From 1bf4efd552eede2a3167a3698c3ef8bda2089141 Mon Sep 17 00:00:00 2001 From: Chris Nutter Date: Sat, 8 Jul 2023 13:03:17 -0700 Subject: [PATCH] first and last commit --- Makefile | 292 + README.md | 0 apps/EmbeddedIOP/EmbeddedIOP.mk | 73 + apps/EmbeddedIOP/EmbeddedIOPFirmware.h | 75 + apps/EmbeddedIOP/EmbeddedIOPProtocol.h | 212 + apps/EmbeddedIOP/application.mk | 85 + apps/EmbeddedIOP/clock_management.c | 26 + apps/EmbeddedIOP/clock_management.h | 20 + apps/EmbeddedIOP/clock_stepping.c | 189 + apps/EmbeddedIOP/clock_stepping.h | 32 + apps/EmbeddedIOP/config/s5l8940xae2-config.mk | 33 + apps/EmbeddedIOP/config/s5l8940xiop-config.mk | 35 + apps/EmbeddedIOP/config/s5l8942xiop-config.mk | 36 + apps/EmbeddedIOP/config/s5l8945xae2-config.mk | 33 + apps/EmbeddedIOP/config/s5l8945xiop-config.mk | 34 + apps/EmbeddedIOP/config/s5l8947xiop-config.mk | 34 + apps/EmbeddedIOP/config/s5l8950xae2-config.mk | 34 + apps/EmbeddedIOP/config/s5l8950xiop-config.mk | 35 + apps/EmbeddedIOP/debugcmds.c | 177 + apps/EmbeddedIOP/function_audio/iop_audio.c | 557 + .../function_audio/iop_audio_protocol.h | 292 + .../function_audio/libstd_stub.cpp | 23 + apps/EmbeddedIOP/function_audio/rules.mk | 35 + .../function_audiodsp/AE2_DMA/ae2_dma.h | 77 + .../function_audiodsp/AE2_DMA/pio_ae2.c | 305 + .../function_audiodsp/AE2_DMA/pio_ae2.h | 55 + .../function_audiodsp/AE2_DMA/pl080dmac_ae2.c | 380 + .../function_audiodsp/AE2_DMA/pl080dmac_ae2.h | 123 + .../function_audiodsp/AE2_I2S/ae2_i2s.h | 88 + .../function_audiodsp/AE2_MCA/ae2_mca.h | 100 + .../function_audiodsp/AudioUnits/AUBase_AE2.h | 50 + .../AudioUnits/AUComponent_AE2.h | 149 + .../function_audiodsp/AudioUnits/AUNull.cpp | 77 + .../function_audiodsp/AudioUnits/AUNull.h | 46 + .../AudioUnits/AUSidetone.cpp | 458 + .../function_audiodsp/AudioUnits/AUSidetone.h | 88 + .../AudioUnits/AudioUnitProperties_AE2.h | 309 + .../AudioUnits/CoreAudioTypes_AE2.h | 248 + .../AudioUnits/iop_au_interface.cpp | 122 + .../AudioUnits/iop_au_interface.h | 44 + .../EmbeddedIOP/function_audiodsp/debug_tap.c | 134 + .../EmbeddedIOP/function_audiodsp/debug_tap.h | 38 + .../function_audiodsp/iop_audiodsp.c | 893 + .../function_audiodsp/iop_audiodsp_protocol.h | 219 + .../function_audiodsp/loopback_device.c | 237 + .../function_audiodsp/loopback_device.h | 61 + .../function_audiodsp/loopback_process.c | 124 + .../function_audiodsp/loopback_process.h | 43 + apps/EmbeddedIOP/function_audiodsp/rules.mk | 48 + .../function_audiodsp/timestamper.c | 174 + .../function_audiodsp/timestamper.h | 24 + apps/EmbeddedIOP/function_ceata/ceata.h | 19 + apps/EmbeddedIOP/function_ceata/iop_ceata.c | 193 + apps/EmbeddedIOP/function_ceata/iop_ceata.h | 12 + .../function_ceata/iop_ceata_protocol.h | 115 + apps/EmbeddedIOP/function_ceata/rules.mk | 26 + apps/EmbeddedIOP/function_fmi/iop_fmi.c | 509 + .../function_fmi/iop_fmi_protocol.h | 553 + apps/EmbeddedIOP/function_fmi/rules.mk | 25 + apps/EmbeddedIOP/function_sdio/iop_sdio.c | 199 + .../function_sdio/iop_sdio_protocol.h | 259 + .../function_sdio/iop_sdio_wrapper.c | 667 + .../function_sdio/iop_sdio_wrapper.h | 35 + apps/EmbeddedIOP/function_sdio/rules.mk | 25 + apps/EmbeddedIOP/iop.h | 56 + apps/EmbeddedIOP/main.c | 618 + apps/EmbeddedIOP/qwi.c | 347 + apps/EmbeddedIOP/qwi.h | 220 + apps/EmbeddedIOP/qwi_protocol.h | 88 + apps/SecureROM/SecureROM.mk | 90 + apps/SecureROM/application.mk | 69 + apps/SecureROM/config/t8002-config.mk | 53 + apps/SecureROM/config/t8010-config-base.mk | 55 + apps/SecureROM/config/t8010-config.mk | 17 + apps/SecureROM/main.c | 371 + .../tests/blinky_armv7/build_rom_test.sh | 118 + apps/SecureROM/tests/blinky_armv7/rom_test.c | 5 + .../tests/blinky_armv8/build_rom_test.sh | 107 + apps/SecureROM/tests/blinky_armv8/rom_test.c | 5 + .../SecureROM/tests/images_t8002/rom_test.bin | Bin 0 -> 24 bytes .../images_t8002/rom_test_ibss_encrypted.im4p | 1 + .../rom_test_ibss_unencrypted.im4p | Bin 0 -> 67 bytes .../images_t8002/rom_test_illb_encrypted.im4p | 1 + .../rom_test_illb_unencrypted.im4p | Bin 0 -> 67 bytes .../SecureROM/tests/images_t8010/rom_test.bin | Bin 0 -> 28 bytes .../images_t8010/rom_test_ibss_encrypted.im4p | Bin 0 -> 192 bytes .../rom_test_ibss_unencrypted.im4p | Bin 0 -> 71 bytes .../images_t8010/rom_test_illb_encrypted.im4p | 1 + .../rom_test_illb_unencrypted.im4p | Bin 0 -> 71 bytes apps/SecureROM/tests/test_generator_hx.py | 1111 + apps/SecureROM/tests/test_generator_mx.py | 924 + apps/iBoot/application.mk | 246 + apps/iBoot/boot.c | 707 + apps/iBoot/config/alcatrazref-config.mk | 74 + apps/iBoot/config/appletv3-config-base.mk | 110 + apps/iBoot/config/appletv4-config-base.mk | 83 + apps/iBoot/config/appletv5-config-base.mk | 89 + apps/iBoot/config/appletv6-config-base.mk | 82 + apps/iBoot/config/b137-config.mk | 13 + apps/iBoot/config/b165-config.mk | 13 + apps/iBoot/config/b184-config.mk | 104 + apps/iBoot/config/b238-config.mk | 78 + apps/iBoot/config/boot-from-nand-template.mk | 28 + apps/iBoot/config/boot-from-nor-template.mk | 21 + apps/iBoot/config/capriref-config.mk | 74 + apps/iBoot/config/cyclonic-config.mk | 63 + apps/iBoot/config/e86-config.mk | 87 + apps/iBoot/config/e88-config.mk | 82 + apps/iBoot/config/elbaref-config.mk | 16 + apps/iBoot/config/elbauiref-config.mk | 36 + apps/iBoot/config/fijiref-config.mk | 72 + apps/iBoot/config/iaccy1-config-base.mk | 70 + apps/iBoot/config/ipad2-config-base.mk | 83 + apps/iBoot/config/ipad2b-config-base.mk | 84 + apps/iBoot/config/ipad3-config-base.mk | 85 + apps/iBoot/config/ipad3b-config-base.mk | 87 + apps/iBoot/config/ipad4-config-base.mk | 87 + apps/iBoot/config/ipad4b-config-base.mk | 88 + apps/iBoot/config/ipad5-config-base.mk | 100 + apps/iBoot/config/ipad5b-config-base.mk | 91 + apps/iBoot/config/ipad5c-config-base.mk | 96 + apps/iBoot/config/ipad6b-config-base.mk | 108 + apps/iBoot/config/ipad6d-config-base.mk | 93 + apps/iBoot/config/iphone5-config-base.mk | 84 + apps/iBoot/config/iphone5b-config-base.mk | 86 + apps/iBoot/config/iphone6-config-base.mk | 87 + apps/iBoot/config/iphone7-config-base.mk | 90 + apps/iBoot/config/iphone8-config-base.mk | 85 + apps/iBoot/config/iphone8b-config-base.mk | 88 + apps/iBoot/config/ipod6-config-base.mk | 106 + apps/iBoot/config/j1-config.mk | 13 + apps/iBoot/config/j105-config.mk | 13 + apps/iBoot/config/j127-config.mk | 14 + apps/iBoot/config/j128-config.mk | 14 + apps/iBoot/config/j2-config.mk | 13 + apps/iBoot/config/j2a-config.mk | 13 + apps/iBoot/config/j33-config.mk | 13 + apps/iBoot/config/j33i-config.mk | 13 + apps/iBoot/config/j34-config.mk | 13 + apps/iBoot/config/j34m-config.mk | 13 + apps/iBoot/config/j42-config.mk | 13 + apps/iBoot/config/j42d-config.mk | 22 + apps/iBoot/config/j42m-config.mk | 13 + apps/iBoot/config/j71-config.mk | 14 + apps/iBoot/config/j72-config.mk | 14 + apps/iBoot/config/j73-config.mk | 14 + apps/iBoot/config/j81-config.mk | 14 + apps/iBoot/config/j82-config.mk | 14 + apps/iBoot/config/j85-config.mk | 16 + apps/iBoot/config/j85m-config.mk | 17 + apps/iBoot/config/j86-config.mk | 16 + apps/iBoot/config/j86m-config.mk | 17 + apps/iBoot/config/j87-config.mk | 16 + apps/iBoot/config/j87m-config.mk | 17 + apps/iBoot/config/j96-config.mk | 14 + apps/iBoot/config/j97-config.mk | 14 + apps/iBoot/config/j98-config.mk | 14 + apps/iBoot/config/j98a-config.mk | 14 + apps/iBoot/config/j99-config.mk | 14 + apps/iBoot/config/j99a-config.mk | 14 + apps/iBoot/config/k93-config.mk | 13 + apps/iBoot/config/k93a-config.mk | 83 + apps/iBoot/config/k94-config.mk | 13 + apps/iBoot/config/k95-config.mk | 13 + apps/iBoot/config/m7ref-config.mk | 65 + apps/iBoot/config/maltaref-config.mk | 15 + apps/iBoot/config/maltauiref-config.mk | 38 + apps/iBoot/config/mauiref-config.mk | 16 + apps/iBoot/config/mauiuiref-config.mk | 38 + apps/iBoot/config/n102-config.mk | 92 + apps/iBoot/config/n27-config.mk | 15 + apps/iBoot/config/n27a-config.mk | 15 + apps/iBoot/config/n28-config.mk | 15 + apps/iBoot/config/n28a-config.mk | 15 + apps/iBoot/config/n41-config.mk | 13 + apps/iBoot/config/n42-config.mk | 13 + apps/iBoot/config/n48-config.mk | 13 + apps/iBoot/config/n49-config.mk | 13 + apps/iBoot/config/n51-config.mk | 13 + apps/iBoot/config/n53-config.mk | 13 + apps/iBoot/config/n56-config.mk | 24 + apps/iBoot/config/n59-config.mk | 98 + apps/iBoot/config/n61-config.mk | 21 + apps/iBoot/config/n66-config-base.mk | 20 + apps/iBoot/config/n66-config.mk | 17 + apps/iBoot/config/n66m-config.mk | 17 + apps/iBoot/config/n69-config.mk | 13 + apps/iBoot/config/n69u-config.mk | 13 + apps/iBoot/config/n71-config-base.mk | 18 + apps/iBoot/config/n71-config.mk | 17 + apps/iBoot/config/n71m-config.mk | 17 + apps/iBoot/config/n78-config.mk | 83 + apps/iBoot/config/n94-config.mk | 106 + apps/iBoot/config/p101-config.mk | 14 + apps/iBoot/config/p102-config.mk | 14 + apps/iBoot/config/p103-config.mk | 14 + apps/iBoot/config/p105-config.mk | 14 + apps/iBoot/config/p106-config.mk | 14 + apps/iBoot/config/p107-config.mk | 14 + apps/iBoot/config/s7002fpga-config.mk | 16 + apps/iBoot/config/s7002sim-config.mk | 15 + apps/iBoot/config/s8000fpga-config.mk | 68 + apps/iBoot/config/s8000ref-config-base.mk | 65 + apps/iBoot/config/s8000sim-config.mk | 67 + apps/iBoot/config/s8001fpga-config.mk | 15 + apps/iBoot/config/s8001ref-config-base.mk | 65 + apps/iBoot/config/s8001sim-config.mk | 15 + apps/iBoot/config/s8003fpga-config.mk | 15 + apps/iBoot/config/s8003sim-config.mk | 15 + apps/iBoot/config/swifter-config.mk | 74 + apps/iBoot/config/t7000fpga-config.mk | 73 + apps/iBoot/config/t7001fpga-config.mk | 16 + apps/iBoot/config/t7001padsim-config.mk | 19 + apps/iBoot/config/t8002fpga-config.mk | 16 + apps/iBoot/config/t8002sim-config.mk | 15 + apps/iBoot/config/t8010fpga-config.mk | 68 + apps/iBoot/config/t8010sim-config.mk | 56 + apps/iBoot/config/typhonic-config.mk | 71 + apps/iBoot/config/watch2-config-base.mk | 99 + apps/iBoot/debugcmds.c | 641 + apps/iBoot/default_env.c | 76 + apps/iBoot/iBoot.mk | 195 + apps/iBoot/main.c | 1382 + apps/iBoot/menu_commands.c | 594 + apps/iBoot/products.mk | 107 + apps/iBoot/upgrade.c | 335 + arch/arm/asm.S | 627 + arch/arm/cache_v7.S | 320 + arch/arm/cachedebug_a8.c | 83 + arch/arm/context.S | 164 + arch/arm/cortex_debug.c | 60 + arch/arm/cortex_hang.S | 41 + arch/arm/cpu.c | 276 + arch/arm/dcc/dcc.c | 108 + arch/arm/dcc/rules.mk | 19 + arch/arm/entropy.S | 39 + arch/arm/exceptions.S | 195 + arch/arm/fp.c | 83 + arch/arm/handlers.c | 560 + arch/arm/include/arch/arch_task.h | 82 + arch/arm/include/arch/arm/arm.h | 320 + arch/arm/include/arch/arm/assembler.h | 34 + arch/arm/link.exp | 1 + arch/arm/mmu.c | 176 + arch/arm/mpu.c | 28 + arch/arm/rules.mk | 248 + arch/arm/start.S | 343 + arch/arm/task.c | 61 + arch/arm64/asm.S | 276 + arch/arm64/context.S | 107 + arch/arm64/cpu.c | 100 + arch/arm64/entropy.S | 41 + arch/arm64/exceptions_el1.S | 306 + arch/arm64/exceptions_el3.S | 315 + arch/arm64/fp.c | 40 + arch/arm64/handlers.c | 138 + arch/arm64/include/arch/arm64/proc_reg.h | 599 + arch/arm64/link.exp | 1 + arch/arm64/mmu.c | 543 + arch/arm64/mmu_test.c | 846 + arch/arm64/rules.mk | 176 + arch/arm64/start.S | 262 + arch/arm64/task.c | 52 + arch/arm64/test.mk | 56 + arch/arm64/tests-mmu.mk | 30 + arch/arm64/timer.c | 147 + docs/Cayman_IOSpreadsheet_Template.xlsx | Bin 0 -> 42520 bytes docs/Doxyfile | 1543 ++ docs/Elba_IOSpreadsheet_Template.xlsx | Bin 0 -> 59262 bytes docs/M8_IOSpreadsheet_Template.xlsx | Bin 0 -> 69410 bytes docs/Maui_IOSpreadsheet_Template.xlsx | Bin 0 -> 68661 bytes docs/chain_validation.txt | 120 + docs/dcs-specs/Elba_Init_A0_July_15_2015.html | 2948 ++ docs/dcs-specs/Elba_Init_B0_Mar_4_2016.html | 3099 +++ docs/dcs-specs/Elba_Init_B0_Oct_30_2015.html | 3014 +++ .../Malta_Init_1200_October_29_2015.html | 3268 +++ .../Malta_Init_A0_1200_June_17_2015.html | 3186 +++ docs/dcs-specs/Malta_Init_A0_May_20_2015.html | 3155 +++ .../Maui_Init_1200_October_29_2015.html | 3026 +++ .../Maui_Init_B0_1200_June_2_2015.html | 2953 ++ docs/dcs-specs/Maui_Init_B0_May_20_2015.html | 2943 ++ docs/fuzzing.txt | 83 + docs/iBoot_IO_Spreadsheet_Standard.pages | Bin 0 -> 137474 bytes docs/image3_format.txt | 199 + docs/image3_pki_interface.txt | 78 + docs/image3_user.txt | 169 + docs/mmu64.txt | 83 + docs/source_layout.txt | 159 + docs/uncrustify.cfg | 168 + docs/unittests.txt | 110 + docs/upgrade_mode.txt | 67 + drivers/aes/aes.c | 288 + drivers/aes/rules.mk | 16 + drivers/analogix/displayport/displayport.c | 1837 ++ .../include/drivers/displayport/displayport.h | 36 + drivers/analogix/displayport/regs.h | 1480 + drivers/analogix/displayport/rules.mk | 17 + drivers/apple/a5iop/a5iop.c | 246 + .../apple/a5iop/include/drivers/a5iop/a5iop.h | 25 + drivers/apple/a5iop/rules.mk | 14 + drivers/apple/a7iop/a7iop.c | 425 + drivers/apple/a7iop/a7iop_debug.c | 84 + .../apple/a7iop/include/drivers/a7iop/a7iop.h | 196 + drivers/apple/a7iop/rules.mk | 16 + drivers/apple/adbe/adbe.c | 64 + drivers/apple/adbe/adbe_regs_v1.h | 97 + drivers/apple/adbe/adbe_regs_v2.h | 89 + drivers/apple/adbe/adbe_regs_v3.h | 153 + drivers/apple/adbe/adbe_v1.c | 185 + drivers/apple/adbe/adbe_v2.c | 166 + drivers/apple/adbe/adbe_v3.c | 163 + .../apple/adbe/include/drivers/adbe/adbe.h | 20 + drivers/apple/adbe/rules.mk | 27 + drivers/apple/adfe/adfe.c | 325 + drivers/apple/adfe/adfe_regs.h | 172 + .../apple/adfe/include/drivers/adfe/adfe.h | 22 + drivers/apple/adfe/rules.mk | 18 + drivers/apple/adfe_v2/adfe_v2.c | 407 + drivers/apple/adfe_v2/adfe_v2_regs.h | 206 + .../adfe_v2/include/drivers/adfe_v2/adfe.h | 23 + drivers/apple/adfe_v2/rules.mk | 18 + drivers/apple/aes/aes_ap.c | 225 + drivers/apple/aes/aes_ap.h | 101 + drivers/apple/aes/rules.mk | 20 + drivers/apple/aes_s7002/aes_s7002.c | 265 + drivers/apple/aes_s7002/aes_s7002.h | 79 + drivers/apple/aes_s7002/rules.mk | 20 + drivers/apple/aes_v2/aes_v2.c | 429 + drivers/apple/aes_v2/aes_v2.h | 46 + drivers/apple/aes_v2/rules.mk | 21 + drivers/apple/aic/aic.c | 533 + drivers/apple/aic/include/drivers/aic/aic.h | 150 + drivers/apple/aic/rules.mk | 34 + drivers/apple/amc/amc.c | 790 + drivers/apple/amc/amc_v2.c | 660 + drivers/apple/amc/calibration_v1.c | 576 + drivers/apple/amc/include/drivers/amc/amc.h | 146 + .../apple/amc/include/drivers/amc/amc_phy.h | 58 + .../apple/amc/include/drivers/amc/amc_regs.h | 27 + .../amc/include/drivers/amc/amc_regs_v12.h | 183 + .../amc/include/drivers/amc/amc_regs_v3.h | 150 + .../amc/include/drivers/amc/amc_regs_v45.h | 165 + drivers/apple/amc/rules.mk | 28 + drivers/apple/amg/amg.c | 328 + drivers/apple/amg/amg.h | 65 + drivers/apple/amg/rules.mk | 14 + drivers/apple/amp/amp_v1.c | 270 + drivers/apple/amp/amp_v2.c | 3190 +++ .../apple/amp/include/drivers/amp/amp_v1.h | 97 + .../apple/amp/include/drivers/amp/amp_v2.h | 137 + .../include/drivers/amp/amp_v2_calibration.h | 80 + drivers/apple/amp/rules.mk | 20 + drivers/apple/amp_v3/amp_v3.c | 185 + drivers/apple/amp_v3/amp_v3_calibration.c | 3461 +++ drivers/apple/amp_v3/iboot/amp_v3_shim.c | 105 + drivers/apple/amp_v3/iboot/amp_v3_shim.h | 69 + drivers/apple/amp_v3/include/amp_v3.h | 114 + .../apple/amp_v3/include/amp_v3_calibration.h | 132 + drivers/apple/amp_v3/rules.mk | 22 + drivers/apple/anc/anc_bootrom.c | 528 + drivers/apple/anc/anc_bootrom.h | 24 + drivers/apple/anc/anc_bootrom_cmds.h | 226 + drivers/apple/anc/anc_bootrom_private.h | 119 + drivers/apple/anc/anc_bootrom_regs.h | 2469 ++ drivers/apple/anc/anc_bootrom_regs_m7.h | 3393 +++ drivers/apple/anc/anc_llb.c | 659 + drivers/apple/anc/anc_llb.h | 73 + drivers/apple/anc/ppn_npl_regs.h | 1528 ++ drivers/apple/anc/rules.mk | 46 + drivers/apple/anc/util_boot.c | 893 + drivers/apple/anc/util_boot.h | 99 + drivers/apple/apcie/apcie.c | 247 + drivers/apple/apcie/rules.mk | 16 + drivers/apple/asp/asp.c | 376 + drivers/apple/asp/common_util.c | 1258 + drivers/apple/asp/common_util.h | 186 + drivers/apple/asp/debug.c | 4207 +++ drivers/apple/asp/rules.mk | 23 + drivers/apple/audio/audio.c | 231 + drivers/apple/audio/debug.c | 61 + .../apple/audio/include/drivers/audio/audio.h | 60 + drivers/apple/audio/rules.mk | 20 + drivers/apple/ausb/ausb.c | 253 + drivers/apple/ausb/ausb.h | 46 + drivers/apple/ausb/rules.mk | 16 + drivers/apple/ccc/ccc.c | 68 + drivers/apple/ccc/include/drivers/ccc/ccc.h | 23 + drivers/apple/ccc/rules.mk | 15 + drivers/apple/cdma/cdma.c | 1104 + drivers/apple/cdma/cdma.h | 152 + drivers/apple/cdma/cdma_aes.c | 299 + drivers/apple/cdma/rules.mk | 21 + .../apple/consistent_debug/consistent_debug.c | 204 + .../consistent_debug_helper_fns.h | 72 + .../consistent_debug_registry.h | 235 + drivers/apple/consistent_debug/rules.mk | 22 + drivers/apple/csi/csi.c | 747 + drivers/apple/csi/debug.c | 283 + drivers/apple/csi/endpoints/builtin.c | 55 + drivers/apple/csi/endpoints/console_ep.c | 237 + drivers/apple/csi/endpoints/crashlog_ep.c | 666 + drivers/apple/csi/endpoints/management_ep.c | 362 + drivers/apple/csi/endpoints/syslog_ep.c | 212 + drivers/apple/csi/firmware/csi_firmware.c | 183 + drivers/apple/csi/firmware/csi_firmware.h | 47 + drivers/apple/csi/firmware/fw_ans.c | 63 + drivers/apple/csi/include/csi_private.h | 151 + .../apple/csi/include/endpoints/console_ep.h | 38 + .../apple/csi/include/endpoints/crashlog_ep.h | 41 + .../csi/include/endpoints/management_ep.h | 101 + .../apple/csi/include/endpoints/syslog_ep.h | 28 + drivers/apple/csi/include/queue.h | 768 + drivers/apple/csi/rules.mk | 31 + drivers/apple/dart_lpae/dart.c | 369 + drivers/apple/dart_lpae/dart_regs.h | 117 + drivers/apple/dart_lpae/rules.mk | 16 + drivers/apple/dcs/dcs.c | 542 + drivers/apple/dcs/dcs_calibration.c | 5070 ++++ drivers/apple/dcs/dcs_calibration_v2.c | 5106 ++++ drivers/apple/dcs/dcs_init_lib.c | 403 + drivers/apple/dcs/include/drivers/dcs/dcs.h | 213 + .../apple/dcs/include/drivers/dcs/dcs_cal.h | 233 + .../dcs/include/drivers/dcs/dcs_cal_v2.h | 291 + .../dcs/include/drivers/dcs/dcs_calibration.h | 271 + .../dcs/include/drivers/dcs/dcs_init_lib.h | 331 + .../apple/dcs/include/drivers/dcs/dcs_regs.h | 676 + drivers/apple/dcs/rules.mk | 27 + drivers/apple/displaypipe/displaypipe.c | 607 + drivers/apple/displaypipe/displaypipe.h | 147 + drivers/apple/displaypipe/rules.mk | 16 + drivers/apple/dither/dither.c | 264 + drivers/apple/dither/dither_v2.h | 52 + drivers/apple/dither/dither_v3.h | 54 + drivers/apple/dither/dither_v4.h | 62 + drivers/apple/dither/rules.mk | 16 + drivers/apple/dockchannel/dockchannel_regs.h | 61 + drivers/apple/dockchannel/dockchannel_uart.c | 296 + .../include/drivers/dockchannel/dockchannel.h | 22 + drivers/apple/dockchannel/rules.mk | 25 + drivers/apple/dockfifo/cobs.c | 226 + drivers/apple/dockfifo/cobs.h | 38 + drivers/apple/dockfifo/dockfifo_bulk.c | 403 + drivers/apple/dockfifo/dockfifo_regs.h | 28 + drivers/apple/dockfifo/dockfifo_uart.c | 242 + .../include/drivers/dockfifo/dockfifo.h | 47 + drivers/apple/dockfifo/rules.mk | 37 + drivers/apple/dpb/dpb.c | 153 + drivers/apple/dpb/dpb.h | 117 + drivers/apple/dpb/rules.mk | 17 + drivers/apple/dpb_v2/dpb_v2.c | 43 + drivers/apple/dpb_v2/dpb_v2.h | 76 + drivers/apple/dpb_v2/rules.mk | 17 + drivers/apple/dwi/dwi.c | 47 + drivers/apple/dwi/dwi.h | 36 + drivers/apple/dwi/rules.mk | 15 + drivers/apple/gpio/gpio.c | 282 + .../apple/gpio/include/drivers/apple/gpio.h | 153 + drivers/apple/gpio/rules.mk | 19 + drivers/apple/h2fmi/H2FIL.c | 192 + drivers/apple/h2fmi/H2fmi.c | 2934 ++ drivers/apple/h2fmi/H2fmi.h | 69 + drivers/apple/h2fmi/H2fmi_8920regs.h | 502 + drivers/apple/h2fmi/H2fmi_8922regs.h | 535 + drivers/apple/h2fmi/H2fmi_8940regs.h | 767 + drivers/apple/h2fmi/H2fmi_8945regs.h | 799 + drivers/apple/h2fmi/H2fmi_8950regs.h | 840 + drivers/apple/h2fmi/H2fmi_boot.c | 483 + drivers/apple/h2fmi/H2fmi_debug.c | 249 + drivers/apple/h2fmi/H2fmi_dma.h | 45 + drivers/apple/h2fmi/H2fmi_dma_iboot.c | 198 + drivers/apple/h2fmi/H2fmi_dma_types.h | 81 + drivers/apple/h2fmi/H2fmi_erase.c | 303 + drivers/apple/h2fmi/H2fmi_iop.c | 902 + drivers/apple/h2fmi/H2fmi_iop.h | 70 + drivers/apple/h2fmi/H2fmi_misc.c | 984 + drivers/apple/h2fmi/H2fmi_ppn.c | 2725 ++ drivers/apple/h2fmi/H2fmi_ppn.h | 512 + drivers/apple/h2fmi/H2fmi_ppn_fil.c | 997 + drivers/apple/h2fmi/H2fmi_ppn_iop.c | 603 + drivers/apple/h2fmi/H2fmi_private.h | 718 + drivers/apple/h2fmi/H2fmi_read.c | 1514 ++ drivers/apple/h2fmi/H2fmi_test.c | 490 + drivers/apple/h2fmi/H2fmi_timing.c | 288 + drivers/apple/h2fmi/H2fmi_timing.h | 110 + drivers/apple/h2fmi/H2fmi_write.c | 1214 + drivers/apple/h2fmi/boot/H2fmi_bootrom.c | 1018 + drivers/apple/h2fmi/boot/H2fmi_private.h | 387 + drivers/apple/h2fmi/boot/H2fmi_regs.h | 761 + drivers/apple/h2fmi/boot/rules.mk | 15 + drivers/apple/h2fmi/debug.c | 865 + drivers/apple/h2fmi/fmiss.c | 131 + drivers/apple/h2fmi/fmiss.h | 42 + drivers/apple/h2fmi/fmiss_ppn.c | 1342 + drivers/apple/h2fmi/fmiss_raw.c | 553 + drivers/apple/h2fmi/rules.mk | 78 + drivers/apple/h2fmi/soc.h | 64 + drivers/apple/iic/iic.c | 282 + drivers/apple/iic/iic.h | 75 + drivers/apple/iic/rules.mk | 19 + .../include/drivers/lpdp_phy/lpdp_phy.h | 31 + drivers/apple/lpdp_phy/lpdp_v1.c | 809 + drivers/apple/lpdp_phy/lpdp_v2.c | 996 + drivers/apple/lpdp_phy/regs_v1.h | 185 + drivers/apple/lpdp_phy/regs_v2.h | 331 + drivers/apple/lpdp_phy/rules.mk | 19 + drivers/apple/mcu/mcu.c | 625 + drivers/apple/mcu/rules.mk | 17 + .../apple/oscar/include/drivers/oscar/oscar.h | 19 + drivers/apple/oscar/oscar.c | 259 + drivers/apple/oscar/rules.mk | 15 + drivers/apple/prc/prc.c | 93 + drivers/apple/prc/prc.h | 26 + drivers/apple/prc/rules.mk | 16 + drivers/apple/reconfig/reconfig.c | 491 + drivers/apple/reconfig/rules.mk | 17 + .../sep/include/drivers/sep/sep_client.h | 20 + drivers/apple/sep/rules.mk | 17 + drivers/apple/sep/sep_client.c | 281 + drivers/apple/sha2/rules.mk | 19 + drivers/apple/sha2/sha2.c | 208 + drivers/apple/sha2/sha2.h | 59 + drivers/apple/shmcon/rules.mk | 25 + drivers/apple/shmcon/shmcon.c | 270 + drivers/apple/swifterpmu/power.c | 190 + drivers/apple/swifterpmu/power.h | 25 + drivers/apple/swifterpmu/rules.mk | 19 + .../include/drivers/voltage_knobs/knobs.h | 165 + drivers/apple/voltage_knobs/knobs.c | 650 + drivers/apple/voltage_knobs/knobs_s7002.c | 141 + drivers/apple/voltage_knobs/knobs_s7002.h | 10 + drivers/apple/voltage_knobs/knobs_s8000.c | 185 + drivers/apple/voltage_knobs/knobs_s8000.h | 10 + drivers/apple/voltage_knobs/knobs_t7000.c | 179 + drivers/apple/voltage_knobs/knobs_t7000.h | 9 + drivers/apple/voltage_knobs/menu_commands.c | 468 + drivers/apple/voltage_knobs/rules.mk | 32 + drivers/apple/wpc/rules.mk | 16 + drivers/apple/wpc/wpc.c | 128 + drivers/apple/wpc/wpc.h | 26 + drivers/arasan/sdio/rules.mk | 25 + drivers/arasan/sdio/sdiocommon/sdhc_debug.c | 76 + drivers/arasan/sdio/sdiocommon/sdhc_debug.h | 36 + .../arasan/sdio/sdiocommon/sdhc_registers.c | 647 + .../arasan/sdio/sdiocommon/sdhc_registers.h | 276 + drivers/arasan/sdio/sdiocommon/sdio_cccr.h | 92 + drivers/arasan/sdio/sdiocommon/sdio_cis.h | 184 + .../arasan/sdio/sdiocommon/sdio_cmdfields.c | 145 + .../arasan/sdio/sdiocommon/sdio_cmdfields.h | 120 + drivers/arasan/sdio/sdiocommon/sdio_cmdprop.c | 114 + drivers/arasan/sdio/sdiocommon/sdio_cmdprop.h | 42 + drivers/arasan/sdio/sdiocommon/sdio_types.h | 276 + drivers/arasan/sdio/sdiodrv_command.c | 139 + drivers/arasan/sdio/sdiodrv_command.h | 70 + drivers/arasan/sdio/sdiodrv_config.c | 215 + drivers/arasan/sdio/sdiodrv_config.h | 83 + drivers/arasan/sdio/sdiodrv_transfer.c | 452 + drivers/arasan/sdio/sdiodrv_transfer.h | 54 + drivers/backlight/lm3534/library.mk | 27 + drivers/backlight/lm3534/lm3534.c | 120 + drivers/backlight/lm3534/rules.mk | 15 + drivers/backlight/lp8559/lp8559.c | 109 + drivers/backlight/lp8559/lp8559.h | 37 + drivers/backlight/lp8559/rules.mk | 16 + drivers/dialog/charger/rules.mk | 22 + drivers/dialog/pmu/NTCTables.h | 92 + drivers/dialog/pmu/charger.c | 1229 + drivers/dialog/pmu/d1755.h | 563 + drivers/dialog/pmu/d1815.h | 677 + drivers/dialog/pmu/d1881.h | 800 + drivers/dialog/pmu/d1946.h | 851 + drivers/dialog/pmu/d1972.h | 913 + drivers/dialog/pmu/d1974.h | 866 + drivers/dialog/pmu/d2018.h | 1049 + drivers/dialog/pmu/d2045.h | 1217 + drivers/dialog/pmu/d2089.h | 1496 + drivers/dialog/pmu/d2186.h | 1430 + drivers/dialog/pmu/d2207.h | 1608 ++ drivers/dialog/pmu/d2231.h | 773 + drivers/dialog/pmu/d2238.h | 1190 + drivers/dialog/pmu/d2255.h | 1363 + drivers/dialog/pmu/d2257.h | 1521 ++ drivers/dialog/pmu/d2355.h | 844 + drivers/dialog/pmu/dCommon.h | 57 + drivers/dialog/pmu/power.c | 1934 ++ drivers/dialog/pmu/rules.mk | 22 + drivers/display/edp/edp.c | 232 + drivers/display/edp/edp.h | 14 + drivers/display/edp/rules.mk | 16 + drivers/display/pinot/pinot.c | 361 + drivers/display/pinot/pinot.h | 20 + drivers/display/pinot/rules.mk | 16 + drivers/display/summit/rules.mk | 16 + drivers/display/summit/summit.c | 774 + drivers/display/summit/summit.h | 18 + drivers/display/tmds/rules.mk | 16 + drivers/display/tmds/tmds.c | 79 + drivers/display/tmds/tmds.h | 49 + drivers/display_pmu/beryllium/beryllium.c | 126 + drivers/display_pmu/beryllium/rules.mk | 17 + drivers/display_pmu/chestnut/chestnut.c | 156 + drivers/display_pmu/chestnut/rules.mk | 17 + drivers/displayport/controller.c | 691 + drivers/displayport/debug.c | 163 + drivers/displayport/device.c | 810 + drivers/displayport/dpcd.h | 261 + drivers/displayport/edid.h | 377 + drivers/displayport/process_edid.c | 1753 ++ drivers/displayport/rules.mk | 18 + drivers/flash_nand/OAM/EmbeddedIOP/WMRBuf.c | 1 + .../flash_nand/OAM/EmbeddedIOP/WMRFeatures.h | 79 + drivers/flash_nand/OAM/EmbeddedIOP/WMROAM.c | 147 + .../flash_nand/OAM/EmbeddedIOP/WMRPlatform.h | 206 + drivers/flash_nand/OAM/EmbeddedIOP/WMRTypes.h | 42 + drivers/flash_nand/OAM/WMRBuf.h | 35 + drivers/flash_nand/OAM/WMROAM.h | 329 + drivers/flash_nand/OAM/iBoot/WMRBuf.c | 127 + drivers/flash_nand/OAM/iBoot/WMRBufTypes.h | 41 + drivers/flash_nand/OAM/iBoot/WMRFeatures.h | 182 + drivers/flash_nand/OAM/iBoot/WMROAM.c | 254 + drivers/flash_nand/OAM/iBoot/WMRPlatform.h | 237 + drivers/flash_nand/OAM/iBoot/WMRTypes.h | 42 + drivers/flash_nand/OAM/rules.mk | 22 + drivers/flash_nand/OAM/spTypes.h | 781 + drivers/flash_nand/benchmark/L2V_Test.c | 208 + drivers/flash_nand/benchmark/benchmark.c | 29 + drivers/flash_nand/benchmark/rules.mk | 40 + .../flash_nand/boot/firmware/nand_firmware.c | 264 + .../flash_nand/boot/firmware/nand_firmware.h | 24 + drivers/flash_nand/boot/firmware/rules.mk | 17 + drivers/flash_nand/boot/nand_boot.c | 563 + drivers/flash_nand/boot/nand_export.c | 343 + drivers/flash_nand/boot/nand_export.h | 43 + drivers/flash_nand/boot/nand_part.h | 425 + drivers/flash_nand/boot/nand_part_core.c | 3317 +++ drivers/flash_nand/boot/nand_part_core.h | 368 + drivers/flash_nand/boot/nand_part_interface.h | 233 + drivers/flash_nand/boot/nvram/nand_nvram.c | 369 + .../flash_nand/boot/nvram/nand_nvram_core.c | 1776 ++ .../flash_nand/boot/nvram/nand_nvram_core.h | 115 + .../flash_nand/boot/nvram/nand_nvram_dump.c | 173 + .../flash_nand/boot/nvram/nand_nvram_dump.h | 21 + .../flash_nand/boot/nvram/nand_nvram_impl.h | 295 + .../boot/nvram/nand_nvram_platform.h | 86 + drivers/flash_nand/boot/nvram/rules.mk | 19 + drivers/flash_nand/boot/rules.mk | 30 + drivers/flash_nand/boot/syscfg/nand_syscfg.c | 128 + drivers/flash_nand/boot/syscfg/rules.mk | 17 + drivers/flash_nand/debug.c | 1524 ++ drivers/flash_nand/ftl/nand.c | 61 + drivers/flash_nand/ftl/rules.mk | 22 + drivers/flash_nand/id/nandid.c | 723 + drivers/flash_nand/id/nandid.h | 311 + drivers/flash_nand/id/rules.mk | 21 + drivers/flash_nand/ppn-swiss/export.txt | 12 + drivers/flash_nand/ppn-swiss/library.mk | 77 + drivers/flash_nand/ppn-swiss/ppn.c | 93 + drivers/flash_nand/ppn-swiss/ppn_syscfg.c | 77 + drivers/flash_nand/ppn-swiss/rules.mk | 37 + .../flash_nand/ppn/WhimoryPPN/Boot/ANDStats.c | 256 + .../flash_nand/ppn/WhimoryPPN/Boot/ANDStats.h | 21 + .../flash_nand/ppn/WhimoryPPN/Boot/RegBoth.c | 28 + .../flash_nand/ppn/WhimoryPPN/Boot/RegSwiss.c | 26 + .../ppn/WhimoryPPN/Boot/RegVanilla.c | 26 + .../ppn/WhimoryPPN/Boot/WhimoryBoot.c | 1262 + .../ppn/WhimoryPPN/Boot/WhimoryBoot.h | 208 + .../ppn/WhimoryPPN/Boot/WhimoryBootTypes.h | 78 + .../ppn/WhimoryPPN/Core/FPart/PPNFPart.c | 1647 ++ .../ppn/WhimoryPPN/Core/FPart/PPNFPartTypes.h | 69 + .../ppn/WhimoryPPN/Core/FPart/PPNTest.c | 97 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V.h | 23 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Assert.h | 27 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Config.h | 33 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Defines.h | 92 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Extern.h | 35 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Forget.c | 92 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Forget.h | 23 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Free.c | 53 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.c | 19 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.h | 105 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Init.c | 82 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.c | 52 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.h | 24 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.c | 144 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.h | 26 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.c | 243 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.h | 25 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Search.c | 140 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.c | 213 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.mak | 28 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.c | 75 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.h | 149 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Update.c | 1197 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.c | 36 + .../ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.h | 28 + .../Core/FTL/L2V/WMRFeatures-test.h | 1 + .../ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.c | 26 + .../ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.h | 56 + .../ppn/WhimoryPPN/Core/FTL/yaFTL.c | 6363 +++++ .../ppn/WhimoryPPN/Core/FTL/yaFTLTypes.h | 335 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.c | 371 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.h | 51 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_Defines.h | 121 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_gc.c | 1716 ++ .../ppn/WhimoryPPN/Core/FTL/yaFTL_gc.h | 40 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_meta.h | 27 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.c | 131 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.h | 116 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.c | 115 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.h | 84 + .../ppn/WhimoryPPN/Core/FTL/yaFTL_whoami.h | 18 + .../ppn/WhimoryPPN/Core/Misc/PPNMisc.c | 842 + .../ppn/WhimoryPPN/Core/Misc/PPNMiscTypes.h | 158 + .../ppn/WhimoryPPN/Core/Misc/VFLBuffer.c | 399 + .../ppn/WhimoryPPN/Core/Misc/VFLBuffer.h | 104 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V.h | 24 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Assert.h | 25 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Config.h | 28 + .../WhimoryPPN/Core/SFTL/L2V/L2V_Defines.h | 85 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump.m | 281 + .../Core/SFTL/L2V/L2V_Dump_Prefix.h | 19 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Extern.h | 41 + .../WhimoryPPN/Core/SFTL/L2V/L2V_FindFrag.c | 157 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Free.c | 48 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.c | 15 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.h | 106 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Init.c | 104 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.c | 50 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.h | 24 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.c | 151 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.h | 26 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.c | 343 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.h | 25 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Search.c | 136 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.c | 227 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.mak | 28 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.c | 72 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.h | 193 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Update.c | 1213 + .../ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Valid.h | 28 + .../Core/SFTL/L2V/WMRFeatures-test.h | 1 + .../WhimoryPPN/Core/SFTL/L2V/WMROAM-test.c | 26 + .../WhimoryPPN/Core/SFTL/L2V/WMROAM-test.h | 62 + .../Core/SFTL/gdb/compare-valid.gdb | 15 + .../ppn/WhimoryPPN/Core/SFTL/gdb/count-bb.gdb | 29 + .../WhimoryPPN/Core/SFTL/gdb/count-sbs.gdb | 67 + .../WhimoryPPN/Core/SFTL/gdb/erases-histo.sh | 3 + .../WhimoryPPN/Core/SFTL/gdb/find-0valid.gdb | 12 + .../Core/SFTL/gdb/find-high-reads.gdb | 12 + .../WhimoryPPN/Core/SFTL/gdb/free-space.gdb | 1 + .../WhimoryPPN/Core/SFTL/gdb/gc-zone-lbas.gdb | 7 + .../WhimoryPPN/Core/SFTL/gdb/log-erases.gdb | 17 + .../WhimoryPPN/Core/SFTL/gdb/log-userseq.gdb | 21 + .../WhimoryPPN/Core/SFTL/gdb/log-valid.gdb | 38 + .../WhimoryPPN/Core/SFTL/gdb/min-valid.gdb | 16 + .../ppn/WhimoryPPN/Core/SFTL/gdb/print-bb.gdb | 28 + .../ppn/WhimoryPPN/Core/SFTL/gdb/wamp.gdb | 3 + .../ppn/WhimoryPPN/Core/SFTL/s_bg.c | 35 + .../ppn/WhimoryPPN/Core/SFTL/s_bg.h | 28 + .../ppn/WhimoryPPN/Core/SFTL/s_boot.c | 104 + .../ppn/WhimoryPPN/Core/SFTL/s_boot.h | 21 + .../ppn/WhimoryPPN/Core/SFTL/s_btoc.c | 560 + .../ppn/WhimoryPPN/Core/SFTL/s_btoc.h | 49 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt.c | 167 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt.h | 40 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.c | 507 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.h | 33 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt_load.c | 444 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt_load.h | 27 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt_save.c | 486 + .../ppn/WhimoryPPN/Core/SFTL/s_cxt_save.h | 21 + .../ppn/WhimoryPPN/Core/SFTL/s_dbg.c | 303 + .../ppn/WhimoryPPN/Core/SFTL/s_dbg.h | 60 + .../ppn/WhimoryPPN/Core/SFTL/s_defines.h | 116 + .../ppn/WhimoryPPN/Core/SFTL/s_external.c | 450 + .../ppn/WhimoryPPN/Core/SFTL/s_flatten.c | 75 + .../ppn/WhimoryPPN/Core/SFTL/s_flatten.h | 22 + .../ppn/WhimoryPPN/Core/SFTL/s_fmt.c | 113 + .../ppn/WhimoryPPN/Core/SFTL/s_fmt.h | 22 + .../ppn/WhimoryPPN/Core/SFTL/s_gc.c | 1111 + .../ppn/WhimoryPPN/Core/SFTL/s_gc.h | 45 + .../ppn/WhimoryPPN/Core/SFTL/s_geom.c | 211 + .../ppn/WhimoryPPN/Core/SFTL/s_geom.h | 59 + .../ppn/WhimoryPPN/Core/SFTL/s_init.c | 249 + .../ppn/WhimoryPPN/Core/SFTL/s_init.h | 25 + .../ppn/WhimoryPPN/Core/SFTL/s_internal.c | 18 + .../ppn/WhimoryPPN/Core/SFTL/s_internal.h | 483 + .../ppn/WhimoryPPN/Core/SFTL/s_meta.c | 161 + .../ppn/WhimoryPPN/Core/SFTL/s_meta.h | 114 + .../ppn/WhimoryPPN/Core/SFTL/s_read.c | 401 + .../ppn/WhimoryPPN/Core/SFTL/s_read.h | 24 + .../ppn/WhimoryPPN/Core/SFTL/s_readdist.c | 111 + .../ppn/WhimoryPPN/Core/SFTL/s_readdist.h | 36 + .../ppn/WhimoryPPN/Core/SFTL/s_sb.c | 450 + .../ppn/WhimoryPPN/Core/SFTL/s_sb.h | 76 + .../ppn/WhimoryPPN/Core/SFTL/s_stats.c | 124 + .../ppn/WhimoryPPN/Core/SFTL/s_stats.h | 38 + .../ppn/WhimoryPPN/Core/SFTL/s_token.c | 34 + .../ppn/WhimoryPPN/Core/SFTL/s_token.h | 22 + .../ppn/WhimoryPPN/Core/SFTL/s_trim.c | 257 + .../ppn/WhimoryPPN/Core/SFTL/s_trim.h | 37 + .../ppn/WhimoryPPN/Core/SFTL/s_wearlev.c | 107 + .../ppn/WhimoryPPN/Core/SFTL/s_wearlev.h | 23 + .../ppn/WhimoryPPN/Core/SFTL/s_write.c | 710 + .../ppn/WhimoryPPN/Core/SFTL/s_write.h | 48 + .../ppn/WhimoryPPN/Core/SVFL/s_vfl.c | 4477 +++ .../ppn/WhimoryPPN/Core/SVFL/s_vfl_types.h | 292 + .../ppn/WhimoryPPN/Core/VFL/PPNVFLInterface.c | 4711 ++++ .../ppn/WhimoryPPN/Core/VFL/PPNVFLTypes.h | 283 + .../flash_nand/ppn/WhimoryPPN/Test/FILTest.c | 433 + .../ppn/WhimoryPPN/Test/FPartTest.c | 45 + .../flash_nand/ppn/WhimoryPPN/Test/FTLTest.c | 45 + .../flash_nand/ppn/WhimoryPPN/Test/VFLTest.c | 426 + drivers/flash_nand/ppn/export.txt | 12 + drivers/flash_nand/ppn/library.mk | 61 + drivers/flash_nand/ppn/ppn.c | 93 + drivers/flash_nand/ppn/ppn_syscfg.c | 77 + drivers/flash_nand/ppn/rules.mk | 36 + .../flash_nand/raw/Whimory/Core/FPart/FPart.c | 1925 ++ .../raw/Whimory/Core/FPart/FPartTypes.h | 125 + .../raw/Whimory/Core/FTL/FTLInterface.c | 4665 ++++ .../raw/Whimory/Core/FTL/FTLTypes.h | 305 + .../flash_nand/raw/Whimory/Core/FTL/L2V/L2V.h | 23 + .../raw/Whimory/Core/FTL/L2V/L2V_Assert.h | 27 + .../raw/Whimory/Core/FTL/L2V/L2V_Config.h | 33 + .../raw/Whimory/Core/FTL/L2V/L2V_Defines.h | 92 + .../raw/Whimory/Core/FTL/L2V/L2V_Extern.h | 35 + .../raw/Whimory/Core/FTL/L2V/L2V_Forget.c | 92 + .../raw/Whimory/Core/FTL/L2V/L2V_Forget.h | 23 + .../raw/Whimory/Core/FTL/L2V/L2V_Free.c | 53 + .../raw/Whimory/Core/FTL/L2V/L2V_Funcs.c | 19 + .../raw/Whimory/Core/FTL/L2V/L2V_Funcs.h | 105 + .../raw/Whimory/Core/FTL/L2V/L2V_Init.c | 82 + .../raw/Whimory/Core/FTL/L2V/L2V_Mem.c | 52 + .../raw/Whimory/Core/FTL/L2V/L2V_Mem.h | 24 + .../raw/Whimory/Core/FTL/L2V/L2V_Print.c | 144 + .../raw/Whimory/Core/FTL/L2V/L2V_Print.h | 26 + .../raw/Whimory/Core/FTL/L2V/L2V_Repack.c | 243 + .../raw/Whimory/Core/FTL/L2V/L2V_Repack.h | 25 + .../raw/Whimory/Core/FTL/L2V/L2V_Search.c | 140 + .../raw/Whimory/Core/FTL/L2V/L2V_Test.c | 213 + .../raw/Whimory/Core/FTL/L2V/L2V_Test.mak | 28 + .../raw/Whimory/Core/FTL/L2V/L2V_Types.c | 75 + .../raw/Whimory/Core/FTL/L2V/L2V_Types.h | 149 + .../raw/Whimory/Core/FTL/L2V/L2V_Update.c | 1197 + .../raw/Whimory/Core/FTL/L2V/L2V_Valid.c | 36 + .../raw/Whimory/Core/FTL/L2V/L2V_Valid.h | 28 + .../Whimory/Core/FTL/L2V/WMRFeatures-test.h | 1 + .../raw/Whimory/Core/FTL/L2V/WMROAM-test.c | 26 + .../raw/Whimory/Core/FTL/L2V/WMROAM-test.h | 56 + .../flash_nand/raw/Whimory/Core/FTL/yaFTL.c | 6343 +++++ .../raw/Whimory/Core/FTL/yaFTLTypes.h | 335 + .../raw/Whimory/Core/FTL/yaFTL_BTOC.c | 371 + .../raw/Whimory/Core/FTL/yaFTL_BTOC.h | 51 + .../raw/Whimory/Core/FTL/yaFTL_Defines.h | 121 + .../raw/Whimory/Core/FTL/yaFTL_gc.c | 1716 ++ .../raw/Whimory/Core/FTL/yaFTL_gc.h | 40 + .../raw/Whimory/Core/FTL/yaFTL_meta.h | 27 + .../raw/Whimory/Core/FTL/yaFTL_meta_ppn.c | 131 + .../raw/Whimory/Core/FTL/yaFTL_meta_ppn.h | 116 + .../raw/Whimory/Core/FTL/yaFTL_meta_raw.c | 115 + .../raw/Whimory/Core/FTL/yaFTL_meta_raw.h | 84 + .../raw/Whimory/Core/FTL/yaFTL_whoami.h | 18 + .../raw/Whimory/Core/VFL/VFLBuffer.c | 399 + .../raw/Whimory/Core/VFL/VFLBuffer.h | 104 + .../raw/Whimory/Core/VFL/VFLInterface.c | 2374 ++ .../raw/Whimory/Core/VFL/VFLTypes.h | 233 + .../raw/Whimory/Core/VFL/VSVFLInterface.c | 4255 +++ .../raw/Whimory/Core/VFL/VSVFLTypes.h | 218 + .../flash_nand/raw/Whimory/Exam/ANDStats.c | 255 + .../flash_nand/raw/Whimory/Exam/ANDStats.h | 21 + drivers/flash_nand/raw/Whimory/Exam/WMRExam.c | 1000 + drivers/flash_nand/raw/Whimory/Exam/WMRExam.h | 136 + drivers/flash_nand/raw/Whimory/Inc/ANDTypes.h | 541 + drivers/flash_nand/raw/Whimory/Inc/FIL.h | 212 + drivers/flash_nand/raw/Whimory/Inc/FILTypes.h | 62 + drivers/flash_nand/raw/Whimory/Inc/FPart.h | 155 + drivers/flash_nand/raw/Whimory/Inc/FTL.h | 265 + drivers/flash_nand/raw/Whimory/Inc/PPN_FIL.h | 166 + drivers/flash_nand/raw/Whimory/Inc/VFL.h | 171 + .../flash_nand/raw/Whimory/Inc/WMRConfig.h | 97 + drivers/flash_nand/raw/Whimory/Inc/WMRTest.h | 22 + drivers/flash_nand/raw/Whimory/Test/FILTest.c | 901 + drivers/flash_nand/raw/export.txt | 5 + drivers/flash_nand/raw/library.mk | 58 + drivers/flash_nand/raw/raw_nand.c | 88 + drivers/flash_nand/raw/rules.mk | 35 + drivers/flash_nand/rules.mk | 26 + drivers/flash_nor/nor.c | 112 + drivers/flash_nor/rules.mk | 19 + drivers/flash_nor/spi/rules.mk | 19 + drivers/flash_nor/spi/spi_flash.c | 632 + drivers/hdc/boot/rules.mk | 19 + drivers/hdc/boot/sw_h2fmi.c | 115 + drivers/hdc/boot/sw_h2fmi_private.h | 29 + drivers/hdc/hdc.c | 77 + drivers/hdc/hdc_private.h | 44 + drivers/hdc/rules.mk | 19 + drivers/hdmi/controller.c | 203 + drivers/hdmi/debug.c | 113 + drivers/hdmi/device.c | 191 + drivers/hdmi/edid.h | 377 + drivers/hdmi/process_edid.c | 1738 ++ drivers/hdmi/rules.mk | 18 + drivers/idt/idtp9022/idtp9022.c | 197 + drivers/idt/idtp9022/rules.mk | 20 + drivers/iic/debug.c | 160 + drivers/iic/rules.mk | 17 + drivers/iic/swiic.c | 355 + drivers/intel/thunderbolt_nhi/nhi.c | 752 + drivers/intel/thunderbolt_nhi/nhi_protocol.h | 72 + drivers/intel/thunderbolt_nhi/rules.mk | 17 + drivers/nvme/nvme.c | 2194 ++ drivers/nvme/nvme_blockdev.c | 326 + drivers/nvme/nvme_blockdev.h | 17 + drivers/nvme/nvme_protocol.h | 392 + drivers/nvme/rules.mk | 17 + drivers/nxp/cbtl1610/cbtl1610.c | 455 + drivers/nxp/cbtl1610/rules.mk | 17 + drivers/pci/pci.c | 1379 + drivers/pci/pci_private.h | 65 + drivers/pci/rules.mk | 16 + drivers/power/hdqgauge/hdqgauge.c | 1602 ++ drivers/power/hdqgauge/rules.mk | 17 + .../include/drivers/primecell/pl080dmac.h | 46 + drivers/primecell/pl080dmac/pl080dmac.c | 329 + drivers/primecell/pl080dmac/pl080dmac_regs.h | 36 + drivers/primecell/pl080dmac/rules.mk | 18 + drivers/primecell/pl192vic/pl192vic.c | 300 + drivers/primecell/pl192vic/pl192vic.h | 47 + drivers/primecell/pl192vic/rules.mk | 15 + drivers/samsung/aes/aes.c | 604 + drivers/samsung/aes/aes.h | 100 + drivers/samsung/aes/rules.mk | 18 + drivers/samsung/arm7iop/arm7.c | 101 + drivers/samsung/arm7iop/rules.mk | 14 + drivers/samsung/arm7m/arm7m.c | 173 + .../arm7m/include/drivers/arm7m/arm7m.h | 25 + drivers/samsung/arm7m/rules.mk | 14 + drivers/samsung/clcd_v2/clcd.c | 178 + drivers/samsung/clcd_v2/clcd_regs.h | 74 + .../clcd_v2/include/drivers/clcd_v2/clcd.h | 20 + drivers/samsung/clcd_v2/rules.mk | 19 + drivers/samsung/displayport/displayport.c | 2007 ++ .../include/drivers/displayport/displayport.h | 31 + drivers/samsung/displayport/regs.h | 912 + drivers/samsung/displayport/rules.mk | 17 + drivers/samsung/drex/drex.c | 131 + drivers/samsung/drex/drex.h | 42 + drivers/samsung/drex/rules.mk | 15 + drivers/samsung/dwi/dwi.c | 47 + drivers/samsung/dwi/dwi.h | 48 + drivers/samsung/dwi/rules.mk | 15 + drivers/samsung/gpio/gpio.c | 209 + drivers/samsung/gpio/gpio.h | 85 + drivers/samsung/gpio/rules.mk | 16 + drivers/samsung/hdmi8947/hdmi.c | 1848 ++ drivers/samsung/hdmi8947/hdmi.h | 70 + drivers/samsung/hdmi8947/hdmi_static_config.c | 919 + drivers/samsung/hdmi8947/regs.h | 998 + drivers/samsung/hdmi8947/rules.mk | 16 + drivers/samsung/mipi/dsim.c | 507 + drivers/samsung/mipi/dsim.h | 171 + drivers/samsung/mipi/rules.mk | 16 + .../samsung/pke/AppleS5L8900XPKE-hardware.c | 717 + .../samsung/pke/AppleS5L8900XPKE-hardware.h | 194 + drivers/samsung/pke/DevPke_cal_R2modM.S | 930 + drivers/samsung/pke/pke.c | 87 + drivers/samsung/pke/rules.mk | 21 + .../rgbout/include/drivers/rgbout/rgbout.h | 20 + drivers/samsung/rgbout/rgbout.c | 107 + drivers/samsung/rgbout/rgbout_regs.h | 29 + drivers/samsung/rgbout/rules.mk | 19 + drivers/samsung/rosc/rosc.c | 113 + drivers/samsung/rosc/rosc.h | 35 + drivers/samsung/rosc/rules.mk | 16 + drivers/samsung/sha1/rules.mk | 19 + drivers/samsung/sha1/sha1.c | 212 + drivers/samsung/sha1/sha1.h | 98 + drivers/samsung/spi/rules.mk | 15 + drivers/samsung/spi/spi.c | 721 + drivers/samsung/spi/spi.h | 136 + drivers/samsung/swi/rules.mk | 15 + drivers/samsung/swi/swi.c | 43 + drivers/samsung/swi/swi.h | 40 + drivers/samsung/timer/rules.mk | 15 + drivers/samsung/timer/timer.c | 484 + drivers/samsung/timer/timer.h | 121 + drivers/samsung/uart/rules.mk | 15 + drivers/samsung/uart/uart.c | 683 + drivers/samsung/uart/uart.h | 134 + drivers/samsung/usbphy/rules.mk | 15 + drivers/samsung/usbphy/usbphy.c | 304 + drivers/samsung/usbphy/usbphy.h | 52 + drivers/sha1/mozilla_sha.c | 164 + drivers/sha1/mozilla_sha.h | 57 + drivers/sha1/rules.mk | 18 + drivers/sha1/sha1.c | 97 + drivers/sha1/tests.c | 41 + drivers/sha1/tests.mk | 21 + drivers/spi/gpio_spi.c | 103 + drivers/spi/rules.mk | 15 + drivers/synopsys/mipi/dsim.c | 751 + drivers/synopsys/mipi/dsim.h | 300 + .../synopsys/mipi/include/drivers/mipi/mipi.h | 47 + drivers/synopsys/mipi/rules.mk | 18 + drivers/synopsys/usbotg/rules.mk | 23 + drivers/synopsys/usbotg/synopsys_otg.c | 1691 ++ drivers/synopsys/usbotg/synopsys_otg_regs.h | 779 + drivers/thunderbolt/ipipe.c | 467 + drivers/thunderbolt/ipipe_protocol.h | 22 + drivers/thunderbolt/rules.mk | 61 + drivers/thunderbolt/tbt_control_port.c | 624 + drivers/thunderbolt/tbt_control_port.h | 37 + drivers/thunderbolt/tbt_cp_crc.c | 109 + drivers/thunderbolt/tbt_cp_crc.h | 16 + drivers/thunderbolt/tbt_protocol.h | 61 + drivers/thunderbolt/tbt_xd_packet.h | 108 + drivers/thunderbolt/tbt_xdomain.c | 265 + drivers/thunderbolt/tbt_xdomain.h | 23 + drivers/thunderbolt/thunderboot.c | 549 + drivers/thunderbolt/thunderboot_debug.c | 176 + drivers/thunderbolt/thunderboot_protocol.h | 48 + drivers/thunderbolt/uuid.c | 131 + drivers/thunderbolt/uuid.h | 31 + drivers/ti/sn2400/rules.mk | 21 + drivers/ti/sn2400/sn2400.c | 449 + drivers/ti/ths7383/rules.mk | 17 + drivers/ti/ths7383/ths7383.c | 281 + drivers/uart/16x50/16x50.c | 139 + drivers/uart/16x50/16x50.h | 95 + drivers/uart/16x50/rules.mk | 18 + drivers/uart/rules.mk | 17 + drivers/uart/uart.c | 157 + drivers/usb/rules.mk | 55 + drivers/usb/usb.c | 128 + drivers/usb/usb_controller.c | 115 + drivers/usb/usb_core.c | 1216 + drivers/usb/usb_debug.c | 263 + drivers/usb/usb_dfu.c | 364 + drivers/usb/usb_dockfifo_controller.c | 904 + drivers/usb/usb_serial.c | 389 + drivers/usb/usb_transfer.c | 416 + include/AssertMacros.h | 1165 + include/Availability.h | 19 + include/arch.h | 96 + include/assert.h | 20 + include/c++/iostream.h | 78 + include/cbuffer.h | 320 + include/compiler.h | 96 + include/debug.h | 121 + include/drivers/aes.h | 76 + include/drivers/anc_boot.h | 24 + include/drivers/apcie.h | 56 + include/drivers/asp.h | 9 + include/drivers/buttons.h | 34 + include/drivers/charger.h | 38 + include/drivers/consistent_debug.h | 88 + include/drivers/csi.h | 102 + include/drivers/dart.h | 28 + include/drivers/display.h | 116 + include/drivers/displayAV.h | 110 + include/drivers/display_pmu.h | 24 + include/drivers/displayport.h | 207 + include/drivers/dither.h | 32 + include/drivers/dma.h | 119 + include/drivers/dpb.h | 27 + include/drivers/dram.h | 86 + include/drivers/edgeic.h | 25 + include/drivers/ethernet.h | 85 + include/drivers/flash_nand.h | 30 + include/drivers/flash_nor.h | 36 + include/drivers/gasgauge.h | 69 + include/drivers/hdc.h | 45 + include/drivers/hdmi.h | 89 + include/drivers/iic.h | 34 + include/drivers/iis.h | 32 + include/drivers/ipipe.h | 24 + include/drivers/mcu.h | 28 + include/drivers/mipi.h | 58 + include/drivers/miu.h | 25 + include/drivers/nand_boot.h | 25 + include/drivers/nand_device_tree.h | 19 + include/drivers/nand_syscfg.h | 23 + include/drivers/nvme.h | 84 + include/drivers/pci.h | 176 + include/drivers/phy.h | 37 + include/drivers/pke.h | 27 + include/drivers/power.h | 213 + include/drivers/prc.h | 23 + include/drivers/process_edid.h | 42 + include/drivers/radio.h | 44 + include/drivers/reconfig.h | 83 + include/drivers/rsecc.h | 31 + include/drivers/sha1.h | 32 + include/drivers/shmcon.h | 28 + include/drivers/spi.h | 32 + include/drivers/sw_h2fmi.h | 23 + include/drivers/thermal.h | 56 + include/drivers/thunderbolt/nhi.h | 42 + include/drivers/thunderbolt/thunderboot.h | 29 + include/drivers/tristar.h | 25 + include/drivers/uart.h | 49 + include/drivers/usb/synopsys_otg_public.h | 95 + include/drivers/usb/usb_chap9.h | 213 + include/drivers/usb/usb_controller.h | 62 + include/drivers/usb/usb_core.h | 149 + include/drivers/usb/usb_debug.h | 13 + include/drivers/usb/usb_public.h | 53 + include/drivers/usbphy.h | 40 + include/drivers/wpc.h | 23 + include/endian_tools.h | 51 + include/gcc/limits.h | 120 + include/gcc/stdarg.h | 133 + include/gcc/syslimits.h | 8 + include/lib/DERApTicket.h | 61 + include/lib/Image2Format.h | 111 + include/lib/blockdev.h | 82 + include/lib/cbuf.h | 51 + include/lib/cksum.h | 45 + include/lib/devicetree.h | 64 + include/lib/env.h | 53 + include/lib/fs.h | 120 + include/lib/heap.h | 101 + include/lib/image.h | 219 + include/lib/image4_spi.h | 59 + include/lib/libc.h | 170 + include/lib/libiboot.h | 31 + include/lib/lzss.h | 35 + include/lib/macho.h | 115 + include/lib/mib.h | 219 + include/lib/mib_def.h | 143 + include/lib/net.h | 28 + include/lib/net/arp.h | 44 + include/lib/net/callbacks.h | 41 + include/lib/net/ethernet.h | 39 + include/lib/net/icmp.h | 29 + include/lib/net/ipv4.h | 35 + include/lib/net/mbuf.h | 54 + include/lib/net/udp.h | 32 + include/lib/net/xp.h | 38 + include/lib/nonce.h | 28 + include/lib/nvram.h | 27 + include/lib/paint.h | 204 + include/lib/paniclog.h | 24 + include/lib/partition.h | 23 + include/lib/pki.h | 27 + include/lib/profile.h | 52 + include/lib/ramdisk.h | 21 + include/lib/random.h | 31 + include/lib/syscfg.h | 101 + include/lib/tftp.h | 23 + include/lib/ticket.h | 35 + include/libkern/OSByteOrder.h | 10 + include/list.h | 230 + include/non_posix_types.h | 40 + include/platform.h | 299 + include/platform/breadcrumbs.h | 37 + include/platform/chipid.h | 56 + include/platform/clocks.h | 47 + include/platform/gpio.h | 93 + include/platform/int.h | 62 + include/platform/memmap_defaults.h | 30 + include/platform/miu.h | 26 + include/platform/pmgr.h | 151 + include/platform/power.h | 40 + include/platform/timer.h | 94 + include/platform/tunables.h | 69 + include/posix/ctype.h | 11 + include/posix/errno.h | 11 + include/posix/machine/endian.h | 1 + include/posix/stdbool.h | 26 + include/posix/stdint.h | 11 + include/posix/stdio.h | 11 + include/posix/stdlib.h | 11 + include/posix/string.h | 11 + include/posix/sys/cdefs.h | 15 + include/posix/sys/errno.h | 214 + include/posix/sys/types.h | 146 + include/sys.h | 299 + include/sys/boot.h | 72 + include/sys/callout.h | 41 + include/sys/hash.h | 39 + include/sys/linker_set.h | 68 + include/sys/menu.h | 98 + include/sys/security.h | 72 + include/sys/task.h | 190 + include/target.h | 91 + lib/blockdev/blockdev.c | 541 + lib/blockdev/debug.c | 260 + lib/blockdev/library.mk | 31 + lib/blockdev/mem_blockdev.c | 77 + lib/blockdev/rules.mk | 13 + lib/blockdev/subdev.c | 92 + lib/blockdev/tests.c | 470 + lib/blockdev/tests.mk | 27 + lib/cbuf/cbuf.c | 105 + lib/cbuf/library.mk | 29 + lib/cbuf/rules.mk | 13 + lib/cksum/adler32.c | 81 + lib/cksum/arm/adler32vec.S | 341 + lib/cksum/arm64/adler32vec.S | 318 + lib/cksum/crc.c | 121 + lib/cksum/crc32.c | 53 + lib/cksum/debug.c | 35 + lib/cksum/library.mk | 33 + lib/cksum/rules.mk | 13 + lib/cksum/siphash.c | 220 + lib/cksum/tests.c | 230 + lib/cksum/tests.mk | 39 + lib/devicetree/devicetree.c | 682 + lib/devicetree/devicetree_debug.c | 67 + lib/devicetree/devicetree_load.c | 150 + lib/devicetree/devicetree_private.h | 32 + lib/devicetree/fuzz.c | 105 + lib/devicetree/fuzzing-dict.txt | 22 + lib/devicetree/library.mk | 29 + lib/devicetree/rules.mk | 14 + lib/devicetree/tests-fuzz.mk | 23 + lib/devicetree/tests.c | 876 + lib/devicetree/tests.mk | 22 + lib/effaceable/README | 9 + lib/effaceable/common/effaceable_context.h | 64 + lib/effaceable/common/effaceable_delegation.h | 22 + lib/effaceable/common/effaceable_locker.h | 38 + lib/effaceable/common/effaceable_nand_core.c | 465 + lib/effaceable/common/effaceable_nand_core.h | 151 + lib/effaceable/common/effaceable_nor_core.c | 214 + lib/effaceable/common/effaceable_nor_core.h | 69 + .../common/effaceable_private_types.h | 39 + .../common/effaceable_storage_core.c | 1553 ++ .../common/effaceable_storage_core.h | 172 + .../common/effaceable_storage_dev.h | 31 + .../include/AppleEffaceableStorageFormat.h | 98 + .../include/AppleEffaceableStorageKeys.h | 130 + .../common/include/effaceable_contract.h | 184 + .../common/include/effaceable_debug.h | 88 + lib/effaceable/common/queue.h | 768 + lib/effaceable/common/rules.mk | 19 + lib/effaceable/docs/notes_to_auditors.txt | 18 + lib/effaceable/iboot/effaceable_cmd.c | 186 + lib/effaceable/iboot/effaceable_storage.c | 187 + lib/effaceable/iboot/effaceable_system.c | 161 + lib/effaceable/iboot/include/lib/effaceable.h | 42 + .../iboot/include/lib/effaceable_impl.h | 34 + lib/effaceable/iboot/nand/effaceable_nand.c | 146 + .../iboot/nand/include/lib/effaceable_nand.h | 25 + lib/effaceable/iboot/nand/rules.mk | 32 + lib/effaceable/iboot/nor/effaceable_nor.c | 221 + .../iboot/nor/include/lib/effaceable_nor.h | 25 + lib/effaceable/iboot/nor/rules.mk | 30 + lib/effaceable/iboot/rules.mk | 25 + lib/effaceable/iokit/AppleEffaceableNAND.cpp | 232 + lib/effaceable/iokit/AppleEffaceableNAND.h | 63 + lib/effaceable/iokit/AppleEffaceableNOR.cpp | 158 + lib/effaceable/iokit/AppleEffaceableNOR.h | 54 + .../iokit/AppleEffaceableStorage.cpp | 545 + lib/effaceable/iokit/AppleEffaceableStorage.h | 132 + .../AppleEffaceableStorageUserClient.cpp | 301 + .../iokit/AppleEffaceableStorageUserClient.h | 33 + lib/effaceable/iokit/Info.plist | 77 + lib/effaceable/ios/effaceable.c | 537 + lib/effaceable/ios/effaceable.h | 38 + lib/env/env.c | 560 + lib/env/library.mk | 27 + lib/env/rules.mk | 13 + lib/env/tests.c | 231 + lib/env/tests.mk | 20 + lib/fs/debug.c | 178 + lib/fs/fs.c | 423 + lib/fs/hfs/cache.c | 154 + lib/fs/hfs/fuzz.c | 89 + lib/fs/hfs/hfs.c | 1372 + lib/fs/hfs/hfs.h | 134 + lib/fs/hfs/hfs_format.h | 746 + lib/fs/hfs/hfs_fs.c | 385 + lib/fs/hfs/library.mk | 32 + lib/fs/hfs/rules.mk | 16 + lib/fs/hfs/test-hfs-helper.sh | 31 + lib/fs/hfs/tests-common.mk | 30 + lib/fs/hfs/tests-fuzz.mk | 24 + lib/fs/hfs/tests.c | 180 + lib/fs/hfs/tests.mk | 29 + lib/fs/library.mk | 29 + lib/fs/rules.mk | 15 + lib/heap/heap.c | 1296 + lib/heap/libc_stub.c | 57 + lib/heap/library.mk | 28 + lib/heap/rules.mk | 14 + lib/heap/tests-common.mk | 23 + lib/heap/tests-debugging.mk | 18 + lib/heap/tests.c | 856 + lib/heap/tests.mk | 18 + lib/image/debug.c | 195 + lib/image/image.c | 323 + lib/image/image3/Image3.c | 1319 + lib/image/image3/Image3.h | 383 + lib/image/image3/Image3Format.h | 135 + lib/image/image3/Image3SuperBlock.h | 76 + lib/image/image3/image3_wrapper.c | 1473 + lib/image/image3/image3_wrapper.h | 56 + lib/image/image3/rules.mk | 21 + lib/image/image4/image4_partial.c | 234 + lib/image/image4/image4_partial.h | 35 + lib/image/image4/image4_wrapper.c | 1356 + lib/image/image4/image4_wrapper.h | 59 + lib/image/image4/rules.mk | 40 + lib/image/rules.mk | 14 + lib/libbuiltin/arm/builtin_divide.c | 450 + lib/libbuiltin/arm/rules.mk | 16 + lib/libbuiltin/library.mk | 41 + lib/libc++/iostream.cpp | 17 + lib/libc++/library.mk | 33 + lib/libc++/misc.cpp | 14 + lib/libc++/new.cpp | 40 + lib/libc++/rules.mk | 19 + lib/libc/arm/bcopy.S | 385 + lib/libc/arm/bzero.S | 145 + lib/libc/arm/rules.mk | 24 + lib/libc/arm/strlen.S | 65 + lib/libc/arm64/asm.h | 47 + lib/libc/arm64/bcopy.S | 294 + lib/libc/arm64/bzero.S | 147 + lib/libc/arm64/memcpy.S | 24 + lib/libc/arm64/memset.S | 39 + lib/libc/arm64/rules.mk | 21 + lib/libc/atoi.c | 42 + lib/libc/ctype.c | 128 + lib/libc/endian.c | 66 + lib/libc/library.mk | 63 + lib/libc/log2.c | 20 + lib/libc/memchr.c | 29 + lib/libc/memcmp.c | 42 + lib/libc/memcpy_chk.c | 28 + lib/libc/memmove_chk.c | 28 + lib/libc/memscan.c | 25 + lib/libc/memset_chk.c | 28 + lib/libc/misc.c | 35 + lib/libc/printf.c | 482 + lib/libc/printf_chk.c | 48 + lib/libc/qsort.c | 194 + lib/libc/stdio.c | 46 + lib/libc/stdlib.c | 38 + lib/libc/strchr.c | 21 + lib/libc/strcmp.c | 25 + lib/libc/strcoll.c | 18 + lib/libc/strdup.c | 25 + lib/libc/strlcat.c | 41 + lib/libc/strlcat_chk.c | 27 + lib/libc/strlcpy.c | 36 + lib/libc/strlcpy_chk.c | 28 + lib/libc/strlen.c | 25 + lib/libc/strncmp.c | 26 + lib/libc/strnicmp.c | 38 + lib/libc/strnlen.c | 22 + lib/libc/strpbrk.c | 28 + lib/libc/strrchr.c | 29 + lib/libc/strsep.c | 67 + lib/libc/strspn.c | 32 + lib/libc/strstr.c | 30 + lib/libc/strtok.c | 35 + lib/libc/strtol.c | 136 + lib/libc/strtoll.c | 136 + lib/libc/strtoul.c | 114 + lib/libc/strtoull.c | 114 + lib/libc/strxfrm.c | 26 + lib/libc/test_printf.c | 401 + lib/libc/tests-base.mk | 17 + lib/libc/tests-release.mk | 18 + lib/libc/tests.mk | 15 + lib/libcorecrypto/library.mk | 16 + lib/lzss/arm/lzssdec.S | 203 + lib/lzss/arm64/lzssdec.S | 179 + lib/lzss/library.mk | 29 + lib/lzss/lzss.c | 124 + lib/lzss/rules.mk | 13 + lib/lzss/tests.c | 76 + lib/lzss/tests.mk | 20 + lib/macho/boot.h | 125 + lib/macho/dt.c | 874 + lib/macho/kernelcache.c | 793 + lib/macho/macho.c | 544 + lib/macho/macho_header.h | 597 + lib/macho/monitor.c | 89 + lib/macho/rules.mk | 23 + lib/mib/header.mk | 24 + lib/mib/library.mk | 37 + lib/mib/mib.base | 80 + lib/mib/mib.c | 313 + lib/mib/mib_gen_def.awk | 58 + lib/mib/mib_gen_hdr.awk | 53 + lib/mib/rules.mk | 11 + lib/net/arp.c | 224 + lib/net/callbacks.c | 71 + lib/net/debug.c | 44 + lib/net/ethernet.c | 152 + lib/net/icmp.c | 103 + lib/net/ipv4.c | 159 + lib/net/mbuf.c | 125 + lib/net/net.c | 116 + lib/net/rules.mk | 25 + lib/net/udp.c | 94 + lib/net/xp.c | 78 + lib/nonce/library.mk | 27 + lib/nonce/nonce.c | 210 + lib/nonce/rules.mk | 12 + lib/nvram/fuzz.c | 41 + lib/nvram/library.mk | 27 + lib/nvram/nvram.c | 555 + lib/nvram/rules.mk | 20 + lib/nvram/tests-common.mk | 24 + lib/nvram/tests-fuzz.mk | 24 + lib/nvram/tests.c | 51 + lib/nvram/tests.mk | 22 + lib/paint/library.mk | 27 + lib/paint/paint.c | 1625 ++ lib/paint/rules.mk | 15 + lib/paint/tests.c | 212 + lib/paint/tests.mk | 26 + lib/paniclog/library.mk | 27 + lib/paniclog/paniclog.c | 179 + lib/paniclog/rules.mk | 12 + lib/partition/gpt.c | 153 + lib/partition/library.mk | 31 + lib/partition/lwvm.c | 270 + lib/partition/mbr.c | 47 + lib/partition/partition.c | 148 + lib/partition/partition_private.h | 41 + lib/partition/rules.mk | 15 + lib/pki/apple_ca.h | 102 + lib/pki/chain-validation.c | 662 + lib/pki/debug.c | 103 + lib/pki/fake_ca.h | 372 + lib/pki/libDER/DER_CertCrl.c | 319 + lib/pki/libDER/DER_CertCrl.h | 233 + lib/pki/libDER/DER_Decode.c | 645 + lib/pki/libDER/DER_Decode.h | 219 + lib/pki/libDER/DER_Digest.c | 162 + lib/pki/libDER/DER_Digest.h | 70 + lib/pki/libDER/DER_Encode.c | 342 + lib/pki/libDER/DER_Encode.h | 98 + lib/pki/libDER/DER_Keys.c | 167 + lib/pki/libDER/DER_Keys.h | 99 + lib/pki/libDER/asn1Types.h | 89 + lib/pki/libDER/libDER.h | 62 + lib/pki/libDER/libDER_config.h | 89 + lib/pki/libDER/oids.c | 516 + lib/pki/libDER/oids.h | 108 + lib/pki/libGiants/giantDebug.c | 63 + lib/pki/libGiants/giantDebug.h | 101 + lib/pki/libGiants/giantExternal.c | 191 + lib/pki/libGiants/giantExternal.h | 59 + lib/pki/libGiants/giantIntegers.c | 1096 + lib/pki/libGiants/giantIntegers.h | 286 + lib/pki/libGiants/giantMemutils.c | 48 + lib/pki/libGiants/giantMod.c | 722 + lib/pki/libGiants/giantMod.h | 124 + lib/pki/libGiants/giantPlatform.h | 370 + lib/pki/libGiants/giantPlatformEmulation.h | 181 + lib/pki/libGiants/giantPortCommon.h | 98 + lib/pki/libGiants/giantPort_C.c | 143 + lib/pki/libGiants/giantPort_Generic.h | 160 + lib/pki/libGiants/giantTypes.h | 42 + lib/pki/libGiantsUtils/GIReturnString.c | 25 + lib/pki/libGiantsUtils/GIReturnString.h | 20 + lib/pki/libgRSA/libgRSA.c | 383 + lib/pki/libgRSA/libgRSA.h | 187 + lib/pki/libgRSA/libgRSA_DER.c | 440 + lib/pki/libgRSA/libgRSA_DER.h | 120 + lib/pki/libgRSA/libgRSA_config.h | 48 + lib/pki/libgRSA/libgRSA_priv.c | 86 + lib/pki/libgRSA/libgRSA_priv.h | 56 + lib/pki/libgRSA/rsaGiantKey.c | 38 + lib/pki/libgRSA/rsaGiantKey.h | 78 + lib/pki/libgRSA/rsaPadding.c | 532 + lib/pki/libgRSA/rsaPadding.h | 97 + lib/pki/libgRSA/rsaRawKey.c | 120 + lib/pki/libgRSA/rsaRawKey.h | 72 + lib/pki/libgRSA/rsaTypes.h | 66 + lib/pki/library.mk | 47 + lib/pki/rules.mk | 25 + lib/pki/tests/fake-hierarchy-img3-test.txt | 86 + lib/pki/tests/intermediate-cert.der | Bin 0 -> 953 bytes lib/pki/tests/intermediate-key.pem | 27 + lib/pki/tests/make-img3-specs | 39 + lib/pki/tests/to_binary_hash.c | 43 + lib/power/power.c | 1642 ++ lib/power/rules.mk | 13 + lib/profile/profile.c | 65 + lib/profile/rules.mk | 22 + lib/ramdisk/library.mk | 27 + lib/ramdisk/ramdisk.c | 130 + lib/ramdisk/rules.mk | 12 + lib/random/library.mk | 27 + lib/random/random.c | 97 + lib/random/rules.mk | 13 + lib/syscfg/library.mk | 27 + lib/syscfg/rules.mk | 13 + lib/syscfg/syscfg.c | 342 + lib/syscfg/tests.c | 252 + lib/syscfg/tests.mk | 26 + lib/tftp/debug.c | 87 + lib/tftp/rules.mk | 17 + lib/tftp/tftp.c | 293 + lib/ticket/DERApTicket.c | 544 + lib/ticket/fuzz.c | 132 + lib/ticket/library.mk | 30 + lib/ticket/rules.mk | 17 + lib/ticket/tests-fuzz.mk | 66 + lib/ticket/ticket.c | 557 + makefiles/build.mk | 186 + makefiles/config.mk | 99 + makefiles/device_map.mk | 218 + makefiles/format-headerfile.awk | 73 + makefiles/headers.mk | 47 + makefiles/lib.mk | 100 + makefiles/libraries.mk | 47 + makefiles/macros.mk | 50 + makefiles/main-nested-module.mk | 52 + makefiles/main.mk | 537 + makefiles/test.mk | 97 + makefiles/tests.mk | 129 + makefiles/tools.mk | 97 + .../defaults/chipid_get_raw_production_mode.c | 23 + platform/defaults/formatter.awk | 37 + platform/defaults/library.mk | 49 + platform/defaults/lister.awk | 18 + platform/defaults/platform.defaults | 135 + .../defaults/platform_get_default_gpio_cfg.c | 34 + .../defaults/platform_get_memory_region.c | 82 + .../defaults/platform_get_spi_frequency.c | 23 + platform/defaults/platform_memory_map.c | 51 + platform/defaults/platform_restore_system.c | 40 + platform/defaults/rules.mk | 52 + .../target_get_boot_battery_capacity.c | 12 + .../target_get_precharge_gg_flag_mask.c | 17 + platform/defaults/target_get_property.c | 17 + platform/defaults/target_get_property_base.c | 49 + platform/defaults/template.c | 27 + platform/generic/breadcrumbs.c | 114 + platform/generic/default_mib.c | 53 + platform/generic/defaults.c | 12 + platform/generic/library.mk | 36 + platform/generic/platform_dep.c | 402 + platform/generic/platform_indep.c | 347 + platform/generic/platform_info.S | 47 + platform/generic/pmgr/pmgr_binning.c | 294 + platform/generic/pmgr/pmgr_binning_menu.c | 344 + platform/generic/pmgr/rules.mk | 42 + platform/generic/rules.mk | 48 + platform/generic/target_dep.c | 29 + platform/generic/target_indep.c | 40 + platform/generic/target_pass_boot_manifest.c | 247 + platform/s5l8747x/asm.S | 42 + platform/s5l8747x/chipid/chipid.c | 146 + platform/s5l8747x/chipid/rules.mk | 15 + platform/s5l8747x/clocks/clocks.c | 504 + platform/s5l8747x/clocks/rules.mk | 15 + platform/s5l8747x/include/platform/gpiodef.h | 53 + .../s5l8747x/include/platform/image_devices.h | 25 + platform/s5l8747x/include/platform/memmap.h | 125 + .../s5l8747x/include/platform/pinconfig.h | 79 + .../s5l8747x/include/platform/soc/chipid.h | 26 + .../s5l8747x/include/platform/soc/clocks.h | 67 + .../s5l8747x/include/platform/soc/hwclocks.h | 60 + .../s5l8747x/include/platform/soc/hwisr.h | 79 + .../s5l8747x/include/platform/soc/hwregbase.h | 106 + platform/s5l8747x/include/platform/soc/miu.h | 40 + .../s5l8747x/include/platform/soc/power.h | 33 + platform/s5l8747x/include/platform/soc/sdo.h | 23 + .../s5l8747x/include/platform/trampoline.h | 20 + .../s5l8747x/include/platform/usbconfig.h | 21 + platform/s5l8747x/init.c | 855 + platform/s5l8747x/miu/miu.c | 102 + platform/s5l8747x/miu/rules.mk | 15 + platform/s5l8747x/pmgr/pmgr.c | 51 + platform/s5l8747x/pmgr/rules.mk | 17 + platform/s5l8747x/rules.mk | 92 + platform/s5l8940x/amc/amc_s5l8940x.c | 269 + platform/s5l8940x/amc/amc_s5l8947x.c | 135 + platform/s5l8940x/amc/rules.mk | 21 + platform/s5l8940x/chipid/chipid.c | 288 + platform/s5l8940x/chipid/rules.mk | 15 + .../s5l8940x/include/platform/amcconfig.h | 12 + .../include/platform/amcconfig_s5l8940x.h | 143 + .../include/platform/amcconfig_s5l8942x.h | 143 + .../include/platform/amcconfig_s5l8947x.h | 135 + .../s5l8940x/include/platform/amgconfig.h | 28 + .../s5l8940x/include/platform/ampconfig.h | 36 + .../s5l8940x/include/platform/boot_pins.h | 27 + .../include/platform/boot_pins_s5l8940x.h | 92 + .../include/platform/boot_pins_s5l8942x.h | 92 + .../include/platform/boot_pins_s5l8947x.h | 76 + platform/s5l8940x/include/platform/gpiodef.h | 26 + .../include/platform/gpiodef_s5l8940x.h | 58 + .../include/platform/gpiodef_s5l8942x.h | 58 + .../include/platform/gpiodef_s5l8947x.h | 55 + .../s5l8940x/include/platform/image_devices.h | 33 + .../s5l8940x/include/platform/memconfig.h | 19 + platform/s5l8940x/include/platform/memmap.h | 143 + .../include/platform/pinconfig_s5l8940x.h | 310 + .../include/platform/pinconfig_s5l8942x.h | 281 + .../include/platform/pinconfig_s5l8947x.h | 201 + .../s5l8940x/include/platform/soc/chipid.h | 37 + .../s5l8940x/include/platform/soc/display.h | 41 + .../include/platform/soc/display_timings.h | 222 + .../s5l8940x/include/platform/soc/hwclocks.h | 130 + .../include/platform/soc/hwdmachannels.h | 20 + .../platform/soc/hwdmachannels_s5l8940x.h | 44 + .../platform/soc/hwdmachannels_s5l8942x.h | 37 + .../platform/soc/hwdmachannels_s5l8947x.h | 36 + .../s5l8940x/include/platform/soc/hwisr.h | 198 + .../s5l8940x/include/platform/soc/hwregbase.h | 202 + platform/s5l8940x/include/platform/soc/miu.h | 165 + platform/s5l8940x/include/platform/soc/pmgr.h | 465 + .../s5l8940x/include/platform/trampoline.h | 20 + .../s5l8940x/include/platform/usbconfig.h | 30 + platform/s5l8940x/init.c | 1181 + platform/s5l8940x/iop_init.c | 208 + platform/s5l8940x/miu/miu.c | 319 + platform/s5l8940x/miu/rules.mk | 15 + platform/s5l8940x/pinconfig_s5l8940x.c | 317 + platform/s5l8940x/pinconfig_s5l8942x.c | 288 + platform/s5l8940x/pinconfig_s5l8947x.c | 208 + platform/s5l8940x/pmgr/pmgr.c | 1306 + platform/s5l8940x/pmgr/rules.mk | 17 + platform/s5l8940x/rules.mk | 124 + platform/s5l8945x/amc/amc.c | 169 + platform/s5l8945x/amc/rules.mk | 16 + platform/s5l8945x/chipid/chipid.c | 231 + platform/s5l8945x/chipid/rules.mk | 15 + .../s5l8945x/include/platform/amcconfig.h | 155 + .../s5l8945x/include/platform/amgconfig.h | 26 + platform/s5l8945x/include/platform/gpiodef.h | 61 + .../s5l8945x/include/platform/image_devices.h | 33 + .../s5l8945x/include/platform/memconfig.h | 19 + platform/s5l8945x/include/platform/memmap.h | 125 + .../s5l8945x/include/platform/pinconfig.h | 330 + .../s5l8945x/include/platform/soc/chipid.h | 45 + .../s5l8945x/include/platform/soc/display.h | 41 + .../include/platform/soc/display_timings.h | 62 + .../s5l8945x/include/platform/soc/hwclocks.h | 123 + .../include/platform/soc/hwdmachannels.h | 48 + .../s5l8945x/include/platform/soc/hwisr.h | 196 + .../s5l8945x/include/platform/soc/hwregbase.h | 146 + platform/s5l8945x/include/platform/soc/miu.h | 186 + platform/s5l8945x/include/platform/soc/pmgr.h | 474 + .../s5l8945x/include/platform/trampoline.h | 20 + .../s5l8945x/include/platform/usbconfig.h | 23 + platform/s5l8945x/init.c | 1229 + platform/s5l8945x/iop_init.c | 208 + platform/s5l8945x/miu/miu.c | 341 + platform/s5l8945x/miu/rules.mk | 15 + platform/s5l8945x/pmgr/pmgr.c | 1087 + platform/s5l8945x/pmgr/rules.mk | 17 + platform/s5l8945x/rules.mk | 122 + platform/s5l8950x/amc/amc.c | 163 + platform/s5l8950x/amc/rules.mk | 16 + platform/s5l8950x/asm.S | 36 + platform/s5l8950x/chipid/chipid.c | 251 + platform/s5l8950x/chipid/rules.mk | 15 + .../s5l8950x/include/platform/amcconfig.h | 140 + .../s5l8950x/include/platform/ampconfig.h | 41 + platform/s5l8950x/include/platform/gpiodef.h | 61 + .../s5l8950x/include/platform/image_devices.h | 37 + .../s5l8950x/include/platform/memconfig.h | 19 + platform/s5l8950x/include/platform/memmap.h | 141 + .../s5l8950x/include/platform/pinconfig.h | 310 + .../s5l8950x/include/platform/soc/chipid.h | 52 + .../s5l8950x/include/platform/soc/display.h | 45 + .../include/platform/soc/display_timings.h | 41 + .../s5l8950x/include/platform/soc/hwclocks.h | 118 + .../include/platform/soc/hwdmachannels.h | 40 + .../s5l8950x/include/platform/soc/hwisr.h | 211 + .../s5l8950x/include/platform/soc/hwregbase.h | 154 + platform/s5l8950x/include/platform/soc/miu.h | 211 + platform/s5l8950x/include/platform/soc/pmgr.h | 538 + .../s5l8950x/include/platform/trampoline.h | 20 + .../s5l8950x/include/platform/usbconfig.h | 25 + platform/s5l8950x/init.c | 1303 + platform/s5l8950x/iop_init.c | 211 + platform/s5l8950x/miu/miu.c | 311 + platform/s5l8950x/miu/rules.mk | 15 + platform/s5l8950x/pmgr/pmgr.c | 1230 + platform/s5l8950x/pmgr/rules.mk | 17 + platform/s5l8950x/rules.mk | 124 + platform/s5l8955x/amc/amc.c | 169 + platform/s5l8955x/amc/rules.mk | 16 + platform/s5l8955x/asm.S | 36 + platform/s5l8955x/chipid/chipid.c | 249 + platform/s5l8955x/chipid/rules.mk | 15 + .../s5l8955x/include/platform/amcconfig.h | 142 + .../s5l8955x/include/platform/ampconfig.h | 41 + platform/s5l8955x/include/platform/gpiodef.h | 62 + .../s5l8955x/include/platform/image_devices.h | 37 + .../s5l8955x/include/platform/memconfig.h | 19 + platform/s5l8955x/include/platform/memmap.h | 117 + .../s5l8955x/include/platform/pinconfig.h | 336 + .../s5l8955x/include/platform/soc/chipid.h | 52 + .../s5l8955x/include/platform/soc/display.h | 45 + .../include/platform/soc/display_timings.h | 41 + .../s5l8955x/include/platform/soc/hwclocks.h | 129 + .../include/platform/soc/hwdmachannels.h | 40 + .../s5l8955x/include/platform/soc/hwisr.h | 235 + .../s5l8955x/include/platform/soc/hwregbase.h | 172 + platform/s5l8955x/include/platform/soc/miu.h | 211 + platform/s5l8955x/include/platform/soc/pmgr.h | 536 + .../s5l8955x/include/platform/trampoline.h | 20 + .../s5l8955x/include/platform/usbconfig.h | 21 + platform/s5l8955x/init.c | 1309 + platform/s5l8955x/iop_init.c | 212 + platform/s5l8955x/miu/miu.c | 312 + platform/s5l8955x/miu/rules.mk | 15 + platform/s5l8955x/pmgr/pmgr.c | 1259 + platform/s5l8955x/pmgr/rules.mk | 17 + platform/s5l8955x/rules.mk | 124 + platform/s5l8960x/amc/amc.c | 312 + platform/s5l8960x/amc/rules.mk | 16 + platform/s5l8960x/asm.S | 56 + platform/s5l8960x/chipid/chipid.c | 478 + platform/s5l8960x/chipid/rules.mk | 15 + .../s5l8960x/error_handler/error_handler.c | 83 + platform/s5l8960x/error_handler/rules.mk | 16 + .../s5l8960x/include/platform/amcconfig.h | 110 + .../s5l8960x/include/platform/ampconfig.h | 47 + .../s5l8960x/include/platform/error_handler.h | 18 + platform/s5l8960x/include/platform/gpiodef.h | 56 + .../s5l8960x/include/platform/image_devices.h | 39 + .../s5l8960x/include/platform/memconfig.h | 19 + platform/s5l8960x/include/platform/memmap.h | 224 + .../s5l8960x/include/platform/pinconfig.h | 268 + platform/s5l8960x/include/platform/soc/ccc.h | 30 + .../s5l8960x/include/platform/soc/chipid.h | 66 + .../s5l8960x/include/platform/soc/display.h | 107 + .../soc/display_color_manager_tables.h | 350 + .../include/platform/soc/display_timings.h | 132 + .../s5l8960x/include/platform/soc/hwclocks.h | 114 + .../s5l8960x/include/platform/soc/hwisr.h | 200 + .../s5l8960x/include/platform/soc/hwregbase.h | 270 + platform/s5l8960x/include/platform/soc/miu.h | 223 + platform/s5l8960x/include/platform/soc/pmgr.h | 562 + .../s5l8960x/include/platform/trampoline.h | 23 + .../s5l8960x/include/platform/usbconfig.h | 31 + platform/s5l8960x/init.c | 1638 ++ platform/s5l8960x/miu/miu.c | 321 + platform/s5l8960x/miu/rules.mk | 15 + platform/s5l8960x/pmgr/pmgr.c | 2331 ++ platform/s5l8960x/pmgr/rules.mk | 17 + platform/s5l8960x/rules.mk | 136 + platform/s5l8960x/trampoline.S | 382 + platform/s7002/amc/amc.c | 565 + platform/s7002/amc/rules.mk | 16 + platform/s7002/asm.S | 37 + platform/s7002/chipid/chipid.c | 130 + platform/s7002/chipid/rules.mk | 15 + platform/s7002/include/platform/amcconfig.h | 145 + platform/s7002/include/platform/ampconfig.h | 49 + platform/s7002/include/platform/dmin.h | 163 + .../s7002/include/platform/dockfifo_config.h | 32 + platform/s7002/include/platform/gpiodef.h | 56 + .../s7002/include/platform/image_devices.h | 45 + platform/s7002/include/platform/memconfig.h | 19 + platform/s7002/include/platform/memmap.h | 204 + platform/s7002/include/platform/pinconfig.h | 301 + .../s7002/include/platform/pl080dmac_config.h | 43 + platform/s7002/include/platform/soc/chipid.h | 33 + platform/s7002/include/platform/soc/display.h | 45 + .../include/platform/soc/display_timings.h | 107 + .../s7002/include/platform/soc/hwclocks.h | 87 + .../include/platform/soc/hwdmachannels.h | 23 + platform/s7002/include/platform/soc/hwisr.h | 159 + .../s7002/include/platform/soc/hwregbase.h | 188 + platform/s7002/include/platform/soc/miu.h | 67 + platform/s7002/include/platform/soc/pmgr.h | 300 + .../s7002/include/platform/soc/reconfig.h | 67 + platform/s7002/include/platform/soc/spu.h | 26 + platform/s7002/include/platform/trampoline.h | 21 + platform/s7002/include/platform/usbconfig.h | 22 + platform/s7002/init.c | 1566 ++ platform/s7002/miu/miu.c | 216 + platform/s7002/miu/rules.mk | 15 + platform/s7002/pmgr/pmgr.c | 1173 + platform/s7002/pmgr/rules.mk | 18 + platform/s7002/reconfig/reconfig.c | 103 + platform/s7002/reconfig/rules.mk | 17 + platform/s7002/rules.mk | 136 + platform/s8000/apcie/apcie_v2.c | 1571 ++ platform/s8000/apcie/rules.mk | 13 + platform/s8000/asm.S | 36 + platform/s8000/chipid/chipid.c | 349 + platform/s8000/chipid/dvfmperf.c | 276 + platform/s8000/chipid/operating_point.c | 210 + platform/s8000/chipid/pmgr_binning_s8000.c | 385 + platform/s8000/chipid/pmgr_binning_s8001.c | 309 + platform/s8000/chipid/pmgr_binning_s8003.c | 378 + platform/s8000/chipid/rules.mk | 42 + platform/s8000/chipid/tunables_pmgr_product.c | 18 + platform/s8000/chipid/tunables_pmgr_s8000.c | 323 + platform/s8000/chipid/tunables_pmgr_s8001.c | 219 + .../s8000/chipid/tunables_pmgr_s8001_ipad6b.c | 67 + platform/s8000/chipid/tunables_pmgr_s8003.c | 203 + platform/s8000/dcs/dcs.c | 921 + platform/s8000/dcs/dcs_init_lib_s8000.c | 849 + platform/s8000/dcs/dcs_init_lib_s8001.c | 963 + platform/s8000/dcs/dcs_init_lib_s8003.c | 889 + platform/s8000/dcs/rules.mk | 26 + platform/s8000/error_handler/error_handler.c | 121 + platform/s8000/error_handler/rules.mk | 16 + platform/s8000/include/platform/apcie.h | 37 + platform/s8000/include/platform/apcie_regs.h | 60 + platform/s8000/include/platform/dcsconfig.h | 23 + .../s8000/include/platform/dcsconfig_s8000.h | 653 + .../s8000/include/platform/dcsconfig_s8001.h | 298 + .../s8000/include/platform/dcsconfig_s8003.h | 365 + .../s8000/include/platform/error_handler.h | 16 + platform/s8000/include/platform/gpiodef.h | 29 + .../s8000/include/platform/gpiodef_s8000.h | 79 + .../s8000/include/platform/gpiodef_s8001.h | 85 + .../s8000/include/platform/image_devices.h | 43 + platform/s8000/include/platform/memconfig.h | 19 + platform/s8000/include/platform/memmap.h | 348 + platform/s8000/include/platform/pcimap.h | 27 + platform/s8000/include/platform/pinconfig.h | 16 + .../s8000/include/platform/pinconfig_s8000.h | 311 + .../s8000/include/platform/pinconfig_s8001.h | 341 + platform/s8000/include/platform/soc/ccc.h | 30 + platform/s8000/include/platform/soc/chipid.h | 167 + platform/s8000/include/platform/soc/display.h | 11 + .../include/platform/soc/display_s8000.h | 122 + .../include/platform/soc/display_s8001.h | 194 + .../include/platform/soc/display_s8003.h | 120 + .../include/platform/soc/display_timings.h | 202 + .../s8000/include/platform/soc/dvfmperf.h | 17 + .../s8000/include/platform/soc/hwclocks.h | 278 + platform/s8000/include/platform/soc/hwisr.h | 564 + .../s8000/include/platform/soc/hwregbase.h | 607 + platform/s8000/include/platform/soc/miu.h | 66 + .../include/platform/soc/operating_point.h | 56 + platform/s8000/include/platform/soc/pmgr.h | 690 + .../s8000/include/platform/soc/reconfig.h | 90 + .../soc/reconfig_sequences_1200_s8000.h | 1474 + .../soc/reconfig_sequences_1200_s8000_b0.h | 1475 + .../soc/reconfig_sequences_1200_s8003.h | 1468 + .../soc/reconfig_sequences_1200_s8003_a0.h | 1475 + .../soc/reconfig_sequences_mcu_1200_s8000.h | 3100 +++ .../reconfig_sequences_mcu_1200_s8000_b0.h | 3081 +++ .../soc/reconfig_sequences_mcu_1200_s8003.h | 3307 +++ .../reconfig_sequences_mcu_1200_s8003_a0.h | 3280 +++ .../soc/reconfig_sequences_mcu_4ch_s8001.h | 3070 +++ .../soc/reconfig_sequences_mcu_4ch_s8001_a0.h | 3009 ++ .../soc/reconfig_sequences_mcu_8ch_s8001.h | 6042 +++++ .../soc/reconfig_sequences_mcu_8ch_s8001_a0.h | 5929 ++++ .../platform/soc/reconfig_sequences_s8001.h | 1792 ++ .../soc/reconfig_sequences_s8001_a0.h | 1794 ++ .../include/platform/soc/s8000/apcie_common.h | 18 + .../include/platform/soc/s8000/apcie_config.h | 18 + .../include/platform/soc/s8000/ausr_cfg.h | 18 + .../include/platform/soc/s8000/ausr_shm_cfg.h | 18 + .../include/platform/soc/s8000/aust_shm_cfg.h | 18 + .../soc/s8000/b0/tunable/apcie_common.h | 179 + .../soc/s8000/b0/tunable/apcie_config.h | 133 + .../platform/soc/s8000/b0/tunable/ausr_cfg.h | 122 + .../soc/s8000/b0/tunable/ausr_shm_cfg.h | 62 + .../soc/s8000/b0/tunable/aust_shm_cfg.h | 82 + .../soc/s8000/b0/tunable/x1_pcie_rc.h | 61 + .../soc/s8000/b0/tunable/x2_pcie_rc.h | 61 + .../soc/s8000/c0/tunable/apcie_common.h | 179 + .../soc/s8000/c0/tunable/apcie_config.h | 133 + .../platform/soc/s8000/c0/tunable/ausr_cfg.h | 122 + .../soc/s8000/c0/tunable/ausr_shm_cfg.h | 62 + .../soc/s8000/c0/tunable/aust_shm_cfg.h | 82 + .../soc/s8000/c0/tunable/x1_pcie_rc.h | 61 + .../soc/s8000/c0/tunable/x2_pcie_rc.h | 61 + .../include/platform/soc/s8000/x1_pcie_rc.h | 18 + .../include/platform/soc/s8000/x2_pcie_rc.h | 18 + .../soc/s8001/a0/tunable/apcie_common.h | 276 + .../soc/s8001/a0/tunable/apcie_config.h | 215 + .../soc/s8001/a0/tunable/apcie_phy_glue.h | 30 + .../soc/s8001/a0/tunable/x2_pcie_rc.h | 149 + .../include/platform/soc/s8001/apcie_common.h | 18 + .../include/platform/soc/s8001/apcie_config.h | 18 + .../platform/soc/s8001/apcie_phy_glue.h | 18 + .../soc/s8001/b0/tunable/apcie_common.h | 276 + .../soc/s8001/b0/tunable/apcie_config.h | 215 + .../soc/s8001/b0/tunable/apcie_phy_glue.h | 30 + .../soc/s8001/b0/tunable/x2_pcie_rc.h | 149 + .../include/platform/soc/s8001/x2_pcie_rc.h | 18 + .../soc/s8003/a0/tunable/apcie_common.h | 179 + .../soc/s8003/a0/tunable/apcie_config.h | 133 + .../soc/s8003/a0/tunable/apcie_phy_glue.h | 30 + .../soc/s8003/a0/tunable/x1_pcie_rc.h | 61 + .../soc/s8003/a0/tunable/x2_pcie_rc.h | 61 + .../soc/s8003/a1/tunable/apcie_common.h | 179 + .../soc/s8003/a1/tunable/apcie_config.h | 133 + .../soc/s8003/a1/tunable/apcie_phy_glue.h | 590 + .../soc/s8003/a1/tunable/x1_pcie_rc.h | 61 + .../soc/s8003/a1/tunable/x2_pcie_rc.h | 61 + .../include/platform/soc/s8003/apcie_common.h | 18 + .../include/platform/soc/s8003/apcie_config.h | 18 + .../platform/soc/s8003/apcie_phy_glue.h | 18 + .../include/platform/soc/s8003/x1_pcie_rc.h | 18 + .../include/platform/soc/s8003/x2_pcie_rc.h | 18 + platform/s8000/include/platform/trampoline.h | 23 + platform/s8000/include/platform/uartconfig.h | 21 + platform/s8000/include/platform/usbconfig.h | 51 + platform/s8000/init.c | 2027 ++ platform/s8000/miu/miu.c | 177 + platform/s8000/miu/rules.mk | 15 + platform/s8000/pmgr/pmgr.c | 4462 +++ platform/s8000/pmgr/rules.mk | 17 + platform/s8000/reconfig.c | 329 + platform/s8000/reconfig_s8000_a1.c | 15 + platform/s8000/rules.mk | 176 + platform/s8000/trampoline.S | 319 + platform/t7000/amc/amc.c | 120 + platform/t7000/amc/rules.mk | 16 + platform/t7000/apcie/apcie_common_regs.h | 50 + platform/t7000/apcie/apcie_v1.c | 477 + platform/t7000/apcie/rules.mk | 13 + platform/t7000/asm.S | 49 + platform/t7000/chipid/chipid.c | 780 + platform/t7000/chipid/rules.mk | 15 + platform/t7000/error_handler/error_handler.c | 83 + platform/t7000/error_handler/rules.mk | 16 + platform/t7000/include/platform/amcconfig.h | 12 + .../t7000/include/platform/amcconfig_t7000.h | 106 + .../t7000/include/platform/amcconfig_t7001.h | 99 + platform/t7000/include/platform/ampconfig.h | 52 + platform/t7000/include/platform/apcie_regs.h | 94 + .../t7000/include/platform/error_handler.h | 16 + platform/t7000/include/platform/gpiodef.h | 25 + .../t7000/include/platform/gpiodef_t7000.h | 78 + .../t7000/include/platform/gpiodef_t7001.h | 93 + .../t7000/include/platform/image_devices.h | 43 + platform/t7000/include/platform/memconfig.h | 19 + platform/t7000/include/platform/memmap.h | 245 + platform/t7000/include/platform/pcimap.h | 27 + platform/t7000/include/platform/pinconfig.h | 12 + .../t7000/include/platform/pinconfig_t7000.h | 279 + .../t7000/include/platform/pinconfig_t7001.h | 249 + platform/t7000/include/platform/soc/ccc.h | 30 + platform/t7000/include/platform/soc/chipid.h | 179 + platform/t7000/include/platform/soc/display.h | 12 + .../include/platform/soc/display_t7000.h | 175 + .../include/platform/soc/display_t7001.h | 102 + .../include/platform/soc/display_timings.h | 268 + .../t7000/include/platform/soc/hwclocks.h | 138 + platform/t7000/include/platform/soc/hwisr.h | 299 + .../t7000/include/platform/soc/hwregbase.h | 337 + platform/t7000/include/platform/soc/miu.h | 145 + platform/t7000/include/platform/soc/pmgr.h | 1003 + platform/t7000/include/platform/trampoline.h | 23 + platform/t7000/include/platform/usbconfig.h | 21 + platform/t7000/init.c | 2104 ++ platform/t7000/miu/miu.c | 307 + platform/t7000/miu/rules.mk | 15 + platform/t7000/pmgr/pmgr.c | 3329 +++ platform/t7000/pmgr/rules.mk | 17 + platform/t7000/rules.mk | 146 + platform/t7000/trampoline.S | 291 + platform/t8002/asm.S | 23 + platform/t8002/chipid/chipid.c | 146 + platform/t8002/chipid/rules.mk | 20 + platform/t8002/chipid/tunables_pmgr_t8002.c | 119 + platform/t8002/dcs/dcs.c | 119 + platform/t8002/dcs/dcs_init_lib_t8002.c | 832 + platform/t8002/dcs/rules.mk | 17 + platform/t8002/include/platform/dcsconfig.h | 377 + platform/t8002/include/platform/dmin.h | 163 + .../include/platform/dockchannel_config.h | 39 + platform/t8002/include/platform/gpiodef.h | 81 + .../t8002/include/platform/image_devices.h | 35 + platform/t8002/include/platform/memconfig.h | 19 + platform/t8002/include/platform/memmap.h | 202 + platform/t8002/include/platform/pinconfig.h | 328 + platform/t8002/include/platform/soc/aop_dma.h | 30 + platform/t8002/include/platform/soc/chipid.h | 37 + platform/t8002/include/platform/soc/display.h | 45 + .../include/platform/soc/display_timings.h | 107 + .../t8002/include/platform/soc/hwclocks.h | 130 + platform/t8002/include/platform/soc/hwisr.h | 217 + .../t8002/include/platform/soc/hwregbase.h | 172 + platform/t8002/include/platform/soc/miu.h | 69 + platform/t8002/include/platform/soc/pmgr.h | 255 + .../t8002/include/platform/soc/spds/aes.h | 22587 ++++++++++++++++ platform/t8002/include/platform/trampoline.h | 21 + platform/t8002/include/platform/uartconfig.h | 21 + platform/t8002/include/platform/usbconfig.h | 25 + platform/t8002/init.c | 1435 + platform/t8002/miu/miu.c | 110 + platform/t8002/miu/rules.mk | 15 + platform/t8002/pmgr/pmgr.c | 1675 ++ platform/t8002/pmgr/rules.mk | 18 + platform/t8002/rules.mk | 139 + platform/t8002/trampoline.S | 64 + platform/t8010/apcie/apcie.c | 896 + platform/t8010/apcie/rules.mk | 13 + platform/t8010/asm.S | 54 + platform/t8010/chipid/chipid.c | 520 + platform/t8010/chipid/dvfmperf.c | 72 + platform/t8010/chipid/operating_point.c | 76 + platform/t8010/chipid/rules.mk | 18 + platform/t8010/dcs/dcs.c | 117 + platform/t8010/dcs/dcs_init_lib_t8010.c | 812 + platform/t8010/dcs/rules.mk | 17 + platform/t8010/error_handler/error_handler.c | 93 + platform/t8010/error_handler/rules.mk | 16 + platform/t8010/include/platform/apcie.h | 22 + platform/t8010/include/platform/apcie_regs.h | 55 + platform/t8010/include/platform/dcsconfig.h | 23 + .../t8010/include/platform/dcsconfig_t8010.h | 272 + .../t8010/include/platform/error_handler.h | 16 + platform/t8010/include/platform/gpiodef.h | 25 + .../t8010/include/platform/gpiodef_t8010.h | 74 + .../t8010/include/platform/image_devices.h | 43 + platform/t8010/include/platform/memconfig.h | 19 + platform/t8010/include/platform/memmap.h | 258 + platform/t8010/include/platform/pcimap.h | 27 + platform/t8010/include/platform/pinconfig.h | 13 + .../t8010/include/platform/pinconfig_t8010.h | 398 + .../platform/soc/aop_config_sequences.h | 135 + platform/t8010/include/platform/soc/ccc.h | 39 + platform/t8010/include/platform/soc/chipid.h | 110 + platform/t8010/include/platform/soc/display.h | 121 + .../include/platform/soc/display_timings.h | 118 + .../t8010/include/platform/soc/dvfmperf.h | 17 + .../t8010/include/platform/soc/hwclocks.h | 167 + platform/t8010/include/platform/soc/hwisr.h | 347 + .../t8010/include/platform/soc/hwregbase.h | 22 + .../include/platform/soc/hwregbase_t8010.h | 237 + platform/t8010/include/platform/soc/miu.h | 80 + .../include/platform/soc/operating_point.h | 52 + platform/t8010/include/platform/soc/pmgr.h | 581 + .../t8010/include/platform/soc/reconfig.h | 66 + .../soc/t8010/a0/tunable/apcie_common.h | 221 + .../soc/t8010/a0/tunable/apcie_config.h | 201 + .../soc/t8010/a0/tunable/x2_pcie_rc.h | 141 + .../include/platform/soc/t8010/apcie_common.h | 17 + .../include/platform/soc/t8010/apcie_config.h | 17 + .../include/platform/soc/t8010/x2_pcie_rc.h | 17 + platform/t8010/include/platform/trampoline.h | 23 + platform/t8010/include/platform/uartconfig.h | 21 + platform/t8010/include/platform/usbconfig.h | 28 + platform/t8010/init.c | 2161 ++ platform/t8010/miu/miu.c | 210 + platform/t8010/miu/rules.mk | 15 + platform/t8010/pmgr/pmgr.c | 2697 ++ platform/t8010/pmgr/rules.mk | 17 + platform/t8010/rules.mk | 136 + platform/t8010/trampoline.S | 215 + sys/boot.c | 56 + sys/callout.c | 187 + sys/debug.c | 202 + sys/halt.c | 203 + sys/hash.c | 66 + sys/init.c | 95 + sys/lock.c | 61 + sys/mem.c | 92 + sys/menu.c | 502 + sys/rules.mk | 45 + sys/security.c | 461 + sys/simple_menu.c | 195 + sys/task.c | 774 + sys/tests-list.c | 282 + sys/tests-sha384.c | 57 + sys/tests.mk | 28 + sys/time.c | 67 + .../include/target/adbe_settings.h | 27 + .../include/target/aspnandconfig.h | 38 + target/alcatrazref/include/target/gpiodef.h | 28 + .../alcatrazref/include/target/powerconfig.h | 88 + .../alcatrazref/include/target/uartconfig.h | 23 + target/alcatrazref/init.c | 112 + target/alcatrazref/pinconfig.c | 308 + target/alcatrazref/rules.mk | 40 + target/b184/include/target/adbe_settings.h | 27 + target/b184/include/target/amcconfig.h | 106 + target/b184/include/target/aspnandconfig.h | 38 + target/b184/include/target/gpiodef.h | 37 + target/b184/include/target/powerconfig.h | 90 + target/b184/include/target/uartconfig.h | 23 + target/b184/include/target/usbconfig.h | 21 + target/b184/init.c | 232 + target/b184/pinconfig.c | 271 + target/b184/properties.c | 35 + target/b184/rules.mk | 45 + target/b238/include/target/aspnandconfig.h | 38 + target/b238/include/target/gpiodef.h | 37 + target/b238/include/target/powerconfig.h | 68 + target/b238/include/target/uartconfig.h | 19 + target/b238/init.c | 182 + target/b238/pinconfig.c | 580 + target/b238/rules.mk | 36 + .../capriref/include/target/adbe_settings.h | 27 + target/capriref/include/target/amcconfig.h | 99 + target/capriref/include/target/ampconfig.h | 40 + .../capriref/include/target/aspnandconfig.h | 38 + target/capriref/include/target/gpiodef.h | 29 + target/capriref/include/target/powerconfig.h | 97 + target/capriref/include/target/uartconfig.h | 23 + target/capriref/init.c | 90 + target/capriref/pinconfig.c | 258 + target/capriref/rules.mk | 32 + .../cyclonic/include/target/adbe_settings.h | 27 + target/cyclonic/include/target/amcconfig.h | 155 + target/cyclonic/include/target/ampconfig.h | 40 + .../cyclonic/include/target/aspnandconfig.h | 38 + target/cyclonic/include/target/gpiodef.h | 20 + .../include/target/nand_spec_tables.h | 153 + target/cyclonic/include/target/powerconfig.h | 23 + target/cyclonic/include/target/uartconfig.h | 17 + target/cyclonic/init.c | 223 + target/cyclonic/pinconfig.c | 272 + target/cyclonic/rules.mk | 31 + target/e86/include/target/adbe_settings.h | 30 + target/e86/include/target/aspnandconfig.h | 38 + target/e86/include/target/gpiodef.h | 41 + target/e86/include/target/powerconfig.h | 115 + target/e86/include/target/uartconfig.h | 23 + target/e86/init.c | 298 + target/e86/pinconfig.c | 316 + target/e86/rules.mk | 44 + target/e88/include/target/gpiodef.h | 35 + target/e88/include/target/nand_spec_tables.h | 92 + target/e88/include/target/powerconfig.h | 130 + target/e88/include/target/uartconfig.h | 17 + target/e88/include/target/usbconfig.h | 29 + target/e88/init.c | 239 + target/e88/pinconfig.c | 580 + target/e88/rules.mk | 43 + target/elbaref/include/target/adbe_settings.h | 32 + target/elbaref/include/target/boardid.h | 25 + target/elbaref/include/target/dcsfixup.h | 47 + target/elbaref/include/target/gpiodef.h | 46 + target/elbaref/include/target/lpdp_settings.h | 20 + target/elbaref/include/target/powerconfig.h | 140 + target/elbaref/include/target/uartconfig.h | 19 + target/elbaref/init.c | 279 + target/elbaref/pinconfig.c | 706 + target/elbaref/rules.mk | 46 + target/fijiref/include/target/adbe_settings.h | 27 + target/fijiref/include/target/aspnandconfig.h | 38 + target/fijiref/include/target/gpiodef.h | 46 + target/fijiref/include/target/powerconfig.h | 115 + target/fijiref/include/target/uartconfig.h | 23 + target/fijiref/init.c | 92 + target/fijiref/pinconfig.c | 282 + target/fijiref/rules.mk | 38 + target/iaccy1/display_get_info.c | 29 + target/iaccy1/include/target/gpiodef.h | 20 + target/iaccy1/include/target/pinconfig.h | 97 + target/iaccy1/include/target/uartconfig.h | 17 + target/iaccy1/init.c | 168 + target/iaccy1/rules.mk | 32 + target/ipad2/include/target/amgconfig.h | 22 + .../include/target/display_gamma_tables.h | 251 + target/ipad2/include/target/gpiodef.h | 40 + .../ipad2/include/target/nand_spec_tables.h | 1464 + target/ipad2/include/target/pinconfig.h | 414 + target/ipad2/include/target/powerconfig.h | 183 + target/ipad2/include/target/radioconfig.h | 25 + target/ipad2/include/target/uartconfig.h | 26 + target/ipad2/init.c | 299 + target/ipad2/pinconfig.c | 29 + target/ipad2/properties.c | 46 + target/ipad2/rules.mk | 49 + .../include/target/display_gamma_tables.h | 85 + target/ipad2b/include/target/gpiodef.h | 42 + .../ipad2b/include/target/nand_spec_tables.h | 92 + target/ipad2b/include/target/pinconfig.h | 294 + target/ipad2b/include/target/powerconfig.h | 183 + target/ipad2b/include/target/uartconfig.h | 22 + target/ipad2b/include/target/usbconfig.h | 28 + target/ipad2b/init.c | 431 + target/ipad2b/pinconfig.c | 29 + target/ipad2b/properties.c | 46 + target/ipad2b/rules.mk | 54 + target/ipad3/include/target/gpiodef.h | 38 + .../ipad3/include/target/nand_spec_tables.h | 93 + target/ipad3/include/target/pinconfig.h | 391 + target/ipad3/include/target/powerconfig.h | 165 + target/ipad3/include/target/radioconfig.h | 25 + target/ipad3/include/target/uartconfig.h | 26 + target/ipad3/init.c | 430 + target/ipad3/pinconfig.c | 29 + target/ipad3/properties.c | 46 + target/ipad3/rules.mk | 34 + target/ipad3b/include/target/gpiodef.h | 40 + .../ipad3b/include/target/nand_spec_tables.h | 92 + target/ipad3b/include/target/pinconfig.h | 359 + target/ipad3b/include/target/powerconfig.h | 210 + target/ipad3b/include/target/radioconfig.h | 29 + target/ipad3b/include/target/uartconfig.h | 26 + target/ipad3b/init.c | 436 + target/ipad3b/pinconfig.c | 29 + target/ipad3b/properties.c | 46 + target/ipad3b/rules.mk | 43 + target/ipad4/include/target/adbe_settings.h | 27 + target/ipad4/include/target/amcconfig.h | 107 + target/ipad4/include/target/aspnandconfig.h | 38 + target/ipad4/include/target/gpiodef.h | 37 + target/ipad4/include/target/pinconfig.h | 787 + target/ipad4/include/target/powerconfig.h | 146 + target/ipad4/include/target/uartconfig.h | 23 + target/ipad4/include/target/usbconfig.h | 21 + target/ipad4/init.c | 387 + target/ipad4/pinconfig.c | 29 + target/ipad4/properties.c | 46 + target/ipad4/rules.mk | 47 + target/ipad4b/include/target/adbe_settings.h | 27 + target/ipad4b/include/target/aspnandconfig.h | 66 + target/ipad4b/include/target/boardid.h | 21 + target/ipad4b/include/target/gpiodef.h | 39 + .../ipad4b/include/target/pinconfig-nomesa.h | 294 + target/ipad4b/include/target/powerconfig.h | 148 + target/ipad4b/include/target/uartconfig.h | 23 + target/ipad4b/include/target/usbconfig.h | 21 + target/ipad4b/init.c | 404 + target/ipad4b/pinconfig-mesa.c | 1577 ++ target/ipad4b/pinconfig-nomesa.c | 29 + target/ipad4b/properties.c | 46 + target/ipad4b/rules.mk | 47 + target/ipad5/include/target/adbe_settings.h | 30 + target/ipad5/include/target/amcconfig.h | 103 + target/ipad5/include/target/aspnandconfig.h | 38 + target/ipad5/include/target/boardid.h | 19 + target/ipad5/include/target/gpiodef.h | 41 + target/ipad5/include/target/lpdp_settings.h | 20 + target/ipad5/include/target/powerconfig.h | 121 + target/ipad5/include/target/uartconfig.h | 23 + target/ipad5/init.c | 462 + target/ipad5/pinconfig.c | 1109 + target/ipad5/properties.c | 46 + target/ipad5/rules.mk | 49 + target/ipad5b/include/target/adbe_settings.h | 30 + target/ipad5b/include/target/aspnandconfig.h | 38 + target/ipad5b/include/target/boardid.h | 19 + target/ipad5b/include/target/gpiodef.h | 37 + target/ipad5b/include/target/lpdp_settings.h | 20 + target/ipad5b/include/target/powerconfig.h | 113 + target/ipad5b/include/target/uartconfig.h | 23 + target/ipad5b/init.c | 522 + target/ipad5b/pinconfig.c | 989 + target/ipad5b/properties.c | 46 + target/ipad5b/rules.mk | 50 + target/ipad5c/include/target/adbe_settings.h | 44 + target/ipad5c/include/target/aspnandconfig.h | 38 + target/ipad5c/include/target/boardid.h | 35 + target/ipad5c/include/target/gpiodef.h | 42 + target/ipad5c/include/target/lpdp_settings.h | 20 + target/ipad5c/include/target/powerconfig.h | 120 + target/ipad5c/include/target/uartconfig.h | 19 + target/ipad5c/init.c | 995 + target/ipad5c/pinconfig.c | 83 + target/ipad5c/pinconfig_evt.c | 989 + target/ipad5c/pinconfig_evt2.c | 989 + target/ipad5c/pinconfig_proto2.c | 989 + target/ipad5c/pinconfig_proto3.c | 989 + target/ipad5c/properties.c | 46 + target/ipad5c/rules.mk | 56 + target/ipad6b/include/target/adbe_settings.h | 33 + target/ipad6b/include/target/boardid.h | 35 + target/ipad6b/include/target/dcsfixup.h | 16 + .../include/target/display_gamma_tables.h | 604 + target/ipad6b/include/target/gpiodef.h | 43 + target/ipad6b/include/target/lpdp_settings.h | 20 + target/ipad6b/include/target/powerconfig.h | 256 + target/ipad6b/include/target/uartconfig.h | 19 + target/ipad6b/include/target/usbconfig.h | 29 + target/ipad6b/init.c | 617 + target/ipad6b/pinconfig.c | 59 + target/ipad6b/pinconfig_proto2.c | 1470 + target/ipad6b/rules.mk | 75 + target/ipad6d/include/target/adbe_settings.h | 35 + target/ipad6d/include/target/boardid.h | 31 + .../include/target/display_gamma_tables.h | 604 + target/ipad6d/include/target/gpiodef.h | 44 + target/ipad6d/include/target/lpdp_settings.h | 20 + target/ipad6d/include/target/powerconfig.h | 252 + target/ipad6d/include/target/uartconfig.h | 19 + target/ipad6d/include/target/usbconfig.h | 29 + target/ipad6d/init.c | 586 + target/ipad6d/pinconfig.c | 1476 + target/ipad6d/rules.mk | 50 + target/iphone5/include/target/gpiodef.h | 48 + .../iphone5/include/target/nand_spec_tables.h | 92 + target/iphone5/include/target/pinconfig.h | 376 + target/iphone5/include/target/powerconfig.h | 138 + target/iphone5/include/target/radioconfig.h | 25 + target/iphone5/include/target/uartconfig.h | 26 + target/iphone5/init.c | 661 + target/iphone5/pinconfig.c | 29 + target/iphone5/rules.mk | 37 + target/iphone5b/include/target/gpiodef.h | 44 + .../include/target/nand_spec_tables.h | 92 + target/iphone5b/include/target/pinconfig.h | 366 + target/iphone5b/include/target/powerconfig.h | 137 + target/iphone5b/include/target/radioconfig.h | 25 + target/iphone5b/include/target/uartconfig.h | 26 + target/iphone5b/init.c | 686 + target/iphone5b/pinconfig.c | 29 + target/iphone5b/rules.mk | 37 + target/iphone6/include/target/adbe_settings.h | 27 + target/iphone6/include/target/aspnandconfig.h | 39 + target/iphone6/include/target/gpiodef.h | 46 + target/iphone6/include/target/powerconfig.h | 91 + target/iphone6/include/target/uartconfig.h | 23 + target/iphone6/init.c | 571 + target/iphone6/pinconfig.c | 306 + target/iphone6/rules.mk | 44 + target/iphone7/include/target/adbe_settings.h | 74 + target/iphone7/include/target/aspnandconfig.h | 38 + target/iphone7/include/target/gpiodef.h | 46 + target/iphone7/include/target/powerconfig.h | 150 + target/iphone7/include/target/uartconfig.h | 23 + target/iphone7/init.c | 1105 + target/iphone7/pinconfig.c | 580 + target/iphone7/rules.mk | 57 + target/iphone8/include/target/adbe_settings.h | 45 + target/iphone8/include/target/aspnandconfig.h | 38 + target/iphone8/include/target/gpiodef.h | 49 + target/iphone8/include/target/powerconfig.h | 142 + target/iphone8/include/target/uartconfig.h | 23 + target/iphone8/init.c | 1036 + target/iphone8/pinconfig.c | 648 + target/iphone8/rules.mk | 50 + target/ipod6/include/target/adbe_settings.h | 24 + target/ipod6/include/target/amcconfig.h | 147 + target/ipod6/include/target/ampconfig.h | 49 + target/ipod6/include/target/aspnandconfig.h | 38 + target/ipod6/include/target/cjay.h | 47 + .../include/target/display_gamma_tables.h | 615 + target/ipod6/include/target/gpiodef.h | 65 + target/ipod6/include/target/powerconfig.h | 76 + target/ipod6/include/target/uartconfig.h | 23 + target/ipod6/init.c | 140 + target/ipod6/init_fpga.c | 158 + target/ipod6/init_fpga.h | 20 + target/ipod6/init_product.c | 1261 + target/ipod6/init_product.h | 22 + target/ipod6/init_sim.c | 208 + target/ipod6/init_sim.h | 20 + target/ipod6/pinconfig_evt.c | 566 + target/ipod6/pinconfig_fpga.c | 312 + target/ipod6/pinconfig_product.c | 82 + target/ipod6/pinconfig_proto2a.c | 566 + target/ipod6/pinconfig_proto2b.c | 566 + target/ipod6/pinconfig_sim.c | 312 + target/ipod6/properties.c | 46 + target/ipod6/rules.mk | 98 + target/ipod6/target_prepare_dali.c | 178 + target/j105/include/target/adbe_settings.h | 29 + target/j105/include/target/aspnandconfig.h | 38 + target/j105/include/target/gpiodef.h | 31 + target/j105/include/target/powerconfig.h | 85 + target/j105/include/target/uartconfig.h | 19 + target/j105/init.c | 247 + target/j105/pinconfig.c | 706 + target/j105/properties.c | 35 + target/j105/rules.mk | 75 + target/j33/include/target/amcconfig.h | 150 + target/j33/include/target/amgconfig.h | 24 + target/j33/include/target/gpiodef.h | 25 + target/j33/include/target/nand_spec_tables.h | 92 + target/j33/include/target/powerconfig.h | 97 + target/j33/include/target/uartconfig.h | 21 + target/j33/init.c | 240 + target/j33/pinconfig.c | 284 + target/j33/rules.mk | 58 + target/j33i/include/target/gpiodef.h | 27 + target/j33i/include/target/nand_spec_tables.h | 92 + target/j33i/include/target/powerconfig.h | 98 + target/j33i/include/target/uartconfig.h | 21 + target/j33i/init.c | 218 + target/j33i/pinconfig.c | 187 + target/j33i/rules.mk | 52 + target/j34/include/target/adbe_settings.h | 32 + target/j34/include/target/amcconfig.h | 106 + target/j34/include/target/aspnandconfig.h | 38 + target/j34/include/target/gpiodef.h | 36 + target/j34/include/target/powerconfig.h | 84 + target/j34/include/target/uartconfig.h | 21 + target/j34/include/target/usbconfig.h | 21 + target/j34/init.c | 322 + target/j34/pinconfig.c | 271 + target/j34/properties.c | 35 + target/j34/rules.mk | 54 + target/j34m/include/target/adbe_settings.h | 32 + target/j34m/include/target/amcconfig.h | 106 + target/j34m/include/target/aspnandconfig.h | 38 + target/j34m/include/target/gpiodef.h | 36 + target/j34m/include/target/powerconfig.h | 83 + target/j34m/include/target/uartconfig.h | 21 + target/j34m/include/target/usbconfig.h | 21 + target/j34m/init.c | 320 + target/j34m/pinconfig.c | 276 + target/j34m/properties.c | 35 + target/j34m/rules.mk | 56 + target/j42/include/target/adbe_settings.h | 29 + target/j42/include/target/amcconfig.h | 103 + target/j42/include/target/aspnandconfig.h | 38 + target/j42/include/target/gpiodef.h | 38 + target/j42/include/target/powerconfig.h | 87 + target/j42/include/target/uartconfig.h | 21 + target/j42/init.c | 290 + target/j42/pinconfig.c | 692 + target/j42/properties.c | 35 + target/j42/rules.mk | 65 + .../include/target/display_gamma_tables.h | 251 + target/k93a/include/target/gpiodef.h | 40 + target/k93a/include/target/nand_spec_tables.h | 92 + target/k93a/include/target/pinconfig.h | 334 + target/k93a/include/target/powerconfig.h | 185 + target/k93a/include/target/uartconfig.h | 22 + target/k93a/init.c | 255 + target/k93a/pinconfig.c | 29 + target/k93a/properties.c | 45 + target/k93a/rules.mk | 43 + target/m7ref/include/target/aspnandconfig.h | 38 + target/m7ref/include/target/gpiodef.h | 34 + target/m7ref/include/target/powerconfig.h | 72 + target/m7ref/include/target/uartconfig.h | 23 + target/m7ref/init.c | 178 + target/m7ref/pinconfig.c | 275 + target/m7ref/rules.mk | 34 + target/mauiref/include/target/adbe_settings.h | 38 + target/mauiref/include/target/aspnandconfig.h | 38 + .../include/target/display_gamma_tables.h | 20 + target/mauiref/include/target/gpiodef.h | 42 + target/mauiref/include/target/powerconfig.h | 123 + target/mauiref/include/target/uartconfig.h | 23 + target/mauiref/init.c | 174 + target/mauiref/pinconfig.c | 646 + target/mauiref/rules.mk | 44 + target/n102/include/target/adbe_settings.h | 31 + target/n102/include/target/aspnandconfig.h | 38 + target/n102/include/target/gpiodef.h | 41 + target/n102/include/target/powerconfig.h | 110 + target/n102/include/target/uartconfig.h | 26 + target/n102/init.c | 512 + target/n102/pinconfig.c | 580 + target/n102/rules.mk | 41 + target/n59/include/target/adbe_settings.h | 30 + target/n59/include/target/aspnandconfig.h | 38 + target/n59/include/target/gpiodef.h | 46 + target/n59/include/target/powerconfig.h | 116 + target/n59/include/target/uartconfig.h | 23 + target/n59/init.c | 507 + target/n59/pinconfig.c | 580 + target/n59/rules.mk | 43 + target/n69/include/target/adbe_settings.h | 31 + target/n69/include/target/aspnandconfig.h | 38 + target/n69/include/target/gpiodef.h | 49 + target/n69/include/target/powerconfig.h | 144 + target/n69/include/target/uartconfig.h | 23 + target/n69/init.c | 542 + target/n69/pinconfig.c | 769 + target/n69/rules.mk | 55 + target/n78/include/target/gpiodef.h | 43 + target/n78/include/target/nand_spec_tables.h | 92 + target/n78/include/target/pinconfig.h | 333 + target/n78/include/target/powerconfig.h | 137 + target/n78/include/target/uartconfig.h | 17 + target/n78/include/target/usbconfig.h | 29 + target/n78/init.c | 461 + target/n78/pinconfig.c | 29 + target/n78/rules.mk | 44 + target/n94/include/target/gpiodef.h | 46 + target/n94/include/target/nand_spec_tables.h | 92 + target/n94/include/target/powerconfig.h | 129 + target/n94/include/target/radioconfig.h | 25 + target/n94/include/target/uartconfig.h | 26 + target/n94/init.c | 443 + target/n94/pinconfig.c | 654 + target/n94/rules.mk | 42 + .../s8000fpga/include/target/adbe_settings.h | 27 + .../s8000fpga/include/target/aspnandconfig.h | 38 + target/s8000fpga/include/target/dcsfixup.h | 18 + .../s8000fpga/include/target/dcsfixup_s8000.h | 74 + .../s8000fpga/include/target/dcsfixup_s8001.h | 69 + .../s8000fpga/include/target/dcsfixup_s8003.h | 66 + target/s8000fpga/include/target/gpiodef.h | 20 + target/s8000fpga/include/target/uartconfig.h | 21 + target/s8000fpga/init.c | 242 + target/s8000fpga/pinconfig_s8000fpga.c | 325 + target/s8000fpga/pinconfig_s8001fpga.c | 353 + target/s8000fpga/rules.mk | 50 + .../s8000sim/include/target/adbe_settings.h | 29 + .../s8000sim/include/target/aspnandconfig.h | 38 + target/s8000sim/include/target/gpiodef.h | 20 + .../include/target/nand_spec_tables.h | 153 + target/s8000sim/include/target/powerconfig.h | 23 + target/s8000sim/include/target/uartconfig.h | 17 + target/s8000sim/init.c | 226 + target/s8000sim/pinconfig_s8000sim.c | 323 + target/s8000sim/pinconfig_s8001sim.c | 353 + target/s8000sim/rules.mk | 46 + .../t7000fpga/include/target/adbe_settings.h | 27 + target/t7000fpga/include/target/amcconfig.h | 16 + .../include/target/amcconfig_t7000.h | 162 + .../include/target/amcconfig_t7001.h | 164 + target/t7000fpga/include/target/ampconfig.h | 41 + .../t7000fpga/include/target/aspnandconfig.h | 38 + target/t7000fpga/include/target/gpiodef.h | 20 + target/t7000fpga/include/target/pinconfig.h | 15 + target/t7000fpga/include/target/uartconfig.h | 21 + target/t7000fpga/init.c | 242 + target/t7000fpga/pinconfig_t7000fpga.c | 283 + target/t7000fpga/pinconfig_t7001fpga.c | 253 + target/t7000fpga/rules.mk | 41 + .../t8010fpga/include/target/adbe_settings.h | 27 + target/t8010fpga/include/target/dcsfixup.h | 13 + .../t8010fpga/include/target/dcsfixup_t8010.h | 68 + target/t8010fpga/include/target/gpiodef.h | 20 + target/t8010fpga/include/target/uartconfig.h | 21 + target/t8010fpga/init.c | 244 + target/t8010fpga/pinconfig_t8010fpga.c | 429 + target/t8010fpga/rules.mk | 38 + target/t8010sim/include/target/gpiodef.h | 20 + .../include/target/nand_spec_tables.h | 153 + target/t8010sim/include/target/powerconfig.h | 23 + target/t8010sim/include/target/uartconfig.h | 17 + target/t8010sim/init.c | 223 + target/t8010sim/pinconfig_t8010sim.c | 429 + target/t8010sim/rules.mk | 33 + .../typhonic/include/target/adbe_settings.h | 29 + target/typhonic/include/target/amcconfig.h | 16 + .../typhonic/include/target/amcconfig_t7000.h | 98 + .../typhonic/include/target/amcconfig_t7001.h | 99 + target/typhonic/include/target/ampconfig.h | 49 + .../typhonic/include/target/aspnandconfig.h | 38 + target/typhonic/include/target/gpiodef.h | 20 + .../include/target/nand_spec_tables.h | 153 + target/typhonic/include/target/pinconfig.h | 16 + target/typhonic/include/target/powerconfig.h | 23 + target/typhonic/include/target/uartconfig.h | 17 + target/typhonic/init.c | 226 + target/typhonic/pinconfig_t7001padsim.c | 253 + target/typhonic/pinconfig_typhonic.c | 283 + target/typhonic/rules.mk | 43 + target/watch2/include/target/adbe_settings.h | 24 + target/watch2/include/target/aspnandconfig.h | 37 + target/watch2/include/target/dcsfixup.h | 66 + target/watch2/include/target/gpiodef.h | 63 + target/watch2/include/target/pinconfig.h | 17 + .../watch2/include/target/pinconfig_product.h | 286 + target/watch2/include/target/powerconfig.h | 73 + target/watch2/include/target/uartconfig.h | 23 + target/watch2/init.c | 140 + target/watch2/init_fpga.c | 157 + target/watch2/init_fpga.h | 20 + target/watch2/init_product.c | 1150 + target/watch2/init_product.h | 22 + target/watch2/init_sim.c | 198 + target/watch2/init_sim.h | 20 + target/watch2/pinconfig_evt.c | 566 + target/watch2/pinconfig_fpga.c | 359 + target/watch2/pinconfig_product.c | 108 + target/watch2/pinconfig_proto2a.c | 566 + target/watch2/pinconfig_proto2b.c | 566 + target/watch2/pinconfig_sim.c | 359 + target/watch2/rules.mk | 77 + target/watch2/target_prepare_dali.c | 81 + tests/fuzz-main.c | 46 + tests/include/linux-support.h | 19 + tests/include/mock_syscfg.h | 19 + tests/include/non-posix.h | 19 + tests/include/unittest.h | 228 + tests/mocks/blockdev.c | 62 + tests/mocks/sys/lock.c | 42 + tests/mocks/sys/security.c | 13 + tests/mocks/syscfg.c | 81 + tests/non-posix.c | 44 + tests/unittest-main.c | 759 + tests/unittest-tests.mk | 18 + tools/BootX2Bin.cpp | 908 + tools/Buffer.cpp | 237 + tools/Buffer.h | 71 + tools/DeviceTreePatcher.cpp | 221 + tools/DeviceTreePatcher.h | 56 + tools/Kernelcache.cpp | 84 + tools/Kernelcache.h | 19 + tools/LoadMachO.cpp | 339 + tools/LoadMachO.h | 57 + tools/Macho2Bin.c | 133 + tools/Makefile | 120 + tools/analyzer-report.py | 105 + tools/analyzer-suppress.txt | 14 + tools/bhc.c | 231 + tools/check_liblist.py | 35 + tools/check_product_size | 25 + tools/code_sizer | 184 + tools/config_debug.tcl | 115 + tools/config_seq.py | 105 + tools/csvtopinconfig.py | 988 + tools/gcovr | 2185 ++ tools/generate_debug_hashes.py | 47 + tools/igmacros | 250 + tools/iop_stitcher.c | 174 + tools/lldb_init_iboot.py | 10 + tools/lldb_os_iboot.py | 199 + tools/macho.py | 946 + tools/macho_post_process.py | 137 + tools/missing-symbol-finder | 102 + tools/ofile_cstring_sizes | 57 + tools/oldskool_csvtopinconfig.py | 893 + tools/parse_release_log.py | 88 + tools/pctrace-decoder | 193 + tools/pickfiles.sh | 45 + tools/ppnfw_asn1.rb | 21 + tools/rom-release | 45 + tools/scrub-SecureROM.sh | 183 + tools/symbolicate-panic | 100 + 2612 files changed, 636500 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 apps/EmbeddedIOP/EmbeddedIOP.mk create mode 100644 apps/EmbeddedIOP/EmbeddedIOPFirmware.h create mode 100644 apps/EmbeddedIOP/EmbeddedIOPProtocol.h create mode 100644 apps/EmbeddedIOP/application.mk create mode 100644 apps/EmbeddedIOP/clock_management.c create mode 100644 apps/EmbeddedIOP/clock_management.h create mode 100644 apps/EmbeddedIOP/clock_stepping.c create mode 100644 apps/EmbeddedIOP/clock_stepping.h create mode 100644 apps/EmbeddedIOP/config/s5l8940xae2-config.mk create mode 100644 apps/EmbeddedIOP/config/s5l8940xiop-config.mk create mode 100644 apps/EmbeddedIOP/config/s5l8942xiop-config.mk create mode 100644 apps/EmbeddedIOP/config/s5l8945xae2-config.mk create mode 100644 apps/EmbeddedIOP/config/s5l8945xiop-config.mk create mode 100644 apps/EmbeddedIOP/config/s5l8947xiop-config.mk create mode 100644 apps/EmbeddedIOP/config/s5l8950xae2-config.mk create mode 100644 apps/EmbeddedIOP/config/s5l8950xiop-config.mk create mode 100644 apps/EmbeddedIOP/debugcmds.c create mode 100644 apps/EmbeddedIOP/function_audio/iop_audio.c create mode 100644 apps/EmbeddedIOP/function_audio/iop_audio_protocol.h create mode 100644 apps/EmbeddedIOP/function_audio/libstd_stub.cpp create mode 100644 apps/EmbeddedIOP/function_audio/rules.mk create mode 100644 apps/EmbeddedIOP/function_audiodsp/AE2_DMA/ae2_dma.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.c create mode 100644 apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.c create mode 100644 apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AE2_I2S/ae2_i2s.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AE2_MCA/ae2_mca.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUBase_AE2.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUComponent_AE2.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.cpp create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.cpp create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/AudioUnitProperties_AE2.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/CoreAudioTypes_AE2.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.cpp create mode 100644 apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/debug_tap.c create mode 100644 apps/EmbeddedIOP/function_audiodsp/debug_tap.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/iop_audiodsp.c create mode 100644 apps/EmbeddedIOP/function_audiodsp/iop_audiodsp_protocol.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/loopback_device.c create mode 100644 apps/EmbeddedIOP/function_audiodsp/loopback_device.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/loopback_process.c create mode 100644 apps/EmbeddedIOP/function_audiodsp/loopback_process.h create mode 100644 apps/EmbeddedIOP/function_audiodsp/rules.mk create mode 100644 apps/EmbeddedIOP/function_audiodsp/timestamper.c create mode 100644 apps/EmbeddedIOP/function_audiodsp/timestamper.h create mode 100644 apps/EmbeddedIOP/function_ceata/ceata.h create mode 100644 apps/EmbeddedIOP/function_ceata/iop_ceata.c create mode 100644 apps/EmbeddedIOP/function_ceata/iop_ceata.h create mode 100644 apps/EmbeddedIOP/function_ceata/iop_ceata_protocol.h create mode 100644 apps/EmbeddedIOP/function_ceata/rules.mk create mode 100644 apps/EmbeddedIOP/function_fmi/iop_fmi.c create mode 100644 apps/EmbeddedIOP/function_fmi/iop_fmi_protocol.h create mode 100644 apps/EmbeddedIOP/function_fmi/rules.mk create mode 100644 apps/EmbeddedIOP/function_sdio/iop_sdio.c create mode 100644 apps/EmbeddedIOP/function_sdio/iop_sdio_protocol.h create mode 100644 apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.c create mode 100644 apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.h create mode 100644 apps/EmbeddedIOP/function_sdio/rules.mk create mode 100644 apps/EmbeddedIOP/iop.h create mode 100644 apps/EmbeddedIOP/main.c create mode 100644 apps/EmbeddedIOP/qwi.c create mode 100644 apps/EmbeddedIOP/qwi.h create mode 100644 apps/EmbeddedIOP/qwi_protocol.h create mode 100644 apps/SecureROM/SecureROM.mk create mode 100644 apps/SecureROM/application.mk create mode 100644 apps/SecureROM/config/t8002-config.mk create mode 100644 apps/SecureROM/config/t8010-config-base.mk create mode 100644 apps/SecureROM/config/t8010-config.mk create mode 100644 apps/SecureROM/main.c create mode 100644 apps/SecureROM/tests/blinky_armv7/build_rom_test.sh create mode 100644 apps/SecureROM/tests/blinky_armv7/rom_test.c create mode 100644 apps/SecureROM/tests/blinky_armv8/build_rom_test.sh create mode 100644 apps/SecureROM/tests/blinky_armv8/rom_test.c create mode 100644 apps/SecureROM/tests/images_t8002/rom_test.bin create mode 100644 apps/SecureROM/tests/images_t8002/rom_test_ibss_encrypted.im4p create mode 100644 apps/SecureROM/tests/images_t8002/rom_test_ibss_unencrypted.im4p create mode 100644 apps/SecureROM/tests/images_t8002/rom_test_illb_encrypted.im4p create mode 100644 apps/SecureROM/tests/images_t8002/rom_test_illb_unencrypted.im4p create mode 100644 apps/SecureROM/tests/images_t8010/rom_test.bin create mode 100644 apps/SecureROM/tests/images_t8010/rom_test_ibss_encrypted.im4p create mode 100644 apps/SecureROM/tests/images_t8010/rom_test_ibss_unencrypted.im4p create mode 100644 apps/SecureROM/tests/images_t8010/rom_test_illb_encrypted.im4p create mode 100644 apps/SecureROM/tests/images_t8010/rom_test_illb_unencrypted.im4p create mode 100644 apps/SecureROM/tests/test_generator_hx.py create mode 100644 apps/SecureROM/tests/test_generator_mx.py create mode 100644 apps/iBoot/application.mk create mode 100644 apps/iBoot/boot.c create mode 100644 apps/iBoot/config/alcatrazref-config.mk create mode 100644 apps/iBoot/config/appletv3-config-base.mk create mode 100644 apps/iBoot/config/appletv4-config-base.mk create mode 100644 apps/iBoot/config/appletv5-config-base.mk create mode 100644 apps/iBoot/config/appletv6-config-base.mk create mode 100644 apps/iBoot/config/b137-config.mk create mode 100644 apps/iBoot/config/b165-config.mk create mode 100644 apps/iBoot/config/b184-config.mk create mode 100644 apps/iBoot/config/b238-config.mk create mode 100644 apps/iBoot/config/boot-from-nand-template.mk create mode 100644 apps/iBoot/config/boot-from-nor-template.mk create mode 100644 apps/iBoot/config/capriref-config.mk create mode 100644 apps/iBoot/config/cyclonic-config.mk create mode 100644 apps/iBoot/config/e86-config.mk create mode 100644 apps/iBoot/config/e88-config.mk create mode 100644 apps/iBoot/config/elbaref-config.mk create mode 100644 apps/iBoot/config/elbauiref-config.mk create mode 100644 apps/iBoot/config/fijiref-config.mk create mode 100644 apps/iBoot/config/iaccy1-config-base.mk create mode 100644 apps/iBoot/config/ipad2-config-base.mk create mode 100644 apps/iBoot/config/ipad2b-config-base.mk create mode 100644 apps/iBoot/config/ipad3-config-base.mk create mode 100644 apps/iBoot/config/ipad3b-config-base.mk create mode 100644 apps/iBoot/config/ipad4-config-base.mk create mode 100644 apps/iBoot/config/ipad4b-config-base.mk create mode 100644 apps/iBoot/config/ipad5-config-base.mk create mode 100644 apps/iBoot/config/ipad5b-config-base.mk create mode 100644 apps/iBoot/config/ipad5c-config-base.mk create mode 100644 apps/iBoot/config/ipad6b-config-base.mk create mode 100644 apps/iBoot/config/ipad6d-config-base.mk create mode 100644 apps/iBoot/config/iphone5-config-base.mk create mode 100644 apps/iBoot/config/iphone5b-config-base.mk create mode 100644 apps/iBoot/config/iphone6-config-base.mk create mode 100644 apps/iBoot/config/iphone7-config-base.mk create mode 100644 apps/iBoot/config/iphone8-config-base.mk create mode 100644 apps/iBoot/config/iphone8b-config-base.mk create mode 100644 apps/iBoot/config/ipod6-config-base.mk create mode 100644 apps/iBoot/config/j1-config.mk create mode 100644 apps/iBoot/config/j105-config.mk create mode 100644 apps/iBoot/config/j127-config.mk create mode 100644 apps/iBoot/config/j128-config.mk create mode 100644 apps/iBoot/config/j2-config.mk create mode 100644 apps/iBoot/config/j2a-config.mk create mode 100644 apps/iBoot/config/j33-config.mk create mode 100644 apps/iBoot/config/j33i-config.mk create mode 100644 apps/iBoot/config/j34-config.mk create mode 100644 apps/iBoot/config/j34m-config.mk create mode 100644 apps/iBoot/config/j42-config.mk create mode 100644 apps/iBoot/config/j42d-config.mk create mode 100644 apps/iBoot/config/j42m-config.mk create mode 100644 apps/iBoot/config/j71-config.mk create mode 100644 apps/iBoot/config/j72-config.mk create mode 100644 apps/iBoot/config/j73-config.mk create mode 100644 apps/iBoot/config/j81-config.mk create mode 100644 apps/iBoot/config/j82-config.mk create mode 100644 apps/iBoot/config/j85-config.mk create mode 100644 apps/iBoot/config/j85m-config.mk create mode 100644 apps/iBoot/config/j86-config.mk create mode 100644 apps/iBoot/config/j86m-config.mk create mode 100644 apps/iBoot/config/j87-config.mk create mode 100644 apps/iBoot/config/j87m-config.mk create mode 100644 apps/iBoot/config/j96-config.mk create mode 100644 apps/iBoot/config/j97-config.mk create mode 100644 apps/iBoot/config/j98-config.mk create mode 100644 apps/iBoot/config/j98a-config.mk create mode 100644 apps/iBoot/config/j99-config.mk create mode 100644 apps/iBoot/config/j99a-config.mk create mode 100644 apps/iBoot/config/k93-config.mk create mode 100644 apps/iBoot/config/k93a-config.mk create mode 100644 apps/iBoot/config/k94-config.mk create mode 100644 apps/iBoot/config/k95-config.mk create mode 100644 apps/iBoot/config/m7ref-config.mk create mode 100644 apps/iBoot/config/maltaref-config.mk create mode 100644 apps/iBoot/config/maltauiref-config.mk create mode 100644 apps/iBoot/config/mauiref-config.mk create mode 100644 apps/iBoot/config/mauiuiref-config.mk create mode 100644 apps/iBoot/config/n102-config.mk create mode 100644 apps/iBoot/config/n27-config.mk create mode 100644 apps/iBoot/config/n27a-config.mk create mode 100644 apps/iBoot/config/n28-config.mk create mode 100644 apps/iBoot/config/n28a-config.mk create mode 100644 apps/iBoot/config/n41-config.mk create mode 100644 apps/iBoot/config/n42-config.mk create mode 100644 apps/iBoot/config/n48-config.mk create mode 100644 apps/iBoot/config/n49-config.mk create mode 100644 apps/iBoot/config/n51-config.mk create mode 100644 apps/iBoot/config/n53-config.mk create mode 100644 apps/iBoot/config/n56-config.mk create mode 100644 apps/iBoot/config/n59-config.mk create mode 100644 apps/iBoot/config/n61-config.mk create mode 100644 apps/iBoot/config/n66-config-base.mk create mode 100644 apps/iBoot/config/n66-config.mk create mode 100644 apps/iBoot/config/n66m-config.mk create mode 100644 apps/iBoot/config/n69-config.mk create mode 100644 apps/iBoot/config/n69u-config.mk create mode 100644 apps/iBoot/config/n71-config-base.mk create mode 100644 apps/iBoot/config/n71-config.mk create mode 100644 apps/iBoot/config/n71m-config.mk create mode 100644 apps/iBoot/config/n78-config.mk create mode 100644 apps/iBoot/config/n94-config.mk create mode 100644 apps/iBoot/config/p101-config.mk create mode 100644 apps/iBoot/config/p102-config.mk create mode 100644 apps/iBoot/config/p103-config.mk create mode 100644 apps/iBoot/config/p105-config.mk create mode 100644 apps/iBoot/config/p106-config.mk create mode 100644 apps/iBoot/config/p107-config.mk create mode 100644 apps/iBoot/config/s7002fpga-config.mk create mode 100644 apps/iBoot/config/s7002sim-config.mk create mode 100644 apps/iBoot/config/s8000fpga-config.mk create mode 100644 apps/iBoot/config/s8000ref-config-base.mk create mode 100644 apps/iBoot/config/s8000sim-config.mk create mode 100644 apps/iBoot/config/s8001fpga-config.mk create mode 100644 apps/iBoot/config/s8001ref-config-base.mk create mode 100644 apps/iBoot/config/s8001sim-config.mk create mode 100644 apps/iBoot/config/s8003fpga-config.mk create mode 100644 apps/iBoot/config/s8003sim-config.mk create mode 100644 apps/iBoot/config/swifter-config.mk create mode 100644 apps/iBoot/config/t7000fpga-config.mk create mode 100644 apps/iBoot/config/t7001fpga-config.mk create mode 100644 apps/iBoot/config/t7001padsim-config.mk create mode 100644 apps/iBoot/config/t8002fpga-config.mk create mode 100644 apps/iBoot/config/t8002sim-config.mk create mode 100644 apps/iBoot/config/t8010fpga-config.mk create mode 100644 apps/iBoot/config/t8010sim-config.mk create mode 100644 apps/iBoot/config/typhonic-config.mk create mode 100644 apps/iBoot/config/watch2-config-base.mk create mode 100644 apps/iBoot/debugcmds.c create mode 100644 apps/iBoot/default_env.c create mode 100644 apps/iBoot/iBoot.mk create mode 100644 apps/iBoot/main.c create mode 100644 apps/iBoot/menu_commands.c create mode 100644 apps/iBoot/products.mk create mode 100644 apps/iBoot/upgrade.c create mode 100644 arch/arm/asm.S create mode 100644 arch/arm/cache_v7.S create mode 100644 arch/arm/cachedebug_a8.c create mode 100644 arch/arm/context.S create mode 100644 arch/arm/cortex_debug.c create mode 100644 arch/arm/cortex_hang.S create mode 100644 arch/arm/cpu.c create mode 100644 arch/arm/dcc/dcc.c create mode 100644 arch/arm/dcc/rules.mk create mode 100644 arch/arm/entropy.S create mode 100644 arch/arm/exceptions.S create mode 100644 arch/arm/fp.c create mode 100644 arch/arm/handlers.c create mode 100644 arch/arm/include/arch/arch_task.h create mode 100644 arch/arm/include/arch/arm/arm.h create mode 100644 arch/arm/include/arch/arm/assembler.h create mode 100644 arch/arm/link.exp create mode 100644 arch/arm/mmu.c create mode 100644 arch/arm/mpu.c create mode 100644 arch/arm/rules.mk create mode 100644 arch/arm/start.S create mode 100644 arch/arm/task.c create mode 100644 arch/arm64/asm.S create mode 100644 arch/arm64/context.S create mode 100644 arch/arm64/cpu.c create mode 100644 arch/arm64/entropy.S create mode 100644 arch/arm64/exceptions_el1.S create mode 100644 arch/arm64/exceptions_el3.S create mode 100644 arch/arm64/fp.c create mode 100644 arch/arm64/handlers.c create mode 100644 arch/arm64/include/arch/arm64/proc_reg.h create mode 100644 arch/arm64/link.exp create mode 100644 arch/arm64/mmu.c create mode 100644 arch/arm64/mmu_test.c create mode 100644 arch/arm64/rules.mk create mode 100644 arch/arm64/start.S create mode 100644 arch/arm64/task.c create mode 100644 arch/arm64/test.mk create mode 100644 arch/arm64/tests-mmu.mk create mode 100644 arch/arm64/timer.c create mode 100644 docs/Cayman_IOSpreadsheet_Template.xlsx create mode 100644 docs/Doxyfile create mode 100644 docs/Elba_IOSpreadsheet_Template.xlsx create mode 100644 docs/M8_IOSpreadsheet_Template.xlsx create mode 100644 docs/Maui_IOSpreadsheet_Template.xlsx create mode 100644 docs/chain_validation.txt create mode 100644 docs/dcs-specs/Elba_Init_A0_July_15_2015.html create mode 100644 docs/dcs-specs/Elba_Init_B0_Mar_4_2016.html create mode 100644 docs/dcs-specs/Elba_Init_B0_Oct_30_2015.html create mode 100644 docs/dcs-specs/Malta_Init_1200_October_29_2015.html create mode 100644 docs/dcs-specs/Malta_Init_A0_1200_June_17_2015.html create mode 100644 docs/dcs-specs/Malta_Init_A0_May_20_2015.html create mode 100644 docs/dcs-specs/Maui_Init_1200_October_29_2015.html create mode 100644 docs/dcs-specs/Maui_Init_B0_1200_June_2_2015.html create mode 100644 docs/dcs-specs/Maui_Init_B0_May_20_2015.html create mode 100644 docs/fuzzing.txt create mode 100644 docs/iBoot_IO_Spreadsheet_Standard.pages create mode 100644 docs/image3_format.txt create mode 100644 docs/image3_pki_interface.txt create mode 100644 docs/image3_user.txt create mode 100644 docs/mmu64.txt create mode 100644 docs/source_layout.txt create mode 100644 docs/uncrustify.cfg create mode 100644 docs/unittests.txt create mode 100644 docs/upgrade_mode.txt create mode 100644 drivers/aes/aes.c create mode 100644 drivers/aes/rules.mk create mode 100644 drivers/analogix/displayport/displayport.c create mode 100644 drivers/analogix/displayport/include/drivers/displayport/displayport.h create mode 100644 drivers/analogix/displayport/regs.h create mode 100644 drivers/analogix/displayport/rules.mk create mode 100644 drivers/apple/a5iop/a5iop.c create mode 100644 drivers/apple/a5iop/include/drivers/a5iop/a5iop.h create mode 100644 drivers/apple/a5iop/rules.mk create mode 100644 drivers/apple/a7iop/a7iop.c create mode 100644 drivers/apple/a7iop/a7iop_debug.c create mode 100644 drivers/apple/a7iop/include/drivers/a7iop/a7iop.h create mode 100644 drivers/apple/a7iop/rules.mk create mode 100644 drivers/apple/adbe/adbe.c create mode 100644 drivers/apple/adbe/adbe_regs_v1.h create mode 100644 drivers/apple/adbe/adbe_regs_v2.h create mode 100644 drivers/apple/adbe/adbe_regs_v3.h create mode 100644 drivers/apple/adbe/adbe_v1.c create mode 100644 drivers/apple/adbe/adbe_v2.c create mode 100644 drivers/apple/adbe/adbe_v3.c create mode 100644 drivers/apple/adbe/include/drivers/adbe/adbe.h create mode 100644 drivers/apple/adbe/rules.mk create mode 100644 drivers/apple/adfe/adfe.c create mode 100644 drivers/apple/adfe/adfe_regs.h create mode 100644 drivers/apple/adfe/include/drivers/adfe/adfe.h create mode 100644 drivers/apple/adfe/rules.mk create mode 100644 drivers/apple/adfe_v2/adfe_v2.c create mode 100644 drivers/apple/adfe_v2/adfe_v2_regs.h create mode 100644 drivers/apple/adfe_v2/include/drivers/adfe_v2/adfe.h create mode 100644 drivers/apple/adfe_v2/rules.mk create mode 100644 drivers/apple/aes/aes_ap.c create mode 100644 drivers/apple/aes/aes_ap.h create mode 100644 drivers/apple/aes/rules.mk create mode 100644 drivers/apple/aes_s7002/aes_s7002.c create mode 100644 drivers/apple/aes_s7002/aes_s7002.h create mode 100644 drivers/apple/aes_s7002/rules.mk create mode 100644 drivers/apple/aes_v2/aes_v2.c create mode 100644 drivers/apple/aes_v2/aes_v2.h create mode 100644 drivers/apple/aes_v2/rules.mk create mode 100644 drivers/apple/aic/aic.c create mode 100644 drivers/apple/aic/include/drivers/aic/aic.h create mode 100644 drivers/apple/aic/rules.mk create mode 100644 drivers/apple/amc/amc.c create mode 100644 drivers/apple/amc/amc_v2.c create mode 100644 drivers/apple/amc/calibration_v1.c create mode 100644 drivers/apple/amc/include/drivers/amc/amc.h create mode 100644 drivers/apple/amc/include/drivers/amc/amc_phy.h create mode 100644 drivers/apple/amc/include/drivers/amc/amc_regs.h create mode 100644 drivers/apple/amc/include/drivers/amc/amc_regs_v12.h create mode 100644 drivers/apple/amc/include/drivers/amc/amc_regs_v3.h create mode 100644 drivers/apple/amc/include/drivers/amc/amc_regs_v45.h create mode 100644 drivers/apple/amc/rules.mk create mode 100644 drivers/apple/amg/amg.c create mode 100644 drivers/apple/amg/amg.h create mode 100644 drivers/apple/amg/rules.mk create mode 100644 drivers/apple/amp/amp_v1.c create mode 100644 drivers/apple/amp/amp_v2.c create mode 100644 drivers/apple/amp/include/drivers/amp/amp_v1.h create mode 100644 drivers/apple/amp/include/drivers/amp/amp_v2.h create mode 100644 drivers/apple/amp/include/drivers/amp/amp_v2_calibration.h create mode 100644 drivers/apple/amp/rules.mk create mode 100644 drivers/apple/amp_v3/amp_v3.c create mode 100644 drivers/apple/amp_v3/amp_v3_calibration.c create mode 100644 drivers/apple/amp_v3/iboot/amp_v3_shim.c create mode 100644 drivers/apple/amp_v3/iboot/amp_v3_shim.h create mode 100644 drivers/apple/amp_v3/include/amp_v3.h create mode 100644 drivers/apple/amp_v3/include/amp_v3_calibration.h create mode 100644 drivers/apple/amp_v3/rules.mk create mode 100644 drivers/apple/anc/anc_bootrom.c create mode 100644 drivers/apple/anc/anc_bootrom.h create mode 100644 drivers/apple/anc/anc_bootrom_cmds.h create mode 100644 drivers/apple/anc/anc_bootrom_private.h create mode 100644 drivers/apple/anc/anc_bootrom_regs.h create mode 100644 drivers/apple/anc/anc_bootrom_regs_m7.h create mode 100644 drivers/apple/anc/anc_llb.c create mode 100644 drivers/apple/anc/anc_llb.h create mode 100644 drivers/apple/anc/ppn_npl_regs.h create mode 100644 drivers/apple/anc/rules.mk create mode 100644 drivers/apple/anc/util_boot.c create mode 100644 drivers/apple/anc/util_boot.h create mode 100644 drivers/apple/apcie/apcie.c create mode 100644 drivers/apple/apcie/rules.mk create mode 100644 drivers/apple/asp/asp.c create mode 100644 drivers/apple/asp/common_util.c create mode 100644 drivers/apple/asp/common_util.h create mode 100644 drivers/apple/asp/debug.c create mode 100644 drivers/apple/asp/rules.mk create mode 100644 drivers/apple/audio/audio.c create mode 100644 drivers/apple/audio/debug.c create mode 100644 drivers/apple/audio/include/drivers/audio/audio.h create mode 100644 drivers/apple/audio/rules.mk create mode 100644 drivers/apple/ausb/ausb.c create mode 100644 drivers/apple/ausb/ausb.h create mode 100644 drivers/apple/ausb/rules.mk create mode 100644 drivers/apple/ccc/ccc.c create mode 100644 drivers/apple/ccc/include/drivers/ccc/ccc.h create mode 100644 drivers/apple/ccc/rules.mk create mode 100644 drivers/apple/cdma/cdma.c create mode 100644 drivers/apple/cdma/cdma.h create mode 100644 drivers/apple/cdma/cdma_aes.c create mode 100644 drivers/apple/cdma/rules.mk create mode 100644 drivers/apple/consistent_debug/consistent_debug.c create mode 100644 drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_helper_fns.h create mode 100644 drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_registry.h create mode 100644 drivers/apple/consistent_debug/rules.mk create mode 100644 drivers/apple/csi/csi.c create mode 100644 drivers/apple/csi/debug.c create mode 100644 drivers/apple/csi/endpoints/builtin.c create mode 100644 drivers/apple/csi/endpoints/console_ep.c create mode 100644 drivers/apple/csi/endpoints/crashlog_ep.c create mode 100644 drivers/apple/csi/endpoints/management_ep.c create mode 100644 drivers/apple/csi/endpoints/syslog_ep.c create mode 100644 drivers/apple/csi/firmware/csi_firmware.c create mode 100644 drivers/apple/csi/firmware/csi_firmware.h create mode 100644 drivers/apple/csi/firmware/fw_ans.c create mode 100644 drivers/apple/csi/include/csi_private.h create mode 100644 drivers/apple/csi/include/endpoints/console_ep.h create mode 100644 drivers/apple/csi/include/endpoints/crashlog_ep.h create mode 100644 drivers/apple/csi/include/endpoints/management_ep.h create mode 100644 drivers/apple/csi/include/endpoints/syslog_ep.h create mode 100644 drivers/apple/csi/include/queue.h create mode 100644 drivers/apple/csi/rules.mk create mode 100644 drivers/apple/dart_lpae/dart.c create mode 100644 drivers/apple/dart_lpae/dart_regs.h create mode 100644 drivers/apple/dart_lpae/rules.mk create mode 100644 drivers/apple/dcs/dcs.c create mode 100644 drivers/apple/dcs/dcs_calibration.c create mode 100644 drivers/apple/dcs/dcs_calibration_v2.c create mode 100644 drivers/apple/dcs/dcs_init_lib.c create mode 100644 drivers/apple/dcs/include/drivers/dcs/dcs.h create mode 100644 drivers/apple/dcs/include/drivers/dcs/dcs_cal.h create mode 100644 drivers/apple/dcs/include/drivers/dcs/dcs_cal_v2.h create mode 100644 drivers/apple/dcs/include/drivers/dcs/dcs_calibration.h create mode 100644 drivers/apple/dcs/include/drivers/dcs/dcs_init_lib.h create mode 100644 drivers/apple/dcs/include/drivers/dcs/dcs_regs.h create mode 100644 drivers/apple/dcs/rules.mk create mode 100644 drivers/apple/displaypipe/displaypipe.c create mode 100644 drivers/apple/displaypipe/displaypipe.h create mode 100644 drivers/apple/displaypipe/rules.mk create mode 100644 drivers/apple/dither/dither.c create mode 100644 drivers/apple/dither/dither_v2.h create mode 100644 drivers/apple/dither/dither_v3.h create mode 100644 drivers/apple/dither/dither_v4.h create mode 100644 drivers/apple/dither/rules.mk create mode 100644 drivers/apple/dockchannel/dockchannel_regs.h create mode 100644 drivers/apple/dockchannel/dockchannel_uart.c create mode 100644 drivers/apple/dockchannel/include/drivers/dockchannel/dockchannel.h create mode 100644 drivers/apple/dockchannel/rules.mk create mode 100644 drivers/apple/dockfifo/cobs.c create mode 100644 drivers/apple/dockfifo/cobs.h create mode 100644 drivers/apple/dockfifo/dockfifo_bulk.c create mode 100644 drivers/apple/dockfifo/dockfifo_regs.h create mode 100644 drivers/apple/dockfifo/dockfifo_uart.c create mode 100644 drivers/apple/dockfifo/include/drivers/dockfifo/dockfifo.h create mode 100644 drivers/apple/dockfifo/rules.mk create mode 100644 drivers/apple/dpb/dpb.c create mode 100644 drivers/apple/dpb/dpb.h create mode 100644 drivers/apple/dpb/rules.mk create mode 100644 drivers/apple/dpb_v2/dpb_v2.c create mode 100644 drivers/apple/dpb_v2/dpb_v2.h create mode 100644 drivers/apple/dpb_v2/rules.mk create mode 100644 drivers/apple/dwi/dwi.c create mode 100644 drivers/apple/dwi/dwi.h create mode 100644 drivers/apple/dwi/rules.mk create mode 100644 drivers/apple/gpio/gpio.c create mode 100644 drivers/apple/gpio/include/drivers/apple/gpio.h create mode 100644 drivers/apple/gpio/rules.mk create mode 100644 drivers/apple/h2fmi/H2FIL.c create mode 100644 drivers/apple/h2fmi/H2fmi.c create mode 100644 drivers/apple/h2fmi/H2fmi.h create mode 100644 drivers/apple/h2fmi/H2fmi_8920regs.h create mode 100644 drivers/apple/h2fmi/H2fmi_8922regs.h create mode 100644 drivers/apple/h2fmi/H2fmi_8940regs.h create mode 100644 drivers/apple/h2fmi/H2fmi_8945regs.h create mode 100644 drivers/apple/h2fmi/H2fmi_8950regs.h create mode 100644 drivers/apple/h2fmi/H2fmi_boot.c create mode 100644 drivers/apple/h2fmi/H2fmi_debug.c create mode 100644 drivers/apple/h2fmi/H2fmi_dma.h create mode 100644 drivers/apple/h2fmi/H2fmi_dma_iboot.c create mode 100644 drivers/apple/h2fmi/H2fmi_dma_types.h create mode 100644 drivers/apple/h2fmi/H2fmi_erase.c create mode 100644 drivers/apple/h2fmi/H2fmi_iop.c create mode 100644 drivers/apple/h2fmi/H2fmi_iop.h create mode 100644 drivers/apple/h2fmi/H2fmi_misc.c create mode 100644 drivers/apple/h2fmi/H2fmi_ppn.c create mode 100644 drivers/apple/h2fmi/H2fmi_ppn.h create mode 100644 drivers/apple/h2fmi/H2fmi_ppn_fil.c create mode 100644 drivers/apple/h2fmi/H2fmi_ppn_iop.c create mode 100644 drivers/apple/h2fmi/H2fmi_private.h create mode 100644 drivers/apple/h2fmi/H2fmi_read.c create mode 100644 drivers/apple/h2fmi/H2fmi_test.c create mode 100644 drivers/apple/h2fmi/H2fmi_timing.c create mode 100644 drivers/apple/h2fmi/H2fmi_timing.h create mode 100644 drivers/apple/h2fmi/H2fmi_write.c create mode 100644 drivers/apple/h2fmi/boot/H2fmi_bootrom.c create mode 100644 drivers/apple/h2fmi/boot/H2fmi_private.h create mode 100644 drivers/apple/h2fmi/boot/H2fmi_regs.h create mode 100644 drivers/apple/h2fmi/boot/rules.mk create mode 100644 drivers/apple/h2fmi/debug.c create mode 100644 drivers/apple/h2fmi/fmiss.c create mode 100644 drivers/apple/h2fmi/fmiss.h create mode 100644 drivers/apple/h2fmi/fmiss_ppn.c create mode 100644 drivers/apple/h2fmi/fmiss_raw.c create mode 100644 drivers/apple/h2fmi/rules.mk create mode 100644 drivers/apple/h2fmi/soc.h create mode 100644 drivers/apple/iic/iic.c create mode 100644 drivers/apple/iic/iic.h create mode 100644 drivers/apple/iic/rules.mk create mode 100644 drivers/apple/lpdp_phy/include/drivers/lpdp_phy/lpdp_phy.h create mode 100644 drivers/apple/lpdp_phy/lpdp_v1.c create mode 100644 drivers/apple/lpdp_phy/lpdp_v2.c create mode 100644 drivers/apple/lpdp_phy/regs_v1.h create mode 100644 drivers/apple/lpdp_phy/regs_v2.h create mode 100644 drivers/apple/lpdp_phy/rules.mk create mode 100644 drivers/apple/mcu/mcu.c create mode 100644 drivers/apple/mcu/rules.mk create mode 100644 drivers/apple/oscar/include/drivers/oscar/oscar.h create mode 100644 drivers/apple/oscar/oscar.c create mode 100644 drivers/apple/oscar/rules.mk create mode 100644 drivers/apple/prc/prc.c create mode 100644 drivers/apple/prc/prc.h create mode 100644 drivers/apple/prc/rules.mk create mode 100644 drivers/apple/reconfig/reconfig.c create mode 100644 drivers/apple/reconfig/rules.mk create mode 100644 drivers/apple/sep/include/drivers/sep/sep_client.h create mode 100644 drivers/apple/sep/rules.mk create mode 100644 drivers/apple/sep/sep_client.c create mode 100644 drivers/apple/sha2/rules.mk create mode 100644 drivers/apple/sha2/sha2.c create mode 100644 drivers/apple/sha2/sha2.h create mode 100644 drivers/apple/shmcon/rules.mk create mode 100644 drivers/apple/shmcon/shmcon.c create mode 100644 drivers/apple/swifterpmu/power.c create mode 100644 drivers/apple/swifterpmu/power.h create mode 100644 drivers/apple/swifterpmu/rules.mk create mode 100644 drivers/apple/voltage_knobs/include/drivers/voltage_knobs/knobs.h create mode 100644 drivers/apple/voltage_knobs/knobs.c create mode 100644 drivers/apple/voltage_knobs/knobs_s7002.c create mode 100644 drivers/apple/voltage_knobs/knobs_s7002.h create mode 100644 drivers/apple/voltage_knobs/knobs_s8000.c create mode 100644 drivers/apple/voltage_knobs/knobs_s8000.h create mode 100644 drivers/apple/voltage_knobs/knobs_t7000.c create mode 100644 drivers/apple/voltage_knobs/knobs_t7000.h create mode 100644 drivers/apple/voltage_knobs/menu_commands.c create mode 100644 drivers/apple/voltage_knobs/rules.mk create mode 100644 drivers/apple/wpc/rules.mk create mode 100644 drivers/apple/wpc/wpc.c create mode 100644 drivers/apple/wpc/wpc.h create mode 100644 drivers/arasan/sdio/rules.mk create mode 100644 drivers/arasan/sdio/sdiocommon/sdhc_debug.c create mode 100644 drivers/arasan/sdio/sdiocommon/sdhc_debug.h create mode 100644 drivers/arasan/sdio/sdiocommon/sdhc_registers.c create mode 100644 drivers/arasan/sdio/sdiocommon/sdhc_registers.h create mode 100644 drivers/arasan/sdio/sdiocommon/sdio_cccr.h create mode 100644 drivers/arasan/sdio/sdiocommon/sdio_cis.h create mode 100644 drivers/arasan/sdio/sdiocommon/sdio_cmdfields.c create mode 100644 drivers/arasan/sdio/sdiocommon/sdio_cmdfields.h create mode 100644 drivers/arasan/sdio/sdiocommon/sdio_cmdprop.c create mode 100644 drivers/arasan/sdio/sdiocommon/sdio_cmdprop.h create mode 100644 drivers/arasan/sdio/sdiocommon/sdio_types.h create mode 100644 drivers/arasan/sdio/sdiodrv_command.c create mode 100644 drivers/arasan/sdio/sdiodrv_command.h create mode 100644 drivers/arasan/sdio/sdiodrv_config.c create mode 100644 drivers/arasan/sdio/sdiodrv_config.h create mode 100644 drivers/arasan/sdio/sdiodrv_transfer.c create mode 100644 drivers/arasan/sdio/sdiodrv_transfer.h create mode 100644 drivers/backlight/lm3534/library.mk create mode 100644 drivers/backlight/lm3534/lm3534.c create mode 100644 drivers/backlight/lm3534/rules.mk create mode 100644 drivers/backlight/lp8559/lp8559.c create mode 100644 drivers/backlight/lp8559/lp8559.h create mode 100644 drivers/backlight/lp8559/rules.mk create mode 100644 drivers/dialog/charger/rules.mk create mode 100644 drivers/dialog/pmu/NTCTables.h create mode 100644 drivers/dialog/pmu/charger.c create mode 100644 drivers/dialog/pmu/d1755.h create mode 100644 drivers/dialog/pmu/d1815.h create mode 100644 drivers/dialog/pmu/d1881.h create mode 100644 drivers/dialog/pmu/d1946.h create mode 100644 drivers/dialog/pmu/d1972.h create mode 100644 drivers/dialog/pmu/d1974.h create mode 100644 drivers/dialog/pmu/d2018.h create mode 100644 drivers/dialog/pmu/d2045.h create mode 100644 drivers/dialog/pmu/d2089.h create mode 100644 drivers/dialog/pmu/d2186.h create mode 100644 drivers/dialog/pmu/d2207.h create mode 100644 drivers/dialog/pmu/d2231.h create mode 100644 drivers/dialog/pmu/d2238.h create mode 100644 drivers/dialog/pmu/d2255.h create mode 100644 drivers/dialog/pmu/d2257.h create mode 100644 drivers/dialog/pmu/d2355.h create mode 100644 drivers/dialog/pmu/dCommon.h create mode 100644 drivers/dialog/pmu/power.c create mode 100644 drivers/dialog/pmu/rules.mk create mode 100644 drivers/display/edp/edp.c create mode 100644 drivers/display/edp/edp.h create mode 100644 drivers/display/edp/rules.mk create mode 100644 drivers/display/pinot/pinot.c create mode 100644 drivers/display/pinot/pinot.h create mode 100644 drivers/display/pinot/rules.mk create mode 100644 drivers/display/summit/rules.mk create mode 100644 drivers/display/summit/summit.c create mode 100644 drivers/display/summit/summit.h create mode 100644 drivers/display/tmds/rules.mk create mode 100644 drivers/display/tmds/tmds.c create mode 100644 drivers/display/tmds/tmds.h create mode 100644 drivers/display_pmu/beryllium/beryllium.c create mode 100644 drivers/display_pmu/beryllium/rules.mk create mode 100644 drivers/display_pmu/chestnut/chestnut.c create mode 100644 drivers/display_pmu/chestnut/rules.mk create mode 100644 drivers/displayport/controller.c create mode 100644 drivers/displayport/debug.c create mode 100644 drivers/displayport/device.c create mode 100644 drivers/displayport/dpcd.h create mode 100644 drivers/displayport/edid.h create mode 100644 drivers/displayport/process_edid.c create mode 100644 drivers/displayport/rules.mk create mode 100644 drivers/flash_nand/OAM/EmbeddedIOP/WMRBuf.c create mode 100644 drivers/flash_nand/OAM/EmbeddedIOP/WMRFeatures.h create mode 100644 drivers/flash_nand/OAM/EmbeddedIOP/WMROAM.c create mode 100644 drivers/flash_nand/OAM/EmbeddedIOP/WMRPlatform.h create mode 100644 drivers/flash_nand/OAM/EmbeddedIOP/WMRTypes.h create mode 100644 drivers/flash_nand/OAM/WMRBuf.h create mode 100644 drivers/flash_nand/OAM/WMROAM.h create mode 100644 drivers/flash_nand/OAM/iBoot/WMRBuf.c create mode 100644 drivers/flash_nand/OAM/iBoot/WMRBufTypes.h create mode 100644 drivers/flash_nand/OAM/iBoot/WMRFeatures.h create mode 100644 drivers/flash_nand/OAM/iBoot/WMROAM.c create mode 100644 drivers/flash_nand/OAM/iBoot/WMRPlatform.h create mode 100644 drivers/flash_nand/OAM/iBoot/WMRTypes.h create mode 100644 drivers/flash_nand/OAM/rules.mk create mode 100644 drivers/flash_nand/OAM/spTypes.h create mode 100644 drivers/flash_nand/benchmark/L2V_Test.c create mode 100644 drivers/flash_nand/benchmark/benchmark.c create mode 100644 drivers/flash_nand/benchmark/rules.mk create mode 100644 drivers/flash_nand/boot/firmware/nand_firmware.c create mode 100644 drivers/flash_nand/boot/firmware/nand_firmware.h create mode 100644 drivers/flash_nand/boot/firmware/rules.mk create mode 100644 drivers/flash_nand/boot/nand_boot.c create mode 100644 drivers/flash_nand/boot/nand_export.c create mode 100644 drivers/flash_nand/boot/nand_export.h create mode 100644 drivers/flash_nand/boot/nand_part.h create mode 100644 drivers/flash_nand/boot/nand_part_core.c create mode 100644 drivers/flash_nand/boot/nand_part_core.h create mode 100644 drivers/flash_nand/boot/nand_part_interface.h create mode 100644 drivers/flash_nand/boot/nvram/nand_nvram.c create mode 100644 drivers/flash_nand/boot/nvram/nand_nvram_core.c create mode 100644 drivers/flash_nand/boot/nvram/nand_nvram_core.h create mode 100644 drivers/flash_nand/boot/nvram/nand_nvram_dump.c create mode 100644 drivers/flash_nand/boot/nvram/nand_nvram_dump.h create mode 100644 drivers/flash_nand/boot/nvram/nand_nvram_impl.h create mode 100644 drivers/flash_nand/boot/nvram/nand_nvram_platform.h create mode 100644 drivers/flash_nand/boot/nvram/rules.mk create mode 100644 drivers/flash_nand/boot/rules.mk create mode 100644 drivers/flash_nand/boot/syscfg/nand_syscfg.c create mode 100644 drivers/flash_nand/boot/syscfg/rules.mk create mode 100644 drivers/flash_nand/debug.c create mode 100644 drivers/flash_nand/ftl/nand.c create mode 100644 drivers/flash_nand/ftl/rules.mk create mode 100644 drivers/flash_nand/id/nandid.c create mode 100644 drivers/flash_nand/id/nandid.h create mode 100644 drivers/flash_nand/id/rules.mk create mode 100644 drivers/flash_nand/ppn-swiss/export.txt create mode 100644 drivers/flash_nand/ppn-swiss/library.mk create mode 100644 drivers/flash_nand/ppn-swiss/ppn.c create mode 100644 drivers/flash_nand/ppn-swiss/ppn_syscfg.c create mode 100644 drivers/flash_nand/ppn-swiss/rules.mk create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/RegBoth.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/RegSwiss.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/RegVanilla.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBootTypes.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPart.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPartTypes.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNTest.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Assert.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Config.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Defines.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Extern.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Forget.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Forget.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Free.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Init.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Search.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.mak create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Update.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMRFeatures-test.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTLTypes.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_Defines.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_whoami.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMisc.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMiscTypes.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Assert.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Config.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Defines.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump.m create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump_Prefix.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Extern.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_FindFrag.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Free.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Init.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Search.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.mak create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Update.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Valid.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMRFeatures-test.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/compare-valid.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-bb.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-sbs.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/erases-histo.sh create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-0valid.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-high-reads.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/free-space.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/gc-zone-lbas.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-erases.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-userseq.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-valid.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/min-valid.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/print-bb.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/wamp.gdb create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_defines.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_external.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl_types.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLInterface.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLTypes.h create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Test/FILTest.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Test/FPartTest.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Test/FTLTest.c create mode 100644 drivers/flash_nand/ppn/WhimoryPPN/Test/VFLTest.c create mode 100644 drivers/flash_nand/ppn/export.txt create mode 100644 drivers/flash_nand/ppn/library.mk create mode 100644 drivers/flash_nand/ppn/ppn.c create mode 100644 drivers/flash_nand/ppn/ppn_syscfg.c create mode 100644 drivers/flash_nand/ppn/rules.mk create mode 100644 drivers/flash_nand/raw/Whimory/Core/FPart/FPart.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FPart/FPartTypes.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/FTLInterface.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/FTLTypes.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Assert.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Config.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Defines.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Extern.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Forget.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Forget.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Free.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Init.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Search.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.mak create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Update.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMRFeatures-test.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTLTypes.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_Defines.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_whoami.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/VFL/VFLInterface.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/VFL/VFLTypes.h create mode 100644 drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLInterface.c create mode 100644 drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLTypes.h create mode 100644 drivers/flash_nand/raw/Whimory/Exam/ANDStats.c create mode 100644 drivers/flash_nand/raw/Whimory/Exam/ANDStats.h create mode 100644 drivers/flash_nand/raw/Whimory/Exam/WMRExam.c create mode 100644 drivers/flash_nand/raw/Whimory/Exam/WMRExam.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/ANDTypes.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/FIL.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/FILTypes.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/FPart.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/FTL.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/PPN_FIL.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/VFL.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/WMRConfig.h create mode 100644 drivers/flash_nand/raw/Whimory/Inc/WMRTest.h create mode 100644 drivers/flash_nand/raw/Whimory/Test/FILTest.c create mode 100644 drivers/flash_nand/raw/export.txt create mode 100644 drivers/flash_nand/raw/library.mk create mode 100644 drivers/flash_nand/raw/raw_nand.c create mode 100644 drivers/flash_nand/raw/rules.mk create mode 100644 drivers/flash_nand/rules.mk create mode 100644 drivers/flash_nor/nor.c create mode 100644 drivers/flash_nor/rules.mk create mode 100644 drivers/flash_nor/spi/rules.mk create mode 100644 drivers/flash_nor/spi/spi_flash.c create mode 100644 drivers/hdc/boot/rules.mk create mode 100644 drivers/hdc/boot/sw_h2fmi.c create mode 100644 drivers/hdc/boot/sw_h2fmi_private.h create mode 100644 drivers/hdc/hdc.c create mode 100644 drivers/hdc/hdc_private.h create mode 100644 drivers/hdc/rules.mk create mode 100644 drivers/hdmi/controller.c create mode 100644 drivers/hdmi/debug.c create mode 100644 drivers/hdmi/device.c create mode 100644 drivers/hdmi/edid.h create mode 100644 drivers/hdmi/process_edid.c create mode 100644 drivers/hdmi/rules.mk create mode 100644 drivers/idt/idtp9022/idtp9022.c create mode 100644 drivers/idt/idtp9022/rules.mk create mode 100644 drivers/iic/debug.c create mode 100644 drivers/iic/rules.mk create mode 100644 drivers/iic/swiic.c create mode 100644 drivers/intel/thunderbolt_nhi/nhi.c create mode 100644 drivers/intel/thunderbolt_nhi/nhi_protocol.h create mode 100644 drivers/intel/thunderbolt_nhi/rules.mk create mode 100644 drivers/nvme/nvme.c create mode 100644 drivers/nvme/nvme_blockdev.c create mode 100644 drivers/nvme/nvme_blockdev.h create mode 100644 drivers/nvme/nvme_protocol.h create mode 100644 drivers/nvme/rules.mk create mode 100644 drivers/nxp/cbtl1610/cbtl1610.c create mode 100644 drivers/nxp/cbtl1610/rules.mk create mode 100644 drivers/pci/pci.c create mode 100644 drivers/pci/pci_private.h create mode 100644 drivers/pci/rules.mk create mode 100644 drivers/power/hdqgauge/hdqgauge.c create mode 100644 drivers/power/hdqgauge/rules.mk create mode 100644 drivers/primecell/pl080dmac/include/drivers/primecell/pl080dmac.h create mode 100644 drivers/primecell/pl080dmac/pl080dmac.c create mode 100644 drivers/primecell/pl080dmac/pl080dmac_regs.h create mode 100644 drivers/primecell/pl080dmac/rules.mk create mode 100644 drivers/primecell/pl192vic/pl192vic.c create mode 100644 drivers/primecell/pl192vic/pl192vic.h create mode 100644 drivers/primecell/pl192vic/rules.mk create mode 100644 drivers/samsung/aes/aes.c create mode 100644 drivers/samsung/aes/aes.h create mode 100644 drivers/samsung/aes/rules.mk create mode 100644 drivers/samsung/arm7iop/arm7.c create mode 100644 drivers/samsung/arm7iop/rules.mk create mode 100644 drivers/samsung/arm7m/arm7m.c create mode 100644 drivers/samsung/arm7m/include/drivers/arm7m/arm7m.h create mode 100644 drivers/samsung/arm7m/rules.mk create mode 100644 drivers/samsung/clcd_v2/clcd.c create mode 100644 drivers/samsung/clcd_v2/clcd_regs.h create mode 100644 drivers/samsung/clcd_v2/include/drivers/clcd_v2/clcd.h create mode 100644 drivers/samsung/clcd_v2/rules.mk create mode 100644 drivers/samsung/displayport/displayport.c create mode 100644 drivers/samsung/displayport/include/drivers/displayport/displayport.h create mode 100644 drivers/samsung/displayport/regs.h create mode 100644 drivers/samsung/displayport/rules.mk create mode 100644 drivers/samsung/drex/drex.c create mode 100644 drivers/samsung/drex/drex.h create mode 100644 drivers/samsung/drex/rules.mk create mode 100644 drivers/samsung/dwi/dwi.c create mode 100644 drivers/samsung/dwi/dwi.h create mode 100644 drivers/samsung/dwi/rules.mk create mode 100644 drivers/samsung/gpio/gpio.c create mode 100644 drivers/samsung/gpio/gpio.h create mode 100644 drivers/samsung/gpio/rules.mk create mode 100644 drivers/samsung/hdmi8947/hdmi.c create mode 100644 drivers/samsung/hdmi8947/hdmi.h create mode 100644 drivers/samsung/hdmi8947/hdmi_static_config.c create mode 100644 drivers/samsung/hdmi8947/regs.h create mode 100644 drivers/samsung/hdmi8947/rules.mk create mode 100644 drivers/samsung/mipi/dsim.c create mode 100644 drivers/samsung/mipi/dsim.h create mode 100644 drivers/samsung/mipi/rules.mk create mode 100644 drivers/samsung/pke/AppleS5L8900XPKE-hardware.c create mode 100644 drivers/samsung/pke/AppleS5L8900XPKE-hardware.h create mode 100644 drivers/samsung/pke/DevPke_cal_R2modM.S create mode 100644 drivers/samsung/pke/pke.c create mode 100644 drivers/samsung/pke/rules.mk create mode 100644 drivers/samsung/rgbout/include/drivers/rgbout/rgbout.h create mode 100644 drivers/samsung/rgbout/rgbout.c create mode 100644 drivers/samsung/rgbout/rgbout_regs.h create mode 100644 drivers/samsung/rgbout/rules.mk create mode 100644 drivers/samsung/rosc/rosc.c create mode 100644 drivers/samsung/rosc/rosc.h create mode 100644 drivers/samsung/rosc/rules.mk create mode 100644 drivers/samsung/sha1/rules.mk create mode 100644 drivers/samsung/sha1/sha1.c create mode 100644 drivers/samsung/sha1/sha1.h create mode 100644 drivers/samsung/spi/rules.mk create mode 100644 drivers/samsung/spi/spi.c create mode 100644 drivers/samsung/spi/spi.h create mode 100644 drivers/samsung/swi/rules.mk create mode 100644 drivers/samsung/swi/swi.c create mode 100644 drivers/samsung/swi/swi.h create mode 100644 drivers/samsung/timer/rules.mk create mode 100644 drivers/samsung/timer/timer.c create mode 100644 drivers/samsung/timer/timer.h create mode 100644 drivers/samsung/uart/rules.mk create mode 100644 drivers/samsung/uart/uart.c create mode 100644 drivers/samsung/uart/uart.h create mode 100644 drivers/samsung/usbphy/rules.mk create mode 100644 drivers/samsung/usbphy/usbphy.c create mode 100644 drivers/samsung/usbphy/usbphy.h create mode 100644 drivers/sha1/mozilla_sha.c create mode 100644 drivers/sha1/mozilla_sha.h create mode 100644 drivers/sha1/rules.mk create mode 100644 drivers/sha1/sha1.c create mode 100644 drivers/sha1/tests.c create mode 100644 drivers/sha1/tests.mk create mode 100644 drivers/spi/gpio_spi.c create mode 100644 drivers/spi/rules.mk create mode 100644 drivers/synopsys/mipi/dsim.c create mode 100644 drivers/synopsys/mipi/dsim.h create mode 100644 drivers/synopsys/mipi/include/drivers/mipi/mipi.h create mode 100644 drivers/synopsys/mipi/rules.mk create mode 100644 drivers/synopsys/usbotg/rules.mk create mode 100644 drivers/synopsys/usbotg/synopsys_otg.c create mode 100644 drivers/synopsys/usbotg/synopsys_otg_regs.h create mode 100644 drivers/thunderbolt/ipipe.c create mode 100644 drivers/thunderbolt/ipipe_protocol.h create mode 100644 drivers/thunderbolt/rules.mk create mode 100644 drivers/thunderbolt/tbt_control_port.c create mode 100644 drivers/thunderbolt/tbt_control_port.h create mode 100644 drivers/thunderbolt/tbt_cp_crc.c create mode 100644 drivers/thunderbolt/tbt_cp_crc.h create mode 100644 drivers/thunderbolt/tbt_protocol.h create mode 100644 drivers/thunderbolt/tbt_xd_packet.h create mode 100644 drivers/thunderbolt/tbt_xdomain.c create mode 100644 drivers/thunderbolt/tbt_xdomain.h create mode 100644 drivers/thunderbolt/thunderboot.c create mode 100644 drivers/thunderbolt/thunderboot_debug.c create mode 100644 drivers/thunderbolt/thunderboot_protocol.h create mode 100644 drivers/thunderbolt/uuid.c create mode 100644 drivers/thunderbolt/uuid.h create mode 100644 drivers/ti/sn2400/rules.mk create mode 100644 drivers/ti/sn2400/sn2400.c create mode 100644 drivers/ti/ths7383/rules.mk create mode 100644 drivers/ti/ths7383/ths7383.c create mode 100644 drivers/uart/16x50/16x50.c create mode 100644 drivers/uart/16x50/16x50.h create mode 100644 drivers/uart/16x50/rules.mk create mode 100644 drivers/uart/rules.mk create mode 100644 drivers/uart/uart.c create mode 100644 drivers/usb/rules.mk create mode 100644 drivers/usb/usb.c create mode 100644 drivers/usb/usb_controller.c create mode 100644 drivers/usb/usb_core.c create mode 100644 drivers/usb/usb_debug.c create mode 100644 drivers/usb/usb_dfu.c create mode 100644 drivers/usb/usb_dockfifo_controller.c create mode 100644 drivers/usb/usb_serial.c create mode 100644 drivers/usb/usb_transfer.c create mode 100644 include/AssertMacros.h create mode 100644 include/Availability.h create mode 100644 include/arch.h create mode 100644 include/assert.h create mode 100644 include/c++/iostream.h create mode 100644 include/cbuffer.h create mode 100644 include/compiler.h create mode 100644 include/debug.h create mode 100644 include/drivers/aes.h create mode 100644 include/drivers/anc_boot.h create mode 100644 include/drivers/apcie.h create mode 100644 include/drivers/asp.h create mode 100644 include/drivers/buttons.h create mode 100644 include/drivers/charger.h create mode 100644 include/drivers/consistent_debug.h create mode 100644 include/drivers/csi.h create mode 100644 include/drivers/dart.h create mode 100644 include/drivers/display.h create mode 100644 include/drivers/displayAV.h create mode 100644 include/drivers/display_pmu.h create mode 100644 include/drivers/displayport.h create mode 100644 include/drivers/dither.h create mode 100644 include/drivers/dma.h create mode 100644 include/drivers/dpb.h create mode 100644 include/drivers/dram.h create mode 100644 include/drivers/edgeic.h create mode 100644 include/drivers/ethernet.h create mode 100644 include/drivers/flash_nand.h create mode 100644 include/drivers/flash_nor.h create mode 100644 include/drivers/gasgauge.h create mode 100644 include/drivers/hdc.h create mode 100644 include/drivers/hdmi.h create mode 100644 include/drivers/iic.h create mode 100644 include/drivers/iis.h create mode 100644 include/drivers/ipipe.h create mode 100644 include/drivers/mcu.h create mode 100644 include/drivers/mipi.h create mode 100644 include/drivers/miu.h create mode 100644 include/drivers/nand_boot.h create mode 100644 include/drivers/nand_device_tree.h create mode 100644 include/drivers/nand_syscfg.h create mode 100644 include/drivers/nvme.h create mode 100644 include/drivers/pci.h create mode 100644 include/drivers/phy.h create mode 100644 include/drivers/pke.h create mode 100644 include/drivers/power.h create mode 100644 include/drivers/prc.h create mode 100644 include/drivers/process_edid.h create mode 100644 include/drivers/radio.h create mode 100644 include/drivers/reconfig.h create mode 100644 include/drivers/rsecc.h create mode 100644 include/drivers/sha1.h create mode 100644 include/drivers/shmcon.h create mode 100644 include/drivers/spi.h create mode 100644 include/drivers/sw_h2fmi.h create mode 100644 include/drivers/thermal.h create mode 100644 include/drivers/thunderbolt/nhi.h create mode 100644 include/drivers/thunderbolt/thunderboot.h create mode 100644 include/drivers/tristar.h create mode 100644 include/drivers/uart.h create mode 100644 include/drivers/usb/synopsys_otg_public.h create mode 100644 include/drivers/usb/usb_chap9.h create mode 100644 include/drivers/usb/usb_controller.h create mode 100644 include/drivers/usb/usb_core.h create mode 100644 include/drivers/usb/usb_debug.h create mode 100644 include/drivers/usb/usb_public.h create mode 100644 include/drivers/usbphy.h create mode 100644 include/drivers/wpc.h create mode 100644 include/endian_tools.h create mode 100644 include/gcc/limits.h create mode 100644 include/gcc/stdarg.h create mode 100644 include/gcc/syslimits.h create mode 100644 include/lib/DERApTicket.h create mode 100644 include/lib/Image2Format.h create mode 100644 include/lib/blockdev.h create mode 100644 include/lib/cbuf.h create mode 100644 include/lib/cksum.h create mode 100644 include/lib/devicetree.h create mode 100644 include/lib/env.h create mode 100644 include/lib/fs.h create mode 100644 include/lib/heap.h create mode 100644 include/lib/image.h create mode 100644 include/lib/image4_spi.h create mode 100644 include/lib/libc.h create mode 100644 include/lib/libiboot.h create mode 100644 include/lib/lzss.h create mode 100644 include/lib/macho.h create mode 100644 include/lib/mib.h create mode 100644 include/lib/mib_def.h create mode 100644 include/lib/net.h create mode 100644 include/lib/net/arp.h create mode 100644 include/lib/net/callbacks.h create mode 100644 include/lib/net/ethernet.h create mode 100644 include/lib/net/icmp.h create mode 100644 include/lib/net/ipv4.h create mode 100644 include/lib/net/mbuf.h create mode 100644 include/lib/net/udp.h create mode 100644 include/lib/net/xp.h create mode 100644 include/lib/nonce.h create mode 100644 include/lib/nvram.h create mode 100644 include/lib/paint.h create mode 100644 include/lib/paniclog.h create mode 100644 include/lib/partition.h create mode 100644 include/lib/pki.h create mode 100644 include/lib/profile.h create mode 100644 include/lib/ramdisk.h create mode 100644 include/lib/random.h create mode 100644 include/lib/syscfg.h create mode 100644 include/lib/tftp.h create mode 100644 include/lib/ticket.h create mode 100644 include/libkern/OSByteOrder.h create mode 100644 include/list.h create mode 100644 include/non_posix_types.h create mode 100644 include/platform.h create mode 100644 include/platform/breadcrumbs.h create mode 100644 include/platform/chipid.h create mode 100644 include/platform/clocks.h create mode 100644 include/platform/gpio.h create mode 100644 include/platform/int.h create mode 100644 include/platform/memmap_defaults.h create mode 100644 include/platform/miu.h create mode 100644 include/platform/pmgr.h create mode 100644 include/platform/power.h create mode 100644 include/platform/timer.h create mode 100644 include/platform/tunables.h create mode 100644 include/posix/ctype.h create mode 100644 include/posix/errno.h create mode 100644 include/posix/machine/endian.h create mode 100644 include/posix/stdbool.h create mode 100644 include/posix/stdint.h create mode 100644 include/posix/stdio.h create mode 100644 include/posix/stdlib.h create mode 100644 include/posix/string.h create mode 100644 include/posix/sys/cdefs.h create mode 100644 include/posix/sys/errno.h create mode 100644 include/posix/sys/types.h create mode 100644 include/sys.h create mode 100644 include/sys/boot.h create mode 100644 include/sys/callout.h create mode 100644 include/sys/hash.h create mode 100644 include/sys/linker_set.h create mode 100644 include/sys/menu.h create mode 100644 include/sys/security.h create mode 100644 include/sys/task.h create mode 100644 include/target.h create mode 100644 lib/blockdev/blockdev.c create mode 100644 lib/blockdev/debug.c create mode 100644 lib/blockdev/library.mk create mode 100644 lib/blockdev/mem_blockdev.c create mode 100644 lib/blockdev/rules.mk create mode 100644 lib/blockdev/subdev.c create mode 100644 lib/blockdev/tests.c create mode 100644 lib/blockdev/tests.mk create mode 100644 lib/cbuf/cbuf.c create mode 100644 lib/cbuf/library.mk create mode 100644 lib/cbuf/rules.mk create mode 100644 lib/cksum/adler32.c create mode 100644 lib/cksum/arm/adler32vec.S create mode 100644 lib/cksum/arm64/adler32vec.S create mode 100644 lib/cksum/crc.c create mode 100644 lib/cksum/crc32.c create mode 100644 lib/cksum/debug.c create mode 100644 lib/cksum/library.mk create mode 100644 lib/cksum/rules.mk create mode 100644 lib/cksum/siphash.c create mode 100644 lib/cksum/tests.c create mode 100644 lib/cksum/tests.mk create mode 100644 lib/devicetree/devicetree.c create mode 100644 lib/devicetree/devicetree_debug.c create mode 100644 lib/devicetree/devicetree_load.c create mode 100644 lib/devicetree/devicetree_private.h create mode 100644 lib/devicetree/fuzz.c create mode 100644 lib/devicetree/fuzzing-dict.txt create mode 100644 lib/devicetree/library.mk create mode 100644 lib/devicetree/rules.mk create mode 100644 lib/devicetree/tests-fuzz.mk create mode 100644 lib/devicetree/tests.c create mode 100644 lib/devicetree/tests.mk create mode 100644 lib/effaceable/README create mode 100644 lib/effaceable/common/effaceable_context.h create mode 100644 lib/effaceable/common/effaceable_delegation.h create mode 100644 lib/effaceable/common/effaceable_locker.h create mode 100644 lib/effaceable/common/effaceable_nand_core.c create mode 100644 lib/effaceable/common/effaceable_nand_core.h create mode 100644 lib/effaceable/common/effaceable_nor_core.c create mode 100644 lib/effaceable/common/effaceable_nor_core.h create mode 100644 lib/effaceable/common/effaceable_private_types.h create mode 100644 lib/effaceable/common/effaceable_storage_core.c create mode 100644 lib/effaceable/common/effaceable_storage_core.h create mode 100644 lib/effaceable/common/effaceable_storage_dev.h create mode 100644 lib/effaceable/common/include/AppleEffaceableStorageFormat.h create mode 100644 lib/effaceable/common/include/AppleEffaceableStorageKeys.h create mode 100644 lib/effaceable/common/include/effaceable_contract.h create mode 100644 lib/effaceable/common/include/effaceable_debug.h create mode 100644 lib/effaceable/common/queue.h create mode 100644 lib/effaceable/common/rules.mk create mode 100644 lib/effaceable/docs/notes_to_auditors.txt create mode 100644 lib/effaceable/iboot/effaceable_cmd.c create mode 100644 lib/effaceable/iboot/effaceable_storage.c create mode 100644 lib/effaceable/iboot/effaceable_system.c create mode 100644 lib/effaceable/iboot/include/lib/effaceable.h create mode 100644 lib/effaceable/iboot/include/lib/effaceable_impl.h create mode 100644 lib/effaceable/iboot/nand/effaceable_nand.c create mode 100644 lib/effaceable/iboot/nand/include/lib/effaceable_nand.h create mode 100644 lib/effaceable/iboot/nand/rules.mk create mode 100644 lib/effaceable/iboot/nor/effaceable_nor.c create mode 100644 lib/effaceable/iboot/nor/include/lib/effaceable_nor.h create mode 100644 lib/effaceable/iboot/nor/rules.mk create mode 100644 lib/effaceable/iboot/rules.mk create mode 100644 lib/effaceable/iokit/AppleEffaceableNAND.cpp create mode 100644 lib/effaceable/iokit/AppleEffaceableNAND.h create mode 100644 lib/effaceable/iokit/AppleEffaceableNOR.cpp create mode 100644 lib/effaceable/iokit/AppleEffaceableNOR.h create mode 100644 lib/effaceable/iokit/AppleEffaceableStorage.cpp create mode 100644 lib/effaceable/iokit/AppleEffaceableStorage.h create mode 100644 lib/effaceable/iokit/AppleEffaceableStorageUserClient.cpp create mode 100644 lib/effaceable/iokit/AppleEffaceableStorageUserClient.h create mode 100644 lib/effaceable/iokit/Info.plist create mode 100644 lib/effaceable/ios/effaceable.c create mode 100644 lib/effaceable/ios/effaceable.h create mode 100644 lib/env/env.c create mode 100644 lib/env/library.mk create mode 100644 lib/env/rules.mk create mode 100644 lib/env/tests.c create mode 100644 lib/env/tests.mk create mode 100644 lib/fs/debug.c create mode 100644 lib/fs/fs.c create mode 100644 lib/fs/hfs/cache.c create mode 100644 lib/fs/hfs/fuzz.c create mode 100644 lib/fs/hfs/hfs.c create mode 100644 lib/fs/hfs/hfs.h create mode 100644 lib/fs/hfs/hfs_format.h create mode 100644 lib/fs/hfs/hfs_fs.c create mode 100644 lib/fs/hfs/library.mk create mode 100644 lib/fs/hfs/rules.mk create mode 100644 lib/fs/hfs/test-hfs-helper.sh create mode 100644 lib/fs/hfs/tests-common.mk create mode 100644 lib/fs/hfs/tests-fuzz.mk create mode 100644 lib/fs/hfs/tests.c create mode 100644 lib/fs/hfs/tests.mk create mode 100644 lib/fs/library.mk create mode 100644 lib/fs/rules.mk create mode 100644 lib/heap/heap.c create mode 100644 lib/heap/libc_stub.c create mode 100644 lib/heap/library.mk create mode 100644 lib/heap/rules.mk create mode 100644 lib/heap/tests-common.mk create mode 100644 lib/heap/tests-debugging.mk create mode 100644 lib/heap/tests.c create mode 100644 lib/heap/tests.mk create mode 100644 lib/image/debug.c create mode 100644 lib/image/image.c create mode 100644 lib/image/image3/Image3.c create mode 100644 lib/image/image3/Image3.h create mode 100644 lib/image/image3/Image3Format.h create mode 100644 lib/image/image3/Image3SuperBlock.h create mode 100644 lib/image/image3/image3_wrapper.c create mode 100644 lib/image/image3/image3_wrapper.h create mode 100644 lib/image/image3/rules.mk create mode 100644 lib/image/image4/image4_partial.c create mode 100644 lib/image/image4/image4_partial.h create mode 100644 lib/image/image4/image4_wrapper.c create mode 100644 lib/image/image4/image4_wrapper.h create mode 100644 lib/image/image4/rules.mk create mode 100644 lib/image/rules.mk create mode 100644 lib/libbuiltin/arm/builtin_divide.c create mode 100644 lib/libbuiltin/arm/rules.mk create mode 100644 lib/libbuiltin/library.mk create mode 100644 lib/libc++/iostream.cpp create mode 100644 lib/libc++/library.mk create mode 100644 lib/libc++/misc.cpp create mode 100644 lib/libc++/new.cpp create mode 100644 lib/libc++/rules.mk create mode 100644 lib/libc/arm/bcopy.S create mode 100644 lib/libc/arm/bzero.S create mode 100644 lib/libc/arm/rules.mk create mode 100644 lib/libc/arm/strlen.S create mode 100644 lib/libc/arm64/asm.h create mode 100644 lib/libc/arm64/bcopy.S create mode 100644 lib/libc/arm64/bzero.S create mode 100644 lib/libc/arm64/memcpy.S create mode 100644 lib/libc/arm64/memset.S create mode 100644 lib/libc/arm64/rules.mk create mode 100644 lib/libc/atoi.c create mode 100644 lib/libc/ctype.c create mode 100644 lib/libc/endian.c create mode 100644 lib/libc/library.mk create mode 100644 lib/libc/log2.c create mode 100644 lib/libc/memchr.c create mode 100644 lib/libc/memcmp.c create mode 100644 lib/libc/memcpy_chk.c create mode 100644 lib/libc/memmove_chk.c create mode 100644 lib/libc/memscan.c create mode 100644 lib/libc/memset_chk.c create mode 100644 lib/libc/misc.c create mode 100644 lib/libc/printf.c create mode 100644 lib/libc/printf_chk.c create mode 100644 lib/libc/qsort.c create mode 100644 lib/libc/stdio.c create mode 100644 lib/libc/stdlib.c create mode 100644 lib/libc/strchr.c create mode 100644 lib/libc/strcmp.c create mode 100644 lib/libc/strcoll.c create mode 100644 lib/libc/strdup.c create mode 100644 lib/libc/strlcat.c create mode 100644 lib/libc/strlcat_chk.c create mode 100644 lib/libc/strlcpy.c create mode 100644 lib/libc/strlcpy_chk.c create mode 100644 lib/libc/strlen.c create mode 100644 lib/libc/strncmp.c create mode 100644 lib/libc/strnicmp.c create mode 100644 lib/libc/strnlen.c create mode 100644 lib/libc/strpbrk.c create mode 100644 lib/libc/strrchr.c create mode 100644 lib/libc/strsep.c create mode 100644 lib/libc/strspn.c create mode 100644 lib/libc/strstr.c create mode 100644 lib/libc/strtok.c create mode 100644 lib/libc/strtol.c create mode 100644 lib/libc/strtoll.c create mode 100644 lib/libc/strtoul.c create mode 100644 lib/libc/strtoull.c create mode 100644 lib/libc/strxfrm.c create mode 100644 lib/libc/test_printf.c create mode 100644 lib/libc/tests-base.mk create mode 100644 lib/libc/tests-release.mk create mode 100644 lib/libc/tests.mk create mode 100644 lib/libcorecrypto/library.mk create mode 100644 lib/lzss/arm/lzssdec.S create mode 100644 lib/lzss/arm64/lzssdec.S create mode 100644 lib/lzss/library.mk create mode 100644 lib/lzss/lzss.c create mode 100644 lib/lzss/rules.mk create mode 100644 lib/lzss/tests.c create mode 100644 lib/lzss/tests.mk create mode 100644 lib/macho/boot.h create mode 100644 lib/macho/dt.c create mode 100644 lib/macho/kernelcache.c create mode 100644 lib/macho/macho.c create mode 100644 lib/macho/macho_header.h create mode 100644 lib/macho/monitor.c create mode 100644 lib/macho/rules.mk create mode 100644 lib/mib/header.mk create mode 100644 lib/mib/library.mk create mode 100644 lib/mib/mib.base create mode 100644 lib/mib/mib.c create mode 100644 lib/mib/mib_gen_def.awk create mode 100644 lib/mib/mib_gen_hdr.awk create mode 100644 lib/mib/rules.mk create mode 100644 lib/net/arp.c create mode 100644 lib/net/callbacks.c create mode 100644 lib/net/debug.c create mode 100644 lib/net/ethernet.c create mode 100644 lib/net/icmp.c create mode 100644 lib/net/ipv4.c create mode 100644 lib/net/mbuf.c create mode 100644 lib/net/net.c create mode 100644 lib/net/rules.mk create mode 100644 lib/net/udp.c create mode 100644 lib/net/xp.c create mode 100644 lib/nonce/library.mk create mode 100644 lib/nonce/nonce.c create mode 100644 lib/nonce/rules.mk create mode 100644 lib/nvram/fuzz.c create mode 100644 lib/nvram/library.mk create mode 100644 lib/nvram/nvram.c create mode 100644 lib/nvram/rules.mk create mode 100644 lib/nvram/tests-common.mk create mode 100644 lib/nvram/tests-fuzz.mk create mode 100644 lib/nvram/tests.c create mode 100644 lib/nvram/tests.mk create mode 100644 lib/paint/library.mk create mode 100644 lib/paint/paint.c create mode 100644 lib/paint/rules.mk create mode 100644 lib/paint/tests.c create mode 100644 lib/paint/tests.mk create mode 100644 lib/paniclog/library.mk create mode 100644 lib/paniclog/paniclog.c create mode 100644 lib/paniclog/rules.mk create mode 100644 lib/partition/gpt.c create mode 100644 lib/partition/library.mk create mode 100644 lib/partition/lwvm.c create mode 100644 lib/partition/mbr.c create mode 100644 lib/partition/partition.c create mode 100644 lib/partition/partition_private.h create mode 100644 lib/partition/rules.mk create mode 100644 lib/pki/apple_ca.h create mode 100644 lib/pki/chain-validation.c create mode 100644 lib/pki/debug.c create mode 100644 lib/pki/fake_ca.h create mode 100644 lib/pki/libDER/DER_CertCrl.c create mode 100644 lib/pki/libDER/DER_CertCrl.h create mode 100644 lib/pki/libDER/DER_Decode.c create mode 100644 lib/pki/libDER/DER_Decode.h create mode 100644 lib/pki/libDER/DER_Digest.c create mode 100644 lib/pki/libDER/DER_Digest.h create mode 100644 lib/pki/libDER/DER_Encode.c create mode 100644 lib/pki/libDER/DER_Encode.h create mode 100644 lib/pki/libDER/DER_Keys.c create mode 100644 lib/pki/libDER/DER_Keys.h create mode 100644 lib/pki/libDER/asn1Types.h create mode 100644 lib/pki/libDER/libDER.h create mode 100644 lib/pki/libDER/libDER_config.h create mode 100644 lib/pki/libDER/oids.c create mode 100644 lib/pki/libDER/oids.h create mode 100644 lib/pki/libGiants/giantDebug.c create mode 100644 lib/pki/libGiants/giantDebug.h create mode 100644 lib/pki/libGiants/giantExternal.c create mode 100644 lib/pki/libGiants/giantExternal.h create mode 100644 lib/pki/libGiants/giantIntegers.c create mode 100644 lib/pki/libGiants/giantIntegers.h create mode 100644 lib/pki/libGiants/giantMemutils.c create mode 100644 lib/pki/libGiants/giantMod.c create mode 100644 lib/pki/libGiants/giantMod.h create mode 100644 lib/pki/libGiants/giantPlatform.h create mode 100644 lib/pki/libGiants/giantPlatformEmulation.h create mode 100644 lib/pki/libGiants/giantPortCommon.h create mode 100644 lib/pki/libGiants/giantPort_C.c create mode 100644 lib/pki/libGiants/giantPort_Generic.h create mode 100644 lib/pki/libGiants/giantTypes.h create mode 100644 lib/pki/libGiantsUtils/GIReturnString.c create mode 100644 lib/pki/libGiantsUtils/GIReturnString.h create mode 100644 lib/pki/libgRSA/libgRSA.c create mode 100644 lib/pki/libgRSA/libgRSA.h create mode 100644 lib/pki/libgRSA/libgRSA_DER.c create mode 100644 lib/pki/libgRSA/libgRSA_DER.h create mode 100644 lib/pki/libgRSA/libgRSA_config.h create mode 100644 lib/pki/libgRSA/libgRSA_priv.c create mode 100644 lib/pki/libgRSA/libgRSA_priv.h create mode 100644 lib/pki/libgRSA/rsaGiantKey.c create mode 100644 lib/pki/libgRSA/rsaGiantKey.h create mode 100644 lib/pki/libgRSA/rsaPadding.c create mode 100644 lib/pki/libgRSA/rsaPadding.h create mode 100644 lib/pki/libgRSA/rsaRawKey.c create mode 100644 lib/pki/libgRSA/rsaRawKey.h create mode 100644 lib/pki/libgRSA/rsaTypes.h create mode 100644 lib/pki/library.mk create mode 100644 lib/pki/rules.mk create mode 100644 lib/pki/tests/fake-hierarchy-img3-test.txt create mode 100644 lib/pki/tests/intermediate-cert.der create mode 100644 lib/pki/tests/intermediate-key.pem create mode 100644 lib/pki/tests/make-img3-specs create mode 100644 lib/pki/tests/to_binary_hash.c create mode 100644 lib/power/power.c create mode 100644 lib/power/rules.mk create mode 100644 lib/profile/profile.c create mode 100644 lib/profile/rules.mk create mode 100644 lib/ramdisk/library.mk create mode 100644 lib/ramdisk/ramdisk.c create mode 100644 lib/ramdisk/rules.mk create mode 100644 lib/random/library.mk create mode 100644 lib/random/random.c create mode 100644 lib/random/rules.mk create mode 100644 lib/syscfg/library.mk create mode 100644 lib/syscfg/rules.mk create mode 100644 lib/syscfg/syscfg.c create mode 100644 lib/syscfg/tests.c create mode 100644 lib/syscfg/tests.mk create mode 100644 lib/tftp/debug.c create mode 100644 lib/tftp/rules.mk create mode 100644 lib/tftp/tftp.c create mode 100644 lib/ticket/DERApTicket.c create mode 100644 lib/ticket/fuzz.c create mode 100644 lib/ticket/library.mk create mode 100644 lib/ticket/rules.mk create mode 100644 lib/ticket/tests-fuzz.mk create mode 100644 lib/ticket/ticket.c create mode 100644 makefiles/build.mk create mode 100644 makefiles/config.mk create mode 100644 makefiles/device_map.mk create mode 100644 makefiles/format-headerfile.awk create mode 100644 makefiles/headers.mk create mode 100644 makefiles/lib.mk create mode 100644 makefiles/libraries.mk create mode 100644 makefiles/macros.mk create mode 100644 makefiles/main-nested-module.mk create mode 100644 makefiles/main.mk create mode 100644 makefiles/test.mk create mode 100644 makefiles/tests.mk create mode 100644 makefiles/tools.mk create mode 100644 platform/defaults/chipid_get_raw_production_mode.c create mode 100644 platform/defaults/formatter.awk create mode 100644 platform/defaults/library.mk create mode 100644 platform/defaults/lister.awk create mode 100644 platform/defaults/platform.defaults create mode 100644 platform/defaults/platform_get_default_gpio_cfg.c create mode 100644 platform/defaults/platform_get_memory_region.c create mode 100644 platform/defaults/platform_get_spi_frequency.c create mode 100644 platform/defaults/platform_memory_map.c create mode 100644 platform/defaults/platform_restore_system.c create mode 100644 platform/defaults/rules.mk create mode 100644 platform/defaults/target_get_boot_battery_capacity.c create mode 100644 platform/defaults/target_get_precharge_gg_flag_mask.c create mode 100644 platform/defaults/target_get_property.c create mode 100644 platform/defaults/target_get_property_base.c create mode 100644 platform/defaults/template.c create mode 100644 platform/generic/breadcrumbs.c create mode 100644 platform/generic/default_mib.c create mode 100644 platform/generic/defaults.c create mode 100644 platform/generic/library.mk create mode 100644 platform/generic/platform_dep.c create mode 100644 platform/generic/platform_indep.c create mode 100644 platform/generic/platform_info.S create mode 100644 platform/generic/pmgr/pmgr_binning.c create mode 100644 platform/generic/pmgr/pmgr_binning_menu.c create mode 100644 platform/generic/pmgr/rules.mk create mode 100644 platform/generic/rules.mk create mode 100644 platform/generic/target_dep.c create mode 100644 platform/generic/target_indep.c create mode 100644 platform/generic/target_pass_boot_manifest.c create mode 100644 platform/s5l8747x/asm.S create mode 100644 platform/s5l8747x/chipid/chipid.c create mode 100644 platform/s5l8747x/chipid/rules.mk create mode 100644 platform/s5l8747x/clocks/clocks.c create mode 100644 platform/s5l8747x/clocks/rules.mk create mode 100644 platform/s5l8747x/include/platform/gpiodef.h create mode 100644 platform/s5l8747x/include/platform/image_devices.h create mode 100644 platform/s5l8747x/include/platform/memmap.h create mode 100644 platform/s5l8747x/include/platform/pinconfig.h create mode 100644 platform/s5l8747x/include/platform/soc/chipid.h create mode 100644 platform/s5l8747x/include/platform/soc/clocks.h create mode 100644 platform/s5l8747x/include/platform/soc/hwclocks.h create mode 100644 platform/s5l8747x/include/platform/soc/hwisr.h create mode 100644 platform/s5l8747x/include/platform/soc/hwregbase.h create mode 100644 platform/s5l8747x/include/platform/soc/miu.h create mode 100644 platform/s5l8747x/include/platform/soc/power.h create mode 100644 platform/s5l8747x/include/platform/soc/sdo.h create mode 100644 platform/s5l8747x/include/platform/trampoline.h create mode 100644 platform/s5l8747x/include/platform/usbconfig.h create mode 100644 platform/s5l8747x/init.c create mode 100644 platform/s5l8747x/miu/miu.c create mode 100644 platform/s5l8747x/miu/rules.mk create mode 100644 platform/s5l8747x/pmgr/pmgr.c create mode 100644 platform/s5l8747x/pmgr/rules.mk create mode 100644 platform/s5l8747x/rules.mk create mode 100644 platform/s5l8940x/amc/amc_s5l8940x.c create mode 100644 platform/s5l8940x/amc/amc_s5l8947x.c create mode 100644 platform/s5l8940x/amc/rules.mk create mode 100644 platform/s5l8940x/chipid/chipid.c create mode 100644 platform/s5l8940x/chipid/rules.mk create mode 100644 platform/s5l8940x/include/platform/amcconfig.h create mode 100644 platform/s5l8940x/include/platform/amcconfig_s5l8940x.h create mode 100644 platform/s5l8940x/include/platform/amcconfig_s5l8942x.h create mode 100644 platform/s5l8940x/include/platform/amcconfig_s5l8947x.h create mode 100644 platform/s5l8940x/include/platform/amgconfig.h create mode 100644 platform/s5l8940x/include/platform/ampconfig.h create mode 100644 platform/s5l8940x/include/platform/boot_pins.h create mode 100644 platform/s5l8940x/include/platform/boot_pins_s5l8940x.h create mode 100644 platform/s5l8940x/include/platform/boot_pins_s5l8942x.h create mode 100644 platform/s5l8940x/include/platform/boot_pins_s5l8947x.h create mode 100644 platform/s5l8940x/include/platform/gpiodef.h create mode 100644 platform/s5l8940x/include/platform/gpiodef_s5l8940x.h create mode 100644 platform/s5l8940x/include/platform/gpiodef_s5l8942x.h create mode 100644 platform/s5l8940x/include/platform/gpiodef_s5l8947x.h create mode 100644 platform/s5l8940x/include/platform/image_devices.h create mode 100644 platform/s5l8940x/include/platform/memconfig.h create mode 100644 platform/s5l8940x/include/platform/memmap.h create mode 100644 platform/s5l8940x/include/platform/pinconfig_s5l8940x.h create mode 100644 platform/s5l8940x/include/platform/pinconfig_s5l8942x.h create mode 100644 platform/s5l8940x/include/platform/pinconfig_s5l8947x.h create mode 100644 platform/s5l8940x/include/platform/soc/chipid.h create mode 100644 platform/s5l8940x/include/platform/soc/display.h create mode 100644 platform/s5l8940x/include/platform/soc/display_timings.h create mode 100644 platform/s5l8940x/include/platform/soc/hwclocks.h create mode 100644 platform/s5l8940x/include/platform/soc/hwdmachannels.h create mode 100644 platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8940x.h create mode 100644 platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8942x.h create mode 100644 platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8947x.h create mode 100644 platform/s5l8940x/include/platform/soc/hwisr.h create mode 100644 platform/s5l8940x/include/platform/soc/hwregbase.h create mode 100644 platform/s5l8940x/include/platform/soc/miu.h create mode 100644 platform/s5l8940x/include/platform/soc/pmgr.h create mode 100644 platform/s5l8940x/include/platform/trampoline.h create mode 100644 platform/s5l8940x/include/platform/usbconfig.h create mode 100644 platform/s5l8940x/init.c create mode 100644 platform/s5l8940x/iop_init.c create mode 100644 platform/s5l8940x/miu/miu.c create mode 100644 platform/s5l8940x/miu/rules.mk create mode 100644 platform/s5l8940x/pinconfig_s5l8940x.c create mode 100644 platform/s5l8940x/pinconfig_s5l8942x.c create mode 100644 platform/s5l8940x/pinconfig_s5l8947x.c create mode 100644 platform/s5l8940x/pmgr/pmgr.c create mode 100644 platform/s5l8940x/pmgr/rules.mk create mode 100644 platform/s5l8940x/rules.mk create mode 100644 platform/s5l8945x/amc/amc.c create mode 100644 platform/s5l8945x/amc/rules.mk create mode 100644 platform/s5l8945x/chipid/chipid.c create mode 100644 platform/s5l8945x/chipid/rules.mk create mode 100644 platform/s5l8945x/include/platform/amcconfig.h create mode 100644 platform/s5l8945x/include/platform/amgconfig.h create mode 100644 platform/s5l8945x/include/platform/gpiodef.h create mode 100644 platform/s5l8945x/include/platform/image_devices.h create mode 100644 platform/s5l8945x/include/platform/memconfig.h create mode 100644 platform/s5l8945x/include/platform/memmap.h create mode 100644 platform/s5l8945x/include/platform/pinconfig.h create mode 100644 platform/s5l8945x/include/platform/soc/chipid.h create mode 100644 platform/s5l8945x/include/platform/soc/display.h create mode 100644 platform/s5l8945x/include/platform/soc/display_timings.h create mode 100644 platform/s5l8945x/include/platform/soc/hwclocks.h create mode 100644 platform/s5l8945x/include/platform/soc/hwdmachannels.h create mode 100644 platform/s5l8945x/include/platform/soc/hwisr.h create mode 100644 platform/s5l8945x/include/platform/soc/hwregbase.h create mode 100644 platform/s5l8945x/include/platform/soc/miu.h create mode 100644 platform/s5l8945x/include/platform/soc/pmgr.h create mode 100644 platform/s5l8945x/include/platform/trampoline.h create mode 100644 platform/s5l8945x/include/platform/usbconfig.h create mode 100644 platform/s5l8945x/init.c create mode 100644 platform/s5l8945x/iop_init.c create mode 100644 platform/s5l8945x/miu/miu.c create mode 100644 platform/s5l8945x/miu/rules.mk create mode 100644 platform/s5l8945x/pmgr/pmgr.c create mode 100644 platform/s5l8945x/pmgr/rules.mk create mode 100644 platform/s5l8945x/rules.mk create mode 100644 platform/s5l8950x/amc/amc.c create mode 100644 platform/s5l8950x/amc/rules.mk create mode 100644 platform/s5l8950x/asm.S create mode 100644 platform/s5l8950x/chipid/chipid.c create mode 100644 platform/s5l8950x/chipid/rules.mk create mode 100644 platform/s5l8950x/include/platform/amcconfig.h create mode 100644 platform/s5l8950x/include/platform/ampconfig.h create mode 100644 platform/s5l8950x/include/platform/gpiodef.h create mode 100644 platform/s5l8950x/include/platform/image_devices.h create mode 100644 platform/s5l8950x/include/platform/memconfig.h create mode 100644 platform/s5l8950x/include/platform/memmap.h create mode 100644 platform/s5l8950x/include/platform/pinconfig.h create mode 100644 platform/s5l8950x/include/platform/soc/chipid.h create mode 100644 platform/s5l8950x/include/platform/soc/display.h create mode 100644 platform/s5l8950x/include/platform/soc/display_timings.h create mode 100644 platform/s5l8950x/include/platform/soc/hwclocks.h create mode 100644 platform/s5l8950x/include/platform/soc/hwdmachannels.h create mode 100644 platform/s5l8950x/include/platform/soc/hwisr.h create mode 100644 platform/s5l8950x/include/platform/soc/hwregbase.h create mode 100644 platform/s5l8950x/include/platform/soc/miu.h create mode 100644 platform/s5l8950x/include/platform/soc/pmgr.h create mode 100644 platform/s5l8950x/include/platform/trampoline.h create mode 100644 platform/s5l8950x/include/platform/usbconfig.h create mode 100644 platform/s5l8950x/init.c create mode 100644 platform/s5l8950x/iop_init.c create mode 100644 platform/s5l8950x/miu/miu.c create mode 100644 platform/s5l8950x/miu/rules.mk create mode 100644 platform/s5l8950x/pmgr/pmgr.c create mode 100644 platform/s5l8950x/pmgr/rules.mk create mode 100644 platform/s5l8950x/rules.mk create mode 100644 platform/s5l8955x/amc/amc.c create mode 100644 platform/s5l8955x/amc/rules.mk create mode 100644 platform/s5l8955x/asm.S create mode 100644 platform/s5l8955x/chipid/chipid.c create mode 100644 platform/s5l8955x/chipid/rules.mk create mode 100644 platform/s5l8955x/include/platform/amcconfig.h create mode 100644 platform/s5l8955x/include/platform/ampconfig.h create mode 100644 platform/s5l8955x/include/platform/gpiodef.h create mode 100644 platform/s5l8955x/include/platform/image_devices.h create mode 100644 platform/s5l8955x/include/platform/memconfig.h create mode 100644 platform/s5l8955x/include/platform/memmap.h create mode 100644 platform/s5l8955x/include/platform/pinconfig.h create mode 100644 platform/s5l8955x/include/platform/soc/chipid.h create mode 100644 platform/s5l8955x/include/platform/soc/display.h create mode 100644 platform/s5l8955x/include/platform/soc/display_timings.h create mode 100644 platform/s5l8955x/include/platform/soc/hwclocks.h create mode 100644 platform/s5l8955x/include/platform/soc/hwdmachannels.h create mode 100644 platform/s5l8955x/include/platform/soc/hwisr.h create mode 100644 platform/s5l8955x/include/platform/soc/hwregbase.h create mode 100644 platform/s5l8955x/include/platform/soc/miu.h create mode 100644 platform/s5l8955x/include/platform/soc/pmgr.h create mode 100644 platform/s5l8955x/include/platform/trampoline.h create mode 100644 platform/s5l8955x/include/platform/usbconfig.h create mode 100644 platform/s5l8955x/init.c create mode 100644 platform/s5l8955x/iop_init.c create mode 100644 platform/s5l8955x/miu/miu.c create mode 100644 platform/s5l8955x/miu/rules.mk create mode 100644 platform/s5l8955x/pmgr/pmgr.c create mode 100644 platform/s5l8955x/pmgr/rules.mk create mode 100644 platform/s5l8955x/rules.mk create mode 100644 platform/s5l8960x/amc/amc.c create mode 100644 platform/s5l8960x/amc/rules.mk create mode 100644 platform/s5l8960x/asm.S create mode 100644 platform/s5l8960x/chipid/chipid.c create mode 100644 platform/s5l8960x/chipid/rules.mk create mode 100644 platform/s5l8960x/error_handler/error_handler.c create mode 100644 platform/s5l8960x/error_handler/rules.mk create mode 100644 platform/s5l8960x/include/platform/amcconfig.h create mode 100644 platform/s5l8960x/include/platform/ampconfig.h create mode 100644 platform/s5l8960x/include/platform/error_handler.h create mode 100644 platform/s5l8960x/include/platform/gpiodef.h create mode 100644 platform/s5l8960x/include/platform/image_devices.h create mode 100644 platform/s5l8960x/include/platform/memconfig.h create mode 100644 platform/s5l8960x/include/platform/memmap.h create mode 100644 platform/s5l8960x/include/platform/pinconfig.h create mode 100644 platform/s5l8960x/include/platform/soc/ccc.h create mode 100644 platform/s5l8960x/include/platform/soc/chipid.h create mode 100644 platform/s5l8960x/include/platform/soc/display.h create mode 100644 platform/s5l8960x/include/platform/soc/display_color_manager_tables.h create mode 100644 platform/s5l8960x/include/platform/soc/display_timings.h create mode 100644 platform/s5l8960x/include/platform/soc/hwclocks.h create mode 100644 platform/s5l8960x/include/platform/soc/hwisr.h create mode 100644 platform/s5l8960x/include/platform/soc/hwregbase.h create mode 100644 platform/s5l8960x/include/platform/soc/miu.h create mode 100644 platform/s5l8960x/include/platform/soc/pmgr.h create mode 100644 platform/s5l8960x/include/platform/trampoline.h create mode 100644 platform/s5l8960x/include/platform/usbconfig.h create mode 100644 platform/s5l8960x/init.c create mode 100644 platform/s5l8960x/miu/miu.c create mode 100644 platform/s5l8960x/miu/rules.mk create mode 100644 platform/s5l8960x/pmgr/pmgr.c create mode 100644 platform/s5l8960x/pmgr/rules.mk create mode 100644 platform/s5l8960x/rules.mk create mode 100644 platform/s5l8960x/trampoline.S create mode 100644 platform/s7002/amc/amc.c create mode 100644 platform/s7002/amc/rules.mk create mode 100644 platform/s7002/asm.S create mode 100644 platform/s7002/chipid/chipid.c create mode 100644 platform/s7002/chipid/rules.mk create mode 100644 platform/s7002/include/platform/amcconfig.h create mode 100644 platform/s7002/include/platform/ampconfig.h create mode 100644 platform/s7002/include/platform/dmin.h create mode 100644 platform/s7002/include/platform/dockfifo_config.h create mode 100644 platform/s7002/include/platform/gpiodef.h create mode 100644 platform/s7002/include/platform/image_devices.h create mode 100644 platform/s7002/include/platform/memconfig.h create mode 100644 platform/s7002/include/platform/memmap.h create mode 100644 platform/s7002/include/platform/pinconfig.h create mode 100644 platform/s7002/include/platform/pl080dmac_config.h create mode 100644 platform/s7002/include/platform/soc/chipid.h create mode 100644 platform/s7002/include/platform/soc/display.h create mode 100644 platform/s7002/include/platform/soc/display_timings.h create mode 100644 platform/s7002/include/platform/soc/hwclocks.h create mode 100644 platform/s7002/include/platform/soc/hwdmachannels.h create mode 100644 platform/s7002/include/platform/soc/hwisr.h create mode 100644 platform/s7002/include/platform/soc/hwregbase.h create mode 100644 platform/s7002/include/platform/soc/miu.h create mode 100644 platform/s7002/include/platform/soc/pmgr.h create mode 100644 platform/s7002/include/platform/soc/reconfig.h create mode 100644 platform/s7002/include/platform/soc/spu.h create mode 100644 platform/s7002/include/platform/trampoline.h create mode 100644 platform/s7002/include/platform/usbconfig.h create mode 100644 platform/s7002/init.c create mode 100644 platform/s7002/miu/miu.c create mode 100644 platform/s7002/miu/rules.mk create mode 100644 platform/s7002/pmgr/pmgr.c create mode 100644 platform/s7002/pmgr/rules.mk create mode 100644 platform/s7002/reconfig/reconfig.c create mode 100644 platform/s7002/reconfig/rules.mk create mode 100644 platform/s7002/rules.mk create mode 100644 platform/s8000/apcie/apcie_v2.c create mode 100644 platform/s8000/apcie/rules.mk create mode 100644 platform/s8000/asm.S create mode 100644 platform/s8000/chipid/chipid.c create mode 100644 platform/s8000/chipid/dvfmperf.c create mode 100644 platform/s8000/chipid/operating_point.c create mode 100644 platform/s8000/chipid/pmgr_binning_s8000.c create mode 100644 platform/s8000/chipid/pmgr_binning_s8001.c create mode 100644 platform/s8000/chipid/pmgr_binning_s8003.c create mode 100644 platform/s8000/chipid/rules.mk create mode 100644 platform/s8000/chipid/tunables_pmgr_product.c create mode 100644 platform/s8000/chipid/tunables_pmgr_s8000.c create mode 100644 platform/s8000/chipid/tunables_pmgr_s8001.c create mode 100644 platform/s8000/chipid/tunables_pmgr_s8001_ipad6b.c create mode 100644 platform/s8000/chipid/tunables_pmgr_s8003.c create mode 100644 platform/s8000/dcs/dcs.c create mode 100644 platform/s8000/dcs/dcs_init_lib_s8000.c create mode 100644 platform/s8000/dcs/dcs_init_lib_s8001.c create mode 100644 platform/s8000/dcs/dcs_init_lib_s8003.c create mode 100644 platform/s8000/dcs/rules.mk create mode 100644 platform/s8000/error_handler/error_handler.c create mode 100644 platform/s8000/error_handler/rules.mk create mode 100644 platform/s8000/include/platform/apcie.h create mode 100644 platform/s8000/include/platform/apcie_regs.h create mode 100644 platform/s8000/include/platform/dcsconfig.h create mode 100644 platform/s8000/include/platform/dcsconfig_s8000.h create mode 100644 platform/s8000/include/platform/dcsconfig_s8001.h create mode 100644 platform/s8000/include/platform/dcsconfig_s8003.h create mode 100644 platform/s8000/include/platform/error_handler.h create mode 100644 platform/s8000/include/platform/gpiodef.h create mode 100644 platform/s8000/include/platform/gpiodef_s8000.h create mode 100644 platform/s8000/include/platform/gpiodef_s8001.h create mode 100644 platform/s8000/include/platform/image_devices.h create mode 100644 platform/s8000/include/platform/memconfig.h create mode 100644 platform/s8000/include/platform/memmap.h create mode 100644 platform/s8000/include/platform/pcimap.h create mode 100644 platform/s8000/include/platform/pinconfig.h create mode 100644 platform/s8000/include/platform/pinconfig_s8000.h create mode 100644 platform/s8000/include/platform/pinconfig_s8001.h create mode 100644 platform/s8000/include/platform/soc/ccc.h create mode 100644 platform/s8000/include/platform/soc/chipid.h create mode 100644 platform/s8000/include/platform/soc/display.h create mode 100644 platform/s8000/include/platform/soc/display_s8000.h create mode 100644 platform/s8000/include/platform/soc/display_s8001.h create mode 100644 platform/s8000/include/platform/soc/display_s8003.h create mode 100644 platform/s8000/include/platform/soc/display_timings.h create mode 100644 platform/s8000/include/platform/soc/dvfmperf.h create mode 100644 platform/s8000/include/platform/soc/hwclocks.h create mode 100644 platform/s8000/include/platform/soc/hwisr.h create mode 100644 platform/s8000/include/platform/soc/hwregbase.h create mode 100644 platform/s8000/include/platform/soc/miu.h create mode 100644 platform/s8000/include/platform/soc/operating_point.h create mode 100644 platform/s8000/include/platform/soc/pmgr.h create mode 100644 platform/s8000/include/platform/soc/reconfig.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000_b0.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003_a0.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000_b0.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003_a0.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001_a0.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001_a0.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_s8001.h create mode 100644 platform/s8000/include/platform/soc/reconfig_sequences_s8001_a0.h create mode 100644 platform/s8000/include/platform/soc/s8000/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8000/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8000/ausr_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/ausr_shm_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/aust_shm_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_shm_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/b0/tunable/aust_shm_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/b0/tunable/x1_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8000/b0/tunable/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_shm_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/c0/tunable/aust_shm_cfg.h create mode 100644 platform/s8000/include/platform/soc/s8000/c0/tunable/x1_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8000/c0/tunable/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8000/x1_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8000/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_phy_glue.h create mode 100644 platform/s8000/include/platform/soc/s8001/a0/tunable/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8001/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8001/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8001/apcie_phy_glue.h create mode 100644 platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_phy_glue.h create mode 100644 platform/s8000/include/platform/soc/s8001/b0/tunable/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8001/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_phy_glue.h create mode 100644 platform/s8000/include/platform/soc/s8003/a0/tunable/x1_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8003/a0/tunable/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_phy_glue.h create mode 100644 platform/s8000/include/platform/soc/s8003/a1/tunable/x1_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8003/a1/tunable/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8003/apcie_common.h create mode 100644 platform/s8000/include/platform/soc/s8003/apcie_config.h create mode 100644 platform/s8000/include/platform/soc/s8003/apcie_phy_glue.h create mode 100644 platform/s8000/include/platform/soc/s8003/x1_pcie_rc.h create mode 100644 platform/s8000/include/platform/soc/s8003/x2_pcie_rc.h create mode 100644 platform/s8000/include/platform/trampoline.h create mode 100644 platform/s8000/include/platform/uartconfig.h create mode 100644 platform/s8000/include/platform/usbconfig.h create mode 100644 platform/s8000/init.c create mode 100644 platform/s8000/miu/miu.c create mode 100644 platform/s8000/miu/rules.mk create mode 100644 platform/s8000/pmgr/pmgr.c create mode 100644 platform/s8000/pmgr/rules.mk create mode 100644 platform/s8000/reconfig.c create mode 100644 platform/s8000/reconfig_s8000_a1.c create mode 100644 platform/s8000/rules.mk create mode 100644 platform/s8000/trampoline.S create mode 100644 platform/t7000/amc/amc.c create mode 100644 platform/t7000/amc/rules.mk create mode 100644 platform/t7000/apcie/apcie_common_regs.h create mode 100644 platform/t7000/apcie/apcie_v1.c create mode 100644 platform/t7000/apcie/rules.mk create mode 100644 platform/t7000/asm.S create mode 100644 platform/t7000/chipid/chipid.c create mode 100644 platform/t7000/chipid/rules.mk create mode 100644 platform/t7000/error_handler/error_handler.c create mode 100644 platform/t7000/error_handler/rules.mk create mode 100644 platform/t7000/include/platform/amcconfig.h create mode 100644 platform/t7000/include/platform/amcconfig_t7000.h create mode 100644 platform/t7000/include/platform/amcconfig_t7001.h create mode 100644 platform/t7000/include/platform/ampconfig.h create mode 100644 platform/t7000/include/platform/apcie_regs.h create mode 100644 platform/t7000/include/platform/error_handler.h create mode 100644 platform/t7000/include/platform/gpiodef.h create mode 100644 platform/t7000/include/platform/gpiodef_t7000.h create mode 100644 platform/t7000/include/platform/gpiodef_t7001.h create mode 100644 platform/t7000/include/platform/image_devices.h create mode 100644 platform/t7000/include/platform/memconfig.h create mode 100644 platform/t7000/include/platform/memmap.h create mode 100644 platform/t7000/include/platform/pcimap.h create mode 100644 platform/t7000/include/platform/pinconfig.h create mode 100644 platform/t7000/include/platform/pinconfig_t7000.h create mode 100644 platform/t7000/include/platform/pinconfig_t7001.h create mode 100644 platform/t7000/include/platform/soc/ccc.h create mode 100644 platform/t7000/include/platform/soc/chipid.h create mode 100644 platform/t7000/include/platform/soc/display.h create mode 100644 platform/t7000/include/platform/soc/display_t7000.h create mode 100644 platform/t7000/include/platform/soc/display_t7001.h create mode 100644 platform/t7000/include/platform/soc/display_timings.h create mode 100644 platform/t7000/include/platform/soc/hwclocks.h create mode 100644 platform/t7000/include/platform/soc/hwisr.h create mode 100644 platform/t7000/include/platform/soc/hwregbase.h create mode 100644 platform/t7000/include/platform/soc/miu.h create mode 100644 platform/t7000/include/platform/soc/pmgr.h create mode 100644 platform/t7000/include/platform/trampoline.h create mode 100644 platform/t7000/include/platform/usbconfig.h create mode 100644 platform/t7000/init.c create mode 100644 platform/t7000/miu/miu.c create mode 100644 platform/t7000/miu/rules.mk create mode 100644 platform/t7000/pmgr/pmgr.c create mode 100644 platform/t7000/pmgr/rules.mk create mode 100644 platform/t7000/rules.mk create mode 100644 platform/t7000/trampoline.S create mode 100644 platform/t8002/asm.S create mode 100644 platform/t8002/chipid/chipid.c create mode 100644 platform/t8002/chipid/rules.mk create mode 100644 platform/t8002/chipid/tunables_pmgr_t8002.c create mode 100644 platform/t8002/dcs/dcs.c create mode 100644 platform/t8002/dcs/dcs_init_lib_t8002.c create mode 100644 platform/t8002/dcs/rules.mk create mode 100644 platform/t8002/include/platform/dcsconfig.h create mode 100644 platform/t8002/include/platform/dmin.h create mode 100644 platform/t8002/include/platform/dockchannel_config.h create mode 100644 platform/t8002/include/platform/gpiodef.h create mode 100644 platform/t8002/include/platform/image_devices.h create mode 100644 platform/t8002/include/platform/memconfig.h create mode 100644 platform/t8002/include/platform/memmap.h create mode 100644 platform/t8002/include/platform/pinconfig.h create mode 100644 platform/t8002/include/platform/soc/aop_dma.h create mode 100644 platform/t8002/include/platform/soc/chipid.h create mode 100644 platform/t8002/include/platform/soc/display.h create mode 100644 platform/t8002/include/platform/soc/display_timings.h create mode 100644 platform/t8002/include/platform/soc/hwclocks.h create mode 100644 platform/t8002/include/platform/soc/hwisr.h create mode 100644 platform/t8002/include/platform/soc/hwregbase.h create mode 100644 platform/t8002/include/platform/soc/miu.h create mode 100644 platform/t8002/include/platform/soc/pmgr.h create mode 100644 platform/t8002/include/platform/soc/spds/aes.h create mode 100644 platform/t8002/include/platform/trampoline.h create mode 100644 platform/t8002/include/platform/uartconfig.h create mode 100644 platform/t8002/include/platform/usbconfig.h create mode 100644 platform/t8002/init.c create mode 100644 platform/t8002/miu/miu.c create mode 100644 platform/t8002/miu/rules.mk create mode 100644 platform/t8002/pmgr/pmgr.c create mode 100644 platform/t8002/pmgr/rules.mk create mode 100644 platform/t8002/rules.mk create mode 100644 platform/t8002/trampoline.S create mode 100644 platform/t8010/apcie/apcie.c create mode 100644 platform/t8010/apcie/rules.mk create mode 100644 platform/t8010/asm.S create mode 100644 platform/t8010/chipid/chipid.c create mode 100644 platform/t8010/chipid/dvfmperf.c create mode 100644 platform/t8010/chipid/operating_point.c create mode 100644 platform/t8010/chipid/rules.mk create mode 100644 platform/t8010/dcs/dcs.c create mode 100644 platform/t8010/dcs/dcs_init_lib_t8010.c create mode 100644 platform/t8010/dcs/rules.mk create mode 100644 platform/t8010/error_handler/error_handler.c create mode 100644 platform/t8010/error_handler/rules.mk create mode 100644 platform/t8010/include/platform/apcie.h create mode 100644 platform/t8010/include/platform/apcie_regs.h create mode 100644 platform/t8010/include/platform/dcsconfig.h create mode 100644 platform/t8010/include/platform/dcsconfig_t8010.h create mode 100644 platform/t8010/include/platform/error_handler.h create mode 100644 platform/t8010/include/platform/gpiodef.h create mode 100644 platform/t8010/include/platform/gpiodef_t8010.h create mode 100644 platform/t8010/include/platform/image_devices.h create mode 100644 platform/t8010/include/platform/memconfig.h create mode 100644 platform/t8010/include/platform/memmap.h create mode 100644 platform/t8010/include/platform/pcimap.h create mode 100644 platform/t8010/include/platform/pinconfig.h create mode 100644 platform/t8010/include/platform/pinconfig_t8010.h create mode 100644 platform/t8010/include/platform/soc/aop_config_sequences.h create mode 100644 platform/t8010/include/platform/soc/ccc.h create mode 100644 platform/t8010/include/platform/soc/chipid.h create mode 100644 platform/t8010/include/platform/soc/display.h create mode 100644 platform/t8010/include/platform/soc/display_timings.h create mode 100644 platform/t8010/include/platform/soc/dvfmperf.h create mode 100644 platform/t8010/include/platform/soc/hwclocks.h create mode 100644 platform/t8010/include/platform/soc/hwisr.h create mode 100644 platform/t8010/include/platform/soc/hwregbase.h create mode 100644 platform/t8010/include/platform/soc/hwregbase_t8010.h create mode 100644 platform/t8010/include/platform/soc/miu.h create mode 100644 platform/t8010/include/platform/soc/operating_point.h create mode 100644 platform/t8010/include/platform/soc/pmgr.h create mode 100644 platform/t8010/include/platform/soc/reconfig.h create mode 100644 platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_common.h create mode 100644 platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_config.h create mode 100644 platform/t8010/include/platform/soc/t8010/a0/tunable/x2_pcie_rc.h create mode 100644 platform/t8010/include/platform/soc/t8010/apcie_common.h create mode 100644 platform/t8010/include/platform/soc/t8010/apcie_config.h create mode 100644 platform/t8010/include/platform/soc/t8010/x2_pcie_rc.h create mode 100644 platform/t8010/include/platform/trampoline.h create mode 100644 platform/t8010/include/platform/uartconfig.h create mode 100644 platform/t8010/include/platform/usbconfig.h create mode 100644 platform/t8010/init.c create mode 100644 platform/t8010/miu/miu.c create mode 100644 platform/t8010/miu/rules.mk create mode 100644 platform/t8010/pmgr/pmgr.c create mode 100644 platform/t8010/pmgr/rules.mk create mode 100644 platform/t8010/rules.mk create mode 100644 platform/t8010/trampoline.S create mode 100644 sys/boot.c create mode 100644 sys/callout.c create mode 100644 sys/debug.c create mode 100644 sys/halt.c create mode 100644 sys/hash.c create mode 100644 sys/init.c create mode 100644 sys/lock.c create mode 100644 sys/mem.c create mode 100644 sys/menu.c create mode 100644 sys/rules.mk create mode 100644 sys/security.c create mode 100644 sys/simple_menu.c create mode 100644 sys/task.c create mode 100644 sys/tests-list.c create mode 100644 sys/tests-sha384.c create mode 100644 sys/tests.mk create mode 100644 sys/time.c create mode 100644 target/alcatrazref/include/target/adbe_settings.h create mode 100644 target/alcatrazref/include/target/aspnandconfig.h create mode 100644 target/alcatrazref/include/target/gpiodef.h create mode 100644 target/alcatrazref/include/target/powerconfig.h create mode 100644 target/alcatrazref/include/target/uartconfig.h create mode 100644 target/alcatrazref/init.c create mode 100644 target/alcatrazref/pinconfig.c create mode 100644 target/alcatrazref/rules.mk create mode 100644 target/b184/include/target/adbe_settings.h create mode 100644 target/b184/include/target/amcconfig.h create mode 100644 target/b184/include/target/aspnandconfig.h create mode 100644 target/b184/include/target/gpiodef.h create mode 100644 target/b184/include/target/powerconfig.h create mode 100644 target/b184/include/target/uartconfig.h create mode 100644 target/b184/include/target/usbconfig.h create mode 100644 target/b184/init.c create mode 100644 target/b184/pinconfig.c create mode 100644 target/b184/properties.c create mode 100644 target/b184/rules.mk create mode 100644 target/b238/include/target/aspnandconfig.h create mode 100644 target/b238/include/target/gpiodef.h create mode 100644 target/b238/include/target/powerconfig.h create mode 100644 target/b238/include/target/uartconfig.h create mode 100644 target/b238/init.c create mode 100644 target/b238/pinconfig.c create mode 100644 target/b238/rules.mk create mode 100644 target/capriref/include/target/adbe_settings.h create mode 100644 target/capriref/include/target/amcconfig.h create mode 100644 target/capriref/include/target/ampconfig.h create mode 100644 target/capriref/include/target/aspnandconfig.h create mode 100644 target/capriref/include/target/gpiodef.h create mode 100644 target/capriref/include/target/powerconfig.h create mode 100644 target/capriref/include/target/uartconfig.h create mode 100644 target/capriref/init.c create mode 100644 target/capriref/pinconfig.c create mode 100644 target/capriref/rules.mk create mode 100644 target/cyclonic/include/target/adbe_settings.h create mode 100644 target/cyclonic/include/target/amcconfig.h create mode 100644 target/cyclonic/include/target/ampconfig.h create mode 100644 target/cyclonic/include/target/aspnandconfig.h create mode 100644 target/cyclonic/include/target/gpiodef.h create mode 100644 target/cyclonic/include/target/nand_spec_tables.h create mode 100644 target/cyclonic/include/target/powerconfig.h create mode 100644 target/cyclonic/include/target/uartconfig.h create mode 100644 target/cyclonic/init.c create mode 100644 target/cyclonic/pinconfig.c create mode 100644 target/cyclonic/rules.mk create mode 100644 target/e86/include/target/adbe_settings.h create mode 100644 target/e86/include/target/aspnandconfig.h create mode 100644 target/e86/include/target/gpiodef.h create mode 100644 target/e86/include/target/powerconfig.h create mode 100644 target/e86/include/target/uartconfig.h create mode 100644 target/e86/init.c create mode 100644 target/e86/pinconfig.c create mode 100644 target/e86/rules.mk create mode 100644 target/e88/include/target/gpiodef.h create mode 100644 target/e88/include/target/nand_spec_tables.h create mode 100644 target/e88/include/target/powerconfig.h create mode 100644 target/e88/include/target/uartconfig.h create mode 100644 target/e88/include/target/usbconfig.h create mode 100644 target/e88/init.c create mode 100644 target/e88/pinconfig.c create mode 100644 target/e88/rules.mk create mode 100644 target/elbaref/include/target/adbe_settings.h create mode 100644 target/elbaref/include/target/boardid.h create mode 100644 target/elbaref/include/target/dcsfixup.h create mode 100644 target/elbaref/include/target/gpiodef.h create mode 100644 target/elbaref/include/target/lpdp_settings.h create mode 100644 target/elbaref/include/target/powerconfig.h create mode 100644 target/elbaref/include/target/uartconfig.h create mode 100644 target/elbaref/init.c create mode 100644 target/elbaref/pinconfig.c create mode 100644 target/elbaref/rules.mk create mode 100644 target/fijiref/include/target/adbe_settings.h create mode 100644 target/fijiref/include/target/aspnandconfig.h create mode 100644 target/fijiref/include/target/gpiodef.h create mode 100644 target/fijiref/include/target/powerconfig.h create mode 100644 target/fijiref/include/target/uartconfig.h create mode 100644 target/fijiref/init.c create mode 100644 target/fijiref/pinconfig.c create mode 100644 target/fijiref/rules.mk create mode 100644 target/iaccy1/display_get_info.c create mode 100644 target/iaccy1/include/target/gpiodef.h create mode 100644 target/iaccy1/include/target/pinconfig.h create mode 100644 target/iaccy1/include/target/uartconfig.h create mode 100644 target/iaccy1/init.c create mode 100644 target/iaccy1/rules.mk create mode 100644 target/ipad2/include/target/amgconfig.h create mode 100644 target/ipad2/include/target/display_gamma_tables.h create mode 100644 target/ipad2/include/target/gpiodef.h create mode 100644 target/ipad2/include/target/nand_spec_tables.h create mode 100644 target/ipad2/include/target/pinconfig.h create mode 100644 target/ipad2/include/target/powerconfig.h create mode 100644 target/ipad2/include/target/radioconfig.h create mode 100644 target/ipad2/include/target/uartconfig.h create mode 100644 target/ipad2/init.c create mode 100644 target/ipad2/pinconfig.c create mode 100644 target/ipad2/properties.c create mode 100644 target/ipad2/rules.mk create mode 100644 target/ipad2b/include/target/display_gamma_tables.h create mode 100644 target/ipad2b/include/target/gpiodef.h create mode 100644 target/ipad2b/include/target/nand_spec_tables.h create mode 100644 target/ipad2b/include/target/pinconfig.h create mode 100644 target/ipad2b/include/target/powerconfig.h create mode 100644 target/ipad2b/include/target/uartconfig.h create mode 100644 target/ipad2b/include/target/usbconfig.h create mode 100644 target/ipad2b/init.c create mode 100644 target/ipad2b/pinconfig.c create mode 100644 target/ipad2b/properties.c create mode 100644 target/ipad2b/rules.mk create mode 100644 target/ipad3/include/target/gpiodef.h create mode 100644 target/ipad3/include/target/nand_spec_tables.h create mode 100644 target/ipad3/include/target/pinconfig.h create mode 100644 target/ipad3/include/target/powerconfig.h create mode 100644 target/ipad3/include/target/radioconfig.h create mode 100644 target/ipad3/include/target/uartconfig.h create mode 100644 target/ipad3/init.c create mode 100644 target/ipad3/pinconfig.c create mode 100644 target/ipad3/properties.c create mode 100644 target/ipad3/rules.mk create mode 100644 target/ipad3b/include/target/gpiodef.h create mode 100644 target/ipad3b/include/target/nand_spec_tables.h create mode 100644 target/ipad3b/include/target/pinconfig.h create mode 100644 target/ipad3b/include/target/powerconfig.h create mode 100644 target/ipad3b/include/target/radioconfig.h create mode 100644 target/ipad3b/include/target/uartconfig.h create mode 100644 target/ipad3b/init.c create mode 100644 target/ipad3b/pinconfig.c create mode 100644 target/ipad3b/properties.c create mode 100644 target/ipad3b/rules.mk create mode 100644 target/ipad4/include/target/adbe_settings.h create mode 100644 target/ipad4/include/target/amcconfig.h create mode 100644 target/ipad4/include/target/aspnandconfig.h create mode 100644 target/ipad4/include/target/gpiodef.h create mode 100644 target/ipad4/include/target/pinconfig.h create mode 100644 target/ipad4/include/target/powerconfig.h create mode 100644 target/ipad4/include/target/uartconfig.h create mode 100644 target/ipad4/include/target/usbconfig.h create mode 100644 target/ipad4/init.c create mode 100644 target/ipad4/pinconfig.c create mode 100644 target/ipad4/properties.c create mode 100644 target/ipad4/rules.mk create mode 100644 target/ipad4b/include/target/adbe_settings.h create mode 100644 target/ipad4b/include/target/aspnandconfig.h create mode 100644 target/ipad4b/include/target/boardid.h create mode 100644 target/ipad4b/include/target/gpiodef.h create mode 100644 target/ipad4b/include/target/pinconfig-nomesa.h create mode 100644 target/ipad4b/include/target/powerconfig.h create mode 100644 target/ipad4b/include/target/uartconfig.h create mode 100644 target/ipad4b/include/target/usbconfig.h create mode 100644 target/ipad4b/init.c create mode 100644 target/ipad4b/pinconfig-mesa.c create mode 100644 target/ipad4b/pinconfig-nomesa.c create mode 100644 target/ipad4b/properties.c create mode 100644 target/ipad4b/rules.mk create mode 100644 target/ipad5/include/target/adbe_settings.h create mode 100644 target/ipad5/include/target/amcconfig.h create mode 100644 target/ipad5/include/target/aspnandconfig.h create mode 100644 target/ipad5/include/target/boardid.h create mode 100644 target/ipad5/include/target/gpiodef.h create mode 100644 target/ipad5/include/target/lpdp_settings.h create mode 100644 target/ipad5/include/target/powerconfig.h create mode 100644 target/ipad5/include/target/uartconfig.h create mode 100644 target/ipad5/init.c create mode 100644 target/ipad5/pinconfig.c create mode 100644 target/ipad5/properties.c create mode 100644 target/ipad5/rules.mk create mode 100644 target/ipad5b/include/target/adbe_settings.h create mode 100644 target/ipad5b/include/target/aspnandconfig.h create mode 100644 target/ipad5b/include/target/boardid.h create mode 100644 target/ipad5b/include/target/gpiodef.h create mode 100644 target/ipad5b/include/target/lpdp_settings.h create mode 100644 target/ipad5b/include/target/powerconfig.h create mode 100644 target/ipad5b/include/target/uartconfig.h create mode 100644 target/ipad5b/init.c create mode 100644 target/ipad5b/pinconfig.c create mode 100644 target/ipad5b/properties.c create mode 100644 target/ipad5b/rules.mk create mode 100644 target/ipad5c/include/target/adbe_settings.h create mode 100644 target/ipad5c/include/target/aspnandconfig.h create mode 100644 target/ipad5c/include/target/boardid.h create mode 100644 target/ipad5c/include/target/gpiodef.h create mode 100644 target/ipad5c/include/target/lpdp_settings.h create mode 100644 target/ipad5c/include/target/powerconfig.h create mode 100644 target/ipad5c/include/target/uartconfig.h create mode 100644 target/ipad5c/init.c create mode 100644 target/ipad5c/pinconfig.c create mode 100644 target/ipad5c/pinconfig_evt.c create mode 100644 target/ipad5c/pinconfig_evt2.c create mode 100644 target/ipad5c/pinconfig_proto2.c create mode 100644 target/ipad5c/pinconfig_proto3.c create mode 100644 target/ipad5c/properties.c create mode 100644 target/ipad5c/rules.mk create mode 100644 target/ipad6b/include/target/adbe_settings.h create mode 100644 target/ipad6b/include/target/boardid.h create mode 100644 target/ipad6b/include/target/dcsfixup.h create mode 100644 target/ipad6b/include/target/display_gamma_tables.h create mode 100644 target/ipad6b/include/target/gpiodef.h create mode 100644 target/ipad6b/include/target/lpdp_settings.h create mode 100644 target/ipad6b/include/target/powerconfig.h create mode 100644 target/ipad6b/include/target/uartconfig.h create mode 100644 target/ipad6b/include/target/usbconfig.h create mode 100644 target/ipad6b/init.c create mode 100644 target/ipad6b/pinconfig.c create mode 100644 target/ipad6b/pinconfig_proto2.c create mode 100644 target/ipad6b/rules.mk create mode 100644 target/ipad6d/include/target/adbe_settings.h create mode 100644 target/ipad6d/include/target/boardid.h create mode 100644 target/ipad6d/include/target/display_gamma_tables.h create mode 100644 target/ipad6d/include/target/gpiodef.h create mode 100644 target/ipad6d/include/target/lpdp_settings.h create mode 100644 target/ipad6d/include/target/powerconfig.h create mode 100644 target/ipad6d/include/target/uartconfig.h create mode 100644 target/ipad6d/include/target/usbconfig.h create mode 100644 target/ipad6d/init.c create mode 100644 target/ipad6d/pinconfig.c create mode 100644 target/ipad6d/rules.mk create mode 100644 target/iphone5/include/target/gpiodef.h create mode 100644 target/iphone5/include/target/nand_spec_tables.h create mode 100644 target/iphone5/include/target/pinconfig.h create mode 100644 target/iphone5/include/target/powerconfig.h create mode 100644 target/iphone5/include/target/radioconfig.h create mode 100644 target/iphone5/include/target/uartconfig.h create mode 100644 target/iphone5/init.c create mode 100644 target/iphone5/pinconfig.c create mode 100644 target/iphone5/rules.mk create mode 100644 target/iphone5b/include/target/gpiodef.h create mode 100644 target/iphone5b/include/target/nand_spec_tables.h create mode 100644 target/iphone5b/include/target/pinconfig.h create mode 100644 target/iphone5b/include/target/powerconfig.h create mode 100644 target/iphone5b/include/target/radioconfig.h create mode 100644 target/iphone5b/include/target/uartconfig.h create mode 100644 target/iphone5b/init.c create mode 100644 target/iphone5b/pinconfig.c create mode 100644 target/iphone5b/rules.mk create mode 100644 target/iphone6/include/target/adbe_settings.h create mode 100644 target/iphone6/include/target/aspnandconfig.h create mode 100644 target/iphone6/include/target/gpiodef.h create mode 100644 target/iphone6/include/target/powerconfig.h create mode 100644 target/iphone6/include/target/uartconfig.h create mode 100644 target/iphone6/init.c create mode 100644 target/iphone6/pinconfig.c create mode 100644 target/iphone6/rules.mk create mode 100644 target/iphone7/include/target/adbe_settings.h create mode 100644 target/iphone7/include/target/aspnandconfig.h create mode 100644 target/iphone7/include/target/gpiodef.h create mode 100644 target/iphone7/include/target/powerconfig.h create mode 100644 target/iphone7/include/target/uartconfig.h create mode 100644 target/iphone7/init.c create mode 100644 target/iphone7/pinconfig.c create mode 100644 target/iphone7/rules.mk create mode 100644 target/iphone8/include/target/adbe_settings.h create mode 100644 target/iphone8/include/target/aspnandconfig.h create mode 100644 target/iphone8/include/target/gpiodef.h create mode 100644 target/iphone8/include/target/powerconfig.h create mode 100644 target/iphone8/include/target/uartconfig.h create mode 100644 target/iphone8/init.c create mode 100644 target/iphone8/pinconfig.c create mode 100644 target/iphone8/rules.mk create mode 100644 target/ipod6/include/target/adbe_settings.h create mode 100644 target/ipod6/include/target/amcconfig.h create mode 100644 target/ipod6/include/target/ampconfig.h create mode 100644 target/ipod6/include/target/aspnandconfig.h create mode 100644 target/ipod6/include/target/cjay.h create mode 100644 target/ipod6/include/target/display_gamma_tables.h create mode 100644 target/ipod6/include/target/gpiodef.h create mode 100644 target/ipod6/include/target/powerconfig.h create mode 100644 target/ipod6/include/target/uartconfig.h create mode 100644 target/ipod6/init.c create mode 100644 target/ipod6/init_fpga.c create mode 100644 target/ipod6/init_fpga.h create mode 100644 target/ipod6/init_product.c create mode 100644 target/ipod6/init_product.h create mode 100644 target/ipod6/init_sim.c create mode 100644 target/ipod6/init_sim.h create mode 100644 target/ipod6/pinconfig_evt.c create mode 100644 target/ipod6/pinconfig_fpga.c create mode 100644 target/ipod6/pinconfig_product.c create mode 100644 target/ipod6/pinconfig_proto2a.c create mode 100644 target/ipod6/pinconfig_proto2b.c create mode 100644 target/ipod6/pinconfig_sim.c create mode 100644 target/ipod6/properties.c create mode 100644 target/ipod6/rules.mk create mode 100644 target/ipod6/target_prepare_dali.c create mode 100644 target/j105/include/target/adbe_settings.h create mode 100644 target/j105/include/target/aspnandconfig.h create mode 100644 target/j105/include/target/gpiodef.h create mode 100644 target/j105/include/target/powerconfig.h create mode 100644 target/j105/include/target/uartconfig.h create mode 100644 target/j105/init.c create mode 100644 target/j105/pinconfig.c create mode 100644 target/j105/properties.c create mode 100644 target/j105/rules.mk create mode 100644 target/j33/include/target/amcconfig.h create mode 100644 target/j33/include/target/amgconfig.h create mode 100644 target/j33/include/target/gpiodef.h create mode 100644 target/j33/include/target/nand_spec_tables.h create mode 100644 target/j33/include/target/powerconfig.h create mode 100644 target/j33/include/target/uartconfig.h create mode 100644 target/j33/init.c create mode 100644 target/j33/pinconfig.c create mode 100644 target/j33/rules.mk create mode 100644 target/j33i/include/target/gpiodef.h create mode 100644 target/j33i/include/target/nand_spec_tables.h create mode 100644 target/j33i/include/target/powerconfig.h create mode 100644 target/j33i/include/target/uartconfig.h create mode 100644 target/j33i/init.c create mode 100644 target/j33i/pinconfig.c create mode 100644 target/j33i/rules.mk create mode 100644 target/j34/include/target/adbe_settings.h create mode 100644 target/j34/include/target/amcconfig.h create mode 100644 target/j34/include/target/aspnandconfig.h create mode 100644 target/j34/include/target/gpiodef.h create mode 100644 target/j34/include/target/powerconfig.h create mode 100644 target/j34/include/target/uartconfig.h create mode 100644 target/j34/include/target/usbconfig.h create mode 100644 target/j34/init.c create mode 100644 target/j34/pinconfig.c create mode 100644 target/j34/properties.c create mode 100644 target/j34/rules.mk create mode 100644 target/j34m/include/target/adbe_settings.h create mode 100644 target/j34m/include/target/amcconfig.h create mode 100644 target/j34m/include/target/aspnandconfig.h create mode 100644 target/j34m/include/target/gpiodef.h create mode 100644 target/j34m/include/target/powerconfig.h create mode 100644 target/j34m/include/target/uartconfig.h create mode 100644 target/j34m/include/target/usbconfig.h create mode 100644 target/j34m/init.c create mode 100644 target/j34m/pinconfig.c create mode 100644 target/j34m/properties.c create mode 100644 target/j34m/rules.mk create mode 100644 target/j42/include/target/adbe_settings.h create mode 100644 target/j42/include/target/amcconfig.h create mode 100644 target/j42/include/target/aspnandconfig.h create mode 100644 target/j42/include/target/gpiodef.h create mode 100644 target/j42/include/target/powerconfig.h create mode 100644 target/j42/include/target/uartconfig.h create mode 100644 target/j42/init.c create mode 100644 target/j42/pinconfig.c create mode 100644 target/j42/properties.c create mode 100644 target/j42/rules.mk create mode 100644 target/k93a/include/target/display_gamma_tables.h create mode 100644 target/k93a/include/target/gpiodef.h create mode 100644 target/k93a/include/target/nand_spec_tables.h create mode 100644 target/k93a/include/target/pinconfig.h create mode 100644 target/k93a/include/target/powerconfig.h create mode 100644 target/k93a/include/target/uartconfig.h create mode 100644 target/k93a/init.c create mode 100644 target/k93a/pinconfig.c create mode 100644 target/k93a/properties.c create mode 100644 target/k93a/rules.mk create mode 100644 target/m7ref/include/target/aspnandconfig.h create mode 100644 target/m7ref/include/target/gpiodef.h create mode 100644 target/m7ref/include/target/powerconfig.h create mode 100644 target/m7ref/include/target/uartconfig.h create mode 100644 target/m7ref/init.c create mode 100644 target/m7ref/pinconfig.c create mode 100644 target/m7ref/rules.mk create mode 100644 target/mauiref/include/target/adbe_settings.h create mode 100644 target/mauiref/include/target/aspnandconfig.h create mode 100644 target/mauiref/include/target/display_gamma_tables.h create mode 100644 target/mauiref/include/target/gpiodef.h create mode 100644 target/mauiref/include/target/powerconfig.h create mode 100644 target/mauiref/include/target/uartconfig.h create mode 100644 target/mauiref/init.c create mode 100644 target/mauiref/pinconfig.c create mode 100644 target/mauiref/rules.mk create mode 100644 target/n102/include/target/adbe_settings.h create mode 100644 target/n102/include/target/aspnandconfig.h create mode 100644 target/n102/include/target/gpiodef.h create mode 100644 target/n102/include/target/powerconfig.h create mode 100644 target/n102/include/target/uartconfig.h create mode 100644 target/n102/init.c create mode 100644 target/n102/pinconfig.c create mode 100644 target/n102/rules.mk create mode 100644 target/n59/include/target/adbe_settings.h create mode 100644 target/n59/include/target/aspnandconfig.h create mode 100644 target/n59/include/target/gpiodef.h create mode 100644 target/n59/include/target/powerconfig.h create mode 100644 target/n59/include/target/uartconfig.h create mode 100644 target/n59/init.c create mode 100644 target/n59/pinconfig.c create mode 100644 target/n59/rules.mk create mode 100644 target/n69/include/target/adbe_settings.h create mode 100644 target/n69/include/target/aspnandconfig.h create mode 100644 target/n69/include/target/gpiodef.h create mode 100644 target/n69/include/target/powerconfig.h create mode 100644 target/n69/include/target/uartconfig.h create mode 100644 target/n69/init.c create mode 100644 target/n69/pinconfig.c create mode 100644 target/n69/rules.mk create mode 100644 target/n78/include/target/gpiodef.h create mode 100644 target/n78/include/target/nand_spec_tables.h create mode 100644 target/n78/include/target/pinconfig.h create mode 100644 target/n78/include/target/powerconfig.h create mode 100644 target/n78/include/target/uartconfig.h create mode 100644 target/n78/include/target/usbconfig.h create mode 100644 target/n78/init.c create mode 100644 target/n78/pinconfig.c create mode 100644 target/n78/rules.mk create mode 100644 target/n94/include/target/gpiodef.h create mode 100644 target/n94/include/target/nand_spec_tables.h create mode 100644 target/n94/include/target/powerconfig.h create mode 100644 target/n94/include/target/radioconfig.h create mode 100644 target/n94/include/target/uartconfig.h create mode 100644 target/n94/init.c create mode 100644 target/n94/pinconfig.c create mode 100644 target/n94/rules.mk create mode 100644 target/s8000fpga/include/target/adbe_settings.h create mode 100644 target/s8000fpga/include/target/aspnandconfig.h create mode 100644 target/s8000fpga/include/target/dcsfixup.h create mode 100644 target/s8000fpga/include/target/dcsfixup_s8000.h create mode 100644 target/s8000fpga/include/target/dcsfixup_s8001.h create mode 100644 target/s8000fpga/include/target/dcsfixup_s8003.h create mode 100644 target/s8000fpga/include/target/gpiodef.h create mode 100644 target/s8000fpga/include/target/uartconfig.h create mode 100644 target/s8000fpga/init.c create mode 100644 target/s8000fpga/pinconfig_s8000fpga.c create mode 100644 target/s8000fpga/pinconfig_s8001fpga.c create mode 100644 target/s8000fpga/rules.mk create mode 100644 target/s8000sim/include/target/adbe_settings.h create mode 100644 target/s8000sim/include/target/aspnandconfig.h create mode 100644 target/s8000sim/include/target/gpiodef.h create mode 100644 target/s8000sim/include/target/nand_spec_tables.h create mode 100644 target/s8000sim/include/target/powerconfig.h create mode 100644 target/s8000sim/include/target/uartconfig.h create mode 100644 target/s8000sim/init.c create mode 100644 target/s8000sim/pinconfig_s8000sim.c create mode 100644 target/s8000sim/pinconfig_s8001sim.c create mode 100644 target/s8000sim/rules.mk create mode 100644 target/t7000fpga/include/target/adbe_settings.h create mode 100644 target/t7000fpga/include/target/amcconfig.h create mode 100644 target/t7000fpga/include/target/amcconfig_t7000.h create mode 100644 target/t7000fpga/include/target/amcconfig_t7001.h create mode 100644 target/t7000fpga/include/target/ampconfig.h create mode 100644 target/t7000fpga/include/target/aspnandconfig.h create mode 100644 target/t7000fpga/include/target/gpiodef.h create mode 100644 target/t7000fpga/include/target/pinconfig.h create mode 100644 target/t7000fpga/include/target/uartconfig.h create mode 100644 target/t7000fpga/init.c create mode 100644 target/t7000fpga/pinconfig_t7000fpga.c create mode 100644 target/t7000fpga/pinconfig_t7001fpga.c create mode 100644 target/t7000fpga/rules.mk create mode 100644 target/t8010fpga/include/target/adbe_settings.h create mode 100644 target/t8010fpga/include/target/dcsfixup.h create mode 100644 target/t8010fpga/include/target/dcsfixup_t8010.h create mode 100644 target/t8010fpga/include/target/gpiodef.h create mode 100644 target/t8010fpga/include/target/uartconfig.h create mode 100644 target/t8010fpga/init.c create mode 100644 target/t8010fpga/pinconfig_t8010fpga.c create mode 100644 target/t8010fpga/rules.mk create mode 100644 target/t8010sim/include/target/gpiodef.h create mode 100644 target/t8010sim/include/target/nand_spec_tables.h create mode 100644 target/t8010sim/include/target/powerconfig.h create mode 100644 target/t8010sim/include/target/uartconfig.h create mode 100644 target/t8010sim/init.c create mode 100644 target/t8010sim/pinconfig_t8010sim.c create mode 100644 target/t8010sim/rules.mk create mode 100644 target/typhonic/include/target/adbe_settings.h create mode 100644 target/typhonic/include/target/amcconfig.h create mode 100644 target/typhonic/include/target/amcconfig_t7000.h create mode 100644 target/typhonic/include/target/amcconfig_t7001.h create mode 100644 target/typhonic/include/target/ampconfig.h create mode 100644 target/typhonic/include/target/aspnandconfig.h create mode 100644 target/typhonic/include/target/gpiodef.h create mode 100644 target/typhonic/include/target/nand_spec_tables.h create mode 100644 target/typhonic/include/target/pinconfig.h create mode 100644 target/typhonic/include/target/powerconfig.h create mode 100644 target/typhonic/include/target/uartconfig.h create mode 100644 target/typhonic/init.c create mode 100644 target/typhonic/pinconfig_t7001padsim.c create mode 100644 target/typhonic/pinconfig_typhonic.c create mode 100644 target/typhonic/rules.mk create mode 100644 target/watch2/include/target/adbe_settings.h create mode 100644 target/watch2/include/target/aspnandconfig.h create mode 100644 target/watch2/include/target/dcsfixup.h create mode 100644 target/watch2/include/target/gpiodef.h create mode 100644 target/watch2/include/target/pinconfig.h create mode 100644 target/watch2/include/target/pinconfig_product.h create mode 100644 target/watch2/include/target/powerconfig.h create mode 100644 target/watch2/include/target/uartconfig.h create mode 100644 target/watch2/init.c create mode 100644 target/watch2/init_fpga.c create mode 100644 target/watch2/init_fpga.h create mode 100644 target/watch2/init_product.c create mode 100644 target/watch2/init_product.h create mode 100644 target/watch2/init_sim.c create mode 100644 target/watch2/init_sim.h create mode 100644 target/watch2/pinconfig_evt.c create mode 100644 target/watch2/pinconfig_fpga.c create mode 100644 target/watch2/pinconfig_product.c create mode 100644 target/watch2/pinconfig_proto2a.c create mode 100644 target/watch2/pinconfig_proto2b.c create mode 100644 target/watch2/pinconfig_sim.c create mode 100644 target/watch2/rules.mk create mode 100644 target/watch2/target_prepare_dali.c create mode 100644 tests/fuzz-main.c create mode 100644 tests/include/linux-support.h create mode 100644 tests/include/mock_syscfg.h create mode 100644 tests/include/non-posix.h create mode 100644 tests/include/unittest.h create mode 100644 tests/mocks/blockdev.c create mode 100644 tests/mocks/sys/lock.c create mode 100644 tests/mocks/sys/security.c create mode 100644 tests/mocks/syscfg.c create mode 100644 tests/non-posix.c create mode 100644 tests/unittest-main.c create mode 100644 tests/unittest-tests.mk create mode 100644 tools/BootX2Bin.cpp create mode 100644 tools/Buffer.cpp create mode 100644 tools/Buffer.h create mode 100644 tools/DeviceTreePatcher.cpp create mode 100644 tools/DeviceTreePatcher.h create mode 100644 tools/Kernelcache.cpp create mode 100644 tools/Kernelcache.h create mode 100644 tools/LoadMachO.cpp create mode 100644 tools/LoadMachO.h create mode 100644 tools/Macho2Bin.c create mode 100644 tools/Makefile create mode 100644 tools/analyzer-report.py create mode 100644 tools/analyzer-suppress.txt create mode 100644 tools/bhc.c create mode 100644 tools/check_liblist.py create mode 100644 tools/check_product_size create mode 100644 tools/code_sizer create mode 100644 tools/config_debug.tcl create mode 100644 tools/config_seq.py create mode 100644 tools/csvtopinconfig.py create mode 100644 tools/gcovr create mode 100644 tools/generate_debug_hashes.py create mode 100644 tools/igmacros create mode 100644 tools/iop_stitcher.c create mode 100644 tools/lldb_init_iboot.py create mode 100644 tools/lldb_os_iboot.py create mode 100644 tools/macho.py create mode 100644 tools/macho_post_process.py create mode 100644 tools/missing-symbol-finder create mode 100644 tools/ofile_cstring_sizes create mode 100644 tools/oldskool_csvtopinconfig.py create mode 100644 tools/parse_release_log.py create mode 100644 tools/pctrace-decoder create mode 100644 tools/pickfiles.sh create mode 100644 tools/ppnfw_asn1.rb create mode 100644 tools/rom-release create mode 100644 tools/scrub-SecureROM.sh create mode 100644 tools/symbolicate-panic diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9dd2c29 --- /dev/null +++ b/Makefile @@ -0,0 +1,292 @@ +# Copyright (C) 2007-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +############################################################################### +# This is the top-level makefile for everything built out of the iBoot source +# tree. + +# Find out what OS we're building on +export BUILD_OS := $(shell uname -s| tr '[:upper:]' '[:lower:]') +$(info %%% building on OS $(BUILD_OS)) + +# Find the root of the source tree from the build system's perspective. +# could be $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) with a newer make +# Note that buildit sets SRCROOT to the destination for installsrc, so it can be +# empty which breaks the VALID_APPLICATIONS probe. +ORIGINAL_SRCROOT := $(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))) +export SRCROOT ?= ${ORIGINAL_SRCROOT} + +# Applications listed in the APPLICATIONS argument are processed one at a +# time, and the per-application makefile in ./makefiles is invoked. +VALID_APPLICATIONS := $(filter-out .%,$(notdir $(shell find $(ORIGINAL_SRCROOT)/apps -mindepth 1 -maxdepth 1 -type d))) + +# Valid applications that should not be built by default +SUPPRESSED_APPLICATIONS := + +# Options that must not be set if building default or multiple APPLICATIONS +SPECIFIC_OPTIONS := TARGETS CONFIGS + +# Default SDK platform +ifeq ($(BUILD_OS),darwin) +export SDK_PLATFORM ?= iphoneos.internal + ifeq ($(SDKROOT),) + SDKROOT_PATH := $(shell xcodebuild -version -sdk $(SDK_PLATFORM) Path) + export SDKROOT := $(SDKROOT_PATH) + else + # SDKROOT may be a canonical name (iphoneos.internal). Normalize into a path. + SDKROOT_PATH := $(shell xcodebuild -version -sdk $(SDKROOT) Path) + export SDKROOT := $(SDKROOT_PATH) + export SDK_PLATFORM := $(shell xcodebuild -version -sdk $(SDKROOT) | head -1 | grep -o '(.*)' | tr -d \(\)) + endif + + export SDK_PRODUCT_NAME := $(shell xcodebuild -version -sdk $(SDKROOT) ProductName) + + ifeq ($(SDKVERSION),) + export SDKVERSION := $(shell xcodebuild -version -sdk $(SDK_PLATFORM) SDKVersion | head -1) + endif + ifeq ($(PLATFORMROOT),) + export PLATFORMROOT := $(shell xcodebuild -version -sdk $(SDK_PLATFORM) PlatformPath) + endif + + export HOST_PLATFORM ?= macosx + ifeq ($(HOST_SDKROOT),) + export HOST_SDKROOT := $(shell xcodebuild -version -sdk $(HOST_PLATFORM) Path) + endif +endif + +export OBJROOT ?= . +export SYMROOT ?= . +export INSTALL_DIR ?= $(DSTROOT)/usr/local/standalone/firmware/ + +############################################################################### +# No user-serviceable parts below + +# Check for spaces in critical paths - we can't handle that +SPACE_CHECK = $(filter ALL,$(and $(findstring $(subst ~, ,~),$(1)),$(error $(2)))) +SDK_ADVICE = A path to a component of the SDK contains one or more spaces; this is not supported. Please relocate your SDK to a path without spaces +$(call SPACE_CHECK,$(SDKROOT_PATH),$(SDK_ADVICE) (SDKROOT=$(SDKROOT_PATH))) +$(call SPACE_CHECK,$(PLATFORMROOT),$(SDK_ADVICE) (PLATFORMROOT=$(PLATFORMROOT))) +$(call SPACE_CHECK,$(HOST_SDKROOT),$(SDK_ADVICE) (HOST_SDKROOT=$(HOST_SDKROOT))) +DIR_ADVICE = A path supplied in a variable contains one or more spaces; this is not supported. +$(call SPACE_CHECK,$(DSTROOT),$(DIR_ADVICE) (DSTROOT=$(DSTROOT))) +$(call SPACE_CHECK,$(OBJROOT),$(DIR_ADVICE) (OBJROOT=$(OBJROOT))) +$(call SPACE_CHECK,$(SYMROOT),$(DIR_ADVICE) (SYMROOT=$(SYMROOT))) +$(call SPACE_CHECK,$(SRCROOT),The iBoot sources are in a folder with one or more spaces in the path; this is not supported (SRCROOT=$(SRCROOT))) + +# Check for the existence of required directories +DIRECTORY_CHECK = $(filter ALL,$(or $(findstring Directory,$(shell stat -Lf %HT $(1))),$(error $(2)))) +DIR_MISSING_ADVICE = A path to a component of the SDK specifies a directory that does not exist +ifeq ($(BUILD_OS),darwin) + $(call DIRECTORY_CHECK,$(SDKROOT_PATH),$(DIR_MISSING_ADVICE) (SDKROOT=$(SDKROOT_PATH))) + $(call DIRECTORY_CHECK,$(PLATFORMROOT),$(DIR_MISSING_ADVICE) (PLATFORMROOT=$(PLATFORMROOT))) + $(call DIRECTORY_CHECK,$(HOST_SDKROOT),$(DIR_MISSING_ADVICE) (HOST_SDKROOT=$(HOST_SDKROOT))) +endif + +# Force the tools to emit consistent punctuation in diagnostics +export LC_ALL=C + +# Work out what we are building +ifneq ($(APPS),) + # APPS is a shortcut for APPLICATIONS, combine if you're dumb enough to specify both + override APPLICATIONS := $(strip $(APPLICATIONS) $(APPS)) +endif +APPLICATIONS ?= $(filter-out $(SUPPRESSED_APPLICATIONS), $(VALID_APPLICATIONS)) +MAKE_APPLICATIONS := $(filter $(VALID_APPLICATIONS), $(APPLICATIONS)) +ERROR_APPLICATIONS := $(filter-out $(VALID_APPLICATIONS), $(APPLICATIONS)) + +ifneq ($(ERROR_APPLICATIONS),) +$(error Unrecognized application(s) - $(ERROR_APPLICATIONS)) +endif + +# Protect against application-specific options if we are building multiple +# applications +ifneq ($(strip $(foreach opt,$(SPECIFIC_OPTIONS),$(value $(opt)))),) +ifneq ($(strip $(shell echo $(MAKE_APPLICATIONS) | wc -w)),1) +$(error must not specify multiple (or default) APPLICATIONS if any of [$(strip $(SPECIFIC_OPTIONS))] is set) +endif +endif + +# Export the list of standard actions, and define targets for each per application. +# Application Makefiles will in turn generate targets based on STANDARD_ACTIONS +# so that we can tunnel more or less arbitrary targets into main.mk. +export STANDARD_ACTIONS := build install library_list +APPLICATION_TEMPLATE := $(addprefix %-,$(MAKE_APPLICATIONS)) +ACTIONS := $(foreach action,$(STANDARD_ACTIONS),$(addprefix $(action)-,$(MAKE_APPLICATIONS))) + +# The 'help' target is special, in that applications are responsible for handling +# it directly. +HELP_APPLICATIONS := $(addprefix help-,$(MAKE_APPLICATIONS)) +ACTIONS += $(HELP_APPLICATIONS) + +# The 'build' targets are special, in that they depend on the non-standard +# 'libraries' target. +BUILD_APPLICATIONS := $(addprefix build-,$(MAKE_APPLICATIONS)) + +# Library list +export LIBLIST := $(OBJROOT)/build/library_list + +# Global header list +export HDRLIST := $(OBJROOT)/build/header_list + +# Where generated host tools are to be found +export TOOLS_BIN := $(OBJROOT)/build/tools + +# Pick up or generate the XBS tag +ifeq ($(RC_ProjectSourceVersion),) +export XBS_BUILD_TAG ?= "$(shell echo localbuild...$$(whoami)...$$(git symbolic-ref --short HEAD 2>/dev/null || echo 'detached')_$$(git rev-parse --short HEAD 2>/dev/null)$$([[ $$(expr $$(git status --porcelain 2>/dev/null| egrep -v '^( |\?\?)' | wc -l)) == '0' ]] || echo '_dirty')...$$(date '+%Y/%m/%d-%H:%M:%S'))" +else +export XBS_BUILD_TAG := "iBoot-$(RC_ProjectSourceVersion)" +endif + +# Work out whether we are building under XBS or just buildit +ifneq ($(RC_XBS),) +ifeq ($(RC_BUILDIT),) +$(warning building under XBS) +export BUILDING_UNDER_XBS := true +else +export BUILDING_UNDER_BUILDIT := true +$(warning building under BUILDIT) +endif +endif + +# Find our tools, now that we know what we're building and in what environment. +include makefiles/tools.mk + +# Verbosity for build rules +VERBOSE ?= NO +ifeq ($(VERBOSE),YES) +export _v = +else +export _v = @ +endif + +# Setup for parallel sub-makes based on 2 times number of logical CPUs +ifndef MAKEJOBS + ifeq ($(BUILD_OS),darwin) + export MAXJOBS := $(shell echo $$((`/usr/sbin//sysctl -n hw.logicalcpu` * 2)) ) + else + export MAXJOBS := $(shell echo $$((`nproc` * 2))) + endif + ifeq ($(BUILDING_UNDER_XBS),true) + export MAKEJOBS := --jobs=$(MAXJOBS) + else + export MAKEJOBS := --jobs=$(shell echo $$(( $(MAXJOBS) > 8 ? 8 : $(MAXJOBS))) ) + endif +endif +# Help does not look so good if built parallel... +ifeq ($(MAKECMDGOALS),help) + export MAKEJOBS = --jobs=1 +endif + +# debug filename hashes are needed for both library and application build phases +export DEBUG_FILENAME_HASHES := $(shell ./tools/generate_debug_hashes.py --src .) + +################################################################################ +# Toplevel rules +# +all: build + +ifeq ($(BUILD_OS),darwin) +# By depending on libraries, we get the depended library pass out of the way +# and then application targets can build parallel. +build: build-headers-and-libraries + +# Don't depend on build; the target install knows how to do that. +install: build-headers-and-libraries +else +# Linux can only build tests for now +build: tests +endif + +# Global headers must be built before the libraries but after we've generated +# the libary list so order them properly with this rule. +build-headers-and-libraries: $(LIBLIST) build-headers build-libraries + +build-libraries: $(LIBLIST) + @echo "%%%% building libraries" + @$(MAKE) $(MAKEJOBS) -f makefiles/libraries.mk build MAKEPHASE=libraries SDKROOT=$(SDKROOT_PATH) + +$(LIBLIST): library_list + @echo "%%%% making $(LIBLIST)" + @cat /dev/null `find $(OBJROOT)/build -name *.library_list` | sort | uniq > $(LIBLIST) + @$(CHECK_LIBLIST) $(LIBLIST) + +build-headers: + @echo "%%%% building global headers" + @cat /dev/null `find $(OBJROOT)/build -name *.header_list` | sort | uniq > $(HDRLIST) + @$(MAKE) $(MAKEJOBS) -f makefiles/headers.mk build MAKEPHASE=headers SDKROOT=$(SDKROOT_PATH) + +clean: + $(_v)rm -rf $(OBJROOT)/build + $(_v)rm -rf $(SYMROOT)/build + +pre-help: + @echo "%%% printing help" + @echo "Valid APPLICATIONS" + @echo " ${VALID_APPLICATIONS}" + @echo "Default APPLICATIONS" + @echo " ${MAKE_APPLICATIONS}" + @echo "" + +help: pre-help $(HELP_APPLICATIONS) + +build-tools: + @echo "%%%% generating build tools" + @$(MAKE) -f tools/Makefile build-tools + +install-tools: + @echo Generating install tools + @$(MAKE) -f tools/Makefile install-tools + +installsrc: + ditto . $(SRCROOT) + +installhdrs: + @echo no headers installed + +build-tests: + @$(MAKE) $(MAKEJOBS) -f makefiles/tests.mk SDKROOT=$(SDKROOT_PATH) build + +.PHONY: tests +tests: + @$(MAKE) $(MAKEJOBS) -f makefiles/tests.mk SDKROOT=$(SDKROOT_PATH) run + +cscope.files: + @echo "Building file list for cscope and tags" + @find . -name '*.h' -type f | grep -v ^..build > _cscope.files 2> /dev/null + @find . -name '*.c' -type f | grep -v ^..build >> _cscope.files 2> /dev/null + @find . -name '*.cpp' -type f | grep -v ^..build >> _cscope.files 2> /dev/null + @find . -name '*.S' -type f | grep -v ^..build >> _cscope.files 2> /dev/null + @echo > cscope.files 2> /dev/null + @sort -u < _cscope.files >> cscope.files 2> /dev/null + @rm -f _cscope.files _cscope.files2 2> /dev/null + +cscope: cscope.files + @echo "Building cscope database" + @cscope -bvU 2> /dev/null + +spotless realclean: + rm -rf build cscope.* + +# Linux only knows how to build tests for now, so elide this on Linux +ifeq ($(BUILD_OS),darwin) +# Define this late, so that manual dependencies stated above for +# the standard actions are satisfied before the automatic depdencies. +$(STANDARD_ACTIONS) : % : $(APPLICATION_TEMPLATE) + +# Build actions require the build-libraries target, which is otherwise only seen as +# a co-dependency of the build target +$(BUILD_APPLICATIONS): build-libraries + +$(ACTIONS): action = $(word 1, $(subst -, ,$@)) +$(ACTIONS): application = $(word 2, $(subst -, ,$@)) +$(ACTIONS): + @echo "%%%%%% $(action) $(application)" + @$(MAKE) $(MAKEJOBS) -f apps/$(application)/$(application).mk $(action) SDKROOT=$(SDKROOT_PATH) APPLICATION=$(application) MAKEPHASE=$(action) +endif diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/apps/EmbeddedIOP/EmbeddedIOP.mk b/apps/EmbeddedIOP/EmbeddedIOP.mk new file mode 100644 index 0000000..ef902db --- /dev/null +++ b/apps/EmbeddedIOP/EmbeddedIOP.mk @@ -0,0 +1,73 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +############################################################################### +# Build rules for the EmbeddedIOP firmware +# +# Recognises values in +# +# BUILDS +# TARGETS +# CONFIGS +# + +VALID_BUILDS := RELEASE DEBUG + +SUPPRESSED_TARGETS:= s5l8720x + +############################################################################### +# No user-serviceable parts below + +CONFIG_DIR := $(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))/config +VALID_TARGETS := $(subst -config.mk,,$(notdir $(wildcard $(CONFIG_DIR)/*-config.mk))) + +BUILDS ?= $(VALID_BUILDS) +MAKE_BUILDS = $(filter $(VALID_BUILDS), $(BUILDS)) + +TARGETS ?= $(filter-out $(SUPPRESSED_TARGETS),$(VALID_TARGETS)) +MAKE_TARGETS = $(filter $(VALID_TARGETS), $(TARGETS)) + +ERROR_TARGETS := $(filter-out $(VALID_TARGETS), $(TARGETS)) + +ifneq ($(ERROR_TARGETS),) +$(error Unrecognized target(s) - $(ERROR_TARGETS)) +endif + +MAKE_PRODUCT = EmbeddedIOP + +LIST = $(foreach build, $(MAKE_BUILDS), $(addprefix $(build)-, $(MAKE_TARGETS))) + +LIST_TEMPLATE := $(addprefix %-,$(LIST)) +$(STANDARD_ACTIONS):%: $(LIST_TEMPLATE) +ACTIONS := $(foreach action,$(STANDARD_ACTIONS),$(addprefix $(action)-,$(LIST))) + +$(ACTIONS): action = $(word 1, $(subst -, ,$@)) +$(ACTIONS): target = $(word 3, $(subst -, ,$@)) +$(ACTIONS): product = $(MAKE_PRODUCT) +$(ACTIONS): build = $(word 2, $(subst -, ,$@)) +$(ACTIONS): install_name = $(product).$(target)$(config).$(build).h +$(ACTIONS): + @echo %%% $(action) $(target)$(config)-$(product)-$(build) + @$(MAKE) -f makefiles/main.mk \ + SUB_TARGET=$(target) \ + CONFIG="" \ + PRODUCT=$(product) \ + BUILD=$(build) \ + INSTALL_NAME=$(install_name) \ + IMAGE_WITH_HEADER=$(SRCROOT)/apps/EmbeddedIOP/EmbeddedIOPFirmware.h \ + BIN_INCLUDES_BSS=true \ + $(action) + +help: + @echo Valid TARGETS + @echo " $(VALID_TARGETS)" + @echo Valid BUILDS + @echo " $(VALID_BUILDS)" + @echo "" + diff --git a/apps/EmbeddedIOP/EmbeddedIOPFirmware.h b/apps/EmbeddedIOP/EmbeddedIOPFirmware.h new file mode 100644 index 0000000..c5876c0 --- /dev/null +++ b/apps/EmbeddedIOP/EmbeddedIOPFirmware.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* EATLINE + * This file is consumed to auto-generate the firmware specfication. EATLINE + * EATLINE + * A line which contains the word EATLINE will be removed. EATLINE + * EATLINE + * Substitution is performed on comment lines beginning with SUBST. Fields EATLINE + * on these lines are separated by ':' characters. EATLINE + * The second field on the line determines the form of substitution, and the fifth EATLINE + * field supplies termination. EATLINE + * EATLINE + * ENV Declares and initialiases a scalar variable with value taken from the EATLINE + * compile-time environment. The variable preamble is read EATLINE + * from the third field, and the environment variable name from EATLINE + * the fourth. EATLINE + * EATLINE + * ENVSTR Declares and initialiases a string variable with value taken from the EATLINE + * compile-time environment. The variable preamble is read EATLINE + * from the third field, and the environment variable name from EATLINE + * the fourth. EATLINE + * EATLINE + * VAR Declares a variable with value taken from the object file. EATLINE + * The variable declaration is read from the third field, and EATLINE + * the symbol name to be looked up in the object file is read EATLINE + * from the fourth. EATLINE + * EATLINE + * FILE The binary file (named in the compile-time environment) is EATLINE + * inserted in the form of lines of 16 comma-separated 8-bit EATLINE + * hex constants, suitable for use as initialisers for an array EATLINE + * of unsigned char. EATLINE + * EATLINE */ + + +/*SUBST:ENVSTR:static const char *fwFirmwareTarget __attribute__((used)) = :SUB_TARGET:;:*/ +/*SUBST:ENVSTR:static const char *fwFirmwareBuild __attribute__((used)) = :BUILD:;:*/ +/*SUBST:ENVSTR:static const char *fwFirmwareVersion __attribute__((used)) = :XBS_BUILD_TAG:;:*/ +/*SUBST:VAR:static unsigned long fwConfigurationOffset __attribute__((used)) = :__iop_config:;:*/ +/*SUBST:VAR:static unsigned long fwHeapBaseOffset __attribute__((used)) = :_heap_base:;:*/ +/*SUBST:VAR:static unsigned long fwHeapSizeOffset __attribute__((used)) = :_heap_size:;:*/ +/*SUBST:VAR:static unsigned long fwPageTableBase __attribute__((used)) = :_tt:;:*/ +/*SUBST:VAR:static unsigned long fwPageTableSize __attribute__((used)) = :_tt_size:;:*/ + +/* IOP panic debug support */ +/*SUBST:VAR:static unsigned long fwPanicStr __attribute__((used)) = :_gPanicStr:;:*/ +/*SUBST:VAR:static unsigned long fwPanicFunc __attribute__((used)) = :_gPanicFunc:;:*/ +/*SUBST:VAR:static unsigned long fwPanicLog __attribute__((used)) = :_gIOPPanicLog:;:*/ +/*SUBST:VAR:static unsigned long fwPanicBytes __attribute__((used)) = :_gIOPPanicBytes:;:*/ +static unsigned long fwPanicBytesMax __attribute__((used)) = +/*SUBST:ENV::IOP_PANIC_LOG_SIZE:;:*/ + +/*EATLINE XXX this may no longer need the section attribute... */ +static unsigned char fwFirmwareImage[] __attribute__ ((aligned(4096))) __attribute__ ((section("__DATA,fwFirmwareImage"))) = { +/*SUBST:FILE:*/ +}; + +/* heap requirements from the IOP configuration */ +static unsigned long fwHeapRequired __attribute__((used)) = +/*SUBST:ENV::IOP_HEAP_REQUIRED:;:*/ + +/* message channel size */ +static unsigned long fwMessageChannelSize __attribute__((used)) = +/*SUBST:ENV::IOP_MESSAGE_CHANNEL_SIZE:;:*/ + +#endif /* _DO_NOT_DEFINE *//* EATLINE */ + diff --git a/apps/EmbeddedIOP/EmbeddedIOPProtocol.h b/apps/EmbeddedIOP/EmbeddedIOPProtocol.h new file mode 100644 index 0000000..ab1bcf2 --- /dev/null +++ b/apps/EmbeddedIOP/EmbeddedIOPProtocol.h @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +/* + * This file defines constants and data structures that comprise the interface protocol between the + * OS driver and the generic IOP firmware. + */ + +/* + * Patch structure. + * + * The IOP firmware contains the original version of this structure. The host driver + * patches it to inform the IOP firmware of its runtime environment before starting it. + * + */ + +struct iop_channel_config { + uint32_t ring_base; + uint32_t ring_size; +}; + +struct iop_configuration { + uint32_t magic; +#define IOP_CONFIG_MAGIC 'cnfg' + + uint32_t options; +#define IOP_OPTION_NO_IDLE (1<<0) /* don't idle */ +#define IOP_OPTION_DO_CLOCK_MGMNT (1<<1) /* do clock management */ + + /* console message buffer */ + uint32_t message_buffer; + + /* (optional) task deep idle timeout */ + uint32_t deep_idle_us; + + /* control channels */ +#define IOP_MAX_CHANNELS 10 + struct iop_channel_config channel[IOP_MAX_CHANNELS]; + +#define IOP_CONTROL_CHANNEL 0 +#define IOP_CONTROL_CHANNEL_SIZE 2 + +#define IOP_MESSAGE_CHANNEL 1 +/* note the message channel size is defined on a per-firmware-image basis */ + +#define SDIO_CONTROL_CHANNEL 3 +#define SDIO_CONTROL_CHANNEL_SIZE 2 + +#define FMI_CONTROL_CHANNEL0 5 +#define FMI_CONTROL_CHANNEL1 6 +#define FMI_CONTROL_CHANNEL_SIZE 3 + +#define AUDIO_CONTROL_CHANNEL 7 +#define AUDIO_CONTROL_CHANNEL_SIZE 2 + +#define AUDIODSP_TIMER_CHANNEL 2 +#define AUDIODSP_TIMER_CHANNEL_SIZE 2 + +#define AUDIODSP_CONTROL_CHANNEL 4 +#define AUDIODSP_CONTROL_CHANNEL_SIZE 2 + +#define AE2_WFI_ENDPOINT_CHANNEL 8 +#define AE2_WFI_ENDPOINT_CHANNEL_SIZE 2 + +}; + +/* + * Default channel definitions; these channels are prototyped by + * the endpoint driver before starting the IOP, so they are + * safe for the IOP firmware to touch at startup. + */ +static struct { + uint32_t channel_index; + uint32_t channel_size; + uint32_t producer; +} iop_default_channels[] __attribute__ ((unused)) = { + { SDIO_CONTROL_CHANNEL, SDIO_CONTROL_CHANNEL_SIZE, true }, + { FMI_CONTROL_CHANNEL0, FMI_CONTROL_CHANNEL_SIZE, true }, + { FMI_CONTROL_CHANNEL1, FMI_CONTROL_CHANNEL_SIZE, true }, + { AUDIO_CONTROL_CHANNEL, AUDIO_CONTROL_CHANNEL_SIZE, true }, + { AUDIODSP_CONTROL_CHANNEL, AUDIODSP_CONTROL_CHANNEL_SIZE, true }, + { AUDIODSP_TIMER_CHANNEL, AUDIODSP_TIMER_CHANNEL_SIZE, false }, + { AE2_WFI_ENDPOINT_CHANNEL, AE2_WFI_ENDPOINT_CHANNEL_SIZE, true }, + { 0, 0, 0 } +}; + +/* + * Host control pipe commands. + */ +#define IOP_CMD_NOP 'nop ' +#define IOP_CMD_TERMINATE 'halt' +#define IOP_CMD_TTYIN 'ttin' +#define IOP_CMD_SLEEP 'slep' +#define IOP_CMD_SUSPEND 'spnd' +#define IOP_CMD_RESUME 'rsum' +#define IOP_CMD_INSTRUMENT 'inst' + +#define IOP_RESULT_SUCCESS 0 +#define IOP_RESULT_ERROR 1 +#define IOP_RESULT_IN_PROGRESS ~0 + +struct iop_command_generic { + uint32_t opcode; + uint32_t result; +}; + +/* + * Send a character to the debug input routine. + */ +struct iop_command_ttyin { + struct iop_command_generic gen; + + uint32_t c; +}; + +/* Instrumentation */ +struct iop_command_instrument { + struct iop_command_generic gen; + + UInt64 uptime_ticks; + UInt64 deep_idle_ticks; + UInt64 deep_idles; + UInt64 idle_ticks; + UInt64 idles; + UInt32 threshold_us; + UInt32 ticksHz; +}; + +/* Ping command */ +struct iop_command_ping { + uint32_t opcode; + uint32_t result; + uint32_t ping_id; +}; + +/* + * Command union must be a multiple of the IOP cacheline size + * because the IOP will invalidate it out of the cache before + * processing it. + */ +#define IOP_ROUNDUP(k,b) (((k) + ((b) - 1)) & ~((b) - 1)) +#if defined(CPU_CACHELINE_SIZE) && (CPU_CACHELINE_SIZE > 32) +#define IOP_COMMAND_MAX IOP_ROUNDUP(sizeof(struct iop_command_instrument), CPU_CACHELINE_SIZE) +#else +#define IOP_COMMAND_MAX IOP_ROUNDUP(sizeof(struct iop_command_instrument), 32) +#endif + +union iop_command { + struct iop_command_generic generic; + struct iop_command_ttyin ttyin; + struct iop_command_instrument instr; + struct iop_command_ping ping; + + uint8_t _pad[IOP_COMMAND_MAX]; +}; + +/* + * IOP to host notifications. + */ +struct iop_message_generic { + uint32_t opcode; + uint32_t size; +}; + +#define IOP_MSG_TTY 'tty ' /* console tty output */ +#define IOP_MSG_PANIC 'pnic' /* firmware panic message */ +#define IOP_MSG_TRACE 'trce' /* trace message */ + +#define IOP_MESSAGE_MAX 128 +#define IOP_MSG_TTY_MAXLEN (IOP_MESSAGE_MAX - sizeof(struct iop_message_generic)) + +/* + * Console output message. + */ +struct iop_message_tty { + struct iop_message_generic gen; + + char bytes[]; +}; + +/* + * Trace message. + */ +struct iop_message_trace { + struct iop_message_generic gen; + + uint32_t ident; + uint32_t arg[4]; + uint64_t timestamp; +}; + +union iop_message { + struct iop_message_generic gen; + struct iop_message_tty tty; + struct iop_message_trace trace; + + uint8_t _pad[IOP_MESSAGE_MAX]; +}; + +struct iop_ping_tracker { + struct iop_command_ping record; + uint64_t timestamp; +}; diff --git a/apps/EmbeddedIOP/application.mk b/apps/EmbeddedIOP/application.mk new file mode 100644 index 0000000..d6d4e92 --- /dev/null +++ b/apps/EmbeddedIOP/application.mk @@ -0,0 +1,85 @@ +# Copyright (C) 2007-2009, 2012, 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +# +# Global headers that are independing of product, target, etc. +# +GLOBAL_HEADERS += \ + lib/mib/mib_nodes.h + + +ALL_OBJS += $(LOCAL_DIR)/debugcmds.o \ + $(LOCAL_DIR)/main.o \ + $(LOCAL_DIR)/clock_management.o \ + $(LOCAL_DIR)/clock_stepping.o \ + $(LOCAL_DIR)/qwi.o + +OPTIONS += WITH_INTERRUPTS=1 \ + QWI_MAX_CHANNELS=8 \ + WITH_APPLICATION_PUTCHAR=1 + +WITH_NO_SECURITY := true + +# basic heap allocation +export IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),28672) + +ifeq ($(BUILD),DEBUG) +############################################################################## +# Debug build +# + +# enable DCC console +WITH_DCC := true +OPTIONS += DEBUG_LEVEL=20 \ + DCC_TX_BUFFER_SIZE=4096 \ + APPLICATION_CONSOLE_BUFFER=4096 \ + WITH_MENU=1 + +#OPTIONS += ARM_DCC_SYNCHRONOUS=1 + +# console 8K +# menu 5.5K +# commands ... +export IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),32768) + +else +############################################################################## +# Release build +# + +endif + +############################################################################## +# Build configuration + +MODULES += lib/heap \ + sys + +LIBRARY_MODULES += lib/libc \ + lib/mib + +GLOBAL_INCLUDES += $(LOCAL_DIR) + +# defeat the default heap initialisation +OPTIONS += HEAP_SIZE=0 + +# configure the message channel +export IOP_MESSAGE_CHANNEL_SIZE = 8 + +# and the panic log buffer +export IOP_PANIC_LOG_SIZE = 32768 +OPTIONS += IOP_PANIC_LOG_SIZE=$(IOP_PANIC_LOG_SIZE) \ + WITH_PANIC_HOOKS=1 + +# basic protocol header +INSTALL_HEADERS := $(LOCAL_DIR)/EmbeddedIOPProtocol.h \ + $(LOCAL_DIR)/qwi_protocol.h diff --git a/apps/EmbeddedIOP/clock_management.c b/apps/EmbeddedIOP/clock_management.c new file mode 100644 index 0000000..64c4d23 --- /dev/null +++ b/apps/EmbeddedIOP/clock_management.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "clock_management.h" +#include + +static bool sParticipateInClockManagement = false; + +void SetParticipateInClockStateManagement(bool enable) +{ + sParticipateInClockManagement = enable; +} + +bool ParticipateInClockStateManagement() +{ + return sParticipateInClockManagement; +} + diff --git a/apps/EmbeddedIOP/clock_management.h b/apps/EmbeddedIOP/clock_management.h new file mode 100644 index 0000000..4738cac --- /dev/null +++ b/apps/EmbeddedIOP/clock_management.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __CLOCK_MANAGEMENT_H__ +#define __CLOCK_MANAGEMENT_H__ + +#include + +void SetParticipateInClockStateManagement(bool enable); +bool ParticipateInClockStateManagement(); + +#endif // __CLOCK_MANAGEMENT_H__ + diff --git a/apps/EmbeddedIOP/clock_stepping.c b/apps/EmbeddedIOP/clock_stepping.c new file mode 100644 index 0000000..2f18ade --- /dev/null +++ b/apps/EmbeddedIOP/clock_stepping.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "clock_stepping.h" +#include "clock_management.h" + +// clock management only supported on AE2 platforms (H4P, H4G, and H5P) +// On other systems, this will be a no-op +#if !(TARGET_S5L8940XAE2 || TARGET_S5L8945XAE2 || TARGET_S5L8950XAE2) + +void SetClockState(clockrequest_reason_t reason, clockvalue_t value) +{ +} + +#else + +#include +#include + +#include +#include + +// helpful macros +#define AE2_CLK_CFG_PENDING (1 << 16) +#define AE2_PCLK_CFG_DIVIDER(_d) (((_d) & 0xFF) << 8) +#define AE2_PCLK_CFG_DIV_MASK AE2_PCLK_CFG_DIVIDER(0xFF) +#define AE2_ACLK_CFG_DIVIDER(_d) (((_d) & 0xFF) << 0) +#define AE2_ACLK_CFG_DIV_MASK AE2_ACLK_CFG_DIVIDER(0xFF) + +// because PMGR.h on sl58950x does not use the rXXX syntax, define it here +#if TARGET_S5L8950XAE2 +#define rPMGR_CLK_CFG_DIV_MASK PMGR_CLK_CFG_DIV_MASK +#define rPMGR_CLK_CFG_DIVIDER PMGR_CLK_CFG_DIVIDER +#define rPMGR_CLK_CFG_PENDING PMGR_CLK_CFG_PENDING +#endif + +#if TARGET_S5L8940XAE2 || TARGET_S5L8945XAE2 +static const size_t ClockStatesStepLowToHigh[][2] = { + { 16, 1 }, + { 4, 1 }, + { 4, 2 }, + { 2, 2 }, +}; +#else +static const size_t ClockStatesStepLowToHigh[][2] = { + { 8, 1 }, + { 2, 1 }, + { 2, 2 }, + { 1, 2 }, +}; +#endif + +typedef enum +{ + kInternalClockStateLow = 0, + kInternalClockStateHigh = 3, +} internal_clockstate_t; + +uint32_t GetAudioClockDivider() +{ + return rPMGR_AUDIO_CLK_CFG & rPMGR_CLK_CFG_DIV_MASK; +} + +void SetAudioClockDivider(uint32_t value) +{ + rPMGR_AUDIO_CLK_CFG = (rPMGR_AUDIO_CLK_CFG & ~rPMGR_CLK_CFG_DIV_MASK) | rPMGR_CLK_CFG_DIVIDER(value); + while (rPMGR_AUDIO_CLK_CFG & rPMGR_CLK_CFG_PENDING) + ; +} + +uint32_t GetACLKDivider() +{ + return (rAE2_ACSCSR & AE2_ACLK_CFG_DIV_MASK) + 1; +} + +void SetACLKDivider(uint32_t value) +{ + rAE2_ACSCSR = (rAE2_ACSCSR & ~AE2_ACLK_CFG_DIV_MASK) | AE2_ACLK_CFG_DIVIDER(value - 1); + while (rAE2_ACSCSR & AE2_CLK_CFG_PENDING) + ; +} + +bool ConfirmClocksValid() +{ + uint32_t AudioDivider = GetAudioClockDivider(); + uint32_t ACLKDivider = GetACLKDivider(); + dprintf(DEBUG_SPEW, "*** clocks at %d %d \n", AudioDivider, ACLKDivider); + return ((AudioDivider == ClockStatesStepLowToHigh[kInternalClockStateHigh][0]) && + (ACLKDivider == ClockStatesStepLowToHigh[kInternalClockStateHigh][1])) + || + ((AudioDivider == ClockStatesStepLowToHigh[kInternalClockStateLow][0]) && + (ACLKDivider == ClockStatesStepLowToHigh[kInternalClockStateLow][1])); +} + +void SetClocksLow() +{ + if (GetAudioClockDivider() == ClockStatesStepLowToHigh[kInternalClockStateLow][0]) + return; + uint32_t whichState = kInternalClockStateHigh; + while (whichState != kInternalClockStateLow) + { + // increment first, then apply the settings + --whichState; + SetAudioClockDivider(ClockStatesStepLowToHigh[whichState][0]); + SetACLKDivider(ClockStatesStepLowToHigh[whichState][1]); + } +} + +void SetClocksHigh() +{ + if (GetAudioClockDivider() == ClockStatesStepLowToHigh[kInternalClockStateHigh][0]) + return; + uint32_t whichState = kInternalClockStateLow; + while (whichState != kInternalClockStateHigh) + { + // increment first, then apply the settings + ++whichState; + SetAudioClockDivider(ClockStatesStepLowToHigh[whichState][0]); + SetACLKDivider(ClockStatesStepLowToHigh[whichState][1]); + } +} + + +void SetClockState(clockrequest_reason_t reason, clockvalue_t value) +{ + static clockvalue_t currentRequestValue[kClockRequestMax]; + clockvalue_t newValue = kClockValueHigh; + + if (!ParticipateInClockStateManagement()) + { + return ; + } + + bool result = true; + dprintf(DEBUG_SPEW, "*** requesting clock to %d (for %d)***\n", value, reason); + // turn interrupts off + enter_critical_section(); + + // make sure our arguments are valid + require((result = value < kClockValueMax), Exit); + require((result = reason < kClockRequestMax), Exit); + // assert clocks in a valid state + require((result = ConfirmClocksValid()), Exit); + + // We modify the actual value of the clock state depending on the value of the current requests + currentRequestValue[reason] = value; + + // If all requests are for kClockValueLow, we switch to the slowest rate + uint32_t n; + for(n=0; n +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +/* "md", "mdh", "mdb" */ +int do_memdump(int argc, struct cmd_arg *args) +{ + addr_t address; + size_t count; + int width; + size_t i; + + /* default dump values */ + static addr_t last_address = 0; + static size_t last_count = 0x100; + + address = last_address; + count = last_count; + + if (!strcmp(args[0].str, "md")) { + width = 32; + } else if (!strcmp(args[0].str, "mdh")) { + width = 16; + } else { + width = 8; + } + + if (argc >= 2) + address = args[1].u; + if (argc >= 3) + count = args[2].u; + +// printf("dumping memory at 0x%x, len 0x%x, width %d\n", address, count, width); + + i = 0; + while (i < count) { + if ((i % 16) == 0) { + if (i != 0) + puts("\n"); + printf("%p: ", (void *)(address + i)); + } + + switch (width) { + case 32: + printf("%08x ", *(uint32_t *)(address + i)); + if ( 4 == (i & 0xf)) + printf(" "); + i += 4; + break; + case 16: + printf("%04x ", *(uint16_t *)(address + i)); + if ( 6 == (i & 0xf)) + printf(" "); + i += 2; + break; + case 8: + printf("%02x ", *(uint8_t *)(address + i)); + if ( 7 == (i & 0xf)) + printf(" "); + i += 1; + break; + } + } + puts("\n"); + + /* save the values so we can continue next time */ + last_count = count; + last_address = address + count; + + return 0; +} + +MENU_COMMAND_DEBUG(md, do_memdump, "memory display - 32bit", NULL); +MENU_COMMAND_DEBUG(mdh, do_memdump, "memory display - 16bit", NULL); +MENU_COMMAND_DEBUG(mdb, do_memdump, "memory display - 8bit", NULL); + +/* "mw", "mwh", "mwb", "mws" */ +int do_memwrite(int argc, struct cmd_arg *args) +{ + static addr_t last_address = ~0UL; + addr_t address; + size_t length; + uint32_t data; + const char *buffer; + int width; + + switch (argc) { + case 2: + if (~0UL == last_address) { + printf("%s - need an address\n", args[0].str); + return -1; + } + address = last_address; + data = args[1].u; + buffer = args[1].str; + break; + case 3: + address = args[1].u; + last_address = address; + data = args[2].u; + buffer = args[2].str; + break; + default: + printf("%s [
] \n", args[0].str); + return -1; + } + + if (!strcmp(args[0].str, "mw")) { + width = 32; + length = 4; + } else if (!strcmp(args[0].str, "mwh")) { + width = 16; + length = 2; + } else if (!strcmp(args[0].str, "mwb")) { + width = 8; + length = 1; + } else { + width = 255; + length = strlen(buffer) + 1; + } + +// printf("writing memory at 0x%x, data 0x%x\n", address, data); + + switch (width) { + case 32: + *(uint32_t *)address = data; + break; + case 16: + *(uint16_t *)address = data; + break; + case 8: + *(uint8_t *)address = data; + break; + + case 255: + strlcpy((char *)address, buffer, length); + break; + } + + return 0; +} + +MENU_COMMAND_DEBUG(mw, do_memwrite, "memory write - 32bit", NULL); +MENU_COMMAND_DEBUG(mwh, do_memwrite, "memory write - 16bit", NULL); +MENU_COMMAND_DEBUG(mwb, do_memwrite, "memory write - 8bit", NULL); +MENU_COMMAND_DEBUG(mws, do_memwrite, "memory write - string", NULL); + +int do_panic(int argc, struct cmd_arg *args) +{ + panic("command prompt"); +} +MENU_COMMAND_DEBUG(panic, do_panic, "...", NULL); + +int do_hang(int argc, struct cmd_arg *args) +{ + for (;;) + ; + + return(0); +} +MENU_COMMAND_DEBUG(hang, do_hang, "spin forever, hanging the system", NULL); + + +#endif diff --git a/apps/EmbeddedIOP/function_audio/iop_audio.c b/apps/EmbeddedIOP/function_audio/iop_audio.c new file mode 100644 index 0000000..ea65ffa --- /dev/null +++ b/apps/EmbeddedIOP/function_audio/iop_audio.c @@ -0,0 +1,557 @@ +/* + * Copyright (C) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include "iop_audio_protocol.h" +#include "AudioCodecA5.h" +#include "clock_stepping.h" + +#ifdef DO_PROFILING + +// doing peak heap check requires heap.c to support it +//#define DO_PEAKHEAPCHECK +// doing peak heap check requires task.c to support it +//#define DO_PEAKSTACKCHECK + +#include +#include + +#define kPerformanceSize 16 +struct PerformanceDetails +{ + bool valid; + utime_t time; + uint32_t cycles; +}; + +struct PerformanceDetails performanceDetails[kPerformanceSize]; + +void PerformanceSnapShotReset() +{ + memset(performanceDetails, 0, sizeof(performanceDetails)); +} + +void PerformanceSnapShotStart(uint32_t which) +{ + if (which >= kPerformanceSize) + return; + performanceDetails[which].time = system_time(); + performanceDetails[which].cycles = arm_read_pmreg(ARM_PMCCNTR); +} + +void PerformanceSnapShotEnd(uint32_t which) +{ + if (which >= kPerformanceSize) + return; + performanceDetails[which].valid = true; + performanceDetails[which].time = system_time() - performanceDetails[which].time; + performanceDetails[which].cycles = arm_read_pmreg(ARM_PMCCNTR) - performanceDetails[which].cycles; +} + +void SetupProfiling(IOPAUDIO_METRICS* metrics) +{ + // mapping from enum to event monitors from the A5 TRM + static const uint32_t eventtable[ACLKCycles-ICacheAccesses] = { 0x14, 0x1, 0x4, 0x3, 0x6, 0x7, 0xF, 0x8, 0x12, 0x10 }; + + // reset our user defined performance counters. + PerformanceSnapShotReset(); + + // select wich events we are going to monitor + uint32_t evt0 = 0x03; // by default we measure dcache fills + uint32_t evt1 = 0x04; // by default we measure dcache accesses + uint32_t i = ICacheAccesses; + // choose the event monitor to follow. We only choose the first two we find + for (;i < ACLKCycles; ++i) + { + if (metrics->mMetricsItemsValid & (1 << i)) + { + evt0 = eventtable[(i - ICacheAccesses)]; + break; + } + } + ++i; + for (;i < ACLKCycles; ++i) + { + if (metrics->mMetricsItemsValid & (1 << i)) + { + evt1 = eventtable[(i - ICacheAccesses)]; + break; + } + } +#ifdef DO_PEAKSTACKCHECK + if (metrics->mMetricsItemsValid & (1<mMetricsItemsValid & (1<mMetricsFields[ProcessTimeUSec] = system_time(); + metrics->mMetricsFields[ProcessCycles] = arm_read_pmreg(ARM_PMCCNTR); +} + +void EndProfiling(IOPAUDIO_METRICS* metrics) +{ + uint32_t evt0, evt1, cycles; + arm_write_pmreg(ARM_PMCNTENCLR, ~0); /* disable all counters */ + utime_t timeEnd = system_time(); + arm_write_pmreg(ARM_PMSELR, 0); + evt0 = arm_read_pmreg(ARM_PMXEVCNTR); /* read event 0 */ + arm_write_pmreg(ARM_PMSELR, 1); + evt1 = arm_read_pmreg(ARM_PMXEVCNTR); /* read event 1 */ + cycles = arm_read_pmreg(ARM_PMCCNTR); /* read cycles */ + + if (arm_read_pmreg(ARM_PMOVSR)) + dprintf(DEBUG_CRITICAL, "*** counter overflow ***\n"); + + uint32_t i = ICacheAccesses; + // choose the event monitor to follow. We only choose the first two we find + for (;i < ACLKCycles; ++i) + { + if (metrics->mMetricsItemsValid & (1 << i)) + { + metrics->mMetricsFields[i] = evt0; + break; + } + } + ++i; + for (;i < ACLKCycles; ++i) + { + if (metrics->mMetricsItemsValid & (1 << i)) + { + metrics->mMetricsFields[i] = evt1; + break; + } + } + + if (metrics->mMetricsItemsValid & (1<mMetricsFields[ProcessTimeUSec] = timeEnd - metrics->mMetricsFields[ProcessTimeUSec]; + if (metrics->mMetricsItemsValid & (1<mMetricsFields[ProcessCycles] = cycles - metrics->mMetricsFields[ProcessCycles]; + if (metrics->mMetricsItemsValid & (1<mMetricsFields[HeapInUsage] = heap_get_free_mem(); +#ifdef DO_PEAKHEAPCHECK + if (metrics->mMetricsItemsValid & (1<mMetricsFields[PeakHeapUsage] = heap_get_peak_mem(); +#endif // DO_PEAKHEAPCHECK +#ifdef DO_PEAKSTACKCHECK + if (metrics->mMetricsItemsValid & (1<mMetricsFields[PeakStackUsage] = get_stack_usage("audio"); +#endif // DO_PEAKSTACKCHECK + + for (uint32_t i = 0; i < kPerformanceSize; ++i) + { + if ((ReservedStart+i) >= MetricsFieldsSize) + break; + if (performanceDetails[i].valid) + { + metrics->mMetricsFields[ReservedStart+i] = performanceDetails[i].time; + metrics->mMetricsItemsValid |= 1<<(ReservedStart+i); + } + } +} + +#else + +void PerformanceSnapShotStart(uint32_t which) {} +void PerformanceSnapShotEnd(uint32_t which) {} +void SetupProfiling(IOPAUDIO_METRICS* metrics) {} +void EndProfiling(IOPAUDIO_METRICS* metrics) { metrics->mMetricsItemsValid = 0; } + +#endif + +static bool audio_message_process(void); + +static int iop_audio_task(void *cfg); +static void iop_audio_sleep(int mode); + +IOP_FUNCTION(audio, iop_audio_task, 64*1024, AUDIO_CONTROL_CHANNEL); +IOP_SLEEP_HOOK(audio, iop_audio_sleep); + +static int audio_channel; + +#define kMaxCodecs 8 +static AudioCodec sTokens[kMaxCodecs] = { NULL, }; + +// return true if registered, false if could not. +static bool +Register(AudioCodec audioCodec) +{ + for (size_t i = 0; i < kMaxCodecs; ++i) + if (!sTokens[i]) + { + sTokens[i] = audioCodec; + return true; + } + return false; +} + +static void +Unregister(AudioCodec audioCodec) +{ + for (size_t i = 0; i < kMaxCodecs; ++i) + if (sTokens[i] == audioCodec) + sTokens[i] = NULL; +} + +static bool +isAudioCodecValid(AudioCodec audioCodec) +{ + for (size_t i = 0; i < kMaxCodecs; ++i) + if (sTokens[i] == audioCodec) + return true; + return false; +} + +static int +iop_audio_task(void *cfg) +{ + struct iop_channel_config *channel = (struct iop_channel_config *)cfg; + struct task_event* audio_message_event = (struct task_event*) malloc(sizeof(struct task_event)); + + dprintf(DEBUG_SPEW, "@@ Audio task starting\n"); + + check(kIOPAUDIO_COMMAND_SIZE == sizeof(IOPAUDIO_Command)); + + /* establish the host communications channel */ + event_init(audio_message_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dprintf(DEBUG_SPEW, "** opening audio channel\n"); + audio_channel = qwi_instantiate_channel("audio command", + QWI_ROLE_CONSUMER, + channel->ring_size, + (void *)mem_static_map_cached(channel->ring_base), + (qwi_channel_hook)event_signal, + audio_message_event); + +#if WITH_VFP && !WITH_VFP_ALWAYS_ON + /* Little doubt we'll need VFP/Neon */ + arch_task_fp_enable(true); +#endif + + for (;;) { + dprintf(DEBUG_SPEW, "@@ waiting for message on audio channel\n"); + while (audio_message_process()) { + // eat all available messages + } + event_wait(audio_message_event); + } + + return(0); +} + +static bool +audio_message_process(void) +{ + uint32_t message; + IOPAUDIO_Command* command; + + dprintf(DEBUG_SPEW, "@@ handling host message\n"); + + /* look to see if there's an item waiting for us */ + if (qwi_receive_item(audio_channel, &message) == -1) + return(false); + + // set the clocks high + SetClockState(kClockRequestMessageProcess, kClockValueHigh); + + dprintf(DEBUG_SPEW, "@@ received audio message\n"); + + /* find the command structure based on the message */ + command = (IOPAUDIO_Command*)mem_static_map_cached(message); + + /* + * Flush any cached item contents we might have lying around - we are guaranteed + * that the command size is a multiple of our cacheline size. + */ + platform_cache_operation(CACHE_INVALIDATE, + (void *)command, + sizeof(*command)); + + /* + * TODO: make this part of the API and push this + * architecture-specific command handling down into the s5l8920x + * platform directory. + */ + switch (command->iopaudio.mOpcode) { + + case kIOPAUDIO_OPCODE_CREATE: + { + AudioComponent comp = NULL; + AudioComponentDescription desc; + desc.componentType = command->create.mComponentDesc.mComponentType; + desc.componentSubType = command->create.mComponentDesc.mComponentSubType; + desc.componentManufacturer = command->create.mComponentDesc.mComponentManufacturer; + desc.componentFlags = command->create.mComponentDesc.mComponentFlags; + desc.componentFlagsMask = command->create.mComponentDesc.mComponentFlagsMask; + comp = AudioComponentFindNext(comp, &desc); + if(comp == NULL) + { + dprintf(DEBUG_CRITICAL, "Could not find AudioComponent\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_CODECERROR; + break; + } + dprintf(DEBUG_CRITICAL, "found component\n"); + AudioCodec audioCodec = NULL; + size_t err = AudioComponentInstanceNew(comp, &audioCodec); + command->iopaudio.Codec.mCodecStatus = err; + if (err != 0 || audioCodec == NULL) + { + dprintf(DEBUG_CRITICAL, "Could not create audioCodec\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_CODECERROR; + break; + } + + const void *magicCookie = (command->create.mAdditionalParametersSizeBytes) ? command->create.mAdditionalParameters : 0; + + err = AudioCodecInitialize(audioCodec, &(command->create.mInputFormat), &(command->create.mOutputFormat), magicCookie, command->create.mAdditionalParametersSizeBytes); + command->iopaudio.Codec.mCodecStatus = err; + if (err != 0) + { + dprintf(DEBUG_CRITICAL, "Could not initialize audioCodec\n"); + AudioComponentInstanceDispose(audioCodec); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_CODECERROR; + break; + } + if (!Register(audioCodec)) + { + dprintf(DEBUG_CRITICAL, "Could not register audioCodec\n"); + AudioComponentInstanceDispose(audioCodec); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_CODECERROR; + break; + } + command->iopaudio.mStatus = kIOPAUDIO_STATUS_SUCCESS; + command->iopaudio.Codec.mIOPToken = (uint32_t)audioCodec; + dprintf(DEBUG_CRITICAL, "Created codec with id %x\n", command->iopaudio.Codec.mIOPToken); + } + break; + case kIOPAUDIO_OPCODE_DESTROY: + { + AudioCodec audioCodec = (AudioCodec)command->iopaudio.Codec.mIOPToken; + if (!isAudioCodecValid(audioCodec)) + { + dprintf(DEBUG_CRITICAL, "Codec not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + AudioComponentInstanceDispose(audioCodec); + Unregister(audioCodec); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_SUCCESS; + } + break; + case kIOPAUDIO_OPCODE_RESET: + { + AudioCodec audioCodec = (AudioCodec)command->iopaudio.Codec.mIOPToken; + if (!isAudioCodecValid(audioCodec)) + { + dprintf(DEBUG_CRITICAL, "Codec not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + size_t err = AudioCodecReset(audioCodec); + command->iopaudio.Codec.mCodecStatus = err; + command->iopaudio.mStatus = kIOPAUDIO_STATUS_SUCCESS; + } + break; + case kIOPAUDIO_OPCODE_GETPROPINFO: + { + AudioCodec audioCodec = (AudioCodec)command->iopaudio.Codec.mIOPToken; + if (isAudioCodecValid(audioCodec)) + { + dprintf(DEBUG_CRITICAL, "Codec not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + size_t err = AudioCodecGetPropertyInfo(audioCodec, command->get_propinfo.mPropertyID, (size_t*)&command->get_propinfo.mPropertySize, (bool*)&command->get_propinfo.mPropertyWritable); + command->iopaudio.Codec.mCodecStatus = err; + command->iopaudio.mStatus = kIOPAUDIO_STATUS_SUCCESS; + } + break; + case kIOPAUDIO_OPCODE_GETPROPERTY: + { + AudioCodec audioCodec = (AudioCodec)command->iopaudio.Codec.mIOPToken; + if (isAudioCodecValid(audioCodec)) + { + dprintf(DEBUG_CRITICAL, "Codec not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + // update getProperty and setProperty to limit property address + size_t max_size_for_property = sizeof(*command) - ((uint32_t)&command->get_property.mPropertyData - (uint32_t)command); + if (max_size_for_property < command->get_property.mPropertySizeBytes) + { + dprintf(DEBUG_CRITICAL, "Parameters not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + + // the message should be cleaned before and after we use it, so do not need to clean ourselves + void* property = (void*)command->get_property.mPropertyData; + + size_t err = AudioCodecGetProperty(audioCodec, command->get_property.mPropertyID, (size_t*)&command->get_property.mPropertySizeBytes, property); + command->iopaudio.Codec.mCodecStatus = err; + command->iopaudio.mStatus = kIOPAUDIO_STATUS_SUCCESS; + } + break; + case kIOPAUDIO_OPCODE_SETPROPERTY: + { + AudioCodec audioCodec = (AudioCodec)command->iopaudio.Codec.mIOPToken; + if (isAudioCodecValid(audioCodec)) + { + dprintf(DEBUG_CRITICAL, "Codec not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + // update getProperty and setProperty to limit property address + size_t max_size_for_property = sizeof(*command) - ((uint32_t)&command->get_property.mPropertyData - (uint32_t)command); + if (max_size_for_property < command->get_property.mPropertySizeBytes) + { + dprintf(DEBUG_CRITICAL, "Parameters not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + + // the message should be cleaned before and after we use it, so do not need to clean ourselves + void* property = (void*)command->get_property.mPropertyData; + + size_t err = AudioCodecSetProperty(audioCodec, command->set_property.mPropertyID, command->set_property.mPropertySizeBytes, property); + command->iopaudio.Codec.mCodecStatus = err; + command->iopaudio.mStatus = kIOPAUDIO_STATUS_SUCCESS; + } + break; + case kIOPAUDIO_OPCODE_PROCESSFRAME: + { + AudioCodec audioCodec = (AudioCodec)command->iopaudio.Codec.mIOPToken; + if (!isAudioCodecValid(audioCodec)) + { + dprintf(DEBUG_CRITICAL, "Codec not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + // function_audio should make sure parameters to processSingleFrame (input, output buffers) are valid + // make sure the parameters are not-null. + if (!command->process_frame.mSrcAddr + || !command->process_frame.mSrcSizeBytes + || !command->process_frame.mDstAddr + || !command->process_frame.mDstSizeBytes) + { + dprintf(DEBUG_CRITICAL, "Parameters not valid\n"); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + const void* src = (const void*)mem_static_map_cached(command->process_frame.mSrcAddr); + void* dst = (void*)mem_static_map_cached(command->process_frame.mDstAddr); + + + // the onus is on the caller to make sure the cache is aligned + void* lineBase = (void*)((uint32_t)src & ~(CPU_CACHELINE_SIZE-1)); + size_t sizeToClean = ((((uint32_t)src & (CPU_CACHELINE_SIZE-1)) + command->process_frame.mSrcSizeBytes)/CPU_CACHELINE_SIZE + 1) * CPU_CACHELINE_SIZE; + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, lineBase, sizeToClean); + + SetupProfiling(&command->process_frame.mMetrics); + + void* packet_dst = dst; + uint16_t numPackets = command->process_frame.mNumPackets; + size_t remaining_dst_size = command->process_frame.mDstSizeBytes; + size_t total_dst_size = 0; + size_t total_src_size = 0; + + //sanity check, if the multi frame fields are not used + if(0 == numPackets) + { + numPackets = 1; + command->process_frame.mPacketSize[0] = command->process_frame.mSrcSizeBytes; + } + + for(uint16_t i = 0; i < numPackets; ++i) + { + size_t src_size = command->process_frame.mPacketSize[i]; + //make sure we dont go pass all of the valid input data + if(total_src_size + src_size > command->process_frame.mSrcSizeBytes) + break; + size_t packet_dst_size = remaining_dst_size; //the current mp3 decoder doesn't take dst size that's bigger than the packet output size + dprintf(DEBUG_SPEW, "IOP_Audio start %d of %d, input %p size %zu, output %p, size %zu\n", i+1, numPackets, src, src_size, packet_dst, packet_dst_size); + size_t err = AudioCodecProcessSinglePacket(audioCodec, src, &src_size, packet_dst, &packet_dst_size); + command->iopaudio.Codec.mCodecStatus = err; + if(err) + break; + packet_dst += packet_dst_size; + remaining_dst_size -= packet_dst_size; + total_dst_size += packet_dst_size; + src += src_size; + total_src_size += src_size; + + //for encoding, write the size back to the msg + command->process_frame.mPacketSize[i] = packet_dst_size; + } + command->process_frame.mSrcSizeBytes = total_src_size; + command->process_frame.mDstSizeBytes = total_dst_size; + + + //dprintf(DEBUG_CRITICAL, "Decoded/Encoded Total SrcSize %d, dstSize %d\n", command->process_frame.mSrcSizeBytes, command->process_frame.mDstSizeBytes); + EndProfiling(&command->process_frame.mMetrics); + + // the onus is on the caller to make sure the cache is aligned + lineBase = (void*)((uint32_t)dst & ~(CPU_CACHELINE_SIZE-1)); + sizeToClean = ((((uint32_t)dst & (CPU_CACHELINE_SIZE-1)) + command->process_frame.mDstSizeBytes)/CPU_CACHELINE_SIZE + 1) * CPU_CACHELINE_SIZE; + platform_cache_operation(CACHE_CLEAN, lineBase, sizeToClean); + + command->iopaudio.mStatus = kIOPAUDIO_STATUS_SUCCESS; + } + break; + default: + dprintf(DEBUG_CRITICAL, "@@ ERROR: unrecognised audio opcode 0x%x\n", + command->iopaudio.mOpcode); + command->iopaudio.mStatus = kIOPAUDIO_STATUS_PARAM_INVALID; + break; + } + + dprintf(DEBUG_SPEW, "@@ done processing audio message with status 0x%08x\n", command->iopaudio.mStatus); + + platform_cache_operation(CACHE_CLEAN, + (void *)command, + sizeof(IOPAUDIO_Command)); + + qwi_send_item(audio_channel, message); + + dprintf(DEBUG_SPEW, "@@ signaled completion of audio message to host\n"); + + // set the clocks low + SetClockState(kClockRequestMessageProcess, kClockValueLow); + + return(true); +} + +static void +iop_audio_sleep(int mode) +{ +} diff --git a/apps/EmbeddedIOP/function_audio/iop_audio_protocol.h b/apps/EmbeddedIOP/function_audio/iop_audio_protocol.h new file mode 100644 index 0000000..670569b --- /dev/null +++ b/apps/EmbeddedIOP/function_audio/iop_audio_protocol.h @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _IOP_AUDIO_PROTOCOL_H_ +#define _IOP_AUDIO_PROTOCOL_H_ + +#include + +/* + * Command size is (somewhat) tunable. + * + * The principal consideration here is the maximum scatter/gather list size + * this permits. + */ +#define kIOPAUDIO_COMMAND_SIZE (512) + + +/* + * IOPAUDIO_opcode_t: identifies the command sent and from the AE2 + */ +typedef uint32_t IOPAUDIO_opcode_t; + +#define kIOPAUDIO_OPCODE_UNKNOWN ((IOPAUDIO_opcode_t) 0) + +/* + * Commands for communicating with AudioCodecs library + */ +#define kIOPAUDIO_OPCODE_CREATE ((IOPAUDIO_opcode_t) 3) +#define kIOPAUDIO_OPCODE_DESTROY ((IOPAUDIO_opcode_t) 4) +#define kIOPAUDIO_OPCODE_RESET ((IOPAUDIO_opcode_t) 5) +#define kIOPAUDIO_OPCODE_PROCESSFRAME ((IOPAUDIO_opcode_t) 6) +#define kIOPAUDIO_OPCODE_GETPROPINFO ((IOPAUDIO_opcode_t) 7) +#define kIOPAUDIO_OPCODE_GETPROPERTY ((IOPAUDIO_opcode_t) 8) +#define kIOPAUDIO_OPCODE_SETPROPERTY ((IOPAUDIO_opcode_t) 9) + +/* + * IOPAUDIO_status_t: result from commands + */ +typedef uint32_t IOPAUDIO_status_t; + +#define kIOPAUDIO_STATUS_UNKNOWN ((IOPAUDIO_status_t) 0) +#define kIOPAUDIO_STATUS_SUCCESS ((IOPAUDIO_status_t) 1) +#define kIOPAUDIO_STATUS_FAILURE ((IOPAUDIO_status_t) 0x80000000) +#define kIOPAUDIO_STATUS_DEVICE_ERROR ((IOPAUDIO_status_t) 0x80000001) +#define kIOPAUDIO_STATUS_DEVICE_TIMEOUT ((IOPAUDIO_status_t) 0x80000002) +#define kIOPAUDIO_STATUS_DMA_TIMEOUT ((IOPAUDIO_status_t) 0x80000003) +#define kIOPAUDIO_STATUS_PARAM_INVALID ((IOPAUDIO_status_t) 0x80000004) +#define kIOPAUDIO_STATUS_UNIMPLEMENTED ((IOPAUDIO_status_t) 0x80000005) +#define kIOPAUDIO_STATUS_CODECERROR ((IOPAUDIO_status_t) 0x80000010) + + +/* + * IOPAUDIO_token_t: The opaque token to use for audio processing + */ +typedef uint32_t IOPAUDIO_token_t; +typedef uint32_t IOPAUDIO_codecstatus_t; + +/* + * IOPAUDIO_CODEC contains the pair of token and codec status + */ +struct _IOPAUDIO_CODEC +{ + IOPAUDIO_token_t mIOPToken; + IOPAUDIO_codecstatus_t mCodecStatus; +}; +typedef struct _IOPAUDIO_CODEC IOPAUDIO_CODEC; + +// Token for sending messages to the iop_audio system itself +#define kIOPAUDIO_system_token_t ((IOPAUDIO_opcode_t) 0xFFFFFFFF) + +/* + * IOPAUDIO_status_t result from commands + */ +struct _IOPAUDIO +{ + IOPAUDIO_opcode_t mOpcode; + IOPAUDIO_status_t mStatus; + IOPAUDIO_CODEC Codec; +}; +typedef struct _IOPAUDIO IOPAUDIO; + +struct _FunctionAudioAudioComponentDescription +{ + uint32_t mComponentType; + uint32_t mComponentSubType; + uint32_t mComponentManufacturer; + uint32_t mComponentFlags; + uint32_t mComponentFlagsMask; +}; +typedef struct _FunctionAudioAudioComponentDescription FunctionAudioAudioComponentDescription; + +struct _FunctionAudioAudioStreamBasicDescription +{ + uint64_t mSampleRate; + uint32_t mFormatID; + uint32_t mFormatFlags; + uint32_t mBytesPerPacket; + uint32_t mFramesPerPacket; + uint32_t mBytesPerFrame; + uint32_t mChannelsPerFrame; + uint32_t mBitsPerChannel; + uint32_t mReserved; +}; +typedef struct _FunctionAudioAudioStreamBasicDescription FunctionAudioAudioStreamBasicDescription; + +enum MetricsFields +{ + ProcessTimeUSec = 0, + ProcessCycles, + PeakStackUsage, + HeapInUsage, + PeakHeapUsage, + ICacheAccesses, // these are measured by A5 performance monitors + ICacheMisses, + DCacheAccesses, + DCacheMisses, + Loads, + Stores, + UnalignedLoadStores, + InstructionsExecuted, + CorrectPredictedBranches, + IncorrectPredictedBranches, + ACLKCycles, // these are measured by AE2 performance monitors + ACLKCyclesInWFI, + SRAMBytesRead, + SRAMBytesWrite, + SRAMBytesReadWrite, + DRAMBytesRead, + DRAMBytesWrite, + DRAMBytesReadWrite, + ReservedStart, + MetricsFieldsSize = 32 +}; + +struct _IOPAUDIO_METRICS +{ + uint32_t mMetricsItemsValid; // bitmap marking which values are valid + uint32_t mMetricsFields[MetricsFieldsSize]; +}; +typedef struct _IOPAUDIO_METRICS IOPAUDIO_METRICS; + +/* + * Messages. Message layout is dependent on the opcode. For instance, if + * the opcode is kIOPAUDIO_OPCODE_CREATE, then the message will be interpreted + * as IOPAUDIO_CREATE. + * It is the senders responsiblity to make sure a message is set correctly. + */ + +/* + * IOPAUDIO_CREATE message + * Message used to create a new audio process. + * If message succeeds, iopToken will contain the token used for processing. + * Fill the input and output with necessary parameters. Additional parameters + * passed through the additional_paramters pointer. + * + * It is decoder specific how additional data is laid out. + */ +struct _IOPAUDIO_CREATE +{ + IOPAUDIO mIOPHeader; + + FunctionAudioAudioComponentDescription mComponentDesc; + FunctionAudioAudioStreamBasicDescription mInputFormat; + FunctionAudioAudioStreamBasicDescription mOutputFormat; + uint32_t mAdditionalParametersSizeBytes; + uint8_t mAdditionalParameters[]; +}; +typedef struct _IOPAUDIO_CREATE IOPAUDIO_CREATE; + +/* + * IOPAUDIO_DESTROY message + * Message used to destroy a token. + * If message succeeds, iopToken is no longer valid. + */ +struct _IOPAUDIO_DESTROY +{ + IOPAUDIO mIOPHeader; +}; +typedef struct _IOPAUDIO_DESTROY IOPAUDIO_DESTROY; + +/* + * IOPAUDIO_RESET message + * Message used to reset an audio process + * If message succeeds, iopToken is reset to the starting state. + */ +struct _IOPAUDIO_RESET +{ + IOPAUDIO mIOPHeader; +}; +typedef struct _IOPAUDIO_RESET IOPAUDIO_RESET; + +/* + * IOPAUDIO_GETPROPINFO message + * Message used to get property information. mPropertyID is the 4-char code + * indicating what property to get info on. + * If message succeeds, size and writablility are set. + */ +struct _IOPAUDIO_GETPROPINFO +{ + IOPAUDIO mIOPHeader; + + uint32_t mPropertyID; + uint32_t mPropertySize; + uint32_t mPropertyWritable; +}; +typedef struct _IOPAUDIO_GETPROPINFO IOPAUDIO_GETPROPINFO; + +/* + * IOPAUDIO_GETPROPERTY message + * Message used to get property. mPropertyID is the 4-char code indicating what + * property to get. + * Addr passed in is the physical address where should be written. It can + * point within the message or point to some other buffer that IOP can access. + * If message succeeds, the property is written to the Addr. + */ +struct _IOPAUDIO_GETPROPERTY +{ + IOPAUDIO mIOPHeader; + + uint32_t mPropertyID; + uint32_t mPropertySizeBytes; + uint8_t mPropertyData[]; +}; +typedef struct _IOPAUDIO_GETPROPERTY IOPAUDIO_GETPROPERTY; + +/* + * IOPAUDIO_SETPROPERTY message + * Message used to set property. mPropertyID is the 4-char code indicating what + * property to set. + * Addr passed in is the physical address which has the data to write. It can + * point within the message or point to some other buffer that IOP can access. + * If message succeeds, the property is written to the Addr. + */ +struct _IOPAUDIO_SETPROPERTY +{ + IOPAUDIO mIOPHeader; + + uint32_t mPropertyID; + uint32_t mPropertySizeBytes; + uint8_t mPropertyData[]; +}; +typedef struct _IOPAUDIO_SETPROPERTY IOPAUDIO_SETPROPERTY; + +/* + * IOPAUDIO_PROCESSFRAME message + * Process audio from the src_addr to the dst_addr. On input, src_size is + * the size of the source data, dst_size is the size available to write into. + * On output, src_size is the amount of data consumed, dst_size is the amount + * of data written. + * Metrics may or may not be filled in, depending on the build. + */ +struct _IOPAUDIO_PROCESSFRAME +{ + IOPAUDIO mIOPHeader; + + uint32_t mSrcAddr; + uint32_t mDstAddr; + uint32_t mSrcSizeBytes; + uint32_t mDstSizeBytes; + IOPAUDIO_METRICS mMetrics; + //add packet information for multple packets + uint16_t mNumPackets; + uint16_t mPacketSize[]; +}; +typedef struct _IOPAUDIO_PROCESSFRAME IOPAUDIO_PROCESSFRAME; + +union _IOPAUDIO_Command +{ + IOPAUDIO iopaudio; + + IOPAUDIO_CREATE create; + IOPAUDIO_DESTROY destroy; + IOPAUDIO_RESET reset; + IOPAUDIO_PROCESSFRAME process_frame; + IOPAUDIO_GETPROPINFO get_propinfo; + IOPAUDIO_GETPROPERTY get_property; + IOPAUDIO_SETPROPERTY set_property; + + uint8_t _pad[kIOPAUDIO_COMMAND_SIZE]; +}; +typedef union _IOPAUDIO_Command IOPAUDIO_Command; + + +#endif // _IOP_AUDIO_PROTOCOL_H_ diff --git a/apps/EmbeddedIOP/function_audio/libstd_stub.cpp b/apps/EmbeddedIOP/function_audio/libstd_stub.cpp new file mode 100644 index 0000000..78d4acd --- /dev/null +++ b/apps/EmbeddedIOP/function_audio/libstd_stub.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + + +/* + * Empty namespace std stubs + */ +namespace std +{ + void __throw_bad_alloc() + {} + + void __throw_length_error(char const*) + {} +}; diff --git a/apps/EmbeddedIOP/function_audio/rules.mk b/apps/EmbeddedIOP/function_audio/rules.mk new file mode 100644 index 0000000..7721047 --- /dev/null +++ b/apps/EmbeddedIOP/function_audio/rules.mk @@ -0,0 +1,35 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +# +# Audio driver +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_FUNCTION_AUDIO=1 +IOP_FUNCTIONS += AUDIO + +ALL_OBJS += $(LOCAL_DIR)/iop_audio.o \ + $(LOCAL_DIR)/libstd_stub.o + +INSTALL_HEADERS += $(LOCAL_DIR)/iop_audio_protocol.h + +# We need 64 k for stack +# and 372064 for heap +# 192512 of which will be in SRAM +export IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),245088) + +GLOBAL_INCLUDES += $(SDKROOT)/usr/local/standalone/firmware \ + $(SDKROOT)/usr/local/standalone/firmware/include \ +# $(SDKROOT)/../../../usr/local/standalone/firmware/Accelerate.framework/Frameworks/vecLib.framework/Headers + +PREBUILT_STATICLIBS += $(SDKROOT)/usr/local/standalone/firmware/libm.a \ + $(SDKROOT)/usr/local/standalone/firmware/libvDSP.a \ + $(SDKROOT)/usr/local/standalone/firmware/libAudioCodecsA5.a diff --git a/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/ae2_dma.h b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/ae2_dma.h new file mode 100644 index 0000000..597911a --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/ae2_dma.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AE2_DMA_H__ +#define __AE2_DMA_H__ + + +typedef void * dma_object_t; + +/* + * dma_object_t is an object that can be used to control a dma + */ + +typedef enum { + kDirectionNone = 0, + kDirectionIn = 1, + kDirectionOut = 2 +} DMADirection; + +typedef struct LLI +{ + uint32_t source; + uint32_t destination; + struct LLI *next; + uint32_t control; +} DMALinkedListItem; + +typedef enum { + kI2S_0 = 0, + kI2S_1, + kI2S_2, + kI2S_3, + kMCA_0, + kMCA_1, + kAudioDevice_Last +} AudioDevice_Index; + +// create a dma object that will transfer to/from a buffer from/to a device, depending +// on the direction. +dma_object_t create_dma_object(void *buffer, AudioDevice_Index device, DMALinkedListItem *chain, DMADirection direction, size_t bytesToTransfer); +void destroy_dma_object(dma_object_t dma); + +void setupInterruptHandler(dma_object_t dma, int_handler handler, void *arg); +void setupErrorHandler(dma_object_t dma, int_handler handler, void *arg); + +typedef enum { + kFrameError = 0, + kRXOverrun, + kRXUnderrun, + kTXOverrun, + kTXUnderrun, + kError_last +} Error_Index; + +static const char* const kErrorTypeStr[kError_last] = { + "Frame_Error", + "RX_Overrun", + "RX_Underrun", + "TX_Overrun", + "TX_Underrun", +}; + +uint32_t getErrorCount(dma_object_t dma, Error_Index which); + +void startDMAObject(dma_object_t dma); +void stopDMAObject(dma_object_t dma, bool immediate); + +#endif /* __AE2_DMA_H__ */ + diff --git a/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.c b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.c new file mode 100644 index 0000000..629558d --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.c @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/** + * The PIO object pretends to be a DMA for MCA. + */ + +#include "pio_ae2.h" +#include "ae2_i2s.h" +#include "ae2_mca.h" +#include +#include +#include + + +//Per AE2 Local DMA Controller/Requests +static void* sDMAAddressRX[kAudioDevice_Last] = { (void*)rI2S0_RXDB, (void*)rI2S1_RXDB, (void*)rI2S2_RXDB, (void*)rI2S3_RXDB, (void*)rMCA0_RXDATA, (void*)rMCA1_RXDATA }; +static void* sDMAAddressTX[kAudioDevice_Last] = { (void*)rI2S0_TXDB, (void*)rI2S1_TXDB, (void*)rI2S2_TXDB, (void*)rI2S3_TXDB, (void*)rMCA0_TXDATA, (void*)rMCA1_TXDATA }; + +static internal_pio_object_t* sPIOObjects[kNumPIOs] = { NULL }; +static uint32_t sPIORunning = 0; + +uint32_t readReg(uint32_t address) +{ + return *(volatile uint32_t *)address; +} + +void writeReg(uint32_t address, uint32_t value) +{ + *(volatile uint32_t *)address = value; +} + +uint32_t readMCA0Reg(uint32_t offset) +{ + return readReg(rMCA0_BASE + offset); +} + +void writeMCA0Reg(uint32_t offset, uint32_t value) +{ + writeReg(rMCA0_BASE + offset, value); +} + +dma_object_t create_dma_object(void *buffer, AudioDevice_Index device, DMALinkedListItem *chain, DMADirection direction, size_t bytesToTransfer) +{ + dprintf(DEBUG_CRITICAL, "Creating a PIO object\n"); + // hardcoding to support only MCA right now. + if ((device >= kAudioDevice_Last) || ((direction != kDirectionIn) && (direction != kDirectionOut)) || (device != kMCA_0)) + { + dprintf(DEBUG_CRITICAL, "oops, bad arg\n"); + return NULL; + } + uint32_t whichPIO = (direction == kDirectionIn) ? kPIOReceive : kPIOTransmit; + // fail if device already exists + if (sPIOObjects[whichPIO]) + { + dprintf(DEBUG_CRITICAL, "PIO already exists\n"); + return NULL; + } + internal_pio_object_t *This = (internal_pio_object_t*)malloc(sizeof(internal_pio_object_t)); + if (This) + { + This->mWhichDevice = whichPIO; + This->mInterruptHandler = NULL; + This->mInterruptHandlerData = NULL; + for (uint32_t i = kFrameError; i < kError_last; ++i) + { + This->mErrorCount[i] = 0; + } + if (direction == kDirectionIn) + { + setupPIO(This, sDMAAddressRX[device], buffer, chain, bytesToTransfer); + } + else + { + setupPIO(This, buffer, sDMAAddressTX[device], chain, bytesToTransfer); + } + sPIOObjects[This->mWhichDevice] = This; + // we can do this here repeatedly + install_int_handler(AE2_INT_MCA0, handleAudioDeviceInterrupt, NULL); + } + return This; +} + +void destroy_dma_object(dma_object_t dma) +{ + // preliminary stop + stopDMAObject(dma, true); + internal_pio_object_t *This = (internal_pio_object_t*)dma; + if (This) + { + sPIOObjects[This->mWhichDevice] = NULL; + free(This); + } +} + +uint32_t getErrorCount(dma_object_t dma, Error_Index which) +{ + // preliminary stop + internal_pio_object_t *This = (internal_pio_object_t*)dma; + if (This) + { + return This->mErrorCount[which]; + } + return 0; +} + +void setupInterruptHandler(dma_object_t dma, int_handler handler, void *arg) +{ + internal_pio_object_t *This = (internal_pio_object_t*)dma; + if (This) + { + This->mInterruptHandler = handler; + This->mInterruptHandlerData = arg; + } +} + +void setupErrorHandler(dma_object_t dma, int_handler handler, void *arg) +{ +} + +void startDMAObject(dma_object_t dma) +{ + internal_pio_object_t *This = (internal_pio_object_t*)dma; + if (This) + { + startPIO(This); + + // we wait until two of them are ready before we unmask the int + sPIORunning |= (1 << This->mWhichDevice); + if (sPIORunning == 3) + { + unmask_int(AE2_INT_MCA0); + } + } +} + +void stopDMAObject(dma_object_t dma, bool immediate) +{ + internal_pio_object_t *This = (internal_pio_object_t*)dma; + if (This) + { + sPIORunning &= ~(1 << This->mWhichDevice); + if (sPIORunning != 3) + { + mask_int(AE2_INT_MCA0); + } + stopPIO(This); + } +} + +bool receivePIOData(DMALinkedListItem * item) +{ + // we do burst sizes of 16-bit data + int16_t data[kBurstSize]; + volatile uint32_t * src = (volatile uint32_t *)item->source; + for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) + { + data[i] = *src; + } + uint8_t * dst = (uint8_t*)item->destination; + memcpy(dst, data, sizeof(data)); + dst += sizeof(data); + item->destination = (uint32_t) dst; + item->control -= sizeof(data); + return !item->control; +} + +bool transmitPIOData(DMALinkedListItem * item) +{ + // we do burst sizes of 16-bit data + int16_t data[kBurstSize]; + uint8_t * src = (uint8_t*)item->source; + memcpy(data, src, sizeof(data)); + volatile uint32_t * dst = (volatile uint32_t *)item->destination; + for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) + { + *dst = data[i]; + } + src += sizeof(data); + item->source = (uint32_t) src; + item->control -= sizeof(data); + return !item->control; +} + +void setupNextLLI(DMALinkedListItem * item) +{ + *item = *(item->next); +} + +void handleAudioDeviceInterrupt() +{ + uint32_t status = readMCA0Reg(rMCASTATUS); + + // Panic when setting AppleSongbirdDSP sidetone EQ + // clear any sort of sticky-bit errors. + uint32_t errors = status & ( rMCASTATUS_FRAMEEEROR_MASK | rMCASTATUS_RXOVERRUN_MASK | rMCASTATUS_RXUNDERRUN_MASK | rMCASTATUS_TXOVERRUN_MASK | rMCASTATUS_TXUNDERRUN_MASK ); + writeMCA0Reg(rMCASTATUS, errors); + if (errors) + { + if (sPIOObjects[kPIOReceive]) + { + if (status & rMCASTATUS_FRAMEEEROR_MASK) ++sPIOObjects[kPIOReceive]->mErrorCount[kFrameError]; + if (status & rMCASTATUS_RXOVERRUN_MASK) ++sPIOObjects[kPIOReceive]->mErrorCount[kRXOverrun]; + if (status & rMCASTATUS_RXUNDERRUN_MASK) ++sPIOObjects[kPIOReceive]->mErrorCount[kRXUnderrun]; + if (status & rMCASTATUS_TXOVERRUN_MASK) ++sPIOObjects[kPIOReceive]->mErrorCount[kTXOverrun]; + if (status & rMCASTATUS_TXUNDERRUN_MASK) ++sPIOObjects[kPIOReceive]->mErrorCount[kTXUnderrun]; + } + } + + if (status & (1 << rMCASTATUS_RXHIGHWATER)) + { + if (sPIOObjects[kPIOReceive]) + { + if (receivePIOData(&sPIOObjects[kPIOReceive]->mCurrentDMAItem)) + { + setupNextLLI(&sPIOObjects[kPIOReceive]->mCurrentDMAItem); + if (sPIOObjects[kPIOReceive]->mInterruptHandler) + { + sPIOObjects[kPIOReceive]->mInterruptHandler(sPIOObjects[kPIOReceive]->mInterruptHandlerData); + } + } + } + } + if (status & (1 << rMCASTATUS_TXLOWWATER)) + { + if (sPIOObjects[kPIOTransmit]) + { + if (transmitPIOData(&sPIOObjects[kPIOTransmit]->mCurrentDMAItem)) + { + setupNextLLI(&sPIOObjects[kPIOTransmit]->mCurrentDMAItem); + if (sPIOObjects[kPIOTransmit]->mInterruptHandler) + { + sPIOObjects[kPIOTransmit]->mInterruptHandler(sPIOObjects[kPIOTransmit]->mInterruptHandlerData); + } + } + } + } +} + +void setupPIO(internal_pio_object_t * This, void *src, void *dst, DMALinkedListItem *chain, size_t bytesToTransfer) +{ + uint32_t transferSize = bytesToTransfer; + uint32_t control = transferSize; + + DMALinkedListItem *chainElement = chain; + while(chainElement != NULL) + { + chainElement->control = (uint32_t)control; + chainElement = chainElement->next; + if(chainElement == chain) + { + //We've populated all of the control values in this circular linked list, we are done here + break; + } + } + + This->mCurrentDMAItem.source = (uint32_t)src; + This->mCurrentDMAItem.destination = (uint32_t)dst; + This->mCurrentDMAItem.next = chain; + This->mCurrentDMAItem.control = control; +} + +void startPIO(internal_pio_object_t * pio_object) +{ + if (pio_object) + { + if (pio_object->mWhichDevice == kPIOReceive) + { + uint32_t MCAUNSRXCFG = readMCA0Reg(rMCAUNSRXCFG); + writeMCA0Reg(rMCAUNSRXCFG, MCAUNSRXCFG | (1 << rMCAUNSRXCFG_IRQ_EN)); + } + else + { + uint32_t MCAUNSTXCFG = readMCA0Reg(rMCAUNSTXCFG); + writeMCA0Reg(rMCAUNSTXCFG, MCAUNSTXCFG | (1 << rMCAUNSTXCFG_IRQ_EN)); + } + } +} + +void stopPIO(internal_pio_object_t * pio_object) +{ + if (pio_object) + { + if (pio_object->mWhichDevice == kPIOReceive) + { + uint32_t MCAUNSRXCFG = readMCA0Reg(rMCAUNSRXCFG); + writeMCA0Reg(rMCAUNSRXCFG, MCAUNSRXCFG & ~((1 << rMCAUNSRXCFG_IRQ_EN))); + } + else + { + uint32_t MCAUNSTXCFG = readMCA0Reg(rMCAUNSTXCFG); + writeMCA0Reg(rMCAUNSTXCFG, MCAUNSTXCFG & ~((1 << rMCAUNSTXCFG_IRQ_EN))); + } + } +} + + diff --git a/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.h b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.h new file mode 100644 index 0000000..a30dc2a --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pio_ae2.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PL080DMAC_AE2__ +#define __PL080DMAC_AE2__ + +#include +#include +#include "ae2_dma.h" + +typedef enum { + kPIOReceive = 0, + kPIOTransmit = 1, + kNumPIOs = 2, +} ePIOType; + +enum { kBurstSize = 4 }; + +typedef struct +{ + ePIOType mWhichDevice; + int_handler mInterruptHandler; + void * mInterruptHandlerData; + DMALinkedListItem mCurrentDMAItem; + uint32_t mErrorCount[kAudioDevice_Last]; +} internal_pio_object_t; + +void handleAudioDeviceInterrupt(); + +/* + setup pio. Set the DMA linked list for doing PIO operations. + preps the pio_object for doing it's first pio op + */ +void setupPIO(internal_pio_object_t * pio_object, void *src, void *dst, DMALinkedListItem *chain, size_t bytesToTransfer); + +/* + Startup PIO + */ +void startPIO(internal_pio_object_t * pio_object); + +/* + Stop PIO + */ +void stopPIO(internal_pio_object_t * pio_object); + +#endif /* __PL080DMAC_AE2__ */ + diff --git a/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.c b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.c new file mode 100644 index 0000000..6f68446 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.c @@ -0,0 +1,380 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "pl080dmac_ae2.h" +#include "ae2_i2s.h" +#include "ae2_mca.h" +#include +#include +#include + +#ifdef MAP_SRAM_CACHED +#error DMA requires the SRAM to be uncached +#endif + + +typedef struct +{ + uint32_t mDMAChannel; + int_handler mInterruptHandler; + void * mInterruptHandlerData; + int_handler mErrorHandler; + void * mErrorHandlerData; +} internal_dma_object_t; + +#define validDMAChannel(dmaChannel) (dmaChannel!=0xffffffff) + +//Per AE2 Local DMA Controller/Requests +static const uint32_t sDMARequestInterfaceRx[kAudioDevice_Last] = {0, 2, 4, 6, 10, 6}; +static const uint32_t sDMARequestInterfaceTx[kAudioDevice_Last] = {1, 3, 5, 7, 11, 7}; +static void* sDMAAddressRX[kAudioDevice_Last] = { (void*)rI2S0_RXDB, (void*)rI2S1_RXDB, (void*)rI2S2_RXDB, (void*)rI2S3_RXDB, (void*)rMCA0_RXDATA, (void*)rMCA1_RXDATA }; +static void* sDMAAddressTX[kAudioDevice_Last] = { (void*)rI2S0_TXDB, (void*)rI2S1_TXDB, (void*)rI2S2_TXDB, (void*)rI2S3_TXDB, (void*)rMCA0_TXDATA, (void*)rMCA1_TXDATA }; + +static internal_dma_object_t* sDMAChannelObjects[kDMAChannelsPerController] = { NULL }; +static uint32_t sDMACC0InUse = 0; +static uint32_t sDMACC0Running = 0; + +uint32_t readReg(uint32_t address) +{ + return *(volatile uint32_t *)address; +} + +void writeReg(uint32_t address, uint32_t value) +{ + *(volatile uint32_t *)address = value; +} + +uint32_t readDMAReg(uint32_t offset) +{ + return readReg(kDMACBase + offset); +} + +void writeDMAReg(uint32_t offset, uint32_t value) +{ + writeReg(kDMACBase + offset, value); +} + +uint32_t readDMAChannelReg(uint32_t channel, uint32_t offset) +{ + uint32_t dmaChannelOffset = kDMAC0Base + channel * kDMACRegisterSize; + return readReg(dmaChannelOffset + offset); +} + +void writeDMAChannelReg(uint32_t channel, uint32_t offset, uint32_t value) +{ + uint32_t dmaChannelOffset = kDMAC0Base + channel * kDMACRegisterSize; + writeReg(dmaChannelOffset + offset, value); +} + + +dma_object_t create_dma_object(void *buffer, AudioDevice_Index device, DMALinkedListItem *chain, DMADirection direction, size_t bytesToTransfer) +{ + dprintf(DEBUG_CRITICAL, "Creating a DMA object\n"); + if ((device >= kAudioDevice_Last) || ((direction != kDirectionIn) && (direction != kDirectionOut))) + { + dprintf(DEBUG_CRITICAL, "oops, bad arg\n"); + return NULL; + } + internal_dma_object_t *This = (internal_dma_object_t*)malloc(sizeof(internal_dma_object_t)); + if (This) + { + uint32_t dmaChannel = acquireDMAChannel(); + dprintf(DEBUG_CRITICAL, "channel is %d\n", dmaChannel); + if (dmaChannel == 0xFFFFFFFF) + { + free(This); + return NULL; + } + This->mDMAChannel = dmaChannel; + This->mInterruptHandler = NULL; + This->mInterruptHandlerData = NULL; + This->mErrorHandler = NULL; + This->mErrorHandlerData = NULL; + configureDMA(This->mDMAChannel); + if (direction == kDirectionIn) + { + setupDMA(This->mDMAChannel, sDMAAddressRX[device], buffer, chain, kDirectionIn, sDMARequestInterfaceRx[device], bytesToTransfer); + } + else + { + setupDMA(This->mDMAChannel, buffer, sDMAAddressTX[device], chain, kDirectionOut, sDMARequestInterfaceTx[device], bytesToTransfer); + } + sDMAChannelObjects[This->mDMAChannel] = This; + // we can do this here repeatedly + install_int_handler(AE2_INT_DMACINTTC, handleAudioDeviceDMAInterrupt, NULL); + install_int_handler(AE2_INT_DMACINTERR, handleAudioDeviceDMAInterruptError, NULL); + } + return This; +} + +void destroy_dma_object(dma_object_t dma) +{ + // preliminary stop + stopDMAObject(dma, true); + internal_dma_object_t *This = (internal_dma_object_t*)dma; + if (This) + { + sDMAChannelObjects[This->mDMAChannel] = NULL; + freeDMAChannel(This->mDMAChannel); + free(This); + } +} + +uint32_t getErrorCount(dma_object_t, Error_Index) +{ + return 0; +} + +void setupInterruptHandler(dma_object_t dma, int_handler handler, void *arg) +{ + internal_dma_object_t *This = (internal_dma_object_t*)dma; + if (This) + { + This->mInterruptHandler = handler; + This->mInterruptHandlerData = arg; + } +} + +void setupErrorHandler(dma_object_t dma, int_handler handler, void *arg) +{ + internal_dma_object_t *This = (internal_dma_object_t*)dma; + if (This) + { + This->mErrorHandler = handler; + This->mErrorHandlerData = arg; + } +} + +void startDMAObject(dma_object_t dma) +{ + internal_dma_object_t *This = (internal_dma_object_t*)dma; + if (This) + { + startDMA(This->mDMAChannel); + + sDMACC0Running |= (1 << This->mDMAChannel); + if (sDMACC0Running) + { + unmask_int(AE2_INT_DMACINTTC); + unmask_int(AE2_INT_DMACINTERR); + } + } +} + +void stopDMAObject(dma_object_t dma, bool immediate) +{ + internal_dma_object_t *This = (internal_dma_object_t*)dma; + if (This) + { + if (immediate) + { + disableDMAImmediate(This->mDMAChannel); + } + else + { + disableDMA(This->mDMAChannel); + } + sDMACC0Running &= ~(1 << This->mDMAChannel); + if (!sDMACC0Running) + { + mask_int(AE2_INT_DMACINTTC); + mask_int(AE2_INT_DMACINTERR); + } + } +} + +void handleAudioDeviceDMAInterrupt() +{ + uint32_t status = readDMAReg(kDMACIntTCStatus); + for (uint32_t channel = 0; channel < kDMAChannelsPerController; channel++) + { + uint32_t mask = 1 << channel; + if (status & mask) + { + writeDMAReg(kDMACIntTCClear, mask); //clear int + + if(sDMAChannelObjects[channel] != NULL && sDMAChannelObjects[channel]->mInterruptHandler) + { + sDMAChannelObjects[channel]->mInterruptHandler(sDMAChannelObjects[channel]->mInterruptHandlerData); + } + } + } +} + +void handleAudioDeviceDMAInterruptError() +{ + uint32_t status = readDMAReg(kDMACIntErrStatus); + for (uint32_t channel = 0; channel < kDMAChannelsPerController; channel++) + { + uint32_t mask = 1 << channel; + if (status & mask) + { + writeDMAReg(kDMACIntErrClear, mask); //clear int + if(sDMAChannelObjects[channel] != NULL && sDMAChannelObjects[channel]->mInterruptHandler) + { + sDMAChannelObjects[channel]->mInterruptHandler(sDMAChannelObjects[channel]->mInterruptHandlerData); + } + } + } +} + +uint32_t acquireDMAChannel(void) +{ + uint32_t result = 0xFFFFFFFF; + for(uint32_t channel = 0; channel < kDMAChannelsPerController; channel++) + { + if(!(sDMACC0InUse & (1 << channel))) + { + sDMACC0InUse |= (1 << channel); + result = channel; + break; + } + } + if (sDMACC0InUse) + { + writeReg(kDMACClockGating, 0); + writeDMAReg(kDMACConfiguration, DMACConfiguration_M2_Little | DMACConfiguration_M1_Little | DMACConfiguration_E_Enable); + } + return result; +} + +void freeDMAChannel(uint32_t dmaChannel) +{ + sDMACC0InUse &= ~(1 << dmaChannel); + // if there are no channels in use, shut down DMA + if (!sDMACC0InUse) + { + uint32_t config = readDMAReg(kDMACConfiguration); + writeDMAReg(kDMACConfiguration, config & ~DMACConfiguration_E_Enable); + } +} + +void configureDMA(uint32_t dmaChannel) +{ + if(!validDMAChannel(dmaChannel)) return; + + uint32_t control = DMACCxControl_I_Enable | + DMACCxControl_D_Master1 | + DMACCxControl_S_Master1 | + DMACCxControl_SWidth_Halfword | + DMACCxControl_DWidth_Halfword | + DMACCxControl_SBSize_4 | + DMACCxControl_DBSize_4; + + writeDMAChannelReg(dmaChannel, kDMACCtrlOffset, control); +} + +void setupDMA(uint32_t dmaChannel, void *src, void *dst, DMALinkedListItem *chain, DMADirection direction, uint32_t peripheral, size_t bytesToTransfer) +{ + if(!validDMAChannel(dmaChannel)) return; + + uint32_t transferSize = bytesToTransfer >> 1; //assuming burst size of DMACCxControl_DWidth_Halfword + uint32_t control = readDMAChannelReg(dmaChannel, kDMACCtrlOffset); + + control &= ~(DMACCxControl_TransferSizeMask | // Clear transfer size + DMACCxControl_SI_Mask | // Clear source increment + DMACCxControl_DI_Mask); // Clear destination increment + + control |= (transferSize & 0x0FFF); + + uint32_t flowControl, sourcePeripheral, destinationPeripheral; + if(direction == kDirectionIn) // -> peripheral-to-memory + { + control |= DMACCxControl_SI_No_Increment; + control |= DMACCxControl_DI_Increment; + + flowControl = DMACCxConfiguration_FlowCntrl_Peripheral_to_Memory_DMA; + sourcePeripheral = peripheral; + destinationPeripheral = 0; //mem + } + else if(direction == kDirectionOut) //kDirectionOut -> memory-to-peripheral + { + control |= DMACCxControl_SI_Increment; + control |= DMACCxControl_DI_No_Increment; + + flowControl = DMACCxConfiguration_FlowCntrl_Memory_to_Peripheral_DMA; + sourcePeripheral = 0; //mem + destinationPeripheral = peripheral; + } + else //kDirectionNone -> mem-to-mem here + { + control |= DMACCxControl_SI_Increment; + control |= DMACCxControl_DI_Increment; + + flowControl = DMACCxConfiguration_FlowCntrl_Memory_to_Memory_DMA; + sourcePeripheral = 0; //mem + destinationPeripheral = 0; //mem + } + + DMALinkedListItem *chainElement = chain; + while(chainElement != NULL) + { + chainElement->control = (uint32_t)control; + chainElement = chainElement->next; + if(chainElement == chain) + { + //We've populated all of the control values in this circular linked list, we are done here + break; + } + } + + writeDMAChannelReg(dmaChannel, kDMACSourceOffset, (uint32_t)src); + writeDMAChannelReg(dmaChannel, kDMACDestOffset, (uint32_t)dst); + writeDMAChannelReg(dmaChannel, kDMACLLIOffset, (uint32_t)chain); + writeDMAChannelReg(dmaChannel, kDMACCtrlOffset, control); + + flowControl |= DMACCxConfiguration_ITC_Enable; + flowControl |= DMACCxConfiguration_IError_Enable; + flowControl |= ((destinationPeripheral & 0xF) << 6); + flowControl |= ((sourcePeripheral & 0xF) << 1); + + // do this in the start + //flowControl |= DMACCxConfiguration_E_Enable; + + writeDMAChannelReg(dmaChannel, kDMACConfigOffset, flowControl); +} + +void startDMA(uint32_t dmaChannel) +{ + if(!validDMAChannel(dmaChannel)) return; + + uint32_t flowControl = readDMAChannelReg(dmaChannel, kDMACConfigOffset); + writeDMAChannelReg(dmaChannel, kDMACConfigOffset, flowControl |= DMACCxConfiguration_E_Enable); +} + +void disableDMA(uint32_t dmaChannel) +{ + if(!validDMAChannel(dmaChannel)) return; + + uint32_t config = readDMAChannelReg(dmaChannel, kDMACConfigOffset); + writeDMAChannelReg(dmaChannel, kDMACConfigOffset, config | DMACCxConfiguration_Halt); + + config = readDMAChannelReg(dmaChannel, kDMACConfigOffset); + // give a chance for the DMA to timeout. But don't wait forever... + int timeToWait = 0x100; + while(config & DMACCxConfiguration_Active && (timeToWait-- > 0)) + { + config = readDMAChannelReg(dmaChannel, kDMACConfigOffset); + } + disableDMAImmediate(dmaChannel); +} + +void disableDMAImmediate(uint32_t dmaChannel) +{ + if(!validDMAChannel(dmaChannel)) return; + + uint32_t config = readDMAChannelReg(dmaChannel, kDMACConfigOffset); + writeDMAChannelReg(dmaChannel, kDMACConfigOffset, config & ~DMACCxConfiguration_E_Enable); + + writeDMAReg(kDMACIntTCClear, 1 << dmaChannel); // clear any outstanding ints + writeDMAReg(kDMACIntErrClear, 1 << dmaChannel); // clear any outstanding ints +} + diff --git a/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.h b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.h new file mode 100644 index 0000000..87f0b68 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AE2_DMA/pl080dmac_ae2.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PL080DMAC_AE2__ +#define __PL080DMAC_AE2__ + +#include +#include +#include "ae2_dma.h" + +#define kDMACClockGating 0x341A0004 + +#define kDMAChannelsPerController 8 + +#define kDMACBase 0x341A3000 +#define kDMAC0Base 0x341A3100 + +#define kDMACIntStatus 0x0 +#define kDMACIntTCStatus 0x4 +#define kDMACIntTCClear 0x8 +#define kDMACIntErrStatus 0xC +#define kDMACIntErrClear 0x10 + +#define kDMACConfiguration 0x30 + +#define kDMACSourceOffset 0x0 +#define kDMACDestOffset 0x4 +#define kDMACLLIOffset 0x8 +#define kDMACCtrlOffset 0xC +#define kDMACConfigOffset 0x10 +#define kDMACRegisterSize 0x20 + +#define DMACConfiguration_M2_Mask (1 << 2) +#define DMACConfiguration_M2_Little (0 << 2) +#define DMACConfiguration_M2_Big (1 << 2) +#define DMACConfiguration_M1_Mask (1 << 1) +#define DMACConfiguration_M1_Little (0 << 1) +#define DMACConfiguration_M1_Big (1 << 1) +#define DMACConfiguration_E_Mask (1 << 0) +#define DMACConfiguration_E_Disable (0 << 0) +#define DMACConfiguration_E_Enable (1 << 0) + +#define DMACCxConfiguration_Halt (1 << 18) +#define DMACCxConfiguration_Active (1 << 17) +#define DMACCxConfiguration_ITC_Enable (1 << 15) +#define DMACCxConfiguration_IError_Enable (1 << 14) +#define DMACCxConfiguration_E_Enable (1 << 0) + +#define DMACCxControl_I_Mask (1 << 31) +#define DMACCxControl_I_Disable (0 << 31) +#define DMACCxControl_I_Enable (1 << 31) +#define DMACCxControl_SI_Mask (1 << 26) +#define DMACCxControl_SI_No_Increment (0 << 26) +#define DMACCxControl_SI_Increment (1 << 26) +#define DMACCxControl_DI_Mask (1 << 27) +#define DMACCxControl_DI_No_Increment (0 << 27) +#define DMACCxControl_DI_Increment (1 << 27) +#define DMACCxControl_D_Master1 (0 << 25) +#define DMACCxControl_S_Master1 (0 << 24) +#define DMACCxControl_SWidth_Halfword (1 << 18) +#define DMACCxControl_DWidth_Halfword (1 << 21) +#define DMACCxControl_DBSize_1 (0 << 15) +#define DMACCxControl_DBSize_4 (1 << 15) +#define DMACCxControl_SBSize_1 (0 << 12) +#define DMACCxControl_SBSize_4 (1 << 12) +#define DMACCxControl_TransferSizeMask (0x0FFF) + +#define DMACCxConfiguration_FlowCntrl_Memory_to_Memory_DMA (0 << 11) +#define DMACCxConfiguration_FlowCntrl_Memory_to_Peripheral_DMA (1 << 11) +#define DMACCxConfiguration_FlowCntrl_Peripheral_to_Memory_DMA (2 << 11) + + +void handleAudioDeviceDMAInterrupt(); + +void handleAudioDeviceDMAInterruptError(); + +/* + Get a free DMA channel +*/ +uint32_t acquireDMAChannel(void); + +/* + Free a DMA channel +*/ +void freeDMAChannel(uint32_t dmaChannel); + +/* + Make sure the pl080 clock is enabled and initialize DMA channels 0 and 1 + */ +void configureDMA(uint32_t dmaChannel); + +/* + Startup DMA from address src to destination dst + If chain is not NULL, will setup that in the LLI to auto-restart DMA from the chain + */ +void setupDMA(uint32_t dmaChannel, void *src, void *dst, DMALinkedListItem *chain, DMADirection direction, uint32_t peripheral, size_t bytesToTransfer); + +/* + Startup DMA from address src to destination dst + If chain is not NULL, will setup that in the LLI to auto-restart DMA from the chain + */ +void startDMA(uint32_t dmaChannel); + +/* + Halts the channel, then blocks until the DMA is complete and then fully disables it + */ +void disableDMA(uint32_t dmaChannel); + +/* + Blocks until the DMA is complete and then fully disables it + */ +void disableDMAImmediate(uint32_t dmaChannel); + +#endif /* __PL080DMAC_AE2__ */ + diff --git a/apps/EmbeddedIOP/function_audiodsp/AE2_I2S/ae2_i2s.h b/apps/EmbeddedIOP/function_audiodsp/AE2_I2S/ae2_i2s.h new file mode 100644 index 0000000..e2f723e --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AE2_I2S/ae2_i2s.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AE2_I2S__ +#define __AE2_I2S__ + +#include +#include + +#define rI2S_BASE 0x34190000 +#define rI2S0_BASE (rI2S_BASE ) +#define rI2S1_BASE (rI2S_BASE + 0x1000) +#define rI2S2_BASE (rI2S_BASE + 0x2000) +#define rI2S3_BASE (rI2S_BASE + 0x3000) + +#define rI2SCLKCON 0 +#define rI2STXCON 0x4 +#define rI2STXCOM 0x8 +#define rI2STXDB 0x10 +#define rI2SRXCON 0x30 +#define rI2SRXCOM 0x34 +#define rI2SRXDB 0x38 +#define rI2SSTATUS 0x3C +#define rI2SBITCLK 0x40 +#define rI2SVERSION 0x44 + +#define rI2S0_CLKCON (rI2S0_BASE + rI2SCLKCON ) +#define rI2S0_TXCON (rI2S0_BASE + rI2STXCON ) +#define rI2S0_TXCOM (rI2S0_BASE + rI2STXCOM ) +#define rI2S0_TXDB (rI2S0_BASE + rI2STXDB ) +#define rI2S0_RXCON (rI2S0_BASE + rI2SRXCON ) +#define rI2S0_RXCOM (rI2S0_BASE + rI2SRXCOM ) +#define rI2S0_RXDB (rI2S0_BASE + rI2SRXDB ) +#define rI2S0_STATUS (rI2S0_BASE + rI2SSTATUS ) +#define rI2S0_BITCLK (rI2S0_BASE + rI2SBITCLK ) +#define rI2S0_VERSION (rI2S0_BASE + rI2SVERSION) + +#define rI2S1_CLKCON (rI2S1_BASE + rI2SCLKCON ) +#define rI2S1_TXCON (rI2S1_BASE + rI2STXCON ) +#define rI2S1_TXCOM (rI2S1_BASE + rI2STXCOM ) +#define rI2S1_TXDB (rI2S1_BASE + rI2STXDB ) +#define rI2S1_RXCON (rI2S1_BASE + rI2SRXCON ) +#define rI2S1_RXCOM (rI2S1_BASE + rI2SRXCOM ) +#define rI2S1_RXDB (rI2S1_BASE + rI2SRXDB ) +#define rI2S1_STATUS (rI2S1_BASE + rI2SSTATUS ) +#define rI2S1_BITCLK (rI2S1_BASE + rI2SBITCLK ) +#define rI2S1_VERSION (rI2S1_BASE + rI2SVERSION) + +#define rI2S2_CLKCON (rI2S2_BASE + rI2SCLKCON ) +#define rI2S2_TXCON (rI2S2_BASE + rI2STXCON ) +#define rI2S2_TXCOM (rI2S2_BASE + rI2STXCOM ) +#define rI2S2_TXDB (rI2S2_BASE + rI2STXDB ) +#define rI2S2_RXCON (rI2S2_BASE + rI2SRXCON ) +#define rI2S2_RXCOM (rI2S2_BASE + rI2SRXCOM ) +#define rI2S2_RXDB (rI2S2_BASE + rI2SRXDB ) +#define rI2S2_STATUS (rI2S2_BASE + rI2SSTATUS ) +#define rI2S2_BITCLK (rI2S2_BASE + rI2SBITCLK ) +#define rI2S2_VERSION (rI2S2_BASE + rI2SVERSION) + +#define rI2S3_CLKCON (rI2S3_BASE + rI2SCLKCON ) +#define rI2S3_TXCON (rI2S3_BASE + rI2STXCON ) +#define rI2S3_TXCOM (rI2S3_BASE + rI2STXCOM ) +#define rI2S3_TXDB (rI2S3_BASE + rI2STXDB ) +#define rI2S3_RXCON (rI2S3_BASE + rI2SRXCON ) +#define rI2S3_RXCOM (rI2S3_BASE + rI2SRXCOM ) +#define rI2S3_RXDB (rI2S3_BASE + rI2SRXDB ) +#define rI2S3_STATUS (rI2S3_BASE + rI2SSTATUS ) +#define rI2S3_BITCLK (rI2S3_BASE + rI2SBITCLK ) +#define rI2S3_VERSION (rI2S3_BASE + rI2SVERSION) + +#define rI2SSTATUS_RXOVERRUN 20 +#define rI2SSTATUS_TXOVERRUN 19 +#define rI2SSTATUS_RXFIFOLVL 13 +#define rI2SSTATUS_TXFIFOLVL 7 +#define rI2SSTATUS_RXOVERRUN_MASK ( 1 << 20) +#define rI2SSTATUS_TXOVERRUN_MASK ( 1 << 19) +#define rI2SSTATUS_RXFIFOLVL_MASK (0x3F << 13) +#define rI2SSTATUS_TXFIFOLVL_MASK (0x3F << 7 ) + +#endif /* __AE2_I2S__ */ \ No newline at end of file diff --git a/apps/EmbeddedIOP/function_audiodsp/AE2_MCA/ae2_mca.h b/apps/EmbeddedIOP/function_audiodsp/AE2_MCA/ae2_mca.h new file mode 100644 index 0000000..b011dc6 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AE2_MCA/ae2_mca.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AE2_MCA__ +#define __AE2_MCA__ + +#include +#include + +#define rMCA_BASE 0x34196000 +#define rMCA0_BASE (rMCA_BASE ) +#define rMCA1_BASE (rMCA_BASE + 0x1000) + +#define rMCAVERSION 0 +#define rMCAFIFOSIZE 0x4 +#define rMCAFIFOSHIFT 0x8 +#define rMCACFG 0xC +#define rMCAUNSCFG 0x10 +#define rMCAIDLE 0x14 +#define rMCATXCFG 0x18 +#define rMCAUNSTXCFG 0x1C +#define rMCATXFIFOCFG 0x20 +#define rMCATXMASK 0x24 +#define rMCATXDATA 0x28 +#define rMCARXCFG 0x2C +#define rMCAUNSRXCFG 0x30 +#define rMCARXFIFOCFG 0x34 +#define rMCARXMASK 0x38 +#define rMCARXDATA 0x3C +#define rMCASTATUS 0x40 +#define rMCACTL 0x44 + +#define rMCA0_VERSION ( rMCA0_BASE + rMCAVERSION ) +#define rMCA0_FIFOSHIFT ( rMCA0_BASE + rMCAFIFOSHIFT) +#define rMCA0_CFG ( rMCA0_BASE + rMCACFG ) +#define rMCA0_UNSCFG ( rMCA0_BASE + rMCAUNSCFG ) +#define rMCA0_IDLE ( rMCA0_BASE + rMCAIDLE ) +#define rMCA0_TXCFG ( rMCA0_BASE + rMCATXCFG ) +#define rMCA0_UNSTXCFG ( rMCA0_BASE + rMCAUNSTXCFG ) +#define rMCA0_TXFIFOCFG ( rMCA0_BASE + rMCATXFIFOCFG) +#define rMCA0_TXMASK ( rMCA0_BASE + rMCATXMASK ) +#define rMCA0_TXDATA ( rMCA0_BASE + rMCATXDATA ) +#define rMCA0_RXCFG ( rMCA0_BASE + rMCARXCFG ) +#define rMCA0_UNSRXCFG ( rMCA0_BASE + rMCAUNSRXCFG ) +#define rMCA0_RXFIFOCFG ( rMCA0_BASE + rMCARXFIFOCFG) +#define rMCA0_RXMASK ( rMCA0_BASE + rMCARXMASK ) +#define rMCA0_RXDATA ( rMCA0_BASE + rMCARXDATA ) +#define rMCA0_STATUS ( rMCA0_BASE + rMCASTATUS ) +#define rMCA0_CTL ( rMCA0_BASE + rMCACTL ) + +#define rMCA1_VERSION ( rMCA1_BASE + rMCAVERSION ) +#define rMCA1_FIFOSHIFT ( rMCA1_BASE + rMCAFIFOSHIFT) +#define rMCA1_CFG ( rMCA1_BASE + rMCACFG ) +#define rMCA1_UNSCFG ( rMCA1_BASE + rMCAUNSCFG ) +#define rMCA1_IDLE ( rMCA1_BASE + rMCAIDLE ) +#define rMCA1_TXCFG ( rMCA1_BASE + rMCATXCFG ) +#define rMCA1_UNSTXCFG ( rMCA1_BASE + rMCAUNSTXCFG ) +#define rMCA1_TXFIFOCFG ( rMCA1_BASE + rMCATXFIFOCFG) +#define rMCA1_TXMASK ( rMCA1_BASE + rMCATXMASK ) +#define rMCA1_TXDATA ( rMCA1_BASE + rMCATXDATA ) +#define rMCA1_RXCFG ( rMCA1_BASE + rMCARXCFG ) +#define rMCA1_UNSRXCFG ( rMCA1_BASE + rMCAUNSRXCFG ) +#define rMCA1_RXFIFOCFG ( rMCA1_BASE + rMCARXFIFOCFG) +#define rMCA1_RXMASK ( rMCA1_BASE + rMCARXMASK ) +#define rMCA1_RXDATA ( rMCA1_BASE + rMCARXDATA ) +#define rMCA1_STATUS ( rMCA1_BASE + rMCASTATUS ) +#define rMCA1_CTL ( rMCA1_BASE + rMCACTL ) + +#define rMCASTATUS_FRAMEERROR 31 +#define rMCASTATUS_RXOVERRUN 29 +#define rMCASTATUS_RXUNDERRUN 28 +#define rMCASTATUS_RXHIGHWATER 27 +#define rMCASTATUS_RXLOWWATER 26 +#define rMCASTATUS_TXOVERRUN 13 +#define rMCASTATUS_TXUNDERRUN 12 +#define rMCASTATUS_TXHIGHWATER 11 +#define rMCASTATUS_TXLOWWATER 10 +#define rMCASTATUS_RXFIFOLVL 16 +#define rMCASTATUS_TXFIFOLVL 0 +#define rMCASTATUS_FRAMEEEROR_MASK ( 1 << rMCASTATUS_FRAMEERROR) +#define rMCASTATUS_RXOVERRUN_MASK ( 1 << rMCASTATUS_RXOVERRUN) +#define rMCASTATUS_RXUNDERRUN_MASK ( 1 << rMCASTATUS_RXUNDERRUN) +#define rMCASTATUS_TXOVERRUN_MASK ( 1 << rMCASTATUS_TXOVERRUN) +#define rMCASTATUS_TXUNDERRUN_MASK ( 1 << rMCASTATUS_TXUNDERRUN) +#define rMCASTATUS_RXFIFOLVL_MASK (0x1FF << rMCASTATUS_RXFIFOLVL) +#define rMCASTATUS_TXFIFOLVL_MASK (0x1FF << rMCASTATUS_TXFIFOLVL) + +#define rMCAUNSRXCFG_IRQ_EN 1 + +#define rMCAUNSTXCFG_IRQ_EN 1 + +#endif /* __AE2_MCA__ */ diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUBase_AE2.h b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUBase_AE2.h new file mode 100644 index 0000000..dba457e --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUBase_AE2.h @@ -0,0 +1,50 @@ +/* + * AudioUnit_AE2.h + * CAServices-Aspen + * + * Created by richardp on 11/28/11. + * Copyright 2011 Apple, Inc. All rights reserved. + * + * Serves as the base class for AudioUnits on AE2 + */ + +#ifndef __AudioUnit_AE2_h__ +#define __AudioUnit_AE2_h__ + +#include + +#include "AudioUnitProperties_AE2.h" + +/** + * AUBase_AE2 is the wrapper to go from AE2 land to CoreAudio land. + * For instance, we assume input channels are 16-bit, whereas CoreAudio + * AudioUnit may require floats. These modules do the translation. + * + * This is not intended to be parity with AudioUnits, but a crippled + * version. + */ + +class AUBase_AE2 +{ +public: + AUBase_AE2() {} + virtual ~AUBase_AE2() {} + + virtual OSStatus Initialize() { return noErr; } + + virtual void Process(const void *inSourceP, + void *inDestP, + uint32_t inFramesToProcess) {} + + // for parameters + virtual OSStatus SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value) { return kAudioUnitErr_InvalidParameter; } + virtual AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID) { return 0; } + + // for properties + virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID, uint32_t& outDataSize, bool& outWritable) { return kAudioUnitErr_InvalidProperty; } + virtual OSStatus GetProperty(AudioUnitPropertyID inID, void* outData) { return kAudioUnitErr_InvalidProperty; } + virtual OSStatus SetProperty(AudioUnitPropertyID inID, const void* inData, uint32_t inDataSize) { return kAudioUnitErr_InvalidProperty; } +}; + +#endif // __AudioUnit_AE2_h__ + diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUComponent_AE2.h b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUComponent_AE2.h new file mode 100644 index 0000000..1a299d5 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUComponent_AE2.h @@ -0,0 +1,149 @@ +/* + * AUComponent_AE2.h + * Stripped down version of AUComponent just for what AE2 needs + * + * Copyright 2010 Apple Computer. All rights reserved. + * + */ + +#ifndef __AUCOMPONENT_AE2__ +#define __AUCOMPONENT_AE2__ + +/*! + @enum Audio unit errors + @discussion These are the various errors that can be returned by AudioUnit... API calls + + @constant kAudioUnitErr_InvalidProperty + The property is not supported + @constant kAudioUnitErr_InvalidParameter + The parameter is not supported + @constant kAudioUnitErr_InvalidElement + The specified element is not valid + @constant kAudioUnitErr_NoConnection + There is no connection (generally an audio unit is asked to render but it has + not input from which to gather data) + @constant kAudioUnitErr_FailedInitialization + The audio unit is unable to be initialised + @constant kAudioUnitErr_TooManyFramesToProcess + When an audio unit is initialised it has a value which specifies the max + number of frames it will be asked to render at any given time. If an audio + unit is asked to render more than this, this error is returned. + @constant kAudioUnitErr_InvalidFile + If an audio unit uses external files as a data source, this error is returned + if a file is invalid (Apple's DLS synth returns this error) + @constant kAudioUnitErr_FormatNotSupported + Returned if an input or output format is not supported + @constant kAudioUnitErr_Uninitialized + Returned if an operation requires an audio unit to be initialised and it is + not. + @constant kAudioUnitErr_InvalidScope + The specified scope is invalid + @constant kAudioUnitErr_PropertyNotWritable + The property cannot be written + @constant kAudioUnitErr_CannotDoInCurrentContext + Returned when an audio unit is in a state where it can't perform the requested + action now - but it could later. Its usually used to guard a render operation + when a reconfiguration of its internal state is being performed. + @constant kAudioUnitErr_InvalidPropertyValue + The property is valid, but the value of the property being provided is not + @constant kAudioUnitErr_PropertyNotInUse + Returned when a property is valid, but it hasn't been set to a valid value at + this time. + @constant kAudioUnitErr_Initialized + Indicates the operation cannot be performed because the audio unit is + initialized. + @constant kAudioUnitErr_InvalidOfflineRender + Used to indicate that the offline render operation is invalid. For instance, + when the audio unit needs to be pre-flighted, + but it hasn't been. + @constant kAudioUnitErr_Unauthorized + Returned by either Open or Initialise, this error is used to indicate that the + audio unit is not authorised, that it cannot be used. A host can then present + a UI to notify the user the audio unit is not able to be used in its current + state. + */ +enum +{ + kAudioUnitErr_InvalidProperty = -10879, + kAudioUnitErr_InvalidParameter = -10878, + kAudioUnitErr_InvalidElement = -10877, + kAudioUnitErr_NoConnection = -10876, + kAudioUnitErr_FailedInitialization = -10875, + kAudioUnitErr_TooManyFramesToProcess = -10874, + kAudioUnitErr_InvalidFile = -10871, + kAudioUnitErr_FormatNotSupported = -10868, + kAudioUnitErr_Uninitialized = -10867, + kAudioUnitErr_InvalidScope = -10866, + kAudioUnitErr_PropertyNotWritable = -10865, + kAudioUnitErr_CannotDoInCurrentContext = -10863, + kAudioUnitErr_InvalidPropertyValue = -10851, + kAudioUnitErr_PropertyNotInUse = -10850, + kAudioUnitErr_Initialized = -10849, + kAudioUnitErr_InvalidOfflineRender = -10848, + kAudioUnitErr_Unauthorized = -10847 +}; + +/*! + @typedef AudioUnitPropertyID + @discussion Type used for audio unit properties. + Properties are used to describe the state of an audio unit (for instance, + the input or output audio format) + */ +typedef UInt32 AudioUnitPropertyID; +/*! + @typedef AudioUnitScope + @discussion Type used for audio unit scopes. Apple reserves the 0 < 1024 range for + audio unit scope identifiers. + Scopes are used to delineate a major attribute of an audio unit + (for instance, global, input, output) + */ +typedef UInt32 AudioUnitScope; +/*! + @typedef AudioUnitElement + @discussion Type used for audio unit elements. + Scopes can have one or more member, and a member of a scope is + addressed / described by its element + For instance, input bus 1 is input scope, element 1 + */ +typedef UInt32 AudioUnitElement; +/*! + @typedef AudioUnitParameterID + @discussion Type used for audio unit parameters. + Parameters are typically used to control and set render state + (for instance, filter cut-off frequency) + */ +typedef UInt32 AudioUnitParameterID; +/*! + @typedef AudioUnitParameterValue + @discussion Type used for audio unit parameter values. + The value of a given parameter is specified using this type + (typically a Float32) + */ +typedef Float32 AudioUnitParameterValue; + + +//----------------------------------------------------------------------------- +// Render flags +//----------------------------------------------------------------------------- + +enum +{ + /* these are obsolete, were never implemented: */ + /* kAudioUnitRenderAction_Accumulate = (1 << 0) */ + /* kAudioUnitRenderAction_UseProvidedBuffer = (1 << 1) */ + kAudioUnitRenderAction_PreRender = (1 << 2), + kAudioUnitRenderAction_PostRender = (1 << 3), + kAudioUnitRenderAction_OutputIsSilence = (1 << 4), + /* Provides hint on return from Render(). if set, the buffer contains all zeroes */ + kAudioOfflineUnitRenderAction_Preflight = (1 << 5), + kAudioOfflineUnitRenderAction_Render = (1 << 6), + kAudioOfflineUnitRenderAction_Complete = (1 << 7), + // this flag is set if on the post-render call an error was returned by the AUs render + // in this case, the error can be retrieved through the lastRenderError property + // and the ioData handed to the post-render notification will be invalid. + kAudioUnitRenderAction_PostRenderError = (1 << 8) +}; + +typedef UInt32 AudioUnitRenderActionFlags; + +#endif \ No newline at end of file diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.cpp b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.cpp new file mode 100644 index 0000000..270ad9e --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "AUNull.h" +#include "string.h" +#include + +#define GENERATE_SAWTOOTH 0 + +AUNull * +AUNull::Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize) +{ + AUNull *This = new AUNull; + if (This) + { + if (This->InitWith(sampleRate, numChannels, sampleSize)) + { + This->Initialize(); + } + else + { + delete This; + This = NULL; + } + } + return This; +} + +AUNull::AUNull() +{ +} + + +bool +AUNull::InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize) +{ + mSampleRate = sampleRate; + mNumChannels = numChannels; + mSampleSize = sampleSize; + return true; +} + +AUNull::~AUNull() +{ +} + +#if GENERATE_SAWTOOTH +static int16_t currentValue = 0; +static const uint32_t kFreq = 600; +#endif + +void +AUNull::Process(const void *inSourceP, + void *inDestP, + UInt32 inFramesToProcess) +{ +#if GENERATE_SAWTOOTH + uint16_t amountToAdd = (0x10000L * kFreq) / mSampleRate; + int16_t *dst = static_cast(inDestP); + size_t i = 0; + for (i = 0; i < (inFramesToProcess * mNumChannels); ++i) + { + *dst++ = currentValue; + currentValue += amountToAdd; + } +#endif +} + + diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.h b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.h new file mode 100644 index 0000000..75eb6bb --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUNull.h @@ -0,0 +1,46 @@ +/* + * AUNull.h + * + * Created by richardp on 11/28/11. + * Copyright 2011 Apple, Inc. All rights reserved. + * + * Does necessary translation between AE2 and CA AU speaker protection + */ + +#ifndef __AUNull_h__ +#define __AUNull_h__ + +#include + +#include "AudioUnitProperties_AE2.h" +#include "AUBase_AE2.h" + +class IIRFilter; + +/** + * AUNull just passes input to output + * Assumes audio data is 16-bit stereo + */ +class AUNull : public AUBase_AE2 +{ +public: + static AUNull* Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize); + virtual ~AUNull(); + + virtual void Process(const void *inSourceP, + void *inDestP, + UInt32 inFramesToProcess); + +private: + AUNull(); + bool InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize); + + // some constants + typedef AUBase_AE2 super; + size_t mSampleRate; + size_t mNumChannels; + size_t mSampleSize; +}; + +#endif // __AUNull_h__ + diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.cpp b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.cpp new file mode 100644 index 0000000..38a53fe --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.cpp @@ -0,0 +1,458 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if USE_SIDETONE +#include "AUSidetone.h" +#include "IIRFiltersA5.h" +#include "VolumeA5.h" +#include "string.h" +#include + + +// a basic fixed 16-bit mono 44.1 description +static AudioStreamBasicDescription kDefaultMonoFormat = { 44100.0, 'lpcm', 0xC, 2, 1, 2, 1, 16, 0 }; + +static void SetDefaultSidetoneEQ(BiquadDescriptor *biquadValues, size_t numBands, uint32_t sampleRate) +{ + size_t i = 0; + if (i < numBands) + { + biquadValues[i].filterType = kAUNBandEQFilterType_2ndOrderButterworthLowPass; + biquadValues[i].frequencyInHertz = (sampleRate == 8000) ? 3800.0f : 7400.0f; + biquadValues[i].gain = 0.f; + biquadValues[i].bw = 0.05; + biquadValues[i].bypassBand = 0.f; + ++i; + } + if (i < numBands) + { + biquadValues[i].filterType = kAUNBandEQFilterType_2ndOrderButterworthHighPass; + biquadValues[i].frequencyInHertz = (sampleRate == 8000) ? 200.0f : 100.0f; + biquadValues[i].gain = 0.f; + biquadValues[i].bw = 0.05; + biquadValues[i].bypassBand = 0.f; + ++i; + } + + for (; i < numBands; ++i) + { + biquadValues[i].filterType = 0; + biquadValues[i].frequencyInHertz = 100.0f; + biquadValues[i].gain = 0.f; + biquadValues[i].bw = 0.05; + biquadValues[i].bypassBand = 1.f; + } +} + + +AUSidetone * +AUSidetone::Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize) +{ + AUSidetone *This = new AUSidetone; + if (This) + { + if (This->InitWith(sampleRate, numChannels, sampleSize)) + { + This->Initialize(); + } + else + { + delete This; + This = NULL; + } + } + return This; +} + + +AUSidetone::AUSidetone() : +mSampleRate(44100), +mNumChannels(1), +mSidetoneEQ(NULL), +mVolume(NULL), +mNumberBands(kMaxNumBands), +mBiquadValues(NULL), +mVolumeInDB(kDefaultSidetoneGain), +mSidetoneEQBypass(false) +{ +} + + +bool +AUSidetone::InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize) +{ + if (sampleSize != 2) + { + return false; + } + + mSampleRate = sampleRate; + mNumChannels = numChannels; + + AudioStreamBasicDescription thisFormat = kDefaultMonoFormat; + thisFormat.mSampleRate = mSampleRate; + thisFormat.mBytesPerPacket *= mNumChannels; + thisFormat.mBytesPerFrame *= mNumChannels; + thisFormat.mChannelsPerFrame *= mNumChannels; + thisFormat.mBitsPerChannel *= mNumChannels; + + mSidetoneEQ = NewAE2IIRFilter(&thisFormat, &thisFormat, kMaxNumBands); + dprintf(DEBUG_INFO, "sidetone eq %p\n", mSidetoneEQ); + mBiquadValues = new BiquadDescriptor[mNumberBands]; + if (mBiquadValues) + { + SetDefaultSidetoneEQ(mBiquadValues, mNumberBands, mSampleRate); + if (mSidetoneEQ) + { + mVolume = NewVolume(thisFormat); + dprintf(DEBUG_INFO, "volume %p\n", mVolume); + if (mVolume) + { + if ((SetAE2IIRFilter(mSidetoneEQ, &thisFormat, mNumberBands, mBiquadValues) == noErr) && + (SetGain(mVolume, mVolumeInDB) == noErr)) + { + dprintf(DEBUG_INFO, "it is all good\n"); + return true; + } + DeleteVolume(mVolume); + mVolume = NULL; + } + DeleteAE2IIRFilter(mSidetoneEQ); + mSidetoneEQ = NULL; + } + delete [] mBiquadValues; + mBiquadValues = NULL; + } + return false; +} + + +AUSidetone::~AUSidetone() +{ + DeleteAE2IIRFilter(mSidetoneEQ); + mSidetoneEQ = NULL; + DeleteVolume(mVolume); + mVolume = NULL; + delete [] mBiquadValues; + mBiquadValues = NULL; +} + + +// These conversion routines are for translating from UInt32 of the AP/AE2 bridge +// to the floating point of the internal representation. Scaling and offsets applied here. +Float32 AudioUnitParameterValue_To_BypassBand(AudioUnitParameterValue value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value == 0) ? 0.f : 1.f)); + return (value == 0) ? 0.f : 1.f; +} + + +AudioUnitParameterValue BypassBand_To_AudioUnitParameterValue(Float32 value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value == 0.f) ? 0 : 1)); + return (value == 0.f) ? 0 : 1; +} + + +UInt32 AudioUnitParameterValue_To_FilterType(AudioUnitParameterValue value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value)); + return value; +} + + +AudioUnitParameterValue FilterType_To_AudioUnitParameterValue(UInt32 value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value)); + return value; +} + + +Float32 AudioUnitParameterValue_To_Frequency(AudioUnitParameterValue value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value)); + return value; +} + + +AudioUnitParameterValue Frequency_To_AudioUnitParameterValue(Float32 value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value)); + return value; +} + + +Float32 AudioUnitParameterValue_To_Gain(AudioUnitParameterValue value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(-96.0 + (value))); + return -96.0 + (value); +} + + +AudioUnitParameterValue Gain_To_AudioUnitParameterValue(Float32 value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value) - (-96.0))); + return (value) - (-96.0); +} + + +Float32 AudioUnitParameterValue_To_Bandwidth(AudioUnitParameterValue value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value / 100.0f)); + return value / 100.0f; +} + + +AudioUnitParameterValue Bandwidth_To_AudioUnitParameterValue(Float32 value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value * 100.0f)); + return value * 100.0f; +} + + +Float32 AudioUnitParameterValue_To_VolumeInDB(AudioUnitParameterValue value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(-96.0 + (value))); + return -96.0 + (value); +} + + +AudioUnitParameterValue VolumeInDB_To_AudioUnitParameterValue(Float32 value) +{ + dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value) - (-96.0))); + return (value) - (-96.0); +} + + +OSStatus +AUSidetone::SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value) +{ + dprintf(DEBUG_INFO, "SetParameter %d value %d\n", paramID, uint32_t(value)); + if (paramID == kAUVolume_InDB) + { + mVolumeInDB = AudioUnitParameterValue_To_VolumeInDB(value); + return SetGain(mVolume, mVolumeInDB); + } + + AudioStreamBasicDescription thisFormat = kDefaultMonoFormat; + thisFormat.mSampleRate = mSampleRate; + thisFormat.mBytesPerPacket *= mNumChannels; + thisFormat.mBytesPerFrame *= mNumChannels; + thisFormat.mChannelsPerFrame *= mNumChannels; + thisFormat.mBitsPerChannel *= mNumChannels; + + // get the index + uint32_t which = paramID % 1000; + uint32_t type = (paramID / 1000)*1000; + bool success = false; + if (which < mNumberBands) + { + success = true; + switch (type) + { + case kAUNBandEQParam_BypassBand: + mBiquadValues[which].bypassBand = AudioUnitParameterValue_To_BypassBand(value); + break; + case kAUNBandEQParam_FilterType: + mBiquadValues[which].filterType = AudioUnitParameterValue_To_FilterType(value); + break; + case kAUNBandEQParam_Frequency: + mBiquadValues[which].frequencyInHertz = AudioUnitParameterValue_To_Frequency(value); + break; + case kAUNBandEQParam_Gain: + mBiquadValues[which].gain = AudioUnitParameterValue_To_Gain(value); + break; + case kAUNBandEQParam_Bandwidth: + mBiquadValues[which].bw = AudioUnitParameterValue_To_Bandwidth(value); + break; + default: + success = false; + } + } + + OSStatus result = 0; + if (success) + { + result = SetAE2IIRFilter(mSidetoneEQ, &thisFormat, mNumberBands, mBiquadValues); + } + else + { + result = super::SetParameter(paramID, value); + } + dprintf(DEBUG_INFO, "result is %d\n", result); + return result; +} + + +AudioUnitParameterValue +AUSidetone::GetParameter(AudioUnitParameterID paramID) +{ + if (paramID == kAUVolume_InDB) + { + return VolumeInDB_To_AudioUnitParameterValue(mVolumeInDB); + } + // get the index + uint32_t which = paramID % 1000; + uint32_t type = (paramID / 1000)*1000; + if (which < mNumberBands) + { + switch (type) + { + case kAUNBandEQParam_BypassBand: + return BypassBand_To_AudioUnitParameterValue(mBiquadValues[which].bypassBand); + case kAUNBandEQParam_FilterType: + return FilterType_To_AudioUnitParameterValue(mBiquadValues[which].filterType); + case kAUNBandEQParam_Frequency: + return Frequency_To_AudioUnitParameterValue(mBiquadValues[which].frequencyInHertz); + case kAUNBandEQParam_Gain: + return Gain_To_AudioUnitParameterValue(mBiquadValues[which].gain); + case kAUNBandEQParam_Bandwidth: + return Bandwidth_To_AudioUnitParameterValue(mBiquadValues[which].bw); + } + } + return super::GetParameter(paramID); +} + + +OSStatus +AUSidetone::GetPropertyInfo(AudioUnitPropertyID inID, uint32_t& outDataSize, bool& outWritable) +{ + OSStatus result = -1; + switch (inID) + { + case kAUSongbird_SidetoneState: + result = GetPropertyInfo(kAUSongbird_SidetoneEQBlockData, outDataSize, outWritable); + if (noErr == result) + { + // leave room for the mVolume field of the AU_SidetoneState; + outDataSize += offsetof(AU_SidetoneState, mFilterDescription); + } + break; + case kAUSongbird_SidetoneEQBlockData: + outDataSize = sizeof(AU_BiquadFilterDescription) - sizeof(AU_BiquadFilter) + mNumberBands * sizeof(AU_BiquadFilter); + outWritable = true; + result = noErr; + break; + default: + result = super::GetPropertyInfo(inID, outDataSize, outWritable); + } + return result; +} + + +OSStatus +AUSidetone::GetProperty(AudioUnitPropertyID inID, void* outData) +{ + OSStatus result = -1; + switch (inID) + { + case kAUSongbird_SidetoneState: + { + AU_SidetoneState * state = static_cast(outData); + state->mVolume = mVolumeInDB; + state->mBypass = mSidetoneEQBypass; + void * biquad_filter_description = &state->mFilterDescription; + result = GetProperty(kAUSongbird_SidetoneEQBlockData, biquad_filter_description); + } + break; + case kAUSongbird_SidetoneEQBlockData: + { + AU_BiquadFilterDescription * description = static_cast(outData); + if (description) + { + description->mBypass = mSidetoneEQBypass; + description->mNumberFilters = mNumberBands; + BiquadCoefficientsDescriptor * filter = static_cast(static_cast(description->mFilters)); + if (filter) + { + result = GetAE2IIRFilterCoefficients(mSidetoneEQ, mNumberBands, filter); + } + } + } + break; + default: + result = super::GetProperty(inID, outData); + } + return result; +} + + +OSStatus +AUSidetone::SetProperty(AudioUnitPropertyID inID, const void* inData, uint32_t inDataSize) +{ + OSStatus result = -1; + switch (inID) + { + case kAUSongbird_SidetoneState: + { + // determine if have a valid data structure + if (inDataSize < (offsetof(AU_SidetoneState, mFilterDescription))) + { + break; + } + const AU_SidetoneState * state = static_cast(inData); + const void * biquad_filter_description = &state->mFilterDescription; + result = SetProperty(kAUSongbird_SidetoneEQBlockData, biquad_filter_description, inDataSize - offsetof(AU_SidetoneState, mFilterDescription)); + if (noErr == result) + { + mSidetoneEQBypass = state->mBypass; + mVolumeInDB = state->mVolume; + result = SetGain(mVolume, mVolumeInDB); + } + } + break; + case kAUSongbird_SidetoneEQBlockData: + { + // determine if we are talking to a valid structure + if (inDataSize < sizeof(AU_BiquadFilterDescription) - sizeof(AU_BiquadFilter)) + { + break; + } + const AU_BiquadFilterDescription * description = static_cast(inData); + if (inDataSize < ((sizeof(AU_BiquadFilterDescription) - sizeof(AU_BiquadFilter) + (sizeof(AU_BiquadFilter) * description->mNumberFilters)))) + { + break; + } + if (description->mNumberFilters > kMaxNumBands) + { + break; + } + const BiquadCoefficientsDescriptor * filter = static_cast(static_cast(description->mFilters)); + result = SetAE2IIRFilterCoefficients(mSidetoneEQ, description->mNumberFilters, static_cast(filter)); + if (!result) + { + mSidetoneEQBypass = description->mBypass; + mNumberBands = description->mNumberFilters; + } + } + break; + default: + result = super::SetProperty(inID, inData, inDataSize); + } + return result; +} + + +void +AUSidetone::Process(const void *inSourceP, + void *inDestP, + UInt32 inFramesToProcess) +{ + if (!mSidetoneEQBypass) + { + ProcessAE2IIRFilter(mSidetoneEQ, inFramesToProcess, inSourceP, inDestP); + } + ProcessVolumeInplace(mVolume, inFramesToProcess, inDestP); +} + + +#endif + diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.h b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.h new file mode 100644 index 0000000..2734c0d --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AUSidetone.h @@ -0,0 +1,88 @@ +/* + * AUSidetone.h + * + * Created by richardp on 11/28/11. + * Copyright 2011 Apple, Inc. All rights reserved. + * + * Does necessary translation between AE2 and CA AU speaker protection + */ + +#ifndef __AUSidetone_h__ +#define __AUSidetone_h__ + +#include + +#include "AudioUnitProperties_AE2.h" +#include "AUBase_AE2.h" + +struct AE2_IIRFilter; +struct AE2_Volume; +struct BiquadDescriptor; + +/** + * AUSidetone implements the sidetone eq and gain. + * + * These values are hard-coded for now. + */ +class AUSidetone : public AUBase_AE2 +{ +public: + static AUSidetone* Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize); + virtual ~AUSidetone(); + + virtual void Process(const void *inSourceP, + void *inDestP, + UInt32 inFramesToProcess); + + // for parameters + virtual OSStatus SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value); + virtual AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID); + // for properties + virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID, uint32_t& outDataSize, bool& outWritable); + virtual OSStatus GetProperty(AudioUnitPropertyID inID, void* outData); + virtual OSStatus SetProperty(AudioUnitPropertyID inID, const void* inData, uint32_t inDataSize); + +private: + AUSidetone(); + bool InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize); + + // some constants + typedef AUBase_AE2 super; + static const size_t kMaxNumBands = 5; + static const float kDefaultSidetoneGain = -32.0; + + // Parameters for the AUNBandEQ unit + // Note that the parameter IDs listed correspond to band 0 (zero) of the unit. The parameter IDs for + // higher bands can be obtained by adding the zero-indexed band number to the corresponding band 0 + // parameter ID up to the number of bands minus one, where the number of bands is described by the + // AUNBandEQ property kAUNBandEQProperty_NumberOfBands. For example, the parameter ID corresponding + // to the filter type of band 4 would be kAUNBandEQParam_FilterType + 3. + enum { + kAUVolume_InDB = 500, + // Global, Boolean, 0 or 1, 1 + kAUNBandEQParam_BypassBand = 1000, + // Global, Indexed, 0->kNumAUNBandEQFilterTypes-1, 0 + kAUNBandEQParam_FilterType = 2000, + // Global, Hz, 20->(SampleRate/2), 1000 + kAUNBandEQParam_Frequency = 3000, + // Global, dB, -96->24, 0 + kAUNBandEQParam_Gain = 4000, + // Global, octaves, 0.05->5.0, 0.5 + kAUNBandEQParam_Bandwidth = 5000 + }; + + uint32_t mSampleRate; + uint32_t mNumChannels; + AE2_IIRFilter *mSidetoneEQ; + AE2_Volume *mVolume; + // to hold the coefficients + uint32_t mNumberBands; + + BiquadDescriptor *mBiquadValues; + + float mVolumeInDB; + bool mSidetoneEQBypass; +}; + +#endif // __AUSidetone_h__ + diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AudioUnitProperties_AE2.h b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AudioUnitProperties_AE2.h new file mode 100644 index 0000000..815c761 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/AudioUnitProperties_AE2.h @@ -0,0 +1,309 @@ +/* + File: AudioUnitProperties_AE2.h + + Contains: Property constants for AudioUnits, stripped down for AE2 + + Copyright: (c) 2010 by Apple, Inc., all rights reserved. + + */ + +#ifndef __AUDIOUNITPROPERTIES_AE2__ +#define __AUDIOUNITPROPERTIES_AE2__ + +#include "CoreAudioTypes_AE2.h" +#include "AUComponent_AE2.h" + +#pragma mark - +#pragma mark Core Implementation +#pragma mark - +/*! + @enum Audio Unit scope types + @abstract The scope IDs for audio units define basic roles and contexts for an audio unit's state. + @discussion Each scope is a discrete context. Apple reserves scope IDs from 0 through 1024. + + @constant kAudioUnitScope_Global The context for audio unit characteristics that apply to the audio unit as a + whole + @constant kAudioUnitScope_Input The context for audio data coming into an audio unit + @constant kAudioUnitScope_Output The context for audio data leaving an audio unit + @constant kAudioUnitScope_Group A context specific to the control scope of parameters (for instance, + MIDI Channels is an example of this scope) + @constant kAudioUnitScope_Part A distinct rendering context. For instance a single timbre in a multi-timbral + instrument, a single loop in a multi looping capable looper unit, etc. + @constant kAudioUnitScope_Layer A context which functions as a layer within a part and allows + grouped control of Cell-scope parameters. + An example is the percussive attack layer for an electric organ instrument + @constant kAudioUnitScope_Note A scope that can be used to apply changes to an individual note. The + elementID used with this scope is the unique note ID returned from + a started note (see MusicDeviceStartNote) + @constant kAudioUnitScope_Cell A scope which represents the finest level of granularity within an AU. + The individual sample zones and envelope generators within a synth are an + example of this. + */ +enum { + kAudioUnitScope_Global = 0, + kAudioUnitScope_Input = 1, + kAudioUnitScope_Output = 2 +}; + +//===================================================================================================================== +#pragma mark - Parameter Definitions + +// assume kAudioUnitParameterUnit_Generic if not found in this enum +/*! + @enum AudioUnitParameterUnit + @constant kAudioUnitParameterUnit_Generic + untyped value generally between 0.0 and 1.0 + @constant kAudioUnitParameterUnit_Indexed + takes an integer value (good for menu selections) + @constant kAudioUnitParameterUnit_Boolean + 0.0 means FALSE, non-zero means TRUE + @constant kAudioUnitParameterUnit_Percent + usually from 0 -> 100, sometimes -50 -> +50 + @constant kAudioUnitParameterUnit_Seconds + absolute or relative time + @constant kAudioUnitParameterUnit_SampleFrames + one sample frame equals (1.0/sampleRate) seconds + @constant kAudioUnitParameterUnit_Phase + -180 to 180 degrees + @constant kAudioUnitParameterUnit_Rate + rate multiplier, for playback speed, etc. (e.g. 2.0 == twice as fast) + @constant kAudioUnitParameterUnit_Hertz + absolute frequency/pitch in cycles/second + @constant kAudioUnitParameterUnit_Cents + unit of relative pitch + @constant kAudioUnitParameterUnit_RelativeSemiTones + useful for coarse detuning + @constant kAudioUnitParameterUnit_MIDINoteNumber + absolute pitch as defined in the MIDI spec (exact freq may depend on tuning table) + @constant kAudioUnitParameterUnit_MIDIController + a generic MIDI controller value from 0 -> 127 + @constant kAudioUnitParameterUnit_Decibels + logarithmic relative gain + @constant kAudioUnitParameterUnit_LinearGain + linear relative gain + @constant kAudioUnitParameterUnit_Degrees + -180 to 180 degrees, similar to phase but more general (good for 3D coord system) + @constant kAudioUnitParameterUnit_EqualPowerCrossfade + 0 -> 100, crossfade mix two sources according to sqrt(x) and sqrt(1.0 - x) + @constant kAudioUnitParameterUnit_MixerFaderCurve1 + 0.0 -> 1.0, pow(x, 3.0) -> linear gain to simulate a reasonable mixer channel fader response + @constant kAudioUnitParameterUnit_Pan + standard left to right mixer pan + @constant kAudioUnitParameterUnit_Meters + distance measured in meters + @constant kAudioUnitParameterUnit_AbsoluteCents + absolute frequency measurement : + if f is freq in hertz then absoluteCents = 1200 * log2(f / 440) + 6900 + @constant kAudioUnitParameterUnit_Octaves + octaves in relative pitch where a value of 1 is equal to 1200 cents + @constant kAudioUnitParameterUnit_BPM + beats per minute, ie tempo + @constant kAudioUnitParameterUnit_Beats + time relative to tempo, i.e., 1.0 at 120 BPM would equal 1/2 a second + @constant kAudioUnitParameterUnit_Milliseconds + parameter is expressed in milliseconds + @constant kAudioUnitParameterUnit_Ratio + for compression, expansion ratio, etc. + @constant kAudioUnitParameterUnit_CustomUnit + this is the parameter unit type for parameters that present a custom unit name + */ +enum +{ + kAudioUnitParameterUnit_Generic = 0, + kAudioUnitParameterUnit_Indexed = 1, + kAudioUnitParameterUnit_Boolean = 2, + kAudioUnitParameterUnit_Percent = 3, + kAudioUnitParameterUnit_Seconds = 4, + kAudioUnitParameterUnit_SampleFrames = 5, + kAudioUnitParameterUnit_Phase = 6, + kAudioUnitParameterUnit_Rate = 7, + kAudioUnitParameterUnit_Hertz = 8, + kAudioUnitParameterUnit_Cents = 9, + kAudioUnitParameterUnit_RelativeSemiTones = 10, + kAudioUnitParameterUnit_MIDINoteNumber = 11, + kAudioUnitParameterUnit_MIDIController = 12, + kAudioUnitParameterUnit_Decibels = 13, + kAudioUnitParameterUnit_LinearGain = 14, + kAudioUnitParameterUnit_Degrees = 15, + kAudioUnitParameterUnit_EqualPowerCrossfade = 16, + kAudioUnitParameterUnit_MixerFaderCurve1 = 17, + kAudioUnitParameterUnit_Pan = 18, + kAudioUnitParameterUnit_Meters = 19, + kAudioUnitParameterUnit_AbsoluteCents = 20, + kAudioUnitParameterUnit_Octaves = 21, + kAudioUnitParameterUnit_BPM = 22, + kAudioUnitParameterUnit_Beats = 23, + kAudioUnitParameterUnit_Milliseconds = 24, + kAudioUnitParameterUnit_Ratio = 25, + kAudioUnitParameterUnit_CustomUnit = 26 +}; +/*! + @typedef AudioUnitParameterUnit + */ +typedef UInt32 AudioUnitParameterUnit; + +/*! + @struct AudioUnitParameterInfo + @field name + UNUSED - set to zero - UTF8 encoded C string (originally). + @field unitName + only valid if kAudioUnitParameterUnit_CustomUnit is set. If kAudioUnitParameterUnit_CustomUnit + is set, this field must contain a valid CFString. + @field clumpID + only valid if kAudioUnitParameterFlag_HasClump + @field cfNameString + only valid if kAudioUnitParameterFlag_HasCFNameString + @field unit + if the "unit" field contains a value not in the enum above, then assume + kAudioUnitParameterUnit_Generic + @field minValue + @field maxValue + @field defaultValue + @field flags + Due to some vagaries about the ways in which Parameter's CFNames have been described, it was + necessary to add a flag: kAudioUnitParameterFlag_CFNameRelease + In normal usage a parameter name is essentially a static object, but sometimes an audio unit will + generate parameter names dynamically.. As these are expected to be CFStrings, in that case + the host should release those names when it is finished with them, but there was no way + to communicate this distinction in behavior. + Thus, if an audio unit will (or could) generate a name dynamically, it should set this flag in + the parameter's info. The host should check for this flag, and if present, release the parameter + name when it is finished with it. + */ +typedef struct AudioUnitParameterInfo +{ + //char name[52]; + //CFStringRef unitName; + UInt32 clumpID; + //CFStringRef cfNameString; + AudioUnitParameterUnit unit; + AudioUnitParameterValue minValue; + AudioUnitParameterValue maxValue; + AudioUnitParameterValue defaultValue; + UInt32 flags; +} AudioUnitParameterInfo; + +/*! + @enum Audio Unit Parameter Flags + @discussion Bit positions 18, 17, and 16 are set aside for display scales. Bit 19 is reserved. + @constant kAudioUnitParameterFlag_CFNameRelease + @constant kAudioUnitParameterFlag_MeterReadOnly + @constant kAudioUnitParameterFlag_DisplayMask + @constant kAudioUnitParameterFlag_DisplaySquareRoot + @constant kAudioUnitParameterFlag_DisplaySquared + @constant kAudioUnitParameterFlag_DisplayCubed + @constant kAudioUnitParameterFlag_DisplayCubeRoot + @constant kAudioUnitParameterFlag_DisplayExponential + @constant kAudioUnitParameterFlag_HasClump + @constant kAudioUnitParameterFlag_ValuesHaveStrings + @constant kAudioUnitParameterFlag_DisplayLogarithmic + @constant kAudioUnitParameterFlag_IsHighResolution + @constant kAudioUnitParameterFlag_NonRealTime + @constant kAudioUnitParameterFlag_CanRamp + @constant kAudioUnitParameterFlag_ExpertMode + @constant kAudioUnitParameterFlag_HasCFNameString + @constant kAudioUnitParameterFlag_IsGlobalMeta + @constant kAudioUnitParameterFlag_IsElementMeta + @constant kAudioUnitParameterFlag_IsReadable + @constant kAudioUnitParameterFlag_IsWritable + */ +enum +{ + kAudioUnitParameterFlag_CFNameRelease = (1L << 4), + kAudioUnitParameterFlag_MeterReadOnly = (1L << 15), + + // bit positions 18,17,16 are set aside for display scales. bit 19 is reserved. + kAudioUnitParameterFlag_DisplayMask = (7L << 16) | (1L << 22), + kAudioUnitParameterFlag_DisplaySquareRoot = (1L << 16), + kAudioUnitParameterFlag_DisplaySquared = (2L << 16), + kAudioUnitParameterFlag_DisplayCubed = (3L << 16), + kAudioUnitParameterFlag_DisplayCubeRoot = (4L << 16), + kAudioUnitParameterFlag_DisplayExponential = (5L << 16), + kAudioUnitParameterFlag_HasClump = (1L << 20), + kAudioUnitParameterFlag_ValuesHaveStrings = (1L << 21), + kAudioUnitParameterFlag_DisplayLogarithmic = (1L << 22), + kAudioUnitParameterFlag_IsHighResolution = (1L << 23), + kAudioUnitParameterFlag_NonRealTime = (1L << 24), + kAudioUnitParameterFlag_CanRamp = (1L << 25), + kAudioUnitParameterFlag_ExpertMode = (1L << 26), + kAudioUnitParameterFlag_HasCFNameString = (1L << 27), + kAudioUnitParameterFlag_IsGlobalMeta = (1L << 28), + kAudioUnitParameterFlag_IsElementMeta = (1L << 29), + kAudioUnitParameterFlag_IsReadable = (1L << 30), + kAudioUnitParameterFlag_IsWritable = (1L << 31) +}; + +typedef struct AUChannelInfo { + SInt16 inChannels; + SInt16 outChannels; +} AUChannelInfo; + +//================================================================================================== + /* + @constant kAUSongbird_SidetoneEQBlockData + @discussion Scope: Global + Value Type: blob + Access: read/write + + A property to get/set the biquad coefficients of the AE2 SidetoneEQ block as an + array of AU_BiquadFilterDescription, sized to be the number of stages. +*/ + +enum { + kAUSongbird_SidetoneEQBlockData = 10000, + kAUSongbird_SidetoneState = 10001 +}; + + +/*! + @struct AU_BiquadFilter + @field mBypass + Boolean to indicate if biquad is bypassed; + @field b0 + @field b1 + @field b2 + @field a1 + @field a2 + Fields for biquad coefficients values; + */ + +typedef struct AU_BiquadFilter { + UInt32 mBypass; + Float64 b0, b1, b2, a1, a2; +} AU_BiquadFilter; + +/*! + @struct AU_BiquadFilterDescription + kAUSongbird_SidetoneEQBlockData data structure + @field mBypass + Boolean to indicate if all biquads are bypassed; + @field mNumberFilters + Number of active filters in the sidetone eq; + @field mFilters + variable length sized as mNumberFilters AU_BiquadFilter structures; + */ + +typedef struct AU_BiquadFilterDescription { + UInt32 mBypass; + UInt32 mNumberFilters; + AU_BiquadFilter mFilters[1]; // this is a variable length array of mNumberFilters elements +} AU_BiquadFilterDescription; + +/*! + @struct AU_SidetoneState + kAUSongbird_SidetoneState data structure + @field mVolume + Gain for Sidetone; + @field mFilterDescription + Filter description for sidetone; + */ + +typedef struct AU_SidetoneState { + bool mBypass; + Float32 mVolume; + AU_BiquadFilterDescription mFilterDescription; +} AU_SidetoneState; + + + +#endif diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/CoreAudioTypes_AE2.h b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/CoreAudioTypes_AE2.h new file mode 100644 index 0000000..beee66e --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/CoreAudioTypes_AE2.h @@ -0,0 +1,248 @@ +/* + * CoreAudioTypes_AE2.h + * Stripped down version of CoreAudioTypes just for what AE2 needs + * + * Copyright 2010 Apple Computer. All rights reserved. + * + */ + +#ifndef __COREAUDIOTYPES_AE2__ +#define __COREAUDIOTYPES_AE2__ + +#define CA_PREFER_FIXED_POINT 1 + +#include + +typedef double Float64; +typedef float Float32; + +typedef SInt32 OSStatus; +typedef SInt32 ComponentResult; + +typedef SInt16 AudioSampleType; +typedef SInt32 AudioUnitSampleType; + +//XXX find the place where this is really defined +enum { + noErr = 0 +}; + +/*! + @struct AudioStreamBasicDescription + @abstract This structure encapsulates all the information for describing the basic + format properties of a stream of audio data. + @discussion This structure is sufficient to describe any constant bit rate format that has + channels that are the same size. Extensions are required for variable bit rate + data and for constant bit rate data where the channels have unequal sizes. + However, where applicable, the appropriate fields will be filled out correctly + for these kinds of formats (the extra data is provided via separate properties). + In all fields, a value of 0 indicates that the field is either unknown, not + applicable or otherwise is inapproprate for the format and should be ignored. + Note that 0 is still a valid value for most formats in the mFormatFlags field. + + In audio data a frame is one sample across all channels. In non-interleaved + audio, the per frame fields identify one channel. In interleaved audio, the per + frame fields identify the set of n channels. In uncompressed audio, a Packet is + one frame, (mFramesPerPacket == 1). In compressed audio, a Packet is an + indivisible chunk of compressed data, for example an AAC packet will contain + 1024 sample frames. + @field mSampleRate + The number of sample frames per second of the data in the stream. + @field mFormatID + A four char code indicating the general kind of data in the stream. + @field mFormatFlags + Flags specific to each format. + @field mBytesPerPacket + The number of bytes in a packet of data. + @field mFramesPerPacket + The number of sample frames in each packet of data. + @field mBytesPerFrame + The number of bytes in a single sample frame of data. + @field mChannelsPerFrame + The number of channels in each frame of data. + @field mBitsPerChannel + The number of bits of sample data for each channel in a frame of data. + @field mReserved + Pads the structure out to force an even 8 byte alignment. +*/ +struct AudioStreamBasicDescription +{ + Float64 mSampleRate; + UInt32 mFormatID; + UInt32 mFormatFlags; + UInt32 mBytesPerPacket; + UInt32 mFramesPerPacket; + UInt32 mBytesPerFrame; + UInt32 mChannelsPerFrame; + UInt32 mBitsPerChannel; + UInt32 mReserved; +}; +typedef struct AudioStreamBasicDescription AudioStreamBasicDescription; + + +// SMPTETime is also defined in the CoreVideo headers. +#if !defined(__SMPTETime__) +#define __SMPTETime__ + +/*! + @struct SMPTETime + @abstract A structure for holding a SMPTE time. + @field mSubframes + The number of subframes in the full message. + @field mSubframeDivisor + The number of subframes per frame (typically 80). + @field mCounter + The total number of messages received. + @field mType + The kind of SMPTE time using the SMPTE time type constants. + @field mFlags + A set of flags that indicate the SMPTE state. + @field mHours + The number of hours in the full message. + @field mMinutes + The number of minutes in the full message. + @field mSeconds + The number of seconds in the full message. + @field mFrames + The number of frames in the full message. + */ +struct SMPTETime +{ + SInt16 mSubframes; + SInt16 mSubframeDivisor; + UInt32 mCounter; + UInt32 mType; + UInt32 mFlags; + SInt16 mHours; + SInt16 mMinutes; + SInt16 mSeconds; + SInt16 mFrames; +}; +typedef struct SMPTETime SMPTETime; + +/*! + @enum SMPTE Time Types + @abstract Constants that describe the type of SMPTE time. + @constant kSMPTETimeType24 + 24 Frame + @constant kSMPTETimeType25 + 25 Frame + @constant kSMPTETimeType30Drop + 30 Drop Frame + @constant kSMPTETimeType30 + 30 Frame + @constant kSMPTETimeType2997 + 29.97 Frame + @constant kSMPTETimeType2997Drop + 29.97 Drop Frame + @constant kSMPTETimeType60 + 60 Frame + @constant kSMPTETimeType5994 + 59.94 Frame + @constant kSMPTETimeType60Drop + 60 Drop Frame + @constant kSMPTETimeType5994Drop + 59.94 Drop Frame + @constant kSMPTETimeType50 + 50 Frame + @constant kSMPTETimeType2398 + 23.98 Frame + */ +enum +{ + kSMPTETimeType24 = 0, + kSMPTETimeType25 = 1, + kSMPTETimeType30Drop = 2, + kSMPTETimeType30 = 3, + kSMPTETimeType2997 = 4, + kSMPTETimeType2997Drop = 5, + kSMPTETimeType60 = 6, + kSMPTETimeType5994 = 7, + kSMPTETimeType60Drop = 8, + kSMPTETimeType5994Drop = 9, + kSMPTETimeType50 = 10, + kSMPTETimeType2398 = 11 +}; + +/*! + @enum SMPTE State Flags + @abstract Flags that describe the SMPTE time state. + @constant kSMPTETimeValid + The full time is valid. + @constant kSMPTETimeRunning + Time is running. + */ +enum +{ + kSMPTETimeValid = (1 << 0), + kSMPTETimeRunning = (1 << 1) +}; + +#endif + +/*! + @struct AudioTimeStamp + @abstract A structure that holds different representations of the same point in time. + @field mSampleTime + The absolute sample frame time. + @field mHostTime + The host machine's time base, mach_absolute_time. + @field mRateScalar + The ratio of actual host ticks per sample frame to the nominal host ticks + per sample frame. + @field mWordClockTime + The word clock time. + @field mSMPTETime + The SMPTE time. + @field mFlags + A set of flags indicating which representations of the time are valid. + @field mReserved + Pads the structure out to force an even 8 byte alignment. + */ +struct AudioTimeStamp +{ + Float64 mSampleTime; + UInt64 mHostTime; + Float64 mRateScalar; + UInt64 mWordClockTime; + SMPTETime mSMPTETime; + UInt32 mFlags; + UInt32 mReserved; +}; +typedef struct AudioTimeStamp AudioTimeStamp; + +/*! + @enum AudioTimeStamp Flags + @abstract The flags that indicate which fields in an AudioTimeStamp structure are valid. + @constant kAudioTimeStampSampleTimeValid + The sample frame time is valid. + @constant kAudioTimeStampHostTimeValid + The host time is valid. + @constant kAudioTimeStampRateScalarValid + The rate scalar is valid. + @constant kAudioTimeStampWordClockTimeValid + The word clock time is valid. + @constant kAudioTimeStampSMPTETimeValid + The SMPTE time is valid. + */ +enum +{ + kAudioTimeStampSampleTimeValid = (1 << 0), + kAudioTimeStampHostTimeValid = (1 << 1), + kAudioTimeStampRateScalarValid = (1 << 2), + kAudioTimeStampWordClockTimeValid = (1 << 3), + kAudioTimeStampSMPTETimeValid = (1 << 4) +}; + +/*! + @enum Commonly Used Combinations of AudioTimeStamp Flags + @abstract Some commonly used combinations of AudioTimeStamp flags. + @constant kAudioTimeStampSampleHostTimeValid + The sample frame time and the host time are valid. + */ +enum +{ + kAudioTimeStampSampleHostTimeValid = (kAudioTimeStampSampleTimeValid | kAudioTimeStampHostTimeValid) +}; + +#endif diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.cpp b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.cpp new file mode 100644 index 0000000..db2b58d --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "iop_au_interface.h" +#include "AUSidetone.h" +#include "AUNull.h" +#include + +extern "C" audio_unit_t Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize) +{ +#if USE_SIDETONE + AUBase_AE2 *This = AUSidetone::Create_AUSidetone(sampleRate, numChannels, sampleSize); + return (audio_unit_t)This; +#else + return NULL; +#endif +} + +extern "C" audio_unit_t Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize) +{ + AUBase_AE2 *This = AUNull::Create_AUNull(sampleRate, numChannels, sampleSize); + return (audio_unit_t)This; +} + +extern "C" void Destroy_AudioUnit(audio_unit_t au) +{ + AUBase_AE2 *This = (AUBase_AE2*)au; + delete This; +} + +extern "C" int32_t AudioUnit_GetParameter(audio_unit_t au, uint32_t parameter, float *parameterValue) +{ + if (!au) + { + return -1; + } + AUBase_AE2 *This = (AUBase_AE2*)au; + *parameterValue = This->GetParameter((AudioUnitParameterID)parameter); + return 0; +} + +extern "C" int32_t AudioUnit_SetParameter(audio_unit_t au, uint32_t parameter, float parameterValue) +{ + if (!au) + { + return -1; + } + AUBase_AE2 *This = (AUBase_AE2*)au; + return This->SetParameter((AudioUnitParameterID)parameter, (AudioUnitParameterValue)parameterValue); +} + +extern "C" int32_t AudioUnit_GetPropertyInfo(audio_unit_t au, uint32_t propID, uint32_t *outSize, bool *outWritable) +{ + if (!au) + { + return -1; + } + AUBase_AE2 *This = (AUBase_AE2*)au; + return This->GetPropertyInfo(static_cast(propID), *outSize, *outWritable); +} + +extern "C" int32_t AudioUnit_GetProperty(audio_unit_t au, uint32_t propID, void *outData, uint32_t *ioSize) +{ + if (!au) + { + return -1; + } + uint32_t propSize; + bool propWritable; + int32_t result = AudioUnit_GetPropertyInfo(au, propID, &propSize, &propWritable); + if (result) + { + return result; + } + if (propSize > *ioSize) + { + return -1; + } + *ioSize = propSize; + AUBase_AE2 *This = (AUBase_AE2*)au; + return This->GetProperty(static_cast(propID), outData); +} + +extern "C" int32_t AudioUnit_SetProperty(audio_unit_t au, uint32_t propID, const void *inData, uint32_t inSize) +{ + if (!au) + { + return -1; + } + uint32_t propSize; + bool propWritable; + int32_t result = AudioUnit_GetPropertyInfo(au, propID, &propSize, &propWritable); + if (result) + { + return result; + } + if ((!propWritable)) + { + return -1; + } + AUBase_AE2 *This = (AUBase_AE2*)au; + return This->SetProperty(static_cast(propID), inData, inSize); +} + +extern "C" void AudioUnit_Process(audio_unit_t au, const void *inSourceP, void *inDestP, uint32_t inFramesToProcess) +{ + if (!au) + { + return ; + } + AUBase_AE2 *This = (AUBase_AE2*)au; + This->Process(inSourceP, inDestP, inFramesToProcess); +} + diff --git a/apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.h b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.h new file mode 100644 index 0000000..754dad2 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/AudioUnits/iop_au_interface.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _IOP_AU_INTERFACE_H_ +#define _IOP_AU_INTERFACE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef void * audio_unit_t; + +audio_unit_t Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize); +audio_unit_t Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize); + +void Destroy_AudioUnit(audio_unit_t au); + +// parameters are single values that can be adjusted +int32_t AudioUnit_GetParameter(audio_unit_t au, uint32_t parameter, float *parameterValue); +int32_t AudioUnit_SetParameter(audio_unit_t au, uint32_t parameter, float parameterValue); + +// properties are blocks of data that can be adjusted, usually a private setting between user and unit +int32_t AudioUnit_GetPropertyInfo(audio_unit_t au, uint32_t propID, uint32_t *outSize, bool *outWritable); +int32_t AudioUnit_GetProperty(audio_unit_t au, uint32_t propID, void *outData, uint32_t *ioSize); +int32_t AudioUnit_SetProperty(audio_unit_t au, uint32_t propID, const void *inData, uint32_t inSize); + +void AudioUnit_Process(audio_unit_t au, const void *inSourceP, void *inDestP, uint32_t inFramesToProcess); + + +#ifdef __cplusplus +} +#endif + +#endif // _IOP_AU_INTERFACE_H_ diff --git a/apps/EmbeddedIOP/function_audiodsp/debug_tap.c b/apps/EmbeddedIOP/function_audiodsp/debug_tap.c new file mode 100644 index 0000000..c97b9aa --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/debug_tap.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "debug_tap.h" +#include "timestamper.h" + +#include +#include +#include +#include +#include + +#include "iop_au_interface.h" + + +typedef struct +{ + uint8_t *IOBufferBegin; + uint8_t *IOBufferEnd; + uint8_t *IOBuffer; +} internal_debug_tap_t; + +debug_tap_t create_debug_tap(uint8_t *inIOBegin, uint8_t *inIOEnd, uint8_t *inIO) +{ + internal_debug_tap_t *This = (internal_debug_tap_t*)malloc(sizeof(debug_tap_t)); + if (This) + { + This->IOBufferBegin = inIOBegin; + This->IOBufferEnd = inIOEnd; + This->IOBuffer = inIO; + } + return This; +} + +void destroy_debug_tap(debug_tap_t tap) +{ + free(tap); +} + +static void clean_cache(void *addr, size_t size) +{ + // the onus is on the caller to make sure the cache is aligned + void* lineBase = (void*)((uint32_t)addr & ~(CPU_CACHELINE_SIZE-1)); + size_t sizeToDo = ((((uint32_t)addr & (CPU_CACHELINE_SIZE-1)) + size)/CPU_CACHELINE_SIZE + 1) * CPU_CACHELINE_SIZE; + platform_cache_operation(CACHE_CLEAN, lineBase, sizeToDo); +} + +static void invalidate_cache(void *addr, size_t size) +{ + void* lineBase = (void*)((uint32_t)addr & ~(CPU_CACHELINE_SIZE-1)); + size_t sizeToDo = ((((uint32_t)addr & (CPU_CACHELINE_SIZE-1)) + size)/CPU_CACHELINE_SIZE + 1) * CPU_CACHELINE_SIZE; + platform_cache_operation(CACHE_INVALIDATE, lineBase, sizeToDo); +} + +static size_t min(size_t a, size_t b) { return (a < b) ? a : b; } + +size_t send_to_tap(debug_tap_t tap, const uint8_t* src, uint32_t sizeInBytes) +{ + internal_debug_tap_t *This = (internal_debug_tap_t*)tap; + size_t result = 0; + + // don't transfer anything to user if sizeInBytes is larger than IOBuffer: + if (sizeInBytes > (uint32_t)(This->IOBufferEnd - This->IOBufferBegin)) + return result; + + // make sure we don't overflow the IOBuffer + size_t dataToSend = min(This->IOBufferEnd - This->IOBuffer, sizeInBytes); + memcpy(This->IOBuffer, src, dataToSend); + clean_cache(This->IOBuffer, dataToSend); + This->IOBuffer += dataToSend; + src += dataToSend; + if (This->IOBuffer >= This->IOBufferEnd) + { + // if we've wrapped around, send the size of the IOBuffer to the caller + This->IOBuffer = This->IOBufferBegin; + result = This->IOBufferEnd - This->IOBufferBegin; + } + + // now that we've sent the data, how much is left + dataToSend = sizeInBytes - dataToSend; + // if there is anything left, send it + if (dataToSend) + { + memcpy(This->IOBuffer, src, dataToSend); + clean_cache(This->IOBuffer, sizeInBytes); + This->IOBuffer += dataToSend; + } + return result; +} + + +size_t get_from_tap(debug_tap_t tap, uint8_t* dst, uint32_t sizeInBytes) +{ + internal_debug_tap_t *This = (internal_debug_tap_t*)tap; + size_t result = 0; + + // don't transfer anything to user if sizeInBytes is larger than IOBuffer: + if (sizeInBytes > (uint32_t)(This->IOBufferEnd - This->IOBufferBegin)) + return result; + + // make sure we don't overflow the IOBuffer + size_t dataToGet = min(This->IOBufferEnd - This->IOBuffer, sizeInBytes); + invalidate_cache(This->IOBuffer, dataToGet); + memcpy(dst, This->IOBuffer, dataToGet); + This->IOBuffer += dataToGet; + dst += dataToGet; + if (This->IOBuffer >= This->IOBufferEnd) + { + // if we've wrapped around, send the size of the IOBuffer to the caller + This->IOBuffer = This->IOBufferBegin; + result = This->IOBufferEnd - This->IOBufferBegin; + } + + // now that we've got the data, how much is left + dataToGet = sizeInBytes - dataToGet; + // if there is anything left, get it + if (dataToGet) + { + invalidate_cache(This->IOBuffer, dataToGet); + memcpy(dst, This->IOBuffer, dataToGet); + This->IOBuffer += dataToGet; + } + return result; +} + + diff --git a/apps/EmbeddedIOP/function_audiodsp/debug_tap.h b/apps/EmbeddedIOP/function_audiodsp/debug_tap.h new file mode 100644 index 0000000..b9075f3 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/debug_tap.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _DEBUG_TAP_H_ +#define _DEBUG_TAP_H_ + +#include + +/* + * A debug_tap is a way of tapping off or tapping in an audio signal from + * user space. Pass the pointer to the beginning, end, and start to create + * a tap. You send or get data from a tap, which causes the write or read + * head to progress around the buffer circularly. When the process wraps, + * the send or get call returns the total number of bytes sent, otherwise + * it returns 0. + */ + +typedef void * debug_tap_t; + +debug_tap_t create_debug_tap(uint8_t *inIOBegin, uint8_t *inIOEnd, uint8_t *inIO); + +void destroy_debug_tap(debug_tap_t tap); + +// return value is nonzero on calls where we wrap IO buffer. Returned +// value indicates number bytes to give to "timestamp" function +size_t send_to_tap(debug_tap_t tap, const uint8_t* src, uint32_t sizeInBytes); +size_t get_from_tap(debug_tap_t tap, uint8_t* dst, uint32_t sizeInBytes); + +#endif // _DEBUG_TAP_H_ + diff --git a/apps/EmbeddedIOP/function_audiodsp/iop_audiodsp.c b/apps/EmbeddedIOP/function_audiodsp/iop_audiodsp.c new file mode 100644 index 0000000..390cadd --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/iop_audiodsp.c @@ -0,0 +1,893 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "clock_stepping.h" + +#define USE_DMA 0 + +#include "iop_audiodsp_protocol.h" +#include "iop_au_interface.h" +#include "loopback_process.h" +#include "timestamper.h" +#include "debug_tap.h" +#include "ae2_mca.h" +#if USE_DMA +#include "ae2_i2s.h" +#include "ae2_dma.h" +#else +#include "loopback_device.h" +#endif + + +static const uint32_t kDefaultSampleRate = 8000; +static const uint32_t kMaxSampleRate = 48000; +// We configure for 0.004 sec of latency. +static const uint32_t kDefaultLatencyInUS = 4000; +static const uint32_t kMaxLatencyInUS = 40000; +// Describing the MCA data format. +static const uint32_t kDefaultNumChannels = 1; +static const uint32_t kMaxNumChannels = 2; +#if USE_DMA +static const uint32_t kValidChannelBitmask = 1; +#endif +static const uint32_t kDefaultSampleSize = 2; + +static const size_t kDefaultDMABufferSize = 0x300; + +static const AudioDevice_Index kDataDevice = kMCA_0; +#if USE_DMA +static const uint32_t kDataReceivePort = rMCA0_RXDATA; +static const uint32_t kDataTransmitPort = rMCA0_TXDATA; +#endif + +static bool audiodsp_message_process(void); + +static int iop_audiodsp_task(void *cfg); +static void iop_audiodsp_sleep(int mode); + +IOP_FUNCTION(audiodsp, iop_audiodsp_task, 8*1024, AUDIODSP_CONTROL_CHANNEL); +IOP_SLEEP_HOOK(audiodsp, iop_audiodsp_sleep); + +static int audiodsp_channel; + +#if USE_DMA +static dma_object_t s_input_dma = NULL; +static dma_object_t s_output_dma = NULL; +static void audiodevice_dma_int_err_handler(void *arg); +static void audiodevice_dma_int_handler(void *arg); + +static const size_t kNumDMABuffers = 4; +static int16_t *sBuffer[kNumDMABuffers]; +static size_t sCurrentProcessBufferIndex; +static DMALinkedListItem *sLLIDMAInput[kNumDMABuffers], *sLLIDMAOutput[kNumDMABuffers]; +#endif +#if !USE_DMA +static loopback_device_t s_loopback_device = NULL; +#endif // USE_DMA + +// Loopback processing "globals" +static audio_unit_t s_loopback_au = NULL; + +// Audio Unit biquad property. +static void* s_loopback_au_state_property = NULL; +static uint32_t s_loopback_au_state_property_size = 0; +// forward declare here. Make sure to change this if id changes +static const uint32_t k_loopback_au_state_property_id = 10001; + +static loopback_process_t s_loopback_process = NULL; +static debug_tap_t sInputTap = NULL; +static debug_tap_t sOutputTap = NULL; + +// forward declaration: +audio_unit_t Create_Loopback_AU(uint32_t sampleRate, uint32_t channels, uint32_t framesToProcess); + +/*** + * IMPORTANT! + * We assume that all the SRAM allocations will total less than 0x1000. + * Adjust the SRAM Heap in memmap.h if this assumption changes. + */ +static uint32_t sSRAMMallocOffset = 0; +#ifdef AUDIO_SRAM_RESERVE +static const uint32_t kSRAMMallocMax = AUDIO_SRAM_RESERVE; +#else /* !AUDIO_SRAM_RESERVE */ +static const uint32_t kSRAMMallocMax = (uint32_t)-1; +#endif /* AUDIO_SRAM_RESERVE */ + +void* mallocFromSRAM(uint32_t byteSize) +{ + //Make sure its a 4-byte aligned allocation (for DMA xfers) + byteSize = (byteSize + 3) / 4; + byteSize *= 4; + + //AUDIO_BASE_ADDR is the start of SRAM in AE2 + void *ptr = (void*)(AUDIO_BASE_ADDR + sSRAMMallocOffset); + sSRAMMallocOffset += byteSize; + + if (sSRAMMallocOffset > kSRAMMallocMax) + panic("mallocFromSRAM beyond limit"); + + memset(ptr, 0, byteSize); + + return ptr; +} + +#if USE_DMA +static bool sDMABuffersInitialized = false; +void +initialize_dma_buffers(void) +{ + if (!sDMABuffersInitialized) + { + for(uint32_t i = 0; i < kNumDMABuffers; i++) + { + sLLIDMAInput[i] = (DMALinkedListItem *)mallocFromSRAM(sizeof(DMALinkedListItem)); + sLLIDMAOutput[i] = (DMALinkedListItem *)mallocFromSRAM(sizeof(DMALinkedListItem)); + sBuffer[i] = (int16_t *)mallocFromSRAM(kDefaultDMABufferSize); + } + + //Setup input chain for infinite quad-buffer looping, control setup handled in startDMA + for(uint32_t i = 0; i < kNumDMABuffers; i++) + { + // RX goes into buffer 2 on start, so we start the chain on 3 + sLLIDMAInput[i]->destination = (uint32_t)sBuffer[(i+3)%kNumDMABuffers]; + sLLIDMAInput[i]->next = sLLIDMAInput[(i+1)%kNumDMABuffers]; + sLLIDMAInput[i]->source = kDataReceivePort; + + // TX goes from buffer 0 on start, so we start the chain on 1 + sLLIDMAOutput[i]->source = (uint32_t)sBuffer[(i+1)%kNumDMABuffers]; + sLLIDMAOutput[i]->next = sLLIDMAOutput[(i+1)%kNumDMABuffers]; + sLLIDMAOutput[i]->destination = kDataTransmitPort; + } + sDMABuffersInitialized = true; + } +} + +void +reset_dma_buffers(void) +{ + for(uint32_t i = 0; i < kNumDMABuffers; i++) + { + memset(sBuffer[i], 0, kDefaultDMABufferSize); + } + sCurrentProcessBufferIndex = 1; +} +#endif + +static int +iop_audiodsp_task(void *cfg) +{ + struct iop_channel_config *channel = (struct iop_channel_config *)cfg; + struct task_event* audiodsp_message_event = (struct task_event*) malloc(sizeof(struct task_event)); + + dprintf(DEBUG_SPEW, "@@ AudioDSP task starting\n"); + + check(kIOPAUDIODSP_COMMAND_SIZE == sizeof(IOPAUDIODSP_Command)); + + /* establish the host communications channel */ + event_init(audiodsp_message_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dprintf(DEBUG_SPEW, "** opening audiodsp channel\n"); + audiodsp_channel = qwi_instantiate_channel("audio command", + QWI_ROLE_CONSUMER, + channel->ring_size, + (void *)mem_static_map_cached(channel->ring_base), + (qwi_channel_hook)event_signal, + audiodsp_message_event); + +#if WITH_VFP && !WITH_VFP_ALWAYS_ON + /* Little doubt we'll need VFP/Neon */ + arch_task_fp_enable(true); +#endif + + // create a audio unit if one does not exist + if (!s_loopback_au) + { + dprintf(DEBUG_INFO, "creating loopback\n"); + s_loopback_au = Create_Loopback_AU(kDefaultSampleRate, kDefaultNumChannels, kDefaultSampleSize); + } + + for (;;) { + dprintf(DEBUG_SPEW, "@@ waiting for message on audiodsp channel\n"); + while (audiodsp_message_process()) { + // eat all available messages + } + event_wait(audiodsp_message_event); + } + + return(0); +} + + +audio_unit_t Create_Loopback_AU(uint32_t sampleRate, uint32_t channels, uint32_t framesToProcess) +{ + audio_unit_t loopback_au = NULL; + dprintf(DEBUG_INFO, "creating loopback\n"); +#if USE_SIDETONE + loopback_au = Create_AUSidetone(sampleRate, channels, kDefaultSampleSize); +#else + loopback_au = Create_AUNull(sampleRate, channels, kDefaultSampleSize); +#endif + if (loopback_au && s_loopback_au_state_property && s_loopback_au_state_property_size) + { + // if we had a previous property + uint32_t propSize = s_loopback_au_state_property_size; + bool propWritable = true; + if (/*noErr*/0 == AudioUnit_GetPropertyInfo(loopback_au, k_loopback_au_state_property_id, &propSize, &propWritable)) + { + if (propWritable && propSize == s_loopback_au_state_property_size) + { + dprintf(DEBUG_INFO, "Restoring previous SidetoneEQ values\n"); + if (/*noErr*/0 != AudioUnit_SetProperty(loopback_au, k_loopback_au_state_property_id, s_loopback_au_state_property, s_loopback_au_state_property_size)) + { + dprintf(DEBUG_INFO, "Warning, could not restore previous SidetoneEQ values\n"); + // now what? Destroy the AU and start over again + Destroy_AudioUnit(loopback_au); + loopback_au = NULL; +#if USE_SIDETONE + loopback_au = Create_AUSidetone(sampleRate, channels, kDefaultSampleSize); +#else + loopback_au = Create_AUNull(sampleRate, channels, kDefaultSampleSize); +#endif + } + } + } + } + return loopback_au; +} + + +void Destroy_Loopback_AU(audio_unit_t loopback_au) +{ + if (loopback_au) + { + uint32_t propSize = s_loopback_au_state_property_size; + bool propWritable = true; + if (/*noErr*/0 == AudioUnit_GetPropertyInfo(loopback_au, k_loopback_au_state_property_id, &propSize, &propWritable)) + { + // clear the old property block if it won't fit + if (s_loopback_au_state_property && s_loopback_au_state_property_size != propSize) + { + free(s_loopback_au_state_property); + s_loopback_au_state_property = NULL; + s_loopback_au_state_property_size = 0; + } + // if we don't have somewhere to write the properties, create it: + if (!s_loopback_au_state_property && (0 != propSize)) + { + s_loopback_au_state_property = malloc(propSize); + s_loopback_au_state_property_size = propSize; + } + // if we do have somewhere to write it, save off what we have + if (s_loopback_au_state_property) + { + dprintf(DEBUG_INFO, "Saving SidetoneEQ values\n"); + if (/*noErr*/0 != AudioUnit_GetProperty(loopback_au, k_loopback_au_state_property_id, s_loopback_au_state_property, &s_loopback_au_state_property_size)) + { + dprintf(DEBUG_INFO, "Warning, could not save SidetoneEQ values\n"); + // for whatever reason, we didn't save the property. free it so we don't try to restore it + free(s_loopback_au_state_property); + s_loopback_au_state_property = NULL; + s_loopback_au_state_property_size = 0; + } + } + } + Destroy_AudioUnit(loopback_au); + loopback_au = NULL; + } +} + + +#if USE_DMA +// Destroy the loopback processing and AU. Assumes that loopback is not running +bool Destroy_Loopback_Processing() +{ + if (s_loopback_process) + { + destroy_loopback_process(s_loopback_process); + s_loopback_process = NULL; + } + if (s_loopback_au) + { + Destroy_Loopback_AU(s_loopback_au); + s_loopback_au = NULL; + } + return true; +} + +// Creates the loopback processing and AU. Assumes that loopback is not running +// will always destroy any existing loopbacks +bool Create_Loopback_Processing(uint32_t sampleRate, uint32_t channels, uint32_t framesToProcess) +{ + Destroy_Loopback_Processing(); + // initialize the loopback processing. It will be enabled later + // create a audio unit if one does not exist + if (!s_loopback_au) + { + dprintf(DEBUG_INFO, "creating loopback\n"); + s_loopback_au = Create_Loopback_AU(sampleRate, channels, kDefaultSampleSize); + } + dprintf(DEBUG_INFO, "loopback is %p\n", s_loopback_au); + // if we have an audio unit, create a loopback proces + if (s_loopback_au && !s_loopback_process) + { + dprintf(DEBUG_INFO, "creating loopback process\n"); + s_loopback_process = create_loopback_process(s_loopback_au, framesToProcess, channels, kDefaultSampleSize, kValidChannelBitmask); + } + dprintf(DEBUG_INFO, "loopback process is %p\n", s_loopback_process); + dprintf(DEBUG_INFO, "free mem after %d\n", heap_get_free_mem()); + + if (s_loopback_process) + { + return true; + } + return false; +} +#endif + +static bool s_loopback_enabled = false; +// return true if loop processing stopped +bool Stop_Loopback_Processing() +{ + // if loopback processing not running, done + if(!s_loopback_enabled) + { + return !s_loopback_enabled; + } +#if USE_DMA + // log any sort of errors encountered + if (s_input_dma || s_output_dma) + { + for (uint32_t i = kFrameError; i < kError_last; ++i) + { + // from Alexei: + // Ignore the frame errors. They're not causing + // interrupts and they are expected (because L81 + // masters BCLK at 12MHz always, which is more than the + // exact number of bits specified in the MCA config; + // unfortunately, there isn't a way to configure MCA to + // say "give me a frame error if there are fewer bits, + // but not if there are more", which is what you'd + // want.) + if (kFrameError == i) + { + continue; + } + + uint32_t error_count = ((s_input_dma) ? getErrorCount(s_input_dma, i) : 0) + ((s_output_dma) ? getErrorCount(s_output_dma, i) : 0); + if (error_count) + { + dprintf(DEBUG_CRITICAL, "DMA encountered %d %s error%s!\n", error_count, kErrorTypeStr[i], error_count > 1 ? "s" : ""); + } + } + } + dprintf(DEBUG_INFO, "Going to stop the DMA\n"); + if (s_input_dma) + { + destroy_dma_object(s_input_dma); + s_input_dma = NULL; + } + if (s_output_dma) + { + destroy_dma_object(s_output_dma); + s_output_dma = NULL; + } + dprintf(DEBUG_CRITICAL, "Stopped the DMA\n"); +#else + // log any sort of errors encountered + if (s_loopback_device) + { + for (uint32_t i = kFrameError; i < kError_last; ++i) + { + // from Alexei: + // Ignore the frame errors. They're not causing + // interrupts and they are expected (because L81 + // masters BCLK at 12MHz always, which is more than the + // exact number of bits specified in the MCA config; + // unfortunately, there isn't a way to configure MCA to + // say "give me a frame error if there are fewer bits, + // but not if there are more", which is what you'd + // want.) + if (kFrameError == i) + { + continue; + } + + uint32_t error_count = getErrorCount(s_loopback_device, i); + if (error_count) + { + dprintf(DEBUG_CRITICAL, "loopback encountered %d %s error%s!\n", error_count, kErrorTypeStr[i], error_count > 1 ? "s" : ""); + } + } + } + dprintf(DEBUG_INFO, "Going to stop the loopback\n"); + if (s_loopback_device) + { + destroy_loopback_device(s_loopback_device); + s_loopback_device = NULL; + } + dprintf(DEBUG_CRITICAL, "Stopped the loopback\n"); +#endif + + SetClockState(kClockRequestLoopback, kClockValueLow); + + s_loopback_enabled = false; + return !s_loopback_enabled; +} + + +// return true if loopback processing started +bool Start_Loopback_Processing(uint32_t sampleRate, uint32_t channels, uint32_t framesToProcess) +{ + dprintf(DEBUG_INFO, "Start_Loopback_Processing(sampleRate %d, channels %d, framesToProcess %d\n", sampleRate, channels, framesToProcess); + if (!Stop_Loopback_Processing()) + { + dprintf(DEBUG_CRITICAL, "Could not stop loopback\n"); + return false; + } + + // if loopback processing already running, done + if (s_loopback_enabled) + { + return s_loopback_enabled; + } + + if (sampleRate > 32000) + { + dprintf(DEBUG_INFO, "Increasing clock rate for loopback\n"); + SetClockState(kClockRequestLoopback, kClockValueHigh); + } + +#if USE_DMA + // create the loopback proessing with this sample rate + if (Create_Loopback_Processing(sampleRate, channels, framesToProcess) && s_loopback_process) + { + dprintf(DEBUG_INFO, "starting up DMA\n"); + initialize_dma_buffers(); + + reset_dma_buffers(); + if (s_input_dma) + { + destroy_dma_object(s_input_dma); + s_input_dma = NULL; + } + s_input_dma = create_dma_object(sBuffer[2], kDataDevice, sLLIDMAInput[0], kDirectionIn, framesToProcess*channels*kDefaultSampleSize); + if (s_output_dma) + { + destroy_dma_object(s_output_dma); + s_output_dma = NULL; + } + s_output_dma = create_dma_object(sBuffer[0], kDataDevice, sLLIDMAOutput[0], kDirectionOut, framesToProcess*channels*kDefaultSampleSize); + if (s_input_dma && s_output_dma) + { + setupInterruptHandler(s_input_dma, audiodevice_dma_int_handler, s_loopback_process); + setupErrorHandler(s_input_dma, audiodevice_dma_int_err_handler, NULL); + setupErrorHandler(s_output_dma, audiodevice_dma_int_err_handler, NULL); + startDMAObject(s_input_dma); + startDMAObject(s_output_dma); + s_loopback_enabled = true; + } + else + { + dprintf(DEBUG_CRITICAL, "could not create DMA objects!\n"); + } + } +#else + if (s_loopback_au) + { + Destroy_Loopback_AU(s_loopback_au); + s_loopback_au = NULL; + } + dprintf(DEBUG_INFO, "creating loopback\n"); + s_loopback_au = Create_Loopback_AU(sampleRate, channels, kDefaultSampleSize); + // create the loopback proessing with this sample rate + if (s_loopback_au) + { + dprintf(DEBUG_INFO, "starting up loopback_device\n"); + if (s_loopback_device) + { + destroy_loopback_device(s_loopback_device); + s_loopback_device = NULL; + } + s_loopback_device = create_loopback_device(kDataDevice, s_loopback_au, channels * kDefaultSampleSize); + if (s_loopback_device) + { + s_loopback_enabled = start_loopback_device(s_loopback_device); + } + else + { + dprintf(DEBUG_CRITICAL, "could not create loopback device!\n"); + } + } +#endif + return s_loopback_enabled; +} + + +bool Check_Parameter_Message_Valid(IOPAUDIODSP_MODULE_COMMAND *command) +{ + if(command->mModule != kIOPAUDIODSP_MODULE_LOOPBACK_PROCESSING) + { + dprintf(DEBUG_CRITICAL, "Invalid kIOPAUDIODSP_OPCODE_SET_PARAMETER received!\n"); + return false; + } + if(!s_loopback_au) + { + dprintf(DEBUG_CRITICAL, "No existing loopback processing audio unit!\n"); + return false; + } + return true; +} + +bool Check_Property_Message_Valid(IOPAUDIODSP_MODULE_COMMAND *command) +{ + if (!Check_Parameter_Message_Valid(command)) + { + return false; + } + size_t max_size_for_property = sizeof(IOPAUDIODSP_Command) - ((uint32_t)&command->mProperty.mPropertyData - (uint32_t)command); + //make sure its formatted correctly ... + if(command->mProperty.mPropertySizeBytes > max_size_for_property) + { + dprintf(DEBUG_CRITICAL, "Invalid message size received!\n"); + return false; + } + return true; +} + +bool Handle_OPCODE_GET_PARAMETER(IOPAUDIODSP_MODULE_COMMAND *command) +{ + if (!Check_Parameter_Message_Valid(command)) + { + return false; + } + //XXX add support for array of parameters (perhaps with mNumberOfParameterValues) + if (AudioUnit_GetParameter(s_loopback_au, command->mParameter.mParameterID, &command->mParameter.mParameterValue)) + { + dprintf(DEBUG_CRITICAL, "FAILED getting parameter(%d) on loopback process!\n", command->mParameter.mParameterID); + return false; + } + return true; +} + +bool Handle_OPCODE_SET_PARAMETER(IOPAUDIODSP_MODULE_COMMAND *command) +{ + if (!Check_Parameter_Message_Valid(command)) + { + return false; + } + //XXX add support for array of parameters (perhaps with mNumberOfParameterValues) + if (AudioUnit_SetParameter(s_loopback_au, command->mParameter.mParameterID, command->mParameter.mParameterValue)) + { + dprintf(DEBUG_CRITICAL, "FAILED setting parameter(%d) on loopback process!\n", command->mParameter.mParameterID); + return false; + } + return true; +} + +bool Handle_OPCODE_GET_PROPERTY(IOPAUDIODSP_MODULE_COMMAND *command) +{ + if (!Check_Property_Message_Valid(command)) + { + return false; + } + uint32_t max_size_for_property = sizeof(IOPAUDIODSP_Command) - ((uint32_t)&command->mProperty.mPropertyData - (uint32_t)command); + if (AudioUnit_GetProperty(s_loopback_au, command->mProperty.mPropertyID, command->mProperty.mPropertyData, &max_size_for_property) ) + { + dprintf(DEBUG_CRITICAL, "FAILED getting property(%d) on loopback process!\n", command->mProperty.mPropertyID); + return false; + } + command->mProperty.mPropertySizeBytes = max_size_for_property; + return true; +} + +bool Handle_OPCODE_SET_PROPERTY(IOPAUDIODSP_MODULE_COMMAND *command) +{ + if (!Check_Property_Message_Valid(command)) + { + return false; + } + //XXX add support for array of parameters (perhaps with mNumberOfParameterValues) + if (AudioUnit_SetProperty(s_loopback_au, command->mProperty.mPropertyID, command->mProperty.mPropertyData, command->mProperty.mPropertySizeBytes)) + { + dprintf(DEBUG_CRITICAL, "FAILED setting parameter(%d) on loopback process!\n", command->mProperty.mPropertyID); + return false; + } + return true; +} + + +static bool +audiodsp_message_process(void) +{ + uint32_t message; + IOPAUDIODSP_Command* command; + + dprintf(DEBUG_SPEW, "@@ handling host message\n"); + + /* look to see if there's an item waiting for us */ + if (qwi_receive_item(audiodsp_channel, &message) == -1) + return(false); + + dprintf(DEBUG_SPEW, "@@ received audio message\n"); + + /* find the command structure based on the message */ + command = (IOPAUDIODSP_Command*)mem_static_map_cached(message); + + /* + * Flush any cached item contents we might have lying around - we are guaranteed + * that the command size is a multiple of our cacheline size. + */ + platform_cache_operation(CACHE_INVALIDATE, + (void *)command, + sizeof(*command)); + + // assume every command is a failure unless it gets set to success + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_FAILURE; + switch (command->iopaudiodsp.mOpcode) { + + case kIOPAUDIODSP_OPCODE_START_LOOPBACK_PROCESSING: + { + uint32_t sampleRate = kDefaultSampleRate; + uint32_t channels = kDefaultNumChannels; + uint32_t latency = kDefaultLatencyInUS; + + // read values from the paramter block + uint32_t* parameterBlock = (uint32_t *)command->start.mAdditionalParameters; + int32_t parameterBlockSize = command->start.mAdditionalParametersSizeBytes; + if (parameterBlockSize > 0) + { + sampleRate = *parameterBlock; + sampleRate = (sampleRate < kMaxSampleRate) ? sampleRate : kMaxSampleRate; + ++parameterBlock; + parameterBlockSize -= sizeof(parameterBlock[0]); + } + if (parameterBlockSize > 0) + { + latency = *parameterBlock; + latency = (latency < kMaxLatencyInUS) ? latency : kMaxLatencyInUS; + ++parameterBlock; + parameterBlockSize -= sizeof(parameterBlock[0]); + } + if (parameterBlockSize > 0) + { + channels = *parameterBlock; + channels = (channels < kMaxNumChannels) ? channels : kMaxNumChannels; + ++parameterBlock; + parameterBlockSize -= sizeof(parameterBlock[0]); + } + if (!sampleRate || !latency || !channels) + { + dprintf(DEBUG_CRITICAL, "Some parameter not correct (sampleRate = %d, latency = %d, channels = %d)\n", sampleRate, latency, channels); + break; + } + dprintf(DEBUG_CRITICAL, "using values sample rate %d, latency %d, channels %d\n", sampleRate, latency, channels); + uint32_t bytesToProcess = ((sampleRate * latency * channels) / 1000000) * kDefaultSampleSize; + // because we have an input buffer and process buffer, need to cut the value in half + bytesToProcess /= 2; + bytesToProcess = (bytesToProcess < kDefaultDMABufferSize) ? bytesToProcess : kDefaultDMABufferSize; + // because the DMA will do burst-4, make sure we have a valid bytes to process size: + uint32_t burstSize = kDefaultSampleSize * 4; + bytesToProcess = ((bytesToProcess + burstSize - 1)/burstSize) * burstSize; + bytesToProcess = (bytesToProcess < kDefaultDMABufferSize) ? bytesToProcess : kDefaultDMABufferSize; + uint32_t framesToProcess = bytesToProcess / (channels * kDefaultSampleSize); + dprintf(DEBUG_CRITICAL, "Start command with sample rate %d, channels %d, frames %d\n", sampleRate, channels, framesToProcess); + + // now what would the latency be? + latency = (framesToProcess * 1000000) / sampleRate; + // because we had to half the latency, we need to double it. + latency *= 2; + + if (Start_Loopback_Processing(sampleRate, channels, framesToProcess)) + { + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + dprintf(DEBUG_CRITICAL, "Started loopback processing!\n"); + } + else + { + dprintf(DEBUG_CRITICAL, "Could not start loopback processing!\n"); + } + + // write values back to the paramter block + parameterBlock = (uint32_t *)command->start.mAdditionalParameters; + parameterBlockSize = command->start.mAdditionalParametersSizeBytes; + if (parameterBlockSize > 0) + { + *parameterBlock = sampleRate; + ++parameterBlock; + parameterBlockSize -= sizeof(parameterBlock[0]); + } + if (parameterBlockSize > 0) + { + *parameterBlock = latency; + ++parameterBlock; + parameterBlockSize -= sizeof(parameterBlock[0]); + } + if (parameterBlockSize > 0) + { + *parameterBlock = channels; + ++parameterBlock; + parameterBlockSize -= sizeof(parameterBlock[0]); + } + } + break; + + case kIOPAUDIODSP_OPCODE_STOP_LOOPBACK_PROCESSING: + { + if (Stop_Loopback_Processing()) + { + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + dprintf(DEBUG_CRITICAL, "Stopped loopback processing!\n"); + } + } + break; + + case kIOPAUDIODSP_OPCODE_GET_PROPERTY: + { + if (Handle_OPCODE_GET_PROPERTY(&command->module_command)) + { + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + } + } + break; + + case kIOPAUDIODSP_OPCODE_SET_PROPERTY: + { + if (Handle_OPCODE_SET_PROPERTY(&command->module_command)) + { + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + } + } + break; + + case kIOPAUDIODSP_OPCODE_GET_PARAMETER: + { + if (Handle_OPCODE_GET_PARAMETER(&command->module_command)) + { + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + } + } + break; + + case kIOPAUDIODSP_OPCODE_SET_PARAMETER: + { + if (Handle_OPCODE_SET_PARAMETER(&command->module_command)) + { + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + } + } + break; + + case kIOPAUDIODSP_OPCODE_INITTIMESTAMP: + { + dprintf(DEBUG_CRITICAL, "Timestamp buffer is 0x%x\n", command->init_timestamp.mTimeStamperBufferAddr); + set_timestamper_message_buffer((IOPAUDIODSP_Command *)mem_static_map_cached(command->init_timestamp.mTimeStamperBufferAddr)); + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + } + break; + + case kIOPAUDIODSP_OPCODE_DO_TRANSFER: + { + dprintf(DEBUG_CRITICAL, "Starting Transfer\n"); + dprintf(DEBUG_CRITICAL, "Index %d\n", command->do_transfer.mIndex); + dprintf(DEBUG_CRITICAL, "Direction %d\n", command->do_transfer.mDirection); + dprintf(DEBUG_CRITICAL, "Do transfer %d\n", command->do_transfer.mDoTransfer); + dprintf(DEBUG_CRITICAL, "Buffer boundary [0x%x,0x%x), starting at offset 0x%x\n", command->do_transfer.mBufferBegin, command->do_transfer.mBufferEnd, command->do_transfer.mBufferStart); + + dprintf(DEBUG_CRITICAL, "Sample Rate %d, bytes per frame %d\n", command->do_transfer.mSampleRate, command->do_transfer.mBytesPerFrame); + + bool doTransfer = command->do_transfer.mDoTransfer; + uint32_t index = command->do_transfer.mIndex; + if (s_loopback_process) + { + set_tap_point(s_loopback_process, index); + } + + if (doTransfer) + { + uint8_t *IOBufferBegin = (uint8_t*)mem_static_map_cached(command->do_transfer.mBufferBegin); + uint8_t *IOBufferEnd = (uint8_t*)mem_static_map_cached(command->do_transfer.mBufferEnd); + uint8_t *IOBuffer = (uint8_t*)mem_static_map_cached(command->do_transfer.mBufferStart); + // unload and delete any tap points + set_debug_tap(s_loopback_process, NULL, NULL); + if (sInputTap) + { + destroy_debug_tap(sInputTap); + sInputTap = NULL; + } + if (sOutputTap) + { + destroy_debug_tap(sOutputTap); + sOutputTap = NULL; + } + // create the tap points + if (command->do_transfer.mDirection & 0x1) + { + sInputTap = create_debug_tap(IOBufferBegin, IOBufferEnd, IOBuffer); + } + if (command->do_transfer.mDirection & 0x2) + { + sOutputTap = create_debug_tap(IOBufferBegin, IOBufferEnd, IOBuffer); + } + // set the tap points + if (s_loopback_process) + { + set_debug_tap(s_loopback_process, sInputTap, sOutputTap); + } + } + + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + } + break; + + default: + dprintf(DEBUG_CRITICAL, "@@ ERROR: unrecognised audiodsp opcode 0x%x\n", + command->iopaudiodsp.mOpcode); + command->iopaudiodsp.mStatus = kIOPAUDIODSP_STATUS_PARAM_INVALID; + break; + } + + dprintf(DEBUG_SPEW, "@@ done processing audiodsp message with status 0x%08x\n", command->iopaudiodsp.mStatus); + + platform_cache_operation(CACHE_CLEAN, + (void *)command, + sizeof(IOPAUDIODSP_Command)); + + qwi_send_item(audiodsp_channel, message); + + dprintf(DEBUG_SPEW, "@@ signaled completion of audiodsp message to host\n"); + + return(true); +} + +static void +iop_audiodsp_sleep(int mode) +{ +} + +#if USE_DMA +static void +audiodevice_dma_int_handler_wFloat(void *arg) +{ + sCurrentProcessBufferIndex = (sCurrentProcessBufferIndex+1) % kNumDMABuffers; + process_data((loopback_process_t)arg, sBuffer[sCurrentProcessBufferIndex]); +} + +static void +audiodevice_dma_int_handler(void *arg) +{ +#if WITH_VFP && !WITH_VFP_ALWAYS_ON + //Enables floating point ops from the ISR + enter_critical_section(); + arm_call_fpsaved(arg, &audiodevice_dma_int_handler_wFloat); + exit_critical_section(); +#endif +} + +static void +audiodevice_dma_int_err_handler(void *arg) +{ + dprintf(DEBUG_CRITICAL, "audiodevice_dma_int_err_handler!\n"); +} +#endif + diff --git a/apps/EmbeddedIOP/function_audiodsp/iop_audiodsp_protocol.h b/apps/EmbeddedIOP/function_audiodsp/iop_audiodsp_protocol.h new file mode 100644 index 0000000..5cbb129 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/iop_audiodsp_protocol.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _IOP_AUDIODSP_PROTOCOL_H_ +#define _IOP_AUDIODSP_PROTOCOL_H_ + +#include + +/* + * Command size is (somewhat) tunable. + * + * The principal consideration here is the maximum scatter/gather list size + * this permits. + */ +#define kIOPAUDIODSP_COMMAND_SIZE (512) + + +/* + * IOPAUDIODSP_opcode_t: identifies the command sent and from the AE2 + */ +typedef uint32_t IOPAUDIODSP_opcode_t; + +#define kIOPAUDIODSP_OPCODE_UNKNOWN ((IOPAUDIODSP_opcode_t) 0) + +/* + * Commands for communicating with DSP library(ies) + */ +#define kIOPAUDIODSP_OPCODE_START_LOOPBACK_PROCESSING ((IOPAUDIODSP_opcode_t) 3) +#define kIOPAUDIODSP_OPCODE_STOP_LOOPBACK_PROCESSING ((IOPAUDIODSP_opcode_t) 4) +#define kIOPAUDIODSP_OPCODE_INITTIMESTAMP ((IOPAUDIODSP_opcode_t) 5) +#define kIOPAUDIODSP_OPCODE_TIMESTAMP ((IOPAUDIODSP_opcode_t) 6) +#define kIOPAUDIODSP_OPCODE_SET_PARAMETER ((IOPAUDIODSP_opcode_t) 7) +#define kIOPAUDIODSP_OPCODE_GET_PARAMETER ((IOPAUDIODSP_opcode_t) 8) +#define kIOPAUDIODSP_OPCODE_DO_TRANSFER ((IOPAUDIODSP_opcode_t) 9) +#define kIOPAUDIODSP_OPCODE_SET_PROPERTY ((IOPAUDIODSP_opcode_t) 10) +#define kIOPAUDIODSP_OPCODE_GET_PROPERTY ((IOPAUDIODSP_opcode_t) 11) + +/* + * IOPAUDIODSP_status_t: result from commands + */ +typedef uint32_t IOPAUDIODSP_status_t; + +#define kIOPAUDIODSP_STATUS_UNKNOWN ((IOPAUDIODSP_status_t) 0) +#define kIOPAUDIODSP_STATUS_SUCCESS ((IOPAUDIODSP_status_t) 1) +#define kIOPAUDIODSP_STATUS_FAILURE ((IOPAUDIODSP_status_t) 0x80000000) +#define kIOPAUDIODSP_STATUS_DEVICE_ERROR ((IOPAUDIODSP_status_t) 0x80000001) +#define kIOPAUDIODSP_STATUS_DEVICE_TIMEOUT ((IOPAUDIODSP_status_t) 0x80000002) +#define kIOPAUDIODSP_STATUS_DMA_TIMEOUT ((IOPAUDIODSP_status_t) 0x80000003) +#define kIOPAUDIODSP_STATUS_PARAM_INVALID ((IOPAUDIODSP_status_t) 0x80000004) +#define kIOPAUDIODSP_STATUS_UNIMPLEMENTED ((IOPAUDIODSP_status_t) 0x80000005) + +/* + * IOPAUDIODSP_module_t: dsp modules + */ +typedef uint32_t IOPAUDIODSP_module_t; + +#define kIOPAUDIODSP_MODULE_LOOPBACK_PROCESSING ((IOPAUDIODSP_module_t) 1) + +/* + * IOPAUDIODSP_token_t: The opaque token to use for audio processing + */ +typedef uint32_t IOPAUDIODSP_token_t; + +// Token for sending messages to the iop_audiodsp system itself +#define kIOPAUDIODSP_system_token_t ((IOPAUDIODSP_opcode_t) 0xFFFFFFFF) + +/* + * IOPAUDIODSP_status_t result from commands + */ +struct _IOPAUDIODSP +{ + IOPAUDIODSP_opcode_t mOpcode; + IOPAUDIODSP_status_t mStatus; +}; +typedef struct _IOPAUDIODSP IOPAUDIODSP; + +/* + * Messages. Message layout is dependent on the opcode. For instance, if + * the opcode is kIOPAUDIODSP_OPCODE_START, then the message will be interpreted + * as IOPAUDIODSP_START. + * It is the senders responsiblity to make sure a message is set correctly. + */ + +/* + * IOPAUDIODSP_START message + * Message used to start a new audio process. + * If message succeeds, iopToken will contain the token used for processing. + * Fill the input and output with necessary parameters. Additional parameters + * passed through the additional_paramters pointer. + */ +struct _IOPAUDIODSP_START +{ + IOPAUDIODSP mIOPHeader; + uint32_t mAdditionalParametersSizeBytes; + uint8_t mAdditionalParameters[]; +}; +typedef struct _IOPAUDIODSP_START IOPAUDIODSP_START; + +/* + * IOPAUDIODSP_STOP message + * Message used to destroy a token. + * If message succeeds, iopToken is no longer valid. + */ +struct _IOPAUDIODSP_STOP +{ + IOPAUDIODSP mIOPHeader; +}; +typedef struct _IOPAUDIODSP_STOP IOPAUDIODSP_STOP; + +/* + * IOPAUDIODSP_INITTIMESTAMP message + */ +struct _IOPAUDIODSP_INITTIMESTAMP +{ + IOPAUDIODSP mIOPHeader; + uint32_t mTimeStamperBufferAddr; +}; +typedef struct _IOPAUDIODSP_INITTIMESTAMP IOPAUDIODSP_INITTIMESTAMP; + +/* + * IOPAUDIODSP_TIMESTAMP message + */ +struct _IOPAUDIODSP_TIMESTAMP +{ + IOPAUDIODSP mIOPHeader; + uint64_t mSampleCount; + uint64_t mTimeStamp; +}; +typedef struct _IOPAUDIODSP_TIMESTAMP IOPAUDIODSP_TIMESTAMP; + +/* + * IOPAUDIODSP_DO_TRANSFER message + */ +struct _IOPAUDIODSP_DO_TRANSFER +{ + IOPAUDIODSP mIOPHeader; + uint32_t mIndex; + uint32_t mDirection; + uint32_t mDoTransfer; + // send the address range of the buffer to work with, as well as where processing should start + uint32_t mBufferBegin; + uint32_t mBufferEnd; + uint32_t mBufferStart; + + // this are necessary if we do psuedo transfer by timer + uint32_t mSampleRate; + // this is necessary to report samples transferred + uint32_t mBytesPerFrame; +}; +typedef struct _IOPAUDIODSP_DO_TRANSFER IOPAUDIODSP_DO_TRANSFER; + +/* + * Format of Parameters is (IOPAUDIODSP_PARAMETER_SUBCOMMAND) ... + * { + * parameter (4-bytes) + * parameter_value (float) + * } + * + */ +struct _IOPAUDIODSP_PARAMETER_SUBCOMMAND +{ + uint32_t mParameterID; + float mParameterValue; +}; +typedef struct _IOPAUDIODSP_PARAMETER_SUBCOMMAND IOPAUDIODSP_PARAMETER_SUBCOMMAND; + +/* + * Format of Properties is (IOPAUDIODSP_PROPERTY_SUBCOMMAND) ... + * { + * Property (4-bytes) + * Property_size (4-byte) + * Property (void*) + * } + * + */ +struct _IOPAUDIODSP_PROPERTY_SUBCOMMAND +{ + uint32_t mPropertyID; + uint32_t mPropertySizeBytes; + uint8_t mPropertyData[]; +}; +typedef struct _IOPAUDIODSP_PROPERTY_SUBCOMMAND IOPAUDIODSP_PROPERTY_SUBCOMMAND; + +struct _IOPAUDIODSP_MODULE_COMMAND +{ + IOPAUDIODSP mIOPHeader; + uint32_t mModule; + union + { + IOPAUDIODSP_PROPERTY_SUBCOMMAND mProperty; + IOPAUDIODSP_PARAMETER_SUBCOMMAND mParameter; + }; +}; +typedef struct _IOPAUDIODSP_MODULE_COMMAND IOPAUDIODSP_MODULE_COMMAND; + +union _IOPAUDIODSP_Command +{ + IOPAUDIODSP iopaudiodsp; + + IOPAUDIODSP_START start; + IOPAUDIODSP_STOP stop; + IOPAUDIODSP_INITTIMESTAMP init_timestamp; + IOPAUDIODSP_DO_TRANSFER do_transfer; + IOPAUDIODSP_TIMESTAMP timestamp; + IOPAUDIODSP_MODULE_COMMAND module_command; + UInt8 _pad[kIOPAUDIODSP_COMMAND_SIZE]; +}; +typedef union _IOPAUDIODSP_Command IOPAUDIODSP_Command; + + +#endif // _IOP_AUDIODSP_PROTOCOL_H_ diff --git a/apps/EmbeddedIOP/function_audiodsp/loopback_device.c b/apps/EmbeddedIOP/function_audiodsp/loopback_device.c new file mode 100644 index 0000000..490e509 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/loopback_device.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "loopback_device.h" + +#include "ae2_mca.h" + +#include +#include +#include +#include +#include + +enum { kBurstSize = 4 }; + +typedef struct +{ + audio_unit_t mAudioUnit; + size_t mBytesPerFrame; + uint32_t mErrorCount[kAudioDevice_Last]; +} internal_loopback_device_t; + + +uint32_t readReg(uint32_t address) +{ + return *(volatile uint32_t *)address; +} + +void writeReg(uint32_t address, uint32_t value) +{ + *(volatile uint32_t *)address = value; +} + +uint32_t readMCA0Reg(uint32_t offset) +{ + return readReg(rMCA0_BASE + offset); +} + +void writeMCA0Reg(uint32_t offset, uint32_t value) +{ + writeReg(rMCA0_BASE + offset, value); +} + + +// if this function takes too long, bail. We cannot hang the system here. +static const utime_t kMaxTime = 1000000; +bool startPIO() +{ + bool result = true; + const utime_t time_out = system_time() + kMaxTime; + + // disable TX and RX + uint32_t MCATXCFG = readMCA0Reg(rMCATXCFG); + writeMCA0Reg(rMCATXCFG, MCATXCFG & ~(1)); + uint32_t MCARXCFG = readMCA0Reg(rMCARXCFG); + writeMCA0Reg(rMCARXCFG, MCARXCFG & ~(1)); + + // Flush the RX and TX fifos + writeMCA0Reg(rMCACTL, 0x300); + uint32_t MCACTL = readMCA0Reg(rMCACTL); + while (result && (MCACTL & 0x300)) + { + MCACTL = readMCA0Reg(rMCACTL); + result = system_time() < time_out; + } + + // "Prime" the tx with zeros. + uint32_t tx_fifo_level = (readMCA0Reg(rMCASTATUS)) & 0x3FF; + while (result && (tx_fifo_level < 0x8)) + { + writeMCA0Reg(rMCATXDATA, 0); + tx_fifo_level = (readMCA0Reg(rMCASTATUS)) & 0x3FF; + result = system_time() < time_out; + } + + // enable RX IRQ (we don't need TX IRQ, we only respond when we have RX samples) + uint32_t MCAUNSRXCFG = readMCA0Reg(rMCAUNSRXCFG); + writeMCA0Reg(rMCAUNSRXCFG, MCAUNSRXCFG | (1 << rMCAUNSRXCFG_IRQ_EN)); + + // enable TX and RX + writeMCA0Reg(rMCATXCFG, MCATXCFG); + writeMCA0Reg(rMCARXCFG, MCARXCFG); + return result; +} + +bool stopPIO() +{ + uint32_t MCAUNSRXCFG = readMCA0Reg(rMCAUNSRXCFG); + writeMCA0Reg(rMCAUNSRXCFG, MCAUNSRXCFG & ~((1 << rMCAUNSRXCFG_IRQ_EN))); + uint32_t MCAUNSTXCFG = readMCA0Reg(rMCAUNSTXCFG); + writeMCA0Reg(rMCAUNSTXCFG, MCAUNSTXCFG & ~((1 << rMCAUNSTXCFG_IRQ_EN))); + return true; +} + +static void +handleAudioDeviceErrors(internal_loopback_device_t * This, const uint32_t status) +{ + // Panic when setting AppleSongbirdDSP sidetone EQ + // clear any sort of sticky-bit errors. + const uint32_t errors = status & ( rMCASTATUS_FRAMEEEROR_MASK | rMCASTATUS_RXOVERRUN_MASK | rMCASTATUS_RXUNDERRUN_MASK | rMCASTATUS_TXOVERRUN_MASK | rMCASTATUS_TXUNDERRUN_MASK ); + writeMCA0Reg(rMCASTATUS, errors); + if (errors && This) + { + if (status & rMCASTATUS_FRAMEEEROR_MASK) ++This->mErrorCount[kFrameError]; + if (status & rMCASTATUS_RXOVERRUN_MASK) ++This->mErrorCount[kRXOverrun]; + if (status & rMCASTATUS_RXUNDERRUN_MASK) ++This->mErrorCount[kRXUnderrun]; + if (status & rMCASTATUS_TXOVERRUN_MASK) ++This->mErrorCount[kTXOverrun]; + if (status & rMCASTATUS_TXUNDERRUN_MASK) ++This->mErrorCount[kTXUnderrun]; + } +} + +static void +handleAudioDeviceInterrupt_wFloat(void *arg) +{ + internal_loopback_device_t * This = (internal_loopback_device_t *)arg; + const uint32_t status = readMCA0Reg(rMCASTATUS); + handleAudioDeviceErrors(This, status); + + // where the magic occurs + if ((status & (1 << rMCASTATUS_RXHIGHWATER))) + { + // we do burst sizes of 16-bit data + int16_t data[kBurstSize]; + for (size_t i = 0; i < kBurstSize; ++i) + { + data[i] = readMCA0Reg(rMCARXDATA); + } + if (This && This->mAudioUnit) + { + AudioUnit_Process(This->mAudioUnit, data, data, sizeof(data)/This->mBytesPerFrame); + } + // , only write if there is room in the TX fifo + const uint32_t tx_fifo_level = status & 0x3FF; + const uint32_t k_tx_fifo_size = readMCA0Reg(rMCAFIFOSIZE) & 0x3FF; + if ((tx_fifo_level + kBurstSize) < k_tx_fifo_size) + { + for (size_t i = 0; i < kBurstSize; ++i) + { + writeMCA0Reg(rMCATXDATA, data[i]); + } + } + } +} + +// enable floating point code +void handleAudioDeviceInterrupt(void * object) +{ + enter_critical_section(); + arm_call_fpsaved(object, &handleAudioDeviceInterrupt_wFloat); + exit_critical_section(); +} + + + + +// create a loopback_device that will read from device rx, optional process, and send to device tx +loopback_device_t create_loopback_device(AudioDevice_Index device, audio_unit_t optional_au, size_t bytes_per_frame) +{ + dprintf(DEBUG_CRITICAL, "Creating a loopback_device object\n"); + // hardcoding to support only MCA right now. + if ((device != kMCA_0)) + { + dprintf(DEBUG_CRITICAL, "oops, bad arg\n"); + return NULL; + } + internal_loopback_device_t *This = (internal_loopback_device_t*)malloc(sizeof(internal_loopback_device_t)); + if (This) + { + This->mAudioUnit = optional_au; + This->mBytesPerFrame = bytes_per_frame; + for (uint32_t i = kFrameError; i < kError_last; ++i) + { + This->mErrorCount[i] = 0; + } + // we can do this here repeatedly + install_int_handler(AE2_INT_MCA0, handleAudioDeviceInterrupt, This); + } + return This; +} + + +void destroy_loopback_device(loopback_device_t device) +{ + // preliminary stop + stop_loopback_device(device); + internal_loopback_device_t *This = (internal_loopback_device_t*)device; + if (This) + { + free(This); + } +} + + +uint32_t getErrorCount(loopback_device_t dma, Error_Index which) +{ + // preliminary stop + internal_loopback_device_t *This = (internal_loopback_device_t*)dma; + if (This) + { + return This->mErrorCount[which]; + } + return 0; +} + + + +bool start_loopback_device(loopback_device_t device) +{ + internal_loopback_device_t *This = (internal_loopback_device_t*)device; + if (This && startPIO()) + { + unmask_int(AE2_INT_MCA0); + return true; + } + return false; +} + +bool stop_loopback_device(loopback_device_t device) +{ + internal_loopback_device_t *This = (internal_loopback_device_t*)device; + if (This) + { + mask_int(AE2_INT_MCA0); + return stopPIO(); + } + return false; +} + + diff --git a/apps/EmbeddedIOP/function_audiodsp/loopback_device.h b/apps/EmbeddedIOP/function_audiodsp/loopback_device.h new file mode 100644 index 0000000..b31910a --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/loopback_device.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __LOOPBACK_DEVICE_H__ +#define __LOOPBACK_DEVICE_H__ + +#include "iop_au_interface.h" + +typedef void * loopback_device_t; + +/* + * loopback_device_t is an object that handles looping device rx to device tx + */ + +typedef enum { + kI2S_0 = 0, + kI2S_1, + kI2S_2, + kI2S_3, + kMCA_0, + kMCA_1, + kAudioDevice_Last +} AudioDevice_Index; + +// create a loopback_device that will read from device rx, optional process, and send to device tx +loopback_device_t create_loopback_device(AudioDevice_Index device, audio_unit_t optional_au, size_t bytes_per_frame); +void destroy_loopback_device(loopback_device_t device); + +typedef enum { + kFrameError = 0, + kRXOverrun, + kRXUnderrun, + kTXOverrun, + kTXUnderrun, + kError_last +} Error_Index; + +static const char* const kErrorTypeStr[kError_last] = { + "Frame_Error", + "RX_Overrun", + "RX_Underrun", + "TX_Overrun", + "TX_Underrun", +}; + +uint32_t getErrorCount(loopback_device_t device, Error_Index which); + +// return true on success +bool start_loopback_device(loopback_device_t device); +bool stop_loopback_device(loopback_device_t device); + +#endif /* __LOOPBACK_DEVICE_H__ */ + diff --git a/apps/EmbeddedIOP/function_audiodsp/loopback_process.c b/apps/EmbeddedIOP/function_audiodsp/loopback_process.c new file mode 100644 index 0000000..d88e6f5 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/loopback_process.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "loopback_process.h" +#include "timestamper.h" +#include "debug_tap.h" + +#include +#include +#include +#include +#include + +typedef struct +{ + uint32_t mNumFrames; + uint32_t mNumChannels; + uint32_t mSampleSize; + uint32_t mChannelBitmask; + // the scratch buffer is used by the AudioUnit. We assume it needs + // 8.24 Mono (channel 0) data + audio_unit_t mAudioUnit; + + // for debug: which index to send to user + uint32_t mIndex; + debug_tap_t mInputTap; + debug_tap_t mOutputTap; + +} internal_loopback_process_t; + + +// XXX channel bitmask currently not implemented. Assuming audio data is packed. + +loopback_process_t create_loopback_process(audio_unit_t au, uint32_t frames_to_process, uint32_t channels_to_process, uint32_t sample_size, uint32_t channel_bitmask) +{ + internal_loopback_process_t *This = (internal_loopback_process_t*)malloc(sizeof(internal_loopback_process_t)); + if (This) + { + This->mNumFrames = frames_to_process; + This->mNumChannels = channels_to_process; + This->mSampleSize = sample_size; + This->mChannelBitmask = channel_bitmask; + This->mAudioUnit = au; + This->mIndex = 0; + This->mInputTap = NULL; + This->mOutputTap = NULL; + } + return This; +} + +void destroy_loopback_process(loopback_process_t loopback) +{ + internal_loopback_process_t *This = (internal_loopback_process_t*)loopback; + free(This); +} + +void set_debug_tap(loopback_process_t loopback, debug_tap_t inputTap, debug_tap_t outputTap) +{ + internal_loopback_process_t *This = (internal_loopback_process_t *)loopback; + // should we turn ints off for this? + This->mInputTap = inputTap; + This->mOutputTap = outputTap; +} + +void set_tap_point(loopback_process_t loopback, uint32_t index) +{ + internal_loopback_process_t *This = (internal_loopback_process_t *)loopback; + // should we turn ints off for this? + This->mIndex = index; +} + +void process_data(loopback_process_t loopback, void *processBuffer) +{ + internal_loopback_process_t *This = (internal_loopback_process_t *)loopback; + + uint32_t sizeOfInput = This->mNumFrames * This->mNumChannels * This->mSampleSize; + uint32_t amountToSend = 0; + + // DebugTap1 + if (This->mInputTap && (This->mIndex == 1)) + { + size_t this_amountToSend = send_to_tap(This->mInputTap, (uint8_t*)processBuffer, sizeOfInput); + if (this_amountToSend) amountToSend = this_amountToSend; + } + + // DebugInput1 + if (This->mOutputTap && (This->mIndex == 1)) + { + size_t this_amountToSend = get_from_tap(This->mOutputTap, (uint8_t*)processBuffer, sizeOfInput); + if (this_amountToSend) amountToSend = this_amountToSend; + } + + AudioUnit_Process(This->mAudioUnit, processBuffer, processBuffer, This->mNumFrames); + + // DebugTap3 + if (This->mInputTap && (This->mIndex == 3)) + { + size_t this_amountToSend = send_to_tap(This->mInputTap, (uint8_t*)processBuffer, sizeOfInput); + if (this_amountToSend) amountToSend = this_amountToSend; + } + + // DebugInput1 + if (This->mOutputTap && (This->mIndex == 3)) + { + size_t this_amountToSend = get_from_tap(This->mOutputTap, (uint8_t*)processBuffer, sizeOfInput); + if (this_amountToSend) amountToSend = this_amountToSend; + } + + if (amountToSend) + { + // Should this be done at the beginning? + uint64_t timestamp = timer_get_ticks(); + send_timestamp(This->mNumFrames, timestamp); + } +} + diff --git a/apps/EmbeddedIOP/function_audiodsp/loopback_process.h b/apps/EmbeddedIOP/function_audiodsp/loopback_process.h new file mode 100644 index 0000000..9b78db8 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/loopback_process.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _SPEAKER_PROT_H_ +#define _SPEAKER_PROT_H_ + +#include "debug_tap.h" +#include "iop_au_interface.h" +#include + +typedef void * loopback_process_t; + +/* + * loopback process is an object that will process an input buffer in- + * place, applying the passed Audio Unit to it. + * + * debug_taps can be added at specific tap points. + * + * It is assumed that the input number of samples to process matches + * with the call to process. + * + */ + +// channel bitmask is to allow cases when audio is not packed. +loopback_process_t create_loopback_process(audio_unit_t au, uint32_t frames_to_process, uint32_t channels_to_process, uint32_t sample_size, uint32_t channel_bitmask); + +void destroy_loopback_process(loopback_process_t loopback); + +void set_debug_tap(loopback_process_t loopback, debug_tap_t inputTap, debug_tap_t outputTap); +void set_tap_point(loopback_process_t loopback, uint32_t index); + +// Assumes that input is as described when loopback created +void process_data(loopback_process_t loopback, void *processBuffer); + +#endif // _SPEAKER_PROT_H_ diff --git a/apps/EmbeddedIOP/function_audiodsp/rules.mk b/apps/EmbeddedIOP/function_audiodsp/rules.mk new file mode 100644 index 0000000..d623ae7 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/rules.mk @@ -0,0 +1,48 @@ +# Copyright (C) 2010-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +# +# Audio driver +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_FUNCTION_AUDIODSP=1 \ + USE_SIDETONE=1 + +IOP_FUNCTIONS += AUDIODSP + +ALL_OBJS += $(LOCAL_DIR)/iop_audiodsp.o \ + $(LOCAL_DIR)/loopback_process.o \ + $(LOCAL_DIR)/loopback_device.o \ + $(LOCAL_DIR)/timestamper.o \ + $(LOCAL_DIR)/debug_tap.o \ + $(LOCAL_DIR)/AudioUnits/iop_au_interface.o \ + $(LOCAL_DIR)/AudioUnits/AUSidetone.o \ + $(LOCAL_DIR)/AudioUnits/AUNull.o \ + +INSTALL_HEADERS += $(LOCAL_DIR)/iop_audiodsp_protocol.h + +# Assuming 8 k for each task, with 2 task. +# Assuming 16 k heap for au process +# 32 k heap total +export IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),32768) + +GLOBAL_INCLUDES += $(SDKROOT)/usr/local/standalone/firmware \ + $(SDKROOT)/usr/local/standalone/firmware/include \ + $(LOCAL_DIR)/AudioUnits \ + $(LOCAL_DIR)/AE2_I2S \ + $(LOCAL_DIR)/AE2_MCA \ + $(LOCAL_DIR)/AE2_DMA \ + $(SDKROOT)/System/Library/Frameworks/AudioUnit.framework/Headers \ + $(SDKROOT)/System/Library/Frameworks/AudioUnit.framework/PrivateHeaders + +PREBUILT_STATICLIBS += $(SDKROOT)/usr/local/standalone/firmware/libm.a \ + $(SDKROOT)/usr/local/standalone/firmware/libvDSP.a + diff --git a/apps/EmbeddedIOP/function_audiodsp/timestamper.c b/apps/EmbeddedIOP/function_audiodsp/timestamper.c new file mode 100644 index 0000000..f806d0b --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/timestamper.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "timestamper.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define kLogTimestamps 0 + +static IOPAUDIODSP_Command *timestamper_message_buffer; + +void set_timestamper_message_buffer(IOPAUDIODSP_Command *buffer) +{ + timestamper_message_buffer = buffer; +} + +static int timestamper_message_channel; +static struct task_event timestamper_message_event; +static struct task_event timestamper_runtask_event; + +static int timestamper_task(void *cfg); +static void timestamper_sleep(int mode); + +IOP_FUNCTION(timestamper, timestamper_task, 8*1024, AUDIODSP_TIMER_CHANNEL); +IOP_SLEEP_HOOK(timestamper, timestamper_sleep); + +/* + * Get a message to send to the Host + */ +static IOPAUDIODSP_Command * +get_timestamper_message(utime_t allowed_delay) +{ + utime_t deadline, t; + int idx; + + /* nothing we can do if we don't have a buffer */ + if (NULL == timestamper_message_buffer) + return(NULL); + + /* try to get a slot right away */ + if (-1 != (idx = qwi_next_send_index(timestamper_message_channel))) + return(timestamper_message_buffer + idx); + if (IOP_MESSAGE_NO_WAIT == allowed_delay) + return(NULL); + + /* spin waiting for a free slot */ + deadline = system_time() + allowed_delay; + for (;;) { + /* get the current time and see if we've timed out */ + t = system_time(); + if (t >= deadline) + return(NULL); + + /* sleep waiting for notification or timeout */ + event_wait_timeout(×tamper_message_event, deadline - t); + + /* try again to get a message slot */ + if (-1 != (idx = qwi_next_send_index(timestamper_message_channel))) + return(timestamper_message_buffer + idx); + } +} + +/* + * Reclaim a message the host has accepted. + */ +static void +timestamper_message_wakeup(void *arg __unused) +{ + bool replies; + uint32_t message; + + /* reap message replies */ + replies = false; + while (qwi_receive_item(timestamper_message_channel, &message) != -1) + replies = true; + + /* if we got at least one reply, wake anyone trying to send */ + if (replies) + { + event_signal(×tamper_message_event); + } +} + +/* + * Try to send a trace message to the host. + */ +void +send_timestamp(uint32_t samplesTransferred, uint64_t timestamp) +{ + IOPAUDIODSP_Command *msg; + + /* now get a message - wait a little while for it but not forever as we might deadlock the host */ + if (NULL != (msg = get_timestamper_message(1000))) { + + /* populate the message */ + msg->timestamp.mIOPHeader.mOpcode = kIOPAUDIODSP_OPCODE_TIMESTAMP; + msg->timestamp.mIOPHeader.mStatus = kIOPAUDIODSP_STATUS_SUCCESS; + msg->timestamp.mSampleCount = samplesTransferred; + msg->timestamp.mTimeStamp = timestamp; + +#if kLogTimestamps + dprintf(DEBUG_CRITICAL, "Timestamp %ull\n", timestamp); +#endif + + /* push it to memory */ + platform_cache_operation(CACHE_CLEAN, msg, sizeof(*msg)); + + /* and give it to the host */ + qwi_send_item(timestamper_message_channel, QWI_ENCODE_ORDINAL(msg - timestamper_message_buffer)); + } + else + { + dprintf(DEBUG_CRITICAL, "couldn't get a timestamp message\n"); + } +} + + +static int +timestamper_task(void *cfg) +{ + struct iop_channel_config *channel = (struct iop_channel_config *)cfg; + + dprintf(DEBUG_SPEW, "@@ Timestamper task starting\n"); + + /* establish the host communications channel */ + event_init(×tamper_message_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(×tamper_runtask_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + dprintf(DEBUG_SPEW, "** opening audiodsp channel\n"); + timestamper_message_channel = qwi_instantiate_channel("audio timestamp", + QWI_ROLE_PRODUCER, + channel->ring_size, + (void *)mem_static_map_cached(channel->ring_base), + timestamper_message_wakeup, + NULL); + +#if WITH_VFP && !WITH_VFP_ALWAYS_ON + /* Little doubt we'll need VFP/Neon */ + arch_task_fp_enable(true); +#endif + + for (;;) { + dprintf(DEBUG_SPEW, "Waiting on run event\n"); + event_wait(×tamper_runtask_event); + } + + return(0); +} + +static void +timestamper_sleep(int mode) +{ +} + diff --git a/apps/EmbeddedIOP/function_audiodsp/timestamper.h b/apps/EmbeddedIOP/function_audiodsp/timestamper.h new file mode 100644 index 0000000..966f748 --- /dev/null +++ b/apps/EmbeddedIOP/function_audiodsp/timestamper.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _TIMESTAMPER_H_ +#define _TIMESTAMPER_H_ + +#include + +#include "iop_audiodsp_protocol.h" + +void set_timestamper_message_buffer(IOPAUDIODSP_Command *buffer); + +void send_timestamp(uint32_t samplesTransferred, uint64_t timestamp); + +#endif // _TIMESTAMPER_H_ + diff --git a/apps/EmbeddedIOP/function_ceata/ceata.h b/apps/EmbeddedIOP/function_ceata/ceata.h new file mode 100644 index 0000000..0239754 --- /dev/null +++ b/apps/EmbeddedIOP/function_ceata/ceata.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +typedef UInt32 CEATA_cmd_t; + +/* XXX these may be just placeholders */ +#define CEATA_IDENTIFY 0xec +#define CEATA_READ_DMA_EXT 0x25 +#define CEATA_WRITE_DMA_EXT 0x35 +#define CEATA_STANDBY_IMMEDIATE 0xe0 +#define CEATA_FLUSH_CACHE_EXT 0xea diff --git a/apps/EmbeddedIOP/function_ceata/iop_ceata.c b/apps/EmbeddedIOP/function_ceata/iop_ceata.c new file mode 100644 index 0000000..ec8621e --- /dev/null +++ b/apps/EmbeddedIOP/function_ceata/iop_ceata.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +#include + +#include +#include + +#include + +#include +#include + +#include "iop_ceata.h" +#include "iop_ceata_protocol.h" + +#include "ceata.h" + +static struct task_event ceata_message_event; + +static int ceata_channel; +static bool ceata_message_process(void); + +static IOPCEATA_status_t ceata_reset(void); +static IOPCEATA_status_t ceata_identify(IOPCEATA_Identify *identify); +static IOPCEATA_status_t ceata_cmd(CEATA_cmd_t cmd); +static IOPCEATA_status_t ceata_io(CEATA_cmd_t cmd, + UInt32 starting_lba, + UInt32 lba_count, + UInt32 segment_count, + IOPCEATA_dma_segment *segments); + +int +iop_ceata_task(void *cfg) +{ + struct iop_channel_config *channel = (struct iop_channel_config *)cfg; + + dprintf(DEBUG_SPEW, "@@ CEATA task starting\n"); + + check(kIOPCEATA_COMMAND_SIZE == sizeof(IOPCEATA_Command)); + + /* establish the host communications channel */ + event_init(&ceata_message_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dprintf(DEBUG_SPEW, "** opening ceata channel\n"); + ceata_channel = qwi_instantiate_channel( + "ceata command", + QWI_ROLE_CONSUMER, + channel->ring_size, + mem_static_map_cached(channel->ring_base), + (qwi_channel_hook)event_signal, + (void *)&ceata_message_event); + + for (;;) { + dprintf(DEBUG_SPEW, "@@ waiting for message on ceata channel\n"); + while (ceata_message_process()) { + // eat all available messages + } + event_wait(&ceata_message_event); + } + + return(0); +} + +static bool +ceata_message_process(void) +{ + uint32_t message; + IOPCEATA_Command* command; + + dprintf(DEBUG_SPEW, "@@ handling host message\n"); + + /* look to see if there's an item waiting for us */ + if (qwi_receive_item(ceata_channel, &message) == -1) + return(false); + + dprintf(DEBUG_SPEW, "@@ received ceata message\n"); + + /* find the command structure based on the message */ + command = (IOPCEATA_Command*)mem_static_map_cached(message); + + /* + * Flush any cached item contents we might have lying around - we are guaranteed + * that the command size is a multiple of our cacheline size. + */ + platform_cache_operation(CACHE_INVALIDATE, + (void *)command, + sizeof(*command)); + + /* + * TODO: make this part of the API and push this + * architecture-specific command handling down into the s5l8920x + * platform directory. + */ + switch (command->iopceata.opcode) { + + case kIOPCEATA_OPCODE_RESET: + dprintf(DEBUG_SPEW, "@@ RESET\n"); + command->iopceata.status = ceata_reset(); + break; + + case kIOPCEATA_OPCODE_IDENTIFY: + dprintf(DEBUG_SPEW, "@@ IDENTIFY\n"); + command->iopceata.status = ceata_identify((IOPCEATA_Identify *)command); + break; + + case kIOPCEATA_OPCODE_READ: + dprintf(DEBUG_SPEW, "@@ READ\n"); + command->iopceata.status = ceata_io( + CEATA_READ_DMA_EXT, + command->read_write.starting_lba, + command->read_write.lba_count, + command->read_write.segment_count, + &command->read_write.data_segments[0]); + break; + + case kIOPCEATA_OPCODE_WRITE: + dprintf(DEBUG_SPEW, "@@ WRITE\n"); + command->iopceata.status = ceata_io( + CEATA_WRITE_DMA_EXT, + command->read_write.starting_lba, + command->read_write.lba_count, + command->read_write.segment_count, + &command->read_write.data_segments[0]); + break; + + case kIOPCEATA_OPCODE_STANDBY: + dprintf(DEBUG_SPEW, "@@ STANDBY\n"); + command->iopceata.status = ceata_cmd(CEATA_STANDBY_IMMEDIATE); + break; + + case kIOPCEATA_OPCODE_FLUSH: + dprintf(DEBUG_SPEW, "@@ FLUSH\n"); + command->iopceata.status = ceata_cmd(CEATA_FLUSH_CACHE_EXT); + break; + + default: + dprintf(DEBUG_CRITICAL, "@@ ERROR: unrecognised ceata opcode 0x%x", + command->iopceata.opcode); + command->iopceata.status = kIOPCEATA_STATUS_PARAM_INVALID; + break; + } + + dprintf(DEBUG_SPEW, "@@ done processing ceata message with status 0x%08x\n", command->iopceata.status); + + platform_cache_operation(CACHE_CLEAN, + (void *)command, + sizeof(IOPCEATA_Command)); + + qwi_send_item(ceata_channel, message); + + dprintf(DEBUG_SPEW, "@@ signaled completion of ceata message to host\n"); + + return(true); +} + + +static IOPCEATA_status_t +ceata_reset(void) +{ + return(kIOPCEATA_STATUS_UNIMPLEMENTED); +} + +static IOPCEATA_status_t +ceata_identify(IOPCEATA_Identify *identify) +{ + return(kIOPCEATA_STATUS_UNIMPLEMENTED); +} + +static IOPCEATA_status_t +ceata_cmd(CEATA_cmd_t cmd) +{ + return(kIOPCEATA_STATUS_UNIMPLEMENTED); +} + +static IOPCEATA_status_t +ceata_io(CEATA_cmd_t cmd, + UInt32 starting_lba, + UInt32 lba_count, + UInt32 segment_count, + IOPCEATA_dma_segment *segments) +{ + return(kIOPCEATA_STATUS_UNIMPLEMENTED); +} diff --git a/apps/EmbeddedIOP/function_ceata/iop_ceata.h b/apps/EmbeddedIOP/function_ceata/iop_ceata.h new file mode 100644 index 0000000..76e51ed --- /dev/null +++ b/apps/EmbeddedIOP/function_ceata/iop_ceata.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +extern int iop_ceata_task(void *arg); diff --git a/apps/EmbeddedIOP/function_ceata/iop_ceata_protocol.h b/apps/EmbeddedIOP/function_ceata/iop_ceata_protocol.h new file mode 100644 index 0000000..9b00cbd --- /dev/null +++ b/apps/EmbeddedIOP/function_ceata/iop_ceata_protocol.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _IOP_CEATA_PROTOCOL_H_ +#define _IOP_CEATA_PROTOCOL_H_ + +#include + +/* + * Command size is (somewhat) tunable. + * + * The principal consideration here is the maximum scatter/gather list size + * this permits. + */ +#define kIOPCEATA_COMMAND_SIZE (512) + + +typedef UInt32 IOPCEATA_opcode_t; + +#define kIOPCEATA_OPCODE_UNKNOWN ((IOPCEATA_opcode_t) 0) + +#define kIOPCEATA_OPCODE_RESET ((IOPCEATA_opcode_t) 1) +#define kIOPCEATA_OPCODE_IDENTIFY ((IOPCEATA_opcode_t) 2) +#define kIOPCEATA_OPCODE_READ ((IOPCEATA_opcode_t) 3) +#define kIOPCEATA_OPCODE_WRITE ((IOPCEATA_opcode_t) 4) +#define kIOPCEATA_OPCODE_STANDBY ((IOPCEATA_opcode_t) 5) +#define kIOPCEATA_OPCODE_FLUSH ((IOPCEATA_opcode_t) 6) + + +typedef UInt32 IOPCEATA_status_t; + +#define kIOPCEATA_STATUS_UNKNOWN ((IOPCEATA_status_t) 0) + +#define kIOPCEATA_STATUS_SUCCESS ((IOPCEATA_status_t) 1) + +#define kIOPCEATA_STATUS_FAILURE ((IOPCEATA_status_t) 0x80000000) +#define kIOPCEATA_STATUS_DEVICE_ERROR ((IOPCEATA_status_t) 0x80000001) +#define kIOPCEATA_STATUS_DEVICE_TIMEOUT ((IOPCEATA_status_t) 0x80000002) +#define kIOPCEATA_STATUS_DMA_TIMEOUT ((IOPCEATA_status_t) 0x80000003) +#define kIOPCEATA_STATUS_PARAM_INVALID ((IOPCEATA_status_t) 0x80000004) +#define kIOPCEATA_STATUS_UNIMPLEMENTED ((IOPCEATA_status_t) 0x80000005) + +/* this must match ::struct dma_segment */ +struct _IOPCEATA_dma_segment { + u_int32_t paddr; + u_int32_t length; +}; +typedef struct _IOPCEATA_dma_segment IOPCEATA_dma_segment; + + +struct _IOPCEATA +{ + IOPCEATA_opcode_t opcode; + IOPCEATA_status_t status; +}; +typedef struct _IOPCEATA IOPCEATA; + + +struct _IOPCEATA_Identify +{ + IOPCEATA iopceata; + + // relevant properties from the CE-ATA Identify operation + UInt8 serial_number[20]; // ASCII bytes, not NUL-terminated + UInt8 firmware_revision[8]; + UInt8 model_number[40]; + + UInt32 device_size; // note this is size, not max LBA + UInt32 lba_size; // LBA size in bytes +}; +typedef struct _IOPCEATA_Identify IOPCEATA_Identify; + + +struct _IOPCEATA_ReadWrite +{ + IOPCEATA iopceata; + + UInt32 starting_lba; + UInt32 lba_count; + + UInt32 segment_count; + IOPCEATA_dma_segment data_segments[]; + +}; +typedef struct _IOPCEATA_ReadWrite IOPCEATA_ReadWrite; + + +union _IOPCEATA_Command +{ + IOPCEATA iopceata; + + IOPCEATA_Identify identify; + IOPCEATA_ReadWrite read_write; + + UInt8 _pad[kIOPCEATA_COMMAND_SIZE]; +}; +typedef union _IOPCEATA_Command IOPCEATA_Command; + +union _IOPCEATA_sgl_sizing_tool +{ + IOPCEATA_ReadWrite io_single_dma; +}; + +#define kIOPCEATA_MAX_SEGMENTS ((kIOPCEATA_COMMAND_SIZE - sizeof(union _IOPCEATA_sgl_sizing_tool)) / sizeof(IOPCEATA_dma_segment)) + + +#endif // _IOP_CEATA_PROTOCOL_H_ diff --git a/apps/EmbeddedIOP/function_ceata/rules.mk b/apps/EmbeddedIOP/function_ceata/rules.mk new file mode 100644 index 0000000..276bea7 --- /dev/null +++ b/apps/EmbeddedIOP/function_ceata/rules.mk @@ -0,0 +1,26 @@ +# Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +# +# CE-ATA driver +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_FUNCTION_CEATA=1 +IOP_FUNCTIONS += CEATA + +ALL_OBJS += $(LOCAL_DIR)/iop_ceata.o + +export FMI_PROTOCOL_HEADER:= $(LOCAL_DIR)/iop_ceata_protocol.h + +export WITH_FUNCTION_CEATA= 1 + +export IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),8192) + diff --git a/apps/EmbeddedIOP/function_fmi/iop_fmi.c b/apps/EmbeddedIOP/function_fmi/iop_fmi.c new file mode 100644 index 0000000..4e58029 --- /dev/null +++ b/apps/EmbeddedIOP/function_fmi/iop_fmi.c @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "iop_fmi_protocol.h" + +#include + +static bool fmi_message_process(int channel, h2fmi_t *fmi); + +static int iop_fmi_task(void *cfg); +static void iop_fmi_sleep(int mode); + +IOP_FUNCTION(fmi0, iop_fmi_task, 1536, FMI_CONTROL_CHANNEL0); +IOP_FUNCTION(fmi1, iop_fmi_task, 1536, FMI_CONTROL_CHANNEL1); +IOP_SLEEP_HOOK(fmi, iop_fmi_sleep); + +static h2fmi_t* g_fmi_table[kIOPFMI_MAX_NUM_OF_BUSES]; +static IOPFMI_Command* g_pCurrentCommand[kIOPFMI_MAX_NUM_OF_BUSES]; +static uint32_t g_fmi_count = 0; + +static int +iop_fmi_task(void *cfg) +{ + struct iop_channel_config *channel = (struct iop_channel_config *)cfg; + h2fmi_t* iop_fmi = (h2fmi_t*) malloc(sizeof(h2fmi_t)); + struct task_event* fmi_message_event = (struct task_event*) malloc(sizeof(struct task_event)); + int fmi_channel; + + check(kIOPFMI_COMMAND_SIZE == sizeof(IOPFMI_Command)); + + /** + * Ensure everything is zero in case we get panicked right away + * by host processor (so our panic handlers don't dereference + * invalid pointers) + */ + memset(iop_fmi,0,sizeof(*iop_fmi)); + iop_fmi->bus_id = (UInt32)-1; + + dprintf(DEBUG_SPEW, "**(%p) FMI task starting\n", iop_fmi); + + /* register the allocated FMI in the table */ + g_fmi_table[g_fmi_count++] = iop_fmi; + + /* establish the host communications channel */ + event_init(fmi_message_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dprintf(DEBUG_SPEW, "**(%p) opening fmi channel\n", iop_fmi); + fmi_channel = qwi_instantiate_channel( + "fmi command", + QWI_ROLE_CONSUMER, + channel->ring_size, + (void *)mem_static_map_cached(channel->ring_base), + (qwi_channel_hook)event_signal, + fmi_message_event); + + for (;;) { + dprintf(DEBUG_SPEW, "**(%p) waiting for message on fmi channel\n", iop_fmi); + while (fmi_message_process(fmi_channel, iop_fmi)) + { + // eat all available messages + } + event_wait(fmi_message_event); + } + + return(0); +} + +static bool +fmi_message_process(int channel, h2fmi_t *fmi) +{ + uint32_t message; + IOPFMI_Command** ppCommand; + IOPFMI_Command* pCommand; + const bool is_ppn = fmi->is_ppn; + + dprintf(DEBUG_SPEW, "**(%p) handling host message\n", fmi); + + /* look to see if there's an item waiting for us */ + if (qwi_receive_item(channel, &message) == -1) + return(false); + + dprintf(DEBUG_SPEW, "**(%p) received fmi message\n", fmi); + + /* find the command structure based on the message */ + pCommand = mem_static_map_cached(message); + if ( ((UInt32)-1)==fmi->bus_id ) + { + ppCommand = NULL; + } + else + { + ppCommand = &g_pCurrentCommand[fmi->bus_id]; + *ppCommand = pCommand; + } + + /* + * Flush any cached item contents we might have lying around - we are guaranteed + * that the command size is a multiple of our cacheline size. + */ + WMR_PREPARE_READ_BUFFER((void *)pCommand, (sizeof(*pCommand))); + + if (0 != (pCommand->iopfmi.state & kIOPFMI_STATE_WAKING_UP)) + { + if (pCommand->iopfmi.opcode != kIOPFMI_OPCODE_SET_CONFIG) + { + h2fmi_restoreFmiRegs(fmi); + } + } + + if (0 != (pCommand->iopfmi.state & kIOPFMI_STATE_POWER_CHANGED)) + { +#if SUPPORT_PPN + if (is_ppn) + { + h2fmi_ppn_iop_power_state_changed(fmi); + } +#endif + } + + /* + * TODO: make this part of the API and push this + * architecture-specific command handling down into the s5l8920x + * platform directory. + */ + switch (pCommand->iopfmi.opcode) { + case kIOPFMI_OPCODE_SET_CONFIG: + dprintf(DEBUG_SPEW, "**(%p) SET_CONFIG\n", fmi); + h2fmi_iop_set_config(fmi, &pCommand->set_config); + break; + + case kIOPFMI_OPCODE_POST_RESET_OPER: + dprintf(DEBUG_SPEW, "**(%p) POST RESET_OPERATIONS\n", fmi); + WMR_ASSERT(is_ppn); + +#if SUPPORT_PPN + h2fmi_ppn_iop_post_rst_pre_pwrstate_operations(fmi, &pCommand->post_reset_oper); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + break; + + case kIOPFMI_OPCODE_SET_FEATURES: + dprintf(DEBUG_SPEW, "**(%p) POST RESET_OPERATIONS\n", fmi); + WMR_ASSERT(is_ppn); + +#if SUPPORT_PPN + h2fmi_ppn_iop_set_feature_list(fmi, &pCommand->set_features); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + break; + + case kIOPFMI_OPCODE_RESET_EVERYTHING: + dprintf(DEBUG_SPEW, "**(%p) RESET_EVERYTHING\n", fmi); + + if (is_ppn) + { +#if SUPPORT_PPN + h2fmi_ppn_iop_reset_everything(fmi, &pCommand->reset_everything); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + } + else + { + h2fmi_iop_reset_everything(fmi, &pCommand->reset_everything); + } + break; + + case kIOPFMI_OPCODE_ERASE_SINGLE: + dprintf(DEBUG_SPEW, "**(%p) ERASE_SINGLE\n", fmi); + + if (is_ppn) + { +#if SUPPORT_PPN + h2fmi_ppn_iop_erase_single(fmi, &pCommand->erase_single); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + } + else + { + h2fmi_iop_erase_single(fmi, &pCommand->erase_single); + } + break; + + case kIOPFMI_OPCODE_ERASE_MULTIPLE: + dprintf(DEBUG_SPEW, "**(%p) ERASE_MULTIPLE\n", fmi); + if (is_ppn) + { + WMR_PANIC("Erase Multiple called on PPN device with Legacy FIL"); + } + else + { + h2fmi_iop_erase_multiple(fmi, &pCommand->erase_multiple); + } + break; + + case kIOPFMI_OPCODE_READ_SINGLE: + dprintf(DEBUG_SPEW, "**(%p) READ_SINGLE\n", fmi); + if (is_ppn) + { +#if SUPPORT_PPN + h2fmi_ppn_iop_read_single(fmi, &pCommand->io_single); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + } + else + { + h2fmi_iop_read_single(fmi, &pCommand->io_single); + } + break; + + case kIOPFMI_OPCODE_READ_MULTIPLE: + dprintf(DEBUG_SPEW, "**(%p) READ_MULTIPLE\n", fmi); + if (is_ppn) + { + WMR_PANIC("Legacy FIL used for PPN read!"); + } + else + { + h2fmi_iop_read_multiple(fmi, &pCommand->io_multiple); + } + break; + + case kIOPFMI_OPCODE_READ_RAW: + dprintf(DEBUG_SPEW, "**(%p) READ_RAW\n", fmi); + if (is_ppn) + { +#if SUPPORT_PPN + h2fmi_ppn_iop_read_raw(fmi, &pCommand->io_raw); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + } + else + { + h2fmi_iop_read_raw(fmi, &pCommand->io_raw); + } + break; + + case kIOPFMI_OPCODE_READ_BOOTPAGE: + dprintf(DEBUG_SPEW, "**(%p) READ_BOOTLOADER\n", fmi); + if (is_ppn) + { +#if SUPPORT_PPN + h2fmi_ppn_iop_read_bootpage(fmi, &pCommand->io_bootpage); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + } + else + { + h2fmi_iop_read_bootpage(fmi, &pCommand->io_bootpage); + } + break; + + case kIOPFMI_OPCODE_WRITE_SINGLE: + dprintf(DEBUG_SPEW, "**(%p) WRITE_SINGLE\n", fmi); + if (is_ppn) + { +#if SUPPORT_PPN + h2fmi_ppn_iop_write_single(fmi, &pCommand->io_single); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + } + else + { + h2fmi_iop_write_single(fmi, &pCommand->io_single); + } + break; + + case kIOPFMI_OPCODE_WRITE_MULTIPLE: + dprintf(DEBUG_SPEW, "**(%p) WRITE_MULTIPLE\n", fmi); + if (is_ppn) + { + WMR_PANIC("WRITE_MULTIPLE on PPN device using legacy FIL"); + } + else + { + h2fmi_iop_write_multiple(fmi, &pCommand->io_multiple); + } + break; + + case kIOPFMI_OPCODE_WRITE_RAW: + dprintf(DEBUG_SPEW, "**(%p) WRITE_RAW\n", fmi); + if (is_ppn) + { + WMR_PANIC("WRITE_RAW on PPN device"); + } + else + { + h2fmi_iop_write_raw(fmi, &pCommand->io_raw); + } + break; + + case kIOPFMI_OPCODE_WRITE_BOOTPAGE: + dprintf(DEBUG_SPEW, "**(%p) WRITE_BOOTLOADER\n", fmi); + if (is_ppn) + { +#if SUPPORT_PPN + h2fmi_ppn_iop_write_bootpage(fmi, &pCommand->io_bootpage); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + } + else + { + h2fmi_iop_write_bootpage(fmi, &pCommand->io_bootpage); + } + break; + + case kIOPFMI_OPCODE_READ_CAU_BBT: + dprintf(DEBUG_SPEW, "**(%p) READ_CAU_BBT\n", fmi); + WMR_ASSERT(is_ppn); +#if SUPPORT_PPN + h2fmi_ppn_iop_read_cau_bbt(fmi, &pCommand->io_ppn); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + break; + + case kIOPFMI_OPCODE_UPDATE_FIRMWARE: + dprintf(DEBUG_SPEW, "**(%p) UPDATE_FIRMWARE\n", fmi); + WMR_ASSERT(is_ppn); +#if SUPPORT_PPN + h2fmi_ppn_iop_update_firmware(fmi, &pCommand->update_firmware); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + + case kIOPFMI_OPCODE_PPN_READ: + dprintf(DEBUG_SPEW, "**(%p) PPN_READ\n", fmi); + WMR_ASSERT(is_ppn); +#if SUPPORT_PPN + h2fmi_ppn_iop_read_multiple(fmi, &pCommand->io_ppn); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + break; + + case kIOPFMI_OPCODE_PPN_WRITE: + dprintf(DEBUG_SPEW, "**(%p) PPN_WRITE\n", fmi); + WMR_ASSERT(is_ppn); +#if SUPPORT_PPN + h2fmi_ppn_iop_write_multiple(fmi, &pCommand->io_ppn); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + break; + + case kIOPFMI_OPCODE_PPN_ERASE: + dprintf(DEBUG_SPEW, "**(%p) PPN_ERASE\n", fmi); + WMR_ASSERT(is_ppn); +#if SUPPORT_PPN + h2fmi_ppn_iop_erase_multiple(fmi, &pCommand->io_ppn); +#else + WMR_PANIC("SUPPORT_PPN"); +#endif + break; + + case kIOPFMI_OPCODE_PPN_SET_POWER: + dprintf(DEBUG_SPEW, "**(%p) PPN_SET_POWER\n", fmi); + WMR_ASSERT(is_ppn); +#if SUPPORT_PPN + h2fmi_ppn_iop_set_power(fmi, &pCommand->set_power); +#endif + break; + + case kIOPFMI_OPCODE_READ_CHIP_IDS: + dprintf(DEBUG_SPEW, "**(%p) READ_CHIP_IDS\n", fmi); + h2fmi_iop_read_chip_ids(fmi, &pCommand->read_chip_ids); + break; + +#if SUPPORT_PPN + case kIOPFMI_OPCODE_GET_FAILURE_INFO: + dprintf(DEBUG_SPEW, "**(%p) GET_FAILURE_INFO\n", fmi); + h2fmi_ppn_iop_get_failure_info(fmi, &pCommand->get_failure_info); + break; + + case kIOPFMI_OPCODE_GET_CONTROLLER_INFO: + dprintf(DEBUG_SPEW, "**(%p) GET_CONTROLLER_INFO\n", fmi); + WMR_ASSERT(is_ppn); + h2fmi_ppn_iop_get_controller_info(fmi, &pCommand->get_controller_info); + break; + + case kIOPFMI_OPCODE_GET_TEMPERATURE: + dprintf(DEBUG_SPEW, "**(%p) GET_TEMPERATURE\n", fmi); + WMR_ASSERT(is_ppn); + h2fmi_ppn_iop_get_temperature(fmi, &pCommand->get_temperature); + break; + + case kIOPFMI_OPCODE_GET_DIE_INFO: + dprintf(DEBUG_SPEW, "**(%p) GET_DIE_INFO\n", fmi); + WMR_ASSERT(is_ppn); + h2fmi_ppn_iop_get_die_info(fmi, &pCommand->get_die_info); + break; +#endif + + default: + dprintf(DEBUG_CRITICAL, "**(%p) ERROR: unrecognised fmi opcode 0x%x", fmi, + pCommand->iopfmi.opcode); + pCommand->iopfmi.status = kIOPFMI_STATUS_PARAM_INVALID; + break; + } + + dprintf(DEBUG_SPEW, "**(%p) done processing fmi message with status 0x%08x\n", fmi, pCommand->iopfmi.status); + + WMR_PREPARE_WRITE_BUFFER((void *)pCommand, sizeof(*pCommand)); + + qwi_send_item(channel, message); + + dprintf(DEBUG_SPEW, "**(%p) signaled completion of fmi message to host\n", fmi); + + if ( NULL!=ppCommand ) + { + *ppCommand = NULL; + } + + return(true); +} + +static void iop_fmi_sleep(int mode) +{ + uint32_t idx; + for (idx = 0; idx < g_fmi_count; idx++) + { + if (IOP_SLEEP_MODE_SLEEPING == mode) + { + h2fmi_iop_sleep(g_fmi_table[idx]); + } + else if (IOP_SLEEP_MODE_WAKING == mode) + { + h2fmi_iop_wake(g_fmi_table[idx]); + } + else + { + dprintf(DEBUG_CRITICAL, "ERROR: unrecognized sleep mode value\n"); + } + } +} + +static void +do_fmi_panic(void *arg __unused) +{ + uint32_t i; + + printf("g_fmi_count: %d, currentTick: 0x%llx\n",g_fmi_count,WMR_CLOCK_TICKS()); + + for ( i=0; ibus_id ? NULL : g_pCurrentCommand[g_fmi_table[i]->bus_id] ); + if (NULL == pCommand) + { + printf("Not executing command\n"); + // Skip HW Regs when idle in case we're gated + dump_fmi_state(g_fmi_table[i], i, FALSE32, FALSE32); + } + else + { + BOOL32 withECC; + + switch (pCommand->iopfmi.opcode) + { + case kIOPFMI_OPCODE_READ_BOOTPAGE: + // fall-through + case kIOPFMI_OPCODE_WRITE_BOOTPAGE: + withECC = TRUE32; + break; + + default: + withECC = (g_fmi_table[i]->is_ppn ? FALSE32 : TRUE32); + break; + } + + printf("Is executing command @ %p opCode: %d\n", pCommand, pCommand->iopfmi.opcode); + dump_fmi_state(g_fmi_table[i], i, TRUE32, withECC); + } + } + +} + +PANIC_HOOK(fmi, do_fmi_panic, NULL); + diff --git a/apps/EmbeddedIOP/function_fmi/iop_fmi_protocol.h b/apps/EmbeddedIOP/function_fmi/iop_fmi_protocol.h new file mode 100644 index 0000000..ed718a2 --- /dev/null +++ b/apps/EmbeddedIOP/function_fmi/iop_fmi_protocol.h @@ -0,0 +1,553 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _IOP_FMI_PROTOCOL_H_ +#define _IOP_FMI_PROTOCOL_H_ + +#include + + +#define kIOPFMI_MAX_NUM_OF_BUSES (2) +#define kIOPFMI_MAX_NUM_OF_BANKS_PER_BUS (8) +#define kIOPFMI_MAX_NUM_OF_CES_PER_BUS (8) +#define kIOPFMI_MAX_NUM_OF_ENABLES (kIOPFMI_MAX_NUM_OF_CES_PER_BUS * kIOPFMI_MAX_NUM_OF_BUSES) +#define kIOPFMI_MAX_NUM_OF_BANKS (kIOPFMI_MAX_NUM_OF_ENABLES * kIOPFMI_MAX_NUM_OF_BUSES) +#define kIOPFMI_MAX_NUM_OF_CHANNELS (kIOPFMI_MAX_NUM_OF_BUSES) +#define kIOPFMI_BYTES_PER_META (10) +#define kIOPFMI_BYTES_PER_CHIPID (5) + +// define the maximum number of pages that the controller is willing +// to support per I/O command; Mike says that it is generally safe to +// assume a practical upper bounds of 1 MB bursts; so, for worst case +// of 2KiB pages, this translates into 512 pages per multi-I/O command +#define kIOPFMI_MAX_IO_PAGES 512 + + +/* + * Command size is (somewhat) tunable. + * + * The principal consideration here is the maximum scatter/gather list size + * this permits. + */ +#define kIOPFMI_COMMAND_SIZE (512) + + +typedef UInt32 IOPFMI_opcode_t; + +#define kIOPFMI_OPCODE_UNKNOWN ((IOPFMI_opcode_t) 0) + +#define kIOPFMI_OPCODE_SET_CONFIG ((IOPFMI_opcode_t) 1) +#define kIOPFMI_OPCODE_RESET_EVERYTHING ((IOPFMI_opcode_t) 2) +#define kIOPFMI_OPCODE_ERASE_SINGLE ((IOPFMI_opcode_t) 3) +#define kIOPFMI_OPCODE_READ_SINGLE ((IOPFMI_opcode_t) 4) +#define kIOPFMI_OPCODE_READ_RAW ((IOPFMI_opcode_t) 5) +#define kIOPFMI_OPCODE_WRITE_SINGLE ((IOPFMI_opcode_t) 6) +#define kIOPFMI_OPCODE_WRITE_RAW ((IOPFMI_opcode_t) 7) +#define kIOPFMI_OPCODE_READ_MULTIPLE ((IOPFMI_opcode_t) 8) +#define kIOPFMI_OPCODE_WRITE_MULTIPLE ((IOPFMI_opcode_t) 9) +#define kIOPFMI_OPCODE_WRITE_BOOTPAGE ((IOPFMI_opcode_t) 10) +#define kIOPFMI_OPCODE_READ_BOOTPAGE ((IOPFMI_opcode_t) 11) +#define kIOPFMI_OPCODE_ERASE_MULTIPLE ((IOPFMI_opcode_t) 12) +#define kIOPFMI_OPCODE_READ_CAU_BBT ((IOPFMI_opcode_t) 13) +#define kIOPFMI_OPCODE_ERASE_SCATTERED ((IOPFMI_opcode_t) 14) +#define kIOPFMI_OPCODE_UPDATE_FIRMWARE ((IOPFMI_opcode_t) 15) +#define kIOPFMI_OPCODE_PPN_READ ((IOPFMI_opcode_t) 16) +#define kIOPFMI_OPCODE_PPN_ERASE ((IOPFMI_opcode_t) 17) +#define kIOPFMI_OPCODE_PPN_WRITE ((IOPFMI_opcode_t) 18) +#define kIOPFMI_OPCODE_PPN_SET_POWER ((IOPFMI_opcode_t) 19) +#define kIOPFMI_OPCODE_READ_CHIP_IDS ((IOPFMI_opcode_t) 20) +#define kIOPFMI_OPCODE_GET_FAILURE_INFO ((IOPFMI_opcode_t) 21) +#define kIOPFMI_OPCODE_GET_CONTROLLER_INFO ((IOPFMI_opcode_t) 22) +#define kIOPFMI_OPCODE_GET_DIE_INFO ((IOPFMI_opcode_t) 23) +#define kIOPFMI_OPCODE_POST_RESET_OPER ((IOPFMI_opcode_t) 24) +#define kIOPFMI_OPCODE_GET_TEMPERATURE ((IOPFMI_opcode_t) 25) +#define kIOPFMI_OPCODE_SET_FEATURES ((IOPFMI_opcode_t) 26) + + +typedef UInt32 IOPFMI_flags_t; + +#define kIOPFMI_FLAGS_NONE ((IOPFMI_flags_t) 0) +#define kIOPFMI_FLAGS_BLANK_CHECK ((IOPFMI_flags_t) (1<<0)) +#define kIOPFMI_FLAGS_WITH_DMA_SGL ((IOPFMI_flags_t) (1<<1)) +#define kIOPFMI_FLAGS_USE_AES ((IOPFMI_flags_t) (1<<2)) +#define kIOPFMI_FLAGS_HOMOGENIZE ((IOPFMI_flags_t) (1<<3)) + + +typedef UInt32 IOPFMI_status_t; + +#define kIOPFMI_STATUS_UNKNOWN ((IOPFMI_status_t) 0) + +#define kIOPFMI_STATUS_SUCCESS ((IOPFMI_status_t) 1) +#define kIOPFMI_STATUS_BLANK ((IOPFMI_status_t) 2) + +#define kIOPFMI_STATUS_FAILURE ((IOPFMI_status_t) 0x80000000) +#define kIOPFMI_STATUS_DEVICE_ERROR ((IOPFMI_status_t) 0x80000001) +#define kIOPFMI_STATUS_DEVICE_TIMEOUT ((IOPFMI_status_t) 0x80000002) +#define kIOPFMI_STATUS_DMA_TIMEOUT ((IOPFMI_status_t) 0x80000003) +#define kIOPFMI_STATUS_PARAM_INVALID ((IOPFMI_status_t) 0x80000004) +#define kIOPFMI_STATUS_UNIMPLEMENTED ((IOPFMI_status_t) 0x80000005) +#define kIOPFMI_STATUS_IOP_NOT_READY ((IOPFMI_status_t) 0x80000006) + +#define kIOPFMI_STATUS_FAILED_RESET_ALL ((IOPFMI_status_t) 0x80000011) +#define kIOPFMI_STATUS_FAILED_READ_ID ((IOPFMI_status_t) 0x80000012) +#define kIOPFMI_STATUS_FAILED_ERASE_BLOCK ((IOPFMI_status_t) 0x80000013) +#define kIOPFMI_STATUS_FAILED_READ_PAGE ((IOPFMI_status_t) 0x80000014) +#define kIOPFMI_STATUS_FAILED_WRITE_PAGE ((IOPFMI_status_t) 0x80000015) +#define kIOPFMI_STATUS_FAILED_READ_RAW ((IOPFMI_status_t) 0x80000016) +#define kIOPFMI_STATUS_FAILED_WRITE_RAW ((IOPFMI_status_t) 0x80000017) +#define kIOPFMI_STATUS_FAILED_READ_MULTI ((IOPFMI_status_t) 0x80000018) +#define kIOPFMI_STATUS_FAILED_WRITE_MULTI ((IOPFMI_status_t) 0x80000019) +#define kIOPFMI_STATUS_FAILED_WRITE_BOOTPAGE ((IOPFMI_status_t) 0x8000001A) +#define kIOPFMI_STATUS_FAILED_READ_BOOTPAGE ((IOPFMI_status_t) 0x8000001B) + +#define kIOPFMI_STATUS_FMC_DONE_TIMEOUT ((IOPFMI_status_t) 0x8000001C) +#define kIOPFMI_STATUS_READY_BUSY_TIMEOUT ((IOPFMI_status_t) 0x8000001D) +#define kIOPFMI_STATUS_ECC_CLEANUP ((IOPFMI_status_t) 0x8000001E) +#define kIOPFMI_STATUS_ECC_DONE_TIMEOUT ((IOPFMI_status_t) 0x8000001F) +#define kIOPFMI_STATUS_PPN_GENERAL_ERROR ((IOPFMI_status_t) 0x80000020) +/** + * Special status -- status code from NAND is in lower 16-bits. + */ +#define kIOPFMI_STATUS_PGM_ERROR ((IOPFMI_status_t) 0x80200000) +#define kIOPFMI_STATUS_PGM_ERROR_MASK 0xffff0000 +#define kIOPFMI_STATUS_ERASE_ERROR ((IOPFMI_status_t) 0x80210000) +#define kIOPFMI_STATUS_ERASE_ERROR_MASK 0xffff0000 +#define kIOPFMI_STATUS_DMA_DONE_TIMEOUT ((IOPFMI_status_t) 0x80000022) +#define kIOPFMI_STATUS_NOT_ALL_CLEAN ((IOPFMI_status_t) 0x80000023) +#define kIOPFMI_STATUS_AT_LEAST_ONE_UECC ((IOPFMI_status_t) 0x80000024) +#define kIOPFMI_STATUS_FUSED ((IOPFMI_status_t) 0x80000025) + +/** + * Vendor-specific codes ... (passed in via vendorProtocol + * field) + */ +#define kVS_NONE 0 +#define kVS_HYNIX_2P 1 +#define kVS_TOSHIBA_2P 2 +#define kVS_MICRON_2P 3 +#define kVS_SAMSUNG_2D 4 +#define kVS_SAMSUNG_2P_2D 5 + +typedef UInt8 IOPFMI_chipid_t[kIOPFMI_BYTES_PER_CHIPID]; + + +typedef UInt32 IOPFMI_correction_t; + +/* this must match ::struct dma_segment */ +struct _IOPFMI_dma_segment { + u_int32_t paddr; + u_int32_t length; +}; +typedef struct _IOPFMI_dma_segment IOPFMI_dma_segment; + +#define kIOPFMI_AES_KEY_TYPE_USER128 (1) +#define kIOPFMI_AES_KEY_TYPE_USER192 (2) +#define kIOPFMI_AES_KEY_TYPE_USER256 (3) +#define kIOPFMI_AES_KEY_TYPE_UID0 (4) +#define kIOPFMI_AES_KEY_TYPE_GID0 (5) +#define kIOPFMI_AES_KEY_TYPE_GID1 (6) + + +typedef UInt32 IOPFMI_state_t; + +#define kIOPFMI_STATE_NONE ((IOPFMI_state_t) 0) +#define kIOPFMI_STATE_WAKING_UP ((IOPFMI_state_t) (1UL << 0)) +#define kIOPFMI_STATE_POWER_CHANGED ((IOPFMI_state_t) (1UL << 1)) + +struct _IOPFMI +{ + IOPFMI_opcode_t opcode; + IOPFMI_flags_t flags; + IOPFMI_status_t status; + UInt32 context; + UInt32 bus; + IOPFMI_state_t state; +}; +typedef struct _IOPFMI IOPFMI; + + +struct _IOPFMI_FailureDetails +{ + /** + * The operation may have had more than + * kIOPFMI_MAX_NUM_OF_ENABLES operations -- so we tell them how + * many were executed so that the caller can then figure out + * exactly where in a large list of things we were at when + * things went wrong. + */ + UInt32 wNumCE_Executed; + IOPFMI_status_t wOverallOperationFailure; + UInt32 wSingleCEStatus; + UInt32 wFirstFailingCE; +}; +typedef struct _IOPFMI_FailureDetails IOPFMI_FailureDetails; + +struct _IOPFMI_PpnStatus +{ + UInt8 operation_status[kIOPFMI_MAX_IO_PAGES]; + UInt8 program_failed_pages[kIOPFMI_MAX_IO_PAGES]; + UInt8 program_ignored_pages[kIOPFMI_MAX_IO_PAGES]; + UInt8 program_retired_pages[kIOPFMI_MAX_IO_PAGES]; +}; +typedef struct _IOPFMI_PpnStatus IOPFMI_PpnStatus; + + +struct _IOPFMI_ResetEverything +{ + IOPFMI iopfmi; +}; +typedef struct _IOPFMI_ResetEverything IOPFMI_ResetEverything; + +struct _IOPFMI_PostResetOperations +{ + IOPFMI iopfmi; +}; +typedef struct _IOPFMI_PostResetOperations IOPFMI_PostResetOperations; + +struct _IOPFMI_EraseSingle +{ + IOPFMI iopfmi; + + UInt16 ce; + UInt32 block_number; + IOPFMI_FailureDetails failure_details; +}; +typedef struct _IOPFMI_EraseSingle IOPFMI_EraseSingle; + + +struct _IOPFMI_EraseMultiple +{ + IOPFMI iopfmi; + + UInt32 number_of_elements; + UInt16 ce[ kIOPFMI_MAX_NUM_OF_ENABLES ]; + UInt32 block_number[ kIOPFMI_MAX_NUM_OF_ENABLES ]; + IOPFMI_FailureDetails failure_details; +}; +typedef struct _IOPFMI_EraseMultiple IOPFMI_EraseMultiple; + +struct _IOPFMI_IOSingle +{ + IOPFMI iopfmi; + + UInt16 ce; + UInt32 page_number; + UInt32 data_address; + UInt32 meta_address; + + // if non-zero, is array of one byte per sector in page + UInt32 correction_address; + + UInt32 aes_iv_array; // Array of IOPFMI_aes_iv entries + UInt32 aes_num_chains; + UInt32 aes_chain_size; + UInt32 aes_key_type; + UInt8 aes_key_bytes[32]; +}; +typedef struct _IOPFMI_IOSingle IOPFMI_IOSingle; + + +struct _IOPFMI_IOMultiple +{ + IOPFMI iopfmi; + + UInt32 page_count; + + UInt32 chip_enable_array; + UInt32 page_number_array; + UInt32 data_segments_array; // Array of IOPFMI_dma_segment entries + UInt32 data_segment_array_length_in_bytes; + UInt32 meta_segments_array; // Array of IOPFMI_dma_segment entries + UInt32 meta_segment_array_length_in_bytes; + + // if non-zero, is array of one byte per sector in page + UInt32 corrections_array; + + UInt32 aes_iv_array; // Array of IOPFMI_aes_iv entries + UInt32 aes_num_chains; + UInt32 aes_chain_size; + UInt32 aes_key_type; + UInt8 aes_key_bytes[32]; + + UInt32 vendorProtocol; + + IOPFMI_FailureDetails failure_details; +}; +typedef struct _IOPFMI_IOMultiple IOPFMI_IOMultiple; + +struct _IOPFMI_IOPpn +{ + IOPFMI iopfmi; + + UInt32 page_count; + UInt32 data_segments_array; + UInt32 data_segments_array_length; + UInt32 meta_segments_array; + UInt32 meta_segments_array_length; + UInt32 ppn_fil_command; + UInt32 ppn_fil_size; + UInt32 aes_iv_array; // Array of IOPFMI_aes_iv entries + UInt32 aes_num_chains; + UInt32 aes_chain_size; + UInt32 aes_key_type; + UInt8 aes_key_bytes[32]; + UInt32 geb_ce; + UInt8 overall_status; +}; +typedef struct _IOPFMI_IOPpn IOPFMI_IOPpn; + +struct _IOPFMI_IORaw +{ + IOPFMI iopfmi; + + UInt16 ce; + UInt32 page_number; + UInt32 buffer_address; +}; +typedef struct _IOPFMI_IORaw IOPFMI_IORaw; + +struct _IOPFMI_IOBootPage +{ + IOPFMI iopfmi; + + UInt16 ce; + UInt32 page_number; + UInt32 buffer_address; + + // if non-zero, is array of one byte per sector in page + UInt32 corrections_array; +}; +typedef struct _IOPFMI_IOBootPage IOPFMI_IOBootPage; + +struct _IOPFMI_ReadCauBbt +{ + IOPFMI iopfmi; + + UInt16 ce; + UInt32 cau; + UInt32 buffer_address; +}; +typedef struct _IOPFMI_ReadCauBbt IOPFMI_ReadCauBbt; + +struct _IOPFMI_UpdateFirmware +{ + IOPFMI iopfmi; + + UInt32 sgl; + UInt32 sgl_length_in_bytes; + UInt32 fw_size; +}; +typedef struct _IOPFMI_UpdateFirmware IOPFMI_UpdateFirmware; + +struct _IOPFMI_SetConfig +{ + IOPFMI iopfmi; + + UInt32 fmi; + UInt32 num_of_ce; + UInt32 valid_ces; + UInt32 pages_per_block; + UInt32 sectors_per_page; + UInt32 bytes_per_page; + UInt32 bytes_per_spare; + UInt32 logical_page_size; + UInt32 blocks_per_ce; + UInt32 read_sample_cycles; + UInt32 read_setup_cycles; + UInt32 read_hold_cycles; + UInt32 write_setup_cycles; + UInt32 write_hold_cycles; + UInt32 dqs_half_cycles; + UInt32 ce_hold_cycles; + UInt32 ce_setup_cycles; + UInt32 adl_cycles; + UInt32 whr_cycles; + UInt32 read_pre_cycles; + UInt32 read_post_cycles; + UInt32 write_pre_cycles; + UInt32 write_post_cycles; + UInt32 enable_diff_DQS; + UInt32 enable_diff_RE; + UInt32 enable_VREF; + UInt32 retire_on_invalid_refresh; + UInt32 reg_dqs_delay; + UInt32 ppn; + UInt32 ppn_version; + UInt32 toggle_system; + UInt32 toggle; + UInt32 wMaxOutstandingCEWriteOperations; + UInt32 valid_bytes_per_meta; + UInt32 total_bytes_per_meta; + UInt32 ppn_debug_flags; + UInt32 ppn_debug_flags_valid; + UInt32 ppn_vs_debug_flags; + UInt32 ppn_vs_debug_flags_valid; + UInt32 ppn_allow_saving_debug_data; + UInt32 clock_speed_khz; +}; +typedef struct _IOPFMI_SetConfig IOPFMI_SetConfig; + +struct _IOPFMI_ReadChipIDs +{ + IOPFMI iopfmi; + UInt32 chip_id_buffer; +}; +typedef struct _IOPFMI_ReadChipIDs IOPFMI_ReadChipIDs; + +// another copy lives in H2fmi_ppn.h (changes should be made to both places) +#define PPN_FEATURE__POWER_STATE__LOW_POWER (0x1) +#define PPN_FEATURE__POWER_STATE__ASYNC (0x2) +#define PPN_FEATURE__POWER_STATE__STANDBY (0x4) +#define PPN_FEATURE__POWER_STATE__DDR (0xA) + +// Power State transition unique identifiers and accessors +// another copy lives in H2fmi_ppn.h (changes should be made to both places) +#define PPN_PS_TRANS_LOW_POWER_TO_ASYNC PS_TRANS_SET(PPN_FEATURE__POWER_STATE__LOW_POWER, PPN_FEATURE__POWER_STATE__ASYNC) +#define PPN_PS_TRANS_STDBY_TO_ASYNC PS_TRANS_SET(PPN_FEATURE__POWER_STATE__STDBY, PPN_FEATURE__POWER_STATE__ASYNC) +#define PPN_PS_TRANS_ASYNC_TO_LOW_POWER PS_TRANS_SET(PPN_FEATURE__POWER_STATE__ASYNC, PPN_FEATURE__POWER_STATE__LOW_POWER) +#define PPN_PS_TRANS_DDR_TO_LOW_POWER PS_TRANS_SET(PPN_FEATURE__POWER_STATE__DDR, PPN_FEATURE__POWER_STATE__LOW_POWER) +#define PPN_PS_TRANS_ASYNC_TO_STDBY PS_TRANS_SET(PPN_FEATURE__POWER_STATE__ASYNC, PPN_FEATURE__POWER_STATE__STDBY) +#define PPN_PS_TRANS_DDR_TO_STDBY PS_TRANS_SET(PPN_FEATURE__POWER_STATE__DDR, PPN_FEATURE__POWER_STATE__STDBY) +#define PPN_PS_TRANS_LOW_POWER_TO_DDR PS_TRANS_SET(PPN_FEATURE__POWER_STATE__LOW_POWER, PPN_FEATURE__POWER_STATE__DDR) +#define PPN_PS_TRANS_STDBY_TO_DDR PS_TRANS_SET(PPN_FEATURE__POWER_STATE__STDBY, PPN_FEATURE__POWER_STATE__DDR) +#define PS_TRANS_SET(from, to) ((((UInt32)(from)) << 16) | ((UInt32)(to))) +#define PS_TRANS_GET_FROM(ps) ((ps) >> 16) +#define PS_TRANS_GET_TO(ps) ((ps) & 0xFFFF) + +struct _IOPFMI_SetPower +{ + IOPFMI iopfmi; + UInt32 power_state_trans; +}; +typedef struct _IOPFMI_SetPower IOPFMI_SetPower; + +struct _IOPFMI_GetFailureInfo +{ + IOPFMI iopfmi; + UInt32 ce; + UInt16 type; + UInt32 rma_buffer_length; + UInt32 sgl; + UInt32 sgl_length; +}; +typedef struct _IOPFMI_GetFailureInfo IOPFMI_GetFailureInfo; + +#define kIOPFMI_PPN_FW_VERSION_LENGTH 16 +#define kIOPFMI_PPN_PACKAGE_ASSEMBLY_CODE_LENGTH 16 +#define kIOPFMI_PPN_CONTROLLER_UNIQUE_ID_LENGTH 16 +#define kIOPFMI_PPN_CONTROLLER_HW_ID_LENGTH 16 +#define kIOPFMI_PPN_MANUFACTURER_ID_LENGTH 8 +#define kIOPFMI_PPN_NAND_MARKETING_NAME_LENGTH 10 + +struct _IOPFMI_GetControllerInfo +{ + IOPFMI iopfmi; + UInt32 ce; + + UInt8 fw_version[kIOPFMI_PPN_FW_VERSION_LENGTH]; + UInt8 package_assembly_code[kIOPFMI_PPN_PACKAGE_ASSEMBLY_CODE_LENGTH]; + UInt8 controller_unique_id[kIOPFMI_PPN_CONTROLLER_UNIQUE_ID_LENGTH]; + UInt8 controller_hw_id[kIOPFMI_PPN_CONTROLLER_HW_ID_LENGTH]; + UInt8 manufacturer_id[kIOPFMI_PPN_MANUFACTURER_ID_LENGTH]; + UInt8 marketing_name[kIOPFMI_PPN_NAND_MARKETING_NAME_LENGTH]; + + UInt32 caus; + UInt32 cau_bits; + UInt32 blocks_per_cau; + UInt32 block_bits; + UInt32 pages_per_block_mlc; + UInt32 pages_per_block_slc; + UInt32 page_address_bits; + UInt32 bits_per_cell_bits; + UInt32 default_bits_per_cell; + UInt32 page_size; + UInt32 dies; + UInt32 tRC; + UInt32 tREA; + UInt32 tREH; + UInt32 tRHOH; + UInt32 tRHZ; + UInt32 tRLOH; + UInt32 tRP; + UInt32 tWC; + UInt32 tWH; + UInt32 tWP; + UInt32 read_queue_size; + UInt32 program_queue_size; + UInt32 erase_queue_size; + UInt32 prep_function_buffer_size; + UInt32 tRST; + UInt32 tPURST; + UInt32 tSCE; + UInt32 tCERDY; +}; +typedef struct _IOPFMI_GetControllerInfo IOPFMI_GetControllerInfo; + +struct _IOPFMI_GetTemperature +{ + IOPFMI iopfmi; + Int16 temperature_celsius; +}; +typedef struct _IOPFMI_GetTemperature IOPFMI_GetTemperature; + +#define kIOPFMI_PPN_DIE_UNIQUE_ID_LENGTH 16 +#define kIOPFMI_PPN_DIE_CHIP_ID_LENGTH 8 + +struct _IOPFMI_GetDieInfo +{ + IOPFMI iopfmi; + UInt32 ce; + UInt32 die; + + UInt8 unique_id[kIOPFMI_PPN_DIE_UNIQUE_ID_LENGTH]; + UInt8 chip_id[kIOPFMI_PPN_DIE_CHIP_ID_LENGTH]; +}; +typedef struct _IOPFMI_GetDieInfo IOPFMI_GetDieInfo; + +struct _IOPFMI_SetFeatures +{ + IOPFMI iopfmi; + + UInt32 list; + UInt32 size; +}; +typedef struct _IOPFMI_SetFeatures IOPFMI_SetFeatures; + +union _IOPFMI_Command +{ + IOPFMI iopfmi; + + IOPFMI_SetConfig set_config; + IOPFMI_ResetEverything reset_everything; + IOPFMI_PostResetOperations post_reset_oper; + IOPFMI_EraseSingle erase_single; + IOPFMI_EraseMultiple erase_multiple; + IOPFMI_IOSingle io_single; + IOPFMI_IOMultiple io_multiple; + IOPFMI_IORaw io_raw; + IOPFMI_IOBootPage io_bootpage; + IOPFMI_ReadCauBbt read_cau_bbt; + IOPFMI_UpdateFirmware update_firmware; + IOPFMI_IOPpn io_ppn; + IOPFMI_ReadChipIDs read_chip_ids; + IOPFMI_SetPower set_power; + IOPFMI_GetFailureInfo get_failure_info; + IOPFMI_GetControllerInfo get_controller_info; + IOPFMI_GetTemperature get_temperature; + IOPFMI_GetDieInfo get_die_info; + IOPFMI_SetFeatures set_features; + + UInt8 _pad[kIOPFMI_COMMAND_SIZE]; +}; +typedef union _IOPFMI_Command IOPFMI_Command; + + +#endif // _IOP_FMI_PROTOCOL_H_ diff --git a/apps/EmbeddedIOP/function_fmi/rules.mk b/apps/EmbeddedIOP/function_fmi/rules.mk new file mode 100644 index 0000000..b56246f --- /dev/null +++ b/apps/EmbeddedIOP/function_fmi/rules.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +# +# Flash Memory Interface driver +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_FUNCTION_FMI=1 +IOP_FUNCTIONS += FMI + +ALL_OBJS += $(LOCAL_DIR)/iop_fmi.o + +INSTALL_HEADERS += $(LOCAL_DIR)/iop_fmi_protocol.h + +# XXX this is probably excessive +IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),8192) + diff --git a/apps/EmbeddedIOP/function_sdio/iop_sdio.c b/apps/EmbeddedIOP/function_sdio/iop_sdio.c new file mode 100644 index 0000000..067d83d --- /dev/null +++ b/apps/EmbeddedIOP/function_sdio/iop_sdio.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "iop_sdio_protocol.h" +#include "iop_sdio_wrapper.h" + +#define cache_op_size(buf_size) (((buf_size) + (CPU_CACHELINE_SIZE-1)) & ~(CPU_CACHELINE_SIZE-1)) + + +static struct task_event sdio_message_event; + +static int sdio_channel; +static void sdio_message_wakeup(void *arg); +static bool sdio_message_process(void); + +static int iop_sdio_task(void *cfg); + +IOP_FUNCTION(sdio, iop_sdio_task, 1024, SDIO_CONTROL_CHANNEL); + +static int +iop_sdio_task(void *cfg) +{ + struct iop_channel_config *channel = (struct iop_channel_config *)cfg; + + dprintf(DEBUG_SPEW, "++ SDIO task starting\n"); + + check(kIOPSDIO_COMMAND_SIZE == sizeof(IOPSDIO_Command)); + + /* establish the host communications channel */ + event_init(&sdio_message_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dprintf(DEBUG_SPEW, "++ opening sdio channel\n"); + sdio_channel = qwi_instantiate_channel( + "sdio message", + QWI_ROLE_CONSUMER, + channel->ring_size, + (void *)mem_static_map_cached(channel->ring_base), + sdio_message_wakeup, + NULL); + + for (;;) { + dprintf(DEBUG_SPEW, "++ waiting for message on sdio channel\n"); + while (sdio_message_process()) + { + // eat all available messages + } + event_wait(&sdio_message_event); + } + + return(0); +} + +static void +sdio_message_wakeup(void *arg __unused) +{ + event_signal(&sdio_message_event); +} + +extern unsigned int do_lookahead; +extern void iopsdio_cacheTransferSDIOData(struct IOPSDIOTargetSDHC *targetSDHC); + + +static bool +sdio_message_process(void) +{ + uint32_t messageAddr; + + dprintf(DEBUG_SPEW, "++ handling host message\n"); + + do_lookahead = 0; + + /* look to see if there's an item waiting for us */ + if (qwi_receive_item(sdio_channel, &messageAddr) == -1) + return(false); + + dprintf(DEBUG_SPEW, "++ received sdio message\n"); + + /* find the command structure based on the message */ + union IOPSDIOMessage *message = (union IOPSDIOMessage*)mem_static_map_cached(messageAddr); + + /* + * Flush any cached item contents we might have lying around - we are guaranteed + * that the message size is a multiple of our cacheline size. + */ + platform_cache_operation(CACHE_INVALIDATE, + (void *)message, + cache_op_size(sizeof(*message))); + + + switch (message->header.opcode) { + + case kIOPSDIOOpcodeInit: + { + dprintf(DEBUG_INFO, "SDHC @ 0x%X: Init\n", + message->targetSDHC.basePhysicalAddr); + + message->header.status = iopsdio_init(&message->targetSDHC, &message->initCmd); + break; + } + case kIOPSDIOOpcodeFree: + { + dprintf(DEBUG_INFO, "SDHC @ 0x%X: Free\n", + message->targetSDHC.basePhysicalAddr); + + message->header.status = iopsdio_free(&message->targetSDHC, &message->freeCmd); + break; + } + case kIOPSDIOOpcodeReset: + { + dprintf(DEBUG_INFO, "SDHC @ 0x%X: Reset 0x%X\n", + message->targetSDHC.basePhysicalAddr, message->resetCmd.resetFlags); + + message->header.status = iopsdio_reset(&message->targetSDHC, &message->resetCmd); + break; + } + case kIOPSDIOOpcodeSetBusParam: + { +/* dprintf(DEBUG_INFO, "SDHC @ 0x%X: clk = %+d, baseClk = %u, clkRate = %u Hz, width = %u, speed = %d\n", + message->targetSDHC.basePhysicalAddr, + message->setBusParamCmd.clockMode, message->setBusParamCmd.baseClockRateHz, + message->setBusParamCmd.clockRateHz, message->setBusParamCmd.busWidth, + message->setBusParamCmd.busSpeedMode); +*/ + message->header.status = iopsdio_setBusConfig(&message->targetSDHC, &message->setBusParamCmd); + break; + } + case kIOPSDIOOpcodeSendCommand: + { +/* dprintf(DEBUG_INFO, "SDHC @ 0x%X: Send SDIO Cmd: index = %u, arg = 0x%X\n", + message->targetSDHC.basePhysicalAddr, + message->sendSDIOCmd.sdioCmdIndex, message->sendSDIOCmd.sdioCmdArgument); +*/ + message->header.status = iopsdio_sendSDIOCmd(&message->targetSDHC, &message->commandCmd); + break; + } + case kIOPSDIOOpcodeTransferData: + { +/* dprintf(DEBUG_INFO, "SDHC @ 0x%X: Send SDIO DMA Cmd: index = %u, arg = 0x%X\n", + message->targetSDHC.basePhysicalAddr, + message->sdioDataCmd.sdioCmdIndex, message->sdioDataCmd.sdioCmdArgument); +*/ + message->header.status = iopsdio_transferSDIOData(&message->targetSDHC, &message->transferCmd); + break; + } + case kIOPSDIOOpcodePing: + dprintf(DEBUG_CRITICAL, "SDHC: Ping received, IOKit <--> IOP Connection established\n"); + message->header.status = kIOPSDIOStatusSuccess; + break; + default: + dprintf(DEBUG_CRITICAL, "SDHC @ 0x%X: ERROR: unrecognised sdio opcode 0x%x\n", + message->targetSDHC.basePhysicalAddr, message->header.opcode); + message->header.status = kIOPSDIOParameterInvalid; + break; + } + + dprintf(DEBUG_SPEW, "++ done processing sdio message with status 0x%08x\n", message->header.status); + + platform_cache_operation(CACHE_CLEAN, + (void *)message, + sizeof(union IOPSDIOMessage)); + + qwi_send_item(sdio_channel, messageAddr); + + + { + if (do_lookahead) { + iopsdio_cacheTransferSDIOData(&message->targetSDHC); + do_lookahead = 0; + } + + + } + + dprintf(DEBUG_SPEW, "++ signaled completion of sdio message to host\n"); + + return(true); +} diff --git a/apps/EmbeddedIOP/function_sdio/iop_sdio_protocol.h b/apps/EmbeddedIOP/function_sdio/iop_sdio_protocol.h new file mode 100644 index 0000000..d1837b5 --- /dev/null +++ b/apps/EmbeddedIOP/function_sdio/iop_sdio_protocol.h @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _IOP_SDIO_PROTOCOL_H_ +#define _IOP_SDIO_PROTOCOL_H_ + +#include + +#ifdef PLATFORM_VARIANT_IOP +#include +#else +#include +#endif + + +/* + * Command size is (somewhat) tunable. + * + * The principal consideration here is the maximum scatter/gather list size + * this permits. + */ +#define kIOPSDIO_MESSAGE_SIZE (512) + + +typedef UInt32 IOPSDIO_opcode_t; + +enum IOPSDIOOpcode +{ + kIOPSDIOOpcodeUnknown = 0, + kIOPSDIOOpcodePing = 1, + kIOPSDIOOpcodeInit = 2, + kIOPSDIOOpcodeFree = 3, + kIOPSDIOOpcodeReset = 4, + kIOPSDIOOpcodeSetBusParam = 5, + kIOPSDIOOpcodeSendCommand = 6, + kIOPSDIOOpcodeTransferData = 7, +}; + + +typedef UInt32 IOPSDIO_flags_t; + +enum IOPSDIOFlags +{ + kIOPSDIOFlagsNone = 0, +}; + + +typedef UInt32 IOPSDIO_status_t; + +enum IOPSDIOStatus +{ +// IOP Messaging Errors + + /** @brief Command succeeded. */ + kIOPSDIOStatusSuccess = 0, + + /** @brief Status is not yet known (e.g. message has not been sent or processed). */ + kIOPSDIOStatusUnknown = 1, + + /** @brief One of the IOP parameters was invalid. */ + kIOPSDIOParameterInvalid = 2, + +// Common IOReturn Values + // If the IOP Status is in the range [0x200 0x300) then it is a standard + // IOKit IOReturn value without the "iokit_common_err( )" bits set + +// SDIOReturn_t Values + // If the IOP status is in the range [0x300 0x800) it is an SDIOReturn_t + // value. This value is the same as the base value of IOSDIOReturn in the + // IOKit SDIO family, without the "iokit_family_err(sub_iokit_sdio, )" + // bits set. +}; + + + +/* this must match ::struct dma_segment */ +struct IOPSDIO_dma_segment { + u_int32_t paddr; + u_int32_t length; +}; + + +/** @brief Standard header on all IOP SDIO Commands. */ +struct IOPSDIOHeader +{ + IOPSDIO_opcode_t opcode; + IOPSDIO_flags_t flags; + IOPSDIO_status_t status; +}; + + +/** @brief Info about the target SDIO Host Controller. */ +struct IOPSDIOTargetSDHC +{ + /** @brief The Base physical address of the SDIO block's register file. */ + UInt32 basePhysicalAddr; + + /** @brief Wake event. */ + UInt32 dmaCompleteEventAddr; +}; + + +// SDIO INIT + + +/** @brief Bus Parameter Command. */ +struct IOPSDIOInitCmd +{ + /** @brief The capabilities of the SDHC. */ + UInt64 sdhcCapabilities; + + /** @brief The Maximum current capabilities of the SDHC. */ + UInt64 sdhcMaxCurrentCapabilities; +}; + + +// SDIO FREE + + +/** @brief Bus Parameter Command. */ +struct IOPSDIOFreeCmd +{ + // Nothing at the moment +}; + + +// SDIO RESET + +/** @brief SDHC Reset Command. */ +struct IOPSDIOResetCmd +{ + /** @brief Reset flags. */ + UInt32 resetFlags; +}; + + +// BUS PARAMETERS + +/** @brief Bus Parameter Command. */ +struct IOPSDIOSetBusParamCmd +{ + /** @brief Base clock rate input to the SD Block. + * If 0, the value from the SDHC capabilities register is used instead. + */ + UInt32 baseClockRateHz; + + /** @brief New SDIO clock rate in Hz. No change if 0. + * On return, this is set the value that was actually programmed into the + * SDHC block. + */ + UInt32 clockRateHz; + + /** @brief New SDIO bus width (1 or 4). No change if 0. */ + UInt8 busWidth; + + /** @brief 1 if the SDIO clock should be on, -1 if off, 0 to leave unchanged */ + int clockMode; + + /** @brief 2 for high speed mode, 1 for normal speed, 0 to leave unchanged. */ + int busSpeedMode; +}; + + +// SDIO COMMAND + +/** @brief Send an SDIO Command using the command line. + * Note that the status of the command will be reflected by the iopsdio.status field. + */ +struct IOPSDIOCommandCmd +{ + /** @brief The SDIO Command. */ + struct SDIOCommand command; + + /** @brief The command response. */ + struct SDIOCommandResponse response; +}; + + +// SDIO DATA COMMAND + +/** @brief Send an SDIO Command with data (including the command line) + * Note that the status of the command will be reflected by the iopsdio.status field. + */ +struct IOPSDIOTransferCmd +{ + /** @brief The SDIO Command. */ + struct SDIOCommand command; + + /** @brief The command response. */ + struct SDIOCommandResponse response; + + /** @brief The SDIO transfer parameters. */ + struct SDIOTransfer transfer; + + /** @brief Information about the memory segments involved in the transfer. */ + struct SDIOMemorySegments memory; + + /** @brief Physical segments for DMA engine. Variable Size. */ + struct IOPSDIO_dma_segment segment[]; +}; + + + +// IOP MESSAGES + +/** @brief IOP SDIO Message. */ +union IOPSDIOMessage +{ + struct { + /** @brief IOP Header. */ + struct IOPSDIOHeader header; + + /** @brief Target SDIO block. */ + struct IOPSDIOTargetSDHC targetSDHC; + + /** @brief Command Data. */ + union { + struct IOPSDIOInitCmd initCmd; + struct IOPSDIOFreeCmd freeCmd; + struct IOPSDIOResetCmd resetCmd; + struct IOPSDIOSetBusParamCmd setBusParamCmd; + struct IOPSDIOCommandCmd commandCmd; + struct IOPSDIOTransferCmd transferCmd; + }; + }; + + UInt8 _pad[kIOPSDIO_MESSAGE_SIZE] SDIO_RESERVED; +}; + + +union _IOPSDIO_sgl_sizing_tool +{ + struct { + /** @brief IOP Header. */ + struct IOPSDIOHeader header; + + /** @brief Target SDIO block. */ + struct IOPSDIOTargetSDHC targetSDHC; + + /** @brief Command Data. */ + union { + struct IOPSDIOTransferCmd transferCmd; + /* XXX add other sgl-using commands */ + }; + }; +}; + +#define kIOPSDIO_MAX_SEGMENTS ((kIOPSDIO_MESSAGE_SIZE - sizeof(union _IOPSDIO_sgl_sizing_tool)) / sizeof(IOPSDIO_dma_segment)) + + +#endif // _IOP_SDIO_PROTOCOL_H_ diff --git a/apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.c b/apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.c new file mode 100644 index 0000000..e13a5da --- /dev/null +++ b/apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.c @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "iop_sdio_wrapper.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "iop_sdio_protocol.h" +#include + +#include "debug.h" +#define cache_op_size(buf_size) (((buf_size) + (CPU_CACHELINE_SIZE-1)) & ~(CPU_CACHELINE_SIZE-1)) + +#define MAGIC_WRITE 0x44555544 +#define MAGIC_READ 0x55555555 + +#define MAX_SDIO_READ_LEN (32*1024) //agreement with AppleBCMWLAN driver that there wont be any read bigger than that + +#define BCOM_SDIO_CHANNEL_OFFSET 5 +#define BCOM_SDIO_NEXTLEN_OFFSET 6 +#define BCOM_SDIO_DATAOFFSET_OFFSET 7 + +#define BCOM_SDIO_GLOM_CHANNEL 3 +#define BCOM_SDIO_GLOM_FRAME_DESCRIPTOR 0x80 + +#define MAGIC_READ_PACKET_LEN_OFFSET 1 +#define MAGIC_READ_ENABLE_OFFSET 2 +#define MAGIC_READ_BUFFER_LENGTH_OFFSET 3 + + +#define LOOKAHEAD_READ_PKT_SIZE (lookahead_read_pkt_size) + +struct cacheCmd { + struct IOPSDIOTransferCmd transferCmd; + struct IOPSDIO_dma_segment segment; +}; + +struct cacheCmd cmd; +SDIOReturn_t cachedError = kSDIOReturnSuccess; +unsigned int do_lookahead = 0; +unsigned int lookahead_read_pkt_size = 12 * 1024; //default buffer, max 12K per packet + + +IOPSDIO_status_t +iopsdio_init(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOInitCmd *initCmd) +{ + check(targetSDHC); + check(initCmd); + + SDHCRegisters_t *sdhc = (SDHCRegisters_t*)targetSDHC->basePhysicalAddr; + if(!sdhc) { + return kSDIOReturnNoHostController; + } + + // Create DMA completion event. + struct task_event* dmaCompleteEvent = malloc(sizeof(struct task_event)); + if(!dmaCompleteEvent) { + return kSDIOReturnNoMemory; + } + + event_init(dmaCompleteEvent, EVENT_FLAG_AUTO_UNSIGNAL, false); + + targetSDHC->dmaCompleteEventAddr = (UInt32)dmaCompleteEvent; + +#if 0 + /* 7256044 */ + initCmd->sdhcCapabilities = sdhc->capabilities; + initCmd->sdhcMaxCurrentCapabilities = sdhc->maxCurrentCapabilities; +#else + initCmd->sdhcCapabilities = 0; + initCmd->sdhcMaxCurrentCapabilities = 0; +#endif + + return kSDIOReturnSuccess; +} + +IOPSDIO_status_t +iopsdio_free(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOFreeCmd *freeCmd) +{ + check(targetSDHC); + check(freeCmd); + + SDHCRegisters_t *sdhc = (SDHCRegisters_t*)targetSDHC->basePhysicalAddr; + if(!sdhc) { + return kSDIOReturnNoHostController; + } + + // Destroy the DMA completion event + free((void*)targetSDHC->dmaCompleteEventAddr); + targetSDHC->dmaCompleteEventAddr = 0; + + return kSDIOReturnSuccess; +} + +IOPSDIO_status_t +iopsdio_reset(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOResetCmd *resetCmd) +{ + check(targetSDHC); + check(resetCmd); + + SDHCRegisters_t *sdhc = (SDHCRegisters_t*)targetSDHC->basePhysicalAddr; + if(!sdhc) { + return kSDIOReturnNoHostController; + } + + SDIOReturn_t retval = sdiodrv_resetSDHC(sdhc, resetCmd->resetFlags); + if(kSDIOReturnSuccess != retval) { + return retval; + } + + // restore interrupt state on reset + if(resetCmd->resetFlags & kSDHCResetAll) { + sdhc_enableCommandStatus(sdhc, true); + sdhc_enableTransferStatus(sdhc, true); + } + + cachedError = retval; + + return retval; +} + +IOPSDIO_status_t +iopsdio_setBusConfig(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOSetBusParamCmd *busParamCmd) +{ + check(targetSDHC); + check(busParamCmd); + + if (cachedError != kSDIOReturnSuccess) + return cachedError; + + SDHCRegisters_t *sdhc = (SDHCRegisters_t*)targetSDHC->basePhysicalAddr; + if(!sdhc) { + return kSDIOReturnNoHostController; + } + + SDIOReturn_t retval = kSDIOReturnSuccess; + + if(busParamCmd->clockRateHz) { + + retval = sdiodrv_setClockRate(sdhc, &busParamCmd->clockRateHz, busParamCmd->baseClockRateHz); + if(kSDIOReturnSuccess != retval) { + return retval; + } + } + + if(busParamCmd->busWidth) { + + retval = sdiodrv_setBusWidth(sdhc, busParamCmd->busWidth); + if(kSDIOReturnSuccess != retval) { + return retval; + } + } + + if(busParamCmd->busSpeedMode) { + + retval = sdiodrv_setBusSpeedMode(sdhc, busParamCmd->busSpeedMode); + if(kSDIOReturnSuccess != retval) { + return retval; + } + } + + if(busParamCmd->clockMode) { + + retval = sdiodrv_setClockMode(sdhc, busParamCmd->clockMode); + if(kSDIOReturnSuccess != retval) { + return retval; + } + } + + return retval; +} + +unsigned int nm = 0; +IOPSDIO_status_t +iopsdio_sendSDIOCmd(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOCommandCmd *commandCmd) +{ + check(targetSDHC); + check(commandCmd); + + if (cachedError != kSDIOReturnSuccess) + return cachedError; + + SDHCRegisters_t *sdhc = (SDHCRegisters_t*)targetSDHC->basePhysicalAddr; + if(!sdhc) { + return kSDIOReturnNoHostController; + } + + SDIOReturn_t retval = sdiodrv_sendSDIOCommand(sdhc, &commandCmd->command, &commandCmd->response); + + return retval; +} + + +/* + * read a complete SDIO packet: + * reads are always block aligned + * + * blocks: number of blocks to read, if zero, then issue a one block read in order to get the frame header and + * obtain the packet length from this header, issue a second read in order to to get the remaining blocks + * max_blocks: max_blocks allowed + * data: virtual address if read buffer + * + */ + + +IOPSDIO_status_t iopsdio_read_packet(unsigned int blocks, unsigned int max_blocks, unsigned int * data, struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOTransferCmd *transferCmd) +{ + IOPSDIO_status_t retval = 0; + SDHCRegisters_t *sdhc = (SDHCRegisters_t*)targetSDHC->basePhysicalAddr; + struct task_event *dmaCompleteEvent = (struct task_event *)targetSDHC->dmaCompleteEventAddr; + + if (blocks == 0) { + + transferCmd->transfer.blockCount = 1; + transferCmd->memory.dataLength = transferCmd->transfer.blockSize; + transferCmd->segment[0].length = transferCmd->transfer.blockSize; + transferCmd->transfer.command.argument = (transferCmd->transfer.command.argument& 0xfffffe00) | 1; + + data = mem_static_map_cached((uint32_t)data); + + platform_cache_operation(CACHE_INVALIDATE, + (void *)data, + (32)); + + if (transferCmd->memory.dataLength > MAX_SDIO_READ_LEN) { + //paranoia + dprintf(DEBUG_CRITICAL, "iopsdio_read_packet1: len frame is too large %llu \n", transferCmd->memory.dataLength); + retval = kSDIOReturnBadArgument; + return retval; + } + + retval = sdiodrv_transferData(sdhc, &transferCmd->transfer, &transferCmd->memory, &transferCmd->response, dmaCompleteEvent); + + if (retval) + return retval; + + + + data = mem_static_map_cached((uint32_t)data); + + platform_cache_operation(CACHE_INVALIDATE, + (void *)data, + (32)); + + unsigned short check = data[0]>>16; + unsigned short fflen = data[0]; + + if (fflen) { + + + + if ((fflen + check) != 0xffff) { + + dprintf(DEBUG_CRITICAL, "iopsdio_read_packet error %x %d - %x blocks %u %x\n", fflen, fflen, check, blocks, data[1]); + dprintf(DEBUG_CRITICAL, " ===== %p %x %x %x\n", data, transferCmd->segment[0].paddr, data[0],*(unsigned int*)transferCmd->segment[0].paddr); + + return retval; + } + + unsigned short mask = transferCmd->transfer.blockSize-1; + unsigned short flen = (fflen+mask) & ~mask; //round up + + unsigned int remain_blocks = flen ; + if (128 == transferCmd->transfer.blockSize) { + remain_blocks = remain_blocks/128; + } else { + remain_blocks = remain_blocks/transferCmd->transfer.blockSize; + } + + if (remain_blocks == 0) { + dprintf(DEBUG_CRITICAL, "iopsdio_read_packet: error zero blocks \n"); + + return kSDIOReturnBadArgument; + + } + remain_blocks--; + + if (remain_blocks >= max_blocks) { + dprintf(DEBUG_CRITICAL, "iopsdio_read_packet: not enough blocks %u orig %u flen %x check %x\n", remain_blocks, max_blocks, fflen, check); + + return kSDIOReturnBadArgument; + } + if (remain_blocks) { + + //read remaining blocks + transferCmd->transfer.blockCount = remain_blocks; + transferCmd->memory.dataLength = transferCmd->transfer.blockSize * remain_blocks; + transferCmd->segment[0].length = transferCmd->transfer.blockSize * remain_blocks; + transferCmd->segment[0].paddr += transferCmd->transfer.blockSize; + + transferCmd->transfer.command.argument = (transferCmd->transfer.command.argument& 0xfffffe00) | remain_blocks; + + if (transferCmd->memory.dataLength > MAX_SDIO_READ_LEN) { + //paranoia, + dprintf(DEBUG_CRITICAL, "iopsdio_read_packet2: len frame is too large %llu remain %u size %hu\n", transferCmd->memory.dataLength, remain_blocks, transferCmd->transfer.blockSize); + retval = kSDIOReturnBadArgument; + return retval; + } + + retval = sdiodrv_transferData(sdhc, &transferCmd->transfer, &transferCmd->memory, &transferCmd->response, dmaCompleteEvent); + transferCmd->segment[0].paddr -= transferCmd->transfer.blockSize; + } + + } + + + } else { + + transferCmd->transfer.blockCount = blocks; + transferCmd->memory.dataLength = transferCmd->transfer.blockSize * blocks; + transferCmd->segment[0].length = transferCmd->transfer.blockSize * blocks; + + transferCmd->transfer.command.argument = (transferCmd->transfer.command.argument& 0xfffffe00) | blocks; + platform_cache_operation(CACHE_INVALIDATE, + (void *)data, + (32)); + retval = sdiodrv_transferData(sdhc, &transferCmd->transfer, &transferCmd->memory, &transferCmd->response, dmaCompleteEvent); + + + } + + + return retval; + +} + +void iopsdio_cacheTransferSDIOData(struct IOPSDIOTargetSDHC *targetSDHC) +{ + + SDIOReturn_t retval = 0; + cachedError = kSDIOReturnSuccess; + + //perform access based on the cached command + struct IOPSDIOTransferCmd *transferCmd = &cmd.transferCmd; + + unsigned int * data = (unsigned int*)transferCmd->segment[0].paddr; + data = mem_static_map_cached((uint32_t)data); + + unsigned int max_blocks; + if (128 == transferCmd->transfer.blockSize) + max_blocks = LOOKAHEAD_READ_PKT_SIZE/128; + else + max_blocks = LOOKAHEAD_READ_PKT_SIZE/transferCmd->transfer.blockSize; + + //kick SDIO transfer + retval = iopsdio_read_packet(transferCmd->transfer.blockCount, max_blocks, data, targetSDHC, transferCmd); + + if (retval) { + if ((retval < kSDIOReturnDataError) || (retval > kSDIOReturnDataTimeout)) { + //paranoia, make sure we return a Data error here, which means that the host will trigger a Reset + cachedError = kSDIOReturnDataError; + } else { + + cachedError = retval; + } + } else { + + cachedError = kSDIOReturnSuccess; + } + + unsigned int *retp = (unsigned int*)(((unsigned char*)data)+LOOKAHEAD_READ_PKT_SIZE); + + //dprintf(0, "iopsdio_cacheTransferSDIOData done %x %x\n", *retp, retval); + + //make sure we tell the host processor that we're done + * retp = retval; + platform_cache_operation(CACHE_CLEAN, + (void *)retp, + (32)); + +} + + + +IOPSDIO_status_t +iopsdio_transferSDIOData(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOTransferCmd *transferCmd) +{ + check(targetSDHC); + check(transferCmd); + unsigned int orig_bcount = 0; + unsigned int nlen = 0; + + if (cachedError != kSDIOReturnSuccess) + return cachedError; + + + SDHCRegisters_t *sdhc = (SDHCRegisters_t*)targetSDHC->basePhysicalAddr; + if(!sdhc) { + return kSDIOReturnNoHostController; + } + + struct task_event *dmaCompleteEvent = (struct task_event *)targetSDHC->dmaCompleteEventAddr; + + transferCmd->memory.segmentList = transferCmd->segment; + + unsigned int orig_data = transferCmd->segment[0].paddr; + + + unsigned int * data = mem_static_map_cached((uint32_t)orig_data); + platform_cache_operation(CACHE_INVALIDATE, + (void *)data, + (32)); + SDIOReturn_t retval = 0; + if (( transferCmd->transfer.direction == kSDIODirectionWrite) && (*data == MAGIC_WRITE) && ((transferCmd->transfer.command.argument & kSDIOCmd53BlockMode) == kSDIOCmd53BlockMode)) { + unsigned int base_addr = transferCmd->segment[0].paddr + transferCmd->transfer.blockSize; + unsigned int * l = data + 1; + unsigned int cnt = 0; + unsigned int bcount = *l ; + // dprintf(0, "iopsdio_transferSDIOData magic wwwrite got %x %x [%x %x] %u %u %u\n",l[0],l[1], transferCmd->transfer.command.argument,transferCmd->transfer.command.index, transferCmd->transfer.blockCount,transferCmd->transfer.blockSize, transferCmd->memory.segmentCount); + + //first sdio block = MAGIC_WRITE/block size of pkt1/block size of pkt 2/block size of pkt3 etc... + //second sdio blocks and so on... = packets data + + if (transferCmd->transfer.blockCount == 1) { + + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData magic write error!! %p %x %x %x\n",data, l[0],l[1],l[2]); + + return kSDIOReturnBadArgument; + } + + while (bcount!=0) { + unsigned int transfer_len = bcount * transferCmd->transfer.blockSize; + + transferCmd->memory.dataLength = transfer_len; + + transferCmd->transfer.command.argument = (transferCmd->transfer.command.argument& 0xfffffe00) | bcount; + + transferCmd->transfer.blockCount = bcount; + + transferCmd->segment[0].length = transfer_len; + transferCmd->segment[0].paddr = base_addr; + unsigned int *p = (unsigned int*)transferCmd->segment[0].paddr; + + + p = mem_static_map_cached((uint32_t)p); + + platform_cache_operation(CACHE_INVALIDATE, + (void *)p, + (32)); + + unsigned short check = p[0]>>16; + unsigned short fflen = p[0]; + if ((check + fflen) != 0xffff) { + //internal error, the sender tries to send a corrupted packet + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData detected error ---> %p : %x %x %x %x \n", p, p[0], p[1], p[2], p[3]); + retval = kSDIOReturnBadArgument; + } else { + + retval = sdiodrv_transferData(sdhc, &transferCmd->transfer, &transferCmd->memory, &transferCmd->response, dmaCompleteEvent); + } + if (retval) { + + *data = cnt; //tell the sender how many packets we did send successfully + + platform_cache_operation(CACHE_CLEAN, + (void *)data, + (32)); + + unsigned int *p = (unsigned int *)base_addr; + + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData ---> %x %x %x %x \n", p[0], p[1], p[2], p[3]); + dprintf(DEBUG_CRITICAL, " --> cnt %u bc %u addr %p arg %x retval %x\n", cnt, transferCmd->transfer.blockCount, (void *)transferCmd->segment[0].paddr, transferCmd->transfer.command.argument, retval); + return retval; + } + base_addr += transfer_len;//transferCmd->transfer.blockSize * bcount; + cnt++; + l++; + bcount = *l ; + + } + + } else if ((transferCmd->transfer.direction == kSDIODirectionRead) && (*data == MAGIC_READ) && ((transferCmd->transfer.command.argument & kSDIOCmd53BlockMode) == kSDIOCmd53BlockMode)) { + + + //MAGIC READ: + //buffer1 of size LOOKAHEAD_READ_PKT_SIZE + buffer2 of size LOOKAHEAD_READ_PKT_SIZE + one + //additional block used as end of transfer marker + + orig_bcount = transferCmd->transfer.blockCount; + // dprintf(0, "iopsdio_transferSDIOData read got %u %u %u \n",l[0],l[1],l[2]); + unsigned int blocks = *(data+MAGIC_READ_PACKET_LEN_OFFSET); + unsigned int lk = *(data+MAGIC_READ_ENABLE_OFFSET); + if (*(data+MAGIC_READ_BUFFER_LENGTH_OFFSET)) { + lookahead_read_pkt_size = *(data+MAGIC_READ_BUFFER_LENGTH_OFFSET); + } + retval = iopsdio_read_packet(blocks, orig_bcount, data, targetSDHC, transferCmd); + + if (lk == 0) { + //Host processor doesn't want the look ahead + return retval; + } + if (retval) { + goto return_clear; + } + + + unsigned char nextlen = *((unsigned char*)data + BCOM_SDIO_NEXTLEN_OFFSET); + unsigned char channel = *((unsigned char*)data + BCOM_SDIO_CHANNEL_OFFSET); + unsigned char offset = *((unsigned char*)data + BCOM_SDIO_DATAOFFSET_OFFSET); + // dprintf(0, "iopsdio_transferSDIOData read got %x %x %x - %u channel %u offset %u\n",data[0],data[1],data[2], nextlen,channel, offset); + + + unsigned short check = data[0]>>16; + unsigned short fflen = data[0]; + + if (fflen) { + + + + if ((fflen + check) != 0xffff) { + + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData cksum error %x %d - %x \n", fflen, fflen, check); + retval = kSDIOReturnDataError; + goto return_clear; + } + } else { + if (check==0) { + //fflen and check are null, hence no more data pending + goto return_clear; + } + } + + + nlen = 16 * nextlen; + + + if (nlen == 0 && channel == (BCOM_SDIO_GLOM_FRAME_DESCRIPTOR|BCOM_SDIO_GLOM_CHANNEL)) { + //reading a Glom descriptor: calculate the length of next frame + //max number of GLom frames is tunable and typically 7, a glom frame descriptor should not be larger than 64 Bytes +#define SANE_MAX_GLOM_FRAME_LEN 64 + if (fflen > SANE_MAX_GLOM_FRAME_LEN) { + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData glom descriptor is too large %hu \n", fflen); + goto return_clear; + } + + if (fflen > 32) { + //uncache the rest of the frame + platform_cache_operation(CACHE_INVALIDATE, + (void *)data, + cache_op_size(fflen)); + } + + unsigned short * p = (unsigned short *)((unsigned char*)data + offset); + unsigned short * end = (unsigned short *)((unsigned char*)data + fflen); + + //calculate nlen + while (p < end){ + nlen += *p++; + } + + + if (nlen > LOOKAHEAD_READ_PKT_SIZE) { + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData calculated glom frame is too large %u \n", nlen); + retval = kSDIOReturnDataError; + goto return_clear; + } + } + + + + //save parameters for the next transfer + nlen += transferCmd->transfer.blockSize-1; + nlen = nlen & ~(transferCmd->transfer.blockSize-1); + + if (nlen > MAX_SDIO_READ_LEN) { + //paranoia + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData magic read calculating a bad len frame large %u \n", nlen); + retval = kSDIOReturnBadArgument; + goto return_clear; + } + + cmd.transferCmd.transfer.command.argument = transferCmd->transfer.command.argument; + cmd.transferCmd.transfer.command.index = transferCmd->transfer.command.index; + + + if (128 == transferCmd->transfer.blockSize) + cmd.transferCmd.transfer.blockCount = nlen/128; + else + cmd.transferCmd.transfer.blockCount = nlen/transferCmd->transfer.blockSize; + + cmd.transferCmd.transfer.blockSize = transferCmd->transfer.blockSize; + cmd.transferCmd.transfer.direction = transferCmd->transfer.direction; + + cmd.segment.length = nlen; + cmd.segment.paddr = orig_data+LOOKAHEAD_READ_PKT_SIZE; + + cmd.transferCmd.memory.segmentList = &cmd.segment; + cmd.transferCmd.memory.dataLength = nlen; + cmd.transferCmd.memory.segmentCount = 1; + + if (lk > 1) { + //experimental mode, read all at once while the host processor wait - used only for debug 14July2011 + iopsdio_cacheTransferSDIOData(targetSDHC); + } else { + //set lookahead to tell the sdio task handler in iop_sdio.c to generate the cached loakahead read + do_lookahead = lk; + } + + } else { + + if (transferCmd->transfer.direction == kSDIODirectionRead) { + //if transfer is cmd53 block read, check that the requested length matches the number of blocks requested + //and check that the total length is not overly large + nlen = transferCmd->transfer.blockCount * transferCmd->transfer.blockSize; + + if (nlen != transferCmd->memory.dataLength) { + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData len mismatch %u %llu direction %hhu\n", nlen, transferCmd->memory.dataLength, transferCmd->transfer.direction); + return kSDIOReturnBadArgument; + } + + if (nlen > MAX_SDIO_READ_LEN) { + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData data transfer is too large %u %llu direction %hhu\n", nlen, transferCmd->memory.dataLength, transferCmd->transfer.direction); + return kSDIOReturnBadArgument; + } + } + + retval = sdiodrv_transferData(sdhc, &transferCmd->transfer, &transferCmd->memory, &transferCmd->response, dmaCompleteEvent); + if (retval) { + dprintf(DEBUG_CRITICAL, "iopsdio_transferSDIOData error %x\n",retval); + } + + } + return retval; + +return_clear: + { + + unsigned int last_block; + if (128 == transferCmd->transfer.blockSize) + last_block = (LOOKAHEAD_READ_PKT_SIZE*2)/128; + else + last_block = (LOOKAHEAD_READ_PKT_SIZE*2)/transferCmd->transfer.blockSize; + + //paranoia: check if we have enough space in the buffer, then mark it as done + if (orig_bcount >= last_block) { + unsigned int *retp = (unsigned int*)(((unsigned char*)data)+LOOKAHEAD_READ_PKT_SIZE*2); + + * retp = retval; + platform_cache_operation(CACHE_CLEAN, + (void *)retp, + (32)); + + } + } + + return retval; + +} + + + + diff --git a/apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.h b/apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.h new file mode 100644 index 0000000..a13d2bc --- /dev/null +++ b/apps/EmbeddedIOP/function_sdio/iop_sdio_wrapper.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _IOP_SDIO_WRAPPER_H +#define _IOP_SDIO_WRAPPER_H + + +#include "iop_sdio_protocol.h" + + +IOPSDIO_status_t iopsdio_init(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOInitCmd *initCmd); + +IOPSDIO_status_t iopsdio_free(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOFreeCmd *freeCmd); + +IOPSDIO_status_t iopsdio_reset(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOResetCmd *resetCmd); + +IOPSDIO_status_t iopsdio_setBusConfig(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOSetBusParamCmd *busParamCmd); + +IOPSDIO_status_t iopsdio_sendSDIOCmd(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOCommandCmd *commandCmd); + +IOPSDIO_status_t iopsdio_transferSDIOData(struct IOPSDIOTargetSDHC *targetSDHC, struct IOPSDIOTransferCmd *transferCmd); + + + +#endif // _IOP_SDIO_WRAPPER_H + + diff --git a/apps/EmbeddedIOP/function_sdio/rules.mk b/apps/EmbeddedIOP/function_sdio/rules.mk new file mode 100644 index 0000000..6ac072a --- /dev/null +++ b/apps/EmbeddedIOP/function_sdio/rules.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +# +# SDIO driver +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_FUNCTION_SDIO=1 +IOP_FUNCTIONS += SDIO + +ALL_OBJS += $(LOCAL_DIR)/iop_sdio.o $(LOCAL_DIR)/iop_sdio_wrapper.o + +INSTALL_HEADERS += $(LOCAL_DIR)/iop_sdio_protocol.h + +# XXX tune this to suit SDIO requirements +IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),8192) + diff --git a/apps/EmbeddedIOP/iop.h b/apps/EmbeddedIOP/iop.h new file mode 100644 index 0000000..67d7bd5 --- /dev/null +++ b/apps/EmbeddedIOP/iop.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +#define IOP_MESSAGE_NO_WAIT 0 +#define IOP_MESSAGE_WAIT_FOREVER 0xffffffff /* actually a bit more than an hour */ + +extern void iop_message_trace(const char *ident, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3); + +/* + * Magic for hooking up IOP functions. + */ +struct iop_function { + const char *function_name; + int (* entrypoint)(void *cfg); + int stack_allocation; + int control_channel; +}; + +#define IOP_FUNCTION(_function_name, _entrypoint, _stack_allocation, _control_channel) \ +static const struct iop_function \ +__attribute__ ((used)) \ +__iop_function_##_function_name = { \ + #_function_name, \ + _entrypoint, \ + _stack_allocation, \ + _control_channel \ +}; \ +LINKER_SET_ENTRY(iop_function, __iop_function_##_function_name); + +/* + * IOP sleep/wake notifications + */ + +struct iop_sleep_hook { + void ( *func)(int mode); +}; +#define IOP_SLEEP_MODE_SLEEPING 0 +#define IOP_SLEEP_MODE_WAKING 1 + +#define IOP_SLEEP_HOOK(_name, _hook_function) \ +static const struct iop_sleep_hook \ +__attribute__ ((used)) \ +__iop_sleep_hook_##_name = { \ + _hook_function \ +}; \ +LINKER_SET_ENTRY(iop_sleep_hook, __iop_sleep_hook_##_name); diff --git a/apps/EmbeddedIOP/main.c b/apps/EmbeddedIOP/main.c new file mode 100644 index 0000000..d8b7f34 --- /dev/null +++ b/apps/EmbeddedIOP/main.c @@ -0,0 +1,618 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iop.h" +#include "qwi.h" +#include "qwi_protocol.h" +#include "EmbeddedIOPProtocol.h" +#include "clock_management.h" +#include "clock_stepping.h" + +/* XXX should get these automagically */ +#if WITH_FUNCTION_SDIO +extern int iop_sdio_task(void *arg); +#endif + +/* configuration, patched by host before we start */ +struct iop_configuration _iop_config = { + .magic = IOP_CONFIG_MAGIC +}; + +static int host_channel; + +static struct task_event host_command_event; + +static int iop_message_channel; +static struct task_event iop_message_event; +static struct task_event iop_console_event; +static union iop_message *iop_message_buffer; +static bool iop_suspended; +struct iop_ping_tracker gControlMessages[128]; +int gControlMessageCount = 0; + +static int no_idle_task(void *arg __unused); +static int host_command_task(void *cfg); +static void host_command_hook(void *user_data); +static bool host_command_process(void); + +static union iop_message *iop_message_alloc(utime_t allowed_delay); +static void iop_message_wakeup(void *arg __unused); +static void iop_message_tty(CBUFFER *pcb); +static int host_console_task(void *arg __unused); + +/* the host command task is just another function */ +IOP_FUNCTION(iop, host_command_task, 1024, IOP_CONTROL_CHANNEL); + +/* sleep/wakeup hook */ +static void sleep_hook(int mode); +IOP_SLEEP_HOOK(iop, sleep_hook); + +/* console */ +CBUFFER console_buffer; +#ifndef APPLICATION_CONSOLE_BUFFER +# define APPLICATION_CONSOLE_BUFFER 256 +#endif + +/* NMI */ +static void iop_nmi_handler(void *junk); + +#if DEBUG_BUILD +static char logo[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x2f, 0x5c, 0x2c, 0x25, 0x2c, 0x5f, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, + 0x25, 0x25, 0x25, 0x2f, 0x2c, 0x5c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x2e, 0x2d, 0x22, 0x25, + 0x25, 0x7c, 0x2f, 0x2f, 0x25, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2e, 0x27, 0x20, 0x20, 0x2e, 0x2d, 0x22, 0x20, + 0x20, 0x2f, 0x25, 0x25, 0x25, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x46, 0x4f, 0x52, 0x20, 0x50, 0x4f, 0x4e, 0x59, 0x21, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x2e, 0x2d, 0x27, 0x5f, 0x2e, 0x2d, + 0x22, 0x20, 0x30, 0x29, 0x20, 0x20, 0x20, 0x5c, 0x25, 0x25, 0x25, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2e, 0x5c, 0x2e, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x25, 0x25, + 0x25, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x2f, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x5f, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x25, 0x25, 0x25, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x22, + 0x2d, 0x2d, 0x2d, 0x22, 0x7e, 0x60, 0x5c, 0x20, 0x20, 0x20, 0x5f, 0x2c, + 0x2a, 0x27, 0x5c, 0x25, 0x25, 0x27, 0x20, 0x20, 0x20, 0x5f, 0x2c, 0x2d, + 0x2d, 0x22, 0x22, 0x22, 0x22, 0x2d, 0x2c, 0x25, 0x25, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x29, 0x2a, 0x5e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x22, + 0x22, 0x7e, 0x7e, 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x5c, 0x25, 0x25, 0x25, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x2f, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5c, 0x25, 0x25, 0x25, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x5f, 0x2e, 0x2d, 0x60, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7c, 0x25, + 0x25, 0x2c, 0x5f, 0x5f, 0x5f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, + 0x2e, 0x2d, 0x22, 0x20, 0x20, 0x20, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0x7c, + 0x25, 0x25, 0x20, 0x20, 0x20, 0x2e, 0x60, 0x5c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x2f, 0x5c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x5c, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x5c, 0x25, 0x27, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x2f, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x5c, 0x20, 0x5f, 0x2c, 0x2f, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x60, 0x7e, 0x2d, 0x2e, 0x5f, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x2c, 0x60, 0x5c, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x60, 0x22, 0x22, 0x7e, 0x7e, + 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x22, 0x60, 0x20, 0x2f, + 0x2d, 0x2e, 0x2c, 0x5f, 0x20, 0x2f, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x60, 0x7e, 0x22, 0x2d, 0x2d, 0x2d, 0x2d, 0x22, 0x7e, 0x20, 0x20, + 0x20, 0x20, 0x60, 0x5c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x0a, 0x20, + 0x20, 0x20, 0x6a, 0x67, 0x73, 0x20, 0x20, 0x20, 0x5c, 0x5f, 0x5f, 0x5f, + 0x2c, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5c, 0x2e, 0x2d, 0x22, 0x60, 0x2f, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, + 0x2d, 0x2d, 0x27, 0x0a, 0x00 +}; +#endif + +int +_main(void) +{ + void **func_cursor; + const struct iop_function *func; + +#if DEBUG_BUILD + printf("\n%s", logo); +#endif + dprintf(DEBUG_INFO, "####\n#### " CONFIG_PROGNAME_STRING ": " XBS_BUILD_TAG "\n####\n"); + + /* initialize the cpu */ + dprintf(DEBUG_INFO, "doing CPU init\n"); + arch_cpu_init(false); + + /* do early initialization of hardware */ + dprintf(DEBUG_INFO, "doing early platform hardware init\n"); + platform_early_init(); + + /* bring up system services (cpu, tasks, callout) */ + dprintf(DEBUG_INFO, "doing system init\n"); + sys_init(); + +#ifdef HEAP_EXT_SIZE + /* + * If we have extra memory for the heap, add it. This needs + * to happen after main memory has been initialized. + */ + dprintf(DEBUG_INFO, "Adding %llu bytes at %p to heap.\n", HEAP_EXT_SIZE, (void *)HEAP_EXT_BASE); + heap_add_chunk((void *)HEAP_EXT_BASE, HEAP_EXT_SIZE, true); +#endif + + /* register our doorbell handler and enable the doorbell */ + platform_init_iop_doorbell((int_handler)qwi_doorbell, NULL); + + /* + * Start the host console task and give it a chance to run, so that we have + * a console past this point. + */ + task_start(task_create("console", host_console_task, NULL, 512)); + task_yield(); + + /* + * Iterate IOP function tasks, starting each as we go. + */ + LINKER_SET_FOREACH(func_cursor, iop_function) { + func = (const struct iop_function *)*func_cursor; + if (NULL != func->entrypoint) { + dprintf(DEBUG_INFO, "starting %s\n", func->function_name); + task_start(task_create( + func->function_name, + func->entrypoint, + (void *)&_iop_config.channel[func->control_channel], + func->stack_allocation)); + } + } +#if DEBUG_BUILD + dprintf(DEBUG_INFO, "starting debug console\n"); + task_start(task_create("menu", menu_task, NULL, 8192)); +#endif + + /* start the slopsucker task if we don't want to go idle */ + if (_iop_config.options & IOP_OPTION_NO_IDLE) + task_start(task_create("slopsucker", no_idle_task, NULL, 512)); + + /* start the slopsucker task if we don't want to go idle */ + if (_iop_config.options & IOP_OPTION_DO_CLOCK_MGMNT) + SetParticipateInClockStateManagement(true); + + /* if the task manager needs retuning, do so */ + if (_iop_config.deep_idle_us != 0) + task_set_idle_threshold(_iop_config.deep_idle_us); + + /* register our NMI handler */ + platform_init_nmi(iop_nmi_handler, NULL); + + dprintf(DEBUG_INFO, "bootstrap task terminating\n"); + + task_exit(0); +} + + +/* + * This task is run when we don't want the IOP to idle, normally when + * JTAG debugging is enabled on the host. + */ +static int +no_idle_task(void *arg __unused) +{ + for (;;) { + task_yield(); + } + return(0); +} + +static int +host_command_task(void *cfg) +{ + struct iop_channel_config *channel = (struct iop_channel_config *)cfg; + + dprintf(DEBUG_INFO, "## IOP control task starting\n"); + + /* establish the host communications channel */ + event_init(&host_command_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dprintf(DEBUG_INFO, "## opening host channel\n"); + host_channel = qwi_instantiate_channel( + "iop control", + QWI_ROLE_CONSUMER, + channel->ring_size, + (void *)mem_static_map_cached(channel->ring_base), + host_command_hook, + &host_command_event); + + iop_suspended = false; + for (;;) { + /* + * Spin handling host commands + */ + while (host_command_process()) + ; + + if (!iop_suspended) { + /* + * Normal operation; wait for an event signalling new work. + */ + dprintf(DEBUG_SPEW, "## waiting for host command\n"); + event_wait(&host_command_event); + } else { + /* + * We are suspended; act as though we had received a doorbell + * interrupt. + */ + host_command_hook(&host_command_event); + } + } + return(0); +} + +static void +host_command_hook(void *user_data) +{ + struct task_event *event = (struct task_event *)user_data; + + /* pass it through to task context */ + event_signal(event); +} + +static bool +host_command_process(void) +{ + uint32_t message; + union iop_command *command; + bool do_sleep = false; + void **hook_cursor; + const struct iop_sleep_hook *hook; + struct idle_statistics stats; // XXX this is 'big', almost never used; ok on stack? + + /* look to see if there's an item waiting for us */ + if (qwi_receive_item(host_channel, &message) == -1) + return(false); + + /* find the command structure based on the message */ + command = (union iop_command *)mem_static_map_cached(message); + if (command == MAP_FAILED) + panic("received bad command pointer on control channel"); + + /* + * Flush any cached item contents we might have lying around - we are guaranteed + * that the command size is a multiple of our cacheline size. + */ + platform_cache_operation(CACHE_INVALIDATE, (void *)command, sizeof(*command)); + + switch (command->generic.opcode) { + case IOP_CMD_NOP: +// dprintf(DEBUG_INFO, "## host NOP\n"); + // Store information on ping commands received, in a global structure + // For use during debug of watchdog time outs + command->generic.result = IOP_RESULT_SUCCESS; + gControlMessages[gControlMessageCount].timestamp = timer_get_ticks(); + gControlMessages[gControlMessageCount].record.opcode = command->ping.opcode; + gControlMessages[gControlMessageCount].record.result = command->ping.result; + gControlMessages[gControlMessageCount].record.ping_id = command->ping.ping_id; + gControlMessageCount = (gControlMessageCount + 1) % 128; + break; + + case IOP_CMD_TTYIN: + debug_pushchar(command->ttyin.c); + command->generic.result = IOP_RESULT_SUCCESS; + break; + + case IOP_CMD_SLEEP: + dprintf(DEBUG_INFO, "## host SLEEP\n"); + do_sleep = true; + command->generic.result = IOP_RESULT_SUCCESS; + break; + + case IOP_CMD_SUSPEND: + dprintf(DEBUG_INFO, "## host SUSPEND\n"); + iop_suspended = true; + platform_cache_operation(CACHE_CLEAN, 0, 0); + command->generic.result = IOP_RESULT_SUCCESS; + break; + + case IOP_CMD_RESUME: + dprintf(DEBUG_INFO, "## host RESUME\n"); + iop_suspended = false; + command->generic.result = IOP_RESULT_SUCCESS; + break; + + case IOP_CMD_INSTRUMENT: + dprintf(DEBUG_INFO, "## host INSTRUMENT\n"); + iop_suspended = false; + task_get_statistics(& stats); + command->generic.result = IOP_RESULT_SUCCESS; + command->instr.uptime_ticks = stats.uptime_ticks; + command->instr.idles = stats.idles; + command->instr.deep_idles = stats.deep_idles; + command->instr.deep_idle_ticks = stats.deep_idle_ticks; + command->instr.idle_ticks = stats.idle_ticks; + command->instr.threshold_us = stats.threshold_us; + command->instr.ticksHz = stats.ticksHz; + break; + + default: + dprintf(DEBUG_CRITICAL, "## unrecognised host opcode 0x%x in command %p\n", command->generic.opcode, command); + command->generic.result = IOP_RESULT_ERROR; + break; + } + + /* this should never fail because we just pulled an item out and so we must own a slot */ + platform_cache_operation(CACHE_CLEAN, (void *)command, sizeof(*command)); + qwi_send_item(host_channel, message); + + /* sleep *after* we have replied */ + if (do_sleep) { + + /* tell anyone that cares that we're sleeping */ + LINKER_SET_FOREACH(hook_cursor, iop_sleep_hook) { + hook = (const struct iop_sleep_hook *)*hook_cursor; + hook->func(IOP_SLEEP_MODE_SLEEPING); + } + + /* go to sleep */ + platform_sleep(); + + /* and tell them we've woken up again */ + LINKER_SET_FOREACH(hook_cursor, iop_sleep_hook) { + hook = (const struct iop_sleep_hook *)*hook_cursor; + hook->func(IOP_SLEEP_MODE_WAKING); + } + } + + return(true); +} + +static void +sleep_hook(int mode) +{ + switch(mode) { + case IOP_SLEEP_MODE_WAKING: + dprintf(DEBUG_INFO, "enabling doorbell\n"); + platform_unmask_doorbell(); + // On some system (like AE2), put the system into lowest power state + // SetClockState will be no-op on other systems + SetClockState(kClockRequestPowerManager, kClockValueLow); + break; + + case IOP_SLEEP_MODE_SLEEPING: + dprintf(DEBUG_INFO, "disabling doorbell\n"); + // on some system(like AE2), restore clocks to high before we go to sleep + SetClockState(kClockRequestPowerManager, kClockValueHigh); + platform_mask_doorbell(); + break; + } +} + + +/* + * Putchar hook. + */ + +char gIOPPanicLog[IOP_PANIC_LOG_SIZE]; +u_int32_t gIOPPanicBytes; + +void +application_putchar(int c) +{ + /* if we are panicking, append the data to the panic log */ + if (NULL != gPanicStr) { + /* + * Printf emits nuls because it's not smart enough to tell the difference between + * strings and streams, so strip them here. + */ + if ((0 != c) && (gIOPPanicBytes < IOP_PANIC_LOG_SIZE)) + gIOPPanicLog[gIOPPanicBytes++] = c; + + } else { + /* + * If we have a console buffer, and this isn't a nul, try to stuff it + * there and wake up the output task. + */ + if ((true == cb_initialized(&console_buffer)) && (0 != c)) { +#if APPLICATION_CONSOLE_RELIABLE + /* Try to be lossless - yield if the buffer is full */ + while (!cb_free_space(&console_buffer)) { + task_yield(); + } +#endif + (void)cb_putc(&console_buffer, c); + event_signal(&iop_console_event); + } + } +} + +/* + * NMI handling + */ +static void +iop_nmi_handler(void *junk) +{ + panic("NMI"); +} + +/******************************************************************************* + * IOP-to-host messaging support + * + * N.B. Since this is used to carry console output, (d)printf should not be + * called in this code. + */ + +/* + * Allocate a message to send to the host. + * + * Note that it is not safe to block between allocating a message and sending it. + */ +static union iop_message * +iop_message_alloc(utime_t allowed_delay) +{ + utime_t deadline, t; + int idx; + + /* nothing we can do if we don't have a buffer */ + if (NULL == iop_message_buffer) + return(NULL); + + /* try to get a slot right away */ + if (-1 != (idx = qwi_next_send_index(iop_message_channel))) + return(iop_message_buffer + idx); + if (IOP_MESSAGE_NO_WAIT == allowed_delay) + return(NULL); + + /* spin waiting for a free slot */ + deadline = system_time() + allowed_delay; + for (;;) { + /* get the current time and see if we've timed out */ + t = system_time(); + if (t >= deadline) + return(NULL); + + /* sleep waiting for notification or timeout */ + event_wait_timeout(&iop_message_event, deadline - t); + + /* try again to get a message slot */ + if (-1 != (idx = qwi_next_send_index(iop_message_channel))) + return(iop_message_buffer + idx); + } +} + +/* + * Reclaim a message the host has accepted. + */ +static void +iop_message_wakeup(void *arg __unused) +{ + bool replies; + uint32_t message; + + /* reap message replies */ + replies = false; + while (qwi_receive_item(iop_message_channel, &message) != -1) + replies = true; + + /* if we got at least one reply, wake anyone trying to send */ + if (replies) + event_signal(&iop_message_event); +} + +/* + * Try to send a trace message to the host. + */ +void +iop_message_trace(const char *ident, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3) +{ + union iop_message *msg; + uint64_t timestamp; + + /* get the raw time shared with the host */ + timestamp = timer_get_ticks(); + + /* now get a message - wait a little while for it but not forever as we might deadlock the host */ + if (NULL != (msg = iop_message_alloc(1000))) { + + /* populate the message */ + msg->gen.opcode = IOP_MSG_TRACE; + msg->gen.size = sizeof(msg->trace); + msg->trace.ident = mem_static_map_physical((uint32_t)ident); + msg->trace.arg[0] = arg0; + msg->trace.arg[1] = arg1; + msg->trace.arg[2] = arg2; + msg->trace.arg[3] = arg3; + msg->trace.timestamp = timestamp; + + /* push it to memory */ + platform_cache_operation(CACHE_CLEAN, msg, IOP_MESSAGE_MAX); + + /* and give it to the host */ + qwi_send_item(iop_message_channel, QWI_ENCODE_ORDINAL(msg - iop_message_buffer)); + } +} + +/* + * Try to send a tty message to the host. + */ +static void +iop_message_tty(CBUFFER *pcb) +{ + union iop_message *msg; + unsigned int count; + + /* get a message */ + if (NULL == (msg = iop_message_alloc(IOP_MESSAGE_WAIT_FOREVER))) + panic("the console is dead, Jim"); + + /* get as many bytes from the cbuffer into our message as we can */ + count = cb_read(pcb, (unsigned char *)msg->tty.bytes, IOP_MSG_TTY_MAXLEN); + msg->gen.opcode = IOP_MSG_TTY; + msg->gen.size = sizeof(msg->gen) + count; + + /* push it to memory */ + platform_cache_operation(CACHE_CLEAN, msg, IOP_MESSAGE_MAX); + + /* and give it to the host */ + qwi_send_item(iop_message_channel, QWI_ENCODE_ORDINAL(msg - iop_message_buffer)); +} + +/* + * Buffer task outputting to the console. + */ +static int +host_console_task(void *arg __unused) +{ + + /* allocate a cbuffer for host console output */ + cb_create(&console_buffer, APPLICATION_CONSOLE_BUFFER); + + /* establish the message channel */ + iop_message_buffer = (union iop_message *)mem_static_map_cached(_iop_config.message_buffer); + event_init(&iop_message_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(&iop_console_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dprintf(DEBUG_INFO, "## opening IOP message channel\n"); + iop_message_channel = qwi_instantiate_channel( + "iop message", + QWI_ROLE_PRODUCER, + _iop_config.channel[IOP_MESSAGE_CHANNEL].ring_size, + (void *)mem_static_map_cached(_iop_config.channel[IOP_MESSAGE_CHANNEL].ring_base), + iop_message_wakeup, + NULL); + + for (;;) { + /* drain the console buffer */ + while (cb_readable_size(&console_buffer) > 0) + iop_message_tty(&console_buffer); + /* wait for more */ + event_wait(&iop_console_event); + } + + return(0); +} + diff --git a/apps/EmbeddedIOP/qwi.c b/apps/EmbeddedIOP/qwi.c new file mode 100644 index 0000000..4070b68 --- /dev/null +++ b/apps/EmbeddedIOP/qwi.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include + +#include "qwi_protocol.h" +#include "qwi.h" + +#ifndef QWI_MAX_CHANNELS +# error Must define QWI_MAX_CHANNELS +#endif + +typedef struct qwi_channel { + const char *qwc_name; + int qwc_role; + int qwc_ring_size; + int qwc_next_in; + int qwc_next_out; + qwi_workitem_t qwc_work_items; + qwi_channel_hook qwc_user_hook; + void *qwc_user_data; + +#if DEBUG_BUILD +# define QWC_STAT_INCR(_cp, _name) do {(_cp)->qwc_stat_##_name++; } while(0) + int qwc_stat_messages; +#else +# define QWC_STAT_INCR(_cp, _name) do { } while(0) +#endif +} *qwi_channel_t; + +/* fetch pointer to workitem */ +#define QWC_WORKITEM(_cp, _index) \ + ((_cp)->qwc_work_items + (_index)) + +/* compute next workitem index */ +#define QWC_ADVANCE(_cp, _index) \ + ((((_index) + 1) >= (_cp)->qwc_ring_size) ? 0 : ((_index) + 1)) + +static int qwi_channel_count; +static struct qwi_channel qwi_channels[QWI_MAX_CHANNELS]; + +/****************************************************************************** + * qwi_instantiate_channel + * + * Create a new channel endpoint using workitems from item_pool. + */ +int +qwi_instantiate_channel( + const char *name, + int role, + int ring_size, + void *item_pool, + qwi_channel_hook hook, + void *user_data) +{ + qwi_workitem_t ip; + qwi_channel_t cp; + int i, handle; + + ASSERT((role == QWI_ROLE_PRODUCER) || (role == QWI_ROLE_CONSUMER)); + ASSERT(qwi_channel_count < QWI_MAX_CHANNELS); + ASSERT(item_pool != NULL); + + qwi_enter_critical(); + + cp = &qwi_channels[qwi_channel_count]; + + /* init the channel */ + cp->qwc_name = name; + cp->qwc_role = role; + cp->qwc_ring_size = ring_size; + cp->qwc_work_items = item_pool; + cp->qwc_user_hook = hook; + cp->qwc_user_data = user_data; + + handle = qwi_channel_count++; + + /* ring initially belongs to the producer, so claim it if we are */ + if (role == QWI_ROLE_PRODUCER) { + for (i = 0; i < ring_size; i++) { + ip = QWC_WORKITEM(cp, i); + ip->qwi_control = QWI_OWNER_PRODUCER; + qwi_cache_store_line(ip); + } + cp->qwc_next_in = ~0; + cp->qwc_next_out = 0; + dprintf(DEBUG_INFO, "allocated producer %d with %d slots, item size %zu\n", + handle, ring_size, sizeof(*ip)); + } else { + cp->qwc_next_in = 0; + cp->qwc_next_out = ~0; + dprintf(DEBUG_INFO, "allocated consumer %d with %d slots, item size %zu\n", + handle, ring_size, sizeof(*ip)); + } + + /* success */ + qwi_exit_critical(); + + return(handle); +} + +/****************************************************************************** + * qwi_send_item + * + * Send the next work item to the other end of the channel. + */ +int +qwi_send_item(int channel_handle, uint32_t message) +{ + qwi_workitem_t ip; + qwi_channel_t cp; + + ASSERT((channel_handle >= 0) && (channel_handle < qwi_channel_count)); + + /* verify item data is aligned correctly */ + ASSERT(message == (message & QWI_ADDRESS_MASK)); + + qwi_enter_critical(); + cp = &qwi_channels[channel_handle]; + + /* if we have no items free to go, we can't do this */ + if (cp->qwc_next_out == ~0) + goto fail; + + /* find the next item for this channel */ + ip = QWC_WORKITEM(cp, cp->qwc_next_out); + + /* set data and assign ownership to the other end */ + ip->qwi_control = QWI_CONTROL(message, cp->qwc_role ^ QWI_OWNER_MASK); + + /* if we didn't have anything outstanding before, we do now */ + if (cp->qwc_next_in == ~0) + cp->qwc_next_in = cp->qwc_next_out; + + /* find the next item we can send */ + cp->qwc_next_out = QWC_ADVANCE(cp, cp->qwc_next_out); + + /* if we have sent the last item, we have nothing free to go */ + if (cp->qwc_next_in == cp->qwc_next_out) + cp->qwc_next_out = ~0; + + /* ensure the item is visible to the consumer */ + qwi_cache_store_line(ip); + + QWC_STAT_INCR(cp, messages); + qwi_exit_critical(); + + /* ring the doorbell */ + qwi_ring_doorbell(); + + return(0); +fail: + qwi_exit_critical(); + return(-1); +} + +/****************************************************************************** + * qwi_receive_item + * + * Receive the next incoming item from the other end of the channel. + */ +int +qwi_receive_item(int channel_handle, uint32_t *message) +{ + qwi_workitem_t ip; + qwi_channel_t cp; + + ASSERT((channel_handle >= 0) && (channel_handle < qwi_channel_count)); + ASSERT(message != NULL); + + qwi_enter_critical(); + + cp = &qwi_channels[channel_handle]; + + /* if we own the entire ring, there's nothing waiting for us */ + if (cp->qwc_next_in == ~0) + goto fail; + + /* find the next item for this channel */ + ip = QWC_WORKITEM(cp, cp->qwc_next_in); + + /* make sure that we own it */ + qwi_cache_invalidate_line(ip); + if (!QWI_ITEM_TEST_OWNER(ip, cp->qwc_role)) + goto fail; + + /* we do, so pass the reply pointer back */ + *message = QWI_ITEM_ADDRESS(ip); + + /* if we didn't have anything free to send with, we do now */ + if (cp->qwc_next_out == ~0) + cp->qwc_next_out = cp->qwc_next_in; + + /* find the next item coming in */ + cp->qwc_next_in = QWC_ADVANCE(cp, cp->qwc_next_in); + + /* if we've received the last item, we own the entire ring again */ + if (cp->qwc_next_out == cp->qwc_next_in) + cp->qwc_next_in = ~0; + + QWC_STAT_INCR(cp, messages); + qwi_exit_critical(); + + return(0); +fail: + qwi_exit_critical(); + return(-1); +} + + +/****************************************************************************** + * qwi_peek_item + * + * Peek at the next item from the other end of the channel. + */ +int +qwi_peek_item(int channel_handle, uint32_t *message) +{ + qwi_workitem_t ip; + qwi_channel_t cp; + + ASSERT((channel_handle >= 0) && (channel_handle < qwi_channel_count)); + + qwi_enter_critical(); + + cp = &qwi_channels[channel_handle]; + + /* if we own the entire ring, there's nothing waiting for us */ + if (cp->qwc_next_in == ~0) + goto fail; + + /* find the next item for this channel */ + ip = QWC_WORKITEM(cp, cp->qwc_next_in); + + /* make sure that we own it */ + qwi_cache_invalidate_line(ip); + if (!QWI_ITEM_TEST_OWNER(ip, cp->qwc_role)) + goto fail; + + /* we do, so pass the reply pointer back */ + if (message) + *message = QWI_ITEM_ADDRESS(ip); + + qwi_exit_critical(); + return(0); +fail: + qwi_exit_critical(); + return(-1); +} + +/****************************************************************************** + * qwi_next_send_index + * + * Return the ring index of the next item that will be sent for the given + * channel. + * + * For protocols that operate strictly in-order this allows the client to avoid + * separately managing their command buffers. + */ +int +qwi_next_send_index(int channel_handle) +{ + qwi_channel_t cp; + int result; + + ASSERT((channel_handle >= 0) && (channel_handle < qwi_channel_count)); + + qwi_enter_critical(); + cp = &qwi_channels[channel_handle]; + + result = (cp->qwc_next_out == ~0) ? -1 : cp->qwc_next_out; + + qwi_exit_critical(); + return(result); +} + +/****************************************************************************** + * qwi_doorbell + * + * Called when the doorbell is rung by the other end. + */ +void +qwi_doorbell(void) +{ + qwi_channel_t cp; + int i, count; + + qwi_enter_critical(); + count = qwi_channel_count; + qwi_exit_critical(); + + /* + * Iterate the channel set, and for channels that have user hooks + * and which have at least one pending item, call the hook. + */ + for (i = 0; i < count; i++) { + cp = &qwi_channels[i]; + if ((cp->qwc_user_hook) && (0 == qwi_peek_item(i, NULL))) + cp->qwc_user_hook(cp->qwc_user_data); + } +} + +#if WITH_MENU + +static int +qwi_dump(int argc __unused, struct cmd_arg *args __unused) +{ + qwi_workitem_t ip; + qwi_channel_t cp; + int chn, i; + + for (chn = 0; chn < qwi_channel_count; chn++) { + cp = &qwi_channels[chn]; + printf("%02d(%s): %s, 0x%x slots, next in 0x%x, next out 0x%x, ring at %p\n", + chn, + cp->qwc_name, + (cp->qwc_role == QWI_ROLE_PRODUCER) ? "producer" : "consumer", + cp->qwc_ring_size, + cp->qwc_next_in, + cp->qwc_next_out, + cp->qwc_work_items); +#if DEBUG_BUILD + printf(" %d messages passed\n", cp->qwc_stat_messages); +#endif + for (i = 0; i < cp->qwc_ring_size; i++) { + ip = QWC_WORKITEM(cp, i); + printf(" %02d@%p: 0x%08x %c %c\n", + i, ip, + ip->qwi_control & QWI_ADDRESS_MASK, + ((ip->qwi_control & QWI_OWNER_MASK) == QWI_ROLE_PRODUCER) ? 'P' : 'C', + (i == cp->qwc_next_in) ? 'i' : (i == cp->qwc_next_out) ? 'o' : ' '); + } + } + return(0); +} + +MENU_COMMAND_DEBUG(qwi, qwi_dump, "print QWI channels", NULL); +#endif diff --git a/apps/EmbeddedIOP/qwi.h b/apps/EmbeddedIOP/qwi.h new file mode 100644 index 0000000..6527a5c --- /dev/null +++ b/apps/EmbeddedIOP/qwi.h @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* + * Queued Work Item protocol library. + * + * + * QWI provides a mechanism for passing work items between processors using + * shared memory and a doorbell interrupt. It is a straightforward design using + * common techniques. + * + * This library supports multiple instances of the QWI protocol (channels) + * operating in either directioion with a single remote endpoint. There is + * assumed to be a single doorbell available at either end. + * + * A QWI channel comprises a fixed-size ring of items. The ring should be sized + * to account for doorbell latency and to permit coalescing of doorbell + * interrupts; it need not be large if the work item throughput is low. + * + * Each channel moves work items in one direction and responses in the other. + * For command/response oriented communication, one channel is thus sufficient. + * For asynchronous interactions, a channel is required in each direction. The + * parties at each end of a channel are referred to as the producer and the + * consumer respectively. + * + * Work items in the ring are owned by either the producer or the consumer. + * Ownership is tracked by a single bit, which can only be set by the current + * owner. Ownership changes always move forwards in the ring, they are never made + * out of order. For example, this ring of eight work items has three currently + * owned by the consumer: + * + * 0 1 2 3 4 5 6 7 + * C C C P P P P P + * + * Work item 0 is always returned to the producer before item 1 is returned. + * + * The payload of a work item is a client-supplied pointer. QWI does not manage + * coherency for the payload; this is a client responsibility. + * + * When attention is signalled via the doorbell, the doorbell must be + * acknowledged and re-armed before any check is made of channels in order to + * prevent items being lost and the queue potentially stalling. + * + * + * The following parameters must be defined: + * + * QWI_MAX_CHANNELS + * + * Establishes the size of the channel table. + * + */ + +#include + +/* must match the protocol definition */ +#define QWI_MESSAGE_ALIGNMENT 64 + +/* must match QWI_OWNER_* values in the protocol definition */ +#define QWI_ROLE_CONSUMER 0 +#define QWI_ROLE_PRODUCER 1 + +typedef void (* qwi_channel_hook)(void *user_data); + +/****************************************************************************** + * API + */ + +extern int qwi_instantiate_channel( + const char *name, + int role, + int ring_size, + void *item_pool, + qwi_channel_hook hook, + void *user_data); +/* + * Instantiates a new channel endpoint and returns a corresponding + * channel handle. Endpoints must be co-ordinated between the + * processors; there is no setup channel. + * + * role + * One of QWI_ROLE_PRODUCER or QWI_ROLE_CONSUMER depending + * on whether the endpoint is the producer or consumer. + * + * ring_size + * The number of entries in the ring. + * + * item_pool + * The buffer allocated for ring items. This can be sized by the + * client using the QWI_POOOL_SIZE() macro. The pool must be + * in uncached memory. + * + * hook + * user_data + * If a hook is supplied for the channel, when the doorbell is + * rung the hook will be called with user_data as an argument. + */ + +extern int qwi_send_item(int channel_handle, uint32_t message); +/* + * Sends a work item to the other end of the channel. + * + * Any memory referenced by item_data should be in a state where it may + * be instantly consumed by the other processor. + * + * Returns -1 if there are no free work items available. + * + * channel_handle + * A handle returned from qwi_instantiate_channel(). + * + * message + * The message to be passed to the other end. + */ + +extern int qwi_receive_item(int channel_handle, uint32_t *message); +/* + * Attempts to receive a work item. If successful, returns the message as + * supplied by the sender. + * + * Returns -1 if there are no waiting items to be received. + * + * channel_handle + * A handle returned from qwi_instantiate_channel(). + * + * message + * Local pointer storage for the value passed by the other end. + */ + +extern int qwi_peek_item(int channel_handle, uint32_t *message); +/* + * Attempts to peek a work item. If successful, returns the message as + * supplied by the sender. Does not remove the item from the queue. + * + * Returns -1 if there are no waiting items to be received. + * + * channel_handle + * A handle returned from qwi_instantiate_channel(). + * + * message + * Local pointer storage for the value passed by the other end. + */ + +extern int qwi_next_send_index(int channel_handle); +/* + * Returns the ring index for the next item to be sent on the given + * channel. If the index returned is -1 there are no free items to send. + * For protocols where items are sent and replied in strict order, the + * index can be used by the client to avoid tracking work item buffer + * ownership separately. + * + * Note that the client is required to co-ordinate between calls to + * qwi_next_send_index() and qwi_send_item() to avoid races. + * + * channel_handle + * A handle returned from qwi_instantiate_channel() + */ + +/****************************************************************************** + * Dependencies + */ + +#include +#include + +extern void qwi_doorbell(void); +/* + * Must be called when the local doorbell is rung. + */ + +/*extern void qwi_cache_store_line(void *address);*/ +static inline void qwi_cache_store_line(void *address) +{ + address = (void *)((uint32_t)address & ~(QWI_MESSAGE_ALIGNMENT - 1)); + platform_cache_operation(CACHE_CLEAN, address, QWI_MESSAGE_ALIGNMENT); +} +/* + * Causes the cache line containing (address) to be stored to coherent memory. + */ + +/*extern void qwi_cache_invalidate_line(void *address);*/ +static inline void qwi_cache_invalidate_line(void *address) +{ + address = (void *)((uint32_t)address & ~(QWI_MESSAGE_ALIGNMENT - 1)); + platform_cache_operation(CACHE_INVALIDATE, address, QWI_MESSAGE_ALIGNMENT); +} +/* + * Causes the cache line containing (address) to be invalidated, forcing the + * next access to read from coherent memory. + */ + +/*extern void qwi_ring_doorbell(void);*/ +static inline void qwi_ring_doorbell(void) +{ + platform_ring_host_doorbell(); +} +/* + * Rings the other processor's doorbell. + */ + +/*extern void qwi_enter_critical(void);*/ +/*extern void qwi_exit_critical(void);*/ +static inline void qwi_enter_critical(void) +{ + enter_critical_section(); +} +static inline void qwi_exit_critical(void) +{ + exit_critical_section(); +} +/* + * These calls are required to avoid re-entry of critical sections of the + * code. Note that the qwi_cache_*() functions must be safely callable + * from within the critical region. + */ diff --git a/apps/EmbeddedIOP/qwi_protocol.h b/apps/EmbeddedIOP/qwi_protocol.h new file mode 100644 index 0000000..39ad31f --- /dev/null +++ b/apps/EmbeddedIOP/qwi_protocol.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* + * Queued Work Item protocol. + * + * + * QWI provides a mechanism for passing work items between processors using + * shared memory and a doorbell interrupt. It is a straightforward design using + * common techniques. + * + * A QWI channel comprises a fixed-size ring of items. The ring should be sized + * to account for doorbell latency and to permit coalescing of doorbell + * interrupts; it need not be large if the work item throughput is low. + * + * Each channel moves work items in one direction and responses in the other. + * For command/response oriented communication, one channel is thus sufficient. + * For asynchronous interactions, a channel is required in each direction. The + * parties at each end of a channel are referred to as the producer and the + * consumer respectively. + * + * Work items in the ring are owned by either the producer or the consumer. + * Ownership is tracked by a single bit, which can only be set by the current + * owner. Ownership changes always move forwards in the ring, they are never made + * out of order. For example, this ring of eight work items has three currently + * owned by the consumer: + * + * 0 1 2 3 4 5 6 7 + * C C C P P P P P + * + * Work item 0 is always returned to the producer before item 1 is returned. + * + * The payload of a work item is a client-supplied pointer. QWI does not manage + * coherency for the payload; this is a client responsibility. + */ + +/* basic quantum of message passing */ +#define QWI_MESSAGE_ALIGNMENT 64 + +/* + * In order to avoid racing, the control and payload information must be stored + * atomically. + * + * It is assumed that stores of a uint32_t (when aligned) are atomic, and that + * user data is 4-byte aligned. + */ + +typedef union qwi_workitem { + uint32_t qwi_control; + char _pad[QWI_MESSAGE_ALIGNMENT]; +} *qwi_workitem_t; + +#define QWI_POOL_SIZE(_ring_count) ((_ring_count) * sizeof(union qwi_workitem)) + +/* ownership/role relation */ +#define QWI_OWNER_CONSUMER 0 +#define QWI_OWNER_PRODUCER 1 + +/* ownership mask */ +#define QWI_OWNER_MASK 1 + +/* bit 1 in qwi_control is reserved for later use */ + +/* address mask */ +#define QWI_ADDRESS_MASK (~(uint32_t)0x3) + +/* construct the qwi_control value */ +#define QWI_CONTROL(_address, _owner) \ + ((uint32_t)(_address) | (_owner)) + +/* fetch the address from a workitem */ +#define QWI_ITEM_ADDRESS(_ip) \ + (((_ip)->qwi_control & QWI_ADDRESS_MASK)) + +/* test ownership of a workitem */ +#define QWI_ITEM_TEST_OWNER(_ip, _who) \ + (((_ip)->qwi_control & QWI_OWNER_MASK) == (uint32_t)(_who)) + +/* en/decode a value so that it can be passed as though it were an item address */ +#define QWI_ENCODE_ORDINAL(_n) ((uint32_t)(_n) << 2) +#define QWI_DECODE_ORDINAL(_n) ((uint32_t)(_n) >> 2) diff --git a/apps/SecureROM/SecureROM.mk b/apps/SecureROM/SecureROM.mk new file mode 100644 index 0000000..726f97e --- /dev/null +++ b/apps/SecureROM/SecureROM.mk @@ -0,0 +1,90 @@ +# Copyright (C) 2007-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +############################################################################### +# Build rules for the SecureROM module. +# +# Recognises values in +# +# BUILDS +# TARGETS +# CONFIGS +# + +VALID_BUILDS := ROMRELEASE DEBUG +VALID_TARGETS := t8002 t8010 +VALID_CONFIGS := si fpga + +# support for temporarily turning off targets +SUPPRESSED_TARGETS := + +############################################################################### +# No user-serviceable parts below + +# DEVICEMAP macros +include makefiles/device_map.mk + +BUILDS ?= $(VALID_BUILDS) +MAKE_BUILDS = $(filter $(VALID_BUILDS), $(BUILDS)) + +CONFIGS ?= $(VALID_CONFIGS) +MAKE_CONFIGS = $(filter $(VALID_CONFIGS), $(CONFIGS)) + +# Consult the device map database for the set of platforms associated with +# at least one target. +MAP_TARGETS := $(DEVICEMAP_PLATFORMS) + +TARGETS ?= $(filter-out $(SUPPRESSED_TARGETS),$(MAP_TARGETS)) +MAKE_TARGETS = $(filter $(VALID_TARGETS), $(TARGETS)) + +MAKE_PRODUCT = SecureROM + +TC_LIST = $(foreach target, $(MAKE_TARGETS), $(addprefix $(target)-, $(MAKE_CONFIGS))) +LIST = $(foreach build, $(MAKE_BUILDS), $(addprefix $(build)-, $(TC_LIST))) + +LIST_TEMPLATE := $(addprefix %-,$(LIST)) +$(STANDARD_ACTIONS):%: $(LIST_TEMPLATE) +ACTIONS := $(foreach action,$(STANDARD_ACTIONS),$(addprefix $(action)-,$(LIST))) + +ROM_IMAGE_si := true +ROM_IMAGE_fpga := true + +build: $(BUILD) +install: $(INSTALL) +clean: $(CLEAN) + +$(ACTIONS): action = $(word 1, $(subst -, ,$@)) +$(ACTIONS): target = $(word 3, $(subst -, ,$@)) +$(ACTIONS): config = $(word 4, $(subst -, ,$@)) +$(ACTIONS): product = $(MAKE_PRODUCT) +$(ACTIONS): build = $(word 2, $(subst -, ,$@)) +$(ACTIONS): install_name = $(product).$(target)$(config).$(build) +$(ACTIONS): + @echo %%% $(action) $(target)$(config)-$(product)-$(build) + @$(MAKE) -f makefiles/main.mk \ + SUB_TARGET=$(target) \ + CONFIG=$(config) \ + PRODUCT=$(product) \ + BUILD=$(build) \ + ROM_IMAGE=$(ROM_IMAGE_$(config)) \ + ROM_IMAGE_SIZE=64k \ + INSTALL_NAME=$(install_name) \ + DEVMAP_EPOCH=$(call DEVICEMAP_EPOCH_FOR_PLATFORM,$(target)) \ + IMAGE_FORMAT=$(or $(call DEVICEMAP_IMGFMT_FOR_PLATFORM,$(target)), $(IMAGE_FORMAT)) \ + CRYPTO_HASH=$(call DEVICEMAP_CRYPTO_HASH_FOR_PLATFORM,$(target)) \ + $(action) + +help: + @echo Valid TARGETS + @echo " $(VALID_TARGETS)" + @echo Valid CONFIGS + @echo " $(VALID_CONFIGS)" + @echo Valid BUILDS + @echo " $(VALID_BUILDS)" + @echo "" diff --git a/apps/SecureROM/application.mk b/apps/SecureROM/application.mk new file mode 100644 index 0000000..a21f533 --- /dev/null +++ b/apps/SecureROM/application.mk @@ -0,0 +1,69 @@ +# Copyright (C) 2007-2010, 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +# +# Global headers that are independing of product, target, etc. +# +GLOBAL_HEADERS += \ + lib/mib/mib_nodes.h + +OPTIONS += \ + READ_ONLY=1 + +ifeq ($(CONFIG),si) +TEXT_AREA ?= ROM +endif + +ifeq ($(CONFIG),fpga) +TEXT_AREA ?= ROM +OPTIONS += \ + SUPPORT_FPGA=1 +endif + +ifeq ($(BUILD),ROMRELEASE) +OPTIONS += \ + DEBUG_LEVEL=DEBUG_SILENT \ + NO_PANIC_STRINGS=1 +endif + +OPTIONS += \ + IMAGE_MAX_COUNT=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/main.o + +MODULES += \ + lib/heap \ + lib/random \ + platform/defaults \ + platform/generic \ + sys + +ifeq ($(IMAGE_FORMAT),) +$(error "IMAGE_FORMAT not set") +endif +ifeq ($(IMAGE_FORMAT),im4p) +MODULES += \ + lib/image/image4 +OPTIONS += \ + WITH_UNTRUSTED_EXECUTION_ALLOWED=1 +else +$(error "IMAGE_FORMAT not supported") +endif + + +LIBRARY_MODULES += \ + lib/libc \ + lib/mib + +OPTIONS += \ + WITH_DFU_MODE=1 diff --git a/apps/SecureROM/config/t8002-config.mk b/apps/SecureROM/config/t8002-config.mk new file mode 100644 index 0000000..8d877d4 --- /dev/null +++ b/apps/SecureROM/config/t8002-config.mk @@ -0,0 +1,53 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +############################################################################### +# Target configuration for the t8002 SecureROM module +# + +PLATFORM := t8002 +ARCH := arm + +ifeq ($(CONFIG),fpga) + CONFIG_FPGA := true +endif + +# Memory configuration (consumed by the t8002 platform module) +ifeq ($(TEXT_AREA),ROM) +TEXT_BANK := srom +TEXT_FOOTPRINT := 512*1024 +endif + +MODULES += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/anc \ + drivers/apple/ausb \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/flash_nor/spi \ + drivers/samsung/spi \ + drivers/synopsys/usbotg + +ifeq ($(BUILD),DEBUG) +MODULES += \ + drivers/samsung/uart + +OPTIONS += \ + WITH_PLATFORM_UARTCONFIG=1 +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto diff --git a/apps/SecureROM/config/t8010-config-base.mk b/apps/SecureROM/config/t8010-config-base.mk new file mode 100644 index 0000000..3e9bd22 --- /dev/null +++ b/apps/SecureROM/config/t8010-config-base.mk @@ -0,0 +1,55 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +############################################################################### +# Target configuration for the t7000 SecureROM module +# + +PLATFORM := t8010 +ARCH := arm64 +HW_TIMER := architected + +# Memory configuration (consumed by the t8010 platform module) +ifeq ($(TEXT_AREA),ROM) +TEXT_BANK := srom +TEXT_FOOTPRINT := 512*1024 +endif + +MODULES += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/apcie \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/apcie \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dart_lpae \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/flash_nor/spi \ + drivers/nvme \ + drivers/pci \ + drivers/samsung/spi \ + drivers/synopsys/usbotg + +ifeq ($(BUILD),DEBUG) +MODULES += \ + drivers/samsung/uart + +OPTIONS += \ + WITH_PLATFORM_UARTCONFIG=1 +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto diff --git a/apps/SecureROM/config/t8010-config.mk b/apps/SecureROM/config/t8010-config.mk new file mode 100644 index 0000000..ff2830e --- /dev/null +++ b/apps/SecureROM/config/t8010-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +############################################################################### +# Target configuration for the T8010 SecureROM module +# + +SUB_PLATFORM := t8010 + +include $(GET_LOCAL_DIR)/t8010-config-base.mk diff --git a/apps/SecureROM/main.c b/apps/SecureROM/main.c new file mode 100644 index 0000000..81dd58a --- /dev/null +++ b/apps/SecureROM/main.c @@ -0,0 +1,371 @@ + /* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_USB_DFU +#include +#endif +#if WITH_TBT_DFU +#include +#endif +#if WITH_ANC_BOOT +# include +#endif + +#define USER_BUTTON_FORCEDFU_TIMEOUT (6 * 1000 * 1000) + +static void boot_selected(enum boot_device boot_device, u_int32_t boot_flag, u_int32_t boot_arg); + + +static struct image_info *lookup_image_in_bdev(const char *name, uint32_t type); +static bool load_selected_image(struct image_info *loaded_image, u_int32_t type, void *load_address, size_t load_length, u_int32_t boot_flag); +static void boot_loaded_image(void *load_address); + +int _main(void) +{ + bool force_dfu, force_reset; + utime_t dfu_time; + enum boot_device boot_device; + u_int32_t boot_flag, boot_arg; + int32_t index; + + /* initialize the cpu */ + arch_cpu_init(false); + + dprintf(DEBUG_CRITICAL, "\n" CONFIG_PROGNAME_STRING " start\n"); + + /* setup the default clock configuration */ + dprintf(DEBUG_INFO, "setting up initial clock configuration\n"); + platform_init_setup_clocks(); + + /* set up any internal memory (internal sram) */ + dprintf(DEBUG_INFO, "setting up internal memory\n"); + platform_init_internal_mem(); + + /* set up the default pin configuration */ + dprintf(DEBUG_INFO, "setting up default pin configuration\n"); + platform_init_hwpins(); + + /* Sample force_dfu and request_dfu pins. */ + force_dfu = platform_get_force_dfu(); + force_reset = platform_get_request_dfu1() && platform_get_request_dfu2(); + + /* bring up system services (cpu, tasks, callout, heap) */ + sys_init(); + + /* generate random stack cookie on platforms without a + requirement for fast resume from suspend-to-RAM via SecureROM */ +#if !WITH_NO_RANDOM_STACK_COOKIE + sys_init_stack_cookie(); +#endif + + /* do some early initialization of hardware */ + /* timers will start firing at this point */ + dprintf(DEBUG_INFO, "doing early platform hardware init\n"); + platform_early_init(); + + /* print version info now that UART is enabled on DEBUG builds */ + dprintf(DEBUG_INFO, "\n\n%s for %s\n", CONFIG_PROGNAME_STRING, CONFIG_BOARD_STRING); + dprintf(DEBUG_INFO, "%s\n", build_tag_string); + dprintf(DEBUG_INFO, "%s\n", build_style_string); + + /* initialize the rest of hardware */ + dprintf(DEBUG_INFO, "doing platform hardware init\n"); + platform_init(); + + /* Check for Force DFU Mode Pin */ + dprintf(DEBUG_INFO, "Checking for Force DFU Mode Pin: %x / %x\n", force_dfu, force_reset); + if (force_dfu && !platform_get_usb_cable_connected()) + force_dfu = false; + + /* Check for Force DFU Mode request pins. Requesting DFU mode is done + by asserting both REQUEST_DFU1 and REQUEST_DFU2, holding them for + the required time, then deasserting REQUEST_DFU1, followed by + deasserting REQUEST_DFU2 after another required hold time. + */ + dprintf(DEBUG_INFO, "Checking for Force DFU Mode request pins: %x / %x\n", force_dfu, force_reset); + if (!force_dfu && force_reset && platform_get_usb_cable_connected()) { + dfu_time = system_time(); + while (platform_get_request_dfu1() && platform_get_request_dfu2() && platform_get_usb_cable_connected()) { + if (time_has_elapsed(dfu_time, USER_BUTTON_FORCEDFU_TIMEOUT)) + break; + task_sleep(100 * 1000); + } + + dfu_time = system_time(); + while (!platform_get_request_dfu1() && platform_get_request_dfu2() && platform_get_usb_cable_connected()) { + if (time_has_elapsed(dfu_time, USER_BUTTON_FORCEDFU_TIMEOUT)) { + force_dfu = true; + break; + } + task_sleep(100 * 1000); + } + } + + /* Try the boot devices in order */ + index = 0; + + /* if DFU is being forced, set index to -1 for force dfu */ + dprintf(DEBUG_INFO, "Force DFU: %x\n", force_dfu); + if (force_dfu) index = -1; + + while (1) { + /* ask the platform code for the selected boot source */ + if (!platform_get_boot_device(index, &boot_device, &boot_flag, &boot_arg)) + break; + + /* Attempt to boot the selected device */ + boot_selected(boot_device, boot_flag, boot_arg); + + if (index < 0) + continue; + + index++; + } + + /* we are hosed */ + dprintf(DEBUG_INFO, "No valid boot device, resetting.\n"); + platform_reset(false); +} + +/* + * Attempt to boot the seleced device. + */ +static void +boot_selected(enum boot_device boot_device, uint32_t boot_flag, uint32_t boot_arg) +{ + struct image_info *loaded_image; + size_t loaded_length; + void *load_address; + size_t load_length; + bool loaded = false; + uint32_t type = IMAGE_TYPE_LLB; + + dprintf(DEBUG_INFO, "boot_selected: boot_device: %08x, boot_flag: %08x, boot_arg: %08x\n", + boot_device, boot_flag, boot_arg); + + /* Enable the pins for the selected boot device */ + platform_enable_boot_interface(true, boot_device, boot_arg); + + /* reset security and clear the insecure memory area */ + security_init(true); + + loaded_image = NULL; + loaded_length = 0; + load_address = (void *)INSECURE_MEMORY_BASE; + load_length = INSECURE_MEMORY_SIZE; + + /* ask the boot source to fetch the boot image */ + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI: + { + dprintf(DEBUG_INFO, "SPI NOR boot selected\n"); + + /* initialise the NOR flash for the desired channel */ + flash_nor_init(boot_arg); + + loaded_image = lookup_image_in_bdev("nor0", type); + if (loaded_image != NULL) + loaded_length = loaded_image->imageLength; + + break; + } +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ +#if WITH_ANC_BOOT + case BOOT_DEVICE_NAND: + { + if (!anc_reset(boot_arg)) { + dprintf(DEBUG_CRITICAL, "Failed to init ASP"); + break; + } + + loaded_length = anc_read_llb(load_address, load_length); + if (loaded_length > load_length) + panic("load overflow"); + + if (loaded_length > 0) { + if ((loaded_image = image_create_from_memory( + load_address, + loaded_length, + IMAGE_OPTION_LOCAL_STORAGE)) == NULL) { + dprintf(DEBUG_INFO, "image creating failed\n"); + } else { + dprintf(DEBUG_INFO, "loaded image from ANC\n"); + } + } + + break; + } +#endif +#if WITH_NVME + case BOOT_DEVICE_NVME: + { + loaded_image = lookup_image_in_bdev("nvme_firmware0", type); + if (loaded_image != NULL) + loaded_length = loaded_image->imageLength; + + break; + } +#endif +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU: + { + int result; + + /* Turn on the DFU STATUS pin */ + platform_set_dfu_status(true); + + /* Set type to iBSS */ + type = IMAGE_TYPE_IBSS; + + /* try to get an image via DFU */ + if ((result = getDFUImage(load_address, load_length)) < 0) { + dprintf(DEBUG_INFO, "fatal DFU download error"); + break; + } + + loaded_length = (size_t)result; + if (loaded_length > load_length) + panic("load overflow"); + + /* wrap the image */ + if ((loaded_image = image_create_from_memory(load_address, loaded_length, 0)) == NULL) { + dprintf(DEBUG_INFO, "failed to create image from DFU download\n"); + break; + } + + dprintf(DEBUG_INFO, "loaded image from USB-DFU\n"); + break; + } +#endif /* WITH_USB_DFU */ +#if WITH_TBT_DFU + case BOOT_DEVICE_TBTDFU: + { + int result; + + /* Set type to iBSS */ + type = IMAGE_TYPE_IBSS; + + /* try to get an image via DFU */ + if ((result = thunderboot_get_dfu_image(load_address, load_length)) < 0) { + dprintf(DEBUG_INFO, "fatal DFU download error"); + break; + } + + loaded_length = (size_t)result; + if (loaded_length > load_length) + panic("load overflow"); + + /* wrap the image */ + if ((loaded_image = image_create_from_memory(load_address, loaded_length, 0)) == NULL) { + dprintf(DEBUG_INFO, "failed to create image from DFU download\n"); + break; + } + + dprintf(DEBUG_INFO, "loaded image from TBT-DFU\n"); + break; + } +#endif /* WITH_USB_DFU */ +/* case BOOT_DEVICE_XMODEM: */ + default: + break; + } + + /* if we found an image, try to load it */ + if (loaded_image) { + loaded = load_selected_image(loaded_image, type, load_address, loaded_length, boot_flag); + image_free(loaded_image); + } else { + loaded = false; + } + + /* Disable the pins for the selected boot device */ + platform_enable_boot_interface(false, boot_device, boot_arg); + + if (loaded) + boot_loaded_image(load_address); + + /* load failed or boot source not supported */ + dprintf(DEBUG_INFO, "failed to load from selected boot device\n"); +} + +static struct image_info * +lookup_image_in_bdev(const char *name, uint32_t type) +{ + struct blockdev *boot_bdev; + struct image_info *loaded_image; + + /* look it up */ + if ((boot_bdev = lookup_blockdev(name)) == NULL) + return NULL; + + dprintf(DEBUG_INFO, "boot device %s initialised\n", name); + + /* look for the image directory in the expected location */ + if (image_search_bdev(boot_bdev, 0, IMAGE_OPTION_LOCAL_STORAGE) == 0) + return NULL; + dprintf(DEBUG_INFO, "found image directory on %s\n", name); + + /* look for the LLB */ + loaded_image = image_find(type); + + dprintf(DEBUG_INFO, "%s LLB image on %s\n", loaded_image != NULL ? "found" : "failed to find", name); + + return loaded_image; +} + +static bool +load_selected_image(struct image_info *loaded_image, u_int32_t type, void *load_address, size_t load_length, u_int32_t boot_flag) +{ + /* image epoch must be greater than or equal to the SecureROM's epoch */ + loaded_image->imageOptions |= IMAGE_OPTION_GREATER_EPOCH; + + /* image decode library make use of this information to do various validation on image */ + loaded_image->imageOptions |= IMAGE_OPTION_NEW_TRUST_CHAIN; + + /* if test mode isn't set, we require the image be trusted, regardless of the security fuse */ + if (!(boot_flag & BOOT_FLAG_TEST_MODE)) + loaded_image->imageOptions |= IMAGE_OPTION_REQUIRE_TRUST; + + /* validate the boot image */ + if (image_load(loaded_image, &type, 1, NULL, &load_address, &load_length)) { + dprintf(DEBUG_INFO, "image load failed\n"); + return false; + } + + return true; +} + +static void +boot_loaded_image(void *load_address) +{ + /* consolidate environment post image validation */ + security_consolidate_environment(); + +#if WITH_SIDP + /* Seal the ROM manifest for Silicon Data Protection */ + security_sidp_seal_rom_manifest(); +#endif + + dprintf(DEBUG_CRITICAL, "executing image...\n"); + prepare_and_jump(BOOT_UNKNOWN, (void *)load_address, NULL); +} diff --git a/apps/SecureROM/tests/blinky_armv7/build_rom_test.sh b/apps/SecureROM/tests/blinky_armv7/build_rom_test.sh new file mode 100644 index 0000000..81c702a --- /dev/null +++ b/apps/SecureROM/tests/blinky_armv7/build_rom_test.sh @@ -0,0 +1,118 @@ +#!/bin/bash + +set -e + +function usage() +{ + echo "build_rom_test.sh -f -p [-a ] [-v ]" + echo " -f: Force rebuild rather than using pre-built / audited binaries" + exit 1 +} + +args=$(getopt "fa:p:v" $*) +if [[ $? != 0 ]]; then + usage +fi + +FORCE_REBUILD=0 +GPIO_BASE=0x47500000 +GPIO_VALUE=0x70203 +PLATFORM="t8002" + +set -- $args +for arg; do + case $arg + in + -a) + GPIO_BASE=$2; shift; shift;; + -v) + GPIO_VALUE=$2; shift; shift;; + -p) + PLATFORM=$2; shift; shift;; + -f) + FORCE_REBUILD=1; shift;; + esac +done + +if [[ "$GPIO_BASE" == "" || "$GPIO_VALUE" == "" || "$PLATFORM" == "" ]]; then + usage +fi + +if [[ $FORCE_REBUILD != 0 ]]; then + echo "Cleaning" + rm -f rom_test.o rom_test rom_test.bin rom_test_*.im4p +fi + +if ! [[ -f rom_test.o ]]; then + echo "Running clang" + xcrun -sdk iphoneos.internal clang -arch armv7 \ + -static -marm \ + -std=gnu99 -Werror -W -Wall \ + -DGPIO_BASE=${GPIO_BASE} -DGPIO_VALUE=${GPIO_VALUE} \ + -c rom_test.c -o rom_test.o +fi + +if ! [[ -f rom_test ]]; then + echo "Standalone link" + xcrun -sdk iphoneos.internal clang -arch armv7 \ + -static -marm \ + -Wl,-new_linker \ + -Wl,-preload \ + -Wl,-merge_zero_fill_sections \ + -nodefaultlibs \ + -nostartfiles \ + -dead_strip \ + -e _start \ + -o rom_test rom_test.o +fi + +if ! [[ -f rom_test.bin ]]; then + echo "Finding __text section" + text_offset=$(xcrun -sdk iphoneos.internal otool -l rom_test | grep -A4 'sectname __text' | grep 'offset' | awk '{print $2}') + text_size=$(xcrun -sdk iphoneos.internal otool -l rom_test | grep -A4 'sectname __text' | grep 'size' | awk '{print $2}') + echo "Found at $text_offset size $text_size" + + echo "Generating bin" + dd if=rom_test ibs=1 skip=${text_offset} obs=1 count=${text_size} \ + >rom_test.bin 2>/dev/null + + echo "Mach-O dump" + xcrun -sdk iphoneos.internal otool -tVj rom_test + + echo "Bin Dump" + hexdump -C rom_test.bin +fi + + +for type in ibss illb; do + for encrypt in encrypted unencrypted; do + if ! [[ -f rom_test_${type}_${encrypt}.im4p ]]; then + echo "Generating ${encrypt} ${type} Image4 payload" + xcrun -sdk iphoneos.internal img4payload \ + -i rom_test.bin -o rom_test_${type}_${encrypt}.im4p \ + -t ${type} -v rom_test_${type}_${encrypt} + if [ "${encrypt}" = "encrypted" ]; then + xcrun -sdk iphoneos.internal img4encrypt \ + -i rom_test_${type}_${encrypt}.im4p \ + -o rom_test_${type}_${encrypt}.im4p \ + -p $PLATFORM + fi + fi + + done +done + +# Personalization, for reference: + +#xcrun -sdk iphoneos.internal personalize_img4 -i rom_test_ibss.im4p -o /tmp -c 0x -b 0xff -d 1 -e 0x12345678ABCD -n 0x9A7A07F30FE84B6403AF5BB549B405BAE16461D2 -r 0x12345678AABBCCDD +#xcrun -sdk iphoneos.internal personalize_img4 -i rom_test_llb.im4p -o /tmp -c 0x -b 0xff -d 1 -e 0x12345678ABCD -n 0x9A7A07F30FE84B6403AF5BB549B405BAE16461D2 -r 0x12345678AABBCCDD + +# Production signing, for reference: + +#xcrun -sdk iphoneos.internal personalize_img4 -m -p -i rom_test_illb_encrypted.im4p -o /tmp -c 0x -b 0xff -d 1 -e 0x12345678ABCD -n 0xcd00fc2e1fa023796d5257b853880e18cd384f7d -s 0x1234567823456789345678904567890156789012 -r 0x12345678AABBCCDD -w -W + +# Production signing with demotion, for reference: + +#xcrun -sdk iphoneos.internal personalize_img4 -m -p -i rom_test_illb_encrypted.im4p -o /tmp -c 0x -b 0xff -d 1 -e 0x12345678ABCD -n 0xcd00fc2e1fa023796d5257b853880e18cd384f7d -s 0x1234567823456789345678904567890156789012 -r 0x12345678AABBCCDD -W -D 1 + +echo "Done" diff --git a/apps/SecureROM/tests/blinky_armv7/rom_test.c b/apps/SecureROM/tests/blinky_armv7/rom_test.c new file mode 100644 index 0000000..e79bb56 --- /dev/null +++ b/apps/SecureROM/tests/blinky_armv7/rom_test.c @@ -0,0 +1,5 @@ +void start(void) +{ + *((volatile unsigned int *)GPIO_BASE) = GPIO_VALUE; + for(;;); +} diff --git a/apps/SecureROM/tests/blinky_armv8/build_rom_test.sh b/apps/SecureROM/tests/blinky_armv8/build_rom_test.sh new file mode 100644 index 0000000..87aa99b --- /dev/null +++ b/apps/SecureROM/tests/blinky_armv8/build_rom_test.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +set -e + +function usage() +{ + echo "build_rom_test.sh -p [-a ] [-v ]" + exit 1 +} + +args=$(getopt "a:p:v" $*) +if [[ $? != 0 ]]; then + usage +fi + +# GPIO[0] == GPIO id 20 == 0x20f100050 +GPIO_BASE=0x20f100050 +GPIO_VALUE=0x70203 +PLATFORM="t8010" + +set -- $args +for arg; do + case $arg + in + -a) + GPIO_BASE=$2; shift; shift;; + -v) + GPIO_VALUE=$2; shift; shift;; + -p) + PLATFORM=$2; shift; shift;; + esac +done + +if [[ "$GPIO_BASE" == "" || "$GPIO_VALUE" == "" || "$PLATFORM" == "" ]]; then + usage +fi + +echo "Cleaning" +rm -f rom_test.o rom_test rom_test.bin rom_test_*.im4p + +echo "Running clang" +xcrun -sdk iphoneos.internal clang -arch arm64 \ + -static \ + -std=gnu99 -Werror -W -Wall \ + -DGPIO_BASE=${GPIO_BASE} -DGPIO_VALUE=${GPIO_VALUE} \ + -c rom_test.c -o rom_test.o + +echo "Standalone link" +xcrun -sdk iphoneos.internal clang -arch arm64 \ + -static \ + -Wl,-new_linker \ + -Wl,-preload \ + -Wl,-merge_zero_fill_sections \ + -nodefaultlibs \ + -nostartfiles \ + -dead_strip \ + -e _start \ + -o rom_test rom_test.o + +echo "Stripping" +xcrun -sdk iphoneos.internal strip -no_uuid rom_test + +echo "Finding __text section" +text_offset=$(xcrun -sdk iphoneos.internal otool -l rom_test | grep -A4 'sectname __text' | grep 'offset' | awk '{print $2}') +text_size=$(xcrun -sdk iphoneos.internal otool -l rom_test | grep -A4 'sectname __text' | grep 'size' | awk '{print $2}') +echo "Found at $text_offset size $text_size" + +echo "Generating bin" +dd if=rom_test ibs=1 skip=${text_offset} obs=1 count=${text_size} \ + >rom_test.bin 2>/dev/null + +echo "Mach-O dump" +xcrun -sdk iphoneos.internal otool -tVj rom_test + +echo "Bin Dump" +hexdump -C rom_test.bin + +for type in ibss illb; do + for encrypt in encrypted unencrypted; do + echo "Generating ${encrypt} ${type} Image4 payload" + xcrun -sdk iphoneos.internal img4payload \ + -i rom_test.bin -o rom_test_${type}_${encrypt}.im4p \ + -t ${type} -v rom_test_${type}_${encrypt} + + if [ "${encrypt}" = "encrypted" ]; then + xcrun -sdk iphoneos.internal img4encrypt \ + -i rom_test_${type}_${encrypt}.im4p \ + -o rom_test_${type}_${encrypt}.im4p \ + -p $PLATFORM + fi + done +done + +# Personalization, for reference: + +#xcrun -sdk iphoneos.internal personalize_img4 -i rom_test_ibss.im4p -o /tmp -c 0x -b 0xff -d 1 -g 384 -e 0x12345678ABCD -n 0xa4f84e2a89c2ef04a07b9f948fec7c0767c8931bd67ede924040aa4f30afe4118a2d524d687fc0db2f4a27e36c7e75a0 -r 0x12345678AABBCCDD +#xcrun -sdk iphoneos.internal personalize_img4 -i rom_test_llb.im4p -o /tmp -c 0x -b 0xff -d 1 -g 384 -e 0x12345678ABCD -n 0xa4f84e2a89c2ef04a07b9f948fec7c0767c8931bd67ede924040aa4f30afe4118a2d524d687fc0db2f4a27e36c7e75a0 -r 0x12345678AABBCCDD + +# Production signing, for reference: + +#xcrun -sdk iphoneos.internal personalize_img4 -m -p -i rom_test_illb_encrypted.im4p -o /tmp -c 0x -b 0xff -d 1 -g 384 -e 0x12345678ABCD -n 0xa4f84e2a89c2ef04a07b9f948fec7c0767c8931bd67ede924040aa4f30afe4118a2d524d687fc0db2f4a27e36c7e75a0 -s 0x1234567823456789345678904567890156789012 -r 0x12345678AABBCCDD -w -W + +# Production signing with demotion, for reference: + +#xcrun -sdk iphoneos.internal personalize_img4 -m -p -i rom_test_illb_encrypted.im4p -o /tmp -c 0x -b 0xff -d 1 -g 384 -e 0x12345678ABCD -n 0xa4f84e2a89c2ef04a07b9f948fec7c0767c8931bd67ede924040aa4f30afe4118a2d524d687fc0db2f4a27e36c7e75a0 -s 0x1234567823456789345678904567890156789012 -r 0x12345678AABBCCDD -W -D 1 + +echo "Done" diff --git a/apps/SecureROM/tests/blinky_armv8/rom_test.c b/apps/SecureROM/tests/blinky_armv8/rom_test.c new file mode 100644 index 0000000..e79bb56 --- /dev/null +++ b/apps/SecureROM/tests/blinky_armv8/rom_test.c @@ -0,0 +1,5 @@ +void start(void) +{ + *((volatile unsigned int *)GPIO_BASE) = GPIO_VALUE; + for(;;); +} diff --git a/apps/SecureROM/tests/images_t8002/rom_test.bin b/apps/SecureROM/tests/images_t8002/rom_test.bin new file mode 100644 index 0000000000000000000000000000000000000000..b1fce848b537822b372519b004efb852ae9593e0 GIT binary patch literal 24 gcmd;JnE#YRVE$7EhQ_D={{Mf)%*4*Xz!2aL0D5r=7ytkO literal 0 HcmV?d00001 diff --git a/apps/SecureROM/tests/images_t8002/rom_test_ibss_encrypted.im4p b/apps/SecureROM/tests/images_t8002/rom_test_ibss_encrypted.im4p new file mode 100644 index 0000000..ad6b268 --- /dev/null +++ b/apps/SecureROM/tests/images_t8002/rom_test_ibss_encrypted.im4p @@ -0,0 +1 @@ +0½IM4Pibssrom_test_ibss_encrypted A°ö–@Û_ÊHþ€7:@´5bJûì=}ôI¸8Y­t0r07ìȃ‡µÿ¯ƒHêo9Árø ÈcTlÅT71³¸Ž½!‚ƒû*¢³ØÐSR#祧>¡07w@#TÚ±ÅsRÝ“£eÒ ÇÃûñ^&ç‚7tÝ0M¸Ý“SÒãùeñd ûå \ No newline at end of file diff --git a/apps/SecureROM/tests/images_t8002/rom_test_ibss_unencrypted.im4p b/apps/SecureROM/tests/images_t8002/rom_test_ibss_unencrypted.im4p new file mode 100644 index 0000000000000000000000000000000000000000..675b3c81cff0bff573ef2be2814ede6faa64b482 GIT binary patch literal 67 zcmXqT6l3x9H3<-7$xJFP7LzQ>&y6ohEiQ=%apOz#QuC6FDho.É™ŠÈÎö æHˆ¿ÓCË`«‹ iU°š˜-SÕËcú{ 5æ^«07µ#4]l-&y6ohEiQ=%apOz#QuC6FDhoQ`BPCMxd32*@YtBqp#>U;*CQ}D0s#U95HaYJ3fZzv unODyAKl4bOumm70S(&F1H5+pdVu=PRIkUPnN)>oU90S{SLY97VByM#s@JT@c literal 0 HcmV?d00001 diff --git a/apps/SecureROM/tests/images_t8010/rom_test_ibss_unencrypted.im4p b/apps/SecureROM/tests/images_t8010/rom_test_ibss_unencrypted.im4p new file mode 100644 index 0000000000000000000000000000000000000000..9de9814567cc8da2508fab355c06d082879632cb GIT binary patch literal 71 zcmXqT6=U)AH3<-7$xJFP7LzQ>&y6ohEiQ=%apOz#QuC6FDho’8ŒàÀÖ2qˆóV¤6 >ƒÓ$ÍI.ôTæP$<t0r07-&y6ohEiQ=%apOz#QuC6FDho certificate epoch for server signing fixed at 1 +kDefaultEpochForServerSigning = 1 + +# Supported platforms +kSupported_platforms = ['t8010'] + +# Image sources +kImageSourceDfu = 1 +kImageSourceNand = 2 +kImageSourceNor = 3 +kImageSourceNVMe = 4 + +# Outcomes +kOutcomeBlinky = 1 +kOutcomeDfu = 2 +kOutcomeBlinkyVcoOverride = 3 + +# Silicon Data Protection (SiDP) State +kSiDPStateUnlocked = 1 +kSiDPStateLockedInvalid = 2 +kSiDPStateLockedValid = 3 + +# Core Type State +kCoreTypeECore = 1 # Efficient core: Zephyr +kCoreTypePCore = 2 # Performant core: Hurricane + +# Can be overidden by command line options. +kImg4DecodeTestTool = 'xcrun -sdk iphoneos.internal -run img4decodetest' +kPersonalizeImg4Tool = 'xcrun -sdk iphoneos.internal -run personalize_img4' +kBfnMaker = 'xcrun -sdk iphoneos.internal -run bfn_maker' + +kBfnMakerPageSize = 8224 +kBfnMakerFormat = 'h6' + +def ErrorText(text): + RedColor = '\033[91m' + NormalColor = '\033[0m' + return RedColor + text + NormalColor + +def WarningText(text): + YellowColor = '\033[93m' + NormalColor = '\033[0m' + return YellowColor + text + NormalColor + +def PassText(text): + GreenColor = '\033[92m' + NormalColor = '\033[0m' + return GreenColor + text + NormalColor + +def ByteSwap(value, bits): + assert (bits % 8) == 0 + result = 0 + for i in xrange(0, bits / 8): + result <<= 8 + result |= value & 0xff + value >>= 8 + return result + +class LogSettings: + def __init__(self): + self._all_settings = [] + + def Append(self, text, settings): + self._all_settings.append((text, settings)) + + def Log(self, log): + # Get a format string which aligns everything. + longest_entry = 0 + for settings in self._all_settings: + for s in settings[1]: + if len(s[0]) > longest_entry: + longest_entry = len(s[0]) + format = ' %%-%ds %%s\n' % longest_entry + + # Dump all settings. + for settings in self._all_settings: + log.write(settings[0] + ':\n') + for s in settings[1]: + if (type(s[1]) == int) or (type(s[1]) == long): + if s[1] < 16: + out = format % (s[0], '%d' % s[1]) + else: + out = format % (s[0], '0x%x' % s[1]) + else: + out = format % (s[0], str(s[1])) + log.write(out) + log.write('\n') + +class PersonalizeImg4: + def __init__(self, + description = None, + manifest = True, + platform = kDefaultPlatform, + options = None, + log = None, + test_number = None, + outcome = None, + sidp_state = None, + core_type = None, + image_source = None, + fuse_production_status = None, + fuse_security_mode = None, + fuse_security_domain = kSecurityDomainDarwin, + fuse_epoch = None, + fuse_ecid = kDefaultEcid, + fuse_cfg_fuse4 = None, + boot_device = None, + test_mode = False, + boot_device_empty = False, + epoch = kDefaultEpochForServerSigning, + chip_id = None, + board_id = None, + force_dfu = 0, + ecid = None, + production_status = None, + security_mode = None, + security_domain = kSecurityDomainDarwin, + allow_mix_and_match = None, + ap_boot_nonce_hash = None, + sep_boot_nonce_hash = None, + enable_keys = None, + encryption = None, + crypto_hash_method = 'sha2-384', + restore_info_nonce = None, + demote_production = None, + demote_secure = None, + lock_fuses = None, + ): + # Validate required arguments. + assert options is not None + assert log is not None + assert type(test_number) == int + assert outcome in [kOutcomeBlinky, kOutcomeDfu, kOutcomeBlinkyVcoOverride] + assert image_source in [kImageSourceDfu, kImageSourceNand, kImageSourceNor, kImageSourceNVMe] + assert boot_device is not None + assert type(boot_device_empty) == bool + assert type(fuse_production_status) == bool + assert type(fuse_security_mode) == bool + assert ((type(fuse_security_domain) == int) and + (fuse_security_domain >= 0) and (fuse_security_domain <= 3)) + assert ((type(fuse_epoch) == int) and + (fuse_epoch >= 0) and (fuse_epoch <= 0x7f)) + assert ((fuse_ecid is not None) and + (fuse_ecid >= 0) and (fuse_ecid < (1 << 64))) + + if manifest: + assert ((type(epoch) == int) and + (epoch >= 0) and (epoch <= 0x7f)) + assert ((type(chip_id) == int) and + (chip_id >= 0) and (chip_id < (1 << 16))) + assert ((type(board_id) == int) and + (board_id >= 0) and (board_id < (1 << 8))) + assert (ecid is not None) and (ecid >= 0) and (ecid < (1 << 64)) + assert type(production_status) == bool + assert type(security_mode) == bool + assert ((type(security_domain) == int) and + (security_domain >= 0) and (security_domain <= 3)) + assert type(allow_mix_and_match) == bool + assert type(enable_keys) == bool + assert type(encryption) == bool + if sep_boot_nonce_hash is None: + sep_boot_nonce_hash = kDefaultSepNonceHash + # Set members. + self._description = description + self._manifest = manifest + self._platform = platform + self._images_dir = 'images_{}'.format(platform) + self._options = options + self._log = log + self._test_number = test_number + self._outcome = outcome + self._sidp_state = sidp_state + self._core_type = core_type + self._image_source = image_source + self._fuse_production_status = fuse_production_status + self._fuse_security_mode = fuse_security_mode + self._fuse_security_domain = fuse_security_domain + self._fuse_epoch = fuse_epoch + self._fuse_ecid = fuse_ecid + if fuse_cfg_fuse4 is None: + self._fuse_cfg_fuse4 = '0x00000000' + self._fcal_vcodigctrl_out = '0x00' + else: + assert (type(fuse_cfg_fuse4) == int) + self._fuse_cfg_fuse4 = '0x%08x' % fuse_cfg_fuse4 + self._fcal_vcodigctrl_out = '0x%02x' % fuse_cfg_fuse4 + self._epoch = epoch + self._chip_id = chip_id + self._board_id = board_id + self._boot_device = boot_device + self._test_mode = test_mode + self._boot_device_empty = boot_device_empty + self._force_dfu = force_dfu + self._ecid = ecid + self._production_status = production_status + self._security_mode = security_mode + self._security_domain = security_domain + self._allow_mix_and_match = allow_mix_and_match + self._ap_boot_nonce_hash = ap_boot_nonce_hash + self._sep_boot_nonce_hash = sep_boot_nonce_hash + self._enable_keys = enable_keys + self._encryption = encryption + self._crypto_hash_method = crypto_hash_method + self._restore_info_nonce = restore_info_nonce + self._demote_production = demote_production + self._demote_secure = demote_secure + self._lock_fuses = lock_fuses + + def Personalize(self, im4p, output_dir): + # Form args. + if self._options.personalize_img4: + args = self._options.personalize_img4.split(' ') + else: + args = kPersonalizeImg4Tool.split(' ') + args += ['-i', im4p, '-o', output_dir] + + if not self._manifest: + args += ['-O'] + else: + if self._chip_id is not None: + args += ['-c', '0x%04x' % self._chip_id] + if self._board_id is not None: + args += ['-b', '0x%x' % self._board_id] + if self._ecid is not None: + args += ['-e', '0x%x' % self._ecid] + if self._production_status: + args += ['-p'] + if self._security_mode: + args += ['-m'] + args += ['-W'] + if self._security_domain is not None: + args += ['-d', '%d' % self._security_domain] + if self._allow_mix_and_match: + args += ['-a'] + if self._ap_boot_nonce_hash is not None: + args += ['-n', '0x%x' % self._ap_boot_nonce_hash] + if self._sep_boot_nonce_hash is not None: + args += ['-s', '0x%x' % self._sep_boot_nonce_hash] + if self._crypto_hash_method == 'sha2-384': + args += ['-g 384'] + # disabling keys or demotions require a plist file with Trusted, EPRO, and ESEC defined + if (not self._enable_keys) or (self._demote_production) or (self._demote_secure): + object_properties = {'Trusted': self._enable_keys} + manifest_properties = {} + + if self._demote_production is not None: + object_properties['DPRO'] = True + + if self._demote_production: + assert self._production_status == True + object_properties['EPRO'] = False + else: + object_properties['EPRO'] = self._production_status + + if self._demote_secure: + assert self._security_mode == True + object_properties['ESEC'] = False + else: + object_properties['ESEC'] = self._security_mode + + all_properties = {'OBJP': object_properties, 'MANP': manifest_properties} + plist_str = plistlib.writePlistToString(all_properties) + plist_file = '/tmp/personalize-{}.plist'.format(self._test_number) + f = open(plist_file, 'w') + f.write(plist_str) + f.close() + + args += ['-f', plist_file] + # personalize_img4 tool expects RestoreInfo nonce in big endian (only for LLB) + if (im4p.find('ibss') == -1) and self._restore_info_nonce is not None: + args += ['-r', '0x%x' % ByteSwap(self._restore_info_nonce, 64)] + args += ['-X'] + + # Convert args to an shell string. + invoke_string = ' '.join(args) + + # Execute personalize_img4 utility. + print('Invoking: %s' % invoke_string) + pipe = subprocess.Popen(invoke_string, shell=True) + if pipe.wait() == 0: + return True + else: + self._log.write('Invocation of personalize_img4 failed\n') + sys.stderr.write(ErrorText('Test %d: Invocation of personalize_img4 failed\n' % self._test_number)) + return False + + def DecodeTest(self, img4): + if self._options.img4decodetest: + args = self._options.img4decodetest.split(' ') + else: + args = kImg4DecodeTestTool.split(' ') + args += ['-c', '-i', img4] + if self._crypto_hash_method == 'sha2-384': + args += ['-n'] + invoke_string = ' '.join(args) + print('Invoking: %s' % invoke_string) + pipe = subprocess.Popen(invoke_string, shell=True) + if pipe.wait() == 0: + return True + else: + self._log.write('Invocation of img4decodetest failed\n') + sys.stderr.write(ErrorText('Test %d: Invocation of img4decodetest failed\n' % self._test_number)) + return False + + def BfnMaker(self, input, output): + if self._options.bfn_maker: + args = self._options.bfn_maker.split(' ') + else: + args = kBfnMaker.split(' ') + args += ['--pageSize', str(kBfnMakerPageSize)] + args += ['--format', str(kBfnMakerFormat)] + args += [input, output] + invoke_string = ' '.join(args) + pipe = subprocess.Popen(invoke_string, shell=True) + if pipe.wait() == 0: + return True + else: + self._log.write('Invocation of bfn_maker failed\n') + sys.stderr.write(ErrorText('Test %d: Invocation of bfn_maker failed\n' % self._test_number)) + return False + + def Execute(self): + # Log header. + self._log.write('-' * kLogWidth + '\n') + self._log.write('Test %d\n' % self._test_number) + self._log.write(textwrap.fill(self._description, width=kLogWidth) + '\n\n') + + # Figure out the input file variant. + image_type, location = {kImageSourceDfu: ('ibss', 'DFU'), + kImageSourceNand: ('illb', 'NAND'), + kImageSourceNor: ('illb', 'NOR'), + kImageSourceNVMe: ('illb', 'NVMe')}[self._image_source] + + # FAST_NOR boot device is currenly only supported for test mode + if self._boot_device in ['FAST_NOR', 'SLOW_NOR']: + if self._test_mode == False: + self._log.write(' Skipping: FAST_NOR/SLOW_NOR boot device requires test mode\n\n') + sys.stderr.write(WarningText('Test %d: FAST_NOR/SLOW_NOR boot device requires test mode\n' % self._test_number)) + return False + + if self._boot_device == 'NOR': + self._boot_config = '0x%x' % (0 + (1 if self._test_mode else 0)) + elif self._boot_device == 'NVME0_X2': + self._boot_config = '0x%x' % (2 + (1 if self._test_mode else 0)) + elif self._boot_device == 'NVME0_X1': + self._boot_config = '0x%x' % (4 + (1 if self._test_mode else 0)) + elif self._boot_device == 'SLOW_NOR': + self._boot_config = '0x6' + elif self._boot_device == 'FAST_NOR': + self._boot_config = '0x7' + else: + assert 0, '_boot_device ' + self._boot_device + ' is unsupported' + + if self._encryption: + encryption_name = 'encrypted' + else: + encryption_name = 'unencrypted' + im4p_basename = 'rom_test_%s_%s' % (image_type, encryption_name) + im4p_filename = im4p_basename + '.im4p' + im4p_path = os.path.join(self._images_dir, im4p_filename) + + # If valid image in boot device, but force_dfu is set, we also need ibss + if self._force_dfu and self._boot_device_empty == False: + dfu_im4p_basename = 'rom_test_ibss_%s' % encryption_name + dfu_im4p_filename = dfu_im4p_basename + '.im4p' + dfu_im4p_path = os.path.join(self._images_dir, dfu_im4p_filename) + + # Output filename. + output_dir = kOutputDirPrefix + self._platform + pretty_filename_base = 'test_%d_%s_%s' % ( + self._test_number, image_type, encryption_name) + pretty_filename_img4 = pretty_filename_base + '.img4' + pretty_path_base = os.path.join(output_dir, pretty_filename_base) + pretty_path_img4 = pretty_path_base + '.img4' + + # If valid image in boot device, but force_dfu is set, we also need ibss + if self._force_dfu and self._boot_device_empty == False: + pretty_dfu_filename_base = 'test_%d_ibss_%s' % ( + self._test_number, encryption_name) + pretty_dfu_filename_img4 = pretty_dfu_filename_base + '.img4' + pretty_dfu_path_base = os.path.join(output_dir, pretty_dfu_filename_base) + pretty_dfu_path_img4 = pretty_dfu_path_base + '.img4' + + # Remove old output file if it exists. + img4 = os.path.join(output_dir, im4p_basename + '.img4') + if self._force_dfu and self._boot_device_empty == False: + dfu_img4 = os.path.join(output_dir, dfu_im4p_basename + '.img4') + try: + os.unlink(img4) + if dfu_img4 is not None: + os.unlink(dfu_img4) + except: + pass + # Personalize this case. + print('Personalize %s -> %s' % (im4p_filename, img4)) + if not self.Personalize(im4p_path, output_dir): + sys.stderr.write(ErrorText('Test %d failed to generate\n' % self._test_number)) + # Log failure + self._log.write(' Failed to generate!\n\n') + return False + + # Now, if force_dfu is set, personalize the 2nd image + if self._force_dfu and self._boot_device_empty == False: + print('Personalize %s -> %s' % (dfu_im4p_filename, dfu_img4)) + if not self.Personalize(dfu_im4p_path, output_dir): + sys.stderr.write(ErrorText('Test %d failed to generate\n' % self._test_number)) + # Log failure + self._log.write(' Failed to generate!\n\n') + return False + + # Rename the output file to the path we want for this test case. + os.rename(img4, pretty_path_img4) + print('Test %d generated %s' % (self._test_number, pretty_filename_img4)) + + if self._force_dfu and self._boot_device_empty == False: + os.rename(dfu_img4, pretty_dfu_path_img4) + print('Test %d generated %s' % (self._test_number, pretty_dfu_filename_img4)) + + # Test that there isn't a certificate vs manifest problem, because + # it's not worth burning a huge amount of DV time running it. + if self._manifest: + if not self.DecodeTest(pretty_path_img4): + self._log.write(' Failed decode test!\n') + self._log.write(' Check manifest vs cert is compatible\n\n') + sys.stderr.write(ErrorText('Test %d: Failed decode test\n' % self._test_number)) + return False + + if self._force_dfu and self._boot_device_empty == False: + if not self.DecodeTest(pretty_dfu_path_img4): + self._log.write(' Failed decode test!\n') + self._log.write(' Check manifest vs cert is compatible\n\n') + sys.stderr.write(ErrorText('Test %d: Failed decode test\n' % self._test_number)) + return False + + # If the source is NAND, we need to pass it through bfn_maker + if self._image_source == kImageSourceNand: + nand_filename = pretty_filename_base + '.nand' + nand_path = os.path.join(output_dir, nand_filename) + if not self.BfnMaker(pretty_path_img4, nand_path): + self._log.write(' Failed to create NAND image\n') + sys.stderr.write(ErrorText('Test %d: Failed to create NAND image\n' % self._test_number)) + return False + pretty_filename = nand_filename + else: + pretty_filename = pretty_filename_img4 + + core_type_string = {kCoreTypeECore: "0 (E-core)", + kCoreTypePCore: "1 (P-core)", + None: "Random" + }[self._core_type] + + # Log success. + settings = LogSettings() + + settings.Append( + 'Fuses', + [('Production Status', int(self._fuse_production_status)), + ('Security Mode', int(self._fuse_security_mode)), + ('Security Domain', self._fuse_security_domain), + ('Board ID', '0x%x' % ((self._board_id or kDefaultBoardId) >> kBoardIdStrapBits)), + ('Epoch', self._fuse_epoch), + ('SE Required', 0), + ('BOOT_PCORE', core_type_string), + ('ECID_LO', '0x%08x' % (kDefaultEcid & 0xffffffff)), + ('ECID_HI', '0x%08x' % ((kDefaultEcid >> 32) & 0xffffffff)), + ('CFG_FUSE4', self._fuse_cfg_fuse4), + ]) + + settings.Append( + 'Straps', + [('Boot-device', self._boot_device), + ('Test mode', self._test_mode), + ('Boot-config', self._boot_config), + ('Board-id', (self._board_id or kDefaultBoardId) & ((1 << kBoardIdStrapBits) - 1)), + ('Force-dfu', self._force_dfu), + ('Boot Device Empty', self._boot_device_empty), + ]) + + if self._force_dfu and self._boot_device_empty == False: + pretty_dfu_filename = pretty_dfu_filename_img4 + else: + pretty_dfu_filename = '' + + settings.Append( + 'Images', + [(pretty_filename, ''), + (pretty_dfu_filename, ''), + ]) + + outcome_string = {kOutcomeBlinky: 'Blinky: {} = {}'.format(kDefaultBlinkyGPIOReg, kDefaultBlinkyGPIOValue), + kOutcomeDfu: 'DFU: {} = {}, {} = {}'.format(kDefaultUSBDCTLReg, kDefaultUSBDCTLValue, kDefaultDFUStatusGPIOReg, kDefaultDFUStatusGPIOValue), + kOutcomeBlinkyVcoOverride: 'Blinky: {} = {}, {} = {}'.format(kDefaultBlinkyGPIOReg, kDefaultBlinkyGPIOValue, kDefaultPCIEVCODIGCTRLReg, self._fcal_vcodigctrl_out), + }[self._outcome] + + sidp_string = {kSiDPStateUnlocked: "Unlocked & Invalid: {} = {}, SEAL_DATA_A(0..7) = don't care".format(kDefaultSiDPReg, kDefaultSiDPUnlocked), + kSiDPStateLockedInvalid: "Locked & Invalid: {} = {}, SEAL_DATA_A(0..7) = zero".format(kDefaultSiDPReg, kDefaultSiDPInvalid), + kSiDPStateLockedValid: "Locked & Valid: {} = {}, SEAL_DATA_A(0..7) = PMGR_SCRATCH_SCRATCH(12..19) = manifest".format(kDefaultSiDPReg, kDefaultSiDPValid), + }[self._sidp_state] + + if self._outcome == kOutcomeDfu: + check_usb_clk = 'USB clock frequency' + check_usb_clk_text = 'Verify USB clock running at spec frequency' + check_usbotg = 'USB Device Mode Tunables' + check_usbotg_text = '{} = {}, {} = {}'.format(kDefaultUSB20PHYCFG0Reg, kDefaultUSB20PHYCFG0Value, kDefaultUSB20PHYCFG1Reg, kDefaultUSB20PHYCFG1Value) + else: + check_usb_clk = '' + check_usb_clk_text = '' + check_usbotg = '' + check_usbotg_text = '' + + # JTAG gets enabled on a production part if it is demoted. + if self._fuse_production_status == True and self._demote_production == True and self._outcome == kOutcomeBlinky: + check_jtag = 'JTAG' + check_jtag_text = 'Starts disabled before test, but enabled after test' + check_prod_mode = 'Production Mode' + check_prod_mode_text = 'Disabled: MINIPMGR_FUSE_CFG_FUSE0.PRODUCTION_MODE @2_102bc000[0] = 0' + else: + check_jtag = '' + check_jtag_text = '' + check_prod_mode = '' + check_prod_mode_text = '' + + if self._enable_keys == None: + self._enable_keys = False + + keys_state = {True: 'Enabled: MINIPMGR_SECURITY_SIO_AES_DISABLE @2_102d0000[31:0] = 0x00000000', + False: 'Disabled: MINIPMGR_SECURITY_SIO_AES_DISABLE @2_102d0000[31:0] = 0x00000007'}[self._enable_keys] + + if self._lock_fuses == None: + if self._outcome == kOutcomeDfu: + self._lock_fuses = False + else: + self._lock_fuses = True + + fuses_locked_state = {True: 'Locked: MINIPMGR_FUSE_CFG_FUSE1.AP_LOCK @2_102bc004[31] = 1', + False: 'Unlocked: MINIPMGR_FUSE_CFG_FUSE1.AP_LOCK @2_102bc004[31] = 0'}[self._lock_fuses] + + # For LLB boot, boot nonce pre-set to 0xdeadbeefdeadbeef. For iBSS boot, set to 0xddccbbaa78563412 + if pretty_filename.find('llb') != -1 and self._force_dfu == 0: + boot_nonce = 0xdeadbeefdeadbeef + else: + if self._restore_info_nonce is not None: + boot_nonce = self._restore_info_nonce + else: + boot_nonce = kDefaultApNonceLittleEndian + + if self._force_dfu and self._outcome == kOutcomeBlinky: + outcome_string += ' via iBSS in DFU mode' + + rom_state = {True: 'Enabled: MINIPMGR_SECURITY_MCC_BOOTROMDIS @2_102d0010[0] = 0', + False: 'Disabled: MINIPMGR_SECURITY_MCC_BOOTROMDIS @2_102d0010[0] = 1'}[self._outcome == kOutcomeDfu] + + settings.Append( + 'Boot Nonce in PMGR Scratch Registers', + [('PMGR_SCRATCH_10', '0x%x' % (boot_nonce & 0xffffffff)), + ('PMGR_SCRATCH_11', '0x%x' % ((boot_nonce >> 32) & 0xffffffff)), + ]) + + settings.Append( + 'PASS', + [('Outcome', outcome_string), + ('ROM Access', rom_state), + ('Keys - UID and GIDs', keys_state), + ('Fuses', fuses_locked_state), + ('SiDP', sidp_string), + ('', ''), + ('Boot Core', 'CPU0 MPIDR_EL1.AFFINITY2 = MINIPMGR_FUSE_CFG_FUSE1.BOOT_PCORE @2_102bc004[18]'), + (check_usbotg, check_usbotg_text), + (check_usb_clk, check_usb_clk_text), + (check_prod_mode, check_prod_mode_text), + (check_jtag, check_jtag_text), + ]) + + settings.Append( + 'FAIL', + [('All PASS conditions not met', ''), + ]) + + if self._manifest: + settings.Append( + '(Informational only - Image4 Personalization Settings Used)', + [('Encryption', self._encryption), + ('Crypto Hash Method', self._crypto_hash_method), + ('Epoch', self._epoch), + ('Chip ID', self._chip_id), + ('Board ID', self._board_id), + ('ECID', self._ecid), + ('Production Status', self._production_status), + ('Security Mode', self._security_mode), + ('Enable Keys', self._enable_keys), + ('DPRO', self._demote_production), + ('DSEC', self._demote_secure), + ('Security Domain', self._security_domain), + ('Allow Mix and Match', self._allow_mix_and_match), + ('AP Boot Nonce Hash', self._ap_boot_nonce_hash), + ('Restore Info Nonce', self._restore_info_nonce), + ('SEP Boot Nonce Hash', self._sep_boot_nonce_hash), + ]) + + settings.Log(self._log) + return True + +def main(): + help_str = ('Use the source.\n') + class MyParser(optparse.OptionParser): + def format_epilog(self, formatter): + return self.epilog + parser = MyParser(epilog=help_str) + parser.add_option( + '--platform', + help='Override the default platform value of ' + kDefaultPlatform) + parser.add_option( + '--personalize_img4', + help='Override path to personalize_img4 tool') + parser.add_option( + '--img4decodetest', + help='Override path to img4decodetest tool') + parser.add_option( + '--bfn_maker', + help='Override path to bfn_maker tool') + (options, args) = parser.parse_args(sys.argv[1:]) + if args: + sys.stderr.write(ErrorText('Unused trailing options: ' + ' '.join(args) + '\n')) + return 1 + + thisPlat = options.platform + if thisPlat is None: + thisPlat = kDefaultPlatform + output_dir = kOutputDirPrefix + str(thisPlat) + + # Determine the chip_id and board_id based on the platform + if thisPlat not in kSupported_platforms: + sys.stderr.write(ErrorText('Only the following platforms are supported by this script: ' + str(kSupported_platforms))) + return 1 + elif thisPlat == kDefaultPlatform: + thisChip_id = kDefaultChipId + thisBoard_id = kDefaultBoardId + else: + assert false, "Unknown platform" + + # Prune any existing output and re-create the directory. + shutil.rmtree(output_dir, ignore_errors=True) + os.makedirs(output_dir) + + log = open(os.path.join(output_dir, kLogFileName), 'w') + log.write('This file generated by iBoot/apps/SecureROM/test_generator_img4\n') + log.write('Generated on: %s GMT\n\n' % time.asctime(time.gmtime())) + + # Result code + rc = True + + # Test 1: + # Boot from SPI NOR without a manifest in testmode. This facility is sometimes used in the factory + # environment and the test is to ensure that we can successfully + # boot in this environment. This is booting a non-secure image on a + # non-secure part in testmode. + rc &= PersonalizeImg4(manifest = False, + platform = thisPlat, + options = options, + log = log, + test_number = 1, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedInvalid, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = False, + fuse_epoch = 0, + boot_device = 'NOR', + test_mode = True, + description = ('Boot image without manifest in testmode with SPI NOR') + ).Execute() + + # Test 2: + # Boot from SPI NOR with manifest that disables keys. This is booting a non-secure + # image on a non-secure part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 2, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = False, + fuse_epoch = 0, + production_status = False, + security_mode = False, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = True, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = False, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot image with manifest that disables keys on an insecure part') + ).Execute() + + # Test 3: + # Fail to boot a non-production image on a Production part in test mode. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 3, + outcome = kOutcomeDfu, + sidp_state = kSiDPStateUnlocked, + core_type = kCoreTypeECore, + image_source = kImageSourceNor, + fuse_production_status = True, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NOR', + test_mode = True, + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Fail to boot a non-production image on a Production part in test mode') + ).Execute() + + # Test 4: + # Boot a production image on a production part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 4, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNor, + fuse_production_status = True, + fuse_security_mode = True, + fuse_epoch = 1, + production_status = True, + security_mode = True, + epoch = kDefaultEpochForServerSigning, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = True, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot a production image on a production part') + ).Execute() + + # Test 5: + # Test Epoch changes by having a chip epoch greater then the + # certificate epoch, and verifying that the object is rejected. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 5, + outcome = kOutcomeDfu, + sidp_state = kSiDPStateUnlocked, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 2, + production_status = False, + security_mode = True, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Fail to boot an image with epoch less than chip epoch') + ).Execute() + + # Test 6: + # Test USB DFU mode on a development device. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 6, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceDfu, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NOR', + boot_device_empty = True, + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + description = ('Boot from USB in DFU mode with boot device set to NOR, but NOR is empty') + ).Execute() + + # Test 7: + # Test Force DFU when a valid image is in NOR. i.e. ignore valid NOR image + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 7, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + force_dfu = 1, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from USB in DFU mode with boot device set to NOR, and valid image in NOR, but force dfu set') + ).Execute() + + # Test 8: + # Boot an image in development mode on a production part (Demotion) + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 8, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNor, + fuse_production_status = True, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = True, + security_mode = True, + epoch = kDefaultEpochForServerSigning, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = True, + demote_production = True, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot an image in development mode on a production part (Demotion)') + ).Execute() + + # Test 9: + # Boot from NVMe on X2 PCIe link a development image on a development part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 9, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNVMe, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NVME0_X2', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from NVMe on PCIE0 in X2 mode a development image on a development part') + ).Execute() + + # Test 10: + # Boot from NVMe on X1 PCIe link a development image on a development part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 10, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + core_type = kCoreTypePCore, + image_source = kImageSourceNVMe, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NVME0_X1', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from NVMe on PCIE0 in X1 mode a development image on a development part') + ).Execute() + + # Test 11: + # Boot from NVMe on X2 PCIe link with L1SS disabled a development image on a development part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 11, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNVMe, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NVME0_X2', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from NVMe with L1SS disabled on PCIE0 in X2 mode a development image on a development part') + ).Execute() + + # Test 12: + # Strapped for NVMe on X2 PCIe link but nothing connected to PCIe Port 0 + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 12, + outcome = kOutcomeDfu, + sidp_state = kSiDPStateUnlocked, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NVME0_X2', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Strapped for NVMe on PCI00 boot but nothing connected to PCIe Port 0. Will time out after 10 seconds.') + ).Execute() + + # Test 13: + # Boot from NOR (fast mode) a development image on a development part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 13, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'FAST_NOR', + test_mode = True, + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from SPI NOR in fast mode a development image on a development part') + ).Execute() + + # Test 14: + # Boot from NOR (slow mode) a development image on a development part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 14, + outcome = kOutcomeBlinky, + sidp_state = kSiDPStateLockedValid, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'SLOW_NOR', + test_mode = True, + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from SPI NOR in slow mode a development image on a development part') + ).Execute() + + # Test 15: + # Boot from SPI NOR in test mode without a manifest in testmode with PCIe PLL VCO overrides. + rc &= PersonalizeImg4(manifest = False, + platform = thisPlat, + options = options, + log = log, + test_number = 15, + outcome = kOutcomeBlinkyVcoOverride, + sidp_state = kSiDPStateLockedInvalid, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = False, + fuse_epoch = 0, + fuse_cfg_fuse4 = 0x15, + boot_device = 'NOR', + test_mode = True, + description = ('Boot image without manifest in testmode from SPI NOR with with PCIe PLL VCO overrides') + ).Execute() + + log.write("In addition, provide a clock-tree dump (including spare clocks). Please pick a test from 1 to 9 AND a test from 10 to 11 for this dump.\n") + + log.close() + + if rc: + sys.stdout.write(PassText('\nSuccess\n')) + return 0 + else: + sys.stderr.write(ErrorText('\nTest plan contains errors\n')) + return 1 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/apps/SecureROM/tests/test_generator_mx.py b/apps/SecureROM/tests/test_generator_mx.py new file mode 100644 index 0000000..5f97b44 --- /dev/null +++ b/apps/SecureROM/tests/test_generator_mx.py @@ -0,0 +1,924 @@ +#!/usr/bin/python2.7 + +import optparse +import os +import plistlib +import textwrap +import shutil +import subprocess +import sys +import time +import hashlib +import binascii + +# ECID: This is the value passed on the personalize_img4 -e option. +kDefaultEcid = 0x000012345678abcd + +# BNCN: This is the value passed on the personalize_img4 -r option. +kDefaultApNonce = 0x12345678aabbccdd + +# Old fashioned terminal size. +kLogWidth = 78 +kOutputDirPrefix = 'test.' +kLogFileName = 'README.txt' + +kDefaultPlatform = 't8002' +kDefaultChipId = 0x8002 +kDefaultBoardId = 0x3f +kDefaultBlinkyGPIOReg = '0x47500000' +kDefaultBlinkyGPIOValue = '0x70203' +kDefaultDFUGPIOReg = '0x47500220' +kDefaultDFUGPIOValue = '0x00478283' +kBoardIdStrapBits = 4 +kSecurityDomainDarwin = 1 + +# The following calculates the nonce hash and formats it correctly so that a +# person doesn't have to deal with generating the a hash, truncating it, and +# getting the endian-ness right. +kDefaultApNonceHashTruncatedSize = 256 +kDefaultApNonceByteArray = bytearray.fromhex(hex(kDefaultApNonce)[2:]) +kDefaultApNonceString = binascii.hexlify(kDefaultApNonceByteArray) +kDefaultApNonceLittleEndian = int("".join(reversed([kDefaultApNonceString[i:i+2] for i in range(0, len(kDefaultApNonceString), 2)])), 16) +kDefaultApNonceHash384 = hashlib.sha384(kDefaultApNonceByteArray).hexdigest() +kDefaultApNonceHash = int(kDefaultApNonceHash384[:kDefaultApNonceHashTruncatedSize/4], 16) + +kDefaultSepNonceHash = 0x1234567823456789345678904567890156789012 + +# certificate epoch for server signing fixed at 1 +kDefaultEpochForServerSigning = 1 + +# Supported platforms +kSupported_platforms = ['t8002'] + +# Image sources +kImageSourceDfu = 1 +kImageSourceNand = 2 +kImageSourceNor = 3 + +# Outcomes +kOutcomeBlinky = 1 +kOutcomeDfu = 2 +kOutcomeBlinkyVcoOverride = 3 +kOutcomeBlinkyVcoDefault = 4 + +# Can be overidden by command line options. +kImg4DecodeTestTool = 'xcrun -sdk iphoneos.internal -run img4decodetest' +kPersonalizeImg4Tool = 'xcrun -sdk iphoneos.internal -run personalize_img4' +kBfnMaker = 'xcrun -sdk iphoneos.internal -run bfn_maker' + +kBfnMakerPageSize = 8224 +kBfnMakerFormat = 'h6' + +def ErrorText(text): + RedColor = '\033[91m' + NormalColor = '\033[0m' + return RedColor + text + NormalColor + +def WarningText(text): + YellowColor = '\033[93m' + NormalColor = '\033[0m' + return YellowColor + text + NormalColor + +def PassText(text): + GreenColor = '\033[92m' + NormalColor = '\033[0m' + return GreenColor + text + NormalColor + +def ByteSwap(value, bits): + assert (bits % 8) == 0 + result = 0 + for i in xrange(0, bits / 8): + result <<= 8 + result |= value & 0xff + value >>= 8 + return result + +class LogSettings: + def __init__(self): + self._all_settings = [] + + def Append(self, text, settings): + self._all_settings.append((text, settings)) + + def Log(self, log): + # Get a format string which aligns everything. + longest_entry = 0 + for settings in self._all_settings: + for s in settings[1]: + if len(s[0]) > longest_entry: + longest_entry = len(s[0]) + format = ' %%-%ds %%s\n' % longest_entry + + # Dump all settings. + for settings in self._all_settings: + log.write(settings[0] + ':\n') + for s in settings[1]: + if (type(s[1]) == int) or (type(s[1]) == long): + if s[1] < 16: + out = format % (s[0], '%d' % s[1]) + else: + out = format % (s[0], '0x%x' % s[1]) + else: + out = format % (s[0], str(s[1])) + log.write(out) + log.write('\n') + +class PersonalizeImg4: + def __init__(self, + description = None, + manifest = True, + platform = kDefaultPlatform, + options = None, + log = None, + test_number = None, + outcome = None, + image_source = None, + fuse_production_status = None, + fuse_security_mode = None, + fuse_security_domain = kSecurityDomainDarwin, + fuse_epoch = None, + fuse_ecid = kDefaultEcid, + fuse_cfg_fuse9 = None, + boot_device = None, + test_mode = False, + boot_device_empty = False, + epoch = kDefaultEpochForServerSigning, + chip_id = None, + board_id = None, + force_dfu = 0, + ecid = None, + production_status = None, + security_mode = None, + security_domain = kSecurityDomainDarwin, + allow_mix_and_match = None, + ap_boot_nonce_hash = None, + sep_boot_nonce_hash = None, + enable_keys = None, + encryption = None, + crypto_hash_method = 'sha2-384', + restore_info_nonce = None, + demote_production = None, + demote_secure = None, + lock_fuses = None, + ): + # Validate required arguments. + assert options is not None + assert log is not None + assert type(test_number) == int + assert outcome in [kOutcomeBlinky, kOutcomeDfu, kOutcomeBlinkyVcoOverride, kOutcomeBlinkyVcoDefault] + assert image_source in [kImageSourceDfu, kImageSourceNand, kImageSourceNor] + assert boot_device is not None + assert type(boot_device_empty) == bool + assert type(fuse_production_status) == bool + assert type(fuse_security_mode) == bool + assert ((type(fuse_security_domain) == int) and + (fuse_security_domain >= 0) and (fuse_security_domain <= 3)) + assert ((type(fuse_epoch) == int) and + (fuse_epoch >= 0) and (fuse_epoch <= 0x7f)) + assert ((fuse_ecid is not None) and + (fuse_ecid >= 0) and (fuse_ecid < (1 << 64))) + + if manifest: + assert ((type(epoch) == int) and + (epoch >= 0) and (epoch <= 0x7f)) + assert ((type(chip_id) == int) and + (chip_id >= 0) and (chip_id < (1 << 16))) + assert ((type(board_id) == int) and + (board_id >= 0) and (board_id < (1 << 8))) + assert (ecid is not None) and (ecid >= 0) and (ecid < (1 << 64)) + assert type(production_status) == bool + assert type(security_mode) == bool + assert ((type(security_domain) == int) and + (security_domain >= 0) and (security_domain <= 3)) + assert type(allow_mix_and_match) == bool + assert type(enable_keys) == bool + assert type(encryption) == bool + if sep_boot_nonce_hash is None: + sep_boot_nonce_hash = kDefaultSepNonceHash + # Set members. + self._description = description + self._manifest = manifest + self._platform = platform + self._images_dir = 'images_{}'.format(platform) + self._options = options + self._log = log + self._test_number = test_number + self._outcome = outcome + self._image_source = image_source + self._fuse_production_status = fuse_production_status + self._fuse_security_mode = fuse_security_mode + self._fuse_security_domain = fuse_security_domain + self._fuse_epoch = fuse_epoch + self._fuse_ecid = fuse_ecid + if fuse_cfg_fuse9 is None: + self._fuse_cfg_fuse9 = '0x00000000' + else: + assert (type(fuse_cfg_fuse9) == int) + self._fuse_cfg_fuse9 = '0x%08x' % fuse_cfg_fuse9 + self._epoch = epoch + self._chip_id = chip_id + self._board_id = board_id + self._boot_device = boot_device + self._test_mode = test_mode + self._boot_device_empty = boot_device_empty + self._force_dfu = force_dfu + self._ecid = ecid + self._production_status = production_status + self._security_mode = security_mode + self._security_domain = security_domain + self._allow_mix_and_match = allow_mix_and_match + self._ap_boot_nonce_hash = ap_boot_nonce_hash + self._sep_boot_nonce_hash = sep_boot_nonce_hash + self._enable_keys = enable_keys + self._encryption = encryption + self._crypto_hash_method = crypto_hash_method + self._restore_info_nonce = restore_info_nonce + self._demote_production = demote_production + self._demote_secure = demote_secure + self._lock_fuses = lock_fuses + + def Personalize(self, im4p, output_dir): + # Form args. + if self._options.personalize_img4: + args = self._options.personalize_img4.split(' ') + else: + args = kPersonalizeImg4Tool.split(' ') + args += ['-i', im4p, '-o', output_dir] + + if not self._manifest: + args += ['-O'] + else: + if self._chip_id is not None: + args += ['-c', '0x%04x' % self._chip_id] + if self._board_id is not None: + args += ['-b', '0x%x' % self._board_id] + if self._ecid is not None: + args += ['-e', '0x%x' % self._ecid] + if self._production_status: + args += ['-p'] + if self._security_mode: + args += ['-m'] + args += ['-W'] + if self._security_domain is not None: + args += ['-d', '%d' % self._security_domain] + if self._allow_mix_and_match: + args += ['-a'] + if self._ap_boot_nonce_hash is not None: + args += ['-n', '0x%x' % self._ap_boot_nonce_hash] + if self._sep_boot_nonce_hash is not None: + args += ['-s', '0x%x' % self._sep_boot_nonce_hash] + if self._crypto_hash_method == 'sha2-384': + args += ['-g 384'] + # disabling keys or demotions require a plist file with Trusted, EPRO, and ESEC defined + if (not self._enable_keys) or (self._demote_production) or (self._demote_secure): + object_properties = {'Trusted': self._enable_keys} + + if self._demote_production is not None: + object_properties['DPRO'] = True + + if self._demote_production: + assert self._production_status == True + object_properties['EPRO'] = False + else: + object_properties['EPRO'] = self._production_status + + if self._demote_secure: + assert self._security_mode == True + object_properties['ESEC'] = False + else: + object_properties['ESEC'] = self._security_mode + + all_properties = {'OBJP': object_properties} + plist_str = plistlib.writePlistToString(all_properties) + plist_file = '/tmp/personalize-{}.plist'.format(self._test_number) + f = open(plist_file, 'w') + f.write(plist_str) + f.close() + + args += ['-f', plist_file] + # personalize_img4 tool expects RestoreInfo nonce in big endian (only for LLB) + if (im4p.find('ibss') == -1) and self._restore_info_nonce is not None: + args += ['-r', '0x%x' % ByteSwap(self._restore_info_nonce, 64)] + args += ['-X'] + + # Convert args to an shell string. + invoke_string = ' '.join(args) + + # Execute personalize_img4 utility. + print('Invoking: %s' % invoke_string) + pipe = subprocess.Popen(invoke_string, shell=True) + if pipe.wait() == 0: + return True + else: + self._log.write('Invocation of personalize_img4 failed\n') + sys.stderr.write(ErrorText('Test %d: Invocation of personalize_img4 failed\n' % self._test_number)) + return False + + def DecodeTest(self, img4): + if self._options.img4decodetest: + args = self._options.img4decodetest.split(' ') + else: + args = kImg4DecodeTestTool.split(' ') + args += ['-c', '-i', img4] + if self._crypto_hash_method == 'sha2-384': + args += ['-n'] + invoke_string = ' '.join(args) + print('Invoking: %s' % invoke_string) + pipe = subprocess.Popen(invoke_string, shell=True) + if pipe.wait() == 0: + return True + else: + self._log.write('Invocation of img4decodetest failed\n') + sys.stderr.write(ErrorText('Test %d: Invocation of img4decodetest failed\n' % self._test_number)) + return False + + def BfnMaker(self, input, output): + if self._options.bfn_maker: + args = self._options.bfn_maker.split(' ') + else: + args = kBfnMaker.split(' ') + args += ['--pageSize', str(kBfnMakerPageSize)] + args += ['--format', str(kBfnMakerFormat)] + args += [input, output] + invoke_string = ' '.join(args) + pipe = subprocess.Popen(invoke_string, shell=True) + if pipe.wait() == 0: + return True + else: + self._log.write('Invocation of bfn_maker failed\n') + sys.stderr.write(ErrorText('Test %d: Invocation of bfn_maker failed\n' % self._test_number)) + return False + + def Execute(self): + # Log header. + self._log.write('-' * kLogWidth + '\n') + self._log.write('Test %d\n' % self._test_number) + self._log.write(textwrap.fill(self._description, width=kLogWidth) + '\n\n') + + # Figure out the input file variant. + image_type, location = {kImageSourceDfu: ('ibss', 'DFU'), + kImageSourceNand: ('illb', 'NAND'), + kImageSourceNor: ('illb', 'NOR')}[self._image_source] + + # FAST_NOR boot device is currenly only supported for test mode + if self._boot_device in ['FAST_NOR', 'SLOW_NOR']: + if self._test_mode == False: + self._log.write(' Skipping: FAST_NOR/SLOW_NOR boot device requires test mode\n\n') + sys.stderr.write(WarningText('Test %d: FAST_NOR/SLOW_NOR boot device requires test mode\n' % self._test_number)) + return False + + if self._boot_device == 'NOR': + self._boot_config = '0x%x' % (0 + (1 if self._test_mode else 0)) + elif self._boot_device == 'NAND': + self._boot_config = '0x%x' % (2 + (1 if self._test_mode else 0)) + elif self._boot_device == 'SLOW_NOR': + self._boot_config = '0x6' + elif self._boot_device == 'FAST_NOR': + self._boot_config = '0x7' + else: + assert 0, '_boot_device ' + self._boot_device + ' is unsupported' + + if self._encryption: + encryption_name = 'encrypted' + else: + encryption_name = 'unencrypted' + im4p_basename = 'rom_test_%s_%s' % (image_type, encryption_name) + im4p_filename = im4p_basename + '.im4p' + im4p_path = os.path.join(self._images_dir, im4p_filename) + + # If valid image in boot device, but force_dfu is set, we also need ibss + if self._force_dfu and self._boot_device_empty == False: + dfu_im4p_basename = 'rom_test_ibss_%s' % encryption_name + dfu_im4p_filename = dfu_im4p_basename + '.im4p' + dfu_im4p_path = os.path.join(self._images_dir, dfu_im4p_filename) + + # Output filename. + output_dir = kOutputDirPrefix + self._platform + pretty_filename_base = 'test_%d_%s_%s' % ( + self._test_number, image_type, encryption_name) + pretty_filename_img4 = pretty_filename_base + '.img4' + pretty_path_base = os.path.join(output_dir, pretty_filename_base) + pretty_path_img4 = pretty_path_base + '.img4' + + # If valid image in boot device, but force_dfu is set, we also need ibss + if self._force_dfu and self._boot_device_empty == False: + pretty_dfu_filename_base = 'test_%d_ibss_%s' % ( + self._test_number, encryption_name) + pretty_dfu_filename_img4 = pretty_dfu_filename_base + '.img4' + pretty_dfu_path_base = os.path.join(output_dir, pretty_dfu_filename_base) + pretty_dfu_path_img4 = pretty_dfu_path_base + '.img4' + + # Remove old output file if it exists. + img4 = os.path.join(output_dir, im4p_basename + '.img4') + if self._force_dfu and self._boot_device_empty == False: + dfu_img4 = os.path.join(output_dir, dfu_im4p_basename + '.img4') + try: + os.unlink(img4) + if dfu_img4 is not None: + os.unlink(dfu_img4) + except: + pass + # Personalize this case. + print('Personalize %s -> %s' % (im4p_filename, img4)) + if not self.Personalize(im4p_path, output_dir): + sys.stderr.write(ErrorText('Test %d failed to generate\n' % self._test_number)) + # Log failure + self._log.write(' Failed to generate!\n\n') + return False + + # Now, if force_dfu is set, personalize the 2nd image + if self._force_dfu and self._boot_device_empty == False: + print('Personalize %s -> %s' % (dfu_im4p_filename, dfu_img4)) + if not self.Personalize(dfu_im4p_path, output_dir): + sys.stderr.write(ErrorText('Test %d failed to generate\n' % self._test_number)) + # Log failure + self._log.write(' Failed to generate!\n\n') + return False + + # Rename the output file to the path we want for this test case. + os.rename(img4, pretty_path_img4) + print('Test %d generated %s' % (self._test_number, pretty_filename_img4)) + + if self._force_dfu and self._boot_device_empty == False: + os.rename(dfu_img4, pretty_dfu_path_img4) + print('Test %d generated %s' % (self._test_number, pretty_dfu_filename_img4)) + + # Test that there isn't a certificate vs manifest problem, because + # it's not worth burning a huge amount of DV time running it. + if self._manifest: + if not self.DecodeTest(pretty_path_img4): + self._log.write(' Failed decode test!\n') + self._log.write(' Check manifest vs cert is compatible\n\n') + sys.stderr.write(ErrorText('Test %d: Failed decode test\n' % self._test_number)) + return False + + if self._force_dfu and self._boot_device_empty == False: + if not self.DecodeTest(pretty_dfu_path_img4): + self._log.write(' Failed decode test!\n') + self._log.write(' Check manifest vs cert is compatible\n\n') + sys.stderr.write(ErrorText('Test %d: Failed decode test\n' % self._test_number)) + return False + + # If the source is NAND, we need to pass it through bfn_maker + if self._image_source == kImageSourceNand: + nand_filename = pretty_filename_base + '.nand' + nand_path = os.path.join(output_dir, nand_filename) + if not self.BfnMaker(pretty_path_img4, nand_path): + self._log.write(' Failed to create NAND image\n') + sys.stderr.write(ErrorText('Test %d: Failed to create NAND image\n' % self._test_number)) + return False + pretty_filename = nand_filename + else: + pretty_filename = pretty_filename_img4 + + # Log success. + settings = LogSettings() + + settings.Append( + 'Fuses', + [('Production Status', int(self._fuse_production_status)), + ('Security Mode', int(self._fuse_security_mode)), + ('Security Domain', self._fuse_security_domain), + ('Board ID', '0x%x' % ((self._board_id or kDefaultBoardId) >> kBoardIdStrapBits)), + ('Epoch', self._fuse_epoch), + ('SE Required', 0), + ('ECID_LO', '0x%08x' % (kDefaultEcid & 0xffffffff)), + ('ECID_HI', '0x%08x' % ((kDefaultEcid >> 32) & 0xffffffff)), + ('CFG_FUSE9', self._fuse_cfg_fuse9), + ]) + + settings.Append( + 'Straps', + [('Boot-device', self._boot_device), + ('Test mode', self._test_mode), + ('Boot-config', self._boot_config), + ('Board-id', (self._board_id or kDefaultBoardId) & ((1 << kBoardIdStrapBits) - 1)), + ('Force-dfu', self._force_dfu), + ('Boot Device Empty', self._boot_device_empty), + ]) + + if self._force_dfu and self._boot_device_empty == False: + pretty_dfu_filename = pretty_dfu_filename_img4 + else: + pretty_dfu_filename = '' + + settings.Append( + 'Images', + [(pretty_filename, ''), + (pretty_dfu_filename, ''), + ]) + + outcome_string = {kOutcomeBlinky: 'Blinky - AP writes {} to {}'.format(kDefaultBlinkyGPIOValue, kDefaultBlinkyGPIOReg), + kOutcomeDfu: 'DFU - AP writes {} to {}'.format(kDefaultDFUGPIOValue, kDefaultDFUGPIOReg), + kOutcomeBlinkyVcoOverride: 'Blinky: SecureROM PLLs (4, CPU) VCO_RCTRL_OW & VCO_RCTRL_SEL overridden', + kOutcomeBlinkyVcoDefault: 'Blinky: SecureROM PLLs (4, CPU) VCO_RCTRL_OW & VCO_RCTRL_SEL default values', + }[self._outcome] + + if self._outcome == kOutcomeDfu: + check_usb_clk = 'USB clock frequency' + check_usbotg = 'USB20PHY_CFG0/USB20PHY_CFG1' + check_usbotg_text = 'set to tunables values for Device mode' + else: + check_usb_clk = '' + check_usbotg = '' + check_usbotg_text = '' + + # JTAG gets enabled on a production part if it is demoted. + if self._fuse_production_status == True and self._demote_production == True and self._outcome == kOutcomeBlinky: + check_jtag = 'JTAG' + check_jtag_text = 'Starts disabled before test, but enabled after test' + else: + check_jtag = '' + check_jtag_text = '' + + + keys_state = {True: 'Enabled', + False: 'Disabled', + None: 'Disabled'}[self._enable_keys] + + if self._outcome == kOutcomeDfu: + fuses_locked_default = 'Unlocked (CFG_FUSE1.AP_LOCK = 0)' + else: + fuses_locked_default = 'Locked (CFG_FUSE1.AP_LOCK = 1)' + + fuses_locked_state = {True: 'Locked (CFG_FUSE1.AP_LOCK = 1)', + False: 'Unlocked (CFG_FUSE1.AP_LOCK = 0)', + None: fuses_locked_default}[self._lock_fuses] + + # For LLB boot, boot nonce pre-set to 0xdeadbeefdeadbeef. For iBSS boot, set to 0xddccbbaa78563412 + if pretty_filename.find('llb') != -1 and self._force_dfu == 0: + boot_nonce = 0xdeadbeefdeadbeef + else: + if self._restore_info_nonce is not None: + boot_nonce = self._restore_info_nonce + else: + boot_nonce = kDefaultApNonceLittleEndian + + if self._force_dfu and self._outcome == kOutcomeBlinky: + outcome_string += ' via iBSS in DFU mode' + + rom_state = {True: 'r/w access enabled', + False: 'r/w access disabled'}[self._outcome == kOutcomeDfu] + + settings.Append( + 'Boot Nonce in PMGR Scratch Registers', + [('PMGR_SCRATCH_10', '0x%x' % (boot_nonce & 0xffffffff)), + ('PMGR_SCRATCH_11', '0x%x' % ((boot_nonce >> 32) & 0xffffffff)), + ]) + + settings.Append( + 'PASS', + [('Outcome', outcome_string), + ('ROM', rom_state), + ('Keys - UID and GIDs', keys_state), + ('Fuses', fuses_locked_state), + (check_usb_clk, ''), + (check_usbotg, check_usbotg_text), + (check_jtag, check_jtag_text), + ]) + + settings.Append( + 'FAIL', + [('All PASS conditions not met', ''), + ]) + + if self._manifest: + settings.Append( + '(Informational only - Image4 Personalization Settings Used)', + [('Encryption', self._encryption), + ('Crypto Hash Method', self._crypto_hash_method), + ('Epoch', self._epoch), + ('Chip ID', self._chip_id), + ('Board ID', self._board_id), + ('ECID', self._ecid), + ('Production Status', self._production_status), + ('Security Mode', self._security_mode), + ('Enable Keys', self._enable_keys), + ('DPRO', self._demote_production), + ('DSEC', self._demote_secure), + ('Security Domain', self._security_domain), + ('Allow Mix and Match', self._allow_mix_and_match), + ('AP Boot Nonce Hash', self._ap_boot_nonce_hash), + ('Restore Info Nonce', self._restore_info_nonce), + ('SEP Boot Nonce Hash', self._sep_boot_nonce_hash), + ]) + + settings.Log(self._log) + return True + +def main(): + help_str = ('Use the source.\n') + class MyParser(optparse.OptionParser): + def format_epilog(self, formatter): + return self.epilog + parser = MyParser(epilog=help_str) + parser.add_option( + '--platform', + help='Override the default platform value of ' + kDefaultPlatform) + parser.add_option( + '--personalize_img4', + help='Override path to personalize_img4 tool') + parser.add_option( + '--img4decodetest', + help='Override path to img4decodetest tool') + parser.add_option( + '--bfn_maker', + help='Override path to bfn_maker tool') + (options, args) = parser.parse_args(sys.argv[1:]) + if args: + sys.stderr.write(ErrorText('Unused trailing options: ' + ' '.join(args) + '\n')) + return 1 + + thisPlat = options.platform + if thisPlat is None: + thisPlat = kDefaultPlatform + output_dir = kOutputDirPrefix + str(thisPlat) + + # Determine the chip_id and board_id based on the platform + if thisPlat not in kSupported_platforms: + sys.stderr.write(ErrorText('Only the following platforms are supported by this script: ' + str(kSupported_platforms))) + return 1 + elif thisPlat == kDefaultPlatform: + thisChip_id = kDefaultChipId + thisBoard_id = kDefaultBoardId + else: + assert false, "Unknown platform" + + # Prune any existing output and re-create the directory. + shutil.rmtree(output_dir, ignore_errors=True) + os.makedirs(output_dir) + + log = open(os.path.join(output_dir, kLogFileName), 'w') + log.write('This file generated by iBoot/apps/SecureROM/test_generator_img4\n') + log.write('Generated on: %s GMT\n\n' % time.asctime(time.gmtime())) + + # Result code + rc = True + + # Test 1: + # Boot from SPI NOR without a manifest in testmode. This facility is sometimes used in the factory + # environment and the test is to ensure that we can successfully + # boot in this environment. This is booting a non-secure image on a + # non-secure part in testmode. + rc &= PersonalizeImg4(manifest = False, + platform = thisPlat, + options = options, + log = log, + test_number = 1, + outcome = kOutcomeBlinky, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = False, + fuse_epoch = 0, + boot_device = 'NOR', + test_mode = True, + description = ('Boot image without manifest in testmode with SPI NOR') + ).Execute() + + # Test 2: + # Boot from SPI NOR with manifest that disables keys. This is booting a non-secure + # image on a non-secure part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 2, + outcome = kOutcomeBlinky, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = False, + fuse_epoch = 0, + production_status = False, + security_mode = False, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = True, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = False, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot image with manifest that disables keys on an insecure part') + ).Execute() + + # Test 3: + # Fail to boot a non-production image on a Production part in test mode. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 3, + outcome = kOutcomeDfu, + image_source = kImageSourceNor, + fuse_production_status = True, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NOR', + test_mode = True, + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Fail to boot a non-production image on a Production part in test mode') + ).Execute() + + # Test 4: + # Boot a development image on a development part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 4, + outcome = kOutcomeBlinky, + image_source = kImageSourceNand, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NAND', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot a development image on a development part') + ).Execute() + + # Test 5: + # Boot a production image on a production part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 5, + outcome = kOutcomeBlinky, + image_source = kImageSourceNor, + fuse_production_status = True, + fuse_security_mode = True, + fuse_epoch = 1, + production_status = True, + security_mode = True, + epoch = kDefaultEpochForServerSigning, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = True, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot a production image on a production part') + ).Execute() + + # Test 6: + # Test Epoch changes by having a chip epoch greater then the + # certificate epoch, and verifying that the object is rejected. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 6, + outcome = kOutcomeDfu, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 2, + production_status = False, + security_mode = True, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Fail to boot an image with epoch less than chip epoch') + ).Execute() + + # Test 7: + # Test USB DFU mode on a development device. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 7, + outcome = kOutcomeBlinky, + image_source = kImageSourceDfu, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NOR', + boot_device_empty = True, + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + description = ('Boot from USB in DFU mode with boot device set to NOR, but NOR is empty') + ).Execute() + + # Test 8: + # Test Force DFU when a valid image is in NOR. i.e. ignore valid NOR image + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 8, + outcome = kOutcomeBlinky, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + force_dfu = 1, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from USB in DFU mode with boot device set to NOR, and valid image in NOR, but force dfu set') + ).Execute() + + # Test 9: + # Boot an image in development mode on a production part (Demotion) + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 9, + outcome = kOutcomeBlinky, + image_source = kImageSourceNor, + fuse_production_status = True, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = True, + security_mode = True, + epoch = kDefaultEpochForServerSigning, + boot_device = 'NOR', + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = True, + demote_production = True, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot an image in development mode on a production part (Demotion)') + ).Execute() + + # Test 10: + # Boot from NOR (slow mode) a development image on a development part. + rc &= PersonalizeImg4(platform = thisPlat, + options = options, + log = log, + test_number = 10, + outcome = kOutcomeBlinky, + image_source = kImageSourceNor, + fuse_production_status = False, + fuse_security_mode = True, + fuse_epoch = 0, + production_status = False, + security_mode = True, + boot_device = 'SLOW_NOR', + test_mode = True, + chip_id = thisChip_id, + board_id = thisBoard_id, + ecid = kDefaultEcid, + allow_mix_and_match = False, + ap_boot_nonce_hash = kDefaultApNonceHash, + enable_keys = True, + encryption = False, + restore_info_nonce = kDefaultApNonceLittleEndian, + description = ('Boot from SPI NOR in slow mode a development image on a development part') + ).Execute() + + + log.write("In addition, provide a clock-tree dump (including spare clocks). Please pick a test from 1 to 10 for this dump.\n") + + log.close() + + if rc: + sys.stdout.write(PassText('\nSuccess\n')) + return 0 + else: + sys.stderr.write(ErrorText('\nTest plan contains errors\n')) + return 1 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/apps/iBoot/application.mk b/apps/iBoot/application.mk new file mode 100644 index 0000000..bcc868c --- /dev/null +++ b/apps/iBoot/application.mk @@ -0,0 +1,246 @@ +# Copyright (C) 2007-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +# +# Global headers that are independing of product, target, etc. +# +GLOBAL_HEADERS += \ + lib/mib/mib_nodes.h + +# +# iBoot application code. +# +ALL_OBJS += \ + $(LOCAL_DIR)/boot.o \ + $(LOCAL_DIR)/main.o \ + $(LOCAL_DIR)/menu_commands.o \ + $(LOCAL_DIR)/debugcmds.o \ + $(LOCAL_DIR)/default_env.o \ + $(LOCAL_DIR)/upgrade.o + +# +# Target module. +# +MODULES_BASIC += \ + target/$(TARGET) + +OPTIONS += \ + WITH_BOOT_STAGE=1 \ + WITH_TARGET_CONFIG=1 \ + IMAGE_MAX_COUNT=32 \ + WITH_APPLICATION_PUTCHAR=1 + +ifeq ($(BUILD),RELEASE) +OPTIONS += \ + TERSE_PANIC_STRINGS=1 +endif + +# +# Essential system modules. +# +MODULES_BASIC += \ + lib/heap \ + lib/nonce \ + lib/random \ + lib/paint \ + sys + +ifeq ($(IMAGE_FORMAT),) +$(error "IMAGE_FORMAT not set") +endif +ifeq ($(IMAGE_FORMAT),img3) +MODULES += \ + lib/image/image3 \ + lib/ticket +endif +ifeq ($(IMAGE_FORMAT),im4p) +MODULES += \ + lib/image/image4 +endif + +# +# Libraries to link with. +# +LIBRARY_MODULES += \ + lib/libc \ + lib/mib + +# +# Uncomment to enable boot time profiling. Shared memory console isn't compatible +# with boot profiling system, so it has to be ommitted when profiling +# +#MODULES_BASIC += \ +# lib/profile +#MODULES_ELIDE += \ +# drivers/apple/shmcon + +################################################################################ +# +# Define option and module lists for basic differentiating features. +# +# Note that these lists are not intended to be overridden by target or platform. +# +################################################################################ + +# +# Interactive console support. +# +OPTIONS_CONSOLE += \ + WITH_MENU=1 + +MODULES_CONSOLE += \ + lib/env + +# +# Interactive console in release builds get the dumb menu. +# +ifeq ($(BUILD),RELEASE) +OPTIONS_CONSOLE += \ + WITH_SIMPLE_MENU=1 +endif + +# +# Functional tests and related commands will be added to console only in debug +# builds. +# +ifeq ($(BUILD),DEBUG) +endif + +# +# This option forces the restore host to bootstrap into restore OS via iBEC +# rather than immediately from current product. +# +OPTIONS_RESTORE_STRAP += \ + WITH_RESTORE_STRAP=1 + + +# iBEC is willing to tolerate any NAND epoch, as it may be used during +# restore to boot upgrade bits from an older install's storage +# device. +# +# XXX this needs to be a runtime option as this code is now in the library. +# +OPTIONS_RESTORE_BOOT += \ + WITH_RESTORE_BOOT=1 \ + AND_DISABLE_EPOCH_CHECK=1 + + +################################################################################ +# +# Define option and module lists for DFU-mode versus recovery mode. +# +# Note that only one of these should ever be included in any particular product. +# Also, these lists are not intended to be overridden by target or platform. +# +################################################################################ + +# +# DFU mode products do USB DFU rather than recovery mode. +# +OPTIONS_DFU += \ + WITH_DFU_MODE=1 + +MODULES_DFU += + +# +# Recovery mode products get additional logic, including console support +# since it is required for recovery mode to function properly. +# +OPTIONS_RECOVERY += \ + $(OPTIONS_CONSOLE) \ + WITH_RECOVERY_MODE=1 + +MODULES_RECOVERY += \ + $(MODULES_CONSOLE) + + +################################################################################ +# +# Define option and module lists for various feature sets. +# +# It is expected that these lists are to be decorated with platform +# and/or target-specific support reflecting differences in hardware +# required to support each feature. +# +################################################################################ + +# +# Display drivers support. +# +MODULES_DISPLAY += + +# +# Firmware image storage support. +# +MODULES_FIRMWARE += \ + lib/blockdev + +# +# NVRAM storage support. +# +MODULES_NVRAM += \ + lib/nvram + +# +# RAMDISK support. +# +MODULES_RAMDISK += \ + lib/ramdisk + +# +# Syscfg storage support. +# +MODULES_SYSCFG += \ + lib/syscfg + +# +# Filesystem support. +# +MODULES_FILESYSTEM += \ + lib/fs/hfs + +OPTIONS_FILESYSTEM += \ + WITH_MASS_STORAGE=1 + + +################################################################################ +# +# Define option and modules lists for composition of features required to +# boot XNU. +# +# This really shouldn't be overridden in any platform or target makefiles +# +################################################################################ + +# +# Products that boot the kernel get some extra options. +# +OPTIONS_BOOT += \ + WITH_BOOT_XNU=1 + +# +# Core technology-neutral software modules required to support booting XNU. +# +MODULES_BOOT += \ + lib/devicetree \ + lib/macho \ + lib/paniclog + +# +# The following feature modules list are also needed to boot XNU. +# +MODULES_BOOT += \ + $(MODULES_FIRMWARE) \ + $(MODULES_NVRAM) \ + $(MODULES_RAMDISK) \ + $(MODULES_SYSCFG) diff --git a/apps/iBoot/boot.c b/apps/iBoot/boot.c new file mode 100644 index 0000000..6a27178 --- /dev/null +++ b/apps/iBoot/boot.c @@ -0,0 +1,707 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_EFFACEABLE +#include +#endif + +#if WITH_CONSISTENT_DBG +#include +#endif + +struct image_device { + const char *name; + off_t image_table_offset; // negative offset means from top of device +}; + +#include + +extern void boot_darwin(void *ptr, void *arg) __noreturn; + +static int boot_flash(u_int32_t type, enum boot_target target); +static int boot_diagnostics_fs(void); + +void find_boot_images(void) +{ + PROFILE_ENTER('FBI'); +#if WITH_BLOCKDEV + struct blockdev *rom_bdev; + uint32_t i; + + /* iterate over each of the rom devices, looking for images and syscfg data */ + for (i=0; i < sizeof(platform_image_devices)/sizeof(platform_image_devices[0]); i++) { + rom_bdev = lookup_blockdev(platform_image_devices[i].name); + if (!rom_bdev) + continue; + + image_search_bdev(rom_bdev, platform_image_devices[i].image_table_offset, 0); + } + +#if WITH_SYSCFG + /* hook up syscfg data */ + for (i=0; i < sizeof(platform_syscfg_devices)/sizeof(platform_syscfg_devices[0]); i++) { + if (lookup_blockdev(platform_syscfg_devices[i].name)) { + if (syscfgInitWithBdev(platform_syscfg_devices[i].name)) + break; + } + } +#endif /* WITH_SYSCFG */ +#endif /* WITH_BLOCKDEV */ + + image_dump_list(false); + PROFILE_EXIT('FBI'); +} + +static int +boot_flash(u_int32_t type, enum boot_target target) +{ + addr_t image_ptr; + size_t image_len; + + image_ptr = INSECURE_MEMORY_BASE; + image_len = INSECURE_MEMORY_SIZE; + + PROFILE_ENTER('ILT'); + if (image_load_type(&image_ptr, &image_len, type, 0)) + return -1; + PROFILE_EXIT('ILT'); + + /* consolidate environment */ + security_consolidate_environment(); + + dprintf(DEBUG_INFO, "boot: loaded image at %p, len %zd\n", (void *)image_ptr, image_len); + + /* boot it */ + prepare_and_jump(target, (void *)image_ptr, NULL); + + return 0; +} + +int boot_check_stage(void) +{ +#if WITH_HW_POWER + int result; + uint8_t data, boot_stage; + uint32_t boot_fail, panic_fail; + + if (power_is_suspended() || power_needs_precharge()) return 0; + + result = power_get_nvram(kPowerNVRAMiBootStageKey, &boot_stage); + if (result != 0) return result; + + if (boot_stage == kPowerNVRAMiBootStageOff) return 0; + + power_set_nvram(kPowerNVRAMiBootErrorStageKey, boot_stage); + + result = power_get_nvram(kPowerNVRAMiBootErrorCountKey, &data); + if (result != 0) return result; + + boot_fail = (data >> kPowerNVRAMiBootErrorBootShift) & kPowerNVRAMiBootErrorCountMask; + panic_fail = (data >> kPowerNVRAMiBootErrorPanicShift) & kPowerNVRAMiBootErrorCountMask; + + if (boot_stage == kPowerNVRAMiBootStagePanicSave) { + if (panic_fail < kPowerNVRAMiBootErrorCountMask) panic_fail++; + } else { + if (boot_fail < kPowerNVRAMiBootErrorCountMask) boot_fail++; + } + + data = (boot_fail << kPowerNVRAMiBootErrorBootShift) | (panic_fail << kPowerNVRAMiBootErrorPanicShift); + + power_set_nvram(kPowerNVRAMiBootErrorCountKey, data); + + power_cancel_buttonwait(); +#endif + + return 0; +} + +int boot_set_stage(uint8_t boot_stage) +{ +#if WITH_HW_POWER + if (power_is_suspended() || power_needs_precharge()) return 0; + + power_set_nvram(kPowerNVRAMiBootStageKey, boot_stage); +#endif + + return 0; +} + +int boot_clear_error_count(void) +{ +#if WITH_HW_POWER + uint8_t data; + + data = (0 << kPowerNVRAMiBootErrorBootShift) | (0 << kPowerNVRAMiBootErrorPanicShift); + + power_set_nvram(kPowerNVRAMiBootErrorCountKey, data); +#endif + + return 0; +} + +int boot_error_count(uint32_t *boot_fail_count, uint32_t *panic_fail_count) +{ + int result = 0; + uint32_t boot_fail = 0, panic_fail = 0; +#if WITH_HW_POWER + uint8_t data = 0; + + result = power_get_nvram(kPowerNVRAMiBootErrorCountKey, &data); + if (result != 0) return result; + + boot_fail = (data >> kPowerNVRAMiBootErrorBootShift) & kPowerNVRAMiBootErrorCountMask; + panic_fail = (data >> kPowerNVRAMiBootErrorPanicShift) & kPowerNVRAMiBootErrorCountMask; +#endif + + if (boot_fail_count != 0) *boot_fail_count = boot_fail; + if (panic_fail_count != 0) *panic_fail_count = panic_fail; + + return result; +} + +#if PRODUCT_IBOOT && WITH_HW_POWER && WITH_BOOT_STAGE +void boot_check_panic(void) +{ + int result; + uint8_t error_stage; + + /* LLB saved the original stage in ErrorStageKey */ + result = power_get_nvram(kPowerNVRAMiBootErrorStageKey, &error_stage); + if (result != 0) goto panic_clear; + + if (error_stage == kPowerNVRAMiBootStagePanicSave) { + /* keep alive a little longer */ + platform_watchdog_tickle(); + /* prevent looping in case of failure in save_panic_log */ + result = power_set_nvram(kPowerNVRAMiBootErrorStageKey, 0); + if (result != 0) goto panic_clear; + boot_set_stage(kPowerNVRAMiBootStagePanicReboot); + platform_init_mass_storage_panic(); + save_panic_log(); + /* reset the system, boot clean */ + dprintf(DEBUG_CRITICAL, "Panic saved, full reset.\n"); + platform_system_reset(false); + } else if (error_stage == kPowerNVRAMiBootStageBooted) { + dprintf(DEBUG_CRITICAL, "iBoot not saving panic log.\n"); + } + +panic_clear: + clear_panic_region(0); +} +#endif + +int boot_iboot(void) +{ + return boot_flash(IMAGE_TYPE_IBOOT, BOOT_IBOOT); +} + +#if WITH_DALI + +int boot_dali_flash(void) +{ + addr_t image_ptr; + size_t image_len; + void* dali_arg = NULL; + + image_ptr = INSECURE_MEMORY_BASE; + image_len = INSECURE_MEMORY_SIZE; + + PROFILE_ENTER('ILT'); + if (image_load_type(&image_ptr, &image_len, IMAGE_TYPE_DALI, 0)) { + dprintf(DEBUG_CRITICAL, "Unable to load dali firmware from flash\n"); + return -1; + } + PROFILE_EXIT('ILT'); + + dali_arg = target_prepare_dali(); + + /* consolidate environment */ + security_consolidate_environment(); + + dprintf(DEBUG_INFO, "dali: loaded image at %p, len %zu\n", (void *)image_ptr, image_len); + + /* boot it */ + prepare_and_jump(BOOT_DALI, (void *)image_ptr, dali_arg); +} + +int do_daliboot(int argc, struct cmd_arg *args) +{ + u_int32_t type; + + if (argc < 2) { + // After , ASP doesn't support finding Dali in the LLB blkdev. Initializing both LLB firmware + // and ASP firmware at the same time is untested, so we are no longer supporting this debug path. + printf("This variant of the dali command is no longer supported. However, you can still usb get / dali $loadaddr.\n"); + return -1; + } else { + const addr_t addr = args[1].u; +#if WITH_IMAGE3 + if (security_allow_memory((void *)addr, DEFAULT_KERNEL_SIZE) && + security_allow_modes(kSecurityModeExUntrust)) { +#elif WITH_IMAGE4 + if (security_allow_memory((void *)addr, DEFAULT_KERNEL_SIZE)) { +#endif + addr_t secure_addr = DEFAULT_KERNEL_ADDRESS; + size_t secure_len = DEFAULT_KERNEL_SIZE; + type = IMAGE_TYPE_DALI; + if (image_load_memory(addr, DEFAULT_KERNEL_SIZE, &secure_addr, &secure_len, &type, 1, NULL, 0)) { + printf("Memory image not valid\n"); + } else { + void* dali_arg = NULL; + dali_arg = target_prepare_dali(); + + /* consolidate environment */ + security_consolidate_environment(); + + printf("jumping into dali image at %p\n", (void *)secure_addr); + prepare_and_jump(BOOT_DALI, (void *)secure_addr, dali_arg); + } + } else { + printf("Permission Denied\n"); + } + } + + return -1; + + +} +MENU_COMMAND_DEVELOPMENT(dali, do_daliboot, "[$loadaddr] boot into dali.", NULL); + +#endif /* WITH_DALI */ + +#if WITH_FS +static int +boot_diagnostics_fs(void) +{ + const char *diags_paths; + addr_t image_ptr; + size_t image_len; + char bootfile[512]; + u_int32_t type; + + /* try booting diags from the filesystem */ + diags_paths = env_get("diags-path"); + + /* try to mount the boot file system */ + if (mount_bootfs() < 0) { + dprintf(DEBUG_INFO, "root filesystem mount failed\n"); + return -1; + } + + if (NULL != diags_paths) { + + dprintf(DEBUG_INFO, "loading diagnostics from %s\n", diags_paths); + + /* build the diags file */ + bootfile[0] = 0; + strlcat(bootfile, "/boot", 512); + strlcat(bootfile, diags_paths, 512); + + /* load the diags image */ + image_ptr = DEFAULT_KERNEL_ADDRESS; + image_len = DEFAULT_KERNEL_SIZE; + type = IMAGE_TYPE_DIAG; + if (image_load_file(bootfile, &image_ptr, &image_len, &type, 1, NULL, 0) == 0) { + dprintf(DEBUG_INFO, "loaded diagnostics at %p, len %zd\n", (void *)image_ptr, image_len); + + /* consolidate environment */ + security_consolidate_environment(); + + /* boot it */ + prepare_and_jump(BOOT_DIAGS, (void *)image_ptr, NULL); + } + } + + fs_unmount("/boot"); + + dprintf(DEBUG_CRITICAL, "failed to load diagnostics\n"); + + return -1; +} +#endif /* WITH_FS */ + +int boot_diagnostics(void) +{ + /* try booting diags from a flash image first */ + boot_flash(IMAGE_TYPE_DIAG, BOOT_DIAGS); + +#if WITH_FS + boot_diagnostics_fs(); +#endif + return -1; +} + +int do_diagboot(int argc, struct cmd_arg *args) +{ + u_int32_t type; + + if (argc < 2) { + boot_diagnostics(); + } else { + const addr_t addr = args[1].u; +#if WITH_IMAGE3 + if (security_allow_memory((void *)addr, DEFAULT_KERNEL_SIZE) && + security_allow_modes(kSecurityModeExUntrust)) { +#elif WITH_IMAGE4 + if (security_allow_memory((void *)addr, DEFAULT_KERNEL_SIZE)) { +#endif + addr_t secure_addr = DEFAULT_KERNEL_ADDRESS; + size_t secure_len = DEFAULT_KERNEL_SIZE; + type = IMAGE_TYPE_DIAG; + if (image_load_memory(addr, DEFAULT_KERNEL_SIZE, &secure_addr, &secure_len, &type, 1, NULL, 0)) { + printf("Memory image not valid\n"); + } else { + /* consolidate environment */ + security_consolidate_environment(); + + printf("jumping into diags image at %p\n", (void *)secure_addr); + prepare_and_jump(BOOT_DIAGS, (void *)secure_addr, NULL); + } + } else { + printf("Permission Denied\n"); + } + } + + return -1; +} + +MENU_COMMAND_DEVELOPMENT(diags, do_diagboot, "boot into diagnostics (if present)", NULL); + +#if WITH_MACHO +void boot_darwin(void *ptr, void *arg) +{ +#if WITH_CONSISTENT_DBG + consistent_debug_update_ap_cpr(DBG_CPR_STATE_RUNNING, 0); +#endif +#if WITH_EFFACEABLE + effaceable_consume_nonce(0); +#endif + clear_panic_region(0); + prepare_and_jump(BOOT_DARWIN, ptr, arg); +} + +int do_bootx(int argc, struct cmd_arg *argv) +{ + int err = -1; + addr_t entry; + addr_t boot_args; + addr_t addr = DEFAULT_LOAD_ADDRESS; + u_int32_t type; + + PROFILE_ENTER('Btx'); + +#if !RELEASE_BUILD + if (argc > 2 || ((argc > 1) && !strcmp("help", argv[1].str))) { + printf("usage:\n\t%s [
]\n", argv[0].str); + err = -1; + goto error; + } + + if (argc > 1) + addr = argv[1].u; +#endif + + if (!security_allow_memory((void *)addr, DEFAULT_KERNEL_SIZE)) { + printf("Permission Denied\n"); + goto error; + } + + printf("Attempting to validate kernelcache @ %p\n", (void *)addr); + +// Image3 requires the non-restore types +#if WITH_IMAGE4 + type = IMAGE_TYPE_KERNELCACHE_RESTORE; +#else + type = IMAGE_TYPE_KERNELCACHE; +#endif + + err = load_kernelcache(addr, DEFAULT_KERNEL_SIZE, type, &entry, &boot_args); + if (err < 0) { + printf("error loading kernelcache\n"); + dprintf(DEBUG_INFO, "error loading kernelcache %d\n", err); + goto error; + } + + printf("kernelcache prepped at address %p\n", (void *)entry); + + PROFILE_EXIT('Btx'); + + boot_darwin((void *)entry, (void *)boot_args); +error: + return err; +} + +/* This command is not used by release products other than those allowed to perform restore boot. */ +#if !RELEASE_BUILD || WITH_RESTORE_BOOT +MENU_COMMAND(bootx, do_bootx, "boot a kernel cache at specified address", NULL); +#endif + +int do_memboot(int argc, struct cmd_arg *argv) +{ + addr_t addr = DEFAULT_LOAD_ADDRESS; + addr_t entry; + addr_t boot_args; + addr_t ramdisk_addr; + size_t len; + size_t ramdisk_size; + struct blockdev *bdev = NULL; + struct image_info *image = NULL; + int err = -1; + + len = env_get_uint("filesize", 0); + +#if !RELEASE_BUILD + if ((argc > 3) || ((argc > 1) && !strcmp("help", argv[1].str))) { + printf("usage:\n\t%s [] [
]\n", argv[0].str); + return -1; + } + + addr = env_get_uint("loadaddr", (uintptr_t)DEFAULT_LOAD_ADDRESS); + + if (argc > 1) + len = argv[1].u; + if (argc > 2) + addr = argv[2].u; +#endif + + if (len == 0) { + printf("filesize variable invalid or not set, aborting\n"); + return -1; + } + if (len > DEFAULT_RAMDISK_SIZE) { + printf("Combo image too large\n"); + return -1; + } + if (!security_allow_memory((void *)addr, len)) { + printf("Permission Denied\n"); + return -1; + } + + bdev = create_mem_blockdev("mem", (void *)addr, len, 64); + + image_search_bdev(bdev, 0, IMAGE_OPTION_MEMORY); + image_dump_list(false); + +#if WITH_TICKET + err = ticket_load(); + if (err < 0) { + dprintf(DEBUG_INFO, "Falling back to image3 validation\n"); + } +#endif + + err = load_ramdisk(&ramdisk_addr, &ramdisk_size); + if (err < 0) { + printf("error loading ramdisk\n"); + dprintf(DEBUG_INFO, "error loading ramdisk %d\n", err); + goto error; + } + + image = image_find(IMAGE_TYPE_KERNELCACHE); + if (image == NULL) { + printf("kernelcache not found\n"); + goto error; + } + + err = load_kernelcache_image(image, IMAGE_TYPE_KERNELCACHE, &entry, &boot_args); + if (err < 0) { + printf("error loading kernelcache\n"); + dprintf(DEBUG_INFO, "error loading kernelcache %d\n", err); + goto error; + } + + printf("kernelcache prepped at address %p\n", (void *)entry); + + boot_darwin((void *)entry, (void *)boot_args); +error: + if (bdev != NULL) { + image_free_bdev(bdev); + free(bdev); + } + return err; +} + +/* This command is not used by release products other than those allowed to perform restore boot. */ +#if !RELEASE_BUILD || WITH_RESTORE_BOOT +MENU_COMMAND(memboot, do_memboot, "boot a combo devicetree/ramdisk/kernelcache at specified address", NULL); +#endif + +#endif /* WITH_MACHO */ + +#if WITH_FS && WITH_ENV && WITH_MACHO && WITH_DEVICETREE +/* + * Support for booting from a filesystem. + */ +int +mount_bootfs(void) +{ + const char *bootdevice; + char bootsubdevice[128]; + + bootdevice = env_get("boot-device"); + if (!bootdevice) { + dprintf(DEBUG_INFO, "error: boot-device not set\n"); + return -1; + } + + /* assume the first partition is the fs but allow an override */ + snprintf(bootsubdevice, 128, "%s%c", bootdevice, (char)env_get_uint("boot-partition", 0) + 'a'); + + return mount_bootfs_from_device(bootsubdevice); +} + +int +mount_bootfs_from_device(const char *device) +{ + int err; + int i; + const char *bootfs; + + /* see if the subdevice exists */ + if (!lookup_blockdev(device)) { + dprintf(DEBUG_INFO, "boot device '%s' does not exist\n", device); + platform_record_breadcrumb("mount_bootfs", "!lookup-blockdev"); + return -1; + } + + /* iterate over filesystems looking for one that will mount this partition */ + for (i = 0; ; i++) { + if ((bootfs = fs_get_fsname(i)) == NULL) { + dprintf(DEBUG_INFO, "can't find a filesystem willing to mount the boot partition\n"); + platform_record_breadcrumb("mount_bootfs", "unknown-fs"); + return -1; + } + + dprintf(DEBUG_INFO, "trying System mount from device '%s', fs '%s', at /boot\n", device, bootfs); + err = fs_mount(device, bootfs, "/boot"); + if (err == 0) { + break; + } + else { + platform_record_breadcrumb_int("fs_mount_err", err); + } + } + + dprintf(DEBUG_INFO, "mount successful\n"); + + return 0; +} + +/* + * Mount the boot filesystem, load an optional ramdisk, load and boot the + * configured kernelcache. + */ +int mount_and_boot_system(void) +{ + int err; + const char *bootpath; + const char *bootramdisk; + addr_t entry; + addr_t boot_args; + char *bootfile; + + err = -1; + bootfile = NULL; + + /* allocate storage for the kernelcache/ramdisk paths */ + bootfile = (char *)malloc(FS_MAXPATHLEN); + + /* find the kernelcache path */ + bootpath = env_get("boot-path"); + if (!bootpath) { + dprintf(DEBUG_INFO, "error: boot-path not set\n"); + goto fail; + } + + PROFILE_ENTER('Mfs'); + /* try to mount the boot file system */ + err = mount_bootfs(); + if (err < 0) { + dprintf(DEBUG_CRITICAL, "root filesystem mount failed\n"); + goto fail; + } + PROFILE_EXIT('Mfs'); + + /* look for optional ramdisk path, load it if set */ + bootramdisk = env_get("boot-ramdisk"); + if ((NULL != bootramdisk) && (0 != bootramdisk[0])) { + /* build the ramdisk path */ + snprintf(bootfile, FS_MAXPATHLEN, "/boot%s", bootramdisk); + + /* load the ramdisk */ + err = load_ramdisk_file(bootfile); + if (err < 0) { + dprintf(DEBUG_CRITICAL, "ramdisk file invalid\n"); + goto fail; + } + } + + /* build the kernelcache path */ + snprintf(bootfile, FS_MAXPATHLEN, "/boot%s", bootpath); + + PROFILE_ENTER('LKF'); + /* load the kernelcache */ + err = load_kernelcache_file(bootfile, IMAGE_TYPE_KERNELCACHE, &entry, &boot_args); + dprintf(DEBUG_INFO, "load_kernelcache returns %d, entry at %p\n", err, (void *)entry); + if (err < 0) + goto fail; + PROFILE_ENTER('LKF'); + + /* boot it */ + dprintf(DEBUG_INFO, "booting kernel\n"); + boot_darwin((void *)entry, (void *)boot_args); + + /* shouldn't get here */ + panic("returned from boot!\n"); + +fail: + if (NULL != bootfile) + free(bootfile); + fs_unmount("/boot"); /* harmless if mount failed */ + return err; +} + +static int +do_fsboot(int argc, struct cmd_arg *argv) +{ + + if (argc >= 2 && !strcmp(argv[1].str, "help")) { + printf("%s: load file from $boot-device on partition $boot-partition at path $boot-path\n", argv[0].str); + return -1; + } + + return mount_and_boot_system(); +} + +MENU_COMMAND_DEVELOPMENT(fsboot, do_fsboot, "boot kernelcache from filesystem", NULL); + +#endif /* WITH_FS && WITH_ENV && WITH_MACHO && WITH_DEVICETREE */ diff --git a/apps/iBoot/config/alcatrazref-config.mk b/apps/iBoot/config/alcatrazref-config.mk new file mode 100644 index 0000000..fe7fe6d --- /dev/null +++ b/apps/iBoot/config/alcatrazref-config.mk @@ -0,0 +1,74 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# AlkatrazRef iboot bootloader build config +PLATFORM := s5l8960x +SUB_PLATFORM := s5l8960x +ARCH := arm64 +HW_TIMER := architected +BOOT_CONFIG := nand +AMC_REG_VERSION := 3 +AMP_FILE_VERSION := 2 +ADBE_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/samsung/dwi \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + +TZ0_SIZE := 6*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/appletv3-config-base.mk b/apps/iBoot/config/appletv3-config-base.mk new file mode 100644 index 0000000..b46f086 --- /dev/null +++ b/apps/iBoot/config/appletv3-config-base.mk @@ -0,0 +1,110 @@ +# Copyright (C) 2009-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# j33 iboot bootloader build config +PLATFORM := s5l8940x +ARCH := arm +NO_AMP_CALIBRATION := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/rosc \ + drivers/samsung/swi \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg + +ifeq ($(SUB_PLATFORM),s5l8947x) + MODULES_BASIC += \ + drivers/apple/amp +else + MODULES_BASIC += \ + drivers/apple/amg +endif + +MODULES_BOOT += \ + drivers/apple/mcu + +ifeq ($(SUB_PLATFORM),s5l8942x) +MODULES_DISPLAY += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/displayport \ + drivers/samsung/rgbout \ + drivers/samsung/displayport +else +MODULES_DISPLAY += +endif + +ifeq ($(SUB_PLATFORM),s5l8947x) +MODULES_DISPLAY += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/hdmi \ + drivers/samsung/rgbout \ + drivers/samsung/hdmi8947 +else +MODULES_DISPLAY += +endif + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +# override default platform display region size config +DISPLAY_SIZE := 31*1024*1024 + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/appletv4-config-base.mk b/apps/iBoot/config/appletv4-config-base.mk new file mode 100644 index 0000000..2d88d7c --- /dev/null +++ b/apps/iBoot/config/appletv4-config-base.mk @@ -0,0 +1,83 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# appletv4 iboot bootloader build config +PLATFORM := s5l8960x +SUB_PLATFORM := s5l8960x +ARCH := arm64 +HW_TIMER := architected +BOOT_CONFIG := nand +AMC_REG_VERSION := 3 +AMP_FILE_VERSION := 2 +ADBE_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/mcu \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/samsung/dwi \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/ti/ths7383 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/apple/dpb \ + drivers/apple/dither \ + drivers/displayport \ + drivers/samsung/displayport + +include $(APPDIR)/products.mk + +# You can override the default memory configuration here but you probably shouldn't. + diff --git a/apps/iBoot/config/appletv5-config-base.mk b/apps/iBoot/config/appletv5-config-base.mk new file mode 100644 index 0000000..675fa02 --- /dev/null +++ b/apps/iBoot/config/appletv5-config-base.mk @@ -0,0 +1,89 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# appletv5 iBoot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 +LPDP_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/voltage_knobs \ + drivers/apple/mcu \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/samsung/dwi \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/ti/ths7383 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/displaypipe \ + drivers/apple/dpb \ + drivers/apple/dither \ + drivers/displayport \ + drivers/analogix/displayport \ + drivers/apple/lpdp_phy + + # override platform default memory map +ASP_SIZE := 10*1024*1024 +TZ0_SIZE := 8*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/appletv6-config-base.mk b/apps/iBoot/config/appletv6-config-base.mk new file mode 100644 index 0000000..ac1b47d --- /dev/null +++ b/apps/iBoot/config/appletv6-config-base.mk @@ -0,0 +1,82 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# appletv6 iBoot bootloader build config +PLATFORM := s8000 +SUB_PLATFORM := s8001 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +ADBE_VERSION := 2 +LPDP_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/voltage_knobs \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/analogix/displayport \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/displaypipe \ + drivers/apple/dither \ + drivers/apple/lpdp_phy \ + drivers/apple/reconfig \ + drivers/displayport + +# Override platform default memory map +ASP_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + +# You can override the default SRAM/SDRAM configuration here but probably shouldn't. diff --git a/apps/iBoot/config/b137-config.mk b/apps/iBoot/config/b137-config.mk new file mode 100644 index 0000000..cd2e57a --- /dev/null +++ b/apps/iBoot/config/b137-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# B137 iboot bootloader build config +TARGET := iaccy1 + +include $(GET_LOCAL_DIR)/iaccy1-config-base.mk diff --git a/apps/iBoot/config/b165-config.mk b/apps/iBoot/config/b165-config.mk new file mode 100644 index 0000000..76bd3f2 --- /dev/null +++ b/apps/iBoot/config/b165-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# B165 iboot bootloader build config +TARGET := iaccy1 + +include $(GET_LOCAL_DIR)/iaccy1-config-base.mk diff --git a/apps/iBoot/config/b184-config.mk b/apps/iBoot/config/b184-config.mk new file mode 100644 index 0000000..0328548 --- /dev/null +++ b/apps/iBoot/config/b184-config.mk @@ -0,0 +1,104 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# B184 iboot bootloader build config +TARGET := b184 +TARGET_HAS_BASEBAND := 0 + + +PLATFORM := s5l8960x +ARCH := arm64 +HW_TIMER := architected +BOOT_CONFIG := nand +AMC_REG_VERSION := 3 +AMP_FILE_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/samsung/dwi \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/ti/ths7383 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8960X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1024*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8960X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1024*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8960X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8960X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +# override default platform display region size config +# TODO: We don't have a display. Can we reclaim this memory? (s5l8960x's memmap assumes one) +#DISPLAY_SIZE := 64*1024*1024 +TZ0_SIZE := 6*1024*1024 + + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/b238-config.mk b/apps/iBoot/config/b238-config.mk new file mode 100644 index 0000000..91d5a71 --- /dev/null +++ b/apps/iBoot/config/b238-config.mk @@ -0,0 +1,78 @@ +# Copyright (C) 2013-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# b238 iProd6,1 iboot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 + +TARGET := b238 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie + +# Override default platform memory map +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/boot-from-nand-template.mk b/apps/iBoot/config/boot-from-nand-template.mk new file mode 100644 index 0000000..ff28d51 --- /dev/null +++ b/apps/iBoot/config/boot-from-nand-template.mk @@ -0,0 +1,28 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +SUBMODULES_NAND_BOOT += \ + $(SUBMODULES_NAND) \ + drivers/flash_nand/boot + +MODULES_FIRMWARE += \ + $(SUBMODULES_NAND_BOOT) \ + drivers/flash_nand/boot/firmware + +MODULES_NVRAM += \ + $(SUBMODULES_NAND_BOOT) \ + drivers/flash_nand/boot/nvram + +MODULES_SYSCFG += \ + $(SUBMODULES_NAND_BOOT) \ + drivers/flash_nand/boot/syscfg + +MODULES_FILESYSTEM += \ + $(SUBMODULES_NAND_BOOT) \ + drivers/flash_nand/ftl diff --git a/apps/iBoot/config/boot-from-nor-template.mk b/apps/iBoot/config/boot-from-nor-template.mk new file mode 100644 index 0000000..ca3434a --- /dev/null +++ b/apps/iBoot/config/boot-from-nor-template.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +MODULES_FIRMWARE += \ + $(SUBMODULES_NOR) + +MODULES_NVRAM += \ + $(SUBMODULES_NOR) + +MODULES_SYSCFG += \ + $(SUBMODULES_NOR) + +MODULES_FILESYSTEM += \ + $(SUBMODULES_NAND) \ + drivers/flash_nand/ftl diff --git a/apps/iBoot/config/capriref-config.mk b/apps/iBoot/config/capriref-config.mk new file mode 100644 index 0000000..cc97bba --- /dev/null +++ b/apps/iBoot/config/capriref-config.mk @@ -0,0 +1,74 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# CAPRIREF iboot bootloader build config + +TARGET := capriref +PLATFORM := t7000 +SUB_PLATFORM ?= t7001 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 5 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/synopsys/usbotg + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie + +# override default platform display region size config +DISPLAY_SIZE := 64*1024*1024 +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/cyclonic-config.mk b/apps/iBoot/config/cyclonic-config.mk new file mode 100644 index 0000000..f31b02d --- /dev/null +++ b/apps/iBoot/config/cyclonic-config.mk @@ -0,0 +1,63 @@ +# Copyright (C) 2011-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# swifter/fastsim iboot bootloader build config +PLATFORM := s5l8960x +SUB_PLATFORM := s5l8960x +ARCH := arm64 +HW_TIMER := architected +BOOT_CONFIG := nand +AMC_REG_VERSION := 3 +AMP_FILE_VERSION := 2 +ADBE_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/apple/swifterpmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe \ + drivers/apple/displaypipe + +include $(APPDIR)/products.mk + +# You can override the default memory configuration here but you probably shouldn't. + diff --git a/apps/iBoot/config/e86-config.mk b/apps/iBoot/config/e86-config.mk new file mode 100644 index 0000000..749fd69 --- /dev/null +++ b/apps/iBoot/config/e86-config.mk @@ -0,0 +1,87 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# FIJIREF iboot bootloader build config +TARGET := e86 + +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 +LPDP_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/nxp/cbtl1610 + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/analogix/displayport \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/displaypipe \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/lpdp_phy \ + drivers/displayport + +# Override default ASP size. +ASP_SIZE := 10*1024*1024 + +# override default platform display region size config +DISPLAY_SIZE := 34*1024*1024 +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/e88-config.mk b/apps/iBoot/config/e88-config.mk new file mode 100644 index 0000000..756ef8b --- /dev/null +++ b/apps/iBoot/config/e88-config.mk @@ -0,0 +1,82 @@ +# Copyright (C) 2010-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# e88 iboot bootloader build config +TARGET := e88 +PLATFORM := s5l8940x +SUB_PLATFORM := s5l8942x +ARCH := arm +NO_AMP_CALIBRATION := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amg \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/ti/ths7383 + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/elbaref-config.mk b/apps/iBoot/config/elbaref-config.mk new file mode 100644 index 0000000..d9a8ec2 --- /dev/null +++ b/apps/iBoot/config/elbaref-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# ElbaRef iBoot bootloader build config + +TARGET := elbaref + +include $(GET_LOCAL_DIR)/s8001ref-config-base.mk + +include $(APPDIR)/products.mk \ No newline at end of file diff --git a/apps/iBoot/config/elbauiref-config.mk b/apps/iBoot/config/elbauiref-config.mk new file mode 100644 index 0000000..0710f8d --- /dev/null +++ b/apps/iBoot/config/elbauiref-config.mk @@ -0,0 +1,36 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# ElbaUIRef iBoot bootloader build config + +TARGET := elbaref +ADBE_VERSION := 2 +LPDP_VERSION := 2 + +include $(GET_LOCAL_DIR)/s8001ref-config-base.mk + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb_v2 \ + drivers/apple/displaypipe \ + drivers/displayport \ + drivers/apple/lpdp_phy \ + drivers/analogix/displayport \ + drivers/display/edp \ + drivers/backlight/lp8559 + +# override default platform display region size config +DISPLAY_SIZE := 108*1024*1024 + +OPTIONS += \ + ELBAUIREF=1 + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/fijiref-config.mk b/apps/iBoot/config/fijiref-config.mk new file mode 100644 index 0000000..0f2b2d1 --- /dev/null +++ b/apps/iBoot/config/fijiref-config.mk @@ -0,0 +1,72 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# FIJIREF iboot bootloader build config +TARGET := fijiref + +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie + +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/iaccy1-config-base.mk b/apps/iBoot/config/iaccy1-config-base.mk new file mode 100644 index 0000000..bbd407f --- /dev/null +++ b/apps/iBoot/config/iaccy1-config-base.mk @@ -0,0 +1,70 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iaccy1 iboot bootloader build config +PLATFORM := s5l8747x +ARCH := arm + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/clocks \ + drivers/primecell/pl192vic \ + drivers/samsung/aes \ + drivers/samsung/drex \ + drivers/samsung/gpio \ + drivers/samsung/pke \ + drivers/samsung/sha1 \ + drivers/samsung/timer \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg + +# We don't have flash, so there's no syscfg +MODULES_ELIDE += \ + $(MODULES_SYSCFG) \ + lib/paint + +# The full console menu is too big, so use the simple +# menu everywhere (and not just on release builds). +# Ditto for printfs +OPTIONS += \ + WITH_SIMPLE_MENU=1 \ + OBFUSCATED_LOGGING=1 + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8747X platform module) +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8747X platform module) +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8747X platform module) +TEXT_FOOTPRINT := 128*1024 + +RECOVERY_MODE_IBSS := true +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8747X platform module) +TEXT_FOOTPRINT := 128*1024 +endif + +ifeq ($(BUILD),DEBUG) +ABORT := true +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/ipad2-config-base.mk b/apps/iBoot/config/ipad2-config-base.mk new file mode 100644 index 0000000..e72a4ce --- /dev/null +++ b/apps/iBoot/config/ipad2-config-base.mk @@ -0,0 +1,83 @@ +# Copyright (C) 2010-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# K93 iboot bootloader build config +PLATFORM := s5l8940x +ARCH := arm +NO_AMP_CALIBRATION := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amg \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/rosc \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/display/pinot \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn \ + drivers/flash_nand/raw + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/ipad2b-config-base.mk b/apps/iBoot/config/ipad2b-config-base.mk new file mode 100644 index 0000000..fae6069 --- /dev/null +++ b/apps/iBoot/config/ipad2b-config-base.mk @@ -0,0 +1,84 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# p105/6/7 iboot bootloader builder config + +PLATFORM := s5l8940x +SUB_PLATFORM := s5l8942x +ARCH := arm +NO_AMP_CALIBRATION := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amg \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/ti/ths7383 \ + drivers/power/hdqgauge + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/display/pinot \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/ipad3-config-base.mk b/apps/iBoot/config/ipad3-config-base.mk new file mode 100644 index 0000000..1eb10a4 --- /dev/null +++ b/apps/iBoot/config/ipad3-config-base.mk @@ -0,0 +1,85 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s5l8945x based ipads iboot bootloader build config +PLATFORM := s5l8945x +ARCH := arm +NO_AMP_CALIBRATION := true +AMC_REG_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amg \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/apple/shmcon \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/rosc \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/display/edp \ + drivers/displayport \ + drivers/samsung/displayport \ + drivers/samsung/clcd_v2 + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss \ + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8945X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8945X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8945X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8945X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/ipad3b-config-base.mk b/apps/iBoot/config/ipad3b-config-base.mk new file mode 100644 index 0000000..08b46e9 --- /dev/null +++ b/apps/iBoot/config/ipad3b-config-base.mk @@ -0,0 +1,87 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s5l8955x based ipads iboot bootloader build config +PLATFORM := s5l8955x +ARCH := arm +NO_AMP_CALIBRATION := true +AMC_REG_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/apple/shmcon \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/dwi \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge \ + drivers/ti/ths7383 + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/apple/dither \ + drivers/display/edp \ + drivers/displayport \ + drivers/samsung/clcd_v2 \ + drivers/samsung/displayport + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8955X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8955X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8955X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8955X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/ipad4-config-base.mk b/apps/iBoot/config/ipad4-config-base.mk new file mode 100644 index 0000000..631cafd --- /dev/null +++ b/apps/iBoot/config/ipad4-config-base.mk @@ -0,0 +1,87 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPad4,x iboot bootloader build config +PLATFORM := s5l8960x +ARCH := arm64 +HW_TIMER := architected +BOOT_CONFIG := nand +AMC_REG_VERSION := 3 +AMP_FILE_VERSION := 2 +ADBE_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/samsung/dwi \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge \ + drivers/ti/ths7383 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/display/edp \ + drivers/displayport \ + drivers/samsung/displayport + +# override default platform display region size config +DISPLAY_SIZE := 64*1024*1024 + +include $(APPDIR)/products.mk + +# You can override the default memory configuration here but you probably shouldn't. + diff --git a/apps/iBoot/config/ipad4b-config-base.mk b/apps/iBoot/config/ipad4b-config-base.mk new file mode 100644 index 0000000..4af95e2 --- /dev/null +++ b/apps/iBoot/config/ipad4b-config-base.mk @@ -0,0 +1,88 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPad4,x iboot bootloader build config +PLATFORM := s5l8960x +ARCH := arm64 +HW_TIMER := architected +BOOT_CONFIG := nand +AMC_REG_VERSION := 3 +AMP_FILE_VERSION := 2 +ADBE_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/samsung/dwi \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/display/edp \ + drivers/displayport \ + drivers/samsung/displayport + +# override platform default memory map +ASP_SIZE := 10*1024*1024 +DISPLAY_SIZE := 64*1024*1024 +ifeq ($(TARGET_HAS_MESA),1) + TZ0_SIZE := 6*1024*1024 +endif + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/ipad5-config-base.mk b/apps/iBoot/config/ipad5-config-base.mk new file mode 100644 index 0000000..0183bfd --- /dev/null +++ b/apps/iBoot/config/ipad5-config-base.mk @@ -0,0 +1,100 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPhone7,x iBoot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 +LPDP_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/synopsys/usbotg \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/displayport \ + drivers/apple/lpdp_phy \ + drivers/analogix/displayport \ + drivers/display/edp \ + drivers/backlight/lp8559 + +# Override platform default memory map +ASP_SIZE := 10*1024*1024 +DISPLAY_SIZE := 64*1024*1024 +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + +# override default platform SDRAM config +SDRAM_LEN := 2*1024*1024*1024 + +# SDRAM TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 256MB +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0x870000000 +TEXT_FOOTPRINT := 1024*1024 +endif \ No newline at end of file diff --git a/apps/iBoot/config/ipad5b-config-base.mk b/apps/iBoot/config/ipad5b-config-base.mk new file mode 100644 index 0000000..e35dc46 --- /dev/null +++ b/apps/iBoot/config/ipad5b-config-base.mk @@ -0,0 +1,91 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPad5,x iBoot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7001 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 5 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 +LPDP_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/synopsys/usbotg \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/displayport \ + drivers/apple/lpdp_phy \ + drivers/analogix/displayport \ + drivers/display/edp + +# Override platform default memory map +ASP_SIZE := 10*1024*1024 +DISPLAY_SIZE := 64*1024*1024 +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/ipad5c-config-base.mk b/apps/iBoot/config/ipad5c-config-base.mk new file mode 100644 index 0000000..39a5c19 --- /dev/null +++ b/apps/iBoot/config/ipad5c-config-base.mk @@ -0,0 +1,96 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPad5,[5,6] iBoot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7001 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 5 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 +LPDP_VERSION := 1 + +OPTIONS += \ + DISPLAY_X136_TUNABLES=1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/charger \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/synopsys/usbotg \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/displayport \ + drivers/apple/lpdp_phy \ + drivers/analogix/displayport \ + drivers/display/edp \ + drivers/backlight/lp8559 + +# Override platform default memory map +ASP_SIZE := 14*1024*1024 +DISPLAY_SIZE := 108*1024*1024 +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/ipad6b-config-base.mk b/apps/iBoot/config/ipad6b-config-base.mk new file mode 100644 index 0000000..691669f --- /dev/null +++ b/apps/iBoot/config/ipad6b-config-base.mk @@ -0,0 +1,108 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPad6,[3,4] iBoot bootloader build config + +# Switch to s8001 once support for Elba is in +# +PLATFORM := s8000 +SUB_PLATFORM ?= s8001 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +ADBE_VERSION := 2 +LPDP_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/dialog/charger \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge \ + drivers/apple/voltage_knobs + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb_v2 \ + drivers/apple/wpc \ + drivers/apple/prc \ + drivers/apple/displaypipe \ + drivers/apple/reconfig \ + drivers/displayport \ + drivers/apple/lpdp_phy \ + drivers/analogix/displayport \ + drivers/display/edp + +# Disabling dpb for rdar://problem/20014397 +# drivers/apple/dpb + +# Override default ASP size. +ASP_SIZE := 18*1024*1024 + +# override default platform display region size config +DISPLAY_SIZE := 64*1024*1024 + +include $(APPDIR)/products.mk + +# You can override the default SRAM/SDRAM configuration here but you +# probably shouldn't. + +# POR for J127 and J128 is 2GB only. Hence limiting it since the default +# for Elba is 4GB. +SDRAM_LEN := 2*1024*1024*1024 + +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0x870000000 +TEXT_FOOTPRINT := 1024*1024 +endif diff --git a/apps/iBoot/config/ipad6d-config-base.mk b/apps/iBoot/config/ipad6d-config-base.mk new file mode 100644 index 0000000..21d1f5e --- /dev/null +++ b/apps/iBoot/config/ipad6d-config-base.mk @@ -0,0 +1,93 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPad6,[7,8] iBoot bootloader build config +PLATFORM := s8000 +SUB_PLATFORM ?= s8001 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +ADBE_VERSION := 2 +LPDP_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/dialog/charger \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge \ + drivers/apple/voltage_knobs + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb_v2 \ + drivers/apple/prc \ + drivers/apple/displaypipe \ + drivers/apple/reconfig \ + drivers/displayport \ + drivers/apple/lpdp_phy \ + drivers/analogix/displayport \ + drivers/display/edp \ + drivers/backlight/lp8559 + +# Override default ASP size. +ASP_SIZE := 18*1024*1024 + +# override default platform display region size config +DISPLAY_SIZE := 108*1024*1024 + +include $(APPDIR)/products.mk + +# You can override the default SRAM/SDRAM configuration here but you +# probably shouldn't. diff --git a/apps/iBoot/config/iphone5-config-base.mk b/apps/iBoot/config/iphone5-config-base.mk new file mode 100644 index 0000000..c3ec589 --- /dev/null +++ b/apps/iBoot/config/iphone5-config-base.mk @@ -0,0 +1,84 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPhone5,x iBoot bootloader build config +PLATFORM := s5l8950x +ARCH := arm +NO_AMP_CALIBRATION := true +AMC_REG_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/apple/shmcon \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/dwi \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge \ + drivers/ti/ths7383 + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss \ + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/iphone5b-config-base.mk b/apps/iBoot/config/iphone5b-config-base.mk new file mode 100644 index 0000000..8492e31 --- /dev/null +++ b/apps/iBoot/config/iphone5b-config-base.mk @@ -0,0 +1,86 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# Lower cost s5l8950x based iPhone iboot bootloader build config +PLATFORM := s5l8950x +ARCH := arm +NO_AMP_CALIBRATION := true +AMC_REG_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/apple/shmcon \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/nxp/cbtl1610 \ + drivers/samsung/dwi \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge \ + drivers/ti/ths7383 + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/display_pmu/chestnut \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss \ + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/iphone6-config-base.mk b/apps/iBoot/config/iphone6-config-base.mk new file mode 100644 index 0000000..9694e44 --- /dev/null +++ b/apps/iBoot/config/iphone6-config-base.mk @@ -0,0 +1,87 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iphone6 iboot bootloader build config +PLATFORM := s5l8960x +SUB_PLATFORM := s5l8960x +ARCH := arm64 +HW_TIMER := architected +BOOT_CONFIG := nand +AMC_REG_VERSION := 3 +AMP_FILE_VERSION := 2 +ADBE_VERSION := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/apple/aes \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/samsung/dwi \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge \ + drivers/ti/ths7383 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/display_pmu/chestnut \ + drivers/samsung/mipi + +# Override platform default memory map +TZ0_SIZE := 6*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/iphone7-config-base.mk b/apps/iBoot/config/iphone7-config-base.mk new file mode 100644 index 0000000..1216a2e --- /dev/null +++ b/apps/iBoot/config/iphone7-config-base.mk @@ -0,0 +1,90 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPhone7,x iBoot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge \ + drivers/ti/sn2400 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/display_pmu/chestnut \ + drivers/synopsys/mipi + +# Override platform default memory map +ASP_SIZE := 10*1024*1024 +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/iphone8-config-base.mk b/apps/iBoot/config/iphone8-config-base.mk new file mode 100644 index 0000000..44a8e85 --- /dev/null +++ b/apps/iBoot/config/iphone8-config-base.mk @@ -0,0 +1,85 @@ +# Copyright (C) 2013-2014, 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPhone8,x iBoot bootloader build config +PLATFORM := s8000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +ADBE_VERSION := 2 +TARGET := iphone8 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/ti/sn2400 \ + drivers/apple/voltage_knobs \ + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/apple/reconfig \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/display_pmu/chestnut \ + drivers/synopsys/mipi + +# Override platform default memory map +ASP_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/iphone8b-config-base.mk b/apps/iBoot/config/iphone8b-config-base.mk new file mode 100644 index 0000000..1f3ec97 --- /dev/null +++ b/apps/iBoot/config/iphone8b-config-base.mk @@ -0,0 +1,88 @@ +# Copyright (C) 2013-2014, 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPhone8,x iBoot bootloader build config +PLATFORM := s8000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +ADBE_VERSION := 2 +TARGET := n69 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/ti/sn2400 \ + drivers/apple/voltage_knobs \ + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/apple/reconfig \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/display_pmu/chestnut \ + drivers/synopsys/mipi + +include $(APPDIR)/products.mk + +OPTIONS += \ + TARGET_DISPLAY_D403=1 \ + TARGET_VID0_SRC_SEL=0xb \ + DISPLAY_D403_TUNABLES=1 \ + WITH_HW_MIPI=1 \ + WITH_HW_AGC_MIPI=0 diff --git a/apps/iBoot/config/ipod6-config-base.mk b/apps/iBoot/config/ipod6-config-base.mk new file mode 100644 index 0000000..9561c35 --- /dev/null +++ b/apps/iBoot/config/ipod6-config-base.mk @@ -0,0 +1,106 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# ipod6 iboot bootloader build config +PLATFORM := s7002 +SUB_PLATFORM := s7002 +TARGET := ipod6 +ARCH := arm +HW_TIMER := pmgr +BOOT_CONFIG := nand +AMC_REG_VERSION := 2 +AMP_FILE_VERSION := 2 +#DOCKFIFOS := uart bulk +DOCKFIFOS := uart +ADBE_VERSION := 3 +IBOOT_ANC_NVRAM := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/reconfig \ + lib/env \ + lib/blockdev \ + lib/nvram \ + drivers/apple/a7iop \ + drivers/apple/aes_s7002 \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/dockfifo \ + drivers/apple/gpio \ + drivers/nxp/cbtl1610 \ + drivers/primecell/pl080dmac \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifneq ($(CONFIG_FPGA),true) +ifneq ($(CONFIG_SIM),true) +MODULES_BASIC += \ + drivers/power/hdqgauge \ + drivers/idt/idtp9022 \ + drivers/dialog/pmu \ + drivers/apple/voltage_knobs +endif +endif + +ifneq ($(CONFIG_SIM), true) +MODULES_BASIC += \ + drivers/apple/iic +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +ifneq ($(CONFIG_FPGA),true) +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/displaypipe \ + +ifneq ($(CONFIG_SIM),true) +MODULES_BOOT += \ + drivers/display_pmu/beryllium \ + drivers/display/summit \ + drivers/samsung/mipi +endif +endif + +include $(APPDIR)/products.mk + +# You can override the default SRAM/SDRAM configuration here but probably shouldn't. + diff --git a/apps/iBoot/config/j1-config.mk b/apps/iBoot/config/j1-config.mk new file mode 100644 index 0000000..f7aceeb --- /dev/null +++ b/apps/iBoot/config/j1-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J1 iboot bootloader build config +TARGET := ipad3 + +include $(GET_LOCAL_DIR)/ipad3-config-base.mk diff --git a/apps/iBoot/config/j105-config.mk b/apps/iBoot/config/j105-config.mk new file mode 100644 index 0000000..99ed564 --- /dev/null +++ b/apps/iBoot/config/j105-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# j105 iboot bootloader build config +TARGET := j105 + +include $(GET_LOCAL_DIR)/appletv6-config-base.mk diff --git a/apps/iBoot/config/j127-config.mk b/apps/iBoot/config/j127-config.mk new file mode 100644 index 0000000..c287634 --- /dev/null +++ b/apps/iBoot/config/j127-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J127 iboot bootloader build config +TARGET := ipad6b +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad6b-config-base.mk diff --git a/apps/iBoot/config/j128-config.mk b/apps/iBoot/config/j128-config.mk new file mode 100644 index 0000000..0540b7c --- /dev/null +++ b/apps/iBoot/config/j128-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J128 iboot bootloader build config +TARGET := ipad6b +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad6b-config-base.mk diff --git a/apps/iBoot/config/j2-config.mk b/apps/iBoot/config/j2-config.mk new file mode 100644 index 0000000..c0dfa63 --- /dev/null +++ b/apps/iBoot/config/j2-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J2 iboot bootloader build config +TARGET := ipad3 + +include $(GET_LOCAL_DIR)/ipad3-config-base.mk diff --git a/apps/iBoot/config/j2a-config.mk b/apps/iBoot/config/j2a-config.mk new file mode 100644 index 0000000..fc07379 --- /dev/null +++ b/apps/iBoot/config/j2a-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J2A iboot bootloader build config +TARGET := ipad3 + +include $(GET_LOCAL_DIR)/ipad3-config-base.mk diff --git a/apps/iBoot/config/j33-config.mk b/apps/iBoot/config/j33-config.mk new file mode 100644 index 0000000..723e729 --- /dev/null +++ b/apps/iBoot/config/j33-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2008-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +SUB_PLATFORM := s5l8942x + +include $(GET_LOCAL_DIR)/appletv3-config-base.mk diff --git a/apps/iBoot/config/j33i-config.mk b/apps/iBoot/config/j33i-config.mk new file mode 100644 index 0000000..932de6f --- /dev/null +++ b/apps/iBoot/config/j33i-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2008-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +SUB_PLATFORM := s5l8947x + +include $(GET_LOCAL_DIR)/appletv3-config-base.mk diff --git a/apps/iBoot/config/j34-config.mk b/apps/iBoot/config/j34-config.mk new file mode 100644 index 0000000..9181287 --- /dev/null +++ b/apps/iBoot/config/j34-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# j34 iboot bootloader build config +TARGET := j34 + +include $(GET_LOCAL_DIR)/appletv4-config-base.mk diff --git a/apps/iBoot/config/j34m-config.mk b/apps/iBoot/config/j34m-config.mk new file mode 100644 index 0000000..119398c --- /dev/null +++ b/apps/iBoot/config/j34m-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# j34m iboot bootloader build config +TARGET := j34m + +include $(GET_LOCAL_DIR)/appletv4-config-base.mk diff --git a/apps/iBoot/config/j42-config.mk b/apps/iBoot/config/j42-config.mk new file mode 100644 index 0000000..e202f16 --- /dev/null +++ b/apps/iBoot/config/j42-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# j42 iboot bootloader build config +TARGET := j42 + +include $(GET_LOCAL_DIR)/appletv5-config-base.mk diff --git a/apps/iBoot/config/j42d-config.mk b/apps/iBoot/config/j42d-config.mk new file mode 100644 index 0000000..b770b6e --- /dev/null +++ b/apps/iBoot/config/j42d-config.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# j42d iboot bootloader build config +TARGET := j42 + +include $(GET_LOCAL_DIR)/appletv5-config-base.mk + +# override default platform SDRAM config +SDRAM_LEN := 2*1024*1024*1024 + +# SDRAM TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 256MB +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0x870000000 +TEXT_FOOTPRINT := 1024*1024 +endif diff --git a/apps/iBoot/config/j42m-config.mk b/apps/iBoot/config/j42m-config.mk new file mode 100644 index 0000000..34db9de --- /dev/null +++ b/apps/iBoot/config/j42m-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# j42m iboot bootloader build config +TARGET := j42 + +include $(GET_LOCAL_DIR)/appletv5-config-base.mk diff --git a/apps/iBoot/config/j71-config.mk b/apps/iBoot/config/j71-config.mk new file mode 100644 index 0000000..4b0f24f --- /dev/null +++ b/apps/iBoot/config/j71-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J71 iboot bootloader build config +TARGET := ipad4 +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad4-config-base.mk diff --git a/apps/iBoot/config/j72-config.mk b/apps/iBoot/config/j72-config.mk new file mode 100644 index 0000000..8128f52 --- /dev/null +++ b/apps/iBoot/config/j72-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J72 iboot bootloader build config +TARGET := ipad4 +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad4-config-base.mk diff --git a/apps/iBoot/config/j73-config.mk b/apps/iBoot/config/j73-config.mk new file mode 100644 index 0000000..e4b12c0 --- /dev/null +++ b/apps/iBoot/config/j73-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J73 iboot bootloader build config +TARGET := ipad4 +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad4-config-base.mk diff --git a/apps/iBoot/config/j81-config.mk b/apps/iBoot/config/j81-config.mk new file mode 100644 index 0000000..050b234 --- /dev/null +++ b/apps/iBoot/config/j81-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J81 iboot bootloader build config +TARGET := ipad5b +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad5b-config-base.mk diff --git a/apps/iBoot/config/j82-config.mk b/apps/iBoot/config/j82-config.mk new file mode 100644 index 0000000..0ebab1a --- /dev/null +++ b/apps/iBoot/config/j82-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J82 iboot bootloader build config +TARGET := ipad5b +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad5b-config-base.mk diff --git a/apps/iBoot/config/j85-config.mk b/apps/iBoot/config/j85-config.mk new file mode 100644 index 0000000..ab44060 --- /dev/null +++ b/apps/iBoot/config/j85-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J85 iboot bootloader build config +TARGET := ipad4b +TARGET_HAS_BASEBAND := 0 + +PINCONFIG_OBJ := pinconfig-nomesa.o + +include $(GET_LOCAL_DIR)/ipad4b-config-base.mk diff --git a/apps/iBoot/config/j85m-config.mk b/apps/iBoot/config/j85m-config.mk new file mode 100644 index 0000000..d82a456 --- /dev/null +++ b/apps/iBoot/config/j85m-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J85M iboot bootloader build config +TARGET := ipad4b +TARGET_HAS_BASEBAND := 0 +TARGET_HAS_MESA := 1 + +PINCONFIG_OBJ := pinconfig-mesa.o + +include $(GET_LOCAL_DIR)/ipad4b-config-base.mk diff --git a/apps/iBoot/config/j86-config.mk b/apps/iBoot/config/j86-config.mk new file mode 100644 index 0000000..2721b99 --- /dev/null +++ b/apps/iBoot/config/j86-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J86 iboot bootloader build config +TARGET := ipad4b +TARGET_HAS_BASEBAND := 1 + +PINCONFIG_OBJ := pinconfig-nomesa.o + +include $(GET_LOCAL_DIR)/ipad4b-config-base.mk diff --git a/apps/iBoot/config/j86m-config.mk b/apps/iBoot/config/j86m-config.mk new file mode 100644 index 0000000..b363cff --- /dev/null +++ b/apps/iBoot/config/j86m-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J86 iboot bootloader build config +TARGET := ipad4b +TARGET_HAS_BASEBAND := 1 +TARGET_HAS_MESA := 1 + +PINCONFIG_OBJ := pinconfig-mesa.o + +include $(GET_LOCAL_DIR)/ipad4b-config-base.mk diff --git a/apps/iBoot/config/j87-config.mk b/apps/iBoot/config/j87-config.mk new file mode 100644 index 0000000..e681d45 --- /dev/null +++ b/apps/iBoot/config/j87-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012 -2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J87 iboot bootloader build config +TARGET := ipad4b +TARGET_HAS_BASEBAND := 1 + +PINCONFIG_OBJ := pinconfig-nomesa.o + +include $(GET_LOCAL_DIR)/ipad4b-config-base.mk diff --git a/apps/iBoot/config/j87m-config.mk b/apps/iBoot/config/j87m-config.mk new file mode 100644 index 0000000..ea112f2 --- /dev/null +++ b/apps/iBoot/config/j87m-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J87M iboot bootloader build config +TARGET := ipad4b +TARGET_HAS_BASEBAND := 1 +TARGET_HAS_MESA := 1 + +PINCONFIG_OBJ := pinconfig-mesa.o + +include $(GET_LOCAL_DIR)/ipad4b-config-base.mk diff --git a/apps/iBoot/config/j96-config.mk b/apps/iBoot/config/j96-config.mk new file mode 100644 index 0000000..179736a --- /dev/null +++ b/apps/iBoot/config/j96-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J96 iboot bootloader build config +TARGET := ipad5 +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad5-config-base.mk diff --git a/apps/iBoot/config/j97-config.mk b/apps/iBoot/config/j97-config.mk new file mode 100644 index 0000000..d0f2523 --- /dev/null +++ b/apps/iBoot/config/j97-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J97 iboot bootloader build config +TARGET := ipad5 +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad5-config-base.mk diff --git a/apps/iBoot/config/j98-config.mk b/apps/iBoot/config/j98-config.mk new file mode 100644 index 0000000..ea5e558 --- /dev/null +++ b/apps/iBoot/config/j98-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J98 iboot bootloader build config +TARGET := ipad5c +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad5c-config-base.mk diff --git a/apps/iBoot/config/j98a-config.mk b/apps/iBoot/config/j98a-config.mk new file mode 100644 index 0000000..0b684bc --- /dev/null +++ b/apps/iBoot/config/j98a-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J98a iboot bootloader build config +TARGET := ipad6d +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad6d-config-base.mk diff --git a/apps/iBoot/config/j99-config.mk b/apps/iBoot/config/j99-config.mk new file mode 100644 index 0000000..efd408d --- /dev/null +++ b/apps/iBoot/config/j99-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J99 iboot bootloader build config +TARGET := ipad5c +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad5c-config-base.mk diff --git a/apps/iBoot/config/j99a-config.mk b/apps/iBoot/config/j99a-config.mk new file mode 100644 index 0000000..1abb2d0 --- /dev/null +++ b/apps/iBoot/config/j99a-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# J99a iboot bootloader build config +TARGET := ipad6d +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad6d-config-base.mk diff --git a/apps/iBoot/config/k93-config.mk b/apps/iBoot/config/k93-config.mk new file mode 100644 index 0000000..29d5375 --- /dev/null +++ b/apps/iBoot/config/k93-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2010-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# K93 iboot bootloader build config +TARGET := ipad2 + +include $(GET_LOCAL_DIR)/ipad2-config-base.mk diff --git a/apps/iBoot/config/k93a-config.mk b/apps/iBoot/config/k93a-config.mk new file mode 100644 index 0000000..6966ebe --- /dev/null +++ b/apps/iBoot/config/k93a-config.mk @@ -0,0 +1,83 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# K93a iboot bootloader build config +TARGET := k93a +PLATFORM := s5l8940x +SUB_PLATFORM := s5l8942x +ARCH := arm +NO_AMP_CALIBRATION := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amg \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/display/pinot \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/k94-config.mk b/apps/iBoot/config/k94-config.mk new file mode 100644 index 0000000..5f5b122 --- /dev/null +++ b/apps/iBoot/config/k94-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2010-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# K94 iboot bootloader build config +TARGET := ipad2 + +include $(GET_LOCAL_DIR)/ipad2-config-base.mk diff --git a/apps/iBoot/config/k95-config.mk b/apps/iBoot/config/k95-config.mk new file mode 100644 index 0000000..49fa8f9 --- /dev/null +++ b/apps/iBoot/config/k95-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2010-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# K95 iboot bootloader build config +TARGET := ipad2 + +include $(GET_LOCAL_DIR)/ipad2-config-base.mk diff --git a/apps/iBoot/config/m7ref-config.mk b/apps/iBoot/config/m7ref-config.mk new file mode 100644 index 0000000..1f8c090 --- /dev/null +++ b/apps/iBoot/config/m7ref-config.mk @@ -0,0 +1,65 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# M7REF iboot bootloader build config + +PLATFORM := s7002 +SUB_PLATFORM := s7002 +TARGET := m7ref +ARCH := arm +HW_TIMER := pmgr +BOOT_CONFIG := nand +AMC_REG_VERSION := 2 +AMP_FILE_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/reconfig \ + drivers/apple/a7iop \ + drivers/apple/aes_s7002 \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/ausb \ + drivers/apple/dockfifo \ + drivers/apple/gpio \ + drivers/primecell/pl080dmac \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/apple/iic \ + drivers/dialog/pmu \ + drivers/apple/voltage_knobs + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/maltaref-config.mk b/apps/iBoot/config/maltaref-config.mk new file mode 100644 index 0000000..b736c41 --- /dev/null +++ b/apps/iBoot/config/maltaref-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# MaltaRef iBoot bootloader build config +SUB_PLATFORM := s8003 + +include $(GET_LOCAL_DIR)/s8000ref-config-base.mk + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/maltauiref-config.mk b/apps/iBoot/config/maltauiref-config.mk new file mode 100644 index 0000000..edbe0bc --- /dev/null +++ b/apps/iBoot/config/maltauiref-config.mk @@ -0,0 +1,38 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# MaltaUIRef iBoot bootloader build config +SUB_PLATFORM := s8003 + +include $(GET_LOCAL_DIR)/s8000ref-config-base.mk + +ADBE_VERSION := 2 + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/display_pmu/chestnut \ + drivers/display/pinot \ + drivers/synopsys/mipi \ + drivers/backlight/lm3534 + +OPTIONS += \ + DISPLAY_D620_TUNABLES=1 \ + TARGET_VID0_SRC_SEL=0x9 \ + TARGET_DISPLAY_D620=1 \ + WITH_HW_MIPI=1 \ + WITH_HW_AGC_MIPI=0 + +include $(APPDIR)/products.mk + +# override default platform display region size config +DISPLAY_SIZE := 34*1024*1024 diff --git a/apps/iBoot/config/mauiref-config.mk b/apps/iBoot/config/mauiref-config.mk new file mode 100644 index 0000000..10c5f35 --- /dev/null +++ b/apps/iBoot/config/mauiref-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# MauiRef iBoot bootloader build config + +SUB_PLATFORM := s8000 + +include $(GET_LOCAL_DIR)/s8000ref-config-base.mk + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/mauiuiref-config.mk b/apps/iBoot/config/mauiuiref-config.mk new file mode 100644 index 0000000..3e0f9d6 --- /dev/null +++ b/apps/iBoot/config/mauiuiref-config.mk @@ -0,0 +1,38 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# MauiUIRef iBoot bootloader build config +SUB_PLATFORM := s8000 + +include $(GET_LOCAL_DIR)/s8000ref-config-base.mk + +ADBE_VERSION := 2 + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/display_pmu/chestnut \ + drivers/display/pinot \ + drivers/synopsys/mipi \ + drivers/backlight/lm3534 + +OPTIONS += \ + DISPLAY_D620_TUNABLES=1 \ + TARGET_VID0_SRC_SEL=0x9 \ + TARGET_DISPLAY_D620=1 \ + WITH_HW_MIPI=1 \ + WITH_HW_AGC_MIPI=0 + +include $(APPDIR)/products.mk + +# override default platform display region size config +DISPLAY_SIZE := 34*1024*1024 diff --git a/apps/iBoot/config/n102-config.mk b/apps/iBoot/config/n102-config.mk new file mode 100644 index 0000000..d6b805b --- /dev/null +++ b/apps/iBoot/config/n102-config.mk @@ -0,0 +1,92 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPod7,1 iBoot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/nxp/cbtl1610 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/display_pmu/chestnut \ + drivers/synopsys/mipi + +OPTIONS += \ + DISPLAY_D410_TUNABLES=1 + +# Override default platform memory map +ASP_SIZE := 10*1024*1024 +DISPLAY_SIZE := 34*1024*1024 +TZ0_SIZE := 8*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/n27-config.mk b/apps/iBoot/config/n27-config.mk new file mode 100644 index 0000000..2a26ca2 --- /dev/null +++ b/apps/iBoot/config/n27-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# n27 iboot bootloader build config + +CONFIG_SIM := false +RECOVERY_MODE_IBSS := false + +include $(GET_LOCAL_DIR)/ipod6-config-base.mk diff --git a/apps/iBoot/config/n27a-config.mk b/apps/iBoot/config/n27a-config.mk new file mode 100644 index 0000000..54128ee --- /dev/null +++ b/apps/iBoot/config/n27a-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# n27a iboot bootloader build config + +CONFIG_SIM := false +RECOVERY_MODE_IBSS := false + +include $(GET_LOCAL_DIR)/ipod6-config-base.mk diff --git a/apps/iBoot/config/n28-config.mk b/apps/iBoot/config/n28-config.mk new file mode 100644 index 0000000..93a73ad --- /dev/null +++ b/apps/iBoot/config/n28-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# n28 iboot bootloader build config + +CONFIG_SIM := false +RECOVERY_MODE_IBSS := false + +include $(GET_LOCAL_DIR)/ipod6-config-base.mk diff --git a/apps/iBoot/config/n28a-config.mk b/apps/iBoot/config/n28a-config.mk new file mode 100644 index 0000000..667e9bb --- /dev/null +++ b/apps/iBoot/config/n28a-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# n28a iboot bootloader build config + +CONFIG_SIM := false +RECOVERY_MODE_IBSS := false + +include $(GET_LOCAL_DIR)/ipod6-config-base.mk diff --git a/apps/iBoot/config/n41-config.mk b/apps/iBoot/config/n41-config.mk new file mode 100644 index 0000000..f6c4869 --- /dev/null +++ b/apps/iBoot/config/n41-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N41 iboot bootloader build config +TARGET := iphone5 + +include $(GET_LOCAL_DIR)/iphone5-config-base.mk diff --git a/apps/iBoot/config/n42-config.mk b/apps/iBoot/config/n42-config.mk new file mode 100644 index 0000000..4ef5202 --- /dev/null +++ b/apps/iBoot/config/n42-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N42 iboot bootloader build config +TARGET := iphone5 + +include $(GET_LOCAL_DIR)/iphone5-config-base.mk diff --git a/apps/iBoot/config/n48-config.mk b/apps/iBoot/config/n48-config.mk new file mode 100644 index 0000000..4424f30 --- /dev/null +++ b/apps/iBoot/config/n48-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N48 iboot bootloader build config +TARGET := iphone5b + +include $(GET_LOCAL_DIR)/iphone5b-config-base.mk diff --git a/apps/iBoot/config/n49-config.mk b/apps/iBoot/config/n49-config.mk new file mode 100644 index 0000000..bc80d70 --- /dev/null +++ b/apps/iBoot/config/n49-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N49 iboot bootloader build config +TARGET := iphone5b + +include $(GET_LOCAL_DIR)/iphone5b-config-base.mk diff --git a/apps/iBoot/config/n51-config.mk b/apps/iBoot/config/n51-config.mk new file mode 100644 index 0000000..a96682e --- /dev/null +++ b/apps/iBoot/config/n51-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N51 iboot bootloader build config +TARGET := iphone6 + +include $(GET_LOCAL_DIR)/iphone6-config-base.mk diff --git a/apps/iBoot/config/n53-config.mk b/apps/iBoot/config/n53-config.mk new file mode 100644 index 0000000..fa330d3 --- /dev/null +++ b/apps/iBoot/config/n53-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N53 iboot bootloader build config +TARGET := iphone6 + +include $(GET_LOCAL_DIR)/iphone6-config-base.mk diff --git a/apps/iBoot/config/n56-config.mk b/apps/iBoot/config/n56-config.mk new file mode 100644 index 0000000..a81232e --- /dev/null +++ b/apps/iBoot/config/n56-config.mk @@ -0,0 +1,24 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N56 iboot bootloader build config +TARGET := iphone7 + +ifeq ($(PRODUCT),iBEC) +MODULES_BASIC += drivers/apple/oscar +endif + +include $(GET_LOCAL_DIR)/iphone7-config-base.mk + +# override default platform display region size config +DISPLAY_SIZE := 34*1024*1024 + +OPTIONS += \ + DISPLAY_D600_TUNABLES=1 + diff --git a/apps/iBoot/config/n59-config.mk b/apps/iBoot/config/n59-config.mk new file mode 100644 index 0000000..9eedf9b --- /dev/null +++ b/apps/iBoot/config/n59-config.mk @@ -0,0 +1,98 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N59 iboot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 + +TARGET := n59 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/voltage_knobs \ + drivers/samsung/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/nxp/cbtl1610 \ + drivers/power/hdqgauge \ + drivers/ti/sn2400 + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/dither \ + drivers/apple/dpb \ + drivers/apple/displaypipe \ + drivers/backlight/lm3534 \ + drivers/display/pinot \ + drivers/display_pmu/chestnut \ + drivers/synopsys/mipi + +# Override platform default memory map +ASP_SIZE := 10*1024*1024 +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + +ifeq ($(PRODUCT),iBEC) +MODULES_BASIC += drivers/apple/oscar +endif + +OPTIONS += \ + DISPLAY_D410_TUNABLES=1 diff --git a/apps/iBoot/config/n61-config.mk b/apps/iBoot/config/n61-config.mk new file mode 100644 index 0000000..3b1ea57 --- /dev/null +++ b/apps/iBoot/config/n61-config.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N61 iboot bootloader build config +TARGET := iphone7 + +include $(GET_LOCAL_DIR)/iphone7-config-base.mk + +# override default platform display region size config +DISPLAY_SIZE := 17*1024*1024 + +OPTIONS += \ + DISPLAY_D500_TUNABLES=1 + + diff --git a/apps/iBoot/config/n66-config-base.mk b/apps/iBoot/config/n66-config-base.mk new file mode 100644 index 0000000..22a63ce --- /dev/null +++ b/apps/iBoot/config/n66-config-base.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +include $(GET_LOCAL_DIR)/iphone8-config-base.mk + +OPTIONS += \ + TARGET_DISPLAY_D620=1 \ + TARGET_VID0_SRC_SEL=0x9 \ + DISPLAY_D620_TUNABLES=1 \ + WITH_HW_MIPI=1 \ + WITH_HW_AGC_MIPI=0 + +# override default platform display region size config +DISPLAY_SIZE := 34*1024*1024 diff --git a/apps/iBoot/config/n66-config.mk b/apps/iBoot/config/n66-config.mk new file mode 100644 index 0000000..eb27e7b --- /dev/null +++ b/apps/iBoot/config/n66-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +SUB_PLATFORM := s8000 + +include $(GET_LOCAL_DIR)/n66-config-base.mk + +OPTIONS += \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=8 \ + TARGET_ICP_CTR=15 diff --git a/apps/iBoot/config/n66m-config.mk b/apps/iBoot/config/n66m-config.mk new file mode 100644 index 0000000..90b8e77 --- /dev/null +++ b/apps/iBoot/config/n66m-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +SUB_PLATFORM := s8003 + +include $(GET_LOCAL_DIR)/n66-config-base.mk + +OPTIONS += \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=4 \ + TARGET_ICP_CTR=5 \ No newline at end of file diff --git a/apps/iBoot/config/n69-config.mk b/apps/iBoot/config/n69-config.mk new file mode 100644 index 0000000..feb322b --- /dev/null +++ b/apps/iBoot/config/n69-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2013-2014, 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPhone8,x iBoot bootloader build config +SUB_PLATFORM := s8003 + +include $(GET_LOCAL_DIR)/iphone8b-config-base.mk \ No newline at end of file diff --git a/apps/iBoot/config/n69u-config.mk b/apps/iBoot/config/n69u-config.mk new file mode 100644 index 0000000..4ba4071 --- /dev/null +++ b/apps/iBoot/config/n69u-config.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2013-2014, 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# iPhone8,x iBoot bootloader build config +SUB_PLATFORM := s8000 + +include $(GET_LOCAL_DIR)/iphone8b-config-base.mk \ No newline at end of file diff --git a/apps/iBoot/config/n71-config-base.mk b/apps/iBoot/config/n71-config-base.mk new file mode 100644 index 0000000..71e1512 --- /dev/null +++ b/apps/iBoot/config/n71-config-base.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +include $(GET_LOCAL_DIR)/iphone8-config-base.mk + +OPTIONS += \ + TARGET_DISPLAY_D520=1 \ + TARGET_VID0_SRC_SEL=0xA \ + DISPLAY_D520_TUNABLES=1 \ + WITH_HW_MIPI=1 \ + WITH_HW_AGC_MIPI=0 diff --git a/apps/iBoot/config/n71-config.mk b/apps/iBoot/config/n71-config.mk new file mode 100644 index 0000000..bfb6f74 --- /dev/null +++ b/apps/iBoot/config/n71-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +SUB_PLATFORM := s8000 + +include $(GET_LOCAL_DIR)/n71-config-base.mk + +OPTIONS += \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=8 \ + TARGET_ICP_CTR=15 \ No newline at end of file diff --git a/apps/iBoot/config/n71m-config.mk b/apps/iBoot/config/n71m-config.mk new file mode 100644 index 0000000..8357a79 --- /dev/null +++ b/apps/iBoot/config/n71m-config.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +SUB_PLATFORM := s8003 + +include $(GET_LOCAL_DIR)/n71-config-base.mk + +OPTIONS += \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=4 \ + TARGET_ICP_CTR=5 \ No newline at end of file diff --git a/apps/iBoot/config/n78-config.mk b/apps/iBoot/config/n78-config.mk new file mode 100644 index 0000000..54b5de9 --- /dev/null +++ b/apps/iBoot/config/n78-config.mk @@ -0,0 +1,83 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# n78 iboot bootloader build config +TARGET := n78 +PLATFORM := s5l8940x +SUB_PLATFORM := s5l8942x +ARCH := arm +NO_AMP_CALIBRATION := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amg \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/ti/ths7383 + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/display/pinot \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/n94-config.mk b/apps/iBoot/config/n94-config.mk new file mode 100644 index 0000000..3c34964 --- /dev/null +++ b/apps/iBoot/config/n94-config.mk @@ -0,0 +1,106 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# N94 iboot bootloader build config +PLATFORM := s5l8940x +ARCH := arm +NO_AMP_CALIBRATION := true + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amg \ + drivers/apple/audio \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sha2 \ + drivers/dialog/pmu \ + drivers/iic \ + drivers/samsung/pke \ + drivers/samsung/uart \ + drivers/samsung/usbphy \ + drivers/synopsys/usbotg \ + drivers/power/hdqgauge + +MODULES_BOOT += \ + drivers/apple/adfe \ + drivers/apple/displaypipe \ + drivers/display/pinot \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +SUBMODULES_NAND += \ + drivers/apple/h2fmi \ + drivers/flash_nand/ppn-swiss \ + +include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8940X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 256*1024 +endif + +########### +# N94 Memory Map Explanation +############ + +# frame buffer size = hight (960) * stride (2560) = 0x258000 +# iBoot and OS memory map use same frame buffer start address = 0x9f8f4000 + +# iBoot: +# +# REGION START END SIZE NOTES +# Panic 0x9fffc000 0x9fffffff 0x00004000 +# iBoot 0x9ff00000 0x9fffbfff 0x0000c000 +# Display 0x9f000000 0x9fefffff 0x00f00000 used for frame buffer, compressed and uncompressed artwork +# [frame buffer 0x9f8f4000 0x9fb4bfff 0x00258000 frame buffer region = 1 x frame buffer size] +# [flat image 0x9f25a000 0x9f7fffff 0x005a6000 uncompressed image] +# [scratch 0x9f000000 0x9f258fff 0x00259000 compressed image; size = frame buffer size + 0x1000] +# Heap etc 0x80000000 0x9f0effff 0x1f0f0000 + +# OS: [Display region is resized; iBoot region is removed] +# +# REGION START END SIZE NOTES +# Panic 0x9fffc000 0x9fffffff 0x00004000 +# Display 0x9f8f4000 0x9fffbfff 0x00708000 display size = 3 x frame buffer size +# Kernel 0x80000000 0x9f8f3fff 0x1f8f4000 + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/p101-config.mk b/apps/iBoot/config/p101-config.mk new file mode 100644 index 0000000..1dc97d4 --- /dev/null +++ b/apps/iBoot/config/p101-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# P101 iboot bootloader build config +TARGET := ipad3b +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad3b-config-base.mk diff --git a/apps/iBoot/config/p102-config.mk b/apps/iBoot/config/p102-config.mk new file mode 100644 index 0000000..dbd55ec --- /dev/null +++ b/apps/iBoot/config/p102-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# P102 iboot bootloader build config +TARGET := ipad3b +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad3b-config-base.mk diff --git a/apps/iBoot/config/p103-config.mk b/apps/iBoot/config/p103-config.mk new file mode 100644 index 0000000..6a1cde4 --- /dev/null +++ b/apps/iBoot/config/p103-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# P103 iboot bootloader build config +TARGET := ipad3b +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad3b-config-base.mk diff --git a/apps/iBoot/config/p105-config.mk b/apps/iBoot/config/p105-config.mk new file mode 100644 index 0000000..28b3c81 --- /dev/null +++ b/apps/iBoot/config/p105-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# P105 iboot bootloader build config +TARGET := ipad2b +TARGET_HAS_BASEBAND := 0 + +include $(GET_LOCAL_DIR)/ipad2b-config-base.mk diff --git a/apps/iBoot/config/p106-config.mk b/apps/iBoot/config/p106-config.mk new file mode 100644 index 0000000..f8319f8 --- /dev/null +++ b/apps/iBoot/config/p106-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# P106 iboot bootloader build config +TARGET := ipad2b +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad2b-config-base.mk diff --git a/apps/iBoot/config/p107-config.mk b/apps/iBoot/config/p107-config.mk new file mode 100644 index 0000000..58d37c5 --- /dev/null +++ b/apps/iBoot/config/p107-config.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# P107 iboot bootloader build config +TARGET := ipad2b +TARGET_HAS_BASEBAND := 1 + +include $(GET_LOCAL_DIR)/ipad2b-config-base.mk diff --git a/apps/iBoot/config/s7002fpga-config.mk b/apps/iBoot/config/s7002fpga-config.mk new file mode 100644 index 0000000..48a19ba --- /dev/null +++ b/apps/iBoot/config/s7002fpga-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s7002fpga iboot bootloader build config + +CONFIG_FPGA := true +RECOVERY_MODE_IBSS := false +NO_WFI := false + +include $(GET_LOCAL_DIR)/ipod6-config-base.mk diff --git a/apps/iBoot/config/s7002sim-config.mk b/apps/iBoot/config/s7002sim-config.mk new file mode 100644 index 0000000..351a2e5 --- /dev/null +++ b/apps/iBoot/config/s7002sim-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s7002sim iboot bootloader build config + +CONFIG_SIM := true +RECOVERY_MODE_IBSS := false + +include $(GET_LOCAL_DIR)/ipod6-config-base.mk diff --git a/apps/iBoot/config/s8000fpga-config.mk b/apps/iBoot/config/s8000fpga-config.mk new file mode 100644 index 0000000..ffea0e8 --- /dev/null +++ b/apps/iBoot/config/s8000fpga-config.mk @@ -0,0 +1,68 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s8000fpga iboot bootloader build config +PLATFORM := s8000 +SUB_PLATFORM ?= s8000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) + +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/reconfig \ + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/s8000ref-config-base.mk b/apps/iBoot/config/s8000ref-config-base.mk new file mode 100644 index 0000000..4f3dba2 --- /dev/null +++ b/apps/iBoot/config/s8000ref-config-base.mk @@ -0,0 +1,65 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# Maui ref boards iBoot bootloader build config + +PLATFORM := s8000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +TARGET := mauiref + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/reconfig \ + drivers/apple/sep \ + drivers/dialog/pmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/apple/voltage_knobs \ + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto diff --git a/apps/iBoot/config/s8000sim-config.mk b/apps/iBoot/config/s8000sim-config.mk new file mode 100644 index 0000000..be2d032 --- /dev/null +++ b/apps/iBoot/config/s8000sim-config.mk @@ -0,0 +1,67 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# fastsim/s8000sim iboot bootloader build config + +PLATFORM := s8000 +SUB_PLATFORM ?= s8000 +ARCH := arm64 +HW_TIMER := architected +ADBE_VERSION := 2 + +OPTIONS += \ + DISPLAY_IPHONE_TUNABLES=1 \ + TARGET_DISPLAY_D520=1 \ + DISPLAY_D520_TUNABLES=1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/apple/swifterpmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/displaypipe \ + drivers/apple/reconfig + +include $(APPDIR)/products.mk + +# You can override the default SRAM/SDRAM configuration here but you probably shouldn't. + diff --git a/apps/iBoot/config/s8001fpga-config.mk b/apps/iBoot/config/s8001fpga-config.mk new file mode 100644 index 0000000..85f515f --- /dev/null +++ b/apps/iBoot/config/s8001fpga-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s8001fpga iboot bootloader build config + +TARGET := s8000fpga +SUB_PLATFORM := s8001 + +include $(GET_LOCAL_DIR)/s8000fpga-config.mk \ No newline at end of file diff --git a/apps/iBoot/config/s8001ref-config-base.mk b/apps/iBoot/config/s8001ref-config-base.mk new file mode 100644 index 0000000..f25070e --- /dev/null +++ b/apps/iBoot/config/s8001ref-config-base.mk @@ -0,0 +1,65 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s8001ref iBoot bootloader build config + +PLATFORM := s8000 +SUB_PLATFORM := s8001 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/reconfig \ + drivers/apple/sep \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + drivers/dialog/pmu \ + drivers/apple/voltage_knobs + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto diff --git a/apps/iBoot/config/s8001sim-config.mk b/apps/iBoot/config/s8001sim-config.mk new file mode 100644 index 0000000..161b358 --- /dev/null +++ b/apps/iBoot/config/s8001sim-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s8001sim iboot bootloader build config + +TARGET := s8000sim +SUB_PLATFORM := s8001 + +include $(GET_LOCAL_DIR)/s8000sim-config.mk \ No newline at end of file diff --git a/apps/iBoot/config/s8003fpga-config.mk b/apps/iBoot/config/s8003fpga-config.mk new file mode 100644 index 0000000..f80d268 --- /dev/null +++ b/apps/iBoot/config/s8003fpga-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s8003fpga iboot bootloader build config + +TARGET := s8000fpga +SUB_PLATFORM := s8003 + +include $(GET_LOCAL_DIR)/s8000fpga-config.mk diff --git a/apps/iBoot/config/s8003sim-config.mk b/apps/iBoot/config/s8003sim-config.mk new file mode 100644 index 0000000..397cf40 --- /dev/null +++ b/apps/iBoot/config/s8003sim-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# s8003sim iboot bootloader build config + +TARGET := s8000sim +SUB_PLATFORM := s8003 + +include $(GET_LOCAL_DIR)/s8000sim-config.mk diff --git a/apps/iBoot/config/swifter-config.mk b/apps/iBoot/config/swifter-config.mk new file mode 100644 index 0000000..4e979c6 --- /dev/null +++ b/apps/iBoot/config/swifter-config.mk @@ -0,0 +1,74 @@ +# Copyright (C) 2010-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# swifter/fastsim iboot bootloader build config +PLATFORM := s5l8950x +ARCH := arm +NO_AMP_CALIBRATION := true +AMC_REG_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp \ + drivers/apple/cdma \ + drivers/apple/gpio \ + drivers/apple/sha2 \ + drivers/apple/iic \ + drivers/apple/h2fmi/boot \ + drivers/hdc/boot \ + drivers/samsung/pke \ + drivers/samsung/spi \ + drivers/samsung/uart + +# Define NOR and NAND technology submodule lists for use only within +# the context of 'boot-from-nor-template.mk' and +# 'boot-from-nand-template.mk'. + +SUBMODULES_NOR += + +MODULES_FILESYSTEM += \ + drivers/hdc \ + drivers/apple/displaypipe \ + drivers/samsung/clcd_v2 \ + drivers/samsung/mipi + +# include $(APPDIR)/config/boot-from-nand-template.mk + +ifeq ($(PRODUCT),iBoot) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBEC) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sdram +TEXT_FOOTPRINT := 1008*1024 +endif + +ifeq ($(PRODUCT),iBSS) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +ifeq ($(PRODUCT),LLB) +# Memory configuration (consumed by the S5L8950X platform module) +TEXT_BANK := sram +TEXT_FOOTPRINT := 512*1024 +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/config/t7000fpga-config.mk b/apps/iBoot/config/t7000fpga-config.mk new file mode 100644 index 0000000..651519c --- /dev/null +++ b/apps/iBoot/config/t7000fpga-config.mk @@ -0,0 +1,73 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# t7000fpga iboot bootloader build config +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 +SUPPORT_FPGA := 1 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/samsung/dwi \ + drivers/apple/gpio \ + drivers/apple/iic \ + drivers/apple/sep \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/anc \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +# Override platform default memory map +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/t7001fpga-config.mk b/apps/iBoot/config/t7001fpga-config.mk new file mode 100644 index 0000000..5801969 --- /dev/null +++ b/apps/iBoot/config/t7001fpga-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# t7001fpga iboot bootloader build config + +TARGET := t7000fpga +SUB_PLATFORM := t7001 +AMC_REG_VERSION := 5 + +include $(GET_LOCAL_DIR)/t7000fpga-config.mk diff --git a/apps/iBoot/config/t7001padsim-config.mk b/apps/iBoot/config/t7001padsim-config.mk new file mode 100644 index 0000000..d8048b3 --- /dev/null +++ b/apps/iBoot/config/t7001padsim-config.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# fastsim-capri-ipad iboot bootloader build config + +SUB_PLATFORM := t7001 +AMC_REG_VERSION := 5 + +include $(GET_LOCAL_DIR)/typhonic-config.mk + +# override default platform display region size config +DISPLAY_SIZE := 64*1024*1024 + diff --git a/apps/iBoot/config/t8002fpga-config.mk b/apps/iBoot/config/t8002fpga-config.mk new file mode 100644 index 0000000..b9574f4 --- /dev/null +++ b/apps/iBoot/config/t8002fpga-config.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# t8002fpga iboot bootloader build config + +CONFIG_FPGA := true +RECOVERY_MODE_IBSS := false +NO_WFI := false + +include $(GET_LOCAL_DIR)/watch2-config-base.mk diff --git a/apps/iBoot/config/t8002sim-config.mk b/apps/iBoot/config/t8002sim-config.mk new file mode 100644 index 0000000..44314c7 --- /dev/null +++ b/apps/iBoot/config/t8002sim-config.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# t8002sim iboot bootloader build config + +CONFIG_SIM := true +RECOVERY_MODE_IBSS := false + +include $(GET_LOCAL_DIR)/watch2-config-base.mk diff --git a/apps/iBoot/config/t8010fpga-config.mk b/apps/iBoot/config/t8010fpga-config.mk new file mode 100644 index 0000000..427c31b --- /dev/null +++ b/apps/iBoot/config/t8010fpga-config.mk @@ -0,0 +1,68 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# t8010fpga iBoot bootloader build config +PLATFORM := t8010 +SUB_PLATFORM ?= t8010 +ARCH := arm64 +BOOT_CONFIG := nand +HW_TIMER := architected + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/dwi \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifeq ($(BOOT_CONFIG), nand) + +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/reconfig \ + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/t8010sim-config.mk b/apps/iBoot/config/t8010sim-config.mk new file mode 100644 index 0000000..f09bcd1 --- /dev/null +++ b/apps/iBoot/config/t8010sim-config.mk @@ -0,0 +1,56 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# fastsim/t8010sim iBoot bootloader build config + +PLATFORM := t8010 +SUB_PLATFORM ?= t8010 +ARCH := arm64 +HW_TIMER := architected + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/error_handler \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/dcs \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/apple/swifterpmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/reconfig \ + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/typhonic-config.mk b/apps/iBoot/config/typhonic-config.mk new file mode 100644 index 0000000..2440c19 --- /dev/null +++ b/apps/iBoot/config/typhonic-config.mk @@ -0,0 +1,71 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# fastsim/typhonic iboot bootloader build config + +TARGET := typhonic +PLATFORM := t7000 +SUB_PLATFORM ?= t7000 +ARCH := arm64 +HW_TIMER := architected +AMC_REG_VERSION ?= 4 +AMC_FILE_VERSION ?= 2 +ADBE_VERSION := 2 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/amc \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/miu \ + platform/$(PLATFORM)/pmgr \ + platform/$(PLATFORM)/error_handler \ + drivers/apple/a7iop \ + drivers/apple/aes \ + drivers/apple/aic \ + drivers/apple/amc \ + drivers/apple/amp_v3 \ + drivers/apple/ausb \ + drivers/apple/ccc \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/apple/swifterpmu \ + drivers/samsung/uart \ + drivers/synopsys/usbotg + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi + +MODULES_FIRMWARE += \ + platform/$(PLATFORM)/apcie \ + drivers/apple/anc \ + drivers/pci \ + drivers/apple/apcie \ + drivers/apple/dart_lpae \ + drivers/nvme + +LIBRARY_MODULES += \ + lib/libcorecrypto + +MODULES_BOOT += \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/displaypipe + +# Override platform default memory map +TZ0_SIZE := 12*1024*1024 + +include $(APPDIR)/products.mk + diff --git a/apps/iBoot/config/watch2-config-base.mk b/apps/iBoot/config/watch2-config-base.mk new file mode 100644 index 0000000..6217bb9 --- /dev/null +++ b/apps/iBoot/config/watch2-config-base.mk @@ -0,0 +1,99 @@ +# Copyright (C) 2013-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# watch2 iboot bootloader build config +PLATFORM := t8002 +SUB_PLATFORM := t8002 +TARGET := watch2 +ARCH := arm +BOOT_CONFIG := nand +DOCKCHANNELS := uart +ADBE_VERSION := 3 + +# code modules +MODULES_BASIC += \ + platform/$(PLATFORM) \ + platform/$(PLATFORM)/chipid \ + platform/$(PLATFORM)/dcs \ + platform/$(PLATFORM)/pmgr \ + drivers/apple/dcs \ + drivers/apple/a7iop \ + drivers/apple/aes_v2 \ + drivers/apple/aic \ + drivers/apple/ausb \ + drivers/apple/dockchannel \ + drivers/apple/gpio \ + drivers/apple/sep \ + drivers/nxp/cbtl1610 \ + drivers/samsung/uart \ + drivers/synopsys/usbotg \ + platform/$(PLATFORM)/miu + +#DISABLED_MODULES += \ + #drivers/apple/reconfig # this can probably go to MODULES_BOOT + +ifneq ($(BUILD),RELEASE) +MODULES_BASIC += \ + drivers/apple/consistent_debug +endif + +ifneq ($(CONFIG_FPGA),true) +ifneq ($(CONFIG_SIM),true) +MODULES_BASIC += \ + drivers/power/hdqgauge \ + drivers/idt/idtp9022 \ + drivers/dialog/pmu \ + drivers/apple/voltage_knobs +endif +endif + +#ifeq ($(CONFIG_SIM),true) +#MODULES_BASIC += \ +# drivers/apple/swifterpmu +#endif + +ifneq ($(CONFIG_SIM), true) +MODULES_BASIC += \ + drivers/apple/iic +endif + +ifeq ($(BOOT_CONFIG), nand) +MODULES_FILESYSTEM += \ + drivers/apple/asp \ + drivers/apple/csi \ + +MODULES_FIRMWARE += \ + drivers/apple/anc +endif + +ifeq ($(BOOT_CONFIG), nor) + +MODULES_BASIC += \ + drivers/samsung/spi + +MODULES_FILESYSTEM += \ + drivers/flash_nor/spi +endif + +LIBRARY_MODULES += \ + lib/libcorecrypto + +ifneq ($(CONFIG_FPGA),true) +ifneq ($(CONFIG_SIM),true) +MODULES_BOOT += \ + drivers/display_pmu/beryllium \ + drivers/apple/adbe \ + drivers/apple/adfe_v2 \ + drivers/apple/displaypipe \ + drivers/display/summit \ + drivers/samsung/mipi +endif +endif + +include $(APPDIR)/products.mk diff --git a/apps/iBoot/debugcmds.c b/apps/iBoot/debugcmds.c new file mode 100644 index 0000000..7b87899 --- /dev/null +++ b/apps/iBoot/debugcmds.c @@ -0,0 +1,641 @@ +/* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +static void +memdump_usage(void) +{ + + dprintf(DEBUG_INFO, "md [-64]
\n"); +} + +/* "md -64" "md", "mdh", "mdb" */ +static int +do_memdump(int argc, struct cmd_arg *args) +{ + uintptr_t address; + size_t count; + int width; + size_t i; + int index_mod = 16; + + /* default dump values */ + static uintptr_t last_address = DEFAULT_LOAD_ADDRESS; + static size_t last_count = 0x100; + + if (!strcmp(args[0].str, "md")) { + width = 32; + if (argc > 1) { + if (!strcmp(args[1].str, "-help")) { + memdump_usage(); + return 0; + } else if (!strcmp(args[1].str, "-64")) { + width = 64; + index_mod = 32; + } + } + } else if (!strcmp(args[0].str, "mdh")) { + width = 16; + } else { + width = 8; + } + + address = last_address; + count = last_count; + + if (width != 64) { + if (argc >= 2) { + if (!isdigit(args[1].str[0])) { + memdump_usage(); + return -1; + } + address = args[1].u; + } + if (argc >= 3) { + if (!isdigit(args[2].str[0])) { + memdump_usage(); + return -1; + } + count = args[2].u; + } + } + else { + if (argc >= 3) { + if (!isdigit(args[2].str[0])) { + memdump_usage(); + return -1; + } + address = args[2].u; + } + if (argc >= 4) { + if (!isdigit(args[3].str[0])) { + memdump_usage(); + return -1; + } + count = args[3].u; + } + } + +// printf("dumping memory at %#lx, len 0x%x, width %d\n", address, count, width); + + if (!security_allow_memory((void *)address, count * width / 8)) { + printf("Permission Denied\n"); + return -1; + } + + i = 0; + while (i < count) { + if ((i % index_mod) == 0) { + if (i != 0) + puts("\n"); + printf("%p: ", (uint8_t *)address + i); + } + + switch (width) { + case 64: + printf("%016llx ", *(uint64_t *)(address + i)); + i += 8; + break; + case 32: + printf("%08x ", *(uint32_t *)(address + i)); + if (4 == (i & 0xf)) + printf(" "); + i += 4; + break; + case 16: + printf("%04x ", *(uint16_t *)(address + i)); + if (6 == (i & 0xf)) + printf(" "); + i += 2; + break; + case 8: + printf("%02x ", *(uint8_t *)(address + i)); + if (7 == (i & 0xf)) + printf(" "); + i += 1; + break; + } + } + puts("\n"); + + /* save the values so we can continue next time */ + last_count = count; + last_address = address + count; + + return 0; +} + +MENU_COMMAND_DEBUG(md, do_memdump, "memory display - 32bit or 64bit", NULL); +MENU_COMMAND_DEBUG(mdh, do_memdump, "memory display - 16bit", NULL); +MENU_COMMAND_DEBUG(mdb, do_memdump, "memory display - 8bit", NULL); + +/* "mw -64" "mw", "mwh", "mwb", "mws" */ +static int +do_memwrite(int argc, struct cmd_arg *args) +{ + static uintptr_t last_address = DEFAULT_LOAD_ADDRESS; + uintptr_t address; + size_t length; + uint64_t data; + const char *buffer; + int width; + + if ((argc <= 1) || (!strcmp(args[1].str, "-help")) || (argc > 4)) + goto print_usage; + + switch (argc) { + case 2: + address = last_address; + data = args[1].u; + buffer = args[1].str; + break; + + case 3: + address = args[1].u; + last_address = address; + data = args[2].u; + buffer = args[2].str; + break; + + case 4: + if (strcmp(args[1].str, "-64") != 0) + goto print_usage; + address = args[2].u; + last_address = address; + data = args[3].u; + buffer = args[3].str; + break; + } + + if (!strcmp(args[0].str, "mw")) { + width = 32; + length = 4; + if ((argc > 1) && (!strcmp(args[1].str, "-64"))) { + width = 64; + length = 8; + } + } else if (!strcmp(args[0].str, "mwh")) { + width = 16; + length = 2; + } else if (!strcmp(args[0].str, "mwb")) { + width = 8; + length = 1; + } else { + width = 255; + length = strlen(buffer) + 1; + } + +// printf("writing memory at %#lx, data %#lx\n", address, data); + + if (!security_allow_memory((void *)address, length)) { + printf("Permission Denied\n"); + return -1; + } + + switch (width) { + case 64: + *(uint64_t *)address = (uint64_t)data; + break; + case 32: + *(uint32_t *)address = (uint32_t)data; + break; + case 16: + *(uint16_t *)address = (uint16_t)data; + break; + case 8: + *(uint8_t *)address = (uint8_t)data; + break; + + case 255: + strlcpy((char *)address, buffer, length); + break; + } + + return 0; + +print_usage: + if (strcmp(args[0].str, "mw") != 0) + printf("%s [
] \n", args[0].str); + else + printf("mw [-64] [
] \n"); + return -1; +} + +MENU_COMMAND_DEBUG(mw, do_memwrite, "memory write - 32bit or 64bit", NULL); +MENU_COMMAND_DEBUG(mwh, do_memwrite, "memory write - 16bit", NULL); +MENU_COMMAND_DEBUG(mwb, do_memwrite, "memory write - 8bit", NULL); +MENU_COMMAND_DEBUG(mws, do_memwrite, "memory write - string", NULL); + + +// Go requires the type to be for iBEC, CFE or RBM +static const u_int32_t go_restricted_types[] = { IMAGE_TYPE_IBEC, + IMAGE_TYPE_CFE_LOADER, + IMAGE_TYPE_RBM, + IMAGE_TYPE_PHLEET, + IMAGE_TYPE_PE_RTOS, + IMAGE_TYPE_HAMMER }; + +static int +do_go_target(int argc, struct cmd_arg *args, enum boot_target target, addr_t addr, addr_t secure_addr, size_t secure_len) +{ + const u_int32_t *types = go_restricted_types; + u_int32_t count = sizeof(go_restricted_types) / sizeof(go_restricted_types[0]); + u_int32_t actual; + u_int32_t options; + +#if !RELEASE_BUILD + if (argc >= 2 && ((argc > 1) && !strcmp("help", args[1].str))) { + printf("%s [
]\n", args[0].str); + return -1; + } + + addr = env_get_uint("loadaddr", addr); + if (argc >= 2) + addr = args[1].u; +#endif + + if (!security_allow_memory((void *)addr, secure_len)) { + printf("Permission Denied\n"); + return -1; + } + + /* execution of 'go' command is treated as starting of a new boot-chain, so tells library to enforce policies it cares about. */ + /* image epoch must be greater than or equal to the current stage's epoch */ + options = IMAGE_OPTION_GREATER_EPOCH | IMAGE_OPTION_NEW_TRUST_CHAIN; + +#if DEBUG_BUILD + // Allow any type in DEBUG builds + types = NULL; + count = 0; +#endif + + if (image_load_memory(addr, secure_len, &secure_addr, &secure_len, types, count, &actual, options)) { + printf("Memory image not valid\n"); + return -1; + } + + dprintf(DEBUG_CRITICAL, "actual = %x\n", actual); + + /* consolidate environment */ + security_consolidate_environment(); + + printf("jumping into image at %p\n", (void *)secure_addr); + + prepare_and_jump(target, (void *)secure_addr, NULL); // XXX don't actually know what we're jumping into + + return 0; +} + +static int +do_go(int argc, struct cmd_arg *args) +{ + return do_go_target(argc, args, BOOT_UNKNOWN, DEFAULT_LOAD_ADDRESS, DEFAULT_KERNEL_ADDRESS, DEFAULT_KERNEL_SIZE); +} + +static int +do_go_dfu(int argc, struct cmd_arg *args) +{ + return do_go_target(argc, args, BOOT_UNKNOWN, INSECURE_MEMORY_BASE, INSECURE_MEMORY_BASE, INSECURE_MEMORY_SIZE); +} + +#if WITH_RECOVERY_MODE +MENU_COMMAND(go, do_go, "jump directly to address", NULL); +#elif WITH_DFU_MODE +MENU_COMMAND(go, do_go_dfu, "jump directly to address", NULL); +#endif + +static int +do_script(int argc, struct cmd_arg *args) +{ + int length = 0; + + if ((argc > 2) || ((argc > 1) && !strcmp("help", args[1].str))) { + printf("%s [
]\n", args[0].str); + return -1; + } + + const char *script = (const char *)env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + + if (argc > 1) + script = (const char *)args[1].u; + + while ((script[length] != 0x04) && (script[length] != 0)) length++; + + if (!security_allow_memory(script, length)) { + printf("Permission Denied\n"); + return -1; + } + + return debug_run_script(script); +} + +MENU_COMMAND_DEVELOPMENT(script, do_script, "run script at specific address", NULL); + +#if !WITH_SIDP +int do_secrom(int argc, struct cmd_arg *args) +{ + printf("Enabling remap and jumping...\n"); +#if defined(SECUREROM_LOAD_ADDRESS) + prepare_and_jump(BOOT_SECUREROM, (void*)SECUREROM_LOAD_ADDRESS, NULL); +#else + prepare_and_jump(BOOT_SECUREROM, NULL, NULL); +#endif +} + +MENU_COMMAND_DEBUG(secrom, do_secrom, "execute previously loaded SecureROM image", NULL); +#endif + +#if WITH_ENV +static int +do_run(int argc, struct cmd_arg *args) +{ + if (argc < 2) { + printf("%s \n", args[0].str); + return -1; + } + + const char *env = env_get(args[1].str); + if (!env) { + printf("could not find variable\n"); + return -1; + } + + return debug_run_script(env); +} + +MENU_COMMAND_DEVELOPMENT(run, do_run, "use contents of environment var as script", NULL); +#endif + +int do_suspend(int argc, struct cmd_arg *args) +{ +#if WITH_HW_POWER + power_suspend(); +#endif + + return 0; +} + +MENU_COMMAND_DEBUG(suspend, do_suspend, "enter suspend to RAM - one way trip for now", NULL); + +int do_bztest(int argc, struct cmd_arg *args) +{ + utime_t start, stop, delta; + u_int64_t rate; + + dprintf(DEBUG_CRITICAL, "Zeroing memory from 0x%llx to 0x%llx\n", + INSECURE_MEMORY_BASE, INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE - 1); + + start = system_time(); + + bzero((void *)INSECURE_MEMORY_BASE, INSECURE_MEMORY_SIZE); + + stop = system_time(); + + delta = stop - start; + + rate = ((INSECURE_MEMORY_SIZE >> 20) * 1000000ULL) / delta; + + dprintf(DEBUG_CRITICAL, "0x%llx bytes in %lldms at %lldMB/s\n", + INSECURE_MEMORY_SIZE, delta / 1000, rate); + + return 0; +} + +#if 0 +// Turned off to save space, enable as needed +MENU_COMMAND_DEBUG(bztest, do_bztest, "bzero test - fills insecure memory area with zeros", NULL); + +int do_ssp_test(int argc, struct cmd_arg *args) +{ + char tmp[8]; + + strlcpy(tmp, "this string should not fit", 32); + printf("stack protector\n"); + + return(0); +} +#endif + +// Turned off to save space, enable as needed +// MENU_COMMAND_DEBUG(ssp_test, do_ssp_test, "test the stack overflow protector", NULL); + +#if WITH_VFP +#include + +void +fp_test(int tid) +{ + int count; + float i, j; + + i = 1.1; + j = 3.7 + (11.5 * tid); + + for (count = 0; ; count++) { + task_sleep(100000); + j *= i; + printf("FP%d:%d: %d\n", tid, count, (int)j); + } +} + +int +fp_test_thread(void *arg) +{ + int tid = (int)arg; + + printf("FP%d: task starting\n", tid); + +#if !WITH_VFP_ALWAYS_ON + /* enable FP for this task */ + arch_task_fp_enable(true); +#endif // !WITH_VFP_ALWAYS_ON + + printf("FP%d: fp enabled\n", tid); + + fp_test(tid); + + return(0); +} + +int do_fp_test(int argc, struct cmd_arg *args) +{ + + /* FP is enabled during CPU init */ + printf("FP on, yielding..."); + task_yield(); + printf("ok\n"); + + task_start(task_create("fp1", fp_test_thread, (void *)1, 0x1000)); + printf("fp1 started, waiting...\n"); + task_sleep(2000000); + task_start(task_create("fp2", fp_test_thread, (void *)2, 0x1000)); + printf("fp2 started\n"); + + return(0); +} + +MENU_COMMAND_DEBUG(fp_test, do_fp_test, "test floatingpoint support", NULL); +#endif /* WITH_VFP */ + + +static int do_panic(int argc, struct cmd_arg *args) +{ + panic("command prompt"); +} +MENU_COMMAND_DEBUG(panic, do_panic, "Force a panic", NULL); + +static int do_double_panic(int argc, struct cmd_arg *args) +{ + // Set gPanicStr so panic() thinks it has recursed. + gPanicStr = "Forced double panic"; + panic("command prompt"); +} +MENU_COMMAND_DEBUG(double_panic, do_double_panic, "Force a double panic", NULL); + +static int do_sleep(int argc, struct cmd_arg *args) +{ + if (argc != 2) { + printf("%s \n", args[0].str); + return(-1); + } + + if (!strcmp(args[0].str, "msleep")) { + task_sleep(1000 * args[1].u); + } else { + task_sleep(1000 * 1000 * args[1].u); + } + + return 0; +} +MENU_COMMAND_DEBUG(sleep, do_sleep, "Pause execution (seconds)", NULL); +MENU_COMMAND_DEBUG(msleep, do_sleep, "Pause execution (milliseconds)", NULL); + +static int do_dram_info(int argc, struct cmd_arg *args) +{ +#if WITH_HW_DCS == 1 + uint8_t rev_id, rev_id2; + platform_get_memory_rev_ids(&rev_id, &rev_id2); + dprintf(DEBUG_INFO, "vendor: %s, rev_id=%d, rev_id2=%d, size: %llu MiB\n", platform_get_memory_manufacturer_string(), rev_id, rev_id2, (platform_get_memory_size() / (1024 * 1024))); +#else + dprintf(DEBUG_INFO, "vendor: %s, size: %llu MiB\n", platform_get_memory_manufacturer_string(), (platform_get_memory_size() / (1024 * 1024))); +#endif + return 0; +} +MENU_COMMAND_DEBUG(dram_info, do_dram_info, "Prints DRAM vendor and size", NULL); + +#if WITH_HW_POWER +// borrowed from AppleARMRTC::convertSecondsToDateTime, with fixed leap year rule from Libc tzfile.c + +// Tables for accumulated days in year by month, latter used for leap years +static const int daysbymonth[] = + { 0, 31, 59, 90, 120, + 151, 181, 212, 243, + 273, 304, 334, 365 }; +static const int lydaysbymonth[] = + { 0, 31, 60, 91, 121, + 152, 182, 213, 244, + 274, 305, 335, 366 }; + +#define daysinyear(y) \ + ((((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) ? 365 : 366) + +struct date_time_t { + uint8_t seconds; /* 0-59 */ + uint8_t minutes; /* 0-59 */ + uint8_t hours; /* 0-23 */ + uint8_t dayWeek; /* 0-6 */ + uint8_t dayMonth; /* 1-31 */ + uint8_t month; /* 1-12 */ + uint16_t year; +}; + +static void convert_seconds_to_date_time(long secs, struct date_time_t *dt ) +{ + const int * dbm = daysbymonth; + long n; + int x, y; + + // Calculate seconds, minutes and hours + + n = secs % (24 * 3600); + dt->seconds = n % 60; + n /= 60; + dt->minutes = n % 60; + dt->hours = n / 60; + + // Calculate day of week + + n = secs / (24 * 3600); + dt->dayWeek = (n + 4) % 7; + + // Calculate year + + for (y = 1970; n >= (x = daysinyear(y)); y++) + n -= x; + dt->year = y; + + // Change table if year is a leap year + + if (x == 366) + dbm = lydaysbymonth; + + // Adjust remaining days value to start at 1 + + n += 1; + + // Calculate month + + for (x = 1; n > dbm[x]; x++) + continue; + dt->month = x; + + // Calculate day of month + + dt->dayMonth = n - dbm[x - 1]; +} + +static int do_date(int argc, struct cmd_arg *args) +{ + utime_t usecs = calendar_time(); + utime_t secs = usecs / 1000000; + + if (argc > 1 && !strcmp(args[1].str, "-r")) { + printf("%llu.%02llu\n", secs, (usecs / 10000) % 100); + } else { + struct date_time_t dt; + convert_seconds_to_date_time(secs, &dt); + + static const char * const days[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + static const char * const months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + printf("%s %s %02u %02u:%02u:%02u.%02llu UTC %04u\n", days[dt.dayWeek], months[dt.month-1], dt.dayMonth, dt.hours, dt.minutes, dt.seconds, (usecs / 10000) % 100, dt.year); + } + + return 0; +} +MENU_COMMAND_DEVELOPMENT(date, do_date, "display or set date and time", NULL); +#endif + +#endif + diff --git a/apps/iBoot/default_env.c b/apps/iBoot/default_env.c new file mode 100644 index 0000000..4a66eab --- /dev/null +++ b/apps/iBoot/default_env.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_ENV + +void sys_setup_default_environment(void) +{ + env_set("boot-partition", "0", 0); + env_set("boot-path", "/System/Library/Caches/com.apple.kernelcaches/kernelcache", 0); + + env_set("build-style", build_style_string, 0); + env_set("build-version", build_tag_string, 0); + + env_set("config_board", CONFIG_BOARD_STRING, 0); + env_set_uint("loadaddr", (uintptr_t)DEFAULT_LOAD_ADDRESS, 0); + + // used by PR to figure out max allowed ramdisk size + env_set_uint("ramdisk-size", (uintptr_t)DEFAULT_RAMDISK_SIZE, 0); + + env_set("boot-command", "fsboot", 0); + +#if DEBUG_BUILD + env_set("bootdelay", "3", 0); + env_set("auto-boot", "false", 0); + env_set("idle-off", "false", 0); + env_set("debug-uarts", "3", 0); +#else + // release, development builds just boot directly + env_set("bootdelay", "0", 0); + env_set("auto-boot", "true", 0); + env_set("idle-off", "true", 0); +#endif + +#if !RELEASE_BUILD + #if WITH_IMAGE4 + env_set("diags-path", "/AppleInternal/Diags/bin/diag.img4", 0); + #else + env_set("diags-path", "/AppleInternal/Diags/bin/diag.img3", 0); + #endif +#endif // !RELEASE_BUILD + + if (target_config_dev()) { + // Dev boards shouldn't idle-off + env_set("idle-off", "false", 0); + } + + platform_setup_default_environment(); +} + +void sys_load_environment(void) +{ +#if WITH_NVRAM + nvram_load(); +#else + dprintf(DEBUG_CRITICAL, "WARNING: No nvram available to load persistent environment from.\n"); +#endif +} + +#endif /* WITH_ENV */ diff --git a/apps/iBoot/iBoot.mk b/apps/iBoot/iBoot.mk new file mode 100644 index 0000000..63ed59f --- /dev/null +++ b/apps/iBoot/iBoot.mk @@ -0,0 +1,195 @@ +# Copyright (C) 2007-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +############################################################################### +# Build rules for the iBoot application. +# +# Recognises values in +# +# TARGETS +# PRODUCTS +# BUILDS +# + +# +# These are the config, product and build kinds that the application +# code recognises. +# +VALID_PRODUCTS := LLB iBoot iBSS iBEC +VALID_BUILDS := RELEASE DEVELOPMENT DEBUG SECRET + +# support for temporarily turning off targets +SUPPRESSED_TARGETS := + +############################################################################### +############################################################################### +# No user-serviceable parts below +############################################################################### +############################################################################### + +# +# Directory containing configuration files. +# +# Must do this before including any other makefile. +# +CONFIG_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))/config + +# DEVICEMAP macros +include makefiles/device_map.mk + +# +# Consult the configuration directory for the set of targets we know +# how to build, and the device map database for the set of targets +# that the current train wants to build. +# +VALID_TARGETS := $(sort $(subst -config.mk,,$(notdir $(wildcard $(CONFIG_DIR)/*-config.mk)))) +MAP_TARGETS_ALL := $(sort $(DEVICEMAP_TARGETS)) + +# Filter MAP_TARGETS for targets with at least one PRODUCT in their manifest. +MAP_TARGETS_WITH_PRODUCTS := \ + $(sort $(call DEVICEMAP_TARGETS_FOR_PRODUCTS,$(VALID_PRODUCTS))) +MAP_TARGETS := $(filter $(MAP_TARGETS_ALL),$(MAP_TARGETS_WITH_PRODUCTS)) +FILTERED_OUT_TARGETS := \ + $(filter-out $(MAP_TARGETS_WITH_PRODUCTS),$(MAP_TARGETS_ALL)) + +# +# Generate and validate the list of targets that we are going to +# build. +# +TARGETS ?= $(filter-out $(SUPPRESSED_TARGETS),$(MAP_TARGETS)) +ERROR_TARGETS := $(filter-out $(VALID_TARGETS), $(TARGETS)) +ifneq ($(ERROR_TARGETS),) +$(warning CONFIG_DIR $(CONFIG_DIR)) +$(warning MAP_TARGETS $(MAP_TARGETS)) +$(warning VALID_TARGETS $(VALID_TARGETS)) +$(error Unrecognized in TARGETS - $(ERROR_TARGETS)) +endif + +# +# If TARGETS contains a target not in the device map, we have to deal +# with not being able to look up PRODUCTS in the map for those +# targets. Since the PRODUCTS handling below allows either an +# explicit list, OR a lookup in the database, we can't handle the case +# where some TARGETS are in the map and some aren't. +# +NONMAP_TARGETS := $(filter-out $(MAP_TARGETS), $(TARGETS)) +ifneq ($(NONMAP_TARGETS),) +ifneq ($(NONMAP_TARGETS), $(TARGETS)) +$(error Some TARGETS not listed in device map (must be all or none) - $(NONMAP_TARGETS)) +endif +endif +PRODUCTS ?= $(VALID_PRODUCTS) + +# +# Validate or fetch the list of PRODUCTS that we are going to build. +# +# In the macro form of PRODUCTS, the argument may also be +# a partially-constructed -... word. +# +# If we invoke DEVICEMAP_PRODUCTS_FOR_TARGET we will get back product +# types that we don't know about, so we have to filter them out at +# this point. +# +# Note that following this it is necessary to use $(call PRODUCTS) +# to get the PRODUCTS list. +# +ERROR_PRODUCTS = $(filter-out $(VALID_PRODUCTS),$(PRODUCTS)) +ifneq ($(ERROR_PRODUCTS),) +$(error Unrecognized in PRODUCTS - $(ERROR_PRODUCTS)) +endif +PRODUCTS ?= $(filter $(VALID_PRODUCTS),$(call DEVICEMAP_PRODUCTS_FOR_TARGET,$(word 1, $(subst -, ,$(1))))) + +# +# Validate the list of build types we're going to build. +# +BUILDS ?= $(filter-out SECRET, $(VALID_BUILDS)) +ERROR_BUILDS = $(filter-out $(VALID_BUILDS), $(BUILDS)) +ifneq ($(ERROR_BUILDS),) +$(error Unrecognized in BUILDS - $(ERROR_BUILDS)) +endif + +# +# Generate a list of -- words. +# +# These words are used to define the things to be built, and are +# decomposed to extract the build configuration in the ACTIONS rule +# below. +# +LIST := $(call DEVICE_MAP_TPB_FILTERED,$(TARGETS),$(PRODUCTS),$(BUILDS)) + +# +# Generate rules for the standard actions that depend on targets +# defining the things to be built. +# +# For each , generate a dependency on +# --- for every valid +# permutation of , , and . +# +LIST_TEMPLATE := $(addprefix %-,$(LIST)) +$(STANDARD_ACTIONS):%: $(LIST_TEMPLATE) + +# +# Generate a list of action words corresponding to the depended +# targets that was produced for the STANDARD_ACTIONS. +# +ACTIONS := $(foreach action,$(STANDARD_ACTIONS),$(addprefix $(action)-,$(LIST))) + +# +# Configuration options for built products - could probably move this to products.mk +# +DFU_IMAGE_LLB := false +DFU_IMAGE_iBoot := false +DFU_IMAGE_iBEC := true +DFU_IMAGE_iBSS := true + +# Look up per-target parameters once so that we don't have to go to the database +# every time we invoke make below +TGT_DICT := $(call DEVICEMAP_TGT_DICT) + +# Look up per-target/product parameters once as well +TGT_PRODUCT_DICT := $(call DEVICEMAP_TGT_PRODUCT_DICT, $(VALID_PRODUCTS)) + +# +# Template rule to build things. +# +$(ACTIONS): action = $(word 1, $(subst -, ,$@)) +$(ACTIONS): target = $(word 2, $(subst -, ,$@)) +$(ACTIONS): product = $(word 3, $(subst -, ,$@)) +$(ACTIONS): build = $(word 4, $(subst -, ,$@)) +$(ACTIONS): install_name = $(product).$(target).$(build) +$(ACTIONS): + @echo %%% $(action) $(install_name) + @$(MAKE) -f makefiles/main.mk \ + SUB_TARGET=$(target) \ + CONFIG="" \ + PRODUCT=$(product) \ + BUILD=$(build) \ + APPLICATION_OPTIONS=$(APPLICATION_OPTIONS) \ + INSTALL_NAME=$(install_name) \ + DFU_IMAGE=$(DFU_IMAGE_$(product)) \ + IMAGE_TYPE=$(call DEVICEMAP_TGT_PRODUCT_DICT_PAYLOADTYPE, $(TGT_PRODUCT_DICT), $(target),$(product)) \ + DEVMAP_EPOCH=$(call DEVICEMAP_TGT_DICT_EPOCH, $(TGT_DICT), $(target)) \ + DEVMAP_PRODUCT_ID=$(call DEVICEMAP_TGT_DICT_PRODUCTID, $(TGT_DICT), $(target)) \ + IMAGE_FORMAT=$(or $(call DEVICEMAP_TGT_DICT_IMGFMT, $(TGT_DICT), $(target), $(IMAGE_FORMAT))) \ + CRYPTO_HASH=$(call DEVICEMAP_TGT_DICT_CRYPTOHASH, $(TGT_DICT), $(target)) \ + $(action) + +help: + @echo Valid TARGETS + @echo " $(VALID_TARGETS)" + @echo Valid PRODUCTS + @echo " $(VALID_PRODUCTS)" + @echo Valid BUILDS + @echo " $(VALID_BUILDS)" + @echo Elided TARGETS with no matching PRODUCTS + @echo " $(FILTERED_OUT_TARGETS)" + @echo "" + @echo Default products: + @echo $(LIST) diff --git a/apps/iBoot/main.c b/apps/iBoot/main.c new file mode 100644 index 0000000..0ea220b --- /dev/null +++ b/apps/iBoot/main.c @@ -0,0 +1,1382 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_USB_DFU +#include +#endif +#if WITH_TBT_DFU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_TICKET +#include +#endif +#if WITH_NAND_FILESYSTEM +#include +#endif + +#if WITH_VOLTAGE_KNOBS +#include +#endif + +#if SUPPORT_FPGA +#define USER_BUTTON_POWERON_TIMEOUT (0 * 1000 * 1000) +#else +// at least 400 ms must elapse since power on due to power button press +#define USER_BUTTON_POWERON_TIMEOUT (400 * 1000) +#endif +#define USER_BUTTON_POWEROFF_TIMEOUT (5 * 1000 * 1000) +#define USER_BUTTON_RECOVER_TIMEOUT (5 * 1000 * 1000) + +static void main_llb(void); +static void main_ibss(void); +static void main_generic(void); +static void main_dfu(void); + +static void do_iboot_autoboot(void); +static void do_ibec_autoboot(void); + +struct autoboot_command +{ + const char *command; + int (*func)(void); +}; +static bool check_autoboot(bool autoboot, uint32_t bootdelay); +static void do_common_autoboot(struct autoboot_command *cmds); + +static void do_ll_init(void); + +static void do_boot_ui(void); +static void do_recoverymode_ui(void); + +static int main_task(void *arg); +static int poweroff_task(void *arg); +static int idleoff_task(void *arg); + +static void print_boot_banner(void); + +static void check_enter_dfu(void); + +#if WITH_TICKET +static bool dfu_parse_ticket(addr_t load_address, size_t load_length, addr_t *new_load_address, size_t *new_load_length); +#endif +static bool dfu_console_init(void); +static addr_t dfu_console_loadaddr(addr_t load_address); +static bool dfu_console_loadctrl(addr_t load_address, size_t load_length); +static int do_dfu_cmd(int argc, struct cmd_arg *args); + +static void init_console_buffer(size_t size); + +/* + * Toplevel main() + */ +void +_main(void) +{ + PROFILE_INIT(); + + /* initialize the cpu */ + arch_cpu_init(false); + + PROFILE_EXIT('ACI'); + + /* main logic flow varies based on what we are building */ +#if PRODUCT_LLB + main_llb(); +#elif PRODUCT_IBSS + main_ibss(); +#else + main_generic(); +#endif +} + +/* + * Main logic flow for LLB. + */ +static void +main_llb(void) +{ + bool resume; + bool poweron, cold_button_boot = false; + + /* do low-level SoC init */ + do_ll_init(); + + /* bring up system services (cpu, tasks, callout, heap) */ + sys_init(); + PROFILE_EXIT('SyI'); + +#if !WITH_NO_RANDOM_STACK_COOKIE + /* Generate random stack cookie for platforms that + * don't have a fast resume path + */ + sys_init_stack_cookie(); + PROFILE_EXIT('SIS'); +#endif + +#if !RELEASE_BUILD + init_console_buffer(4096); +#endif + + /* do some early initialization of hardware */ + /* timers will start firing at this point */ + dprintf(DEBUG_INFO, "doing early platform hardware init\n"); + platform_early_init(); + PROFILE_EXIT('PEI'); + + /* reset watchdog timer in case it's enabled */ + platform_watchdog_tickle(); + + /* Detect cold boot, and power on conditions */ + poweron = target_should_poweron(&cold_button_boot); + + /* Detect if device has been suspended */ + resume = power_is_suspended(); + + /* initialize sdram */ + dprintf(DEBUG_INFO, "initializing main memory\n"); + PROFILE_ENTER('PIM'); + platform_init_mainmem(resume); + PROFILE_EXIT('PIM'); + + /* try to restore_system */ + if (resume) { +#if WITH_VOLTAGE_KNOBS + knobs_load_from_standby_storage(); +#endif + + platform_restore_system(); + + /* Suspended memory is no longer valid, re-init security */ + security_init(true); + boot_set_stage(kPowerNVRAMiBootStageBooted); + + /* + * If we get here, resume has failed and we are going to + * re-start the system. Note that we don't want to do the + * user poweron detection as the user already expects that + * the system is on. + */ + + } else { +#if WITH_NO_RANDOM_STACK_COOKIE + /* generate random stack cookie now that we know we + * aren't on the fast resume path + */ + sys_init_stack_cookie(); + PROFILE_EXIT('SIS'); +#endif + +#if WITH_VOLTAGE_KNOBS + // prepare for voltage knobs adjustments + knobs_prepare_standby_storage(); +#endif + + /* Wait for a user poweron request if started */ + while (cold_button_boot) { +#if WITH_TARGET_CHARGETRAP + if (target_needs_chargetrap()) { + // If charge trap is implemented in the target (e.g. Dali Mode), + // we should immediately proceed with boot if we know we need to + // boot into it. + break; + } +#endif + poweron &= target_should_poweron(&cold_button_boot); + if (!poweron) { + dprintf(DEBUG_CRITICAL, "Power on canceled.\n"); + platform_poweroff(); + } + + // Ensure that at least USER_BUTTON_POWERON_TIMEOUT number of us have elapsed since power on. + // Start time is 0 because timer on H3+ platforms will start counting up from 0 after power on. + if (time_has_elapsed(0, USER_BUTTON_POWERON_TIMEOUT)) { + power_cancel_buttonwait(); + break; + } + + spin(10 * 1000); + } + } + +#ifdef HEAP_EXT_SIZE + /* + * If we have extra memory for the heap, add it. This needs + * to happen after main memory has been initialized, after any + * decision has been whether to resume, but before + * platform_init() gets called. + */ + dprintf(DEBUG_INFO, "Adding 0x%llx bytes at %p to heap.\n", HEAP_EXT_SIZE, (void*)HEAP_EXT_BASE); + PROFILE_ENTER('Hep'); + heap_add_chunk((void *)HEAP_EXT_BASE, HEAP_EXT_SIZE, true); + PROFILE_EXIT('Hep'); +#endif + + /* initialize the rest of hardware */ + dprintf(DEBUG_INFO, "doing platform hardware init\n"); + PROFILE_ENTER('PIn'); + platform_init(); + PROFILE_EXIT('PIn'); + + /* check for external request to enter DFU (if detected then enter DFU) */ + check_enter_dfu(); + + dprintf(DEBUG_INFO, "looking for boot images\n"); + find_boot_images(); + +#if WITH_TICKET + /* load the root ticket */ + ticket_load(); +#endif + + /* find iBoot and boot it */ + boot_iboot(); + + /* failed to load system */ + dprintf(DEBUG_CRITICAL, "do_boot: failed to find anything to load\n"); + + /* re-init security after failed iBoot load */ + security_init(false); + + dprintf(DEBUG_CRITICAL, "LLB done, failed to boot asking for DFU...\n"); + main_dfu(); +} + +static void +main_dfu(void) +{ +#if WITH_USB_DFU || WITH_TBT_DFU + bool autoboot = dfu_console_init(); + + while (1) { + int result; + addr_t load_address; + size_t load_length; + uint32_t type, options; + + /* reset secuirity and clear the insecure memory area */ + security_init(true); + + load_address = INSECURE_MEMORY_BASE; + load_length = INSECURE_MEMORY_SIZE; + + if (!autoboot) { + load_address = dfu_console_loadaddr(load_address); + } + +#if WITH_USB_DFU + result = getDFUImage((void *)load_address, load_length); +#elif WITH_TBT_DFU + result = thunderboot_get_dfu_image((void *)load_address, load_length); +#else +#error "No valid DFU driver" +#endif + if (result < 0) { + dprintf(DEBUG_INFO, "fatal DFU download error"); + continue; + } + + load_length = result; + + if (!autoboot && dfu_console_loadctrl(load_address, load_length)) { + continue; + } + +#if WITH_TICKET + if (!dfu_parse_ticket(load_address, + load_length, + &load_address, + &load_length) ) { + continue; + } +#endif + + /* image epoch must be greater than or equal to the current stage's epoch */ + options = IMAGE_OPTION_GREATER_EPOCH; + +#if PRODUCT_LLB + /* llb in usb-dfu mode is starting a new boot-chain, so tells library to enforce policies it cares about. */ + options |= IMAGE_OPTION_NEW_TRUST_CHAIN; +#endif + + type = IMAGE_TYPE_IBEC; + if (0 == image_load_memory(load_address, /* fromAddress */ + load_length, /* fromLength */ + &load_address, /* address */ + &load_length, /* length */ + &type, /* list of types */ + 1, /* count of types */ + NULL, /* actual type not needed */ + options)) { + dprintf(DEBUG_CRITICAL, "executing image...\n"); + + /* consolidate environment */ + security_consolidate_environment(); + +#if WITH_SIDP + /* Always seal the manifest that authorizes iBEC. */ + security_sidp_seal_boot_manifest(true); +#endif + + prepare_and_jump(BOOT_IBOOT, (void *)load_address, NULL); + break; + } + + dprintf(DEBUG_INFO, "image load failed\n"); + } +#endif /* WITH_USB_DFU || WITH_TBT_DFU */ + + /* DFU failed, poweroff the system */ + platform_poweroff(); + + panic("poweroff failed"); +} + +/* + * Early main logic flow for iBSS. + */ +static void +main_ibss(void) +{ + /* do low-level SoC init */ + do_ll_init(); + + /* bring up system services (cpu, tasks, callout, heap) */ + sys_init(); + PROFILE_EXIT('SyI'); + + /* generate random stack cookie */ + sys_init_stack_cookie(); + PROFILE_EXIT('SIS'); + +#if !RELEASE_BUILD + init_console_buffer(4096); +#endif + + /* do some early initialization of hardware */ + /* timers will start firing at this point */ + dprintf(DEBUG_INFO, "doing early platform hardware init\n"); + platform_early_init(); + PROFILE_EXIT('PEI'); + + /* reset watchdog timer in case it's enabled */ + platform_watchdog_tickle(); + +#if WITH_VOLTAGE_KNOBS + // prepare for voltage knobs adjustments + knobs_prepare_standby_storage(); +#endif + + /* initialize sdram */ + dprintf(DEBUG_INFO, "initializing main memory\n"); + platform_init_mainmem(false /*resume*/); + PROFILE_EXIT('PIM'); + +#if WITH_DFU_MODE + dprintf(DEBUG_CRITICAL, "iBSS ready, asking for DFU...\n"); + platform_init(); + PROFILE_EXIT('PIn'); + main_dfu(); +#elif WITH_RECOVERY_MODE + /* start a task to finish setting up the system and boot */ + /* this also effectively moves the system stack to the heap */ + task_start(task_create("main", main_task, NULL, 0x1C00)); +#else + #error "!(WITH_DFU_MODE || WITH_RECOVERY_MODE)" +#endif + + task_exit(0); +} + +/* + * Early main logic flow for non LLB/iBSS products.. + */ +static void +main_generic(void) +{ + /* bring up system services (cpu, tasks, callout, heap) */ + sys_init(); + PROFILE_EXIT('SyI'); + + /* generate random stack cookie */ + sys_init_stack_cookie(); + PROFILE_EXIT('SIS'); + +#if !RELEASE_BUILD + init_console_buffer(100*1024); +#endif + + /* do some early initialization of hardware */ + /* timers will start firing at this point */ + dprintf(DEBUG_INFO, "doing early platform hardware init\n"); + platform_early_init(); + + /* reset watchdog timer in case it's enabled */ + platform_watchdog_tickle(); + + /* start a task to finish setting up the system and boot */ + /* this also effectively moves the system stack to the heap */ + task_start(task_create("main", main_task, NULL, 0x1C00)); + + task_exit(0); +} + + +/* + * Main task, chained from main() by recovery mode products. + */ +utime_t gPowerOnTime; +utime_t gDebugPromptTime; +utime_t gLoadKernelTime; + +static utime_t poweroff_time; +static utime_t recover_time; + +static int +main_task(void *arg) +{ + bool need_precharge = false; + + PROFILE_ENTER('Mai'); + + gPowerOnTime = system_time(); + + /* + * Test for target-specific power-off request (e.g. button + * being pressed). Start the timer if so. + */ + if (target_should_poweroff(true)) + poweroff_time = system_time(); + + /* + * Test for target-specific recovery-mode request (e.g. + * button being pressed). Start the timer if so. + */ + if (target_should_recover()) { + recover_time = system_time(); + power_cancel_buttonwait(); + } + + /* call this early to sample boot voltage before things are turned on */ + need_precharge = power_needs_precharge(); + + /* set full performance early if precharge not needed */ + if (!need_precharge) + platform_set_performance(kPerformanceHigh); + + /* + * Suspended memory is no longer valid, re-init security. + * This needs to happen after main memory has initialized and + * before it has been added to the heap. In addition, this + * needs to happen before any images are loaded. + */ + PROFILE_ENTER('ScI'); + security_init(true); + PROFILE_EXIT('ScI'); + +#ifdef HEAP_EXT_SIZE + /* + * If we have extra memory for the heap, add it. This needs + * to happen after main memory has been initialized, after + * security_init() has been called, but before platform_init() + * gets called. + */ + dprintf(DEBUG_INFO, "Adding 0x%llx bytes at %p to heap.\n", HEAP_EXT_SIZE, (void*)HEAP_EXT_BASE); + bool clear_heap; +#ifdef SECURE_MEMORY_SIZE + clear_heap = (HEAP_EXT_BASE < SECURE_MEMORY_BASE) || + (HEAP_EXT_BASE + HEAP_EXT_SIZE > SECURE_MEMORY_BASE + SECURE_MEMORY_SIZE); +#else + clear_heap = true; +#endif + PROFILE_ENTER('Hep'); + heap_add_chunk((void *)HEAP_EXT_BASE, HEAP_EXT_SIZE, clear_heap); + PROFILE_EXIT('Hep'); +#endif + + /* initialize the rest of hardware */ + dprintf(DEBUG_INFO, "doing platform hardware init\n"); + platform_init(); + PROFILE_EXIT('PIn'); + + /* initialize the system environment from nvram */ + sys_load_environment(); + PROFILE_EXIT('LdE'); + +#if WITH_VOLTAGE_KNOBS + // load voltage knobs from system environment, update PMU scratch registers, and apply knobs + knobs_update_PMU_registers(true); +#endif + + /* Turn on uart debugging if requested */ + debug_enable_uarts(env_get_uint("debug-uarts", 0)); + +#if PRODUCT_IBOOT && WITH_HW_POWER && WITH_BOOT_STAGE + /* save and reboot if this is from a soft-reset for panic logging */ + boot_check_panic(); +#endif + + /* Note that find_boot_images() is the first point at which + * syscfg services must be available. For boot-from-nand, + * this means that Whimory must be initialized by this point. + */ + dprintf(DEBUG_INFO, "looking for boot images\n"); + find_boot_images(); + +#if WITH_TICKET + /* load the root ticket */ + ticket_load(); +#endif + + /* Performance needs to be atleast medium for the display */ + if (need_precharge) + platform_set_performance(kPerformanceMedium); + +#if WITH_TARGET_CHARGETRAP + target_do_chargetrap(); +#else + power_do_chargetrap(); +#endif + + /* Turn on the display */ + dprintf(DEBUG_INFO, "initializing display\n"); + PROFILE_ENTER('PID'); + platform_init_display(); + PROFILE_EXIT('PID'); + +#if WITH_HW_POWER + power_dark_boot_checkpoint(); +#endif + /* Draw the apple logo */ + do_boot_ui(); + + /* Let backlight go to full if needed */ + PROFILE_ENTER('PID'); + platform_init_display(); + PROFILE_EXIT('PID'); + + platform_set_performance(kPerformanceHigh); + + /* + * If we saw a power-off request on entry and we are + * still seeing it now, wait out the rest of the timer + * to decide whether to power off. + */ + while (poweroff_time && target_should_poweroff(true)) { + if (time_has_elapsed(poweroff_time, USER_BUTTON_POWEROFF_TIMEOUT)) { + dprintf(DEBUG_INFO, "Force power off.\n"); + platform_poweroff(); + } + task_sleep(10 * 1000); + } + + PROFILE_ENTER('PLI'); + platform_late_init(); + PROFILE_EXIT('PLI'); + + print_boot_banner(); + +#if WITH_HW_POWER + power_dark_boot_checkpoint(); +#endif + +#if WITH_NAND_BOOT + /* Enable breadcrumbing subsystem */ + platform_init_breadcrumbs(); +#endif + + /* do auto-boot for products that support it */ +#if PRODUCT_IBOOT + do_iboot_autoboot(); +#elif PRODUCT_IBEC + do_ibec_autoboot(); +#endif + + boot_set_stage(kPowerNVRAMiBootStageOff); + + /* show UI to indicate that we are entering recovery mode */ + do_recoverymode_ui(); + + /* we're entering recovery mode, bring up any additional hardware */ + platform_debug_init(); + + task_start(task_create("poweroff", poweroff_task, NULL, 0x200)); + + /* start the command prompt/parser */ + printf("Entering recovery mode, starting command prompt\n"); +#if defined(MENU_TASK_SIZE) + task_start(task_create("command", menu_task, NULL, MENU_TASK_SIZE)); +#else + task_start(task_create("command", menu_task, NULL, 0x1C00)); +#endif + + /* sample activity time before starting idleoff task. */ + gMenuLastActivityTime = system_time(); + +#if WITH_ENV + if (env_get_bool("idle-off", false)) + task_start(task_create("idleoff", idleoff_task, NULL, 0x200)); +#endif + + PROFILE_EXIT('Mai'); + return -1; +} + +/* + * Boot a script (custom set of commands) through boot-command interface. + */ +static int +boot_script(void) +{ + debug_run_script("run boot-script"); + + return 0; +} + +/* + * Auto-boot flow for iBoot. + */ +static void +do_iboot_autoboot(void) +{ + uint32_t boot_fail_count = 0, panic_fail_count = 0; + static struct autoboot_command iboot_bootcommands[] = { + {"fsboot", mount_and_boot_system}, + {"diags", boot_diagnostics}, + {"upgrade", mount_and_upgrade_system}, +#if DEBUG_BUILD + {"script", boot_script}, +#endif + {NULL, NULL} + }; + + /* bring up mass storage devices */ + /* XXX this should be done lazily the first time we use it */ + dprintf(DEBUG_INFO, "initializing mass storage\n"); + PROFILE_ENTER('PMS'); + platform_init_mass_storage(); + PROFILE_EXIT('PMS'); + +#if WITH_HW_POWER + // At this point, NVRAM can be written. To prevent dark boot loops, clear out the dark boot flag + power_clear_dark_boot_flag(); +#endif + + /* Check for diag dock and force diags */ + if (power_get_diags_dock()) { + boot_diagnostics(); + } + + /* Check whether we have failed to boot too many times, and abandon auto-boot if so */ + if (boot_error_count(&boot_fail_count, &panic_fail_count) == 0) { + dprintf(DEBUG_CRITICAL, "Boot Failure Count: %u\tPanic Fail Count: %u\n", boot_fail_count, panic_fail_count); + if (false && (boot_fail_count >= 5)) { + dprintf(DEBUG_CRITICAL, "Too many boot failures, forcing recovery mode...\n"); + return; + } + } + + PROFILE(); + /* Wait for a user recover request if started */ + /* XXX should this be hoisted to common code? */ + while (recover_time && target_should_recover()) { + if (time_has_elapsed(recover_time, USER_BUTTON_RECOVER_TIMEOUT)) { + dprintf(DEBUG_INFO, "Force recovery mode....\n"); + return; + } + task_sleep(10 * 1000); + } + PROFILE(); + + /* handle auto-boot/bootcommand as legal for iBoot */ + do_common_autoboot(iboot_bootcommands); +} + +/* + * Auto-boot flow for iBEC. + */ +static void +do_ibec_autoboot(void) +{ + uint32_t boot_fail_count = 0, panic_fail_count = 0; + static struct autoboot_command ibec_bootcommands[] = { + {"upgrade", boot_upgrade_system}, + {NULL, NULL} + }; + + /* bring up mass storage devices */ + /* XXX this should be done lazily the first time we use it */ + dprintf(DEBUG_INFO, "initializing mass storage\n"); + platform_init_mass_storage(); + +#if WITH_HW_POWER + // At this point, NVRAM can be written. To prevent dark boot loops, clear out the dark boot flag + power_clear_dark_boot_flag(); +#endif + + /* Check whether we have failed to boot too many times, and abandon auto-boot if so */ + if (boot_error_count(&boot_fail_count, &panic_fail_count) == 0) { + dprintf(DEBUG_CRITICAL, "Boot Failure Count: %u\tPanic Fail Count: %u\n", boot_fail_count, panic_fail_count); + if (false && (boot_fail_count >= 5)) { + dprintf(DEBUG_CRITICAL, "Too many boot failures, forcing recovery mode...\n"); + return; + } + } + + /* handle auto-boot/bootcommand as legal for iBEC */ + do_common_autoboot(ibec_bootcommands); +} + +/* + * Common auto-boot check allowing for bootdelay abort. + */ +static bool +check_autoboot(bool autoboot, uint32_t bootdelay) +{ + /* see if we need to delay a bit on debug builds */ + if (autoboot) { + /* delay for a bit according to the bootdelay variable */ + utime_t t; + + printf("Delaying boot for %d seconds. Hit enter to break into the command prompt...\n", bootdelay); + t = system_time(); + while (1) { + int c = debug_getchar_nowait(); + + if (c == '\n' || c == '\r') { + printf("aborting autoboot due to user intervention.\n"); + autoboot = false; + break; + } + + if ((system_time()) - t > (bootdelay * 1000000)) + break; + + task_sleep(10 * 1000); + } + } + + return autoboot; +} + + +/* + * Common auto-boot flow. + */ +static void +do_common_autoboot(struct autoboot_command *cmds) +{ + bool autoboot; + int i; + + /* see if we should auto-boot or drop into the debugger */ + autoboot = env_get_bool("auto-boot", false); + + gDebugPromptTime = system_time(); + +#if WITH_HW_POWER + power_dark_boot_checkpoint(); +#endif + /* + * Handle auto-boot. + * + * Note that we only support a limited set of boot-command directives. Honouring + * an arbitrary command here could be abused by an attacker to perform arbitrary + * operations as part of an exploit. + */ + if (check_autoboot(autoboot, env_get_uint("bootdelay", 1))) { + const char *bootcommand = env_get("boot-command"); + + if (!bootcommand) { + dprintf(DEBUG_CRITICAL, "auto-boot set but no boot-command, aborting boot\n"); + return; + } + + /* XXX this should move */ + gLoadKernelTime = system_time(); + + /* compare found command with list of legal commands */ + for (i = 0; NULL != cmds[i].command; i++) { + if (!strcmp(bootcommand, cmds[i].command)) { +#if WITH_HW_POWER + power_dark_boot_checkpoint(); +#endif + cmds[i].func(); + + /* auto-boot failed, fall through to recovery mode */ + return; + } + } + dprintf(DEBUG_CRITICAL, "boot-command '%s' not supported\n", bootcommand); + } +} + +/* + * Do low-level init as the first component running after the ROM. + */ +static void +do_ll_init(void) +{ + PROFILE_ENTER('DLI'); + /* setup the default clock configuration */ + dprintf(DEBUG_INFO, "setting up initial clock configuration\n"); + platform_init_setup_clocks(); + + /* set up the default pin configuration */ + dprintf(DEBUG_INFO, "setting up default pin configuration\n"); + platform_init_hwpins(); + + /* set up any internal memory (internal sram) */ + dprintf(DEBUG_INFO, "setting up internal memory\n"); + platform_init_internal_mem(); + + PROFILE_EXIT('DLI'); +} + +/* + * Indicate to the user that we are trying to boot. + */ +static void +do_boot_ui(void) +{ +#if WITH_PAINT + PROFILE_ENTER('bUI'); +#if !PRODUCT_IBEC + // Don't enable remapping for iBEC because it will cause a + // "white flash" on white-faced units in restore mode. + // boot logo color remapping support for restore mode + paint_color_map_enable(paint_color_map_is_desired()); +#endif + paint_set_bgcolor(0, 0, 0); + paint_set_picture(0); + paint_set_picture_for_tag(IMAGE_TYPE_LOGO); + paint_update_image(); + PROFILE_EXIT('bUI'); +#endif +} + +/* + * Indicate to the user that we are entering recovery mode. + */ +static void +do_recoverymode_ui(void) +{ +#if WITH_PAINT + // XXX Restore team should decide how to refactor in terms + // of changes due to two-stage iBSS bootstrap. + paint_color_map_enable(false); + paint_set_bgcolor( 0, 0, 0); // Default to black background + paint_set_picture(0); + paint_set_picture_for_tag(IMAGE_TYPE_RECMODE); + paint_update_image(); +#endif /* WITH_PAINT */ + +#if WITH_HW_POWER + // Disable dark boot on recovery mode, so the user knows their device is dead. + // We don't have a trivial way of responding to button presses in this mode. + + // Note that our recovery graphics are black background so this shouldn't be + // overly irritating. + power_disable_dark_boot(); +#endif +} + +/* + * Explicit power-off detection (e.g. request_dfu1 (hold) button) + */ +static int +poweroff_task(void *arg) +{ + utime_t poweroff_time = 0; + + /* Require a break in the request to prevent confusion with poweron request */ + while (target_should_poweroff(false)) { + task_sleep(10 * 1000); + } + + /* Wait for poweroff request */ + while (1) { + if (target_should_poweroff(false)) { + if (poweroff_time == 0) + poweroff_time = system_time(); + else if (time_has_elapsed(poweroff_time, USER_BUTTON_POWEROFF_TIMEOUT)) { + dprintf(DEBUG_CRITICAL, "Force power off.\n"); + platform_quiesce_display(); + + /* Require a break in the request to prevent poweron */ + while (target_should_poweroff(false)) { + task_sleep(10 * 1000); + } + platform_poweroff(); + } + } else { + poweroff_time = 0; + } + + task_sleep(10 * 1000); + } + + return 0; +} + +/* + * Idle timeout power-off. + */ +#define NO_USB_IDLEOFF_TIMEOUT (30 * 1000 * 1000) +#define ACTIVITY_IDLEOFF_TIMEOUT (15 * 60 * 1000 * 1000) + +static int +idleoff_task(void *arg) +{ + utime_t usb_timeout = system_time(); + + while (!time_has_elapsed(gMenuLastActivityTime, ACTIVITY_IDLEOFF_TIMEOUT)) { + if (power_has_usb()) + usb_timeout = system_time(); + + if (time_has_elapsed(usb_timeout, NO_USB_IDLEOFF_TIMEOUT)) + break; + + task_sleep(1 * 1000 * 1000); + } + + dprintf(DEBUG_CRITICAL, "Idle power off.\n"); + + platform_poweroff(); + + return 0; +} + +#if RELEASE_BUILD +/* + * Environment variable whitelist for release builds. + * + * Only variables authorised by this routine may be set using setenv console command + */ +bool +env_blacklist(const char *name, bool write) +{ + int i; + + static const char * const release_env_set_whitelist[] = { + "auto-boot", + "boot-args", + "debug-uarts", +#if WITH_USB_DFU + "filesize", +#endif + "pwr-path", + NULL + }; + + /* selective setenv */ + if (write) { + for (i = 0; NULL != release_env_set_whitelist[i]; i++) + if (!strcmp(name, release_env_set_whitelist[i])) + return(false); + + /* variable is blacklisted */ + return(true); + } + + /* allow indiscriminate getenv */ + return(false); +} +#endif + +/* + * Environment variable NVRAM whitelist. + * + * Only variables authorized by this routine may be read from NVRAM using env_get + */ +bool +env_blacklist_nvram(const char *name) +{ + int i; + + static const char * const whitelist[] = { + // Most nvram variables should only be visible on debug builds. + // Put new variables here unless they're definitely needed in + // factory or customer scenarios +#if DEBUG_BUILD + "DClr_override", + "adbe-tunable", + "adbe-tunables", + "adfe-tunables", + "boot-device", + "boot-partition", + "boot-path", + "boot-ramdisk", + "boot-script", + "bt1addr", + "btaddr", + "cam-use-ext-ldo", + "core-bin-offset", + "cpu-bin-offset", + "debug-gg", + "debug-soc", + "display-color-space", + "display-timing", + "e75", + "enable-upgrade-fallback", + "eth1addr", + "ethaddr", + "fixed-lcm-boost", + "force-upgrade-fail", + "kaslr-off", + "kaslr-slide", + "loadaddr", + "pinot-panel-id", + "pintoaddr", + "rbdaddr0", + "soc-bin-offset", + "summit-panel-id", + "usb-enabled", + "wifi1addr", + "wifiaddr", +#endif + + // NVRAM variables needed in factory scenarios go here + +#if DEVELOPMENT_BUILD || DEBUG_BUILD + "auto-boot-usb", // probably just a debug thing, leaving here just in case + "boot-args", // factory needs to set boot-args + "bootdelay", // not sure if factory uses this, but shouldn't hurt + "diags-path", // not sure if factory uses this, but shouldn't hurt +#if WITH_DALI + "dali-pmu-debug", // needed for debugging dead units +#endif + +#endif + + // NVRAM variables needed in customer scenarios go here + + "auto-boot", // needed to boot the system + "backlight-level", + "boot-command", // needed for OTA updates + "com.apple.System.boot-nonce", +#if WITH_DALI + "dali-24h-mode", // used on watches for Dali mode +#endif + "debug-uarts", + "device-material", // used on watches for Dali mode + "display-rotation", // used on watches for wrist selection + "idle-off", // used by a few CoreAutomation scripts, leaving just in case + "is-tethered", // not sure if this is needed for stevenotes, leaving just in case + "darkboot", // Used for Sub-TLF: Dark Boot + "ota-breadcrumbs", // Used for appending to OTA failure tracing +#if WITH_DALI + "utc-offset", // used on watches for Dali mode +#endif + "pwr-path", // Disable debug power in N27a/N28a customer bundle + NULL + }; + +#if DEBUG_BUILD + // We'll also allow "quick access" commands on debug iBoot, as they'll never + // conflict with things we might do on release iBoot. + if (strlen(name) == 1) { + return false; + } +#endif + + for (i = 0; NULL != whitelist[i]; i++) + if (strcmp(name, whitelist[i]) == 0) + return(false); + + + /* variable is blacklisted */ + return(true); +} + +void +print_boot_banner(void) +{ +#if !WITH_BRIEF_BOOT_BANNER + dprintf(DEBUG_RELEASE, "\n\n=======================================\n"); + dprintf(DEBUG_RELEASE, "::\n"); + dprintf(DEBUG_RELEASE, ":: %s\n", build_banner_string); + dprintf(DEBUG_RELEASE, "::\n"); + dprintf(DEBUG_RELEASE, "::\tBUILD_TAG: %s\n", build_tag_string); + dprintf(DEBUG_RELEASE, "::\n"); +#if !DEBUG_BUILD + dprintf(DEBUG_RELEASE, "::\tBUILD_STYLE: %s\n", build_style_string); +#else + dprintf(DEBUG_RELEASE, "::\tBUILD_STYLE:\x1b[1;5;31m %s \x1b[m\n", build_style_string); +#endif + dprintf(DEBUG_RELEASE, "::\n"); + dprintf(DEBUG_RELEASE, "::\tUSB_SERIAL_NUMBER: %s\n", platform_get_usb_serial_number_string(false)); + dprintf(DEBUG_RELEASE, "::\n"); + dprintf(DEBUG_RELEASE, "=======================================\n\n"); +#else + dprintf(DEBUG_RELEASE, "\n%s for %s\n", CONFIG_PROGNAME_STRING, CONFIG_BOARD_STRING); + dprintf(DEBUG_RELEASE, "%s\n", build_tag_string); + dprintf(DEBUG_RELEASE, "%s\n\n", build_style_string); +#endif +} + +static volatile bool gDFUSuspend = false; +static volatile bool gDFURestart = false; + +static void check_enter_dfu(void) +{ + int result; + uint8_t enter_dfu; + + result = power_get_nvram(kPowerNVRAMiBootEnterDFUKey, &enter_dfu); + if ((result == 0) && (enter_dfu == kPowerNVRAMiBootEnterDFURequest)) { + /* acknowledge enter DFU trigger detected by clearing the request */ + power_set_nvram(kPowerNVRAMiBootEnterDFUKey, kPowerNVRAMiBootEnterDFUOff); + + dprintf(DEBUG_CRITICAL, "Entering DFU (NVRAM request)\n"); + main_dfu(); + } +} + +#if WITH_TICKET +static bool +dfu_parse_ticket(addr_t load_address, size_t load_length, addr_t *new_load_address, size_t *new_load_length) +{ + bool parsed = false; + const uint8_t * padding; + size_t padding_length; + size_t ticket_length; + size_t image_offset; + unsigned i; + + if (ticket_set((const uint8_t *) load_address, load_length, true, &ticket_length) == 0) { + + padding_length = ((ticket_length % 64) != 0) ? (64 - (ticket_length % 64)) : 0; + + /* ensure the padding is a byte string of 0xFF */ + padding = (const uint8_t *) load_address + ticket_length; + for (i = 0; i < padding_length; ++i) { + if (padding[i] != 0xFF) { + dprintf(DEBUG_INFO, "corrupt padding"); + goto exit; + } + } + + image_offset = ticket_length + padding_length; + } + else { + dprintf(DEBUG_INFO, "no valid ticket found"); + image_offset = 0; + } + + *new_load_address = load_address + image_offset; + *new_load_length = load_length - image_offset; + + parsed = true; + +exit: + return parsed; +} +#endif + +static bool +dfu_console_init(void) +{ + bool autoboot = true; + +#if !RELEASE_BUILD && WITH_MENU + /* if we've fallen into DFU mode with (uart-only) console + * enabled, enable uarts irregardless of what is specified in + * (default) environment; then, print the boot banner. + */ + debug_enable_uarts(3); + print_boot_banner(); + + /* if the user opts to abort autoboot, start the command + * prompt/parser. otherwise, return uarts to whatever + * is specified in (default) environment. + */ + if (!check_autoboot(autoboot, 3)) { + printf("Starting command prompt\n"); +#if defined(MENU_TASK_SIZE) + task_start(task_create("command", menu_task, NULL, MENU_TASK_SIZE)); +#else + task_start(task_create("command", menu_task, NULL, 0x1C00)); +#endif + dprintf(DEBUG_CRITICAL, "Use 'dfu' command to control normal DFU operation.\n"); + } else { + debug_enable_uarts(env_get_uint("debug-uarts", 0)); + } +#endif + + return autoboot; +} + +static addr_t +dfu_console_loadaddr(addr_t load_address) +{ +#if WITH_ENV + load_address = env_get_uint("loadaddr", load_address); +#endif + dprintf(DEBUG_CRITICAL, "Defaulting to address %p\n", (void *)load_address); + return load_address; +} + +static bool +dfu_console_loadctrl(addr_t load_address, size_t load_length) +{ + bool restart_transfer = false; + + dprintf(DEBUG_CRITICAL, "DFU image loaded: length %zu bytes; address %p\n", load_length, (void *)load_address); + + if (gDFUSuspend) { + dprintf(DEBUG_CRITICAL, "DFU suspended (use 'dfu resume' to continue)\n"); + while (gDFUSuspend) { + task_sleep(10 * 1000); + } + dprintf(DEBUG_CRITICAL, "DFU resumed\n"); + } + + if (gDFURestart) { + dprintf(DEBUG_CRITICAL, "DFU restarted\n"); + gDFURestart = false; + restart_transfer = true; + } + + return restart_transfer; +} + +static int +do_dfu_cmd(int argc, struct cmd_arg *args) +{ + int result = 0; + + if (argc != 2) { + result = -1; + } else { + const char* subcmd = args[1].str; + if (!strcmp(subcmd, "resume")) { + dprintf(DEBUG_CRITICAL, "resuming DFU\n"); + gDFUSuspend = false; + } else if (!strcmp(subcmd, "suspend")) { + dprintf(DEBUG_CRITICAL, "suspending DFU\n"); + gDFUSuspend = true; + } else if (!strcmp(subcmd, "restart")) { + dprintf(DEBUG_CRITICAL, "restarting DFU\n"); + gDFURestart = true; + } else if (!strcmp(subcmd, "status")) { + dprintf(DEBUG_CRITICAL, + "DFU status\n" + "\tsuspend\t%sabled\n" + "\trestart\t%sabled\n", + gDFUSuspend ? "en" : "dis", + gDFURestart ? "en" : "dis"); + gDFURestart = true; + } else { + result = -1; + } + } + + if (result < 0) + dprintf(DEBUG_CRITICAL, "Usage: dfu {suspend | resume | restart | status}\n"); + + return result; +} + +#if WITH_DFU_MODE +MENU_COMMAND_DEVELOPMENT(dfu, do_dfu_cmd, "control DFU operation", NULL); +#endif // WITH_DFU_MODE + +#if !RELEASE_BUILD +char *g_console_buffer; +size_t g_console_buffer_size; +size_t g_console_buffer_offset; +bool g_console_buffer_wrapped; +static bool g_console_buffer_paused; + +void application_putchar(int c) +{ + if (g_console_buffer != NULL && !g_console_buffer_paused && g_console_buffer_size > 1) { + enter_critical_section(); + + // Add character to the buffer + g_console_buffer[g_console_buffer_offset] = (char)c; + g_console_buffer_offset++; + + // Wrap 1 before the end of the buffer so that the + // pre-wrap buffer is always null-terminated + if (g_console_buffer_offset >= g_console_buffer_size - 1) { + g_console_buffer_offset = 0; + g_console_buffer_wrapped = true; + } + + // Add null terminator to make dumping easier + g_console_buffer[g_console_buffer_offset] = 0; + + exit_critical_section(); + } +} + +static void init_console_buffer(size_t size) +{ + g_console_buffer = calloc(size, 1); + g_console_buffer_size = size; +} + +static int do_dump_console(int argc, struct cmd_arg *args) +{ + + if (g_console_buffer != NULL) { + // Stop dumping to the console buffer so that + // we don't overwrite it with the dumped data + bool was_paused = g_console_buffer_paused; + g_console_buffer_paused = true; + + printf("console buffer at %p\n", g_console_buffer); + printf("offset 0x%zx\n", g_console_buffer_offset); + printf("size 0x%zx\n", g_console_buffer_size); + printf("wrapped %d\n", g_console_buffer_wrapped); + printf("\n\n-*-*-*-*-\n"); + + if (g_console_buffer_wrapped) { + printf("%s", g_console_buffer + g_console_buffer_offset + 1); + } + printf("%s\n-*-*-*-*-\n", g_console_buffer); + + g_console_buffer_paused = was_paused; + return 0; + } else { + printf("Console buffer not initialized\n"); + return -1; + } +} + +MENU_COMMAND_DEVELOPMENT(dump_console, do_dump_console, "dump console history", NULL); + +#else +void application_putchar(int c) +{ +} +#endif diff --git a/apps/iBoot/menu_commands.c b/apps/iBoot/menu_commands.c new file mode 100644 index 0000000..a558d51 --- /dev/null +++ b/apps/iBoot/menu_commands.c @@ -0,0 +1,594 @@ +/* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_MENU + +static int do_reset(int argc, struct cmd_arg *args) +{ + platform_quiesce_display(); + +#if WITH_HW_POWER + // Clear any pending PMU events + power_clr_events(1); +#endif + + platform_system_reset(false); + + return 0; +} + +static int do_halt(int argc, struct cmd_arg *args) +{ + halt(); +} + +MENU_COMMAND(reboot, do_reset, "reboot the device", NULL); +MENU_COMMAND(reset, do_reset, NULL, NULL); +MENU_COMMAND_DEVELOPMENT(halt, do_halt, "halt the system (good for JTAG)", NULL); + +static int do_poweroff(int argc, struct cmd_arg *args) +{ + platform_poweroff(); + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(poweroff, do_poweroff, "power off the device", NULL); + +#if defined(WITH_TFTP) +static int do_eload(int argc, struct cmd_arg *args) +{ + char cmdbuf[128]; + + if (argc != 2) { + printf("wrong number of args.\n"); + printf("%s \n", args[0].str); + return(-1); + } + + env_set("serverip", "17.202.24.178", 0); + + snprintf(cmdbuf, 128, "tftp getscript scripts/%s/%s.%s\n", + CONFIG_PROGNAME_STRING, + args[1].str, + CONFIG_BOARD_STRING); + + debug_run_script(cmdbuf); + return(0); +} + +MENU_COMMAND_DEVELOPMENT(eload, do_eload, "tftp via ethernet from hardcoded install server", NULL); +#endif /* WITH_TFTP */ + +#if !WITH_SIMPLE_MENU +struct memory_region_t +{ + memory_region_type_t type; + const char *name; +}; + +static const struct memory_region_t memory_regions[] = +{ + { kMemoryRegion_StorageProcessor,"Storage Processor" }, + { kMemoryRegion_ConsistentDebug, "Consistent Debug" }, + { kMemoryRegion_SleepToken, "Sleep Token" }, + { kMemoryRegion_DramConfig, "DRAM Config" }, + { kMemoryRegion_Panic, "Panic" }, + { kMemoryRegion_Display, "Display" }, + { kMemoryRegion_Heap, "Heap" }, + { kMemoryRegion_Stacks, "Stacks" }, + { kMemoryRegion_PageTables, "Page Tables" }, + { kMemoryRegion_iBoot, "iBoot" }, + { kMemoryRegion_Kernel, "Kernel" }, + { kMemoryRegion_Monitor, "Monitor" }, + { kMemoryRegion_SecureProcessor, "Secure Processor" }, + { kMemoryRegion_AOP, "AOP" }, + { kMemoryRegion_Reconfig, "Reconfig" }, +}; + +void display_physical_memory_regions(bool final) +{ + unsigned int i; + uintptr_t base; + uintptr_t end; + size_t size; + + printf("Physical Region Start End Size\n"); + // "xxxxxxxxxxxxxxxxxxx 0x123456789 0x123456789 0x123456789 + + for (i = 0; i < ARRAY_SIZE(memory_regions); ++i) { + base = platform_get_memory_region_base_optional(memory_regions[i].type); + size = platform_get_memory_region_size_optional(memory_regions[i].type); + + if ((base == (uintptr_t)-1) || (size == (size_t)-1)) { + continue; + } + + end = base + size - 1; + printf("%-19s 0x%09llx 0x%09llx 0x%09zx\n", + memory_regions[i].name, (uint64_t)base, (uint64_t)end, size); + } +} + +static int do_regions(int argc, struct cmd_arg *args) +{ + if (ARRAY_SIZE(memory_regions) != kMemoryRegion_NumberOfRegions) { + panic("memory region list mismatch"); + } + + display_physical_memory_regions(false); + return 0; +} + +MENU_COMMAND_DEVELOPMENT(regions, do_regions, "show physical memory region allocations", NULL); +#endif // !WITH_SIMPLE_MENU + +static int do_echo(int argc, struct cmd_arg *args) +{ + int i; + + for (i = 1; i < argc; i++) + printf("%s ",args[i].str); + printf("\n"); + + return(0); +} + +MENU_COMMAND_DEVELOPMENT(echo, do_echo, NULL, NULL); + +#if WITH_PAINT +/* set the background color on the display */ +static int do_bgcolor(int argc, struct cmd_arg *args) +{ + if (argc != 4) { +#if !RELEASE_BUILD + printf("wrong number of args.\n"); + printf("%s \n", args[0].str); +#endif + return -1; + } + + paint_set_bgcolor(args[1].u, args[2].u, args[3].u); + paint_update_image(); + + return 0; +} + +/* This command is not used by release products other than those allowed to perform restore boot. */ +#if WITH_RECOVERY_MODE && (!RELEASE_BUILD || WITH_RESTORE_BOOT) +MENU_COMMAND(bgcolor, do_bgcolor, "set the display background color", NULL); +#endif + +/* set the image on the display */ +static int do_setpict(int argc, struct cmd_arg *args) +{ + struct image_info *image; + int update = 0; + int blank = 1; + int restore = 0; + int result; + addr_t addr = DEFAULT_LOAD_ADDRESS; + size_t size; + + size = env_get_uint("filesize", 0x00100000); + +#if !RELEASE_BUILD + if (argc < 2) { + printf("wrong number of args.\n"); + printf("%s optbitmask [ []]\n", args[0].str); + printf("optbitmask:\n"); + printf(" 0x01 = update the image on screen\n"); + printf(" 0x02 = don't clear previous images\n"); + printf(" 0x04 = restore mode image\n"); + return -1; + } + + addr = env_get_uint("loadaddr", addr); + + update = (args[1].u & 1) != 0; + blank = (args[1].u & 2) == 0; + if (argc >= 3) + addr = args[2].u; + if (argc >= 4) + size = args[3].u; +#endif + + if (argc >= 2) { + restore = (args[1].u & 4) != 0; + } + + if (size > 0x00100000) { + printf("picture too large, size:%zu\n", size); + return -1; + } + + if (!security_allow_memory((void *)addr, size)) { + printf("Permission Denied\n"); + return -1; + } + + image = image_create_from_memory((void *)addr, size, 0); + if (image == 0) { + printf("Memory image corrupt\n"); + return -1; + } + + if (blank) { + result = paint_set_picture(0); + } + + result = paint_set_picture(image); + + // If this is a restore image, color remapping will have been disabled + // when we dropped into recovery mode. Make sure the color remapping is + // set to the policy desired by the device. + if (restore) { + paint_color_map_enable(paint_color_map_is_desired()); + } + + if ((update != 0) && (result == 0)) result = paint_update_image(); + + return result; +} + +/* This command is not used by release products other than those allowed to perform restore boot. */ +#if WITH_RECOVERY_MODE && (!RELEASE_BUILD || WITH_RESTORE_BOOT) +MENU_COMMAND(setpicture, do_setpict, "set the image on the display", NULL); +#endif + +/* XXX move to the paint module */ +/* test the display */ +static int do_displaytest(int argc, struct cmd_arg *args) +{ + paint_displaytest(); + + return 0; +} + +#if WITH_RECOVERY_MODE +MENU_COMMAND_DEBUG(displaytest, do_displaytest, "test the display", NULL); +#endif + +/* Enable/Disable color remapping */ +static int do_remapcolor(int argc, struct cmd_arg *args) +{ + bool old_state; + bool new_state; + + if ((argc == 2) && !strcmp(args[1].str, "on")) { + new_state = true; + } else if ((argc == 2) && !strcmp(args[1].str, "off")) { + new_state = false; + } else if ((argc == 2) && !strcmp(args[1].str, "desired")) { + new_state = paint_color_map_is_desired(); + } else { + printf("usage: %s on|off|desired\n", args[0].str); + return -1; + } + + old_state = paint_color_map_enable(new_state); + + if (new_state && (paint_color_map_is_enabled() != new_state)) { + printf("Color remapping not supported for this target\n"); + return -1; + } + if (old_state != new_state) { + paint_update_image(); + } + + return 0; +} + +#if WITH_RECOVERY_MODE +MENU_COMMAND_DEBUG(remapcolor, do_remapcolor, "enable/disable color remap", NULL); +#endif + +#endif /* WITH_PAINT */ + +static int do_display(int argc, struct cmd_arg *args) +{ + if ((argc == 2) && !strcmp(args[1].str, "on")) { + return platform_init_display(); + } else if ((argc == 2) && !strcmp(args[1].str, "off")) { + return platform_quiesce_display(); + } else { + printf("usage: %s on|off\n", args[0].str); + return -1; + } +} + +#if WITH_RECOVERY_MODE +MENU_COMMAND_DEBUG(display, do_display, "enable/disable display", NULL); +#endif + +#if DEBUG_BUILD + +#define kCommandLineSize (256) +#define kMaxEntropyRadio (1000) + +static int do_random(int argc, struct cmd_arg *args) +{ + int ret; + char *command_line = NULL; + u_int8_t *buffer; + u_int32_t save_data, length; + u_int32_t entropy_ratio, sweep; + utime_t start_time, end_time, delta_time; + + if (argc < 2) { + dprintf(DEBUG_CRITICAL, "too few arguments\n"); + dprintf(DEBUG_CRITICAL, "usage: %s save_data? [entropy_ratio [ []]]\n", args[0].str); + + return -1; + } + + save_data = args[1].u; + + entropy_ratio = PLATFORM_ENTROPY_RATIO; + if (argc >= 3) + entropy_ratio = args[2].u; + if (entropy_ratio >= kMaxEntropyRadio) + entropy_ratio = kMaxEntropyRadio; + sweep = entropy_ratio; + if (entropy_ratio == 0) { + entropy_ratio = 1; + sweep = kMaxEntropyRadio; + } + + length = 1024 * 1024; + if (argc >= 4) + length = args[3].u; + + buffer = (u_int8_t *)env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + if (argc >= 5) + buffer = (u_int8_t *)args[4].u; + + if (!security_allow_memory(buffer, length)) { + printf("Permission Denied\n"); + return -1; + } + + if (save_data) { + command_line = malloc(kCommandLineSize); + } + + while (entropy_ratio <= sweep) { + dprintf(DEBUG_CRITICAL, "Generating random numbers with entropy ratio %u at %p of length 0x%08x", entropy_ratio, buffer, length); + + start_time = system_time(); + random_get_bytes_debug(buffer, length, entropy_ratio); + end_time = system_time(); + delta_time = end_time - start_time; + + dprintf(DEBUG_CRITICAL, " in %lld.%lldus/byte\n", delta_time / length, ((delta_time * 10) / length) % 10); + + if (save_data) { + snprintf(command_line, kCommandLineSize, + "usb put /tmp/random-%s-%d.bin 0x%08x\n", + CONFIG_BOARD_STRING, entropy_ratio, length); + + process_command_line(command_line, &ret); + } + + entropy_ratio *= 2; + } + + if (save_data) { + free(command_line); + } + + return 0; +} + +MENU_COMMAND_DEBUG(random, do_random, "generate random data", NULL); + +#endif /* DEBUG_BUILD */ + +// ***************************************************************************** +// Miscellaneous commands whose function bodies live in libraries +// ***************************************************************************** + +// ----------------------------------------------------------------------------- +// Block device commands +// ----------------------------------------------------------------------------- + +#if WITH_BLOCKDEV +MENU_COMMAND_DEBUG(bdev, do_blockdev, "block device commands", NULL); +#endif + +// ----------------------------------------------------------------------------- +// Checksum commands +// ----------------------------------------------------------------------------- + +#if WITH_CKSUM && !WITH_SIMPLE_MENU +MENU_COMMAND_DEVELOPMENT(crc, do_crc, "POSIX 1003.2 checksum of specified memory address range.", NULL); +#endif + +// ----------------------------------------------------------------------------- +// Devicetree commands +// ----------------------------------------------------------------------------- + +/* This command is not used by the release iBoot application iBoot product */ +#if !RELEASE_BUILD || !APPLICATION_IBOOT || !PRODUCT_IBOOT +int do_devicetree(int argc, struct cmd_arg *argv); +static int do_devicetree_wrapper(int argc, struct cmd_arg *argv) +{ + int result; + + PROFILE_ENTER('Dtr'); + result = do_devicetree(argc, argv); + PROFILE_EXIT('Dtr'); + return result; +} + +MENU_COMMAND(devicetree, do_devicetree_wrapper, "create a device tree from the specified address", NULL); +#endif + +#if WITH_DEVICETREE +void dump_tree_int(dt_node_t *node, int indent, bool verbose); +static int do_dump_tree(int argc, struct cmd_arg *args) +{ + dt_node_t *node; + + if (dt_get_size() == 0) { + printf("no devicetree loaded\n"); + return -1; + } + + if (argc == 2) { + printf("Looking for node \"%s\"\n", args[1].str); + if (!dt_find_node(0, args[1].str, &node)) { + printf("node not found\n"); + return -1; + } + } else { + node = dt_get_root(); + } + + dump_tree_int(node, 0, false); + + return 0; +} + +MENU_COMMAND_DEBUG(dtdump, do_dump_tree, "dump devicetree", NULL); +#endif + +// ----------------------------------------------------------------------------- +// File system commands +// ----------------------------------------------------------------------------- + +#if WITH_FS +MENU_COMMAND_DEVELOPMENT(fs, do_fs, "file system commands", NULL); +#endif + +// ----------------------------------------------------------------------------- +// Environment variable commands +// ----------------------------------------------------------------------------- + +#if WITH_ENV + +int do_saveenv(int argc, struct cmd_arg *args) +{ +#if WITH_NVRAM + return nvram_save(); +#else + dprintf(DEBUG_CRITICAL, "WARNING: with no NVRAM storage available, 'saveenv' has no effect\n"); + return 0; +#endif +} + +MENU_COMMAND_DEVELOPMENT(clearenv, do_clearenv, "clear all environment variables", NULL); +MENU_COMMAND_DEVELOPMENT(printenv, do_printenv, "print one or all environment variables", NULL); +MENU_COMMAND(getenv, do_getenv, "get environment variable over usb", NULL); +MENU_COMMAND(saveenv, do_saveenv, "save current environment to flash", NULL); +MENU_COMMAND(setenv, do_setenv, "set an environment variable", NULL); +MENU_COMMAND_DEBUG(envprot, do_envprot, "enable/disable NVRAM whitelist", NULL); +#endif + +// ----------------------------------------------------------------------------- +// Heap commands +// ----------------------------------------------------------------------------- + +MENU_COMMAND_DEBUG(malloc, do_malloc, "examine the system heap", NULL); + +// ----------------------------------------------------------------------------- +// Module Information Base (MIB) commands +// ----------------------------------------------------------------------------- + +#if !WITH_SIMPLE_MENU +MENU_COMMAND_DEVELOPMENT(mib, do_mib, "dump the MIB", NULL); +#endif + +// ----------------------------------------------------------------------------- +// Nonce commands +// ----------------------------------------------------------------------------- + +MENU_COMMAND_DEBUG(nonce, do_nonce, "nonce utilities", NULL); + +// ----------------------------------------------------------------------------- +// RAMDISK commands +// ----------------------------------------------------------------------------- + +/* This command is not used by release products other than those allowed to perform restore boot. */ +#if WITH_RAMDISK && (!RELEASE_BUILD || WITH_RESTORE_BOOT) + +int do_ramdisk(int argc, struct cmd_arg *argv); +static int do_ramdisk_wrapper(int argc, struct cmd_arg *argv) +{ + int result; + + PROFILE_ENTER('RDk'); + result = do_ramdisk(argc, argv); + + PROFILE_EXIT('RDk'); + return result; +} + +MENU_COMMAND(ramdisk, do_ramdisk_wrapper, "create a ramdisk from the specified address", NULL); +#endif + +// ----------------------------------------------------------------------------- +// Syscfg commands +// ----------------------------------------------------------------------------- + +#if WITH_SYSCFG +MENU_COMMAND_DEVELOPMENT(syscfg, do_syscfg, "flash SysCfg inspection", NULL); +#endif + +// ----------------------------------------------------------------------------- +// Ticket commands +// ----------------------------------------------------------------------------- + +#if WITH_TICKET +MENU_COMMAND( ticket, do_ticket, "", NULL ); +#if WITH_FS +MENU_COMMAND_DEBUG( ticketfile, do_ticket_file, "load ticket from file", NULL ); +#endif +MENU_COMMAND_DEBUG( ticketdump, do_ticket_dump, "", NULL ); +MENU_COMMAND_DEBUG( ticketload, do_ticket_load, "", NULL ); +#endif + +#if WITH_PAINT +static int do_paint_info(int argc, struct cmd_arg *args) +{ + + if (argc == 1) { + display_paint_information(); + } else { + if (!strcmp("canvas", args[1].str)) { + display_paint_canvas(); + } else if (!strcmp("plane", args[1].str)) { + uint32_t plane = args[2].u; + display_paint_plane(plane); + } + } + return 0; +} + +MENU_COMMAND_DEBUG(paintinfo, do_paint_info, "Display Paint related information", NULL); +#endif + +#endif /* WITH_MENU */ diff --git a/apps/iBoot/products.mk b/apps/iBoot/products.mk new file mode 100644 index 0000000..dd6e1fe --- /dev/null +++ b/apps/iBoot/products.mk @@ -0,0 +1,107 @@ +# Copyright (C) 2010-2011, 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +# +# Derivation of MODULES based on PRODUCT. +# +# This file should contain NO target-specific knowledge. +# + +# +# Always build 'basic' modules. +# +MODULES += $(MODULES_BASIC) + + +################################################################################ +# +# iBoot +# +ifeq ($(PRODUCT),iBoot) + +TEXT_BANK := sdram +OPTIONS += $(OPTIONS_RECOVERY) $(OPTIONS_BOOT) $(OPTIONS_FILESYSTEM) $(OPTIONS_RESTORE_STRAP) +MODULES += $(MODULES_RECOVERY) $(MODULES_BOOT) $(MODULES_FILESYSTEM) $(MODULES_DISPLAY) + +endif # iBoot + + +################################################################################ +# +# iBEC +# +ifeq ($(PRODUCT),iBEC) + +TEXT_BANK := sdram +OPTIONS += $(OPTIONS_RECOVERY) $(OPTIONS_BOOT) $(OPTIONS_FILESYSTEM) $(OPTIONS_RESTORE_BOOT) +MODULES += $(MODULES_RECOVERY) $(MODULES_BOOT) $(MODULES_FILESYSTEM) + +endif # iBEC + + +################################################################################ +# +# iBSS +# +ifeq ($(PRODUCT),iBSS) + +TEXT_BANK := sram +ifneq ($(RECOVERY_MODE_IBSS),true) +OPTIONS += $(OPTIONS_DFU) $(OPTIONS_RESTORE_STRAP) +MODULES += $(MODULES_DFU) + +# +# It is also possible, for development or triage purposes, to rebuild +# iBSS with uart-only console support by changing NEVER below to DEBUG; +# however, do NOT submit such a change to trunk. +# +ifeq ($(BUILD),NEVER) +OPTIONS += $(OPTIONS_CONSOLE) +MODULES += $(MODULES_CONSOLE) +endif + +else # RECOVERY_MODE_IBSS is true + +# Dongle products get an iBSS with all of iBoot's recovery mode accroutements, +# EXCEPT for filesystem support +OPTIONS += $(OPTIONS_RECOVERY) $(OPTIONS_BOOT) $(OPTIONS_RESTORE_BOOT) +MODULES += $(MODULES_RECOVERY) $(MODULES_BOOT) + +endif # RECOVERY_MODE_IBSS + +endif # iBSS + + +################################################################################ +# +# LLB +# +ifeq ($(PRODUCT),LLB) + +TEXT_BANK := sram +OPTIONS += $(OPTIONS_DFU) $(OPTIONS_RESTORE_STRAP) +MODULES += $(MODULES_DFU) $(MODULES_FIRMWARE) + +# +# It is also possible, for development or triage purposes, to rebuild +# LLB with uart-only console support by changing NEVER below to DEBUG; +# however, do NOT submit such a change to trunk. +# +# This is intentionally of considerably less utility than the iBSS +# variant of the DFU-mode console since it only becomes available to +# break into if iBoot firmware image load/boot fails and the unit +# falls over into DFU mode. +# +ifeq ($(BUILD),NEVER) +OPTIONS += $(OPTIONS_CONSOLE) +MODULES += $(MODULES_CONSOLE) +endif + +endif # LLB diff --git a/apps/iBoot/upgrade.c b/apps/iBoot/upgrade.c new file mode 100644 index 0000000..151df27 --- /dev/null +++ b/apps/iBoot/upgrade.c @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Upgrade dependencies. + */ +#if WITH_FS && WITH_MACHO && WITH_DEVICETREE && WITH_ENV + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Support for the 'upgrade' workflow. + */ + +static int mount_upgradefs(void); + +static int mount_upgrade_partition(void); + +extern void boot_darwin(void *ptr, void *arg) __noreturn; + +#define FORCE_FAIL_AT_IBOOT (1) +#define FORCE_FAIL_AT_IBEC (1<<1) + +#ifndef UPGRADE_PARTITION +# define UPGRADE_PARTITION "2" +#endif +#ifndef UPGRADE_TICKET +# define UPGRADE_TICKET "/boot/apticket.der" +#endif +#ifndef UPGRADE_LOADER +# define UPGRADE_LOADER "/boot/iBEC" +#endif +#ifndef UPGRADE_KERNELCACHE +# define UPGRADE_KERNELCACHE "/boot/kernelcache" +#endif +#ifndef UPGRADE_RAMDISK +# define UPGRADE_RAMDISK "/boot/ramdisk" +#endif +#ifndef UPGRADE_DEVICETREE +# define UPGRADE_DEVICETREE "/boot/devicetree" +#endif +#ifndef UPGRADE_PICTURE +# define UPGRADE_PICTURE "/boot/applelogo" +#endif +#ifndef UPGRADE_BOOTARGS +# define UPGRADE_BOOTARGS " rd=md0 nand-enable-reformat=1 -progress" +#endif + + +static bool upgrade_fallback_recovery() +{ +#if RELEASE_BUILD + return true; +#else + return env_get_bool("enable-upgrade-fallback", false); +#endif +} + +static void stash_failure_reason(const char* ota_result, const char* ota_failure_reason) +{ + dprintf(DEBUG_CRITICAL, "Recording upgrade failure:\n ota-result: %s\n ota-failure-reason: %s\n", ota_result, ota_failure_reason); + env_set("ota-result", ota_result, ENV_PERSISTENT); + env_set("ota-failure-reason", ota_failure_reason, ENV_PERSISTENT); + nvram_save(); + + platform_commit_breadcrumbs("ota-breadcrumbs"); +} + +/* + * Mount the upgrade partition, check for iBEC and launch it if found. + */ +int +mount_and_upgrade_system(void) +{ + addr_t addr; + size_t len; + uint32_t type, options; + + addr = DEFAULT_KERNEL_ADDRESS; + len = DEFAULT_KERNEL_SIZE; + + char* upgrade_fail_reason = ""; + +#if !RELEASE_BUILD + if (env_get_uint("force-upgrade-fail", 0) & FORCE_FAIL_AT_IBOOT) + { + upgrade_fail_reason = "simulated failure via force-upgrade-fail"; + dprintf(DEBUG_CRITICAL, "force-upgrade-fail is set. Simulating upgrade failure.\n"); + goto fail; + } +#endif + + if (mount_upgrade_partition()) { + upgrade_fail_reason = "failed to mount upgrade partition"; + dprintf(DEBUG_CRITICAL, "failed to mount upgrade partition\n"); + goto fail; + } + +#if WITH_TICKET + if (ticket_load_file(UPGRADE_TICKET, DEFAULT_LOAD_ADDRESS, DEFAULT_LOAD_SIZE)) { + dprintf(DEBUG_INFO, "WARNING: failed to load ticket %s\n", UPGRADE_TICKET); + } +#endif + + /* image epoch must be greater than or equal to the current stage's epoch */ + /* Recovery mode restore: iBoot -> iBEC hand-off. Let image library enforce whatever policies it cares about. */ + options = IMAGE_OPTION_GREATER_EPOCH | IMAGE_OPTION_NEW_TRUST_CHAIN; + + /* try to load the iBEC from it */ + type = IMAGE_TYPE_IBEC; + if (image_load_file(UPGRADE_LOADER, &addr, &len, &type, 1, NULL, options)) { + upgrade_fail_reason = "failed to load upgrade iBEC"; + dprintf(DEBUG_CRITICAL, "could not load %s", UPGRADE_LOADER); + goto fail; + } + + /* consolidate environment */ + security_consolidate_environment(); + +#if WITH_SIDP + /* Always seal the manifest that authorizes iBEC. */ + security_sidp_seal_boot_manifest(true); +#endif + + /* start it */ + prepare_and_jump(BOOT_IBOOT, (void *)addr, NULL); + + panic("%s returned", UPGRADE_LOADER); +fail: + /* Stash away the reason why the upgrade failed */ + stash_failure_reason("failed to execute upgrade command from iBoot", upgrade_fail_reason); + + if (upgrade_fallback_recovery()) { + // On a release build, fall back to booting the OS off NAND if the upgrade fails. As long as + // we didn't boot into Restore OS, the old OS can still recover itself and save the customer + // from being trapped in Recovery Mode. + // + + dprintf(DEBUG_CRITICAL, "Upgrade failed, requesting reboot into old OS...\n"); + env_unset("boot-command"); + nvram_save(); + platform_system_reset(false); + } + + return(-1); +} + +/* + * Boot from the upgrade partition. + */ +int +boot_upgrade_system(void) +{ + addr_t entry; + addr_t boot_args; + + const char* upgrade_fail_reason = "unknown"; + + if (upgrade_fallback_recovery()) { + // On a release build, fall back to booting the OS off NAND if the upgrade fails. As long as + // we didn't boot into Restore OS, the old OS can still recover itself and save the customer + // from being trapped in Recovery Mode. + // + + env_unset("boot-command"); + nvram_save(); + } else { + // For internal users, we want to capture units that failed to boot into the upgrade environment. + // Clear auto-boot to trap them into recovery mode. + env_set("auto-boot", "false", ENV_PERSISTENT); + nvram_save(); + } + + /* for release builds, the presence of a ramdisk forces suitable boot-args */ +#ifndef RELEASE_BUILD + { + const char *bootargs; + char *newbootargs; + size_t nbaSize; + + /* respect existing boot-args */ + if (NULL == (bootargs = env_get("boot-args"))) + bootargs = ""; + nbaSize = strlen(bootargs) + strlen(UPGRADE_BOOTARGS) + 1; + newbootargs = malloc(nbaSize); + + snprintf(newbootargs, nbaSize, "%s%s", bootargs, UPGRADE_BOOTARGS); + env_set("boot-args", newbootargs, 0); + dprintf(DEBUG_INFO, "set boot-args %s\n", newbootargs); + free(newbootargs); + } +#endif + + /* mount the upgrade filesystem */ + if (mount_upgrade_partition()) { + upgrade_fail_reason = "failed to mount upgrade partition"; + dprintf(DEBUG_CRITICAL, "failed to mount upgrade partition\n"); + // No need for additional breadcrumb here -- mount_upgrade_partition already + // breadcrumbs every failure path. + goto fail; + } + +#if WITH_TICKET + if (ticket_load_file(UPGRADE_TICKET, DEFAULT_LOAD_ADDRESS, DEFAULT_LOAD_SIZE)) { + dprintf(DEBUG_INFO, "WARNING: failed to load ticket %s\n", UPGRADE_TICKET); + } +#endif + +#if WITH_PAINT + /* + * If there's been an epoch change between the original bootloader and + * us running as iBEC from the upgrade partition, the Apple logo in + * the firmware space will not have been displayed. Try to grab one + * from the upgrade partition. + * + * It's OK for this to fail - the system may not support images. + */ + paint_set_picture_from_file(UPGRADE_PICTURE, IMAGE_TYPE_LOGO); +#endif + + /* load the devicetree */ + if (dt_load_file(UPGRADE_DEVICETREE)) { + upgrade_fail_reason = "failed to load devicetree"; + dprintf(DEBUG_CRITICAL, "failed to load devicetree\n"); + goto fail; + } + + /* load the ramdisk */ + if (load_ramdisk_file(UPGRADE_RAMDISK)) { + upgrade_fail_reason = "failed to load ramdisk"; + dprintf(DEBUG_CRITICAL, "failed to load ramdisk\n"); + goto fail; + } + + /* load the kernelcache */ +#if WITH_IMAGE4 + if (load_kernelcache_file(UPGRADE_KERNELCACHE, IMAGE_TYPE_KERNELCACHE_RESTORE, &entry, &boot_args)) +#else + if (load_kernelcache_file(UPGRADE_KERNELCACHE, IMAGE_TYPE_KERNELCACHE, &entry, &boot_args)) +#endif + { + upgrade_fail_reason = "failed to load kernelcache"; + dprintf(DEBUG_CRITICAL, "failed to load kernelcache\n"); + goto fail; + } + +#if !RELEASE_BUILD + if (env_get_uint("force-upgrade-fail", 0) & FORCE_FAIL_AT_IBEC) + { + upgrade_fail_reason = "simulated failure via force-upgrade-fail"; + dprintf(DEBUG_CRITICAL, "force-upgrade-fail is set. Simulating upgrade failure.\n"); + goto fail; + } +#endif + + /* boot the kernel */ + dprintf(DEBUG_INFO, "booting upgrade kernel\n"); + boot_darwin((void *)entry, (void *)boot_args); + + panic("upgrade kernel returned"); + +fail: + fs_unmount(UPGRADE_PARTITION); /* harmless if mount failed */ + + /* Stash away the reason why the upgrade failed */ + stash_failure_reason("failed to execute upgrade command from new iBEC", upgrade_fail_reason); + + if (upgrade_fallback_recovery()) { + // For customer scenarios, reboot here. Since auto-boot will still be set and + // the boot-command was cleared (to fsboot), we should attempt to reboot the original OS. + dprintf(DEBUG_CRITICAL,"Upgrade command failed. Stashed failure details and requesting reboot\n"); + platform_system_reset(false); + } + + /* return an error here so that we fall back into recovery mode */ + return(-1); +} + +static int +mount_upgrade_partition(void) +{ + const char *device_name = NULL; + + /* + * Iterate over the published blockdevs, seeking the device marked as the + * upgrade partition, then mount it so the system can boot from it. + */ + for (struct blockdev *dev = first_blockdev(); dev != NULL; dev = next_blockdev(dev)) { + if (dev->flags & BLOCKDEV_FLAG_UPGRADE_PARTITION) { + device_name = dev->name; + break; + } + } + + if (device_name == NULL) { + dprintf(DEBUG_CRITICAL, "could not locate upgrade partition\n"); + platform_record_breadcrumb("mount_upgrade_partition", "!device_name"); + + return -1; + } + + dprintf(DEBUG_INFO, "mounting upgrade partition from device '%s'\n", device_name); + if (mount_bootfs_from_device(device_name)) { + dprintf(DEBUG_CRITICAL, "failed to mount upgrade partition"); + platform_record_breadcrumb("mount_upgrade_partition", "mount-failed"); + + return -1; + } + + return 0; +} + +#endif /* WITH_FS etc. */ diff --git a/arch/arm/asm.S b/arch/arm/asm.S new file mode 100644 index 0000000..bff12b6 --- /dev/null +++ b/arch/arm/asm.S @@ -0,0 +1,627 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + + .text + +#define ALL_ROUTINES 1 + +// Define isb as a nop for older architectures +#if !ARCH_ARMv7 +#define isb nop +#define dsb nop +#endif /* ! ARCH_ARMv7 */ + +ARM_FUNCTION _arm_read_cpsr + + mrs r0, cpsr + bx lr + +#if ALL_ROUTINES +ARM_FUNCTION _arm_read_main_id + + mrc p15, 0, r0, c0, c0, 0 + bx lr +#endif + +#if ALL_ROUTINES +ARM_FUNCTION _arm_read_cache_id + + mrc p15, 0, r0, c0, c0, 1 + bx lr + +ARM_FUNCTION _arm_read_cache_level_id + + mrc p15, 1, r0, c0, c0, 1 + bx lr + +ARM_FUNCTION _arm_read_cache_size_selection + + mrc p15, 2, r0, c0, c0, 0 + bx lr + +ARM_FUNCTION _arm_write_cache_size_selection + + mcr p15, 2, r0, c0, c0, 0 + isb + bx lr + +ARM_FUNCTION _arm_read_cache_size_id + + mrc p15, 1, r0, c0, c0, 0 + bx lr +#endif + +#if ALL_ROUTINES +ARM_FUNCTION _arm_read_extended_feature_regs + + mov r12, r0 + mrc p15, 0, r0, c0, c1, 0 + mrc p15, 0, r1, c0, c1, 1 + mrc p15, 0, r2, c0, c1, 2 + mrc p15, 0, r3, c0, c1, 3 + stmia r12!, { r0-r3 } + mrc p15, 0, r0, c0, c1, 4 + mrc p15, 0, r1, c0, c1, 5 + mrc p15, 0, r2, c0, c1, 6 + mrc p15, 0, r3, c0, c1, 7 + stmia r12!, { r0-r3 } + mrc p15, 0, r0, c0, c2, 0 + mrc p15, 0, r1, c0, c2, 1 + mrc p15, 0, r2, c0, c2, 2 + mrc p15, 0, r3, c0, c2, 3 + stmia r12!, { r0-r3 } + mrc p15, 0, r0, c0, c2, 4 + mrc p15, 0, r1, c0, c2, 5 + mrc p15, 0, r2, c0, c2, 6 + mrc p15, 0, r3, c0, c2, 7 + stmia r12, { r0-r3 } + bx lr +#endif + +#if ALL_ROUTINES +ARM_FUNCTION _arm_read_memory_model_feature_regs + + mov r12, r0 + mrc p15, 0, r0, c0, c1, 4 + mrc p15, 0, r1, c0, c1, 5 + mrc p15, 0, r2, c0, c1, 6 + mrc p15, 0, r3, c0, c1, 7 + stmia r12, { r0-r3 } + bx lr +#endif + +#if ALL_ROUTINES +ARM_FUNCTION _arm_read_instruction_set_attribute_regs + + mov r12, r0 + mrc p15, 0, r0, c0, c2, 0 + mrc p15, 0, r1, c0, c2, 1 + mrc p15, 0, r2, c0, c2, 2 + mrc p15, 0, r3, c0, c2, 3 + stmia r12!, { r0-r3 } + mrc p15, 0, r0, c0, c2, 4 + mrc p15, 0, r1, c0, c2, 5 + stmia r12!, { r0-r1 } + bx lr +#endif + +ARM_FUNCTION _arm_read_cr + + mrc p15, 0, r0, c1, c0, 0 + bx lr + +ARM_FUNCTION _arm_write_cr + + mcr p15, 0, r0, c1, c0, 0 + isb + bx lr + +ARM_FUNCTION _arm_read_aux_cr + + mrc p15, 0, r0, c1, c0, 1 + bx lr + +ARM_FUNCTION _arm_write_aux_cr + + mcr p15, 0, r0, c1, c0, 1 + isb + bx lr + +ARM_FUNCTION _arm_write_dar + + mcr p15, 0, r0, c3, c0, 0 + isb + bx lr + +ARM_FUNCTION _arm_write_ttb + + mcr p15, 0, r0, c2, c0, 0 + isb + bx lr + +ARM_FUNCTION _arm_write_ttbcr + + mcr p15, 0, r0, c2, c0, 2 + isb + bx lr + +ARM_FUNCTION _arm_read_ifsr + + mrc p15, 0, r0, c5, c0, 1 + bx lr + +ARM_FUNCTION _arm_read_dfsr + + mrc p15, 0, r0, c5, c0, 0 + bx lr + +ARM_FUNCTION _arm_read_ifar + +#if ARCH_ARMv7 + mrc p15, 0, r0, c6, c0, 2 + bx lr +#endif +ARM_FUNCTION _arm_read_dfar + + mrc p15, 0, r0, c6, c0, 0 + bx lr + +ARM_FUNCTION _arm_read_cp_access_cr + + mrc p15, 0, r0, c1, c0, 2 + bx lr + +ARM_FUNCTION _arm_write_cp_access_cr + + mcr p15, 0, r0, c1, c0, 2 + isb + bx lr + +#if WITH_VFP +ARM_FUNCTION _arm_read_fpexc + + vmrs r0, fpexc + bx lr + +ARM_FUNCTION _arm_write_fpexc + + vmsr fpexc, r0 + bx lr + +ARM_FUNCTION _arm_read_fpscr + + vmrs r0, fpscr + bx lr + +ARM_FUNCTION _arm_write_fpscr + + vmsr fpscr, r0 + bx lr + +// Reset core registers to a known value. Kingfisher doesnt +// do this on reset, and simulation traces will show 'x' +// uninitialized values otherwise. Prefer deterministic +ARM_FUNCTION _arm_init_fp_regs + + vmov.i64 q0, #0 + vmov q1, q0 + vmov q2, q0 + vmov q3, q0 + vmov q4, q0 + vmov q5, q0 + vmov q6, q0 + vmov q7, q0 +#if FP_REGISTER_COUNT > 16 + vmov q8, q0 + vmov q9, q0 + vmov q10, q0 + vmov q11, q0 + vmov q12, q0 + vmov q13, q0 + vmov q14, q0 + vmov q15, q0 +#endif + bx lr + +#endif + +#if ARCH_ARMv7 +ARM_FUNCTION _arm_read_l2_aux_cr + + mrc p15, 1, r0, c9, c0, 2 + bx lr + +ARM_FUNCTION _arm_write_l2_aux_cr + + mcr p15, 1, r0, c9, c0, 2 + isb + bx lr + +ARM_FUNCTION _arm_read_pmreg + + cmp r0, #0 + bne 1f + mrc p15, 0, r0, c9, c12, 0 + b 2f +1: cmp r0, #1 + bne 1f + mrc p15, 0, r0, c9, c12, 1 + b 2f +1: cmp r0, #2 + bne 1f + mrc p15, 0, r0, c9, c12, 2 + b 2f +1: cmp r0, #3 + bne 1f + mrc p15, 0, r0, c9, c12, 3 + b 2f +1: cmp r0, #4 + bne 1f + mrc p15, 0, r0, c9, c12, 4 + b 2f +1: cmp r0, #5 + bne 1f + mrc p15, 0, r0, c9, c12, 5 + b 2f +1: cmp r0, #6 + bne 1f + mrc p15, 0, r0, c9, c13, 0 + b 2f +1: cmp r0, #7 + bne 1f + mrc p15, 0, r0, c9, c13, 1 + b 2f +1: cmp r0, #8 + bne 2f + mrc p15, 0, r0, c9, c13, 2 + b 2f +1: cmp r0, #9 + bne 2f + mcr p15, 0, r0, c9, c14, 0 + b 2f +1: cmp r0, #10 + bne 2f + mcr p15, 0, r0, c9, c14, 1 + b 2f +1: cmp r0, #11 + bne 2f + mcr p15, 0, r0, c9, c14, 2 +2: isb + bx lr + +ARM_FUNCTION _arm_write_pmreg + + cmp r0, #0 + bne 1f + mcr p15, 0, r1, c9, c12, 0 + b 2f +1: cmp r0, #1 + bne 1f + mcr p15, 0, r1, c9, c12, 1 + b 2f +1: cmp r0, #2 + bne 1f + mcr p15, 0, r1, c9, c12, 2 + b 2f +1: cmp r0, #3 + bne 1f + mcr p15, 0, r1, c9, c12, 3 + b 2f +1: cmp r0, #4 + bne 1f + mcr p15, 0, r1, c9, c12, 4 + b 2f +1: cmp r0, #5 + bne 1f + mcr p15, 0, r1, c9, c12, 5 + b 2f +1: cmp r0, #6 + bne 1f + mcr p15, 0, r1, c9, c13, 0 + b 2f +1: cmp r0, #7 + bne 1f + mcr p15, 0, r1, c9, c13, 1 + b 2f +1: cmp r0, #8 + bne 2f + mcr p15, 0, r1, c9, c13, 2 + b 2f +1: cmp r0, #9 + bne 2f + mcr p15, 0, r1, c9, c14, 0 + b 2f +1: cmp r0, #10 + bne 2f + mcr p15, 0, r1, c9, c14, 1 + b 2f +1: cmp r0, #11 + bne 2f + mcr p15, 0, r1, c9, c14, 2 +2: isb + bx lr +#endif /* ARCH_ARMv7 */ + +#if ALL_ROUTINES +ARM_FUNCTION _arm_read_user_rw_tid + + mrc p15, 0, r0, c13, c0, 2 + bx lr + +ARM_FUNCTION _arm_write_user_rw_tid + + mcr p15, 0, r0, c13, c0, 2 + isb + bx lr + +ARM_FUNCTION _arm_read_user_ro_tid + + mrc p15, 0, r0, c13, c0, 3 + bx lr + +ARM_FUNCTION _arm_write_user_ro_tid + + mcr p15, 0, r0, c13, c0, 3 + isb + bx lr + +ARM_FUNCTION _arm_read_sup_tid + + mrc p15, 0, r0, c13, c0, 4 + bx lr + +ARM_FUNCTION _arm_write_sup_tid + + mcr p15, 0, r0, c13, c0, 4 + isb + bx lr +#endif + +ARM_FUNCTION _arm_read_perip_port_remap + + mrc p15, 0, r0, c15, c2, 4 + bx lr + +ARM_FUNCTION _arm_write_perip_port_remap + + mcr p15, 0, r0, c15, c2, 4 + isb + bx lr + +ARM_FUNCTION _arm_flush_tlbs + + mov r0, #0 + mcr p15, 0, r0, c8, c7, 0 + dsb + isb + bx lr + +#define EXT(x) _ ## x + +#if ALL_ROUTINES +/* mpu routines */ +#define WRITE_DATA_PROT_REGION(func, n) \ + .global EXT(func); \ +EXT(func): \ + mcr p15, 0, r0, c6, c##n, 0; \ + isb + bx lr + +WRITE_DATA_PROT_REGION(arm_write_dprot_region_0, 0) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_1, 1) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_2, 2) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_3, 3) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_4, 4) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_5, 5) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_6, 6) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_7, 7) +WRITE_DATA_PROT_REGION(arm_write_dprot_region_8, 8) + +#define WRITE_INSTRUCTION_PROT_REGION(func, n) \ + .global EXT(func); \ +EXT(func): \ + mcr p15, 0, r0, c6, c##n, 1; \ + isb + bx lr + +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_0, 0) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_1, 1) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_2, 2) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_3, 3) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_4, 4) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_5, 5) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_6, 6) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_7, 7) +WRITE_INSTRUCTION_PROT_REGION(arm_write_iprot_region_8, 8) + + .global _arm_write_data_prot_register +_arm_write_data_prot_register: + mcr p15, 0, r0, c5, c0, 0 + isb + bx lr + + .global _arm_write_ins_prot_register +_arm_write_ins_prot_register: + mcr p15, 0, r0, c5, c0, 1 + isb + bx lr + + .global _arm_write_cacheable_registers +_arm_write_cacheable_registers: + mcr p15, 0, r0, c2, c0, 0 + mcr p15, 0, r1, c2, c0, 1 + isb + bx lr + + .global _arm_write_bufferable_register +_arm_write_bufferable_register: + mcr p15, 0, r0, c3, c0, 0 + isb + bx lr +#endif + +/* uint arch_enable_ints(void); */ +ARM_FUNCTION _arch_enable_ints + + mrs r0, cpsr + bic r1, r0, #(1<<7) +#if WITH_FIQ_TIMER + bic r1, r1, #(1<<6) +#endif + msr cpsr_c, r1 + and r0, r0, #(1<<7) + bx lr + +/* uint arch_disable_ints(void); */ +ARM_FUNCTION _arch_disable_ints + + mrs r0, cpsr + orr r1, r0, #(1<<7) +#if WITH_FIQ_TIMER + orr r1, r1, #(1<<6) +#endif + msr cpsr_c, r1 + and r0, r0, #(1<<7) + bx lr + +/* uint arch_restore_ints(uint state); */ +ARM_FUNCTION _arch_restore_ints + + mrs r1, cpsr + and r0, r0, #(1<<7) + bic r1, r1, #(1<<7) + orr r2, r1, r0 + msr cpsr_c, r2 + and r0, r1, #(1<<7) + bx lr + +/* void arm_enable_fiqs(void); */ +ARM_FUNCTION _arm_enable_fiqs + + mrs r0, cpsr + bic r0, r0, #(1<<6) + msr cpsr_c, r0 + bx lr + +/* void arm_disable_fiqs(void); */ +ARM_FUNCTION _arm_disable_fiqs + + mrs r0, cpsr + orr r0, r0, #(1<<6) + msr cpsr_c, r0 + bx lr + +#if ARCH_ARMv7 +ARM_FUNCTION _arm_read_vbar + + mrc p15, 0, r0, c12, c0, 0 + bx lr + +ARM_FUNCTION _arm_write_vbar + + mcr p15,0, r0, c12, c0, 0 + bx lr + +#endif + +#if ARCH_ARMv7 +ARM_FUNCTION _arm_flush_branch_predictor + + mov r0, #0 + mcr p15, 0, r0, c7, c5, 6 /* flush the branch predictor cache */ + isb + mov pc, lr +#endif + +/* void arm_memory_barrier(void); */ +ARM_FUNCTION _arm_memory_barrier + +#if ARCH_ARMv7 + dmb +#endif + bx lr + +#ifdef PRODUCT_EMBEDDEDIOP +/* WFI errata workaround for Cortex-A5 */ + dummy_store: + .long 0xaaaabbbb + + .balign 32 +#endif //PRODUCT_EMBEDDEDIOP + +ARM_FUNCTION _arch_halt + +#if !NO_ARM_HALT +# if ARCH_ARMv7 + dsb +#ifdef PRODUCT_EMBEDDEDIOP + str r0, dummy_store +#endif //PRODUCT_EMBEDDEDIOP + wfi +# else + mov r0, #0 + mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ +# endif +#endif + bx lr + +ARM_FUNCTION _arch_spin + +#if ARCH_ARMv7 || ARCH_ARMv8 + wfe +#endif + b _arch_spin + +#if WITH_ARM_DCC +ARM_FUNCTION _read_dtr + + mrc p14, 0, r0, c0, c5, 0 + bx lr + +ARM_FUNCTION _write_dtr + + mcr p14, 0, r0, c0, c5, 0 + isb + bx lr + +ARM_FUNCTION _read_dscr + + mrc p14, 0, r0, c0, c1, 0 + bx lr +#endif /* WITH_ARM_DCC */ + + +#if CPU_APPLE_SWIFT +ARM_FUNCTION _swift_read_l2cerrsts + + mrc p15, 1, r0, c15, c2, 5 + bx lr + +ARM_FUNCTION _swift_write_l2cerrsts + + mcr p15, 1, r0, c15, c2, 5 + isb + bx lr + +ARM_FUNCTION _swift_read_l2cerradr + + mrc p15, 1, r0, c15, c2, 7 + bx lr + +ARM_FUNCTION _swift_write_l2cerradr + + mcr p15, 1, r0, c15, c2, 7 + isb + bx lr +#endif /* CPU_APPLE_SWIFT */ diff --git a/arch/arm/cache_v7.S b/arch/arm/cache_v7.S new file mode 100644 index 0000000..3477991 --- /dev/null +++ b/arch/arm/cache_v7.S @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + + .text + + /* + * Cache functions for ARM v7 + */ + + /* perform loop unrolling to optimize for multi-line operations rdar://problem/6722268 */ +ARM_FUNCTION _arm_clean_dcache_line_8 + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_dcache_line_7 + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_dcache_line_6 + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_dcache_line_5 + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_dcache_line_4 + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_dcache_line_3 + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_dcache_line_2 + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_dcache_line + + mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA + dmb + bx lr + + /* perform loop unrolling to optimize for multi-line operations rdar://problem/6722268 */ +ARM_FUNCTION _arm_invalidate_dcache_line_8 + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_invalidate_dcache_line_7 + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_invalidate_dcache_line_6 + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_invalidate_dcache_line_5 + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_invalidate_dcache_line_4 + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_invalidate_dcache_line_3 + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_invalidate_dcache_line_2 + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_invalidate_dcache_line + + mcr p15, 0, r0, c7, c6, 1 // invalidate L1/L2 line by MVA + dmb + bx lr + + /* perform loop unrolling to optimize for multi-line operations rdar://problem/6722268 */ +ARM_FUNCTION _arm_clean_invalidate_dcache_line_8 + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_invalidate_dcache_line_7 + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_invalidate_dcache_line_6 + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_invalidate_dcache_line_5 + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_invalidate_dcache_line_4 + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_invalidate_dcache_line_3 + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_invalidate_dcache_line_2 + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + add r0, r0, #(CPU_CACHELINE_SIZE) + +ARM_FUNCTION _arm_clean_invalidate_dcache_line + + mcr p15, 0, r0, c7, c14, 1 // clean/invalidate L1/L2 line by MVA + dmb + bx lr + + +ARM_FUNCTION _arm_clean_dcache + + mov r2, #((1 << CPU_CACHEINDEX_SHIFT) << CPU_CACHELINE_SHIFT) +1: + sub r2, r2, #(1 << CPU_CACHELINE_SHIFT) + mov r1, #((1 << CPU_CACHESET_SHIFT) << (32-CPU_CACHESET_SHIFT)) +2: + subs r1, r1, #(1 << (32-CPU_CACHESET_SHIFT)) + orr r0, r1, r2 + mcr p15, 0, r0, c7, c10, 2 // clean one line by way and set + bne 2b + cmp r2, #0 + bne 1b + +#if L2_CACHE_SIZE + mov r2, #((1 << L2_CACHE_SETS) << 6) +1: + sub r2, r2, #(1 << 6) + mov r1, #((1 << 3) << 29) +2: + subs r1, r1, #(1 << 29) + orr r0, r1, r2 + orr r0, r0, #(1 << 1) + mcr p15, 0, r0, c7, c10, 2 // clean one line by way and set + bne 2b + cmp r2, #0 + bne 1b +#endif + + mov r0, #0 + dmb + bx lr + +ARM_FUNCTION _arm_clean_invalidate_dcache + + mov r2, #((1 << CPU_CACHEINDEX_SHIFT) << CPU_CACHELINE_SHIFT) +1: + sub r2, r2, #(1 << CPU_CACHELINE_SHIFT) + mov r1, #((1 << CPU_CACHESET_SHIFT) << (32-CPU_CACHESET_SHIFT)) +2: + subs r1, r1, #(1 << (32-CPU_CACHESET_SHIFT)) + orr r0, r1, r2 + mcr p15, 0, r0, c7, c14, 2 // clean and invalidate one line by way and set + bne 2b + cmp r2, #0 + bne 1b + +#if L2_CACHE_SIZE + mov r2, #((1 << L2_CACHE_SETS) << 6) +1: + sub r2, r2, #(1 << 6) + mov r1, #((1 << 3) << 29) +2: + subs r1, r1, #(1 << 29) + orr r0, r1, r2 + orr r0, r0, #(1 << 1) + mcr p15, 0, r0, c7, c14, 2 // clean and invalidate one line by way and set + bne 2b + cmp r2, #0 + bne 1b +#endif + + mov r0, #0 + dmb + bx lr + +ARM_FUNCTION _arm_invalidate_dcache + + // This is a fancy way of writing "0". Thr first sub will make this (1< +#include +#include + +void arm_l1cache_dump(int dcache, unsigned int mva) +{ + register unsigned index = (mva >> 6) & 0x7f; + unsigned way, addr, word, data0, data1; + unsigned tag, i, parity, tmp; + unsigned lookup; + unsigned cr = arm_read_cr(); + + arm_write_cr(cr & ~((1 << 12) | (1 << 2))); + lookup = (mva != -1UL); + for (way=0; way<4; way++) { + if (!lookup) index = 0; + do { + addr = (way << 30) | (index << 6); + if (dcache) { + __asm__ volatile("mcr p15,0,%0,c15,c2,6" ::"r"(addr)); + __asm__ volatile("mrc p15,0,%0,c15,c0,0" :"=r"(tag)); + } else { + __asm__ volatile("mcr p15,0,%0,c15,c3,6" ::"r"(addr)); + __asm__ volatile("mrc p15,0,%0,c15,c1,0" :"=r"(tag)); + } + tag <<= 12; + for (word = 0; word < 16; word++) { + addr = (way << 30) | (index << 6) | (word << 2); + if (dcache) { + __asm__ volatile("mcr p15,0,%0,c15,c2,7" ::"r"(addr)); + __asm__ volatile("mrc p15,0,%0,c15,c0,0" :"=r"(data0)); + __asm__ volatile("mrc p15,0,%0,c15,c0,1" :"=r"(data1)); + } else { + __asm__ volatile("mcr p15,0,%0,c15,c3,7" ::"r"(addr)); + __asm__ volatile("mrc p15,0,%0,c15,c1,0" :"=r"(data0)); + __asm__ volatile("mrc p15,0,%0,c15,c1,1" :"=r"(data1)); + } + if (word == 0) + printf("PA %08x: %c ", tag | ((index & 0x3f) << 6), + dcache && (data1&1) ? 'D':' '); + parity = 0; + tmp = data0; + for (i=0; i<8; i++) { + parity ^= tmp & 0x01010101; + tmp >>= 1; + } + parity &= 0x01010101; + parity = (parity >> 21) | (parity >> 14) | (parity >> 7) | parity; + if ((parity ^ (data1 >> 2)) & 0xf) + printf(" >%08x-%x<", data0, (data1>>2)&0xf); + else + printf(" %08x", data0); + } + printf("\n"); + } while (!lookup && (++index < 128)); + } + arm_clean_dcache(); + arm_write_cr(cr); +} + +void dump_l1caches(int disable) +{ + unsigned cr; + + cr = arm_read_cr(); + + if (disable) { + arm_write_cr(cr & ~((1<<12)|(1<<2))); + arm_clean_dcache(); + } + + arm_l1cache_dump(0, -1); + arm_l1cache_dump(1, -1); + + if (disable) + arm_write_cr(cr); +} + +#if defined(WITH_MENU) && WITH_MENU +static int do_l1dump(int argc, struct cmd_arg *args) { dump_l1caches(1); return 0; } +MENU_COMMAND_DEVELOPMENT(l1dump, do_l1dump, "dump L1 i/d contents", NULL); +#endif diff --git a/arch/arm/context.S b/arch/arm/context.S new file mode 100644 index 0000000..169f9c0 --- /dev/null +++ b/arch/arm/context.S @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +/* + * Task context switch support. + * + * Basic VFP/Neon floating point context switch only. + */ + +/* + * Code here must remain synchronised with the structure and offsets defined in arch_task.h: + * + * struct arch_task { + * uint32_t regs[10]; // r4-r11, r13, r14 + * #if WITH_VFP + * uint32_t fpscr; + * uint32_t fpexc; + * uint32_t fpinst; + * uint32_t fpinst2; + * uint64_t fpregs[32]; // assume VFP-D32 + * #endif + * }; +*/ + +/* + * void arch_task_context_switch(struct arch_task *old, struct arch_task *new_task); + */ + +ARM_FUNCTION _arch_task_context_switch + + /* save non-volatile core registers */ + stmia r0, { r4-r11, r13, r14 } + +#if WITH_VFP +#if !WITH_VFP_ALWAYS_ON + /* save fpexc */ + vmrs r2, fpexc + str r2, [r0, #ARM_ARCH_TASK_FPEXC] + + /* check FP enable state */ + tst r2, #FPEXC_EN + beq L_fp_save_done + + /* save fpscr */ + vmrs r4, fpscr + str r4, [r0, #ARM_ARCH_TASK_FPSCR] +#endif + + /* save the FP registers */ + add r3, r0, #ARM_ARCH_TASK_FPREGS + vstm.64 r3!, { d0-d15 } +#if FP_REGISTER_COUNT > 16 + vstm.64 r3, { d16-d31 } +#endif +L_fp_save_done: +#endif /* WITH_VFP */ + + /* select the context we're going to switch to and invoke the context restore */ + mov r0, r1 + b _arch_task_context_restore + + +/* + * void arch_task_context_restore(struct arch_task *restore_context) + */ + +ARM_FUNCTION _arch_task_context_restore + +#if WITH_VFP +#if !WITH_VFP_ALWAYS_ON + /* restore fpexc */ + ldr r2, [r0, #ARM_ARCH_TASK_FPEXC] + vmsr fpexc, r2 + + /* check FP enable state */ + tst r2, #FPEXC_EN + beq L_fp_restore_done + + /* restore fpscr */ + ldr r4, [r0, #ARM_ARCH_TASK_FPSCR] + vmsr fpscr, r4 +#endif + + /* restore the FP registers */ + add r3, r0, #ARM_ARCH_TASK_FPREGS + vldm.64 r3!, { d0-d15 } +#if FP_REGISTER_COUNT > 16 + vldm.64 r3, { d16-d31 } +#endif +L_fp_restore_done: +#endif /* WITH_VFP */ + + /* restore non-volatile core registers */ + ldmia r0, { r4-r11, r13, r14 } + bx lr + + +#if WITH_VFP && !WITH_VFP_ALWAYS_ON +/* + * void arm_call_fpsaved(void *arg, void (*func)(void *arg)) + */ + .globl _arm_call_fpsaved +_arm_call_fpsaved: + stmfd sp!, {lr} + + /* fetch fpexc and check FP enable state */ + vmrs r2, fpexc + tst r2, #FPEXC_EN + beq 1f /* bypass save if VFP is off */ + + /* save fpscr */ + vmrs r3, fpscr + push {r3} + + /* save the FP registers */ +#if FP_REGISTER_COUNT > 16 + vpush { d16-d31 } +#endif + vpush { d0-d15 } +1: + /* stack fpexc last, always guranteed to be on the stack */ + push {r2} + + /* unconditionally enable VFP for this call */ + orr r2, r2, #FPEXC_EN + vmsr fpexc, r2 + + /* branch to the routine */ + blx r1 + + /* pop fpexc and test whether FP was saved */ + pop {r2} + tst r2, #FPEXC_EN + beq 2f + + /* restore the FP registers */ + vpop { d0-d15 } +#if FP_REGISTER_COUNT > 16 + vpop { d16-d31 } +#endif + + /* restore fpcsr */ + pop {r3} + vmsr fpscr, r2 +2: + /* restore fpexc last, may disable VFP */ + vmsr fpexc, r2 + + ldmfd sp!, {lr} + bx lr +#endif /* WITH_VFP */ diff --git a/arch/arm/cortex_debug.c b/arch/arm/cortex_debug.c new file mode 100644 index 0000000..59628aa --- /dev/null +++ b/arch/arm/cortex_debug.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +extern char cortex_hang_start, cortex_hang_ffe, cortex_hang_end; +typedef uint32_t (*hang_func_t)(uint32_t); +static uint8_t *hang_buffer = NULL; +static hang_func_t cortex_hang; + +static int do_hang(int argc, struct cmd_arg *args) +{ + u_int32_t count = 10000; + utime_t before, after; + int i, ret, always = 0; + char *entry_point; + + if (argc > 1) + count = args[1].u; + if (!strcmp(args[0].str, "hangloop")) + always = 1; + + if (hang_buffer == NULL) { + hang_buffer = malloc(8192); + entry_point = (char *)((((uint32_t)hang_buffer + 0xfff) & ~0xfff) - + (&cortex_hang_ffe + 2 - &cortex_hang_start)); + memcpy(entry_point, &cortex_hang_start, &cortex_hang_end - &cortex_hang_start); + arm_clean_dcache(); + arm_invalidate_icache(); + cortex_hang = (hang_func_t)(entry_point+1); /* Thumb */ + printf("Created hang code buffer; base = %p, entry = %p\n", hang_buffer, cortex_hang); + } + + for (i=0; (i<100) || always; i++) { + printf("Try %3d: ", i+1); + before = system_time(); + ret = cortex_hang(count); + after = system_time(); + printf("complete; time = %6d\n", after-before); + if (ret != 0) printf(" EARLY EXIT!\n"); + } + return 0; +} + +MENU_COMMAND_DEBUG(hang, do_hang, "try to hang cortex", NULL); +MENU_COMMAND_DEBUG(hangloop, do_hang, "try to hang cortex - run forever", NULL); + +#endif diff --git a/arch/arm/cortex_hang.S b/arch/arm/cortex_hang.S new file mode 100644 index 0000000..96eb2cb --- /dev/null +++ b/arch/arm/cortex_hang.S @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + .text + .global _cortex_hang_start, _cortex_hang_ffe, _cortex_hang_end + .thumb + .syntax unified + +// Believe it or not, without this, it does not fail +#define NOP mov r8,r8 + + // R0 holds the number of iterations we should run + // start this routine at a page boundary +_cortex_hang_start: + // save some registers and set aside a word + push {r4,r5,r6,r7,lr} + sub sp, #4 +1: + cmp r0, #0 + beq 1f + NOP // 0xff0 + NOP // 0xff2 + NOP // 0xff4 + NOP // 0xff6 + subs r0, #1 // 0xff8 + str.w ip, [sp] // 0xffa +_cortex_hang_ffe: + bl 1b // 0xffe +1: + add sp, #4 + pop {r4,r5,r6,r7,pc} + bx lr +_cortex_hang_end: diff --git a/arch/arm/cpu.c b/arch/arm/cpu.c new file mode 100644 index 0000000..7494f85 --- /dev/null +++ b/arch/arm/cpu.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#if PERIPH_PORT_REMAP +static void config_periph_port_remap(void *base, size_t len); +#endif + +#if WITH_EARLY_ICACHE && WITH_L1_PARITY +#error Early i-cache init and L1 parity enable are mutually exclusive +#endif + +int arch_cpu_init(bool resume) +{ + u_int32_t cr, aux_cr; + + aux_cr = 0; + +#if WITH_CACHE + /* make sure the cpu caches are invalidated */ +#if !WITH_EARLY_ICACHE + /* d-cache init is deferred if we're turning i-cache on early */ + arm_invalidate_dcache(); +#endif + arm_invalidate_icache(); +#endif + +#if ARCH_ARMv7 + aux_cr = arm_read_aux_cr(); + +#if CPU_ARM_CORTEX_A8 + // Ask platform if WFI should be enabled or not + if (platform_get_core_idle_enable()) { + aux_cr &= ~(1 << 8); + } else { + aux_cr |= (1 << 8); + } +#endif + +#if WITH_ARCHITECTED_L2 + /* Manage the v7 L2 cache */ +# if WITH_AUX_L2_ENABLE_BIT && L2_CACHE_SIZE + aux_cr |= (1 << 1); +# else + aux_cr &= ~(1 << 1); +# endif +#endif + +#if SET_AUX_SMP_BIT + /* Set SMP bit; enable snooping within cluster and sharing of L2 */ + aux_cr |= (1 << 6); +#endif + + arm_write_aux_cr(aux_cr); +#endif + + /* read control register default value */ + cr = arm_read_cr(); + +#if WITH_BRANCH_PREDICTION + /* turn on branch predictor */ + cr |= (1 << 11); +#endif + +#if WITH_CACHE && WITH_EARLY_ICACHE + /* early i-cache enable */ + cr |= (1 << 12); + + arm_write_cr(cr); +#endif + +#if PERIPH_PORT_REMAP + /* do any peripheral port remapping */ + config_periph_port_remap((void *)PERIPH_BASE, PERIPH_LEN); +#endif + +#if WITH_CACHE + +#if WITH_EARLY_ICACHE + /* d-cache invalidation delayed until this point */ + arm_invalidate_dcache(); +#else + /* turn on i-cache */ + cr |= (1 << 12); +#endif + + /* turn on d-cache */ + cr |= (1 << 2); + +#if WITH_L1_PARITY + arm_enable_l1parity(); +#endif +#endif + +#if WITH_UNALIGNED_MEM + /* enable unaligned access handler */ + cr &= ~(1 << 1); +#if !ARCH_ARMv7 + cr |= (1 << 22); +#endif +#endif + + /* enable the caches and etc. before setting up the translation table */ + arm_write_cr(cr); + +#if WITH_MMU + /* set up the translation table and then turn on the MMU */ + arm_mmu_init(resume); + cr |= (1 << 0); + + arm_write_cr(cr); +#endif + +#if WITH_VFP + /* initialize VFP */ + arm_fp_init(); +#if WITH_VFP_ALWAYS_ON + arm_fp_enable(true); +#endif +#endif + + return 0; +} + +int arch_cpu_quiesce(void) +{ + u_int32_t cr, aux_cr; + + aux_cr = 0; + +#if ARCH_ARMv7 + aux_cr = arm_read_aux_cr(); + +#if CPU_ARM_CORTEX_A8 + /* turn WFI on */ + aux_cr &= ~(1 << 8); +#endif + + arm_write_aux_cr(aux_cr); +#endif + +#if WITH_CACHE && !CLEAN_INV_CACHE_ON_QUIESCE + /* clean the d-cache */ + arm_clean_dcache(); +#endif + + /* read the control regiser base value */ + cr = arm_read_cr(); + +#if WITH_MMU + /* turn off the mmu */ + cr &= ~(1 << 0); +#endif +#if WITH_CACHE + /* turn off d-cache */ + cr &= ~(1 << 2); + + /* turn off i-cache */ + cr &= ~(1 << 12); +#endif + +#if WITH_BRANCH_PREDICTION + /* turn off branch predictor */ + cr &= ~(1 << 11); +#endif + +#if WITH_UNALIGNED_MEM + /* disable unaligned access handler */ + cr |= (1 << 1); + cr &= ~(1 << 22); +#endif + + /* disable the MMU, caches and etc. */ + arm_write_cr(cr); + +#if WITH_CACHE && CLEAN_INV_CACHE_ON_QUIESCE + /* clean and/or invalidate the caches */ + arm_clean_invalidate_dcache(); + arm_invalidate_icache(); +#endif + +#if CPU_APPLE_SWIFT + +#if !CLEAN_INV_CACHE_ON_QUIESCE + /* Invalidate all lines in the L1-D cache */ + arm_invalidate_dcache(); +#endif + + /* Clear any pending L2C errors */ + swift_write_l2cerrsts(0); + swift_write_l2cerradr(0); +#endif /* CPU_APPLE_SWIFT */ + + return 0; +} + +int arch_cpu_init_posttasks(void) +{ +#if WITH_ARM_DCC + /* initialize the DCC mechanism */ + arm_dcc_init(); +#endif + + return 0; +} + +u_int32_t arch_get_noncached_address(u_int32_t address) +{ +#if WITH_MMU + return arm_get_noncached_address(address); +#else + return address; /* not really any other choice... */ +#endif +} + +#if PERIPH_PORT_REMAP +static void config_periph_port_remap(void *base, size_t len) +{ + uint32_t val = (uint32_t)base; + + switch (len) { + case 0: val |= 0x0; break; + case 0x1000: val |= 0x3; break; + case 0x2000: val |= 0x4; break; + case 0x4000: val |= 0x5; break; + case 0x8000: val |= 0x6; break; + case 0x10000: val |= 0x7; break; + case 0x20000: val |= 0x8; break; + case 0x40000: val |= 0x9; break; + case 0x80000: val |= 0xa; break; + case 0x100000: val |= 0xb; break; + case 0x200000: val |= 0xc; break; + case 0x400000: val |= 0xd; break; + case 0x800000: val |= 0xe; break; + case 0x1000000: val |= 0xf; break; + case 0x2000000: val |= 0x10; break; + case 0x4000000: val |= 0x11; break; + case 0x8000000: val |= 0x12; break; + case 0x10000000: val |= 0x13; break; + case 0x20000000: val |= 0x14; break; + case 0x40000000: val |= 0x15; break; + case 0x80000000: val |= 0x16; break; + } + + arm_write_perip_port_remap(val); +} +#endif + +static bool cpu_setup_mmu(bool resume) +{ +#if WITH_MMU + arm_mmu_init(resume); + return true; +#endif + +#if WITH_MPU + arm_mpu_init(); + return true; +#endif + + return false; +} + diff --git a/arch/arm/dcc/dcc.c b/arch/arm/dcc/dcc.c new file mode 100644 index 0000000..46075e6 --- /dev/null +++ b/arch/arm/dcc/dcc.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#define DSCR_WDTR_FULL (1L<<29) +#define DSCR_RDTR_FULL (1L<<30) + +#if ARM_DCC_SYNCHRONOUS +static bool dcc_wait_tx = true; +#else +static bool dcc_wait_tx; +#endif + +#ifndef DCC_TX_BUFFER_SIZE +# define DCC_TX_BUFFER_SIZE 256 +#endif + +static struct cbuf *dcc_output_cbuf; + +extern u_int32_t read_dtr(void); +extern void write_dtr(u_int32_t c); +extern u_int32_t read_dscr(void); + +void arm_write_dcc_char(int c) +{ + if (dcc_wait_tx) { + while (read_dscr() & DSCR_WDTR_FULL); + write_dtr(c); + } else { + if (dcc_output_cbuf != 0) + cbuf_write_char(dcc_output_cbuf, c); + } +} + +int arm_read_dcc_char(void) +{ + while (!(read_dscr() & DSCR_RDTR_FULL)); + + return read_dtr(); +} + +int arm_read_dcc_char_nowait(void) +{ + if (!(read_dscr() & DSCR_RDTR_FULL)) + return -1; + + return read_dtr(); +} + +static int dcc_read_task(void *arg) +{ + for(;;) { + int c; + + c = arm_read_dcc_char_nowait(); + if (c >= 0) { + if (c != '\r') + debug_pushchar(c); + } + task_sleep(1 * 1000); + } + return 0; +} + +static int dcc_write_task(void *arg) +{ + for(;;) { + ssize_t ret; + char c; + + ret = cbuf_read_char(dcc_output_cbuf, &c); + if (ret == 1) { + while(read_dscr() & DSCR_WDTR_FULL) + task_yield(); + write_dtr(c); + } + task_sleep(1 * 1000); + } + return 0; +} + +int arm_dcc_init(void) +{ + if (arm_read_dcc_char_nowait() >= 0) + dcc_wait_tx = true; + + if (!dcc_wait_tx) { + dcc_output_cbuf = cbuf_create(DCC_TX_BUFFER_SIZE, NULL); + task_start(task_create("dcc write", &dcc_write_task, NULL, 256)); + } + + task_start(task_create("dcc read", &dcc_read_task, NULL, 512)); + + return 0; +} diff --git a/arch/arm/dcc/rules.mk b/arch/arm/dcc/rules.mk new file mode 100644 index 0000000..bdb8916 --- /dev/null +++ b/arch/arm/dcc/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_ARM_DCC=1 + +MODULES += \ + lib/cbuf + +ALL_OBJS += \ + $(LOCAL_DIR)/dcc.o diff --git a/arch/arm/entropy.S b/arch/arm/entropy.S new file mode 100644 index 0000000..dba9a5a --- /dev/null +++ b/arch/arm/entropy.S @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + + .text + +// u_int32_t arch_get_entropy(volatile u_int32_t *counter_address) +// +// arch_get_entropy exploits the uncertainty in the asynchronous boundary crossing +// between the CPU and a counter. To work correctly, the CPU and counter must be +// derived from clocks with relative jitter (PLL vs. OSC). Ideally the inner loop, +// up to 32 iterations, should consume a large part of the effective read period of +// the counter. +// + +ARM_FUNCTION _arch_get_entropy + + mov r1, r0 + mov r0, #0 + mov r2, #32 +1: + mov r3, r2 +2: + subs r3, r3, #1 + bne 2b + ldr r3, [r1] + and r3, r3, #1 + orr r0, r3, r0, lsl #1 + subs r2, r2, #1 + bne 1b + bx lr diff --git a/arch/arm/exceptions.S b/arch/arm/exceptions.S new file mode 100644 index 0000000..59d1475 --- /dev/null +++ b/arch/arm/exceptions.S @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include + +/* + * struct arm_exception_frame { + * uint32_t sp; + * uint32_t lr; + * uint32_t spsr; + * uint32_t r[13]; + * uint32_t pc; + * uint64_t fpr[32]; + * uint32_t fpscr; + * uint32_t fpexc; + * }; + * + * Note that when returning to the mode in which the exception was + * taken that set the I and F bits to mask interrupts and clear the + * T bit so that we stay in ARM mode. + */ + +#if VFP_REV >= 3 + +#define VFP_SAVE \ + vstmdb.64 sp!, {d0-d3} ; \ + vstmdb.64 sp!, {d4-d7} ; \ + vstmdb.64 sp!, {d8-d11} ; \ + vstmdb.64 sp!, {d12-d15} ; \ + vstmdb.64 sp!, {d16-d19} ; \ + vstmdb.64 sp!, {d20-d23} ; \ + vstmdb.64 sp!, {d24-d27} ; \ + vstmdb.64 sp!, {d28-d31} ; \ + fmrx r1, fpscr ; \ + stmfd sp!, { r1 } ; \ + fmrx r1, fpexc ; \ + stmfd sp!, { r1 } + + +#define VFP_LOAD \ + ldmfd sp!, { r1 } ; \ + fmxr fpexc, r1 ; \ + ldmfd sp!, { r1 } ; \ + vldmia.64 sp!, {d28-d31} ; \ + vldmia.64 sp!, {d24-d27} ; \ + vldmia.64 sp!, {d20-d23} ; \ + vldmia.64 sp!, {d16-d19} ; \ + vldmia.64 sp!, {d12-d15} ; \ + vldmia.64 sp!, {d8-d11} ; \ + vldmia.64 sp!, {d4-d7} ; \ + vldmia.64 sp!, {d0-d3} ; \ + fmxr fpscr, r1 + +#else + +#define VFP_SAVE +#define VFP_LOAD + +#endif + +#define PUSH_EXCEPTION_FRAME \ + stmfd sp!, { r0-r12, lr } ; \ + mrs r0, spsr ; \ + stmfd sp!, { r0 } ; \ + orr r0, r0, #0xc0 ; \ + bic r0, r0, #(1 << 5) ; \ + mrs r1, cpsr ; \ + msr cpsr_c, r0 ; \ + mov r2, sp ; \ + mov r3, lr ; \ + msr cpsr_c, r1 ; \ + stmfd sp!, { r2-r3 } + +#define POP_EXCEPTION_FRAME \ + add sp, sp, #12 ; \ + ldmfd sp!, { r0-r12, pc }^ + + + .text +/* + * Interrupt handling. + * + * Note that FIQ is not intended to be "fast", but rather an NMI. + */ + +ARM_FUNCTION ___arm_irq + + sub lr, lr, #4 /* fix up return address */ + + PUSH_EXCEPTION_FRAME + VFP_SAVE + +#if ARCH_ARMv7 + mrs r1, cpsr + bic r1, #0x100 /* re-enable imprecise data aborts */ + msr cpsr_x, r1 +#endif + + bl _arm_irq /* call handler */ + + VFP_LOAD + POP_EXCEPTION_FRAME + + +ARM_FUNCTION ___arm_fiq + + sub lr, lr, #4 /* fix up return address */ + + /* + * We can't use PUSH_EXCEPTION_FRAME here as we need to save banked registers, + * but the only difference should be the re-saving of r8-r12 in the saved mode. + */ + stmfd sp!, { r0-r12, lr } /* save unbanked registers */ + mrs r0, spsr /* save spsr */ + stmfd sp!, { r0 } + add r4, sp, #36 /* address of r8 in save frame */ + orr r0, r0, #0xc0 /* mask interrupts and swap to previous mode */ + mrs r1, cpsr + msr cpsr_c, r0 + stmia r4, { r8-r12 } /* save banked registers */ + mov r2, sp /* grab sp & lr, swap back and save them */ + mov r3, lr + msr cpsr_c, r1 +#if ARCH_ARMv7 + bic r1, #0x100 /* re-enable imprecise data aborts */ + msr cpsr_x, r1 +#endif + stmfd sp!, { r2-r3 } + + VFP_SAVE + + bl _arm_fiq /* call handler */ + + VFP_LOAD + POP_EXCEPTION_FRAME + + + +/* + * Exception handling. + * + * In each case, the handler is expected to populate the + * exception frame structure and call the high-level dispatch + * routine. Note that we don't support resuming from any + * exceptions other than IRQ/FIQ. + * + */ + +ARM_FUNCTION ___arm_undefined + + PUSH_EXCEPTION_FRAME + + mov r0, sp + bl _arm_undefined + b . + +ARM_FUNCTION ___arm_syscall + + PUSH_EXCEPTION_FRAME + + mov r0, sp + bl _arm_syscall + b . + +ARM_FUNCTION ___arm_prefetch_abort + + sub lr, lr, #4 + + PUSH_EXCEPTION_FRAME + + mov r0, sp + bl _arm_prefetch_abort + b . + +ARM_FUNCTION ___arm_data_abort + + PUSH_EXCEPTION_FRAME + + mov r0, sp + bl _arm_data_abort + b . + +ARM_FUNCTION ___arm_reserved + + b . diff --git a/arch/arm/fp.c b/arch/arm/fp.c new file mode 100644 index 0000000..4051311 --- /dev/null +++ b/arch/arm/fp.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include + +/* + * VFP/Neon support + */ + +#if WITH_VFP + +void +arm_fp_init(void) +{ + u_int32_t cr; + + cr = arm_read_cp_access_cr(); + cr |= CPACR_CP_BITS(10, CPACR_CP_FULL) | CPACR_CP_BITS(11, CPACR_CP_FULL); + arm_write_cp_access_cr(cr); +} + +#if WITH_VFP_ALWAYS_ON +void +arm_fp_enable(bool enable) +{ + arm_write_fpexc(FPEXC_EN); + + /* reset VFP/NEON state */ + arm_write_fpscr(FPSCR_DEFAULT); + + /* zero init VFP/NEON registers */ + arm_init_fp_regs(); +} +#endif /* WITH_VFP_ALWAYS_ON */ + +bool +arch_task_fp_enable(bool enable) +{ + bool current; + u_int32_t cr; + struct task *t; + struct arch_task *at; + + /* get the current FP enable state */ + t = task_get_current_task(); + at = &t->arch; + current = (at->fpexc & FPEXC_EN); + + if (enable != current) { + + /* fetch current hardware state */ + cr = arm_read_fpexc(); + if (enable) { + /* enable VFP/NEON */ + at->fpexc = FPEXC_EN; + arm_write_fpexc(at->fpexc); + + /* reset VFP/NEON state */ + at->fpscr = 0; + arm_write_fpscr(FPSCR_DEFAULT); + + } else { + /* disable VFP/NEON */ + at->fpexc = cr & ~FPEXC_EN; + arm_write_fpexc(at->fpexc); + } + + return(!enable); + } + return(enable); +} + +#endif /* WITH_VFP */ diff --git a/arch/arm/handlers.c b/arch/arm/handlers.c new file mode 100644 index 0000000..195e8f3 --- /dev/null +++ b/arch/arm/handlers.c @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +extern void platform_irq(void); +extern void platform_fiq(void); + +static const char *arm_abort_decode_status(unsigned int dfsr); +static const char *arm_decode_mode(unsigned int status_reg); +static void arm_exception_abort(struct arm_exception_frame *frame, + const char *kind, + unsigned int fsr, + unsigned int far) __noreturn; + +static struct arm_exception_frame *arm_get_exception_frame(void) __pure; +static struct arm_exception_frame *arm_get_interrupt_frame(void) __pure; +static struct arm_exception_frame *arm_get_fiq_frame(void) __pure; +static void arm_print_frame_registers(struct arm_exception_frame *frame, const char *prefix); +static void arm_backtrace(const char *prefix, u_int32_t pc, u_int32_t fp, u_int32_t stack_base, u_int32_t stack_len); +static void arm_stack_for_status_reg(u_int32_t status_reg, u_int32_t *stack_base, u_int32_t *stack_len); + +static bool exception_dump_near_pc; + +#if WITH_MMU +static char status_str[32]; + +static const char * +arm_abort_decode_status(unsigned int fsr) +{ + /* mask bit 10 & low 4 bits for cause decoding */ + fsr &= FSR_CAUSE_MASK; + + /* ARMv4v5 architecture reference B4-20 */ + switch (fsr) { + case 0x01: + case 0x03: + return("alignment error"); + case 0x04: + return("icache operation error"); + case 0x0c: + case 0x0e: + return("external abort on translation"); + case 0x05: + case 0x07: + return("translation error"); + case 0x09: + case 0x0b: + return("domain violation"); + case 0x0d: + case 0x0f: + return("permission violation"); + case 0x08: + case 0x0a: /* this code is deprecated in ARMv7*/ + return("precise external abort"); + case 0x406: + return("imprecise external abort"); /* ARMv7 */ + case 0x40a: + return("coprocessor data abort"); + case 0x408: + return("data cache parity error"); /* ARMv7 */ + case 0x409: + return("instruction cache parity error"); /* ARMv7 */ + case 0x02: + return("debug event"); + } + + snprintf(status_str, sizeof(status_str), "", fsr); + + return(status_str); +} +#endif + +static const char * +arm_decode_mode(unsigned int status_reg) +{ + switch (CPSR_MODE(status_reg)) { + case CPSR_MODE_USER: + return("user"); + case CPSR_MODE_FIQ: + return("FIQ"); + case CPSR_MODE_IRQ: + return("IRQ"); + case CPSR_MODE_SUPERVISOR: + return("supervisor"); + case CPSR_MODE_ABORT: + return("abort"); + case CPSR_MODE_UNDEFINED: + return("undefined"); + case CPSR_MODE_SYSTEM: + return("system"); + } + return(""); +} + +void +arm_data_abort(struct arm_exception_frame *frame) +{ + unsigned int fsr = arm_read_dfsr(); + unsigned int far = arm_read_dfar(); + + frame->pc -= 8; + if (fsr == 0x408) { + arm_l1cache_dump(1, far); + } + arm_exception_abort(frame, "data abort", fsr, far); +} + +void +arm_prefetch_abort(struct arm_exception_frame *frame) +{ + unsigned int fsr = arm_read_ifsr(); + unsigned int far = arm_read_ifar(); + + frame->pc -= 4; + if (fsr == 0x409) { + arm_l1cache_dump(0, far); + } + arm_exception_abort(frame, "prefetch abort", fsr, far); +} + +void +arm_undefined(struct arm_exception_frame *frame) +{ + exception_dump_near_pc = true; + frame->pc -= (frame->spsr & CPSR_STATE_THUMB) ? 2: 4; + arm_exception_abort(frame, "undefined instruction", ~0, frame->pc); +} + +void +arm_syscall(struct arm_exception_frame *frame) +{ + exception_dump_near_pc = true; + frame->pc -= (frame->spsr & CPSR_STATE_THUMB) ? 2: 4; + arm_exception_abort(frame, "syscall", arm_read_ifsr(), frame->pc); +} + +static void +arm_exception_abort(struct arm_exception_frame *frame, const char *kind, unsigned int fsr, unsigned int far) +{ +#if WITH_MMU + panic("ARM %s abort in %s mode at 0x%08x due to %s:\n" + " far 0x%08x fsr 0x%08x\n" + " r0 0x%08x 0x%08x 0x%08x 0x%08x\n" + " r4 0x%08x 0x%08x 0x%08x 0x%08x\n" + " r8 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n" + " sp 0x%08x lr 0x%08x spsr 0x%08x\n", + kind, arm_decode_mode(frame->spsr), frame->pc, arm_abort_decode_status(fsr), far, fsr, + frame->r[0], frame->r[1], frame->r[2], frame->r[3], + frame->r[4], frame->r[5], frame->r[6], frame->r[7], + frame->r[8], frame->r[9], frame->r[10], frame->r[11], frame->r[12], + frame->sp, frame->lr, frame->spsr); +#else + panic("ARM %s abort in %s mode at 0x%08x\n" + " r0 0x%08x 0x%08x 0x%08x 0x%08x\n" + " r4 0x%08x 0x%08x 0x%08x 0x%08x\n" + " r8 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n" + " sp 0x%08x lr 0x%08x spsr 0x%08x\n", + kind, arm_decode_mode(frame->spsr), frame->pc, + frame->r[0], frame->r[1], frame->r[2], frame->r[3], + frame->r[4], frame->r[5], frame->r[6], frame->r[7], + frame->r[8], frame->r[9], frame->r[10], frame->r[11], frame->r[12], + frame->sp, frame->lr, frame->spsr); +#endif +} + +void +arm_irq() /* __attribute__ ((naked)) */ +{ +#if WITH_FIQ_TIMER + // Currently only defined on M7, M7 uses a FIQ for thetimer, and we need to hold off timer interrupts + // until we are done running ISR code to prevent unwanted preemption (e.g. ) + arm_disable_fiqs(); +#endif + _irq_enter_critical_section(); + platform_irq(); + _irq_exit_critical_section(); +#if WITH_FIQ_TIMER + arm_enable_fiqs(); +#endif +} + +void +arm_fiq() /* __attribute__ ((naked)) */ +{ + _irq_enter_critical_section(); + platform_fiq(); + _irq_exit_critical_section(); +} + +/* + * Accessors for exception frame information. + * + * These may return NULL if we don't believe the frame requested is currently valid. + * + * Note that not all possible cases of nesting are necessarily handled here; only those + * that are likely to be interesting in the case of a fatality. + */ +static struct arm_exception_frame * +arm_get_exception_frame(void) +{ + /* + * As exceptions are considered fatal, we don't expect to be asked for + * the exception frame in any other context. + */ + switch (CPSR_MODE(arm_read_cpsr())) { + case CPSR_MODE_ABORT: + case CPSR_MODE_UNDEFINED: + return((struct arm_exception_frame *)exc_stack_top - 1); + default: + return(NULL); + } +} + +static struct arm_exception_frame * +arm_get_interrupt_frame(void) +{ + switch (CPSR_MODE(arm_read_cpsr())) { + case CPSR_MODE_ABORT: + case CPSR_MODE_UNDEFINED: + /* + * In some configurations the IRQ and exception stacks share a top, + * in which case we can't return the IRQ frame because the exception + * frame has overwritten it. + */ + if (&irq_stack_top == &exc_stack_top) + return(NULL); + + /* + * If we took an exception while servicing an interrupt, the IRQ frame + * will be valid. + */ + if (CPSR_MODE_IRQ != arm_get_exception_frame()->spsr) + return(NULL); + break; + + case CPSR_MODE_IRQ: + /* we're in interrupt mode, so the frame is valid */ + break; + + case CPSR_MODE_FIQ: + /* + * If we took a FIQ while in interrupt mode, the IRQ frame will be + * valid. + */ + if (CPSR_MODE_IRQ != CPSR_MODE(arm_get_fiq_frame()->spsr)) + return(NULL); + break; + + default: + /* the interrupt frame is invalid in other modes */ + return(NULL); + } + return ((struct arm_exception_frame *)irq_stack_top - 1); +} + +static struct arm_exception_frame * +arm_get_fiq_frame(void) +{ + switch (CPSR_MODE(arm_read_cpsr())) { + case CPSR_MODE_ABORT: + case CPSR_MODE_UNDEFINED: + /* + * If we took an exception while servicing a FIQ, the frame + * will be valid. + */ + if (CPSR_MODE_FIQ != CPSR_MODE(arm_get_exception_frame()->spsr)) + return(NULL); + break; + + case CPSR_MODE_FIQ: + /* we're in FIQ mode, so the frame is valid */ + break; + + default: + /* the FIQ frame is invalid in other modes */ + return(NULL); + } + return((struct arm_exception_frame *)fiq_stack_top - 1); +} + +/* + * arm_print_frame_registers + * + * Print the registers from an exception frame. + */ +static void +arm_print_frame_registers(struct arm_exception_frame *frame, const char *prefix) +{ + dprintf(DEBUG_CRITICAL, + "%sr0 0x%08x 0x%08x 0x%08x 0x%08x\n" + "%sr4 0x%08x 0x%08x 0x%08x 0x%08x\n" + "%sr8 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n" + "%spc 0x%08x sp 0x%08x lr 0x%08x spsr 0x%08x\n", + prefix, frame->r[0], frame->r[1], frame->r[2], frame->r[3], + prefix, frame->r[4], frame->r[5], frame->r[6], frame->r[7], + prefix, frame->r[8], frame->r[9], frame->r[10], frame->r[11], frame->r[12], + prefix, frame->pc, frame->sp, frame->lr, frame->spsr); +} + +/* + * arm_backtrace + * + * Print a backtrace until we run out of frames on the stack. + */ +static void +arm_backtrace(const char *prefix, u_int32_t pc, u_int32_t fp, u_int32_t stack_base, u_int32_t stack_len) +{ + u_int32_t prev_fp; + u_int32_t stack_top; + u_int32_t *fpp; + + /* print the mode prefix and current pc for starters */ + dprintf(DEBUG_CRITICAL, " %10s 0x%08x 0x%08x\n", prefix, pc, fp); + + /* sanity check our arguments as much as we can */ + if ((stack_base % 4) || /* bump these to CPU_CACHELINE_SIZE if/when stack allocation gets smarter */ + (stack_len % 4) || + (stack_len < 16) || + (stack_len > 100 * 1024)) { + dprintf(DEBUG_CRITICAL, "improbable stack, base %p size 0x%08x (task smashed?)\n", (void *)stack_base, stack_len); + return; + } + + /* loop unwinding frames until we leave the stack region */ + prev_fp = stack_base; + stack_top = stack_base + stack_len; + for (;;) { + /* + * Frame pointer must be aligned, must be above the previous frame, must not point outside the stack. + * + * It would be nice to have a sentinel to allow differentiating clean termination from a smashed + * stack, but that would require support in the interrupt and exception handlers. + */ + if ((fp % 4) || (fp <= prev_fp) || (fp > stack_top)) + return; + + /* + * Looks like it's inside the stack, so go ahead and deref it. + */ + fpp = (u_int32_t *)fp; + prev_fp = fp; + fp = fpp[0]; + + /* + * Print the return address for this frame. + */ + dprintf(DEBUG_CRITICAL, " 0x%08x 0x%08x\n", fpp[1], fp); + } +} + +/* + * arm_stack_for_status_reg + * + * Returns the base and size of the stack for the given status register value if it's "special". + */ +static void +arm_stack_for_status_reg(u_int32_t status_reg, u_int32_t *stack_base, u_int32_t *stack_len) +{ + *stack_base = 0; + *stack_len = 0; + +#ifdef STACK_BASE + *stack_base = (void *)STACK_BASE; + switch (CPSR_MODE(status_reg)) { + case CPSR_MODE_FIQ: + *stack_len = FIQ_STACK_SIZE; + break; + case CPSR_MODE_IRQ: + *stack_len = IRQ_STACK_SIZE; + break; + case CPSR_MODE_ABORT: + case CPSR_MODE_UNDEFINED: + *stack_len = EXCEPTION_STACK_SIZE; + break; + + } +#else + switch (CPSR_MODE(status_reg)) { + case CPSR_MODE_FIQ: + *stack_base = (u_int32_t)fiq_stack_top - FIQ_STACK_SIZE; + *stack_len = FIQ_STACK_SIZE; + break; + case CPSR_MODE_IRQ: + *stack_base = (u_int32_t)irq_stack_top - IRQ_STACK_SIZE; + *stack_len = IRQ_STACK_SIZE; + break; + case CPSR_MODE_ABORT: + case CPSR_MODE_UNDEFINED: + *stack_base = (u_int32_t)exc_stack_top - EXCEPTION_STACK_SIZE; + *stack_len = EXCEPTION_STACK_SIZE; + break; + } +#endif +} + +/* + * arch_backtrace_current_task + * + * Print a backtrace for the current task. + * + * We support being called with the following context nesting: + * + * supervisor + * supervisor interrupt + * supervisor FIQ + * supervisor exception + * supervisor interrupt FIQ + * supervisor interrupt exception + * supervisor FIQ exception + * supervisor interrupt FIQ exception + * + */ + +void +arch_backtrace_current_task(void *stack_base, size_t stack_len) +{ + struct arm_exception_frame *exception_frame, *fiq_frame, *interrupt_frame, *outer_frame; + u_int32_t esb, esl; + u_int32_t base, count, *insn, offending_pc; + + uintptr_t btext = (uintptr_t)__segment_start(__TEXT); + uintptr_t etext = (uintptr_t)__segment_end(__TEXT); + + /* + * Find the stack limits for the current context and then backtrace it. + */ + arm_stack_for_status_reg(arm_read_cpsr(), &esb, &esl); + if (0 == esl) { + esb = (u_int32_t)stack_base; + esl = stack_len; + } + arm_backtrace(arm_decode_mode(arm_read_cpsr()), + (u_int32_t)&arch_backtrace_current_task, (u_int32_t)__builtin_frame_address(0), + esb, esl); + + /* + * Find valid saved contexts, for the case where we may be in an exception state. + */ + exception_frame = arm_get_exception_frame(); + fiq_frame = arm_get_fiq_frame(); + interrupt_frame = arm_get_interrupt_frame(); + outer_frame = NULL; + + /* + * If we have a valid exception context, backtrace the context it was called from first. + * That context may be supervisor, FIQ or interrupt mode. If it was FIQ mode, we will + * dump the context the FIQ was called from next. + */ + if (NULL != exception_frame) { + + /* dump registers at entry to exception mode */ + arm_print_frame_registers(exception_frame, " "); + + /* + * If the exception handler thought that the data around the PC was worth + * displaying, and we think the PC was inside the text section, display it here. + */ + if (true == exception_dump_near_pc) { + offending_pc = exception_frame->pc; + if ((offending_pc >= btext) && (offending_pc <= etext)) { + if ((offending_pc - btext) < 8) { + base = btext; + } else { + base = offending_pc - 8; + } + dprintf(DEBUG_CRITICAL, " [0x%08x:", base); + for (count = 0; count < 4; count++) { + insn = (u_int32_t *)base + count; + dprintf(DEBUG_CRITICAL, " 0x%08x", *insn); + } + dprintf(DEBUG_CRITICAL, "]\n"); + } else { + dprintf(DEBUG_CRITICAL, " [pc 0x%08x not in text %p-%p]\n", + offending_pc, (void *)btext, (void *)etext); + } + } + + /* + * If the exception occurred in a context with a special stack (FIQ or interrupt) + * backtrace that stack here. + */ + arm_stack_for_status_reg(exception_frame->spsr, &esb, &esl); + if (0 != esl) { + arm_backtrace(arm_decode_mode(exception_frame->spsr), + exception_frame->pc, exception_frame->r[7], + esb, esl); + } else { + /* the outer context is in the exception frame */ + outer_frame = exception_frame; + } + } + + /* + * If we have a valid FIQ context, backtrace the context it was invoked from now. + */ + if (NULL != fiq_frame) { + + /* dump registers at entry to FIQ mode */ + arm_print_frame_registers(fiq_frame, " "); + + /* + * If the FIQ occurred from interrupt mode, backtrace the interrupt mode stack here. + */ + arm_stack_for_status_reg(fiq_frame->spsr, &esb, &esl); + if (0 != esl) { + arm_backtrace(arm_decode_mode(fiq_frame->spsr), + fiq_frame->pc, fiq_frame->r[7], + esb, esl); + } else { + /* the outer context is in the FIQ frame */ + outer_frame = fiq_frame; + } + } + + /* + * If we have an interrupt-saved context, fetch the task state from it. + */ + if (NULL != interrupt_frame) { + + /* dump registers at entry to interrupt mode */ + arm_print_frame_registers(interrupt_frame, " "); + + outer_frame = interrupt_frame; + } + + /* + * Print the task context backtrace from the outer frame. + */ + if (NULL != outer_frame) { + arm_backtrace(arm_decode_mode(outer_frame->spsr), + outer_frame->pc, outer_frame->r[7], + (u_int32_t)stack_base, (u_int32_t)stack_len); + } +} + +/* + * arch_backtrace_task + * + * Print a backtrace from a saved task context. + */ +void +arch_backtrace_task(struct arch_task *arch_task, void *stack_base, size_t stack_len) +{ + arm_backtrace("supervisor", arch_task->regs[ARM_ARCH_TASK_LR], arch_task->regs[ARM_ARCH_TASK_FP], + (u_int32_t)stack_base, (u_int32_t)stack_len); +} diff --git a/arch/arm/include/arch/arch_task.h b/arch/arm/include/arch/arch_task.h new file mode 100644 index 0000000..380c313 --- /dev/null +++ b/arch/arm/include/arch/arch_task.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2006-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __ARCH_TASK_H +#define __ARCH_TASK_H + +/* + * Note that this structure is known implicitly by code in context.S, and + * must be kept in sync. + */ +#if defined(__arm__) +#ifndef __ASSEMBLY__ +struct arch_task { + /* + * Core registers. + */ + uint32_t regs[10]; // r4-r11, r13, r14 + +#if WITH_VFP + /* + * VFP/Neon registers. + * + * Note that layout must be kept in sync with offset defines below. + */ + uint32_t fpexc; + uint32_t fpscr; + uint64_t fpregs[32]; +#endif +}; +#endif /* __ASSEMBLY__ */ + +/* + * Indices for useful core registers. + */ +#define ARM_ARCH_TASK_FP 3 +#define ARM_ARCH_TASK_SP 8 +#define ARM_ARCH_TASK_LR 9 + +/* + * VFP/Neon field offsets - it would be nice to generate these automatically. + */ +#define ARM_ARCH_TASK_FP_OFFSET 40 +#define ARM_ARCH_TASK_FPEXC (ARM_ARCH_TASK_FP_OFFSET + 0) +#define ARM_ARCH_TASK_FPSCR (ARM_ARCH_TASK_FP_OFFSET + 4) +#define ARM_ARCH_TASK_FPREGS (ARM_ARCH_TASK_FP_OFFSET + 8) + + +#elif defined(__arm64__) + +#ifndef __ASSEMBLY__ + +typedef __uint128_t uint128_t; + +struct arch_task { + /* Core registers */ + uint64_t regs[29]; // x0-x28 + uint64_t fp; + uint64_t lr; + uint64_t sp; +#if WITH_VFP + /* Neon registers */ + union { + uint128_t q; + uint64_t d; + uint32_t s; + } vregs[32]; // v0-v31 + uint32_t fpsr; + uint32_t fpcr; +#endif +}; +#endif /* __ASSEMBLY__ */ + +#endif /* __arm64__ */ + +#endif /* ! __ARCH_TASK_H */ diff --git a/arch/arm/include/arch/arm/arm.h b/arch/arm/include/arch/arm/arm.h new file mode 100644 index 0000000..7034702 --- /dev/null +++ b/arch/arm/include/arch/arm/arm.h @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __ARM_H +#define __ARM_H + +#ifndef __ASSEMBLER__ + +#include +#include +#include +#include + +__BEGIN_DECLS + +unsigned int arm_read_cpsr(void) __pure; + +unsigned int arm_read_main_id(void) __pure; +unsigned int arm_read_cache_id(void) __pure; +unsigned int arm_read_cache_level_id(void) __pure; +unsigned int arm_read_cache_size_selection(void) __pure; +void arm_write_cache_size_selection(unsigned int); +unsigned int arm_read_cache_size_id(void) __pure; + +void arm_read_memory_model_feature_regs(unsigned int regs[4]) __pure; +void arm_read_instruction_set_attribute_regs(unsigned int regs[6]) __pure; +void arm_read_extended_feature_regs(unsigned int regs[16]) __pure; + +unsigned int arm_read_cr(void) __pure; +void arm_write_cr(unsigned int cr); +unsigned int arm_read_aux_cr(void) __pure; +void arm_write_aux_cr(unsigned int cr); +unsigned int arm_read_perip_port_remap(void) __pure; +void arm_write_perip_port_remap(unsigned int val); + +extern uint32_t arm_read_cp_access_cr(void) __pure; +extern void arm_write_cp_access_cr(uint32_t val); + +extern void arm_fp_init(void); +extern void arm_fp_enable(bool); + +extern uint32_t arm_read_fpexc(void) __pure; +extern void arm_write_fpexc(uint32_t val); + +extern uint32_t arm_read_fpscr(void) __pure; +extern void arm_write_fpscr(uint32_t val); + +extern void arm_init_fp_regs(); + +#if ARCH_ARMv7 +extern uint32_t arm_read_l2_aux_cr(void) __pure; +extern void arm_write_l2_aux_cr(uint32_t val); + +typedef enum { + ARM_PMCR = 0, /* The order here matches a jump table in asm.S */ + ARM_PMCNTENSET, + ARM_PMCNTENCLR, + ARM_PMOVSR, + ARM_PMSWINC, + ARM_PMSELR, + + ARM_PMCCNTR, + ARM_PMXEVTYPER, + ARM_PMXEVCNTR, + + ARM_PMUSERNR, + ARM_PMINTENSET, + ARM_PMINTENCLR, +} arm_pmreg_t; + +extern uint32_t arm_read_pmreg(arm_pmreg_t reg) __pure; +extern void arm_write_pmreg(arm_pmreg_t reg, uint32_t val); +#endif /* ARCH_ARMv7 */ + +#if ARCH_ARMv8 + +extern void arm_write_mair(uint64_t mair); +extern void arm_write_tcr(uint64_t tcr); +extern void arm_write_ttbr0(void *ttbr0); +extern void arm_store_pte(uint64_t *ent_p, uint64_t ent); + +#if WITH_L2_AS_RAM +extern uint64_t arm_read_l2_cramconfig(void); +#endif + +#endif /* ARCH_ARMv8 */ + +void arm_mmu_init(bool resume); +void arm_mpu_init(void); + +uint32_t arm_get_noncached_address(uint32_t address); + +void arm_write_dar(unsigned int dar); +void arm_write_ttb(void *tt); +void arm_write_ttbcr(unsigned int ttbc); + +#if WITH_MMU +#define FSR_CAUSE_MASK ((1 << 10) | (0xF << 0)) +unsigned int arm_read_ifsr(void) __pure; +unsigned int arm_read_dfsr(void) __pure; +unsigned int arm_read_dfar(void) __pure; +unsigned int arm_read_ifar(void) __pure; +#else +# define arm_read_ifsr() ~0 +# define arm_read_dfsr() ~0 +# define arm_read_dfar() ~0 +# define arm_read_ifar() ~0 +#endif + +#if WITH_CACHE_DEBUG +void arm_l1cache_dump(int dcache, unsigned int addr); +#else +#define arm_l1cache_dump(dcache, addr) +#endif + +/* + * Exception frame saved at the top of the exception/interrupt stacks. + */ +struct arm_exception_frame { + uint32_t sp; /* saved stack pointer (r13) */ + uint32_t lr; /* saved link register (r14) */ + uint32_t spsr; /* saved cpsr */ + uint32_t r[13]; /* r0 - r12 */ + uint32_t pc; /* saved pc (r15) */ +}; + +struct arm_exception_frame64 { + uint64_t regs[29]; // x0-x28 + uint64_t fp; + uint64_t lr; + uint64_t sp; + uint32_t spsr; + uint32_t reserved0; + uint64_t pc; + uint64_t far; + uint32_t esr; + uint32_t reserved1; +}; + +extern void *irq_stack_top; /* stacks defined in start.S */ +extern void *fiq_stack_top; +extern void *exc_stack_top; +extern void *svc_stack_top; + +void arm_flush_tlbs(void); + +void arm_invalidate_dcache(void); +void arm_invalidate_icache(void); +void arm_clean_caches(void); +void arm_clean_dcache(void); +void arm_clean_dcache_line(addr_t addr); +void arm_clean_dcache_line_2(addr_t addr); +void arm_clean_dcache_line_3(addr_t addr); +void arm_clean_dcache_line_4(addr_t addr); +void arm_clean_dcache_line_5(addr_t addr); +void arm_clean_dcache_line_6(addr_t addr); +void arm_clean_dcache_line_7(addr_t addr); +void arm_clean_dcache_line_8(addr_t addr); +void arm_invalidate_dcache_line(addr_t addr); +void arm_invalidate_dcache_line_2(addr_t addr); +void arm_invalidate_dcache_line_3(addr_t addr); +void arm_invalidate_dcache_line_4(addr_t addr); +void arm_invalidate_dcache_line_5(addr_t addr); +void arm_invalidate_dcache_line_6(addr_t addr); +void arm_invalidate_dcache_line_7(addr_t addr); +void arm_invalidate_dcache_line_8(addr_t addr); +void arm_clean_invalidate_dcache_line(addr_t addr); +void arm_clean_invalidate_dcache_line_2(addr_t addr); +void arm_clean_invalidate_dcache_line_3(addr_t addr); +void arm_clean_invalidate_dcache_line_4(addr_t addr); +void arm_clean_invalidate_dcache_line_5(addr_t addr); +void arm_clean_invalidate_dcache_line_6(addr_t addr); +void arm_clean_invalidate_dcache_line_7(addr_t addr); +void arm_clean_invalidate_dcache_line_8(addr_t addr); +void arm_clean_invalidate_dcache(void); + +void arm_enable_l1parity(void); + +void arm_drain_write_buffer(void); + +void arm_flush_branch_predictor(void); + +void arm_init_vfp(void); +void arm_enable_vfp(void); +void arm_disable_vfp(void); + +void arm_enable_fiqs(void); +void arm_disable_fiqs(void); + +unsigned int arm_read_vbar(void); +void arm_write_vbar(unsigned int addr); + +void arm_memory_barrier(void); + +/* mmu stuff */ +#ifdef ARCH_ARMv8 + +typedef enum { + kARMMMUDeviceRX, + kARMMMUDeviceR, + kARMMMUDeviceRW, + kARMMMUNormalRX, + kARMMMUNormalR, + kARMMMUNormalRW, + kARMMMUNumExtendedAttr, +} arm_mmu_extended_attr_t; + +void arm_mmu_map_range(addr_t vaddr, addr_t paddr, size_t size, arm_mmu_extended_attr_t attr); + +// map in place using the specified attributes +void arm_mmu_map_rw(addr_t addr, size_t size); +void arm_mmu_map_rx(addr_t addr, size_t size); +void arm_mmu_map_ro(addr_t addr, size_t size); +void arm_mmu_map_device_rw(addr_t addr, size_t size); +void arm_mmu_map_device_rx(addr_t addr, size_t size); +void arm_mmu_map_device_ro(addr_t addr, size_t size); + +#else + +typedef enum { + kARMMMUStronglyOrdered = 0, + kARMMMUDevice, + kARMMMUNormal, + kARMMMUInnerNormalOuterNoncached, + kARMMMUWriteCombined, + kARMMMUNormalRX, + kARMMMUNumAttr, +} arm_mmu_attr_t; + +// Section and page mapping is explicit as there is always a fixed +// granule at each level (without LPAE) in ARMv4-ARMv7. +void arm_mmu_map_section(addr_t vaddr, addr_t paddr, arm_mmu_attr_t attr, bool shared); +void arm_mmu_map_section_range(addr_t vaddr, addr_t paddr, size_t sections, arm_mmu_attr_t attr, bool shared, bool flush); + +#endif + +/* mpu stuff */ +void mpu_init(void); +void arm_write_dprot_region_0(uint32_t base_size); +void arm_write_dprot_region_1(uint32_t base_size); +void arm_write_dprot_region_2(uint32_t base_size); +void arm_write_dprot_region_3(uint32_t base_size); +void arm_write_dprot_region_4(uint32_t base_size); +void arm_write_dprot_region_5(uint32_t base_size); +void arm_write_dprot_region_6(uint32_t base_size); +void arm_write_dprot_region_7(uint32_t base_size); +void arm_write_iprot_region_0(uint32_t base_size); +void arm_write_iprot_region_1(uint32_t base_size); +void arm_write_iprot_region_2(uint32_t base_size); +void arm_write_iprot_region_3(uint32_t base_size); +void arm_write_iprot_region_4(uint32_t base_size); +void arm_write_iprot_region_5(uint32_t base_size); +void arm_write_iprot_region_6(uint32_t base_size); +void arm_write_iprot_region_7(uint32_t base_size); +void arm_write_data_prot_register(uint32_t prot); +void arm_write_ins_prot_register(uint32_t prot); +void arm_write_cacheable_registers(uint32_t dcache, uint32_t icache); +void arm_write_bufferable_register(uint32_t buff); + +/* thread id */ +uint32_t arm_read_user_ro_tid(void) __pure; +uint32_t arm_read_user_rw_tid(void) __pure; +uint32_t arm_read_sup_tid(void) __pure; +void arm_write_user_ro_tid(uint32_t tid); +void arm_write_user_rw_tid(uint32_t tid); +void arm_write_sup_tid(uint32_t tid); + +/* DCC based debug */ +void arm_write_dcc_char(int c); +int arm_read_dcc_char(void); +int arm_read_dcc_char_nowait(void); +int arm_dcc_init(void); + +#if CPU_APPLE_SWIFT +extern uint32_t swift_read_l2cerrsts(void) __pure; +extern void swift_write_l2cerrsts(uint32_t l2cerrsts); +extern uint32_t swift_read_l2cerradr(void) __pure; +extern void swift_write_l2cerradr(uint32_t l2cerradr); +#endif /* CPU_APPLE_SWIFT */ + +/* FP support */ +#if WITH_VFP +void arm_call_fpsaved(void *arg, void (*func)(void *arg)); +#endif + +__END_DECLS + +#endif /* __ASSEMBLER__ */ + +#define CPSR_MODE(_x) ((_x) & 0x1f) +#define CPSR_MODE_USER 0x10 +#define CPSR_MODE_FIQ 0x11 +#define CPSR_MODE_IRQ 0x12 +#define CPSR_MODE_SUPERVISOR 0x13 +#define CPSR_MODE_ABORT 0x17 +#define CPSR_MODE_UNDEFINED 0x1b +#define CPSR_MODE_SYSTEM 0x1f + +#define CPSR_STATE_THUMB 0x20 + +#define CPACR_CP_BITS(_cp, _bits) ((_bits) << ((_cp) * 2)) +#define CPACR_CP_DENIED 0x0 +#define CPACR_CP_PRIVILEGED 0x1 +#define CPACR_CP_FULL 0x3 + +#define FPEXC_EX (1<<31) +#define FPEXC_EN (1<<30) +#define FPEXC_FP2V (1<<28) + +#define FPSCR_DEFAULT (1<<25) | (1<<24) // DN, FZ bits + +#endif diff --git a/arch/arm/include/arch/arm/assembler.h b/arch/arm/include/arch/arm/assembler.h new file mode 100644 index 0000000..bdf7aea --- /dev/null +++ b/arch/arm/include/arch/arm/assembler.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +/* + * Declare a globally-visible ARM function + */ +.macro ARM_FUNCTION + .text + .arm + .balign 4 + .global $0 +$0: +.endmacro + +/* + * Declare a globally-visible THUMB function + */ +.macro THUMB_FUNCTION + .text + .thumb_func $0 + .balign 2 + .global $0 +$0: +.endmacro + diff --git a/arch/arm/link.exp b/arch/arm/link.exp new file mode 100644 index 0000000..c0a2947 --- /dev/null +++ b/arch/arm/link.exp @@ -0,0 +1 @@ +_start diff --git a/arch/arm/mmu.c b/arch/arm/mmu.c new file mode 100644 index 0000000..f343a1a --- /dev/null +++ b/arch/arm/mmu.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2006-2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#define SECTION_SIZE MB +#define LARGE_PAGE_SIZE 65536 +#define PAGE_SIZE 4096 + +#define TTBCR_PD1 (1 << 5) + +typedef u_int32_t tt_ent; + +/* needs to be in non-static, initialized data for successful patching + * during IOP firmware loading */ +u_int32_t tt_size __attribute__((used)) = MMU_TT_SIZE; +tt_ent *tt = (void *)0xffffffff; + +/* ARM MMU first-level section descriptor definitions */ +#define ARM_DESC_SECT ((0 << 18) | (1 << 1)) +#define ARM_SECT_B (1 << 2) +#define ARM_SECT_C (1 << 3) +#define ARM_SECT_XN (1 << 4) +#define ARM_SECT_DOMAIN(_d) ((_d) << 5) +#define ARM_SECT_TEX(_t) ((_t) << 12) +#define ARM_SECT_SHARED (1 << 16) +#define ARM_SECT_FULLACC ((0 << 15) | (3 << 10)) +#define ARM_SECT_EXEC (ARM_SECT_DOMAIN(0)) +#define ARM_SECT_NOEXEC (ARM_SECT_DOMAIN(1) | ARM_SECT_XN) +#define ARM_SECT_READ_ONLY (1 << 15) + +/* Non-normal memory needs XN set (and consequently a client domain assignment) to avoid + * instruction prefetch to those regions */ +static u_int32_t sect_flags[] = { + [kARMMMUStronglyOrdered] = ARM_SECT_NOEXEC | ARM_SECT_FULLACC, + [kARMMMUDevice] = ARM_SECT_NOEXEC | ARM_SECT_B | ARM_SECT_FULLACC, + [kARMMMUNormal] = ARM_SECT_EXEC | ARM_SECT_C | ARM_SECT_B | ARM_SECT_FULLACC, + [kARMMMUInnerNormalOuterNoncached] = ARM_SECT_EXEC | ARM_SECT_TEX(4) | ARM_SECT_C | ARM_SECT_B | ARM_SECT_FULLACC, + [kARMMMUWriteCombined] = ARM_SECT_NOEXEC | ARM_SECT_TEX(1) | ARM_SECT_FULLACC, + [kARMMMUNormalRX] = ARM_SECT_DOMAIN(1) | ARM_SECT_C | ARM_SECT_B | ARM_SECT_READ_ONLY | ARM_SECT_FULLACC, +}; + +static tt_ent attr_to_sect_flags(arm_mmu_attr_t attr) +{ + if (attr >= kARMMMUNumAttr) + attr = kARMMMUStronglyOrdered; + return sect_flags[attr]; +} + +void arm_mmu_map_section(addr_t vaddr, addr_t paddr, arm_mmu_attr_t attr, bool shared) +{ + if ((vaddr & (SECTION_SIZE - 1)) != 0) + panic("section virtual address base is nonzero"); + if ((paddr & (SECTION_SIZE - 1)) != 0) + panic("section physical address base is nonzero"); + + tt[vaddr / MB] = paddr | ARM_DESC_SECT | attr_to_sect_flags(attr) | (shared ? ARM_SECT_SHARED : 0); + + arm_clean_dcache_line((unsigned long)&tt[vaddr / MB]); + arm_flush_tlbs(); +} + +void arm_mmu_map_section_range(addr_t vaddr, addr_t paddr, size_t sections, arm_mmu_attr_t attr, bool shared, bool flush) +{ + tt_ent entry, *tt_ptr; + addr_t flush_start, flush_stop; + u_int32_t cnt; + + if ((vaddr & (SECTION_SIZE - 1)) != 0) + panic("section range virtual address base is nonzero"); + if ((paddr & (SECTION_SIZE - 1)) != 0) + panic("section range physical address base is nonzero"); + + entry = paddr | ARM_DESC_SECT | attr_to_sect_flags(attr) | (shared ? ARM_SECT_SHARED : 0); + tt_ptr = &tt[vaddr / MB]; + + while (sections > 0) { + cnt = (sections < 16) ? sections : 16; + switch (cnt) { + case 16 : tt_ptr[15] = entry + MB * 15; + case 15 : tt_ptr[14] = entry + MB * 14; + case 14 : tt_ptr[13] = entry + MB * 13; + case 13 : tt_ptr[12] = entry + MB * 12; + case 12 : tt_ptr[11] = entry + MB * 11; + case 11 : tt_ptr[10] = entry + MB * 10; + case 10 : tt_ptr[ 9] = entry + MB * 9; + case 9 : tt_ptr[ 8] = entry + MB * 8; + case 8 : tt_ptr[ 7] = entry + MB * 7; + case 7 : tt_ptr[ 6] = entry + MB * 6; + case 6 : tt_ptr[ 5] = entry + MB * 5; + case 5 : tt_ptr[ 4] = entry + MB * 4; + case 4 : tt_ptr[ 3] = entry + MB * 3; + case 3 : tt_ptr[ 2] = entry + MB * 2; + case 2 : tt_ptr[ 1] = entry + MB * 1; + case 1 : tt_ptr[ 0] = entry + MB * 0; + } + + entry += MB * cnt; + tt_ptr += cnt; + sections -= cnt; + } + + if (flush) { + flush_start = ((addr_t)&tt[vaddr / MB]) & ~CPU_CACHELINE_SIZE; + flush_stop = ((addr_t)tt_ptr + (CPU_CACHELINE_SIZE - 1)) & ~CPU_CACHELINE_SIZE; + + while (flush_start < flush_stop) { + arm_clean_dcache_line(flush_start); + + flush_start += CPU_CACHELINE_SIZE; + } + + arm_flush_tlbs(); + } +} + +void arm_mmu_init(bool resume) +{ +#ifdef MMU_TT_BASE + /* TT usually at the end of memory */ + tt = (tt_ent *)MMU_TT_BASE; +#endif + + if (false == resume) { + /* identity map everything using the translation table as noncached */ + arm_mmu_map_section_range(0, 0, MMU_TT_SIZE / sizeof(tt_ent), kARMMMUStronglyOrdered, false, false); + } + + /* let the platform code get a shot at mapping some ranges */ + platform_mmu_setup(resume); + + /* set up the domain register */ + arm_write_dar(0x7); /* domain 0 manager, domain 1 client */ + + /* write the new translation table */ +#if MMU_TT_SIZE == 0x4000 + arm_write_ttbcr(0); +#elif (MMU_TT_SIZE == 0x1000) && (WITH_MMU_SECURITY_EXTENSIONS) + arm_write_ttbcr(2 | TTBCR_PD1); +#else +#error "Must set up TTBCR appropriately for translation table smaller than 16 kB" +#endif + arm_write_ttb(tt); + + arm_flush_tlbs(); +} + +u_int32_t arm_get_noncached_address(u_int32_t address) +{ +#ifdef MMU_NONCACHE0_SIZE + if (((int32_t)(address - MMU_NONCACHE0_PBASE) >= 0) && ((address - MMU_NONCACHE0_PBASE) < MMU_NONCACHE0_SIZE)) { + return address - MMU_NONCACHE0_PBASE + MMU_NONCACHE0_VBASE; + } +#endif + +#ifdef MMU_NONCACHE1_SIZE + if (((int32_t)(address - MMU_NONCACHE1_PBASE) >= 0) && ((address - MMU_NONCACHE1_PBASE) < MMU_NONCACHE1_SIZE)) { + return address - MMU_NONCACHE1_PBASE + MMU_NONCACHE1_VBASE; + } +#endif + + return 0xFFFFFFFF; +} diff --git a/arch/arm/mpu.c b/arch/arm/mpu.c new file mode 100644 index 0000000..444820f --- /dev/null +++ b/arch/arm/mpu.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include + +void arm_mpu_init(void) +{ + /* set everything as fully cached, except for the hardware register region */ + arm_write_iprot_region_0(0x0000003f); + arm_write_dprot_region_0(0x0000003f); +#ifdef PERIPH_BASE + arm_write_dprot_region_1((PERIPH_BASE | (0x1F - ((PERIPH_LEN == 0) ? 0 : (__builtin_clz(PERIPH_LEN) + 1))) << 1) | 1); +#endif + arm_write_ins_prot_register(0x3); // region 0 full access + arm_write_data_prot_register(0xf); // region 0 & 1 full access + arm_write_cacheable_registers(0x1, 0x1); // region 0 data and instruction is cacheable + arm_write_bufferable_register(0x1); // data region 0 is write bufferable +} + diff --git a/arch/arm/rules.mk b/arch/arm/rules.mk new file mode 100644 index 0000000..f8e6941 --- /dev/null +++ b/arch/arm/rules.mk @@ -0,0 +1,248 @@ +# Copyright (C) 2007-2010 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# +# ARM CPU config +# + +# sanity check +ifeq ($(ARM_CPU),) +$(error ARM_CPU is not set) +endif + +ifneq ($(ARM_ARCH),) +$(info ARM_ARCH does not need to be set at the platform level) +endif + +################################################################################ +# Per-CPU configuration +################################################################################ + +# +# Apple Swift +# +ifeq ($(ARM_CPU),apple-swift) +ARM_ARCH ?= armv7 +ARM_ARCH_OPTIONS := ARCH_ARMv7=1 WITH_VFP=1 +OPTIONS += \ + CPU_APPLE_SWIFT=1 \ + WITH_MMU=1 \ + WITH_MMU_SECURITY_EXTENSIONS=1 \ + WITH_CACHE=1 \ + CPU_CACHELINE_SIZE=64 \ + CPU_CACHELINE_SHIFT=6 \ + CPU_CACHEINDEX_SHIFT=8 \ + CPU_CACHESET_SHIFT=3 \ + WITH_BRANCH_PREDICTION=1 \ + WITH_UNALIGNED_MEM=1 \ + WITH_L1_PARITY=1 \ + PAGE_SIZE=4096 +ALL_OBJS += \ + $(LOCAL_DIR)/cache_v7.o \ + $(LOCAL_DIR)/mmu.o \ + $(LOCAL_DIR)/fp.o +endif + +# +# ARM Cortex A8 +# +ifeq ($(ARM_CPU),cortex-a8) +ARM_ARCH ?= armv7 +ARM_ARCH_OPTIONS := ARCH_ARMv7=1 WITH_VFP=1 +OPTIONS += \ + CPU_ARM_CORTEX_A8=1 \ + WITH_MMU=1 \ + WITH_MMU_SECURITY_EXTENSIONS=1 \ + WITH_CACHE=1 \ + CPU_CACHELINE_SIZE=64 \ + CPU_CACHELINE_SHIFT=6 \ + CPU_CACHEINDEX_SHIFT=7 \ + CPU_CACHESET_SHIFT=2 \ + WITH_BRANCH_PREDICTION=1 \ + WITH_UNALIGNED_MEM=1 \ + WITH_L1_PARITY=1 \ + WITH_CACHE_DEBUG=1 \ + WITH_ARCHITECTED_L2=1 \ + WITH_AUX_L2_ENABLE_BIT=1 \ + PAGE_SIZE=4096 +ALL_OBJS += \ + $(LOCAL_DIR)/cache_v7.o \ + $(LOCAL_DIR)/mmu.o \ + $(LOCAL_DIR)/fp.o \ + $(LOCAL_DIR)/cachedebug_a8.o + +# Turned off to save space, enable as needed +ifeq ($(APPLICATION),XXX_iBoot) +ALL_OBJS += \ + $(LOCAL_DIR)/cortex_hang.o \ + $(LOCAL_DIR)/cortex_debug.o +endif +endif + +# +# ARM Cortex A9 +# +ifeq ($(ARM_CPU),cortex-a9) +ARM_ARCH ?= armv7 +ARM_ARCH_OPTIONS := ARCH_ARMv7=1 WITH_VFP=1 +OPTIONS += \ + CPU_ARM_CORTEX_A9=1 \ + WITH_MMU=1 \ + WITH_MMU_SECURITY_EXTENSIONS=1 \ + WITH_CACHE=1 \ + CPU_CACHELINE_SIZE=32 \ + CPU_CACHELINE_SHIFT=5 \ + CPU_CACHEINDEX_SHIFT=8 \ + CPU_CACHESET_SHIFT=2 \ + WITH_BRANCH_PREDICTION=1 \ + WITH_UNALIGNED_MEM=1 \ + WITH_L1_PARITY=1 \ + SET_AUX_SMP_BIT=1 \ + PAGE_SIZE=4096 +ALL_OBJS += \ + $(LOCAL_DIR)/cache_v7.o \ + $(LOCAL_DIR)/mmu.o \ + $(LOCAL_DIR)/fp.o +endif + +# +# ARM Cortex A5 "Sparrow" +# +ifeq ($(ARM_CPU),cortex-a5) +ARM_ARCH ?= armv7 +ARM_ARCH_OPTIONS := ARCH_ARMv7=1 WITH_VFP=1 +OPTIONS += \ + CPU_ARM_CORTEX_A5=1 \ + FP_REGISTER_COUNT=32 \ + WITH_MMU=1 \ + WITH_MMU_SECURITY_EXTENSIONS=1 \ + WITH_CACHE=1 \ + CPU_CACHELINE_SIZE=32 \ + CPU_CACHELINE_SHIFT=5 \ + CPU_CACHEINDEX_SHIFT=8 \ + CPU_CACHESET_SHIFT=2 \ + WITH_BRANCH_PREDICTION=1 \ + WITH_UNALIGNED_MEM=1 \ + SET_AUX_SMP_BIT=1 \ + PAGE_SIZE=4096 +ALL_OBJS += \ + $(LOCAL_DIR)/cache_v7.o \ + $(LOCAL_DIR)/mmu.o \ + $(LOCAL_DIR)/fp.o +endif + +# +# ARM Cortex A7 "Kingfisher" +# +ifeq ($(ARM_CPU),cortex-a7) +ARM_ARCH ?= armv7k +ARM_ARCH_OPTIONS := ARCH_ARMv7=1 WITH_VFP=1 WITH_VFP_ALWAYS_ON=1 +OPTIONS += \ + CPU_ARM_CORTEX_A7=1 \ + VFP_REV=4 \ + FP_REGISTER_COUNT=32 \ + WITH_MMU=1 \ + WITH_MMU_SECURITY_EXTENSIONS=1 \ + WITH_CACHE=1 \ + WITH_EARLY_ICACHE=1 \ + CPU_CACHELINE_SIZE=64 \ + CPU_CACHELINE_SHIFT=6 \ + CPU_CACHEINDEX_SHIFT=7 \ + CPU_CACHESET_SHIFT=2 \ + WITH_BRANCH_PREDICTION=1 \ + WITH_UNALIGNED_MEM=1 \ + WITH_ARCHITECTED_L2=1 \ + SET_AUX_SMP_BIT=1 \ + PAGE_SIZE=4096 +ALL_OBJS += \ + $(LOCAL_DIR)/cache_v7.o \ + $(LOCAL_DIR)/mmu.o \ + $(LOCAL_DIR)/fp.o +endif + +################################################################################ +# General and conditional configuration +################################################################################ + +# sanity check +ifeq ($(ARM_ARCH),) +$(error ARM_ARCH not set, no valid CPU selected) +endif + +# build for the proper cpu +OPTIONS += ARCH_ARM=1 +GLOBAL_ALLFLAGS += -arch $(ARM_ARCH) $(addprefix -D,$(ARM_ARCH_OPTIONS)) +GLOBAL_LDFLAGS += -arch $(ARM_ARCH) + +# Tell the build system how libraries should be tagged +LIBRARY_TAG += $(ARM_ARCH) +LIBRARY_OPTIONS += ARCH=arm ARM_ARCH=$(ARM_ARCH) + +# Always build libbuiltin, to partially override the gcc static library. +LIBRARY_MODULES += lib/libbuiltin + +# set up to build with thumb +WITH_THUMB ?= true +ifeq ($(WITH_THUMB),true) +THUMBFLAGS := -mthumb +LIBRARY_TAG += thumb +else +THUMBFLAGS := -mno-thumb +LIBRARY_TAG += arm +endif + +GLOBAL_ALLFLAGS += $(THUMBFLAGS) +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# Defaults for stack sizes +# These are override in platform/.../rules.mk +ifeq ($(IRQ_STACK_SIZE),) + IRQ_STACK_SIZE ?= 2048 +endif +ifeq ($(FIQ_STACK_SIZE),) + FIQ_STACK_SIZE ?= 1024 +endif +ifeq ($(EXCEPTION_STACK_SIZE),) + EXCEPTION_STACK_SIZE ?= 2048 +endif +ifeq ($(BOOTSTRAP_STACK_SIZE),) + BOOTSTRAP_STACK_SIZE ?= 2048 +endif +OPTIONS += \ + IRQ_STACK_SIZE=$(IRQ_STACK_SIZE) \ + FIQ_STACK_SIZE=$(FIQ_STACK_SIZE) \ + EXCEPTION_STACK_SIZE=$(EXCEPTION_STACK_SIZE) \ + BOOTSTRAP_STACK_SIZE=$(BOOTSTRAP_STACK_SIZE) + +# Force start.o and asm.o to link first +ALL_OBJS := \ + $(LOCAL_DIR)/start.o \ + $(LOCAL_DIR)/asm.o \ + $(ALL_OBJS) + +# Code common to all cores +ALL_OBJS += \ + $(LOCAL_DIR)/cpu.o \ + $(LOCAL_DIR)/context.o \ + $(LOCAL_DIR)/entropy.o \ + $(LOCAL_DIR)/exceptions.o \ + $(LOCAL_DIR)/handlers.o \ + $(LOCAL_DIR)/task.o + +LINKER_EXPORTS := $(LOCAL_DIR)/link.exp + +# if someone requests DCC, add it in +ifeq ($(WITH_DCC),true) +OPTIONS += ARM_DCC_SYNCHRONOUS=1 +include $(LOCAL_DIR)/dcc/rules.mk +endif + diff --git a/arch/arm/start.S b/arch/arm/start.S new file mode 100644 index 0000000..009da35 --- /dev/null +++ b/arch/arm/start.S @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + + .text + .balign 4 + .no_dead_strip _start + .global _start + +_start: + b __reset + + ldr pc, vectoraddr + 4 + ldr pc, vectoraddr + 8 + ldr pc, vectoraddr + 12 + ldr pc, vectoraddr + 16 + ldr pc, vectoraddr + 20 + ldr pc, vectoraddr + 24 + ldr pc, vectoraddr + 28 + +vectoraddr: + .word __reset + .word ___arm_undefined + .word ___arm_syscall + .word ___arm_prefetch_abort + .word ___arm_data_abort + .word ___arm_reserved + .word ___arm_irq + .word ___arm_fiq + +__reset: + /* + * Test the running versus desired the start of the text + * to determine if relocaiton is required + */ + adr r0, _start + ldr r1, L_TEXT_START + cmp r0, r1 + +#ifdef PLATFORM_START_FUNCTION + /* + * r0 and r1 must be preserved + * 'eq' will be true if no text relocation is required + */ + bl PLATFORM_START_FUNCTION +#endif + + /* re-test the running start versus desired start of the text */ + cmp r0, r1 + beq __do_relocate_data + + /* relocate to the desired text location and branch to it */ + ldr r2, L_TEXT_END + sub r2, r2, r1 +__relocate_loop: + subs r2, r2, #4 + ldr r3, [r0, r2] + str r3, [r1, r2] + bne __relocate_loop + +#if ARCH_ARMv7 + /* prevent speculation to the desired text location */ + dsb + isb +#endif + + /* branch into the desired text location */ + bx r1 + + /* test if the data if needs to be relocated */ +__do_relocate_data: + ldr r0, L_DATA_RO_START + mov r1, #0x00001000 // Round up to a 4K page + sub r1, r1, #1 // + add r0, r0, r1 // + bic r0, r0, r1 // + ldr r1, L_DATA_START + cmp r0, r1 + beq __stacksetup + + /* relocate the data */ + ldr r2, L_DATA_END + sub r2, r2, r1 +__relocate_data_loop: + subs r2, r2, #4 + ldr r3, [r0, r2] + str r3, [r1, r2] + bne __relocate_data_loop + +__stacksetup: + /* set up the stack for irq, fiq, abort, undefined, and lastly supervisor mode */ + mrs r0, cpsr + bic r0, r0, #0x1f + + orr r1, r0, #0x12 // irq + msr cpsr_c, r1 + mov lr, #0 + ldr sp, _irq_stack_top + + orr r1, r0, #0x11 // fiq + msr cpsr_c, r1 + mov lr, #0 + ldr sp, _fiq_stack_top + + orr r1, r0, #0x17 // abort + msr cpsr_c, r1 + mov lr, #0 + ldr sp, _exc_stack_top + + orr r1, r0, #0x1b // undefined + msr cpsr_c, r1 + mov lr, #0 + ldr sp, _exc_stack_top + + orr r1, r0, #0x13 // supervisor + msr cpsr_c, r1 + ldr sp, _svc_stack_top + +#if ARCH_ARMv7 + mrs r1, cpsr + bic r1, #0x100 // enable imprecise data aborts + msr cpsr_x, r1 +#endif + +#if SUPPORT_SLEEP + /* look at the global wakeup flag, avoid clearing the BSS and go straight to wake up */ +.global _platform_wakeup + ldr r1, _arch_sleep_magic /* will be zero on the wake path, nonzero otherwise */ + eor r0, r0, r0 + cmp r0, r1 + bne __do_bss + ldr r0, L__platform_wakeup + mov lr, pc + bx r0 +#endif + +__do_bss: + /* clear the bss section */ + ldr r0, L_BSS_START + ldr r1, L_BSS_END + mov r2, #0 + mov r3, #0 + mov r4, #0 + mov r5, #0 + mov r6, #0 + mov r7, #0 + mov r8, #0 + mov r10, #0 + sub r12, r1, r0 + /* If there are less than 256 bytes, skip this loop */ + subs r12, r12, #256 + blo __bss_lessthan256 + +__bss_loop256: + /* Clear 256 bytes at a time */ + subs r12, #256 + stmia r0!, {r2-r8, r10} + stmia r0!, {r2-r8, r10} + stmia r0!, {r2-r8, r10} + stmia r0!, {r2-r8, r10} + stmia r0!, {r2-r8, r10} + stmia r0!, {r2-r8, r10} + stmia r0!, {r2-r8, r10} + stmia r0!, {r2-r8, r10} + bge __bss_loop256 + +__bss_lessthan256: + /* If are less than 32 bytes left to handle, skip this loop */ + adds r12, r12, #(256 - 32) + bcc __bss_lessthan32 + +__bss_loop32: + /* Clear 32 bytes at a time */ + subs r12, r12, #32 + stmia r0!, {r2-r8, r10} + bge __bss_loop32 + +__bss_lessthan32: + /* If there's nothing left to go, skip this loop */ + adds r12, r12, #32 + beq __bss_done + +__bss_loop4: + /* Clear 4 bytes at a time */ + subs r12, r12, #4 + str r2, [r0],#4 + bgt __bss_loop4 + +__bss_done: + /* branch to main */ + ldr r0, L__main + mov lr, pc + bx r0 + b . + + + .org 0x200 +L__build_banner_string: + .ascii CONFIG_PROGNAME_STRING + .ascii " for " + .ascii CONFIG_BOARD_STRING + .ascii ", Copyright 2007-2016, Apple Inc." + + .org 0x240 +L__build_style_string: + .ascii BUILD_STYLE + +/* This will get replaced by macho_post_process.py so that the build tag + is accurate even for iterative desktop builds that don't rebuild start.o */ + .org 0x280 +_build_tag_string_contents: + +/* Placeholder for macho_post_process.py. Placing the UUID here allows + debuggers to locate the UUID based on the address of the vectors */ + .org 0x300 +_UUID: + .space 0x20 + + .global _build_banner_string +_build_banner_string: + .long L__build_banner_string + + .global _build_style_string +_build_style_string: + .long L__build_style_string + + .global _build_tag_string +_build_tag_string: + .long _build_tag_string_contents + +L__main: + .long __main + + /* linked start and end addresses of the text */ +L_TEXT_START: + .long (TEXT_BASE) +L_TEXT_END: + .long section$start$__DATA$__zerofill + + /* start address of the data in the read only text */ +L_DATA_RO_START: + .long segment$end$__TEXT + + /* linked start and end addresses of the data */ +L_DATA_START: + .long segment$start$__DATA +L_DATA_END: + .long section$start$__DATA$__zerofill + + /* linked start and end addresses of the zero-filled range */ +L_BSS_START: + .long section$start$__DATA$__zerofill +L_BSS_END: + .long segment$end$__DATA + + /* + * Stacks. + * + * The following stacks must be defined: + * + * bootstrap stack + * Used as the stack for the initial thread. + * + * exception stack + * Used when handling exceptions other than interrupts. + * + * interrupt stack + * Used when handling regular interrupts. + * + * fiq stack + * Used when handling FIQ interrupts. + */ + + .global _irq_stack_top + .global _fiq_stack_top + .global _exc_stack_top + .global _svc_stack_top + +#ifndef STACK_SIZE + /* + * This is a bit hokey, as the platform doesn't really know + * what the bootstrap stack size should be. + */ +# define STACK_SIZE BOOTSTRAP_STACK_SIZE +#endif +#if APPLICATION_EMBEDDEDIOP + /* + * Locally-allocated stacks. + */ +_irq_stack_top: + .long irq_stack + IRQ_STACK_SIZE +_fiq_stack_top: + .long fiq_stack + FIQ_STACK_SIZE +_exc_stack_top: + .long exc_stack + EXCEPTION_STACK_SIZE +_svc_stack_top: + .long svc_stack + STACK_SIZE + + /* allocate stacks here */ + .lcomm irq_stack, IRQ_STACK_SIZE, 4 + .lcomm fiq_stack, FIQ_STACK_SIZE, 4 + .lcomm exc_stack, EXCEPTION_STACK_SIZE, 4 + .lcomm svc_stack, STACK_SIZE, 4 + +#elif defined(STACK_BASE) + /* + * Simple stack layout with just one allocation in STACK_BASE/STACK_SIZE + * supplied by the platform definition. + * + * Bootstrap stack starts at the top of the allocation, + * exception stack and interrupt stack share the same + * chunk at the bottom. + */ +_fiq_stack_top: + .long STACK_BASE + FIQ_STACK_SIZE +_exc_stack_top: +_irq_stack_top: + .long STACK_BASE + IRQ_STACK_SIZE +_svc_stack_top: + .long STACK_BASE + STACK_SIZE +#else +# error No stack defined +#endif + +#if SUPPORT_SLEEP +.global _arch_sleep_magic +_arch_sleep_magic: + .long 0xffffffff + +L__platform_wakeup: + .long _platform_wakeup + +#endif diff --git a/arch/arm/task.c b/arch/arm/task.c new file mode 100644 index 0000000..f2e670d --- /dev/null +++ b/arch/arm/task.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include + +static void arch_task_trampoline(void) __noreturn; + +static void +arch_task_trampoline(void) +{ + /* exit the critical section we implicitly started with */ + exit_critical_section(); + + dprintf(DEBUG_SPEW, "arch_task_trampoline: task %p (%s) routine %p, arg %p\n", + current_task, current_task->name, current_task->routine, current_task->arg); + + /* call the start routine */ + int ret = current_task->routine(current_task->arg); + + dprintf(DEBUG_SPEW, "arch_task_trampoline: task %p (%s) exits with %d\n", + current_task, current_task->name, ret); + + task_exit(ret); + + /* never return */ +} + +int +arch_task_create(struct task *t) +{ + int i; + + for (i=0; i < 10; i++) + t->arch.regs[i] = 0; + + /* set the default starting point to be arch_task_trampoline */ + t->arch.regs[ARM_ARCH_TASK_LR] = (uint32_t)&arch_task_trampoline; + /* the ARM describes some encodings of SP ops (pre/post increment and/or decrement) as + potentially reaching above the SP by a word. Our toolchain might not emit such encodings, + but we'd rather be safe than sorry. Originally, we took off 4 bytes, but + to better align the stacks for some of the newer ABIs (e.g. armv7k), we'll consistently + take off 16 bytes from the top of the stack */ + t->arch.regs[ARM_ARCH_TASK_SP] = (uint32_t)t->stack_base + t->stack_len - 16; + t->arch.regs[ARM_ARCH_TASK_FP] = 0; + +#if WITH_VFP + t->arch.fpexc = 0; /* default state is FP disabled */ +#endif + + return 0; +} diff --git a/arch/arm64/asm.S b/arch/arm64/asm.S new file mode 100644 index 0000000..eff6b41 --- /dev/null +++ b/arch/arm64/asm.S @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2011-2012, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + + .text + .align 2 + .globl _arm_read_sctlr +_arm_read_sctlr: + mrs x0, SCTLR_ELx + ret + + .text + .align 2 + .globl _arm_write_sctlr +_arm_write_sctlr: + msr SCTLR_ELx, x0 + dsb sy + isb sy + // The ifdef should match the ifdef in arch_cpu_quiesce() +#if CPU_APPLE_CYCLONE + // Don't allow MMU or WXN to be disabled. Placing the check after the msr + // means that a ROP attack will fail unless an attacker can trigger an + // interrupt between the msr and check + mov x1, x0 + orr x0, x0, #SCTLR_M_ENABLED + orr x0, x0, #SCTLR_WXN_ENABLED + cmp x0, x1 + b.ne _arm_write_sctlr +#endif + ret + +#if WITH_EL3 + .text + .align 2 + .globl _arm_write_scr +_arm_write_scr: + msr SCR_EL3, x0 + isb sy + ret +#endif + +#if WITH_L2_AS_RAM + .text + .align 2 + .globl _arm_read_l2_cramconfig +_arm_read_l2_cramconfig: + mrs x0, s3_3_c15_c7_0 + ret +#endif + + .text + .align 2 + .globl _arm_write_mair +_arm_write_mair: + msr MAIR_ELx, x0 + isb sy + ret + + .text + .align 2 + .globl _arm_write_tcr +_arm_write_tcr: + msr TCR_ELx, x0 + isb sy + ret + + .text + .align 2 + .globl _arm_write_ttbr0 +_arm_write_ttbr0: + msr TTBR0_ELx, x0 + isb sy + ret + + + .text + .align 2 + .globl _arm_read_cpacr +_arm_read_cpacr: + mrs x0, CPACR_EL1 + ret + + .text + .align 2 + .globl _arm_write_cpacr +_arm_write_cpacr: + msr CPACR_EL1, x0 + isb sy + ret + + .text + .align 2 + .globl _arm_read_cntp_ctl +_arm_read_cntp_ctl: + isb sy + mrs x0, CNTP_CTL_EL0 + ret + + .text + .align 2 + .globl _arm_write_cntp_ctl +_arm_write_cntp_ctl: + msr CNTP_CTL_EL0, x0 + isb sy + ret + + .text + .align 2 + .globl _arm_read_cntpct +_arm_read_cntpct: + isb sy + mrs x0, CNTPCT_EL0 + ret + + .text + .align 2 + .globl _arm_write_cntp_tval +_arm_write_cntp_tval: + msr CNTP_TVAL_EL0, x0 + isb sy + ret + + .text + .align 2 + .globl _arm_flush_tlbs +_arm_flush_tlbs: + dsb sy +#if WITH_EL3 + tlbi alle3 +#else + tlbi vmalle1 +#endif + dsb sy + isb sy + ret + + .text + .align 2 + .globl _arm_invalidate_icache +_arm_invalidate_icache: + ic iallu + dsb sy + isb sy + ret + + .text + .align 2 + .globl _arm_invalidate_dcache_line +_arm_invalidate_dcache_line: + ret + + .text + .align 2 + .globl _arm_clean_dcache_line +_arm_clean_dcache_line: + ret + + .text + .align 2 + .globl _arm_clean_invalidate_dcache +_arm_clean_invalidate_dcache: + ret + + .text + .align 2 + .globl _arm_clean_dcache +_arm_clean_dcache: + ret + + .text + .align 2 + .globl _arm_invalidate_dcache +_arm_invalidate_dcache: + ret + + .text + .align 2 + .globl _arm_clean_invalidate_dcache_line +_arm_clean_invalidate_dcache_line: + dc civac, x0 + ret + + .text + .align 2 + .globl _arm_drain_write_buffer +_arm_drain_write_buffer: + ret + + .text + .align 2 + .globl _arm_memory_barrier +_arm_memory_barrier: + dmb sy + ret + + .text + .align 2 + .globl _arm_vtop +_arm_vtop: + mrs x2, DAIF // Load current DAIF + msr DAIFSet, #(DAIFSC_IRQF | DAIFSC_FIQF) // Disable IRQ + isb sy + mov x9, x0 // Saved address + at s1e3r, x0 // Translation Stage 1 EL1 + isb sy + mrs x1, PAR_EL1 // Read result + tst x1, #1 // Test Translation not valid + cset x0, eq + b.ne L_arm_vtop_ret + movk x3, #0xf000 + movk x3, #0xffff, lsl #16 + movk x3, #0xffff, lsl #32 + and x1, x1, x3 // Get physical address base + and x0, x9, #0xfff + orr x0, x1, x0 // Add page offset +L_arm_vtop_ret: + msr DAIF, x2 // Restore interrupt state, return + isb sy + ret + + .text + .align 2 + .globl _arm_disable_async_aborts +_arm_disable_async_aborts: + msr DAIFSet, #(DAIFSC_ASYNCF) + isb sy + ret + + .text + .align 2 + .globl _arm_enable_async_aborts +_arm_enable_async_aborts: + msr DAIFClr, #(DAIFSC_ASYNCF) + isb sy + ret + + .text + .align 2 + .globl _arch_disable_ints +_arch_disable_ints: + msr DAIFSet, #(DAIFSC_IRQF | DAIFSC_FIQF) + isb sy + ret + + .text + .align 2 + .globl _arch_enable_ints +_arch_enable_ints: + msr DAIFClr, #(DAIFSC_IRQF | DAIFSC_FIQF) + isb sy + ret + + .text + .align 2 + .globl _arch_halt +_arch_halt: + dsb sy + isb sy + wfi + ret + + .text + .align 2 + .globl _arch_spin +_arch_spin: + hint 0x45 // make fastsim drop to debugger (nop on hardware) + b . diff --git a/arch/arm64/context.S b/arch/arm64/context.S new file mode 100644 index 0000000..71f1f59 --- /dev/null +++ b/arch/arm64/context.S @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Task context switch support. + * + */ + +/* + * Code here must remain synchronized with the structure and offsets defined in arch_task.h: + * + * struct arch_task { + * uint64_t regs[29]; // x0-x28 + * uint64_t fp; + * uint64_t lr; + * uint64_t sp; + * + * union { + * uint128_t q; + * uint64_t d; + * uint32_t s; + * } vregs[32]; // v0-v31 + * uint32_t fpsr; + * uint32_t fpcr; + * }; + */ + +/* AAPCS-64 5.1.1 Page 13: + * Preserve r16-17, r19-r28, FP, and SP. + * + * AAPCS-64 5.1.2 Page 14: + * Registers d8-d15 (s8-s15) must be preserved by a callee across subroutine + * calls; the remaining registers (v0-v7, v16-v31) do not need to be preserved + * (or should be preserved by the caller). + */ + +/* + * void arch_task_context_switch(struct arch_task *old, struct arch_task *new_task); + */ + + .text + .align 2 + .globl _arch_task_context_switch +_arch_task_context_switch: + stp x16, x17, [x0, #120] + stp x19, x20, [x0, #152] + stp x21, x22, [x0, #168] + stp x23, x24, [x0, #184] + stp x25, x26, [x0, #200] + stp x27, x28, [x0, #216] + stp fp, lr, [x0, #232] + mov x2, sp + str x2, [x0, #248] + +#if WITH_VFP + str d8, [x0, #384] + str d9, [x0, #400] + str d10, [x0, #416] + str d11, [x0, #432] + str d12, [x0, #448] + str d13, [x0, #464] + str d14, [x0, #480] + str d15, [x0, #496] +#endif + + mov x0, x1 + b _arch_task_context_restore + +/* + * void arch_task_context_restore(struct arch_task *restore_context) + */ + + .text + .align 2 + .globl _arch_task_context_restore +_arch_task_context_restore: + ldp x16, x17, [x0, #120] + ldp x19, x20, [x0, #152] + ldp x21, x22, [x0, #168] + ldp x23, x24, [x0, #184] + ldp x25, x26, [x0, #200] + ldp x27, x28, [x0, #216] + ldp fp, lr, [x0, #232] + ldr x1, [x0, #248] + mov sp, x1 + +#if WITH_VFP + ldr d8, [x0, #384] + ldr d9, [x0, #400] + ldr d10, [x0, #416] + ldr d11, [x0, #432] + ldr d12, [x0, #448] + ldr d13, [x0, #464] + ldr d14, [x0, #480] + ldr d15, [x0, #496] +#endif + + ret + diff --git a/arch/arm64/cpu.c b/arch/arm64/cpu.c new file mode 100644 index 0000000..4003e74 --- /dev/null +++ b/arch/arm64/cpu.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011-2012, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +extern void arm_write_sctlr(uint64_t); +extern uint64_t arm_read_sctlr(); +extern void arm_enable_async_aborts(); +#if WITH_EL3 +extern void arm_write_scr(uint64_t); +#endif + +int arch_cpu_init(bool resume) +{ + uint64_t sctlr; + +#if WITH_EL3 + uint64_t scr; + + /* enable interrupts forwarding to EL3 */ + scr = (SCR_EA | SCR_FIQ | SCR_IRQ); + arm_write_scr(scr); +#endif + + /* enable async aborts */ + arm_enable_async_aborts(); + + /* invalidate caches */ + arm_invalidate_icache(); + arm_invalidate_dcache(); + + sctlr = arm_read_sctlr(); + + /* turn on Stack Alignment check */ + sctlr |= SCTLR_SA_ENABLED; + + /* turn on the mmu */ + arm_mmu_init(resume); + sctlr |= SCTLR_M_ENABLED; + + /* disallow executing from writeable pages */ + sctlr |= SCTLR_WXN_ENABLED; + + /* turn on d-cache */ + sctlr |= SCTLR_D_ENABLED; + + /* turn on i-cache */ + sctlr |= SCTLR_I_ENABLED; + + /* enable the MMU, caches and etc. */ + arm_write_sctlr(sctlr); + +#if WITH_VFP + /* initialize VFP */ + arm_fp_init(); +#endif + + return 0; +} + +int arch_cpu_quiesce(void) +{ +#if !CPU_APPLE_CYCLONE + uint64_t sctlr; + + /* clean the d-cache */ + arm_clean_dcache(); + + /* read the control regiser base value */ + sctlr = arm_read_sctlr(); + + sctlr &= ~(SCTLR_D_ENABLED | SCTLR_SA_ENABLED | SCTLR_I_ENABLED | SCTLR_M_ENABLED | SCTLR_WXN_ENABLED); + + /* disable the MMU, caches and etc. */ + arm_write_sctlr(sctlr); + + /* invalidate i-cache */ + arm_invalidate_icache(); +#endif /* !CPU_APPLE_CYCLONE */ + + return 0; +} + +int arch_cpu_init_posttasks(void) +{ + return 0; +} + diff --git a/arch/arm64/entropy.S b/arch/arm64/entropy.S new file mode 100644 index 0000000..945c74b --- /dev/null +++ b/arch/arm64/entropy.S @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + + .text + .balign 4 + .globl _arch_get_entropy + +// u_int32_t arch_get_entropy(volatile u_int32_t *counter_address) +// +// arch_get_entropy exploits the uncertainty in the asynchronous boundary crossing +// between the CPU and a counter. To work correctly, the CPU and counter must be +// derived from clocks with relative jitter (PLL vs. OSC). Ideally the inner loop, +// up to 32 iterations, should consume a large part of the effective read period of +// the counter. +// + +_arch_get_entropy: + + mov x1, x0 + mov w0, #0 + mov w2, #32 +1: + mov w3, w2 +2: + subs w3, w3, #1 + b.ne 2b + ldr w3, [x1] + and w3, w3, #1 + orr w0, w3, w0, lsl #1 + subs w2, w2, #1 + b.ne 1b + ret diff --git a/arch/arm64/exceptions_el1.S b/arch/arm64/exceptions_el1.S new file mode 100644 index 0000000..d868140 --- /dev/null +++ b/arch/arm64/exceptions_el1.S @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2011-2012, 2014 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#if WITH_EL3 +#error "This file should not be built for platforms WITH_EL3" +#endif + +//////////////////////////////////////////////////////////// +// This is what exception frame looks like: +// +// struct arm_exception_frame64 { +// uint64_t regs[29]; // x0-x28 +// uint64_t fp; +// uint64_t lr; +// uint64_t sp; +// uint32_t spsr; +// uint32_t reserved0; +// uint64_t pc; +// uint64_t far; +// uint32_t esr; +// uint32_t reserved1; +// uint64_t reserved2; // stp requires multiple of 16 in imm field +// uint64_t reserved3; // stp requires multiple of 16 in imm field +// union { +// uint128_t q; +// uint64_t d; +// uint32_t s; +// } vregs[32]; // v0-v31 +// uint32_t fpsr; +// uint32_t reserved4; +// uint32_t fpcr; +// uint32_t reserved5; +// }; +//////////////////////////////////////////////////////////// + +.macro EL1_SP0_VECTOR + msr SPSel, #0 // Switch to SP0 + sub sp, sp, #832 // Create exception frame + stp x0, x1, [sp, #0] // Save x0, x1 to exception frame + add x0, sp, #832 // Calculate the original stack pointer + str x0, [sp, #248] // Save stack pointer to exception frame + stp fp, lr, [sp, #232] // Save fp and lr to exception frame + mrs lr, ELR_EL1 // Get exception link reg so _dispatch64 can make a frame + mov x0, sp // Copy saved state pointer to x0 +.endmacro + +.macro FASTSIM_DEBUG_HINT + hint 0x45 // make fastsim drop to debugger (nop on hardware) +.endmacro + + .text + .align 12 + .globl _exception_vector_base +_exception_vector_base: +L__el1_sp0_synchronous_vector: + EL1_SP0_VECTOR + mrs x1, ESR_EL1 // Load exception syndrome + str x1, [x0, #280] + mrs x1, FAR_EL1 // Load fault address + str x1, [x0, #272] + adrp x1, _arm_synchronous_exception@page + add x1, x1, _arm_synchronous_exception@pageoff + b __dispatch64 + + .text + .align 7 +L__el1_sp0_irq_vector: + EL1_SP0_VECTOR + adrp x1, _interrupt_stack_top@page + add x1, x1, _interrupt_stack_top@pageoff + ldr x1, [x1] + mov sp, x1 + adrp x1, _arm_irq@page + add x1, x1, _arm_irq@pageoff + b __dispatch64 + + .text + .align 7 +L__el1_sp0_fiq_vector: + EL1_SP0_VECTOR + adrp x1, _interrupt_stack_top@page + add x1, x1, _interrupt_stack_top@pageoff + ldr x1, [x1] + mov sp, x1 + adrp x1, _arm_fiq@page + add x1, x1, _arm_fiq@pageoff + b __dispatch64 + + .text + .align 7 +L__el1_sp0_serror_vector: + EL1_SP0_VECTOR + mrs x1, ESR_EL1 // Load exception syndrome + str x1, [x0, #280] + mrs x1, FAR_EL1 // Load fault address + str x1, [x0, #272] + adrp x1, _arm_serror_exception@page + add x1, x1, _arm_serror_exception@pageoff + b __dispatch64 + + .text + .align 7 +L__el1_sp1_synchronous_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__el1_sp1_irq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__el1_sp1_fiq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__el1_sp1_serror_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_64_synchronous_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_64_irq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_64_fiq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_64_serror_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_synchronous_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_irq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_fiq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_serror_vector: + FASTSIM_DEBUG_HINT + b . + +/* Placeholder for macho_post_process.py. Placing the UUID here + allows debuggers to locate the UUID based on the value of VBAR */ + .text + .align 7 +_UUID: + .space 32 + +/* 64-bit first level exception handler dispatcher. +* Completes register context saving and branches to FLEH. +* Expects: +* {x0, x1, fp, lr, sp} - saved +* x0 - arm_context_t +* x1 - address of FLEH +* fp - previous stack frame if EL1 +* lr - unused +* sp - kernel stack +*/ + .text + .align 2 +__dispatch64: + stp fp, lr, [sp, #-16]! // Create a frame to help debuggers unwind + mov fp, sp // past the exception handler + stp x2, x3, [x0, #16] // Save remaining GPRs + stp x4, x5, [x0, #32] + stp x6, x7, [x0, #48] + stp x8, x9, [x0, #64] + stp x10, x11, [x0, #80] + stp x12, x13, [x0, #96] + stp x14, x15, [x0, #112] + stp x16, x17, [x0, #128] + stp x18, x19, [x0, #144] + stp x20, x21, [x0, #160] + stp x22, x23, [x0, #176] + stp x24, x25, [x0, #192] + stp x26, x27, [x0, #208] + str x28, [x0, #224] + mrs lr, ELR_EL1 // Get exception link register + str lr, [x0, #264] // Save ELR to PCB + mrs x2, SPSR_EL1 // Get CPSR + str w2, [x0, #256] // Save CPSR to PCB + +#if WITH_VFP + stp q0, q1, [x0, #304] + stp q2, q3, [x0, #336] + stp q4, q5, [x0, #368] + stp q6, q7, [x0, #400] + stp q8, q9, [x0, #432] + stp q10, q11, [x0, #464] + stp q12, q13, [x0, #496] + stp q14, q15, [x0, #528] + stp q16, q17, [x0, #560] + stp q18, q19, [x0, #592] + stp q20, q21, [x0, #624] + stp q22, q23, [x0, #656] + stp q24, q25, [x0, #688] + stp q26, q27, [x0, #720] + stp q28, q29, [x0, #752] + stp q30, q31, [x0, #784] + mrs x2, FPSR + str w2, [x0, #816] + mrs x2, FPCR + str w2, [x0, #820] +#endif + + mov x21, x0 // Copy arm_context_t pointer to x21 + blr x1 + b __exception_return + + .text + .align 2 +__exception_return: + mov sp, x21 // Reload the arm_context_t pointer + +#if WITH_VFP + ldp q0, q1, [sp, #304] + ldp q2, q3, [sp, #336] + ldp q4, q5, [sp, #368] + ldp q6, q7, [sp, #400] + ldp q8, q9, [sp, #432] + ldp q10, q11, [sp, #464] + ldp q12, q13, [sp, #496] + ldp q14, q15, [sp, #528] + ldp q16, q17, [sp, #560] + ldp q18, q19, [sp, #592] + ldp q20, q21, [sp, #624] + ldp q22, q23, [sp, #656] + ldp q24, q25, [sp, #688] + ldp q26, q27, [sp, #720] + ldp q28, q29, [sp, #752] + ldp q30, q31, [sp, #784] + ldr w3, [sp, #816] + msr FPSR, x3 + ldr w4, [sp, #820] + msr FPCR, x4 +#endif + + ldr x0, [sp, #264] // Get the return address + msr ELR_EL1, x0 // Load the return address into ELR + ldr w1, [sp, #256] // Get the return CPSR + msr SPSR_EL1, x1 // Load the return CPSR into SPSR + ldp x0, x1, [sp, #0] // Restore the GPRs + ldp x2, x3, [sp, #16] + ldp x4, x5, [sp, #32] + ldp x6, x7, [sp, #48] + ldp x8, x9, [sp, #64] + ldp x10, x11, [sp, #80] + ldp x12, x13, [sp, #96] + ldp x14, x15, [sp, #112] + ldp x16, x17, [sp, #128] + ldp x18, x19, [sp, #144] + ldp x20, x21, [sp, #160] + ldp x22, x23, [sp, #176] + ldp x24, x25, [sp, #192] + ldp x26, x27, [sp, #208] + ldr x28, [sp, #224] + ldp fp, lr, [sp, #232] + + /* Use exception stack to restore SP0 */ + + msr SPSel, #1 // Switch to SPx + stp x0, x1, [sp, #-16]! // Save x0 and x1 + mrs x0, SP_EL0 // Reload the pcb pointer from SP0 + ldr x1, [x0, #248] // Get the saved SP from the pcb + msr SP_EL0, x1 // Restore SP0 + ldp x0, x1, [sp], #16 // Restore x0 and x1 + eret diff --git a/arch/arm64/exceptions_el3.S b/arch/arm64/exceptions_el3.S new file mode 100644 index 0000000..2bc118d --- /dev/null +++ b/arch/arm64/exceptions_el3.S @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2011-2012, 2014 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#if !WITH_EL3 +#error "This file should only be built for platforms WITH_EL3" +#endif + +//////////////////////////////////////////////////////////// +// This is what exception frame looks like: +// +// struct arm_exception_frame64 { +// uint64_t regs[29]; // x0-x28 +// uint64_t fp; +// uint64_t lr; +// uint64_t sp; +// uint32_t spsr; +// uint32_t reserved0; +// uint64_t pc; +// uint64_t far; +// uint32_t esr; +// uint32_t reserved1; +// uint64_t reserved2; // stp requires multiple of 16 in imm field +// uint64_t reserved3; // stp requires multiple of 16 in imm field +// union { +// uint128_t q; +// uint64_t d; +// uint32_t s; +// } vregs[32]; // v0-v31 +// uint32_t fpsr; +// uint32_t reserved4; +// uint32_t fpcr; +// uint32_t reserved5; +// }; +//////////////////////////////////////////////////////////// + +.macro EL3_SP0_VECTOR + msr SPSel, #0 // Switch to SP0 + sub sp, sp, #832 // Create exception frame + stp x0, x1, [sp, #0] // Save x0, x1 to exception frame + add x0, sp, #832 // Calculate the original stack pointer + str x0, [sp, #248] // Save stack pointer to exception frame + stp fp, lr, [sp, #232] // Save fp and lr to exception frame + mrs lr, ELR_EL3 // Get exception link reg so _dispatch64 can make a frame + mov x0, sp // Copy saved state pointer to x0 +.endmacro + +.macro FASTSIM_DEBUG_HINT + hint 0x45 // make fastsim drop to debugger (nop on hardware) +.endmacro + + .text + .align 12 + .globl _exception_vector_base +_exception_vector_base: +L__el3_sp0_synchronous_vector: + EL3_SP0_VECTOR + mrs x1, ESR_EL3 // Load exception syndrome + str x1, [x0, #280] + mrs x1, FAR_EL3 // Load fault address + str x1, [x0, #272] + adrp x1, _arm_synchronous_exception@page + add x1, x1, _arm_synchronous_exception@pageoff + b __dispatch64 + + .text + .align 7 +L__el3_sp0_irq_vector: + EL3_SP0_VECTOR + adrp x1, _interrupt_stack_top@page + add x1, x1, _interrupt_stack_top@pageoff + ldr x1, [x1] + mov sp, x1 + adrp x1, _arm_irq@page + add x1, x1, _arm_irq@pageoff + b __dispatch64 + + .text + .align 7 +L__el3_sp0_fiq_vector: + EL3_SP0_VECTOR + adrp x1, _interrupt_stack_top@page + add x1, x1, _interrupt_stack_top@pageoff + ldr x1, [x1] + mov sp, x1 + adrp x1, _arm_fiq@page + add x1, x1, _arm_fiq@pageoff + b __dispatch64 + + .text + .align 7 +L__el3_sp0_serror_vector: + EL3_SP0_VECTOR + mrs x1, ESR_EL3 // Load exception syndrome + str x1, [x0, #280] + mrs x1, FAR_EL3 // Load fault address + str x1, [x0, #272] + adrp x1, _arm_serror_exception@page + add x1, x1, _arm_serror_exception@pageoff + b __dispatch64 + + .text + .align 7 +L__el3_sp3_synchronous_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__el3_sp3_irq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__el3_sp3_fiq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__el3_sp3_serror_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_64_synchronous_vector: + // Monitor (EL3) call. + // Check "smc #0x5ec3" was executed and no other reason code. + movz x1, #0x5ec3 + movk x1, #0x5e00, lsl #16 + mrs x2, ESR_EL3 + cmp x1, x2 + b.eq 1f + FASTSIM_DEBUG_HINT + b . +1: // Got here from an "smc". Branch to x0. + br x0 + + .text + .align 7 +L__elx_64_irq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_64_fiq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_64_serror_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_synchronous_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_irq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_fiq_vector: + FASTSIM_DEBUG_HINT + b . + + .text + .align 7 +L__elx_32_serror_vector: + FASTSIM_DEBUG_HINT + b . + +/* Placeholder for macho_post_process.py. Placing the UUID here + allows debuggers to locate the UUID based on the value of VBAR */ + .text + .align 7 +_UUID: + .space 32 + +/* 64-bit first level exception handler dispatcher. +* Completes register context saving and branches to FLEH. +* Expects: +* {x0, x1, fp, lr, sp} - saved +* x0 - arm_context_t +* x1 - address of FLEH +* fp - previous stack frame if EL1 +* lr - unused +* sp - kernel stack +*/ + .text + .align 2 +__dispatch64: + stp fp, lr, [sp, #-16]! // Create a frame to help debuggers unwind + mov fp, sp // past the exception handler + stp x2, x3, [x0, #16] // Save remaining GPRs + stp x4, x5, [x0, #32] + stp x6, x7, [x0, #48] + stp x8, x9, [x0, #64] + stp x10, x11, [x0, #80] + stp x12, x13, [x0, #96] + stp x14, x15, [x0, #112] + stp x16, x17, [x0, #128] + stp x18, x19, [x0, #144] + stp x20, x21, [x0, #160] + stp x22, x23, [x0, #176] + stp x24, x25, [x0, #192] + stp x26, x27, [x0, #208] + str x28, [x0, #224] + mrs lr, ELR_EL3 // Get exception link register + str lr, [x0, #264] // Save ELR to PCB + mrs x2, SPSR_EL3 // Get CPSR + str w2, [x0, #256] // Save CPSR to PCB + +#if WITH_VFP + stp q0, q1, [x0, #304] + stp q2, q3, [x0, #336] + stp q4, q5, [x0, #368] + stp q6, q7, [x0, #400] + stp q8, q9, [x0, #432] + stp q10, q11, [x0, #464] + stp q12, q13, [x0, #496] + stp q14, q15, [x0, #528] + stp q16, q17, [x0, #560] + stp q18, q19, [x0, #592] + stp q20, q21, [x0, #624] + stp q22, q23, [x0, #656] + stp q24, q25, [x0, #688] + stp q26, q27, [x0, #720] + stp q28, q29, [x0, #752] + stp q30, q31, [x0, #784] + mrs x2, FPSR + str w2, [x0, #816] + mrs x2, FPCR + str w2, [x0, #820] +#endif + + mov x21, x0 // Copy arm_context_t pointer to x21 + blr x1 + b __exception_return + + .text + .align 2 +__exception_return: + mov sp, x21 // Reload the arm_context_t pointer + +#if WITH_VFP + ldp q0, q1, [sp, #304] + ldp q2, q3, [sp, #336] + ldp q4, q5, [sp, #368] + ldp q6, q7, [sp, #400] + ldp q8, q9, [sp, #432] + ldp q10, q11, [sp, #464] + ldp q12, q13, [sp, #496] + ldp q14, q15, [sp, #528] + ldp q16, q17, [sp, #560] + ldp q18, q19, [sp, #592] + ldp q20, q21, [sp, #624] + ldp q22, q23, [sp, #656] + ldp q24, q25, [sp, #688] + ldp q26, q27, [sp, #720] + ldp q28, q29, [sp, #752] + ldp q30, q31, [sp, #784] + ldr w3, [sp, #816] + msr FPSR, x3 + ldr w4, [sp, #820] + msr FPCR, x4 +#endif + + ldr x0, [sp, #264] // Get the return address + msr ELR_EL3, x0 // Load the return address into ELR + ldr w1, [sp, #256] // Get the return CPSR + msr SPSR_EL3, x1 // Load the return CPSR into SPSR + ldp x0, x1, [sp, #0] // Restore the GPRs + ldp x2, x3, [sp, #16] + ldp x4, x5, [sp, #32] + ldp x6, x7, [sp, #48] + ldp x8, x9, [sp, #64] + ldp x10, x11, [sp, #80] + ldp x12, x13, [sp, #96] + ldp x14, x15, [sp, #112] + ldp x16, x17, [sp, #128] + ldp x18, x19, [sp, #144] + ldp x20, x21, [sp, #160] + ldp x22, x23, [sp, #176] + ldp x24, x25, [sp, #192] + ldp x26, x27, [sp, #208] + ldr x28, [sp, #224] + ldp fp, lr, [sp, #232] + + /* Use exception stack to restore SP0 */ + + msr SPSel, #1 // Switch to SPx + stp x0, x1, [sp, #-16]! // Save x0 and x1 + mrs x0, SP_EL0 // Reload the pcb pointer from SP0 + ldr x1, [x0, #248] // Get the saved SP from the pcb + msr SP_EL0, x1 // Restore SP0 + ldp x0, x1, [sp], #16 // Restore x0 and x1 + eret diff --git a/arch/arm64/fp.c b/arch/arm64/fp.c new file mode 100644 index 0000000..2eded31 --- /dev/null +++ b/arch/arm64/fp.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012-2013 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include + +/* + * VFP/Neon support + */ + +#if WITH_VFP + +extern uint32_t arm_read_cpacr(); +extern void arm_write_cpacr(uint32_t); + +void arm_fp_init(void) +{ + uint32_t cpacr; + + /* v8: CPACR FPEN bits [21:20] needs to be programmed correctly to avoid a trap */ + cpacr = arm_read_cpacr(); + cpacr |= (3 << 20); + arm_write_cpacr(cpacr); +} + +bool arch_task_fp_enable(bool enable) +{ + return true; +} + +#endif /* WITH_VFP */ diff --git a/arch/arm64/handlers.c b/arch/arm64/handlers.c new file mode 100644 index 0000000..8e6f3a3 --- /dev/null +++ b/arch/arm64/handlers.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +extern void platform_irq(void); + +typedef enum { + ESR_EC_UNCATEGORIZED = 0x00, + ESR_EC_TRAP_SIMD_FP = 0x07, + ESR_EC_ILLEGAL_INSTR_SET = 0x0c, + ESR_EC_SVC_32 = 0x11, + ESR_EC_SVC_64 = 0x15, + ESR_EC_MSR_TRAP = 0x18, + ESR_EC_IABORT_EL0 = 0x20, + ESR_EC_IABORT_EL1 = 0x21, + ESR_EC_PC_ALIGN = 0x22, + ESR_EC_DABORT_EL0 = 0x24, + ESR_EC_DABORT_EL1 = 0x25, + ESR_EC_SP_ALIGN = 0x26 +} esr_exception_class_t; + +typedef enum { + FSC_TRANSLATION_FAULT_L0 = 0x04, + FSC_TRANSLATION_FAULT_L1 = 0x05, + FSC_TRANSLATION_FAULT_L2 = 0x06, + FSC_TRANSLATION_FAULT_L3 = 0x07, + FSC_ACCESS_FLAG_FAULT_L1 = 0x09, + FSC_ACCESS_FLAG_FAULT_L2 = 0x0A, + FSC_ACCESS_FLAG_FAULT_L3 = 0x0B, + FSC_PERMISSION_FAULT_L1 = 0x0D, + FSC_PERMISSION_FAULT_L2 = 0x0E, + FSC_PERMISSION_FAULT_L3 = 0x0F, + FSC_SYNC_EXT_ABORT = 0x10, + FSC_ASYNC_EXT_ABORT = 0x11, + FSC_SYNC_EXT_ABORT_TT_L1 = 0x15, + FSC_SYNC_EXT_ABORT_TT_L2 = 0x16, + FSC_SYNC_EXT_ABORT_TT_L3 = 0x17, + FSC_SYNC_PARITY = 0x18, + FSC_ASYNC_PARITY = 0x19, + FSC_SYNC_PARITY_TT_L1 = 0x1D, + FSC_SYNC_PARITY_TT_L2 = 0x1E, + FSC_SYNC_PARITY_TT_L3 = 0x1F, + FSC_ALIGNMENT_FAULT = 0x21, + FSC_DEBUG_FAULT = 0x22 +} fault_status_t; + +static const char *exception_codes[50] = { + [0x00] = "Unknown", + [0x0E] = "Illegal Instruction Set", + [0x21] = "Instruction Abort", + [0x22] = "PC Alignment", + [0x25] = "Data Abort", + [0x26] = "Stack Pointer Alignment", + [0x2F] = "SError", +}; + +void +arm_synchronous_exception(struct arm_exception_frame64 *frame) +{ + const char **kind; + + kind = &exception_codes[ESR_EC(frame->esr)]; + + panic("ARM synchronous abort at 0x%016llx:\n" + " esr 0x%08x (ec: %s, iss: 0x%08x) far 0x%016llx\n" + " x0 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x4 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x8 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x12 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x16 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x20 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x24 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x28 0x%016llx sp 0x%016llx lr 0x%016llx spsr 0x%08x\n", + frame->pc, + frame->esr, *kind, ESR_ISS(frame->esr), frame->far, + frame->regs[0], frame->regs[1], frame->regs[2], frame->regs[3], + frame->regs[4], frame->regs[5], frame->regs[6], frame->regs[7], + frame->regs[8], frame->regs[9], frame->regs[10], frame->regs[11], + frame->regs[12], frame->regs[13], frame->regs[14], frame->regs[15], + frame->regs[16], frame->regs[17], frame->regs[18], frame->regs[19], + frame->regs[20], frame->regs[21], frame->regs[22], frame->regs[23], + frame->regs[24], frame->regs[25], frame->regs[26], frame->regs[27], + frame->regs[28], frame->sp, frame->lr, frame->spsr); +} + +void +arm_serror_exception(struct arm_exception_frame64 *frame) +{ + const char **kind; + + kind = &exception_codes[ESR_EC(frame->esr)]; + + platform_asynchronous_exception(); + + panic("ARM SError abort at 0x%016llx:\n" + " esr 0x%08x (ec: %s, iss: 0x%08x) far 0x%016llx\n" + " x0 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x4 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x8 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x12 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x16 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x20 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x24 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n" + " x28 0x%016llx sp 0x%016llx lr 0x%016llx spsr 0x%08x\n", + frame->pc, + frame->esr, *kind, ESR_ISS(frame->esr), frame->far, + frame->regs[0], frame->regs[1], frame->regs[2], frame->regs[3], + frame->regs[4], frame->regs[5], frame->regs[6], frame->regs[7], + frame->regs[8], frame->regs[9], frame->regs[10], frame->regs[11], + frame->regs[12], frame->regs[13], frame->regs[14], frame->regs[15], + frame->regs[16], frame->regs[17], frame->regs[18], frame->regs[19], + frame->regs[20], frame->regs[21], frame->regs[22], frame->regs[23], + frame->regs[24], frame->regs[25], frame->regs[26], frame->regs[27], + frame->regs[28], frame->sp, frame->lr, frame->spsr); +} + +void +arm_irq() +{ + _irq_enter_critical_section(); + platform_irq(); + _irq_exit_critical_section(); +} diff --git a/arch/arm64/include/arch/arm64/proc_reg.h b/arch/arm64/include/arch/arm64/proc_reg.h new file mode 100644 index 0000000..9d72662 --- /dev/null +++ b/arch/arm64/include/arch/arm64/proc_reg.h @@ -0,0 +1,599 @@ +/* + * Copyright (c) 2007-2011, 2014 Apple Inc. All rights reserved. + */ +/* + * Processor registers for ARM64 + */ +#ifndef _ARM64_PROC_REG_H_ +#define _ARM64_PROC_REG_H_ + +// Pick the right registers depending on the exception level we're booting into. +#if WITH_EL3 +#define SCTLR_ELx SCTLR_EL3 +#define MAIR_ELx MAIR_EL3 +#define TCR_ELx TCR_EL3 +#define TTBR0_ELx TTBR0_EL3 +#define VBAR_ELx VBAR_EL3 +#else +#define SCTLR_ELx SCTLR_EL1 +#define MAIR_ELx MAIR_EL1 +#define TCR_ELx TCR_EL1 +#define TTBR0_ELx TTBR0_EL1 +#define VBAR_ELx VBAR_EL1 +#endif + +/* + * 64-bit Program Status Register (PSR64) + * + * 31 27 22 21 20 19 10 9 5 4 0 + * +-+-+-+-+------+--+--+----------+-+-+-+-+-+-----+ + * |N|Z|C|V|000000|SS|IL|0000000000|D|A|I|F|0| M | + * +-+-+-+-+-+----+--+--+----------+-+-+-+-+-+-----+ + * + * where: + * NZCV Comparison flags + * SS Single step + * IL Illegal state + * DAIF Interrupt masks + * M Mode field + */ + +#define PSR64_NZCV_SHIFT 28 +#define PSR64_NZCV_MASK (1 << PSR64_NZCV_SHIFT) + +#define PSR64_N_SHIFT 31 +#define PSR64_N (1 << PSR64_N_SHIFT) + +#define PSR64_Z_SHIFT 30 +#define PSR64_Z (1 << PSR64_Z_SHIFT) + +#define PSR64_C_SHIFT 29 +#define PSR64_C (1 << PSR64_C_SHIFT) + +#define PSR64_V_SHIFT 28 +#define PSR64_V (1 << PSR64_V_SHIFT) + +#define PSR64_SS_SHIFT 21 +#define PSR64_SS (1 << PSR64_SS_SHIFT) + +#define PSR64_IL_SHIFT 20 +#define PSR64_IL (1 << PSR64_IL_SHIFT) + +/* + * msr DAIF, Xn and mrs Xn, DAIF transfer into + * and out of bits 9:6 + */ +#define DAIF_DEBUG_SHIFT 9 +#define DAIF_DEBUGF (1 << DAIF_DEBUG_SHIFT) + +#define DAIF_ASYNC_SHIFT 8 +#define DAIF_ASYNCF (1 << DAIF_ASYNC_SHIFT) + +#define DAIF_IRQF_SHIFT 7 +#define DAIF_IRQF (1 << DAIF_IRQF_SHIFT) + +#define DAIF_FIQF_SHIFT 6 +#define DAIF_FIQF (1 << DAIF_FIQF_SHIFT) + +#define DAIF_ALL (DAIF_DEBUGF | DAIF_ASYNCF | DAIF_IRQF | DAIF_FIQF) +#define DAIF_STANDARD_DISABLE (DAIF_ASYNCF | DAIF_IRQF | DAIF_FIQF) + +#define SPSR_INTERRUPTS_ENABLED(x) (!(x & DAIF_FIQF)) + +/* + * msr DAIFSet, Xn, and msr DAIFClr, Xn transfer + * from bits 3:0. + */ +#define DAIFSC_DEBUGF (1 << 3) +#define DAIFSC_ASYNCF (1 << 2) +#define DAIFSC_IRQF (1 << 1) +#define DAIFSC_FIQF (1 << 0) +#define DAIFSC_ALL (DAIFSC_DEBUGF | DAIFSC_ASYNCF | DAIFSC_IRQF | DAIFSC_FIQF) +#define DAIFSC_STANDARD_DISABLE (DAIFSC_ASYNCF | DAIFSC_IRQF | DAIFSC_FIQF) + +/* + * ARM64_TODO: unify with ARM? + */ +#define PSR64_CF 0x20000000 /* Carry/Borrow/Extend */ + +#define PSR64_MODE_MASK 0x1F + +#define PSR64_MODE_USER32_THUMB 0x20 + +#define PSR64_MODE_RW_SHIFT 4 +#define PSR64_MODE_RW_64 0 +#define PSR64_MODE_RW_32 (0x1 << PSR64_MODE_RW_SHIFT) + +#define PSR64_MODE_EL_SHIFT 2 +#define PSR64_MODE_EL_MASK (0x3 << PSR64_MODE_EL_SHIFT) +#define PSR64_MODE_EL3 (0x3 << PSR64_MODE_EL_SHIFT) +#define PSR64_MODE_EL1 (0x1 << PSR64_MODE_EL_SHIFT) +#define PSR64_MODE_EL0 0 + +#define PSR64_MODE_SPX 0x1 +#define PSR64_MODE_SP0 0 + +#define PSR64_USER32_DEFAULT (PSR64_MODE_RW_32 | PSR64_MODE_EL0 | PSR64_MODE_SP0) +#define PSR64_USER64_DEFAULT (PSR64_MODE_RW_64 | PSR64_MODE_EL0 | PSR64_MODE_SP0) +#define PSR64_KERNEL_DEFAULT (DAIF_STANDARD_DISABLE | PSR64_MODE_RW_64 | PSR64_MODE_EL1 | PSR64_MODE_SP0) + +#define PSR64_IS_KERNEL(x) ((x & PSR64_MODE_EL_MASK) == PSR64_MODE_EL1) +#define PSR64_IS_USER(x) ((x & PSR64_MODE_EL_MASK) == PSR64_MODE_EL0) + + +/* + * Floating Point Control Register (FPCR) + */ +#define FPCR_DN (1 << 25) + +#define FPCR_DEFAULT (FPCR_DN) + + +/* + * System Control Register (SCTLR) + * + * 31 26 25 24 23 19 18 15 14 13 12 11 7 6 5 4 3 2 1 0 + * +-----+---+--+---+----+---+---+---+---+--+--+----+---+----+------+---+--+-+-+-+ + * |00110|UCI|EE|E0E|1101|WXN|101|UCT|DZE| 0|I |1000|ITD|THEE|C15BEN|SA0|SA|D|A|M| + * +-----+---+--+---+----+---+---+---+---+--+--+----+---+----+------+---+--+-+-+-+ + * + * UCI User Cache Instructions + * EE Exception Endianness + * E0E EL0 Endianness + * WXN Writeable implies eXecute Never + * UCT User Cache Type register (CTR_EL0) + * DZE user Data Cache Zero (DC ZVA) + * I Instruction cache enable + * ITD IT Disable + * THEE THumb EE enable + * CP15BEN CP15 Barrier ENable + * SA0 Stack Alignment check for EL0 + * SA Stack Alignment check enable + * D Data/unified cache enable + * A Alignment check enable + * M MMU enable + */ +#define SCTLR_RESERVED 0x30d50800 + +#define SCTLR_UCI_ENABLED (1 << 26) +#define SCTLR_EE_ENABLED (1 << 25) +#define SCTLR_E0E_ENABLED (1 << 24) +#define SCTLR_WXN_ENABLED (1 << 19) +#define SCTLR_UCT_ENABLED (1 << 15) +#define SCTLR_DZE_ENABLED (1 << 14) +#define SCTLR_I_ENABLED (1 << 12) +#define SCTLR_ITD_DISABLED (1 << 7) +#define SCTLR_THEE_ENABLED (1 << 6) +#define SCTLR_CP15BEN_ENABLED (1 << 5) +#define SCTLR_SA0_ENABLED (1 << 4) +#define SCTLR_SA_ENABLED (1 << 3) +#define SCTLR_D_ENABLED (1 << 2) +#define SCTLR_A_ENABLED (1 << 1) +#define SCTLR_M_ENABLED (1 << 0) + +#define SCTLR_EL1_DEFAULT (SCTLR_RESERVED | SCTLR_I_ENABLED | SCTLR_SA_ENABLED | SCTLR_D_ENABLED | SCTLR_M_ENABLED) + +/* + * Secure Configuratio Register (SCR) + * + * 31 12 0 + * +---+---+------+------+--------------------+ + * |00000000000000000000 || + * +---+---+------+------+--------------------+ + * + * where: + * TTA Trace trap + * FPEN Floating point enable + */ +#define SCR_EA_SHIFT (3) +#define SCR_EA (1 << SCR_EA_SHIFT) + +#define SCR_FIQ_SHIFT (2) +#define SCR_FIQ (1 << SCR_FIQ_SHIFT) + +#define SCR_IRQ_SHIFT (1) +#define SCR_IRQ (1 << SCR_IRQ_SHIFT) + +#define SCR_DEFAULT (SCR_EA | SCR_FIQ | SCR_IRQ) + +/* + * Coprocessor Access Control Register (CPACR) + * + * 31 28 27 22 21 20 19 0 + * +---+---+------+------+--------------------+ + * |000|TTA|000000| FPEN |00000000000000000000| + * +---+---+------+------+--------------------+ + * + * where: + * TTA Trace trap + * FPEN Floating point enable + */ +#define CPACR_TTA_SHIFT 28 +#define CPACR_TTA (1 << CPACR_TTA_SHIFT) + +#define CPACR_FPEN_SHIFT 20 +#define CPACR_FPEN_EL0_TRAP (0x1 << CPACR_FPEN_SHIFT) +#define CPACR_FPEN_ENABLE (0x3 << CPACR_FPEN_SHIFT) + +/* + * Translation Control Register (TCR) - EL3 + * + * 31 30 24 23 22 21 20 19 18 16 14 13 12 11 10 9 8 7 6 5 0 + * +-+-------+--+-----+---+--+-----+---+-----+-----+-----+-+-+----+ + * |1| 0 | 1| 0 |TBI| 0| PS |TG0| SH0 |ORGN0|IRGN0|0|0|T0SZ| + * +-+-------+--+-----+---+--+-----+---+-----+-----+-----+-+-+----+ + * + * TBI Top Byte Ignored for TTBR0 region + * PS Physical Address Size limit + * TG0 Granule Size for TTBR0 region + * SH0 Shareability for TTBR0 region + * ORGN0 Outer Cacheability for TTBR0 region + * IRGN0 Inner Cacheability for TTBR0 region + * T0SZ Virtual address size for TTBR0 + + * Translation Control Register (TCR) - EL1 + * + * 63 39 38 37 36 34 32 30 29 28 27 26 25 24 23 22 21 16 14 13 12 11 10 9 8 7 5 0 + * +------+----+----+--+-+-----+-+---+-----+-----+-----+----+--+------+-+---+-----+-----+-----+----+-+----+ + * | 0 |TBI1|TBI0|AS|0| IPS |0|TG1| SH1 |ORGN1|IRGN1|EPD1|A1| T1SZ |0|TG0| SH0 |ORGN0|IRGN0|EPD0|0|T0SZ| + * +------+----+----+--+-+-----+-+---+-----+-----+-----+----+--+------+-+---+-----+-----+-----+----+-+----+ + * + * TBI1 Top Byte Ignored for TTBR1 region + * TBI0 Top Byte Ignored for TTBR0 region + * AS ASID Size + * IPS Physical Address Size limit + * TG1 Granule Size for TTBR1 region + * SH1 Shareability for TTBR1 region + * ORGN1 Outer Cacheability for TTBR1 region + * IRGN1 Inner Cacheability for TTBR1 region + * EPD1 Translation table walk disable for TTBR1 + * A1 ASID selection from TTBR1 enable + * T1SZ Virtual address size for TTBR1 + * TG0 Granule Size for TTBR0 region + * SH0 Shareability for TTBR0 region + * ORGN0 Outer Cacheability for TTBR0 region + * IRGN0 Inner Cacheability for TTBR0 region + * T0SZ Virtual address size for TTBR0 + */ + +// Common defintions for EL1 and EL3 versions of this register +#define TCR_ELx_T0SZ_SHIFT 0 + +#define TCR_ELx_IRGN0_SHIFT 8 +#define TCR_ELx_IRGN0_DISABLED (0ULL << TCR_ELx_IRGN0_SHIFT) +#define TCR_ELx_IRGN0_WRITEBACK (1ULL << TCR_ELx_IRGN0_SHIFT) +#define TCR_ELx_IRGN0_WRITETHRU (2ULL << TCR_ELx_IRGN0_SHIFT) +#define TCR_ELx_IRGN0_WRITEBACKNO (3ULL << TCR_ELx_IRGN0_SHIFT) + +#define TCR_ELx_ORGN0_SHIFT 10 +#define TCR_ELx_ORGN0_DISABLED (0ULL << TCR_ELx_ORGN0_SHIFT) +#define TCR_ELx_ORGN0_WRITEBACK (1ULL << TCR_ELx_ORGN0_SHIFT) +#define TCR_ELx_ORGN0_WRITETHRU (2ULL << TCR_ELx_ORGN0_SHIFT) +#define TCR_ELx_ORGN0_WRITEBACKNO (3ULL << TCR_ELx_ORGN0_SHIFT) + +#define TCR_ELx_SH0_SHIFT 12 +#define TCR_ELx_SH0_NONE (0ULL << TCR_ELx_SH0_SHIFT) +#define TCR_ELx_SH0_OUTER (2ULL << TCR_ELx_SH0_SHIFT) +#define TCR_ELx_SH0_INNER (3ULL << TCR_ELx_SH0_SHIFT) + +#define TCR_ELx_TG0_GRANULE_SHIFT 14 +#define TCR_ELx_TG0_GRANULE_4KB (0ULL << TCR_ELx_TG0_GRANULE_SHIFT) +#define TCR_ELx_TG0_GRANULE_64KB (1ULL << TCR_ELx_TG0_GRANULE_SHIFT) +#define TCR_ELx_TG0_GRANULE_16KB (2ULL << TCR_ELx_TG0_GRANULE_SHIFT) + +#if WITH_EL3 +// EL3-specific TCR register definitions + +#define TCR_EL3_PS_SHIFT 16 +#define TCR_EL3_PS_32BITS (0ULL << TCR_EL3_PS_SHIFT) +#define TCR_EL3_PS_36BITS (1ULL << TCR_EL3_PS_SHIFT) +#define TCR_EL3_PS_40BITS (2ULL << TCR_EL3_PS_SHIFT) +#define TCR_EL3_PS_42BITS (3ULL << TCR_EL3_PS_SHIFT) +#define TCR_EL3_PS_44BITS (4ULL << TCR_EL3_PS_SHIFT) +#define TCR_EL3_PS_48BITS (5ULL << TCR_EL3_PS_SHIFT) + +#define TCR_EL3_TBI_TOPBYTE_IGNORED (1ULL << 20) + +#else +// EL1-specific TCR register definitions + +#define TCR_EL1_EPD0_TTBR0_DISABLED (1ULL << 7) + +#define TCR_EL1_T1SZ_SHIFT 16 + +#define TCR_EL1_A1_ASID1 (1ULL << 22) +#define TCR_EL1_EPD1_TTBR1_DISABLED (1ULL << 23) + +#define TCR_EL1_IRGN1_SHIFT 24 +#define TCR_EL1_IRGN1_DISABLED (0ULL << TCR_EL1_IRGN1_SHIFT) +#define TCR_EL1_IRGN1_WRITEBACK (1ULL << TCR_EL1_IRGN1_SHIFT) +#define TCR_EL1_IRGN1_WRITETHRU (2ULL << TCR_EL1_IRGN1_SHIFT) +#define TCR_EL1_IRGN1_WRITEBACKNO (3ULL << TCR_EL1_IRGN1_SHIFT) + +#define TCR_EL1_ORGN1_SHIFT 26 +#define TCR_EL1_ORGN1_DISABLED (0ULL << TCR_EL1_ORGN1_SHIFT) +#define TCR_EL1_ORGN1_WRITEBACK (1ULL << TCR_EL1_ORGN1_SHIFT) +#define TCR_EL1_ORGN1_WRITETHRU (2ULL << TCR_EL1_ORGN1_SHIFT) +#define TCR_EL1_ORGN1_WRITEBACKNO (3ULL << TCR_EL1_ORGN1_SHIFT) + +#define TCR_EL1_SH1_SHIFT 28 +#define TCR_EL1_SH1_NONE (0ULL << TCR_EL1_SH1_SHIFT) +#define TCR_EL1_SH1_OUTER (2ULL << TCR_EL1_SH1_SHIFT) +#define TCR_EL1_SH1_INNER (3ULL << TCR_EL1_SH1_SHIFT) + +#define TCR_EL1_TG1_GRANULE_SHIFT 30 +#define TCR_EL1_TG1_GRANULE_16KB (1ULL << TCR_EL1_TG1_GRANULE_SHIFT) +#define TCR_EL1_TG1_GRANULE_4KB (2ULL << TCR_EL1_TG1_GRANULE_SHIFT) +#define TCR_EL1_TG1_GRANULE_64KB (3ULL << TCR_EL1_TG1_GRANULE_SHIFT) + +#define TCR_EL1_IPS_SHIFT 32 +#define TCR_EL1_IPS_32BITS (0ULL << TCR_EL1_IPS_SHIFT) +#define TCR_EL1_IPS_36BITS (1ULL << TCR_EL1_IPS_SHIFT) +#define TCR_EL1_IPS_40BITS (2ULL << TCR_EL1_IPS_SHIFT) +#define TCR_EL1_IPS_42BITS (3ULL << TCR_EL1_IPS_SHIFT) +#define TCR_EL1_IPS_44BITS (4ULL << TCR_EL1_IPS_SHIFT) +#define TCR_EL1_IPS_48BITS (5ULL << TCR_EL1_IPS_SHIFT) + +#define TCR_EL1_AS_16BIT_ASID (1ULL << 36) +#define TCR_EL1_TBI0_TOPBYTE_IGNORED (1ULL << 37) +#define TCR_EL1_TBI1_TOPBYTE_IGNORED (1ULL << 38) + +#endif + +/* + * Translation Table Base Register (TTBR) + * + * 63 48 47 x x-1 0 + * +--------+------------------+------+ + * | ASID | Base Address | zero | + * +--------+------------------+------+ + * + */ +#define TTBR_ASID_SHIFT 48 +#define TTBR_ASID_MASK 0xffff000000000000 + +#define TTBR_BADDR_MASK 0x0000ffffffffffff + +/* + * Memory Attribute Indirection Register + * + * 63 56 55 48 47 40 39 32 31 24 23 16 15 8 7 0 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | Attr7 | Attr6 | Attr5 | Attr4 | Attr3 | Attr2 | Attr1 | Attr0 | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * + */ + +#define MAIR_ATTR_SHIFT(x) (8*(x)) + +/* Strongly ordered or device memory attributes */ +#define MAIR_OUTER_STRONGLY_ORDERED 0x0 +#define MAIR_OUTER_DEVICE 0x0 + +#define MAIR_INNER_STRONGLY_ORDERED 0x0 +#define MAIR_INNER_DEVICE 0x4 + +/* Normal memory attributes */ +#define MAIR_OUTER_NON_CACHEABLE 0x40 +#define MAIR_OUTER_WRITE_THROUGH 0x80 +#define MAIR_OUTER_WRITE_BACK 0xc0 + +#define MAIR_INNER_NON_CACHEABLE 0x4 +#define MAIR_INNER_WRITE_THROUGH 0x8 +#define MAIR_INNER_WRITE_BACK 0xc + +/* Allocate policy for cacheable memory */ +#define MAIR_OUTER_WRITE_ALLOCATE 0x10 +#define MAIR_OUTER_READ_ALLOCATE 0x20 + +#define MAIR_INNER_WRITE_ALLOCATE 0x1 +#define MAIR_INNER_READ_ALLOCATE 0x2 + +/* Memory Atribute Encoding */ +#define MAIR_DISABLE 0x04 /* Strongly Ordered */ +#define MAIR_WRITECOMB 0x44 /* Normal Memory, Outer Non-Cacheable, Inner Non-Cacheable */ +#define MAIR_WRITETHRU 0xBB /* Normal Memory, Outer Write-through, Inner Write-through */ +#define MAIR_WRITEBACK 0xFF /* Normal Memory, Outer Write-back, Inner Write-back */ +#define MAIR_INNERWRITEBACK 0x4F /* Normal Memory, Outer Non-Cacheable, Inner Write-back */ + + +/* + * ARM 4-level Page Table support - 2*1024TB (2^48) of address space + */ + + +/* + * Memory Attribute Index + */ +#define CACHE_ATTRINDX_DISABLE 0x0 /* no cache, no buffer */ +#define CACHE_ATTRINDX_WRITEBACK 0x1 /* cache enabled, buffer enabled */ +#define CACHE_ATTRINDX_WRITECOMB 0x1 /* no cache, buffered writes */ +#define CACHE_ATTRINDX_WRITETHRU 0x2 /* cache enabled, buffer disabled */ +#define CACHE_ATTRINDX_INNERWRITEBACK 0x4 /* inner cache enabled, buffer enabled, write allocate */ +#define CACHE_ATTRINDX_DEFAULT CACHE_ATTRINDX_WRITEBACK + +/* + * Access protection bit values (TTEs and PTEs) + */ +#define AP_RWNA 0x0 /* priv=read-write, user=no-access */ +#define AP_RWRW 0x1 /* priv=read-write, user=read-write */ +#define AP_RONA 0x2 /* priv=read-only, user=no-access */ +#define AP_RORO 0x3 /* priv=read-only, user=read-only */ +#define AP_MASK 0x3 /* mask to find ap bits */ + +/* + * Shareability attributes + */ +#define SH_NONE 0x0 /* Non shareable */ +#define SH_OUTER_MEMORY 0x2 /* Normal memory Inner shareable - Outer shareable */ +#define SH_INNER_MEMORY 0x3 /* Normal memory Inner shareable - Outer non shareable */ + +/* + * LPAE/ARMv8 Table Entry + * + * 63 62 61 60 59 58 52 51 48 47 12 11 2 1 0 + * ,--+-----+--+---+-------+------+----------------------+-------+-+-. + * |NS| AP |XN|PXN|ignored| zero | TableOutputAddress |ignored|1|V| + * `--+-----+--+---+-------+------+----------------------+-------+-+-' + * + * LPAE/ARMv8 Block Entry + * + * 63 59 58 55 54 53 52 51 48 47 12 11 10 9 8 7 6 5 4 2 1 0 + * ,-----+-----+--+---+----+-----+-------------+--+--+----+----+--+-------+-+-. + * | ign | SW |XN|PXN|HINT| zero|OutputAddress|nG|AF| SH | AP |NS|AttrIdx|W|V| + * `-----+-----+--+---+----+-----+-------------+--+--+----+----+--+-------+-+-' + * + * NS (NSTable) Non-Secure: NS=1 for everything outside of TZ region + * AP (APTable) Access Permission: AP[2:1]=0 for RW, 2 for RO + * XN (XNTable) eXecute Never: XN=0 for code, 1 for data + * PXN (PXNTable) Privileged eXecute Never: 1=dont execute when EL3 + * TableOutputAddress Next physical base: Lower bits 0 as alignment requires. + * SW Reserved for software use (unused, can have metadata) + * HINT Contiguous hint. Optimization only, leave as 0. + * OutputAddress Block physical base: Lower bits 0 as alignment requires. + * nG notGlobal: nG=1 restricts TLB hit to matching ASID + * AF Access Flag: 0=never,1=hit. ARMv8 may fault if 0. + * SH Shareability, SH[1:0]=2 for normal memory + * AttrIdx Memory Attribute Index, 0 for device, 1 for normal + * W "Walk" flag: L0-2 0=Block,1=Table; L3 0=Fault,1=Block + */ + +#define ARM_LPAE_TABLE_MASK (0x0000fffffffff000ULL) /* mask for extracting pointer to next table (works at any level) */ + +#define ARM_LPAE_NSTABLE 0x8000000000000000ULL /* value for a secure mapping */ +#define ARM_LPAE_NSTABLE_MASK 0x8000000000000000ULL /* notSecure mapping mask */ + +#define ARM_LPAE_APTABLE_SHIFT 61 +#define ARM_LPAE_APTABLE(x) ((x)<> ESR_EC_SHIFT) + +#define ESR_IL_SHIFT 25 +#define ESR_IL (1 < ESR_IL_SHIFT) + +#define ESR_IS_THUMB(x) (!(x & ESR_IL)) + +#define ESR_ISS_MASK 0x01FFFFFF +#define ESR_ISS(x) (x & ESR_ISS_MASK) + +/* + * Instruction Abort ISS (EL1) + * 24 10 9 5 0 + * +---------------+--+---+------+ + * |000000000000000|EA|000| IFSC | + * +---------------+--+---+------+ + * + * where: + * EA External Abort type + * IFSC Instruction Fault Status Code + */ + +#define ISS_IA_EA_SHIFT 9 +#define ISS_IA_EA (0x1 << ISS_IA_EA_SHIFT) + +#define ISS_IA_FSC_MASK 0x2F +#define ISS_IA_FSC(x) (x & ISS_DA_FSC_MASK) + + +/* + * Data Abort ISS (EL1) + * + * 24 9 8 7 6 5 0 + * +---------------+--+--+-+---+----+ + * |000000000000000|EA|CM|0|WnR|DFSC| + * +---------------+--+--+-+---+----+ + * + * where: + * EA External Abort type + * CM Cache Maintenance operation + * WnR Write not Read + * DFSC Data Fault Status Code + */ +#define ISS_DA_EA_SHIFT 9 +#define ISS_DA_EA (0x1 << ISS_DA_EA_SHIFT) + +#define ISS_DA_CM_SHIFT 8 +#define ISS_DA_CM (0x1 << ISS_DA_CM_SHIFT) + +#define ISS_DA_WNR_SHIFT 6 +#define ISS_DA_WNR (0x1 << ISS_DA_WNR_SHIFT) + +#define ISS_DA_FSC_MASK 0x2F +#define ISS_DA_FSC(x) (x & ISS_DA_FSC_MASK) + +#define PLATFORM_SYSCALL_TRAP_NO 0x80000000 + +#define ARM64_SYSCALL_CODE_REG_NUM (16) + +#define ARM64_CLINE_SHIFT 6 + +/* + * Timer definitions. + */ +#define CNTKCTL_EL1_PL0PTEN (0x1 << 9) /* 1: EL0 access to physical timer regs permitted */ +#define CNTKCTL_EL1_PL0VTEN (0x1 << 8) /* 1: EL0 access to virtual timer regs permitted */ +#define CNTKCTL_EL1_EVENTI_MASK (0x000000f0) /* Mask for bits describing which bit to use for triggering event stream */ +#define CNTKCTL_EL1_EVENTI_SHIFT (0x4) /* Shift for same */ +#define CNTKCTL_EL1_EVENTDIR (0x1 << 3) /* 1: one-to-zero transition of specified bit causes event */ +#define CNTKCTL_EL1_EVNTEN (0x1 << 2) /* 1: enable event stream */ +#define CNTKCTL_EL1_PL0VCTEN (0x1 << 1) /* 1: EL0 access to physical timebase + frequency reg enabled */ +#define CNTKCTL_EL1_PL0PCTEN (0x1 << 0) /* 1: EL0 access to virtual timebase + frequency reg enabled */ + +#endif /* _ARM64_PROC_REG_H_ */ diff --git a/arch/arm64/link.exp b/arch/arm64/link.exp new file mode 100644 index 0000000..c0a2947 --- /dev/null +++ b/arch/arm64/link.exp @@ -0,0 +1 @@ +_start diff --git a/arch/arm64/mmu.c b/arch/arm64/mmu.c new file mode 100644 index 0000000..341d322 --- /dev/null +++ b/arch/arm64/mmu.c @@ -0,0 +1,543 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * See docs/mmu64.txt for an in-depth version of what is going on here. + * Short version: + * - H6, H7 use 4KB page granule. + * - H8 uses 16KB page granule (4KB not supported by hardware). + * - Start at L1 for 4KB page granule. + * - Start at L2 for 16KB page granule. + * - Set virtual memory limit so the first level (L0/L1) has just two entries. + * - ...then never touch the top level so we don't suffer from NS/S coherency. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifndef TEST +# include +# include +# include +# include +#endif + +#define LAST_TABLE_LEVEL 3 + +extern uint64_t arm_read_sctlr(); + +// Start level page table entries +static uint64_t *tt_top_level; + +// Allocation area and current allocation pointer. +static addr_t tt_alloc_start, tt_alloc_next, tt_alloc_end; + +#ifdef TEST + +// Mock test interfaces for mmu.c, implemented in mmu_test.c + +void mmu_printf(int verbosity, const char *fmt, ...); +unsigned get_page_granule_shift(void); +void mmu_get_memmap(addr_t *page_tables_base, + size_t *page_tables_size); +void platform_mmu_setup(bool resume); +void get_table_entry_hook(unsigned level, addr_t table_base, size_t index); +void set_table_entry_hook(unsigned level, addr_t table_base, size_t index, + uint64_t value); + +#else // !defined(TEST) + +// Real interfaces, designed to be inlined. These have no host-side coverage, +// so they should be no-ops or simple constants. + +// No printf spew. +static void mmu_printf(int verbosity, const char *fmt, ...) +{ + (void) verbosity; + (void) fmt; +} + +// Constants. +static unsigned get_page_granule_shift(void) { return PAGE_GRANULE_SHIFT; } +static void mmu_get_memmap(addr_t *page_tables_base, + size_t *page_tables_size) +{ + *page_tables_base = PAGE_TABLES_BASE; + *page_tables_size = PAGE_TABLES_SIZE; +} + +// Remove expensive validity checking. +static void get_table_entry_hook(unsigned level, addr_t table_base, + size_t index) +{ + (void) level; (void) table_base; (void) index; +} +static void set_table_entry_hook(unsigned level, addr_t table_base, + size_t index, uint64_t value) +{ + (void) level; (void) table_base; (void) index; (void) value; +} + +#endif // !defined(TEST) + +#define mmu_spew(x...) mmu_printf(1, x) +#define mmu_extra_spew(x...) mmu_printf(2, x) + +static void assert_valid_level(unsigned level) +{ + ASSERT((get_page_granule_shift() == 12 || level >= 1) && + level <= LAST_TABLE_LEVEL); +} + +static bool level_permits_blocks(unsigned level) +{ + assert_valid_level(level); + // No granule supports L0 blocks. + // 4KB granule supports L1 blocks. + // All granules support L2 and L3 blocks. + return (level == 1 && get_page_granule_shift() == 12) || level >= 2; +} + +static uint64_t get_table_entry(unsigned level, addr_t table_base, + size_t index) +{ + get_table_entry_hook(level, table_base, index); + mmu_extra_spew("get_table_entry(%u, 0x%llx, %u) ", + level, (unsigned long long) table_base, + (unsigned) index); + // No possible aliases, known aligned. + uint64_t result = *(uint64_t *) (table_base + index * 8); + mmu_extra_spew("= 0x%016llx\n", (unsigned long long) result); + return result; +} + +static void set_table_entry(unsigned level, addr_t table_base, size_t index, + uint64_t value) +{ + set_table_entry_hook(level, table_base, index, value); + mmu_extra_spew("set_table_entry(%u, 0x%llx, %u, 0x%llx)\n", + level, (unsigned long long) table_base, (unsigned) index, + (unsigned long long) value); + *((volatile uint64_t *) (table_base + index * 8)) = value; +} + +static unsigned get_start_level(void) +{ + switch (get_page_granule_shift()) { + case 12: return 1; + case 14: return 2; + case 16: return 2; + default: panic("Bad granule"); + } +} + +static unsigned get_virt_address_bits(void) +{ + switch (get_page_granule_shift()) { + case 12: return 36; + case 14: return 36; + case 16: return 36; + default: panic("Bad granule"); + } +} + +static uint64_t get_mair(void) +{ + return (MAIR_WRITEBACK << MAIR_ATTR_SHIFT(CACHE_ATTRINDX_WRITEBACK)) | + (MAIR_DISABLE << MAIR_ATTR_SHIFT(CACHE_ATTRINDX_DISABLE)); +} + +static uint64_t get_tcr(void) +{ + // Form the contents of the TCR register for the selected + // virtual address limit and page granule. + uint64_t tcr; + uint32_t txsz = 64 - get_virt_address_bits(); +#if WITH_EL3 + switch (get_page_granule_shift()) { + case 12: tcr = TCR_ELx_TG0_GRANULE_4KB; break; + case 14: tcr = TCR_ELx_TG0_GRANULE_16KB; break; + case 16: tcr = TCR_ELx_TG0_GRANULE_64KB; break; + default: panic("Bad granule"); + } + tcr |= TCR_EL3_PS_36BITS | + TCR_ELx_SH0_OUTER | TCR_ELx_ORGN0_WRITEBACK | TCR_ELx_IRGN0_WRITEBACK | + (txsz << TCR_ELx_T0SZ_SHIFT); +#else + switch (get_page_granule_shift()) { + case 12: tcr = TCR_ELx_TG0_GRANULE_4KB | TCR_EL1_TG1_GRANULE_4KB; break; + case 14: tcr = TCR_ELx_TG0_GRANULE_16KB | TCR_EL1_TG1_GRANULE_16KB; break; + case 16: tcr = TCR_ELx_TG0_GRANULE_64KB | TCR_EL1_TG1_GRANULE_64KB; break; + default: panic("Bad granule"); + } + tcr |= TCR_EL1_IPS_36BITS | + TCR_ELx_SH0_OUTER | TCR_ELx_ORGN0_WRITEBACK | TCR_ELx_IRGN0_WRITEBACK | + (txsz << TCR_ELx_T0SZ_SHIFT) | + TCR_EL1_EPD1_TTBR1_DISABLED | + TCR_EL1_SH1_OUTER | TCR_EL1_ORGN1_WRITEBACK | TCR_EL1_IRGN1_WRITEBACK | + (txsz << TCR_EL1_T1SZ_SHIFT); +#endif + return tcr; +} + +static uint64_t get_table_flags(void) +{ + // All table walks after the start level are non-secure. + return ARM_LPAE_NSTABLE | ARM_LPAE_TYPE_TABLE | ARM_LPAE_VALID; +} + +static uint64_t get_block_flags(unsigned level, arm_mmu_extended_attr_t attr) +{ + assert_valid_level(level); + RELEASE_ASSERT(level_permits_blocks(level)); + bool normal, writable, executable; + switch (attr) { + case kARMMMUDeviceR: + normal = false; writable = false; executable = false; break; + case kARMMMUDeviceRX: + normal = false; writable = false; executable = true; break; + case kARMMMUDeviceRW: + normal = false; writable = true; executable = false; break; + case kARMMMUNormalR: + normal = true; writable = false; executable = false; break; + case kARMMMUNormalRX: + normal = true; writable = false; executable = true; break; + case kARMMMUNormalRW: + normal = true; writable = true; executable = false; break; + default: + panic("Bad attr %d", (int) attr); + } + // Always set Access Flag, Non-Secure and Valid. + uint64_t value = ARM_LPAE_AF | ARM_LPAE_NS | ARM_LPAE_VALID; + if (level < LAST_TABLE_LEVEL) { + value |= ARM_LPAE_TYPE_L0L1L2BLOCK; + } else { + value |= ARM_LPAE_TYPE_L3BLOCK; + } + uint64_t sh, attr_indx; + if (normal) { + sh = SH_OUTER_MEMORY; + attr_indx = CACHE_ATTRINDX_WRITEBACK; + } else { + sh = SH_NONE; + attr_indx = CACHE_ATTRINDX_DISABLE; + } + value |= ARM_LPAE_SH(sh); + value |= ARM_LPAE_ATTRINDX(attr_indx); + uint64_t ap = writable ? 0 : 2; + value |= ARM_LPAE_AP(ap); + if (!executable) { + value |= ARM_LPAE_PXN | ARM_LPAE_XN; + } + return value; +} + +static uint64_t get_virt_size_bytes(void) +{ + return 1ULL << get_virt_address_bits(); +} + +static uint64_t get_phys_size_bytes(void) +{ + return 1ULL << 40; +} + +static size_t get_level_shift(unsigned level) +{ + assert_valid_level(level); + switch (get_page_granule_shift()) { + case 12: return 39 - (level * 9); + case 14: return 47 - (level * 11); + case 16: return 55 - (level * 13); + default: panic("Granule 2^%u not supported\n", + get_page_granule_shift()); + } +} + +static size_t get_level_entries(unsigned level) +{ + assert_valid_level(level); + // 1 granule per sub-table, 8 bytes per entry. + return ((size_t) 1) << (get_page_granule_shift() - 3); +} + +static addr_t tt_alloc(unsigned level) +{ + // Allocate a translation table. The start level was + // allocated as tt_top_level in arm_mmu_init and should not be + // requested to be allocated. All levels are the + // same size: one granule. + RELEASE_ASSERT(level > get_start_level() && level <= LAST_TABLE_LEVEL); + size_t bytes = ((size_t) 1) << get_page_granule_shift(); + mmu_spew("Allocate L%u size 0x%llx\n", level, + (unsigned long long) bytes); + if (bytes > tt_alloc_end || tt_alloc_next > tt_alloc_end - bytes) { + panic("Out of table allocation space L%u\n", level); + } + addr_t ret = tt_alloc_next; + // Alignment is guaranteed by arm_mmu_init() and all + // allocations being the same size (1 granule), but it's cheap + // to double-check allocation alignment. + if ((ret & (bytes - 1)) != 0) { + panic("Bad aligned pte alloc 0x%llx\n", + (unsigned long long) ret); + } + tt_alloc_next += bytes; + mmu_spew("Allocated L%u size 0x%llx at 0x%llx\n", + level, (unsigned long long) bytes, (unsigned long long) ret); + return ret; +} + +static size_t map_at_level(unsigned level, addr_t table_base, + addr_t vaddr, addr_t paddr, size_t size, + arm_mmu_extended_attr_t attr, + bool blank_table) +{ + mmu_spew("map_at_level(level=%u,\n" + " table_base=0x%llx,\n" + " vaddr=0x%llx,\n" + " paddr=0x%llx,\n" + " size=0x%llx,\n" + " attr=%u\n", + level, (unsigned long long) table_base, + (unsigned long long) vaddr, (unsigned long long) paddr, + (unsigned long long) size, (unsigned) attr); + + // Check this mapping is bounded by virtual and physical address limits. + assert_valid_level(level); + RELEASE_ASSERT(size <= get_virt_size_bytes() && + vaddr <= get_virt_size_bytes() - size); + RELEASE_ASSERT(size <= get_phys_size_bytes() && + paddr <= get_phys_size_bytes() - size); + + // Calculate constants about this translation level. + size_t level_shift = get_level_shift(level); + size_t level_entries = get_level_entries(level); + size_t level_size = 1ULL << level_shift; + size_t level_mask = level_size - 1; + bool permit_block = level_permits_blocks(level); + size_t index = (vaddr >> level_shift) & (level_entries - 1); + mmu_spew("shift:%d entries:%d size:0x%llx mask:0x%llx " + "block:%d index:%d\n", + (int) level_shift, + (int) level_entries, + (unsigned long long) level_size, + (unsigned long long) level_mask, + (int) permit_block, + (int) index); + + // Can we make block entries here? Must be permitted at this + // level, have enough bytes remaining, and both virtual and + // physical addresses aligned to a block. + if (permit_block && + size >= level_size && + ((vaddr | paddr) & level_mask) == 0) { + // Map contiguous blocks. + mmu_spew("Array of blocks\n"); + size_t mapped_size = 0; + size_t remaining_size = size; + // Common block flags for all entries at this level. + uint64_t block_flags = get_block_flags(level, attr); + while (remaining_size >= level_size && index < level_entries) { + // Check the existing entry is unused. + uint64_t entry = get_table_entry(level, table_base, + index); + if (entry != 0) { + // Not difficult but no use case. + panic("Remapping an existing L%u at 0x%016llx", + level, (unsigned long long) vaddr); + } + // Form an entry. + uint64_t ent = block_flags | paddr; + // Write a block entry to the table. + set_table_entry(level, table_base, index, ent); + // Next index. + mapped_size += level_size; + remaining_size -= level_size; + paddr += level_size; + vaddr += level_size; + ++index; + } + // Must make forward progress... and not too much. + RELEASE_ASSERT(mapped_size > 0 && mapped_size <= size); + return mapped_size; + } else { + // Sub-divide into a next level table. + mmu_spew("Sub-divide\n"); + + // Only so much granularity available. + RELEASE_ASSERT(level < LAST_TABLE_LEVEL); + + // Get the existing entry. + uint64_t entry = blank_table ? 0 : get_table_entry(level, table_base, index); + if ((entry & ARM_LPAE_VALID) && + (entry & ARM_LPAE_TYPE_MASK) == ARM_LPAE_TYPE_L0L1L2BLOCK) { + // Not hard but no use case. + panic("Breaking down blocks not implemented"); + } + + unsigned sub_level = level + 1; + bool blank_sub_table; + addr_t sub_base; + if (entry & ARM_LPAE_VALID) { + mmu_spew("Existing entry\n"); + sub_base = entry & ARM_LPAE_TABLE_MASK; + blank_sub_table = false; + } else { + mmu_spew("Allocating sub-level table\n"); + sub_base = tt_alloc(sub_level); + // Form an entry. + uint64_t ent = get_table_flags() | sub_base; + // Store an entry pointing to the sub-level table. + set_table_entry(level, table_base, index, ent); + blank_sub_table = true; + } + // Recurse at next level. + return map_at_level(sub_level, sub_base, + vaddr, paddr, size, attr, blank_sub_table); + } +} + +void arm_mmu_map_range(addr_t vaddr, addr_t paddr, size_t size, + arm_mmu_extended_attr_t attr) +{ + // Ensure all addresses and sizes are at least L3 aligned. + size_t l3_align = ((size_t) 1) << get_level_shift(LAST_TABLE_LEVEL); + RELEASE_ASSERT(((vaddr | paddr | size) & (l3_align - 1)) == 0); + while (size > 0) { + // Map at the top level first, allowing the mapper function + // to break it down into smaller chunks as necessary. + size_t mapped = map_at_level(get_start_level(), + (addr_t) tt_top_level, + vaddr, paddr, size, attr, false); + RELEASE_ASSERT(mapped <= size); + size -= mapped; + vaddr += mapped; + paddr += mapped; + } + + if ((arm_read_sctlr() & SCTLR_M_ENABLED) != 0) { + arm_flush_tlbs(); + } +} + +void arm_mmu_map_ro(addr_t addr, size_t size) +{ + arm_mmu_map_range(addr, addr, size, kARMMMUNormalR); +} + +void arm_mmu_map_rw(addr_t addr, size_t size) +{ + arm_mmu_map_range(addr, addr, size, kARMMMUNormalRW); +} + +void arm_mmu_map_rx(addr_t addr, size_t size) +{ + arm_mmu_map_range(addr, addr, size, kARMMMUNormalRX); +} + +void arm_mmu_map_device_ro(addr_t addr, size_t size) +{ + arm_mmu_map_range(addr, addr, size, kARMMMUDeviceR); +} + +void arm_mmu_map_device_rw(addr_t addr, size_t size) +{ + arm_mmu_map_range(addr, addr, size, kARMMMUDeviceRW); +} + +void arm_mmu_map_device_rx(addr_t addr, size_t size) +{ + arm_mmu_map_range(addr, addr, size, kARMMMUDeviceRX); +} + +void arm_mmu_init(bool resume) +{ + // Setup memory attributes. + arm_write_mair(get_mair()); + + // Setup translation control register. + arm_write_tcr(get_tcr()); + + /* + * Sub-level page table allocations starts in the book-keeping + * region after all stacks, rounded up. Allocation rounded down. + */ + size_t granule_mask = (((size_t) 1) << get_page_granule_shift()) - 1; + addr_t page_tables_base; + size_t page_tables_size; + mmu_get_memmap(&page_tables_base, + &page_tables_size); + + RELEASE_ASSERT((page_tables_base & granule_mask) == 0); + RELEASE_ASSERT((page_tables_size & granule_mask) == 0); + + tt_alloc_start = page_tables_base; + tt_alloc_next = tt_alloc_start; + tt_alloc_end = (page_tables_base + page_tables_size) & ~granule_mask; + + // allocate top-level page table + tt_top_level = (uint64_t *)tt_alloc_start; + tt_alloc_next += 1 << get_page_granule_shift(); + + // Defer to platform code for the memory map setup. + platform_mmu_setup(resume); + + // Write the translation table base. + arm_write_ttbr0(tt_top_level); + + // Flush TLBs. + arm_flush_tlbs(); +} + + +#ifdef TEST +// static->global stubs for mmu_test.c +uint64_t *mmu_get_tt_top_level(void) { return tt_top_level; } +unsigned mmu_get_start_level(void) { return get_start_level(); } +uint64_t mmu_get_tcr(void) { return get_tcr(); } +uint64_t mmu_tt_alloc(unsigned level) { return tt_alloc(level); } +size_t mmu_get_level_entries(unsigned level) { + return get_level_entries(level); +} +uint64_t mmu_get_table_flags(void) { + return get_table_flags(); +} +uint64_t mmu_get_block_flags(unsigned level, arm_mmu_extended_attr_t attr) { + return get_block_flags(level, attr); +} + +size_t mmu_map_at_level(unsigned level, addr_t table_base, + addr_t vaddr, addr_t paddr, size_t size, + arm_mmu_extended_attr_t attr) +{ + return map_at_level(level, table_base, vaddr, paddr, size, attr, false); +} + +void mmu_get_tt_alloc_range(addr_t *start, addr_t *next, addr_t *end) +{ + *start = tt_alloc_start; + *next = tt_alloc_next; + *end = tt_alloc_end; +} + +void mmu_reset_state(void) +{ + tt_top_level = 0; + tt_alloc_start = 0; + tt_alloc_next = 0; + tt_alloc_end = 0; +} +#endif // defined(TEST) diff --git a/arch/arm64/mmu_test.c b/arch/arm64/mmu_test.c new file mode 100644 index 0000000..559e93f --- /dev/null +++ b/arch/arm64/mmu_test.c @@ -0,0 +1,846 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERBOSITY FAILURE + +#define FAILURE 0 +#define INFO 1 +#define SPEW 2 + +static size_t tests_run, tests_passed; + +enum Reason { + REASON_OK = 0, + REASON_EXPECTED_PANIC, + REASON_UNEXPECTED_PANIC, + REASON_PARAMS, + REASON_LEVEL, + REASON_OOM, + REASON_PTE_ALIGNMENT, + REASON_PTE_BASE, + REASON_PTE_INDEX, + REASON_PTE_ACCESS, + REASON_PTE_MISMATCH +}; + +static void test_unwind(enum Reason reason) __attribute__((noreturn)); + +#define TEST_ASSERT(reason, c) \ + do { \ + if (!(c)) { \ + printf("!!! Test assertion failure: %s\n", \ + #c ); \ + test_unwind(reason); \ + } \ + } while (0) + +struct State { + // Environment constants for an individual test. + const char *test_name; + const char *expect_panic_func; + const char *expect_panic_substr; + size_t level_entries[4]; + void *page_tables_base; + size_t page_tables_size; + size_t total_stack_size; + unsigned page_granule_shift; + jmp_buf jmp_env; + + // Updated during test. + bool arm_flush_tlbs_called; + + // Callbacks from test. + void (^mmu_setup_func)(); + void (^get_table_entry_hook)(); + void (^set_table_entry_hook)(); +}; + +static struct State state; + +unsigned get_page_granule_shift(void) { return state.page_granule_shift; } + +void mmu_get_memmap(addr_t *page_tables_base, + size_t *page_tables_size) +{ + *page_tables_base = (addr_t) state.page_tables_base; + *page_tables_size = state.page_tables_size; +} + +// Access to mmu.c static functions and variables. +uint64_t *mmu_get_tt_top_level(void); +unsigned mmu_get_start_level(void); +uint64_t mmu_get_tcr(void); +addr_t mmu_tt_alloc(unsigned level); +size_t mmu_get_level_entries(unsigned level); +uint64_t mmu_get_table_flags(void); +uint64_t mmu_get_block_flags(unsigned level, arm_mmu_extended_attr_t attr); +size_t mmu_map_at_level(unsigned level, addr_t table_base, + addr_t vaddr, addr_t paddr, size_t size, + arm_mmu_extended_attr_t attr); +void mmu_get_tt_alloc_range(addr_t *start, addr_t *next, addr_t *end); +void mmu_reset_state(void); + +const char *reason_to_string(int reason) +{ + switch (reason) { + case REASON_OK: return "OK"; + case REASON_EXPECTED_PANIC: return "Expected panic() called"; + case REASON_UNEXPECTED_PANIC: return "Unexpected panic() called"; + case REASON_PARAMS: return "Bad parameters detected"; + case REASON_LEVEL: return "Invalid level used"; + case REASON_OOM: return "Test ran out of memory for structures"; + case REASON_PTE_ALIGNMENT: return "Bad page table alignment"; + case REASON_PTE_BASE: return "Page table base does not match allocated"; + case REASON_PTE_INDEX: return "Page table index out of bounds"; + case REASON_PTE_ACCESS: return "Page table unexpected access"; + case REASON_PTE_MISMATCH: return "Page table value mismatch"; + default: + printf("Bad reason code %d\n", (int) reason); + abort(); + } +} + +void mmu_printf(int verbosity, const char *fmt, ...) +{ + if (VERBOSITY >= verbosity) { + va_list va; + va_start(va, fmt); + vprintf(fmt, va); + va_end(va); + } +} + +static void test_unwind(enum Reason reason) +{ + assert(reason != REASON_OK); + longjmp(state.jmp_env, (int) reason); +} + +void _panic(const char *func, const char *fmt, ...) +{ + char *buf = malloc(4096); + va_list va; + + va_start(va, fmt); + vsnprintf(buf, 4096, fmt, va); + va_end(va); + + bool expected = state.expect_panic_func && state.expect_panic_substr && + strstr(func, state.expect_panic_func) != NULL && + strstr(buf, state.expect_panic_substr) != NULL; + + if (!expected) { + mmu_printf(FAILURE, "!!! Unexpected panic in function %s: %s\n", func, buf); + } else { + mmu_printf(INFO, "Expected panic in function %s: %s\n", func, buf); + } + + free(buf); + + if (expected) { + test_unwind(REASON_EXPECTED_PANIC); + } else if (strstr(buf, "Out of table allocation space")) { + test_unwind(REASON_OOM); + } else { + test_unwind(REASON_UNEXPECTED_PANIC); + } +} + +static void expect_panic(const char *func, const char *substr) +{ + state.expect_panic_func = func; + state.expect_panic_substr = substr; +} + +uint64_t check_valid_index(unsigned level, addr_t table_base, size_t index) +{ + if (level < mmu_get_start_level() || level > 3) { + mmu_printf(FAILURE, "L%u invalid level\n", level); + test_unwind(REASON_LEVEL); + } + void *p = NULL; + + size_t table_size = + mmu_get_level_entries(level) * sizeof(uint64_t); + size_t table_entries = mmu_get_level_entries(level); + uint64_t alloc_start, alloc_next, alloc_end; + mmu_get_tt_alloc_range(&alloc_start, &alloc_next, &alloc_end); + if (table_base < alloc_start || + table_size > alloc_next || + table_base > alloc_next - table_size) { + mmu_printf(FAILURE, "L%u base 0x%" PRIx64 " size 0x%" PRIx64 + " outside allocated space\n", + level, + (uint64_t) table_base, + (uint64_t) table_size); + test_unwind(REASON_PTE_BASE); + } + if (index > table_entries) { + mmu_printf(FAILURE, "L%u entry %u >= table_entries %u\n", + level, (unsigned) index, + (unsigned) table_entries); + test_unwind(REASON_PTE_INDEX); + } + p = (void *) (table_base + index * 8); + + uint64_t result; + memcpy(&result, p, sizeof(result)); + return result; +} + +static void get_table_entry_internal(unsigned level, addr_t table_base, + size_t index) +{ + mmu_printf(SPEW, "get_table_entry(%u, 0x%" PRIx64 ", %u) ", + level, (uint64_t) table_base, (unsigned) index); + uint64_t result = check_valid_index(level, table_base, index); + mmu_printf(SPEW, "= 0x%016" PRIx64 "\n", result); +} + +void get_table_entry_hook(unsigned level, addr_t table_base, size_t index) +{ + if (state.get_table_entry_hook) { + state.get_table_entry_hook(level, table_base, index); + return; + } else { + get_table_entry_internal(level, table_base, index); + } +} + +static void set_table_entry_internal(unsigned level, addr_t table_base, + size_t index, uint64_t value) +{ + mmu_printf(SPEW, "set_table_entry(%u, 0x%" PRIx64 ", %u, " + "0x%" PRIx64 ") ", + level, (uint64_t) table_base, (unsigned) index, + value); + uint64_t old = check_valid_index(level, table_base, index); + mmu_printf(SPEW, " was 0x%016" PRIx64 "\n", old); +} + +void set_table_entry_hook(unsigned level, addr_t table_base, size_t index, + uint64_t value) +{ + if (state.set_table_entry_hook) { + state.set_table_entry_hook(level, table_base, index, value); + return; + } else { + set_table_entry_internal(level, table_base, index, value); + } +} + +// Mock HAL. + +uint64_t arm_read_sctlr(void) +{ + mmu_printf(INFO, "arm_read_sctlr()\n"); + return 0; +} + +void arm_write_mair(uint64_t mair) +{ + mmu_printf(INFO, "arm_write_mair(0x%016" PRIx64 ")\n", (uint64_t) mair); +} + +void arm_write_tcr(uint64_t tcr) +{ + mmu_printf(INFO, "arm_write_tcr(0x%016" PRIx64 ")\n", (uint64_t) tcr); +} + +void arm_write_ttbr0(void *ttbr0) +{ + mmu_printf(INFO, "arm_write_ttbr0(%p)\n", ttbr0); + if ((addr_t) ttbr0 != (addr_t) mmu_get_tt_top_level()) { + mmu_printf(FAILURE, "TTBR0 written with %p expected %p\n", + ttbr0, mmu_get_tt_top_level()); + test_unwind(REASON_PTE_BASE); + } +} + +void arm_flush_tlbs(void) +{ + mmu_printf(INFO, "arm_flush_tlbs()\n"); + state.arm_flush_tlbs_called = true; +} + +void platform_mmu_setup(bool resume) +{ + (void) resume; + uint64_t alloc_start, alloc_next, alloc_end; + mmu_get_tt_alloc_range(&alloc_start, &alloc_next, &alloc_end); + mmu_printf(INFO, "platform_mmu_setup(%d)\n", (int) resume); + mmu_printf(INFO, "tt_top_level = %p\n", mmu_get_tt_top_level()); + mmu_printf(INFO, "page_tables_base = %p\n", state.page_tables_base); + mmu_printf(INFO, "page_tables_size = 0x%" PRIx64 "\n", + (uint64_t) state.page_tables_size); + mmu_printf(INFO, "tt_alloc_start = 0x%" PRIx64 "\n" + "tt_alloc_next = 0x%" PRIx64 "\n" + "tt_alloc_end = 0x%" PRIx64 "\n", + (uint64_t) alloc_start, + (uint64_t) alloc_next, + (uint64_t) alloc_end); + if (state.mmu_setup_func) { + state.mmu_setup_func(); + } +} + +// Test setup functions. + +static void reset_state(void) +{ + mmu_reset_state(); + assert(state.page_tables_base == NULL); // Prevent leak. + memset(&state, 0, sizeof(state)); +} + +static void mmu_setup_flat(void) +{ + uint64_t io_base = 0x200000000ULL; + uint64_t io_size = 256ULL * 1024 * 1024; + uint64_t sdram_base = 0x800000000ULL; + uint64_t sdram_len = 1ULL << 30; + arm_mmu_map_rw(sdram_base, sdram_len); + arm_mmu_map_device_rw(io_base, io_size); +} + +static void mmu_setup_fail_remap_existing(void) +{ + uint64_t io_base = 0x200000000ULL; + uint64_t io_size = 256ULL * 1024 * 1024; + arm_mmu_map_rw(io_base, io_size); + // Map again + arm_mmu_map_device_rw(io_base, io_size); +} + +static void mmu_setup_fail_breaking_down(void) +{ + uint64_t io_base = 0x200000000ULL; + uint64_t io_size = 256ULL * 1024 * 1024; + arm_mmu_map_rw(io_base, io_size); + // Map one L3 page again + arm_mmu_map_rw(io_base, 4096); +} + +static void mmu_setup_misaligned(void) +{ + uint64_t sdram_base = 0x800000000ULL; + uint64_t sdram_len = 1ULL << 30; + arm_mmu_map_rw(sdram_base, sdram_len + 512); +} + +static void test_delete(void) +{ + uint64_t alloc_start, alloc_next, alloc_end; + mmu_get_tt_alloc_range(&alloc_start, &alloc_next, &alloc_end); + mmu_printf(INFO, "Allocation space used: 0x%" PRIx64 "\n", + alloc_next - alloc_start); + mmu_printf(INFO, "Allocation space remaining: 0x%" PRIx64 "\n", + alloc_end - alloc_next); + if (state.page_tables_base) { + free(state.page_tables_base); + state.page_tables_base = NULL; + } + reset_state(); +} + +static int mmu_test(void) +{ + mmu_printf(INFO, "Test \"%s\" running\n", state.test_name); + int ret = posix_memalign(&state.page_tables_base, + 1 << state.page_granule_shift, + state.page_tables_size); + assert(ret == 0); + memset(state.page_tables_base, 0, state.page_tables_size); + arm_mmu_init(false); + // Calls back on platform_mmu_setup(resume) + if (state.arm_flush_tlbs_called) { + return true; + } else { + mmu_printf(FAILURE, "!!! arm_flush_tlbs() was not called\n"); + return false; + } +} + +static void do_test(enum Reason expect_reason, int (^test_func)(void)) +{ + assert(state.test_name != NULL); + mmu_printf(INFO, "----------------------------------------" + "--------------------------------------\n"); + mmu_printf(INFO, "Test: %s\n", state.test_name); + + // Increment number of tests run. + ++tests_run; + + // Set a jump environment for panic/abort exit path. + int reason_code = setjmp(state.jmp_env); + if (reason_code != 0) { + // Returns non-zero if longjmp() invoked to return here. + if (reason_code == (int) expect_reason) { + // Failure for an expected reason: exercising error + // detection. + mmu_printf(INFO, "Test \"%s\" aborted for expected reason: %s\n", + state.test_name, + reason_to_string(expect_reason)); + ++tests_passed; + } else { + mmu_printf(FAILURE, "!!! Test \"%s\" failed: %s\n", + state.test_name, + reason_to_string(reason_code)); + mmu_printf(FAILURE, "!!! Expected outcome: %s\n", + reason_to_string(expect_reason)); + } + test_delete(); + reset_state(); + return; + } + + if (test_func()) { + mmu_printf(INFO, "Test \"%s\" completed, passed\n", + state.test_name); + ++tests_passed; + } else { + mmu_printf(FAILURE, "!!! Test \"%s\" failed at completion\n", + state.test_name); + mmu_printf(FAILURE, "!!! Expected outcome: %s\n", + reason_to_string(expect_reason)); + } + + test_delete(); + reset_state(); +} + +static void setup_standard_granule(size_t granule) +{ + switch (granule) { + case 4096: + state.page_granule_shift = 12; + state.page_tables_size = 4096 * 4; + break; + + case 16384: + state.page_granule_shift = 14; + state.page_tables_size = 16384 * 4; + break; + + case 65536: + state.page_granule_shift = 16; + state.page_tables_size = 65536 * 4; + break; + + default: + mmu_printf(FAILURE, "Bad granule %u\n", (unsigned) granule); + abort(); + } +} + +static void test_granule(size_t bytes) +{ + state.mmu_setup_func = ^{ mmu_setup_flat(); }; + setup_standard_granule(bytes); + do_test(REASON_OK, ^{ return mmu_test(); }); +} + +static void test_granule_4kb(void) +{ + state.test_name = "4KB granule"; + test_granule(4096); +} + +static void test_granule_16kb(void) +{ + state.test_name = "16KB granule"; + test_granule(16384); +} + +static void test_granule_64kb(void) +{ + state.test_name = "64KB granule"; + test_granule(65536); +} + +static void test_fail_oom(void) +{ + state.test_name = "Detect out-of-memory PTE allocation"; + state.mmu_setup_func = ^{ mmu_setup_flat(); }; + setup_standard_granule(4096); + // Too small. + state.page_tables_size = 16384; + expect_panic("tt_alloc", "Out of table allocation space L2"); + do_test(REASON_EXPECTED_PANIC, ^{ return mmu_test(); }); +} + +static void test_fail_range_misaligned(void) +{ + state.test_name = "Detect misaligned mapping request"; + state.mmu_setup_func = ^{ mmu_setup_misaligned(); }; + setup_standard_granule(4096); + // Expect vaddr, paddr, size to misaligned. + expect_panic("arm_mmu_map_range", "vaddr | paddr | size"); + do_test(REASON_EXPECTED_PANIC, ^{ return mmu_test(); }); +} + +static void test_fail_bad_granule(void) +{ + state.test_name = "Detect bad granule size"; + state.mmu_setup_func = ^{ + // Alter the granule to an illegal value. + ++state.page_granule_shift; + mmu_setup_flat(); + }; + setup_standard_granule(4096); + expect_panic("get_level_shift", "Granule 2^13"); + do_test(REASON_EXPECTED_PANIC, ^{ return mmu_test(); }); +} + +static void test_fail_remap_existing(void) +{ + state.test_name = "Detect remapping existing page"; + state.mmu_setup_func = ^{ mmu_setup_fail_remap_existing(); }; + setup_standard_granule(4096); + expect_panic("map_at_level", "Remapping an existing L2"); + do_test(REASON_EXPECTED_PANIC, ^{ return mmu_test(); }); +} + +static void test_fail_breaking_down(void) +{ + state.test_name = "Detect breaking down existing mapping"; + state.mmu_setup_func = ^{ mmu_setup_fail_breaking_down(); }; + setup_standard_granule(4096); + expect_panic("map_at_level", "Breaking down"); + do_test(REASON_EXPECTED_PANIC, ^{ return mmu_test(); }); +} + +static void test_get_tcr(void) +{ + state.test_name = "get_tcr()"; + do_test(REASON_OK, + ^{ + state.page_granule_shift = 12; + mmu_get_tcr(); + state.page_granule_shift = 14; + mmu_get_tcr(); + state.page_granule_shift = 16; + mmu_get_tcr(); + return true; + }); +} + +static void test_fail_get_tcr_bad_granule(void) +{ + state.test_name = "Detect get_tcr() with bad granule"; + expect_panic("get_tcr", "Bad granule"); + state.page_granule_shift = 13; + do_test(REASON_EXPECTED_PANIC, ^{ mmu_get_tcr(); return false; }); +} + +static void test_get_block_flags_for_level(unsigned level) +{ + // [63:59] SBZ + // [58:55] S/W use SBZ + // [54:53] XN,PXN = execute never, 0 for RX, 3 for R/RW + // [52] Contiguous hint, SBZ + // [51:12] SBZ and address bits, also SBZ + // [11] nG - non-global, we don't use ASID - SBZ + // [10] AF - access flag, should set - SBO + // [9:8] SH - shareability - 0 for device, 2 for normal + // [7:6] AP - access permission - 0 for RW, 2 for RO + // [5] NS - non-secure, should set - SBO + // [4:2] AttrIndx - 0 for device, 1 for normal + // [1] Walk - L0,L1,L2 0=Block; L3 1=Block + // [0] V - 0=fault, 1=valid + const uint64_t sbo = (1 << 10) | (1 << 5) | (1 << 0); + const uint64_t normal = (2 << 8) | (1 << 2); + const uint64_t device = (0 << 8) | (0 << 2); + const uint64_t read_write = 0 << 6; + const uint64_t read_only = 2 << 6; + const uint64_t execute = 0ULL << 53; + const uint64_t no_execute = 3ULL << 53; + static const struct { + arm_mmu_extended_attr_t attr; + uint64_t expect; + } tests[] = { + { kARMMMUDeviceR, sbo | device | read_only | no_execute }, + { kARMMMUDeviceRX, sbo | device | read_only | execute }, + { kARMMMUDeviceRW, sbo | device | read_write | no_execute }, + { kARMMMUNormalR, sbo | normal | read_only | no_execute }, + { kARMMMUNormalRX, sbo | normal | read_only | execute }, + { kARMMMUNormalRW, sbo | normal | read_write | no_execute }, + }; + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { + arm_mmu_extended_attr_t attr = tests[i].attr; + uint64_t expect = tests[i].expect; + if (level == 3) { + expect |= 1 << 1; // "Walk" flag + } + uint64_t value = mmu_get_block_flags(level, attr); + if (value != expect) { + mmu_printf(FAILURE, "get_block_flags level %u test %u enum %u\n", + level, (unsigned) i, (unsigned) attr); + mmu_printf(FAILURE, "got 0x%" PRIx64 "\n", value); + mmu_printf(FAILURE, "expect 0x%" PRIx64 "\n", expect); + test_unwind(REASON_PTE_MISMATCH); + } + } +} + +static void test_get_block_flags(void) +{ + state.test_name = "get_block_flags()"; + state.page_granule_shift = 12; + do_test(REASON_OK, ^{ + for (unsigned level = 1; level <= 3; ++level) { + test_get_block_flags_for_level(level); + } + return true; + }); +} + +static void test_get_table_flags(void) +{ + state.test_name = "get_tte_flags()"; + state.page_granule_shift = 12; + // [63] NS + // [62:61] AP + // [60] XN + // [59] PXN + // [58:52] ignored + // [51:48] zero, sbz + // [47:12] TableOutputAddress + // [11:2] ignored + // [1] type=1, sbo + // [0] valid=1, sbo + const uint64_t expect = (1ULL << 63) | (1ULL << 1) | (1ULL << 0); + do_test(REASON_OK, ^{ + uint64_t value = mmu_get_table_flags(); + if (value != expect) { + mmu_printf(FAILURE, "get_table_flags() mismatch\n"); + mmu_printf(FAILURE, "Got 0x%" PRIx64 "\n", value); + mmu_printf(FAILURE, "Expect 0x%" PRIx64 "\n", expect); + test_unwind(REASON_PTE_MISMATCH); + } + return true; + }); +} + +static void test_fail_get_block_flags_bad_attr(void) +{ + state.test_name = "Detect get_block_flags() bad attribute"; + state.page_granule_shift = 12; + expect_panic("get_block_flags", "Bad attr"); + do_test(REASON_EXPECTED_PANIC, + ^{ mmu_get_block_flags(3, -1); return false; }); +} + +static void test_fail_get_block_flags_bad_level(void) +{ + state.test_name = "Detect get_pte_flags() bad level"; + state.page_granule_shift = 16; + expect_panic("get_block_flags", "level_permits_blocks"); + // Should not allow a block at L1 with 64KB granule. + do_test(REASON_EXPECTED_PANIC, + ^{ mmu_get_block_flags(1, kARMMMUNormalRW); return false; }); +} + +static void test_tt_alloc(unsigned granule_shift) +{ + state.test_name = "tt_alloc()"; + state.page_granule_shift = granule_shift; + state.page_tables_size = (1 << granule_shift) * 3; + state.mmu_setup_func = ^{}; + do_test(REASON_OK, + ^{ + arm_mmu_init(false); + if (granule_shift == 12) + mmu_tt_alloc(2); + mmu_tt_alloc(3); + return true; + }); +} + +static void test_tt_alloc_bad_level(void) +{ + state.test_name = "Detect tt_alloc() bad level"; + state.page_granule_shift = 14; + state.page_tables_size = 16384 * 3; + state.mmu_setup_func = ^{}; + expect_panic("tt_alloc", "level > "); + do_test(REASON_EXPECTED_PANIC, + ^{ + arm_mmu_init(false); + mmu_tt_alloc(1); + return false; + }); +} + +static void test_tt_alloc_bad_alignment(void) +{ + state.test_name = "Detect tt_alloc() bad alignment"; + state.page_granule_shift = 14; + state.page_tables_size = 65536 * 3; // Enough space. + state.mmu_setup_func = ^{}; + expect_panic("tt_alloc", "Bad aligned pte alloc"); + do_test(REASON_EXPECTED_PANIC, + ^{ + arm_mmu_init(false); + mmu_tt_alloc(3); + // Allocation is aligned, so only way to trip it up + // is to artificially tamper with the granule. + state.page_granule_shift = 16; + mmu_tt_alloc(3); + return false; + }); +} + +static void test_map_at_top_level_large(void) +{ + state.test_name = "map_at_level() at top level traverses only L1"; + setup_standard_granule(4096); + __block uint64_t alloc_start, alloc_next, alloc_end; + state.mmu_setup_func = ^{ + mmu_get_tt_alloc_range(&alloc_start, &alloc_next, &alloc_end); + mmu_map_at_level(1, + (addr_t) mmu_get_tt_top_level(), + 1ULL << 30, 1ULL << 30, 1ULL << 30, + kARMMMUNormalRW); + }; + __block size_t calls = 0; + state.set_table_entry_hook = ^(unsigned level, + uint64_t base, + size_t index, + uint64_t value) { + (void) value; + ++calls; + mmu_printf(INFO, "calls:%u %u 0x%" PRIx64 " 0x%" PRIx64 + " 0x%" PRIx64 "\n", + (unsigned) calls, + level, base, (uint64_t) index, value); + if (calls == 1) { + if (level != 1 || + base != (uint64_t) mmu_get_tt_top_level() || + index != 1) { + mmu_printf(FAILURE, "Did not write L0 index 0\n"); + test_unwind(REASON_PTE_ACCESS); + } + } else { + mmu_printf(FAILURE, "Too many calls to get_table_entry()\n"); + test_unwind(REASON_PTE_ACCESS); + } + }; + do_test(REASON_OK, + ^{ + if (!mmu_test()) { + return false; + } + return true; + }); +} + +static void test_map_at_l3(void) +{ + state.test_name = "map_at_level() at l3"; + setup_standard_granule(16384); + __block uint64_t alloc_start = 0, alloc_next = 0, alloc_end = 0; + __block uint64_t l3_base = 0; + state.mmu_setup_func = ^{ + mmu_get_tt_alloc_range(&alloc_start, &alloc_next, &alloc_end); + l3_base = mmu_tt_alloc(3); + mmu_map_at_level(3, l3_base, + (1ULL << 30) + 16384 * 3, + 16384 * 7, + 16384, + kARMMMUDeviceRW); + }; + __block size_t calls = 0; + state.set_table_entry_hook = ^(unsigned level, + uint64_t base, + size_t index, + uint64_t value) { + (void) value; + ++calls; + mmu_printf(INFO, "calls:%u %u 0x%" PRIx64 " 0x%" PRIx64 + " 0x%" PRIx64 "\n", + (unsigned) calls, + level, base, (uint64_t) index, value); + if (calls == 1) { + if (level != 3 || + base != l3_base || + index != 3) { + mmu_printf(FAILURE, "Did not write L3 index 3\n"); + test_unwind(REASON_PTE_ACCESS); + } + } else { + mmu_printf(FAILURE, "Too many calls to get_table_entry()\n"); + test_unwind(REASON_PTE_ACCESS); + } + }; + do_test(REASON_OK, + ^{ + if (!mmu_test()) { + return false; + } + return true; + }); +} + +int main() +{ + reset_state(); + + test_granule_4kb(); + test_granule_16kb(); + test_granule_64kb(); + + test_fail_oom(); + test_fail_range_misaligned(); + test_fail_bad_granule(); + + test_fail_remap_existing(); + test_fail_breaking_down(); + + test_get_tcr(); + // test_fail_get_tcr_bad_granule(); !!!FIXME!!! Unexpected panic in function get_virt_address_bits: Bad granule + + test_get_block_flags(); + test_get_table_flags(); + test_fail_get_block_flags_bad_attr(); + test_fail_get_block_flags_bad_level(); + + test_tt_alloc(12); + test_tt_alloc(14); + test_tt_alloc(16); + test_tt_alloc_bad_level(); + test_tt_alloc_bad_alignment(); + + test_map_at_top_level_large(); + test_map_at_l3(); + + mmu_printf(INFO, "%" PRIu64 "/%" PRIu64 " tests passed\n", + (uint64_t) tests_passed, (uint64_t) tests_run); + assert(tests_passed <= tests_run); + if (tests_passed == tests_run) { + mmu_printf(INFO, "Pass\n"); + return 0; + } else { + mmu_printf(INFO, "!!! Fail\n"); + return 1; + } +} diff --git a/arch/arm64/rules.mk b/arch/arm64/rules.mk new file mode 100644 index 0000000..d14df38 --- /dev/null +++ b/arch/arm64/rules.mk @@ -0,0 +1,176 @@ +# Copyright (C) 2011-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# +# ARM CPU config +# + +# sanity check +ifeq ($(ARM_CPU),) +$(error ARM_CPU is not set) +endif + +ifneq ($(ARM_ARCH),) +$(info ARM_ARCH does not need to be set at the platform level) +endif + +ARCH_ARMV8_CPUS := apple-cyclone apple-typhoon apple-typhoon-capri apple-twister apple-hurricane-zephyr + +################################################################################ +# Per-CPU configuration +################################################################################ + +# +# Apple Cyclone/Typhoon +# +ifneq (,$(filter $(ARCH_ARMV8_CPUS),$(ARM_CPU))) +ARM_ARCH ?= arm64 +ARM_ARCH_OPTIONS := ARCH_ARMv8=1 WITH_VFP=1 WITH_VFP_ALWAYS_ON=1 +OPTIONS += \ + CPU_APPLE_CYCLONE=1 \ + L1_CACHELINE_SIZE=64 \ + L1_CACHELINE_SHIFT=6 \ + CPU_CACHELINE_SIZE=L1_CACHELINE_SIZE \ + CPU_CACHELINE_SHIFT=L1_CACHELINE_SHIFT \ + WITH_HW_TIMER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/mmu.o \ + $(LOCAL_DIR)/timer.o + +ifneq (,$(filter apple-cyclone apple-typhoon,$(ARM_CPU))) +WITH_EL3 := 1 +OPTIONS += \ + L1_CACHEINDEX_SHIFT=9 \ + L1_CACHEWAY_SHIFT=1 \ + L2_CACHE_SIZE=1048576 \ + L2_CACHEINDEX_SHIFT=11 \ + L2_CACHEWAY_SHIFT=3 \ + L2_CACHEWAY_COUNT=8 \ + L2_CACHELINE_SHIFT=6 \ + PAGE_GRANULE_SHIFT=12 \ + PAGE_SIZE=4096 \ + WITH_EL3=1 \ + WITH_MCC_AS_RAM=1 + +#4k-algined linker pages +GLOBAL_LDFLAGS += -Wl,-segalign,0x1000 + +else ifneq (,$(filter apple-typhoon-capri,$(ARM_CPU))) +WITH_EL3 := 1 +OPTIONS += \ + L1_CACHEINDEX_SHIFT=9 \ + L1_CACHEWAY_SHIFT=1 \ + L2_CACHE_SIZE=2097152 \ + L2_CACHEINDEX_SHIFT=12 \ + L2_CACHEWAY_SHIFT=3 \ + L2_CACHEWAY_COUNT=8 \ + L2_CACHELINE_SHIFT=6 \ + PAGE_GRANULE_SHIFT=12 \ + PAGE_SIZE=4096 \ + WITH_EL3=1 \ + WITH_MCC_AS_RAM=1 + +#4k-algined linker pages +GLOBAL_LDFLAGS += -Wl,-segalign,0x1000 + +else ifneq (,$(filter apple-twister,$(ARM_CPU))) +WITH_EL3 := 1 +OPTIONS += \ + L1_CACHEINDEX_SHIFT=8 \ + L1_CACHEWAY_SHIFT=2 \ + L2_CACHE_SIZE=3145728 \ + L2_CACHEINDEX_SHIFT=12 \ + L2_CACHEWAY_SHIFT=4 \ + L2_CACHEWAY_COUNT=12 \ + L2_CACHELINE_SHIFT=6 \ + PAGE_GRANULE_SHIFT=14 \ + PAGE_SIZE=16384 \ + WITH_EL3=1 \ + WITH_MCC_AS_RAM=1 + +#16k-algined linker pages +GLOBAL_LDFLAGS += -Wl,-segalign,0x4000 + +else ifneq (,$(filter apple-hurricane-zephyr,$(ARM_CPU))) +OPTIONS += \ + L1_CACHEINDEX_SHIFT=8 \ + L1_CACHEWAY_SHIFT=2 \ + L2_CACHE_SIZE=3145728 \ + L2_CACHEINDEX_SHIFT=11 \ + L2_CACHEWAY_SHIFT=4 \ + L2_CACHEWAY_COUNT=12 \ + L2_CACHELINE_SHIFT=7 \ + PAGE_GRANULE_SHIFT=14 \ + PAGE_SIZE=16384 \ + WITH_L2_AS_RAM=1 + +#16k-algined linker pages +GLOBAL_LDFLAGS += -Wl,-segalign,0x4000 + +endif + +endif + +################################################################################ +# General and conditional configuration +################################################################################ + +# sanity check +ifeq ($(ARM_ARCH),) +$(error ARM_ARCH not set, no valid CPU selected) +endif + +# build for the proper cpu +OPTIONS += ARCH_ARM=1 +GLOBAL_ALLFLAGS += -arch $(ARM_ARCH) $(addprefix -D,$(ARM_ARCH_OPTIONS)) +GLOBAL_LDFLAGS += -arch $(ARM_ARCH) + +# Tell the build system how libraries should be tagged +LIBRARY_TAG += $(ARM_ARCH) +LIBRARY_OPTIONS += ARCH=arm64 ARM_ARCH=$(ARM_ARCH) + +GLOBAL_INCLUDES += arch/arm/include +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# Defaults for stack sizes (stacks laid out from top to bottom as listed) +INTERRUPT_STACK_SIZE ?= 8192 +BOOTSTRAP_STACK_SIZE ?= 4096 +EXCEPTION_STACK_SIZE ?= 4096 +OPTIONS += \ + INTERRUPT_STACK_SIZE=$(INTERRUPT_STACK_SIZE) \ + EXCEPTION_STACK_SIZE=$(EXCEPTION_STACK_SIZE) \ + BOOTSTRAP_STACK_SIZE=$(BOOTSTRAP_STACK_SIZE) + +# Force start.o and asm.o to link first +ALL_OBJS := \ + $(LOCAL_DIR)/start.o \ + $(LOCAL_DIR)/asm.o \ + $(ALL_OBJS) + +# Code common to all cores +ALL_OBJS += \ + $(LOCAL_DIR)/cpu.o \ + $(LOCAL_DIR)/context.o \ + $(LOCAL_DIR)/entropy.o \ + $(LOCAL_DIR)/fp.o \ + $(LOCAL_DIR)/handlers.o \ + $(LOCAL_DIR)/task.o + +ifeq ($(WITH_EL3),1) +ALL_OBJS += \ + $(LOCAL_DIR)/exceptions_el3.o +else +ALL_OBJS += \ + $(LOCAL_DIR)/exceptions_el1.o +endif + +LINKER_EXPORTS := $(LOCAL_DIR)/link.exp diff --git a/arch/arm64/start.S b/arch/arm64/start.S new file mode 100644 index 0000000..72607a2 --- /dev/null +++ b/arch/arm64/start.S @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + + .text + .align 12 + .no_dead_strip _start + .globl _start +_start: + // Relocate, if needed + adrp x0, _start@page + add x0, x0, _start@pageoff + ldr x1, L_TEXT_BASE + +#ifdef PLATFORM_START_FUNCTION + /* + * x0 and x1 must be preserved + * 'eq' will be true if no text relocation is required + */ + bl PLATFORM_START_FUNCTION +#endif + + cmp x1, x0 + b.eq L__continue_start + + +#if !CPU_APPLE_CYCLONE + mov x2, #(SCTLR_I_ENABLED) + msr SCTLR_ELx, x2 + ic iallu +#endif + + mov lr, x1 + ldr x2, L_TEXT_END + ldr x3, L_TEXT_BASE + sub x2, x2, x3 +L__relocate_loop: + ldp x3, x4, [x0], #16 + stp x3, x4, [x1], #16 + subs x2, x2, #16 + b.ne L__relocate_loop + ret + +L__continue_start: + // Disable all interrupts + msr DAIFSet, #(DAIFSC_ALL) + + // Setup return address (virtual) + adrp lr, __main@page + add lr, lr, __main@pageoff + + // Set up exception vectors + adrp x10, _exception_vector_base@page + add x10, x10, _exception_vector_base@pageoff + msr VBAR_ELx, x10 + + // bzero stacks region + ldr x10, L_STACKS_BASE + ldr x11, L_STACKS_SIZE + add x11, x11, x10 + mov x12, #0 +L__stacks_zero_loop: + stp x12, x12, [x10], #16 + cmp x10, x11 + b.ne L__stacks_zero_loop + + // bzero page tables region + ldr x10, L_PAGE_TABLES_BASE + ldr x11, L_PAGE_TABLES_SIZE + add x11, x11, x10 + mov x12, #0 +L__tables_zero_loop: + stp x12, x12, [x10], #16 + cmp x10, x11 + b.ne L__tables_zero_loop + + // Set up stack pointers + ldr x10, L_STACKS_BASE + + // exception stack goes at very bottom + add x10, x10, #(EXCEPTION_STACK_SIZE) + mov sp, x10 // set SPx to exception stack + + // bootstrap stack above exception stack + msr SPSel, #0 // switch to SP0 + add x10, x10, #(BOOTSTRAP_STACK_SIZE) + mov sp, x10 // set SP0 to bootstrap stack + + // Save interrupt stack top, to be stored after bss is cleared + // interrupt stack goes at top so that it can share with bootstrap + // stack after bootstrap task exits + add x20, x10, #(INTERRUPT_STACK_SIZE) + + // SecureROM: relocate data to SRAM +#if APPLICATION_SECUREROM + ldr x10, L_DATA_RO_START + mov x11, #(PAGE_SIZE - 1) + add x10, x10, x11 + bic x10, x10, x11 + ldr x11, L_DATA_BASE + cmp x10, x11 + b.eq L__do_bss + + ldr x12, L_DATA_END +L__relocate_data_loop: + ldp x13, x14, [x10], #16 + stp x13, x14, [x11], #16 + cmp x11, x12 + b.ne L__relocate_data_loop +#endif // APPLICATION_SECUREROM + + // Clear the bss section + // We requested all the sections to be aligned by 64. + // Section length should be 4 byte aligned. +L__do_bss: + ldr x10, L_BSS_START + ldr x11, L_BSS_END + mov x12, #15 + bic x12, x11, x12 + mov x13, #0 +L__bss_loop_stp: + stp x13, x13, [x10], #16 + cmp x10, x12 + b.ne L__bss_loop_stp + cmp x11, x12 + b.eq L__bss_done +L__bss_loop_word: + str w13, [x10], #4 + cmp x10, x11 + b.lt L__bss_loop_word +L__bss_done: + + // Store interrupt stack top + adrp x11, _interrupt_stack_top@page + add x11, x11, _interrupt_stack_top@pageoff + str x20, [x11] + +#if defined(HEAP_GUARD) && (HEAP_GUARD != SRAM_END) + // Clear the heap guard page, which will never be mapped + mov x13, #0 + ldr x10, L_HEAP_GUARD + mov x11, #(PAGE_SIZE) + add x11, x10, x11 +L__loop_heap_guard: + stp x13, x13, [x10], #16 + stp x13, x13, [x10], #16 + stp x13, x13, [x10], #16 + stp x13, x13, [x10], #16 + cmp x10, x11 + b.ne L__loop_heap_guard +#endif + +#ifdef BOOT_TRAMPOLINE_BASE + // copy the trampoline into a non-writeable page + ldr x3, L_boot_trampoline_start + ldr x4, L_boot_trampoline_end + ldr x5, L_boot_trampoline_dst +1: + ldp x6, x7, [x3], #16 + stp x6, x7, [x5], #16 + cmp x3, x4 + b.lo 1b +#endif + + + // Branch to main + ret + + + .org 0x200 +L__build_banner_string: + .ascii CONFIG_PROGNAME_STRING + .ascii " for " + .ascii CONFIG_BOARD_STRING + .ascii ", Copyright 2007-2016, Apple Inc." + + .org 0x240 +L__build_style_string: + .ascii BUILD_STYLE + +/* This will get replaced by macho_post_process.py so that the build tag + is accurate even for iterative desktop builds that don't rebuild start.o */ + .org 0x280 +_build_tag_string_contents: + + .org 0x300 + .globl _build_banner_string +_build_banner_string: + .8byte L__build_banner_string + + .balign 8 + .globl _build_style_string +_build_style_string: + .8byte L__build_style_string + + .balign 8 + .globl _build_tag_string +_build_tag_string: + .8byte _build_tag_string_contents + + .balign 8 + // Linked start and end addresses of the text +L_TEXT_BASE: + .8byte (TEXT_BASE) +L_TEXT_END: + .8byte section$start$__DATA$__zerofill +L_TEXT_SIZE: + .8byte segment$end$__TEXT - segment$start$__TEXT + + // start address of the data in the read only text */ +L_DATA_RO_START: + .8byte segment$end$__TEXT + + // Linked start and end addresses of the data +L_DATA_BASE: + .8byte segment$start$__DATA +L_DATA_END: + .8byte section$start$__DATA$__zerofill + + // Linked start and end addresses of the zero-filled range +L_BSS_START: + .8byte section$start$__DATA$__zerofill +L_BSS_END: + .8byte segment$end$__DATA + +L_STACKS_BASE: + .8byte (STACKS_BASE) +L_STACKS_SIZE: + .8byte (STACKS_SIZE) +L_PAGE_TABLES_BASE: + .8byte (PAGE_TABLES_BASE) +L_PAGE_TABLES_SIZE: + .8byte (PAGE_TABLES_SIZE) + +#if defined(HEAP_GUARD) && (HEAP_GUARD != SRAM_END) +L_HEAP_GUARD: + .8byte (HEAP_GUARD) +#endif +#ifdef BOOT_TRAMPOLINE_BASE +L_boot_trampoline_start: + .8byte _boot_handoff_trampoline +L_boot_trampoline_end: + .8byte _boot_handoff_trampoline_end +L_boot_trampoline_dst: + .8byte BOOT_TRAMPOLINE_BASE +#endif + + .data + + .globl _interrupt_stack_top +_interrupt_stack_top: + .space 8 diff --git a/arch/arm64/task.c b/arch/arm64/task.c new file mode 100644 index 0000000..b6b7e0a --- /dev/null +++ b/arch/arm64/task.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include + +static void arch_task_trampoline(void) __noreturn; + +static void +arch_task_trampoline(void) +{ + /* exit the critical section we implicitly started with */ + exit_critical_section(); + + dprintf(DEBUG_SPEW, "arch_task_trampoline: task %p (%s) routine %p, arg %p\n", + current_task, current_task->name, current_task->routine, current_task->arg); + + /* call the start routine */ + int ret = current_task->routine(current_task->arg); + + dprintf(DEBUG_SPEW, "arch_task_trampoline: task %p (%s) exits with %d\n", + current_task, current_task->name, ret); + + task_exit(ret); + + /* never return */ +} + +int +arch_task_create(struct task *t) +{ + int i; + + for (i=0; i < 29; i++) + t->arch.regs[i] = 0; + + /* set the default starting point to be arch_task_trampoline */ + t->arch.lr = (uintptr_t)&arch_task_trampoline; + t->arch.sp = (uintptr_t)t->stack_base + t->stack_len; + t->arch.fp = 0; + + return 0; +} diff --git a/arch/arm64/test.mk b/arch/arm64/test.mk new file mode 100644 index 0000000..d37c060 --- /dev/null +++ b/arch/arm64/test.mk @@ -0,0 +1,56 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +CC := $(shell xcodebuild -sdk macosx.internal -find clang) +GCOV := $(shell xcodebuild -sdk macosx.internal -find gcov) + +TEST_DIR := host_tests + +INCDIRS := . \ + include \ + ../arm/include \ + ../../include + +CFLAGS := -arch x86_64 \ + -std=c11 \ + -g -Wall -Werror -O \ + $(addprefix -I,$(INCDIRS)) \ + -DARCH_ARMv8 -DTEST + +TESTS := mmu_test + +TEST_PASSES := $(patsubst %,$(TEST_DIR)/%.pass,$(TESTS)) + +.PHONY: all +all: host-tests + +.PHONY: host-tests +host-tests: $(TEST_PASSES) + +.PHONY: clean +clean: + rm -rf $(TEST_DIR) + rm -f *.gcno *.gcda + +$(TEST_DIR)/mmu_test.pass: $(TEST_DIR)/mmu_test + @echo "Test running $(notdir $<)" + @rm -f mmu_test.gcda mmu.gcda + @$< 2>&1 1>$(TEST_DIR)/mmu_test.out || \ + { cat $(TEST_DIR)/mmu_test.out; false; } + @echo "Test passed $(notdir $<)" + @$(GCOV) -a mmu.c + @mv -f mmu.c.gcov $(TEST_DIR) + @grep '#####' $(TEST_DIR)/mmu.c.gcov || true + @touch $@ + +$(TEST_DIR)/mmu_test: mmu_test.c mmu.c + @echo "Build $(notdir $@)" + @mkdir -p $(dir $@) + @$(CC) -o $@ $^ $(CFLAGS) --coverage diff --git a/arch/arm64/tests-mmu.mk b/arch/arm64/tests-mmu.mk new file mode 100644 index 0000000..f0ebe4a --- /dev/null +++ b/arch/arm64/tests-mmu.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := arm64-mmu + +TEST_OBJS := \ + $(LOCAL_DIR)/mmu.o \ + +TEST_SUPPORT_OBJS := \ + $(LOCAL_DIR)/mmu_test.o + +TEST_CFLAGS := \ + -DCPU_CACHELINE_SIZE=64 \ + -DARCH_ARMv8=1 \ + -DTEST=1 \ + -Iarch/arm64/include/ \ + -Iarch/arm/include + +TEST_INCLUDES := \ + arch/arm64/include/ \ + arch/arm/include diff --git a/arch/arm64/timer.c b/arch/arm64/timer.c new file mode 100644 index 0000000..a0af792 --- /dev/null +++ b/arch/arm64/timer.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +extern void arm_write_cntp_ctl(uint64_t); +extern uint64_t arm_read_cntp_ctl(); +extern void arm_write_cntp_tval(uint64_t); +extern uint64_t arm_read_cntpct(); + +static void timer_deadline(void *arg); +static void (* timer_deadline_func)(void); + +#define DECR_MAX_COUNT (INT32_MAX) + +int timer_init(uint32_t timer) +{ + uint64_t val; + + val = (0<<0) | (1<<1); + arm_write_cntp_ctl(val); + + return 0; +} + +void timer_stop_all(void) +{ + uint64_t val; + + val = (0<<0) | (1<<1); + arm_write_cntp_ctl(val); +} + +void timer_deadline_enter(uint64_t deadline, void (* func)(void)) +{ + uint64_t ticks; + uint64_t decr; + uint64_t val; + + timer_deadline_func = func; + if (func) { + /* convert absolute deadline to relative time */ + ticks = timer_get_ticks(); + if (deadline < ticks) { +// printf(" %llu too soon (it is now %llu)\n", deadline, ticks); + deadline = 0; + } else { + deadline -= ticks; + } + + /* clamp the deadline to our maximum */ + decr = (deadline >= DECR_MAX_COUNT) ? DECR_MAX_COUNT : deadline; + // printf(" using decrementer count %u\n", decr); + + /* + * Reset the decrementer by programming the max count, clearing + * any pending interrupt status, then programming the desired count. + * Note the timer's value is a signed 32 bit number + */ + arm_write_cntp_tval(DECR_MAX_COUNT); + val = (1<<0) | (0<<1); + arm_write_cntp_ctl(val); + arm_write_cntp_tval(decr); + } else { + /* no deadline, disable the decrementer */ + val = (0<<0) | (1<<1); + arm_write_cntp_ctl(val); + } +} + +void arm_fiq() +{ + uint64_t val; + + _irq_enter_critical_section(); + + val = arm_read_cntp_ctl(); + if (val & (1 << 2)) { + /* acknowledge the interrupt and disable the timer */ + val = (0<<0) | (1<<1); + arm_write_cntp_ctl(val); + + /* if we have a callback, invoke it now */ + if (timer_deadline_func) + timer_deadline_func(); + } + + _irq_exit_critical_section(); +} + +#ifdef OSC_FREQ + +utime_t timer_ticks_to_usecs(uint64_t ticks) +{ +#if (OSC_FREQ % 1000000) == 0 + return ticks / (OSC_FREQ / 1000000); +#else +#error "The code below has overflow issues. Make sure you really want to use it" + return (ticks * 1000 * 1000) / OSC_FREQ; +#endif +} + +uint64_t timer_usecs_to_ticks(utime_t usecs) +{ +#if (OSC_FREQ % 1000000) == 0 + return usecs * (OSC_FREQ / 1000000); +#else +#error "The code below has overflow issues. Make sure you really want to use it" + uint64_t timer_scale = ((uint64_t)(OSC_FREQ) << 20) / (1000 * 1000); + return (ticks * timer_scale) >> 20; +#endif +} + +uint32_t timer_get_tick_rate(void) +{ + return OSC_FREQ; +} + +#endif + +uint64_t timer_get_ticks(void) +{ + return (arm_read_cntpct()); +} + +void arm_no_wfe_spin(uint32_t usecs) +{ + uint64_t delta_time = (uint64_t)usecs * (OSC_FREQ / 1000000); + uint64_t start_time; + + start_time = timer_get_ticks(); + while (true) { + if ((timer_get_ticks() - start_time) > delta_time) + break; + } +} diff --git a/docs/Cayman_IOSpreadsheet_Template.xlsx b/docs/Cayman_IOSpreadsheet_Template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e5d086e960f7f24b4c9a6f9bffd556109e191817 GIT binary patch literal 42520 zcmeEtPUG&b!QI{6-CcrPa1ZW~1cJ+Z$Rqc;b2Br4 zz`T5bU++_WcAeU*R;{Y0WyB#M(ZQg>V8Ot^2*IEa%b{bz!N5MifPtZb!M;!zu(Gr_ zw6xb&aIrSD)1-B_Fek`?d_j=~_5!f~|3CkSBQUDCYT8SH-hqFN=i8WDeWDXKRfoCi z*o-m9<2@ZKXsR&t*!~b-F^tFwdli06L8g+67wm3A* zeO%iulH|LONq5{-R5XnrdQi2;!!~5F=XjFbG9Vc&ofGJ?96t-MYr z;e0TIy&WbD%u1enaf<+6;sRQDwSPzfMa;elM%wly@jqoaNP{r_|L|8U~| z)*4J#Xg>u5g@tSU94wo4JV9@DHtlb%Y|2M7}o7eB3*y-HySYtVB)L`PTdP!ndN6*;x&^CK!5Blwyf? z4^uYg+CLm_OPWaRo!Teef96{oqyC6kF(gIUSQeRheE$>fcWLsDyO#(DNFY^6Ft9gZ zu;9+-bbn-ula;NRo|To^bJ6=NYruiZ2iX4K{%MQr7VD!&4)}!{%V|dkj758-cRgAT z9^O$>sWldIjH>lkRz*vWy2Xi`r1VcwPftk*i{^Z(Debwr!*9Sv(IEtK&9#!{x|TO? zcEPb+Ol(!v{a$dAEP&>fQ!&f(krG9eX{x{KiFjXjcxV7gPSB zRFX>_U1-y`Yk3I1m`uLB_hN-t8=TADLgaCI`Sr*AZ$l;WexJ32zT(f}i4x!HP-zBh zbrGPPag|aaLv$k8wUUG(3G|@k(Ybh$*&#TIGe(^qe#_})?l@|`{+aV#jdN7H9sYok709yY9RhayUkUT zqtQjElw>Z}TVpnbEa=*UG;G6MJ*zvyhrzX&a-fL6D!lF zGRjwq`eIad!RdBK#$jgXI&&)+^?ot#^|&JZL~R?`(6OL$*0za!X>zOVwa39?QKHcCWda%PHnvI#k4gVy87TcBSpb<1QNx&6^bMpA;uQ+Q&ChH_G zC&zfi+H4(F$oyF*b0ZQ$UYV_);yY`Y$5V*w;u+Odz`}=2r^7l0u~u4bv1-*aN7sDP z1kj0=wenU$dsm}{(+=t z(g5C@Qzn$qJFcU!8jFTt!)(c&DB&3b$9%XP~OFW zBCb%XGhTSFGfsHo_s{q+wG_A$1Y+3;(c)}es)VXC1{-~UvOMy zZA>nDt}XM58`P@2(K?aLsH##Emlw7++#j}ONG zK<<_64)mF)e`RXY3Dv~2~Ow3LSv zIgnee{euaT9rnHaJMnlUvoAjbp(b8Nd#r5pnAYLYBzE+4HWS)evEw$lHB%=P6V^nQ zzq+-|o#y1U-hUOHZ)G*v7$BT0JCMyLn9xzn&&P4>phnwH7=kT1!B$i+KpvasCR+3L zSeC{GbFei$&0P{|N=7JAORrnLo@Ng9-ZvBu+4w^MhGevwp@9!X&?bu1uCHD@*eROE zjb7l3W`?}^4~)pn@(^ck*a2ZG=WchmjaJ%TK5HGGKX-Q$t+XCD#*8xCU2fb)Mv|{# z3uPTP=Q|&V*1c{hZN!=|2UK3DH`j^zo8 z6yAJ9B6b!CB`)Gbn8Bux+mKz6orqFa#A|EMf5!NVAwNP>+L)ke8~zh-fpL&YxhTl~ z6!MGf7vdCeZ6yazzf!#AG;U#m@xwY^GE7=h5=anB&jhU9=ruAOhSZ_TxOGnnv{#6t z2KlxX$o>0qrJO&|PC-GQFnnL_OItJLH=FK21lK`A5h6!mQ`!kRpA(Vb zoHm_W^x!2BhQac)v!*-M)PL8K`CMSyKPYeFY6S;Hk=B)!VZ@rA zw-RK?zLKZ!$DvWBV(c?LVF#lujV)E`?>$3Tg zN6<&a;8{4N6Ki=S%;oTy@MtPVw4Ckzv+X{$Ouh9!g6HAo}Q%mO3WMx-n>Z6k!m zW2=?OpY>w;a1qOe%`8C)B6pSAA1?Iddu?tsJhT~cZ{N{k-xpKMYIIG+Hm$p?lWZ^} z2rFy(*x0uTx=CY0DhQ9A>sWK0Fi>8x-(QXr-}>Sxg{2@!`dLvs&f-kl1) zVy&TJuSv@TomM<3(=G!x$`no5=%*y~ucq_$2Gs;UC7i8{ITl9Rb|l;4AN!aQ>88?X z`mv#}{3Ppn3FEDGbWznhyADzs8g91r%p#a)nP>!z1{g;4(sJ{8(uDXLtW%t0 zZ(|=cwQGdWfyAJ5-sPj z^d?GkbuN3kXr&44wcyI;tipl>r)GcXgjof+nW||xEibU&A1w7XTB~TQN9!i z)x+1r)u(MKagud^e1YqMQ1~bgvMMxywjx8Sk@wk6tb+0OfJ&pWg|JnIkKV6zuYRu# zy{W{}#s8{Rj>4NCKLrwt#&uIqtSas$V#}z#J9v?v9^1=Ma$HR5Zbdcj5N<@mZ`3uu zqF=E;OgLj-IZUeRO*XXnhe}D!&IP}eIR2!KdThIusAJPHdierzASz^>GS}3Q_K7@uL=q+eCUzj*FCl$BZ5iGMkGDmrYUf~0@!Fd zLTNVN*X80y0E3A8SiCbfjOoatkm*UqD5vhA|*t3DViAhgxsXhRd23ntIdL`;}s&( z@>si4Ec0c+>X7l7@wO9Z;MRsQ`z7Dh5G*0;G(E||LS0WyQ@7_+6_YO(s9C{qq{TAz zT&SmEY|Juuegr2GqCI`yrG8CL6XGGAYrj{ia-PP$QGMBE6$|>TtEgW)7ulKrMVSf9 z9=8T~S2q&$4AZq$H#>X{A{% z->XKml0(7s5Kets^Ho*P!La@%hV6_E z4ejmde*Iy57BXq+>UPT_3FYh3eK$ymJQ50H3W-pMr&A8#)l_tvG?ogVk*pYFUoZ?*3+bO8ShK z`BR6xC(ptvkNd;UYGEZ;M*!P8Yw_02)`0X`X35^w)BTT&pZ&@|P7cmnF)yC(tTH{H zD(XF4Iz=6T``!)kc|DEX?a_7ShID$|-XH9&OXhP`cC>jhJ>1RjS)DyzVqZNNRX?4! z&#m6WC_e2>-&swpXYzI2haGC&Mf~8&Y~ytaPw{-%=_OzBiG7%DER3{r8s3!Tz(Wt@ zs`Pru2l6sAx0K{qAC8b9$b9KRnu2|6AkUo>$Z40Zbrphbt%TOs$8z zOQ)5g<@E0H(!{-Wx(wcqunb-=A!0YK%C&Z{n~Taqj-IvC`;(iUotx0swXh%XlLJ;0 zPiF^a)1ieE(m@|#G}BLXw1X?{RdF#W9y`Y@n4f&qo$*cy9~##tnubDd8kN1=t{zM- z?r%<~0~6PyJevxUr194u&dJi1#IMkJy zBP0ng$?*0{SU!(^g-fbrY0Tu94D74{^rmR7z3uL2qSb^~TMzEp?n?=Zr0x(lx1yN` zVv0lZ0J6d4R#<_zW3OOZO~sTW=|Z~Bl5QS<9%ZrL?)>c3SVm>O;J>>IH_@y{i4GBw zG>|YL+9sHBr-ED}!{fAcGN$4e&R)Qdwj;t6qzxVo(tz_Jj6qDV<6=(Cik-|hBVrS@ z45kjEmjCg_51$dNV}Tta;)AISG=e72AQ*{$Q>Wflm4{cZ#H3EuGGa*$|3|K(ap+e| z{9786Yy4csG4OAW>;0riVG&`S*szWp{R&WLhMRp%PN^~LjO;llps~3$4SYj*roWE> zx6nyRHT09PQ%3bK{1B%z!ET!Iic!@w9gdO1Iu;K5I5lh8JW4d~BkLf^Fe91*t}wV- zfDcTWE_64h<1lxh!oHD+GQuM};@n&47+BL9Lv+2BkRi$B_^4P=1WU-wV~+Z#W(L=r zfUL+)sR2HT%e7PP<9p_olJv369i8|B-cj6PqTi!D-I*Be4QOk5*`Gh1X8NrzC0gAX zP`6Y2qN7P)ep%t9SGA*Jdkd8&#^Wb5f!&{m)=Xe4Y9O>7GMF~V5{*ODDEL}1!G|Qc z+KO?jl2C+cD`Jo*8ipuRP^^*8q|g-GPEq|G2aEXF7`tG;fkDh=K7v<>!M%K6uja7x zT~Pw*_sPZ2F%>GyF+PGjNTbwzFBzyl?hIuaQ=9B&s?j!3FU~wJw^~W#JKlTNu6fDh z6Ww)snO=sESKqBhte)8(Kbj7lRyve5@7Xj7wC@FzAK@M8$H=CO@dWEr?xqbwMT-+L z5h)Aq3RVQKAUBiN5Y!-$?2dWk;`l1`aS>e!z766=r4$zu5K3##&$DC{%qKAqF}Ri| z*~-k3x0L<7EL@L!)bIwh&hXx)6H5I7IUY|eO(y_w_G;`02whL%dKk^7Oci0q)+S%S zT~t>2HjD{A+s2rGInB9dje(a;)`99LNkn$i-zY^%Mr$Us71&M~^c`f3Vz)d_Le3*v zLun@e@qRm6M3ph5IIlcDjUzu#>e(5IznwYt4{MAx<@lVAYQBM`T=ozKPeSFT_Zl-7 zIaf|0BS?RgEH@$a0hfufv}e+{f#bVDyS}?b&Y{AgD6Rm*o*-?I25K@&GZ7=Xt>kvV zAWbw>v>}1b$^rwS$j3HfTj_0|LE`8d17?H1WO=be5&;FVo;>4GhoS32*+N{>t&?1} z2%96yBP{lcBkZk^dOS1{g~u*Vvc95k@#LFWwOJ)QdUONmphh-C8sk(n={c^?10*F< z`5Ao-=yp=uzJsLE*wOEZ?1<(CErV82RgqPpQ3t~D(EjTw5DUd{4k5?K&{M{2NJocx zg-A8KVq4+Q+J?EcFRU{NC?lMCel53Vtg~`Fi|@PUiD8hY!MtnkRxv$(N4dFp&=<>d z5BpG4_)^}4bN5m1P*gl$bs80+lB@w`6obh(U8S4kGdxJCu3qDqJV`U>R!pv&Ta_+} zIUSblr#VTI8@@ouMq9R-oaHb}OtEAjO8-W^TZJsb7u$HEN^|aQvxs@q_9bbx)`Vy^ zISZ(Aj4K88NIJ%XkeshZA$l_$x$r`XVW6-ItTAj&rWRfM5#w%SN?0a2+~FC!vB~>* z_%((Wql>QnXjxT|N{m4YpCMV{aFl|L$Z(Vx9FEaal7R{t%5W5%q(`|)k+qf6abJ6I z>AiaPwhM!KiD?3#4Tbf>vQ}xNUfi%8T+GjiWHZ2>5v9wqNfk3usR*cY?H?jCwwdzf zRP`9eHserqSelF}3@v)hM)qU-0aG-&P`QSJHq=ZFIm;cPP!7&#*gW*E29WBq4~8*@ zOJL^xHYo~2UENB!g~8FEB^hlBu?v#Fjx<>8Xu)Hv6P6w6ve;*`d{Yl9a;r8&40soe z+M6`sRjz!8{kbBzE@6hg!_Mp#)2!_jo;d&MW3MTdWI==NDMkgXO3`DP@F zrk&Wd#?<$NGywPYGRT&B}Y$OhVpzA_@qze$sa=eAWuX99@xh>bF;cc3igo z3^jqRN#A0?tZ(0MJiebY^(t3g2wrF;D5sz}+^`tq%Ln0m+Sdy96Z<|>#KhcaMV{Pf zNrsF_;xrM{?&o&ScJMpwXlz4O5|%o}@eNZMiz~?%UT3dX0}GEcD(UaOiuoCUYU#)> zZ0VFwl10s^>vgP9nY=Z3T3a0(8D}5ss0~WhOx;p>*jK>5I-_vVEz-vLJmzbj@uQFT0nV0q%*Vu+H3?NT!C3$cE@hL>#l59y|Xa_X`(%|iVf zEjso?#-H~?rqZTZa&d$j!(NAdI|3gQC>~L=Uv|=%=gEZ;iVV|vSAyU0?7~9G)(5J7 zhHgFYEi!D!6kS5Jl-s3-9;UG+Q@>BwlWSEs%=SI8&V~k zFH@*<7FzYz%j|?1#EiDYqLaE;q=86;7r8)(=f4ihJ&}Se$Lo~0;E`gN|2T#JKOBf5 z>di-N%r^Z$@RVCKTBRFc7*m3viV>KHP#i}u8D@a3U<%5kj)lFZ`LOraf!_?#e(#O? z%`m<<84XfuNs5r1c5?X$g^-D-vTxLn(=GE)$#$kRQxnPs2{z_}%jvL(-!N7wJjtg^ zlW#+E##yK$HlT9Fg_wkt!*;_euvh6@4C{32&}VkuwVZHO9A!*F@h4&h7_h2 zkbUod!j$h6V-9=L!3)IqW)=sPH}WHf+3Y*%cgkM}ZcZi{p!?NnkcyZat|QI6HYb)Jr+Adr=QaFzIH^)> zqC7cMC>68#D7%LmkMO&2gi%Boetw2%b=IN7A3iJqK9oQE(D2I#37x-v*f!r;V@WEf z?`e6fEO2#)Iwv5!Th$puz!J7d0qmWrJ9=&f>>cnuUEM5+a`<47E+5fpYp8?et!teT z(Uqef&X5Mj`9=b9uINqyGi0#=$WHBO$1`RshMhU*r9|E);?U*~6G|x7xY6`ifGt#d zs6cq!e*a%b{?gC>duVZ zZ_=iIbM9djh9PMa%axx=DRnNuT4qY|&N^cYZ zhpv$S#2aghhCTj!a@`~V-3yigE>MmCK?z^UOYlAQ5{AgGgSVIiV|0Bp*)3yq3$b_Q z-oNc?T5QPt_O;RTL#^gS;YL?{ZKS>aCo$g{N*l!~?n%@3l?lp%XkdTNekaRv`2vbU z;?6kEm2j)7m$sF!M$zk{4IUi?N~3{zvqU+eK7#dn>WcvBD=Ji)H5o)jA05I)5=wp{ zPC407+pqbR6E+HR6-(BJKB*uIr2bKdxTR?I>g9-L@E$v+7|Z$M{IX| zt6{K)#|xVu+?4SG-^`2$Tt&iD$}``);eR zkiBb)NIzZ*sSym|M0xVE%hg1!Tn8SK8|Y-8J}1fbQo{C+#L;RwNiMf5Cv}B$Gsirw zMzL@rGJX(ev*20VLl-$>-x}Eqqy0~nke?MF8|U?|3+fDOmC04-Vh~olnPiV&_JC28 zP7z+kgrj2q>)3lZ0R!PK_+~IP#_{WsgU?1JpueX6{BpZ={>3p6VJE}Ok%c3 z{NEH#k3Neez%XKf){!5x^#QS8x93X1HmyK#Sq67cj(}HMEnrDF#q!+Wbh!TQ1`qoeu1FcCG&KE zxX(goLv{mq*2)B)%xTJWomkEVav!xd@YoYn1qnd*QpWmdhDNA@$)BlM!H@J9WyKz?P|Ypw#%+ml_n4J_vSZMQ{Y2+J)Ex-kxa0ZTyz^ z(CZjo?x~Xh7S<@c1af$G$h8uz8=>YLw1Bf@qx{dLH;rINS!If7TiBp(&ULk;!g*

z*Gz~l%o3Xhiw4T!CRm~QFRVcF$v%8TtCbBf;mn`di4w3$`bu6QEl)(_mJ$qX zJ}kZ5zCiK4(NHgZERQ9O;`ShEZcw2j#`cih?o{5a{^4HG%wXN}=w@3sFteyr-k#z% zm^RbQYir>*I#!%t(-RQ!zuP(kmIHkN(sT3nm-M2A(z|S&cRRiIOx=@rJ*M+~N%1{) z=xE9l_DfpXGt;A$&!GZa!<(#Ij!3_CxDLMM`WOflnx*ET-;(_E&P0l*O%-lJNMUcW zyQLNQ?)!imqjF}WF__IR@eOT2lJS_iSL0>bkLd)u_R9yZyoA&K;O`$uWo!0U*pQx+ zvi7A#`1Pwqg_Y_(i8bpTOQW68E03$q!Y5p2^Wo$PEevv@II$cBCMLq!XWA7|dmJ{a zYdXpJ#d(#rwvDxFOir|&;h;zE_3dPo{G~*BuTH4O^>p=LTq^WgO}r%8s!^c!TFI2s zq3)SYPxoidSe^actzSEma(PbcHl0P9tB0ds(h)15=DUE_Kkh%1tGxxsBxn6hAr#3x2P%x1&umJ+-GG*h zBeFbWn|eASQ#Oh{=IILCv)*H_N2l*Zs)Vm_gACjKO4WLJOq4L zypb>qMwNhcFn&FOlqi?wz*Wj(*Sc-NeBOGbMEq>a8O77&1--ETsr>IcqrkLo3DlV| z<3FF)lDsY)e<)Lz+5P{eivp!|{ADL>mf!ouKQKd|LAeLo{1S%d^K>kJEvpb=8-kuZQE4*JP z-Q|inVa4sQNKr5QErHr=B6O~5Ok%n#8weWWeeYV64YI+XlxFI@wq%jRO@UHzKu*{X z2klw{^dQX?JE~t!nm*y)3KX(Cu;N_c*5{+;NsZqNv`re{P#&+-mLQT0d%;Z-n(WfG z(lOe?zkX6SO!XShtQx)N=e~^v*EfMg+DkI(*hCzQ@$hy;-|6{c0u;_u2t?aEZ-`;0 zVAQcN2eab5LXgl6Kt-kvL%d)+3fqRKj!LGEK@4kT6DhWi_|`g^sc%SAutm+9SLB(F zB+E&sBqndU1!N{AUe=k{s@2k5fd@8wbon%=i{%P35u4B?x|xFJ-vA(6B)bEP3r#Wn zRj+|0>a_tF8Rl4ZmZTHO-5KUXX05lBN-2?S}m=gS1^k)GcEh8(O%8` zLe!tPbJ>MA-yeJ4bkW0Gbzk|-4ohvPqsqum#@{l*3C|_r7@{sWbthS!!K!+W{o>up zTo-yEC|lbE5EUflJGRne#=Kh|-U=((f9zcFY?+%3gq9fxT`2C5o_cCEWzKU}3_xi4 z#PL~iczpu%1nVM9mc|9>)G@|xXO3%V_blBiR~3Y>@OPvFjF$1BiZmCnyZFRZKFjx<1 z30^E%e{EO^#RXjwT{>-3!F}Q>a4AW38b!SrvV98L zLH!Q0khaIr;?-Xffd~DtEM}eZlNWcSy`vfwA?~)U(XAOP-4nYZzjM+|f%gJO%yK zXxL%hrl@^|y?{{<8EkOr1_tOHamKsv8vs%PLt4n49E0Xo)%qEZC0oodaZI0aqZoQ0 zyLc`l#&*;WRXRD%<3uu&?wAul2`TslE3D{_8lc6rr^d%L&t9=kdx2)PRAftt@$*eU zHB~_7e+eV2ofMfF%>{BrGU&pfcW9Jmqj8G57LGC^oMKjXfq>ZsMAizh^K=;KZ%a+U zQebRF&IM=e9<_B=M3*l_6Yo>KOK!4_;xn~@w9O*x6YM#c4IsR2seZ^E8n2EYl6NKG zc;}8nXR)*90PMO}#|8GB@6&^Tgkw2xKN_qxfQf2Nk59qN?Ofhgl^^GR@$!y*_*rNl zzkdJk{7SK%jJ`lU5wZ0;%b8evX;aM6jNg>6w#N1c>oM4{x1SEgwFkiX+^RiY3&48yrQpaOpHM2f%=eLN6@RD%PoWjb+ANvmovem%?te z%ii7Hj~%&_y?!{mN-NALt3RM zcgz(Ly}?;rAGoqDTAtaD##4Z}q)Tw=B#N5DG44fqt13-0SJtu+qw=^p;r@Jighv!8 zSv47G8#4`l>EH@0pwPwihyQ9@YMc+T-r83f4D{GIr*Syst;;14#D_JgbVPX4$wnNY zkk#kKxXci$+U_T{rpBu}`Vy{@jilI;jl8@K3l|IqT@c==RbCA<9X$bL5kzL(ZVW3& zN0;9Pa&e5|aOh*xwBJ!(j5Ev3`iPzh=cjod$_q?%@G2moOip6NDz9Sa#$DCKsZO8+ zV+&U{D5D%7|69zH_9nG8T?iZhJLa`_=+P2I3+2w?peH-x9SV-wd&#g9hP=PzcZHD7 zik?ciq6y~*+CIXor<9D2GB2=PV)awBuZqc7$GNns9{u!;s6qNzPTHbNWPD=aK*c|F zE#Xsl{@+eFjLUP4@BaaLYoI9-W*Ess!v#jx0z(uDTM|G^^d@l#jGf9Nw|AmaUr{|!WK#9hx)c&hIN8q^2%cS>CKJFKx$co%xEPk=Xoevr7wblH z7L1U;ZHWy9hvDdbM#WE8{L)EITVR-^^u1l(EFKspO+F8k_BPP< ze_roW4sW>5RhRQYGHA1rfnrUuf3m=jt5A>A;sxtY;YpU{!`^oSH9B87wmO8#2nEf^J<161T zAHDi%piQKde7EmH;BUG7)bcX3jgybv<{9IJ@d92t<>O`K2;80lJ?_kZ)8ozzw~WUOy~B(!(=*cvBeJxN25O8E zhJzL80UDwkB+5p#Y{O(6N@e+>t2EkSx4v@@8y2#-IJcG%K`1>6gvNxUUPofO(#u() zNc%qITaP`aB4dw9u>_avnoN%%YtbLBUBJW&!hMq1$8_0edW}%#$#xT!1{9; z>a{TIUJG&oG5kL)#vKqgI0Kpm-{}|hFHSc{g!cYgu*T~JoM{)%VoUPN?Q%yX|3$%&w zuaZ+AaYu(aNAbG}>UQtb;nkzZXGn^~8Wl#^C5HZU*{2_TJekh_0Ic_47D-I_0!fj& zwCia%?2II;ro~Z=l>RqO?4twp+d*_|oOG0qOlNv*Zrh&{tEuQMd8*i1FYgGlJ_db> ziTaS_I$=IS036r>kNhkDIMXV6*fWh2x*Gvi{Mj9$1G|xMIlh7}nWwIdH@cEyA9ZE) z=qVVm;;<0J5THq+{ZRe*gS)f(bpBXot`dB4YcGgepbF*}kTd+}YFrW%MK7~>Jw_wi z_Fz)HjsI#&9I=2Fwx2Bt!Z0$lWHv*Qn_u(nG=s;_V(Edd%?0!eGvR(qSou%S$5*5} z_yH4tayq*WEzVR;T6m)6o`NSV7fLt3VQxBl^Y>x;D|&QQ>|M=;`modB0sjc95pMwf zuaHSJv8Ro@8>{EUmq%DT7)b7#DUo-?&oM^!k+ibI#yTgI=Lxf6V zUcy^NixNtp;SjkM&>0-BV+9V%6=e>#RUn-hFAsj0m|;z}R!J%zj)I(jGqW7lODf2SC{?GkHW*}X z;uZXSEJlDZ)Gttz*KgOnAr&#b`Pt!gwJ5!&s%`%^OQ-rsyM#;}YsFQ^#yq6QQ-=d? z`YzzLoWdOZT>-NFckqWf_)9-R8MzXZa!l?cH98TbEePnI&rjY*6kz{D8Uso60-zQ< zP1xz^Pya~tJu(~D4b>Ae`W0sJ>_%Y%3ugbO*U5$m81EMkgbnF+fiuu7(S&01VSy@&0w} zku})dO_|xtl*YX1{_5&=e^x5JxR(l)@C8iodO0C47}Hk~!UR|ja;0vkbvaLe&de4x zS{Epi_uBjqfWOiiER=X zX}crizD<%SeAR|(R=;sho5p;OgwoO{wA}s0 zP5=ILUBd7CDluvej6p?9;iWJU^xtEY;mmrSMFg!%oN^}7_z+k~JV2tsYs&^OLFL-Id1$1D{hn$>Q%+&gBY?+XK|erOxj+0XH8F%;a6oOCgu!5ifwfIS zba2|X4lUcanli<2T`N<1r*fU`Yrg6c9sCqxk)?41lw1SK=9* z|F~vXpq~T+z?u8(PMra+O3hDD>jOG+BAOFc&f)hks3)#?hE059wdszJSzQOXjt_x#`Q{}^UK}aBig2kz z*n)f~#_D;qb#=@86cD6nCyZ?IQl`872drnyWyh=JUylb7$~tYO#kKjRqB zqtl|OAV0m*^#lU>T-7x$y0w^PsrjK}YJ7I`djjfo3+`J2)@{6qv!xN|Ak1;Bdw(O4 zU=TU@Lm!jAH{67>pJq4+g^YV*&a>myX1)=&n&e>t%VzUxD~eSu99`|nfDJKktfsA)rt@(?3pC6wf8)$BE5_2vMffC+3hqd=wP03;?+HXG zPajb!4ey*2p+u-2)i>(VT(VaT1gMi{@5PwD4em}xG`zauQGdtxI+XWii>astl8sQe zknfACXo7%nNCtC~AYEd91ROZM1rg+4Azv(3)IQ)+!yrA0Vh~VVT9lp62qjor#6zfn ztDA2b0n-pW9JuES^UjjEJDPAh#>O58F5*u}=+d&Sobr^{wo@z$ytdkCA@szrOI}M8 z=*9K^@$#}QcuC~3ASKgE`5*Q%FC&Q(NWFs8-rJ_X+^z8o`dHfyRsQNnND zoMfOxDv`b++r&%efZP=20S zZofictYfoMrD|-nMFBURGblq@LX;W^DVX3LPvqrxd+j*T-(DQLtM1LK3txMFWPjfa z`R!!9cU(HRbg@WdhUtDCiL2G?^j={$x7)WuV0XyoxcC; zA3_V^MJqP$WO)P3ByT#izC~WIOLKAYJ^r}ORS!IQo=R*J4mkte^kp`QL`kFDCQ2EPX6g8#)QIj|zKR7wo z?2MEyt3x?kH208NV<-{+)F5L_e{?t-*ctp|+1=5q_wO+&XC@qWqmf7jxRzM`FUpQo z$?<}w3H`$dysYt{y8g4b`G*ckHyW&Gui==NmHm%e8&PV9CmbLljynI`TKrvVzmsvK z9l7VZ%r!%NDc9J0nSw-i4E1_ow~P8P`(u!t55XrR*9IGdl^3dj0636XMrN$bwGaTr z@>>U9s^qOKGkXFFVesE_>)(_Mv?>c}2OpA3;Q!`bPQ7t^1l{N6%MM;50%0*8p+a59 z)<7hI8MWY99Odwb9jtV>Fr=qWa=vwFlH|yjCg;1uX>Iz5k1=ZSI<-j?Zr_M(t^AXt zeN%R%k=Yoe#TO@Nxjr~#MDs7(j7!aS4!L+_4YVgwY>)4Gu{rj!RlZzQxNH(fe@I%R z5WJ)gk~n+KoRv68td$n%SZ5J*oP39Z&P5NSGAM>0ze4XHd4@x;FAD|&`<)VzIaJ37DpCOJ1&q^68cY@T@dvzO=_9k^#@~&Kt}Y1^*`%B?nE3*@wC@$6@DCz zcIoeo6XASF^=r-E-XIhE7k`-Ssr}07N|_J-pkcHW5R;8(f%Cz2S3zy>xwQ+#pFjPX+u_8IAAF@d%@!#q zi3;|=b-Ii-_xbJ&60@I<5JbzzAOQ&Pu7USI+_obH2H46j!Errez^V<3&* zB!sR04{Ah=zUtj&Cz);vloPgNrY;ipWsf9PcT zyzt7}2aOe{GrJQz6c}y1JEIjhXOyxRThFRQenETC9}B2QAK)iuvM-r#CO^J#<*3Wy z$x`xL^7Ugx{2A`RF(XVW09BlyY7v-%M}sT&aYIJWnu38n4hvTd0g)6s5YmSR^RTMVk*@P0cVE?$5CV*XFQbMzZof3?onjA)-k)15U9)|;b)vG5PL14)M?{KZx za!2Or1=|5P(2yILJC1E316-&GtLFR~S1dDo(%Ta;{~<>yw&MfF+>S5+sd%lzOl{-@ zScr33)&Dvb_^aIoh6R`^j9qQs;kuk%^x709e@_lL&KV?_WYleTfhNZqXmZYNNJa;M zju-Zv0f8fiCDZNPbgXeGb;iThFcjcsY@9p8#y?@sFH%C5+zr)}06&DWTbp$(F4tY*F{i5Q{c-0R|v~x;h26@Z@z&os9 ziA1b`P!%IyXMteC)jFINMnuo{oX}`P_>^VnFROxBJH=>YS8^=oEy_D?(e+;pi{cOU zkaQi!oL0@>69}mxmrj-_0!q`;h5P`wGSF@8T039Js8uBb2d24e+~0s`cz6sMU!zK1*|x_pqls_<>I1 z3QhKL|9TTF|DK4t@}4yVlc-Va6eZ8HjbFrgv?1q6xglBDwCcQ`Ss}Niz~11SFC4S8 z^NSy0Ifa*6I0JL9feo-dXPFYEv+N8E)35M+oTdC3IL{?NJvOo=v6ZE_QPg;TG#8mw zs5!QZqSrGMYZ|GQj;VUL-*I^`@3W<%BGX%%CK zgK<6*>H%11aR}&UjkU_@)o~^CXGBe$jl%-)hRyKOROo5nvNv26mTyJ_X{s=Y+@p$= z+d6X>4SAAx+hr!*CaM@&@5Y6Ub<4OBL{J#cGnV-X#EHVrGs*^=Q!=jfW(C$_3x(z{ zWDE~`-FkZ6d^dQyzh&q+OVhWJW38bfoWTWLLH@O@Yv``N#-#RE=O5SL*W{7UC>KH+ zzw#KWMRA-_qMcC&T>*FxcHlhwluO-s+Kr=jwO^3#6K}I%b46#*P%|oTSt;U#rW;py zFUu4gTOS*U<3ZH$Mcz18?DZ3}J_XN9C$>%3nNK~N&QHtOXWMQ$B zlEEUzCkm)S<{~``HRQT|bMf?P%n~tGHi8@4A0qq@+KAf;M?3T4DJ1-DP!B7Hmx@Wk z7NY!%4WxU5%HQd-3nr21Ze93fUYzc+87GZ1)&z_n8YjVSG0)6SEfq5ZwgG@`Z%}!u zE;~U|p6>r+?;WEoYu0tav~4>pZQE9*%}TSfaZ3k&uvyRn1cwj@z=(~W^4i}Hnlw5))%IDoY9BDYtp zI%n;N?Jkyagc;7OHFd++`8(daD?hO4Fv;~uO|{y&{N3b&?6uAsEH3t&G&@L}l&oBM z;)APN$zVOoDvzf^G~BGiz`u#mV&NL~EF-}VhG;Od_XpGxV?@E%8UPM?Zv2|0u7LY) zB|^LKFDW2{#xfF(hJ*nDSyd#CENqJAnd9+zek&dM2g2!GuX2q{~Q~S18e0Meg>G6}nV>x}y zBXhN9zx5)t^%VH-fTCg|)vA1=xMRx^cHt|ZjlmSo@*Tuuo`0vcfiG)~0Pb=*#ABO( zwyFm9cF2oL0Eg-f?fV+UW0n8!gv{|a^nbQWq&^_rrg<-!P7z#!NnOwDQ0N083a$cQOI~`e;Ox((LW=d5M zb4Uw(<>vch2BP-4?)&l~RiwIW__Y)v5GF(jyzfVV;nyC<5(6w1MmTCL2z0nVV)$~h zlFOPoMVp@ol)rwcv3~pKQCcjO9&Twznu-{B)9}$Qp+Y(xV)$~8Gv7C$u_p7^fi&SU zdw-Kk^TC=50}VAsS{jX-iU8;JL$v^tWD9$(i3&qG)gm#iiT=9L{yG>fA~rf)1eR=* z9eB+YTXuP&r}bJy-6-1nytVZ|k>5;=1D+_ZQ8}R4a9~)=LTp~z`KNJhwoEwm(lCq` zx*DmDc7tWGJ*qh;W;QEMG$`OvTM}{7I&0Q-m(Ur>Ap88Ent_eV4Hi-2#_-YNW#t?= z?Uy6z7$lVfc+F>c2nrM@S@K3>)RE2LA}2w~9nkiuYI?KM>t8B5j6wBbLn=|#R>|d2 z7fqDuV|sgv&h*`;ls$7S^H%ZmXAVSZ>{#-~0%lBlj_VAZR%*&L zeMKW+!WTPX2Ol`IMA`_dAE2Y#UHsCEtqz;Qf~!f@s9UIj&1(z8(1TPee)#3S_AC?2nHVo8Ji#j zYWa}PRY3th#@Lx$$yz3x+k7QHcH0FA)8{szo=d-$VI{o{8Gif#S7PG^e9J~=W?0lJ z1wKneYB$V}t66_1=0|SZ?B&+qWrmX&ne)%!U$qRS3CVQ89I6HGG*| zR%o>(r2s~%Ic$>_Pmb(?Q77ykg-mV~h!N2s&7)GbRg`dA3Z)?lV@TXn6K9|y$w*6v zg@FPG3mp;+)+ZeBm)NkJ?oUmy8XK8{PYywNkA2n_w}Nrguwl@YQ}o%dyK`q!gsEqt6~Y>)LAb^DHE}mRRgcg5L;> zE*4ZvbX@1CB7#1ganjiqL|Dp-qB%Ma8P`GASk-~lI{m>u8|iztL5n=24h2>fD%=uu z$Qf9lbHEOF&p*Uw8rUl-XHh8&1OJlNY;%L3O^?xqf(fQ$SS)ZtEK$uF6`E?*%oA13 z?dpDCZ}WssrAXAFXr}*bkT!nU<<2(=o+dF`aekXDJ5GSw(>Y3!O=@s)ScAf@C0-I! zBj@N%;X|uJ1^JJa`0u*G(U7h=WY5&K{jJ6rI>iR~9<2x4+$LHDs(V;E#j=sf85TWC zfi3cpu08hUXT9E$j`(Z{mCjCc^p<7z-yu8yKvLOBeWZQ4Ow1C_qbph%rp1>WQX)N)C{%?n9XfIf9U2dDZU;`tH#nVI#Cn{W>12Am^CuJV z9pzv9Wy}Olv@hOb{M^DBrFnm=c~%us=v8<~cHHu`ge@H}z})mQO_AN~zQmy_6n9A0 z4?9{h?UMI$-ekSiRyHcjxg+DERO6))>(S1h{Yk9ZLw0i>_p`3@(~YYsniX|QPAx1I zYOmjMfhea@IUKW=_-51)V|Re$ECQ3cR%%xhM!nw=6=zl~LFxzu^#sK*%ZYnWlPB2; z88@LSOOi;Jwyw&_kcUsNt#75X1u-{u;~+5Vf{eIrX|bK^vV`Qomc+h{b~5sIP?AhO zND<{NIrlhf;r#w^AS{>=y2d8^6JjA>r|$G}&+mYq*8<7M&OiZoxgO%N!@twqfB|=z z5dM4$;<3!X)7BtJCFyuEPCA!%Do{muSB_rm`vl5wT0kh3DKa(Vl?amcAuNV0d(Gsc#^j-wf7wog)eZXu@YfgE+vT`Cpe zV3|PfBi^U!L5LrDmPMb;VCHs`oTWnD~O8Os}3Xd9sar+qO(%n+18Q zvX#q=azY%|#y6YgMPfxpDjqef4%M_D^KE@Cg;&v?W?R{iPCQ>3V+G?d@X zs1>VmvXdDow!Z-D${soO9ofA_kJ}u^EKSqb$?`ONinNPj6=&muG}OCLUy!gD=w`<> zaW@LL$N9?5RwcK*7&{3h$Z|I;i?oSiQDjd7PED@cA5u`BICIZ>Ht9nAmO-XVYU3Dc zC8|r7?qrKB{=cMC{*z7`)1g{wmMwwZjI1D%EO9azc9y)C^2Dn*(y%gHx-AS|N}VFF zG{d2ItL=pNC{uOe==B z8;SHU7c%3uDn?;264_nQ6!XY<=-<1@o9mAR|NSx9&2h##C(G+QV-lo2(5~mz(d`a$ zwQbA~3k!5rz9$AAtKjPf<>q_0ai}1{kVA;y#qU1(>9f54(e*NSGcxl&GqOfV6fE(a zIyL5-yVd@LI-S-1YUtS2xm^(K%kKN$%=3vuxv&-A=GD-BHu@>ML-=x3JTXD&yYY&} zTySx9m$v(SRhOlNjW|LrvMX$rXRNSSHW;3muPi*x^FASuI4N9 zfMX;sAVyTONM5y8!pOqCN272@9Fi;wg9)bf*?B{ZKKL;Mmc*S+{y{60kTME$Y-rTSZHl>U zusHOozFqK-(u_Ldp;2Vm?h(saI#>L3Rd4NG`(F;2lgx&?@glp7Qu|54_o9!*rD4_$ z??GW%3CXl|JRHLND&|?kwtmQ5fPUmM5+Ny0Fd2&-F2oUy333)gfF2}^|7O~2kQ$fv zLP#NGoUckkK|4|IxUu-9mowg3tQj!Oi8}O$h{}_DlB9kL?n`Q@@5hCS#+yNU@tAJZ zkH5H#TAELIaoj;R0LoogB;hjDG~RIhEBC>l++ldN#PP}_c{K4lD^zCe-i2c0B5?@_(lKjX_G(s{ z0-9;bNSep3Jv}U*~ z?*DJl{h(7yNU_eQejpTFN!Wlg-bRI5&$dF1YsbvEOC|R$xyS7 zI)`4;$Ws1Uhe2jG5~-3woOaZenzGj=K@WZmNjC!KfZ*n8lx|Lu@Vb z0JPL-Bkh!23k$$W7_`pz0IZ^;9ysYtES9$4=7gn`lL%NdXrIhpA_|$Q6E;U?a?Iw* z6iWq|-Hn=dCwx^hL4N~k|BaFUhTrIo0;>}9{tYX+>ja)9S;VWY6^W{2w{LUP z+4d-54mpqZJF^|@U?Q|GI_oZr3{`guXz9FfcyIA_vj=S!kT%o_9kzn+)mqW=k1tLX z4;Z<7b@6^)EZy0SmCr>^jSW1AyT(2l_)I$kG1*mBrBL?GEe9#KU=ZO-J+nZmn8hKv$PO1@lT@&(5o(O^5$OPI`XvtS!XVcnC&uhQ7$rsuVq&0?l=u<<_`{2;ragR`4W|MdN_s!hy zd*3d14Y6-Wn{d-JVdvk1n5%r5u2K9H+{9dxVm2s#s=Qb$}`Jj$MiS#y;s^^pKo@5 z8=Z~4yj2c7Jw;Aw>jZ4>2{6$2mG}s_z1$11=jeJ1+6zAo9FRCQzTIW2JLSK9gF+%; z`0#zI(f;gc`^oPxhnjtOrtjk)G%^^#gE<@mrt`O5IJdogIBZz_yK9>TlDcRe@r~b*kI#><}dk zqG4=1$R&#w)}aLqFbXFOi7UxIS-3Zk){;q9qfv!*M1Qd&&c*3sG#BaG6AR%K{1eTHhJAt$GSdJMsv* zMrORXwU!zAgUD@d#iTpEG-HT299N8>bFL-@9LiyEZRP=I^1`qYyazgaV1#G(nk=M9 zkG>35F6|Z-@tZ+BRSX*(RdBYFHAF^yA>#gR;hp_plF7NMpkq&tiY6K^x&Zc9U#5W> z%P@&{h#7tnmyfAOT@IX8Psi+$LPCsD@s1-??C{#+0-@2Tm@N@1N8_)~g?wG&$6Vj4DDvy5TOF0Z zwTuIhp%rh@x0PjiNn3pp4tTV-`Oo*K>4xqBIo;Ozxc*-ykY8!pTZuM*y*RnKgR0_& z=hH#swm1g=et&26z7?;GJ;iZQ%_dp+wW{SKQQ>kRsaiZfn@OH5S(!WV?aP~3&W$sc zi-r%2fsa91KFik_TQKLgBioPM>=bg156MRq%~e7exY~A}xQHWDL93{9kl*|Hle@r2 z(1bpj|9K;c|KsNW#ozeF4Jl-&~n~`=E8GX9^XD7`{%kym<<{CFQcYC?+RZNwFR0TfN9rEx zO`~IWk1xE52bj{le7keoQJgabO;UYQZz@i34>?}~-oe5j7ds)@&>cf1o?8H@xpuuX zeoYz)fyOw2v@<73dAPxU9B0@DG#yj2d%l$>&cDjP9Z!cd%I3_{7;jtnyWx2kQR_ji z7^u5BQ7pW1I;nR{H|)2*vRYN4I_Yl;@cXU)6}ZDPpzfWbaFSx_i0yQQDY{=oFV#_% zh&m%BX&t{t8?Or2+0;vCG$vF~pEM;Kt4rOfB`A|`pci}u?=@|dCtSiR6;hu2BsZ87 zYsycoi@=UFSv}n^OFNVwrht!Ba_Z5{tJ0LJ87SD06{n;esVULXo&EV>s4Q6J6Y^9> zR|}tf$xZ3dy0cAoO$e%~Jhjy6b7Js}20hTqbKlF-Ab7u>X0d$EKIqw6=}(Y81Z|>y*7jA9*3Roicv|+M5gt9@%c&zIYP6sLOS>Qf75Wi476KM` zFWy2LCV1B*hCj26ywS*j8$x%`TvBLvkZyr*vQx$>G`t5u# zYO`pE_1I59`26>Q)uo|C%mmXc;|G~Zf3ad$~iiw%*NIqAxAE5cJxIs3Yo>45W zE>#obg`FpjBlU2-<_Jj1`}NuKpPmBH-(|Cm=@}${T|RjOe2i|3pnTSIM;ca>A}9uQ z_l7$;y~Gvz<*oW{2L7hO(0Nc=^DZc><%^xVosT9#fyW~F(IBXBC8`qE9IcmrF?e+v z!C1)BbE1qYQ=od|opV0tSeCNtt09u8&w!|$R#319e8{+C{B5-C6MD5AY@XW)-2Is_ zYnw#*?9wk)S-z`GMe1@0ByB|)M~5H%<+B5Cx^(DkDPeDt#k3c-8)N8RvTMHvyiEq?pQgdSi2=50r=Yo0P%S0cEEMtuGWkYOo z-A0uASkPkJnuxTiax2d~yzTm(eUYRqf)Hml=<7s|oH9of6`a+P~~jf>gdOGXx?(6%J5_8Sw*bw$Ux z7=DS$(lS{@nOX+w*IaoJUpgfePm}-SJEqENmUVJbw%J)AV>aTV$dSlUJ!jh2@+wE* z@8un7R**SFuC!fl~lr+z@t#Xj!@?&r)u1&-!oKCv84GOa-HX7w5 z`+iQeHHJfSCjOi#YV7gjb_~9!$#h*}ce)K8lZZQ#v{8Q-Em-6wz5{-9D!Hy|u02{Q z8geFJwpeSPQow=~sg^qvBmNzUoDCn%NJGmv;9!WB9lbidI%s>gf`+v%USPhjvp5(7 zb>?L`&C#ec*47SwE@ZtN<7;3^VR@0v3n{`Fqv*ZRWdCMlycaX1hQr#hhLLuKXAkiW z>qsf%qp;6w*L2HG3HrVjcLmy_fH?wMq@(ljN!a2J>UQgCVeyp&5`0`hgpr0LS}-#7 z?u0j@kE>sV38d`RstKjtcTo_9hm*XVU@9Q0A7$>9E@8mRi z8^}><)~Z7XR>1$J+esAbG#fbZsfMhe~Exy zV(}%9*?WN5e@EYXSCf>r$N|dW}(X6Qu>EhswtaIvgU~$9exN*s$QJCuRUW5%( zC^n0BQ{VB7BEuIl8D7mdr5xO8H0=_SIle7e?S@Y%BPj7Q;bEy=4Di%>7$<4S8vA`T z(Sq4i42mhpLZ{mS^&#@8=sl&qSn|lpY+;6I@udX(DZ^g@f>gKeCb)xsiaVdC|zRVV@i9CXxmRPHGjphO4BBM zon=tRF)p-ja^4Ab)9l0vu(GZ!fieWJLWy!->{PwL6ANgdnZn-sPNr9-9kPg?6NI#( zKrP8)rV%J!=*lt76TW_VBdsc%FE;0PveCofzqp7Vza2wU=E^LgEU8l$cMuZqPXOO% zDSXIO2B5upSLMBUI_#X@78ZMWmDxrx`a6Wj4Kg`2c>exkf9tMyZ8t@>}y1Oxd0&x;u7lpzPZ z4zPL4pZ7oZaIrBlwlHL{urV|zFYN-84fDGJ>XO(_)od=w|cH@r01mb=Txm4ot&I` zZ+_TJ&CKaC0U&BV6q27H5||peA-T9P5C}3bn1Y0#pdc8Mm*C`}3KWssD-ak6iQhJ; z1ACD$P|qAB5fTzG7-3vJ6FLY~4nL5;9~9BEUsiM}lHm0{Fcg?5P!Ht3wQMj@Krx~q z5fKO!KatrtYA_^TZy*q0WWj4-E?i||zwHxHB&aZ;0L0;yG#EgUg#T|W@|;)J`{TX! z^zw2t-|}=GNux5H6b2+5ir42|;O@o=h2t6WxI{_TJ?Q4<7elU9L2=Ir?RD~Ij6q%m%QLeP|k zDVQBxp)dGIbPJ)+vk*KYA_co`UkH5o*bl#bfL%C*=%o-%O|Px4s+4jZLWM(zWICPR(@u(ielzBa0!S2@NnC zuxqa|>ZNl!Iyy^J)4>vpx5o>>O?klsfKJ-0zoR#EbgX~9>i&#cYjnNR+cQxz;02fy z0mqetZl{OpNTyAZh^}t-2?-SgFfdpyP!5Bp$>BPHK3ARBE}hl!6VfzN`) z3RDXD0yTElP|qgzQgDiQRls;VYuWI17@3SMJ_HvepEkUvtd)~m$Yu(|%e!%pLBZUF?Pjojvx2BH}Wnf=mETf0(YNn`hBux7neY&E+^~nQ5`k3k)VO)%#{w_e*Tuq{#XE zrpFoG!-Bg02?DYi6)>1x>9<+)l#vJd+7Mx_+M5PbHuU zZDv6eJ!j#^nLIG)b%d#Il&O}_k0eqo_=7?k9Z)3l0UF2GCD}=C-(c)(6FCg%fHXi76)9yvR|+cgp3>dZ>g zaM<;MgrNM~9$4!lrv2E*H8ac9{a}LqY6I)kIV{iky|#4G^CwgnXTBJfF`erQ&u@VG zB6n@xivcFu1{U`;51^i#8_*O~;ej!egq?OHTVpfUykl!h9^Pu9oey<`@tH zzaYQuMl$3Lc|0~wR$&l7lYGSCs-`mN$K?FPlp5X1f*xkpuIQ+*Lq&Rr@!I!zY`^Nd zJG^%VSMKB@yZf!l)m+1q?xyS)Elb<#Z~)*Ks}e-Xqa!1Vl`?^;9{;4ErT7)WF_tb$ zVrOeBevZRVFFFDz=x!{nArI8UV3sF(&Mb|zPENFD@cD9-dx;aLG=}_+QUh>XRlr5Z zZGPZ%;FqT@-*&q&Ay}k$khJdKkC`5?_a^~ZU2XE)tBqFFl@lB~#(~>gZgP71o!)Ov zk^BV{Vo>i7OZs9;L5^wd_jX=%b0*Lq$Z<;%01r9NHDsa_zOL>Wfr=Yivt{xYZ$g0{ zmJ!YM{csO2?UTgl*fw#HQ&(5V+C&(ZUb%{)t4ZPEb?X_!bH~*O*1e=Qk|wY5{q%7L zR6;2cGMWB3)1}TMvI9fWKf*54$7p(gJ*$RK zKJ;Z0g3(J!{PHa17vIS%072!}%A@c-_gC$=p`;1}8Om(I?*XacC~lW}9+0(cg*we+ zhiE~!P+$~pwu{M2Le_HLm+M^GnWoO|0Vo~kcNnhK9Oa!@8hgf5Tq~HdU-|uifK8oM zAGji|ISgmK)@`5>697cr-(6?jT85K3fHfmBka7jT2AHvBKI0FBWYyhOjwe&}Qy@ic zo2*z|P7YmBvhOFc9YK#kfswk&A0;}Y;W_}q!RjpC>H9$k>Sbg&*cz!^So4`f&xD9JHF z03$-{{MolcA*dYW&5J6UF%9H#Bq-tQsB2Sh8NEUkHMK+4M%M=jVmEQOt5-UR0Wv^w z*gM}I5n$^^-mbtL!2*!p@9!J9jFOV5fZ1W0B6*;CGR4F#G*PybP3s#vF?mUYRuDui zY*DZEuCpfFH-riw5)%_IaSg-4H(~YkI*3~2{EBH0-;X-C-9xOZ>i1P=?~bPK%2wMw zIx#z331Fv*QYcuCoWSg2$jJ*uw*kP0Dj83&7K)!Ym&c3=HZ9Fj6Dh!~DWw%5QC*6Z zl+<1ILbX!}s;jMSm8Lk@eEioh!7x+YW-h26yX6|d&PFifDZjFLTQ=T?zAienxo zXj@~BZgd=~0j-ojNpwZSl|H__Z2E~U-%JeE<0yUQM3`;$Ua8%D*mXxv0O-DMi@72< zr(qLx|I$*bg{37k)l3~LSwJO%Tr0IPZ0!Kfu@i_#B~1j?0~-vm+&o4}0|EcqTBbh` z>J8V@0yYr&J%vu2)){z$I`tQ!@4KQc#%wn+z*<(uf93KsEZy4J*nD6m{UnFt7XeU| z#R%HjRU5V0yznA>y^IeVLi+=}aU~(8WiHA9jDfziveJ2orJ;e+|K`SiVRcoD6(9N# z8jSooBqYRr?Bx*rPrMy~>zLKWPTF?8T-W5rR^k@smm zMYq=1D>P8bYj6Wm-+8V&l+z$2vM7iW9lAb0JO^O7Jk%j5+%&gh+#g;iw`D5M+3)va z1pzR2nBEXywSNj(Oruy$}IziZjYljXm< zOjY=OTM(lB>a~2Nbp|ju$I9H%JL2!#zx=(Zn|>_*kZ{ukH~anifYIXr#aL>4!*y$- zj=TI6M(cVvoKzx4;{XXKksesHj(4B%WgDD<<4Ua(hCrl^y1wLonqlwwq?(5`_Lx@5 zI6_Xd-ZXl(+t)XOZCRf+!1p45Zzy){ib^Xj4Jg(qS@_zn4f*a2^=#x7WYhQ4`)n=E z1r+%mw-*4O4Oc6u1SCLy$~S06;PrG9*STD1HCioI6?#2yp@KwRe!7wc=uiJ_P058pzpwt-gzTi?S^9Tl}Wq;*1(JtqSvFy z#{szSjuyi^QB@Jj7M0WewqOmSVA=yrAE<1+wW_R)`g@Z38g$qvr;PR`Iaqhrh|c)Q zT=7xY-2gtwAAlrVF#87EbJi+ad;6XOPpJ-Md_wF~0?Px~na30rpUd?UuX+l@(0I=9 zC4RH^Td15|T^SuzR~Qd94b1{1q1RV3^iUfjqB9(?*OOv))`3+3pheLk3c|dQN^B$2Zwe6EQr%Tw$oGt(_TdTA8N=)6e5Dren>SNQI)=GiFAA zeSf*bUOF{(hU$Xr9--O;xa{b#&@3%f7N>mx7b-}uscT1|99mVnqP`cbOtX?8ZYT3R*Xm_p-Jx}0D(;=kqw8#?kQVGf|- ze5Z$TSf3|oUtriF18C!t;^ zdv`9;Y`s)(HZ|Wn1+eOcU%&h^(np%DhE+^A^%>WKkvcSUBBiaYtds$>)yUo1cL_cC zjZRP32J$*tE;*bWUiUnJkz#re4h2jJ6rz#Ohh zuhS!0T8_C>#bqp>Jbf+;ij|G6@b&F&0bt_`fIgeQzjva348x~YOomx4`3jaxuqHf%zClS4pSJaWrj6187vD6Xr!k>^qOdbHCQdir>=HWTXyeKU6Ftm)=(cQ~P$j%3US z#s94t@RBHgIf!|7kfYCw<9ctp@a5p-EV zoc&jgswisECyG%vEsEBsum-?H1_L%8={gZ8;AyT}100wR7_53gm<;S4 zFf;vqPopLzCl=IuZMTz1$5+6TV8&Qu!Wyp`)cyt% z&ojzHp^CdN)Hv_Hic2!$v6*QAj}SB9i{|W0-x=STS>~`q@IJaIQIWky30B8)Pg=?| ze6JNH{Lp*DzD@elL7ctaAevhuYEdW^T&pf~;tyH{<3=|le)bazMAgn*VLlm) z64HjoSb?=;bm&LCF=EvleHdd7xMf@ttEEV(9ydJB?|8!NMbyEWb~v@Z)(LXF&1mo`WH90l0>ND zn!|-3xehtJa7ri5D)%|aKi1wC~g%DA6PZ9$LkDRs-T=@F_w&HOd+54plbm*}c2!4QX zHH=Wa`-6G8-xJZ>TZj_FPqYR*g2BGSC!t_s7yRY%kVz*WNGru~e~oEfoW`O)Cho%e zJH=KacU^@{*9C-;@Xm-nEAj5yO!LL7A@ZvgkIPZj(V(ZW4BGp^T(K&W_~SZg36EGk zCbo@(qv)n9reX_p>J4dJV(-DM?vHOtA;yw|7OWZ}LLJB$JM3XX>JZa|v^ibiJ5RrQ zZLV3pZCIDzk@Rd3b13szacG4ZqQE%5Pa|-N)W+t5H^nBn@{?Sl4_x+Q@aNO@+MpaJ ze=m@9#wv&+DHUjjU8)ThAgR%0D@6J9{kp&G?~SvE5^WlVo&sg29MN;|YgcrxRZVWq z@hCpBP;0g8>;lyU6|7%I`QnZKS(bDqf5D3q(DKpkcCk+V`1H->16(H1)@^m;L5_30 z2G8%#vn=)xDykSS=+I5qk4ZSN1PV7dS_E8egKs@+cGgqG#2!Qdv(hbeL($?8mv&H06p^7CTD6A=zj z!qB!L&z>Fq#@ST@DrLEWxz(FkD<9sZ$+o>i$eeb>k1{ezpmoIZFrCUmW=3N^&y@SB zf|4x?u5h+|F6dKO7rjiY2apX5pZ4=5mj~G|8KM9w*>@(Tj8s7x2E^2ZYwS zb%mQzW{xw0xg-%sBjgDN6jFBIj_>!=vX0xc1sSTu0!3zB4_-wy3+2p|x)>*6o=o>w zw(`{3hOV9!H%n1LNPAhwBRj$z2-Tira8FXkC@b9UYsZb{=HAOS>D$RbhA!mZHd3|<^~-i9b*F0so~@K3@}t7lh&L8fs+anPYgbwdNs z?^Gsyb)T`Gz5OtUUqzUF{JFlei~WEj2Y!fhyJ&|F@qlU!Vw_a@wdxv<6NX`_-`PwX zUV90Gs-gVh0273&QrX%%sB^(}I$@q{LQ zg52(Nw*dyQ9>cbF%)2PsXprG@%);-_(BA2z_3Fa)# zbvE+Jml;Uo%RCdToS8L{1_Db1g&&zj7uLY!mlJPxqc8QT(5-ed6_JiDaTyg}Hq>2ekr*wvvlWqgZX%(^Oj)c0 zV`a4{_xEGhc36N6z#n3Bak%N-n-eq->h;wqW->|faLbM|I~!tphN67^;+Oa24GVN~ zhz}#!iqt=$19V-yOJuH;)`T0@fP2TJV@0$GAps)_W#HqBh0yECUd^^3)Plt&$XwC)!Yw7l)~Ff>blLUEBC zd`nZ})bKeNHlWYc^{K|mhX>_gBwvu~-@@V&h{GkVPdaUGmBK6ETN4Rfy|OxR!f?M$ ziI#i~RyO?NULZx#D{Q=NOd?HK%xEQ@;{t2&V7d`7IN}-!OR>+A9UK8ulbTh$H8|<; zg#?bY+y+L5>&NacZA$2I7O=~ul6*1{(L_7ykD3Hf&}(*(d31q>STv-~aS3@L4Gme3 zL~dFluQzV6#BM$T+T&{na=Sir>8{v5Onb{M75k<6owruMSWCEp@C#!tu)wM2DoCE> zk&gm`s)f;N?Vm@%Tk)h`L3GdYM-W?eo1EfDokFk-ReMBUuNSP`Zg~0u2u&i6+!DLn ztso%a6i&S`x?F^u zE41^r*Y8V?@za-4KtLEalRgs(qWNa*%SOa!D~X zGfEf1cGAO(8Y0mO?kL@~lB!KRr)1*rx?fUA`t*iAKbW}E5`n0l^R6+CoZFXP>kvt` zCqT=;u$r#vZ6%zwowjOi84t>QfH8J@(l)T4pV?{L{-H?d%x);d&1U*7u@rv{#|k1b zmOazCjjRU$rWTHLMaOqu$%1f>6)tiF(r(@?f6+6d_fq-7ZlO!rhKm+HQ$hc#%o;z6 zC$Y5W9#j`Uc7;7#o<}(uFQ02R)5Q60zeTvUa1~}@wbpbmM;swErL-|#BBi_`Ft`38 zg|M5F^cNqT!*anoV2{)FzzaLCYNI!3(e{Ny^17CtPZS2Q)>=x^r2qlK6MRoyB!RnN8WO*f^qv#`D@=ZmVZ&o-njx)+T1#GULuV zNv<_oXP}hu5T@CG_#n{h9JC&7qvx2Lwm4sfi{T9>W)G-{^|)i;WFM;79&DEfoN}*r z?+U121Rruonc}Dg;Q&e}6y!U;G@65L{28JHLDV+3d7E$ObTW~Xw;4^{=D?C8L$}O~ zhzpg0ATR>Bn?^?orxG@ds&8L(s60{N1dwEl6R~$Vo(UwFWRc0#d)`F92EEzEXmYa6%qw zvY^y0r4#|N)C{r|gR{8-X6l$xqfw#}{FgEMP&{g(a5(2MH0SLovwhTuG2&amU!){y znwU6Ed^ABVP3&^A#6<+-5b?P^G(&q3AH89$%<`Tv!w97wBUVxyfPuS>84InI#XRvo{%7(B5XqgwcfwK}Bf^j(Y7_RAbG%#`L@aCJ z5w{5W0epPy2sV7&>S%-*3_b#Rw=9I)Ftd|Fn`Z(QOfDGVruL)PQM)2dq^-aZa|}+q z6P1bB*%Jf$%}6q57q*E$%VE~3+2dDk*$X;xog*M0Ye+bPHI@*4nkdK47cVuQN=W5x+e3*`$AP5hHHs<0iL?5=pb(MQz<}Li z{d!U`3+&EQg9sxb~u?*;NtSVK`#q z$Ow6wEaCBapZ1C8jS4?9mMcgi@%rL(p@*gB{uyX~rG25JFJGbGHrS;#!A~j-{`D=o z%xO`#J*p}#cD=B$6IJFPQYHKo(OdDlw9}fuVtx&YVty&lIw!2$Euo}p_9E0L<1>3K zo0ZQ+a*$0aMiX~|PsZnY`;@DxdU4bKFr1VXg{ZmGM_JI{EyFH}6tsH>PfmQT(No zuh7@4;?$4 zs9JT+Cbs5OHpkf2t==5(lDT|LE?3m~;dKanT9bS5S4VYpxH_+-ZFggw{o00zVR6PR zw@OuB@jH#l5r)l$1F>EdErok4XxYn&22nch?nvM%CwB`DS<=8E)WH&CXC0B*D&L1V z-p?M}>gFEJ^N6)8kk>=FZz}0fi3Lc9BL)Y0tsDVu$vA zYusE(MUxm|i=$bx@PNbxKC+N4PAt`a-f}cIgBtt-e+1iKFs?&LDc*7#u|^7Y1)_vGVqx3X`z(G2ybzJAzr z+dAnwuq?3s=R#!lbkS>Wy3XtEK+-+Io1GeY?~R|w3=FM?^sfvnx$XY?Czx| zI-#wL>%Rh}r2nopg^wj2Gy^i#nGFItxHFgSah{Iaot$IgX<0~Fky<#jXmL83zy&S%Gw7bNA( z@xL%s{S~i$)mVjAR*smPB|rVmVWYam?(-pbvFDSX z*{Imq@_1t6IIpnrC5)Ed7iaTG<5U?J^?*gT8}q)ZQDN#YH=d9-WLDej;vTeQw-4XH z3xx+Q%r+Va?pgNy79O_W2}r|J0^6rmX4%u;4r`BcwsUdY&P42henPJ{T;~r}!GO}+ z2DJ+Xo?A~23f7qqq%)^l6*Y}#~h|^)qe5wS~c&+y+p03Sx;=a%%qd+ z?$BKDLkrJ{BU>9^=S@9c2TJ73yQ}EiF9yd`0<1&6ln%k7UK58)pQMi8cUc%-@Ye`& zqx(_B5?j7_sU`M$PEJmHiWhf`k7uWM6FmmIYCY;C1&aKh41M$rwJJILI@{MK^A4k) zuUJ($Aw)=gotzVF_-)g!7;%ksvQv117avj6 zylr-{D+*Mq4=%fRu%8mBQJ-2a?O<0j+{%`)T^!n-vP@=H=+- zWn<>&?ufs+ou)=tb_0w84X6yjOAknGzFpp(z%cl(=VnS-!Hy@@TaJkVEnnw=Kty*r zt^kv4U{T<^uP@H?4hDz2v)%TdoXE3pmc)U^3xVc=zMZnBJrCPo1BIRb z2FQ{|gChjXi&+uE0lmi_M}pZ|Fa@llWKr<9_oVEZ6=1;^i^A`=yK_7D)Av~ZTIs@~ zSa~ohVBHJ2GvIY}7CQt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. + +GENERATE_TREEVIEW = NONE + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Options related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/docs/Elba_IOSpreadsheet_Template.xlsx b/docs/Elba_IOSpreadsheet_Template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..63233f56a08fd89276bf5855f8275f7e1ceb7034 GIT binary patch literal 59262 zcmeEubzGHe)9#`>L^>DJ-O?=*QqtWGE>cRQOF&w>I~1fr5Tv`LyFrm|q|UR@z2Cj} z`+n#5o%84U4u33NKgRo>d*+&Z=9=+&l%K)DNz>e zOkhM8;&r+#?NF=dAfn0;7Z8~arBk%`J`t^5nZ#LT+xNE*1LN%KX9)69+up0kR{1`) z*2}M{w?`X;%X**Vpi|VXrH}RI_!JqbkD_R2PS?sYI$-kgEolq`yrJBW{aVK+QxF{N_^yznJZaqWTj5|v zLAJ9w6-V=v`4Q>!%!~RvDhe1SqLGuPCh9kvPhh;Xm<}`}T_ru`8q6>|q#dTC${_r;Ss zW*k2>oXE#>>5p6wH~o7p|G^Rbm!rRrRZwha#|}D|nQu*by;cnlR8EIrtGFQt!O8Dho8a8_ zxKe%=4wjP4!%_Fo7hc=iA51;9U>AN>h+R_!n;?Y}@!myl?&%lXo9cQb{D(S0pR1^s zWga}9IGy+z^lzbP0*k>F8GGUCtl|japLlGXkp>Nm?{nOSbo2Bg!~gX7AMFjGOdWFHjsRZxyu@Yr8St^!IWPHz>U$3XdcRf`x)8)=q)tZu_kkdTUD9L4xDRgYw zglxmiB-71p!On{q!U(#&khz_k!`3;4mlU@1K| zTnoB$BXtCpWZQ#0HV+?KXLPq`oYDK+2RZHB%|9A0PIC@*1O^O0qy2cCpVa5fe*UbD zUb{3s;T=&ohm13JZ!C7ZKqPj+NmX{$T+A(({7*q5?=wm>LjV!~4y{yk^X2CN=!^hp zVF3~VwEhaJG&NoOS$16S%<8*kohFGdl=>kuj2dE+v!6<)q}K(IOn7Rk<`{|#ZqCU< zz83swFF5qwU)s>)6n>#5OWrDA?II@~KuMDo)SJIpaI)z+BbwdeQRZwwjKT04R$8el zilRW!lw$9#2N*d^Uk+`*R2G;2x$i2(h;hWdl0(BW>RIDkJ#)XUGSERu#I%DuDFZ9d z0+swui&4_xQ`97q=S(BsSSH!)QrK5b@fKFTcp$G}vA$^$@+q6J9 zFOnQ*CgUvwmfnE*Lf(!?hXiI{4{gtMd}62}exF!* zVzfmX@P#Z;2-U!V4E-%VgIR`TkwwZ)XX|tONz=GRg(!tw%q5?=D&F;PS4HPE*m})W z-@ayRyMRA-wP9Cs5@Q`ozhT!IpEN1XT|wRzve9_lNxrH>IAgWyeU2T42jWy&FDBw%ms+S! z$XjUOmhx*Sc!lRLT9B~iWF0IqhGSBM?C}0a^s!@w+CBj4{6#Wot$&X`7c27@=4|($ z9MEfRM_b9BL<+Zs>X7W|D|=HqS7PaxCDRqUR%1^qbjR1+h0heZ8mm%>=ngSzq^YT& zi0ehyJBo?rYpkk>C}bgrjhBB(O1B{eXeRb-~7CE#pQFhU9*;yE%}Ig zLzb(^pbS2gnv&wH**yB*S!3d3SZX}Q;H1Mq?f{0E)|wA)OATSX>Q7Ak#YAFK>xrJo z<)<<+aRwSQvmM7%A3!>!BJhO54*QgssYXbu-c87vzozNpMp5=RReoj3okJ=9`UB^5 z-#a%#AzHa@zvwp^8VaN+0c7NAJQ9lLsVFX?+FZUK!PiAfk?OvL38)6#0b!SD8ntC* z%Y*Wv#R!!&4P}@8>zsZottH8-5lEeR6Oa#%=7l5nAo;;Hfpo=2RhAPX5T@k8_^isL z_78}fZo?2x&u!Y&LfJSI4}sy=mdBRPxf3=MB*`oq#V|9OHT>64%|F+E-d@J&S^eRB zp<~;)VBmIuXm$vE*?ZUJIoL^}++pR!9x@5D>&mr@VAe5%!R7_GO!5w0L{j`Q?o56m z;o%dOz8XT&oH4>@Z;po;Xm;1{_FK_y>M(veaJTEV} zL=6%SMSadkl|;R_kt7fXnLQ6L;|w!|Jq|m&TfC2_;g;~-m4nZ%<*7d@M2?6=wem_v z*zyyF9?PCk$&;aw`az<$Bg06ScNr{1^up`c7aooXd42g2hZOnYvy43M>3|nk7}+xG z*89$&MBh};GMx4sSFd|2g7#F$+s2>CW@4s2NkLi2;^;8nJ|>dbb*OrURl|4e@mUg6 zpBfk5f_&{Nke}P2`(co2W}ir;cJhI)mXrw9E7b=Hj%3B)ucmE$+vsoNMUn+!uUQao zXoI~sFs@iryI57|J(tHk(3}mP?i~cU2Cj{V?2b}1nl8m5MduLiI&K8)JJm^?aCN}Y zp|!t`!l9eD!6>BjT1Hd>@R}6Lc&Crj z+L}KTThW*%7n47WcS6~c;@X+`aQN|D^Q>BXY72XgpIW2Q%PM5*#KC)>ew?thYg0Z| zsk#7XiV>fbXw-g3%na=<`Ddu(hOU?d99T;5(` zsD!aaHqfJd3^9!l>3p(Mj`Do7<|TETq>1D@dgAo^l<5ry?yXGM;mw}QX=W|BuS1X9 z@;X*gX%bo{?y@XP^KfQc$_C&=nP?5xCD*e zWQKNlfs7?N@3ppiP=7cA!dko|W8Q2lXC()Bd8Km2lVP)6!w*v~mHH8I85Wgkc(x?b zkM5H2ux)s&&A1=(dz_>aR^ffeCALd8%cd}>}2T8PYKd*X|$9HH>MR#>P zmM@bkg9EZ=3r(r%ndumD0(Zo9IcMC0D{X2|wB9kRnsJtxmC1jYfpe14GCcqCav=Z? zSG*(@5?cckAeip6=d2+fP_dXB|6}mGS?5=4+vWYm`e_ryLd9Jgm)p&20$TjiE4$OG zqo+cKRQ-|P2&(i|Sjtf?4{fevcSrgfK|&hv$?Hg&UW?O3YRBT4+E z(7G!^PQEe7CKwl43Rw(WJ`UKx64x;Ns*k}b!z*)T3%Vi~w2G50tsJ)yq!`p`)-pVJ zT9b5+J2P8pzWQ3RGF%~EFkLmAK-RVEV|xvmt_;tUGnY4QBlMynNnet%^f&CEdmVsa zKf~4CKD202?8VKHC(C=)W;W%ERXC$WyX$XTrI=~V9ZPd%7WnOePt*rjej2CJQ09oG zQrwm!-707~Wq)KD)xw>{MzdeS{nTznqHO@3r4jovfsF{l!E0vQ`JYxu?sH}zrasj> z6=)q<((AUli<&RS4Ohm`1gzS^og&5;uT7~Ya3HJ?(vf?u;1Wg}2#@&~k5(i@R9t^R ztFwQv-%R0i8=3h*AY^?Q5aF*33a#Iqt<23`oZ0UG;Dn~p_v!j^^R=-B`@AN1lG28D z(^cKuw530vFE3nq0X+~|5EZ$uU-I#GcX9DKb$s>8Z z;|e9xYkFb9U~ffq|CaC5ombswFAAkkpZT|=qLiW_Y~`Y4CV?StJRGhRB6@}|LKY?x z=XMK)5gXd!_65V|6jxIw=7j`X?53f!KPjAZ!PY#yPwpaQ^ zMRxaCeOmmQT3mnhGewf!QK9*~di}Dlaq0E6sIP9|t)~$10iJc$|XbEClIlVJowi;%vB<7yGz- zVx@Is;`S%S+|=^f#liW4cS|Eix2g6{>&Xh_JabN|VredwR$NN+J=MV@ek=o&<_wLCPg(+N}(|-}>D3!ce4@|6Eh2e%*4% zq%2y-h; zh4Y$4pEo^;pTLuZB)H{r{xo20?DWvOsQm1SA_MvL;GrUgOOQL)Yk^$C1Kw^eVXez- zWEV^SFDZBr16ufdK9PS%NXPIQn<;&njpk7AeD7lzy7mc%?OF2e5qy0L~3Y# zO18C4R3(^*wx@*?tm&NC=kd9(t4xG^$|cFaIG`DSd(AP~tz;;Bz|3NDvzKNmzjZf^ z$}b#V;U#&C$Xi1<71EYu@gL?Rike%DZ;Lmh9Ad)yR~#BzypFy>&bMIns40hp-={hB z?ve**9bjceu&n(ge7%Z_e7Opv{m{6x1@*aiJeRTGC!`;u87B)fxw$@HDql&7DD@Ub z{ZQxop>09L*`K7HVVQuTt$}lipzRy6t!yuN5}T&DUhUJ%e3zo_-N!6ynV^}xK~O1{ zEE^K}!p$JAKiOq#YT$^rs%en9#XP}n)(IYtEf?!ywd=`n`-U*)*_gxRn&e<@Rk2XN zFzFTLxz-G!>0U)G`LJ`;-njSzu9srkFxrXVc0x9P1VlX+T zm)kUjy=M1{Psq~U@Tn*U)5|w*#6 z$|o9a*U0l{F5>CL8b2~eL5Uw6_|X#Fc4Bi*^ohL#NHoH6_KeQz^*OLsAF4QgCf&$t zBfGmiJc3-^V%vvwowgq`yPOFu<_C^yu|;)xT60g13mphZUb1{0Ze7L?eZSzk^#A-b};LS zV02g?MFVz2<$o<2yQ*j)5kSxIAnXi1rX`HF{7VlR+1Mz)j5k>hee@VN4Mf)XQQYbi zd9rqstM9q|7&D48QQwLta|<=}37RuDLgSF@-1mXr44Si%q?E!F1nAn1T)bcc9`O z^75t$Cl}w2O*?%o_@i#%D3bXl6(RijJo4&709mUYW|%6WxQ{+X`$KV_m_rCtByI0q zY}3wy+M;s&C1qa133iSw7NyR(`;C0XyYF~zo-8{)y$a>dW91Fs6(F9esownx`#oyB zu`41b5b8sb_QmJxfC{6+FL<s>=&7e-yaiWm=- z@dpa13Msfc=nSqUlnBD~v8b-nC2sV=2mEQDI_i7*3)(UAuG_=5Smn|l-P+Vr7J8(O z>%M)cKuo8DuIO6w1!W7*@o8iCcXy0l2K$a*Ez%_3W@9_0SNb?Ip=VZ*!d{SwOkrCe=&=gx%pT|Sh*LS!2nm1yC8kKG%6Z9$= zhvC!8NS^0i_S#6erq~7r8z2nFc*n35oHLM{6KSPp^|ffkM7cs0qXb;`tVr2~q_x78 z@#VKphS;M_s{D4Ayvhl5lD}J@SVbHzQ6|QBQfh+CvZ#Y8$0?-y;&oXy_2hy}X1#24 zHvMr?5fw3B3O8dlq1ujG03-b(4x?IIL6HW8f!Gr;dDEg&h;A68Zt=%|nj8<;{tYgp zv1EyELovt6D&F&kcEE(bjCZw2k2#~l1ah8d%jQaii+3vW6#1{SWJ@sEDW9gN5=*if zJa`w^05x|X%#w1vhuZjqx2Oulcsl5et|j7tCv#BGs{2MhSUra61T@BR-Pv$JW8@_# z34^V$;AX7J`*UH2v%IJJ3PqPzZbcfbZz%btR219V>YkwQeUiEvXH&;Ta7v-=WMNP- zQ_1Vek$s~YCal0%G}U&k8*{=l)w0MkCwUZBMB2+i7AagT`EoPU4RDNFgG%8TcZptc zIAG{3b->W=Dfu=VB^Fw5RH-*CwvsUGqK}yHe!*NSh*klWrJxAFs#{oDdtlfqpWc!Lw97R;Vq}{bTftYGQ3-ncPhbC1fmn?I z(iHNJPfDe16NnbSagSORW2)o4BB~VJ6mEuULX{mgNk*#)9ES0a32L<}P+b$Q9cci3 znls@&1yI2P1Qir+G5~;z!RpWQl-r0^4tP|qUQ`;>03Lbf1b|t&p>N^eJc5^JgMufg z6|mi=zZ48r!Jw!Rinbuse?!|yz@uU#x9zGQ={OV`e?nrrO?~g5AVw&8sa=FMO8#65 z8S<7GI6N}M8$yrj;-(Ye{0tQ~85h3N3VAi&M9JphrFH<;Xa=}G$QaNNTu%>}6N^%F z$|WT@y42RO#1H$#ytxV8c0B!KQ-_=bT0h_+u>&R~spJqbve9>6Qj$bvF5kc=%NZ3C zBa8DVfU|O_k#FN_9a%z1z}MfV;DP1*biQJbdDPcF6K<#+JY*M{+0)#{JKA5E_!E9$~%;X zHoa*@%+MYdaEju@myx4z=f}89%ZugpBKZ8wAlk?sqpj*=_KHIlxrNiPVA`H43crLDH3$Q60KPanAYZr z#hH2uWQ*hqo9|3m3e3k=q-FsiPvxk~! z2-s zjX!?I+k1H4x-G>#T;&n*cED1eY?LTh)^Z>rB_hDPm&@BzPNmx`xzt%wn7aHxw!gS^ zmV+##IPfAhwu9!X$4m10X2W`4gyNWR@FLzNB1pW5ZhAyejsV0GtM}_{`YOG8n$95k zuy8G#dTJJ{hERNY@lQhv@hkFx81GjgnSJSO*)oD^t1Qh;z-`THC(EEP^-LuqA)LMo zH}8kOIJzZNRsCc@)x#fXQpsBqWTSc`c?}s==+2SY-F9q;{f9lvpy`jdY|`6Ul=Hy zOdL_(0*Mjd%^I3(m>a$ojBzI*j=shZv?|t9&e9p(?K2Lg>+TdbaZC*6AcM5Veqf!B z^I#s=)n~E#sx_^m$}*z&0Pt%+kqtx>vptzliWw3KED48y2Nw<$pxuCFwMOzPKIX%s zHE}nF(##6uYhp?|g=x*l3IT}KBE15nI@?$nn9WqQI#dE^ibmR~1?W(0C-r{Im9RtQ z^y2SV`#hngWf1P0BgXzN0b$$&JDY|%&j9 z?DA3m+phETuMDA@ZIVu?6RSRRoIpXUbYu$Hl;Wt{og%PwHuG44PS}b{_ z3N@sSo`kD2Dy&-u5MWKc%1(qv&f%a>rTu@{`cN}PDvy*W@z`zc|5kupZ0AK3y+rn8Iv*PN>PPbOOGHyVQA;~lzTI>uuk^~;ctijAx3Mq=OMoN za~Cmq9k-(Xh+=F7k@@zS0<>JANo;UQ>G}$G9u7ETQb)6qpmKgy=Z=23UR_(y|M=d9 z^S^B~@oUow*g?Ds_{K5k88+YHP6mzeF&=1%N29Cz@xg`a$^reHk8?Uw4x zZ&3VJRg3n?u9WQf&tbUWb-enEC2?TcXASi^a{wG!8%pxWxDyf8UpWs9A4TislNvX*7S`G~?sXqCII?^B%GgoWF=)k!Ujc?5>@P$?I@P zp?@C*+o7BOw1a?S^!z8894WJl8ZNGCS0vIN;n)3yG6MX%YI`7B{^proDe+0qPJU{@ zdo}ad_g2)#pN}v)@dox?AA?l zIkT32^j=NuL6b6a{7)~fGUbnl}BnjVIP^l57Ktqob&`y zLy&u(d2Ecp_TVvs+FbEL&n?lx)kI=;C9t?pAP=x*%`l42m)?QIR)c-#J8>ChNOeFB zL8u_(Bm}YX1en0baG?t7zW(zpu#YP2U>aay?gdYAKyM_`z;%eNa*%fU59{A*d}Abt zBCNOwXViimR~54aS?5t*W^5(jk(jt}A+yi&y~HxEoT_&C`>IVWlSFS!^)2V!COeY)>c*=3wl0A)L0Xv!sSr;P=sSR@vRX9WZ1S$(PZ!)ThDqdEWaJa8bqm5W;T9mt#$gPI}ZZu!@ zf#XYLF7$ThgX~&#ifSSeyOPz1d6qF)vYPGPZ<)rU+$kyO3Vfpg!Cp zZ10Zjpr}&SBtt?AKdc(_i>$!|V^zG&Ec$RSnHU?9*Jp>2#Iq_%F;*^++1j{%YsLl| zcCa?+$qOPeD=yz@;K=lSkH9K<_{t*f9T+hDNFZuV7QFa!F+vL%>>6`W_8)ty=*t$gmKg*#-8B@bEw0hhE;NRTA9{@dpCv(heb&CV@Wikb%j9K47y>e z+TyI}pf+|i-y#+`)Q z`mb=2HGhmjF9RGdHm|_{T8SPMT`when@tVE2|*N_5p>`ifCbz1gCtU6I-p2V#fOQZ zt?^BhM}$T}8XO>oFLp^B_!}d$=-|hI!a0@5p-+kt$2VTh6ntL8R;JC1lSIq%!f4xL z2IYv5{9)4~s7>?nqjgQP`~j<)%L(uUXr2PwS;Any?D}(0bzo0M9^dQ42tYYXFfXrB z*c(Z>teqR-zuFW)8>6#WG=H(m^@jUaooMhtXEu#95_Z`Vp#`P0O}|;><2e4*63!6X z{^Sri*;x-q^yF~KXPcKLe#Xm6qt9oiMDkeT_%p0HEmgyKZs7U%UT6?I&z_*?k!if5 zwTS~nXPm^0H@UWIT{g|elEaG`kHH5=1DURnM4o{qA2&B;;G%iU(1h+ANXx>cp7P;5 zvs?7sm{w#Xw+o+LB?|rNWW#qDr+!+9{yf!(&`~*!wr_i7FuC=VPu=ukBUY6SEkFD8 z!WmT?7qI6{!9GPbXU`c_qe?9);Rx+~^b{xc=W4ak`P8lJO%C@%{TrTuogAU6${4yG&>DVl2UkGOH=$X+icY%bYhqb@=#> zZ)X>M`e0v%Gq6RVIdZJ|*Y-K0I92npQd^$Zr!_J$%9|XvIrieZJ0&G|lpeh6Iw^gq zFLiih3xb=|_7zW;Wj8o_V}X;aOOu)P6wr9kMkL*^*m< zZ!T*L36aYDP;6pOZ=`!4UGHwZ3XzjsT^)&aZ}u`y3hEd|xqYu)0@mO^bofGpi8|#? z@_>_ocVIr-4*&tB^W8P_CVa4;C=CPK7vrAMV%Fn&Q|;nuYbLJak?MYLN?3fvz~sga z6E#ehp;8ySUId4;UD zh#~sgr5*7suqEDp=lLCnpY^`JInWY&Akor?gNj-y6N+1;&sNnN_t?1|#|cvmxDcr0 zSx9*1KFjI`V?Q%P0MZK$F0~nuiIg#l4EeL+Xs96%qB8?QGNiOKO>zvhe*fB)uw7;)=p!n`dC zTTQ{}2EOX}rv*Ip0}`9#3B9B*Xq_Lco0G@uayYAar+LsymYxM1|JY_Us*~YFr)U)LmARJASGf_)5sabK@bwmabAkbjP#GVQqN8E;ET?1{uu<~BnU|uAQS5$ zZD%%9e33jbY5@e5`sRok|FMIZc?QZr$?l?8&DDoCu(O>drSo>gFI6VY$j`-@)CFHe zcm1?ZM;TZj;oO`NDr7%ScGeYeuKYgG38*rn(>Wmf{t$Hwf1{#wc6u-v({bCn#!Tl}?E(flvF{Yv)5s#Zt$@T$$w>6L#`v5G3P5*&->PmY7qlmZ!-eojAmsgq?2%79F1%uW{+Pd}Q zeX(kRq$pteM-l^9hk3~q5s4^11wq%Fxq0GbwGvk@Iz0qSu^q7z@VGrhLES5>mowAh zi}2csCi*g!K~J{=x|UBzwx7~%xE(57D=md%b2N~S?UsPN2;6>IY>+685{gB=!SSd# zYRSZ==qTN+ryIcj#)}R~9wPHZgCTY)QAs5i@h`W>hF<){FE_M=c)*Bg3}$>nK)nc+ zM9Z|h$!16MLbXXyp%W!_Vkm@wKWr zP?o|==|U?#1dJA~f&0|W!~v~0e2-|5+rMN!(!H*OH;@4;vJ5Lw1w&^_b4R!Sh8$kU ztFOrn3A<7w&;kzs@HsS>PJ(SL$+6vNVLZEcB}b8Gh=|37@vXJ;!y zw@l?pcxmR(&kvNDQxtZVepoNN{){{!{2xf_`40vzU$uO7b?u=W>+j7DQfj_6vIn$F z#Q0sc!YL$N2ErMzSvy&7mf;L18%VvH8`T-6F$ODh>YKB8T>?+yD z39L&3%SbQUrI`~yKR52kH+Io|J;JZ0XL}ay2GK26Yu9A~lGb5nW4N91CJH}x>Vx!R zawfVfmTnmzyI4yK<$as10Q{=#(vPdme9{F68}_Y6tODHi{fXp*1*5*c&;e!izG|76 z_zz{BB0fP{vtn2r7B)is)kXsvRVgfI0+9ZAqG$Uj?t$}+FbLK<@K3%@!a7wUZ_5Mq zArp2Hm!lOZ{*JxTqDmObCC(HODvE&|@))2#FG^ur2Xpns?vr%gA`IBk3T7PMM|wo-zaVEUS>y1LN-eqB@$LF}>O!s$T+(-Y7?%Eawz{7Gkoo|%_sN@kUu(N zF*~`60(0g0(K0o$CW?%7W5o@0eJ4pV2x??sHiB|3{Byx$-+Hb;i}l~NFFf1EndW7+ zIt8o~4YWom37=-XV|h7f;SDU?QNsWI$;?VQ>PURFYvbXH`r;c>dT`8KPq#WD5D3Ar zD&<1CnVM5O+t6#SA+kX0BX+M{da^N4f1~wmFZIyfap=u9VqMn5!T}ek`At1L31$_0 z>pjvf{3`&e6dey-cCx4N{XX_7X9toZWnX-wFjRZ#41NERWu60<=c5U)WuCPeSZWB2 z@);uuaM@ryWWM|0I_T;HHNq~*Jz2&ze}K)Pg3+^Yhlv&q@G2y1=sizSh?{Z6UQha| z%ZS*-6wUmpFemP)1$||4m`QZHR2a1`h7?_%UyeJa)D{T0Gdn0px4<_CgG=hcXMB1U zddUYbf*+-p&?7qPcetNWYqz<&^yh%*mc@m1Zur9%^Y-V~ja8YcFfl$ib} zR)IzyKg!e1vBJN)f{XT5W(}*`vg4t%@0bID- zqutm7rXmip<1qq#atTNw^sKphaB+69Qrv@*qI?FBp{PrOp@?5Z^ZIrxrob*TdSFas z2(%-r&LI@d_3UY%jzA)hdSjxdcKQIE0f+l%mM}u=ci*pF3HKUWsE4J9?Y)?5UR=Tj zz~iTM7XA|RS1$i3miS5}QoR9$0HeDu2|FE%K-UY9SK}K#q-82h7O$gIq(AD2 z>NoH=I_su2uJ0-C^nklobA8SJ%n!<$9bcjzqx~WJi(JQB$6zt&>Wg~Mx!$LK{pDZm zdWz!j?0O^(VAt9h6oobSw0R2zq+7qJJIBZ4Siyg7#n2V?KB95Nbh=r-5(Chls-*+rDe^cU=*b#`maFg3WhVEG}z#NGM_&fH-VUCu< z799l9d{K#Y9>%WJfVb8Tpi2TQnD$-rPx`hd>j#qs#jua0 zO4yEW`req`cbWJ{1buZAv&Oto{?TTlHa8HD=9g9Z)N(YOL+R|8M33R6&Uw*V8oNfz zb5OF*)67T|(O)iySeUO#6VQKB8oRPQP#UXwJC&lGpETMAR-U!M9}i>iE62N&34q+LQTrq?TXJ?IF$59tt}pd&qXKIpKN*b$>zA3`Pj=G(CKdi zHh@5JU$W(=1{+PNKyT~c1@5bLa9O@%#i?jw5REjciJ&?E8rS*KP>@YG`@vQOc(Yc1 z(>0h@o{=XQVAy;(?Yh=)zV6m zCC+31YO{>N;}ndeJb+_(Z>CZ+clxI!{!Au1t_%zski|MmvRvilk822 zH%1O)^H1_86DYvn^(jk!p5_#7PjTgx7!JQ-ygQX9gqQa)#tsc9g0D`d0qW%dY+ORj zwx5*pGjvg_b@4{4G5)#Y2bug5mv1EP3cZr~9dm%8HiucHFUEI?w48J(>vp>%6K&*xOYj1?fRTgRl(;t=U*t8^Zqc1qmIRX}Z+fbTd~ z_ciIbz)@&3IZYmrvph~~8?YRD@qM7TfQtZNWwMI1HNv|>Arl$Bz3U^<9%mBi%@$+) zuAEBOW+4sS!%)%{8^`L*M5mdY<}&wXLVu!?cjJo&j-v)k1VDx&ert3L*nC0}HL`R; zL3u=W72s~H15jS}7Xm1LhRa1a(~)fH#QEZOGS)+6xZ>|TGg=rRcaNWM-rAC|Z>~a> zAqNs$G=Ggbr*tX+w7+w*4_}*Ndl!}ATE_e^nHPi{b!naP?QDWffkXYd6LFahRyBa` z3{ydX+W`p49gKjsfv_qIllXgShrG;1Z3_ik^GP;;3;o4gzirGtKijL=qX*#sQvEF? zNt3{#opgx`gLk0NrM>A>QN6K&KJy}bIjaTqch0;6Go`kCxk2Jt)q~)yL3G$u8$?Qo zu?C}PBZY3}ioA1jp_^o zEc&=GZXIz<2_ju!Pq}()&bP_xtm4qLZst^J16N}=P(@Q{0aueT$C+H^DxXN?R5~C; z|IuVKZ<)`TSIg9}hARbtnvRcaZcPsXT?Qfm zu>TUtTXqLRQoCj&8PLT|&ai5ONHAF%!6m1+NlLMctUD|@mphJQc-?Fw!BTtkQV6)z zy3zzpyMA>l-tu#6lOH>Pdu3awFbA9+t&+B8<`nt<(#!xl2yQ4$Z~6B*yCyP(asDIT z%`wia-2_usOdVQ=F#1^JKF7&#H}GAiKNVjutC~uJ<`3n`3 zwTe>Ep$Y*A+U~|Rb}A~*I(4kIQHFN&iB!d{xbT3)FthH4uy$)MC6p#f|`{;v3vwVZA3he#LC+1E-9xWFKxI1_|;?LOwH52S3 zSxcCP7zD9Ze3(l%6G;T10}8$yqb>T!=tCJIC6;%Mp7oGU{=QPzGy%FuI-m{Pf3&lU zClrO>_)6)Fm!PikvI5HjvyVqoQC|`=a0RUE&g>^bQ2(04RFW0S#l?|K5TwM!hk~$1 z%9`i*-Rg$j-0Bh!rX`zq4^5SH-v=o*OdMltY7cj?oZ=bfYz9U_E@RQIIp>c3F+guJ zA(In7&|CwsM6*$@CQj?Ell$VETVV4+a6!Ts%1szf}v0czdJYRWZQ13?SdeXAgY+pl-sf``9}BqbVM*Fwwy9{17@yB8yLyrfLLNx4o*gr#7S;dK-y7`cT` z0&d4753zY7j8Hq`=p>w-?^_X$RMkLt`V)S1Dji5>{t@_2U-X`Y&*QoOF%kLQ?Ut)S z4vjBESf6}(Uj;mXzb6u78n}Py_yhD`4VZ;|*AavGAwjK8Dh{o(eVtyYS52i>n}dw6 zfZjboVDbS{CN~A^WDB&`e+^=wL~GWMA=nt7@h>wjlOmq++p z`PXOn6iGbJTx><`6I(k4ccviOeO1-a33op@BR~Wh6JBs(B*x*gP4^1r=K+JO2!tf+ zN$#wANu6SU_aEG<;s!{VuK}tRxm*Nb*xVMoh6^iHFqi4xNr0`?wc($XjKewwAo_N& zfch4zFaWLx6Mgrf6UaM%QyO3{#VTk$-^KpwA>9C*THiR}Xm(4`=?ySHco2O%)IGMi zyAW(U5;W!qk_qI5b%F;5a?n;vR*LX)9t&KkIhSayM>pi1t+Mhvzz1?K5bophw@ZO8 z4G&N*%5&TgO^ShWi283i7H}aP40M1YjSW};h+Y~atpI?G{dK%@Kk5L+E0_R={#=mM z@}I=H1emX=6(g*>fd98nWds^d5FMIbAFp2pt^a?#3y@Qo;ZTv9Vw)WV0L1_(Nn-sn z<0hdz2QXL+`#G2?>-?{Flg3xamMRs5LvL%(u+~z;8?Nu`fU2z(N4+&J!GaybeXkQX z0o&ul1nslyjh^FXSsXlh`$V{;mLjWrus=*Y+ND~%{%0U_2S!y-XBc0#g&*CdIg9}( z{(%CD*ILim;tQjviEvZWGLO>8-`UEyiK+%VB*D`^W8qSQ=QfIQNRBgt$jv4C6JyA&A)rynP<@)GG;?3UW>7e&3H|&<)Bh$MB zeXN~*H@B<0tNxpWfzpuuHrhz{<(a*)s~^B4R}aa(CPlsQF@rODJP!78uX=Omb{8n- zEay^FuL4RJ5|zZ<5n4OK{4!jzc=eIjcGy0Jl*^qN3Vc(y(@?Ar@myWhUtHEqKby+D z<*UDoN?Njb`H^2Zz+(A@_wvt`!NkkA57vG1g+YdLA|59&%|@pin@7E+hTd0u8*_()sfLSQ z=dRa>gH;4et%ofyG?sksZgQ#4{3pO?IVHU8!z%V|!{?i?j%~7e%Pl;e)z<3+-EJJ< zTG-3_5HystfFjoX z?%sX3euwrSpRmL$FA@3-{Duj5sS4G)oI$>N zV#gF1JUL)Ig-I~G3V4B2d01#~&+6~L{K7Kv#-dn!_jhjunIo7hsYjj%DSGr zdjcPx&IMn3U#49i{mQeUXo%aSPiY>@PpW`#a- z5~8x%leI1PTK)Zhem{sXVzt?S>-1cIzJuoPr&oCeoc?p@vide0bMG0_9JSdR@bqGM z7TA4m#=IrDIHgv{7 zbiExu)8{3gedV0qn@@q?_q1utg6K^}VV-#3dE}BLgR`0P%lu}>Nw)v!dp73do@U@T z)c^9mnUk@bHN?{S_ZxVAf4zTI#c$t>+rV+4OPvQTwptn57KAJJxmPmy**$Xt8QTgK zn9fWq%0LVyc`gkUrzRc=)OTTyBkWnuj_?k-dPUb^qrz!1~RL0>;LRT$sE+cQF zl3Xt3NC^DPPg{`N%=82rty`Hh9PL>ORP>5Q!RW9p3o+Y>9oU=o+@V#NEffmx)E3}? z|Ne0CfBX3Nj~M?ycl;GR8=7L^y*LDzp#SRG>U-4ZY3e#}KgRanm%j_>-ft!NqKC*g z7APqpffGBHam;K7lQNya^hQjv@a{8H@8jAH+3zQvv7-Clv-%$DZN&*U#t(LkekX8JDvG*QeQ8eAUXd?(JNl*bn7!@&qWF*6gNRp%=Ss2Mf&N+;N zfMg{~R&p3XvSa}P$&z!HoMwmv3^TX!i~rgGIeS0n+@ultv@${uQdnV+{4~$s3)wSszZH7vFB5h(J$0J-Q9OpO&+6=4>lBMaB}1 z&n)Bgj9~H@=OoqoXiAV;_v^lULU}trh)?_QE+qLJ#=iwBdu#t4**j9IsZ`1PdMjv( z$Vok5%R>@qH=1r3RuuFCFbgbOojd|hD z2W4R?YhORCVXT+#-)A3t$wBj&-au#eHEI0i#i0*hpOguQ2=!-6>;~F%YWNrN)s||~ zqXRiK^Jx5wer!1Td|V>FQi%6umgpuiY#6p$IR2I?(M@33&|57^|CAs~hHG(5tipYYY}MGYxefeZ5D5?%I@C^`rO^pgK0PNlWQQM;*8u?Nxu2I z)`8d~zoBo51$s}axV=OTIaO$R5o4!6<{`D}9*sSAAq={;!>Tp3Rr+Q}g*PZnYSn5hPPb`Qxaw%CyXC`-`$4N8j|Ookh@%z>;qq)^E2my=x@$DNvOhmS9O^ z)dg7iqn-?_kP>;R8QiiryzW4FXnsBT+DeRQh0qxe3Ay>tGsm3=*uWhQukW$-9ezg{ zV|@=d$$vIHR2Mp99UEM^m%-#fwKx2<4tn)_$!jF}&*q1Ed2b1;pIM*37A;?4bQkaL zE}uR$P|(tqS8Z?jgl|q*fThYQtT6L&Ax9AxON}>kc7-;vlF`+D@1zAK`L8Q%EH!#f zF&XzR4QOpD21@A8HAK-3v8ZdG3ELQr@Mg9Sx8fnUNEtJtFY>UCG<$3^dAlEVoS~RG zduWl+IeMV|=n;c@kE|N`k<{vB?$*sI_*WXMvs#u!>tpO`E&+E^{=cv?vIurj;w`|t^ z^(W!HWIOqLf}db73EB?HgC$L#Nq;m`6Y$STdUl)c<{9C$UlA&pi#@z&qMIRm(hXlB z5_4ZqWZ(V30;N=vGGExVEEQ67x?(nEfj4QvWL}*o zrr~QXJ(=g0yX}0~ncXKLc{7-H+}oDiW8St;$BSv7rKxPKentrza6y(9#H9q<86|C2{Y{OZ<1)W*Zc zxGs7X4j|rQDJm~g`&Men;roy=Uk89i7DhjuVFU^@ruKC0iFABN+jIW8S_kQ54?9I(GK_(C~MsT0mSbAdTEN4gJeFH~SR`6?vrlXJ(Le(tdrB)VN& zzk!t6{KM9g{rQo>0Jj%8LV25{-7w6z=0BL1`2}(-I4A z6RqX6X+OIZ<$fVDM3`6u<3v)dYM7yU?S5OJ&gHP4$r$$U&a;6c-g=F%?}-se%|_Ch zvOEk)rba%v!<|`AdMR{%=LJocu=M;=T=`|^AHqSXoBd2r`EW9s&XO>)cjJo}J?6^8 z2kp%4KA@cYQ=CcL_b+O)%>;@tE6wg-_!458UyDN0TIVmJ_OF>&NJ|P}FR3v+vnc#& zaqbG4>aKd(lESgRk?)zniU{IXKOJkkPqqW}WCVKhW?>Mz+Z}ElT?OcLYQeY(#`lrZ ztZCU?-^Lqp@^dnkmPGN_jO}95pZVuBgu;ocu>{(60+2F08=I_|1BORwJ#@SeE?IR>9igzaMaiQ%@aQTmyiidP0Ewx9Nt1qno9% z!>@;-P4-x`$v6|Eyk6B1N?djNsj{enE-Gw9CJO|D? zH|L|?83WVVpzQwj&SNWCJCU2CS~lnu4a32? zi7?@xJKHp(b=4E9&}3(-(5%ac2k!2pkb|WP^mamhv?ZxU3G7~XV_f&Dr@kurZ?PI9^2emPB7JxKWHiV zJRay=m$0)Z;AutXi#GPsfF(QbnAqZ8P$Ke8eS^K1vX08VnFV{K(JgDSis+4(-O44& zts>4XI~tqO7q@g}ruHX~orRYvU4q8u8DbVW5!~B7kA{8-?{h=hIb2kysv2xDf>tpr zwuh1Z^E`;2)fEg9>##Jtmai8n4y`?0Rqn@m8Dlp|CKUXAI}Y!PdugUb zcl4R^f9P3y4w*;ht%*}d28Ql~*fQR@xSsp#{;o4YDln#okY zww<=!VlK;!;1@^z+h7A|Ix<&}Fcik@y5Z_e+V(`%ZkK3rcdVcnKH|-IHYqz|W%8KS z@gmS-RKDy+y2$a1^fDh=yfeR>?e|`+6oV;Z=Pi%VATZ^*VV`J2Swe=`Af6W85D!2t zHq#R7)==5hIYQ<=cTz33mJqI8w=Io52FRw1BlBL?Wbckx@a{EgAS7L&31(; z&g_tOO-xxwWkZ0p%2=P2*fsA&fp_(KV*8o7t9wuGR93Hs*vOcsjfVS?XLNN7u&Bdg zuKZ|$9iQyme!;>igJ(I5jh$_tKF__h6Kv4LcZznAX8@_FdSR?-(Sa{%XurfV&mJd{8dd}TEd3wCl zwUaZKhRLq`p8@ZBHgbU22TQa7Dhpjb;5sH z$T>LtsU{8g=eDHdJZjU6^W5?L^vff;zk7s9^$(A@{oy+B*i*4yJe_)SxOn&o{mk>- z;q${ZP=4J;Eb~a^mwdo>*irZ&Te1y!nMLZ<9e$uYuJ7b*%YgEu)9wmjy`0KZEHLgt z{@BE(i#xo7_m>iuNSkHQ5{s&!yJZeb>i0hUsz((s#&(fa=pUPVopJ05%|?$v5ACn& z$@-&uxc{i0D3?F#aR9OF*}-wlK9*whUvzlPe>)tkp#OIGf4A_{u=4+ENGWyql5lo( z_jDP&Ivv(6T>{}$ev&An5otW^KK;zZ+rPn95UQo-B(fB_Vl3t*=!8FVcg6Q_EY~C_ zD`uwQEbSVamFsnCHdj1;dN=i7Y=;lY{BW$^68at`@°AKUkA&21n5fPQssbxf94 z^|#=tTKap8iFWevl?P+8jI!cJaqz*>ZQoUkI{YULU!lNhq}B?*_j~NsQ2QhHGClt* z_Np3Jugk3LB>k7-V~>6cUZ^TNpeelMSpQ@=FQI?_&}AXGyZNW{3vWb=+T<|8FRR8$ zgR(wYweAI8>O=SB;I@lBy*G1XHD|Nq=8+nO{+NhU2iJF+@Ukry}k{A{KFO%S`cY*pArt;?jlIAXjeVeWC2tJ-lH+)-!hRSc}09`l)eqE5wdi zq+)+g$Dw*}g2?7QyJV-b!H2P1Go#XKqJG6I+7?~@_Uzsq;P3yYJ>KRs+%kTpxHYV8 zZ1ttCCOka4?0r*LPA_ib%rJZh$dB-tCvF!&d|?=|_0sRyav)?8qd%w|lC0rwoMx99 z3$Zn{m<F8(*rK@wGx0ueGYHupjE9LHqvEi2-F?qdTBT?XAG!lfE z@PnfboA~n&JTakyD4|dH~nr|yA zimJ#!45qIlZM0a~_2og+g>wC~jHvi|*ov(Z_RVjo7WhA`yIJL;b= zv5f>?S^svy+2E{5iBFPNLpSoJsrqMLwh@O0JDM@I@GG0StwAn>hG%P5dvA6-+@g%Q z!alb{dH=3$9y|sK|A2(YBjJficrp_H5eZL4!qbuPOe8!T3C~5skw|y}68;$pFGj*k zk??XP{0kCZg@o52;dMy(S0ua<3IB$Kw;01`fggpVNM zV@UV}5r-6+k503Hkj>te7-OO&&zqGI z*WcG^X0}+$=b#-g^pCM+c(c;t`g=Q9;ERrY4#M$5j9rOgCQAPpyT5bAY;l**!989` ztSd3uL`j)9D=V)5pJJ2oIS|JS5q2fMHtBxIYx*&c_ebYd_~JjtX6{OSZ_+KxYnmR% z+t+#3Y%zq-K{{UOA7ek}HBF7RHz)Rh=$(*2LI`#a;z7CZSIOyY%j zyAtC}x)pd$Gvj#wDK^qQdds=nhNNlqC3b#6PQXPZg(Nn154_&y6s{D`xjKuQU-#B@ zX*qf3)hCuf77#hT+R+VOY*|~e<-%o*S60VEw3M#6WwFj*4{d*5qpCHPZ&h^){ z`(H^tX8gpq8=2hn!)rdv=#4OQt_RZYe#{VF-Egjc}6r3gg86 zVepUjV8gogg(^o%9yt$(CNn+wiHs@sgoMieV-?u91kJwc{(d9f1 zeXau`E<-Rp3x9rBHa9=qW6F*cE@b0X+V4$t_X+EBmcgL_fvqoR`QGY421+3WtdSQo ze3_R|i|C%;C%ytcxDkBVGpsSMg8pIhCTq;wAeK~v zz--NbnEYfQm#s<78uKQI<)0;aSYtwhSkesIvNiuna+~Bj;}PxkJRs#0_Ueb7@djId zI=rh}pVf(ses1zggDDs4>WnPCU<7ekx*xOItgNBMqCXu@@I~l zm0fgxk2T|A+zXflr`4W&l~sol7J6kNg`Ug8KAOTv^7pGh| zj^Kv#7Q;R9@vutnvCLOhVY(2j!QIU2?lH}dJLHA+iUq2;(vwxO?D#3S;d}S+nD$H; zi;WQQuHGTqnQv8jtG>{NBhz`*owVFawqF?JiYw%G9ycpr&?&;>@)L;2w zBFyy8?ezrg8R+7_)Z7ckcO2y+L=sQ1nD9H3 zS%vtrx@!|*+w*xi9*h%@PU2kp@$TNXT5#EJZ`TC*>CL?LT|Btn>EEmb%Z?6Mj35Sp z#|!{)`S-h$aD97YBUMNH)75aNHzz~1z;}f`x#%4ph5tO4qc-@;Dq{Ef`71?c1}v|_ zhZ9SMg^RC^_^5r>g~4~WdXNGi;HKrP^68xw4&$Shae2!1&N}6^#?gzTPCdd5yC1&C z9I|!|4cAKT9-ag+<*nY*VHp>_G+b-?Y)?E?Nx2|5*W_!0+HkF+E-mEv#JrNKI$gMf z^gY2gJEw~rIX-61TP^CQmKwv2)yZ-jN@Cg*-3Sx0^3DWg-KLkIi#xKd4-#s7rCGdw zJ+vU#(NQhDFF~|W>t4*E^_}8q&7vm*4>UD(_ttvVV96?XY$7&dx+0RUzebLV1*!yC z6C%1j!*6lc=W7*fN2fl@b=`R`rcpLhB<>KYjojJRiskOGczw0sDaKOk^D+sO;9i=X zJc0FK)}5^p@lk%CT0`RqYbX6W5BCU@vb*6EtFCcI7B?zchF97crj6a6Ns8uG$ol`} zOh`4UFrK;`5}dC&)EOXul93YXdbyhNU`HyQ8Rq0u(}*C!zc&iLJkyZ)`%co7KV7MP9K&`*LU_U%Z_Qw!Z&*K;fPQMa~zkr}e4DFMEMKeGoIud_bod;!Bu-rQac zUp^X?Z^)2nd(&#AV%k??{(-@`S-09xE2S^rm!F2f?JT|n;q+KPnKo*Z<>y6;g|?eO_+={S`iQEmM+T6`1+HrvWs(n|*~ z(_XZneM<7>dv2-Hfmx`!+SKLd{j1p4;H9MSmcZ7Z)yvSgwGVYxYjT1!H;=Dkje8wl zTONG7WQmb~Oc|->V{oNA%kmkEh2t1of9=Z}4yp12fzGCeVWkkl6CPrZ=V6#MS{c=_ zC*7ozy;2y_x1mjD0kZ^7!g1_#$8E!Op#?5GB;nG6ZsH%N{C{G=M`qMNRAPPnD0{hF z?yAB|t_Q}Jq+^2m;fY}c&!fM7%YEwOB1&m6V)$Kd_tmomg#fCw{BK5#McKmkM1hYy zfHt$Gb2$IViA2goezhi+bK#axLWg9?pge(IdYv!kniNQ8&8H;3m^of#>Jm98Fip`o zZ$vU1SmulR*)QR0y>WeF^wvOTk$ibHMY4SqS0PsvH?=Q?@&gRvW5p7Z5c=1YblkFX z-*+16v~%@>!Y-yf&K?hgv>sfF*f@Lr!%^BWOuh1G=+NX^O<`ZOYe%1g*9^-T*+`=i zrDTeDZE3`YWd;KzP`AjhyW`<4->Fv0l;E`(o>6fY5Eknwl>7A6pgXgh2 zL1GN+&whO2eQk_*gb_V+j>dsnIOfZzPv6R#(Gx)K1ycjHyA7mql;ixB&nwm{H;dz2 zZ0T8ryCtMr&u1?S9$#k6N=}`x+40d7FOquI$NJ7ViFI-+jdIOz^8;=7(rcx}SD5Or zlEtv)yW15FH^Uy`_noP66q1Br<UIOKU`kTROpXLx#_*r>1I4ERgcvzePK82 zytr)_voL<;`ypH1fz?Mfn7^lmtvb!hka2S{`QgxvD4~i5(#5yJj(01javR%NO3o4t? zt(Mvg;*d%p-fUq`4TU#?JRqwv%wJWy6zPn9XX2x6TX^-*lB@4Zg5K5pX^2hcr}66R z<|(1N%#M9EEr{0U#zmsP#h;QINZUROCqt-#;V-n^y8(wHo-&3vu!oC+(*ynZ*?_@ zQ+#Ok6_(B7CSWrhsPv5U*4*ZDwcxcdL>QPq;sCk{iXf6b4=WuAM~vC+yfWRq-cD{n-U zoJS38B~E_-gzb}jXa}EC?USvCB2Bg9tCu#efY7H+j2fVLy%HP(HUI0gb zr=J_Zx1yh_ZzTZW^h*nJjBE^_+S}MVfG_WKvNEvNH?!n0w>37!kKkv3i%+EGqyYi~ z0zekr0Q@ZADCKHq0sxAN04tdH96&@s51a)luqZ&BfZ=I(OyO7(REEN?dv3?pq^L3cbwA$r22*qwh~XDDx6}T%KpOsm)-u*FWrHD_J5!L zFT(%hKcq&+4u+ud=fDITBL_n(kah)tvzCUo_KpBR{1fC0x;WZ`Gzqw%5V&j)DhSeC zr?lyB^y5?7;5S9_VaDyLzI7*g8J_T?fKtYfGim zvOs%@D2yF`*$841E<3`XpPm6=ULt-+`{%#sCDJxAla~8k-qY6dS6c*iBTBb-QaRNP z#3%ZpZ!aYS(jX4ewz0L^soy~QES-`5<5S;qfV4QEPM{AM12%vGxHkl>ffL|5paRGM zkHDiXU=OC40A_$C$T0>}jX{nX0Xbj+^8UTt(_b>b<@rm(^jGfX)7)Sw|6b;|5>|ef zu_2-*;v(V&zam5mL}EmOMBt;3h@eCdiNuK>gIpmZkv}zf`ZqnV1E#^p*0@n$@5;hRl6Sfc*5?23-`S0ugH?w-1p@^$#bXKx1q+43pHkN;XeqcUWGU`|DGYzso8@2W|6+?7 zpauHs53m0FvQEzcGe8a0#0+o&W$i()o_g3Ca05~QexCfUDG?J9H<8@`&}s!w+wvb; z5K9q1CYAuM6SEQv5pxqiIi>$N^N8<&X+q#$>QC)|J9GY&_!kR||0V@`;U#;%6 zt)Av~2KBZC^)_}ib_M$m0Fbn?b+b1!g*#s7;o=gwE&+CB#@FSn4LR;#*SEC1{wvAh zy1lW3vAwgg5eIPE51!@&e_EpQtA8V)>G_N2s0aXJn_$fP@fT0q2>_4|;4p&kFWy}+ zCSFMafG_-pPWH~f;ej1*7XUbz@bdinpMdNU7@MZ>_#H4_kwgH%$$LEhI28~6z8u7# z0D!NS_^$xfIRHig5E4)UXQ&7WsR;1j00`I>oCQZCrvs8dkk1ejoh2qYcm4t?C{T70 zI72{4c!r4Z?Ag-+0)ZF78E`Z~b(Z=Dw*>K}XZj>J?Jo1Ye*ftl^P{4MD=NLHTf7GL zKIbpc(9&I{XSsdn?mbq%2mAtpLc)@drKDwK<({ZMS5wyj%`-GIHZg^pnL9W-IlH*J zx%d(86qM=B9c?P2+p{G zUqULPvp2YjsU@C~=-XYo$@BW$wl!}lFfC9LWjC3G?7=#sf^)ml!XSS9SDe!dAG~Im@_9{nj;- z$ngi&{2BA4ldRos#&GF0Hy1O8uOUS;dgT&Lqj-SU1fv9*wT$GOyT8Nb6hm^i%~ms{ zgSSOgjQ&fF%;0BDZ8h#IwPCcBI#g;ZS*j7C_XeWV&hwZGs)l5#JbQDq@Sa=-UBN~z zHD8Se9yt3L5BNy+%p#~HXX?i(_pkUi_btb#>s_rJuF;uk?qzpcxu2`q9Hs-45}OYfE}nG{)6s+oZ@E#}r3`vf&6 z_*i4Tw^aJ>BHQgm>v$H`>&MU!nyDLq;aAAu((IV(4-LV$*1JK*1SyZmn-DXrreU~V zJb-!z!`wayaoq9`L_zlVP6BE!WiP`n^D!b?IT2{uhNEkGH&EnB{)IGIvv@$bzo}}a zTE0u#i$@EYRdOtf8gE;qF_N9Y1A(?j4;@je&36iwi03$QF7?%jN9txV<$bNQ3>sCM zK`!dOS$Sp2$2R3zz0;`O6bv)x2_qg@2P@GJ_8N+5hM+khvXnu_bjUGT#LL~dm$*qe>Lo^ir`J}VOl1-y4P^Pm}bE@tOgitpIYZ9m7v zF9Uo>`gx+w_0GP4Tgjzh4SW5n;S8{b1*o>haZ+orls3|1WsYi?UgM;7ZLLUtmF}(? zcIZG!R~ajI2Y0Rm56B>nui$}MjTvPew+vQ3ppOt2k`)BS_}W4602gP+7GysLh6g0R zSRjUv^zi_t99U00c%XM0*NniZVJ_i;5U^^gXLn!Wfi$+caNP9?89dN=<0K7ae4G%# zQDj2?Ykv5v&i=cc|8M)v)ZYw-QlZ4KbV3+K)#gHN_D4^G_hA0CW8%RiKBXPd;HfKp z`JVS!3L^Kd5Xysf5Q&fEoZpVZiV8~B_`Nx5hZd_o7e%n&WDp_hr`mJCu{5m^-~nmX zW(aH#^0uCH{TRo#vj{D_`L;j1=O53-xCZ=%7F1hUcGg>CNAY zYx?hk{(tJa9nMe$N_7i!OATyRJ;5~MWG997hSL}YPH_g;x$(v{X>_blewpu_5SBNm zHI|l|pCDoE6}RKngKT=N993|_;&g}xYH$#djVR`i zoKqy3qg>xOX15TwX=PNFMun*30U89{=FOPReoFLgAq3-zF>IpGU4P zr=OI}DBl!M7L!Mu%hx5Zj0av|##b74HRs9HWkSM(5-r}%@!T8E^GQ~26jg{qJC%?{ zGAdsR^m~z~iCpu{oBRtQ z=2;AU{fqm7r9(A2W)7F;3b7XvxC<=D4_%A#KqHh44;U+tYRuM$cr&dY;nL=9C_TAO z((7oZEx634SYs644; z!&qbV=P4QNp5*&=+-*8G_4yLSMhYV#dv2#0@<3aQH4nN0v65EH8P0#}s7D_kDsyij zYKYT+N8vH^1x+&ItM@9~`tudL)fJ^h+Y?#n3d{r;#+0M0w>e;3%9sZSxC=)ImvlHA zU;!o;t}`*uA&hmG7N}?1Z{A_LeanVR{#AR{!uN@DZ2JiGv!2u@D@1|Y!eE&vL$jF$ zw($6NUxnVdlPSqjN+KS(4R-t&ZhDx0($T!cUK8fQfE5oOlHa@uqsws&8fmi6ouuGR<3YH;Ub& zZi%dmOE-(zK9?3T$JQmcRc0l*g^}NXbwZCp+-NX%s}H&+^UckliPtr8_)^0QEosf5 z=-W%2rb?NFSKfx+nw-BT%}FIV*^;=TKX{EF($RvdGku%iBT4Gl)cx3cKPOb03uFl zhM?wam{U}qJNQPWMs6 zNb{3SUc#V{B^Rz{Io*%s^`}o}%G7$5n{&6oG%#z+zA9`(m6&>n4~invFz?Kd*b9>8M8udz zT4~bEW_7%n6-$as%KG*aGznQ=SM-l7_^uT0I)CRrwC1S@_r7U@xnE87#D=ZYRUnAl zvB>p_mY70;;0s0fIAc$fo2vPDO&)No<*Mb2s&QI~3`e1<)QUyhtMWYyf!v``ouQ*H zaVM3G>9XpNwR?BGPVVoC3-y6PX&ixJ<)}pPN2g+#XZ-VX8XjcS962W(KfzMf)%nli z0YxkG_VZR&HKzB`T`uX&t1-RBBq_@3HKB@Cacq0xnC$6ZQ(Um<8XmZa10A>|H;)H$ z4tuu2VJj;2wvAu?%)}PvURLOC60a^Q{Eat>Yp~2v#68DQ8TpfRZ_){!Roe+EFFUIT z!H7ofe224>1qlc@W6>wQdLv_sUhtjKoGsr9ML>o2f2@b5G z1K6cQEDnK)Kt{WdI+`p#idVWAA3w!jtgh(qZ+1_r z3!aUQu|Qmvjo_%w*BytCJ*(h3DbbAM`w|C^hU9?==|*QPoU*egO)g8g41XXE9pjf=tM%kMC( z+VbBytx88Xp2>s+TD)~4?GU-D|Dug?VX(IPZoEV|+fey1q_n5u?&22|E-*)Pd91GF z0;16{j_*W7eE`Wfo)^u+Tvrt|%r0c~9GqQ(-a~X5CyO!k`??lwRQ2DR+|?GyFE0(> zg9_mkpt#FY-r-v-gCa5P(3uGs=3W<8k1n~R5q72^6A3S=wb?V(0=HPmR)X2v%!+$$V*a_s-J zFe%(UaLy)F2zFcz^aqWerW}29I#Kr@Zy4)sKz~p_0L!ovW zrdGT+U6Sa>g!m_dh~f3(R>#}?-Nk+38%#%RZDmZnJq7g%K3}Th4~2}+3oJMv?fzMs z47O}feb?nhov#3vK@pt9tChdk|AKKrS)bP%R<4uHJV~n~m0{Le?U%92n9PNSTnQ~t zv%7CQ(n%1usYNZwq+xsohJIF`+H*qVHjKN01qWr_U^GXFA!JgEmBFtF7ZN#%IOuXgvh@J@{PoFwrH zOg;acb`qw!Y4`JsIdm=!A(e7;f2R;DiOItQNjLr~Bng3iv;z9c2W(P{Rg*eB6zjehBG-(!=h7|WUwy6gzUVj04n4b2(IEUUMzHy|W zG&zrM!YHArBPCS20oa7E2lr&eHWf1 zCtRjav_$g-Dr9x%ny_N}cmc9zGSb~9)uz}3g73vO)!iA#L@1By&8;<$dD3S!ZP3mx z`D11B&8E%|ipuEEt@Th~oO=|8tPS2hjM*P9H)wCmKr@B&m8`_qMKh&kPL55DOw^XV za^Ej=Kxe6-mi#z9uR5Tjr}np`YkCXz0+vUQKnr`RM zC~vscTs~Tiye3d_;1ZZ#o1ZxJ&RqWCm3kvi!qqw^G)V|zHeq~bq1~*G0!0=&$F8G| zX`6$PTi|HWp2AV_HbJ5cNDCWRr}=qZnTFV^p5U72g?605q7o*ej}BsCW4Bjl2sd;z zp%y(GT`;Sq^|d9hV3{4;6snyH@0oED4o?w&qq{ick2 z{E@Kj`U+FB4EYWzTShq}bDzjn!_%|A=-ws|f3FTlU z_e}%7RUtyyZNx8{^;qR}r8m#yLljRwi830S%}pA9+fR6K{H^MTqsRuKT1D-bs1rI`fGa@ zP)64(T_#3D@I@N0v)AJ9SHXfgOFKM5Ssv7aZ|?--sX+GFim=3&zNw?RRt;dKM!*F{ zI8z@ug9)7_m)ZCDf)?=eWKQpx{ot4Y9V7WRM=A!J-ClNA3Y}#*=NPzAfYqO~A#@v7 zkAJK|%XGto)XPw_|3-i5xR<>)FwX~lizr?Qc!QOi5#bDm0epq$)+A*yoNmNvbC9qD zcUs>)FV&XT=GYW6QK30TN%{IdPl0)MSj$kX9uN9AV?HBwxYFGU^t6W*}-yy9lijQe%i*K~P~e(mfs6Pts6^>Zp9b$*BTpG4nA=0Ot%Q z@>9OA?s70w?d%Aog+9NjEmdmH6%Z~Y_9Qz=egNJC06js870SkPR-#PmC;=7XeQ*12ElW!eg;v)GdmF-CfY6!jH>4DlzK`CvNPC{n&DrOXI znqundYqZkGmk~5|bgMCS)M(`ZzUh0-&2>enEt$%i0nUA0#jLkOONv1)s|PA!yM&>r z`X;DPGI&kc4{AK?K}ld9?_KKw4vBprlr{3{YX~~z?(#0|JSL#2{=(c~OJ1he+m2a9 z4IMPhX9Ih7ZjzP3AN?SvJ_8f18TtH2!2^q7V0Vig*F#Sd`T!E(eRDwcDr!r;AFGoq zf6VMD-s>rg2QE)bqGmCdW^Arv;3*rrOj^Wg79Ocs)&a|P(U)VJrQl3xjiw(D6qj{) zsmnj4w6($9wi zMtP=2IKEk*sH&8(u}VB3^CSXihRjTn=yj^@&?&rV)@wdMu%{e(tdHnfTHn9}o}S=c zou5wt(Ufsg90F=;b38u>Ue3Jvl;9_B1h#W{EP|MZP(cr=Us2xK2S>swJ)`3|3?>i{ ze2)VD^XS5)yaC=xfTomGoS@N{@WA`Kz&65?^ALNIRKFGeHU%5_kmP?y86nEIT)1Hb z>b2|mhCoV5D|oYOmKqI7DH6YFvyCX)5}iz0PVq2tKK?<1@543L-M5IXBRz>M^pu-l zI|i>;iC17O(hAaMp%fVTW+>|2T9s8xsQIO))@QwS*WqEz^#LcOYSr=c@_kcn1>;ZQ zmU^JX{h*seb8UpLng!d#*=hLxmXep zoL5iNC-D=fUpW|q`RpbrLe z;Hb$h$yF67_ZcraFw*?YBOfc6;M^Z!eZDy%&t(~McFYB^K1uin-KFWPN69$gfsQdi zylW0}L}~`ZFjwM%g$=;7Z4NOCof&S?#PZG|0+Rt0G{mXnuA`NDtLl)Wn2JS*$eJ># zuB+bI;+SlW+=X#v8sA*K6`WP+Gv52}yAgd>`2{zDr9I^l&VBD8PxU&E0Z-cWF4y~; zFTL0~L}50w$HC)C>WW4d74C`^Auog0^h#=zmsi|Fwr=#PY%Z@9=_vBHf4$^Nxlei$ zUq=UCrl2gFCcxgtAZ903XBE4%+)#^))3WHZeHif_?ZDX~>s=8KFe2*ej7*w;M~6O{ zqkB`4V%YztyCX~M4e+%Bj2F({T`^-}S>DMPUZ)N0)?QMew@ki)33EK*JU+9go}xUk ztC$RxpXAgI>sODI2v;kw(@B7kj_Y7dp9nh#u%Co36UEe{ln|rB-O!s5pL&Y;5zIJ_ z=5cwfwnktXDO(ETVQ;&rnu~F^Ys=!$me#{?B8^yXMLzym_fVwbHR0&xM8e)uJTOW* z)1B~XS)8E)rQx5|>&bg3Fr)YW9v|AdbjY-YGYuL@EuRl-sThv^ylU7qc8lExAvQoW z~w--KgY2OY_5oeZWF-_@cWuZ`vs&>82 zz^Yk8LLH}1%xenM*3%r zPqG4b*XjXRB`dbZDN#ERh1Nzrp!}H9mv3ub3LU@VBEWR5Utvr-C2w*} z8CekQpQk{sc3t*CsDA!(ymO`TzLnmj4IQDw!;?612*zNz!C9CcIaH3I^n|(0 zPoLB7n1j4MK$(fN*W1vFe?peJ2Ye&_l--kE5r)-vy1S=d7w}AYu&pj=Hno(0hG}iz z<{}>Wq4NZs<}&txx3b~DvA|ozGJ6JMCTs~0#FheH|H&ByF+o$FoGmTHQh|4MxA$LB zmbeDse8x0z=Qa_C9uG-IYrxZ6!io*NKIa0()_x>hp91GeAIqb`hANVR)B8d2f4>fb z({Iaau-pEK!vyQ556g(L+KCP(*v}kn6G@-;1*PElm5v?g73$*V2usu zI4QilFS=%Z6~B(=ub5kdo^_SpY;8=j_Eq!2U5%7hgvs{r%3IJa)%;)WeRo(?%d+o` z4NY2QRL4pLy3{k=`yms&J9{2X_ zbI$$eecyZc?ipAE3;Ng9wW_PDdey3GNLNWlO)FNs{}4P{HZ>rvxJN7SP$KA&M`6g8 zo*(;bSd^5paDV%9RKi+X^1DLD%I=2+rVT~HHH}$TS)&sjx9r@*M@qlpr9lqLHY3eX ziS9KY3j*IcN*j6}=Lnd!1#WU%2IaT1e;`2*MiTo^}2YM zGN+XnA4h%f${}d}PaqwLm85&KjGt-GTy$e4G_yPjRGHqO!l@ws85X{Tt!P=*(5ipx z8CJ;~xGG%?_W1@FQ3A49M>osPv1-hb)U6kg4o(QF3%K_=N5C(CA{Kbu4q=?6Y(8KZ z4Mf-zfjfygXlE?rs3%ipDEx&B$Rar;&<1R94n5KXa+U!@S_KjPCz}69cP|D)3w%u* z0wB9>ktO#)P9<=D_ zt;>ja=a3y3B7VI2L`N1=iuVE{D>;Z{tJy*64q?*gAO??6)r66r+D3QlsZb=Q_mkLb zG?sFPzh8Oqo+n2}=JvE9C+5nZn?Ymo0*46q!D7z~R0^9W&K>1R>vRq1Jf`i3|U0`>2w5-E_>p8I{m8zb>#)!`vS>IH=+o(dvbtm zj-ooH?7z};=$xl-Atl`$OTDG}8mQ;DBo;fqA8D`oI>(XKh7*jHIlSR3u-ouiqBfWJ zVT<4{(b#0E(_(SB9VA_)xvLqs>@BJ`jO71%ytP^CzRGjRtE5&NSUol6K=n|8?L)+D zmC2wRE>FlJ51&c(vnC5ew2|g_q36)UG9(7jn(?a;)GXrx)>t!wk`bkrgD zmM~L@mA8vA&cYS}tkNTSI)81^b*jCl`Loq>;BbiUk=T-3$6Yj+Gw;A5MxfI^8U~*5 z1rcolH7Dy2lsD88_#z)5uzy1#+TU&e4X@B*j>AiE0vL~1_%}<;V1g|ucCG7bcb_`c zD>l+*MCQr!xh|nS`-XKnhv;Gq^#LW7$!~NX|F#+ynWnnhj9(@M3mKYqydxTEcrQiE z^|! zq=|jkJQhi{Ktvp^qcK#yCE6jwfe@Ods6wDJ#?mwk5&NdQu%MlsVGlJG-kkc+xy^{> zRtKG%g+}4-NAHLnU051ap$D-OKvoHrfXUqjJ6?t`S^}{XXGGyK0plzY8tPzQ66mra z>v$`aQi979)%RotqsH_lgFRw?f6nvTH8qH{f9MaPS_(Yod2#`X(S{z;d!e4h0oku4 zLW#>>ZlbLkn{J(=Hgy)($zMA&IJ-`i6wphFbqbHiLjSh1{xA(Pbw*eZY}+nyZ`TOx z0zwBI0g0V+ELLC<+AtzrgNVvEnh)q=!A+g#fxA5rnbuNZFuKB!lyVo4PEN?*t^Ye* zTMS^C+)x9{Stsw6D!RC`CrDMBD2H;cILv5YQ#2gt?RDG`x>7IvxCjUcs%kkr7cqR> zZ2N`Zq{*BF?BTl{WM1F6gXnxBjB)JSIzJd*^ZE5e<9Lv8N=&P6q?$R}+^pH$lqSME zehQ5*mmNN>3Z3yoj{vuy8L?&XyvsC4_>s){j$?N`U&$~Ud3$}Lu}fcw+>#&E&AtV< zjG1mpqxjlwT`WESyx-mqK46=+GNHW5iMF=0*{_BQk=6psrw|Mnn9%doqQIffA|PK^ zz!Kk+25GH=doUg=3s(T^5i_4?!d>2cGmX!La`XYVgpoEG7OkGjj2GpnEyxV2Z=`wE z8U#8b$P|9F4jCuYQqJ*xvr(7s1|o}c@U;jWK7=EVLX^UU*|1dLU2+b2&vT~QWHG91 ztstxzsp0Ed--ARhAXUQrr_Ts;1(qbK?3dWnI8zO2Oi_(0#oA^@Pq!-$YKAh>A<4hrP3TB1J+fHY0bH! zo;lWWQW{6i=TFLSUYaFGr%4O2={>-WkBNb@8!2N3!NBdd`op^FM()-N$fa)xC*+5k zlCkvHW$n_UO2?6T#`i>$Nsw&26tjav{k% zLO)ZuK^ut)l6RLsI9=WzF&HEq&2cAPeK)44z&l(R?z zF5LWXJ3kl7NKhujXXFi@l3)mb^!Cg8ov+8Ruj-Xw*0QG@5jxnGDkVV)gSF~Z0*Ja0Kp!TChZ$tj1H5z!<=08~5?imZtlNH7KD zpU>EM2QJ38oH-FG*Jig}%Rf4G$`Is0vYwu8C3CW>P`R!~m4w_D<-VR_BY;i`83#hP zi*Q7Rhy@}tcY(I$d=2^g)c@n0Kug*k?`VGdAtl()ywK2bSIs|gA=_xwd5;-&c#+k zxGDwmS9Rqrm2Z*c-ICj7%FDo|c|7PPQ}<}{OKMiCOjhZX)!N#I|18RB@H5<0Kte*| zB{p%8EHS!1h9$eA{Er7Z(Y2I~)ZN|v`fXYo&FIk3^VcTVIXHsm69n_0j-%h0Z)|K_|NK(v zp0BSjbwW#v9C~w<>JbUH%%c^vQO?4R@iKD*e)A@i&!v-b0qr;F)H5N$TJ#m!6z(1# zH^*0WbadFMU(+6{^(eEvL?>>zm4Tx2+?o>h*k94uayU~RD>H8nC}^eY1zaA)uHG2! zs_}7jeB*n#uE(QO{N|1IGHZg-CG1%qEq=9))m3d#=NV-i+F-4xgNAnKF8Bq37~RqD z83T^x2#AO{M4Veg2*P`Ff|h_>xQ3V|GYt++Pfh6-i7rRTSv=)e26nAW9TK-DV24#KFfGnGb$~O-nGhky4I;ENvmZSjKF&)V^CN~DBp&wxcXC(PT}y?G*>b(6L9A1 zGHMD7IcipRX6kgDrmDGW_PE4kz{JVUgp2RYHm2V>qyD0!kpA8RJ^OO*BaE3kx57;d zN7b6!46S;4dP!*+?$l(m2x_!*2e}-Jeazis~OM$kX)a_mSh2huKCvaN_p0u=uE)U}Hm7A(%dZJ)n*! zhe-W8@b3C#i?GA<S>t92@qHYy;K9&Gd^J6S$82&(UKg8HgYo2Yvl%!{#~Jj` zZ4dd)8p8Cx6zjbi=}zDneT;@>wak$q4F)IOq}<5u;QX14 zdi$k1W{#J>!#8<4Iy&+S%9i7DcpmfaZ;h9lN`8;Kz?mco^2B_*tb2zt!~1A6HErv7 z&pg-Uh`mL25gBg;6RA(p*DS}jVE#(Wf<6*MF)dlobZPh1=MugLtHFtW z8mc*8Jwk=*%e03n#na4h%zpV&!XV@KVyb?{HBI^qjpc+FvQv zs|jC3uN$L!*o#737aTn3h<`X$Ei|}^C)syktorKs0=r4<CU_AvM!6TeSiDN0_dZ1 z*Aebfe4pz~gCkB7f?PFQAKYDy+}4H*R=GmA#U4fiVQH7bMU78Q6)y>8SujFRNY1`S z^5=De2*rU?O6Fr0)N@+B6n^uVtXwLUo`npYuIt8c8>%YFh>^H{OTI_-J5Bp52VNLD zjpA(k=SJf1$|Y01b%LVRdFou3RfPmgWl8gR*_dKgY;nu_E;x8NK1PW4rruz2aduYR zq!Hn}(Ty+bW20)Q32EWC&%3dCU6pu-ooU+Q;^bTQHqGs`X+@Q9I@UNoN{rTd;9tOZ|g`k*;KRpWTIq+is;=E?k=w}zQ{qyJfLq)dMQ zO>E@hxcSZ7Pu*VBAGrAO!fkO-B+thqzzkWWlb7#dl8Pu^f*Ydp7ogF=_B@>C9Br-x9RxklRS3b z+wpH#SYXV-;W`~>ac0Us2u{Hu_1-q~#i|f4FnQOzLjH6Q z8=b@3c`RvM?!Jcq_Kdi3x}8UTFloc)KBZTg=$ppNhKn|X;*(Ud+A@!G&<8ilmc59l zUAxjwE5DF4Gk{ag54?uG-*+X6LX9HQh_hw2gYAXWkLlY(GAj2=`jR->IEbU>Z6_VJ z2Re5+MV1nUzu|OaqqBNzeoOEmr*#GDU}^}za5`u{)6-lmI%TWOc2QaWI#`LQVXpQ! z=I2|UP>(Ko3AbQp32)47ckP{WGmAfFLLdBcvP925NV>EwRk&{_Mf`N$sG~>SzWYrg zP$CV*N2RkMtB!!cLgu3U^)R@P+bp3xqLN&=#q?5TDtZe(K)BdjRuin|WT(0WR)o5d z4eJ6q>@1Smty1n@Ly|sXYkyOKThV*xlozv|4RlAnV0}c0 zSJ{2GgYJeNOpH7@s1~s&1r`VtqPEsNmpChA=~9 z4Ag&-D>zI@NZ6*e49A$oGc#*odan^w$g_g{);RAI;#gX>q&K|(ZE(MMs@}Jes=Z7-% z*C>bG^x?x4cj2?UeIGx{hS|}+6UT0GnJ8}&6T|IG{+KE0Rar6wpCSfNY999U)Wv+; zHE}HiqtskW@FJ&GUESWU&860S$BfP*T~5qp$Cgo;(6x<`b#W=P z`rrftY5Y$5x-4-XgV{J4pZp#kWr5DmS5#8s(J5G6&G~qD_u=T&)EyyuoE02&_T!L{ z5TD+Y6^tMHwjIA=*pxbP-fMftNP_ydghEbLl@0+Rp#*$Zik2pEeq()o&qm`57wPd@ zVfIK{+l>g}<6G|9!Bi>CzA%aH+uSx6k9$-2xl>;#aH=zjwE$D2{u)7yn1<|)IpCKY zlD;XYeL{wm+-cBxfvJ?i!Ia?Ibb)%*jw|kKfXU%)G#BG@csekz_I6X`U@;a}91}xm zu72H4=|M1+Yt&xHY3wM*m-i19{P+7s@7=xIweD#*DTbcS?zG;M5yTVevD`y3Iy+lB zVW?Xa@%i)T)V@Xwxo2|$XS`nSya}d`PYr4dlj_cntj|?m)Y4)(K_GD z579aGoA`ET1BjbjNp{aZ^Mm=1kNvLJ=8WYic^hHapPwF5zJGkhMrHns*Ia+4#G7^8 zJBY90tV%J4%fvJZd{CoGsU^mfc?^Eh9sLqq289n-t6m=r@h`5fl}WP3uJYWriO?{r zvWuQ-4h)PCo-h{*4%~XV*cm&$!*%Dy3rMV0l03rY1Ihjd*+%#2rP;s>|BdMvo@gXU z+E2iEww!v)1yj0|t66OnLD$mETA3YPr-UsZy zeI82x1if3>&SYXfd->Ct`9r?w=8)pPI*Vw3)(>P%lVrs_Q?C8xI-6nl&@WO9R z`|b3Xei%sV`NL;;EgN+=D)x}c1e^vCn>FTu*LaecEmU@7^x|IIbY+8-mNsz9lepOm z>rf4i%3@yZrZCB?+}xvBjDFf|6roN`OdB+Qr)z~GLhVz)pd~e76%7(`o-veHjbBoc zUFmgu>1<2Hbewe3M{m3ILcwyGYLdUaqT+K;?c@k2x_O?c4X;pEe+oADqRn-RQ{>4$ z_4vA-2X+&Fb2rx_n6f=xa>G2>8DbBE#mU%%6%p*gX&P5p!)Ll!C**RPnzDp(dLLi} z^P?rRB|RhdVScH8my11x-bO5mpNKD*Kh_}ePO@4&5wrOv^MDiECV~g$p6HBl2au8U zR;3#OGvg(o3o43BO8N_3Lmh7-a5B7hzqaRi38)0|-5Ps>MRZl4Iwq93rE^gvMeW9* zMuRwAQD9tA6^{`GqhN6CAYTtx*^r2^a0QRPd`y8&3UAgkVdmd_gD)nUYhkWv;nM3X z&o5uFd{^T$d2i7$GlY8s5hBHxmqHl6N&q$0j#BrGSL2X(1#6IaYaOW#`3Lv4_`~so zy_al}H{KH;ZBCL2c;uGwRaaQKySsNh3;8h8(cP^wIy{^Q%wt!_+ORv6JI|F2D%JNl zmEPSSud*K;`7{Wmdi3MRptRKPcaB}UcC+T!rk@cv7-dDOIyyS)0B<$&>o8KujNnV- zBd==qN_BA!nk*@wJRqc0{vDm236ut|0Y(m>^QxYw1ndSh%JS&hl`nyPIs$ySQnN|MD*3k8%t?AFPK{&g;`yNK#uKO$fMybR$(%3TA z@4!o`@MJmW*j0ls@3}a#b}LX+OzidcTr;D;qN1Ye6^TbUEaU5yWsJ=JfQkMcQ#4Db zhNU~U`H8f4YDy}pjU0umz|D&+wOuabw)FNk4EI-1P*8QYX!71=`H&w+8?qO-{E3E! z#!!R@E0pD!E{Cf4_ETngd(&F^r(s&EK?Ec5q(U#U{fF>B<#X~vugu=9AjW~haG1Pd z=Mj3uL!`2ZJ3Ke!KWYINT&vlN0=*hIGL(36#E1k)@OOBbAqJEeieA<(&xVc!p6U4k zx4xXL8l=VXZN==5WQ%@o#^s3 z*T035wnc-(C!;I7RcX0svTzMk`TouudovD6a9=dx*+oYiKGBq=TLuE!Ad&Ag6NL)5Ag^?fP{ zAf)ZreD1s2`r^6XUB!MQYl(p^&%JqZ#xtr(%qwhWX9JrmdJQ|GmD`Dm4J4k{s`zB@ z;o`4G@4d)#94+fMT~%~_H3;d@a;lFR7GkB!mfUkL(cHM}+m_m!y5H%bnWFUZ8{=*r zKSqf!*Pg*M1D|9bqZPAcmW%g@+s@>Nx&{o4H_u;xyAmKJbB`^JwDYox2&8Ae2CM(p z(^j><19Wbt-Y3O@!pg+DXMYO4E$OWHm)BgtuNhJ-c!#->7BqsAXbO9*b8MX`JDN-Mx60 zqpD1y9lsr{p$TVVuTLaRyQ!ypzMU0w_u)0V729)9ay)U?Qxa*cTaLE6jxP6vpX$8C z`;z-P>}gikYS$?#Su@uh&Hc?`mKV~I zR$I8znjSpnL75#Z>eO3AAODkUw68$o<);fS=)cEmPyTelpXoc3Z}zS6wF?U$ zO6I!YrAtpssA+k+m08%l7)ine``~JUpR(1KWn4zrLI(rs=R^V-_{PWg9mbb*rtcFL z7VhtFtZkH@EPkI0NK5ZOtc6MM%ncN_mY$qFaFT(cj$2#dsI9e>l=BS-x8?=+FT(uq zrq2eaw+`2qAIzA;GUtd2&p6BnQWjC37rT2NkNlhIjt0k5S{FS1ruC;|rWenHS9TX1 z+$M#a_1_7lkDJ1U)8Ex6+nw#o1*RPCV9n9Bzua3582{cp@kq#9$XCe6-3wH;yf`Dg zP@~s{y$;Ym&pDMle6o%;N>t3ha}~Uclj_~`-1Fe!nj8|DtL}L^{)MNShnee=qn-6% zO?OM*&J>XS{(eS=r%LsdZ`I_vxOeb2$s}vB(v8@=3@6{B{UYOB76j?aV!S$g7q_Sd zxLC7n+7i{@$Kx1ZUr@Ue)%{d3wfqX%tj+E7{8N>~s&)I(!QyN^*qZ?T^S7r)zn$PO zHrH)_9dPSB&o`7?(}1o_%-l#ja8UMA{!Ray*JYH4qj^nt8pOzFK-g`>>fqNwwact6PcsJ+WIW z)`Aa8)^_VUzcFM#^4s=F{&7hAaS$=Fo3S;qov|^onXxvp&ab$Z+@5Dhif1Lx6H-u4 zoZP}$pGVkIIF`9ivHo&1f?Tg?iI_FsN5io~#kakrGm z<8yy5k0;<>D32%P-nEcv3ksWdoH1KGqM4I#OAK>iw$jXp7^+8HrV!w^GHk03dq}d+ zf~lw;b(vZ~(CTj6NLU4l8!M)gddy{d0ZA+Gwu7);l6_W8W%cKmnFSQA!fckMgZW`r z)={)7Gs<5T_cW|rU}hOIC@`h|Ip_Zv;Y)!!kmJ)G{FNAj4gE)sa*%KP$7Ey5Lx*za z{GNmx%*Fq;uZ#o@m+5QxAvc?%v=?j1m0 z%!UnSA4`Z4Jr=ScRWs~^r*-jPR?t&meMkuxvAaq|qw<+Ra-~?6`@P3{BUEkkYH!oE z39<>&9=yP-F9<29c>SyIuIYA$YPGj0S+q3!xKziJ*OPOX1S=Tas*G1Pb~WVidV~>D zRS~5$K=Ar|&KlG8feyYoP6rF>GU6m5?2Jq_B!i7;Q_Tnz!^PoqFbfswNb@43YTN7jBRwafr z=D=Hn>4$#u7gRgL!e&!XR+FhjAG)7tIn6!T!1JQzm)LfoSxUcy$+>th_QWk{u9E@- zPGK}QyqzO;52fM0v*B=jg~8DqZm#R|z}C(5hjePI{TaZ&PdAGI0DJ-BjQ6M3qd=dV zyV~A&QJ5nM=x&z&*Wqu1!2lxM@7g-q{(cnrtKnOtzpUpG z2gNZ=p}!TZ`AGmDU?%|h(YxDSTU&QG{@*@+bLV~~gQBchsu48h2K-?C2?2h34k`)! z8Rd7j{KWc8rbuH}+x#_P3`p($F98MrC71bm_Pd$@J#7C(VHBv70093{rssG1{#dN% zFDd-jfRUh(!oLLkjeUO!xIl4_y$Hwv72)r$^iMWMfa(o@9`bM8`)#nlUJ2)Ao|hIt zaQA^wfH;{yyc|F+hQC1hOR0z@ojq{`^*qL!(I5nWzyNa)RPX>OZtgz!ZGWrC_bUOv zR`L7UIte6T|Izf<(Qu+MS=gaj?Awh zzeX_q1hH%Rjg(*GnSLG1ulplE0aQl+ax8y2y?%A)exl4z{D$%;=k8Y;{%oKAYzqqG sfb{jhTC2ad{_}GG$JSDFe`x(*i@&xS#*fe~2nBfOU_c;U3qOAQKbqeXV*mgE literal 0 HcmV?d00001 diff --git a/docs/M8_IOSpreadsheet_Template.xlsx b/docs/M8_IOSpreadsheet_Template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..5031d041d0f51db1f01aa37b6a23dcb899177c68 GIT binary patch literal 69410 zcmeFYWmH^U)-8-X!7UI7?vUUFcZb5Qu%N-+B?;~l+}$NO1WSP6?(VL^gMSCo-Otl+ z_dCY@{oTu8R8eE^v-Xm?=G^B{8zch_gAD-(fdBykK?;#st6Y@|2?5~@4*`J%fdHi~ zVq@)SZ0)G0;$~~?pu^;9W%)WA28t#V0t%S_|9<{2&cJ}`pfwaJdMoEHk7WY~llhnY z4`9BT%bDZ}ehB~3yedJ6$E8+iEyDrvMYA#8c%7Boq$J}VRJFK1+?8gwZ?Dsult8nh^!Q#pFwlc>=$yqpfS?G^0xdv zq`+dVR+p(IQq8=z0La=A;*}PueU$ex0hMLB@MTr|Za9|T7t4lOyga1#Qq`F1kK!M| zd9@8T$m7tNrP;Pxh20uDXu)R}2=IL*g$MK6W_D4&QydRO(X=pn()-7CcFl&6sn}8B ziO4pk?Pj~uqj`4K%!Ve{Cq@&6Nxh=>=mEp@0}e-J&{Up?=yY)fZz~cfOm_+f)AO?& zjLF}&iY|;uTxI-jcqAu*R3I2RZ*Hat-V%lM)S&;R9^owFF5PJKqEo_lCbHaGKjYR9 zZFPo4D|0@f|E!hLywKyi!Y7@{Gz3k?5<{KoCgMtCVWwVuNF(yf&vy&XTiZ&so&oa{ zGG+wFd>Wba$<}B1Mcg$;D!~b}aYu_w9{`V!kI)dHe`{*50hM%Aps5#uo<#6t z(t(-j>Gl6L^Z&&i{I}3cW8~yJ-k|$mNiO_I_FAub?FUM;Mptq{@Q0Q?{O}(0vB#OT zg)cx%Bo|Zla~|LN_VHlKg~=N}j{@}CYN&WI#IRCF>3Q+*7WXv`@VHo7{w>uME0P!- zlNXaW{_e8Zik7vJ3?(x(nR2}Xw#3FVaE7bAv*6h#{WqJ2W(^Xv1|puS@h-e~6Ccg9 zd+VeHXNn2+FGjaB9j`sSJrVP1mu~AfoOz>j53rN)5DP+^0ab;v}lQ22*Y=7g9pWI|AQu~Zi}yA* z7Ehx1&t`%Ilo6QwfA>#w><{VAH|PP!pO4YEtjC?5aAqCR=-YLjygo+Br&L)fv1r!X z*c8q=8x$q1QNDSMdVEYonY9#1Np8u>>3az&g$*r|W2u{@^nHHydJ7WY?Ss9hwlCB> ziW!q>^%T6)JhTK!b;in-_mUqkTfH_?W4pwajI`OZlr^R$NuE6s~YDk)LhpZ`Dw}uQC35u@~MX7OGLejcFV$Kfs z6ME%S5=_hVpkP28l>QErTqumpf-LjnI5Y#LHPHhGW>Z;ZC|?(FA>`vp53d5VjD(~4 z+Gp;N19Zz^0+Y4~5&I5>P+|wNJhg-RVl1mLDS40Rku+3wScAXq$G}ilAF<%QIE|&i z-+M*$DpBsjid=d?$$d&eGO#EkPP8#_9$7n)kF(y690ztmxbD<>6Le4ZIg|XvCc(_0a&A)6HY{vlu$bFca+WjdF&J|q$--;R3~9rc)% zFEOEUA+?=C-Ec2DlHZ}EDA2vVg?HQoaes;HQ1-hE-}3@5(aqyMsEK6C7z^whjzN3v zlsvM-k|d^+Jdkt5)_C9o-x1^-c#=wW0-I+i>_Z|hKb2u3k7QjlNk6@=6>w|U@phAR zf+)G@)nNfgN{>4)d$Y#CXSd#|-+P1=CuB&cZQ)hFehEb10|fP-SbT#PWPt(f`j=ik z?fjpy=xAnaWz78i`u2(B4m1^P2*t45$WLC0d)OFKJHM20DxRs-HX9eO)Sg&(<-3$; zZK_TtpguvZm7t&y6#_>!*a-^esjVsT%Vi>jOjLYNNm{&+=e1776cltYYpHI#+G<(8 zW%aq-t6fjb5+S45lwvK^Er$uBASD?yT0l9vY)asOqQH?4NIdal^QDdcQCsG++!(^C zD*FDjAb)g91A(Y?UJ5-ui=P1l^I0s#FY8XRFdW{HlRnT2`3PZk+@!Rz7iAY4BIvUr z$itK^n^efFjAf=T&IO;BN_y{8RB*bQ91)`LD`FLPVR_>eM8_aa){kxhcZCWOsvq&= zk#yO7L#~n4>dMPk24#baV5=w_%dh)4SU#=(C{9uiga4U3X zXwGkW!{v6qv$1-mmO$V(qAEP zecz8ZYNOERe*K$OKsWwGz~^dILBM+tUKn@@j=?yY#1j!p9W%a?FluKrGkWSUJ1PJTwnB(ex>X3fu>=D-2X^)x?_aBrwZ`iM7?E7>0(l%abFpCLw3*=Klu4EntZ8E<8?e8ZQv7Ft4s_uo)z91E1Y z+1zyIO|Wn3(pIhJt>Nas23?12cNLkmAY3t9j`Fz19AFfNTvP5@1$xhC`969E>ZzYNn-b)~y?vbBVl9LqU$9k#cZJyB&({pgl95HBerOsB;X#drvw5k!V3f zpWGKlodkq)L6+Ly+Vawj(lDurSSHpUaa)Y_V6yDw>y`Rtjpp<=`aCyGlnJ`MxV>|C5I?e9yfFRHbQGQ(=@`APXZ18NPWv>e;^na#GSaL616 zroQ?DFbowPm3j)O+ph+CKxfv5v4KBDS1S+|w`!dz+C|=rY@j5}lqSz?(z0!5I1g|2 zT+c9QK#vV^wCDa@yVH!>0RIRxLg&?yW1yYJl^IcFHJec1heWcQLlL(f^UttD68hrK z95jnx9x6;}IhC#%nlEWe%z3A&>fav<3%ed`N0&SIgQe;%TSXP9QgqnpP_Jy-u}UWl zI^Coy6~}@witI5F2i=^r#)yq9iw?etExWNgQj>ZEOH7pcC28bv^3&pjJq0UPrZ-Re0a4BTv%y$z_NKJ1{2bD#VQ}WgV;+B}l?2A-M)r1KT z$)HxNhTbpn+QcjD*|{p?H81(9P`Oy1H04k{Dd(=Q9ks8tCD}zU9fR9PXaoWizbB&U zY}zP#{(^vNfv$hRGHH|V#ZH%fmFv-NH2o2+U{-C0UvDH z8O$m@$y3HEA&a+ZX8tS5$0I99Ca#R;>ixp57nZBS?E@%`P3RnW=KQd~ycjGNZp`3a z=Z(syzctwBYn+qQ$-gGOe%ozNZLOa27_H?1)(TmmYBTST_Dx{WN zXU$G$5ku-1h`mgW1NT!KJsX=B4>L;w;NzooVvb0vK=}EllEvHorbq=ePP_tviWg|a zmkBP%%r?$0^96xERwOST4`+QIZ4@3B79Y=6$DNx5GErR66wm|?uQEtTUh#pw=9YB% zdFQ;AmK6H~7w-=@(;vFG8uYzf4i*H5coH3cpP-jhqa_(kNWDn!Uf(2Q48A6EoJ_Ium5 z-TylOm9TXpkbgG2I$BLFp5+6!dGti^=AY4f@NR9H)jg~~E&>I@Kh7Om4_7cXI?&U_ z+-+N^-HF34>v}J=e!H`{G9Gpt?ZLV8s=uX{&{Y~jblN-HT)bSVI2+FG81L9!{o#Fe zJ$c#j@bfZ&<$;BVx1o7X@3GQL=4(M<+wtY?B4d5Z+p2<*z}v;PI+p;yUHb73QpuCl zcMrcv0^Z#BfML4|A{@lw(|uesdIDhNA%uG_p?9BP-eeeAkY?QNl z?|r*^+CTWPcr;vnc+suUSxu^&pBuUSIB88%Zl+)P(lMrF5!E<%*mvF{otTY|sV&*( z(GiiP%w)W`G>J*Ww@sG)Aet*cl&yQD?J{w9BO2Zz(tDZzKta>C&*x(E6PwdwIEx~) z9M#RV$veehxEJa3zPoz6-_8?x-r6!;Or<71ICT$^FeaS!vgqpw8GSe#ZDU$KRs7P+ zIZ|Ml;``vlZ4znn4V%2vY!3hZd4&uMb3&|mE_d=nt;F!w2fX}E*sZ1HusdHl?u-q% znI8rFSI71E(a>bg&!ByY0}?jM&AE z%9@mv$GaG16JMCT8}=2HNLkdfpvUiF-*$WUk;yFg7Mju0(an-r;aVV_7*jbG z#Ul1cqH54kFq~$BnNaH*Lt9UDjU+GVJknII+SC3VK4bQMx^`IO=foUcifE2tN2v|A z;8H6iYc=wt;iPa-q*ox7+(K3YZcS{*L%irix~MK?wBDDVeTvgAaWnR)7jkPy&9zZ+ zj@$JVr%b`A)X||7RfyygDy~KRaxr6j6~Ff^`Yux=-Q6W~Twg$kxeWRO654 z1-XTB$zhbN<5$U(b|cxtNpdOS+QlRYjxgY~_N$^?Ya?;1MYWl}4jC!I&fXfSpcNi< zOCwW}Sc1Ta==_p6IFD^t3b$`VYgAO#EJI2U%RMZpV#BP|Q~A;=1*H?M-mH0i3^&4s zGm~4kpGapSw>^AVAI^&&Uw0w)Wg1&D%&kW<9Z7l%@4W$^hx>0IG#~eqt&31Srf<{d zk0dXs_0W9GoAAb~j~?#?qns}VtS=u^E?){L>Pw>v5Di7*VLdFbMm}0R2+V7ad`&J@ zEB_R6m-ON``r&GPbv05Ufc6~Cwd4G9NdP%i-XIGz#ac^toj97Z-3BJA# zIz7|f+!pC8(QJY9CEXl`Af?`l^$8AY!)>mL%H(>X1R~N}wEwyKl__Emh?OZK89R;b z5*z;FwGx~0!gm#{JGLQ%77<>AsqZM#2$D3UWG5@CGPm>|Dw*a-Gy?iLq{FR@zvQji zSHG&Mrq$!1$gGd2T#rZ@`WG|5|0%yt6c=NqJ})7Xq5IkxX$S&QRg6N(DO>ucj~J&gnWxyavatupP3rQCGseIIzWzF&4|1iFt9YX902v zDjw+Y>$_!hrC1zL+Iy=nD0t|LK}bO$4MF5nx<_*d3D}y#%#ZI*r(RJdE)yvSH_MQ1 z_bTE^85xor!)~CCfgmeCg&-F)Wic*mox@I~=bR1V;HaFr0+!U#?}O+7OG3y<^of4D zP5jKc_%>rB^K9qZFWnOYhQ>$4Ue3*cG)di9*;OPh>#~LSoXR&nz6p^|#?=63{AJ7e zxVmjgKLsOwXxi$(>~p40bZyJenr6br9y3YknTI(`3IAQ)@;8qtH`260!i`ApCGZmD zC-bdfIztOvug9;qPR9mg`d<&d1;5kJ9wWsb5<)&bwYG%s_gfp(kf*U6d!IEC(Pjl> zT7$;&G32T=9A$)`y#n9O<@PgCgo}-|DM%@-h*l+R2S#L96#+aq@*DFIUj{QxfN>0gWFq@}iwcus zBN+>2fnKP*#-r3V-eov%d{y+mwuXvPHDFl{;e=o6Xl+~-pPsvz3&rL z77X^rk#>%mW*@SDnNp27qiU_T!&k*|guM8KAx?FKyqHp}7=x^X)*qfz=8ITnV{#S2$W-MNnT6GOl$ggC^X zTYS{mvR)Ju!nC9Eu${sm1QxEh?6b}{4W0rpc6klV@)yh0)ZtaA%cPzqr~7 zkIzm+>Z8dM2XCj)$12H;6-h(c(EF$LeG zh(tgMysQeJU;CaWNP`dlWvMRYPPiqJ4*!1`}GWd1nC`N+h8^U$q5?s%D3bki>pR=v6Is>H9F z0j$k>doDl9sUFMRSlG)gJanRrVBtaa8SYzWB5P=HU*LklH9BG)^zngR)>cwza{mTT z)JG;TTDyvzRx6vT&9w>NygHUbU%}qEdn|3nQrpc|$my<3hICAZ7p`dMZNKSTgKJ9~ znha>zY6U@l7p0^#%n^T?qv85qqG`R7^jGH$)xOsG#rS0sNm@mkV?eiQ?V2(wsK%sg zWi@rwN?*=0TUl2u(i0*UB!7gn@ZVUakVbNk?u{L)Au1fsA8@TmsidV!A7E2WpURQF zn0TlIx_@$fnmaDHz9-!O(W5vmkqQQibA8@a_)HV5XrgH zxMyHkE}KuMz=MUYuJG8J_hdntd_#qDw}|*13z$zo+X*x4t2-{X+VCehBnN8`ZjFB# zm|WL}Xxv+!5(M+|3`Oq`K9CS;=o&oV)tU+Ls?M1yZO};kcqvriNjsxxLnhtEb@*?XsTjjVS@_> zn$mP=RJ96-no5;+%qsGrT}3Dk)HBspDJepT-$_W~T7F^9>HEge;bxPmmqJ{1MT^)K-{?F}u+))BP`R)Lm=lh=`xY;Jo>r;zd?~`YWSwrl>RygcyN@7#T zR?r!p;^?*2vCS@ILhyI0e65!dJ}8Ik-89WJPz0};#Z~UF)X|WJ2oT_9Tbd0M-kzuq zFL1?I(2m4k#0D!o=wS_;*nlgIngnnN$oy>fdJ8E_Uhf>LC0hRzg^AypftFCzeHP5u8jPE3HOLL7)bx53QeY9s`X^-zVwV z_a4d0NOh{Taa=G$1bGw9yIW&`zh_2q!Z8MUAA@6sfoY$G^N0#XY3oY4^Yo45l!C?3 zV-=+lX9x2dg=s0T=BNOh)FFSLxhJGX8$r*^o<_MJn;E7g-DAx(h$Bt8j~z3z{c#_L zN(qoMT4ba+`^?ua8T;V#83!zNX?9k2Gp$G#Xwq-UHF_x~B8l;6iD~?t2&DTKygog2(O*x28 zv%oguDQ{D>e(i68GA9CMp6zC0FTh@~D2-j3sznB}TqAKcxG7!R`wl2FJ*;dlpw>#b z*mQteOIOMORx)C=w zvlPoH?bp}WZfBLgW$yPhPcycD4*(cLZ?>NUNMB}6icmJDV%U|_ZA$Ba-eV>IWgAvQKr>=y>)$VgG@shb(5Sm23! zh;jRr46+j}$sMY`>(V{h8yq!}1>7WgcGKOeQYyf>@_{S%=e40JDkld<*&A<;OZjZ# z?&bmRt&M(N-Vozag$b9|MsU1xOWh1bM^$dbEHQ2b?sk@pk%4a_A>*3}^P0ld5hhr` z0eXWc2c)KOQw=q6^*`4d8xHGmaLn9pihiUH6C0V&bEc&s|IG6Csn1C@rGQ#ud<+&9 zER=<*bK=I(zludDo;XwjiNhFc0)0&?TxGpN)IkP;75ovDgkZUEPxk$Y7DJ^-`%Esm z%9UwSvJ21ZX8&TzbG~Ra=ZYsQS*l7pllos5`1OT+w_El()6lF!10(gIz-)@YTV7yA zA0UK5xJ+!d55x1kd9QQ>h4}D(Y}5QMMJk~rx`Ill+`TQuv2pLweoWj)alVKw#;0rO zb3iEUkI(O0Y62B~+sfJZq+0+2XZD`(wG`tnr%#r(f=mjbBcEi@WVjUi^Yqq;#cQuM(##1b=K`>G*VD`<6Khf%07xK1o!y{0ACBJLWcsH|EGbc1=Z z|EUUPZ^;KCUvn+l!hBRQVRrMp`3=Dq^UImv>tW#vb?wAP6Dl3WXM>yOd&d|&s#5L~ zqBen(K+|Jo0k%zm4Kf+1BDvYbgh{{q&G0BJ!?lhtJOO*${5}B8WOK9UZR5x+utkPS zu)vBd8Z&%|WZe?DZutyfNp}+&1|&W!!8~h|l z0cAex!5=1-ti^?);y}4o6!&MIIEu3Jff=B9I*7P%oXY`j)s?(;g4}#b4~Ew{AzF6; z=ah#$NQc$Rv6Ld+U<|(Y6IKOxCNy5nHX3q_a;xf>ldEo-57lq!3#d)h)&sdHE_`MN z)tJE_G9DU*(m$P76Lp;AaT*RaaB53|i4`Ga6M!bEPB7>IH&(?IP5ud&UqNvp_Z@Es zt4ryKrXM6{d#8vFR28$IgecBPM@S+-6_P4h2*JO&L9!Pmd)!!cwLwj6w*68=&_w5X z8W`u^#rP?9oO5y|*ennZ9xcd!DdLOj&(1iy@eQ&KMRD9bt>-p7vjv2$x2h8VC91dS z*!GB;W|n9O90bU z&m{XA59$?d0fdAupa1q9i|FrxbQV?imevD90BdNAX5{f(ik~kW?{1=(u>a z(Rtmn<@P2@jJ{>?1gaA|zy_<4?gsDGA8^Rdb?nG^Z{WFbs5rM6MaHFw{L&pI8mnK> z_V!^Kh>I3$k^-7Ibj%sZQ~zggQQtrLBw%p-29!sgDO3HL7XZI8RRE2 z#43ur2jYo=4fL;Skc=uEHcvgDk-}0iQtZgO035A*aum0vW`@GIN<)?=6cx5gGFLR7 zc-RdJ4{tE5=q2ituPSMO5C?nngiYAAa1}cy6*b(HAd?sprxxG5?u7IW&!U$o&vCf} zw>$uj*q(8eSshI`ROGG-&J~R#K6Z~eD>r{rL)=-s)5drNbP(Mh(K9?8Ih1}jYF31V z#ukpP+bFO+I2Xf-0NWm%TBN7jN&s!Nzv?eVqv^O9!0Lc49A~d2i!;Op{hIOt>_cEn zMK`y6vt_S(K6nlE1g{#u;7+p4JsBd}6b``AIQrR@pFxE{5Mem)bkuMnEC}mWn&+{ege+qhC^o|l)c}yd7-Pe? zogNFJBfk7@eP)te^h)QK{QOJbQ9c-}?-;!NP@!M8MbPpcO%v_|4~X=b*kVqWWvND! zPPbEAKcGH&qEma0-nE3GlTcIK6 zGXr<3fj$hTdDLw@{RqcME>dm!2kWSuxMi-rzQTaLfs`(-I|y_PJVB7{83X})xPXv& zX0${P!ssmuK`kn;X#V{#+8>Lhs8a~Wv1aFx>?;1O@JM(Dc%c%xFQrq6_GWG)c3yRy z6M^-v^$At4C%)#MBBE?6gNr<&B>Op;X_sgEdv{TwHwj&Z+#IswMdb?+q57>b1hKxIQU-7L_M96<-lEK1Ivl7xH1!D*oHl$ zKItY1GCa%iiXa&Nr9|c(ln``+m8s0zDf1&n@hj0Q*#1wz+e_G8_7|QKd&nTLUME!K zeobh|tjldt(l35eZEDNcYwwDR#GNp)_j1*!V{{?-oP>4EBKH{uPvvBo`h$46R2k6T zNAofnz4N=CVn&NhE#+NUDGQhSVhQ!;S10;7jC7cAD%EjR{+&#yATcG2PD-?~DDlVl zZs?&Kc3EU@JFx_AW?)+pL9i8$85rR;KHd~*TI|5km(f`_mNz^KW3y5(NpxoGMPqVz zNW5;mzI@w@UWBBHip7=cloa#PKmN5g8#g)326I!y2;VZtQy=%)doWk9&4eXik9Bvt zA}MUw^p>+U0~YqC#j&%U^n-za%qbjAS|y{`vOO=wWLzQzj^G=L!N?QJybn7u?_2Ss zm}pr&q&_5Lj;1J%ra(Tu{?He7{P=zpBUIESE88x0Su$p4^hGpPAdrqs3CC9cfdMFd z1(3%If_f_d)}C`n>~JEY`+gHLj@@QBI@}DeYbAqSoL6iku6cqOv@Ap|nAL+hZzHLn z*x~0VMID{OAo}?m2KC=w$w@24C`5KRf{f}!TuSO6-4{~kjf_;+Pr`P+URXQc+J)~20TqqEl`1LR=HkVZ0GJEttN@`I}?umOyJNtLRK zI^@I@4t#_yEX`JkM(3n|NJEudzrBA6R(UW6qr0+0U3m}h-|R{k3^;7U9j7ICdf>KL za`)pTNi;xVJBTr??FmzYX*JVJJ|Hwu@sC2&b${ivO)P;O6*zi-6Qi49zJb;#4LD60 zxqzQ08{08I}FAn%RRsrqrIUFpZP@GOI@#@aCmGk@puVP;d|H7d*GpHoo zA500@376=*a5G%)kp%m)A*(KOd|YKoouQ92Exa41(%bG1?KLX)VQ+OV2tHSIK^r2X znd&B>KNc`wVxLXCA~CtZsKD9F5r^3&f3uS#tBeOB9vC()!I++lCeNCUCRoWIB(~n| z5B0v~DtnL+uKMQtb>T@)06Z`~C(_$9;v7TJpMQ@n7p*F62O3lgG&w($N-kPTb}7HD zj5G;5uO!JQArkf-DH2GPoiBG(l^gy+M=F*4Twb}6$T+(l;&dfwL~5mx-Z$yz82IN> z2ifqk`#Co4W50iV5byf4{!IfYn%}au>gIbKt=Gh_*IqDiUYMb~kT^HF`+s@)XVwfb ztM^~CuvwG!pbAH*b$p_XMM*xs_d*Xn2k69WX2ba6)2;GN;i}LL0?G}A+7vY1xzsdC zstGU)%8R4iXF|!A^+)q-CVIFujYr*d?>4N*x!_K8{7#T{5L_rk-_H>jCbLQ*+?(^% ziB76&Xwd5}8NATW5eBAHnz#%jvm*votq9KOEsr zi>I$3BUJ9SEI+}SnDsCLVzoH<@Dnv>>Zz>1&vi7;qIf@z4-_v|0g5*SkB$5#%$ zi#04a#y?2?47nmQnM|fyw#EMrVh{@t!P%BNMxE(?yM5NZIKhi08R;}|Sj~FoCdDn0 zQ3Nca3@noWa#NO>Ig?dM{^OcG8E)LT|LLZR|Jo~9Bz9C{rYvED5{$uO@y8<4LAp;_ zAoDrJEEx0wx-&!D>$H?@tKX-{USs>n|Bl#WnyMT9lB{#Z_1GsMDvpOdLpvC;PE-8+ zN728a<0=t739pTs7y0scZshmONT?`&D4J>NMZb9lksHf}qIR5!2U$^~xMVJveynXc zo5Gd;h{>(MAY_zIoR2}snV%bCBAel>!qDM^`0vZJGPpMTu(kvI8nn=Z8omqi&LX-A z3NGjd%A`-EMe-N%khm(jq`N7poQFZiaN7BCXMZ@ zNb2mWLH~0Qpw>KqT1(nhbrk;NN?1KiaS}D&m&A^L!nExDBuZy1j zX79_(_Rb2kLL1n7T4GMJ!~adx#K60;ZsiN;wsHqnqx9ER|HkU=lg$}Sz!S^0cS#k& z$7dh=-dds&ZJ7&Us1qVTtDQ$Q!}JX2ZkiwJ|Xd$rF2t;OrL z_m_(PR=kA%42SvZ2zui;S%xmM8QuAYXI! z8kqb{R?dNI9|yvi=3m~>qcFMT9^df(0zYBze^0RX?Sr{4`BY-Pg)uT*2`Q{{M?pvQ z!;;Ij=s*jBtT8nvyL@*uF}(~FaeK66MgpUIk-GKfKuZrjrJ|w1z}nitH#yByDC1yMURZ`7(CsrYx!HW~$o<{$-^ zyp`;PH3{0ER>H7@jKz8s;}ej^k%*7ZdI2J}bLP=pTWc3yGasc|gMzkWe|R=R?-k7T zM1zG^nc zI7X27BiMaJ3a*~-#f*HF(2`oDg#P5`%UmFo&CZMhhv)pNNT%uod5glw|MxiPug(5g z*coq1)$KRe?T9VoN)yErkdpY8`CYpVvQrxZr+Ko0Y^g^$BRxh-ob!cB*L<@uZTEbu zHm%mYyh`9)SI&2B#Btbcj)?fwwL zvCbTWsQXL4Fq}t~^q7A>e`yM4$^1sCMU~Kf1*||)pYN^p-If+I8Rvsvc8h}bUzbmLk}&~* z-9?dz$5?|HEx6)ri63m%rqQ;2CnXI=HTqLJexP*RCroLpPdWXfWyNu%BG$PZiF1Y{ z;amLMv0U7q@Vg*5r49ll1Wq$KtU|$b$rN7W%eN|CvNg(on!tjArwq4d?mU(OhXm+p zpK#|tVB!IupJ;=k#n-u^WE2I134$!gTccHwy2W#5OZH#=4@k}eCQuW~8ul=rA^jiYe;`X)KE?E$7vET5bCBqIs>H4} z`HyfA*dh@TyKO|Dj40J#FQ2j-f$S@m)hyr8w;Y5cZn6X0#qVRP(1IHy>M<*lD zxbx-UpOgFQ`lP;}3{m|90Xhl@b`ADd!I}0+uXhHhZCXR}EGC-4?j*q5F`6fcnnd*p zDDegWP)U--<4@@V$%7wh5mo=m0#@n(-0vCe*x`Uh1bHi?hyjo> zQvTsrfT`+qG}kIGsyip=#GVMaxL@U|o78VG?Ti2d1}1#o40iBsjo9Buc`oW?z7U@hBB= zna*>9%eEV6FpE9W_usCX|i}H1AmFrdi4Bq@F>64vuI9y<<=#VG2SOnPOpn<`z*7=Y2+&>ff zUnC2RH)ybo8_0k!f}TtCT!O!q=)f5$VYl(WO8A=cS-eP&GqWNX$U7nFDCEEL+F6fG z+qHPSe&(|qKu>@Q0Alx40dz0-gz^1_0Sj;yPQjPlf4TZ6ZG8H|J7b@Zl z&GM8I3$3R9$A-O)JK3ej-=BnVGV*Apiv66N`f(uX+eMA!R>L5R?84`NY6#xeZGb=b9HwI>QSJE9-+pVWZ^+#URdqCaZ)_wna7QX5*;WdKP9nDx2n zl*BwtGT?BbXYzQ4*MI8azu>0>2rp2|^SqFM2qqSTLMq|i1zzU`AL)Owu%nzRahyOj zj#o|S?b+CHbNY38G5zSshIv=;EaG!cpu+rN>!0s;UK_XZw6xCJ9HR|XB>E)rFa0Wc zAa=gGJ-grZw&|`J#=>+Z=px;gsOXVnE$Gpx_Zi=$JxnyYCS5;Wq6 zj$hi$k-J3Iy^vmw$6?;t%%*wd{LQ!a)qFFL7jC!bQ7@MDbeH+SmTgC9XiGl#zfSMR zMOtZpT|c(z9mDXz_M9>F7T@T5RGx z_U1bFcDq_TfH!{(c0XN@6yWE!e{&6$dJrW&I`-=&c_rv^^SvCE4s!Z;m1-Elngc;GQ`Ei?df^yN$He#3X;zq`pb;HNxQf^XH)(?am{ z`RyduaZfv1-zKn3^TumbCc3Vs%bltD;e`Y3*rn^k;oO)s`uTQKDYBf6PpjfQESm1k zUM|_E9GREPqSr5=m>&e-Y#im*=WzimFPmHLuf;#@5~hXJgfo5cl(A2gnO#ZqzFi4t zGWRU7Z4eNfBfh%W)~+>{;IjUiE%Wj*UO!Pfsm4ov=j2E-9u_c~@UMmi0(V zpH!le>MZ4lO!A!*jT^Ha1otSWE+c$gHdFvJG!g@$y&O*}#1PGTfU=@{O^|{O`LY27U*%1K)OTd}L~3xGAr< zDcA9=eB@WpZCyH_JUZL#KCDQ%BH0!1`!RS4y@;8_yLL?0-1hKW>cOz>cA!4@h4=E| zE^!?2UE9mk`*`bOSz?Ue9o7<@`M*dU9fBRwZLakANk+U985i?bwL!oa|HsRUZ~OP} zSAS54JcimVFVtjQ_kS*+KKrtH65Hmz5_x$4a6@O6S#x~M{J6m*dKFo*D?fbSf3+2l zx!C1)@zv+j?}6{Py~6B+19ygOes}fOwqE=&wE**P!*9Ilcb=ZSR_P>diKz_KUmoA_ z{&x3pxcc?`a(}!-;r4#JTS5X&J)^EZ0WH$HqTOtV|Q`P4edi3KSP;Pgl|clyG175ZJ&^ ze`sLqp2UTrcEpu9mh6y4xpi+W9AbOlr?7zbNi3ghYNP<$S-NufgK#{5RDZ%$H==TU zr849o4v*4)_DtdL-j6q-wDM{qytA01tbqr28He-EZybMZaYV}qFvN!c?ipmkG?b9? zjXi$V7O1qm0y^;qIeM``a>K-&h?^h0*%* zd`f8MYuEW%z}4%36~t5hqiH=cV^cWYkZ(8=9Gs9U= zD=zgCbpJm-J|BGjN9~2oq2Hp2UHLElFw?Wh4+ZtPR?&X4l(B~} zu;9%%oSl)EwAK^hM8*C#@pyMNQq%TRPN#7qs`GmxJcxm#@%7U8Ye!c%XjQ`C97aUK z1_%H9yE`_oQ}MFMy_fc?X=Ib%=d`>fN}V?)RSO2jQYhmj%QAi%Qr(KBpE%(=Yk0Hj zd+QhHu!172VVu5gTR&u^#ZziLNM2%U&XFLYR5tNMg>0J$T7(@y-EZU!twC-hl6a@I z{nx|3|Ht7!A6WYTUHHK%sARdonR}EM5dYgrt!LEds%tx}abSBN%Rc&cAOFDn4u+fg z&>j;N#i-5w&C)d{AdRO)ceGIBTMh7g*%q(i-ghis(Mcu1kUeKTZRt(ZX7kG zyfZPK!`f`*w5_GIGM*9Yb(N=K7y_}ON&D&uE0s&) z2YbD^J+q44q}0X)3n%bF>33E{i)P253qHP{_L7>}tJi5d zY|v3uA|Wfj7gpYF@P9ES++C|JVPG&Cvf+t~C?ZQfvzbbj*T_z#LF>}3^#*k)h+pvt zyHA6DoIcbaBV(sstMToWQvLX8bHrhq>pcn42@-!PrCw9?F;!zNnm1|iWBAq2< zEwKd*`r8^mYnHBA#x=PpV8RG6F?bX(=xpacJS={!>Ph`Vw_o?N-K~hg z_$N0t<@P;^u%961g2k0Wq_Hw-NI*eyw55k~#_bo391rM6<{q2$>$T;+SMOf`g#KJE zEpj15OU{!P2uFyJXORUfG%G`CpF^sQdRc@`~j_Q4FKDy`#^PTo~YE-wWsJwt?vz~q0_oRfX(zYs0 za#DJC+eNVmWtG87g<$T`xp1b{skF2`%)@V;>N?rV35mOyExI}zYQd@b4cZ9}%9vc9 zajd#+Oe{9&MKTNfn5F@|JD8?T46!gTtc)dXK+9W-c)J-mqsqQLn)d00qC-{Hmgw9v z!!p2UZ(Tysh|!8kQj-dI(mtvYM*1T)Z;55w5<^#Y;qIQ;n_iHPUjI^ zTv6)G5qyN0i@NpzN1BDsH01VDcf)AQrJZ(wg!*O4I{dgd9w%SA4?R_|I=kXIsm`qEiPYy z5#sjdS)`4v2!BXo2k!-acx|!A!UoBI)wOl-%aZ?(z4ri%qG=jM2T6(q5fMajRa6ip zNtUnz0s@kiD6EKtCFi)X3JMAW3IZ=VNlr?XxRON#Bqw2Ek(_pk3v9T9Z~Vf!=R4>8 z_j&KV&p-3bOl@^_byan$?&BkhWt@;%LpB|U)eH7E5XtN=n*=WBsvuPTdEH%c$ww9&Kv^J&qrvJoI z<+p*-m}llbr`&X6rIM{bk7z}{%R$ zDI2S2bFKgI+Kh`z;AAugevw{-cX9h zsu1aC1EAMiVd8$Yd>}?Yo0Pr5bL6gRgDnnXgdGNtzp&ULE}fB zuhOc%k6D#w^vaY9PC*oNdWh>!go=D4blz^?;-)(B!tIC~H#G(N#$>e;pFGBtg;NDc zc>p-;o-*{!UQ=E$qWGG;l~J>dcJtttz3+5T!(S0x)XLd!XLMFKl=aaGM!kE5jt7;* z5BU`GYO!B3hy>4|r`KP z4O5G2u`#2=&?FV`HpuSZ^e)T;PMtAQfp zs2LB6Iwii_qb5hwkZV@Rf9p74K#P6;slI%aSK|CMU#_H%!fi5^F;c263t z|C2h(#`~q%7u%>Wuicp=`A5RoY1)ph#YP!(G!Zhj-||lkPFTO8{mgZh>CL5Up>MBL z@c2WzT(G0Z!_Ik@?QcotEE)6%Gm>4UIXnX#vWJ5@@VRz!TQ$j62yrRME5XPb^3G<5 zLG^fb%69uaar*K1a~|sn%WJR*G7iF6V(ryD*FT>f@3C~PZCGWZr)+d^n3i_fIyF&; zyx;sI|I9G7`j@*ZL?eHxdYO+63F5@f8GpPn8sWvyH}hw-q*ddOI4Y;C@5h7 zOV&^}AdXJC3!VGAc6xrvQ`s6uc9u%Hdyvz7bHHTgz`DRq&`d^(XyYuN{6I^<3bM4w zc$JMUsBCVLr&C@k*ZQVh-7l}Khm*@Xy1ex*?sJt%E)Sz#aihYu=8*d6dh!TvdK-Nc zwG*<?V8q`uGmWN-gq}d~h6-&W>7~8*qj$#ewRa0Lj%$pO;N` z*SogrpldyXGkb{}wI)O;c{`PSfJUYw5u2K|-0f(4vo9jYwrb5Ep4l3UBd&407xa7a zL&QLgsrhE*F1mj&$LZ?47nyMRc2DxcHkJRj{kVRwC->OCt)_$%xRnph%;sFB6m%)J zy>YMM3~B5ujWw}5vP)xA%{k>2CZxH4gpA~2uL!2)$0BywGtv7QZsg4#FN2Es$mP0^ujVmsn=>YI{!**xGiNKI zQ@%IOCG~K}bVerX-AT@|4%!pliXm&O33UH>sPVOX_q!L2-?3$p$jo%@6q_vW;f&gx zsa>KDO6bK$j@#>sydI~v58MPM&#aTvnBUe%URZUa+NJj0SoNA6SMoEQz=51U&KEe9 zac`r2NNZc;YkrNjeF!7dXQIg5q*)F}k47e^{^Pd()%8qmJ?dY$(du#|Hf&{Bli>F} zt7E;I-2Iz1pI}8M>JC>st0I^}x>^e-I~J!lHVLS*jzL0$rd3%Dhn$=YWJ{2HhV-7~ z{r={oZS>w7R+>RTWny%`CK$%=av)LGL8RM#NJ>|+MsB~j88`@-5m#K3N|?$RkuyhN zva13i*rhl@nwpQyB?0biGl*?_MqwdJ{&Vn7mk;2g3 zWb&wsQ;H`SWXTX;(OLcJKv{RZ&q(B4K!U_;lv$ylo@>RM?`H085}DDxDH5tF z6Y}jL9wt++GPZ4Hdo*2$BA6FT_fn@-jiKD6Ssh}~Q)L*~ACw65u^{fl^qY-P+x_l0?7FSO>NAHr3)9INZJGFiCfhuYRu!E5lIdP1 zL5H;BD0kmKui+jnzr;4UzHojJIq=&VYoa%XwpkAejl=|fW%~k|joh&IT4orGTT9`o1e5a3^(q{`jHLb9$f@Dtl$M+rRvjLf3z_ zQ+f&d`{^5Ckw`qf+EdlT_EYMd-=!A*UFtZm-_;vHZXr6w5BSGYol*r)L0W0!wPK(k zeb3sE#ZN)hw<`qKbIHG-3wyB+J0|5&v>c2_E|lp;DlhUa^h@eQQTrc)PwJ3=KYKU% z$5*OskPZF~+K5w-$8z^Ule~r2nneDzwcy}zLtQ56k8|Fna@48!&>ZPMO_=|i3D4{O zZbF~mZ4Ewqs_e_q8N|JvJq4T&;`QFW-*Qqmdtdh_{lP}We&p|GiqohSO6g#8b@MqU z6Mtbd4>VvVVRXXxE|`sn^gFYhzngm-B8x8V3JBYo{|^n`VENw$2P@Bi8~ndZ_+i8H zU(lo=+XzyUcEQbBWwqv;!(q!a&3gs=iu3laA}O36^^4~rlYjIuo0-1R(rnSQZ>7mD zLgyw?emCP&B>E57s@OUqjAn9Ug^`sL-DN6X`vwNhwbAWrMTKsgdQ- za}Od^y1a+>Wa1e~`b;asOsRts3Gk|j*{L1OEXANsp+F91={UQ#5z~S!v+YY_Tl~aa z*1n^)$Gll2Q6lUtsll&zuOhyi#`>&R&gOVIa@)R4O-)c+blA>;p0K z{!YyWyG$SOzvy*mlEwR@JKP7*;7*itx&AvHg43m+^vPEqG>H@(bEX;Rd9o`g{`#x0 zXXwQBm*LkcNgs<}+(bL-F>ih7YA?$lx~Wl|zb$KFXQJaMyT%PC+TWH?mL=n=XE&ms zILbb=?%Svj$_?^E7z_v5Brbn~Z!w5;cKRc@T1>j!$u1)CVo;65u*Owi+&)6B{K0

FPmBY2-@Z&b*K93tDm!MpSz4S{d8u6x#Uk2`Pmvv>d zEt=npbpP(^)YXP&ZLltdOM5t&6}WWkRB9%1o38HBnN0S0@QgRuWsYh$gr%w{66Yh& zV-n9^wtT|BYuEfDQv8fj-0sW|9n=Hsw(<4TA8-4?3EPiI_A|)xcJ0oE$TP^U z@F9k(Z~)3N1&O`j#6Fd28X+hg7)gU~Re4Wx=wOQrioAsHUR++)u#E`{^T&tq<6DCX z%>oG3Vn;`){eV{+QO9jSHl98t8lAA&z3XMrZzy{rCKQBeAUZ z?R1qE)Z-rlR}C9I3m^LFznA43Nny3`p{ul}mVO_|Y1qhE_>flrJtg1B8`hQ2be@l? zrAq@jjT$uzA9CxzXW<)p$-2@)=V?VPT^5*Z)Yx74&|3ffalVn~tSe1)p61lG?*kot z3vCk5^L@{553O4KaKzEK{Ke+Ej-YqxO5eX-(ky$IZr=Az6mF9wDyqf7!NZ{OHdt9r zQ6wupz3tZZ7zc+CgT^nx%6An-vePg2 ze|rnJ`6?=E&A}ncppg))tf5$zoo?R$tsHLiT~ySGgF})*BPm!}Q&A)*E55()D;z#o zF6w5SAjRL66l$G^0Z(q;Y%+ZUw(IiMwb|w97=y&lVeP7SO=U$1r zDJMvAbtS#A>b@gl{db|`ZRYNZx?N3>V(ChHY1MsO#5yBhr1$IJhPFzO66s2cx9Ywt zVx1i?(*HFcKKE7B?QcUrx9V09u}+UK`}WnyX70ME+vx*P9?)CNJghgi| zQr38NJ${;yd$uOIKe5qSoV^D&2#Y28I0sC=imb`@b4GX%(TAj3c{OK?tVJedu0=Pq zczQQ7O3=tmK5Y-`6?urKXNMkd>j}h_JtSQJ2|mTSJtUlChtjt7JjHE3B*?Hs!NGda zA$Wux1+)o1!5#kz9&Hm0#DzU1Tw+Io;8UFXL&8aR6xAWv`H*mf9YxLu&+(oP32jY(^f!Z%p{<#ZaJhyuyr=(O@K~te};Enxz!E3pObiA>Fp;>8<{+|Ks zbgn}+volG~+vE9ukpVEb^=g<-y-b>gLCD8gra^RVC4qm0RL$gHb0&Phzt$;nxomOD zRy@8~j<{0N)Twb*mbQ*g#I58mKk~x0;ig+3%M_sO z{ca@PmG1BC&s^(J-5Xin#$fQXsb=)S%`?pfB>SPe?c8B(IdKpPCMl`CU*rO+B!Bd_ zGscFTA6O6AJ6MW~pS+YtJ05^;$4_+BqO^v+5V;3ccPwVDi@XNW(Z1S9_~P(Vs@8_m zCQQ8{7bVldwjCFX&_Vh{2`&lp?`4oSF2e?3#v8L_b!2=&O-;ZMlvDh$>zI4G>rsNK zt6o6UTSK9QX&o=(CQ5uhC{c$vySbaX563P)u9R#&L~rPY5nl!^@9jbT9TP@z|AX~Z zF9!F_pVI)qk+T4B>bG|zHs-FDkM-PL4;R)Pz9M;M1anHfa{?LpcK!WEXGOm8_+^c8 zJxnM7*Rh`|m4x36?!<>Q|GoBSIE zjrcB`TZZ8J9(Y4F$Mwv_;dR<~bE*xRrI)M?g1GgWv@a~TF~`gfG@Uinco5t$57O}@aUs@AL5q2QuJm)V=WUKW#5m* z$Y3e{)|)8yy8_GZt{vQq9y-ptAMSq`|A6QkdS{h%oME~1V(J6ND+ZlD$&b&(b4v#w z@hS6r7{lmqjHkevzOD29{`zr!u^~foMwcS-o?9iCBIa_EL+Fw!)WXb}hPq!PriD$Dn6;@a8k)T5@cxzik3`Ma0tC5z+AEPRrO%^# zoHwL21Hz&O0iTEht8WhW+K%?$9PPE8=vj4AI8c;y0;@u$m<7H&&8Lrs-@5(Oq3DIh ztu_~%+piD&!y+u$RF6>KRh&QVu}b^U+)nE5$r^0CFzd_g)XXPFxBSmx;ZKgd-T%ae z$$hgJp=1A15x{d|cz!UVU8$zVYION0;xDuDWh8s*wg=4?w8p13B| zL}d(gh%ztgyiziz7{0S`>fxOPos}ja@3F$dm!pRKz1L;RFs(%UcYcd6UWLEN;_Ab? z5TM(EY-pcXcs0qHuQlOse2l>pJETXL+)rY#^!+ns~R4i!8bfPcIE%hHXT zz1KF{-81zDg>Sxbj8@wk*UZ_^?4Gjk*UhOPI(FmLyZVZ}s1W*J9tu7hu9Y^+?5xdD zDt@fePw{2r=Io-}Y}#&L_VqIEX`vBS=)v&5{B8%zUeeN!X3X)M^Yo1XYBqFR%y(2sg z$cC8HhJECxea9*jbO+;gVIS^8!w{tgp)ERl%}<-{m*M6uUx?!f5aPosMENb%YQ<^hr(^B}O zZQk|V{dTYQ$CKl{mE4)KLhB=4wOk)YMIP1OV1cM#!rW~c4)GK`QOr}e`>rt5qYQK5 ztEYgO^pA+yu56y@>lEkX$K516>!eQha#3-nUl6|9>^OAM*?8r|NUJoJW(wW0`s(vV znn$j}Lq2_Ue=*7-*>f%4ubJ3AptxOn(KMWD#999NX0P>2DyxhW(+?KfiaAG*$SYiZ zck@KTC}p~r?*(^W58{QLX2F{3-G02=g{7Uz2I^w$oY|?K2P$z=-_p&ezwWl4!aT2e zb|j-jh>q^o)ykkJVUi0+<#&1RAo?_PPu{pAb;EtmVLNrl?(_(JFBx6VBs(ETC3 z@4y&UfVN7jC~X$_9$zRaYsh&ypEl_Gtu43S{kas2wpE^uxi=7?Y;anSsk4xaYR3E7 zL!rpmjmkc3^vgPQZ97LB0mwym%VQn*=5?!(DSg#5-+5k6iK|jcs9yT0bh42l>ZoJS z^z;jR)^{5Gq4mW#PoeL~WL`BArfp#i&pg3d{0@;yxoZbrPT=JRUS8nk2VTfj%1Fgj zN&z}|;o z1Kx}dJ$;a!dAZUpYAR#h^E(XnVd`bB;oUFSPM8F9u1j2#i1`v9aX)Qw(q;-kcu59$Rsndf7k!Nxig(Lj6XJ-I;okeF0{2!0Ym>9=zvy zv@Un3;_y7Ao(pvsmdj(2cB1h5D@_zjXZG2=(-72=H--63vKf+DEfmY6gzOitBNXQi zh2>rv@*nAxe;db|sWfm=Te;0NoFwwmNbX@qp!3~I4)>P=)F#*}VzV|OL~IY-xBXwY zZ4Z&j6X5`t%(R1D*KbQ^{#Xk7*F~W3?vFcu7eC=I_zighFA%2d9#YY0JjPG=u}G&J za!dWK(%VbaQGUllNq)g^-)>)G&=x%q#n4-KC%N5)2GnUDNsbqP(7~a?M8$PgdeCi8 ze+EjHq@h-B(;d}Izg&Rhw!*egL_%fE{7g;n7BGvx&JOJ1h#cy^&z|7;m_>}q*6L(w zP#;SLHV@ro)_=S_>9e|P(Dk-@Iyp!+ zkN}^>+{cn1L&WIoEQ*#iS)x60udM=&olDN_*$eftCYqhOo{3!J(oWD{u}uv(<#O+< zYeTlTro6rpK$q}VR9<02@x5TQ%;%1aT6c7BYYY%(992|3ZqV;!WhC!eb@S|fNnu$p zzhV2HDLJ8udcn#I;CS=L27r`qM^;Xrd4z?Jt zzC+|oR}b$L)vQ-rza`yVKh7}8jQ6iUTXfYiUO7-pEI7o4KV$IdI$nOq%vinJ5aV@E z5--7fYfZz($<$i^^G$TqW@&>|U^B!=o!>**HLupdU)GHrf`S6L1D*hR z8gN(ghFbxEh6cb3#ytv9QE&j%AOt1_$WfgA16HQs0l-QN;=%7{g}?!DHSbRvP4Ibm zfZTrm{`Gkz?a1#G6hIo~?=bM@kd(X%NNU?SxjVVpI5}Ss5fB0-6;w5-4mpCyPx#7D z@WcS;tI1F{cfA~RHr^jv<4j}9e0Mzyt&aUnNK=T8{OM1CGgD~wm5I*G!3JAhNhp_dp@a;qR z(XX)KPnvtWiXhFQtc(^m=8r)b0m9cG{RMCR7x-5hKnjqLilw8aE8OD3p)J6YUXdAbc9cKZd)j-un&j>-b1h3xvVAM>6c3 z)DQU_(tNgXQv_`ZTms=q8%x#0JO<^V1Rh)7Rs!McAbj4& z9+qB^52dTExtcZzbAa#*S0~-Wv_P3DGc4^@4$}hpQ?@y~YyTz#<$|NV=3!c(zEq5s zZa;Mdc~UO8+uS>>0bpDzad+2yzs038wt_3G{zi{*w*OfcLD{I@xq9dx$_DbM`eyE` zqyoYqAF2&Y$NPtN17T|R$L6;WZ7Tr6a)3UCIbaDm0gu4D1>gt}feU~xpaLj>PiMdt z46y>>fIWz@1Vb%B44i@iumf@bo=*EG&98C(q_F-Od*LuPn99GW`89>b-)Nku*rMoTml_ZrEaDfU+b&E=l>Nbd#qLThY0`0%Zc>%Bn7C}jW<>LZ)fGHo!p${m$ z=J4S8BhH0DR~X!)ClU)v^QV?he};p6{?Hhd+3Bwq0Ng+e{H`7UU+vV6sAK;lepm|CP%hdH+-2L)@XZhq>^3 zdVjUGC1B5}z<8FCi}5xigz*aF-9M-uaKH$()$dmQ z_h}v0061_TlmrfVfwZomRSzxf2>5_p|5{Iela%T_l`xg+Kb2a^!?OIl6f{aSw`t^o z3pBhmQZ&LeYKQReHIIfH43h%yN`FZIYt8wC;vY1y{0kLml|T6K|15QfW%V$&Cn&c) zD7U4%r8n4j0Dz*CvyUs>+Q$9D4Iv?k3-VxBW_dx?(L&(*1#^4*3qOP0F1T8{S-N^! zJ{ABD`@zF_0I;e1vwx#F-Sa2TT>}7Q*T6RG+n+dN(1j>;1KkMGKXE)@o5-3903XFI zJX}40#)_C355EZwh(^ux*+olQ+TkiZ%)Wh;PW`gA6j6m6*Ud*(PMPSL4t}Cz!3^c$|F>i z)YOL#0);=t5zw1prapO5Se}MO$DH<(%c&br-=rVqQuxrws@sdbEb_=T@EF}`Huf_d zSFUpNT;mlL6PJ*bx~X_uNm=ENs+!)t`}zi;dKQl@t*mX}wr=hoo?hNQzCq8P2Zy|P z85$M+HYPUim-vK?%y(JYIk|cHrDf$6l~o_BYnqx{THD$`cYNvV9~c}O9vK~*#?1Vf zots}+T*7T^Zf)=E;`jCs^*Yq^_v2T^K)L^_7ia{EBUDtBRJ4bBQ5^9CFG^-A>WjiO zC*^f$&0Sb7-FSNRl){_z4~@sTM0ByNk6e4{PG1(CzJfbc?Wbn{nPP$eTbli$*q?fh z1B!>PCKy&1EVLSEmOfU*~gFPe5tv5U_v@u(&f?c$rrNX zmEkRdQE7HM<(=3f$A&elcSWL9chL$pCvA zC5aW*l)8UHhJg$`n+ziZZ9HJg&ke9Sq-RW&$Z3fTGJp#O@F6>USnF_t1lCQyffz4C zZ4HT-#Xp5R6m(6Yf@>h5+ujIaGH?_YArK@Ni(s9xJ~)@cUx9tgayNlRxle;3ie+spFnI(aiFYLfrxEvapn-@BW2UHP6fikHS{ame zmPc?Mp^m$Hyz`edA)jj=9!};KtS$LerOnp%k<}L?ZD=$8HCcoc21)gnn9tRVke_Bc zwE&}igw1JIM+I9vVGQzJ2XlVV`h|@0U1I zpSj=uwl0>e)~T1OZjH8B<3&uWZVf-!h*?-bCHwx~_a z)cPoahF4T?q@QZ<=@#$$*b>Tz8N=--9uE z(z{@s+*R(<;Q_bZ6>7b8lGND%BpTrjodRwkh=5HA9`klxzC4XQ_PyQC=5o-9v14nFSMNM(Q81c)jp&|z zBFpt3mht}9fa8NjWWYg-#zxrtl8Mvk4)U3?(vM69yo06RG#?pwIeh*yKFlHC#5>Ha zpL7-<&Mykx$Pp#rt_?Q65hxGD3CzO?%4r5Kee9LzLj?ui2Db;c&yIRP zPvndVmWX!xg%#vo3Nj46vT5xV(|098_~WyCrs<|=uid9JurjtrWFU+qfK46Ka}FVj z6)(a#NMi(B(KM!Ji>FDK`wJc2Q>h6$IHwR9u3Y&XTeGV}jw}5pSjW`q)c~Qfm;nhL z+Ye~tFGE$@B5eNXN!l;Sa@Z>m^k{)Gt|11iHzkIOtdpH4((Z)e%ZhC(8wBv-nG>z% zShprf*`^KY7&bgLWNfF&)UPcer=?4QSnT1m(y!H9CsJ%S-kh&-(ukKb5zlv^j9$porc<(J1Ybbe$$+&Ji*15ID1r-%nvqzU#jUqj!H%z$)M<94O?rD_ zkd5)6;|T2RG7NSx~tP{IaZ^nnT31*FxWePp(w^FJCELI^k5 zR)}B=t@VNoVAl~YWMKY{%1)&P8IbpAz|QB90qB+8+t6w7!+`7iClM-SAjEGbk_^a% zLMzH3`^SrRLu9q~_5^D#k^%bX2T_6S3M+#71dx31e7|?^>x{L=CVcczpkbF)d z?W~|%Y$ofBzNwoVFn2}Lnd3VFU}MSMg2a0@NRolg&zZj~=Iu5>22!IAG9cK`u(Dm^ zF*z;^16BcbMB144(3VNk>}nklhEI^^8q* z?AWC0Y*l5H3l7rdeIa&f$?%cYwNr5-H9YX755$5$lyX?Tva7OBklR51mneoTS^oSV zSo(@zVw{+XX>S{?3(Ix;@x6Htq2k1g;qRL5IzP(dGS+HI>-NeNRp4XKF+ByGHOjG~gr`LaypXy{_q-V!z(7t%9OK*De zLms^5dHImnzCRggbqe>2l^F68E|(CGi;X5IdkZ)eU-As~zN!*xI2xs7`G|)!_z(6b z1D^<_8FDXagmeyZJyI8soC;SYv8=y54RgR|KlRv=W;$W0XkjO5y(+z3?I zXH2%Cpk?^zJfZ_$3M)af&V_4VZU~uvZnU}%yo*kXa&>j}P4SU+^^uAGzTJ@qctCV+ zK@wmzBxW8;G-mt# z9hz`MGGC&H&ovAA12xlwYykP`Y)9fPWg(=nl2v)I^|RIlTk#up>xF{*w9Uw=YUDEV}=k7d?Nmu|b?S z8JI$m79iL!zEC0?Y%B=uZn~4nz*kF%A#95&7|c;{05bd3$19R_oD8fz1^c(0Oft~x zLCl3>R~FHPHl6L~WZ)LwiNGdEGGzOmqqkst>eILs(0hCij%bd~uTmUn7=x~)!+{!t z8}EXFNMnK%-F8yx@P+u01FJsHNhYnb?;6BZhgnkrGtL|v>0k7>c$)&o6PZGGdG6&F z(bO-Djeju(HCn57WD0nkT!HuToIvQJQCiXm4WQ%k&vNPig9gvcOu>#ekPIB8A)Bu) zkbx~zq%9Lc`lc5d5Ps`#j{GJE%1PZx24bmaC!u(7%vnQAxRC<(ze>Y9X<+YJ2DSlb zREF4yl+!5e1JvHb{|%1knX!sfrs!}nEL40>7fQA4lwW=n}X-b*#()sqj`9G36D;*u|vJHO4N>{>5@a~p_M zEq()9hNf*|z*yDP^q_8h3m;QdVh|82Ze0tC{?Gcxg#1N~lK*ei+db$G4zE>2peMeB z+C_##8BsRSG1y(OCN&{PJ7;KHpwzY!C>Hm6h^KT zE3rfRhVx3oA1GcHCvo1s#l8ZbA5LQa8j9;3%>*6%5HWc)CEDmv-a{ z9iTJduLK~h54eyWmxjo|$}}0UhZ5~j5n_9j9%O(^#sClcl#2=0tXdIfIsG29uTKHm z6t}3swRzwJBIJ!EX_;Vli3uSqXfjX`w^LL!OIlVTHQ61;qFktlE%-wXkMaPGoXBPZ z=;|2*dlox6iw8o;(Rl(TDL}BeP>|4q9N~8&mgf>nuw_fWvzK`QP&hdgVmul6@sL;o zUBT6XV&?}c;A!=+hfp61#Am+<&0?{@ivET&Hp0XF=6fNoN`VLs% z2Q4wYD_~_ozfav^Rwo1MN{Ta)_{_aja{vE|t(ZdO!~?#k(#Wu75LB@}K@FE|B#@^O z((i1CZnDMy`b*%(bsg06;;fg*67C`!5;^}{-p46s6pB6l%)xXyun z$GTF+vlzA(bV%y4@}q?NIO(>Avskv^xj}n(9x>FZrPzJVRF|S9JLi4RH%_u0M`m;z z)YYr`?bD3}u7nQF-G24%WX<<$-G$ZgCcP+44JFgu0@I37@tCa%r}uqMw-YyvNwDGX z0$Dhb>B%=!4k8%O%o!xTF+pkwgB{qHi0J-cE%9vI4|!&C1U`APx?gPEC%eC7wNBMP zf3dQLzpJR_z3oZ#SeTdP8+E#56$uT62g?cA+4AT>N7WpwBwa5JxZ_jns*>q~Yo-Vo zUeAItUUs)7l4_*A2q7^@5(eD|2i(;dtNqj_B-6OfZo+O$7<;j!dBRMi@s*qxqI}7) z7M(Wti5r|2no&C#*190Ko%@`tnvR34+>a;nrL!~^R>k{E>(P9w(sVs#t5pX56ob88~-u;JF#T{A^T!lf>lfHmH6Z)kL zi(fvxK?J+Ig2R=WVuLf&>sx#$Q!&Y0)2T1FnV4WUea7$Nbe1X;>g$u+lCPA?Hkqj$ zR|w}(%B0W0NqUGTar&yM!H$O|-HYC^-Q764e7Uw_53GfPbp%F-q0%rjFAco!v~1jex#DjcaQ6 z26P>i?-dEa?=Azb8RHbe7jkEhWt-Ue`mYt_PfWZN?42nq>o4z8!<7gPl{V+V&ic&R zsWzE3VOUgq^AjuTJ3Krq*G1K z66y(pT(m(*b9)K~{wDB%^PVxE{H5kUsFwGrSB zV^BsGQlkYK$gw+uHz%>~m2vM3;Ur$lT*HPn?e5FfVwk{5Z*V5C>Qg=K40jlT-yfN| zY{r7;EF#GFtu$P=)5b@t+iXLR!RHzaw^C1dqqI``=9@@o2R;04V2kfZHS&zv@3h^2 zoS>VKWqi-#azc!y#(~(Et>}h)ezB`jWz{+cHT~9ht9~90#8vN!MSra}EoOucF;DI? z9Ckk7GO2s=Dlvn=jUApE4%#X>F!gIipV^LN6C`jMdp$+ktRJ(RJcUh(wnUaJg45<6 zC9DX84_MmJIxd{a^31m3UbZ?xoX9VnSGalM}}?-NBn=jC(ujTlF@uEOBWKG;re$nkHGl zJ?veTF`5#jAH~P2a~k(+l;WuByldQN)Qa+&PJ|ot9hc0_(T~oN&|kIFadTDEjgEdb zZeZZ@N-WcJ>8-K4shE>v?0Rt*KU4BH=(q1w;^u;|C7A5!nI1;(5FKo42-2qH)p;&F z8+QIvfN1Y}InzrBQv(IQsBG`A22ce_Bds{ z=}p5jLvT=@)@aAIFX2~=JudY>D^M1w5OnQKmMHE}{?b*gT>Ypx)x@a2D5nnmzSw&9 zVtG#=Y$S0879Jqs&5a@MhS!--pZCc1Tku(5})5zf4+#+)RZ#Xj(s`wI6lse!QY z;oBJr4K+)*qx37b4F+>c^3e^Q0hP8gRRmTjNe3LeP*aeBGHGHua@)u|GzCT?J|hF~ zLt*>ij>;}%;1p7XJn*0UC^_yoxY9gd)RZ1$TUR!^b5gK|<)g zw=l8e`C4DA!%Of^EygLydHijP5AMY2%1Gd9r@Fv7_zuQQxbt!T)`|f=J|V<6+7&^< zNmyGCG$h~}LMF1QN`a5zQG1&ResaQ`0}*Ab@0lQr3ih~mCf0L+*?n(Y_R2+;w(H}1 zBK&!V=T|6q&i$MYI79l3-ndhNI*>$;Gm!z~^_lPhuVm!s9##@Ba^EVxRc|IPZ)?Km zG2~jnFxWT~?jI<6(}Ip@h|F0GKeX8w{Zvle8-n@taX>~32d?JOE5#N^Vu_w&5OuCVDmV$rED@-UVtjcnSEa@I!K)XI*d?KVATHx1BpevzxJWPl1i zEGJ2j!<%P-13y-G6eZXbNgc2)p~|$L$RM3EmJEV4aj~`U@Q|hyo?*eQt&dMD1cMu- zv5YTgAV=`+O?qlhYwoDi#!H@2#bs&mD)Bv?_NKQ>)p~EI4cN9r&StIUb-Tc9`(Gu2 zJNvKl>^QKT8LiD;ThFYhBeD6pkDEwKm-_^OZ)~XQ@E>LbPZ919$hhGO8mr_^;%3*w zDr7~P8XzBV5pOJMYF(xx$2yzPOm#*@@;M#vRJ}^@20HjnY%{DjQG1|H3n`F;4dff= zN0_7@vmu@ClM3fiPUV-{lvk2ck2Q9io|P<^xN=3!rBC`^nPz{|Sdy;3Mm@`7Rq}di zRnw}U(L}YU8ED`@dxAU`*#=HsHbDDGVp;9Yks*`P{W7MR1X+JrTPy_oqMQxIv<*76 za%{1N6{8-e))=djY1AoW{Lav(5q2=8AlnYdsYV7&%jhQjOzq-`oZE)N}u@Rn~<&YUL0y(#x z*dwyy3tjO$fG!QE=&r}DBsjIEj&<+Me^Iz6({Pt*HrOQ_>lN zQbVr=sX5f|IGV|5%sUGqBcn0hvCUu}rU5?|-5R0iRtP584Rl*6!QfjO zR`Y4`1mRjO_F3u)T~3kKVYzd-?4oR#2Ieu|0dqE-O&{y98;TIIhPz};dgqv6CmP;8 z4uqE3)%)a)mS_AJb8~tleT}bJMeNMAT(u=NUVTK#Xa_u_GBE&hvI14$0J)9t!p!4# z1ECg?XQ9st>QfasgH@*k8M{gnJ1*45#XD2&!vJmAe1E@jP_ys+OHn(M@mktSl(=WY z#8#}%M7tfrp@Q9UWvcs?Y!c3SPItC>DD171)iD3+*XZ8GJ@LXHnV_4wLyFr*yXLH( zIgmtHCZElS07hf z@N~%8l#glM3ajX^PbuQhn!P+!Ibl~bZjyRw35it=f&|J@s(|T-o{oc@mIL1qSWPaQ z3F1EEU|}*+m`HFz$rbSB^ZK-4^Mv57MBPXdGxC`)cbKDC&+0nkVs2cVF*2-9$)7&1 zrp(yKR9)o3V08B2&A4*&&NE8gGBH^m20f zyyk4X{p~?eDiWr3bjyCb5M9ouqVyXA3#ptWwo& zRVY4z`|CpiOLMyxj&`+S2^*SS1!C)>lU4PT!?jK&i|0{0>cj-nWdwUoWJ@Y5K@YoY zjFU?~kPhfhEmMv($JT1##Nt9snxJKaso`?X81#ureCfS`?MQZfjvj94-Qx%bx#qjr zxv-p(MNh3fbq_y3ozRx1s#-M>9ghNi$4t!!gFbAR)D{(ZkF5*9r4RD2QT@oWgVm4M zj`9g!aS~MeFdp!g3~UGm45#jRPfCN67xLIkIV{*|=*ns6zUPPI(;;|+xt^>F4TW*l zzHJTTO|OxyA_?t*b@4ruhK`)kE+2Qcp4g)j>=$1Prpla{C%X5lR1YUytG-<2aAj%Y z38A_ktY$@sYeNWO{{n<4-Vb;DK|MC-RRik+l7)M43agG+pEh_#;zF3<4X|^att4<| z)-%#YyP<^b;15{{l{h_YB!SNwH%U}ftcz@MhI5$KPV_7k)?`HO#9VlrsngVL>lSnK zKDSMtp1#XlekgoprKq#Z9aiR#tcLG zl)Bi4hYK6(^th7fDEnX|z^nt#Zq$IX_=)BYZD))QUYLfxIyOt;zZWV@E53M__G4x9;quy@Q1_W*-j&I1_B=v-P=Ex-M0lf6R7-la9{9NYZ zn3}7n8(i7xyIGe~h0nboUSXvUSFU^>sxpQy5;TesDP0976Z_FS4+iC!@gY-j&t>$m zicR`*ba*5tG4;f<_!w*QaIo01nPE2AfIE`;yB$YP5J43~WV$zOIk*+}qJr-;LA?OY z)yNu=BUV9-X-l^3e0kr(Sf_|vs#VD}k6%hJR81#Ll{*VlSDf4tv$l@fM(-~VV0-Yq zNJ6GGiH;Ji@m>cCWMHWj$7&Zx22keE|BJGBk7v67|HpN?N)ih>M68qKxDF15woV8k z=NNXCq*=JSBExKz^Qm1WToH3V#H?bDV=?2BU!%(ilttsGu4>-V}opU?aKd4K-< z{%*HWf3(f^d_EtK$NltNJd`EQOn^K_@QBldpTqy}O=v~F9Mlu=6L2~r=YgUQ1Vp4n z!9KY|cr)rVLNh1~Y@)1TKa8J>BKTWOPe`8ZO#N(?`uATKdd?}Jy&xdG9OtVsG=8C9 zWH1Gh@j5%%SXrG`GB*hwyzwN%e!47NDb_?_R3fi5^TclPGT+%rUd3y#-VKa1gFE+u z8p%pCbFHXG5534OQf2xswURQb1Ki1GdtbVfosBA-Q*v$7@24Kr_@X@kBNct@gDQ*F zze0uXb7Oz={YSl5eo7E=Vp2jN_?KbPj5rP;HffW#s2PO*XqmO?(Lr|e59Bf&vz2D7 zCmS%8u|_WOVGv5^5l}j2yhmm{Kmj?y?%VXn{f-Sjc$Z;)XwN%qzrI6sZQd^9-+z37 z$3^~8;+1x7u+kxrRpz|6qT+&Gap7>b(b}^GEw5*M=M2{}hhq4?c3a^yp9z-39Oo;% zoU;EPjP}3K&|MN-Er2w&Q@gP)ooN=5iw+C(|KrJ4;dR-Gw2r#0%-$m=->j$E6X%U< zXREHBHttKV@Iwg$$b zEQ`5YV|V(&ibo7xPV}%^nb1O+iubKK-yJU1W7)V$9)>#}BpQ{{HbWaQgip@4Ix1V$1&e zO{l7yfw`eO;Ku!X{``ehZ*FB%>Zl%icDUB;6+kmFRLE4L>Ak%7B`0pH`*f#`?VJ%i z+{3FZ8szYNw$c%|V2Ymr{Pzw}7^xh%4p$PlX=-Gyw|j-A6?buipzV`T!Ej51t7X(# zNh^WrqdTD~>dzW#Sfg!X<;J>4dVP>N4`rH+Qj)EWd-*d;@ABD*7cZI&K9%4_z35&o z&By3)LX@~^T)eI1rT9ImrnE8NhU*hBMPSIfFkH|Z4jCpfgsH8gGd5XQ`YrT$Fv;85 zxVn>X`)vY>fm2Meu7Da>Q;^KLAe4JuS_syXQ1rFrx$nBvz10&#+2PNM&X~`B{i534 zj5)@!JJ9@f)ne0iEAOX-A42-mtd|v8K;*)ohZkcB9rwNLGdg2tK6P_B`#3q~)wR2&NyB=WY>zJ0TC;v#rwaJRJvV(7DXK<99LsdtY_L=`R{Q zA5l#@F@DbWWuY1yXP!58%h(TDG%_#95*1-Yr8m9$ zktr$f^0A*eSn2LW(m(vZ#L%tR(3P*w*6Cg-b_pI?Z{<*O%-SCuY{-+b0~J=!{T{JL zq^pAiG9FoOZ=nSleYahTyUa^cv(b30v^V{MZh`dB3mw)!J3Q_51>J8iW(==&>i9I; z+8=p3+>E(v>lEv+W31X~=$t-ab;9FWPUMlNLG^EjxQe`bMx&Ef3Nt(O$=@kQ{y5}o zW}{wyGc=5<`}h1sJ)MKk9!X0XuQ}nEpU-dDv2vuIyOu+xEy8US|N9PWxDLx2lL63 z_NJj9=8Y>nN*u^)PbwU2N=^snq<-0FI9FlGEPIJAd%fyjREFN@%q^eYpr)0U70<7! zG`Uxn1}Y1E(HnWsE0A{n<>=A1^x{8#K5{(!jLBcBgx%Yjv^N)xLe!f)vUBW>*yz&i z3FDWT-cuK6G)&iETTfTw1>e#1n)>z}YeDsEG*5OLt9@&dF! zgyGCvv0U?D$q3R(+|wfHOo}Qalcz}`C%+1>W%Wj`p8d?%ist>OZeokR(G4i?Ss~90 zUwmG!93^y#CN?=fy~{hr?>IFc59oCWt}LJ^pffmvKWEu9@vEHISVxDul>nxr$@h5y zrd54t`={_jGmPxaxWe1)-A%t1)F#$y9KO=OR28(63m^Qj-NNBeN#lZRmR@Sc=apy3 zXE*C=pXFqoL{HRLHY;($Irns-AHT18KGJ}12V@1)mutz|p8bo;%hu873t71HAr#N~ zfu5rUcf$;pKCR((gvJ@IWc<2U=W~CaY+#Q~>+9N~YHr3BMv<~yR_Q!2?$(1jlJWFz z%9}UAI^90nho7&17dMN`iszIOGOatY$a4aGLcl*gzIbnZv;!0}>n=}I9`v1@n8e0- z=N)_7K%)o9Luxn=F#N*h`=uUHPAZopS5BeMgHG5T_f@{cQRU%zudv|!M|L<1Un`qQW0y?ZLn zmNPG%JAb`-to`?T`KulM6r^_7g$%VPmF`7_KhT3^%R?1MOY|=6Ni91%{LCeCp(jm$ z+#uKMYP?BmiPgKy|FNSVVjxl|m19g`@j!*~eevXLeEVf~@L)t=i&MSP%IaUQ% zpIv|BE8_`EE56^V5g*>Dd{w;h{cqQkDc9%`cWd4eXYQWU^xQmvyCTeDQsN>LQfa8F zG0f`;fZvfRhP3+p5+Z|*qd^qV-#|K2kswDK-E+Iu@OeOE3vF77k~Y?o~lvRea9xmIGhP*0$VxSH^-S~|B% zDuvDs$C`t>k;ND%u&uENl?8?*P%ynN(t?MNA-HPb^up=^Dbt;K2wvD$3vr3e5o&!y zOdmvDYjB{91g(~=!UFJN4!cU01X1QKA!|RDf|DkoV7VXKK=to7F{%8gfC3erTN#s z-MtkJ`SM=Z8uhh38$P3#1^3MA3%;WvjjT6PgpYm$v+Y6BR2F3zE|sOd4iy7|5*Ce! zhMyAajH}zebZ>zSY^&M>h@sjqY~I?W3syE_&TX?l1UCs%`$*)0>xjJnbyQRWM5$;|Q~& zj?m+$U*Hv0;wsESUtjy-RAK8fonf8Y(KA+C>)l(N-9oNjCzgvOggYvE#BrCkN3Fx9 zPd8oaz~17ffyu@e|M8hHnH*>ml!`k!e+oHXe1GjJ=Wn&8C4+&WB{s@X;;`GqkL4s_ zdzKxT5?)jpsQTkfL%Gj8s@|N6)|b+8%&nr8{ild|eizk~bB!(g6diQ4pOy8f4!-fo z_!1SIL$BD7{?~g)*M~p*_d6=pP13;Yip~QzyhdtB0#wcq$mMA`GDxza6{1s!lqtdK zgo`c01q-LpZ_s($`>R@|vES{R`e`RL z@}B!)oBT%;p~$8N@km2U^X4VH=U1_<4d^lyUxTPhPS^1y=D*EdhIP8 zKBzMN-z`!@nnuPy{qQ~3qx5J3-iYU_cmW(G=$hMbyEbY-pDE$!+9JywHcBfBMa@8l8wlHkgy&dc7AvmZ!N_x#sV zY=UCQy)AW& z;cir?Q>4)*;R)yxXfFc-Kw-LRJVD?VBwCZ)5W9iAZvbNDWG7*2PLr@^2o}N%@0B(; zRkvpP)=;li+RrL(+Ja1N4L{-GN|0R#{Fv~Zfc{9VzhDN5t8MY<#2*>P`S4(i_R8v> z*ID|@G)wY)Q{tOA(O*YsPY%kcx=~~l;~0FsVdjnUF8L&isWUaQ+PT8LX!0Iz{u=?| zBlq$8tV=Aq9sJzoonj9wskWbRcS?1=S+uv-#@rxdu`w9bob3nH#mQYuFmO@ReL=yI z8e{Vm_>X)u#1GS-68d^$&f?2IB~a_T5!}Z(@N}{CTLV!N28TlUCJP;VPT1Nu@Kd52 zl-Wh;qPn3AVlF8UQ74tKN_a4NifALqN~5FAdo>|(b#TK0KHNe`PoanpV`q@U$Bo<* zQxhgZhV~{BXFs4JzH#Z^-Y^V1D=?s|& zOzGd*F&|65w5Dulv2zv*cC&1g%=29wH(~$#DQb%e#g6`VKMrpZKAjpTa39kk{|_JJ z3;QmSB4f&6n8}>zOBA1Rycd4=?8MMFoY(N~EENxD+PbO2t5@pNc@diEVuaDtW^;x2 z%$8*AVzgT5>_8VE?Od|cxx`lW<-5IetmM>#+n0<|!A010Gb1x;zjODu=kHwdkTK6@ zbR7Q3P;Iom7wr5jFY8(Hr<^+S1e;GofGpfMK#6-c%0p-!k8=|)oEJ(Z8l|b6A6X58 z@s+9Q@Rzs6`)MPqvNDb>w-@jC?#PJZ*+=qNdab6zhHt*?bBZ|eL_84sEoa3YfhLH~Zmj>5I54WRb_)g8*-*l_5b?F3#R|d^0%bEED(HfPI@-e5 zn;;s*T^^dMK8~KAu*eAaoL-)SSN$Z0f6c5j$nQ zrg?fHC#IF>^s^(vV(kyVJN%*TaI=KWDUX7fT<=!Jk_Tkec8B6&+h>B|c~I4AVTQU0}1 zyAZb_V?B02kRYa0(^vq~5^S?g)F34Ow>k_b6|XaN$0*7ms?%3PFxklKwXiV${s$Nddj+E>x(>nIfQ1}%0?t{V6+|7e1$r zkMLL?4hEj3FBH(FEXT0Y`q#r0ks@g=+S1KFoFDn}!OKdapX;udJANq#!%QUJO8h3b zf)PJpZ#I)Y_|rV=vMF#u8%il9uK@_@XWgV+xAtvwVlDT%m? z(Y)T^aciKr+N-Ss$a1M=Er!VkP8+}46+$sE$~BYzZ0QzOo47RTGya}=eU@KoVRe!; zQrWGgJ3M2SakKE*jgm92(;0Z*T2N8WS0HP3 zcoFrcMD#>V|GF;(DG2D?A}~2>A|-AVoo&a>Bj<~*0(w)ZhxMA~!oD;MyAptN1$YAO zFqie~@YNX#ZLzkk9aynHK~tDCZy2hb3)3+o?&$R^o4DqUO>whR5Br~IgMsx1>`1>u z{Iy+cPuA?6EDL+vYky5+0{;%x3RF`S(A5t{$w zR%T=j;v5Tef=q2fk}l=QUXq1udjD_5DFX-FZhXPN4y~KOAgi-!eT_;<3T{1t&RjDi zrUX|P3jt4(5oxq2(XFa(zjt7gAQHfQRH#HbpUGW(tz=jUF}h zPgL&gwX!$*qInyXKjvmuT1OKHRX~O=K-`N`!S6-Rk`z{!(_qCS8-P%Do==xpKq#+9 zOeKTV8J>-j$J)7I?_7V1dTkRCR{W`3=KNs`$Ps(>B|VOQ*9lPI!57xV^0>$Bl)#;M zlYFfE4E0#I$%~s+EcB=LeO7J`zgIXKwqGbYqtkx3Na>iZA;>(`-bJ6L-pXzn1MROv zqQg_UR^wdL1e$H0IY82715yqntaF03qQLL(>Na+JR2JXP{DYxjG`N$Qmm8!%Pd$jm(}pm5#`^NG3? zYabD%)cQ(4OnuxHxo=g*yy$l2&R-s!m1#4((*&;+THEKi423;6z-yx_10!n}?v{He z2ndgEqH3?a?%3Z^btrZ5*Gq|INBqy3&;N@q0a+7BUmtsXjWJ3HK&X1(&fL&Q&Gsj@ zlVM$vPPD;gYS2X>5Cs~vS#MWaU6zKuJx}@m@}Zt^$Qz|-Jxq)Vy&T7NQ}t_Dz)11`fF+f=~^<& z@zEg0b@Q53Kk4-gGvl(wMghiNu%2K9-8t(8O`sBX&%xCMEwqt5&A~f39X><>dt+y4 zie1vzGHPvZD6uXDZ5X^;!N+D##=zcwDVFPhsQkA}`~lrVP4i>4N(lQBY3AEAMq0q` zOA1T!83+nH_SK*Dm1?hksdcD|O!0g3RIjV9p`q?_iJhnNeUA=n{C0^`+^(cx5n3?A z<)p64Xt9hT`>;}Nctbi%v3IPLgUw->`8GzBX}_p|_o(Om2=e%FDd*1NUbl2?zT7*I z026fp4?*x!Vg#>@I|n>0!6tAAgw_c(7_Uzqu%sclHn7nyO-09Dzyf#qkw}l%r=&j; zo>{NCAIK>K_)Y-P-!}ttT!a+1jCmYTxl}*=)ff>Qo~I-P59?hv`Jw=9 zjE{P*Upq%mrOV5vzp8-N1fIe%_OFuvo~_T!JCY9>*_5HuU%jSZE_)bKMTWV{{FQ2Y zoIFgsml%Bg$X~&S6n0K0KK0A+lsS`!n1IkLqKLwgzWs4kIrQziA$-vQX(iR$1&xxe+Kt*p~@9V{S z`?3SR@uU^@Bq!%i9ueTg5Y`N-!|c~=c-9m$8qsdHo;=$AQ({~b=40OFjz6SkydF<8CAUvO z4d)5e<)w7)9IO_aB8C8AQ?3cz3pg)9R_ZD$&UEsi=7G`Q1Z5qdT)`YLrJ&UyiD6_( zTkwR*y~s$qe%+6|bZgy-Wwd3mLe^UppAhVlh$d>OH@ z4lBbRzA${FNn+D_?c9*M>sB^i(Z{$oF6ax|_t4-7Z1?O2{$c)KE0Fy_*|~VW{Xpn5 z;uTg=YswY7xuwNJ$*iR;)05}bthjq6=hXh=wEpFRMHau0_#5CO!0-?q>S+!OR>bz! zeN97(&Tj;LqN5&}qo*8$%Eq>`+LxkB&sTXnMnr6{HCf+Ci%;L3PM)Sl1QjEF-{(sU z6g%*G!tgdieBM#vNCDTtrBiJbO!dH75~i%e1+g3H76T3a69UbhHy-OnmDRhw4zf~b zl@@}Q2Y*Y6)h3B!lHUkjoH|m6Bj_MfYSm-B6zSFg>G`w1IzmERwS^3qF1?@@kY=G+ zf(`G4{~}0WaP}{VkHuUPnqh0s0~u3&DnJ*ncLg=}C*e2T8G%Z2@X9`8b+W>y_3&Hc zRXY3BS{c}3z)u6G7#s+ldlj<*VbUMsC4uc>AmAEbCqBiZp^8P95DG>?j!aG1Xzj9c zUzv5m+=%b)2B6^VTG|%r9=A`b&u^;xidbvpsqn4ECNE*hUzpQ2c@!AuMn#24e4@nR zj{tScR>Eis!v<$RwZf`}N#X7YA?=)auW?UrWZ*a4ZQuznBtBauHf$m20u*tPAdkL> zHCc9U6xPT4Kal)OsIpYBdG5lbp$-#^IbbW>K7j`3H-#YT5414!-Bx?Z3b2Bx}@Uybgxfd-q*anddlb4MxP?R zuldyYT)b^HkTw{K1^zezn6cdE%1 z3H`Xnoz22~jzA@buP%Fk)S+d_n5ZhcB$&>svnw*>G4x43_Zs^Ke0 zqCuxBKK7Q+k9uUseeiPmLS?>>J3PKW>d+-yiRJQtEOh^)9YLI?-=VP0`3Y?y`_GpG zl2?T4vt3-byq2k61Op}W8<2EQXwA!f&FfRZ-g6ez6@-VMZAN>UGRQ|q+wj^WM)cjE z#T=6%@i)Q^S*?aYgYnmej!&;x2S{bp{``uMPiJ zvl(1hpf7^V;YzK!O+G9Nq^p9)#E{fHIe;r*FgS8FSeW4xZVoIZ3n6D=^=-ZtDtJ&k z9M+f6WEodl$?J_`!jH0WF7VulN}Qz-MD5aWC%9a$%qvJONc9AV$m4ra(yQpt1KMaK z${w_^kK3Zim{jkt4l;tO10=>q^vLr9tV7ooLFe=BBcu|qPc5wv%dVmAEo$ro(7!qt zUX>dBPbVZuAa*gg2v-G^_GJx#Xe0au>)|>;I};UE1|<6!`rMK|^!1eLqp!Sn1H}&d zY`c~GCsZ$YBC^LS-g<BOG_k_3`msmJi6o;_uv3qr)h&>+W7 z_cyZ??kDU+K9(wz6Rmc|xFo(nAHi0;`AFS}&I%@n9jomOQp=s7{eKlA(|0xZ1E|EyK2r0zcbu9Cv zAc-Uhl>!yr5?Ut4|EQ(Nh|Y`}_3bvGCxK|M9QIF17bGyeiN+Q&Ir}a4l>!JaK&Koj zasv)damHrca=6Petp|a7Zi0Ful6N$RM^XX4cl-_(L$m0Shb41x*?NFdm7|W>9SB#i zYw3rp)bcyj-UZg@?}v8uvCG!-1zAaWP@Z_XwSmqOff_`n0PyQFQ)!n0R|WP~`-gEb zFUB||7O~y1mJVDBjgCYm=2-}d4{`Eb$NlpsyLmn)>``XkzD9v|%3`oZH223Hi8G`< z_)$*X_8e?QaBU@B`l26!*9X`d`T+(nffphr;bbzW_5qj$c5(vrjCt^kpvnZU4^F{_ zf4j5bE<~h%ZQOEr@=wudZVeXHU1BXqF(CHgJ;fLDY@iJ9eh$ZTd{62kB?Yds&jn#h1DdW*m6D zz0Ozuki10lwlAa_)3;xSaofwWBwh=LNZlmv#TI!CTPT*{&gad5v%R2;0pQYLj5Plx1(hGi27g69UqKs|Ni2vU1!%k)$WqK^8#J@$GEs^l z;+|i#!s|agB1i$cybHmrGAWgf^*wqG--D0rRKFSJx3hNJ?0@bh=nHzCbr+OT24LN( z`3nFo5?vDR=j=6hlonkYYTYl|EzHIe-mZz2X-&d}q|oT2Jzb`)`vs*jTM4pRakzbG zp1ov;ra^DF6EWgvM*CyaC3d z1n)Mvi)!0zC)Mc3XT|b$j;dH9ZzidV7RFP(gF^&{nOA_ZTWI88gK%cmqSOG=g#ilLh`tjYsU1f?)HG1rEd83h1+^b6 z4aelzoxbth{Q>;({}u$WE=VQ-8CBTLa{_46Dj_aUzD~&LK-!;%NMW7VeOMO8*DDr0 zOikAAe+x7lp+uK_^qONkd)tr$3d?}I^Yjsa1?HDpki=3 z7(Pk@P1r>XoBAn{sJTyor$qBBEPMpxF2ECENY{pa?_|?J*OWSC2i6z18+bEwX~5#r zwt^~==vnM9v)ozh-%}gf%7|E(m(_&7eV`1bI8^mnx>%hj06!m2&*C~ z9gYyr9Q?STw=V{M5HJkcSG;je%77vsMAci?U~`s~@uvmv-Lv4wHFZcA0Ci|`F<>W@ zatL9&h?PRxINLyic4uh;ScvuBk`(%4z?7^NA%u7orRd{D++Xt%OK+zOUWH!g9)|=2 zMZ)m4CP8(YP%a{vX2;FJppsgZ>IZ0G?p~~WtHlrv!tD)Nv(DnFVL>mJg&HjJuyBMJ zvFXGt#vL0L`GsGvK#h3<@td|{)lDoN2VX#= z>DL*-d%8;NE`aC_%y8AgV2Y*?VrPzDrR`eh=+%A-UK4j#c&OX&9{1zQlJ2DhpHb>~ z)WjLDH4r_Fd=cKNJZyM~HsJfNUveJu>+MMEcq%H{>}Z^yTu$*vk;9Pk;5*5K$q@54 z@vc0dQctb)nQZGn`Xf+xWdlySOGKa-ff&l$tZ14<$oFWRb$XS|*Q zvpByajr&9Ujl_>AaD=R#Sz6~V!OdZ8yUxhvwtcIPV{|WoSrXx^0l4skTo_=%EE9mG z-;t~Gb_?0%yI`4j_Hpb${lPQ5u7a}XifFehd zd-k|pZMIlevMWzdu=dCvd@AuSHRO7%@*uxYySlfK+}Gg>2>Gqy(x!c)PC> znC<|P#$5z^CWI_d*0J71NfAj=<_LR?8sJbs6Yv?#gzUkACShG?0fuN6FFCX}W z4_YEN#j5ZSozP!_dwh6(IpBCMhdHUkYSlsK?H9<7SK4nMX}p}6J^C;| z-5MZOh#d1q+gcSG5!=MavA4w_iYj;s{}r7^;9`cN5j;K6opOHv2wclP3Zz6-j%!Hz zu=<#1_x&l!7Q^xVh`O?e@ZI7eH4cNg8-v#ZV)6sU(oOv(^@8~41lZf360-B0H_9=> zm`(+>rY5!j3jvCpBPkU$3S^&*a<0(^LukLTGbwP&buN8T=PlyeN@WG5w&mo;G}}%u zXTqfY8}HrKcI26_&L5sr{DN<-Q< z4Y8Q_L}t_>BWAO3Ce0u;ZuGNY-uqfgr3MU{IzGp^dLm-23Ab}#JS3TY;9X+AruybS zEP+YigWJxVxX90_PYDW>g>|~K9pj91=<3)q8&U_`3{Yvynmjz@_qs-C(GTJiA4S%! z!n%a~$)HEb2}QeCPkDz!>lJOcE#^rLhJv;bF!Bp+|Hqm#s19K^`^=kWQ`-~(M4QW* z^s7ULhSgsY5r>1m2i#K&O8Pyq@|?!jf9xcwnS`Z>LKe7YN$ThQ1*4Y2?URWlnI&VA z)HpW$?Op5#M@^jTu*i`Y0-5)cqej4~#gv2<=r6N%ld_{BBOSfuK$AQeZKx_}Imp7e ze5^t0{XJ1M$Y&$~o>bYxJb11jx92Eu14rP(l;@zkzX*ei2>c$97dSU!u}u)(v4M(T zU2?Idj^Hqq+mS(aHRW?=v2`1=d8CrLr@mtt{9)89iTiK}z!8GpB$UjZAdzMrTouUO zyom3wgQ|nmDn!5>0!d7(=fcf)l#ITG)JvMeobc~Zuru69NCe&Rm7UpdCIXw*o)-j~ zjk2q+*VKa$DFnneZ=Us?@!865RSXOdu#LDmXuNRjOaDrcIfHG_%uM4uD$Zv6e~C{j zz8F%17I4tnVYzcD4v+NC9LcjwJbY~$3_i2&|93JD2oY}Ma%$^S#D@TxDQzZ9RixGL znACdsHe4M^k(uRnhAx7CzJDtJn))&cn;xo7%M>OT}dFhYQ2 zr!tnnv)U(Ic;N}51Vt?UV$55wfCOV7 zHGVr>gJpr53IYR0((YJX|5YuQo@yY%Od0rfarV-j%8*F%hm>OM(M@YsCP6+&7V0HI zt-`r&QE{F;!eh<7;C#Q{HpT_Y1ju$$jkwG-c7>pJ8$`Zoey|Q%ZKha9SY3hP5f0Xp zPhAmE6FQbIds+HN6eCf$#XG)zrIM|ec5UkrS%U^Z3{(~%@(mvr8Vpa9xP6I}hUx9T zr&#cPD2&-|vmjE8*l?aMEmqbz6HKP2aFnq1op2ceEMA1+L267AO4vY*O+){x=TC{c zrLRT;xqH4_U|$e)8j{q}v{$U21ha6vN9h9(S34A97cHQW#8$N%#C1|=X&*os}j?9a@69=+xl$1+? zGU_*=lE=@UMYy@?xCdwODszFyo+ZdF8!d#$p~!1gLKwU#zqJKpk{ebvj%0?wpKbir zVqSP#@sP2{uHZ$c{l=w+iFZ}j|%nd>^6c24uVpcM7k_YCRn2}-KyBGF=~WAQ4B9h(P6e(!>uV(FV^DU?BIIe_ zVhiDPP63~U&(ydWKW2ws=I`?6+d+3;!=A==y}c>|Dd7iHfNE~Dn&!*r z-T`4@kw4$(B=^|_md?mFjgdjGt9{L>xU}t_SIbtj2%OZ?G*w%XocJc+8lmG*^%^Lb$U)2O+ppjQBYC3+H;Qd8hb}tZ)+8*K@T-YB4bO zEpzDZK(7}ACKbxWh;o~?`>#|~O!A=xYI>jS3TMAflq~3BYekW}RZ!m$4;xg9~ z#k&(OQH2^4+#w4@7}@6Dy_b{dOrrn2;_71KOL=ql@10fGE`QseFUNX|+Fg*o_5}D4 z))$|hOK%4UkiND`jzlj{9VXY!MMC$n?fDF$CgWUP{m|D{4YTPWgqvXJ(BaHZJ#$dZ zG(4%EfN?xIC0Q)MXO!N~9%Y_|S-qjMYI{&gqwOQ_-W_=~qLkG(xiiyI_t;xYh(7V~ zZ@3SOGg@g9;jaIAyu9Glo#iYAT<4<@Qw|A2nGP>wPJ5cUz2I!wL!4t77IS$JuQvfO zI_g03LW-C@JuhF;RRS0;zh#qRLMQHzUlovN2Su1N;vz+HUd>=r0@o8U)d%QEJqk9~ zgDLk+8v14Su%_>!>cYd?bSRWpm+7&Ye&dK9^#B6sNvKWh zfxxEKp=|e}3J&04K5^=*z&$N0;P$q`IS;T}?I`2XA9<*mR0@Atb{wSN=A^l!YF`cd z(_)pL>{`pz+gJ}7G<^BCP@fj;-74hx@l0qB!?p%Mkb`N(Gi_=0RWPile zg)1&ZUNNgKD6tNUC@q=zn#)}uUgoj#hmE4`TsKd!YJ);9jTqK$`To5PaZ6r!1}`Ck z5&5QTJvfJy3$z&KJ!~AAUJuiXL5&<5Se13x!%W!USvH2s9VHSBbM94Q%u2J?9+oad zPB)UhQ1k2gn#fyy4DJj?DbW*Pt;&;F$*V#N zV-Bx0i91=F#hlb=X5rkpgjf?WX=fFp1ZE}V9R_lw;=z++M-z(%n!sics5Oyd3Bd#< zpqc;pA#aP|B^XT*VT8!3G)fyqMRWv6FwF21RB|(hIPyVotp%woK{AY{>Y@rXT$*K} z9q|%8*TsixhVceKGUF=MQ>0zmUFs=u7ok|VRY$h46Fz2uk%i4v%65_lFzO-*Nem_1 zIe_GB^3;eieTN8>!u5ExVgPdyet2EzBZ3Mb#6y5}G!LdU*N?r5rC5*X2hsev>K{dC zc^wTBU&22AqZP27JhX`t8Sa~kN2wu!4lK-D&|3w{HWjr)*w=7}hQ!k9EnY)&^zBvl zeT$!QcgrT=Is0F;Ew}26<_$1H$mTi8GT{+UU6_cZVC;n1yf8ap%>#^NIMP^i7s2;l zTs9PROk|o_cZ9^jj|^G3CY1r0PSSo#t0D)ZDgEk=U?i8@7w5GjJ`Aw1ET4y)c}Q$I z2_k_E9F(ghECNF?Ed`YL(aw|THmh9i6c5YSnn%+ecfBlZTW!OQTzA@wRDEEn>h@0r zKNWulr%OeRDfD#^c8T}H3xt8uQry;p;@&CBueT=;2(2g)CS}|otHaIl>$XFeMm*Ry z!$|iA|3?I!oOiVNaI4>BP%?1ES@utfC37L(-kNKjBswb~T@ln}lmX%A!Alwz9N>yV zMDmd)7I;&I|5WttIbj>OMbDn~HHTp$-fLHx=IBi$B1cy%eGr@GcA&_n8mo6{Ky;>3 zNOpMPtPgsM}vA{@UW7(^&dHvleWL z$Rn|97_FwMA_c)Rld|V_n&2f9C+R1s8?}knUFL%a!Lq^}UauK=9tGMkI$sg|0qeGJ z0Hg!13a*jFY70d!U7lS}Ot%-t!i`zAGDjtTJX%6bmBMASt`6cbJW9&sQNfqd_AH@w zoG~fZR{@NA5P1~h?heuPgbLreGYqH#Mga@G)F9N3J1DfTeoRsn*_8tqFA3IiB0!lc z1W0gwBgk1$`&zwi@;3bB7KOTm;mQ?pm({UEWCOHzhS|46+@GgPtskO@_Dw|}2Jxoa zfP@vI()c|57+CE>+y-&RQS#S)-~7nj$5M46@|9o#V=^%ANv0?I3lasQ$s-S|?i@`) zrMuXrAsibN#?Ec~It1cFUx<&zTKEb4PM|=DZ~<8jeiu}6F-YXXH-N)-U=!NwID)Dw z(N0{z)K0ttHk}KnmvOLO3!Xv^db=lF2Vn4yJ`*1rzBxh*&!6SU!Gdt66f79j^t*)b zhygvsaUW2_C&r5|B2wV{&>-?e5m?&+GJHsE6DQUf3IV`fRH@zJW6rZqqMZxt`xR_E zfCsa!@&hzu9!DOnw&HvWl$=9Bl~rkX0Qc8iRmmjaIS(>^4>YrM2Ep1-;-W@qIw3-- zPBYRYoFA7iInJ!~nwY?v^DmL4#7eVpg;5I~tyZ#N*;*)mA}EC=5|oXQ6MpT!$NF*h z1%!}5_@3H2;r#f6dupIomOfPwIH|32pQ9dhVAC<>voHmFxJ^y70(1;ssYlcjMY>=f zh_vU5dY#bp?b7WzdJR^%p6C-+DRX-D9L|n1+vNllhUUxFceZMSkV8zMujE!m7$jEB zl&CL0s@0lP2$;7M_S9m0PIfWYTU7>e5qJ3zsOT4==Ig0bQ-pnG9WVtX7TFH^M9axb6P4smbI_P?U{|Uq2 zg9DPTI#|o@Qv2us$l6@K^w0H=&xw z!`-yGblw%aZ7Da&Wv{h*g8IO*vw#Eck+gjG)Z>g8%+Re5hoNidPS ztiF*JqEhCoPK@*|TVDz3_#UO$NfqV$t#}jdZ zD(U}Uta3wK$>ZX@dTnd#OP2N85Rp#7D`s5uR}gW}bDe{OgS;0Ydmc+&BP3)Ogf|CVd)1ZUy#Vk68DJRC(AzgT zF`=0!v=}U9><5**nKBQNp!uRQjJ&+?IOu{lUbnHof8W2P^yW<}w6`N{^UDTs5s!ov zd$#6qIx!^*d0iZUHsBriu3MuU+}zyO=H{*Mtj-QM?>xET-vStEzHE=j!rs2@bi45~ zbh5&E+i)JHZY&Pa>4wlY(xBc=t0Tqst&D-e>s2NWC>k0#9h3&ug)L1D=BjG&1`eKR z7Ps<{q1xn@Ra?J&`7#tLwUhTIOzXB!gnv)E(&px7Np2TKmYSa4`;ia28eCLucUZjV z?)cg2X(4+qdhcCkk9;6ySIK@Xh}p&rX!CrJX|$;EA~~53Sq7i1w9SiCMSTZa;4+ok zE5Og6ZN`yb{wYr*ci>hsk`(X+oVn`MirifGilyzTY7N_oa*m2!4q*wvanfH8ifqr+ zr#v~Mn%0m>sWJwqUw`ugbE?`tcZ1wUp+fyevzC@tTym-d6{+M76~@OmHRUSH+C_#1 z*QafF?7j*z9DjONC(g&qYhosaN0<8cEt{6EZl0KIDl5PO*6{Xxs!}I+>aWM&=Yw7M ztRe;U*nEV#22TerejFLi+s3XRHU|>YKoih=0QjY(CkB~TD8x*i?rRbIR_he2DRDIL zz1~k}h|;F}Q?R#=b~A44+y}$jMymwG7940`M4st@Wqe1!!AM@M-B)Sqp6qTioZ=u@ zu$?WZo3U}zgBUY2%91-NUm#zU@T7Kjk4ZoGO3wV9ERgmx=7do)UYl{YdT-+{ZK~?`|wK)?5B(DF?WH+-EDYK z&-%Rb*-V2+t>}xx57FyRK4-x5GYO>@^lC=-EVqICT&=CGnK?y^Q5jq>x%W0l3k}4M zqAqd9iM^e$J}hcJp-6Q(+(=5^Jl@q-iG$5LxYj;9EOJ*hm2l%2-CiFl(BR7y5)_R0 zz&7;b)>G&TLq$bJt!S)K`H!6)P9ol)o}R8?v#mxbVevRt;)2tC*3DR{Txa#cw?##% z-v{Ut2Z0uueIAgov9m9ih7>Qt&sxK1m`xDVH5D7KJG=9&f)Xw}3?#03-_mS8`#?)g za=M9igjFS-QtmpeM2foYulU5eD=TDta}4CKEm9kx5J@(Yotd64xFO-5I8nQVOul=D z!SKE_mc}gJAX>wcs{ZWsl<5uh9F5~6-Qruyln7dp%(1LOePq`l^YNlmXK=OSdVG!N zj~Z%vdMIc5tIvGuAv?~S6FCb}y3|r~cDlD^oMHtk937^dIx8Bdw8zRURHvAL4w^G{ zdUR2lb?zfw6iELsWLbZt{$O$-gU9Vcc*v1HTwBPIe+g4o>=$3p2FMX zOGtxo)_o2$Zs&2aA3*noe6u~z1t?krjyxJ#WFBo%^qn$}=^{R9UwklSaiG}M^UZ5K zdpAZ^q9gMbVoh=fR;7Mu42(y`$RW;Qd{;h(-XUAjI~*08H4aE!`_+M*6^_6y;pZU$ zSz5$#FGeRO@)!8ijOo!%h|j)-Kr`Fi4lBMCQZODfT}0AoB|weB)80@%?EIRF)6S>& zp{}fyl;|ASeZlRpcDrG3Y2O)Bqh5q%?}x6)$6~Q07Y*+)C9Z1Zq5}V&LP?TLZWe}! zhcMit?n`zq_NHK=t|VC|1RO56K`qE5+kr3XYNnv00zyG8GG#aT6o{r+877S{PnOfS zs3X<8h|fui0k_rK{qTBD0xb#c>AWkaKSkF&}UiR_;Hkn@94qxY{a} zF+wxgy7g3nwb<*@(-BZYJqA0DXC=j{)GefrLSZKm^welPK?*NzT!+({U^KkbN}Tzu z(-80R&MsW6Z1wRLEe~Cs<93xfbgRS|b9Qi0Bb9(7mEmeEO-@cuwX~TD!&e734>pSj zbk#0XqU#sM3cz&wcttF13>+cyOlVg;6QIv`+X7nS80M=}~DFdR(u;pa|z&%Jgs z5)Mn)EP~BHkmdtsBC2~x3)#6jlrPorg0lb$k|wY|wbj0R%E>75k^$U1eX>Bu+Do#q zC7!!yE>7e(r`y`8WYO_H78pe8@(&AVfHz$8@_v0iFU=P;=xRShAiYycCV(`a|X}Qu#TZh**lkO>3q3<&NaZM zuxvqVU~jp1FMp!et)8;Z`37DeLp=MPWd|@KoRu|4b`A(^IO1pxOCS>B>0%bVc!`Pj zx@!ZumhDS9SREcYS0L&`Oon7-upXg_W(X$~ROh9~mJidxdQW`qwt+1$rNs z8unOk0Oo778hq>G&<-PinU}{gJUVKjm7;H>1SsL>T%bn*M*z<8)t8n-fdPWT^9Pul zdHaF!y_Y2=yjLOA8I83So-grvJhvW~BU;a`geH2g^G9%sfksAvE#uuy=@QV{7cICVZrWJvF1oYf zt_P=I<`h3{2=32E+{+ISCoodtGncpXp+tu6ww^`|V@_8+m+{!^5wfBD31YCx7&98(a=bN zURmKp@Tm{&SO4=jGJzlLKw<6i-WyK`2L?#Oj>kuy$=jlEFLu5*JGpp2UXV7PZSbfb zN^#CX;TksWDM@T^C8++`%?{8wbst-PvJTMAz97AGkI`81Ov%8Zc=c^6$wiyx;4 z6jd+T%pT57JJ0r%ioRdNeX{fI6|;P}&LRGHN<=C zr0X50=rdlI9_y2dP8h`JG@pRr*<|7a$31!UH!9`2!L+DG#!{!vClxlMg*ooWv!v*u zTbIr(K1O|Ss^g77%~?gepOhROE95C!gfLN1WA@tat?624DSRUjhMj(S`V->-Vj7}z zlF(e0*Xrct(#O)yXW!OZfb+fRvA6t;fZ0PD9uUf zM4Y#1i+U+c%mz(PqGn1=1C^Ca^SL1nL1MQ!Ift?7-PKsg18o@?)~Vf3S91mVTPA>j zmPDUf$XgITr6a8nz3@ejj(NakJKLoOxFD&*&wWHlS$*VoSbdU}*_dBV zwKI=NWi<3E*_uVfsKZ;#uPSiCh`8lq@+|6X?u@9y?Gvu_+k^@ zdQ24_NQ7#e7feu;?NzQ5q0RG($}8j2C8xjR6Vc1l$x+lNC?HV6^;kMQ$1H(6&0m1= zXKpa9ud*71#CUagZ7K5lCDV~2kA9VL-Bcg0>`s60)AW$H9>*Gzz7`jfd^!Z=aD|5TZgC3AeD#`6T~Vw_gQ*aH0fC&;v$J7<hW7UzZXE{EaXpH| zop`4PPQNjEpVisPDL*ak26Jx5uIRhag;Ena1B2;Ix6;$)ug!sLhntiA5#Bi8yY?J) zU66ZAJ-SImW_KYHrXPVrKKEoX{1~aslNl*;Ub*QdBrN=HYqpWzLrzXkflc%U4%6sb zX%Ri62Vg{x)(Pr`Q=P(XSavLpxuX2TqI0r?ya7U^K3 zaif8YTBKRP=RjuqW1sV}l%ygEW%Iu<|5t3Ya}Q^OrPfg6904rCfgavhku8)q_PJW( zBLiW9Aiy(5(2KMlT@wrts2Cpv0+!{jmiWw&CeBuH3;Tax@bS3VKHJcq49^xM@`#A_ zDn9>We0@-#e?LEPE1XF=`ce4_h%ga_JJ#-G^!U-mT^PpT;CNVRhXM@;bsDbrqmTB& z4zu-Qgm*=ewtms9;c$qY{zyLYZuRHJx>;;0xmLdMV#9}q-w3DXoYxVJ)nY<5!bt^k zk&?;iaK$NIF$xpQwQ$1jsdrI|JCzEA-Jc3P321s$BHdP+6C<@O<$82YMZau1?aqnN zpHYruv9TDQec5=ZRktlvx)m!|N9<&(fKOUADDrmLIx*8`xTwQmMGpD47u2e1TN^&W z&rF#vwhJ#%S+{iioYa-H*Jh=XAm6l1|GgTDS>VR8tL?At8qcM>WEjtMS+%1MCp*y8 zzCnNg$Gc@VPjLxrmSmE)>kkD%opTk~J&*jF6}$JroD5yQ`CbAK^7Bo1lMvnQHh3G) z`v)l)7s<8|MV)sKo=%0_80p5f==JuZ@X(wLPDW^XT(2r84dmZW!aPh?3B_VI*!lXZ z`S$4<8+x`bs`n5zHZG0Lt#GcFY76O@Kg&>fK&}?O<)f@J$iP|~OOkwFOY_H8TDax& z+q6rtA5LU=BFv}6cd;MYz%*?T)&hPSS$NZL`h)z^(pK6}Nk|(xW~rZT3@|0aSqrtZ z*3(Vi7e6X4SgPDg9sjhnWDoItek@=lxSse-PV!)N-`5(X=2YAXou9I1xXYO#<$%>L zUe9}~_Ozzc{u|BSj|}Rmhf3CkH5M zFLj}ibkxHk=3n3U_o`|Yu@fC#BuBZEQ-}`ePw0T0I*hB5yj{sOko3za&$t{kTPu#9OpI^zZY7K_l6`3<%oVo};#{Yy2bK{M@?nlf+ z`8k-t!JVB3p~rUG;aPz@dI2K`9if-!7BX|X&>^G@&3jfc>lXCPlbECJ4f0OO931y6 z{3Xy{r#D_R(pu3-Zhn8fdr<9eBB8yqn(luw@@A#c3)=aEZU3#e(23X0{fD^s8s3hM z;0&bnU4~t6!1>|DwQqPnogQ{T4>;ZBB?jo9ZmG7kZC-;80=*#yfr$QcOH-3)rZSc$ zR`4r#d^V;CpL{^(|J4;^+_%Y9UcANGSj1P(0&^7;!e>g;*Bt35XK}=cUjF)cQ0;!{ zTH|Lg=yQjolg4JxgKhT)@$~SNTlDMJ0`$(gfy?vrZ%>!k6YjNHJ66LZ2q%B63M2Bj z_i|3%FTY0APCGT8ty`VB>vN0ILQ~dO-8@dp4UL>s_e@@#xVR-nbj2ZZfolWLH2Tqm zguObCD)FAZgJPqEnyt}5nD5#J{G%u$zj2UYc+FKqVA#5`Saba&9$rf?9zwC_vwCe) zV`CTgq@DJ3?f$*a$yWj|l=+7EhJ*;Xwh3un;R_}Gx$)WuFIr5y6xwhX!!^a!Hy)Ib zcK=@TM7RWUbC#-xG*i^zqHD_Xs8zp}t8!D6PAj);L*>-)4@K(qzZAC=F(>C|+o1!K zb5uF>IUn0hW7>EkY;T;23%YIWkFAxAnwGV}d&8WZ8K6c44LD zaxArduu;snZjLXhBz4dzi9`*bBUa!f!a9Jxt+>-bHtP}9@W3b=IzYJ^vVZ@S3Ap{e zyp-Uc%!QqmKTD4<9em{U1UHyM4lm2U|C6Oj`RymyxkLXCZXtp2_J9tT51};=uxI*I z3{dr7X`6&XF?45#lqX}AM>UlP$&`DCl)7S-+BB7#$&?z06l-apx85C0>nMZ?i*=^H z4p(7cw$b$H3FL+g>%T5wgJAfbppK2*Zi^?PmsVAL4e;~YESvY-;)E6z@*IN&Ciu>7>-d%O4n9+)+~-u;d+v90w9OP8I~ z0!;aHw%&VoW29BM`S0y+wYLU`gkOBLTm=4lws(<{#h61Pz&Px2Y)vd@R+hYxMy2|M z@a~vd`XTj)IgO+TsWg3v{ywQCA5{Y&@%hAOz-R*_2H(T}%>2&N-3G>_(BGelp)6r; z>6wEzQ@oKYy@J9W$+L{j0*`gcSrpq!2JZ$&6pew1aMQr1cDHjU@@(OY?nEr}>SL7G zrPRNXl<=FOrLR>4?-PDIiFGl)?kb$_ZBllq< zpseW=wQ`RrSk@Fle%8{q>}5?_8!>~(Z$_*Oa2XDa z?8JX(yD0(*`(L{Ma&h-)0~_Dl*ZsG#&j_PmC_h!ymgPRnsMR%jw&gqRzfcfoh5t}= zz0qiBL|4!$DRoamWSjB(np)fprKQFYpAqZ=TWQ6$GC%7jTDWnI*DgF!fe+4cX z`p^9yw_7ZqC9_$Y18=uU|8~^VY~Pq~)LzI*a5D@uq6*90=CwqHlG~Az&8TrGyR`Px zj?n3X8WCnim5e=Oi*h=*8 z@IRwMqcjy@q!adEzv2JY1y@&kG6=W>4DMj0>1qeFH@IS`n&LkJJi0a0t^okk0HyK% zAw3KX=|)J{GkYk{)%kZpPVr_Y8bDAN3<6RALy#2E1xQ2wl66KPZJr_!Hdl535y!!y zs@n*t+y=lQ{09yk=O@nJ5q?+VHerwrF;LwM-S5pm1sVe=;a~}~h5dEr{ZsS(X3svl z@d7&?IM9BkPrnop2X;FE09Uo!Tf$%t_Ryc-ekN1Dt3h6rFJ2Fbasu{X{sjSCZOHzP z@|RhDVg1o4cd^RN{tUQw|9=3y^WRz-%C*2i`w94;N#kGo{puTTB{7C_uP04c80 z;a^9S@*h$D$cl{2>sa3baaSO-zV-_OxMFzp6UE-a^%>0mPlO5@J~8nJ_RgTwfB-lB z`yp=qm#C!)5@x31fV@i4|AY`Io_B{DXhIu+^3Nvh+5JTL&#wA=C;erJUt52CM6Q>R zIRZKWUzC4W10>@B0$w5guQ1KQ($V%Q+{Ee`kF_1l;&+hW_YeKT30?iE%I~|0e(#Ro zS0{b}Ab$L@Eq`>c-;=3dC|GD{S5Eqm)arK~{u!eFk_CabFwlNk;$H#l@6!LA^8YS9 eh4nY-e+K|+ikMd$r$FRD$-o4Gp5Xuv2l@~6is~f* literal 0 HcmV?d00001 diff --git a/docs/Maui_IOSpreadsheet_Template.xlsx b/docs/Maui_IOSpreadsheet_Template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..53816a5233b83ee11b46e3f7434a966f5ae09a56 GIT binary patch literal 68661 zcmeFZWmuH$+BQsgHzFZDBS@EYch3-_bhngrHws91cStEnw{(MaNuz+okOJ?8_geS5 z@3q$RZSU{zdHFHQb{%uZaqP#w@8>piqNa$5LgT08=B>Fq;|H5*&H8q%;1R zljDOiyy$Ymi!TRG;y4f@J^_xL>s$w1-zQT^){ z6Zj0G*mo(I4i#ONdkPbUuj|-M%&(43r%O@?q@3_V$DR&5A66nVdZXik6N@>jQl>3- zi$}7Ga-GfSINGF^#$_+EFF)VYQNyc}kDs-)&_`@b!F%gG{iz-8Ch4irXo}M#>o^zl z!QL?YCKz{pj`Ky%V)D>w8-sO;*Hx8Y)-#JpTt!=a?Pu4~7dlIG4KkxTF&Du>+bF(z zc2W&21Ob=?(Y%Y9v~I`SfvC$Q-&h&NrY)yjY|i}vJl@|U!m0hOseOhaS=c~RF9SV` z2{g5VlbNkE+p~w)|JTg_i#zx)Td#;yR_SKP3%QV6>P++5_(&71mT8Zt@dhmfQR%?S znBczO?MbU}sI+7O0W`2scw^^iBpqhXF6>o|_o)scNgDlag^R+XOoz?w$IqxFgfBu` z>*&|y@OfuoGuI)WN>}Q(pJG_b=a_Sp2SgpI%oI^f)`jL@&NmyfZ<$zrmYp|}^oAzA z5&AXlZ=E+#uOK#8Mqvn>*vY=n8^LCPq{J$cTCPhnV#-^vReTv&Bgo0{9-TdI&hMY@ z7(-mv$JsphV%?h<2zrt}>b}iQUmH0sMBphZ`|+1*9_W-mJ9mfrnTy~~lR(nU7E60o z7n!y-uDON!1zkU=M6=TUblSVOmq}6A2k4Lg?4GAW-Lw=y_vj+Q!99XQgLk)O`=f#0 zI5^oDJ2==ph~ht+2_8^JAohRvPfJ3lLJvD$=uzMi-nRXen=A3W3+~e{eODjFNa`Jg1*CpVdw$ttiAzmeXdfSu>XNKX3Ed%t-hmqhYGYovW!cD@U!MeWF#C&+@+b zb<4K>KKy(t)8Y=ol86Dkpo^W{-QpsNbm7l|GR>eb2H|VeUn%A3t_{JjBJ?|G@Q(z` znehIJH>?P({ca+-Hc%-LBB2(uR1q)-c;5=TNo3_Vl+ll*S?ZJwV@gzHPQmT?S% zYmB66K5pS%5w-Mt&^Hp5PFLr0s_{iZD)1h30yFi5lG&w`+-Hxse45 z(93tYD*>z5he8T-^D*2j^ds?*)D?!a9|=aGvq9v&Cfsi-Pvy;@$v%F4c6=zmQ(e!Qa>gV^XEkIB^FIF`-Pp^f`|YcY%N?Kyp!T|cXBA!+7Io3J!m;c2soCE0|O zh#u6s;RU7Tst@k0+C$lIs5L$u=2ob|k)bso6hu6?NTZV2c8C)kny|?^)G@}VeBZTJ!1ujI{wTMv zNWAzOKj9uU8XZY@6u-h}uy(E)U@t%)g@vS&DcS<=Ru3m-ka((25!CG$kkud`^yRkt zS>`u+YdXT~@7(4SW-W=+;JayT5xpVJE(Uv-#X9(jOmr;|6As%{X9B6zNord`< z;hJ)wqQeh0=AF>9mvW(jMP=kI*~TT|scqV0?LM$yAWzt@fq`xdCR{&$kF(v)^$V?J zI(I~-joP)LD$%RkA>0WE)ppOTOD<9Uq+?OPiwRXx-+fdGcUd5_h%G3o9l1CgtdHk(f?C$+tEFvXAFmyN%tc;CecoIq z92fHL_#TfMUD+z9L28uTfdJm#3XxABw9E1r=E_q2%VQE ze$s2oQkqGVF8+P2hy;;TL4;qd$hVB4zFXKg&(gm<(_r>ooASVP)|WZ_8RQncF&%a= zK@T=rjYo~mBRhD#6?Ej(AaTak1J8un?Gr=5v}C~-*zEEng!VAtW*@i5t3`97>-x-fyG47H#p>{@$ek~x=B;QKY_=1E?r}fxOCqlr_U*!a z7juK|y~Fe&L!_(87L{a8A6H`MTI=UM`Y`!c=mvFEmB||!MppE?5V(JICv$ti~?3ttQ67w`!`Il{_bk&bV#4LjI3yDgg%X7wf=qGi>F)f~=)S}&Ct(g3?wxG6vF-k=ITjtn$x+^}g5GbxbmKN(cD^;m6MCi00-7aJ99QSEoYwvhkMVi| zOU7|BB>Odnc)TZD_&nK%CRkdn0 zQe&nE29>iewXfbHW|`M!5Zh41(%z>K<5}~4H07qv1*0}|=QY;F=rU~*N=valqRNF& z5BI@ZM^*VGDhXci>LU8+>%Yh|Qtz>K{Nm zk203kQ4+H%!27c??>(kd$$bNlg=2VokSK* zQ_eEe4@#Buh)!}k1{WQ!%Rz`l;$`Xfai8FW1T*~(owdY+YF6?SzK`sg_D)*atR1a< zo-;-%RykmBx!e9l%1BavV+*T0kr6VW8;af~t$U@xT7_Y8Y{Ok!x-uSYMzS{f!bb3G zMqfE>i9h^XOCP(=4-1XYs1n!II`<`Lski#Mq|+j+VJneqr$Jk|;#vliudq4g_~dSE z;BKe{E#u|OYp2ZxsYhP4=@|T!`IK@&G`~=5_RUA7HcB}`FjF&%RNn1Nb@wMqJvkn! zbC-y&ac0r5l#UeKS6dG1-ap|GS`i!W2+iA728gnhC=0y0OlSRZi|17t4+3rKRI-h@ z;}~vCgLi-Oi~12M%@NcZ$epm(ira8xT86Bp9gVMHn7gxDYY$1d!)(_jx`we>oAG!_ ztwoT3`moq6U0b5MFPc`)Hhp#~(mAnU*6VT?HCu@vt4){>`euU&LrEyznAJ?;K;9f- zqVirRB8%1+p7JxAs7bZgaQpt>6?Dh~{Yg6u9NZOf+$Q^%p>wu0Gjnlf`~45+gN#;W zsyi?7JAXJ*h28}zkb)d)Z6dhx-^Lp4mRXvOjh4dt>3_)zGs6? z;>YO#n{2Zn?&8cr@4lyVvv1qY?6uK_fx)ltdyn&-?K=ltgW2x~I3AyU+}mzkn_C4} z7QOiIo7!}Rg_f5p9ZI*Hoc-z+CbKUL&Z!O$XUj30Cq`f^rha~HZ|a(wmP5ieZV0H; zhla{eU7H2&-Rjzwy9RErJwFv5i+Z;*IO6$ zbOABQXUEs)%KO61*;_`=?LuFuF8FT4`gTY1>?reK|3dZqci5Gik2tFJo1LTdk&)ul zMDitkO8UFg%qPB;Z>hBmzB*|8*|pidGvH36ySyV=zF%|}tm(X1_uaXe>Ar?- zUyD{ft2aQWLcZ#~c7h#v-n>5D*}L8!(q32$ZCOP0@;=sX_T?}B$*EKle>%eBQIIXj zr)?gmW?Rv=xa#K_rW#Wee{01h!2bBIwy(!7!Vax)In=k=j`2n{XzuOq1+4qL$B^lM zXO$|vochC0sr-*wyA7uw)uK^&vl`#+@!@95+M;k&v%dT4rqq60Usrs3W$QOzf50Sj+~LSnE81nfzG&6{`yLBrSHUm1 z^ofPz6hHpty4#oj2SD*Z>(J4n((pX4K8vXiLuXvLmk1L{OUE0nvvT?|czcz?tI3X~ z)+f;@O1-U2v_oVr#HDyK73R&AO(p%I7PXt6jvgaDZehj^_HF)ldyMkM*YF!e2EG^c z=^GJO8&}T`Kse-12{UsnQa*VBrv!yt&Kp|{4)XHf0xJAkEO9Kx&hOZT1xKD*GRpE= zq*UrNCGpm{L~PO5uw4Own0 zoF0*n1Vj!tlmbVZQ=2k1k(I(oy1flyqL2K?RICNxB+D#ura7)zi`8YXO=O%)et8dC zC1j61yeYgcgYmH<{&m9ExABV_yWxc6Z#@%_!S1Y4N_mtGZpZAKfjvRWTJW`w2gh7rgEJe$cKI9qr559sDTkhsycv zl+Wqvq3XTRO|jdfPuw>*$x9N8cM=qLQuntl%{NnZt%`#6NAb5fi$nR%JWfLQtA3EMHT(njr)0B!GS!QL(2_o>oL( zqoa?=OxGG=h;sgTixeNCMUi+Ijres$i38m0;^5i<_bM{zl6Wd#!`iBF0U@-Qojdl<`N3Qsweu=0s} z3?m~1)M?JkPbm{^k6I#z!Y?AWB#o~|bOXP~L~Lo+&g}F!ZL=g0@(W$#=7LtjaGpeZ z5fcBXm{$$Vf^OrL4c2mLhvcz~y|!O&+~?5FRC3vO(GSIa;zPpB%cpG(3Y<8BU{A9n z3Fi@RNW8~h3l_B`mega(ly4@xQpX%hN=LtPa4#KORF$bUrW{K5OsuaH(nN}jxGcbe z3EL3kUA1ozNlFFjMjmZ}e96*L_U7@I&dl*VXqi~l3YI;&E+&|$hm{nn+*iKJ%114r z=Lw^NdLr~`s~HSu=NvWO3ia0+I-?ndKWNfUGk0mO<5N&}#P`=qF@U@a;=&^IEkE$P zdk(yM&en}Omf0`8(`8@hPW4d3?(sJ55D(F$lLyPAvD6k!i@0I)&BkhEvScP3 zY3$0!27(y3q&Prq;3v}Y+=_#9&?^zmLWRZZ{y2>&Q_?gWIfhcgOsx1onZHKT^~Z6# zN$-n6r|r6F6&0YtuPi^%@M!)qC|NiS@;}!g7MWoouiH#JqvWE7oG4v*q5}-6Rx01( zqHkF&k@-REPO~`Iz}sUgl@_8;lxwX1b2)ty#J8os-Xl+6CM^*uos^)!kqM)8OwN=W zPDp-0)?ns#Z-HT?ynwpWV3dMf>S=_MLiU=FWSoZJ1j>7cLNT}8M#dtSJSY87`Nq1u z6e1-K5L2YQhdMe)b74m=cayXr&4(Cv5DZ00Y~vme*~Wl8r+fya19FJPAcL&=7DyjN z9}+l7)GGk_aG11n3|_4#)Y64SKIB7T|s*o}ywt9g~ z$@My^$`o?2futnwQXJZvOiJy}*BEJgAmVOh%b4C44Yjq*@L0csIB*|sAtbg)De=mS6ku))f zv(WlknOc_uL=%enQ4;_}lLqbxPYGoAH+aax!~ZgBk=97A1ol&PhHPOaT{HF4%pVfY z*k$zEx$#DjaWn{fZ%GET%$77miBe^nWXK~epbX?+RdhqpOSV-=7i4uOpo(|K-II2t zQ>i6V?)%(<(QGZZ4C4*@L{rCk1kbqxStw1kLm*tx__EAe3>Tu-XCJjE0}QSQ%*+)~ zABm$D@w;U(7i~ztKiW0bT6w>u`F`x}tEmZ(PuSpb^|PjNec3)c*_#Q~J}cwrqeK(O zdEq!ww5zQyo{>Mv!CC@!(GVA)(t9O?b(kahj$O)~vP~F{`o@p}N)Ht}H6vVOh!yc+ zef|ImjwBmcGt@k89BZpoqOeGv0z#7b;;L!qTtLFD zZx4Yqg15{7-UiU|*D@C2015XgQ!6!{9@POLI<*Gi9y|cuH6lg||6?d|2~J#&F+eO|`|Q7r@DxnbKQvRpc>KR;PGWGnKtQ7e z%1}yQ^w6YRHR-RNu}kSSJBQdomPmhebUeTm8bIMdCfYp3ceIv*Ccv0leGg5iKtTLF zH~Zyffiy99;GcZ;bJ+|3GN<@?gPXDf2H8hVRk#(aw70|4)d0V9ePEz(t$=3AH$D<76InLrDE+8r@j!&7<|ote zV4e5HXT|Y<3C39ZM~iZR3<6IR5qHAvnNI-m%d_o0UZB4&pej^rSm5)*#=uQpaRMR;djYx44nQ>uMYHp#yFY=dv8GoGb7Lg z1xlG|bRpN!I0fSez8^GMhW{TV%4~4@F({!bE@5!~06q!}Nz^oV~P7v z=it>4Kzik~B$&?PlTQld-Uy>>%&{;cM==w&0943IxGgN*^vOm8Y}OzSg!?>@0LYa; zX>^F@kJ{0=en}!=5hlJ8(tOWn{p^#tY4tE6%cShYyX`YWGLQI$NmtIdy~K;^nR~oZ zHDXeAQFJw;FFXg2Jc@p)Q0I2iMoF`JW}c{rOLsn41|4=hd{*{eot8qRC=f4KghwgTwrf^tU{#QShje};tRiw|RSX3xM?^lz39Q1HtOX6Ywjex@L{L zQ=#KagwM_cx|V^G%xTZvRlByP{ROd9{1z4`lPyRi(0YGj! z6LqFptZ;QrYfARZFh_WFAWVQ2`TrVDH}@gzx5@fjrGAe_tV6OdRv*SvtK(8b3E+di z5jhjfBtXV60QBV>D}#<_B@1>z+5^nWssWmz3KA&K3{z&^K zJvDu|kvVM_KSO{R8YDjb#$YSAl-$`U^o2(7yp&nyS9{xX+96HS2lG@Mx%IFyjC^7v z6wSxx0JuV$hKxDfpr|U4Hp|~T3u*sjXH0{NswqbFXYq96Vc$xf>F12NzV)UnpCLw! zExAcdlbW49zF|?Z(dNg6)>{Yle}f=P0w8zXH{EW*igQX!N#K%J|B@8`ij73m#+-2# z-&#%JYIkQqoP z;3gljU>pKU_K((?0CF>7Y(4UrWI6{yu`b)uC~+$<>C0hwy3Oa3f{(zEjX6x6$VDkp z4GE4Mz2?!Fk!qdNRf&}zF_;8Ry?I)n9{?jChxz<(Eo;mbhAdsuF}VxP6*dM&#Bm`_ zd-{2Iu@#^ec2X=U#{keaF!M{LPpKP$V2D#{Sz6KWz^`S%c#iUuzyGuVZdk;H0U_7`fd*(DpF$C2k)x*f(P)f&+rl}WeNtrMAeipm?Z^c0t_&- zlu8Pd7CA}2IG`k%NSySD(_aJd#ZCM2cZ2{JX{Mo zwL&mXk~AClvX3r#Et{$W8J4ldQ$0eNAQ_$s(z!9tJl`zgPcT|dJw91*3}9S5z)OIt zua~ww9CIL6uMc>mwpsP^41Wmj=%hq))&0_Kj^?^OujehnN|q-YJ}1|DWl4=JS&Xv2 zxMbf<7NT#gk|`tgjxGC2s5?UHF)WW=+8hTtQWc6`l0Uo95c9%N?ESF7o*8q4BGH^Z z88SBlveIjayP`ZKrHeBR0l8QzSNp=P6P%+4(4Rgz@lV0G2#*2~ipWA55^~r-nc^T@ zD}_i@?j8g}#c~N0Nf(}~cO0=}SR!Gh7!v_N?@EXfAYy(>jNzJD{;GN~Z+yn@KVtHV zpX+ayZ7{E|P56o<6M?OPnIaHcar6CUa{NIu>#PjS%#G&xU2`yu+VR;ZBozo4#5}Jo ztEAxDyP0$FnGGY=0V2lOe-_m>M~rcM*X!0vD=8t0)d)B~n#(I}<&$41I}Bgq5*k$K zsts*9NE|>N5*OW@jXB~$>U9Atxu(23g^70wZ@y02Bjo1F4A8|y;9^=|mUw1gc8s7=htpHfAyGSE2!8bAhwij4Ks~Ya1BDM|{jt_{!X<{k=E!X7FjX~lugqG1)FOAXsIZJ1m&y#9$sHl!6fkkJY7KtHg85_b7*ncJ&^8B*C#h?h+o)T(|7YY7B2kk6M|jICAzTJi!W((KCjt z4#rD&O?>KoP9Tn1MA@lIqi&27Zc>{77?LItp4opK_jVHsv1rj`i}SC}h1*o_)b@i* zMNdFBr63TKM?y|TE@+n!tHSXa*6n&q9Da7F_L&@IQwkxruGfDKg4CZd+=#Wgim8AY z6`lHszg35rfe(f*wl5R~SJQD#-Xuk?!ePJw>Te{64{oEUnM0y+!0_V56E89!MUddI zvy}Cp#-bHtL8O6>;nR>n;1sg3*O%YINf;2|*&@X9g$Pr?nSwW2Xmr=;#Ll$Y(eQ@g z6L-v5|7@%Zoo_G*)=fCg;{$`>u z!9qP<5*L#u+7kv{i%&QZSL6}!FDHipqSJEuwtU%( zMtL!76apHOX*dOfSZ6K-G#`1fYIL!chXTjzij{C7)A)oDBjc6hiIpMHh_IBb=Oe(R zn)e#lbWgezjubR{n5C6Qrp2G1>R~{Sw&-qT`dM^zITv5aXC15r&uSppYIvYNfVdIO z)|~tLEPI;`Lbs0oN29D39nUu>gNYG?MPV~u7o@GrrDhhS;@ivgOVAH=F{YNn-t})oK=W_QM5~p3GO%rlMk6c0S0J-$EYn2){@NVc zTGeUzyp)i1{8~Ku+UkgeePwCT3{gL@p$uXg=qVvh5_~KH-ov&vWHaFakkEwxfl)BR zZ`37>VyJ1%gzy<5JcR8PJKC2m$@#CDBjHK?flp%iJl#xG(?<}ftcSW*8j(1FWY=AE zJj_8l%RGl}8Zk#8m$c|;yzu?$k#OqC9%4n}@GnZRB)xTzMZk6h)FjhC$bH?f=r? z&pw<6cEy~VHn7D;ai*7re`Xgg7zBgYNa#55~;{;+*fK@De>n&844qO!)gEC2YrwRT@hw4 z25RC`B2=KQ61V=43!c=!$_3EQk&7(Ukk&w4pCksvY`7XM|7j;he;qYM=8=%Ur9br> zFD4qa3eF|r#EAHk9_Brf&I3c5n%!4z!=kE(YX<(}! z4wRN>?JPT!Hq=F~26IfDnE}w>3hhwf^I1oqLDLDR*O{Bne?1L*L5oR#%K{3tB)f{` z!Om@}yKyQwp?Ysd++PNc0010nn?|-C>U$!x7cLC*kvE@HqnB~OXuFP*y7@5laLBn~uceeIcjD12iZ5{*R^d`&5u+NxEkr$8|_jZbHzT_B(m z+=SE~^%`1fd$SRQ)PES<5g_Trh7V$ToUcLpZ^fBz1d8JiNR8sK zvb!$RWr=j+r5s<#aXfua+^olS8$Go_Uszh#6xFWzn}mr3H~Nq z%n=DpAMsoHrGB|gbUVajI#4fAIz(loUE^%9LqaK?u+|^pJJ-*cCgBb$b%rI) z7r+^l!!R5p!=1AOS+e49bnt?=Kz8 zguO{+M$DzY7EqHAe2)~2jSPrf+qFfC54zd2z@IoYpqXk4&e=O~kQv6X~t&yGG=8#pzQ!870O5f=YeCP2tI`A-&6xP5ql3!PS=bwK*uU z7_SkK_~`s;;`|K>{aZ@WVnH%>{%VC_F|gQgNiOt5=m~rzW_1z>G_b4e@cPbwRn1X?4}NfFT5(z5PV9cZ2mmUvcSERx!o59D<~ zO=n6eL#T$tw9vy@Fu@Y4tCq6Pg!VEif38osrZ+IXB`pLoX$y+c<>V#*|04BB=bbL+N$zl=~%Cr!f+a&nNN0s zgC`Toq`UQDap|_xjU(KxibIX$+Z$4WF?GG(bC90CgqpRf$5WJtY+3Ub7%kRa-}!>l zOBL9AP@(MVNZF>xn1Lsksr#g*Y(AoN-t1%peaU<4`wZ>+BV= zlO<9No;z}J>OG0;Hzcf^Ntf`(k;($8Xo_&tLMj8tq>67e+2T!3klB>QuV|j$1P+(* zX;!Dkd>CsNw&mkvO20`b9s%jc8}J^!OWPhL%(9Iy?Yc-agGU@eha|e#gczXhSu*fO z?)AtBj@5tGON_AG$+R_UQu9&>!AcAWW#uPk#PWCP#*qw(oilwWJ04_CFNp5~pS%g{82xZsUb-{pif zZOZ%>H4uiPe#_oXod0+`;MS%6l>mz#JgEV%A)EA|eUKSBAPk#2k`(U*p1sXVi@9YF0 zfQC@Fh^C%Cg@0g7vuL=Q92B**pud?TjKV{ymzM*r6wYzJ`854-a;(lsa!JEi&H*4l z2IQfZHj^w`GYMB+CU^HC=LXm=3JkG_T4_(7^TaozIUQv~@C!7Q7Lgtn{NW+* zz!~EDZ^s!(B0wm7#59S<0Iy-?Y}P)9Hx@_EIa@i44nUJ-)Cj@8f7>-MTJ91= zQ>l;)p@$PrW9YFm$AcGl#sf|`fpY(ppQ18ACK^HTd)L9gZO#%fW(i!vO1Az9mC9-| zQt%z1Jb-mA8)TtLNXLj(;P_p{B!S=L9Lc530jTX?Ebf1gv--DE|1BlIOZWhZ$;W>a zgg+S8g`rXv{&m@3IGM{9B$OVpA#OEs0&Yrx>slWyLMi`+f+^(Ed5`LM<*v* z75Te*oU(tIRPn!?)G|&?w5=ipU>88&BNt?+0^_k`^e=Tg9*W!)rF4dJ#O*HkotUHE zxDEf%&tZgk<(|MDAP-fOg5$^at8?7gs*UFLW5IqbNF%ZrRe)@UKk&(fA?&)(_Wm3vM6_0 z92uB_x%sr49GQ6t2#DlcR0?~|Ejfq+&p&ag#*7V@vOm&yuxI;Fubr;P-In#Zo%dZR zlY{I%PMd*Hv+k;&Zo9sLf#{D6hqh$`<0fTBo%LO)bBpa;3axJ6g~#nf^Q(N^;6+x4 zpJL8KG4`(S(lhI|8w}j2?iLSMCtbXJuZ|aCo)$N=%hy-W1{%uC7sJNBA1y9tMja(P zJhOD<<~Ta6;=RybZ2vjCZST{*V1Ech(OVc^+L3IKoy>%;e$ZxHX}$loIZ}MM(RV?e z?Y*z>>+N$Lyx^y=;&;7QY~iIZZPgK-XUUy#kT)^zLP0gs{C=W^f^0;eWR+}Y{x~j{ z_yCjDZlZ16p!-Hc!tLC>77`(q|75f~AM|9AFRkx=VRMD0#yG)Cq-5||wcxgTQFpT@ zLNdxv_ZF8jye}qHQvyO+1TD849*@_^88W5o>RytKp7G|iB zpxbgkj@(;cPcS^B9Nl1^@_LKLwj7`rIE!TeQ54C`-B01?BplVqtk4hsN4UtapY95m z=P^64{YM53dbBERw;7ax1$HG}`wHpR)Tbs>VaF5)+ugfU^(EOmJd=2u#CwW%y#5L# zE-36NqzgolQBkR&&#$Zt5&X!*s(AU;S8iB^GzRsl7SAcmEj3)d1Ah#n;>8WAbcIge zupV#dMFG9B#eLLEny(zE2vNW~rEHHJsZhUW)F#LBI3!~zhI;gk{rr#+Ti8ZTS+~uj zKjH2>Oz>4OtFM-IsBSya&d303kGk{xIN~eI3nL+yJ!?}T1|vmn6VGUv$$V1b3r)OW zAC3Y)q{X&PUSC>!eLwPdJ7FxwF7I~3Y723-BQ*kbdWXGK?=LJ#2P_obO$&HzBuYQ>jLMII zk%Yb5{gQ?>#Ael!N*)Jb4*ZUBW!1+dfgUK+^jq1on^I=t+_m*gVy5Kd$?#<4{NK#w3{r#0| zYm?4YAIFWVym#aLxU9})kccR!h-hWQ>Y>{%VFr&+n~6w;XPcKSwKZ^+sJ>ayVBqe} zY3G=$m#o2jmNH3Q?=MGV`}ivppZ3=0sucYPy|??Sr@E83$HYD|F8AAAzL!$eaIHRb zZSFGdZ`zjQ8}9kC4~|rEibvSkcB;<(1lUCxPrGjoaB!JM%DZQ8qOR`l?pK$ue4Tx6 z9KBC(uMTGq&JW!kj@EyDzcz>cJlo#?<$GG)xFjOHy7a^D8C%uptQTMTX)EmF6b7Su zwembqw94M9vGL0H*ZP6qk6%rVIWe`nmTm2?{BklI?(fD_KT@1$Z^sKfqViqnJiKje zyidP<{ImD|;co=|=d~f?sxqNg;K@_q;v?OEeChd*yORI<>htfLlEE<}7+vgm!4EeC z&+R8Y@!l8dOZ^1H;FC;mg6s%tkBc1~o&^T3*;yptninmI7OO9TPS!F*HAras$sJH< ztv+-2&5$55xsb>n$#pAX-FP;ZjB*fXql1LJX9ZLS%hpw4a zqX|DkEU584Z?5EW!2dc5q@pD$G*2MK753v-_Q9eXyUWjQ-uH^4ED7%}`$sqlOl0MQ z5{@X_!!)-0bM_T{pcVi94xcc}N7MhS-E;kUPxSA**YE;%-x|IK-A7~@I7eNiH{DoW zOpnT;abKJ_Yfmjr>l2Egkfv&#s!l>ibNaG40eduhVDt&O6FswcKydOWeQ1&Xvob>E zloLW+6T|nQXdWz3NT!A@O4|EE+)dy^$k$&I%zi+{oIA51xk>s`LaQg`0%)l27hE<${B60%xC9Zx z^oW}h!4123QQDp@-KGts{%%h&ILS74O`<)}nrYqzNJ~6Iq!X$P?tdAGmlyvi2HD7B z4z~PZ=fX_Gr~fmKvvTFe&U5zd=WUAun2J%nDN)GpL+7;I*8&+s8hIG2H7apTM!Bu= zeDbi4H3!*~ijqkb=|m=wZ4#fo4Y98xL=xsJalfU0jP4{thS_HSbd`x0+X;sZGkRrf z!XG0?D3D|Ju+fgfWAE!*Ai`P1&(s|$%I90`+w59-mC!nq*kzl zE@{4*#pw@f(pSG3HLT*%xo+8HDwNamsE?evNyJ7FeWv8)apr0WzPdOf=q zq3;x$6Or#gHJ)9H2ICUq4iX~9Ij-8r9_=6VrFA)&Wn9TIWeZGg7yR~ zGdCbb4;JciCin@rGHBRXYri_)|FD!o;QPwhUcu!%fq`;_{wrf61$S|}l7<&3DyHP; zzL{GpiXD4T8Crb1vkO6l)4GSs5i*RzDFofm`xF#AYJ~L&xWApxF;0aqX{IaDxsBOz zzU!}8G=1dT{&9d?$j>fb;6`6j&a!)-ytGWbU9MFRMmZQ@Ko!@Fu%9$O8GNX`o9jRN z@+qMwcP9(*%B8W-r(BFOyfL}BiPyKwC^ZnH= z$;)PKpR1oi0bV?0mn*QfFOuUe_8y3jT9Y&(i@|uNeLTfhEc!CtzXrq z7sDNR_sExJ45S})YJIms@j17MbK5Y>7i^MwqQG|pTzmdcdM95`u(d2MW6o+{iv<;UeWD^kDI@QxTb;e z&Sl2fjvybdsBL*%MF_9PjKI65Ck%PpWw9{YVo^Wu{g;}?EajM5WiK|*bjhxb&hC~S z^UvaSF^tghtmCH&KaJ3!VHre5rhc%NdKcd~NnCe16V<`}qPmL$YK9kPL;z9x`cax} zx52RF>ZKD0)EgSHP*3wBVYth$F5%sLKJ*u>Bk>gQv1m7R2F{pK(JEV*nSq$vTX$Na zP8WS;v83;kYVkg!Q#;PaYTjv8b`M=_z5qY2R~q-85k z6B#AQ6*FeD6hjUk28TuYq_1}Rn8dRrl1UMXHChhltl}=mf{w;O#n0e?aJJHdr}RBB zcFvD9Ypvj?4q?#8`qCUUmxDUc1BZpwhET^93gcypFAjA-4p?dqS@KO3O|oB6nLNJV z@#NpB>T5#XbB!+`WgI=aH%78U^R6x)uANXT#}-$oBPlZaAe|>pZMC7|zEKcMBZih6 z;4U2LInS;`C+}U%-BvK&E&@&ak$_i&sNqz`xm@ahBhH|p|LXiWPD50P206!h4XJ_6 z(MiKmA-YQb1{F!w+gr^Ex*@?aFF#3GcQ$Ri0Pba)yPYL+lS|QM6Pijk%uo|!9|b98 z5D|GZc^(y2BJI7Yba{;U*$KWwUfp~zwTYs@!i@d(WYqq=v@4S^)SZj|59<`B zE`>&BP z^8&LSPkd4w!)7}%&Y%^Y^Fmaeep12f(3fkkYT~k~;k0ZIv`uamv>v(njhh-}=u2m& zn?82CJ|twanv*4=tq1a;^0UH{kqqMVv=IwFCClR-p;!~Wys;OydI zYv%m>PYo=O+0$veq5SmmZ$a#Y);h*t_)Wxehc7aIi6TQ;KsQ%Zm*!cgEmdRCOM{;4 zZo;304@hp3fFctZ5}AFd)9u#Mb#)4Kd-aM(1upKMS%)(DHD*FHR|mIXE*zoS7vc@JD2{h==AU! zYjyO?O@=A&i#tze*oZqv^P`!mQ!AdzBdwi%H}ee#zm^QPr2JDbF6`^&guCDsX9ctbILqsNZ@zmU-+0gc zYW{V2+c&E6;eO@H4zl&ew&9H%r#>XgtavncfR1ZK@N}Z$rQf%WlC&(g;*s?D3ELOT zm8<%c4UyZoJLXf~b|b}}BVu2>=dZHvDBAuHd+z}i#quRf$TL99Kj{ zKtOU5P>`^sm7Eqy!Zc~ zd%knt%&*^&sI)W4oNq%L z6tYBaxM}-%HfQ!?Ci*<`{SajzL)k)7Hc;Ii0c#Z@-o);aNjQJF-#OoJ!0shH6eB%yVDI)CqYg=X~pVaRv6XgyW=({B)-@VX*Ys%~S z&eqS@{2DW1rXC^0qKvtK9{u$@#wlI9lIZzw6jIlBQ_tBA6^S=fHG4OG5MB8aDLKjx zEo8cz5=9G|(uFs}zGYlqSFtfjgU$0$Zc7Ru?qO?6wNStWKoRA&EOR?rD!DgqZnaMI zJeRR?Lm8qaAA)~ELDArzHk@9Qh`ArozAqsY-qfe{Bwjvz|Iq0$O3ROZQ*fpZFZ8_Y z{ahNnyoHDnL^AJr>@@tafi=Dnznls+=?P}6uK5vNy+B*p@QqA2m6o{Pxs${!H#Q_n zOg{TsM>(Kkqiy}11WtZwSlv@_sk%qM$lGX6xhCB<%#&;>@g{Y@wqU8ATTQv+z8z#0(^}nR?Xix%xWa`kQZ5kXws>y6O zVqpu&IEouI2`|e`O>bE{~Xvnl%5Mq3z*soDVd3oQnJQIRRF<-HJ zYt6oIDU`9>?XFOa{Jb>r z?F7$?C;4;n^L^+@h70Lj!b)DmO*Jw(>)7^+da?FoUIa0OiD5iqJ*yg1VbzV^)C;1o z*WVrMnO`ib-CuC>w-t{r zZg^q(*nEx2C#wpK0J?d`M=0;OdbUeYDY3PuMv5D9hPyszQ;OPi2-D53h1_jgc=bh_ z-5jDJ`IM)cX=q`iiCs~tdsNQrxgq4>Z~L&d@fgNsEjlJ)GU7AmC&)~~`rO?m#-Wr& z-L1SmrQu*(lGbm#a|0@iG_)O7KoC~@h{y)n3L}}SCvN=4*rDVvY&Q|%5+HDkxW(8W^%lT7|{NLq}`dyCXfZqik zL~at>)%L~4P;it48>Efyg~4+uNZ*Scb^sY4$n7V(RzUfEpWjUm-L|fPV$|$})nb@0 zqAnnxK|i5dN;-ZDlCrpDF=0sgeec^4+h4ABK{kdq-axQH?x>l9NT;8O@6Bz)mM8) zKj}Nxxb9@P7+F<6mWyFTx?e)(CEMxm#>lz%t(A~d+s5k=xy>HQB4j_CS-2LFEs|8LO3 zI~Ji02abBNu8253y|X~cv-rGU^5Jm>3V}w(_t0YgXOwUlw7`lrK!NWpnskzgbO zQ~S3=$d9MwZ|%Se#mWb?CXB0=njPfiHtm@uUrKQ16r~ULR)=Bu@gx%`Z=P>56ykQ( z8K0b>Z!E~#7a1vCSTK}Z>CqAM8I;y* z6PrG)&z@ZlP~5GU>$O~Ely@`mTDf^?KgBZ%-^F;YdL}w1P|lG_Q8>wbs8=rbRDQIf zYQI-k!*|Qq(0<#V@wwhgrgfa*-BJj#VDQR;lT*#id;f#a~0LuM? zQ}>DdF&v9Ly8Vb6_YZSOQ~e5IXy!-G5jD%xs!-!nYmWY0+b;F;jVs?ml9$C8$EIVy z`R+TpEfH_;h0YCChmQ0l#;w~Bxq<@Nck-eMvyOs}_w-i3uho}U|1jrSXRgC(o}BJp ziH_UrLCA<0)U{}uiiJr?C?Ol_E~E_kl9yg3`wXXJt``R@!Tqs50Th*n_ri1CuJXtM z@?2;4eeX=u$0w;>w}%z@TxS(OJ+vs3dwpyC)qP3v?swrHmQ7W!Z&{nYJuUJzp548J zp~``FyexdhvT6JEtq`-fsv=)A*_S^s_}`*cej9$;qKWDCEiJRRd?H_;vM+yR@V`T= zTo#^T(WL+SmXO(7R*|o?fB#UMy`_77i`k-y_iec9E!y!-%RaeKv-f%^cKCoZ?YB)B z%ba2&owi17VENH2_tUa1`@cxSTvBCZ^tn@o7#W{M3F>I@I<|8fK7QY0f|#+@p{ z$e0`@sH>5amp$75_@s}vU>l%EovbhGnJb}4XmEQLH;X*-2klIzR8< zL;K43D5WZ%?oN+)($|vC&v`M>_j$o(_FqG*cBf}L=^IGr=f4;j_`Cp{-IVbOPF4K3 z&^?!=owHs@fBDSiGJ8zM=Wwbbb$9xGr+*LK|CtLm`&h>3YN{e%cluMOo@>(1xi6&u zE%bF6AHh^b*6#F2PCZw^CtY7i_kDihGW)NgkESaA|M7{HPu=K*JIO7?ZZ^lJeMTm@M9G1lyeioQZkI=0G#_kP?QW~dW@nz z0D~mMcpszarskRsK&r=fz!c{P0_{(bW{R_kpeY%~^4N}MD&+$~Kr)Q}vE88qko^{s zK{AZ?B>K=}JF0d#@V8IzW)qOAc2a$SPQzvI)-gQ@B_ma!cPxfAVzD(# zMXJEy7z0}bLtEArsRF}eF>DbR+On=o6&N35V2{vg%QBHFFg+H-9^u-SbyKRq{1^jA zL`>UD`?3NH(F+{0|2BB)0!MUATeiJdfyKWJ=Gfy4EL1LVB*e7+yWpV<$@gLevh3*# zEdFKirTwD)wy~KS#&N$IRrndCL{mW{h_xaOQs}=b*Y5145j^{|hZr8wxNTeUaca0}BYf)ZxkG zB?kFK+1Xjz*qc+^TyT=(5nF4NDDCK4Fm15#RP(S>BXw20`P5D4vC%Zqa-_6ZU))n@ zBm+O`WQ+3OD5ZHbp>Qzc>DQR3S!v;)oHCdH9eWp7hUta+fGgI>)k!eZjEtLci?ug< zqKi4_QXm1$Tujhc3DDO}L7Qb0dtYqHt0`y+G?#{GTYP-mf9WU-7{ z*le&lNwtt}D6j@|1@LKq@pot#@KLc1@?{fQEb5(evCeO?sD7P@s6>t z_rcgA)A`#`oH5&vL!*@!z!9u>4k0r2p`%HC+ayxTxpG z8r;s_edY6nR&Tj<`Nq4Aa0xZi#Ouy@Sr1F|6zVyW%O#7-f)vNf+Ebs)(*huLxigxT zqQib|;&c+PPa|rTRBK$U^=aTkwoI9d7_#iCs#xc$^J6<($)<;P4dv6qV^Q6%Up;xu zM8}=m2~MiMS~=y|SHi_qmV-8J5_HaU6Zd>gcgr0bU%iL)(3x|31o<_Uep;%X&AlBP zTz-2fQB1o_fm7aHB8s?ZFKn=oG}0EV=hPOJeQC%e)576$wKiLl@TJaJh=`GB3ZvWo z3uCI45@OCg7x}}QMvFXcuXB~BN`JI?Q)I7~xGPEjzz|yZ?sl_iSnxXCDEm_UQ|LA0 zXKuz8)2Pg6?9Scyts(Fj*Eas@X(iPl*4^9*Z%L6J&XgaFOQ~*DLi^$ zj7)QuPMsmQgsSvjpH9<$B2HA>qZ3e87;Wq1)#sg>W>(le_Jl7bc(?Lxd;Lq`6x%N^ zgr3L6w{dsa$2*jDl%1UZQ0&$)_kmxJ;*w2yG+?9q52nemdv3E_EUUm@rIs#XMvm1$0L{SdMMpYW1{+@^g#HE*7V-x zAW1345nl>b_EF5sx#zvz8#3vA3a4kz)5_juzI{J05r*77*?(9Y8J`+4eJY@i+H zK88QG>+dXC+_vXS%^SI={7A)GhUT7DOF69>5cta#;*IKJHmS8-;*^zb;!)D8%xN|b zezA^z{+qgmeqwpUmCvk3)+ZhQ)))0J zUD}n|UYq06tRjq57^2ys}CoG9zAIQWRM9lDqO@m1m6Z0D5k z9Vh*Sd+CcTBh!7!4oUYJYL22}^{umRGMva8RFdgVazjL&rkGRTyDM#$K>VSEY&;v6`H*?2)<`r7f=XcA3TLVek<- zYWhxv`z{4P;>5mxh!_fxdqJy6x>{yi=-5YaM5I&kRBF zu~uxKTEAjkC9NvAK=5JoALg2xPt_e+=G1PJbB%darr;dJN(r*smnnvMeImHs?U5=t^88o2j8CNS~+zCuBD7SM-k_k z)X>xQT#QP=Md-B4jaPnDKi3Gbu$a_R2rcZ6R=xtGa$E1L?-IPGr9PIQ_v;=v)Z4jU zi~79r2&HM)obHt5uHQ}l@{^kWYK!9A0B(V&1~~{NijKyOf^$W#CmY2!Pm10xMG(wh z?hej6+WK(!%Dz8y>I?u$sV-ZRj|1&@TQg9ojDfmVctuL|h-#FA zzWuuZg|As&z*E}>y1v^)fXpnkciXvl!QSB>P1{MyHaRr)VbqgW&sk~6Zq`?gw-GzX zPq76b@r+lcacObgO>RofAAAyjIeETJ z+lTpf*D!C3T!m`X=iL(w;U>P7y-rx=OZFFN8R6&L^-baXNXQ<9NPfz9VT0TN<5?-0xS0mmEn)KbuSz`?S_~uzdQ}7%zbe7`s@MH|S<_#HKB=KLDPeiK}N^^rL z9pFIr+wzG&76<-ySzxZ|xaT*yI>m1_^nSGhbW6nM4KG&gP_4IO?(_U>i z8a2-5FUAWw;X1x2Kvir*Y;3Lgzdwxa%>V_XCwq zUtFzz>oQ6=o?m6*s-G{cRaF8 z?V=EFcg;8!h8^49G42lkP@y(5e;p7}?IpdIT(eGWuH$S7Cu|X4vaGqCa^PQ}xu7we zDWk!{1efh%v{FxT9wIqDG3mZG!!w@t!jI$IR1qgf_KeXgbgjLCK@Cy^q{3zvYv z5ZPn(4ke5FtV#a(Cr;s3cT2f;-6i|k(`>m!bC9ciH&V@(T~Tp1e7^nl?Z}R{%qJJa z7*e0fs9#>!cq@^l^0D)*!8M~RdV|C%Pc3b~i^sO}US{k%^$72N%4A)uxaj(pIU}{1 zcHSuf;C}jLoHe7cKnj07$mPRV#&ZwiPec#RuLj&=KNd3>O&)45=C_C3!N7X+Wo%V3bvxU>t%7EhpG&s(R-=Jhx)6dm{(|?_osc9%M+(BVZGPk;FD%5Y|-cF z6BU&2S%pHD6ZB5p=@2#;XZ9GV=zBH%aX(XAes;gj`$*i0dJNHZbKH$@^W0<~#Y_P6 zJhDed{$$z*p3+#VE@AzT#y1aly#5$*=URW(XKj`z1&9mMiO;k{>g^U@=x&olvUTIS zWb_+!)-EZxG>kJ&unsxWR0M{ZEK}lV=)W})}-n~iSS4LWwj~8L4*iyXMwvqdmaiw0C4c- z1TlBu4mZ5vcYVP3Gx&Mfd)|h*i@V-+bf$cz`~Z&YT-Ck`P*G6<*T5a1OwzsA*3huK zVPtSs`?@BW0049ax9{F{KXe8FJUo59jkGSGv9Po{LpKV(+Kmf*PZT$B^tOY~UG*C` zt{)VCKznfh`?fv&>+5a?#Qr(`@6`X(ucLPyeH;LQ>R?$p{Em-<2M7lO0Ij>jU2k6i zI6MvF6#{(kf-v1F5N7iR1q5Nq1K9aj_{srn|0`_qlg7kI1Ee{SmC3>7_8kyLfUv0j zU+~U10UEj+GctH?e_H#2;2jL3fhsw#je!U{8B}0}uxD9(w5p*FE5KK=aYTM+3Aaa1MkgTpYCz>KK%V z8o1+lMH7TYL73OY@7iztsdaq(jSuiY`2@RY=z}oGhuYiqw$2R@<_6)1-f*LXvOt-s zUpl&L9h3#~r*6ONd*e45sOLT1^$*Gd^`&8Q^!ceH$dh{B*Tn>Erw4gy+NTBAREY^=F4qwO)U@x`OvI8dYT^C4TNb=-no6{z_#Kb ztOl4--3A;1IA9MR9RN>&1e^hk04?A$c)kmGgDFk`3~&cAj$o=Ih=EZt0&XDgpXqM= zr1>?^pA^nNbI%{-221&8nqNy;_>Bfm!$~7aBMp9)X|B_#(kRd<0%vHTG?!@9Xs&=* zMH=NlB)IVxInMyjzyc`guY9}!Kd|HjIn02|Pq_Vr|HyMD+}jT3(3^k*rTJ4!_@C(@ zpFcDPWrqLN0)P)_f#0UNg5cMbjNI5e^^Zw?*u?_@a@V~P!?KJH??GShzrTzA2 ze%f)`Z{R)(sDm}&{!=0kP%7BZn(+C9PV8?wG=Y@9z-{n|1?k|RtiMb8w;FZwe8T-_ z%7G;uqxHA-fpF13v63T_E0RN!*^;@EOMfflPmX`H5_J-FC3ORJ4RtN`XW$I=2kItj zG<7?5DRtc+JpZ}wf93K=-T&100C%A6K`s1V-d}C)2)Hv{X5wMuW4giwVG>}v{s+|= zCQc?PrfW<>U<%J4_2&L(`rmYc0hXYxez)pBmvztsV1Owo2@D7TX}v+K9$45D2m-nO zwV(VZDGe`;6pi-()M^zD+VbyG9M(L1<*+(%=J18Xiif2R>m0zp_q@YGV45O$)ciyG zUwh6U6o1pe@h?=MRsP^3_OsO;wAF*${-E6MpxlnWj)CCV0RS5CyFuPCXBXcy7bPX- z&!~e#nd2F4PX}?)Gq>H{&-_gCIpgi< zP&Pn+MVANwq^A_h{!0pllmqhr1^^%2DOkW)GZ5wk0D5`{ULSl>D-9JlKnp@t;8%@` z=MVTQl`!bQ5AcToAQ}eH{6=%&s}HsV|9X(;*YlyQL%&l{0a?_)!@$!6Qpz}>aS%QH zUu_3W{;wDuWTt!oSdIWssQ_v!7T^#I6*UVLr4@jHn$Z5r`#{`-jp`6J4eepNBlHYM zL4wNTz#%GX>O(Ztw6rv!A*e#ZbbyA1_QY8!^~0=&x9QG#v0c3XH2VnO<+3JrqdpwJ zw7qvYJp%{lNiJ>yK_TJu7i47R+}hqD?Cu@tb)e_(+dt|B8iDE%4GlF7-GN?IhXM{1 zXQ81zD|PsUx*^?dFV=Gx?;l~i{4~3)iJni|2*+;k-N(SeFM}1pAE@?Iv;R!7@c$#t z{!r{sy~coJ)L^4zp=JS~06C{Zx%Zf0T%K4@WOn!6+R&_2%ZfTn$7I7p@I-BHIp+ZP za_JMTNtr&Tt6Q_^t}W_HTq*HFiJc_}FaNL_Cqb$ICPuzbG@@#zMGZS6rUayU-~D-H*~FtCy^kP_^@fx1;{>~=;H@sA z3BKorLs%_GhL@9Xs9*>Wqm*xpLjC#M0u>^DC)&LDPw4u{e!jCi{Q^0%6|j4ME1GyA zArif5fMBHn4~F9?z{h7)c&!ybZ11B??mB`$1t?GWkipqH9L7FK0kDn;^H@C`JX}ys z9H$kvWpl0vL|#oCBPFT!G)$dlHpHuyhVhKG~O z=I+S7)i`$BA&w0Qh7d3GM%rzj2?UwZcXNUqUBF@@Epf%<2h7w+tl~=wur3BbaK&ou z$S?PQz==XKc4W;g=7&f)>M#M*f~1q-SsP9IUtjjf8D?6!p*LpF0x zrDgTzp=bz05)fK24utysz(kR$(75PGiFys(cyqE9 zX)S6~q`|w(7*`ru;wPeKKc`!nW?VTa=37xWAXZwkW*hkC$H1F6?q@Uj<9jCE{Nk?y z3s9^X;sOQ8rv88-=)0hav6txnGv$K5N4F$IOW>W`tU?Gv&5U{DL}eV~N<*59lHt23 z@=h!I#I5?87*>zzyrH3n$j9aym%Dn{i%Vo=phxpmx9qDC9Y<{8SQV%bzcFYPyeZ;4ZBBBrm)kN$Yxp+>PP93 zF;eNId8B)3SZ6lu1}Vqjy*vh1S+ia;(p{0}8uX>BR%onl@W&0hJY@50f++>KOm`oR zOYcMOa@c4w_CMBj%~qt=egyc<}IWeJeFmqdzGSA<_6Do>0fopAC!rc zH%Z;@InMkN`Csan7mnM<_O_%oXid7>5k#8h&pY7Hk-H3ZOXzf-d&q3z&<|D}Dl1Nm zvoL05&d%P65i6s2PSxbe^}eLaM`m|!F5Nq>!U*>6*;uf5R{;ND5*fT*_?8=T+_))~ z&Gtz0_;x4?%kebm!n_^haw$RpiC3CxMX`8P>cUyv#*i&`ECTsYv&RFKf^H4hJO4=I zxi&Gp*sf=^xH#MWL9OdQ>RBwLJR;Q(M&|7R!d!_9?{VCl=OqhJ`mi&LR{Di`^Ri8SaN(w;p-DZ5D)+w7e+dg?DAXTq>5eP0_ zPQk_*w<2j|#(QI`C;0JN@iLf)XkMaFL12;@dW0xlu#~EGKMaa6z?nyE>1MEM4Q{T8 zcfTQWfpRi;@mP$u!Gn%!g+;+Dxu${PLG&HeJ> z(4egD=oaJUWy=K$aJAV4rha_^lQK6R3wP{J0|4EwHZfUczv5;%i&~x zuKlZiUA;twImHc~fyA5Lme%N05ak4%?@&e2=a#= zj()C?xK4!b9;X0Nmq{q}yfz*}K1~7Qp~Uq9^3Z4G{KaZAEd_j7ZxN}2W+q>OVxOR$ z*Y-{zv?xF{aw>rWs1!jfeIR?sN+`g6EaDaAh+z2Ji3JeF@d z+E8)Lv(|1wLdg>o+8wP4vOlVm7Z)w;out|XKCi}b!;V76Y7$6?%_zW!lwCSigSiwe z_;x1%_tCC=heWT&M*&*U_znt?Y5FH2`p2(?ppT3uUgTURfun}OLom}C(Tf7iJ=fZP z<3It_pQCXS1gc)+-5COM{VWAI7P${aeo2~y5|t^yDdg^qA*uKm3h>1dPCQBmdS0EZ~Ry;EDzOuJ|ba88~1 zpvJ6aTdWDxH>=%h#ugW{4>T35sdbrp^v06`am`p}g-x=3;F^`jDZ_00f~=plKsyYM zx_?$e5?D$9X_5ae>|%l@J*EIoB(qOz*N4)8xS0JZ&Zv4z&|Ps5?~<}TWHYp; z@>gVE#zGhoR|b6b==A&Q+4r@Grr@=QZ-a;~7}V%5k6FROxN);j^V>^(R1!mf=@u>J zk2m-*JLI4%)uw(UYox-cKI>arhJwCcqlfjgwB2-5p1J2WW(^L=wz|wxunXtsBK!PF z1xVcT0*2T&lCg!_i*7;wsHOm&PlEyy$cNCMq1b1e347w0N@nuu46vvFQma-@0d5fB zL=FnDD_LI$dJ`(USqSb^uoj6EJ_dFKrk)H6@Yx1pNdXEF^5mmP;xD!~plbI@H<$^I zU}zRwy`lm7ac6xBFe{$$ngR@}@lXI-H2J!OI39Fe=DVOH%6v)zG{?8W3T`RSM{aOx z4I>vJU^Ewwp#XxMDS=>@5h1paxeTsRfR`)#H$Z78n^y9`L|InTb>csi|)9&j`Z-j!B6VfnAeY9lcC$BStphMFUr( zg}6-Vp+L`*9x)H96NiJIrPLx|7dj2|jTZ@?FtcL1{c2o$#(Axkoo5+)n2!O7Vr;`i zePf22a}B8d`31K*6Ss|9a^2@TNCJC^(BCNBGO`T``cFp zwB~Z2rVBJiu4+BBD+2T4ytPe9)zTZ%p7rM))PHRWZ~tQLkNODf>!-=o8r=nL_ zV3W*a)Z3{w5m*Yaa(c2fI_#uHm@q7PcA$CBt_2+#cDB4SBcB|1JWxQ41_2|N^g`zT)~;;gy7|M2i=zu##jjTlF~$U zfM0&skHMI|3CxZ1a7zz?+o$GV$)Ayu?R!wn@b$Ioc`T0jT;%eJO8GELZJ|=>@2a0- zJ+;-$(sZ%arbE!B&!iTD9tGe>V=<&hwpGaREcltCf$n z;YaU&fZT}BS%hW)20 zZ|2Ee%<)D+q6$GTOKY<9(S$4xbFW@ruGk@4y@Zf&Qr+*n9|t$FjvlCp4O+F-Y|ld^ zr+8aiUgm$Fs%-tjNcz-?ci+wr77KCTeKwtxWT;n>q+LDZU%5Ksl{?W{JyTGd(%Ksx ztaZPl_t98N98t;xH)kE&V$Lle-&5u+|6nTw$u;p6HgTe6Kz0e{G*G%yuN_*nP*p3| z{d&ErKsVG~Y})UMEJKEtJT1M?8@KjuZ3V&U)Zl!!jDaCq)EvR}lerxyneA)aD}zux zUz42Fk{#m~^0Ad-170x2X%E$mWFCic)`FqW$v2+%sZ&i>0{IVRL^AAJ4co^&)0oQg zwL`oZzBk+KUx?p+@V)4QexK(M4@{i`gjTGa{+>}~KT^J5Teq;3^JVj)k?t>(so!}6 z^B)O?TRhFx&VGL4+U%oe$MLngJUN9Iy3R?0j|-;NV(?V$^eO)Hjy!E(>Xrw zsy8*M-i3{B2Yb?(-20FF2UGO++hL*s7Byl-s^tEy0GLi^UBK%!9<$QVzANHHP5C6fWy(He(r4{j{ZBOnd&TG5SCdXvzj6M+HR z1h*f$ahK;tGEY31o%xhfo}2qUM{DA-Tj#zGz4m#1lR+bot0pDlFq7wTr&#N(#>h4+ zes5}nY%JH%ixNau<2E}MqT{~A!XBp0#-XitE*90nD^LY?|MvbxAGebHmREtWm2&|@ z9~$;A=*f;>Id)Ac`+JH74QQyKo)(`qHu!1XR~LxpFZ$f5m_T$Td*_ zXB3Wkm(W<=3`SvEq;Rmmj9)%*Gg}nkG|_=zh(q7N4L`^8OiDaZVJ#%IFDw%!@(D@S z6$5bDnwND0uZ0qO=)YYPEh*iKJJ-BslCJT}%FcDnCSz#YTq!Qyc#6UF!g+@X%13{TK2H|-%YtQURm{E*(*#MJkSI=Fx1*7ut;DbA&H zA@B{7{>XK3SV^$N$sk#Mdmq^zts@}z>eYDFq`0>pbF-r#da9^|pVHsFd7ajfbU4)? zhN-rlB6ATP3A*?k-G<>t7NR!Jyfs5aFZt7Hot>u4a|3?!o4c~gvV*?p>b%G6-A<`* z(wC5VdOoLaEG8?~y-l3`CUdV)r$q3%l}|+Q8<)zk`0n}T%}`^Ep)xpE!P<%ZFAm^@nM39YkpHMWhFum5|bmI#Mrz%vowYgUgRBB`YJ2ehIr6h;AMk8I!BT zLhp}ZT2G62OzPuSfNG=zM9uda;~aE!MEm!Iars=bsU=}sae5n@=IL#KHM+A^te zL-~*Hyd5f$>5@3E+Yy_uFHR}C)AO73eS{-g)))*z;R9sCynjBM}*~I zTp%aZAP8zaJQi_&UkTx6E#^J8Z=%MES5Y#}t+npi>p>SA6jYUEHMCVno(ly7MNT6W ze`0z;ziGZgS1N1C$xjV}Q;t1pBX^!B4ZTaZFZFA9J#JQ&0;}|_!*ok;rfdrmMyBlI zCg=(1&?)%IK#56yaBPRVKu;3SNy6ly7qEbF00@)hmf+ zm0Q}21H)@Y`{a=H>VFJ6GVREu2Nd9KjNP8q5rh{7U_(l8C1B-=ptp@iZVLoDQ-JH+ z&-ZSB3uXimB`=X5hwwh+PoWrcwk=&2Q^w%O`1@n$7C#EuHE=nexz;$Zk6jg}CTtT@ zevpt@Oe-^2ph(-3F1JZ$MnbIdK;>Dl_p+^z{P>?Nvef`mW+cYIi&IDp+64{}p}4sSgl0YgZjBRa@1-VMaB@e-sGSKs?5c5)F}&QW=5Z#F5v`CQumIZ#f!*xNYb2=AG}70v2+QSp^cD5EPb@ZCmR z#+p?2n(WnlnIhA|*8?+t9OuNYl7?I+I^{nNEl+iY_4$W%E^d2tmG;^xuZAS7u!A$$ zm=QGvq8j1$%Xu)2u0T^Gt`ZdYITz982KQ8u@RzRU5&HP#22h;lOyLpu=4NeVr9@Pt z3XbW~6yy-0tJzq0dp|>>Ex9%$xA65mx5prtVMp_`#cF-y$eVV<0z7%Eg`d2vmGxP@ z((g15hRCJ2`+F|b)vc8`?z_!Y6{^jzldQ?~L3q1%+Y5x^g21^c^9WCb(9}4F(>2&R z5&?CX665`J+JCAEQkfFj$V(`a%5MpC7R+Z$j%xs4aDYnQ4q0i~ zmjL7SCb_UP1n3la(+IMFG#sb_ffbjGie-i9eI$!9u$-9&!f z*+vePs^noLMtw1{(8`RJ-e-}|R2r`{&ty9uBN%;R($dhkaHaReoAz({7M$I*E!|W} zYQo@*Q1=@}24ront~Ft}R5*Qd1F6*s`Es#S%*O()Fcv8v)Wjj>gA zc&zton*NM}&YJGHdCs`C{E`Q6ccs&65M3PdM+ua8%m-BK)flrXfi_t?r1Yv9ItiXua}1CQ;vtXbRoIB@OGCYnv@RL1mRw-HJ>1=U-Rwd zyh#WEBgnK+`9}lT(ubbDHr7qm6X$W=8F}roL6apuE&h8i633wBZVf?&V|v0hI@;Zh zSC;eGM)*>VjHjOuJ~MgUu{>P?6M=0kRxQj13$?>Jp$YXY`=2am*J6We`b%cVgK6io5^0^JKPW+l_x!yS2l8( zomFlsKC8LA^>T)1w6ZJ2N4Q~gyno3oWo&8nUH%H!z5>D-zt$$)D2g~n$Of;uqSb_k z!Wb*Y%--Bgv&M%-Qg0y!c|Aq%`XVMA5a!6*cjxoC{K&G z-sI`?6+-cwEtBVsa~I4W%t2fi$Hc5Wn$+91-;airJ-d_U1*`M07a!5z4#}%Pw`T6! z_`B?K8iUh)*JZ+v5EvoRWMRv12n&J+DJ`TVu%&~qEld>bEKsZ+A&tz6et=^3Z8+p{ zRf3>NW|_|vL)|1#;8s%~1^ML@>RQeFR99bn9NH4?Ry3P^HKbHsaVv*Qvq$B*;0!W2 zC$2=O{4rwf=FaTw=%#LCN@F}3MyBh}6eK06giNi4qai9hlSr;WK21Wz{$=t&BMm7> zb{8S-FbQ^ZfS|6zJZW&>$eLiF;h`@kZ8zdsN)*B=eOSyC8kAXK-!kA1j5Qvd?ibyh zj%V#Xb@QxkoF>;NHW&REZ!hDtbT?b0cQ7kIR9(PoZmGX`NT;f8Tu9HF^#nPbV zK#!JAYBj~aCu-yE+MvvSrK~VadFk@PzKqK@iUERJFq{Bg!`vEy<9ST^ZjaiP0@Nt%$TsI zy6U*M$9y7vr!G3AVOwXsL1u0K>3G;@aDj+q*a&Jna6*{^45{M;^I36NIX8#ItzzE$&0!Y_=GnySDD#M>i-EdW^9N); zqBX%Bx7gc87QjOukk7ger>;bmX^?37U>WZ0H~( zj%Th4mc5y|**du^?81WSj?Bn0Z8 z1)4XFL0VKLrs88u^j-$aEtyCBD9LYzFd=O5cCFy8uFd>NTNfnAgj-Mx2 z<@Jhf@^-d{X)4WL9e^B?AqeXDRC56O&(pv10rUK&DSP*I?DE1HRT5rca= z9w?-N_nUj9#!Cp$OKBg_#0Rw5@`3j=qbli_>*c{!J*;TL^CfPvk%t0(uS+HJ2Lx`p zwQXD&Eae)gcs9K}+y59-w<=s!dLcc2Vf}la-^bxvm;K!}Ovv|L=|#Iy9}|MsBqZFH z4R6rIOm9ID`M`U=2G3OPk!|@s(BVd=s+S*0OA9a1Q(hDZZ4Hz7vZd#5V|T44!MHx5 zb*y1sh2`s_j}>OrAm7q^($r%3nVWWxm!Y|48h_$g}3ycOGS9s;x z39*FjTO)p@M_p3i6q7Qgt3FR)MsMm5&vQLzNq^Y)g4I>Zh)OUeiwGr{W54TFs4_QC zP~j?bzAvS|n;)~yz>);dbD2!IntNHOdr<2bve*W(qwM)_t(X{=Fvyn47T%sW&T!qz z=k_gBSJcm)UOCw&X6@cnY2|y~q{PZAU+3A)MU%9O+ea2>g!=eY5Y`0vduD>J@A9zS4thE*mIQ&&Vwm|| z%tCES$J*H5dh_-uu`8qwyxroK5Pw3$>u5Z$;_)c6Rpyc~gH|?I>_&Ph1Mc~SLD%*S zD<88Ar6+lMIwuTZn%`w$E9ZxGD$lp)T`1JgxK`JGH?iK4b4c6u#g=B^4>sTi)xrEC zaD$Fs9&Gr4x@vbt=J^4{l5TOa$n%61)+3(Fo&pv1)v&YS*NEe81y0o&rk(LFxp8mj zKZMeXvrj5*7MkTHIpph9DwyTTYOW9FnK9%kJ*_i;j1}&YfN8#}2vAvY+I4pn*5%RE zVNDlo*y&QxZuaufEN=IDcBeEq$-tyHgUDGLXxEOa(&`Wiy-04ceQP%g-S+9PjCEw> zSC=4*g$=#Z75OT71unk&$>*8xsLVyl-TSiLzs$UdH`SsykZhWiG`%p~YMNWz)YQWg zd9nta7&&3ACs!5h>316+=zdc`MK;jPWOhpaFsW0aU0Y{CX3SN$c5rPAGb+7pk5}!D zUL|Van6XY}K3KbD7VIdvG${Yt*!3`uKB5@dx)`m;BQ-5WHyL?8OwgD0i+Y-ch^Zn@ zW8Gri0@qZax!GZ-2@R98{HSC1$q9fxdZiiT%DM@bO*t`PNDZUOT{Bwn6;&E8!N`! zA*9DdA)jm*cXc!L!Jgy9Q&0_-QJ9%IH#5pdC>jAnPAaPC)D}5S+8wucOU-|Xu=J80 zd4#TXw$Zg7SzXQ#-!Vj|+Br}q;}5&(yy25*cJO+3+e~J0D4R~Z?~_EY0mT~8%e zxUY1DihA2ipAzJF870K7AE&L6DVdZa9pS0+txT_=Mzgq1aG-L`S!iD~5c44*DXeqi z)EC(X(QeSJaX5wn?f#NvYviWQ#esGvvDYt?Pd>@Zh%CR@!X>Ee!WF*!_-O?pMD@ds zb_c0ZTWRL#C|=jR;EL3IE|X^tOhGo|nI4*UK{Bl(-pSql?r3H!^+-n`D@`rJh2Zw#8$;u9pjI>SqRqDWSY^lactu&2D(Mc7@oGB zP)Sri&dye*aJcArhGlbxLd{^ILi6#M`h3OCt5PxFKN-OU>O7mD<(&NF?JD*7W}e`3 z&dFCZf)kzm<8a5qW}!BCwD(J0&X~;wzNZ}5rZww*6XmI%_6>h6&M7?hIyZ{u_%+4S zmx!~i3l-}sO)_J!KG>^jJ$c`O@6tWw(NCGhr`7X|+{R=E7E_}NcNPQ9m$P5Pg2~zY z)~>a(o80jkKKpkNm#=xQ{8C{cP}+>VUsWwN9eJCdQ?iTZclIRDLExp8NzJX@G8k+ zY?+u%<;=A(SIl1D>-9Oj-=EL-_x%Tcw_CVzi)(vc&+GYoJnpCGrM(AKyKemXX~Ukc zS?6)yooVMkbkUfP9sl^5(wn7~DxGg~DETsKQRI>5Qi8Z&NbpeBFtpq*1~*F)z+ zZqA3WugmppumbZ5d;9J;ffmk&9&c+q%f0rWuDm;q?V4$I6yZ&exp2xpIBcnT$1ckz z;#)iiALu@f%1gXL>U;FNh{<=(&mxrYarvxC!cX#GzOoS_YrOyH*N?T5M}ThEl^X=6 zwnuVKX6sZua54?WW;O^BLB-||%^9z~M+$!QNBBoqY8)J@LW4i|*7h|<_RaN8efva{+b(8YOu^ow zEF&L$U~23j2(wwi>JXp4&J=6l#{|*Ln;#1=^f|>u9-`kRJ6{bh_Nf&x@_I-#-22Yp z@jwgX4_B!;-q^y(Xjf%LQDZSq;F0Q;k=AGxQM$Q}^JK)@IlW=(w!U_|E%HSVNQIu| zgspTp8h3ufo!}MB%*x8h>@7mWyL;s+EsOT2yMkxcL-Adc->W!X;l^XFSht!FwKZ8$ z)^9z72+z9TyghKr4qdX#u7v8VV&(GmLBVPlk)7?AJ@;C!mo{4(Zc1z@blTv({+z>s z`qr8+j%H_E9V{o-_r8CR{|fpkRqxBJ>O3%jGqtzB6SGx7J8<0_%5@*6Bu-r2q8#)6Ns_B^{+{@q1JsEp@E!P$8Z zH6yEz?t7N^{%+u(ovrVCy7N}~?)ns3o8HghiBWbqHQ z0Yuvi8)}a=d7}gY7% z`ICF9x--z?Kw$XSaQsP_?*ENx z_2ZwYzKC>%Q80MKdc8dY>epU%^1h*mIrfkMQ=a! z%~Yug*r;#lwtThI+bi-g@1X?8qUdpGbLu{*AiugVVsiFbOxqPGS~+i6w_sG7aaD z%HP32&a#$=3+aEu$d%yfB|kncLbx~^uh<3q^<4>xNW`Yf^{|%*_o3}aF$uMlM@xRY zLGP5uso425Q*ua4eim#Vn7R{*(BX-7aU_7$TPJ5*yc4jt7LiZNOy)E4a+BM?ohLm# zoR$}eIb~8E!7Tf8vNYgY!WH_wI}PsMbk)<$Sl!zwd>`uxgu%@uW9v++$r#!>J^bnBkFAY%ljn*mUxoeRm!`W7AMiukeoD03VD0}f+d%Vd zS04Ht!rk%L93zk~7#cSG@4;lW!1Mk+#z+Hl1XwInkr>|n+0EWeK9DY@CWT|yDl9q+ zfX_-)eEm|rwR6qvJ?{mq6N`+<0{_#F*}7${z{^7}3kS00Uj#pGJXd^b-pqM>LtnK5 zMcaEb7c2Ub9nHT-SHGaGYK9xhbzIDi3ak3{q{1>o$LbF8T$rziN$R7y3p4LFR@tF^ z%A@ekS01nnnm9V-BZDPwgYdf5WGsZDYLe0q%j^~F(+5z=w(u8Y`$swn*(=)LC|8rF zPgS?G_UdIk@g-GX6(;H8t3N0OAJ{bu$DIy5I@HL^M4sUFn7>zUmOAo_4)$kgKi;|P zgx%>3t0f1W&8Nc80Mli`FIpb^xqg=YKDX1+T$Gnm;#uVU@$A`<8+Uf()jTq_?EUHD z-VHrB4EBFdP7WPg{_m07EKJ+}P^rV(&C4@KI(wuOxY)LEnZ zt!cs)XG*dxoJgSGrT*(>>cLH?6lU!>q>tSGQ=P zHfA)o`Crehu@rmWwhHqB(jl}^6JYxPJ+yKE9#?%W8Qr^^ytj~~>)LtsL7Qt95=jt5 zwjgXPbaa$@6^W)tHyV0WR%JBG!ZIpV1#>G=Mj=1;dyIN-yqNpv<^AL4udN-=ui4zy zb#`2m>gaR&0TuoE7#hxHsC}Fe?@c?I;2;A0o0*Fn_G_R%Z7C<(` zFpaWhq&0M)RrholQ)XUt>2l|Fz@?$T)l|(iugdUKg@?&DSB;xDh|^`WS`epwRnLYe z)>h~Y#(Feo?*rrIQ|e@QS#W%qvm3S>HDio{d{U0(9VlktO=Hid7t1GZX1x(ie;b(- zTG~lF@i)f8gToQ9Xv14GNi%vL(t8ipCkqOj{bZJl?$hU4R`aR-e({P8d#!W=?mvmx zq-y_5{l1Z*&CSC$^RQh@vtJZ^9TiwbUn?R67ZQYk12N`my>YLx4 zdosV&kjQAyXuSU-0S)6(9cr)agp$_TOKIa1;4`oGe%d-wI`tta^9n>b? zC~_e;PhfS*qUxEnnpN{OvqCAi{85Gi6h zbkHi&u)C~!W3)!drD@i44H1HUAbrpy zxisw05)10aVT4`f?uv@?iUpTE?fBTDk1z23J|odyP1V(5h>DVYLgxkXVd_-~KABN- znxy{J|3v>~KZ!wEV3VkNOZ`Jg#KVjE;Y17I_Zm zw$x@izYC7fLf*5rDgJ6-)YnFk`6)H0)Q^Q9sE!C-K%pRsJkAFi^gZ&kf5RSNLgp~z zzX#G+D~E9?4kkea^ihrwMTq75FY8H zP8w=N3~?9FtSWaf4Ufe(=sfr;u9xRKx&1$`BI6|aEfy%$UYJauS5U#+*iukedM_^@ zS_ouQJowtLpj9J#^`Ykd0&k70(Os{#iT~xwp^Xu)|FDkn+-h-RRjz%4W36 za)>h&F6JM=%v`Ye2FaFGaG3YM{)Wx3$eY7V!>?k0Z=c(IqFJHE9Wd=~Z0u`GQXa&H zM}{2g>-t5;cdx0`@i@bpv(nnbxBFd?WuHZWw?a0#?`7*^vqv<6fuZ51fvNI2nHO+wBq+u{QKs-oYt+x9_*q$a9Tz)h ze|g)W`?9|av#81CSL){P-!Au; z7#mE^1@tGXsU)VppmAMatZvD6&0Dczx2JuUdtYJWj=u2>8UYgRh7M5Yjgd@_5~&X9 z`2H|X`5*UefAD{dl!{_++pWK0!*3{^(90%Uh?R$P|HuFO?^)VP^m&V^XJ~$FjA4Ln zgYvS-<;bgvW3C{#_`M&q6A3t{_k0>%;Lbmr=QIszQ)Z@j4oF_(c5(4u2A!Cqjb0p4t;)SZiLTHBcH%M`tj*^ruj}o9l{Pip{Kay zguO}2+wKhkXf^etZ_Yj_a?HBZ`GEQ0LAL=jdaP?E9rUFy`y1AAei3RR0FcO0-15f$ zdvf}Dyf0APUr67)n1k^%MM)|f;2TN82FyCn^|1-+N%W@53Zgibvb*bzdCZ}hCT~5U zze?Kb1&PLEjHn-x zAE451yf>HZ3LcbDwMjxLW@3XjqZCp|;|s)U!KwO&{27J@AsUs+a*_lh8!fF}@~)ar z(qECLxmhkx2i5e<<{f^Py_GGuyotTBZTeN=j}IFi_uoT2^IN^!&T*v4mE7?lvYPOU z-*@Qva3`U_Mcu)i?*QQp`Ppd@mNLvIJjX#>$3ck2?>cu*NU?fdsQQ|tU4Hm=&PAhJ z`2(;6up25%YZ()^t)tT>v5?Nt3}XBZZu||q{2f|SP3oxwNslL}m*97NR9U+Ri`!@j zND-_~2#HYc0^>s^9Jsf4*jYsPSU zJx}T0`=r;u930D|zT|oC%G+4va^~jamk&IGKAs;hNaS`DsG1k@3ml*S-rZodCw>3V zOcVE%ESFzIX>?85bZ#AGUpSvr2Jy=&@|-T0A_;vX=|PKh=ngANwi2}hB(P9`N`sG1 zc&v^OkkmjRv1r@ktEq|bKiQvyOvwjBfnq1{98gDg z1d><+Dl?q3c{J-vQM z*+yLrkuWw~k9-K-EYj1{5S-+RlEm1ove+H2Zp5E3n8(6fuKJcx{YT{$d+Gn$QEC72 z4(@GR;32gGe0XY?q^Nt@+YqKhDXc>;p8DvMPnDw&0@u=18l&ED{L>EnnUA1ylXgP3 ziV_AI`L0G-D)#yiV|tZWjqCfr|0=W}92tCWr*3B>09$2iNPbE!Cm+?G)E+RRP!@#A6FUGGPL^Z`?NQ@;V= z{ZQKCtop0p8SBuYh><+EcjTDcj>?(e2tD9V(?YvvE z>&rf8$9-p>{!D#HD9FWG_-?%N``p2%JX_9c)juBjt$w}dOsaHhlVKo&U_R$;klrm` z1sb|mfXNK~l0DF1amfcDdvbDh0Lgv(nR;6*X5)^{W(@>q0ol-<#+?*4v z5@x=`k1cI>tt~(Pj()nV%JS|zD0AZl$9AUBuFD$K4+6J8U!hZ*4ahGNw%>DYt`IAf^#*13YHXf?3C2^?^81 zlduu@24QyJBwC!pG=;ljL^_q)xXYsCYknf#x zk%$D&BJXxM7ax((ZDT5)}ikI0YvG3w>V6*Ho9&!_6V zwl^aZbJzJt{%md%U3((=8XUy_TCzt)j4Yd*&{Jtl(`|AW&D}-oo+l#gQv(!R2dL{u zL@al-9(aGT7?`fhHbHO_nO?-R>1VpP1LC_1-y-rML2k!XxtdKMwE_3YQm3QO!Q%NJ zD!hIZh!=~ebU@5`3O;2jP9W9{A|D&z+(oeO7m|)S$z169pdUp1z&Y39I%HH?ne5G( z`~uVT#BvUes?Lg)saupkF!b{8w(xx4w%IK4gJM?n~g|m9sp-`0nRO0{h*Hk7E!yvhdxBl%>>Bq3@fW&BF3{~%dfPoVuJygjS-9|Ll=kV zK;u(An~@n>>OJhOFSIB=wDvFQ9KNPAtfuy8uYH+~k52R(x$G<6vY9uxDgx8D1^GlD z5)Ir=rDe69kPXqox+=RBP=Te5C;I?ATKe=|pB z#{ecf8~CpG#{QvvG08Ka&`vN@vuM3#tyVJ~a7Cr`uLL7Q2bT;`VWf1=_aHH9Fc1YX z|9O#x{iI3ZX`1|xu7KG-gIL6z8{ZtH=w9cnU?D?g!N-{#;nog|V14iFEu{?sOq-G` z%i0wo3pXLvE}pc{*~$sfNgt3I*3&nFd=DS^1=B9&2ALsk_Q-m~y)qpd`It09AI|LH zdvu4#I(D_adQI|m?R+Wp;2{#8-#NV5y#R71XoAo4G0B47x_&L0iekI>ZW;DAb1=V@ zg^?TpvT1=b7b!+maP(K>Up}|Be~}NpE$^DRXf@tBwqF;cX*sdQAErl%Ux-#5{~)^{ zI;OCwkaZzkI8w3NNESS9D?781gD?+N7ezryJ(fLVvy?=x)h@hX8P{^S)_G`knBdLPbbmROmnn zV)hIQNos0yxh?fVtbSyF^=k1BOF_tAcD*s@-4DE2dcYTE)UJ}OY!=|eji>}sDMO~) zh|#csZ@f-9Ahb1pGluiIYwPg>viH|?&MdBjTD3Z>i0X2VVux~VM$GTP83-@)!r{a% zF@Z${tGCSgW39VXa=`tLwBrKG?vaQ&L|T_6M~iVATkLODUGZW|W_|zaKc7J6ZemJH zs(FI%{!>2>+_t;3Z5K?h?;ncyKbYPnzaQD6Rk5E`O5*A9vn)V#l(vqu@OKd&(!G**jzwz^XSx`;(2&P z%wv;Tn zFY*)%rkBZMh}@)KiWab>Uevz%-XOgR##QnEY}!ooLk7{?EN5J8cJ3ZzL^oz#2eT~{%oD}Myjfrd5Y7B`K-VkNy|3uMw{A~dVAZW z=`R(wT`Y`rhxI*9fyD=vQPg;!Os$cs1vx~(vL=ll_RD@#@O};F7i8lE`{SGEyVR!lq=Ct*PW`$&qkl)EemRUX2P2HJ8uF(tF5eLeUjOD{n6I5B#y< z*rM}|j2zSoE_8U-rvaGBnX4CE}O2+foN&Z7#IW zrmumDOEuYG15!P_H&_L>zh zF#dJK^SMNN191(-K(?WF_N|Iu)B-`-jv$VWy@Jw_^mjsaJSBJ|Xv{@k0iECQ$gx1E zVLMR0A~;XICHz zJlN~-gd7`Q*l2x%0UoehGJj%WC!}XfZ{)})*^^x!h9*60hL(K-!wCZKdy~uw8UC6Ui9`7JTfw5u;{#WuAY&2;5ga@ zkf%w-nxsy##8tL7UeZfV5^FGfy<&I(c&=Q}*e+4PZM2N2IPIVHvbV=xJqyQO>Y}|w z)o22m@?W_}x+o?JgAYQA8T6!V2qgPnDuueG>cn@0$fWGed<#M;OHYE)@Fz;V%#RHO z9yQhFW+^M*kgVl;KK8X;=FrMViuCEk^VmCSSlYQ~%eoa>FVBOa?qF^%ffKl}fzE?g z$L$Np&UA&xG#CKX+d&&!3rB?>)oEY6-ML%$mA4l`E)`(++a(VB=d;^4JRXuTvlFVZP% zaKp&eljv3c^bJ8QElHS+s@UN{U;l=DHas?#6JnIKt!3n~J}PSnyI zWZSUC-y9-IOMadD8&=*tQSK*wj^a)$w$dcc^-s_{6ds-BZRztKT;n#4VVPnlU7ijY zCQ|eiXMv^!jV_ZGP-mdxh4h3h?@Lu)|8-ISyO2DEL*+X*5Rvw}_k&6|^?hbD{T@}5 zZ2~o>nT@N0F%oYQ#U=sVDqF7DDpR?237pCmeFcrCykvO`qbcht%h|wpQ6Dp!db@Ny zpw!kYP}(x3ab4&U9eIZlR=aB1jK%{OhmVIKE9Y37Fbn4RuMPs113v(A7^C_dK(9fL z<_LNVR&_MXiiQeiLff@dp3@udE3YPB4X_*`FY7_N-Jf*tc{0_LqZ-3*}hL+7^zOOLM_*yvacfZ1Qo)!8xPA^xP(@Ant_1% zwrgj~g8iw7AIqE;EhqVBQciVlV>uiBwXC;rnHEo2&3+Q-FQ&)l5r zcGw-ntRMF>Bg0=^&kt;Y;0>bxUOYh=@#7bp|8t$?&p3<`1xfklv)R-nm#>H#pl$@4 zxz+`VimTGqP@@E2OV*R!dm1tjGo?m`0d!uPFW19ob%|nEg>r{rf^FgrE=Vxk1s%Z* z!D1p) zkfxhJT=Y37m`$_cR(sQZq2wOx$T;@uk$&S2^1*z9Hv-bQ+Pb~Q6A;&G^1$YL9ql^( zWT{w`D}UH|1qh(SXC*RQe=&?44sAgq5!tAw+l*x_jYWE78N-n$vm)aZ>%-G@A%W5C zPYr^bMRrvwDaH}l1L(*($->6HaUnuZ1$=@QG!M4V^fI(c>5+$4O_?#q_}Fzh_R zJ)q+4;fmEIBZ#YsDbn>&U+7ffgzwt1tQ?F5+$8x7V5+`4P5zK#p@(g--teRQv$v7# zg33f>v@^5w+X;g9hl=}JCW&Wn+gz=i8^|yNyjo1XKppW9=*K+=>Ar@ zf4I}jWr+|(9_>_Eye7MLgyAF0`6g@w@nXhmv#H?c%c1a%bG$o!qdGc~4}&v2LVkWb zx!&?GdDDi&DmnkHOI$Ef&AyxgJ@qEvp72D^7aPERhG+Et}@rEx!62=D*tvtxd}B^#O~ej8&xK z!HlX`AAwGvTj>&1n!`Zs(dhwYx}+7^h$}4yF1JV?ry?#?7w}LzAm?ydw?eISID4r~ z{Y^EsDIGx+tB^f>8L$|?2Dr#q+D(f`qdY0y(UcU(rgn<6P7!qpaI4dyao=-agO`1l zg2wKEdzu8#ffK90V>EL*SyxL&DH;!(upxe^)bg0spK;gzC|Z1203*i(RQZ#|npsGT zawJlAd0OgoD|{n)b?I34Qo#(ihofAFProbPcoAUK_t|4XSE-F1h?Nwl>2T*M3@JRx z5?ka6St1}eCqT3g^R||G(Hdgyc@$IFd`umONuO9TC{Cj;WiAA-1uKLDYdJu?#8lWQ zMqmMABhI@#PuV`tqpmlFUI46rqq)JM1HyuTd1vX%+_Ov1bm zpls_WF^<6&cmK}{bJsE&`1lQJ;V^(qo~0&aYgRykUwG#O)CN6?Q(xpM$i!4s^6gu1 zPw&UVF$@OMoPbD z?X0B9;&Fh>(@+`GxogJRitEt<7VY>@(G`>rOx~v!jfhrtiI#V7?KCY{dsk2&v*FEy zC%J#X;G~>2SS>H2I~pO|IhV*B4o_d_Ns76^0)D24?!MjYAzM+J8HrBL`_{%rZ4-z9JDUDJ*Ds%L~Z6Y)KYoMwVe}`6<%T-Sn=~bv~0#KMoub~pXIDyu&f#Qn4U6DcYw)%D^ZlMnk2(BGAkOMN7-{5d&{SM z?K_Es1@=yaC<00$(Nx$j=8$(w7`N!_XT8>mPj)c0n%K6W8iS~B6)(Y!SR4Ek<92kx zJyTM=m1^+#+LGC+@gXT=GpS9I8a*|bOepjCDX*L-YG0W1j2b@v%*?-%iTa zZIUMx6nTS8ze?8DV3}2r5++8bSvI>rnMf;r@xmJlGl-F%c+fP&eK#_HHhFCggD9A* zzF9l*kNp3@6xsCkg%c2x=zD$1tjcZkL)*DHMx&nA(RVcG&H##`|I*G+%eJ3Tc@C}6 z%iGNO#vcva%paWWeHQom=)gtTTIIiEE&v}9wF$isP^qILL9S%x{jotkU8TlgZj1I4 z{de2U@?>fa*632MbJp&`YUEeky+UNzsf$O2yUv_+KMqs;g)C<@sZrGxo580NdMcuz zQ61GxE!QrPV8Ju)4;3bz>@DBO1_Ckxn5*~R+&v55fG4dS9rBLdCi;m?s&1>VRgqNE z&_)EP%NPsJ_h;|uybKx_f(7odd6fLhVu2D$Ls+Fm_fz=$3F6i0{Uc&cR?I)VZ=L=& zul)^k71m_>YBZ8m$yKTWf~PU+3C;H=6kDZJTK?G^XuKEUQ7kWN0H2v;c8MQYhc*K1 z7j7yAI#%?h<>ENpkYcB|I%hG(9J7&p0m9TJZE7IrC?7*;fecVS+T|y0S4iQjdPx)? zt;!^phm;B@MI5r!)8bXHyg$(Dd-84jEVPKX4z}*c=D>@|OCY*LY9XFTh6X+nfozHm zm2$?5sKC(C?m)J=H|W!#GYzH>UMrCXry;JTLs3wT=ygDLat<_Yl?jrn@?6G|d{2&? z!!3c=SBUZ|N~Fbw;cwwx|Awyr0Yhzvq%*<@XaQD4n$md1KJl5k+{)xY84hA$$@YGL z+%xNdM`NV5c3BAVm467q`_hw=S*IkZGW|`AXj;{`aoHb>e=1@a3fD!tasxE)?Vi3K zL2rdnP~6nHGQq6gevfWMj2GUGzpbm(!b^+G*6Ij9Fx!IHjg5fhC-#udJI`xm{_(5% zu>GD6EBfkGs@qj82Az*x=p=6%)WdTTHw3oWJkW_Jq9-zMr*G+Iow)Qu+&7H#yl3fo z1#z!fJ@3iMz8xV4&-YzOgdx+jmo8ROjEAE$9!lCafbplHVQiSvAVH}GDHa^jCf4r2 zU@3|=&$x}bicAn|hojcwM*4MuP7v?P?qZ{e;tjTNiLvuBu9X#Azl*Zj-+NuR3Dk&; z%w<&M=wF4Tcg)3NmLU)TW^yq)X5=HXH3~T2HdKOKJCdctrRv~`d@%Ru;%nA1*De@ikNt~dp z?r(rM};@k__X?d(8>^`;q1hd)4}!ZYA3lW+cR@T~2-7jmF-@p5f6kk7h z9-Ix}ti%L7x0i4dCYfz(ueU3F1ZYhPKYI;;sl#mkM#?=3{CHMe1dd69lMQMfqlVIiF9k9~2iZA6v7{VGn9M~b zD2>2DF2X%uxyi|RdB^42c4n*@F=pqjzv7yAWO}^+xbs_`{tt;b5v^Md9(?65I@h0{ zZA_PRm%hkXU>A;^cg``lA^A5Fq#gUyk+7l3z?k`;K1U{aZk1}&h+fj1{!KVj=<`Xkl4_HUTN z?2x?=7-^X3{MzeKc}xHCchD<36mC(c(m{QPX>1eWrPrQF7x&9EfHmGLWte!fE?{CG zQb6!PL_)|e18i>S-!3yuA)k;`8P-%&$43I&?)Y-r{fuLw;nt!ClcEkPNs82|)dvfRlV;)Yk>V0k zJQh$^#^wyS8P#PqRr%$6T^K<)ec_p?6^-u2pJz@UJ!-gbuWEiAW)E6lDMT`z6J8R$ ztpS~6mYby2gR3+XUITkxDlo#Z8u3c;FmkD_sZ7NcnBlBRy?FtQcf+Q5^xJ~L1BKG= zK&=b4z?BM7d24E>c69dZB|r7|E#^ZRQ;RB+1|nO#EWI&%Z@R=M=^u5)x?V|k-a%PH zYx`nu@T^*Egwp0I(Rq6#X63l84uEbx-w|+=2=cJ!|F~a{ zpMalgAE>~WMB6OfSnDz;|8ue2)W^$9=Qy3W%$X(gPM5%~BoRdr^0t~@Z=*&{o+_Yp zW$y5?3+s#cG{j}EsPMVN{n%v@-nAp<{C1^~ul%%R!U_Xv0sT{uFcPg1arKGJ)}3CK zJ`us#|@{k#s&dhk|023C)r1P^KX_s8VqV*G930_ zR1jqPOQ3W>0m_Uu3ad&1djlc5sa)!WP4ZFYl!x^#{nX+rm?W=2@qE-9Wn05)ob7&g ze!)uyt_ibyzkEnF`IM@=Ee^c`fTYg7j-3kwYjZN_S_-mqduCG`#LZBQpmfR_djK=3Bh3*IQ9G#B4aco zQtNB)h$!*h&f?M3cX6adhD=5N8#_VtQ8`a`$+UAyqnDL@sTyd5kBBnwm49U6fquT% zTM+7~)D`zhRt?qO>4oH@54qO4Q67kUv}^OVU7Eyu3V*m;lVgF11hZBTJGo@{vcCq_ zLEE3W&PNYgjP%qTp`#zbbF%%--Wxc8IBnL;zG*I6`$;YY>57w>n7ID+GIb6uEExXW zZDIczX#YwXtOL^qIIF!cM-J0G?OMYK%yt^8JvA`{In|L|u+(<7Auo6x zsgDhre$N9u5A>?rUmz#_hj@7^M`lV(&F?nbQcK-PK4=|T=d1z&AOg7$K=*PoD9y0k zGZtN53h^*#6UgN6dsM0MQ1Xhifo#`FR+ZH@rv$scA5>cIgCyRXMQZHKD3RG5kLUJV)bh6q%QrGd z!eh;JOcACpPv}1niPS5f{h5`K=~0m(T*q=;GDJsEHum`=-&;JMYrrh`_Qz;XvJL^# zg%c0!{}`@dZ?9ol(`b|BMP@Wn-8S!15zlrNenK>Pto9v(;T;V^5fi9(CJK-@~se zL0OnuxnB>`D_N6ySkEwireyzd0ekmIw8i7n=lLRq3tPLw-F1id+hnrdz>`Fu*t%I6=!Qu8>qy8Y9{G@$@DH^TVlEF#YWF{mr9;*n_k$#`*nZa z$Hf=&%V~QxjR!s*U1`1qltEUf)+j*OIN#Ml>8!TmnHuyCOlGrTcL(hR=JX_l@Qz}W zG#$i-7yE1)7HiJLdemD7^QJa=jYMC>!s>kk2MW!xtH6{-Yx}eb3m@I{(BT-+{F7pN z5H&e9h)SjG1+nskc1Ua==5T-d)Q`SuS^f zcU?}|3>479eAW(ouYWMMfNh)?RM}oc?(&ABCF@mR-; z;6YxyVECN^U>dI;@kJUN>_9u$WnMVRFz>3V<+IT9wF+DqqBOn8Kk?g$$g=V!QO6xo z{>M_v=k3y)P#Ui{eG{hwFAc+O_>MMy$}Z1+0@|WGJ*_z%&d8r z<50MJ4WiK^^qTPQxk~(MJHeM#DnEkb6vTyS(0gNv1u_u=^lSqGNR!Of-%~3yRP3~_ zyyG^=elD#=%42{#8Cmx63YUIVpmk?UGo9(2$tzYzo~hx_+61p0=994JIwoEMKZ^r> zb74_a_ufFa=EZ%*K@vr8l)ib26%!7W;n_f}AU7muBsz#z>SZ_qd1!_jl%|ye)}>V&KZ>Jj4e0^7Ze3!s98ccgRg zEKBLS3~8DY{!;Eh>jtN3nuwZHg4sxFAkkavQs9Dl>{Dr7=L~kkBEzF zkQ^-YL~DY_n$)7C1g3Zm6o~EDkN`v!V^YGMFqT)4KnZtVF~Tt{S&-E$`{wsj-{W8 zNm-aUZq(cS#_Jn#ccJ6JW@Y7(Ex zsenZf-DWx?xmlb>Q=P+nld!;TEz)q1$q(zjUSd*mryt5L|MlAvc-@SAV*bE!;cU?T zo^*pa8_~ZQ%VkZR>v&Fb245?RAijQ%QBUo@p27; z#|pBsLG`aU1LFx-GuBmVHjFO$-TM-3le6$`322k^RR2JyqXM+eSS5NJXeC7^R^n7r zX5chY`A~zN;mNl$Y@;rnCg|VHj&E@1HY?Er^XE>-fH^KwVU{<2%>x%@Ut1u0@H~4xzaxP5umm2 zoA*9z%v}q-sg5MJuU(}Jy%K!5;7Q^P2GcBtnNou)$;m63r`YLrnFwT$Vta^e=_Cx^8U3&O^dA6U zu>1~G2LOnnSr@FmzOD=&Z;X^dh~a=rL$5g9avDdzPz5aV*n4hI zu9^s64;?kk<+i@*wGX^jq1>9;u$?;%9Y+2BZ5B$yp=f6lz2KWk#c5bfIV90}G7Bm! zpzJL}^~cS32O)uuVM58Qq2@@XzJasZgaQ*>_}AwYeLA|-L|Xet_44wl^VNelU>7i1|g`H z3K_@>yt~L7)SJ2c3r0#_i<=i5NA>q~D5$7ZTfJArN^cB!z#(j2)4KT0`7I~9N7Eg(!__?FAEa~Z7z#Tmd4aop20RV>&bL*WL2N$U2pRX|^5 zvr{9@RThSXQ!B}ulD{(D7N6u+fN#P$x+IqPx@A6J&c63cC}C0b0Po_(=cWGI(}dR7 zq}v7G9R z%I(tM+D=}H<-+x^vsb?ZV+OHzttUA}glv;82A)e<$tUaP`{N-0YWc=EGt>d8{qNeqmOA=<9=W)@ zeffVY75~+x{?8iXKYvL5y9YXJ@3hmh<^Mixc@&ks>Ae;V_Rk0O4@L?=1zx>ExP&4E zUh=!T*X%}+U-D@edv#UBKfj~yaPs&+N7gF-`B=3Q`s`Nx(GU8v`o>AmP#8=N`V(qe zOJG^gpo7r0t~eY&a+b7Y;(4;$dV5`(ZpW^>Nh?n@?)N`y&xw` z4tYn7&K|vV(pB@N>k-+Om(NrYx7s4nRWUt%PqLq&vr9#nM@GhC`;~!h9el67*4Ea! zt2E*cYbGj_K?qByF9){WHnf30q z*M8UDYi-tZ=Kb^6_XXJ40v6&0bAu+qiVMxn%^M$bR33PHdsD@?x66TBBh`+Gv1J~w zn2xjOZ%&q)8S$F6-2YHA73j@>ApQJ?6$w6xov-@Hc@KU>X+9++YeZI7`tk7yrJU$KW1-K9lhVN+*LwCHW8PKEYr zf^~7##7W%uMXC#HM>L(J289X)2cQiY<cU-ZOv?UJT#5%$+DAWz)(v6v6Cf2DEv!&oo)udXbVs2d{LRsc|ew z)NbDeM&LP{HY_Y8lxxjVSoO9*KY!$A3Y--11e}HXwCenPw(6Cg*?N7)=_-!uJq|G$ zz;QCuN5yyMn^W(eQO)Tqq}G{(Gp}Vm#+ z>d(i!i{W1T_Rodyu?C9vkDiWPeEVv)=$Np1)DcQZ!}|h#5P)AvzH5?g-wvB^f~1SP zbUjG5pOr!b-x_{<2CHaOnuWe{bDsC!vvm`oHjI)9d@ z9?Tse!zl}chC4fQdYhZK-Hx}mrYsjs9l{>cz>`BIe;KM3m}(ccf4=-`Stw)DG(K*C z?N;D$=wqJhKEdM~az`GQTb09cWODOqI1I;WbkCuOyrxZI26Kf5Z^nA#*~Xt>T(Mkc ziecx0sMJT>O2(UGa%Xd* zSYIGpR751n_lju{_dT`#sP@>{*fsqPs^E`jM>DWDr>CcDS6J6$G_ZKwYH-1sft%JW zR9>I%gZU&RsNaM@h{Hh3%z?K_SlQTCDkJv}dH=CgMKdJ!m(?diOwSO~S8vNMEF!978^+Rb&=y|21;*63rU zt@bPvFhL7e?oTc*{8$_sY{f@_GV?UFFx0Y&tk&ovxPF52QU3)>Kydh=EAG*BmC*1O zp5(y6J+)WIm)I?0IZ7PX+#XYs-+<|h_~Lk;4^XrL{QT?KGV^4o`qNqS_=A5{;PP%s`dT|B2Tc)@EHosmVU z+V?pPr$^vkQB!3FDbYEu&yx31<4()|%7F)_ezW+E{cjNQ+A_&xPyK)>4X%3lvYL=! zi7ZJr_YH;^RVZ%hz$F_OTU)qjf3hMI%*jc4i&}(7u@_&~%UaD?3)IeQo2|Gdphh&y z!Z2fgd9s>`q<*f~Pkc^N2Dq)kUQzmj3|cbU$=6T*jj%8|Jfd@SMC-SsRPWP+^}uT_ z4O$D+)ebj{2Sx8&KVA6bscCA~?0Z%dA(K0(gnfQEX{MwXE{M0p%;H8k!LN{y}~=9i9!t(3bHhtdLf6GF=fo@ zK`ZcKKq%nM7OH)!(((D}O zqww`m9UUD~A^nZ3RE1^~HRq?BrB@SI{Q2c@O_SnTkL3blo271Had_5CYCC7Pm0NWu z6q&2Dr^`AAzQ82$M4EbEDHqPWU)#Sz7PN;AX7hBKNSu^=sOgKG6~C8iL1Ixkm zd;I*FfQ58-GqI=_+ojOO+wuayPDFJJZmYPk(EgNae91$&9XmsKa~9dNcgo2q{)7QM zJa@80$1+T^gp|tPw~-d2-kp#Pi!Foc+ec14P*Js7REJgt}?o z9YezvgKCdMEJjad&z)0ltj-%icT}IPjtKB7de3&iF5p0-^Mivbam$1R4m1%w{s>9z z_EaThdkD!wqD^I0Go=)B&=i4!y%QvcEdKUpU?9-Avg8RQA7TNMaLQbp^wsSy=KE7l6QqBazm$99u>z zQ__|n4}oxj5Cz)SB-Ind8>uogGkY0q8#K#dw=^_NbLI!z4Yak%hS|{6ietCKK9;qM ziQx_;wWUjXR207-ohE9^k3Jmas*hgXy$>%1Mya(P??FbRwuVI3WKn6=GGe#8sO`AY zr#qY%->Y3|*=M;9n6K4-^p&S;50v~#K>^43U{?dK#3ra;(HWMFu*xJKc(eR zW59053kH~*&3D`U)|2vb{_i2w8O;NGyr;zHN!<6i+|UMZzG$QOKi74l7-?k$*fKTH zmMOzKx##HUcyTQuiv?Ro;o}`>v@8r(YT4j;B1Pn zv0JxbRTcY_-Q7py)6;i_=x|nWz%0ihAt7GG0D)+Rwq~Sqh;=&Y-BCq<}5U(UB37sN<=LhboTkxEH9;9qyh1 zhD-A1pIUtD$5K7=+Hpc}bGd#mB*R;@zODT>+7YtGg_`JK8`Eix_u+%i#Z(p@+6yDUHk^Gh z(YaJaJ*+#LPM^sqa0YB07d0EnG62MV`&<;h@dmosPNZU9d$}`Mx$nKfW}w1>`jW!J zo6ZS#GdN+FV(RyhEa29(-unaVqxq{X`<-;?-vcC#+>tZ9_RV_5^1btvcxI z*Ladx?UXj8bmAUJ+R|YP3+qvfli2xkt58kNib8JemN3bioSfrV=zVla0WHaWX3+oYI4KI4Z8)uwU=WNaM`{dxe+exG_gm4;-oBr z$|#n=6irsxSY#S zK043(1$RcUFyoKhVD7%wdKetzne@iW^J|w(U)6c;*O@oXzQ&^0U0u6^LmI}q zdV5vJM@F)N@EGn;6Lyzk=edeeg~tAtO6|kRO55SFx5EId$J^QhQj&XX9eVEA%$xDe z1QRtuG9uI*931q4Y&GJ`$hnH?)w$-!9#t$A8seJN8B$)^07)r*ySlsMDU9HL5PP8W z%D$khEJoC~<-wU1IY4|m2IO!hz}L_vs%Z)|-*NAcWl0`Q!xj=2&O1Fj8wWT(4%lq$ z;K23fQ5YSUZX)jVYaMXr^%*4=4|n&%jEw8d`MrA*uOpW#ER;=5=CZvjPFFv7gl-&d z&wPjpz}fBJcY}Ds_g4lX$wb!D*fLhNz@?IZvK)O3*W}55E`DCK?Jp`O_8R%AmEKob zSy_!$;xP`>ZMcTk{xJn0*#HjifVE*TmBl5=0%i1mrFSrKYAf7U8-Q%5+TolCn@Qh*93wq((j{Oj|AB>R23! z5F*p}J^tHVc5XD*dAo8V9JE_F44${Xg&PpPCy_2a21fqP~gQ9 zq2fV-Uq?%gG10iuz@?q?H^ApWX8P@b(@;)U9n|jd|1ke6wn5#(*}Bnas(%gx4&gwm zN?M8~^5%ixkNC(ySRicR9wX>+#vsH30|Y9=2Z4ZNx$j4O)^H0Cdna3$f4vdl@pOE+ zWi%6=D?;QOli*)=K4gAv^uEwRVJI@1Ni$Bj>I6iHXvh87<8EfCdm#(FU>PV&&(uDdvk*xN3%iYI!hzY>vFfNAHNt_n#eM`dgIdqM*E$f-4eXQ$ zAyyJY+wOY{;`C>fQ&_AwOwWe4R1KPTL@SU9%1y-XR%-a9b)(|1#vdTE9mY$0P1cm* zuZBTg+K!FUBSOrSnUZ@>#af$o-tUt8llQyrwO**St2&Q)`rgr7?jd zMakgKH)KY%-6KBQ73ep2GCXnSQ)1~Wx(?7g4zLHpLHap(b6Fq4f-*AJdQM45TRA>a zKinE&LO8LM80BncTD&RKEh}EBL8eW;U0HF#_Iq?JY$mdac&IFUxPI{T0Z7NatdDnb z_5p)5=Sw+PtRAUm{!<;xhCY`sH2dFPQqQVt=!q#*@2~c5FNMBUPtm10qcg&QV{Oq& z96>)48zMh~T$2^<8x+v)`MokVrITH7-Q%c&$L&;@C}U8Ux(67Jf>V8!o{r0?#cyxd z6xMtQG-OK&Q8!xYZ->)Sk4M;ie)C~i+n|(<=<7vFtPeSb#K`?=V~~5Vd0ldV7nwes zezn~%F%Qkro@9xm7oBAJ>q+?gG^ekV%+lDstv)wgZ$8R+_e^EoU^Lpf)Q0)u)KkO| z|1CVqn?K=N5HSzsyKn+mA2u4;J>Zewe$}{>7f^E0SM;j<5@t?MI+&cP&EPs_)6zYg zWac;*lY&z+SGR-eU>UUZ%+{-B25b5$9dC~J4(oj^WQ^96TU&53LmJEbN`WyW_*jx#$sD+K^or(w(eim)iZIuh;snUu#Bh4#3)w*Tc=S zuAFa<(oH%(c)mUfln82nlxj`yT5+oz>fRrtl7@`pk0P6HY4N6??0%ccw@f*i&_45% z(pIqbyIScr?{{7{b-0M^&$^{G2oJSK4t#cR^l_T;^0=n;?cB8me-ys7dg8qS>+j!G zmozI;Xw4+-aF&cJt`w=xU&gX&oD!ZK@-Z;Y@Y{+M9jr6fIP;VBCzRq6=i#Qjs6YQ) z)Rxzi_bzWB56XGb>f5Pz^7Z;Waqy|UZ&r(r*=yc0$_>23;8QiXg4bHAvqCUZncS! zNQ%y~T1AK(M#ow$BE%@7pICjW8WD|Hf8OcYV<}_J&rpFNf<%UK*(g#dFhy{DxJyz% zd6;cFR_gkQC6W_*UzK@=y-T+!2cc3PW697dAO4JthC^AeC>Nnx9&gFssTW>Ac8{Y= zuP6_pUjD+8uhTNTmn@Y-S-in3WD3=Ip|2;q3gK zeGJ)PH1?Mu;1mD1ue5kg*bEhJ3n@@D*lOZygA-Q~T$mml zNryI-ets-h^mL!72gF())EQ}@=+`d3flD1+iKyY%Z+Ooh?)34IQIc{;^XM5C*KVrN zw|Adq&GFbv&g&UyZt~pqhJARu9!;3JpA*xj=d;@)a#wdtuOyOyz(loI&EBflBGE_M z?lmTTzv9wt!2A^jm1JBQ_fF+E)JeOzkV0xXl)9``z(!ZCA?r&rZtlD9m*fLiJZKlL zs{3&S5pY=*<0?bK1JWNldp924mTRd)g^+`?7IgW*k6nuBW>yS`9?J>6dRx*4A|cg( zH>-2?*to>t5$;A+Vwe+zK{$;R|D1W5$pd~x_`4}U@`*8{18}hiT_D= zD;OO5|9t=D<34e^>K%Nv?>=F+D)c^1eZ`rI=Xm8N>ANR(O1s=QE*(2X3RG=sVX$eZ zYK2|?`u>ZX20df&rdrY5& zm(@CQ42A9P1?lGN-(OE&bxxxrA_|lVmt?&HgrM~h|VOi+3n?x5~CFV|Nd$VY# z`NI@eJ603?7nuvS;~g$WyLCdmEESYKdy{kip{p>qRI6Z%(7{<2!X zA`Rf9`<0*ncK>I=PzN@p6W`n0)7_j{5Haz5{nMt^xpa0HN`IlO6}U zG=oDQy72ORfBjRCQ>ufB1`vdRK_Kei1W5s1fZX7xtOpG4UEf5HhL- z1K4EE2NpmcVKz6lUl93aK-Cuc|sLS67g>~bMD;_9lVW9y5Zu-wF%<8A8odq0f zt?vr|o;UvuAyleBkQx|5H-Pf{5HuhBK=}7m{d1Cj8sb+yj9ucMCny_yL` Q4*a~t1cCgq0EYwp2Np_W4gdfE literal 0 HcmV?d00001 diff --git a/docs/chain_validation.txt b/docs/chain_validation.txt new file mode 100644 index 0000000..cc6c20e --- /dev/null +++ b/docs/chain_validation.txt @@ -0,0 +1,120 @@ + +CHAIN VALIDATION + +- cert chain consists of concatenation of certificates (binary/der) +- first is a trusted anchor (optional if embedded: PKI_CHECK_ANCHOR_BY_SHA1=0, + otherwise it needs to be there and is compared to an embedded SHA-1 hash), + second intermediate, third leaf. +- if PKI_APPLE_ROOT_CA=1, the chain is anchored to Apple's root, otherwise a + fake chain that matches all checks. +- check signatures on chain +- check intermediate cert subject CN: Apple Secure Boot Certification Authority +- find spec oid extension in leaf and return pointer to blob in cert chain + memory +- generate digest info from passed in hash and add padding +- verify against signature (digest info || hash || padding) + +DEBUG style builds expose pki menu commands in iBoot that performs validation +and will print failures. + +GENERATE FAKE CHAIN + +# Generate and self-sign test CA +openssl req -newkey rsa:2048 -sha1 -days 365 -sha1 -subj "/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA" -nodes -keyout CA-key.pem -out CA-csr.pem +openssl x509 -req -sha1 -in CA-csr.pem -signkey CA-key.pem -set_serial 0 -out CA-cert.pem -extfile SecureBootCertSpecExtension.txt -extensions CA_default + +# Generate and output request for intermediate +openssl req -newkey rsa:2048 -sha1 -days 365 -sha1 -subj "/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Secure Boot Certification Authority" -nodes -keyout intermediate-key.pem -out intermediate-csr.pem +# Sign intermediate +openssl x509 -req -sha1 -in intermediate-csr.pem -CA CA-cert.pem -CAkey CA-key.pem -set_serial 16 -out intermediate-cert.pem -extfile SecureBootCertSpecExtension.txt -extensions v3_req + +# Generate and output request for test leaf +openssl req -newkey rsa:1024 -sha1 -days 365 -sha1 -subj "/C=US/O=Apple Inc./OU=Apple Secure Boot Certification Authority/CN=S5L8900 Secure Boot" -nodes -out leaf-prod-csr.pem -keyout leaf-prod-key.pem +# Sign leaf +openssl x509 -req -sha1 -in leaf-prod-csr.pem -CA intermediate-cert.pem -CAkey intermediate-key.pem -set_serial 1 -out leaf-prod-cert.pem -extfile SecureBootCertSpecExtension.txt -extensions prod_apple_spec_oid + +# Generate and output request for test leaf +openssl req -newkey rsa:1024 -sha1 -days 365 -sha1 -subj "/C=US/O=Apple Inc./OU=Apple Secure Boot Certification Authority/CN=S5L8900 Secure Boot" -nodes -out leaf-dev-csr.pem -keyout leaf-dev-key.pem +# Sign leaf +openssl x509 -req -sha1 -in leaf-dev-csr.pem -CA intermediate-cert.pem -CAkey intermediate-key.pem -set_serial 2 -out leaf-dev-cert.pem -extfile SecureBootCertSpecExtension.txt -extensions dev_apple_spec_oid + +# convert certs and keys to der +openssl x509 -in CA-cert.pem -outform DER -out CA-cert.der +openssl rsa -in CA-key.pem -outform DER -out CA-key.der +openssl x509 -in intermediate-cert.pem -outform DER -out intermediate-cert.der +openssl x509 -in leaf-prod-cert.pem -outform DER -out leaf-prod-cert.der +openssl x509 -in leaf-dev-cert.pem -outform DER -out leaf-dev-cert.der + +# generate blob and sign with leaf +dd if=/dev/random of=blob bs=1000k count=1 +openssl dgst -binary -sha1 -out blob.sha1 blob +openssl dgst -sign leaf-prod-key.pem -binary -sha1 -out blob-prod.sig blob +openssl dgst -sign leaf-dev-key.pem -binary -sha1 -out blob-dev.sig blob + +# add CA-cert.der to fake_ca.h +openssl x509 -in CA-cert.pem -C > for-fake_ca.h + +# partial chain for verification +cat intermediate-cert.der leaf-dev-cert.der > dev-chain.der +cat intermediate-cert.der leaf-prod-cert.der > prod-chain.der + +# BUILDS=DEBUG iBoot verification +#usb get blob.sha1 0x09001000 +#usb get blob-dev.sig 0x09002000 +#usb get dev-chain.der 0x09003000 +#pki verify 0x09003000 1632 0x09002000 128 0x09001000 20 + +Make sure to add the new root cert to lib/pki/anchor_ca.h and use it in +lib/pki/chain-validation.c. + +SecureBootCertSpecExtension.txt: + +oid_section = new_oids + +[ CA_default ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always +basicConstraints = critical,CA:true +keyUsage = digitalSignature + +[ v3_req ] + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always + +[ new_oids ] +apple_spec_oid=1.2.840.113635.100.6.1.1 + +[ foo_apple_spec_oid ] +1.2.840.113635.100.6.1.1=critical,DER:04:04:46:6f:6f:21 +# Octet (04) Length (04) Value (Foo!) +#apple_spec_oid=critical,DER:FEEDFACE +#apple_spec_oid=critical,ASN1:FORMAT:HEX,OCTETSTRING:FEEDFACE + +[ prod_apple_spec_oid ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always +1.2.840.113635.100.6.1.1=critical,DER:04:24:33:67:6d:49:24:00:00:00:1c:00:00:00:00:00:00:00:2a:2a:2a:2a:44:4f:52:50:10:00:00:00:04:00:00:00:01:00:00:00 + +[ dev_apple_spec_oid ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always +1.2.840.113635.100.6.1.1=critical,DER:04:24:33:67:6d:49:24:00:00:00:1c:00:00:00:00:00:00:00:2a:2a:2a:2a:44:4f:52:50:10:00:00:00:04:00:00:00:00:00:00:00 + +# 0x30 total: Img3, 0x30 skip, 0x1c size, 0x0 no signed data, **** type, +# empty DATA, SMOD 0x0000000000000400 + +# PROD, skip 16, len 4, val 0 => 44:4f:52:50:10:00:00:00:04:00:00:00:00:00:00:00 +# Img3 33:67:6d:49 +# skip 30:00:00:00 +# len 1c:00:00:00 +# lsgn 00:00:00:00 +# type 2a:2a:2a:2a +# DATA 41:54:41:44:0c:00:00:00:00:00:00:00 +# SDOM 4d:4f:44:53:10:00:00:00:04:00:00:00:00:00:00:00 diff --git a/docs/dcs-specs/Elba_Init_A0_July_15_2015.html b/docs/dcs-specs/Elba_Init_A0_July_15_2015.html new file mode 100644 index 0000000..6191695 --- /dev/null +++ b/docs/dcs-specs/Elba_Init_A0_July_15_2015.html @@ -0,0 +1,2948 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Tue Jul 14 10:45:09 2015
AMC Version: 14 Major Release: 2 Minor Release: 0
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/a0.elba/amcc/tb/cfg/static/maqstb_cfg.pl#16
AMP UM Init sourced from: //depot/ip_lib/apple/amp/a0.elba/amp/tb/cfg/phy_helper_fxns.pl#7
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - cpolapra - Files Edited: maqs_gen_cfg.pl#6 - maqs_gen_cfg_c.pl#6 - maqstb_cfg.pl#13 - mcu_helper_fxns.c#8 -
* Fix compile errors from cortex boot
* ------------------------------------------------------------------
* Version:7 - cpolapra - Files Edited: maqstb_cfg.pl#17 - mcu_helper_fxns.c#10 -
* 1600 Mhz mcu init changes
* ------------------------------------------------------------------
* Version:8 - herb - Files Edited: gen_mcu_init.pl#7 -
* amp v0.9.2
* amcx v0.0.10
* amph V0007
* ------------------------------------------------------------------
* Version:9 - thuang - Files Edited: maqstb_cfg.pl#33 -
* add back SPLLCtrl programming now that is resolved
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else
       amcc_MccLockRegion_mccchnldec = 0x00050120
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x1
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3
       slvpll_cp_lp = 0x0
       slvpll_cp_md = 0x0
       slvpll_cp_pd = 0x0
       slvpll_cp_r_set = 0x8
---
+ +
    spllctrl_SpllCtrl_ModeReg(n) = 0x00000001
       override_spll_lock = 0x0
       override_spllseq_outputs = 0x0
       override_value_spll_lock = 0x0
       slvpll_byp = 0x0
       slvpll_mode = 0x1
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000016
       slvpll_vco_buf_pd = 0x0
       slvpll_vco_cap = 0x1
       slvpll_vco_kvco = 0x0
       slvpll_vco_pd = 0x0
       slvpll_vco_rv2i = 0x6
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000015
       slvpll_vco_buf_pd = 0x0
       slvpll_vco_cap = 0x1
       slvpll_vco_kvco = 0x0
       slvpll_vco_pd = 0x0
       slvpll_vco_rv2i = 0x5
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0
       slvpll_reg_pd = 0x0
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0
       spll_mode_dcs_pwrdn = 0x1
       use_idle_for_pd = 0x0
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 132.33Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 132.33Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xde012d02
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x2d
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xde
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0
       freqchngmrw9_ctrl_freq0 = 0x0
       freqchngmrw9_data_freq0 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xd303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xd3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xd303220b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x22
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xd3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000216
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x2
       freqchngmrw9_addr_freq1 = 0x0
       freqchngmrw9_ctrl_freq1 = 0x0
       freqchngmrw9_data_freq1 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0
       freqchngmrw9_ctrl_freq2 = 0x0
       freqchngmrw9_data_freq2 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0
       freqchngmrw9_ctrl_freq3 = 0x0
       freqchngmrw9_data_freq3 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalVREFCodeControl(n) = 0x19191111
       WrDqCalVREFCode_f0 = 0x11
       WrDqCalVREFCode_f1 = 0x11
       WrDqCalVREFCode_f2 = 0x19
       WrDqCalVREFCode_f3 = 0x19
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalVREFCodeControl(n) = 0x19191191
       RdDqCalVREFCode_f0 = 0x91
       RdDqCalVREFCode_f1 = 0x11
       RdDqCalVREFCode_f2 = 0x19
       RdDqCalVREFCode_f3 = 0x19
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFControl(n) = 0x02d0b060
       HWRdDqCalVREFEnable = 0x0
       HWRdDqCalVREFMax = 0xd0
       HWRdDqCalVREFMaxOffsetScaleFactor = 0x2
       HWRdDqCalVREFMaxScoreSel = 0x0
       HWRdDqCalVREFMin = 0xb0
       HWRdDqCalVREFNumPoints = 0x6
       HWRdDqCalVREFScoreMinSel = 0x0
       HWRdDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFOffsetControl1(n) = 0x06040200
       HWRdDqCalOffset0 = 0x0
       HWRdDqCalOffset1 = 0x2
       HWRdDqCalOffset2 = 0x4
       HWRdDqCalOffset3 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFOffsetControl2(n) = 0x00fafcfe
       HWRdDqCalOffset4 = 0xfe
       HWRdDqCalOffset5 = 0xfc
       HWRdDqCalOffset6 = 0xfa
       HWRdDqCalOffset7 = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFControl(n) = 0x02200060
       HWWrDqCalVREFEnable = 0x0
       HWWrDqCalVREFMax = 0x20
       HWWrDqCalVREFMaxOffsetScaleFactor = 0x2
       HWWrDqCalVREFMaxScoreSel = 0x0
       HWWrDqCalVREFMin = 0x0
       HWWrDqCalVREFNumPoints = 0x6
       HWWrDqCalVREFScoreMinSel = 0x0
       HWWrDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFOffsetControl1(n) = 0x06040200
       HWWrDqCalOffset0 = 0x0
       HWWrDqCalOffset1 = 0x2
       HWWrDqCalOffset2 = 0x4
       HWWrDqCalOffset3 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFOffsetControl2(n) = 0x00fafcfe
       HWWrDqCalOffset4 = 0xfe
       HWWrDqCalOffset5 = 0xfc
       HWWrDqCalOffset6 = 0xfa
       HWWrDqCalOffset7 = 0x0
---
+ +
    glbtimer_GlbTimer_PerVrefCalCfg = 0x00000003
       LegacyMode = 0x0
       PreVrefDcc = 0x1
       PreVrefMdll = 0x1
       PreVrefTimCal = 0x0
---
+ +
    glbtimer_GlbTimer_VrefCntrl = 0x00060006
       VrefPointsRd = 0x6
       VrefPointsWr = 0x6
       override_refready = 0x0
---
+ +
    amcx_dramtim_modereg(n) = 0x120c90b8
       tMRRCyc = 0x8
       tMRRICyc = 0xb
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x12
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_rwcfg(n) = 0x000210ef
       CasAPEn = 0x1
       DBIRDEn_freq0 = 0x0
       DBIRDEn_freq1 = 0x1
       DBIRDEn_freq2 = 0x1
       DBIRDEn_freq3 = 0x1
       DBIWREn_freq0 = 0x1
       DBIWREn_freq1 = 0x1
       DBIWREn_freq2 = 0x1
       DBIWREn_freq3 = 0x1
       DBIWRType = 0x0
       tCCDMWCyc = 0x2
else
       amcx_dramcfg_rwcfg(n) = 0x000210ef
          CasAPEn = 0x1
          DBIRDEn_freq0 = 0x0
          DBIRDEn_freq1 = 0x1
          DBIRDEn_freq2 = 0x1
          DBIRDEn_freq3 = 0x1
          DBIWREn_freq0 = 0x1
          DBIWREn_freq1 = 0x1
          DBIWREn_freq2 = 0x1
          DBIWREn_freq3 = 0x1
          DBIWRType = 0x0
          tCCDMWCyc = 0x2
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7
       DllUpdtDur = 0x3
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0
       FreqChangeSDLLUpdDur = 0x50
       SDLLUpdDur = 0x50
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7
       DllUpdtDur = 0x3
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0
       FreqChangeSDLLUpdDur = 0x50
       SDLLUpdDur = 0x50
---
+ +
    amcx_dramtim_pdn(n) = 0x72276265
       tCKECyc = 0x5
       tCKEPDECyc = 0x1
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x7
       tCKb4CKECyc = 0x2
       tXPCyc = 0x6
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-3200 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3
       tDQSCKMinCyc_freq0 = 0x0
       tDQSSMaxCyc_freq0 = 0x1
else
       amcx_dramtim_lat_freq0(n) = 0x00103387
          DRAMRL_freq0 = 0xe
          DRAMWL_freq0 = 0x7
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x0
          tDQSSMaxCyc_freq0 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x0
       tDQSSMaxCyc_freq1 = 0x1
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x0
          tDQSSMaxCyc_freq1 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010d01
       PHYRdLat_freq0 = 0xd
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00060d0c
          PHYRdLat_freq0 = 0xd
          PHYtPhyWrlat_freq0 = 0x6
          PHYtRddataEn_freq0 = 0xc
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010b01
       PHYRdLat_freq1 = 0xb
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050b06
          PHYRdLat_freq1 = 0xb
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
       PHYRdLat_freq2 = 0xb
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
          PHYRdLat_freq2 = 0xb
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
       PHYRdLat_freq3 = 0x9
       PHYtPhyWrlat_freq3 = 0x1
       PHYtRddataEn_freq3 = 0x1
else
       amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
          PHYRdLat_freq3 = 0x9
          PHYtPhyWrlat_freq3 = 0x1
          PHYtRddataEn_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x63e2080f
       tRASCyc_freq0 = 0x22
       tRCDCyc_freq0 = 0xf
       tRTPCyc_freq0 = 0x6
       tWRCyc_freq0 = 0xf
       tWTRCyc_freq0 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x63e2080f
          tRASCyc_freq0 = 0x22
          tRCDCyc_freq0 = 0xf
          tRTPCyc_freq0 = 0x6
          tWRCyc_freq0 = 0xf
          tWTRCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x2008110f
       tFAWCyc_freq0 = 0x20
       tRPCyc_freq0 = 0xf
       tRPabCyc_freq0 = 0x11
       tRRDCyc_freq0 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x2008110f
          tFAWCyc_freq0 = 0x20
          tRPCyc_freq0 = 0xf
          tRPabCyc_freq0 = 0x11
          tRRDCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x48900078
       tRFCBaseCyc_freq0 = 0x78
       tRFCCyc_freq0 = 0x90
       tRFCpbCyc_freq0 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x48900078
          tRFCBaseCyc_freq0 = 0x78
          tRFCCyc_freq0 = 0x90
          tRFCpbCyc_freq0 = 0x48
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0xa0096012
       tFCCyc_freq0 = 0xa0
       tXSRCyc_freq0 = 0x96
       tZQCalCyc_freq0 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12
else
       amcx_dramtim_selfref_freq0(n) = 0xa0096012
          tFCCyc_freq0 = 0xa0
          tXSRCyc_freq0 = 0x96
          tZQCalCyc_freq0 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x1a0cc0f4
       tMRRCyc = 0x4
       tMRRICyc = 0xf
       tMRWCyc = 0xc
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x1a
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060c5024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x5
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x1a0cc0f4
          tMRRCyc = 0x4
          tMRRICyc = 0xf
          tMRWCyc = 0xc
          tVRCGOFFCyc = 0xc
          tZQLatCyc = 0x1a
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x63e2080f
       tRASCyc_freq1 = 0x22
       tRCDCyc_freq1 = 0xf
       tRTPCyc_freq1 = 0x6
       tWRCyc_freq1 = 0xf
       tWTRCyc_freq1 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq1(n) = 0x2008110f
       tFAWCyc_freq1 = 0x20
       tRPCyc_freq1 = 0xf
       tRPabCyc_freq1 = 0x11
       tRRDCyc_freq1 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq1(n) = 0x48900050
       tRFCBaseCyc_freq1 = 0x50
       tRFCCyc_freq1 = 0x90
       tRFCpbCyc_freq1 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0xa0096012
       tFCCyc_freq1 = 0xa0
       tXSRCyc_freq1 = 0x96
       tZQCalCyc_freq1 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x63e2080f
       tRASCyc_freq2 = 0x22
       tRCDCyc_freq2 = 0xf
       tRTPCyc_freq2 = 0x6
       tWRCyc_freq2 = 0xf
       tWTRCyc_freq2 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x2008110f
       tFAWCyc_freq2 = 0x20
       tRPCyc_freq2 = 0xf
       tRPabCyc_freq2 = 0x11
       tRRDCyc_freq2 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x48900014
       tRFCBaseCyc_freq2 = 0x14
       tRFCCyc_freq2 = 0x90
       tRFCpbCyc_freq2 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0xa0096012
       tFCCyc_freq2 = 0xa0
       tXSRCyc_freq2 = 0x96
       tZQCalCyc_freq2 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x03050005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x5
       tRFCpbCyc_freq3 = 0x3
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x28005012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x5
       tZQCalCyc_freq3 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0015005d
       tREFBWtRFCcnt = 0x15
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x612762c6
       tCKECyc = 0x6
       tCKEPDECyc = 0x1
       tCKESRCyc = 0xc
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x6
       tCKb4CKECyc = 0x1
       tXPCyc = 0x6
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21272222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x722762c6
          tCKECyc = 0x6
          tCKEPDECyc = 0x1
          tCKESRCyc = 0xc
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x7
          tCKafCKECyc = 0x7
          tCKb4CKECyc = 0x2
          tXPCyc = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq0 = 0x5
       tRASDrtCyc_freq0 = 0x24
       tRCDDrtCyc_freq0 = 0x10
       tRPDrtCyc_freq0 = 0x10
       tRPabDrtCyc_freq0 = 0x13
       tRRDDrtCyc_freq0 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x4d05a910
          tDQSCKMaxDrtCyc_freq0 = 0x5
          tRASDrtCyc_freq0 = 0x24
          tRCDDrtCyc_freq0 = 0x10
          tRPDrtCyc_freq0 = 0x10
          tRPabDrtCyc_freq0 = 0x13
          tRRDDrtCyc_freq0 = 0xa
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq1 = 0x5
       tRASDrtCyc_freq1 = 0x24
       tRCDDrtCyc_freq1 = 0x10
       tRPDrtCyc_freq1 = 0x10
       tRPabDrtCyc_freq1 = 0x13
       tRRDDrtCyc_freq1 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq2 = 0x5
       tRASDrtCyc_freq2 = 0x24
       tRCDDrtCyc_freq2 = 0x10
       tRPDrtCyc_freq2 = 0x10
       tRPabDrtCyc_freq2 = 0x13
       tRRDDrtCyc_freq2 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00123387
       DRAMRL_freq0 = 0xe
       DRAMWL_freq0 = 0x7
       tDQSCKMaxCyc_freq0 = 0x3
       tDQSCKMinCyc_freq0 = 0x2
       tDQSSMaxCyc_freq0 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1
else
       amcx_dramtim_lat_freq0(n) = 0x00123387
          DRAMRL_freq0 = 0xe
          DRAMWL_freq0 = 0x7
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x2
          tDQSSMaxCyc_freq0 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00123206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x3
       tDQSCKMinCyc_freq1 = 0x2
       tDQSSMaxCyc_freq1 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001230c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x3
       tDQSCKMinCyc_freq2 = 0x2
       tDQSSMaxCyc_freq2 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq0(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq0 = 0x2
       R2rTatDeadCyc_freq0 = 0x1
       R2wRnkMissTatDeadCyc_freq0 = 0x2
       R2wTatDeadCyc_freq0 = 0x4
       W2rRnkMissTatDeadCyc_freq0 = 0x2
       W2wRnkMissTatDeadCyc_freq0 = 0x2
       W2wTatDeadCyc_freq0 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2
       R2rTatDeadCyc_freq0 = 0x1
       R2wRnkMissTatDeadCyc_freq0 = 0x2
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2
       W2wRnkMissTatDeadCyc_freq0 = 0x2
       W2wTatDeadCyc_freq0 = 0x1
else
       amcx_dramtim_tat_freq0(n) = 0x01412222
          R2rRnkMissTatDeadCyc_freq0 = 0x2
          R2rTatDeadCyc_freq0 = 0x1
          R2wRnkMissTatDeadCyc_freq0 = 0x2
          R2wTatDeadCyc_freq0 = 0x4
          W2rRnkMissTatDeadCyc_freq0 = 0x2
          W2wRnkMissTatDeadCyc_freq0 = 0x2
          W2wTatDeadCyc_freq0 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq1(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq1 = 0x2
       R2rTatDeadCyc_freq1 = 0x1
       R2wRnkMissTatDeadCyc_freq1 = 0x2
       R2wTatDeadCyc_freq1 = 0x4
       W2rRnkMissTatDeadCyc_freq1 = 0x2
       W2wRnkMissTatDeadCyc_freq1 = 0x2
       W2wTatDeadCyc_freq1 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2
       R2rTatDeadCyc_freq1 = 0x1
       R2wRnkMissTatDeadCyc_freq1 = 0x2
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2
       W2wRnkMissTatDeadCyc_freq1 = 0x2
       W2wTatDeadCyc_freq1 = 0x1
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2
          R2rTatDeadCyc_freq1 = 0x1
          R2wRnkMissTatDeadCyc_freq1 = 0x2
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2
          W2wRnkMissTatDeadCyc_freq1 = 0x2
          W2wTatDeadCyc_freq1 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq2 = 0x2
       R2rTatDeadCyc_freq2 = 0x1
       R2wRnkMissTatDeadCyc_freq2 = 0x2
       R2wTatDeadCyc_freq2 = 0x4
       W2rRnkMissTatDeadCyc_freq2 = 0x2
       W2wRnkMissTatDeadCyc_freq2 = 0x2
       W2wTatDeadCyc_freq2 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq2(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq2 = 0x2
       R2rTatDeadCyc_freq2 = 0x1
       R2wRnkMissTatDeadCyc_freq2 = 0x2
       R2wTatDeadCyc_freq2 = 0x2
       W2rRnkMissTatDeadCyc_freq2 = 0x2
       W2wRnkMissTatDeadCyc_freq2 = 0x2
       W2wTatDeadCyc_freq2 = 0x1
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2
          R2rTatDeadCyc_freq2 = 0x1
          R2wRnkMissTatDeadCyc_freq2 = 0x2
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2
          W2wRnkMissTatDeadCyc_freq2 = 0x2
          W2wTatDeadCyc_freq2 = 0x1
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x0
       ZqCalIntrvl = 0x0
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0
       SchEn = 0x1
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0
       tPhyUpdGap = 0x0
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amph_CFGH_DCC_BYPCK(n) = 0x00003f3f
       ck_bypass = 0x0
       ck_bypn = 0x3f
       ck_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPCS(n) = 0x00003f3f
       cs_bypass = 0x0
       cs_bypn = 0x3f
       cs_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPB0(n) = 0x00003f3f
       b0_bypass = 0x0
       b0_bypn = 0x3f
       b0_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPDQS0(n) = 0x00003f3f
       dqs0_bypass = 0x0
       dqs0_bypn = 0x3f
       dqs0_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPB1(n) = 0x00003f3f
       b1_bypass = 0x0
       b1_bypn = 0x3f
       b1_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPDQS1(n) = 0x00003f3f
       dqs1_bypass = 0x0
       dqs1_bypn = 0x3f
       dqs1_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPCA(n) = 0x00003f3f
       ca_bypass = 0x0
       ca_bypn = 0x3f
       ca_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPCK(n) = 0x00013f3f
       ck_bypass = 0x1
       ck_bypn = 0x3f
       ck_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPCS(n) = 0x00013f3f
       cs_bypass = 0x1
       cs_bypn = 0x3f
       cs_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPB0(n) = 0x00013f3f
       b0_bypass = 0x1
       b0_bypn = 0x3f
       b0_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPDQS0(n) = 0x00013f3f
       dqs0_bypass = 0x1
       dqs0_bypn = 0x3f
       dqs0_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPB1(n) = 0x00013f3f
       b1_bypass = 0x1
       b1_bypn = 0x3f
       b1_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPDQS1(n) = 0x00013f3f
       dqs1_bypass = 0x1
       dqs1_bypn = 0x3f
       dqs1_bypp = 0x3f
---
+ +
    amph_CFGH_DCC_BYPCA(n) = 0x00013f3f
       ca_bypass = 0x1
       ca_bypn = 0x3f
       ca_bypp = 0x3f
---
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x03030305
       ClkEn2Valid = 0x3
       ReqWaitDelay = 0x5
       Valid2ClkEn = 0x3
       ValidLen = 0x3
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x00030005
       ClkEn2Valid = 0x0
       ReqWaitDelay = 0x5
       Valid2ClkEn = 0x0
       ValidLen = 0x3
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0002
       Rd0RunSDLLUpd = 0x0
       Rd0RunSDLLUpdOverride = 0x1
       Rd0RunSDLLUpdWrResult = 0x0
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdOverride
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x2) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0000
       Rd0RunSDLLUpd = 0x0
       Rd0RunSDLLUpdOverride = 0x0
       Rd0RunSDLLUpdWrResult = 0x0
       Rd0SDLLOvrVal = 0xff
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000002
       WrDqDqsRunSDLLUpd = 0x0
       WrDqDqsRunSDLLUpdOverride = 0x1
       WrDqDqsRunSDLLUpdWrResult = 0x0
       WrDqDqsWrLvlReBalanceEn = 0x0
       WrDqSDLLAddHalfClk_f0 = 0x0
       WrDqSDLLAddHalfClk_f1 = 0x0
       WrDqSDLLAddHalfClk_f2 = 0x0
       WrDqSDLLAddHalfClk_f3 = 0x0
       WrDqSDLLHalfClkEn = 0x0
       WrDqSDLLHalfClkOvrVal = 0x0
       WrDqSDLLHalfClkStatus = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdOverride
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x2) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000000
       WrDqDqsRunSDLLUpd = 0x0
       WrDqDqsRunSDLLUpdOverride = 0x0
       WrDqDqsRunSDLLUpdWrResult = 0x0
       WrDqDqsWrLvlReBalanceEn = 0x0
       WrDqSDLLAddHalfClk_f0 = 0x0
       WrDqSDLLAddHalfClk_f1 = 0x0
       WrDqSDLLAddHalfClk_f2 = 0x0
       WrDqSDLLAddHalfClk_f3 = 0x0
       WrDqSDLLHalfClkEn = 0x0
       WrDqSDLLHalfClkOvrVal = 0x0
       WrDqSDLLHalfClkStatus = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff01ff
       WrLvlMaxWrDqsSDLLCode = 0xff
       WrLvlRunUpdOverride = 0x1
       WrLvlRunUpdWrResult = 0x0
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdOverride
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x100) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff00ff
       WrLvlMaxWrDqsSDLLCode = 0xff
       WrLvlRunUpdOverride = 0x0
       WrLvlRunUpdWrResult = 0x0
       WrLvlSDLLCode = 0xff
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00c801f4
          DllIncLockTim = 0xc8
          DllInitLockTim = 0x1f4
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00c801f4
          DllIncLockTim = 0xc8
          DllInitLockTim = 0x1f4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000410
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000410
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000410
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x06020404
       tCA2CAEntry_f0 = 0x4
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x4
       tCKEHExit_f0 = 0x6
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020402
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020402
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020404
       tCA2CAEntry_f3 = 0x4
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x01040508
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x8
       tWL = 0x5
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x000c0012
       tRdDqCalSegLen = 0x12
       tWrDqCalSegLen = 0xc
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x01040402
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x4
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f3(n) = 0x01040508
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x8
       tWL = 0x5
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x000c0012
       tRdDqCalSegLen = 0x12
       tWrDqCalSegLen = 0xc
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000381e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x38
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x01141101
       tRd2Rd = 0x1
       tRd2Wr = 0x11
       tWr2Rd = 0x14
       tWr2Wr = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55553c5a
       PatInvertMask = 0x5555
       PatPRBS4 = 0x3c5a
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x00003c5a
       PatInvertMask = 0x0
       PatPRBS4 = 0x3c5a
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_0(n) = 0x87654321
       PatPRBS7 = 0x87654321
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_1(n) = 0xcdedcba9
       PatPRBS7 = 0xcdedcba9
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_2(n) = 0x456789ab
       PatPRBS7 = 0x456789ab
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_3(n) = 0x5fa63123
       PatPRBS7 = 0x5fa63123
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatInvertMask(n) = 0x55550000
       PatInvertMask = 0x5555
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00ff01d1
       EndPoint = 0xff
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x00ff0160
       EndPoint = 0xff
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00ff01d1
       EndPoint = 0xff
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x00ff0160
       EndPoint = 0xff
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxRdDqsSDLLMulFactor(n) = 0x00a01414
       MaxRdDqsSDLLCodeStatus = 0xa0 *read-only
       RdDqsSDLLMulFactorF0 = 0x14
       RdDqsSDLLMulFactorF1 = 0x14
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a00c0d
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xd
       WrDqsSDLLMulFactorF1 = 0xc
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000810
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1
          RdCapLat_f0 = 0x10
          RdDatLat_f0 = 0x8
          WrPhaseDelay_f0 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100060a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x6
          WrPhaseDelay_f1 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000408
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1
          RdCapLat_f2 = 0x8
          RdDatLat_f2 = 0x4
          WrPhaseDelay_f2 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000408
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1
          RdCapLat_f3 = 0x8
          RdDatLat_f3 = 0x4
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x80017580
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0
          FreqChangeSDLLUpdDur = 0x80
          SDLLUpdDur = 0x80
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x80017580
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0
          FreqChangeSDLLUpdDur = 0x80
          SDLLUpdDur = 0x80
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1
       DllFastUpdtIntvl = 0x20
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1
       DllFastUpdtIntvl = 0x20
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0
---
+ +
    ampsca_ampscaiocfg_DCCControl(n) = 0x10050b27
       DCCEnable = 0x1
       DCCIdle1Len = 0x27
       DCCIdle2Len = 0x5
       DCCStopClk2Upd = 0x0
       DCCUpdLen = 0xb
---
+ +
    ampsca_ampscaiocfg_DCCTimer(n) = 0x00000190
       DCCTimer = 0x190
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalDynamicHalfClkDelayControl(n) = 0x00000001
       DynamicHalfClkDelayEn = 0x1
---
+ +
    amph_CFGH_CB_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_CB_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CB_IOCTL(n) = 0x00020023
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x0
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       protect_drvstren = 0x1
       sel_rx_ac = 0x0
       sel_rx_dc = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_CK_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_CK_ZDET_BIASEN(n) = 0x00000000
       bias_ena = 0x0
       disable_zdet = 0x0
       sel_zdet = 0x0
---
+ +
    amph_CFGH_CK_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CK_IOCTL(n) = 0x00000027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       sel_rx_ac = 0x0
       sel_rx_dc = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B0_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_B0_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B0_IOCTL(n) = 0x71500027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_B1_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_B1_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B1_IOCTL(n) = 0x71500027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS0_WKPUPD(n) = 0x00000782
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x1
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x1
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x7
---
+ +
    amph_CFGH_DQS0_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS0_IOCTL(n) = 0x71500007
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x0
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_DQS0_ODT(n) = 0x01c00336
       dspd_f0 = 0x6
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS0_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_DQS1_WKPUPD(n) = 0x00000782
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x1
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x1
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x7
---
+ +
    amph_CFGH_DQS1_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS1_IOCTL(n) = 0x71500007
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x0
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_DQS1_ODT(n) = 0x01c00336
       dspd_f0 = 0x6
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS1_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_DBG_DBG_REG0(n) = 0x00000000
       cb_bias_ena = 0x0
       cb_odte = 0x0
       clk_en_sync_flop_rst = 0x0
       mon_vdd_mem = 0x0
       mon_vdd_soc = 0x0
---
+ +
    amph_CFGH_ZC_ZCAL_FSM1(n) = 0x00887f7f
       bias_ena_dly = 0x88
       io_pd = 0x7f *read-only
       io_pu = 0x7f *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM0(n) = 0x000f031b
       zc_dly = 0x1b
       zc_dnbd = 0x0
       zc_tap = 0x3
       zc_upbd = 0xf
---
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x00000016
       control = 0x16
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x06000504
       tCA2CAEntry = 0x4
       tCA2CAExit = 0x0
       tCKEHEntry = 0x5
       tCKEHExit = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCaltVREF(n) = 0x08080808
       HWRdDqCaltVREF_f0 = 0x8
       HWRdDqCaltVREF_f1 = 0x8
       HWRdDqCaltVREF_f2 = 0x8
       HWRdDqCaltVREF_f3 = 0x8
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x0d012019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1
       PhyUpdWaittXSR = 0x0
       PreFreqChngWaitThr = 0x2
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x03050005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x5
       tRFCpbCyc_freq3 = 0x3
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x48900013
       tRFCBaseCyc_freq2 = 0x13
       tRFCCyc_freq2 = 0x90
       tRFCpbCyc_freq2 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq1(n) = 0x48900049
       tRFCBaseCyc_freq1 = 0x49
       tRFCCyc_freq1 = 0x90
       tRFCpbCyc_freq1 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x48900092
       tRFCBaseCyc_freq0 = 0x92
       tRFCCyc_freq0 = 0x90
       tRFCpbCyc_freq0 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x48900092
          tRFCBaseCyc_freq0 = 0x92
          tRFCCyc_freq0 = 0x90
          tRFCpbCyc_freq0 = 0x48
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x002f0013
       tREFBWtRFCcnt = 0x2f
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x0
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x0
          ZqCalIntrvl = 0x0
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01022008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x2
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030004
       FreqCSettleCyc = 0x5
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0
       tPhyUpdGap = 0x4
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x1
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10010000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x0
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x01010000
       freqchngfspop = 0x1
       freqchngfspopupd = 0x0
       freqchngmrwcnt_freq0 = 0x0
       freqchngmrwcnt_freq1 = 0x0
       freqchngmrwcnt_freq2 = 0x0
       freqchngmrwcnt_freq3 = 0x0
       freqchngrunsocupd = 0x1
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x01000000
       freqchngfspop = 0x1
       freqchngfspopupd = 0x0
       freqchngmrwcnt_freq0 = 0x0
       freqchngmrwcnt_freq1 = 0x0
       freqchngmrwcnt_freq2 = 0x0
       freqchngmrwcnt_freq3 = 0x0
       freqchngrunsocupd = 0x0
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x0
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x1
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x1
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ + + + + + +
if (platform == FOUR_CH_ONE_RANK)
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
else if (platform == EIGHT_CH_ONE_RANK)
    glbtimer_GlbTimer_ChEn = 0x000000ff
       ChEn = 0xff
else
       glbtimer_GlbTimer_ChEn = 0x000000ff
          ChEn = 0xff
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0
       MRCmdCs = 0x0
       MRCmdData = 0x4f
       MRCmdIsMPC = 0x1
       MRCmdIsRd = 0x0
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0
       MRCmdCs = 0x0
       MRCmdData = 0x51
       MRCmdIsMPC = 0x1
       MRCmdIsRd = 0x0
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x2
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x1
          MRCmdCs = 0x0
          MRCmdData = 0x8e
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xf3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and modified refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x18
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0xc
          MRCmdCs = 0x0
          MRCmdData = 0x59
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0xe
          MRCmdCs = 0x0
          MRCmdData = 0x59
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x17
          MRCmdCs = 0x0
          MRCmdData = 0x80
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0xf
          MRCmdCs = 0x0
          MRCmdData = 0x55
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x14
          MRCmdCs = 0x0
          MRCmdData = 0x55
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5a204100
          MRCmdAddr = 0x20
          MRCmdCs = 0x0
          MRCmdData = 0x5a
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x3c284100
          MRCmdAddr = 0x28
          MRCmdCs = 0x0
          MRCmdData = 0x3c
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FPGA)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050101
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060101
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060100
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FPGA)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060110
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else
       amcc_MccLockRegion_mccchnldec = 0x00050120
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x1
          NumMcuChnl = 0x2
---
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1 and FSP-OP to 0 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x58
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x2d020100
          MRCmdAddr = 0x2
          MRCmdCs = 0x0
          MRCmdData = 0x2d
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xde010100
          MRCmdAddr = 0x1
          MRCmdCs = 0x0
          MRCmdData = 0xde
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xb3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x4
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x44
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0xc
          MRCmdCs = 0x0
          MRCmdData = 0x11
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0xe
          MRCmdCs = 0x0
          MRCmdData = 0x11
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0
          WrLvlRunUpdWrResult = 0x1
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 28, 14);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0
          ForceDRAMClkEn = 0x0
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0
          ForceMClkWakeUp = 0x0
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0 + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update + +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x1
YesYes-
Poll ampsdqdllctl dllupdtcmd + +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0
          ForceDRAMClkEn = 0x0
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0
          ForceMClkWakeUp = 0x0
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
+ +
       amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
          freqchngmrw2_addr_freq0 = 0xe
          freqchngmrw2_ctrl_freq0 = 0x0
          freqchngmrw2_data_freq0 = 0x11
          freqchngmrw3_addr_freq0 = 0xc
          freqchngmrw3_ctrl_freq0 = 0x0
          freqchngmrw3_data_freq0 = 0x11
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 0, FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x98
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
YesNo-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR + +
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
YesYes-
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x02009999
          freqchngfspop = 0x0
          freqchngfspopupd = 0x1
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0
YesYes-
WrDqDqsSDLLCtrl + +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0
          WrDqDqsRunSDLLUpdOverride = 0x0
          WrDqDqsRunSDLLUpdWrResult = 0x0
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0
          WrDqSDLLAddHalfClk_f1 = 0x0
          WrDqSDLLAddHalfClk_f2 = 0x0
          WrDqSDLLAddHalfClk_f3 = 0x0
          WrDqSDLLHalfClkEn = 0x0
          WrDqSDLLHalfClkOvrVal = 0x0
          WrDqSDLLHalfClkStatus = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 1600Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x1
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 28, 14);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00010782
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0
          idle_active_en_f3 = 0x0
          pdpwk_f0 = 0x1
          pdpwk_f1 = 0x0
          pdpwk_f2 = 0x0
          pdpwk_f3 = 0x1
          pupwk_f0 = 0x0
          pupwk_f1 = 0x0
          pupwk_f2 = 0x0
          pupwk_f3 = 0x0
          wkds = 0x7
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00010782
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0
          idle_active_en_f3 = 0x0
          pdpwk_f0 = 0x1
          pdpwk_f1 = 0x0
          pdpwk_f2 = 0x0
          pdpwk_f3 = 0x1
          pupwk_f0 = 0x0
          pupwk_f1 = 0x0
          pupwk_f2 = 0x0
          pupwk_f3 = 0x0
          wkds = 0x7
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 28, 14);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 28, 14);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 0 and FSP-OP to 1 and reset VRCG

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x900d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x90
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x50
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
---
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0
          WrDqDqsRunSDLLUpdOverride = 0x0
          WrDqDqsRunSDLLUpdWrResult = 0x0
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0
          WrDqSDLLAddHalfClk_f1 = 0x0
          WrDqSDLLAddHalfClk_f2 = 0x0
          WrDqSDLLAddHalfClk_f3 = 0x0
          WrDqSDLLHalfClkEn = 0x0
          WrDqSDLLHalfClkOvrVal = 0x0
          WrDqSDLLHalfClkStatus = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-
RdDqSDLLDelaySel

DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_RdDqSDLLDelaySel(n) = 0x00000000
          RdDqSDLLDelaySel = 0x0
-No-
rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00140004
          Rd0RunSDLLUpd = 0x0
          Rd0RunSDLLUpdOverride = 0x0
          Rd0RunSDLLUpdWrResult = 0x1
          Rd0SDLLOvrVal = 0x14
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


FPGA: Skip this step

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


FPGA: Skip this step

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFControl(n) = 0x02d0b061
       HWRdDqCalVREFEnable = 0x1
       HWRdDqCalVREFMax = 0xd0
       HWRdDqCalVREFMaxOffsetScaleFactor = 0x2
       HWRdDqCalVREFMaxScoreSel = 0x0
       HWRdDqCalVREFMin = 0xb0
       HWRdDqCalVREFNumPoints = 0x6
       HWRdDqCalVREFScoreMinSel = 0x0
       HWRdDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFControl(n) = 0x02200061
       HWWrDqCalVREFEnable = 0x1
       HWWrDqCalVREFMax = 0x20
       HWWrDqCalVREFMaxOffsetScaleFactor = 0x2
       HWWrDqCalVREFMaxScoreSel = 0x0
       HWWrDqCalVREFMin = 0x0
       HWWrDqCalVREFNumPoints = 0x6
       HWWrDqCalVREFScoreMinSel = 0x0
       HWWrDqCalVREFStaticSel = 0x0
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x0d012019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1
       PhyUpdWaittXSR = 0x0
       PreFreqChngWaitThr = 0x2
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10010000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x0
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+ +
    amph_CFGH_B0_DYN_ISEL_ASRTIME(n) = 0x00000019
       rcvr_minisel_assrttime_f0 = 0x19
       rcvr_minisel_assrttime_f1 = 0x0
       rcvr_minisel_assrttime_f2 = 0x0
       rcvr_minisel_assrttime_f3 = 0x0
---
+ +
    amph_CFGH_B0_DYN_ISEL(n) = 0x00000001
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x0
       dyn_isel_ctrl_en_f2 = 0x0
       dyn_isel_ctrl_en_f3 = 0x0
---
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + +
if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00000000
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x0
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x0
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000000a8
          RdCwfEarlyCyc_freq0 = 0x8
          RdCwfEarlyCyc_freq1 = 0x0
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x0
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x0
       SpecRdNum = 0x1
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1
       Mcc0AfDramRdPropQTrakEnbl = 0x0
       Mcc0DpPropQCfg = 0x0
       Mcc0DpPropQCmd = 0x1
       Mcc0DpPropQTrakEnbl = 0x0
       Mcc0MsqQPropCfg = 0x0
       Mcc0MsqQPropQCmd = 0x0
       Mcc0MsqQPropTrakEnbl = 0x0
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1
       Mcc1AfDramRdPropQTrakEnbl = 0x0
       Mcc1DpPropQCfg = 0x0
       Mcc1DpPropQCmd = 0x1
       Mcc1DpPropQTrakEnbl = 0x0
       Mcc1MsqQPropCfg = 0x0
       Mcc1MsqQPropQCmd = 0x0
       Mcc1MsqQPropTrakEnbl = 0x0
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
+ +
    spllctrl_SpllCtrl_MDLLPwrDnCfg0(n) = 0x00000001
       Freq3_en = 0x1
       powergating_en = 0x0
---
disable dynamic power-down. + + + + +
if (platform == FPGA)
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
else
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
---
enable dynamic power-down for cold boot. + + + + +
if (platform == FPGA)
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
else
          amcx_dramcfg_pwrmngten(n) = 0x00000133
             AutoSR = 0x1
             DynPwrDnEn = 0x1
             McPhyUpdDramClkOff = 0x0
             PwrDnClkOff = 0x1
             SRClkOff = 0x1
             SRExitOpt = 0x1
-No-
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000001ff
          DccEn = 0x1
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
YesNo-
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x00f000f0
       PreFreqChng2AllBankDly_f0 = 0xf0
       PreFreqChng2AllBankDly_f1 = 0xf0
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x00f000f0
       PreFreqChng2AllBankDly_f2 = 0xf0
       PreFreqChng2AllBankDly_f3 = 0xf0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02400240
       PreFreqChng2FreqChngDly_f0 = 0x240
       PreFreqChng2FreqChngDly_f1 = 0x240
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02400240
       PreFreqChng2FreqChngDly_f2 = 0x240
       PreFreqChng2FreqChngDly_f3 = 0x240
---
+ +
    glbtimer_GlbTimer_CalSeg2AllBank0 = 0x00fa0120
       CalSeg2AllBank_f0 = 0x120
       CalSeg2AllBank_f1 = 0xfa
---
+ +
    glbtimer_GlbTimer_AllBank2CalSeg0 = 0x00fa0120
       AllBank2CalSeg_f0 = 0x120
       AllBank2CalSeg_f1 = 0xfa
---


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_DCCTimer = 0x00000bb8
          DCCTimerCnt = 0xbb8
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6bb
          RdCalTimerCnt = 0x2dc6bb
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x00000001
          PerCal_FreqChngTimerCnt = 0x1
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
Yes--
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa
       MCUBCGClkGateEn = 0x0
       MCUBCGPwrGateEn = 0x0
       PwrRstCyc = 0x5
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x4
       MRCmdCs = 0x0
       MRCmdData = 0x50
       MRCmdIsMPC = 0x0
       MRCmdIsRd = 0x1
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Elba_Init_B0_Mar_4_2016.html b/docs/dcs-specs/Elba_Init_B0_Mar_4_2016.html new file mode 100644 index 0000000..571daca --- /dev/null +++ b/docs/dcs-specs/Elba_Init_B0_Mar_4_2016.html @@ -0,0 +1,3099 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Fri Mar 4 14:27:59 2016
AMC Version: 14 Major Release: 3 Minor Release: 0
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/trunk.elba/amcc/tb/cfg/static/maqstb_cfg.pl#104
AMP UM Init sourced from: //depot/ip_lib/apple/amp/trunk.elba/amp/tb/cfg/phy_helper_fxns.pl#73
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - cpolapra - Files Edited: maqs_gen_cfg.pl#6 - maqs_gen_cfg_c.pl#6 - maqstb_cfg.pl#13 - mcu_helper_fxns.c#8 -
* Fix compile errors from cortex boot
* ------------------------------------------------------------------
* Version:7 - cpolapra - Files Edited: maqstb_cfg.pl#17 - mcu_helper_fxns.c#10 -
* 1600 Mhz mcu init changes
* ------------------------------------------------------------------
* Version:8 - herb - Files Edited: gen_mcu_init.pl#7 -
* amp v0.9.2
* amcx v0.0.10
* amph V0007
* ------------------------------------------------------------------
* Version:9 - thuang - Files Edited: maqstb_cfg.pl#33 -
* add back SPLLCtrl programming now that is resolved
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x0
       SpecRdNum = 0x1
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1 *read-only
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1 *read-only
       MccStickyEn = 0x1 *read-only
---
program mccgen + +
    amcc_mcccfg_MccGen = 0x00000194
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050120
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x1
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3
       slvpll_cp_lp = 0x0
       slvpll_cp_md = 0x0
       slvpll_cp_pd = 0x0
       slvpll_cp_r_set = 0x8
---
+ +
    spllctrl_SpllCtrl_ModeReg(n) = 0x00000001
       override_spll_lock = 0x0
       override_spllseq_outputs = 0x0
       override_value_spll_lock = 0x0
       slvpll_byp = 0x0
       slvpll_mode = 0x1
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000016
       slvpll_vco_buf_pd = 0x0
       slvpll_vco_cap = 0x1
       slvpll_vco_kvco = 0x0
       slvpll_vco_pd = 0x0
       slvpll_vco_rv2i = 0x6
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000015
       slvpll_vco_buf_pd = 0x0
       slvpll_vco_cap = 0x1
       slvpll_vco_kvco = 0x0
       slvpll_vco_pd = 0x0
       slvpll_vco_rv2i = 0x5
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0
       slvpll_reg_pd = 0x0
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0
       spll_mode_dcs_pwrdn = 0x1
       use_idle_for_pd = 0x0
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 132.33Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 132.33Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xde012d02
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x2d
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xde
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0
       freqchngmrw9_ctrl_freq0 = 0x0
       freqchngmrw9_data_freq0 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xd303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xd3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xd303220b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x22
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xd3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000216
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x2
       freqchngmrw9_addr_freq1 = 0x0
       freqchngmrw9_ctrl_freq1 = 0x0
       freqchngmrw9_data_freq1 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0
       freqchngmrw9_ctrl_freq2 = 0x0
       freqchngmrw9_data_freq2 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0
       freqchngmrw9_ctrl_freq3 = 0x0
       freqchngmrw9_data_freq3 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalVREFCodeControl(n) = 0x19191111
       WrDqCalVREFCode_f0 = 0x11
       WrDqCalVREFCode_f1 = 0x11
       WrDqCalVREFCode_f2 = 0x19
       WrDqCalVREFCode_f3 = 0x19
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalVREFCodeControl(n) = 0x19191191
       RdDqCalVREFCode_f0 = 0x91
       RdDqCalVREFCode_f1 = 0x11
       RdDqCalVREFCode_f2 = 0x19
       RdDqCalVREFCode_f3 = 0x19
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFControl(n) = 0x01d0b060
       HWRdDqCalVREFEnable = 0x0
       HWRdDqCalVREFMax = 0xd0
       HWRdDqCalVREFMaxOffsetScaleFactor = 0x1
       HWRdDqCalVREFMaxScoreSel = 0x0
       HWRdDqCalVREFMin = 0xb0
       HWRdDqCalVREFNumPoints = 0x6
       HWRdDqCalVREFScoreMinSel = 0x0
       HWRdDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFOffsetControl1(n) = 0x06040200
       HWRdDqCalOffset0 = 0x0
       HWRdDqCalOffset1 = 0x2
       HWRdDqCalOffset2 = 0x4
       HWRdDqCalOffset3 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFOffsetControl2(n) = 0x00fafcfe
       HWRdDqCalOffset4 = 0xfe
       HWRdDqCalOffset5 = 0xfc
       HWRdDqCalOffset6 = 0xfa
       HWRdDqCalOffset7 = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFControl(n) = 0x02200060
       HWWrDqCalVREFEnable = 0x0
       HWWrDqCalVREFMax = 0x20
       HWWrDqCalVREFMaxOffsetScaleFactor = 0x2
       HWWrDqCalVREFMaxScoreSel = 0x0
       HWWrDqCalVREFMin = 0x0
       HWWrDqCalVREFNumPoints = 0x6
       HWWrDqCalVREFScoreMinSel = 0x0
       HWWrDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFOffsetControl1(n) = 0x06040200
       HWWrDqCalOffset0 = 0x0
       HWWrDqCalOffset1 = 0x2
       HWWrDqCalOffset2 = 0x4
       HWWrDqCalOffset3 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFOffsetControl2(n) = 0x00fafcfe
       HWWrDqCalOffset4 = 0xfe
       HWWrDqCalOffset5 = 0xfc
       HWWrDqCalOffset6 = 0xfa
       HWWrDqCalOffset7 = 0x0
---
+ +
    glbtimer_GlbTimer_PerVrefCalCfg = 0x00000003
       LegacyMode = 0x0
       PreVrefDcc = 0x1
       PreVrefMdll = 0x1
       PreVrefTimCal = 0x0
---
+ +
    glbtimer_GlbTimer_VrefCntrl = 0x00060006
       VrefPointsRd = 0x6
       VrefPointsWr = 0x6
       override_refready = 0x0
---
+ +
    amcx_dramtim_modereg(n) = 0x120c90b8
       tMRRCyc = 0x8
       tMRRICyc = 0xb
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x12
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7
       DllUpdtDur = 0x3
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0
       FreqChangeSDLLUpdDur = 0x50
       SDLLUpdDur = 0x50
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7
       DllUpdtDur = 0x3
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0
       FreqChangeSDLLUpdDur = 0x50
       SDLLUpdDur = 0x50
---
+ +
    amcx_dramtim_pdn(n) = 0x72276265
       tCKECyc = 0x5
       tCKEPDECyc = 0x1
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x7
       tCKb4CKECyc = 0x2
       tXPCyc = 0x6
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-3200 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3
       tDQSCKMinCyc_freq0 = 0x0
       tDQSSMaxCyc_freq0 = 0x1
else
       amcx_dramtim_lat_freq0(n) = 0x00103387
          DRAMRL_freq0 = 0xe
          DRAMWL_freq0 = 0x7
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x0
          tDQSSMaxCyc_freq0 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x0
       tDQSSMaxCyc_freq1 = 0x1
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x0
          tDQSSMaxCyc_freq1 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010d01
       PHYRdLat_freq0 = 0xd
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00060d0c
          PHYRdLat_freq0 = 0xd
          PHYtPhyWrlat_freq0 = 0x6
          PHYtRddataEn_freq0 = 0xc
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010b01
       PHYRdLat_freq1 = 0xb
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050b06
          PHYRdLat_freq1 = 0xb
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
       PHYRdLat_freq2 = 0xb
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
          PHYRdLat_freq2 = 0xb
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
       PHYRdLat_freq3 = 0x9
       PHYtPhyWrlat_freq3 = 0x1
       PHYtRddataEn_freq3 = 0x1
else
       amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
          PHYRdLat_freq3 = 0x9
          PHYtPhyWrlat_freq3 = 0x1
          PHYtRddataEn_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x63e2080f
       tRASCyc_freq0 = 0x22
       tRCDCyc_freq0 = 0xf
       tRTPCyc_freq0 = 0x6
       tWRCyc_freq0 = 0xf
       tWTRCyc_freq0 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x63e2080f
          tRASCyc_freq0 = 0x22
          tRCDCyc_freq0 = 0xf
          tRTPCyc_freq0 = 0x6
          tWRCyc_freq0 = 0xf
          tWTRCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x2008110f
       tFAWCyc_freq0 = 0x20
       tRPCyc_freq0 = 0xf
       tRPabCyc_freq0 = 0x11
       tRRDCyc_freq0 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x2008110f
          tFAWCyc_freq0 = 0x20
          tRPCyc_freq0 = 0xf
          tRPabCyc_freq0 = 0x11
          tRRDCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x48900078
       tRFCBaseCyc_freq0 = 0x78
       tRFCCyc_freq0 = 0x90
       tRFCpbCyc_freq0 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x48900078
          tRFCBaseCyc_freq0 = 0x78
          tRFCCyc_freq0 = 0x90
          tRFCpbCyc_freq0 = 0x48
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0xa0096012
       tFCCyc_freq0 = 0xa0
       tXSRCyc_freq0 = 0x96
       tZQCalCyc_freq0 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12
else
       amcx_dramtim_selfref_freq0(n) = 0xa0096012
          tFCCyc_freq0 = 0xa0
          tXSRCyc_freq0 = 0x96
          tZQCalCyc_freq0 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x1a0cc0f4
       tMRRCyc = 0x4
       tMRRICyc = 0xf
       tMRWCyc = 0xc
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x1a
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060c5024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x5
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x1a0cc0f4
          tMRRCyc = 0x4
          tMRRICyc = 0xf
          tMRWCyc = 0xc
          tVRCGOFFCyc = 0xc
          tZQLatCyc = 0x1a
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x63e2080f
       tRASCyc_freq1 = 0x22
       tRCDCyc_freq1 = 0xf
       tRTPCyc_freq1 = 0x6
       tWRCyc_freq1 = 0xf
       tWTRCyc_freq1 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq1(n) = 0x2008110f
       tFAWCyc_freq1 = 0x20
       tRPCyc_freq1 = 0xf
       tRPabCyc_freq1 = 0x11
       tRRDCyc_freq1 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq1(n) = 0x48900050
       tRFCBaseCyc_freq1 = 0x50
       tRFCCyc_freq1 = 0x90
       tRFCpbCyc_freq1 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0xa0096012
       tFCCyc_freq1 = 0xa0
       tXSRCyc_freq1 = 0x96
       tZQCalCyc_freq1 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x63e2080f
       tRASCyc_freq2 = 0x22
       tRCDCyc_freq2 = 0xf
       tRTPCyc_freq2 = 0x6
       tWRCyc_freq2 = 0xf
       tWTRCyc_freq2 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x2008110f
       tFAWCyc_freq2 = 0x20
       tRPCyc_freq2 = 0xf
       tRPabCyc_freq2 = 0x11
       tRRDCyc_freq2 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x48900014
       tRFCBaseCyc_freq2 = 0x14
       tRFCCyc_freq2 = 0x90
       tRFCpbCyc_freq2 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0xa0096012
       tFCCyc_freq2 = 0xa0
       tXSRCyc_freq2 = 0x96
       tZQCalCyc_freq2 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x03050005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x5
       tRFCpbCyc_freq3 = 0x3
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x28005012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x5
       tZQCalCyc_freq3 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0015005d
       tREFBWtRFCcnt = 0x15
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x612762c6
       tCKECyc = 0x6
       tCKEPDECyc = 0x1
       tCKESRCyc = 0xc
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x6
       tCKb4CKECyc = 0x1
       tXPCyc = 0x6
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21272222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x722762c6
          tCKECyc = 0x6
          tCKEPDECyc = 0x1
          tCKESRCyc = 0xc
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x7
          tCKafCKECyc = 0x7
          tCKb4CKECyc = 0x2
          tXPCyc = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq0 = 0x5
       tRASDrtCyc_freq0 = 0x24
       tRCDDrtCyc_freq0 = 0x10
       tRPDrtCyc_freq0 = 0x10
       tRPabDrtCyc_freq0 = 0x13
       tRRDDrtCyc_freq0 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x4d05a910
          tDQSCKMaxDrtCyc_freq0 = 0x5
          tRASDrtCyc_freq0 = 0x24
          tRCDDrtCyc_freq0 = 0x10
          tRPDrtCyc_freq0 = 0x10
          tRPabDrtCyc_freq0 = 0x13
          tRRDDrtCyc_freq0 = 0xa
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq1 = 0x5
       tRASDrtCyc_freq1 = 0x24
       tRCDDrtCyc_freq1 = 0x10
       tRPDrtCyc_freq1 = 0x10
       tRPabDrtCyc_freq1 = 0x13
       tRRDDrtCyc_freq1 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq2 = 0x5
       tRASDrtCyc_freq2 = 0x24
       tRCDDrtCyc_freq2 = 0x10
       tRPDrtCyc_freq2 = 0x10
       tRPabDrtCyc_freq2 = 0x13
       tRRDDrtCyc_freq2 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00123387
       DRAMRL_freq0 = 0xe
       DRAMWL_freq0 = 0x7
       tDQSCKMaxCyc_freq0 = 0x3
       tDQSCKMinCyc_freq0 = 0x2
       tDQSSMaxCyc_freq0 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1
else
       amcx_dramtim_lat_freq0(n) = 0x00123387
          DRAMRL_freq0 = 0xe
          DRAMWL_freq0 = 0x7
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x2
          tDQSSMaxCyc_freq0 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00123206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x3
       tDQSCKMinCyc_freq1 = 0x2
       tDQSSMaxCyc_freq1 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001230c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x3
       tDQSCKMinCyc_freq2 = 0x2
       tDQSSMaxCyc_freq2 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq0(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq0 = 0x2
       R2rTatDeadCyc_freq0 = 0x1
       R2wRnkMissTatDeadCyc_freq0 = 0x2
       R2wTatDeadCyc_freq0 = 0x4
       W2rRnkMissTatDeadCyc_freq0 = 0x2
       W2wRnkMissTatDeadCyc_freq0 = 0x2
       W2wTatDeadCyc_freq0 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2
       R2rTatDeadCyc_freq0 = 0x1
       R2wRnkMissTatDeadCyc_freq0 = 0x2
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2
       W2wRnkMissTatDeadCyc_freq0 = 0x2
       W2wTatDeadCyc_freq0 = 0x1
else
       amcx_dramtim_tat_freq0(n) = 0x01412222
          R2rRnkMissTatDeadCyc_freq0 = 0x2
          R2rTatDeadCyc_freq0 = 0x1
          R2wRnkMissTatDeadCyc_freq0 = 0x2
          R2wTatDeadCyc_freq0 = 0x4
          W2rRnkMissTatDeadCyc_freq0 = 0x2
          W2wRnkMissTatDeadCyc_freq0 = 0x2
          W2wTatDeadCyc_freq0 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq1(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq1 = 0x2
       R2rTatDeadCyc_freq1 = 0x1
       R2wRnkMissTatDeadCyc_freq1 = 0x2
       R2wTatDeadCyc_freq1 = 0x4
       W2rRnkMissTatDeadCyc_freq1 = 0x2
       W2wRnkMissTatDeadCyc_freq1 = 0x2
       W2wTatDeadCyc_freq1 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2
       R2rTatDeadCyc_freq1 = 0x1
       R2wRnkMissTatDeadCyc_freq1 = 0x2
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2
       W2wRnkMissTatDeadCyc_freq1 = 0x2
       W2wTatDeadCyc_freq1 = 0x1
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2
          R2rTatDeadCyc_freq1 = 0x1
          R2wRnkMissTatDeadCyc_freq1 = 0x2
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2
          W2wRnkMissTatDeadCyc_freq1 = 0x2
          W2wTatDeadCyc_freq1 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq2 = 0x2
       R2rTatDeadCyc_freq2 = 0x1
       R2wRnkMissTatDeadCyc_freq2 = 0x2
       R2wTatDeadCyc_freq2 = 0x4
       W2rRnkMissTatDeadCyc_freq2 = 0x2
       W2wRnkMissTatDeadCyc_freq2 = 0x2
       W2wTatDeadCyc_freq2 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq2(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq2 = 0x2
       R2rTatDeadCyc_freq2 = 0x1
       R2wRnkMissTatDeadCyc_freq2 = 0x2
       R2wTatDeadCyc_freq2 = 0x2
       W2rRnkMissTatDeadCyc_freq2 = 0x2
       W2wRnkMissTatDeadCyc_freq2 = 0x2
       W2wTatDeadCyc_freq2 = 0x1
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2
          R2rTatDeadCyc_freq2 = 0x1
          R2wRnkMissTatDeadCyc_freq2 = 0x2
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2
          W2wRnkMissTatDeadCyc_freq2 = 0x2
          W2wTatDeadCyc_freq2 = 0x1
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x0
       ZqCalIntrvl = 0x0
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0
       SchEn = 0x1
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0
       tPhyUpdGap = 0x0
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x03030305
       ClkEn2Valid = 0x3
       ReqWaitDelay = 0x5
       Valid2ClkEn = 0x3
       ValidLen = 0x3
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x00030005
       ClkEn2Valid = 0x0
       ReqWaitDelay = 0x5
       Valid2ClkEn = 0x0
       ValidLen = 0x3
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0002
       Rd0RunSDLLUpd = 0x0
       Rd0RunSDLLUpdOverride = 0x1
       Rd0RunSDLLUpdWrResult = 0x0
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdOverride
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x2) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0000
       Rd0RunSDLLUpd = 0x0
       Rd0RunSDLLUpdOverride = 0x0
       Rd0RunSDLLUpdWrResult = 0x0
       Rd0SDLLOvrVal = 0xff
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000002
       WrDqDqsRunSDLLUpd = 0x0
       WrDqDqsRunSDLLUpdOverride = 0x1
       WrDqDqsRunSDLLUpdWrResult = 0x0
       WrDqDqsWrLvlReBalanceEn = 0x0
       WrDqSDLLAddHalfClk_f0 = 0x0
       WrDqSDLLAddHalfClk_f1 = 0x0
       WrDqSDLLAddHalfClk_f2 = 0x0
       WrDqSDLLAddHalfClk_f3 = 0x0
       WrDqSDLLHalfClkEn = 0x0
       WrDqSDLLHalfClkOvrVal = 0x0
       WrDqSDLLHalfClkStatus = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdOverride
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x2) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000000
       WrDqDqsRunSDLLUpd = 0x0
       WrDqDqsRunSDLLUpdOverride = 0x0
       WrDqDqsRunSDLLUpdWrResult = 0x0
       WrDqDqsWrLvlReBalanceEn = 0x0
       WrDqSDLLAddHalfClk_f0 = 0x0
       WrDqSDLLAddHalfClk_f1 = 0x0
       WrDqSDLLAddHalfClk_f2 = 0x0
       WrDqSDLLAddHalfClk_f3 = 0x0
       WrDqSDLLHalfClkEn = 0x0
       WrDqSDLLHalfClkOvrVal = 0x0
       WrDqSDLLHalfClkStatus = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff01ff
       WrLvlMaxWrDqsSDLLCode = 0xff
       WrLvlRunUpdOverride = 0x1
       WrLvlRunUpdWrResult = 0x0
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdOverride
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x100) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff00ff
       WrLvlMaxWrDqsSDLLCode = 0xff
       WrLvlRunUpdOverride = 0x0
       WrLvlRunUpdWrResult = 0x0
       WrLvlSDLLCode = 0xff
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00c801f4
          DllIncLockTim = 0xc8
          DllInitLockTim = 0x1f4
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00c801f4
          DllIncLockTim = 0xc8
          DllInitLockTim = 0x1f4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000710
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x7
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000710
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x7
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000510
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x5
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x06020704
       tCA2CAEntry_f0 = 0x4
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x7
       tCKEHExit_f0 = 0x6
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020702
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x7
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020702
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x7
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020504
       tCA2CAEntry_f3 = 0x4
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x5
       tCKEHExit_f3 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_RdDqCal2(n) = 0x00000019
       RdDqCal_FullScan_Wait_CKEHigh = 0x19
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x01040508
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x8
       tWL = 0x5
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00040008
       tRdDqCalSegLen = 0x8
       tWrDqCalSegLen = 0x4
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x01040402
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x4
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f3(n) = 0x01040508
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x8
       tWL = 0x5
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x000c0012
       tRdDqCalSegLen = 0x12
       tWrDqCalSegLen = 0xc
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000381e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x38
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x01141101
       tRd2Rd = 0x1
       tRd2Wr = 0x11
       tWr2Rd = 0x14
       tWr2Wr = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55553c5a
       PatInvertMask = 0x5555
       PatPRBS4 = 0x3c5a
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x00003c5a
       PatInvertMask = 0x0
       PatPRBS4 = 0x3c5a
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_0(n) = 0x87654321
       PatPRBS7 = 0x87654321
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_1(n) = 0xcdedcba9
       PatPRBS7 = 0xcdedcba9
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_2(n) = 0x456789ab
       PatPRBS7 = 0x456789ab
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_3(n) = 0x5fa63123
       PatPRBS7 = 0x5fa63123
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatInvertMask(n) = 0x55550000
       PatInvertMask = 0x5555
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00ff01d1
       EndPoint = 0xff
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x00ff0160
       EndPoint = 0xff
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00ff01d1
       EndPoint = 0xff
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x00ff0160
       EndPoint = 0xff
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxRdDqsSDLLMulFactor(n) = 0x00a01414
       MaxRdDqsSDLLCodeStatus = 0xa0 *read-only
       RdDqsSDLLMulFactorF0 = 0x14
       RdDqsSDLLMulFactorF1 = 0x14
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a00c0d
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xd
       WrDqsSDLLMulFactorF1 = 0xc
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000810
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1
          RdCapLat_f0 = 0x10
          RdDatLat_f0 = 0x8
          WrPhaseDelay_f0 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100060a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x6
          WrPhaseDelay_f1 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000408
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1
          RdCapLat_f2 = 0x8
          RdDatLat_f2 = 0x4
          WrPhaseDelay_f2 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000408
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1
          RdCapLat_f3 = 0x8
          RdDatLat_f3 = 0x4
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x80017580
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0
          FreqChangeSDLLUpdDur = 0x80
          SDLLUpdDur = 0x80
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x80017580
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0
          FreqChangeSDLLUpdDur = 0x80
          SDLLUpdDur = 0x80
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1
       DllFastUpdtIntvl = 0x20
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1
       DllFastUpdtIntvl = 0x20
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0
---
+ +
    ampsca_ampscaiocfg_DCCControl(n) = 0x10050b27
       DCCEnable = 0x1
       DCCIdle1Len = 0x27
       DCCIdle2Len = 0x5
       DCCStopClk2Upd = 0x0
       DCCUpdLen = 0xb
---
+ +
    ampsca_ampscaiocfg_DCCTimer(n) = 0x00000190
       DCCTimer = 0x190
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalDynamicHalfClkDelayControl(n) = 0x00000001
       DynamicHalfClkDelayEn = 0x1
---
+ +
    amph_CFGH_CB_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_CB_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CB_IOCTL(n) = 0x00020023
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x0
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       protect_drvstren = 0x1
       sel_rx_ac = 0x0
       sel_rx_dc = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_CK_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_CK_ZDET_BIASEN(n) = 0x00000000
       bias_ena = 0x0
       disable_zdet = 0x0
       sel_zdet = 0x0
---
+ +
    amph_CFGH_CK_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CK_IOCTL(n) = 0x00000027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       sel_rx_ac = 0x0
       sel_rx_dc = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B0_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_B0_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B0_IOCTL(n) = 0x71500027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_B1_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_B1_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B1_IOCTL(n) = 0x71500027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS0_WKPUPD(n) = 0x00000782
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x1
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x1
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x7
---
+ +
    amph_CFGH_DQS0_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS0_IOCTL(n) = 0x71500007
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x0
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_DQS0_ODT(n) = 0x01c00336
       dspd_f0 = 0x6
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS0_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_DQS1_WKPUPD(n) = 0x00000782
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x1
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x1
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x7
---
+ +
    amph_CFGH_DQS1_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS1_IOCTL(n) = 0x71500007
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x0
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_DQS1_ODT(n) = 0x01c00336
       dspd_f0 = 0x6
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS1_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_DBG_DBG_REG0(n) = 0x00000000
       cb_bias_ena = 0x0
       cb_odte = 0x0
       clk_en_sync_flop_rst = 0x0
       mon_vdd_mem = 0x0
       mon_vdd_soc = 0x0
---
+ +
    amph_CFGH_ZC_ZCAL_FSM1(n) = 0x00887f7f
       bias_ena_dly = 0x88
       io_pd = 0x7f *read-only
       io_pu = 0x7f *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM0(n) = 0x000f031b
       zc_dly = 0x1b
       zc_dnbd = 0x0
       zc_tap = 0x3
       zc_upbd = 0xf
---
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x00000816
       control = 0x816
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x06001604
       tCA2CAEntry = 0x4
       tCA2CAExit = 0x0
       tCKEHEntry = 0x16
       tCKEHExit = 0x6
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x06021604
       tCA2CAEntry_f0 = 0x4
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x16
       tCKEHExit_f0 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCaltVREF(n) = 0x08080808
       HWRdDqCaltVREF_f0 = 0x8
       HWRdDqCaltVREF_f1 = 0x8
       HWRdDqCaltVREF_f2 = 0x8
       HWRdDqCaltVREF_f3 = 0x8
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x0d012019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1
       PhyUpdWaittXSR = 0x0
       PreFreqChngWaitThr = 0x2
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x03050005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x5
       tRFCpbCyc_freq3 = 0x3
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x48900013
       tRFCBaseCyc_freq2 = 0x13
       tRFCCyc_freq2 = 0x90
       tRFCpbCyc_freq2 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq1(n) = 0x48900049
       tRFCBaseCyc_freq1 = 0x49
       tRFCCyc_freq1 = 0x90
       tRFCpbCyc_freq1 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x48900092
       tRFCBaseCyc_freq0 = 0x92
       tRFCCyc_freq0 = 0x90
       tRFCpbCyc_freq0 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x48900092
          tRFCBaseCyc_freq0 = 0x92
          tRFCCyc_freq0 = 0x90
          tRFCpbCyc_freq0 = 0x48
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x002f0013
       tREFBWtRFCcnt = 0x2f
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x0
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x0
          ZqCalIntrvl = 0x0
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01022008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x2
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030004
       FreqCSettleCyc = 0x5
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0
       tPhyUpdGap = 0x4
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x1
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10010000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x0
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x01010000
       freqchngfspop = 0x1
       freqchngfspopupd = 0x0
       freqchngmrwcnt_freq0 = 0x0
       freqchngmrwcnt_freq1 = 0x0
       freqchngmrwcnt_freq2 = 0x0
       freqchngmrwcnt_freq3 = 0x0
       freqchngrunsocupd = 0x1
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x01000000
       freqchngfspop = 0x1
       freqchngfspopupd = 0x0
       freqchngmrwcnt_freq0 = 0x0
       freqchngmrwcnt_freq1 = 0x0
       freqchngmrwcnt_freq2 = 0x0
       freqchngmrwcnt_freq3 = 0x0
       freqchngrunsocupd = 0x0
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x0
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x1
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x1
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ + + + + + +
if (platform == FOUR_CH_ONE_RANK)
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
else if (platform == EIGHT_CH_ONE_RANK)
    glbtimer_GlbTimer_ChEn = 0x000000ff
       ChEn = 0xff
else
       glbtimer_GlbTimer_ChEn = 0x000000ff
          ChEn = 0xff
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0
       MRCmdCs = 0x0
       MRCmdData = 0x4f
       MRCmdIsMPC = 0x1
       MRCmdIsRd = 0x0
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0
       MRCmdCs = 0x0
       MRCmdData = 0x51
       MRCmdIsMPC = 0x1
       MRCmdIsRd = 0x0
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x2
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x1
          MRCmdCs = 0x0
          MRCmdData = 0x8e
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xf3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and modified refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x18
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0xc
          MRCmdCs = 0x0
          MRCmdData = 0x59
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0xe
          MRCmdCs = 0x0
          MRCmdData = 0x59
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x17
          MRCmdCs = 0x0
          MRCmdData = 0x80
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0xf
          MRCmdCs = 0x0
          MRCmdData = 0x55
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x14
          MRCmdCs = 0x0
          MRCmdData = 0x55
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5a204100
          MRCmdAddr = 0x20
          MRCmdCs = 0x0
          MRCmdData = 0x5a
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x3c284100
          MRCmdAddr = 0x28
          MRCmdCs = 0x0
          MRCmdData = 0x3c
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FPGA)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050101
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060101
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060100
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FPGA)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060110
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050120
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x1
          NumMcuChnl = 0x2
---


SAMSUNG: Perform this step
+ +
       ampsdq_ampsdqodt_VRef_f0(n) = 0x00d800d8
          DqsVRefSel = 0xd8
          VRefSel = 0xd8
-No-


SAMSUNG: Perform this step
+ +
       ampsdq_ampsdqodt_VRef_f1(n) = 0x00d800d8
          DqsVRefSel = 0xd8
          VRefSel = 0xd8
-No-


SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf2030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xf2
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x4f004100
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x4f
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x51004100
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x51
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 20ns for tZQLAT. +
---


SAMSUNG: Perform this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x0
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
else
          amcx_dramcfg_freqchngctl2_freq0(n) = 0xb203330b
             freqchngmrw4_addr_freq0 = 0xb
             freqchngmrw4_ctrl_freq0 = 0x0
             freqchngmrw4_data_freq0 = 0x33
             freqchngmrw5_addr_freq0 = 0x3
             freqchngmrw5_ctrl_freq0 = 0x0
             freqchngmrw5_data_freq0 = 0xb2
-No-


SAMSUNG: Perform this step
+ +
       amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000316
          freqchngmrw8_addr_freq0 = 0x16
          freqchngmrw8_ctrl_freq0 = 0x0
          freqchngmrw8_data_freq0 = 0x3
          freqchngmrw9_addr_freq0 = 0x0
          freqchngmrw9_ctrl_freq0 = 0x0
          freqchngmrw9_data_freq0 = 0x0
-No-


SAMSUNG: Perform this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
else
          amcx_dramcfg_freqchngctl2_freq3(n) = 0xf203000b
             freqchngmrw4_addr_freq3 = 0xb
             freqchngmrw4_ctrl_freq3 = 0x0
             freqchngmrw4_data_freq3 = 0x0
             freqchngmrw5_addr_freq3 = 0x3
             freqchngmrw5_ctrl_freq3 = 0x0
             freqchngmrw5_data_freq3 = 0xf2
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_CB_IMPCTL(n) = 0x01001c2b
          en160_tx_f0 = 0x0
          en160_tx_f1 = 0x0
          en160_tx_f2 = 0x0
          en160_tx_f3 = 0x0
          en160pd_tx_f0 = 0x1
          en160pd_tx_f1 = 0x0
          en160pd_tx_f2 = 0x0
          en160pd_tx_f3 = 0x0
          zcpd_ovrr = 0x1c
          zcpu_ovrr = 0x2b
          zcpu_pd_ovrr = 0x0
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_B0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_B1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_DQS0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_DQS1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1 and FSP-OP to 0 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x58
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x2d020100
          MRCmdAddr = 0x2
          MRCmdCs = 0x0
          MRCmdData = 0x2d
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xde010100
          MRCmdAddr = 0x1
          MRCmdCs = 0x0
          MRCmdData = 0xde
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Skip this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xb3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Skip this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Perform this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb2030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xb2
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x4
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x03160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Skip this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x44
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Skip this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Perform this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x330b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x33
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0xc
          MRCmdCs = 0x0
          MRCmdData = 0x11
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0xe
          MRCmdCs = 0x0
          MRCmdData = 0x11
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0
          WrLvlRunUpdWrResult = 0x1
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 28, 14);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0
          ForceDRAMClkEn = 0x0
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0
          ForceMClkWakeUp = 0x0
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0 + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update + +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x1
YesYes-
Poll ampsdqdllctl dllupdtcmd + +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0
          ForceDRAMClkEn = 0x0
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0
          ForceMClkWakeUp = 0x0
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
          freqchngmrw2_addr_freq0 = 0xe
          freqchngmrw2_ctrl_freq0 = 0x0
          freqchngmrw2_data_freq0 = 0x11
          freqchngmrw3_addr_freq0 = 0xc
          freqchngmrw3_ctrl_freq0 = 0x0
          freqchngmrw3_data_freq0 = 0x11
YesYes-


FPGA: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x0
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
else
          amcx_dramcfg_freqchngctl2_freq0(n) = 0xb203330b
             freqchngmrw4_addr_freq0 = 0xb
             freqchngmrw4_ctrl_freq0 = 0x0
             freqchngmrw4_data_freq0 = 0x33
             freqchngmrw5_addr_freq0 = 0x3
             freqchngmrw5_ctrl_freq0 = 0x0
             freqchngmrw5_data_freq0 = 0xb2
YesYes-


FPGA: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
else
          amcx_dramcfg_freqchngctl2_freq3(n) = 0xf203000b
             freqchngmrw4_addr_freq3 = 0xb
             freqchngmrw4_ctrl_freq3 = 0x0
             freqchngmrw4_data_freq3 = 0x0
             freqchngmrw5_addr_freq3 = 0x3
             freqchngmrw5_ctrl_freq3 = 0x0
             freqchngmrw5_data_freq3 = 0xf2
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000316
          freqchngmrw8_addr_freq0 = 0x16
          freqchngmrw8_ctrl_freq0 = 0x0
          freqchngmrw8_data_freq0 = 0x3
          freqchngmrw9_addr_freq0 = 0x0
          freqchngmrw9_ctrl_freq0 = 0x0
          freqchngmrw9_data_freq0 = 0x0
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x00061a80
          ZQCTimerCnt = 0x61a80
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_CB_IMPCTL(n) = 0x01001c2b
          en160_tx_f0 = 0x0
          en160_tx_f1 = 0x0
          en160_tx_f2 = 0x0
          en160_tx_f3 = 0x0
          en160pd_tx_f0 = 0x1
          en160pd_tx_f1 = 0x0
          en160pd_tx_f2 = 0x0
          en160pd_tx_f3 = 0x0
          zcpd_ovrr = 0x1c
          zcpu_ovrr = 0x2b
          zcpu_pd_ovrr = 0x0
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_B0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_B1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_DQS0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_DQS1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 0, FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x98
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
YesNo-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR + +
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
YesYes-
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x02009999
          freqchngfspop = 0x0
          freqchngfspopupd = 0x1
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0
YesYes-
WrDqDqsSDLLCtrl + +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0
          WrDqDqsRunSDLLUpdOverride = 0x0
          WrDqDqsRunSDLLUpdWrResult = 0x0
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0
          WrDqSDLLAddHalfClk_f1 = 0x0
          WrDqSDLLAddHalfClk_f2 = 0x0
          WrDqSDLLAddHalfClk_f3 = 0x0
          WrDqSDLLHalfClkEn = 0x0
          WrDqSDLLHalfClkOvrVal = 0x0
          WrDqSDLLHalfClkStatus = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 1600Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x1
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 28, 14);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00010782
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0
          idle_active_en_f3 = 0x0
          pdpwk_f0 = 0x1
          pdpwk_f1 = 0x0
          pdpwk_f2 = 0x0
          pdpwk_f3 = 0x1
          pupwk_f0 = 0x0
          pupwk_f1 = 0x0
          pupwk_f2 = 0x0
          pupwk_f3 = 0x0
          wkds = 0x7
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00010782
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0
          idle_active_en_f3 = 0x0
          pdpwk_f0 = 0x1
          pdpwk_f1 = 0x0
          pdpwk_f2 = 0x0
          pdpwk_f3 = 0x1
          pupwk_f0 = 0x0
          pupwk_f1 = 0x0
          pupwk_f2 = 0x0
          pupwk_f3 = 0x0
          wkds = 0x7
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 28, 14);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 28, 14);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x00000c16
       control = 0xc16
---
Program FSP-WR to 0 and FSP-OP to 1 and reset VRCG

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x900d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x90
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x50
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
---
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0
          WrDqDqsRunSDLLUpdOverride = 0x0
          WrDqDqsRunSDLLUpdWrResult = 0x0
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0
          WrDqSDLLAddHalfClk_f1 = 0x0
          WrDqSDLLAddHalfClk_f2 = 0x0
          WrDqSDLLAddHalfClk_f3 = 0x0
          WrDqSDLLHalfClkEn = 0x0
          WrDqSDLLHalfClkOvrVal = 0x0
          WrDqSDLLHalfClkStatus = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-
RdDqSDLLDelaySel

DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_RdDqSDLLDelaySel(n) = 0x00000000
          RdDqSDLLDelaySel = 0x0
-No-
rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00140004
          Rd0RunSDLLUpd = 0x0
          Rd0RunSDLLUpdOverride = 0x0
          Rd0RunSDLLUpdWrResult = 0x1
          Rd0SDLLOvrVal = 0x14
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


FPGA: Skip this step

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


FPGA: Skip this step

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFControl(n) = 0x01d0b061
       HWRdDqCalVREFEnable = 0x1
       HWRdDqCalVREFMax = 0xd0
       HWRdDqCalVREFMaxOffsetScaleFactor = 0x1
       HWRdDqCalVREFMaxScoreSel = 0x0
       HWRdDqCalVREFMin = 0xb0
       HWRdDqCalVREFNumPoints = 0x6
       HWRdDqCalVREFScoreMinSel = 0x0
       HWRdDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFControl(n) = 0x02200061
       HWWrDqCalVREFEnable = 0x1
       HWWrDqCalVREFMax = 0x20
       HWWrDqCalVREFMaxOffsetScaleFactor = 0x2
       HWWrDqCalVREFMaxScoreSel = 0x0
       HWWrDqCalVREFMin = 0x0
       HWWrDqCalVREFNumPoints = 0x6
       HWWrDqCalVREFScoreMinSel = 0x0
       HWWrDqCalVREFStaticSel = 0x0
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x0d012019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1
       PhyUpdWaittXSR = 0x0
       PreFreqChngWaitThr = 0x2
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10010000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x0
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+ +
    amph_CFGH_B0_DYN_ISEL_ASRTIME(n) = 0x00000019
       rcvr_minisel_assrttime_f0 = 0x19
       rcvr_minisel_assrttime_f1 = 0x0
       rcvr_minisel_assrttime_f2 = 0x0
       rcvr_minisel_assrttime_f3 = 0x0
---
+ +
    amph_CFGH_B0_DYN_ISEL(n) = 0x00000001
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x0
       dyn_isel_ctrl_en_f2 = 0x0
       dyn_isel_ctrl_en_f3 = 0x0
---
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + +
if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00000000
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x0
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x0
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000000a8
          RdCwfEarlyCyc_freq0 = 0x8
          RdCwfEarlyCyc_freq1 = 0x0
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x0
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x0
       SpecRdNum = 0x1
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1
       Mcc0AfDramRdPropQTrakEnbl = 0x0
       Mcc0DpPropQCfg = 0x0
       Mcc0DpPropQCmd = 0x1
       Mcc0DpPropQTrakEnbl = 0x0
       Mcc0MsqQPropCfg = 0x0
       Mcc0MsqQPropQCmd = 0x0
       Mcc0MsqQPropTrakEnbl = 0x0
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1
       Mcc1AfDramRdPropQTrakEnbl = 0x0
       Mcc1DpPropQCfg = 0x0
       Mcc1DpPropQCmd = 0x1
       Mcc1DpPropQTrakEnbl = 0x0
       Mcc1MsqQPropCfg = 0x0
       Mcc1MsqQPropQCmd = 0x0
       Mcc1MsqQPropTrakEnbl = 0x0
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
+ +
    spllctrl_SpllCtrl_MDLLPwrDnCfg0(n) = 0x00000001
       Freq3_en = 0x1
       powergating_en = 0x0
---
disable dynamic power-down. + + + + +
if (platform == FPGA)
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
else
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
---
enable dynamic power-down for cold boot. + + + + +
if (platform == FPGA)
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
else
          amcx_dramcfg_pwrmngten(n) = 0x00000133
             AutoSR = 0x1
             DynPwrDnEn = 0x1
             McPhyUpdDramClkOff = 0x0
             PwrDnClkOff = 0x1
             SRClkOff = 0x1
             SRExitOpt = 0x1
-No-
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000001ff
          DccEn = 0x1
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
YesNo-
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x00f000f0
       PreFreqChng2AllBankDly_f0 = 0xf0
       PreFreqChng2AllBankDly_f1 = 0xf0
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x00f000f0
       PreFreqChng2AllBankDly_f2 = 0xf0
       PreFreqChng2AllBankDly_f3 = 0xf0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02400240
       PreFreqChng2FreqChngDly_f0 = 0x240
       PreFreqChng2FreqChngDly_f1 = 0x240
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02400240
       PreFreqChng2FreqChngDly_f2 = 0x240
       PreFreqChng2FreqChngDly_f3 = 0x240
---
+ +
    glbtimer_GlbTimer_CalSeg2AllBank0 = 0x00fa0120
       CalSeg2AllBank_f0 = 0x120
       CalSeg2AllBank_f1 = 0xfa
---
+ +
    glbtimer_GlbTimer_AllBank2CalSeg0 = 0x00fa0120
       AllBank2CalSeg_f0 = 0x120
       AllBank2CalSeg_f1 = 0xfa
---


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_DCCTimer = 0x00000bb8
          DCCTimerCnt = 0xbb8
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6bb
          RdCalTimerCnt = 0x2dc6bb
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--


SAMSUNG: Skip this step

PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
YesNo-


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x00000001
          PerCal_FreqChngTimerCnt = 0x1
YesNo-


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
YesNo-
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa
       MCUBCGClkGateEn = 0x0
       MCUBCGPwrGateEn = 0x0
       PwrRstCyc = 0x5
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x4
       MRCmdCs = 0x0
       MRCmdData = 0x50
       MRCmdIsMPC = 0x0
       MRCmdIsRd = 0x1
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Elba_Init_B0_Oct_30_2015.html b/docs/dcs-specs/Elba_Init_B0_Oct_30_2015.html new file mode 100644 index 0000000..8e95f24 --- /dev/null +++ b/docs/dcs-specs/Elba_Init_B0_Oct_30_2015.html @@ -0,0 +1,3014 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Fri Oct 30 17:07:30 2015
AMC Version: 14 Major Release: 3 Minor Release: 0
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/trunk.elba/amcc/tb/cfg/static/maqstb_cfg.pl#103
AMP UM Init sourced from: //depot/ip_lib/apple/amp/trunk.elba/amp/tb/cfg/phy_helper_fxns.pl#73
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - cpolapra - Files Edited: maqs_gen_cfg.pl#6 - maqs_gen_cfg_c.pl#6 - maqstb_cfg.pl#13 - mcu_helper_fxns.c#8 -
* Fix compile errors from cortex boot
* ------------------------------------------------------------------
* Version:7 - cpolapra - Files Edited: maqstb_cfg.pl#17 - mcu_helper_fxns.c#10 -
* 1600 Mhz mcu init changes
* ------------------------------------------------------------------
* Version:8 - herb - Files Edited: gen_mcu_init.pl#7 -
* amp v0.9.2
* amcx v0.0.10
* amph V0007
* ------------------------------------------------------------------
* Version:9 - thuang - Files Edited: maqstb_cfg.pl#33 -
* add back SPLLCtrl programming now that is resolved
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x0
       SpecRdNum = 0x1
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1 *read-only
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1 *read-only
       MccStickyEn = 0x1 *read-only
---
program mccgen + +
    amcc_mcccfg_MccGen = 0x00000194
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050120
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x1
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3
       slvpll_cp_lp = 0x0
       slvpll_cp_md = 0x0
       slvpll_cp_pd = 0x0
       slvpll_cp_r_set = 0x8
---
+ +
    spllctrl_SpllCtrl_ModeReg(n) = 0x00000001
       override_spll_lock = 0x0
       override_spllseq_outputs = 0x0
       override_value_spll_lock = 0x0
       slvpll_byp = 0x0
       slvpll_mode = 0x1
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000016
       slvpll_vco_buf_pd = 0x0
       slvpll_vco_cap = 0x1
       slvpll_vco_kvco = 0x0
       slvpll_vco_pd = 0x0
       slvpll_vco_rv2i = 0x6
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000015
       slvpll_vco_buf_pd = 0x0
       slvpll_vco_cap = 0x1
       slvpll_vco_kvco = 0x0
       slvpll_vco_pd = 0x0
       slvpll_vco_rv2i = 0x5
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0
       slvpll_reg_pd = 0x0
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0
       spll_mode_dcs_pwrdn = 0x1
       use_idle_for_pd = 0x0
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 132.33Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 132.33Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xde012d02
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x2d
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xde
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0
       freqchngmrw9_ctrl_freq0 = 0x0
       freqchngmrw9_data_freq0 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xd303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xd3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xd303220b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x22
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xd3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000216
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x2
       freqchngmrw9_addr_freq1 = 0x0
       freqchngmrw9_ctrl_freq1 = 0x0
       freqchngmrw9_data_freq1 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0
       freqchngmrw9_ctrl_freq2 = 0x0
       freqchngmrw9_data_freq2 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0
       freqchngmrw9_ctrl_freq3 = 0x0
       freqchngmrw9_data_freq3 = 0x0
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalVREFCodeControl(n) = 0x19191111
       WrDqCalVREFCode_f0 = 0x11
       WrDqCalVREFCode_f1 = 0x11
       WrDqCalVREFCode_f2 = 0x19
       WrDqCalVREFCode_f3 = 0x19
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalVREFCodeControl(n) = 0x19191191
       RdDqCalVREFCode_f0 = 0x91
       RdDqCalVREFCode_f1 = 0x11
       RdDqCalVREFCode_f2 = 0x19
       RdDqCalVREFCode_f3 = 0x19
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFControl(n) = 0x01d0b060
       HWRdDqCalVREFEnable = 0x0
       HWRdDqCalVREFMax = 0xd0
       HWRdDqCalVREFMaxOffsetScaleFactor = 0x1
       HWRdDqCalVREFMaxScoreSel = 0x0
       HWRdDqCalVREFMin = 0xb0
       HWRdDqCalVREFNumPoints = 0x6
       HWRdDqCalVREFScoreMinSel = 0x0
       HWRdDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFOffsetControl1(n) = 0x06040200
       HWRdDqCalOffset0 = 0x0
       HWRdDqCalOffset1 = 0x2
       HWRdDqCalOffset2 = 0x4
       HWRdDqCalOffset3 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFOffsetControl2(n) = 0x00fafcfe
       HWRdDqCalOffset4 = 0xfe
       HWRdDqCalOffset5 = 0xfc
       HWRdDqCalOffset6 = 0xfa
       HWRdDqCalOffset7 = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFControl(n) = 0x02200060
       HWWrDqCalVREFEnable = 0x0
       HWWrDqCalVREFMax = 0x20
       HWWrDqCalVREFMaxOffsetScaleFactor = 0x2
       HWWrDqCalVREFMaxScoreSel = 0x0
       HWWrDqCalVREFMin = 0x0
       HWWrDqCalVREFNumPoints = 0x6
       HWWrDqCalVREFScoreMinSel = 0x0
       HWWrDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFOffsetControl1(n) = 0x06040200
       HWWrDqCalOffset0 = 0x0
       HWWrDqCalOffset1 = 0x2
       HWWrDqCalOffset2 = 0x4
       HWWrDqCalOffset3 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFOffsetControl2(n) = 0x00fafcfe
       HWWrDqCalOffset4 = 0xfe
       HWWrDqCalOffset5 = 0xfc
       HWWrDqCalOffset6 = 0xfa
       HWWrDqCalOffset7 = 0x0
---
+ +
    glbtimer_GlbTimer_PerVrefCalCfg = 0x00000003
       LegacyMode = 0x0
       PreVrefDcc = 0x1
       PreVrefMdll = 0x1
       PreVrefTimCal = 0x0
---
+ +
    glbtimer_GlbTimer_VrefCntrl = 0x00060006
       VrefPointsRd = 0x6
       VrefPointsWr = 0x6
       override_refready = 0x0
---
+ +
    amcx_dramtim_modereg(n) = 0x120c90b8
       tMRRCyc = 0x8
       tMRRICyc = 0xb
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x12
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7
       DllUpdtDur = 0x3
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0
       FreqChangeSDLLUpdDur = 0x50
       SDLLUpdDur = 0x50
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7
       DllUpdtDur = 0x3
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0
       FreqChangeSDLLUpdDur = 0x50
       SDLLUpdDur = 0x50
---
+ +
    amcx_dramtim_pdn(n) = 0x72276265
       tCKECyc = 0x5
       tCKEPDECyc = 0x1
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x7
       tCKb4CKECyc = 0x2
       tXPCyc = 0x6
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-3200 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3
       tDQSCKMinCyc_freq0 = 0x0
       tDQSSMaxCyc_freq0 = 0x1
else
       amcx_dramtim_lat_freq0(n) = 0x00103387
          DRAMRL_freq0 = 0xe
          DRAMWL_freq0 = 0x7
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x0
          tDQSSMaxCyc_freq0 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x0
       tDQSSMaxCyc_freq1 = 0x1
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x0
          tDQSSMaxCyc_freq1 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010d01
       PHYRdLat_freq0 = 0xd
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00060d0c
          PHYRdLat_freq0 = 0xd
          PHYtPhyWrlat_freq0 = 0x6
          PHYtRddataEn_freq0 = 0xc
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010b01
       PHYRdLat_freq1 = 0xb
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050b06
          PHYRdLat_freq1 = 0xb
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
       PHYRdLat_freq2 = 0xb
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
          PHYRdLat_freq2 = 0xb
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
       PHYRdLat_freq3 = 0x9
       PHYtPhyWrlat_freq3 = 0x1
       PHYtRddataEn_freq3 = 0x1
else
       amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
          PHYRdLat_freq3 = 0x9
          PHYtPhyWrlat_freq3 = 0x1
          PHYtRddataEn_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x63e2080f
       tRASCyc_freq0 = 0x22
       tRCDCyc_freq0 = 0xf
       tRTPCyc_freq0 = 0x6
       tWRCyc_freq0 = 0xf
       tWTRCyc_freq0 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x63e2080f
          tRASCyc_freq0 = 0x22
          tRCDCyc_freq0 = 0xf
          tRTPCyc_freq0 = 0x6
          tWRCyc_freq0 = 0xf
          tWTRCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x2008110f
       tFAWCyc_freq0 = 0x20
       tRPCyc_freq0 = 0xf
       tRPabCyc_freq0 = 0x11
       tRRDCyc_freq0 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x2008110f
          tFAWCyc_freq0 = 0x20
          tRPCyc_freq0 = 0xf
          tRPabCyc_freq0 = 0x11
          tRRDCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x48900078
       tRFCBaseCyc_freq0 = 0x78
       tRFCCyc_freq0 = 0x90
       tRFCpbCyc_freq0 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x48900078
          tRFCBaseCyc_freq0 = 0x78
          tRFCCyc_freq0 = 0x90
          tRFCpbCyc_freq0 = 0x48
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0xa0096012
       tFCCyc_freq0 = 0xa0
       tXSRCyc_freq0 = 0x96
       tZQCalCyc_freq0 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12
else
       amcx_dramtim_selfref_freq0(n) = 0xa0096012
          tFCCyc_freq0 = 0xa0
          tXSRCyc_freq0 = 0x96
          tZQCalCyc_freq0 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x1a0cc0f4
       tMRRCyc = 0x4
       tMRRICyc = 0xf
       tMRWCyc = 0xc
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x1a
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060c5024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x5
       tVRCGOFFCyc = 0xc
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x1a0cc0f4
          tMRRCyc = 0x4
          tMRRICyc = 0xf
          tMRWCyc = 0xc
          tVRCGOFFCyc = 0xc
          tZQLatCyc = 0x1a
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x63e2080f
       tRASCyc_freq1 = 0x22
       tRCDCyc_freq1 = 0xf
       tRTPCyc_freq1 = 0x6
       tWRCyc_freq1 = 0xf
       tWTRCyc_freq1 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq1(n) = 0x2008110f
       tFAWCyc_freq1 = 0x20
       tRPCyc_freq1 = 0xf
       tRPabCyc_freq1 = 0x11
       tRRDCyc_freq1 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq1(n) = 0x48900050
       tRFCBaseCyc_freq1 = 0x50
       tRFCCyc_freq1 = 0x90
       tRFCpbCyc_freq1 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0xa0096012
       tFCCyc_freq1 = 0xa0
       tXSRCyc_freq1 = 0x96
       tZQCalCyc_freq1 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x63e2080f
       tRASCyc_freq2 = 0x22
       tRCDCyc_freq2 = 0xf
       tRTPCyc_freq2 = 0x6
       tWRCyc_freq2 = 0xf
       tWTRCyc_freq2 = 0x8
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x2008110f
       tFAWCyc_freq2 = 0x20
       tRPCyc_freq2 = 0xf
       tRPabCyc_freq2 = 0x11
       tRRDCyc_freq2 = 0x8
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x48900014
       tRFCBaseCyc_freq2 = 0x14
       tRFCCyc_freq2 = 0x90
       tRFCpbCyc_freq2 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0xa0096012
       tFCCyc_freq2 = 0xa0
       tXSRCyc_freq2 = 0x96
       tZQCalCyc_freq2 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x03050005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x5
       tRFCpbCyc_freq3 = 0x3
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x28005012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x5
       tZQCalCyc_freq3 = 0x12
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0015005d
       tREFBWtRFCcnt = 0x15
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x612762c6
       tCKECyc = 0x6
       tCKEPDECyc = 0x1
       tCKESRCyc = 0xc
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x6
       tCKb4CKECyc = 0x1
       tXPCyc = 0x6
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21272222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x7
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x722762c6
          tCKECyc = 0x6
          tCKEPDECyc = 0x1
          tCKESRCyc = 0xc
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x7
          tCKafCKECyc = 0x7
          tCKb4CKECyc = 0x2
          tXPCyc = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq0 = 0x5
       tRASDrtCyc_freq0 = 0x24
       tRCDDrtCyc_freq0 = 0x10
       tRPDrtCyc_freq0 = 0x10
       tRPabDrtCyc_freq0 = 0x13
       tRRDDrtCyc_freq0 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x4d05a910
          tDQSCKMaxDrtCyc_freq0 = 0x5
          tRASDrtCyc_freq0 = 0x24
          tRCDDrtCyc_freq0 = 0x10
          tRPDrtCyc_freq0 = 0x10
          tRPabDrtCyc_freq0 = 0x13
          tRRDDrtCyc_freq0 = 0xa
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq1 = 0x5
       tRASDrtCyc_freq1 = 0x24
       tRCDDrtCyc_freq1 = 0x10
       tRPDrtCyc_freq1 = 0x10
       tRPabDrtCyc_freq1 = 0x13
       tRRDDrtCyc_freq1 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x4d05a910
       tDQSCKMaxDrtCyc_freq2 = 0x5
       tRASDrtCyc_freq2 = 0x24
       tRCDDrtCyc_freq2 = 0x10
       tRPDrtCyc_freq2 = 0x10
       tRPabDrtCyc_freq2 = 0x13
       tRRDDrtCyc_freq2 = 0xa
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00123387
       DRAMRL_freq0 = 0xe
       DRAMWL_freq0 = 0x7
       tDQSCKMaxCyc_freq0 = 0x3
       tDQSCKMinCyc_freq0 = 0x2
       tDQSSMaxCyc_freq0 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1
else
       amcx_dramtim_lat_freq0(n) = 0x00123387
          DRAMRL_freq0 = 0xe
          DRAMWL_freq0 = 0x7
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x2
          tDQSSMaxCyc_freq0 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00123206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x3
       tDQSCKMinCyc_freq1 = 0x2
       tDQSSMaxCyc_freq1 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001230c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x3
       tDQSCKMinCyc_freq2 = 0x2
       tDQSSMaxCyc_freq2 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq0(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq0 = 0x2
       R2rTatDeadCyc_freq0 = 0x1
       R2wRnkMissTatDeadCyc_freq0 = 0x2
       R2wTatDeadCyc_freq0 = 0x4
       W2rRnkMissTatDeadCyc_freq0 = 0x2
       W2wRnkMissTatDeadCyc_freq0 = 0x2
       W2wTatDeadCyc_freq0 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2
       R2rTatDeadCyc_freq0 = 0x1
       R2wRnkMissTatDeadCyc_freq0 = 0x2
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2
       W2wRnkMissTatDeadCyc_freq0 = 0x2
       W2wTatDeadCyc_freq0 = 0x1
else
       amcx_dramtim_tat_freq0(n) = 0x01412222
          R2rRnkMissTatDeadCyc_freq0 = 0x2
          R2rTatDeadCyc_freq0 = 0x1
          R2wRnkMissTatDeadCyc_freq0 = 0x2
          R2wTatDeadCyc_freq0 = 0x4
          W2rRnkMissTatDeadCyc_freq0 = 0x2
          W2wRnkMissTatDeadCyc_freq0 = 0x2
          W2wTatDeadCyc_freq0 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq1(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq1 = 0x2
       R2rTatDeadCyc_freq1 = 0x1
       R2wRnkMissTatDeadCyc_freq1 = 0x2
       R2wTatDeadCyc_freq1 = 0x4
       W2rRnkMissTatDeadCyc_freq1 = 0x2
       W2wRnkMissTatDeadCyc_freq1 = 0x2
       W2wTatDeadCyc_freq1 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2
       R2rTatDeadCyc_freq1 = 0x1
       R2wRnkMissTatDeadCyc_freq1 = 0x2
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2
       W2wRnkMissTatDeadCyc_freq1 = 0x2
       W2wTatDeadCyc_freq1 = 0x1
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2
          R2rTatDeadCyc_freq1 = 0x1
          R2wRnkMissTatDeadCyc_freq1 = 0x2
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2
          W2wRnkMissTatDeadCyc_freq1 = 0x2
          W2wTatDeadCyc_freq1 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01412222
       R2rRnkMissTatDeadCyc_freq2 = 0x2
       R2rTatDeadCyc_freq2 = 0x1
       R2wRnkMissTatDeadCyc_freq2 = 0x2
       R2wTatDeadCyc_freq2 = 0x4
       W2rRnkMissTatDeadCyc_freq2 = 0x2
       W2wRnkMissTatDeadCyc_freq2 = 0x2
       W2wTatDeadCyc_freq2 = 0x1
else if (platform == FPGA)
    amcx_dramtim_tat_freq2(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq2 = 0x2
       R2rTatDeadCyc_freq2 = 0x1
       R2wRnkMissTatDeadCyc_freq2 = 0x2
       R2wTatDeadCyc_freq2 = 0x2
       W2rRnkMissTatDeadCyc_freq2 = 0x2
       W2wRnkMissTatDeadCyc_freq2 = 0x2
       W2wTatDeadCyc_freq2 = 0x1
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2
          R2rTatDeadCyc_freq2 = 0x1
          R2wRnkMissTatDeadCyc_freq2 = 0x2
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2
          W2wRnkMissTatDeadCyc_freq2 = 0x2
          W2wTatDeadCyc_freq2 = 0x1
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x0
       ZqCalIntrvl = 0x0
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0
       SchEn = 0x1
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0
       tPhyUpdGap = 0x0
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x03030305
       ClkEn2Valid = 0x3
       ReqWaitDelay = 0x5
       Valid2ClkEn = 0x3
       ValidLen = 0x3
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x00030005
       ClkEn2Valid = 0x0
       ReqWaitDelay = 0x5
       Valid2ClkEn = 0x0
       ValidLen = 0x3
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0002
       Rd0RunSDLLUpd = 0x0
       Rd0RunSDLLUpdOverride = 0x1
       Rd0RunSDLLUpdWrResult = 0x0
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdOverride
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x2) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0000
       Rd0RunSDLLUpd = 0x0
       Rd0RunSDLLUpdOverride = 0x0
       Rd0RunSDLLUpdWrResult = 0x0
       Rd0SDLLOvrVal = 0xff
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000002
       WrDqDqsRunSDLLUpd = 0x0
       WrDqDqsRunSDLLUpdOverride = 0x1
       WrDqDqsRunSDLLUpdWrResult = 0x0
       WrDqDqsWrLvlReBalanceEn = 0x0
       WrDqSDLLAddHalfClk_f0 = 0x0
       WrDqSDLLAddHalfClk_f1 = 0x0
       WrDqSDLLAddHalfClk_f2 = 0x0
       WrDqSDLLAddHalfClk_f3 = 0x0
       WrDqSDLLHalfClkEn = 0x0
       WrDqSDLLHalfClkOvrVal = 0x0
       WrDqSDLLHalfClkStatus = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdOverride
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x2) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000000
       WrDqDqsRunSDLLUpd = 0x0
       WrDqDqsRunSDLLUpdOverride = 0x0
       WrDqDqsRunSDLLUpdWrResult = 0x0
       WrDqDqsWrLvlReBalanceEn = 0x0
       WrDqSDLLAddHalfClk_f0 = 0x0
       WrDqSDLLAddHalfClk_f1 = 0x0
       WrDqSDLLAddHalfClk_f2 = 0x0
       WrDqSDLLAddHalfClk_f3 = 0x0
       WrDqSDLLHalfClkEn = 0x0
       WrDqSDLLHalfClkOvrVal = 0x0
       WrDqSDLLHalfClkStatus = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff01ff
       WrLvlMaxWrDqsSDLLCode = 0xff
       WrLvlRunUpdOverride = 0x1
       WrLvlRunUpdWrResult = 0x0
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdOverride
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x100) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff00ff
       WrLvlMaxWrDqsSDLLCode = 0xff
       WrLvlRunUpdOverride = 0x0
       WrLvlRunUpdWrResult = 0x0
       WrLvlSDLLCode = 0xff
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00c801f4
          DllIncLockTim = 0xc8
          DllInitLockTim = 0x1f4
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00c801f4
          DllIncLockTim = 0xc8
          DllInitLockTim = 0x1f4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000710
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x7
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000710
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x7
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000510
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x5
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x06020704
       tCA2CAEntry_f0 = 0x4
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x7
       tCKEHExit_f0 = 0x6
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020702
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x7
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020702
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x7
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020504
       tCA2CAEntry_f3 = 0x4
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x5
       tCKEHExit_f3 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_RdDqCal2(n) = 0x00000019
       RdDqCal_FullScan_Wait_CKEHigh = 0x19
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x01040508
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x8
       tWL = 0x5
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00040008
       tRdDqCalSegLen = 0x8
       tWrDqCalSegLen = 0x4
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x01040402
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x4
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f3(n) = 0x01040508
       CoarseStepSize = 0x4
       FineStepSize = 0x1
       tRL = 0x8
       tWL = 0x5
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x000c0012
       tRdDqCalSegLen = 0x12
       tWrDqCalSegLen = 0xc
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000381e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x38
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x01141101
       tRd2Rd = 0x1
       tRd2Wr = 0x11
       tWr2Rd = 0x14
       tWr2Wr = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55553c5a
       PatInvertMask = 0x5555
       PatPRBS4 = 0x3c5a
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x00003c5a
       PatInvertMask = 0x0
       PatPRBS4 = 0x3c5a
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_0(n) = 0x87654321
       PatPRBS7 = 0x87654321
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_1(n) = 0xcdedcba9
       PatPRBS7 = 0xcdedcba9
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_2(n) = 0x456789ab
       PatPRBS7 = 0x456789ab
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS7_3(n) = 0x5fa63123
       PatPRBS7 = 0x5fa63123
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatInvertMask(n) = 0x55550000
       PatInvertMask = 0x5555
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00ff01d1
       EndPoint = 0xff
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x00ff0160
       EndPoint = 0xff
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00ff01d1
       EndPoint = 0xff
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x00ff0160
       EndPoint = 0xff
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxRdDqsSDLLMulFactor(n) = 0x00a01414
       MaxRdDqsSDLLCodeStatus = 0xa0 *read-only
       RdDqsSDLLMulFactorF0 = 0x14
       RdDqsSDLLMulFactorF1 = 0x14
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a00c0d
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xd
       WrDqsSDLLMulFactorF1 = 0xc
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000810
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1
          RdCapLat_f0 = 0x10
          RdDatLat_f0 = 0x8
          WrPhaseDelay_f0 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100060a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x6
          WrPhaseDelay_f1 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000408
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1
          RdCapLat_f2 = 0x8
          RdDatLat_f2 = 0x4
          WrPhaseDelay_f2 = 0x0
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000408
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1
          RdCapLat_f3 = 0x8
          RdDatLat_f3 = 0x4
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x80017580
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0
          FreqChangeSDLLUpdDur = 0x80
          SDLLUpdDur = 0x80
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x80017580
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0
          FreqChangeSDLLUpdDur = 0x80
          SDLLUpdDur = 0x80
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1
       DllFastUpdtIntvl = 0x20
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1
       DllFastUpdtIntvl = 0x20
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0
---
+ +
    ampsca_ampscaiocfg_DCCControl(n) = 0x10050b27
       DCCEnable = 0x1
       DCCIdle1Len = 0x27
       DCCIdle2Len = 0x5
       DCCStopClk2Upd = 0x0
       DCCUpdLen = 0xb
---
+ +
    ampsca_ampscaiocfg_DCCTimer(n) = 0x00000190
       DCCTimer = 0x190
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalDynamicHalfClkDelayControl(n) = 0x00000001
       DynamicHalfClkDelayEn = 0x1
---
+ +
    amph_CFGH_CB_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_CB_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CB_IOCTL(n) = 0x00020023
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x0
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       protect_drvstren = 0x1
       sel_rx_ac = 0x0
       sel_rx_dc = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_CK_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_CK_ZDET_BIASEN(n) = 0x00000000
       bias_ena = 0x0
       disable_zdet = 0x0
       sel_zdet = 0x0
---
+ +
    amph_CFGH_CK_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CK_IOCTL(n) = 0x00000027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       sel_rx_ac = 0x0
       sel_rx_dc = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B0_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_B0_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B0_IOCTL(n) = 0x71500027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_B1_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_B1_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B1_IOCTL(n) = 0x71500027
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_B1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS0_WKPUPD(n) = 0x00000782
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x1
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x1
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x7
---
+ +
    amph_CFGH_DQS0_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS0_IOCTL(n) = 0x71500007
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x0
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_DQS0_ODT(n) = 0x01c00336
       dspd_f0 = 0x6
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS0_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_DQS1_WKPUPD(n) = 0x00000782
       idle_active_en_f0 = 0x0
       idle_active_en_f1 = 0x0
       idle_active_en_f2 = 0x0
       idle_active_en_f3 = 0x0
       pdpwk_f0 = 0x1
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x1
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x7
---
+ +
    amph_CFGH_DQS1_DRIVE_STR(n) = 0x33838317
       dspd_f0 = 0x7
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x8
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS1_IOCTL(n) = 0x71500007
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x0
       tx_ac_f1 = 0x0
       tx_ac_f2 = 0x0
       tx_ac_f3 = 0x0
---
+ +
    amph_CFGH_DQS1_ODT(n) = 0x01c00336
       dspd_f0 = 0x6
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0
       zcpd_val = 0x1c
---
+ +
    amph_CFGH_DQS1_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0
       dspu_f1 = 0x0
       dspu_f2 = 0x0
       dspu_f3 = 0x0
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0
          dspu_f1 = 0x0
          dspu_f2 = 0x0
          dspu_f3 = 0x0
          odten_f0 = 0x1
          odten_f1 = 0x1
          odten_f2 = 0x1
          odten_f3 = 0x0
---
+ +
    amph_CFGH_DBG_DBG_REG0(n) = 0x00000000
       cb_bias_ena = 0x0
       cb_odte = 0x0
       clk_en_sync_flop_rst = 0x0
       mon_vdd_mem = 0x0
       mon_vdd_soc = 0x0
---
+ +
    amph_CFGH_ZC_ZCAL_FSM1(n) = 0x00887f7f
       bias_ena_dly = 0x88
       io_pd = 0x7f *read-only
       io_pu = 0x7f *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM0(n) = 0x000f031b
       zc_dly = 0x1b
       zc_dnbd = 0x0
       zc_tap = 0x3
       zc_upbd = 0xf
---
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x00000816
       control = 0x816
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x06001604
       tCA2CAEntry = 0x4
       tCA2CAExit = 0x0
       tCKEHEntry = 0x16
       tCKEHExit = 0x6
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x06021604
       tCA2CAEntry_f0 = 0x4
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x16
       tCKEHExit_f0 = 0x6
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCaltVREF(n) = 0x08080808
       HWRdDqCaltVREF_f0 = 0x8
       HWRdDqCaltVREF_f1 = 0x8
       HWRdDqCaltVREF_f2 = 0x8
       HWRdDqCaltVREF_f3 = 0x8
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x0d012019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1
       PhyUpdWaittXSR = 0x0
       PreFreqChngWaitThr = 0x2
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x03050005
       tRFCBaseCyc_freq3 = 0x5
       tRFCCyc_freq3 = 0x5
       tRFCpbCyc_freq3 = 0x3
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x48900013
       tRFCBaseCyc_freq2 = 0x13
       tRFCCyc_freq2 = 0x90
       tRFCpbCyc_freq2 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq1(n) = 0x48900049
       tRFCBaseCyc_freq1 = 0x49
       tRFCCyc_freq1 = 0x90
       tRFCpbCyc_freq1 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x48900092
       tRFCBaseCyc_freq0 = 0x92
       tRFCCyc_freq0 = 0x90
       tRFCpbCyc_freq0 = 0x48
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x48900092
          tRFCBaseCyc_freq0 = 0x92
          tRFCCyc_freq0 = 0x90
          tRFCpbCyc_freq0 = 0x48
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x002f0013
       tREFBWtRFCcnt = 0x2f
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x0
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x0
          ZqCalIntrvl = 0x0
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01022008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x2
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030004
       FreqCSettleCyc = 0x5
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0
       tPhyUpdGap = 0x4
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x1
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10010000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x0
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x01010000
       freqchngfspop = 0x1
       freqchngfspopupd = 0x0
       freqchngmrwcnt_freq0 = 0x0
       freqchngmrwcnt_freq1 = 0x0
       freqchngmrwcnt_freq2 = 0x0
       freqchngmrwcnt_freq3 = 0x0
       freqchngrunsocupd = 0x1
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x01000000
       freqchngfspop = 0x1
       freqchngfspopupd = 0x0
       freqchngmrwcnt_freq0 = 0x0
       freqchngmrwcnt_freq1 = 0x0
       freqchngmrwcnt_freq2 = 0x0
       freqchngmrwcnt_freq3 = 0x0
       freqchngrunsocupd = 0x0
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x0
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x1
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x0
          RunRdLvl = 0x0
          RunSRExit = 0x1
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ + + + + + +
if (platform == FOUR_CH_ONE_RANK)
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
else if (platform == EIGHT_CH_ONE_RANK)
    glbtimer_GlbTimer_ChEn = 0x000000ff
       ChEn = 0xff
else
       glbtimer_GlbTimer_ChEn = 0x000000ff
          ChEn = 0xff
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0
       MRCmdCs = 0x0
       MRCmdData = 0x4f
       MRCmdIsMPC = 0x1
       MRCmdIsRd = 0x0
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0
       MRCmdCs = 0x0
       MRCmdData = 0x51
       MRCmdIsMPC = 0x1
       MRCmdIsRd = 0x0
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x2
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x1
          MRCmdCs = 0x0
          MRCmdData = 0x8e
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xf3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and modified refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x18
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0xc
          MRCmdCs = 0x0
          MRCmdData = 0x59
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0xe
          MRCmdCs = 0x0
          MRCmdData = 0x59
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x17
          MRCmdCs = 0x0
          MRCmdData = 0x80
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0xf
          MRCmdCs = 0x0
          MRCmdData = 0x55
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x14
          MRCmdCs = 0x0
          MRCmdData = 0x55
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5a204100
          MRCmdAddr = 0x20
          MRCmdCs = 0x0
          MRCmdData = 0x5a
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x3c284100
          MRCmdAddr = 0x28
          MRCmdCs = 0x0
          MRCmdData = 0x3c
          MRCmdIsMPC = 0x1
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FPGA)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_addrcfg = 0x00030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x0
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050101
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060101
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050110
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060100
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == FPGA)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060110
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050100
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x0
else if (platform == EIGHT_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050120
       ChSelHiBits = 0x5
       ChSelTyp = 0x0
       ChnlStartBit = 0x1
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050120
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x1
          NumMcuChnl = 0x2
---


SAMSUNG: Perform this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x0
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
else
          amcx_dramcfg_freqchngctl2_freq0(n) = 0xb203330b
             freqchngmrw4_addr_freq0 = 0xb
             freqchngmrw4_ctrl_freq0 = 0x0
             freqchngmrw4_data_freq0 = 0x33
             freqchngmrw5_addr_freq0 = 0x3
             freqchngmrw5_ctrl_freq0 = 0x0
             freqchngmrw5_data_freq0 = 0xb2
-No-


SAMSUNG: Perform this step
+ +
       amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000316
          freqchngmrw8_addr_freq0 = 0x16
          freqchngmrw8_ctrl_freq0 = 0x0
          freqchngmrw8_data_freq0 = 0x3
          freqchngmrw9_addr_freq0 = 0x0
          freqchngmrw9_ctrl_freq0 = 0x0
          freqchngmrw9_data_freq0 = 0x0
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_CB_IMPCTL(n) = 0x01001c2b
          en160_tx_f0 = 0x0
          en160_tx_f1 = 0x0
          en160_tx_f2 = 0x0
          en160_tx_f3 = 0x0
          en160pd_tx_f0 = 0x1
          en160pd_tx_f1 = 0x0
          en160pd_tx_f2 = 0x0
          en160pd_tx_f3 = 0x0
          zcpd_ovrr = 0x1c
          zcpu_ovrr = 0x2b
          zcpu_pd_ovrr = 0x0
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_B0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_B1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_DQS0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-


SAMSUNG: Perform this step
+ +
       amph_CFGH_DQS1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
-No-
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1 and FSP-OP to 0 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x58
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x2d020100
          MRCmdAddr = 0x2
          MRCmdCs = 0x0
          MRCmdData = 0x2d
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xde010100
          MRCmdAddr = 0x1
          MRCmdCs = 0x0
          MRCmdData = 0xde
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Skip this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xb3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Skip this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Perform this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb2030100
          MRCmdAddr = 0x3
          MRCmdCs = 0x0
          MRCmdData = 0xb2
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x4
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x03160100
          MRCmdAddr = 0x16
          MRCmdCs = 0x0
          MRCmdData = 0x3
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Skip this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x44
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Skip this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


SAMSUNG: Perform this step

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x330b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x33
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0xb
          MRCmdCs = 0x0
          MRCmdData = 0x0
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0xc
          MRCmdCs = 0x0
          MRCmdData = 0x11
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0xe
          MRCmdCs = 0x0
          MRCmdData = 0x11
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0
          WrLvlRunUpdWrResult = 0x1
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 28, 14);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0
          ForceDRAMClkEn = 0x0
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0
          ForceMClkWakeUp = 0x0
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0 + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update + +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x1
YesYes-
Poll ampsdqdllctl dllupdtcmd + +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0
          ForceDRAMClkEn = 0x0
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0
          ForceMClkWakeUp = 0x0
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
          freqchngmrw2_addr_freq0 = 0xe
          freqchngmrw2_ctrl_freq0 = 0x0
          freqchngmrw2_data_freq0 = 0x11
          freqchngmrw3_addr_freq0 = 0xc
          freqchngmrw3_ctrl_freq0 = 0x0
          freqchngmrw3_data_freq0 = 0x11
YesYes-


FPGA: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x0
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
else
          amcx_dramcfg_freqchngctl2_freq0(n) = 0xb203330b
             freqchngmrw4_addr_freq0 = 0xb
             freqchngmrw4_ctrl_freq0 = 0x0
             freqchngmrw4_data_freq0 = 0x33
             freqchngmrw5_addr_freq0 = 0x3
             freqchngmrw5_ctrl_freq0 = 0x0
             freqchngmrw5_data_freq0 = 0xb2
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000316
          freqchngmrw8_addr_freq0 = 0x16
          freqchngmrw8_ctrl_freq0 = 0x0
          freqchngmrw8_data_freq0 = 0x3
          freqchngmrw9_addr_freq0 = 0x0
          freqchngmrw9_ctrl_freq0 = 0x0
          freqchngmrw9_data_freq0 = 0x0
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x00061a80
          ZQCTimerCnt = 0x61a80
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_CB_IMPCTL(n) = 0x01001c2b
          en160_tx_f0 = 0x0
          en160_tx_f1 = 0x0
          en160_tx_f2 = 0x0
          en160_tx_f3 = 0x0
          en160pd_tx_f0 = 0x1
          en160pd_tx_f1 = 0x0
          en160pd_tx_f2 = 0x0
          en160pd_tx_f3 = 0x0
          zcpd_ovrr = 0x1c
          zcpu_ovrr = 0x2b
          zcpu_pd_ovrr = 0x0
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_B0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_B1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_DQS0_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-


PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       amph_CFGH_DQS1_ODT(n) = 0x01c00339
          dspd_f0 = 0x9
          dspd_f1 = 0x3
          dspd_f2 = 0x3
          dspd_f3 = 0x0
          zcpd_ovrr = 0x0
          zcpd_val = 0x1c
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 0, FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x98
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
YesNo-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR + +
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
YesYes-
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x02009999
          freqchngfspop = 0x0
          freqchngfspopupd = 0x1
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0
YesYes-
WrDqDqsSDLLCtrl + +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0
          WrDqDqsRunSDLLUpdOverride = 0x0
          WrDqDqsRunSDLLUpdWrResult = 0x0
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0
          WrDqSDLLAddHalfClk_f1 = 0x0
          WrDqSDLLAddHalfClk_f2 = 0x0
          WrDqSDLLAddHalfClk_f3 = 0x0
          WrDqSDLLHalfClkEn = 0x0
          WrDqSDLLHalfClkOvrVal = 0x0
          WrDqSDLLHalfClkStatus = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 1600Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x1
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 28, 14);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00010782
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0
          idle_active_en_f3 = 0x0
          pdpwk_f0 = 0x1
          pdpwk_f1 = 0x0
          pdpwk_f2 = 0x0
          pdpwk_f3 = 0x1
          pupwk_f0 = 0x0
          pupwk_f1 = 0x0
          pupwk_f2 = 0x0
          pupwk_f3 = 0x0
          wkds = 0x7
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00010782
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0
          idle_active_en_f3 = 0x0
          pdpwk_f0 = 0x1
          pdpwk_f1 = 0x0
          pdpwk_f2 = 0x0
          pdpwk_f3 = 0x1
          pupwk_f0 = 0x0
          pupwk_f1 = 0x0
          pupwk_f2 = 0x0
          pupwk_f3 = 0x0
          wkds = 0x7
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 28, 14);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 28, 14);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x00000c16
       control = 0xc16
---
Program FSP-WR to 0 and FSP-OP to 1 and reset VRCG

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x900d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x90
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0xd
          MRCmdCs = 0x0
          MRCmdData = 0x50
          MRCmdIsMPC = 0x0
          MRCmdIsRd = 0x0
          RunMRCmd = 0x1
          RunRdLvl = 0x0
          RunSRExit = 0x0
---
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0
          freqchngfspopupd = 0x0
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0
          WrDqDqsRunSDLLUpdOverride = 0x0
          WrDqDqsRunSDLLUpdWrResult = 0x0
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0
          WrDqSDLLAddHalfClk_f1 = 0x0
          WrDqSDLLAddHalfClk_f2 = 0x0
          WrDqSDLLAddHalfClk_f3 = 0x0
          WrDqSDLLHalfClkEn = 0x0
          WrDqSDLLHalfClkOvrVal = 0x0
          WrDqSDLLHalfClkStatus = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-
RdDqSDLLDelaySel

DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_RdDqSDLLDelaySel(n) = 0x00000000
          RdDqSDLLDelaySel = 0x0
-No-
rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00140004
          Rd0RunSDLLUpd = 0x0
          Rd0RunSDLLUpdOverride = 0x0
          Rd0RunSDLLUpdWrResult = 0x1
          Rd0SDLLOvrVal = 0x14
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


FPGA: Skip this step

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


FPGA: Skip this step

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWRdDqCalFullScanEnable16bit = 0x0
          HWWrDqCalFullScanEnable = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalVREFControl(n) = 0x01d0b061
       HWRdDqCalVREFEnable = 0x1
       HWRdDqCalVREFMax = 0xd0
       HWRdDqCalVREFMaxOffsetScaleFactor = 0x1
       HWRdDqCalVREFMaxScoreSel = 0x0
       HWRdDqCalVREFMin = 0xb0
       HWRdDqCalVREFNumPoints = 0x6
       HWRdDqCalVREFScoreMinSel = 0x0
       HWRdDqCalVREFStaticSel = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalVREFControl(n) = 0x02200061
       HWWrDqCalVREFEnable = 0x1
       HWWrDqCalVREFMax = 0x20
       HWWrDqCalVREFMaxOffsetScaleFactor = 0x2
       HWWrDqCalVREFMaxScoreSel = 0x0
       HWWrDqCalVREFMin = 0x0
       HWWrDqCalVREFNumPoints = 0x6
       HWWrDqCalVREFScoreMinSel = 0x0
       HWWrDqCalVREFStaticSel = 0x0
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x0d012019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1
       PhyUpdWaittXSR = 0x0
       PreFreqChngWaitThr = 0x2
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10010000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x0
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+ +
    amph_CFGH_B0_DYN_ISEL_ASRTIME(n) = 0x00000019
       rcvr_minisel_assrttime_f0 = 0x19
       rcvr_minisel_assrttime_f1 = 0x0
       rcvr_minisel_assrttime_f2 = 0x0
       rcvr_minisel_assrttime_f3 = 0x0
---
+ +
    amph_CFGH_B0_DYN_ISEL(n) = 0x00000001
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x0
       dyn_isel_ctrl_en_f2 = 0x0
       dyn_isel_ctrl_en_f3 = 0x0
---
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + +
if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00000000
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x0
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x0
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000000a8
          RdCwfEarlyCyc_freq0 = 0x8
          RdCwfEarlyCyc_freq1 = 0x0
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x0
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x0
       SpecRdNum = 0x1
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1
       Mcc0AfDramRdPropQTrakEnbl = 0x0
       Mcc0DpPropQCfg = 0x0
       Mcc0DpPropQCmd = 0x1
       Mcc0DpPropQTrakEnbl = 0x0
       Mcc0MsqQPropCfg = 0x0
       Mcc0MsqQPropQCmd = 0x0
       Mcc0MsqQPropTrakEnbl = 0x0
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1
       Mcc1AfDramRdPropQTrakEnbl = 0x0
       Mcc1DpPropQCfg = 0x0
       Mcc1DpPropQCmd = 0x1
       Mcc1DpPropQTrakEnbl = 0x0
       Mcc1MsqQPropCfg = 0x0
       Mcc1MsqQPropQCmd = 0x0
       Mcc1MsqQPropTrakEnbl = 0x0
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
+ +
    spllctrl_SpllCtrl_MDLLPwrDnCfg0(n) = 0x00000001
       Freq3_en = 0x1
       powergating_en = 0x0
---
disable dynamic power-down. + + + + +
if (platform == FPGA)
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
else
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
---
enable dynamic power-down for cold boot. + + + + +
if (platform == FPGA)
       amcx_dramcfg_pwrmngten(n) = 0x00000132
          AutoSR = 0x1
          DynPwrDnEn = 0x0
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
else
          amcx_dramcfg_pwrmngten(n) = 0x00000133
             AutoSR = 0x1
             DynPwrDnEn = 0x1
             McPhyUpdDramClkOff = 0x0
             PwrDnClkOff = 0x1
             SRClkOff = 0x1
             SRExitOpt = 0x1
-No-
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000001ff
          DccEn = 0x1
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
YesNo-
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x00f000f0
       PreFreqChng2AllBankDly_f0 = 0xf0
       PreFreqChng2AllBankDly_f1 = 0xf0
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x00f000f0
       PreFreqChng2AllBankDly_f2 = 0xf0
       PreFreqChng2AllBankDly_f3 = 0xf0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02400240
       PreFreqChng2FreqChngDly_f0 = 0x240
       PreFreqChng2FreqChngDly_f1 = 0x240
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02400240
       PreFreqChng2FreqChngDly_f2 = 0x240
       PreFreqChng2FreqChngDly_f3 = 0x240
---
+ +
    glbtimer_GlbTimer_CalSeg2AllBank0 = 0x00fa0120
       CalSeg2AllBank_f0 = 0x120
       CalSeg2AllBank_f1 = 0xfa
---
+ +
    glbtimer_GlbTimer_AllBank2CalSeg0 = 0x00fa0120
       AllBank2CalSeg_f0 = 0x120
       AllBank2CalSeg_f1 = 0xfa
---


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_DCCTimer = 0x00000bb8
          DCCTimerCnt = 0xbb8
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6bb
          RdCalTimerCnt = 0x2dc6bb
Yes--


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--


SAMSUNG: Skip this step

PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
YesNo-


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x00000001
          PerCal_FreqChngTimerCnt = 0x1
YesNo-


PALLADIUM: Skip this step
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
YesNo-
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa
       MCUBCGClkGateEn = 0x0
       MCUBCGPwrGateEn = 0x0
       PwrRstCyc = 0x5
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x4
       MRCmdCs = 0x0
       MRCmdData = 0x50
       MRCmdIsMPC = 0x0
       MRCmdIsRd = 0x1
       RunMRCmd = 0x1
       RunRdLvl = 0x0
       RunSRExit = 0x0
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Malta_Init_1200_October_29_2015.html b/docs/dcs-specs/Malta_Init_1200_October_29_2015.html new file mode 100644 index 0000000..6f5f8e9 --- /dev/null +++ b/docs/dcs-specs/Malta_Init_1200_October_29_2015.html @@ -0,0 +1,3268 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Thu Oct 29 18:44:46 2015
AMC Version: Major Release: Minor Release:
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/trunk.malta/amcc/tb/cfg/static/maqstb_cfg.pl#25
AMP UM Init sourced from: //depot/ip_lib/apple/amp/trunk.malta/amp/tb/cfg/phy_helper_fxns.pl#19
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - herb - Files Edited: maqstb_cfg.pl#8 -
* changes for updated amph V0013 and mcu init gen flow.
* ------------------------------------------------------------------
* Version:7 - rishah - Files Edited: maqs_gen_cfg.pl#7 - maqstb_cfg.pl#13 -
* Ported over changes from Maui B0 related to INIT Sequence.
* ------------------------------------------------------------------
* Version:8 - rishah - Files Edited: phy_helper_fxns.pl#15 -
* Updated MCU init sequence.
* ------------------------------------------------------------------
* Version:9 - cpolapra - Files Edited: maqs_gen_cfg_c.pl#6 -
* Ported over init and calibration changes from Maui A0/B0 and Elba
* ------------------------------------------------------------------
* Version:10 - rishah - Files Edited: phy_helper_fxns.pl#16 -
* Init sequence update for VrefSel for SW Calib.
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x0
       SpecRdNum = 0x1
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1 *read-only
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1 *read-only
       MccStickyEn = 0x1 *read-only
---
program mccgen + +
    amcc_mcccfg_MccGen = 0x00000194
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0
       MccStop = 0x0
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
+ + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5 *read-only
          ChSelTyp = 0x0 *read-only
          ChnlStartBit = 0x2 *read-only
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3 *read-only
       slvpll_cp_lp = 0x0 *read-only
       slvpll_cp_md = 0x0 *read-only
       slvpll_cp_pd = 0x0 *read-only
       slvpll_cp_r_set = 0x8 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000076
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x6 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000078
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x8
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0 *read-only
       slvpll_reg_pd = 0x0 *read-only
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0 *read-only
       spll_mode_dcs_pwrdn = 0x1 *read-only
       use_idle_for_pd = 0x0 *read-only
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xce012402
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x24
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xce
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0 *read-only
       freqchngmrw9_ctrl_freq0 = 0x0 *read-only
       freqchngmrw9_data_freq0 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303030b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x3
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000416
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x4
       freqchngmrw9_addr_freq1 = 0x0 *read-only
       freqchngmrw9_ctrl_freq1 = 0x0 *read-only
       freqchngmrw9_data_freq1 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0 *read-only
       freqchngmrw9_ctrl_freq2 = 0x0 *read-only
       freqchngmrw9_data_freq2 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0 *read-only
       freqchngmrw9_ctrl_freq3 = 0x0 *read-only
       freqchngmrw9_data_freq3 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-2667 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3 *read-only
       tDQSCKMinCyc_freq0 = 0x0 *read-only
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00103306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3 *read-only
          tDQSCKMinCyc_freq0 = 0x0 *read-only
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2 *read-only
       tDQSCKMinCyc_freq1 = 0x0 *read-only
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2 *read-only
          tDQSCKMinCyc_freq1 = 0x0 *read-only
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010d01
       PHYRdLat_freq0 = 0xd
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00050d0a
          PHYRdLat_freq0 = 0xd
          PHYtPhyWrlat_freq0 = 0x5
          PHYtRddataEn_freq0 = 0xa
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010c01
       PHYRdLat_freq1 = 0xc
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050c06
          PHYRdLat_freq1 = 0xc
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010c01
       PHYRdLat_freq2 = 0xc
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010c01
          PHYRdLat_freq2 = 0xc
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x42110408
       tRASCyc_freq0 = 0x11
       tRCDCyc_freq0 = 0x8
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x8
       tWTRCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x531a060b
          tRASCyc_freq0 = 0x1a
          tRCDCyc_freq0 = 0xb
          tRTPCyc_freq0 = 0x5
          tWRCyc_freq0 = 0xc
          tWTRCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x10040908
       tFAWCyc_freq0 = 0x10
       tRPCyc_freq0 = 0x8
       tRPabCyc_freq0 = 0x9
       tRRDCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x18060d0b
          tFAWCyc_freq0 = 0x18
          tRPCyc_freq0 = 0xb
          tRPabCyc_freq0 = 0xd
          tRRDCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c0078
          tRFCBaseCyc_freq0 = 0x78 *read-only
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0x50057012
       tFCCyc_freq0 = 0x50
       tXSRCyc_freq0 = 0x57
       tZQCalCyc_freq0 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq0(n) = 0x78071012
          tFCCyc_freq0 = 0x78
          tXSRCyc_freq0 = 0x71
          tZQCalCyc_freq0 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x0e0a9084
       tMRRCyc = 0x4
       tMRRICyc = 0x8
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0xe
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060a9024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x140a90b4
          tMRRCyc = 0x4
          tMRRICyc = 0xb
          tMRWCyc = 0x9
          tVRCGOFFCyc = 0xa
          tZQLatCyc = 0x14
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x42110408
       tRASCyc_freq1 = 0x11
       tRCDCyc_freq1 = 0x8
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x8
       tWTRCyc_freq1 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480050. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480050.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50 *read-only
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50 *read-only
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0x50057012
       tFCCyc_freq1 = 0x50
       tXSRCyc_freq1 = 0x57
       tZQCalCyc_freq1 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x42110408
       tRASCyc_freq2 = 0x11
       tRCDCyc_freq2 = 0x8
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x8
       tWTRCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x10040908
       tFAWCyc_freq2 = 0x10
       tRPCyc_freq2 = 0x8
       tRPabCyc_freq2 = 0x9
       tRRDCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14 *read-only
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0x50057012
       tFCCyc_freq2 = 0x50
       tXSRCyc_freq2 = 0x57
       tZQCalCyc_freq2 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x42110408
       tRASCyc_freq3 = 0x11
       tRCDCyc_freq3 = 0x8
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x8
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x10040b0a
       tFAWCyc_freq3 = 0x10
       tRPCyc_freq3 = 0xa
       tRPabCyc_freq3 = 0xb
       tRRDCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5 *read-only
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x50057012
       tFCCyc_freq3 = 0x50
       tXSRCyc_freq3 = 0x57
       tZQCalCyc_freq3 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15 *read-only
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15 *read-only
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x31263263
       tCKECyc = 0x3
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x3
       tCKb4CKECyc = 0x1
       tXPCyc = 0x3
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21262222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x62265295
          tCKECyc = 0x5
          tCKEPDECyc = 0x1 *read-only
          tCKESRCyc = 0x9
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x6
          tCKafCKECyc = 0x6
          tCKb4CKECyc = 0x2
          tXPCyc = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq0 = 0x3
       tRASDrtCyc_freq0 = 0x12
       tRCDDrtCyc_freq0 = 0x8
       tRPDrtCyc_freq0 = 0x8
       tRPabDrtCyc_freq0 = 0xa
       tRRDDrtCyc_freq0 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x38c486cc
          tDQSCKMaxDrtCyc_freq0 = 0x4
          tRASDrtCyc_freq0 = 0x1b
          tRCDDrtCyc_freq0 = 0xc
          tRPDrtCyc_freq0 = 0xc
          tRPabDrtCyc_freq0 = 0xe
          tRRDDrtCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq1 = 0x3
       tRASDrtCyc_freq1 = 0x12
       tRCDDrtCyc_freq1 = 0x8
       tRPDrtCyc_freq1 = 0x8
       tRPabDrtCyc_freq1 = 0xa
       tRRDDrtCyc_freq1 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq2 = 0x3
       tRASDrtCyc_freq2 = 0x12
       tRCDDrtCyc_freq2 = 0x8
       tRPDrtCyc_freq2 = 0x8
       tRPabDrtCyc_freq2 = 0xa
       tRRDDrtCyc_freq2 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x30a35488
       tDQSCKMaxDrtCyc_freq3 = 0x3
       tRASDrtCyc_freq3 = 0x12
       tRCDDrtCyc_freq3 = 0x8
       tRPDrtCyc_freq3 = 0xa
       tRPabDrtCyc_freq3 = 0xc
       tRRDDrtCyc_freq3 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00112306
       DRAMRL_freq0 = 0xc
       DRAMWL_freq0 = 0x6
       tDQSCKMaxCyc_freq0 = 0x2
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00113306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x1
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00112206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001120c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x2
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001120c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x2
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2rTatDeadCyc_freq0 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wTatDeadCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_tat_freq0(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2rTatDeadCyc_freq0 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2wTatDeadCyc_freq0 = 0x3
          W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wTatDeadCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2rTatDeadCyc_freq1 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wTatDeadCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2rTatDeadCyc_freq1 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wTatDeadCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2rTatDeadCyc_freq2 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2wTatDeadCyc_freq2 = 0x3
       W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wTatDeadCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2rTatDeadCyc_freq2 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wTatDeadCyc_freq2 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq3(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2rTatDeadCyc_freq3 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2wTatDeadCyc_freq3 = 0x3
       W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wTatDeadCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_tat_freq3(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2rTatDeadCyc_freq3 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2wTatDeadCyc_freq3 = 0x2
          W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wTatDeadCyc_freq3 = 0x1 *read-only
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0 *read-only
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0 *read-only
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0 *read-only
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0 *read-only
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0 *read-only
       SchEn = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3 *read-only
       PhyInitStartCyc = 0x0 *read-only
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f0(n) = 0x000b316b
       CaDsPd_f0 = 0xb
       Ck0DsPd_f0 = 0xb
       Ck1DsPd_f0 = 0xc *read-only
       CsDsPd_f0 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f1(n) = 0x000b216b
       CaDsPd_f1 = 0xb
       Ck0DsPd_f1 = 0xb
       Ck1DsPd_f1 = 0x8 *read-only
       CsDsPd_f1 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f2(n) = 0x000b3d6b
       CaDsPd_f2 = 0xb
       Ck0DsPd_f2 = 0xb
       Ck1DsPd_f2 = 0xf *read-only
       CsDsPd_f2 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f3(n) = 0x000b3d6b
       CaDsPd_f3 = 0xb
       Ck0DsPd_f3 = 0xb
       Ck1DsPd_f3 = 0xf *read-only
       CsDsPd_f3 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqds_f1(n) = 0x00080508
       CaDs_f1 = 0x8
       Ck0Ds_f1 = 0x8
       Ck1Ds_f1 = 0x1 *read-only
       CsDs_f1 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f2(n) = 0x00083d08
       CaDs_f2 = 0x8
       Ck0Ds_f2 = 0x8
       Ck1Ds_f2 = 0xf *read-only
       CsDs_f2 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f3(n) = 0x00083d08
       CaDs_f3 = 0x8
       Ck0Ds_f3 = 0x8
       Ck1Ds_f3 = 0xf *read-only
       CsDs_f3 = 0x8
---
+ +
    ampsca_ampscaiocfg_CaCkCsWkDs(n) = 0x000000db
       CaWkDs = 0x3
       CkWkDs = 0x3
       CsWkDs = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f0(n) = 0x000c0b08
       RdDqODTDs = 0xc
       WrDqPdDs = 0xb
       WrDqPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqds_f1(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f2(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f3(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f0(n) = 0x000c0b08
       RdDqDqsODTDs = 0xc
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f1(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f2(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f3(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsdq_ampsdqodt_VRef_f2(n) = 0x00800080
       DqsVRefSel = 0x80
       VRefSel = 0x80
---
+ +
    ampsdq_ampsdqodt_VRef_f3(n) = 0x00800080
       DqsVRefSel = 0x80
       VRefSel = 0x80
---
+ +
    ampsdq_ampsdqrdtim_dqspdres(n) = 0x00000001
       DqsPdVal = 0x1 *read-only
       DqsWkPuPdVal = 0x0
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x0303030b
       ClkEn2Valid = 0x3 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x3 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x0003000b
       ClkEn2Valid = 0x0 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x0 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0004
       Rd0RunSDLLUpd = 0x0 *read-only
       Rd0RunSDLLUpdOverride = 0x0 *read-only
       Rd0RunSDLLUpdWrResult = 0x0 *read-only
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000004
       WrDqDqsRunSDLLUpd = 0x0 *read-only
       WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
       WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
       WrDqDqsWrLvlReBalanceEn = 0x0 *read-only
       WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
       WrDqSDLLHalfClkEn = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff02ff
       WrLvlMaxWrDqsSDLLCode = 0xff *read-only
       WrLvlRunUpdOverride = 0x0 *read-only
       WrLvlRunUpdWrResult = 0x0 *read-only
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdWrResult
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x04000410
       tCA2CAEntry = 0x10
       tCA2CAExit = 0x0
       tCKEHEntry = 0x4
       tCKEHExit = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000410
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000410
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000410
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x04020402
       tCA2CAEntry_f0 = 0x2
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x4
       tCKEHExit_f0 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020402
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020402
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020402
       tCA2CAEntry_f3 = 0x2
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x00001426
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x6
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x00001422
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000301e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x30
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x03111004
       tRd2Rd = 0x4
       tRd2Wr = 0x10
       tWr2Rd = 0x11
       tWr2Wr = 0x3 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00b101d1
       EndPoint = 0xb1
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x012f0360
       EndPoint = 0x12f
       StartPoint = 0x360 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00f801d1
       EndPoint = 0xf8
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x012f0360
       EndPoint = 0x12f
       StartPoint = 0x360 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxRdDqsSDLLMulFactor(n) = 0x00a01414
       MaxRdDqsSDLLCodeStatus = 0xa0 *read-only
       RdDqsSDLLMulFactorF0 = 0x14
       RdDqsSDLLMulFactorF1 = 0x14
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqSDLLMulFactor(n) = 0x00a00a0f
       MaxWrDqSDLLCodeStatus = 0xa0 *read-only
       WrDqSDLLMulFactorF0 = 0xf
       WrDqSDLLMulFactorF1 = 0xa
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a00c0c
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xc
       WrDqsSDLLMulFactorF1 = 0xc
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0 *read-only
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq0(n) = 0x00000008
       CaOutDllScl_f0 = 0x8
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq0(n) = 0x00000008
       DqsInDll0Scl_f0 = 0x8
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100080a
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0xa
       RdDatLat_f0 = 0x8
       WrPhaseDelay_f0 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100080d
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1 *read-only
          RdCapLat_f0 = 0xd
          RdDatLat_f0 = 0x8
          WrPhaseDelay_f0 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq1(n) = 0x0000000c
       CaOutDllScl_f1 = 0xc
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq1(n) = 0x0000000c
       DqsInDll0Scl_f1 = 0xc
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1 *read-only
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100070a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1 *read-only
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x7
          WrPhaseDelay_f1 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq2(n) = 0x00000030
       CaOutDllScl_f2 = 0x30
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq2(n) = 0x00000030
       DqsInDll0Scl_f2 = 0x30
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x4100050a
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0xa
       RdDatLat_f2 = 0x5
       WrPhaseDelay_f2 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000508
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1 *read-only
          RdCapLat_f2 = 0x8
          RdDatLat_f2 = 0x5
          WrPhaseDelay_f2 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq3(n) = 0x0000003f
       CaOutDllScl_f3 = 0x3f
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq3(n) = 0x0000003f
       DqsInDll0Scl_f3 = 0x3f
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x6100050a
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1 *read-only
       RdCapLat_f3 = 0xa
       RdDatLat_f3 = 0x5
       WrPhaseDelay_f3 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1 *read-only
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000508
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1 *read-only
          RdCapLat_f3 = 0x8
          RdDatLat_f3 = 0x5
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---


FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impautocal(n) = 0x00010000
          impautocalen = 0x1
          impcalintvl = 0x0 *read-only
          impcaltype = 0x0
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
Enable DLL + +
    ampsca_ampscadllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000000
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
+ +
    amph_CFGH_CB_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x0 *read-only
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x0 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x0
---
+ +
    amph_CFGH_CB_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CB_IOCTL(n) = 0x000200a3
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x0 *read-only
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       protect_drvstren = 0x1 *read-only
       sel_rx_ac = 0x0 *read-only
       sel_rx_dc = 0x0 *read-only
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_CK_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x0 *read-only
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x0 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x0
---
+ +
    amph_CFGH_CK_ZDET_BIASEN(n) = 0x00000000
       bias_ena = 0x0 *read-only
       disable_zdet = 0x0
       sel_zdet = 0x0 *read-only
---
+ +
    amph_CFGH_CK_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CK_IOCTL(n) = 0x000000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       sel_rx_ac = 0x0 *read-only
       sel_rx_dc = 0x0 *read-only
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_B0_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_B0_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B0_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B0_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B1_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_B1_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B1_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS0_WKPUPD(n) = 0x00000788
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x1
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x1 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x7 *read-only
---
+ +
    amph_CFGH_DQS0_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS0_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS0_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x1
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_WKPUPD(n) = 0x00000788
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x1
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x1 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x7 *read-only
---
+ +
    amph_CFGH_DQS1_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS1_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS1_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x1
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DBG_DBG_REG0(n) = 0x00000000
       cb_bias_ena = 0x0
       cb_odte = 0x0 *read-only
       clk_en_sync_flop_rst = 0x0 *read-only
       mon_vdd_mem = 0x0 *read-only
       mon_vdd_soc = 0x0 *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM1(n) = 0x00667f7f
       bias_ena_dly = 0x66
       io_pd = 0x7f *read-only
       io_pu = 0x7f *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM0(n) = 0x000f0315
       zc_dly = 0x15
       zc_dnbd = 0x0
       zc_tap = 0x3
       zc_upbd = 0xf
---
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x0000000e
       control = 0xe
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x08010019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0x8
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480050
       tRFCBaseCyc_freq3 = 0x50
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480050
       tRFCBaseCyc_freq2 = 0x50
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480049. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480049.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480050
       tRFCBaseCyc_freq0 = 0x50
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c006e
          tRFCBaseCyc_freq0 = 0x6e
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00170013
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0 *read-only
          ShareZQRes = 0x0 *read-only
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x0 *read-only
          ZqCalIntrvl = 0x0 *read-only
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01012008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030007
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x7
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x11100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x1
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x11000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x1
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x11110000
          ARpbEn_freq1 = 0x1 *read-only
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x1
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1111013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x1
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00010000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00000000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR11 for FPGA

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and Modified Refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x26204100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5e284100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + +
if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000001f
       DramSize = 0x1f
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050201
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060201
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060210
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x1
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060220
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x2
          NumMcuChnl = 0x2
---
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

7. Setup registers for CA calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1, and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x52020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xae010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x030b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0 *read-only
          WrLvlRunUpdWrResult = 0x0 *read-only
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode

FPGA: Skip this step
+ +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

8. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step8Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 1, 16, 12);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change

FPGA: Skip this step
+ +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x0 *read-only
YesYes-
Poll ampsdqdllctl dllupdtcmd

FPGA: Skip this step
+ +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
RdWrDqCalSegLen_f0

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
RdWrDqCalSegLen_f1

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
          freqchngmrw2_addr_freq0 = 0xe
          freqchngmrw2_ctrl_freq0 = 0x0
          freqchngmrw2_data_freq0 = 0x11
          freqchngmrw3_addr_freq0 = 0xc
          freqchngmrw3_ctrl_freq0 = 0x0
          freqchngmrw3_data_freq0 = 0x11
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
          freqchngmrw2_addr_freq1 = 0xe
          freqchngmrw2_ctrl_freq1 = 0x0
          freqchngmrw2_data_freq1 = 0x11
          freqchngmrw3_addr_freq1 = 0xc
          freqchngmrw3_ctrl_freq1 = 0x0
          freqchngmrw3_data_freq1 = 0x11
YesYes-


FPGA: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x0
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
else
          amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
             freqchngmrw4_addr_freq0 = 0xb
             freqchngmrw4_ctrl_freq0 = 0x0
             freqchngmrw4_data_freq0 = 0x44
             freqchngmrw5_addr_freq0 = 0x3
             freqchngmrw5_ctrl_freq0 = 0x0
             freqchngmrw5_data_freq0 = 0xb3
YesYes-


FPGA: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x00061a80
          ZQCTimerCnt = 0x61a80
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

9. Setup registers for DQ calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xd80d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
YesNo-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngten(n) = 0x00000002
          AutoSR = 0x1
          DynPwrDnEn = 0x0 *read-only
          McPhyUpdDramClkOff = 0x0 *read-only
          PwrDnClkOff = 0x0 *read-only
          SRClkOff = 0x0 *read-only
          SRExitOpt = 0x0 *read-only
-Yes-
Program FreqChngMRW Cnt

FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
YesYes-
WrDqDqsSDLLCtrl

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff00000c
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates

FPGA: Skip this step
+ +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 800Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl

FPGA: Skip this step
+ +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

10. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 1, 16, 12);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
The scale factors for Bin0 and Bin1 WR DQS/DQ skew have to to programmed to the correct values based on board charaterization. Fields are being set to 0 here, since exact board skews are not available now (04/01/14).

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_WrtDQSDQSkewControl(n) = 0x06000000
          WrDqDqsIDTVTScaleEn = 0x1 *read-only
          WrDqDqsMDLLVTScaleEn = 0x1 *read-only
          WrtDQSDQScaleFactorF0 = 0x0
          WrtDQSDQScaleFactorF1 = 0x0
          WrtDQSDQScaleFactorPlusSel = 0x0
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00000788
          idle_active_en_f0 = 0x0
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00000788
          idle_active_en_f0 = 0x0
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-
Program FSP-WR to 0 and FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x24020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xce010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 24, 12);
+
---


FPGA: Skip this step

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x340b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x4f004100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x51004100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 20ns for tZQLAT. +
---


SAMSUNG: Perform this step
+ +
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303340b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x34
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
-No-
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 0 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Call custom API provided by PMGR for changing mcu_clk to 1200Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl

FPGA: Skip this step
+ +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 24, 12);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x0000040e
       control = 0x40e
---
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG, since all calibrations are done + +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-


DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x001a0004
          Rd0RunSDLLUpd = 0x0 *read-only
          Rd0RunSDLLUpdOverride = 0x0 *read-only
          Rd0RunSDLLUpdWrResult = 0x0 *read-only
          Rd0SDLLOvrVal = 0x1a
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x08010019
       FreqChngWaitThr = 0x1 *read-only
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0x8
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0 *read-only
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x11100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x1
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x11000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x1
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x11110000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x1
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1111013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x1
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+ +
    amph_CFGH_B0_DYN_ISEL_ASRTIME(n) = 0x00001117
       rcvr_minisel_assrttime_f0 = 0x17
       rcvr_minisel_assrttime_f1 = 0x11
       rcvr_minisel_assrttime_f2 = 0x0 *read-only
       rcvr_minisel_assrttime_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_DYN_ISEL(n) = 0x00000003
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_DYN_ISEL(n) = 0x00000003
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_DCD_IOCTL(n) = 0x00030000
       dcdi = 0x0 *read-only
       dcdo = 0x0 *read-only
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_DCD_IOCTL(n) = 0x00030000
       dcdi = 0x0 *read-only
       dcdo = 0x0 *read-only
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbrparam(n) = 0x61616161
       RdCwfEarlyCyc_freq0 = 0x1
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x1
       RdCwfEarlyCyc_freq3 = 0x1
       RdRemEarlyCyc_freq0 = 0x6
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x6
       RdRemEarlyCyc_freq3 = 0x6
else if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00006100
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000061a5
          RdCwfEarlyCyc_freq0 = 0x5
          RdCwfEarlyCyc_freq1 = 0x1
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x6
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1 *read-only
       Mcc0AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc0DpPropQCfg = 0x0 *read-only
       Mcc0DpPropQCmd = 0x1 *read-only
       Mcc0DpPropQTrakEnbl = 0x0 *read-only
       Mcc0MsqQPropCfg = 0x0 *read-only
       Mcc0MsqQPropQCmd = 0x0 *read-only
       Mcc0MsqQPropTrakEnbl = 0x0 *read-only
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0 *read-only
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0 *read-only
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1 *read-only
       Mcc1AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc1DpPropQCfg = 0x0 *read-only
       Mcc1DpPropQCmd = 0x1 *read-only
       Mcc1DpPropQTrakEnbl = 0x0 *read-only
       Mcc1MsqQPropCfg = 0x0 *read-only
       Mcc1MsqQPropQCmd = 0x0 *read-only
       Mcc1MsqQPropTrakEnbl = 0x0 *read-only
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0 *read-only
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0 *read-only
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1 *read-only
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0 *read-only
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
disable dynamic power-down. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
---
disable dynamic power-down. + +
       amcx_dramcfg_pwrmngten(n) = 0x00000133
          AutoSR = 0x1
          DynPwrDnEn = 0x1
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
-No-
Revert auto self-refresh wait timer to guided value.

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngtparam_freq0(n) = 0x01800000
          BypsPwrDnDlyCyc_freq0 = 0x0 *read-only
          SelfRefTmrVal_freq0 = 0x180
---
Setting WqAgeOutVal to be 3/4 of SelfRefTmrVal, to flush writes in a reasonable time.

FPGA: Skip this step
+ +
       amcx_mcusch_psqwqctl1(n) = 0x01640120
          WqAgeOutVal_freq0 = 0x120
          WqAgeOutVal_freq1 = 0x164 *read-only
---
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000000ff
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
Yes--
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x01500150
       PreFreqChng2AllBankDly_f0 = 0x150
       PreFreqChng2AllBankDly_f1 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x01500150
       PreFreqChng2AllBankDly_f2 = 0x150
       PreFreqChng2AllBankDly_f3 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02a002a0
       PreFreqChng2FreqChngDly_f0 = 0x2a0
       PreFreqChng2FreqChngDly_f1 = 0x2a0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02a002a0
       PreFreqChng2FreqChngDly_f2 = 0x2a0
       PreFreqChng2FreqChngDly_f3 = 0x2a0
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly0 = 0x00900090
       Cal2PreFreqChngDly_f0 = 0x90
       Cal2PreFreqChngDly_f1 = 0x90
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly1 = 0x00900090
       Cal2PreFreqChngDly_f2 = 0x90
       Cal2PreFreqChngDly_f3 = 0x90
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly0 = 0x01200120
       FreqChng2PstCalDly_f0 = 0x120
       FreqChng2PstCalDly_f1 = 0x120
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly1 = 0x01200120
       FreqChng2PstCalDly_f2 = 0x120
       FreqChng2PstCalDly_f3 = 0x120
---
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6c0
          RdCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--


SAMSUNG: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
YesNo-
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x000493e0
          PerCal_FreqChngTimerCnt = 0x493e0
YesNo-
+ +
       glbtimer_GlbTimer_VoltRampTimer = 0x000493e0
          VoltRampTimerCnt = 0x493e0
YesNo-
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
YesNo-
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly0 = 0x00d800d8
          VoltRamp2AllBankDly_f0 = 0xd8
          VoltRamp2AllBankDly_f1 = 0xd8
YesNo-
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly1 = 0x00d800d8
          VoltRamp2AllBankDly_f2 = 0xd8
          VoltRamp2AllBankDly_f3 = 0xd8
YesNo-
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly0 = 0x00900090
          AllBank2PmgrAckDly_f0 = 0x90
          AllBank2PmgrAckDly_f1 = 0x90
YesNo-
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly1 = 0x00900090
          AllBank2PmgrAckDly_f2 = 0x90
          AllBank2PmgrAckDly_f3 = 0x90
YesNo-
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa *read-only
       MCUBCGClkGateEn = 0x0 *read-only
       MCUBCGPwrGateEn = 0x0 *read-only
       PwrRstCyc = 0x5 *read-only
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0 *read-only
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Malta_Init_A0_1200_June_17_2015.html b/docs/dcs-specs/Malta_Init_A0_1200_June_17_2015.html new file mode 100644 index 0000000..72a63c7 --- /dev/null +++ b/docs/dcs-specs/Malta_Init_A0_1200_June_17_2015.html @@ -0,0 +1,3186 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Wed Jun 17 11:45:29 2015
AMC Version: Major Release: Minor Release:
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/a0.malta/amcc/tb/cfg/static/maqstb_cfg.pl#18
AMP UM Init sourced from: //depot/ip_lib/apple/amp/a0.malta/amp/tb/cfg/phy_helper_fxns.pl#5
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - herb - Files Edited: maqstb_cfg.pl#8 -
* changes for updated amph V0013 and mcu init gen flow.
* ------------------------------------------------------------------
* Version:7 - rishah - Files Edited: maqs_gen_cfg.pl#7 - maqstb_cfg.pl#13 -
* Ported over changes from Maui B0 related to INIT Sequence.
* ------------------------------------------------------------------
* Version:8 - rishah - Files Edited: phy_helper_fxns.pl#15 -
* Updated MCU init sequence.
* ------------------------------------------------------------------
* Version:9 - cpolapra - Files Edited: maqs_gen_cfg_c.pl#6 -
* Ported over init and calibration changes from Maui A0/B0 and Elba
* ------------------------------------------------------------------
* Version:10 - rishah - Files Edited: phy_helper_fxns.pl#16 -
* Init sequence update for VrefSel for SW Calib.
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1
       MccStickyEn = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
Maximum Number of Powered Ways. + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000110
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x1 *read-only
---
Turn on the MCC + +
    amcc_mcccfg_MccGen = 0x00000195
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x1
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
Set Dynamic Way PowerGating + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000010
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x0
---
+ + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5 *read-only
          ChSelTyp = 0x0 *read-only
          ChnlStartBit = 0x2 *read-only
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3 *read-only
       slvpll_cp_lp = 0x0 *read-only
       slvpll_cp_md = 0x0 *read-only
       slvpll_cp_pd = 0x0 *read-only
       slvpll_cp_r_set = 0x8 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000076
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x6 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000078
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x8
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0 *read-only
       slvpll_reg_pd = 0x0 *read-only
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0 *read-only
       spll_mode_dcs_pwrdn = 0x1 *read-only
       use_idle_for_pd = 0x0 *read-only
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xce012402
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x24
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xce
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0 *read-only
       freqchngmrw9_ctrl_freq0 = 0x0 *read-only
       freqchngmrw9_data_freq0 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303030b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x3
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000416
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x4
       freqchngmrw9_addr_freq1 = 0x0 *read-only
       freqchngmrw9_ctrl_freq1 = 0x0 *read-only
       freqchngmrw9_data_freq1 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0 *read-only
       freqchngmrw9_ctrl_freq2 = 0x0 *read-only
       freqchngmrw9_data_freq2 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0 *read-only
       freqchngmrw9_ctrl_freq3 = 0x0 *read-only
       freqchngmrw9_data_freq3 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-2667 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3 *read-only
       tDQSCKMinCyc_freq0 = 0x0 *read-only
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00103306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3 *read-only
          tDQSCKMinCyc_freq0 = 0x0 *read-only
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2 *read-only
       tDQSCKMinCyc_freq1 = 0x0 *read-only
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2 *read-only
          tDQSCKMinCyc_freq1 = 0x0 *read-only
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010d01
       PHYRdLat_freq0 = 0xd
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00050d0a
          PHYRdLat_freq0 = 0xd
          PHYtPhyWrlat_freq0 = 0x5
          PHYtRddataEn_freq0 = 0xa
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010c01
       PHYRdLat_freq1 = 0xc
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050c06
          PHYRdLat_freq1 = 0xc
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010c01
       PHYRdLat_freq2 = 0xc
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010c01
          PHYRdLat_freq2 = 0xc
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x42110408
       tRASCyc_freq0 = 0x11
       tRCDCyc_freq0 = 0x8
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x8
       tWTRCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x531a060b
          tRASCyc_freq0 = 0x1a
          tRCDCyc_freq0 = 0xb
          tRTPCyc_freq0 = 0x5
          tWRCyc_freq0 = 0xc
          tWTRCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x10040908
       tFAWCyc_freq0 = 0x10
       tRPCyc_freq0 = 0x8
       tRPabCyc_freq0 = 0x9
       tRRDCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x18060d0b
          tFAWCyc_freq0 = 0x18
          tRPCyc_freq0 = 0xb
          tRPabCyc_freq0 = 0xd
          tRRDCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c0078
          tRFCBaseCyc_freq0 = 0x78 *read-only
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0x50057012
       tFCCyc_freq0 = 0x50
       tXSRCyc_freq0 = 0x57
       tZQCalCyc_freq0 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq0(n) = 0x78071012
          tFCCyc_freq0 = 0x78
          tXSRCyc_freq0 = 0x71
          tZQCalCyc_freq0 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x0e0a9084
       tMRRCyc = 0x4
       tMRRICyc = 0x8
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0xe
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060a9024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x140a90b4
          tMRRCyc = 0x4
          tMRRICyc = 0xb
          tMRWCyc = 0x9
          tVRCGOFFCyc = 0xa
          tZQLatCyc = 0x14
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x42110408
       tRASCyc_freq1 = 0x11
       tRCDCyc_freq1 = 0x8
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x8
       tWTRCyc_freq1 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480050. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480050.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50 *read-only
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50 *read-only
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0x50057012
       tFCCyc_freq1 = 0x50
       tXSRCyc_freq1 = 0x57
       tZQCalCyc_freq1 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x42110408
       tRASCyc_freq2 = 0x11
       tRCDCyc_freq2 = 0x8
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x8
       tWTRCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x10040908
       tFAWCyc_freq2 = 0x10
       tRPCyc_freq2 = 0x8
       tRPabCyc_freq2 = 0x9
       tRRDCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14 *read-only
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0x50057012
       tFCCyc_freq2 = 0x50
       tXSRCyc_freq2 = 0x57
       tZQCalCyc_freq2 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x42110408
       tRASCyc_freq3 = 0x11
       tRCDCyc_freq3 = 0x8
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x8
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x10040b0a
       tFAWCyc_freq3 = 0x10
       tRPCyc_freq3 = 0xa
       tRPabCyc_freq3 = 0xb
       tRRDCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5 *read-only
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x50057012
       tFCCyc_freq3 = 0x50
       tXSRCyc_freq3 = 0x57
       tZQCalCyc_freq3 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15 *read-only
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15 *read-only
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x31263263
       tCKECyc = 0x3
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x3
       tCKb4CKECyc = 0x1
       tXPCyc = 0x3
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21262222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x62265295
          tCKECyc = 0x5
          tCKEPDECyc = 0x1 *read-only
          tCKESRCyc = 0x9
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x6
          tCKafCKECyc = 0x6
          tCKb4CKECyc = 0x2
          tXPCyc = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq0 = 0x3
       tRASDrtCyc_freq0 = 0x12
       tRCDDrtCyc_freq0 = 0x8
       tRPDrtCyc_freq0 = 0x8
       tRPabDrtCyc_freq0 = 0xa
       tRRDDrtCyc_freq0 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x38c486cc
          tDQSCKMaxDrtCyc_freq0 = 0x4
          tRASDrtCyc_freq0 = 0x1b
          tRCDDrtCyc_freq0 = 0xc
          tRPDrtCyc_freq0 = 0xc
          tRPabDrtCyc_freq0 = 0xe
          tRRDDrtCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq1 = 0x3
       tRASDrtCyc_freq1 = 0x12
       tRCDDrtCyc_freq1 = 0x8
       tRPDrtCyc_freq1 = 0x8
       tRPabDrtCyc_freq1 = 0xa
       tRRDDrtCyc_freq1 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq2 = 0x3
       tRASDrtCyc_freq2 = 0x12
       tRCDDrtCyc_freq2 = 0x8
       tRPDrtCyc_freq2 = 0x8
       tRPabDrtCyc_freq2 = 0xa
       tRRDDrtCyc_freq2 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x30a35488
       tDQSCKMaxDrtCyc_freq3 = 0x3
       tRASDrtCyc_freq3 = 0x12
       tRCDDrtCyc_freq3 = 0x8
       tRPDrtCyc_freq3 = 0xa
       tRPabDrtCyc_freq3 = 0xc
       tRRDDrtCyc_freq3 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00112306
       DRAMRL_freq0 = 0xc
       DRAMWL_freq0 = 0x6
       tDQSCKMaxCyc_freq0 = 0x2
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00113306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x1
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00112206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001120c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x2
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001120c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x2
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2rTatDeadCyc_freq0 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wTatDeadCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_tat_freq0(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2rTatDeadCyc_freq0 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2wTatDeadCyc_freq0 = 0x3
          W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wTatDeadCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2rTatDeadCyc_freq1 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wTatDeadCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2rTatDeadCyc_freq1 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wTatDeadCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2rTatDeadCyc_freq2 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2wTatDeadCyc_freq2 = 0x3
       W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wTatDeadCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2rTatDeadCyc_freq2 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wTatDeadCyc_freq2 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq3(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2rTatDeadCyc_freq3 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2wTatDeadCyc_freq3 = 0x3
       W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wTatDeadCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_tat_freq3(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2rTatDeadCyc_freq3 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2wTatDeadCyc_freq3 = 0x2
          W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wTatDeadCyc_freq3 = 0x1 *read-only
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0 *read-only
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0 *read-only
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0 *read-only
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0 *read-only
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0 *read-only
       SchEn = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3 *read-only
       PhyInitStartCyc = 0x0 *read-only
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f0(n) = 0x000b316b
       CaDsPd_f0 = 0xb
       Ck0DsPd_f0 = 0xb
       Ck1DsPd_f0 = 0xc *read-only
       CsDsPd_f0 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f1(n) = 0x000b216b
       CaDsPd_f1 = 0xb
       Ck0DsPd_f1 = 0xb
       Ck1DsPd_f1 = 0x8 *read-only
       CsDsPd_f1 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f2(n) = 0x000b3d6b
       CaDsPd_f2 = 0xb
       Ck0DsPd_f2 = 0xb
       Ck1DsPd_f2 = 0xf *read-only
       CsDsPd_f2 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f3(n) = 0x000b3d6b
       CaDsPd_f3 = 0xb
       Ck0DsPd_f3 = 0xb
       Ck1DsPd_f3 = 0xf *read-only
       CsDsPd_f3 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqds_f1(n) = 0x00080508
       CaDs_f1 = 0x8
       Ck0Ds_f1 = 0x8
       Ck1Ds_f1 = 0x1 *read-only
       CsDs_f1 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f2(n) = 0x00083d08
       CaDs_f2 = 0x8
       Ck0Ds_f2 = 0x8
       Ck1Ds_f2 = 0xf *read-only
       CsDs_f2 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f3(n) = 0x00083d08
       CaDs_f3 = 0x8
       Ck0Ds_f3 = 0x8
       Ck1Ds_f3 = 0xf *read-only
       CsDs_f3 = 0x8
---
+ +
    ampsca_ampscaiocfg_CaCkCsWkDs(n) = 0x000000db
       CaWkDs = 0x3
       CkWkDs = 0x3
       CsWkDs = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f0(n) = 0x000c0b08
       RdDqODTDs = 0xc
       WrDqPdDs = 0xb
       WrDqPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqds_f1(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f2(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f3(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f0(n) = 0x000c0b08
       RdDqDqsODTDs = 0xc
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f1(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f2(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f3(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
+ +
    ampsdq_ampsdqodt_VRef_f2(n) = 0x00800080
       DqsVRefSel = 0x80
       VRefSel = 0x80
---
+ +
    ampsdq_ampsdqodt_VRef_f3(n) = 0x00800080
       DqsVRefSel = 0x80
       VRefSel = 0x80
---
+ +
    ampsdq_ampsdqrdtim_dqspdres(n) = 0x00000001
       DqsPdVal = 0x1 *read-only
       DqsWkPuPdVal = 0x0
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x0303030b
       ClkEn2Valid = 0x3 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x3 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x0003000b
       ClkEn2Valid = 0x0 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x0 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0004
       Rd0RunSDLLUpd = 0x0 *read-only
       Rd0RunSDLLUpdOverride = 0x0 *read-only
       Rd0RunSDLLUpdWrResult = 0x0 *read-only
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000004
       WrDqDqsRunSDLLUpd = 0x0 *read-only
       WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
       WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
       WrDqDqsWrLvlReBalanceEn = 0x0 *read-only
       WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
       WrDqSDLLHalfClkEn = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff02ff
       WrLvlMaxWrDqsSDLLCode = 0xff *read-only
       WrLvlRunUpdOverride = 0x0 *read-only
       WrLvlRunUpdWrResult = 0x0 *read-only
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdWrResult
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x04000410
       tCA2CAEntry = 0x10
       tCA2CAExit = 0x0
       tCKEHEntry = 0x4
       tCKEHExit = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000410
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000410
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000410
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x04020402
       tCA2CAEntry_f0 = 0x2
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x4
       tCKEHExit_f0 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020402
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020402
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020402
       tCA2CAEntry_f3 = 0x2
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x00001426
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x6
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x00001422
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000301e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x30
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x03111004
       tRd2Rd = 0x4
       tRd2Wr = 0x10
       tWr2Rd = 0x11
       tWr2Wr = 0x3 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00b101d1
       EndPoint = 0xb1
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x012f0360
       EndPoint = 0x12f
       StartPoint = 0x360 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00f801d1
       EndPoint = 0xf8
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x012f0360
       EndPoint = 0x12f
       StartPoint = 0x360 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxRdDqsSDLLMulFactor(n) = 0x00a01414
       MaxRdDqsSDLLCodeStatus = 0xa0 *read-only
       RdDqsSDLLMulFactorF0 = 0x14
       RdDqsSDLLMulFactorF1 = 0x14
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqSDLLMulFactor(n) = 0x00a00a0f
       MaxWrDqSDLLCodeStatus = 0xa0 *read-only
       WrDqSDLLMulFactorF0 = 0xf
       WrDqSDLLMulFactorF1 = 0xa
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a00c0c
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xc
       WrDqsSDLLMulFactorF1 = 0xc
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0 *read-only
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq0(n) = 0x00000008
       CaOutDllScl_f0 = 0x8
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq0(n) = 0x00000008
       DqsInDll0Scl_f0 = 0x8
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100080a
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0xa
       RdDatLat_f0 = 0x8
       WrPhaseDelay_f0 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100080d
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1 *read-only
          RdCapLat_f0 = 0xd
          RdDatLat_f0 = 0x8
          WrPhaseDelay_f0 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq1(n) = 0x0000000c
       CaOutDllScl_f1 = 0xc
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq1(n) = 0x0000000c
       DqsInDll0Scl_f1 = 0xc
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1 *read-only
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100070a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1 *read-only
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x7
          WrPhaseDelay_f1 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq2(n) = 0x00000030
       CaOutDllScl_f2 = 0x30
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq2(n) = 0x00000030
       DqsInDll0Scl_f2 = 0x30
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x4100050a
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0xa
       RdDatLat_f2 = 0x5
       WrPhaseDelay_f2 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000508
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1 *read-only
          RdCapLat_f2 = 0x8
          RdDatLat_f2 = 0x5
          WrPhaseDelay_f2 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq3(n) = 0x0000003f
       CaOutDllScl_f3 = 0x3f
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq3(n) = 0x0000003f
       DqsInDll0Scl_f3 = 0x3f
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x6100050a
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1 *read-only
       RdCapLat_f3 = 0xa
       RdDatLat_f3 = 0x5
       WrPhaseDelay_f3 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1 *read-only
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000508
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1 *read-only
          RdCapLat_f3 = 0x8
          RdDatLat_f3 = 0x5
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---


FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impautocal(n) = 0x00010000
          impautocalen = 0x1
          impcalintvl = 0x0 *read-only
          impcaltype = 0x0
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
Enable DLL + +
    ampsca_ampscadllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000000
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
+ +
    amph_CFGH_CB_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x0 *read-only
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x0 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x0
---
+ +
    amph_CFGH_CB_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CB_IOCTL(n) = 0x000200a3
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x0 *read-only
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       protect_drvstren = 0x1 *read-only
       sel_rx_ac = 0x0 *read-only
       sel_rx_dc = 0x0 *read-only
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_CK_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x0 *read-only
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x0 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x0
---
+ +
    amph_CFGH_CK_ZDET_BIASEN(n) = 0x00000000
       bias_ena = 0x0 *read-only
       disable_zdet = 0x0
       sel_zdet = 0x0 *read-only
---
+ +
    amph_CFGH_CK_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CK_IOCTL(n) = 0x000000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       sel_rx_ac = 0x0 *read-only
       sel_rx_dc = 0x0 *read-only
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_B0_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_B0_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B0_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B0_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B1_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_B1_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B1_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS0_WKPUPD(n) = 0x00000788
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x1
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x1 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x7 *read-only
---
+ +
    amph_CFGH_DQS0_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS0_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS0_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS0_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x1
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_WKPUPD(n) = 0x00000788
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x1
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x1 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x7 *read-only
---
+ +
    amph_CFGH_DQS1_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS1_IMPCTL(n) = 0x00201c2b
       en160_tx_f0 = 0x0
       en160_tx_f1 = 0x1
       en160_tx_f2 = 0x0
       en160_tx_f3 = 0x0
       zcpd_ovrr = 0x1c *read-only
       zcpu_ovrr = 0x2b *read-only
       zcpu_pd_ovrr = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS1_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS1_ODTCTRL(n) = 0x00000007
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x1
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DBG_DBG_REG0(n) = 0x00000000
       cb_bias_ena = 0x0
       cb_odte = 0x0 *read-only
       clk_en_sync_flop_rst = 0x0 *read-only
       mon_vdd_mem = 0x0 *read-only
       mon_vdd_soc = 0x0 *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM1(n) = 0x00667f7f
       bias_ena_dly = 0x66
       io_pd = 0x7f *read-only
       io_pu = 0x7f *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM0(n) = 0x000f0315
       zc_dly = 0x15
       zc_dnbd = 0x0
       zc_tap = 0x3
       zc_upbd = 0xf
---
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x0000000e
       control = 0xe
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x08010019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0x8
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480050
       tRFCBaseCyc_freq3 = 0x50
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480050
       tRFCBaseCyc_freq2 = 0x50
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480049. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480049.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480050
       tRFCBaseCyc_freq0 = 0x50
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c006e
          tRFCBaseCyc_freq0 = 0x6e
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00170013
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0 *read-only
          ShareZQRes = 0x0 *read-only
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x0 *read-only
          ZqCalIntrvl = 0x0 *read-only
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01012008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030007
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x7
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x11100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x1
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x11000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x1
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x11110000
          ARpbEn_freq1 = 0x1 *read-only
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x1
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1111013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x1
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00010000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00000000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR11 for FPGA

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and Modified Refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x26204100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5e284100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + +
if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000001f
       DramSize = 0x1f
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050201
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060201
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060210
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x1
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060220
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x2
          NumMcuChnl = 0x2
---
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

7. Setup registers for CA calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1, and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x52020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xae010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x030b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0 *read-only
          WrLvlRunUpdWrResult = 0x0 *read-only
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode

FPGA: Skip this step
+ +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

8. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step8Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 1, 16, 12);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change

FPGA: Skip this step
+ +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x0 *read-only
YesYes-
Poll ampsdqdllctl dllupdtcmd

FPGA: Skip this step
+ +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
RdWrDqCalSegLen_f0

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
RdWrDqCalSegLen_f1

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
          freqchngmrw2_addr_freq0 = 0xe
          freqchngmrw2_ctrl_freq0 = 0x0
          freqchngmrw2_data_freq0 = 0x11
          freqchngmrw3_addr_freq0 = 0xc
          freqchngmrw3_ctrl_freq0 = 0x0
          freqchngmrw3_data_freq0 = 0x11
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
          freqchngmrw2_addr_freq1 = 0xe
          freqchngmrw2_ctrl_freq1 = 0x0
          freqchngmrw2_data_freq1 = 0x11
          freqchngmrw3_addr_freq1 = 0xc
          freqchngmrw3_ctrl_freq1 = 0x0
          freqchngmrw3_data_freq1 = 0x11
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

9. Setup registers for DQ calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xd80d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
YesNo-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngten(n) = 0x00000002
          AutoSR = 0x1
          DynPwrDnEn = 0x0 *read-only
          McPhyUpdDramClkOff = 0x0 *read-only
          PwrDnClkOff = 0x0 *read-only
          SRClkOff = 0x0 *read-only
          SRExitOpt = 0x0 *read-only
-Yes-
Program FreqChngMRW Cnt

FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
YesYes-
WrDqDqsSDLLCtrl

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff00000c
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates

FPGA: Skip this step
+ +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 800Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl

FPGA: Skip this step
+ +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

10. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 1, 16, 12);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
The scale factors for Bin0 and Bin1 WR DQS/DQ skew have to to programmed to the correct values based on board charaterization. Fields are being set to 0 here, since exact board skews are not available now (04/01/14).

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_WrtDQSDQSkewControl(n) = 0x06000000
          WrDqDqsIDTVTScaleEn = 0x1 *read-only
          WrDqDqsMDLLVTScaleEn = 0x1 *read-only
          WrtDQSDQScaleFactorF0 = 0x0
          WrtDQSDQScaleFactorF1 = 0x0
          WrtDQSDQScaleFactorPlusSel = 0x0
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00000788
          idle_active_en_f0 = 0x0
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00000788
          idle_active_en_f0 = 0x0
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-
Program FSP-WR to 0 and FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x24020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xce010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 24, 12);
+
---
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 0 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Call custom API provided by PMGR for changing mcu_clk to 1200Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl

FPGA: Skip this step
+ +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 24, 12);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG, since all calibrations are done + +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-


DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x001a0004
          Rd0RunSDLLUpd = 0x0 *read-only
          Rd0RunSDLLUpdOverride = 0x0 *read-only
          Rd0RunSDLLUpdWrResult = 0x0 *read-only
          Rd0SDLLOvrVal = 0x1a
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x08010019
       FreqChngWaitThr = 0x1 *read-only
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0x8
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0 *read-only
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x11100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x1
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x11000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x1
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x11110000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x1
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1111013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x1
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+ +
    amph_CFGH_B0_DYN_ISEL_ASRTIME(n) = 0x00001117
       rcvr_minisel_assrttime_f0 = 0x17
       rcvr_minisel_assrttime_f1 = 0x11
       rcvr_minisel_assrttime_f2 = 0x0 *read-only
       rcvr_minisel_assrttime_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_DYN_ISEL(n) = 0x00000003
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_DYN_ISEL(n) = 0x00000003
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_DCD_IOCTL(n) = 0x00030000
       dcdi = 0x0 *read-only
       dcdo = 0x0 *read-only
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_DCD_IOCTL(n) = 0x00030000
       dcdi = 0x0 *read-only
       dcdo = 0x0 *read-only
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbrparam(n) = 0x61616161
       RdCwfEarlyCyc_freq0 = 0x1
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x1
       RdCwfEarlyCyc_freq3 = 0x1
       RdRemEarlyCyc_freq0 = 0x6
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x6
       RdRemEarlyCyc_freq3 = 0x6
else if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00006100
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000061a5
          RdCwfEarlyCyc_freq0 = 0x5
          RdCwfEarlyCyc_freq1 = 0x1
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x6
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1 *read-only
       Mcc0AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc0DpPropQCfg = 0x0 *read-only
       Mcc0DpPropQCmd = 0x1 *read-only
       Mcc0DpPropQTrakEnbl = 0x0 *read-only
       Mcc0MsqQPropCfg = 0x0 *read-only
       Mcc0MsqQPropQCmd = 0x0 *read-only
       Mcc0MsqQPropTrakEnbl = 0x0 *read-only
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0 *read-only
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0 *read-only
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1 *read-only
       Mcc1AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc1DpPropQCfg = 0x0 *read-only
       Mcc1DpPropQCmd = 0x1 *read-only
       Mcc1DpPropQTrakEnbl = 0x0 *read-only
       Mcc1MsqQPropCfg = 0x0 *read-only
       Mcc1MsqQPropQCmd = 0x0 *read-only
       Mcc1MsqQPropTrakEnbl = 0x0 *read-only
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0 *read-only
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0 *read-only
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1 *read-only
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0 *read-only
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
disable dynamic power-down. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
---
disable dynamic power-down. + +
       amcx_dramcfg_pwrmngten(n) = 0x00000133
          AutoSR = 0x1
          DynPwrDnEn = 0x1
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
-No-
Revert auto self-refresh wait timer to guided value.

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngtparam_freq0(n) = 0x01800000
          BypsPwrDnDlyCyc_freq0 = 0x0 *read-only
          SelfRefTmrVal_freq0 = 0x180
---
Setting WqAgeOutVal to be 3/4 of SelfRefTmrVal, to flush writes in a reasonable time.

FPGA: Skip this step
+ +
       amcx_mcusch_psqwqctl1(n) = 0x01640120
          WqAgeOutVal_freq0 = 0x120
          WqAgeOutVal_freq1 = 0x164 *read-only
---
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000000ff
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
Yes--
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x01500150
       PreFreqChng2AllBankDly_f0 = 0x150
       PreFreqChng2AllBankDly_f1 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x01500150
       PreFreqChng2AllBankDly_f2 = 0x150
       PreFreqChng2AllBankDly_f3 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02a002a0
       PreFreqChng2FreqChngDly_f0 = 0x2a0
       PreFreqChng2FreqChngDly_f1 = 0x2a0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02a002a0
       PreFreqChng2FreqChngDly_f2 = 0x2a0
       PreFreqChng2FreqChngDly_f3 = 0x2a0
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly0 = 0x00900090
       Cal2PreFreqChngDly_f0 = 0x90
       Cal2PreFreqChngDly_f1 = 0x90
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly1 = 0x00900090
       Cal2PreFreqChngDly_f2 = 0x90
       Cal2PreFreqChngDly_f3 = 0x90
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly0 = 0x01200120
       FreqChng2PstCalDly_f0 = 0x120
       FreqChng2PstCalDly_f1 = 0x120
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly1 = 0x01200120
       FreqChng2PstCalDly_f2 = 0x120
       FreqChng2PstCalDly_f3 = 0x120
---
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6c0
          RdCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
Yes--
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x000493e0
          PerCal_FreqChngTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_VoltRampTimer = 0x000493e0
          VoltRampTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly0 = 0x00d800d8
          VoltRamp2AllBankDly_f0 = 0xd8
          VoltRamp2AllBankDly_f1 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly1 = 0x00d800d8
          VoltRamp2AllBankDly_f2 = 0xd8
          VoltRamp2AllBankDly_f3 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly0 = 0x00900090
          AllBank2PmgrAckDly_f0 = 0x90
          AllBank2PmgrAckDly_f1 = 0x90
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly1 = 0x00900090
          AllBank2PmgrAckDly_f2 = 0x90
          AllBank2PmgrAckDly_f3 = 0x90
Yes--
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa *read-only
       MCUBCGClkGateEn = 0x0 *read-only
       MCUBCGPwrGateEn = 0x0 *read-only
       PwrRstCyc = 0x5 *read-only
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0 *read-only
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Malta_Init_A0_May_20_2015.html b/docs/dcs-specs/Malta_Init_A0_May_20_2015.html new file mode 100644 index 0000000..a8acbee --- /dev/null +++ b/docs/dcs-specs/Malta_Init_A0_May_20_2015.html @@ -0,0 +1,3155 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Wed May 20 18:14:26 2015
AMC Version: Major Release: Minor Release:
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/a0.malta/amcc/tb/cfg/static/maqstb_cfg.pl#16
AMP UM Init sourced from: //depot/ip_lib/apple/amp/a0.malta/amp/tb/cfg/phy_helper_fxns.pl#5
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - herb - Files Edited: maqstb_cfg.pl#8 -
* changes for updated amph V0013 and mcu init gen flow.
* ------------------------------------------------------------------
* Version:7 - rishah - Files Edited: maqs_gen_cfg.pl#7 - maqstb_cfg.pl#13 -
* Ported over changes from Maui B0 related to INIT Sequence.
* ------------------------------------------------------------------
* Version:8 - rishah - Files Edited: phy_helper_fxns.pl#15 -
* Updated MCU init sequence.
* ------------------------------------------------------------------
* Version:9 - cpolapra - Files Edited: maqs_gen_cfg_c.pl#6 -
* Ported over init and calibration changes from Maui A0/B0 and Elba
* ------------------------------------------------------------------
* Version:10 - rishah - Files Edited: phy_helper_fxns.pl#16 -
* Init sequence update for VrefSel for SW Calib.
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1
       MccStickyEn = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
Maximum Number of Powered Ways. + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000110
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x1 *read-only
---
Turn on the MCC + +
    amcc_mcccfg_MccGen = 0x00000195
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x1
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
Set Dynamic Way PowerGating + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000010
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x0
---
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5 *read-only
          ChSelTyp = 0x0 *read-only
          ChnlStartBit = 0x2 *read-only
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3 *read-only
       slvpll_cp_lp = 0x0 *read-only
       slvpll_cp_md = 0x0 *read-only
       slvpll_cp_pd = 0x0 *read-only
       slvpll_cp_r_set = 0x8 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000076
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x6 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000078
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x8
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0 *read-only
       slvpll_reg_pd = 0x0 *read-only
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0 *read-only
       spll_mode_dcs_pwrdn = 0x1 *read-only
       use_idle_for_pd = 0x0 *read-only
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 99Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 99Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xce012402
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x24
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xce
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0 *read-only
       freqchngmrw9_ctrl_freq0 = 0x0 *read-only
       freqchngmrw9_data_freq0 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303040b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x4
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000416
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x4
       freqchngmrw9_addr_freq1 = 0x0 *read-only
       freqchngmrw9_ctrl_freq1 = 0x0 *read-only
       freqchngmrw9_data_freq1 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0 *read-only
       freqchngmrw9_ctrl_freq2 = 0x0 *read-only
       freqchngmrw9_data_freq2 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0 *read-only
       freqchngmrw9_ctrl_freq3 = 0x0 *read-only
       freqchngmrw9_data_freq3 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-2667 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3 *read-only
       tDQSCKMinCyc_freq0 = 0x0 *read-only
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00103306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3 *read-only
          tDQSCKMinCyc_freq0 = 0x0 *read-only
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2 *read-only
       tDQSCKMinCyc_freq1 = 0x0 *read-only
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2 *read-only
          tDQSCKMinCyc_freq1 = 0x0 *read-only
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010d01
       PHYRdLat_freq0 = 0xd
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00050d0a
          PHYRdLat_freq0 = 0xd
          PHYtPhyWrlat_freq0 = 0x5
          PHYtRddataEn_freq0 = 0xa
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010c01
       PHYRdLat_freq1 = 0xc
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050c06
          PHYRdLat_freq1 = 0xc
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010c01
       PHYRdLat_freq2 = 0xc
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010c01
          PHYRdLat_freq2 = 0xc
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x42110408
       tRASCyc_freq0 = 0x11
       tRCDCyc_freq0 = 0x8
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x8
       tWTRCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x531a060b
          tRASCyc_freq0 = 0x1a
          tRCDCyc_freq0 = 0xb
          tRTPCyc_freq0 = 0x5
          tWRCyc_freq0 = 0xc
          tWTRCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x10040908
       tFAWCyc_freq0 = 0x10
       tRPCyc_freq0 = 0x8
       tRPabCyc_freq0 = 0x9
       tRRDCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x18060d0b
          tFAWCyc_freq0 = 0x18
          tRPCyc_freq0 = 0xb
          tRPabCyc_freq0 = 0xd
          tRRDCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c0078
          tRFCBaseCyc_freq0 = 0x78 *read-only
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0x50057012
       tFCCyc_freq0 = 0x50
       tXSRCyc_freq0 = 0x57
       tZQCalCyc_freq0 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq0(n) = 0x78071012
          tFCCyc_freq0 = 0x78
          tXSRCyc_freq0 = 0x71
          tZQCalCyc_freq0 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x0e0a9084
       tMRRCyc = 0x4
       tMRRICyc = 0x8
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0xe
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060a9024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x140a90b4
          tMRRCyc = 0x4
          tMRRICyc = 0xb
          tMRWCyc = 0x9
          tVRCGOFFCyc = 0xa
          tZQLatCyc = 0x14
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x42110408
       tRASCyc_freq1 = 0x11
       tRCDCyc_freq1 = 0x8
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x8
       tWTRCyc_freq1 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480050. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480050.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50 *read-only
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50 *read-only
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0x50057012
       tFCCyc_freq1 = 0x50
       tXSRCyc_freq1 = 0x57
       tZQCalCyc_freq1 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x42110408
       tRASCyc_freq2 = 0x11
       tRCDCyc_freq2 = 0x8
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x8
       tWTRCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x10040908
       tFAWCyc_freq2 = 0x10
       tRPCyc_freq2 = 0x8
       tRPabCyc_freq2 = 0x9
       tRRDCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14 *read-only
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0x50057012
       tFCCyc_freq2 = 0x50
       tXSRCyc_freq2 = 0x57
       tZQCalCyc_freq2 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x42110408
       tRASCyc_freq3 = 0x11
       tRCDCyc_freq3 = 0x8
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x8
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x10040b0a
       tFAWCyc_freq3 = 0x10
       tRPCyc_freq3 = 0xa
       tRPabCyc_freq3 = 0xb
       tRRDCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5 *read-only
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x50057012
       tFCCyc_freq3 = 0x50
       tXSRCyc_freq3 = 0x57
       tZQCalCyc_freq3 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15 *read-only
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15 *read-only
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x31263263
       tCKECyc = 0x3
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x3
       tCKb4CKECyc = 0x1
       tXPCyc = 0x3
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21262222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x62265295
          tCKECyc = 0x5
          tCKEPDECyc = 0x1 *read-only
          tCKESRCyc = 0x9
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x6
          tCKafCKECyc = 0x6
          tCKb4CKECyc = 0x2
          tXPCyc = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq0 = 0x3
       tRASDrtCyc_freq0 = 0x12
       tRCDDrtCyc_freq0 = 0x8
       tRPDrtCyc_freq0 = 0x8
       tRPabDrtCyc_freq0 = 0xa
       tRRDDrtCyc_freq0 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x38c486cc
          tDQSCKMaxDrtCyc_freq0 = 0x4
          tRASDrtCyc_freq0 = 0x1b
          tRCDDrtCyc_freq0 = 0xc
          tRPDrtCyc_freq0 = 0xc
          tRPabDrtCyc_freq0 = 0xe
          tRRDDrtCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq1 = 0x3
       tRASDrtCyc_freq1 = 0x12
       tRCDDrtCyc_freq1 = 0x8
       tRPDrtCyc_freq1 = 0x8
       tRPabDrtCyc_freq1 = 0xa
       tRRDDrtCyc_freq1 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq2 = 0x3
       tRASDrtCyc_freq2 = 0x12
       tRCDDrtCyc_freq2 = 0x8
       tRPDrtCyc_freq2 = 0x8
       tRPabDrtCyc_freq2 = 0xa
       tRRDDrtCyc_freq2 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x30a35488
       tDQSCKMaxDrtCyc_freq3 = 0x3
       tRASDrtCyc_freq3 = 0x12
       tRCDDrtCyc_freq3 = 0x8
       tRPDrtCyc_freq3 = 0xa
       tRPabDrtCyc_freq3 = 0xc
       tRRDDrtCyc_freq3 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00112306
       DRAMRL_freq0 = 0xc
       DRAMWL_freq0 = 0x6
       tDQSCKMaxCyc_freq0 = 0x2
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00113306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x1
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00112206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001120c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x2
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001120c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x2
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2rTatDeadCyc_freq0 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wTatDeadCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_tat_freq0(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2rTatDeadCyc_freq0 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2wTatDeadCyc_freq0 = 0x3
          W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wTatDeadCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2rTatDeadCyc_freq1 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wTatDeadCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2rTatDeadCyc_freq1 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wTatDeadCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2rTatDeadCyc_freq2 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2wTatDeadCyc_freq2 = 0x3
       W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wTatDeadCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2rTatDeadCyc_freq2 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wTatDeadCyc_freq2 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq3(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2rTatDeadCyc_freq3 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2wTatDeadCyc_freq3 = 0x3
       W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wTatDeadCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_tat_freq3(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2rTatDeadCyc_freq3 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2wTatDeadCyc_freq3 = 0x2
          W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wTatDeadCyc_freq3 = 0x1 *read-only
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0 *read-only
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0 *read-only
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0 *read-only
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0 *read-only
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0 *read-only
       SchEn = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3 *read-only
       PhyInitStartCyc = 0x0 *read-only
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f0(n) = 0x000b316b
       CaDsPd_f0 = 0xb
       Ck0DsPd_f0 = 0xb
       Ck1DsPd_f0 = 0xc *read-only
       CsDsPd_f0 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f1(n) = 0x000b216b
       CaDsPd_f1 = 0xb
       Ck0DsPd_f1 = 0xb
       Ck1DsPd_f1 = 0x8 *read-only
       CsDsPd_f1 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f2(n) = 0x000b3d6b
       CaDsPd_f2 = 0xb
       Ck0DsPd_f2 = 0xb
       Ck1DsPd_f2 = 0xf *read-only
       CsDsPd_f2 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f3(n) = 0x000b3d6b
       CaDsPd_f3 = 0xb
       Ck0DsPd_f3 = 0xb
       Ck1DsPd_f3 = 0xf *read-only
       CsDsPd_f3 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqds_f1(n) = 0x00080508
       CaDs_f1 = 0x8
       Ck0Ds_f1 = 0x8
       Ck1Ds_f1 = 0x1 *read-only
       CsDs_f1 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f2(n) = 0x00083d08
       CaDs_f2 = 0x8
       Ck0Ds_f2 = 0x8
       Ck1Ds_f2 = 0xf *read-only
       CsDs_f2 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f3(n) = 0x00083d08
       CaDs_f3 = 0x8
       Ck0Ds_f3 = 0x8
       Ck1Ds_f3 = 0xf *read-only
       CsDs_f3 = 0x8
---
+ +
    ampsca_ampscaiocfg_CaCkCsWkDs(n) = 0x000000db
       CaWkDs = 0x3
       CkWkDs = 0x3
       CsWkDs = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f0(n) = 0x000c0b08
       RdDqODTDs = 0xc
       WrDqPdDs = 0xb
       WrDqPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqds_f1(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f2(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f3(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f0(n) = 0x000c0b08
       RdDqDqsODTDs = 0xc
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f1(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f2(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f3(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
**IMPORTANT** : For power saving on SOC's these setings are mandatory. With Samsung DRAM, VRef_f1 should be set to 0x00F000F0. With Micron DRAM, VRef_f1 should be set to 0x00EE00EE. With Hynix DRAM, VRef_f1 should be set to 0x00E900E9.
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00e900e9
       DqsVRefSel = 0xe9
       VRefSel = 0xe9
---
+ +
    ampsdq_ampsdqodt_VRef_f2(n) = 0x00800080
       DqsVRefSel = 0x80
       VRefSel = 0x80
---
+ +
    ampsdq_ampsdqodt_VRef_f3(n) = 0x00800080
       DqsVRefSel = 0x80
       VRefSel = 0x80
---
+ +
    ampsdq_ampsdqrdtim_dqspdres(n) = 0x00000001
       DqsPdVal = 0x1 *read-only
       DqsWkPuPdVal = 0x0
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x0303030b
       ClkEn2Valid = 0x3 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x3 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x0003000b
       ClkEn2Valid = 0x0 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x0 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0004
       Rd0RunSDLLUpd = 0x0 *read-only
       Rd0RunSDLLUpdOverride = 0x0 *read-only
       Rd0RunSDLLUpdWrResult = 0x0 *read-only
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000004
       WrDqDqsRunSDLLUpd = 0x0 *read-only
       WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
       WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
       WrDqDqsWrLvlReBalanceEn = 0x0 *read-only
       WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
       WrDqSDLLHalfClkEn = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff02ff
       WrLvlMaxWrDqsSDLLCode = 0xff *read-only
       WrLvlRunUpdOverride = 0x0 *read-only
       WrLvlRunUpdWrResult = 0x0 *read-only
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdWrResult
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x04000410
       tCA2CAEntry = 0x10
       tCA2CAExit = 0x0
       tCKEHEntry = 0x4
       tCKEHExit = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000410
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000410
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000410
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x04020402
       tCA2CAEntry_f0 = 0x2
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x4
       tCKEHExit_f0 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020402
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020402
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020402
       tCA2CAEntry_f3 = 0x2
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x00001426
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x6
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x00001422
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000301e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x30
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x03111004
       tRd2Rd = 0x4
       tRd2Wr = 0x10
       tWr2Rd = 0x11
       tWr2Wr = 0x3 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00b101d1
       EndPoint = 0xb1
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x012f0360
       EndPoint = 0x12f
       StartPoint = 0x360 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00f801d1
       EndPoint = 0xf8
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x012f0360
       EndPoint = 0x12f
       StartPoint = 0x360 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxRdDqsSDLLMulFactor(n) = 0x00a01414
       MaxRdDqsSDLLCodeStatus = 0xa0 *read-only
       RdDqsSDLLMulFactorF0 = 0x14
       RdDqsSDLLMulFactorF1 = 0x14
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqSDLLMulFactor(n) = 0x00a00a0f
       MaxWrDqSDLLCodeStatus = 0xa0 *read-only
       WrDqSDLLMulFactorF0 = 0xf
       WrDqSDLLMulFactorF1 = 0xa
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a00c0c
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xc
       WrDqsSDLLMulFactorF1 = 0xc
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0 *read-only
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq0(n) = 0x00000008
       CaOutDllScl_f0 = 0x8
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq0(n) = 0x00000008
       DqsInDll0Scl_f0 = 0x8
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100080a
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0xa
       RdDatLat_f0 = 0x8
       WrPhaseDelay_f0 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100080d
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1 *read-only
          RdCapLat_f0 = 0xd
          RdDatLat_f0 = 0x8
          WrPhaseDelay_f0 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq1(n) = 0x0000000d
       CaOutDllScl_f1 = 0xd
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq1(n) = 0x0000000d
       DqsInDll0Scl_f1 = 0xd
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1 *read-only
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100070a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1 *read-only
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x7
          WrPhaseDelay_f1 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq2(n) = 0x00000030
       CaOutDllScl_f2 = 0x30
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq2(n) = 0x00000030
       DqsInDll0Scl_f2 = 0x30
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x4100050a
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0xa
       RdDatLat_f2 = 0x5
       WrPhaseDelay_f2 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000508
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1 *read-only
          RdCapLat_f2 = 0x8
          RdDatLat_f2 = 0x5
          WrPhaseDelay_f2 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq3(n) = 0x0000003f
       CaOutDllScl_f3 = 0x3f
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq3(n) = 0x0000003f
       DqsInDll0Scl_f3 = 0x3f
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x6100050a
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1 *read-only
       RdCapLat_f3 = 0xa
       RdDatLat_f3 = 0x5
       WrPhaseDelay_f3 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1 *read-only
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000508
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1 *read-only
          RdCapLat_f3 = 0x8
          RdDatLat_f3 = 0x5
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---


FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impautocal(n) = 0x00010000
          impautocalen = 0x1
          impcalintvl = 0x0 *read-only
          impcaltype = 0x0
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
Enable DLL + +
    ampsca_ampscadllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000000
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
+ +
    amph_CFGH_CB_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x0 *read-only
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x0 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x0
---
+ +
    amph_CFGH_CB_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CB_IOCTL(n) = 0x000200a3
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x0 *read-only
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       protect_drvstren = 0x1 *read-only
       sel_rx_ac = 0x0 *read-only
       sel_rx_dc = 0x0 *read-only
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_CK_WKPUPD(n) = 0x00000000
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x0 *read-only
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x0 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x0
---
+ +
    amph_CFGH_CK_ZDET_BIASEN(n) = 0x00000000
       bias_ena = 0x0 *read-only
       disable_zdet = 0x0
       sel_zdet = 0x0 *read-only
---
+ +
    amph_CFGH_CK_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_CK_IOCTL(n) = 0x000000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel = 0x0
       sel_rx_ac = 0x0 *read-only
       sel_rx_dc = 0x0 *read-only
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_B0_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B0_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B0_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_B1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_B1_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_WKPUPD(n) = 0x00000000
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0
       pdpwk_f1 = 0x0
       pdpwk_f2 = 0x0
       pdpwk_f3 = 0x0
       pupwk_f0 = 0x0
       pupwk_f1 = 0x0
       pupwk_f2 = 0x0
       pupwk_f3 = 0x0
       wkds = 0x0
---
+ +
    amph_CFGH_B1_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS0_WKPUPD(n) = 0x00000788
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x1
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x1 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x7 *read-only
---
+ +
    amph_CFGH_DQS0_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS0_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS0_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS0_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS0_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_WKPUPD(n) = 0x00000788
       idle_active_en_f0 = 0x0 *read-only
       idle_active_en_f1 = 0x0 *read-only
       idle_active_en_f2 = 0x0 *read-only
       idle_active_en_f3 = 0x0 *read-only
       pdpwk_f0 = 0x0 *read-only
       pdpwk_f1 = 0x1
       pdpwk_f2 = 0x0 *read-only
       pdpwk_f3 = 0x1 *read-only
       pupwk_f0 = 0x0 *read-only
       pupwk_f1 = 0x0 *read-only
       pupwk_f2 = 0x0 *read-only
       pupwk_f3 = 0x0 *read-only
       wkds = 0x7 *read-only
---
+ +
    amph_CFGH_DQS1_DRIVE_STR(n) = 0x33831717
       dspd_f0 = 0x7
       dspd_f1 = 0x7
       dspd_f2 = 0x3
       dspd_f3 = 0x3
       dspu_f0 = 0x1
       dspu_f1 = 0x1
       dspu_f2 = 0x8
       dspu_f3 = 0x3
---
+ +
    amph_CFGH_DQS1_IOCTL(n) = 0x715000a7
       en_pulse_tx_f0 = 0x1
       en_pulse_tx_f1 = 0x1
       en_pulse_tx_f2 = 0x1
       en_pulse_tx_f3 = 0x0
       isel_f0 = 0x1
       isel_f1 = 0x1
       isel_f2 = 0x1
       isel_f3 = 0x0
       sel_rx_ac_f0 = 0x0
       sel_rx_ac_f1 = 0x0
       sel_rx_ac_f2 = 0x0
       sel_rx_ac_f3 = 0x0
       sel_rx_dc_f0 = 0x1
       sel_rx_dc_f1 = 0x1
       sel_rx_dc_f2 = 0x1
       sel_rx_dc_f3 = 0x0
       tx_ac_f0 = 0x2
       tx_ac_f1 = 0x2
       tx_ac_f2 = 0x0 *read-only
       tx_ac_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_ODT(n) = 0x01c00333
       dspd_f0 = 0x3
       dspd_f1 = 0x3
       dspd_f2 = 0x3
       dspd_f3 = 0x0
       zcpd_ovrr = 0x0 *read-only
       zcpd_val = 0x1c *read-only
---
+ +
    amph_CFGH_DQS1_ZDET_BIASEN(n) = 0x00060028
       bias_ena_f0 = 0x0
       bias_ena_f1 = 0x1
       bias_ena_f2 = 0x1
       bias_ena_f3 = 0x0
       disable_zdet_f0 = 0x0
       disable_zdet_f1 = 0x0
       disable_zdet_f2 = 0x0
       disable_zdet_f3 = 0x0
       sel_zdet_f0 = 0x0
       sel_zdet_f1 = 0x2
       sel_zdet_f2 = 0x2
       sel_zdet_f3 = 0x0
---
+ + + + + + +
if (platform == PALLADIUM)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else if (platform == FPGA)
    amph_CFGH_DQS1_ODTCTRL(n) = 0x00000000
       dspu_f0 = 0x0 *read-only
       dspu_f1 = 0x0 *read-only
       dspu_f2 = 0x0 *read-only
       dspu_f3 = 0x0 *read-only
       odten_f0 = 0x0
       odten_f1 = 0x0
       odten_f2 = 0x0
       odten_f3 = 0x0
else
       amph_CFGH_DQS1_ODTCTRL(n) = 0x00000005
          dspu_f0 = 0x0 *read-only
          dspu_f1 = 0x0 *read-only
          dspu_f2 = 0x0 *read-only
          dspu_f3 = 0x0 *read-only
          odten_f0 = 0x1 *read-only
          odten_f1 = 0x0
          odten_f2 = 0x1 *read-only
          odten_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DBG_DBG_REG0(n) = 0x00000000
       cb_bias_ena = 0x0
       cb_odte = 0x0 *read-only
       clk_en_sync_flop_rst = 0x0 *read-only
       mon_vdd_mem = 0x0 *read-only
       mon_vdd_soc = 0x0 *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM1(n) = 0x00667f7f
       bias_ena_dly = 0x66
       io_pd = 0x7f *read-only
       io_pu = 0x7f *read-only
---
+ +
    amph_CFGH_ZC_ZCAL_FSM0(n) = 0x000f0315
       zc_dly = 0x15
       zc_dnbd = 0x0
       zc_tap = 0x3
       zc_upbd = 0xf
---
+ +
    amph_CFGH_DEBUG_SPARE0(n) = 0x0000000e
       control = 0xe
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x0d010019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480050
       tRFCBaseCyc_freq3 = 0x50
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480050
       tRFCBaseCyc_freq2 = 0x50
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480049. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480049.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480050
       tRFCBaseCyc_freq0 = 0x50
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c006e
          tRFCBaseCyc_freq0 = 0x6e
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00170013
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0 *read-only
          ShareZQRes = 0x0 *read-only
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x0 *read-only
          ZqCalIntrvl = 0x0 *read-only
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01022008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x2
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030007
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x7
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10110000
          ARpbEn_freq1 = 0x1 *read-only
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00010000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00000000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR11 for FPGA

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and Modified Refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x26204100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5e284100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + +
if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000001f
       DramSize = 0x1f
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050201
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060201
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060210
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x1
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060220
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x2
          NumMcuChnl = 0x2
---
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

7. Setup registers for CA calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1, and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x52020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xae010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x040b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0 *read-only
          WrLvlRunUpdWrResult = 0x0 *read-only
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode

FPGA: Skip this step
+ +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

8. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step8Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 1, 16, 12);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change

FPGA: Skip this step
+ +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x0 *read-only
YesYes-
Poll ampsdqdllctl dllupdtcmd

FPGA: Skip this step
+ +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
RdWrDqCalSegLen_f0

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
RdWrDqCalSegLen_f1

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
          freqchngmrw2_addr_freq1 = 0xe
          freqchngmrw2_ctrl_freq1 = 0x0
          freqchngmrw2_data_freq1 = 0x11
          freqchngmrw3_addr_freq1 = 0xc
          freqchngmrw3_ctrl_freq1 = 0x0
          freqchngmrw3_data_freq1 = 0x11
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step

FPGA: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

9. Setup registers for DQ calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xd80d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
YesNo-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngten(n) = 0x00000002
          AutoSR = 0x1
          DynPwrDnEn = 0x0 *read-only
          McPhyUpdDramClkOff = 0x0 *read-only
          PwrDnClkOff = 0x0 *read-only
          SRClkOff = 0x0 *read-only
          SRExitOpt = 0x0 *read-only
-Yes-
Program FreqChngMRW Cnt

FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
YesYes-
WrDqDqsSDLLCtrl

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff00000c
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates

FPGA: Skip this step
+ +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 800Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl

FPGA: Skip this step
+ +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

10. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 1, 16, 12);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
The scale factors for Bin0 and Bin1 WR DQS/DQ skew have to to programmed to the correct values based on board charaterization. Fields are being set to 0 here, since exact board skews are not available now (04/01/14).

FPGA: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_WrtDQSDQSkewControl(n) = 0x06000000
          WrDqDqsIDTVTScaleEn = 0x1 *read-only
          WrDqDqsMDLLVTScaleEn = 0x1 *read-only
          WrtDQSDQScaleFactorF0 = 0x0
          WrtDQSDQScaleFactorF1 = 0x0
          WrtDQSDQScaleFactorPlusSel = 0x0
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00000788
          idle_active_en_f0 = 0x0
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00000788
          idle_active_en_f0 = 0x0
          idle_active_en_f1 = 0x0
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-
Program FSP-WR to 0 and FSP-OP to 1 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x24020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xce010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 24, 12);
+
---
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 0 and set VRCG and modified refresh

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Call custom API provided by PMGR for changing mcu_clk to 1200Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl

FPGA: Skip this step
+ +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 24, 12);
+
---


FPGA: Skip this step
+ +
       amph_CFGH_DQS0_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-


FPGA: Skip this step
+ +
       amph_CFGH_DQS1_WKPUPD(n) = 0x00030788
          idle_active_en_f0 = 0x1
          idle_active_en_f1 = 0x1
          idle_active_en_f2 = 0x0 *read-only
          idle_active_en_f3 = 0x0 *read-only
          pdpwk_f0 = 0x0 *read-only
          pdpwk_f1 = 0x1
          pdpwk_f2 = 0x0 *read-only
          pdpwk_f3 = 0x1 *read-only
          pupwk_f0 = 0x0 *read-only
          pupwk_f1 = 0x0 *read-only
          pupwk_f2 = 0x0 *read-only
          pupwk_f3 = 0x0 *read-only
          wkds = 0x7 *read-only
-No-
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG, since all calibrations are done + +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-


DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x001a0004
          Rd0RunSDLLUpd = 0x0 *read-only
          Rd0RunSDLLUpdOverride = 0x0 *read-only
          Rd0RunSDLLUpdWrResult = 0x0 *read-only
          Rd0SDLLOvrVal = 0x1a
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x0d010019
       FreqChngWaitThr = 0x1 *read-only
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0 *read-only
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10110000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+ +
    amph_CFGH_B0_DYN_ISEL_ASRTIME(n) = 0x00001117
       rcvr_minisel_assrttime_f0 = 0x17
       rcvr_minisel_assrttime_f1 = 0x11
       rcvr_minisel_assrttime_f2 = 0x0 *read-only
       rcvr_minisel_assrttime_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B0_DYN_ISEL(n) = 0x00000003
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_B1_DYN_ISEL(n) = 0x00000003
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS0_DCD_IOCTL(n) = 0x00030000
       dcdi = 0x0 *read-only
       dcdo = 0x0 *read-only
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+ +
    amph_CFGH_DQS1_DCD_IOCTL(n) = 0x00030000
       dcdi = 0x0 *read-only
       dcdo = 0x0 *read-only
       dyn_isel_ctrl_en_f0 = 0x1
       dyn_isel_ctrl_en_f1 = 0x1
       dyn_isel_ctrl_en_f2 = 0x0 *read-only
       dyn_isel_ctrl_en_f3 = 0x0 *read-only
---
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbrparam(n) = 0x61616161
       RdCwfEarlyCyc_freq0 = 0x1
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x1
       RdCwfEarlyCyc_freq3 = 0x1
       RdRemEarlyCyc_freq0 = 0x6
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x6
       RdRemEarlyCyc_freq3 = 0x6
else if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00006100
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000061a5
          RdCwfEarlyCyc_freq0 = 0x5
          RdCwfEarlyCyc_freq1 = 0x1
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x6
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1 *read-only
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1 *read-only
       Mcc0AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc0DpPropQCfg = 0x0 *read-only
       Mcc0DpPropQCmd = 0x1 *read-only
       Mcc0DpPropQTrakEnbl = 0x0 *read-only
       Mcc0MsqQPropCfg = 0x0 *read-only
       Mcc0MsqQPropQCmd = 0x0 *read-only
       Mcc0MsqQPropTrakEnbl = 0x0 *read-only
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0 *read-only
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0 *read-only
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1 *read-only
       Mcc1AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc1DpPropQCfg = 0x0 *read-only
       Mcc1DpPropQCmd = 0x1 *read-only
       Mcc1DpPropQTrakEnbl = 0x0 *read-only
       Mcc1MsqQPropCfg = 0x0 *read-only
       Mcc1MsqQPropQCmd = 0x0 *read-only
       Mcc1MsqQPropTrakEnbl = 0x0 *read-only
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0 *read-only
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0 *read-only
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0 *read-only
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
disable dynamic power-down. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
---
disable dynamic power-down. + +
       amcx_dramcfg_pwrmngten(n) = 0x00000133
          AutoSR = 0x1
          DynPwrDnEn = 0x1
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
-No-
Revert auto self-refresh wait timer to guided value.

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngtparam_freq0(n) = 0x01800000
          BypsPwrDnDlyCyc_freq0 = 0x0 *read-only
          SelfRefTmrVal_freq0 = 0x180
---
Setting WqAgeOutVal to be 3/4 of SelfRefTmrVal, to flush writes in a reasonable time.

FPGA: Skip this step
+ +
       amcx_mcusch_psqwqctl1(n) = 0x01640120
          WqAgeOutVal_freq0 = 0x120
          WqAgeOutVal_freq1 = 0x164 *read-only
---
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000000ff
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
Yes--
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x01500150
       PreFreqChng2AllBankDly_f0 = 0x150
       PreFreqChng2AllBankDly_f1 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x01500150
       PreFreqChng2AllBankDly_f2 = 0x150
       PreFreqChng2AllBankDly_f3 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02a002a0
       PreFreqChng2FreqChngDly_f0 = 0x2a0
       PreFreqChng2FreqChngDly_f1 = 0x2a0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02a002a0
       PreFreqChng2FreqChngDly_f2 = 0x2a0
       PreFreqChng2FreqChngDly_f3 = 0x2a0
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly0 = 0x00900090
       Cal2PreFreqChngDly_f0 = 0x90
       Cal2PreFreqChngDly_f1 = 0x90
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly1 = 0x00900090
       Cal2PreFreqChngDly_f2 = 0x90
       Cal2PreFreqChngDly_f3 = 0x90
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly0 = 0x01200120
       FreqChng2PstCalDly_f0 = 0x120
       FreqChng2PstCalDly_f1 = 0x120
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly1 = 0x01200120
       FreqChng2PstCalDly_f2 = 0x120
       FreqChng2PstCalDly_f3 = 0x120
---
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6c0
          RdCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
Yes--
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x000493e0
          PerCal_FreqChngTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_VoltRampTimer = 0x000493e0
          VoltRampTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly0 = 0x00d800d8
          VoltRamp2AllBankDly_f0 = 0xd8
          VoltRamp2AllBankDly_f1 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly1 = 0x00d800d8
          VoltRamp2AllBankDly_f2 = 0xd8
          VoltRamp2AllBankDly_f3 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly0 = 0x00900090
          AllBank2PmgrAckDly_f0 = 0x90
          AllBank2PmgrAckDly_f1 = 0x90
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly1 = 0x00900090
          AllBank2PmgrAckDly_f2 = 0x90
          AllBank2PmgrAckDly_f3 = 0x90
Yes--
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa *read-only
       MCUBCGClkGateEn = 0x0 *read-only
       MCUBCGPwrGateEn = 0x0 *read-only
       PwrRstCyc = 0x5 *read-only
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0 *read-only
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Maui_Init_1200_October_29_2015.html b/docs/dcs-specs/Maui_Init_1200_October_29_2015.html new file mode 100644 index 0000000..6ce5f36 --- /dev/null +++ b/docs/dcs-specs/Maui_Init_1200_October_29_2015.html @@ -0,0 +1,3026 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Thu Oct 29 19:23:56 2015
AMC Version: Major Release: Minor Release:
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/trunk.maui/amcc/tb/cfg/static/maqstb_cfg.pl#237
AMP UM Init sourced from: //depot/ip_lib/apple/amp/trunk.maui/amp/tb/cfg/phy_helper_fxns.pl#104
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - thuang - Files Edited: mcu_helper_fxns.c#5 - mcu_helper_fxns.c#7 - mcu_helper_fxns.h#6 -
* Added Rama's change in pmgr_amc_clk_cfg
* ------------------------------------------------------------------
* Version:7 - thuang - Files Edited: mcu_helper_fxns.c#8 - mcu_helper_fxns.h#6 -
* Release init, specifically to deal with 1202MHz at bucket 0
* ------------------------------------------------------------------
* Version:8 - jayp - Files Edited: mcu_helper_fxns.c#8 - mcu_helper_fxns.h#6 -
* release latest init to match AMCX release
* ------------------------------------------------------------------
* Version:9 - jayp - Files Edited: mcu_helper_fxns.c#9 - mcu_helper_fxns.h#7 -
* update to new dcsh/v.hspds that now points to the real amph.spds
* ------------------------------------------------------------------
* Version:10 - jayp - Files Edited: mcu_helper_fxns.c#10 - mcu_helper_fxns.h#8 -
* updating to preFinal releases of amp, amph, and amcx
* ------------------------------------------------------------------
* Version:11 - thuang - Files Edited: mcu_helper_fxns.c#11 - mcu_helper_fxns.h#9 -
* Init update
* ------------------------------------------------------------------
* Version:12 - jayp - Files Edited: mcu_helper_fxns.c#11 - mcu_helper_fxns.h#9 -
* moving to new amp pointer
* ------------------------------------------------------------------
* Version:13 - cpolapra - Files Edited: maqstb_cfg.pl#72 - calibration_fxns.pl#8 - mcu_helper_fxns.c#12 - mcu_helper_fxns.h#10 -
* Updated chip level config files for calibration at both Bucket 0 & Bucket 1
* ------------------------------------------------------------------
* Version:14 - jayp - Files Edited: mcu_helper_fxns.c#13 - mcu_helper_fxns.h#12 -
* update to init code for latest amcx and amp releases
* ------------------------------------------------------------------
* Version:15 - jayp - Files Edited: gen_mcu_init.pl#6 - mcu_helper_fxns.c#15 - mcu_helper_fxns.h#14 -
* moving to latest amph, amcx, and amp pointers
* ------------------------------------------------------------------
* Version:16 - allin - Files Edited: maqs_gen_cfg_c.pl#12 - maqstb_cfg.pl#123 - mem_tparams.pl#27 - phy_helper_fxns.pl#53 - move_generated_files.pl#4 - mcu_helper_fxns.c#18 - mcu_helper_fxns.h#16 -
* Fixes to MRR/MRW inclusion in resume boot
* ------------------------------------------------------------------
* Version:17 - jayp - Files Edited: maqstb_cfg.pl#125 - mcu_helper_fxns.c#20 - mcu_helper_fxns.h#18 -
* moving to latest amp and amcx releases
* ------------------------------------------------------------------
* Version:18 - jayp - Files Edited: maqs_gen_cfg_c.pl#14 - maqstb_cfg.pl#135 -
* releasing new amp to change global timer register naming so that chip and ams both work
* ------------------------------------------------------------------
* Version:19 - cpolapra - Files Edited: maqstb_cfg.pl#141 -
* Fixed tDIPW denali error
* ------------------------------------------------------------------
* Version:20 - cpolapra - Files Edited: maqstb_cfg.pl#148 -
* PMGR random fixes
* ------------------------------------------------------------------
* Version:21 - cpolapra - Files Edited: maqstb_cfg.pl#152 -
* Waiting 5us after frequency change in Step 3 of init sequence
* ------------------------------------------------------------------
* Version:22 - allin - Files Edited: maqs_gen_cfg.pl#12 - maqs_gen_cfg_html.pl#5 - maqstb_cfg.pl#153 - mcu_helper_fxns.c#23 -
* Changes for radar 16013438.
* ------------------------------------------------------------------
* Version:25 - thuang - Files Edited: maqs_gen_cfg_c.pl#18 - maqstb_cfg.pl#170 -
* Release latest amc init without SPLLCTRL programmings
* ------------------------------------------------------------------
* Version:26 - thuang - Files Edited: maqstb_cfg.pl#172 -
* Push out FPGA/Palladium refresh-related changes
* ------------------------------------------------------------------
* Version:27 - cpolapra - Files Edited: maqstb_cfg.pl#173 -
* Restoring post-calib registers for cortex.
* ------------------------------------------------------------------
* Version:28 - cpolapra - Files Edited: maqstb_cfg.pl#176 -
* Added DQS/Dq skew scale factor programming
* ------------------------------------------------------------------
* Version:29 - thuang - Files Edited: maqstb_cfg.pl#183 -
* Move VRCG enable from step7 to step4
* ------------------------------------------------------------------
* Version:30 - jayp - Files Edited: maqs_gen_cfg_c.pl#19 -
* new init for disablint LLT for A0 (16459536) and spllctrl renaming (16317738)
* ------------------------------------------------------------------
* Version:31 - jayp - Files Edited: maqs_gen_cfg_c.pl#22 -
* latest init sequence release + amcx release (tunables) + fix for spllctrl naming (16317738)
* ------------------------------------------------------------------
* Version:32 - jayp - Files Edited: maqstb_cfg.pl#186 -
* uncommenting spllctrl registers from maqstb_cfg.pl
* ------------------------------------------------------------------
* Version:33 - thuang - Files Edited: maqstb_cfg.pl#187 -
* Update AutoSR and DBI settings for FPGA to match ASIC
* ------------------------------------------------------------------
* Version:34 - cpolapra - Files Edited: gen_mcu_init.pl#9 -
* Fix for
* ------------------------------------------------------------------
* Version:35 - herb - Files Edited: maqstb_cfg.pl#199 -
* acmx v0.33.2
* amp v0.64.3
* ------------------------------------------------------------------
* Version:36 - thuang - Files Edited: maqstb_cfg.pl#202 -
* Always set MR13[4] for modified refresh
* ------------------------------------------------------------------
* Version:37 - thuang - Files Edited: maqstb_cfg.pl#210 -
* Update tMRWCyc and also push out init update
* ------------------------------------------------------------------
* Version:38 - cpolapra - Files Edited: maqs_gen_cfg.pl#21 - maqs_gen_cfg_c.pl#26 - maqs_gen_cfg_html.pl#7 - maqstb_cfg.pl#215 -
* Ported over SW calibration code and init sequence from Maui A0
* ------------------------------------------------------------------
* Version:39 - cpolapra - Files Edited: maqstb_cfg.pl#216 -
* Init sequence update for radars rdar://problem/18103117&18434646
* ------------------------------------------------------------------
* Version:40 - cpolapra - Files Edited: phy_helper_fxns.pl#96 -
* Fix for rdar://problem/18956147
* ------------------------------------------------------------------
* Version:41 - thuang - Files Edited: maqstb_cfg.pl#218 -
* Set HiTempRefRnkAgeOut_freq1 to 1 per rdar://problem/19067264
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1
       MccStickyEn = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
Maximum Number of Powered Ways. + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000110
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x1 *read-only
---
Turn on the MCC + +
    amcc_mcccfg_MccGen = 0x00000195
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x1
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
Set Dynamic Way PowerGating + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000010
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x0
---
+ + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5 *read-only
          ChSelTyp = 0x0 *read-only
          ChnlStartBit = 0x2 *read-only
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3 *read-only
       slvpll_cp_lp = 0x0 *read-only
       slvpll_cp_md = 0x0 *read-only
       slvpll_cp_pd = 0x0 *read-only
       slvpll_cp_r_set = 0x8 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000076
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x6 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000078
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x8
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0 *read-only
       slvpll_reg_pd = 0x0 *read-only
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0 *read-only
       spll_mode_dcs_pwrdn = 0x1 *read-only
       use_idle_for_pd = 0x0 *read-only
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xce012402
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x24
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xce
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0 *read-only
       freqchngmrw9_ctrl_freq0 = 0x0 *read-only
       freqchngmrw9_data_freq0 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303020b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x2
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000416
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x4
       freqchngmrw9_addr_freq1 = 0x0 *read-only
       freqchngmrw9_ctrl_freq1 = 0x0 *read-only
       freqchngmrw9_data_freq1 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0 *read-only
       freqchngmrw9_ctrl_freq2 = 0x0 *read-only
       freqchngmrw9_data_freq2 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0 *read-only
       freqchngmrw9_ctrl_freq3 = 0x0 *read-only
       freqchngmrw9_data_freq3 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-2667 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3 *read-only
       tDQSCKMinCyc_freq0 = 0x0 *read-only
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00103306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3 *read-only
          tDQSCKMinCyc_freq0 = 0x0 *read-only
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2 *read-only
       tDQSCKMinCyc_freq1 = 0x0 *read-only
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2 *read-only
          tDQSCKMinCyc_freq1 = 0x0 *read-only
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010c01
       PHYRdLat_freq0 = 0xc
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00050c0a
          PHYRdLat_freq0 = 0xc
          PHYtPhyWrlat_freq0 = 0x5
          PHYtRddataEn_freq0 = 0xa
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010b01
       PHYRdLat_freq1 = 0xb
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050b06
          PHYRdLat_freq1 = 0xb
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
       PHYRdLat_freq2 = 0xb
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
          PHYRdLat_freq2 = 0xb
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
       PHYRdLat_freq3 = 0x9
       PHYtPhyWrlat_freq3 = 0x1
       PHYtRddataEn_freq3 = 0x1
else
       amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
          PHYRdLat_freq3 = 0x9
          PHYtPhyWrlat_freq3 = 0x1
          PHYtRddataEn_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x42110408
       tRASCyc_freq0 = 0x11
       tRCDCyc_freq0 = 0x8
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x8
       tWTRCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x531a060b
          tRASCyc_freq0 = 0x1a
          tRCDCyc_freq0 = 0xb
          tRTPCyc_freq0 = 0x5
          tWRCyc_freq0 = 0xc
          tWTRCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x10040908
       tFAWCyc_freq0 = 0x10
       tRPCyc_freq0 = 0x8
       tRPabCyc_freq0 = 0x9
       tRRDCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x18060d0b
          tFAWCyc_freq0 = 0x18
          tRPCyc_freq0 = 0xb
          tRPabCyc_freq0 = 0xd
          tRRDCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c0078
          tRFCBaseCyc_freq0 = 0x78 *read-only
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0x50057012
       tFCCyc_freq0 = 0x50
       tXSRCyc_freq0 = 0x57
       tZQCalCyc_freq0 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq0(n) = 0x78071012
          tFCCyc_freq0 = 0x78
          tXSRCyc_freq0 = 0x71
          tZQCalCyc_freq0 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x0e0a9084
       tMRRCyc = 0x4
       tMRRICyc = 0x8
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0xe
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060a9024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x140a90b4
          tMRRCyc = 0x4
          tMRRICyc = 0xb
          tMRWCyc = 0x9
          tVRCGOFFCyc = 0xa
          tZQLatCyc = 0x14
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x42110408
       tRASCyc_freq1 = 0x11
       tRCDCyc_freq1 = 0x8
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x8
       tWTRCyc_freq1 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480050. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480050.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50 *read-only
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50 *read-only
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0x50057012
       tFCCyc_freq1 = 0x50
       tXSRCyc_freq1 = 0x57
       tZQCalCyc_freq1 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x42110408
       tRASCyc_freq2 = 0x11
       tRCDCyc_freq2 = 0x8
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x8
       tWTRCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x10040908
       tFAWCyc_freq2 = 0x10
       tRPCyc_freq2 = 0x8
       tRPabCyc_freq2 = 0x9
       tRRDCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14 *read-only
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0x50057012
       tFCCyc_freq2 = 0x50
       tXSRCyc_freq2 = 0x57
       tZQCalCyc_freq2 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x42110408
       tRASCyc_freq3 = 0x11
       tRCDCyc_freq3 = 0x8
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x8
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x10040b0a
       tFAWCyc_freq3 = 0x10
       tRPCyc_freq3 = 0xa
       tRPabCyc_freq3 = 0xb
       tRRDCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5 *read-only
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x50057012
       tFCCyc_freq3 = 0x50
       tXSRCyc_freq3 = 0x57
       tZQCalCyc_freq3 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15 *read-only
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15 *read-only
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x31263263
       tCKECyc = 0x3
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x3
       tCKb4CKECyc = 0x1
       tXPCyc = 0x3
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21262222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x62265295
          tCKECyc = 0x5
          tCKEPDECyc = 0x1 *read-only
          tCKESRCyc = 0x9
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x6
          tCKafCKECyc = 0x6
          tCKb4CKECyc = 0x2
          tXPCyc = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq0 = 0x3
       tRASDrtCyc_freq0 = 0x12
       tRCDDrtCyc_freq0 = 0x8
       tRPDrtCyc_freq0 = 0x8
       tRPabDrtCyc_freq0 = 0xa
       tRRDDrtCyc_freq0 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x38c486cc
          tDQSCKMaxDrtCyc_freq0 = 0x4
          tRASDrtCyc_freq0 = 0x1b
          tRCDDrtCyc_freq0 = 0xc
          tRPDrtCyc_freq0 = 0xc
          tRPabDrtCyc_freq0 = 0xe
          tRRDDrtCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq1 = 0x3
       tRASDrtCyc_freq1 = 0x12
       tRCDDrtCyc_freq1 = 0x8
       tRPDrtCyc_freq1 = 0x8
       tRPabDrtCyc_freq1 = 0xa
       tRRDDrtCyc_freq1 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq2 = 0x3
       tRASDrtCyc_freq2 = 0x12
       tRCDDrtCyc_freq2 = 0x8
       tRPDrtCyc_freq2 = 0x8
       tRPabDrtCyc_freq2 = 0xa
       tRRDDrtCyc_freq2 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x30a35488
       tDQSCKMaxDrtCyc_freq3 = 0x3
       tRASDrtCyc_freq3 = 0x12
       tRCDDrtCyc_freq3 = 0x8
       tRPDrtCyc_freq3 = 0xa
       tRPabDrtCyc_freq3 = 0xc
       tRRDDrtCyc_freq3 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00112306
       DRAMRL_freq0 = 0xc
       DRAMWL_freq0 = 0x6
       tDQSCKMaxCyc_freq0 = 0x2
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00113306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x1
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00112206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001120c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x2
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001120c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x2
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2rTatDeadCyc_freq0 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wTatDeadCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_tat_freq0(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2rTatDeadCyc_freq0 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2wTatDeadCyc_freq0 = 0x3
          W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wTatDeadCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2rTatDeadCyc_freq1 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wTatDeadCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2rTatDeadCyc_freq1 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wTatDeadCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2rTatDeadCyc_freq2 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2wTatDeadCyc_freq2 = 0x3
       W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wTatDeadCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2rTatDeadCyc_freq2 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wTatDeadCyc_freq2 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq3(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2rTatDeadCyc_freq3 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2wTatDeadCyc_freq3 = 0x3
       W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wTatDeadCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_tat_freq3(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2rTatDeadCyc_freq3 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2wTatDeadCyc_freq3 = 0x2
          W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wTatDeadCyc_freq3 = 0x1 *read-only
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0 *read-only
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0 *read-only
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0 *read-only
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0 *read-only
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0 *read-only
       SchEn = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3 *read-only
       PhyInitStartCyc = 0x0 *read-only
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f0(n) = 0x000b316b
       CaDsPd_f0 = 0xb
       Ck0DsPd_f0 = 0xb
       Ck1DsPd_f0 = 0xc *read-only
       CsDsPd_f0 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f1(n) = 0x000b216b
       CaDsPd_f1 = 0xb
       Ck0DsPd_f1 = 0xb
       Ck1DsPd_f1 = 0x8 *read-only
       CsDsPd_f1 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f2(n) = 0x000b3d6b
       CaDsPd_f2 = 0xb
       Ck0DsPd_f2 = 0xb
       Ck1DsPd_f2 = 0xf *read-only
       CsDsPd_f2 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f3(n) = 0x000b3d6b
       CaDsPd_f3 = 0xb
       Ck0DsPd_f3 = 0xb
       Ck1DsPd_f3 = 0xf *read-only
       CsDsPd_f3 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqds_f1(n) = 0x00000000
       CaDs_f1 = 0x0
       Ck0Ds_f1 = 0x0
       Ck1Ds_f1 = 0x0
       CsDs_f1 = 0x0
---
+ +
    ampsca_ampscaiocfg_nondqds_f2(n) = 0x00083d08
       CaDs_f2 = 0x8
       Ck0Ds_f2 = 0x8
       Ck1Ds_f2 = 0xf *read-only
       CsDs_f2 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f3(n) = 0x00083d08
       CaDs_f3 = 0x8
       Ck0Ds_f3 = 0x8
       Ck1Ds_f3 = 0xf *read-only
       CsDs_f3 = 0x8
---
+ +
    ampsca_ampscaiocfg_CaCkCsWkDs(n) = 0x000000db
       CaWkDs = 0x3
       CkWkDs = 0x3
       CsWkDs = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
          ODTEnable = 0x0
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f0(n) = 0x000c0b08
       RdDqODTDs = 0xc
       WrDqPdDs = 0xb
       WrDqPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqds_f1(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f2(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f3(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f0(n) = 0x00030b08
       RdDqDqsODTDs = 0x3
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f1(n) = 0x00010b00
       RdDqDqsODTDs = 0x1
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f2(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f3(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
**IMPORTANT** : For power saving on SOC's these setings are mandatory. With Samsung DRAM, VRef_f1 should be set to 0x00EC00EC. With Micron DRAM, VRef_f1 should be set to 0x00EA00EA. With Hynix DRAM, VRef_f1 should be set to 0x00DF00DF.
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00df00df
       DqsVRefSel = 0xdf
       VRefSel = 0xdf
---
+ +
    ampsdq_ampsdqrdtim_dqspdres(n) = 0x00000031
       DqsPdVal = 0x1 *read-only
       DqsWkPuPdVal = 0x3
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x0303030b
       ClkEn2Valid = 0x3 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x3 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x0003000b
       ClkEn2Valid = 0x0 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x0 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqiocfg_diffmode_freq3(n) = 0x00000001
       DqInVrefMode_f3 = 0x0
       DqsInDiffMode_f3 = 0x0
       DqsOutDiffMode_f3 = 0x1
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0004
       Rd0RunSDLLUpd = 0x0 *read-only
       Rd0RunSDLLUpdOverride = 0x0 *read-only
       Rd0RunSDLLUpdWrResult = 0x0 *read-only
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000004
       WrDqDqsRunSDLLUpd = 0x0 *read-only
       WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
       WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
       WrDqDqsWrLvlReBalanceEn = 0x0 *read-only
       WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
       WrDqSDLLHalfClkEn = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff02ff
       WrLvlMaxWrDqsSDLLCode = 0xff *read-only
       WrLvlRunUpdOverride = 0x0 *read-only
       WrLvlRunUpdWrResult = 0x0 *read-only
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdWrResult
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
+ +
    ampsdq_ampsdqrdtim_dqsPdEnAlwaysOn(n) = 0x00000001
       DqsPdEnAlwaysOn = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x04000410
       tCA2CAEntry = 0x10
       tCA2CAExit = 0x0
       tCKEHEntry = 0x4
       tCKEHExit = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000410
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000410
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000410
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x04020402
       tCA2CAEntry_f0 = 0x2
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x4
       tCKEHExit_f0 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020402
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020402
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020402
       tCA2CAEntry_f3 = 0x2
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x00001426
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x6
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x00001422
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000301e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x30
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x03111004
       tRd2Rd = 0x4
       tRd2Wr = 0x10
       tWr2Rd = 0x11
       tWr2Wr = 0x3 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00aa01d1
       EndPoint = 0xaa
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x00ca0160
       EndPoint = 0xca
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00aa01d1
       EndPoint = 0xaa
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x00ca0160
       EndPoint = 0xca
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a0080c
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xc
       WrDqsSDLLMulFactorF1 = 0x8
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0 *read-only
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq0(n) = 0x00000008
       CaOutDllScl_f0 = 0x8
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq0(n) = 0x00000008
       DqsInDll0Scl_f0 = 0x8
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100070a
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0xa
       RdDatLat_f0 = 0x7
       WrPhaseDelay_f0 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100070d
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1 *read-only
          RdCapLat_f0 = 0xd
          RdDatLat_f0 = 0x7
          WrPhaseDelay_f0 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq1(n) = 0x0000000c
       CaOutDllScl_f1 = 0xc
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq1(n) = 0x0000000c
       DqsInDll0Scl_f1 = 0xc
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1 *read-only
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100060a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1 *read-only
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x6
          WrPhaseDelay_f1 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq2(n) = 0x00000030
       CaOutDllScl_f2 = 0x30
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq2(n) = 0x00000030
       DqsInDll0Scl_f2 = 0x30
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x4100040a
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0xa
       RdDatLat_f2 = 0x4
       WrPhaseDelay_f2 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000406
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1 *read-only
          RdCapLat_f2 = 0x6
          RdDatLat_f2 = 0x4
          WrPhaseDelay_f2 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq3(n) = 0x0000003f
       CaOutDllScl_f3 = 0x3f
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq3(n) = 0x0000003f
       DqsInDll0Scl_f3 = 0x3f
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x6100040a
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0xa
       RdDatLat_f3 = 0x4
       WrPhaseDelay_f3 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000406
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1
          RdCapLat_f3 = 0x6
          RdDatLat_f3 = 0x4
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---


FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impautocal(n) = 0x00010000
          impautocalen = 0x1
          impcalintvl = 0x0 *read-only
          impcaltype = 0x0
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
Enable DLL + +
    ampsca_ampscadllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000000
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
+ +
    ampsca_ampscaiocfg_BISTRxMode(n) = 0x0000001c
       BISTRxMode = 0x0 *read-only
       BISTRxODT = 0x7
       BISTRxODTEn = 0x0 *read-only
---
+ +
    amph_SLC_SLC_REG0(n) = 0x0000003f
       pad_ca0_slc = 0xf
       pad_ca1_slc = 0x3
       pad_ca2_slc = 0x0 *read-only
       pad_ca3_slc = 0x0 *read-only
       pad_ca4_slc = 0x0 *read-only
       pad_ca5_slc = 0x0 *read-only
       pad_ck_slc = 0x0 *read-only
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x08010019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0x8
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480050
       tRFCBaseCyc_freq3 = 0x50
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480050
       tRFCBaseCyc_freq2 = 0x50
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480049. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480049.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480050
       tRFCBaseCyc_freq0 = 0x50
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c006e
          tRFCBaseCyc_freq0 = 0x6e
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00170013
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0 *read-only
          ShareZQRes = 0x0 *read-only
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x0 *read-only
          ZqCalIntrvl = 0x0 *read-only
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01012008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030007
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x7
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x11100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x1
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x11000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x1
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x11110000
          ARpbEn_freq1 = 0x1 *read-only
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x1
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1111013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x1
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00010000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00000000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR11 for FPGA

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and Modified Refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x26204100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5e284100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + +
if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000001f
       DramSize = 0x1f
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050201
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060201
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060210
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x1
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060220
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x2
          NumMcuChnl = 0x2
---
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

7. Setup registers for CA calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1, and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x52020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xae010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x020b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0 *read-only
          WrLvlRunUpdWrResult = 0x0 *read-only
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

8. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step8Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 1, 16, 12);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0 + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update + +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x0 *read-only
YesYes-
Poll ampsdqdllctl dllupdtcmd + +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
RdWrDqCalSegLen_f0

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
RdWrDqCalSegLen_f1

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
+ +
       amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
          freqchngmrw2_addr_freq0 = 0xe
          freqchngmrw2_ctrl_freq0 = 0x0
          freqchngmrw2_data_freq0 = 0x11
          freqchngmrw3_addr_freq0 = 0xc
          freqchngmrw3_ctrl_freq0 = 0x0
          freqchngmrw3_data_freq0 = 0x11
YesYes-
+ +
       amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
          freqchngmrw2_addr_freq1 = 0xe
          freqchngmrw2_ctrl_freq1 = 0x0
          freqchngmrw2_data_freq1 = 0x11
          freqchngmrw3_addr_freq1 = 0xc
          freqchngmrw3_ctrl_freq1 = 0x0
          freqchngmrw3_data_freq1 = 0x11
YesYes-


FPGA: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x0
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
else
          amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
             freqchngmrw4_addr_freq0 = 0xb
             freqchngmrw4_ctrl_freq0 = 0x0
             freqchngmrw4_data_freq0 = 0x44
             freqchngmrw5_addr_freq0 = 0x3
             freqchngmrw5_ctrl_freq0 = 0x0
             freqchngmrw5_data_freq0 = 0xb3
YesYes-


FPGA: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x00061a80
          ZQCTimerCnt = 0x61a80
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

9. Setup registers for DQ calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 1 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0xd80d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
YesNo-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR + +
       amcx_dramcfg_pwrmngten(n) = 0x00000002
          AutoSR = 0x1
          DynPwrDnEn = 0x0 *read-only
          McPhyUpdDramClkOff = 0x0 *read-only
          PwrDnClkOff = 0x0 *read-only
          SRClkOff = 0x0 *read-only
          SRExitOpt = 0x0 *read-only
-Yes-
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
YesYes-
WrDqDqsSDLLCtrl + +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff00000c
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 800Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

10. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 1, 16, 12);
+
---
+ +
    ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000010
       DqIdleActive = 0x0
       DqsIdleActive = 0x1
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
The scale factors for Bin0 and Bin1 WR DQS/DQ skew have to to programmed to the correct values based on board charaterization. Fields are being set to 0 here, since exact board skews are not available now (04/01/14). + +
    ampsdq_ampsdqsdllctrl_WrtDQSDQSkewControl(n) = 0x06000000
       WrDqDqsIDTVTScaleEn = 0x1 *read-only
       WrDqDqsMDLLVTScaleEn = 0x1 *read-only
       WrtDQSDQScaleFactorF0 = 0x0
       WrtDQSDQScaleFactorF1 = 0x0
       WrtDQSDQScaleFactorPlusSel = 0x0
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
       ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000000
          DqIdleActive = 0x0
          DqsIdleActive = 0x0
-No-
Program FSP-WR to 0 and FSP-OP to 1 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x24020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xce010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 24, 12);
+
---


FPGA: Skip this step

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x340b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x4f004100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers

SAMSUNG: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x51004100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

SAMSUNG: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 20ns for tZQLAT. +
---


SAMSUNG: Perform this step
+ +
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303340b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x34
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
-No-
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 0 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Call custom API provided by PMGR for changing mcu_clk to 1200Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 24, 12);
+
---
+ +
       ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000010
          DqIdleActive = 0x0
          DqsIdleActive = 0x1
-No-
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    ampsca_ampscaiocfg_BISTRxMode(n) = 0x00000000
       BISTRxMode = 0x0 *read-only
       BISTRxODT = 0x0
       BISTRxODTEn = 0x0 *read-only
---
+ +
    amph_SLC_SLC_REG0(n) = 0x0000013f
       pad_ca0_slc = 0xf
       pad_ca1_slc = 0x3
       pad_ca2_slc = 0x1
       pad_ca3_slc = 0x0 *read-only
       pad_ca4_slc = 0x0 *read-only
       pad_ca5_slc = 0x0 *read-only
       pad_ck_slc = 0x0 *read-only
---
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG, since all calibrations are done + +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-


DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00150004
          Rd0RunSDLLUpd = 0x0 *read-only
          Rd0RunSDLLUpdOverride = 0x0 *read-only
          Rd0RunSDLLUpdWrResult = 0x0 *read-only
          Rd0SDLLOvrVal = 0x15
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x08010019
       FreqChngWaitThr = 0x1 *read-only
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0x8
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0 *read-only
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x11100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x1
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x11000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x1
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x11110000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x1
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1111013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x1
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbrparam(n) = 0x61616161
       RdCwfEarlyCyc_freq0 = 0x1
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x1
       RdCwfEarlyCyc_freq3 = 0x1
       RdRemEarlyCyc_freq0 = 0x6
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x6
       RdRemEarlyCyc_freq3 = 0x6
else if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00006100
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000061a5
          RdCwfEarlyCyc_freq0 = 0x5
          RdCwfEarlyCyc_freq1 = 0x1
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x6
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1 *read-only
       Mcc0AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc0DpPropQCfg = 0x0 *read-only
       Mcc0DpPropQCmd = 0x1 *read-only
       Mcc0DpPropQTrakEnbl = 0x0 *read-only
       Mcc0MsqQPropCfg = 0x0 *read-only
       Mcc0MsqQPropQCmd = 0x0 *read-only
       Mcc0MsqQPropTrakEnbl = 0x0 *read-only
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0 *read-only
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0 *read-only
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1 *read-only
       Mcc1AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc1DpPropQCfg = 0x0 *read-only
       Mcc1DpPropQCmd = 0x1 *read-only
       Mcc1DpPropQTrakEnbl = 0x0 *read-only
       Mcc1MsqQPropCfg = 0x0 *read-only
       Mcc1MsqQPropQCmd = 0x0 *read-only
       Mcc1MsqQPropTrakEnbl = 0x0 *read-only
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0 *read-only
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0 *read-only
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1 *read-only
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0 *read-only
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
disable dynamic power-down. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
---
disable dynamic power-down. + +
       amcx_dramcfg_pwrmngten(n) = 0x00000133
          AutoSR = 0x1
          DynPwrDnEn = 0x1
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
-No-
Revert auto self-refresh wait timer to guided value.

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngtparam_freq0(n) = 0x01800000
          BypsPwrDnDlyCyc_freq0 = 0x0 *read-only
          SelfRefTmrVal_freq0 = 0x180
---
Setting WqAgeOutVal to be 3/4 of SelfRefTmrVal, to flush writes in a reasonable time.

FPGA: Skip this step
+ +
       amcx_mcusch_psqwqctl1(n) = 0x01640120
          WqAgeOutVal_freq0 = 0x120
          WqAgeOutVal_freq1 = 0x164 *read-only
---
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000000ff
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
Yes--
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x01500150
       PreFreqChng2AllBankDly_f0 = 0x150
       PreFreqChng2AllBankDly_f1 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x01500150
       PreFreqChng2AllBankDly_f2 = 0x150
       PreFreqChng2AllBankDly_f3 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02a002a0
       PreFreqChng2FreqChngDly_f0 = 0x2a0
       PreFreqChng2FreqChngDly_f1 = 0x2a0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02a002a0
       PreFreqChng2FreqChngDly_f2 = 0x2a0
       PreFreqChng2FreqChngDly_f3 = 0x2a0
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly0 = 0x00900090
       Cal2PreFreqChngDly_f0 = 0x90
       Cal2PreFreqChngDly_f1 = 0x90
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly1 = 0x00900090
       Cal2PreFreqChngDly_f2 = 0x90
       Cal2PreFreqChngDly_f3 = 0x90
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly0 = 0x01200120
       FreqChng2PstCalDly_f0 = 0x120
       FreqChng2PstCalDly_f1 = 0x120
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly1 = 0x01200120
       FreqChng2PstCalDly_f2 = 0x120
       FreqChng2PstCalDly_f3 = 0x120
---
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6c0
          RdCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--


SAMSUNG: Skip this step
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
YesNo-
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x000493e0
          PerCal_FreqChngTimerCnt = 0x493e0
YesNo-
+ +
       glbtimer_GlbTimer_VoltRampTimer = 0x000493e0
          VoltRampTimerCnt = 0x493e0
YesNo-
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
YesNo-
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly0 = 0x00d800d8
          VoltRamp2AllBankDly_f0 = 0xd8
          VoltRamp2AllBankDly_f1 = 0xd8
YesNo-
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly1 = 0x00d800d8
          VoltRamp2AllBankDly_f2 = 0xd8
          VoltRamp2AllBankDly_f3 = 0xd8
YesNo-
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly0 = 0x00900090
          AllBank2PmgrAckDly_f0 = 0x90
          AllBank2PmgrAckDly_f1 = 0x90
YesNo-
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly1 = 0x00900090
          AllBank2PmgrAckDly_f2 = 0x90
          AllBank2PmgrAckDly_f3 = 0x90
YesNo-
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa *read-only
       MCUBCGClkGateEn = 0x0 *read-only
       MCUBCGPwrGateEn = 0x0 *read-only
       PwrRstCyc = 0x5 *read-only
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0 *read-only
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Maui_Init_B0_1200_June_2_2015.html b/docs/dcs-specs/Maui_Init_B0_1200_June_2_2015.html new file mode 100644 index 0000000..def35a1 --- /dev/null +++ b/docs/dcs-specs/Maui_Init_B0_1200_June_2_2015.html @@ -0,0 +1,2953 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Tue Jun 2 23:37:28 2015
AMC Version: Major Release: Minor Release:
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/b0.maui/amcc/tb/cfg/static/maqstb_cfg.pl#24
AMP UM Init sourced from: //depot/ip_lib/apple/amp/b0.maui/amp/tb/cfg/phy_helper_fxns.pl#11
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - thuang - Files Edited: mcu_helper_fxns.c#5 - mcu_helper_fxns.c#7 - mcu_helper_fxns.h#6 -
* Added Rama's change in pmgr_amc_clk_cfg
* ------------------------------------------------------------------
* Version:7 - thuang - Files Edited: mcu_helper_fxns.c#8 - mcu_helper_fxns.h#6 -
* Release init, specifically to deal with 1202MHz at bucket 0
* ------------------------------------------------------------------
* Version:8 - jayp - Files Edited: mcu_helper_fxns.c#8 - mcu_helper_fxns.h#6 -
* release latest init to match AMCX release
* ------------------------------------------------------------------
* Version:9 - jayp - Files Edited: mcu_helper_fxns.c#9 - mcu_helper_fxns.h#7 -
* update to new dcsh/v.hspds that now points to the real amph.spds
* ------------------------------------------------------------------
* Version:10 - jayp - Files Edited: mcu_helper_fxns.c#10 - mcu_helper_fxns.h#8 -
* updating to preFinal releases of amp, amph, and amcx
* ------------------------------------------------------------------
* Version:11 - thuang - Files Edited: mcu_helper_fxns.c#11 - mcu_helper_fxns.h#9 -
* Init update
* ------------------------------------------------------------------
* Version:12 - jayp - Files Edited: mcu_helper_fxns.c#11 - mcu_helper_fxns.h#9 -
* moving to new amp pointer
* ------------------------------------------------------------------
* Version:13 - cpolapra - Files Edited: maqstb_cfg.pl#72 - calibration_fxns.pl#8 - mcu_helper_fxns.c#12 - mcu_helper_fxns.h#10 -
* Updated chip level config files for calibration at both Bucket 0 & Bucket 1
* ------------------------------------------------------------------
* Version:14 - jayp - Files Edited: mcu_helper_fxns.c#13 - mcu_helper_fxns.h#12 -
* update to init code for latest amcx and amp releases
* ------------------------------------------------------------------
* Version:15 - jayp - Files Edited: gen_mcu_init.pl#6 - mcu_helper_fxns.c#15 - mcu_helper_fxns.h#14 -
* moving to latest amph, amcx, and amp pointers
* ------------------------------------------------------------------
* Version:16 - allin - Files Edited: maqs_gen_cfg_c.pl#12 - maqstb_cfg.pl#123 - mem_tparams.pl#27 - phy_helper_fxns.pl#53 - move_generated_files.pl#4 - mcu_helper_fxns.c#18 - mcu_helper_fxns.h#16 -
* Fixes to MRR/MRW inclusion in resume boot
* ------------------------------------------------------------------
* Version:17 - jayp - Files Edited: maqstb_cfg.pl#125 - mcu_helper_fxns.c#20 - mcu_helper_fxns.h#18 -
* moving to latest amp and amcx releases
* ------------------------------------------------------------------
* Version:18 - jayp - Files Edited: maqs_gen_cfg_c.pl#14 - maqstb_cfg.pl#135 -
* releasing new amp to change global timer register naming so that chip and ams both work
* ------------------------------------------------------------------
* Version:19 - cpolapra - Files Edited: maqstb_cfg.pl#141 -
* Fixed tDIPW denali error
* ------------------------------------------------------------------
* Version:20 - cpolapra - Files Edited: maqstb_cfg.pl#148 -
* PMGR random fixes
* ------------------------------------------------------------------
* Version:21 - cpolapra - Files Edited: maqstb_cfg.pl#152 -
* Waiting 5us after frequency change in Step 3 of init sequence
* ------------------------------------------------------------------
* Version:22 - allin - Files Edited: maqs_gen_cfg.pl#12 - maqs_gen_cfg_html.pl#5 - maqstb_cfg.pl#153 - mcu_helper_fxns.c#23 -
* Changes for radar 16013438.
* ------------------------------------------------------------------
* Version:25 - thuang - Files Edited: maqs_gen_cfg_c.pl#18 - maqstb_cfg.pl#170 -
* Release latest amc init without SPLLCTRL programmings
* ------------------------------------------------------------------
* Version:26 - thuang - Files Edited: maqstb_cfg.pl#172 -
* Push out FPGA/Palladium refresh-related changes
* ------------------------------------------------------------------
* Version:27 - cpolapra - Files Edited: maqstb_cfg.pl#173 -
* Restoring post-calib registers for cortex.
* ------------------------------------------------------------------
* Version:28 - cpolapra - Files Edited: maqstb_cfg.pl#176 -
* Added DQS/Dq skew scale factor programming
* ------------------------------------------------------------------
* Version:29 - thuang - Files Edited: maqstb_cfg.pl#183 -
* Move VRCG enable from step7 to step4
* ------------------------------------------------------------------
* Version:30 - jayp - Files Edited: maqs_gen_cfg_c.pl#19 -
* new init for disablint LLT for A0 (16459536) and spllctrl renaming (16317738)
* ------------------------------------------------------------------
* Version:31 - jayp - Files Edited: maqs_gen_cfg_c.pl#22 -
* latest init sequence release + amcx release (tunables) + fix for spllctrl naming (16317738)
* ------------------------------------------------------------------
* Version:32 - jayp - Files Edited: maqstb_cfg.pl#186 -
* uncommenting spllctrl registers from maqstb_cfg.pl
* ------------------------------------------------------------------
* Version:33 - thuang - Files Edited: maqstb_cfg.pl#187 -
* Update AutoSR and DBI settings for FPGA to match ASIC
* ------------------------------------------------------------------
* Version:34 - cpolapra - Files Edited: gen_mcu_init.pl#9 -
* Fix for
* ------------------------------------------------------------------
* Version:35 - herb - Files Edited: maqstb_cfg.pl#199 -
* acmx v0.33.2
* amp v0.64.3
* ------------------------------------------------------------------
* Version:36 - thuang - Files Edited: maqstb_cfg.pl#202 -
* Always set MR13[4] for modified refresh
* ------------------------------------------------------------------
* Version:37 - thuang - Files Edited: maqstb_cfg.pl#210 -
* Update tMRWCyc and also push out init update
* ------------------------------------------------------------------
* Version:38 - cpolapra - Files Edited: maqs_gen_cfg.pl#21 - maqs_gen_cfg_c.pl#26 - maqs_gen_cfg_html.pl#7 - maqstb_cfg.pl#215 -
* Ported over SW calibration code and init sequence from Maui A0
* ------------------------------------------------------------------
* Version:39 - cpolapra - Files Edited: maqstb_cfg.pl#216 -
* Init sequence update for radars rdar://problem/18103117&18434646
* ------------------------------------------------------------------
* Version:40 - cpolapra - Files Edited: phy_helper_fxns.pl#96 -
* Fix for rdar://problem/18956147
* ------------------------------------------------------------------
* Version:41 - thuang - Files Edited: maqstb_cfg.pl#218 -
* Set HiTempRefRnkAgeOut_freq1 to 1 per rdar://problem/19067264
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1
       MccStickyEn = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
Maximum Number of Powered Ways. + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000110
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x1 *read-only
---
Turn on the MCC + +
    amcc_mcccfg_MccGen = 0x00000195
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x1
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
Set Dynamic Way PowerGating + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000010
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x0
---
+ + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5 *read-only
          ChSelTyp = 0x0 *read-only
          ChnlStartBit = 0x2 *read-only
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3 *read-only
       slvpll_cp_lp = 0x0 *read-only
       slvpll_cp_md = 0x0 *read-only
       slvpll_cp_pd = 0x0 *read-only
       slvpll_cp_r_set = 0x8 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000076
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x6 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000078
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x8
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0 *read-only
       slvpll_reg_pd = 0x0 *read-only
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0 *read-only
       spll_mode_dcs_pwrdn = 0x1 *read-only
       use_idle_for_pd = 0x0 *read-only
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xce012402
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x24
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xce
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0 *read-only
       freqchngmrw9_ctrl_freq0 = 0x0 *read-only
       freqchngmrw9_data_freq0 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303020b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x2
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000416
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x4
       freqchngmrw9_addr_freq1 = 0x0 *read-only
       freqchngmrw9_ctrl_freq1 = 0x0 *read-only
       freqchngmrw9_data_freq1 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0 *read-only
       freqchngmrw9_ctrl_freq2 = 0x0 *read-only
       freqchngmrw9_data_freq2 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0 *read-only
       freqchngmrw9_ctrl_freq3 = 0x0 *read-only
       freqchngmrw9_data_freq3 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_rwcfg(n) = 0x000210ef
       CasAPEn = 0x1
       DBIRDEn_freq0 = 0x0
       DBIRDEn_freq1 = 0x1
       DBIRDEn_freq2 = 0x1
       DBIRDEn_freq3 = 0x1
       DBIWREn_freq0 = 0x1
       DBIWREn_freq1 = 0x1
       DBIWREn_freq2 = 0x1
       DBIWREn_freq3 = 0x1
       DBIWRType = 0x0
       tCCDMWCyc = 0x2
else
       amcx_dramcfg_rwcfg(n) = 0x000210ef
          CasAPEn = 0x1
          DBIRDEn_freq0 = 0x0
          DBIRDEn_freq1 = 0x1
          DBIRDEn_freq2 = 0x1
          DBIRDEn_freq3 = 0x1
          DBIWREn_freq0 = 0x1
          DBIWREn_freq1 = 0x1
          DBIWREn_freq2 = 0x1
          DBIWREn_freq3 = 0x1
          DBIWRType = 0x0
          tCCDMWCyc = 0x2
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-2667 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3 *read-only
       tDQSCKMinCyc_freq0 = 0x0 *read-only
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00103306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3 *read-only
          tDQSCKMinCyc_freq0 = 0x0 *read-only
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2 *read-only
       tDQSCKMinCyc_freq1 = 0x0 *read-only
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2 *read-only
          tDQSCKMinCyc_freq1 = 0x0 *read-only
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010c01
       PHYRdLat_freq0 = 0xc
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00050c0a
          PHYRdLat_freq0 = 0xc
          PHYtPhyWrlat_freq0 = 0x5
          PHYtRddataEn_freq0 = 0xa
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010b01
       PHYRdLat_freq1 = 0xb
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050b06
          PHYRdLat_freq1 = 0xb
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
       PHYRdLat_freq2 = 0xb
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
          PHYRdLat_freq2 = 0xb
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
       PHYRdLat_freq3 = 0x9
       PHYtPhyWrlat_freq3 = 0x1
       PHYtRddataEn_freq3 = 0x1
else
       amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
          PHYRdLat_freq3 = 0x9
          PHYtPhyWrlat_freq3 = 0x1
          PHYtRddataEn_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x42110408
       tRASCyc_freq0 = 0x11
       tRCDCyc_freq0 = 0x8
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x8
       tWTRCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x531a060b
          tRASCyc_freq0 = 0x1a
          tRCDCyc_freq0 = 0xb
          tRTPCyc_freq0 = 0x5
          tWRCyc_freq0 = 0xc
          tWTRCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x10040908
       tFAWCyc_freq0 = 0x10
       tRPCyc_freq0 = 0x8
       tRPabCyc_freq0 = 0x9
       tRRDCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x18060d0b
          tFAWCyc_freq0 = 0x18
          tRPCyc_freq0 = 0xb
          tRPabCyc_freq0 = 0xd
          tRRDCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c0078
          tRFCBaseCyc_freq0 = 0x78 *read-only
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0x50057012
       tFCCyc_freq0 = 0x50
       tXSRCyc_freq0 = 0x57
       tZQCalCyc_freq0 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq0(n) = 0x78071012
          tFCCyc_freq0 = 0x78
          tXSRCyc_freq0 = 0x71
          tZQCalCyc_freq0 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x0e0a9084
       tMRRCyc = 0x4
       tMRRICyc = 0x8
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0xe
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060a9024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x140a90b4
          tMRRCyc = 0x4
          tMRRICyc = 0xb
          tMRWCyc = 0x9
          tVRCGOFFCyc = 0xa
          tZQLatCyc = 0x14
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x42110408
       tRASCyc_freq1 = 0x11
       tRCDCyc_freq1 = 0x8
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x8
       tWTRCyc_freq1 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480050. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480050.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50 *read-only
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50 *read-only
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0x50057012
       tFCCyc_freq1 = 0x50
       tXSRCyc_freq1 = 0x57
       tZQCalCyc_freq1 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x42110408
       tRASCyc_freq2 = 0x11
       tRCDCyc_freq2 = 0x8
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x8
       tWTRCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x10040908
       tFAWCyc_freq2 = 0x10
       tRPCyc_freq2 = 0x8
       tRPabCyc_freq2 = 0x9
       tRRDCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14 *read-only
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0x50057012
       tFCCyc_freq2 = 0x50
       tXSRCyc_freq2 = 0x57
       tZQCalCyc_freq2 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x42110408
       tRASCyc_freq3 = 0x11
       tRCDCyc_freq3 = 0x8
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x8
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x10040b0a
       tFAWCyc_freq3 = 0x10
       tRPCyc_freq3 = 0xa
       tRPabCyc_freq3 = 0xb
       tRRDCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5 *read-only
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x50057012
       tFCCyc_freq3 = 0x50
       tXSRCyc_freq3 = 0x57
       tZQCalCyc_freq3 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15 *read-only
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15 *read-only
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x31263263
       tCKECyc = 0x3
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x3
       tCKb4CKECyc = 0x1
       tXPCyc = 0x3
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21262222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x62265295
          tCKECyc = 0x5
          tCKEPDECyc = 0x1 *read-only
          tCKESRCyc = 0x9
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x6
          tCKafCKECyc = 0x6
          tCKb4CKECyc = 0x2
          tXPCyc = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq0 = 0x3
       tRASDrtCyc_freq0 = 0x12
       tRCDDrtCyc_freq0 = 0x8
       tRPDrtCyc_freq0 = 0x8
       tRPabDrtCyc_freq0 = 0xa
       tRRDDrtCyc_freq0 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x38c486cc
          tDQSCKMaxDrtCyc_freq0 = 0x4
          tRASDrtCyc_freq0 = 0x1b
          tRCDDrtCyc_freq0 = 0xc
          tRPDrtCyc_freq0 = 0xc
          tRPabDrtCyc_freq0 = 0xe
          tRRDDrtCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq1 = 0x3
       tRASDrtCyc_freq1 = 0x12
       tRCDDrtCyc_freq1 = 0x8
       tRPDrtCyc_freq1 = 0x8
       tRPabDrtCyc_freq1 = 0xa
       tRRDDrtCyc_freq1 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq2 = 0x3
       tRASDrtCyc_freq2 = 0x12
       tRCDDrtCyc_freq2 = 0x8
       tRPDrtCyc_freq2 = 0x8
       tRPabDrtCyc_freq2 = 0xa
       tRRDDrtCyc_freq2 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x30a35488
       tDQSCKMaxDrtCyc_freq3 = 0x3
       tRASDrtCyc_freq3 = 0x12
       tRCDDrtCyc_freq3 = 0x8
       tRPDrtCyc_freq3 = 0xa
       tRPabDrtCyc_freq3 = 0xc
       tRRDDrtCyc_freq3 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00112306
       DRAMRL_freq0 = 0xc
       DRAMWL_freq0 = 0x6
       tDQSCKMaxCyc_freq0 = 0x2
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00113306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x1
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00112206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001120c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x2
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001120c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x2
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2rTatDeadCyc_freq0 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wTatDeadCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_tat_freq0(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2rTatDeadCyc_freq0 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2wTatDeadCyc_freq0 = 0x3
          W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wTatDeadCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2rTatDeadCyc_freq1 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wTatDeadCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2rTatDeadCyc_freq1 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wTatDeadCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2rTatDeadCyc_freq2 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2wTatDeadCyc_freq2 = 0x3
       W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wTatDeadCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2rTatDeadCyc_freq2 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wTatDeadCyc_freq2 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq3(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2rTatDeadCyc_freq3 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2wTatDeadCyc_freq3 = 0x3
       W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wTatDeadCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_tat_freq3(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2rTatDeadCyc_freq3 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2wTatDeadCyc_freq3 = 0x2
          W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wTatDeadCyc_freq3 = 0x1 *read-only
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0 *read-only
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0 *read-only
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0 *read-only
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0 *read-only
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0 *read-only
       SchEn = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3 *read-only
       PhyInitStartCyc = 0x0 *read-only
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f0(n) = 0x000b316b
       CaDsPd_f0 = 0xb
       Ck0DsPd_f0 = 0xb
       Ck1DsPd_f0 = 0xc *read-only
       CsDsPd_f0 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f1(n) = 0x000b216b
       CaDsPd_f1 = 0xb
       Ck0DsPd_f1 = 0xb
       Ck1DsPd_f1 = 0x8 *read-only
       CsDsPd_f1 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f2(n) = 0x000b3d6b
       CaDsPd_f2 = 0xb
       Ck0DsPd_f2 = 0xb
       Ck1DsPd_f2 = 0xf *read-only
       CsDsPd_f2 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f3(n) = 0x000b3d6b
       CaDsPd_f3 = 0xb
       Ck0DsPd_f3 = 0xb
       Ck1DsPd_f3 = 0xf *read-only
       CsDsPd_f3 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqds_f1(n) = 0x00000000
       CaDs_f1 = 0x0
       Ck0Ds_f1 = 0x0
       Ck1Ds_f1 = 0x0
       CsDs_f1 = 0x0
---
+ +
    ampsca_ampscaiocfg_nondqds_f2(n) = 0x00083d08
       CaDs_f2 = 0x8
       Ck0Ds_f2 = 0x8
       Ck1Ds_f2 = 0xf *read-only
       CsDs_f2 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f3(n) = 0x00083d08
       CaDs_f3 = 0x8
       Ck0Ds_f3 = 0x8
       Ck1Ds_f3 = 0xf *read-only
       CsDs_f3 = 0x8
---
+ +
    ampsca_ampscaiocfg_CaCkCsWkDs(n) = 0x000000db
       CaWkDs = 0x3
       CkWkDs = 0x3
       CsWkDs = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
          ODTEnable = 0x0
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f0(n) = 0x000c0b08
       RdDqODTDs = 0xc
       WrDqPdDs = 0xb
       WrDqPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqds_f1(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f2(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f3(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f0(n) = 0x00030b08
       RdDqDqsODTDs = 0x3
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f1(n) = 0x00010b00
       RdDqDqsODTDs = 0x1
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f2(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f3(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
**IMPORTANT** : For power saving on SOC's these setings are mandatory. With Samsung DRAM, VRef_f1 should be set to 0x00EC00EC. With Micron DRAM, VRef_f1 should be set to 0x00EA00EA. With Hynix DRAM, VRef_f1 should be set to 0x00DF00DF.
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00df00df
       DqsVRefSel = 0xdf
       VRefSel = 0xdf
---
+ +
    ampsdq_ampsdqrdtim_dqspdres(n) = 0x00000031
       DqsPdVal = 0x1 *read-only
       DqsWkPuPdVal = 0x3
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x0303030b
       ClkEn2Valid = 0x3 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x3 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x0003000b
       ClkEn2Valid = 0x0 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x0 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqiocfg_diffmode_freq3(n) = 0x00000001
       DqInVrefMode_f3 = 0x0
       DqsInDiffMode_f3 = 0x0
       DqsOutDiffMode_f3 = 0x1
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0004
       Rd0RunSDLLUpd = 0x0 *read-only
       Rd0RunSDLLUpdOverride = 0x0 *read-only
       Rd0RunSDLLUpdWrResult = 0x0 *read-only
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000004
       WrDqDqsRunSDLLUpd = 0x0 *read-only
       WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
       WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
       WrDqDqsWrLvlReBalanceEn = 0x0 *read-only
       WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
       WrDqSDLLHalfClkEn = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff02ff
       WrLvlMaxWrDqsSDLLCode = 0xff *read-only
       WrLvlRunUpdOverride = 0x0 *read-only
       WrLvlRunUpdWrResult = 0x0 *read-only
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdWrResult
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
+ +
    ampsdq_ampsdqrdtim_dqsPdEnAlwaysOn(n) = 0x00000001
       DqsPdEnAlwaysOn = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x04000410
       tCA2CAEntry = 0x10
       tCA2CAExit = 0x0
       tCKEHEntry = 0x4
       tCKEHExit = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000410
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000410
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000410
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x04020402
       tCA2CAEntry_f0 = 0x2
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x4
       tCKEHExit_f0 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020402
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020402
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020402
       tCA2CAEntry_f3 = 0x2
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x00001426
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x6
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x00001422
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000301e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x30
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x03111004
       tRd2Rd = 0x4
       tRd2Wr = 0x10
       tWr2Rd = 0x11
       tWr2Wr = 0x3 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00aa01d1
       EndPoint = 0xaa
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x00ca0160
       EndPoint = 0xca
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00aa01d1
       EndPoint = 0xaa
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x00ca0160
       EndPoint = 0xca
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a0080c
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xc
       WrDqsSDLLMulFactorF1 = 0x8
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0 *read-only
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq0(n) = 0x00000008
       CaOutDllScl_f0 = 0x8
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq0(n) = 0x00000008
       DqsInDll0Scl_f0 = 0x8
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100070a
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0xa
       RdDatLat_f0 = 0x7
       WrPhaseDelay_f0 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100070d
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1 *read-only
          RdCapLat_f0 = 0xd
          RdDatLat_f0 = 0x7
          WrPhaseDelay_f0 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq1(n) = 0x0000000c
       CaOutDllScl_f1 = 0xc
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq1(n) = 0x0000000c
       DqsInDll0Scl_f1 = 0xc
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1 *read-only
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100060a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1 *read-only
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x6
          WrPhaseDelay_f1 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq2(n) = 0x00000030
       CaOutDllScl_f2 = 0x30
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq2(n) = 0x00000030
       DqsInDll0Scl_f2 = 0x30
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x4100040a
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0xa
       RdDatLat_f2 = 0x4
       WrPhaseDelay_f2 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000406
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1 *read-only
          RdCapLat_f2 = 0x6
          RdDatLat_f2 = 0x4
          WrPhaseDelay_f2 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq3(n) = 0x0000003f
       CaOutDllScl_f3 = 0x3f
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq3(n) = 0x0000003f
       DqsInDll0Scl_f3 = 0x3f
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x6100040a
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0xa
       RdDatLat_f3 = 0x4
       WrPhaseDelay_f3 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000406
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1
          RdCapLat_f3 = 0x6
          RdDatLat_f3 = 0x4
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---


FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impautocal(n) = 0x00010000
          impautocalen = 0x1
          impcalintvl = 0x0 *read-only
          impcaltype = 0x0
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
Enable DLL + +
    ampsca_ampscadllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000000
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
+ +
    ampsca_ampscaiocfg_BISTRxMode(n) = 0x0000001c
       BISTRxMode = 0x0 *read-only
       BISTRxODT = 0x7
       BISTRxODTEn = 0x0 *read-only
---
+ +
    amph_SLC_SLC_REG0(n) = 0x0000003f
       pad_ca0_slc = 0xf
       pad_ca1_slc = 0x3
       pad_ca2_slc = 0x0 *read-only
       pad_ca3_slc = 0x0 *read-only
       pad_ca4_slc = 0x0 *read-only
       pad_ca5_slc = 0x0 *read-only
       pad_ck_slc = 0x0 *read-only
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x0d010019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480050
       tRFCBaseCyc_freq3 = 0x50
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480050
       tRFCBaseCyc_freq2 = 0x50
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480049. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480049.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480050
       tRFCBaseCyc_freq0 = 0x50
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c006e
          tRFCBaseCyc_freq0 = 0x6e
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00170013
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0 *read-only
          ShareZQRes = 0x0 *read-only
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x0 *read-only
          ZqCalIntrvl = 0x0 *read-only
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01022008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x2
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030007
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x7
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10110000
          ARpbEn_freq1 = 0x1 *read-only
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00010000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00000000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR11 for FPGA

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and Modified Refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x26204100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5e284100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + +
if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000001f
       DramSize = 0x1f
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050201
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060201
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060210
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x1
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060220
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x2
          NumMcuChnl = 0x2
---
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

7. Setup registers for CA calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1, and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x52020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xae010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x020b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0 *read-only
          WrLvlRunUpdWrResult = 0x0 *read-only
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

8. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step8Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 1, 16, 12);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0 + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update + +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x0 *read-only
YesYes-
Poll ampsdqdllctl dllupdtcmd + +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
RdWrDqCalSegLen_f0

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
RdWrDqCalSegLen_f1

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
+ +
       amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
          freqchngmrw2_addr_freq0 = 0xe
          freqchngmrw2_ctrl_freq0 = 0x0
          freqchngmrw2_data_freq0 = 0x11
          freqchngmrw3_addr_freq0 = 0xc
          freqchngmrw3_ctrl_freq0 = 0x0
          freqchngmrw3_data_freq0 = 0x11
YesYes-
+ +
       amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
          freqchngmrw2_addr_freq1 = 0xe
          freqchngmrw2_ctrl_freq1 = 0x0
          freqchngmrw2_data_freq1 = 0x11
          freqchngmrw3_addr_freq1 = 0xc
          freqchngmrw3_ctrl_freq1 = 0x0
          freqchngmrw3_data_freq1 = 0x11
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

9. Setup registers for DQ calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 1 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0xd80d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
YesNo-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR + +
       amcx_dramcfg_pwrmngten(n) = 0x00000002
          AutoSR = 0x1
          DynPwrDnEn = 0x0 *read-only
          McPhyUpdDramClkOff = 0x0 *read-only
          PwrDnClkOff = 0x0 *read-only
          SRClkOff = 0x0 *read-only
          SRExitOpt = 0x0 *read-only
-Yes-
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
YesYes-
WrDqDqsSDLLCtrl + +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff00000c
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 800Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

10. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 1, 16, 12);
+
---
+ +
    ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000010
       DqIdleActive = 0x0
       DqsIdleActive = 0x1
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
The scale factors for Bin0 and Bin1 WR DQS/DQ skew have to to programmed to the correct values based on board charaterization. Fields are being set to 0 here, since exact board skews are not available now (04/01/14). + +
    ampsdq_ampsdqsdllctrl_WrtDQSDQSkewControl(n) = 0x06000000
       WrDqDqsIDTVTScaleEn = 0x1 *read-only
       WrDqDqsMDLLVTScaleEn = 0x1 *read-only
       WrtDQSDQScaleFactorF0 = 0x0
       WrtDQSDQScaleFactorF1 = 0x0
       WrtDQSDQScaleFactorPlusSel = 0x0
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
       ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000000
          DqIdleActive = 0x0
          DqsIdleActive = 0x0
-No-
Program FSP-WR to 0 and FSP-OP to 1 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x24020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xce010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 24, 12);
+
---
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 0 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Call custom API provided by PMGR for changing mcu_clk to 1200Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 24, 12);
+
---
+ +
       ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000010
          DqIdleActive = 0x0
          DqsIdleActive = 0x1
-No-
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    ampsca_ampscaiocfg_BISTRxMode(n) = 0x00000000
       BISTRxMode = 0x0 *read-only
       BISTRxODT = 0x0
       BISTRxODTEn = 0x0 *read-only
---
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG, since all calibrations are done + +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-


DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00150004
          Rd0RunSDLLUpd = 0x0 *read-only
          Rd0RunSDLLUpdOverride = 0x0 *read-only
          Rd0RunSDLLUpdWrResult = 0x0 *read-only
          Rd0SDLLOvrVal = 0x15
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x0d010019
       FreqChngWaitThr = 0x1 *read-only
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0 *read-only
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10110000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbrparam(n) = 0x61616161
       RdCwfEarlyCyc_freq0 = 0x1
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x1
       RdCwfEarlyCyc_freq3 = 0x1
       RdRemEarlyCyc_freq0 = 0x6
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x6
       RdRemEarlyCyc_freq3 = 0x6
else if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00006100
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000061a5
          RdCwfEarlyCyc_freq0 = 0x5
          RdCwfEarlyCyc_freq1 = 0x1
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x6
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1 *read-only
       Mcc0AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc0DpPropQCfg = 0x0 *read-only
       Mcc0DpPropQCmd = 0x1 *read-only
       Mcc0DpPropQTrakEnbl = 0x0 *read-only
       Mcc0MsqQPropCfg = 0x0 *read-only
       Mcc0MsqQPropQCmd = 0x0 *read-only
       Mcc0MsqQPropTrakEnbl = 0x0 *read-only
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0 *read-only
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0 *read-only
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1 *read-only
       Mcc1AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc1DpPropQCfg = 0x0 *read-only
       Mcc1DpPropQCmd = 0x1 *read-only
       Mcc1DpPropQTrakEnbl = 0x0 *read-only
       Mcc1MsqQPropCfg = 0x0 *read-only
       Mcc1MsqQPropQCmd = 0x0 *read-only
       Mcc1MsqQPropTrakEnbl = 0x0 *read-only
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0 *read-only
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0 *read-only
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1 *read-only
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0 *read-only
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
disable dynamic power-down. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
---
disable dynamic power-down. + +
       amcx_dramcfg_pwrmngten(n) = 0x00000133
          AutoSR = 0x1
          DynPwrDnEn = 0x1
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
-No-
Revert auto self-refresh wait timer to guided value.

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngtparam_freq0(n) = 0x01800000
          BypsPwrDnDlyCyc_freq0 = 0x0 *read-only
          SelfRefTmrVal_freq0 = 0x180
---
Setting WqAgeOutVal to be 3/4 of SelfRefTmrVal, to flush writes in a reasonable time.

FPGA: Skip this step
+ +
       amcx_mcusch_psqwqctl1(n) = 0x01640120
          WqAgeOutVal_freq0 = 0x120
          WqAgeOutVal_freq1 = 0x164 *read-only
---
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000000ff
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
Yes--
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x01500150
       PreFreqChng2AllBankDly_f0 = 0x150
       PreFreqChng2AllBankDly_f1 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x01500150
       PreFreqChng2AllBankDly_f2 = 0x150
       PreFreqChng2AllBankDly_f3 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02a002a0
       PreFreqChng2FreqChngDly_f0 = 0x2a0
       PreFreqChng2FreqChngDly_f1 = 0x2a0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02a002a0
       PreFreqChng2FreqChngDly_f2 = 0x2a0
       PreFreqChng2FreqChngDly_f3 = 0x2a0
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly0 = 0x00900090
       Cal2PreFreqChngDly_f0 = 0x90
       Cal2PreFreqChngDly_f1 = 0x90
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly1 = 0x00900090
       Cal2PreFreqChngDly_f2 = 0x90
       Cal2PreFreqChngDly_f3 = 0x90
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly0 = 0x01200120
       FreqChng2PstCalDly_f0 = 0x120
       FreqChng2PstCalDly_f1 = 0x120
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly1 = 0x01200120
       FreqChng2PstCalDly_f2 = 0x120
       FreqChng2PstCalDly_f3 = 0x120
---
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6c0
          RdCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
Yes--
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x000493e0
          PerCal_FreqChngTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_VoltRampTimer = 0x000493e0
          VoltRampTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly0 = 0x00d800d8
          VoltRamp2AllBankDly_f0 = 0xd8
          VoltRamp2AllBankDly_f1 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly1 = 0x00d800d8
          VoltRamp2AllBankDly_f2 = 0xd8
          VoltRamp2AllBankDly_f3 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly0 = 0x00900090
          AllBank2PmgrAckDly_f0 = 0x90
          AllBank2PmgrAckDly_f1 = 0x90
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly1 = 0x00900090
          AllBank2PmgrAckDly_f2 = 0x90
          AllBank2PmgrAckDly_f3 = 0x90
Yes--
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa *read-only
       MCUBCGClkGateEn = 0x0 *read-only
       MCUBCGPwrGateEn = 0x0 *read-only
       PwrRstCyc = 0x5 *read-only
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0 *read-only
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dcs-specs/Maui_Init_B0_May_20_2015.html b/docs/dcs-specs/Maui_Init_B0_May_20_2015.html new file mode 100644 index 0000000..7820016 --- /dev/null +++ b/docs/dcs-specs/Maui_Init_B0_May_20_2015.html @@ -0,0 +1,2943 @@ + + + + + + +

AMC Initialization Sequence

+This file was created using the following files on: Wed May 20 11:51:00 2015
AMC Version: Major Release: Minor Release:
AMP Version: 3 Major Release: 1 Minor Release: 3
AMC UM Init sourced from: //depot/ip_lib/apple/amcc/b0.maui/amcc/tb/cfg/static/maqstb_cfg.pl#23
AMP UM Init sourced from: //depot/ip_lib/apple/amp/b0.maui/amp/tb/cfg/phy_helper_fxns.pl#11
+

Change Log

+ * ------------------------------------------------------------------
* Version:1 - Files Edited: all
* Initial fiji checkin
* ------------------------------------------------------------------
* Version:6 - thuang - Files Edited: mcu_helper_fxns.c#5 - mcu_helper_fxns.c#7 - mcu_helper_fxns.h#6 -
* Added Rama's change in pmgr_amc_clk_cfg
* ------------------------------------------------------------------
* Version:7 - thuang - Files Edited: mcu_helper_fxns.c#8 - mcu_helper_fxns.h#6 -
* Release init, specifically to deal with 1202MHz at bucket 0
* ------------------------------------------------------------------
* Version:8 - jayp - Files Edited: mcu_helper_fxns.c#8 - mcu_helper_fxns.h#6 -
* release latest init to match AMCX release
* ------------------------------------------------------------------
* Version:9 - jayp - Files Edited: mcu_helper_fxns.c#9 - mcu_helper_fxns.h#7 -
* update to new dcsh/v.hspds that now points to the real amph.spds
* ------------------------------------------------------------------
* Version:10 - jayp - Files Edited: mcu_helper_fxns.c#10 - mcu_helper_fxns.h#8 -
* updating to preFinal releases of amp, amph, and amcx
* ------------------------------------------------------------------
* Version:11 - thuang - Files Edited: mcu_helper_fxns.c#11 - mcu_helper_fxns.h#9 -
* Init update
* ------------------------------------------------------------------
* Version:12 - jayp - Files Edited: mcu_helper_fxns.c#11 - mcu_helper_fxns.h#9 -
* moving to new amp pointer
* ------------------------------------------------------------------
* Version:13 - cpolapra - Files Edited: maqstb_cfg.pl#72 - calibration_fxns.pl#8 - mcu_helper_fxns.c#12 - mcu_helper_fxns.h#10 -
* Updated chip level config files for calibration at both Bucket 0 & Bucket 1
* ------------------------------------------------------------------
* Version:14 - jayp - Files Edited: mcu_helper_fxns.c#13 - mcu_helper_fxns.h#12 -
* update to init code for latest amcx and amp releases
* ------------------------------------------------------------------
* Version:15 - jayp - Files Edited: gen_mcu_init.pl#6 - mcu_helper_fxns.c#15 - mcu_helper_fxns.h#14 -
* moving to latest amph, amcx, and amp pointers
* ------------------------------------------------------------------
* Version:16 - allin - Files Edited: maqs_gen_cfg_c.pl#12 - maqstb_cfg.pl#123 - mem_tparams.pl#27 - phy_helper_fxns.pl#53 - move_generated_files.pl#4 - mcu_helper_fxns.c#18 - mcu_helper_fxns.h#16 -
* Fixes to MRR/MRW inclusion in resume boot
* ------------------------------------------------------------------
* Version:17 - jayp - Files Edited: maqstb_cfg.pl#125 - mcu_helper_fxns.c#20 - mcu_helper_fxns.h#18 -
* moving to latest amp and amcx releases
* ------------------------------------------------------------------
* Version:18 - jayp - Files Edited: maqs_gen_cfg_c.pl#14 - maqstb_cfg.pl#135 -
* releasing new amp to change global timer register naming so that chip and ams both work
* ------------------------------------------------------------------
* Version:19 - cpolapra - Files Edited: maqstb_cfg.pl#141 -
* Fixed tDIPW denali error
* ------------------------------------------------------------------
* Version:20 - cpolapra - Files Edited: maqstb_cfg.pl#148 -
* PMGR random fixes
* ------------------------------------------------------------------
* Version:21 - cpolapra - Files Edited: maqstb_cfg.pl#152 -
* Waiting 5us after frequency change in Step 3 of init sequence
* ------------------------------------------------------------------
* Version:22 - allin - Files Edited: maqs_gen_cfg.pl#12 - maqs_gen_cfg_html.pl#5 - maqstb_cfg.pl#153 - mcu_helper_fxns.c#23 -
* Changes for radar 16013438.
* ------------------------------------------------------------------
* Version:25 - thuang - Files Edited: maqs_gen_cfg_c.pl#18 - maqstb_cfg.pl#170 -
* Release latest amc init without SPLLCTRL programmings
* ------------------------------------------------------------------
* Version:26 - thuang - Files Edited: maqstb_cfg.pl#172 -
* Push out FPGA/Palladium refresh-related changes
* ------------------------------------------------------------------
* Version:27 - cpolapra - Files Edited: maqstb_cfg.pl#173 -
* Restoring post-calib registers for cortex.
* ------------------------------------------------------------------
* Version:28 - cpolapra - Files Edited: maqstb_cfg.pl#176 -
* Added DQS/Dq skew scale factor programming
* ------------------------------------------------------------------
* Version:29 - thuang - Files Edited: maqstb_cfg.pl#183 -
* Move VRCG enable from step7 to step4
* ------------------------------------------------------------------
* Version:30 - jayp - Files Edited: maqs_gen_cfg_c.pl#19 -
* new init for disablint LLT for A0 (16459536) and spllctrl renaming (16317738)
* ------------------------------------------------------------------
* Version:31 - jayp - Files Edited: maqs_gen_cfg_c.pl#22 -
* latest init sequence release + amcx release (tunables) + fix for spllctrl naming (16317738)
* ------------------------------------------------------------------
* Version:32 - jayp - Files Edited: maqstb_cfg.pl#186 -
* uncommenting spllctrl registers from maqstb_cfg.pl
* ------------------------------------------------------------------
* Version:33 - thuang - Files Edited: maqstb_cfg.pl#187 -
* Update AutoSR and DBI settings for FPGA to match ASIC
* ------------------------------------------------------------------
* Version:34 - cpolapra - Files Edited: gen_mcu_init.pl#9 -
* Fix for
* ------------------------------------------------------------------
* Version:35 - herb - Files Edited: maqstb_cfg.pl#199 -
* acmx v0.33.2
* amp v0.64.3
* ------------------------------------------------------------------
* Version:36 - thuang - Files Edited: maqstb_cfg.pl#202 -
* Always set MR13[4] for modified refresh
* ------------------------------------------------------------------
* Version:37 - thuang - Files Edited: maqstb_cfg.pl#210 -
* Update tMRWCyc and also push out init update
* ------------------------------------------------------------------
* Version:38 - cpolapra - Files Edited: maqs_gen_cfg.pl#21 - maqs_gen_cfg_c.pl#26 - maqs_gen_cfg_html.pl#7 - maqstb_cfg.pl#215 -
* Ported over SW calibration code and init sequence from Maui A0
* ------------------------------------------------------------------
* Version:39 - cpolapra - Files Edited: maqstb_cfg.pl#216 -
* Init sequence update for radars rdar://problem/18103117&18434646
* ------------------------------------------------------------------
* Version:40 - cpolapra - Files Edited: phy_helper_fxns.pl#96 -
* Fix for rdar://problem/18956147
* ------------------------------------------------------------------
* Version:41 - thuang - Files Edited: maqstb_cfg.pl#218 -
* Set HiTempRefRnkAgeOut_freq1 to 1 per rdar://problem/19067264
* ------------------------------------------------------------------
+

0. AMC Prolog

+

Program SPLL registers

+
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1
       MccStickyEn = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
Maximum Number of Powered Ways. + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000110
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x1 *read-only
---
Turn on the MCC + +
    amcc_mcccfg_MccGen = 0x00000195
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x1
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
Set Dynamic Way PowerGating + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000010
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x0
---
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050200
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050210
       ChSelHiBits = 0x5 *read-only
       ChSelTyp = 0x0 *read-only
       ChnlStartBit = 0x2 *read-only
       NumMcuChnl = 0x1
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5 *read-only
          ChSelTyp = 0x0 *read-only
          ChnlStartBit = 0x2 *read-only
          NumMcuChnl = 0x2
---
+ +
    spllctrl_SpllCtrl_ChargePump(n) = 0x00000068
       slvpll_cp_boost = 0x0
       slvpll_cp_i_set = 0x3 *read-only
       slvpll_cp_lp = 0x0 *read-only
       slvpll_cp_md = 0x0 *read-only
       slvpll_cp_pd = 0x0 *read-only
       slvpll_cp_r_set = 0x8 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000076
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x6 *read-only
---
+ +
    spllctrl_SpllCtrl_VCO(n) = 0x00000078
       slvpll_vco_buf_pd = 0x0 *read-only
       slvpll_vco_cap = 0x1 *read-only
       slvpll_vco_kvco = 0x3
       slvpll_vco_pd = 0x0 *read-only
       slvpll_vco_rv2i = 0x8
---
+ +
    spllctrl_SpllCtrl_LDO(n) = 0x00000004
       slvpll_bg_start_sel = 0x0 *read-only
       slvpll_reg_pd = 0x0 *read-only
       slvpll_vreg_adj = 0x4
---
+ +
    spllctrl_SpllCtrl_SPLLPwrDnCfg(n) = 0x00000011
       bypass_en_stby_pd = 0x1
       spll_fast_pd_exit = 0x0 *read-only
       spll_mode_dcs_pwrdn = 0x1 *read-only
       use_idle_for_pd = 0x0 *read-only
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 99Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
Call custom API provided in mcu_helper_fxns.c for setting PLL3 frequency to 99Mhz. This call is only applicable to Cold boot.

FPGA: Skip this step

+
---
+

1. AMC Initial Configuration

+

Perform the proper configurations of the AMC. Note that all the timing parameters should be programmed with respect to the normal clock, not the slow boot clock.

+ + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+

Setting up MCU registers and FSP for Freq change

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcx_dramcfg_freqchngctl0_freq0(n) = 0x18cd104d
       freqchngmrw0_addr_freq0 = 0xd
       freqchngmrw0_ctrl_freq0 = 0x1
       freqchngmrw0_data_freq0 = 0x10
       freqchngmrw1_addr_freq0 = 0xd
       freqchngmrw1_ctrl_freq0 = 0x3
       freqchngmrw1_data_freq0 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq0(n) = 0x110c110e
       freqchngmrw2_addr_freq0 = 0xe
       freqchngmrw2_ctrl_freq0 = 0x0
       freqchngmrw2_data_freq0 = 0x11
       freqchngmrw3_addr_freq0 = 0xc
       freqchngmrw3_ctrl_freq0 = 0x0
       freqchngmrw3_data_freq0 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303000b
       freqchngmrw4_addr_freq0 = 0xb
       freqchngmrw4_ctrl_freq0 = 0x0
       freqchngmrw4_data_freq0 = 0x0
       freqchngmrw5_addr_freq0 = 0x3
       freqchngmrw5_ctrl_freq0 = 0x0
       freqchngmrw5_data_freq0 = 0xb3
else
       amcx_dramcfg_freqchngctl2_freq0(n) = 0xb303440b
          freqchngmrw4_addr_freq0 = 0xb
          freqchngmrw4_ctrl_freq0 = 0x0
          freqchngmrw4_data_freq0 = 0x44
          freqchngmrw5_addr_freq0 = 0x3
          freqchngmrw5_ctrl_freq0 = 0x0
          freqchngmrw5_data_freq0 = 0xb3
---
+ +
    amcx_dramcfg_freqchngctl3_freq0(n) = 0xce012402
       freqchngmrw6_addr_freq0 = 0x2
       freqchngmrw6_ctrl_freq0 = 0x0
       freqchngmrw6_data_freq0 = 0x24
       freqchngmrw7_addr_freq0 = 0x1
       freqchngmrw7_ctrl_freq0 = 0x0
       freqchngmrw7_data_freq0 = 0xce
---
+ +
    amcx_dramcfg_freqchngctl4_freq0(n) = 0x00000416
       freqchngmrw8_addr_freq0 = 0x16
       freqchngmrw8_ctrl_freq0 = 0x0
       freqchngmrw8_data_freq0 = 0x4
       freqchngmrw9_addr_freq0 = 0x0 *read-only
       freqchngmrw9_ctrl_freq0 = 0x0 *read-only
       freqchngmrw9_data_freq0 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq0(n) = 0x000c1108
       freqchngclkofflat_freq0 = 0x8
       freqchngclkonlat_freq0 = 0x11
       freqchngsocupdlat_freq0 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq1(n) = 0x18cd104d
       freqchngmrw0_addr_freq1 = 0xd
       freqchngmrw0_ctrl_freq1 = 0x1
       freqchngmrw0_data_freq1 = 0x10
       freqchngmrw1_addr_freq1 = 0xd
       freqchngmrw1_ctrl_freq1 = 0x3
       freqchngmrw1_data_freq1 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
       freqchngmrw2_addr_freq1 = 0xe
       freqchngmrw2_ctrl_freq1 = 0x0
       freqchngmrw2_data_freq1 = 0x11
       freqchngmrw3_addr_freq1 = 0xc
       freqchngmrw3_ctrl_freq1 = 0x0
       freqchngmrw3_data_freq1 = 0x11
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303000b
       freqchngmrw4_addr_freq1 = 0xb
       freqchngmrw4_ctrl_freq1 = 0x0
       freqchngmrw4_data_freq1 = 0x0
       freqchngmrw5_addr_freq1 = 0x3
       freqchngmrw5_ctrl_freq1 = 0x0
       freqchngmrw5_data_freq1 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq1(n) = 0xf303020b
          freqchngmrw4_addr_freq1 = 0xb
          freqchngmrw4_ctrl_freq1 = 0x0
          freqchngmrw4_data_freq1 = 0x2
          freqchngmrw5_addr_freq1 = 0x3
          freqchngmrw5_ctrl_freq1 = 0x0
          freqchngmrw5_data_freq1 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq1(n) = 0xae015202
       freqchngmrw6_addr_freq1 = 0x2
       freqchngmrw6_ctrl_freq1 = 0x0
       freqchngmrw6_data_freq1 = 0x52
       freqchngmrw7_addr_freq1 = 0x1
       freqchngmrw7_ctrl_freq1 = 0x0
       freqchngmrw7_data_freq1 = 0xae
---
+ +
    amcx_dramcfg_freqchngctl4_freq1(n) = 0x00000416
       freqchngmrw8_addr_freq1 = 0x16
       freqchngmrw8_ctrl_freq1 = 0x0
       freqchngmrw8_data_freq1 = 0x4
       freqchngmrw9_addr_freq1 = 0x0 *read-only
       freqchngmrw9_ctrl_freq1 = 0x0 *read-only
       freqchngmrw9_data_freq1 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq1(n) = 0x000c1108
       freqchngclkofflat_freq1 = 0x8
       freqchngclkonlat_freq1 = 0x11
       freqchngsocupdlat_freq1 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq2(n) = 0x18cd104d
       freqchngmrw0_addr_freq2 = 0xd
       freqchngmrw0_ctrl_freq2 = 0x1
       freqchngmrw0_data_freq2 = 0x10
       freqchngmrw1_addr_freq2 = 0xd
       freqchngmrw1_ctrl_freq2 = 0x3
       freqchngmrw1_data_freq2 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq2(n) = 0x590c590e
       freqchngmrw2_addr_freq2 = 0xe
       freqchngmrw2_ctrl_freq2 = 0x0
       freqchngmrw2_data_freq2 = 0x59
       freqchngmrw3_addr_freq2 = 0xc
       freqchngmrw3_ctrl_freq2 = 0x0
       freqchngmrw3_data_freq2 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
       freqchngmrw4_addr_freq2 = 0xb
       freqchngmrw4_ctrl_freq2 = 0x0
       freqchngmrw4_data_freq2 = 0x0
       freqchngmrw5_addr_freq2 = 0x3
       freqchngmrw5_ctrl_freq2 = 0x0
       freqchngmrw5_data_freq2 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq2(n) = 0xf303000b
          freqchngmrw4_addr_freq2 = 0xb
          freqchngmrw4_ctrl_freq2 = 0x0
          freqchngmrw4_data_freq2 = 0x0
          freqchngmrw5_addr_freq2 = 0x3
          freqchngmrw5_ctrl_freq2 = 0x0
          freqchngmrw5_data_freq2 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq2(n) = 0x8e010002
       freqchngmrw6_addr_freq2 = 0x2
       freqchngmrw6_ctrl_freq2 = 0x0
       freqchngmrw6_data_freq2 = 0x0
       freqchngmrw7_addr_freq2 = 0x1
       freqchngmrw7_ctrl_freq2 = 0x0
       freqchngmrw7_data_freq2 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq2(n) = 0x00000016
       freqchngmrw8_addr_freq2 = 0x16
       freqchngmrw8_ctrl_freq2 = 0x0
       freqchngmrw8_data_freq2 = 0x0
       freqchngmrw9_addr_freq2 = 0x0 *read-only
       freqchngmrw9_ctrl_freq2 = 0x0 *read-only
       freqchngmrw9_data_freq2 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq2(n) = 0x000c1108
       freqchngclkofflat_freq2 = 0x8
       freqchngclkonlat_freq2 = 0x11
       freqchngsocupdlat_freq2 = 0xc
---
+ +
    amcx_dramcfg_freqchngctl0_freq3(n) = 0x18cd104d
       freqchngmrw0_addr_freq3 = 0xd
       freqchngmrw0_ctrl_freq3 = 0x1
       freqchngmrw0_data_freq3 = 0x10
       freqchngmrw1_addr_freq3 = 0xd
       freqchngmrw1_ctrl_freq3 = 0x3
       freqchngmrw1_data_freq3 = 0x18
---
+ +
    amcx_dramcfg_freqchngctl1_freq3(n) = 0x590c590e
       freqchngmrw2_addr_freq3 = 0xe
       freqchngmrw2_ctrl_freq3 = 0x0
       freqchngmrw2_data_freq3 = 0x59
       freqchngmrw3_addr_freq3 = 0xc
       freqchngmrw3_ctrl_freq3 = 0x0
       freqchngmrw3_data_freq3 = 0x59
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
       freqchngmrw4_addr_freq3 = 0xb
       freqchngmrw4_ctrl_freq3 = 0x0
       freqchngmrw4_data_freq3 = 0x0
       freqchngmrw5_addr_freq3 = 0x3
       freqchngmrw5_ctrl_freq3 = 0x0
       freqchngmrw5_data_freq3 = 0xf3
else
       amcx_dramcfg_freqchngctl2_freq3(n) = 0xf303000b
          freqchngmrw4_addr_freq3 = 0xb
          freqchngmrw4_ctrl_freq3 = 0x0
          freqchngmrw4_data_freq3 = 0x0
          freqchngmrw5_addr_freq3 = 0x3
          freqchngmrw5_ctrl_freq3 = 0x0
          freqchngmrw5_data_freq3 = 0xf3
---
+ +
    amcx_dramcfg_freqchngctl3_freq3(n) = 0x8e010002
       freqchngmrw6_addr_freq3 = 0x2
       freqchngmrw6_ctrl_freq3 = 0x0
       freqchngmrw6_data_freq3 = 0x0
       freqchngmrw7_addr_freq3 = 0x1
       freqchngmrw7_ctrl_freq3 = 0x0
       freqchngmrw7_data_freq3 = 0x8e
---
+ +
    amcx_dramcfg_freqchngctl4_freq3(n) = 0x00000016
       freqchngmrw8_addr_freq3 = 0x16
       freqchngmrw8_ctrl_freq3 = 0x0
       freqchngmrw8_data_freq3 = 0x0
       freqchngmrw9_addr_freq3 = 0x0 *read-only
       freqchngmrw9_ctrl_freq3 = 0x0 *read-only
       freqchngmrw9_data_freq3 = 0x0 *read-only
---
+ +
    amcx_dramcfg_freqchngtim_freq3(n) = 0x000c1108
       freqchngclkofflat_freq3 = 0x8
       freqchngclkonlat_freq3 = 0x11
       freqchngsocupdlat_freq3 = 0xc
---
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_rwcfg(n) = 0x000210ef
       CasAPEn = 0x1
       DBIRDEn_freq0 = 0x0
       DBIRDEn_freq1 = 0x1
       DBIRDEn_freq2 = 0x1
       DBIRDEn_freq3 = 0x1
       DBIWREn_freq0 = 0x1
       DBIWREn_freq1 = 0x1
       DBIWREn_freq2 = 0x1
       DBIWREn_freq3 = 0x1
       DBIWRType = 0x0
       tCCDMWCyc = 0x2
else
       amcx_dramcfg_rwcfg(n) = 0x000210ef
          CasAPEn = 0x1
          DBIRDEn_freq0 = 0x0
          DBIRDEn_freq1 = 0x1
          DBIRDEn_freq2 = 0x1
          DBIRDEn_freq3 = 0x1
          DBIWREn_freq0 = 0x1
          DBIWREn_freq1 = 0x1
          DBIWREn_freq2 = 0x1
          DBIWREn_freq3 = 0x1
          DBIWRType = 0x0
          tCCDMWCyc = 0x2
---
+ +
    ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
+ +
    ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017350
       DllInitUpdtDur = 0x7 *read-only
       DllUpdtDur = 0x3 *read-only
       DllUpdtMode = 0x1
       DllUpdtPhyUpdtTyp = 0x0 *read-only
       FreqChangeSDLLUpdDur = 0x50 *read-only
       SDLLUpdDur = 0x50 *read-only
---
Configure DRAM timing parameters for default frequencyset. Example here shows LPDDR4-2667 8Gb DRAM die. See Section 3.2.2.4 for other value.
Configure the PHY timing. These are determined by the design of the PHY and the interface between the PHY and AMC.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001030c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x3 *read-only
       tDQSCKMinCyc_freq0 = 0x0 *read-only
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00103306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3 *read-only
          tDQSCKMinCyc_freq0 = 0x0 *read-only
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001020c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x2 *read-only
       tDQSCKMinCyc_freq1 = 0x0 *read-only
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00102206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2 *read-only
          tDQSCKMinCyc_freq1 = 0x0 *read-only
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq0(n) = 0x00010c01
       PHYRdLat_freq0 = 0xc
       PHYtPhyWrlat_freq0 = 0x1
       PHYtRddataEn_freq0 = 0x1
else
       amcx_phytim_phyrdwrtim_freq0(n) = 0x00050c0a
          PHYRdLat_freq0 = 0xc
          PHYtPhyWrlat_freq0 = 0x5
          PHYtRddataEn_freq0 = 0xa
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq1(n) = 0x00010b01
       PHYRdLat_freq1 = 0xb
       PHYtPhyWrlat_freq1 = 0x1
       PHYtRddataEn_freq1 = 0x1
else
       amcx_phytim_phyrdwrtim_freq1(n) = 0x00050b06
          PHYRdLat_freq1 = 0xb
          PHYtPhyWrlat_freq1 = 0x5
          PHYtRddataEn_freq1 = 0x6
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
       PHYRdLat_freq2 = 0xb
       PHYtPhyWrlat_freq2 = 0x1
       PHYtRddataEn_freq2 = 0x1
else
       amcx_phytim_phyrdwrtim_freq2(n) = 0x00010b01
          PHYRdLat_freq2 = 0xb
          PHYtPhyWrlat_freq2 = 0x1
          PHYtRddataEn_freq2 = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
       PHYRdLat_freq3 = 0x9
       PHYtPhyWrlat_freq3 = 0x1
       PHYtRddataEn_freq3 = 0x1
else
       amcx_phytim_phyrdwrtim_freq3(n) = 0x00010901
          PHYRdLat_freq3 = 0x9
          PHYtPhyWrlat_freq3 = 0x1
          PHYtRddataEn_freq3 = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq0(n) = 0x42110408
       tRASCyc_freq0 = 0x11
       tRCDCyc_freq0 = 0x8
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x8
       tWTRCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq0(n) = 0x40c20402
       tRASCyc_freq0 = 0x2
       tRCDCyc_freq0 = 0x2
       tRTPCyc_freq0 = 0x4
       tWRCyc_freq0 = 0x3
       tWTRCyc_freq0 = 0x4
else
       amcx_dramtim_caspch_freq0(n) = 0x531a060b
          tRASCyc_freq0 = 0x1a
          tRCDCyc_freq0 = 0xb
          tRTPCyc_freq0 = 0x5
          tWRCyc_freq0 = 0xc
          tWTRCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq0(n) = 0x10040908
       tFAWCyc_freq0 = 0x10
       tRPCyc_freq0 = 0x8
       tRPabCyc_freq0 = 0x9
       tRRDCyc_freq0 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq0(n) = 0x01020202
       tFAWCyc_freq0 = 0x1
       tRPCyc_freq0 = 0x2
       tRPabCyc_freq0 = 0x2
       tRRDCyc_freq0 = 0x2
else
       amcx_dramtim_act_freq0(n) = 0x18060d0b
          tFAWCyc_freq0 = 0x18
          tRPCyc_freq0 = 0xb
          tRPabCyc_freq0 = 0xd
          tRRDCyc_freq0 = 0x6
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010078
       tRFCBaseCyc_freq0 = 0x78 *read-only
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c0078
          tRFCBaseCyc_freq0 = 0x78 *read-only
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq0(n) = 0x50057012
       tFCCyc_freq0 = 0x50
       tXSRCyc_freq0 = 0x57
       tZQCalCyc_freq0 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq0(n) = 0x28002012
       tFCCyc_freq0 = 0x28
       tXSRCyc_freq0 = 0x2
       tZQCalCyc_freq0 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq0(n) = 0x78071012
          tFCCyc_freq0 = 0x78
          tXSRCyc_freq0 = 0x71
          tZQCalCyc_freq0 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_modereg(n) = 0x0e0a9084
       tMRRCyc = 0x4
       tMRRICyc = 0x8
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0xe
else if (platform == FPGA)
    amcx_dramtim_modereg(n) = 0x060a9024
       tMRRCyc = 0x4
       tMRRICyc = 0x2
       tMRWCyc = 0x9
       tVRCGOFFCyc = 0xa
       tZQLatCyc = 0x6
else
       amcx_dramtim_modereg(n) = 0x140a90b4
          tMRRCyc = 0x4
          tMRRICyc = 0xb
          tMRWCyc = 0x9
          tVRCGOFFCyc = 0xa
          tZQLatCyc = 0x14
---
Configure DRAM timing parameters for alternative frequency points. For the dynamic frequency change support, all frequency sets should be programmed. See Section 3.2.2.3 for details. The actual values should correspond to the desired frequency points and the actual device specifications.
(N=1/2/3)
*since mcu_clk freq1 = 200MHz and per-bank refresh is not enabled,
mcusch.mifcassch_freq1. HiTempRefRnkAgeOut_freq1 =0x0
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq1(n) = 0x42110408
       tRASCyc_freq1 = 0x11
       tRCDCyc_freq1 = 0x8
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x8
       tWTRCyc_freq1 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq1(n) = 0x40c20402
       tRASCyc_freq1 = 0x2
       tRCDCyc_freq1 = 0x2
       tRTPCyc_freq1 = 0x4
       tWRCyc_freq1 = 0x3
       tWTRCyc_freq1 = 0x4
else
       amcx_dramtim_caspch_freq1(n) = 0x42110408
          tRASCyc_freq1 = 0x11
          tRCDCyc_freq1 = 0x8
          tRTPCyc_freq1 = 0x4
          tWRCyc_freq1 = 0x8
          tWTRCyc_freq1 = 0x4
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_act_freq1(n) = 0x01020202
       tFAWCyc_freq1 = 0x1
       tRPCyc_freq1 = 0x2
       tRPabCyc_freq1 = 0x2
       tRRDCyc_freq1 = 0x2
else
       amcx_dramtim_act_freq1(n) = 0x10040908
          tFAWCyc_freq1 = 0x10
          tRPCyc_freq1 = 0x8
          tRPabCyc_freq1 = 0x9
          tRRDCyc_freq1 = 0x4
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480050. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480050.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010050
       tRFCBaseCyc_freq1 = 0x50 *read-only
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480050
          tRFCBaseCyc_freq1 = 0x50 *read-only
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq1(n) = 0x50057012
       tFCCyc_freq1 = 0x50
       tXSRCyc_freq1 = 0x57
       tZQCalCyc_freq1 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq1(n) = 0x28002012
       tFCCyc_freq1 = 0x28
       tXSRCyc_freq1 = 0x2
       tZQCalCyc_freq1 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq1(n) = 0x5004b012
          tFCCyc_freq1 = 0x50
          tXSRCyc_freq1 = 0x4b
          tZQCalCyc_freq1 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq2(n) = 0x42110408
       tRASCyc_freq2 = 0x11
       tRCDCyc_freq2 = 0x8
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x8
       tWTRCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq2(n) = 0x40c20402
       tRASCyc_freq2 = 0x2
       tRCDCyc_freq2 = 0x2
       tRTPCyc_freq2 = 0x4
       tWRCyc_freq2 = 0x3
       tWTRCyc_freq2 = 0x4
else
       amcx_dramtim_caspch_freq2(n) = 0x40c50402
          tRASCyc_freq2 = 0x5
          tRCDCyc_freq2 = 0x2
          tRTPCyc_freq2 = 0x4
          tWRCyc_freq2 = 0x3
          tWTRCyc_freq2 = 0x4
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq2(n) = 0x10040908
       tFAWCyc_freq2 = 0x10
       tRPCyc_freq2 = 0x8
       tRPabCyc_freq2 = 0x9
       tRRDCyc_freq2 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq2(n) = 0x01020202
       tFAWCyc_freq2 = 0x1
       tRPCyc_freq2 = 0x2
       tRPabCyc_freq2 = 0x2
       tRRDCyc_freq2 = 0x2
else
       amcx_dramtim_act_freq2(n) = 0x04020302
          tFAWCyc_freq2 = 0x4
          tRPCyc_freq2 = 0x2
          tRPabCyc_freq2 = 0x3
          tRRDCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010014
       tRFCBaseCyc_freq2 = 0x14 *read-only
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120014
          tRFCBaseCyc_freq2 = 0x14 *read-only
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq2(n) = 0x50057012
       tFCCyc_freq2 = 0x50
       tXSRCyc_freq2 = 0x57
       tZQCalCyc_freq2 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq2(n) = 0x28002012
       tFCCyc_freq2 = 0x28
       tXSRCyc_freq2 = 0x2
       tZQCalCyc_freq2 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq2(n) = 0x28013012
          tFCCyc_freq2 = 0x28
          tXSRCyc_freq2 = 0x13
          tZQCalCyc_freq2 = 0x12 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_caspch_freq3(n) = 0x42110408
       tRASCyc_freq3 = 0x11
       tRCDCyc_freq3 = 0x8
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x8
       tWTRCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_caspch_freq3(n) = 0x40c20402
       tRASCyc_freq3 = 0x2
       tRCDCyc_freq3 = 0x2
       tRTPCyc_freq3 = 0x4
       tWRCyc_freq3 = 0x3
       tWTRCyc_freq3 = 0x4
else
       amcx_dramtim_caspch_freq3(n) = 0x40c20402
          tRASCyc_freq3 = 0x2
          tRCDCyc_freq3 = 0x2
          tRTPCyc_freq3 = 0x4
          tWRCyc_freq3 = 0x3
          tWTRCyc_freq3 = 0x4
---
Process act_freq3 for all platforms + + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_act_freq3(n) = 0x10040b0a
       tFAWCyc_freq3 = 0x10
       tRPCyc_freq3 = 0xa
       tRPabCyc_freq3 = 0xb
       tRRDCyc_freq3 = 0x4
else if (platform == FPGA)
    amcx_dramtim_act_freq3(n) = 0x01020404
       tFAWCyc_freq3 = 0x1
       tRPCyc_freq3 = 0x4
       tRPabCyc_freq3 = 0x4
       tRRDCyc_freq3 = 0x2
else
       amcx_dramtim_act_freq3(n) = 0x02020404
          tFAWCyc_freq3 = 0x2
          tRPCyc_freq3 = 0x4
          tRPabCyc_freq3 = 0x4
          tRRDCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010005
       tRFCBaseCyc_freq3 = 0x5 *read-only
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5 *read-only
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_selfref_freq3(n) = 0x50057012
       tFCCyc_freq3 = 0x50
       tXSRCyc_freq3 = 0x57
       tZQCalCyc_freq3 = 0x12 *read-only
else if (platform == FPGA)
    amcx_dramtim_selfref_freq3(n) = 0x28002012
       tFCCyc_freq3 = 0x28
       tXSRCyc_freq3 = 0x2
       tZQCalCyc_freq3 = 0x12 *read-only
else
       amcx_dramtim_selfref_freq3(n) = 0x28006012
          tFCCyc_freq3 = 0x28
          tXSRCyc_freq3 = 0x6
          tZQCalCyc_freq3 = 0x12 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00150013
       tREFBWtRFCcnt = 0x15 *read-only
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0015005d
          tREFBWtRFCcnt = 0x15 *read-only
          tREFICyc = 0x5d
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_pdn(n) = 0x31263263
       tCKECyc = 0x3
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x6
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x3
       tCKb4CKECyc = 0x1
       tXPCyc = 0x3
else if (platform == FPGA)
    amcx_dramtim_pdn(n) = 0x21262222
       tCKECyc = 0x2
       tCKEPDECyc = 0x1 *read-only
       tCKESRCyc = 0x2
       tCKEafSRCyc = 0x2
       tCKEb4SRCyc = 0x6
       tCKafCKECyc = 0x2
       tCKb4CKECyc = 0x1
       tXPCyc = 0x2
else
       amcx_dramtim_pdn(n) = 0x62265295
          tCKECyc = 0x5
          tCKEPDECyc = 0x1 *read-only
          tCKESRCyc = 0x9
          tCKEafSRCyc = 0x2
          tCKEb4SRCyc = 0x6
          tCKafCKECyc = 0x6
          tCKb4CKECyc = 0x2
          tXPCyc = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq0(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq0 = 0x3
       tRASDrtCyc_freq0 = 0x12
       tRCDDrtCyc_freq0 = 0x8
       tRPDrtCyc_freq0 = 0x8
       tRPabDrtCyc_freq0 = 0xa
       tRRDDrtCyc_freq0 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq0(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq0 = 0x1
       tRASDrtCyc_freq0 = 0x2
       tRCDDrtCyc_freq0 = 0x2
       tRPDrtCyc_freq0 = 0x2
       tRPabDrtCyc_freq0 = 0x2
       tRRDDrtCyc_freq0 = 0x2
else
       amcx_dramtim_derate_freq0(n) = 0x38c486cc
          tDQSCKMaxDrtCyc_freq0 = 0x4
          tRASDrtCyc_freq0 = 0x1b
          tRCDDrtCyc_freq0 = 0xc
          tRPDrtCyc_freq0 = 0xc
          tRPabDrtCyc_freq0 = 0xe
          tRRDDrtCyc_freq0 = 0x8
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq1(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq1 = 0x3
       tRASDrtCyc_freq1 = 0x12
       tRCDDrtCyc_freq1 = 0x8
       tRPDrtCyc_freq1 = 0x8
       tRPabDrtCyc_freq1 = 0xa
       tRRDDrtCyc_freq1 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq1(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq1 = 0x1
       tRASDrtCyc_freq1 = 0x2
       tRCDDrtCyc_freq1 = 0x2
       tRPDrtCyc_freq1 = 0x2
       tRPabDrtCyc_freq1 = 0x2
       tRRDDrtCyc_freq1 = 0x2
else
       amcx_dramtim_derate_freq1(n) = 0x28835488
          tDQSCKMaxDrtCyc_freq1 = 0x3
          tRASDrtCyc_freq1 = 0x12
          tRCDDrtCyc_freq1 = 0x8
          tRPDrtCyc_freq1 = 0x8
          tRPabDrtCyc_freq1 = 0xa
          tRRDDrtCyc_freq1 = 0x5
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq2(n) = 0x28835488
       tDQSCKMaxDrtCyc_freq2 = 0x3
       tRASDrtCyc_freq2 = 0x12
       tRCDDrtCyc_freq2 = 0x8
       tRPDrtCyc_freq2 = 0x8
       tRPabDrtCyc_freq2 = 0xa
       tRRDDrtCyc_freq2 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq2(n) = 0x08212082
       tDQSCKMaxDrtCyc_freq2 = 0x1
       tRASDrtCyc_freq2 = 0x2
       tRCDDrtCyc_freq2 = 0x2
       tRPDrtCyc_freq2 = 0x2
       tRPabDrtCyc_freq2 = 0x2
       tRRDDrtCyc_freq2 = 0x2
else
       amcx_dramtim_derate_freq2(n) = 0x0c212142
          tDQSCKMaxDrtCyc_freq2 = 0x1
          tRASDrtCyc_freq2 = 0x5
          tRCDDrtCyc_freq2 = 0x2
          tRPDrtCyc_freq2 = 0x2
          tRPabDrtCyc_freq2 = 0x3
          tRRDDrtCyc_freq2 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_derate_freq3(n) = 0x30a35488
       tDQSCKMaxDrtCyc_freq3 = 0x3
       tRASDrtCyc_freq3 = 0x12
       tRCDDrtCyc_freq3 = 0x8
       tRPDrtCyc_freq3 = 0xa
       tRPabDrtCyc_freq3 = 0xc
       tRRDDrtCyc_freq3 = 0x5
else if (platform == FPGA)
    amcx_dramtim_derate_freq3(n) = 0x10412082
       tDQSCKMaxDrtCyc_freq3 = 0x1
       tRASDrtCyc_freq3 = 0x2
       tRCDDrtCyc_freq3 = 0x2
       tRPDrtCyc_freq3 = 0x4
       tRPabDrtCyc_freq3 = 0x4
       tRRDDrtCyc_freq3 = 0x2
else
       amcx_dramtim_derate_freq3(n) = 0x10412082
          tDQSCKMaxDrtCyc_freq3 = 0x1
          tRASDrtCyc_freq3 = 0x2
          tRCDDrtCyc_freq3 = 0x2
          tRPDrtCyc_freq3 = 0x4
          tRPabDrtCyc_freq3 = 0x4
          tRRDDrtCyc_freq3 = 0x2
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq0(n) = 0x00112306
       DRAMRL_freq0 = 0xc
       DRAMWL_freq0 = 0x6
       tDQSCKMaxCyc_freq0 = 0x2
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq0(n) = 0x001110c2
       DRAMRL_freq0 = 0x3
       DRAMWL_freq0 = 0x2
       tDQSCKMaxCyc_freq0 = 0x1
       tDQSCKMinCyc_freq0 = 0x1
       tDQSSMaxCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_lat_freq0(n) = 0x00113306
          DRAMRL_freq0 = 0xc
          DRAMWL_freq0 = 0x6
          tDQSCKMaxCyc_freq0 = 0x3
          tDQSCKMinCyc_freq0 = 0x1
          tDQSSMaxCyc_freq0 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq1(n) = 0x00112206
       DRAMRL_freq1 = 0x8
       DRAMWL_freq1 = 0x6
       tDQSCKMaxCyc_freq1 = 0x2
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq1(n) = 0x001110c2
       DRAMRL_freq1 = 0x3
       DRAMWL_freq1 = 0x2
       tDQSCKMaxCyc_freq1 = 0x1
       tDQSCKMinCyc_freq1 = 0x1
       tDQSSMaxCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_lat_freq1(n) = 0x00112206
          DRAMRL_freq1 = 0x8
          DRAMWL_freq1 = 0x6
          tDQSCKMaxCyc_freq1 = 0x2
          tDQSCKMinCyc_freq1 = 0x1
          tDQSSMaxCyc_freq1 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq2(n) = 0x001120c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x2
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq2(n) = 0x001110c2
       DRAMRL_freq2 = 0x3
       DRAMWL_freq2 = 0x2
       tDQSCKMaxCyc_freq2 = 0x1
       tDQSCKMinCyc_freq2 = 0x1
       tDQSSMaxCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_lat_freq2(n) = 0x001110c2
          DRAMRL_freq2 = 0x3
          DRAMWL_freq2 = 0x2
          tDQSCKMaxCyc_freq2 = 0x1
          tDQSCKMinCyc_freq2 = 0x1
          tDQSSMaxCyc_freq2 = 0x1 *read-only
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_lat_freq3(n) = 0x001120c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x2
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else if (platform == FPGA)
    amcx_dramtim_lat_freq3(n) = 0x001110c2
       DRAMRL_freq3 = 0x3
       DRAMWL_freq3 = 0x2
       tDQSCKMaxCyc_freq3 = 0x1
       tDQSCKMinCyc_freq3 = 0x1
       tDQSSMaxCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_lat_freq3(n) = 0x001110c2
          DRAMRL_freq3 = 0x3
          DRAMWL_freq3 = 0x2
          tDQSCKMaxCyc_freq3 = 0x1
          tDQSCKMinCyc_freq3 = 0x1
          tDQSSMaxCyc_freq3 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq0(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2rTatDeadCyc_freq0 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       R2wTatDeadCyc_freq0 = 0x2
       W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
       W2wTatDeadCyc_freq0 = 0x1 *read-only
else
       amcx_dramtim_tat_freq0(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2rTatDeadCyc_freq0 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          R2wTatDeadCyc_freq0 = 0x3
          W2rRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq0 = 0x2 *read-only
          W2wTatDeadCyc_freq0 = 0x1 *read-only
---
+ + + + +
if (platform == FPGA)
    amcx_dramtim_tat_freq1(n) = 0x01212222
       R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2rTatDeadCyc_freq1 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       R2wTatDeadCyc_freq1 = 0x2
       W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
       W2wTatDeadCyc_freq1 = 0x1 *read-only
else
       amcx_dramtim_tat_freq1(n) = 0x01312222
          R2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2rTatDeadCyc_freq1 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          R2wTatDeadCyc_freq1 = 0x3
          W2rRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq1 = 0x2 *read-only
          W2wTatDeadCyc_freq1 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq2(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2rTatDeadCyc_freq2 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       R2wTatDeadCyc_freq2 = 0x3
       W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
       W2wTatDeadCyc_freq2 = 0x1 *read-only
else
       amcx_dramtim_tat_freq2(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2rTatDeadCyc_freq2 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          R2wTatDeadCyc_freq2 = 0x2
          W2rRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq2 = 0x2 *read-only
          W2wTatDeadCyc_freq2 = 0x1 *read-only
---
+ + + + +
if (platform == PALLADIUM)
    amcx_dramtim_tat_freq3(n) = 0x01312222
       R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2rTatDeadCyc_freq3 = 0x1 *read-only
       R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       R2wTatDeadCyc_freq3 = 0x3
       W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
       W2wTatDeadCyc_freq3 = 0x1 *read-only
else
       amcx_dramtim_tat_freq3(n) = 0x01212222
          R2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2rTatDeadCyc_freq3 = 0x1 *read-only
          R2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          R2wTatDeadCyc_freq3 = 0x2
          W2rRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wRnkMissTatDeadCyc_freq3 = 0x2 *read-only
          W2wTatDeadCyc_freq3 = 0x1 *read-only
---
+ +
    amcx_dramcfg_rnkcfg(n) = 0x00006061
       Rnk0Odts = 0x6 *read-only
       Rnk0Valid = 0x1
       Rnk1Odts = 0x6 *read-only
       Rnk1Valid = 0x0 *read-only
---
+ +
    amcx_mifqctrl_mifqmaxctrl_freq0(n) = 0x00000100
       HiTempMifQMax_freq0 = 0x0 *read-only
       MifQMaxAlways = 0x1
---
+ + + + +
if (platform == FPGA)
    amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000003
       HiTempMifQMax_freq3 = 0x3
else
       amcx_mifqctrl_mifqmaxctrl_freq3(n) = 0x00000001
          HiTempMifQMax_freq3 = 0x1
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000000
       AutoSR = 0x0
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x0
       SRClkOff = 0x0
       SRExitOpt = 0x0 *read-only
---
Turn off optional power- savingfeatures. This includes dynamic power down, auto self-refresh entry, and clock stopping. + +
    amcx_dramcfg_odtszqc(n) = 0x00002000
       DerateParamSRExit = 0x1
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0 *read-only
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
---
Turn off transaction scheduling for non- initialization commands + +
    amcx_amcgen_amcctrl(n) = 0x00000002
       McuEn = 0x0 *read-only
       SchEn = 0x1
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3 *read-only
       PhyInitStartCyc = 0x0 *read-only
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
Program AMC to
- wait tXP+2tCK after actual clock changes before valid command
- wait 2 cycles after all timing parameter are satisfied before actual clock change
- wait indefinitely for AMP to complete handshake.
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030000
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x0 *read-only
---
+

2. AMP Initial Configurations

+

Perform the proper configurations of the AMP. There are two separate AMP register blocks; the code below must be repeated on both AMP0 and AMP1. (N=0..1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Assert AMP enable + +
    ampsca_ampscagen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
Assert AMP enable + +
    ampsdq_ampsdqgen_ampen(n) = 0x00000001
       AmpEn = 0x1
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f0(n) = 0x000b316b
       CaDsPd_f0 = 0xb
       Ck0DsPd_f0 = 0xb
       Ck1DsPd_f0 = 0xc *read-only
       CsDsPd_f0 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f1(n) = 0x000b216b
       CaDsPd_f1 = 0xb
       Ck0DsPd_f1 = 0xb
       Ck1DsPd_f1 = 0x8 *read-only
       CsDsPd_f1 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f2(n) = 0x000b3d6b
       CaDsPd_f2 = 0xb
       Ck0DsPd_f2 = 0xb
       Ck1DsPd_f2 = 0xf *read-only
       CsDsPd_f2 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqdspd_f3(n) = 0x000b3d6b
       CaDsPd_f3 = 0xb
       Ck0DsPd_f3 = 0xb
       Ck1DsPd_f3 = 0xf *read-only
       CsDsPd_f3 = 0xb
---
+ +
    ampsca_ampscaiocfg_nondqds_f1(n) = 0x00000000
       CaDs_f1 = 0x0
       Ck0Ds_f1 = 0x0
       Ck1Ds_f1 = 0x0
       CsDs_f1 = 0x0
---
+ +
    ampsca_ampscaiocfg_nondqds_f2(n) = 0x00083d08
       CaDs_f2 = 0x8
       Ck0Ds_f2 = 0x8
       Ck1Ds_f2 = 0xf *read-only
       CsDs_f2 = 0x8
---
+ +
    ampsca_ampscaiocfg_nondqds_f3(n) = 0x00083d08
       CaDs_f3 = 0x8
       Ck0Ds_f3 = 0x8
       Ck1Ds_f3 = 0xf *read-only
       CsDs_f3 = 0x8
---
+ +
    ampsca_ampscaiocfg_CaCkCsWkDs(n) = 0x000000db
       CaWkDs = 0x3
       CkWkDs = 0x3
       CsWkDs = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f0(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f1(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f2(n) = 0x00000003
       VRefSel = 0x3
---
+ +
    ampsca_ampscaodt_VRef_f3(n) = 0x00000003
       VRefSel = 0x3
---
ODTEnable_f0 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f0(n) = 0x00000001
          ODTEnable = 0x1
---
ODTEnable_f1 + + + + + + +
if (platform == PALLADIUM)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else if (platform == FPGA)
    ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
       ODTEnable = 0x0
else
       ampsca_ampscaodt_ODTEnable_f1(n) = 0x00000000
          ODTEnable = 0x0
---
ODTEnable_f3 + +
    ampsca_ampscaodt_ODTEnable_f3(n) = 0x00000000
       ODTEnable = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f0(n) = 0x000c0b08
       RdDqODTDs = 0xc
       WrDqPdDs = 0xb
       WrDqPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqds_f1(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f2(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqds_f3(n) = 0x00080b00
       RdDqODTDs = 0x8
       WrDqPdDs = 0xb
       WrDqPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f0(n) = 0x00030b08
       RdDqDqsODTDs = 0x3
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x8
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f1(n) = 0x00010b00
       RdDqDqsODTDs = 0x1
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f2(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqiocfg_dqdqsds_f3(n) = 0x00080b00
       RdDqDqsODTDs = 0x8
       WrDqDqsPdDs = 0xb
       WrDqDqsPuDs = 0x0
---
+ +
    ampsdq_ampsdqodt_VRef_f0(n) = 0x00c000c0
       DqsVRefSel = 0xc0
       VRefSel = 0xc0
---
**IMPORTANT** : For power saving on SOC's these setings are mandatory. With Samsung DRAM, VRef_f1 should be set to 0x00EC00EC. With Micron DRAM, VRef_f1 should be set to 0x00EA00EA. With Hynix DRAM, VRef_f1 should be set to 0x00DF00DF.
+ +
    ampsdq_ampsdqodt_VRef_f1(n) = 0x00df00df
       DqsVRefSel = 0xdf
       VRefSel = 0xdf
---
+ +
    ampsdq_ampsdqrdtim_dqspdres(n) = 0x00000031
       DqsPdVal = 0x1 *read-only
       DqsWkPuPdVal = 0x3
---
+ +
    ampsca_ampscasdllctrl_SDLLUpdateCtrl(n) = 0x0303030b
       ClkEn2Valid = 0x3 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x3 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqsdllctrl_SDLLUpdateCtrl(n) = 0x0003000b
       ClkEn2Valid = 0x0 *read-only
       ReqWaitDelay = 0xb
       Valid2ClkEn = 0x0 *read-only
       ValidLen = 0x3 *read-only
---
+ +
    ampsdq_ampsdqiocfg_diffmode_freq3(n) = 0x00000001
       DqInVrefMode_f3 = 0x0
       DqsInDiffMode_f3 = 0x0
       DqsOutDiffMode_f3 = 0x1
---
+ +
    ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00ff0004
       Rd0RunSDLLUpd = 0x0 *read-only
       Rd0RunSDLLUpdOverride = 0x0 *read-only
       Rd0RunSDLLUpdWrResult = 0x0 *read-only
       Rd0SDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl rd0sdllctrl + +
Poll: ampsdqsdllctrl_rd0sdllctrl
+    Rd0RunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000004
       WrDqDqsRunSDLLUpd = 0x0 *read-only
       WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
       WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
       WrDqDqsWrLvlReBalanceEn = 0x0 *read-only
       WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
       WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
       WrDqSDLLHalfClkEn = 0x0 *read-only
       WrDqSDLLOvrVal = 0x0
       WrDqsSDLLOvrVal = 0xff
---
Poll ampsdqsdllctrl WrDqDqsSDLLCtrl + +
Poll: ampsdqsdllctrl_WrDqDqsSDLLCtrl
+    WrDqDqsRunSDLLUpdWrResult
+   while((CSR(ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n)) & 0x4) != 0x0)
+
---
+ +
    ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00ff02ff
       WrLvlMaxWrDqsSDLLCode = 0xff *read-only
       WrLvlRunUpdOverride = 0x0 *read-only
       WrLvlRunUpdWrResult = 0x0 *read-only
       WrLvlSDLLCode = 0xff
---
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+    WrLvlRunUpdWrResult
+   while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
---
+ +
    ampsdq_ampsdqrdtim_dqsPdEnAlwaysOn(n) = 0x00000001
       DqsPdEnAlwaysOn = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_DFICalTiming(n) = 0x04000410
       tCA2CAEntry = 0x10
       tCA2CAExit = 0x0
       tCKEHEntry = 0x4
       tCKEHExit = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f1(n) = 0x04000410
       tCA2CAEntry_f1 = 0x10
       tCA2CAExit_f1 = 0x0
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f2(n) = 0x04000410
       tCA2CAEntry_f2 = 0x10
       tCA2CAExit_f2 = 0x0
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsca_DFICalTiming2_DFICalTiming_f3(n) = 0x04000410
       tCA2CAEntry_f3 = 0x10
       tCA2CAExit_f3 = 0x0
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f0(n) = 0x04020402
       tCA2CAEntry_f0 = 0x2
       tCA2CAExit_f0 = 0x2
       tCKEHEntry_f0 = 0x4
       tCKEHExit_f0 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f1(n) = 0x04020402
       tCA2CAEntry_f1 = 0x2
       tCA2CAExit_f1 = 0x2
       tCKEHEntry_f1 = 0x4
       tCKEHExit_f1 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f2(n) = 0x04020402
       tCA2CAEntry_f2 = 0x2
       tCA2CAExit_f2 = 0x2
       tCKEHEntry_f2 = 0x4
       tCKEHExit_f2 = 0x4
---
+ +
    ampsdq_DFICalTiming_DFICalTiming_f3(n) = 0x04020402
       tCA2CAEntry_f3 = 0x2
       tCA2CAExit_f3 = 0x2
       tCKEHEntry_f3 = 0x4
       tCKEHExit_f3 = 0x4
---
+ +
    ampsdq_ampsdqdllctl_MDLLCodeCaptureControl(n) = 0x00000002
       MDLLLoopCnt = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f0(n) = 0x00001426
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x6
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalTiming_f1(n) = 0x00001422
       CoarseStepSize = 0x4 *read-only
       FineStepSize = 0x1
       tRL = 0x2
       tWL = 0x2
---
+ +
    ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
       tRdDqCalSegLen = 0x2
       tWrDqCalSegLen = 0x1
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl1(n) = 0x0000301e
       tRd2SDLL = 0x0
       tSDLL2Rd = 0x1e
       tSDLL2Wr = 0x30
       tWr2SDLL = 0x0
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdWrDqCalTimingCtrl2(n) = 0x03111004
       tRd2Rd = 0x4
       tRd2Wr = 0x10
       tWr2Rd = 0x11
       tWr2Wr = 0x3 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_HWRdDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_HWWrDqCalPatPRBS4I(n) = 0x55555e26
       PatInvertMask = 0x5555
       PatPRBS4 = 0x5e26
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f0(n) = 0x00aa01d1
       EndPoint = 0xaa
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f0(n) = 0x00ca0160
       EndPoint = 0xca
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_RdDqCalWindow_f1(n) = 0x00aa01d1
       EndPoint = 0xaa
       StartPoint = 0x1d1
---
+ +
    ampsca_ampscaRdWrDqCal_WrDqCalWindow_f1(n) = 0x00ca0160
       EndPoint = 0xca
       StartPoint = 0x160 *read-only
---
+ +
    ampsca_ampscaRdWrDqCal_MaxWrDqsSDLLMulFactor(n) = 0xa0a0080c
       MaxWrDqsSDLLCodeStatusF0 = 0xa0 *read-only
       MaxWrDqsSDLLCodeStatusF1 = 0xa0 *read-only
       WrDqsSDLLMulFactorF0 = 0xc
       WrDqsSDLLMulFactorF1 = 0x8
---
+ +
    ampsdq_ampsdqMulFactor_RdDqsMulFactor(n) = 0x20181000
       Factor0 = 0x0 *read-only
       Factor1 = 0x10
       Factor2 = 0x18
       Factor3 = 0x20
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq0(n) = 0x00000008
       CaOutDllScl_f0 = 0x8
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq0(n) = 0x00000008
       DqsInDll0Scl_f0 = 0x8
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100070a
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0xa
       RdDatLat_f0 = 0x7
       WrPhaseDelay_f0 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x01000606
       DqIeDeAssertPullIn_f0 = 0x0
       DqsPdEn_f0 = 0x1 *read-only
       RdCapLat_f0 = 0x6
       RdDatLat_f0 = 0x6
       WrPhaseDelay_f0 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq0(n) = 0x0100070d
          DqIeDeAssertPullIn_f0 = 0x0
          DqsPdEn_f0 = 0x1 *read-only
          RdCapLat_f0 = 0xd
          RdDatLat_f0 = 0x7
          WrPhaseDelay_f0 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq1(n) = 0x0000000d
       CaOutDllScl_f1 = 0xd
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq1(n) = 0x0000000d
       DqsInDll0Scl_f1 = 0xd
---
Program capture latency and recapture latency + + + + +
if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x21000606
       DqIeDeAssertPullIn_f1 = 0x2
       DqsPdEn_f1 = 0x1 *read-only
       RdCapLat_f1 = 0x6
       RdDatLat_f1 = 0x6
       WrPhaseDelay_f1 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq1(n) = 0x2100060a
          DqIeDeAssertPullIn_f1 = 0x2
          DqsPdEn_f1 = 0x1 *read-only
          RdCapLat_f1 = 0xa
          RdDatLat_f1 = 0x6
          WrPhaseDelay_f1 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq2(n) = 0x00000030
       CaOutDllScl_f2 = 0x30
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq2(n) = 0x00000030
       DqsInDll0Scl_f2 = 0x30
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x4100040a
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0xa
       RdDatLat_f2 = 0x4
       WrPhaseDelay_f2 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000606
       DqIeDeAssertPullIn_f2 = 0x4
       DqsPdEn_f2 = 0x1 *read-only
       RdCapLat_f2 = 0x6
       RdDatLat_f2 = 0x6
       WrPhaseDelay_f2 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq2(n) = 0x41000406
          DqIeDeAssertPullIn_f2 = 0x4
          DqsPdEn_f2 = 0x1 *read-only
          RdCapLat_f2 = 0x6
          RdDatLat_f2 = 0x4
          WrPhaseDelay_f2 = 0x0
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsca_ampscadllctl_caoutdllscl_freq3(n) = 0x0000003f
       CaOutDllScl_f3 = 0x3f
---
Program DLL scaling factors (assuming freq0/1/2/3 = 522/400/200/50MHz, FMCLK=522 MHz) + +
    ampsdq_ampsdqdllctl_dqsindll0scl_freq3(n) = 0x0000003f
       DqsInDll0Scl_f3 = 0x3f
---
Program capture latency and recapture latency + + + + + + +
if (platform == PALLADIUM)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x6100040a
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0xa
       RdDatLat_f3 = 0x4
       WrPhaseDelay_f3 = 0x0
else if (platform == FPGA)
    ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000606
       DqIeDeAssertPullIn_f3 = 0x6
       DqsPdEn_f3 = 0x1
       RdCapLat_f3 = 0x6
       RdDatLat_f3 = 0x6
       WrPhaseDelay_f3 = 0x0
else
       ampsdq_ampsdqrdtim_rdcapcfg_freq3(n) = 0x61000406
          DqIeDeAssertPullIn_f3 = 0x6
          DqsPdEn_f3 = 0x1
          RdCapLat_f3 = 0x6
          RdDatLat_f3 = 0x4
          WrPhaseDelay_f3 = 0x0
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---
Updating the programming of DLL*UpdtDur Fields

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dllupdtctrl(n) = 0x50017550
          DllInitUpdtDur = 0x7
          DllUpdtDur = 0x5
          DllUpdtMode = 0x1
          DllUpdtPhyUpdtTyp = 0x0 *read-only
          FreqChangeSDLLUpdDur = 0x50 *read-only
          SDLLUpdDur = 0x50 *read-only
---


FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impautocal(n) = 0x00010000
          impautocalen = 0x1
          impcalintvl = 0x0 *read-only
          impcaltype = 0x0
---
+ +
    ampsca_ampscadllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
+ +
    ampsdq_ampsdqdllctl_dllupdtintvl(n) = 0x10200020
       DllFastUpdtAlwaysON = 0x1 *read-only
       DllFastUpdtIntvl = 0x20 *read-only
       DllUpdtAlwaysON = 0x0
       DllUpdtIntvl = 0x20 *read-only
---
Enable DLL + +
    ampsca_ampscadllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Enable DLL + +
    ampsdq_ampsdqdllctl_dllen(n) = 0x00000100
       DLLEn = 0x1
       MDllReset = 0x0 *read-only
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000000
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
+ +
    ampsca_ampscaiocfg_BISTRxMode(n) = 0x0000001c
       BISTRxMode = 0x0 *read-only
       BISTRxODT = 0x7
       BISTRxODTEn = 0x0 *read-only
---
+ +
    amph_SLC_SLC_REG0(n) = 0x0000003f
       pad_ca0_slc = 0xf
       pad_ca1_slc = 0x3
       pad_ca2_slc = 0x0 *read-only
       pad_ca3_slc = 0x0 *read-only
       pad_ca4_slc = 0x0 *read-only
       pad_ca5_slc = 0x0 *read-only
       pad_ck_slc = 0x0 *read-only
---
Assert init_done + +
    ampsca_ampscagen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
Assert init_done + +
    ampsdq_ampsdqgen_ampinit(n) = 0x00000001
       InitDone = 0x1
---
+

3. Self-Refresh Exit

+

Prior to this step, the DRAM is assumed to be in the self-refresh state, and CKE has been kept low, either by retention circuitry in the PHY/IO, or, after SOC power is up and the reset is done, by the controller. This step will take DRAM out of the self-refresh mode. Software must guarantee that at least 50 us have passed since the de- assertion of AMC reset before self-refresh exit, in the resume-boot case. + The frequency change to 50MHz here is initiated by PMGR. + For ResumeBoot, the auto-refresh must be enabled before exiting self-refresh state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us after Impedance Calibration in Step2. This is to avoid McPhyPending preventing the SRFSM from exiting SR. +
---
radar #8707478 has been fixed. SetSRExitRefCnt to 2. + +
    amcx_dramcfg_arefparam(n) = 0x0d010019
       FreqChngWaitThr = 0x1
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq3(n) = 0x24480050
       tRFCBaseCyc_freq3 = 0x50
       tRFCCyc_freq3 = 0x48
       tRFCpbCyc_freq3 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq3(n) = 0x01010001
       tRFCBaseCyc_freq3 = 0x1
       tRFCCyc_freq3 = 0x1
       tRFCpbCyc_freq3 = 0x1
else
       amcx_dramtim_autoref_freq3(n) = 0x03050005
          tRFCBaseCyc_freq3 = 0x5
          tRFCCyc_freq3 = 0x5
          tRFCpbCyc_freq3 = 0x3
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq2(n) = 0x24480050
       tRFCBaseCyc_freq2 = 0x50
       tRFCCyc_freq2 = 0x48
       tRFCpbCyc_freq2 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq2(n) = 0x01010001
       tRFCBaseCyc_freq2 = 0x1
       tRFCCyc_freq2 = 0x1
       tRFCpbCyc_freq2 = 0x1
else
       amcx_dramtim_autoref_freq2(n) = 0x09120013
          tRFCBaseCyc_freq2 = 0x13
          tRFCCyc_freq2 = 0x12
          tRFCpbCyc_freq2 = 0x9
---
**IMPORTANT** : For power saving on SOC's using Samsung and Hynix DRAM's, it's mandatory to set autoref_freq1 to 0x1C480049. For SOC's using Micron DRAM, autoref_freq1 should be set to 0x20480049.
+ + + + +
if (platform == FPGA)
    amcx_dramtim_autoref_freq1(n) = 0x01010001
       tRFCBaseCyc_freq1 = 0x1
       tRFCCyc_freq1 = 0x1
       tRFCpbCyc_freq1 = 0x1
else
       amcx_dramtim_autoref_freq1(n) = 0x24480049
          tRFCBaseCyc_freq1 = 0x49
          tRFCCyc_freq1 = 0x48
          tRFCpbCyc_freq1 = 0x24
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_freq0(n) = 0x24480050
       tRFCBaseCyc_freq0 = 0x50
       tRFCCyc_freq0 = 0x48
       tRFCpbCyc_freq0 = 0x24
else if (platform == FPGA)
    amcx_dramtim_autoref_freq0(n) = 0x01010001
       tRFCBaseCyc_freq0 = 0x1
       tRFCCyc_freq0 = 0x1
       tRFCpbCyc_freq0 = 0x1
else
       amcx_dramtim_autoref_freq0(n) = 0x366c006e
          tRFCBaseCyc_freq0 = 0x6e
          tRFCCyc_freq0 = 0x6c
          tRFCpbCyc_freq0 = 0x36
---
+ + + + + + +
if (platform == PALLADIUM)
    amcx_dramtim_autoref_params(n) = 0x0017005d
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x5d
else if (platform == FPGA)
    amcx_dramtim_autoref_params(n) = 0x00170013
       tREFBWtRFCcnt = 0x17
       tREFICyc = 0x13
else
       amcx_dramtim_autoref_params(n) = 0x0017005d
          tREFBWtRFCcnt = 0x17
          tREFICyc = 0x5d
---
Enable auto refresh derating by setting TempDrtEn to 1. However, we do not enable ODTS interval until the end of the init. Setting TempDrtEn to 1 allows the chip to be in the hi-temp state and become more conservative. + + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0x00000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x0 *read-only
       ShareZQRes = 0x0 *read-only
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x0 *read-only
       ZqCalIntrvl = 0x0 *read-only
else
       amcx_dramcfg_odtszqc(n) = 0x00001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x0 *read-only
          ShareZQRes = 0x0 *read-only
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x0 *read-only
          ZqCalIntrvl = 0x0 *read-only
---
set SRExtraRefCnt to correct value (which is 1) and set LongSRCnt to be tREFW/4 (32ms/4=8ms)
If RefCntrHiWaterMark is changed from its default value, then LongSRExitRefCnt needs to be programmed to the same value.
Palladium: LongSRCnt=0x1004 because Palladium uses 1Gb device.
+ +
    amcx_dramcfg_longsr(n) = 0x01022008
       LongSRCnt = 0x2008
       LongSRExitRefCnt = 0x1
       SRExtraRefCnt = 0x2
---
+ +
    amcx_dramcfg_mcphyupdtparam(n) = 0x15030007
       FreqCSettleCyc = 0x5 *read-only
       McPhyTimeParamCyc = 0x3
       PhyInitStartCyc = 0x0
       PhyUpdMDLL = 0x1
       UpdPhyLatCyc = 0x0 *read-only
       tPhyUpdGap = 0x7
---
Call custom API provided by PMGR for changing mcu_clk to 55Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
Wait 5us to avoid a race condition between frequency change to bucket 3 & MCU being enabled +
---
Turn on enables for various AMC blocks MCU. + +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
Run impedance calibration and optionally enable periodic auto impedance calibration

FPGA: Skip this step
+ +
       ampsca_ampscaiocfg_impcalcmd(n) = 0x00000001
          RunImpCal = 0x0 *read-only
          RunImpCalType = 0x0
---
Poll ampscaiocfg impcalcmd

FPGA: Skip this step
+ +
Poll: ampscaiocfg_impcalcmd
+       RunImpCal
+      while((CSR(ampsca_ampscaiocfg_impcalcmd(n)) & 0x1) != 0x0)
+
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-Yes-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10110000
          ARpbEn_freq1 = 0x1 *read-only
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-Yes-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-Yes-
Wait 200us for tINIT1 in real init, which we have cooked down to 200ns for simulation. +
---
Wait 2 ms for tINIT3 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00010000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+    freqchngrunsocupd
+   while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
---
+ +
    amcx_dramcfg_freqchngctl(n) = 0x00000000
       freqchngfspop = 0x0 *read-only
       freqchngmrwcnt_freq0 = 0x0 *read-only
       freqchngmrwcnt_freq1 = 0x0 *read-only
       freqchngmrwcnt_freq2 = 0x0 *read-only
       freqchngmrwcnt_freq3 = 0x0 *read-only
       freqchngrunsocupd = 0x0 *read-only
---
Wait 2us for the soc update to finish +
---
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00004000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00004001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-Yes-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-Yes-
Assert MPC to Sending SR Exit during Resume Boot + +
       amcx_dramcmd_mrinitcmd(n) = 0x00000000
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Issue self-refresh exit command. One for each channel.
SW needs to guarantee that at least 50usec has passed since removal of reset to AMC before issuing the self-refresh exit command, in case of resume boot.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00000001
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunSRExit
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x1) != 0x0)
+
-No-
Wait 2 us for tINIT5 in real init, which we have cooked down to 200ns for simulation. +
---
+ +
    glbtimer_GlbTimer_ChEn = 0x0000000f
       ChEn = 0xf
---
+

4. DRAM Reset, ZQ Calibration & Configuration (Cold Boot Only).

+

This step is only required for ColdBoot. + This step is to be repeated for each of the number of ranks per channel. The dramcmd.mrcmdch{N}.MRCmdCsCh{N} bit (Noted by letter R in the section) should be incremented in each loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Issue DRAM ZQ calibration START MPC command MRINIT CMD registers.
Note that the MPC command can be issued to different channels independently, as long as the system has separate ZQ reference resistor for eachchannel. TheZQcalibration MPC to each rank within the same channel must be issued in series.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x4f004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 1us for tZQCAL. +
---
Issue DRAM ZQ calibration LATCH MPC command MRINIT CMD registers + +
    amcx_dramcmd_mrinitcmd(n) = 0x51004100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Wait 20ns for tZQLAT. +
---
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices. + +
       amcx_dramcmd_mrinitcmd(n) = 0x00020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x8e010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x00160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR11 for FPGA

FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program VRCG and Modified Refresh to 1 + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x590e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x80170100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x550f4100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR15/20 to match PatInvertMask of HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x55144100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x26204100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Program MR32/40 to match the PatPRBS4 pattern for HW RdDQ calibration + +
       amcx_dramcmd_mrinitcmd(n) = 0x5e284100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

5. Topology-specific configuration.

+

Here we perform MRR's to the memory to find out device density and program addrcfg, DramAccCtrl and mccchnldec registers

+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ + + + + + + + +
if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_addrcfg = 0x01030201
       BnkAddrWid = 0x1
       ColAddrWid = 0x2
       CsWid = 0x1
       RowAddrWid = 0x3
else
       amcc_MccLockRegion_addrcfg = 0x00030201
          BnkAddrWid = 0x1
          ColAddrWid = 0x2
          CsWid = 0x0
          RowAddrWid = 0x3
---
+ + + + + + + + + + + + + + + + + + +
if (platform == FPGA_LPDDR3)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000003
       DramSize = 0x3
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else if (platform == FOUR_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FPGA)
    amcc_MccLockRegion_DramAccCtrl = 0x0000000f
       DramSize = 0xf
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x0000001f
       DramSize = 0x1f
else if (platform == TWO_CH_ONE_RANK)
    amcc_MccLockRegion_DramAccCtrl = 0x00000007
       DramSize = 0x7
else
       amcc_MccLockRegion_DramAccCtrl = 0x0000000f
          DramSize = 0xf
---
dram_Density_config(); +
---
+ + + + + + + + + + +
if (platform == ONE_CH_ONE_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00050201
       ChSelHiBits = 0x5
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == ONE_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060201
       ChSelHiBits = 0x6
       ChSelTyp = 0x1
       ChnlStartBit = 0x2
       NumMcuChnl = 0x0
else if (platform == TWO_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060210
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x1
else if (platform == FOUR_CH_TWO_RANK)
    amcc_MccLockRegion_mccchnldec = 0x00060220
       ChSelHiBits = 0x6
       ChSelTyp = 0x0
       ChnlStartBit = 0x2
       NumMcuChnl = 0x2
else
       amcc_MccLockRegion_mccchnldec = 0x00050220
          ChSelHiBits = 0x5
          ChSelTyp = 0x0
          ChnlStartBit = 0x2
          NumMcuChnl = 0x2
---
+

6. Prepare for switch from boot-clock speed to normal operation speed

+

The frequency change is initiated by PMGR.

+ + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Wait 5us before issuing a freq change to make sure all refreshes have been flushed. +
---
Enable AMC scheduler to allow normal transactions to be processed.
Scheduler has to be enabled to let AMC issue self-refresh entry and allow frequency change.
+ +
    amcx_amcgen_amcctrl(n) = 0x00000003
       McuEn = 0x1
       SchEn = 0x1
---
+

7. Setup registers for CA calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR to 1, and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x580d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x52020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xae010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xf3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x020b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       ampsca_ampscawrlvl_ampcawrlvlsdllcode(n) = 0x00000200
          WrLvlMaxWrDqsSDLLCode = 0x0
          WrLvlRunUpdOverride = 0x0 *read-only
          WrLvlRunUpdWrResult = 0x0 *read-only
          WrLvlSDLLCode = 0x0
-No-
Poll ampscawrlvl ampcawrlvlsdllcode + +
Poll: ampscawrlvl_ampcawrlvlsdllcode
+       WrLvlRunUpdWrResult
+      while((CSR(ampsca_ampscawrlvl_ampcawrlvlsdllcode(n)) & 0x200) != 0x0)
+
-No-
+

8. AMP Dynamic Address Timing Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step8Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 1, 16, 12);
+
---
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x00130013
          DllIncLockTim = 0x13
          DllInitLockTim = 0x13
YesYes-
Disable AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00100001
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x1
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Defer SDLL update until frequency change + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000001
          DeferEn = 0x1
YesYes-
Set MDLL override to 0 + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00010000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x1
YesYes-
Run MDLL update + +
       ampsdq_ampsdqdllctl_dllupdtcmd(n) = 0x00000001
          RunDllUpdt = 0x0 *read-only
YesYes-
Poll ampsdqdllctl dllupdtcmd + +
Poll: ampsdqdllctl_dllupdtcmd
+       RunDllUpdt
+      while((CSR(ampsdq_ampsdqdllctl_dllupdtcmd(n)) & 0x1) != 0x0)
+
YesYes-
Enable back AMP Clock Gating for RunDllUpdt to go through

FPGA: Skip this step
+ +
       ampsca_ampscagen_ampclk(n) = 0x00000000
          FMClkIdleDetectEn = 0x0 *read-only
          ForceDRAMClkEn = 0x0 *read-only
          ForceDiv2MClkTopGaterOn = 0x0
          ForceFMClkWakeUp = 0x0 *read-only
          ForceMClkWakeUp = 0x0 *read-only
          TopClkGateDis = 0x0
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsca_ampscadllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
Program DLL Init and Incr lock timers based on 24 MHz value

FPGA: Skip this step
+ +
       ampsdq_ampsdqdllctl_dlllocktim(n) = 0x012c012c
          DllIncLockTim = 0x12c
          DllInitLockTim = 0x12c
YesYes-
RdWrDqCalSegLen_f0

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f0(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
RdWrDqCalSegLen_f1

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_RdWrDqCalSegLen_f1(n) = 0x00010002
          tRdDqCalSegLen = 0x2
          tWrDqCalSegLen = 0x1
YesYes-
+ +
       amcx_dramcfg_freqchngctl1_freq1(n) = 0x110c110e
          freqchngmrw2_addr_freq1 = 0xe
          freqchngmrw2_ctrl_freq1 = 0x0
          freqchngmrw2_data_freq1 = 0x11
          freqchngmrw3_addr_freq1 = 0xc
          freqchngmrw3_ctrl_freq1 = 0x0
          freqchngmrw3_data_freq1 = 0x11
YesYes-
HWRdWrDqCalFullScanEnable

PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
YesYes-
+

9. Setup registers for DQ calibration for bucket 1

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 1 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0xd80d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
YesNo-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
YesNo-
Wait 1us for FSP setting to take affect. +
---
Program AutoSR + +
       amcx_dramcfg_pwrmngten(n) = 0x00000002
          AutoSR = 0x1
          DynPwrDnEn = 0x0 *read-only
          McPhyUpdDramClkOff = 0x0 *read-only
          PwrDnClkOff = 0x0 *read-only
          SRClkOff = 0x0 *read-only
          SRExitOpt = 0x0 *read-only
-Yes-
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
YesYes-
WrDqDqsSDLLCtrl + +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff00000c
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
YesYes-
Re-enable SDLL updates + +
       ampsca_ampscasdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Re-enable SDLL updates + +
       ampsdq_ampsdqsdllctrl_SDLLUpdateDeferEn(n) = 0x00000000
          DeferEn = 0x0
YesYes-
Disable MDLL override + +
       ampsdq_ampsdqdllctl_MDLLOverride(n) = 0x00000000
          MDLLOvrCode = 0x0
          MDLLOvrSel = 0x0
YesYes-
Call custom API provided by PMGR for changing mcu_clk to 800Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

10. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 1, 16, 12);
+
---
+ +
    ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000010
       DqIdleActive = 0x0
       DqsIdleActive = 0x1
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
step10Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 1, 16, 12);
+
---
The scale factors for Bin0 and Bin1 WR DQS/DQ skew have to to programmed to the correct values based on board charaterization. Fields are being set to 0 here, since exact board skews are not available now (04/01/14). + +
    ampsdq_ampsdqsdllctrl_WrtDQSDQSkewControl(n) = 0x06000000
       WrDqDqsIDTVTScaleEn = 0x1 *read-only
       WrDqDqsMDLLVTScaleEn = 0x1 *read-only
       WrtDQSDQScaleFactorF0 = 0x0
       WrtDQSDQScaleFactorF1 = 0x0
       WrtDQSDQScaleFactorPlusSel = 0x0
---
+

11. Setup registers for CA calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
       ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000000
          DqIdleActive = 0x0
          DqsIdleActive = 0x0
-No-
Program FSP-WR to 0 and FSP-OP to 1 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x980d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR2 register (latency) through MRR/MRW command registers. The example shows the nominal programming for LPDDR2-1066 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x24020100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Configure DRAM MR1 register through MRR/MRW command registers.
This includes the following: WC=Wrap BT=Sequential BL=BL16.
nWR, the example shows the nominal programming for LPDDR3- 1600 devices based on the JEDEC specifications. See Section 3.2.2.3 for values for other devices.

FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xce010100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0xb3030100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x04160100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Skip this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x440b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Skip this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-


FPGA: Perform this step
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x000b0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd

FPGA: Perform this step
+ +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110c0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+ +
       amcx_dramcmd_mrinitcmd(n) = 0x110e0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
+

12. AMP Dynamic Address Timing Calibration

+


+ + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step12Calibration(0, LPDDR3, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, CA_CALIB, 0, 0, 0, 0, 0, 0, 0, 24, 12);
+
---
+

13. Setup registers for DQ calibration for bucket 0

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Program FSP-WR and FSP-OP to 0 and set VRCG and modified refresh + +
       amcx_dramcmd_mrinitcmd(n) = 0x180d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Call custom API provided by PMGR for changing mcu_clk to 1200Mhz and mcu_fixed_clk to Mhz
// TO BE COMPLETED

FPGA: Skip this step

+
---
+
---
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00010000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Poll dramcfg freqchngctl + +
Poll: dramcfg_freqchngctl
+       freqchngrunsocupd
+      while((CSR(amcx_dramcfg_freqchngctl(n)) & 0x10000) != 0x0)
+
-No-
+ +
       amcx_dramcfg_freqchngctl(n) = 0x00000000
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x0
          freqchngmrwcnt_freq1 = 0x0
          freqchngmrwcnt_freq2 = 0x0
          freqchngmrwcnt_freq3 = 0x0
          freqchngrunsocupd = 0x0 *read-only
-No-
Wait 2us for the soc update to finish +
---
+

14. AMP Dynamic DQ Calibration

+


+ + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WRLVL, 0, 0, 0, 0, 0, 24, 12);
+
---
+ +
       ampsdq_ampsdqiocfg_dqfltctrl(n) = 0x00000010
          DqIdleActive = 0x0
          DqsIdleActive = 0x1
-No-
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, RD_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
step14Calibration(0, resume_boot, AMC_NUM_CHANS, AMC_NUM_RANKS, WR_DQ_CAL, 0, 0, 0, 0, 0, 24, 12);
+
---
+

15. Setup registers for boot.

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    ampsca_ampscaiocfg_BISTRxMode(n) = 0x00000000
       BISTRxMode = 0x0 *read-only
       BISTRxODT = 0x0
       BISTRxODTEn = 0x0 *read-only
---
Program FSP-WR to 1 and FSP-OP to 0 and reset VRCG, since all calibrations are done + +
       amcx_dramcmd_mrinitcmd(n) = 0x500d0100
          MRCmdAddr = 0x0 *read-only
          MRCmdCs = 0x0 *read-only
          MRCmdData = 0x0 *read-only
          MRCmdIsMPC = 0x0 *read-only
          MRCmdIsRd = 0x0 *read-only
          RunMRCmd = 0x0 *read-only
          RunRdLvl = 0x0 *read-only
          RunSRExit = 0x0 *read-only
-No-
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+       RunMRCmd
+      while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
-No-
Wait 1us for FSP setting to take affect. +
---
Program FreqChngMRW Cnt + +
       amcx_dramcfg_freqchngctl(n) = 0x00009999
          freqchngfspop = 0x0 *read-only
          freqchngmrwcnt_freq0 = 0x9
          freqchngmrwcnt_freq1 = 0x9
          freqchngmrwcnt_freq2 = 0x9
          freqchngmrwcnt_freq3 = 0x9
          freqchngrunsocupd = 0x0 *read-only
-No-
+ +
       ampsdq_ampsdqsdllctrl_WrDqDqsSDLLCtrl(n) = 0xff000008
          WrDqDqsRunSDLLUpd = 0x0 *read-only
          WrDqDqsRunSDLLUpdOverride = 0x0 *read-only
          WrDqDqsRunSDLLUpdWrResult = 0x0 *read-only
          WrDqDqsWrLvlReBalanceEn = 0x1
          WrDqSDLLAddHalfClk_f0 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f1 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f2 = 0x0 *read-only
          WrDqSDLLAddHalfClk_f3 = 0x0 *read-only
          WrDqSDLLHalfClkEn = 0x0 *read-only
          WrDqSDLLOvrVal = 0x0
          WrDqsSDLLOvrVal = 0xff
-No-


DO_CALIBRATION: Skip this step
+ +
       ampsdq_ampsdqsdllctrl_rd0sdllctrl(n) = 0x00150004
          Rd0RunSDLLUpd = 0x0 *read-only
          Rd0RunSDLLUpdOverride = 0x0 *read-only
          Rd0RunSDLLUpdWrResult = 0x0 *read-only
          Rd0SDLLOvrVal = 0x15
-No-
Poll ampsdqsdllctrl rd0sdllctrl

DO_CALIBRATION: Skip this step
+ +
Poll: ampsdqsdllctrl_rd0sdllctrl
+       Rd0RunSDLLUpdWrResult
+      while((CSR(ampsdq_ampsdqsdllctrl_rd0sdllctrl(n)) & 0x4) != 0x0)
+
-No-


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000000
          HWRdDqCalFullScanEnable = 0x0
          HWWrDqCalFullScanEnable = 0x0
---


PALLADIUM: Skip this step
+ +
       ampsca_ampscaRdWrDqCal_HWRdWrDqCalFullScanEnable(n) = 0x00000003
          HWRdDqCalFullScanEnable = 0x1
          HWWrDqCalFullScanEnable = 0x1
---
+

16. Enable other features

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Turn on the freq change waiting for refresh and self-refresh exit feature + +
    amcx_dramcfg_arefparam(n) = 0x0d010019
       FreqChngWaitThr = 0x1 *read-only
       PhyUpdWaitRefresh = 0x1
       PhyUpdWaitThr = 0x1 *read-only
       PhyUpdWaittXSR = 0x0
       RefAssertCnt = 0xd
       SRExitRefCnt = 0x1
---
Enable periodic ZQC. (Optional)
Note the ZqCalIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~128ms (max supported value). The actual setting may vary depending on the DRAM and the system.
+ + + + +
if (platform == FPGA)
    amcx_dramcfg_odtszqc(n) = 0xc0000000
       DerateParamSRExit = 0x0
       OdtsRdIntrvl = 0x0
       SRExitZQCChnlQuiet = 0x1
       ShareZQRes = 0x0
       TempDrtEn = 0x0
       ZQCChnlQuiet = 0x0 *read-only
       ZQCStack = 0x1
       ZqCalIntrvl = 0x0
else
       amcx_dramcfg_odtszqc(n) = 0xc0001000
          DerateParamSRExit = 0x0
          OdtsRdIntrvl = 0x0
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x1
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
---
Turn on the QBR enables. + +
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0 *read-only
---
+ +
       amcx_dramcfg_arefen_freq3(n) = 0x10100000
          ARpbEn_freq3 = 0x0
          HiTempRefRnkAgeOut_freq3 = 0x1
          RefCntrHiWaterMark_freq3 = 0x1
          RefCntrLoWaterMark_freq3 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq2(n) = 0x10000000
          ARpbEn_freq2 = 0x0
          HiTempRefRnkAgeOut_freq2 = 0x0
          RefCntrHiWaterMark_freq2 = 0x1
          RefCntrLoWaterMark_freq2 = 0x0
-No-
+ +
       amcx_dramcfg_arefen_freq1(n) = 0x10110000
          ARpbEn_freq1 = 0x1
          HiTempRefRnkAgeOut_freq1 = 0x1
          RefCntrHiWaterMark_freq1 = 0x1
          RefCntrLoWaterMark_freq1 = 0x0
-No-
Turn on auto refresh. + +
       amcx_dramcfg_arefen_freq0(n) = 0x1011013f
          ARpbEn_freq0 = 0x1
          AutoRefEn = 0x1
          AutoRefSchEn = 0x1
          DisableHiTempREFab = 0x1
          EarlyCasAgeOut = 0x0
          HiPriREFpbPch = 0x1
          HiTempRefRnkAgeOut_freq0 = 0x1
          REFpb2bank = 0x0
          REFpbEarlyPch = 0x1
          RefCntrHiWaterMark_freq0 = 0x1
          RefCntrLoWaterMark_freq0 = 0x0
          RefOpptEn = 0x1
          tREFBWREFpb = 0x1
-No-
+

17. Enable the Fast Critical Word Forwarding feature (optional)

+


+ + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Configure the MIF FCWF pull- in cycles.
(Here we just use 0x8 as an example, please refer to register description for the valid programming range and refer to performance simulation results)
+ + + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbrparam(n) = 0x61616161
       RdCwfEarlyCyc_freq0 = 0x1
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x1
       RdCwfEarlyCyc_freq3 = 0x1
       RdRemEarlyCyc_freq0 = 0x6
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x6
       RdRemEarlyCyc_freq3 = 0x6
else if (platform == FPGA)
    amcx_mcusch_qbrparam(n) = 0x00006100
       RdCwfEarlyCyc_freq0 = 0x0
       RdCwfEarlyCyc_freq1 = 0x1
       RdCwfEarlyCyc_freq2 = 0x0
       RdCwfEarlyCyc_freq3 = 0x0
       RdRemEarlyCyc_freq0 = 0x0
       RdRemEarlyCyc_freq1 = 0x6
       RdRemEarlyCyc_freq2 = 0x0
       RdRemEarlyCyc_freq3 = 0x0
else
       amcx_mcusch_qbrparam(n) = 0x000061a5
          RdCwfEarlyCyc_freq0 = 0x5
          RdCwfEarlyCyc_freq1 = 0x1
          RdCwfEarlyCyc_freq2 = 0x0
          RdCwfEarlyCyc_freq3 = 0x0
          RdRemEarlyCyc_freq0 = 0xa
          RdRemEarlyCyc_freq1 = 0x6
          RdRemEarlyCyc_freq2 = 0x0
          RdRemEarlyCyc_freq3 = 0x0
---
Turn on the PredictiveM2AReq feature in MIF. (The other Qbr enables are turned on here, but not related to CWF feature) + + + + +
if (platform == PALLADIUM)
    amcx_mcusch_qbren(n) = 0x0000000d
       ErlyQbrEn = 0x1
       LateQbrEn = 0x1
       MifQbrEn = 0x1
       PredictiveM2AReq = 0x0
else
       amcx_mcusch_qbren(n) = 0x0000000f
          ErlyQbrEn = 0x1
          LateQbrEn = 0x1
          MifQbrEn = 0x1
          PredictiveM2AReq = 0x1
---
+ +
    amcc_mcccfg_MccGen = 0x00000126
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x1 *read-only
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
+ +
    amcc_amccperfcntr_Mcc0QPropCtrl = 0x300011a2
       Mcc0AfCacheRdPropQCmd = 0x1 *read-only
       Mcc0AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc0AfDramRdPropQCmd = 0x1 *read-only
       Mcc0AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc0DpPropQCfg = 0x0 *read-only
       Mcc0DpPropQCmd = 0x1 *read-only
       Mcc0DpPropQTrakEnbl = 0x0 *read-only
       Mcc0MsqQPropCfg = 0x0 *read-only
       Mcc0MsqQPropQCmd = 0x0 *read-only
       Mcc0MsqQPropTrakEnbl = 0x0 *read-only
       Mcc0QpropOutSel = 0x3
       Mcc0TpPropQCmd = 0x0 *read-only
       Mcc0TpPropQTrakEnbl = 0x1
       Mcc0TpQPropSel = 0x4
       Mcc0TpQpropMask = 0x0 *read-only
---
+ +
    amcc_amccperfcntr_Mcc1QPropCtrl = 0x300011a2
       Mcc1AfCacheRdPropQCmd = 0x1 *read-only
       Mcc1AfCacheRdPropQTrakEnbl = 0x0 *read-only
       Mcc1AfDramRdPropQCmd = 0x1 *read-only
       Mcc1AfDramRdPropQTrakEnbl = 0x0 *read-only
       Mcc1DpPropQCfg = 0x0 *read-only
       Mcc1DpPropQCmd = 0x1 *read-only
       Mcc1DpPropQTrakEnbl = 0x0 *read-only
       Mcc1MsqQPropCfg = 0x0 *read-only
       Mcc1MsqQPropQCmd = 0x0 *read-only
       Mcc1MsqQPropTrakEnbl = 0x0 *read-only
       Mcc1QpropOutSel = 0x3
       Mcc1TpPropQCmd = 0x0 *read-only
       Mcc1TpPropQTrakEnbl = 0x1
       Mcc1TpQPropSel = 0x4
       Mcc1TpQpropMask = 0x0 *read-only
---
+

18. Enable Power & ClockGating features and Configure the MCC and Global Timer

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Enable AMPCA Fixed MCLK Clock Gating + +
    ampsca_ampscagen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
Enable AMPDQ Fixed MCLK Clock Gating + +
    ampsdq_ampsdqgen_ampclk(n) = 0x00000000
       FMClkIdleDetectEn = 0x0
       ForceDRAMClkEn = 0x0 *read-only
       ForceDiv2MClkTopGaterOn = 0x0 *read-only
       ForceFMClkWakeUp = 0x0
       ForceMClkWakeUp = 0x0
       TopClkGateDis = 0x0
---
disable dynamic power-down. + +
    amcx_dramcfg_pwrmngten(n) = 0x00000132
       AutoSR = 0x1
       DynPwrDnEn = 0x0
       McPhyUpdDramClkOff = 0x0
       PwrDnClkOff = 0x1
       SRClkOff = 0x1
       SRExitOpt = 0x1
---
disable dynamic power-down. + +
       amcx_dramcfg_pwrmngten(n) = 0x00000133
          AutoSR = 0x1
          DynPwrDnEn = 0x1
          McPhyUpdDramClkOff = 0x0
          PwrDnClkOff = 0x1
          SRClkOff = 0x1
          SRExitOpt = 0x1
-No-
Revert auto self-refresh wait timer to guided value.

FPGA: Skip this step
+ +
       amcx_dramcfg_pwrmngtparam_freq0(n) = 0x01800000
          BypsPwrDnDlyCyc_freq0 = 0x0 *read-only
          SelfRefTmrVal_freq0 = 0x180
---
Setting WqAgeOutVal to be 3/4 of SelfRefTmrVal, to flush writes in a reasonable time.

FPGA: Skip this step
+ +
       amcx_mcusch_psqwqctl1(n) = 0x01640120
          WqAgeOutVal_freq0 = 0x120
          WqAgeOutVal_freq1 = 0x164 *read-only
---
Enable wakeups from glbl timer to pmgr + +
       glbtimer_GlbTimer_PmgrWakeUpCfg = 0x000000ff
          FreqChngEn = 0x1
          IdtEn = 0x1
          ImpCalEn = 0x1
          MdllEn = 0x1
          RdCalEn = 0x1
          VoltRampEn = 0x1
          WrCalEn = 0x1
          ZQCalEn = 0x1
Yes--
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly0 = 0x01500150
       PreFreqChng2AllBankDly_f0 = 0x150
       PreFreqChng2AllBankDly_f1 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreq2AllBankDly1 = 0x01500150
       PreFreqChng2AllBankDly_f2 = 0x150
       PreFreqChng2AllBankDly_f3 = 0x150
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly0 = 0x02a002a0
       PreFreqChng2FreqChngDly_f0 = 0x2a0
       PreFreqChng2FreqChngDly_f1 = 0x2a0
---
+ +
    glbtimer_GlbTimer_PreFreqChng2FreqChngDly1 = 0x02a002a0
       PreFreqChng2FreqChngDly_f2 = 0x2a0
       PreFreqChng2FreqChngDly_f3 = 0x2a0
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly0 = 0x00900090
       Cal2PreFreqChngDly_f0 = 0x90
       Cal2PreFreqChngDly_f1 = 0x90
---
+ +
    glbtimer_GlbTimer_Cal2PreFreqChngDly1 = 0x00900090
       Cal2PreFreqChngDly_f2 = 0x90
       Cal2PreFreqChngDly_f3 = 0x90
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly0 = 0x01200120
       FreqChng2PstCalDly_f0 = 0x120
       FreqChng2PstCalDly_f1 = 0x120
---
+ +
    glbtimer_GlbTimer_FreqChng2PstCalDly1 = 0x01200120
       FreqChng2PstCalDly_f2 = 0x120
       FreqChng2PstCalDly_f3 = 0x120
---
+ +
       glbtimer_GlbTimer_MdllTimer = 0x00000bb8
          MdllTimerCnt = 0xbb8
Yes--
+ +
       glbtimer_GlbTimer_MdllVoltRampTimer = 0x0000004b
          MdllVoltRampTimerCnt = 0x4b
Yes--
+ +
       glbtimer_GlbTimer_CtrlUpdMaskTimer = 0x0000000f
          CtrlUpdMaskTimerCnt = 0xf
Yes--
+ +
       glbtimer_GlbTimer_RdCalTimer = 0x002dc6c0
          RdCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_WrCalTimer = 0x002dc6c0
          WrCalTimerCnt = 0x2dc6c0
Yes--
+ +
       glbtimer_GlbTimer_ZQCTimer = 0x003d0900
          ZQCTimerCnt = 0x3d0900
Yes--
+ +
       glbtimer_GlbTimer_PerCal_FreqChngTimer = 0x000493e0
          PerCal_FreqChngTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_VoltRampTimer = 0x000493e0
          VoltRampTimerCnt = 0x493e0
Yes--
+ +
       glbtimer_GlbTimer_ImpCalTimer = 0x00002ee0
          ImpCalTimerCnt = 0x2ee0
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly0 = 0x00d800d8
          VoltRamp2AllBankDly_f0 = 0xd8
          VoltRamp2AllBankDly_f1 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_VoltRamp2AllBankDly1 = 0x00d800d8
          VoltRamp2AllBankDly_f2 = 0xd8
          VoltRamp2AllBankDly_f3 = 0xd8
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly0 = 0x00900090
          AllBank2PmgrAckDly_f0 = 0x90
          AllBank2PmgrAckDly_f1 = 0x90
Yes--
+ +
       glbtimer_GlbTimer_AllBank2PmgrAckDly1 = 0x00900090
          AllBank2PmgrAckDly_f2 = 0x90
          AllBank2PmgrAckDly_f3 = 0x90
Yes--
Dynamic clk pwr gating reg + +
    amcx_amcgen_amcclkpwrgate(n) = 0x050a0000
       ClkPwrWaitCyc = 0xa *read-only
       MCUBCGClkGateEn = 0x0 *read-only
       MCUBCGPwrGateEn = 0x0 *read-only
       PwrRstCyc = 0x5 *read-only
---
+

19. Do a ODTS read and set ODTS interval so MR4 on-die temperature sensor read occurs periodically.

+


+ + + + + + + + + + + + + + +
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
Perform an MRR to DRAM mode register MR4 to establish a base value for ODTS reading.
Another intention is to bring DRAM out of self-refresh. Done in both cold boot and resume boot.
+ +
    amcx_dramcmd_mrinitcmd(n) = 0x50041100
       MRCmdAddr = 0x0 *read-only
       MRCmdCs = 0x0 *read-only
       MRCmdData = 0x0 *read-only
       MRCmdIsMPC = 0x0 *read-only
       MRCmdIsRd = 0x0 *read-only
       RunMRCmd = 0x0 *read-only
       RunRdLvl = 0x0 *read-only
       RunSRExit = 0x0 *read-only
---
Poll dramcmd mrinitcmd + +
Poll: dramcmd_mrinitcmd
+    RunMRCmd
+   while((CSR(amcx_dramcmd_mrinitcmd(n)) & 0x100) != 0x0)
+
---
Enable periodic ODTS and temperature based refresh rate modulation. (Optional)
Note the OdtsRdIntrvl setting shown here is based on tREFI=3.9us and the target interval is ~100. The actual setting may vary depending on the DRAM and the system.
Palladium: this step is skipped, ODTS is not supported

PALLADIUM: Skip this step
+ + + + +
if (platform == FPGA)
       amcx_dramcfg_odtszqc(n) = 0xc0002320
          DerateParamSRExit = 0x1
          OdtsRdIntrvl = 0x320
          SRExitZQCChnlQuiet = 0x1
          ShareZQRes = 0x0
          TempDrtEn = 0x0
          ZQCChnlQuiet = 0x0 *read-only
          ZQCStack = 0x1
          ZqCalIntrvl = 0x0
else
          amcx_dramcfg_odtszqc(n) = 0xc0003320
             DerateParamSRExit = 0x1
             OdtsRdIntrvl = 0x320
             SRExitZQCChnlQuiet = 0x1
             ShareZQRes = 0x0
             TempDrtEn = 0x1
             ZQCChnlQuiet = 0x0 *read-only
             ZQCStack = 0x1
             ZqCalIntrvl = 0x0
---
+

Mcc Cache Initialization. This section is not part of the essential init sequence. This should be run when the system is done using the CacheAsRam

+


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/fuzzing.txt b/docs/fuzzing.txt new file mode 100644 index 0000000..7345166 --- /dev/null +++ b/docs/fuzzing.txt @@ -0,0 +1,83 @@ +Introduction +============ + +A number of iBoot modules have fuzzing interfaces. This document describes +how to fuzz those modules, and how to set up a new module for fuzzing. + +There are a number of open and closed-source fuzzers available, but by far +the best is AFL (american fuzzy lop): . +The rest of this document is geared towards fuzzing with AFL, but the +interface is fairly generic. + +Getting AFL +=========== +AFL is available in source format at http://lcamtuf.coredump.cx/afl/. +Building should just be a matter of typing "make". + +The source includes a good README. The following AFL docs are also +useful (in the AFL source): +- docs/technical_details.txt +- docs/status_screen.txt +- docs/notes_for_asan.txt + +Instrumenting Test Binaries +=========================== + +AFL is an instrumentation-guided fuzzer, so the test case needs to be +built with AFL's instrumentation. As described in the documents above, +this is accomplished by using the afl-clang tool, which interposes on +clang to modify the assembly produced by clang. It's possible to build +iBoot's test binaries using afl-clang as follows: + make TESTS_FLAVOR=tests-darwin-afl USE_XCRUN=NO HOST_CC='path/to/afl/afl-clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk' build-tests + +The exact SDK path will depend on the version of OS X being used. + +This should produce a number of test binaries located at: + ./build/test-darwin-afl// + +By convention, iBoot fuzz tests have names ending in -fuzz and take a +test input file as the first argument on the commandline. + +Seeding the fuzzer +================== + +It's possible to seed the fuzzer with a file containing all 0's: + dd if=/dev/zero of=testcases/zeroes bs=1024 count=1 + +If the binary format being fuzzed is not too complicated, this may +produce good results. + +However, the fuzzer does best by starting valid input files. If possible, +their size should be no more than a few kB. If this isn't possible, just +find seed test cases that are as small as possible. + +Running Fuzz Jobs +================= + + mkdir testcases + + mkdir findings + + path/to/afl/afl-fuzz -i testcases -o findings -t 500 ./build/tests-darwin-afl// @@ + +Interpreting Results +==================== + +Read the AFL documentation for details on interpreting the results. Here +are a few tips: +- Inputs producing crashes are obviously very important, and can be found + in findings/crashes. +- Inputs producing hangs may be interesting, or may be a result of the + system being briefly bogged down. Run the test manually to confirm if + it's a real hang. Real hangs can be a sign of a programming error, and + can make it harder to find crashing test cases. +- Inputs producing results that vary from run to run are often a sign of + use after free or buffer overflows. Use address sanitizer to diagnose. + +As AFL runs, it produces a corpus of input files that result in different +paths through the program under test. Even if afl doesn't find crashes, +this is a useful set of inputs to run with address sanitizer. This can be +done as follows: + make SANITIZE=YES build-tests + for i in findings/queue/*; do echo; echo $i; ./build/tests-darwin-sanitize// $i; done + diff --git a/docs/iBoot_IO_Spreadsheet_Standard.pages b/docs/iBoot_IO_Spreadsheet_Standard.pages new file mode 100644 index 0000000000000000000000000000000000000000..b3412e8732569d31f734460b72111c5955a69d37 GIT binary patch literal 137474 zcma$(30xCL_cNPa*n}ix4{$-S%MlGJi6JBeumTAo6ep-+3(bz&`)~?Mk$I9q!T%e5J&V|b8 zTGlM14{PFO^bYQm<_ZdsO#-QNFuGaqEli3Pop6QE_fzfoL+uDB8LU#Hi><(QJycDirq865vO1ya?&N zJ}mVVOYfEBdWz(IdlwdAc}|kMU%xz$u~%WfqGPYZk`nPBxp{fH?)+kTG4>^U^jGd_9EzjyFk?g7Yl`@CB?bf9xa86L#z>O>sX~x;VKMy6DgtyvbbN|U0rbwNS&DF zfkxwr@8%YW!2XnvdwKH2{)I&!WEB>E5YdWJQztagn-VvU6tlB)OJJB=vF^d&Jy=VoyOayz`OANX>9fK}_$AlKzEa4oCtt zwWzRvaU@ilExJQOgn|KLR$=x4stIO882P6m9-+9Or&n(80otZfgOMAr*6!7Q8!{dT zX-bL;^YS9L+1m-g*9&FSi{sxws0e>Ti-rAgvf$2x5iBf`PXsNH9T3pkAFn~i(s$_& zh5e~tG`(|+ic4@%NI%@K_fv%25y@%GXkewogvgIPo@Eh>jj2c#VE8z^xWrvlBKFTM z$&owAk|LZ&UnrZUYQbM9n=OL;G2um?j{rA{?F!S1w0lSx-&pzQabsNFQQwY8R3sPX zmF5?SZ6Xdw`J!TXD9UzqLYjPgH%NC0wO&(_ zlUtOnEf^iyTFV>76p$dlq_k+1JDMR&3i064-a&4$7}}iYN%4y)2(uqOWdtMU)=V9)H}uJL^lnOoexgM6a0U!J>{-52M-A4nPuc0cHG?wf|z zqgPgjgdEZU<<#EHdK5|72MC5SC~Nqf)K(I~;M2@Wsjv3w?`prJQ+tcXYJ@i!0;xV^ zk%ziLW_c0{Wx?G8MrhZd;ZnCgoQGP|L zp;_t@O|h7lTde)3&XWg|Pgh!y=P5q0Ngjd^Yx3PiA9yPEkMDpYsKu%Qx9_osSB&*;SpC`LLQ)6{tGqHcdOG;^k|g8By_z;^lrqj{75+wz-EpB2VuQsN7%m zv;B>(@V2L4i90I~X3Kzr!h!+$#i9;oK;@{AcB*yf%WzBia1`OXNZFUu?!018R_f~a zk=!c6SoF^UJua$S(s++!8NPf%{s@d&Z?d6xDdjaM8H5$Lz0StJGs3<^}uqdNOdagt_+OgE8Fauqe*pw zL{|JnraDz!Rma*7!@UKQAq(bWcExOynCdi&X{C83x&876q*%!u&$SBqB%sN(QDzMg zEh&76Ra4MM%q=Ouhg(wr!tTofWRVDh(Hs@o4`>GDdh)VUkCN_eIj4F`7kT>FAJau* zDIUEn2`Bqyz*te4C^@jZJf#iNmEtS~zW)UcEGwT(DpJ)CF#VQ zBx)x$AfX(i+|(@~hyF(t{_n`0{Ys1a6&8a+E-c6!U{tj8lu)TzeGwCacc(;L_yExz z-b>5sje;N&U8M!R@FIKy+0A|M@t(NcM1zX9w}mMvPo~{sZ&h~0oBceXYI}hmhc}E0 z1?emTT_$!cDe@HbDam2iDh1Ky?p0D)l(hxLMW znNo=pg=|l6H;kGpBy}kAsD~(;jZuQM=5`=;1?q!7bY9*7dzGb2RLhPg82kvM*e3RE z_efNXsb&*=V%8&6?77PKf@PtPC*;G*J2%q(c^^rSWbhqLhK^BIHBxB9`QD&Y3;UNh zU3NEcn1b{aubi3E_rMBCq333c{X9j~7F}<5es11?cxl!^rUs~nk;Rez`82!N2e}Wg4-#S3D=5kBz42!aXz)IsMF*}W;*0YADI4fqPjSQ# z=6|C2ei*q!z7k4du`epjr|gnymzyees&*^y#fKBurbr3n4ZIiyER8h7KGaOHxYnpc zC>nR|*1=8ld7eJ*UISt{ii!(d;(OyHDy=HyVIx!E>2Do{j47We(>t|H@15l>^efHF zEA7`3d(+v#;qQ=`GL4F1uA*W#+}AjgpcdinWO^sO0p;el=RpQxNjv`=4I4gns2cx+ zHk9^bKGVQ54GOCoWoy+a{ro9)ly68S$~9UL9@)-{Kv7W6ig(#uU;i)U2A_Z)Mh#hM zFcrdVPKVmX(tcvmhY$SkD5N>ok=hfo8Qx9zrY6v^4&Vsnu3A#A$S#gow25xn#`1B? zHdcTb02@GTdb~ED2dQe=CQhZ&bR8U!y= z9jfXrqbqySJvw$+yECAB+8Ebj?AM7Di~Td0@=K1*l)9|(LFv|m5i^rd_r1nq{c;sB9(%l`r4Q(MNIG*(X!ZcL+qx?1Fdjy2oDU`}F>p z3K$&Whm65%j)eq-lTJ_HAg{Pzy3a#Bezc0}Z=78pOIeateYb;2{9E=wEPvGzDZAmTQ6_ zuEKAabWp$w=`rwJjRQ4F5ZB;9T`xF2jKT_<9*yNeG)<4e3Vt^SiBoX^nvQ*8=MR~4 zu>w`&0C6t?4?oG^prV7aH?V>VcjYo~%$Y%gHjed|;4_E>{Dc;n|wQ3Yt5L?a}J|E4KWpB1tX?Zv*jIYH2xxj~S!4)a=pJR1xYBx0TT zRc}DI58&10;1K5DXb7a`B48mk_kCM0irQ!WkAQ79jlbni__z7YvQwE^;W8>oR@%z+9o8foCP2{JJT z1A+mWj^#=ee?peu9DQkj;0{0sLz<*qM2D~<|uQU>d{{3ys`eEIWD0Da`=%RdkRS>#?qHSEPJ?7DwkP=A{JXPcx=Z6cV$%9V2CxKKnLtEVK&{=q{b|;Ekgmj$w z225{v>ku3I)@Z}zRDZ1vWx3x9DL`N2SkGJZ39cxW1M@t%V zuGi@hZr*=%vy94R&s$iqz)5%kwkJ~`UtayU&<26KwpX|P!BDTX*}wAtV=SuNJ+ z*y!X~mkY|DkjhUDW5Zq1)~Gm3oXHR!V~#RdEDn<)F4^obIAWqqw%BBc&1Nz~`DtNL zekPQUO-_k2IZQ5SkHu=RM46)vj$}u)!DTZg$J*^yht=$a^0Tn%cJ~WfHr#Bp#U;l? zyA0-NJG9^GN-;PrF)oACWpc#XtSM$|vIWXt)B^qMP~PP-x#G-@Sc56X>@ry5tTuz) z3GFe(M4L>pQO>B8WD}IX0p&wR+|CGhIHRnwalnX zE{#jE*_u=wzw4zeHAJT5)4c5J#_dg2nCY!2Hm6 zIXy8X7BYv#YEZCb-xQGndk6W_-%3Wi+o~3(UQ9oIvG!s%}~_6>Sw z;OS5l=l?Y9c6u;aGqIkY$Da(C&sXxpFdm1|G>qn9v=pN?7;gh})Sowv90NuMBH&w!(f~LYXU<0LZ<8TcH@vm6U z#;Md>RH8RLt+c~bQrlFzRd!$c*8t%4l_sgnlwd8r6|X_$#;_O>q1*8yB3Ib~C6@=r zKytMeLbNj8gwP7J3DLpy{P;MT?ihcZKgoZ?pWwfCw?xN)HOB!Y`~<`&F{Swi*mSIR zGImVHv>$!Ep_?Zg;%^$_6Akg#5CeOFd}X|a(0$K;%m2Wi;=kih+x6&MAo(4p*vCqA z+TIdWJ4OG%`(b%)0Obgv(6_ahkmC}9T7GDtcB&!%t|30%K%Jw1P@mH4JJM*XT_mUS zY)6{h^(lm!U7vFF>G&21c5E%sbO#{cOHb3_X`1x(o%FN-o)!QSP6#lEWD*BPqTM5 zEMo|rMg!Uw!n>NxX*3;9pX@zEF3jXl1kB=RXAY5*GkGHrL*z=ip17$_ zlDo0yW`Hk!(_Bk~1k8$e6T1EU0e&yPkN=Y2WB&)VX)m;CpZy=OH>F^|M$uo^waHC5 z+ypuh&*0jvIAkl@+c4n!q&iiEU4_1ENZHdM0>Sib5U|KvzRa)O?-@VPZ;+q5TNFsu zGfY7mu(%v*7zhG9$j^_itsRFP<51oF9Y#2Y5oEa^5OTr9eHQ-|DF?$gE1@+-4(3;V z>V*PB-ba3+ANYn31JyLxZ!|xF5AElR0@eRAlcHT6YW5!#%6<`=4YpW==qv;iX^H5} zEr!F1WSNwM3E@87VVE>*xAAsC4FJ~O)JOofdT5TX*!gn{kPN5=_YcOQwjV$ zSlLf^h=;4Cap@3@2kuS)mPabs{tdYlJrq;kXq?;|O#)aA zPz`VZ;48T|IfS61&@6aZ4zOPCZ8`uv_M@kyvl@D^CgSv4T0OZJ?ttiEjZ8qHzV_xv zBGpHXNUtsojx@uDgNsE;@WMi4D}3AU-RA}eeDR1H`*Dez>pZz5}}~-B-G?&m}LQ}R~+UpbC=1A9kxY0ToE_R+Eg*w>K z`yP?d6ls91ie&a;^T0v6Z~Ee3TZkNqfj1%p(s0grbLY`vq`v=+5Oi6c7$nlLUNRuS zm$0f$FwDf30C50LNY8*1d~@2H?#_f-+>rJk*w75a5J>VZ$@Cfk(4FW@fTN&Vh7yn| z3G)g}ksAnoERDidgU})Msv!I+90%pN5Nv6M%EO#Pt!j=&s8`6z14QO7Z&0iAjD-Yh znpTMH6(v6(kKY3-Y7ifBuS(?dLcB|Xav5h zjHop=33;W`2|W>-D2YG|l^HdmCL<=~gwSth zHA45LU^iC##iDXE2<&4Vgf1}|=z)|DhXCluI3vQ!rh0NuWShh;HuN$boaV;gjAEP8*@M&zd--F&(_#*UO6y+w$5t0_5EP><6h zA>kTJ4%5a+i@17G7&$E*P^B+D)nDJMsm1_1%!t5VO|uNGBNK~Dv-)~^m9*yQGwSXN zeF=xAxLctq@m&?5P1nTVY$|M$w)&gQ)X31AO_kyFDrZ(z)1WQRtRYiWIX-}52gi9P@uc&WNi9<@k$YYFwGZA#Y}hu-GhBA zx+`s752hJmZ_3eU;Z?$$;o~U~pn!H)DEyJO5(M?W>De{bGEF`$2Pqo6hXz zu4zuQ7r2?s45p0#QS%e`i2H?`&79RtWgc?hXy!1rApg>}{xs%yxYGYtbB(*Hxx!u1 zoa27xPHQf5ziNKv&TGo~tD5uNNzD^(E_1bRw#;Mha?iLMnpw;(m_v6p1DP|L?=&~L zd)&{OUo>|#*I`yY=1ypCbEh;@nC~@{nJ>8On%kOz{C)16=9cCu_akS*|Sd*4fxTgi7?sA66?};-A_!^);vv2H0->am}vDAV#&+T z60}cmK1(p5^Uo3>C7d|?X@b`4MsCTLgxU`#YTHkC^6Us#o( z9bV#{XqdIdKUfH1MD4}a?nJ|m+G@!CwM9{)_Qde^iH0x7If4bt<*vOFwHrT)O*AaR zX{`coi+h{Cov58Ok4sbwyg3%@$`Z9z-zFs*t}eY4+=lu%Xa%EBH2j?27ieAYlAoxZ zweO8Y!}fV`K-1itcH9OnPr-@WAv=dB7&bkOZN0|yZTfc! z+K)cN35JSA()){VFH6u)%$e2N@YT(4q5Pw#{SvhOc7?PyjQY<+xzKOE*Gz>XlkEbY zA)yLsfDgK06xJJH6n@y6_Ac_XkF!rkiK_6nIs#_Wbt;^CAd0Z``dvCWCCS_swQWPV zx*}INF`+BMW${kJ0cj$!xGRd$)!{*Pcz7KyNTu4w*5N$Sy(<#f&_Gc`1lpVTeCMk@ zt+j7nQ6w7fk87D|J$&fhL^DCFlTdKDMfLX41nu=o1B_&o)(M@%k!8^F(nRgKnC^*& zny%HYAw_$d-tkmj`VC5Q_@NgfE`souzUqgsf2X7G_DAj;~r#t==gW!@jhVtMT{?SQYLSS6qJTNg-glb@0 zWI*zmAlz2rcj9PNg0|y-S|L7qy}w;-275KoBxMO&+(ZNyr;{28z5$)qaPR~RBgLQA zz@h|4Pp~Lb|1}I?N_S2J+rIOXv(yWf2qhX+B7a@u0ILin)Tv^K8&omqfjeI3)!{s7 zxu;gJFrcQ-Eez-asM3pEsCp8QLg6+=39b1F-n^o|^&YyaCRlzT165vw6VX=6lhgST8+>{fJXog%Mp44_)~!20d@n_ z0>BxGF5~0XC+nz}V})fPU+vut)YMD{fD{!8{-b{)HcU&U9m=On$jK|Pv7 ztJHIv>Q?c7L5692XJEJGiCHTwkO#N+R4Vyvs%b| z?E05pzl>eTu43n~OWDP2CHomWn_bS%W#_Yt*jelXb_F|=oyX2#SF%f_3TLRRZ2U|X znh4$0&1Rv}IV@EA`h&?tv2jhdu*XiK#BD*mzAZe0yJ;s<-d& z*zusp4aLDV96cjG3dgQyX$tCE&4vN6&00q}*?qu?jqDo!67XRsdzk&++7hh^0f2ZT zE<}d`{~q8Hz&>kBVJF*@Y6ZvLmU!NHb}~Dhox~1hhp6U^KuOJQ1#wC^Qb>FHUt` zra>n&KQHFi4Ni&Jnf37AoI?Zqar9JZR^&jICZLl8p_2pQS+^E?xQG3b{hHmL(i3h? zw#9cR&?P|iB|L+sej9u&CCjBE3<@I$E;#DFGRBTj2A?@G^(jYBgQl5IFtiNn zI>BfGV#dna?0`-lW6!c1`3vk?egl7i-C&JEYwbPJMhQZq&@q4w06PE<09>#}31``! zvR3q55RG})nMceM<__~K^Ne}O{Kk~AH<(+@@62Q7K68_K%G_oiFn5`IOf9^69pFYt zWWDwQ{C0>SZ3G)>fjSKkLjI)&Xqf$7%V03i4*!gg8v1tE=`)fNPq%wJL{DGkYNreE z_jtNMx1#68e}d;7Wonpe<^XeysbUT@JDGjVA?8cwD`qcqoY~DBWR5Vqm_5vX1}si! zC%_jWrC@iWP!-_Sa8#AfPLkT$10boXeE|DI(j?nY-I?kj#D@S514!CW(u79=j=^Xg zhtXIx`O1OXwaM0d z4!ZmT%~~D5;{fwk+iBxA1y0DSda!__r^IK;Vh6D_1|b>5wg6y5ckI&nZ)W#{pd5wy z?(QjU;?J;E?B&wzMZ4iPEgNkD*bHzK;0(ZJfc>S}LKWK+bM)l+|3i^Kfvpip{seRD zr+5_{Mla{<4zgQ8cdTd6v!`M{MyK8ad-lh`>5tJtfKvcl{XQ1fvpvBkyj|Vdie?1v zV??9@FJRV(o~6<#=V2PFtyZOoby(fPXIK($gVJ#q+!KRC3i=qAVLS|jMgS8HHZI3- z7Y4J2+=l%}$I)NnaQ|-FpmaDr7K=`gx}cp-%mAmJJaC#YmZ;=G$FTrDu2BXob6PT@ z%<&deyb10*Voj#g*w_EkKS+ZUo1Nf0c^kt@g~|vtj8K5naC#$8>548@k%6$}OAr81 z?ZMP;-)E}ruL+RnyO_@C|;qO zG5sT_U+>geesxsRvTy9R+1G58#T4|3f-3SJ2w+$eFQ6oQV!yD&%vo=DP@R4Zdu zuwkX>yMlE8Eg~L&t?{KNLhpX=IRSdT7cS@_hZbplnj#gv(cc8KIDYTBRowX$+E&)w z8AyROd<+)HV7NIEO*oL0F4RLQuk^Mw{S5wr#VDQX0;KdmV@2Cf(h(0A?LOjkoQ@Uo z>0ldIrITYYZqF;;g-Q%rvyjdUuHZFSm14PCuky)k2lo6a?NE5RT613^J`nU?aw(B4 zSL0b44c6}`23Df*2ZCmqOq?53m)jAM4+PwiRJ`}eEfhXCNVC&hJQF5m#RD~^p|y4* z)gEPh(jJAM3DcCx#52vM%$W8_+6L}TZ`&FDX9)^A(_C}KOWbY1ov}|$XXI*+EE>|Z z+u#dDK-@N&QkT4Ig+{9tluBYSOQ}dCLxFNN3boHg-=)rdOXpiR&{8f8CHjMyUyond zSqt(lK~u=B7xQFyUawM^P~eZ8QqU*2pk6vd0??A7`1ZRzIPbH*^gM94kiHC95~n9- z@a&X0g-6juvwO{z9AV+b6$4e`XJt~ScFKg zmM(|P;(tO>i32HmD+JAhCzZcpVchl4W+=sq`z3XgdO+2Xdv3$^rL^#L zdf5cEICACm3YG5Qi81@A`rM2o+eTfZgl*F&{Y;CC*Y2N3>lQ3N`MCBdaveoo9)B}t zEEZ~xtz9P*KYzIKCrY<#?!z%M$aO&OXH{#5DTIqpS6(2+b-!Qv+*h~h?2;uu4TKlZ zA6w-s>{&E#0wr!aHU12(8#{I24akhiLGC3Pzw9}$6{g>szKsyemp$A->%Ka6@us}? zE9CeJbva-AY!@Xgt=_o}x_fQhuavHA#!nOJh7K*gH*Y93dFs*&zT)DEi#95CJ4P-# zsA#Bn!-dO>Rl@hnXFXPn<0h~DU8Ngwd~z8yIp!z|nVY_9Q$>KV@3Z+MC~?QkDTgUt z^~#!Owcik~Z-|T|Q_kP_6@Iw%d9_;H{^O0QD&3|Z77vCt#e9V-S7od_eR-^xFzUd< z3ot`ApFQWRTXFO9A*j}sgVI-w+p$U|%vrh}xV-7vh;81w?|(iBd2Mr0#^o_{56gwM z-)}js5LZvGoh#FA`1Rq9+C*7QqAceF82sB?_Mejr_YO?^(py}9;P4%}u4d%qrM|V_ z67PR2#Dg=G;6PM=IeUauXgbcn?K~id z)~}jAdbzLg^T?euC~^D91y|L&H7AaKO|lngg|DQOOt`IgdRf_Ex+jJNaQ10P7*?M^ zs6y%TvNCxnlBpOpkYNxB@gRsPhzCRL1#tz$-Vm4J{u&C%(0&X#jHVbQ_hZl~IfE1s zkAv7p#Zc3+6DjLr2B{iibwlji5Nm+g5WE~ShyiRUkY^ztjv37xK%N791f=m$`iv$V zQv3juO8Ym&O&VeWN{(bYfi)i50dE9CJR0Jrkl$a!z?(r525$y8#LXJwH&l!^1k%NZ zIHVyCZHU95+%SzFPzaYWD5-6Tn>WNQAa;g$;PRush6so|K{zk+m*nP)tK?gSe9>0*b~0 z<^-Z~4RL%!+)BlGPHR+9;w|VH+%=)rP|Y~z5K4j){c$w1*ToESG{nhLj8wJ9Rr=$q z%D9XPzZ}~@2*Xw_2kkfL{*djY?%33g_i8h|f6tH%2SZ{Hb6xg79eBW3C|k1i4ka$x zJpP`K?(Vi{Pn5M~Ugk0{a+CS+_4JA*H@?Nfl>0-!B*i7SYC?3=Z|)jj%X-DIUT8`c ztL`iBGH2SXb%b#6+@i<6;;<_f+tj)}E9MPW*PcQFrvl4-GsbU!FjXOppFQXTAx^us zd4pQF^ZRilYLClfj?2|@pY*dw=4~T|-K!=~@DgXNKlFxf`LC0X)MB|F%hNRC(q;Px zV`22E3iWEWSUG#3uWrKDX%lLj`0AVZs&nO03o{mN`nF6dJotLTe3dx;i|dzsb>AJS zsj1D-xH2>uTfV#U9VPs*dd)zYxM0vv=VZE?ZL5E%ZH;4EC9b$Ua68tG7`x-LPpw1daL6(a4ZHNzM;N$&$Cs2i|MH2a-n!#I&e{c; zF%DTdn=$I_54+^T)+h4@D#iI(* zxD-Zm!@Z*sfC|}H32NGt_FXo;R!F*;Kyba zF;XUY=XC#yR|3Z2o1NQn62^w~?!2Hbjlst{|GTan4dwdtQZv1Qhyk!5+6&VD#Yq?i zSkt<4Bw&~2Qko2~{JLBMu&_GH7-x2F&PWYFY}Pl>&ZgiH+$57zNG}9Jv95Km1_Ndk zq}*nZ3vTa#sQ}yKBb8G_Zr{3czJPUr+#p&57)=X+1+juAbEmhI7!HXRmDD3G^ld_2 zT60KiQ-`$xthSD~I>0v6VG)3JQ%UdY0UHKsP3bqG;)J@~NJzU!Nx25VmQxvlV7B5# znZDlh5G+eP98VSmZVz(8E`6uuu(^}h0Kn;Pp(=n})wFkaP8S%hXsIyJ;m0wlc7Rt5 zL?3XP3ph|AbbrQ?8U&Y&B&nGKw+~plZ-fteNJ8^TUxbLZ@JRj#0-1z)0cMtC)m%hN zX;fP%qL45z=`|ukju2zb{Lzopctb)$G42k@w3O#H1B%KejGh630x&~@^-TA<2>AeI zz#vum0#m)f)Gsh!z>xAkXE4%8m>TL8m_W0_sEEwn25UNYZv!7Ld;te!O%O;8+ZJxR z`A;C=jI*I}@*L=$r93qADobj3s9!Z35mMXzBx-ei^p`NHkElso8Y6#f?fVwEY)OO! ziBN!q1xi?;@fb>YgUrm7lbWVLE1^s#bsz``l$J?Y@C&Tj3+#;-nD_zp`R@tR9yLg+l@BQVG+(z?vJ^5XS4WzJd(3fcyOXUy$;XO9awE^D5rx3;m3cux5Rs zp?V1mmasPgL-Z#{5sH*Bh13m$gsCOWC}A22Ybjwt5@wRHW)c=<{E#rdMO5iBC;F2b zGqeto@!h^Qz;{ag#9W=4*J^jZvJ@G(tP<>!y zDUIa07$}OAzWy+1Rx9N4u60L30y!uZ_#MNQj|xu2C>9RUF-i@5rYv942Hdd5f&&t0 zH|gVTI7EBXcrrhhH`5BQs$aqFL~=sBtEqEBB&)HXPml{5!`kUzRnKmhRug*5W!uQu zr?#86A^b@GhV80tJ$v1Dn!RoN$#%(h-!`7#89R}`WgEl)V*A;4%{G?5W4mHggvXg} z);Nnf25d8NHt-dVjy1$aJM4zoD2vS*WpTth<5Hl@J7Yt8N=<^+J+(n_%@!zE$hUUA zYy(@yPd2b++_0Ht^mSV-PC{+H6s*?wwxa{e1m}KR7Tg5b`pE`@ljbek2nes*CP4U$ zZ3cvwY|_W(H*F>o?y}@{rX3O50hSQ3f|TQsUY4cXO-aKg%SF#l_uD7oR^&(?x5^p9 zOYe>6mqR$F&Np;yop0zw{x}7$g_QE$a~STl@g2xN%|61ojKISQIKt!X351NkW19it z$k_Q1u4mUlc-yv($l{sw3j{%a;nD}`w{4JgNEM0b zkQ;&sPJeKRjfG|-HSVXGS^>ULzk~J00+e~5;RWy>0&j&-nQ~zG^zi&p5K@pmgfbl< zd%cglL+N>2liP;M5Q0EAFdR5NJ={eP4DUARcGq1nsAI!Ng+C3e4O<=lTi6i(e%MH` z_&p0d&6bCc47|SPNFqXfCIR+6z zZCI9!ei)WIh_FV3|7%-OBk<;lA|P@XnnGxN;DTorugIjKHXJtVi3^rrK*VYa{J7Xl6nr%6x3V zk>EKNi4Ll|AoEA@6k?XeBTY;^MNZ~pY6#_F{s`Zx2AtLW+%+37lSzg-HH7Z41 zTCOHwEUyT+$E3JYEM}7-HYO^?V6j=E40e|#)&Oa-c8A@bY_-KeHKU+<;b$J$wu0+a zlk}PND+?<*VB0DV*tV8))DXfN4%oJiORXWH>KbxA1VO7giESGIRn`QU==W=owYG*> zTtkq*@KEMD|9%a51F%fS*sX?t0#1}S_|7#1x{d|llHEQ%vpB$>uY3aTzUEs*=9?zq z;4cZCQRa#O+!+k#k?m`cCavc8@4?@tlAwR$ue7Tq#OQB(B>P=`^0{M1Hkh*Qm6|KS zrJoWiiST9IQf?kF=pk>P-gR%ld~PwffLji}pbNRD0ps~fZV5M$w^s%|;D6&E@ryWn z<+xa@HQMEfvK!)JTp(CcmNUZ`~3V7j26++0B9GN&-EwSE70ESE5RY=L0MN zSnPs~MSv_xt3=CFD$!Dag#gP^D*3$upaEoSvyrW~l2{A{A40~XZk6b_l*-JhA>Ar9 zPk|v1?cT=WL}p%?JsLet0PI8nFyS}cxhBVhPPLOcp!G{86)WQ+x5d|C~flv0Bx0E_{c z2(Y^{8&NR2<_^$ugl^R?Rk)Ta&@ITi-K_@wno^Uw$lR?)^Bb_}S9?U;d;+efh4%Sm zQ$_b4&Fp#Tw}jKc`p&1D1GjD&JE6+0nXDOv<|vMATTQg;ad-v#SGsj#MnTB>@gOD zH99UOIoe`1SzT7BW}gt+oF>N#>T3!lp-Dpom}TVx%(7tu%(6j(qd6@M6kwKB2>wuX zsGx>$xD*Br7Nm(bLc-C$%8F2+Vd+p!)b>?%=&K@U*OlBYG>7t=Bs|m0)~#B21iafV zurYnX#@;z4&fW<NTSn$xO+oKH79{PNzOs6M2jpZ!w<5&EW`iw5yqu0jhd8GfnRMK3gWt5O>@ z?~dh{nAe!6ndg}onCF=1nuqW^&Gv&qr`a0wcz%}IUUPM}d8T>3d6jvwxzaqtJl(7a zx5PS9%moGt}WYZW;Y0?iz=iHZ$1Xvkf{){}n1k#y~JV{%xAR#$Rm*5i0wK`fXs^90;xgrn$!Z z($|)^@S?qttf~cGhV;#baathCsz=I19m0DHtRL!yr)Z4={N(2O3ee`>4hH zDDnyKCec$pWdAOe8Q)oJ`ZuY046^q$G zRjY^DVJ8@8j)Fze83UgOMa4SdyDTd(%;qvdda@sGC~&u=4|WFB#J ztI|9K=G+U}-#(*qP-iB}z6(7x?jqEu{4&=>19R>JbE*jNf)SW}w=q+Z435x^@BFkS zEv`PlL=1*)dSYNeZlgq0Kb1A9Oy0m5KfQuj_^omFylKfCC~@5aUdmqU+)a`rM=-np594O z|D8SjvIGqYKIu-1$$<~<3j+OUIVAY%>V5+yLXn+YEM1W{Zn16nN8kMoHkhq1vtgFG z5gVYE#zeQ-pJYkrCJDex_)mBnQ_tEE@HPL~m#z(aiKZ`f*(*>E-3d4{I0|Ob-&|P*gC%~J7K^x8GL?3Xe?$WT}Ehr$I>ap1UHVrNA+v?xWOm&AJ51B zFRE-b1Ma^(Or#`WjagIq#Wz=qpbHZGIZaDkT{j94ID{_Sa`Cn)qOQY#F^yNB9 zY1%g?y7>H(+kbYH*a7sVq&(#>e#N6P4}bYCH16+ox6x$S(73y=@bI%{|9tQ_h(?*}y4%3R zC5?%`!b9p*a?`&D4fV409;{)YRN>V7 zU!@9b*k37CBm>QgNGYJCz)MoJ-hZNK&wCB~{&`>jT$?mroYptyAFPRuN4jFef$g=> zMG2bxv8x%md7g&8Jw|9MJ5NJjwn2C9G^`jyz>5pM3Zq3*zg6;OAp%V@BzraqIs+>f zP{WdwN3a0bz35JolnAsK!wE#Eg^Tb8IEoO@ z!c#gRoMM45ACrjJ{&h=2L_!jQL5}zSk5x2hmAL3R(LWa$ zTO;-QsPU5aiokUEeb#jlbR@ywnj7_N^gCdhgt_tf<++jGcy5q?*l-{jqk^x!eQ1(V zS)@$r`MmhUfGAowYxTUFe>EV{FDsUrjdyLYXsd{$c}x7kqAJ1bCq}(WVKExS!Niy% zxePv^7;Rhri}u~w}gZ@%ns9^%#YLc^W&5> zKV*UFsp0l^VCNuVig-VtB58f?@5(UY>-x%s0UK(>^YQs}F^p}rAn*GhqK#eE zBcId!i!qOGw3v)@JgIWf|Bf;y(ynaqE!f0O*jCtA1W4q2CGaAw!kf6y`JPzHY~0dUy8qk1{>}UiqS1}!_LY~n zu&>z{`)3WFlnt{$fSqb{z6Y%>qWVt6|>E+ZG{?Yg1Pd%6)&H0 zy`P_LVT@nXivBCOHf@0m68x=AOZ`^C1xEnbw2Y7j@41yE`T3^h|0S+gOfYS*1EAoOp3$ z`3s`vM*F&_jhDVxo`BKZaM;&<_VT`NOgQx48}@bdtB2e_ z?&X92*8%q}IN(;*A8=#q4z+3V_8En5a7y=fKfnbPlEm z!YOz#`Rd=}!K4xj*Bx)kv?NUb*%^2Q9D7OW5KR45ssAJqN@y_Eo0P+`0z%mNlk(U8 z1(I^)l`xn@UZV$Ny7OSNTheRG-6ZAyP}Ezh+xxHT{shkOf84}*r@iBTe*FCN>1eLk zov`rqfkkcA%Zpn37mFGVk`1Erd^wTKs4o^az=`Ke%Ig<4*(GxhELTW^zYtVYy-G|* zs6DjghV7+=t<{T`_&`hQ7p^+X?sFrq*Yg(CxAKn$+v;~u-})Q#&(vr`ceU}}>lHOp zJ8bo`zd^LY4BW808T7Iud5szT&UcqfMgpHC`13)t)U#?Rf-i5sgB{(=L_dK!s0M>F z{HGp)$~IQ`Rbu#2V(B-D1K~$YA&uw~0~qj0!CL@%=MWlufq&iE# zVhxEhs>!IR=hsJdKXn|)(@LPCZv4aEjh7|yYOl7#paT;8t!1f!M}y%<<}fG~@FDVf zv5WW-zAJ>s7ndzB7ACt&MG}6&s+Wx)*wSDegw?7A@|Ns`v=qptKp_P_QlOLql@zF@ z!1w>jd-M1vitvAYcDpH?G~FbdZJLHQq-hh{KuUU2Doxrz3sk^T4xw@tXgP#}g(9Fp zL6Aeif>H$K6c7+pK;)1cMJR`eaw-TS$RQ}FiW+|JN!r>7D4)-N-{0r;nqzl%c6N7m zj%S|dJSKxT7gO8*g$({%j!VsF>}%MV!# zT$X;%YKLK)dVGsNF+ll~UY<@HhU^YS9WP2irB*Xx)`p_daC!w`hF&HNTZ;+fsDrXl zBvHUq4kaI~Cjn`C633AL9K>sLDO)wo%mEiBxJ^^SWi{m~n-bgHFnI6`!|@r6@=?QY zW=1$TIdn|Vg-ZW%uV&@|flWD)S>R1}>l#M6I1lBqAhBB&OD1UA+hAXMSu&J|Gx1Z; zM(&|*+C~iZ$f5)fC(wJtqlzBY^}#XM$^Ce?nzVRyV@dI&Ek3OMU;m~p#D~xpbsj=n z6l}QTIgVdL{l7fYN2Y&8p!??+=pDNkh2LMjdifSzOdXD;TwV0+IzGMSx#;KsLI1O( zdj|;Uov9umu*fj5?Hw2@f@BJHJYpr{1jNCJ>9`^wrUQ)%aWZ0Ta8lC|NQ1aBVlCoS z#F9+Wvl35fNG6A_2WgBm6wHu$n8`;R^eVQU{}p`GBz z<9w<1qL}h+{=xijKWEZ2kJDrQRwBRp4+9S{(PsZKpL?7_{ida>{?pO}>*Egl&9|zX z;J?kbzGY+;eS4*Lp?|l*e~2Ve<<$~P|0?gi>imN04|#MO^k>4%tKIB5IyL#1+2*a| zt*cj5k2Q%@6<@WaT3mZ=Q@x~0cyb0^iOSISnUDhmy(>_)q`V)w*H(a6`YCwH1iniA8E+8yIuYs&$AiLBS!z=ieXU2zM(=+;;cpV8G)@P6DQtVU6PxGCoYig86lN zS2p}K{nr784sjbfNNT#`7CKQ6*vPdSk@=!$3-_SAzJ;5%<$-0-^0AFuyYPwBKi;_E zTXk3AeD2m3yZr;_6X5-oAQK8MM8Ea^9RD`@z`%Yg#rim0=_J42 zG~b_z@W3FVO3OI>--xR!9zvuKaW$d#i&Df@fOle`N)G;sxO(-^=5wq2)nl>6d^J+t zt>~m&%}uQCR#luZp9r-2#J^jOi+*)Ai!Md|!@HGlpoJvgE2)23j~`o23;&y>ULS}? zg+ig7!Y8YT5b1wJ16N7v8D3o_r}q)Sa`dK0QNNJ8SIg>ax)B%}4|BC-^}GzbLMV;= zP*FV+A0n+Us|fn*aayh4s$_yc;q*YOy>WH()il%^^^es8e9bon?77J*{=QhN1;qL@ zMgwVYguI*1=4>_p_#d|J-iM+1YQd-!kgiv;G^L!@K*Tx z@GL065_^JUID+-#rUVDc62WZMi+5SC4c^UQ+W!Q6W zXqNT|PH|pZ*uQOGEPHlF_2>Qz`J3psBw65JhYwI!UnGC_PIaM=u0wys^d$c>AE-mu z3#~qVjAc%uk4~>z<}9o|8`5Qt%sX@WSoU5JW|04?+rM&}-mjcj{T=^OImv$0`dj`V z^1#Y+|E7b%jnNROf2_vfYrcuT0df{Cy?TnQ9w1lxWNF?hlCriSZL3Q0|DJhETW)v> zkEQ-!zQ^JFp0R{XU=FLW;{%VZW*rQ}8bWIb^|A^y?Q1aQCTOmQEj27ID8LdnB71_n zfKUG$oUZXAF)8Rg_3bLqITbDc6Lb!K17$JzpzHo`zj{scm5=c^68-3*iU098P8~`4 zS%n#%`bRg_s#X=mknL=_ntzp&<<&LvKJ@adC4KgG@~g89~c3{aSWZwbj9 z2#dZjrf5n~Fm+<6LMBrpt_7*%@Dt+0BEajY%PSIa;s}e_7!Npp9q_(XFkuUex2AqD z5=f2UR!iP}qWLT=(`Z%mGL^o0W(S-Fgs5YhWw-FQYH)&Orn2mgZJV{vYHd*B1sOwN zGq1^Ai1al$Q#@5V%mG!VCI=G4V3EYj#DVb!JFmsX`d)cIr2cTjOeOuPDOFieY7wmA z;>ep=P(0HA@6;uIPK`plqW;kpncy2oh7+huJfY{OX+>>KMb2kzfv;g6ysyQVsnAiu z(Z*DAUyDQ3WA$MWCMt^K7BFen$OI_Bo6e+ONrfy3CIuS%#PCRav;=;|t*Pef7WL?N zt`fjkG4yx;hX7OSxZ9z+%zx=)Nq$ngcWQUBhp>7(EIl{;F$zugV^YlbZ~6~RpR;5C z$k!MAy(Hs5AWEXK1s`WQ&b$5AzhGQ)`fM!Zrm-`|);3SLaA!N9g8 zJs*L7tYk<-h|#A*#Dd36U|Lx+$AbM6*v4Yg;wt8Se}Qr68rR-W2z78&T7 z#Xjh+%wkD^8-cvdEF$7Mj$4iFw1$P${9*Z#h>RS)L(v9yqlz=xPT{0jkO95>s2dWH zSw`;&qIcxur7~c&go>6<&Mdd+LKnI`|}HIKbf z?JZ`x>~VUH-(>K!Kg0TgaqC>&?(WAa)Ne5S%U_1_z^wK8Yu46-(Uz%y^blV)6Fy5w z|6iJ`pkARC3EKsoqYB_)2!J7NLme;3k?B%RVO8%I;=L3W+jcN=1Tf|o+ad!th*iOl0K4(x;OdIuKQSSPUDA&@8s zr8Q-tz3}0Aarc-GweZ-N0*M~?DARCrSg<~`gQuK(sGA0Z1kQ4f7}`XWU_3!clJER8 zvuWHw7Q*ib-^rJf+2L<2HYR|GHXVS+?m(nA$?bBxvrxQDvoLpUO*xy&fgBtA3` z5(glgf@X_qle%-^qnl8XcX2#`nPOKn$3c2!*u_aEtqDr;sZiG`k;rp;d-nA zXs-GwY`Om5K0rmY#UR^W!@oUKO|!)!+qaL*mY@0{2H@Svo!M&6#J`M4KI*KBF|oAv zfaGILQ0Y#vKR2Qlv%-ID8UOKLBW?hnLH*y4Y(BVmDb?ZJe%MGTxb9b2wW0YMEI4mv zhUlRe3ahOd)ZjFF?Ig|?_%$rgd`0b3@5D;*WvT;iA5cQCP({_-U{QkVRj<;cF0E;U z#HmaSnTW)_jKu9uVC-sYyK@Gt>rOx-wd8gX=5%+!oKYWG1dvEMQmAdW-AtHQKReai zPIb5+fu9B&z@O`JJB&L^A5g2!mB{rquDrrXeO{A9okBIRVC3M^VfLZ)bL`3SB2@ir zLG<@YO~T>VS}3UaS`7mz3f#O$i=;Jept@;0Hg#^(+NhoAT@YE}Z3w>3t3%$aH=dD2 z@6+0-oeEe?WM1=HrNi|q{qfvPN!Cs}C!(}hV7~cNM$dhw#SnKAI&`MX^{5ghnSl%E zplQ1t@or>zS(5c5n;2z>SE){)&-DmCph}T;Q^gtEQf0ZYfteaTQL=^Mq2o1TWCeZb zmrRMTBINC%S-u7LN-m78y}_9I!&+OU8%pN&u&AJ+_2-x%IT#f_7!$%JRV!0!vLaF; zZ%fs44>Tn-7E_8DREdr1{mPZ)V@`@8X&mg3F*ziks3IriXF-`-S{C7w<8cW4t23$U zzaN9AhNs(Dn1)swB1dy3MxK<*6k>EIg+)b083-2e~B69 zvr;skof^Tb46qgclq@P~@y5kY%aSdNo%RJEEq2PHpq`wN46OHv9cEZE66ymjBq}kL zS(w$mWP}r+^0Xsq?Vw2yv9lfFO)i7yH{x^0euKoS=Ij*C8r44YoDJ}~GiRYk&GSo@ zI|U{3>e~4T>vzWaotga3c)v5P-&sSyvjD#{W$m+;j!HJTW#Pc#g~R&yE@)d=T6mMy z-41r#_~A^toy4_MA#*8 zMQ0SwjFxBOEL!L$aT%G6k;~KyIvp?Y7Y$1!wGImKwPK#c?a~_aq-Z7|?Xwrr@-GXA zBy!s@T2i`g>~7tQ64`BjQBtz`4ux){l(Rz?o+AOVmyr>IP8tDkf!!G`Uk>F%mxIeB zgN;3>R>(V(b5?5zmrt0N)d?u|6(&wIK^cRK!3{$u@Jzn0`vAi2)J9w(Q8`zLJ|Lg; zQY~eKixOEa3sjzEh*pRUoms*pbsN?$qp;hsFEa|WLnC}`fAgjBnK+x5S@>nv21ZhU znW@EKHF>H|7e05+92a^-m{3>86`>l`8R#iHU`C$WdcIH&&n7i%6I`JdLFPQ;tj*8cD`E>2xSKscR&WljcU! zkq9R_EHp?b7Yq?jwav!9A&K*x+#8Y=p*~HxlINH;?VBeoUxwUBw|~>hri*Wm&iqFQ z>o-mknR6pOl|^37nRF|xq(AL@T!^{&5HA11%^3x)%n!}`hPB+5K@-xMbA+n>6K_d+=OTj3E z%YJ&KL4H(UiivCcOoq9YV7hd!mtL@=Q1PPfs|Da%z~oMe0;_Wotg}XCf4ChLyT>`bOU4&)EHZ&32Il1UF1mQ z)A8o+V?mN=LAb@lkL|P}Bb@YNbMY-RB7?ilCHq^!=gegtb3THZyY}aMxa{X;Lt=wO zfD9H28)^mo!VIl2q*K^Ml9*F36a!=g*q7?qN?}Vj9dd>C9pzn^dFZNjpSJdEz| zAT6p`cl`k?-3r}B(SG32%&ckr(Iqmz> z2b!bmS>kS(Z2DI7zPL@irQIQ(*Q|masD0v>njgf=nyu1WX{z{*=Ct^ocB6DsTrOSH zmWg|`OQi3$v&D9Ps0@DU5!WcjkrO)1S3*6)k|Q9YQA_}b5Hw= z_N;hP{hoA0^NaeU8grDJrQ4bnnl<7E*mL?;y$SZxE~`J0){2#y@6=ytwn!hsROSrv zH_a6BU6{)J3%0ket5?E`+DDo<#Z&6-n!}o{;(GBc%vEjFyeck-SV|r{ctCtZ zTC1rP@4`Ii0&yd3ynU{DOFW_eMYB|TSKOi5DN-YyKWWctuBw06o`T(~12E3HQ2a^# zqvo7=Nb|9@QnOCFMUCA}p+?~<>Cq(`d`^SiGFIZLt#t$|pWo=gZ&+f1 z2$ts2>nlMtEX5db6P}viI|2VQ6D2L6tFn{02n&1CWi?K|!3i}lwF#cuA6$Vo*Lf^Q z=<#P*b$tMT5k*rwWz=fc4@^gIycPMjGIr=348tOcnx;~DZM9KbXFo&b!c*gt8{ucd|HZ7t8d?GMFA2D> z81E+G+n^B<@4O!IH24khw^5h$Kb&KFAioN$L?i07F_hyfu-Nn&89a(QTY~Rdg}mob z&TORbL|$q&?Kt8a$om~UOc>NX*Kq9|(&poN^gmt4JMG8ua`^E~AMgJMmGIOs;uWO*gz}Cc{Ve>C@VjsyefMp+ZzYrMZ5Q9*8>u}$YI^N5>f#E{ z436cRYUq;#oNV z1pX?{-@r4E!QV&O3vqq`9rGAn+V8-F#v{{lT%Z+8D`+PQUX6GO{I__}9yILJxV9XX zdXrJSxk4k>Q|Nm`#y`xSU>{NdU34V{L;87VrXGo46U-E`kk*8RarU8%;YB;uoqby? zMk)-$D9oT);lP3RM0-E4D!aVF&&ymyT=aZccarGrPMW78^G1yrrVxkrD;QE}ci3gT ztiXiSZ`5L_LM@*Q4aGwXOZpcM?Lk>8XJtvU5xhMK*)&7AjUw~9V<;A+&yH+1co5|) zX`a?Zk#CD%Crl6SBMsAB_O$G{jw4cw1y{$$E13gp}=sd==5z-H1WM`4Hymhr}?I@u7uZNVUBn5A#LI{JVpY8A?XFx?j1R!T`Dn9Oj$)YJ?*qLr6jua~co<-OdlBl^7X(TJV z9dHjLkQHY?7Eh8z#z^N2HTv=huvsf@gi9345L-Xr9lE=cb8m%>e~Xx$#n$ z`>?#NrtF^m5gmv_(}CGf7RWl_9g7Pi4;IvWE|fc^W{R0l)djtW6_%v0CqH##OXDM- zCFjzPup~MA2+RE-hOHzHr-ww|l~#+Q1S@IJD~EZ124xrh6tROO#qA)b8yYcO5i)FW z@37XvD~x$==_f7VL@%WX!#;JfFve>_4uW1k2{XbY|QBW)cgIy3w--u#}LXaPT^6`O%eG7~GpenX&3QW#vgn51D+#$?+>{h#kQsB*NWzNtvKMKsACGv#-950N2idT+p7RNYi+8}#>77oq13r6! z+?zLYR$ycVcTi~Nh+kDb|Z z7fDLk#gem@=iK)Q^E=rSahfE~I3L-ctSTN##!VxC?hzQ?Fg-f?v1FJyH@xmy;9gDYtqOA@nh*CG4TSG&I^U^*_J z_@uLfiByrROP|b2KG!fVo#oD|t+6~wUaukBia#Wg7IHC*b&e0nyh65*9=HAlW&v63 z+^mS4OwOmDcXyS+q~M!kl+rR?+zxHc*i^AwUstj?g`HnjlWlQC$0=k&#Bh?B0%+9tHV7P;B&jCp-frjC4T85LU(EqDbXdv(+0Io*Po zY2?CEUF@52+gQvp*Naz>$Y01ku_9QL?mmi+BHPQuUxEbWjdHYL0 zkL*s~vF(+UgpqkT7B1VDv28PzTpWlm;E`3}V8#DdI>Q{%}WzTcJq_kdvg~Sv0DQy<^_VllTM#8zMgLxFxeE z`M?sa8y7^9QxN<#Z;qP;78H^9J|p7dpo1UH7|5Mar<{~)){#8x9~!btmhNo8s_C?N zx$P}>oJdZm_j1o5nct9i3%AM-qV^6FawX!RyGRB#@t4!*cPxuElO^f%(K+Tb(5P&a zJNJ_C;?jWwQO5YRBJ|trHi6`Vg|}ppq|3j@XOWY|>qulQxscYK82RAzB7C^0vnfeZ z3W6J3zs9iHmwbA9H;Etl966CTiG40SWfDvFck5qTFR}%>Yn!1U32Di7$fT`@-O9jm z5oEUP^VpO4Lnj&Tl3H*J^6xRCeh)S5>6z}QNx?eudRkHdNk~BOndSGwJn>Drp-eKq zDJSb9u9SWenL(yT9CE7yh2A{bl(v!fbRA2!$Zp7wVFo*f9iGL<$hfD-YqE`*Glf5b z+)HHSo29$Mj+5k8!!^gzf3}gxePn%_Etn)HBr{}v))&rhvTI-m=H!vswS% zc(d=*8tIJFgp{W_vZh-FM%RK4#f4qbvJ_s4Z|$;omxDi&1tS+rjQ?Phve=(BvVCxkj-$bSkNKwk>4WH z-Lqv-)?MM;6wKt|RX*=HiusJZy0n4(v$P|kbXsj|st6Erwc!E$Cn8>ruBYf)fYR?+ z-$|cPX%bx$Zic6p#X&<#8zd_35<=9t>s`r~kK<zG0(7{GUa=FUIr?%B1`S4AUhSg=J*g{3S1Gu~GtN<`-i!K&p2pJ+a-gl(|VpGcq+S8qZ|% z9fX_5Fy`=u4D%twe8w=83>viCJi2WBD5e8@7r`oX3> z6NfKXyJMJirnTN{Fqw2?f>Nvada#;|RVoNStz|NqC3{-_0$C~>NF@~E0CpW_m=g?B zXi`C10edvN*n)b>y)2_Hu<}9tkMkdV@a6DmApDNZL5zJqWNal$%YE5-PS1D*vQ5An3m=A%ppMU~ zx3h|RqCsEJ9l(>MSRK6U^{jn~~eFXTg#obtbGQ-3k;8rq4O#@Pl8&5OYE)mb$BY{0(je zyYyFL-lubHh;HJtY_c_R*|$VCX|-KeZ;vhz)=DNGB!ePXDo5d`2lpgVo}NV0v!JO| z=32>+&10Uy&a;zWu4tv#vzEc)OKF);kqk!Gs!NzckM@Q}@XOL1$7Ghg$&%$PyOCuj zA(rp*ZR>@ozon8QRw2(WDJ(QmGtOf7!y%SpWo}~r%k6$7j(cwfdM>i0Um61986TK4 zK9E}~Wt~G%agKcq5g7j^zWc1I(^{GPd4*@Ktj0}WD??++S2xKe%l~5CxeRf%+KX25 zR=d4iZl;s1vuvfz(?i~?hum{Du;OYUGKcHXe3z^qpngTG2o(*RtmY_ft8q!FzH6c) zMPX7vpe@?Ik}Gk*%GCIKB9ZfIVqlCWNCm+U-)`fCWojaxN+sA`zxwN(8O*7#WyH4P zGf0TT+I2|KE)G6PE@vN=nwmxoI3=;&N!rnYcU}%S>FpP8IAp zw7a#-a-g!c%YI-->wVvmUcE3`4xmAa+>rF$nKMqyo!i5l_FFe^I>k45GD>d9=?AGS z)2l8-vPE@C^KyoJlaVcCWXl=(hYYuo;f#ZoNp%i0{0W9X%hb8V)VVpJnF9JR*=FK9 z!5lufsa$LZ#Ky}QXRu4d!Hs8&-cbbiOmLt`B$5oBN|2Y6nI$+*5?q41%w-C+3;JLo zAZW;3mMjJal_i^5vWq2^EW!E`wp+euVUw!WQuT=wot+j&rnDbB(K&XW`z|Z|0etBA zvjVvpoaeY1Gu&x;lYPT!|7hcfH}eR&7o3+5 z(~^m8NoEG;z>P0Ku*0fIB)u0 zQt=bRtqquxlY^Aa!F6*65wa_|u23G7CW@pI2@vleLG_VS-s2Hx1DHzzCzaxZ z2z%1mJ^w@q$q*aE0Ai-Gv8a@tWmv=4A*Q9$5f(Tbtt70iYn`elb9GbIdW_s|uoJS2 zv;=y7JY&^x=CNvLp_Ztd!~$tis1J3THz`~p)1cwU20#}wXZkDi6u3 zB+El2Gs*IGqvXx^Pr?XtcsfRq%89LA$%%=H#uh@3ff%Yo#~=6ZIW6PLh|7N8o`?01^v)pd>OqR1vjIc99kEQG;0gN(R35$`hZ>N z1fP67_VPF(BeZfV)3${`I5PsB@N3iI3zQ_eErL|t&+>`|%ABV{Jqwg@?<0-F1@L)n z-$pk)z}VQ8l43asMo~91Htt@N*ai}xKLtEe!`so0@A@4~x4a=pF1u{TpSoc|1^p{8 za6B7qtec@E%f++N(SM_y zbWe*pAF!uh46tAKPDns5Ehf&zgfqEngMj{D1TLvTfH37k`$Qopkt`S5B=VSYtS`mK z9A?Q0aJg7=i8XJqbm}3HjLJ4@VNjaZTWlGb z^DFDQsLQ{oBhPi37$tOTvTR}$Oo4W5BJIeiWI(vQ-iW`_Of9$?JNq}$-AU1lP;;oq z$oFw;qA(YkiB(q~#SQF}U1%mLy0Q?-i;hwYsqVQJtKn|6&0>Y+EQ{6WrsGU4e45iF zDsD*=_u>RyohZ+eCN*yOk|wy!HR}|W8n-)3cP-Hql?rE!O0DcJ$3aO{s&F|yJ1Ui^ z1X~Mhh*jBL5iQ!1y5w|iF-2k3TOAh{_jXy%XBE2a7s~qRCWRI2t=vIPeprC}<>tDn zNuIEP8aE~^fLkQm`qk$?(^>n~H#g1M2P;}PxOa7mQ*)C&N2*-Ok>qgI;y|Ss=q?d1 zhpRDkvS|q#N`SF$8V8uz92#>bHV<)(%*5vBi=BZYG>g66j{7}dbXm@^WWbOqh! ziw)^9(U*Sg>#{6f6zQ@HQ&PkQHZsaHoD3LFDK}3yG5|B)RK&&INNPD#=S_xN$Z*RU z{zImYEvKS9W(UM}3gHeVn2oP%=s?^%8VA#pk}7_W z#Q}(>CM{`vmxSG=F(pY5QyQwHs$#6RBp}vvnHzAK^JK;P-1V&3{B2BS=K!1*A<=tB zRxIrZYhsXQ&59LD<4l(Ce(vM4Pj25x_XIDrl4D37o`v~VxcE$`?J5#)J)AG<@;u9w zHE!lIC0fCgKy--2Eg~4$_F$5sV=5nzZ-foB9KNw`e-a9~_mnkAQhv-TR=a~F65lCE z(zR^K5?7vS{tW7A7Z{2b?d~q0cdWFb<0rm{)3Ubd2TuFBy$8%+ zst&CRv{RUASUW>$LvI|1xDyHM&|q$9!$Y5$J@}+r zt^$b|fxkE8oQi>Bfg^bY$7t3Gm14yP&2U@=O;Ibq@AwSTe`4rWjJ_%%p#&pcbOT32 zuqgPfK|}f#4DCNOJEj3?tV@)_*?g+^6-4UAQtN>}J$JE+`UJpA%O;qqnT%SpKZJQ zqzob42+9QEv2czE;K*L^B6PxM&sxtm&v+ZO^HIQPfT@;s7(AqZ@0@R&lVn4$1~$ZH zMK{ADQ%#o2y?dSZ&6}F&zKHSMwddcpJ6~vL__C+)Lc47@!^jTv3+;g0G_=a)kBUdc z7uo^2)n~xmb*{tX1KQ&?yO>wE%Qg_BH#7{19e{%*LKEv&g`U;z9(1FS;RXZp zc52kc^fWq#?v3)Sj44_fLq|!_tw)qb93%ZMG42htUdK1r$Celb3G zyu223t4BC!IGrEjPRV4uJgVNZpE# zhUcE83y9G{zRe{Mt4_!dudflqfHX0k_J}` zxa1Yd3S(9nRu4i5UwK|;te-?HwlD7)9aJ-f4#p(*I!}SprEzt4aXxy zJt9OsdPC0!#e;4*F5O_xJyp4%M=n}Jp@GO%gkx`0{n(d?F|t-7j`4U}ZPi6y$7yx7 zc{BQ|ZG(cg&nSf_NoP&cIr363J1rS6nq2lhZ#Ta@4tM8oP>}cI+K0qF)7IT|x_Qh~ z1MW`}T)MR8x-q|)J@+U1T*CcHyqez@nQJ`uYR>0rBsuQQnYPcRXi!(I9BHTi@zO9>z4 zobq1$Cw#bq6u-le%iZ5$+#mx((E>oMlCT7IqY z`K!;FNrRk5*paPiM8r62xe!p!6MVhvZELEHE7w}{JDBfQ>>ERy{7uhAZH?=6Q5z#I z4usah7GU=lo154;CM{b>X=}z!;{X$rLu0VD^APhg6Jyw6bgcXSeWzv0usSaL+Z%Pd z*IO9m5^eg`q2rUyo1K=~6*`xFMtQlsEpDN`0hiGmyrE4ldE%$mcGu&lit$r(UaBKJ zrB2wdsn{tRahH!P5h3C(+B-f2lAosZQ| zo8Pr@j{G1^3E~i8-#cN; z)Dd8lNN!6iK-Z*~{H!i_5&sDUfE|}`D&E*;5&2LzdvVI@c|_)%*M#fL3YBvSrNE2} z=#q0mldP7g6Yw(yEJ2e%@VwsybdCaI80)HHotkj5pIiuoi_z z&%=20o}{oUf`m_AB__jfY1w^3R}7Eq6Y6o#gLAs)8Gf2Jzwdy!sD-`ygp&7kG!R}; zw|icV4Q%JMS;M(=TH~{2gqh!imBrxsD|U3!hPqc-%y$gtH_JUk2l(8~p#wnnF`KPn zu4s&M*op*nZM5~xauT1jj5Q38w}rbrLKiqu=;91_r4+x$$s&ZO=Zqh`%sCre=dMc$Jo@PUW4sIOVa*exm)V2Kgcbo@tuF&J(X|Z=%nBvacw@Npj$3z~=`y7;btCb@HN06|PE^(&1fccQ(7;ij9FyTwa+w;m_Pr= zmF}0i8D=y)XIeI+*_2X}VScF_|6Mb6@k`w}(CSGaSo?+Mfno7MJ&*168dqU^odhJ1 zlm`MsMrhK}kj^g4ZGsJLKS?8SC|sw0eB; zX7r6O8I)~>Om{Ov1yM9vR!mX5?CW279kfe{L}?d%?)PAV8cmULB*neJY&f9tWUs1m zy6jbG?zTPFkKLx#Xzt4-#Y?QPX@-*GGE=(j(OnHv%k$4OinxWvmW$yV`y@K;BfggD z!sL+`g(+^cRO(naGtOn%dU#*Debe&y&CLoi!>X{)gpt{#QbWT&LVaagLuJ991h=dr zHBh#Qm-=~Uh?TAm*TB{p#-|iL!3%OUd*w71W|K9&LZlqw^Xe#A+p8UL0eNZkJmKmn z$L)|IF3YT#5SM+8yU;?FeB{c^FJgPWZ z9dLirhLaRr?MBkN{e4jL?Aiyzua4?uXHzQV6( zm$&0fqfKyp5F}nDT#P4MHXvK(3Do%9^*~J(TPILcghVe}Cs0Evz7n z_^P0KF8l1tQ)Y`C;-=w&8WJkR>;-EqP$TuQ1s)YY$bLGS@P-$=@@1K}wl8)~dM>$@ z%d%yv&T0Ro+lHp%lsv9ixGrc4`NkSrU*G<@Qs^ENO=j&+LiYe|ci!pv3Eq)O#Rz{1T zMfV!oU3ks3;UJ-RADYziFJ)R5K>iSlm@ZZhOw{f!lU&4+iWOUsw&%Ezxhd%~Zx^ zR@7-$FobGR%h5;MyO2a7eg=nzGkZUTQ=a%4aMt)4WJsEQbV{X_D0bc4L&~}%*ldW2 zMmHRI#(G<7cocGn4x!d1rKKkSf2t`soyd-1D|H{%t6{81=Rk^MR!1FR7s) zV{fR=@)5U*5srss-}qX7PU7joXha> zv=H7*-|H)DyqLGVwXTKTv%GbUo4dR`U)yX-ILPuBewYFLm; z$H*R$2uX>~-Mww=S0QW0;D{s)j^5DIBl1Bv9G7k|69?^CoM3#*+gO_gd)`tP;n+7e zz7klKjm-v>LMh1TWc3JZLN|VY1S@k$4{nW z$c0MXF8hdet1&u`tVfxUUDWuCkw069E8E8GBu#Qw4<_-tnew<94o}QZpDV%z-a5l! zM64DX|7=~a$opWB`T1t#n&4~Q{G+e zkZc3i)J(ENw(Ux06sN%Cf>61+-_pVba8s9TTw!J|0c$xxz64_h$%q5{0x<;W)zWx1 zmBu@-L#E*qrC0jP(LFygO@6ADoX=(WwE_C>pgI2*oM&!mwTDqy4tquCcm5WgGcB-B z{(mJr&m1(Sw)nhY^Z!hIE_uc0_N)o(n*imd$ZAV%t=x7qVSI*($?PL}p<589JD%pI zJ1s@4zzH}}x6`bf7~Xzq`!I1jS0heW^OHpM$Hn!1S}eSf8*TOeiNALm#Cwrwpzv4h z4C2dN=GZiU5KjN-Oh>|Eu3|jPrv`M33B`p0)G4b1<9I$lp6Q61;eO?SwF5vg8XPtAPX3Zor}Q6flM2q163Lb(u5d3@`k0| zNXZWcXQU`Nsf=L&?TXxKB3RRVA#j$1YE;5$B>o2k4v4SX5V*#Y4+59<`~wI$qvelB zBH%dHSInb?>jm-!@Jp(36xjJ9s*)Ws;7U^_j76d7Fz%?{MDY}&=#FRhrNug?$iabe zF!vk`>DS4@cof_$MPyR=W(jBt7L4bML*{eS9Wro$R!2s0OX{N$ zd%;%feeJ^&t2O}H>;40BwRK4q;)?7zS67X-1w~vX)gZ3u)|M*7mEkhKXkFTSf#)Vy zUgn8ScZ&ClN~&>JZtVW4!CeJZ;jRLza906UxT}CF+*LrnZa$yXkCZ)O*;U@sX`eCt zO{e&(${%_4kA=dx#{^zw@Tva5E2em55XUwXhRS&tfLE({;u2N{`9ZJ7_axQ8D`f_7 zry(`Ks{zU?;MHZG*)j0na94)sHPg2S3u>jOu6Vt!2td`TxdFzyBBdNv0uqaGjLEp1 z1AwY39g}fQI_8VPSpFN{(BxEVaGfq#>WV%`%d1+jkeh~mn(5uSibJ#z-}GEpq|@^x z4KiEnijE(DJNks>>f(2u_FupCV0vCH(8Wt#QTl=EE4*SjAoTl)RlHXt0k6gqC1UUz z+}rw>%1}Spa0qxz!4mAb69lKb6GWa%yA#B9cAM|35Y9)Kk%8+{hEMk0N8y!ycT{%@ z!j1+i_$HzJX;4f2WqVfFJ6`xl0wXB)Gk{lAZB$FZ4m7d1pyQP>@_dkJW`hZ8vILtZ z^`#@FF3Z`J?k@Z8uDjBc&+XPHu)L5##AR(26{+t;!^<< z{(Bh&e8{_ExECLyKCR&|Xg(Skm&@`(*_&QFj*V5jMz9!iqm^R7TO60RP2v%QN zd$s!GE{sE3KI+CJye&6g2_@T$4G|C!?pFXoy4Hx}49}HN0T)&dcug|ZV2XA9P2zp6 zr$q!@NeieJ;=hSIYE)+f)(~MmYJ@QFsIh7*pg6=B+X1LDFlvi-7?E>BTqi=DDKoHx zCVNJ`lC}iD?^4`tCQd+#Ril#4=X#{b7uwE*d2Tb7+a94F+!&!AvfYTp{@R=~Vdiy8 z;;_{9tW(ywwMZgu9}*bWDIH^@iOVvvH5jii&yeYkL?Mm-$m-Bvo`c_s3;3M~@jJbt z4Fv~!@J9b|>y+8J4o=9E^2*N@$V-3SJUQN~2**BZ|Bv9Rbo{+q={Uw`(7#vx71wcE z{r9{XeSdGA5`Pbw?&3q9UF>jKHjV|SRTq&8PAeX=PN~0HwOj&v>SggYeK_4B2<=_8 zM}MLa=gTE%w&<%U9I&_Hp+u&qTM{8=@M^MZ->(3A!6WX*guB%I5}~}IF;PKbC7NjB za9`8`Q{vG?*SI`QbVfC#gu=JHXgokigfluCp7Msryx|d@z6wi{C38$R^DfJ}BO9Fd zH3Jj6ED_QTJ{ZaMH?BJ^f9AgEw9jM0LjW#w3HPG^9Y}IP(e};I#|4f|vHSx#GR5NY zcc-RUC~9Q8-1weX&^C+rycbmT9xQKqeo8g}l!{~@Tfv)(|B1^^r1_vC*MdA=cl}yW z6;I(>P!UqRtF&uW_;zTs!n06sU8r{$5*xWJqh|i(wEwW6u!^g&-y&)GHBby@UZ_|1 zhDI7uoSj6$a%FHrHzDP$x0Vxxz|ax zd7KrcYF)#W8m@b<)aV_5bKTFSRB_#VrGn}qYW}#;JCw|~_m;L``=b~f+nbB0EpAsZ zNq*b~E2Ey<~$uy+YcT%;1pSFSPNM^$lp{ZgUQh;n8poFnONWq$pjt!OQzT< zK3v2$4psC1CA#O6B`9fovT)?}X(V_WMuiMl(KJHxm}yDu_OfjuF`G2oBUeu@=4r*^dc2w zf1BI8D{T_hh!)R2)NPB0n#YG;K_b0q`?re;|8_C$-!66(CS>v8D(NN(LaHFvRSLHf z%v)O=`dQ@rkrLr(b7h%pA|nh^L9qc?DCLY$X_1yQ0XqI(oGFnkG@255K$?xuC6m;g zH{8}fnbVDl{)lDWFtulRR;S@vq?dD!+b}Hot}&6TbJje^Z8RkE68}rw9C!44pr*G- zibjB6cT8#y&G&uq+pCZzg?&VgbBWt9zrOfYGu`_s#Nm0zeeWGN8I;x;*eC1zDJFHz z7Lv8uyxP4~*p@A>OTh@gHe2YHM79Xa-C%=m5sad3eKsUJqESR>Gy*(LRf$m%38tE} z1Nz63q|NXS5i^mXX9=JkgxjRAS=Yh z=E5u3_?i>{#ORxjr)Mv7S{e=f&}r`xp6+$v26V4O%75=p%0I@zjtkudjnl1ed#*cKdagSjc6-qoMs&{hg{J7D^DXHdjZ@6g z-q41^&bO@XuAgryB1P6H8yPT3&udUw9BIstqLVah^5jPq;n+7xZ!W<`x<0CAlGaBRA=x|J>!av!Ur&WhR(+HZUyo{V5}&B&+4w~9#wW-MkXIO| zosn^i%p}pX$XweQ7Mamj*TgAB(miGW6C|N%{}V>x83%XaKIX^k_nmff?tUv}(Rup2 zHbj0&E*b{6ikp%SjT29540Dv8Dd{z?WJ)?R?Tf=UpyjrcPWM})?o*2z`x)M13@t+V z+)Uf|x1QlV)5(ObTvs*lGD` zk=OpxW+M|A1<* z)|2I8K=<(RRSGGMlE&euj&h1s*c)BBrH-L}8y^brK#Vv3{||C|_&{OMK-9vJfgFI_ z_tXGxGbdQ)EXx469bKAp5?lX-%1fcfGab>UxH9LS%9P<&!=WX_Xf^m+TXd-xv`te1 z#`;GpmaW4}X=?;?(+k)J<8l`TZZE-}o2vLfbWWlPEf*R{#+{*Y%2;T~*cqxziNc{L zX^_v&O&UZl$2GQ+cg4n5uf_|ZRWBKDYm2p1{v=~mNdEbNgs6~;cJ%~Z1SpT-UM-`5k_cf4hCt^NeGNb`OvF!}YLpmKJ zDe?6xju9V@ba?~3Uu7I07B`!9^I?XYLp;|y`rNi_9Wg|G7x!^2xvE33GiyGLl5&35 zbBh?mo#BohcU&&Z?mt~F`?gyy-IY+!_l)~{=F|@R{6n$ii^Wl_;oSen-Mhd;wY~r2 zYcn)6X2uu{CdMVBs2O8&uLcuBxkORAC`Ab=6}lX%Q0YE#B$Z2dQc(+NUG&&>k=X4{aE(B|KN&2z;MJ%FoCntFdyUwDmxROJu~{Wy~{CqDFy% z{X7)U-lKz7dp8Os?!3e9JlH8|6aX`#J#EW!nvS{l76%ZRynSo)+C~A)IMSD+EzI*# zNW?xLWotiA%HUWU1sO>#i-Tu>upaM<0ul)QiIS2PGE-Bs0)jhu8S;=-QT<9u6G$84 zrlv^|0ya80v#Yo`M@t6qkg_wpH=dXAw498R^c&xkQNQrCB!m!9A5RPF<7q*CJS_<4 zX#r-gr_*g;t)acNVLjmDBXhqU{B*i>@t=#2%-}f~nLOZ1o=*Rh5k8&n9k)R|m%`3d zg~6FInc9@63L~@N1yyV_0z8v5mWZKugQskW1}0c30nUF2QMx9`HZr<-ptM0oV54hWa(MPn!6~$$KxTux#2@GW!9S zcW(n4X=1kC;2;Sdoqbz!Zv&XhLt3;!!_jJR&b+sQ=9A!jZv%9M9$q|+S-OnStx79h z#=vY@2SskB%Rm&TSXENG3`}h4G8V~}v5t05J!VDeGJ3Zvo!H~B!y}F+nogDIGGwMf zmw}Gy4`ENI@=QhD%mrX-A*W^Tq z4($cEkeXJw?Ee6k63W`kPr7_@g#tuIepJ3`=v|UHi;~_IOJsvPN)$sg>IAar?mE8r{MBgDCWG^rw(H?T(J4I8D_GS`o z>MoK3vwae#MpCG87!r$3)K&)g9gw)oU?n)vadAc(<3gYweBSq=^Vl;6gc=p%b6mEH zyUCD&yECihMU5QEDEk4EJjxy_>f(YQ4rpZj4+l40TJR4C@G0UgM7Ga60L1`XtDhJ_*3|3A}Fv zRv3d{VR;2a0uxUOxoe zS9F1>9f~m#quOy6w}a?lw!aZGmnONQYjQ;wA(L%KP%kZ(%CW!HIl-1S zlOmx6gIPccM&?GiRZIz9u^=2}(>yfRR4lpCA&0%P4XC)p&bD8gcW7rRdhu}Kx48z(CirRg$r%DMf6eOELQdJGOG0j1s*1r0TGbA9_V1Q%;cVJMwaSJu?8klL zhW+Q7u`+Q(4MXT_0)d8jm?qHR{SNkF`U4>oTjZv0fvPV_@T+pcz#%j334U(X3u{aW zaEZ505=>Gf8}$q@uH?;x0h9A)0wQ=f>ix-L8*=$yw|oJ{{bxKoZYO`4pivKhWcux3 zLoWWvz$H8~Qd`of_g51IL7%WSje_z);_qxWm4s*hwhlNT1I}+I^bI=aiG4vZTcH9( z)X2Ws3ed|&B^Z6+hVTsa-=q~1?w_qR>IH+hbhgr{hmSsudhLyRe1*k2cAN&~Ks#>R zZ~K53-H_{T$c65_mNwD`z?y&P3>!iQ&P9M+3t|9oxs43_jwQ#YNb#3?@rC*ev=MCf zmWODX(BvTn#}N!RdFU371t;Sx9J^?CWVUz@x^4m%-x91miFnW7nit|dhNlT+CHJ7Y zAyV~(VGxixR?Imp0}Mkd;vR-W&}MU7^rzL5$(plcp^E6poQp?rW{w$Ee(g^r#zXFZc797;!>Gbf7xMVtFTqWdOti+NX{YFY6#Pbv=WV z1TxttB6z9$a0wx^hL8!H@1u~5!zi;neGd3|fY0iE9E_KQ;L44VnW%LD9AIXGePGZ3 zxG^}e2dX=dR!wE^9>qKEDzciuYT-&=FOZp%*9)Yh)GlSW+b%E&-F7(+=W?2y8T*nJ zdTUbVj4aq?&IaSBqDo1b^MLU!bN)qIUJj(?X=A2>WrOaY>Uh`4!;W+EyugmT zt$nvpDk8tq7Jn9YXvys0Vba$JT*9*;wIw^W{%WEi2woq2X5}#rAj6-8wM-xj2Dhx2 zf7R^shd0Pi{@^x%xX}CilWm2|{x^t}P}ci*XyLtohgSOzEt;>I9w+0=3;?^yD}&Cz zL(61`7H_33`T!y<9-W%VT+*re|D!noS#Xi^H1T0k8X;KThDB{PDmDnglYlEyP+&^e zwAJu6?J)vuF!WJ%Or-Mjy0$i~E30TL%!vVgj{nu_IVRBZP!Lq4!%o`Tbj1I8F`R>) zpU}S;E@Pbd+vRY5gMYOgPWQ%lcmA{(Ic}Vz0R#!+}F!8M@68)}e9E7FdU-6F=j8 zGza^bjbuy{GG-(5e&EyrPNSdTYRFVH@$w&lH43SdfO`Tw(XZ?imXEE0Z4*}J>6nm? z!6Lj=p-DgA#4mU?SRda6*2g!2_3=$$INt;vL^}L6od%nqIcILiDZFHE$31<<+|Ft6 zuWS?Mzld}Q6+HfmS2N+Scs1piL#pF->`$B%T!lJ^Px!K;02tfl#vY0RP z{S006FZd@2<|5K1q`2m=!lnN%WQ`&L$ptNoh10)5tjQt#gjmx}_#4EU428cztYKCY zDL7l-KZ2}TBV-hia2B`qMSsSv`EN4c5grlh0|@`Kz%@7n1hCs7VcB9Fx`uD_0mR8!PZbPg89lPCS*=q3~Qva^r9@1zFZa>DW4Az%@fCT$`jA{yE8ISpu z(N6s+S}iz45U-b$?eo=dLqYmZ6xim&sDXfa6^KB5J00{=_3!ins~wF+WXLHoQ>p#X zS2S}X&auT561B)%{@4bT;;c!fZ*cf4*auW4p1@TbH7PR~y<~GPzKaRkjpT_n3_Xl9 znF4%v8jLMUVK|7`0I!>rs{`M_)F7T!1GHHO(2As(4+QN&Q53&1EhU` zUkewYdCb5;Z*bP&V*MYei7M{nu`~YRIPwo3I~jztCF!tcAD10%FO33db0nw{TYq=T z&zyDoPjJpU?bTAwI^a8`sKNLH2si8_B*Fl)948xfa9q^@aN}28xj!-0{e&yW{{>f$ zW<+5rDjQ2ke}^hJsSj07##INRCpeSk7asEr#axPe!jLjA0@Snuk)vy@BU@8Pj2n^s z_ZlH~oR8Xoe$tY&I7A&CQE2%I`^5Fxui|zjgP*{(?=XC}czCG8!a7)HOfxl!hq}yEfXC~Z zic_vcH7U@{|yt3$vUvyXLxrFLDq8P7hg3B5)W z--*u~%*Y0)NQvRlzcnR>Lx-_`n#bo2rJWzzH;)$$>z~IPz15XX;t@CPgE7qE{fyCd zhAx}ASgCIoFB-g<)A(?c zKc?|CKQ`@-o~1f$_aoYK%HPlB(}vfi4VTU3d3hL2<^Mo~6gzH8359vth-D(cr|bRp zpH_26@$nG&q6J%uYb8BPOay;2Jn(llWn@x$Jz8QRpY6$lIX#YQl`;a{_?$kG3yx$p zQ+zodd}JJHvLLCClv`dFG9XHtWd=xd_^n}%-+#+ixa^+F*y~QU~nNSbel>UQ;uc7i%Iw?`SJD*o`byYGTG0!8edKW4#8B({@T?#uu3J zfj=$T<|qC%_mK>VwPYsjO7mCDRU9v&5|w}v+lG0DQDPa z_djulU3QoJWYR9XyAic$FEj-HT4lw6)u`sd-Z26fmiWXIs(9fM`y zLU6{xg=Aj%$FEQh7eE7V8M9c;V2RYU)(q}r7ONQ?3_j8)pk^>U0TA9^GnjT(NsqI6 zO1hAnULiJ;A_{rbz~gH`@X*%4l}G>+FH32{2%L-eu$qjEm-g9>E>$-{o23N81xsiu z6BvO?BY*=Jc31ltd9exBs4fW630lCn<8Y zfSGrSCu1>B%F4^AG^I`P1o*_Cxp^6`{=ld;ehOi=J?24s;BL6u9(a3kmVhm^ITZFA zZJwq(lt0^2QfVbKHI-Jt*}qnep<*#4EE{%9Pve~Z!^ku#`pZvTK?bfKi0cFrEUaoP zVDHCa6d7(F6p*oF7{D24@MnDYVEB0ai6g0oE%EX2_3@wth5`<)mj`hBGrT;cK#E%& z_QCZfdm3&#xOsWdmV1sq-N*c|OnfaB7-9K($V5FD?jED18a~XVIyQnLLBog13=iPP zGbb}6hPrtZq1ywPA+2?W=pMc~{G3*x%QjWUw@XX`@Clr*S7qBJlZ++(#&?qOPZ$}D zCDU}2Y2mmv54UE6Wi)LXzd%wXC zJ95D5PMVfHZUoNjK5d$;-wy1|nHd|I8S~G25bQWvT|?}+9b+4T*FA#?JE|VAYd38g ztY+QgHIwL4sT`wblG;eAJdXD(5~G6($S%z3%now!D-v*_9OdcwBO4}ImxN#`vcPI{ z*6}CMycii|K>pG4M+G#D3b>qqa1SV)mog71(G)JomFdvg> zD`pz%_3`>M7{X~PFb`zgNa2Fn%S1gV~n{rF2w?<+X@pM&|xzb{Od=H;)6 z;Y>iE)Z88@(p2?fa{6=@5zw*)8yH+O$c*Gt!A0Xitb{$9ac>;H7&g=x4(^6a00Eo8>l)dDu^*&eXZwrV0%$0%y2<-k^3s~2YMg^oL9uq`!t`Ag79I0KUI zT1ozr0ka~12?dv(G1%w;xW@TQ0Ane9D04l2UOW_5eQ3+1_VS_3FjdE2wuGdDhwMq3 z_ygN-dlVQ2&PTYXr_=^e(Mg~@{m&)}2w)NQgIeW$CJ^JVmO@n^3kJ7z5w%$62~X=! zp5l0BB1D8|wLigDxa^-@NeN}o=p^a)$|Vh;Gn%BS{rerBkTYSb4XZ!{;Fcz7nt*pM z2lkj-WP8jd>asm%<}`t}dH)u(8D(ILnejm-Cux;uh9AU>f{h~m~-99Cad56ZzGQexxQ!0H5;lIEcz%DWbz>o<>FRkN~tqf7-2Z z+20aULRm|A;=n>c)D9VK3;{v;gHxJ?T)Endz{u}OHt{4IWf{Q6Wgcz!D)fd`Ny4Ev zfU|Y?Dx9-*_bT9Q1y#0voUL~kjMG47E5>P@dp<(*O&|aNzLmg_b&N0L$I3KNATlxy z7<46k5hj7XWTo5b!46G=K!SLRf`S!dE!e=v@mwdy<4omSCujpxInI}LmG_wpI}GVu z*kK4zXR`J1w^^kmojYKB)46&Bki3j-T-aFHid$*8l?s;87Ovw84Zwsk%>*&}>h+st zTMRAIR_eEdw@A0!;1b$KYD-$ke>G7M1j5wwn_8qz@?;Q@1cO`FBKh04A&!GOxx4xPWVHSQCbttQrQN<1-^o; z^cR^W2!>|^f}#GUw!}~AuOl5B;`{`!{^_Dvw9QW6+RvQ^J$s~-PU64{QE63(#Wu3tlEhU-ckncj|gwcMg* zk{0l-i308t+9+qnC^C<4jU#Dgt4sLSC46hpmaz>mHuQ!$1E>vQ0@N-DTPUFS2a25Ob6a*LLTj;Gl4^9gi|zeU~qGWs%WAG zfp0~MGCA%H_?^d{!O*}t&(_a^I7MVnlWe2;S>VEa;AzhQi*9h-Sq-ouKwgz$V2<(( za-1nGICpuV7VtSy-53fq(BtJsrGY}*2iumb!do+iUnVDr9VA{#geu#=#-H6q^=_SP zAl@NqojhQ~t&?HX=x;1R>tz1(Em=a2LH$tp_V!zGRIY3u?a+7w@F#0pkLG9{t`u@t zcG;^N#zT5CP>+5G>j-Vc&!~7T+G0qr599+JGLVmc2VJ(0a!+*fX*IFujp)%gzrcfjcm4g>5yOrwIbSkpTS+cJ$sUJQzv<A#10ya&d_|7JRWBtb6>D9*5eF*+w^cdPD@a@9rwL|IP)3_0%$*!7(?R) z@|3EZC{pNBH4y=!bjg(m=U+KQz~g5Qk^hTJBxgk1^*@!E$*&nf@-nFduxsur;DK$J z%$x$p;|v3+4ODrB!N$~mBeAOB#o&;ws`j4~;`^_mlJUh>Y)ByU`HFc)7<6_|?rJtc<4GSgsKjIPl>3}GMC z^RBXCDmqE3YzB527;rj&3m76CX6; z5(Z7F%^>MY&R+hLVS!JXj!~Hon~1-?M5=7D4(`T#?obvul3nJCPjYY{=&N2zV&H9+ zg~ECokt|zJlLgAY%SgJ+L?3)Sy~dWA)@$s6@$?!y7`&zZ_!=9pSq&XYG|woSH=^;; zTszJh+7}^r0iTx0Xdo@h5sG{Ozed*6tbBAM4z;t38t(okxZYF$Gteg3>VXecZM6wS= zP$kxUnW?engV!Zqyd1A&KC+OU2^=t;X96Lp%prEc^^wTT|N2OHC2V{xxjwSw`bfGO zuC&w0e4b%Gd=Y_i8)LFEZGun@aBYqBoEg5+&Z#j5jb>;w+c21}=U}4h!d`ccks8DJ zk!$;LB<-6j;~*zCboS%d6@yWPbbyUA5lTBxM-}NPJklghhFuU&hA_dF8SnSRABa%1K>^Ny-;Z>XX8%u1)QkSx0 z_S?am?eTsNm(b6pwnUxrR}%$6FgfdLY8;Pu?Oqy?1grP)T^55wHZ%CiQ`|sJgh8LDxfvLpx7~qKZJ*c=#VW~R&HRKG3Ceb z;LMjC7RpQ@TqzoXb%=FX2wkg&771%844x{TcQ3}k$4?TG4u%ntUWpWG)0YAhctrZl zh;$0TN+6GjbW{TC16c>5lV%oq%?yWyO^gm1Gbu!X2?vk(hT6g zEamyIt+&JDbBTd#37HhKG%U#3mCZUHPZ;TMP$Ncd!SO0IA)9g5ly+TP;=+z}VWYWl zwuCcc*n!0~dQBU}MwggiWza_HvA=11AN4d?ts*(@v1N@kBoU4LvfwL`P$rL;nm}*W2^7^a5IOtTt++i?daf8Fqu+@9V0>e`V zFg|dx->mt4-;raphK5t!uaKy&bqg=ac`TF1;cy8cAE93j zAT_Q-`#@?!q7C~&Y6AEQsegj0nX!8SrpCeYU&GW;fX&J?*p&dH>vk1I1lW81h1cpA zj2hI(YlZrFtxzAY73$-)LjIZ@r3p{6YDaSJZMZ4q?n}^-uDIF#q8{v590ymIzcO3> ztQ<^HrX1{~)t_~P#Q|s$k}EUE-_~T<|FO%A`-Q?sxp)KS5B)x z0h&>8__X>Gz|aIftB_ip85!X2|0~sCnVqB>7#cMHFPW_V57mQJ^ZB#ut} zGV>9r%4LHkkUSy{n6yVE8E6ay$gv)g`b4dy4qVhq>cB;HLUDpQRCz@ao}( zM9)SH0JR#eOf1G1jvryN*Ax0R(YSqW?>49+gdafOm#BNt(%ExoFP$w-Wt}S89@w^0 znJ5PwQ~nLG(d|ix#psgBe@Pv4p!W;=2jx>kpdCl z+1!d{NjwC&Uz27Bh6OD#b%dmGbr&qgpFFr0<_7W@pf%u@7nvqFWI^S}{cN2&q!Xs%!_$G7EvN4N~J0Hv#e!b(q?u zkgy;YRfh`l`nINsXhl5e)`~!vAwaL#AhaNAG4gK2VZKjhHvv{D4>rQ;FZm1RZDfGb-w zjP4FKo`B!#Eas*}K>P6wgh4(lQ1C7uRCk{T>>OcS*r11>E^=Imr1Q z2DckTpjZ++hd3`#6oo+3Sk_?l@hoRzSDH22tKeNF56PWyJBys5IA;)rP0SPsDv5${ z0#uh3agW;+pPNdVQ`kSa?aGL>rButE;P06@u-xW=s%ImaW*m_eYT z`**xMi1v%WDhL}eq6Kl6TP_mC4HDL2kPFbo zghYvQz`e!-X$<0tcZmwfMsP=7&6UL?whs|}lqaxgENddIf~vd#iR3Y4EqsL$#}gBq)+5Ws3ebSN6xzP$m01V@A>l3Id-_+!$d^6 zF>AfY;koh1%Dek z^dqg4;O0w0TiwkB-sUjP+hS4?`Tijut6etx-E#?-5@84O2Tn?{e4K= zBrh7l^fJL;WEy{Z-?2BaY@KkbZEkyz^J`3$LpA3R#Y_gtHzX+92i}Z2e)fVvpnOTf z&;)(gvpiV_#52ybkZ2u3t!d3Lt_t%9O)vtj-tc;w9~2%W{ajlzKPX6N2E`Vj_kzAy zAID()XD}Qi<}3>bTpf=Q$WTCp81$!*CW)+8p{j`q6hZk{J)H#eL=~_utCEOnHyHx> z?4#-s&N4{q=n9pH9#J*XRVo*Kq0&)3RS#{WC1_C~p;B;HQ#B{lFd&N_tW8AXX#nON zJ3DO7vM|n7y3@jWAq#oIm?P**SA{g;;g*LNBUpK$Or!^nkC?JriY9n$!qlXC)IY1i zMLw(_;)>8W!m$AZ;2F3+0`7g7!mum>5M0p$D+%In#xf}Ij!UMVQ2Rm$zx5ak?ZS*v zI>guwF*1NA0o<+F0>VbkjooVbhCsC+n8#CqG9EJo70)XOT|-EQC>7Iyn`xjdh}Nq= z1+ByMfk37sWgVskH=lz5S{k)u0t9N*(Q43%k^^U4v-<&T0bU&im?LV{AB2u7XkfMo zzM0WGDAs!*_^xk)eg}=Mo#1x@V?zSN&>nF2LU=0pufcrqa%|R@(}PoqHDvO4$lP0O z9BP5+$DtUw#`tdPLv#(B3R>qqp_m#d4g9X_`$CdxC>Ln({B46Hkva!$#hySGG|&z> zu3~(Y4E}2{5A+6G0Gj2M(GP4d(2yaV3uPfgHWVOj0TP3IH57NAX-6Z%H| z2K7lr5u>7(My>nmuXNb-Rop z&2%gYReB^L#w#Xj66+}lE68g3y1<`CO#OZ~YU45VCFx%3HuNFsAj(MEj7s47`Jn#+ zud4UpdNz?}@oRjLd61T=5(FiaEg zMc1f1pvTbhRF6`vQ5D24f+Ghb;-Oc-c^M*XfC#tYXvK!%lz9Brvp?g`lMojOE2;K? zd(B4$5ONQWcDVC%jE_^ihBUT-S1t7t%7V1-30E#;BJ895T>_g1$7p>EX&Df z@G6HR56CXSdDrZtsF-STuLPbCE`Gap)aNJ(#+d66_z`XcUJoJ1aJS8}V%>wp&tUer z&ku0cLAs|^={u-i@Dxc4TZCETf$-|1LqM^>bs543s2VO6&kP=v18KL)QY(k79fQ1l zkk!iiHFE*DTSxPi3Uos;ljM(jsOo4V)eW8j0Uk9KZuuGx2~-zk?S?FCC!iwkK%y_P zwK&l!sO~~p`nMtNW)(dMzX`_?Dxa-HgdtB4&$F1zLeC(xkj`BoJB{f%1VGG>vP{-N zdTns*hP)R->)yra`jNm=m% zGq_Jf47llb@RG=Cs8*K62T%p=;M)p>&#Cro&^Ue*?)eIiPVfTFns^S&fT9d8)2NGJ z%#c>}OKcII2fR5Gs6_T067-zX#wHsx@1aj9ySzqb?wBfGnJ##-Q!c1#bX#10Y44<3 zpw)2TeID{s0X^p>mCmpy<82>r?Wzt%;-jySP%WGjA(4Y{yNgidwQz2p?TsGNUX$Rl zvV{Vhz+H%F4;)2Q0dxyGWSb9pTmXvBiSX9bgeP?vIu7n{;C?3S0$ZTxeV0`TydxQI zN_cHuhj{rwlMbag4sH4t+-o4cPqMa21ZSlzP9sp@UHTmy4LkL(Y~LRwwMVKj z>?V2$NNx5o&bB+kI9q#r^`^>wyRxk48y=lcyz%u?Z7__pZyaHq-BWNdZ+ClIRt$Y> z{?XnS9r<6+;KToFbx5Qr+XJRuEaFGZW_oRYbxlKCZ^k-|UiAK0%BB}db>kt84orLc z+wEVfx0jY=zQyPXKlblB_Wt+!5s<__tO7moK8h#s2@<%H^!wY2tyNhsG5U^c^`D<- z71kO6RRv~)y1Zf9Ihc4E-YehXy#f)wW4_ZLyt#J1b!}DFL5zMTcVlK+{@D|wAVNJv z5c^NYV5rnVY54o78XU>E;}JL#amPJy#N&>~`Zv%f?@B!NHTr3&*xMFQ{R8%9`oq?j zH@4-!$=HO^cc1?7Zq2UkRhE!?7PbUE_4Y+XEn=&K?vxE(%{ey`+p`?#`|qqR-LR`- zwFeMggC*^5e`{C=#H^>J+}^(RXzSjrK>FEh`I(0gRi`MsP zG)*dWX52M~zze9Dt=^L{xMc&}a=Wzr z;Mjya?t>!%9GVga+@|1=$257MTdUuMPS3POm>(*@scL{K1$VsF7fxu;y?yu1>OC3B z@aE21eW&6^ZQ(I}A@pTi)Z;D0Z*vvMf8gYo!0}Dia-a2MT(&+hIp5v!;t-vFy6e@J zjqxc*zd^M&LjHF6=OGx&bInapF z6K@u8d2r;xj(Jehn~>6KS)ch`|0Ftt$Lxh{72=NL`r8PNk3EQT(1b0sXHDtaR9kv4 zWo@P{ec$`TCoa~UXxD}$ZeWv<#CsWDigLJTCmyp59PP53x9Q7GKfSM8oLBN9y9A?W zrYCONxuxR7Xo&e9%bk#MdG*V$xt9-DL)UDs%s+K?)9qUQTQL0kqICb)2nH}6l!_<$ z6dXw&FjW%H@-*-y(imzbN8P*~@)i+7th2{mOAej?(&*bfmYPpU_@c0&0FQ`}B|!m# z7~X#{t(;P^2lJA25kFNFABl8Ue%&Z5Mxp0AB~Qm50fpz2~p%cBYb;iNP2` z_@RZ=Q2&aZsaIsgqM*p7Awf%ci^5=y4Fg7BOdbSkUyjeV;s&C%ZaMiwcUw!*KVMu-OaeErWH&X(3D8mxV12 z@d9@MT_qS+*`#R4OMPX;Q$bQ9G6;_nKp)Dtwf!fHg_DC822Az|pc{^~;M-U@I0?Ac z4vu5F=4MWgT#=dCSgy$2(b8FDZQ*F?=nQ24Bu($2g`~-5JPRKGAEt|lP_G8a7!+TL z(0JsBLeVm`A00xs&==H>zM~#loyzsqEdn0#pMRL)uMOs%+5N~62=HU@&kff9Rq2XD zwuS_QPGG#ra5DVYfBq*`@#_uihqw>n$N?|{90ot%P_!&0Y;IrkxIhnyh+O_hSHY?A zU;lZuT}*hGUSG?PF)-ut4fKK*0s{qf*)ax_CpmMi4eW&E(fW>_V<%1Za?+D_Ej_Qv zq6w~J^$fVCrVfjs$D5iuPIA=qn&9d)Ne|L6HFfeZ&@-67bm<~nQ`6|^Xx?m`iZ>@B z94B1T-;0;ytHfN0z?-{tt^wRemijN*0pHn?fH^NDlSVID8VUIlT8IP|qfPrR{_vLe zX}v(a_*}PTVS0LIdIG+g*}tLmh=|fNv-l^JZp#+x32bmm!M{nIUroXHM6$l|I1KmxRuqv3diFM%mly0A8p!K-=j^X%^@WJ+VN^) z?0?^tix7S&LC0H!4=O>?FxJh(dp7Qk|N76pPkZYS-Obt68DSWPT;Pv->yf=vOh_<7 z?(PUQDZ;~uC4?XXxbVk~1qbXIX2|vX$TKtK``tJZq|kz_z2-+OjaV`tKypU%V4qy% z>Q0aa%G?|&A^oAw=IRu5iqO28wBtjED7NDM+CRmf2NgN_NS*GrN zug!2|VB}g7nW>?v#o`zZ9cFA|ZeeLsT@q{+U1Q>OaQnHv;5Z+^&v zB}YDn7##gVK-n?yo_v!POuix6gcl_wY%Y`9%S+NF6_NQ{GK)K`y z1bMwz6b32azd^)7(jT$!N0$DS@E>*H z*9(bYkOo9n1VbeaA`OK7V@L0E=$3-s8c$W?($A9{S+k)Q<&xw+ZCnP)foR758YA8Nfbn4wa zZ~qxz?YzHsb#Z+wsN+3$^0*7;zK{1e6D)qd12q>&m+~#3sWdZo=?7;KI^wK&HSgGKSnhMT$(YioK+B0P!_5> zb9!S-@xlgEvrB0FU^B92$_0{E#geooR1030>PAa@&HlHnS8DwoZ>;2#_^KTtmIK%T)tZvMKj}@^h54y)M zpS$#jsn_YP=NDZ*>Gf_A?McP!JJv(;eX1X=96vr(X-ZgFD z$R{0Z!fR(GhAe_dfX#D$C!^Sqd!j06ckI>Eq)n zuQquW?|SE$GPruS=oQaJOK)+SV(6Fcbwj(=2iK*vP(RHRb=cLLQaX-b@%MMSwZzK~Ur=NVYGA^}qnv?pE>@LS% zROY<2bZuOr<<2hajyabKVrs9lQrd&gyV7#R!)cj0H;R?K<7?t}&$;^gl=YUy6|TA~ z4u+T}dfa^I>Ef1EWAgEC&xivTwl|ty(_P<-3VPAnSD!wX=S5MK+{R5Yc)^<5x=@>O zqV|erNbr``9x5J>6lxa?=XdY;WZKRAQosJtk4^^dQ+|4_8d&&-!3hd^6>@d0Zq4CrCtG=;Hj~{roF)tpm9Xo&5lWjG>-TFK) zY~l;Y^2s+e*(*evTXLpuQ16WJuVf^;e;euTUag?!cdHi_X19d5&1s+9)>B;YX}r(2 znG5tG$4h?`nk_yWpegy3EV#a5(-unFIcJj6`Nin9@sZpDm-34#hlk}~8J^O?Q@--; z;Vs|&N){WIgpKe>wqo$;W4F(}E z9Uf=7@Lp{ceieTle1r1tqRY51YLVBocHO5(&TQUu@IcFumIcEO9L)IJIe5vao@1rq zo(Z}qKgR@mZm_jHn`@ew^tq-N%^4RyR2()sNfJ@R)2sM6CaUH6-8b6vYDyHkXSemD zYcJQ^4k~}CH1);PkeLRFA>n!76p|LE&fe#uyhA^25}|PJW}CXrb*}~yUTau?*t`FD z>8s1J?-Ru>GnVJ2_#a3#MiT?}1ZbDm9p0}flv@@2FqRmTdu66^$>XKfBj%*N@r=Kb zr~R@_?NfS4guyC>9g3AShl+7Szb?{V{aZ-6mHXrXrT5JdUmWbBVymWA+ik7=$V?n| z@Q=ZA^2Liq55kUH3~nY^K0Z16fy;A-by@J756I|(U43cG*e+prz$cZq{Z~wNn%P4h zD->>zud47dJU~p$z3zN(z4trX%3aL-^o7b!(I-Dnnm9B1Q$&MrN?UY&_D12bj=dfI$;+scPk3sfS-*N>D}x|u!Sx6vuqx))t}-;07@ zcB-yg+>2J%ME9Z*!+KG|6Upt;uSOk>y$CD(D48;u5qoXoOx>)vs; z?xxOIkNZWg$LkVb`naSu``@3p<|Z*{Cx0qQbIG;oerJ5PO`oyTEG_LEdDwx}zrHV) zycqFmUczXl`io=BCA`vv@%IXMu$tQ2>r&O|*)O8?w6T|oUp}sXS*TGKkrZvae*fhZ zjplvBcDp7UNBDVex$(;I^}3)Av~bwdP8Rd{%|$DQUrY)7+n)5_|H_l^{p(kVd}_y< zUSy!V(e8uFZ@uUMyEJWohml72e%&hpoz2JMnh&>^=0$AK{jA@yRZ^z$vQz*44`Ub- zX2;$5)NRp=j_vGL<{igqrh zO|kwFJo?ErNccntWRtwL-TPkA&5l)hbFO`{+Q{43b-894DR8IcV|8kfe1Y2|O}mDN zS1)Fq_3JoPS|5Dgx^qV0qa&9Srk*ct%d^v1+P&+Golm-<+= z?yYZ`dO^27$zs~;kgPq^#vAZj_60qEIy8<@F~sLGCAM}I9jeG%a*K_%jY&_rdPg}$ zyW?=E*SW)omM>eTEf<0WoMZHxjBzafWg8z$8{Wt@-Mwg)&AEiKfYVXy7dP5W_8Zr6 zi2TmSvohBqw?#ZoFsptFbHuaF^YY^6Jv=dSJTKelSbl7mQ|ZMU&&(ntbgYLSjOwZh zi1gRJsobqr(5~Ee?L%4gfo``BkA*|p#%(yh+he=?+4SSO6CM)6O-3wnnULl%dj4z2 z^?S7j^UAiFzTe-?xYEAnvBWy|b}9fFoJ;#2(5BOTH~ZY)?ic}~ZE_r!7~euO}6*HkT0+hW#2qJ|A!#dis{}>(7z#28)zd++I2GE`n+y+UH>P`B5Fgg`JQ|Az?HU@y)`I1>lHDqq%6YPrK~YT z9HN`7WH#n~=a+nVFVqfd_rXW+FskpP)>SJH#>{INvr%%R=;4TnJl?#WV&}<)=TD6s z;^FN(D<@Ao=j!nftBTe&nud}Ntz6m@=jq&|>tw?rIh_y4|Iv%49gK{_Vin@bOiTFP zW)Cjtwtewv%ir*NS2?q>CECbT?Z;-}awAj2=zA^!i+{*fD66bqpm|O2Unlj^$JxB_ID09=TQTa&go2aO-@Hjx6ZA zu{}AXRoip#5Q;Z7-qhU9KfX7*efam3%>}hDh*`ec-A6~SOWrx!Z=2*!T=B=2po7hYuZpXREk3M!cdIty?Af;%Z3GtTni_ecY{rGftfCvz>yG%drc7;U*{c8Bg+l zE$(bN_x03_PVHsJ5975SgzgMqR&pmlx^!>Ki_)5x67rC`i0Z)&wB2pruS!%O71i$b z9Jgsoa>M2MLz3o*m)8*;4_emE9y*5av?}w{NQu&%wm0^V4IW4|R@s$&3g5AjwX&;c zTo>EUB6Z3^v%%AL>P$*Iw8yEk?U0Mbr|;d&$o7}sJqK249I3JF;9VfiF?Zh_WLQ!X zWc^*SbZ*?-xN6h7=(VN65#;$+658EwyYtmzVk^3?T1B_}eouR6rE%g|>nXR&uFQ>x zhLht>5(O91uI*cIQ@Q!w&6pecdtV1N2bHdjwms>cO>WBuR%_F4F}JkDKkkZV=_!qF zwSaovmf1PF3S;LisaGD%DVTmd={J+bs7WZZS7%Nv%GL7lA#dRoiV)fQoPEC zQMp%oQQ*gpp#dLS4#nPq4jfmmOR9;vQZD4)=N4^xpX9SDwdUGyn)`-_#zg;E{A1#| zT$e#RKAve+D$@ATd7>k)euhtb`qqYz6?x=1&9~m~pRkg%4s1#>e0KGayqQj7Ilw|K2|;`S*RKivSR$aTW9YV9r-r+;Mdv+i@aTSr60wmAre-%TbpP3M?y$| zO03SiE$?j=3zYYUETcKwbEfKODki%;RZFwNQrGyRM9G|96slXhqrvdZk- znYa(R#!H{iylZ^LVa(?{5sUn6`TXYTd8abx(~ z=lj#!zde4r{A+ZJE;MI&$H+FH@^jl)uTsvK+3oPSaCy?j50Af3d>S(G*%0+K^>fCf z(_B>u!t0dfbv8D&UwYB{(z-MI2A_R2C!yjcDWdSXc`rH!HF4&f()#A_;Y~#a&L1BK z<)f1ixEJZXNa+T$gn3=yhH51v9N5jfM&(1h=*C zK6Kk~Q29*mxqAy){K)XzJ+Gf_n4(e?@S$wl@z)%eGV6BTjv>(>KDFH}XVX3fT+`Kf z`*=m`*^s=wO5<7UNQ>F~wV8LHjW;(oNS}Jx3Y)OwS5a?Sm#<%U)&-CG@-Yydpj-m5jq!TV*w%ah7iQxv-mU=pz`Mz_K4D%E++aQnMo z^F&RbUzdfMwx?I-7#yGaDz)0%+-vIdwQIHpK-;!WxwCpdO{f{uc&QiByX6noy!DBx z)bY^qt-7psx=7sU85%V$Rc-dp;CJJ19^zGe@?M9+OhLbMmo$7qBF6>8RY;nhfxTwSF881wg z$;t22d{+icl5{mW9S_>X`88 zo5qKe(BH>*jOlXjxZ>Fne*Ep}5`|AQk4;#yO2g++>;7nKg>@>=bFN+vMjxi?J1zN~ zs}bbe?b?%W7y5ETz=^1$22*lJN`2n(0~Xnd?xHLHr?nb_hq19;GVf6jlotoj}KON7^>d3B7Nhva=PhHUYTkiAPYxQp)HHvM9#FMy< zw_?MtlNcbp^J=)_tfC^#D>cq`YW`2MJZ~)P32$2Rc-zH2`>$|LN9+%J`DNVA(l+lK z2Tu2tUYNaPR9GVEg58LewY76n+zWyO)fl29hIOiI0uJ;dMqFKSEV?^-yl`tbZ--A}ix<*Nl{Jv-Tu*KZh#ZTV0aX71Qz3Gij~G zjk~jb!&(&G1-Bin33c=Cm#&EA$Cj5C98T}z#AMf3rPk%KZkq>CXTF%aU~%=ho&&q~ zre}?g&RdH1zA@E&0aGH|V9QEIQ91ckw%EDwVK&N97%gxmf|}(Mde{T~p%#x`8aY@qJ>)yy?^ORbwv4th<@f?5?>o=K1(>oL5z%X}P_Kh`rX6 zzEnQtONi%}jkYWNzVX0RZIOgnvU~_dbT+y3O30ARAw#vAw+4{Meu}%YPp>EYc&z!V zrT2KFLl4f3iGT0=Xlcr5`zH&g-l8*Sz0==#p~$S~0b}`c^lDk)?5-NG-(Pzty-eSo z((tJB+sx3k#05$Ir~F=rn2v(mU+TK3`ypVxUEP^jt@Doqf4`^gY$^-H5c&hXkkI2LsPi4r;w-wQx#7h&1Z2U?H(=QOhc9auQ;f;}r7(*pc{&T! zu`z$H$#eWO%)9p?RiZmT;olt;nt5mV1?b7Ble-ivGMIR{aEpv2Ep)L{^y(h9G*gG0 zav6up4LhTT27aW9ec^rkE{y53Z*CLtQP>O(L45&Y5%)(5iE>>TMEiKf3N%}#XvSBG zF?cgqRgpey?0Zih=rQQjl9}hso4eiFA4H_E23suv1S%7>0{Zh|@#;wpNTqdbe`abM z7zp%4&ZOZn8>htG?!e6wTUe_RIk(u|ewqiXPUMG*U5oeZo$YY)_K6CJ{GvgNhN_6q z!<+JW+_d(>lfQJF>IMaK>lvvlf!R+RKEoE?>H3PY3S{Zneth&``zvY+M;3ov;7n3E zxJJs1qWBhDt_M(=+ou#y(a>;lYa{2zI{aG64c5Tm=-|n=c zdc%K^$@cLtn7-*-%|J$@tNwXE&oknq?@L@jiPuLdF*_~LY7`9-F;N)Mx|%{ppM_E@|?6j$nQ$;xr;Tue5`S$A8&^LIum!~ zd$9bMF6}KlL?LTw$nY8cIO{o6a8_^@a_TEN&a6t*8J00;EEB3b}8m) zZ~NDeYECo5Xx!E5$FOU2L*Pvn-AEugXP9Hv;`Dw9e-;+!RGGO1u4b>f zOZydrI{t4K#6}ktJ(OG$3q{g-00NQu4zCWBMrdmm`Ag?292I{8Oitw6ih5B6L-rge z?lA?Hg2cM5rmb`!lNZnBr_;Bnef@eSwA1qKD`tmWy$K7YamD=^%GB(Xvq8CEnF{~i z_0{&jbP~Ip&8xsVBMMi{d`Z7O=PH$sl#~)kJn6Bnk6_{m@)cal^nUs0TsZV>*EgBh z_;YVR$scKM->llt+ytK(!vYWV$li`5ksd5ys}&qt(OFQ{{yL@q<~Q}*-)Z~Y=LLo{pDiG(%k_lXM*t>2xxl!M;7B zgEId*s#v3y*V}#A#vTM&+^7>O;IXUJS5~nmB$#&`$Y2dZZM05gKfEZ=TILxZ`5_^J zZ@~WNHA#;7wEW`Sq?!w3o!#%!clYZ!-cLBDd_9-W6cK=yBj3bDsml{@8{O0++DZlMs(gpIM~1bOUDP7 zLct;A{vx?Io0Vwukv)hwKG$cIjwZe<#3J`3Un-;~JvVU4z{%m^Id)c+zQ|8M~kOa9Y-%U%#TJ7_^%3eSQYr z84-}@k7Ww-4g%RYm|rVh>tLsCG)F2u8Pnaeluy#s9EY=&uS^<+up}rXnkn6@z5>}4 zyE2pJ)BA2CUF5z(pFw$#F!71ebn?7m^NGl+kTS_4Vh?)7!|rybnXTcrMNRa9(G8|= z5cWCo^sBwxU%BFn75>!xVGa|e$dIM*K=!a%KE#(Q7k0RcaProkNBj#BOqSz|K*?J{ zSr$Dh-HVxDJq2eyz{VcD``T?S2Z8#;mWIQr<@oaS3vWDhwpv>4ck8f|V~fW*JQN=O zhZ@&z84%+({ebu0*~+#hhWw%5!AvK3nE}0 z@!b8^H<6s5fTgAwdB-qybTbNf2IPu+EM;5!`Ae0zF#{xAyTa>~)K!9+}o z$G3wXPI>zMavk-&Uh6uxbtBiH?uaqGz=CnLNx6&lx0mNQZMRvj1Ybx%ykLu)V<%Ok zl;iQU`k*OKe}I;(NTaec51&@{@9(ugP@EtU7oQ(R7sSGOD@zTPBnbeL={gRN`%8D$ zXrOOj>dtsUXvv5N#CoiCta%LXMEmApxCqhWjTZ$-tmr(Xs_RQ(FHDHH8%P)-p%x8L z@inli`dN}zYw5sz9te-4a4+Dgb=8_B6azA}lAhaQ6vm=fF{fe*hA4#uQ85Q_I)jx zac%cX*B5#Yu<*;WNKxbWi8(*M+YgCcZyQMn<~w~gMFHRwEvT1ndsMn---}v2MRkST zW|-)$G#S1UJu8|}m{jzxfHD}N+$eIsgND8$q{trKc_Jj0URaxEk>y$}OY|E@(2U#G zS+9%@Wt=>S_sb7eLVXDXv$M7LtOP0(<9z5ZUtw%?$*{m$xqkOhmU`-m(6V;kanFVn z7xBH*ZxYEht7(1|ca=U#;kHFtX)L>pcj=@1TxO5y=wH!oFsOdW_VH3X$6>5z^z>8Q zO+A_(@ali%0RH{I`fC0wJ5Ni?|CF6a9nD8C@dB!8CWdr98Xz55>t?VNx+oICX1xPt zqz+@wz?rHa5TNJaO2n8Lbo^5Si>BVsN||Z`yOj1N#ml1c%~va4L_fGjbpM?Ei(ngA zXHF5LI#wR7gorJZXDG?by9cA=+Zay_SrQe4aGhmzNqa=x+{8p%;a_&DWA@tJ@vyFM z?3F1gKMb1odl7osUb)VN;K>%l97fRew5DKtn|y+(_oMtPoB@m<&urS=#S2eY%&WYj zcmsPd7sw*IqZCu0DLLgTW{FL&!`Jm2wy|nOqFeV2jml6ji}ZeWKaRs$NX%l!%J&_r zwh3YuMX7f2`@!}j!E#G6RK}7MZgOiUt;|B(V}bak6u@7)NQ#cuQin`|EY`3j88@ux z)(rB<{bZ_gv+j0`bjv*woEAwV2H{W1f%71_3p9?%xiJ}~_|*hEV@VwkRoJq0d|GzU zHe)NZlkohjdTlpDq{cFIH7ea!?+$b2#cK%>Y)`e|69lp1nj`IX)iOy>R=L{SMPX_j3fwjCCV`!R4byM~an z7XrEoC)4Wpr%ab1|@>b`gJpFOH_)l{OlvQVoWjW zSH*!x<0)Ak zwjyT#@L-G9xH19AGd(A&|vWc;gHEZx$5J3kL{t`iVSs42$fo;%0i&1|$eyZj4h`tM1A3yyedR9V#^U z*jX~I)4S=DMqm$Dbl7vuWR;7Ds%#ZDW|n%FUZiaA zTHNwG(GtGTVLN~6!m0W+;zB*?!^9XBV^LyC1a$$4pp}orIPC>w)Q&AV`{G%}7MIe` zmbTx^6;7NZbOGr(K*`;MWWqh^UFBmOfktxbA5_w$O+g08zCDjUh#y^(_@{QHeg;Np zu-bBl&PQJyZ>=$v`EVoJF9}mxf&7(rpw*gNEk@SDbI}aoH%9TX3eA02xSp{F(LE=n zeCcl{OW<*@!uVE!zksY1l|r(s0bq&W;Kl&Iq}8ywQ`FPjLK}|_pcmNO%f~Gm4Ut3~ zaiC9O`KjM(tNk$*wO&S{C7n*E`c??r0&R(Ypj+HHBjS0a$7MRnODvl^vUFbrSR=#j z7EkWcJ_o8tMq(K15i|k*Y8y+n9ju@$8`6O+F>rE-<6pn?!oCJQg|!t6Pf$DKryE%< zO233vkEb%3Cjr4mmvo**K^d%H^$4)bZP%Vz(fK+&iE*d$Q-^`{8ZvM;vVA4RfXEip zreD@Ok74VQ^9QJ2+Ufy2Ub=F$(eXk{6dwqojU^e!hZYjkU5DCcPeFMd<+#`ewdrmi z!)%agVux`=V=*RXma-W(tiegnItd7y`AoS#?)m4k0YOsTfS}*R)iGGSI$2xM>m_=p z(ikZ4ax2%p*rOvf$Zoz{-`%|XNmoBXeJm#y+!a`qHF1}0ONOpQYwL0 z@agS3h6}t7-l^^q7f)25m91V?J6*&5Q8lwpcTZP(H)`+q4l{g=<3I2{gKvdlv zt35b}n0c*4>4IAk1CxRCxwwXUA=TvWvQjs5>!G;{{BV6fh{aU9jWu;fwCQD_PN!oo}tcFIUG-b1N5< z_=}kqw|F?3Zf$>&jJU7&l_k^{zdbE{U{5SYv10HvXdT90I}Ryi@AS#ms?%kT^AS?` z8gT0#?@Mj>;~O<)jJ^dXIdkrF@q?iV{q0c2lDl11s_`3Y$HzwqYk#W3KXimR%q5^J zD!IGYzFs17OKDTNYjUXpBQ*OgYa`YeLg{J1oBy<_ zP58ttnHdJeo2Qpr!L+;TjQo}6^4Vw5i~C(~7N*a6tqXWRO8(r;x;V4=6r-{ix?n#Y zdEie@t~MYb1mViWK6Itc+cDhiYQVPt-KU(q&cB2n(wu{7ujp2-3l2ia7u6+rUJZ96 zE&-$QEj%Nu>~0xG&l_J@sgt~ZzNc(fcYmM3Fh34bG;6nh8D&&=2n`KYv6twuc?Gv zpotL|$#sM4B;Yr-_qZe$eu>0$f85`Q$$iQpq(bd!io2>^iB~Z%@AVHo)lO!Xi;1(0 z@5du9Iz!hyI`im=!rh5td%`h!{G;k}#k#j`+B4!E&m%p@n#{n==Bs=>&SnfXsdT*a z7D(9g0r(WDA+~Nr01CtJ5`VN;=;b?M+Q$HkEh*Y`>P0FY7Yuq9(BPqO=B6d}sRkOW zVu;Sr!5>GG61opVim_n^jnLlH4XOF{*A!#d0%sJ^+jdaI^?M%`_@;K_82eMw9#<{(-XQMct+{Wp<5+D~gd8W#sj?hvY z8?Y1t-YCVXBL5`nZS9j8)3C3<eAmUV)it71vnYv%AzANSm z(=!Gd>eDx(@J_m-U*_h|d;OUzfI+)8_=y3r9(dG6u(GO9ibD~AMucG1^mVx2*Ieml zFLYy)7nKx9b!T7fHe$Qr@l6+~--s|juvL`HY9UquJPWJVol8D}4#%k>KvyLBrfWD{ zYu>>03#RdLyhPHL5J9(cU;Yz#Dqz>T1$C^{``%K-T>D&MT*6gle(+P!Zk`dF8=^jD z(=*$3qkn#|ivAIayVXNH{Zq{@OH}Pu>WH^&_l-`*+P1Co?{CX~6_!^atn8#t(-AI6 zzO_T4Yb5)w?Mv>#xeK>{&lwe9b7E(snFg;V+-?BI#@@S2XibixLG~~%xMXAA6h8B{ zq7h@i--9N;$4G{(4=7FPM{%Q9X1tZqjBW4VI9N|Ak9clEsN3HM>cwtyo`Xq>`@@M_R`RW zx>&VG-TQ1?QWl#UZ^p=~lI-Jf`@d z5vMrILX+yG1jbs0R9>BHk&!m(tIdlz6VM6G>J%$>ESOTBp?as)?Hw1Uo9entyWQt( z&tTl4SEQLE=R@ybp*gRPLxXsFkr!aQ)JwA`9uF2uDXQ7gQO=dKYaIe7dR(7roYa?9 zK&^hvCB<7mUie0g=x`fE@v0z9>=?<{iT3!0GTCP0`WGP{VndN4i-*`!e1X;KAsc;d z>!Z<`ZvOX!H)>2?>P04mCl&NkFA8d>c*He4KP2`ngG{6NV|g!uPZvzg?|ZC5*}}fk)I3^DR)YD{ z$Qz0@F+HOIaxH`D-6$Yi$I0|9DMPa+d}S~~&0>U$RdM!im)@3jkl5nV$!gJIN9^6Q zF5`g3z+LF@?mqA>G^#`DA2y(K6Q`AO1vDbaXwz-;dGjc=s@Rx)&HCQ=@{ze;dTT41 zikEH(J;45Ke*D{XQx3~SWxDX9(yhVTVq;`}YDDQmmQ(u#T;JJMTGWH)xO$F`U4AU9 z^Br~V=J~ViGnt2V{TQYWez@tF!>EQB45Upm_`vEEE$Gn4KOXzF6Gr(1Nla3aWmTJE znnzB@(1JI#vX=lnOQ8kt_=@|w(bOsZM*ULVs~R>lO#LZSVBWIGcLi6?0~a?7LJ`0< zESIe1w;$QKf)k9~+Hs!k$=$znU3(sc1wWT;x4Bh@+rXgde zD;yDK%8GyG?E32qmlCBXtk1qaF6=8%P?#W&!OtYRTraU($;1W^9_W|CmlLxxzncp= zK`$~~Wxd3E9#e-Up}43&kTj2E(tZ|PYr#IcgMA8ZMOwCZR~1X27;jqbu)6N*8Iq<6 zaS(*LWux2D|I$6)K1}`89#L@5a~p9_c&Yv*5f_QOQWYjgks+4!^7Bh6&LB8fm0KzU z((a_{aIf9M^N!Q?`X;=(y&~O*@Io9Zvc)3~r0o$aTziu-`70f~BO8=^_#urcz0tiD z6YP(H0nWyT#%TH1NsBGsx0F|FbL+Bpa zTO)&<;VC0A43?MO<^3is4KI%g_YwZ>6xb&g_WwjEu_? zS@-svVhPQSQQG3RNn%=bb?*-(Wx6n8nCIJMDVCUxqWLQQ`NLi$>sm`k3^erKQjYBV z8z=q=yO$*zQki0}oARdUN4BZneW`h#A5j`i{7WZ59TKj?^$gik9xQCfXz)(?TfG#; zw2f~5X?@EYzBIjbN3c=8*T-b3=x!5)R!_3+*at#b)^^5Ub7s^`pZ=v=qW-1RJPM(4 z+W@#B?Ju839aA-k>Bg}9*1Q~jPvrh+V?EBPmOUf;;NTI1$nQ~T?w4r+_t;EHUW^fN zzLfTj8(|#OPGJ@eUho)t2otqG%cQG|i_X~yw%vIAP>tuNWm2Tl@h0tD@p4_;QQW?k za0OyUJl;}P2Rx{4&T`z+I}^AyR5dAV4=XTdx@Ml7pBQezIeUXFE> zmDk1rqkiUQDGp7#m+x3Szsmfo$2HBcP-KIP5%Ikc7ozr;4p}u=V6A_7eSB)xTOYju z-8o7Ao=g@oqGY=i&;-gP8uM8=>A#Dh@Q5bY!Ucu*#(L}rjZnXl=gCZ8aIAjOKQ)BN zzPiM|j4`EdE4Rs8;DbI_I>l&dzeJVKPnjG=&*VkaQGAJY_~f3Is%zwQJj;dNl+}%G zx9p`XNEx72kIwgUbJG2&h{Rs+56pX2@;e8+2@6Hdh#kwKV_xU&HOg-+4oTZFm_^?O zd$Jgc@_xB{_;|JIFWoA32g4G^h!`-VF~7BCD8#DsEW(V+P0Wl^XUU%-J9etdBJrnu z!$FN>^%a(tRo8cIzEW*&l|OFH&B|d^=t=ulEz~_P@ugk57eUMeBUsxcTnSLLe&{J0 zn*Xb}^t9ZePnSCWIks&|rWYBoB;#Xf05xgJxaY_|qBgUHTzPTR0AHe6fmx@zb_x?M zp+}16X@X3F?q9l}uBb?a6N-gg*NY+QA(E|mA{_D-%yN2od@8xWEe$EPw>P9KeRq2m z(YraS^<_{1|KQGrV_s5BIE9PE^jJfXbQrUTVP7@4@x)UpUJ|>W2 z+A|?Wa?m_mbc;=kL^q0gg~~Nnl3QI=HzIRwtm;p0x^a=)=BT0qmzGJ7QxyFjdI8ST zow1%VD7j*btU*kT!qIw=bczJJ3Jby_?a9k{FgkXhDa3Nm zz;14U|41?GhC&ue;73AUa4nmHOw)8Dztx*A+Qtv3PGaphAtZf$63=VD)>-K;JAtv8 zC!-mZo4;*zhL?UDlKO@PwBm2Pws5TBdLJ=kag3OvIlQJ3J;&qJ8&e%zu*ZicE$Jmq z&1u>VIQ8m4#Z)|9%5<#E_e&CK*=zeo(&$O`B;;kcp>$t z3Rr119r~JpE8UERZoI#0umz%N<5TZEgli8sCJ2Hip-@|zd#g(GX^StQcVakZLo6H2 zW}bpQ`=h_v!QffW@i^%+Ru6Y!X~?b#SW>CVr-#+TZv z1wPMo@?YIq5K#&)h`w4y(7C3SBsqTL23>i10d0;R4Wn_1-L3!gJK&;}WD%e%PO?l= z@>3k$|H|?A|E_WF|G6#s|Lw*V`hV8%_TOZ={@=Ye`hU{z^}qWZ{=0sU{{Q1mPG^$} zgo*&~VhfEJ(9<)EgT72QkJ=Jv3Upt%4E$l%X%ZFkjvPFVBmhq@_!&{yeAQJ7L!jg6xtgmsdHsgW%b)JtB#BUkNT z8X~lW6!?e+vjF`xXujU?>D3+NXSnuXx{q72v@i}zrdo|0u)X<9wIE)4C|HHLlPnrTf~ z;3d408Tm(Bx>=PRKyIGL{C2-L6SuLbq2Q&5X0Mz@oo-z_z7kh=pMld%EmYg6H7^9D zU+R)Q-7qZRBi;5SL^VPWSw&~_soZXjo6qU|x=C~NDBXPpqZ@s%@*;gNE4Yu=w!}Q- zwRF1j_1e#~|Hm)=`!&Iz`6oSY|Mf=DFW_b_&?@%Vfe(m*n-^ZN=g?l;iJ~W~oiDW* zk+rumKb4v~1)@$kH}5X3Edh;h*m>Cv5sd$ zFlqCCxuIE8pr+y0%atAhfn7V@z!POSM>`qx34S%LTVCRIo03@Du~MOm%B|nvDelT) zu3q$pFW`>_Wa)5z6wAKduE12jo&gu2bAb5Vlc1s6V50ck`nNc$ z1Ope>LfjM4XtBrA*4Ds2R5F#9{OyG!3D}bvpdr*of)N)JV!F+z!Z;=>`S6vS3DzB% zfT5v`8uiw|{-8fIvAS;_w^}CGtMi}SgI_1I9X!gr`V-5a%VXLxSyjCyhmw;M9Y;$C zpj%p+o0{@;s~1zx%WpM-l}n$tKCHgwc$%(3-@D*SqJ;6M_)AOz@z*_Gl-d8KbINtS z-hn$!KR|A5qoMp1T;29AFevvgos!=}<3!7EYxN!RAfLHGujGMkvl*$1v3K0ZGs{Cz zjS9oT$7oC+=7Ktc6iD!&j3FZM!?Aw$(ek2UiX@>DM6p{&AWx>lST9eu-(~FdcZ^e_ zzEsA6BS%}pdSb%jx^K5IFVGDUN4-g8>t<2wQ?-beLwzLeBj4-~$>~KOZkob?<_%+? zTE+;iV2AK6l?>;127J*kIp0QwRZIb$*^_c7oXxiuyw)Cx$I!Xj^R~OhXPR zPd}a{xLNhx;-Pewa{vsElYUEkn9Bucyj(c)QX5T^^d)^9i3q9O&S1837EOZ%>b$|2NteK4}m2vv3HxiUKvTeeU7J=rlk zeSMVje&DQUy=xL&gPcs_w?9pX8xwF>>@^V!f@g(!SCLp{WsEbZ0>wIK|EtrdVc>^I zP}o4Kg49icw@p{+mvGTY=8mgyg(=#-*yg4HYSFcmZMG%0(;mS^?`}vVuYhSQ%rVXj zeK5Y&x-?QuW3-|@wThA6A*JpLUq*FrdE}Zbfd(7J z%>#PshD0`hOw6M1Kc(A2#LyTW+?U~~<8@ekr-opNbf<^Eqr3Px6b0B@*Pm9Od82p| zk`w#ckBjI{A7!+1ra{s%0Kx!qQfT>jv+dQv+5Sf^WEoj67ZWfZ1^svRG%b z4QiiU9>mn6qS`0VsRCr94A8Vsx*y$V;7$TVbg}P&A9Ej2TOyISa$as>!HFm9%Wx`XrPoF z;ByA|iNdBWTS2b{7^J0l!iVTETKBpPjL?#8&^xPxN`InyM?7^*+Nz z>^<#;hNZ~?7-zBDRyYiAq_cMo`U2zN|M8KU}S0tR#+IlC#M%L~{o>vl7|4j})UfefgTUYV@wThj{oo&@@(2s}7+TDfx znUQ(awPxs>B)wRHoJK5!mUJgybo*(yqB`_PNQxvEOR>N=OrjxdkH$qwEWN$IUsi3t zW4ATndOh~SF^^5wJ9Vv4vT_VQw1@5pj2~MJ4fYopt2eIR8fo-K1pu{d|)+J%Xw z3X@ys$!*T~nUE97#EIFcp`dC08swqy!Pzo_kGy^WJx!;I zQA8%;x2QL0`OSRl330M@LD2AyIuL->JV0=WwQ91o*Av4Q0fpKL*K{{-sL? zB3nxq&J!StzsZlUX(GPqVAFHWppO@knmC6)BSd3~vj>t3g??FjuXg{({_H z{41#H>M@f{)5N80*g-FEdgX+P+>r~9@7>w{6u1(3msAP&CkA$*VzY-MQTs?Pa7%O% zf$jWCMlB1dQ<|YZ(7bDFU#>d8*<#m(8^C#9`>ihbN++twlgdYqz%9rnQLk4~xEnMi ziPhoxzuFkGcd+aFIcBL=S$se_FS$?h_+J_3%;j`|c_AUP*vTU@vLDCfKb*)D#sUlD zG76;0YL{4(rcBp6M6x!D#};mD1JG^Oa9?eeTz@`&AJolKgYq*a=bAG=VWvbL@ zkFiMwqXzJH2*2!cYxSUo^h#(2LGa;UI^Ca201N%G#R-(>#&T2R=kOG<)@;e?)N^3Q zPxX~&&-O@4q%y#H97*f661!WDpA6C^$ ztV?T?e$(6>@2B*Hm$d_&rBW>|s2H4Zn1n4XZ9xR?NSsZMr1dt&V3ji~Emui%{iWX< zd^-_}W3#qBkF<~*1y{<$FPo@z1e!~9v(dCnVV)iYQ$D%B6y|QrHosUjZf!dk>m8&- zZHFBg70t}rX?mYCp5CZS!RjnzEck7{?WDUfRZZm}4^f~b$6jmkW{*!p3rN5g zVBJ122TdI{Z_oTRcQB@nx387hyiO2Kw7|kO0OS~ayO9}&*xS%37ggCNQcep@^!|$+ zO6_w+AvfH)-`2pgK`_SKT#&U}{M!TMlP^eSDi9V)Xnfrv0{4Ypn3fAyyr*eUW5lHE z@2^}IQvQaWu;kLx&~PHan6YMpy{+=2r~bXx@GnI(Z!eO$HPvfo9o;z9@hQ$jd+|v6 z2s&ffsl{oo#lUGyD+vC54&nb_5z9^6Z|v^;q`_;B9^uOrgX_t9#JL>*vf1>$1+Gen z$j!)!886O22L>2)+wx@9*68G8HOi<|96;!3#MO2uM({T*mmKVzrlPT1|g26 zS_pcqt>K@jB;NGzK5Ca=mh0Y8H=fA16^!CqQW56YV6nCaA0CF?Blaj`+eT+rcXcbR z3Io$XUq|!>n4QmBBt3HSf2dcRe(kbWV9L6xIyT4cGY+KjF=I7gGG2kVw=KcUSw6Du z@%M`?iG>koN?cTmm(n?nbPro}wo85rN#NoK8f@IJEjBHwDZy?cw zxD3Ls2X|T97?gljwPHcBPHlNy(u{4N0Ofyz%9G+#J^t`xBJAt8yJ<}YFtTsO%4Jxl z5qXw4^R&6Xl^B*82>oaci!rRvz|Q?V8WIhtvw6s`;S@QPQotC(_B-yT$hmh@yS@@D zg!B#rso>1JyFR!L>|D78bg3PuNi68LW=o&~;aX(2qIKMPT94yO2P@g58V0g~a+5>n z$Aq8RN;xE+X)-qz&U@pK>YQ*p>Zc%XR%ZGLl&{#v0 zNpV?!dH^{1j%4UTT;To|0$3L|oF_w!s+#S~C+66a*l42WrLdnJB9qWILD%9Zn;{>E z!4PQ4-1KT?oLuGn^Dh^>MZ_&mt$dm^Zl30<+b?W0ultgH@hY+EO2k20Bb5MLDx?_p zpnfJ^zx5v9+>f;}GfbvYxITDtEYn0_<6`Umu5ymk%f?m@c8(~(Be^=tY3g3SiZzFAbdt*sG!e<6Vfo>i4Vs7atwq!8|H2i^U4~Q zK$&A==p?y%Fpt7-9pTNmlV(?gN`Azu#l|{kFa#B?D9iy@NbAy2{!9+}C|*{MT`kXk z_OzNjrPVmj2QCh*^Kw>YbE>JFW`Y+ud zM1}Of^N75EITEjYvaum>B&*Ujj-V8n&}Jy8+1G2UYw~#U`2)cRSCzsmU}Ig!Ja6jd zF1a7SHpgOOvsV>!v{^bfD?jZnUwUV=<5q#wo@m zM*^TVQTkCR!Y&&-Wieg|-B>r}Ye2M=PdcuyRRC5LN1e`4m+I%-7ZunmsdPi|CRMfNb*3>g$j` zGJ>}2ZUJwrSd(Z&Kk~`jgyE~-h>cy1*xbrgSZ4nx1IKPYmJD>cW--jeB%*I%jz6SX zq~46yo{q_Tl=Xwl>{*R}lqlACay=^;e5^)6+6sbZebZ`97LQJ5QAG>T?2b&2{qj$F zFvyG4r6sMntMA%U)fgU`@yhfN=>$@PEf!geNDBu|lY4B;-xSt_g!JzLE$wOkJB#~c z`=_*kz@oM3S<*2g+L}iY)L5G14jTQgujsoS>ty2`R!B}+I7f~;xkPU5D>12=1cAse z%IEYE#obEn>EB0JO|qOK_}@yzDV#L)OR`@(vR^u1T)6qrf6AyoM9nL$4!uE1bTc_f z&(~V{v$=|<|yOc`#o!#na5jS1aj`f%^C?hc5iIUO-dD! zR?!jZ=M!m-vu{)0m)Te*@mm86l_e zIkezYJ=fg<7K#exZoMtkZC__8U&7>rD`h537;rbEe+^)PZbf%A>bFW2G(|jkmm$HL zpz5TM%7(YkQpH69-5!v(4}8ZpMB(}oyQbsYa81O$q^yr1YfG!BF>de%Vb{*;PeO0Y z8JXmz>ZP~O@fL4JsLJpcIo-6efEqj$KpcV@WCznWA!!u(&*PXa*D`OC))K)G2t!oQ zXY7o1#@y~#cI~h$%unW=A8qp9gc2YX!QykRp2*qN;Nl~~np~9V_S#0HcIK zWt@D41f{jM&60q6BTBQ{M#RS{G@~2K3U(?^23VWl+TPI)F*U0VfjRTA_ky`L%+KnE zf&aXEmGW6F52Lr*G;Kdc48RlwHrh*D@00}HIcQv{>aY$9+IFCMC1n0*d=mZ09y{R% zbToC@v@Q-y@P;rCd-L^+F2-G)h=1|n^G!~HKaRXrag=a*4n9-?-*qzlCDMAaBvp>z_i^(!HCJd!bvS&X~fKh3vq2A+LjRR zg_u71+(JZmq;s`^z1QEiH4MG*OYjm6F}Z-%>U^tkLAnkK1jo&XEwT#{aJCUWM1&QITX zIq*w@xujG*j*>&N?ccmalE4pl3%?1IBF8`-SurGz2lZoqLu!v2W}F=FfzAKX?4c5Mvv11%WQ()dfN$eHks)Gx#GkS zHi=+@D>sfW5cAN8YFM&P+Z5V>ZyF^&<~O6}(HgS7@uw;Es+?}lp#1IkySw$UF1GjT zW~8%R<6#mWc2YF%`!8Mm#`DQ@Pfz2zwoYs&#-5D>0E(-irwvUyd$|e&ljB2BzMdRe zp*0t5=MSl_&k>NeMxfhYc;F$6LqHrG`+p znSEz}*4GN3&t3Mpc&}F#Bcsl+V8l(f|H3C6uE7WE*t*C6jKtb39P?+iKD^pvN>w?X zrCvcPv9-q&P{nWR5o6JOiPL=aVT$Z%euzB-+>CreQXa(HN8w2}LfjMTkLK<)PWfN* z%X!@4jnCPuf8Fgl?Cl|lw{tQBzp(lG<&GKGw>R@xqL*=n5UAZ=A;9=Ujz{|D#-D5h zwAk~K2%%XMWj$0(TC^VG4zqnJ{T^air2`SZ7YA<}<%|%KIO};wI zuG+fkZyV(=_eMhr0)0qa?qOO-u)8B!I;2m-{XrnVI*8scvfVLNL`Hr|a*NZ@F>R1B z%O*--68hSsle$wFCKMu#OFb}|5Odk63Udx=+J?BsHN?ptrmm92Bp`q3TJ|lpS5CQ( znu#h4sLeBkZ4MZH&zxAiX$x^X`7pF$VE1ADm}0xU1Uh4B(%|NiY~I>B1DCBUJMZQC zxEp;Vd%``a%akW1xxQSH`6*gZlvT5C4dbT5Cd~ER!#E(%-l3 za0YZfGKp%mP?n39zv^i}adSLsQydE^-N9w4Jw7yF$=#~@ShjFo)vMC9wsAqiA~FE zaX$W;^W}_RR)Wr8;=)@Zv=@oJu;BayS>R>|7*pp5ltiIHvnD&;Phw0!RYuyAUiI~< zSsM5Pw%J0Y_E|CCGLspgBF8#HBz|QU@N~l zn+BSHH^{y?+3qi0!Jb7Il7V`i;yJ!Q{JMo^gl;o)tz5-$wW$S_4;Rd=8e4T1=`$3y zj{}{vtV%)$WvAiGZ@ItSk7U$XM@cIWlsoUI^QD@29rqoKn#5Zd)y3~@40KPK(sd88}#ff~jr( zHIfC`+9--3-1ypSDf3F^A&5ewe;E-1|i_S&y)^uAONxfffWlZOGfZ z(~`D%&}eL@bEx6S`#nwmUG8wxEA5}-&q}rI4fd%Wi-*^D?+HWK_Yol)_UO|@pzA$g zcMS}rOKihJ6057kn;krrLiI+M4KaDwnMZ&9?)J;%c5t%Md#lT*`_11$w+f(npigE% z;BjnZXLS{2Boq%t|D|)b1qW9b6t6u!ZOdrIm0H_sg{WZPXCjBPC{sr`UpnoPannUx zOa*91H<%u>ed>W2YFrymQonM-2fsZ^6||zLkz76`y5hGv$&t3iu@&nmYMOW9jQdoe z9P{N_YXgW+4#eg1z^8|aNrBJ#HtY|8r@5Kk!A4PjG^j%pho)C}4zu&pmD5Ubt5cIa z)^BF~CJ!5Eb3-20Ri8_#{G?2Gwv9Oyprsb38#;;W7~JCj(7F%ZZr_|CAVRj_BZw1W z>aYdYJgV>kKC8Zza`%Ns<_nF)3U_OR`P!DZL+Tu})3y(MebSy-Tbeppc#3Qg~&9EDMo}b_IF}P(p-FFZRls+%`U|4C^_)+_x@rID2 zZOk0?fYCtL;GX$#C=N*{iFHeu?>9m%6lNQQPQwI%xjp zC1%zpR831o{Lj*1C<0~vB=lD)Akz>z8Na2z+=sZ-c7{Z6LhPs`RLNIEDZHgDMh{z} z*Oo>@)ZVsUVh8DSsQX9^ikfi8nc+ubxVk)WwacBtmsi3Bf6DGj=UBo;Gv(bHRlTZ8 zS6iY!sJza3lW{z{#@`U_;6rMwOt>%VY$1GqM0dSuEI_{j3D`W$bDfuqq;ZNoKfKh> zeC+&m8*I*Z9pw5}`+!A3KMPWDrLOjDs-5BHHG74}Z?kwm%dfsOHj}!m_H8!pYH7tk zXhV}*pZRde+c>v(rGlNy!{;&)L zdxgwO_KN2~D#Xx>0Og58SGfr(P^5%v$ll^Ktqo8OJKK*BDAy$ukltbfTaxt|fAAY;%o9}=Za|{BTv!BQD z>3&asbxX^fq_UAk!@OLui1l8J4mDCoZpGRaQI*4Bp?q+@K0Kv*oX7P^E&4=P>&UEV z&MfTdeL_d&r{w)K`GdR}Y{(>flYhDu9bz}MzFwNa8kc;-IzZzQZ62#5^sGmVc~pTB z0m1PLM0WNv)q~tHP}9kqmP0HoYV}4Vp|=5@N5!lgqKK@W-%~j@)Gr#BW6X)|(J=(f zm0vLX`=Rbf*CLMjJ!Syf&y?S%8D=m&I#GOdpX%gh_Q3Na|DW08OIm(E36!~{ck7Di z(SfN{aC_rn4kqAN9%JNG=B@_I6y^nzZH*l!eSfUYw5k)2V77739F@p&Wi4%-8iJgx4~?1;rvGGgFZV)km{?<^_GB@MtM2aTa_&Buka0?aqAB`>5dGHM!ISd5^+%qb{KmuB?12H$h5CB1<}H^9$sd!>=gwcNJv@*k zhlb#BEMyRs9m$Qgf<2z|FyPkbZFX<8%X6qF@Vbm!mM+P8(g&YNa_o4TnxQ<(h>BJrFfU-BlsFKkGrsSIF4|Gu;6u z;1)-)$tw04(dr2>$jh~6Y(873@UCpCnzX#k0|$eE4&l@6Jt(7*hc_O@O^!5Bw!TRY zo(14XQYH6#-VR*1?8~e>b>x<7{4V;T21U~|%V}HHL};K0)NjjY;1ROw)fl)P_*>+4 zk#H2qdCJ)%bkcm!HkpptxN%enGhFUWwSpD&@F-KypgmYvN0(0&dszy)GB%m&11>4X zjXW;5DwONfJipXVjg$V-=U71~8MdO4lZSJyTXmI;b4Ws{*uy;o9&AR2LLR$9%jU~7sd)pqn_cp7C z%~Af&9&0Tu+6VchlJNR_E{J%;>w48k!Ag0VL98{7)wb)I_73&64dVfzhnewr zjlDU;AL(>yfiFkEEf$hDgGi_@APdDiAJx4?wCKUHtzup3&NiT2%fUkh_Oqv1+f~)p zIF2@sGv|KZtF2Wp{n7&O|E07&9YZkcF%Skp<1pN^+ijY_1H}%Z)}Qsm8&z@-+kSdQ z?W5PgX|{8{-u_}=&*T5R6uNf9_$qHD;tKVv9e|uxKt5O}O!YWTs)GopXQ#S@14@eB zz$KP$8Qg(P!JnjgTAIOm9%y!(+rL@XxHtwGS!{sq%ZH%Z#++ciW1r1Z#q8QK$fXEi z89O1nv5vLhXYS|GeUIN~p5^!azpwxOdw%z)PR(m(uJ@dCu5+DpKG)~E&NWB%oJ^SU z69fy)>nTVgn}(X|3qrcq+?NIn&AiSQV>$c;ZTQEU@{De_WNO1HTgs9`lk(2Y@>W3= zbeies?kd(QGEWXNx>SeCn2Ms_#+mK!K_cqAXwp4&rlO&XCfXF8FVbK(h1=VGVQr#s z4?NL&AKt_V?Bnlw?uEd1*D11085M8bPCK*`ldX=}FCm-*ucEncD|WPz+!t0{l00Wf zB4+8JX6-=h^(b{&muD2|7&DhpXB9<4cO5*g~=sH}5DNfdyg> zn#_V$f#h#XcO;SqS6~u3V@Ao>J;T$H+HU+|<;+UXONx$2ib|d0Dm@qn)v;R~{I?4? zEtR&DTuctHCSwoJ@*m2PXf3eQfhwtr(IOD;n-9yX43;z!9E4_o^H;g9F$kO7C-Hi< zv?{>pduRm#DGk#I*L^R6Z}h%J1maK5umxhawDl;ks%l*ye@l0d^Gjd-)+hU~*iy z5a`h@?x^0u0gU0~T?dyW&52ZCQ!6J!oo4uru}s6Ur9lgXaFDpm;a=OTSoZ)gMH#;; z4uy9k;hqh53;YZ&qfxzb;ZjluPk%13D$}}7*C2F1h}7mreTa+&!yRrIyX1CgzPyUB zN8V)BX*5v(UQt0Fh3b~1=v=-p06hXVvn_uEEA#nkxfr(ai6{8^qcDDfvgxhU+c8_3 zLmZ5gJEwseKTa$)ddv6~62%p&q$OFrQ5Egd{B*k$-T0_!v69pB2||r8W@mKNAj06{*UF>Q z!;^@WbD~psVEP7kBN7}lia#_Nw(G(hQ`l-A261@xhGq`k??`>c(ep@UD8-;=a3T8G zb~aW_fh#HP^=L~^{)OD_K-;u0UTJ(^`V;_z5(y6s{;FtYMq7skZZwZn!bX!sXtN%; zvV2z3s8nEmfNqcxaHRWs36>3mIyFvVPEDM6-m7eV+P}G`Pq(yeY-zobBY&zezY*j@WHgcpFweDhh%0O`M5#n@)NA1IbChv`T=J6Sj?UCQ&+kJ745ZYTb==1 zPJ?_8xE4?&S+2E-R4SS0ZD$Ip45Me@;X|?+#rqYD#>(z7+?Q|mljgQDJXA9jz4K9# z4cJ|LklP3sw!?@$nf6R8`&{1p$34jBL!TA^$dwa!b(@xSY z`Fef0DXgeoZ~c~0z-8=UT=HT$ZvJDhdg~A_I#9XPRz6F_J~vHh1)b4ZItlBa?=ibH zZ6q=)GujeqoDcj-;Ir5dG_U`e7T z%u2`3w9vg8x&316g3QdsA=L28@Y2W=mEQKVD=ZY=`e$xeqVE){z(ajc*-W%3F?r`O zIH|E^`6msVLntEToEUgzdXo9w6Y$^H@bwfi#-HSF&pNaQe5uVUgXXgF( z=u({RsT*Opkcd?;;CKoC%q`&n%vzm6JO?#OprpMgD~e*=-yOE9ik>hlB3XULaB)E3 zbij#XO4ix^OhO{iYbb2(c;X4wkMf#>0Iqd$48cd*{m5Izuw~w5{DPR>$ z$(#i2nfy`1>cB@Vtf5NQj`AdrU)|?a&?iyFI(emu=wu)0atw7FbIfKkTGOgBR18$- z?fMLJe(uT^^Ptz&w!mb=EVij7bsm0>vYvxY9`@?nLEpTJNqu@6v za>a$MfJn?<(OqGl8=hT+PyF{3J+4HcrfoNpV&ADsb`(ZtV&z)Z55zOkmVo zRc^aZ`T%8*d^LZ3n*32`MvYZy?sFIVvt_D_2xLk8YaP_QyL}>}`rSBf#dlp#r~c`- zFF*+~vv{SiLO&t!x5YoU;IL6e@`kLbfg=k=xMJvrc2F*=G`julH3n2U%+;)LP~by# zxd4xq)r-84&Y0D7+=o=2POl>hRQ-o(p&Npx{F>5O-bdlZXHC^=;&hIA+`S*ocfmeX zP$f`?^G?(I%6+414)hjZCemUGU4JCSo+s%_;D?>I_AX5|;B=?C z7p7N6?>y@~exN|sXmF+tSQv_fnc*yfn_oKUY83=)l97^{XP!NEbP7{mNB=@vM$I?U&>53O9cN+{hJX`;T?qjOX`(4sc} zs{NWa9G;Q#&b4d1YIYfT+@*ud!X6uCFI<>^U!)dSF4+D0f;BrzBv4Q#KgQPF)fKEC(V0&M6kV|#ntj){poA!hbCHZs7-D!CG12fPz6A0p(=1V<@Cs0+ijGI zoL;w-ali16RDgh+ZKQUjdRf0D!-9${5n0Am2=DF@YpGS zBkDmH^jfdIFVuLrIIr87d#!J)wG~*bO046?V*rue9Tlpm?t!@~FfM1OvxiQh%*}?bUZ(mFJ)@e<*O`;4cg6 z4+_*X3;QYh&qy5?jvL)MN*BD+j7Oz!t5V z@X}63Hnj-Lr;T;F8<*hFru4$Z_(!R}1a)3}pQ_8`wKL||-$&8Sc<_42cVe(>Kmlr> zakVW2-;-%Cz0PAr!sVqr6oVu+6D*3`^CaosZn8RlQ-_L1bV(;F$u-MoD)AqXPNv>z z{9vMn(Ob7}L8+Ur1&VhTI10NKR6j4(oR*CVvs!5vhh3@KE?Cs*&EL2QYzN>dc8|2u z^re_8XKSsSXZbN8xxjPRKbNu4KF+UCRNhrF?UQ=t%HyDnX-7qynLj{L_YiUsv~fE zicYQ>vUP-aB2X%l-VEk*ta|f$O5ZB8cS+K)+UrDPadBIFUMWWObv0;HFi%Pts~VI?tjQ9VcC0UQyu^-y9$zXeZskT~Yojdx9Ov z`7a|sj&73G`mo{*b3S7kjhKsLkO=+CP|cFU;x^lef$>ExmGlH2RJ3|J!1T$#R2Gs}Uw5wLu{6cqZ3?u+mIg`*ITn9bow5`PTs?&1l3CUI{Fp&{R=hV?bf)ZB zlYqQuuUt?r1Mcvq?l)7UbCc}hpyF!WjYP%OdZPeT&XmNIky{2dUyH4N)wied%Slwp zgBupoQ8g}AYFfEg9ut16i#+^QuNSbpqW9;iOl~s5y zn{AMqA=7@6Kj!`t-Bh$sAR=NxAOMeh0a z66m?&N1>5oCJE|`7l)IQaLxrOX+&J`n-YGBtz z_{*?w2aY#PUH~c|J;|KSsh~l5No%syCf`DPF12XB9gH6|;{7oCDXDv)qTH}lr&ix# zXQg=2L1xlzU3aqj)#hE`NlxpP*Z*wRn8@c~hnEp-5+Ks<&-fj(f41S_|0-Gjss!=p zw6XvF1 ze(FE5*T3e+{;W3E@n2+Pf5n&oWQ_h#wf!r;{8`8TU-9LC%I5zQ-2eXjmqK~<0z;hT zg(~d6r^kE0onMlD+EUV1n}0{V>3%e&e0Rg$)>)}n_T^u~J#90!t!=YD^OQgM)yA4y!ra936q26>bP_F`c+tV#l#_?b3gbRjRStQ(nBj?8&kkWy*5scZyPU1a_e`W(mIpde7X zFpvh#vEN7yrT6RUH8f3cVQE?o{l-`E=n~7@01Ur1CVjtVBS%{2Pl)~ep>Jl$S6X~E z1N_}yazjD0!txhJv=ju$GL4K(zV%LBM0UY`@+Q)!rEa4je5E2>$tdwl(|HEbVk3nl zK^^L`q^lK0rR%A7qv2j?p4|FZ^p~tBE8*A-3!DJ{lv2n2W+u4oW!T}vm$H=v#q#EZ zgooasU>^dSqtEb^9d_hsIicrDE={H5pdoyEtLx3wdWmL5Rcbl)nWZu_8}wqyd^={t z-gB0I$$Dj?0pW+kmPT$_n~xyKZa}-&s!pd)YiY?&YZz;~ml@}sgOja)bqK5PdK1i7 zmyNlH`6&P*};Xv_)6;~hVhnlkE zyhq?`Jc^Yxs2r7znp-2Jt=+R z>Xd$_-StHt-K?*|b-uNeDTC{gu`}^$qtOm)oYk+!Sv(3k4^SsD_n15uyd zzO>dEslFSTKLWklQ*ODUpQlPy=~FdeTtOM>1i#$Z;_Ja;^p?S=`)EKpN zrE3$TS>a}2kvL|6(8e9yQ7`QgD4N_57>OkFL8tO`OGX|>#xzthbxF2_ZZkHN&JMS* z$znFPQz&@)3YL--1RJv^!4lLhodgOwjzlNdfH$46Y^y+Gsi{4JyI6) zdAqr~S*B zIOkp-y%Mki&5v6=&b^*_i$O~D_RE`vC+3dV#O97tR8$W$^5IUNH4=076z~yJ@e$&< zpku~^b6&lV6^?X$xpf8`5G)g>aAK03Gwou;VC|ziyTpuQ1_q-f`-|sPSGe8;uy|jj znlN-oI`$}vafuf8RZ1j`b{aUF&jc%1yV`x%H2o>mXjDCG>NQvYP3azZ$5K=zm7(f-S~XGM$<1Ki(fcDaQYG*3?=DZb3)ZVPpc$#ZWyGP{d_RLY%b=yzD z)gE;BTsK5!l`ISL6Fe-36d6v&jwHddx7c1?DZlAf#p~$_72yi#G}bw0tnLn@i|O62 zl2b;0jkCJV-=*^=xm=}qN9Wp>Zkq$f9&`NS&8||twC1-W+o-{e-1+Pkdio`ytcF1* znAw}lgDgB~#bGwAU=?*)cY4WNHJcED;y2LrSj&L%VXewA@~CvJagW`<6hp1)Vu=UUIzlCJx^={9}EmKuR z2FV_LmBLo#UFFcyxslk&+LGV_?6KUL^)U@ZyBK^>JXCET%E1UN=PijHZl%Q)12wL2 z?wgi3(So_~p@2;@^lSnAQ=+rIxS0}bs4I1}as&+KD>G5XPuG4aZ3uy>)9Wf$+-Ho8 z86FJ26tV?7`EFH6Mk`P|j;G{n{_q1>aK=tM@|OS6VW-7U6$3JQEUDyiuh6k)KPH!I z<@et0&8$kCvC8oD$k{60sa)>clnueb-kYIhf`p50I)y7mMzmQCjd7NB13d3KT(ra+ zo8f{ha>M(_jaryja!3XVa^SsI?PYdm~TA$4+NF${=sHc1+?>o#bzmw5J7sv2W zJ?ztbC6(CQOa-Mo9@+bxr|=pC5r6+lw4;;u%>0-wqE%&Z9(9g6wExFD_tN#PiuCT6 z1u^n6o0`+^>>P{=Cvl!5R8rfQ8jPv~i?xpSFQ+^DB;M{;`M$I-M<`bShH&sf^DNbe zpN^vP#s;hv1ez+KeRz=8@|Us<2PPxp4fGikeKMFYd02Z|O7!*_f8zGAu!&GUA%9IB zZ_WKoH}Xpst6Q{}3}!Hwo!6{JHl(Yds0}%HjR|L<1nG(YnVAZ#Hio9rj8>jxp}-95 zUI&-Z?2uv;(5|SA)-syYL<*Ug`oDla)KL<+Sq}f;=f$N|6Dtv=6Dj%FKqtc)^CL6+ z;{(qSS9ShD;6&$B$BAqVAOWesMV5pO4D4?3VeFKbZTB!kltk0VygAFkP20DxhP$kw zm3x6^q+PAXMf%no5A%l4W#oS0b>e=dRgPwvlGila$60*l`JaxqqXnTptY0fVU&3^aFJ+}5E|pa5d_W5c zwV#>E`!r%f_rFQq zn$dEiC7E2d6)%KL>wFF0Zbrk+;{-f%t(e0uvP^qIk7CsGuZ{DklE;5AOJJ^w2g*g> zV9shV+Xsx*1*GD8g_D)&;-J|%m#CL!%`bX!&YEcJx9#&>)ujya2e{(;P@mt`=F~>> zoF^Oio>ZZ^baG{UU}MmDdN8k`Kc4AKS=o=SuJ&Gduk{)S18#oxJX&5eyJx!mb`?W) zMKN5Tz8IV4pN^G&BDivvJ68G5x&Gq9zVmI6lj;vXgiZ6@V%dSaIi*>u&-EzKjp*plu@NFdI}BK}HQc297+FM?#w^F4FPGDh#U7sGZ__UOK!n z?K$tQrp~{#vQu5~ex0R3u_!XUN)#g<4r~BwVlbMEf@j&gxiO?NweftF?zfNAg|?gB zeAoCadwr<^<|tkp!sTzIY8!F!n9Zv#8el)5=UC^?Y20FyQ5AZ*btXk%lS3&+y(EGk zAvibZAp9)mYNbT~<=f^eR!ECr_t~)dGaJz%`L?Ld9hvHhbvONN>CUtj;EbOZ_;Tmq zL>l`Rd1RBq*>Y@hVy|In;KJnxJ#ghDZ9mtXlv_RvAKx;njy5Zv0y3)grQ$oOtlNo| zh=uv<)m;k5kyA~V%dm%6AIeU4ER(&YhR?aC=o*xGo{L`{w0(<`Mb*oVZ7N^87iMmf zVLZcpI>oSD! zV)!N9?ky(U-03KVC~JmPhvlRm2m0GKsTis^MRgu@PEVtB;|(_4FXDs~IUZUpJh$Jm zZy1$pWu&h9T)Lxx%0@-LnO)NETk=YikRSD_NlEXsOUHbf94wIeGG&(7>kwCXY;Ckz zC=U^v>;iJ-b zVsaMl7Ie$F!lUQ>!v{ud_Y|$QV6~aCIb3JooJ_64%@7 zrK2*I$4{l6Q?Wvbe%i6p3ZUlVQMA?3r7r7@-vBl_C9w^P@M-zd+v4n;;&;dvq;p1K z9L!UxZ0!hnl}x^P>zuwDHA363NKW(~Y~hR(3${A0Pd0&=XI(FdtYY<2?^HNp=yeeX z9r?^y*L~+lkzJ|iv=RA6pHqWS?M=a`CsHPojUSu+Dn603cg_{-0h>1`J-yJ{^IF>@ zG3C&e(jl~&v)a1q;ht*KuTm^#LF}~Hki)@>h>il+bDl=+JN=f~CkqZHGfEd^_4f4? zOJkd|4250?44Wzz@jY2$c--7KIk->w1WswBHP9&k-Ri7uq5^_2Wn=JV_cDsPv@Tz!|oX3J3LiDV+ z-&%Nb8f2#xSQuTLO0%#QB#%JkAZ3PMN%|Z|=eY#D?qITflXL~O)A4TeHr8Z2@r(Oa zP88~>W{E1332H@)-s?+yq`Dlct+acqLK@RqF&-PO`CRjRfwlK+UYe`bT(msnWt?Ju z)8<*l_bG^a{ZjYpg)r^mpp^=^Sl;s^Np7gpgxtirYbIRZtgff%Upip$QGfqi(JgkM zE|IsdMwgEWZd$u*wo;C#`|g#5;n{s!`_Z#Yy;{)KB(!6;z4Of{7OC1NrJ|45iMbmx zS@JLY(@m>)j;|&T`YtW{z;v&;ukXlhRhE<1$HwUB;yD?FWkS?zu4@+KvKbBmV|U!m6ydbs|Td0 z+6Tt%LLJ3#*5?+oh0#8YM;-2osekZst;UBLn=5N}AK~gvX2@)nc;RiwEpLk3*Wngb zn^ulOxlLF66SQ*FXf(*5Sof@~(95?bUYi!$TB)is=;}S>v!pc# zVPoTaP(o&P<*z1v1Uo9VpJ9-Jb<{bNZB4mM19R;=7|nV{W%WC)2uB*DW?DVUPb~GR zJqxzO{-w2wq`kO{)ROBwj50DYDSVoKD(E=l1e$fXIO(zIfdO6tRy$L5=~LqB+;PrR z#d;T_(bAW+I`^f&CE1dz;xvDwmfW*UbUCeRC)rnvxDbA70Xtyp zJA@ed{#Tuc)pJ#ojGPXFzr>zjR((!$pxcrh0>Kk4gbs4Y$=VHS?Jfj|S~?+w?eEx< zK#u(OA-)0rOZe;Ox1U3hBO0pest^(q5{Me`2l8_ma$W@qwShpiv>>N}FHu2A0-+Fm z3le~s0fInCpOXH1=k!yuU$3R{AO4($oVjX;a6vfRA?}=z5Eg};xu~v1{`cSf?KLm{ zdypd?Y+*f-kT>L$_o$!D;4b?7d=H_ef=EM7laX*iNNGvPXi0w7LpXq6rU3ZEv-tOm zgp`b&Vjm?H^?n-Q3#cOyQW7#UQgSj13jEKIcmtn9$Z08#a*AEpcTC5elFN}!{C?Ck zD(;JgHT2io7I-8qoE}i`XJ9Rs12xM65y zX=QC=YX`M=c5!ucM|#}#d*~k!7!({59rHLgF8)bE;`8(u8JSrxvtPX_Dn^x*mc1>n zt*dWnZ2Hjru^rvf+13562Qxe}`h9GC;>Y9^c5!KWWpxd=zJZsE1VZ*Vv3^OmM=n}G zE>d!GGIC11TqLCK0Flv>Q*esyJ9 z=EdSg`%SWcO|S?5N0R*#?030(AxaR^-!3vzpqI$VfSw`;E(%Ht{6$Gc`P)VH_iO)e z7Y+V8`0M%!fRF$fK;wPD--FbY)W1IamtXws2h5V}CkAqWj07+yGFpftWE&edVmCKC z+m2D^exhdTdip5Wy<4I@VuLZ^PnRcHua|$X)ES18)$i+?H<5TXIn%D%X3}CGawD5} z>n*MET$sa`vrR_B@STG=F4*zBp=#`bRcwBPz=)9gWB(uGr8h>i+V7o94O#5KX$|w3 zRN0ix9Dnm+W8itauw$%&4DW-K^wWnFB~pv(e3;Q*0x+q}C*AEYmY9+U2DH64L;P#s z)kllJ+%Nic$hA@Z>7m3ByW7dPB41`*r34Cb{OB4kD{Id;M_u6g@{sFM81=@P)4sGJ z>BD6Ox8B$xZnuAqt@gXMbUZTQLl_0qPsj-a6%~l(G-G1k3&)aJD-pv`2i+5qc4QIS z1sXQ-FQ;T|TRJ3ratHawMOd2dqhp==enKjYUG$TuTYQT(^ac(^#a^ow6quNnr}myh~SeH6_eANB97 zLiue6L1rPRx=z_WHTL4EQ)J&;9|E;hwhTtig5zb`s~%x4!fjQGBhD(Q3-u*i74FAb zusyjo3%Ql*Q}hbkgHaLCrlWmPkn-gv8Cw${&w=DrtsDPR-S)$H*N~~v!0paUZoR#Mi9g6Z&$TAR`21GvbJP!qYTe-kjC}wTsYk`#b|jA#|%58$KCozOlspV z(>o5q+DhN;=Z6BAsz?}Q~ z;bQ;AQ&*YPAQo9|3hX$VIv>WE8g}-DftXCBn_k>m$t2C==7lb4!DPnIsh+4EZjF_z z7*CouU%9+Bx==9NIcj#uXbMQ+OZYfzVT{VF;|XH)jb9R-Mz!KjnV=ptyQgmfrAp(bFDE#R8j2)oyotP8si5qr zCCGas@x=Z2`cY3LxVY8LuA1(&_!h0KjQczC-CI62D=)YGw9ClK$h-0`H0Ih7>an=5 zm%cX(3#DUbGU6#I6PMX6hYjjDj!Z5>W!E0M2x&CJ#yh^3RG{-F{O6xgz~U~2WhXp_ zi_?}xP&Y7B;d1JKLKd#J?gvWbFh|4!r-}G)_a{pip~Blu8pEZQY0S&JhQvLjGt91r z^PKcxXUnw?-`D?*S#h?1M2qp-yY?MUqz0Yh!V~*)*7!L0HdI6u9O`UsyI)H-H&hZR zJw+>+W)oaHbAXpiVoj^5ruw15-IN`a>rmRE&oAwxG$~d(5>0ZnUFm*sMe#bbPZ)BO znA~{u5ptIFRqxgzoQPebms=I-!Y6?jpSq=K*rV*8ciEmYQac~|-A(M7U>VP=)Tibo z3+@knhn^0cC|ckP=x!PyEi1=HRA<^TmV4c`{s23tCH2IW+G|UNt-kBNYJvhMzrEXT?D$Z);e4OH^FqOJ zs6BRic9@N7%JGJ;braI17jaHdzKF3WPFv(o;74Bh*KRYsjuEHs_TA-R^)lIhS|#;u z5}2tPTA)vsE-$FhQ@r}FW9T)Sv0hghE_kb42SyiZ_)oOeGeoIM{>VHZ&70rJez6>q%Z=F|#x8JjVpzL&v)@3k8zIm6OgkGE zCCHreJrQ2iXIh_egSS3Fy#3{=z(Z;u3)WOwQ1vC38Wp&<%eIV%-|1d&bJ#g{^W8wW zbN1w#ebtE~Ogu&*oZ+4O5e37K8DW92uz<%v4qLuheWZHmS@h&8J6GuNykGn3c#}$1 zr%Uhj^bnkFxxO%ZPA)c>G)Fo9y@z9;{QXD43_>5Zf2iOq#F7m3-830MI;*F8zO_vq zF%*2}9tX>Dw3Ux&ptgq-*QEHWyRiI}b@<(p)B_97C$MfiNRK+R5oD=(5`Oh4H z^mmiycN(*>2#J3j)IvXv=xT50c|gT^fmKI^*vS-!*#(Q57ap~H9Vp$?`}VxySX4P^W8_11f^mwUw+`C1aF@m zuOq8%H8cr1!-Q_hgc5NBDd$H4hOm=W@LO*%XfV{ zAI(H+A!Wg-Z+rXHI#TKJIfZ(`4#m{MM(-JSU|9ca^UFRVZ z3Zzb)nfU^JRdr^M`ZN2xQu&ctlZ7>hl1qvbVxN=viG0#L_(Z4mX4l~W1rZ}$no((+ zZfzAm`e1XcN>@e(3iU?v#8I}E=(m((JmwMS&ypX$nfVPUkMs}EK{>p8a(aOTmTb$6 z`BU0LsLJqC#%)f8LEh%F0lHfwlKV+4E|4eRVqLmF89Qb)Q7c4g3Y5n+g=-oX$LRH} zKA9;<960$c#E(Sv0_Lgh*=^B-^l;zdyQb=b?trrohc2iig1(o^Nc5?ky}llFhugZp zVr;qTlSh^cN0V9U`S#DlzHcNy6upd?`4Bh!Wlgti-{VZtL!FfQcSC?<3Q4!vUaG}t zy62>4R5E;Q8~pIZ*mZyS{YIde4iiuEN?yUiEur>Gv23HMlJdq1cd1tz{s2bB*F$=%BNBj7LQxjC^uHo+s$bzuxxb>s;xI+TeJV%R6!Y?FPiczdz*YK(dW&Q5P zzVhBwW|j`CPM?T0KQ1e-(dZSsq+l(uL_w+$IL@=i^kLcTI8s*exRNbhVt!VJcZ8)V zTzu$!yS2t_%;}o=(zKkh(%fI1QhC!2S}_^pJAp zrxz=QJ+P!X4oO~09?#C2nSb7Uv&AC|h{CJRS3X#anyH4=$aqyKbDm#s1#X7~LMBsg z(&ZP>163e2fudr(7Y+KiC%!&52*Pa9mK2vHViXy1&;0ASKYaFi7_Vaeaa>T?J^B7U zWUIz<ff;ul}<3(-eGn>JNFB(VE0SP9pD6}fuPYh?0?O^2UyDDuI0HH^_pS8PY;)tCbNeXl+mHNjPk*m> zb@5b0uUuHN4(D<}_A*&i-W_X|vbeYZ)bo3a|F#(dGYcf73cwr!{=(0Irae?XxFHCE z;OXdZ@BZ;0bq6bJq=+)Y(iLv);35olH{aXd|3-}$n_)j||X8dSQ6x58!=f#!JP`5gv$ zby{-|Q)<@cR@P3sE(j-cTkDIimN08jBM{VH{bfspyyfgg+_fbkNl7p%J68v*&H|j^ zi4f^0QKU1{U`WL@>IS>2Cq#0(yhqAkJe>j6*R$%b2`7LbJP{%_5=D|c3&s;lcv%)) zIwvh+Jc)~eA^os9#q01JZPiLeV3_9B6GA*cu3e~w*lmpek83F;B!PE1S! z%vkxq-p*nG9!KJdun+I=h5D@zLCv&)hl_ugA3|+?x=xIrGoZ#vqFNiei$o~d34LNn zViKUku=m?LiflkCJP}Ifx)a0*UVl*s4mD34N($5#q8r~R0a*_OPlRcxvN18PKo#ZLJL$g* zL^xhP5CsyG0<{G9oMUQ0z6rq-p`*HTa}Q5ojtbPfOgy-9ZdYZ5{n)n`^Y>H@RAWI) zmA7}12n7{2*~8s0Br!2ioyps7+!6nb{ced388koNbB%4QE!cpC-F z`V`0~hIU6Wpz*l0F=P65~ls92817 zAExiLzVvnC{R`DwQw!%DxGjJAGRkdpeSgpzL7hcw#yZv*8PY> zfg))obzj~MhJ?eWdoL2$umMjhk87U(zRMn=q*q`>B^3vCTkKbcM!})di9?BkcBR;K z+!;H-Oz}jhG#pVVDbOhKv*RI=Ihw@V#N`9^3;Yx=`@rR!{|8W@c};MvpDK7)D#Q11 z1=^LM&L%kNxF4{-6TilDPe82L3;J6?1RakrePu2y0$Rrtp^+U%{41P+Mtvx4a4fjy zV)lam@?l~Upimg;lSFQUeh`O}1ntkmvgf~oPv)Mxvq#ilT!E(|VOz?HyWL5crY7%2 z0_{#Pzki=6ERPiENjwpzH%A@!aQ9npf{vqmaWvcDidT2q1M*8mF$qxX!cLb@%K}D$ zCqfxh_d8)=khr;jEn|= zmhePq5pVV)fmsBopyT&oQM=p`h9fOE;(~(4@K&jY^j#=IL7x+c0u5}6p6d1B*}y7s zBneO``JW$Cc9|lS&)%J=d{UsEu;uONgED~X@kFTp>b+24>IXHBlnk{}KL8I;gzU*8 ziLxgO%3fZf@+)vjam1k{K!+rzU3&g7;0EzT*ppfw#JB=iKMTYPa~F^ePlQNuz*_`& z9>4sdIH+}HFNJXJibsf~;Ykb$d@|>l=&If>5~0phi6V(ff+jn98N+ViP)o$2q(BWd zo_~vK7m83mH7}y_fd&p93Jn!mK;L*G%qWugB7xbd7^wQaCCd?)06;tuvd7|0j6Lv# z!t+*f;jW;B>Q5$$Bqj+OgZv&)w}V4r{{a-JAFNkDLgYERst+;w#3Vsg^`q!){cc7_ z=qHl)LV@WYv`=5jHqnDi%I-^)J@5n_U3vE9DPY|Ko*04N{QYv?3-w!`1M0WF$Xp29 zm66cKzTV%%515SL4+oP-UQ&PysrO(H=r3m>CIzamVHVSi;85BB01DK|nj%kL1~Od; zo(L^}hbR>I5a$<`m)gx*36+)w_RVq-}@4H#r|*)=x^N# zuKKK?8>G7tmr%$@fqPJXsUCd#{z1t$61yJ)!4n}888H3yHz9Xd=;*q504r_mtijh; zeE(|BTL@%@cw!=uOgLs2Nzcw2ZvBs8RL#P57=Y$@;v|4!U?TZDLl+zz5WrF$V5Q9k zR~I|P?%EHq+XUa#g{h!pz+4(YM+x9yzu>g2UCgb31tC03CWV-fjtCI)#c{~xO-yOn#fZ5fwx)rb>3TgwjcG?Rx z%&o=E3%CM2aS_O)BJu~Ii>}byR{GXX&VY{80Dcfo9^i~&kmvmpb082r(GcKOiIME? zSjF!H+sg>y=GH&9jP3u`@b|5*dz%yPI{RaDxsl(S|9ubIRZWV0_^. + += Address space sizes = + +All of our ARMv8 CPUs are in SoCs with 36-bit physical addresses. +Because we always map so that a virtual address corresponds to its +physical address, we set the virtual address size to 36 bits in TCR +to match the physical address. As a result, one less level of walk +is required than if we used the full 48-bit virtual addresses +supported by the architecture + +Address translation source bits at L0..L3 depend on selection of +4KB/16KB/64KB granule. + += Translation table sizes = + +Because translation tables cannot be modified after enabling the MMU, +they need to live in their own pages. Therefore, regardless of how +many entries in a tables are used, each table must be aligned to and +have the size of a mapping granule. + +L0 Translation table. +Not used + +L1 Translation table. +Granule bits entries size in bytes entry type + 4KB [35:30] 128 4096 1GB L2 or block + 16KB N/A 0 0 64GB L2 + 64KB N/A 0 0 4TB L2 + +L2 Translation table. +Granule bits entries size in bytes entry type + 4KB [29:21] 512 4096 2MB L3 or block + 16KB [35:25] 2048 16384 32MB L3 or block + 64KB [35:29] 2048 65536 512MB L3 or block + +L3 Translation table +Granule bits entries size in bytes entry type + 4KB [20:12] 512 4096 4KB block + 16KB [24:14] 2048 16384 16KB block + 64KB [28:16] 8192 65536 64KB block + diff --git a/docs/source_layout.txt b/docs/source_layout.txt new file mode 100644 index 0000000..48587d9 --- /dev/null +++ b/docs/source_layout.txt @@ -0,0 +1,159 @@ +/apps + Top-level applications, typically corresponds to a deliverable. + +/apps/SecureROM + SecureROM for Darwin SoCs. + +/apps/iBoot + Multi-platform Darwin bootloader. + +/apps/EmbeddedIOP + Runtime for embedded IO processors. + +/arch + Platform architecture-specific code. + +/arch/arm + ARM-specific code. + +/docs + Optimisim. + +/drivers + Portable drivers and driver infrastructure. + +/drivers/apple + Drivers for Apple devices. + +/drivers/flash_nand + The AND flash translation layer. + +/drivers/flash_nor + NOR flash support. + +/drivers/power + PMU drivers. + +/drivers/primecell + Drivers for ARM Primecell devices. + +/drivers/samsung + Drivers for Samsung devices. + +/drivers/usb + Device-independent USB infrastructure. + +/include + Common header files. + +/include/drivers + Headers describing interfaces to drivers and common properties of drivers. + +/include/lib +/include/lib/net +/include/lib/usb + Library interface defintions. + +/include/platform + Generic interfaces to platform-specific functions. + +/include/posix +/include/posix/sys + Interfaces to the Posix subset libarary. + +/include/sys + Interfaces to OS services. + +/lib + Support library. + +/lib/blockdev + Block device support. + +/lib/cbuf + Inter-thread pipe. + +/lib/cksum + Various checksum routines. + +/lib/devicetree + I/O Kit device tree support. + +/lib/env + NVRAM environment support. + +/lib/fs + Filesystems. + +/lib/fs/hfs + HFS+ + +/lib/heap + Malloc and friends. + +/lib/image + Support for the Image2 and Image3 pseudo-filesystems. + +/lib/pki + cert chain validation and signature checking. + +/lib/libc + Posix libc subset. + +/lib/lzss + LZSS decompressor. + +/lib/macho + Support for the Mach-O executable format. + +/lib/net + Ethernet/IP networking. + +/lib/nvram + CHRP NVRAM support. + +/lib/paint + Simple graphics primitives. + +/lib/partition + MBR partition scheme support. + +/lib/syscfg + Support for the diagnostics/manufacturing system configuration area. + +/lib/tftp + TFTP client. + +/lib/usb + USB client code. + +/makefiles + Deliverable makefiles and infrastructure. + +/platform + SoC-specific code. One directory per SoC, containing drivers unique to + the SoC, startup code, etc. + +/platform/s5l8720x + Samsung S5L8720X ("M2") + +/platform/s5l8920x + Apple S5L8920X ("H2P") + +/platform/s5l8930x + Apple S5L8930X ("H3P") + +/platform/s5l8940x + Apple S5L8940x ("H4P") + +/sys + Core OS services. + +/target + Target-specific code. + +/target/s5l8720xfpga + FPGA board for the S5L8720X + +/target/s5l8920xfpga + FPGA board for the S5L8920X diff --git a/docs/uncrustify.cfg b/docs/uncrustify.cfg new file mode 100644 index 0000000..46468c3 --- /dev/null +++ b/docs/uncrustify.cfg @@ -0,0 +1,168 @@ +indent_align_string=true +indent_braces=false +indent_braces_no_func=false +indent_brace_parent=false +indent_namespace=false +indent_extern=false +indent_class=false +indent_class_colon=false +indent_else_if=false +indent_func_call_param=false +indent_func_def_param=false +indent_func_proto_param=false +indent_func_class_param=false +indent_func_ctor_var_param=false +indent_template_param=false +indent_func_param_double=false +indent_relative_single_line_comments=false +indent_col1_comment=false +indent_access_spec_body=false +indent_paren_nl=false +indent_comma_paren=false +indent_bool_paren=false +indent_square_nl=false +indent_preserve_sql=false +sp_balance_nested_parens=false +align_keep_tabs=false +align_with_tabs=false +align_on_tabstop=false +align_number_left=false +align_func_params=false +align_same_func_call_params=false +align_var_def_colon=false +align_var_def_inline=false +align_right_cmt_mix=false +align_mix_var_proto=false +align_single_line_func=true +align_single_line_brace=false +align_nl_cont=true +align_left_shift=true +nl_collapse_empty_body=false +nl_assign_leave_one_liners=true +nl_class_leave_one_liners=true +nl_enum_leave_one_liners=true +nl_getset_leave_one_liners=true +nl_func_leave_one_liners=true +nl_if_leave_one_liners=false +nl_multi_line_cond=false +nl_multi_line_define=false +nl_before_case=false +nl_after_case=false +nl_after_return=true +nl_after_semicolon=true +nl_after_brace_open=true +nl_after_brace_open_cmt=false +nl_after_vbrace_open=true +nl_define_macro=false +nl_squeeze_ifdef=false +nl_ds_struct_enum_cmt=false +nl_ds_struct_enum_close_brace=false +nl_create_if_one_liner=false +nl_create_for_one_liner=false +nl_create_while_one_liner=false +ls_for_split_full=true +ls_func_split_full=true +nl_after_multiline_comment=false +eat_blanks_after_open_brace=true +eat_blanks_before_close_brace=true +mod_pawn_semicolon=true +mod_full_paren_if_bool=true +mod_remove_extra_semicolon=true +mod_sort_import=false +mod_sort_using=false +mod_sort_include=false +mod_move_case_break=false +cmt_indent_multi=false +cmt_c_group=false +cmt_c_nl_start=false +cmt_c_nl_end=false +cmt_cpp_group=false +cmt_cpp_nl_start=false +cmt_cpp_nl_end=false +cmt_cpp_to_c=false +cmt_star_cont=true +cmt_multi_check_last=true +pp_indent_at_level=false +pp_region_indent_code=false +pp_if_indent_code=false +pp_define_at_level=false +input_tab_size=8 +indent_columns=8 +code_width=120 +nl_after_func_body=2 +nl_before_block_comment=1 +nl_before_c_comment=1 +nl_before_cpp_comment=1 +cmt_width=120 +cmt_sp_before_star_cont=1 +cmt_sp_after_star_cont=1 +newlines=auto +indent_with_tabs=0 +sp_arith=add +sp_assign=add +sp_enum_assign=add +sp_bool=add +sp_compare=add +sp_inside_paren=remove +sp_paren_paren=remove +sp_paren_brace=add +sp_before_ptr_star=add +sp_between_ptr_star=remove +sp_after_ptr_star=remove +sp_before_byref=add +sp_before_sparen=add +sp_inside_sparen=remove +sp_after_sparen=add +sp_sparen_brace=add +sp_before_semi=remove +sp_before_square=remove +sp_before_squares=remove +sp_inside_square=remove +sp_after_comma=add +sp_before_comma=remove +sp_sizeof_paren=remove +sp_func_proto_paren=remove +sp_func_def_paren=remove +sp_inside_fparen=remove +sp_func_call_paren=remove +sp_return_paren=remove +sp_attribute_paren=remove +sp_defined_paren=remove +sp_else_brace=add +sp_brace_else=add +sp_brace_typedef=add +sp_cond_colon=add +sp_cond_question=add +sp_case_label=add +nl_end_of_file=force +nl_fcall_brace=remove +nl_enum_brace=force +nl_struct_brace=force +nl_union_brace=force +nl_if_brace=remove +nl_brace_else=remove +nl_elseif_brace=remove +nl_else_brace=remove +nl_else_if=remove +nl_while_brace=remove +nl_do_brace=remove +nl_brace_while=remove +nl_switch_brace=remove +nl_func_type_name=force +nl_func_proto_type_name=remove +nl_func_paren=remove +nl_func_decl_start=remove +nl_func_decl_end=remove +nl_fdef_brace=add +nl_return_expr=remove +pos_arith=trail +pos_assign=trail +pos_bool=trail +pos_comma=trail +mod_full_brace_do=add +mod_full_brace_for=add +mod_full_brace_function=add +mod_full_brace_if=add +mod_full_brace_while=add +mod_paren_on_return=add +pp_space=add diff --git a/docs/unittests.txt b/docs/unittests.txt new file mode 100644 index 0000000..a7baa96 --- /dev/null +++ b/docs/unittests.txt @@ -0,0 +1,110 @@ +iBoot has a system for building and running unit tests. Currently the system only allows +for tests to be run on an x86 host using the native libc, but it's intended that the +system will allow tests to run on x86 with iBoot's libc, and built for arm and run on +targets (either hosted or freestanding). + +Overview +======== + +To add tests to a module, do the following: +1. Create a test driver .c file (details below). +2. Create a test makefile in the module's directory, normally called tests.mk. If the module + requires multiple test binaries (usually because of different compilation options), add + a makefile per binary, usually called tests-.mk. Details on makefiles are below +3. Add the makefile to the TEST_MAKEFILES list in makefiles/tests.mk + +Writing tests +============= +The only requirement for test binaries is that their main function returns 0 on success +and nonzero on failure. By default, tests should only print to stdio on failure. iBoot +includes a unit testing framework, but its use is optional is a different testing strategy +is needed (or for legacy tests that don't use the framework). Most unit tests should use +the testing framework, however. + +Using the testing framework +=========================== + +To use the testing framework, add tests/unittest-main.o to the test's object file list +(normally TEST_SUPPORT_OBJS, not TEST_OBJS) and include in your main test +file. unittest-main includes a main() function to run test cases, so only the test cases +themselves need to be defined when using the testing framework. + +The unit testing frameworks works with test suites and test cases. A test suite includes +an optional setup function, a list of test cases, and an optional cleanup function. +The setup and cleanup function are respectively run before and after each test case. +Each test cases is simply a function that takes a uintptr_t parameter. + +Use struct test_suite to define a test suite, and then use the TEST_SUITE macro to make +the test suite visble to the main() function. For example: + +struct test_suite my_test_suite = { + .name = "mymodule", + .setup_function = my_setup_function // optional + .cleanup_function = my_cleanup_function // optional + .test_cases = { + { "test1", run_test1, 0 }, + { "test2,0", run_test2, 0 }, // passes 0 in parameter + { "test2,100", run_test2, 100 }, // passes 100 in parameter + TEST_CASE_LAST + } +}; + +Test cases are defined by their name, their function, and their argument (a uintptr_t). +Test case functions take a single uintptr_t parameter and return void. + +A test succeeds if no assertions fail, no unexpected panics occur, expected panics +(if any) do occur, and TEST_FAIL is not called. Tests are immediately aborted on +assertion failures, panics (expected or unexpected), and calls to TEST_FAIL. + +Assertions can be embedded inside the code under test using the typical iBoot ASSERT +and RELEASE_ASSERT macros. These assertions end up in shipping code, of course. For +assertions in the test code, the unittest framework provides a number of convenience +macros, including: + +For integeger types: TEST_ASSERT_{EQ,NEQ,GT,LT,GTE,LTE} +For C strings: TEST_ASSERT_STR_EQ, TEST_ASSERT_STR_NEQ +For binary data: TEST_ASSERT_MEM_EQ, TEST_ASSERT_MEM_NEQ +For pointers: TEST_ASSERT_PTR_EQ, TEST_ASSERT_PTR_NEQ, TEST_ASSERT_NULL, TEST_ASSERT_NOT_NULL + +These macros (with the exception of the MEM macros) support printing the expression and +value for the left hand and right hand side of the comparison on failure. + +A general-purpose TEST_FAIL macro is also provided for things not covered by the assertion +macros above. + +Writing test makefiles +====================== +Test makefiles define the following variables: + +TEST_NAME + The name of the test binary, must be unique + +TEST_OBJS + The object files being tested + +TEST_SUPPORT_OBJS (optional): + Object files used to run the tests. These are listed separately so that + their source files are not included in test coverage reporting + +TEST_CFLAGS (optional): + CFLAGS to be used while building the test binary + +TEST_LDFLAGS (optional): + LDFLAGS to be used when building the test binary + +Test coverage +============= +The unit tests are automatically built with gcov support. This can be suppressed by passing +COVERAGE=NO on the make commandline. +make COVERAGE=NO tests + +The best way to parse the coverage info generated by the tests is with the gcovr tool +(find it online until it gets included in iBoot source). Run the tool as follows: +mkdir -p build/coverage && ./gcovr -b -r . --html -o build/coverage/index.html --html-details + +This will only give coverage statistics for the source files as built for unit testing, which +may be different from how they're built for real targets. To see how well the tests are +covering real world scenarios, it's possible to generate coverage info for real targets. This +will just emit info on which source lines emitted executable code; no profiling will actually +be performed on the targets. To generate this info, add COVERAGE=YES to the make commandline: +make COVERAGE=YES build diff --git a/docs/upgrade_mode.txt b/docs/upgrade_mode.txt new file mode 100644 index 0000000..54b97b8 --- /dev/null +++ b/docs/upgrade_mode.txt @@ -0,0 +1,67 @@ +iBoot Upgrade Mode +================== + +The iBoot application normally insists on booting from the first +partition on the storage device, using a kernelcache located in +/System/Library/Caches/com.apple.kernelcaches/kernelcache, with a +devicetree located in ROM and with the first partition as the root +device. + +Upgrade mode provides an alternative boot path suitable for booting a +standalone restore/recovery system. It chains to a new bootloader, +and the new bootloader then loads kernelcache, devicetree, ramdisk and +optionally a display image before booting the kernelcache. + +To invoke upgrade mode, the boot-command variable must be set to +'upgrade', and the upgrade partition must contain the following files: + + /iBEC + /kernelcache + /devicetree + /ramdisk + /apticket.der + +being the appropriate iBoot iBEC component, kernelcache, device tree, +ramdisk and personalised AP ticket for the system. In addition if the +file /logo is present, it will be displayed by the iBEC before the other +components are loaded. + +When the kernelcache is booted, the RELEASE-configured iBEC will force +the boot-args variable to: + + 'rd=md0 nand-enable-reformat=1 -progress' + +Non-RELEASE configurations will add 'rd=md0' to boot-args but +otherwise preserve its contents. In neither case is the value saved +to NVRAM. + +All of the files listed above are expected to be in their usual +(image3) format, and must be signed and/or personalised as normal. + +Both iBoot and the upgrade iBEC will identify the upgrade partition by +its LwVM partition name, which must be 'Update'. + +If any of the following occurs, the unit will end up in the ROM +iBoot in recovery mode: + + - the upgrade partition does not exist or cannot be mounted + - the file /iBEC does not exist in the upgrade partition + - the contents of the iBEC file are not an Image3 file or fail + authentication + +If any of the following occurs, the unit will end up in the upgrade +iBEC in recovery mode: + + - the upgrade partition cannot be mounted (e.g. due to NAND + format incompatibility) + - the files /kernelcache, /devicetree and /ramdisk do not exist + in the upgrade partition + - the contents of any of these files are not valid Image3, or + fail authentication + - the kernelcache file does not contain a compressed mach-o + kernelcache + - the devicetree file does not contain a valid devicetree + +The iBEC component will set the auto-boot variable to false when +loaded in upgrade mode, to avoid the risk of locking the unit up due +to a hang while booting the upgrade kernel. diff --git a/drivers/aes/aes.c b/drivers/aes/aes.c new file mode 100644 index 0000000..0a4cbc5 --- /dev/null +++ b/drivers/aes/aes.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if WITH_CORECRYPTO + +#include +#include + +static const struct ccmode_cbc *aes_get_ccaes_cbc_decrypt_mode() +{ +#if WITH_VFP + return ((const struct ccmode_cbc *)ccaes_cbc_decrypt_mode()); +#else + return (&ccaes_gladman_cbc_decrypt_mode); +#endif +} + +static const struct ccmode_cbc *aes_get_ccaes_cbc_encrypt_mode() +{ +#if WITH_VFP + return ((const struct ccmode_cbc *)ccaes_cbc_encrypt_mode()); +#else + return (&ccaes_gladman_cbc_encrypt_mode); +#endif +} + +static const struct ccmode_ecb *aes_get_ccaes_ecb_decrypt_mode() +{ +#if WITH_VFP + return ((const struct ccmode_ecb *)ccaes_ecb_decrypt_mode()); +#else + return (&ccaes_ltc_ecb_decrypt_mode); +#endif +} + +static const struct ccmode_ecb *aes_get_ccaes_ecb_encrypt_mode() +{ +#if WITH_VFP + return ((const struct ccmode_ecb *)ccaes_ecb_encrypt_mode()); +#else + return (&ccaes_ltc_ecb_encrypt_mode); +#endif +} + +#endif // WITH_CORECRYPTO + +int +aes_crypto_cmd(u_int32_t cmd, void *src, void *dst, size_t len, u_int32_t opts, const void *key, void *iv) +{ + /* argument sanity */ + if (0 != (len % AES_BLOCK_SIZE)) + goto fail; + if ((AES_KEY_TYPE_USER == (opts & AES_KEY_TYPE_MASK)) && (NULL == key)) + goto fail; + switch (cmd & AES_CMD_DIR_MASK) { + case AES_CMD_ENC : break; + case AES_CMD_DEC : break; + default : goto fail; + } + +#if WITH_CORECRYPTO + u_int32_t key_size; + + // Ops with explicit user key will be handled by libcorecrypto (SW AES) + if (AES_KEY_TYPE_USER == (opts & AES_KEY_TYPE_MASK)) { + switch (opts & AES_KEY_SIZE_MASK) { + case AES_KEY_SIZE_128: + key_size = CCAES_KEY_SIZE_128; + break; + + case AES_KEY_SIZE_192: + key_size = CCAES_KEY_SIZE_192; + break; + + case AES_KEY_SIZE_256: + key_size = CCAES_KEY_SIZE_256; + break; + + default: + panic("invalid AES key size"); + break; + } + + if (likely((cmd & AES_CMD_MODE_MASK) == AES_CMD_CBC)) { + const struct ccmode_cbc *mode; + + if (likely((cmd & AES_CMD_DIR_MASK) == AES_CMD_DEC)) + mode = aes_get_ccaes_cbc_decrypt_mode(); + else + mode = aes_get_ccaes_cbc_encrypt_mode(); + + cccbc_one_shot(mode, key_size, key, iv, (len / AES_BLOCK_SIZE), src, dst); + } + else { + const struct ccmode_ecb *mode; + + if (likely((cmd & AES_CMD_DIR_MASK) == AES_CMD_DEC)) + mode = aes_get_ccaes_ecb_decrypt_mode(); + else + mode = aes_get_ccaes_ecb_encrypt_mode(); + + ccecb_one_shot(mode, key_size, key, len, src, dst); + } + + return 0; + } +#endif + +#if WITH_HW_OLD_AES + u_int32_t keyType = 0; + + /* Only supports UID0, GID0 and USER keys */ + switch (opts & AES_KEY_TYPE_MASK) { + case AES_KEY_TYPE_USER : keyType = AES_KEY_TYPE_REGISTER; break; + case AES_KEY_TYPE_UID0 : keyType = AES_KEY_TYPE_CHIP; break; + case AES_KEY_TYPE_GID0 : keyType = AES_KEY_TYPE_GLOBAL; break; + default: goto fail; + } + + /* Only 128 bit keys are supported */ + if ((opts & AES_KEY_SIZE_MASK) != AES_KEY_SIZE_128) goto exit; + + /* Only CBC mode is supported */ + if ((cmd & AES_CMD_MODE_MASK) != AES_CMD_CBC) goto exit; + + if (dst == NULL) + dst = src; + if (dst != src) + memcpy(dst, src, len); + + switch (cmd & AES_CMD_DIR_MASK) { + case AES_CMD_ENC : + (void)AES_CBC_EncryptInPlace(dst, len, keyType, (void *)key, iv); + break; + + case AES_CMD_DEC : + (void)AES_CBC_DecryptInPlace(dst, len, keyType, (void *)key, iv); + break; + } +#elif WITH_HW_AES + if (aes_hw_crypto_cmd(cmd, src, dst, len, opts, key, iv)) + return(-1); + goto exit; +#else +#error "aes_crypto_cmd: no valid implementation\n"; +#endif + +exit: + dprintf(DEBUG_SPEW, "aes_crypto_cmd: cmd: %08x, src: %p, dst: %p, len: %08zx, opts: %08x, key: %p, iv: %p \n", + cmd, src, dst, len, opts, key, iv); + + return(0); + +fail: + panic("AES: bad arguments"); +} + +int +do_aes_cmd(int argc, struct cmd_arg *args) +{ + u_int8_t pt[32]; + u_int8_t ct[32]; + u_int8_t k[16]; + u_int8_t iv[16]; + int i; + + /* seed the plaintext */ + for (i = 0; i < 32; i++) { + pt[i] = system_time() & 0xff; + } + + memset(k, 0x55, sizeof(k)); + memset(iv, 0, sizeof(iv)); + + if (argc > 1) { + if (strcmp(args[1].str, "uid0") == 0) { + printf("uid0\n"); + aes_cbc_encrypt(k, k, sizeof(k), AES_KEY_TYPE_UID0, NULL, NULL); + } + else if (strcmp(args[1].str, "gid0") == 0) { + printf("gid0\n"); + aes_cbc_encrypt(k, k, sizeof(k), AES_KEY_TYPE_GID0, NULL, NULL); + } + else if (strcmp(args[1].str, "gid1") == 0) { + printf("gid1\n"); + aes_cbc_encrypt(k, k, sizeof(k), AES_KEY_TYPE_GID1, NULL, NULL); + } + } + + printf("AES plaintext input:\n"); + hexdump(pt, 32); + memset(ct, 0, 32); + aes_crypto_cmd( + AES_CMD_ENC | AES_CMD_CBC, + &pt[0], + &ct[0], + 32, + AES_KEY_TYPE_USER | AES_KEY_SIZE_128, + k, + iv); + printf("AES ciphertext result:\n"); + hexdump(ct, 32); + memset(pt, 0, 32); + aes_crypto_cmd( + AES_CMD_DEC | AES_CMD_CBC, + &ct[0], + &pt[0], + 32, + AES_KEY_TYPE_USER | AES_KEY_SIZE_128, + k, + iv); + printf("AES plaintext result:\n"); + hexdump(pt, 32); + + return 0; +} + +int +do_aes_golden_vec_cmd(int argc, struct cmd_arg *args) +{ + uint8_t ct[16]; + uint8_t pt[16]; + + printf("encrypt:\n"); + + for (int i = 0; i < 10; i++) { + memset(pt, 0, sizeof(pt)); + memset(ct, 0x55, sizeof(pt)); + pt[0] = i; + + printf("src: [%p]", pt); + for (unsigned int j = 0; j < sizeof(pt); j++) + printf(" %02x", pt[j]); + printf("\n"); + + if (aes_crypto_cmd(AES_CMD_ENC | AES_CMD_CBC, pt, ct, sizeof(pt), AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256, NULL, NULL) != 0) { + printf("encyrpt failed\n"); + return -1; + } + + printf("dst: [%p]", ct); + for (unsigned int j = 0; j < sizeof(ct); j++) + printf(" %02x", ct[j]); + printf("\n"); + } + + printf("decrypt\n"); + + for (int i = 0; i < 10; i++) { + memset(ct, 0, sizeof(pt)); + memset(pt, 0x55, sizeof(pt)); + ct[0] = i; + + printf("src: [%p]", ct); + for (unsigned int j = 0; j < sizeof(ct); j++) + printf(" %02x", ct[j]); + printf("\n"); + + if (aes_crypto_cmd(AES_CMD_DEC | AES_CMD_CBC, ct, pt, sizeof(pt), AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256, NULL, NULL) != 0) { + printf("decrypt failed\n"); + return -1; + } + + printf("dst: [%p]", pt); + for (unsigned int j = 0; j < sizeof(pt); j++) + printf(" %02x", pt[j]); + printf("\n"); + } + + return 0; +} + + +// Turned off to save space, enable as needed +//MENU_COMMAND_DEBUG(aes, do_aes_cmd, "AES test", NULL); +//MENU_COMMAND_DEBUG(aes_golden_vec, do_aes_golden_vec_cmd, "AES golden vector test", NULL); diff --git a/drivers/aes/rules.mk b/drivers/aes/rules.mk new file mode 100644 index 0000000..0606c65 --- /dev/null +++ b/drivers/aes/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_AES=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/aes.o diff --git a/drivers/analogix/displayport/displayport.c b/drivers/analogix/displayport/displayport.c new file mode 100644 index 0000000..1286c62 --- /dev/null +++ b/drivers/analogix/displayport/displayport.c @@ -0,0 +1,1837 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "regs.h" + +#if WITH_HW_DISPLAY_DISPLAYPORT +#include +#endif + +#ifndef DISPLAYPORT_VERSION +#error "DISPLAYPORT_VERSION must be defined" +#endif + +///////////////////////////////////////// +////////// debug support + +#define DP_DEBUG_MASK ( \ + DP_DEBUG_INIT | \ + DP_DEBUG_ERROR | \ + DP_DEBUG_INFO | \ + DP_DEBUG_INT | \ + DP_DEBUG_VIDEO | \ + DP_DEBUG_AUX | \ + DP_DEBUG_DPCD | \ + DP_DEBUG_PLL | \ + DP_DEBUG_PHY | \ + 0) + +#undef DP_DEBUG_MASK +#define DP_DEBUG_MASK (DP_DEBUG_INIT | DP_DEBUG_ERROR) + +#define DP_DEBUG_INIT (1<<16) // initialisation +#define DP_DEBUG_ERROR (1<<17) // errors +#define DP_DEBUG_INFO (1<<18) // info +#define DP_DEBUG_INT (1<<19) // interrupts +#define DP_DEBUG_VIDEO (1<<20) // video +#define DP_DEBUG_AUX (1<<21) // aux channel +#define DP_DEBUG_DPCD (1<<22) // dpcp read/write +#define DP_DEBUG_I2C (1<<23) // i2c read/write +#define DP_DEBUG_PLL (1<<24) // PLL +#define DP_DEBUG_PHY (1<<25) // PLL +#define DP_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((DP_DEBUG_ ## _fac) & (DP_DEBUG_MASK | DP_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "DP: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +///////////////////////////////////////// +////////// consts + +// Crude screensaver: Turn off displayport after 3 minutes. +#define kScreenBurnTimeout (3 * 60 * 1000000) +#define kDPAuxRetryDelayUS 5000 +#define kAUXMaxBurstLengthStandard 16 + +#define kDisplayPortStackSize 8192 + +#define kLSClock_81mhz 81000000ULL +#define kLSClock_135mhz 135000000ULL +#define kLSClock_171mhz 171000000UL + +#define kLinkRatePhysical_162gbps 1620000000ULL +#define kLinkRatePhysical_270gps 2700000000ULL +#define kLinkRatePhysical_324gps 3240000000ULL + +#define kAUXRetryIntervalUS 5000 +#define kMaxAuxTransactionRetry 100 +#define kMaxI2CTransactionRetry 5 + +#define LPTX_BUF_DATA_COUNT 16 + +#define kDPHPDTimeout (70 * 1000) + +//The display spec for edp requires 134ms from HPD to backlight ON. +//The following time accounts for HPD occurring upto before programming the backlight. +//Depending on the backlight solution, its programming time varies. Best guess is around 10ms. +#define kDPDeviceHPD2BLON (170 * 1000) + +///////////////////////////////////////// +////////// typedefs, enums, structs + +enum { + kDPAuxTranscationStatus_None = -1, + kDPAuxTranscationStatus_Success, + kDPAuxTranscationStatus_IODefer, + kDPAuxTranscationStatus_IOError, + kDPAuxTranscationStatus_OtherError +}; + +enum { + kBaseVoltageType_Neg_120mV, + kBaseVoltageType_Neg_80mV, + kBaseVoltageType_Neg_40mV, + kBaseVoltageType_Pos_0mV, + kBaseVoltageType_Pos_40mV, + kBaseVoltageType_Pos_80mV, + kBaseVoltageType_Pos_120mV, + kBaseVoltageType_Pos_160mV +}; + +struct eq_calibration { + uint32_t swing; + uint32_t swing_max; + uint32_t eq; + uint32_t eq_max; +}; + +struct swing_calibration { + int32_t base; + uint32_t boost; + struct eq_calibration eq_levels[4]; +}; + +struct port_calibration { + struct swing_calibration swing[4]; +}; + +enum { + kI2COptionsNone = 0, + kI2COptionsTransactionStart = (1 << 0), + kI2COptionsTransactionEnd = (1 << 1), + kI2COptionsRetryOnDeferOnly = (1 << 2), +}; + +///////////////////////////////////////// +////////// local variables + +static const uint32_t __s_bpp_coeff[3] = {3, 2, 3}; // RGB:3, YCBR422:2, YCBR444:3 + +static addr_t __base_address; + +static bool dp_voltage_boost; + +static volatile bool dp_aux_transaction_pending; +static volatile int dp_aux_transaction_status; + +static bool dp_started; +static bool dp_video_started; +#if WITH_HW_DISPLAY_DISPLAYPORT +static bool dp_aux_abort; +#endif + +static struct task *dp_task; +static struct task_event dp_controller_task_event; +static bool dp_interrupt_occurred; + +static dp_t *dp_link_config_ptr; + +static uint32_t dp_controller_common_sta_4_val; +static uint32_t dp_controller_common_sta_3_val; +static uint32_t dp_controller_common_sta_2_val; +static uint32_t dp_controller_common_sta_1_val; +static uint32_t dp_controller_sta_val; + +static struct callout dp_controller_screensaver_callout; + +static struct task_event dp_controller_hpd_event; + +static uint32_t dp_min_lane_count; + +///////////////////////////////////////// +////////// local functions declaration + +static int dp_controller_task(void *arg); +static void reset(); +static int configure_video(struct video_link_data *data); +static void init_video(); +static void configure_video_m_n(struct video_link_data *data); +static int configure_video_color(struct video_link_data *data); +static int configure_video_mode(struct video_link_data *data); +static int validate_video(struct video_link_data *data, uint32_t *m_vid, uint32_t *n_vid); +static void configure_video_bist(struct video_link_data *data); +static void interrupt_filter(void *arg); +static void handle_interrupt(void); +static int commit_aux_transaction(bool use_interrupts, bool deferRetryOnly, uint32_t max_retry_count); +static int wait_for_aux_idle(); +static int read_bytes_i2c_internal(uint32_t device_addr, uint32_t addr, u_int8_t *data, uint32_t length); +static void uninit_video(); +static void disable_video(void); +static void init_aux(); + +static void handle_screensaver_callout(struct callout *co, void *args); + +static uint32_t read_reg(uint32_t offset); +static void write_reg(uint32_t offset, uint32_t val); +static void and_reg(uint32_t offset, uint32_t val); +static void or_reg(uint32_t offset, uint32_t val); +static void set_bits_in_reg(uint32_t offset, uint32_t pos, uint32_t mask, uint32_t value); +static inline uint32_t ulmin(uint32_t a, uint32_t b) +{ + return (a < b ? a : b); +} + +struct dp_controller_config { + addr_t base_address; + uint32_t clock; + uint32_t irq; + const char *dt_path; +}; + +static const struct dp_controller_config dp_config[] = { +#if WITH_HW_DISPLAY_DISPLAYPORT + { DP_BASE_ADDR, CLK_DPLINK, INT_DPORT0, DP_DTPATH }, +#else + { 0, 0, 0, 0 }, +#endif // WITH_HW_DISPLAY_DISPLAYPORT +#if WITH_HW_DISPLAY_EDP + { EDP_BASE_ADDR, CLK_EDPLINK, INT_EDP0, DP_DTPATH }, +#else + { 0, 0, 0, 0 }, +#endif // WITH_HW_DISPLAY_EDP +}; + +///////////////////////////////////////// +////////// controller global functions + +int dp_controller_start(dp_t *dp_link_config) +{ + DTNodePtr node; + char * prop_name; + void * prop_data; + uint32_t prop_size; + + if (dp_started) + return 0; + + dp_link_config_ptr = dp_link_config; + + if (dp_link_config_ptr->type > kDPControllerType_EDP) { + debug(INIT, "dp_controller_start: bad controller type: %d\n", dp_link_config->type); + return -1; + } + + if (dp_config[dp_link_config_ptr->type].dt_path == 0) { + debug(INIT, "dp_controller_start: controller type not configured: %d\n", dp_link_config->type); + return -1; + } + + __base_address = dp_config[dp_link_config_ptr->type].base_address; + // turn on the clock + clock_gate(dp_config[dp_link_config_ptr->type].clock, true); + + //reset Device + clock_reset_device(dp_config[dp_link_config_ptr->type].clock); + spin(100); //TODO: how long? + + dp_voltage_boost = false; + + lpdp_init(DPPHY_DTPATH); + + // gather calibration data from DeviceTree + if ( FindNode(0, dp_config[dp_link_config_ptr->type].dt_path, &node) ) { + // max lane count + prop_name = "max_lane_count"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_link_config_ptr->lanes = *((uint32_t*)prop_data); + } + + // max link rate + prop_name = "max_link_rate"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_link_config_ptr->max_link_rate = *((uint32_t*)prop_data); + } + + // min lane count + prop_name = "min_lane_count"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_min_lane_count = *((uint32_t*)prop_data); + } + + // min link rate + prop_name = "min_link_rate"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_link_config_ptr->min_link_rate = *((uint32_t*)prop_data); + } + + // downspread + prop_name = "downspread_support"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_link_config_ptr->ssc = *((uint32_t*)prop_data); + } + } + + // register interrupt handler + install_int_handler(dp_config[dp_link_config_ptr->type].irq, interrupt_filter, NULL); + + event_init(&dp_controller_task_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + dp_task = task_create("displayport", &dp_controller_task, NULL, kDisplayPortStackSize); + task_start(dp_task); + + event_init(&dp_controller_hpd_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + reset(); + + dp_started = true; + + unmask_int(dp_config[dp_link_config_ptr->type].irq); + + debug(INIT, "dp inited\n"); + debug(INIT, "dp_link_config_ptr->type %d\n", dp_link_config_ptr->type); + debug(INIT, "dp_link_config_ptr->mode %d\n", dp_link_config_ptr->mode); + debug(INIT, "dp_link_config_ptr->lanes %d\n", dp_link_config_ptr->lanes); + debug(INIT, "dp_link_config_ptr->max_link_rate 0x%x\n", dp_link_config_ptr->max_link_rate); + debug(INIT, "dp_link_config_ptr->min_link_rate 0x%x\n", dp_link_config_ptr->min_link_rate); + debug(INIT, "dp_link_config_ptr->ssc %d\n", dp_link_config_ptr->ssc); + + return 0; +} + +void dp_controller_stop() +{ + if (!dp_started || !dp_video_started) + return; + +#if WITH_HW_DISPLAY_DISPLAYPORT + dp_aux_abort = true; + +#if WITH_HW_MCU + // Stop background EDID polling. + abort_edid(); +#endif +#endif + + displayport_enable_alpm(false); + dp_controller_stop_video(); + + // disable interrupt source + mask_int(dp_config[dp_link_config_ptr->type].irq); + + dp_video_started = false; + + dp_device_stop(); + + write_reg(DPTX_INTERRUPT_MASK_1, 0); + write_reg(DPTX_INTERRUPT_MASK_4, 0); + write_reg(DPTX_INTERRUPT_ENABLE, 0); + + write_reg(DPTX_COMMON_INTERRUPT_STATUS_1, 0xff); + write_reg(DPTX_COMMON_INTERRUPT_STATUS_4, 0xff); + write_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS, 0xff); + + if (dp_link_config_ptr->type == kDPControllerType_DP) { + callout_dequeue(&dp_controller_screensaver_callout); + } + + // Turn off all functions. + write_reg(DPTX_FUNCTION_ENABLE_2, DPTX_SSC_FUNC_EN_N | + DPTX_AUX_FUNC_EN_N | + DPTX_SERDES_FIFO_FUNC_EN_N | + DPTX_LS_CLK_DOMAIN_FUNC_EN_N ); + + lpdp_quiesce(); + + // disable the clock + clock_gate(dp_config[dp_link_config_ptr->type].clock, false); + + dp_started = false; + + // exit task and free memory + event_signal(&dp_controller_task_event); + task_wait_on(dp_task); + task_destroy(dp_task); +} + +#if WITH_HW_DISPLAY_EDP +// Ensure enough time has passed from HPD and turning the backlight ON +void dp_controller_wait_for_HPD_to_BL(utime_t hpd_time) +{ + utime_t hpd2blON = hpd_time + kDPDeviceHPD2BLON; + utime_t now = system_time(); + utime_t timeleft = 0; + + if (now >= hpd2blON) { + debug(INIT, "no need to wait hpd2blON 0x%llx hpd_time 0x%llx now 0x%llx timeleft 0x%llx\n", hpd2blON, hpd_time, now, timeleft); + return; + } + timeleft = hpd2blON - now; + spin(timeleft); + debug(INIT, "waited hpd2blON 0x%llx hpd_time 0x%llx now 0x%llx timeleft 0x%llx\n", hpd2blON, hpd_time, now, timeleft); +} + +bool dp_controller_wait_for_edp_hpd(utime_t *hpd_time) +{ + bool res; + + res = event_wait_timeout(&dp_controller_hpd_event, kDPHPDTimeout); + //We might have missed the interrupt yet HPD is high. Check one last time before giving up + if (!res) { + if ( read_reg(DPTX_SYSTEM_CONTROL_3) & DPTX_HPD_STATUS ) { + dp_device_start((dp_link_config_ptr->type == kDPControllerType_EDP) ? true : false); + res = true; + } + } + *hpd_time = system_time(); + + return res; +} +#endif // WITH_HW_DISPLAY_EDP + +int dp_controller_validate_video(struct video_timing_data *timings) +{ + // Assume basic settings. + struct video_link_data data; + bzero(&data, sizeof(data)); + bcopy(timings, &data.timing, sizeof(*timings)); + data.mirror_mode = false; + data.test_mode = 0; + data.color.depth = 8; + data.color.space = kDisplayColorSpacesRGB; + data.color.range = kDisplayColorDynamicRangeVESA; + data.color.coefficient = kDisplayColorCoefficientITU601; + return validate_video(&data, NULL, NULL); +} + +uint32_t dp_controller_get_max_lane_count() +{ + return dp_link_config_ptr->lanes; +} + +uint32_t dp_controller_get_max_link_rate() +{ + return dp_link_config_ptr->max_link_rate; +} + +uint32_t dp_controller_get_min_lane_count() +{ + return dp_min_lane_count; +} + +uint32_t dp_controller_get_min_link_rate() +{ + return dp_link_config_ptr->min_link_rate; +} + +int dp_controller_set_link_rate(uint32_t link_rate) +{ + + return lpdp_set_link_rate(link_rate); +} + +int dp_controller_get_link_rate(uint32_t *link_rate) +{ + return lpdp_get_link_rate(link_rate); +} + +int dp_controller_set_lane_count(uint32_t lane_count) +{ + bool is_downspread_supported = false; + + // disable SSC, SERDES FIFO, and link symbol clock domain modules + or_reg(DPTX_FUNCTION_ENABLE_2, DPTX_SSC_FUNC_EN_N | DPTX_SERDES_FIFO_FUNC_EN_N | DPTX_LS_CLK_DOMAIN_FUNC_EN_N); + + lpdp_phy_set_lane_count(lane_count); + + // Note: DPTX_LANE_COUNT_SET == 0 is an illegal value; see + write_reg(DPTX_MAIN_LINK_LANE_COUNT, lane_count); + + dp_controller_get_downspread(&is_downspread_supported); + + // enable SSC (if applicable), SERDES FIFO, and link symbol clock domain modules + and_reg(DPTX_FUNCTION_ENABLE_2, ~((is_downspread_supported ? DPTX_SSC_FUNC_EN_N : 0) | DPTX_SERDES_FIFO_FUNC_EN_N | DPTX_LS_CLK_DOMAIN_FUNC_EN_N)); + + write_reg(DPTX_FUNCTION_ENABLE_1, DPTX_LINK_CONTROLLER_RESET); + and_reg(DPTX_FUNCTION_ENABLE_1, ~DPTX_LINK_CONTROLLER_RESET); + + return 0; +} + +int dp_controller_get_lane_count(uint32_t * lane_count) +{ + *lane_count = read_reg(DPTX_MAIN_LINK_LANE_COUNT); + + return 0; +} + +bool dp_controller_get_supports_fast_link_training() +{ + return dp_link_config_ptr->fast_link_training; +} + +bool dp_controller_get_supports_downspread() +{ + return (dp_link_config_ptr->ssc && lpdp_get_supports_downspread()); +} + +int dp_controller_set_downspread(bool state) +{ + return lpdp_set_downspread(state); +} + +int dp_controller_get_downspread(bool *state) +{ + *state = lpdp_get_downspread(); + + return 0; +} + +int dp_controller_set_enhanced_mode(bool mode) +{ + if ( mode ) + or_reg(DPTX_SYSTEM_CONTROL_4, DPTX_ENHANCED); + else + and_reg(DPTX_SYSTEM_CONTROL_4, ~(DPTX_ENHANCED)); + + return 0; +} + +int dp_controller_get_enhanced_mode(bool * mode) +{ + *mode = read_reg(DPTX_SYSTEM_CONTROL_4) & DPTX_ENHANCED; + + return 0; +} + +int dp_controller_set_ASSR(bool mode) +{ + if ( mode ) + or_reg(DPTX_DP_EDP_CONTROL, DPTX_ALTERNATE_SR_EN); + else + and_reg(DPTX_DP_EDP_CONTROL, ~DPTX_ALTERNATE_SR_EN); + + return 0; +} + +int dp_controller_get_ASSR(bool * mode) +{ + *mode = read_reg(DPTX_DP_EDP_CONTROL) & DPTX_ALTERNATE_SR_EN; + + return 0; +} + +int dp_controller_get_adjustment_levels(uint32_t lane, uint32_t *voltage_swing, uint32_t *eq) +{ + uint32_t lane_count; + int ret = 0; + + if ( lane > dp_link_config_ptr->lanes ) + return -1; + + ret = dp_controller_get_lane_count(&lane_count); + if (ret != 0) + return ret; + + return (lpdp_phy_get_adjustment_levels(lane, voltage_swing, eq)); +} + +int dp_controller_set_adjustment_levels(uint32_t lane, uint32_t voltage_swing, uint32_t eq, + bool *voltage_max_reached, bool *eq_max_reached) +{ + return (lpdp_phy_set_adjustment_levels(lane, voltage_swing, eq, voltage_max_reached, eq_max_reached)); +} + +int dp_controller_set_training_pattern(uint32_t value, bool scramble) +{ + uint32_t scram_setting = 0; + + debug(INFO, "training pattern=%d scrambled=%d\n", value, scramble); + //TODO: fix need for scrambling via settings rdar://problem/15466504> + + scram_setting |= scramble ? 0 : DPTX_SCRAMBLING_DISABLE; + write_reg(DPTX_DP_TRAINING_PATTERN_SET, scram_setting | value); + + return 0; +} + +int dp_controller_get_training_pattern(uint32_t *pattern, bool *scramble) +{ + uint32_t value = read_reg(DPTX_DP_TRAINING_PATTERN_SET); + + if ( scramble ) + *scramble = (value & DPTX_SCRAMBLING_DISABLE) == 0; + + if ( pattern ) + *pattern = (value & DPTX_SW_TRAINING_PTRN_SET_SW_MASK); + + return 0; +} + +void setup_aux_transaction(uint32_t address, uint32_t length, uint32_t command) +{ + write_reg(DPTX_DP_AUX_CHANNEL_LENGTH, DPTX_AUX_LENGTH(length - 1)); + + write_reg(DPTX_DP_AUX_CH_ADDRESS_0, 0xFF & address); + write_reg(DPTX_DP_AUX_CH_ADDRESS_1, 0xFF & (address >> 8)); + write_reg(DPTX_DP_AUX_CH_CONTROL_1, (command & DPTX_AUX_CH_CTL_1_AUX_TX_COMM_MASK) | (0x0F & (address >> 16))); + + // Ensure that AUX_CH_CTL_2[ADDR_ONLY] is set appropriately for each transaction + write_reg(DPTX_DP_AUX_CH_CONTROL_2, (length > 0) ? 0 : DPTX_ADDR_ONLY); +} + +int dp_controller_read_bytes_dpcd(uint32_t addr, u_int8_t *data, uint32_t length) +{ + uint32_t startOffset = 0; + uint32_t maxBurstLength = kAUXMaxBurstLengthStandard; + int ret = 0; + + debug(DPCD, "addr=0x%08x data=%p length=%d payload:\n", addr, data, length); + + while (startOffset < length) { + uint32_t actualDataCount; + uint32_t currentDataCount = __min(maxBurstLength, (length - startOffset)); + + setup_aux_transaction(addr+startOffset, currentDataCount, + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_NATIVE | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_READ); + + //Clear Buffer + write_reg(DPTX_DP_BUFFER_DATA_COUNT, DPTX_BUF_CLR); + + //Start Aux transaction + ret = commit_aux_transaction(false, false, kMaxAuxTransactionRetry); + if ( ret != 0 ) + return -1; + + actualDataCount = read_reg(DPTX_DP_BUFFER_DATA_COUNT) & 0xff; + debug(DPCD, "Aux data length %d, expecting %d\n", actualDataCount, currentDataCount); + + if (actualDataCount == 0) { + debug(ERROR, "actual count is 0\n"); + return -1; + } + + if ( currentDataCount != actualDataCount ) + currentDataCount = __min(actualDataCount, currentDataCount); + + debug(DPCD, "read: Bytes:\n"); + + for(uint32_t currentDataIndex = 0; currentDataIndex < currentDataCount; currentDataIndex++) { + data[startOffset + currentDataIndex] = (uint8_t)read_reg(DPTX_AUX_CH_BUFFER_DATA_0 + (currentDataIndex*sizeof(uint32_t))); + debug(DPCD, "read: " "\t0x%08x: %02x\n", addr + currentDataIndex, data[startOffset + currentDataIndex]); + } + + startOffset += currentDataCount; + } + + return 0; +} + +int dp_controller_read_bytes_i2c(uint32_t device_addr, uint32_t addr, u_int8_t *data, uint32_t length) +{ + uint32_t startOffset = 0; + int ret = 0; + + // try the 128 byte read first + if ( read_bytes_i2c_internal(device_addr, addr, data, length) == 0 ) + return 0; + + debug(I2C, "retrying with segmented reads\n"); + + // if that fails, fall back to individual 16 byte reads + while ( startOffset < length ) { + uint32_t currentDataCount = ((length - startOffset) > LPTX_BUF_DATA_COUNT) ? LPTX_BUF_DATA_COUNT: (length - startOffset); + uint32_t retryCount = 0; + + ret = read_bytes_i2c_internal(device_addr, addr + startOffset, data + startOffset, currentDataCount); + + debug(I2C, "segmented read result=0x%08x with %d retries\n", ret, retryCount); + + if ( ret != 0 ) + break; + + startOffset += currentDataCount; + } + return ret; +} + +int dp_controller_write_bytes_dpcd(uint32_t addr, u_int8_t *data, uint32_t length) +{ + uint32_t startOffset = 0; + int ret; + + ret = -1; + + debug(DPCD, "write: addr=0x%08x data=%p length=%d \n", addr, data, length); + + while (startOffset < length) { + uint32_t currentDataCount; + uint32_t currentDataIndex; + + currentDataCount = ((length - startOffset) > LPTX_BUF_DATA_COUNT) ? LPTX_BUF_DATA_COUNT: (length - startOffset); + + setup_aux_transaction(addr+startOffset, currentDataCount, + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_NATIVE | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_WRITE); + + //Clear Buffer + write_reg(DPTX_DP_BUFFER_DATA_COUNT, DPTX_BUF_CLR); + + debug(DPCD, "write: Bytes:\n"); + for(currentDataIndex = 0; currentDataIndex < currentDataCount; currentDataIndex++) { + debug(DPCD, "write:\t 0x%08x: %2.2x\n", addr + currentDataIndex, data[startOffset + currentDataIndex]); + write_reg(DPTX_AUX_CH_BUFFER_DATA_0 + (currentDataIndex*sizeof(uint32_t)), + data[startOffset + currentDataIndex]); + } + + //Start Aux transaction + ret = commit_aux_transaction(false, false, kMaxAuxTransactionRetry); + if ( ret != 0 ) + break; + + startOffset += currentDataCount; + } + debug(DPCD,"\n"); + + return ret; +} + +int issue_i2c_write_request(uint32_t options, uint32_t address, const uint8_t * data, unsigned int length) +{ + //If not end set mot = 1 + uint32_t mot = (options & kI2COptionsTransactionEnd) ? 0 : DPTX_AUX_CH_CTL_1_AUX_TX_COMM_MOT; + int ret; + + if (length > DPTX_BUF_DATA_COUNT) + return -1; + + //Clear Buffer + write_reg(DPTX_DP_BUFFER_DATA_COUNT, DPTX_BUF_CLR); + debug(I2C, "writing %d bytes @ I2C 0x%02x:\n", length, address); + + //Fill buffer + for (unsigned int i = 0; i < length; i++ ) { + write_reg(DPTX_AUX_CH_BUFFER_DATA_0 + (i * sizeof(uint32_t)), data[i]); + } + setup_aux_transaction(address, length, mot | DPTX_AUX_CH_CTL_1_AUX_TX_COMM_WRITE); + + //Start Aux transaction + ret = commit_aux_transaction(false, false, options & kI2COptionsRetryOnDeferOnly); + if ( ret ) + debug(I2C, "ret=0x%08x\n", ret); + + return ret; +} + +int dp_controller_write_bytes_i2c(uint32_t device_addr, uint32_t addr, u_int8_t *data, uint32_t length) +{ + int ret = 0; + uint32_t offset = 0; + uint32_t attemptCount = 0; + uint32_t maxAttempts = kMaxI2CTransactionRetry + 1; + uint32_t maxBurstLength = kAUXMaxBurstLengthStandard; + int transfer_status = 0; + + // Since we don't allow any retries on commitAuxTransaction, we should really + // retry on the whole transaction, which includes: start, commmit, and stop + while( attemptCount++ < maxAttempts ) { + if ( ret != 0 ) { + debug(I2C, "waiting %dms till next attempt\n", kAUXRetryIntervalUS); + task_sleep(kAUXRetryIntervalUS); + } + + debug(I2C, "retry=%d device_addr=0x%08x addr=0x%08x data=%p length=%d\n", attemptCount, device_addr, addr, data, length); + + ret = issue_i2c_write_request(kI2COptionsTransactionStart, device_addr, NULL, 0); + if ( ret != 0 ) + goto check; + + while (offset < length) { + uint32_t chunk = ulmin(maxBurstLength, (length - offset)); + + debug(I2C,"offset=%d requesting=%d bytes\n", offset, chunk); + + ret = issue_i2c_write_request(kI2COptionsRetryOnDeferOnly, device_addr, data + offset, chunk); + if (ret != 0 ) + goto check; + offset += chunk; + } +check: + // save transfer status + transfer_status = ret; + + // terminate transaction regardless of transfer errors + ret = issue_i2c_write_request(kI2COptionsTransactionEnd, device_addr, NULL, 0); + + // if stop was successful, use transfer error as return status + ret = transfer_status; + } + debug(I2C,"result=0x%08x\n",ret); + return ret; +} + +int dp_controller_start_video(struct video_link_data *data) +{ +#if WITH_HW_MCU && WITH_HW_DISPLAY_DISPLAYPORT + struct video_link_data edid_data; +#endif + struct video_link_data *timings = NULL; + if ( !dp_started ) + return -1; +#if WITH_HW_MCU && WITH_HW_DISPLAY_DISPLAYPORT + // Overwriting timings with EDID preference. + bcopy(data, &edid_data, sizeof(edid_data)); + if (get_edid_timings(&edid_data.timing) == 0) timings = &edid_data; +#endif + if (timings == NULL) timings = data; + + return configure_video(timings); +} + +int dp_controller_stop_video() +{ + if ( !dp_video_started ) + return -1; + + and_reg(DPTX_SYSTEM_CONTROL_3, ~DPTX_VIDEO_SENDING_EN); + + and_reg(DPTX_VIDEO_CONTROL_1, ~DPTX_VIDEO_EN); + + dp_video_started = false; + + return 0; +} + +bool dp_controller_video_configured() +{ + return dp_video_started; +} + +bool dp_controller_get_supports_alpm(void) +{ + return dp_link_config_ptr->alpm; +} + +int dp_controller_enable_alpm(bool enable, struct video_link_data *data) +{ + if (enable) { + // Force PLL lock to high all the time to avoid un-necessary reset during ALPM mode + or_reg(DPTX_DP_DEBUG_CONTROL_1, ( DPTX_F_PLL_LOCK | DPTX_PLL_LOCK_CTRL)); + +#if DISPLAYPORT_VERSION < 5 + write_reg(DPTX_DP_VIDEO_DATA_FIFO_THRESHOLD, DPTX_VIDEO_TH_VALUE(0x8)); + + // To avoid Video FIFO overrun + or_reg(DPTX_DP_VIDEO_DATA_FIFO_THRESHOLD, DPTX_VIDEO_TH_CTRL); +#endif + + lpdp_phy_configure_alpm(enable); + +#if DISPLAYPORT_VERSION >= 5 + // Program AUX_LINES_START/AUX_LINES_END registers + write_reg(DPTX_AUX_LINES_START, + 0); + write_reg(DPTX_AUX_LINES_END, + data->timing.axis[kDisplayAxisTypeVertical].active + + data->timing.axis[kDisplayAxisTypeVertical].sync_width + + data->timing.axis[kDisplayAxisTypeVertical].back_porch); +#endif + + // Program ALPM control registers + // Clear PHY_SLEEP_DIS (use PHY_SLEEP only) + and_reg(DPTX_ADVANCED_LINK_POWER_MANAGEMENT_CONTROL_2, ~(DPTX_PHY_SLEEP_EN)); + write_reg(DPTX_WAKEUP_LINES, dp_link_config_ptr->rx_n1); + write_reg(DPTX_WAKEUP_CR_SYMBOLS, dp_link_config_ptr->rx_n2); + write_reg(DPTX_SYMBOL_LOCK_PATTERN, dp_link_config_ptr->rx_n3); + +#if DISPLAYPORT_VERSION >= 4 + write_reg(DPTX_SLEEP_STANDBY_DELAY_REG, DPTX_SLEEP_STANDBY_DELAY(dp_link_config_ptr->rx_n5)); +#endif + // Enable ALPM. ML_PHY_SLEEP_EN is used only + // why need to set AUX_WAKE_UP_EN instead of WAKE_F_CHANGE_EN + or_reg(DPTX_ADVANCED_LINK_POWER_MANAGEMENT_CONTROL_1, (DPTX_ALPM_PARA_UPDATE_EN | DPTX_ALPM_MODE | DPTX_ML_PHY_SLEEP_EN | DPTX_WAKE_F_CHANGE_EN)); + } else { + // Disable ALPM.. + and_reg(DPTX_ADVANCED_LINK_POWER_MANAGEMENT_CONTROL_1, ~(DPTX_ML_PHY_SLEEP_EN | DPTX_ML_PHY_STANDBY_EN)); + spin(17 * 1000); + +#if DISPLAYPORT_VERSION >= 5 + // Program AUX_LINES_START/AUX_LINES_END registers + write_reg(DPTX_AUX_LINES_START, 0); + write_reg(DPTX_AUX_LINES_END, 0); +#endif + } + + return 0; + +} +///////////////////////////////////////// +////////// controller local functions + +static void handle_screensaver_callout(struct callout *co, void *args) +{ + debug(ALWAYS, "Analogix Screensaver\n"); + + display_clear(); +} + +static int dp_controller_task(void *arg) +{ + // External display, we would like to put screensaver + if (dp_link_config_ptr->type == kDPControllerType_DP) { + callout_enqueue(&dp_controller_screensaver_callout, kScreenBurnTimeout, handle_screensaver_callout, NULL); + } + + for (;;) { + + event_wait(&dp_controller_task_event); + + // if controller was stopped before dp task got chance to run, exit + if (dp_started == false) { + printf("dp not started\n"); + return 0; + } + + mask_int(dp_config[dp_link_config_ptr->type].irq); + + if (dp_interrupt_occurred) { + dp_interrupt_occurred = false; + + if (dp_link_config_ptr->type == kDPControllerType_DP) { + callout_reset(&dp_controller_screensaver_callout, 0); + } + // Invoke bottom half. + handle_interrupt(); + } + + unmask_int(dp_config[dp_link_config_ptr->type].irq); + } + + return 0; +} + +static void init_registers() +{ + write_reg(DPTX_FUNCTION_ENABLE_2, DPTX_SSC_FUNC_EN_N | + DPTX_AUX_FUNC_EN_N | + DPTX_SERDES_FIFO_FUNC_EN_N | + DPTX_LS_CLK_DOMAIN_FUNC_EN_N ); + disable_video(); + + write_reg(DPTX_VIDEO_CONTROL_4, 0); + + write_reg(DPTX_SYSTEM_CONTROL_1, 0x0); + write_reg(DPTX_SYSTEM_CONTROL_2, DPTX_CHA_CRI(1)); + write_reg(DPTX_SYSTEM_CONTROL_3, 0x0); + write_reg(DPTX_SYSTEM_CONTROL_4, 0x0); + + write_reg(DPTX_PACKET_SEND_CONTROL, 0x0); + + write_reg(DPTX_DP_HPD_DE_GLITCH, DPTX_HPD_DEGLITCH_DEFAULT); + + write_reg(DPTX_DP_LINK_DEBUG_CONTROL, DPTX_NEW_PRBS7); + + write_reg(DPTX_THRESHOLD_OF_M_VID_GENERATION_FILTER, 0x4); // register default + +#if DISPLAYPORT_VERSION < 5 + write_reg(DPTX_DP_VIDEO_DATA_FIFO_THRESHOLD, 0x0); + + // set video FIFO threshold + // + // Reference: + // Fiji/Capri LPDP-TX Programming Sequence Guideline Document, Revision A.3 + set_bits_in_reg(DPTX_DP_VIDEO_DATA_FIFO_THRESHOLD, + DPRX_VIDEO_TH_VALUE_SHIFT, + DPRX_VIDEO_TH_VALUE_MASK, 8); // TODO: allow configuration via device tree + + or_reg(DPTX_DP_VIDEO_DATA_FIFO_THRESHOLD, DPTX_VIDEO_TH_CTRL); +#endif +} + +static void reset() +{ + // initialize PHY/PL + lpdp_initialize_phy_and_pll(); + + // initialize registers + init_registers(); + + //Initialize controller + and_reg(DPTX_DP_ANALOG_POWER_DOWN, ~DPTX_DP_PHY_PD); + and_reg(DPTX_FUNCTION_ENABLE_2, ~(DPTX_SERDES_FIFO_FUNC_EN_N | DPTX_LS_CLK_DOMAIN_FUNC_EN_N)); + and_reg(DPTX_FUNCTION_ENABLE_1, ~(DPTX_VID_CAP_FUNC_EN_N | DPTX_VID_FIFO_FUNC_EN_N | DPTX_SW_FUNC_EN_N)); + + // Initially, let's only register for HPD changes + write_reg(DPTX_INTERRUPT_MASK_4, DPTX_HOTPLUG_CHG | DPTX_PLUG | DPTX_HPD_LOST); + write_reg(DPTX_INTERRUPT_ENABLE, DPTX_INT_HPD); + + init_aux(); + + //TODO + // Fiji/Capri LPDP: Implement eDP ALTERNATE SCRAMBLER RESET +} + +static void init_aux() +{ + // clear pending interrupts + or_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS, DPTX_RPLY_RECEIV | DPTX_AUX_ERR); + + // power off aux to reset + or_reg(DPTX_FUNCTION_ENABLE_2, DPTX_AUX_FUNC_EN_N); + + write_reg(DPTX_DP_AUX_CH_DEFER_CONTROL, DPTX_DEFER_CTRL_EN | DPTX_DEFER_COUNT(0)); + + set_bits_in_reg(DPTX_BIST_AUX_CH_RELATED_REGISTER, 0, + DPTX_BIST_AUX_AUX_TC_MASK | DPTX_BIST_AUX_AUX_RETRY_TIMER_MASK, + DPTX_AUX_TC_d599 | DPTX_BIST_AUX_AUX_RETRY_TIMER(0)); + +#if WITH_HW_DISPLAY_EDP + set_bits_in_reg(DPTX_BIST_AUX_CH_RELATED_REGISTER, DPTX_BIST_AUX_AUX_RETRY_TIMER_SHIFT, DPTX_BIST_AUX_AUX_RETRY_TIMER_MASK, 7); +#endif + + and_reg(DPTX_FUNCTION_ENABLE_2, ~DPTX_AUX_FUNC_EN_N); + + write_reg(DPTX_DP_AUX_CH_CONTROL_2, 0); + write_reg(DPTX_DP_AUX_CH_CONTROL_1, 0); +} + +static void interrupt_filter(void *arg) +{ + dp_controller_common_sta_4_val = read_reg(DPTX_COMMON_INTERRUPT_STATUS_4); + write_reg(DPTX_COMMON_INTERRUPT_STATUS_4, dp_controller_common_sta_4_val); + + dp_controller_common_sta_1_val = read_reg(DPTX_COMMON_INTERRUPT_STATUS_1); + write_reg(DPTX_COMMON_INTERRUPT_STATUS_1, dp_controller_common_sta_1_val); + + dp_controller_sta_val = read_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS); + write_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS, dp_controller_sta_val); + + debug(INT, "Interrupt received. common_sta_4_val=0x%08x common_sta_3_val=0x%08x common_sta_2_val=0x%08x common_sta_1_val=0x%08x sta_val=0x%08x\n", + dp_controller_common_sta_4_val, dp_controller_common_sta_3_val, dp_controller_common_sta_2_val, dp_controller_common_sta_1_val, dp_controller_sta_val); + + dp_interrupt_occurred = true; + + event_signal(&dp_controller_task_event); +} + +static void handle_interrupt(void) +{ + // This occurs in task context with interrupt masked. + + uint32_t common_sta_4_val; + uint32_t common_sta_3_val; + uint32_t common_sta_2_val; + uint32_t common_sta_1_val; + uint32_t sta_val; + + common_sta_4_val = dp_controller_common_sta_4_val; + common_sta_3_val = dp_controller_common_sta_2_val; + common_sta_2_val = dp_controller_common_sta_2_val; + common_sta_1_val = dp_controller_common_sta_1_val; + sta_val = dp_controller_sta_val; + + debug(INT, "Interrupt received. common_sta_4_val=0x%08x common_sta_3_val=0x%08x common_sta_2_val=0x%08x common_sta_1_val=0x%08x sta_val=0x%08x\n", + common_sta_4_val, common_sta_3_val, common_sta_2_val, common_sta_1_val, sta_val); + + if ( dp_aux_transaction_pending ) { + + if ( (read_reg(DPTX_DP_AUX_CH_CONTROL_2) & DPTX_AUX_EN) == 0 ) { + + if ( DPTX_RPLY_RECEIV & sta_val ) { + dp_aux_transaction_status = kDPAuxTranscationStatus_Success; + debug(AUX, "waking pending dp_aux_transaction_status\n"); + // wake up dp_aux_transaction_status + } + + if ( DPTX_AUX_ERR & sta_val ) { + uint8_t aux_err = read_reg(DPTX_AUX_CHANNEL_ACCESS_STATUS) & 0xf; + dp_aux_transaction_status = ( aux_err == DPTX_MUCH_DEFER_ERROR ) ? kDPAuxTranscationStatus_IODefer : kDPAuxTranscationStatus_IOError; + debug(AUX, "waking pending dp_aux_transaction_status\n"); + // wake up dp_aux_transaction_status + } + } + } + + if ( DPTX_INT_HPD & sta_val ) { + debug(INT, "DPTX_DP_INT_STA_INT_HPD\n"); + } + + if ( DPTX_HOTPLUG_CHG & common_sta_4_val ) { + debug(INT, "DPTX_SYSTEM_CONTROL_3=%d\n", read_reg(DPTX_SYSTEM_CONTROL_3)); + } + + if ( DPTX_HPD_LOST & common_sta_4_val ) { + if ( !(read_reg(DPTX_SYSTEM_CONTROL_3) & DPTX_HPD_STATUS) ) { + dp_device_stop(); + } + } + + if ( DPTX_HOTPLUG_CHG & common_sta_4_val ) { + if ( read_reg(DPTX_SYSTEM_CONTROL_3) & DPTX_HPD_STATUS ) { + event_signal(&dp_controller_hpd_event); + +#if WITH_HW_DISPLAY_DISPLAYPORT + dp_aux_abort = false; +#endif + dp_device_start((dp_link_config_ptr->type == kDPControllerType_EDP) ? true : false); + } + } + +} + +#define USE_F_SEL 1 + + +#if !USE_F_SEL +#define kSlaveClockRetry 200 +#define kSlaveClockStreamValidationCycles 10 +static int validate_video_capture() +{ + int ret = -1; + uint32_t valid = 0; + uint32_t retry = 0; + + while (retry++ < kSlaveClockRetry ) { + uint32_t value; + + spin(5 * 1000); + + value = read_reg(DPTX_SYSTEM_CONTROL_1); + write_reg(DPTX_SYSTEM_CONTROL_1, value); + value = read_reg(DPTX_SYSTEM_CONTROL_1); + if ((value & DPTX_DET_STA) == 0) { + printf("Error! Input stream clock not detected. 0x%08x\n", value); + valid = 0; + continue; + } + + //To check whether input stream clock is stable. + //To do that clear it first. + value = read_reg(DPTX_SYSTEM_CONTROL_2); + write_reg(DPTX_SYSTEM_CONTROL_2, value); + value = read_reg(DPTX_SYSTEM_CONTROL_2); + if (value & DPTX_DET_STA) { + printf("Error! Input stream clock is changing 0x%08x\n", value); + valid = 0; + continue; + } + + value = read_reg(DPTX_SYSTEM_CONTROL_3); + write_reg(DPTX_SYSTEM_CONTROL_3, value); + value = read_reg(DPTX_SYSTEM_CONTROL_3); + if ((value & DPTX_STRM_VALID) == 0) { + printf("Error! Input stream not valid. 0x%08x\n", value); + valid = 0; + continue; + } + + if ( valid++ < kSlaveClockStreamValidationCycles ) + continue; + + ret = 0; + break; + } + + if ( ret ) + printf("Error! Timed out validating video capture. \n"); + else + printf("Validated video capture\n"); + + printf( "ret=0x%08x\n", ret); + + return ret; +} + +int get_link_data_capture_and_compare(struct video_link_data *data) +{ + uint32_t dp_vid_ctl; + int ret = -1; + + //allow enough time 2 frames at least + spin(34 * 1000); + ret = validate_video_capture(); + if (ret != 0) { + printf("validate_video_capture failed\n"); + goto exit; + } + + dp_vid_ctl = read_reg(DPTX_DP_VIDEO_CONTROL); + + uint32_t space = ((dp_vid_ctl & (3<1)) >> 1); + printf("cp space %d tm space %d: %s\n", space, data->color.space, space != data->color.space ? "differ" : "equal"); + uint32_t range = ((dp_vid_ctl & DPTX_DP_VIDEO_CONTROL_D_RANGE_MASK) >> DPTX_DP_VIDEO_CONTROL_D_RANGE_SHIFT); + printf("cp range %d tm range %d: %s\n", range, data->color.range, range != data->color.range ? "differ" : "equal"); + uint32_t coefficient = ((dp_vid_ctl & DPTX_DP_VIDEO_CONTROL_YC_COEFF_MASK) >> DPTX_DP_VIDEO_CONTROL_YC_COEFF_SHIFT); + printf("cp coefficient %d tm coefficient %d: %s\n", coefficient, data->color.coefficient, coefficient != data->color.coefficient ? "differ" : "equal"); + uint32_t depth = (((dp_vid_ctl & DPTX_DP_VIDEO_CONTROL_BPC_MASK) >> DPTX_DP_VIDEO_CONTROL_BPC_SHIFT)); + switch(depth) { + case 0: + depth = 6; + break; + case 1: + depth = 8; + break; + case 2: + depth = 10; + break; + case 3: + depth = 12; + break; + } + printf("cp depth %d tm depth %d: %s\n", depth, data->color.depth, depth != data->color.depth ? "differ" : "equal"); + + uint32_t v_total = read_reg(DPTX_TOTAL_LINE_STATUS); + printf("cp v_total %d tm v_total %d \n", v_total, data->timing.axis[kDisplayAxisTypeVertical].total); + uint32_t v_active = read_reg(DPTX_ACTIVE_LINE_STATUS); + printf("cp v_active %d tm v_active %d \n", v_active, data->timing.axis[kDisplayAxisTypeVertical].active); + uint32_t v_sync_width = read_reg(DPTX_VERTICAL_SYNC_WIDTH_STATUS); + printf("cp v_sync_width %d tm v_sync_width %d \n", v_sync_width, data->timing.axis[kDisplayAxisTypeVertical].sync_width); + uint32_t v_back_porch = read_reg(DPTX_VERTICAL_BACK_PORCH_STATUS); + printf("cp v_back_porch %d tm v_back_porch %d \n", v_back_porch, data->timing.axis[kDisplayAxisTypeVertical].back_porch); + uint32_t v_front_porch = read_reg(DPTX_VERTICAL_FRONT_PORCH_STATUS); + printf("cp v_front_porch %d tm v_front_porch %d \n", v_front_porch, data->timing.axis[kDisplayAxisTypeVertical].front_porch); + uint32_t v_sync_polarity = (read_reg(DPTX_VIDEO_STATUS) & DPTX_VSYNC_P_S) == 0; + printf("cp v_sync_polarity %d tm v_sync_polarity %d \n", v_sync_polarity, data->timing.axis[kDisplayAxisTypeVertical].sync_polarity); + + uint32_t h_total = read_reg(DPTX_TOTAL_PIXEL_STATUS); + printf("cp h_total %d tm h_total %d \n", h_total, data->timing.axis[kDisplayAxisTypeHorizontal].total); + uint32_t h_active = read_reg(DPTX_ACTIVE_PIXEL_STATUS); + printf("cp h_active %d tm h_active %d\n", h_active, data->timing.axis[kDisplayAxisTypeHorizontal].active); + uint32_t h_sync_width = read_reg(DPTX_HORIZON_SYNC_WIDTH_STATUS); + printf("cp h_sync_width %d tm h_sync_width %d\n", h_sync_width, data->timing.axis[kDisplayAxisTypeHorizontal].sync_width); + uint32_t h_back_porch = read_reg(DPTX_HORIZON_BACK_PORCH_STATUS); + printf("cp h_back_porch %d tm h_back_porch %d\n", h_back_porch, data->timing.axis[kDisplayAxisTypeHorizontal].back_porch); + uint32_t h_front_porch = read_reg(DPTX_HORIZON_FRONT_PORCH_STATUS); + printf("cp h_front_porch %d tm h_front_porch %d\n", h_front_porch, data->timing.axis[kDisplayAxisTypeHorizontal].front_porch); + uint32_t h_sync_polarity = (read_reg(DPTX_VIDEO_STATUS) & DPTX_HSYNC_P_S) == 0; + printf("cp h_sync_polarity %d tm h_sync_polarity %d\n", h_sync_polarity, data->timing.axis[kDisplayAxisTypeHorizontal].sync_polarity); + + uint32_t my_mVid = read_reg(DPTX_M_VID_VALUE_MONITOR); + uint32_t my_nVid = (read_reg(DPTX_N_VID_CFG_2) << 16) | (read_reg(DPTX_N_VID_CFG_1) << 8) | (read_reg(DPTX_N_VID_CFG_0) << 0); + + uint32_t my_linkRate; + dp_controller_get_link_rate(&my_linkRate); + + printf("my_nvid %d my_mVid 0x%lx my_linkRate 0x%x\n", my_nVid, my_mVid, my_linkRate); + uint64_t tmp = my_linkRate == 0xa ? 270000000ULL : 162000000ULL; + uint64_t my_streamClk = my_nVid ? ((tmp * my_mVid)/my_nVid) : 0; + + uint32_t totalArea = h_total * v_total; + + uint32_t syncRate = (my_streamClk<<16) / totalArea; + + printf("Timing: syncRate=%d.%d\n", (int)(syncRate >> 16), (int)(((syncRate & 0xffff) * 10000)>>16)); + uint8_t sink_status; + dp_controller_read_bytes_dpcd(0x205, &sink_status, 1); + if (sink_status == 0) + printf("SINK STATUS IS FAILED\n"); + ret = 0; + +exit: + printf("ret=0x%08x\n", ret); + return ret; +} +#endif //USE_F_SEL + +static int configure_video(struct video_link_data *data) +{ + int downstream_type = kDPDownstreamTypeDP; + debug(VIDEO, "starting to configure video\n"); + + if (dp_video_started) return 0; + + // Uncomment to show the timings we finally decide to use. +#if 0 + debug(ALWAYS, "configure_video with:\n"); + debug(ALWAYS, "mirror_mode: %d\n", data->mirror_mode); + debug(ALWAYS, "test_mode: 0x%08x\n", data->test_mode); + debug(ALWAYS, "color:\n"); + debug(ALWAYS, " depth: %u\n", data->color.depth); + debug(ALWAYS, " space: %u\n", data->color.space); + debug(ALWAYS, " range: %u\n", data->color.range); + debug(ALWAYS, " coefficient: %u\n", data->color.coefficient); + debug(ALWAYS, "timing:\n"); + debug(ALWAYS, " interlaced: %d\n", data->timing.interlaced); + { + int i; + for (i = 0; i < kDisplayAxisCount; ++i) { + debug(ALWAYS, " Axis %d:\n", i); + debug(ALWAYS, " total: %u\n", data->timing.axis[i].total); + debug(ALWAYS, " active: %u\n", data->timing.axis[i].active); + debug(ALWAYS, " sync_width: %u\n", data->timing.axis[i].sync_width); + debug(ALWAYS, " back_porch: %u\n", data->timing.axis[i].back_porch); + debug(ALWAYS, " front_porch: %u\n", data->timing.axis[i].front_porch); + debug(ALWAYS, " sync_rate: %u (%uHz)\n", + data->timing.axis[i].sync_rate, data->timing.axis[i].sync_rate >> 16); + debug(ALWAYS, " sync_polarity: %u\n", data->timing.axis[i].sync_polarity); + } + } +#endif + + init_video(); + +#if USE_F_SEL + if ( configure_video_mode(data) != 0 ) + goto exit; +#endif //USE_F_SEL + + if ( configure_video_color(data) != 0 ) + goto exit; + + configure_video_bist(data); + + configure_video_m_n(data); + + //the phy/pll epilogue + lpdp_init_finalize(); + + //Set the PLL lock override bit in display port controller to avoid link controller reset during ALPM + //( LPDP ALPM needs programming F_PLL_LOCK from DP_DEBUG_CONTROL_REGISTER_1 (0x2067006c0)) + or_reg(DPTX_DP_DEBUG_CONTROL_1, DPTX_PLL_LOCK_CTRL | DPTX_F_PLL_LOCK); + +#if WITH_HW_MCU && WITH_HW_DISPLAY_DISPLAYPORT + downstream_type = get_edid_downstream_type(); +#endif + // start video + or_reg(DPTX_VIDEO_CONTROL_1, DPTX_VIDEO_EN); + + or_reg(DPTX_SYSTEM_CONTROL_3, DPTX_VIDEO_SENDING_EN); + +#if !USE_F_SEL + get_link_data_capture_and_compare(data); +#endif + + // Setup InfoFrame + // RY:Please refer to page 65 of the CEA861 spec + // do not send info frames if alpm is supported + if ((downstream_type == kDPDownstreamTypeHDMI) && (!dp_link_config_ptr->alpm)) { + debug(VIDEO, "downstream type is %d and alpm not set. Sending info frames\n", downstream_type); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 0), 0); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 1), 0x08); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 2), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 3), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 4), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 5), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 6), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 7), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 8), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 9), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 10), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 11), 0x00); + write_reg(DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 + (4 * 12), 0x00); + or_reg(DPTX_PACKET_SEND_CONTROL, DPTX_AVI_INFO_UP); + or_reg(DPTX_PACKET_SEND_CONTROL, DPTX_AVI_INFO_EN); + } + + dp_video_started = true; + + debug(VIDEO, "finished configuring video\n"); + + return 0; + +exit: + debug(ERROR, "failed to configure video\n"); + dp_video_started = false; + return -1; +} + +static void disable_video(void) +{ + and_reg(DPTX_SYSTEM_CONTROL_3, ~(DPTX_VIDEO_SENDING_EN)); + + and_reg(DPTX_VIDEO_CONTROL_1, ~DPTX_VIDEO_EN); + + // disable vid capture and vid fifo + or_reg(DPTX_FUNCTION_ENABLE_1, (DPTX_VID_CAP_FUNC_EN_N | DPTX_VID_FIFO_FUNC_EN_N)); +} + +static void init_video() +{ + // configure video + write_reg(DPTX_SYSTEM_CONTROL_1, 0); // clear force_det and det_ctrl + write_reg(DPTX_VIDEO_CONTROL_8, DPTX_VID_HRES_TH(2) | DPTX_VID_VRES_TH(0)); // vid_hres_th and vid_vres_th + write_reg(DPTX_VIDEO_CONTROL_10, 0); + write_reg(DPTX_SYSTEM_CONTROL_2, (0xf << 4)); + +#if DISPLAYPORT_VERSION >= 4 + and_reg(DPTX_VIDEO_CONTROL_10, ~DPTX_F_SEL); + and_reg(DPTX_VIDEO_CONTROL_10, DPTX_F_SEL); +#endif + // enable vid capture and vid fifo + and_reg(DPTX_FUNCTION_ENABLE_1, ~(DPTX_VID_CAP_FUNC_EN_N | DPTX_VID_FIFO_FUNC_EN_N | DPTX_SW_FUNC_EN_N)); +} + +static void configure_video_m_n(struct video_link_data *data) +{ + // using register calcuated M/N + // we are defaulting to operating in master mode + // therefore we are ensuring that async clock + // is being used to calculate M/N + and_reg(DPTX_SYSTEM_CONTROL_4, ~(DPTX_FIX_M_VID)); + write_reg(DPTX_N_VID_CFG_0, 0); + write_reg(DPTX_N_VID_CFG_1, 0x80); + write_reg(DPTX_N_VID_CFG_2, 0); +} + +static int configure_video_color(struct video_link_data *data) +{ + uint32_t val; + + // set video color format + switch (data->color.depth) { + case 12: + val = DPTX_IN_BPC_12_BITS; + break; + case 10: + val = DPTX_IN_BPC_10_BITS; + break; + case 8: + val = DPTX_IN_BPC_8_BITS; + break; + case 6: + val = DPTX_IN_BPC_6_BITS; + break; + default: + return -1; + } + + // Set color range / space + write_reg(DPTX_VIDEO_CONTROL_2, (data->color.range << DPTX_VIDEO_CTL_2_IN_D_RANGE_SHIFT) | + val | + data->color.space); + + // set color coeff + set_bits_in_reg(DPTX_VIDEO_CONTROL_3, DPTX_IN_YC_COEFFI_SHIFT, + DPTX_IN_YC_COEFFI_MASK, data->color.coefficient); + + return 0; +} + +static int configure_video_mode(struct video_link_data *data) +{ + write_reg(DPTX_TOTAL_LINE_CFG, data->timing.axis[kDisplayAxisTypeVertical].total); + write_reg(DPTX_ACTIVE_LINE_CFG, data->timing.axis[kDisplayAxisTypeVertical].active); + + write_reg(DPTX_VERTICAL_FRONT_PORCH_CFG, data->timing.axis[kDisplayAxisTypeVertical].front_porch); + write_reg(DPTX_VERTICAL_SYNC_WIDTH_CFG, data->timing.axis[kDisplayAxisTypeVertical].sync_width); + write_reg(DPTX_VERTICAL_BACK_PORCH_CFG, data->timing.axis[kDisplayAxisTypeVertical].back_porch); + + write_reg(DPTX_TOTAL_PIXEL_CFG, data->timing.axis[kDisplayAxisTypeHorizontal].total); + write_reg(DPTX_ACTIVE_PIXEL_CFG, data->timing.axis[kDisplayAxisTypeHorizontal].active); + write_reg(DPTX_HORIZON_FRONT_PORCH_CFG, data->timing.axis[kDisplayAxisTypeHorizontal].front_porch); + write_reg(DPTX_HORIZON_SYNC_WIDTH_CFG, data->timing.axis[kDisplayAxisTypeHorizontal].sync_width); + write_reg(DPTX_HORIZON_BACK_PORCH_CFG, data->timing.axis[kDisplayAxisTypeHorizontal].back_porch); + + or_reg(DPTX_VIDEO_CONTROL_10, DPTX_F_SEL); + + write_reg(DPTX_THRESHOLD_OF_M_VID_GENERATION_FILTER, 0); // Video Filter Thresold + and_reg(DPTX_DP_M_VID_CALCULATION_CONTROL, ~(1 << 2)); // disable low-pass filter for m-vid + + return 0; +} + +static int validate_video(struct video_link_data *data, uint32_t *m_vid, uint32_t *n_vid) +{ + uint32_t lr; + uint32_t lc; + uint64_t streamClk, maxStreamClk; + uint32_t bpp; + uint32_t vTotalBppPerFrame; + uint64_t maxAvailableVSyncRate; + uint32_t mVid; + uint32_t nVid; + + nVid = 0; + maxStreamClk = 0; + + streamClk = data->timing.axis[kDisplayAxisTypeVertical].total * + data->timing.axis[kDisplayAxisTypeHorizontal].total; + streamClk *= data->timing.axis[kDisplayAxisTypeVertical].sync_rate; // vTotal * hTotal * vSyncRate + streamClk >>= 16; + + bpp = data->color.depth * __s_bpp_coeff[data->color.space]; + + vTotalBppPerFrame = bpp * + data->timing.axis[kDisplayAxisTypeVertical].total * + data->timing.axis[kDisplayAxisTypeHorizontal].total; + + if (vTotalBppPerFrame == 0) { + // Prevent divide-by-zero. + debug(VIDEO, "Frame is zero sized\n"); + return -1; + } + + // if interlaced + if ( data->timing.interlaced ) { + + // XXX tempoorary hack to not support interlaced for the moment + return -1; + + streamClk >>= 1; + vTotalBppPerFrame >>= 1; + } + + debug(VIDEO, "stream clock=%lld\n", streamClk); + + // get link rate and lane count + dp_controller_get_link_rate(&lr); + dp_controller_get_lane_count(&lc); + + if (lc == 0) { + debug(ERROR, "Lane count programmed to zero\n"); + return -1; + } + + switch (lr) { + case kLinkRate270Gbps: + maxAvailableVSyncRate = kLinkRatePhysical_270gps; + break; + case kLinkRate162Gbps: + maxAvailableVSyncRate = kLinkRatePhysical_162gbps; + break; + case kLinkRate324Gbps: + maxAvailableVSyncRate = kLinkRatePhysical_324gps; + break; + default: + debug(ERROR, "Unknown link rate %d\n", lr); + return -1; + } + + maxAvailableVSyncRate /= 10; + maxAvailableVSyncRate *= 8; + maxAvailableVSyncRate *= lc; + maxAvailableVSyncRate /= vTotalBppPerFrame; + + // setup M and N, master mode + switch (lr) { + case kLinkRate270Gbps: + maxStreamClk = kLSClock_171mhz; + nVid = kLSClock_171mhz; + break; + case kLinkRate162Gbps: + maxStreamClk = kLSClock_81mhz; + nVid = kLSClock_81mhz; + break; + case kLinkRate324Gbps: + maxStreamClk = kLSClock_81mhz; + nVid = kLSClock_81mhz; + break; + } + + debug(VIDEO, "max stream clock=%lld\n", maxStreamClk); + + if ( streamClk > maxStreamClk ) { + debug(VIDEO, "stream-clk value is bad, %lld\n", streamClk); + return -1; + } + + mVid = (uint32_t)streamClk; + + debug(VIDEO, "maxAvailableVSyncRate=%lld mVid=%d nVid=%d\n", maxAvailableVSyncRate, mVid,nVid); + + if((uint64_t)data->timing.axis[kDisplayAxisTypeVertical].sync_rate > (maxAvailableVSyncRate<<16)) { + debug(VIDEO, "vsync rate is too high, vSyncRate:%d, maxAvailableVSyncRate:%llu\n", + data->timing.axis[kDisplayAxisTypeVertical].sync_rate, maxAvailableVSyncRate); + return -1; + } + + if ( m_vid ) + *m_vid = mVid; + + if ( n_vid ) + *n_vid = nVid; + + return 0; +} + +static void configure_video_bist(struct video_link_data *data) +{ + // enable bist mode + if ( data->test_mode ) { + write_reg(DPTX_VIDEO_CONTROL_4, DPTX_BIST_EN | (data->test_mode - 1)); + debug(VIDEO, "Finished Video BIST\n"); + } else { + and_reg(DPTX_VIDEO_CONTROL_4, ~(DPTX_BIST_EN)); + } +} + +static int issue_i2c_read_request(uint32_t options, uint32_t address, uint8_t * data, unsigned int length) +{ + //If not end set mot = 1 + uint32_t mot = (options & kI2COptionsTransactionEnd) ? 0 : DPTX_AUX_CH_CTL_1_AUX_TX_COMM_MOT; + uint32_t bytesRead; + int ret; + + if(length > DPTX_BUF_DATA_COUNT) { + ret = -1; + goto exit; + } + + setup_aux_transaction(address, length, mot | DPTX_AUX_CH_CTL_1_AUX_TX_COMM_READ); + + //Clear Buffer + write_reg(DPTX_DP_BUFFER_DATA_COUNT, DPTX_BUF_CLR); + + //Start Aux transaction + ret = commit_aux_transaction(false, false, options & kI2COptionsRetryOnDeferOnly); + if (ret != 0) { + goto exit; + } + + bytesRead = read_reg(DPTX_DP_BUFFER_DATA_COUNT) & DPTX_BUFFER_DATA_COUNT_MASK; + if(bytesRead != length) { + debug(ERROR, "SHORT RX!!! read %d, expecting %d\n", bytesRead, length); + ret = -1; + goto exit; + } + + //Copy out buffer + for (unsigned int i = 0; i < length; i++ ) { + data[i] = read_reg(DPTX_AUX_CH_BUFFER_DATA_0 + (i * sizeof(uint32_t))); + } + +exit: + if ( ret ) + debug(I2C, "ret=0x%08x\n", ret); + + return ret; +} + +static int read_bytes_i2c_internal(uint32_t device_addr, uint32_t addr, u_int8_t *data, uint32_t length) +{ + int ret = 0; + uint32_t offset = 0; + uint32_t attemptCount = 0; + uint32_t maxAttempts = kMaxI2CTransactionRetry + 1; + uint32_t maxBurstLength = kAUXMaxBurstLengthStandard; + int transfer_status = 0; + + debug(I2C, "device_addr=0x%08x addr=0x%08x data=%p length=%d payload=\n", device_addr, addr, + data, length); + + // Since we don't allow any retries on commitAuxTransaction, we should really + // retry on the whole transaction, which includes: start, commmit, and stop + while ( attemptCount++ < maxAttempts ) { + if ( ret != 0 ) { + debug(I2C, "waiting %dus till next attempt\n", kAUXRetryIntervalUS); + task_sleep(kAUXRetryIntervalUS); + } + + ret = issue_i2c_read_request(kI2COptionsTransactionStart, device_addr, NULL, 0); + if ( ret != 0 ) + goto check; + + while (offset < length) { + uint32_t chunk = ulmin(maxBurstLength, (length - offset)); + + debug(I2C, "offset=%d requesting=%d bytes\n", offset, chunk); + + ret = issue_i2c_read_request(kI2COptionsRetryOnDeferOnly, device_addr, data + offset, chunk); + if (ret != 0 ) + goto check; + offset += chunk; + } + +check: + // save transfer status + transfer_status = ret; + + // terminate transaction regardless of transfer errors + ret = issue_i2c_read_request(kI2COptionsTransactionEnd, device_addr, NULL, 0); + + // if stop was successful, use transfer error as return status + ret = transfer_status; + break; + } + + debug(I2C, "result=%d\n", ret); + return ret; +} + +static int wait_for_aux_idle() +{ + uint32_t timeout_time = 20; + while (timeout_time-- && (read_reg(DPTX_AUX_CHANNEL_ACCESS_STATUS) & DPTX_AUX_BUSY)) + task_sleep(50); + return (timeout_time == 0) ? -1 : 0; +} + +static int commit_aux_transaction(bool useInterrupts, bool deferRetryOnly, uint32_t maxRetryCount) +{ + uint32_t attemptCount = 0; + uint32_t maxAttempts = maxRetryCount + 1; + int ret = 0; + + if ( useInterrupts ) { + debug(AUX, "dp_aux_transaction_pending=%d sleeping\n", dp_aux_transaction_pending); + + // sleep on dp_aux_transaction_pending + while( dp_aux_transaction_pending ) + task_yield(); + + debug(AUX, "dp_aux_transaction_pending=%d waking\n", dp_aux_transaction_pending); + + dp_aux_transaction_pending = true; + } + + for ( attemptCount = 0; attemptCount <= maxAttempts; attemptCount ++ ) { + + if ( ret ) { + debug(AUX, "waiting %dus till next attempt\n", kAUXRetryIntervalUS); + task_sleep(kAUXRetryIntervalUS); + } + + ret = wait_for_aux_idle(); + if ( ret != 0 ) { + debug(ERROR, "Timeout waiting for AUX done\n"); + continue; + } + + // enable interrupt + write_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS, DPTX_RPLY_RECEIV | DPTX_AUX_ERR); + or_reg(DPTX_INTERRUPT_ENABLE, DPTX_RPLY_RECEIV| DPTX_AUX_ERR); + + // start aux + or_reg(DPTX_DP_AUX_CH_CONTROL_2, DPTX_AUX_EN); + + dp_aux_transaction_status = kDPAuxTranscationStatus_None; + if ( useInterrupts ) { + debug(AUX, "sleeping on dp_aux_transaction_status\n"); + // sleep on dp_aux_transaction_status + while ( dp_aux_transaction_status == kDPAuxTranscationStatus_None ) + task_yield(); + debug(AUX, "waking on dp_aux_transaction_status\n"); + } + else { + // Wait until interrupt received and aux channel enable auto-clears. + uint32_t int_sta; + for (;;) { + int_sta = read_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS) & (DPTX_RPLY_RECEIV | DPTX_AUX_ERR); + write_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS, int_sta); + if (int_sta != 0 && (read_reg(DPTX_DP_AUX_CH_CONTROL_2) & DPTX_AUX_EN) == 0) + break; +#if WITH_HW_DISPLAY_DISPLAYPORT + if (dp_aux_abort) + return -1; //return error so abort_edid takes effect +#endif + + task_yield(); + } + + if (dp_link_config_ptr->type == kDPControllerType_DP) { + callout_reset(&dp_controller_screensaver_callout, 0); + } + + if (int_sta & DPTX_AUX_ERR) { + uint8_t aux_err = read_reg(DPTX_AUX_CHANNEL_ACCESS_STATUS) & 0xF; + debug(AUX, "AUX_STATUS error: %d\n", aux_err); + + dp_aux_transaction_status = ( aux_err == DPTX_MUCH_DEFER_ERROR ) ? kDPAuxTranscationStatus_IODefer : kDPAuxTranscationStatus_IOError; + + } else { + dp_aux_transaction_status = kDPAuxTranscationStatus_Success; + } + } + + // make sure the aux channel is not busy + ret = wait_for_aux_idle(); + if ( ret != 0 ) { + and_reg(DPTX_DP_AUX_CH_CONTROL_2, ~DPTX_AUX_EN); + debug(ERROR, "Timeout waiting for AUX done\n"); + continue; + } + + debug(AUX, "dp_aux_transaction_status=0x%08x\n", dp_aux_transaction_status); + + ret = dp_aux_transaction_status; + if (ret == kDPAuxTranscationStatus_Success) { + break; + } else if (ret!=kDPAuxTranscationStatus_IODefer && deferRetryOnly ) { + debug(AUX, "Not retrying because error not defer. ret=0x%08x\n", ret); + break; + } + } + + // clear reply receive interrupt + or_reg(DPTX_DISPLAYPORT_INTERRUPT_STATUS, (DPTX_RPLY_RECEIV | DPTX_AUX_ERR)); + and_reg(DPTX_INTERRUPT_ENABLE, ~(DPTX_RPLY_RECEIV | DPTX_AUX_ERR)); + + if ( useInterrupts ) { + dp_aux_transaction_pending = false; + // wake up dp_aux_transaction_pending + debug(AUX, "waking pending dp_aux_transaction_pending\n"); + } + + if ( ret == kDPAuxTranscationStatus_IOError) + debug(AUX, "AUX transaction failed\n"); + + return ret; +} + +static uint32_t read_reg(uint32_t offset) +{ + return(*(volatile uint32_t *)(__base_address + offset)); +} + +static void write_reg(uint32_t offset, uint32_t value) +{ + *(volatile uint32_t *)(__base_address + offset) = value; +} + +static void and_reg(uint32_t offset, uint32_t value) +{ + write_reg(offset, read_reg(offset) & value); +} + +static void or_reg(uint32_t offset, uint32_t value) +{ + write_reg(offset, read_reg(offset) | value); +} + +static void set_bits_in_reg(uint32_t offset, uint32_t pos, uint32_t mask, uint32_t value) +{ + uint32_t set = read_reg(offset); + + set &= ~mask; + set |= (value << pos); + + write_reg(offset, set); +} diff --git a/drivers/analogix/displayport/include/drivers/displayport/displayport.h b/drivers/analogix/displayport/include/drivers/displayport/displayport.h new file mode 100644 index 0000000..26ebc43 --- /dev/null +++ b/drivers/analogix/displayport/include/drivers/displayport/displayport.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef DRIVER_DISPLAYPORT_H +#define DRIVER_DISPLAYPORT_H 1 + +#include +#include + +typedef struct +{ + uint32_t mode : 4; // 3:0 + uint32_t type : 4; // 7:4 + uint32_t min_link_rate : 8; // 15:8 + uint32_t max_link_rate : 8; // 23:16 + uint32_t lanes : 4; // 27:24 + uint32_t ssc : 1; // 28 + uint32_t alpm : 1; // 29 + uint32_t vrr_enable : 1; // 30 + uint32_t vrr_on : 1; // 31 + uint32_t rx_n1; + uint32_t rx_n2; + uint32_t rx_n3; + uint32_t rx_n5; + bool fast_link_training; +} dp_t; + +#endif //DRIVER_DISPLAYPORT_H diff --git a/drivers/analogix/displayport/regs.h b/drivers/analogix/displayport/regs.h new file mode 100644 index 0000000..8bdc714 --- /dev/null +++ b/drivers/analogix/displayport/regs.h @@ -0,0 +1,1480 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _LPDP_REGS_H +#define _LPDP_REGS_H + +#define DPTX_VERSION 0x0010 + +#define DPTX_FUNCTION_ENABLE_1 0x0018 +#define DPTX_VID_CAP_FUNC_EN_N (1 << 6) +#define DPTX_VID_FIFO_FUNC_EN_N (1 << 5) +#define DPTX_LINK_CONTROLLER_RESET (1 << 1) +#define DPTX_SW_FUNC_EN_N (1 << 0) + +#define DPTX_FUNCTION_ENABLE_2 0x001C +#define DPTX_SSC_FUNC_EN_N (1 << 7) +#define DPTX_AUX_FUNC_EN_N (1 << 2) +#define DPTX_SERDES_FIFO_FUNC_EN_N (1 << 1) +#define DPTX_LS_CLK_DOMAIN_FUNC_EN_N (1 << 0) + +#define DPTX_VIDEO_CONTROL_1 0x0020 +#define DPTX_VIDEO_EN (1 << 7) +#define DPTX_VIDEO_MUTE (1 << 6) +#define DPTX_FRAME_CHANGE_EN (1 << 0) + +#define DPTX_VIDEO_CONTROL_2 0x0024 +#define DPTX_VIDEO_CTL_2_IN_D_RANGE_SHIFT 7 +#define DPTX_IN_D_RANGE (1 << 7) +#define DPTX_IN_BPC_12_BITS (3 << 4) +#define DPTX_IN_BPC_10_BITS (2 << 4) +#define DPTX_IN_BPC_8_BITS (1 << 4) +#define DPTX_IN_BPC_6_BITS (0 << 4) +#define DPTX_IN_COLOR_F_YCBCR444 (2 << 0) +#define DPTX_IN_COLOR_F_YCBCR422 (1 << 0) +#define DPTX_IN_COLOR_F_RGB (0 << 0) + +#define DPTX_VIDEO_CONTROL_3 0x0028 +#define DPTX_IN_YC_COEFFI (1 << 7) +#define DPTX_IN_YC_COEFFI_SHIFT (7) +#define DPTX_IN_YC_COEFFI_MASK (1 << 7) +#define DPTX_VID_CHK_UPDATE_TYPE (1 << 4) + +#define DPTX_VIDEO_CONTROL_4 0x002C +#define DPTX_BIST_EN (1 << 3) +#define DPTX_BIST_WIDTH (1 << 2) +#define DPTX_BIST_TYPE(n) ((n) << 0) + +#define DPTX_VIDEO_CONTROL_8 0x003C +#define DPTX_VID_HRES_TH(n) (n << 4) +#define DPTX_VID_VRES_TH(n) (n << 0) + +#define DPTX_VIDEO_CONTROL_10 0x0044 +#define DPTX_F_SEL (1 << 4) +#define DPTX_SLAVE_I_SCAN_CFG (1 << 2) +#define DPTX_SLAVE_VSYNC_P_CFG (1 << 1) +#define DPTX_SLAVE_HSYNC_P_CFG (1 << 0) + +#define DPTX_TOTAL_LINE_CFG 0x0048 + +#define DPTX_ACTIVE_LINE_CFG 0x004C + +#define DPTX_VERTICAL_FRONT_PORCH_CFG 0x0050 +#define DPTX_V_F_PORCH_CFG(n) ((n) << 0) + +#define DPTX_VERTICAL_SYNC_WIDTH_CFG 0x0054 +#define DPTX_V_SYNC_WIDTH_CFG(n) ((n) << 0) + +#define DPTX_VERTICAL_BACK_PORCH_CFG 0x0058 +#define DPTX_V_B_PORCH_CFG(n) ((n) << 0) + +#define DPTX_TOTAL_PIXEL_CFG 0x005C + +#define DPTX_ACTIVE_PIXEL_CFG 0x0060 + +#define DPTX_HORIZON_FRONT_PORCH_CFG 0x0064 +#define DPTX_H_F_PORCH_CFG(n) ((n) << 0) + +#define DPTX_HORIZON_SYNC_WIDTH_CFG 0x0068 +#define DPTX_H_SYNC_CFG(n) ((n) << 0) + +#define DPTX_HORIZON_BACK_PORCH_CFG 0x006C +#define DPTX_H_B_PORCH_CFG(n) ((n) << 0) + +#define DPTX_AUX_LINES_START 0x0070 +#define DPTX_AUX_LINES_END 0x0074 + +#define DPTX_VIDEO_STATUS 0x008C +#define DPTX_FIELD_S (1 << 3) +#define DPTX_I_SCAN_S (1 << 2) +#define DPTX_VSYNC_P_S (1 << 1) +#define DPTX_HSYNC_P_S (1 << 0) + +#define DPTX_TOTAL_LINE_STATUS 0x0090 +#define DPTX_TOTAL_LINE_STA(n) ((n) << 0) + +#define DPTX_ACTIVE_LINE_STATUS 0x0094 +#define DPTX_ACTIVE_LINE_STA(n) ((n) << 0) + +#define DPTX_VERTICAL_FRONT_PORCH_STATUS 0x0098 +#define DPTX_V_F_PORCH_STA(n) ((n) << 0) + +#define DPTX_VERTICAL_SYNC_WIDTH_STATUS 0x009C +#define DPTX_V_SYNC_STA(n) ((n) << 0) + +#define DPTX_VERTICAL_BACK_PORCH_STATUS 0x00A0 +#define DPTX_V_B_PORCH_STA(n) ((n) << 0) + +#define DPTX_TOTAL_PIXEL_STATUS 0x00A4 +#define DPTX_TOTAL_PIXEL_STA(n) ((n) << 0) + +#define DPTX_ACTIVE_PIXEL_STATUS 0x00A8 +#define DPTX_ACTIVE_PIXEL_STA(n) ((n) << 0) + +#define DPTX_HORIZON_FRONT_PORCH_STATUS 0x00AC +#define DPTX_H_F_PORCH_STA(n) ((n) << 0) + +#define DPTX_HORIZON_SYNC_WIDTH_STATUS 0x00B0 +#define DPTX_H_SYNC_STA(n) ((n) << 0) + +#define DPTX_HORIZON_BACK_PORCH_STATUS 0x00B4 +#define DPTX_H_B_PORCH_STA(n) ((n) << 0) + +#define DPTX_ADVANCED_LINK_POWER_MANAGEMENT_CONTROL_1 0x0110 +#define DPTX_ALPM_PARA_UPDATE_EN (1 << 7) +#define DPTX_ALPM_MODE (1 << 6) +#define DPTX_ML_PHY_SLEEP_EN (1 << 5) +#define DPTX_ML_PHY_STANDBY_EN (1 << 4) +#define DPTX_WAKE_F_CHANGE_EN (1 << 3) +#define DPTX_AUX_WAKE_UP_EN (1 << 2) +#define DPTX_WAKE_ACK_STATE (1 << 1) +#define DPTX_PLL_PWRDWN_TIMER_SEL (1 << 0) + +#define DPTX_ADVANCED_LINK_POWER_MANAGEMENT_CONTROL_2 0x0114 +#define DPTX_SEND_SR_OPTION (1 << 6) +#define DPTX_PHY_SLEEP_EN (1 << 5) +#define DPTX_PHY_PLL_PWRDWN_EN (1 << 4) +#define DPTX_AUX_WAKEUP_TO_MAIN_LINK (1 << 3) +#define DPTX_PHY_SLEEP_ASSERT_TIME (1 << 2) +#define DPTX_PLL_PWRDWN_ASSERT_TIME (1 << 1) +#define DPTX_PHY_SLEEP_DEASSERT_TIME (1 << 0) + +#define DPTX_PLL_POWER_DOWN_TO_ML_WAKEUP_TIMER 0x0118 +#define DPTX_PLL_PWD_TO_ML_WAKEUP(n) ((n) << 0) + +#define DPTX_WAIT_AUX_PHY_WAKE_ACK_TIMER 0x011C +#define DPTX_WAIT_WAKE_ACK_TIMER(n) ((n) << 0) + +#define DPTX_WAKEUP_LINES 0x0120 + +#define DPTX_WAKEUP_CR_SYMBOLS 0x0124 + +#define DPTX_SYMBOL_LOCK_PATTERN 0x0130 + +#define DPTX_PLL_POWER_DOWN_TO_ML_WAKEUP_LINES 0x0134 +#define DPTX_PLL_PWD_TO_LINK_LINES(n) ((n) << 0) + +#define DPTX_PLL_POWER_DOWN_TO_ML_WAKEUP_TIME 0x0138 +#define DPTX_PLL_PWD_TO_LINK_TIME(n) ((n) << 0) + +#define DPTX_WAKEUP_F_CHANGE_M_VID_7_0 0x0140 +#define DPTX_WAKEUP_F_CHANGE_M_VID_0(n) ((n) << 0) + +#define DPTX_WAKEUP_F_CHANGE_M_VID_15_8 0x0144 +#define DPTX_WAKEUP_F_CHANGE_M_VID_1(n) ((n) << 0) + +#define DPTX_WAKEUP_F_CHANGE_M_VID_23_16 0x0148 +#define DPTX_WAKEUP_F_CHANGE_M_VID_2(n) ((n) << 0) + +#if DISPLAYPORT_VERSION >= 4 +#define DPTX_SLEEP_STANDBY_DELAY_REG 0x0154 +#define DPTX_SLEEP_STANDBY_DELAY(n) ((n) << 0) +#endif + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_1 0x01D0 +#define DPTX_AVI_DB1(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_2 0x01D4 +#define DPTX_AVI_DB2(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_3 0x01D8 +#define DPTX_AVI_DB3(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_4 0x01DC +#define DPTX_AVI_DB4(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_5 0x01E0 +#define DPTX_AVI_DB5(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_6 0x01E4 +#define DPTX_AVI_DB6(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_7 0x01E8 +#define DPTX_AVI_DB7(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_8 0x01EC +#define DPTX_AVI_DB8(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_9 0x01F0 +#define DPTX_AVI_DB9(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_10 0x01F4 +#define DPTX_AVI_DB10(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_11 0x01F8 +#define DPTX_AVI_DB11(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_12 0x01FC +#define DPTX_AVI_DB12(n) ((n) << 0) + +#define DPTX_AVI_INFOFRAME_PACKET_DATA_BYTE_13 0x0200 +#define DPTX_AVI_DB13(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_TYPE_CODE 0x0244 +#define DPTX_IF_TYPE(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_1 0x0254 +#define DPTX_IF_PKT_DB1(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_2 0x0258 +#define DPTX_IF_PKT_DB2(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_3 0x025C +#define DPTX_IF_PKT_DB3(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_4 0x0260 +#define DPTX_IF_PKT_DB4(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_5 0x0264 +#define DPTX_IF_PKT_DB5(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_6 0x0268 +#define DPTX_IF_PKT_DB6(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_7 0x026C +#define DPTX_IF_PKT_DB7(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_8 0x0270 +#define DPTX_IF_PKT_DB8(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_9 0x0274 +#define DPTX_IF_PKT_DB9(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_10 0x0278 +#define DPTX_IF_PKT_DB10(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_11 0x027C +#define DPTX_IF_PKT_DB11(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_12 0x0280 +#define DPTX_IF_PKT_DB12(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_13 0x0284 +#define DPTX_IF_PKT_DB13(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_14 0x0288 +#define DPTX_IF_PKT_DB14(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_15 0x028C +#define DPTX_IF_PKT_DB15(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_16 0x0290 +#define DPTX_IF_PKT_DB16(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_17 0x0294 +#define DPTX_IF_PKT_DB17(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_18 0x0298 +#define DPTX_IF_PKT_DB18(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_19 0x029C +#define DPTX_IF_PKT_DB19(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_20 0x02A0 +#define DPTX_IF_PKT_DB20(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_21 0x02A4 +#define DPTX_IF_PKT_DB21(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_22 0x02A8 +#define DPTX_IF_PKT_DB22(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_23 0x02AC +#define DPTX_IF_PKT_DB23(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_24 0x02B0 +#define DPTX_IF_PKT_DB24(n) ((n) << 0) + +#define DPTX_INFOFRAME_PACKET_DATA_BYTE_25 0x02B4 +#define DPTX_IF_PKT_DB25(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_1 0x02D0 +#define DPTX_MPEG_DB1(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_2 0x02D4 +#define DPTX_MPEG_DB2(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_3 0x02D8 +#define DPTX_MPEG_DB3(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_4 0x02DC +#define DPTX_MPEG_DB4(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_5 0x02E0 +#define DPTX_MPEG_DB5(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_6 0x02E4 +#define DPTX_MPEG_DB6(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_7 0x02E8 +#define DPTX_MPEG_DB7(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_8 0x02EC +#define DPTX_MPEG_DB8(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_9 0x02F0 +#define DPTX_MPEG_DB9(n) ((n) << 0) + +#define DPTX_MPEG_SOURCE_INFOFRAME_PACKET_DATA_BYTE_10 0x02F4 +#define DPTX_MPEG_DB10(n) ((n) << 0) + +#define DPTX_BIST_AUX_CH_RELATED_REGISTER 0x0390 +#define DPTX_BIST_AUX_AUX_TC_MASK 3 +#define DPTX_BIST_YCBCR422_CONTROL (1 << 5) +#define DPTX_AUX_TC_1us (3 << 3) +#define DPTX_AUX_TC_d999 (2 << 3) +#define DPTX_AUX_TC_d799 (1 << 3) +#define DPTX_AUX_TC_d599 (0 << 3) +#define DPTX_BIST_AUX_AUX_RETRY_TIMER_SHIFT 0 +#define DPTX_BIST_AUX_AUX_RETRY_TIMER_MASK (7 << DPTX_BIST_AUX_AUX_RETRY_TIMER_SHIFT) +#define DPTX_BIST_AUX_AUX_RETRY_TIMER(n) ((n) << 0) + +#define DPTX_INTERRUPT_STATUS 0x03C0 +#define DPTX_INT_STATE (1 << 0) + +#define DPTX_COMMON_INTERRUPT_STATUS_1 0x03C4 +#define DPTX_VSYNC_DET (1 << 7) +#define DPTX_PLL_LOCK_CHG (1 << 6) +#define DPTX_VID_FORMAT_CHG (1 << 3) +#define DPTX_VID_CLK_STABLE (1 << 1) +#define DPTX_SW_INT (1 << 0) + +#define DPTX_COMMON_INTERRUPT_STATUS_4 0x03D0 +#define DPTX_HOTPLUG_CHG (1 << 2) +#define DPTX_HPD_LOST (1 << 1) +#define DPTX_PLUG (1 << 0) + +#define DPTX_DISPLAYPORT_INTERRUPT_STATUS 0x03DC +#define DPTX_INT_HPD (1 << 6) +#define DPTX_HW_TRAINING_FINISH (1 << 5) +#define DPTX_POLLING_ERROR (1 << 4) +#define DPTX_SINK_LOST (1 << 3) +#define DPTX_LINK_LOST (1 << 2) +#define DPTX_RPLY_RECEIV (1 << 1) +#define DPTX_AUX_ERR (1 << 0) + +#define DPTX_INTERRUPT_MASK_1 0x03E0 +#define DPTX_INTERRUPT_MASK_4 0x03EC + +#define DPTX_INTERRUPT_ENABLE 0x03F8 + +#define DPTX_INTERRUPT_CONTROL 0x03FC +#define DPTX_SOFT_INT_CTRL (1 << 2) +#define DPTX_INT_POL_HIGH (1 << 0) +#define DPTX_INT_POL_LOW (0 << 0) + +#define DPTX_SYSTEM_CONTROL_1 0x0600 +#define DPTX_AUX_DEGLITCH_BYPASS (1 << 3) +#define DPTX_DET_STA (1 << 2) +#define DPTX_FORCE_DET (1 << 1) +#define DPTX_DET_CTRL (1 << 0) + +#define DPTX_SYSTEM_CONTROL_2 0x0604 +#define DPTX_CHA_CRI(n) ((n) << 4) +#define DPTX_CHA_STA (1 << 2) +#define DPTX_FORCE_CHA (1 << 1) +#define DPTX_CHA_CTRL (1 << 0) + +#define DPTX_SYSTEM_CONTROL_3 0x0608 +#define DPTX_HPD_POLARITY (1 << 7) +#define DPTX_HPD_STATUS (1 << 6) +#define DPTX_F_HPD (1 << 5) +#define DPTX_HPD_CTRL (1 << 4) +#define DPTX_STRM_VALID (1 << 2) +#define DPTX_VIDEO_SENDING_EN (1 << 1) + +#define DPTX_SYSTEM_CONTROL_4 0x060C +#define DPTX_ENHANCED (1 << 3) +#define DPTX_FIX_M_VID (1 << 2) +#define DPTX_M_VID_UPDATE_CTRL(n) ((n) << 0) + +#define DPTX_DP_VIDEO_CONTROL 0x0610 +#define DPTX_YC_COEFF (1 << 4) +#define DPTX_D_RANGE (1 << 3) +#define DPTX_DP_VIDEO_CONTROL_BPC_SHIFT 5 +#define DPTX_DP_VIDEO_CONTROL_BPC_MASK (0x7< +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Cache control + */ +void +a5iop_cache_operation(int operation, void *address, u_int32_t length) +{ + uint32_t actual_base, lines, extra; + + if (unlikely(length == 0)) { + enter_critical_section(); + if (operation & CACHE_CLEAN) + arm_clean_dcache(); + if (operation & CACHE_INVALIDATE) + arm_invalidate_dcache(); + exit_critical_section(); + + /* on the panic path, disable the cache? XXX */ + if (operation & CACHE_PANIC) { } + } else { + actual_base = (uint32_t)address; + ASSERT((actual_base & ~(CPU_CACHELINE_SIZE-1)) == actual_base); + ASSERT((length % CPU_CACHELINE_SIZE) == 0); + + lines = length >> CPU_CACHELINE_SHIFT; + ASSERT(lines > 0); + + extra = lines & 7; + lines -= extra; + + /* perform loop unrolling to optimize multi-line operations rdar://problem/6722268 */ + if (operation & (CACHE_CLEAN | CACHE_INVALIDATE)) { + switch (extra) { + case 0: + break; + case 1: + arm_clean_invalidate_dcache_line(actual_base); + break; + case 2: + arm_clean_invalidate_dcache_line_2(actual_base); + break; + case 3: + arm_clean_invalidate_dcache_line_3(actual_base); + break; + case 4: + arm_clean_invalidate_dcache_line_4(actual_base); + break; + case 5: + arm_clean_invalidate_dcache_line_5(actual_base); + break; + case 6: + arm_clean_invalidate_dcache_line_6(actual_base); + break; + case 7: + arm_clean_invalidate_dcache_line_7(actual_base); + break; + } + actual_base += CPU_CACHELINE_SIZE * extra; + + while (lines) { + arm_clean_invalidate_dcache_line_8(actual_base); + lines -= 8; + actual_base += CPU_CACHELINE_SIZE * 8; + } + } else if (operation & CACHE_CLEAN) { + switch (extra) { + case 0: + break; + case 1: + arm_clean_dcache_line(actual_base); + break; + case 2: + arm_clean_dcache_line_2(actual_base); + break; + case 3: + arm_clean_dcache_line_3(actual_base); + break; + case 4: + arm_clean_dcache_line_4(actual_base); + break; + case 5: + arm_clean_dcache_line_5(actual_base); + break; + case 6: + arm_clean_dcache_line_6(actual_base); + break; + case 7: + arm_clean_dcache_line_7(actual_base); + break; + } + actual_base += CPU_CACHELINE_SIZE * extra; + + while (lines) { + arm_clean_dcache_line_8(actual_base); + lines -= 8; + actual_base += CPU_CACHELINE_SIZE * 8; + } + } else {// operation & CACHE_INVALIDATE + switch (extra) { + case 0: + break; + case 1: + arm_invalidate_dcache_line(actual_base); + break; + case 2: + arm_invalidate_dcache_line_2(actual_base); + break; + case 3: + arm_invalidate_dcache_line_3(actual_base); + break; + case 4: + arm_invalidate_dcache_line_4(actual_base); + break; + case 5: + arm_invalidate_dcache_line_5(actual_base); + break; + case 6: + arm_invalidate_dcache_line_6(actual_base); + break; + case 7: + arm_invalidate_dcache_line_7(actual_base); + break; + } + actual_base += CPU_CACHELINE_SIZE * extra; + + while (lines) { + arm_invalidate_dcache_line_8(actual_base); + lines -= 8; + actual_base += CPU_CACHELINE_SIZE * 8; + } + } + } +} + +#if SUPPORT_SLEEP +static struct task *sleeping_task; +static u_int32_t idle_sleep; +static u_int32_t powergate_cnt, powerwake_cnt, powerfall_cnt; +static u_int32_t suspend_cnt, wake_cnt; +static u_int64_t sleep_stamp, wake_stamp; +extern u_int32_t arch_sleep_magic; + +void +a5iop_sleep(u_int32_t going_idle) +{ + idle_sleep = going_idle; + if (idle_sleep) + powergate_cnt++; + else + suspend_cnt++; + + /* disable interrupts; this is matched in the wake path */ + enter_critical_section(); + + /* we are the sleeping task */ + sleeping_task = task_get_current_task(); + + sleep_stamp = timer_get_ticks(); + + /* fool the upcoming test on the sleep path */ + arch_sleep_magic = SLEEP_MAGIC_NOT_ASLEEP; + + /* save our current context - on wake we will return from this call */ + arch_task_context_switch(&sleeping_task->arch, &sleeping_task->arch); + + /* if we are on the wake path, go back */ + if (SLEEP_MAGIC_WAKEY_WAKEY == arch_sleep_magic) { + RELEASE_ASSERT(powergate_cnt == powerfall_cnt + powerwake_cnt); + RELEASE_ASSERT(suspend_cnt == wake_cnt); + return; + } + + /* flip the switch and wait for us to go to sleep */ + arch_sleep_magic = SLEEP_MAGIC_WAKEY_WAKEY; + + /* Flush and invalidate the the entire dcache + * Don't call a5iop_cache_operation directly because the + * irq_disable count won't get flushed */ + arm_clean_dcache(); + + /* Use WFI to fully quiesce */ + arch_halt(); + + if (idle_sleep) { + /* It's possible to fall through the WFI without + * power-gating, so carry on in that case. */ + powerfall_cnt++; + exit_critical_section(); + } else { + /* On the sleep/suspend path, it's not acceptible to + * return from this routine. We don't expect to fall + * through the WFI but better safe than sorry. */ + while (1) arch_halt(); + } +} + +void +platform_wakeup(void) +{ + /* Reestablish the correct CPU configuration */ + arch_cpu_init(true); + + wake_stamp = timer_get_ticks(); + + if (idle_sleep) { + /* Waking from idle power-gating; timer and interrupt + * state is intact; we just need to pop a level of IRQ + * disable and start running. */ + powerwake_cnt++; + exit_critical_section(); + } else { + wake_cnt++; + platform_early_init(); + } + /* There should be a better abstracted way to enable NMI */ + arm_enable_fiqs(); + + /* kick the callout system to re-evaluate deadlines */ + callout_reset_deadline(); + + /* and switch back to the context that went to sleep */ + arch_task_context_restore(&sleeping_task->arch); + + panic("arch_task_context_restore didn't"); +} + +#endif /* SUPPORT_SLEEP */ diff --git a/drivers/apple/a5iop/include/drivers/a5iop/a5iop.h b/drivers/apple/a5iop/include/drivers/a5iop/a5iop.h new file mode 100644 index 0000000..c3f803a --- /dev/null +++ b/drivers/apple/a5iop/include/drivers/a5iop/a5iop.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __A5IOP_H +#define __A5IOP_H + +#include + +__BEGIN_DECLS + +extern void a5iop_init(void); +extern void a5iop_cache_operation(int operation, void *address, u_int32_t length); +extern void a5iop_sleep(u_int32_t going_idle); + +__END_DECLS + +#endif diff --git a/drivers/apple/a5iop/rules.mk b/drivers/apple/a5iop/rules.mk new file mode 100644 index 0000000..53cc3f6 --- /dev/null +++ b/drivers/apple/a5iop/rules.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += $(LOCAL_DIR)/a5iop.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/a7iop/a7iop.c b/drivers/apple/a7iop/a7iop.c new file mode 100644 index 0000000..c9ed687 --- /dev/null +++ b/drivers/apple/a7iop/a7iop.c @@ -0,0 +1,425 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define low_bits(x) ((x) & 0x00000000ffffffffULL) +#define high_bits(x) (((x) & 0xffffffff00000000ULL) >> 32) + +#define MAX_CLOCKS (2) + +static int32_t _akf_init(const KFWRAPPER_TYPE_T kfw_type); +static void _akf_recv_mbox_nonempty_int_handler(void *arg); +static void _akf_send_mbox_empty_int_handler(void *arg); +static void _akf_set_timebase(addr_t regs_base); + +// KFWrappers are indexed by types defined in enum table +static struct akf_wrapper { + uint64_t base; + uint32_t clock_idx[MAX_CLOCKS]; + uint32_t inbox_int; + uint32_t outbox_int; + struct task_event recv_mbox_wait_event; + struct task_event send_mbox_wait_event; + bool set_iop_timebase; +} _akf_wrappers[] = { +#ifdef ANS_AKF_BASE_ADDR +#ifdef WITH_ANS_DLL + [KFW_ANS] = { .base = ANS_AKF_BASE_ADDR, + .clock_idx = { CLK_ANS, CLK_ANS_DLL }, + .inbox_int = INT_ANS_KF_INBOX_EMPTY, + .outbox_int = INT_ANS_KF_OUTBOX_NOTEMPTY, + .set_iop_timebase = true + }, +#else + [KFW_ANS] = { .base = ANS_AKF_BASE_ADDR, + .clock_idx = { CLK_ANS, UINT32_MAX }, + .inbox_int = INT_ANS_KF_INBOX_EMPTY, + .outbox_int = INT_ANS_KF_OUTBOX_NOTEMPTY, + .set_iop_timebase = true + }, +#endif +#else + [KFW_ANS] = { .base = UINT64_MAX, + .clock_idx = { UINT32_MAX }, + .inbox_int = UINT32_MAX, + .outbox_int = UINT32_MAX, + .set_iop_timebase = false + }, +#endif +#ifdef ASIO_AKF_BASE_ADDR + [KFW_SIO] = { .base = ASIO_AKF_BASE_ADDR, + .clock_idx = { CLK_SIO, CLK_SIO_P }, + .inbox_int = INT_SIO_KF_INBOX_EMPTY, + .outbox_int = INT_SIO_KF_OUTBOX_NOTEMPTY, + .set_iop_timebase = false + }, +#else + [KFW_SIO] = { .base = UINT64_MAX, + .clock_idx = { UINT32_MAX }, + .inbox_int = UINT32_MAX, + .outbox_int = UINT32_MAX, + .set_iop_timebase = false + }, +#endif +#ifdef ASEP_AKF_BASE_ADDR + [KFW_SEP] = { .base = ASEP_AKF_BASE_ADDR, + .clock_idx = { UINT32_MAX, UINT32_MAX }, + .inbox_int = INT_SEP_KF_INBOX_EMPTY, + .outbox_int = INT_SEP_KF_OUTBOX_NOTEMPTY + }, +#else + [KFW_SEP] = { .base = UINT64_MAX, + .clock_idx = { UINT32_MAX }, + .inbox_int = UINT32_MAX, + .outbox_int = UINT32_MAX, + .set_iop_timebase = false + }, +#endif +}; + +/* + * akf_start + * + * Initialize KFWrapper (clocks, interrupts), sets up remap window, + * Enable FIFOs, and boot KF core. + * It assumes firmware address is aligned, and memory allocated is contiguous. + * + */ +int32_t akf_start(const KFWRAPPER_TYPE_T kfw_type, const addr_t firmware_address, const uint64_t firmware_size) +{ + addr_t fw_phy_addr; + addr_t akf_base; + uint32_t i; + + akf_base = _akf_wrappers[kfw_type].base; + ASSERT(akf_base != 0); + + // register for interrupts + install_int_handler(_akf_wrappers[kfw_type].outbox_int, _akf_recv_mbox_nonempty_int_handler, (void *)kfw_type); + install_int_handler(_akf_wrappers[kfw_type].inbox_int, _akf_send_mbox_empty_int_handler, (void *)kfw_type); + + // initialize wait events + event_init(&_akf_wrappers[kfw_type].recv_mbox_wait_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(&_akf_wrappers[kfw_type].send_mbox_wait_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + // enable clock and power + for (i = 0; i < MAX_CLOCKS; i++) { + if (_akf_wrappers[kfw_type].clock_idx[i] == UINT32_MAX) + break; + clock_gate(_akf_wrappers[kfw_type].clock_idx[i], true); + } + + // mask all the interrupts + rAKF_AP_MAILBOX_SET(akf_base) = AKF_MAILBOX_O_NONEMPTY_MSK | AKF_MAILBOX_O_EMPTY_MSK | + AKF_MAILBOX_I_NONEMPTY_MSK | AKF_MAILBOX_I_EMPTY_MSK; + + // setup remap + rAKF_AXI_START(akf_base) = 0; + rAKF_AXI_START_EXT(akf_base) = 0; + + rAKF_AXI_END(akf_base) = (uint32_t)(low_bits(firmware_size)); + rAKF_AXI_END_EXT(akf_base) = (uint32_t)(high_bits(firmware_size)); + + fw_phy_addr = mem_static_map_physical(firmware_address); + + rAKF_AXI_BASE(akf_base) = (uint32_t)(low_bits(fw_phy_addr)); + rAKF_AXI_BASE_EXT(akf_base) = (uint32_t)(high_bits(fw_phy_addr)); + + // enable FIFOs + rAKF_AP_INBOX_CTRL(akf_base) |= AKF_AP_INBOX_CTRL_ENABLE; + rAKF_AP_OUTBOX_CTRL(akf_base) |= AKF_AP_OUTBOX_CTRL_ENABLE; + +#if AKF_VERSION == 2 + rAKF_KIC_MAILBOX_EXT_CLR(akf_base) = 0x1111; +#endif + // if appropriate, set IOP timebase to be close to and in sync with local timebase (from aic), + if (_akf_wrappers[kfw_type].set_iop_timebase) { + _akf_set_timebase(akf_base); + } + + // set run bit + rAKF_CPU_CTRL(akf_base) = AKF_CPU_CTRL_RUN; + + // let interrupt flow + unmask_int(_akf_wrappers[kfw_type].outbox_int); + unmask_int(_akf_wrappers[kfw_type].inbox_int); + + return 0; +} + +/* + * akf_start_sep + * + * SEP needs special handling. + * Register and enables interrupts, enable fifos + * + */ +int32_t akf_start_sep(void) +{ + // register for interrupts + install_int_handler(_akf_wrappers[KFW_SEP].outbox_int, _akf_recv_mbox_nonempty_int_handler, (void *)KFW_SEP); + install_int_handler(_akf_wrappers[KFW_SEP].inbox_int, _akf_send_mbox_empty_int_handler, (void *)KFW_SEP); + + // initialize wait events + event_init(&_akf_wrappers[KFW_SEP].recv_mbox_wait_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(&_akf_wrappers[KFW_SEP].send_mbox_wait_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + // mask all the interrupts + rAKF_AP_MAILBOX_SET(_akf_wrappers[KFW_SEP].base) = AKF_MAILBOX_O_NONEMPTY_MSK | AKF_MAILBOX_O_EMPTY_MSK | + AKF_MAILBOX_I_NONEMPTY_MSK | AKF_MAILBOX_I_EMPTY_MSK; + + // enable FIFOs + rAKF_AP_INBOX_CTRL(_akf_wrappers[KFW_SEP].base) |= AKF_AP_INBOX_CTRL_ENABLE; + rAKF_AP_OUTBOX_CTRL(_akf_wrappers[KFW_SEP].base) |= AKF_AP_OUTBOX_CTRL_ENABLE; + + // let interrupt flow + unmask_int(_akf_wrappers[KFW_SEP].outbox_int); + unmask_int(_akf_wrappers[KFW_SEP].inbox_int); + + return 0; +} + +/* + * akf_recv_mbox + * + * Fetch a message from outbound mailbox. + * If there are no messages in outbox, outbox-non-empty interrupt will be enabled. + * If wait_timeout is UINT32_MAX, driver will wait for ever for a message + * 0: success, -1: outbox empty, -2: timed out + * + */ +int32_t akf_recv_mbox(const KFWRAPPER_TYPE_T kfw_type, uint64_t *msg, uint32_t wait_timeout) +{ + int32_t ret; + addr_t akf_base; + + akf_base = _akf_wrappers[kfw_type].base; + ASSERT(akf_base != 0); + + ret = 0; + enter_critical_section(); + + while (rAKF_AP_OUTBOX_CTRL(akf_base) & AKF_AP_OUTBOX_CTRL_EMPTY) { + if (!wait_timeout) { + ret = -1; + goto exit; + } + + rAKF_AP_MAILBOX_CLR(akf_base) = AKF_MAILBOX_O_NONEMPTY_MSK; + if (wait_timeout == UINT32_MAX) { + event_wait(&_akf_wrappers[kfw_type].recv_mbox_wait_event); + } + else { + // XXX recompute wait timeout here? + if (event_wait_timeout(&_akf_wrappers[kfw_type].recv_mbox_wait_event, wait_timeout) == false) { + ret = -2; + goto exit; + } + } + } + + // assert for over-flow and under-flow errors + RELEASE_ASSERT((rAKF_AP_OUTBOX_CTRL(akf_base) & (AKF_AP_OUTBOX_CTRL_UDFL | AKF_AP_OUTBOX_CTRL_OVFL)) == 0); + + *msg = akf_read_ap_outbox(akf_base); + +exit: + exit_critical_section(); + return ret; +} + +/* + * akf_send_mbox + * + * Send a message to inbound mailbox. + * If there is no space in the inbox, inbox-empty interrupt will be enabled. + * If wait_timeout is UINT32_MAX, driver will wait for ever for space in the mailbox to stuff a new message. + * 0: success, -1: inbox full, -2: timed out + * + */ +int32_t akf_send_mbox(const KFWRAPPER_TYPE_T kfw_type, const uint64_t msg, uint32_t wait_timeout) +{ + int32_t ret; + addr_t akf_base; + + akf_base = _akf_wrappers[kfw_type].base; + ASSERT(akf_base != 0); + + ret = 0; + enter_critical_section(); + + while (rAKF_AP_INBOX_CTRL(akf_base) & AKF_AP_INBOX_CTRL_FULL) { + if (!wait_timeout) { + ret = -1; + goto exit; + } + + rAKF_AP_MAILBOX_CLR(akf_base) = AKF_MAILBOX_I_EMPTY_MSK; + if (wait_timeout == UINT32_MAX) { + event_wait(&_akf_wrappers[kfw_type].send_mbox_wait_event); + } + else { + // XXX recompute wait timeout here? + if (event_wait_timeout(&_akf_wrappers[kfw_type].send_mbox_wait_event, wait_timeout) == false) { + ret = -2; + goto exit; + } + } + } + + // assert for over-flow and under-flow errors + RELEASE_ASSERT((rAKF_AP_INBOX_CTRL(akf_base) & (AKF_AP_INBOX_CTRL_UDFL | AKF_AP_INBOX_CTRL_OVFL)) == 0); + + akf_write_ap_inbox(akf_base, msg); + +exit: + exit_critical_section(); + return ret; +} + +/* + * akf_send_nmi + * + * Sends NMI to the KF core. + * KF Timer1 is used for generating FIQ NMI. It setups up FIQ Software source. + * + */ +int32_t akf_send_nmi(const KFWRAPPER_TYPE_T kfw_type) +{ + addr_t akf_base; + + akf_base = _akf_wrappers[kfw_type].base; + ASSERT(akf_base != 0); + + if ((rAKF_KIC_TMR_CFG1(akf_base) & AKF_KIC_TMR_CFG_NMI) == 0) { + dprintf(DEBUG_INFO, "akf_send_nmi: KIC_TMR_CFG1 not configured for NMI\n"); + return -1; + } + + rAKF_KIC_TMR_STATE_SET1(akf_base) = AKF_KIC_TMR_STATE_SET_SGT; + + return 0; +} + +/* + * akf_stop + * + * Stops the KF core, mask all FIFO interrupts + * Book-keeping related to shutdown (quiesce clocks, uninstall interrupt handler, clears remap window) + * + */ +int32_t akf_stop(const KFWRAPPER_TYPE_T kfw_type) +{ + addr_t akf_base; + uint32_t i; + + akf_base = _akf_wrappers[kfw_type].base; + ASSERT(akf_base != 0); + + enter_critical_section(); + + // mask interrupts + mask_int(_akf_wrappers[kfw_type].outbox_int); + mask_int(_akf_wrappers[kfw_type].inbox_int); + + // XXX clear any pending interrupts? + + // disable FIFOs + rAKF_AP_INBOX_CTRL(akf_base) = (rAKF_AP_INBOX_CTRL(akf_base) & ~AKF_AP_INBOX_CTRL_ENABLE); + rAKF_AP_OUTBOX_CTRL(akf_base) = (rAKF_AP_OUTBOX_CTRL(akf_base) & ~AKF_AP_OUTBOX_CTRL_ENABLE); + + // SEP: special handling, clean local states + if (kfw_type == KFW_SEP) + goto done; + + // at this time, KF should be idle (not generating any transactions to fabric) + + // stop KF and keep it in reset + rAKF_CPU_CTRL(akf_base) = (rAKF_CPU_CTRL(akf_base) & ~AKF_CPU_CTRL_RUN); + + // clear remap registers + rAKF_AXI_START(akf_base) = 0; + rAKF_AXI_START_EXT(akf_base) = 0; + + rAKF_AXI_END(akf_base) = 0; + rAKF_AXI_END_EXT(akf_base) = 0; + + rAKF_AXI_BASE(akf_base) = 0; + rAKF_AXI_BASE_EXT(akf_base) = 0; + + // disable clock and power, clock_gate calls takes care of both + for (i = 0; i < MAX_CLOCKS; i++) { + if (_akf_wrappers[kfw_type].clock_idx[i] == UINT32_MAX) + break; + clock_gate(_akf_wrappers[kfw_type].clock_idx[i], false); + } + +done: + exit_critical_section(); + + return 0; +} + +static void _akf_recv_mbox_nonempty_int_handler(void *arg) +{ + KFWRAPPER_TYPE_T kfw_type = (KFWRAPPER_TYPE_T)arg; + + RELEASE_ASSERT(kfw_type < KFW_TYPE_MAX); + ASSERT(_akf_wrappers[kfw_type].base != 0); + + rAKF_AP_MAILBOX_SET(_akf_wrappers[kfw_type].base) = AKF_MAILBOX_O_NONEMPTY_MSK; + // NOTE: this akf reg access will ensure that interrupt mask operation above + // will complete before exiting interrupt handling - the read result is unimportant + (void)rAKF_AP_INBOX_CTRL(_akf_wrappers[kfw_type].base); + + event_signal(&_akf_wrappers[kfw_type].recv_mbox_wait_event); +} + +static void _akf_send_mbox_empty_int_handler(void *arg) +{ + KFWRAPPER_TYPE_T kfw_type = (KFWRAPPER_TYPE_T)arg; + + RELEASE_ASSERT(kfw_type < KFW_TYPE_MAX); + ASSERT(_akf_wrappers[kfw_type].base != 0); + + rAKF_AP_MAILBOX_SET(_akf_wrappers[kfw_type].base) = AKF_MAILBOX_I_EMPTY_MSK; + // NOTE: this akf reg access will ensure that interrupt mask operation above + // will complete before exiting interrupt handling - the read result is unimportant + (void)rAKF_AP_INBOX_CTRL(_akf_wrappers[kfw_type].base); + + event_signal(&_akf_wrappers[kfw_type].send_mbox_wait_event); +} + + +static void _akf_set_timebase(addr_t regs_base) +{ + uint32_t reg_value; + uint64_t now; + + reg_value = rAKF_KIC_GLB_CFG(regs_base); + + enter_critical_section(); + rAKF_KIC_GLB_CFG(regs_base) = (reg_value & ~AKF_KIC_GLB_CFG_TEN); + now = timer_get_ticks(); + rAKF_KIC_GLB_TIME_BASE_LO(regs_base) = (uint32_t)now; + rAKF_KIC_GLB_TIME_BASE_HI(regs_base) = (uint32_t)(now>>32); + rAKF_KIC_GLB_CFG(regs_base) = (reg_value | AKF_KIC_GLB_CFG_TEN); + exit_critical_section(); +} diff --git a/drivers/apple/a7iop/a7iop_debug.c b/drivers/apple/a7iop/a7iop_debug.c new file mode 100644 index 0000000..2945596 --- /dev/null +++ b/drivers/apple/a7iop/a7iop_debug.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +static int _a7iop_debug_main(int argc, struct cmd_arg *args); +static int _a7iop_debug_start_kf(KFWRAPPER_TYPE_T type); +static int _a7iop_debug_stop_kf(KFWRAPPER_TYPE_T type); + +MENU_COMMAND_DEBUG(a7iop_test, _a7iop_debug_main, "Test A7IOP interface", NULL); + +static int _a7iop_debug_main(int argc, struct cmd_arg *args) { + const char *s; + KFWRAPPER_TYPE_T type; + + if (argc < 3) { + goto print_usage; + } + + s = args[1].str; + if (strcmp(s, "ans") == 0) { + type = KFW_ANS; + } + else if (strcmp(s, "sio") == 0) { + type = KFW_SIO; + } + else if (strcmp(s, "sep") == 0) { + type = KFW_SEP; + } else { + goto print_usage; + } + + s = args[2].str; + if (strcmp(s, "start") == 0) { + return _a7iop_debug_start_kf(type); + } + else if (strcmp(s, "stop") == 0) { + return _a7iop_debug_stop_kf(type); + } else { + goto print_usage; + } + +print_usage: + printf("Usage: "); + printf("a7iop_test [ans/sio/sep] [start/stop]\n"); + return -1; +} + +static int _a7iop_debug_start_kf(KFWRAPPER_TYPE_T type) +{ + addr_t fw_base; + uint32_t code[] = { 0xe3a00000, 0xe3a01001, 0xe3a02002, 0xe3a03003, 0xe3a04004, 0xe320f003 }; + + fw_base = (addr_t)DEFAULT_LOAD_ADDRESS; + bcopy((void *)code, (void *)fw_base, sizeof(code)); + + akf_start(type, fw_base, sizeof(code)); + + return 0; +} + +static int _a7iop_debug_stop_kf(KFWRAPPER_TYPE_T type) +{ + akf_stop(type); + + return 0; +} + +#endif // defined(WITH_MENU) && WITH_MENU diff --git a/drivers/apple/a7iop/include/drivers/a7iop/a7iop.h b/drivers/apple/a7iop/include/drivers/a7iop/a7iop.h new file mode 100644 index 0000000..1b22933 --- /dev/null +++ b/drivers/apple/a7iop/include/drivers/a7iop/a7iop.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _APPLE_A7IOP_H +#define _APPLE_A7IOP_H + +#include +#include + +/******************************************* + * KFWrappers + * +********************************************/ +typedef enum { + KFW_ANS = 0, + KFW_SIO, + KFW_SEP, + KFW_TYPE_MAX, +} KFWRAPPER_TYPE_T; + +#define A7IOP_WAIT_FOREVER (UINT32_MAX) +#define A7IOP_NO_WAIT (0) + +/******************************************* + * A7IOP interface + * +********************************************/ + +int32_t akf_start(const KFWRAPPER_TYPE_T kfw_type, const addr_t firmware_address, const uint64_t firmware_size); +int32_t akf_start_sep(void); +int32_t akf_send_mbox(const KFWRAPPER_TYPE_T kfw_type, const uint64_t msg, uint32_t wait_timeout) __attribute__((warn_unused_result)); +int32_t akf_recv_mbox(const KFWRAPPER_TYPE_T kfw_type, uint64_t *msg, uint32_t wait_timeout) __attribute__((warn_unused_result)); +int32_t akf_send_nmi(const KFWRAPPER_TYPE_T kfw_type); +int32_t akf_stop(const KFWRAPPER_TYPE_T kfw_type); + + +/******************************************* + * KFWrapper registers + * + * Below are offsets, and bit definitions + * + ********************************************/ + +#if AKF_VERSION == 1 + +#define AKF_STRIDE (0x1000) + +#define rAKF_AXI_BASE(_b) (*(volatile uint32_t *)((_b) + 0x0008)) +#define rAKF_AXI_BASE_EXT(_b) (*(volatile uint32_t *)((_b) + 0x000C)) + +#define rAKF_AXI_START(_b) (*(volatile uint32_t *)((_b) + 0x0010)) +#define rAKF_AXI_START_EXT(_b) (*(volatile uint32_t *)((_b) + 0x0014)) + +#define rAKF_AXI_END(_b) (*(volatile uint32_t *)((_b) + 0x0018)) +#define rAKF_AXI_END_EXT(_b) (*(volatile uint32_t *)((_b) + 0x001C)) + +#define rAKF_CPU_CTRL(_b) (*(volatile uint32_t *)((_b) + 0x0028)) + +#define rAKF_KIC_GLB_TIME_BASE_LO(_b) (*(volatile uint32_t *)((_b) + 0x0810)) +#define rAKF_KIC_GLB_TIME_BASE_HI(_b) (*(volatile uint32_t *)((_b) + 0x0818)) + +#define rAKF_KIC_TMR_CFG1(_b) (*(volatile uint32_t *)((_b) + 0x0884)) + +#define rAKF_KIC_TMR_STATE_SET1(_b) (*(volatile uint32_t *)((_b) + 0x08A4)) + +#elif AKF_VERSION == 2 + +#define AKF_STRIDE (0x4000) + +#define rAKF_AXI_BASE(_b) (*(volatile uint32_t *)((_b) + 0x0008)) +#define rAKF_AXI_BASE_EXT(_b) (*(volatile uint32_t *)((_b) + 0x0010)) + +#define rAKF_AXI_START(_b) (*(volatile uint32_t *)((_b) + 0x0018)) +#define rAKF_AXI_START_EXT(_b) (*(volatile uint32_t *)((_b) + 0x0020)) + +#define rAKF_AXI_END(_b) (*(volatile uint32_t *)((_b) + 0x0028)) +#define rAKF_AXI_END_EXT(_b) (*(volatile uint32_t *)((_b) + 0x0030)) + +#define rAKF_CPU_CTRL(_b) (*(volatile uint32_t *)((_b) + 0x0044)) + +#define rAKF_KIC_MAILBOX_EXT_SET(_b) (*(volatile uint32_t *)((_b) + 0x0c00)) +#define rAKF_KIC_MAILBOX_EXT_CLR(_b) (*(volatile uint32_t *)((_b) + 0x0c04)) + +#define rAKF_KIC_GLB_TIME_BASE_LO(_b) (*(volatile uint32_t *)((_b) + 0xc030)) +#define rAKF_KIC_GLB_TIME_BASE_HI(_b) (*(volatile uint32_t *)((_b) + 0xc038)) + +#define rAKF_KIC_TMR_CFG1(_b) (*(volatile uint32_t *)((_b) + 0xc000)) + +#define rAKF_KIC_TMR_STATE_SET1(_b) (*(volatile uint32_t *)((_b) + 0xc020)) + +#else +#error "Invalid or no AKF_VERSION" +// shut up additional errors +#define AKF_STRIDE (0) +#endif + +#define AKF_CPU_CTRL_RUN (1<<4) + +#define rAKF_KIC_GLB_CFG(_b) (*(volatile uint32_t *)((_b) + 0x080c)) +#define AKF_KIC_GLB_CFG_TEN (1<<1) + +#define AKF_KIC_TMR_CFG_FSL_TIMER (0 << 4) +#define AKF_KIC_TMR_CFG_FSL_SW (1 << 4) +#define AKF_KIC_TMR_CFG_FSL_EXTERNAL (2 << 4) +#define AKF_KIC_TMR_CFG_SMD_FIQ (0<<3) +#define AKF_KIC_TMR_CFG_SMD_IRQ (1<<3) +#define AKF_KIC_TMR_CFG_EMD_IRQ (1<<2) +#define AKF_KIC_TMR_CFG_IMD_FIQ (0<<1) +#define AKF_KIC_TMR_CFG_IMD_IRQ (1<<1) +#define AKF_KIC_TMR_CFG_EN (1<<0) +#define AKF_KIC_TMR_CFG_NMI (AKF_KIC_TMR_CFG_FSL_SW | AKF_KIC_TMR_CFG_SMD_FIQ | AKF_KIC_TMR_CFG_IMD_FIQ | AKF_KIC_TMR_CFG_EN) + +#define AKF_KIC_TMR_STATE_SET_SGT (1<<0) + +#define rAKF_AP_MAILBOX_SET(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x000)) +#define rAKF_AP_MAILBOX_CLR(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x004)) +#define AKF_MAILBOX_O_NONEMPTY_MSK (1<<12) +#define AKF_MAILBOX_O_EMPTY_MSK (1<<8) +#define AKF_MAILBOX_I_NONEMPTY_MSK (1<<4) +#define AKF_MAILBOX_I_EMPTY_MSK (1<<0) + +#define rAKF_AP_INBOX_CTRL(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x008)) +#define AKF_AP_INBOX_CTRL_UDFL (1<<19) +#define AKF_AP_INBOX_CTRL_OVFL (1<<18) +#define AKF_AP_INBOX_CTRL_EMPTY (1<<17) +#define AKF_AP_INBOX_CTRL_FULL (1<<16) +#define AKF_AP_INBOX_CTRL_ENABLE (1<<0) + +// AKF "64-bit" register helpers. +__attribute__((always_inline)) inline void _akf_write_reg_64(addr_t low_addr, uint64_t value) +{ +#if defined(__arm64__) + (*(volatile uint64_t *)(low_addr)) = value; +#else + uint32_t low = (uint32_t)(value & 0xFFFFFFFF); + uint32_t high = (uint32_t)((value >> 32) & 0xFFFFFFFF); + __asm__ __volatile__("strd %0, %1, [%2]" : : "r"(low), "r"(high) , "r"(low_addr)); +#endif +} + +__attribute__((always_inline)) inline uint64_t _akf_read_reg_64(addr_t low_addr) +{ +#if defined(__arm64__) + return (*(volatile uint64_t *)(low_addr)); +#else + uint32_t low, high; + __asm__ __volatile__ ("ldrd %0, %1, [%2]" : "=r"(low), "=r"(high) : "r"(low_addr)); + return ((uint64_t)high << 32) | low; +#endif +} + +__attribute__((always_inline)) inline void akf_write_ap_inbox(addr_t akf_base, uint64_t value) +{ + _akf_write_reg_64(akf_base + AKF_STRIDE + 0x010, value); +} +#define rAKF_AP_INBOX_WR_L(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x010)) +#define rAKF_AP_INBOX_WR_H(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x014)) + +__attribute__((always_inline)) inline uint64_t akf_read_ap_inbox(addr_t akf_base) +{ + return _akf_read_reg_64(akf_base + AKF_STRIDE + 0x018); +} +#define rAKF_AP_INBOX_RD(_b) (*(volatile uint64_t *)((_b) + AKF_STRIDE + 0x018)) +#define rAKF_AP_INBOX_RD_L(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x018)) +#define rAKF_AP_INBOX_RD_H(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x01C)) + +#define rAKF_AP_OUTBOX_CTRL(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x020)) +#define AKF_AP_OUTBOX_CTRL_UDFL (1<<19) +#define AKF_AP_OUTBOX_CTRL_OVFL (1<<18) +#define AKF_AP_OUTBOX_CTRL_EMPTY (1<<17) +#define AKF_AP_OUTBOX_CTRL_FULL (1<<16) +#define AKF_AP_OUTBOX_CTRL_ENABLE (1<<0) + +__attribute__((always_inline)) inline void akf_write_ap_outbox(addr_t akf_base, uint64_t value) +{ + _akf_write_reg_64(akf_base + AKF_STRIDE + 0x030, value); +} +#define rAKF_AP_OUTBOX_WR_L(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x030)) +#define rAKF_AP_OUTBOX_WR_H(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x034)) + +__attribute__((always_inline)) inline uint64_t akf_read_ap_outbox(addr_t akf_base) +{ + return _akf_read_reg_64(akf_base + AKF_STRIDE + 0x038); +} +#define rAKF_AP_OUTBOX_RD_L(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x038)) +#define rAKF_AP_OUTBOX_RD_H(_b) (*(volatile uint32_t *)((_b) + AKF_STRIDE + 0x03C)) + +#endif /* _APPLE_A7IOP_H */ diff --git a/drivers/apple/a7iop/rules.mk b/drivers/apple/a7iop/rules.mk new file mode 100644 index 0000000..17aa26e --- /dev/null +++ b/drivers/apple/a7iop/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/a7iop.o \ + $(LOCAL_DIR)/a7iop_debug.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/adbe/adbe.c b/drivers/apple/adbe/adbe.c new file mode 100644 index 0000000..85a1cf2 --- /dev/null +++ b/drivers/apple/adbe/adbe.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void adbe_enable_clocks(bool enable) +{ + int device; + + if (ADBE_DISPLAYPIPE_BASE_ADDR == DISP0_BASE_ADDR) + device = CLK_DISP0; +#ifdef DISP1_BASE_ADDR + else + device = CLK_DISP1; +#endif //DISP1_BASE_ADDR + + if (enable) + clock_gate(device, true); + else + clock_gate(device, false); +} + +void adbe_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl) +{ + RELEASE_ASSERT(red_lut != NULL); + RELEASE_ASSERT(green_lut != NULL); + RELEASE_ASSERT(blue_lut != NULL); + RELEASE_ASSERT(wpcl != NULL); + +#ifdef WITH_DPB + //gamma correction is done in the dpb block + dpb_install_gamma_table(red_lut, green_lut, blue_lut, wpcl); +#endif + +#ifdef WITH_WPC + //gamma correction is done in the wpc block + wpc_install_gamma_table(red_lut, green_lut, blue_lut, wpcl); +#endif + +#ifdef WITH_PRC + //gamma correction is done in the prc block + prc_install_gamma_table(red_lut, green_lut, blue_lut, wpcl); +#endif +} diff --git a/drivers/apple/adbe/adbe_regs_v1.h b/drivers/apple/adbe/adbe_regs_v1.h new file mode 100644 index 0000000..8e592db --- /dev/null +++ b/drivers/apple/adbe/adbe_regs_v1.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __ADBE_REGS_H +#define __ADBE_REGS_H + +#include + +#define rDBEMODECNTL (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x4)) +#define DBEMODECNTL_ENABLE (1 << 31) +#define DBEMODECNTL_PRE_CSC_LUT_ENABLE (1 << 30) +#define DBEMODECNTL_CSC_ENABLE (1 << 29) +#define DBEMODECNTL_POST_CSC_LUT_ENABLE (1 << 28) +#define DBEMODECNTL_AAP_ENABLE (1 << 27) +#define DBEMODECNTL_DPB_ENABLE (1 << 26) +#define DBEMODECNTL_BN_DITHER_ENABLE (1 << 25) +#define DBEMODECNTL_ST_DITHER_ENABLE (1 << 24) +#define DBEMODECNTL_DYN_CLK_GATE_ENABLE (1 << 23) +#define DBEMODECNTL_AFC_TEARDOWN_ENABLE (1 << 22) +#define DBEMODECNTL_PMGR_CLK_GATE_ENABL (1 << 21) +#define DBEMODECNTL_BLK_CLK_GATE_ENABLE (1 << 20) +#define DBEMODECNTL_VSYNC_POLARITY (1 << 19) +#define DBEMODECNTL_HSYNC_POLARITY (1 << 18) +#define DBEMODECNTL_I_P_SELECT(x) (x << 16) +#define DBEMODECNTL_UPDATE_ENABLE_TIMING (1 << 15) +#define DBEMODECNTL_UPDATE_REQ_TIMING (1 << 14) +#define DBEMODECNTL_CH2_SEL(x) (x << 12) +#define DBEMODECNTL_CH1_SEL(x) (x << 10) +#define DBEMODECNTL_CH0_SEL(x) (x << 8) +#define DBEMODECNTL_CRC_ENABLE (1 << 7) +#define DBEMODECNTL_CRC_MULTIFRAME_ENABLE (1 << 6) +#define DBEMODECNTL_CRC_WINDOW_ENABLE (1 << 5) +#define DBEMODECNTL_CRC_VALID (1 << 4) +#define DBEMODECNTL_VFTG_STATUS (1 << 0) + +#define rDBECONSTCOLOR (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x8)) +#define rDBESCRNSZ (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0xC)) +#define rDBEFRONTPORCH (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x10)) +#define rDBESYNCPULSE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x14)) +#define rDBEBACKPORCH (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x18)) +#define rDBEVBLANKPOS (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x1C)) +#define rDBEVBLANKCLKGATE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x20)) +#define rDBEVBLANKIDLE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x24)) +#define rDBECRCWINDOW (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x28)) +#define rDBECRCRESULT (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x2C)) + +//Only Alcatraz has the color manager on the back end. No need to generated a new driver just for it. +#define rCM_DEGAMMA_RED(n) (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x0400 + ((n) * 4))) +#define rCM_DEGAMMA_GREEN(n) (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x0800 + ((n) * 4))) +#define rCM_DEGAMMA_BLUE(n) (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x0c00 + ((n) * 4))) +#define rCM_CSC_00 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1000) +#define rCM_MATRIX_BASE(n) (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1000 + ((n) * 4))) +#define rCM_CSC_01 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1004)) +#define rCM_CSC_02 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1008)) +#define rCM_CSC_C0 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x100c)) +#define rCM_CSC_CI0 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1010)) +#define rCM_CSC_10 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1014)) +#define rCM_CSC_11 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1018)) +#define rCM_CSC_12 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x101c)) +#define rCM_CSC_C1 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1020)) +#define rCM_CSC_CI1 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1024)) +#define rCM_CSC_20 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1028)) +#define rCM_CSC_21 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1020)) +#define rCM_CSC_22 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1030)) +#define rCM_CSC_C2 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1034)) +#define rCM_CSC_CI2 (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1038)) +#define rCM_LUT_CTL (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x103c)) +#define CM_LUT_CTL (DISP_CM_BASE_ADDR + 0x103c) +#define CM_LUT_CTL_UPDATE_ENABLE_ENG_BLUE (1 << 23) +#define CM_LUT_CTL_UPDATE_REQ_ENG_BLUE (1 << 22) +#define CM_LUT_CTL_BYPASS_ENG_BLUE (1 << 21) +#define CM_LUT_CTL_UPDATE_ENABLE_DEG_BLUE (1 << 19) +#define CM_LUT_CTL_UPDATE_REQ_DEG_BLUE (1 << 18) +#define CM_LUT_CTL_BYPASS_DEG_BLUE (1 << 17) +#define CM_LUT_CTL_UPDATE_ENABLE_ENG_GREEN (1 << 15) +#define CM_LUT_CTL_UPDATE_REQ_ENG_GREEN (1 << 14) +#define CM_LUT_CTL_BYPASS_ENG_GREEN (1 << 13) +#define CM_LUT_CTL_UPDATE_ENABLE_DEG_GREEN (1 << 11) +#define CM_LUT_CTL_UPDATE_REQ_DEG_GREEN (1 << 10) +#define CM_LUT_CTL_BYPASS_DEG_GREEN (1 << 9) +#define CM_LUT_CTL_UPDATE_ENABLE_ENG_RED (1 << 7) +#define CM_LUT_CTL_UPDATE_REQ_ENG_RED (1 << 6) +#define CM_LUT_CTL_BYPASS_ENG_RED (1 << 5) +#define CM_LUT_CTL_UPDATE_ENABLE_DEG_RED (1 << 3) +#define CM_LUT_CTL_UPDATE_REQ_DEG_RED (1 << 2) +#define CM_LUT_CTL_BYPASS_DEG_RED (1 << 1) +#define rCM_ENGAMMA_RED(n) (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x1200 + ((n) * 4))) +#define rCM_ENGAMMA_GREEN(n) (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x2200 + ((n) * 4))) +#define rCM_ENGAMMA_BLUE(n) (*(volatile u_int32_t *)(DISP_CM_BASE_ADDR + 0x3200 + ((n) * 4))) +#endif /* __ADBE_REGS_H */ diff --git a/drivers/apple/adbe/adbe_regs_v2.h b/drivers/apple/adbe/adbe_regs_v2.h new file mode 100644 index 0000000..818853a --- /dev/null +++ b/drivers/apple/adbe/adbe_regs_v2.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __ADBE_REGS_H +#define __ADBE_REGS_H + +#include + +#define rDBEMODECNTL (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x4)) +#define DBEMODECNTL_AAP_ENABLE (1 << 31) +#define DBEMODECNTL_DPB_ENABLE (1 << 30) +#define DBEMODECNTL_BN_DITHER_ENABLE (1 << 29) +#define DBEMODECNTL_ST_DITHER_ENABLE (1 << 28) +#define DBEMODECNTL_DPB_BUSY_MASK (1 << 23) +#define DBEMODECNTL_PMGR_CLK_GATE_ENABLE (1 << 22) +#define DBEMODECNTL_DYN_CLK_GATE_ENABLE (1 << 21) +#define DBEMODECNTL_BLK_CLK_GATE_ENABLE (1 << 20) + +#define DBEMODECNTL_DITHER_ENABLE (1 << 28) +#define DBEMODECNTL_PRC_ENABLE (1 << 27) +#define DBEMODECNTL_WPC_ENABLE (1 << 26) + +#define rDBEVFTGCTL (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x8)) +#define DBEVFTGCT_VFTG_ENABLE (1 << 31) +#define DBEVFTGCT_VFTG_STATUS (1 << 30) +#define DBEVFTGCT_FRAME_COUNT_ENABLE (1 << 29) +#define DBEVFTGCT_FRAME_COUNT_RESET (1 << 28) +#define DBEVFTGCT_IDLE_FRAME_VBLANK_ENABLE (1 << 24) +#define DBEVFTGCT_VSYNC_POLARITY(n) ((n) << 19) +#define DBEVFTGCT_HSYNC_POLARITY(n) ((n) << 18) +#define DBEVFTGCT_SCAN_SELECT(n) ((n) << 16) +#define DBEVFTGCT_UPDATE_ENABLE_TIMING (1 << 15) +#define DBEVFTGCT_UPDATE_REQ_TIMING (1 << 14) +#define DBEVFTGCT_CH2_SEL(n) ((n) << 12) +#define DBEVFTGCT_CH1_SEL(n) ((n) << 10) +#define DBEVFTGCT_CH0_SEL(n) ((n) << 8) +#define DBEVFTGCT_VERTICAL_STATUS(n) ((n) << 4) +#define DBEVFTGCT_HORIZONTAL_STATUS(n) ((n) << 0) + +#define rDBESCRNSZ (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0xC)) +#define rDBEFRONTPORCH (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x10)) +#define rDBESYNCPULSE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x14)) +#define rDBEBACKPORCH (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x18)) +#define rDBECOUNTER_STATUS (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x1C)) +#define rDBECOUNTER_POSITION (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x20)) +#define rDBEVBLANK_POSITION (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x24)) +#define rDBEVBLANKCLKGATE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x28)) +#define rDBEVBLANKBUSY (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x2C)) +#define rDBEISR (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x30)) +#define rDBECONST_COLOR (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x34)) +#define rDBECRC_CTL (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x38)) +#define rDBECRCWINDOW (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x3C)) +#define rDBECRCRESULT (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x40)) +#define rDBEFIFO_CONFIG (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x44)) +#define rDBEFIFO_STATUS (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x48)) +#define rDBESPARE_CONFIG0 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x4C)) +#define rDBESPARE_CONFIG1 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x50)) +#define rDBESPARE_CONFIG2 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x54)) +#define rDBESPARE_CONFIG3 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x58)) +#define rDBESPARE_STATUS0 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x5C)) +#define rDBESPARE_STATUS1 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x60)) +#define rDBESPARE_STATUS2 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x64)) +#define rDBESPARE_STATUS3 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x68)) + +#define rAAP_FORMAT_CONTROL_REG0 (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x0)) +#define rAAP_FORMAT_CONTROL_REG1 (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x4)) +#define AAP_FORMAT_CONTROL_REG1_AUTOSIZE (1 << 7) +#define AAP_FORMAT_CONTROL_REG1_AUTOPOS (1 << 6) +#define AAP_FORMAT_CONTROL_REG1_FCMODE(n) ((n & 0x3) << 4) +#define AAP_FORMAT_CONTROL_REG1_RSVD(n) ((n & 0xf) << 2) +#define AAP_FORMAT_CONTROL_REG1_VS_POL (1 << 1) +#define AAP_FORMAT_CONTROL_REG1_HS_POL (1 << 0) +#define rAAP_FORMAT_HS_POS_LSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x8)) +#define rAAP_FORMAT_HS_POS_MSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0xC)) +#define rAAP_FORMAT_FRAME_WIDTH_LSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x10)) +#define rAAP_FORMAT_FRAME_WIDTH_MSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x14)) +#define rAAP_FORMAT_FRAME_HEIGHT_LSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x18)) +#define rAAP_FORMAT_FRAME_HEIGHT_MSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x1C)) +#define rAAP_FORMAT_VS_POS_LSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x20)) +#define rAAP_FORMAT_VS_POS_MSB (*(volatile u_int32_t *)(DISP0_AAP_BASE_ADDR + 0x24)) + +#endif /* __ADBE_REGS_H */ diff --git a/drivers/apple/adbe/adbe_regs_v3.h b/drivers/apple/adbe/adbe_regs_v3.h new file mode 100644 index 0000000..de7eb68 --- /dev/null +++ b/drivers/apple/adbe/adbe_regs_v3.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __ADBE_REGS_V3_H +#define __ADBE_REGS_V3_H + +#define rADBE_VERSION (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0000)) + +#define rADBE_NRT_CTL (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0004)) +#define ADBE_NRT_CTL_VFTG_MODE_COMMAND (1 << 25) +#define ADBE_NRT_CTL_TE_ENABLE_SEL_SW (1 << 24) +#define ADBE_NRT_CTL_TE_MODE_MASK (3 << 22) +#define ADBE_NRT_CTL_TE_MODE_IDLE (0 << 22) +#define ADBE_NRT_CTL_TE_MODE_POS (1 << 22) +#define ADBE_NRT_CTL_TE_MODE_NEG (2 << 22) +#define ADBE_NRT_CTL_TE_MODE_TOGGLE (3 << 22) +#define ADBE_NRT_CTL_AAP_ENABLE (1 << 21) +#define ADBE_NRT_CTL_BN_DITHER_ENABLE (1 << 20) +#define ADBE_NRT_CTL_ST_DITHER_ENABLE (1 << 19) +#define ADBE_NRT_CTL_ADISP_CLK_GATE_ENABLE (1 << 18) +#define ADBE_NRT_CTL_ADBE_CLK_GATE_ENABLE (1 << 17) +#define ADBE_NRT_CTL_BLK_CLK_GATE_ENABLE (1 << 16) +#define ADBE_NRT_CTL_VSYNC_POLARITY(n) ((n) << 9) +#define ADBE_NRT_CTL_HSYNC_POLARITY(n) ((n) << 8) +#define ADBE_NRT_CTL_SCAN_SELECT_PROG_NOCHG (0 << 6) +#define ADBE_NRT_CTL_SCAN_SELECT_INT_ODD (1 << 6) +#define ADBE_NRT_CTL_SCAN_SELECT_PROG_CHG (2 << 6) +#define ADBE_NRT_CTL_SCAN_SELECT_INT_EVEN (3 << 6) +#define ADBE_NRT_CTL_CH2_SEL_RED (0 << 4) +#define ADBE_NRT_CTL_CH2_SEL_GREEN (1 << 4) +#define ADBE_NRT_CTL_CH2_SEL_BLUE (2 << 4) +#define ADBE_NRT_CTL_CH2_SEL_CONST (3 << 4) +#define ADBE_NRT_CTL_CH1_SEL_RED (0 << 2) +#define ADBE_NRT_CTL_CH1_SEL_GREEN (1 << 2) +#define ADBE_NRT_CTL_CH1_SEL_BLUE (2 << 2) +#define ADBE_NRT_CTL_CH1_SEL_CONST (3 << 2) +#define ADBE_NRT_CTL_CH0_SEL_RED (0 << 0) +#define ADBE_NRT_CTL_CH0_SEL_GREEN (1 << 0) +#define ADBE_NRT_CTL_CH0_SEL_BLUE (2 << 0) +#define ADBE_NRT_CTL_CH0_SEL_CONST (3 << 0) + +#define rADBE_RT_CTL (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0008)) +#define ADBE_RT_CTL_VFTG_STATUS_EN (1 << 16) +#define ADBE_RT_CTL_VERTICAL_STATUS_IDLE (0 << 12) +#define ADBE_RT_CTL_VERTICAL_STATUS_ACTIVE (8 << 12) +#define ADBE_RT_CTL_VERTICAL_STATUS_FRONT (4 << 12) +#define ADBE_RT_CTL_VERTICAL_STATUS_SYNC (2 << 12) +#define ADBE_RT_CTL_VERTICAL_STATUS_BACK (1 << 12) +#define ADBE_RT_CTL_HORIZONTAL_STATUS_IDLE (0 << 8) +#define ADBE_RT_CTL_HORIZONTAL_STATUS_ACTIVE (8 << 8) +#define ADBE_RT_CTL_HORIZONTAL_STATUS_FRONT (4 << 8) +#define ADBE_RT_CTL_HORIZONTAL_STATUS_SYNC (2 << 8) +#define ADBE_RT_CTL_HORIZONTAL_STATUS_BACK (1 << 8) +#define ADBE_RT_CTL_VFTG_ENABLE_CMD_EN (1 << 5) +#define ADBE_RT_CTL_VFTG_ENABLE_VID_EN (1 << 4) +#define ADBE_RT_CTL_UPDATE_ENABLE_TIMING_READY (1 << 3) +#define ADBE_RT_CTL_UPDATE_REQ_TIMING_NOSYNC (1 << 2) +#define ADBE_RT_CTL_FRAME_COUNT_ENABLE (1 << 1) +#define ADBE_RT_CTL_FRAME_COUNT_RESET_EN (1 << 0) + +#define rADBE_ACTIVE_SIZE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x000c)) +#define ADBE_ACTIVE_SIZE_VERTICAL(n) ((n) << 16) +#define ADBE_ACTIVE_SIZE_HORIZONTAL(n) ((n) << 0) + +#define rADBE_FRONT_PORCH (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0010)) +#define ADBE_FRONT_PORCH_VERTICAL(n) ((n) << 16) +#define ADBE_FRONT_PORCH_HORIZONTAL(n) ((n) << 0) + +#define rADBE_SYNC_PULSE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0014)) +#define ADBE_SYNC_PULSE_VERTICAL(n) ((n) << 16) +#define ADBE_SYNC_PULSE_HORIZONTAL(n) ((n) << 0) + +#define rADBE_BACK_PORCH (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0018)) +#define ADBE_BACK_PORCH_VERTICAL(n) ((n) << 16) +#define ADBE_BACK_PORCH_HORIZONTAL(n) ((n) << 0) + +#define rADBE_COUNTER_STATUS (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x001c)) +#define ADBE_COUNTER_STATUS_FRAME_COUNTER(n) ((n) << 16) +#define ADBE_COUNTER_STATUS_LINE_COUNTER(n) ((n) << 0) + +#define rADBE_COUNTER_POSITION (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0020)) +#define ADBE_COUNTER_POSITION_FRAME_COUNTER(n) ((n) << 16) +#define ADBE_COUNTER_POSITION_LINE_COUNTER(n) ((n) << 0) + +#define rADBE_VBLANK_POSITION (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0024)) +#define ADBE_VBLANK_POSITION_FIELD_OUT(n) ((n) << 16) +#define ADBE_VBLANK_POSITION_VBI_PULSE(n) ((n) << 0) + +#define rADBE_VBLANK_CLK_GATE (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0028)) +#define ADBE_VBLANK_CLK_GATE_WAKEUP(n) ((n) << 16) +#define ADBE_VBLANK_CLK_GATE_IDLE(n) ((n) << 0) + +#define rADBE_VBLANK_BUSY (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x002c)) +#define ADBE_VBLANK_BUSY_FINISH(n) ((n) << 16) +#define ADBE_VBLANK_BUSY_START(n) ((n) << 0) + +#define rADBE_INTERRUPT (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0030)) +#define ADBE_INTERRUPT_COUNTER_MASK (1 << 18) +#define ADBE_INTERRUPT_VFTG_DOWN_MASK (1 << 17) +#define ADBE_INTERRUPT_VBI_TE_MASK (1 << 16) +#define ADBE_INTERRUPT_COUNTER_STATUS (1 << 2) +#define ADBE_INTERRUPT_VFTG_DOWN_STATUS (1 << 1) +#define ADBE_INTERRUPT_VBI_TE_STATUS (1 << 0 ) + +#define rADBE_CONST_COLOR (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0034)) +#define ADBE_CONST_COLOR_VALUE_CH2(n) ((n) << 20) +#define ADBE_CONST_COLOR_VALUE_CH1(n) ((n) << 10) +#define ADBE_CONST_COLOR_VALUE_CH0(n) ((n) << 0) + +#define rADBE_CRC_CTL (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0038)) +#define ADBE_CRC_CTL_ENABLE (1 << 3) +#define ADBE_CRC_CTL_MULTIFRAME_ENABLE (1 << 2) +#define ADBE_CRC_CTL_WINDOW_ENABLE (1 << 1) +#define ADBE_CRC_CTL_VALID (1 << 0) + +#define rADBE_CRC_WINDOW (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x003c)) +#define ADBE_CRC_WINDOW_RIGHT ((n) << 16) +#define ADBE_CRC_WINDOW_LEFT ((n) << 0) + +#define rADBE_CRC_RESULT (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0040)) + +#define rADBE_FIFO_CONFIG (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0044)) +#define ADBE_FIFO_CONFIG_UNDERRUN_MODE_DEFAULT (0 << 30) +#define ADBE_FIFO_CONFIG_UNDERRUN_MODE_NORMAL (1 << 30) +#define ADBE_FIFO_CONFIG_UNDERRUN_MODE_FRAME (2 << 30) +#define ADBE_FIFO_CONFIG_UNDERRUN_MODE_STICKY (3 << 30) +#define ADBE_FIFO_CONFIG_UNDERRUN_CH2(n) ((n) << 20) +#define ADBE_FIFO_CONFIG_UNDERRUN_CH1(n) ((n) << 10) +#define ADBE_FIFO_CONFIG_UNDERRUN_CH0(n) ((n) << 0) + +#define rADBE_FIFO_STATUS (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0048)) +#define ADBE_FIFO_STATUS_FULL (1 << 25) +#define ADBE_FIFO_STATUS_EMPTY (1 << 24) +#define ADBE_FIFO_STATUS_PUSH_COUNT_GRAY(n) ((n) << 12) +#define ADBE_FIFO_STATUS_POP_COUNT_GRAY(n) ((n) << 0) + +#define rADBE_SPARE_CONFIG0 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x004c)) +#define rADBE_SPARE_CONFIG1 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0050)) +#define rADBE_SPARE_CONFIG2 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0054)) +#define rADBE_SPARE_CONFIG3 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0058)) + +#define rADBE_SPARE_STATUS0 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x005c)) +#define rADBE_SPARE_STATUS1 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0060)) +#define rADBE_SPARE_STATUS2 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0064)) +#define rADBE_SPARE_STATUS3 (*(volatile u_int32_t *)(DISP0_ADBE_BASE_ADDR + 0x0068)) +#endif // __ADBE_REGS_V3_H diff --git a/drivers/apple/adbe/adbe_v1.c b/drivers/apple/adbe/adbe_v1.c new file mode 100644 index 0000000..bffb00a --- /dev/null +++ b/drivers/apple/adbe/adbe_v1.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include "adbe_regs_v1.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct adbe_v1_tuneable { + char *name; + uint32_t adbe0_tunable_mode_ctrl; + uint32_t adbe0_vblank_pos_vbi_pulse; + uint32_t adbe0_vblank_clk_gate_wakeup; + uint32_t adbe0_vblank_clk_gate_idle; + uint32_t adbe0_vblank_blk_idle_dpb; + uint32_t adbe0_vblank_blk_idle_aap; + uint32_t adbe0_aap_support; +}; + +#include + +static struct adbe_v1_tuneable *adbe_tuneables_info; +static const int32_t adbe_tuneables_list_size = sizeof(adbe_tuneables) / sizeof(struct adbe_v1_tuneable); + +static void adbe_program_color_manager() +{ + uint32_t i; + uint32_t engamma_table_count = mib_get_u32(kMIBTargetDisplayCMEngammaTableCount); + uint32_t degamma_table_count = mib_get_u32(kMIBTargetDisplayCMDegammaTableCount); + uint32_t matrix_table_count = mib_get_u32(kMIBTargetDisplayCMMatrixTableCount); + + if (engamma_table_count != 0 && degamma_table_count != 0 && matrix_table_count != 0) { + const uint32_t * engamma_table_base = (const uint32_t *)mib_get_ptr(kMIBTargetDisplayCMEngammaTablePtr); + const uint32_t * degamma_table_base = (const uint32_t *)mib_get_ptr(kMIBTargetDisplayCMDegammaTablePtr); + const uint32_t * matrix_table_base = (const uint32_t *)mib_get_ptr(kMIBTargetDisplayCMMatrixTablePtr); + + for (i = 0; i < degamma_table_count; i++) { + rCM_DEGAMMA_RED(i) = degamma_table_base[i]; + rCM_DEGAMMA_GREEN(i) = degamma_table_base[i]; + rCM_DEGAMMA_BLUE(i) = degamma_table_base[i]; + } + + for (i = 0; i < matrix_table_count; i++) { + rCM_MATRIX_BASE(i) = matrix_table_base[i]; + } + for (i = 0; i < engamma_table_count; i++) { + rCM_ENGAMMA_RED(i) = engamma_table_base[i]; + rCM_ENGAMMA_GREEN(i) = engamma_table_base[i]; + rCM_ENGAMMA_BLUE(i) = engamma_table_base[i]; + } + + + //enabe LUTs in the lut register + rCM_LUT_CTL = CM_LUT_CTL_UPDATE_ENABLE_ENG_BLUE | + CM_LUT_CTL_UPDATE_REQ_ENG_BLUE | + CM_LUT_CTL_UPDATE_ENABLE_DEG_BLUE | + CM_LUT_CTL_UPDATE_REQ_DEG_BLUE | + CM_LUT_CTL_UPDATE_ENABLE_ENG_GREEN | + CM_LUT_CTL_UPDATE_REQ_ENG_GREEN | + CM_LUT_CTL_UPDATE_ENABLE_DEG_GREEN | + CM_LUT_CTL_UPDATE_REQ_DEG_GREEN | + CM_LUT_CTL_UPDATE_ENABLE_ENG_RED | + CM_LUT_CTL_UPDATE_REQ_ENG_RED | + CM_LUT_CTL_UPDATE_ENABLE_DEG_RED | + CM_LUT_CTL_UPDATE_REQ_DEG_RED; + } +} + +void adbe_init(struct display_timing *timing) +{ + const char *env; + int32_t cnt; + + env = env_get("adbe-tunable"); + if (env == 0) env = "default"; + + for (cnt = 0; cnt < adbe_tuneables_list_size; cnt++) { + if (strcmp(env, adbe_tuneables[cnt].name)) continue; + + adbe_tuneables_info = adbe_tuneables + cnt; + } + if (adbe_tuneables_info == 0) { + dprintf(DEBUG_INFO, "Failed to find adbe tunables info, bailing adbe_init()\n"); + return; + } + + rDBESCRNSZ = (timing->v_active << 16) | (timing->h_active << 0); + rDBEFRONTPORCH = (timing->v_front_porch << 16) | (timing->h_front_porch << 0); + rDBESYNCPULSE = (timing->v_pulse_width << 16) | (timing->h_pulse_width << 0); + rDBEBACKPORCH = (timing->v_back_porch << 16) | (timing->h_back_porch << 0); + + rDBEVBLANKPOS = adbe_tuneables_info->adbe0_vblank_pos_vbi_pulse; + +#ifdef TARGET_ADBE0_VBLANK_POSITION + rDBEVBLANKPOS |= TARGET_ADBE0_VBLANK_POSITION; +#endif + + adbe_tuneables_info->adbe0_vblank_clk_gate_wakeup = timing->v_back_porch + timing->v_front_porch + timing->v_pulse_width - 5; + + rDBEVBLANKCLKGATE = ((adbe_tuneables_info->adbe0_vblank_clk_gate_wakeup << 16) | adbe_tuneables_info->adbe0_vblank_clk_gate_idle); + rDBEVBLANKIDLE = ((adbe_tuneables_info->adbe0_vblank_blk_idle_dpb << 16) | adbe_tuneables_info->adbe0_vblank_blk_idle_aap); + + //csc lut programming should occur here + + //Set AAP + rDBEMODECNTL |= (adbe_tuneables_info->adbe0_aap_support) ? DBEMODECNTL_AAP_ENABLE: 0; + +#ifdef WITH_DPB + // Need to enable block first in order to access its registers + rDBEMODECNTL |= DBEMODECNTL_DPB_ENABLE; + dpb_init(); +#endif + + // Dither +#ifdef WITH_HW_DITHER + //Currently, no product uses BN on H6. + uint8_t dither_type = DITHER_SPATIO_TEMPORAL; +#ifdef TARGET_DITHER_TYPE + dither_type = TARGET_DITHER_TYPE; +#endif //TARGET_DITHER_TYPE + + //Dithering gets enabled in this block, no need to call into dithering to enable + //We need to enable to block to access their corresponding registers + switch(dither_type) { + case DITHER_SPATIO_TEMPORAL: + rDBEMODECNTL |= DBEMODECNTL_ST_DITHER_ENABLE; + break; + case DITHER_BLUE_NOISE: + rDBEMODECNTL |= DBEMODECNTL_BN_DITHER_ENABLE; + break; + case DITHER_NONE: + default: + rDBEMODECNTL &= ~(DBEMODECNTL_ST_DITHER_ENABLE | DBEMODECNTL_BN_DITHER_ENABLE); + break; + } + + dither_init(timing->display_depth); +#endif +#ifdef TARGET_ENABLE_CM + rDBEMODECNTL |= (DBEMODECNTL_PRE_CSC_LUT_ENABLE | DBEMODECNTL_CSC_ENABLE | DBEMODECNTL_POST_CSC_LUT_ENABLE); + adbe_program_color_manager(); + +#endif + + rDBEMODECNTL |= adbe_tuneables_info->adbe0_tunable_mode_ctrl; + + // Radar J72dev2 - Innsbruck11A289 | Playing a video in full screen causes the screen to go blank + // need to force an update to the timing before enabling the timing generator + rDBEMODECNTL |= (DBEMODECNTL_UPDATE_ENABLE_TIMING | DBEMODECNTL_UPDATE_REQ_TIMING); +} + +void adbe_enable_timing_generator(bool enable) +{ + if (enable) { + rDBEMODECNTL |= DBEMODECNTL_ENABLE; // Enable VFTG + while ((rDBEMODECNTL & DBEMODECNTL_VFTG_STATUS) == 0); // Wait for it to be enabled + } + else { + rDBEMODECNTL &= ~DBEMODECNTL_ENABLE; // Enable VFTG + while ((rDBEMODECNTL & DBEMODECNTL_VFTG_STATUS) == 1); // Wait for it to be disabled + } +} + +bool adbe_get_enable_timing_generator(void) +{ + return ((rDBEMODECNTL & DBEMODECNTL_ENABLE) == (uint32_t)DBEMODECNTL_ENABLE); +} diff --git a/drivers/apple/adbe/adbe_v2.c b/drivers/apple/adbe/adbe_v2.c new file mode 100644 index 0000000..75d4081 --- /dev/null +++ b/drivers/apple/adbe/adbe_v2.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include "adbe_regs_v2.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct adbe_v2_tuneable { + char *name; + uint32_t adbe0_tunable_mode_ctrl; + uint32_t adbe0_vftgctl_idle_frame_vblank_enable; + uint32_t adbe0_vblank_pos_vbi_pulse; + uint32_t adbe0_vblank_clk_gate_wakeup; + uint32_t adbe0_vblank_clk_gate_idle; + uint32_t adbe0_vblank_busy_finish; + uint32_t adbe0_aap_support; + uint32_t adbe0_aap_format_control_reg1; +}; + +#include + +static struct adbe_v2_tuneable *adbe_tuneables_info; +static const int32_t adbe_tuneables_list_size = sizeof(adbe_tuneables) / sizeof(struct adbe_v2_tuneable); + +void adbe_init(struct display_timing *timing) +{ + const char *env; + int32_t cnt; + + env = env_get("adbe-tunables"); + if (env == 0) env = "default"; + + for (cnt = 0; cnt < adbe_tuneables_list_size; cnt++) { + if (strcmp(env, adbe_tuneables[cnt].name)) continue; + + adbe_tuneables_info = adbe_tuneables + cnt; + } + if (adbe_tuneables_info == 0) { + dprintf(DEBUG_INFO, "Failed to find adbe tunables info, bailing adbe_init()\n"); + return; + } + + rDBESCRNSZ = (timing->v_active << 16) | (timing->h_active << 0); + rDBEFRONTPORCH = (timing->v_front_porch << 16) | (timing->h_front_porch << 0); + rDBESYNCPULSE = (timing->v_pulse_width << 16) | (timing->h_pulse_width << 0); + rDBEBACKPORCH = (timing->v_back_porch << 16) | (timing->h_back_porch << 0); + + rDBEVFTGCTL |= (DBEVFTGCT_VSYNC_POLARITY(timing->neg_vsync) | DBEVFTGCT_HSYNC_POLARITY(timing->neg_hsync)); + rDBEVFTGCTL |= DBEVFTGCT_FRAME_COUNT_ENABLE | DBEVFTGCT_SCAN_SELECT(0x2); + rDBEVFTGCTL |= adbe_tuneables_info->adbe0_vftgctl_idle_frame_vblank_enable ? DBEVFTGCT_IDLE_FRAME_VBLANK_ENABLE : 0 ; + + rDBEVBLANK_POSITION = (rDBEVBLANK_POSITION & ~0xFFFF) | adbe_tuneables_info->adbe0_vblank_pos_vbi_pulse; + + rDBEVBLANKCLKGATE = ((adbe_tuneables_info->adbe0_vblank_clk_gate_wakeup << 16) | adbe_tuneables_info->adbe0_vblank_clk_gate_idle); + + rDBEVBLANKBUSY = (adbe_tuneables_info->adbe0_vblank_busy_finish << 16); + + //csc lut programming should occur here + + rAAP_FORMAT_CONTROL_REG1 = adbe_tuneables_info->adbe0_aap_format_control_reg1; + + //Set AAP + rDBEMODECNTL |= (adbe_tuneables_info->adbe0_aap_support) ? DBEMODECNTL_AAP_ENABLE: 0; + +#ifdef WITH_DPB + // Need to enable block first in order to access its registers + rDBEMODECNTL |= DBEMODECNTL_DPB_ENABLE; +#if DPB_VERSION < 2 + dpb_init(); +#else + dpb_init(timing->h_active, timing->v_active); +#endif +#endif + +#ifdef WITH_WPC + // Need to enable block first in order to access its registers + rDBEMODECNTL |= DBEMODECNTL_WPC_ENABLE; + wpc_init(timing->h_active, timing->v_active); +#endif + +#ifdef WITH_PRC + // Need to enable block first in order to access its registers + rDBEMODECNTL |= DBEMODECNTL_PRC_ENABLE; + prc_init(timing->h_active, timing->v_active); +#endif + +// Dither +#if DITHER_VERSION < 4 +#ifdef WITH_HW_DITHER + //Currently, no product uses BN on H6. + uint8_t dither_type = DITHER_SPATIO_TEMPORAL; +#ifdef TARGET_DITHER_TYPE + dither_type = TARGET_DITHER_TYPE; +#endif //TARGET_DITHER_TYPE + //Dithering gets enabled in this block, no need to call into dithering to enable + //We need to enable to block to access their corresponding registers + switch(dither_type) { + case DITHER_SPATIO_TEMPORAL: + rDBEMODECNTL |= DBEMODECNTL_ST_DITHER_ENABLE; + break; + case DITHER_BLUE_NOISE: + rDBEMODECNTL |= DBEMODECNTL_BN_DITHER_ENABLE; + break; + case DITHER_NONE: + default: + rDBEMODECNTL &= ~(DBEMODECNTL_ST_DITHER_ENABLE | DBEMODECNTL_BN_DITHER_ENABLE); + break; + } + + dither_init(timing->display_depth); +#endif + +#else // DITHER_VERSION >= 4 +#ifdef WITH_HW_DITHER + // Enable Dither Block + rDBEMODECNTL |= DBEMODECNTL_DITHER_ENABLE; + + dither_init(timing->h_active, timing->v_active, timing->display_depth); +#endif +#endif + + rDBEMODECNTL |= adbe_tuneables_info->adbe0_tunable_mode_ctrl; + + rDBEFIFO_CONFIG = 0x400003ff; + + //disable interrupts + rDBEISR = ((1 << 18) | (1 << 17) | (1 << 16)); + + rDBEVFTGCTL |= (DBEVFTGCT_UPDATE_ENABLE_TIMING | DBEVFTGCT_UPDATE_REQ_TIMING); +} + +void adbe_enable_timing_generator(bool enable) +{ + if (enable) { + rDBEVFTGCTL |= DBEVFTGCT_VFTG_ENABLE; // Enable VFTG + while ((rDBEVFTGCTL & DBEVFTGCT_VFTG_STATUS) == 0); // Wait for it to be enabled + } else { + rDBEVFTGCTL &= ~DBEVFTGCT_VFTG_ENABLE; // Disable VFTG + while ((rDBEVFTGCTL & DBEVFTGCT_VFTG_STATUS) == DBEVFTGCT_VFTG_STATUS); // Wait for it to be disabled + } +} + +bool adbe_get_enable_timing_generator(void) +{ + return ((rDBEVFTGCTL & DBEVFTGCT_VFTG_ENABLE) == (uint32_t)DBEVFTGCT_VFTG_ENABLE); +} diff --git a/drivers/apple/adbe/adbe_v3.c b/drivers/apple/adbe/adbe_v3.c new file mode 100644 index 0000000..8b59626 --- /dev/null +++ b/drivers/apple/adbe/adbe_v3.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include "adbe_regs_v3.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct adbe_v3_tuneable { + char *name; + uint32_t adbe0_vblank_clk_gate_wakeup; + uint32_t adbe0_vblank_clk_gate_idle; + uint32_t adbe0_tunable_nrt_ctl; + uint32_t adbe0_aap_support; +}; + +#include + +static bool is_video_mode = true; + +static struct adbe_v3_tuneable *adbe_tuneables_info; +static const int32_t adbe_tuneables_list_size = sizeof(adbe_tuneables) / sizeof(struct adbe_v3_tuneable); + +void adbe_init(struct display_timing *timing) +{ + const char *env; + int32_t cnt; + + env = env_get("adbe-tunable"); + if (env == 0) env = "default"; + + for (cnt = 0; cnt < adbe_tuneables_list_size; cnt++) { + if (strcmp(env, adbe_tuneables[cnt].name)) continue; + + adbe_tuneables_info = adbe_tuneables + cnt; + } + if (adbe_tuneables_info == 0) { + dprintf(DEBUG_INFO, "Failed to find adbe tunables info, bailing adbe_init()\n"); + return; + } + + rADBE_ACTIVE_SIZE = ADBE_ACTIVE_SIZE_VERTICAL(timing->v_active) | ADBE_ACTIVE_SIZE_HORIZONTAL(timing->h_active); + rADBE_FRONT_PORCH = ADBE_FRONT_PORCH_VERTICAL(timing->v_front_porch) | ADBE_FRONT_PORCH_HORIZONTAL(timing->h_front_porch ); + rADBE_SYNC_PULSE = ADBE_SYNC_PULSE_VERTICAL(timing->v_pulse_width) | ADBE_SYNC_PULSE_HORIZONTAL(timing->h_pulse_width); + rADBE_BACK_PORCH = ADBE_BACK_PORCH_VERTICAL(timing->v_back_porch) | ADBE_BACK_PORCH_HORIZONTAL(timing->h_back_porch); + + //rdar://16085315 Errata Samsung’s DSIM_MDRESOL.MainStandby register field description. + rADBE_NRT_CTL &= ~ADBE_NRT_CTL_TE_MODE_MASK; + rADBE_NRT_CTL |= (ADBE_NRT_CTL_VSYNC_POLARITY(timing->neg_vsync) | ADBE_NRT_CTL_HSYNC_POLARITY(timing->neg_hsync)); + rADBE_RT_CTL |= ADBE_RT_CTL_FRAME_COUNT_ENABLE; + rADBE_NRT_CTL |= ADBE_NRT_CTL_SCAN_SELECT_PROG_CHG; + +#ifdef TARGET_ADBE0_VBLANK_POSITION + rADBE_VBLANK_POSITION = TARGET_ADBE0_VBLANK_POSITION; +#endif + adbe_tuneables_info->adbe0_vblank_clk_gate_wakeup = timing->v_back_porch + timing->v_front_porch + timing->v_pulse_width - 5; + + rADBE_VBLANK_CLK_GATE = + (ADBE_VBLANK_CLK_GATE_WAKEUP(adbe_tuneables_info->adbe0_vblank_clk_gate_wakeup) | + adbe_tuneables_info->adbe0_vblank_clk_gate_idle); + + //Set AAP + rADBE_NRT_CTL |= (adbe_tuneables_info->adbe0_aap_support) ? ADBE_NRT_CTL_AAP_ENABLE: 0; + + // Dither +#ifdef WITH_HW_DITHER + uint8_t dither_type = DITHER_SPATIO_TEMPORAL; +#ifdef TARGET_DITHER_TYPE + dither_type = TARGET_DITHER_TYPE; +#endif //TARGET_DITHER_TYPE + + //Dithering gets enabled in this block, no need to call into dithering to enable + //We need to enable to block to access their corresponding registers + switch(dither_type) { + case DITHER_SPATIO_TEMPORAL: + rADBE_NRT_CTL |= ADBE_NRT_CTL_ST_DITHER_ENABLE; + break; + case DITHER_BLUE_NOISE: + rADBE_NRT_CTL |= ADBE_NRT_CTL_BN_DITHER_ENABLE; + break; + case DITHER_NONE: + default: + rADBE_NRT_CTL &= ~(ADBE_NRT_CTL_ST_DITHER_ENABLE | ADBE_NRT_CTL_BN_DITHER_ENABLE); + break; + } + + dither_init(timing->display_depth); +#endif + + rADBE_NRT_CTL |= adbe_tuneables_info->adbe0_tunable_nrt_ctl; + + //Underrun setup + rADBE_FIFO_CONFIG = ADBE_FIFO_CONFIG_UNDERRUN_MODE_STICKY | ADBE_FIFO_CONFIG_UNDERRUN_CH0(0x3FF); + +} + +static void adbe_enable_timing_generator_v3_video_mode(bool enable) +{ + if (enable) { + rADBE_RT_CTL |= ADBE_RT_CTL_VFTG_ENABLE_VID_EN; // Enable VFTG + while ((rADBE_RT_CTL & ADBE_RT_CTL_VFTG_STATUS_EN) == 0); // Wait for it to be enabled + } else { + rADBE_RT_CTL &= ~ADBE_RT_CTL_VFTG_ENABLE_VID_EN; // Disable VFTG + while ((rADBE_RT_CTL & ADBE_RT_CTL_VFTG_STATUS_EN) == ADBE_RT_CTL_VFTG_STATUS_EN); // Wait for it to be disabled + } +} + +static void adbe_enable_timing_generator_v3_command_mode(bool enable) +{ + if (enable) { + rADBE_RT_CTL |= ADBE_RT_CTL_VFTG_ENABLE_CMD_EN; // Enable VFTG + while ((rADBE_RT_CTL & ADBE_RT_CTL_VFTG_STATUS_EN) == 0); // Wait for it to be enabled + } else { + rADBE_RT_CTL &= ~ADBE_RT_CTL_VFTG_ENABLE_CMD_EN; // Disable VFTG + while ((rADBE_RT_CTL & ADBE_RT_CTL_VFTG_STATUS_EN) == ADBE_RT_CTL_VFTG_STATUS_EN); // Wait for it to be disabled + } +} + +void adbe_enable_timing_generator(bool enable) +{ +#ifdef TARGET_DISP_VIDEO_MODE + is_video_mode = TARGET_DISP_VIDEO_MODE; +#endif //TARGET_DISP_VIDEO_MODE + + if (is_video_mode) { + rADBE_RT_CTL |= (ADBE_RT_CTL_UPDATE_ENABLE_TIMING_READY | ADBE_RT_CTL_UPDATE_REQ_TIMING_NOSYNC); + adbe_enable_timing_generator_v3_video_mode(enable); + } else { + rADBE_NRT_CTL |= ADBE_NRT_CTL_TE_MODE_POS | ADBE_NRT_CTL_VFTG_MODE_COMMAND | ADBE_NRT_CTL_TE_ENABLE_SEL_SW; + rADBE_RT_CTL |= (ADBE_RT_CTL_UPDATE_ENABLE_TIMING_READY | ADBE_RT_CTL_UPDATE_REQ_TIMING_NOSYNC); + adbe_enable_timing_generator_v3_command_mode(enable); + } +} + +bool adbe_get_enable_timing_generator(void) +{ +#ifdef TARGET_DISP_VIDEO_MODE + is_video_mode = TARGET_DISP_VIDEO_MODE; +#endif //TARGET_DISP_VIDEO_MODE + + if (is_video_mode) { + return ((rADBE_RT_CTL & ADBE_RT_CTL_VFTG_ENABLE_VID_EN) == (uint32_t)ADBE_RT_CTL_VFTG_ENABLE_VID_EN); + } else { + return ((rADBE_RT_CTL & ADBE_RT_CTL_VFTG_ENABLE_CMD_EN) == (uint32_t)ADBE_RT_CTL_VFTG_ENABLE_CMD_EN); + } +} diff --git a/drivers/apple/adbe/include/drivers/adbe/adbe.h b/drivers/apple/adbe/include/drivers/adbe/adbe.h new file mode 100644 index 0000000..0ec5231 --- /dev/null +++ b/drivers/apple/adbe/include/drivers/adbe/adbe.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_BACKEND_H +#define __APPLE_DISPLAY_BACKEND_H + +void adbe_enable_clocks(bool enable); +void adbe_init(struct display_timing *timing); +void adbe_enable_timing_generator(bool enable); +bool adbe_get_enable_timing_generator(void); +void adbe_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl); + +#endif /* __APPLE_DISPLAY_BACKEND_H */ diff --git a/drivers/apple/adbe/rules.mk b/drivers/apple/adbe/rules.mk new file mode 100644 index 0000000..ec78141 --- /dev/null +++ b/drivers/apple/adbe/rules.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + DISPLAYPIPE_BASE_ADDR=ADBE_DISPLAYPIPE_BASE_ADDR \ + WITH_DBE_ADBE=1 \ + ADBE_VERSION=$(ADBE_VERSION) + +ALL_OBJS += \ + $(LOCAL_DIR)/adbe.o + +ifeq ($(ADBE_VERSION),) + $(error "ADBE_VERSION not set") +else + ALL_OBJS += \ + $(LOCAL_DIR)/adbe_v$(ADBE_VERSION).o +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/adfe/adfe.c b/drivers/apple/adfe/adfe.c new file mode 100644 index 0000000..95d7ab8 --- /dev/null +++ b/drivers/apple/adfe/adfe.c @@ -0,0 +1,325 @@ +/* + * Copyright (C) 2009-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include "adfe_regs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Display Tunables structures */ +struct adfe_v1_tuneable { + char *name; + uint32_t disp_dpcclkcntl[2]; + uint32_t disp_dpbclklvl_clock_off_level[2]; + uint32_t disp_dpbclklvl_clock_on_level[2]; + uint32_t disp_dpusrcstrd[2]; + uint32_t disp_dpcqoscnfg[2]; + uint32_t disp_dpbqoslvl_med_watermark[2]; + uint32_t disp_dpbqoslvl_high_watermark[2]; + uint32_t disp_dpureqcfg[2]; + uint32_t disp_dpvreqcfg[2]; + uint32_t disp_dpvsrcstrd[2]; + uint32_t disp_dpcwbstrd[2]; +}; + +#include + +#ifndef DISP_VERSION +#error DISP_VERSION undefined +#endif + +static struct adfe_v1_tuneable *adfe_tuneables_info; +static const int32_t adfe_tuneables_list_size = sizeof(adfe_tuneables) / sizeof(struct adfe_v1_tuneable); + +static void adfe_irq_handler(void *arg) +{ + int which = (int)arg; + dprintf(DEBUG_INFO, "adfe_irq_handler: DPCIRQ(%d) is 0x%x -- attempting to clear\n", which, rDPCIRQ); + rDPCIRQ = rDPCIRQ; +} + +void adfe_init(struct display_timing *timing) +{ + const char *env; + int32_t cnt; + + env = env_get("adfe-tunables"); + if (env == 0) env = "default"; + + for (cnt = 0; cnt < adfe_tuneables_list_size; cnt++) { + if (strcmp(env, adfe_tuneables[cnt].name)) continue; + + adfe_tuneables_info = adfe_tuneables + cnt; + } + if (adfe_tuneables_info == 0) { + dprintf(DEBUG_INFO, "Failed to find adfe tunables info, bailing adfe_init()\n"); + return; + } + + adfe_enable_error_handler(); + +#if DISP_VERSION < 5 + // Turn on AutoMode + rDPCPFDMA |= DPCPFDMA_AUTOMODE; + + // Set FIFO DMA Burst Size to 2 Words + rDPCPFDMA = (rDPCPFDMA & ~DPCPFDMA_BURSTSIZE_MASK) | DPCPFDMA_BURSTSIZE_2WORDS; + + // Set FIFO DMA Water Mark to 0x400 + rDPCPFDMA = (rDPCPFDMA & ~DPCPFDMA_WATERMARK_MASK) | DPCPFDMA_WATERMARK(0x400); +#else + // Turn on AutoMode + rDPCPFMODE = DPCPFMODE_AUTOEN; +#endif + + // Set screen size + rDPCSIZE = (timing->h_active << 16) | (timing->v_active << 0); + + // Set the blend layer clock gating on level based on which adfe +#ifdef DISP0_BASE_ADDR + if (DISPLAYPIPE_BASE_ADDR == DISP0_BASE_ADDR) { + rDPBCLKLVL = + adfe_tuneables_info->disp_dpbclklvl_clock_off_level[0] | + adfe_tuneables_info->disp_dpbclklvl_clock_on_level[0]; + } else +#endif +#ifdef DISP1_BASE_ADDR + if (DISPLAYPIPE_BASE_ADDR == DISP1_BASE_ADDR) { + rDPBCLKLVL = + adfe_tuneables_info->disp_dpbclklvl_clock_off_level[1] | + adfe_tuneables_info->disp_dpbclklvl_clock_on_level[1]; + } else +#endif + panic("adfe_init: unsupported adfe_base_addr: %p", (void *)DISPLAYPIPE_BASE_ADDR); + +#if (DISP_VERSION < 3) + // Set blend layer panic level to 0x90 + rDPBPANLVL = 0x90; + + // Enable memory panic for blender with 5000 cycle delay + rDPCPANCNFG = DPCPANCNFG_PANENAB | DPCPANCNFG_PANBENAB | DPCPANCNFG_PANTIMER(5000); +#else +#ifdef DISP0_BASE_ADDR + if (DISPLAYPIPE_BASE_ADDR == DISP0_BASE_ADDR) { + // Set the blend QOS level + rDPBQOSLVL = + adfe_tuneables_info->disp_dpbqoslvl_med_watermark[0] | + adfe_tuneables_info->disp_dpbqoslvl_high_watermark[0]; + + // Enable memory panic + rDPCQOSCNFG = adfe_tuneables_info->disp_dpcqoscnfg[0]; + } else +#endif +#ifdef DISP1_BASE_ADDR + if (DISPLAYPIPE_BASE_ADDR == DISP1_BASE_ADDR) { + // Set the blend QOS level + rDPBQOSLVL = + adfe_tuneables_info->disp_dpbqoslvl_med_watermark[1] | + adfe_tuneables_info->disp_dpbqoslvl_high_watermark[1]; + + // Enable memory panic + rDPCQOSCNFG = adfe_tuneables_info->disp_dpcqoscnfg[1]; + } else +#endif + panic("adfe_init: unsupported adfe_base_addr: %p", (void *)DISPLAYPIPE_BASE_ADDR); + + // Set the CSC to pass through + rDPBCSCCOEFR(0) = 0x1000; + rDPBCSCCOEFG(1) = 0x1000; + rDPBCSCCOEFB(2) = 0x1000; +#endif + +#if 0 + // Enable clock gating but not in U0, U1 or V + rDPCCLKCNTL = DPCCLKCNTL_GATEENAB; +#endif +#if (DISP_VERSION > 4) + uint32_t i; +#ifdef DISP0_BASE_ADDR + if (DISPLAYPIPE_BASE_ADDR == DISP0_BASE_ADDR) { + + for (i = 0; i < 2; i ++) { + rDPCWBSTRD(i) = adfe_tuneables_info->disp_dpcwbstrd[0]; + rDPUSRCSTRD(i) = adfe_tuneables_info->disp_dpusrcstrd[0]; + rDPUREQCFG(i) = (rDPUREQCFG(i) & DPUREQCFG_CACHEHINT_MASK) | adfe_tuneables_info->disp_dpureqcfg[0]; + } + + for (i = 0; i < 3; i ++) { + rDPVREQCFG(i) = (rDPVREQCFG(i) & DPVREQCFG_CACHEHINT_MASK) | adfe_tuneables_info->disp_dpvreqcfg[0]; + rDPVSRCSTRD(i) = adfe_tuneables_info->disp_dpvsrcstrd[0]; + } + + rDPCCLKCNTL = adfe_tuneables_info->disp_dpcclkcntl[0]; + } else +#endif +#ifdef DISP1_BASE_ADDR + if (DISPLAYPIPE_BASE_ADDR == DISP1_BASE_ADDR) { + + for (i = 0; i < 2; i ++) { + rDPCWBSTRD(i) = adfe_tuneables_info->disp_dpcwbstrd[1]; + rDPUSRCSTRD(i) = adfe_tuneables_info->disp_dpusrcstrd[1]; + rDPUREQCFG(i) = (rDPUREQCFG(i) & DPUREQCFG_CACHEHINT_MASK) | adfe_tuneables_info->disp_dpureqcfg[1]; + } + + for (i = 0; i < 3; i ++) { + rDPVREQCFG(i) = (rDPVREQCFG(i) & DPVREQCFG_CACHEHINT_MASK) | adfe_tuneables_info->disp_dpvreqcfg[1]; + rDPVSRCSTRD(i) = adfe_tuneables_info->disp_dpvsrcstrd[1]; + } + + rDPCCLKCNTL = adfe_tuneables_info->disp_dpcclkcntl[1]; + } else +#endif + panic("adfe_init: unsupported adfe_base_addr: %p", (void *)DISPLAYPIPE_BASE_ADDR); +#endif + + // Set the blend pipe underrun color to red + rDPBUNDRCNFG = (2 << 30) | (0x3FF << 20); +} + +void adfe_set_ui_layer(u_int32_t layer, enum colorspace color, struct plane *plane0, struct plane *plane1, + u_int32_t width, u_int32_t height) +{ + uint32_t adfe_color; + addr_t base; + + if (layer > 1) return; + + RELEASE_ASSERT(plane0 != NULL); + + base = (addr_t)(plane0->fb_virt); + + switch (color) { + case CS_RGB565 : + adfe_color = 4; + break; + case CS_RGB888 : + adfe_color = 0; + break; + default: + panic("unsupported color 0x%x", color); + return; + } + // Set adfe color, no swap and linear frame buffer + rDPUSRCFMT(layer) = (adfe_color << 8) | (0 << 4) | (1 << 0); + + // Set base address of this layer (lower 32 bits, in case of 64 bits address) + rDPUSRCBASE(layer) = (uint32_t)(base); + + // Set stride bytes + uint32_t rmw = rDPUSRCSTRD(layer); + rmw &= ~DPUSRCSTRD_SRCSTRIDE_MASK; + rmw |= (plane0->stride & DPUSRCSTRD_SRCSTRIDE_MASK); + rDPUSRCSTRD(layer) = rmw; + +#if (DISP_VERSION >= 3) + // Set the source scale region geometry + rDPUSRCXY(layer) = 0; + rDPUSRCWH(layer) = (width << 16) | (height << 0); + // Set the destination frame geometry + rDPUDSTXY(layer) = 0; + rDPUDSTWH(layer) = (width << 16) | (height << 0); + // Enable source active region 0 + rDPUSRCRGN(layer) = (1 << 0); +#if (DISP_VERSION < 5) + // No MMU for UI requests + // This should not be done on DISP_VERSION >= 5, as it clears + // HighAddr. + rDPUMMUCNTL(layer) = 0; +#endif + // No scaling (init=0,0 step=1.0,1.0) + rDPUDDAINITX(layer) = 0; + rDPUDDAINITY(layer) = 0; + rDPUDDASTEPX(layer) = 0x100000; + rDPUDDASTEPY(layer) = 0x100000; +#endif + +#if (DISP_VERSION > 4) + rDPUMMUCNTL(layer) = ((base >> 32) & 0xf) << 4; +#endif + + // Set first region for the requested window + rDPUSRCSTRXY(layer, 0) = (0 << 16) | (0 << 0); + rDPUSRCENDXY(layer, 0) = (width << 16) | (height << 0); + + // Set blend layer 1 to pass through layer 1 + rDPBLAY1CNFG = (0xFF << 24) | (0xFF << 16) | (2 << 8) | (2 << 0); + +#if (DISP_VERSION < 3) + // Set first region enabled + rDPUSRCRGNENAB(layer) = (1 << 0); + + // Set ui layer fifo on / off levels to 0x20 / 0x60 + rDPUCLKLVL(layer) = (0x20 << 16) | (0x60 << 0); + + // Set ui layer panic level to 0x20 + rDPUPANLVL(layer) = (0x20 << 0); +#endif +} + +void adfe_enable_error_handler(void) +{ +#if (DISP_VERSION < 5) +// Error handling not implemented before version 5. +#else + rDPCIRQENAB |= DPCIRQ_MSTRERR; + install_int_handler(INT_DISP0, adfe_irq_handler, 0); + unmask_int(INT_DISP0); +#endif +} + +void adfe_disable_error_handler(void) +{ +#if (DISP_VERSION < 5) +#else + rDPCIRQENAB &= ~DPCIRQ_MSTRERR; + mask_int(INT_DISP0); +#endif +} + +void adfe_set_background_color(u_int32_t color) +{ + rDPBBACKCOLOR = color; +} + +void adfe_activate_window(void) +{ + u_int32_t layer = 0; + + if (layer > 1) return; + + // Enable the requested layer + rDPCENAB |= (1 << (layer + 8)); +#if (DISP_VERSION > 4) + // Enable VBI, its needed for AutoMode + rDPCENAB |= (1 << 0); +#endif +} + +bool adfe_get_enable(void) +{ +#if (DISP_VERSION < 5) + return (rDPCPFDMA & DPCPFDMA_AUTOMODE) != 0; +#else + return (rDPCIRQENAB & DPCIRQ_MSTRERR) != 0; +#endif +} diff --git a/drivers/apple/adfe/adfe_regs.h b/drivers/apple/adfe/adfe_regs.h new file mode 100644 index 0000000..c53ca3b --- /dev/null +++ b/drivers/apple/adfe/adfe_regs.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAYPIPE_H +#define __APPLE_DISPLAYPIPE_H + +#include + +#define rDPCVERSION (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1018)) +#define rDPCSTATE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x101C)) +#define rDPCGO (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1020)) +#define rDPCRESTART (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1024)) +#define rDPCIRQENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1028)) +#define DPCIRQ_MSTRERR (1<<11) +#define rDPCIRQ (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x102C)) +#define rDPCSIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1030)) +#define rDPCFRMCNT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1034)) +#define rDPCENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1038)) +#if DISP_VERSION < 5 +#define rDPCPFTOP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x103C)) +#endif +#define rDPCPFSIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1040)) +#define rDPCPFSTAT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1044)) +#define rDPCPFHEAD (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1048)) +#if DISP_VERSION < 5 +#define rDPCPFDMA (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104C)) +#define DPCPFDMA_AUTOMODE (1 << 4) +#define DPCPFDMA_BURSTSIZE_1WORD (0 << 8) +#define DPCPFDMA_BURSTSIZE_2WORDS (1 << 8) +#define DPCPFDMA_BURSTSIZE_4WORDS (2 << 8) +#define DPCPFDMA_BURSTSIZE_8WORDS (3 << 8) +#define DPCPFDMA_BURSTSIZE_16WORDS (4 << 8) +#define DPCPFDMA_BURSTSIZE_MASK (7 << 8) +#define DPCPFDMA_WATERMARK(n) ((n) << 16) +#define DPCPFDMA_WATERMARK_MASK (0x7FF << 16) +#else +#define rDPCPFMODE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104C)) +#define DPCPFMODE_WBEN (1 << 1) +#define DPCPFMODE_AUTOEN (1 << 0) +#endif +#define rDPCPFFLUSH (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1050)) +#define rDPCCLKCNTL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1054)) +#define DPCCLKCNTL_FLOOR(n) ((n & 0xFFFF) << 16) +#define DPCCLKCNTL_PIPE_ENABLE (1 << 12) +#define DPCCLKCNTL_LB_ENABLE (1 << 8) +#define DPCCLKCNTL_V_ENABLE (1 << 4) +#define DPCCLKCNTL_GATEENAB (1 << 0) +#define rDPCMEMACC (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1058)) + +#if (DISP_VERSION < 3) +#define rDPCPANCNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x105C)) +#define DPCPANCNFG_PANENAB (1 << 0) +#define DPCPANCNFG_PANU0ENAB (1 << 8) +#define DPCPANCNFG_PANU1ENAB (1 << 9) +#define DPCPANCNFG_PANVENAB (1 << 10) +#define DPCPANCNFG_PANBENAB (1 << 11) +#define DPCPANCNFG_PANTIMER(n) ((n) << 16) +#define DPCPANCNFG_PANTIMER_MASK (0xFFFF << 16) +#else +#define rDPCQOSCNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x105C)) +#define DPCQOSCNFG_QOS_ENABLE (1 << 0) +#define DPCQOSCNFG_UIFIFO_ENABLE (1 << 1) +#define DPCQOSCNFG_VIDFIFO_ENABLE (1 << 2) +#if (DISP_VERSION < 4) +#define DPCQOSCNFG_QOS_OPTIMISTIC (1 << 3) +#else +#define DPCQOSCNFG_QOS_OPTIMISTIC (1 << 4) +#endif +#define DPCQOSCNFG_PIPE_ENABLE (1 << 8) +#define DPCQOSCNFG_QOS_TIMER(n) ((n) << 16) +#endif + +#if (DISP_VERSION > 4) +#define rDPCWBSTRD(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x1068)) +#define DPCWBSTRD_DSTBURST_1BLOCK (0 << 0) +#define DPCWBSTRD_DSTBURST_2BLOCKS (1 << 0) +#define DPCWBSTRD_DSTBURST_4BLOCKS (2 << 0) +#define DPCWBSTRD_DSTBURST_8BLOCKS (3 << 0) +#define DPCWBSTRD_DSTBURST_MASK (3 << 0) +#define DPCWBSTRD_DSTSTRIDE_MASK (~0x3F) +#endif + +#define rDPBBACKCOLOR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x203C)) +#define rDPBLAY1CNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2040)) +#define rDPBLAY2CNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2044)) +#define rDPBLAY3CNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2048)) +#define rDPBCRCENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x204C)) +#define rDPBCRCDATA (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2050)) +#define rDPBCRCSNAP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2054)) +#define rDPBOUTSIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2058)) +#define rDPBCLKLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x205C)) +#define DPBCLKLVL_OFFLVL(n) ((n) << 0) +#define DPBCLKLVL_ONLVL(n) ((n) << 16) +#define rDPBUNDRCNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2064)) +#if (DISP_VERSION < 3) +#define rDPBPANLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2060)) +#else +#define rDPBQOSLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2060)) +#define DPBQOSLVL_MED_WATERMARK(n) ((n) << 0) +#define DPBQOSLVL_HIGH_WATERMARK(n) ((n) << 16) +#define rDPBCSCCOEFR(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x2068)) +#define rDPBCSCCOEFG(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x2074)) +#define rDPBCSCCOEFB(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x2080)) +#define rDPBCSCCOFFR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x208C)) +#define rDPBCSCCOFFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2090)) +#define rDPBCSCCOFFB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2094)) +#endif + +#if (DISP_VERSION > 4) +#define rDPVREQCFG(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x3050)) +#define DPVREQCFG_REQ_CNT(_n) ((_n) & 0xFF) +#define DPVREQCFG_CACHEHINT_MASK (7 << 8) +#endif + +#define rDPVSRCSTRD(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x3088)) +#define DPVSRCSTRD_SRCBURST_1BLOCK (0 << 0) +#define DPVSRCSTRD_SRCBURST_2BLOCKS (1 << 0) +#define DPVSRCSTRD_SRCBURST_4BLOCKS (2 << 0) +#define DPVSRCSTRD_SRCBURST_8BLOCKS (3 << 0) +#define DPVSRCSTRD_SRCBURST_MASK (3 << 0) +#define DPVSRCSTRD_SRCSTRIDE_MASK (~0x3F) + +#if (DISP_VERSION > 4) +#define rDPUREQCFG(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x403C)) +#define DPUREQCFG_REQ_CNT(_n) ((_n) & 0xFF) +#define DPUREQCFG_CACHEHINT_MASK (7 << 8) +#endif +#define rDPUSRCFMT(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4040)) +#define rDPUSRCBASE(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4044)) +#define rDPUSRCSTRD(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4048)) +#define DPUSRCSTRD_SRCBURST_1BLOCK (0 << 0) +#define DPUSRCSTRD_SRCBURST_2BLOCKS (1 << 0) +#define DPUSRCSTRD_SRCBURST_4BLOCKS (2 << 0) +#define DPUSRCSTRD_SRCBURST_8BLOCKS (3 << 0) +#define DPUSRCSTRD_SRCBURST_MASK (3 << 0) +#define DPUSRCSTRD_SRCSTRIDE_MASK (~0x3F) +#if (DISP_VERSION < 3) +#define rDPUSRCRGNENAB(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x404C)) +#define rDPUOUTSIZE(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4070)) +#define rDPUCLKLVL(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4074)) +#define rDPUPANLVL(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4078)) +#define rDPUSRCSTRXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4050 + (4 * (r)))) +#define rDPUSRCENDXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4060 + (4 * (r)))) +#else +#define rDPUSRCXY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x404C)) +#define rDPUSRCWH(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4050)) +#define rDPUDSTXY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4054)) +#define rDPUDSTWH(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4058)) +#define rDPUSRCRGN(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x405C)) +#define rDPUSRCSTRXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4060 + (4 * (r)))) +#define rDPUSRCENDXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4070 + (4 * (r)))) +#define rDPUDDAINITX(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4080)) +#define rDPUDDAINITY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4084)) +#define rDPUDDASTEPX(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4088)) +#define rDPUDDASTEPY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x408C)) +#define rDPUMMUCNTL(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4090)) +#endif + +#define rDPCPERFCNTL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6008)) +#define rDPCPERFSTAT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x600C)) +#define rDPCPERFCNFG(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6010 + (4 * (n)))) +#define rDPCPERFDATA(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6020 + (4 * (n)))) +#define rDPCPERFSNAP(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6030 + (4 * (n)))) + +#endif /* ! __APPLE_DISPLAYPIPE_H */ diff --git a/drivers/apple/adfe/include/drivers/adfe/adfe.h b/drivers/apple/adfe/include/drivers/adfe/adfe.h new file mode 100644 index 0000000..a9df17f --- /dev/null +++ b/drivers/apple/adfe/include/drivers/adfe/adfe.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_FRONTEND_H +#define __APPLE_DISPLAY_FRONTEND_H + +void adfe_init(struct display_timing *timing); +void adfe_set_ui_layer(u_int32_t pixel_pipe, enum colorspace color, struct plane *plane0, struct plane *plane1, u_int32_t width, u_int32_t height); +void adfe_enable_error_handler(void); +void adfe_disable_error_handler(void); +void adfe_set_background_color(u_int32_t color); +void adfe_activate_window(void); +bool adfe_get_enable(void); + +#endif /* __APPLE_DISPLAY_FRONTEND_H */ diff --git a/drivers/apple/adfe/rules.mk b/drivers/apple/adfe/rules.mk new file mode 100644 index 0000000..0fcc4c8 --- /dev/null +++ b/drivers/apple/adfe/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2009-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_DFE_ADFE=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/adfe.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/adfe_v2/adfe_v2.c b/drivers/apple/adfe_v2/adfe_v2.c new file mode 100644 index 0000000..533ba37 --- /dev/null +++ b/drivers/apple/adfe_v2/adfe_v2.c @@ -0,0 +1,407 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include "adfe_v2_regs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#if TARGET_USES_GP_CM || TARGET_USES_BLEND_CM +#include +#endif //TARGET_USES_GP_CM || TARGET_USES_BLEND_CM +#if WITH_SYSCFG +#include +#endif +#if WITH_DEVICETREE +#include +#endif + +struct adfe_v2_tuneable { + char *name; + uint32_t disp_dpcclkcntl; + uint32_t disp_dpcclklvl_clock_on_level; + uint32_t disp_dpcclklvl_clock_off_level; + uint32_t disp_dpcqoscfg; + uint32_t disp_dpcqosylvl_yellow_off; + uint32_t disp_dpcqosylvl_yellow_on; + uint32_t disp_dpcqosrlvl_red_off; + uint32_t disp_dpcqosrlvl_red_on; + uint32_t disp_dpclinkdown; + uint32_t disp_dpgpreqaggr; + uint32_t disp_dpcafclkgate; //ADP_VERSION > 1 + uint32_t disp_dpcenab; +}; + +#include + +#ifndef ADP_VERSION +#error ADP_VERSION undefined +#endif + +static void adfe_set_pixel_pipe_plane(u_int32_t pixel_pipe, u_int32_t plane_num, struct plane *plane); +static void adfe_gp_gamut_adjustment(u_int32_t pixel_pipe); +static void adfe_blend_gamut_adjustment(void); + +static uint8_t display_pipe; +static uint8_t gen_pixel_pipe = 0; + +static struct adfe_v2_tuneable *adfe_tuneables_info; +static const int32_t adfe_tuneables_list_size = sizeof(adfe_tuneables) / sizeof(struct adfe_v2_tuneable); + +static void adfe_irq_handler(void *arg) +{ + int which = (int)arg; + dprintf(DEBUG_INFO, "adfe_irq_handler: ADPCIRQ(%d) is 0x%x -- attempting to clear\n", which, rADPCIRQ); + rADPCIRQ = rADPCIRQ; +} + +void adfe_init(struct display_timing *timing) +{ + const char *env; + int32_t cnt; + + env = env_get("adfe-tunables"); + if (env == 0) env = "default"; + + for (cnt = 0; cnt < adfe_tuneables_list_size; cnt++) { + if (strcmp(env, adfe_tuneables[cnt].name)) continue; + + adfe_tuneables_info = adfe_tuneables + cnt; + } + if (adfe_tuneables_info == 0) { + panic("Failed to find adfe tunables info, bailing adfe_init()\n"); + } + + display_pipe = 0; + gen_pixel_pipe = 0; + +#ifdef DISP1_BASE_ADDR + if (DISPLAYPIPE_BASE_ADDR == DISP1_BASE_ADDR) { + display_pipe = 1; + gen_pixel_pipe = 0; + } +#endif //DISP1_BASE_ADDR + + adfe_enable_error_handler(); + + // Turn on AutoMode + rADPCPFMODE = ADPCPFMODE_AUTOEN | ADPCPFMODE_VBIEN; + + // Set screen size + rADPCFRAMESIZE = (timing->h_active << 16) | (timing->v_active << 0); + + // Set the pipes clock gating on level (generic to both pipes) + rADPCCLKLVL = adfe_tuneables_info->disp_dpcclklvl_clock_off_level | + adfe_tuneables_info->disp_dpcclklvl_clock_on_level; + + // Set the Memory QOS configuration + rADPCQOSCFG = adfe_tuneables_info->disp_dpcqoscfg; + + //set output FIFO QOS Yellow level + rADPCQOSYLVL = adfe_tuneables_info->disp_dpcqosylvl_yellow_on | + adfe_tuneables_info->disp_dpcqosylvl_yellow_off; + + //set output FIFO QOS Red level + rADPCQOSRLVL = adfe_tuneables_info->disp_dpcqosrlvl_red_on | + adfe_tuneables_info->disp_dpcqosrlvl_red_off; + + rADPCCLKCNTL = adfe_tuneables_info->disp_dpcclkcntl; + rADPCLINKDOWN = adfe_tuneables_info->disp_dpclinkdown; + + // Register added in Capri.. +#if ADP_VERSION > 1 + rADPCAFCLKGATE = adfe_tuneables_info->disp_dpcafclkgate; +#endif + + + // Disable CSC + rADPCCRCCTRL = 0; +} + +void adfe_set_axis_flip(uint32_t pixel_pipe, bool flipX, bool flipY) +{ + rADPGPSRCFMT(pixel_pipe) |= ((!!flipX) << 2) | ((!!flipY) << 1); +} + +// Algorithm provided by display team to do fixed point rounding. +static uint64_t fixed_to_fixed( uint64_t in, int inprec, int outprec ) +{ + long long sval = *((long long *) &in); + bool neg = sval < 0; + + if( neg ) sval = -sval; + if( outprec < inprec ) { + sval = ((sval >> (inprec - outprec - 1)) + 1) >> 1; + } else { + sval <<= outprec - inprec; + } + + if( neg ) sval = -sval; + return *((uint64_t *) &sval); +} + +/* + * The ADP has 2 Generic Pixel Pipes. These pipes process pixels from memory before entering the Blend Unit. + * A Plane is a single contigous location in memory containing pixel information + * No scaling of any component is required (i.e. DDAInitX/DDAInitY are equal to SrcX/SrcY, and all DDA steps are equal to 1). + * The Scale Region is equal to the Destination Region. + * All pixels in the scale region are also in an Active Region (ARGB formats only). + * 2DSN is disabled (YCbCr 4:4:4 formats only). + */ +void adfe_set_ui_layer(u_int32_t pixel_pipe, enum colorspace color, struct plane *plane0, struct plane *plane1, + u_int32_t width, u_int32_t height) +{ + uint8_t num_planes; + uint8_t pixel_size, pixel_fmt; + uint8_t is_ARGB; + uint32_t reg = 0; + + if (pixel_pipe > 1) return; + + switch(color) { + case CS_RGB565 : + is_ARGB = true; + pixel_size = 2; + pixel_fmt = 2; + num_planes = 1; + break; + case CS_RGB888 : + is_ARGB = true; + pixel_size = 1; + pixel_fmt = 1; + num_planes = 1; + break; + case CS_ARGB8101010 : + is_ARGB = true; + pixel_size = 3; + pixel_fmt = 0; + num_planes = 2; + break; + default: + return; + } + RELEASE_ASSERT(plane0 != NULL); + if (num_planes > 1) RELEASE_ASSERT(plane1 != NULL); + + +#if defined(__arm64__) + rADPSMMU_BYPASS_ADDR = (((((addr_t)plane0->fb_virt) >> 32) & 0xF) << 8); +#endif + rADPSMMU_DIAG_BOGUS_ACCESS = 0x20ffff; + + rADPDART_DIAG_CONFIG = 0x100; + rADPDART_DIAG_BOGUS_ACCESS = 0x20ffff; + rADPDART_FETCH_REQ_CONFIG = 0xe0303; + + // Set displaypixel_pipe color, no swap and linear frame buffer + reg = rADPGPSRCFMT(pixel_pipe); + //clean up the fields we are about to set + reg &= ~((0x3 << 26) | (0x3 << 24) | (1 << 22) | (1 << 21) | (1 << 20) | (0x1f << 4) | (1 << 0)); + reg |= (pixel_fmt << 26) | (pixel_size << 24) | ((num_planes - 1 ) << 22) | (is_ARGB << 21) | (0 << 4) | (1 << 0); + rADPGPSRCFMT(pixel_pipe) = reg; + + adfe_set_pixel_pipe_plane(pixel_pipe, 0, plane0); + if (num_planes > 1) { + adfe_set_pixel_pipe_plane(pixel_pipe, 1, plane1); + } + + // Enable source active region 0 + rADPGPSRCCFG(pixel_pipe) = (1 << 0); + + // Set the destination frame geometry + rADPGPDSTXY(pixel_pipe) = 0; + rADPGPDSTWH(pixel_pipe) = (width << 16) | (height << 0); + + //No Scale Mode + rADPGPCFG(pixel_pipe) = ADPGPCFG_NO_SCALE; + + //Dithering off + rADPGPNOISECFG(pixel_pipe) = 0; + + //No color Space Conversion + rADPGPCSCCFG(pixel_pipe)= ADPGPCSCCFG_CSC_BYPASS; + + // No Color Management + rADPGPCMCFG(pixel_pipe)= ADPGPCMCFG_CM_BYPASS; + + //Bypass Color space conversion + rADPBCSCCFG = ADPBCSCCFG_CSCBYPASS; + + adfe_gp_gamut_adjustment(pixel_pipe); + + // Bypass Blend Color Management + rADPBCMCFG = ADPBCMCFG_CMBYPASS; + + //Tunable + rADPGPREQAGGR(pixel_pipe, 0) = adfe_tuneables_info->disp_dpgpreqaggr; + + rADPGPREQAGGR(pixel_pipe, 1) = adfe_tuneables_info->disp_dpgpreqaggr; + + //No Need for Blend +#define BLEND_BYPASS 1 +#if BLEND_BYPASS + rADPBCFG = ADPBCFG_BLEND_BYPASS; +#endif //BLEND_BYPASS + rADPBLAYCFG(pixel_pipe) = (1 << 4) | (pixel_pipe << 0); + rADPBLAYCFG(1-pixel_pipe) = (0 << 4) | ((1-pixel_pipe) << 0); + //rADPBBACKCOLOR = 0xf; + + adfe_blend_gamut_adjustment(); + +} + +static void adfe_set_pixel_pipe_plane(u_int32_t pixel_pipe, u_int32_t plane_num, struct plane *plane) +{ + // Set base address of this pixel_pipe (lower 32 bits, in case of 64 bits address) + rADPGPSRCBASE(pixel_pipe, plane_num) = (uint32_t)plane->fb_virt; + + // Set burst size and stride bytes + rADPGPSRCSTRD(pixel_pipe, plane_num) = plane->stride; + + // Set the source scale region geometry + rADPGPSRCXY(pixel_pipe, plane_num) = 0; + rADPGPSRCWH(pixel_pipe, plane_num) = (plane->width << 16) | (plane->height << 0); + + //Note that if the pipe is being used in No Scale or Scaler Bypass mode DdaInitX must equal SrcX + rADPGPDDAINITX(pixel_pipe, plane_num) = 0; + rADPGPDDASTEPX(pixel_pipe, plane_num) = 0x100000; + //Note that if the pipe is being used in No Scale or Scaler Bypass mode DdaInitY must equal SrcY + rADPGPDDAINITY(pixel_pipe, plane_num) = 0; + rADPGPDDASTEPY(pixel_pipe, plane_num) = 0x100000; + + // Set first region for the requested window + rADPGPSRCACTXY(pixel_pipe, plane_num) = (0 << 16) | (0 << 0); + rADPGPSRCACTWH(pixel_pipe, plane_num) = (plane->width << 16) | (plane->height << 0); +} + +void adfe_enable_error_handler(void) +{ + rADPCIRQENAB |= ADPCIRQ_OUTUNDERIRQ; + install_int_handler(INT_DISP0, adfe_irq_handler, 0); + unmask_int(INT_DISP0); +} + +void adfe_disable_error_handler(void) +{ + rADPCIRQENAB &= ~ADPCIRQ_OUTUNDERIRQ; + mask_int(INT_DISP0); +} + +void adfe_set_background_color(u_int32_t color) +{ + rADPBBACKCOLOR = color; +} + +void adfe_activate_window(void) +{ + if (gen_pixel_pipe > 1) return; + + //Set SID to bypass due to + // SMMU Configuration Timing + // Enable the requested generic pixel pipe + rADPCENAB = adfe_tuneables_info->disp_dpcenab | ADPCENAB_SIDSEL_BYPASS | (1 << (gen_pixel_pipe * 4)); +} + +bool adfe_get_enable(void) +{ + return (rADPCIRQENAB & ADPCIRQ_OUTUNDERIRQ) != 0; +} + +static void adfe_blend_gamut_adjustment(void) +{ +#if TARGET_USES_BLEND_CM +#if WITH_SYSCFG + struct primary_calibration_matrix { + uint32_t version; + uint32_t matrix[3][3]; + }; + + struct primary_calibration_matrix pcm; + + if (syscfgCopyDataForTag('DPCl', (u_int8_t *)&pcm, sizeof(pcm)) > 0) { + + int row, col; + + //Program degamma LUT + for (row = 0; row < ADP_CM_DEGAMMA_PAIRED_LUT_SIZE; row++) { + rADPBDEGAMMATABLE(row) = target_blend_degamma_tables[row]; + } + + //Program Linear Degamma + rADPBDEGAMMALINEAR = target_blend_degamma_tables[row]; + + for(row = 0; row < 3; row ++) { + for(col = 0; col < 3; col++) { + // Convert from 8.24 to 4.12 + rADPBCMCOEF(row, col) = (uint32_t)(fixed_to_fixed( pcm.matrix[row][col], 24, 12 ) & 0xFFFF); + } + } + + for (row = 0; row < ADP_CM_ENGAMMA_PAIRED_LUT_SIZE; row++) { + rADPBGAMMATABLE_R(row) = target_blend_engamma_tables[row]; + rADPBGAMMATABLE_G(row) = target_blend_engamma_tables[row]; + rADPBGAMMATABLE_B(row) = target_blend_engamma_tables[row]; + } + + rADPBGAMMALINEAR_R = target_blend_engamma_tables[row]; + rADPBGAMMALINEAR_G = target_blend_engamma_tables[row]; + rADPBGAMMALINEAR_B = target_blend_engamma_tables[row]; + + // Turn off Blend Color Management Bypass + rADPBCMCFG &= ~ADPBCMCFG_CMBYPASS; + } +#endif +#endif +} + +static void adfe_gp_gamut_adjustment(u_int32_t pixel_pipe) +{ +#if TARGET_USES_GP_CM + int col; + int row; + + //Program degamma LUT + for (row = 0; row < ADP_CM_DEGAMMA_PAIRED_LUT_SIZE; row++) { + rADPGPDEGAMMATABLE(pixel_pipe, row) = target_gp_degamma_tables[row]; + } + + //Program Linear Degamma + rADPGPDEGAMMALINEAR(pixel_pipe) = target_gp_degamma_tables[row]; + + for(row = 0; row < 3; row ++ ) { + for(col = 0; col < 3; col ++ ) { + rADPGPCMCOEF(pixel_pipe, row, col) = target_gp_csc_matrix[row][col]; + } + } + + for (row = 0; row < ADP_CM_ENGAMMA_PAIRED_LUT_SIZE; row++) { + rADPGPGAMMATABLE(pixel_pipe, row) = target_gp_engamma_tables[row]; + } + + rADPGPGAMMALINEAR(pixel_pipe) = target_gp_engamma_tables[row]; + + //Unbypass the gamut adjustment block + rADPGPCMCFG(pixel_pipe) &= ~ADPGPCMCFG_CM_BYPASS; + +#endif //TARGET_USES_GP_CM +} diff --git a/drivers/apple/adfe_v2/adfe_v2_regs.h b/drivers/apple/adfe_v2/adfe_v2_regs.h new file mode 100644 index 0000000..56b1ca5 --- /dev/null +++ b/drivers/apple/adfe_v2/adfe_v2_regs.h @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_FRONTEND_REGS_H +#define __APPLE_DISPLAY_FRONTEND_REGS_H + +#include + +//General control registers +#define rADPCSPARE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1000)) +#define rADPCVERSION (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1018)) +#define rADPCSTATE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x101c)) +#define rADPCGO (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1020)) +#define rADPCRESTART (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1024)) +#define rADPCIRQENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1028)) +#define ADPCIRQ_WBPARTIRQ (1 << 14) +#define ADPCIRQ_WBCMPLIRQ (1 << 13) +#define ADPCIRQ_WRERRIRQ (1 << 12) +#define ADPCIRQ_RDERRIRQ (1 << 1) +#define ADPCIRQ_PFPROCIRQ (1 << 10) +#define ADPCIRQ_PFOVERIRQ (1 << 9) +#define ADPCIRQ_PFHDRIRQ (1 << 8) +#define ADPCIRQ_PFEMPTYIRQ (1 << 7) +#define ADPCIRQ_PFALIGNIRQ (1 << 6) +#define ADPCIRQ_PFREPEATIRQ (1 << 5) +#define ADPCIRQ_PFSYNCIRQ (1 << 4) +#define ADPCIRQ_PFMISSIRQ (1 << 3) +#define ADPCIRQ_PFUNDERIRQ (1 << 2) +#define ADPCIRQ_OUTUNDERIRQ (1 << 1) +#define ADPCIRQ_VBIIRQ (1 << 0) +#define rADPCIRQ (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x102c)) +#define rADPCFRAMESIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1030)) +#define rADPCFRMCNT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1034)) +#define rADPCENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1038)) +#define ADPCENAB_IDEAL_ARB_ENAB (1 << 16) +#define ADPCENAB_SIDSEL_BYPASS (1 << 12) +#define rADPCPFSIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x103c)) +#define rADPCPFSTAT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1040)) +#define rADPCPFHEAD (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1044)) +#define rADPCPFMODE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1048)) +#define ADPCPFMODE_AUTOEN (1 << 0) +#define ADPCPFMODE_VBIEN (1 << 4) +#define rADPCPFFLUSH (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104c)) +#define rADPCCLKCNTL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1050)) +#define ADPCCLKCNTL_FLOOR(n) ((n) << 16) +#define ADPCCLKCNTL_PIPE_ENABLE (1 << 8) +#define ADPCCLKCNTL_LB_ENABLE (1 << 4) +#define ADPCCLKCNTL_PIO_GATE_ENABLE (1 << 3) +#define ADPCCLKCNTL_STAT_GATE_ENABLE (1 << 2) +#define ADPCCLKCNTL_EXT_GATE_ENABLE (1 << 1) +#define ADPCCLKCNTL_DYN_GATE_ENABLE (1 << 0) +#define rADPCCLKLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1054)) +#define ADPCCLKLVL_ONLVL(n) ((n) << 16) +#define ADPCCLKLVL_OFFLVL(n) ((n) << 0) +#define rADPCQOSCFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1058)) +#define ADPCQOSCFG_QOS_TIMER(n) ((n) << 16) +#define ADPCQOSCFG_PIPE_ENABLE (1 << 8) +#define ADPCQOSCFG_MINLVL_ENABLE (1 << 6) +#define ADPCQOSCFG_MON_MODE (1 << 5) +#define ADPCQOSCFG_MON_ENABLE (1 << 4) +#define ADPCQOSCFG_QOS_ENABLE (1 << 0) +#define rADPCQOSYLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x105c)) +#define ADPCQOSYLVL_YELLOW_OFF(n) ((n) << 16) +#define ADPCQOSYLVL_YELLOW_ON(n) ((n) << 0) +#define rADPCQOSRLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1060)) +#define ADPCQOSRLVL_RED_OFF(n) ((n) << 16) +#define ADPCQOSRLVL_RED_ON(n) ((n) << 0) +#define rADPCQOSGSNAP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1064)) +#define rADPCQOSYSNAP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1068)) +#define rADPCQOSRSNAP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x106c)) +#define rADPCQOSMINLVLSNAP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1070)) +#define rADPCCRCCTRL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1074)) +#define rADPCLINKDOWN (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1078)) +#define ADPCLINKDOWN_TEARDOWNNOSCL (1 << 8) +#define ADPCLINKDOWN_TEARDOWNAGGR (1 << 4) +#define ADPCLINKDOWN_TEARDOWNEN (1 << 0) +#if ADP_VERSION > 1 +#define rADPCAFCLKGATE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x107C)) +#define ADPAFIDLECOUNT(n) ((n) << 16) +#define ADPAFDYNCLKGATEEN (1 << 0) +#endif +#define rADPCPFTOP(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x10c0 + (4 * (n)))) + +//Blend Unit registers +#define rADPBSPARE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2000)) +#define rADPBCFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2020)) +#define ADPBCFG_BLEND_BYPASS (1 << 0) +#define rADPBBACKCOLOR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2024)) +#define rADPBLAYCFG(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2028 + (4 * (n)))) +#define rADPBCRCDATA (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2030)) +#define rADPBCSCCFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2034)) +#define ADPBCSCCFG_CSCBYPASS (1 << 0) +#define rADPBCSCINOFF(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2038 + (4 * (n)))) +#define rADPBCSCCOEF(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2044 + (12 * (p)) + (4 * (n)))) +#define rADPBCSCOUTOFF(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2068 + (4 * (n)))) +#define rADPBCMCFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2074)) +#define ADPBCMCFG_CMBYPASS (1 << 0) +#define rADPBDEGAMMALINEAR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2078)) +#define rADPBCMCOEF(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x207c + (12 * (p)) + (4 * (n)))) +#define rADPBGAMMALINEAR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x20a0)) +#define rADPBGAMMALINEAR_R (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x20a0)) +#define rADPBGAMMALINEAR_G (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x20a4)) +#define rADPBGAMMALINEAR_B (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x20a8)) +#define rADPBOUTFIFODEPTH (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x20ac)) +#define rADPBDEGAMMATABLE(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2200 + (4 * (n)))) +#define rADPBGAMMATABLE(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2800 + (4 * (n)))) +#define rADPBGAMMATABLE_R(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2800 + (4 * (n)))) +#define rADPBGAMMATABLE_G(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x3000 + (4 * (n)))) +#define rADPBGAMMATABLE_B(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x3800 + (4 * (n)))) + +//Generic Pipe registers +#define rADPGPSPARE(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4000 + ((p) * 0x2000))) +#define rADPGPCFG(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4020 + ((p) * 0x2000))) +#define ADPGPCFG_SCALE_BYPASS (1 << 4) +#define ADPGPCFG_NO_SCALE (1 << 0) +#define rADPGPREQAGGR(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4024 + ((p) * 0x2000) + (4 * (n)))) +#define ADPGPREQARRG_CACHEHINT_MASK (0x0F0000) +#define ADPGPREQAGGR_CACHEHINT(n) ((n) << 16) +#define ADPGPREQAGGR_REQAGGRTHRESH(n) ((n) << 4) +#define ADPGPREQARRG_OPPORTUNISMENAB (1 << 1) +#define ADPGPREQAGGR_REQAGGRENAB (1 << 0) +#define rADPGPSRCFMT(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x402c + ((p) * 0x2000))) +#define rADPGPSRCBASE(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4030 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPSRCSTRD(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4038 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPSRCXY(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4040 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPSRCWH(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4048 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPDSTXY(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4050 + ((p) * 0x2000))) +#define rADPGPDSTWH(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4054 + ((p) * 0x2000))) +#define rADPGPTBEDGEALPHA(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4058 + ((p) * 0x2000))) +#define rADPGPLREDGEALPHA(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x405c + ((p) * 0x2000))) +#define rADPGPTCEDGEALPHA(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4060 + ((p) * 0x2000))) +#define rADPGPBCEDGEALPHA(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4064 + ((p) * 0x2000))) +#define rADPGPSRCCFG(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4068 + ((p) * 0x2000))) +#define rADPGPSRCACTXY(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x406c + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPSRCACTWH(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x407c + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPNOISECFG(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x408c + ((p) * 0x2000))) +#define rADPGPNOISELFSR(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4090 + ((p) * 0x2000))) +#define rADPGPDDAINITX(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4094 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPDDASTEPX(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x409c + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPDDAINITY(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40a4 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPDDASTEPY(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40ac + ((p) * 0x2000) + (4 * (n)))) + +#define rADPGPCSCCFG(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40b4 + ((p) * 0x2000))) +#define ADPGPCSCCFG_CSC_BYPASS (1 << 0) +#define rADPGPCSCINOFF(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40b8 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPCSCCOEF(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40c4 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPCSCOUTOFF(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40e8 + ((p) * 0x2000) + (4 * (n)))) + +#define rADPGPCMCFG(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40f4 + ((p) * 0x2000))) +#define ADPGPCMCFG_CM_BYPASS (1 << 0) +#define rADPGPDEGAMMALINEAR(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40f8 + ((p) * 0x2000))) +#define rADPGPCMCOEF(p, r, c) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x40fc + ((p) * 0x2000) + ((r) * 0xc) + (4 * (c)))) + +#define rADPGPGAMMALINEAR(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4120 + ((p) * 0x2000))) +#define rADPGPCRCCTRL(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4124 + ((p) * 0x2000))) +#define rADPGPCRCDATA(p) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4128 + ((p) * 0x2000))) +#define rADPGPINVDDASTEPX(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x412c + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPDEGAMMATABLE(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4200 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPGAMMATABLE(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x4800 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPCOEFX(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x5000 + ((p) * 0x2000) + (4 * (n)))) +#define rADPGPCOEFY(p, n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x5800 + ((p) * 0x2000) + (4 * (n)))) + +//DP Noise RAM Registers +#define rADPNOISEARRAY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x8000 + (4 * (n))) + +//DP Write Back Registers +#define rADPWBSPARE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9000)) +#define rADPWBBASE(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9020 + (4 * (n)))) +#define rADPWBSTRD(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9028 + (4 * (n)))) +#define rADPWBCNTL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9030)) +#define rADPWBCHROMADOWN (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9034)) +#define rADPWBLINECNT(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9038 + (4 * (n)))) +#define rADP_DITHER_SKEW0 (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9040)) +#define rADP_DITHER_SKEW1 (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9044)) +#define rADP_DITHER_SKEW2 (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x9048)) +#define rADP_DITHER_KERNEL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x904c)) + +//SMMU Registers +#define rADPSMMU_CONFIG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x10000c)) +#define rADPSMMU_ERR_STATUS (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x100010)) +#define rADPSMMU_ERR_AXI_REQ0 (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x100014)) +#define rADPSMMU_ERR_AXI_REQ1 (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x100018)) +#define rADPSMMU_ERR_ADDRESS (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x10001c)) +#define rADPSMMU_DIAG_CONFIG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x100020)) +#define rADPSMMU_DIAG_BOGUS_ACCESS (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x100024)) +#define rADPSMMU_BYPASS_ADDR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x10002c)) +#define rADPSMMU_ERR_STTIDX (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x100030)) +#define rADPSMMU_REQ_SCOREBOARD(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x100080 + ((n) * 4)) +#define rADPSMMU_ACK_SCOREBOARD(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1000c0 + ((n) * 4)) +#define rADPSMMU_PERF_CONFIG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x101000)) +#define rADPSMMU_CTR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x101004)) +#define rADPSMMU_STT_PA_DATA (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x102000)) + +//DART Registers +#define rADPDART_DIAG_CONFIG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104020)) +#define rADPDART_DIAG_BOGUS_ACCESS (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104024)) +#define rADPDART_FETCH_REQ_CONFIG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104030)) + +#endif /* ! __APPLE_DISPLAY_FRONTEND_REGS_H */ diff --git a/drivers/apple/adfe_v2/include/drivers/adfe_v2/adfe.h b/drivers/apple/adfe_v2/include/drivers/adfe_v2/adfe.h new file mode 100644 index 0000000..2cbd772 --- /dev/null +++ b/drivers/apple/adfe_v2/include/drivers/adfe_v2/adfe.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_FRONTEND_H +#define __APPLE_DISPLAY_FRONTEND_H + +void adfe_init(struct display_timing *timing); +void adfe_set_ui_layer(u_int32_t pixel_pipe, enum colorspace color, struct plane *plane0, struct plane *plane1, u_int32_t width, u_int32_t height); +void adfe_enable_error_handler(void); +void adfe_disable_error_handler(void); +void adfe_set_background_color(u_int32_t color); +void adfe_activate_window(void); +bool adfe_get_enable(void); +void adfe_set_axis_flip(uint32_t pixel_pipe, bool flipX, bool flipY); + +#endif /* __APPLE_DISPLAY_FRONTEND_H */ diff --git a/drivers/apple/adfe_v2/rules.mk b/drivers/apple/adfe_v2/rules.mk new file mode 100644 index 0000000..2a44be2 --- /dev/null +++ b/drivers/apple/adfe_v2/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_DFE_ADFE_V2=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/adfe_v2.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/aes/aes_ap.c b/drivers/apple/aes/aes_ap.c new file mode 100644 index 0000000..b7571fa --- /dev/null +++ b/drivers/apple/aes/aes_ap.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include + +#include "aes_ap.h" + +void _load_input_block(const uint32_t *src); +void _store_output_block(uint32_t *dst); + +#if AES_AP_VERSION < 1 + +void +aes_ap_disable_keys(uint32_t gid, uint32_t uid) +{ + uint32_t keydis = (((gid & AES_DIS_GID_MASK) << AES_DIS_SET_GID_SHIFT) | ((uid & AES_DIS_UID_MASK) << AES_DIS_SET_UID_SHIFT)); + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return; + + clock_gate(CLK_AES0, true); + rAES_AP_DIS = keydis; + clock_gate(CLK_AES0, false); +} + +bool +aes_ap_keys_disabled(uint32_t gid, uint32_t uid) +{ + uint32_t key_disabled; + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return true; + + clock_gate(CLK_AES0, true); + key_disabled = rAES_AP_DIS; + clock_gate(CLK_AES0, false); + + return (key_disabled & ((gid & AES_DIS_GID_MASK) << AES_DIS_GID_SHIFT)) && (key_disabled & ((uid & AES_DIS_UID_MASK) << AES_DIS_UID_SHIFT)); +} + +#endif // AES_AP_VERSION < 1 + +int +aes_hw_crypto_cmd(u_int32_t cmd, void *src, void *dst, size_t len, u_int32_t opts, const void *key, void *iv) +{ + uint32_t key_in_ctrl; + uint32_t blocks; + uint32_t *local_src, *local_dst, *local_iv, *local_key; + + dprintf(DEBUG_SPEW, "aes_hw_crypto_cmd: cmd: %08x, src: %p, dst: %p, len: %08zx, opts: %08x, key: %p, iv: %p \n", + cmd, src, dst, len, opts, key, iv); + + clock_gate(CLK_AES0, true); + + ASSERT(src != NULL); + ASSERT(dst != NULL); + + local_src = (uint32_t *)src; + local_dst = (uint32_t *)dst; + local_iv = (uint32_t *)iv; + local_key = (uint32_t *)key; + + /* Make sure length is multiple of 16 bytes */ + ASSERT((len > 0) && ((len & 0xf) == 0)); + blocks = len / 16; + + key_in_ctrl = 0; + + switch (cmd & AES_CMD_MODE_MASK) { + case AES_CMD_ECB : key_in_ctrl |= KEY_IN_CTRL_MOD_ECB; break; + case AES_CMD_CBC : key_in_ctrl |= KEY_IN_CTRL_MOD_CBC; break; + default : goto fail; + } + + switch (cmd & AES_CMD_DIR_MASK) { + case AES_CMD_ENC : key_in_ctrl |= KEY_IN_CTRL_DIR_ENC; break; + case AES_CMD_DEC : key_in_ctrl |= KEY_IN_CTRL_DIR_DEC; break; + default : goto fail; + } + + /* Get the key length */ + switch (opts & AES_KEY_SIZE_MASK) { + case AES_KEY_SIZE_128 : key_in_ctrl |= KEY_IN_CTRL_LEN_128; break; + case AES_KEY_SIZE_192 : key_in_ctrl |= KEY_IN_CTRL_LEN_192; break; + case AES_KEY_SIZE_256 : key_in_ctrl |= KEY_IN_CTRL_LEN_256; break; + default : goto fail; + } + + /* Set the key */ + switch (opts & AES_KEY_TYPE_MASK) { + case AES_KEY_TYPE_USER : + key_in_ctrl |= KEY_IN_CTRL_SEL_SW; + + switch (opts & AES_KEY_SIZE_MASK) { + default: + rAES_AP_KEY_IN7 = local_key[7]; + rAES_AP_KEY_IN6 = local_key[6]; + case AES_KEY_SIZE_192: + rAES_AP_KEY_IN5 = local_key[5]; + rAES_AP_KEY_IN4 = local_key[4]; + case AES_KEY_SIZE_128: + rAES_AP_KEY_IN3 = local_key[3]; + rAES_AP_KEY_IN2 = local_key[2]; + rAES_AP_KEY_IN1 = local_key[1]; + rAES_AP_KEY_IN0 = local_key[0]; + } + break; + + case AES_KEY_TYPE_UID0 : key_in_ctrl |= KEY_IN_CTRL_SEL_UID1; break; + case AES_KEY_TYPE_GID0 : key_in_ctrl |= KEY_IN_CTRL_SEL_GID0; break; + case AES_KEY_TYPE_GID1 : key_in_ctrl |= KEY_IN_CTRL_SEL_GID1; break; + } + + /* Make sure the requested key is not disabled */ + if (((opts & AES_KEY_TYPE_MASK) != AES_KEY_TYPE_USER) && ((rAES_AP_DIS & (opts & AES_KEY_TYPE_MASK)) == (opts & AES_KEY_TYPE_MASK))) { + dprintf(DEBUG_INFO, "SIO_AES: requested AES key has been disabled\n"); + return -1; + } + + /* Make sure AES block is not busy */ + ASSERT(rAES_AP_KEY_IN_STS & KEY_IN_STS_RDY); + ASSERT(rAES_AP_TXT_IN_STS & TXT_IN_STS_RDY); + ASSERT(!(rAES_AP_TXT_OUT_STS & TXT_OUT_STS_VAL_SET)); + + /* Setup Key configurator, and load the context */ + rAES_AP_KEY_IN_CTRL = key_in_ctrl; + rAES_AP_KEY_IN_CTRL |= KEY_IN_CTRL_VAL_SET; + + dprintf(DEBUG_SPEW, "sio_aes: key_in_ctrl:0x%08x, rAES_AP_KEY_IN_CTRL:0x%08x\n", key_in_ctrl, rAES_AP_KEY_IN_CTRL); + + /* Load IV */ + if (iv != 0) { + rAES_AP_IV_IN0 = local_iv[0]; + rAES_AP_IV_IN1 = local_iv[1]; + rAES_AP_IV_IN2 = local_iv[2]; + rAES_AP_IV_IN3 = local_iv[3]; + } else { + rAES_AP_IV_IN0 = 0; + rAES_AP_IV_IN1 = 0; + rAES_AP_IV_IN2 = 0; + rAES_AP_IV_IN3 = 0; + } + rAES_AP_IV_IN_CTRL = (0 << IV_IN_CTRL_CTX_SHIFT); + rAES_AP_IV_IN_CTRL |= IV_IN_CTRL_VAL_SET; + + /* Perform AES operation */ + + /* Load first block */ + _load_input_block(local_src); + rAES_AP_TXT_IN_CTRL = ((0 << TXT_IN_CTRL_IV_CTX_SHIFT) | (0 << TXT_IN_CTRL_KEY_CTX_SHIFT) | TXT_IN_CTRL_VAL_SET); + while(--blocks) { + /* Wait until we can shove next block in */ + while ((rAES_AP_TXT_IN_STS & TXT_IN_STS_RDY) != TXT_IN_STS_RDY); + + /* Load next block */ + local_src += 4; + _load_input_block(local_src); + rAES_AP_TXT_IN_CTRL = ((0 << TXT_IN_CTRL_IV_CTX_SHIFT) | (0 << TXT_IN_CTRL_KEY_CTX_SHIFT)); + rAES_AP_TXT_IN_CTRL |= TXT_IN_CTRL_VAL_SET; + + /* Store result of the previous operation */ + while ((rAES_AP_TXT_OUT_STS & TXT_OUT_STS_VAL_SET) != TXT_OUT_STS_VAL_SET); + _store_output_block(local_dst); + local_dst += 4; + } + /* Store result of the last operation */ + while ((rAES_AP_TXT_OUT_STS & TXT_OUT_STS_VAL_SET) != TXT_OUT_STS_VAL_SET); + _store_output_block(local_dst); + + /* Clear user key from the registers */ + if ((opts & AES_KEY_TYPE_MASK) == AES_KEY_TYPE_USER) { + rAES_AP_KEY_IN7 = 0; + rAES_AP_KEY_IN6 = 0; + rAES_AP_KEY_IN5 = 0; + rAES_AP_KEY_IN4 = 0; + rAES_AP_KEY_IN3 = 0; + rAES_AP_KEY_IN2 = 0; + rAES_AP_KEY_IN1 = 0; + rAES_AP_KEY_IN0 = 0; + } + + clock_gate(CLK_AES0, false); + + return 0; + +fail: + panic("SIO_AES: bad arguments\n"); +} + +void _load_input_block(const uint32_t *src) +{ + dprintf(DEBUG_SPEW, "src: "); + for(int i = 0; i < 4; i++) dprintf(DEBUG_SPEW, "%08x ", src[i]); + dprintf(DEBUG_SPEW, "\n"); + + rAES_AP_TXT_IN0 = src[0]; + rAES_AP_TXT_IN1 = src[1]; + rAES_AP_TXT_IN2 = src[2]; + rAES_AP_TXT_IN3 = src[3]; +} + +void _store_output_block(uint32_t *dst) +{ + dst[0] = rAES_AP_TXT_OUT0; + dst[1] = rAES_AP_TXT_OUT1; + dst[2] = rAES_AP_TXT_OUT2; + dst[3] = rAES_AP_TXT_OUT3; + + dprintf(DEBUG_SPEW, "dst: "); + for(int i = 0; i < 4; i++) dprintf(DEBUG_SPEW, "%08x ", dst[i]); + dprintf(DEBUG_SPEW, "\n"); +} diff --git a/drivers/apple/aes/aes_ap.h b/drivers/apple/aes/aes_ap.h new file mode 100644 index 0000000..8789024 --- /dev/null +++ b/drivers/apple/aes/aes_ap.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_AES_AP_H +#define __APPLE_AES_AP_H + +#include + +/* AES-AP registers */ + +#define rAES_AP_STS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0000)) +#define STS_BUSY (1U << 0) + +#define rAES_AP_DIS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0004)) +#define AES_DIS_GID1 (1U << 10) +#define AES_DIS_GID0 (1U << 9) +#define AES_DIS_UID1 (1U << 8) +#define AES_DIS_GID_SHIFT (9) +#define AES_DIS_UID_SHIFT (8) +#define AES_DIS_SET_DSB (1U << 3) +#define AES_DIS_SET_GID1 (1U << 2) +#define AES_DIS_SET_GID0 (1U << 1) +#define AES_DIS_SET_UID1 (1U << 0) +#define AES_DIS_SET_GID_SHIFT (1) +#define AES_DIS_SET_UID_SHIFT (0) +#define AES_DIS_GID_MASK (0x3) +#define AES_DIS_UID_MASK (0x1) + +#define rAES_AP_TXT_IN_CTRL (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0008)) +#define TXT_IN_CTRL_IV_CTX_SHIFT (2) +#define TXT_IN_CTRL_KEY_CTX_SHIFT (1) +#define TXT_IN_CTRL_VAL_SET (1U << 0) + +#define rAES_AP_TXT_IN_STS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x000C)) +#define TXT_IN_STS_RDY (1U << 0) + +#define rAES_AP_TXT_IN0 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0040)) +#define rAES_AP_TXT_IN1 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0044)) +#define rAES_AP_TXT_IN2 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0048)) +#define rAES_AP_TXT_IN3 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x004C)) + +#define rAES_AP_TXT_OUT_STS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0050)) +#define TXT_OUT_STS_IV_CTX_SHIFT (2) +#define TXT_OUT_STS_KEY_CTX_SHIFT (1) +#define TXT_OUT_STS_VAL_SET (1U << 0) + +#define rAES_AP_TXT_OUT0 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0080)) +#define rAES_AP_TXT_OUT1 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0084)) +#define rAES_AP_TXT_OUT2 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0088)) +#define rAES_AP_TXT_OUT3 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x008C)) + +#define rAES_AP_KEY_IN_CTRL (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0090)) +#define KEY_IN_CTRL_MOD_CBC (1U << 13) +#define KEY_IN_CTRL_MOD_ECB (0U << 13) +#define KEY_IN_CTRL_DIR_ENC (1U << 12) +#define KEY_IN_CTRL_DIR_DEC (0U << 12) +#define KEY_IN_CTRL_LEN_256 (2U << 6) +#define KEY_IN_CTRL_LEN_192 (1U << 6) +#define KEY_IN_CTRL_LEN_128 (0U << 6) +#define KEY_IN_CTRL_SEL_GID1 (3U << 4) +#define KEY_IN_CTRL_SEL_GID0 (2U << 4) +#define KEY_IN_CTRL_SEL_UID1 (1U << 4) +#define KEY_IN_CTRL_SEL_SW (0U << 4) +#define KEY_IN_CTRL_CTX_SHIFT (1) +#define KEY_IN_CTRL_VAL_SET (1U << 0) + +#define rAES_AP_KEY_IN_STS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0094)) +#define KEY_IN_STS_RDY (1U << 0) + +#define rAES_AP_KEY_IN0 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00C0)) +#define rAES_AP_KEY_IN1 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00C4)) +#define rAES_AP_KEY_IN2 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00C8)) +#define rAES_AP_KEY_IN3 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00CC)) +#define rAES_AP_KEY_IN4 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00D0)) +#define rAES_AP_KEY_IN5 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00D4)) +#define rAES_AP_KEY_IN6 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00D8)) +#define rAES_AP_KEY_IN7 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00DC)) + +#define rAES_AP_IV_IN_CTRL (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x00E0)) +#define IV_IN_CTRL_CTX_SHIFT (1) +#define IV_IN_CTRL_VAL_SET (1U << 0) + +#define rAES_AP_IV_IN0 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0100)) +#define rAES_AP_IV_IN1 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0104)) +#define rAES_AP_IV_IN2 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x0108)) +#define rAES_AP_IV_IN3 (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x010C)) + +/* rAES_AP_IV_OUTxxxx to rAES_AP_DSB_xxxx */ + +#define rAES_AP_ERR (*(volatile uint32_t *)(AES_AP_BASE_ADDR + 0x01D0)) +#define AES_ERR_SET (1U << 0) + +#endif /* __APPLE_AES_AP_H */ diff --git a/drivers/apple/aes/rules.mk b/drivers/apple/aes/rules.mk new file mode 100644 index 0000000..a790b1e --- /dev/null +++ b/drivers/apple/aes/rules.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AES=1 + +MODULES += \ + drivers/aes + +ALL_OBJS += \ + $(LOCAL_DIR)/aes_ap.o diff --git a/drivers/apple/aes_s7002/aes_s7002.c b/drivers/apple/aes_s7002/aes_s7002.c new file mode 100644 index 0000000..d1086a0 --- /dev/null +++ b/drivers/apple/aes_s7002/aes_s7002.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "aes_s7002.h" + +void _load_input_block(const uint32_t *src); +void _store_output_block(uint32_t *dst); + +#if AES_USE_DMA +int +aes_execute_cmd(uint32_t cmd, void *addr, uint32_t length, bool block) +{ + struct task_event event; + struct dma_segment seg; + void *fifo; + int32_t ret; + int dma_channel; + + // build an SGL for the one segment + switch (cmd & DMA_CMD_DIR_MASK) { + case DMA_CMD_DIR_TX: + seg.paddr = (uintptr_t)addr; + fifo = (void*)0x47380040; + dma_channel = DMA_AES_WR; + break; + case DMA_CMD_DIR_RX: + seg.paddr = (uintptr_t)addr; + fifo = (void*)0x47380080; + dma_channel = DMA_AES_RD; + break; + default: + return -1; + } + seg.length = length; + + if (block) { + // run the operation + event_init(&event, EVENT_FLAG_AUTO_UNSIGNAL, false); + ret = dma_execute_async(cmd, dma_channel, &seg, fifo, length, 0, 0, + (dma_completion_function)event_signal, (void *)&event); + + if (!ret) + // and block waiting for it to complete + event_wait(&event); + } else { + ret = dma_execute_async(cmd, dma_channel, &seg, fifo, length, 0, 0, + NULL, NULL); + } + + return ret; +} +#endif + +int +aes_hw_crypto_cmd(u_int32_t cmd, void *src, void *dst, size_t len, u_int32_t opts, const void *key, void *iv) +{ + uint32_t key_in_ctrl; + uint32_t blocks; + uint32_t *local_iv, *local_key; + + dprintf(DEBUG_SPEW, "aes_hw_crypto_cmd: cmd: %08x, src: %p, dst: %p, len: %zx, opts: %08x, key: %p, iv: %p \n", + cmd, src, dst, len, opts, key, iv); + + clock_gate(CLK_AES0, true); + + ASSERT(src != NULL); + ASSERT(dst != NULL); + + local_iv = (uint32_t *)iv; + local_key = (uint32_t *)key; + + /* Make sure length is multiple of 16 bytes */ + ASSERT((len > 0) && ((len & 0xf) == 0)); + blocks = len / 16; + + key_in_ctrl = 0; + + switch (cmd & AES_CMD_MODE_MASK) { + case AES_CMD_ECB : key_in_ctrl |= KEY_IN_CTRL_MOD_ECB; break; + case AES_CMD_CBC : key_in_ctrl |= KEY_IN_CTRL_MOD_CBC; break; + default : goto fail; + } + + switch (cmd & AES_CMD_DIR_MASK) { + case AES_CMD_ENC : key_in_ctrl |= KEY_IN_CTRL_DIR_ENC; break; + case AES_CMD_DEC : key_in_ctrl |= KEY_IN_CTRL_DIR_DEC; break; + default : goto fail; + } + + /* Get the key length */ + switch (opts & AES_KEY_SIZE_MASK) { + case AES_KEY_SIZE_128 : key_in_ctrl |= KEY_IN_CTRL_LEN_128; break; + case AES_KEY_SIZE_192 : key_in_ctrl |= KEY_IN_CTRL_LEN_192; break; + case AES_KEY_SIZE_256 : key_in_ctrl |= KEY_IN_CTRL_LEN_256; break; + default : goto fail; + } + + bool key_disabled = false; + + /* Set the key */ + switch (opts & AES_KEY_TYPE_MASK) { + case AES_KEY_TYPE_USER : + key_in_ctrl |= KEY_IN_CTRL_SEL_SW; + + switch (opts & AES_KEY_SIZE_MASK) { + default: + rAES_S7002_KEY_IN7 = local_key[7]; + rAES_S7002_KEY_IN6 = local_key[6]; + case AES_KEY_SIZE_192: + rAES_S7002_KEY_IN5 = local_key[5]; + rAES_S7002_KEY_IN4 = local_key[4]; + case AES_KEY_SIZE_128: + rAES_S7002_KEY_IN3 = local_key[3]; + rAES_S7002_KEY_IN2 = local_key[2]; + rAES_S7002_KEY_IN1 = local_key[1]; + rAES_S7002_KEY_IN0 = local_key[0]; + } + break; + + case AES_KEY_TYPE_UID0 : + key_in_ctrl |= KEY_IN_CTRL_SEL_UID1; + key_disabled = platform_keys_disabled(0,1); + break; + case AES_KEY_TYPE_GID0 : + key_in_ctrl |= KEY_IN_CTRL_SEL_GID0; + key_disabled = platform_keys_disabled(1,0); + break; + case AES_KEY_TYPE_GID1 : + key_in_ctrl |= KEY_IN_CTRL_SEL_GID1; + key_disabled = platform_keys_disabled(1,0); + break; + } + + if (key_disabled) { + dprintf(DEBUG_INFO, "SIO_AES: requested AES key has been disabled\n"); + return -1; + } + + /* Make sure AES block is not busy */ + ASSERT(rAES_S7002_KEY_IN_STS & KEY_IN_STS_RDY); + ASSERT(rAES_S7002_TXT_IN_STS & TXT_IN_FIFO_SPACE_AVAIL); + ASSERT(!(rAES_S7002_TXT_OUT_STS & TXT_OUT_DATA_AVAIL)); + + /* Setup Key configurator, and load the context */ + rAES_S7002_KEY_IN_CTRL = key_in_ctrl; + rAES_S7002_KEY_IN_CTRL |= KEY_IN_CTRL_VAL_SET; + + dprintf(DEBUG_SPEW, "sio_aes: key_in_ctrl:0x%08x, rAES_S7002_KEY_IN_CTRL:0x%08x\n", key_in_ctrl, rAES_S7002_KEY_IN_CTRL); + + /* Load IV */ + if (iv != 0) { + rAES_S7002_IV_IN0 = local_iv[0]; + rAES_S7002_IV_IN1 = local_iv[1]; + rAES_S7002_IV_IN2 = local_iv[2]; + rAES_S7002_IV_IN3 = local_iv[3]; + } else { + rAES_S7002_IV_IN0 = 0; + rAES_S7002_IV_IN1 = 0; + rAES_S7002_IV_IN2 = 0; + rAES_S7002_IV_IN3 = 0; + } + rAES_S7002_IV_IN_CTRL = (0 << IV_IN_CTRL_CTX_SHIFT); + rAES_S7002_IV_IN_CTRL |= IV_IN_CTRL_VAL_SET; + + /* Perform AES operation */ + + /* Load first block */ + rAES_S7002_TXT_IN_CTRL = ((0 << TXT_IN_CTRL_IV_CTX_SHIFT) | (0 << TXT_IN_CTRL_KEY_CTX_SHIFT)); + +#if AES_USE_DMA + /* Do cache operations */ + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, (void *)((uint32_t)dst & ~(CPU_CACHELINE_SIZE-1)), ROUNDUP(len, CPU_CACHELINE_SIZE) + CPU_CACHELINE_SIZE); + + /* start the operation */ + aes_execute_cmd(DMA_CMD_DIR_RX, dst, len, false); + + /* Do cache operations */ + platform_cache_operation(CACHE_CLEAN, (void *)((uint32_t)src & ~(CPU_CACHELINE_SIZE-1)), ROUNDUP(len, CPU_CACHELINE_SIZE) + CPU_CACHELINE_SIZE); + + /* start the operation */ + aes_execute_cmd(DMA_CMD_DIR_TX, src, len, true); +#else + uint32_t *local_src = (uint32_t *)src; + uint32_t *local_dst = (uint32_t *)dst; + + rAES_S7002_TXT_IN_CTRL = ((0 << TXT_IN_CTRL_IV_CTX_SHIFT) | (0 << TXT_IN_CTRL_KEY_CTX_SHIFT)); + _load_input_block(local_src); + while(--blocks) { + /* Wait until we can shove next block in */ + while ((rAES_S7002_TXT_IN_STS & TXT_IN_FIFO_SPACE_AVAIL) != TXT_IN_FIFO_SPACE_AVAIL); + + /* Load next block */ + local_src += 4; + rAES_S7002_TXT_IN_CTRL = ((0 << TXT_IN_CTRL_IV_CTX_SHIFT) | (0 << TXT_IN_CTRL_KEY_CTX_SHIFT)); + _load_input_block(local_src); + + /* Store result of the previous operation */ + while ((rAES_S7002_TXT_OUT_STS & TXT_OUT_DATA_AVAIL) != TXT_OUT_DATA_AVAIL); + _store_output_block(local_dst); + local_dst += 4; + } + /* Store result of the last operation */ + while ((rAES_S7002_TXT_OUT_STS & TXT_OUT_DATA_AVAIL) != TXT_OUT_DATA_AVAIL); + _store_output_block(local_dst); +#endif + + /* Clear user key from the registers */ + if ((opts & AES_KEY_TYPE_MASK) == AES_KEY_TYPE_USER) { + rAES_S7002_KEY_IN7 = 0; + rAES_S7002_KEY_IN6 = 0; + rAES_S7002_KEY_IN5 = 0; + rAES_S7002_KEY_IN4 = 0; + rAES_S7002_KEY_IN3 = 0; + rAES_S7002_KEY_IN2 = 0; + rAES_S7002_KEY_IN1 = 0; + rAES_S7002_KEY_IN0 = 0; + } + + clock_gate(CLK_AES0, false); + + return 0; + +fail: + panic("AES_S7002: bad arguments\n"); +} + +void _load_input_block(const uint32_t *src) +{ + dprintf(DEBUG_SPEW, "src: "); + for(int i = 0; i < 4; i++) dprintf(DEBUG_SPEW, "%08x ", src[i]); + dprintf(DEBUG_SPEW, "\n"); + + rAES_S7002_TXT_IN = src[0]; + rAES_S7002_TXT_IN = src[1]; + rAES_S7002_TXT_IN = src[2]; + rAES_S7002_TXT_IN = src[3]; +} + +void _store_output_block(uint32_t *dst) +{ + dst[0] = rAES_S7002_TXT_OUT; + dst[1] = rAES_S7002_TXT_OUT; + dst[2] = rAES_S7002_TXT_OUT; + dst[3] = rAES_S7002_TXT_OUT; + + dprintf(DEBUG_SPEW, "dst: "); + for(int i = 0; i < 4; i++) dprintf(DEBUG_SPEW, "%08x ", dst[i]); + dprintf(DEBUG_SPEW, "\n"); +} diff --git a/drivers/apple/aes_s7002/aes_s7002.h b/drivers/apple/aes_s7002/aes_s7002.h new file mode 100644 index 0000000..dce8382 --- /dev/null +++ b/drivers/apple/aes_s7002/aes_s7002.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_AES_S7002_H +#define __APPLE_AES_S7002_H + +#include + +/* AES-AP registers */ + +#define rAES_S7002_STS (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0000)) +#define STS_BUSY (1U << 0) + +#define rAES_S7002_TXT_IN_CTRL (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0008)) +#define TXT_IN_CTRL_IV_CTX_SHIFT (2) +#define TXT_IN_CTRL_KEY_CTX_SHIFT (1) + +#define rAES_S7002_TXT_IN_STS (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x000C)) +#define TXT_IN_FIFO_SPACE_AVAIL (1U << 0) + +#define rAES_S7002_TXT_IN (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0040)) + +#define rAES_S7002_TXT_OUT_STS (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0050)) +#define TXT_OUT_STS_IV_CTX_SHIFT (2) +#define TXT_OUT_STS_KEY_CTX_SHIFT (1) +#define TXT_OUT_DATA_AVAIL (1U << 0) + +#define rAES_S7002_TXT_OUT (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0080)) + +#define rAES_S7002_KEY_IN_CTRL (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0090)) +#define KEY_IN_CTRL_MOD_CBC (1U << 13) +#define KEY_IN_CTRL_MOD_ECB (0U << 13) +#define KEY_IN_CTRL_DIR_ENC (1U << 12) +#define KEY_IN_CTRL_DIR_DEC (0U << 12) +#define KEY_IN_CTRL_LEN_256 (2U << 6) +#define KEY_IN_CTRL_LEN_192 (1U << 6) +#define KEY_IN_CTRL_LEN_128 (0U << 6) +#define KEY_IN_CTRL_SEL_GID1 (3U << 4) +#define KEY_IN_CTRL_SEL_GID0 (2U << 4) +#define KEY_IN_CTRL_SEL_UID1 (1U << 4) +#define KEY_IN_CTRL_SEL_SW (0U << 4) +#define KEY_IN_CTRL_CTX_SHIFT (1) +#define KEY_IN_CTRL_VAL_SET (1U << 0) + +#define rAES_S7002_KEY_IN_STS (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0094)) +#define KEY_IN_STS_RDY (1U << 0) + +#define rAES_S7002_KEY_IN0 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00C0)) +#define rAES_S7002_KEY_IN1 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00C4)) +#define rAES_S7002_KEY_IN2 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00C8)) +#define rAES_S7002_KEY_IN3 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00CC)) +#define rAES_S7002_KEY_IN4 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00D0)) +#define rAES_S7002_KEY_IN5 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00D4)) +#define rAES_S7002_KEY_IN6 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00D8)) +#define rAES_S7002_KEY_IN7 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00DC)) + +#define rAES_S7002_IV_IN_CTRL (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x00E0)) +#define IV_IN_CTRL_CTX_SHIFT (1) +#define IV_IN_CTRL_VAL_SET (1U << 0) + +#define rAES_S7002_IV_IN0 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0100)) +#define rAES_S7002_IV_IN1 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0104)) +#define rAES_S7002_IV_IN2 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x0108)) +#define rAES_S7002_IV_IN3 (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x010C)) + +/* rAES_S7002_IV_OUTxxxx to rAES_S7002_DSB_xxxx */ + +#define rAES_S7002_ERR (*(volatile uint32_t *)(AES_S7002_BASE_ADDR + 0x01D0)) +#define AES_ERR_SET (1U << 0) + +#endif /* __APPLE_AES_S7002_H */ diff --git a/drivers/apple/aes_s7002/rules.mk b/drivers/apple/aes_s7002/rules.mk new file mode 100644 index 0000000..9581ffa --- /dev/null +++ b/drivers/apple/aes_s7002/rules.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AES=1 + +MODULES += \ + drivers/aes + +ALL_OBJS += \ + $(LOCAL_DIR)/aes_s7002.o diff --git a/drivers/apple/aes_v2/aes_v2.c b/drivers/apple/aes_v2/aes_v2.c new file mode 100644 index 0000000..41a3ef2 --- /dev/null +++ b/drivers/apple/aes_v2/aes_v2.c @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#if WITH_HW_SEP +#include +#endif +#include +#include + +#include "aes_v2.h" + +#define COMMAND_FIFO_SIZE 128 + +typedef enum { + BLOCK_MODE_ECB = 0, + BLOCK_MODE_CBC = 1, + BLOCK_MODE_CTR = 2, +} block_mode_t; + +typedef enum { + KEY_LEN_128 = 0, + KEY_LEN_192 = 1, + KEY_LEN_256 = 2, +} key_len_t; + +typedef enum { + KEY_SELECT_SOFTWARE = 0, + KEY_SELECT_UID1 = 1, + KEY_SELECT_GID_AP_1 = 2, + KEY_SELECT_GID_AP_2 = 3, + KEY_SELECT_HDCP_0 = 4, + KEY_SELECT_HDCP_1 = 5, + KEY_SELECT_HDCP_2 = 6, + KEY_SELECT_HDCP_3 = 7, +} key_select_t; + +typedef enum { + KEY_FUNC_NONE = 0, + KEY_FUNC_LEGACY = 1, + KEY_FUNC_FAIRPLAY_LEGACY = 2, + KEY_FUNC_FAIRPLAY_H8F = 3, +} key_func_t; + +typedef enum { + OPCODE_KEY = 0x01, + OPCODE_IV = 0x02, + OPCODE_DSB = 0x03, + OPCODE_SKG = 0x04, + OPCODE_DATA = 0x05, + OPCODE_STORE_IV = 0x06, + OPCODE_WRITE_REG = 0x07, + OPCODE_FLAG = 0x08, +} command_opcodes_t; + +#define COMMAND_OPCODE_SHIFT (28) +#define COMMAND_OPCODE_MASK (0xF) + +typedef struct command_key { + #define COMMAND_KEY_COMMAND_KEY_CONTEXT_SHIFT (27) + #define COMMAND_KEY_COMMAND_KEY_CONTEXT_MASK (0x1) + + #define COMMAND_KEY_COMMAND_KEY_SELECT_SHIFT (24) + #define COMMAND_KEY_COMMAND_KEY_SELECT_MASK (0x7) + + #define COMMAND_KEY_COMMAND_KEY_LENGTH_SHIFT (22) + #define COMMAND_KEY_COMMAND_KEY_LENGTH_MASK (0x3) + + #define COMMAND_KEY_COMMAND_WRAPPED_SHIFT (21) + #define COMMAND_KEY_COMMAND_WRAPPED_MASK (0x1) + + #define COMMAND_KEY_COMMAND_ENCRYPT_SHIFT (20) + #define COMMAND_KEY_COMMAND_ENCRYPT_MASK (0x1) + + #define COMMAND_KEY_COMMAND_KEY_FUNC_SHIFT (18) + #define COMMAND_KEY_COMMAND_KEY_FUNC_MASK (0x3) + + #define COMMAND_KEY_COMMAND_BLOCK_MODE_SHIFT (16) + #define COMMAND_KEY_COMMAND_BLOCK_MODE_MASK (0x3) + + #define COMMAND_KEY_COMMAND_COMMAND_ID_SHIFT (0) + #define COMMAND_KEY_COMMAND_COMMAND_ID_MASK (0xFF) + uint32_t command; + uint32_t key[8]; +} command_key_t; + +typedef struct aes_command_iv { + #define COMMAND_IV_COMMAND_IV_CONTEXT_SHIFT (26) + #define COMMAND_IV_COMMAND_IV_CONTEXT_MASK (0x3) + + #define COMMAND_IV_COMMAND_HDCP_KEY_SHIFT (25) + #define COMMAND_IV_COMMAND_HDCP_KEY_MASK (0x1) + + #define COMMAND_IV_COMMAND_IV_IN_HDCP_SHIFT (23) + #define COMMAND_IV_COMMAND_IV_IN_HDCP_MASK (0x3) + uint32_t command; + uint32_t iv[4]; +} command_iv_t; + +typedef struct aes_command_data { + #define COMMAND_DATA_COMMAND_KEY_CONTEXT_SHIFT (27) + #define COMMAND_DATA_COMMAND_KEY_CONTEXT_MASK (0x1) + + #define COMMAND_DATA_COMMAND_IV_CONTEXT_SHIFT (25) + #define COMMAND_DATA_COMMAND_IV_CONTEXT_MASK (0x3) + + #define COMMAND_DATA_COMMAND_LENGTH_SHIFT (0) + #define COMMAND_DATA_COMMAND_LENGTH_MASK (0xFFFFFF) + uint32_t command; + #define COMMAND_DATA_UPPER_ADDR_SOURCE_SHIFT (16) + #define COMMAND_DATA_UPPER_ADDR_SOURCE_MASK (0xFF) + + #define COMMAND_DATA_UPPER_ADDR_DEST_SHIFT (0) + #define COMMAND_DATA_UPPER_ADDR_DEST_MASK (0xFF) + uint32_t upper_addr; + uint32_t source_addr; + uint32_t dest_addr; +} command_data_t; + +typedef struct aes_command_store_iv { + #define COMMAND_STORE_IV_COMMAND_CONTEXT_SHIFT (26) + #define COMMAND_STORE_IV_COMMAND_CONTEXT_MASK (0x3) + + #define COMMAND_STORE_IV_COMMAND_UPPER_ADDR_DEST_SHIFT (0) + #define COMMAND_STORE_IV_COMMAND_UPPER_ADDR_DEST_MASK (0xFF) + uint32_t command; + uint32_t dest_addr; +} command_store_iv_t; + +#define COMMAND_FLAG_ID_CODE_SHIFT (0) +#define COMMAND_FLAG_ID_CODE_MASK (0xFF) +#define COMMAND_FLAG_STOP_COMMANDS_SHIFT (26) +#define COMMAND_FLAG_SEND_INTERRUPT_SHIFT (27) + +#if WITH_DPA +static bool dpa_seeded(void) { + if ((rAES_STATUS & AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_UMASK) == 0 || + (rAES_STATUS & AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_UMASK) == 0) { + return false; + } else { + return true; + } +} +#endif + +uint32_t command_fifo_level(void) { + return ((rAES_COMMAND_FIFO_STATUS) & AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK) >> 8; +} + +void push_commands(uint32_t *cmd, uint32_t size) { + uint32_t words; + ASSERT(size % sizeof(uint32_t) == 0); + + words = size / sizeof(uint32_t); + + ASSERT(command_fifo_level() + words <= COMMAND_FIFO_SIZE); + + for (uint32_t i = 0; i < words; i ++) { + dprintf(DEBUG_SPEW, "sio_aes: cmd[%d]: 0x%08x\n", i, cmd[i]); + rAES_COMMAND_FIFO = cmd[i]; + } +} + +uint32_t key_size(uint8_t mode) { + switch(mode) { + case KEY_LEN_128: return 128; + case KEY_LEN_192: return 192; + case KEY_LEN_256: return 256; + default: panic("Unknown key size: %d\n", mode); + } + return 0; +} + +void push_command_key(uint32_t command, uint8_t *key) +{ + command_key_t ckey; + + memset(&ckey, 0, sizeof(ckey)); + + ckey.command = OPCODE_KEY << COMMAND_OPCODE_SHIFT | command; + + if(((command >> COMMAND_KEY_COMMAND_KEY_SELECT_SHIFT) & COMMAND_KEY_COMMAND_KEY_SELECT_MASK) == 0) { + // software key (Key Select == 0) + ASSERT(key != NULL); + + uint32_t key_len = + key_size((command >> COMMAND_KEY_COMMAND_KEY_LENGTH_SHIFT) & COMMAND_KEY_COMMAND_KEY_LENGTH_MASK) / 8; + memcpy(ckey.key, key, key_len); + + // Key is not wrapped + push_commands((uint32_t*)&ckey.command, sizeof(ckey.command)); + push_commands((uint32_t*)&ckey.key[0], key_len); + } else { + // non-software keys just need the command word + push_commands((uint32_t*)&ckey.command, sizeof(ckey.command)); + } +} + +void push_command_iv(uint8_t context, uint8_t hdcp_key, bool iv_in_hdcp, uint8_t* iv) +{ + command_iv_t civ; + + memset(&civ, 0, sizeof(civ)); + + civ.command = (OPCODE_IV << COMMAND_OPCODE_SHIFT) | + ((context & COMMAND_IV_COMMAND_IV_CONTEXT_MASK) << COMMAND_IV_COMMAND_IV_CONTEXT_SHIFT) | + ((hdcp_key & COMMAND_IV_COMMAND_HDCP_KEY_MASK) << COMMAND_IV_COMMAND_HDCP_KEY_SHIFT) | + ((iv_in_hdcp & COMMAND_IV_COMMAND_IV_IN_HDCP_MASK) << COMMAND_IV_COMMAND_IV_IN_HDCP_SHIFT); + + if (iv) { + memcpy(&civ.iv, iv, sizeof(civ.iv)); + } + + push_commands((uint32_t*)&civ, sizeof(command_iv_t)); +} + +void push_command_data(uint8_t key_ctx, uint8_t iv_ctx, uint64_t src, uint64_t dst, uint32_t len) +{ + command_data_t data; + + memset(&data, 0, sizeof(data)); + + data.command = (OPCODE_DATA << COMMAND_OPCODE_SHIFT) | + ((len & COMMAND_DATA_COMMAND_LENGTH_MASK) << COMMAND_DATA_COMMAND_LENGTH_SHIFT) | + ((key_ctx & COMMAND_DATA_COMMAND_KEY_CONTEXT_MASK) << COMMAND_DATA_COMMAND_KEY_CONTEXT_SHIFT) | + ((iv_ctx & COMMAND_DATA_COMMAND_IV_CONTEXT_MASK) << COMMAND_DATA_COMMAND_IV_CONTEXT_SHIFT); + data.upper_addr = + (((src >> 32) & COMMAND_DATA_UPPER_ADDR_SOURCE_MASK) << COMMAND_DATA_UPPER_ADDR_SOURCE_SHIFT) | + (((dst >> 32) & COMMAND_DATA_UPPER_ADDR_DEST_MASK) << COMMAND_DATA_UPPER_ADDR_DEST_SHIFT); + data.source_addr = (uint32_t)src; + data.dest_addr = (uint32_t)dst; + + push_commands((uint32_t*)&data, sizeof(command_data_t)); +} + +void push_command_flag(uint16_t id_code, bool stop, bool interrupt) +{ + uint32_t flag = 0; + + flag = (OPCODE_FLAG << COMMAND_OPCODE_SHIFT) | + ((id_code & COMMAND_FLAG_ID_CODE_MASK) << COMMAND_FLAG_ID_CODE_SHIFT); + + if (stop) + flag |= 1 << COMMAND_FLAG_SEND_INTERRUPT_SHIFT; + if (interrupt) + flag |= 1 << COMMAND_FLAG_STOP_COMMANDS_SHIFT; + + push_commands(&flag, sizeof(flag)); +} + +uint32_t create_key_command(bool context, uint8_t select, uint8_t len, bool wrapped, bool encrypt, uint8_t func, uint8_t mode, uint8_t id) { + return (OPCODE_KEY << COMMAND_OPCODE_SHIFT) | + ((context & COMMAND_KEY_COMMAND_KEY_CONTEXT_MASK) << COMMAND_KEY_COMMAND_KEY_CONTEXT_SHIFT) | + ((select & COMMAND_KEY_COMMAND_KEY_SELECT_MASK) << COMMAND_KEY_COMMAND_KEY_SELECT_SHIFT) | + ((len & COMMAND_KEY_COMMAND_KEY_LENGTH_MASK) << COMMAND_KEY_COMMAND_KEY_LENGTH_SHIFT) | + ((wrapped & COMMAND_KEY_COMMAND_WRAPPED_MASK) << COMMAND_KEY_COMMAND_WRAPPED_SHIFT) | + ((encrypt & COMMAND_KEY_COMMAND_ENCRYPT_MASK) << COMMAND_KEY_COMMAND_ENCRYPT_SHIFT) | + ((func & COMMAND_KEY_COMMAND_KEY_FUNC_MASK) << COMMAND_KEY_COMMAND_KEY_FUNC_SHIFT) | + ((mode & COMMAND_KEY_COMMAND_BLOCK_MODE_MASK) << COMMAND_KEY_COMMAND_BLOCK_MODE_SHIFT) | + ((id & COMMAND_KEY_COMMAND_COMMAND_ID_MASK) << COMMAND_KEY_COMMAND_COMMAND_ID_SHIFT); +} + +void wait_for_command_flag(void) +{ + while ((rAES_INT_STATUS & AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK) == 0) {} + + rAES_INT_STATUS = AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK; + + dprintf(DEBUG_SPEW, "sio_aes: AES_STATUS=0x%08x\n", rAES_STATUS); + dprintf(DEBUG_SPEW, "sio_aes: AES_COMMAND_FIFO_STATUS=0x%08x\n", rAES_COMMAND_FIFO_STATUS); + dprintf(DEBUG_SPEW, "sio_aes: INT_STATUS=0x%08x\n", rAES_INT_STATUS); + + ASSERT((rAES_COMMAND_FIFO_STATUS & AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK) != 0); + if (rAES_INT_STATUS) { + panic("AES command failed, AES_STATUS=0x%08x, AES_COMMAND_FIFO_STATUS=0x%08x, INT_STATUS=0x%08x", rAES_STATUS, rAES_COMMAND_FIFO_STATUS, rAES_INT_STATUS); + } +} + +int +aes_hw_crypto_cmd(u_int32_t cmd, void *src, void *dst, size_t len, u_int32_t opts, const void *key, void *iv) +{ + uintptr_t *local_src, *local_dst; + uint8_t *local_iv, *local_key; + + dprintf(DEBUG_SPEW, "aes_hw_crypto_cmd: cmd: 0x%08x, src: %p, dst: %p, len: 0x%08zx, opts: 0x%08x, key: %p, iv: %p \n", + cmd, src, dst, len, opts, key, iv); + + clock_gate(CLK_AES0, true); + +#if WITH_DPA + if (!dpa_seeded()) { + sep_client_seed_aes(); + if(!dpa_seeded()) { + panic("AES DPA not Seeded"); + } + } +#endif + + ASSERT(src != NULL); + ASSERT(dst != NULL); + + local_src = (uintptr_t *)src; + local_dst = (uintptr_t *)dst; + local_iv = (uint8_t *)iv; + local_key = (uint8_t *)key; + + /* Make sure length is multiple of 16 bytes */ + ASSERT((len > 0) && ((len & 0xf) == 0)); + + uint8_t key_select = KEY_SELECT_SOFTWARE; + uint8_t key_len = KEY_LEN_128; + uint8_t key_mode = BLOCK_MODE_ECB; + bool encrypt = false; + + switch (cmd & AES_CMD_MODE_MASK) { + case AES_CMD_ECB : key_mode = BLOCK_MODE_ECB; break; + case AES_CMD_CBC : key_mode = BLOCK_MODE_CBC; break; + default : goto fail; + } + + switch (cmd & AES_CMD_DIR_MASK) { + case AES_CMD_ENC : encrypt = true; break; + case AES_CMD_DEC : encrypt = false; break; + default : goto fail; + } + + /* Get the key length */ + switch (opts & AES_KEY_SIZE_MASK) { + case AES_KEY_SIZE_128 : key_len = KEY_LEN_128; break; + case AES_KEY_SIZE_192 : key_len = KEY_LEN_192; break; + case AES_KEY_SIZE_256 : key_len = KEY_LEN_256; break; + default : goto fail; + } + + bool key_disabled = false; + + /* Set the key */ + /* Make sure the requested key is not disabled */ + switch (opts & AES_KEY_TYPE_MASK) { + case AES_KEY_TYPE_USER : + key_select = KEY_SELECT_SOFTWARE; + break; + case AES_KEY_TYPE_UID0 : + key_select = KEY_SELECT_UID1; + key_disabled = platform_keys_disabled(0,1); + break; + case AES_KEY_TYPE_GID0 : + key_select = KEY_SELECT_GID_AP_1; + key_disabled = platform_keys_disabled(1,0); + break; + case AES_KEY_TYPE_GID1 : + key_select = KEY_SELECT_GID_AP_2; + key_disabled = platform_keys_disabled(2,0); + break; + default : goto fail; + } + + if (key_disabled) { + dprintf(DEBUG_INFO, "SIO_AES: requested AES key has been disabled\n"); + return -1; + } + + uint32_t key_command = + create_key_command(0, key_select, key_len, false, encrypt, KEY_FUNC_NONE, key_mode, 0); + + dprintf(DEBUG_SPEW, "sio_aes: key_command:0x%08x\n", key_command); + + /* Verify everything is flushed out of write buffers */ + platform_memory_barrier(); + + // We're going to poll for the flag interrupt after the command finishes, so clear it now + rAES_INT_STATUS = AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK; + + /* Start the block consuming commands */ + dprintf(DEBUG_SPEW, "sio_aes: AES_CONTROL_START\n"); + rAES_CONTROL = AES_BLK_CONTROL_START_UMASK; + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN, (void *)((uint32_t)local_key & ~(CPU_CACHELINE_SIZE-1)), ROUNDUP(len, CPU_CACHELINE_SIZE) + CPU_CACHELINE_SIZE); +#endif /*WITH_NON_COHERENT_DMA*/ + + // Push the key command out to the block + push_command_key(key_command, local_key); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN, (void *)((uint32_t)local_iv & ~(CPU_CACHELINE_SIZE-1)), ROUNDUP(len, CPU_CACHELINE_SIZE) + CPU_CACHELINE_SIZE); +#endif /* WITH_NON_COHERENT_DMA */ + + /* Load IV */ + push_command_iv(0, 0, 0, local_iv); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN, (void *)((uint32_t)local_src & ~(CPU_CACHELINE_SIZE-1)), ROUNDUP(len, CPU_CACHELINE_SIZE) + CPU_CACHELINE_SIZE); +#endif /*WITH_NON_COHERENT_DMA*/ + + /* Perform AES operation */ + push_command_data(0, 0, (uint64_t)local_src, (uint64_t)local_dst, len); + + // Raise an interrupt and stop executing commands once all AF responses are received + push_command_flag(0, true, true); + + wait_for_command_flag(); + + platform_memory_barrier(); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, (void *)((uint32_t)local_dst & ~(CPU_CACHELINE_SIZE-1)), ROUNDUP(len, CPU_CACHELINE_SIZE) + CPU_CACHELINE_SIZE); +#endif /*WITH_NON_COHERENT_DMA*/ + + /* Stop the block consuming commands */ + dprintf(DEBUG_SPEW, "sio_aes: AES_CONTROL_STOP\n"); + rAES_CONTROL = AES_BLK_CONTROL_STOP_UMASK; + + clock_gate(CLK_AES0, false); + + return 0; + +fail: + panic("SIO_AES: bad arguments\n"); +} diff --git a/drivers/apple/aes_v2/aes_v2.h b/drivers/apple/aes_v2/aes_v2.h new file mode 100644 index 0000000..9f72295 --- /dev/null +++ b/drivers/apple/aes_v2/aes_v2.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_AES_V2_H +#define __APPLE_AES_V2_H + +#include +#include SUB_PLATFORM_SPDS_HEADER(aes) + +/* AES-v2 registers */ + +#define rAES_VERSION (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_VERSION_OFFSET)) + +#define rAES_CONFIG (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_CONFIG_OFFSET)) + +#define rAES_CONTROL (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_CONTROL_OFFSET)) + +#define rAES_STATUS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_STATUS_OFFSET)) + +#define rAES_INT_STATUS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_INT_STATUS_OFFSET)) + +#define rAES_INT_ENABLE (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_INT_ENABLE_OFFSET)) + +#define rAES_WATERMARKS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_WATERMARKS_OFFSET)) + +#define rAES_COMMAND_FIFO_STATUS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_COMMAND_FIFO_STATUS_OFFSET)) + +#define rAES_HISTORY_FIFO_STATUS (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_HISTORY_FIFO_STATUS_OFFSET)) + +#define rAES_COMMAND_FIFO_COUNT (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_COMMAND_FIFO_COUNT_OFFSET)) + +#define rAES_FLAG_COMMAND (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_FLAG_COMMAND_OFFSET)) + +#define rAES_SKG_KEY (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_SKG_KEY_OFFSET)) + +#define rAES_COMMAND_FIFO (*(volatile uint32_t *)(AES_AP_BASE_ADDR + AES_BLK_COMMAND_FIFO_OFFSET)) + +#endif /* __APPLE_AES_V2_H */ diff --git a/drivers/apple/aes_v2/rules.mk b/drivers/apple/aes_v2/rules.mk new file mode 100644 index 0000000..c86df50 --- /dev/null +++ b/drivers/apple/aes_v2/rules.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AES=1 + +MODULES += \ + drivers/aes + +ALL_OBJS += \ + $(LOCAL_DIR)/aes_v2.o + \ No newline at end of file diff --git a/drivers/apple/aic/aic.c b/drivers/apple/aic/aic.c new file mode 100644 index 0000000..dfc62c3 --- /dev/null +++ b/drivers/apple/aic/aic.c @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_AIC_TIMERS +static void timer_deadline(void *arg); +static void (* timer_deadline_func)(void); +#endif + +#if WITH_AIC_INTERRUPTS || WITH_AIC_TIMERS + +static inline uint32_t _aic_read_reg(volatile uint32_t *reg) +{ + uint32_t val; +#if PLATFORM_VARIANT_IOP || AIC_VERSION > 0 + val = *reg; +#else + /* An exclusive load is required for the CPU ID to be passed along */ + __asm__ volatile( "ldrex %0, [%1]" : "=r" (val) : "r" (reg)); +#endif // PLATFORM_VARIANT_IOP || AIC_VERSION > 0 + return val; +} + +static inline void _aic_write_reg(volatile uint32_t *reg, uint32_t val) +{ + *reg = val; +} + +static void _aic_init() +{ +#if AIC_VERSION > 0 + rAIC_GLB_CFG |= (AIC_GLBCFG_SYNC_ACG | AIC_GLBCFG_EIR_ACG | AIC_GLBCFG_REG_ACG); + + /* Clear the timeout values before setting them to avoid set bits from the default values */ + rAIC_GLB_CFG &= ~(AIC_GLBCFG_SEWT(AIC_GLBCFG_WT_MASK) | AIC_GLBCFG_AEWT(AIC_GLBCFG_WT_MASK)); + rAIC_GLB_CFG &= ~(AIC_GLBCFG_SIWT(AIC_GLBCFG_WT_MASK) | AIC_GLBCFG_AIWT(AIC_GLBCFG_WT_MASK)); + rAIC_GLB_CFG |= (AIC_GLBCFG_SEWT(AIC_GLBCFG_WT_64MICRO) | AIC_GLBCFG_AEWT(AIC_GLBCFG_WT_64MICRO)); + rAIC_GLB_CFG |= (AIC_GLBCFG_SIWT(AIC_GLBCFG_WT_64MICRO) | AIC_GLBCFG_AIWT(AIC_GLBCFG_WT_64MICRO)); +#else + rAIC_GLB_CFG |= AIC_GLBCFG_ACG; + + /* Clear the timeout values before setting them to avoid set bits from the default values */ + rAIC_GLB_CFG &= ~(AIC_GLBCFG_EWT(AIC_GLBCFG_WT_MASK) | AIC_GLBCFG_IWT(AIC_GLBCFG_WT_MASK)); + rAIC_GLB_CFG |= (AIC_GLBCFG_EWT(AIC_GLBCFG_WT_64MICRO) | AIC_GLBCFG_IWT(AIC_GLBCFG_WT_64MICRO)); +#endif // AIC_VERSION > 0 + + // Enable Interrupts + rAIC_GLB_CFG |= AIC_GLBCFG_IEN; +} + +#endif + +#if WITH_AIC_INTERRUPTS + +/* + * Interrupt support + */ + +extern void __arm_irq(void); + +static struct interrupt_entry handlers[kAIC_NUM_INTS]; + +#if AIC_VERSION < 1 +static uint32_t fiq_source = kAIC_INT_SPURIOUS; +#endif // AIC_VERSION < 1 + +static void _aic_mask_timer_int(bool mask) +{ +#if AIC_VERSION < 1 + if (mask) + _aic_write_reg(&rAIC_TMR_ST_SET, AIC_TMRST_TIM); + else + _aic_write_reg(&rAIC_TMR_ST_CLR, AIC_TMRST_TIM); +#endif // AIC_VERSION < 1 +} + +static void _aic_mask_int_internal(uint32_t vector) +{ + if (vector == kAIC_VEC_IPI) { + /* Not maskable */ + } else if (vector == kAIC_VEC_TMR) { + _aic_mask_timer_int(true); + } else if (vector == kAIC_VEC_SW_TMR) { + /* Not maskable */ + } else { + uint32_t reg = AIC_SRC_TO_EIR(vector); + rAIC_EIR_MASK_SET(reg) = AIC_SRC_TO_MASK(vector); + } +} + +static void _aic_unmask_int_internal(uint32_t vector) +{ + if (vector == kAIC_VEC_IPI) { + /* Not maskable */ + } else if (vector == kAIC_VEC_TMR) { + _aic_mask_timer_int(false); + } else { + /* if AIC client requested interrupt state is not masked, unmask it */ + if (!handlers[vector].int_mask_requested) { + uint32_t reg = AIC_SRC_TO_EIR(vector); + rAIC_EIR_MASK_CLR(reg) = AIC_SRC_TO_MASK(vector); + } + } +} + +int interrupt_init(void) +{ + _aic_init(); + +#if !PLATFORM_VARIANT_IOP + /* mask everything */ + interrupt_mask_all(); +#endif + + /* also enable it */ + exit_critical_section(); + + return 0; +} + +void interrupt_mask_all(void) +{ + uint32_t eir; + + /* mask everything */ + for (eir = 0; eir < kAIC_NUM_EIRS; eir++) { + rAIC_EIR_MASK_SET(eir) = 0xffffffff; + } + /* XXX timers? */ +} + +void mask_int(uint32_t vector) +{ + /* save AIC client requested interrupt mask state */ + handlers[vector].int_mask_requested = true; + _aic_mask_int_internal(vector); +} + +void unmask_int(uint32_t vector) +{ + /* clear AIC client requested interrupt mask state */ + handlers[vector].int_mask_requested = false; + _aic_unmask_int_internal(vector); +} + + +void set_int_type(uint32_t vector, int type) +{ + enter_critical_section(); + +#if AIC_VERSION < 1 + uint32_t reg; + + if (type & INT_TYPE_FIQ) { + reg = _aic_read_reg(&rAIC_TMR_CFG); + reg &= ~kAIC_TMRCFG_FSL_MASK; + if ((reg & (AIC_TMRCFG_IMD|AIC_TMRCFG_EMD|AIC_TMRCFG_SMD)) != + (AIC_TMRCFG_IMD|AIC_TMRCFG_EMD|AIC_TMRCFG_SMD)) + panic("Can't support multiple timer FIQ sources\n"); + if (vector == kAIC_VEC_TMR) { + reg &= ~AIC_TMRCFG_IMD; + _aic_write_reg(&rAIC_TMR_CFG, reg | AIC_TMRCFG_FSL(kAIC_TMRCFGFSL_PVT)); + fiq_source = kAIC_INT_PVT_TMR; + arm_enable_fiqs(); + } else if (vector == kAIC_VEC_SW_TMR) { + reg &= ~AIC_TMRCFG_SMD; + _aic_write_reg(&rAIC_TMR_CFG, reg | AIC_TMRCFG_FSL(kAIC_TMRCFGFSL_SGT)); + fiq_source = kAIC_INT_SW_TMR; + arm_enable_fiqs(); + } + } else { + if (vector == kAIC_VEC_TMR) { + _aic_write_reg(&rAIC_TMR_CFG, _aic_read_reg(&rAIC_TMR_CFG) | AIC_TMRCFG_IMD); + } else if (vector == kAIC_VEC_SW_TMR) { + _aic_write_reg(&rAIC_TMR_CFG, _aic_read_reg(&rAIC_TMR_CFG) | AIC_TMRCFG_SMD); + } + } +#endif // AIC_VERSION < 1 + + if (type & INT_TYPE_EDGE) + panic("set_int_type: edge not supported\n"); + + exit_critical_section(); +} + +int install_int_handler(uint32_t vector, int_handler handler, void *arg) +{ + ASSERT(vector < kAIC_NUM_INTS); + + enter_critical_section(); + + handlers[vector].handler = handler; + handlers[vector].arg = arg; + + if (vector < kAIC_MAX_EXTID) { + rAIC_EIR_DEST(vector) = 1 << AIC_CPU_ID; + } + + exit_critical_section(); + + return 0; +} + +static uint32_t spurious = 0; + +#define SPURIOUS_DEBUG 0 +#define PLATFORM_IRQ_SLICES ((PLATFORM_IRQ_COUNT + 31) / 32) + +void platform_irq(void) +{ +#if SPURIOUS_DEBUG + uint32_t unmasked[PLATFORM_IRQ_SLICES]; + uint32_t i; + + for (i = 0; i < PLATFORM_IRQ_SLICES; i++) { + unmasked[i] = rAIC_EIR_INT_RO(i) & ~rAIC_EIR_MASK_CLR(i); + } +#endif + uint32_t vector = _aic_read_reg(&rAIC_IACK); + uint32_t source; + + if (vector == kAIC_INT_SPURIOUS) { + /* Do some extra checking to be sure IACK is behaving + * as expected. We don't really expect spurious + * interrupts in this environment, and certainly want + * to see a non-spurious IACK any time a source is + * active. */ +#if SPURIOUS_DEBUG + for (i = 0; i < PLATFORM_IRQ_SLICES; i++) { + if (unmasked[i]) + panic("IACK=0 but sources are pending\n"); + } + printf("spurious\n"); +#endif + spurious++; + return; + } + while (vector != kAIC_INT_SPURIOUS) { + if (AIC_INT_EXT(vector)) { + source = AIC_INT_EXTID(vector); + } else if (AIC_INT_IPI(vector)) { + panic("Unexpected IPI\n"); +#if AIC_VERSION < 1 + } else if (vector == kAIC_INT_PVT_TMR) { + source = kAIC_VEC_TMR; + } else if (vector == kAIC_INT_SW_TMR) { + _aic_write_reg(&rAIC_TMR_ST_CLR, AIC_TMRST_SGT); + source = kAIC_VEC_SW_TMR; +#endif // AIC_VERSION < 1 + } else { + panic("Unrecognized IRQ vector: %x\n", vector); + } + if (handlers[source].handler) + handlers[source].handler(handlers[source].arg); + _aic_unmask_int_internal(source); + vector = _aic_read_reg(&rAIC_IACK); + } +} + +#if AIC_VERSION < 1 + +void platform_fiq(void) +{ + uint32_t source; + + if (fiq_source == kAIC_INT_SW_TMR) { + _aic_write_reg(&rAIC_TMR_ST_CLR, AIC_TMRST_SGT); + source = kAIC_VEC_SW_TMR; + } else if (fiq_source == kAIC_INT_PVT_TMR) { + source = kAIC_VEC_TMR; + } else + panic("Unexpected FIQ\n"); + if (handlers[source].handler) + handlers[source].handler(handlers[source].arg); + _aic_unmask_int_internal(source); +} + +#endif // AIC_VERSION < 1 + +#if AIC_VERSION == 2 + +void platform_fiq(void) +{ + /* clear FIQ and disable decrementer */ + _aic_write_reg(&rAIC_TMR_CFG, ~AIC_TMRCFG_EN); + _aic_write_reg(&rAIC_TMR_ISR, AIC_TMRISR_PCT); + + /* if we have a callback, invoke it now */ + if (timer_deadline_func) { + timer_deadline_func(); + } +} + +#endif // AIC_VERSION == 2 + +#if PLATFORM_VARIANT_IOP + +void interrupt_generate_ipc(uint32_t vector) +{ + uint32_t reg = AIC_SRC_TO_EIR(vector); + rAIC_EIR_SW_SET(reg) = AIC_SRC_TO_MASK(vector); +} + +void interrupt_clear_ipc(uint32_t vector) +{ + uint32_t reg = AIC_SRC_TO_EIR(vector); + rAIC_EIR_SW_CLR(reg) = AIC_SRC_TO_MASK(vector); +} + +#endif + +#endif + +#if WITH_AIC_TIMERS +/* + * Timer support; currently assumes that the banked register block works + * (XXX no it doesn't - see top of file) + */ + +#define DECR_MAX_COUNT (0xffffffffULL) + +int timer_init(uint32_t timer) +{ + /* Allow only banked access to CPU's own timer */ + if (timer != 0) return -1; + + /* Default to disabled and IRQ for all modes */ + _aic_write_reg(&rAIC_TMR_CFG, AIC_TMRCFG_IMD|AIC_TMRCFG_EMD|AIC_TMRCFG_SMD); + + /* install our interrupt handler */ + install_int_handler(kAIC_VEC_TMR, (int_handler)&timer_deadline, NULL); + unmask_int(kAIC_VEC_TMR); + + return 0; +} + +void timer_stop_all(void) +{ + /* Even though it says "all", only stop the dedicated timer */ + _aic_write_reg(&rAIC_TMR_CFG, _aic_read_reg(&rAIC_TMR_CFG) & ~AIC_TMRCFG_EN); +} + +void timer_deadline_enter(uint64_t deadline, void (* func)(void)) +{ + uint64_t ticks; + uint32_t decr; + + timer_deadline_func = func; + if (func) { +// printf("installing deadline %p\n", func); + + /* convert absolute deadline to relative time */ + ticks = timer_get_ticks(); + if (deadline < ticks) { +// printf(" %llu too soon (it is now %llu)\n", deadline, ticks); +#if AIC_VERSION == 2 + deadline = 1; +#else // AIC_VERSION == 2 + deadline = 0; +#endif + } else { + deadline -= ticks; + } + + /* clamp the deadline to our maximum, which is about 178 seconds */ + decr = (deadline > DECR_MAX_COUNT) ? DECR_MAX_COUNT : deadline; +// printf(" using decrementer count %u\n", decr); + + /* + * Reset the decrementer by programming the max count, clearing + * any pending interrupt status, then programming the desired count. + */ + _aic_write_reg(&rAIC_TMR_CNT, DECR_MAX_COUNT); + _aic_write_reg(&rAIC_TMR_CFG, _aic_read_reg(&rAIC_TMR_CFG) | AIC_TMRCFG_EN); + _aic_write_reg(&rAIC_TMR_ISR, AIC_TMRISR_PCT); + _aic_write_reg(&rAIC_TMR_CNT, decr); + } else { + /* no deadline, disable the decrementer */ + _aic_write_reg(&rAIC_TMR_CFG, _aic_read_reg(&rAIC_TMR_CFG) & ~AIC_TMRCFG_EN); + _aic_write_reg(&rAIC_TMR_ISR, _aic_read_reg(&rAIC_TMR_ISR) | AIC_TMRISR_PCT); + } +} + +static void timer_deadline(void *arg) +{ + /* acknowledge the interrupt and disable the timer */ + _aic_write_reg(&rAIC_TMR_CFG, _aic_read_reg(&rAIC_TMR_CFG) & ~AIC_TMRCFG_EN); + _aic_write_reg(&rAIC_TMR_ISR, _aic_read_reg(&rAIC_TMR_ISR) | AIC_TMRISR_PCT); + + /* if we have a callback, invoke it now */ + if (timer_deadline_func) + timer_deadline_func(); +} + +#endif // WITH_AIC_TIMERS + +/* + * The rest are defined for all targets that include the AIC driver + */ + +uint64_t aic_get_ticks(void) +{ + uint32_t time_lo, time_hi; + + /* read the timebase */ + do { + time_hi = rAIC_TIME_HI; + time_lo = rAIC_TIME_LO; + } while (time_hi != rAIC_TIME_HI); + + return ((uint64_t)time_hi << 32) | time_lo; +} + +void aic_spin(uint32_t usecs) +{ + uint32_t delta_time = usecs * (OSC_FREQ / 1000000); + uint32_t start_time = rAIC_TIME_LO; + + while ((rAIC_TIME_LO - start_time) < delta_time); +} + +#if WITH_AIC_TIMERS + +#ifdef OSC_FREQ + +utime_t timer_ticks_to_usecs(uint64_t ticks) +{ +#if (OSC_FREQ % 1000000) == 0 + return ticks / (OSC_FREQ / 1000000); +#else +#error "The code below has overflow issues. Make sure you really want to use it" + return (ticks * 1000 * 1000) / OSC_FREQ; +#endif +} + +uint64_t timer_usecs_to_ticks(utime_t usecs) +{ +#if (OSC_FREQ % 1000000) == 0 + return usecs * (OSC_FREQ / 1000000); +#else +#error "The code below has overflow issues. Make sure you really want to use it" + uint64_t timer_scale = ((uint64_t)(OSC_FREQ) << 20) / (1000 * 1000); + return (ticks * timer_scale) >> 20; +#endif +} + +uint32_t timer_get_tick_rate(void) +{ + return OSC_FREQ; +} + +#endif // OSC_FREQ + +uint64_t timer_get_ticks(void) +{ + return aic_get_ticks(); +} + +#endif // WITH_AIC_TIMERS + +uint32_t timer_get_entropy(void) +{ + return arch_get_entropy(&rAIC_TIME_LO); +} + +#ifndef PMGR_WDG_VERSION +#error "PMGR_WDG_VERSION not defined" +#endif + +#if PMGR_WDG_VERSION < 1 +void wdt_chip_reset(void) +{ + rPMGR_WDOG_CTL = 0; // Turn off any pending events + rPMGR_WDOG_RST = 1; // Set counter for immediate reset + rPMGR_WDOG_TMR = 0x80000000; // Set counter to a safe value + rPMGR_WDOG_CTL = 4; // Enable watchdog reset + rPMGR_WDOG_TMR = 0; // Reset counter to zero +} + +void wdt_enable(void) +{ + rPMGR_WDOG_CTL = 0; // Turn off any pending events + rPMGR_WDOG_RST = 120*OSC_FREQ; // Set counter for two minute reset + rPMGR_WDOG_TMR = 0x80000000; // Set counter to a safe value + rPMGR_WDOG_CTL = 0x0C; // Enable watchdog system reset + rPMGR_WDOG_TMR = 0; // Reset counter to zero +} +#else +void wdt_chip_reset(void) +{ + rPMGR_CHIP_WDOG_CTL = 0; + rPMGR_CHIP_WDOG_RST_CNT = 1; + rPMGR_CHIP_WDOG_TMR = 0x80000000; + rPMGR_CHIP_WDOG_CTL = 4; + rPMGR_CHIP_WDOG_TMR = 0; +} + +void wdt_system_reset(void) +{ + rPMGR_SYS_WDOG_CTL = 0; // Turn off watchdog + rPMGR_SYS_WDOG_RST_CNT = 1; // Set counter for immediate reset + rPMGR_SYS_WDOG_TMR = 0x80000000;// Set up-counter to safe value + rPMGR_SYS_WDOG_CTL = 4; // Turn on interrupt + rPMGR_SYS_WDOG_TMR = 0; // Reset counter to zero +} + +void wdt_enable(void) +{ + rPMGR_SYS_WDOG_CTL = 0; + rPMGR_SYS_WDOG_RST_CNT = 120 * OSC_FREQ; + rPMGR_SYS_WDOG_TMR = 0x80000000; + rPMGR_SYS_WDOG_CTL = 4; +} +#endif diff --git a/drivers/apple/aic/include/drivers/aic/aic.h b/drivers/apple/aic/include/drivers/aic/aic.h new file mode 100644 index 0000000..4212214 --- /dev/null +++ b/drivers/apple/aic/include/drivers/aic/aic.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_AIC_H +#define __PLATFORM_SOC_AIC_H + +#include + +// AIC_VERSION +// 0 - < H6 +// 1 - H6-H8, M7 +// 2 - M8 +// 3 - H9 + +#ifndef AIC_VERSION +#error "AIC_VERSION is not defined in hwregbase.h" +#endif +#ifndef AIC_INT_COUNT +#error "AIC_INT_COUNT is not defined in hwregbase.h" +#endif + +#define rAIC_REV (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x0000)) +#define rAIC_CAP0 (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x0004)) +#define rAIC_CAP1 (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x0008)) +#define rAIC_RST (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x000C)) + +#define rAIC_GLB_CFG (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x0010)) +#define AIC_GLBCFG_IEN (1 << 0) +#if AIC_VERSION < 1 +#define AIC_GLBCFG_TEN (1 << 1) +#define AIC_GLBCFG_EWT(_t) ((_t) << 4) +#define AIC_GLBCFG_IWT(_t) ((_t) << 8) +#define AIC_GLBCFG_ACG (1 << 16) +#define AIC_GLBCFG_WT_MASK (7) +#else +#define AIC_GLBCFG_AEWT(_t) ((_t) << 4) +#define AIC_GLBCFG_SEWT(_t) ((_t) << 8) +#define AIC_GLBCFG_AIWT(_t) ((_t) << 12) +#define AIC_GLBCFG_SIWT(_t) ((_t) << 16) +#define AIC_GLBCFG_SYNC_ACG (1 << 29) +#define AIC_GLBCFG_EIR_ACG (1 << 30) +#define AIC_GLBCFG_REG_ACG (1 << 31) +#define AIC_GLBCFG_WT_MASK (15) +#endif // AIC_VERSION < 1 +#define AIC_GLBCFG_WT_64MICRO (7) + +#if AIC_VERSION < 1 +#define rAIC_TIME_LO (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x0020)) +#define rAIC_TIME_HI (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x0028)) +#elif AIC_VERSION < 3 +#define rAIC_TIME_LO (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x1020)) +#define rAIC_TIME_HI (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x1028)) +#else // (AIC_VERSION >= 3) +#define rAIC_TIME_LO (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x8020)) +#define rAIC_TIME_HI (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x8028)) +#endif // AIC_VERSION + +#define rAIC_WHOAMI (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2000)) +#define rAIC_IACK (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2004)) +#define rAIC_IPI_SET (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2008)) +#define rAIC_IPI_CLR (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x200C)) +#define AIC_IPI_NORMAL (1 << 0) +#define AIC_IPI_SELF (1 << 31) +#define rAIC_TMR_CFG (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2010)) +#define AIC_TMRCFG_EN (1 << 0) +#define AIC_TMRCFG_IMD (1 << 1) +#define AIC_TMRCFG_EMD (1 << 2) +#define AIC_TMRCFG_SMD (1 << 3) +#define AIC_TMRCFG_FSL(_s) ((_s) << 4) +#define kAIC_TMRCFGFSL_PVT 0 +#define kAIC_TMRCFGFSL_SGT 1 +#define kAIC_TMRCFGFSL_EXT 2 +#define kAIC_TMRCFG_FSL_MASK (AIC_TMRCFG_FSL(3)) +#if AIC_VERSION < 1 +#define rAIC_TMR_CNT (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2014)) +#define rAIC_TMR_ISR (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2018)) +#define AIC_TMRISR_PCT (1 << 0) +#define AIC_TMRISR_ETS (1 << 1) +#define AIC_TMRISR_STS (1 << 2) +#define rAIC_TMR_ST_SET (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x201C)) +#define rAIC_TMR_ST_CLR (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2020)) +#define AIC_TMRST_SGT (1 << 0) +#define AIC_TMRST_TIM (1 << 1) +#endif // AIC_VERSION < 1 +#define rAIC_IPI_MASK_SET (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2024)) +#define rAIC_IPI_MASK_CLR (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2028)) +#if AIC_VERSION > 0 +#define rAIC_PVT_STAMP_CFG (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2040)) +#define AIC_PVT_STAMP_CFG_EN (1 << 31) +#define rAIC_PVT_STAMP_LO (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2048)) +#define rAIC_PVT_STAMP_HI (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x204C)) +#endif // AIC_VERSION > 0 + +#define rAIC_EIR_DEST(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x3000 + ((_n) * 4))) +#define rAIC_EIR_SW_SET(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x4000 + ((_n) * 4))) +#define rAIC_EIR_SW_CLR(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x4080 + ((_n) * 4))) +#define rAIC_EIR_MASK_SET(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x4100 + ((_n) * 4))) +#define rAIC_EIR_MASK_CLR(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x4180 + ((_n) * 4))) +#define rAIC_EIR_INT_RO(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x4200 + ((_n) * 4))) + +#define rAIC_WHOAMI_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5000 + ((_n) * 0x80))) +#define rAIC_IACK_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5004 + ((_n) * 0x80))) +#define rAIC_IPI_SET_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5008 + ((_n) * 0x80))) +#define rAIC_IPI_CLR_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x500C + ((_n) * 0x80))) +#define rAIC_TMR_CFG_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5010 + ((_n) * 0x80))) +#define rAIC_TMR_CNT_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5014 + ((_n) * 0x80))) +#define rAIC_TMR_ISR_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5018 + ((_n) * 0x80))) +#define rAIC_TMR_ST_SET_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x501C + ((_n) * 0x80))) +#define rAIC_TMR_ST_CLR_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5020 + ((_n) * 0x80))) +#define rAIC_IPI_MASK_SET_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5024 + ((_n) * 0x80))) +#define rAIC_IPI_MASK_CLR_Pn(_n) (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x5028 + ((_n) * 0x80))) + +#define kAIC_INT_SPURIOUS (0x00000) +#define kAIC_INT_EXT (0x10000) +#define kAIC_INT_IPI (0x40000) +#define kAIC_INT_IPI_NORM (0x40001) +#define kAIC_INT_IPI_SELF (0x40002) +#define kAIC_INT_TMR (0x70000) +#define kAIC_INT_PVT_TMR (0x70001) +#define kAIC_INT_EXT_TMR (0x70002) +#define kAIC_INT_SW_TMR (0x70004) + +#define AIC_INT_EXT(_v) (((_v) & 0x70000) == kAIC_INT_EXT) +#define AIC_INT_IPI(_v) (((_v) & 0x70000) == kAIC_INT_IPI) +#define AIC_INT_TMR(_v) (((_v) & 0x70000) == kAIC_INT_TMR) + +#define AIC_INT_EXTID(_v) ((_v) & 0x1FF) + +#define AIC_SRC_TO_EIR(_s) ((_s) >> 5) +#define AIC_SRC_TO_MASK(_s) (1 << ((_s) & 0x1F)) + +#define kAIC_MAX_EXTID (AIC_INT_COUNT) +#define kAIC_VEC_IPI (kAIC_MAX_EXTID) +#define kAIC_VEC_TMR (kAIC_MAX_EXTID + 1) +#define kAIC_VEC_SW_TMR (kAIC_VEC_TMR + 1) +#define kAIC_NUM_INTS (kAIC_VEC_SW_TMR + 1) + +#define kAIC_NUM_EIRS AIC_SRC_TO_EIR(kAIC_MAX_EXTID) +#if AIC_VERSION < 1 +#define kAIC_NUM_TMRS (3) +#endif // AIC_VERSION < 1 + +#endif /* ! __PLATFORM_SOC_AIC_H */ diff --git a/drivers/apple/aic/rules.mk b/drivers/apple/aic/rules.mk new file mode 100644 index 0000000..a0463dc --- /dev/null +++ b/drivers/apple/aic/rules.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2009-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AIC=1 + +ifneq ($(PLATFORM_VARIANT),Audio) +OPTIONS += \ + WITH_AIC_INTERRUPTS=1 +endif + +ifeq ($(HW_TIMER),) + +OPTIONS += \ + WITH_HW_TIMER=1 + +ifneq ($(PLATFORM_VARIANT),Audio) +OPTIONS += \ + WITH_AIC_TIMERS=1 +endif + +endif + +ALL_OBJS += $(LOCAL_DIR)/aic.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/amc/amc.c b/drivers/apple/amc/amc.c new file mode 100644 index 0000000..08ffb0e --- /dev/null +++ b/drivers/apple/amc/amc.c @@ -0,0 +1,790 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// if there are separate ap/dev parameters, amc_init will copy +// the appropriate ones here +#if AMC_PARAMS_AP_DEV +static struct amc_param amc_params; +#endif +static bool amc_params_initialized; + +static const struct amc_channel_addrs { + volatile uint32_t *rnkcfg; + volatile uint32_t *mrcmd; + volatile uint32_t *mrstatus; + uint32_t mrpoll; + uint32_t mrshift; + volatile uint32_t *initcmd; + volatile uint32_t *initstatus; + uint32_t mcuen; +} _amc_chregs[] = { + { &rAMC_CH0RNKCFG0, &rAMC_CH0MRCMD, &rAMC_CH01MRSTATUS, 0x01, 8, &rAMC_CH0INITCMD, &rAMC_CH01INITSTATUS, 0x0001 }, + { &rAMC_CH1RNKCFG0, &rAMC_CH1MRCMD, &rAMC_CH01MRSTATUS, 0x10, 16, &rAMC_CH1INITCMD, &rAMC_CH01INITSTATUS, 0x0100 }, + { &rAMC_CH2RNKCFG0, &rAMC_CH2MRCMD, &rAMC_CH23MRSTATUS, 0x01, 8, &rAMC_CH2INITCMD, &rAMC_CH23INITSTATUS, 0x0010 }, + { &rAMC_CH3RNKCFG0, &rAMC_CH3MRCMD, &rAMC_CH23MRSTATUS, 0x10, 16, &rAMC_CH3INITCMD, &rAMC_CH23INITSTATUS, 0x1000 }, +}; + +static struct amc_memory_device_info _amc_device_info; +static bool _amc_device_info_inited; + +// Local static functions +static uint32_t amc_odd_parity(uint32_t input); + +/* + * Based on H4P/H4G AMC UM 0.63, H4 Tunables 0.36, + * H5P/Bali AMC UM 0.48, H5P/Bali Tunables 0.63 + * Alcatraz AMC Init.html (A0: AMC: 3.53.5 AMP: 2.13.0 (v22). B0: 3.56.4 AMP: 2.13.1 (v76)) + * Alcatraz A0 AMC Tunables dated Dec 8, 2012 + * M7 AMC Init.html (AMC: 12.3.0 AMP: 5.7.0, dated Wed Mar 11 17:47:57 2014, Tunables as of Apr 9, 2014) + */ + +void amc_mrcmd(amc_mrcmd_op_t op, uint8_t channels, uint8_t ranks, int reg, uintptr_t val) +{ + uint8_t ch, r; + + for (ch = 0; ch < channels; ch++) { + for (r = 0; r < ranks; r++) { + amc_mrcmd_to_ch_rnk(op, ch, r, reg, val); + } + } +} + +// Only send the cmd to specific channel and rank (used during calibration on H6 and later) +void amc_mrcmd_to_ch_rnk(amc_mrcmd_op_t op, uint8_t channel, uint8_t rank, int32_t reg, uintptr_t val) +{ + uint32_t cmd, regval; + uint8_t *buffer = (uint8_t *) val; + + if (op == MR_READ) + cmd = 0x00000011 | (reg << 8); + else + cmd = 0x00000001 | (reg << 8) | (((uint32_t)val) << 24); + + *_amc_chregs[channel].mrcmd = cmd | (rank << 16); + +// Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP +#if AMC_REG_VERSION > 2 + platform_memory_barrier(); +#endif + + while(((regval = *_amc_chregs[channel].mrstatus) & _amc_chregs[channel].mrpoll) != 0) ; + if (op == MR_READ) + *buffer++ = (regval >> _amc_chregs[channel].mrshift) & 0xff; +} + +void amc_enable_autorefresh(void) +{ + // Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last. + + rAMC_AREFEN_FREQ(1) = 0x00000000 | amc_params.aref_freq1; + + rAMC_AREFEN_FREQ(2) = 0x00000000; + rAMC_AREFEN_FREQ(3) = 0x00000000; + + rAMC_AREFEN_FREQ(0) = 0x01011001 | amc_params.aref_freq0; +} + +void amc_configure_default_address_decoding_and_mapping(void) +{ + rAMC_ADDRCFG = 0x00020101; // Default: 2Gb geometry: 9col, 14row, 8bank + if (AMC_NUM_RANKS > 1) + rAMC_ADDRCFG |= 0x01000000; // 2rank + rAMC_CHNLDEC = 0x00040000 | amc_params.chnldec; // 2Gb/channel, interleaved +#if AMC_REG_VERSION < 3 && !SUB_PLATFORM_S7002 + if (amc_params.chnldec2) + rAMC_CHNLDEC2 = amc_params.chnldec2; + if (amc_params.chnldec4) + rAMC_CHNLDEC4 = amc_params.chnldec4; +#endif + + rAMC_ADDRMAP_MODE = 2; // RIBI2 + +#if AMC_REG_VERSION < 3 && !SUB_PLATFORM_S7002 + if (amc_params.flags & FLAG_AMC_PARAM_MRR_BIT_SWIZZLE) + rAMC_PHYMRRDATADQBITMUX = 0x56714230; + + if (amc_params.flags & FLAG_AMC_PARAM_MRR_BYTE_SWIZZLE) + rAMC_PHYMRRDATADQBYTEMUX = 0x2; +#endif +} + +int32_t amc_init(bool resume) +{ + uint8_t config_id = 0; + uint32_t tREFi; + uint64_t deadline; + uint32_t ch, r, i; + +#if AMC_PARAMS_AP_DEV + if (target_config_dev()) { + memcpy(&amc_params, &amc_params_dev, sizeof(amc_params)); + } else { + memcpy(&amc_params, &amc_params_ap, sizeof(amc_params)); + } +#endif + amc_params_initialized = true; + +#if (AMC_REG_VERSION == 2 && SUB_PLATFORM_S7002) + clocks_set_performance(kPerformanceMemoryLow); +#else + // Make sure we're at full memory frequency + clocks_set_performance(kPerformanceMemoryFull); +#endif + + // The clock_reset_device() call takes care of the requirements in + clock_reset_device(CLK_MCU); + + // Keep track of 50us after MCU reset to ensure resume timing is in spec + deadline = timer_get_ticks() + timer_usecs_to_ticks(50); + + ////////////////////////////////////////////////////////// + // + // 1. AMC initial configuration + // + ////////////////////////////////////////////////////////// + + amc_phy_enable_dqs_pulldown(false); + + tREFi = amc_params.tREFi; + + for (i = 0; i < AMC_FREQUENCY_SLOTS; i++) { + rAMC_CAS_FREQ(i) = amc_params.freq[i].cas; + rAMC_PCH_FREQ(i) = amc_params.freq[i].pch; + rAMC_ACT_FREQ(i) = amc_params.freq[i].act; + rAMC_AUTO_FREQ(i) = amc_params.freq[i].autoref | ((i == 0) ? tREFi : 0); + rAMC_SELF_FREQ(i) = amc_params.freq[i].selfref; + rAMC_MODE_FREQ(i) = amc_params.freq[i].modereg; + rAMC_MIFCASSCH_FREQ(i) = amc_params.freq[i].mifcassch; + } + +#if (AMC_REG_VERSION == 2 && SUB_PLATFORM_S7002) + rAMC_TREFBWBASECYC_FREQ(0) = amc_params.freq[0].trefbwbasecyc; + rAMC_TREFBWBASECYC_FREQ(1) = amc_params.freq[1].trefbwbasecyc; + rAMC_TREFBWBASECYC_FREQ(2) = amc_params.freq[2].trefbwbasecyc; +#endif + + rAMC_LAT = (amc_params.rdlat << 16) | (amc_params.wrlat << 8); + rAMC_PDN = amc_params.pdn; + rAMC_DERATE = amc_params.derate; + rAMC_RD = amc_params.read; + + if (amc_params.flags & FLAG_AMC_PARAM_BUSTAT23) { + rAMC_BUSTAT_FREQ01 = amc_params.bustat; + rAMC_BUSTAT_FREQ23 = amc_params.bustat2; + } else { + rAMC_BUSTAT = amc_params.bustat; + } + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + for (r = 0; r < AMC_NUM_RANKS; r++) + *(_amc_chregs[ch].rnkcfg + AMC_RNKCFG_OFFSET(r)) = 1; + + rAMC_PHYRDWRTIM = (amc_params.phywrlat << 16) | (amc_params.phyrdlat << 8) | (amc_params.rdlat - 2); + + rAMC_PWRMNGTEN = amc_params.pwrmngten_default; + rAMC_SCHEN = amc_params.schen_default; // disable the scheduler + + rAMC_MCPHY_UPDTPARAM = amc_params.mcphyupdate; +#if (AMC_REG_VERSION == 3) || (AMC_REG_VERSION == 2 && SUB_PLATFORM_S7002) + rAMC_MCPHY_UPDTPARAM1 = amc_params.mcphyupdate1; +#endif + + if (amc_params.autoref_params) + rAMC_AUTOREF_PARAMS = amc_params.autoref_params; + + amc_configure_address_decoding_and_mapping(); + + // Enable MCUs + rAMC_AMCEN = (amc_params.flags & FLAG_AMC_PARAM_LEGACY) ? 0x80000000 : 0; + +// Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP +#if AMC_REG_VERSION > 2 + platform_memory_barrier(); +#endif + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + rAMC_AMCEN |= _amc_chregs[ch].mcuen; + // Enable AIU, if supported + if (amc_params.flags & FLAG_AMC_PARAM_ENABLE_AIU) + rAMC_AMCEN |= 0x10000; + + ////////////////////////////////////////////////////////// + // + // 2. PHY Initial Configuartions + // + ////////////////////////////////////////////////////////// +#ifdef AMP_SWIZZLE +#if (AMP_SWIZZLE == AMP_SWIZZLE_PER_J34M) // per + // Set up the MRR Bit Mapping Muxen + rAMC_PHYMRRDATADQBYTEMUX = 0x00000002; + rAMC_PHYMRRDATADQBITMUX = 0x76543210; +#endif +#endif + amc_phy_init(resume); + + ////////////////////////////////////////////////////////// + // + // 3. Self-Refresh and DRAM Reset + // + ////////////////////////////////////////////////////////// +#if (AMC_REG_VERSION == 3) || ((AMC_REG_VERSION == 2) && SUB_PLATFORM_S7002) + rAMC_AREFPARAM = amc_params.freq[0].arefparam; + + for (i = 1; i < AMC_FREQUENCY_SLOTS; i++) { + rAMC_AREFPARAM_FREQ(i) = amc_params.freq[i].arefparam; + } +#else + rAMC_AREFPARAM = 0x00060532 | amc_params.arefparam; +#endif + +#if !((AMC_REG_VERSION == 2) && SUB_PLATFORM_S7002) + amc_enable_slow_boot(true); +#endif + + // + // + rAMC_LONGSR = 0x00000000; + +#if (AMC_REG_VERSION == 3) || ((AMC_REG_VERSION == 2) && SUB_PLATFORM_S7002) + rAMC_LONGSR = 0x01000000 | amc_params.longsrcnt | amc_params.srextrarefcnt; +#endif + + if (resume) { + // Enable temperature based refresh rate modulation to compensate for missing refresh + if (amc_params.odts) { + #if SUPPORT_FPGA + rAMC_ODTS = amc_params.odts; + #else + rAMC_ODTS = 0x00010000 | amc_params.odts; + #endif + } + + amc_enable_autorefresh(); + // Software must guarantee that at least 50 us have passed since the de-assertion + // of AMC reset before self-refresh exit, in the resume-boot case. + while (deadline > timer_get_ticks()) ; + } + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + *_amc_chregs[ch].initcmd = 0x00001000; // start self-refresh exit seq on ch + +// Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP +#if AMC_REG_VERSION > 2 + platform_memory_barrier(); +#endif + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + while (*_amc_chregs[ch].initcmd != 0) ; + +#if AMC_REG_VERSION < 3 && !SUB_PLATFORM_S7002 + rAMC_AREFPARAM = 0x00020532 | amc_params.arefparam; + rAMC_LONGSR = 0x05000000 | amc_params.longsrcnt | amc_params.srextrarefcnt; +#endif + + ////////////////////////////////////////////////////////// + // + // 4. DRAM Reset, ZQ Calibration & Configuration (cold boot only) + // + ////////////////////////////////////////////////////////// + if (!resume) { + spin(200); + + // MR63 (DRAM reset and auto-refresh enable) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x3f, amc_params.mr63); + spin(12); + + // MR10 (ZQ initial calibration) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0xa, 0xff); + spin(1); + + // MR2 register (read/write latency, assumes legal combo in amc_params) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x2, (amc_params.mr2 ? amc_params.mr2 : (amc_params.rdlat - 2))); + } + + // Read device info: vendor, revision, and configuration info + // Configuration info: device width, device type, device density + // We are assuming all of our devices are identical + amc_mrcmd(MR_READ, 1, 1, 0x5, (uintptr_t)&_amc_device_info.vendor_id); + amc_mrcmd(MR_READ, 1, 1, 0x6, (uintptr_t)&_amc_device_info.rev_id); + amc_mrcmd(MR_READ, 1, 1, 0x7, (uintptr_t)&_amc_device_info.rev_id2); + amc_mrcmd(MR_READ, 1, 1, 0x8, (uintptr_t)&config_id); + + if ((_amc_device_info.vendor_id == 0) || (config_id == 0)) + panic("failed to read vendor-id/config-id, vid:%08x, config:%08x, rev:%08x\n", _amc_device_info.vendor_id, + config_id, _amc_device_info.rev_id); + + _amc_device_info.width = (32 >> ((config_id >> JEDEC_MR8_WIDTH_SHIFT) & JEDEC_MR8_WIDTH_MASK)) >> 3; + _amc_device_info.density = ((config_id >> JEDEC_MR8_DENSITY_SHIFT) & JEDEC_MR8_DENSITY_MASK); + _amc_device_info.type = ((config_id >> JEDEC_MR8_TYPE_SHIFT) & JEDEC_MR8_TYPE_MASK); + + _amc_device_info_inited = true; + + dprintf(DEBUG_INFO, "sdram vendor id:0x%02x rev id:0x%02x rev id2:%02x\n", + _amc_device_info.vendor_id, _amc_device_info.rev_id, _amc_device_info.rev_id2); + dprintf(DEBUG_INFO, "sdram config: width %d/%d Mbit/type %d\n", _amc_device_info.width << 3, + 64 << _amc_device_info.density, _amc_device_info.type); + + if ((_amc_device_info.density < JEDEC_DENSITY_1Gb) || (_amc_device_info.density > JEDEC_DENSITY_4Gb)) + panic("unsupported DRAM density: %dMbit", 64 << _amc_device_info.density); + + if (!resume) { + // MR1 (nWR=pch_freq0.tWRCyc), WC=wrap, BT=Seq, BL=16) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x1, + (amc_params.mr1 ? amc_params.mr1 : + (((amc_params.freq[0].pch - 0x200) & 0xf00) >> 3) | 0x04)); + + // MR3 register (output buffer drive strength 48-Ohm unless overridden) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x3, (amc_params.mr3 ? amc_params.mr3 : 0x3)); + } + + // DRAM vendor-specific workarounds + amc_dram_workarounds(resume); + + ////////////////////////////////////////////////////////// + // + // 5. Topology-specific AMC re-configuration + // + ////////////////////////////////////////////////////////// + if (amc_params.flags & FLAG_AMC_PARAM_RECONFIG) { + uint8_t num_banks; + + num_banks = 8; + if (((_amc_device_info.type == JEDEC_TYPE_S4_SDRAM) && (_amc_device_info.density <= JEDEC_DENSITY_512Mb)) || + ((_amc_device_info.type == JEDEC_TYPE_S2_SDRAM) && (_amc_device_info.density <= JEDEC_DENSITY_2Gb))) + num_banks = 4; + + if (_amc_device_info.density == JEDEC_DENSITY_1Gb) { + if (_amc_device_info.type == JEDEC_TYPE_S4_SDRAM) + rAMC_AUTO_FREQ(0) = amc_params.freq[0].autoref | amc_params.tREFi_1Gb; + + rAMC_LONGSR = 0x05010000 | amc_params.longsrcnt_1Gb | amc_params.srextrarefcnt; + + if ((AMC_NUM_RANKS == 1) && (num_banks == 8)) { + rAMC_CHNLDEC &= ~(7 << 16); + rAMC_CHNLDEC |= 0x00030000; // 1Gb/channel, interleaved + rAMC_ADDRCFG = 0x00010101; + } + } + else if (_amc_device_info.density == JEDEC_DENSITY_4Gb) { + if ((AMC_NUM_RANKS == 1) && (num_banks == 8)) { + rAMC_CHNLDEC &= ~(7 << 16); + rAMC_CHNLDEC |= 0x00050000; // 4Gb/channel, interleaved + rAMC_ADDRCFG = 0x00020201; + } + } + + if (AMC_NUM_CHANNELS == 1) { + switch(_amc_device_info.density) { + case JEDEC_DENSITY_2Gb: + rAMC_CHNLDEC |= 0x00000001; // 2Gb/channel, stacked + break; + + case JEDEC_DENSITY_4Gb: + rAMC_CHNLDEC &= ~(7 << 16); + rAMC_CHNLDEC |= 0x00050001; // 4Gb/channel, stacked + break; + + case JEDEC_DENSITY_1Gb: + rAMC_CHNLDEC &= ~(7 << 16); + rAMC_CHNLDEC |= 0x00030001; // 1Gb/channel, stacked + break; + + } + } + } + +// For Alcatraz and later, we can configure the total memory size register dynamically +#if AMC_REG_VERSION > 2 + uint32_t device_size_Mbits = 64 << _amc_device_info.density; + uint32_t total_size_Mbytes = (AMC_NUM_CHANNELS * AMC_NUM_RANKS * device_size_Mbits) >> 3; + // Units of 128 MBs in the register + rMCC_DRAMACCCTRL = (total_size_Mbytes >> 7) - 1; + dprintf(DEBUG_INFO, "rMCC_DRAMACCCTRL: 0x%08x, memory_size: %u bytes\n", rMCC_DRAMACCCTRL, (total_size_Mbytes << 20)); +#endif + + if (amc_params.flags & FLAG_AMC_PARAM_ZQCL) { + if (resume) { + uint8_t temp; + + rAMC_ZQC = 0x00090000; + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0xa, 0xab); + spin(1); + rAMC_ZQC = 0x00080000; + + // MR4 read to bring memory out of self-refresh + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&temp); + } + + // Wait 5 us before freq change to make sure all refreshes have been flushed + spin(5); + } + + ////////////////////////////////////////////////////////// + // + // 6. Switch from boot-clock speed to normal speed + // + ////////////////////////////////////////////////////////// +#if !SUPPORT_FPGA + // Only enable AutoSR on pre-H6 devices +#if AMC_REG_VERSION < 3 && !SUB_PLATFORM_S7002 + rAMC_PWRMNGTEN |= 0x00000010; +#endif +#endif // !SUPPORT_FPGA + + rAMC_SCHEN = amc_params.schen_default | 0x1; // enable the scheduler + + amc_enable_slow_boot(false); + + amc_phy_enable_dqs_pulldown(true); + + ////////////////////////////////////////////////////////// + // + // 7. PHY DQ and address timing calibration + // + ////////////////////////////////////////////////////////// +#if !SUPPORT_FPGA + rAMC_READ_LEVELING = amc_params.readleveling; +#endif // !SUPPORT_FPGA + amc_phy_calibration_ca_rddq_cal(resume); + + ////////////////////////////////////////////////////////// + // + // 8. Enable power saving and other features, and turn on AMC scheduler + // + ////////////////////////////////////////////////////////// + amc_finalize(resume); + + amc_phy_finalize(); + +#if AMC_REG_VERSION < 3 && !SUB_PLATFORM_S7002 + // Program tunables + for (i = 0; i < sizeof(amc_tunables) / sizeof(amc_tunables[0]); i++) { + if (amc_tunables[i].reg == 0) + break; + *amc_tunables[i].reg = amc_tunables[i].value; + } +#endif + + ////////////////////////////////////////////////////////// + // + // 9. PHY write DQ calibration + // + ////////////////////////////////////////////////////////// + amc_phy_calibration_wrdq_cal(resume); + +#if (AMC_REG_VERSION == 3) || ((AMC_REG_VERSION == 2) && SUB_PLATFORM_S7002) + + // requires moving MR4 from step 8 to after wrdqcal + if (!resume) { + // MR4 to bring memory out of self-refresh + uint8_t odts; + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&odts); + } + + // Program tunables after wrdqcal for H6 + for (i = 0; i < sizeof(amc_tunables) / sizeof(amc_tunables[0]); i++) { + if (amc_tunables[i].reg == 0) + break; + *amc_tunables[i].reg = amc_tunables[i].value; + } +#endif + + // cache memory info for later + platform_set_memory_info(_amc_device_info.vendor_id, amc_get_memory_size()); + + return 0; +} + +void mcu_late_init(void) +{ +} + +uint64_t amc_get_memory_size(void) +{ + // if memory is not inited, density is unknown, spin here ... + if (false == _amc_device_info_inited) + for(;;) ; + + // device density (in MBytes) * num of channels * num of ranks + return ((8 << _amc_device_info.density) * AMC_NUM_CHANNELS * AMC_NUM_RANKS); +} + +const struct amc_memory_device_info *amc_get_memory_device_info(void) +{ + // if memory is not inited, device info is unknown, spin here ... + if (false == _amc_device_info_inited) + for(;;) ; + + return ((const struct amc_memory_device_info *)&_amc_device_info); +} + +const struct amc_param *amc_get_params(void) +{ + ASSERT(amc_params_initialized); + return &amc_params; +} + +void amc_scheduler_en_workaround(bool init) +{ + if (init) { + uint8_t temp[AMC_NUM_CHANNELS]; + + rAMC_PWRMNGTEN = 0x00000000; + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, 1, 0x4, (uintptr_t)temp); + } else { + rAMC_PWRMNGTEN = 0x00000010; + } +} + +// H6 and M7 specific routine used during dynamic calibration +#if (AMC_REG_VERSION == 3) || ((AMC_REG_VERSION == 2) && SUB_PLATFORM_S7002) + +// returns 1 if number of 1s in input is odd, otherwise returns 0 +static uint32_t amc_odd_parity(uint32_t input) +{ + uint32_t output = input; + + output = (output & 0x0000ffff) ^ (output >> 16); + output = (output & 0x000000ff) ^ (output >> 8); + output = (output & 0x0000000f) ^ (output >> 4); + output = (output & 0x00000003) ^ (output >> 2); + output = (output & 0x00000001) ^ (output >> 1); + + return output; +} + +// Given ch, rnk, bank, row, and col, compute the Apple Fabric address that CPU can use to do reads/writes +// For details of addr mapping, see "Address_Unamp.xls" at +// https://seg-fijipublic.ecs.apple.com/doc/release/index.php?dir=/reference/org-seg-services-vhost-seg--fijipublic.ecs.apple.com/content/doc/release/specs/Apple_IP/AMC +addr_t amc_get_uncached_dram_virt_addr(uint32_t ch, uint32_t rnk, uint32_t bank, uint32_t row, uint32_t col) +{ + addr_t system_addr; + uint32_t ch_dropped_addr, ch_inserted_val; + uint32_t col_val; + uint32_t rank_off, bank_off, row_off, col_off; + uint32_t temp_bank_bit2, temp_bank_bit1, temp_bank_bit0; + uint32_t rank_wid, bank_wid, row_wid, col_wid; + uint32_t addrcfg = rAMC_ADDRCFG; + uint32_t ch_insert_point, ch_insert_width, ch_insert_mask; + uint32_t addrmapmode = rAMC_ADDRMAP_MODE; +#if AMC_REG_VERSION < 3 + uint32_t addrbankhash0 = rAMC_AIU_ADDRBANKHASH0; + uint32_t addrbankhash1 = rAMC_AIU_ADDRBANKHASH1; + uint32_t addrbankhash2 = rAMC_AIU_ADDRBANKHASH2; +#else + uint32_t addrbankhash0 = rAMC_MCSADDRBNKHASH(0); + uint32_t addrbankhash1 = rAMC_MCSADDRBNKHASH(1); + uint32_t addrbankhash2 = rAMC_MCSADDRBNKHASH(2); +#endif + uint32_t chnldec = rAMC_CHNLDEC; + uint32_t amcen = rAMC_AMCEN; +#if AMC_REG_VERSION < 3 + uint32_t temp_ch_bit0, temp_ch_bit1; + bool h4p_legacy_mode = amcen & 0x80000000; +#endif + + system_addr = SDRAM_BASE_UNCACHED; + + /* + DRAM Address Mapping Mode (H6 and M7 uses RIBI2) + RSBS: 0 Rank Stacked, Bank Stacked. {CS, BA, RA, CA} + RIBI1: 1 Rank Interleaved, Bank Interleaved, Option 1. {RA, CA-high, CS, BA, CA-low(128B)} + RIBI2: 2 Rank Interleaved, Bank Interleaved, Option 2. {RA, CS, BA, CA} + RSBI1: 3 Rank Stacked, Bank Interleaved, Option 1. {CS, RA, CA-high, BA, CA-low(128B)} + RIBI3: 4 Rank Interleaved, Bank Interleaved, Option 3. {RA, CS, CA-high, BA, CA-low(128B)} + */ + + /* + BnkAddrWid + 2-bits: 0 + 3-bits: 1 (H6) + ColAddrWid + 8-bits: 0 + 9-bits: 1 + 10-bits: 2 (H6) + 11-bits: 3 + RowAddrWid + 12-bits: 0 + 13-bits: 1 + 14-bits: 2 (H6) + 15-bits: 3 + CsWid + 0-bits: 0 (N51) + 1-bits: 1 (J71) + */ + + // whether rank needs a bit depends on ADDRCFG.CSWID bit + rank_wid = ((addrcfg >> 24) & 1); + // rest of the bit widths also depend on ADDRCFG fields + bank_wid = (addrcfg & 1) + 2; + row_wid = ((addrcfg >> 16) & 0x3) + 12; + col_wid = ((addrcfg >> 8) & 0x3) + 8; + + // column bits always start at bit 2 (each [row, col] specifies 4 bytes) + col_off = 2; + + // these are used in addressing modes 1, 3, and 4 + uint32_t col_low_bits = 5; // 128B - 2 + uint32_t col_low_mask = (1 << col_low_bits) - 1; + + switch(addrmapmode) + { + case 0: + col_val = col; + row_off = col_off + col_wid; + bank_off = row_off + row_wid; + rank_off = bank_off + bank_wid; + break; + case 1: + col_val = ((col & ~col_low_mask) << (rank_wid + bank_wid)) | (col & col_low_mask); + bank_off = col_off + col_low_bits; + rank_off = bank_off + bank_wid; + row_off = col_off + col_wid + bank_wid + rank_wid; // slightly different due to col split + break; + default: + case 2: + // RIBI2 (H6) + col_val = col; + bank_off = col_off + col_wid; + rank_off = bank_off + bank_wid; + row_off = rank_off + rank_wid; + break; + case 3: + col_val = ((col & ~col_low_mask) << bank_wid) | (col & col_low_mask); + bank_off = col_off + col_low_bits; + row_off = col_off + col_wid + bank_wid; // slightly different due to col split + rank_off = row_off + row_wid; + break; + case 4: + col_val = ((col & ~col_low_mask) << bank_wid) | (col & col_low_mask); + bank_off = col_off + col_low_bits; + rank_off = col_off + col_wid + bank_wid; // slightly different due to col split + row_off = rank_off + rank_wid; + break; + } + + // bank hashing + // + temp_bank_bit2 = amc_odd_parity(row & ~addrbankhash2); + temp_bank_bit1 = amc_odd_parity(row & ~addrbankhash1); + temp_bank_bit0 = amc_odd_parity(row & ~addrbankhash0); + bank = bank ^ ((temp_bank_bit2 << 2) | (temp_bank_bit1 << 1) | temp_bank_bit0); + + // our address so far - only the channel num stuff is missing now + // + ch_dropped_addr = (rnk << rank_off) | (bank << bank_off) | (row << row_off) | (col_val << col_off); + + /* + ChSelTyp + Interleaving: 0 (H6) + Stacked: 1 + */ + if (chnldec & 1) { + // in stacked mode, ch will be inserted at bit 29 for H6 + ch_inserted_val = ch_dropped_addr | (ch << (((chnldec >> 16) & 0x7) + 24)); + } + else { // interleaving + +#if AMC_REG_VERSION < 3 + if (h4p_legacy_mode) { + switch((chnldec >> 8) & 0xf) { + case (1 << 0): + ch_insert_point = 6; + break; + + case (1 << 1): + ch_insert_point = 8; + break; + + case (1 << 2): + ch_insert_point = 10; + break; + + case (1 << 3): + ch_insert_point = 12; + break; + + default: + panic("AMC CHNLDEC is not programmed correctly\n"); + } + } + else +#endif + { + // ch is inserted at bit 6 for interleaving + ch_insert_point = 6; + } + + // ch insertion width ( 1 or 0 bits) depends on whether more than 1 channel is enabled + ch_insert_width = (amcen >> 8) & 1; + ch_insert_width += (amcen >> 12) & 1; + + // now fix the address so we can reconstruct the XOR + ch_insert_mask = (1 << ch_insert_point) - 1; + ch_dropped_addr = ((ch_dropped_addr & ~ch_insert_mask) << ch_insert_width) | (ch_dropped_addr & ch_insert_mask); + + // calculate the XOR value - XOR all the bits + + ch_inserted_val = ch; +#if AMC_REG_VERSION < 3 + if (h4p_legacy_mode) { + switch((chnldec >> 8) & 0xf) { + case (1 << 0): + ch_inserted_val ^= (ch_dropped_addr >> 6); + break; + + case (1 << 1): + ch_inserted_val ^= (ch_dropped_addr >> 8); + break; + + case (1 << 2): + ch_inserted_val ^= (ch_dropped_addr >> 10); + break; + + case (1 << 3): + ch_inserted_val ^= (ch_dropped_addr >> 12); + break; + } + } + else { + temp_ch_bit0 = amc_odd_parity(ch_inserted_val & (rAMC_CHNLDEC2 & 0x3ffffff)); + temp_ch_bit1 = amc_odd_parity(ch_inserted_val & (rAMC_CHNLDEC4 & 0x3ffffff)); + ch_inserted_val = (temp_ch_bit1 << 1) | temp_ch_bit0; + } +#else + ch_inserted_val |= (ch_dropped_addr >> ch_insert_point); + ch_inserted_val = amc_odd_parity(ch_inserted_val & rMCC_MCUCHNHASH); +#endif + + // finally, insert the XOR bits + ch_insert_mask = (1 << ch_insert_width) - 1; // reuse this var in a pseudo-related way + ch_inserted_val = ch_dropped_addr | ((ch_inserted_val & ch_insert_mask) << ch_insert_point); + } + + system_addr += (addr_t) ch_inserted_val; + + return system_addr; +} +#endif // AMC_REG_VERSION > 2 diff --git a/drivers/apple/amc/amc_v2.c b/drivers/apple/amc/amc_v2.c new file mode 100644 index 0000000..a4898de --- /dev/null +++ b/drivers/apple/amc/amc_v2.c @@ -0,0 +1,660 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// if there are separate ap/dev parameters, amc_init will copy +// the appropriate ones here +#if AMC_PARAMS_AP_DEV +static struct amc_param amc_params; +#endif +static bool amc_params_initialized; + +static const struct amc_channel_addrs { + volatile uint32_t *rnkcfg; + volatile uint32_t *mrcmd; + volatile uint32_t *mrstatus; + uint32_t mrpoll; + uint32_t mrshift; + volatile uint32_t *initcmd; + volatile uint32_t *initstatus; + uint32_t mcuen; +} _amc_chregs[] = { + { &rAMC_CH0RNKCFG0, &rAMC_CH0MRCMD, &rAMC_CH01MRSTATUS, 0x01, 8, &rAMC_CH0INITCMD, &rAMC_CH01INITSTATUS, 0x0001 }, + { &rAMC_CH1RNKCFG0, &rAMC_CH1MRCMD, &rAMC_CH01MRSTATUS, 0x10, 16, &rAMC_CH1INITCMD, &rAMC_CH01INITSTATUS, 0x0100 }, + { &rAMC_CH2RNKCFG0, &rAMC_CH2MRCMD, &rAMC_CH23MRSTATUS, 0x01, 8, &rAMC_CH2INITCMD, &rAMC_CH23INITSTATUS, 0x0010 }, + { &rAMC_CH3RNKCFG0, &rAMC_CH3MRCMD, &rAMC_CH23MRSTATUS, 0x10, 16, &rAMC_CH3INITCMD, &rAMC_CH23INITSTATUS, 0x1000 }, +}; + +static struct amc_memory_device_info _amc_device_info; +static bool _amc_device_info_inited; + +/* + * Based on Fiji AMC Init.html (v48 - dated May 23, 2014). Tunables v7.1.0 + * Capri AMC Init.html (v23 - dated May 23, 2014). Tunables v8.6.0 + * j42d and j96 AMC Init.2GB.html (v48 - dated Dec 11, 2014) + */ + +void amc_mrcmd(amc_mrcmd_op_t op, uint8_t channels, uint8_t ranks, int reg, uintptr_t val) +{ + uint8_t ch, r; + + for (ch = 0; ch < channels; ch++) { + for (r = 0; r < ranks; r++) { + amc_mrcmd_to_ch_rnk(op, ch, r, reg, val); + } + } +} + +// Only send the cmd to specific channel and rank (used during calibration on H6 and later) +void amc_mrcmd_to_ch_rnk(amc_mrcmd_op_t op, uint8_t channel, uint8_t rank, int32_t reg, uintptr_t val) +{ + uint32_t cmd, regval; + uint8_t *buffer = (uint8_t *) val; + + if (op == MR_READ) + cmd = 0x00000011 | (reg << 8); + else + cmd = 0x00000001 | (reg << 8) | (((uint32_t)val) << 24); + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + *_amc_chregs[channel].mrcmd = cmd | (rank << 16); + while(((regval = *_amc_chregs[channel].mrstatus) & _amc_chregs[channel].mrpoll) != 0) ; + if (op == MR_READ) + *buffer++ = (regval >> _amc_chregs[channel].mrshift) & 0xff; +} + +void amc_enable_autorefresh(void) +{ + // Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last. + + rAMC_AREFEN_FREQ(3) = 0x00000000; + rAMC_AREFEN_FREQ(2) = 0x00000000; + rAMC_AREFEN_FREQ(1) = 0x00000000; + + rAMC_AREFEN_FREQ(0) = 0x01011111; +} + +int32_t amc_init(bool resume) +{ + uint8_t config_id = 0; + uint32_t tREFi; + uint64_t deadline; + uint32_t ch, r, i; + +#if AMC_PARAMS_AP_DEV + if (target_config_dev()) { + memcpy(&amc_params, &amc_params_dev, sizeof(amc_params)); + } else { + memcpy(&amc_params, &amc_params_ap, sizeof(amc_params)); + } +#endif + amc_params_initialized = true; + + // Make sure we're at full memory frequency + clocks_set_performance(kPerformanceMemoryFull); + + // The clock_reset_device() call takes care of the requirements in + clock_reset_device(CLK_MCU); + + // Keep track of 50us after MCU reset to ensure resume timing is in spec + deadline = timer_get_ticks() + timer_usecs_to_ticks(50); + + ////////////////////////////////////////////////////////// + // + // 1. AMC initial configuration + // + ////////////////////////////////////////////////////////// + + rAMC_PHYUPDATETIMERS = 0x50; + amc_phy_preinit(); + + rAMC_LAT = amc_params.lat; + rAMC_PHYRDWRTIM = amc_params.phyrdwrtim; + + tREFi = amc_params.tREFi; + + for (i = 0; i < AMC_FREQUENCY_SLOTS; i++) { + rAMC_CAS_FREQ(i) = amc_params.freq[i].cas; + rAMC_PCH_FREQ(i) = amc_params.freq[i].pch; + rAMC_ACT_FREQ(i) = amc_params.freq[i].act; + rAMC_AUTO_FREQ(i) = amc_params.freq[i].autoref | ((i == 0) ? tREFi : 0); + rAMC_SELF_FREQ(i) = amc_params.freq[i].selfref; + rAMC_MODE_FREQ(i) = amc_params.freq[i].modereg; + } + + rAMC_PDN = amc_params.pdn; + rAMC_DERATE = amc_params.derate; + rAMC_RD = amc_params.read; + + rAMC_BUSTAT_FREQ01 = amc_params.bustat; + rAMC_BUSTAT_FREQ23 = amc_params.bustat2; + rAMC_MIFCASSCH_FREQ(0) = 0x110; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + for (r = 0; r < AMC_NUM_RANKS; r++) + *(_amc_chregs[ch].rnkcfg + AMC_RNKCFG_OFFSET(r)) = 1; + + + rAMC_PWRMNGTEN = amc_params.pwrmngten_default; + rAMC_SCHEN = amc_params.schen_default; // disable the scheduler + + rAMC_MCPHY_UPDTPARAM1 = amc_params.mcphyupdate1; + rAMC_MCPHY_UPDTPARAM = amc_params.mcphyupdate; + + // Enable MCUs + rAMC_AMCEN = 0; + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + rAMC_AMCEN |= _amc_chregs[ch].mcuen; + + amc_configure_address_decoding_and_mapping(); + + ////////////////////////////////////////////////////////// + // + // 2. PHY Initial Configuartions + // + ////////////////////////////////////////////////////////// + amc_phy_init(resume); + + ////////////////////////////////////////////////////////// + // + // 3. Self-Refresh and DRAM Reset + // + ////////////////////////////////////////////////////////// + + // Wait 5 us after Impedence Calibration to avoid McPhyPending + // preventing the SRFSM from exiting SR. + spin(5); + + amc_phy_restore_calibration_values(resume); + + rAMC_AREFPARAM = amc_params.arefparam; + + amc_enable_slow_boot(true); + +#if !SUPPORT_FPGA + // Enable auto refresg derating by setting TempDrtEn + rAMC_ODTS = 0x00010000; +#endif + + rAMC_LONGSR = amc_params.longsr; + + if (resume) { + amc_enable_autorefresh(); + // Software must guarantee that at least 50 us have passed since the de-assertion + // of AMC reset before self-refresh exit, in the resume-boot case. + while (deadline > timer_get_ticks()) ; + } + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + *_amc_chregs[ch].initcmd = 0x00001000; // start self-refresh exit seq on ch + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + while (*_amc_chregs[ch].initcmd != 0) ; + + ////////////////////////////////////////////////////////// + // + // 4. DRAM Reset, ZQ Calibration & Configuration (cold boot only) + // + ////////////////////////////////////////////////////////// + if (!resume) { + spin(200); + + // MR63 (DRAM reset and auto-refresh enable) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x3f, 0xfc); + spin(12); + + // MR10 (ZQ initial calibration) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0xa, 0xff); + spin(1); + + // MR2 register (read/write latency, assumes legal combo in amc_params) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x2, amc_params.mr2); + + // MR1 + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x1, amc_params.mr1); + + // MR3 register (output buffer drive strength 48-Ohm unless overridden) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x3, (amc_params.mr3 ? amc_params.mr3 : 0x3)); + } + + ////////////////////////////////////////////////////////// + // + // 5. Topology-specific AMC re-configuration + // + ////////////////////////////////////////////////////////// + + if (resume) { + rAMC_ZQC = 0x00090000; + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0xa, 0xab); + spin(1); + rAMC_ZQC = 0x00080000; + } + + rAMC_ADDRCFG = amc_params.addrcfg; + + // Read device info: vendor, revision, and configuration info + // Configuration info: device width, device type, device density + // We are assuming all of our devices are identical + amc_mrcmd(MR_READ, 1, 1, 0x5, (uintptr_t)&_amc_device_info.vendor_id); + amc_mrcmd(MR_READ, 1, 1, 0x6, (uintptr_t)&_amc_device_info.rev_id); + amc_mrcmd(MR_READ, 1, 1, 0x7, (uintptr_t)&_amc_device_info.rev_id2); + amc_mrcmd(MR_READ, 1, 1, 0x8, (uintptr_t)&config_id); + +#if SUPPORT_FPGA + if ((config_id == 0xff) || (config_id == 0)) { + // Fake the MR_READ results to something accurate but innocuous + config_id = (0 << JEDEC_MR8_WIDTH_SHIFT) | (5 << JEDEC_MR8_DENSITY_SHIFT) | (0 << JEDEC_MR8_TYPE_SHIFT); + _amc_device_info.vendor_id = JEDEC_MANUF_ID_RSVD2; + } +#endif + + if ((_amc_device_info.vendor_id == 0) || (config_id == 0)) + panic("failed to read vendor-id/config-id, vid:%08x, config:%08x, rev:%08x\n", _amc_device_info.vendor_id, + config_id, _amc_device_info.rev_id); + + _amc_device_info.width = (32 >> ((config_id >> JEDEC_MR8_WIDTH_SHIFT) & JEDEC_MR8_WIDTH_MASK)) >> 3; + _amc_device_info.density = ((config_id >> JEDEC_MR8_DENSITY_SHIFT) & JEDEC_MR8_DENSITY_MASK); + _amc_device_info.type = ((config_id >> JEDEC_MR8_TYPE_SHIFT) & JEDEC_MR8_TYPE_MASK); + + _amc_device_info_inited = true; + + dprintf(DEBUG_INFO, "sdram vendor id:0x%02x rev id:0x%02x rev id2:%02x\n", + _amc_device_info.vendor_id, _amc_device_info.rev_id, _amc_device_info.rev_id2); + dprintf(DEBUG_INFO, "sdram config: width %d/%d Mbit/type %d\n", _amc_device_info.width << 3, + 64 << _amc_device_info.density, _amc_device_info.type); + + if ((_amc_device_info.density < JEDEC_DENSITY_1Gb) || (_amc_device_info.density > JEDEC_DENSITY_32Gb)) + panic("unsupported DRAM density: %dMbit", 64 << _amc_device_info.density); + + uint32_t device_size_Mbits = 64 << _amc_device_info.density; + uint32_t total_size_Mbytes = (AMC_NUM_CHANNELS * AMC_NUM_RANKS * device_size_Mbits) >> 3; + // Units of 128 MBs in the register + rMCC_DRAMACCCTRL = (total_size_Mbytes >> 7) - 1; + dprintf(DEBUG_INFO, "rMCC_DRAMACCCTRL: 0x%08x, memory_size: %u bytes\n", rMCC_DRAMACCCTRL, (total_size_Mbytes << 20)); + + rMCC_CHNLDEC = amc_params.mccchnldec; + rAMC_MCSCHNLDEC = amc_params.mcschnldec; + rMCC_MCUCHNHASH = amc_params.mcuchnhash; + if (amc_params.mcuchnhash2) + rMCC_MCUCHNHASH2 = amc_params.mcuchnhash2; + + // DRAM vendor-specific workarounds + amc_dram_workarounds(resume); + + ////////////////////////////////////////////////////////// + // + // 6. Switch from boot-clock speed to normal speed + // + ////////////////////////////////////////////////////////// + + // Wait 5 us before freq change to make sure all refreshes have been flushed + spin(5); + + rAMC_SCHEN = amc_params.schen_default | 0x1; // enable the scheduler + + amc_phy_pre_normal_speed_enable(); + amc_enable_slow_boot(false); + + ////////////////////////////////////////////////////////// + // + // 7. PHY DQ and address timing calibration + // + ////////////////////////////////////////////////////////// +#if !SUPPORT_FPGA + rAMC_READ_LEVELING = amc_params.readleveling; + amc_phy_calibration_ca_rddq_cal(resume); +#endif // !SUPPORT_FPGA + + ////////////////////////////////////////////////////////// + // + // 8. Enable other features + // + ////////////////////////////////////////////////////////// + + rAMC_ZQC = 0x010c03ff; + rAMC_QBREN = 0x00110001; + + if (!resume) + amc_enable_autorefresh(); + + ////////////////////////////////////////////////////////// + // + // 9. Enable the Fast Critical Word Forwarding feature + // + ////////////////////////////////////////////////////////// + + rAMC_QBRPARAM = amc_params.qbrparam; + rAMC_QBREN = 0x00111001; + rMCC_MCCGEN = 0x00000126; + + ////////////////////////////////////////////////////////// + // + // 10. PHY write DQ calibration + // + ////////////////////////////////////////////////////////// +#if !SUPPORT_FPGA + amc_phy_calibration_wrdq_cal(resume); +#endif + rAMC_PHYUPDATETIMERS = 0x00000f50; + + ////////////////////////////////////////////////////////// + // + // 11. Enable Power & ClockGating features + // + ////////////////////////////////////////////////////////// + amc_phy_finalize(); + amc_finalize(resume); + + ////////////////////////////////////////////////////////// + // + // 12. ODTS read and bring memory out of self-refresh + // + ////////////////////////////////////////////////////////// + + // MR4 read to bring memory out of self-refresh + uint8_t temp; + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&temp); + + rAMC_ODTS |= amc_params.odts; + + // Program tunables at the end + for (i = 0; i < sizeof(amc_tunables) / sizeof(amc_tunables[0]); i++) { + if (amc_tunables[i].reg == 0) + break; + *amc_tunables[i].reg = amc_tunables[i].value; + } + + // cache memory info for later + platform_set_memory_info(_amc_device_info.vendor_id, amc_get_memory_size()); + + return 0; +} + +void mcu_late_init(void) +{ +} + +uint64_t amc_get_memory_size(void) +{ + // if memory is not inited, density is unknown, spin here ... + if (false == _amc_device_info_inited) + for(;;) ; + + // device density (in MBytes) * num of channels * num of ranks + return ((8 << _amc_device_info.density) * AMC_NUM_CHANNELS * AMC_NUM_RANKS); +} + +const struct amc_memory_device_info *amc_get_memory_device_info(void) +{ + // if memory is not inited, device info is unknown, spin here ... + if (false == _amc_device_info_inited) + for(;;) ; + + return ((const struct amc_memory_device_info *)&_amc_device_info); +} + +const struct amc_param *amc_get_params(void) +{ + ASSERT(amc_params_initialized); + return &amc_params; +} + +/* + * Some routines used during dynamic calibration + */ + +// Some AMC features to be changed before calibration starts, and restored after calibration is complete +void amc_calibration_start(bool start) +{ + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + if (start) { + // Disable OdtsRdIntrvl + rAMC_ODTS &= 0xFFFFFC00; + } else { + // Re-enable OdtsRdIntrvl + rAMC_ODTS |= amc_params.odts; + } +} + +void amc_enable_rddqcal(bool enable) +{ + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + if (enable) { + rAMC_READ_LEVELING |= 1; + } else { + rAMC_READ_LEVELING &= ~1; + } +} + +void amc_wrdqcal_start(bool start) +{ + if (start) { + + // Enable WriteMergeEn and WqInOrderEn + rAMC_PSQWQCTL0 = (1 << 8) | (1 << 0); + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + // Set SelfRefTmrVal to max + rAMC_PWRMNGTPARAM |= (0xFFFF << 16); + + // Designer suggests 0xBB, so that writes do not age out + rAMC_PSQWQCTL1 = 0xBB; + + } else { + rAMC_PSQWQCTL0 = 0; + } +} + +// returns 1 if number of 1s in input is odd, otherwise returns 0 +static uint32_t amc_odd_parity(uint32_t input) +{ + uint32_t output = input; + + output = (output & 0x0000ffff) ^ (output >> 16); + output = (output & 0x000000ff) ^ (output >> 8); + output = (output & 0x0000000f) ^ (output >> 4); + output = (output & 0x00000003) ^ (output >> 2); + output = (output & 0x00000001) ^ (output >> 1); + + return output; +} + +// Given ch, rnk, bank, row, and col, compute the Apple Fabric address that CPU can use to do reads/writes +// For details of addr mapping, see "Address_Unamp.xls" at +// https://seg-fijipublic.ecs.apple.com/doc/release/index.php?dir=/reference/org-seg-services-vhost-seg--fijipublic.ecs.apple.com/content/doc/release/specs/Apple_IP/AMC +uint64_t amc_get_uncached_dram_virt_addr(uint32_t ch, uint32_t rnk, uint32_t bank, uint32_t row, uint32_t col) +{ + uint64_t system_addr; + uint32_t ch_dropped_addr, ch_inserted_val; + uint32_t col_val; + uint32_t bank_addr_pos, col_low_bits, col_low_mask; + uint32_t rank_off, bank_off, row_off, col_off; + uint32_t temp_bank_bit2, temp_bank_bit1, temp_bank_bit0; + uint32_t rank_wid, bank_wid, row_wid, col_wid; + uint32_t addrcfg = rAMC_ADDRCFG; + uint32_t ch_insert_point, ch_insert_width, ch_insert_mask; + uint32_t addrmapmode = rAMC_ADDRMAP_MODE; + uint32_t mcsaddrbankhash0 = rAMC_MCSADDRBNKHASH(0); + uint32_t mcsaddrbankhash1 = rAMC_MCSADDRBNKHASH(1); + uint32_t mcsaddrbankhash2 = rAMC_MCSADDRBNKHASH(2); + uint32_t chnldec = rMCC_CHNLDEC; + uint32_t mcschnldec = rAMC_MCSCHNLDEC; + + system_addr = SDRAM_BASE_UNCACHED; + + /* + DRAM Address Mapping Mode (H7 uses RIBI1) + RSBS: 0 Rank Stacked, Bank Stacked. {CS, BA, RA, CA} + RIBI1: 1 Rank Interleaved, Bank Interleaved, Option 1. {RA, CA-high, CS, BA, CA-low(128B)} + RIBI2: 2 Rank Interleaved, Bank Interleaved, Option 2. {RA, CS, BA, CA} + RSBI1: 3 Rank Stacked, Bank Interleaved, Option 1. {CS, RA, CA-high, BA, CA-low(128B)} + RIBI3: 4 Rank Interleaved, Bank Interleaved, Option 3. {RA, CS, CA-high, BA, CA-low(128B)} + */ + + /* + BnkAddrWid + 2-bits: 0 + 3-bits: 1 (H7) + ColAddrWid + 8-bits: 0 + 9-bits: 1 + 10-bits: 2 (H7) + 11-bits: 3 + RowAddrWid + 12-bits: 0 + 13-bits: 1 + 14-bits: 2 (H7) + 15-bits: 3 + CsWid + 0-bits: 0 + 1-bits: 1 + */ + + // whether rank needs a bit depends on ADDRCFG.CSWID bit + rank_wid = ((addrcfg >> 24) & 1); + // rest of the bit widths also depend on ADDRCFG fields + bank_wid = (addrcfg & 1) + 2; + row_wid = ((addrcfg >> 16) & 0x3) + 12; + col_wid = ((addrcfg >> 8) & 0x3) + 8; + + // column bits always start at bit 2 (each [row, col] specifies 4 bytes) + col_off = 2; + + bank_addr_pos = 6 + ((addrmapmode & 0x700) >> 8); + + switch(addrmapmode & 1) + { + case 0: + col_val = col; + row_off = col_off + col_wid; + bank_off = row_off + row_wid; + rank_off = bank_off + bank_wid; + break; + + default: + case 1: + // RIBI1 (H7) + if (bank_addr_pos == (col_wid + col_off)) { + col_val = col; + bank_off = col_off + col_wid; + rank_off = bank_off + bank_wid; + row_off = rank_off + rank_wid; + } else { + // bank bits interleaved with column bits (not POR on H7) + col_low_bits = bank_addr_pos - col_off; + col_low_mask = (1 << col_low_bits) - 1; + + col_val = ((col & ~col_low_mask) << bank_wid) | (col & col_low_mask); + bank_off = bank_addr_pos; + rank_off = col_off + col_wid + bank_wid; + row_off = rank_off + rank_wid; + } + break; + } + + // bank hashing + // + temp_bank_bit2 = amc_odd_parity(row & ~mcsaddrbankhash2); + temp_bank_bit1 = amc_odd_parity(row & ~mcsaddrbankhash1); + temp_bank_bit0 = amc_odd_parity(row & ~mcsaddrbankhash0); + bank = bank ^ ((temp_bank_bit2 << 2) | (temp_bank_bit1 << 1) | temp_bank_bit0); + + // our address so far - only the channel num stuff is missing now + // + ch_dropped_addr = (rnk << rank_off) | (bank << bank_off) | (row << row_off) | (col_val << col_off); + + /* + ChSelTyp + Interleaving: 0 (H7) + Stacked: 1 + */ + if (chnldec & 1) { + // in stacked mode, ch will be inserted at bit 29 for H7 + ch_inserted_val = ch_dropped_addr | (ch << (((chnldec >> 16) & 0xF) + 24)); + } + else { // interleaving + + // for H7, ch is inserted for interleaving at bit specified by rAMC_MCSCHNLDEC.ChnlStartBit + ch_insert_point = 6 + ((mcschnldec & 0x300) >> 8); + + // ch insertion width (0, 1, 2, or 3 bits) depends on how many channels are enabled + ch_insert_width = (mcschnldec & 0x30000) >> 16; + + // now fix the address so we can reconstruct the XOR + ch_insert_mask = (1 << ch_insert_point) - 1; + ch_dropped_addr = ((ch_dropped_addr & ~ch_insert_mask) << ch_insert_width) | (ch_dropped_addr & ch_insert_mask); + + if (ch_insert_width <= 1) { + // calculate the XOR value - XOR all the bits (only the bits that can participate -- determined via rMCC_MCUCHNHASH) + ch_inserted_val = ch | (ch_dropped_addr >> ch_insert_point); + // now shift up the ch_inserted_val to align with rMCC_MCUCHNHASH, whose bit 0 maps to PA[6] of AF address + ch_inserted_val = amc_odd_parity((ch_inserted_val << (ch_insert_point - 6)) & rMCC_MCUCHNHASH); + } else { + // This code only handles 2 bits for channel number + if (ch_insert_width > 2) + panic("Unable to handle addressing for more than 4 channels"); + + // handle 2 bit channel value differently (for Capri) + uint32_t chnhash_addr = (ch << (ch_insert_point - 6) | (ch_dropped_addr >> 6)); + ch_inserted_val = amc_odd_parity(chnhash_addr & rMCC_MCUCHNHASH); + + ch_inserted_val |= (amc_odd_parity(chnhash_addr & rMCC_MCUCHNHASH2)) << 1; + } + + // finally, insert the XOR bits + ch_insert_mask = (1 << ch_insert_width) - 1; // reuse this var in a pseudo-related way + ch_inserted_val = ch_dropped_addr | ((ch_inserted_val & ch_insert_mask) << ch_insert_point); + } + + system_addr += (uint64_t) ch_inserted_val; + return system_addr; +} + +// Returns number of consecutive bytes given channel and rank before channel interleaving +uint32_t amc_get_consecutive_bytes_perchnrnk(void) +{ + // FIXME: DV says assume this is 0 for now (resulting in 64 consecutive bytes) + // uint32_t ch_start_bit = (rAMC_MCSCHNLDEC & 0x300) >> 8; + uint32_t ch_start_bit = 0; + + // given ChnlStartBit, consecutive bytes is simply 1 << (6 + ChnlStartBit) + return (1 << (6 + ch_start_bit)); +} diff --git a/drivers/apple/amc/calibration_v1.c b/drivers/apple/amc/calibration_v1.c new file mode 100644 index 0000000..350a7ac --- /dev/null +++ b/drivers/apple/amc/calibration_v1.c @@ -0,0 +1,576 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Constants across phys +#define NUM_BYTES (AMC_CHANNEL_WIDTH) // channel width in words +#define RD_DQ_RETEST_COUNT (1) +#define WR_DQ_RETEST_COUNT (1) +#define BINARY_SEARCH_THRESHOLD (2) +#define INCR_SEARCH_STEP_SIZE (4) +#define WRITE_REGION_SIZE (64) // in words +#define CA_PIVOTS_LIST_MAX_SIZE (9) +#define DQ_PIVOTS_LIST_MAX_SIZE (5) +#define CA_PIVOT_THRESHOLD (2) + +// Phy specific +#define CA_PIVOTS_LIST_SIZE (calibration_data->ca_pivots_list_size) +#define DQ_PIVOTS_LIST_SIZE (calibration_data->dq_pivots_list_size) +#define BIT_TIME_PS (calibration_data->bit_time_ps) +#define MIN_CA_WINDOW_WIDTH_PS (calibration_data->min_ca_window_width_ps) +#define MIN_DQ_WINDOW_WIDTH_PS (calibration_data->min_dq_window_width_ps) +#define CA_PIVOT_STEP_SIZE_PS (calibration_data->ca_pivot_step_size_ps) +#define DQ_PIVOT_STEP_SIZE_PS (calibration_data->dq_pivot_step_size_ps) +#define MAX_OFFSET_SETTING (calibration_data->max_offset_setting) +#define MIN_OFFSET_FACTOR (calibration_data->min_offset_factor) +#define DLL_F2_DELAY_FS (calibration_data->dll_f2_delay_fs) + +// Macros +#define RD_WR_ADDR_OFFSET(offset) (((((offset) < 0) ? 1 : 0) << 6) | __abs((offset))) + +// Local variables +static int calibration_done; +static const struct amc_phy_calibration_data *calibration_data; + +static const int *ca_pivot_ps; +static const int *dq_pivot_ps; +static int ca_pivot_fs[CA_PIVOTS_LIST_MAX_SIZE] = { -1 }; +static int dq_pivot_fs[DQ_PIVOTS_LIST_MAX_SIZE] = { -1 }; +static int min_offset_fs = -1; +static int max_offset_fs = -1; +static int dq_pivot_step_size_fs = -1; +static int min_dq_window_width_fs = -1; +static uint32_t save_restore_region_content[WRITE_REGION_SIZE]; + +// Local functions +static void calibration_ca_rddq_cal_init(); +static void calibration_ca_rddq_cal_finalize(); +static int calibration_find_min_element(int8_t *array, uint8_t array_len); +static int calibration_binary_search_offset(uint8_t ch, uint8_t byte, int8_t sweep_lo, int8_t sweep_hi); +static int calibration_check_rddq(uint8_t ch, uint8_t byte); +static void calibration_rddq_cal(uint8_t ch, int8_t *rd_dq_offset, int8_t *rd_dq_window); +static int8_t calibration_ca_rddq_cal(uint8_t ch); +static void calibration_wrdq_cal(uint8_t ch, int8_t *wr_dq_offset, int8_t *wr_dq_window); +static void calibration_get_save_restore_region(uint8_t ch, uint32_t **region); + +// External functions +extern void amc_scheduler_en_workaround(bool init); + + +/////////////////////////////////////////////////////////////////////////////// +////// Global functions +/////////////////////////////////////////////////////////////////////////////// + +void amc_phy_calibration_restore_ca_offset(uint8_t ch) +{ + // restore CA offsets from PMU + int8_t ca_offset; + + if (power_get_nvram(kPowerNVRAMiBootMemCalCAOffset0Key + ch, (uint8_t *)&ca_offset) == -1) + for(;;) ; + + amc_phy_set_addr_offset(ch, RD_WR_ADDR_OFFSET(ca_offset)); +} + +void amc_phy_calibration_ca_rddq_cal(bool resume) +{ + uint8_t ch; + int8_t ca_offset; + + if (amc_phy_rddq_cal() == true) { + calibration_done = 1; + return; + } + + calibration_data = amc_phy_get_calibration_data(); + ca_pivot_ps = calibration_data->ca_pivot_ps; + dq_pivot_ps = calibration_data->dq_pivot_ps; + + // force resume boot flow if indicated by phy data (for AMP) + if (calibration_data->use_resume_boot_flow) + resume = true; + + calibration_ca_rddq_cal_init(); + + if (!resume) { + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + // find offset, and save address offset to PMU + ca_offset = calibration_ca_rddq_cal(ch); + if (power_set_nvram(kPowerNVRAMiBootMemCalCAOffset0Key + ch, ca_offset) != 0) + for (;;) ; + } + } + else { + int8_t rd_dq_offset[NUM_BYTES]; + int8_t rd_dq_window[NUM_BYTES]; + uint8_t byte; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + calibration_rddq_cal(ch, rd_dq_offset, rd_dq_window); + + // shift it, if needed + amc_phy_shift_dq_offset(rd_dq_offset, NUM_BYTES); + + for (byte = 0; byte < NUM_BYTES; byte++) + amc_phy_set_rd_offset(ch, byte, RD_WR_ADDR_OFFSET(rd_dq_offset[byte])); + + amc_phy_run_dll_update(ch); + } + } + + calibration_ca_rddq_cal_finalize(); +} + +void amc_phy_calibration_wrdq_cal(bool resume) +{ + uint8_t ch; + uint32_t saved_addr_map_mode, chnselhibits; + const struct amc_memory_device_info *dev_info; + + if (calibration_done) + return; + + saved_addr_map_mode = 0; + + // disable pulse-mode dll operation + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + amc_phy_configure_dll_pulse_mode(ch, false); + + // save aiucfg.aiuchnldec + saved_addr_map_mode = *(volatile uint32_t *)(AMC_BASE_ADDR + 0x0A4); + + dev_info = amc_get_memory_device_info(); + if (dev_info->density == JEDEC_DENSITY_4Gb) + chnselhibits = 5; + else if (dev_info->density == JEDEC_DENSITY_2Gb) + chnselhibits = 4; + else + chnselhibits = 3; + + // aiucfg.aiuchnldec = (DENSITY = 2Gb) ? 0x0004_0101) : 0x0003_0101 + *(volatile uint32_t *)(AMC_BASE_ADDR + 0x0A4) = ((chnselhibits << 16) | (1 << 8) | (1 << 0)); + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + int8_t wr_dq_window[NUM_BYTES]; + int8_t wr_dq_offset[NUM_BYTES]; + uint8_t byte; + + if (resume) { + uint32_t word; + uint32_t *region; + + memset(save_restore_region_content, 0, sizeof(save_restore_region_content)); + + calibration_get_save_restore_region(ch, ®ion); + + for(word = 0; word < WRITE_REGION_SIZE; word++) + save_restore_region_content[word] = *(region + word); + } + + memset(wr_dq_window, 0, sizeof(wr_dq_window)); + memset(wr_dq_offset, 0, sizeof(wr_dq_offset)); + + calibration_wrdq_cal(ch, wr_dq_offset, wr_dq_window); + + // shift it, if needed + amc_phy_shift_dq_offset(wr_dq_offset, NUM_BYTES); + + for (byte = 0; byte < NUM_BYTES; byte++) + amc_phy_set_wr_offset(ch, byte, RD_WR_ADDR_OFFSET(wr_dq_offset[byte])); + + amc_phy_run_dll_update(ch); + + if (resume) { + uint32_t word; + uint32_t *region; + + calibration_get_save_restore_region(ch, ®ion); + + for(word = 0; word < WRITE_REGION_SIZE; word++) + *(region + word) = save_restore_region_content[word]; + } + } + + // restore aiucfg.aiuchnldec + *(volatile uint32_t *)(AMC_BASE_ADDR + 0x0A4) = saved_addr_map_mode; + + // re-enable pulse mode + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) + amc_phy_configure_dll_pulse_mode(ch, true); + + calibration_done = 1; +} + +/////////////////////////////////////////////////////////////////////////////// +////// Local functions +/////////////////////////////////////////////////////////////////////////////// + +static void calibration_ca_rddq_cal_init() +{ + uint8_t i; + uint32_t fine_lock_ps; + + amc_phy_calibration_init(&fine_lock_ps); + + // workaround for AMC scheduler enable issue + amc_scheduler_en_workaround(true); + + max_offset_fs = __min((int)MAX_OFFSET_SETTING, ((BIT_TIME_PS / 4) / (int)fine_lock_ps)); + min_offset_fs = __max(-((int)MAX_OFFSET_SETTING), (-((BIT_TIME_PS / 4) / (int)fine_lock_ps) + MIN_OFFSET_FACTOR + DLL_F2_DELAY_FS)); + + for (i = 0; i < CA_PIVOTS_LIST_SIZE; i++) { + if (ca_pivot_ps[i] > 0) + ca_pivot_fs[i] = __min((ca_pivot_ps[i] / (int)fine_lock_ps), + ((BIT_TIME_PS / 4) / (int)fine_lock_ps)); + else + ca_pivot_fs[i] = __max((ca_pivot_ps[i] / (int)fine_lock_ps), + (-((BIT_TIME_PS / 4) / (int)fine_lock_ps) + MIN_OFFSET_FACTOR + DLL_F2_DELAY_FS)); + } + + for (i = 0; i < DQ_PIVOTS_LIST_SIZE; i++) { + if (dq_pivot_ps[i] > 0) + dq_pivot_fs[i] = __min((dq_pivot_ps[i] / (int)fine_lock_ps), + ((BIT_TIME_PS / 4) / (int)fine_lock_ps)); + else + dq_pivot_fs[i] = __max((dq_pivot_ps[i] / (int)fine_lock_ps), + (-((BIT_TIME_PS / 4) / (int)fine_lock_ps) + MIN_OFFSET_FACTOR)); + } + + dq_pivot_step_size_fs = DQ_PIVOT_STEP_SIZE_PS / (int)fine_lock_ps; + min_dq_window_width_fs = MIN_DQ_WINDOW_WIDTH_PS / (int)fine_lock_ps; +} + +static void calibration_ca_rddq_cal_finalize() +{ + // workaround for AMC scheduler enable issue + amc_scheduler_en_workaround(false); +} + +static int calibration_find_min_element(int8_t *array, uint8_t array_len) +{ + uint8_t i; + int8_t min; + + min = array[0]; + for (i = 1; i < array_len; i++) { + if (array[i] < min) + min = array[i]; + } + + return (min); +} + +static int calibration_check_rddq(uint8_t ch, uint8_t byte) +{ + uint8_t byte_result; + uint8_t i; + + for (i = 0; i < RD_DQ_RETEST_COUNT; i++) { + amc_phy_run_dq_training(ch); + + if ((byte_result = amc_phy_get_dq_training_status(ch, byte, NUM_BYTES)) == 0) + break; + } + + // '1' pass, '0' fail + return (byte_result); +} + +static int calibration_binary_search_offset(uint8_t ch, uint8_t byte, int8_t sweep_lo, int8_t sweep_hi) +{ + int8_t mid; + + amc_phy_set_rd_offset(ch, byte, RD_WR_ADDR_OFFSET(sweep_hi)); + amc_phy_run_dll_update(ch); + if (calibration_check_rddq(ch, byte) != 0) + return sweep_hi; + + do { + mid = (sweep_lo + sweep_hi) / 2; + + amc_phy_set_rd_offset(ch, byte, RD_WR_ADDR_OFFSET(mid)); + amc_phy_run_dll_update(ch); + if (calibration_check_rddq(ch, byte) != 0) + sweep_lo = mid; + else + sweep_hi = mid; + + } while (__abs(sweep_hi - sweep_lo) > BINARY_SEARCH_THRESHOLD); + + return sweep_lo; +} + +static void calibration_rddq_cal(uint8_t ch, int8_t *rd_dq_offset, int8_t *rd_dq_window) +{ + int8_t min_pivot[NUM_BYTES]; + int8_t max_pivot[NUM_BYTES]; + int8_t pivot_count[NUM_BYTES]; + uint8_t i, pivot, byte; + int8_t pos_sweep_hi, pos_sweep_lo, neg_sweep_hi, neg_sweep_lo; + int8_t pos_offset, neg_offset; + + for (i = 0; i < NUM_BYTES; i++) { + min_pivot[i] = max_offset_fs; + max_pivot[i] = min_offset_fs; + pivot_count[i] = 0; + rd_dq_offset[i] = 0; + rd_dq_window[i] = 0; + } + + for (pivot = 0; pivot < DQ_PIVOTS_LIST_SIZE; pivot++) { + for (byte = 0; byte < NUM_BYTES; byte++) + amc_phy_set_rd_offset(ch, byte, RD_WR_ADDR_OFFSET(dq_pivot_fs[pivot])); + amc_phy_run_dll_update(ch); + + for (byte = 0; byte < NUM_BYTES; byte++) { + if (0 != calibration_check_rddq(ch, byte)) { + if (dq_pivot_fs[pivot] < min_pivot[byte]) + min_pivot[byte] = dq_pivot_fs[pivot]; + if (dq_pivot_fs[pivot] > max_pivot[byte]) + max_pivot[byte] = dq_pivot_fs[pivot]; + + pivot_count[byte]++; + } + } + } + + if (calibration_find_min_element(pivot_count, NUM_BYTES) < + (MIN_DQ_WINDOW_WIDTH_PS / DQ_PIVOT_STEP_SIZE_PS)) + return; + + for (byte = 0; byte < NUM_BYTES; byte++) { + pos_sweep_hi = __min(max_offset_fs, (max_pivot[byte] + dq_pivot_step_size_fs)); + neg_sweep_hi = __max(min_offset_fs, (min_pivot[byte] - dq_pivot_step_size_fs)); + + pos_sweep_lo = (pos_sweep_hi + neg_sweep_hi) / 2; + neg_sweep_lo = pos_sweep_lo; + + pos_offset = calibration_binary_search_offset(ch, byte, pos_sweep_lo, pos_sweep_hi); + neg_offset = calibration_binary_search_offset(ch, byte, neg_sweep_lo, neg_sweep_hi); + + rd_dq_offset[byte] = (pos_offset + neg_offset) / 2; + rd_dq_window[byte] = __abs(pos_offset - neg_offset); + } +} + +static int8_t calibration_ca_rddq_cal(uint8_t ch) +{ + bool prev_ca_status; // 0: fail, 1: pass + int8_t ca_pass_count, ca_offset; + int8_t ca_weighted_offset[CA_PIVOTS_LIST_SIZE][2]; + int8_t saved_rd_dq_offset[NUM_BYTES]; + int8_t saved_rd_dq_window[NUM_BYTES]; + int8_t rd_dq_offset[NUM_BYTES]; + int8_t rd_dq_window[NUM_BYTES]; + uint8_t i, byte; + int8_t min_rd_dq_window; + int32_t sum; + + prev_ca_status = false; + ca_pass_count = 0; + memset(saved_rd_dq_offset, 0, sizeof(saved_rd_dq_offset)); + memset(saved_rd_dq_window, 0, sizeof(saved_rd_dq_window)); + + for (i = 0; i < CA_PIVOTS_LIST_SIZE; i++) { + + //if the saturation point and the next CA pivot is closer than 2 fine-steps, + // jump to the next CA pivot + if (i > 0 && ( (ca_pivot_fs[i] - ca_pivot_fs[i-1]) < CA_PIVOT_THRESHOLD ) ) + continue; + + amc_phy_set_addr_offset(ch, RD_WR_ADDR_OFFSET(ca_pivot_fs[i])); + amc_phy_run_dll_update(ch); + + calibration_rddq_cal(ch, rd_dq_offset, rd_dq_window); + + min_rd_dq_window = calibration_find_min_element(rd_dq_window, NUM_BYTES); + + amc_phy_reset_fifos(); + + if (min_rd_dq_window < min_dq_window_width_fs) { + // XXX soft reset? + + if (prev_ca_status == true) + break; + + continue; + } + + prev_ca_status = true; + + ca_weighted_offset[ca_pass_count][0] = ca_pivot_fs[i]; + ca_weighted_offset[ca_pass_count][1] = min_rd_dq_window; + ca_pass_count++; + + for (byte = 0; byte < NUM_BYTES; byte++) { + if (rd_dq_window[byte] > saved_rd_dq_window[byte]) { + saved_rd_dq_window[byte] = rd_dq_window[byte]; + saved_rd_dq_offset[byte] = rd_dq_offset[byte]; + } + } + } + + // if ca window too small, spin + if (ca_pass_count < (MIN_CA_WINDOW_WIDTH_PS / CA_PIVOT_STEP_SIZE_PS)) + for(;;) ; + + sum = 0; + for (i = 0; i < ca_pass_count; i++) + sum += ca_weighted_offset[i][1]; + + ca_offset = 0; + for (i = 0; i < ca_pass_count; i++) + ca_offset += (ca_weighted_offset[i][0] * ca_weighted_offset[i][1] / sum); + + amc_phy_set_addr_offset(ch, RD_WR_ADDR_OFFSET(ca_offset)); + + // Shift the rd_dq offset, if needed + amc_phy_shift_dq_offset(saved_rd_dq_offset, NUM_BYTES); + + for(byte = 0; byte < NUM_BYTES; byte++) + amc_phy_set_rd_offset(ch, byte, RD_WR_ADDR_OFFSET(saved_rd_dq_offset[byte])); + + amc_phy_run_dll_update(ch); + + return (ca_offset); +} + +static void calibration_get_save_restore_region(uint8_t channel, uint32_t **region) +{ + uint32_t device_size; // in bytes + + device_size = (amc_get_memory_size() / AMC_NUM_CHANNELS) * 1024 * 1024; + *region = (uint32_t *)(SDRAM_BASE + ((channel + 1) * device_size)) - WRITE_REGION_SIZE; +} + +static uint8_t calibration_check_wrdq(uint8_t channel) +{ + uint8_t i, byte, word; + static const uint32_t patterns[] = { + 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff + }; + uint32_t *save_restore_region; + uint8_t result; + uint32_t temp; + uint32_t num_patterns; + + result = 0; + num_patterns = sizeof(patterns) / sizeof(patterns[0]); + calibration_get_save_restore_region(channel, &save_restore_region); + + for (i = 0; i < WR_DQ_RETEST_COUNT; i++) { + for (word = 0; word < WRITE_REGION_SIZE; word++) { + *(save_restore_region + word) = patterns[word % num_patterns]; + } + + for (word = 0; word < WRITE_REGION_SIZE; word++) + if ((temp = (*(save_restore_region + word) ^ patterns[word % num_patterns])) != 0) { + for (byte = 0; byte < NUM_BYTES; byte++) + if (temp & (0xf << byte)) + result |= (1 << byte); + break; + } + } + + return result; +} + +static void calibration_incr_search(uint8_t ch, int8_t sweep_lo, int8_t sweep_hi, int8_t step, int8_t *passing_offsets) +{ + uint8_t fail_flag, result, mask; + uint8_t byte; + int8_t sweep; + + fail_flag = 0; + + for (sweep = sweep_lo; __abs(sweep + step) <= __abs(sweep_hi); sweep += step) + { + for (byte = 0; byte < NUM_BYTES; byte++) + amc_phy_set_wr_offset(ch, byte, RD_WR_ADDR_OFFSET(sweep)); + amc_phy_run_dll_update(ch); + + result = calibration_check_wrdq(ch); + + for (byte = 0; byte < NUM_BYTES; byte++) { + mask = (1 << byte); + + if (fail_flag & mask) + continue; + + if ((result & mask) == 0) + passing_offsets[byte] = sweep; + else + fail_flag |= mask; + } + + // all failed + if (fail_flag & 0xf) + break; + } +} + +static void calibration_wrdq_cal(uint8_t ch, int8_t *wr_dq_offset, int8_t *wr_dq_window) +{ + uint8_t byte; + int8_t min_pivot, max_pivot; + uint32_t pivot_count; + int8_t pivot; + int8_t pos_sweep_hi, pos_sweep_lo, neg_sweep_hi, neg_sweep_lo; + int8_t pos_offset[NUM_BYTES], neg_offset[NUM_BYTES]; + + min_pivot = max_offset_fs; + max_pivot = min_offset_fs; + pivot_count = 0; + memset(pos_offset, 0, sizeof(pos_offset)); + memset(neg_offset, 0, sizeof(neg_offset)); + + for (pivot = 0; pivot < DQ_PIVOTS_LIST_SIZE; pivot++) { + for (byte = 0; byte < NUM_BYTES; byte++) + amc_phy_set_wr_offset(ch, byte, RD_WR_ADDR_OFFSET(dq_pivot_fs[pivot])); + amc_phy_run_dll_update(ch); + + if (calibration_check_wrdq(ch) == 0) { + if (dq_pivot_fs[pivot] < min_pivot) + min_pivot = dq_pivot_fs[pivot]; + if (dq_pivot_fs[pivot] > max_pivot) + max_pivot = dq_pivot_fs[pivot]; + pivot_count++; + } + } + + //if wr dq window too small, spin + if (pivot_count < (uint32_t)(MIN_DQ_WINDOW_WIDTH_PS / DQ_PIVOT_STEP_SIZE_PS)) + for(;;) ; + + pos_sweep_hi = __min(max_offset_fs, (max_pivot + dq_pivot_step_size_fs)); + neg_sweep_hi = __max(min_offset_fs, (min_pivot - dq_pivot_step_size_fs)); + + pos_sweep_lo = (pos_sweep_hi + neg_sweep_hi) / 2; + neg_sweep_lo = pos_sweep_lo; + + calibration_incr_search(ch, pos_sweep_lo, pos_sweep_hi, INCR_SEARCH_STEP_SIZE, pos_offset); + calibration_incr_search(ch, neg_sweep_lo, neg_sweep_hi, -INCR_SEARCH_STEP_SIZE, neg_offset); + + for (byte = 0; byte < NUM_BYTES; byte++) { + wr_dq_offset[byte] = (pos_offset[byte] + neg_offset[byte]) / 2; + wr_dq_window[byte] = __abs(pos_offset[byte] - neg_offset[byte]); + } +} diff --git a/drivers/apple/amc/include/drivers/amc/amc.h b/drivers/apple/amc/include/drivers/amc/amc.h new file mode 100644 index 0000000..8ec9b0b --- /dev/null +++ b/drivers/apple/amc/include/drivers/amc/amc.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __AMC_H +#define __AMC_H + +#include + +/* Apple Memory Controller */ + +#define AMC_MAX_FREQUENCY_SLOTS 4 +#define AMC_MAX_TUNABLES 50 + +#define FLAG_AMC_PARAM_BUSTAT23 0x0001 +#define FLAG_AMC_PARAM_LEGACY 0x0002 +#define FLAG_AMC_PARAM_SLOW_BOOT 0x0004 +#define FLAG_AMC_PARAM_ENABLE_AIU 0x0008 +#define FLAG_AMC_PARAM_RECONFIG 0x0010 +#define FLAG_AMC_PARAM_MRR_BYTE_SWIZZLE 0x0020 +#define FLAG_AMC_PARAM_MRR_BIT_SWIZZLE 0x0040 +#define FLAG_AMC_PARAM_ZQCL 0x0080 + +#define AMP_SWIZZLE_PER_J34M 2 // ...and This is the second Swizzle ever needed for H6 + // per + +#define __abs(x) (((x) < 0) ? -(x) : (x)) + +typedef enum { + MR_READ, + MR_WRITE +} amc_mrcmd_op_t; + +struct amc_per_freq { + uint32_t cas; + uint32_t pch; + uint32_t act; + uint32_t autoref; + uint32_t selfref; + uint32_t modereg; + uint32_t mifcassch; + uint32_t mifqmaxctrl; + uint32_t arefparam; + uint32_t trefbwbasecyc; +}; + +struct amc_param { + uint32_t flags; + uint32_t freqsel; + uint32_t tREFi; + uint32_t tREFi_1Gb; + uint32_t longsrcnt; + uint32_t longsrcnt_1Gb; + uint32_t srextrarefcnt; + uint32_t rdlat; + uint32_t wrlat; + uint32_t phyrdlat; + uint32_t phywrlat; + uint32_t pdn; + uint32_t read; + uint32_t bustat; + uint32_t bustat2; + uint32_t derate; + uint32_t mr1; + uint32_t mr2; + uint32_t mr3; + uint32_t mr63; + uint32_t mcphyupdate; + uint32_t autoref_params; + uint32_t pwrmngtparam_small; + uint32_t pwrmngtparam_guided; + uint32_t arefparam; + uint32_t chnldec; + uint32_t chnldec2; + uint32_t chnldec4; + uint32_t aref_freq0; + uint32_t aref_freq1; + uint32_t bootclkdivsr; + uint32_t schen_default; + uint32_t pwrmngten_default; + uint32_t mcphyupdate1; + uint32_t odts; + uint32_t readleveling; + uint32_t lat; + uint32_t phyrdwrtim; + uint32_t longsr; + uint32_t addrcfg; + uint32_t mccchnldec; + uint32_t mcuchnhash; + uint32_t mcuchnhash2; + uint32_t mcschnldec; + uint32_t qbrparam; + uint32_t addrmapmode; + uint32_t bankhash0; + uint32_t bankhash1; + uint32_t bankhash2; + int8_t offset_shift_hynix; + int8_t offset_shift_elpida; + int8_t offset_shift_elpida25nm; + struct amc_per_freq freq[AMC_MAX_FREQUENCY_SLOTS]; +}; + +struct amc_tunable { + volatile uint32_t *reg; + uint32_t value; +}; + +struct amc_memory_device_info { + uint32_t vendor_id; + uint32_t rev_id; + uint32_t rev_id2; + uint32_t type; + uint32_t width; // Device width in Bytes + uint32_t density; // Device density in MBytes +}; + + +// AMC protected functions (meant to be called from per platform/target amc implementation) +int32_t amc_init(bool resume); +uint64_t amc_get_memory_size(void); +const struct amc_memory_device_info *amc_get_memory_device_info(void); +void amc_mrcmd(amc_mrcmd_op_t op, uint8_t channels, uint8_t ranks, int32_t reg, uintptr_t val); +void amc_mrcmd_to_ch_rnk(amc_mrcmd_op_t op, uint8_t channel, uint8_t rank, int32_t reg, uintptr_t val); +void amc_enable_autorefresh(void); +void amc_finalize(bool resume); +void amc_dram_workarounds(bool resume); +void amc_dram_shift_dq_offset(int8_t *dq_offset, uint8_t num_bytes); +void amc_enable_slow_boot(bool enable); +void amc_configure_address_decoding_and_mapping(void); +void amc_configure_default_address_decoding_and_mapping(void); +addr_t amc_get_uncached_dram_virt_addr(uint32_t ch, uint32_t rnk, uint32_t bank, uint32_t row, uint32_t col); +uint32_t amc_get_consecutive_bytes_perchnrnk(void); +const struct amc_param *amc_get_params(void); + +// AMC function to be called from AMC PHY calibration code +void amc_calibration_start(bool start); +void amc_enable_rddqcal(bool enable); +void amc_wrdqcal_start(bool start); + +#endif /* ! __AMC_H */ diff --git a/drivers/apple/amc/include/drivers/amc/amc_phy.h b/drivers/apple/amc/include/drivers/amc/amc_phy.h new file mode 100644 index 0000000..a4d5e76 --- /dev/null +++ b/drivers/apple/amc/include/drivers/amc/amc_phy.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_AMC_PHY_H +#define __DRIVERS_AMC_PHY_H + +#include + +/* XXX TODO: cleanup 'int' to what's needed */ +struct amc_phy_calibration_data { + int bit_time_ps; + int min_ca_window_width_ps; + int min_dq_window_width_ps; + int ca_pivot_step_size_ps; + int dq_pivot_step_size_ps; + int max_offset_setting; + int min_offset_factor; + int dll_f2_delay_fs; + uint8_t ca_pivots_list_size; + int *ca_pivot_ps; + uint8_t dq_pivots_list_size; + int *dq_pivot_ps; + bool use_resume_boot_flow; +}; + +void amc_phy_preinit(void); +void amc_phy_init(bool resume); +void amc_phy_pre_normal_speed_enable(); +void amc_phy_scale_dll(int freqsel, int factor); +bool amc_phy_rddq_cal(); +void amc_phy_bypass_prep(int step); +void amc_phy_finalize(); +const struct amc_phy_calibration_data *amc_phy_get_calibration_data(); +void amc_phy_calibration_init(uint32_t *fine_lock_ps); +void amc_phy_run_dll_update(uint8_t ch); +void amc_phy_set_addr_offset(uint8_t ch, uint8_t value); +void amc_phy_set_rd_offset(uint8_t ch, uint8_t byte, uint8_t value); +void amc_phy_set_wr_offset(uint8_t ch, uint8_t byte, uint8_t value); +void amc_phy_configure_dll_pulse_mode(uint8_t ch, bool enable); +void amc_phy_run_dq_training(uint8_t ch); +uint32_t amc_phy_get_dq_training_status(uint8_t ch, uint8_t byte, uint8_t num_bytes); +void amc_phy_reset_fifos(); +void amc_phy_enable_dqs_pulldown(bool enable); + +void amc_phy_restore_calibration_values(bool resume); +void amc_phy_calibration_restore_ca_offset(uint8_t ch); +void amc_phy_calibration_ca_rddq_cal(bool resume); +void amc_phy_calibration_wrdq_cal(bool resume); +void amc_phy_shift_dq_offset(int8_t *dq_offset, uint8_t num_bytes); + +#endif /* __DRIVERS_AMC_PHY_H */ diff --git a/drivers/apple/amc/include/drivers/amc/amc_regs.h b/drivers/apple/amc/include/drivers/amc/amc_regs.h new file mode 100644 index 0000000..44f2d0a --- /dev/null +++ b/drivers/apple/amc/include/drivers/amc/amc_regs.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AMC_REGS_H +#define __AMC_REGS_H + +#include + +#if (AMC_REG_VERSION == 1 || AMC_REG_VERSION == 2) +#include "amc_regs_v12.h" +#elif AMC_REG_VERSION == 3 +#include "amc_regs_v3.h" +#elif (AMC_REG_VERSION == 4 || AMC_REG_VERSION == 5) +#include "amc_regs_v45.h" +#else +#error "amc_regs header missing" +#endif + +#endif /* __AMC_REGS_H */ diff --git a/drivers/apple/amc/include/drivers/amc/amc_regs_v12.h b/drivers/apple/amc/include/drivers/amc/amc_regs_v12.h new file mode 100644 index 0000000..efe0c09 --- /dev/null +++ b/drivers/apple/amc/include/drivers/amc/amc_regs_v12.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Apple Memory Controller */ + +#ifndef __PLATFORM_SOC_AMC_H +#define __PLATFORM_SOC_AMC_H + +#include +#include +#include +#include + +#define AMC_FREQUENCY_SLOTS (4) + +#define rAMC_AMCEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x000)) +#define rAMC_BOOTCLK (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x004)) +#define rAMC_CLKGATE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x008)) +#define rAMC_FREQSEL (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x00C)) + +#define rAMC_AIUPRT_CFG (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x080)) +#define rAMC_AIUPRT_RD_CWF (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x084)) +#define rAMC_AIUPRT_RD_GEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x088)) +#define rAMC_AIUPRT_ROTT_D1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x08C)) +#define rAMC_AIUPRT_ROTT_D2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x090)) +#define rAMC_AIUPRT_WR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x094)) +#define rAMC_AIUPRT_WOTT_D1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x098)) +#define rAMC_AIUPRT_WOTT_D2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x09C)) +#define rAMC_AIUPRT_TBADDR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x0A0)) +#define rAMC_AIU_CHNLDEC (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x0A4)) +#define rAMC_CHNLDEC rAMC_AIU_CHNLDEC +#define rAMC_AIU_CHNLDEC2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x0A8)) +#define rAMC_CHNLDEC2 rAMC_AIU_CHNLDEC2 +#define rAMC_AIU_CHNLDEC4 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x0AC)) +#define rAMC_CHNLDEC4 rAMC_AIU_CHNLDEC4 +#define rAMC_AIU_ADDRBANKHASH0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x0B0)) +#define rAMC_AIU_ADDRBANKHASH1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x0B4)) +#define rAMC_AIU_ADDRBANKHASH2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x0B8)) + +#define rAMC_AIU_CHNLCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x100)) +#define rAMC_AIU_CHNLTM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x104)) +#define rAMC_AIU_RDBRSTLEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x108)) +#define rAMC_AIU_RDMAXCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x10C)) +#define rAMC_AIU_RDMINCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x110)) +#define rAMC_AIU_RDREFL (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x114)) +#define rAMC_AIU_WRBRSTLEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x118)) +#define rAMC_AIU_WRMAXCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x11C)) +#define rAMC_AIU_WRMINCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x120)) +#define rAMC_AIU_WRREFL (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x124)) +#define rAMC_AIU_CPUSPCREQ (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x128)) +#define rAMC_AIU_GFXSPCREQ (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x12C)) +#define rAMC_AIU_NRTSPCREQ (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x130)) +#define rAMC_AIU_RTSPCREQ (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x134)) +#define rAMC_AIU_WPQSCH (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x138)) +#define rAMC_AIU_THOTLEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x13C)) +#define rAMC_AIU_THOTLCPUPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x140)) +#define rAMC_AIU_THOTLRTPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x144)) +#define rAMC_AIU_THOTLNRTPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x148)) +#define rAMC_AIU_THOTLGFXPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x14C)) +#define rAMC_AIU_PUSHEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x150)) + +#if AMC_REG_VERSION == 2 && SUB_PLATFORM_S7002 +#define rAMC_AIU_THOTLCPUPARAM2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x154)) +#define rAMC_AIU_THOTLRTPARAM2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x158)) +#define rAMC_AIU_THOTLNRTPARAM2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x15C)) +#define rAMC_AIU_THOTLGFXPARAM2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x160)) +#endif + +#define rAMC_AIU_LLTSCHCTL (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x164)) + +#define rAMC_SCHEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x200)) +#define rAMC_OPIDLETMR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x204)) +#define rAMC_OPTMRADJEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x208)) +#define rAMC_OPTMRADJPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x20C)) +#define rAMC_MIFNRTAGE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x210)) +#define rAMC_MIFRTAGE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x214)) +#define rAMC_MIFPCAGE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x218)) +#define rAMC_QBREN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x21C)) +#define rAMC_QBRPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x220)) +#define rAMC_MIFACTSCH (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x224)) +#define rAMC_MIFCASSCH_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x228)) +#define rAMC_PSQAFNTY (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x238)) +#define rAMC_PSQRQCTL0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x23C)) +#define rAMC_PSQRQCTL1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x240)) +#define rAMC_PSQRQTIMER0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x244)) +#define rAMC_PSQRQTIMER1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x248)) +#define rAMC_PSQRQTIMER2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x24C)) +#define rAMC_PSQRQBRST (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x250)) +#define rAMC_PSQRQSCHCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x254)) +#define rAMC_PSQWQCTL0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x258)) +#define rAMC_PSQWQCTL1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x25C)) +#define rAMC_PSQWQTHR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x260)) +#define rAMC_PSQWQBRST (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x264)) +#define rAMC_PSQWQSCHCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x268)) +#define rAMC_MCUQOS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x26C)) +#define rAMC_MCUQOSLLT (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x270)) + +#define rAMC_PHYRDWRTIM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x280)) + +#define rAMC_PHYMRRDATADQBITMUX (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x300)) +#define rAMC_PHYMRRDATADQBYTEMUX (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x304)) + +#define rAMC_LAT (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x380)) +#define rAMC_CAS_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x384)) +#define rAMC_PCH_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x394)) +#define rAMC_ACT_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3A4)) +#define rAMC_AUTO_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3B4)) +#define rAMC_SELF_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3C4)) +#define rAMC_PDN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3D4)) +#define rAMC_MODE_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3D8)) +#define rAMC_RD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3E8)) +#define rAMC_BUSTAT (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3EC)) +#define rAMC_BUSTAT_FREQ01 rAMC_BUSTAT +#define rAMC_DERATE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3F0)) +#define rAMC_TRANSGAP (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3F4)) +#define rAMC_AUTOREF_PARAMS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3F8)) +#define rAMC_BUSTAT_FREQ23 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3FC)) + +#define rAMC_ADDRMAP_MODE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x400)) +#define rAMC_ADDRCFG (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x404)) +#define rAMC_CH0RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x408)) +#define rAMC_CH0RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x40C)) +#define rAMC_CH1RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x410)) +#define rAMC_CH1RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x414)) +#define rAMC_AREFEN_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x418)) +#define rAMC_AREFPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x428)) +#define rAMC_LONGSR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x42C)) +#define rAMC_ZQC (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x430)) +#define rAMC_PWRMNGTEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x434)) +#define rAMC_PWRMNGTPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x438)) +#define rAMC_ODTS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x43C)) +#define rAMC_ODTS_MAPPING (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x440)) +#define rAMC_MCPHY_UPDTPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x444)) +#define rAMC_READ_LEVELING (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x448)) +#define rAMC_CH2RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x44C)) +#define rAMC_CH2RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x450)) +#define rAMC_CH3RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x454)) +#define rAMC_CH3RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x458)) +#define AMC_RNKCFG_OFFSET(_r) ((_r) * 1) + +#if AMC_REG_VERSION == 2 && SUB_PLATFORM_S7002 +// These defs are for AREFPARAM regs for freqs 1, 2, and 3 only (freq0 already defined above as rAMC_AREFPARAM) +#define rAMC_AREFPARAM_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x460)) +#define rAMC_MCPHY_UPDTPARAM1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x478)) +#endif + +#define rAMC_CH0MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x480)) +#define rAMC_CH0INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x484)) +#define rAMC_CH1MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x488)) +#define rAMC_CH1INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x48C)) +#define rAMC_CH01MRSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x490)) +#define rAMC_CH01INITSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x494)) +#define rAMC_CH2MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x498)) +#define rAMC_CH2INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x49C)) +#define rAMC_CH3MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4A0)) +#define rAMC_CH3INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4A4)) +#define rAMC_CH23MRSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4A8)) +#define rAMC_CH23INITSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4AC)) + +/* XXX perfcntr */ + +#define rAMC_INTEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x700)) +#define rAMC_INTSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x704)) +#define rAMC_BAELOG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x708)) +#define rAMC_BAELOG2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x70C)) + +#define rAMC_MIFQMAXCTRL_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x780)) + +#if AMC_REG_VERSION == 2 && SUB_PLATFORM_S7002 +#define rAMC_TREFBWBASECYC_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x800)) +#endif + +#include + +#endif /* ! __PLATFORM_SOC_AMC_H */ diff --git a/drivers/apple/amc/include/drivers/amc/amc_regs_v3.h b/drivers/apple/amc/include/drivers/amc/amc_regs_v3.h new file mode 100644 index 0000000..d335212 --- /dev/null +++ b/drivers/apple/amc/include/drivers/amc/amc_regs_v3.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Apple Memory Controller */ + +#ifndef __PLATFORM_SOC_AMC_H +#define __PLATFORM_SOC_AMC_H + +#include +#include +#include +#include + +#define AMC_FREQUENCY_SLOTS (4) + +#define rAMC_AMCEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x000)) +#define rAMC_BOOTCLK (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x004)) +#define rAMC_CLKGATE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x008)) +#define rAMC_FREQSEL (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x00C)) +#define rAMC_CLKPWRGATE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x010)) +#define rAMC_CLKPWRGATE2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x014)) + +#define rAMC_MCSADDRBNKHASH(_n) (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x080 + ((_n) * 4))) + +#define rAMC_MCSRDRTNCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x100)) +#define rAMC_MCSCHNLCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x104)) +#define rAMC_MCSCHNLTM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x108)) +#define rAMC_MCSARBCFG (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x10C)) + +#define rAMC_SCHEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x200)) +#define rAMC_OPIDLETMR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x204)) +#define rAMC_OPTMRADJEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x208)) +#define rAMC_OPTMRADJPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x20C)) +#define rAMC_MIFNRTAGE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x210)) +#define rAMC_MIFRTAGE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x214)) +#define rAMC_MIFPCAGE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x218)) +#define rAMC_QBREN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x21C)) +#define rAMC_QBRPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x220)) +#define rAMC_MIFACTSCH (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x224)) +#define rAMC_MIFCASSCH_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x228)) +#define rAMC_PSQAFNTY (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x238)) +#define rAMC_PSQRQCTL0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x23C)) +#define rAMC_PSQRQCTL1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x240)) +#define rAMC_PSQRQTIMER0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x244)) +#define rAMC_PSQRQTIMER1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x248)) +#define rAMC_PSQRQTIMER2 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x24C)) +#define rAMC_PSQRQBRST (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x250)) +#define rAMC_PSQRQSCHCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x254)) +#define rAMC_PSQWQCTL0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x258)) +#define rAMC_PSQWQCTL1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x25C)) +#define rAMC_PSQWQTHR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x260)) +#define rAMC_PSQWQBRST (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x264)) +#define rAMC_PSQWQSCHCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x268)) +#define rAMC_MCUQOS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x26C)) +#define rAMC_MCUQOSLLT (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x270)) +#define rAMC_PSQRQTIMER3 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x274)) + +#define rAMC_PHYRDWRTIM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x280)) + +#define rAMC_PHYMRRDATADQBITMUX (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x300)) +#define rAMC_PHYMRRDATADQBYTEMUX (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x304)) + +#define rAMC_LAT (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x380)) +#define rAMC_CAS_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x384)) +#define rAMC_PCH_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x394)) +#define rAMC_ACT_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3A4)) +#define rAMC_AUTO_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3B4)) +#define rAMC_SELF_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3C4)) +#define rAMC_PDN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3D4)) +#define rAMC_MODE_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x3D8)) +#define rAMC_RD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3E8)) +#define rAMC_BUSTAT (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3EC)) +#define rAMC_BUSTAT_FREQ01 rAMC_BUSTAT +#define rAMC_DERATE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3F0)) +#define rAMC_TRANSGAP (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3F4)) +#define rAMC_AUTOREF_PARAMS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3F8)) +#define rAMC_BUSTAT_FREQ23 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x3FC)) + +#define rAMC_ADDRMAP_MODE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x400)) +#define rAMC_ADDRCFG (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x404)) +#define rAMC_CH0RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x408)) +#define rAMC_CH0RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x40C)) +#define rAMC_CH1RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x410)) +#define rAMC_CH1RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x414)) +#define rAMC_AREFEN_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x418)) +#define rAMC_AREFPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x428)) +#define rAMC_LONGSR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x42C)) +#define rAMC_ZQC (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x430)) +#define rAMC_PWRMNGTEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x434)) +#define rAMC_PWRMNGTPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x438)) +#define rAMC_ODTS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x43C)) +#define rAMC_ODTS_MAPPING (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x440)) +#define rAMC_MCPHY_UPDTPARAM (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x444)) +#define rAMC_READ_LEVELING (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x448)) +#define rAMC_CH2RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x44C)) +#define rAMC_CH2RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x450)) +#define rAMC_CH3RNKCFG0 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x454)) +#define rAMC_CH3RNKCFG1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x458)) +#define AMC_RNKCFG_OFFSET(_r) ((_r) * 1) + +// These defs are for AREFPARAM regs for freqs 1, 2, and 3 only (freq0 already defined above as rAMC_AREFPARAM) +#define rAMC_AREFPARAM_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x460)) + +#define rAMC_MCPHY_UPDTPARAM1 (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x478)) + +#define rAMC_CH0MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x480)) +#define rAMC_CH0INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x484)) +#define rAMC_CH1MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x488)) +#define rAMC_CH1INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x48C)) +#define rAMC_CH01MRSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x490)) +#define rAMC_CH01INITSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x494)) +#define rAMC_CH2MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x498)) +#define rAMC_CH2INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x49C)) +#define rAMC_CH3MRCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4A0)) +#define rAMC_CH3INITCMD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4A4)) +#define rAMC_CH23MRSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4A8)) +#define rAMC_CH23INITSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x4AC)) + +#define rAMC_INTEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x700)) +#define rAMC_INTSTATUS (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x704)) + + +#define rAMC_MIFQMAXCTRL_FREQ(_f) (*(volatile uint32_t *)(AMC_BASE_ADDR + ((_f) * 4) + 0x780)) + +#define rMCC_MCCEN (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x800)) +#define rMCC_CHNLDEC (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x80C)) +#define rAMC_CHNLDEC rMCC_CHNLDEC +#define rMCC_MCUCHNHASH (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x810)) +#define rMCC_DRAMACCCTRL (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x81C)) +#define rMCC_ALCHINT (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x850)) +#define rMCC_AFWRMERGE (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x854)) + +#define rMCC_MCSCMDCRD (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x880)) +#define rMCC_MCCAFDTHR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x884)) +#define rMCC_MCDHWMTHR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x888)) +#define rMCC_MCFTHR (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x88C)) + +#define rMCC_DATASETID(_n) (*(volatile uint32_t *)(AMC_BASE_ADDR + 0x1000 + ((_n) * 0x1000))) + +#include + +#endif /* __PLATFORM_SOC_AMC_H */ diff --git a/drivers/apple/amc/include/drivers/amc/amc_regs_v45.h b/drivers/apple/amc/include/drivers/amc/amc_regs_v45.h new file mode 100644 index 0000000..a58f900 --- /dev/null +++ b/drivers/apple/amc/include/drivers/amc/amc_regs_v45.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Apple Memory Controller version 3 */ + +#ifndef __PLATFORM_SOC_AMC_H +#define __PLATFORM_SOC_AMC_H + +#include +#include +#include +#include + +#define AMC_FREQUENCY_SLOTS (4) + +// AMCX registers + +#define rAMC_AMCEN (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x000)) +#define rAMC_CLKGATE (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x004)) +#define rAMC_FREQSEL (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x008)) +#define rAMC_CLKPWRGATE (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x010)) +#define rAMC_CLKPWRGATE2 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x014)) + +#define rAMC_MCSADDRBNKHASH(_n) (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x080 + ((_n) * 4))) +#define rAMC_MCSCHNLDEC (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x08C)) +#define rAMC_ADDRMAP_MODE (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x090)) +#define rAMC_ADDRCFG (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x094)) + +#define rAMC_MCSRDRTNCRD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x100)) +#define rAMC_MCSCHNLCRD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x104)) +#define rAMC_MCSCHNLTM (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x108)) +#define rAMC_MCSARBCFG (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x10C)) + +#define rAMC_SCHEN (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x180)) +#define rAMC_OPIDLETMR (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x184)) +#define rAMC_OPTMRADJEN (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x188)) +#define rAMC_OPTMRADJPARAM (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x18C)) +#define rAMC_MIFNRTAGE (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x190)) +#define rAMC_MIFRTAGE (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x194)) +#define rAMC_MIFPCAGE (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x198)) +#define rAMC_QBREN (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x19C)) +#define rAMC_QBRPARAM (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1A0)) +#define rAMC_MIFACTSCH (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1A4)) +#define rAMC_MIFCASSCH_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x1A8)) +#define rAMC_PSQAFNTY (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1B8)) +#define rAMC_PSQRQCTL0 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1BC)) +#define rAMC_PSQRQCTL1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1C0)) +#define rAMC_PSQRQTIMER0 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1C4)) +#define rAMC_PSQRQTIMER1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1C8)) +#define rAMC_PSQRQTIMER2 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1CC)) +#define rAMC_PSQRQBRST (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1D0)) +#define rAMC_PSQRQSCHCRD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1D4)) +#define rAMC_PSQWQCTL0 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1D8)) +#define rAMC_PSQWQCTL1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1DC)) +#define rAMC_PSQWQTHR (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1E0)) +#define rAMC_PSQWQBRST (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1E4)) +#define rAMC_PSQWQSCHCRD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1E8)) +#define rAMC_MCUQOS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1EC)) +#define rAMC_MCUQOSLLT (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1F0)) +#define rAMC_PSQRQTIMER3 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x1F4)) + +#define rAMC_PHYRDWRTIM (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x200)) +#define rAMC_PHYUPDATETIMERS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x280)) + +#define rAMC_LAT (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x300)) +#define rAMC_CAS_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x304)) +#define rAMC_PCH_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x314)) +#define rAMC_ACT_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x324)) +#define rAMC_AUTO_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x334)) +#define rAMC_SELF_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x344)) +#define rAMC_PDN (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x354)) +#define rAMC_MODE_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x358)) +#define rAMC_RD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x368)) +#define rAMC_BUSTAT (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x36C)) +#define rAMC_BUSTAT_FREQ01 rAMC_BUSTAT +#define rAMC_DERATE (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x370)) +#define rAMC_TRANSGAP (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x374)) +#define rAMC_AUTOREF_PARAMS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x378)) +#define rAMC_BUSTAT_FREQ23 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x37C)) + +#define rAMC_CH0RNKCFG0 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x380)) +#define rAMC_CH0RNKCFG1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x384)) +#define rAMC_CH1RNKCFG0 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x388)) +#define rAMC_CH1RNKCFG1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x38C)) +#define rAMC_AREFEN_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x390)) +#define rAMC_AREFPARAM (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3A0)) +#define rAMC_LONGSR (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3A4)) +#define rAMC_ZQC (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3A8)) +#define rAMC_PWRMNGTEN (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3AC)) +#define rAMC_PWRMNGTPARAM (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3B0)) +#define rAMC_ODTS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3B4)) +#define rAMC_ODTS_MAPPING (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3B8)) +#define rAMC_MCPHY_UPDTPARAM (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3BC)) +#define rAMC_READ_LEVELING (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3C0)) +#define rAMC_CH2RNKCFG0 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3C4)) +#define rAMC_CH2RNKCFG1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3C8)) +#define rAMC_CH3RNKCFG0 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3CC)) +#define rAMC_CH3RNKCFG1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3D0)) +#define AMC_RNKCFG_OFFSET(_r) ((_r) * 1) + +// These defs are for AREFPARAM regs for freqs 1, 2, and 3 only (freq0 already defined above as rAMC_AREFPARAM) +#define rAMC_AREFPARAM_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x3D8)) + +#define rAMC_MCPHY_UPDTPARAM1 (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x3F0)) + +#define rAMC_CH0MRCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x400)) +#define rAMC_CH0INITCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x404)) +#define rAMC_CH1MRCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x408)) +#define rAMC_CH1INITCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x40C)) + +#if AMC_REG_VERSION == 4 + +#define rAMC_CH01MRSTATUS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x410)) +#define rAMC_CH01INITSTATUS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x414)) +#define rAMC_CH2MRCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x418)) +#define rAMC_CH2INITCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x41C)) +#define rAMC_CH3MRCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x420)) +#define rAMC_CH3INITCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x424)) + +#else + +#define rAMC_CH2MRCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x410)) +#define rAMC_CH2INITCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x414)) +#define rAMC_CH3MRCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x418)) +#define rAMC_CH3INITCMD (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x41C)) +#define rAMC_CH01MRSTATUS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x420)) +#define rAMC_CH01INITSTATUS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x424)) + +#endif + +#define rAMC_CH23MRSTATUS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x428)) +#define rAMC_CH23INITSTATUS (*(volatile uint32_t *)(AMCX_BASE_ADDR + 0x42C)) + +#define rAMC_MIFQMAXCTRL_FREQ(_f) (*(volatile uint32_t *)(AMCX_BASE_ADDR + ((_f) * 4) + 0x700)) + +// AMCC registers + +#define rMCC_CHNLDEC (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x4A4)) +#define rMCC_MCUCHNHASH (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x4A8)) +#define rMCC_MCUCHNHASH2 (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x4AC)) +#define rMCC_DRAMACCCTRL (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x4B4)) + +#define rAMC_INTEN (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x700)) +#define rAMC_INTSTATUS (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x704)) +#define rAMC_MCCTAGPARLOG1 (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x710)) +#define rAMC_MCCTAGPARLOG2 (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x714)) +#define rAMC_MCCDATERRLOG (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x718)) +#define rAMC_MCCAFERRLOG0 (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x71c)) +#define rAMC_MCCAFERRLOG1 (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x720)) +#define rAMC_MCCAFERRLOG2 (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x724)) +#define rAMC_MCCDPERRCNTCTRL (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x728)) + +#define rMCC_MCCGEN (*(volatile uint32_t *)(AMCC_BASE_ADDR + 0x780)) + +#include + +#endif /* __PLATFORM_SOC_AMC_H */ diff --git a/drivers/apple/amc/rules.mk b/drivers/apple/amc/rules.mk new file mode 100644 index 0000000..7a72197 --- /dev/null +++ b/drivers/apple/amc/rules.mk @@ -0,0 +1,28 @@ +# Copyright (C) 2009-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifeq ($(AMC_REG_VERSION),) + OPTIONS += AMC_REG_VERSION=1 +else + OPTIONS += AMC_REG_VERSION=$(AMC_REG_VERSION) +endif + +ifeq ($(AMC_FILE_VERSION),) + ALL_OBJS += $(LOCAL_DIR)/amc.o +else + ALL_OBJS += $(LOCAL_DIR)/amc_v2.o +endif + +ifeq ($(NO_AMP_CALIBRATION),true) + ALL_OBJS += $(LOCAL_DIR)/calibration_v1.o +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/amg/amg.c b/drivers/apple/amg/amg.c new file mode 100644 index 0000000..ea6faab --- /dev/null +++ b/drivers/apple/amg/amg.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "amg.h" + +#define CA_PIVOTS_LIST_SIZE (7) +#define DQ_PIVOTS_LIST_SIZE (5) + +static const int ca_pivot_ps[CA_PIVOTS_LIST_SIZE] = {-375, -250, -125, 0, 125, 250, 375}; +static const int dq_pivot_ps[DQ_PIVOTS_LIST_SIZE] = {-500, -250, 0, 250, 500}; +static struct amc_phy_calibration_data amg_calibration_data = { + .bit_time_ps = 2500, + .min_ca_window_width_ps = 250, + .min_dq_window_width_ps = 250, + .ca_pivot_step_size_ps = 125, + .dq_pivot_step_size_ps = 250, + .max_offset_setting = 63, + .min_offset_factor = 12, + .ca_pivots_list_size = CA_PIVOTS_LIST_SIZE, + .ca_pivot_ps = (int *)ca_pivot_ps, + .dq_pivots_list_size = DQ_PIVOTS_LIST_SIZE, + .dq_pivot_ps = (int *)dq_pivot_ps, +}; + +void amc_phy_init(bool resume) +{ + int i; + + // overwrite bit_time_ps if presented + if (amc_phy_params.bit_time_ps) + amg_calibration_data.bit_time_ps = amc_phy_params.bit_time_ps; + + for (i = 0; i < AMC_NUM_CHANNELS; i++) { + int ch = AMG_INDEX_FOR_CHANNEL(i); // cope with hole in AMG address space + + rAMG_CORE_CONFIG(ch) = amc_phy_params.core_config; + +#if !SUPPORT_FPGA + // PHY ZQ calibration + rAMG_ZQ_CONF(ch) = 0x00ff0096; // + rAMG_ZQ_CONTROL(ch) = 0x00000009; // + rAMG_ZQ_CONTROL(ch) = 0x0000000b; + // Not testing the error bit. This will never happen in normal operation, + // and in fact _can't_ be set in H4P B0. + while ((rAMG_ZQ_STATUS(ch) & 0x80) == 0) ; + + // Train master DLL + rAMG_DLL_CONTROL(ch) = 0x00110001; + rAMG_DLL_CONTROL(ch) = 0x00110005; + while ((rAMG_DLL_STATUS(ch) & 1) != 1) ; + // check for timeout + if ((rAMG_DLL_STATUS(ch) & 0x4) != 0) + for (;;) ; + + if (amc_phy_params.flags & FLAG_AMG_PARAM_CAL_STATIC) { + // CA static offset programming; note it's too early to use + // MRRs, so this relies on the SOC fusing. + uint16_t fine_lock = (rAMG_DLL_STATUS(ch) >> 5) & 0x3ff; + uint32_t fine_unit = (amg_calibration_data.bit_time_ps) / fine_lock; + uint32_t addr_offset; + uint32_t vendor_id = chipid_get_memory_manufacturer(); + switch (vendor_id) { + case JEDEC_MANUF_ID_SAMSUNG: + addr_offset = (110/fine_unit) | (1 << 6); /* -110ps */ + break; + case JEDEC_MANUF_ID_ELPIDA: + addr_offset = (50/fine_unit) | (1 << 6); /* -50ps */ + break; + case JEDEC_MANUF_ID_HYNIX: + addr_offset = 0; /* 0ps */ + break; + default: + addr_offset = 0; + break; + } + rAMG_ADDR_OFFSET(ch) = addr_offset; + } else if (resume) { + amc_phy_calibration_restore_ca_offset(i); + } + + rAMG_DLL_TIMER(ch) = 0x0003061a; + + // set frequency scaling parameters + if (likely(!amc_phy_params.freq_scale)) + rAMG_FREQ_SCALE(ch) = 0x00e40688; + else + rAMG_FREQ_SCALE(ch) = amc_phy_params.freq_scale; + +#endif // !SUPPORT_FPGA + + rAMG_READ_LATENCY(ch) = amc_phy_params.read_latency; // [linked to AMC phyrdwrtim] + rAMG_GATE_OFFSET(ch) = amc_phy_params.gate_offset; + + rAMG_INIT_CONTROL(ch) = 0x00000001; + } +} + +void amc_phy_scale_dll(int freqsel, int factor) +{ + int i; + + // Make sure AMG was inited. + // Assumptions: all supported channels are inited together, + // and channel 0 is always used. + if ((rAMG_INIT_CONTROL(0) & 1) == 0) + return; + + // Scale the current lock value + for (i = 0; i < AMC_NUM_CHANNELS; i++) { + int ch = AMG_INDEX_FOR_CHANNEL(i); + uint16_t new_lock; + uint16_t fine_lock; + + // The fine_lock is 10 bits and coarse is 8. Since the override + // is in coarse units, we do shifty math on the fine units. + fine_lock = (rAMG_DLL_STATUS(ch) >> 5) & 0x3ff; + if (factor == 1) + new_lock = fine_lock >> 2; + else if (factor == 8) + new_lock = fine_lock << 1; + else + panic("amc_phy_scale_dll: unsupported DLL scale factor"); + if (new_lock > 0xff) + new_lock = 0xff; + rAMG_DLL_OVERRIDE(ch) = new_lock; + rAMG_DLL_CONTROL(ch) = 0x00110004; + while (!(rAMG_DLL_STATUS(ch) & 1)) ; + } +} + +bool amc_phy_rddq_cal() +{ + uint32_t *dq_cal_data; + bool result; + uint8_t index, i; + uint32_t device_width; + uint8_t slot, ch; + uint16_t fine_lock; + uint32_t fine_unit; + uint32_t offset; + + result = false; + + if (amc_phy_params.flags & FLAG_AMG_PARAM_CAL_STATIC) { + dq_cal_data = malloc(AMC_NUM_CHANNELS * 2 * sizeof(uint32_t)); + + if (chipid_get_memory_dqcal(dq_cal_data)) { + index = 0; + device_width = (amc_get_memory_device_info())->width; + + for (i = 0; i < AMC_NUM_CHANNELS; i++) { + ch = AMG_INDEX_FOR_CHANNEL(i); // cope with hole in AMG address space + fine_lock = (rAMG_DLL_STATUS(ch) >> 5) & 0x3ff; + fine_unit = (amg_calibration_data.bit_time_ps) / fine_lock; + + // Loop across all bytes twice, first for read then for write, + // which matches the order in which the data is given to us. + for (slot = 0; slot < device_width * 2; slot++) { + offset = (((dq_cal_data[index] & 0x8) << 3) | + ((((dq_cal_data[index] & 0x7) * 40) / fine_unit) & 0x3f)); + dq_cal_data[index] >>= 4; + if (slot < device_width) + rAMG_RD_OFFSET(ch, slot) = offset; + else + rAMG_WR_OFFSET(ch, (slot - device_width)) = offset; + // Bump at end of "device_width" bytes of read and write + if ((slot % device_width) == (device_width - 1)) + index++; + } + } + + result = true; + } + + free(dq_cal_data); + } + + return result; +} + +void amc_phy_bypass_prep(int step) +{ + // Make sure AMG was inited. + // Assumptions: all supported channels are inited together, + // and channel 0 is always used. + if ((rAMG_INIT_CONTROL(0) & 1) == 0) + return; + + // We need to be sure the DLL is in forced mode. Reload the + // original full-speed lock result. + // Note the 0 is the unused freqsel argument. + amc_phy_scale_dll(0, 1); +} + +void amc_phy_finalize() +{ + int i; + + // Enable pulse-mode DLL training + for (i = 0; i < AMC_NUM_CHANNELS; i++) { + int ch = AMG_INDEX_FOR_CHANNEL(i); // cope with hole in AMG address space + rAMG_DLL_FILTER(ch) = 0x0000002e; + rAMG_DLL_CONTROL(ch) = 0x00110006; + } +} + +void amc_phy_enable_dqs_pulldown(bool enable) +{ +} + +void amc_phy_reset_fifos() +{ +} + +const struct amc_phy_calibration_data * amc_phy_get_calibration_data() +{ + return &amg_calibration_data; +} + +void amc_phy_calibration_init(uint32_t *fine_lock_ps) +{ + uint8_t ch; + uint16_t lock_result; + const struct amc_memory_device_info *dev_info; + + ASSERT(fine_lock_ps != NULL); + + *fine_lock_ps = 0; + dev_info = amc_get_memory_device_info(); + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + rAMG_DLL_FILTER(AMG_INDEX_FOR_CHANNEL(ch)) = 0; + + lock_result = ((rAMG_DLL_STATUS(AMG_INDEX_FOR_CHANNEL(ch)) >> 5) & 0x3ff); // fine value + rAMG_DLL_OVERRIDE(AMG_INDEX_FOR_CHANNEL(ch)) = lock_result / 4; // coarse value + amc_phy_run_dll_update(ch); + + *fine_lock_ps += (amg_calibration_data.bit_time_ps) / (lock_result); + + // Modified guidance for AMG bit_sample field setting + if (((dev_info->vendor_id == JEDEC_MANUF_ID_SAMSUNG) && (dev_info->density == JEDEC_DENSITY_2Gb) && (dev_info->rev_id == 0)) || + ((dev_info->vendor_id == JEDEC_MANUF_ID_SAMSUNG) && (dev_info->density == JEDEC_DENSITY_4Gb) && (dev_info->rev_id == 1)) || + ((dev_info->vendor_id == JEDEC_MANUF_ID_HYNIX) && (dev_info->density == JEDEC_DENSITY_1Gb))) + rAMG_DQCAL_CONTROL(AMG_INDEX_FOR_CHANNEL(ch)) = 0x00001ffb; + else + rAMG_DQCAL_CONTROL(AMG_INDEX_FOR_CHANNEL(ch)) = 0x00003ffb; + } + + *fine_lock_ps = *fine_lock_ps / AMC_NUM_CHANNELS; +} + +void amc_phy_run_dll_update(uint8_t ch) +{ + uint8_t ch_amg_idx = AMG_INDEX_FOR_CHANNEL(ch); + + rAMG_DLL_CONTROL(ch_amg_idx) = 0x00110000 | (1 << 2) | (0 << 0); + while ((rAMG_DLL_STATUS(ch_amg_idx) & 1) == 0) ; +} + +void amc_phy_set_addr_offset(uint8_t ch, uint8_t value) +{ + rAMG_ADDR_OFFSET(AMG_INDEX_FOR_CHANNEL(ch)) = value; +} + +void amc_phy_set_rd_offset(uint8_t ch, uint8_t byte, uint8_t value) +{ + rAMG_RD_OFFSET(AMG_INDEX_FOR_CHANNEL(ch), byte) = value; +} + +void amc_phy_set_wr_offset(uint8_t ch, uint8_t byte, uint8_t value) +{ + rAMG_WR_OFFSET(AMG_INDEX_FOR_CHANNEL(ch), byte) = value; +} + +void amc_phy_configure_dll_pulse_mode(uint8_t ch, bool enable) +{ + if (!enable) { + rAMG_DLL_FILTER(AMG_INDEX_FOR_CHANNEL(ch)) = 0x0000000a; + } + else { + rAMG_DLL_FILTER(AMG_INDEX_FOR_CHANNEL(ch)) = 0x0000002e; + rAMG_DLL_CONTROL(AMG_INDEX_FOR_CHANNEL(ch)) = 0x00110006; + } +} + +void amc_phy_run_dq_training(uint8_t ch) +{ + uint8_t ch_amg_idx = AMG_INDEX_FOR_CHANNEL(ch); + + rAMG_DQCAL_CONTROL(ch_amg_idx) |= (1 << 14); // start + while ((rAMG_DQCAL_STATUS(ch_amg_idx) & 1) == 0) ; // wait for 'Done' bit to set +} + +uint32_t amc_phy_get_dq_training_status(uint8_t ch, uint8_t byte, uint8_t num_bytes) +{ + uint8_t byte_result; + uint32_t status; + + status = rAMG_DQCAL_STATUS(AMG_INDEX_FOR_CHANNEL(ch)); + + // bits[MAX_BYTE-1:0] of the byte_result field are for pos DQS strobe, + // and bits [2*MAX_BYTE-1:MAX_BYTE] for neg DQS strobe. Final result is + // 'AND' of two, for specified byte + byte_result = (status & (1 << (byte + 1))); + byte_result = byte_result && (status & (1 << (byte + num_bytes + 1))); + + return byte_result; +} + +void amc_phy_shift_dq_offset(int8_t *dq_offset, uint8_t num_bytes) { + amc_dram_shift_dq_offset(dq_offset, num_bytes); +} diff --git a/drivers/apple/amg/amg.h b/drivers/apple/amg/amg.h new file mode 100644 index 0000000..67fc2db --- /dev/null +++ b/drivers/apple/amg/amg.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_AMG_H +#define __PLATFORM_SOC_AMG_H + +#include + +/* Apple Memory Gasket */ + +#define AMG_INDEX_FOR_CHANNEL(_c) (((_c) < 2) ? (_c) : ((_c) + 2)) + +#define rAMG_DLL_CONFIG(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x00)) +#define rAMG_DLL_OVERRIDE(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x04)) +#define rAMG_DLL_CONTROL(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x08)) +#define rAMG_DLL_STATUS(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x0C)) +#define rAMG_DLL_TIMER(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x1C)) + +#define rAMG_GATE_OFFSET(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x10)) +#define rAMG_FINE_OFFSET(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x14)) +#define rAMG_ADDR_OFFSET(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x18)) + +#define rAMG_RD_OFFSET(_c,_n) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x20 + ((_n)*4))) +#define rAMG_WR_OFFSET(_c,_n) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x30 + ((_n)*4))) + +#define rAMG_CORE_CONFIG(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x40)) +#define rAMG_INIT_CONTROL(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x44)) +#define rAMG_DLL_FILTER(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x48)) +#define rAMG_FREQ_SCALE(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x4C)) + +#define rAMG_ZQ_OVERRIDE(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x50)) +#define rAMG_ZQ_STATUS(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x54)) +#define rAMG_ZQ_CONTROL(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x58)) + +#define rAMG_READ_LATENCY(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x5C)) + +#define rAMG_DQCAL_CONTROL(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x60)) +#define rAMG_DQCAL_STATUS(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x64)) + +#define rAMG_ZQ_CONF(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x70)) +#define rAMG_CKSTOP_CONF(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x74)) +#define rAMG_DLLTIMER_CONF(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x78)) +#define rAMG_DLL_CONF(_c) (*(volatile u_int32_t *)(AMG_BASE_ADDR + ((_c)*AMG_SPACING) + 0x7C)) + +struct amg_params { + uint32_t flags; + uint32_t core_config; + uint32_t read_latency; + uint32_t gate_offset; + uint32_t freq_scale; + uint32_t bit_time_ps; +}; + +#define FLAG_AMG_PARAM_CAL_STATIC 0x0001 + +#include + +#endif /* ! __PLATFORM_SOC_AMG_H */ diff --git a/drivers/apple/amg/rules.mk b/drivers/apple/amg/rules.mk new file mode 100644 index 0000000..80bb7af --- /dev/null +++ b/drivers/apple/amg/rules.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_HW_AMG=1 + +ALL_OBJS += $(LOCAL_DIR)/amg.o diff --git a/drivers/apple/amp/amp_v1.c b/drivers/apple/amp/amp_v1.c new file mode 100644 index 0000000..7520ead --- /dev/null +++ b/drivers/apple/amp/amp_v1.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CA_PIVOTS_LIST_SIZE (9) +#define DQ_PIVOTS_LIST_SIZE (5) + +static const int ca_pivot_ps[CA_PIVOTS_LIST_SIZE] = {-400, -300, -200, -100, 0, 100, 200, 300, 400}; +static const int dq_pivot_ps[DQ_PIVOTS_LIST_SIZE] = {-300, -150, 0, 150, 300}; +static const struct amc_phy_calibration_data amp_calibration_data = { + .bit_time_ps = 1875, + .min_ca_window_width_ps = 150, + .min_dq_window_width_ps = 150, + .ca_pivot_step_size_ps = 100, + .dq_pivot_step_size_ps = 150, + .max_offset_setting = 63, + .min_offset_factor = 0, + .dll_f2_delay_fs = 10, + .ca_pivots_list_size = CA_PIVOTS_LIST_SIZE, + .ca_pivot_ps = (int *)ca_pivot_ps, + .dq_pivots_list_size = DQ_PIVOTS_LIST_SIZE, + .dq_pivot_ps = (int *)dq_pivot_ps, + .use_resume_boot_flow = true, // to use static CA but dynamic DQ calibration +}; +static uint32_t amp_dllupdtctrl[AMC_NUM_CHANNELS]; + +void amc_phy_init(bool resume) +{ + int i, d, f; + + for (i = 0; i < AMC_NUM_CHANNELS; i++) { + int ch = AMP_INDEX_FOR_CHANNEL(i); // cope with hole in AMP address space + + rAMP_AMPEN(ch) = 1; + +#if !SUPPORT_FPGA + rAMP_DQDQSDS(ch) = 0x0a0a0a0a; + rAMP_NONDQDS(ch) = 0x0a0a0a0a; +#endif + + if (amc_phy_params.flags & FLAG_AMP_PARAM_FULLDIFFMODE) { + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) + rAMP_DIFFMODE_FREQ(ch, f) = 0x00000121; + } + + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + for (d = 0; d < AMP_NUM_DLL; d++) { + rAMP_DQSINDLLSCL_FREQ(ch,d,f) = amc_phy_params.freq[f].scl; + rAMP_DQOUTDLLSCL_FREQ(ch,d,f) = amc_phy_params.freq[f].scl; + } + rAMP_CAOUTDLLSCL_FREQ(ch,f) = amc_phy_params.freq[f].scl; + rAMP_CTLOUTDLLSCL_FREQ(ch,f) = amc_phy_params.freq[f].scl; + } + +#if !SUPPORT_FPGA + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + rAMP_RDCAPCFG_FREQ(ch,f) = amc_phy_params.freq[f].rdcapcfg; + } + + rAMP_DLLEN(ch) = 0x100; + // Reset the master DLL to make sure that master DLL locking happens from scratch + rAMP_DLLEN(ch) |= 0x1; + rAMP_DLLEN(ch) &= ~0x1; + amc_phy_run_dll_update(ch); +#endif + + rAMP_AMPINIT(ch) = 0x1; + +#if !SUPPORT_FPGA + rAMP_IMPCALCMD(ch) = 0x101; + while (rAMP_IMPCALCMD(ch) & 0x1) ; +#endif + } +} + +void amc_phy_enable_dqs_pulldown(bool enable) +{ +} + +void amc_phy_scale_dll(int freqsel, int factor) +{ + int i; + + for (i=0; ivendor_id == JEDEC_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 0)) || + ((dev_info->vendor_id == JEDEC_MANUF_ID_HYNIX) && (dev_info->density == JEDEC_DENSITY_1Gb)) ) + rAMP_CALDQMSK(ch) = 0xfefefefe; + else + rAMP_CALDQMSK(ch) = 0x00000000; + } + + *fine_lock_ps = *fine_lock_ps / AMC_NUM_CHANNELS; +} + +void amc_phy_run_dll_update(uint8_t ch) +{ + ch = AMP_INDEX_FOR_CHANNEL(ch); // cope with hole in AMP address space + rAMP_DLLUPDTCMD(ch) = 0x1; + while ((rAMP_DLLUPDTCMD(ch) & 0x1) != 0) ; +} + +void amc_phy_set_addr_offset(uint8_t ch, uint8_t value) +{ + rAMP_CAOUTDLLOVRRD(AMP_INDEX_FOR_CHANNEL(ch)) = value; +} + +void amc_phy_set_rd_offset(uint8_t ch, uint8_t byte, uint8_t value) +{ + rAMP_DQSINDLLOVRRD(AMP_INDEX_FOR_CHANNEL(ch), byte) = value; +} + +void amc_phy_set_wr_offset(uint8_t ch, uint8_t byte, uint8_t value) +{ + rAMP_DQOUTDLLOVRRD(AMP_INDEX_FOR_CHANNEL(ch), byte) = value; +} + +void amc_phy_run_dq_training(uint8_t ch) +{ + ch = AMP_INDEX_FOR_CHANNEL(ch); // cope with hole in AMP address space + + amc_phy_run_dll_update(ch); + rAMP_DQTRNCMD(ch) = 0x1; // execute DQ training sequence + while ((rAMP_DQTRNCMD(ch) & 0x1) != 0) ; // wait for training to be finished +} + +uint32_t amc_phy_get_dq_training_status(uint8_t ch, uint8_t byte, uint8_t num_bytes) +{ + uint8_t byte_result; + uint32_t status; + + status = rAMP_DQTRNSTS(AMP_INDEX_FOR_CHANNEL(ch)); + byte_result = (status & (1 << (byte + 16))); + + return byte_result; +} + +void amc_phy_configure_dll_pulse_mode(uint8_t ch, bool enable) +{ + ch = AMP_INDEX_FOR_CHANNEL(ch); // cope with hole in AMP address space + + if (!enable) { + rAMP_DLLUPDTCTRL(ch) &= ~((3 << 20) | (1 << 16)); // DLLUptMode = 0, DllUpdtPhyUpdtTyp = 0 + } + else { + rAMP_DLLUPDTCTRL(ch) = amp_dllupdtctrl[ch]; + amc_phy_run_dll_update(ch); + } +} + +void amc_phy_shift_dq_offset(int8_t *dq_offset, uint8_t num_bytes) { + amc_dram_shift_dq_offset(dq_offset, num_bytes); +} diff --git a/drivers/apple/amp/amp_v2.c b/drivers/apple/amp/amp_v2.c new file mode 100644 index 0000000..8ac4ebd --- /dev/null +++ b/drivers/apple/amp/amp_v2.c @@ -0,0 +1,3190 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// PRBS7 patterns used for ca calibration. amc_phy_params.cacalib_sw_loops * amc_phy_params.cacalib_hw_loops must equal 64 +// We extend the size by 8 and repeat the first 8 values because when swloop=64, we don't go outside the array for programming CACALPAT1-7 +static const uint32_t CA_PRBS7_PATTERNS[CA_NUM_PATTERNS + 8] = { + 0x2550B, 0xCF135, 0xC4342, 0x67BFF, 0x825A0, 0x1487E, 0x984EF, 0xEA43E, + 0x0B277, 0xA388D, 0xE5E5F, 0x96DDe, 0x8CC91, 0x720D1, 0xE1649, 0xA8ACA, + 0x466E2, 0x73381, 0x1A14F, 0xFEC40, 0x93698, 0x49C83, 0xEEC28, 0x35563, + 0x692CE, 0xE4D0F, 0x6DAD8, 0xDAA1B, 0xA70AB, 0xDB94B, 0x5C7AD, 0x8DFC1, + 0x897D7, 0xB70C3, 0x7DAB0, 0x7C9E0, 0x87EE6, 0xD186C, 0x04816, 0x3E714, + 0xCAA73, 0x01350, 0xFB706, 0x5668A, 0xD507A, 0x3AF02, 0xF4D67, 0xCB923, + 0xFA456, 0xAD18C, 0x836F0, 0xEEF78, 0xCE265, 0x3F444, 0x31D75, 0x575DA, + 0x2E77C, 0x6C988, 0x21D1D, 0xF1621, 0x0E931, 0x668AF, 0x792A6, 0x42EF4, + 0x2550B, 0xCF135, 0xC4342, 0x67BFF, 0x825A0, 0x1487E, 0x984EF, 0xEA43E, +}; + + +// PRBS patterns for Wrdq and Rddq (for the one after Wrdq) calibration +static const uint32_t DQ_PRBS7_PATTERNS[DQ_NUM_PATTERNS] = { + 0x85858585, 0x4a4a4a4a, 0x9a9a9a9a, 0x9e9e9e9e, 0xa1a1a1a1, 0x88888888, 0xffffffff, 0xcfcfcfcf, + 0xd0d0d0d0, 0x04040404, 0x3f3f3f3f, 0x29292929, 0x77777777, 0x30303030, 0x1f1f1f1f, 0xd4d4d4d4, + 0x3b3b3b3b, 0x16161616, 0x5e5e5e5e, 0x47474747, 0x2f2f2f2f, 0xcbcbcbcb, 0xefefefef, 0x2d2d2d2d, + 0x48484848, 0x19191919, 0x68686868, 0xe4e4e4e4, 0x24242424, 0xc2c2c2c2, 0x65656565, 0x51515151, + 0x71717171, 0x8c8c8c8c, 0xc0c0c0c0, 0xe6e6e6e6, 0xa7a7a7a7, 0x34343434, 0x20202020, 0xfdfdfdfd, + 0x4c4c4c4c, 0x26262626, 0x41414141, 0x93939393, 0x14141414, 0xdddddddd, 0xb1b1b1b1, 0x6a6a6a6a, + 0x67676767, 0xd2d2d2d2, 0x87878787, 0xc9c9c9c9, 0x6c6c6c6c, 0xdbdbdbdb, 0x0d0d0d0d, 0xb5b5b5b5, + 0x55555555, 0x4e4e4e4e, 0xa5a5a5a5, 0xb7b7b7b7, 0xd6d6d6d6, 0xb8b8b8b8, 0xe0e0e0e0, 0x1b1b1b1b, + 0xebebebeb, 0x12121212, 0x61616161, 0x6e6e6e6e, 0x58585858, 0xfbfbfbfb, 0xf0f0f0f0, 0xf9f9f9f9, + 0x73737373, 0x0f0f0f0f, 0x36363636, 0xa3a3a3a3, 0x0b0b0b0b, 0x09090909, 0x8a8a8a8a, 0x7c7c7c7c, + 0x39393939, 0x95959595, 0xa8a8a8a8, 0x02020202, 0x83838383, 0xf6f6f6f6, 0x45454545, 0xacacacac, + 0x3d3d3d3d, 0xaaaaaaaa, 0x81818181, 0x75757575, 0xb3b3b3b3, 0xe9e9e9e9, 0x91919191, 0x97979797, + 0x2b2b2b2b, 0xf4f4f4f4, 0xc6c6c6c6, 0x5a5a5a5a, 0x78787878, 0x06060606, 0xbcbcbcbc, 0xdfdfdfdf, + 0x32323232, 0x9c9c9c9c, 0x22222222, 0x7e7e7e7e, 0xbabababa, 0x63636363, 0xedededed, 0xaeaeaeae, + 0xbebebebe, 0x5c5c5c5c, 0xc4c4c4c4, 0xd9d9d9d9, 0x8e8e8e8e, 0x43434343, 0x10101010, 0xe2e2e2e2, + 0x98989898, 0x1d1d1d1d, 0x57575757, 0xcdcdcdcd, 0x53535353, 0xf2f2f2f2, 0x7a7a7a7a, 0x85858585 +}; + + +static uint32_t ca_patterns_mask[CA_NUM_PATTERNS]; +static int32_t mdllcode[AMC_NUM_CHANNELS][2]; // 1 for AMP_DQ and 1 for AMP_CA + +// Used to save calibration values for each bit per channel and rank for every iteration +static int32_t ca_cal_per_loopchrnk_right[CA_MAX_LOOP_CHN_RNK][CA_NUM_BITS]; +static int32_t ca_cal_per_loopchrnk_left[CA_MAX_LOOP_CHN_RNK][CA_NUM_BITS]; + +// ca data aggregated over all iterations +static int32_t ca_cal_per_chrnk_right[AMC_NUM_CHANNELS * AMC_NUM_RANKS][CA_NUM_BITS]; +static int32_t ca_cal_per_chrnk_left[AMC_NUM_CHANNELS * AMC_NUM_RANKS][CA_NUM_BITS]; + +// rddq data aggregated over all iterations +static int32_t rddq_cal_per_chrnk_right[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; +static int32_t rddq_cal_per_chrnk_left[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; + +// wrdq data aggregated over all iterations +static int32_t wrdq_cal_per_chrnk_right[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; +static int32_t wrdq_cal_per_chrnk_left[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; + +// wrlvl data aggregated over all iterations, we save value for 4 byte lanes + the ca value +static int32_t wrlvl_cal_per_chrnk_rise[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_NUM_BYTES + 1]; +static int32_t wrlvl_cal_per_chrnk_fall[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_NUM_BYTES + 1]; + +// This array will hold the contents of memory that will be used for dq calibration +static uint8_t dqcal_saved_data[AMC_NUM_RANKS][sizeof(DQ_PRBS7_PATTERNS) * AMC_NUM_CHANNELS]__aligned(32); + +// This array will hold the calibration values to be saved to the PMU for resume boot +static uint8_t cal_pmu_bits[CALIB_PMU_BYTES] = { 0 }; + +// Static local function declarations +static void calibrate_ca(void); +static void calibrate_rddq(bool after_wrddqcal); +static void calibrate_wrlvl(void); +static void calibrate_wrdq(void); +static void save_masterdll_values(void); +static void generate_ca_patterns_mask(void); +static void amp_program_ca_patterns(uint32_t ch, uint32_t rnk, uint32_t swloop); +static void amp_init_ca_offset_and_deskew(uint32_t ch); +static uint32_t amp_mask_ca_bits(uint32_t ch, uint32_t mr_cmd); +static void amp_push_casdll_out(uint32_t ch, int32_t offset); +static void amp_enable_cacal_mode(bool enable, uint32_t ch); +static void amp_run_cacal(uint32_t ch); +static void amp_push_ctl_out(uint32_t ch, uint32_t dly_val); +static void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk); +static void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t offset); +static void amp_run_rddqcal(uint32_t ch); +static void amp_wrlvl_init(void); +static void amp_phy_update(uint32_t ch, uint32_t update); +static void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset, bool set_dly_sel); +static void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset, bool set_dly_sel); +static void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun); +static void amp_set_wrdq_sdll(uint32_t ch, uint32_t byte, int32_t offset); +static void run_cacal_sequence(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t mask_bits, uint32_t swloop); +static void find_cacal_right_side_failing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop); +static void find_cacal_right_side_passing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop); +static void enter_cacal_mode(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, bool enter); +static void find_cacal_left_side_failing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop); +static void find_cacal_left_side_passing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop); +static void ca_program_final_values(void); +static void find_rddqcal_right_side_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal); +static void find_rddqcal_right_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal); +static void find_rddqcal_left_side_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal); +static void find_rddqcal_left_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal); +static void rddq_program_final_values(bool after_wrddqcal); +static uint32_t wrlvl_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val); +static uint32_t wrlvl_encode_clk90dly(uint32_t ch, uint32_t val); +static void push_wrlvl_to_0s_region(uint32_t ch, uint32_t rnk); +static void find_wrlvl_0to1_transition(uint32_t ch, uint32_t rnk); +static void find_wrlvl_1to0_transition(uint32_t ch, uint32_t rnk); +static void wrlvl_program_final_values(void); +static void find_wrdqcal_right_side_failing_point(uint32_t ch, uint32_t rnk); +static void find_wrdqcal_right_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b); +static void find_wrdqcal_left_side_failing_point(uint32_t ch, uint32_t rnk); +static void find_wrdqcal_left_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b); +static void wrdq_program_final_values(void); +static uint32_t wr_rd_pattern_result(uint32_t ch, uint32_t rnk, uint32_t sdll_value); +static void save_restore_ca_wrlvl_regs(uint32_t save_or_restore); +static void save_restore_memory_region(bool dqcal_start); +static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val); +static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t min_or_max); + +/////////////////////////////////////////////////////////////////////////////// +////// Global functions +/////////////////////////////////////////////////////////////////////////////// + +#ifdef AMP_SWIZZLE +void amp_swizzle_init(void) +{ +#if (AMP_SWIZZLE == AMP_SWIZZLE_PER_J34M) // per + int ch; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + // Set up the CA Byte Select Mapping for both DQ and CA + rAMP_CACALBYTESEL(AMP_DQ,ch) = 0x00000001; + rAMP_CACALBYTESEL(AMP_CA,ch) = 0x00000001; + + // Set up the CA Bit Select Bit Mapping for both DQ and CA + rAMP_CACALBITSELMAP(AMP_DQ,ch,0) = 0x01234567; + rAMP_CACALBITSELMAP(AMP_DQ,ch,1) = 0xabcdef67; + rAMP_CACALBITSELMAP(AMP_DQ,ch,2) = 0x0000ef89; + rAMP_CACALBITSELMAP(AMP_CA,ch,0) = 0x01234567; + rAMP_CACALBITSELMAP(AMP_CA,ch,1) = 0xabcdef67; + rAMP_CACALBITSELMAP(AMP_CA,ch,2) = 0x0000ef89; + } +#endif // end of (AMP_SWIZZLE == AMP_SWIZZLE_PER_J34M) +} +#endif + +void amc_phy_init(bool resume) +{ + uint32_t ch, f; +#if !SUPPORT_FPGA + uint32_t rd, dq; +#endif + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + rAMP_DLLUPDTCTRL(AMP_DQ, ch) = 0x00017307; + rAMP_DLLUPDTCTRL(AMP_CA, ch) = 0x00017307; + } + amc_phy_enable_dqs_pulldown(false); + +#ifdef AMP_SWIZZLE + amp_swizzle_init(); +#endif + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + rAMP_AMPEN(AMP_DQ, ch) = 1; + rAMP_AMPEN(AMP_CA, ch) = 1; + +#if !SUPPORT_FPGA + + rAMP_DQDQSDS(ch) = amc_phy_params.drive_strength; + rAMP_NONDQDS(ch) = amc_phy_params.drive_strength; +#endif + + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + rAMP_DIFFMODE_FREQ(ch, f) = 0x00000121; + } + +#if !SUPPORT_FPGA + for (rd = 0; rd < AMP_MAX_RD; rd++) { + for (dq = 0; dq < AMP_MAX_DQ; dq++) { + rAMP_RDDQDESKEW_CTRL(ch, rd, dq) = 0x00000006; + } + } + + rAMP_DLLLOCKTIM(AMP_DQ, ch) = 0x000d0013; + rAMP_DLLLOCKTIM(AMP_CA, ch) = 0x000d0013; +#endif + + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + rAMP_DQSINDLLSCL_FREQ(ch, f) = amc_phy_params.freq[f].dqsindllscl; + rAMP_CAOUTDLLSCL_FREQ(ch, f) = amc_phy_params.freq[f].caoutdllscl; + } + + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + rAMP_RDCAPCFG_FREQ(AMP_DQ, ch, f) = amc_phy_params.freq[f].rdcapcfg; + } + +#if !SUPPORT_FPGA + rAMP_DLLUPDTCTRL(AMP_DQ, ch) = 0x00017507; + rAMP_DLLUPDTCTRL(AMP_CA, ch) = 0x00017507; + + if (!amc_phy_params.imp_auto_cal) { + rAMP_IMPAUTOCAL(AMP_DQ, ch) = 0x000103ac; + rAMP_IMPAUTOCAL(AMP_CA, ch) = 0x000103ac; + } + else { + rAMP_IMPAUTOCAL(AMP_DQ, ch) = amc_phy_params.imp_auto_cal; + rAMP_IMPAUTOCAL(AMP_CA, ch) = amc_phy_params.imp_auto_cal; + } +#endif + +#if !SUPPORT_FPGA + // Keep DLL update interval to 0, it will restored after write calibration. + // CoreOS: M7 init sequence change +#if SUB_PLATFORM_S7002 + rAMP_DLLUPDTINTVL(AMP_DQ, ch) = 0x10200000; + rAMP_DLLUPDTINTVL(AMP_CA, ch) = 0x10200000; +#else + rAMP_DLLUPDTINTVL(AMP_DQ, ch) = 0x1020005a; + rAMP_DLLUPDTINTVL(AMP_CA, ch) = 0x1020005a; +#endif + +# ifdef rAMP_MDLLFREQBINDISABLE + rAMP_MDLLFREQBINDISABLE(AMP_DQ, ch) = 0x00000008; + rAMP_MDLLFREQBINDISABLE(AMP_CA, ch) = 0x00000008; +# endif +#else + rAMP_DLLUPDTINTVL(AMP_DQ, ch) = 0; + rAMP_DLLUPDTINTVL(AMP_CA, ch) = 0; + +# ifdef rAMP_MDLLFREQBINDISABLE + rAMP_MDLLFREQBINDISABLE(AMP_DQ, ch) = 0x0000000F; + rAMP_MDLLFREQBINDISABLE(AMP_CA, ch) = 0x0000000F; +# endif +#endif + +#if !SUPPORT_FPGA + rAMP_DLLEN(AMP_DQ, ch) = 0x00000100; + rAMP_DLLEN(AMP_CA, ch) = 0x00000100; + + rAMP_DLLEN(AMP_DQ, ch) = 0x00000101; + rAMP_DLLEN(AMP_CA, ch) = 0x00000101; + + rAMP_DLLEN(AMP_DQ, ch) = 0x00000100; + rAMP_DLLEN(AMP_CA, ch) = 0x00000100; + + amc_phy_run_dll_update(ch); +#endif + + rAMP_AMPINIT(AMP_DQ, ch) = 0x00000001; + rAMP_AMPINIT(AMP_CA, ch) = 0x00000001; + +#if !SUPPORT_FPGA + rAMP_IMPCALCMD(AMP_CA, ch) = 0x00000101; + rAMP_IMPCALCMD(AMP_DQ, ch) = 0x00000101; + + while (rAMP_IMPCALCMD(AMP_CA, ch) & 0x1) {} + while (rAMP_IMPCALCMD(AMP_DQ, ch) & 0x1) {} + + // Wait 5 us after Impedence Calibration to avoid McPhyPending + // preventing the SRFSM from exiting SR. + spin(5); +#endif + } + +#if !SUPPORT_FPGA +#ifndef AMP_CALIBRATION_SKIP + // Restore CA and WrLvl offsets from PMU + if (resume) + save_restore_ca_wrlvl_regs(CALIB_RESTORE); +#endif +#endif +} + +void amc_phy_enable_dqs_pulldown(bool enable) +{ +// Stub because H6 init sequence does not recommend doing this +} + +void amc_phy_scale_dll(int freqsel, int factor) +{ +} + +void amc_phy_run_dll_update(uint8_t ch) +{ + rAMP_DLLUPDTCMD(AMP_DQ, ch) = 0x00000001; + rAMP_DLLUPDTCMD(AMP_CA, ch) = 0x00000001; + + while ((rAMP_DLLUPDTCMD(AMP_DQ, ch) & 0x1) != 0) ; + while ((rAMP_DLLUPDTCMD(AMP_CA, ch) & 0x1) != 0) ; +} + +void amc_phy_bypass_prep(int step) +{ +} + +void amc_phy_finalize() +{ +} + +// Perform CA, RDDQ, and WRLVL calibration +void amc_phy_calibration_ca_rddq_cal(bool resume) +{ +#ifndef AMP_CALIBRATION_SKIP + + if ((amc_phy_params.cacalib_hw_loops * amc_phy_params.cacalib_sw_loops) != CA_NUM_PATTERNS) + panic("Memory calibration: hwloops (%d) and swloops (%d) values are unexpected\n", + amc_phy_params.cacalib_hw_loops, amc_phy_params.cacalib_sw_loops); + + amc_calibration_start(true); + + if (!resume) + calibrate_ca(); + + /* + * The first RdDq Cal is using MRR32 and MRR40. It's needed for WrDq calibration. Hence run before WrDq. + * The second Rd Dq calibration is PRBS pattern based, which needs Wr Dq calibration done. Hence done after WrDq. + * PRBS patterns help in reducing aliasing, hence needed for better accuracy. + */ + calibrate_rddq(false); + + if (!resume) { + calibrate_wrlvl(); + // Save off the CA and WrLvl offsets to PMU + save_restore_ca_wrlvl_regs(CALIB_SAVE); + } + + amc_calibration_start(false); +#endif +} + +void amc_phy_calibration_wrdq_cal(bool resume) +{ +#ifndef AMP_CALIBRATION_SKIP + if (resume) + save_restore_memory_region(true); + + amc_calibration_start(true); + + // ok to keep PSQWQCTL0 and PSQWQCTL1 at their value setup for wrdqcal even for the rddqcal that follows + amc_wrdqcal_start(true); + + calibrate_wrdq(); + + /* + * The first RdDq Cal is using MRR32 and MRR40. It's needed for WrDq calibration. Hence run before WrDq. + * The second Rd Dq calibration is PRBS pattern based, which needs Wr Dq calibration done. Hence done after WrDq. + * PRBS patterns help in reducing aliasing, hence needed for better accuracy. + */ + calibrate_rddq(true); + + amc_wrdqcal_start(false); + + amc_calibration_start(false); + + if (resume) + save_restore_memory_region(false); +#endif + + uint8_t ch; + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + // Restore AMP DLL update interval to POR value + // CoreOS: M7 init sequence change +#if !SUPPORT_FPGA +#if SUB_PLATFORM_S7002 + rAMP_DLLUPDTINTVL(AMP_DQ, ch) = 0x1020005a; + rAMP_DLLUPDTINTVL(AMP_CA, ch) = 0x1020005a; +#endif +#endif + + // Enable AMP clock gating only after Wrdqcal is done + rAMP_AMPCLK(AMP_DQ, ch) = 0x00010000; + rAMP_AMPCLK(AMP_CA, ch) = 0x00010000; + } +} + +/////////////////////////////////////////////////////////////////////////////// +////// Local functions +/////////////////////////////////////////////////////////////////////////////// + +// To dump calibration results from iBoot menu command +static int dump_mem_calibration_info(int argc, struct cmd_arg *args) +{ + uint32_t ch, byte, bit; + + dprintf(DEBUG_INFO, "Memory calibration results\n"); + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + dprintf(DEBUG_INFO, "Channel %d\n", ch); + + dprintf(DEBUG_INFO, "\tCA SDLL: 0x%02x\n", rAMP_CASDLLCTRL(ch) & DLLVAL_BITS); + + dprintf(DEBUG_INFO, "\t\tPer Bit Deskew: "); + for (bit = 0; bit < CA_NUM_BITS; bit++) + dprintf(DEBUG_INFO, "0x%02x ", rAMP_CADESKEW_CTRL(ch, bit) & DESKEW_CTRL_BITS); + + dprintf(DEBUG_INFO, "\n\t\tCS, CK, CKE Deskew: 0x%02x", rAMP_CKDESKEW_CTRL(ch) & DESKEW_CTRL_BITS); + + dprintf(DEBUG_INFO, "\n"); + + dprintf(DEBUG_INFO, "\tCA WrLvlSDLL: 0x%02x\n", rAMP_CAWRLVLSDLLCODE(ch) & DLLVAL_BITS); + dprintf(DEBUG_INFO, "\tDQ WrLvlSDLL: "); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + dprintf(DEBUG_INFO, "0x%02x ", rAMP_DQWRLVLSDLLCODE(ch, byte) & DLLVAL_BITS); + + dprintf(DEBUG_INFO, "\n"); + + dprintf(DEBUG_INFO, "\tRead DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dprintf(DEBUG_INFO, "\t\tByte %d SDLL: 0x%02x\n", byte, rAMP_DQSDLLCTRL_RD(ch, byte) & DLLVAL_BITS); + + dprintf(DEBUG_INFO, "\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + dprintf(DEBUG_INFO, "0x%02x ", rAMP_RDDQDESKEW_CTRL(ch, byte, bit) & DESKEW_CTRL_BITS); + + dprintf(DEBUG_INFO, "\n"); + + } + + dprintf(DEBUG_INFO, "\tWrite DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dprintf(DEBUG_INFO, "\t\tByte %d SDLL: 0x%02x\n", byte, rAMP_DQSDLLCTRL_WR(ch, byte) & DLLVAL_BITS); + + dprintf(DEBUG_INFO, "\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + dprintf(DEBUG_INFO, "0x%02x ", rAMP_WRDQDESKEW_CTRL(ch, byte, bit) & DESKEW_CTRL_BITS); + + dprintf(DEBUG_INFO, "\n"); + } + } + + return 0; +} +MENU_COMMAND_DEBUG(memcal_info, dump_mem_calibration_info, "Prints memory calibration results", NULL); + +static void calibrate_ca(void) +{ + uint32_t ch, rnk, swloop, mask_bits; + + generate_ca_patterns_mask(); + + // Required since the dll values may change slightly during calibration + save_masterdll_values(); + + // Calibration sequence is to be run for each rank in each channel, amc_phy_params.cacalib_sw_loops number of times + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + for (rnk = 0; rnk < AMC_NUM_RANKS; rnk++) { + for (swloop = 0; swloop < amc_phy_params.cacalib_sw_loops; swloop++) { + amp_program_ca_patterns(ch, rnk, swloop); + + amp_init_ca_offset_and_deskew(ch); + + // Training of CA Bits 0-3 and 5-8: MR41 cmd (training cmd must be sent before cacalibmode is enabled in AMP) + mask_bits = amp_mask_ca_bits(ch, MR41); + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR41, MR41 << 2); + amp_enable_cacal_mode(true, ch); + run_cacal_sequence(ch, rnk, MR41, mask_bits, swloop); + amp_enable_cacal_mode(false, ch); + + amp_init_ca_offset_and_deskew(ch); + + // Training of CA Bits 4 and 9: MR48 cmd (training cmd must be sent before cacalibmode is enabled in AMP) + mask_bits = amp_mask_ca_bits(ch, MR48); + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR48, MR48 << 2); + amp_enable_cacal_mode(true, ch); + run_cacal_sequence(ch, rnk, MR48, mask_bits, swloop); + amp_enable_cacal_mode(false, ch); + + amp_init_ca_offset_and_deskew(ch); + + // Exit CA Training mode: MR42 + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR42, MR42 << 2); + } + } + } + + // By now, we have compiled right and left edges of passing window for all CA bits over a number of iterations + // Aggregate the results, and find the center point of the window, and program it + ca_program_final_values(); +} + +static void calibrate_rddq(bool after_wrddqcal) +{ + uint32_t ch, rnk, data; + + // step7 + if (after_wrddqcal == false) { + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + for (rnk = 0; rnk < AMC_NUM_RANKS; rnk++) { + amp_setup_rddq_cal(ch, rnk); + + amc_mrcmd_to_ch_rnk(MR_READ, ch, rnk, MR5, (uintptr_t)&data); + + amc_enable_rddqcal(true); + + // Find the left and right edges of the eye + find_rddqcal_right_side_failing_point(ch, rnk, false); + find_rddqcal_left_side_failing_point(ch, rnk, false); + + amc_enable_rddqcal(false); + } + } + } + // step10 + else { + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + for (rnk = 0; rnk < AMC_NUM_RANKS; rnk++) { + // Find the left and right edges of the eye using PRBS patterns + // These results will be more accurate + find_rddqcal_right_side_failing_point(ch, rnk, true); + find_rddqcal_left_side_failing_point(ch, rnk, true); + } + } + } + + // Now that we have per bit left and right endpoints for each channel and rank, aggregate and program final values + rddq_program_final_values(after_wrddqcal); +} + +// Align the clock signal with the DQ signals +static void calibrate_wrlvl(void) +{ + uint32_t ch, rnk; + uint32_t data, cawrlvlsdll; + + amp_wrlvl_init(); + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + + cawrlvlsdll = rAMP_CAWRLVLSDLLCODE(ch); + + for (rnk = 0; rnk < AMC_NUM_RANKS; rnk++) { + data = 0x80 + RD_LATENCY_ENCODE; // 0x80 is added here to set the Write Level bit (bit 7) to 1 + + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR2, data); + + // find the region where all bits return a 0 + push_wrlvl_to_0s_region(ch, rnk); + + // push out the clock signal until all bits return a 1 + find_wrlvl_0to1_transition(ch, rnk); + + // now go back towards the transition edge found earlier, but from this side of the edge + find_wrlvl_1to0_transition(ch, rnk); + + // reset cawrlvlsdllcode to original value (0), before sending cmd to exit wrlvl mode (MR2) + amp_set_cawrlvl_sdll(ch, cawrlvlsdll, false); + + data = RD_LATENCY_ENCODE; + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR2, data); + } + } + + // Program the final wrlvl values + wrlvl_program_final_values(); +} + +static void calibrate_wrdq(void) +{ + uint32_t ch, rnk; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + for (rnk = 0; rnk < AMC_NUM_RANKS; rnk++) { + find_wrdqcal_right_side_failing_point(ch, rnk); + find_wrdqcal_left_side_failing_point(ch, rnk); + } + } + + wrdq_program_final_values(); +} + +static void save_masterdll_values(void) +{ + uint32_t ch; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + mdllcode[ch][AMP_DQ] = (rAMP_MDLLCODE(AMP_DQ, ch) & DLLVAL_BITS); + mdllcode[ch][AMP_CA] = (rAMP_MDLLCODE(AMP_CA, ch) & DLLVAL_BITS); + } +} + +static void generate_ca_patterns_mask(void) +{ + uint32_t index, patr, patf = 0; + uint32_t mask = 0; + + // generate the pattern to be used for each CA calibration iteration + for (index = 0; index < (amc_phy_params.cacalib_sw_loops * amc_phy_params.cacalib_hw_loops); index++) { + patr = (CA_PRBS7_PATTERNS[index]) & CA_ALL_BITS; + patf = (CA_PRBS7_PATTERNS[index]) >> CA_NUM_BITS; + mask = patr ^ patf; + ca_patterns_mask[index] = mask; + } +} + +static void amp_program_ca_patterns(uint32_t ch, uint32_t rnk, uint32_t swloop) +{ + uint32_t cacalctrl, p; + + // Program rank, hardware loop count, and timing params + // Timing params are taken from lpddr3 jedec spec + cacalctrl = (rnk << 24) | ((amc_phy_params.cacalib_hw_loops - 1) << 16) | (16 << 8) | (10 << 0); + + rAMP_CACALCTRL(AMP_DQ, ch) = cacalctrl; + rAMP_CACALCTRL(AMP_CA, ch) = cacalctrl; + + for (p = 0; p < AMP_MAX_PATTERNS; p++) { + rAMP_CACALPAT(AMP_DQ, ch, p) = CA_PRBS7_PATTERNS[(swloop * amc_phy_params.cacalib_hw_loops) + p]; + rAMP_CACALPAT(AMP_CA, ch, p) = CA_PRBS7_PATTERNS[(swloop * amc_phy_params.cacalib_hw_loops) + p]; + } +} + +// (Re-)Initialize ca offset and deskew registers +static void amp_init_ca_offset_and_deskew(uint32_t ch) +{ + uint8_t d; + int32_t camdllcode = mdllcode[ch][AMP_CA]; + + // ensure negative sign is set with mdllcode value for ca offset (mdllcode guaranteed by designers not to be negative) + amp_push_casdll_out(ch, (-1 * camdllcode)); + + // Clear cadeskewctrl registers + for (d = 0; d < CA_NUM_BITS; d++) + rAMP_CADESKEW_CTRL(ch, d) = 0; +} + +static uint32_t amp_mask_ca_bits(uint32_t ch, uint32_t mr_cmd) +{ + uint32_t mask_bits; + + // Assuming no byte swizzling + if (mr_cmd == MR41) { + // MR41: Mask out bits 9 and 4 + mask_bits = 0x210; + } else if (mr_cmd == MR48) { + // MR48: Mask out bits 0-3 and bits 5-8 + mask_bits = 0x1EF; + } else { + // No bits are masked out + mask_bits = 0; + } + + rAMP_CACALMASK(AMP_DQ, ch) = mask_bits; + rAMP_CACALMASK(AMP_CA, ch) = mask_bits; + + return mask_bits; +} + +static void amp_push_casdll_out(uint32_t ch, int32_t offset) +{ + uint32_t ca_bit; + uint32_t cadeskewcode; + int32_t camdllcode = mdllcode[ch][AMP_CA]; + + if (offset > 0) { + // New equation given by Rakesh: if offset is within DELIMIT_POS_ADJ_CASDLL steps of camdllcode, limit it to (master dll - DELIMIT_POS_ADJ_CASDLL) + if (offset >= (camdllcode - DELIMIT_POS_ADJ_CASDLL)) { + uint8_t difference = (uint8_t) (offset - (camdllcode - DELIMIT_POS_ADJ_CASDLL)); + offset = camdllcode - DELIMIT_POS_ADJ_CASDLL; + + if (difference >= MAX_DESKEW_PROGRAMMED) + cadeskewcode = MAX_DESKEW_PROGRAMMED; + else + cadeskewcode = difference; + + // Adjust deskew registers for each ca bit + for (ca_bit = 0; ca_bit < CA_NUM_BITS; ca_bit++) + rAMP_CADESKEW_CTRL(ch, ca_bit) = cadeskewcode; + + } + } + + rAMP_CASDLLCTRL(ch) = (1 << 24) | INT_TO_OFFSET(offset); + while (rAMP_CASDLLCTRL(ch) & (1 << 24)); +} + +static void amp_enable_cacal_mode(bool enable, uint32_t ch) +{ + // Set or clear CACalMode bit + if (enable) + rAMP_CACALRUN(AMP_CA, ch) |= CACALRUN_CACALMODE; + else + rAMP_CACALRUN(AMP_CA, ch) &= ~CACALRUN_CACALMODE; +} + +static void amp_run_cacal(uint32_t ch) +{ + // DQ must be set before CA + rAMP_CACALRUN(AMP_DQ, ch) |= CACALRUN_RUNCACAL; + // CACalMode should already be set + rAMP_CACALRUN(AMP_CA, ch) |= CACALRUN_RUNCACAL; + // Poll on the DQ register + while(rAMP_CACALRUN(AMP_DQ, ch) & CACALRUN_RUNCACAL); +} + +static void amp_push_ctl_out(uint32_t ch, uint32_t dly_val) +{ + uint32_t cadramsigdly; + + rAMP_TESTMODE(AMP_CA, ch) = TESTMODE_FORCECKELOW; + + // Fix for Radar 10790574 - Hold Violation on CKE + if (dly_val >= 0xd) + cadramsigdly = (3 << 4); + else if (dly_val >= 0xa) + cadramsigdly = (2 << 4); + else if (dly_val >= 0x8) + cadramsigdly = (1 << 4); + else + cadramsigdly = (0 << 4); + + rAMP_DRAMSIGDLY(AMP_CA, ch, 0) = cadramsigdly; + rAMP_CSDESKEW_CTRL(ch) = dly_val; + rAMP_CKDESKEW_CTRL(ch) = dly_val; + rAMP_CKEDESKEW_CTRL(ch) = dly_val; + + rAMP_TESTMODE(AMP_CA, ch) = 0; +} + +static void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk) +{ + // At this point the AMC's READLEVELING should already be setup as 0x00000300 + // Make DQCALCTRL.DQCalPatSel (bits 1:0) match READLEVELING.RdLvlPatOpt + rAMP_DQCALCTRL(ch) = (rnk << 16) | (RDDQ_LOOPCNT << 8) | (3 << 0); +} + +// This functions set the slave dll for a particular byte lane of RDDQ as specified in the offset parameter +static void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t offset) +{ + rAMP_DQSDLLCTRL_RD(ch, byte) = (1 << 24) | offset; + // Wait for Run bit to clear + while(rAMP_DQSDLLCTRL_RD(ch, byte) & (1 << 24)); +} + +static void amp_run_rddqcal(uint32_t ch) +{ + rAMP_DQCALRUN(ch) = 1; + while (rAMP_DQCALRUN(ch) & 1); +} + +static void amp_wrlvl_init(void) +{ + uint32_t ch; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + // Write Leveling Timing Control Registers to program tMRD and tWLO timing params + // Taking these values from jedec_lpddr3s8_4gb_x32_1600.soma + // tWLO has a max value of 20ns for 1600 freq + // tWLMRD has a min value of 40tck for 1600 freq + + rAMP_DQWRLVLTIM(ch) = (12 << 8) | (16 << 0); + } +} + +// follow a certain sequence required when wrlvl dlysel is to be updated +static void amp_phy_update(uint32_t ch, uint32_t update) { + // Release CKE and disable phyupdt to allow normal operation + if (!update) + rAMP_TESTMODE(AMP_CA, ch) = 0; + + // issue phyupdt to block AMC traffic + rAMP_CAPHYUPDTCRTL(ch) = update; + // wait for the phyupdt change to take effect. there is only 1 bit in the status reg: bit 0. + while((rAMP_CAPHYUPDTSTATUS(ch) & 1) != (update & 1)); + + // CKE must be low when updating dlysel to avoid glitches + if (update) + rAMP_TESTMODE(AMP_CA, ch) = TESTMODE_FORCECKELOW; +} + +// Must ensure that WrLvL SDLLs are programmed with all precautions to avoid glitch on clock signals +static void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset, bool set_dly_sel) +{ + if (set_dly_sel) { + // Must send phyupdt to AMC to avoid traffic while CKE is low + amp_phy_update(ch, 1); + + // Ok to set directly to final value (instead of incrementing) since CKE is low + rAMP_CAWRLVLSDLLCODE(ch) = offset; + + /* + * Since M7 memory clock much slower than Alcatraz, need to toggle phyupdt to ensure + * refreshes that have piled up due to phyupdt being set are flushed out + */ + if (amc_phy_params.wrlvl_togglephyupdt) { + amp_phy_update(ch, 0); + amp_phy_update(ch, 1); + } + + // program the dlysel value with CKE low to avoid glitches to DRAM + rAMP_CAWRLVLCLKDLYSEL(ch) = wrlvl_encode_dlyval(ch, AMP_CA, offset); + + // disable phyupdt and release CKE back to high + amp_phy_update(ch, 0); + } else { + uint32_t cawrlvlsdll = rAMP_CAWRLVLSDLLCODE(ch); + int32_t step = (cawrlvlsdll < offset) ? 1 : -1; + + // when CKE is not low, need to step by 1 to avoid glitches to DRAM + for ( ; cawrlvlsdll != offset; cawrlvlsdll += step) + rAMP_CAWRLVLSDLLCODE(ch) = cawrlvlsdll + step; + } +} + +// Must ensure that WrLvL SDLLs are programmed with all precautions to avoid glitches +static void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset, bool set_dly_sel) +{ + if (set_dly_sel) { + uint32_t dqwrlvldlychainctrl = rAMP_DQWRLVLDLYCHAINCTRL(ch, byte); + + // Must send phyupdt to AMC to avoid traffic while CKE is low + amp_phy_update(ch, 1); + + // Ok to set directory final value (instead of incrementing) since CKE is low + rAMP_DQWRLVLSDLLCODE(ch, byte) = offset; + + /* + * Since M7 memory clock much slower than Alcatraz, need to toggle phyupdt to ensure + * refreshes that have piled up due to phyupdt being set are flushed out + */ + if (amc_phy_params.wrlvl_togglephyupdt) { + amp_phy_update(ch, 0); + amp_phy_update(ch, 1); + } + + // program dlysel (also, preserve bits 17:16) with CKE low to avoid glitches to DRAM + rAMP_DQWRLVLDLYCHAINCTRL(ch, byte) = (dqwrlvldlychainctrl & 0x00030000) | wrlvl_encode_dlyval(ch, AMP_DQ, offset); + + // disable phyupdt and release CKE back to high + amp_phy_update(ch, 0); + } else { + uint32_t dqwrlvlsdll = rAMP_DQWRLVLSDLLCODE(ch, byte); + int32_t step = (dqwrlvlsdll < offset) ? 1 : -1; + + // when CKE is not low, need to step by 1 to avoid glitches to DRAM + for ( ; dqwrlvlsdll != offset; dqwrlvlsdll += step) + rAMP_DQWRLVLSDLLCODE(ch, byte) = dqwrlvlsdll + step; + } +} + +static void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun) +{ + rAMP_DQWRLVLRUN(ch) = wrlvlrun; + while(rAMP_DQWRLVLRUN(ch)); +} + +// This functions set the slave dll for a particular byte lane of WRDQ as specified in the offset parameter +static void amp_set_wrdq_sdll(uint32_t ch, uint32_t byte, int32_t offset) +{ + uint32_t dq_bit; + uint32_t dqdeskewcode; + int32_t dqmdllcode = mdllcode[ch][AMP_DQ]; + + if (offset > 0) { + // New equation given by Rakesh: if offset is within DELIMIT_POS_ADJ_WRDQSDLL steps of dqmdllcode, limit it to (master dll - DELIMIT_POS_ADJ_WRDQSDLL) + if (offset >= (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL)) { + uint8_t difference = (uint8_t) (offset - (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL)); + offset = dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL; + + if (difference >= DQ_MAX_DESKEW_PER_BIT) + dqdeskewcode = DQ_MAX_DESKEW_PER_BIT; + else + dqdeskewcode = difference; + + // Adjust deskew registers for each dq bit + for (dq_bit = 0; dq_bit < DQ_NUM_BITS_PER_BYTE; dq_bit++) + rAMP_WRDQDESKEW_CTRL(ch, byte, dq_bit) = dqdeskewcode; + + // Also update the Data Mask (DM), controlled by the DQSDESKEW register + rAMP_WRDQSDESKEW_CTRL(ch, byte) = dqdeskewcode; + } + + // set wrlvlclk90dly (bits 17:16 of wrlvldlychainctrl reg) if positive sdll value + rAMP_DQWRLVLDLYCHAINCTRL(ch, byte) = (wrlvl_encode_clk90dly(ch, offset) << 16) | (rAMP_DQWRLVLDLYCHAINCTRL(ch, byte) & 0x3); + } + + rAMP_DQSDLLCTRL_WR(ch, byte) = (1 << 24) | INT_TO_OFFSET(offset); + // Wait for Run bit to clear + while(rAMP_DQSDLLCTRL_WR(ch, byte) & (1 << 24)); +} + +static void run_cacal_sequence(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t mask_bits, uint32_t swloop) +{ + uint32_t combined_mask, hwloop; + uint32_t pat_mask = 0; + + for (hwloop = 0; hwloop < amc_phy_params.cacalib_hw_loops; hwloop++) + pat_mask |= ca_patterns_mask[(swloop * amc_phy_params.cacalib_hw_loops) + hwloop]; + + // This represents the bits that don't have a transition on any of the patterns used during the hwloop calibration + combined_mask = mask_bits | (CA_ALL_BITS - pat_mask); + + // To find the FAIL <-> PASS <-> FAIL window + find_cacal_right_side_failing_point(ch, rnk, mr_cmd, combined_mask, swloop); + find_cacal_left_side_failing_point(ch, rnk, combined_mask, swloop); +} + +// Establish the right edge of the window by finding the point where all CA bits fail +static void find_cacal_right_side_failing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop) +{ + bool all_bits_fail = false; + uint32_t cacalresult = 0; + uint32_t push_ck_out = 0; + + cacalresult = CA_ALL_BITS; + + // Increase delay to the right until all bits fail + do { + amp_run_cacal(ch); + cacalresult = cacalresult & (rAMP_CACALRESULT(ch) & CA_ALL_BITS); + + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = false; + push_ck_out = push_ck_out + FINER_STEP_SZ; + + amp_init_ca_offset_and_deskew(ch); + + // Make AMP and DRAM exit CaCal Mode in order to update the CK, CKE, and CS delays + enter_cacal_mode(ch, rnk, mr_cmd, false); + + // Update CK, CKE, and CS signal delays + amp_push_ctl_out(ch, push_ck_out); + + // Re-enter CaCal mode + enter_cacal_mode(ch, rnk, mr_cmd, true); + } else { + all_bits_fail = true; + + // Do a per bit calculation of when they start passing again + find_cacal_right_side_passing_point(ch, rnk, mr_cmd, combined_mask, swloop); + } + } while ((push_ck_out < MAX_DESKEW_OFFSET) && (all_bits_fail == false)); + + if ((push_ck_out >= MAX_DESKEW_OFFSET) && (all_bits_fail == false)) { + dprintf(DEBUG_INFO, "Memory CA calibration: Unable to find right side failing point for channel %d\n", ch); + + // Failing point cannot be found, continuing to passing point assuming failure at this setting + find_cacal_right_side_passing_point(ch, rnk, mr_cmd, combined_mask, swloop); + } + + // Reset CK delay back to 0 + if (rAMP_CKDESKEW_CTRL(ch)) { + // Exit CaCal Mode for AMP and DRAM before modifying CK, CKE, and CS signals + enter_cacal_mode(ch, rnk, mr_cmd, false); + + // Ok from Rakesh to set to 0 directly instead of decrementing by 1 + amp_push_ctl_out(ch, 0); + + // Re-enable CACal Mode + enter_cacal_mode(ch, rnk, mr_cmd, true); + } +} + +// Finds the passing region on the right edge of window +static void find_cacal_right_side_passing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop) +{ + bool switch_from_cktoca; + int32_t tap_value; + uint32_t cacalresult; + int32_t camdllcode; + int32_t saved_val; + uint32_t all_bits_pass; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + uint32_t step_incr; + uint8_t bit_indx; + uint32_t ckdeskew; + uint32_t loopchrnk_indx; + + all_bits_pass = 0; + step_incr = FINER_STEP_SZ; + camdllcode = mdllcode[ch][AMP_CA]; + ckdeskew = rAMP_CKDESKEW_CTRL(ch); + + // For every swloop, we'll save passing values for each channel & rank + loopchrnk_indx = (swloop * AMC_NUM_CHANNELS * AMC_NUM_RANKS) + (ch * AMC_NUM_RANKS) + rnk; + + if (ckdeskew) { + tap_value = ckdeskew; + switch_from_cktoca = false; + } else { + // Since clock delay is already down to 0, use the slave delay. + // We only have 2 knobs to turn for delay: clock and sdll + tap_value = (rAMP_CASDLLCTRL(ch) & DLLVAL_BITS); + tap_value = OFFSET_TO_INT(tap_value); + switch_from_cktoca = true; + } + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those done + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + // Finding Right side passing point on per bit level. Moving Right to Left to find point where it turns from FAIL TO PASS + do { + if (switch_from_cktoca == false) { + // Make AMP and DRAM exit CaCal Mode in order to update the CK, CKE, and CS delays + enter_cacal_mode(ch, rnk, mr_cmd, false); + + // Update CK, CKE, and CS signal delays + amp_push_ctl_out(ch, tap_value); + + // Re-enter CaCal mode + enter_cacal_mode(ch, rnk, mr_cmd, true); + } else { + amp_push_casdll_out(ch, tap_value); + } + + // Run the ca calibration in hw + amp_run_cacal(ch); + cacalresult = rAMP_CACALRESULT(ch) & CA_ALL_BITS; + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + // For bits that are not masked, need to check pass/fail + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // Bit has passed for SOLID_PASS_DETECT number of times, consider it done. + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // This is the first time this bit has passed, save this point in the array + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + if (switch_from_cktoca == false) { + // MdllCode is considered '0' in this case + saved_val = -1 * (tap_value + camdllcode); + } else { + saved_val = tap_value; + } + + ca_cal_per_loopchrnk_right[loopchrnk_indx][bit_indx] = saved_val; + } + } else { + // Bit failed to pass calibration, reset the SolidBitPass value to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // If ALL bits are not passing - keep moving ca signals from Right to Left + if (all_bits_pass == 0) { + if ((tap_value == 0) && (switch_from_cktoca == false)) { + switch_from_cktoca = true; + + tap_value = (rAMP_CASDLLCTRL(ch) & DLLVAL_BITS); + tap_value = OFFSET_TO_INT(tap_value); + } + + if (switch_from_cktoca == false) { + tap_value = tap_value - step_incr; + } else { + tap_value = tap_value + step_incr; + } + } + + } while ((tap_value <= MAX_SDLL_VAL) && (all_bits_pass == 0)); + + if (all_bits_pass == 0) { + panic("Memory CA calibration: Unable to find passing point for all bits on the right side"); + } +} + +static void enter_cacal_mode(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, bool enter) +{ + // For entry, send MR41 command to DRAM before AMP register is changed + if (enter) { + // Re-enter CaCal Mode with MR41 always since some DRAMs don't support entering this mode with MR48 + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR41, MR41 << 2); + if (mr_cmd != MR41) + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, mr_cmd, mr_cmd << 2); + + amp_enable_cacal_mode(true, ch); + } + + // For exit, change AMP register before sending DRAM command (MR42) + else { + amp_enable_cacal_mode(false, ch); + amc_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR42, MR42 << 2); + } +} + +static void find_cacal_left_side_failing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop) +{ + // At this point, we've already played with all possible CK delays. At the end of find_cacal_right_side_failing_point routine, + // we reset the CK delays to 0. + // Loop through CaSDLLOvrVal from -MasterDLL to +Max until all failing points on the left side are found + + uint32_t all_bits_fail; + uint32_t step_incr; + int32_t push_ca_out; + uint32_t cacalresult; + int32_t camdllcode; + uint32_t max_caleft_point_reached; + int32_t max_caleft_point_val; + int32_t casdllctrl, ca0deskewctrl; + + all_bits_fail = 0; + cacalresult = CA_ALL_BITS; + step_incr = COARSE_STEP_SZ; + max_caleft_point_reached = 0; + + camdllcode = mdllcode[ch][AMP_CA]; + max_caleft_point_val = camdllcode + MAX_DESKEW_OFFSET - DELIMIT_POS_ADJ_CASDLL; + + casdllctrl = rAMP_CASDLLCTRL(ch) & DLLVAL_BITS; + casdllctrl= OFFSET_TO_INT(casdllctrl); + ca0deskewctrl = rAMP_CADESKEW_CTRL(ch, 0); + + // ca0deskewctrl will be non-zero only if casdll reached (camdllcode - DELIMIT_POS_ADJ_CASDLL) + push_ca_out = casdllctrl + ca0deskewctrl; + + // Increment CaSDLLOvrVal from -ve Master Code to +MAX_SDLL_VAL + do { + if (push_ca_out >= max_caleft_point_val) { + max_caleft_point_reached = 1; + } + // Push out this new ca offset + amp_push_casdll_out(ch, push_ca_out); + + // run the calibration in hw + amp_run_cacal(ch); + cacalresult = cacalresult & (rAMP_CACALRESULT(ch) & CA_ALL_BITS); + + // combined mask has don't care bits (based on pattern) and masked bits (based on MR41 or MR48) that we should ignore + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = 0; + } else { + all_bits_fail = 1; + + // Now, we have found the left edge of window. Find the passing point for all bits + find_cacal_left_side_passing_point(ch, rnk, combined_mask, swloop); + } + + // increase the offset + if (all_bits_fail == 0) + push_ca_out = push_ca_out + step_incr; + + if ((push_ca_out > MAX_SDLL_VAL) && (all_bits_fail == 0)) { + panic("Memory CA calibration: Unable to find failing point for all bits on the left side"); + } + + // Forcefully ending this loop as there are no more sdll taps left to proceed ahead + if (max_caleft_point_reached && (all_bits_fail == 0)) + { + dprintf(DEBUG_INFO, "Memory CA calibration: SDLL ran out of taps when trying to find left side failing point\n"); + + find_cacal_left_side_passing_point(ch, rnk, combined_mask, swloop); + all_bits_fail = 1; + } + } while ((push_ca_out <= MAX_SDLL_VAL) && (all_bits_fail == 0) && (max_caleft_point_reached == 0)); +} + +static void find_cacal_left_side_passing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop) +{ + uint32_t loopchrnk_indx; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + int32_t tap_value; + uint32_t cacalresult; + int32_t camdllcode; + int32_t ca0deskewctrl; + uint32_t all_bits_pass; + uint32_t step_incr; + uint32_t bit_indx; + + loopchrnk_indx = (swloop * AMC_NUM_CHANNELS * AMC_NUM_RANKS) + (ch * AMC_NUM_RANKS) + rnk; + + tap_value = rAMP_CASDLLCTRL(ch) & DLLVAL_BITS; + tap_value = OFFSET_TO_INT(tap_value); + ca0deskewctrl = rAMP_CADESKEW_CTRL(ch, 0); + camdllcode = mdllcode[ch][AMP_CA]; + + step_incr = FINER_STEP_SZ; + all_bits_pass = 0; + + // ca0deskewctrl will be non-zero only if casdll reached (camdllcode - DELIMIT_POS_ADJ_CASDLL) + tap_value += ca0deskewctrl; + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those passed + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + // Finding Left side passing point on per bit level. Move Left to Right to find point where it turns from FAIL TO PASS + do { + // Push out this new ca offset + amp_push_casdll_out(ch, tap_value); + + // Run the calibration in hw + amp_run_cacal(ch); + cacalresult = rAMP_CACALRESULT(ch) & CA_ALL_BITS; + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + // check pass/fail for bits not masked + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // bit has passed SOLID_PASS_DETECT straight times, consider it done + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // first time bit has passed, record this value + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + ca_cal_per_loopchrnk_left[loopchrnk_indx][bit_indx] = tap_value; } + } else { + // bit failed calibration, reset the SolidBitPass value back to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window + if (all_bits_pass == 0) { + tap_value = tap_value - step_incr; + } + + if ((tap_value < (-1 * camdllcode)) && (all_bits_pass == 0)) { + // print error message as Left Failing Point cannot be found + all_bits_pass = 1; + panic("Memory CA calibration: Unable to find passing point for all bits on the left side"); + } + } while ((tap_value > (-1 * camdllcode)) && (all_bits_pass == 0)); +} + +static void ca_program_final_values(void) +{ + uint32_t loopchrnk0_indx, loopchrnk1_indx, chrnk0_indx, chrnk1_indx, ch; + uint32_t bit_indx; + int32_t ca_bit_center[CA_NUM_BITS]; + int32_t ca_bit_deskew[CA_NUM_BITS]; + int32_t tmp_left_pos_val, tmp_right_pos_val; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t camdllcode; + int32_t min_ca_bit_center; + int32_t adj_ca_bit_center; + uint32_t cs_adj_val; + + int32_t rank_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t swloop, hwloop; + uint32_t mask; + uint32_t comb_mask, tmp_mask; + uint32_t mask_txn_detect; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + camdllcode = mdllcode[ch][AMP_CA]; + + // Calculate the Center Points for each CA bit + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + comb_mask = 0x0; + mask_txn_detect = 0x0; + tmp_mask = 0x0; + + // Compute the aggr eye over multiple swloop and hwloop for all ranks + for (swloop = 0; swloop < amc_phy_params.cacalib_sw_loops; swloop++) { + mask = 0x0; + for (hwloop=0; hwloop < amc_phy_params.cacalib_hw_loops; hwloop++) + mask = mask | ca_patterns_mask[(swloop * amc_phy_params.cacalib_hw_loops) + hwloop]; + + // An explanation of the masks is below. Note that we only recorded result for a bit from a particular iteration if the bit had a transition. + // mask: for pattern(s) sent in this swloop, indicates if the bit had a transition + // tmp_mask: aggregates mask over all loops, including current swloop + // comb_mask: aggregates mask over all loops, upto the last iteration of the swloop. After it is used to generate mask_txn_detect, it catches upto same value as tmp_mask + // mask_txn_detect: indicates the first time a bit transitioned was in this swloop + tmp_mask = tmp_mask | mask; + mask_txn_detect = tmp_mask ^ comb_mask; + comb_mask = comb_mask | mask; + + /* + * Rank 0 + */ + + loopchrnk0_indx = (swloop * AMC_NUM_CHANNELS * AMC_NUM_RANKS) + (ch * AMC_NUM_RANKS) + 0; + chrnk0_indx = (ch * AMC_NUM_RANKS) + 0; + + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[0] = ca_cal_per_loopchrnk_left[loopchrnk0_indx][bit_indx]; + tmp_left_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + left_pos_val = tmp_left_pos_val; + ca_cal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = ca_cal_per_chrnk_left[chrnk0_indx][bit_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + ca_cal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[0] = ca_cal_per_loopchrnk_right[loopchrnk0_indx][bit_indx]; + tmp_right_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + right_pos_val = tmp_right_pos_val; + ca_cal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = ca_cal_per_chrnk_right[chrnk0_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MAX_ENDPT); + ca_cal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } + + if (AMC_NUM_RANKS > 1) { + /* + * Rank 1 + */ + + if (AMC_NUM_RANKS > AMP_MAX_RANKS_PER_CHAN) + panic("amp_v2: AMC_NUM_RANKS = %d is more than hw is capable of supporting (%d)\n", AMC_NUM_RANKS, AMP_MAX_RANKS_PER_CHAN); + + loopchrnk1_indx = (swloop * AMC_NUM_CHANNELS * AMC_NUM_RANKS) + (ch * AMC_NUM_RANKS) + 1; + chrnk1_indx = (ch * AMC_NUM_RANKS) + 1; + + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[1] = ca_cal_per_loopchrnk_left[loopchrnk1_indx][bit_indx]; + tmp_left_pos_val = rank_val[1]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + left_pos_val = tmp_left_pos_val; + ca_cal_per_chrnk_left[chrnk1_indx][bit_indx] = left_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = ca_cal_per_chrnk_left[chrnk1_indx][bit_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + ca_cal_per_chrnk_left[chrnk1_indx][bit_indx] = left_pos_val; + } + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[1] = ca_cal_per_loopchrnk_right[loopchrnk1_indx][bit_indx]; + tmp_right_pos_val = rank_val[1]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + right_pos_val = tmp_right_pos_val; + ca_cal_per_chrnk_right[chrnk1_indx][bit_indx] = right_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = ca_cal_per_chrnk_right[chrnk1_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MAX_ENDPT); + ca_cal_per_chrnk_right[chrnk1_indx][bit_indx] = right_pos_val; + } + + // Find the common endpoint for both ranks + left_pos_val = find_common_endpoint(ca_cal_per_chrnk_left[chrnk0_indx][bit_indx], ca_cal_per_chrnk_left[chrnk1_indx][bit_indx], MIN_ENDPT); + right_pos_val = find_common_endpoint(ca_cal_per_chrnk_right[chrnk0_indx][bit_indx], ca_cal_per_chrnk_right[chrnk1_indx][bit_indx], MAX_ENDPT); + } + + } + + // At this point, the left edge and the right edge of the eye for this channel and bit are defined by left_pos_val and right_pos_val + // Find the center of the eye + ca_bit_center[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + } + + // Since center for each bit may be different, find the min val + // Min val will get programmed to the sdll, while the other bits will require deskew + min_ca_bit_center = ca_bit_center[0]; + + for (bit_indx = 1; bit_indx < CA_NUM_BITS; bit_indx++) { + if (ca_bit_center[bit_indx] < min_ca_bit_center) + min_ca_bit_center = ca_bit_center[bit_indx]; + } + + // for positive sdll, clamp it to mdllcode - DELIMIT_POS_ADJ_CASDLL + if (min_ca_bit_center > (camdllcode - DELIMIT_POS_ADJ_CASDLL)) { + min_ca_bit_center = camdllcode - DELIMIT_POS_ADJ_CASDLL; + } + + // Since the min value of all bits is chosen for sdll, if the rest of the bits need more delay, compute their deskew + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + + if (ca_bit_center[bit_indx] < min_ca_bit_center) + panic("Memory CA Calibration: ca_bit_center[%d] = (%d) < min_ca_bit_center = %d\n", bit_indx, ca_bit_center[bit_indx], min_ca_bit_center); + + ca_bit_deskew[bit_indx] = ca_bit_center[bit_indx] - min_ca_bit_center; + } + + // If min < -camdllcode, then we will clamp the sdll to -mdll + // and put the remaining delay on the CK signals + if (min_ca_bit_center < (-1 * camdllcode)) { + cs_adj_val = (-1 * min_ca_bit_center) - camdllcode; + adj_ca_bit_center = (-1 * camdllcode); + } else { + cs_adj_val = 0; + adj_ca_bit_center = min_ca_bit_center; + } + + /* + * Finally, program the values + */ + + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + // Make sure deskew value programmed is not negative and is <= MAX_DESKEW_PROGRAMMED + if ((ca_bit_deskew[bit_indx] < 0) || (ca_bit_deskew[bit_indx] > MAX_DESKEW_PROGRAMMED)) + panic("Memory CA Calibration: ca_bit_deskew[%d] = %d invalid\n", bit_indx, ca_bit_deskew[bit_indx]); + } + + // Push the remainder of the delay to CK signals (if adj_CaBitCenterPoint_val_data was clamped to camdll) + amp_push_ctl_out(ch, cs_adj_val); + + // Program the SDLL with the adjusted min value + amp_push_casdll_out(ch, adj_ca_bit_center); + + // Program the CA Deskew values for each bit + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + rAMP_CADESKEW_CTRL(ch, bit_indx) = ca_bit_deskew[bit_indx]; + } + } +} + +// Loop through PerBitDeskewCode ranges for rddq until failing points for each byte (& bit) are found. +static void find_rddqcal_right_side_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal) +{ + uint32_t dq_deskew; + uint32_t all_bits_fail; + uint32_t bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t rddqcalresult; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte, bit; + + all_bits_fail = 0; + dq_deskew = 0; + + // set the rddq sdll to negative dqmdllcode + mdllcode[ch][AMP_DQ] = (rAMP_MDLLCODE(AMP_DQ, ch) & DLLVAL_BITS); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_set_rddq_sdll(ch, byte, (1 << SIGN_BIT_POS) + mdllcode[ch][AMP_DQ]); + + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + } + + rddqcalresult = 0xFFFFFFFF; + + // PerBit Deskew lines cannot be pushed beyond DQ_MAX_DESKEW_PER_BIT value + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) { + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + rAMP_RDDQDESKEW_CTRL(ch, byte, bit) = dq_deskew; + } + } + + // Call Basic run Dq Cal Commands + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult &= rAMP_DQCALRESULT(ch); + } else { + rddqcalresult &= wr_rd_pattern_result(ch, rnk, dq_deskew); + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if all bits haven't failed yet and this run shows all bits failing, we have found the failing point for this byte + if ((bits_fail_b[byte] == 0) && ((rddqcalresult & mask_b[byte]) == 0)) { + bits_fail_b[byte] = 1; + start_b[byte] = dq_deskew; + } + } + + all_bits_fail = bits_fail_b[0] & bits_fail_b[1] & bits_fail_b[2] & bits_fail_b[3]; + + if (all_bits_fail == 1) { + // If failing point has been found for all bits, find the passing point now + find_rddqcal_right_side_passing_point(ch, rnk, start_b, after_wrddqcal); + } else { + // To find right failing point, make more negative adjustment to the sdll (same as incrementing deskew) + dq_deskew = dq_deskew + COARSE_STEP_SZ; + } + + } while ((dq_deskew <= DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)); + + if ((dq_deskew > DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)) { + // print error message as Right Failing Point cannot be found + dprintf(DEBUG_INFO, "Memory Rddq cal: Right side failing point not found, max deskew limit reach for channel %d", ch); + + // Assume failure at this setting, and continue to passing point + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if all bits haven't failed yet, assign start_b for this byte to current reg setting + if (bits_fail_b[byte] == 0) + start_b[byte] = dq_deskew - COARSE_STEP_SZ; + } + + find_rddqcal_right_side_passing_point(ch, rnk, start_b, after_wrddqcal); + } + + // Reset deskew for all bits to 0 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + rAMP_RDDQDESKEW_CTRL(ch, byte, bit) = 0; +} + +// Purpose of this function is to start from right side failing point and find locations for every DQ bit +// until the start of passing window for that bit is found +// Save all this locations to compute the center of window +static void find_rddqcal_right_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + bool switch_from_dqstodq, max_tap_value_reached; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t step_incr; + uint32_t bit_indx, byte; + int32_t dqmdllcode; + int32_t saved_val; + + chrnk_indx = (ch * AMC_NUM_RANKS) + rnk; + all_bits_pass = 0; + switch_from_dqstodq = false; + max_tap_value_reached = false; + rddqcalresult = 0xFFFFFFFF; + step_incr = FINER_STEP_SZ; + dqmdllcode = mdllcode[ch][AMP_DQ]; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Moving Right to Left to find point where each bit turns from FAIL TO PASS + do { + if (switch_from_dqstodq == false) { + // continue to update per bit deskew until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) + rAMP_RDDQDESKEW_CTRL(ch, byte, bit_indx) = tap_value_b[byte]; + } + } + } else { + // adjust rddq sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (all_bits_pass_b[byte] == 0) + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(tap_value_b[byte])); + } + + // Run rddq calibration in hw + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult = rAMP_DQCALRESULT(ch); + } else { + rddqcalresult = wr_rd_pattern_result(ch, rnk, tap_value_b[0]); + } + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (switch_from_dqstodq == false) + // consider mdllcode as '0' since sdll is set to -mdllcode + saved_val = -1 * (tap_value_b[byte] + dqmdllcode); + else + saved_val = tap_value_b[byte]; + + rddq_cal_per_chrnk_right[chrnk_indx][bit_indx] = saved_val; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Right to Left Side of window (by adding less negative adjustment to mdll) + if (all_bits_pass == 0) { + // Even if one of the byte lanes arrives early to tap_value = 0. Remain here until all byte lane catch up before proceeding to pushing out dq + + // check for all bytes reaching 0 on the tap value (could be deskew or sdll) + int32_t all_bytes_tap = tap_value_b[0]; + for (byte = 1; (byte < DQ_NUM_BYTES) && (all_bytes_tap == 0); byte++) { + all_bytes_tap += tap_value_b[byte]; + } + + // if the tap_value for all bytes has reached 0 on the deskew, make the transition to SDLL + if ((all_bytes_tap == 0) && (switch_from_dqstodq == false)) { + switch_from_dqstodq = true; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = (rAMP_DQSDLLCTRL_RD(ch, byte) & DLLVAL_BITS); + tap_value_b[byte] = OFFSET_TO_INT(tap_value_b[byte]); + } + + } + + // To find right side passing point, add less negative adjustment to mdll (same as decrementing deskew) + + // For deskew taps, we just decrement by step_incr if we haven't reached 0 yet + if (switch_from_dqstodq == false) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (tap_value_b[byte] > 0) + tap_value_b[byte] -= step_incr; + } else { + // For sdll taps, increment it + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + tap_value_b[byte] += step_incr; + } + } + } + } + + // trigger for loop to end if any of the bytes reach max tap value + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] > MAX_SDLL_VAL); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + panic("Memory rddq calibration: Unable to find right side passing point, max tap value reached"); + + break; + } + } + + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +// Purpose of this function is to start push DQS out till left side failing point of Data window is found +static void find_rddqcal_left_side_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal) +{ + int32_t rddqsdll[DQ_NUM_BYTES]; + uint32_t rddqcalresult; + uint32_t all_bits_fail; + uint32_t all_bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t step_incr; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte; + bool max_tap_value_reached = false; + + all_bits_fail = 0; + rddqcalresult = 0xFFFFFFFF; + step_incr = COARSE_STEP_SZ; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + + // Get the starting values for RD DQS SDLL + rddqsdll[byte] = rAMP_DQSDLLCTRL_RD(ch, byte); + rddqsdll[byte] = OFFSET_TO_INT(rddqsdll[byte]); + } + + // To find left failing point, keep adding less negative adjustment to mdll + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // set the new sdll for this byte lane if all bits are not yet failing + if (all_bits_fail_b[byte] == 0) + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(rddqsdll[byte])); + } + + // Run rddqcal in hw + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult &= rAMP_DQCALRESULT(ch); + } else { + rddqcalresult &= wr_rd_pattern_result(ch, rnk, rddqsdll[0]); + } + + // If the result of all bits in this byte show a fail, record this as the failing point + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((all_bits_fail_b[byte] == 0) && ((rddqcalresult & mask_b[byte]) == 0)) { + all_bits_fail_b[byte] = 1; + start_b[byte] = rddqsdll[byte]; + } + + all_bits_fail &= all_bits_fail_b[byte]; + } + + // all bytes fail, call the function to find left passing point + if (all_bits_fail == 1) { + find_rddqcal_left_side_passing_point(ch, rnk, start_b, after_wrddqcal); + } else { + // if the byte has not yet failed, find the next sdll value to be set + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) { + rddqsdll[byte] += step_incr; + } + } + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // none of the previous bytes reached max_tap_value, then update the boolean + if (!max_tap_value_reached) { + max_tap_value_reached = (rddqsdll[byte] > MAX_SDLL_VAL); + + if (max_tap_value_reached) { + dprintf(DEBUG_INFO, "Memory rddq calibration: Unable to find left failing point, max tap value reached for ch %d byte %d", ch, byte); + break; + } + } + } + + if (max_tap_value_reached) { + // Continue to passing point if any of the bytes reaches max value and not all bits are failing + if (all_bits_fail == 0) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) + start_b[byte] = MAX_SDLL_VAL; + } + + find_rddqcal_left_side_passing_point(ch, rnk, start_b, after_wrddqcal); + } + } + } while ((!max_tap_value_reached) && (all_bits_fail == 0)); +} + +// Purpose of this function is to start from left side failing point and find passing locations for every DQ bit on left side of window +// Save all the locations to compute the center of window later +// To find left passing point, move to the right from the failing point, which means keep adding more negative adjustment to mdll +static void find_rddqcal_left_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + bool max_tap_value_reached = false; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t step_incr; + uint32_t bit_indx, byte; + + chrnk_indx = (ch * AMC_NUM_RANKS) + rnk; + all_bits_pass = 0; + rddqcalresult = 0xFFFFFFFF; + step_incr = FINER_STEP_SZ; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Finding Left side passing point on per bit level. Moving Left to Right (keep adding more negative adj to mdll) to find point where it turns from FAIL TO PASS + do { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if we haven't found all bits passing for this byte, push out new sdll value + if (all_bits_pass_b[byte] == 0) + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(tap_value_b[byte])); + } + + // Run rddqcal in hw + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult = rAMP_DQCALRESULT(ch); + } else { + rddqcalresult = wr_rd_pattern_result(ch, rnk, tap_value_b[0]); + } + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the left edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + rddq_cal_per_chrnk_left[chrnk_indx][bit_indx] = tap_value_b[byte]; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window (by adding more negative adjustment to mdll) + if (all_bits_pass == 0) { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + // if this byte lane does not have all passing bits, adjust this byte's sdll + if (all_bits_pass_b[byte] == 0) { + tap_value_b[byte] -= step_incr; + } + } + } + + // check for end of loop condition + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] < (-1 * MAX_SDLL_VAL)); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + panic("Memory rddq calibration: Unable to find left passing point, max tap value reached"); + break; + } + + // panic if we get beyond -dqmdllcode, since we really shouldn't have to go that far + if ((all_bits_pass == 0) && (tap_value_b[byte] < (-1 * mdllcode[ch][AMP_DQ]))) + panic("Memory rddq calibration: Not yet found left passing point but SDLL < -dqmdllcode for ch %d byte %d", ch, byte); + } + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +static void rddq_program_final_values(bool after_wrddqcal) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx, chrnk1_indx; + int32_t rddq_bit_center[DQ_TOTAL_BITS]; + int32_t rddq_bit_deskew[DQ_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t max_rddq_center[DQ_NUM_BYTES]; + int32_t dqmdllcode; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + dqmdllcode = mdllcode[ch][AMP_DQ]; + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + chrnk0_indx = (ch * AMC_NUM_RANKS) + 0; + left_pos_val = rddq_cal_per_chrnk_left[chrnk0_indx][bit_indx]; + right_pos_val = rddq_cal_per_chrnk_right[chrnk0_indx][bit_indx]; + + if (AMC_NUM_RANKS > 1) { + + chrnk1_indx = (ch * AMC_NUM_RANKS) + 1; + + // find the endpoint that covers both ranks + left_pos_val = find_common_endpoint(rddq_cal_per_chrnk_left[chrnk0_indx][bit_indx], + rddq_cal_per_chrnk_left[chrnk1_indx][bit_indx], + MIN_ENDPT); + right_pos_val = find_common_endpoint(rddq_cal_per_chrnk_right[chrnk0_indx][bit_indx], + rddq_cal_per_chrnk_right[chrnk1_indx][bit_indx], + MAX_ENDPT); + } + + // find center of the eye for this bit + rddq_bit_center[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + } + + // , Need additional shift to DQ offset + if (after_wrddqcal) { + + int8_t signed_byte_center_point[DQ_TOTAL_BITS]; + + // convert to signed bytes first as required by shift function + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) + signed_byte_center_point[bit_indx] = (int8_t) rddq_bit_center[bit_indx]; + + // call platform specific amc routine to apply apropriate shifts depending on DRAM vendor + amc_dram_shift_dq_offset(signed_byte_center_point, DQ_TOTAL_BITS); + + // convert shifted signed bytes back to signed ints + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) + rddq_bit_center[bit_indx] = (int32_t) signed_byte_center_point[bit_indx]; + } + + // initialize the max centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + max_rddq_center[byte] = rddq_bit_center[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the maximum CenterPoint per byte lane given each bit's center point + for (bit_indx=0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // if this bit's center point is greater than current max, make it the new max (we'll program this to sdll, and other values will require deskew) + if (rddq_bit_center[bit_indx] > max_rddq_center[byte]) + max_rddq_center[byte] = rddq_bit_center[bit_indx]; + } + + // if the max for each byte lane is < -dqmdllcode, clamp it to -dqmdllcode (the remainder will go on per bit deskew) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + if (max_rddq_center[byte] < (-1 * dqmdllcode)) + max_rddq_center[byte] = (-1 * dqmdllcode); + } + + // Compute the individual deskew values: any bits with center point < max for its byte lane will require deskew + // Each bit's center is guaranteed to be <= max for its byte lane + // Deskewing means adding more negative adjustment for this bit in addition to the sdll, which is clamped on the negative side to -dqmdllcode + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (rddq_bit_center[bit_indx] > max_rddq_center[byte]) + panic("Memory Rddq calibration: rddq_bit_center[%d] = %d > max_rddq_center[%d] = %d\n", bit_indx, rddq_bit_center[bit_indx], byte, max_rddq_center[byte]); + + rddq_bit_deskew[bit_indx] = max_rddq_center[byte] - rddq_bit_center[bit_indx]; + + if ((rddq_bit_deskew[bit_indx] < 0) || (rddq_bit_deskew[bit_indx] > DQ_MAX_DESKEW_PER_BIT)) + panic("Memory Rddq calibration: rddq_bit_deskew[%d] = %d invalid\n", bit_indx, rddq_bit_deskew[bit_indx]); + } + + // Program the SDLL and deskew per bit for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(max_rddq_center[byte])); + + // per bit deskew for this byte lane + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + rAMP_RDDQDESKEW_CTRL(ch, byte, bit_indx) = rddq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]; + } + } + } // for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) +} + +static uint32_t wrlvl_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val) { + + uint32_t ret_val, mdll; + + mdll = mdllcode[ch][phy_type]; + + if (val < ( (2 * mdll) - 2 )) { + ret_val = 0; + } else if (val < ( 2 * mdll )) { + ret_val = 1; + } else if (val < ( (2 * mdll) + 3 )) { + ret_val = 2; + } else { + ret_val = 3; + } + + return ret_val; +} + +static uint32_t wrlvl_encode_clk90dly(uint32_t ch, uint32_t val) { + + uint32_t ret_val, mdll; + + mdll = mdllcode[ch][AMP_DQ]; + + if (val < (mdll - 2)) { + ret_val = 0; + } else if (val < mdll) { + ret_val = 1; + } else if (val < (mdll + 3)) { + ret_val = 2; + } else { + ret_val = 3; + } + + return ret_val; +} + +static void push_wrlvl_to_0s_region(uint32_t ch, uint32_t rnk) +{ + uint32_t wrlvldata, byte; + uint32_t cawrlvlcode = 0; + bool max_tap_value_reached = false; + uint32_t wrlvlrun = 0xF; + uint32_t dqwrlvlcode[DQ_NUM_BYTES] = { 0 }; + + // Note that incrementing cawrlvl sdll has opposite effect of incrementing dqwrlvl + + do { + // If any byte lane shows that it returned a value of 1 - push ca wrlvl sdll out by 1 tap + cawrlvlcode++; + amp_set_cawrlvl_sdll(ch, cawrlvlcode, false); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte already showed a 0 during last run, push dqwrlvl sdll by 1 tap + // this is done to ensure this byte remains at 0 despite cawrlvl sdll being incremented above + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + + // Run Wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLDATA register + wrlvldata = rAMP_DQWRLVLDATA(ch); + + // check if all bits for this byte returned a 0, then this byte is done + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + if ((wrlvldata & (0xFF << (byte * DQ_NUM_BITS_PER_BYTE))) == 0) + wrlvlrun &= ~(1 << byte); + } + } + + // Exit if ca or dq wrlvl sdlls reach max tap value + if (cawrlvlcode == MAX_CAWRLVL_CODE) { + max_tap_value_reached = true; + if (wrlvlrun) + panic("Memory Wrlvl calibration: CA sdll reached max tap value, yet all bytes not all 0s"); + } else { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 0s", byte); + max_tap_value_reached = true; + break; + } + } + } + } while (wrlvlrun && !max_tap_value_reached); +} + +// Keep incrementing dqsdll until the byte shows 1s again. This counters the casdll that was incremented previously in order to show 0s +static void find_wrlvl_0to1_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte; + uint32_t wrlvlrun, wrlvldata; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = rAMP_CAWRLVLSDLLCODE(ch); + + wrlvlrun = 0xF; + wrlvldata = 0; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + dqwrlvlcode[byte] = rAMP_DQWRLVLSDLLCODE(ch, byte); + + chrnk_indx = (ch * AMC_NUM_RANKS) + rnk; + + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte is still showing a 0, increment the sdll + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + wrlvldata = rAMP_DQWRLVLDATA(ch); + + // check if all bits return a 1 for this byte, then this byte is done + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + if (((int) (wrlvldata & (0xFF << (byte * DQ_NUM_BITS_PER_BYTE)))) == (0xFF << (byte * DQ_NUM_BITS_PER_BYTE))) + wrlvlrun &= ~(1 << byte); + } + } + + // Exit if any of the byte lane's sdll reaches max + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 1s", byte); + max_tap_value_reached = true; + break; + } + } + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvl_cal_per_chrnk_rise[chrnk_indx][byte] = dqwrlvlcode[byte]; + // in the "5th byte" entry, save the cawrlvl code + wrlvl_cal_per_chrnk_rise[chrnk_indx][byte] = cawrlvlcode; +} + +// Go back towards the 0s region (that was found earlier). Note: not trying to find the next edge, just the previous edge that was found already +static void find_wrlvl_1to0_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte; + uint32_t wrlvlrun, wrlvldata; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = rAMP_CAWRLVLSDLLCODE(ch); + bool incr_cawrlvl = false; + + chrnk_indx = (ch * AMC_NUM_RANKS) + rnk; + wrlvlrun = 0xF; + + // jump ahead by SOLID_PASS_DETECT into the 1s region + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dqwrlvlcode[byte] = rAMP_DQWRLVLSDLLCODE(ch, byte); + dqwrlvlcode[byte] += (SOLID_PASS_DETECT + 1); // + 1 because code is decremented before programming the sdll + } + + do { + // Make sure dqwrlvlsdll > 0, otherwise switch to cawrlvlsdll + for (byte = 0; (byte < DQ_NUM_BYTES) && !incr_cawrlvl; byte++) { + if (dqwrlvlcode[byte] == 0) + incr_cawrlvl = true; + } + + // if we've reached 0 on any dqwrlvlsdll that were being decremented, switch to incrementing the cawrlvlsdll (same effect) + if (incr_cawrlvl) { + cawrlvlcode++; + amp_set_cawrlvl_sdll(ch, cawrlvlcode, false); + + // In order to keep bytes that have transitioned to 0 to stay there, increment dqwrlvlsdll (counters effect of incrementing cawrlvlsdll) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + } else { + // if run bit is set for this byte, push out the new sdll value after decrementing by 1 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]--; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + wrlvldata = rAMP_DQWRLVLDATA(ch); + + // check if all bits for this byte returned a 0, then this byte is done + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + if ((wrlvldata & (0xFF << (byte * DQ_NUM_BITS_PER_BYTE))) == 0) + wrlvlrun &= ~(1 << byte); + } + } + + // check if we've reached max tap value + if (incr_cawrlvl && (cawrlvlcode == MAX_CAWRLVL_CODE)) { + max_tap_value_reached = true; + if (wrlvlrun) + panic("Memory Wrlvl calibration: max tap value reached, yet all bytes not back to 0s"); + } + + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvl_cal_per_chrnk_fall[chrnk_indx][byte] = dqwrlvlcode[byte]; + + // in the "5th byte" entry, save the cawrlvl code + wrlvl_cal_per_chrnk_fall[chrnk_indx][byte] = cawrlvlcode; +} + +static void wrlvl_program_final_values(void) +{ + uint32_t ch, chrnk0_indx, chrnk1_indx; + uint32_t rank_rise_val[AMP_MAX_RANKS_PER_CHAN], rank_fall_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t edge_pos[AMP_MAX_RANKS_PER_CHAN]; + uint32_t common_edge_pos, min_edge_pos; + uint32_t byte; + uint32_t saved_val[DQ_NUM_BYTES + 1]; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + // we go upto DQ_NUM_BYTES + 1 to also take into account the cawrlvlcode that is stored in the 5th element + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // Rank 0 + chrnk0_indx = (ch * AMC_NUM_RANKS) + 0; + rank_rise_val[0] = wrlvl_cal_per_chrnk_rise[chrnk0_indx][byte]; + rank_fall_val[0] = wrlvl_cal_per_chrnk_fall[chrnk0_indx][byte]; + // average of 2 values is the edge for this rank + edge_pos[0] = (rank_rise_val[0] + rank_fall_val[0]) >> 1; + common_edge_pos = edge_pos[0]; + + // Adjust for Dual ranks + if (AMC_NUM_RANKS > 1) { + chrnk1_indx = (ch * AMC_NUM_RANKS) + 1; + rank_rise_val[1] = wrlvl_cal_per_chrnk_rise[chrnk1_indx][byte]; + rank_fall_val[1] = wrlvl_cal_per_chrnk_fall[chrnk1_indx][byte]; + edge_pos[1] = (rank_rise_val[1] + rank_fall_val[1]) >> 1; + + // common_edge_pos between both ranks is simply their average + common_edge_pos = (edge_pos[0] + edge_pos[1]) >> 1; + } + + // save the wrlvlsdll for each byte (and the ca) + saved_val[byte] = common_edge_pos; + } + + // Find the min among all bytes (and the ca) + min_edge_pos = saved_val[DQ_NUM_BYTES]; // initialize min as the cawrlvlsdll + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (saved_val[byte] < min_edge_pos) + min_edge_pos = saved_val[byte]; + + // We'll subtract the min from all 5 sdlls, including ca + // so the byte sdlls which are in opposite direction also need to be asjusted + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + saved_val[byte] -= min_edge_pos; + + // Program the values into the registers + if (byte == DQ_NUM_BYTES) { + // cawrlvl (use dlysel, which will require phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, saved_val[byte], true); + } else { + // dqwrlvl (use dlysel, which will require phyupdt and forceckelow) + amp_set_dqwrlvl_sdll(ch, byte, saved_val[byte], true); + } + } + } +} + + +// Keep pushing out WRDQS lines (controlled by WRDQM registers, oddly) until right side failing point is found +static void find_wrdqcal_right_side_failing_point(uint32_t ch, uint32_t rnk) +{ + uint32_t push_dqs_out; + uint32_t all_bits_fail; + uint32_t bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t wrdqcalresult_cumulative; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte; + uint32_t cawrlvlcode = rAMP_CAWRLVLSDLLCODE(ch); + + all_bits_fail = 0; + push_dqs_out = 0; + wrdqcalresult_cumulative = 0xFFFFFFFF; + + // set the wrdq sdll to negative dqmdllcode + mdllcode[ch][AMP_DQ] = (rAMP_MDLLCODE(AMP_DQ, ch) & DLLVAL_BITS); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_set_wrdq_sdll(ch, byte, (-1 * mdllcode[ch][AMP_DQ])); + + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + } + + do { + // NOTE: When DQS are pushed out then - cawrlvl sdll needs to be pushed out as well with equal taps + // can use dlysel (with phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, cawrlvlcode + push_dqs_out, true); + + // Keep pushing per bit DQS (controlled by DM regs, oddly) out until all bytes start to fail + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + rAMP_WRDMDESKEW_CTRL(ch, byte) = push_dqs_out; + + // Perform the WrDq calibration with PRBS patterns + wrdqcalresult_cumulative &= wr_rd_pattern_result(ch, rnk, push_dqs_out); + + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) { + // if all bits fail for this byte for the 1st time, we've found the right failing point + if ((wrdqcalresult_cumulative & mask_b[byte]) == 0) { + bits_fail_b[byte] = 1; + start_b[byte] = push_dqs_out; + } + } + + all_bits_fail &= bits_fail_b[byte]; + } + + // if all bits in all bytes fail, find the right passing point + if (all_bits_fail == 1) { + find_wrdqcal_right_side_passing_point(ch, rnk, start_b); + } else { + // increase the deskew since all bits are not yet failing + push_dqs_out += COARSE_STEP_SZ; + } + + } while ((push_dqs_out <= DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)); + + if ((push_dqs_out > DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)) { + // Right Failing Point cannot be found + dprintf(DEBUG_INFO, "Memory Wrdq calibration: Max deskew reached, but right failing point not found for ch %d", ch); + + // Assume failure point is current reg setting + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) + start_b[byte] = push_dqs_out - COARSE_STEP_SZ; + } + + // conitnue to passing point + find_wrdqcal_right_side_passing_point(ch, rnk, start_b); + } + + // Before quitting restore the cawrlvlsdll and per byte deskew back to original values. + // can use dlysel (with phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, cawrlvlcode, true); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + rAMP_WRDMDESKEW_CTRL(ch, byte) = 0; +} + +// Keep decreasing per byte deskew until right passing point is found +static void find_wrdqcal_right_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b) +{ + uint32_t chrnk_indx; + bool switch_from_dqstodq, max_tap_value_reached; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t wrdqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t step_incr; + uint32_t bit_indx, byte; + int32_t dqmdllcode, max_tap_value; + int32_t saved_val, max_value; + uint32_t cawrlvlcode = rAMP_CAWRLVLSDLLCODE(ch); + + chrnk_indx = (ch * AMC_NUM_RANKS) + rnk; + all_bits_pass = 0; + switch_from_dqstodq = false; + max_tap_value_reached = false; + step_incr = FINER_STEP_SZ; + dqmdllcode = mdllcode[ch][AMP_DQ]; + max_tap_value = dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL + DQ_MAX_DESKEW_PER_BIT; + + // initialize tap_values to max of all bytes' start values + max_value = start_b[0]; + for (byte = 1; byte < DQ_NUM_BYTES; byte++) + max_value = (start_b[byte] > max_value) ? start_b[byte] : max_value; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = max_value; + } + + // Any change in DM_DESKEW registers will require an equal change to cawrlvl sdll + do { + if (switch_from_dqstodq == false) { + // cawrlvlcode is decremented with tap_value_b each time + // can use dlysel (with phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, cawrlvlcode, true); + + // Keep pushing per bit DQS out until all bytes start to fail + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + rAMP_WRDMDESKEW_CTRL(ch, byte) = tap_value_b[byte]; + } else { + // adjust wrdq sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) + amp_set_wrdq_sdll(ch, byte, tap_value_b[byte]); + } + } + + // Send the PRBS patterns and read them back to see which bits are passing or failing + wrdqcalresult = wr_rd_pattern_result(ch, rnk, tap_value_b[0] + tap_value_b[1] + tap_value_b[2] + tap_value_b[3]); + + // Make sure that each Bit sees a transition from 0 (fail) to 1 (pass) on wrdqcalresult + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((wrdqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (switch_from_dqstodq == false) + // consider mdllcode as '0' since sdll is set to -mdllcode + saved_val = -1 * (tap_value_b[byte] + dqmdllcode); + else + saved_val = tap_value_b[byte]; + + wrdq_cal_per_chrnk_right[chrnk_indx][bit_indx] = saved_val; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Right to Left Side of window (by adding less negative adjustment to mdll) + if (all_bits_pass == 0) { + // Even if one of the byte lanes arrives early to tap_value = 0. Remain here until all byte lane catch up before proceeding to pushing out dq + + // check for all bytes reaching 0 on the tap value (could be deskew or sdll) + uint32_t all_bytes_tap = tap_value_b[0]; + for (byte = 1; (byte < DQ_NUM_BYTES) && (all_bytes_tap == 0); byte++) { + all_bytes_tap += tap_value_b[byte]; + } + + // if the tap_value for all bytes has reached 0 on the deskew, make the transition to SDLL + if ((all_bytes_tap == 0) && (switch_from_dqstodq == false)) { + switch_from_dqstodq = true; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = (rAMP_DQSDLLCTRL_WR(ch, byte) & DLLVAL_BITS); + tap_value_b[byte] = OFFSET_TO_INT(tap_value_b[byte]); + } + + } + + // To find right side passing point, add less negative adjustment to mdll (same as decrementing deskew) + + // For deskew taps, we just decrement by step_incr if we haven't reached 0 yet + // Note: All deskew taps will reach 0 at the same time since their start values are equal, and they are decremented regardless of pass or fail + if (switch_from_dqstodq == false) { + + // Also decrement cawrlvlsdllcode along with tap_value_b + if (tap_value_b[0] > 0) + cawrlvlcode -= step_incr; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (tap_value_b[byte] > 0) + tap_value_b[byte] -= step_incr; + } else { + // For sdll taps, increment + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + tap_value_b[byte] += step_incr; + } + } + } + } + + // trigger for loop to end if any of the bytes reach max tap value + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] > max_tap_value); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + panic("Memory wrdq calibration: Unable to find right side passing point for channel %d, max tap value reached. start_b[] = {0x%x 0x%x 0x%x 0x%x}", ch, start_b[0], start_b[1], start_b[2], start_b[3]); + } + } + + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +// To find left failing point, keep adding less negative adjustment to mdll +static void find_wrdqcal_left_side_failing_point(uint32_t ch, uint32_t rnk) +{ + int32_t wrdqsdll[DQ_NUM_BYTES]; + uint32_t wrdqcalresult; + uint32_t all_bits_fail; + uint32_t all_bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t step_incr; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte; + bool max_tap_value_reached = false; + int32_t dqmdllcode, max_tap_value; + + dqmdllcode = mdllcode[ch][AMP_DQ]; + max_tap_value = dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL + DQ_MAX_DESKEW_PER_BIT; + + all_bits_fail = 0; + wrdqcalresult = 0xFFFFFFFF; + step_incr = COARSE_STEP_SZ; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + + // Get the starting values for WR DQS SDLL + wrdqsdll[byte] = rAMP_DQSDLLCTRL_WR(ch, byte) & DLLVAL_BITS; + wrdqsdll[byte] = OFFSET_TO_INT(wrdqsdll[byte]); + + + // Add per-bit deskew to wrdqsdll[byte] if sdll reached mdll - DELIMIT_POS_ADJ_WRDQSDLL (otherwise, deskew should be 0) + // At this point per-bit deskew should be the same for each bit in this byte. Use bit 0's deskew value + wrdqsdll[byte] += rAMP_WRDQDESKEW_CTRL(ch, byte, 0); + } + + // Start with sdll value for which right passing point was found, then increase (less negative) until all bits fail + do { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // set the new sdll for this byte lane if all bits are not yet failing + if (all_bits_fail_b[byte] == 0) + amp_set_wrdq_sdll(ch, byte, wrdqsdll[byte]); + } + + // Send the PRBS patterns and read them back to see which bits are passing or failing + wrdqcalresult &= wr_rd_pattern_result(ch, rnk, wrdqsdll[0] + wrdqsdll[1] + wrdqsdll[2] + wrdqsdll[3]); + + // If the result of all bits in this byte show a fail, record this as the failing point + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((all_bits_fail_b[byte] == 0) && ((wrdqcalresult & mask_b[byte]) == 0)) { + all_bits_fail_b[byte] = 1; + start_b[byte] = wrdqsdll[byte]; + } + + all_bits_fail &= all_bits_fail_b[byte]; + } + + if (all_bits_fail == 1) { + find_wrdqcal_left_side_passing_point (ch, rnk, start_b); + } else { + // if the byte has not yet failed, find the next sdll value to be set + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) { + wrdqsdll[byte] += step_incr; + } + } + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // none of the previous bytes reached max_tap_value, then update the boolean + if (!max_tap_value_reached) { + max_tap_value_reached = (wrdqsdll[byte] > max_tap_value); + + if (max_tap_value_reached) { + dprintf(DEBUG_INFO, "Memory wrdq calibration: Unable to find left failing point, max tap value reached for ch %d byte %d", ch, byte); + break; + } + } + } + + if (max_tap_value_reached) { + // Continue to passing point if any of the bytes reaches max value and not all bits are failing + if (all_bits_fail == 0) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) + start_b[byte] = max_tap_value; + } + + find_wrdqcal_left_side_passing_point(ch, rnk, start_b); + } + } + } while ((!max_tap_value_reached) && (all_bits_fail == 0)); +} + +static void find_wrdqcal_left_side_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b) +{ + uint32_t chrnk_indx; + bool max_tap_value_reached = false; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t wrdqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t step_incr; + uint32_t bit_indx, byte; + int32_t dqmdllcode, max_tap_value; + + dqmdllcode = mdllcode[ch][AMP_DQ]; + max_tap_value = -1 * dqmdllcode; + + chrnk_indx = (ch * AMC_NUM_RANKS) + rnk; + all_bits_pass = 0; + wrdqcalresult = 0xFFFFFFFF; + step_incr = FINER_STEP_SZ; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Finding Left side failing point on per bit level. Moving Left to Right (keep adding more negative adj to mdll) to find point where it turns from FAIL TO PASS + do { + // adjust wrdq sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) + amp_set_wrdq_sdll(ch, byte, tap_value_b[byte]); + } + + // Send the PRBS patterns and read them back to see which bits are passing or failing + wrdqcalresult = wr_rd_pattern_result(ch, rnk, tap_value_b[0] + tap_value_b[1] + tap_value_b[2] + tap_value_b[3]); + + // Make sure that each Bit sees a transition from 0 (fail) to 1 (pass) on wrdqcalresult + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((wrdqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + wrdq_cal_per_chrnk_left[chrnk_indx][bit_indx] = tap_value_b[byte]; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window (by adding more negative adjustment to mdll) + if (all_bits_pass == 0) { + // For sdll taps, increment for neg tap_val, decrement for positive + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + tap_value_b[byte] -= step_incr; + } + } + } + + // check for end of loop condition + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] < max_tap_value); + + if (max_tap_value_reached) { + if (all_bits_pass_b[byte] == 0) + panic("Memory wrdq calibration: Unable to find left passing point, max tap value reached. start_b[] = {0x%x, 0x%x, 0x%x, 0x%x}", start_b[0], start_b[1], start_b[2], start_b[3]); + break; + } + } + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +static void wrdq_program_final_values(void) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx, chrnk1_indx; + int32_t dqmdllcode; + int32_t wrdq_bit_center[DQ_TOTAL_BITS]; + int32_t wrdq_bit_deskew[DQ_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t min_wrdq_center[DQ_NUM_BYTES]; + int32_t min_dq_deskew_code, max_dq_deskew_code; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + dqmdllcode = mdllcode[ch][AMP_DQ]; + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + chrnk0_indx = (ch * AMC_NUM_RANKS) + 0; + left_pos_val = wrdq_cal_per_chrnk_left[chrnk0_indx][bit_indx]; + right_pos_val = wrdq_cal_per_chrnk_right[chrnk0_indx][bit_indx]; + + if (AMC_NUM_RANKS > 1) { + + chrnk1_indx = (ch * AMC_NUM_RANKS) + 1; + + // find the endpoint that covers both ranks + left_pos_val = find_common_endpoint(wrdq_cal_per_chrnk_left[chrnk0_indx][bit_indx], + wrdq_cal_per_chrnk_left[chrnk1_indx][bit_indx], + MIN_ENDPT); + right_pos_val = find_common_endpoint(wrdq_cal_per_chrnk_right[chrnk0_indx][bit_indx], + wrdq_cal_per_chrnk_right[chrnk1_indx][bit_indx], + MAX_ENDPT); + } + + // find center of the eye for this bit + wrdq_bit_center[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + } + + + // , Need additional shift to DQ offset + int8_t signed_byte_center_point[DQ_TOTAL_BITS]; + + // convert to signed bytes first as required by the shift function + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) + signed_byte_center_point[bit_indx] = (int8_t) wrdq_bit_center[bit_indx]; + + // call platform specific amc routine to apply apropriate shifts depending on DRAM vendor + amc_dram_shift_dq_offset(signed_byte_center_point, DQ_TOTAL_BITS); + + // convert shifted signed bytes back to offset format + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) + wrdq_bit_center[bit_indx] = (int32_t) signed_byte_center_point[bit_indx]; + + + // initialize the min centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + min_wrdq_center[byte] = wrdq_bit_center[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the min CenterPoint per byte lane given each bit's center point + for (bit_indx=0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // if this bit's center point is less than current min, make it the new min + // if this bit's center point is less than current min, make it the new min + if (wrdq_bit_center[bit_indx] < min_wrdq_center[byte]) + min_wrdq_center[byte] = wrdq_bit_center[bit_indx]; + } + + // for positive value, clamp it to mdllcode - DELIMIT_POS_ADJ_WRDQSDLL + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (min_wrdq_center[byte] > (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL)) + min_wrdq_center[byte] = (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL); + } + + // Compute the individual deskew values: any bits with center point > min for its byte lane will require deskew + // Each bit's center is guaranteed to be >= min for its byte lane + // Deskewing means adding more positive adjustment for this bit in addition to the sdll, which is clamped on the negative side to -dqmdllcode + // and clamped on the positive side to (mdllcode - DELIMIT_POS_ADJ_WRDQSDLL) + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (wrdq_bit_center[bit_indx] < min_wrdq_center[byte]) + panic("Memory Wrdq Calibration: wrdq_bit_center[%d] = (%d) < min_wrdq_center[%d] = %d\n", bit_indx, wrdq_bit_center[bit_indx], byte, min_wrdq_center[byte]); + + wrdq_bit_deskew[bit_indx] = wrdq_bit_center[bit_indx] - min_wrdq_center[byte]; + + // Make sure deskew value programmed is not negative and is <= DQ_MAX_DESKEW_PER_BIT + if ((wrdq_bit_deskew[bit_indx] < 0) || (wrdq_bit_deskew[bit_indx] > DQ_MAX_DESKEW_PER_BIT)) + panic("Memory Wrdq Calibration: wrdq_bit_deskew[%d] = %d invalid\n", bit_indx, wrdq_bit_deskew[bit_indx]); + } + + // if the min for each byte lane is < -dqmdllcode, we'll need to adjust/clamp it to -dqmdllcode + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (min_wrdq_center[byte] < (-1 * dqmdllcode)) { + int32_t dqs_deskew = (-1 * dqmdllcode) - min_wrdq_center[byte]; + // put the remainder on DQS + rAMP_WRDMDESKEW_CTRL(ch, byte) = dqs_deskew; + min_wrdq_center[byte] = (-1 * dqmdllcode); + } + } + + // Program the SDLL and deskew per bit for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_set_wrdq_sdll(ch, byte, min_wrdq_center[byte]); + + // init the min and max deskew values for each byte to the 1st bit in the byte + min_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE)]; + max_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE)]; + // per bit deskew for this byte lane + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + rAMP_WRDQDESKEW_CTRL(ch, byte, bit_indx) = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]; + + // is this bit the new min or max? + if (wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] < min_dq_deskew_code) + min_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]; + else if (wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] > max_dq_deskew_code) + max_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]; + } + + // find midpoint of deskew registers for this byte, and program it to DM (controlled by DQS regs, oddly) + rAMP_WRDQSDESKEW_CTRL(ch, byte) = (min_dq_deskew_code + max_dq_deskew_code) >> 1; + } + } // for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) +} + +// This function writes PRBS7 patterns to dram for given channel and rank, +// and reads them back. Read back values are compared with data that was written +static uint32_t wr_rd_pattern_result(uint32_t ch, uint32_t rnk, uint32_t sdll_value) +{ + uint32_t chrnk_indx, result, result_per_wr_and_rdbk; + uint32_t pattern_indx, pattern, readback_data; + uint32_t col, word; + uint64_t mem_region, mem_addr; + uint32_t all_bits = 0xFFFFFFFF; + uint32_t consecutive_cols_per_chrnk = (DQ_CONSECUTIVE_BYTES_PER_CHRNK / DQ_BYTES_PER_COL); + + result = all_bits; + result_per_wr_and_rdbk = all_bits; + + chrnk_indx = (ch * AMC_NUM_RANKS) + rnk; + pattern_indx = sdll_value & DLLVAL_BITS; // sdll tap indexes into pattern array + + // need APB read inserted in function wr_rd_pattern_result + rAMP_RDFIFOPTRSTS(ch); + + // write the patterns to memory 4 bytes at a time + // interleaving applies every DQ_CONSECUTIVE_BYTES_PER_CHRNK bytes, so recompute the address at that point + // Note that bank and row are fixed + for (col = 0; col < DQ_NUM_PATTERNS; col += consecutive_cols_per_chrnk) { + + mem_region = amc_get_uncached_dram_virt_addr(ch, rnk, DQ_BANK, DQ_ROW, col); + + // next 16 words (or columns) are consecutively stored in a [channel,rank] combo + for (word = 0; word < consecutive_cols_per_chrnk; word++) { + + mem_addr = mem_region + (uint64_t)((word << 2)); + + // last pattern in array is dummy value, so skip it + pattern = DQ_PRBS7_PATTERNS[pattern_indx % (DQ_NUM_PATTERNS - 1)]; + pattern_indx++; + + // write the pattern + *(uint32_t *)mem_addr = pattern; + } + } + + pattern_indx = sdll_value & DLLVAL_BITS; + + // Now, read back the patterns (have to do it in a separate loop than the writes to get more robust calib values) + for (col = 0; col < DQ_NUM_PATTERNS; col += consecutive_cols_per_chrnk) { + + mem_region = amc_get_uncached_dram_virt_addr(ch, rnk, DQ_BANK, DQ_ROW, col); + + // next 16 words (or columns) are consecutively stored in a [channel,rank] combo + for (word = 0; word < consecutive_cols_per_chrnk; word++) { + + mem_addr = mem_region + (uint64_t)((word << 2)); + + // last pattern in array is dummy value, so skip it + pattern = DQ_PRBS7_PATTERNS[pattern_indx % (DQ_NUM_PATTERNS - 1)]; + pattern_indx++; + + // read the pattern + readback_data = *(uint32_t *)mem_addr; + + // records if read back value was different than written value by + // clearing bits that are different in the final result + result_per_wr_and_rdbk &= ~(readback_data ^ pattern); + } + + // result variable accumulates the results of all pattern matching results for a given sdll_value + result &= result_per_wr_and_rdbk; + } + + // failing bits are clear, passing bits are set + return result; +} + +// Save or restore ca and wrlvl registers for resume boot +// Registers must be stored/retrieved in exactly the order below +static void save_restore_ca_wrlvl_regs(uint32_t save_or_restore) +{ + uint32_t ch, bit_indx, byte; + uint32_t byte_pos = 0; + + if (save_or_restore == CALIB_SAVE) { + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + + // save the CA registers for this channel + uint8_t casdll = (uint8_t) (rAMP_CASDLLCTRL(ch) & DLLVAL_BITS); + + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + uint8_t ca_deskew = (uint8_t) (rAMP_CADESKEW_CTRL(ch, bit_indx) & DESKEW_CTRL_BITS); + uint8_t ca_offset = INT_TO_OFFSET(OFFSET_TO_INT(casdll) + OFFSET_TO_INT(ca_deskew)); + cal_pmu_bits[byte_pos++] = ca_offset; + } + + // CK, CS, and CKE share the same value + uint8_t ck_deskew = (uint8_t) (rAMP_CKDESKEW_CTRL(ch) & DESKEW_CTRL_BITS); + cal_pmu_bits[byte_pos++] = ck_deskew; + + // save the WrLvl registers for this channel (4 DQ SDLLs and 1 CA SDLL) + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // cawrlvlsdll is stored as the "5th" byte + if (byte == DQ_NUM_BYTES) + cal_pmu_bits[byte_pos++] = (uint8_t) (rAMP_CAWRLVLSDLLCODE(ch) & DLLVAL_BITS); + else + cal_pmu_bits[byte_pos++] = (uint8_t) (rAMP_DQWRLVLSDLLCODE(ch, byte) & DLLVAL_BITS); + } + } + +#if !SUB_PLATFORM_S7002 + // Save the cal_pmu_bits array to PMU nvram + if (power_store_memory_calibration((void *) cal_pmu_bits, CALIB_NUM_BYTES_TO_SAVE) == 0) + { +#if AMP_NO_PMU_PANIC + printf("Unable to save memory calibration values to PMU nvram\n"); +#else + panic("Unable to save memory calibration values to PMU nvram\n"); +#endif + } +#endif // #if !SUB_PLATFORM_S7002 + + } else { + +#if !SUB_PLATFORM_S7002 + // Retrieve cal_pmu_bits array from PMU nvram + if (power_load_memory_calibration((void *) cal_pmu_bits, CALIB_NUM_BYTES_TO_SAVE) == 0) + { +#if AMP_NO_PMU_PANIC + printf("Unable to load memory calibration values from PMU nvram\n"); +#else + panic("Unable to load memory calibration values from PMU nvram\n"); +#endif + } +#endif // #if !SUB_PLATFORM_S7002 + + save_masterdll_values(); + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + + int8_t casdll = OFFSET_TO_INT(cal_pmu_bits[byte_pos]); + int32_t ca_offset[CA_NUM_BITS]; + + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + ca_offset[bit_indx] = OFFSET_TO_INT(cal_pmu_bits[byte_pos]); + byte_pos++; + if (ca_offset[bit_indx] < casdll) + casdll = ca_offset[bit_indx]; + } + + // get the value pushed on CK, CS, CKE signals, add it to casdll + casdll -= OFFSET_TO_INT(cal_pmu_bits[byte_pos]); + byte_pos++; + uint8_t caclk = 0; + + // check if sdll < -camdllcode, then clamp to it. If sdll > camdllcode - DELIMIT_POS_ADJ_CASDLL, then also clamp it. + if (casdll < (-1 * mdllcode[ch][AMP_CA])) { + caclk = (uint8_t) ((-1 * casdll) - mdllcode[ch][AMP_CA]); + casdll = (-1 * mdllcode[ch][AMP_CA]); + } else if (casdll > (mdllcode[ch][AMP_CA] - DELIMIT_POS_ADJ_CASDLL)) { + casdll = mdllcode[ch][AMP_CA] - DELIMIT_POS_ADJ_CASDLL; + } + + // write the casdll register, and caclk into ctl signals + amp_push_casdll_out(ch, casdll); + if (caclk) + amp_push_ctl_out(ch, caclk); + + // compute deskew and write to the per bit deskew registers + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + uint8_t ca_deskew = (uint8_t) (ca_offset[bit_indx] - (casdll - caclk)); + rAMP_CADESKEW_CTRL(ch, bit_indx) = ca_deskew;; + } + + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + uint8_t wrlvlsdll = cal_pmu_bits[byte_pos++]; + + // At this point, DRAM is not in WRLVL mode so can use dlysel with forceckelow + if (byte == DQ_NUM_BYTES) + amp_set_cawrlvl_sdll(ch, wrlvlsdll, true); + else + amp_set_dqwrlvl_sdll(ch, byte, wrlvlsdll, true); + } + } + } +} + + +// Bit packing functions are not needed (enough space in PMU to be rid of this complexity) +#if 0 +// Inserts the data at given byte and bit position in the cal_pmu_bits array +// Assumes that num_bits is always <= 8 +static void cal_save_value(uint8_t data, uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos) +{ + uint32_t space_in_this_byte; + uint8_t mask; + + if (((*bit_pos) > 7) || ((*byte_pos) >= CALIB_PMU_BYTES)) + panic("Error! bit position %d > 7 or byte position %d > capacity (%d)\n", *bit_pos, *byte_pos, CALIB_PMU_BYTES); + + // how many bits left in this byte? + space_in_this_byte = 8 - (*bit_pos); + + // we'll grab as many bits from the data as there is space in this byte + if (space_in_this_byte >= num_bits) + mask = (1 << num_bits) - 1; + else + mask = (1 << space_in_this_byte) - 1; + + // Set the data value at given byte (only as many bits as space and making sure to preserve the other bits in this byte) + cal_pmu_bits[*byte_pos] |= ((data & mask) << *bit_pos); + + if (space_in_this_byte < num_bits) { + // any remainder bits get saved to the next byte + cal_pmu_bits[(*byte_pos) + 1] = (data >> space_in_this_byte); + (*byte_pos)++; + *bit_pos = num_bits - space_in_this_byte; + } else if (space_in_this_byte == num_bits) { + (*byte_pos)++; + *bit_pos = 0; + } else { + (*bit_pos) += num_bits; + } +} + +// Retrieve the data at given byte and bit position in the cal_pmu_bits array +// Assumes that num_bits is always <= 8 +static uint8_t cal_retrieve_value(uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos) +{ + uint32_t space_in_this_byte; + uint8_t mask, remainder_mask, ret_val; + + if (((*bit_pos) > 7) || ((*byte_pos) >= CALIB_PMU_BYTES)) + panic("Error! bit position %d > 7 or byte position %d > capacity (%d)\n", *bit_pos, *byte_pos, CALIB_PMU_BYTES); + + // how many bits left in this byte? + space_in_this_byte = 8 - (*bit_pos); + + // we'll grab as many bits from the array as there is space in this byte (max of num_bits) + if (space_in_this_byte >= num_bits) + mask = (1 << num_bits) - 1; + else { + mask = (1 << space_in_this_byte) - 1; + remainder_mask = (1 << (num_bits - space_in_this_byte)) - 1; + } + + // Get the data value at given byte (only as many bits as space) + ret_val = (cal_pmu_bits[*byte_pos] >> *bit_pos) & mask; + + if (space_in_this_byte < num_bits) { + // any remainder bits get loaded from the next byte + ret_val |= (cal_pmu_bits[(*byte_pos) + 1] & remainder_mask) << space_in_this_byte; + (*byte_pos)++; + *bit_pos = num_bits - space_in_this_byte; + } else if (space_in_this_byte == num_bits) { + (*byte_pos)++; + *bit_pos = 0; + } else { + (*bit_pos) += num_bits; + } + + return ret_val; +} +#endif + + +// Before starting dq calibration, saves the contents of dram region that will be written to with calibration patterns. +// After calibration is complete, restores the contents back to DRAM. +static void save_restore_memory_region(bool dqcal_start) +{ + uint32_t rnk; + volatile uintptr_t mem_addr, src, dest; + + mem_addr = SDRAM_BASE_UNCACHED; + + for (rnk = 0; rnk < AMC_NUM_RANKS; rnk++) { + mem_addr |= (rnk << DQ_ADDR_RANK_BIT); + + if (dqcal_start) { + dest = (uintptr_t) &(dqcal_saved_data[rnk][0]); + src = mem_addr; + } else { + dest = mem_addr; + src = (uintptr_t) &(dqcal_saved_data[rnk][0]); + } + + // we'll be writing (or have written) the patterns for each channel + memcpy((void *) dest, (void *) src, sizeof(DQ_PRBS7_PATTERNS) * AMC_NUM_CHANNELS); + } +} + +#if 0 +// Given an input where bit SIGN_BIT_POS represents the sign, and the rest is magnitude +// separate out the sign and magnitude and return those values to the caller +static void get_offset_sign_magnitude(uint32_t offset, uint32_t *neg_bit_set, uint32_t *tap_val) +{ + *neg_bit_set = (offset & (1 << SIGN_BIT_POS)) >> SIGN_BIT_POS; + *tap_val = offset - (*neg_bit_set << SIGN_BIT_POS); +} +#endif + +static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val) +{ + if (left_pos_val < right_pos_val) + panic("Memory calibration: find_center_of_eye: Left value (0x%x) is < right value (0x%x)", left_pos_val, right_pos_val); + + // center of 2 signed integers is simply their average + return ((left_pos_val + right_pos_val) / 2); +} + +// Select the value that would include the other value in the eye +static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t min_or_max) +{ + int32_t retVal = val0; + + // For the right endpoint, select the rightmost value on the number line (max value) + if (min_or_max == MAX_ENDPT) { + retVal = (val0 > val1) ? val0 : val1; + } + // For the left endpoint, select the leftmost value (min value) + else { + retVal = (val0 < val1) ? val0 : val1; + } + + return retVal; +} diff --git a/drivers/apple/amp/include/drivers/amp/amp_v1.h b/drivers/apple/amp/include/drivers/amp/amp_v1.h new file mode 100644 index 0000000..87c291d --- /dev/null +++ b/drivers/apple/amp/include/drivers/amp/amp_v1.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _AMP_V1_H +#define _AMP_V1_H + +#include + +/* Apple Memory Phy */ + +#define AMP_NUM_DLL (4) +#define AMP_FREQUENCY_SLOTS (4) + +#define AMP_INDEX_FOR_CHANNEL(_c) (((_c) < 2) ? (_c) : ((_c) + 4)) + +#define rAMP_AMPEN(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x000)) +#define rAMP_AMPCLK(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x004)) +#define rAMP_AMPINIT(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x008)) +#define rAMP_AMPVER(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x00C)) + +#define rAMP_IMPCODE(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x080)) +#define rAMP_IMPOVRRD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x084)) +#define rAMP_IMPAUTOCAL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x088)) +#define rAMP_IMPCALPHYUPDT(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x08C)) +#define rAMP_IMPCALCMD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x090)) +#define rAMP_DRAMSIGDLY(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x094)) +#define rAMP_DRAMSIGPH(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x098)) +#define rAMP_DQDQSDS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x09C)) +#define rAMP_NONDQDS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x0A0)) +#define rAMP_DIFFMODE_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x0A4 + ((_f) * 4))) +#define rAMP_DQFLTCTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x0B4)) + +#define rAMP_RDCAPCFG_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x100 + ((_f) * 4))) +#define rAMP_DQSPDRES(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x110)) +#define rAMP_CALDQMSK(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x114)) +#define rAMP_CALPATCFG(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x118)) +#define rAMP_GATETRNCMD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x11C)) +#define rAMP_GATETRNRESLT(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x120)) +#define rAMP_DQTRNCFG(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x124)) +#define rAMP_DQTRNCMD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x128)) +#define rAMP_DQTRNSTS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x12C)) + +#define rAMP_DLLEN(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x180)) +#define rAMP_DLLUPDTCMD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x184)) +#define rAMP_MDLLCODE(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x188)) +#define rAMP_DLLLOCKTIM(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x18C)) +#define rAMP_DLLLOCKCTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x190)) +#define rAMP_DLLUPDTINTVL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x194)) +#define rAMP_DLLUPDTCTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x198)) +#define rAMP_DLLSTS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x19C)) + +#define rAMP_DQSINDLLCODE(_c,_d) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x1A0 + ((_d) * 0x18))) +#define rAMP_DQSINDLLOVRRD(_c,_d) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x1A4 + ((_d) * 0x18))) +#define rAMP_DQSINDLLSCL_FREQ(_c,_d,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x1A8 + ((_d) * 0x18) + ((_f) * 4))) + +#define rAMP_DQOUTDLLCODE(_c,_d) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x200 + ((_d) * 0x18))) +#define rAMP_DQOUTDLLOVRRD(_c,_d) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x204 + ((_d) * 0x18))) +#define rAMP_DQOUTDLLSCL_FREQ(_c,_d,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x208 + ((_d) * 0x18) + ((_f) * 4))) + +#define rAMP_CAOUTDLLCODE(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x260)) +#define rAMP_CAOUTDLLOVRRD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x264)) +#define rAMP_CAOUTDLLSCL_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x268 + ((_f) * 4))) + +#define rAMP_CTLOUTDLLCODE(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x278)) +#define rAMP_CTLOUTDLLOVRRD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x27C)) +#define rAMP_CTLOUTDLLSCL_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x280 + ((_f) * 4))) + +#define rAMP_CAPSTDLLCODE(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x290)) +#define rAMP_CAPSTDLLOVRRD(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x294)) +#define rAMP_CAPSTDLLSCL_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x298 + ((_f) * 4))) + +#define rAMP_INTEN(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x400)) +#define rAMP_INSTS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x404)) + +struct amp_per_freq { + uint32_t scl; + uint32_t rdcapcfg; +}; + +struct amp_params { + uint32_t flags; + struct amp_per_freq freq[AMP_FREQUENCY_SLOTS]; +}; + +#define FLAG_AMP_PARAM_SUPPORT_FMCLK_OFF 0x0001 +#define FLAG_AMP_PARAM_FULLDIFFMODE 0x0002 + +#include + +#endif /* ! _AMP_V1_H */ diff --git a/drivers/apple/amp/include/drivers/amp/amp_v2.h b/drivers/apple/amp/include/drivers/amp/amp_v2.h new file mode 100644 index 0000000..f107f03 --- /dev/null +++ b/drivers/apple/amp/include/drivers/amp/amp_v2.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _AMP_V2_H +#define _AMP_V2_H + +#include + +#define AMP_FREQUENCY_SLOTS (4) + +/* _t: type, CA or DQ */ +/* _c: channel, 0 or 1 */ +#define AMP_DQ (0) +#define AMP_CA (1) + +#ifndef AMP_REG_OFFSET +# define AMP_REG_OFFSET (0) +#endif + +#define rAMP_AMPEN(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x000)) +#define rAMP_AMPCLK(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x004)) +#define rAMP_AMPINIT(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x008)) +#define rAMP_AMPVER(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x00C)) + +#define rAMP_IMPCODE(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x080)) +#define rAMP_IMPOVRRD(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x084)) +#define rAMP_IMPAUTOCAL(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x088)) +#define rAMP_IMPCALPHYUPDT(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x08C)) +#define rAMP_IMPCALCMD(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x090)) +#define rAMP_DRAMSIGDLY(_t,_c,_n) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x094 + ((_n) * 4))) +#define rAMP_NONDQDS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x098)) +#define rAMP_DQDQSDS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x0A4)) +#define rAMP_DIFFMODE_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x0A8 + ((_f) * 4))) +#define rAMP_DQFLTCTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x0B8)) + +#define rAMP_RDCAPCFG_FREQ(_t,_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x100 + ((_f) * 4))) +#define rAMP_DQSPDENALWYSON(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x110)) +#define rAMP_DQSPDRES(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x114)) +#define rAMP_RDFIFOPTRSTS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x118)) +#define rAMP_CALDQMSK(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x11C)) +#define rAMP_CALPATCFG(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x120) - ((_t)*0xC)) +#define rAMP_DQTRNCFG(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x124) - ((_t)*0xC)) +#define rAMP_DQTRNCMD(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x128) - ((_t)*0xC)) +#define rAMP_DQTRNSTS(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x12C) - ((_t)*0xC)) + +#define rAMP_DLLEN(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x180)) +#if SUB_PLATFORM_S7002 +#define rAMP_MDLLFREQBINDISABLE(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x184)) +#endif +#define rAMP_DLLUPDTCMD(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x184 + AMP_REG_OFFSET)) +#define rAMP_MDLLOVRRD(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x04) + 0x188 + AMP_REG_OFFSET)) +#define rAMP_MDLLCODE(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) - ((_t)*0x04) + 0x18C + AMP_REG_OFFSET)) +#define rAMP_DLLLOCKTIM(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x190 + AMP_REG_OFFSET)) +#define rAMP_DLLLOCKCTRL(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x194 + AMP_REG_OFFSET)) +#define rAMP_DLLUPDTINTVL(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x198 + AMP_REG_OFFSET)) +#define rAMP_DLLUPDTCTRL(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x19C + AMP_REG_OFFSET)) +#define rAMP_DLLSTS(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + 0x1A0 + AMP_REG_OFFSET)) +#define rAMP_DQSINDLLSCL_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x1B8 + ((_f) * 4) + AMP_REG_OFFSET)) +#define rAMP_CAOUTDLLSCL_FREQ(_c,_f) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x1B8 + ((_f) * 4) + AMP_REG_OFFSET)) + +#define rAMP_TESTMODE(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x180) + 0x200)) + +#define rAMP_WRDQDESKEW_CTRL(_c,_r,_d) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x400 + ((_r)*0x28) + ((_d)*4))) +#define rAMP_WRDQSDESKEW_CTRL(_c,_r) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x420 + ((_r)*0x28))) +#define rAMP_WRDMDESKEW_CTRL(_c,_b) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x424 + ((_b)*0x28))) +#define rAMP_RDDQDESKEW_CTRL(_c,_r,_d) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x4A0 + ((_r)*0x28) + ((_d)*4))) +#define rAMP_RDDQSDESKEW_CTRL(_c,_r) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x4C0 + ((_r)*0x28))) +#define rAMP_RDDMDESKEW_CTRL(_c,_r) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x4C4 + ((_r)*0x28))) + +#define rAMP_CADESKEW_CTRL(_c,_d) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + ((_d)*4) + 0x500)) +#define rAMP_CSDESKEW_CTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x528)) +#define rAMP_CKEDESKEW_CTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x52C)) +#define rAMP_CKDESKEW_CTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x530)) + +#define rAMP_DQSDLLCTRL_WR(_c, _b) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b)*0x08) + 0x600)) +#define rAMP_DQSDLLCTRL_RD(_c, _b) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b)*0x08) + 0x620)) +#define rAMP_DQWRLVLTIM(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x700)) +#define rAMP_DQWRLVLDLYCHAINCTRL(_c, _b) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b)*0x04) + 0x704)) +#define rAMP_DQWRLVLSDLLCODE(_c, _b) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b)*0x04) + 0x714)) +#define rAMP_DQWRLVLRUN(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x724)) +#define rAMP_DQWRLVLDATA(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x728)) + +#define rAMP_CASDLLCTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x700)) +#define rAMP_CAWRLVLSDLLCODE(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x800)) +#define rAMP_CAWRLVLCLKDLYSEL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x804)) + +#define rAMP_CACALCTRL(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x100) + 0x800)) +#define rAMP_CACALMASK(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x100) + 0x804)) +#define rAMP_CACALBYTESEL(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x100) + 0x808)) +#define rAMP_CACALBITSELMAP(_t,_c,_n) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x100) + ((_n)*0x04) + 0x80C)) +#define rAMP_CACALPAT(_t,_c, _p) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x100) + ((_p)*0x04) + 0x818)) +#define rAMP_CACALRUN(_t,_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_CA_SPACING) + ((_t)*0x100) + 0x838)) +#define rAMP_CACALRESULT(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x83C)) + +#define rAMP_DQCALCTRL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x900)) +#define rAMP_DQCALRUN(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x908)) +#define rAMP_DQCALRESULT(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x90C)) + +#define rAMP_CAPHYUPDTCRTL(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xb00)) +#define rAMP_CAPHYUPDTSTATUS(_c) (*(volatile u_int32_t *)(AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xb04)) + +// Some bit definitions +#define CACALRUN_CACALMODE (1 << 16) +#define CACALRUN_RUNCACAL (1 << 0) +#define TESTMODE_FORCECKELOW (1 << 8) + +#define SIGN_BIT_POS (6) + +#define AMP_MAX_RD (4) +#define AMP_MAX_DQ (8) +#define AMP_MAX_RANKS_PER_CHAN (2) + +struct amp_per_freq { + uint32_t caoutdllscl; + uint32_t dqsindllscl; + uint32_t rdcapcfg; +}; + +struct amp_params { + struct amp_per_freq freq[AMP_FREQUENCY_SLOTS]; + uint32_t drive_strength; + uint32_t cacalib_hw_loops; + uint32_t cacalib_sw_loops; + bool wrlvl_togglephyupdt; + uint32_t imp_auto_cal; +}; + +#include + +#endif /* _AMP_V2_H */ diff --git a/drivers/apple/amp/include/drivers/amp/amp_v2_calibration.h b/drivers/apple/amp/include/drivers/amp/amp_v2_calibration.h new file mode 100644 index 0000000..c9a739d --- /dev/null +++ b/drivers/apple/amp/include/drivers/amp/amp_v2_calibration.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AMP_V2_CALIBRATION_H +#define __AMP_V2_CALIBRATION_H + +#define AMP_MAX_PATTERNS 8 + +#define CALIB_SAVE 0 +#define CALIB_RESTORE 1 +#define CALIB_PMU_BYTES 64 +// 10 CA bit offsets (8 bits * 10), CK/CKE/CS deskew (8 bits), 5 WrLvl SDLLs (8 bits * 5) +#define CALIB_NUM_BYTES_TO_SAVE (AMC_NUM_CHANNELS * (16)) + +#define CA_NUM_BITS 10 +#define CA_ALL_BITS ((1 << CA_NUM_BITS) - 1) +#define CA_NUM_PATTERNS 64 +#define DELIMIT_POS_ADJ_CASDLL 5 +#define DELIMIT_POS_ADJ_WRDQSDLL 5 + +#define CA_MAX_SW_LOOPS CA_NUM_PATTERNS +#define CA_MAX_LOOP_CHN_RNK (CA_MAX_SW_LOOPS * AMC_NUM_CHANNELS * AMC_NUM_RANKS) + +#define MR2 0x02 +#define MR5 0x05 +#define MR41 0x29 +#define MR42 0x2A +#define MR48 0x30 + +#define MIN_ENDPT 0 +#define MAX_ENDPT 1 + +#define MAX_DESKEW_OFFSET 24 +#define MAX_DESKEW_PROGRAMMED 31 +#define MAX_SDLL_VAL 63 +#define MIN_SDLL_VAL 24 +#define FINER_STEP_SZ 1 +#define COARSE_STEP_SZ 4 +#define SOLID_PASS_DETECT 8 +#define DLLVAL_BITS 0x7F +#define DESKEW_CTRL_BITS 0x1F +#define SDLL_NUM_BITS 7 +#define DESKEW_NUM_BITS 5 + +#if SUB_PLATFORM_S7002 +#define RD_LATENCY_ENCODE 6 +#else +#define RD_LATENCY_ENCODE 26 +#endif + +// maximum possible loops in the hw +#define RDDQ_LOOPCNT 63 +#define DQ_NUM_BYTES 4 +#define DQ_NUM_BITS_PER_BYTE 8 +#define DQ_TOTAL_BITS (DQ_NUM_BYTES * DQ_NUM_BITS_PER_BYTE) +#define DQ_MAX_DESKEW_PER_BIT 24 +#define MAX_CAWRLVL_CODE 47 +#define MAX_DQWRLVL_CODE 127 +#define DQ_NUM_PATTERNS 128 +// The number of bytes below is consecutive for a given ch, rnk, bank, and row (interleaving starts after these bytes) +#define DQ_CONSECUTIVE_BYTES_PER_CHRNK 64 +#define DQ_BYTES_PER_COL 4 // That makes for 16 consecutive columns (or words) +// the bank and row numbers where patterns will be written +#define DQ_ROW 0 +#define DQ_BANK 0 +#define DQ_ADDR_RANK_BIT 16 // RIBI2 addressing for dual rank devices + +// Macros to change format between signed integer value and offset with sign and magnitude +#define INT_TO_OFFSET(val) ((((val < 0) ? 1 : 0) << SIGN_BIT_POS) | __abs(val)) +#define OFFSET_TO_INT(val) ((val & ~(1 << SIGN_BIT_POS)) * ((val & (1 << SIGN_BIT_POS)) ? -1 : 1)) + +#endif /* ! __AMP_V2_CALIBRATION_H */ diff --git a/drivers/apple/amp/rules.mk b/drivers/apple/amp/rules.mk new file mode 100644 index 0000000..dc25bc1 --- /dev/null +++ b/drivers/apple/amp/rules.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2010-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_HW_AMP=1 + +ifeq ($(AMP_FILE_VERSION),) + ALL_OBJS += $(LOCAL_DIR)/amp_v1.o +else + ALL_OBJS += $(LOCAL_DIR)/amp_v2.o +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/amp_v3/amp_v3.c b/drivers/apple/amp_v3/amp_v3.c new file mode 100644 index 0000000..d2bc737 --- /dev/null +++ b/drivers/apple/amp_v3/amp_v3.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "iboot/amp_v3_shim.h" + +/////////////////////////////////////////////////////////////////////////////// +////// Global functions +/////////////////////////////////////////////////////////////////////////////// + +void amc_phy_preinit(void) +{ + uint32_t ch; + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + CSR_WRITE(rAMP_DLLUPDTCTRL(AMP_DQ0, ch), 0x00017307); + CSR_WRITE(rAMP_DLLUPDTCTRL(AMP_DQ1, ch), 0x00017307); + CSR_WRITE(rAMP_DLLUPDTCTRL(AMP_CA, ch), 0x00017307); + } +} + +void amc_phy_init(bool resume) +{ + uint32_t ch, f; +#if !SUPPORT_FPGA + uint32_t rd, dq; +#endif + + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + CSR_WRITE(rAMP_AMPEN(AMP_CA, ch), 1); + CSR_WRITE(rAMP_AMPEN(AMP_DQ0, ch), 1); + CSR_WRITE(rAMP_AMPEN(AMP_DQ1, ch), 1); + +#if !SUPPORT_FPGA + CSR_WRITE(rAMP_DQDQSDS(AMP_DQ0, ch), amc_phy_params.dqdqsds); + CSR_WRITE(rAMP_DQDQSDS(AMP_DQ1, ch), amc_phy_params.dqdqsds); + CSR_WRITE(rAMP_NONDQDS(ch), amc_phy_params.nondqds); + + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + CSR_WRITE(rAMP_DIFFMODE_FREQ(AMP_DQ0, ch, f), 0x00000121); + CSR_WRITE(rAMP_DIFFMODE_FREQ(AMP_DQ1, ch, f), 0x00000121); + } + + for (rd = 0; rd < AMP_MAX_RD; rd++) { + for (dq = 0; dq < AMP_MAX_DQ; dq++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(AMP_DQ0, ch, rd, dq), 0x00000006); + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(AMP_DQ1, ch, rd, dq), 0x00000006); + } + } + + CSR_WRITE(rAMP_DLLLOCKTIM(AMP_CA, ch), 0x000d0013); + CSR_WRITE(rAMP_DLLLOCKTIM(AMP_DQ0, ch), 0x000d0013); + CSR_WRITE(rAMP_DLLLOCKTIM(AMP_DQ1, ch), 0x000d0013); +#endif + + for (f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + CSR_WRITE(rAMP_CAOUTDLLSCL_FREQ(ch, f), amc_phy_params.freq[f].caoutdllscl); + CSR_WRITE(rAMP_DQSINDLLSCL_FREQ(AMP_DQ0, ch, f), amc_phy_params.freq[f].dqsindllscl); + CSR_WRITE(rAMP_DQSINDLLSCL_FREQ(AMP_DQ1, ch, f), amc_phy_params.freq[f].dqsindllscl); + + CSR_WRITE(rAMP_RDCAPCFG_FREQ(AMP_DQ0, ch, f), amc_phy_params.freq[f].rdcapcfg); + CSR_WRITE(rAMP_RDCAPCFG_FREQ(AMP_DQ1, ch, f), amc_phy_params.freq[f].rdcapcfg); + + CSR_WRITE(rAMP_DQODTVREF_F(AMP_DQ0, ch, f), 0x00000080); + CSR_WRITE(rAMP_DQODTVREF_F(AMP_DQ1, ch, f), 0x00000080); + } + +#if !SUPPORT_FPGA + CSR_WRITE(rAMP_DLLUPDTCTRL(AMP_CA, ch), 0x00017507); + CSR_WRITE(rAMP_DLLUPDTCTRL(AMP_DQ0, ch), 0x00017507); + CSR_WRITE(rAMP_DLLUPDTCTRL(AMP_DQ1, ch), 0x00017507); + + CSR_WRITE(rAMP_IMPAUTOCAL(AMP_DQ0, ch), 0x00010000); + CSR_WRITE(rAMP_IMPAUTOCAL(AMP_DQ1, ch), 0x00010000); + CSR_WRITE(rAMP_IMPAUTOCAL(AMP_CA, ch), 0x00010000); + + CSR_WRITE(rAMP_DLLUPDTINTVL(AMP_CA, ch), 0x10200020); + CSR_WRITE(rAMP_DLLUPDTINTVL(AMP_DQ0, ch), 0x10200020); + CSR_WRITE(rAMP_DLLUPDTINTVL(AMP_DQ1, ch), 0x10200020); + + CSR_WRITE(rAMP_DLLEN(AMP_CA, ch), 0x00000100); + CSR_WRITE(rAMP_DLLEN(AMP_DQ0, ch), 0x00000100); + CSR_WRITE(rAMP_DLLEN(AMP_DQ1, ch), 0x00000100); + + CSR_WRITE(rAMP_DLLEN(AMP_CA, ch), 0x00000101); + CSR_WRITE(rAMP_DLLEN(AMP_DQ0, ch), 0x00000101); + CSR_WRITE(rAMP_DLLEN(AMP_DQ1, ch), 0x00000101); + + CSR_WRITE(rAMP_DLLEN(AMP_CA, ch), 0x00000100); + CSR_WRITE(rAMP_DLLEN(AMP_DQ0, ch), 0x00000100); + CSR_WRITE(rAMP_DLLEN(AMP_DQ1, ch), 0x00000100); + + amc_phy_run_dll_update(ch); + + CSR_WRITE(rAMP_IMPCALCMD(AMP_CA, ch), 0x00000101); + CSR_WRITE(rAMP_IMPCALCMD(AMP_DQ0, ch), 0x00000101); + CSR_WRITE(rAMP_IMPCALCMD(AMP_DQ1, ch), 0x00000101); + + while (CSR_READ(rAMP_IMPCALCMD(AMP_CA, ch)) & 0x1) {} + while (CSR_READ(rAMP_IMPCALCMD(AMP_DQ0, ch)) & 0x1) {} + while (CSR_READ(rAMP_IMPCALCMD(AMP_DQ1, ch)) & 0x1) {} +#endif + + CSR_WRITE(rAMP_AMPINIT(AMP_CA, ch), 0x00000001); + CSR_WRITE(rAMP_AMPINIT(AMP_DQ0, ch), 0x00000001); + CSR_WRITE(rAMP_AMPINIT(AMP_DQ1, ch), 0x00000001); + } +} + +void amc_phy_run_dll_update(uint8_t ch) +{ + CSR_WRITE(rAMP_DLLUPDTCMD(AMP_CA, ch), 0x00000001); + CSR_WRITE(rAMP_DLLUPDTCMD(AMP_DQ0, ch), 0x00000001); + CSR_WRITE(rAMP_DLLUPDTCMD(AMP_DQ1, ch), 0x00000001); + + while ((CSR_READ(rAMP_DLLUPDTCMD(AMP_CA, ch)) & 0x1)) ; + while ((CSR_READ(rAMP_DLLUPDTCMD(AMP_DQ0, ch)) & 0x1)) ; + while ((CSR_READ(rAMP_DLLUPDTCMD(AMP_DQ1, ch)) & 0x1)) ; +} + +// : workaround to avoid memory read failure when switching from boot speed (f = 3) to normal speed (f = 0) +void amc_phy_pre_normal_speed_enable() +{ + uint8_t ch, f; + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + for (f = 1; f < AMP_FREQUENCY_SLOTS; f++) { + CSR_WRITE(rAMP_CAOUTDLLSCL_FREQ(ch, f), amc_phy_params.freq[0].caoutdllscl); + CSR_WRITE(rAMP_DQSINDLLSCL_FREQ(AMP_DQ0, ch, f), amc_phy_params.freq[0].dqsindllscl); + CSR_WRITE(rAMP_DQSINDLLSCL_FREQ(AMP_DQ1, ch, f), amc_phy_params.freq[0].dqsindllscl); + } + +#if !SUPPORT_FPGA + amc_phy_run_dll_update(ch); +#endif + } +} + +void amc_phy_finalize() +{ + uint8_t ch; + for (ch = 0; ch < AMC_NUM_CHANNELS; ch++) { + CSR_WRITE(rAMP_AMPCLK(AMP_CA, ch), amc_phy_params.ampclk); + CSR_WRITE(rAMP_AMPCLK(AMP_DQ0, ch), amc_phy_params.ampclk); + CSR_WRITE(rAMP_AMPCLK(AMP_DQ1, ch), amc_phy_params.ampclk); + } +} + +void amc_phy_bypass_prep(int step) +{ +} + +void amc_phy_restore_calibration_values(bool resume) +{ +#if !SUPPORT_FPGA +#ifndef AMP_CALIBRATION_SKIP + // Restore offsets from PMU + if (resume) + calibration_save_restore_regs(CALIB_RESTORE, AMC_NUM_CHANNELS); +#endif +#endif +} + +// Perform CA, RDDQ, and WRLVL calibration +void amc_phy_calibration_ca_rddq_cal(bool resume) +{ +#ifndef AMP_CALIBRATION_SKIP + if (!resume) + calibration_ca_rddq_wrlvl(resume); +#endif +} + +void amc_phy_calibration_wrdq_cal(bool resume) +{ +#ifndef AMP_CALIBRATION_SKIP + if (!resume) + calibration_wrdq_rddq(resume); +#endif +} diff --git a/drivers/apple/amp_v3/amp_v3_calibration.c b/drivers/apple/amp_v3/amp_v3_calibration.c new file mode 100644 index 0000000..c96c658 --- /dev/null +++ b/drivers/apple/amp_v3/amp_v3_calibration.c @@ -0,0 +1,3461 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef ENV_IBOOT +#include "iboot/amp_v3_shim.h" +#elif defined ENV_DV +#include "dv/amp_v3_shim.h" +#elif defined ENV_CFE +#include "include/amp_v3_shim.h" +#else +#error "Unidentified compilation environment for shared memory calibration code" +#endif + +// PRBS7 patterns used for ca calibration. cfg_params.cacalib_sw_loops * cfg_params.cacalib_hw_loops must equal 64 +// We extend the size by 8 and repeat the first 8 values because when swloop=64, we don't go outside the array for programming CACALPAT1-7 +static const uint32_t CA_PRBS7_PATTERNS[CA_NUM_PATTERNS + 8] = { + 0x2550B, 0xCF135, 0xC4342, 0x67BFF, 0x825A0, 0x1487E, 0x984EF, 0xEA43E, + 0x0B277, 0xA388D, 0xE5E5F, 0x96DDe, 0x8CC91, 0x720D1, 0xE1649, 0xA8ACA, + 0x466E2, 0x73381, 0x1A14F, 0xFEC40, 0x93698, 0x49C83, 0xEEC28, 0x35563, + 0x692CE, 0xE4D0F, 0x6DAD8, 0xDAA1B, 0xA70AB, 0xDB94B, 0x5C7AD, 0x8DFC1, + 0x897D7, 0xB70C3, 0x7DAB0, 0x7C9E0, 0x87EE6, 0xD186C, 0x04816, 0x3E714, + 0xCAA73, 0x01350, 0xFB706, 0x5668A, 0xD507A, 0x3AF02, 0xF4D67, 0xCB923, + 0xFA456, 0xAD18C, 0x836F0, 0xEEF78, 0xCE265, 0x3F444, 0x31D75, 0x575DA, + 0x2E77C, 0x6C988, 0x21D1D, 0xF1621, 0x0E931, 0x668AF, 0x792A6, 0x42EF4, + 0x2550B, 0xCF135, 0xC4342, 0x67BFF, 0x825A0, 0x1487E, 0x984EF, 0xEA43E, +}; + +// PRBS patterns for Wrdq and Rddq (for the one after Wrdq) calibration +static const uint32_t DQ_PRBS7_PATTERNS[DQ_NUM_PATTERNS] = { + 0x85858585, 0x4a4a4a4a, 0x9a9a9a9a, 0x9e9e9e9e, 0xa1a1a1a1, 0x88888888, 0xffffffff, 0xcfcfcfcf, + 0xd0d0d0d0, 0x04040404, 0x3f3f3f3f, 0x29292929, 0x77777777, 0x30303030, 0x1f1f1f1f, 0xd4d4d4d4, + 0x3b3b3b3b, 0x16161616, 0x5e5e5e5e, 0x47474747, 0x2f2f2f2f, 0xcbcbcbcb, 0xefefefef, 0x2d2d2d2d, + 0x48484848, 0x19191919, 0x68686868, 0xe4e4e4e4, 0x24242424, 0xc2c2c2c2, 0x65656565, 0x51515151, + 0x71717171, 0x8c8c8c8c, 0xc0c0c0c0, 0xe6e6e6e6, 0xa7a7a7a7, 0x34343434, 0x20202020, 0xfdfdfdfd, + 0x4c4c4c4c, 0x26262626, 0x41414141, 0x93939393, 0x14141414, 0xdddddddd, 0xb1b1b1b1, 0x6a6a6a6a, + 0x67676767, 0xd2d2d2d2, 0x87878787, 0xc9c9c9c9, 0x6c6c6c6c, 0xdbdbdbdb, 0x0d0d0d0d, 0xb5b5b5b5, + 0x55555555, 0x4e4e4e4e, 0xa5a5a5a5, 0xb7b7b7b7, 0xd6d6d6d6, 0xb8b8b8b8, 0xe0e0e0e0, 0x1b1b1b1b, + 0xebebebeb, 0x12121212, 0x61616161, 0x6e6e6e6e, 0x58585858, 0xfbfbfbfb, 0xf0f0f0f0, 0xf9f9f9f9, + 0x73737373, 0x0f0f0f0f, 0x36363636, 0xa3a3a3a3, 0x0b0b0b0b, 0x09090909, 0x8a8a8a8a, 0x7c7c7c7c, + 0x39393939, 0x95959595, 0xa8a8a8a8, 0x02020202, 0x83838383, 0xf6f6f6f6, 0x45454545, 0xacacacac, + 0x3d3d3d3d, 0xaaaaaaaa, 0x81818181, 0x75757575, 0xb3b3b3b3, 0xe9e9e9e9, 0x91919191, 0x97979797, + 0x2b2b2b2b, 0xf4f4f4f4, 0xc6c6c6c6, 0x5a5a5a5a, 0x78787878, 0x06060606, 0xbcbcbcbc, 0xdfdfdfdf, + 0x32323232, 0x9c9c9c9c, 0x22222222, 0x7e7e7e7e, 0xbabababa, 0x63636363, 0xedededed, 0xaeaeaeae, + 0xbebebebe, 0x5c5c5c5c, 0xc4c4c4c4, 0xd9d9d9d9, 0x8e8e8e8e, 0x43434343, 0x10101010, 0xe2e2e2e2, + 0x98989898, 0x1d1d1d1d, 0x57575757, 0xcdcdcdcd, 0x53535353, 0xf2f2f2f2, 0x7a7a7a7a, 0x85858585 +}; + +/* Global configuration parameters for calibration, setup is different for iBoot, DV, SiVal, PE */ +static struct amp_calibration_params cfg_params; + +int32_t mdllcode[AMC_NUM_CHANNELS][3]; // 1 for each AMP_DQ, and 1 for AMP_CA +static uint32_t cacal_patterns_mask[CA_NUM_PATTERNS]; + +// This array will hold the calibration values to be saved for resume boot. +// Size is CALIB_PMU_BYTES, as this is the max space available in PMU for calibration, in iBoot environment +static uint8_t cal_bits[CALIB_PMU_BYTES] = { 0 }; + +/* + * Following global arrays will record passing points for calibration operations + */ + +// Used to save calibration values for each bit per channel and rank for every iteration +int32_t cacal_per_loopchrnk_right[AMC_NUM_CHANNELS * AMC_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_BITS]; +int32_t cacal_per_loopchrnk_left[AMC_NUM_CHANNELS * AMC_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_BITS]; + +// ca data aggregated over all iterations +int32_t cacal_per_chrnk_right[AMC_NUM_CHANNELS * AMC_NUM_RANKS][CA_NUM_BITS]; +int32_t cacal_per_chrnk_left[AMC_NUM_CHANNELS * AMC_NUM_RANKS][CA_NUM_BITS]; +int32_t cacal_saved_val[AMC_NUM_CHANNELS][CA_NUM_BITS + 4]; + +// wrlvl data aggregated over all iterations, we save value for 4 byte lanes + the ca value +uint32_t wrlvlcal_per_chrnk_rise[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_NUM_BYTES + 1]; +uint32_t wrlvlcal_per_chrnk_fall[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_NUM_BYTES + 1]; +uint32_t wrlvlcal_saved_val[AMC_NUM_CHANNELS][DQ_NUM_BYTES + 1]; + +// rddq data aggregated over all iterations +int32_t rddqcal_per_chrnk_right[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; +int32_t rddqcal_per_chrnk_left[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; + +// wrdq data aggregated over all iterations +int32_t wrdqcal_per_chrnk_right[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; +int32_t wrdqcal_per_chrnk_left[AMC_NUM_CHANNELS * AMC_NUM_RANKS][DQ_TOTAL_BITS]; + +// +void calibrate_ca(void); +void calibrate_rddq(bool after_wrddqcal); +void calibrate_wrlvl(void); +void calibrate_wrdq(void); +// Force initialization of cfg_params (used by DV) +void calibration_init_cfg_params(bool resume); +// save off mdll values, used by DV for individual calibration simulations +void amp_save_masterdll_values(void); + +// Static local function declarations +static void amp_program_ca_patterns(uint32_t ch, uint32_t rnk, uint32_t swloop); +static void amp_init_ca_offset_and_deskew(uint32_t ch); +static uint32_t amp_mask_ca_bits(uint32_t ch, uint32_t mr_cmd); +static void amp_push_casdll_out(uint32_t ch, int32_t offset); +static void amp_enable_cacal_mode(bool enable, uint32_t ch); +static uint32_t amp_run_cacal(uint32_t ch); +static void amp_push_ctl_out(uint32_t ch, uint32_t dly_val); +static void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk); +static void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t offset); +static void amp_run_rddqcal(uint32_t ch); +static void amp_wrlvl_init(void); +static void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset, bool set_dly_sel); +static void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset, bool set_dly_sel); +static void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun); +static void amp_set_wrdq_sdll(uint32_t ch, uint32_t byte, int32_t offset); +static void cacal_generate_patterns_mask(void); +static void cacal_run_sequence(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t mask_bits, uint32_t swloop); +static void cacal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop); +static void cacal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop); +static void cacal_enter_cacal_mode(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, bool enter); +static void cacal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop); +static void cacal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop); +static void cacal_program_final_values(void); +static void rddqcal_find_right_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal); +static void rddqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal); +static void rddqcal_find_left_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal); +static void rddqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal); +static void rddqcal_program_final_values(void); +static uint32_t dqcal_handle_swizzle(uint32_t result, bool after_wrddqcal); +static uint32_t wrlvlcal_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val); +static uint32_t wrlvlcal_encode_clk90dly(uint32_t ch, uint32_t phy_type, uint32_t val); +static void wrlvlcal_push_to_0s_region(uint32_t ch, uint32_t rnk); +static void wrlvlcal_find_0to1_transition(uint32_t ch, uint32_t rnk); +static void wrlvlcal_find_1to0_transition(uint32_t ch, uint32_t rnk); +static void wrlvlcal_program_final_values(void); +static void wrdqcal_find_right_failing_point(uint32_t ch, uint32_t rnk); +static void wrdqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b); +static void wrdqcal_find_left_failing_point(uint32_t ch, uint32_t rnk); +static void wrdqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b); +static void wrdqcal_program_final_values(void); +static uint32_t dqcal_wr_rd_pattern_result(uint32_t ch, uint32_t rnk, uint32_t sdll_value); +// Helper functions +static uint32_t map_byte_to_dq(uint32_t *byte); +static uint8_t reverse_bits_in_byte(uint8_t result); +static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val); +static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t min_or_max); +static int32_t offset_convert(int32_t offset, uint32_t direction); + +/////////////////////////////////////////////////////////////////////////////// +////// Global functions +/////////////////////////////////////////////////////////////////////////////// + +// Perform CA, RDDQ, and WRLVL calibration +void calibration_ca_rddq_wrlvl(bool resume) +{ + // Initialize calibration parameters to their default values + calibration_init_cfg_params(resume); + + if ((cfg_params.cacalib_hw_loops * cfg_params.cacalib_sw_loops) != CA_NUM_PATTERNS) + shim_panic("Memory calibration: hwloops (%d) and swloops (%d) values are unexpected\n", + cfg_params.cacalib_hw_loops, cfg_params.cacalib_sw_loops); + + // Configure AMC registers and perform other pre-ca calibration steps + shim_configure_pre_ca(); + + if (cfg_params.dbg_calib_mode & SELECT_CACAL) { + if (!resume) + calibrate_ca(); + } + + /* + * The first RdDq Cal is using MRR32 and MRR40. It's needed for WrDq calibration. Hence run before WrDq. + * The second Rd Dq calibration is PRBS pattern based, which needs Wr Dq calibration done. Hence done after WrDq. + * PRBS patterns help in reducing aliasing, hence needed for better accuracy. + */ + if (cfg_params.dbg_calib_mode & SELECT_RDDQCAL) { + calibrate_rddq(false); + } + + if (cfg_params.dbg_calib_mode & SELECT_WRLVLCAL) { + if (!resume) + calibrate_wrlvl(); + } + + shim_configure_post_wrlvl(&cfg_params); +} + +void calibration_wrdq_rddq(bool resume) +{ + shim_configure_pre_wrdq(resume); + + if (cfg_params.dbg_calib_mode & SELECT_WRDQCAL) { + calibrate_wrdq(); + } + + /* + * The first RdDq Cal is using MRR32 and MRR40. It's needed for WrDq calibration. Hence run before WrDq. + * The second Rd Dq calibration is PRBS pattern based, which needs Wr Dq calibration done. Hence done after WrDq. + * PRBS patterns help in reducing aliasing, hence needed for better accuracy. + */ + if (cfg_params.dbg_calib_mode & SELECT_RDDQCAL2) { + calibrate_rddq(true); + } + + shim_configure_post_prbs_rddq(&cfg_params); +} + +// Save or restore ca, wrlvl, rddq, and wrdq registers for resume boot +void calibration_save_restore_regs(uint32_t save_or_restore, uint32_t channels) +{ + uint32_t ch, bit_indx, byte, dq, dq_byte; + uint32_t byte_pos = 0; + + if (save_or_restore == CALIB_SAVE) { + + for (ch = 0; ch < channels; ch++) { + + // save the CA per bit offset for this channel into global array (offset = sdll + deskew) + uint8_t casdll = (uint8_t) (CSR_READ(rAMP_CASDLLCTRL(ch)) & DLLVAL_BITS); + + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + uint8_t ca_deskew = (uint8_t) (CSR_READ(rAMP_CADESKEW_CTRL(ch, bit_indx)) & DESKEW_CTRL_BITS); + // need to convert deskew into sdll scale, since offsets are saved in sdll scale + ca_deskew = offset_convert(ca_deskew, DIRECTION_DESKEW_TO_SDLL); + uint8_t ca_offset = INT_TO_OFFSET(OFFSET_TO_INT(casdll) + OFFSET_TO_INT(ca_deskew)); + cal_bits[byte_pos++] = ca_offset; + } + + // CK, CS, and CKE share the same value + uint8_t ck_deskew = (uint8_t) (CSR_READ(rAMP_CKDESKEW_CTRL(ch, 0)) & DESKEW_CTRL_BITS); + // need to convert deskew into sdll scale, since offsets are saved in sdll scale + cal_bits[byte_pos++] = offset_convert(ck_deskew, DIRECTION_DESKEW_TO_SDLL); + + // save the WrLvl registers for this channel (4 DQ SDLLs and 1 CA SDLL) + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + // cawrlvlsdll is stored as the "5th" byte + if (byte == DQ_NUM_BYTES) + cal_bits[byte_pos++] = (uint8_t) (CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS); + else + cal_bits[byte_pos++] = (uint8_t) (CSR_READ(rAMP_DQWRLVLSDLLCODE(dq, ch, dq_byte)) & DLLVAL_BITS); + } + + // save the RDDQ registers for this channel (32 per bit offset = sdll - deskew) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + uint8_t rddqsdll = (uint8_t) (CSR_READ(rAMP_DQSDLLCTRL_RD(dq, ch, dq_byte)) & DLLVAL_BITS); + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + uint8_t rddq_deskew = (uint8_t) (CSR_READ(rAMP_RDDQDESKEW_CTRL(dq, ch, dq_byte, bit_indx)) & DESKEW_CTRL_BITS); + // need to convert deskew into sdll scale, since offsets are saved in sdll scale + rddq_deskew = offset_convert(rddq_deskew, DIRECTION_DESKEW_TO_SDLL); + uint8_t rddq_offset = INT_TO_OFFSET(OFFSET_TO_INT(rddqsdll) - OFFSET_TO_INT(rddq_deskew)); + cal_bits[byte_pos++] = rddq_offset; + } + } + + // save the WRDQ registers for this channel (32 per bit offset = sdll + deskew) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + uint8_t wrdqsdll = (uint8_t) (CSR_READ(rAMP_DQSDLLCTRL_WR(dq, ch, dq_byte)) & DLLVAL_BITS); + + // if sdll is negative, dqs deskew adds to sdll. For positive sdll, dqs should be 0 + if (wrdqsdll & (1 << SIGN_BIT_POS)) { + // need to convert deskew into sdll scale, since offsets are saved in sdll scale + uint8_t dqs_deskew = (uint8_t) (CSR_READ(rAMP_WRDMDESKEW_CTRL(dq, ch, dq_byte)) & DESKEW_CTRL_BITS); + dqs_deskew = offset_convert(dqs_deskew, DIRECTION_DESKEW_TO_SDLL); + wrdqsdll += dqs_deskew; + } + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + uint8_t wrdq_deskew = (uint8_t) (CSR_READ(rAMP_WRDQDESKEW_CTRL(dq, ch, dq_byte, bit_indx)) & DESKEW_CTRL_BITS); + // need to convert deskew into sdll scale, since offsets are saved in sdll scale + wrdq_deskew = offset_convert(wrdq_deskew, DIRECTION_DESKEW_TO_SDLL); + uint8_t wrdq_offset = INT_TO_OFFSET(OFFSET_TO_INT(wrdqsdll) + OFFSET_TO_INT(wrdq_deskew)); + cal_bits[byte_pos++] = wrdq_offset; + } + } + } + + // Save the cal_bits array + shim_store_memory_calibration((void *) cal_bits, CALIB_NUM_BYTES_TO_SAVE); + } else { + // Retrieve cal_bits array + shim_load_memory_calibration((void *) cal_bits, CALIB_NUM_BYTES_TO_SAVE); + + // Initialize calibration parameters to their default values + calibration_init_cfg_params(true); + + amp_save_masterdll_values(); + + for (ch = 0; ch < channels; ch++) { + + /* + * CA + */ + + // CA bit offsets are first 10 values + int32_t casdll = OFFSET_TO_INT(cal_bits[byte_pos]); + int32_t ca_offset[CA_NUM_BITS]; + + // Find the min, assign to sdll. + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + ca_offset[bit_indx] = OFFSET_TO_INT(cal_bits[byte_pos]); + byte_pos++; + if (ca_offset[bit_indx] < casdll) + casdll = ca_offset[bit_indx]; + } + + // get the value pushed on CK, CS, CKE signals, add it to casdll + casdll -= OFFSET_TO_INT(cal_bits[byte_pos]); + byte_pos++; + uint8_t caclk = 0; + + // check if sdll < -camdllcode, then clamp to it. If sdll > camdllcode - DELIMIT_POS_ADJ_CASDLL, then also clamp it. + if (casdll < (-1 * mdllcode[ch][AMP_CA])) { + caclk = (uint8_t) ((-1 * casdll) - mdllcode[ch][AMP_CA]); + casdll = (-1 * mdllcode[ch][AMP_CA]); + } else if (casdll > (mdllcode[ch][AMP_CA] - DELIMIT_POS_ADJ_CASDLL)) { + casdll = mdllcode[ch][AMP_CA] - DELIMIT_POS_ADJ_CASDLL; + } + + // write the casdll register, and caclk into ctl signals + amp_push_casdll_out(ch, casdll); + if (caclk) + amp_push_ctl_out(ch, offset_convert(caclk, DIRECTION_SDLL_TO_DESKEW)); + + // compute deskew and write to the per bit deskew registers + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + uint8_t ca_deskew = (uint8_t) (ca_offset[bit_indx] - (casdll - caclk)); + // need to convert to deskew scale + ca_deskew = offset_convert(ca_deskew, DIRECTION_SDLL_TO_DESKEW); + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit_indx), ca_deskew); + } + + /* + * WrLvl + */ + + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + uint8_t wrlvlsdll = cal_bits[byte_pos++]; + + // At this point, DRAM is not in WRLVL mode so can use dlysel with forceckelow + if (byte == DQ_NUM_BYTES) + amp_set_cawrlvl_sdll(ch, wrlvlsdll, true); + else + amp_set_dqwrlvl_sdll(ch, byte, wrlvlsdll, true); + } + + /* + * Rddq + */ + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + // find the max offset and assign it to sdll + int32_t rddqsdll = OFFSET_TO_INT(cal_bits[byte_pos]); + int32_t rddq_offset[DQ_NUM_BITS_PER_BYTE]; + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + rddq_offset[bit_indx] = OFFSET_TO_INT(cal_bits[byte_pos]); + byte_pos++; + if (rddq_offset[bit_indx] > rddqsdll) + rddqsdll = rddq_offset[bit_indx]; + } + + // clamp sdll to -mdllcode if it is < -mdllcode + if (rddqsdll < (-1 * mdllcode[ch][dq])) + rddqsdll = (-1 * mdllcode[ch][dq]); + + // write the rddqsdll register + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(rddqsdll)); + + // compute deskew and write to the per bit deskew registers + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + uint8_t rddq_deskew = (uint8_t) (rddqsdll - rddq_offset[bit_indx]); + // need to convert to deskew scale + rddq_deskew = offset_convert(rddq_deskew, DIRECTION_SDLL_TO_DESKEW); + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(dq, ch, dq_byte, bit_indx), rddq_deskew); + } + } + + /* + * Wrdq + */ + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + // find the min offset and assign it to sdll + int32_t wrdqsdll = OFFSET_TO_INT(cal_bits[byte_pos]); + int32_t wrdq_offset[DQ_NUM_BITS_PER_BYTE]; + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + wrdq_offset[bit_indx] = OFFSET_TO_INT(cal_bits[byte_pos]); + byte_pos++; + if (wrdq_offset[bit_indx] < wrdqsdll) + wrdqsdll = wrdq_offset[bit_indx]; + } + + uint8_t wrdqs_deskew = 0; + + // clamp sdll to -mdllcode if it is < -mdllcode + if (wrdqsdll < (-1 * mdllcode[ch][dq])) { + wrdqs_deskew = (uint8_t) ((-1 * wrdqsdll) - mdllcode[ch][dq]); + wrdqsdll = (-1 * mdllcode[ch][dq]); + } else if (wrdqsdll > (mdllcode[ch][dq] - DELIMIT_POS_ADJ_WRDQSDLL)) { + // for positive sdll, clamp to mdllcode - DELIMIT_POS_ADJ_WRDQSDLL + wrdqsdll = mdllcode[ch][dq] - DELIMIT_POS_ADJ_WRDQSDLL; + } + + // set the wrdqsdll register + amp_set_wrdq_sdll(ch, byte, wrdqsdll); + if (wrdqs_deskew) + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(dq, ch, dq_byte), offset_convert(wrdqs_deskew, DIRECTION_SDLL_TO_DESKEW)); + + // compute deskew and write to the per bit deskew registers (keeping track of min and max deskews for data mask) + uint8_t min_wrdq_deskew = (uint8_t) (wrdq_offset[0] - (wrdqsdll - wrdqs_deskew)); + uint8_t max_wrdq_deskew = (uint8_t) (wrdq_offset[0] - (wrdqsdll - wrdqs_deskew)); + // need to convert to deskew scale + min_wrdq_deskew = offset_convert(min_wrdq_deskew, DIRECTION_SDLL_TO_DESKEW); + max_wrdq_deskew = offset_convert(max_wrdq_deskew, DIRECTION_SDLL_TO_DESKEW); + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + uint8_t wrdq_deskew = (uint8_t) (wrdq_offset[bit_indx] - (wrdqsdll - wrdqs_deskew)); + // need to convert to deskew scale + wrdq_deskew = offset_convert(wrdq_deskew, DIRECTION_SDLL_TO_DESKEW); + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(dq, ch, dq_byte, bit_indx), wrdq_deskew); + + if (wrdq_deskew < min_wrdq_deskew) + min_wrdq_deskew = wrdq_deskew; + if (wrdq_deskew > max_wrdq_deskew) + max_wrdq_deskew = wrdq_deskew; + } + + // put average of min and max into data mask + CSR_WRITE(rAMP_WRDQSDESKEW_CTRL(dq, ch, dq_byte), (min_wrdq_deskew + max_wrdq_deskew) >> 1); + } + } + } +} + +void calibration_dump_results(uint32_t operations, bool dump_passing_points) +{ + uint32_t ch, rnk, chrnk_indx, dq, dq_byte, bit, byte; + + shim_printf("Memory calibration results with passing points per rank in brackets:\n"); + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + shim_printf("Channel %d\n", ch); + + if (operations & SELECT_CACAL) { + + shim_printf("\tCA SDLL: %d\n", OFFSET_TO_INT(CSR_READ(rAMP_CASDLLCTRL(ch)) & DLLVAL_BITS)); + + shim_printf("\t\tPer Bit Deskew: "); + for (bit = 0; bit < CA_NUM_BITS; bit++) { + shim_printf("%d ", CSR_READ(rAMP_CADESKEW_CTRL(ch, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_points) { + + shim_printf("["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + if (rnk > 0) + shim_printf(", "); + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + + shim_printf("%d ", cacal_per_chrnk_right[chrnk_indx][bit]); + shim_printf("%d", cacal_per_chrnk_left[chrnk_indx][bit]); + } + + shim_printf("] "); + } + + } + shim_printf("\n\t\tCS, CK, CKE Deskew: %d", CSR_READ(rAMP_CKDESKEW_CTRL(ch, 0)) & DESKEW_CTRL_BITS); + + shim_printf("\n"); + } + + if (operations & SELECT_WRLVLCAL) { + + shim_printf("\tCA WrLvlSDLL: %d", CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS); + + if (dump_passing_points) { + shim_printf(" ["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + if (rnk > 0) + shim_printf(", "); + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + + shim_printf("%d ", wrlvlcal_per_chrnk_rise[chrnk_indx][DQ_NUM_BYTES]); + shim_printf("%d", wrlvlcal_per_chrnk_fall[chrnk_indx][DQ_NUM_BYTES]); + } + + shim_printf("]"); + } + + shim_printf("\n"); + + shim_printf("\tDQ WrLvlSDLL: "); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + shim_printf("%d ", CSR_READ(rAMP_DQWRLVLSDLLCODE(dq, ch, dq_byte)) & DLLVAL_BITS); + + if (dump_passing_points) { + shim_printf("["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + if (rnk > 0) + shim_printf(", "); + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + + shim_printf("%d ", wrlvlcal_per_chrnk_rise[chrnk_indx][byte]); + shim_printf("%d", wrlvlcal_per_chrnk_fall[chrnk_indx][byte]); + } + + shim_printf("] "); + } + } + + shim_printf("\n"); + } + + if ((operations & SELECT_RDDQCAL) || (operations & SELECT_RDDQCAL2)) { + + shim_printf("\tRead DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + shim_printf("\t\tByte %d SDLL: %d\n", byte, OFFSET_TO_INT(CSR_READ(rAMP_DQSDLLCTRL_RD(dq, ch, dq_byte)) & DLLVAL_BITS)); + + shim_printf("\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + shim_printf("%d ", CSR_READ(rAMP_RDDQDESKEW_CTRL(dq, ch, dq_byte, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_points) { + shim_printf("["); + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + if (rnk > 0) + shim_printf(", "); + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + + shim_printf("%d ", rddqcal_per_chrnk_right[chrnk_indx][bit + DQ_NUM_BITS_PER_BYTE * byte]); + shim_printf("%d", rddqcal_per_chrnk_left[chrnk_indx][bit + DQ_NUM_BITS_PER_BYTE * byte]); + } + shim_printf("] "); + } + } + + shim_printf("\n"); + } + } + + if (operations & SELECT_WRDQCAL) { + + shim_printf("\tWrite DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + shim_printf("\t\tByte %d SDLL: %d\n", byte, OFFSET_TO_INT(CSR_READ(rAMP_DQSDLLCTRL_WR(dq, ch, dq_byte)) & DLLVAL_BITS)); + + shim_printf("\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + shim_printf("%d ", CSR_READ(rAMP_WRDQDESKEW_CTRL(dq, ch, dq_byte, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_points) { + shim_printf(" ["); + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + if (rnk > 0) + shim_printf(", "); + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + + shim_printf("%d ", wrdqcal_per_chrnk_right[chrnk_indx][bit + DQ_NUM_BITS_PER_BYTE * byte]); + shim_printf("%d", wrdqcal_per_chrnk_left[chrnk_indx][bit + DQ_NUM_BITS_PER_BYTE * byte]); + } + shim_printf("] "); + } + } + + shim_printf("\n"); + } + } + } +} + +// +// Force initialization of cfg_params +void calibration_init_cfg_params(bool resume) +{ + // Initialize calibration parameters to their default values + cfg_params.num_channels = 2; + cfg_params.num_ranks = 1; + cfg_params.resume = resume; + cfg_params.cacalib_hw_loops = 8; + cfg_params.cacalib_sw_loops = 8; + // On Fiji B0 and Capri A0, deskew step is 22% bigger than sdll step + cfg_params.sdll_scale = 122; + cfg_params.deskew_scale = 100; + cfg_params.dv_params_valid = false; + cfg_params.dv_randomize = false; + cfg_params.dbg_calib_mode = SELECT_CAL_ALL; + + // Allow shim layer to change parameters as needed + shim_init_calibration_params(&cfg_params); +} + +#ifdef ENV_IBOOT +// To dump calibration results from iBoot menu command +static int dump_mem_calibration_info(int argc, struct cmd_arg *args) +{ + calibration_init_cfg_params(false); + calibration_dump_results(SELECT_CAL_ALL, false); + return 0; +} +MENU_COMMAND_DEBUG(memcal_info, dump_mem_calibration_info, "Prints memory calibration results", NULL); +#endif + +void calibrate_ca(void) +{ + uint32_t ch, rnk, swloop, mask_bits; + + cacal_generate_patterns_mask(); + + // Required since the dll values may change slightly during calibration + amp_save_masterdll_values(); + + // Calibration sequence is to be run for each rank in each channel, cfg_params.cacalib_sw_loops number of times + for (ch = 0; ch < cfg_params.num_channels; ch++) { + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + amp_program_ca_patterns(ch, rnk, swloop); + + amp_init_ca_offset_and_deskew(ch); + + // Training of CA Bits 0-3 and 5-8: MR41 cmd (training cmd must be sent before cacalibmode is enabled in AMP) + mask_bits = amp_mask_ca_bits(ch, MR41); + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR41, MR41 << 2); + amp_enable_cacal_mode(true, ch); + cacal_run_sequence(ch, rnk, MR41, mask_bits, swloop); + amp_enable_cacal_mode(false, ch); + + amp_init_ca_offset_and_deskew(ch); + + // Training of CA Bits 4 and 9: MR48 cmd (training cmd must be sent before cacalibmode is enabled in AMP) + mask_bits = amp_mask_ca_bits(ch, MR48); + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR48, MR48 << 2); + amp_enable_cacal_mode(true, ch); + cacal_run_sequence(ch, rnk, MR48, mask_bits, swloop); + amp_enable_cacal_mode(false, ch); + + amp_init_ca_offset_and_deskew(ch); + + // Exit CA Training mode: MR42 + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR42, MR42 << 2); + } + } + } + + // By now, we have compiled right and left edges of passing window for all CA bits over a number of iterations + // Aggregate the results, and find the center point of the window, and program it + cacal_program_final_values(); +} + +void calibrate_rddq(bool after_wrddqcal) +{ + uint32_t ch, rnk, data; + + // step7 + if (after_wrddqcal == false) { + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + amp_setup_rddq_cal(ch, rnk); + + shim_mrcmd_to_ch_rnk(MR_READ, ch, rnk, MR5, (uintptr_t)&data); + + shim_enable_rddqcal(true); + + // Find the left and right edges of the eye + rddqcal_find_right_failing_point(ch, rnk, false); + rddqcal_find_left_failing_point(ch, rnk, false); + + shim_enable_rddqcal(false); + } + } + } + // step10 + else { + for (ch = 0; ch < cfg_params.num_channels; ch++) { + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + // Find the left and right edges of the eye using PRBS patterns + // These results will be more accurate + rddqcal_find_right_failing_point(ch, rnk, true); + rddqcal_find_left_failing_point(ch, rnk, true); + } + } + } + + // Now that we have per bit left and right endpoints for each channel and rank, aggregate and program final values + rddqcal_program_final_values(); +} + +// Align the clock signal with the DQ signals +void calibrate_wrlvl(void) +{ + uint32_t ch, rnk; + uint32_t data, cawrlvlsdll; + + amp_wrlvl_init(); + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + + cawrlvlsdll = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + data = 0x80 + RD_LATENCY_ENCODE; // 0x80 is added here to set the Write Level bit (bit 7) to 1 + + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR2, data); + + // find the region where all bits return a 0 + wrlvlcal_push_to_0s_region(ch, rnk); + + // push out the clock signal until all bits return a 1 + wrlvlcal_find_0to1_transition(ch, rnk); + + // now go back towards the transition edge found earlier, but from this side of the edge + wrlvlcal_find_1to0_transition(ch, rnk); + + // reset cawrlvlsdllcode to original value (0), before sending cmd to exit wrlvl mode (MR2) + amp_set_cawrlvl_sdll(ch, cawrlvlsdll, false); + + data = RD_LATENCY_ENCODE; + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR2, data); + } + } + + // Program the final wrlvl values + wrlvlcal_program_final_values(); +} + +void calibrate_wrdq(void) +{ + uint32_t ch, rnk; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + wrdqcal_find_right_failing_point(ch, rnk); + wrdqcal_find_left_failing_point(ch, rnk); + } + } + + wrdqcal_program_final_values(); + +} + +void amp_save_masterdll_values(void) +{ + uint32_t ch; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + mdllcode[ch][AMP_DQ0] = (CSR_READ(rAMP_MDLLCODE(AMP_DQ0, ch)) & DLLVAL_BITS); + mdllcode[ch][AMP_DQ1] = (CSR_READ(rAMP_MDLLCODE(AMP_DQ1, ch)) & DLLVAL_BITS); + mdllcode[ch][AMP_CA] = (CSR_READ(rAMP_MDLLCODE(AMP_CA, ch)) & DLLVAL_BITS); + } +} + +/////////////////////////////////////////////////////////////////////////////// +////// Local functions +/////////////////////////////////////////////////////////////////////////////// + +static void amp_program_ca_patterns(uint32_t ch, uint32_t rnk, uint32_t swloop) +{ + uint32_t cacalctrl, p; + + // Map the CA bits to appropriate dq byte lanes, accounting for swizzling. + // Bytes 0 and 2 from DDR are hooked to AMPDQ0, and are bit swizzled (i.e., bit 0 from DDR connected to bit 7 on AMPDQ, and so on). + // Bytes 1 and 3 are hooked to AMPDQ1, and are NOT bit swizzled. + // For the 10 CA bits, that means CA0-3 (MR41) and CA4 (MR48) come back from DDR on AMPDQ0, + // and CA5-8 (MR41) and CA9 (MR48) on AMPDQ1. + + CSR_WRITE(rAMP_CACALCAMAP0(AMP_DQ0, ch), 0x01234567); + CSR_WRITE(rAMP_CACALCAMAP1(AMP_DQ0, ch), 0xdcba9867); + CSR_WRITE(rAMP_CACALCABYTESEL(AMP_DQ0, ch), 0); + + CSR_WRITE(rAMP_CACALCAMAP1(AMP_DQ1, ch), 0x54321010); + CSR_WRITE(rAMP_CACALCAMAP2(AMP_DQ1, ch), 0x00001076); + CSR_WRITE(rAMP_CACALCABYTESEL(AMP_DQ1, ch), 0); + + // Program rank, hardware loop count, and timing params + // Timing params are taken from lpddr3 jedec spec + cacalctrl = (rnk << 24) | ((cfg_params.cacalib_hw_loops - 1) << 16) | (16 << 8) | (10 << 0); + + CSR_WRITE(rAMP_CACALCTRL(AMP_DQ0, ch), cacalctrl); + CSR_WRITE(rAMP_CACALCTRL(AMP_DQ1, ch), cacalctrl); + CSR_WRITE(rAMP_CACALCTRL(AMP_CA, ch), cacalctrl); + + for (p = 0; p < AMP_MAX_PATTERNS; p++) { + CSR_WRITE(rAMP_CACALPAT(AMP_DQ0, ch, p), CA_PRBS7_PATTERNS[(swloop * cfg_params.cacalib_hw_loops) + p]); + CSR_WRITE(rAMP_CACALPAT(AMP_DQ1, ch, p), CA_PRBS7_PATTERNS[(swloop * cfg_params.cacalib_hw_loops) + p]); + CSR_WRITE(rAMP_CACALPAT(AMP_CA, ch, p), CA_PRBS7_PATTERNS[(swloop * cfg_params.cacalib_hw_loops) + p]); + } +} + +// (Re-)Initialize ca offset and deskew registers +static void amp_init_ca_offset_and_deskew(uint32_t ch) +{ + uint32_t d; + int32_t camdllcode = mdllcode[ch][AMP_CA]; + + // ensure negative sign is set with mdllcode value for ca offset (mdllcode guaranteed by designers not to be negative) + amp_push_casdll_out(ch, (-1 * camdllcode)); + + // Clear cadeskewctrl registers + for (d = 0; d < CA_NUM_BITS; d++) + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, d), 0); +} + +static uint32_t amp_mask_ca_bits(uint32_t ch, uint32_t mr_cmd) +{ + uint32_t mask_bits, dq0_mask, dq1_mask; + + if (mr_cmd == MR41) { + // MR41: Mask out bits 9 and 4 + mask_bits = 0x210; + + // set all bits except CA0-3 in mask register for MR41 on DQ0 + dq0_mask = 0x3F0; + + // set all bits except CA5-8 in mask register for MR41 on DQ1 + dq1_mask = 0x21F; + } else if (mr_cmd == MR48) { + // MR48: Mask out bits 0-3 and bits 5-8 + mask_bits = 0x1EF; + + // set all bits except CA4 in mask register for MR48 on DQ0 + dq0_mask = 0x3EF; + + // set all bits except CA9 in mask register for MR48 on DQ1 + dq1_mask = 0x1FF; + } else { + // No bits are masked out + mask_bits = 0; + dq0_mask = 0; + dq1_mask = 0; + } + + CSR_WRITE(rAMP_CACALMASK(AMP_DQ0, ch), dq0_mask); + CSR_WRITE(rAMP_CACALMASK(AMP_DQ1, ch), dq1_mask); + + return mask_bits; +} + +static void amp_push_casdll_out(uint32_t ch, int32_t offset) +{ + uint32_t ca_bit; + uint32_t cadeskewcode; + int32_t camdllcode = mdllcode[ch][AMP_CA]; + + if (offset > 0) { + // if offset is within DELIMIT_POS_ADJ_CASDLL steps of camdllcode, limit it to (master dll - DELIMIT_POS_ADJ_CASDLL) + if (offset >= (camdllcode - DELIMIT_POS_ADJ_CASDLL)) { + uint8_t difference = (uint8_t) (offset - (camdllcode - DELIMIT_POS_ADJ_CASDLL)); + offset = camdllcode - DELIMIT_POS_ADJ_CASDLL; + // convert sdll taps into deskew taps + difference = offset_convert(difference, DIRECTION_SDLL_TO_DESKEW); + + if (difference >= CA_MAX_DESKEW_OFFSET) + cadeskewcode = CA_MAX_DESKEW_OFFSET; + else + cadeskewcode = difference; + + // Adjust deskew registers for each ca bit + for (ca_bit = 0; ca_bit < CA_NUM_BITS; ca_bit++) + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, ca_bit), cadeskewcode); + } + } + + CSR_WRITE(rAMP_CASDLLCTRL(ch), (1 << 24) | INT_TO_OFFSET(offset)); + while (CSR_READ(rAMP_CASDLLCTRL(ch)) & (1 << 24)); +} + +static void amp_enable_cacal_mode(bool enable, uint32_t ch) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(AMP_CA, ch)); + + // Set or clear CACalMode bit + if (enable) + CSR_WRITE(rAMP_CACALRUN(AMP_CA, ch), cacalrun | CACALRUN_CACALMODE); + else + CSR_WRITE(rAMP_CACALRUN(AMP_CA, ch), cacalrun & ~CACALRUN_CACALMODE); +} + +static uint32_t amp_run_cacal(uint32_t ch) +{ + uint32_t cacalrun_dq = CSR_READ(rAMP_CACALRUN(AMP_DQ0, ch)); + uint32_t cacalrun_ca = CSR_READ(rAMP_CACALRUN(AMP_CA, ch)); + + // DQ must be set before CA + CSR_WRITE(rAMP_CACALRUN(AMP_DQ0, ch), cacalrun_dq | CACALRUN_RUNCACAL); + CSR_WRITE(rAMP_CACALRUN(AMP_DQ1, ch), cacalrun_dq | CACALRUN_RUNCACAL); + // CACalMode should already be set + CSR_WRITE(rAMP_CACALRUN(AMP_CA, ch), cacalrun_ca | CACALRUN_RUNCACAL); + // Poll on the DQ register + while(CSR_READ(rAMP_CACALRUN(AMP_DQ0, ch)) & CACALRUN_RUNCACAL); + while(CSR_READ(rAMP_CACALRUN(AMP_DQ1, ch)) & CACALRUN_RUNCACAL); + + return ((CSR_READ(rAMP_CACALRESULT(AMP_DQ0, ch)) & CA_ALL_BITS) & + (CSR_READ(rAMP_CACALRESULT(AMP_DQ1, ch)) & CA_ALL_BITS)); +} + +static void amp_push_ctl_out(uint32_t ch, uint32_t dly_val) +{ + uint32_t cadramsigdly; + + CSR_WRITE(rAMP_TESTMODE(AMP_CA, ch), TESTMODE_FORCECKELOW); + + // Fix for Radar 10790574 - Hold Violation on CKE + if (dly_val >= 0xd) + cadramsigdly = (3 << 4); + else if (dly_val >= 0xa) + cadramsigdly = (2 << 4); + else if (dly_val >= 0x8) + cadramsigdly = (1 << 4); + else + cadramsigdly = (0 << 4); + + CSR_WRITE(rAMP_DRAMSIGDLY(AMP_CA, ch, 0), cadramsigdly); + CSR_WRITE(rAMP_CSDESKEW_CTRL(ch), dly_val); + CSR_WRITE(rAMP_CKDESKEW_CTRL(ch, 0), dly_val); + CSR_WRITE(rAMP_CKDESKEW_CTRL(ch, 1), dly_val); + CSR_WRITE(rAMP_CKEDESKEW_CTRL(ch), dly_val); + + CSR_WRITE(rAMP_TESTMODE(AMP_CA, ch), 0); +} + +static void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk) +{ + // At this point the AMC's READLEVELING should already be setup as 0x00000300 + // Make DQCALCTRL.DQCalPatSel (bits 1:0) match READLEVELING.RdLvlPatOpt + CSR_WRITE(rAMP_DQCALCTRL(AMP_DQ0, ch), (rnk << 16) | (RDDQ_LOOPCNT << 8) | (3 << 0)); + CSR_WRITE(rAMP_DQCALCTRL(AMP_DQ1, ch), (rnk << 16) | (RDDQ_LOOPCNT << 8) | (3 << 0)); +} + +// This functions set the slave dll for a particular byte lane of RDDQ as specified in the offset parameter +static void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t offset) +{ + uint32_t dq = map_byte_to_dq(&byte); + + CSR_WRITE(rAMP_DQSDLLCTRL_RD(dq, ch, byte), (1 << 24) | offset); + + // Wait for Run bit to clear + while(CSR_READ(rAMP_DQSDLLCTRL_RD(dq, ch, byte)) & (1 << 24)); +} + +static void amp_run_rddqcal(uint32_t ch) +{ + CSR_WRITE(rAMP_DQCALRUN(AMP_DQ0, ch), 1); + CSR_WRITE(rAMP_DQCALRUN(AMP_DQ1, ch), 1); + while (CSR_READ(rAMP_DQCALRUN(AMP_DQ0, ch)) & 1); + while (CSR_READ(rAMP_DQCALRUN(AMP_DQ1, ch)) & 1); +} + +static void amp_wrlvl_init(void) +{ + uint32_t ch; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + // Write Leveling Timing Control Registers to program tMRD and tWLO timing params + // Taking these values from jedec_lpddr3s8_4gb_x32_1600.soma + // tWLO has a max value of 20ns for 1600 freq + // tWLMRD has a min value of 40tck for 1600 freq + + CSR_WRITE(rAMP_DQWRLVLTIM(AMP_DQ0, ch), (12 << 8) | (16 << 0)); + CSR_WRITE(rAMP_DQWRLVLTIM(AMP_DQ1, ch), (12 << 8) | (16 << 0)); + } +} + +// Must ensure that WrLvL SDLLs are stepped by 1 to their final value to avoid glitch on clock signals +static void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset, bool set_dly_sel) +{ + uint32_t cawrlvlsdll = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + int32_t step = (cawrlvlsdll < offset) ? 1 : -1; + + if (set_dly_sel) { + /* Must send phyupdt to AMC to avoid traffic while CKE is low */ + CSR_WRITE(rAMP_CAPHYUPDTREQ(ch), 1); + while((CSR_READ(rAMP_CAPHYUPDTSTATUS(ch)) & 1) == 0); + + /* CKE must be low when updating dlysel to avoid glitches */ + CSR_WRITE(rAMP_TESTMODE(AMP_CA, ch), TESTMODE_FORCECKELOW); + } + + for ( ; cawrlvlsdll != offset; cawrlvlsdll += step) { + CSR_WRITE(rAMP_CAWRLVLSDLLCODE(ch), cawrlvlsdll + step); + } + + if (set_dly_sel) { + // final value programmed into the sdllcode will be offset + CSR_WRITE(rAMP_CAWRLVLCLKDLYSEL(ch), wrlvlcal_encode_dlyval(ch, AMP_CA, offset)); + + /* Release CKE and disable phyupdt to allow normal operation */ + CSR_WRITE(rAMP_TESTMODE(AMP_CA, ch), 0); + + CSR_WRITE(rAMP_CAPHYUPDTREQ(ch), 0); + while((CSR_READ(rAMP_CAPHYUPDTSTATUS(ch)) & 1) == 1); + } +} + +// Must ensure that WrLvL SDLLs are stepped by 1 to their final value to avoid glitch on clock signals +static void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset, bool set_dly_sel) +{ + uint32_t dq_byte = byte; + uint32_t dq = map_byte_to_dq(&dq_byte); + uint32_t dqwrlvlsdll = CSR_READ(rAMP_DQWRLVLSDLLCODE(dq, ch, dq_byte)); + uint32_t dqwrlvldlychainctrl = CSR_READ(rAMP_DQWRLVLDLYCHAINCTRL(dq, ch, dq_byte)); + + int32_t step = (dqwrlvlsdll < offset) ? 1 : -1; + + if (set_dly_sel) { + /* Must send phyupdt to AMC to avoid traffic while CKE is low */ + CSR_WRITE(rAMP_CAPHYUPDTREQ(ch), 1); + while((CSR_READ(rAMP_CAPHYUPDTSTATUS(ch)) & 1) == 0); + + /* CKE must be low when updating dlysel to avoid glitches */ + CSR_WRITE(rAMP_TESTMODE(AMP_CA, ch), TESTMODE_FORCECKELOW); + } + + for ( ; dqwrlvlsdll != offset; dqwrlvlsdll += step) + CSR_WRITE(rAMP_DQWRLVLSDLLCODE(dq, ch, dq_byte), dqwrlvlsdll + step); + + if (set_dly_sel) { + // final value programmed into the sdllcode will be offset (also, preserve bits 17:16) + CSR_WRITE(rAMP_DQWRLVLDLYCHAINCTRL(dq, ch, dq_byte), (dqwrlvldlychainctrl & 0x00030000) | + wrlvlcal_encode_dlyval(ch, dq, offset)); + + /* Release CKE and disable phyupdt to allow normal operation */ + CSR_WRITE(rAMP_TESTMODE(AMP_CA, ch), 0); + + CSR_WRITE(rAMP_CAPHYUPDTREQ(ch), 0); + while((CSR_READ(rAMP_CAPHYUPDTSTATUS(ch)) & 1) == 1); + } +} + +static void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun) +{ + CSR_WRITE(rAMP_DQWRLVLRUN(AMP_DQ0, ch), wrlvlrun & 0x3); + CSR_WRITE(rAMP_DQWRLVLRUN(AMP_DQ1, ch), wrlvlrun >> 2); + while(CSR_READ(rAMP_DQWRLVLRUN(AMP_DQ0, ch))); + while(CSR_READ(rAMP_DQWRLVLRUN(AMP_DQ1, ch))); +} + +// This functions set the slave dll for a particular byte lane of WRDQ as specified in the offset parameter +static void amp_set_wrdq_sdll(uint32_t ch, uint32_t byte, int32_t offset) +{ + uint32_t dq_bit; + uint32_t dqdeskewcode; + // + uint32_t dq = map_byte_to_dq(&byte); + int32_t dqmdllcode = mdllcode[ch][dq]; + + if (offset > 0) { + // New equation given by Rakesh: if offset is within DELIMIT_POS_ADJ_WRDQSDLL steps of dqmdllcode, limit it to (master dll - DELIMIT_POS_ADJ_WRDQSDLL) + if (offset >= (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL)) { + uint8_t difference = (uint8_t) (offset - (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL)); + offset = dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL; + // convert sdll taps to deskew taps + difference = offset_convert(difference, DIRECTION_SDLL_TO_DESKEW); + + if (difference >= DQ_MAX_DESKEW_PER_BIT) + dqdeskewcode = DQ_MAX_DESKEW_PER_BIT; + else + dqdeskewcode = difference; + + // Adjust deskew registers for each dq bit + for (dq_bit = 0; dq_bit < DQ_NUM_BITS_PER_BYTE; dq_bit++) + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(dq, ch, byte, dq_bit), dqdeskewcode); + + // Also update the Data Mask (DM), controlled by the DQSDESKEW register + CSR_WRITE(rAMP_WRDQSDESKEW_CTRL(dq, ch, byte), dqdeskewcode); + } + + // set wrlvlclk90dly (bits 17:16 of wrlvldlychainctrl reg) if positive sdll value + CSR_WRITE(rAMP_DQWRLVLDLYCHAINCTRL(dq, ch, byte), (wrlvlcal_encode_clk90dly(ch, dq, offset) << 16) | + (CSR_READ(rAMP_DQWRLVLDLYCHAINCTRL(dq, ch, byte)) & 0x3)); + } + + CSR_WRITE(rAMP_DQSDLLCTRL_WR(dq, ch, byte), (1 << 24) | INT_TO_OFFSET(offset)); + + // Wait for Run bit to clear + while(CSR_READ(rAMP_DQSDLLCTRL_WR(dq, ch, byte)) & (1 << 24)); +} + +static void cacal_generate_patterns_mask(void) +{ + uint32_t index, patr, patf = 0; + uint32_t mask = 0; + + // generate the pattern to be used for each CA calibration iteration + for (index = 0; index < (cfg_params.cacalib_sw_loops * cfg_params.cacalib_hw_loops); index++) { + patr = (CA_PRBS7_PATTERNS[index]) & CA_ALL_BITS; + patf = (CA_PRBS7_PATTERNS[index]) >> CA_NUM_BITS; + mask = patr ^ patf; + cacal_patterns_mask[index] = mask; + } +} + +static void cacal_run_sequence(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t mask_bits, uint32_t swloop) +{ + uint32_t combined_mask, hwloop; + uint32_t pat_mask = 0; + + for (hwloop = 0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + pat_mask |= cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // This represents the bits that don't have a transition on any of the patterns used during the hwloop calibration + combined_mask = mask_bits | (CA_ALL_BITS - pat_mask); + + // To find the FAIL <-> PASS <-> FAIL window + cacal_find_right_failing_point(ch, rnk, mr_cmd, combined_mask, swloop); + cacal_find_left_failing_point(ch, rnk, combined_mask, swloop); +} + +// Establish the right edge of the window by finding the point where all CA bits fail +static void cacal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop) +{ + bool all_bits_fail = false; + uint32_t cacalresult = CA_ALL_BITS; + uint32_t push_ck_out = 0; + + // Increase delay to the right until all bits fail + do { + cacalresult = cacalresult & amp_run_cacal(ch); + + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = false; + push_ck_out = push_ck_out + FINER_STEP_SZ; + + amp_init_ca_offset_and_deskew(ch); + + // Make AMP and DRAM exit CaCal Mode in order to update the CK, CKE, and CS delays + cacal_enter_cacal_mode(ch, rnk, mr_cmd, false); + + // Update CK, CKE, and CS signal delays + amp_push_ctl_out(ch, push_ck_out); + + // Re-enter CaCal mode + cacal_enter_cacal_mode(ch, rnk, mr_cmd, true); + } else { + all_bits_fail = true; + + // Do a per bit calculation of when they start passing again + cacal_find_right_passing_point(ch, rnk, mr_cmd, combined_mask, swloop); + } + } while ((push_ck_out <= CA_MAX_DESKEW_OFFSET) && (all_bits_fail == false)); + + if (all_bits_fail == false) { + shim_printf("Memory CA calibration: Unable to find right side failing point for channel %d\n", ch); + + // Failing point cannot be found, continuing to passing point assuming failure at this setting + cacal_find_right_passing_point(ch, rnk, mr_cmd, combined_mask, swloop); + } + + // Reset CK delay back to 0 + if (CSR_READ(rAMP_CKDESKEW_CTRL(ch, 0))) { + // Exit CaCal Mode for AMP and DRAM before modifying CK, CKE, and CS signals + cacal_enter_cacal_mode(ch, rnk, mr_cmd, false); + + // Ok from Rakesh to set to 0 directly instead of decrementing by 1 + amp_push_ctl_out(ch, 0); + + // Re-enable CACal Mode + cacal_enter_cacal_mode(ch, rnk, mr_cmd, true); + } +} + +// Finds the passing region on the right edge of window +static void cacal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, uint32_t combined_mask, uint32_t swloop) +{ + bool switch_from_cktoca; + int32_t tap_value, max_ca_tap_val; + uint32_t cacalresult; + int32_t camdllcode, sdll_limit; + int32_t saved_val, deskew_taps; + uint32_t all_bits_pass; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + uint32_t bit_indx; + uint32_t ckdeskew; + uint32_t loopchrnk_indx; + + all_bits_pass = 0; + camdllcode = mdllcode[ch][AMP_CA]; + ckdeskew = CSR_READ(rAMP_CKDESKEW_CTRL(ch, 0)); + sdll_limit = camdllcode - DELIMIT_POS_ADJ_CASDLL; + max_ca_tap_val = sdll_limit + offset_convert(CA_MAX_DESKEW_OFFSET, DIRECTION_DESKEW_TO_SDLL); + + // For every swloop, we'll save passing values for each channel & rank + loopchrnk_indx = (swloop * cfg_params.num_channels * cfg_params.num_ranks) + (ch * cfg_params.num_ranks) + rnk; + + if (ckdeskew) { + tap_value = ckdeskew; + switch_from_cktoca = false; + } else { + // Since clock delay is already down to 0, use the slave delay. + // We only have 2 knobs to turn for delay: clock and sdll + tap_value = OFFSET_TO_INT(CSR_READ(rAMP_CASDLLCTRL(ch)) & DLLVAL_BITS); + switch_from_cktoca = true; + } + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those done + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + // Finding Right side passing point on per bit level. Moving Right to Left to find point where it turns from FAIL TO PASS + do { + if (switch_from_cktoca == false) { + // Make AMP and DRAM exit CaCal Mode in order to update the CK, CKE, and CS delays + cacal_enter_cacal_mode(ch, rnk, mr_cmd, false); + + // Update CK, CKE, and CS signal delays + amp_push_ctl_out(ch, tap_value); + + // Re-enter CaCal mode + cacal_enter_cacal_mode(ch, rnk, mr_cmd, true); + } else { + amp_push_casdll_out(ch, tap_value); + } + + // Run the ca calibration in hw + cacalresult = amp_run_cacal(ch); + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + // For bits that are not masked, need to check pass/fail + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // Bit has passed for SOLID_PASS_DETECT number of times, consider it done. + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // This is the first time this bit has passed, save this point in the array + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + if (switch_from_cktoca == false) { + // MdllCode is considered '0' in this case + // convert tap_value into sdll steps, since saved value is units of sdll + saved_val = -1 * (offset_convert(tap_value, DIRECTION_DESKEW_TO_SDLL) + camdllcode); + } else { + // saved value is in units of sdll + if (tap_value >= sdll_limit) + saved_val = sdll_limit + offset_convert(deskew_taps, DIRECTION_DESKEW_TO_SDLL); + else + saved_val = tap_value; + } + + cacal_per_loopchrnk_right[loopchrnk_indx][bit_indx] = saved_val; + } + } else { + // Bit failed to pass calibration, reset the SolidBitPass value to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // If ALL bits are not passing - keep moving ca signals from Right to Left + if (all_bits_pass == 0) { + if ((tap_value == 0) && (switch_from_cktoca == false)) { + switch_from_cktoca = true; + + tap_value = OFFSET_TO_INT(CSR_READ(rAMP_CASDLLCTRL(ch)) & DLLVAL_BITS); + } + + if (switch_from_cktoca == false) { + tap_value -= FINER_STEP_SZ; + } else { + tap_value += FINER_STEP_SZ; + + if (tap_value >= sdll_limit) + deskew_taps = tap_value - sdll_limit; + } + } + + } while ((tap_value <= max_ca_tap_val) && (all_bits_pass == 0)); + + if (all_bits_pass == 0) { + shim_panic("Memory CA calibration: Unable to find passing point for all bits on the right side"); + } +} + +static void cacal_enter_cacal_mode(uint32_t ch, uint32_t rnk, uint32_t mr_cmd, bool enter) +{ + // For entry, send MR41 command to DRAM before AMP register is changed + if (enter) { + // Re-enter CaCal Mode with MR41 always since some DRAMs don't support entering this mode with MR48 + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR41, MR41 << 2); + if (mr_cmd != MR41) + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, mr_cmd, mr_cmd << 2); + + amp_enable_cacal_mode(true, ch); + } + + // For exit, change AMP register before sending DRAM command (MR42) + else { + amp_enable_cacal_mode(false, ch); + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, rnk, MR42, MR42 << 2); + } +} + +static void cacal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop) +{ + // At this point, we've already played with all possible CK delays. At the end of cacal_find_right_failing_point routine, + // we reset the CK delays to 0. + // Loop through CaSDLLOvrVal from -MasterDLL to +Max until all failing points on the left side are found + + uint32_t all_bits_fail; + int32_t push_ca_out; + uint32_t cacalresult; + int32_t camdllcode, ca0deskewctrl; + uint32_t max_caleft_point_exceeded; + int32_t max_caleft_point_val; + int32_t casdllctrl, sdll_limit; + + all_bits_fail = 0; + cacalresult = CA_ALL_BITS; + max_caleft_point_exceeded = 0; + + camdllcode = mdllcode[ch][AMP_CA]; + sdll_limit = camdllcode - DELIMIT_POS_ADJ_CASDLL; + max_caleft_point_val = sdll_limit + offset_convert(CA_MAX_DESKEW_OFFSET, DIRECTION_DESKEW_TO_SDLL); + + casdllctrl = OFFSET_TO_INT(CSR_READ(rAMP_CASDLLCTRL(ch)) & DLLVAL_BITS); + ca0deskewctrl = CSR_READ(rAMP_CADESKEW_CTRL(ch, 0)); + // convert deskew taps to sdll taps + ca0deskewctrl = offset_convert(ca0deskewctrl, DIRECTION_DESKEW_TO_SDLL); + + // ca0deskewctrl will be non-zero only if casdll reached (camdllcode - DELIMIT_POS_ADJ_CASDLL) + push_ca_out = casdllctrl + ca0deskewctrl; + + // Increment CaSDLLOvrVal from -ve Master Code to max_caleft_point_val + do { + // Push out this new ca offset + amp_push_casdll_out(ch, push_ca_out); + + // run the calibration in hw + cacalresult = cacalresult & amp_run_cacal(ch); + + // combined mask has don't care bits (based on pattern) and masked bits (based on MR41 or MR48) that we should ignore + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = 0; + } else { + all_bits_fail = 1; + + // Now, we have found the left edge of window. Find the passing point for all bits + cacal_find_left_passing_point(ch, rnk, combined_mask, swloop); + } + + if (all_bits_fail == 0) { + if ((push_ca_out + COARSE_STEP_SZ) <= max_caleft_point_val) + push_ca_out += COARSE_STEP_SZ; + else + push_ca_out += FINER_STEP_SZ; + } + + if (push_ca_out > max_caleft_point_val) { + max_caleft_point_exceeded = 1; + } + + // Forcefully ending this loop as there are no more sdll taps left to proceed ahead + if (max_caleft_point_exceeded && (all_bits_fail == 0)) + { + shim_printf("Memory CA calibration: SDLL ran out of taps when trying to find left side failing point\n"); + + cacal_find_left_passing_point(ch, rnk, combined_mask, swloop); + all_bits_fail = 1; + } + } while ((all_bits_fail == 0) && (max_caleft_point_exceeded == 0)); +} + +static void cacal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t combined_mask, uint32_t swloop) +{ + uint32_t loopchrnk_indx; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + int32_t tap_value; + uint32_t cacalresult; + int32_t camdllcode; + int32_t ca0deskewctrl; + uint32_t all_bits_pass; + uint32_t bit_indx; + int32_t sdll_limit, deskew_taps; + + loopchrnk_indx = (swloop * cfg_params.num_channels * cfg_params.num_ranks) + (ch * cfg_params.num_ranks) + rnk; + + tap_value = OFFSET_TO_INT(CSR_READ(rAMP_CASDLLCTRL(ch)) & DLLVAL_BITS); + ca0deskewctrl = CSR_READ(rAMP_CADESKEW_CTRL(ch, 0)); + deskew_taps = ca0deskewctrl; + // convert deskew taps to sdll taps + ca0deskewctrl = offset_convert(ca0deskewctrl, DIRECTION_DESKEW_TO_SDLL); + camdllcode = mdllcode[ch][AMP_CA]; + sdll_limit = camdllcode - DELIMIT_POS_ADJ_CASDLL; + + all_bits_pass = 0; + + // ca0deskewctrl will be non-zero only if casdll reached (camdllcode - DELIMIT_POS_ADJ_CASDLL) + tap_value += ca0deskewctrl; + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those passed + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + + // Finding Left side passing point on per bit level. Move Left to Right to find point where it turns from FAIL TO PASS + do { + // Push out this new ca offset + amp_push_casdll_out(ch, tap_value); + + // Run the calibration in hw + cacalresult = amp_run_cacal(ch); + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + // check pass/fail for bits not masked + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // bit has passed SOLID_PASS_DETECT straight times, consider it done + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // first time bit has passed, record this value + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + int32_t saved_val; + + // saved value is in units of sdll steps + if (tap_value >= sdll_limit) + saved_val = sdll_limit + offset_convert(deskew_taps, DIRECTION_DESKEW_TO_SDLL); + else + saved_val = tap_value; + + cacal_per_loopchrnk_left[loopchrnk_indx][bit_indx] = saved_val; + } + } else { + // bit failed calibration, reset the SolidBitPass value back to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window + if (all_bits_pass == 0) { + tap_value -= FINER_STEP_SZ; + + if (tap_value >= sdll_limit) + deskew_taps = offset_convert(tap_value - sdll_limit, DIRECTION_SDLL_TO_DESKEW); + } + + if ((tap_value < (-1 * camdllcode)) && (all_bits_pass == 0)) { + // print error message as Left Passing Point cannot be found + all_bits_pass = 1; + shim_panic("Memory CA calibration: Unable to find passing point for all bits on the left side"); + } + } while ((tap_value > (-1 * camdllcode)) && (all_bits_pass == 0)); +} + +static void cacal_program_final_values(void) +{ + uint32_t loopchrnk0_indx, loopchrnk1_indx, chrnk0_indx, chrnk1_indx, ch; + uint32_t bit_indx; + int32_t ca_bit_center[CA_NUM_BITS]; + int32_t ca_bit_deskew[CA_NUM_BITS]; + int32_t tmp_left_pos_val, tmp_right_pos_val; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t camdllcode; + int32_t min_ca_bit_center; + int32_t adj_ca_bit_center; + uint32_t cs_adj_val; + + int32_t rank_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t swloop, hwloop; + uint32_t mask; + uint32_t comb_mask, tmp_mask; + uint32_t mask_txn_detect; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + camdllcode = mdllcode[ch][AMP_CA]; + + // Calculate the Center Points for each CA bit + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + comb_mask = 0x0; + mask_txn_detect = 0x0; + tmp_mask = 0x0; + + // Compute the aggr eye over multiple swloop and hwloop for all ranks + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + mask = 0x0; + for (hwloop=0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + mask = mask | cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // An explanation of the masks is below. Note that we only recorded result for a bit from a particular iteration if the bit had a transition. + // mask: for pattern(s) sent in this swloop, indicates if the bit had a transition + // tmp_mask: aggregates mask over all loops, including current swloop + // comb_mask: aggregates mask over all loops, upto the last iteration of the swloop. After it is used to generate mask_txn_detect, it catches upto same value as tmp_mask + // mask_txn_detect: indicates the first time a bit transitioned was in this swloop + tmp_mask = tmp_mask | mask; + mask_txn_detect = tmp_mask ^ comb_mask; + comb_mask = comb_mask | mask; + + /* + * Rank 0 + */ + + loopchrnk0_indx = (swloop * cfg_params.num_channels * cfg_params.num_ranks) + (ch * cfg_params.num_ranks) + 0; + chrnk0_indx = (ch * cfg_params.num_ranks) + 0; + + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[0] = cacal_per_loopchrnk_left[loopchrnk0_indx][bit_indx]; + tmp_left_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + left_pos_val = tmp_left_pos_val; + cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = cacal_per_chrnk_left[chrnk0_indx][bit_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } else { + // + left_pos_val = tmp_left_pos_val; + cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[0] = cacal_per_loopchrnk_right[loopchrnk0_indx][bit_indx]; + tmp_right_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cacal_per_chrnk_right[chrnk0_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MAX_ENDPT); + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else { + // + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = 0; + } + + if (cfg_params.num_ranks > 1) { + /* + * Rank 1 + */ + + if (cfg_params.num_ranks > AMP_MAX_RANKS_PER_CHAN) + shim_panic("amp_v3: cfg_params.num_ranks = %d is more than hw is capable of supporting (%d)\n", cfg_params.num_ranks, AMP_MAX_RANKS_PER_CHAN); + + loopchrnk1_indx = (swloop * cfg_params.num_channels * cfg_params.num_ranks) + (ch * cfg_params.num_ranks) + 1; + chrnk1_indx = (ch * cfg_params.num_ranks) + 1; + + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[1] = cacal_per_loopchrnk_left[loopchrnk1_indx][bit_indx]; + tmp_left_pos_val = rank_val[1]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + left_pos_val = tmp_left_pos_val; + cacal_per_chrnk_left[chrnk1_indx][bit_indx] = left_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = cacal_per_chrnk_left[chrnk1_indx][bit_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + cacal_per_chrnk_left[chrnk1_indx][bit_indx] = left_pos_val; + } else { + // + left_pos_val = tmp_left_pos_val; + cacal_per_chrnk_left[chrnk1_indx][bit_indx] = left_pos_val; + } + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[1] = cacal_per_loopchrnk_right[loopchrnk1_indx][bit_indx]; + tmp_right_pos_val = rank_val[1]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk1_indx][bit_indx] = right_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cacal_per_chrnk_right[chrnk1_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MAX_ENDPT); + cacal_per_chrnk_right[chrnk1_indx][bit_indx] = right_pos_val; + } else { + // + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk1_indx][bit_indx] = 0; + } + + // Find the common endpoint for both ranks + left_pos_val = find_common_endpoint(cacal_per_chrnk_left[chrnk0_indx][bit_indx], cacal_per_chrnk_left[chrnk1_indx][bit_indx], MIN_ENDPT); + right_pos_val = find_common_endpoint(cacal_per_chrnk_right[chrnk0_indx][bit_indx], cacal_per_chrnk_right[chrnk1_indx][bit_indx], MAX_ENDPT); + } + + } + + // At this point, the left edge and the right edge of the eye for this channel and bit are defined by left_pos_val and right_pos_val + // Find the center of the eye + ca_bit_center[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + } + + // Since center for each bit may be different, find the min val + // Min val will get programmed to the sdll, while the other bits will require deskew + min_ca_bit_center = ca_bit_center[0]; + + for (bit_indx = 1; bit_indx < CA_NUM_BITS; bit_indx++) { + if (ca_bit_center[bit_indx] < min_ca_bit_center) + min_ca_bit_center = ca_bit_center[bit_indx]; + } + + // for positive sdll, clamp it to mdllcode - DELIMIT_POS_ADJ_CASDLL + if (min_ca_bit_center > (camdllcode - DELIMIT_POS_ADJ_CASDLL)) { + min_ca_bit_center = camdllcode - DELIMIT_POS_ADJ_CASDLL; + } + + // Since the min value of all bits is chosen for sdll, if the rest of the bits need more delay, compute their deskew + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + + if (ca_bit_center[bit_indx] < min_ca_bit_center) + shim_panic("Memory CA Calibration: ca_bit_center[%d] = (%d) < min_ca_bit_center = %d\n", bit_indx, ca_bit_center[bit_indx], min_ca_bit_center); + + ca_bit_deskew[bit_indx] = ca_bit_center[bit_indx] - min_ca_bit_center; + } + + // If min < -camdllcode, then we will clamp the sdll to -mdll + // and put the remaining delay on the CK signals + if (min_ca_bit_center < (-1 * camdllcode)) { + cs_adj_val = (-1 * min_ca_bit_center) - camdllcode; + adj_ca_bit_center = (-1 * camdllcode); + } else { + cs_adj_val = 0; + adj_ca_bit_center = min_ca_bit_center; + } + + /* + * Finally, program the values + */ + + // Need to convert deskew values, which have been in the sdll scale so far, into the deskew scale + cs_adj_val = offset_convert(cs_adj_val, DIRECTION_SDLL_TO_DESKEW); + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + ca_bit_deskew[bit_indx] = offset_convert(ca_bit_deskew[bit_indx], DIRECTION_SDLL_TO_DESKEW); + // Make sure deskew value programmed is not negative and is <= CA_MAX_DESKEW_OFFSET + if ((ca_bit_deskew[bit_indx] < 0) || (ca_bit_deskew[bit_indx] > CA_MAX_DESKEW_OFFSET)) + shim_panic("Memory CA Calibration: ca_bit_deskew[%d] = %d invalid\n", bit_indx, ca_bit_deskew[bit_indx]); + } + + // Push the remainder of the delay to CK signals (if adj_CaBitCenterPoint_val_data was clamped to camdll) + amp_push_ctl_out(ch, cs_adj_val); + + // Program the SDLL with the adjusted min value + amp_push_casdll_out(ch, adj_ca_bit_center); + + // saved for data collection + cacal_saved_val[ch][CSBIT] = cs_adj_val; + cacal_saved_val[ch][CKBIT] = cs_adj_val; + cacal_saved_val[ch][CKEBIT] = cs_adj_val; + cacal_saved_val[ch][CASDLLBIT] = adj_ca_bit_center; + + // Program the CA Deskew values for each bit + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit_indx), ca_bit_deskew[bit_indx]); + cacal_saved_val[ch][bit_indx] = ca_bit_deskew[bit_indx]; + } + } +} + +// Loop through PerBitDeskewCode ranges for rddq until failing points for each byte (& bit) are found. +static void rddqcal_find_right_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal) +{ + uint32_t dq_deskew; + uint32_t all_bits_fail; + uint32_t bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t rddqcalresult, result_swiz; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte, bit;//, dqbyte; + uint32_t dq, dq_byte; + + all_bits_fail = 0; + dq_deskew = 0; + + // set the rddq sdll to negative dqmdllcode + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + amp_set_rddq_sdll(ch, byte, (1 << SIGN_BIT_POS) + mdllcode[ch][dq]); + + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + } + + rddqcalresult = 0xFFFFFFFF; + + // PerBit Deskew lines cannot be pushed beyond DQ_MAX_DESKEW_PER_BIT value + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(dq, ch, dq_byte, bit), dq_deskew); + } + } + + // Call Basic run Dq Cal Commands + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult &= ((CSR_READ(rAMP_DQCALRESULT(AMP_DQ1, ch)) << 16) | + CSR_READ(rAMP_DQCALRESULT(AMP_DQ0, ch))); + } else { + rddqcalresult &= dqcal_wr_rd_pattern_result(ch, rnk, dq_deskew); + } + + // Account for swizzled bits and bytes of the result + result_swiz = dqcal_handle_swizzle(rddqcalresult, after_wrddqcal); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if all bits haven't failed yet and this run shows all bits failing, we have found the failing point for this byte + if ((bits_fail_b[byte] == 0) && ((result_swiz & mask_b[byte]) == 0)) { + bits_fail_b[byte] = 1; + start_b[byte] = dq_deskew; + } + } + + all_bits_fail = bits_fail_b[0] & bits_fail_b[1] & bits_fail_b[2] & bits_fail_b[3]; + + if (all_bits_fail == 1) { + // If failing point has been found for all bits, find the passing point now + rddqcal_find_right_passing_point(ch, rnk, start_b, after_wrddqcal); + } else { + // To find right failing point, make more negative adjustment to the sdll (same as incrementing deskew) + if ((dq_deskew + COARSE_STEP_SZ) <= DQ_MAX_DESKEW_PER_BIT) + dq_deskew += COARSE_STEP_SZ; + else + dq_deskew += FINER_STEP_SZ; + } + + } while ((dq_deskew <= DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)); + + if ((dq_deskew > DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)) { + // print error message as Right Failing Point cannot be found + shim_printf("Memory Rddq cal: Right side failing point not found, max deskew limit reach for channel %d\n", ch); + + // Assume failure at this setting, and continue to passing point + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if all bits haven't failed yet, assign start_b for this byte to current reg setting + if (bits_fail_b[byte] == 0) + start_b[byte] = DQ_MAX_DESKEW_PER_BIT; + } + + rddqcal_find_right_passing_point(ch, rnk, start_b, after_wrddqcal); + } + + // Reset deskew for all bits to 0 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(dq, ch, dq_byte, bit), 0); + } +} + +// Purpose of this function is to start from right side failing point and find locations for every DQ bit +// until the start of passing window for that bit is found +// Save all this locations to compute the center of window +static void rddqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + bool switch_from_dqstodq, max_tap_value_reached; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + int32_t dqmdllcode; + int32_t saved_val; + uint32_t dq, dq_byte; + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + all_bits_pass = 0; + switch_from_dqstodq = false; + max_tap_value_reached = false; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Moving Right to Left to find point where each bit turns from FAIL TO PASS + do { + if (switch_from_dqstodq == false) { + // continue to update per bit deskew until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(dq, ch, dq_byte, bit_indx), tap_value_b[byte]); + } + } + } else { + // adjust rddq sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (all_bits_pass_b[byte] == 0) + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(tap_value_b[byte])); + } + + // Run rddq calibration in hw + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult = ((CSR_READ(rAMP_DQCALRESULT(AMP_DQ1, ch)) << 16) | + CSR_READ(rAMP_DQCALRESULT(AMP_DQ0, ch))); + } else { + rddqcalresult = dqcal_wr_rd_pattern_result(ch, rnk, tap_value_b[0]); + } + + // Account for swizzled bits and bytes of the result + rddqcalresult = dqcal_handle_swizzle(rddqcalresult, after_wrddqcal); + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (switch_from_dqstodq == false) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqmdllcode = mdllcode[ch][dq]; + + // consider mdllcode as '0' since sdll is set to -mdllcode + // need to convert tap_valyue_b into sdll scale, since saved value is in units of sdll steps + saved_val = -1 * (offset_convert(tap_value_b[byte], DIRECTION_DESKEW_TO_SDLL) + dqmdllcode); + } else + saved_val = tap_value_b[byte]; + + rddqcal_per_chrnk_right[chrnk_indx][bit_indx] = saved_val; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Right to Left Side of window (by adding less negative adjustment to mdll) + if (all_bits_pass == 0) { + // Even if one of the byte lanes arrives early to tap_value = 0. Remain here until all byte lane catch up before proceeding to pushing out dq + + // if the tap_value for all bytes has reached 0 on the deskew, make the transition to SDLL + if (switch_from_dqstodq == false) { + + // check for all bytes reaching 0 on the tap value (could be deskew or sdll) + int32_t all_bytes_tap = tap_value_b[0]; + for (byte = 1; (byte < DQ_NUM_BYTES) && (all_bytes_tap == 0); byte++) { + all_bytes_tap += tap_value_b[byte]; + } + + if (all_bytes_tap == 0) { + switch_from_dqstodq = true; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + tap_value_b[byte] = OFFSET_TO_INT(CSR_READ(rAMP_DQSDLLCTRL_RD(dq, ch, dq_byte)) & DLLVAL_BITS); + } + } + } + + // To find right side passing point, add less negative adjustment to mdll (same as decrementing deskew) + + // For deskew taps, we just decrement by FINER_STEP_SZ if we haven't reached 0 yet + if (switch_from_dqstodq == false) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (tap_value_b[byte] > 0) + tap_value_b[byte] -= FINER_STEP_SZ; + } else { + // For sdll taps, increment it + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + tap_value_b[byte] += FINER_STEP_SZ; + } + } + } + } + + // trigger for loop to end if any of the bytes reach max tap value + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] > MAX_SDLL_VAL); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + shim_panic("Memory rddq calibration: Unable to find right side passing point, max tap value reached"); + + break; + } + } + + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +// Purpose of this function is to start push DQS out till left side failing point of Data window is found +static void rddqcal_find_left_failing_point(uint32_t ch, uint32_t rnk, bool after_wrddqcal) +{ + int32_t rddqsdll[DQ_NUM_BYTES]; + uint32_t rddqcalresult, result_swiz; + uint32_t all_bits_fail; + uint32_t all_bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte, dq, dq_byte; + bool max_tap_value_reached = false; + + all_bits_fail = 0; + rddqcalresult = 0xFFFFFFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + // Get the starting values for RD DQS SDLL + rddqsdll[byte] = OFFSET_TO_INT(CSR_READ(rAMP_DQSDLLCTRL_RD(dq, ch, dq_byte)) & DLLVAL_BITS); + } + + // To find left failing point, keep adding less negative adjustment to mdll + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // set the new sdll for this byte lane if all bits are not yet failing + if (all_bits_fail_b[byte] == 0) + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(rddqsdll[byte])); + } + + // Run rddqcal in hw + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult &= ((CSR_READ(rAMP_DQCALRESULT(AMP_DQ1, ch)) << 16) | + CSR_READ(rAMP_DQCALRESULT(AMP_DQ0, ch))); + } else { + rddqcalresult &= dqcal_wr_rd_pattern_result(ch, rnk, rddqsdll[0]); + } + + // Account for swizzled bits and bytes of the result + result_swiz = dqcal_handle_swizzle(rddqcalresult, after_wrddqcal); + + // If the result of all bits in this byte show a fail, record this as the failing point + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((all_bits_fail_b[byte] == 0) && ((result_swiz & mask_b[byte]) == 0)) { + all_bits_fail_b[byte] = 1; + start_b[byte] = rddqsdll[byte]; + } + + all_bits_fail &= all_bits_fail_b[byte]; + } + + // all bytes fail, call the function to find left passing point + if (all_bits_fail == 1) { + rddqcal_find_left_passing_point(ch, rnk, start_b, after_wrddqcal); + } else { + // if the byte has not yet failed, find the next sdll value to be set + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) { + if ((rddqsdll[byte] + COARSE_STEP_SZ) <= MAX_SDLL_VAL) + rddqsdll[byte] += COARSE_STEP_SZ; + else + rddqsdll[byte] += FINER_STEP_SZ; + } + } + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // none of the previous bytes reached max_tap_value, then update the boolean + if (!max_tap_value_reached) { + max_tap_value_reached = (rddqsdll[byte] > MAX_SDLL_VAL); + + if (max_tap_value_reached) { + shim_printf("Memory rddq calibration: Unable to find left failing point, max tap value reached for ch %d byte %d\n", ch, byte); + break; + } + } + } + + if (max_tap_value_reached) { + // Continue to passing point if any of the bytes reaches max value and not all bits are failing + if (all_bits_fail == 0) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) + start_b[byte] = MAX_SDLL_VAL; + } + + rddqcal_find_left_passing_point(ch, rnk, start_b, after_wrddqcal); + } + } + + } while ((!max_tap_value_reached) && (all_bits_fail == 0)); +} + +// Purpose of this function is to start from left side failing point and find passing locations for every DQ bit on left side of window +// Save all the locations to compute the center of window later +// To find left passing point, move to the right from the failing point, which means keep adding more negative adjustment to mdll +static void rddqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + bool max_tap_value_reached = false; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + all_bits_pass = 0; + rddqcalresult = 0xFFFFFFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Finding Left side passing point on per bit level. Moving Left to Right (keep adding more negative adj to mdll) to find point where it turns from FAIL TO PASS + do { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if we haven't found all bits passing for this byte, push out new sdll value + if (all_bits_pass_b[byte] == 0) + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(tap_value_b[byte])); + } + + // Run rddqcal in hw + if (after_wrddqcal == false) { + amp_run_rddqcal(ch); + rddqcalresult = ((CSR_READ(rAMP_DQCALRESULT(AMP_DQ1, ch)) << 16) | + CSR_READ(rAMP_DQCALRESULT(AMP_DQ0, ch))); + } else { + rddqcalresult = dqcal_wr_rd_pattern_result(ch, rnk, tap_value_b[0]); + } + + rddqcalresult = dqcal_handle_swizzle(rddqcalresult, after_wrddqcal); + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the left edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + rddqcal_per_chrnk_left[chrnk_indx][bit_indx] = tap_value_b[byte]; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window (by adding more negative adjustment to mdll) + if (all_bits_pass == 0) { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + // if this byte lane does not have all passing bits, adjust this byte's sdll + if (all_bits_pass_b[byte] == 0) + tap_value_b[byte] -= FINER_STEP_SZ; + } + } + + // check for end of loop condition + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + uint32_t dq_byte = byte; + uint32_t dq = map_byte_to_dq(&dq_byte); + + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] < (-1 * MAX_SDLL_VAL)); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + shim_panic("Memory rddq calibration: Unable to find left passing point, max tap value reached"); + break; + } + + // panic if we get beyond -dqmdllcode, since we really shouldn't have to go that far + if ((all_bits_pass == 0) && (tap_value_b[byte] < (-1 * mdllcode[ch][dq]))) + shim_panic("Memory rddq calibration: Not yet found left passing point but SDLL < -dqmdllcode for ch %d byte %d", ch, byte); + } + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +static void rddqcal_program_final_values(void) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx, chrnk1_indx; + uint32_t dq, dq_byte; + int32_t rddq_bit_center[DQ_TOTAL_BITS]; + int32_t rddq_bit_deskew[DQ_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t max_rddq_center[DQ_NUM_BYTES]; + int32_t dqmdllcode; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + chrnk0_indx = (ch * cfg_params.num_ranks) + 0; + left_pos_val = rddqcal_per_chrnk_left[chrnk0_indx][bit_indx]; + right_pos_val = rddqcal_per_chrnk_right[chrnk0_indx][bit_indx]; + + if (cfg_params.num_ranks > 1) { + + chrnk1_indx = (ch * cfg_params.num_ranks) + 1; + + // find the endpoint that covers both ranks + left_pos_val = find_common_endpoint(rddqcal_per_chrnk_left[chrnk0_indx][bit_indx], + rddqcal_per_chrnk_left[chrnk1_indx][bit_indx], + MIN_ENDPT); + right_pos_val = find_common_endpoint(rddqcal_per_chrnk_right[chrnk0_indx][bit_indx], + rddqcal_per_chrnk_right[chrnk1_indx][bit_indx], + MAX_ENDPT); + } + + // find center of the eye for this bit + rddq_bit_center[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + } + + // initialize the max centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + max_rddq_center[byte] = rddq_bit_center[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the maximum CenterPoint per byte lane given each bit's center point + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // if this bit's center point is greater than current max, make it the new max (we'll program this to sdll, and other values will require deskew) + if (rddq_bit_center[bit_indx] > max_rddq_center[byte]) + max_rddq_center[byte] = rddq_bit_center[bit_indx]; + } + + // if the max for each byte lane is < -dqmdllcode, clamp it to -dqmdllcode (the remainder will go on per bit deskew) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqmdllcode = mdllcode[ch][dq]; + + if (max_rddq_center[byte] < (-1 * dqmdllcode)) + max_rddq_center[byte] = (-1 * dqmdllcode); + } + + // Compute the individual deskew values: any bits with center point < max for its byte lane will require deskew + // Each bit's center is guaranteed to be <= max for its byte lane + // Deskewing means adding more negative adjustment for this bit in addition to the sdll, which is clamped on the negative side to -dqmdllcode + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqmdllcode = mdllcode[ch][dq]; + + if (rddq_bit_center[bit_indx] > max_rddq_center[byte]) + shim_panic("Memory Rddq calibration: rddq_bit_center[%d] = %d > max_rddq_center[%d] = %d\n", bit_indx, rddq_bit_center[bit_indx], byte, max_rddq_center[byte]); + + rddq_bit_deskew[bit_indx] = max_rddq_center[byte] - rddq_bit_center[bit_indx]; + + // need to convert the deskew value, which is in sdll scale so far, into deskew scale + rddq_bit_deskew[bit_indx] = offset_convert(rddq_bit_deskew[bit_indx], DIRECTION_SDLL_TO_DESKEW); + + if ((rddq_bit_deskew[bit_indx] < 0) || (rddq_bit_deskew[bit_indx] > DQ_MAX_DESKEW_PER_BIT)) + shim_panic("Memory Rddq calibration: rddq_bit_deskew[%d] = %d invalid\n", bit_indx, rddq_bit_deskew[bit_indx]); + } + + // Program the SDLL and deskew per bit for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_set_rddq_sdll(ch, byte, INT_TO_OFFSET(max_rddq_center[byte])); + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + // per bit deskew for this byte lane + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(dq, ch, dq_byte, bit_indx), rddq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]); + } + } + } // for (ch = 0; ch < cfg_params.num_channels; ch++) +} + +/* We want to end up returning the result in the following order + * B3.B1.B2.B0, where B0 and B2 are mapped to ampdq0[0:7] and ampdq[8:15], respectively + * and B1 and B3 are mapped to ampdq1[0:7] and ampdq1[8:15], respectively. + * In addition, ampdq0 bytes (B0 and B2) requires their bits unswizzled. + */ +static uint32_t dqcal_handle_swizzle(uint32_t result, bool after_wrddqcal) +{ + uint32_t result_unswz, result_tmp; + uint8_t result_byte; + + result_unswz = 0; + + if (after_wrddqcal) { + // In the case of PRBS patterns, the result was constructed + // by the CPU, which has normal byte order: B3.B2.B1.B0, so swap them around + // to produce B3.B1.B2.B0 + + // B3 and B0 are in the right place already, just swap around B2 and B1 + result_tmp = result & (0xFF0000FF); + result_tmp |= (result & 0x00FF0000) >> 8; + result_tmp |= (result & 0x0000FF00) << 8; + } else { + // In the case of rddq before wrdq, the result was constructed + // with the byte order we want: B3.B1.B2.B0, so no byte swapping required + result_tmp = result; + } + + // Undo bit swizzling in DQ0 only (lower 16 bits of the result) + result_byte = (result_tmp & 0x000000FF); + result_byte = reverse_bits_in_byte(result_byte); + result_unswz = result_byte; + result_byte = (result_tmp & 0x0000FF00) >> 8; + result_byte = reverse_bits_in_byte(result_byte); + result_unswz |= result_byte << 8; + + // Now simply or in the top 16 bits (DQ1 does not have bits swizzled) + result_unswz |= (result_tmp & 0xFFFF0000); + + return result_unswz; +} + +static uint8_t reverse_bits_in_byte(uint8_t byte) +{ + uint8_t i, tmp; + uint8_t reversed_byte = 0; + + for (i = 0; i < 8; i++) { + tmp = byte & (1 << i); + tmp >>= i; + reversed_byte |= (tmp << (7 - i)); + } + + return reversed_byte; +} + +static uint32_t wrlvlcal_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val) +{ + uint32_t ret_val, mdll; + + mdll = (uint32_t) mdllcode[ch][phy_type]; + + if (val < ( (2 * mdll) - 2 )) { + ret_val = 0; + } else if (val < ( 2 * mdll )) { + ret_val = 1; + } else if (val < ( (2 * mdll) + 3 )) { + ret_val = 2; + } else { + ret_val = 3; + } + + return ret_val; +} + +static uint32_t wrlvlcal_encode_clk90dly(uint32_t ch, uint32_t phy_type, uint32_t val) +{ + uint32_t ret_val, mdll; + + mdll = (uint32_t) mdllcode[ch][phy_type]; + + if (val < (mdll - 2)) { + ret_val = 0; + } else if (val < mdll) { + ret_val = 1; + } else if (val < (mdll + 3)) { + ret_val = 2; + } else { + ret_val = 3; + } + + return ret_val; +} + +static void wrlvlcal_push_to_0s_region(uint32_t ch, uint32_t rnk) +{ + uint32_t wrlvldata, byte; + uint32_t cawrlvlcode = 0; + bool max_tap_value_reached = false; + uint32_t wrlvlrun = 0xF; + uint32_t dqwrlvlcode[DQ_NUM_BYTES] = { 0 }; + + // Note that incrementing cawrlvl sdll has opposite effect of incrementing dqwrlvl + + do { + // If any byte lane shows that it returned a value of 1 - push ca wrlvl sdll out by 1 tap + cawrlvlcode++; + amp_set_cawrlvl_sdll(ch, cawrlvlcode, false); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte already showed a 0 during last run, push dqwrlvl sdll by 1 tap + // this is done to ensure this byte remains at 0 despite cawrlvl sdll being incremented above + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + + // Run Wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLDATA register + wrlvldata = (CSR_READ(rAMP_DQWRLVLDATA(AMP_DQ1, ch)) << 16) | + (CSR_READ(rAMP_DQWRLVLDATA(AMP_DQ0, ch))); + + // check if all bits for this byte returned a 0, then this byte is done + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + if ((wrlvldata & (0xFF << (byte * DQ_NUM_BITS_PER_BYTE))) == 0) + wrlvlrun &= ~(1 << byte); + } + } + + // Exit if ca or dq wrlvl sdlls reach max tap value + if (cawrlvlcode == MAX_CAWRLVL_CODE) { + max_tap_value_reached = true; + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: CA sdll reached max tap value, yet all bytes not all 0s"); + } else { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 0s", byte); + max_tap_value_reached = true; + break; + } + } + } + } while (wrlvlrun && !max_tap_value_reached); +} + +// Keep incrementing dqsdll until the byte shows 1s again. This counters the casdll that was incremented previously in order to show 0s +static void wrlvlcal_find_0to1_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte, dq, dq_byte; + uint32_t wrlvlrun, wrlvldata; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + + wrlvlrun = 0xF; + wrlvldata = 0; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqwrlvlcode[byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(dq, ch, dq_byte)); + } + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte is still showing a 0, increment the sdll + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + wrlvldata = (CSR_READ(rAMP_DQWRLVLDATA(AMP_DQ1, ch)) << 16) | + (CSR_READ(rAMP_DQWRLVLDATA(AMP_DQ0, ch))); + + // check if all bits return a 1 for this byte, then this byte is done + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + if (((int) (wrlvldata & (0xFF << (byte * DQ_NUM_BITS_PER_BYTE)))) == (0xFF << (byte * DQ_NUM_BITS_PER_BYTE))) + wrlvlrun &= ~(1 << byte); + } + } + + // Exit if any of the byte lane's sdll reaches max + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 1s", byte); + max_tap_value_reached = true; + break; + } + } + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvlcal_per_chrnk_rise[chrnk_indx][byte] = dqwrlvlcode[byte]; + // in the "5th byte" entry, save the cawrlvl code + wrlvlcal_per_chrnk_rise[chrnk_indx][byte] = cawrlvlcode; +} + +// Go back towards the 0s region (that was found earlier). Note: not trying to find the next edge, just the previous edge that was found already +static void wrlvlcal_find_1to0_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte, dq, dq_byte; + uint32_t wrlvlrun, wrlvldata; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + bool incr_cawrlvl = false; + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + wrlvlrun = 0xF; + + // jump ahead by SOLID_PASS_DETECT into the 1s region + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqwrlvlcode[byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(dq, ch, dq_byte)); + dqwrlvlcode[byte] += (SOLID_PASS_DETECT + 1); // + 1 because code is decremented before programming the sdll + } + + do { + // Make sure dqwrlvlsdll > 0, otherwise switch to cawrlvlsdll + for (byte = 0; (byte < DQ_NUM_BYTES) && !incr_cawrlvl; byte++) { + if (dqwrlvlcode[byte] == 0) + incr_cawrlvl = true; + } + + // if we've reached 0 on any dqwrlvlsdll that were being decremented, switch to incrementing the cawrlvlsdll (same effect) + if (incr_cawrlvl) { + cawrlvlcode++; + amp_set_cawrlvl_sdll(ch, cawrlvlcode, false); + + // In order to keep bytes that have transitioned to 0 to stay there, increment dqwrlvlsdll (counters effect of incrementing cawrlvlsdll) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + } else { + // if run bit is set for this byte, push out the new sdll value after decrementing by 1 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]--; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte], false); + } + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + wrlvldata = (CSR_READ(rAMP_DQWRLVLDATA(AMP_DQ1, ch)) << 16) | + (CSR_READ(rAMP_DQWRLVLDATA(AMP_DQ0, ch))); + + // check if all bits for this byte returned a 0, then this byte is done + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + if ((wrlvldata & (0xFF << (byte * DQ_NUM_BITS_PER_BYTE))) == 0) + wrlvlrun &= ~(1 << byte); + } + } + + // check if we've reached max tap value + if (incr_cawrlvl && (cawrlvlcode == MAX_CAWRLVL_CODE)) { + max_tap_value_reached = true; + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: max tap value reached, yet all bytes not back to 0s"); + } + + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvlcal_per_chrnk_fall[chrnk_indx][byte] = dqwrlvlcode[byte]; + + // in the "5th byte" entry, save the cawrlvl code + wrlvlcal_per_chrnk_fall[chrnk_indx][byte] = cawrlvlcode; +} + +static void wrlvlcal_program_final_values(void) +{ + uint32_t ch, chrnk0_indx, chrnk1_indx; + uint32_t rank_rise_val[AMP_MAX_RANKS_PER_CHAN], rank_fall_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t edge_pos[AMP_MAX_RANKS_PER_CHAN]; + uint32_t common_edge_pos, min_edge_pos; + uint32_t byte; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + // we go upto DQ_NUM_BYTES + 1 to also take into account the cawrlvlcode that is stored in the 5th element + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // Rank 0 + chrnk0_indx = (ch * cfg_params.num_ranks) + 0; + rank_rise_val[0] = wrlvlcal_per_chrnk_rise[chrnk0_indx][byte]; + rank_fall_val[0] = wrlvlcal_per_chrnk_fall[chrnk0_indx][byte]; + // average of 2 values is the edge for this rank + edge_pos[0] = (rank_rise_val[0] + rank_fall_val[0]) >> 1; + common_edge_pos = edge_pos[0]; + + // Adjust for Dual ranks + if (cfg_params.num_ranks > 1) { + chrnk1_indx = (ch * cfg_params.num_ranks) + 1; + rank_rise_val[1] = wrlvlcal_per_chrnk_rise[chrnk1_indx][byte]; + rank_fall_val[1] = wrlvlcal_per_chrnk_fall[chrnk1_indx][byte]; + edge_pos[1] = (rank_rise_val[1] + rank_fall_val[1]) >> 1; + + // common_edge_pos between both ranks is simply their average + common_edge_pos = (edge_pos[0] + edge_pos[1]) >> 1; + } + + // save the wrlvlsdll for each byte (and the ca) + wrlvlcal_saved_val[ch][byte] = common_edge_pos; + } + + // Find the min among all bytes (and the ca) + min_edge_pos = wrlvlcal_saved_val[ch][DQ_NUM_BYTES]; // initialize min as the cawrlvlsdll + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (wrlvlcal_saved_val[ch][byte] < min_edge_pos) + min_edge_pos = wrlvlcal_saved_val[ch][byte]; + + // We'll subtract the min from all 5 sdlls, including ca + // so the byte sdlls which are in opposite direction also need to be adjusted + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + wrlvlcal_saved_val[ch][byte] -= min_edge_pos; + + // Program the values into the registers + if (byte == DQ_NUM_BYTES) { + // cawrlvl (use dlysel, which will require phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, wrlvlcal_saved_val[ch][byte], true); + } else { + // dqwrlvl (use dlysel, which will require phyupdt and forceckelow) + amp_set_dqwrlvl_sdll(ch, byte, wrlvlcal_saved_val[ch][byte], true); + } + } + } +} + + +// Keep pushing out WRDQS lines (controlled by WRDQM registers, oddly) until right side failing point is found +static void wrdqcal_find_right_failing_point(uint32_t ch, uint32_t rnk) +{ + uint32_t push_dqs_out; + uint32_t all_bits_fail; + uint32_t bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t wrdqcalresult_swiz, wrdqcalresult; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte, dq_byte, dq; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + + all_bits_fail = 0; + push_dqs_out = 0; + wrdqcalresult = 0xFFFFFFFF; + + // set the wrdq sdll to negative dqmdllcode + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + amp_set_wrdq_sdll(ch, byte, (-1 * mdllcode[ch][dq])); + + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + } + + do { + // NOTE: When DQS are pushed out then - cawrlvl sdll needs to be pushed out as well with equal taps + // can use dlysel (with phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, cawrlvlcode + push_dqs_out, true); + + // Keep pushing per bit DQS (controlled by DM regs, oddly) out until all bytes start to fail + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(dq, ch, dq_byte), push_dqs_out); + } + + // Perform the WrDq calibration with PRBS patterns + wrdqcalresult &= dqcal_wr_rd_pattern_result(ch, rnk, push_dqs_out); + wrdqcalresult_swiz = dqcal_handle_swizzle(wrdqcalresult, true); + + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) { + // if all bits fail for this byte for the 1st time, we've found the right failing point + if ((wrdqcalresult_swiz & mask_b[byte]) == 0) { + bits_fail_b[byte] = 1; + start_b[byte] = push_dqs_out; + } + } + + all_bits_fail &= bits_fail_b[byte]; + } + + // if all bits in all bytes fail, find the right passing point + if (all_bits_fail == 1) { + wrdqcal_find_right_passing_point(ch, rnk, start_b); + } else { + // increase the deskew since all bits are not yet failing + if ((push_dqs_out + COARSE_STEP_SZ) <= DQ_MAX_DESKEW_PER_BIT) + push_dqs_out += COARSE_STEP_SZ; + else + push_dqs_out += FINER_STEP_SZ; + } + + } while ((push_dqs_out <= DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)); + + if ((push_dqs_out > DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)) { + // Right Failing Point cannot be found + shim_printf("Memory Wrdq calibration: Max deskew reached, but right failing point not found for ch %d\n", ch); + + // Assume failure point is max dqs deskew setting + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) + start_b[byte] = DQ_MAX_DESKEW_PER_BIT; + } + + // continue to passing point + wrdqcal_find_right_passing_point(ch, rnk, start_b); + } + + // Before quitting restore the cawrlvlsdll and per byte deskew back to original values. + // can use dlysel (with phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, cawrlvlcode, true); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(dq, ch, dq_byte), 0); + } +} + +// Keep decreasing per byte deskew until right passing point is found +static void wrdqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b) +{ + uint32_t chrnk_indx; + bool switch_from_dqstodq, max_tap_value_reached; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t wrdqcalresult, wrdqcalresult_swiz; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + int32_t saved_val, max_value, dqmdllcode; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + uint32_t dq, dq_byte; + int32_t max_tap_value[AMP_DQ_PER_CHAN]; + int32_t sdll_limit_b[DQ_NUM_BYTES], deskew_taps_b[DQ_NUM_BYTES]; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + sdll_limit_b[byte] = mdllcode[ch][dq] - DELIMIT_POS_ADJ_WRDQSDLL; + } + + max_tap_value[AMP_DQ0] = mdllcode[ch][AMP_DQ0] - DELIMIT_POS_ADJ_WRDQSDLL + offset_convert(DQ_MAX_DESKEW_PER_BIT, DIRECTION_DESKEW_TO_SDLL); + max_tap_value[AMP_DQ1] = mdllcode[ch][AMP_DQ1] - DELIMIT_POS_ADJ_WRDQSDLL + offset_convert(DQ_MAX_DESKEW_PER_BIT, DIRECTION_DESKEW_TO_SDLL); + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + all_bits_pass = 0; + switch_from_dqstodq = false; + max_tap_value_reached = false; + + max_value = start_b[0]; + // initialize tap_values to max of all bytes' start values + for (byte = 1; byte < DQ_NUM_BYTES; byte++) + max_value = (start_b[byte] > max_value) ? start_b[byte] : max_value; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = max_value; + } + + // Any change in DM_DESKEW registers will require an equal change to cawrlvl sdll + do { + if (switch_from_dqstodq == false) { + // cawrlvlcode is decremented with tap_value_b each time + // can use dlysel (with phyupdt and forceckelow) + amp_set_cawrlvl_sdll(ch, cawrlvlcode, true); + + // Keep pushing per bit DQS out until all bytes start to fail + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(dq, ch, dq_byte), tap_value_b[byte]); + } + } else { + // adjust wrdq sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) + amp_set_wrdq_sdll(ch, byte, tap_value_b[byte]); + } + } + + // Send the PRBS patterns and read them back to see which bits are passing or failing + wrdqcalresult = dqcal_wr_rd_pattern_result(ch, rnk, tap_value_b[0] + tap_value_b[1] + tap_value_b[2] + tap_value_b[3]); + wrdqcalresult_swiz = dqcal_handle_swizzle(wrdqcalresult, true); + + // Make sure that each Bit sees a transition from 0 (fail) to 1 (pass) on wrdqcalresult_swiz + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((wrdqcalresult_swiz & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (switch_from_dqstodq == false) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqmdllcode = mdllcode[ch][dq]; + + // consider mdllcode as '0' since sdll is set to -mdllcode + // saved value is in units of sdll steps + saved_val = -1 * (offset_convert(tap_value_b[byte], DIRECTION_DESKEW_TO_SDLL) + dqmdllcode); + } else { + // saved value is in units of sdll steps + if (tap_value_b[byte] >= sdll_limit_b[byte]) + saved_val = sdll_limit_b[byte] + offset_convert(deskew_taps_b[byte], DIRECTION_DESKEW_TO_SDLL); + else + saved_val = tap_value_b[byte]; + } + + wrdqcal_per_chrnk_right[chrnk_indx][bit_indx] = saved_val; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Right to Left Side of window (by adding less negative adjustment to mdll) + if (all_bits_pass == 0) { + // Even if one of the byte lanes arrives early to tap_value = 0. Remain here until all byte lane catch up before proceeding to pushing out dq + + // if the tap_value for all bytes has reached 0 on the deskew, make the transition to SDLL + if (switch_from_dqstodq == false) { + + // check for all bytes reaching 0 on the tap value (could be deskew or sdll) + uint32_t all_bytes_tap = tap_value_b[0]; + for (byte = 1; (byte < DQ_NUM_BYTES) && (all_bytes_tap == 0); byte++) { + all_bytes_tap += tap_value_b[byte]; + } + + if (all_bytes_tap == 0) { + switch_from_dqstodq = true; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + tap_value_b[byte] = OFFSET_TO_INT(CSR_READ(rAMP_DQSDLLCTRL_WR(dq, ch, dq_byte)) & DLLVAL_BITS); + } + } + + } + + // To find right side passing point, add less negative adjustment to mdll (same as decrementing deskew) + + // For deskew taps, we just decrement by FINER_STEP_SZ if we haven't reached 0 yet + // Note: All deskew taps will reach 0 at the same time since their start values are equal, and they are decremented regardless of pass or fail + if (switch_from_dqstodq == false) { + + // Also decrement cawrlvlsdllcode along with tap_value_b + if (tap_value_b[0] > 0) + cawrlvlcode -= FINER_STEP_SZ; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (tap_value_b[byte] > 0) + tap_value_b[byte] -= FINER_STEP_SZ; + } else { + // For sdll taps, increment + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + tap_value_b[byte] += FINER_STEP_SZ; + + if (tap_value_b[byte] >= sdll_limit_b[byte]) + deskew_taps_b[byte] = offset_convert(tap_value_b[byte] - sdll_limit_b[byte], DIRECTION_SDLL_TO_DESKEW); + } + } + } + } + + // trigger for loop to end if any of the bytes reach max tap value + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] > max_tap_value[dq]); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + shim_panic("Memory wrdq calibration: Unable to find right side passing point, max tap value reached. ch %d, byte %d, start_b[] = {0x%x 0x%x 0x%x 0x%x}", ch, byte, start_b[0], start_b[1], start_b[2], start_b[3]); + } + } + + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +// To find left failing point, keep adding less negative adjustment to mdll +static void wrdqcal_find_left_failing_point(uint32_t ch, uint32_t rnk) +{ + int32_t wrdqsdll[DQ_NUM_BYTES]; + uint32_t wrdqcalresult, wrdqcalresult_swiz; + uint32_t all_bits_fail; + uint32_t all_bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t mask_b[DQ_NUM_BYTES]; + int32_t start_b[DQ_NUM_BYTES]; + uint32_t byte, dq, dq_byte; + bool max_tap_value_reached = false; + int32_t max_tap_value[AMP_DQ_PER_CHAN]; + int32_t dq_deskew; + + max_tap_value[AMP_DQ0] = mdllcode[ch][AMP_DQ0] - DELIMIT_POS_ADJ_WRDQSDLL + offset_convert(DQ_MAX_DESKEW_PER_BIT, DIRECTION_DESKEW_TO_SDLL); + max_tap_value[AMP_DQ1] = mdllcode[ch][AMP_DQ1] - DELIMIT_POS_ADJ_WRDQSDLL + offset_convert(DQ_MAX_DESKEW_PER_BIT, DIRECTION_DESKEW_TO_SDLL); + + all_bits_fail = 0; + wrdqcalresult = 0xFFFFFFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // initialize the mask for each byte lane + mask_b[byte] = 0xFF << (byte * 8); + + dq_byte = byte; + // + dq = map_byte_to_dq(&dq_byte); + + // Get the starting values for WR DQS SDLL + wrdqsdll[byte] = OFFSET_TO_INT(CSR_READ(rAMP_DQSDLLCTRL_WR(dq, ch, dq_byte)) & DLLVAL_BITS); + + // Add per-bit deskew to wrdqsdll[byte] if sdll reached mdll - DELIMIT_POS_ADJ_WRDQSDLL (otherwise, deskew should be 0) + // At this point per-bit deskew should be the same for each bit in this byte. Use bit 0's deskew value + dq_deskew = CSR_READ(rAMP_WRDQDESKEW_CTRL(dq, ch, dq_byte, 0)); + // convert deskew taps to sdll taps + dq_deskew = offset_convert(dq_deskew, DIRECTION_DESKEW_TO_SDLL); + wrdqsdll[byte] += dq_deskew; + } + + // Start with sdll value for which right passing point was found, then increase (less negative) until all bits fail + do { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // set the new sdll for this byte lane if all bits are not yet failing + if (all_bits_fail_b[byte] == 0) + amp_set_wrdq_sdll(ch, byte, wrdqsdll[byte]); + } + + // Send the PRBS patterns and read them back to see which bits are passing or failing + wrdqcalresult &= dqcal_wr_rd_pattern_result(ch, rnk, wrdqsdll[0] + wrdqsdll[1] + wrdqsdll[2] + wrdqsdll[3]); + wrdqcalresult_swiz = dqcal_handle_swizzle(wrdqcalresult, true); + + // If the result of all bits in this byte show a fail, record this as the failing point + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((all_bits_fail_b[byte] == 0) && ((wrdqcalresult_swiz & mask_b[byte]) == 0)) { + all_bits_fail_b[byte] = 1; + start_b[byte] = wrdqsdll[byte]; + } + + all_bits_fail &= all_bits_fail_b[byte]; + } + + if (all_bits_fail == 1) { + wrdqcal_find_left_passing_point (ch, rnk, start_b); + } else { + // if the byte has not yet failed, find the next sdll value to be set + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + if ((wrdqsdll[byte] + COARSE_STEP_SZ) <= max_tap_value[dq]) + wrdqsdll[byte] += COARSE_STEP_SZ; + else + wrdqsdll[byte] += FINER_STEP_SZ; + } + } + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + // none of the previous bytes reached max_tap_value, then update the boolean + if (!max_tap_value_reached) { + max_tap_value_reached = (wrdqsdll[byte] > max_tap_value[dq]); + + if (max_tap_value_reached) { + shim_printf("Memory wrdq calibration: Unable to find left failing point, max tap value reached for ch %d byte %d\n", ch, byte); + break; + } + } + } + + if (max_tap_value_reached) { + // Continue to passing point if any of the bytes reaches max value and not all bits are failing + if (all_bits_fail == 0) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + if (all_bits_fail_b[byte] == 0) + start_b[byte] = max_tap_value[dq]; + } + + wrdqcal_find_left_passing_point(ch, rnk, start_b); + } + } + } while ((!max_tap_value_reached) && (all_bits_fail == 0)); +} + +static void wrdqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, int32_t *start_b) +{ + uint32_t chrnk_indx; + bool max_tap_value_reached = false; + int32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS] = { 0 }; + uint32_t wrdqcalresult, wrdqcalresult_swiz; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + uint32_t dq, dq_byte; + int32_t max_tap_value[AMP_DQ_PER_CHAN]; + int32_t sdll_limit_b[DQ_NUM_BYTES], deskew_taps_b[DQ_NUM_BYTES]; + + max_tap_value[AMP_DQ0] = -1 * mdllcode[ch][AMP_DQ0]; + max_tap_value[AMP_DQ1] = -1 * mdllcode[ch][AMP_DQ1]; + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + all_bits_pass = 0; + wrdqcalresult = 0xFFFFFFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + sdll_limit_b[byte] = mdllcode[ch][dq] - DELIMIT_POS_ADJ_WRDQSDLL; + + if (tap_value_b[byte] >= sdll_limit_b[byte]) + deskew_taps_b[byte] = offset_convert(tap_value_b[byte] - sdll_limit_b[byte], DIRECTION_SDLL_TO_DESKEW); + else + deskew_taps_b[byte] = 0; + } + + // Finding Left side failing point on per bit level. Moving Left to Right (keep adding more negative adj to mdll) to find point where it turns from FAIL TO PASS + do { + // adjust wrdq sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) + amp_set_wrdq_sdll(ch, byte, tap_value_b[byte]); + } + + // Send the PRBS patterns and read them back to see which bits are passing or failing + wrdqcalresult = dqcal_wr_rd_pattern_result(ch, rnk, tap_value_b[0] + tap_value_b[1] + tap_value_b[2] + tap_value_b[3]); + wrdqcalresult_swiz = dqcal_handle_swizzle(wrdqcalresult, true); + + // Make sure that each Bit sees a transition from 0 (fail) to 1 (pass) on wrdqcalresult_swiz + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((wrdqcalresult_swiz & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + int32_t saved_val; + // saved value is in units of sdll steps + if (tap_value_b[byte] >= sdll_limit_b[byte]) + saved_val = sdll_limit_b[byte] + offset_convert(deskew_taps_b[byte], DIRECTION_DESKEW_TO_SDLL); + else + saved_val = tap_value_b[byte]; + + wrdqcal_per_chrnk_left[chrnk_indx][bit_indx] = saved_val; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window (by adding more negative adjustment to mdll) + if (all_bits_pass == 0) { + // For sdll taps, decrement it + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + tap_value_b[byte] -= FINER_STEP_SZ; + + if (tap_value_b[byte] >= sdll_limit_b[byte]) + deskew_taps_b[byte] = offset_convert(tap_value_b[byte] - sdll_limit_b[byte], DIRECTION_SDLL_TO_DESKEW); + } + } + } + + // check for end of loop condition + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] < max_tap_value[dq]); + + if (max_tap_value_reached) { + if (all_bits_pass_b[byte] == 0) + shim_panic("Memory wrdq calibration: Unable to find left passing point, max tap value reached. ch %d, byte %d, start_b[] = {0x%x, 0x%x, 0x%x, 0x%x}", ch, byte, start_b[0], start_b[1], start_b[2], start_b[3]); + break; + } + } + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +static void wrdqcal_program_final_values(void) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx, chrnk1_indx; + int32_t dqmdllcode; + int32_t wrdq_bit_center[DQ_TOTAL_BITS]; + int32_t wrdq_bit_deskew[DQ_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t min_wrdq_center[DQ_NUM_BYTES]; + int32_t min_dq_deskew_code, max_dq_deskew_code; + uint32_t dq, dq_byte; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + chrnk0_indx = (ch * cfg_params.num_ranks) + 0; + left_pos_val = wrdqcal_per_chrnk_left[chrnk0_indx][bit_indx]; + right_pos_val = wrdqcal_per_chrnk_right[chrnk0_indx][bit_indx]; + + if (cfg_params.num_ranks > 1) { + + chrnk1_indx = (ch * cfg_params.num_ranks) + 1; + + // find the endpoint that covers both ranks + left_pos_val = find_common_endpoint(wrdqcal_per_chrnk_left[chrnk0_indx][bit_indx], + wrdqcal_per_chrnk_left[chrnk1_indx][bit_indx], + MIN_ENDPT); + right_pos_val = find_common_endpoint(wrdqcal_per_chrnk_right[chrnk0_indx][bit_indx], + wrdqcal_per_chrnk_right[chrnk1_indx][bit_indx], + MAX_ENDPT); + } + + // find center of the eye for this bit + wrdq_bit_center[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + } + + // initialize the min centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + min_wrdq_center[byte] = wrdq_bit_center[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the min CenterPoint per byte lane given each bit's center point + for (bit_indx=0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + // if this bit's center point is less than current min, make it the new min + if (wrdq_bit_center[bit_indx] < min_wrdq_center[byte]) + min_wrdq_center[byte] = wrdq_bit_center[bit_indx]; + } + + // for positive value, clamp it to mdllcode - DELIMIT_POS_ADJ_WRDQSDLL + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqmdllcode = mdllcode[ch][dq]; + + if (min_wrdq_center[byte] > (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL)) + min_wrdq_center[byte] = (dqmdllcode - DELIMIT_POS_ADJ_WRDQSDLL); + } + + // Compute the individual deskew values: any bits with center point > min for its byte lane will require deskew + // Each bit's center is guaranteed to be >= min for its byte lane + // Deskewing means adding more positive adjustment for this bit in addition to the sdll + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS; bit_indx++) { + + byte = bit_indx >> 3; // bit_indx / DQ_NUM_BITS_PER_BYTE + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqmdllcode = mdllcode[ch][dq]; + + if (wrdq_bit_center[bit_indx] < min_wrdq_center[byte]) + shim_panic("Memory Wrdq Calibration: wrdq_bit_center[%d] = (%d) < min_wrdq_center[%d] = %d\n", bit_indx, wrdq_bit_center[bit_indx], byte, min_wrdq_center[byte]); + + wrdq_bit_deskew[bit_indx] = wrdq_bit_center[bit_indx] - min_wrdq_center[byte]; + + // Need to convert deskew values, which have been in the sdll scale so far, into the deskew scale + wrdq_bit_deskew[bit_indx] = offset_convert(wrdq_bit_deskew[bit_indx], DIRECTION_SDLL_TO_DESKEW); + + // Make sure deskew value programmed is not negative and is <= DQ_MAX_DESKEW_PER_BIT + if ((wrdq_bit_deskew[bit_indx] < 0) || (wrdq_bit_deskew[bit_indx] > DQ_MAX_DESKEW_PER_BIT)) + shim_panic("Memory Wrdq Calibration: wrdq_bit_deskew[%d] = %d invalid\n", bit_indx, wrdq_bit_deskew[bit_indx]); + } + + // if the min for each byte lane is < -dqmdllcode, we'll need to adjust/clamp it to -dqmdllcode + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + dqmdllcode = mdllcode[ch][dq]; + + if (min_wrdq_center[byte] < (-1 * dqmdllcode)) { + int32_t dqs_deskew = (-1 * dqmdllcode) - min_wrdq_center[byte]; + // need to convert from sdll scale to deskew scale + dqs_deskew = offset_convert(dqs_deskew, DIRECTION_SDLL_TO_DESKEW); + // put the remainder on DQS + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(dq, ch, dq_byte), dqs_deskew); + min_wrdq_center[byte] = (-1 * dqmdllcode); + } + } + + // Program the SDLL and deskew per bit for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_set_wrdq_sdll(ch, byte, min_wrdq_center[byte]); + + dq_byte = byte; + dq = map_byte_to_dq(&dq_byte); + + // init the min and max deskew values for each byte to the 1st bit in the byte + min_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE)]; + max_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE)]; + // per bit deskew for this byte lane + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(dq, ch, dq_byte, bit_indx), wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]); + + // is this bit the new min or max? + if (wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] < min_dq_deskew_code) + min_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]; + else if (wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] > max_dq_deskew_code) + max_dq_deskew_code = wrdq_bit_deskew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx]; + } + + // find midpoint of deskew registers for this byte, and program it to DM (controlled by DQS regs, oddly) + CSR_WRITE(rAMP_WRDQSDESKEW_CTRL(dq, ch, dq_byte), (min_dq_deskew_code + max_dq_deskew_code) >> 1); + } + } // for (ch = 0; ch < cfg_params.num_channels; ch++) +} + +// This function writes PRBS7 patterns to dram for given channel and rank, +// and reads them back. Read back values are compared with data that was written +static uint32_t dqcal_wr_rd_pattern_result(uint32_t ch, uint32_t rnk, uint32_t sdll_value) +{ + uint32_t chrnk_indx, result, result_per_wr_and_rdbk; + uint32_t pattern_indx, pattern, readback_data; + uint32_t col, word; + uint64_t mem_region; + uint32_t all_bits = 0xFFFFFFFF; + uint32_t consecutive_cols_per_chrnk = (shim_get_consecutive_bytes_perchnrnk() / DQ_BYTES_PER_COL); + + result = all_bits; + result_per_wr_and_rdbk = all_bits; + + chrnk_indx = (ch * cfg_params.num_ranks) + rnk; + pattern_indx = sdll_value & DLLVAL_BITS; // sdll tap indexes into pattern array + + // need APB read inserted in function wr_rd_pattern_result + CSR_READ(rAMP_RDFIFOPTRSTS(AMP_DQ0, ch)); + + // write the patterns to memory 4 bytes at a time + // interleaving applies x bytes (obtained by shim_get_consecutive_bytes_perchnrnk), so recompute the address at that point + // Note that bank and row are fixed + for (col = 0; col < DQ_NUM_PATTERNS; col += consecutive_cols_per_chrnk) { + + mem_region = shim_compute_dram_addr(ch, rnk, DQ_BANK, DQ_ROW, col); + + // next 64 words (or columns, for H7 this is 256 bytes) are consecutively stored in a [channel,rank] combo + for (word = 0; word < consecutive_cols_per_chrnk; word++) { + + // last pattern in array is dummy value, so skip it + pattern = DQ_PRBS7_PATTERNS[pattern_indx % (DQ_NUM_PATTERNS - 1)]; + pattern_indx++; + + // + // write the pattern: 3rd argument for DV requires +1, others should subtract 1 before adding to mem_region + MEM_WRITE(mem_region, pattern, (word+1)); + } + } + + pattern_indx = sdll_value & DLLVAL_BITS; + + // Now, read back the patterns (have to do it in a separate loop than the writes to get more robust calib values) + for (col = 0; col < DQ_NUM_PATTERNS; col += consecutive_cols_per_chrnk) { + + mem_region = shim_compute_dram_addr(ch, rnk, DQ_BANK, DQ_ROW, col); + + // next 16 words (or columns) are consecutively stored in a [channel,rank] combo + for (word = 0; word < consecutive_cols_per_chrnk; word++) { + + // last pattern in array is dummy value, so skip it + pattern = DQ_PRBS7_PATTERNS[pattern_indx % (DQ_NUM_PATTERNS - 1)]; + pattern_indx++; + + // + // read the pattern: 2nd argument for DV requires +1, others should subtract 1 before adding to mem_region + readback_data = MEM_READ(mem_region, (word+1)); + + // records if read back value was different than written value by + // clearing bits that are different in the final result + result_per_wr_and_rdbk &= ~(readback_data ^ pattern); + } + + // result variable accumulates the results of all pattern matching results for a given sdll_value + result &= result_per_wr_and_rdbk; + } + + // failing bits are clear, passing bits are set + return result; +} + +// The change that switched to signed integer format from sign/magnitude () +// has rendered this function unused. But leaving the code in for posterity's sake +#if 0 +// Given an input where bit SIGN_BIT_POS represents the sign, and the rest is magnitude +// separate out the sign and magnitude and return those values to the caller +static void get_offset_sign_magnitude(uint32_t offset, uint32_t *neg_bit_set, uint32_t *tap_val) +{ + *neg_bit_set = (offset & (1 << SIGN_BIT_POS)) >> SIGN_BIT_POS; + *tap_val = offset - (*neg_bit_set << SIGN_BIT_POS); +} +#endif + +static uint32_t map_byte_to_dq(uint32_t *byte) +{ + if (*byte < DQ_NUM_BYTES_PER_DQ) + return AMP_DQ0; + else { + *byte -= DQ_NUM_BYTES_PER_DQ; + return AMP_DQ1; + } +} + +static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val) +{ + if (left_pos_val < right_pos_val) + shim_panic("Memory calibration: find_center_of_eye: Left value (0x%x) is < right value (0x%x)", left_pos_val, right_pos_val); + + // center of 2 signed integers is simply their average + return ((left_pos_val + right_pos_val) / 2); +} + +// Select the value that would include the other value in the eye +static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t min_or_max) +{ + int32_t retVal = val0; + + // For the right endpoint, select the rightmost value on the number line (max value) + if (min_or_max == MAX_ENDPT) { + retVal = (val0 > val1) ? val0 : val1; + } + // For the left endpoint, select the leftmost value (min value) + else { + retVal = (val0 < val1) ? val0 : val1; + } + + return retVal; +} + +// Starting with Fiji B0, deskew steps are 22% bigger than sdll steps. This function helps convert between the 2 units +static int32_t offset_convert(int32_t offset, uint32_t direction) { + + if ((cfg_params.sdll_scale == 0) || (cfg_params.deskew_scale == 0)) + shim_panic("Memory calibration: Zero value for sdll (%d) or deskew (%d) scaling factor", cfg_params.sdll_scale, cfg_params.deskew_scale); + + if (direction == DIRECTION_DESKEW_TO_SDLL) + return ((offset * cfg_params.sdll_scale + (cfg_params.deskew_scale >> 1)) / cfg_params.deskew_scale); + else + return ((offset * cfg_params.deskew_scale + (cfg_params.sdll_scale >> 1)) / cfg_params.sdll_scale); +} diff --git a/drivers/apple/amp_v3/iboot/amp_v3_shim.c b/drivers/apple/amp_v3/iboot/amp_v3_shim.c new file mode 100644 index 0000000..a4a1895 --- /dev/null +++ b/drivers/apple/amp_v3/iboot/amp_v3_shim.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "amp_v3_shim.h" + +// This array will hold the contents of memory that will be used for dq calibration +// static uint8_t dqcal_saved_data[AMC_NUM_RANKS][sizeof(DQ_PRBS7_PATTERNS) * AMC_NUM_CHANNELS]__aligned(32); + +static void shim_save_restore_memory_region(uint32_t save_or_restore); + +/////////////////////////////////////////////////////////////////////////////// +////// Local functions +/////////////////////////////////////////////////////////////////////////////// + +// Before starting dq calibration, saves the contents of dram region that will be written to with calibration patterns. +// After calibration is complete, restores the contents back to DRAM. +static void shim_save_restore_memory_region(uint32_t save_or_restore) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +////// Global functions +/////////////////////////////////////////////////////////////////////////////// + +void shim_init_calibration_params(struct amp_calibration_params *cfg_params) +{ + // Set the number of channels and ranks on this target + cfg_params->num_channels = AMC_NUM_CHANNELS; + cfg_params->num_ranks = AMC_NUM_RANKS; + + // Fiji A0 has a 1 to 1 deskew to sdll step ratio + if((platform_get_chip_id() == 0x7000) && (platform_get_chip_revision() == CHIP_REVISION_A0)) { + cfg_params->sdll_scale = 1; + cfg_params->deskew_scale = 1; + } +} + +void shim_configure_pre_ca(void) +{ + amc_calibration_start(true); +} + +void shim_enable_rddqcal(bool enable) +{ + amc_enable_rddqcal(enable); +} + +void shim_configure_post_wrlvl(struct amp_calibration_params *cfg_params) +{ + amc_calibration_start(false); +} + +void shim_configure_pre_wrdq(bool resume) +{ + amc_calibration_start(true); + + // ok to keep PSQWQCTL0 and PSQWQCTL1 at their value setup for wrdqcal even for the rddqcal that follows + amc_wrdqcal_start(true); +} + +void shim_configure_post_prbs_rddq(struct amp_calibration_params *cfg_params) +{ + amc_wrdqcal_start(false); + + amc_calibration_start(false); + + // Save off the CA, WrLvl, Rddq, and Wrdq offsets to PMU + if (!(cfg_params->resume)) + calibration_save_restore_regs(CALIB_SAVE, cfg_params->num_channels); +} + +void shim_mrcmd_to_ch_rnk(uint8_t rw, uint8_t channel, uint8_t rank, int32_t reg, uintptr_t val) +{ + amc_mrcmd_to_ch_rnk((amc_mrcmd_op_t) rw, channel, rank, reg, val); +} + +uint64_t shim_compute_dram_addr(uint32_t ch, uint32_t rnk, uint32_t bank, uint32_t row, uint32_t col) +{ + return amc_get_uncached_dram_virt_addr(ch, rnk, bank, row, col); +} + +uint32_t shim_get_consecutive_bytes_perchnrnk(void) +{ + // query AMC for how many consecutive bytes before channel interleaving + return amc_get_consecutive_bytes_perchnrnk(); +} + +void shim_store_memory_calibration(void *cal_values, uint32_t cal_size) +{ + if (power_store_memory_calibration(cal_values, cal_size) == 0) + panic("Unable to save memory calibration values to PMU nvram\n"); +} +void shim_load_memory_calibration(void *cal_values, uint32_t cal_size) +{ + if (power_load_memory_calibration(cal_values, cal_size) == 0) + panic("Unable to load memory calibration values from PMU nvram\n"); +} diff --git a/drivers/apple/amp_v3/iboot/amp_v3_shim.h b/drivers/apple/amp_v3/iboot/amp_v3_shim.h new file mode 100644 index 0000000..4231c8a --- /dev/null +++ b/drivers/apple/amp_v3/iboot/amp_v3_shim.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _AMP_T7000_SHIM_H +#define _AMP_T7000_SHIM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "amp_v3.h" +#include "amp_v3_calibration.h" + +#define AMP_MAX_RD (2) // 4 bytes are split across 2 DQ PHYs with 2 bytes each +#define AMP_MAX_DQ (8) + +#define shim_panic(...) do { calibration_dump_results(SELECT_CAL_ALL, true); panic(__VA_ARGS__); } while(0) +#define shim_printf(...) dprintf(DEBUG_CRITICAL, __VA_ARGS__) +#define CSR_READ(x) *(volatile u_int32_t *) x +#define CSR_WRITE(x, y) *(volatile u_int32_t *) x = y + +// +// "word" for DV requires +1, so for iBoot, should subtract 1 before adding to mem_base +#define MEM_WRITE(mem_base, data, word) *(uint32_t *)(mem_base + ((word-1) << 2)) = data +#define MEM_READ(mem_base, word) *(uint32_t *)(mem_base + ((word-1) << 2)) + +void shim_init_calibration_params(struct amp_calibration_params *cfg_params); +void shim_configure_pre_ca(void); +void shim_enable_rddqcal(bool enable); +void shim_configure_post_wrlvl(struct amp_calibration_params *cfg_params); +void shim_configure_pre_wrdq(bool resume); +void shim_configure_post_prbs_rddq(struct amp_calibration_params *cfg_params); +void shim_mrcmd_to_ch_rnk(uint8_t rw, uint8_t channel, uint8_t rank, int32_t reg, uintptr_t val); +uint64_t shim_compute_dram_addr(uint32_t ch, uint32_t rnk, uint32_t bank, uint32_t row, uint32_t col); +uint32_t shim_get_consecutive_bytes_perchnrnk(void); +void shim_store_memory_calibration(void *cal_values, uint32_t cal_size); +void shim_load_memory_calibration(void *cal_values, uint32_t cal_size); + +struct amp_per_freq { + uint32_t caoutdllscl; + uint32_t dqsindllscl; + uint32_t rdcapcfg; +}; + +struct amp_params { + struct amp_per_freq freq[AMP_FREQUENCY_SLOTS]; + uint32_t dqdqsds; + uint32_t nondqds; + uint32_t ampclk; +}; + +#include + +#endif /* _AMP_T7000_SHIM_H */ diff --git a/drivers/apple/amp_v3/include/amp_v3.h b/drivers/apple/amp_v3/include/amp_v3.h new file mode 100644 index 0000000..84f6357 --- /dev/null +++ b/drivers/apple/amp_v3/include/amp_v3.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _AMP_T7000_H +#define _AMP_T7000_H + +#define AMP_FREQUENCY_SLOTS (4) + +/* _t: type, DQ0, DQ1, or CA */ +/* _c: channel, 0 or 1 */ +#define AMP_DQ0 (0) +#define AMP_DQ1 (1) +#define AMP_CA (2) + +#define rAMP_AMPEN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x000) +#define rAMP_AMPCLK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x004) +#define rAMP_AMPINIT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x008) +#define rAMP_AMPVER(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x00C) + +#define rAMP_IMPCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x080) +#define rAMP_IMPOVRRD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x084) +#define rAMP_IMPAUTOCAL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x088) +#define rAMP_IMPCALPHYUPDT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x08C) +#define rAMP_IMPCALCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x090) +#define rAMP_DRAMSIGDLY(_t,_c,_n) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x094 + ((_n) * 4)) +#define rAMP_NONDQDS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x098) +#define rAMP_DQDQSDS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x09C) +#define rAMP_DIFFMODE_FREQ(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x0A0 + ((_f) * 4)) +#define rAMP_DQFLTCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x0B0) + +#define rAMP_RDCAPCFG_FREQ(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x100 + ((_f) * 4)) +#define rAMP_DQSPDENALWYSON(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x110) +#define rAMP_DQSPDRES(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x114) +#define rAMP_RDFIFOPTRSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x118) +#define rAMP_CALDQMSK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x11C) +#define rAMP_CALPATCFG(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x120 - ((_t >> 1) * 0x10)) +#define rAMP_DQTRNCFG(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x124 - ((_t >> 1) * 0x10)) +#define rAMP_DQTRNCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x128 - ((_t >> 1) * 0x10)) +#define rAMP_DQTRNSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x12C - ((_t >> 1) * 0x10)) + +#define rAMP_DLLEN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x180) +#define rAMP_DLLUPDTCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x184) +#define rAMP_MDLLOVRRD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x188 + ((_t >> 1) * 4)) +#define rAMP_MDLLCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x18C - ((_t >> 1) * 4)) +#define rAMP_DLLLOCKTIM(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x190) +#define rAMP_DLLLOCKCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x194) +#define rAMP_DLLUPDTINTVL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x198) +#define rAMP_DLLUPDTCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x19C) +#define rAMP_DLLSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x1A0) +#define rAMP_DQSINDLLSCL_FREQ(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x1B8 + ((_f) * 4)) +#define rAMP_CAOUTDLLSCL_FREQ(_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x1B8 + ((_f) * 4)) +// +#define rAMP_TESTMODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x200 + ((_t >> 1) * 0x180)) + +#define rAMP_WRDQDESKEW_CTRL(_t,_c,_r,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x400 + ((_r)*0x28) + ((_d)*4)) +#define rAMP_WRDQSDESKEW_CTRL(_t,_c,_r) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x420 + ((_r)*0x28)) +#define rAMP_WRDMDESKEW_CTRL(_t,_c,_b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x424 + ((_b)*0x28)) +#define rAMP_RDDQDESKEW_CTRL(_t,_c,_r,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x450 + ((_r)*0x28) + ((_d)*4)) +#define rAMP_RDDQSDESKEW_CTRL(_t,_c,_r) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x470 + ((_r)*0x28)) +#define rAMP_RDDMDESKEW_CTRL(_t,_c,_r) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x474 + ((_r)*0x28)) + +#define rAMP_CADESKEW_CTRL(_c,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x500 + ((_d)*4)) +#define rAMP_CSDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x528) +#define rAMP_CKEDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x52C) +#define rAMP_CKDESKEW_CTRL(_c,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x530 + ((_d)*4)) + +#define rAMP_DQSDLLCTRL_WR(_t,_c,_b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x600 + ((_b)*0x08)) +#define rAMP_DQSDLLCTRL_RD(_t,_c,_b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x610 + ((_b)*0x08)) +#define rAMP_DQWRLVLTIM(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x700) +#define rAMP_DQWRLVLDLYCHAINCTRL(_t,_c,_b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x704 + ((_b)*0x04)) +#define rAMP_DQWRLVLSDLLCODE(_t,_c,_b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x70C + ((_b)*0x04)) +#define rAMP_DQWRLVLRUN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x714) +#define rAMP_DQWRLVLDATA(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x718) + +#define rAMP_CASDLLCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x700) +#define rAMP_CAWRLVLSDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x800) +#define rAMP_CAWRLVLCLKDLYSEL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x804) + +#define rAMP_CACALCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x800 + ((_t >> 1) * 0x100)) +#define rAMP_CACALMASK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x804) +#define rAMP_CACALCABYTESEL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x808) +#define rAMP_CACALCAMAP0(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x80C) +#define rAMP_CACALCAMAP1(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x810) +#define rAMP_CACALCAMAP2(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x814) +#define rAMP_CACALPAT(_t,_c,_p) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x818 + ((_t >> 1) * 0xEC) + ((_p)*0x04)) +#define rAMP_CACALRUN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x838 + ((_t >> 1) * 0xEC)) +#define rAMP_CACALRESULT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x83C) + +#define rAMP_DQCALCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x900) +#define rAMP_DQCALRUN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x908) +#define rAMP_DQCALRESULT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0x90C) + +#define rAMP_DQODTVREF_F(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQCA_SPACING) + 0xB00 + ((_f)*0x04)) + +#define rAMP_CAPHYUPDTREQ(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xB00) +#define rAMP_CAPHYUPDTSTATUS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xB04) + +// Some bit definitions +#define CACALRUN_CACALMODE (1 << 16) +#define CACALRUN_RUNCACAL (1 << 0) +#define TESTMODE_FORCECKELOW (1 << 8) + +#define SIGN_BIT_POS (6) + +#define AMP_MAX_RANKS_PER_CHAN (2) + +#endif /* _AMP_T7000_H */ diff --git a/drivers/apple/amp_v3/include/amp_v3_calibration.h b/drivers/apple/amp_v3/include/amp_v3_calibration.h new file mode 100644 index 0000000..51add3a --- /dev/null +++ b/drivers/apple/amp_v3/include/amp_v3_calibration.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AMP_V3_CALIBRATION_H +#define __AMP_V3_CALIBRATION_H + +#define AMP_DQ_PER_CHAN 2 + +#define AMP_MAX_PATTERNS 8 + +#define CALIB_SAVE 0 +#define CALIB_RESTORE 1 +#define CALIB_PMU_BYTES 400 +// Each register is saved as 1 byte in the array. We will save 1 offset per bit, where offset = SDLL + deskew. +// Number of bytes to save per channel = 10 CA bit offsets + 1 CK/CKE/CS deskew + 5 WrLvl SDLLs +// + 32 RDDQ deskews + 32 WRDQ deskews = 80 +#define CALIB_NUM_BYTES_TO_SAVE (AMC_NUM_CHANNELS * (80)) + +#define CA_NUM_BITS 10 +#define CA_ALL_BITS ((1 << CA_NUM_BITS) - 1) +#define CA_NUM_PATTERNS 64 +// +#define DELIMIT_POS_ADJ_CASDLL 6 +#define DELIMIT_POS_ADJ_WRDQSDLL 6 + +#define CSBIT (CA_NUM_BITS) +#define CKBIT (CA_NUM_BITS + 1) +#define CKEBIT (CA_NUM_BITS + 2) +#define CASDLLBIT (CA_NUM_BITS + 3) + +#define CACAL_MAX_SWLOOPS (8) + +#define MR_READ 0 +#define MR_WRITE 1 + +#define MR2 0x02 +#define MR5 0x05 +#define MR41 0x29 +#define MR42 0x2A +#define MR48 0x30 + +#define MIN_ENDPT 0 +#define MAX_ENDPT 1 + +/* defines for conversion between sdll and deskew steps */ +#define DIRECTION_DESKEW_TO_SDLL 0 +#define DIRECTION_SDLL_TO_DESKEW 1 + +#define CA_MAX_DESKEW_OFFSET 29 +#define MAX_DESKEW_PROGRAMMED 31 +#define MAX_SDLL_VAL 63 +#define MIN_SDLL_VAL 24 +#define FINER_STEP_SZ 1 +#define COARSE_STEP_SZ 4 +#define SOLID_PASS_DETECT 8 +#define DLLVAL_BITS 0x7F +#define DESKEW_CTRL_BITS 0x1F +#define SDLL_NUM_BITS 7 +#define DESKEW_NUM_BITS 5 +#define RD_LATENCY_ENCODE 26 + +// maximum possible loops in the hw +#define RDDQ_LOOPCNT 63 +#define DQ_NUM_BYTES 4 +#define DQ_NUM_BYTES_PER_DQ 2 +#define DQ_NUM_BITS_PER_BYTE 8 +#define DQ_TOTAL_BITS (DQ_NUM_BYTES * DQ_NUM_BITS_PER_BYTE) +#define DQ_MAX_DESKEW_PER_BIT 29 +#define MAX_CAWRLVL_CODE 127 +#define MAX_DQWRLVL_CODE 127 +#define DQ_NUM_PATTERNS 128 +// The number of bytes below is consecutive for a given ch, rnk, bank, and row (interleaving starts after these bytes) +//#define DQ_CONSECUTIVE_BYTES_PER_CHRNK 256 +#define DQ_BYTES_PER_COL 4 // That makes for 64 consecutive columns (or words) +// the bank and row numbers where patterns will be written +#define DQ_ROW 0 +#define DQ_BANK 0 +#define DQ_ADDR_RANK_BIT 16 // RIBI2 addressing for dual rank devices + +// Calibration operation selection +#define SELECT_CACAL 0x1 +#define SELECT_WRLVLCAL 0x2 +#define SELECT_RDDQCAL 0x4 +#define SELECT_WRDQCAL 0x8 +#define SELECT_RDDQCAL2 0x10 +#define SELECT_CAL_ALL (SELECT_RDDQCAL2 | SELECT_WRDQCAL | SELECT_RDDQCAL | SELECT_WRLVLCAL | SELECT_CACAL) + +// This defintion is put here for non-iBoot compilation environments +#ifndef __abs +#define __abs(x) (((x) < 0) ? -(x) : (x)) +#endif + +// Macros to change format between signed integer value and offset with sign and magnitude +#define INT_TO_OFFSET(val) ((((val < 0) ? 1 : 0) << SIGN_BIT_POS) | __abs(val)) +#define OFFSET_TO_INT(val) ((val & ~(1 << SIGN_BIT_POS)) * ((val & (1 << SIGN_BIT_POS)) ? -1 : 1)) + +void calibration_ca_rddq_wrlvl(bool resume); +void calibration_wrdq_rddq(bool resume); +void calibration_save_restore_regs(uint32_t save_or_restore, uint32_t channels); +void calibration_dump_results(uint32_t operations, bool dump_passing_points); + +struct amp_calibration_params { + uint32_t num_channels; + uint32_t num_ranks; + bool resume; + uint32_t cacalib_hw_loops; + uint32_t cacalib_sw_loops; + + /* + * Starting with Fiji B0, 1 deskew step is ~22% bigger than 1 sdll step. + * Fiji B0 / Capri B0 should define deskew_scale to 100 and sdll_scale to 122 (or some combo of numbers that indicates 22% increase), + * while Fiji A0 should define 1 and 1. + */ + int32_t sdll_scale; + int32_t deskew_scale; + + // SEG specific flags + bool dv_params_valid; // DV flag + bool dv_randomize; // flag to be used by DV to randomize some register values for DV purposes + uint32_t dbg_calib_mode; // flag to be used by SEG to skip calibration operations for debug purposes +}; + + +#endif /* ! __AMP_V3_CALIBRATION_H */ diff --git a/drivers/apple/amp_v3/rules.mk b/drivers/apple/amp_v3/rules.mk new file mode 100644 index 0000000..0a80bde --- /dev/null +++ b/drivers/apple/amp_v3/rules.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2010-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_HW_AMP=1 + +# Set ENV_IBOOT for calibration code that is shared with SEG +OPTIONS += ENV_IBOOT + +ALL_OBJS += \ + $(LOCAL_DIR)/amp_v3.o \ + $(LOCAL_DIR)/iboot/amp_v3_shim.o \ + $(LOCAL_DIR)/amp_v3_calibration.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/anc/anc_bootrom.c b/drivers/apple/anc/anc_bootrom.c new file mode 100644 index 0000000..26ac380 --- /dev/null +++ b/drivers/apple/anc/anc_bootrom.c @@ -0,0 +1,528 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "anc_bootrom.h" +#include "anc_bootrom_private.h" + +#define NAND_BOOTBLOCK_OFFSET 2 + +#define NAND_BOOT_MIN_WRITE_CYCLE_NANOS 50 +#define NAND_BOOT_MIN_READ_CYCLE_NANOS 50 +#define NAND_BOOT_MIN_CA_CYCLE_NANOS 50 +#define NAND_BOOT_MIN_WRITE_SETUP_NANOS 20 +#define NAND_BOOT_MIN_WRITE_HOLD_NANOS 20 +#define NAND_BOOT_MIN_READ_SETUP_NANOS 20 +#define NAND_BOOT_MIN_READ_HOLD_NANOS 20 +#define NAND_BOOT_MIN_CA_SETUP_NANOS 20 +#define NAND_BOOT_MIN_CA_HOLD_NANOS 20 + +#define T_CERDY_CYCLES 2675 // 50us @ 53.5MHz + +#define ANC_TIMEOUT_MICROS 1000000UL // Applies to reg status waits - not tRST timeout +#define T_PURST_USEC (10 * 1000) // 10ms + +anc_t g_boot_anc[ANC_BOOT_CONTROLLERS]; + +static bool anc_boot_init_minimal(anc_t *anc, uint32_t interface); +static void anc_configure_pins(void); +static void anc_boot_reset(anc_t *anc); +static bool anc_boot_nand_reset(int busesToReset); +static int anc_boot_read_boot_pages(uint32_t valid_controllers, void *data, size_t *size); +static void anc_boot_set_init_timings(anc_t *anc); + +int anc_bootrom_init(bool reset_devices, int resetMode) +{ + int i; + int busesToReset; + + if (resetMode == ANC_BOOT_MODE_RESET_ALL_CONTROLLERS) { + busesToReset = ANC_BOOT_CONTROLLERS; + } else if (resetMode == ANC_BOOT_MODE_RESET_ONE_CONTROLLER) { + busesToReset = 1; + } else { + return -1; + } + + anc_configure_pins(); + + for (i = 0; i < ANC_BOOT_CONTROLLERS; i++) + { + if (!anc_boot_init_minimal(&g_boot_anc[i], i)) + { + dprintf(DEBUG_INFO, "failed: unable to initialize ANC%d\n", i); + return -1; + } + } + + if (reset_devices && !anc_boot_nand_reset(busesToReset)) + { + dprintf(DEBUG_INFO, "failed: unable to reset NAND devices\n"); + return -1; + } + + return 0; +} + +static void anc_configure_pins() +{ + uint32_t *npl = (uint32_t *)ANS_PPN_N_PL_BASE_ADDR; + anc_npl_wr(npl, R_PPNNPL_PPN0_CLE, M_PPNNPL_PPN0_CLE_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN0_ALE, M_PPNNPL_PPN0_ALE_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN0_REN, M_PPNNPL_PPN0_REN_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN0_WEN, M_PPNNPL_PPN0_WEN_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN0_CEN, M_PPNNPL_PPN0_CEN_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN0_IO, (V_PPNNPL_PPN0_IO_INPUT_ENABLE(0xFF) | + V_PPNNPL_PPN0_IO_PULL_ENABLE(0xFF))); +#if ANC_TOGGLE_SUPPORTED == 1 + anc_npl_wr(npl, R_PPNNPL_PPN0_DQS, (M_PPNNPL_PPN0_DQS_INPUT_ENABLE | + M_PPNNPL_PPN0_DQS_PULL_ENABLE)); +#endif + anc_npl_wr(npl, R_PPNNPL_PPN0_DS, V_PPNNPL_PPN0_DS_DRIVE_STRENGTH(ANC_PPNNPL_DS_DRIVE_STRENGTH)); + anc_npl_wr(npl, R_PPNNPL_CONFIG, M_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN); +#if APPLICATION_SECUREROM && defined(ANC_PPNNPL_INPUT_SELECT_SCHMITT) + // N56, High power on 1V8_H7P_IO - rail - PPN_INPUT_SELECT + anc_npl_wr(npl, R_PPNNPL_PPN0_INPUT_SELECT, M_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT | + M_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT); +#endif + +#if ANC_BOOT_CONTROLLERS > 1 + anc_npl_wr(npl, R_PPNNPL_PPN1_CLE, M_PPNNPL_PPN1_CLE_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN1_ALE, M_PPNNPL_PPN1_ALE_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN1_REN, M_PPNNPL_PPN1_REN_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN1_WEN, M_PPNNPL_PPN1_WEN_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN1_CEN, M_PPNNPL_PPN1_CEN_OUTPUT_ENABLE); + anc_npl_wr(npl, R_PPNNPL_PPN1_IO, (V_PPNNPL_PPN1_IO_INPUT_ENABLE(0xFF) | + V_PPNNPL_PPN1_IO_PULL_ENABLE(0xFF))); +#if ANC_TOGGLE_SUPPORTED == 1 + anc_npl_wr(npl, R_PPNNPL_PPN1_DQS, (M_PPNNPL_PPN1_DQS_INPUT_ENABLE | + M_PPNNPL_PPN1_DQS_PULL_ENABLE)); +#endif + anc_npl_wr(npl, R_PPNNPL_PPN1_DS, V_PPNNPL_PPN1_DS_DRIVE_STRENGTH(ANC_PPNNPL_DS_DRIVE_STRENGTH)); +#if APPLICATION_SECUREROM && defined(ANC_PPNNPL_INPUT_SELECT_SCHMITT) + // N56, High power on 1V8_H7P_IO - rail - PPN_INPUT_SELECT + anc_npl_wr(npl, R_PPNNPL_PPN1_INPUT_SELECT, M_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT | + M_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT); +#endif +#endif +} + +static bool anc_boot_init_minimal(anc_t *anc, uint32_t interface) +{ +#if ANC_BOOT_CONTROLLERS > 1 + anc->regs = (uint32_t *)((interface == 0) ? ANS_ANC_0_BASE_ADDR : ANS_ANC_1_BASE_ADDR); +#else + anc->regs = (uint32_t *)ANS_ANC_BASE_ADDR; + if (interface > 0) + { + return false; + } +#endif + if (interface == 0) + { + clock_gate(CLK_ANS, true); +#ifdef WITH_ANS_DLL + clock_gate(CLK_ANS_DLL, true); +#endif + } + anc_boot_reset(anc); + anc_boot_set_init_timings(anc); + + anc->bus_id = interface; + anc->initialized = true; + anc->pages_per_block = NAND_BOOT_PAGES_PER_BLOCK; + anc->bytes_per_meta = NAND_BOOT_BYTES_PER_META; + anc->meta_words = NAND_BOOT_BYTES_PER_META / sizeof(uint32_t); + anc->bytes_per_page = NAND_BOOT_BYTES_PER_PAGE; + anc->logical_page_size = NAND_BOOT_LOGICAL_PAGE_SIZE; + anc->lbas_per_page = NAND_BOOT_BYTES_PER_PAGE / NAND_BOOT_LOGICAL_PAGE_SIZE; + + return true; +} + +static void anc_boot_reset(anc_t *anc) +{ + anc_wr(anc, R_ANC_LINK_CONFIG, (V_ANC_LINK_CONFIG_ENABLE_CRC(0) | + V_ANC_LINK_CONFIG_DDR_MODE(0))); + anc_wr(anc, R_ANC_LINK_CMD_TIMEOUT, (V_ANC_LINK_CMD_TIMEOUT_VALUE(60 * 1000 * 1000) | + V_ANC_LINK_CMD_TIMEOUT_ENABLE(1))); + anc_wr(anc, R_ANC_DMA_CONTROL, V_ANC_DMA_CONTROL_START(1)); + anc_wr(anc, R_ANC_LINK_CONTROL, V_ANC_LINK_CONTROL_START(1)); +} + +static void anc_boot_set_init_timings(anc_t *anc) +{ + // All timings are fixed and recommend by DV: + anc_wr(anc, R_ANC_LINK_SDR_DATA_TIMING, (V_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME(ANC_LINK_SDR_REN_HOLD_TIME) | + V_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME(ANC_LINK_SDR_REN_SETUP_TIME) | + V_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME(ANC_LINK_SDR_WEN_HOLD_TIME) | + V_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME(ANC_LINK_SDR_REN_SETUP_TIME))); + anc_wr(anc, R_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING, + (V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME(ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_HOLD_TIME) | + V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME(ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_SETUP_TIME))); + anc_wr(anc, R_ANC_LINK_READ_STATUS_CONFIG, (V_ANC_LINK_READ_STATUS_CONFIG_POSITION(0x40) | + V_ANC_LINK_READ_STATUS_CONFIG_POLARITY(0x40) | + V_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY(10) | + V_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY(8))); + + anc_wr(anc, R_ANC_LINK_SDR_TIMING, + (V_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY(ANC_LINK_SDR_DATA_CAPTURE_DELAY) | + V_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME(ANC_LINK_SDR_CLE_ALE_SETUP_TIME) | + V_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME(0))); +} + +static bool anc_boot_nand_reset(int busesToReset) +{ + bool ret; + int controller; + anc_t *anc; + const uint32_t int_mask = (M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG | + M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE | + M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT); + uint32_t int_status; + utime_t current_time; + + // Wait 10ms after SoC reset to ensure we don't violate tPURST + current_time = system_time(); + if (current_time < T_PURST_USEC) + { + task_sleep(T_PURST_USEC - current_time); + } + + // First, issue a reset on all CEs attached to each bus + for (controller = 0; controller < busesToReset; controller++) + { + anc = &g_boot_anc[controller]; + + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(T_CERDY_CYCLES)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__RESET)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(0)); + } + + // Wait for bus 0, ce 0 to complete + anc = &g_boot_anc[0]; + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__LOW_POWER_READ_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_STATUS(0, PPN_LOW_POWER_STATUS__READY, PPN_LOW_POWER_STATUS__READY)); + anc_boot_put_link_command(anc, LINK_COMMAND__SEND_INTERRUPT(0, 0)); + + int_status = anc_boot_wait_interrupt(anc, int_mask); + if (!int_status) + { + // Timeout waiting for any status bits (including timeout bit - if we hit this, the ANC hw timeout + // parts aren't working right + dprintf(DEBUG_INFO, "Timeout waiting for CHAN_INT_STATUS != 0 - this should never happen\n"); + return false; + } + + if (G_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG(int_status)) + { + // Successful status read + ret = true; + } + else + { + // Timeout or invalid status + dprintf(DEBUG_INFO, "Unexpected status 0x%08X\n", int_status); + dprintf(DEBUG_INFO, "NAND Status: 0x%02X\n", anc_rd(anc, R_ANC_LINK_NAND_STATUS)); + ret = false; + } + + return ret; +} + +bool anc_bootrom_read_phys_page(uint32_t band, + uint32_t dip, + uint32_t page, + uint32_t num_lbas, + void *data, + uint32_t *meta) +{ + anc_t *anc = &g_boot_anc[0]; + const uint32_t intmask = (M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG | + M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT | + M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE); + uint32_t intstatus; + unsigned int lba; + addr_t paddr; + bool ret = true; + + paddr = mem_static_map_physical((addr_t)data); + if (!paddr) + { + dprintf(DEBUG_INFO, "No buffer\n"); + return false; + } + + if ((paddr & (16 - 1)) != 0) + { + dprintf(DEBUG_INFO, "ANC buffers must be 16 byte aligned\n"); + return false; + } + if (!meta) + { + dprintf(DEBUG_INFO, "No meta buffer\n"); + return false; + } + if (num_lbas == 0) + { + dprintf(DEBUG_INFO, "Invalid num_lbas %d\n", num_lbas); + return false; + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, data, NAND_BOOT_LOGICAL_PAGE_SIZE * num_lbas); +#endif + + anc_boot_put_dma_command(anc, DMA_COMMAND_CONFIG(DMA_DIRECTION_N2M, false)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__READ)); + + // Can't use LINK_CMD_ADDR6: rdar://problem/10941493 + anc_boot_put_link_command(anc, LINK_COMMAND__OPCODE(LINK_CMD_OP_ADDR6) | ((page & 0xFF) << 16)); + anc_boot_put_link_command(anc, page >> 8); + + anc_boot_put_link_command(anc, LINK_COMMAND__CMD2(NAND_CMD__READ_CONFIRM, NAND_CMD__READ_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_STATUS(0x00, + (PPN_LOW_POWER_STATUS__READY | + PPN_LOW_POWER_STATUS__FAIL), + PPN_LOW_POWER_STATUS__READY)); + + // Wait 27 clocks for RW turnaround + anc_boot_put_link_command(anc, LINK_COMMAND__OPCODE(LINK_CMD_OP_WAIT_TIME) | 0x1b); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__READ)); + anc_boot_put_link_command(anc, LINK_COMMAND__OPCODE(LINK_CMD_OP_WAIT_TIME) | 0x1b); + for (lba = 0; lba < num_lbas; lba++) + { + anc_boot_put_link_command(anc, LINK_COMMAND__READ_PIO(NAND_BOOT_BYTES_PER_META, false, false)); + if (lba == (num_lbas - 1)) + { + anc_boot_put_link_command(anc, LINK_COMMAND__SEND_INTERRUPT(0, 0)); + } + anc_boot_put_link_command(anc, LINK_COMMAND__READ_DMA(NAND_BOOT_LOGICAL_PAGE_SIZE, false, false)); + anc_boot_put_dma_command(anc, DMA_COMMAND_BUFDESC(NAND_BOOT_LOGICAL_PAGE_SIZE, + (uint64_t)paddr + lba * NAND_BOOT_LOGICAL_PAGE_SIZE)); + } + + anc_boot_put_dma_command(anc, DMA_COMMAND_FLAG(0, 0)); + + intstatus = anc_boot_wait_interrupt(anc, intmask); + if (!intstatus) + { + dprintf(DEBUG_INFO, "Timeout waiting for CHAN_INT_STATUS != 0 - this should never happen\n"); + return false; + } + + // We've either timed out or gotten our status by now + if (intstatus & M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) + { + // Timeout waiting for status: flush LINK CmdQ and return error + dprintf(DEBUG_INFO, "Timeout waiting for NAND status\n"); + anc_wr(anc, R_ANC_LINK_CONTROL, M_ANC_LINK_CONTROL_RESET_CMDQ); + return false; + } + else if (intstatus & M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) + { + // Invalid status (probably has error bit set). Reset CmdQ and return error + dprintf(DEBUG_INFO, "Invalid NAND status 0x%02X\n", anc_rd(anc, R_ANC_LINK_NAND_STATUS)); + anc_wr(anc, R_ANC_LINK_CONTROL, M_ANC_LINK_CONTROL_RESET_CMDQ); + + return false; + } + + // We've got a good status and metadata should be available now. + + for (lba = 0; lba < num_lbas; lba++) + { + uint32_t meta_index; + for (meta_index = 0; meta_index < (NAND_BOOT_BYTES_PER_META/ sizeof(uint32_t)); meta_index++) + { + uint32_t meta_word = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + if ((meta_index == 0) && (meta_word != meta[0])) + { + dprintf(DEBUG_INFO, "Invalid meta: expected 0x%08X got 0x%08X\n", meta[0], meta_word); + ret = false; + } + } + } + +#if APPLICATION_SECUREROM + if (!anc_boot_wait_reg(anc, R_ANC_CHAN_INT_STATUS, + M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG, + M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG)) + { + dprintf(DEBUG_INFO, "Timeout waiting for DMA to complete\n"); + return false; + } +#else // APPLICATION_SECUREROM + intstatus = anc_boot_wait_interrupt(anc, M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG | M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT); + if (!intstatus || (intstatus & M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT)) + { + dprintf(DEBUG_INFO, "Timeout waiting for DMA to complete - 0x%08x\n", intstatus); + return false; + } +#endif // APPLICATION_SECUREROM + + anc_wr(anc, R_ANC_CHAN_INT_STATUS, M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, data, NAND_BOOT_LOGICAL_PAGE_SIZE * num_lbas); +#endif + + return ret; +} + +void anc_boot_put_link_command(anc_t *anc, uint32_t value) +{ +#if APPLICATION_SECUREROM + anc_boot_wait_reg(anc, R_ANC_CHAN_LINK_CMDQ_FIFO_STATUS, M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL, 0); + anc_wr(anc, R_ANC_CHAN_LINK_CMDQ_FIFO, value); +#else // APPLICATION_SECUREROM + if (anc_boot_wait_reg_int_timeout(anc, R_ANC_CHAN_LINK_CMDQ_FIFO_STATUS, M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL, 0, M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT)) + { + anc_wr(anc, R_ANC_CHAN_LINK_CMDQ_FIFO, value); + } + else + { + dprintf(DEBUG_INFO, "Timeout waiting for room in link command FIFO\n"); + } +#endif // APPLICATION_SECUREROM +} + +void anc_boot_put_dma_command(anc_t *anc, uint64_t value) +{ +#if APPLICATION_SECUREROM + anc_boot_wait_reg(anc, R_ANC_CHAN_LINK_CMDQ_FIFO_STATUS, M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL, 0); + anc_wr(anc, R_ANC_CHAN_DMA_CMDQ_FIFO, value & 0xFFFFFFFFUL); + anc_wr(anc, R_ANC_CHAN_DMA_CMDQ_FIFO, (value >> 32UL)); +#else // APPLICATION_SECUREROM + if (anc_boot_wait_reg_int_timeout(anc, R_ANC_CHAN_LINK_CMDQ_FIFO_STATUS, M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL, 0, M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT)) + { + anc_wr(anc, R_ANC_CHAN_DMA_CMDQ_FIFO, value & 0xFFFFFFFFUL); + anc_wr(anc, R_ANC_CHAN_DMA_CMDQ_FIFO, (value >> 32UL)); + } + else + { + dprintf(DEBUG_INFO, "Timeout waiting for room in DMA command FIFO\n"); + } +#endif // APPLICATION_SECUREROM +} + +// Wait up to ANC_TIMEOUT_MICROS for ((reg & mask) == value) +bool anc_boot_wait_reg(anc_t *anc, uint32_t reg, uint32_t mask, uint32_t value) +{ + utime_t start_time = system_time(); + uint32_t regval; + + do + { + regval = anc_rd(anc, reg); + if ((regval & mask) == value) + { + return true; + } + } while (!time_has_elapsed(start_time, ANC_TIMEOUT_MICROS)); + + return false; +} + +#if !APPLICATION_SECUREROM +// Like anc_boot_wait_reg, but waits until (R_ANC_CHAN_INT_MASK & tomask) to determine the timeout instead of using ANC_TIMEOUT_MICROS. Only used by LLB. +bool anc_boot_wait_reg_int_timeout(anc_t *anc, uint32_t reg, uint32_t mask, uint32_t value, uint32_t tomask) +{ + uint32_t regval, intval; + + do + { + regval = anc_rd(anc, reg); + if ((regval & mask) == value) + { + return true; + } + intval = anc_rd(anc, R_ANC_CHAN_INT_STATUS); + } while (!(intval & tomask)); + + anc_wr(anc, R_ANC_CHAN_INT_STATUS, (intval & tomask)); + + regval = anc_rd(anc, reg); + if ((regval & mask) == value) + { + return true; + } + + return false; +} +#endif // !APPLICATION_SECUREROM + +uint32_t anc_boot_wait_interrupt(anc_t *anc, uint32_t mask) +{ +#if APPLICATION_SECUREROM + utime_t start_time = system_time(); +#endif // APPLICATION_SECUREROM + uint32_t regval; + + do + { + regval = anc_rd(anc, R_ANC_CHAN_INT_STATUS); + if (regval & mask) + { + // Only clear the bits we're looking for + anc_wr(anc, R_ANC_CHAN_INT_STATUS, (regval & mask)); + return regval; + } +#if APPLICATION_SECUREROM + } while (!time_has_elapsed(start_time, ANC_TIMEOUT_MICROS)); +#else // APPLICATION_SECUREROM + } while (1); +#endif // APPLICATION_SECUREROM + + return 0; +} + +static void anc_disable_uid(anc_t *anc) +{ + // The DISABLE_UID bit doesn't work unless AES is enabled. Force a DMA_CONFIG to enable it + anc_boot_put_dma_command(anc, DMA_COMMAND_CONFIG(DMA_DIRECTION_N2M, true)); + + // Wait for AES to become enabled + anc_boot_wait_reg(anc, R_ANC_DMA_STATUS, M_ANC_DMA_STATUS_AES_ENABLED, M_ANC_DMA_STATUS_AES_ENABLED); +#ifdef M_ANC_DMA_UID_CONFIG_DISABLE_UID + // Disable UID1 (doesn't exist on M7) + anc_wr(anc, R_ANC_DMA_UID_CONFIG, M_ANC_DMA_UID_CONFIG_DISABLE_UID); +#endif +} + +void anc_disable_uid_key(void) +{ + int i; + + if (!g_boot_anc[0].initialized) + { + // If we came in here through the DFU path, ANC isn't configured. + anc_bootrom_init(false, ANC_BOOT_MODE_RESET_ALL_CONTROLLERS); + } + + for (i = 0; i < ANC_BOOT_CONTROLLERS; i++) + { + anc_disable_uid(&g_boot_anc[i]); + } +} + diff --git a/drivers/apple/anc/anc_bootrom.h b/drivers/apple/anc/anc_bootrom.h new file mode 100644 index 0000000..fc66fd3 --- /dev/null +++ b/drivers/apple/anc/anc_bootrom.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _ANC_BOOTROM_H_ +#define _ANC_BOOTROM_H_ + +#include + +int anc_bootrom_init(bool reset, int resetMode); +bool anc_bootrom_read_phys_page(uint32_t band, + uint32_t dip, + uint32_t page, + uint32_t num_lbas, + void *data, + uint32_t *meta); +#endif // _ANC_BOOTROM_H_ diff --git a/drivers/apple/anc/anc_bootrom_cmds.h b/drivers/apple/anc/anc_bootrom_cmds.h new file mode 100644 index 0000000..f4a5ba7 --- /dev/null +++ b/drivers/apple/anc/anc_bootrom_cmds.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _ANC_CMDS_H_ +#define _ANC_CMDS_H_ + +#define LINK_CMDQ_SIZE 128 +#define DMA_CMDQ_SIZE 64 // 64b words, not 32b +#define LINK_PIO_READ_FIFO_SIZE 64 + +//////////////////////////////////////////////////////////////////////////////// +// DMA Command Definitions +#define DMA_COMMAND__OPCODE(n) (((n) & 0x7FULL) << 60) +#define DMA_COMMAND__OPCODE__CONFIG (0) +#define DMA_COMMAND__OPCODE__BUFDESC (1) +#define DMA_COMMAND__OPCODE__AES_KEY_IV (2) +#define DMA_COMMAND__OPCODE__AES_UID1_IV (3) +#define DMA_COMMAND__OPCODE__AES_IV (4) +#define DMA_COMMAND__OPCODE__FLAG (5) + +#define DMA_COMMAND_CONFIG__DMA_DIRECTION(n) (((n) & 0x1ULL) << 53) +#define DMA_DIRECTION_M2N (0) +#define DMA_DIRECTION_N2M (1) +#define DMA_COMMAND_CONFIG__PROC_ENABLE_AES(n) (((n) & 0x1ULL) << 54) + +#define DMA_COMMAND_BUFDESC__LENGTH(n) (((n) & 0x1FFFULL) << 40) +#define DMA_COMMAND_BUFDESC__ADDRESS(n) (((n) & 0xFFFFFFFFFFULL) << 0) + +#define DMA_COMMAND_AESKEY__UNWRAP(n) (((n) & 0x1ULL) << 2) +#define DMA_COMMAND_AESKEY__KEY_LEN(n) (((n) & 0x3ULL) << 0) +#define DMA_COMMAND_AESKEY_128_BITS (0) +#define DMA_COMMAND_AESKEY_192_BITS (1) +#define DMA_COMMAND_AESKEY_256_BITS (2) + +#define DMA_COMMAND_FLAG__PAUSE(n) (((n) & 0x1ULL) << 16) +#define DMA_COMMAND_FLAG__CODE(n) (((n) & 0xFFFFULL) << 0) + +#define DMA_COMMAND_CONFIG(dir,aes) \ + (DMA_COMMAND__OPCODE(DMA_COMMAND__OPCODE__CONFIG) | \ + DMA_COMMAND_CONFIG__DMA_DIRECTION(dir) | \ + DMA_COMMAND_CONFIG__PROC_ENABLE_AES(aes)) +#define DMA_COMMAND_BUFDESC(data_bytes,address) \ + (DMA_COMMAND__OPCODE(DMA_COMMAND__OPCODE__BUFDESC) | \ + DMA_COMMAND_BUFDESC__LENGTH(data_bytes) | \ + DMA_COMMAND_BUFDESC__ADDRESS(address)) +#define DMA_COMMAND_AES_KEY_IV(key_len, unwrap_en) \ + (DMA_COMMAND__OPCODE(DMA_COMMAND__OPCODE__AES_KEY_IV) | \ + DMA_COMMAND_AESKEY__KEY_LEN(key_len) | \ + DMA_COMMAND_AESKEY__UNWRAP(unwrap_en)) +#define DMA_COMMAND_FLAG(code,pause) \ + (DMA_COMMAND__OPCODE(DMA_COMMAND__OPCODE__FLAG) | \ + DMA_COMMAND_FLAG__PAUSE(pause) | \ + DMA_COMMAND_FLAG__CODE(code)) + +//////////////////////////////////////////////////////////////////////////////// +// Link Command Definitions +#define LINK_COMMAND__YIELD (1UL << 31) +#define LINK_COMMAND__OPCODE(n) (((n) & 0x3FUL) << 24) + +#define LINK_CMD_OP_DEBUG_DLL 0x00 +#define LINK_CMD_OP_CMD0 0x01 +#define LINK_CMD_OP_CMD1 0x02 +#define LINK_CMD_OP_CMD1_OP 0x03 +#define LINK_CMD_OP_CMD2 0x04 +#define LINK_CMD_OP_CMD2_OP 0x05 +#define LINK_CMD_OP_CMD3 0x06 +#define LINK_CMD_OP_CMD3_OP 0x07 +#define LINK_CMD_OP_CMD4 0x08 +#define LINK_CMD_OP_CMD4_OP 0x09 +#define LINK_CMD_OP_CMD5 0x0A +#define LINK_CMD_OP_CMD5_OP 0x0B +#define LINK_CMD_OP_CMD6 0x0C +#define LINK_CMD_OP_CMD6_OP 0x0D +#define LINK_CMD_OP_CMD7 0x0E +#define LINK_CMD_OP_CMD7_OP 0x0F +#define LINK_CMD_OP_CMD8_OP 0x10 +#define LINK_CMD_OP_ADDR1 0x12 +#define LINK_CMD_OP_ADDR1_OP 0x13 +#define LINK_CMD_OP_ADDR2 0x14 +#define LINK_CMD_OP_ADDR2_OP 0x15 +#define LINK_CMD_OP_ADDR3 0x16 +#define LINK_CMD_OP_ADDR3_OP 0x17 +#define LINK_CMD_OP_ADDR4 0x18 +#define LINK_CMD_OP_ADDR4_OP 0x19 +#define LINK_CMD_OP_ADDR5 0x1A +#define LINK_CMD_OP_ADDR5_OP 0x1B +#define LINK_CMD_OP_ADDR6 0x1C +#define LINK_CMD_OP_ADDR6_OP 0x1D +#define LINK_CMD_OP_ADDR7 0x1E +#define LINK_CMD_OP_ADDR7_OP 0x1F +#define LINK_CMD_OP_ADDR8_OP 0x20 +#define LINK_CMD_OP_READ_RELEASE 0x21 +#define LINK_CMD_OP_CE 0x22 +#define LINK_CMD_OP_CE_OP 0x23 +#define LINK_CMD_OP_READ_DMA 0x24 +#define LINK_CMD_OP_READ_DMA_OP 0x25 +#define LINK_CMD_OP_READ_PIO 0x26 +#define LINK_CMD_OP_READ_PIO_OP 0x27 +#define LINK_CMD_OP_READ_NUL 0x28 +#define LINK_CMD_OP_READ_NUL_OP 0x29 +#define LINK_CMD_OP_READ_STATUS 0x2A +#define LINK_CMD_OP_READ_STATUS_ABORT_ENABLED 0x2B +#define LINK_CMD_OP_WRITE_DMA 0x2C +#define LINK_CMD_OP_WRITE_DMA_OP 0x2D +#define LINK_CMD_OP_WRITE_PIO 0x2E +#define LINK_CMD_OP_WRITE_PIO_OP 0x2F +#define LINK_CMD_OP_WRITE_PIO_IMM 0x30 +#define LINK_CMD_OP_WRITE_PAD 0x32 +#define LINK_CMD_OP_WRITE_PAD_OP 0x33 +#define LINK_CMD_OP_READ_REGISTER 0x34 +#define LINK_CMD_OP_WRITE_REGISTER 0x35 +#define LINK_CMD_OP_POLL_REGISTER 0x36 +#define LINK_CMD_OP_POLL_REGISTER_ABORT_ENABLED 0x37 +#define LINK_CMD_OP_WAIT_TIME 0x38 +#define LINK_CMD_OP_WAIT_TIME_ABORT_ENABLED 0x39 +#define LINK_CMD_OP_WAIT_FOR_INTERRUPT 0x3A +#define LINK_CMD_OP_WAIT_FOR_INTERRUPT_ABORT_ENABLED 0x3B +#define LINK_CMD_OP_SEND_INTERRUPT 0x3C +#define LINK_CMD_OP_MACRO 0x3D +#define LINK_CMD_OP_DPI_OUT 0x3E +#define LINK_CMD_OP_DPI_IN 0x3F + +#define LINK_COMMAND__CE__CE(ce) (((ce) & 0xFFUL) << 0) +#define LINK_COMMAND__CE(ce) (LINK_COMMAND__OPCODE(LINK_CMD_OP_CE) | LINK_COMMAND__CE__CE(ce)) + +#define LINK_COMMAND__CMD__CMD2(n) (((n) & 0xFFUL) << 16) +#define LINK_COMMAND__CMD__CMD1(n) (((n) & 0xFFUL) << 8) +#define LINK_COMMAND__CMD__CMD0(n) (((n) & 0xFFUL) << 0) + +#define LINK_COMMAND__CMD1(cmd1) (LINK_COMMAND__OPCODE(LINK_CMD_OP_CMD1) | LINK_COMMAND__CMD__CMD0(cmd1)) +#define LINK_COMMAND__CMD2(cmd1,cmd2) (LINK_COMMAND__OPCODE(LINK_CMD_OP_CMD2) | \ + LINK_COMMAND__CMD__CMD0(cmd1) | \ + LINK_COMMAND__CMD__CMD1(cmd2)) +#define LINK_COMMAND__CMD3(cmd1,cmd2,cmd3) (LINK_COMMAND__OPCODE(LINK_CMD_OP_CMD3) | \ + LINK_COMMAND__CMD__CMD0(cmd1) | \ + LINK_COMMAND__CMD__CMD1(cmd2) | \ + LINK_COMMAND__CMD__CMD2(cmd3)) + + +#define LINK_COMMAND__ADDR__ADDR2(n) (((n) & 0xFFUL) << 16) +#define LINK_COMMAND__ADDR__ADDR1(n) (((n) & 0xFFUL) << 8) +#define LINK_COMMAND__ADDR__ADDR0(n) (((n) & 0xFFUL) << 0) +#define LINK_COMMAND__ADDR1(addr0) (LINK_COMMAND__OPCODE(LINK_CMD_OP_ADDR1) | \ + LINK_COMMAND__ADDR__ADDR0(addr0)) +#define LINK_COMMAND__ADDR2(addr0,addr1) (LINK_COMMAND__OPCODE(LINK_CMD_OP_ADDR2) | \ + LINK_COMMAND__ADDR__ADDR0(addr0) | \ + LINK_COMMAND__ADDR__ADDR1(addr1)) +#define LINK_COMMAND__ADDR3(addr0,addr1,addr2) (LINK_COMMAND__OPCODE(LINK_CMD_OP_ADDR3) | \ + LINK_COMMAND__ADDR__ADDR0(addr0) | \ + LINK_COMMAND__ADDR__ADDR1(addr1) | \ + LINK_COMMAND__ADDR__ADDR2(addr2)) + +#define LINK_COMMAND__WRITE_DMA__LEN(n) (((n) & 0x7FFFUL) << 0) +#define LINK_COMMAND__WRITE_DMA__CRC_START(n) (((n) & 0x1UL) << 22) +#define LINK_COMMAND__WRITE_DMA__CRC_STOP(n) (((n) & 0x1UL) << 23) +#define LINK_COMMAND__WRITE_DMA(len, crc_start, crc_stop) (LINK_COMMAND__OPCODE(LINK_CMD_OP_WRITE_DMA) | \ + LINK_COMMAND__WRITE_DMA__LEN(len) | \ + LINK_COMMAND__WRITE_DMA__CRC_START(crc_start) | \ + LINK_COMMAND__WRITE_DMA__CRC_STOP(crc_stop)) + +#define LINK_COMMAND__WRITE_PIO__LEN(n) (((n) & 0x7FFFUL) << 0) +#define LINK_COMMAND__WRITE_PIO__CRC_START(n) (((n) & 0x1UL) << 22) +#define LINK_COMMAND__WRITE_PIO__CRC_STOP(n) (((n) & 0x1UL) << 23) +#define LINK_COMMAND__WRITE_PIO(len, crc_start, crc_stop) (LINK_COMMAND__OPCODE(LINK_CMD_OP_WRITE_PIO) | \ + LINK_COMMAND__WRITE_PIO__LEN(len) | \ + LINK_COMMAND__WRITE_PIO__CRC_START(crc_start) | \ + LINK_COMMAND__WRITE_PIO__CRC_STOP(crc_stop)) + +#define LINK_COMMAND__READ_DMA__LEN(n) (((n) & 0x7FFFUL) << 0) +#define LINK_COMMAND__READ_DMA__CRC_START(n) (((n) & 0x1UL) << 22) +#define LINK_COMMAND__READ_DMA__CRC_STOP(n) (((n) & 0x1UL) << 23) +#define LINK_COMMAND__READ_DMA(len, crc_start, crc_stop) (LINK_COMMAND__OPCODE(LINK_CMD_OP_READ_DMA) | \ + LINK_COMMAND__READ_DMA__LEN(len) | \ + LINK_COMMAND__READ_DMA__CRC_START(crc_start) | \ + LINK_COMMAND__READ_DMA__CRC_STOP(crc_stop)) + +#define LINK_COMMAND__READ_PIO__LEN(n) (((n) & 0x7FFFUL) << 0) +#define LINK_COMMAND__READ_PIO__CRC_START(n) (((n) & 0x1UL) << 22) +#define LINK_COMMAND__READ_PIO__CRC_STOP(n) (((n) & 0x1UL) << 23) +#define LINK_COMMAND__READ_PIO(len, crc_start, crc_stop) (LINK_COMMAND__OPCODE(LINK_CMD_OP_READ_PIO) | \ + LINK_COMMAND__READ_PIO__LEN(len) | \ + LINK_COMMAND__READ_PIO__CRC_START(crc_start) | \ + LINK_COMMAND__READ_PIO__CRC_STOP(crc_stop)) + +#define LINK_COMMAND__READ_STATUS__CODE(n) (((n) & 0xFFUL) << 16) +#define LINK_COMMAND__READ_STATUS__MASK(n) (((n) & 0xFFUL) << 8) +#define LINK_COMMAND__READ_STATUS__COND(n) (((n) & 0xFFUL) << 0) +#define LINK_COMMAND__READ_STATUS(code,mask,cond) (LINK_COMMAND__OPCODE(LINK_CMD_OP_READ_STATUS) | \ + LINK_COMMAND__READ_STATUS__CODE(code) | \ + LINK_COMMAND__READ_STATUS__MASK(mask) | \ + LINK_COMMAND__READ_STATUS__COND(cond)) + +#define LINK_COMMAND__SEND_INTERRUPT__PAUSE(n) (((n) & 0x1UL) << 23) +#define LINK_COMMAND__SEND_INTERRUPT__CODE(n) (((n) & 0xFFFFUL) << 0) +#define LINK_COMMAND__SEND_INTERRUPT(pause,code) (LINK_COMMAND__OPCODE(LINK_CMD_OP_SEND_INTERRUPT) | \ + LINK_COMMAND__SEND_INTERRUPT__PAUSE(pause) | \ + LINK_COMMAND__SEND_INTERRUPT__CODE(code)) + +#define LINK_COMMAND__READ_REGISTER__ADDR(n) (((n) & 0xFFFFFFUL) << 0) +#define LINK_COMMAND__READ_REGISTER(addr) (LINK_COMMAND__OPCODE(LINK_CMD_OP_READ_REGISTER) | \ + LINK_COMMAND__READ_REGISTER__ADDR(addr)) + +#define LINK_COMMAND__WRITE_REGISTER__ADDR(n) (((n) & 0xFFFFFFUL) << 0) +#define LINK_COMMAND__WRITE_REGISTER(addr) (LINK_COMMAND__OPCODE(LINK_CMD_OP_WRITE_REGISTER) | \ + LINK_COMMAND__WRITE_REGISTER__ADDR(addr)) + +#define LINK_COMMAND__WAIT_TIME__CYCLES(n) (((n) & 0xFFFFUL) << 0) +#define LINK_COMMAND__WAIT_TIME(link_cycles) (LINK_COMMAND__OPCODE(LINK_CMD_OP_WAIT_TIME) | \ + LINK_COMMAND__WAIT_TIME__CYCLES((link_cycles))) + +#define LINK_COMMAND__MACRO__LENGTH(n) (((n) & 0xFFUL) << 0) +#define LINK_COMMAND__MACRO__ADDR(n) (((n) & 0xFFUL) << 8) +#define LINK_COMMAND__MACRO__REPEAT(n) (((n) & 0xFFUL) << 16) +#define LINK_COMMAND__MACRO(addr,length,repeat) (LINK_COMMAND__OPCODE(LINK_CMD_OP_MACRO) | \ + LINK_COMMAND__MACRO__LENGTH(length-1) | \ + LINK_COMMAND__MACRO__ADDR(addr) | \ + LINK_COMMAND__MACRO__REPEAT(repeat)) + +#endif // _ANC_CMDS_H_ diff --git a/drivers/apple/anc/anc_bootrom_private.h b/drivers/apple/anc/anc_bootrom_private.h new file mode 100644 index 0000000..2644dbe --- /dev/null +++ b/drivers/apple/anc/anc_bootrom_private.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _ANC_BOOTROM_PRIVATE_H_ +#define _ANC_BOOTROM_PRIVATE_H_ + +#if SUB_PLATFORM_S7002 +# include "anc_bootrom_regs_m7.h" +#else +# include "anc_bootrom_regs.h" +#endif +#include "ppn_npl_regs.h" +#include "anc_bootrom_cmds.h" + +#define ANC_MAX_CES_PER_BUS (1) +#define ANC_NAND_ID_SIZE (6) + +#define NAND_BOOT_PAGES_PER_BLOCK 128 +#define NAND_BOOT_BYTES_PER_META 16 +#define NAND_BOOT_BYTES_PER_PAGE 8192 +#define NAND_BOOT_LOGICAL_PAGE_SIZE 4096 + +// NAND Commands +#define NAND_CMD__RESET ((uint8_t)0xFF) +#define NAND_CMD__READ_ID ((uint8_t)0x90) +#define NAND_CMD__READ_STATUS ((uint8_t)0x70) +#define NAND_CMD__READ ((uint8_t)0x00) +#define NAND_CMD__READ_CONFIRM ((uint8_t)0x30) + +#define NAND_CMD__MULTIPAGE_READ ((uint8_t)0x07) +#define NAND_CMD__MULTIPAGE_READ_LAST ((uint8_t)0x0A) +#define NAND_CMD__MULTIPAGE_READ_CONFIRM ((uint8_t)0x37) +#define NAND_CMD__MULTIPAGE_PROGRAM ((uint8_t)0x87) +#define NAND_CMD__MULTIPAGE_PROGRAM_LAST ((uint8_t)0x8A) +#define NAND_CMD__MULTIPAGE_PROGRAM_CONFIRM ((uint8_t)0x17) +#define NAND_CMD__MULTIPAGE_PREP ((uint8_t)0xB0) +#define NAND_CMD__MULTIPAGE_PREP__CONFIRM ((uint8_t)0xB8) +#define NAND_CMD__MULTIBLOCK_ERASE ((uint8_t)0x67) +#define NAND_CMD__MULTIBLOCK_ERASE_LAST ((uint8_t)0x6A) +#define NAND_CMD__MULTIBLOCK_ERASE_CONFIRM ((uint8_t)0xD7) +#define NAND_CMD__LOW_POWER_READ_STATUS ((uint8_t)0x70) +#define NAND_CMD__GET_NEXT_OPERATION_STATUS ((uint8_t)0x77) +#define NAND_CMD__OPERATION_STATUS ((uint8_t)0x7D) +#define NAND_CMD__READ_SERIAL_OUTPUT ((uint8_t)0x7A) +#define NAND_CMD__CONTROLLER_STATUS ((uint8_t)0x79) +#define NAND_CMD__READ_DEVICE_PARAMETERS ((uint8_t)0x92) +#define NAND_CMD__READ_DEVICE_PARAMETERS_CONFIRM ((uint8_t)0x97) +#define NAND_CMD__SET_FEATURES ((uint8_t)0xEF) +#define NAND_CMD__GET_FEATURES ((uint8_t)0xEE) +#define NAND_CMD__SET_GET_FEATURES_CONFIRM ((uint8_t)0xE7) +#define NAND_CMD__SET_DEBUG_DATA ((uint8_t)0xE9) +#define NAND_CMD__GET_DEBUG_DATA ((uint8_t)0xE8) +#define NAND_CMD__UPDATE_FW ((uint8_t)0xED) +#define NAND_CMD__PPN_STATUS_CONFIRM ((uint8_t)0xED) + +#define PPN_LOW_POWER_STATUS__FAIL (1 << 0) +#define PPN_LOW_POWER_STATUS__READY (1 << 6) +#define PPN_LOW_POWER_STATUS__WRITE_PROTECT_BAR (1 << 7) + +#define PPN_FEATURE__POWER_STATE ((uint16_t)0x0180) + +#define PPN_FEATURE__POWER_STATE__LOW_POWER 0x1 +#define PPN_FEATURE__POWER_STATE__NORMAL_ASYNC 0x2 +#define PPN_FEATURE__POWER_STATE__NORMAL_DDR 0xA +#define PPN_FEATURE__POWER_STATE__STANDBY 0x4 + +#define CHIPID_ADDR (0x00) + +#define PPN_BLOCK_PAIRING__NO_PAIRING (0x00) +#define PPN_BLOCK_PAIRING__EVEN_ODD (0x10) +#define PPN_BLOCK_PAIRING__FOUR_PLANE (0x20) + +#define ROUNDUPTO(num, gran) ((((num) + (gran) - 1) / (gran)) * (gran)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define ANC_BOOT_MAX_TIMING_REG_VALUE (M_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME >> S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME) + +typedef uint8_t anc_chip_id_t[ANC_NAND_ID_SIZE]; + +typedef struct anc_t +{ + uint32_t bus_id; + bool initialized; + uint32_t *regs; + + uint32_t pages_per_block; + uint32_t bytes_per_meta; + uint32_t meta_words; + uint32_t bytes_per_page; + uint32_t logical_page_size; + uint32_t lbas_per_page; + + anc_chip_id_t chip_id; + +} anc_t; + +extern anc_t g_boot_anc[ANC_BOOT_CONTROLLERS]; + +#define anc_wr(anc, reg, val) (*((anc)->regs + ((reg) >> 2)) = (val)) +#define anc_wr64(anc, reg, val) anc_store64((volatile uint64_t *)((anc)->regs + ((reg) >> 2)), (val)) +#define anc_rd(anc, reg) (*(volatile uint32_t *)((uint8_t *)((anc)->regs) + (reg))) +#define anc_npl_wr(npl, reg, val) (*(npl + ((reg) >> 2)) = (val)) + +void anc_boot_put_link_command(anc_t *anc, uint32_t value); +void anc_boot_put_dma_command(anc_t *anc, uint64_t value); +uint32_t anc_boot_wait_interrupt(anc_t *anc, uint32_t mask); +bool anc_boot_wait_reg(anc_t *anc, uint32_t reg, uint32_t mask, uint32_t value); +#if !APPLICATION_SECUREROM +bool anc_boot_wait_reg_int_timeout(anc_t *anc, uint32_t reg, uint32_t mask, uint32_t value, uint32_t tomask); +#endif // !APPLICATION_SECUREROM + +#endif // _ANC_BOOTROM_PRIVATE_H_ diff --git a/drivers/apple/anc/anc_bootrom_regs.h b/drivers/apple/anc/anc_bootrom_regs.h new file mode 100644 index 0000000..6b53c44 --- /dev/null +++ b/drivers/apple/anc/anc_bootrom_regs.h @@ -0,0 +1,2469 @@ + +// +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form +// in whole or in part, without the express written permission of +// Apple Inc. +// +#ifndef __ANC_H__ +#define __ANC_H__ + +#define _MM_MAKEMASK(width, offset) (((1 << (width)) - 1) << (offset)) +#define _MM_MAKEVALUE(value, offset) ((value) << (offset)) +#define _MM_GETVALUE(registerContent, offset, mask) (((registerContent) & (mask))>> (offset)) + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_CHAN_BASE 0x00000000 +#define A_ANC_CHAN_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_CHAN_VERSION 0x00000000 +#define RRV_ANC_CHAN_VERSION 0x00000100 +#define RRM_ANC_CHAN_VERSION 0x00000000 +#define R_ANC_CHAN_CONFIG 0x00000004 +#define RRV_ANC_CHAN_CONFIG 0x00000000 +#define RRM_ANC_CHAN_CONFIG 0x00000000 +#define R_ANC_CHAN_INT_STATUS 0x00000008 +#define RRV_ANC_CHAN_INT_STATUS 0x00000000 +#define RRM_ANC_CHAN_INT_STATUS 0x00000000 +#define R_ANC_CHAN_INT_ENABLE 0x0000000c +#define RRV_ANC_CHAN_INT_ENABLE 0x00000000 +#define RRM_ANC_CHAN_INT_ENABLE 0x00000000 +#define R_ANC_CHAN_DMA_WATERMARKS 0x00000010 +#define RRV_ANC_CHAN_DMA_WATERMARKS 0x00000000 +#define RRM_ANC_CHAN_DMA_WATERMARKS 0x00000000 +#define R_ANC_CHAN_LINK_WATERMARKS 0x00000014 +#define RRV_ANC_CHAN_LINK_WATERMARKS 0x00000000 +#define RRM_ANC_CHAN_LINK_WATERMARKS 0x00000000 +#define R_ANC_CHAN_DMA_CMDQ_FIFO_STATUS 0x00000018 +#define RRV_ANC_CHAN_DMA_CMDQ_FIFO_STATUS 0x00000000 +#define RRM_ANC_CHAN_DMA_CMDQ_FIFO_STATUS 0x00000000 +#define R_ANC_CHAN_LINK_CMDQ_FIFO_STATUS 0x0000001c +#define RRV_ANC_CHAN_LINK_CMDQ_FIFO_STATUS 0x00000000 +#define RRM_ANC_CHAN_LINK_CMDQ_FIFO_STATUS 0x00000000 +#define R_ANC_CHAN_LINK_BYPASS_FIFO_STATUS 0x00000020 +#define RRV_ANC_CHAN_LINK_BYPASS_FIFO_STATUS 0x00000000 +#define RRM_ANC_CHAN_LINK_BYPASS_FIFO_STATUS 0x00000000 +#define R_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS 0x00000024 +#define RRV_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS 0x00000000 +#define RRM_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS 0x00000000 +#define R_ANC_CHAN_DMA_DEBUG_FIFO_STATUS 0x00000028 +#define RRV_ANC_CHAN_DMA_DEBUG_FIFO_STATUS 0x00000000 +#define RRM_ANC_CHAN_DMA_DEBUG_FIFO_STATUS 0x00000000 +#define R_ANC_CHAN_LINK_DEBUG_FIFO_STATUS 0x0000002c +#define RRV_ANC_CHAN_LINK_DEBUG_FIFO_STATUS 0x00000000 +#define RRM_ANC_CHAN_LINK_DEBUG_FIFO_STATUS 0x00000000 +#define R_ANC_CHAN_DMA_CMDQ_FIFO 0x00000100 +#define RRV_ANC_CHAN_DMA_CMDQ_FIFO 0x00000000 +#define RRM_ANC_CHAN_DMA_CMDQ_FIFO 0x00000000 +#define R_ANC_CHAN_LINK_CMDQ_FIFO 0x00000140 +#define RRV_ANC_CHAN_LINK_CMDQ_FIFO 0x00000000 +#define RRM_ANC_CHAN_LINK_CMDQ_FIFO 0x00000000 +#define R_ANC_CHAN_LINK_BYPASS_FIFO 0x00000180 +#define RRV_ANC_CHAN_LINK_BYPASS_FIFO 0x00000000 +#define RRM_ANC_CHAN_LINK_BYPASS_FIFO 0x00000000 +#define R_ANC_CHAN_LINK_PIO_READ_FIFO 0x000001c0 +#define RRV_ANC_CHAN_LINK_PIO_READ_FIFO 0x00000000 +#define RRM_ANC_CHAN_LINK_PIO_READ_FIFO 0x00000000 +#define R_ANC_CHAN_DMA_DEBUG_FIFO 0x00000200 +#define RRV_ANC_CHAN_DMA_DEBUG_FIFO 0x00000000 +#define RRM_ANC_CHAN_DMA_DEBUG_FIFO 0x00000000 +#define R_ANC_CHAN_LINK_DEBUG_FIFO 0x00000240 +#define RRV_ANC_CHAN_LINK_DEBUG_FIFO 0x00000000 +#define RRM_ANC_CHAN_LINK_DEBUG_FIFO 0x00000000 +#define R_ANC_CHAN_LAST 0x00000240 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_CHAN_VERSION +#define rANC_CHAN_CONFIG +#define rANC_CHAN_INT_STATUS +#define rANC_CHAN_INT_ENABLE +#define rANC_CHAN_DMA_WATERMARKS +#define rANC_CHAN_LINK_WATERMARKS +#define rANC_CHAN_DMA_CMDQ_FIFO_STATUS +#define rANC_CHAN_LINK_CMDQ_FIFO_STATUS +#define rANC_CHAN_LINK_BYPASS_FIFO_STATUS +#define rANC_CHAN_LINK_PIO_READ_FIFO_STATUS +#define rANC_CHAN_DMA_DEBUG_FIFO_STATUS +#define rANC_CHAN_LINK_DEBUG_FIFO_STATUS +#define rANC_CHAN_DMA_CMDQ_FIFO +#define rANC_CHAN_LINK_CMDQ_FIFO +#define rANC_CHAN_LINK_BYPASS_FIFO +#define rANC_CHAN_LINK_PIO_READ_FIFO +#define rANC_CHAN_DMA_DEBUG_FIFO +#define rANC_CHAN_LINK_DEBUG_FIFO +#define rANC_CHAN_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_DMA_BASE 0x00001000 +#define A_ANC_DMA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_DMA_CONFIG 0x00001000 +#define RRV_ANC_DMA_CONFIG 0x00000000 +#define RRM_ANC_DMA_CONFIG 0x00000000 +#define R_ANC_DMA_CONTROL 0x00001004 +#define RRV_ANC_DMA_CONTROL 0x00000000 +#define RRM_ANC_DMA_CONTROL 0x00000000 +#define R_ANC_DMA_UID_CONFIG 0x00001008 +#define RRV_ANC_DMA_UID_CONFIG 0x00000000 +#define RRM_ANC_DMA_UID_CONFIG 0x00000000 +#define R_ANC_DMA_STATUS 0x0000100c +#define RRV_ANC_DMA_STATUS 0x00000007 +#define RRM_ANC_DMA_STATUS 0x00000000 +#define R_ANC_DMA_AES_STATUS 0x00001010 +#define RRV_ANC_DMA_AES_STATUS 0x00000000 +#define RRM_ANC_DMA_AES_STATUS 0x00000000 +#define R_ANC_DMA_CMDQ_COUNT 0x00001014 +#define RRV_ANC_DMA_CMDQ_COUNT 0x00000000 +#define RRM_ANC_DMA_CMDQ_COUNT 0x00000000 +#define R_ANC_DMA_CMD_TIMEOUT 0x00001018 +#define RRV_ANC_DMA_CMD_TIMEOUT 0x7fffffff +#define RRM_ANC_DMA_CMD_TIMEOUT 0x00000000 +#define R_ANC_DMA_CMDQ_INT_CODE 0x0000101c +#define RRV_ANC_DMA_CMDQ_INT_CODE 0x00000000 +#define RRM_ANC_DMA_CMDQ_INT_CODE 0x00000000 +#define R_ANC_DMA_AXI 0x00001020 +#define RRV_ANC_DMA_AXI 0x20000000 +#define RRM_ANC_DMA_AXI 0x00000000 +#define R_ANC_DMA_AXI_NEXT 0x00001024 +#define RRV_ANC_DMA_AXI_NEXT 0x00000000 +#define RRM_ANC_DMA_AXI_NEXT 0x00000000 +#define R_ANC_DMA_AXI_NEXT_ADDRESS 0x00001028 +#define RRV_ANC_DMA_AXI_NEXT_ADDRESS 0x00000000 +#define RRM_ANC_DMA_AXI_NEXT_ADDRESS 0x00000000 +#define R_ANC_DMA_LAST 0x00001028 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_DMA_CONFIG +#define rANC_DMA_CONTROL +#define rANC_DMA_UID_CONFIG +#define rANC_DMA_STATUS +#define rANC_DMA_AES_STATUS +#define rANC_DMA_CMDQ_COUNT +#define rANC_DMA_CMD_TIMEOUT +#define rANC_DMA_CMDQ_INT_CODE +#define rANC_DMA_AXI +#define rANC_DMA_AXI_NEXT +#define rANC_DMA_AXI_NEXT_ADDRESS +#define rANC_DMA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_BASE 0x00002000 +#define A_ANC_LINK_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_CONFIG 0x00002000 +#define RRV_ANC_LINK_CONFIG 0x00000000 +#define RRM_ANC_LINK_CONFIG 0x00000000 +#define R_ANC_LINK_CONTROL 0x00002004 +#define RRV_ANC_LINK_CONTROL 0x00000000 +#define RRM_ANC_LINK_CONTROL 0x00000000 +#define R_ANC_LINK_STATUS 0x00002008 +#define RRV_ANC_LINK_STATUS 0x00000000 +#define RRM_ANC_LINK_STATUS 0x00000000 +#define R_ANC_LINK_CHIP_ENABLE 0x0000200c +#define RRV_ANC_LINK_CHIP_ENABLE 0x00000000 +#define RRM_ANC_LINK_CHIP_ENABLE 0x00000000 +#define R_ANC_LINK_READ_STATUS_CONFIG 0x00002010 +#define RRV_ANC_LINK_READ_STATUS_CONFIG 0x00004040 +#define RRM_ANC_LINK_READ_STATUS_CONFIG 0x00000000 +#define R_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING 0x00002014 +#define RRV_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING 0x00000000 +#define RRM_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING 0x00000000 +#define R_ANC_LINK_SDR_TIMING 0x00002018 +#define RRV_ANC_LINK_SDR_TIMING 0x00000000 +#define RRM_ANC_LINK_SDR_TIMING 0x00000000 +#define R_ANC_LINK_SDR_DATA_TIMING 0x0000201c +#define RRV_ANC_LINK_SDR_DATA_TIMING 0x00000000 +#define RRM_ANC_LINK_SDR_DATA_TIMING 0x00000000 +#define R_ANC_LINK_DDR_DATA_TIMING 0x00002020 +#define RRV_ANC_LINK_DDR_DATA_TIMING 0x00000000 +#define RRM_ANC_LINK_DDR_DATA_TIMING 0x00000000 +#define R_ANC_LINK_DDR_READ_TIMING 0x00002024 +#define RRV_ANC_LINK_DDR_READ_TIMING 0x00000000 +#define RRM_ANC_LINK_DDR_READ_TIMING 0x00000000 +#define R_ANC_LINK_DDR_WRITE_TIMING 0x00002028 +#define RRV_ANC_LINK_DDR_WRITE_TIMING 0x00000000 +#define RRM_ANC_LINK_DDR_WRITE_TIMING 0x00000000 +#define R_ANC_LINK_DQS_TIMING 0x0000202c +#define RRV_ANC_LINK_DQS_TIMING 0x00000000 +#define RRM_ANC_LINK_DQS_TIMING 0x00000000 +#define R_ANC_LINK_CMDQ_COUNT 0x00002030 +#define RRV_ANC_LINK_CMDQ_COUNT 0x00000000 +#define RRM_ANC_LINK_CMDQ_COUNT 0x00000000 +#define R_ANC_LINK_BYPASS_COUNT 0x00002034 +#define RRV_ANC_LINK_BYPASS_COUNT 0x00000000 +#define RRM_ANC_LINK_BYPASS_COUNT 0x00000000 +#define R_ANC_LINK_CMD_TIMEOUT 0x00002038 +#define RRV_ANC_LINK_CMD_TIMEOUT 0x7fffffff +#define RRM_ANC_LINK_CMD_TIMEOUT 0x00000000 +#define R_ANC_LINK_CMDQ_INT_CODE 0x0000203c +#define RRV_ANC_LINK_CMDQ_INT_CODE 0x00000000 +#define RRM_ANC_LINK_CMDQ_INT_CODE 0x00000000 +#define R_ANC_LINK_TIMER 0x00002040 +#define RRV_ANC_LINK_TIMER 0x00000000 +#define RRM_ANC_LINK_TIMER 0x00000000 +#define R_ANC_LINK_CRC 0x00002044 +#define RRV_ANC_LINK_CRC 0x00000000 +#define RRM_ANC_LINK_CRC 0x00000000 +#define R_ANC_LINK_NPL_INTERFACE 0x00002048 +#define RRV_ANC_LINK_NPL_INTERFACE 0x00000000 +#define RRM_ANC_LINK_NPL_INTERFACE 0x00000000 +#define R_ANC_LINK_MACRO_STATUS 0x0000204c +#define RRV_ANC_LINK_MACRO_STATUS 0x00000000 +#define RRM_ANC_LINK_MACRO_STATUS 0x00000000 +#define R_ANC_LINK_BYPASS_MACRO_STATUS 0x00002050 +#define RRV_ANC_LINK_BYPASS_MACRO_STATUS 0x00000000 +#define RRM_ANC_LINK_BYPASS_MACRO_STATUS 0x00000000 +#define R_ANC_LINK_NAND_STATUS 0x00002054 +#define RRV_ANC_LINK_NAND_STATUS 0x00000000 +#define RRM_ANC_LINK_NAND_STATUS 0x00000000 +#define R_ANC_LINK_LAST 0x00002054 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_CONFIG +#define rANC_LINK_CONTROL +#define rANC_LINK_STATUS +#define rANC_LINK_CHIP_ENABLE +#define rANC_LINK_READ_STATUS_CONFIG +#define rANC_LINK_COMMAND_ADDRESS_PULSE_TIMING +#define rANC_LINK_SDR_TIMING +#define rANC_LINK_SDR_DATA_TIMING +#define rANC_LINK_DDR_DATA_TIMING +#define rANC_LINK_DDR_READ_TIMING +#define rANC_LINK_DDR_WRITE_TIMING +#define rANC_LINK_DQS_TIMING +#define rANC_LINK_CMDQ_COUNT +#define rANC_LINK_BYPASS_COUNT +#define rANC_LINK_CMD_TIMEOUT +#define rANC_LINK_CMDQ_INT_CODE +#define rANC_LINK_TIMER +#define rANC_LINK_CRC +#define rANC_LINK_NPL_INTERFACE +#define rANC_LINK_MACRO_STATUS +#define rANC_LINK_BYPASS_MACRO_STATUS +#define rANC_LINK_NAND_STATUS +#define rANC_LINK_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_MACRO_TABLE_BASE 0x00003000 +#define A_ANC_MACRO_TABLE_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_MACRO_TABLE_COMMAND 0x00003000 +#define RRV_ANC_MACRO_TABLE_COMMAND 0x00000000 +#define RRM_ANC_MACRO_TABLE_COMMAND 0x00000000 +#define R_ANC_MACRO_TABLE_LAST 0x00003000 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_MACRO_TABLE_COMMAND +#define rANC_MACRO_TABLE_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_DMA_CMDQ_FIFO_DA_BASE 0x00004000 +#define A_ANC_DMA_CMDQ_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_DMA_CMDQ_FIFO_DA_WORD 0x00004000 +#define RRV_ANC_DMA_CMDQ_FIFO_DA_WORD 0x00000000 +#define RRM_ANC_DMA_CMDQ_FIFO_DA_WORD 0x00000000 +#define R_ANC_DMA_CMDQ_FIFO_DA_LAST 0x00004000 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_DMA_CMDQ_FIFO_DA_WORD +#define rANC_DMA_CMDQ_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_CMDQ_FIFO_DA_BASE 0x00004200 +#define A_ANC_LINK_CMDQ_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_CMDQ_FIFO_DA_WORD 0x00004200 +#define RRV_ANC_LINK_CMDQ_FIFO_DA_WORD 0x00000000 +#define RRM_ANC_LINK_CMDQ_FIFO_DA_WORD 0x00000000 +#define R_ANC_LINK_CMDQ_FIFO_DA_LAST 0x00004200 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_CMDQ_FIFO_DA_WORD +#define rANC_LINK_CMDQ_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_BYPASS_FIFO_DA_BASE 0x00004400 +#define A_ANC_LINK_BYPASS_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_BYPASS_FIFO_DA_WORD 0x00004400 +#define RRV_ANC_LINK_BYPASS_FIFO_DA_WORD 0x00000000 +#define RRM_ANC_LINK_BYPASS_FIFO_DA_WORD 0x00000000 +#define R_ANC_LINK_BYPASS_FIFO_DA_LAST 0x00004400 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_BYPASS_FIFO_DA_WORD +#define rANC_LINK_BYPASS_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_PIO_READ_FIFO_DA_BASE 0x00004500 +#define A_ANC_PIO_READ_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_PIO_READ_FIFO_DA_WORD 0x00004500 +#define RRV_ANC_PIO_READ_FIFO_DA_WORD 0x00000000 +#define RRM_ANC_PIO_READ_FIFO_DA_WORD 0x00000000 +#define R_ANC_PIO_READ_FIFO_DA_LAST 0x00004500 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_PIO_READ_FIFO_DA_WORD +#define rANC_PIO_READ_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_DMA_DEBUG_FIFO_BASE 0x00004600 +#define A_ANC_DMA_DEBUG_FIFO_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_DMA_DEBUG_FIFO_COMMAND 0x00004600 +#define RRV_ANC_DMA_DEBUG_FIFO_COMMAND 0x00000000 +#define RRM_ANC_DMA_DEBUG_FIFO_COMMAND 0x00000000 +#define R_ANC_DMA_DEBUG_FIFO_LAST 0x00004600 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_DMA_DEBUG_FIFO_COMMAND +#define rANC_DMA_DEBUG_FIFO_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_DEBUG_FIFO_BASE 0x00004700 +#define A_ANC_LINK_DEBUG_FIFO_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_DEBUG_FIFO_COMMAND 0x00004700 +#define RRV_ANC_LINK_DEBUG_FIFO_COMMAND 0x00000000 +#define RRM_ANC_LINK_DEBUG_FIFO_COMMAND 0x00000000 +#define R_ANC_LINK_DEBUG_FIFO_LAST 0x00004700 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_DEBUG_FIFO_COMMAND +#define rANC_LINK_DEBUG_FIFO_LAST +#endif + +/******************************************************************************/ +/* Register Fields defines */ +/******************************************************************************/ +#define S_ANC_CHAN_VERSION_MINOR_RELEASE 0 //Access: read-only +#define M_ANC_CHAN_VERSION_MINOR_RELEASE _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_MINOR_RELEASE) +#define V_ANC_CHAN_VERSION_MINOR_RELEASE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_MINOR_RELEASE) +#define G_ANC_CHAN_VERSION_MINOR_RELEASE(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_MINOR_RELEASE,M_ANC_CHAN_VERSION_MINOR_RELEASE) + +#define S_ANC_CHAN_VERSION_MAJOR_RELEASE 8 //Access: read-only +#define M_ANC_CHAN_VERSION_MAJOR_RELEASE _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_MAJOR_RELEASE) +#define V_ANC_CHAN_VERSION_MAJOR_RELEASE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_MAJOR_RELEASE) +#define G_ANC_CHAN_VERSION_MAJOR_RELEASE(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_MAJOR_RELEASE,M_ANC_CHAN_VERSION_MAJOR_RELEASE) + +#define S_ANC_CHAN_VERSION_VERSION 16 //Access: read-only +#define M_ANC_CHAN_VERSION_VERSION _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_VERSION) +#define V_ANC_CHAN_VERSION_VERSION(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_VERSION) +#define G_ANC_CHAN_VERSION_VERSION(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_VERSION,M_ANC_CHAN_VERSION_VERSION) + +#define S_ANC_CHAN_VERSION_RSVD0 24 //Access: read-as-zero +#define M_ANC_CHAN_VERSION_RSVD0 _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_RSVD0) +#define V_ANC_CHAN_VERSION_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_RSVD0) +#define G_ANC_CHAN_VERSION_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_RSVD0,M_ANC_CHAN_VERSION_RSVD0) + + +#define S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN 0 //Access: read-write +#define M_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN _MM_MAKEMASK(1,S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN) +#define V_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN(V) _MM_MAKEVALUE((V),S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN) +#define G_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN(V) _MM_GETVALUE((V),S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN,M_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN) + +#define S_ANC_CHAN_CONFIG_RSVD0 1 //Access: read-as-zero +#define M_ANC_CHAN_CONFIG_RSVD0 _MM_MAKEMASK(31,S_ANC_CHAN_CONFIG_RSVD0) +#define V_ANC_CHAN_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_CONFIG_RSVD0) +#define G_ANC_CHAN_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_CONFIG_RSVD0,M_ANC_CHAN_CONFIG_RSVD0) + + +#define S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG 0 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG) +#define V_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG) +#define G_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG,M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG 1 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG) +#define V_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG) +#define G_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG,M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG) + +#define S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED 2 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED) +#define V_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED) +#define G_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED,M_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED) + +#define S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW 3 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW 4 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW 5 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW) +#define V_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW) +#define G_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW,M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH 6 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH) +#define V_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH) +#define G_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH,M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH) + +#define S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW 7 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW 8 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW 9 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW,M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW 10 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW) +#define V_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW) +#define G_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW,M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW) + +#define S_ANC_CHAN_INT_STATUS_CRC_ERR 11 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_CRC_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_CRC_ERR) +#define V_ANC_CHAN_INT_STATUS_CRC_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_CRC_ERR) +#define G_ANC_CHAN_INT_STATUS_CRC_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_CRC_ERR,M_ANC_CHAN_INT_STATUS_CRC_ERR) + +#define S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE 12 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) +#define V_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) +#define G_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE,M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) + +#define S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND 13 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND) +#define V_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND) +#define G_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND,M_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND) + +#define S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND 14 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND) +#define V_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND) +#define G_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND,M_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND) + +#define S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY 15 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY) +#define V_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY) +#define G_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY,M_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY) + +#define S_ANC_CHAN_INT_STATUS_AES_ERR 16 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_AES_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_AES_ERR) +#define V_ANC_CHAN_INT_STATUS_AES_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_AES_ERR) +#define G_ANC_CHAN_INT_STATUS_AES_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_AES_ERR,M_ANC_CHAN_INT_STATUS_AES_ERR) + +#define S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT 17 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT,M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT 18 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT,M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_STATUS_RSVD0 19 //Access: read-as-zero +#define M_ANC_CHAN_INT_STATUS_RSVD0 _MM_MAKEMASK(13,S_ANC_CHAN_INT_STATUS_RSVD0) +#define V_ANC_CHAN_INT_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_RSVD0) +#define G_ANC_CHAN_INT_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_RSVD0,M_ANC_CHAN_INT_STATUS_RSVD0) + + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG 0 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG,M_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG 1 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG,M_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG) + +#define S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED 2 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED) +#define V_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED) +#define G_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED,M_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED) + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW 3 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW 4 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW 5 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW,M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH 6 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH) +#define V_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH) +#define G_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH,M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH) + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW 7 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW 8 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW 9 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW,M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW 10 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW,M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_CRC_ERR 11 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_CRC_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_CRC_ERR) +#define V_ANC_CHAN_INT_ENABLE_CRC_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_CRC_ERR) +#define G_ANC_CHAN_INT_ENABLE_CRC_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_CRC_ERR,M_ANC_CHAN_INT_ENABLE_CRC_ERR) + +#define S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE 12 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE) +#define V_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE) +#define G_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE,M_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE) + +#define S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND 13 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND) +#define V_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND) +#define G_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND,M_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND) + +#define S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND 14 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND) +#define V_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND) +#define G_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND,M_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND) + +#define S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY 15 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY) +#define V_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY) +#define G_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY,M_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY) + +#define S_ANC_CHAN_INT_ENABLE_AES_ERR 16 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_AES_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_AES_ERR) +#define V_ANC_CHAN_INT_ENABLE_AES_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_AES_ERR) +#define G_ANC_CHAN_INT_ENABLE_AES_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_AES_ERR,M_ANC_CHAN_INT_ENABLE_AES_ERR) + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT 17 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT,M_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT 18 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT,M_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_ENABLE_RSVD0 19 //Access: read-as-zero +#define M_ANC_CHAN_INT_ENABLE_RSVD0 _MM_MAKEMASK(13,S_ANC_CHAN_INT_ENABLE_RSVD0) +#define V_ANC_CHAN_INT_ENABLE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_RSVD0) +#define G_ANC_CHAN_INT_ENABLE_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_RSVD0,M_ANC_CHAN_INT_ENABLE_RSVD0) + + +#define S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW 0 //Access: read-write +#define M_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW _MM_MAKEMASK(7,S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW,M_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_DMA_WATERMARKS_RSVD0 7 //Access: read-as-zero +#define M_ANC_CHAN_DMA_WATERMARKS_RSVD0 _MM_MAKEMASK(25,S_ANC_CHAN_DMA_WATERMARKS_RSVD0) +#define V_ANC_CHAN_DMA_WATERMARKS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_RSVD0) +#define G_ANC_CHAN_DMA_WATERMARKS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_RSVD0,M_ANC_CHAN_DMA_WATERMARKS_RSVD0) + + +#define S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW 0 //Access: read-write +#define M_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW _MM_MAKEMASK(8,S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW,M_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_LINK_WATERMARKS_RSVD0 8 //Access: read-as-zero +#define M_ANC_CHAN_LINK_WATERMARKS_RSVD0 _MM_MAKEMASK(8,S_ANC_CHAN_LINK_WATERMARKS_RSVD0) +#define V_ANC_CHAN_LINK_WATERMARKS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD0) +#define G_ANC_CHAN_LINK_WATERMARKS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD0,M_ANC_CHAN_LINK_WATERMARKS_RSVD0) + +#define S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW 16 //Access: read-write +#define M_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW _MM_MAKEMASK(4,S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW) +#define V_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW) +#define G_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW,M_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW) + +#define S_ANC_CHAN_LINK_WATERMARKS_RSVD1 20 //Access: read-as-zero +#define M_ANC_CHAN_LINK_WATERMARKS_RSVD1 _MM_MAKEMASK(4,S_ANC_CHAN_LINK_WATERMARKS_RSVD1) +#define V_ANC_CHAN_LINK_WATERMARKS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD1) +#define G_ANC_CHAN_LINK_WATERMARKS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD1,M_ANC_CHAN_LINK_WATERMARKS_RSVD1) + +#define S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH 24 //Access: read-write +#define M_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH _MM_MAKEMASK(7,S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH) +#define V_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH) +#define G_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH,M_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH) + +#define S_ANC_CHAN_LINK_WATERMARKS_RSVD2 31 //Access: read-as-zero +#define M_ANC_CHAN_LINK_WATERMARKS_RSVD2 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_WATERMARKS_RSVD2) +#define V_ANC_CHAN_LINK_WATERMARKS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD2) +#define G_ANC_CHAN_LINK_WATERMARKS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD2,M_ANC_CHAN_LINK_WATERMARKS_RSVD2) + + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW 0 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL 1 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW 2 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL _MM_MAKEMASK(7,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1 15 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2 22 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2 _MM_MAKEMASK(2,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3 30 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3 _MM_MAKEMASK(2,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3) + + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW 0 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL 1 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW 2 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL _MM_MAKEMASK(8,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(7,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1 23 //Access: read-as-zero +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(7,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2 31 //Access: read-as-zero +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2) + + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW 0 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL 1 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL _MM_MAKEMASK(1,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW 2 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL _MM_MAKEMASK(4,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1 12 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1 _MM_MAKEMASK(4,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(3,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2 19 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(3,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3 27 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3) + + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH 0 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY 1 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW 2 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL _MM_MAKEMASK(7,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1 15 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2 22 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2 _MM_MAKEMASK(2,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3 30 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3 _MM_MAKEMASK(2,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3) + + +#define S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER 0 //Access: read-only +#define M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(4,S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0 4 //Access: read-as-zero +#define M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0 _MM_MAKEMASK(28,S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0,M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0) + + +#define S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER 0 //Access: read-only +#define M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(5,S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0 5 //Access: read-as-zero +#define M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0 _MM_MAKEMASK(27,S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0) + + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD 0 //Access: write-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD _MM_MAKEMASK(32,S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD,M_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD) + + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD 0 //Access: write-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD,M_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD) + + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD 0 //Access: write-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD,M_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD) + + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD 0 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD,M_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD) + + +#define S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD 0 //Access: read-only +#define M_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD _MM_MAKEMASK(32,S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD) +#define V_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD) +#define G_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD,M_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD) + + +#define S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD 0 //Access: read-only +#define M_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD) +#define V_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD) +#define G_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD,M_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD) + + +#define S_ANC_DMA_CONFIG_AXI_AXQOS 0 //Access: read-write +#define M_ANC_DMA_CONFIG_AXI_AXQOS _MM_MAKEMASK(4,S_ANC_DMA_CONFIG_AXI_AXQOS) +#define V_ANC_DMA_CONFIG_AXI_AXQOS(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_AXI_AXQOS) +#define G_ANC_DMA_CONFIG_AXI_AXQOS(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_AXI_AXQOS,M_ANC_DMA_CONFIG_AXI_AXQOS) + +#define S_ANC_DMA_CONFIG_RSVD0 4 //Access: read-as-zero +#define M_ANC_DMA_CONFIG_RSVD0 _MM_MAKEMASK(4,S_ANC_DMA_CONFIG_RSVD0) +#define V_ANC_DMA_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_RSVD0) +#define G_ANC_DMA_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_RSVD0,M_ANC_DMA_CONFIG_RSVD0) + +#define S_ANC_DMA_CONFIG_BURST_SIZE 8 //Access: read-write +#define M_ANC_DMA_CONFIG_BURST_SIZE _MM_MAKEMASK(2,S_ANC_DMA_CONFIG_BURST_SIZE) +#define V_ANC_DMA_CONFIG_BURST_SIZE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_BURST_SIZE) +#define G_ANC_DMA_CONFIG_BURST_SIZE(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_BURST_SIZE,M_ANC_DMA_CONFIG_BURST_SIZE) + +#define S_ANC_DMA_CONFIG_RSVD1 10 //Access: read-as-zero +#define M_ANC_DMA_CONFIG_RSVD1 _MM_MAKEMASK(22,S_ANC_DMA_CONFIG_RSVD1) +#define V_ANC_DMA_CONFIG_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_RSVD1) +#define G_ANC_DMA_CONFIG_RSVD1(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_RSVD1,M_ANC_DMA_CONFIG_RSVD1) + + +#define S_ANC_DMA_CONTROL_START 0 //Access: write-auto-clear +#define M_ANC_DMA_CONTROL_START _MM_MAKEMASK(1,S_ANC_DMA_CONTROL_START) +#define V_ANC_DMA_CONTROL_START(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_START) +#define G_ANC_DMA_CONTROL_START(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_START,M_ANC_DMA_CONTROL_START) + +#define S_ANC_DMA_CONTROL_STOP 1 //Access: write-auto-clear +#define M_ANC_DMA_CONTROL_STOP _MM_MAKEMASK(1,S_ANC_DMA_CONTROL_STOP) +#define V_ANC_DMA_CONTROL_STOP(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_STOP) +#define G_ANC_DMA_CONTROL_STOP(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_STOP,M_ANC_DMA_CONTROL_STOP) + +#define S_ANC_DMA_CONTROL_RESET 2 //Access: write-auto-clear +#define M_ANC_DMA_CONTROL_RESET _MM_MAKEMASK(1,S_ANC_DMA_CONTROL_RESET) +#define V_ANC_DMA_CONTROL_RESET(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_RESET) +#define G_ANC_DMA_CONTROL_RESET(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_RESET,M_ANC_DMA_CONTROL_RESET) + +#define S_ANC_DMA_CONTROL_RSVD0 3 //Access: read-as-zero +#define M_ANC_DMA_CONTROL_RSVD0 _MM_MAKEMASK(29,S_ANC_DMA_CONTROL_RSVD0) +#define V_ANC_DMA_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_RSVD0) +#define G_ANC_DMA_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_RSVD0,M_ANC_DMA_CONTROL_RSVD0) + + +#define S_ANC_DMA_UID_CONFIG_DISABLE_UID 0 //Access: write-only +#define M_ANC_DMA_UID_CONFIG_DISABLE_UID _MM_MAKEMASK(1,S_ANC_DMA_UID_CONFIG_DISABLE_UID) +#define V_ANC_DMA_UID_CONFIG_DISABLE_UID(V) _MM_MAKEVALUE((V),S_ANC_DMA_UID_CONFIG_DISABLE_UID) +#define G_ANC_DMA_UID_CONFIG_DISABLE_UID(V) _MM_GETVALUE((V),S_ANC_DMA_UID_CONFIG_DISABLE_UID,M_ANC_DMA_UID_CONFIG_DISABLE_UID) + +#define S_ANC_DMA_UID_CONFIG_RSVD0 1 //Access: read-as-zero +#define M_ANC_DMA_UID_CONFIG_RSVD0 _MM_MAKEMASK(31,S_ANC_DMA_UID_CONFIG_RSVD0) +#define V_ANC_DMA_UID_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_UID_CONFIG_RSVD0) +#define G_ANC_DMA_UID_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_UID_CONFIG_RSVD0,M_ANC_DMA_UID_CONFIG_RSVD0) + + +#define S_ANC_DMA_STATUS_DMA_ACTIVE 0 //Access: read-only +#define M_ANC_DMA_STATUS_DMA_ACTIVE _MM_MAKEMASK(1,S_ANC_DMA_STATUS_DMA_ACTIVE) +#define V_ANC_DMA_STATUS_DMA_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_DMA_ACTIVE) +#define G_ANC_DMA_STATUS_DMA_ACTIVE(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_DMA_ACTIVE,M_ANC_DMA_STATUS_DMA_ACTIVE) + +#define S_ANC_DMA_STATUS_AXI_ACTIVE 1 //Access: read-only +#define M_ANC_DMA_STATUS_AXI_ACTIVE _MM_MAKEMASK(1,S_ANC_DMA_STATUS_AXI_ACTIVE) +#define V_ANC_DMA_STATUS_AXI_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_AXI_ACTIVE) +#define G_ANC_DMA_STATUS_AXI_ACTIVE(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_AXI_ACTIVE,M_ANC_DMA_STATUS_AXI_ACTIVE) + +#define S_ANC_DMA_STATUS_AES_ACTIVE 2 //Access: read-only +#define M_ANC_DMA_STATUS_AES_ACTIVE _MM_MAKEMASK(1,S_ANC_DMA_STATUS_AES_ACTIVE) +#define V_ANC_DMA_STATUS_AES_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_AES_ACTIVE) +#define G_ANC_DMA_STATUS_AES_ACTIVE(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_AES_ACTIVE,M_ANC_DMA_STATUS_AES_ACTIVE) + +#define S_ANC_DMA_STATUS_CMDQ_ENABLED 3 //Access: read-only +#define M_ANC_DMA_STATUS_CMDQ_ENABLED _MM_MAKEMASK(1,S_ANC_DMA_STATUS_CMDQ_ENABLED) +#define V_ANC_DMA_STATUS_CMDQ_ENABLED(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_CMDQ_ENABLED) +#define G_ANC_DMA_STATUS_CMDQ_ENABLED(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_CMDQ_ENABLED,M_ANC_DMA_STATUS_CMDQ_ENABLED) + +#define S_ANC_DMA_STATUS_AES_ENABLED 4 //Access: read-only +#define M_ANC_DMA_STATUS_AES_ENABLED _MM_MAKEMASK(1,S_ANC_DMA_STATUS_AES_ENABLED) +#define V_ANC_DMA_STATUS_AES_ENABLED(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_AES_ENABLED) +#define G_ANC_DMA_STATUS_AES_ENABLED(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_AES_ENABLED,M_ANC_DMA_STATUS_AES_ENABLED) + +#define S_ANC_DMA_STATUS_DMA_DIRECTION 5 //Access: read-only +#define M_ANC_DMA_STATUS_DMA_DIRECTION _MM_MAKEMASK(1,S_ANC_DMA_STATUS_DMA_DIRECTION) +#define V_ANC_DMA_STATUS_DMA_DIRECTION(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_DMA_DIRECTION) +#define G_ANC_DMA_STATUS_DMA_DIRECTION(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_DMA_DIRECTION,M_ANC_DMA_STATUS_DMA_DIRECTION) + +#define S_ANC_DMA_STATUS_RSVD0 6 //Access: read-as-zero +#define M_ANC_DMA_STATUS_RSVD0 _MM_MAKEMASK(26,S_ANC_DMA_STATUS_RSVD0) +#define V_ANC_DMA_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_RSVD0) +#define G_ANC_DMA_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_RSVD0,M_ANC_DMA_STATUS_RSVD0) + + +#define S_ANC_DMA_AES_STATUS_WRAPPING_ENABLED 0 //Access: read-only +#define M_ANC_DMA_AES_STATUS_WRAPPING_ENABLED _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_WRAPPING_ENABLED) +#define V_ANC_DMA_AES_STATUS_WRAPPING_ENABLED(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_WRAPPING_ENABLED) +#define G_ANC_DMA_AES_STATUS_WRAPPING_ENABLED(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_WRAPPING_ENABLED,M_ANC_DMA_AES_STATUS_WRAPPING_ENABLED) + +#define S_ANC_DMA_AES_STATUS_KEY_SELECT 1 //Access: read-only +#define M_ANC_DMA_AES_STATUS_KEY_SELECT _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_KEY_SELECT) +#define V_ANC_DMA_AES_STATUS_KEY_SELECT(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_KEY_SELECT) +#define G_ANC_DMA_AES_STATUS_KEY_SELECT(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_KEY_SELECT,M_ANC_DMA_AES_STATUS_KEY_SELECT) + +#define S_ANC_DMA_AES_STATUS_KEY_LENGTH 2 //Access: read-only +#define M_ANC_DMA_AES_STATUS_KEY_LENGTH _MM_MAKEMASK(2,S_ANC_DMA_AES_STATUS_KEY_LENGTH) +#define V_ANC_DMA_AES_STATUS_KEY_LENGTH(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_KEY_LENGTH) +#define G_ANC_DMA_AES_STATUS_KEY_LENGTH(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_KEY_LENGTH,M_ANC_DMA_AES_STATUS_KEY_LENGTH) + +#define S_ANC_DMA_AES_STATUS_UID_DISABLED 4 //Access: read-only +#define M_ANC_DMA_AES_STATUS_UID_DISABLED _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_UID_DISABLED) +#define V_ANC_DMA_AES_STATUS_UID_DISABLED(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_UID_DISABLED) +#define G_ANC_DMA_AES_STATUS_UID_DISABLED(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_UID_DISABLED,M_ANC_DMA_AES_STATUS_UID_DISABLED) + +#define S_ANC_DMA_AES_STATUS_KEY_IN_CTX 5 //Access: read-only +#define M_ANC_DMA_AES_STATUS_KEY_IN_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_KEY_IN_CTX) +#define V_ANC_DMA_AES_STATUS_KEY_IN_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_KEY_IN_CTX) +#define G_ANC_DMA_AES_STATUS_KEY_IN_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_KEY_IN_CTX,M_ANC_DMA_AES_STATUS_KEY_IN_CTX) + +#define S_ANC_DMA_AES_STATUS_IV_IN_CTX 6 //Access: read-only +#define M_ANC_DMA_AES_STATUS_IV_IN_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_IV_IN_CTX) +#define V_ANC_DMA_AES_STATUS_IV_IN_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_IV_IN_CTX) +#define G_ANC_DMA_AES_STATUS_IV_IN_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_IV_IN_CTX,M_ANC_DMA_AES_STATUS_IV_IN_CTX) + +#define S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX 7 //Access: read-only +#define M_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX) +#define V_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX) +#define G_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX,M_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX) + +#define S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX 8 //Access: read-only +#define M_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX) +#define V_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX) +#define G_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX,M_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX) + +#define S_ANC_DMA_AES_STATUS_AES_ERR 9 //Access: read-only +#define M_ANC_DMA_AES_STATUS_AES_ERR _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_AES_ERR) +#define V_ANC_DMA_AES_STATUS_AES_ERR(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_AES_ERR) +#define G_ANC_DMA_AES_STATUS_AES_ERR(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_AES_ERR,M_ANC_DMA_AES_STATUS_AES_ERR) + +#define S_ANC_DMA_AES_STATUS_RSVD0 10 //Access: read-as-zero +#define M_ANC_DMA_AES_STATUS_RSVD0 _MM_MAKEMASK(22,S_ANC_DMA_AES_STATUS_RSVD0) +#define V_ANC_DMA_AES_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_RSVD0) +#define G_ANC_DMA_AES_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_RSVD0,M_ANC_DMA_AES_STATUS_RSVD0) + + +#define S_ANC_DMA_CMDQ_COUNT_TOTAL 0 //Access: read-only +#define M_ANC_DMA_CMDQ_COUNT_TOTAL _MM_MAKEMASK(32,S_ANC_DMA_CMDQ_COUNT_TOTAL) +#define V_ANC_DMA_CMDQ_COUNT_TOTAL(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_COUNT_TOTAL) +#define G_ANC_DMA_CMDQ_COUNT_TOTAL(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_COUNT_TOTAL,M_ANC_DMA_CMDQ_COUNT_TOTAL) + + +#define S_ANC_DMA_CMD_TIMEOUT_VALUE 0 //Access: read-write +#define M_ANC_DMA_CMD_TIMEOUT_VALUE _MM_MAKEMASK(31,S_ANC_DMA_CMD_TIMEOUT_VALUE) +#define V_ANC_DMA_CMD_TIMEOUT_VALUE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMD_TIMEOUT_VALUE) +#define G_ANC_DMA_CMD_TIMEOUT_VALUE(V) _MM_GETVALUE((V),S_ANC_DMA_CMD_TIMEOUT_VALUE,M_ANC_DMA_CMD_TIMEOUT_VALUE) + +#define S_ANC_DMA_CMD_TIMEOUT_ENABLE 31 //Access: read-write +#define M_ANC_DMA_CMD_TIMEOUT_ENABLE _MM_MAKEMASK(1,S_ANC_DMA_CMD_TIMEOUT_ENABLE) +#define V_ANC_DMA_CMD_TIMEOUT_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMD_TIMEOUT_ENABLE) +#define G_ANC_DMA_CMD_TIMEOUT_ENABLE(V) _MM_GETVALUE((V),S_ANC_DMA_CMD_TIMEOUT_ENABLE,M_ANC_DMA_CMD_TIMEOUT_ENABLE) + + +#define S_ANC_DMA_CMDQ_INT_CODE_CODE 0 //Access: read-only +#define M_ANC_DMA_CMDQ_INT_CODE_CODE _MM_MAKEMASK(16,S_ANC_DMA_CMDQ_INT_CODE_CODE) +#define V_ANC_DMA_CMDQ_INT_CODE_CODE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_CODE) +#define G_ANC_DMA_CMDQ_INT_CODE_CODE(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_CODE,M_ANC_DMA_CMDQ_INT_CODE_CODE) + +#define S_ANC_DMA_CMDQ_INT_CODE_RSVD0 16 //Access: read-as-zero +#define M_ANC_DMA_CMDQ_INT_CODE_RSVD0 _MM_MAKEMASK(16,S_ANC_DMA_CMDQ_INT_CODE_RSVD0) +#define V_ANC_DMA_CMDQ_INT_CODE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_RSVD0) +#define G_ANC_DMA_CMDQ_INT_CODE_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_RSVD0,M_ANC_DMA_CMDQ_INT_CODE_RSVD0) + + +#define S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING 0 //Access: read-only +#define M_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING _MM_MAKEMASK(5,S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING) +#define V_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING) +#define G_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING,M_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING) + +#define S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING 5 //Access: read-only +#define M_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING _MM_MAKEMASK(9,S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING) +#define V_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING) +#define G_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING,M_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING) + +#define S_ANC_DMA_AXI_RESPONSE 14 //Access: read-only +#define M_ANC_DMA_AXI_RESPONSE _MM_MAKEMASK(2,S_ANC_DMA_AXI_RESPONSE) +#define V_ANC_DMA_AXI_RESPONSE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_RESPONSE) +#define G_ANC_DMA_AXI_RESPONSE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_RESPONSE,M_ANC_DMA_AXI_RESPONSE) + +#define S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE 16 //Access: read-only +#define M_ANC_DMA_AXI_WRITE_DATA_AVAILABLE _MM_MAKEMASK(7,S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE) +#define V_ANC_DMA_AXI_WRITE_DATA_AVAILABLE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE) +#define G_ANC_DMA_AXI_WRITE_DATA_AVAILABLE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE,M_ANC_DMA_AXI_WRITE_DATA_AVAILABLE) + +#define S_ANC_DMA_AXI_READ_SPACE_AVAILABLE 23 //Access: read-only +#define M_ANC_DMA_AXI_READ_SPACE_AVAILABLE _MM_MAKEMASK(7,S_ANC_DMA_AXI_READ_SPACE_AVAILABLE) +#define V_ANC_DMA_AXI_READ_SPACE_AVAILABLE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_READ_SPACE_AVAILABLE) +#define G_ANC_DMA_AXI_READ_SPACE_AVAILABLE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_READ_SPACE_AVAILABLE,M_ANC_DMA_AXI_READ_SPACE_AVAILABLE) + +#define S_ANC_DMA_AXI_RSVD0 30 //Access: read-as-zero +#define M_ANC_DMA_AXI_RSVD0 _MM_MAKEMASK(2,S_ANC_DMA_AXI_RSVD0) +#define V_ANC_DMA_AXI_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_RSVD0) +#define G_ANC_DMA_AXI_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_RSVD0,M_ANC_DMA_AXI_RSVD0) + + +#define S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH 0 //Access: read-only +#define M_ANC_DMA_AXI_NEXT_REQUEST_LENGTH _MM_MAKEMASK(4,S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH) +#define V_ANC_DMA_AXI_NEXT_REQUEST_LENGTH(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH) +#define G_ANC_DMA_AXI_NEXT_REQUEST_LENGTH(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH,M_ANC_DMA_AXI_NEXT_REQUEST_LENGTH) + +#define S_ANC_DMA_AXI_NEXT_RSVD0 4 //Access: read-as-zero +#define M_ANC_DMA_AXI_NEXT_RSVD0 _MM_MAKEMASK(20,S_ANC_DMA_AXI_NEXT_RSVD0) +#define V_ANC_DMA_AXI_NEXT_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_RSVD0) +#define G_ANC_DMA_AXI_NEXT_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_RSVD0,M_ANC_DMA_AXI_NEXT_RSVD0) + +#define S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE 24 //Access: read-only +#define M_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE _MM_MAKEMASK(8,S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE) +#define V_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE) +#define G_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE,M_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE) + + +#define S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES 0 //Access: read-only +#define M_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES _MM_MAKEMASK(32,S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES) +#define V_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES) +#define G_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES,M_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES) + + +#define S_ANC_LINK_CONFIG_DDR_MODE 0 //Access: read-write +#define M_ANC_LINK_CONFIG_DDR_MODE _MM_MAKEMASK(1,S_ANC_LINK_CONFIG_DDR_MODE) +#define V_ANC_LINK_CONFIG_DDR_MODE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_DDR_MODE) +#define G_ANC_LINK_CONFIG_DDR_MODE(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_DDR_MODE,M_ANC_LINK_CONFIG_DDR_MODE) + +#define S_ANC_LINK_CONFIG_ENABLE_CRC 1 //Access: read-write +#define M_ANC_LINK_CONFIG_ENABLE_CRC _MM_MAKEMASK(1,S_ANC_LINK_CONFIG_ENABLE_CRC) +#define V_ANC_LINK_CONFIG_ENABLE_CRC(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_ENABLE_CRC) +#define G_ANC_LINK_CONFIG_ENABLE_CRC(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_ENABLE_CRC,M_ANC_LINK_CONFIG_ENABLE_CRC) + +#define S_ANC_LINK_CONFIG_AUTOPAD_CRC 2 //Access: read-write +#define M_ANC_LINK_CONFIG_AUTOPAD_CRC _MM_MAKEMASK(1,S_ANC_LINK_CONFIG_AUTOPAD_CRC) +#define V_ANC_LINK_CONFIG_AUTOPAD_CRC(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_AUTOPAD_CRC) +#define G_ANC_LINK_CONFIG_AUTOPAD_CRC(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_AUTOPAD_CRC,M_ANC_LINK_CONFIG_AUTOPAD_CRC) + +#define S_ANC_LINK_CONFIG_RSVD0 3 //Access: read-as-zero +#define M_ANC_LINK_CONFIG_RSVD0 _MM_MAKEMASK(29,S_ANC_LINK_CONFIG_RSVD0) +#define V_ANC_LINK_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_RSVD0) +#define G_ANC_LINK_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_RSVD0,M_ANC_LINK_CONFIG_RSVD0) + + +#define S_ANC_LINK_CONTROL_START 0 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START) +#define V_ANC_LINK_CONTROL_START(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START) +#define G_ANC_LINK_CONTROL_START(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START,M_ANC_LINK_CONTROL_START) + +#define S_ANC_LINK_CONTROL_STOP 1 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP) +#define V_ANC_LINK_CONTROL_STOP(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP) +#define G_ANC_LINK_CONTROL_STOP(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP,M_ANC_LINK_CONTROL_STOP) + +#define S_ANC_LINK_CONTROL_YIELD 2 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_YIELD _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_YIELD) +#define V_ANC_LINK_CONTROL_YIELD(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_YIELD) +#define G_ANC_LINK_CONTROL_YIELD(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_YIELD,M_ANC_LINK_CONTROL_YIELD) + +#define S_ANC_LINK_CONTROL_ABORT 3 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_ABORT _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_ABORT) +#define V_ANC_LINK_CONTROL_ABORT(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_ABORT) +#define G_ANC_LINK_CONTROL_ABORT(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_ABORT,M_ANC_LINK_CONTROL_ABORT) + +#define S_ANC_LINK_CONTROL_RESET 4 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET) +#define V_ANC_LINK_CONTROL_RESET(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET) +#define G_ANC_LINK_CONTROL_RESET(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET,M_ANC_LINK_CONTROL_RESET) + +#define S_ANC_LINK_CONTROL_START_CMDQ 5 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START_CMDQ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START_CMDQ) +#define V_ANC_LINK_CONTROL_START_CMDQ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START_CMDQ) +#define G_ANC_LINK_CONTROL_START_CMDQ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START_CMDQ,M_ANC_LINK_CONTROL_START_CMDQ) + +#define S_ANC_LINK_CONTROL_STOP_CMDQ 6 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP_CMDQ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP_CMDQ) +#define V_ANC_LINK_CONTROL_STOP_CMDQ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP_CMDQ) +#define G_ANC_LINK_CONTROL_STOP_CMDQ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP_CMDQ,M_ANC_LINK_CONTROL_STOP_CMDQ) + +#define S_ANC_LINK_CONTROL_RESET_CMDQ 7 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_CMDQ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_CMDQ) +#define V_ANC_LINK_CONTROL_RESET_CMDQ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_CMDQ) +#define G_ANC_LINK_CONTROL_RESET_CMDQ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_CMDQ,M_ANC_LINK_CONTROL_RESET_CMDQ) + +#define S_ANC_LINK_CONTROL_START_BYPASS 8 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START_BYPASS _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START_BYPASS) +#define V_ANC_LINK_CONTROL_START_BYPASS(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START_BYPASS) +#define G_ANC_LINK_CONTROL_START_BYPASS(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START_BYPASS,M_ANC_LINK_CONTROL_START_BYPASS) + +#define S_ANC_LINK_CONTROL_STOP_BYPASS 9 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP_BYPASS _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP_BYPASS) +#define V_ANC_LINK_CONTROL_STOP_BYPASS(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP_BYPASS) +#define G_ANC_LINK_CONTROL_STOP_BYPASS(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP_BYPASS,M_ANC_LINK_CONTROL_STOP_BYPASS) + +#define S_ANC_LINK_CONTROL_RESET_BYPASS 10 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_BYPASS _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_BYPASS) +#define V_ANC_LINK_CONTROL_RESET_BYPASS(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_BYPASS) +#define G_ANC_LINK_CONTROL_RESET_BYPASS(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_BYPASS,M_ANC_LINK_CONTROL_RESET_BYPASS) + +#define S_ANC_LINK_CONTROL_START_TIMER 11 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START_TIMER _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START_TIMER) +#define V_ANC_LINK_CONTROL_START_TIMER(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START_TIMER) +#define G_ANC_LINK_CONTROL_START_TIMER(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START_TIMER,M_ANC_LINK_CONTROL_START_TIMER) + +#define S_ANC_LINK_CONTROL_STOP_TIMER 12 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP_TIMER _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP_TIMER) +#define V_ANC_LINK_CONTROL_STOP_TIMER(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP_TIMER) +#define G_ANC_LINK_CONTROL_STOP_TIMER(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP_TIMER,M_ANC_LINK_CONTROL_STOP_TIMER) + +#define S_ANC_LINK_CONTROL_RESET_TIMER 13 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_TIMER _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_TIMER) +#define V_ANC_LINK_CONTROL_RESET_TIMER(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_TIMER) +#define G_ANC_LINK_CONTROL_RESET_TIMER(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_TIMER,M_ANC_LINK_CONTROL_RESET_TIMER) + +#define S_ANC_LINK_CONTROL_RESET_PIO_READ 14 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_PIO_READ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_PIO_READ) +#define V_ANC_LINK_CONTROL_RESET_PIO_READ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_PIO_READ) +#define G_ANC_LINK_CONTROL_RESET_PIO_READ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_PIO_READ,M_ANC_LINK_CONTROL_RESET_PIO_READ) + +#define S_ANC_LINK_CONTROL_RSVD0 15 //Access: read-as-zero +#define M_ANC_LINK_CONTROL_RSVD0 _MM_MAKEMASK(17,S_ANC_LINK_CONTROL_RSVD0) +#define V_ANC_LINK_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RSVD0) +#define G_ANC_LINK_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RSVD0,M_ANC_LINK_CONTROL_RSVD0) + + +#define S_ANC_LINK_STATUS_CMDQ_ACTIVE 0 //Access: read-only +#define M_ANC_LINK_STATUS_CMDQ_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_STATUS_CMDQ_ACTIVE) +#define V_ANC_LINK_STATUS_CMDQ_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_CMDQ_ACTIVE) +#define G_ANC_LINK_STATUS_CMDQ_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_CMDQ_ACTIVE,M_ANC_LINK_STATUS_CMDQ_ACTIVE) + +#define S_ANC_LINK_STATUS_FSM_ACTIVE 1 //Access: read-only +#define M_ANC_LINK_STATUS_FSM_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_STATUS_FSM_ACTIVE) +#define V_ANC_LINK_STATUS_FSM_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_FSM_ACTIVE) +#define G_ANC_LINK_STATUS_FSM_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_FSM_ACTIVE,M_ANC_LINK_STATUS_FSM_ACTIVE) + +#define S_ANC_LINK_STATUS_READ_HOLD_ACTIVE 2 //Access: read-only +#define M_ANC_LINK_STATUS_READ_HOLD_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_STATUS_READ_HOLD_ACTIVE) +#define V_ANC_LINK_STATUS_READ_HOLD_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_READ_HOLD_ACTIVE) +#define G_ANC_LINK_STATUS_READ_HOLD_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_READ_HOLD_ACTIVE,M_ANC_LINK_STATUS_READ_HOLD_ACTIVE) + +#define S_ANC_LINK_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_LINK_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_LINK_STATUS_RSVD0) +#define V_ANC_LINK_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_RSVD0) +#define G_ANC_LINK_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_RSVD0,M_ANC_LINK_STATUS_RSVD0) + +#define S_ANC_LINK_STATUS_CMDQ_STATE 8 //Access: read-only +#define M_ANC_LINK_STATUS_CMDQ_STATE _MM_MAKEMASK(4,S_ANC_LINK_STATUS_CMDQ_STATE) +#define V_ANC_LINK_STATUS_CMDQ_STATE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_CMDQ_STATE) +#define G_ANC_LINK_STATUS_CMDQ_STATE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_CMDQ_STATE,M_ANC_LINK_STATUS_CMDQ_STATE) + +#define S_ANC_LINK_STATUS_RSVD1 12 //Access: read-as-zero +#define M_ANC_LINK_STATUS_RSVD1 _MM_MAKEMASK(4,S_ANC_LINK_STATUS_RSVD1) +#define V_ANC_LINK_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_RSVD1) +#define G_ANC_LINK_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_RSVD1,M_ANC_LINK_STATUS_RSVD1) + +#define S_ANC_LINK_STATUS_FSM_STATE 16 //Access: read-only +#define M_ANC_LINK_STATUS_FSM_STATE _MM_MAKEMASK(6,S_ANC_LINK_STATUS_FSM_STATE) +#define V_ANC_LINK_STATUS_FSM_STATE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_FSM_STATE) +#define G_ANC_LINK_STATUS_FSM_STATE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_FSM_STATE,M_ANC_LINK_STATUS_FSM_STATE) + +#define S_ANC_LINK_STATUS_RSVD2 22 //Access: read-as-zero +#define M_ANC_LINK_STATUS_RSVD2 _MM_MAKEMASK(10,S_ANC_LINK_STATUS_RSVD2) +#define V_ANC_LINK_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_RSVD2) +#define G_ANC_LINK_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_RSVD2,M_ANC_LINK_STATUS_RSVD2) + + +#define S_ANC_LINK_CHIP_ENABLE_CE 0 //Access: read-write +#define M_ANC_LINK_CHIP_ENABLE_CE _MM_MAKEMASK(8,S_ANC_LINK_CHIP_ENABLE_CE) +#define V_ANC_LINK_CHIP_ENABLE_CE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CHIP_ENABLE_CE) +#define G_ANC_LINK_CHIP_ENABLE_CE(V) _MM_GETVALUE((V),S_ANC_LINK_CHIP_ENABLE_CE,M_ANC_LINK_CHIP_ENABLE_CE) + +#define S_ANC_LINK_CHIP_ENABLE_RSVD0 8 //Access: read-as-zero +#define M_ANC_LINK_CHIP_ENABLE_RSVD0 _MM_MAKEMASK(24,S_ANC_LINK_CHIP_ENABLE_RSVD0) +#define V_ANC_LINK_CHIP_ENABLE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CHIP_ENABLE_RSVD0) +#define G_ANC_LINK_CHIP_ENABLE_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CHIP_ENABLE_RSVD0,M_ANC_LINK_CHIP_ENABLE_RSVD0) + + +#define S_ANC_LINK_READ_STATUS_CONFIG_POSITION 0 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_POSITION _MM_MAKEMASK(8,S_ANC_LINK_READ_STATUS_CONFIG_POSITION) +#define V_ANC_LINK_READ_STATUS_CONFIG_POSITION(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POSITION) +#define G_ANC_LINK_READ_STATUS_CONFIG_POSITION(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POSITION,M_ANC_LINK_READ_STATUS_CONFIG_POSITION) + +#define S_ANC_LINK_READ_STATUS_CONFIG_POLARITY 8 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_POLARITY _MM_MAKEMASK(8,S_ANC_LINK_READ_STATUS_CONFIG_POLARITY) +#define V_ANC_LINK_READ_STATUS_CONFIG_POLARITY(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POLARITY) +#define G_ANC_LINK_READ_STATUS_CONFIG_POLARITY(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POLARITY,M_ANC_LINK_READ_STATUS_CONFIG_POLARITY) + +#define S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY 16 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY _MM_MAKEMASK(4,S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY) +#define V_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY) +#define G_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY,M_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY) + +#define S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY 20 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY _MM_MAKEMASK(4,S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY) +#define V_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY) +#define G_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY,M_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY) + +#define S_ANC_LINK_READ_STATUS_CONFIG_RSVD0 24 //Access: read-as-zero +#define M_ANC_LINK_READ_STATUS_CONFIG_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_READ_STATUS_CONFIG_RSVD0) +#define V_ANC_LINK_READ_STATUS_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_RSVD0) +#define G_ANC_LINK_READ_STATUS_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_RSVD0,M_ANC_LINK_READ_STATUS_CONFIG_RSVD0) + + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME 0 //Access: read-write +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME) + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0 _MM_MAKEMASK(3,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0) + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME 8 //Access: read-write +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME) + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1 13 //Access: read-as-zero +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1 _MM_MAKEMASK(19,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1) + + +#define S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME 0 //Access: read-write +#define M_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME) +#define V_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME) +#define G_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME,M_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME) + +#define S_ANC_LINK_SDR_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_SDR_TIMING_RSVD0 _MM_MAKEMASK(3,S_ANC_LINK_SDR_TIMING_RSVD0) +#define V_ANC_LINK_SDR_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD0) +#define G_ANC_LINK_SDR_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD0,M_ANC_LINK_SDR_TIMING_RSVD0) + +#define S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME 8 //Access: read-write +#define M_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME) +#define V_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME) +#define G_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME,M_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME) + +#define S_ANC_LINK_SDR_TIMING_RSVD1 13 //Access: read-as-zero +#define M_ANC_LINK_SDR_TIMING_RSVD1 _MM_MAKEMASK(3,S_ANC_LINK_SDR_TIMING_RSVD1) +#define V_ANC_LINK_SDR_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD1) +#define G_ANC_LINK_SDR_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD1,M_ANC_LINK_SDR_TIMING_RSVD1) + +#define S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY 16 //Access: read-write +#define M_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY _MM_MAKEMASK(5,S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY) +#define V_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY) +#define G_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY,M_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY) + +#define S_ANC_LINK_SDR_TIMING_RSVD2 21 //Access: read-as-zero +#define M_ANC_LINK_SDR_TIMING_RSVD2 _MM_MAKEMASK(11,S_ANC_LINK_SDR_TIMING_RSVD2) +#define V_ANC_LINK_SDR_TIMING_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD2) +#define G_ANC_LINK_SDR_TIMING_RSVD2(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD2,M_ANC_LINK_SDR_TIMING_RSVD2) + + +#define S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME 0 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME,M_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD0 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD0) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD0) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD0,M_ANC_LINK_SDR_DATA_TIMING_RSVD0) + +#define S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME 8 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME,M_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD1 13 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD1 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD1) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD1) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD1,M_ANC_LINK_SDR_DATA_TIMING_RSVD1) + +#define S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME 16 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME,M_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD2 21 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD2 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD2) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD2) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD2(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD2,M_ANC_LINK_SDR_DATA_TIMING_RSVD2) + +#define S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME 24 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME,M_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD3 29 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD3 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD3) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD3) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD3(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD3,M_ANC_LINK_SDR_DATA_TIMING_RSVD3) + + +#define S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH 0 //Access: read-write +#define M_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH _MM_MAKEMASK(5,S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH) +#define V_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH) +#define G_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH,M_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH) + +#define S_ANC_LINK_DDR_DATA_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_DDR_DATA_TIMING_RSVD0 _MM_MAKEMASK(27,S_ANC_LINK_DDR_DATA_TIMING_RSVD0) +#define V_ANC_LINK_DDR_DATA_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_RSVD0) +#define G_ANC_LINK_DDR_DATA_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_RSVD0,M_ANC_LINK_DDR_DATA_TIMING_RSVD0) + + +#define S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE 0 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE) +#define V_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE) +#define G_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE,M_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE) + +#define S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE 8 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE) +#define V_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE) +#define G_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE,M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE) + +#define S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD 16 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD) +#define V_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD) +#define G_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD,M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD) + +#define S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND 24 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND) +#define V_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND) +#define G_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND,M_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND) + + +#define S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE 0 //Access: read-write +#define M_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE) +#define V_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE) +#define G_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE,M_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE) + +#define S_ANC_LINK_DDR_WRITE_TIMING_RSVD0 8 //Access: read-as-zero +#define M_ANC_LINK_DDR_WRITE_TIMING_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_RSVD0) +#define V_ANC_LINK_DDR_WRITE_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD0) +#define G_ANC_LINK_DDR_WRITE_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD0,M_ANC_LINK_DDR_WRITE_TIMING_RSVD0) + +#define S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE 16 //Access: read-write +#define M_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE) +#define V_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE) +#define G_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE,M_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE) + +#define S_ANC_LINK_DDR_WRITE_TIMING_RSVD1 24 //Access: read-as-zero +#define M_ANC_LINK_DDR_WRITE_TIMING_RSVD1 _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_RSVD1) +#define V_ANC_LINK_DDR_WRITE_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD1) +#define G_ANC_LINK_DDR_WRITE_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD1,M_ANC_LINK_DDR_WRITE_TIMING_RSVD1) + + +#define S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY 0 //Access: read-write +#define M_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY _MM_MAKEMASK(6,S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY) +#define V_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY) +#define G_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY,M_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY) + +#define S_ANC_LINK_DQS_TIMING_RSVD0 6 //Access: read-as-zero +#define M_ANC_LINK_DQS_TIMING_RSVD0 _MM_MAKEMASK(26,S_ANC_LINK_DQS_TIMING_RSVD0) +#define V_ANC_LINK_DQS_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_DQS_TIMING_RSVD0) +#define G_ANC_LINK_DQS_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_DQS_TIMING_RSVD0,M_ANC_LINK_DQS_TIMING_RSVD0) + + +#define S_ANC_LINK_CMDQ_COUNT_TOTAL 0 //Access: read-only +#define M_ANC_LINK_CMDQ_COUNT_TOTAL _MM_MAKEMASK(32,S_ANC_LINK_CMDQ_COUNT_TOTAL) +#define V_ANC_LINK_CMDQ_COUNT_TOTAL(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_COUNT_TOTAL) +#define G_ANC_LINK_CMDQ_COUNT_TOTAL(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_COUNT_TOTAL,M_ANC_LINK_CMDQ_COUNT_TOTAL) + + +#define S_ANC_LINK_BYPASS_COUNT_TOTAL 0 //Access: read-only +#define M_ANC_LINK_BYPASS_COUNT_TOTAL _MM_MAKEMASK(32,S_ANC_LINK_BYPASS_COUNT_TOTAL) +#define V_ANC_LINK_BYPASS_COUNT_TOTAL(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_COUNT_TOTAL) +#define G_ANC_LINK_BYPASS_COUNT_TOTAL(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_COUNT_TOTAL,M_ANC_LINK_BYPASS_COUNT_TOTAL) + + +#define S_ANC_LINK_CMD_TIMEOUT_VALUE 0 //Access: read-write +#define M_ANC_LINK_CMD_TIMEOUT_VALUE _MM_MAKEMASK(31,S_ANC_LINK_CMD_TIMEOUT_VALUE) +#define V_ANC_LINK_CMD_TIMEOUT_VALUE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMD_TIMEOUT_VALUE) +#define G_ANC_LINK_CMD_TIMEOUT_VALUE(V) _MM_GETVALUE((V),S_ANC_LINK_CMD_TIMEOUT_VALUE,M_ANC_LINK_CMD_TIMEOUT_VALUE) + +#define S_ANC_LINK_CMD_TIMEOUT_ENABLE 31 //Access: read-write +#define M_ANC_LINK_CMD_TIMEOUT_ENABLE _MM_MAKEMASK(1,S_ANC_LINK_CMD_TIMEOUT_ENABLE) +#define V_ANC_LINK_CMD_TIMEOUT_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMD_TIMEOUT_ENABLE) +#define G_ANC_LINK_CMD_TIMEOUT_ENABLE(V) _MM_GETVALUE((V),S_ANC_LINK_CMD_TIMEOUT_ENABLE,M_ANC_LINK_CMD_TIMEOUT_ENABLE) + + +#define S_ANC_LINK_CMDQ_INT_CODE_CODE 0 //Access: read-only +#define M_ANC_LINK_CMDQ_INT_CODE_CODE _MM_MAKEMASK(16,S_ANC_LINK_CMDQ_INT_CODE_CODE) +#define V_ANC_LINK_CMDQ_INT_CODE_CODE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_CODE) +#define G_ANC_LINK_CMDQ_INT_CODE_CODE(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_CODE,M_ANC_LINK_CMDQ_INT_CODE_CODE) + +#define S_ANC_LINK_CMDQ_INT_CODE_RSVD0 16 //Access: read-as-zero +#define M_ANC_LINK_CMDQ_INT_CODE_RSVD0 _MM_MAKEMASK(16,S_ANC_LINK_CMDQ_INT_CODE_RSVD0) +#define V_ANC_LINK_CMDQ_INT_CODE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_RSVD0) +#define G_ANC_LINK_CMDQ_INT_CODE_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_RSVD0,M_ANC_LINK_CMDQ_INT_CODE_RSVD0) + + +#define S_ANC_LINK_TIMER_COUNT 0 //Access: read-only +#define M_ANC_LINK_TIMER_COUNT _MM_MAKEMASK(32,S_ANC_LINK_TIMER_COUNT) +#define V_ANC_LINK_TIMER_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_TIMER_COUNT) +#define G_ANC_LINK_TIMER_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_TIMER_COUNT,M_ANC_LINK_TIMER_COUNT) + + +#define S_ANC_LINK_CRC_PARITY_DATA 0 //Access: read-only +#define M_ANC_LINK_CRC_PARITY_DATA _MM_MAKEMASK(32,S_ANC_LINK_CRC_PARITY_DATA) +#define V_ANC_LINK_CRC_PARITY_DATA(V) _MM_MAKEVALUE((V),S_ANC_LINK_CRC_PARITY_DATA) +#define G_ANC_LINK_CRC_PARITY_DATA(V) _MM_GETVALUE((V),S_ANC_LINK_CRC_PARITY_DATA,M_ANC_LINK_CRC_PARITY_DATA) + + +#define S_ANC_LINK_NPL_INTERFACE_CLE 0 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_CLE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_CLE) +#define V_ANC_LINK_NPL_INTERFACE_CLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_CLE) +#define G_ANC_LINK_NPL_INTERFACE_CLE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_CLE,M_ANC_LINK_NPL_INTERFACE_CLE) + +#define S_ANC_LINK_NPL_INTERFACE_ALE 1 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_ALE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_ALE) +#define V_ANC_LINK_NPL_INTERFACE_ALE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_ALE) +#define G_ANC_LINK_NPL_INTERFACE_ALE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_ALE,M_ANC_LINK_NPL_INTERFACE_ALE) + +#define S_ANC_LINK_NPL_INTERFACE_REN 2 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_REN _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_REN) +#define V_ANC_LINK_NPL_INTERFACE_REN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_REN) +#define G_ANC_LINK_NPL_INTERFACE_REN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_REN,M_ANC_LINK_NPL_INTERFACE_REN) + +#define S_ANC_LINK_NPL_INTERFACE_WEN 3 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_WEN _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_WEN) +#define V_ANC_LINK_NPL_INTERFACE_WEN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_WEN) +#define G_ANC_LINK_NPL_INTERFACE_WEN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_WEN,M_ANC_LINK_NPL_INTERFACE_WEN) + +#define S_ANC_LINK_NPL_INTERFACE_DATA_OUT 4 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_DATA_OUT _MM_MAKEMASK(8,S_ANC_LINK_NPL_INTERFACE_DATA_OUT) +#define V_ANC_LINK_NPL_INTERFACE_DATA_OUT(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT) +#define G_ANC_LINK_NPL_INTERFACE_DATA_OUT(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT,M_ANC_LINK_NPL_INTERFACE_DATA_OUT) + +#define S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE 12 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE) +#define V_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE) +#define G_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE,M_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE) + +#define S_ANC_LINK_NPL_INTERFACE_WRITE_DQS 13 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_WRITE_DQS _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_WRITE_DQS) +#define V_ANC_LINK_NPL_INTERFACE_WRITE_DQS(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS) +#define G_ANC_LINK_NPL_INTERFACE_WRITE_DQS(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS,M_ANC_LINK_NPL_INTERFACE_WRITE_DQS) + +#define S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE 14 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE) +#define V_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE) +#define G_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE,M_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE) + +#define S_ANC_LINK_NPL_INTERFACE_PULLDOWN 15 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_PULLDOWN _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_PULLDOWN) +#define V_ANC_LINK_NPL_INTERFACE_PULLDOWN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_PULLDOWN) +#define G_ANC_LINK_NPL_INTERFACE_PULLDOWN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_PULLDOWN,M_ANC_LINK_NPL_INTERFACE_PULLDOWN) + +#define S_ANC_LINK_NPL_INTERFACE_DATA_IN 16 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_DATA_IN _MM_MAKEMASK(8,S_ANC_LINK_NPL_INTERFACE_DATA_IN) +#define V_ANC_LINK_NPL_INTERFACE_DATA_IN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_IN) +#define G_ANC_LINK_NPL_INTERFACE_DATA_IN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_IN,M_ANC_LINK_NPL_INTERFACE_DATA_IN) + +#define S_ANC_LINK_NPL_INTERFACE_RSVD0 24 //Access: read-as-zero +#define M_ANC_LINK_NPL_INTERFACE_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_NPL_INTERFACE_RSVD0) +#define V_ANC_LINK_NPL_INTERFACE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_RSVD0) +#define G_ANC_LINK_NPL_INTERFACE_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_RSVD0,M_ANC_LINK_NPL_INTERFACE_RSVD0) + + +#define S_ANC_LINK_MACRO_STATUS_ADDRESS 0 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_ADDRESS _MM_MAKEMASK(8,S_ANC_LINK_MACRO_STATUS_ADDRESS) +#define V_ANC_LINK_MACRO_STATUS_ADDRESS(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_ADDRESS) +#define G_ANC_LINK_MACRO_STATUS_ADDRESS(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_ADDRESS,M_ANC_LINK_MACRO_STATUS_ADDRESS) + +#define S_ANC_LINK_MACRO_STATUS_WORD_COUNT 8 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_WORD_COUNT _MM_MAKEMASK(8,S_ANC_LINK_MACRO_STATUS_WORD_COUNT) +#define V_ANC_LINK_MACRO_STATUS_WORD_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_WORD_COUNT) +#define G_ANC_LINK_MACRO_STATUS_WORD_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_WORD_COUNT,M_ANC_LINK_MACRO_STATUS_WORD_COUNT) + +#define S_ANC_LINK_MACRO_STATUS_LOOP_COUNT 16 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_LOOP_COUNT _MM_MAKEMASK(8,S_ANC_LINK_MACRO_STATUS_LOOP_COUNT) +#define V_ANC_LINK_MACRO_STATUS_LOOP_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_LOOP_COUNT) +#define G_ANC_LINK_MACRO_STATUS_LOOP_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_LOOP_COUNT,M_ANC_LINK_MACRO_STATUS_LOOP_COUNT) + +#define S_ANC_LINK_MACRO_STATUS_ACTIVE 24 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_MACRO_STATUS_ACTIVE) +#define V_ANC_LINK_MACRO_STATUS_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_ACTIVE) +#define G_ANC_LINK_MACRO_STATUS_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_ACTIVE,M_ANC_LINK_MACRO_STATUS_ACTIVE) + +#define S_ANC_LINK_MACRO_STATUS_RSVD0 25 //Access: read-as-zero +#define M_ANC_LINK_MACRO_STATUS_RSVD0 _MM_MAKEMASK(7,S_ANC_LINK_MACRO_STATUS_RSVD0) +#define V_ANC_LINK_MACRO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_RSVD0) +#define G_ANC_LINK_MACRO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_RSVD0,M_ANC_LINK_MACRO_STATUS_RSVD0) + + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS 0 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS _MM_MAKEMASK(8,S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS,M_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT 8 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT _MM_MAKEMASK(8,S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT,M_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT 16 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT _MM_MAKEMASK(8,S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT,M_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE 24 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE,M_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0 25 //Access: read-as-zero +#define M_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0 _MM_MAKEMASK(7,S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0,M_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0) + + +#define S_ANC_LINK_NAND_STATUS_VALUE 0 //Access: read-only +#define M_ANC_LINK_NAND_STATUS_VALUE _MM_MAKEMASK(8,S_ANC_LINK_NAND_STATUS_VALUE) +#define V_ANC_LINK_NAND_STATUS_VALUE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NAND_STATUS_VALUE) +#define G_ANC_LINK_NAND_STATUS_VALUE(V) _MM_GETVALUE((V),S_ANC_LINK_NAND_STATUS_VALUE,M_ANC_LINK_NAND_STATUS_VALUE) + +#define S_ANC_LINK_NAND_STATUS_RSVD0 8 //Access: read-as-zero +#define M_ANC_LINK_NAND_STATUS_RSVD0 _MM_MAKEMASK(24,S_ANC_LINK_NAND_STATUS_RSVD0) +#define V_ANC_LINK_NAND_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_NAND_STATUS_RSVD0) +#define G_ANC_LINK_NAND_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_NAND_STATUS_RSVD0,M_ANC_LINK_NAND_STATUS_RSVD0) + + +#define S_ANC_MACRO_TABLE_COMMAND 0 //Access: memory +#define M_ANC_MACRO_TABLE_COMMAND _MM_MAKEMASK(32,S_ANC_MACRO_TABLE_COMMAND) +#define V_ANC_MACRO_TABLE_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_MACRO_TABLE_COMMAND) +#define G_ANC_MACRO_TABLE_COMMAND(V) _MM_GETVALUE((V),S_ANC_MACRO_TABLE_COMMAND,M_ANC_MACRO_TABLE_COMMAND) + + +#define S_ANC_DMA_CMDQ_FIFO_DA_WORD 0 //Access: memory +#define M_ANC_DMA_CMDQ_FIFO_DA_WORD _MM_MAKEMASK(32,S_ANC_DMA_CMDQ_FIFO_DA_WORD) +#define V_ANC_DMA_CMDQ_FIFO_DA_WORD(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_FIFO_DA_WORD) +#define G_ANC_DMA_CMDQ_FIFO_DA_WORD(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_FIFO_DA_WORD,M_ANC_DMA_CMDQ_FIFO_DA_WORD) + + +#define S_ANC_LINK_CMDQ_FIFO_DA_WORD 0 //Access: memory +#define M_ANC_LINK_CMDQ_FIFO_DA_WORD _MM_MAKEMASK(32,S_ANC_LINK_CMDQ_FIFO_DA_WORD) +#define V_ANC_LINK_CMDQ_FIFO_DA_WORD(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_FIFO_DA_WORD) +#define G_ANC_LINK_CMDQ_FIFO_DA_WORD(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_FIFO_DA_WORD,M_ANC_LINK_CMDQ_FIFO_DA_WORD) + + +#define S_ANC_LINK_BYPASS_FIFO_DA_WORD 0 //Access: memory +#define M_ANC_LINK_BYPASS_FIFO_DA_WORD _MM_MAKEMASK(32,S_ANC_LINK_BYPASS_FIFO_DA_WORD) +#define V_ANC_LINK_BYPASS_FIFO_DA_WORD(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_FIFO_DA_WORD) +#define G_ANC_LINK_BYPASS_FIFO_DA_WORD(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_FIFO_DA_WORD,M_ANC_LINK_BYPASS_FIFO_DA_WORD) + + +#define S_ANC_PIO_READ_FIFO_DA_WORD 0 //Access: memory +#define M_ANC_PIO_READ_FIFO_DA_WORD _MM_MAKEMASK(32,S_ANC_PIO_READ_FIFO_DA_WORD) +#define V_ANC_PIO_READ_FIFO_DA_WORD(V) _MM_MAKEVALUE((V),S_ANC_PIO_READ_FIFO_DA_WORD) +#define G_ANC_PIO_READ_FIFO_DA_WORD(V) _MM_GETVALUE((V),S_ANC_PIO_READ_FIFO_DA_WORD,M_ANC_PIO_READ_FIFO_DA_WORD) + + +#define S_ANC_DMA_DEBUG_FIFO_COMMAND 0 //Access: memory +#define M_ANC_DMA_DEBUG_FIFO_COMMAND _MM_MAKEMASK(32,S_ANC_DMA_DEBUG_FIFO_COMMAND) +#define V_ANC_DMA_DEBUG_FIFO_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_DMA_DEBUG_FIFO_COMMAND) +#define G_ANC_DMA_DEBUG_FIFO_COMMAND(V) _MM_GETVALUE((V),S_ANC_DMA_DEBUG_FIFO_COMMAND,M_ANC_DMA_DEBUG_FIFO_COMMAND) + + +#define S_ANC_LINK_DEBUG_FIFO_COMMAND 0 //Access: memory +#define M_ANC_LINK_DEBUG_FIFO_COMMAND _MM_MAKEMASK(32,S_ANC_LINK_DEBUG_FIFO_COMMAND) +#define V_ANC_LINK_DEBUG_FIFO_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_LINK_DEBUG_FIFO_COMMAND) +#define G_ANC_LINK_DEBUG_FIFO_COMMAND(V) _MM_GETVALUE((V),S_ANC_LINK_DEBUG_FIFO_COMMAND,M_ANC_LINK_DEBUG_FIFO_COMMAND) + + + +/******************************************************************************/ +/* Register Fields typedef structs */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ + +typedef union anc_chan_version_t { //RRV:0x00000100 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t minor_release:8; //Access: read-only + uint32_t major_release:8; //Access: read-only + uint32_t version:8; //Access: read-only + uint32_t rsvd0:8; //Access: read-as-zero + }f; +} anc_chan_version_t; + +typedef union anc_chan_config_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t auto_clk_gating_en:1; //Access: read-write + uint32_t rsvd0:31; //Access: read-as-zero + }f; +} anc_chan_config_t; + +typedef union anc_chan_int_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t dma_cmd_flag:1; //Access: write-once-clear + uint32_t link_cmd_flag:1; //Access: write-once-clear + uint32_t channel_stopped:1; //Access: write-once-clear + uint32_t dma_cmdq_fifo_low:1; //Access: read-only + uint32_t link_cmdq_fifo_low:1; //Access: read-only + uint32_t link_bypass_fifo_low:1; //Access: read-only + uint32_t link_pio_read_fifo_high:1; //Access: read-only + uint32_t dma_cmdq_fifo_overflow:1; //Access: write-once-clear + uint32_t link_cmdq_fifo_overflow:1; //Access: write-once-clear + uint32_t link_bypass_fifo_overflow:1; //Access: write-once-clear + uint32_t link_pio_read_fifo_underflow:1; //Access: write-once-clear + uint32_t crc_err:1; //Access: write-once-clear + uint32_t read_status_err_response:1; //Access: write-once-clear + uint32_t invalid_dma_command:1; //Access: write-once-clear + uint32_t invalid_link_command:1; //Access: write-once-clear + uint32_t axi_response_not_okay:1; //Access: write-once-clear + uint32_t aes_err:1; //Access: write-once-clear + uint32_t dma_cmd_timeout:1; //Access: write-once-clear + uint32_t link_cmd_timeout:1; //Access: write-once-clear + uint32_t rsvd0:13; //Access: read-as-zero + }f; +} anc_chan_int_status_t; + +typedef union anc_chan_int_enable_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t dma_cmd_flag:1; //Access: read-write + uint32_t link_cmd_flag:1; //Access: read-write + uint32_t channel_stopped:1; //Access: read-write + uint32_t dma_cmdq_fifo_low:1; //Access: read-write + uint32_t link_cmdq_fifo_low:1; //Access: read-write + uint32_t link_bypass_fifo_low:1; //Access: read-write + uint32_t link_pio_read_fifo_high:1; //Access: read-write + uint32_t dma_cmdq_fifo_overflow:1; //Access: read-write + uint32_t link_cmdq_fifo_overflow:1; //Access: read-write + uint32_t link_bypass_fifo_overflow:1; //Access: read-write + uint32_t link_pio_read_fifo_underflow:1; //Access: read-write + uint32_t crc_err:1; //Access: read-write + uint32_t read_status_err_response:1; //Access: read-write + uint32_t invalid_dma_command:1; //Access: read-write + uint32_t invalid_link_command:1; //Access: read-write + uint32_t axi_response_not_okay:1; //Access: read-write + uint32_t aes_err:1; //Access: read-write + uint32_t dma_cmd_timeout:1; //Access: read-write + uint32_t link_cmd_timeout:1; //Access: read-write + uint32_t rsvd0:13; //Access: read-as-zero + }f; +} anc_chan_int_enable_t; + +typedef union anc_chan_dma_watermarks_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t dma_cmdq_fifo_low:7; //Access: read-write + uint32_t rsvd0:25; //Access: read-as-zero + }f; +} anc_chan_dma_watermarks_t; + +typedef union anc_chan_link_watermarks_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t link_cmdq_fifo_low:8; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + uint32_t link_bypass_fifo_low:4; //Access: read-write + uint32_t rsvd1:4; //Access: read-as-zero + uint32_t link_pio_read_fifo_high:7; //Access: read-write + uint32_t rsvd2:1; //Access: read-as-zero + }f; +} anc_chan_link_watermarks_t; + +typedef union anc_chan_dma_cmdq_fifo_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t low:1; //Access: read-only + uint32_t full:1; //Access: read-only + uint32_t overflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t read_pointer:6; //Access: read-only + uint32_t rsvd2:2; //Access: read-as-zero + uint32_t write_pointer:6; //Access: read-only + uint32_t rsvd3:2; //Access: read-as-zero + }f; +} anc_chan_dma_cmdq_fifo_status_t; + +typedef union anc_chan_link_cmdq_fifo_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t low:1; //Access: read-only + uint32_t full:1; //Access: read-only + uint32_t overflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:8; //Access: read-only + uint32_t read_pointer:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t write_pointer:7; //Access: read-only + uint32_t rsvd2:1; //Access: read-as-zero + }f; +} anc_chan_link_cmdq_fifo_status_t; + +typedef union anc_chan_link_bypass_fifo_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t low:1; //Access: read-only + uint32_t full:1; //Access: read-only + uint32_t overflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:4; //Access: read-only + uint32_t rsvd1:4; //Access: read-as-zero + uint32_t read_pointer:3; //Access: read-only + uint32_t rsvd2:5; //Access: read-as-zero + uint32_t write_pointer:3; //Access: read-only + uint32_t rsvd3:5; //Access: read-as-zero + }f; +} anc_chan_link_bypass_fifo_status_t; + +typedef union anc_chan_link_pio_read_fifo_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t high:1; //Access: read-only + uint32_t empty:1; //Access: read-only + uint32_t underflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t read_pointer:6; //Access: read-only + uint32_t rsvd2:2; //Access: read-as-zero + uint32_t write_pointer:6; //Access: read-only + uint32_t rsvd3:2; //Access: read-as-zero + }f; +} anc_chan_link_pio_read_fifo_status_t; + +typedef union anc_chan_dma_debug_fifo_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t write_pointer:4; //Access: read-only + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} anc_chan_dma_debug_fifo_status_t; + +typedef union anc_chan_link_debug_fifo_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t write_pointer:5; //Access: read-only + uint32_t rsvd0:27; //Access: read-as-zero + }f; +} anc_chan_link_debug_fifo_status_t; + +typedef union anc_chan_dma_cmdq_fifo_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t push_word:32; //Access: write-only + }f; +} anc_chan_dma_cmdq_fifo_t; + +typedef union anc_chan_link_cmdq_fifo_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t push_word:32; //Access: write-only + }f; +} anc_chan_link_cmdq_fifo_t; + +typedef union anc_chan_link_bypass_fifo_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t push_word:32; //Access: write-only + }f; +} anc_chan_link_bypass_fifo_t; + +typedef union anc_chan_link_pio_read_fifo_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t pop_word:32; //Access: read-only + }f; +} anc_chan_link_pio_read_fifo_t; + +typedef union anc_chan_dma_debug_fifo_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t pop_word:32; //Access: read-only + }f; +} anc_chan_dma_debug_fifo_t; + +typedef union anc_chan_link_debug_fifo_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t pop_word:32; //Access: read-only + }f; +} anc_chan_link_debug_fifo_t; + + +typedef union anc_dma_config_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t axi_axqos:4; //Access: read-write + uint32_t rsvd0:4; //Access: read-as-zero + uint32_t burst_size:2; //Access: read-write + uint32_t rsvd1:22; //Access: read-as-zero + }f; +} anc_dma_config_t; + +typedef union anc_dma_control_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t start:1; //Access: write-auto-clear + uint32_t stop:1; //Access: write-auto-clear + uint32_t reset:1; //Access: write-auto-clear + uint32_t rsvd0:29; //Access: read-as-zero + }f; +} anc_dma_control_t; + +typedef union anc_dma_uid_config_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t disable_uid:1; //Access: write-only + uint32_t rsvd0:31; //Access: read-as-zero + }f; +} anc_dma_uid_config_t; + +typedef union anc_dma_status_t { //RRV:0x00000007 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t dma_active:1; //Access: read-only + uint32_t axi_active:1; //Access: read-only + uint32_t aes_active:1; //Access: read-only + uint32_t cmdq_enabled:1; //Access: read-only + uint32_t aes_enabled:1; //Access: read-only + uint32_t dma_direction:1; //Access: read-only + uint32_t rsvd0:26; //Access: read-as-zero + }f; +} anc_dma_status_t; + +typedef union anc_dma_aes_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t wrapping_enabled:1; //Access: read-only + uint32_t key_select:1; //Access: read-only + uint32_t key_length:2; //Access: read-only + uint32_t uid_disabled:1; //Access: read-only + uint32_t key_in_ctx:1; //Access: read-only + uint32_t iv_in_ctx:1; //Access: read-only + uint32_t txt_in_key_ctx:1; //Access: read-only + uint32_t txt_in_iv_ctx:1; //Access: read-only + uint32_t aes_err:1; //Access: read-only + uint32_t rsvd0:22; //Access: read-as-zero + }f; +} anc_dma_aes_status_t; + +typedef union anc_dma_cmdq_count_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t total:32; //Access: read-only + }f; +} anc_dma_cmdq_count_t; + +typedef union anc_dma_cmd_timeout_t { //RRV:0x7fffffff + uint32_t all; //RRM:0x00000000 + struct { + uint32_t value:31; //Access: read-write + uint32_t enable:1; //Access: read-write + }f; +} anc_dma_cmd_timeout_t; + +typedef union anc_dma_cmdq_int_code_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t code:16; //Access: read-only + uint32_t rsvd0:16; //Access: read-as-zero + }f; +} anc_dma_cmdq_int_code_t; + +typedef union anc_dma_axi_t { //RRV:0x20000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t address_requests_outstanding:5; //Access: read-only + uint32_t address_requests_words_remaining:9; //Access: read-only + uint32_t response:2; //Access: read-only + uint32_t write_data_available:7; //Access: read-only + uint32_t read_space_available:7; //Access: read-only + uint32_t rsvd0:2; //Access: read-as-zero + }f; +} anc_dma_axi_t; + +typedef union anc_dma_axi_next_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t request_length:4; //Access: read-only + uint32_t rsvd0:20; //Access: read-as-zero + uint32_t address_high_byte:8; //Access: read-only + }f; +} anc_dma_axi_next_t; + +typedef union anc_dma_axi_next_address_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t lower_four_bytes:32; //Access: read-only + }f; +} anc_dma_axi_next_address_t; + + +typedef union anc_link_config_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t ddr_mode:1; //Access: read-write + uint32_t enable_crc:1; //Access: read-write + uint32_t autopad_crc:1; //Access: read-write + uint32_t rsvd0:29; //Access: read-as-zero + }f; +} anc_link_config_t; + +typedef union anc_link_control_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t start:1; //Access: write-auto-clear + uint32_t stop:1; //Access: write-auto-clear + uint32_t yield:1; //Access: write-auto-clear + uint32_t abort:1; //Access: write-auto-clear + uint32_t reset:1; //Access: write-auto-clear + uint32_t start_cmdq:1; //Access: write-auto-clear + uint32_t stop_cmdq:1; //Access: write-auto-clear + uint32_t reset_cmdq:1; //Access: write-auto-clear + uint32_t start_bypass:1; //Access: write-auto-clear + uint32_t stop_bypass:1; //Access: write-auto-clear + uint32_t reset_bypass:1; //Access: write-auto-clear + uint32_t start_timer:1; //Access: write-auto-clear + uint32_t stop_timer:1; //Access: write-auto-clear + uint32_t reset_timer:1; //Access: write-auto-clear + uint32_t reset_pio_read:1; //Access: write-auto-clear + uint32_t rsvd0:17; //Access: read-as-zero + }f; +} anc_link_control_t; + +typedef union anc_link_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t cmdq_active:1; //Access: read-only + uint32_t fsm_active:1; //Access: read-only + uint32_t read_hold_active:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t cmdq_state:4; //Access: read-only + uint32_t rsvd1:4; //Access: read-as-zero + uint32_t fsm_state:6; //Access: read-only + uint32_t rsvd2:10; //Access: read-as-zero + }f; +} anc_link_status_t; + +typedef union anc_link_chip_enable_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t ce:8; //Access: read-write + uint32_t rsvd0:24; //Access: read-as-zero + }f; +} anc_link_chip_enable_t; + +typedef union anc_link_read_status_config_t { //RRV:0x00004040 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t position:8; //Access: read-write + uint32_t polarity:8; //Access: read-write + uint32_t status_capture_delay:4; //Access: read-write + uint32_t ready_sample_delay:4; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + }f; +} anc_link_read_status_config_t; + +typedef union anc_link_command_address_pulse_timing_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t ca_setup_time:5; //Access: read-write + uint32_t rsvd0:3; //Access: read-as-zero + uint32_t ca_hold_time:5; //Access: read-write + uint32_t rsvd1:19; //Access: read-as-zero + }f; +} anc_link_command_address_pulse_timing_t; + +typedef union anc_link_sdr_timing_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t cle_ale_setup_time:5; //Access: read-write + uint32_t rsvd0:3; //Access: read-as-zero + uint32_t cle_ale_hold_time:5; //Access: read-write + uint32_t rsvd1:3; //Access: read-as-zero + uint32_t data_capture_delay:5; //Access: read-write + uint32_t rsvd2:11; //Access: read-as-zero + }f; +} anc_link_sdr_timing_t; + +typedef union anc_link_sdr_data_timing_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t ren_setup_time:5; //Access: read-write + uint32_t rsvd0:3; //Access: read-as-zero + uint32_t ren_hold_time:5; //Access: read-write + uint32_t rsvd1:3; //Access: read-as-zero + uint32_t wen_setup_time:5; //Access: read-write + uint32_t rsvd2:3; //Access: read-as-zero + uint32_t wen_hold_time:5; //Access: read-write + uint32_t rsvd3:3; //Access: read-as-zero + }f; +} anc_link_sdr_data_timing_t; + +typedef union anc_link_ddr_data_timing_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t ddr_pulse_width:5; //Access: read-write + uint32_t rsvd0:27; //Access: read-as-zero + }f; +} anc_link_ddr_data_timing_t; + +typedef union anc_link_ddr_read_timing_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t read_preamble:8; //Access: read-write + uint32_t read_postamble:8; //Access: read-write + uint32_t read_postamble_hold:8; //Access: read-write + uint32_t read_turnaround:8; //Access: read-write + }f; +} anc_link_ddr_read_timing_t; + +typedef union anc_link_ddr_write_timing_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t write_preamble:8; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + uint32_t write_postamble:8; //Access: read-write + uint32_t rsvd1:8; //Access: read-as-zero + }f; +} anc_link_ddr_write_timing_t; + +typedef union anc_link_dqs_timing_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t write_dqs_delay:6; //Access: read-write + uint32_t rsvd0:26; //Access: read-as-zero + }f; +} anc_link_dqs_timing_t; + +typedef union anc_link_cmdq_count_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t total:32; //Access: read-only + }f; +} anc_link_cmdq_count_t; + +typedef union anc_link_bypass_count_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t total:32; //Access: read-only + }f; +} anc_link_bypass_count_t; + +typedef union anc_link_cmd_timeout_t { //RRV:0x7fffffff + uint32_t all; //RRM:0x00000000 + struct { + uint32_t value:31; //Access: read-write + uint32_t enable:1; //Access: read-write + }f; +} anc_link_cmd_timeout_t; + +typedef union anc_link_cmdq_int_code_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t code:16; //Access: read-only + uint32_t rsvd0:16; //Access: read-as-zero + }f; +} anc_link_cmdq_int_code_t; + +typedef union anc_link_timer_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t count:32; //Access: read-only + }f; +} anc_link_timer_t; + +typedef union anc_link_crc_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t parity_data:32; //Access: read-only + }f; +} anc_link_crc_t; + +typedef union anc_link_npl_interface_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t cle:1; //Access: read-only + uint32_t ale:1; //Access: read-only + uint32_t ren:1; //Access: read-only + uint32_t wen:1; //Access: read-only + uint32_t data_out:8; //Access: read-only + uint32_t data_out_enable:1; //Access: read-only + uint32_t write_dqs:1; //Access: read-only + uint32_t write_dqs_enable:1; //Access: read-only + uint32_t pulldown:1; //Access: read-only + uint32_t data_in:8; //Access: read-only + uint32_t rsvd0:8; //Access: read-as-zero + }f; +} anc_link_npl_interface_t; + +typedef union anc_link_macro_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t address:8; //Access: read-only + uint32_t word_count:8; //Access: read-only + uint32_t loop_count:8; //Access: read-only + uint32_t active:1; //Access: read-only + uint32_t rsvd0:7; //Access: read-as-zero + }f; +} anc_link_macro_status_t; + +typedef union anc_link_bypass_macro_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t address:8; //Access: read-only + uint32_t word_count:8; //Access: read-only + uint32_t loop_count:8; //Access: read-only + uint32_t active:1; //Access: read-only + uint32_t rsvd0:7; //Access: read-as-zero + }f; +} anc_link_bypass_macro_status_t; + +typedef union anc_link_nand_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t value:8; //Access: read-only + uint32_t rsvd0:24; //Access: read-as-zero + }f; +} anc_link_nand_status_t; + + +/******************************************************************************/ +/* Registers typedef structs */ +/******************************************************************************/ +/* errors in perl template and spds required these to be commented out + + +typedef union anc_chan_t { + uint32_t all[192]; + struct { + anc_chan_version_t VERSION ; // 0x00000000 + anc_chan_config_t CONFIG ; // 0x00000004 + anc_chan_int_status_t INT_STATUS ; // 0x00000008 + anc_chan_int_enable_t INT_ENABLE ; // 0x0000000c + anc_chan_dma_watermarks_t DMA_WATERMARKS ; // 0x00000010 + anc_chan_link_watermarks_t LINK_WATERMARKS ; // 0x00000014 + anc_chan_dma_cmdq_fifo_status_t DMA_CMDQ_FIFO_STATUS ; // 0x00000018 + anc_chan_link_cmdq_fifo_status_t LINK_CMDQ_FIFO_STATUS ; // 0x0000001c + anc_chan_link_bypass_fifo_status_t LINK_BYPASS_FIFO_STATUS ; // 0x00000020 + anc_chan_link_pio_read_fifo_status_t LINK_PIO_READ_FIFO_STATUS ; // 0x00000024 + anc_chan_dma_debug_fifo_status_t DMA_DEBUG_FIFO_STATUS ; // 0x00000028 + anc_chan_link_debug_fifo_status_t LINK_DEBUG_FIFO_STATUS ; // 0x0000002c + uint32_t rsvd0[52]; + anc_chan_dma_cmdq_fifo_t DMA_CMDQ_FIFO ; // 0x00000100 + uint32_t rsvd1[15]; + anc_chan_link_cmdq_fifo_t LINK_CMDQ_FIFO ; // 0x00000140 + uint32_t rsvd2[15]; + anc_chan_link_bypass_fifo_t LINK_BYPASS_FIFO ; // 0x00000180 + uint32_t rsvd3[15]; + anc_chan_link_pio_read_fifo_t LINK_PIO_READ_FIFO ; // 0x000001c0 + uint32_t rsvd4[15]; + anc_chan_dma_debug_fifo_t DMA_DEBUG_FIFO ; // 0x00000200 + uint32_t rsvd5[15]; + anc_chan_link_debug_fifo_t LINK_DEBUG_FIFO ; // 0x00000240 + }r; +} anc_chan_t; + + +typedef union anc_dma_t { + uint32_t all[192]; + struct { + anc_dma_config_t CONFIG ; // 0x00001000 + anc_dma_control_t CONTROL ; // 0x00001004 + anc_dma_uid_config_t UID_CONFIG ; // 0x00001008 + anc_dma_status_t STATUS ; // 0x0000100c + anc_dma_aes_status_t AES_STATUS ; // 0x00001010 + anc_dma_cmdq_count_t CMDQ_COUNT ; // 0x00001014 + anc_dma_cmd_timeout_t CMD_TIMEOUT ; // 0x00001018 + anc_dma_cmdq_int_code_t CMDQ_INT_CODE ; // 0x0000101c + anc_dma_axi_t AXI ; // 0x00001020 + anc_dma_axi_next_t AXI_NEXT ; // 0x00001024 + anc_dma_axi_next_address_t AXI_NEXT_ADDRESS ; // 0x00001028 + }r; +} anc_dma_t; + + +typedef union anc_link_t { + uint32_t all[64]; + struct { + anc_link_config_t CONFIG ; // 0x00002000 + anc_link_control_t CONTROL ; // 0x00002004 + anc_link_status_t STATUS ; // 0x00002008 + anc_link_chip_enable_t CHIP_ENABLE ; // 0x0000200c + anc_link_read_status_config_t READ_STATUS_CONFIG ; // 0x00002010 + anc_link_command_address_pulse_timing_t COMMAND_ADDRESS_PULSE_TIMING ; // 0x00002014 + anc_link_sdr_timing_t SDR_TIMING ; // 0x00002018 + anc_link_sdr_data_timing_t SDR_DATA_TIMING ; // 0x0000201c + anc_link_ddr_data_timing_t DDR_DATA_TIMING ; // 0x00002020 + anc_link_ddr_read_timing_t DDR_READ_TIMING ; // 0x00002024 + anc_link_ddr_write_timing_t DDR_WRITE_TIMING ; // 0x00002028 + anc_link_dqs_timing_t DQS_TIMING ; // 0x0000202c + anc_link_cmdq_count_t CMDQ_COUNT ; // 0x00002030 + anc_link_bypass_count_t BYPASS_COUNT ; // 0x00002034 + anc_link_cmd_timeout_t CMD_TIMEOUT ; // 0x00002038 + anc_link_cmdq_int_code_t CMDQ_INT_CODE ; // 0x0000203c + anc_link_timer_t TIMER ; // 0x00002040 + anc_link_crc_t CRC ; // 0x00002044 + anc_link_npl_interface_t NPL_INTERFACE ; // 0x00002048 + anc_link_macro_status_t MACRO_STATUS ; // 0x0000204c + anc_link_bypass_macro_status_t BYPASS_MACRO_STATUS ; // 0x00002050 + anc_link_nand_status_t NAND_STATUS ; // 0x00002054 + }r; +} anc_link_t; + + +typedef union anc_regs_s{ + struct { + anc_chan_t CHAN; // 0x00000000 + uint32_t rsvd0[832]; + anc_dma_t DMA; // 0x00001000 + uint32_t rsvd1[832]; + anc_link_t LINK; // 0x00002000 + }ab; + uint32_t all[2112]; + }; +}anc_regs_t; +*/ + +/******************************************************************************/ +/* Registers enum */ +/******************************************************************************/ +/* errors in perl template and spds required these to be commented out + + +typedef enum anc_chan_regenum { + version = 0, + config = 1, + int_status = 2, + int_enable = 3, + dma_watermarks = 4, + link_watermarks = 5, + dma_cmdq_fifo_status = 6, + link_cmdq_fifo_status = 7, + link_bypass_fifo_status = 8, + link_pio_read_fifo_status = 9, + dma_debug_fifo_status = 10, + link_debug_fifo_status = 11, + rsvd_anc_chan_0_52 = 63, + dma_cmdq_fifo = 64, + rsvd_anc_chan_1_15 = 79, + link_cmdq_fifo = 80, + rsvd_anc_chan_2_15 = 95, + link_bypass_fifo = 96, + rsvd_anc_chan_3_15 = 111, + link_pio_read_fifo = 112, + rsvd_anc_chan_4_15 = 127, + dma_debug_fifo = 128, + rsvd_anc_chan_5_15 = 143, + link_debug_fifo = 144, +}anc_chan_regenum; + + +typedef enum anc_dma_regenum { + config = 0, + control = 1, + uid_config = 2, + status = 3, + aes_status = 4, + cmdq_count = 5, + cmd_timeout = 6, + cmdq_int_code = 7, + axi = 8, + axi_next = 9, + axi_next_address = 10, +}anc_dma_regenum; + + +typedef enum anc_link_regenum { + config = 0, + control = 1, + status = 2, + chip_enable = 3, + read_status_config = 4, + command_address_pulse_timing = 5, + sdr_timing = 6, + sdr_data_timing = 7, + ddr_data_timing = 8, + ddr_read_timing = 9, + ddr_write_timing = 10, + dqs_timing = 11, + cmdq_count = 12, + bypass_count = 13, + cmd_timeout = 14, + cmdq_int_code = 15, + timer = 16, + crc = 17, + npl_interface = 18, + macro_status = 19, + bypass_macro_status = 20, + nand_status = 21, +}anc_link_regenum; + + + + + + + + + +*/ +#endif +#endif diff --git a/drivers/apple/anc/anc_bootrom_regs_m7.h b/drivers/apple/anc/anc_bootrom_regs_m7.h new file mode 100644 index 0000000..e53fe9c --- /dev/null +++ b/drivers/apple/anc/anc_bootrom_regs_m7.h @@ -0,0 +1,3393 @@ + +// +// Copyright (C) 2013 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form +// in whole or in part, without the express written permission of +// Apple Inc. +// +#ifndef __ANC_H__ +#define __ANC_H__ + +#define _MM_MAKEMASK(width, offset) (((1 << (width)) - 1) << (offset)) +#define _MM_MAKEVALUE(value, offset) ((value) << (offset)) +#define _MM_GETVALUE(registerContent, offset, mask) (((registerContent) & (mask))>> (offset)) + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_CHAN_BASE 0x00000000 +#define A_ANC_CHAN_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_CHAN_VERSION 0x00000000 +#define R_ANC_CHAN_CONFIG 0x00000004 +#define R_ANC_CHAN_INT_STATUS 0x00000008 +#define R_ANC_CHAN_INT_ENABLE 0x0000000c +#define R_ANC_CHAN_DMA_WATERMARKS 0x00000010 +#define R_ANC_CHAN_LINK_WATERMARKS 0x00000014 +#define R_ANC_CHAN_STATUS_WATERMARKS 0x00000018 +#define R_ANC_CHAN_DMA_CMDQ_FIFO_STATUS 0x0000001c +#define R_ANC_CHAN_LINK_CMDQ_FIFO_STATUS 0x00000020 +#define R_ANC_CHAN_LINK_BYPASS_FIFO_STATUS 0x00000024 +#define R_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS 0x00000028 +#define R_ANC_CHAN_DMA_DEBUG_FIFO_STATUS 0x0000002c +#define R_ANC_CHAN_LINK_DEBUG_FIFO_STATUS 0x00000030 +#define R_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS 0x00000034 +#define R_ANC_CHAN_DMA_CMDQ_FIFO 0x00000100 +#define R_ANC_CHAN_LINK_CMDQ_FIFO 0x00000140 +#define R_ANC_CHAN_LINK_BYPASS_FIFO 0x00000180 +#define R_ANC_CHAN_LINK_PIO_READ_FIFO 0x000001c0 +#define R_ANC_CHAN_DMA_DEBUG_FIFO 0x00000200 +#define R_ANC_CHAN_LINK_DEBUG_FIFO 0x00000240 +#define R_ANC_CHAN_LINK_ECC_STATUS_FIFO 0x00000280 +#define R_ANC_CHAN_LAST 0x00000280 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_CHAN_VERSION +#define rANC_CHAN_CONFIG +#define rANC_CHAN_INT_STATUS +#define rANC_CHAN_INT_ENABLE +#define rANC_CHAN_DMA_WATERMARKS +#define rANC_CHAN_LINK_WATERMARKS +#define rANC_CHAN_STATUS_WATERMARKS +#define rANC_CHAN_DMA_CMDQ_FIFO_STATUS +#define rANC_CHAN_LINK_CMDQ_FIFO_STATUS +#define rANC_CHAN_LINK_BYPASS_FIFO_STATUS +#define rANC_CHAN_LINK_PIO_READ_FIFO_STATUS +#define rANC_CHAN_DMA_DEBUG_FIFO_STATUS +#define rANC_CHAN_LINK_DEBUG_FIFO_STATUS +#define rANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS +#define rANC_CHAN_DMA_CMDQ_FIFO +#define rANC_CHAN_LINK_CMDQ_FIFO +#define rANC_CHAN_LINK_BYPASS_FIFO +#define rANC_CHAN_LINK_PIO_READ_FIFO +#define rANC_CHAN_DMA_DEBUG_FIFO +#define rANC_CHAN_LINK_DEBUG_FIFO +#define rANC_CHAN_LINK_ECC_STATUS_FIFO +#define rANC_CHAN_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_DMA_BASE 0x00001000 +#define A_ANC_DMA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_DMA_CONFIG 0x00001000 +#define R_ANC_DMA_CONTROL 0x00001004 +#define R_ANC_DMA_STATUS 0x00001008 +#define R_ANC_DMA_AES_STATUS 0x0000100c +#define R_ANC_DMA_CMDQ_COUNT 0x00001010 +#define R_ANC_DMA_CMD_TIMEOUT 0x00001014 +#define R_ANC_DMA_CMDQ_INT_CODE 0x00001018 +#define R_ANC_DMA_AXI 0x0000101c +#define R_ANC_DMA_AXI_NEXT 0x00001020 +#define R_ANC_DMA_AXI_NEXT_ADDRESS 0x00001024 +#define R_ANC_DMA_AXI_DMA_COUNT 0x00001028 +#define R_ANC_DMA_AXI_COUNT 0x0000102c +#define R_ANC_DMA_DLFIFO_COUNT 0x00001030 +#define R_ANC_DMA_DLFIFO_DMA_COUNT 0x00001034 +#define R_ANC_DMA_AXI_DMA_LAST_COUNT 0x00001038 +#define R_ANC_DMA_AXI_LAST_COUNT 0x0000103c +#define R_ANC_DMA_DLFIFO_LAST_COUNT 0x00001040 +#define R_ANC_DMA_DLFIFO_DMA_LAST_COUNT 0x00001044 +#define R_ANC_DMA_LAST 0x00001044 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_DMA_CONFIG +#define rANC_DMA_CONTROL +#define rANC_DMA_STATUS +#define rANC_DMA_AES_STATUS +#define rANC_DMA_CMDQ_COUNT +#define rANC_DMA_CMD_TIMEOUT +#define rANC_DMA_CMDQ_INT_CODE +#define rANC_DMA_AXI +#define rANC_DMA_AXI_NEXT +#define rANC_DMA_AXI_NEXT_ADDRESS +#define rANC_DMA_AXI_DMA_COUNT +#define rANC_DMA_AXI_COUNT +#define rANC_DMA_DLFIFO_COUNT +#define rANC_DMA_DLFIFO_DMA_COUNT +#define rANC_DMA_AXI_DMA_LAST_COUNT +#define rANC_DMA_AXI_LAST_COUNT +#define rANC_DMA_DLFIFO_LAST_COUNT +#define rANC_DMA_DLFIFO_DMA_LAST_COUNT +#define rANC_DMA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_BASE 0x00002000 +#define A_ANC_LINK_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_CONFIG 0x00002000 +#define R_ANC_LINK_CONTROL 0x00002004 +#define R_ANC_LINK_STATUS 0x00002008 +#define R_ANC_LINK_CHIP_ENABLE 0x0000200c +#define R_ANC_LINK_READ_STATUS_CONFIG 0x00002010 +#define R_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING 0x00002014 +#define R_ANC_LINK_SDR_TIMING 0x00002018 +#define R_ANC_LINK_SDR_DATA_TIMING 0x0000201c +#define R_ANC_LINK_DDR_DATA_TIMING 0x00002020 +#define R_ANC_LINK_DDR_READ_TIMING 0x00002024 +#define R_ANC_LINK_DDR_WRITE_TIMING 0x00002028 +#define R_ANC_LINK_DQS_TIMING 0x0000202c +#define R_ANC_LINK_CMDQ_COUNT 0x00002030 +#define R_ANC_LINK_BYPASS_COUNT 0x00002034 +#define R_ANC_LINK_CMD_TIMEOUT 0x00002038 +#define R_ANC_LINK_CMDQ_INT_CODE 0x0000203c +#define R_ANC_LINK_TIMER 0x00002040 +#define R_ANC_LINK_CRC 0x00002044 +#define R_ANC_LINK_NPL_INTERFACE 0x00002048 +#define R_ANC_LINK_MACRO_STATUS 0x0000204c +#define R_ANC_LINK_BYPASS_MACRO_STATUS 0x00002050 +#define R_ANC_LINK_NAND_STATUS 0x00002054 +#define R_ANC_LINK_DLFIFO_LINK_COUNT 0x00002058 +#define R_ANC_LINK_DLFIFO_COUNT 0x0000205c +#define R_ANC_LINK_PIO_LINK_COUNT 0x00002060 +#define R_ANC_LINK_PIO_COUNT 0x00002064 +#define R_ANC_LINK_PHY_COUNT 0x00002068 +#define R_ANC_LINK_PHY_LINK_COUNT 0x0000206c +#define R_ANC_LINK_FSM_COUNTS 0x00002070 +#define R_ANC_LINK_ECC_WATERMARK 0x00002074 +#define R_ANC_LINK_ECC_CONFIG 0x00002078 +#define R_ANC_LINK_LAST 0x00002078 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_CONFIG +#define rANC_LINK_CONTROL +#define rANC_LINK_STATUS +#define rANC_LINK_CHIP_ENABLE +#define rANC_LINK_READ_STATUS_CONFIG +#define rANC_LINK_COMMAND_ADDRESS_PULSE_TIMING +#define rANC_LINK_SDR_TIMING +#define rANC_LINK_SDR_DATA_TIMING +#define rANC_LINK_DDR_DATA_TIMING +#define rANC_LINK_DDR_READ_TIMING +#define rANC_LINK_DDR_WRITE_TIMING +#define rANC_LINK_DQS_TIMING +#define rANC_LINK_CMDQ_COUNT +#define rANC_LINK_BYPASS_COUNT +#define rANC_LINK_CMD_TIMEOUT +#define rANC_LINK_CMDQ_INT_CODE +#define rANC_LINK_TIMER +#define rANC_LINK_CRC +#define rANC_LINK_NPL_INTERFACE +#define rANC_LINK_MACRO_STATUS +#define rANC_LINK_BYPASS_MACRO_STATUS +#define rANC_LINK_NAND_STATUS +#define rANC_LINK_DLFIFO_LINK_COUNT +#define rANC_LINK_DLFIFO_COUNT +#define rANC_LINK_PIO_LINK_COUNT +#define rANC_LINK_PIO_COUNT +#define rANC_LINK_PHY_COUNT +#define rANC_LINK_PHY_LINK_COUNT +#define rANC_LINK_FSM_COUNTS +#define rANC_LINK_ECC_WATERMARK +#define rANC_LINK_ECC_CONFIG +#define rANC_LINK_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_ECC_BASE 0x00002200 +#define A_ANC_ECC_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_ECC_P_CHIEN_CLOCK_CONFIG 0x00002200 +#define R_ANC_ECC_P_CONFIG 0x0000220c +#define R_ANC_ECC_P_OFFSET1 0x00002210 +#define R_ANC_ECC_P_BCH_DIRECTION_CNFG 0x00002218 +#define R_ANC_ECC_P_PAGE_IDX 0x0000221c +#define R_ANC_ECC_P_PAGE_STRUCTURE 0x00002220 +#define R_ANC_ECC_P_ECC_CLK_CNFG 0x00002224 +#define R_ANC_ECC_P_OFFSET3 0x00002228 +#define R_ANC_ECC_P_CHIEN_START_OFFSET 0x0000222c +#define R_ANC_ECC_P_CHIEN_EARLY_INTERRUPT 0x00002230 +#define R_ANC_ECC_P_OFFSET4 0x0000223c +#define R_ANC_ECC_P_STATUS 0x000022a0 +#define R_ANC_ECC_P_BCH_DIR_CNTRS 0x000022a4 +#define R_ANC_ECC_P_BMA_STATUS 0x000022b4 +#define R_ANC_ECC_LAST 0x000022b4 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_ECC_P_CHIEN_CLOCK_CONFIG +#define rANC_ECC_P_CONFIG +#define rANC_ECC_P_OFFSET1 +#define rANC_ECC_P_BCH_DIRECTION_CNFG +#define rANC_ECC_P_PAGE_IDX +#define rANC_ECC_P_PAGE_STRUCTURE +#define rANC_ECC_P_ECC_CLK_CNFG +#define rANC_ECC_P_OFFSET3 +#define rANC_ECC_P_CHIEN_START_OFFSET +#define rANC_ECC_P_CHIEN_EARLY_INTERRUPT +#define rANC_ECC_P_OFFSET4 +#define rANC_ECC_P_STATUS +#define rANC_ECC_P_BCH_DIR_CNTRS +#define rANC_ECC_P_BMA_STATUS +#define rANC_ECC_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_MACRO_TABLE_BASE 0x00003000 +#define A_ANC_MACRO_TABLE_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_MACRO_TABLE_COMMAND 0x00003000 +#define R_ANC_MACRO_TABLE_LAST 0x00003000 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_MACRO_TABLE_COMMAND +#define rANC_MACRO_TABLE_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_DMA_CMDQ_FIFO_DA_BASE 0x00004000 +#define A_ANC_DMA_CMDQ_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_DMA_CMDQ_FIFO_DA_WORD 0x00004000 +#define R_ANC_DMA_CMDQ_FIFO_DA_LAST 0x00004000 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_DMA_CMDQ_FIFO_DA_WORD +#define rANC_DMA_CMDQ_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_CMDQ_FIFO_DA_BASE 0x00004200 +#define A_ANC_LINK_CMDQ_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_CMDQ_FIFO_DA_WORD 0x00004200 +#define R_ANC_LINK_CMDQ_FIFO_DA_LAST 0x00004200 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_CMDQ_FIFO_DA_WORD +#define rANC_LINK_CMDQ_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_BYPASS_FIFO_DA_BASE 0x00004400 +#define A_ANC_LINK_BYPASS_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_BYPASS_FIFO_DA_WORD 0x00004400 +#define R_ANC_LINK_BYPASS_FIFO_DA_LAST 0x00004400 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_BYPASS_FIFO_DA_WORD +#define rANC_LINK_BYPASS_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_PIO_READ_FIFO_DA_BASE 0x00004500 +#define A_ANC_PIO_READ_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_PIO_READ_FIFO_DA_WORD 0x00004500 +#define R_ANC_PIO_READ_FIFO_DA_LAST 0x00004500 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_PIO_READ_FIFO_DA_WORD +#define rANC_PIO_READ_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_DMA_DEBUG_FIFO_BASE 0x00004600 +#define A_ANC_DMA_DEBUG_FIFO_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_DMA_DEBUG_FIFO_COMMAND 0x00004600 +#define R_ANC_DMA_DEBUG_FIFO_LAST 0x00004600 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_DMA_DEBUG_FIFO_COMMAND +#define rANC_DMA_DEBUG_FIFO_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_DEBUG_FIFO_BASE 0x00004700 +#define A_ANC_LINK_DEBUG_FIFO_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_DEBUG_FIFO_COMMAND 0x00004700 +#define R_ANC_LINK_DEBUG_FIFO_LAST 0x00004700 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_DEBUG_FIFO_COMMAND +#define rANC_LINK_DEBUG_FIFO_LAST +#endif + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_ANC_LINK_ECC_STATUS_FIFO_DA_BASE 0x00004800 +#define A_ANC_LINK_ECC_STATUS_FIFO_DA_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_ANC_LINK_ECC_STATUS_FIFO_DA_WORD 0x00004800 +#define R_ANC_LINK_ECC_STATUS_FIFO_DA_LAST 0x00004800 + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rANC_LINK_ECC_STATUS_FIFO_DA_WORD +#define rANC_LINK_ECC_STATUS_FIFO_DA_LAST +#endif + +/******************************************************************************/ +/* Register Fields defines */ +/******************************************************************************/ +#define S_ANC_CHAN_VERSION_MINOR_RELEASE 0 //Access: read-only +#define M_ANC_CHAN_VERSION_MINOR_RELEASE _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_MINOR_RELEASE) +#define V_ANC_CHAN_VERSION_MINOR_RELEASE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_MINOR_RELEASE) +#define G_ANC_CHAN_VERSION_MINOR_RELEASE(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_MINOR_RELEASE,M_ANC_CHAN_VERSION_MINOR_RELEASE) + +#define S_ANC_CHAN_VERSION_MAJOR_RELEASE 8 //Access: read-only +#define M_ANC_CHAN_VERSION_MAJOR_RELEASE _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_MAJOR_RELEASE) +#define V_ANC_CHAN_VERSION_MAJOR_RELEASE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_MAJOR_RELEASE) +#define G_ANC_CHAN_VERSION_MAJOR_RELEASE(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_MAJOR_RELEASE,M_ANC_CHAN_VERSION_MAJOR_RELEASE) + +#define S_ANC_CHAN_VERSION_VERSION 16 //Access: read-only +#define M_ANC_CHAN_VERSION_VERSION _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_VERSION) +#define V_ANC_CHAN_VERSION_VERSION(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_VERSION) +#define G_ANC_CHAN_VERSION_VERSION(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_VERSION,M_ANC_CHAN_VERSION_VERSION) + +#define S_ANC_CHAN_VERSION_RSVD0 24 //Access: read-as-zero +#define M_ANC_CHAN_VERSION_RSVD0 _MM_MAKEMASK(8,S_ANC_CHAN_VERSION_RSVD0) +#define V_ANC_CHAN_VERSION_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_VERSION_RSVD0) +#define G_ANC_CHAN_VERSION_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_VERSION_RSVD0,M_ANC_CHAN_VERSION_RSVD0) + + +#define S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN 0 //Access: read-write +#define M_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN _MM_MAKEMASK(1,S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN) +#define V_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN(V) _MM_MAKEVALUE((V),S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN) +#define G_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN(V) _MM_GETVALUE((V),S_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN,M_ANC_CHAN_CONFIG_AUTO_CLK_GATING_EN) + +#define S_ANC_CHAN_CONFIG_RSVD0 1 //Access: read-as-zero +#define M_ANC_CHAN_CONFIG_RSVD0 _MM_MAKEMASK(31,S_ANC_CHAN_CONFIG_RSVD0) +#define V_ANC_CHAN_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_CONFIG_RSVD0) +#define G_ANC_CHAN_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_CONFIG_RSVD0,M_ANC_CHAN_CONFIG_RSVD0) + + +#define S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG 0 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG) +#define V_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG) +#define G_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG,M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG 1 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG) +#define V_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG) +#define G_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG,M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG) + +#define S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED 2 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED) +#define V_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED) +#define G_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED,M_ANC_CHAN_INT_STATUS_CHANNEL_STOPPED) + +#define S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW 3 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW 4 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW 5 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW) +#define V_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW) +#define G_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW,M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_LOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH 6 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH) +#define V_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH) +#define G_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH,M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_HIGH) + +#define S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW 7 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_STATUS_DMA_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW 8 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_STATUS_LINK_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW 9 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW,M_ANC_CHAN_INT_STATUS_LINK_BYPASS_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW 10 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW) +#define V_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW) +#define G_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW,M_ANC_CHAN_INT_STATUS_LINK_PIO_READ_FIFO_UNDERFLOW) + +#define S_ANC_CHAN_INT_STATUS_CRC_ERR 11 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_CRC_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_CRC_ERR) +#define V_ANC_CHAN_INT_STATUS_CRC_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_CRC_ERR) +#define G_ANC_CHAN_INT_STATUS_CRC_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_CRC_ERR,M_ANC_CHAN_INT_STATUS_CRC_ERR) + +#define S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE 12 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) +#define V_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) +#define G_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE,M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) + +#define S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND 13 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND) +#define V_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND) +#define G_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND,M_ANC_CHAN_INT_STATUS_INVALID_DMA_COMMAND) + +#define S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND 14 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND) +#define V_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND) +#define G_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND,M_ANC_CHAN_INT_STATUS_INVALID_LINK_COMMAND) + +#define S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY 15 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY) +#define V_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY) +#define G_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY,M_ANC_CHAN_INT_STATUS_AXI_RESPONSE_NOT_OKAY) + +#define S_ANC_CHAN_INT_STATUS_AES_ERR 16 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_AES_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_AES_ERR) +#define V_ANC_CHAN_INT_STATUS_AES_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_AES_ERR) +#define G_ANC_CHAN_INT_STATUS_AES_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_AES_ERR,M_ANC_CHAN_INT_STATUS_AES_ERR) + +#define S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT 17 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT,M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT 18 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT,M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH 19 //Access: read-only +#define M_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH) +#define V_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH) +#define G_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH,M_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_HIGH) + +#define S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW 20 //Access: write-once-clear +#define M_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW) +#define V_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW) +#define G_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW,M_ANC_CHAN_INT_STATUS_LINK_ECC_STATUS_FIFO_UNDERFLOW) + +#define S_ANC_CHAN_INT_STATUS_RSVD0 21 //Access: read-as-zero +#define M_ANC_CHAN_INT_STATUS_RSVD0 _MM_MAKEMASK(11,S_ANC_CHAN_INT_STATUS_RSVD0) +#define V_ANC_CHAN_INT_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_STATUS_RSVD0) +#define G_ANC_CHAN_INT_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_STATUS_RSVD0,M_ANC_CHAN_INT_STATUS_RSVD0) + + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG 0 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG,M_ANC_CHAN_INT_ENABLE_DMA_CMD_FLAG) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG 1 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG,M_ANC_CHAN_INT_ENABLE_LINK_CMD_FLAG) + +#define S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED 2 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED) +#define V_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED) +#define G_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED,M_ANC_CHAN_INT_ENABLE_CHANNEL_STOPPED) + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW 3 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW 4 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW,M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW 5 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW,M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_LOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH 6 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH) +#define V_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH) +#define G_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH,M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_HIGH) + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW 7 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_ENABLE_DMA_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW 8 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW,M_ANC_CHAN_INT_ENABLE_LINK_CMDQ_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW 9 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW,M_ANC_CHAN_INT_ENABLE_LINK_BYPASS_FIFO_OVERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW 10 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW,M_ANC_CHAN_INT_ENABLE_LINK_PIO_READ_FIFO_UNDERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_CRC_ERR 11 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_CRC_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_CRC_ERR) +#define V_ANC_CHAN_INT_ENABLE_CRC_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_CRC_ERR) +#define G_ANC_CHAN_INT_ENABLE_CRC_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_CRC_ERR,M_ANC_CHAN_INT_ENABLE_CRC_ERR) + +#define S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE 12 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE) +#define V_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE) +#define G_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE,M_ANC_CHAN_INT_ENABLE_READ_STATUS_ERR_RESPONSE) + +#define S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND 13 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND) +#define V_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND) +#define G_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND,M_ANC_CHAN_INT_ENABLE_INVALID_DMA_COMMAND) + +#define S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND 14 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND) +#define V_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND) +#define G_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND,M_ANC_CHAN_INT_ENABLE_INVALID_LINK_COMMAND) + +#define S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY 15 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY) +#define V_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY) +#define G_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY,M_ANC_CHAN_INT_ENABLE_AXI_RESPONSE_NOT_OKAY) + +#define S_ANC_CHAN_INT_ENABLE_AES_ERR 16 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_AES_ERR _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_AES_ERR) +#define V_ANC_CHAN_INT_ENABLE_AES_ERR(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_AES_ERR) +#define G_ANC_CHAN_INT_ENABLE_AES_ERR(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_AES_ERR,M_ANC_CHAN_INT_ENABLE_AES_ERR) + +#define S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT 17 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT,M_ANC_CHAN_INT_ENABLE_DMA_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT 18 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT) +#define V_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT) +#define G_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT,M_ANC_CHAN_INT_ENABLE_LINK_CMD_TIMEOUT) + +#define S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH 19 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH) +#define V_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH) +#define G_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH,M_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_HIGH) + +#define S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW 20 //Access: read-write +#define M_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW) +#define V_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW) +#define G_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW,M_ANC_CHAN_INT_ENABLE_LINK_ECC_STATUS_FIFO_UNDERFLOW) + +#define S_ANC_CHAN_INT_ENABLE_RSVD0 21 //Access: read-as-zero +#define M_ANC_CHAN_INT_ENABLE_RSVD0 _MM_MAKEMASK(11,S_ANC_CHAN_INT_ENABLE_RSVD0) +#define V_ANC_CHAN_INT_ENABLE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_INT_ENABLE_RSVD0) +#define G_ANC_CHAN_INT_ENABLE_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_INT_ENABLE_RSVD0,M_ANC_CHAN_INT_ENABLE_RSVD0) + + +#define S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW 0 //Access: read-write +#define M_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW _MM_MAKEMASK(7,S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW,M_ANC_CHAN_DMA_WATERMARKS_DMA_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_DMA_WATERMARKS_RSVD0 7 //Access: read-as-zero +#define M_ANC_CHAN_DMA_WATERMARKS_RSVD0 _MM_MAKEMASK(25,S_ANC_CHAN_DMA_WATERMARKS_RSVD0) +#define V_ANC_CHAN_DMA_WATERMARKS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_RSVD0) +#define G_ANC_CHAN_DMA_WATERMARKS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_WATERMARKS_RSVD0,M_ANC_CHAN_DMA_WATERMARKS_RSVD0) + + +#define S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW 0 //Access: read-write +#define M_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW _MM_MAKEMASK(8,S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW) +#define V_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW) +#define G_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW,M_ANC_CHAN_LINK_WATERMARKS_LINK_CMDQ_FIFO_LOW) + +#define S_ANC_CHAN_LINK_WATERMARKS_RSVD0 8 //Access: read-as-zero +#define M_ANC_CHAN_LINK_WATERMARKS_RSVD0 _MM_MAKEMASK(8,S_ANC_CHAN_LINK_WATERMARKS_RSVD0) +#define V_ANC_CHAN_LINK_WATERMARKS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD0) +#define G_ANC_CHAN_LINK_WATERMARKS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD0,M_ANC_CHAN_LINK_WATERMARKS_RSVD0) + +#define S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW 16 //Access: read-write +#define M_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW _MM_MAKEMASK(4,S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW) +#define V_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW) +#define G_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW,M_ANC_CHAN_LINK_WATERMARKS_LINK_BYPASS_FIFO_LOW) + +#define S_ANC_CHAN_LINK_WATERMARKS_RSVD1 20 //Access: read-as-zero +#define M_ANC_CHAN_LINK_WATERMARKS_RSVD1 _MM_MAKEMASK(4,S_ANC_CHAN_LINK_WATERMARKS_RSVD1) +#define V_ANC_CHAN_LINK_WATERMARKS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD1) +#define G_ANC_CHAN_LINK_WATERMARKS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD1,M_ANC_CHAN_LINK_WATERMARKS_RSVD1) + +#define S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH 24 //Access: read-write +#define M_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH _MM_MAKEMASK(7,S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH) +#define V_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH) +#define G_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH,M_ANC_CHAN_LINK_WATERMARKS_LINK_PIO_READ_FIFO_HIGH) + +#define S_ANC_CHAN_LINK_WATERMARKS_RSVD2 31 //Access: read-as-zero +#define M_ANC_CHAN_LINK_WATERMARKS_RSVD2 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_WATERMARKS_RSVD2) +#define V_ANC_CHAN_LINK_WATERMARKS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD2) +#define G_ANC_CHAN_LINK_WATERMARKS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_WATERMARKS_RSVD2,M_ANC_CHAN_LINK_WATERMARKS_RSVD2) + + +#define S_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH 0 //Access: read-write +#define M_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH _MM_MAKEMASK(7,S_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH) +#define V_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH) +#define G_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH,M_ANC_CHAN_STATUS_WATERMARKS_LINK_ECC_STATUS_FIFO_HIGH) + +#define S_ANC_CHAN_STATUS_WATERMARKS_RSVD0 7 //Access: read-as-zero +#define M_ANC_CHAN_STATUS_WATERMARKS_RSVD0 _MM_MAKEMASK(25,S_ANC_CHAN_STATUS_WATERMARKS_RSVD0) +#define V_ANC_CHAN_STATUS_WATERMARKS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_STATUS_WATERMARKS_RSVD0) +#define G_ANC_CHAN_STATUS_WATERMARKS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_STATUS_WATERMARKS_RSVD0,M_ANC_CHAN_STATUS_WATERMARKS_RSVD0) + + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW 0 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LOW) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL 1 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_FULL) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW 2 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_OVERFLOW) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL _MM_MAKEMASK(7,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1 15 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2 22 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2 _MM_MAKEMASK(2,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD2) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3 30 //Access: read-as-zero +#define M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3 _MM_MAKEMASK(2,S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3,M_ANC_CHAN_DMA_CMDQ_FIFO_STATUS_RSVD3) + + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW 0 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LOW) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL 1 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_FULL) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW 2 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_OVERFLOW) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL _MM_MAKEMASK(8,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(7,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1 23 //Access: read-as-zero +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(7,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2 31 //Access: read-as-zero +#define M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2,M_ANC_CHAN_LINK_CMDQ_FIFO_STATUS_RSVD2) + + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW 0 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LOW) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL 1 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL _MM_MAKEMASK(1,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_FULL) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW 2 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_OVERFLOW) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL _MM_MAKEMASK(4,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1 12 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1 _MM_MAKEMASK(4,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(3,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2 19 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD2) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(3,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3 27 //Access: read-as-zero +#define M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3,M_ANC_CHAN_LINK_BYPASS_FIFO_STATUS_RSVD3) + + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH 0 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_HIGH) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY 1 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_EMPTY) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW 2 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_UNDERFLOW) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL _MM_MAKEMASK(7,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1 15 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2 22 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2 _MM_MAKEMASK(2,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD2) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3 30 //Access: read-as-zero +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3 _MM_MAKEMASK(2,S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3,M_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_RSVD3) + + +#define S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER 0 //Access: read-only +#define M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(4,S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0 4 //Access: read-as-zero +#define M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0 _MM_MAKEMASK(28,S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0,M_ANC_CHAN_DMA_DEBUG_FIFO_STATUS_RSVD0) + + +#define S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER 0 //Access: read-only +#define M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(5,S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0 5 //Access: read-as-zero +#define M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0 _MM_MAKEMASK(27,S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_DEBUG_FIFO_STATUS_RSVD0) + + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH 0 //Access: read-only +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH _MM_MAKEMASK(1,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_HIGH) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY 1 //Access: read-only +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY _MM_MAKEMASK(1,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_EMPTY) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW 2 //Access: read-only +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW _MM_MAKEMASK(1,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_UNDERFLOW) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD0) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL 8 //Access: read-only +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL _MM_MAKEMASK(7,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_LEVEL) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1 15 //Access: read-as-zero +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD1) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER 16 //Access: read-only +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_READ_POINTER) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2 22 //Access: read-as-zero +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2 _MM_MAKEMASK(2,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD2) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER 24 //Access: read-only +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER _MM_MAKEMASK(6,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_WRITE_POINTER) + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3 30 //Access: read-as-zero +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3 _MM_MAKEMASK(2,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_STATUS_RSVD3) + + +#define S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD 0 //Access: write-only +#define M_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD _MM_MAKEMASK(32,S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD) +#define V_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD) +#define G_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD,M_ANC_CHAN_DMA_CMDQ_FIFO_PUSH_WORD) + + +#define S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD 0 //Access: write-only +#define M_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD) +#define V_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD) +#define G_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD,M_ANC_CHAN_LINK_CMDQ_FIFO_PUSH_WORD) + + +#define S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD 0 //Access: write-only +#define M_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD) +#define V_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD) +#define G_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD,M_ANC_CHAN_LINK_BYPASS_FIFO_PUSH_WORD) + + +#define S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD 0 //Access: read-only +#define M_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD) +#define V_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD) +#define G_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD,M_ANC_CHAN_LINK_PIO_READ_FIFO_POP_WORD) + + +#define S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD 0 //Access: read-only +#define M_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD _MM_MAKEMASK(32,S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD) +#define V_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD) +#define G_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD,M_ANC_CHAN_DMA_DEBUG_FIFO_POP_WORD) + + +#define S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD 0 //Access: read-only +#define M_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD) +#define V_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD) +#define G_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD,M_ANC_CHAN_LINK_DEBUG_FIFO_POP_WORD) + + +#define S_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD 0 //Access: read-only +#define M_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD _MM_MAKEMASK(32,S_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD) +#define V_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD(V) _MM_MAKEVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD) +#define G_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD(V) _MM_GETVALUE((V),S_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD,M_ANC_CHAN_LINK_ECC_STATUS_FIFO_POP_WORD) + + +#define S_ANC_DMA_CONFIG_AXI_AXQOS 0 //Access: read-write +#define M_ANC_DMA_CONFIG_AXI_AXQOS _MM_MAKEMASK(4,S_ANC_DMA_CONFIG_AXI_AXQOS) +#define V_ANC_DMA_CONFIG_AXI_AXQOS(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_AXI_AXQOS) +#define G_ANC_DMA_CONFIG_AXI_AXQOS(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_AXI_AXQOS,M_ANC_DMA_CONFIG_AXI_AXQOS) + +#define S_ANC_DMA_CONFIG_RSVD0 4 //Access: read-as-zero +#define M_ANC_DMA_CONFIG_RSVD0 _MM_MAKEMASK(4,S_ANC_DMA_CONFIG_RSVD0) +#define V_ANC_DMA_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_RSVD0) +#define G_ANC_DMA_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_RSVD0,M_ANC_DMA_CONFIG_RSVD0) + +#define S_ANC_DMA_CONFIG_BURST_SIZE 8 //Access: read-write +#define M_ANC_DMA_CONFIG_BURST_SIZE _MM_MAKEMASK(2,S_ANC_DMA_CONFIG_BURST_SIZE) +#define V_ANC_DMA_CONFIG_BURST_SIZE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_BURST_SIZE) +#define G_ANC_DMA_CONFIG_BURST_SIZE(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_BURST_SIZE,M_ANC_DMA_CONFIG_BURST_SIZE) + +#define S_ANC_DMA_CONFIG_RSVD1 10 //Access: read-as-zero +#define M_ANC_DMA_CONFIG_RSVD1 _MM_MAKEMASK(22,S_ANC_DMA_CONFIG_RSVD1) +#define V_ANC_DMA_CONFIG_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONFIG_RSVD1) +#define G_ANC_DMA_CONFIG_RSVD1(V) _MM_GETVALUE((V),S_ANC_DMA_CONFIG_RSVD1,M_ANC_DMA_CONFIG_RSVD1) + + +#define S_ANC_DMA_CONTROL_START 0 //Access: write-auto-clear +#define M_ANC_DMA_CONTROL_START _MM_MAKEMASK(1,S_ANC_DMA_CONTROL_START) +#define V_ANC_DMA_CONTROL_START(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_START) +#define G_ANC_DMA_CONTROL_START(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_START,M_ANC_DMA_CONTROL_START) + +#define S_ANC_DMA_CONTROL_STOP 1 //Access: write-auto-clear +#define M_ANC_DMA_CONTROL_STOP _MM_MAKEMASK(1,S_ANC_DMA_CONTROL_STOP) +#define V_ANC_DMA_CONTROL_STOP(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_STOP) +#define G_ANC_DMA_CONTROL_STOP(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_STOP,M_ANC_DMA_CONTROL_STOP) + +#define S_ANC_DMA_CONTROL_RESET 2 //Access: write-auto-clear +#define M_ANC_DMA_CONTROL_RESET _MM_MAKEMASK(1,S_ANC_DMA_CONTROL_RESET) +#define V_ANC_DMA_CONTROL_RESET(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_RESET) +#define G_ANC_DMA_CONTROL_RESET(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_RESET,M_ANC_DMA_CONTROL_RESET) + +#define S_ANC_DMA_CONTROL_RSVD0 3 //Access: read-as-zero +#define M_ANC_DMA_CONTROL_RSVD0 _MM_MAKEMASK(29,S_ANC_DMA_CONTROL_RSVD0) +#define V_ANC_DMA_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_CONTROL_RSVD0) +#define G_ANC_DMA_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_CONTROL_RSVD0,M_ANC_DMA_CONTROL_RSVD0) + + +#define S_ANC_DMA_STATUS_DMA_ACTIVE 0 //Access: read-only +#define M_ANC_DMA_STATUS_DMA_ACTIVE _MM_MAKEMASK(1,S_ANC_DMA_STATUS_DMA_ACTIVE) +#define V_ANC_DMA_STATUS_DMA_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_DMA_ACTIVE) +#define G_ANC_DMA_STATUS_DMA_ACTIVE(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_DMA_ACTIVE,M_ANC_DMA_STATUS_DMA_ACTIVE) + +#define S_ANC_DMA_STATUS_AXI_ACTIVE 1 //Access: read-only +#define M_ANC_DMA_STATUS_AXI_ACTIVE _MM_MAKEMASK(1,S_ANC_DMA_STATUS_AXI_ACTIVE) +#define V_ANC_DMA_STATUS_AXI_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_AXI_ACTIVE) +#define G_ANC_DMA_STATUS_AXI_ACTIVE(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_AXI_ACTIVE,M_ANC_DMA_STATUS_AXI_ACTIVE) + +#define S_ANC_DMA_STATUS_AES_ACTIVE 2 //Access: read-only +#define M_ANC_DMA_STATUS_AES_ACTIVE _MM_MAKEMASK(1,S_ANC_DMA_STATUS_AES_ACTIVE) +#define V_ANC_DMA_STATUS_AES_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_AES_ACTIVE) +#define G_ANC_DMA_STATUS_AES_ACTIVE(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_AES_ACTIVE,M_ANC_DMA_STATUS_AES_ACTIVE) + +#define S_ANC_DMA_STATUS_CMDQ_ENABLED 3 //Access: read-only +#define M_ANC_DMA_STATUS_CMDQ_ENABLED _MM_MAKEMASK(1,S_ANC_DMA_STATUS_CMDQ_ENABLED) +#define V_ANC_DMA_STATUS_CMDQ_ENABLED(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_CMDQ_ENABLED) +#define G_ANC_DMA_STATUS_CMDQ_ENABLED(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_CMDQ_ENABLED,M_ANC_DMA_STATUS_CMDQ_ENABLED) + +#define S_ANC_DMA_STATUS_AES_ENABLED 4 //Access: read-only +#define M_ANC_DMA_STATUS_AES_ENABLED _MM_MAKEMASK(1,S_ANC_DMA_STATUS_AES_ENABLED) +#define V_ANC_DMA_STATUS_AES_ENABLED(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_AES_ENABLED) +#define G_ANC_DMA_STATUS_AES_ENABLED(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_AES_ENABLED,M_ANC_DMA_STATUS_AES_ENABLED) + +#define S_ANC_DMA_STATUS_DMA_DIRECTION 5 //Access: read-only +#define M_ANC_DMA_STATUS_DMA_DIRECTION _MM_MAKEMASK(1,S_ANC_DMA_STATUS_DMA_DIRECTION) +#define V_ANC_DMA_STATUS_DMA_DIRECTION(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_DMA_DIRECTION) +#define G_ANC_DMA_STATUS_DMA_DIRECTION(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_DMA_DIRECTION,M_ANC_DMA_STATUS_DMA_DIRECTION) + +#define S_ANC_DMA_STATUS_RSVD0 6 //Access: read-as-zero +#define M_ANC_DMA_STATUS_RSVD0 _MM_MAKEMASK(26,S_ANC_DMA_STATUS_RSVD0) +#define V_ANC_DMA_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_STATUS_RSVD0) +#define G_ANC_DMA_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_STATUS_RSVD0,M_ANC_DMA_STATUS_RSVD0) + + +#define S_ANC_DMA_AES_STATUS_RSVD0 0 //Access: read-as-zero +#define M_ANC_DMA_AES_STATUS_RSVD0 _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_RSVD0) +#define V_ANC_DMA_AES_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_RSVD0) +#define G_ANC_DMA_AES_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_RSVD0,M_ANC_DMA_AES_STATUS_RSVD0) + +#define S_ANC_DMA_AES_STATUS_KEY_SELECT 1 //Access: read-only +#define M_ANC_DMA_AES_STATUS_KEY_SELECT _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_KEY_SELECT) +#define V_ANC_DMA_AES_STATUS_KEY_SELECT(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_KEY_SELECT) +#define G_ANC_DMA_AES_STATUS_KEY_SELECT(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_KEY_SELECT,M_ANC_DMA_AES_STATUS_KEY_SELECT) + +#define S_ANC_DMA_AES_STATUS_KEY_LENGTH 2 //Access: read-only +#define M_ANC_DMA_AES_STATUS_KEY_LENGTH _MM_MAKEMASK(2,S_ANC_DMA_AES_STATUS_KEY_LENGTH) +#define V_ANC_DMA_AES_STATUS_KEY_LENGTH(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_KEY_LENGTH) +#define G_ANC_DMA_AES_STATUS_KEY_LENGTH(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_KEY_LENGTH,M_ANC_DMA_AES_STATUS_KEY_LENGTH) + +#define S_ANC_DMA_AES_STATUS_RSVD1 4 //Access: read-as-zero +#define M_ANC_DMA_AES_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_RSVD1) +#define V_ANC_DMA_AES_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_RSVD1) +#define G_ANC_DMA_AES_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_RSVD1,M_ANC_DMA_AES_STATUS_RSVD1) + +#define S_ANC_DMA_AES_STATUS_KEY_IN_CTX 5 //Access: read-only +#define M_ANC_DMA_AES_STATUS_KEY_IN_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_KEY_IN_CTX) +#define V_ANC_DMA_AES_STATUS_KEY_IN_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_KEY_IN_CTX) +#define G_ANC_DMA_AES_STATUS_KEY_IN_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_KEY_IN_CTX,M_ANC_DMA_AES_STATUS_KEY_IN_CTX) + +#define S_ANC_DMA_AES_STATUS_IV_IN_CTX 6 //Access: read-only +#define M_ANC_DMA_AES_STATUS_IV_IN_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_IV_IN_CTX) +#define V_ANC_DMA_AES_STATUS_IV_IN_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_IV_IN_CTX) +#define G_ANC_DMA_AES_STATUS_IV_IN_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_IV_IN_CTX,M_ANC_DMA_AES_STATUS_IV_IN_CTX) + +#define S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX 7 //Access: read-only +#define M_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX) +#define V_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX) +#define G_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX,M_ANC_DMA_AES_STATUS_TXT_IN_KEY_CTX) + +#define S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX 8 //Access: read-only +#define M_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX) +#define V_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX) +#define G_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX,M_ANC_DMA_AES_STATUS_TXT_IN_IV_CTX) + +#define S_ANC_DMA_AES_STATUS_AES_ERR 9 //Access: read-only +#define M_ANC_DMA_AES_STATUS_AES_ERR _MM_MAKEMASK(1,S_ANC_DMA_AES_STATUS_AES_ERR) +#define V_ANC_DMA_AES_STATUS_AES_ERR(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_AES_ERR) +#define G_ANC_DMA_AES_STATUS_AES_ERR(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_AES_ERR,M_ANC_DMA_AES_STATUS_AES_ERR) + +#define S_ANC_DMA_AES_STATUS_RSVD2 10 //Access: read-as-zero +#define M_ANC_DMA_AES_STATUS_RSVD2 _MM_MAKEMASK(22,S_ANC_DMA_AES_STATUS_RSVD2) +#define V_ANC_DMA_AES_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_DMA_AES_STATUS_RSVD2) +#define G_ANC_DMA_AES_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_DMA_AES_STATUS_RSVD2,M_ANC_DMA_AES_STATUS_RSVD2) + + +#define S_ANC_DMA_CMDQ_COUNT_TOTAL 0 //Access: read-only +#define M_ANC_DMA_CMDQ_COUNT_TOTAL _MM_MAKEMASK(32,S_ANC_DMA_CMDQ_COUNT_TOTAL) +#define V_ANC_DMA_CMDQ_COUNT_TOTAL(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_COUNT_TOTAL) +#define G_ANC_DMA_CMDQ_COUNT_TOTAL(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_COUNT_TOTAL,M_ANC_DMA_CMDQ_COUNT_TOTAL) + + +#define S_ANC_DMA_CMD_TIMEOUT_VALUE 0 //Access: read-write +#define M_ANC_DMA_CMD_TIMEOUT_VALUE _MM_MAKEMASK(31,S_ANC_DMA_CMD_TIMEOUT_VALUE) +#define V_ANC_DMA_CMD_TIMEOUT_VALUE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMD_TIMEOUT_VALUE) +#define G_ANC_DMA_CMD_TIMEOUT_VALUE(V) _MM_GETVALUE((V),S_ANC_DMA_CMD_TIMEOUT_VALUE,M_ANC_DMA_CMD_TIMEOUT_VALUE) + +#define S_ANC_DMA_CMD_TIMEOUT_ENABLE 31 //Access: read-write +#define M_ANC_DMA_CMD_TIMEOUT_ENABLE _MM_MAKEMASK(1,S_ANC_DMA_CMD_TIMEOUT_ENABLE) +#define V_ANC_DMA_CMD_TIMEOUT_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMD_TIMEOUT_ENABLE) +#define G_ANC_DMA_CMD_TIMEOUT_ENABLE(V) _MM_GETVALUE((V),S_ANC_DMA_CMD_TIMEOUT_ENABLE,M_ANC_DMA_CMD_TIMEOUT_ENABLE) + + +#define S_ANC_DMA_CMDQ_INT_CODE_CODE 0 //Access: read-only +#define M_ANC_DMA_CMDQ_INT_CODE_CODE _MM_MAKEMASK(16,S_ANC_DMA_CMDQ_INT_CODE_CODE) +#define V_ANC_DMA_CMDQ_INT_CODE_CODE(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_CODE) +#define G_ANC_DMA_CMDQ_INT_CODE_CODE(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_CODE,M_ANC_DMA_CMDQ_INT_CODE_CODE) + +#define S_ANC_DMA_CMDQ_INT_CODE_RSVD0 16 //Access: read-as-zero +#define M_ANC_DMA_CMDQ_INT_CODE_RSVD0 _MM_MAKEMASK(16,S_ANC_DMA_CMDQ_INT_CODE_RSVD0) +#define V_ANC_DMA_CMDQ_INT_CODE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_RSVD0) +#define G_ANC_DMA_CMDQ_INT_CODE_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_INT_CODE_RSVD0,M_ANC_DMA_CMDQ_INT_CODE_RSVD0) + + +#define S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING 0 //Access: read-only +#define M_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING _MM_MAKEMASK(5,S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING) +#define V_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING) +#define G_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING,M_ANC_DMA_AXI_ADDRESS_REQUESTS_OUTSTANDING) + +#define S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING 5 //Access: read-only +#define M_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING _MM_MAKEMASK(9,S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING) +#define V_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING) +#define G_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING,M_ANC_DMA_AXI_ADDRESS_REQUESTS_WORDS_REMAINING) + +#define S_ANC_DMA_AXI_RESPONSE 14 //Access: read-only +#define M_ANC_DMA_AXI_RESPONSE _MM_MAKEMASK(2,S_ANC_DMA_AXI_RESPONSE) +#define V_ANC_DMA_AXI_RESPONSE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_RESPONSE) +#define G_ANC_DMA_AXI_RESPONSE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_RESPONSE,M_ANC_DMA_AXI_RESPONSE) + +#define S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE 16 //Access: read-only +#define M_ANC_DMA_AXI_WRITE_DATA_AVAILABLE _MM_MAKEMASK(7,S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE) +#define V_ANC_DMA_AXI_WRITE_DATA_AVAILABLE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE) +#define G_ANC_DMA_AXI_WRITE_DATA_AVAILABLE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_WRITE_DATA_AVAILABLE,M_ANC_DMA_AXI_WRITE_DATA_AVAILABLE) + +#define S_ANC_DMA_AXI_READ_SPACE_AVAILABLE 23 //Access: read-only +#define M_ANC_DMA_AXI_READ_SPACE_AVAILABLE _MM_MAKEMASK(7,S_ANC_DMA_AXI_READ_SPACE_AVAILABLE) +#define V_ANC_DMA_AXI_READ_SPACE_AVAILABLE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_READ_SPACE_AVAILABLE) +#define G_ANC_DMA_AXI_READ_SPACE_AVAILABLE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_READ_SPACE_AVAILABLE,M_ANC_DMA_AXI_READ_SPACE_AVAILABLE) + +#define S_ANC_DMA_AXI_RSVD0 30 //Access: read-as-zero +#define M_ANC_DMA_AXI_RSVD0 _MM_MAKEMASK(2,S_ANC_DMA_AXI_RSVD0) +#define V_ANC_DMA_AXI_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_RSVD0) +#define G_ANC_DMA_AXI_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_RSVD0,M_ANC_DMA_AXI_RSVD0) + + +#define S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH 0 //Access: read-only +#define M_ANC_DMA_AXI_NEXT_REQUEST_LENGTH _MM_MAKEMASK(4,S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH) +#define V_ANC_DMA_AXI_NEXT_REQUEST_LENGTH(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH) +#define G_ANC_DMA_AXI_NEXT_REQUEST_LENGTH(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_REQUEST_LENGTH,M_ANC_DMA_AXI_NEXT_REQUEST_LENGTH) + +#define S_ANC_DMA_AXI_NEXT_RSVD0 4 //Access: read-as-zero +#define M_ANC_DMA_AXI_NEXT_RSVD0 _MM_MAKEMASK(20,S_ANC_DMA_AXI_NEXT_RSVD0) +#define V_ANC_DMA_AXI_NEXT_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_RSVD0) +#define G_ANC_DMA_AXI_NEXT_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_RSVD0,M_ANC_DMA_AXI_NEXT_RSVD0) + +#define S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE 24 //Access: read-only +#define M_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE _MM_MAKEMASK(8,S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE) +#define V_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE) +#define G_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE,M_ANC_DMA_AXI_NEXT_ADDRESS_HIGH_BYTE) + + +#define S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES 0 //Access: read-only +#define M_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES _MM_MAKEMASK(32,S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES) +#define V_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES) +#define G_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES,M_ANC_DMA_AXI_NEXT_ADDRESS_LOWER_FOUR_BYTES) + + +#define S_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS 0 //Access: read-only +#define M_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS _MM_MAKEMASK(32,S_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS) +#define V_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS) +#define G_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS,M_ANC_DMA_AXI_DMA_COUNT_WRITE_WORDS) + + +#define S_ANC_DMA_AXI_COUNT_READ_WORDS 0 //Access: read-only +#define M_ANC_DMA_AXI_COUNT_READ_WORDS _MM_MAKEMASK(32,S_ANC_DMA_AXI_COUNT_READ_WORDS) +#define V_ANC_DMA_AXI_COUNT_READ_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_COUNT_READ_WORDS) +#define G_ANC_DMA_AXI_COUNT_READ_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_COUNT_READ_WORDS,M_ANC_DMA_AXI_COUNT_READ_WORDS) + + +#define S_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS 0 //Access: read-only +#define M_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS _MM_MAKEMASK(32,S_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS) +#define V_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS) +#define G_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS,M_ANC_DMA_DLFIFO_COUNT_WRITE_WORDS) + + +#define S_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS 0 //Access: read-only +#define M_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS _MM_MAKEMASK(32,S_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS) +#define V_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS) +#define G_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS,M_ANC_DMA_DLFIFO_DMA_COUNT_READ_WORDS) + + +#define S_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS 0 //Access: read-only +#define M_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS _MM_MAKEMASK(32,S_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS) +#define V_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS) +#define G_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS,M_ANC_DMA_AXI_DMA_LAST_COUNT_WRITE_WORDS) + + +#define S_ANC_DMA_AXI_LAST_COUNT_READ_WORDS 0 //Access: read-only +#define M_ANC_DMA_AXI_LAST_COUNT_READ_WORDS _MM_MAKEMASK(32,S_ANC_DMA_AXI_LAST_COUNT_READ_WORDS) +#define V_ANC_DMA_AXI_LAST_COUNT_READ_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_AXI_LAST_COUNT_READ_WORDS) +#define G_ANC_DMA_AXI_LAST_COUNT_READ_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_AXI_LAST_COUNT_READ_WORDS,M_ANC_DMA_AXI_LAST_COUNT_READ_WORDS) + + +#define S_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS 0 //Access: read-only +#define M_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS _MM_MAKEMASK(32,S_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS) +#define V_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS) +#define G_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS,M_ANC_DMA_DLFIFO_LAST_COUNT_WRITE_WORDS) + + +#define S_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS 0 //Access: read-only +#define M_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS _MM_MAKEMASK(32,S_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS) +#define V_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS(V) _MM_MAKEVALUE((V),S_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS) +#define G_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS(V) _MM_GETVALUE((V),S_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS,M_ANC_DMA_DLFIFO_DMA_LAST_COUNT_READ_WORDS) + + +#define S_ANC_LINK_CONFIG_DDR_MODE 0 //Access: read-write +#define M_ANC_LINK_CONFIG_DDR_MODE _MM_MAKEMASK(1,S_ANC_LINK_CONFIG_DDR_MODE) +#define V_ANC_LINK_CONFIG_DDR_MODE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_DDR_MODE) +#define G_ANC_LINK_CONFIG_DDR_MODE(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_DDR_MODE,M_ANC_LINK_CONFIG_DDR_MODE) + +#define S_ANC_LINK_CONFIG_ENABLE_CRC 1 //Access: read-write +#define M_ANC_LINK_CONFIG_ENABLE_CRC _MM_MAKEMASK(1,S_ANC_LINK_CONFIG_ENABLE_CRC) +#define V_ANC_LINK_CONFIG_ENABLE_CRC(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_ENABLE_CRC) +#define G_ANC_LINK_CONFIG_ENABLE_CRC(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_ENABLE_CRC,M_ANC_LINK_CONFIG_ENABLE_CRC) + +#define S_ANC_LINK_CONFIG_AUTOPAD_CRC 2 //Access: read-write +#define M_ANC_LINK_CONFIG_AUTOPAD_CRC _MM_MAKEMASK(1,S_ANC_LINK_CONFIG_AUTOPAD_CRC) +#define V_ANC_LINK_CONFIG_AUTOPAD_CRC(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_AUTOPAD_CRC) +#define G_ANC_LINK_CONFIG_AUTOPAD_CRC(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_AUTOPAD_CRC,M_ANC_LINK_CONFIG_AUTOPAD_CRC) + +#define S_ANC_LINK_CONFIG_ENABLE_SCRAMBLER 3 //Access: read-write +#define M_ANC_LINK_CONFIG_ENABLE_SCRAMBLER _MM_MAKEMASK(1,S_ANC_LINK_CONFIG_ENABLE_SCRAMBLER) +#define V_ANC_LINK_CONFIG_ENABLE_SCRAMBLER(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_ENABLE_SCRAMBLER) +#define G_ANC_LINK_CONFIG_ENABLE_SCRAMBLER(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_ENABLE_SCRAMBLER,M_ANC_LINK_CONFIG_ENABLE_SCRAMBLER) + +#define S_ANC_LINK_CONFIG_RSVD0 4 //Access: read-as-zero +#define M_ANC_LINK_CONFIG_RSVD0 _MM_MAKEMASK(28,S_ANC_LINK_CONFIG_RSVD0) +#define V_ANC_LINK_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONFIG_RSVD0) +#define G_ANC_LINK_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CONFIG_RSVD0,M_ANC_LINK_CONFIG_RSVD0) + + +#define S_ANC_LINK_CONTROL_START 0 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START) +#define V_ANC_LINK_CONTROL_START(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START) +#define G_ANC_LINK_CONTROL_START(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START,M_ANC_LINK_CONTROL_START) + +#define S_ANC_LINK_CONTROL_STOP 1 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP) +#define V_ANC_LINK_CONTROL_STOP(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP) +#define G_ANC_LINK_CONTROL_STOP(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP,M_ANC_LINK_CONTROL_STOP) + +#define S_ANC_LINK_CONTROL_YIELD 2 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_YIELD _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_YIELD) +#define V_ANC_LINK_CONTROL_YIELD(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_YIELD) +#define G_ANC_LINK_CONTROL_YIELD(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_YIELD,M_ANC_LINK_CONTROL_YIELD) + +#define S_ANC_LINK_CONTROL_ABORT 3 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_ABORT _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_ABORT) +#define V_ANC_LINK_CONTROL_ABORT(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_ABORT) +#define G_ANC_LINK_CONTROL_ABORT(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_ABORT,M_ANC_LINK_CONTROL_ABORT) + +#define S_ANC_LINK_CONTROL_RESET 4 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET) +#define V_ANC_LINK_CONTROL_RESET(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET) +#define G_ANC_LINK_CONTROL_RESET(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET,M_ANC_LINK_CONTROL_RESET) + +#define S_ANC_LINK_CONTROL_START_CMDQ 5 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START_CMDQ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START_CMDQ) +#define V_ANC_LINK_CONTROL_START_CMDQ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START_CMDQ) +#define G_ANC_LINK_CONTROL_START_CMDQ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START_CMDQ,M_ANC_LINK_CONTROL_START_CMDQ) + +#define S_ANC_LINK_CONTROL_STOP_CMDQ 6 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP_CMDQ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP_CMDQ) +#define V_ANC_LINK_CONTROL_STOP_CMDQ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP_CMDQ) +#define G_ANC_LINK_CONTROL_STOP_CMDQ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP_CMDQ,M_ANC_LINK_CONTROL_STOP_CMDQ) + +#define S_ANC_LINK_CONTROL_RESET_CMDQ 7 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_CMDQ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_CMDQ) +#define V_ANC_LINK_CONTROL_RESET_CMDQ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_CMDQ) +#define G_ANC_LINK_CONTROL_RESET_CMDQ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_CMDQ,M_ANC_LINK_CONTROL_RESET_CMDQ) + +#define S_ANC_LINK_CONTROL_START_BYPASS 8 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START_BYPASS _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START_BYPASS) +#define V_ANC_LINK_CONTROL_START_BYPASS(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START_BYPASS) +#define G_ANC_LINK_CONTROL_START_BYPASS(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START_BYPASS,M_ANC_LINK_CONTROL_START_BYPASS) + +#define S_ANC_LINK_CONTROL_STOP_BYPASS 9 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP_BYPASS _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP_BYPASS) +#define V_ANC_LINK_CONTROL_STOP_BYPASS(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP_BYPASS) +#define G_ANC_LINK_CONTROL_STOP_BYPASS(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP_BYPASS,M_ANC_LINK_CONTROL_STOP_BYPASS) + +#define S_ANC_LINK_CONTROL_RESET_BYPASS 10 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_BYPASS _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_BYPASS) +#define V_ANC_LINK_CONTROL_RESET_BYPASS(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_BYPASS) +#define G_ANC_LINK_CONTROL_RESET_BYPASS(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_BYPASS,M_ANC_LINK_CONTROL_RESET_BYPASS) + +#define S_ANC_LINK_CONTROL_START_TIMER 11 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_START_TIMER _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_START_TIMER) +#define V_ANC_LINK_CONTROL_START_TIMER(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_START_TIMER) +#define G_ANC_LINK_CONTROL_START_TIMER(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_START_TIMER,M_ANC_LINK_CONTROL_START_TIMER) + +#define S_ANC_LINK_CONTROL_STOP_TIMER 12 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_STOP_TIMER _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_STOP_TIMER) +#define V_ANC_LINK_CONTROL_STOP_TIMER(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_STOP_TIMER) +#define G_ANC_LINK_CONTROL_STOP_TIMER(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_STOP_TIMER,M_ANC_LINK_CONTROL_STOP_TIMER) + +#define S_ANC_LINK_CONTROL_RESET_TIMER 13 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_TIMER _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_TIMER) +#define V_ANC_LINK_CONTROL_RESET_TIMER(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_TIMER) +#define G_ANC_LINK_CONTROL_RESET_TIMER(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_TIMER,M_ANC_LINK_CONTROL_RESET_TIMER) + +#define S_ANC_LINK_CONTROL_RESET_PIO_READ 14 //Access: write-auto-clear +#define M_ANC_LINK_CONTROL_RESET_PIO_READ _MM_MAKEMASK(1,S_ANC_LINK_CONTROL_RESET_PIO_READ) +#define V_ANC_LINK_CONTROL_RESET_PIO_READ(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RESET_PIO_READ) +#define G_ANC_LINK_CONTROL_RESET_PIO_READ(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RESET_PIO_READ,M_ANC_LINK_CONTROL_RESET_PIO_READ) + +#define S_ANC_LINK_CONTROL_RSVD0 15 //Access: read-as-zero +#define M_ANC_LINK_CONTROL_RSVD0 _MM_MAKEMASK(17,S_ANC_LINK_CONTROL_RSVD0) +#define V_ANC_LINK_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CONTROL_RSVD0) +#define G_ANC_LINK_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CONTROL_RSVD0,M_ANC_LINK_CONTROL_RSVD0) + + +#define S_ANC_LINK_STATUS_CMDQ_ACTIVE 0 //Access: read-only +#define M_ANC_LINK_STATUS_CMDQ_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_STATUS_CMDQ_ACTIVE) +#define V_ANC_LINK_STATUS_CMDQ_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_CMDQ_ACTIVE) +#define G_ANC_LINK_STATUS_CMDQ_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_CMDQ_ACTIVE,M_ANC_LINK_STATUS_CMDQ_ACTIVE) + +#define S_ANC_LINK_STATUS_FSM_ACTIVE 1 //Access: read-only +#define M_ANC_LINK_STATUS_FSM_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_STATUS_FSM_ACTIVE) +#define V_ANC_LINK_STATUS_FSM_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_FSM_ACTIVE) +#define G_ANC_LINK_STATUS_FSM_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_FSM_ACTIVE,M_ANC_LINK_STATUS_FSM_ACTIVE) + +#define S_ANC_LINK_STATUS_READ_HOLD_ACTIVE 2 //Access: read-only +#define M_ANC_LINK_STATUS_READ_HOLD_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_STATUS_READ_HOLD_ACTIVE) +#define V_ANC_LINK_STATUS_READ_HOLD_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_READ_HOLD_ACTIVE) +#define G_ANC_LINK_STATUS_READ_HOLD_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_READ_HOLD_ACTIVE,M_ANC_LINK_STATUS_READ_HOLD_ACTIVE) + +#define S_ANC_LINK_STATUS_RSVD0 3 //Access: read-as-zero +#define M_ANC_LINK_STATUS_RSVD0 _MM_MAKEMASK(5,S_ANC_LINK_STATUS_RSVD0) +#define V_ANC_LINK_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_RSVD0) +#define G_ANC_LINK_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_RSVD0,M_ANC_LINK_STATUS_RSVD0) + +#define S_ANC_LINK_STATUS_CMDQ_STATE 8 //Access: read-only +#define M_ANC_LINK_STATUS_CMDQ_STATE _MM_MAKEMASK(4,S_ANC_LINK_STATUS_CMDQ_STATE) +#define V_ANC_LINK_STATUS_CMDQ_STATE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_CMDQ_STATE) +#define G_ANC_LINK_STATUS_CMDQ_STATE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_CMDQ_STATE,M_ANC_LINK_STATUS_CMDQ_STATE) + +#define S_ANC_LINK_STATUS_RSVD1 12 //Access: read-as-zero +#define M_ANC_LINK_STATUS_RSVD1 _MM_MAKEMASK(4,S_ANC_LINK_STATUS_RSVD1) +#define V_ANC_LINK_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_RSVD1) +#define G_ANC_LINK_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_RSVD1,M_ANC_LINK_STATUS_RSVD1) + +#define S_ANC_LINK_STATUS_FSM_STATE 16 //Access: read-only +#define M_ANC_LINK_STATUS_FSM_STATE _MM_MAKEMASK(6,S_ANC_LINK_STATUS_FSM_STATE) +#define V_ANC_LINK_STATUS_FSM_STATE(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_FSM_STATE) +#define G_ANC_LINK_STATUS_FSM_STATE(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_FSM_STATE,M_ANC_LINK_STATUS_FSM_STATE) + +#define S_ANC_LINK_STATUS_RSVD2 22 //Access: read-as-zero +#define M_ANC_LINK_STATUS_RSVD2 _MM_MAKEMASK(10,S_ANC_LINK_STATUS_RSVD2) +#define V_ANC_LINK_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_LINK_STATUS_RSVD2) +#define G_ANC_LINK_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_LINK_STATUS_RSVD2,M_ANC_LINK_STATUS_RSVD2) + + +#define S_ANC_LINK_CHIP_ENABLE_CE 0 //Access: read-write +#define M_ANC_LINK_CHIP_ENABLE_CE _MM_MAKEMASK(8,S_ANC_LINK_CHIP_ENABLE_CE) +#define V_ANC_LINK_CHIP_ENABLE_CE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CHIP_ENABLE_CE) +#define G_ANC_LINK_CHIP_ENABLE_CE(V) _MM_GETVALUE((V),S_ANC_LINK_CHIP_ENABLE_CE,M_ANC_LINK_CHIP_ENABLE_CE) + +#define S_ANC_LINK_CHIP_ENABLE_RSVD0 8 //Access: read-as-zero +#define M_ANC_LINK_CHIP_ENABLE_RSVD0 _MM_MAKEMASK(24,S_ANC_LINK_CHIP_ENABLE_RSVD0) +#define V_ANC_LINK_CHIP_ENABLE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CHIP_ENABLE_RSVD0) +#define G_ANC_LINK_CHIP_ENABLE_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CHIP_ENABLE_RSVD0,M_ANC_LINK_CHIP_ENABLE_RSVD0) + + +#define S_ANC_LINK_READ_STATUS_CONFIG_POSITION 0 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_POSITION _MM_MAKEMASK(8,S_ANC_LINK_READ_STATUS_CONFIG_POSITION) +#define V_ANC_LINK_READ_STATUS_CONFIG_POSITION(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POSITION) +#define G_ANC_LINK_READ_STATUS_CONFIG_POSITION(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POSITION,M_ANC_LINK_READ_STATUS_CONFIG_POSITION) + +#define S_ANC_LINK_READ_STATUS_CONFIG_POLARITY 8 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_POLARITY _MM_MAKEMASK(8,S_ANC_LINK_READ_STATUS_CONFIG_POLARITY) +#define V_ANC_LINK_READ_STATUS_CONFIG_POLARITY(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POLARITY) +#define G_ANC_LINK_READ_STATUS_CONFIG_POLARITY(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_POLARITY,M_ANC_LINK_READ_STATUS_CONFIG_POLARITY) + +#define S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY 16 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY _MM_MAKEMASK(4,S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY) +#define V_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY) +#define G_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY,M_ANC_LINK_READ_STATUS_CONFIG_STATUS_CAPTURE_DELAY) + +#define S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY 20 //Access: read-write +#define M_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY _MM_MAKEMASK(4,S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY) +#define V_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY) +#define G_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY,M_ANC_LINK_READ_STATUS_CONFIG_READY_SAMPLE_DELAY) + +#define S_ANC_LINK_READ_STATUS_CONFIG_RSVD0 24 //Access: read-as-zero +#define M_ANC_LINK_READ_STATUS_CONFIG_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_READ_STATUS_CONFIG_RSVD0) +#define V_ANC_LINK_READ_STATUS_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_RSVD0) +#define G_ANC_LINK_READ_STATUS_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_READ_STATUS_CONFIG_RSVD0,M_ANC_LINK_READ_STATUS_CONFIG_RSVD0) + + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME 0 //Access: read-write +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_SETUP_TIME) + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0 _MM_MAKEMASK(3,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD0) + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME 8 //Access: read-write +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_CA_HOLD_TIME) + +#define S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1 13 //Access: read-as-zero +#define M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1 _MM_MAKEMASK(19,S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1) +#define V_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1) +#define G_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1,M_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING_RSVD1) + + +#define S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME 0 //Access: read-write +#define M_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME) +#define V_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME) +#define G_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME,M_ANC_LINK_SDR_TIMING_CLE_ALE_SETUP_TIME) + +#define S_ANC_LINK_SDR_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_SDR_TIMING_RSVD0 _MM_MAKEMASK(3,S_ANC_LINK_SDR_TIMING_RSVD0) +#define V_ANC_LINK_SDR_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD0) +#define G_ANC_LINK_SDR_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD0,M_ANC_LINK_SDR_TIMING_RSVD0) + +#define S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME 8 //Access: read-write +#define M_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME) +#define V_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME) +#define G_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME,M_ANC_LINK_SDR_TIMING_CLE_ALE_HOLD_TIME) + +#define S_ANC_LINK_SDR_TIMING_RSVD1 13 //Access: read-as-zero +#define M_ANC_LINK_SDR_TIMING_RSVD1 _MM_MAKEMASK(3,S_ANC_LINK_SDR_TIMING_RSVD1) +#define V_ANC_LINK_SDR_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD1) +#define G_ANC_LINK_SDR_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD1,M_ANC_LINK_SDR_TIMING_RSVD1) + +#define S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY 16 //Access: read-write +#define M_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY _MM_MAKEMASK(5,S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY) +#define V_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY) +#define G_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY,M_ANC_LINK_SDR_TIMING_DATA_CAPTURE_DELAY) + +#define S_ANC_LINK_SDR_TIMING_RSVD2 21 //Access: read-as-zero +#define M_ANC_LINK_SDR_TIMING_RSVD2 _MM_MAKEMASK(11,S_ANC_LINK_SDR_TIMING_RSVD2) +#define V_ANC_LINK_SDR_TIMING_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD2) +#define G_ANC_LINK_SDR_TIMING_RSVD2(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_TIMING_RSVD2,M_ANC_LINK_SDR_TIMING_RSVD2) + + +#define S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME 0 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME,M_ANC_LINK_SDR_DATA_TIMING_REN_SETUP_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD0 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD0) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD0) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD0,M_ANC_LINK_SDR_DATA_TIMING_RSVD0) + +#define S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME 8 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME,M_ANC_LINK_SDR_DATA_TIMING_REN_HOLD_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD1 13 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD1 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD1) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD1) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD1,M_ANC_LINK_SDR_DATA_TIMING_RSVD1) + +#define S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME 16 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME,M_ANC_LINK_SDR_DATA_TIMING_WEN_SETUP_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD2 21 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD2 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD2) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD2) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD2(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD2,M_ANC_LINK_SDR_DATA_TIMING_RSVD2) + +#define S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME 24 //Access: read-write +#define M_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME _MM_MAKEMASK(5,S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME) +#define V_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME) +#define G_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME,M_ANC_LINK_SDR_DATA_TIMING_WEN_HOLD_TIME) + +#define S_ANC_LINK_SDR_DATA_TIMING_RSVD3 29 //Access: read-as-zero +#define M_ANC_LINK_SDR_DATA_TIMING_RSVD3 _MM_MAKEMASK(3,S_ANC_LINK_SDR_DATA_TIMING_RSVD3) +#define V_ANC_LINK_SDR_DATA_TIMING_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD3) +#define G_ANC_LINK_SDR_DATA_TIMING_RSVD3(V) _MM_GETVALUE((V),S_ANC_LINK_SDR_DATA_TIMING_RSVD3,M_ANC_LINK_SDR_DATA_TIMING_RSVD3) + + +#define S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH 0 //Access: read-write +#define M_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH _MM_MAKEMASK(5,S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH) +#define V_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH) +#define G_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH,M_ANC_LINK_DDR_DATA_TIMING_DDR_PULSE_WIDTH) + +#define S_ANC_LINK_DDR_DATA_TIMING_RSVD0 5 //Access: read-as-zero +#define M_ANC_LINK_DDR_DATA_TIMING_RSVD0 _MM_MAKEMASK(27,S_ANC_LINK_DDR_DATA_TIMING_RSVD0) +#define V_ANC_LINK_DDR_DATA_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_RSVD0) +#define G_ANC_LINK_DDR_DATA_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_DATA_TIMING_RSVD0,M_ANC_LINK_DDR_DATA_TIMING_RSVD0) + + +#define S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE 0 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE) +#define V_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE) +#define G_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE,M_ANC_LINK_DDR_READ_TIMING_READ_PREAMBLE) + +#define S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE 8 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE) +#define V_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE) +#define G_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE,M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE) + +#define S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD 16 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD) +#define V_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD) +#define G_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD,M_ANC_LINK_DDR_READ_TIMING_READ_POSTAMBLE_HOLD) + +#define S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND 24 //Access: read-write +#define M_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND _MM_MAKEMASK(8,S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND) +#define V_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND) +#define G_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND,M_ANC_LINK_DDR_READ_TIMING_READ_TURNAROUND) + + +#define S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE 0 //Access: read-write +#define M_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE) +#define V_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE) +#define G_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE,M_ANC_LINK_DDR_WRITE_TIMING_WRITE_PREAMBLE) + +#define S_ANC_LINK_DDR_WRITE_TIMING_RSVD0 8 //Access: read-as-zero +#define M_ANC_LINK_DDR_WRITE_TIMING_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_RSVD0) +#define V_ANC_LINK_DDR_WRITE_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD0) +#define G_ANC_LINK_DDR_WRITE_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD0,M_ANC_LINK_DDR_WRITE_TIMING_RSVD0) + +#define S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE 16 //Access: read-write +#define M_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE) +#define V_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE) +#define G_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE,M_ANC_LINK_DDR_WRITE_TIMING_WRITE_POSTAMBLE) + +#define S_ANC_LINK_DDR_WRITE_TIMING_RSVD1 24 //Access: read-as-zero +#define M_ANC_LINK_DDR_WRITE_TIMING_RSVD1 _MM_MAKEMASK(8,S_ANC_LINK_DDR_WRITE_TIMING_RSVD1) +#define V_ANC_LINK_DDR_WRITE_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD1) +#define G_ANC_LINK_DDR_WRITE_TIMING_RSVD1(V) _MM_GETVALUE((V),S_ANC_LINK_DDR_WRITE_TIMING_RSVD1,M_ANC_LINK_DDR_WRITE_TIMING_RSVD1) + + +#define S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY 0 //Access: read-write +#define M_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY _MM_MAKEMASK(6,S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY) +#define V_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY(V) _MM_MAKEVALUE((V),S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY) +#define G_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY(V) _MM_GETVALUE((V),S_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY,M_ANC_LINK_DQS_TIMING_WRITE_DQS_DELAY) + +#define S_ANC_LINK_DQS_TIMING_RSVD0 6 //Access: read-as-zero +#define M_ANC_LINK_DQS_TIMING_RSVD0 _MM_MAKEMASK(26,S_ANC_LINK_DQS_TIMING_RSVD0) +#define V_ANC_LINK_DQS_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_DQS_TIMING_RSVD0) +#define G_ANC_LINK_DQS_TIMING_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_DQS_TIMING_RSVD0,M_ANC_LINK_DQS_TIMING_RSVD0) + + +#define S_ANC_LINK_CMDQ_COUNT_TOTAL 0 //Access: read-only +#define M_ANC_LINK_CMDQ_COUNT_TOTAL _MM_MAKEMASK(32,S_ANC_LINK_CMDQ_COUNT_TOTAL) +#define V_ANC_LINK_CMDQ_COUNT_TOTAL(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_COUNT_TOTAL) +#define G_ANC_LINK_CMDQ_COUNT_TOTAL(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_COUNT_TOTAL,M_ANC_LINK_CMDQ_COUNT_TOTAL) + + +#define S_ANC_LINK_BYPASS_COUNT_TOTAL 0 //Access: read-only +#define M_ANC_LINK_BYPASS_COUNT_TOTAL _MM_MAKEMASK(32,S_ANC_LINK_BYPASS_COUNT_TOTAL) +#define V_ANC_LINK_BYPASS_COUNT_TOTAL(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_COUNT_TOTAL) +#define G_ANC_LINK_BYPASS_COUNT_TOTAL(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_COUNT_TOTAL,M_ANC_LINK_BYPASS_COUNT_TOTAL) + + +#define S_ANC_LINK_CMD_TIMEOUT_VALUE 0 //Access: read-write +#define M_ANC_LINK_CMD_TIMEOUT_VALUE _MM_MAKEMASK(31,S_ANC_LINK_CMD_TIMEOUT_VALUE) +#define V_ANC_LINK_CMD_TIMEOUT_VALUE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMD_TIMEOUT_VALUE) +#define G_ANC_LINK_CMD_TIMEOUT_VALUE(V) _MM_GETVALUE((V),S_ANC_LINK_CMD_TIMEOUT_VALUE,M_ANC_LINK_CMD_TIMEOUT_VALUE) + +#define S_ANC_LINK_CMD_TIMEOUT_ENABLE 31 //Access: read-write +#define M_ANC_LINK_CMD_TIMEOUT_ENABLE _MM_MAKEMASK(1,S_ANC_LINK_CMD_TIMEOUT_ENABLE) +#define V_ANC_LINK_CMD_TIMEOUT_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMD_TIMEOUT_ENABLE) +#define G_ANC_LINK_CMD_TIMEOUT_ENABLE(V) _MM_GETVALUE((V),S_ANC_LINK_CMD_TIMEOUT_ENABLE,M_ANC_LINK_CMD_TIMEOUT_ENABLE) + + +#define S_ANC_LINK_CMDQ_INT_CODE_CODE 0 //Access: read-only +#define M_ANC_LINK_CMDQ_INT_CODE_CODE _MM_MAKEMASK(16,S_ANC_LINK_CMDQ_INT_CODE_CODE) +#define V_ANC_LINK_CMDQ_INT_CODE_CODE(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_CODE) +#define G_ANC_LINK_CMDQ_INT_CODE_CODE(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_CODE,M_ANC_LINK_CMDQ_INT_CODE_CODE) + +#define S_ANC_LINK_CMDQ_INT_CODE_RSVD0 16 //Access: read-as-zero +#define M_ANC_LINK_CMDQ_INT_CODE_RSVD0 _MM_MAKEMASK(16,S_ANC_LINK_CMDQ_INT_CODE_RSVD0) +#define V_ANC_LINK_CMDQ_INT_CODE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_RSVD0) +#define G_ANC_LINK_CMDQ_INT_CODE_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_INT_CODE_RSVD0,M_ANC_LINK_CMDQ_INT_CODE_RSVD0) + + +#define S_ANC_LINK_TIMER_COUNT 0 //Access: read-only +#define M_ANC_LINK_TIMER_COUNT _MM_MAKEMASK(32,S_ANC_LINK_TIMER_COUNT) +#define V_ANC_LINK_TIMER_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_TIMER_COUNT) +#define G_ANC_LINK_TIMER_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_TIMER_COUNT,M_ANC_LINK_TIMER_COUNT) + + +#define S_ANC_LINK_CRC_PARITY_DATA 0 //Access: read-only +#define M_ANC_LINK_CRC_PARITY_DATA _MM_MAKEMASK(32,S_ANC_LINK_CRC_PARITY_DATA) +#define V_ANC_LINK_CRC_PARITY_DATA(V) _MM_MAKEVALUE((V),S_ANC_LINK_CRC_PARITY_DATA) +#define G_ANC_LINK_CRC_PARITY_DATA(V) _MM_GETVALUE((V),S_ANC_LINK_CRC_PARITY_DATA,M_ANC_LINK_CRC_PARITY_DATA) + + +#define S_ANC_LINK_NPL_INTERFACE_CLE 0 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_CLE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_CLE) +#define V_ANC_LINK_NPL_INTERFACE_CLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_CLE) +#define G_ANC_LINK_NPL_INTERFACE_CLE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_CLE,M_ANC_LINK_NPL_INTERFACE_CLE) + +#define S_ANC_LINK_NPL_INTERFACE_ALE 1 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_ALE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_ALE) +#define V_ANC_LINK_NPL_INTERFACE_ALE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_ALE) +#define G_ANC_LINK_NPL_INTERFACE_ALE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_ALE,M_ANC_LINK_NPL_INTERFACE_ALE) + +#define S_ANC_LINK_NPL_INTERFACE_REN 2 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_REN _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_REN) +#define V_ANC_LINK_NPL_INTERFACE_REN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_REN) +#define G_ANC_LINK_NPL_INTERFACE_REN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_REN,M_ANC_LINK_NPL_INTERFACE_REN) + +#define S_ANC_LINK_NPL_INTERFACE_WEN 3 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_WEN _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_WEN) +#define V_ANC_LINK_NPL_INTERFACE_WEN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_WEN) +#define G_ANC_LINK_NPL_INTERFACE_WEN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_WEN,M_ANC_LINK_NPL_INTERFACE_WEN) + +#define S_ANC_LINK_NPL_INTERFACE_DATA_OUT 4 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_DATA_OUT _MM_MAKEMASK(8,S_ANC_LINK_NPL_INTERFACE_DATA_OUT) +#define V_ANC_LINK_NPL_INTERFACE_DATA_OUT(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT) +#define G_ANC_LINK_NPL_INTERFACE_DATA_OUT(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT,M_ANC_LINK_NPL_INTERFACE_DATA_OUT) + +#define S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE 12 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE) +#define V_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE) +#define G_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE,M_ANC_LINK_NPL_INTERFACE_DATA_OUT_ENABLE) + +#define S_ANC_LINK_NPL_INTERFACE_WRITE_DQS 13 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_WRITE_DQS _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_WRITE_DQS) +#define V_ANC_LINK_NPL_INTERFACE_WRITE_DQS(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS) +#define G_ANC_LINK_NPL_INTERFACE_WRITE_DQS(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS,M_ANC_LINK_NPL_INTERFACE_WRITE_DQS) + +#define S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE 14 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE) +#define V_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE) +#define G_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE,M_ANC_LINK_NPL_INTERFACE_WRITE_DQS_ENABLE) + +#define S_ANC_LINK_NPL_INTERFACE_PULLDOWN 15 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_PULLDOWN _MM_MAKEMASK(1,S_ANC_LINK_NPL_INTERFACE_PULLDOWN) +#define V_ANC_LINK_NPL_INTERFACE_PULLDOWN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_PULLDOWN) +#define G_ANC_LINK_NPL_INTERFACE_PULLDOWN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_PULLDOWN,M_ANC_LINK_NPL_INTERFACE_PULLDOWN) + +#define S_ANC_LINK_NPL_INTERFACE_DATA_IN 16 //Access: read-only +#define M_ANC_LINK_NPL_INTERFACE_DATA_IN _MM_MAKEMASK(8,S_ANC_LINK_NPL_INTERFACE_DATA_IN) +#define V_ANC_LINK_NPL_INTERFACE_DATA_IN(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_IN) +#define G_ANC_LINK_NPL_INTERFACE_DATA_IN(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_DATA_IN,M_ANC_LINK_NPL_INTERFACE_DATA_IN) + +#define S_ANC_LINK_NPL_INTERFACE_RSVD0 24 //Access: read-as-zero +#define M_ANC_LINK_NPL_INTERFACE_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_NPL_INTERFACE_RSVD0) +#define V_ANC_LINK_NPL_INTERFACE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_NPL_INTERFACE_RSVD0) +#define G_ANC_LINK_NPL_INTERFACE_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_NPL_INTERFACE_RSVD0,M_ANC_LINK_NPL_INTERFACE_RSVD0) + + +#define S_ANC_LINK_MACRO_STATUS_ADDRESS 0 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_ADDRESS _MM_MAKEMASK(8,S_ANC_LINK_MACRO_STATUS_ADDRESS) +#define V_ANC_LINK_MACRO_STATUS_ADDRESS(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_ADDRESS) +#define G_ANC_LINK_MACRO_STATUS_ADDRESS(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_ADDRESS,M_ANC_LINK_MACRO_STATUS_ADDRESS) + +#define S_ANC_LINK_MACRO_STATUS_WORD_COUNT 8 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_WORD_COUNT _MM_MAKEMASK(8,S_ANC_LINK_MACRO_STATUS_WORD_COUNT) +#define V_ANC_LINK_MACRO_STATUS_WORD_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_WORD_COUNT) +#define G_ANC_LINK_MACRO_STATUS_WORD_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_WORD_COUNT,M_ANC_LINK_MACRO_STATUS_WORD_COUNT) + +#define S_ANC_LINK_MACRO_STATUS_LOOP_COUNT 16 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_LOOP_COUNT _MM_MAKEMASK(8,S_ANC_LINK_MACRO_STATUS_LOOP_COUNT) +#define V_ANC_LINK_MACRO_STATUS_LOOP_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_LOOP_COUNT) +#define G_ANC_LINK_MACRO_STATUS_LOOP_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_LOOP_COUNT,M_ANC_LINK_MACRO_STATUS_LOOP_COUNT) + +#define S_ANC_LINK_MACRO_STATUS_ACTIVE 24 //Access: read-only +#define M_ANC_LINK_MACRO_STATUS_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_MACRO_STATUS_ACTIVE) +#define V_ANC_LINK_MACRO_STATUS_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_ACTIVE) +#define G_ANC_LINK_MACRO_STATUS_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_ACTIVE,M_ANC_LINK_MACRO_STATUS_ACTIVE) + +#define S_ANC_LINK_MACRO_STATUS_RSVD0 25 //Access: read-as-zero +#define M_ANC_LINK_MACRO_STATUS_RSVD0 _MM_MAKEMASK(7,S_ANC_LINK_MACRO_STATUS_RSVD0) +#define V_ANC_LINK_MACRO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_MACRO_STATUS_RSVD0) +#define G_ANC_LINK_MACRO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_MACRO_STATUS_RSVD0,M_ANC_LINK_MACRO_STATUS_RSVD0) + + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS 0 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS _MM_MAKEMASK(8,S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS,M_ANC_LINK_BYPASS_MACRO_STATUS_ADDRESS) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT 8 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT _MM_MAKEMASK(8,S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT,M_ANC_LINK_BYPASS_MACRO_STATUS_WORD_COUNT) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT 16 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT _MM_MAKEMASK(8,S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT,M_ANC_LINK_BYPASS_MACRO_STATUS_LOOP_COUNT) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE 24 //Access: read-only +#define M_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE _MM_MAKEMASK(1,S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE,M_ANC_LINK_BYPASS_MACRO_STATUS_ACTIVE) + +#define S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0 25 //Access: read-as-zero +#define M_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0 _MM_MAKEMASK(7,S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0) +#define V_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0) +#define G_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0,M_ANC_LINK_BYPASS_MACRO_STATUS_RSVD0) + + +#define S_ANC_LINK_NAND_STATUS_VALUE 0 //Access: read-only +#define M_ANC_LINK_NAND_STATUS_VALUE _MM_MAKEMASK(8,S_ANC_LINK_NAND_STATUS_VALUE) +#define V_ANC_LINK_NAND_STATUS_VALUE(V) _MM_MAKEVALUE((V),S_ANC_LINK_NAND_STATUS_VALUE) +#define G_ANC_LINK_NAND_STATUS_VALUE(V) _MM_GETVALUE((V),S_ANC_LINK_NAND_STATUS_VALUE,M_ANC_LINK_NAND_STATUS_VALUE) + +#define S_ANC_LINK_NAND_STATUS_RSVD0 8 //Access: read-as-zero +#define M_ANC_LINK_NAND_STATUS_RSVD0 _MM_MAKEMASK(24,S_ANC_LINK_NAND_STATUS_RSVD0) +#define V_ANC_LINK_NAND_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_NAND_STATUS_RSVD0) +#define G_ANC_LINK_NAND_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_NAND_STATUS_RSVD0,M_ANC_LINK_NAND_STATUS_RSVD0) + + +#define S_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES 0 //Access: read-only +#define M_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES _MM_MAKEMASK(32,S_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES) +#define V_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES(V) _MM_MAKEVALUE((V),S_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES) +#define G_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES(V) _MM_GETVALUE((V),S_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES,M_ANC_LINK_DLFIFO_LINK_COUNT_WRITE_BYTES) + + +#define S_ANC_LINK_DLFIFO_COUNT_READ_BYTES 0 //Access: read-only +#define M_ANC_LINK_DLFIFO_COUNT_READ_BYTES _MM_MAKEMASK(32,S_ANC_LINK_DLFIFO_COUNT_READ_BYTES) +#define V_ANC_LINK_DLFIFO_COUNT_READ_BYTES(V) _MM_MAKEVALUE((V),S_ANC_LINK_DLFIFO_COUNT_READ_BYTES) +#define G_ANC_LINK_DLFIFO_COUNT_READ_BYTES(V) _MM_GETVALUE((V),S_ANC_LINK_DLFIFO_COUNT_READ_BYTES,M_ANC_LINK_DLFIFO_COUNT_READ_BYTES) + + +#define S_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES 0 //Access: read-only +#define M_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES _MM_MAKEMASK(32,S_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES) +#define V_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES(V) _MM_MAKEVALUE((V),S_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES) +#define G_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES(V) _MM_GETVALUE((V),S_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES,M_ANC_LINK_PIO_LINK_COUNT_WRITE_BYTES) + + +#define S_ANC_LINK_PIO_COUNT_READ_BYTES 0 //Access: read-only +#define M_ANC_LINK_PIO_COUNT_READ_BYTES _MM_MAKEMASK(32,S_ANC_LINK_PIO_COUNT_READ_BYTES) +#define V_ANC_LINK_PIO_COUNT_READ_BYTES(V) _MM_MAKEVALUE((V),S_ANC_LINK_PIO_COUNT_READ_BYTES) +#define G_ANC_LINK_PIO_COUNT_READ_BYTES(V) _MM_GETVALUE((V),S_ANC_LINK_PIO_COUNT_READ_BYTES,M_ANC_LINK_PIO_COUNT_READ_BYTES) + + +#define S_ANC_LINK_PHY_COUNT_WRITE_BYTES 0 //Access: read-only +#define M_ANC_LINK_PHY_COUNT_WRITE_BYTES _MM_MAKEMASK(32,S_ANC_LINK_PHY_COUNT_WRITE_BYTES) +#define V_ANC_LINK_PHY_COUNT_WRITE_BYTES(V) _MM_MAKEVALUE((V),S_ANC_LINK_PHY_COUNT_WRITE_BYTES) +#define G_ANC_LINK_PHY_COUNT_WRITE_BYTES(V) _MM_GETVALUE((V),S_ANC_LINK_PHY_COUNT_WRITE_BYTES,M_ANC_LINK_PHY_COUNT_WRITE_BYTES) + + +#define S_ANC_LINK_PHY_LINK_COUNT_READ_BYTES 0 //Access: read-only +#define M_ANC_LINK_PHY_LINK_COUNT_READ_BYTES _MM_MAKEMASK(32,S_ANC_LINK_PHY_LINK_COUNT_READ_BYTES) +#define V_ANC_LINK_PHY_LINK_COUNT_READ_BYTES(V) _MM_MAKEVALUE((V),S_ANC_LINK_PHY_LINK_COUNT_READ_BYTES) +#define G_ANC_LINK_PHY_LINK_COUNT_READ_BYTES(V) _MM_GETVALUE((V),S_ANC_LINK_PHY_LINK_COUNT_READ_BYTES,M_ANC_LINK_PHY_LINK_COUNT_READ_BYTES) + + +#define S_ANC_LINK_FSM_COUNTS_DATA_COUNT 0 //Access: read-only +#define M_ANC_LINK_FSM_COUNTS_DATA_COUNT _MM_MAKEMASK(16,S_ANC_LINK_FSM_COUNTS_DATA_COUNT) +#define V_ANC_LINK_FSM_COUNTS_DATA_COUNT(V) _MM_MAKEVALUE((V),S_ANC_LINK_FSM_COUNTS_DATA_COUNT) +#define G_ANC_LINK_FSM_COUNTS_DATA_COUNT(V) _MM_GETVALUE((V),S_ANC_LINK_FSM_COUNTS_DATA_COUNT,M_ANC_LINK_FSM_COUNTS_DATA_COUNT) + +#define S_ANC_LINK_FSM_COUNTS_DATA_LENGTH 16 //Access: read-only +#define M_ANC_LINK_FSM_COUNTS_DATA_LENGTH _MM_MAKEMASK(16,S_ANC_LINK_FSM_COUNTS_DATA_LENGTH) +#define V_ANC_LINK_FSM_COUNTS_DATA_LENGTH(V) _MM_MAKEVALUE((V),S_ANC_LINK_FSM_COUNTS_DATA_LENGTH) +#define G_ANC_LINK_FSM_COUNTS_DATA_LENGTH(V) _MM_GETVALUE((V),S_ANC_LINK_FSM_COUNTS_DATA_LENGTH,M_ANC_LINK_FSM_COUNTS_DATA_LENGTH) + + +#define S_ANC_LINK_ECC_WATERMARK_WATERMARK 0 //Access: read-write +#define M_ANC_LINK_ECC_WATERMARK_WATERMARK _MM_MAKEMASK(8,S_ANC_LINK_ECC_WATERMARK_WATERMARK) +#define V_ANC_LINK_ECC_WATERMARK_WATERMARK(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_WATERMARK_WATERMARK) +#define G_ANC_LINK_ECC_WATERMARK_WATERMARK(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_WATERMARK_WATERMARK,M_ANC_LINK_ECC_WATERMARK_WATERMARK) + +#define S_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE 8 //Access: read-write +#define M_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE _MM_MAKEMASK(1,S_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE) +#define V_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE) +#define G_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE,M_ANC_LINK_ECC_WATERMARK_WATERMARK_ENABLE) + +#define S_ANC_LINK_ECC_WATERMARK_RSVD0 9 //Access: read-as-zero +#define M_ANC_LINK_ECC_WATERMARK_RSVD0 _MM_MAKEMASK(23,S_ANC_LINK_ECC_WATERMARK_RSVD0) +#define V_ANC_LINK_ECC_WATERMARK_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_WATERMARK_RSVD0) +#define G_ANC_LINK_ECC_WATERMARK_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_WATERMARK_RSVD0,M_ANC_LINK_ECC_WATERMARK_RSVD0) + + +#define S_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS 0 //Access: read-write +#define M_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS _MM_MAKEMASK(8,S_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS) +#define V_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS) +#define G_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS,M_ANC_LINK_ECC_CONFIG_MAX_BIT_FLIPS) + +#define S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00 8 //Access: read-write +#define M_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00 _MM_MAKEMASK(8,S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00) +#define V_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00) +#define G_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00,M_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_00) + +#define S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF 16 //Access: read-write +#define M_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF _MM_MAKEMASK(8,S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF) +#define V_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF) +#define G_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF,M_ANC_LINK_ECC_CONFIG_ALLOWED_STUCK_BITS_FF) + +#define S_ANC_LINK_ECC_CONFIG_RSVD0 24 //Access: read-as-zero +#define M_ANC_LINK_ECC_CONFIG_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_ECC_CONFIG_RSVD0) +#define V_ANC_LINK_ECC_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_CONFIG_RSVD0) +#define G_ANC_LINK_ECC_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_CONFIG_RSVD0,M_ANC_LINK_ECC_CONFIG_RSVD0) + + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK 0 //Access: write-only +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK _MM_MAKEMASK(7,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_4_CHIN_CLK) + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0 7 //Access: read-as-zero +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0 _MM_MAKEMASK(1,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD0) + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK 8 //Access: write-only +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK _MM_MAKEMASK(7,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_3_CHIN_CLK) + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1 15 //Access: read-as-zero +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1 _MM_MAKEMASK(1,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD1) + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK 16 //Access: write-only +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK _MM_MAKEMASK(7,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DIV_2_CHIN_CLK) + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2 23 //Access: read-as-zero +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2 _MM_MAKEMASK(1,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD2) + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG 24 //Access: write-only +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG _MM_MAKEMASK(7,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_DONT_START_CHIEN_CONFIG) + +#define S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3 31 //Access: read-as-zero +#define M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3 _MM_MAKEMASK(1,S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3) +#define V_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3) +#define G_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3,M_ANC_ECC_P_CHIEN_CLOCK_CONFIG_RSVD3) + + +#define S_ANC_ECC_P_CONFIG_RSVD0 0 //Access: read-as-zero +#define M_ANC_ECC_P_CONFIG_RSVD0 _MM_MAKEMASK(1,S_ANC_ECC_P_CONFIG_RSVD0) +#define V_ANC_ECC_P_CONFIG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_RSVD0) +#define G_ANC_ECC_P_CONFIG_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_RSVD0,M_ANC_ECC_P_CONFIG_RSVD0) + +#define S_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND 1 //Access: write-only +#define M_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND _MM_MAKEMASK(1,S_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND) +#define V_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND) +#define G_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND,M_ANC_ECC_P_CONFIG_STOP_IF_ALL_ERROR_FOUND) + +#define S_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK 2 //Access: write-only +#define M_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK _MM_MAKEMASK(1,S_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK) +#define V_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK) +#define G_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK,M_ANC_ECC_P_CONFIG_EARLY_TERMINATION_MASK) + +#define S_ANC_ECC_P_CONFIG_RSVD1 3 //Access: read-as-zero +#define M_ANC_ECC_P_CONFIG_RSVD1 _MM_MAKEMASK(5,S_ANC_ECC_P_CONFIG_RSVD1) +#define V_ANC_ECC_P_CONFIG_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_RSVD1) +#define G_ANC_ECC_P_CONFIG_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_RSVD1,M_ANC_ECC_P_CONFIG_RSVD1) + +#define S_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT 8 //Access: write-only +#define M_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT _MM_MAKEMASK(1,S_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT) +#define V_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT) +#define G_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT,M_ANC_ECC_P_CONFIG_CHIEN_BMA_ABORT) + +#define S_ANC_ECC_P_CONFIG_RSVD2 9 //Access: read-as-zero +#define M_ANC_ECC_P_CONFIG_RSVD2 _MM_MAKEMASK(7,S_ANC_ECC_P_CONFIG_RSVD2) +#define V_ANC_ECC_P_CONFIG_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_RSVD2) +#define G_ANC_ECC_P_CONFIG_RSVD2(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_RSVD2,M_ANC_ECC_P_CONFIG_RSVD2) + +#define S_ANC_ECC_P_CONFIG_SYND_ABORT 16 //Access: write-only +#define M_ANC_ECC_P_CONFIG_SYND_ABORT _MM_MAKEMASK(1,S_ANC_ECC_P_CONFIG_SYND_ABORT) +#define V_ANC_ECC_P_CONFIG_SYND_ABORT(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_SYND_ABORT) +#define G_ANC_ECC_P_CONFIG_SYND_ABORT(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_SYND_ABORT,M_ANC_ECC_P_CONFIG_SYND_ABORT) + +#define S_ANC_ECC_P_CONFIG_RSVD3 17 //Access: read-as-zero +#define M_ANC_ECC_P_CONFIG_RSVD3 _MM_MAKEMASK(7,S_ANC_ECC_P_CONFIG_RSVD3) +#define V_ANC_ECC_P_CONFIG_RSVD3(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_RSVD3) +#define G_ANC_ECC_P_CONFIG_RSVD3(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_RSVD3,M_ANC_ECC_P_CONFIG_RSVD3) + +#define S_ANC_ECC_P_CONFIG_MASK_INT_EN 24 //Access: write-only +#define M_ANC_ECC_P_CONFIG_MASK_INT_EN _MM_MAKEMASK(1,S_ANC_ECC_P_CONFIG_MASK_INT_EN) +#define V_ANC_ECC_P_CONFIG_MASK_INT_EN(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_MASK_INT_EN) +#define G_ANC_ECC_P_CONFIG_MASK_INT_EN(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_MASK_INT_EN,M_ANC_ECC_P_CONFIG_MASK_INT_EN) + +#define S_ANC_ECC_P_CONFIG_RSVD4 25 //Access: read-as-zero +#define M_ANC_ECC_P_CONFIG_RSVD4 _MM_MAKEMASK(7,S_ANC_ECC_P_CONFIG_RSVD4) +#define V_ANC_ECC_P_CONFIG_RSVD4(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CONFIG_RSVD4) +#define G_ANC_ECC_P_CONFIG_RSVD4(V) _MM_GETVALUE((V),S_ANC_ECC_P_CONFIG_RSVD4,M_ANC_ECC_P_CONFIG_RSVD4) + + +#define S_ANC_ECC_P_OFFSET1_START_ADD_OFFSET 0 //Access: write-only +#define M_ANC_ECC_P_OFFSET1_START_ADD_OFFSET _MM_MAKEMASK(13,S_ANC_ECC_P_OFFSET1_START_ADD_OFFSET) +#define V_ANC_ECC_P_OFFSET1_START_ADD_OFFSET(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_OFFSET1_START_ADD_OFFSET) +#define G_ANC_ECC_P_OFFSET1_START_ADD_OFFSET(V) _MM_GETVALUE((V),S_ANC_ECC_P_OFFSET1_START_ADD_OFFSET,M_ANC_ECC_P_OFFSET1_START_ADD_OFFSET) + +#define S_ANC_ECC_P_OFFSET1_RSVD0 13 //Access: read-as-zero +#define M_ANC_ECC_P_OFFSET1_RSVD0 _MM_MAKEMASK(19,S_ANC_ECC_P_OFFSET1_RSVD0) +#define V_ANC_ECC_P_OFFSET1_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_OFFSET1_RSVD0) +#define G_ANC_ECC_P_OFFSET1_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_OFFSET1_RSVD0,M_ANC_ECC_P_OFFSET1_RSVD0) + + +#define S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH 0 //Access: write-only +#define M_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH _MM_MAKEMASK(13,S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH) +#define V_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH) +#define G_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH,M_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_ADD_TH) + +#define S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0 13 //Access: read-as-zero +#define M_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0 _MM_MAKEMASK(3,S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0) +#define V_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0) +#define G_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0,M_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD0) + +#define S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN 16 //Access: write-only +#define M_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN _MM_MAKEMASK(3,S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN) +#define V_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN) +#define G_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN,M_ANC_ECC_P_BCH_DIRECTION_CNFG_BCH_DIR_CPL1_EN) + +#define S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1 19 //Access: read-as-zero +#define M_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1 _MM_MAKEMASK(13,S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1) +#define V_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1) +#define G_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1,M_ANC_ECC_P_BCH_DIRECTION_CNFG_RSVD1) + + +#define S_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE 0 //Access: write-only +#define M_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE _MM_MAKEMASK(5,S_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE) +#define V_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE) +#define G_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE,M_ANC_ECC_P_PAGE_IDX_P_BCH_DEC_PAGE) + +#define S_ANC_ECC_P_PAGE_IDX_RSVD0 5 //Access: read-as-zero +#define M_ANC_ECC_P_PAGE_IDX_RSVD0 _MM_MAKEMASK(11,S_ANC_ECC_P_PAGE_IDX_RSVD0) +#define V_ANC_ECC_P_PAGE_IDX_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_IDX_RSVD0) +#define G_ANC_ECC_P_PAGE_IDX_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_IDX_RSVD0,M_ANC_ECC_P_PAGE_IDX_RSVD0) + +#define S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1 16 //Access: write-only +#define M_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1 _MM_MAKEMASK(5,S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1) +#define V_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1) +#define G_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1,M_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE1) + +#define S_ANC_ECC_P_PAGE_IDX_RSVD1 21 //Access: read-as-zero +#define M_ANC_ECC_P_PAGE_IDX_RSVD1 _MM_MAKEMASK(3,S_ANC_ECC_P_PAGE_IDX_RSVD1) +#define V_ANC_ECC_P_PAGE_IDX_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_IDX_RSVD1) +#define G_ANC_ECC_P_PAGE_IDX_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_IDX_RSVD1,M_ANC_ECC_P_PAGE_IDX_RSVD1) + +#define S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2 24 //Access: write-only +#define M_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2 _MM_MAKEMASK(5,S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2) +#define V_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2) +#define G_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2,M_ANC_ECC_P_PAGE_IDX_P_BCH_DIR_RD_PAGE2) + +#define S_ANC_ECC_P_PAGE_IDX_RSVD2 29 //Access: read-as-zero +#define M_ANC_ECC_P_PAGE_IDX_RSVD2 _MM_MAKEMASK(3,S_ANC_ECC_P_PAGE_IDX_RSVD2) +#define V_ANC_ECC_P_PAGE_IDX_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_IDX_RSVD2) +#define G_ANC_ECC_P_PAGE_IDX_RSVD2(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_IDX_RSVD2,M_ANC_ECC_P_PAGE_IDX_RSVD2) + + +#define S_ANC_ECC_P_PAGE_STRUCTURE_T_CODE 0 //Access: write-only +#define M_ANC_ECC_P_PAGE_STRUCTURE_T_CODE _MM_MAKEMASK(8,S_ANC_ECC_P_PAGE_STRUCTURE_T_CODE) +#define V_ANC_ECC_P_PAGE_STRUCTURE_T_CODE(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_T_CODE) +#define G_ANC_ECC_P_PAGE_STRUCTURE_T_CODE(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_T_CODE,M_ANC_ECC_P_PAGE_STRUCTURE_T_CODE) + +#define S_ANC_ECC_P_PAGE_STRUCTURE_RSVD0 8 //Access: read-as-zero +#define M_ANC_ECC_P_PAGE_STRUCTURE_RSVD0 _MM_MAKEMASK(8,S_ANC_ECC_P_PAGE_STRUCTURE_RSVD0) +#define V_ANC_ECC_P_PAGE_STRUCTURE_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_RSVD0) +#define G_ANC_ECC_P_PAGE_STRUCTURE_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_RSVD0,M_ANC_ECC_P_PAGE_STRUCTURE_RSVD0) + +#define S_ANC_ECC_P_PAGE_STRUCTURE_N_CODE 16 //Access: write-only +#define M_ANC_ECC_P_PAGE_STRUCTURE_N_CODE _MM_MAKEMASK(13,S_ANC_ECC_P_PAGE_STRUCTURE_N_CODE) +#define V_ANC_ECC_P_PAGE_STRUCTURE_N_CODE(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_N_CODE) +#define G_ANC_ECC_P_PAGE_STRUCTURE_N_CODE(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_N_CODE,M_ANC_ECC_P_PAGE_STRUCTURE_N_CODE) + +#define S_ANC_ECC_P_PAGE_STRUCTURE_RSVD1 29 //Access: read-as-zero +#define M_ANC_ECC_P_PAGE_STRUCTURE_RSVD1 _MM_MAKEMASK(3,S_ANC_ECC_P_PAGE_STRUCTURE_RSVD1) +#define V_ANC_ECC_P_PAGE_STRUCTURE_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_RSVD1) +#define G_ANC_ECC_P_PAGE_STRUCTURE_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_PAGE_STRUCTURE_RSVD1,M_ANC_ECC_P_PAGE_STRUCTURE_RSVD1) + + +#define S_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN 0 //Access: write-only +#define M_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN _MM_MAKEMASK(1,S_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN) +#define V_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN) +#define G_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN(V) _MM_GETVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN,M_ANC_ECC_P_ECC_CLK_CNFG_P_SYND_FORCE_CLK_EN) + +#define S_ANC_ECC_P_ECC_CLK_CNFG_RSVD0 1 //Access: read-as-zero +#define M_ANC_ECC_P_ECC_CLK_CNFG_RSVD0 _MM_MAKEMASK(7,S_ANC_ECC_P_ECC_CLK_CNFG_RSVD0) +#define V_ANC_ECC_P_ECC_CLK_CNFG_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_RSVD0) +#define G_ANC_ECC_P_ECC_CLK_CNFG_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_RSVD0,M_ANC_ECC_P_ECC_CLK_CNFG_RSVD0) + +#define S_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN 8 //Access: write-only +#define M_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN _MM_MAKEMASK(1,S_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN) +#define V_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN) +#define G_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN(V) _MM_GETVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN,M_ANC_ECC_P_ECC_CLK_CNFG_P_BMA_FORCE_CLK_EN) + +#define S_ANC_ECC_P_ECC_CLK_CNFG_RSVD1 9 //Access: read-as-zero +#define M_ANC_ECC_P_ECC_CLK_CNFG_RSVD1 _MM_MAKEMASK(7,S_ANC_ECC_P_ECC_CLK_CNFG_RSVD1) +#define V_ANC_ECC_P_ECC_CLK_CNFG_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_RSVD1) +#define G_ANC_ECC_P_ECC_CLK_CNFG_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_RSVD1,M_ANC_ECC_P_ECC_CLK_CNFG_RSVD1) + +#define S_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN 16 //Access: write-only +#define M_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN _MM_MAKEMASK(1,S_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN) +#define V_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN) +#define G_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN(V) _MM_GETVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN,M_ANC_ECC_P_ECC_CLK_CNFG_P_CHIEN_FORCE_CLK_EN) + +#define S_ANC_ECC_P_ECC_CLK_CNFG_RSVD2 17 //Access: read-as-zero +#define M_ANC_ECC_P_ECC_CLK_CNFG_RSVD2 _MM_MAKEMASK(15,S_ANC_ECC_P_ECC_CLK_CNFG_RSVD2) +#define V_ANC_ECC_P_ECC_CLK_CNFG_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_RSVD2) +#define G_ANC_ECC_P_ECC_CLK_CNFG_RSVD2(V) _MM_GETVALUE((V),S_ANC_ECC_P_ECC_CLK_CNFG_RSVD2,M_ANC_ECC_P_ECC_CLK_CNFG_RSVD2) + + +#define S_ANC_ECC_P_OFFSET3_P_OFFSET3 0 //Access: write-only +#define M_ANC_ECC_P_OFFSET3_P_OFFSET3 _MM_MAKEMASK(13,S_ANC_ECC_P_OFFSET3_P_OFFSET3) +#define V_ANC_ECC_P_OFFSET3_P_OFFSET3(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_OFFSET3_P_OFFSET3) +#define G_ANC_ECC_P_OFFSET3_P_OFFSET3(V) _MM_GETVALUE((V),S_ANC_ECC_P_OFFSET3_P_OFFSET3,M_ANC_ECC_P_OFFSET3_P_OFFSET3) + +#define S_ANC_ECC_P_OFFSET3_RSVD0 13 //Access: read-as-zero +#define M_ANC_ECC_P_OFFSET3_RSVD0 _MM_MAKEMASK(19,S_ANC_ECC_P_OFFSET3_RSVD0) +#define V_ANC_ECC_P_OFFSET3_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_OFFSET3_RSVD0) +#define G_ANC_ECC_P_OFFSET3_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_OFFSET3_RSVD0,M_ANC_ECC_P_OFFSET3_RSVD0) + + +#define S_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET 0 //Access: write-only +#define M_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET _MM_MAKEMASK(16,S_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET) +#define V_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET) +#define G_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET,M_ANC_ECC_P_CHIEN_START_OFFSET_CHIEN_START_OFFSET) + +#define S_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0 16 //Access: read-as-zero +#define M_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0 _MM_MAKEMASK(16,S_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0) +#define V_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0) +#define G_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0,M_ANC_ECC_P_CHIEN_START_OFFSET_RSVD0) + + +#define S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING 0 //Access: write-only +#define M_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING _MM_MAKEMASK(13,S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING) +#define V_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING) +#define G_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING,M_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_CHIEN_EARLY_INT_TIMING) + +#define S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0 13 //Access: read-as-zero +#define M_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0 _MM_MAKEMASK(19,S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0) +#define V_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0) +#define G_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0,M_ANC_ECC_P_CHIEN_EARLY_INTERRUPT_RSVD0) + + +#define S_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE 0 //Access: write-only +#define M_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE _MM_MAKEMASK(13,S_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE) +#define V_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE) +#define G_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE(V) _MM_GETVALUE((V),S_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE,M_ANC_ECC_P_OFFSET4_CHIEN_LAST_FIX_BYTE) + +#define S_ANC_ECC_P_OFFSET4_RSVD0 13 //Access: read-as-zero +#define M_ANC_ECC_P_OFFSET4_RSVD0 _MM_MAKEMASK(19,S_ANC_ECC_P_OFFSET4_RSVD0) +#define V_ANC_ECC_P_OFFSET4_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_OFFSET4_RSVD0) +#define G_ANC_ECC_P_OFFSET4_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_OFFSET4_RSVD0,M_ANC_ECC_P_OFFSET4_RSVD0) + + +#define S_ANC_ECC_P_STATUS_STATUS 0 //Access: read-only +#define M_ANC_ECC_P_STATUS_STATUS _MM_MAKEMASK(1,S_ANC_ECC_P_STATUS_STATUS) +#define V_ANC_ECC_P_STATUS_STATUS(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_STATUS_STATUS) +#define G_ANC_ECC_P_STATUS_STATUS(V) _MM_GETVALUE((V),S_ANC_ECC_P_STATUS_STATUS,M_ANC_ECC_P_STATUS_STATUS) + +#define S_ANC_ECC_P_STATUS_RSVD0 1 //Access: read-as-zero +#define M_ANC_ECC_P_STATUS_RSVD0 _MM_MAKEMASK(7,S_ANC_ECC_P_STATUS_RSVD0) +#define V_ANC_ECC_P_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_STATUS_RSVD0) +#define G_ANC_ECC_P_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_STATUS_RSVD0,M_ANC_ECC_P_STATUS_RSVD0) + +#define S_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR 8 //Access: read-only +#define M_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR _MM_MAKEMASK(7,S_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR) +#define V_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR) +#define G_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR(V) _MM_GETVALUE((V),S_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR,M_ANC_ECC_P_STATUS_NUMBER_OF_FOUND_ERROR) + +#define S_ANC_ECC_P_STATUS_RSVD1 15 //Access: read-as-zero +#define M_ANC_ECC_P_STATUS_RSVD1 _MM_MAKEMASK(1,S_ANC_ECC_P_STATUS_RSVD1) +#define V_ANC_ECC_P_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_STATUS_RSVD1) +#define G_ANC_ECC_P_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_STATUS_RSVD1,M_ANC_ECC_P_STATUS_RSVD1) + +#define S_ANC_ECC_P_STATUS_BCH_CE 16 //Access: read-only +#define M_ANC_ECC_P_STATUS_BCH_CE _MM_MAKEMASK(2,S_ANC_ECC_P_STATUS_BCH_CE) +#define V_ANC_ECC_P_STATUS_BCH_CE(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_STATUS_BCH_CE) +#define G_ANC_ECC_P_STATUS_BCH_CE(V) _MM_GETVALUE((V),S_ANC_ECC_P_STATUS_BCH_CE,M_ANC_ECC_P_STATUS_BCH_CE) + +#define S_ANC_ECC_P_STATUS_RSVD2 18 //Access: read-as-zero +#define M_ANC_ECC_P_STATUS_RSVD2 _MM_MAKEMASK(14,S_ANC_ECC_P_STATUS_RSVD2) +#define V_ANC_ECC_P_STATUS_RSVD2(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_STATUS_RSVD2) +#define G_ANC_ECC_P_STATUS_RSVD2(V) _MM_GETVALUE((V),S_ANC_ECC_P_STATUS_RSVD2,M_ANC_ECC_P_STATUS_RSVD2) + + +#define S_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR 0 //Access: read-only +#define M_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR _MM_MAKEMASK(7,S_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR) +#define V_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR) +#define G_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR,M_ANC_ECC_P_BCH_DIR_CNTRS_ZERO_TO_ONE_CNTR) + +#define S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0 7 //Access: read-as-zero +#define M_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0 _MM_MAKEMASK(9,S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0) +#define V_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0) +#define G_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0,M_ANC_ECC_P_BCH_DIR_CNTRS_RSVD0) + +#define S_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR 16 //Access: read-only +#define M_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR _MM_MAKEMASK(7,S_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR) +#define V_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR) +#define G_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR,M_ANC_ECC_P_BCH_DIR_CNTRS_ONE_TO_ZERO_CNTR) + +#define S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1 23 //Access: read-as-zero +#define M_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1 _MM_MAKEMASK(9,S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1) +#define V_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1) +#define G_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1,M_ANC_ECC_P_BCH_DIR_CNTRS_RSVD1) + + +#define S_ANC_ECC_P_BMA_STATUS_BMA_DEGREE 0 //Access: read-only +#define M_ANC_ECC_P_BMA_STATUS_BMA_DEGREE _MM_MAKEMASK(7,S_ANC_ECC_P_BMA_STATUS_BMA_DEGREE) +#define V_ANC_ECC_P_BMA_STATUS_BMA_DEGREE(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BMA_STATUS_BMA_DEGREE) +#define G_ANC_ECC_P_BMA_STATUS_BMA_DEGREE(V) _MM_GETVALUE((V),S_ANC_ECC_P_BMA_STATUS_BMA_DEGREE,M_ANC_ECC_P_BMA_STATUS_BMA_DEGREE) + +#define S_ANC_ECC_P_BMA_STATUS_RSVD0 7 //Access: read-as-zero +#define M_ANC_ECC_P_BMA_STATUS_RSVD0 _MM_MAKEMASK(1,S_ANC_ECC_P_BMA_STATUS_RSVD0) +#define V_ANC_ECC_P_BMA_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BMA_STATUS_RSVD0) +#define G_ANC_ECC_P_BMA_STATUS_RSVD0(V) _MM_GETVALUE((V),S_ANC_ECC_P_BMA_STATUS_RSVD0,M_ANC_ECC_P_BMA_STATUS_RSVD0) + +#define S_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION 8 //Access: read-only +#define M_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION _MM_MAKEMASK(1,S_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION) +#define V_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION) +#define G_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION(V) _MM_GETVALUE((V),S_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION,M_ANC_ECC_P_BMA_STATUS_BMA_EARLY_TERMINATION_INDICATION) + +#define S_ANC_ECC_P_BMA_STATUS_RSVD1 9 //Access: read-as-zero +#define M_ANC_ECC_P_BMA_STATUS_RSVD1 _MM_MAKEMASK(23,S_ANC_ECC_P_BMA_STATUS_RSVD1) +#define V_ANC_ECC_P_BMA_STATUS_RSVD1(V) _MM_MAKEVALUE((V),S_ANC_ECC_P_BMA_STATUS_RSVD1) +#define G_ANC_ECC_P_BMA_STATUS_RSVD1(V) _MM_GETVALUE((V),S_ANC_ECC_P_BMA_STATUS_RSVD1,M_ANC_ECC_P_BMA_STATUS_RSVD1) + + +#define S_ANC_MACRO_TABLE_COMMAND_RSVD0 0 //Access: read-as-zero +#define M_ANC_MACRO_TABLE_COMMAND_RSVD0 _MM_MAKEMASK(256,S_ANC_MACRO_TABLE_COMMAND_RSVD0) +#define V_ANC_MACRO_TABLE_COMMAND_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_MACRO_TABLE_COMMAND_RSVD0) +#define G_ANC_MACRO_TABLE_COMMAND_RSVD0(V) _MM_GETVALUE((V),S_ANC_MACRO_TABLE_COMMAND_RSVD0,M_ANC_MACRO_TABLE_COMMAND_RSVD0) + + +#define S_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0 0 //Access: read-as-zero +#define M_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0 _MM_MAKEMASK(128,S_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0) +#define V_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0) +#define G_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0,M_ANC_DMA_CMDQ_FIFO_DA_WORD_RSVD0) + + +#define S_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0 0 //Access: read-as-zero +#define M_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0 _MM_MAKEMASK(128,S_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0) +#define V_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0) +#define G_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0,M_ANC_LINK_CMDQ_FIFO_DA_WORD_RSVD0) + + +#define S_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0 0 //Access: read-as-zero +#define M_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0 _MM_MAKEMASK(8,S_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0) +#define V_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0) +#define G_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0,M_ANC_LINK_BYPASS_FIFO_DA_WORD_RSVD0) + + +#define S_ANC_PIO_READ_FIFO_DA_WORD_RSVD0 0 //Access: read-as-zero +#define M_ANC_PIO_READ_FIFO_DA_WORD_RSVD0 _MM_MAKEMASK(64,S_ANC_PIO_READ_FIFO_DA_WORD_RSVD0) +#define V_ANC_PIO_READ_FIFO_DA_WORD_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_PIO_READ_FIFO_DA_WORD_RSVD0) +#define G_ANC_PIO_READ_FIFO_DA_WORD_RSVD0(V) _MM_GETVALUE((V),S_ANC_PIO_READ_FIFO_DA_WORD_RSVD0,M_ANC_PIO_READ_FIFO_DA_WORD_RSVD0) + + +#define S_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0 0 //Access: read-as-zero +#define M_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0 _MM_MAKEMASK(32,S_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0) +#define V_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0) +#define G_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0(V) _MM_GETVALUE((V),S_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0,M_ANC_DMA_DEBUG_FIFO_COMMAND_RSVD0) + + +#define S_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0 0 //Access: read-as-zero +#define M_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0 _MM_MAKEMASK(32,S_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0) +#define V_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0) +#define G_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0,M_ANC_LINK_DEBUG_FIFO_COMMAND_RSVD0) + + +#define S_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0 0 //Access: read-as-zero +#define M_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0 _MM_MAKEMASK(64,S_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0) +#define V_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0(V) _MM_MAKEVALUE((V),S_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0) +#define G_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0(V) _MM_GETVALUE((V),S_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0,M_ANC_LINK_ECC_STATUS_FIFO_DA_WORD_RSVD0) + + + +/******************************************************************************/ +/* Register Fields typedef structs */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ + +typedef union anc_chan_version_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t minor_release:8; //Access: read-only + uint32_t major_release:8; //Access: read-only + uint32_t version:8; //Access: read-only + uint32_t rsvd0:8; //Access: read-as-zero + }f; +} anc_chan_version_t; + +typedef union anc_chan_config_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t auto_clk_gating_en:1; //Access: read-write + uint32_t rsvd0:31; //Access: read-as-zero + }f; +} anc_chan_config_t; + +typedef union anc_chan_int_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t dma_cmd_flag:1; //Access: write-once-clear + uint32_t link_cmd_flag:1; //Access: write-once-clear + uint32_t channel_stopped:1; //Access: write-once-clear + uint32_t dma_cmdq_fifo_low:1; //Access: read-only + uint32_t link_cmdq_fifo_low:1; //Access: read-only + uint32_t link_bypass_fifo_low:1; //Access: read-only + uint32_t link_pio_read_fifo_high:1; //Access: read-only + uint32_t dma_cmdq_fifo_overflow:1; //Access: write-once-clear + uint32_t link_cmdq_fifo_overflow:1; //Access: write-once-clear + uint32_t link_bypass_fifo_overflow:1; //Access: write-once-clear + uint32_t link_pio_read_fifo_underflow:1; //Access: write-once-clear + uint32_t crc_err:1; //Access: write-once-clear + uint32_t read_status_err_response:1; //Access: write-once-clear + uint32_t invalid_dma_command:1; //Access: write-once-clear + uint32_t invalid_link_command:1; //Access: write-once-clear + uint32_t axi_response_not_okay:1; //Access: write-once-clear + uint32_t aes_err:1; //Access: write-once-clear + uint32_t dma_cmd_timeout:1; //Access: write-once-clear + uint32_t link_cmd_timeout:1; //Access: write-once-clear + uint32_t link_ecc_status_fifo_high:1; //Access: read-only + uint32_t link_ecc_status_fifo_underflow:1; //Access: write-once-clear + uint32_t rsvd0:11; //Access: read-as-zero + }f; +} anc_chan_int_status_t; + +typedef union anc_chan_int_enable_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t dma_cmd_flag:1; //Access: read-write + uint32_t link_cmd_flag:1; //Access: read-write + uint32_t channel_stopped:1; //Access: read-write + uint32_t dma_cmdq_fifo_low:1; //Access: read-write + uint32_t link_cmdq_fifo_low:1; //Access: read-write + uint32_t link_bypass_fifo_low:1; //Access: read-write + uint32_t link_pio_read_fifo_high:1; //Access: read-write + uint32_t dma_cmdq_fifo_overflow:1; //Access: read-write + uint32_t link_cmdq_fifo_overflow:1; //Access: read-write + uint32_t link_bypass_fifo_overflow:1; //Access: read-write + uint32_t link_pio_read_fifo_underflow:1; //Access: read-write + uint32_t crc_err:1; //Access: read-write + uint32_t read_status_err_response:1; //Access: read-write + uint32_t invalid_dma_command:1; //Access: read-write + uint32_t invalid_link_command:1; //Access: read-write + uint32_t axi_response_not_okay:1; //Access: read-write + uint32_t aes_err:1; //Access: read-write + uint32_t dma_cmd_timeout:1; //Access: read-write + uint32_t link_cmd_timeout:1; //Access: read-write + uint32_t link_ecc_status_fifo_high:1; //Access: read-write + uint32_t link_ecc_status_fifo_underflow:1; //Access: read-write + uint32_t rsvd0:11; //Access: read-as-zero + }f; +} anc_chan_int_enable_t; + +typedef union anc_chan_dma_watermarks_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t dma_cmdq_fifo_low:7; //Access: read-write + uint32_t rsvd0:25; //Access: read-as-zero + }f; +} anc_chan_dma_watermarks_t; + +typedef union anc_chan_link_watermarks_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t link_cmdq_fifo_low:8; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + uint32_t link_bypass_fifo_low:4; //Access: read-write + uint32_t rsvd1:4; //Access: read-as-zero + uint32_t link_pio_read_fifo_high:7; //Access: read-write + uint32_t rsvd2:1; //Access: read-as-zero + }f; +} anc_chan_link_watermarks_t; + +typedef union anc_chan_status_watermarks_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t link_ecc_status_fifo_high:7; //Access: read-write + uint32_t rsvd0:25; //Access: read-as-zero + }f; +} anc_chan_status_watermarks_t; + +typedef union anc_chan_dma_cmdq_fifo_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t low:1; //Access: read-only + uint32_t full:1; //Access: read-only + uint32_t overflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t read_pointer:6; //Access: read-only + uint32_t rsvd2:2; //Access: read-as-zero + uint32_t write_pointer:6; //Access: read-only + uint32_t rsvd3:2; //Access: read-as-zero + }f; +} anc_chan_dma_cmdq_fifo_status_t; + +typedef union anc_chan_link_cmdq_fifo_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t low:1; //Access: read-only + uint32_t full:1; //Access: read-only + uint32_t overflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:8; //Access: read-only + uint32_t read_pointer:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t write_pointer:7; //Access: read-only + uint32_t rsvd2:1; //Access: read-as-zero + }f; +} anc_chan_link_cmdq_fifo_status_t; + +typedef union anc_chan_link_bypass_fifo_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t low:1; //Access: read-only + uint32_t full:1; //Access: read-only + uint32_t overflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:4; //Access: read-only + uint32_t rsvd1:4; //Access: read-as-zero + uint32_t read_pointer:3; //Access: read-only + uint32_t rsvd2:5; //Access: read-as-zero + uint32_t write_pointer:3; //Access: read-only + uint32_t rsvd3:5; //Access: read-as-zero + }f; +} anc_chan_link_bypass_fifo_status_t; + +typedef union anc_chan_link_pio_read_fifo_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t high:1; //Access: read-only + uint32_t empty:1; //Access: read-only + uint32_t underflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t read_pointer:6; //Access: read-only + uint32_t rsvd2:2; //Access: read-as-zero + uint32_t write_pointer:6; //Access: read-only + uint32_t rsvd3:2; //Access: read-as-zero + }f; +} anc_chan_link_pio_read_fifo_status_t; + +typedef union anc_chan_dma_debug_fifo_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_pointer:4; //Access: read-only + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} anc_chan_dma_debug_fifo_status_t; + +typedef union anc_chan_link_debug_fifo_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_pointer:5; //Access: read-only + uint32_t rsvd0:27; //Access: read-as-zero + }f; +} anc_chan_link_debug_fifo_status_t; + +typedef union anc_chan_link_ecc_status_fifo_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t high:1; //Access: read-only + uint32_t empty:1; //Access: read-only + uint32_t underflow:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t level:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t read_pointer:6; //Access: read-only + uint32_t rsvd2:2; //Access: read-as-zero + uint32_t write_pointer:6; //Access: read-only + uint32_t rsvd3:2; //Access: read-as-zero + }f; +} anc_chan_link_ecc_status_fifo_status_t; + +typedef union anc_chan_dma_cmdq_fifo_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t push_word:32; //Access: write-only + }f; +} anc_chan_dma_cmdq_fifo_t; + +typedef union anc_chan_link_cmdq_fifo_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t push_word:32; //Access: write-only + }f; +} anc_chan_link_cmdq_fifo_t; + +typedef union anc_chan_link_bypass_fifo_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t push_word:32; //Access: write-only + }f; +} anc_chan_link_bypass_fifo_t; + +typedef union anc_chan_link_pio_read_fifo_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t pop_word:32; //Access: read-only + }f; +} anc_chan_link_pio_read_fifo_t; + +typedef union anc_chan_dma_debug_fifo_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t pop_word:32; //Access: read-only + }f; +} anc_chan_dma_debug_fifo_t; + +typedef union anc_chan_link_debug_fifo_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t pop_word:32; //Access: read-only + }f; +} anc_chan_link_debug_fifo_t; + +typedef union anc_chan_link_ecc_status_fifo_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t pop_word:32; //Access: read-only + }f; +} anc_chan_link_ecc_status_fifo_t; + + +typedef union anc_dma_config_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t axi_axqos:4; //Access: read-write + uint32_t rsvd0:4; //Access: read-as-zero + uint32_t burst_size:2; //Access: read-write + uint32_t rsvd1:22; //Access: read-as-zero + }f; +} anc_dma_config_t; + +typedef union anc_dma_control_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t start:1; //Access: write-auto-clear + uint32_t stop:1; //Access: write-auto-clear + uint32_t reset:1; //Access: write-auto-clear + uint32_t rsvd0:29; //Access: read-as-zero + }f; +} anc_dma_control_t; + +typedef union anc_dma_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t dma_active:1; //Access: read-only + uint32_t axi_active:1; //Access: read-only + uint32_t aes_active:1; //Access: read-only + uint32_t cmdq_enabled:1; //Access: read-only + uint32_t aes_enabled:1; //Access: read-only + uint32_t dma_direction:1; //Access: read-only + uint32_t rsvd0:26; //Access: read-as-zero + }f; +} anc_dma_status_t; + +typedef union anc_dma_aes_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t key_select:1; //Access: read-only + uint32_t key_length:2; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t key_in_ctx:1; //Access: read-only + uint32_t iv_in_ctx:1; //Access: read-only + uint32_t txt_in_key_ctx:1; //Access: read-only + uint32_t txt_in_iv_ctx:1; //Access: read-only + uint32_t aes_err:1; //Access: read-only + uint32_t rsvd2:22; //Access: read-as-zero + }f; +} anc_dma_aes_status_t; + +typedef union anc_dma_cmdq_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t total:32; //Access: read-only + }f; +} anc_dma_cmdq_count_t; + +typedef union anc_dma_cmd_timeout_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t value:31; //Access: read-write + uint32_t enable:1; //Access: read-write + }f; +} anc_dma_cmd_timeout_t; + +typedef union anc_dma_cmdq_int_code_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t code:16; //Access: read-only + uint32_t rsvd0:16; //Access: read-as-zero + }f; +} anc_dma_cmdq_int_code_t; + +typedef union anc_dma_axi_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t address_requests_outstanding:5; //Access: read-only + uint32_t address_requests_words_remaining:9; //Access: read-only + uint32_t response:2; //Access: read-only + uint32_t write_data_available:7; //Access: read-only + uint32_t read_space_available:7; //Access: read-only + uint32_t rsvd0:2; //Access: read-as-zero + }f; +} anc_dma_axi_t; + +typedef union anc_dma_axi_next_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t request_length:4; //Access: read-only + uint32_t rsvd0:20; //Access: read-as-zero + uint32_t address_high_byte:8; //Access: read-only + }f; +} anc_dma_axi_next_t; + +typedef union anc_dma_axi_next_address_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t lower_four_bytes:32; //Access: read-only + }f; +} anc_dma_axi_next_address_t; + +typedef union anc_dma_axi_dma_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_words:32; //Access: read-only + }f; +} anc_dma_axi_dma_count_t; + +typedef union anc_dma_axi_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_words:32; //Access: read-only + }f; +} anc_dma_axi_count_t; + +typedef union anc_dma_dlfifo_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_words:32; //Access: read-only + }f; +} anc_dma_dlfifo_count_t; + +typedef union anc_dma_dlfifo_dma_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_words:32; //Access: read-only + }f; +} anc_dma_dlfifo_dma_count_t; + +typedef union anc_dma_axi_dma_last_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_words:32; //Access: read-only + }f; +} anc_dma_axi_dma_last_count_t; + +typedef union anc_dma_axi_last_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_words:32; //Access: read-only + }f; +} anc_dma_axi_last_count_t; + +typedef union anc_dma_dlfifo_last_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_words:32; //Access: read-only + }f; +} anc_dma_dlfifo_last_count_t; + +typedef union anc_dma_dlfifo_dma_last_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_words:32; //Access: read-only + }f; +} anc_dma_dlfifo_dma_last_count_t; + + +typedef union anc_link_config_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t ddr_mode:1; //Access: read-write + uint32_t enable_crc:1; //Access: read-write + uint32_t autopad_crc:1; //Access: read-write + uint32_t enable_scrambler:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} anc_link_config_t; + +typedef union anc_link_control_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t start:1; //Access: write-auto-clear + uint32_t stop:1; //Access: write-auto-clear + uint32_t yield:1; //Access: write-auto-clear + uint32_t abort:1; //Access: write-auto-clear + uint32_t reset:1; //Access: write-auto-clear + uint32_t start_cmdq:1; //Access: write-auto-clear + uint32_t stop_cmdq:1; //Access: write-auto-clear + uint32_t reset_cmdq:1; //Access: write-auto-clear + uint32_t start_bypass:1; //Access: write-auto-clear + uint32_t stop_bypass:1; //Access: write-auto-clear + uint32_t reset_bypass:1; //Access: write-auto-clear + uint32_t start_timer:1; //Access: write-auto-clear + uint32_t stop_timer:1; //Access: write-auto-clear + uint32_t reset_timer:1; //Access: write-auto-clear + uint32_t reset_pio_read:1; //Access: write-auto-clear + uint32_t rsvd0:17; //Access: read-as-zero + }f; +} anc_link_control_t; + +typedef union anc_link_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t cmdq_active:1; //Access: read-only + uint32_t fsm_active:1; //Access: read-only + uint32_t read_hold_active:1; //Access: read-only + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t cmdq_state:4; //Access: read-only + uint32_t rsvd1:4; //Access: read-as-zero + uint32_t fsm_state:6; //Access: read-only + uint32_t rsvd2:10; //Access: read-as-zero + }f; +} anc_link_status_t; + +typedef union anc_link_chip_enable_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t ce:8; //Access: read-write + uint32_t rsvd0:24; //Access: read-as-zero + }f; +} anc_link_chip_enable_t; + +typedef union anc_link_read_status_config_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t position:8; //Access: read-write + uint32_t polarity:8; //Access: read-write + uint32_t status_capture_delay:4; //Access: read-write + uint32_t ready_sample_delay:4; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + }f; +} anc_link_read_status_config_t; + +typedef union anc_link_command_address_pulse_timing_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t ca_setup_time:5; //Access: read-write + uint32_t rsvd0:3; //Access: read-as-zero + uint32_t ca_hold_time:5; //Access: read-write + uint32_t rsvd1:19; //Access: read-as-zero + }f; +} anc_link_command_address_pulse_timing_t; + +typedef union anc_link_sdr_timing_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t cle_ale_setup_time:5; //Access: read-write + uint32_t rsvd0:3; //Access: read-as-zero + uint32_t cle_ale_hold_time:5; //Access: read-write + uint32_t rsvd1:3; //Access: read-as-zero + uint32_t data_capture_delay:5; //Access: read-write + uint32_t rsvd2:11; //Access: read-as-zero + }f; +} anc_link_sdr_timing_t; + +typedef union anc_link_sdr_data_timing_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t ren_setup_time:5; //Access: read-write + uint32_t rsvd0:3; //Access: read-as-zero + uint32_t ren_hold_time:5; //Access: read-write + uint32_t rsvd1:3; //Access: read-as-zero + uint32_t wen_setup_time:5; //Access: read-write + uint32_t rsvd2:3; //Access: read-as-zero + uint32_t wen_hold_time:5; //Access: read-write + uint32_t rsvd3:3; //Access: read-as-zero + }f; +} anc_link_sdr_data_timing_t; + +typedef union anc_link_ddr_data_timing_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t ddr_pulse_width:5; //Access: read-write + uint32_t rsvd0:27; //Access: read-as-zero + }f; +} anc_link_ddr_data_timing_t; + +typedef union anc_link_ddr_read_timing_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_preamble:8; //Access: read-write + uint32_t read_postamble:8; //Access: read-write + uint32_t read_postamble_hold:8; //Access: read-write + uint32_t read_turnaround:8; //Access: read-write + }f; +} anc_link_ddr_read_timing_t; + +typedef union anc_link_ddr_write_timing_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_preamble:8; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + uint32_t write_postamble:8; //Access: read-write + uint32_t rsvd1:8; //Access: read-as-zero + }f; +} anc_link_ddr_write_timing_t; + +typedef union anc_link_dqs_timing_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_dqs_delay:6; //Access: read-write + uint32_t rsvd0:26; //Access: read-as-zero + }f; +} anc_link_dqs_timing_t; + +typedef union anc_link_cmdq_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t total:32; //Access: read-only + }f; +} anc_link_cmdq_count_t; + +typedef union anc_link_bypass_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t total:32; //Access: read-only + }f; +} anc_link_bypass_count_t; + +typedef union anc_link_cmd_timeout_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t value:31; //Access: read-write + uint32_t enable:1; //Access: read-write + }f; +} anc_link_cmd_timeout_t; + +typedef union anc_link_cmdq_int_code_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t code:16; //Access: read-only + uint32_t rsvd0:16; //Access: read-as-zero + }f; +} anc_link_cmdq_int_code_t; + +typedef union anc_link_timer_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t count:32; //Access: read-only + }f; +} anc_link_timer_t; + +typedef union anc_link_crc_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t parity_data:32; //Access: read-only + }f; +} anc_link_crc_t; + +typedef union anc_link_npl_interface_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t cle:1; //Access: read-only + uint32_t ale:1; //Access: read-only + uint32_t ren:1; //Access: read-only + uint32_t wen:1; //Access: read-only + uint32_t data_out:8; //Access: read-only + uint32_t data_out_enable:1; //Access: read-only + uint32_t write_dqs:1; //Access: read-only + uint32_t write_dqs_enable:1; //Access: read-only + uint32_t pulldown:1; //Access: read-only + uint32_t data_in:8; //Access: read-only + uint32_t rsvd0:8; //Access: read-as-zero + }f; +} anc_link_npl_interface_t; + +typedef union anc_link_macro_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t address:8; //Access: read-only + uint32_t word_count:8; //Access: read-only + uint32_t loop_count:8; //Access: read-only + uint32_t active:1; //Access: read-only + uint32_t rsvd0:7; //Access: read-as-zero + }f; +} anc_link_macro_status_t; + +typedef union anc_link_bypass_macro_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t address:8; //Access: read-only + uint32_t word_count:8; //Access: read-only + uint32_t loop_count:8; //Access: read-only + uint32_t active:1; //Access: read-only + uint32_t rsvd0:7; //Access: read-as-zero + }f; +} anc_link_bypass_macro_status_t; + +typedef union anc_link_nand_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t value:8; //Access: read-only + uint32_t rsvd0:24; //Access: read-as-zero + }f; +} anc_link_nand_status_t; + +typedef union anc_link_dlfifo_link_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_bytes:32; //Access: read-only + }f; +} anc_link_dlfifo_link_count_t; + +typedef union anc_link_dlfifo_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_bytes:32; //Access: read-only + }f; +} anc_link_dlfifo_count_t; + +typedef union anc_link_pio_link_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_bytes:32; //Access: read-only + }f; +} anc_link_pio_link_count_t; + +typedef union anc_link_pio_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_bytes:32; //Access: read-only + }f; +} anc_link_pio_count_t; + +typedef union anc_link_phy_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t write_bytes:32; //Access: read-only + }f; +} anc_link_phy_count_t; + +typedef union anc_link_phy_link_count_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t read_bytes:32; //Access: read-only + }f; +} anc_link_phy_link_count_t; + +typedef union anc_link_fsm_counts_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t data_count:16; //Access: read-only + uint32_t data_length:16; //Access: read-only + }f; +} anc_link_fsm_counts_t; + +typedef union anc_link_ecc_watermark_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t watermark:8; //Access: read-write + uint32_t watermark_enable:1; //Access: read-write + uint32_t rsvd0:23; //Access: read-as-zero + }f; +} anc_link_ecc_watermark_t; + +typedef union anc_link_ecc_config_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t max_bit_flips:8; //Access: read-write + uint32_t allowed_stuck_bits_00:8; //Access: read-write + uint32_t allowed_stuck_bits_ff:8; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + }f; +} anc_link_ecc_config_t; + + +typedef union anc_ecc_p_chien_clock_config_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t div_4_chin_clk:7; //Access: write-only + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t div_3_chin_clk:7; //Access: write-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t div_2_chin_clk:7; //Access: write-only + uint32_t rsvd2:1; //Access: read-as-zero + uint32_t dont_start_chien_config:7; //Access: write-only + uint32_t rsvd3:1; //Access: read-as-zero + }f; +} anc_ecc_p_chien_clock_config_t; + +typedef union anc_ecc_p_config_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t stop_if_all_error_found:1; //Access: write-only + uint32_t early_termination_mask:1; //Access: write-only + uint32_t rsvd1:5; //Access: read-as-zero + uint32_t chien_bma_abort:1; //Access: write-only + uint32_t rsvd2:7; //Access: read-as-zero + uint32_t synd_abort:1; //Access: write-only + uint32_t rsvd3:7; //Access: read-as-zero + uint32_t mask_int_en:1; //Access: write-only + uint32_t rsvd4:7; //Access: read-as-zero + }f; +} anc_ecc_p_config_t; + +typedef union anc_ecc_p_offset1_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t start_add_offset:13; //Access: write-only + uint32_t rsvd0:19; //Access: read-as-zero + }f; +} anc_ecc_p_offset1_t; + +typedef union anc_ecc_p_bch_direction_cnfg_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t bch_dir_add_th:13; //Access: write-only + uint32_t rsvd0:3; //Access: read-as-zero + uint32_t bch_dir_cpl1_en:3; //Access: write-only + uint32_t rsvd1:13; //Access: read-as-zero + }f; +} anc_ecc_p_bch_direction_cnfg_t; + +typedef union anc_ecc_p_page_idx_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t p_bch_dec_page:5; //Access: write-only + uint32_t rsvd0:11; //Access: read-as-zero + uint32_t p_bch_dir_rd_page1:5; //Access: write-only + uint32_t rsvd1:3; //Access: read-as-zero + uint32_t p_bch_dir_rd_page2:5; //Access: write-only + uint32_t rsvd2:3; //Access: read-as-zero + }f; +} anc_ecc_p_page_idx_t; + +typedef union anc_ecc_p_page_structure_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t t_code:8; //Access: write-only + uint32_t rsvd0:8; //Access: read-as-zero + uint32_t n_code:13; //Access: write-only + uint32_t rsvd1:3; //Access: read-as-zero + }f; +} anc_ecc_p_page_structure_t; + +typedef union anc_ecc_p_ecc_clk_cnfg_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t p_synd_force_clk_en:1; //Access: write-only + uint32_t rsvd0:7; //Access: read-as-zero + uint32_t p_bma_force_clk_en:1; //Access: write-only + uint32_t rsvd1:7; //Access: read-as-zero + uint32_t p_chien_force_clk_en:1; //Access: write-only + uint32_t rsvd2:15; //Access: read-as-zero + }f; +} anc_ecc_p_ecc_clk_cnfg_t; + +typedef union anc_ecc_p_offset3_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t p_offset3:13; //Access: write-only + uint32_t rsvd0:19; //Access: read-as-zero + }f; +} anc_ecc_p_offset3_t; + +typedef union anc_ecc_p_chien_start_offset_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t chien_start_offset:16; //Access: write-only + uint32_t rsvd0:16; //Access: read-as-zero + }f; +} anc_ecc_p_chien_start_offset_t; + +typedef union anc_ecc_p_chien_early_interrupt_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t chien_early_int_timing:13; //Access: write-only + uint32_t rsvd0:19; //Access: read-as-zero + }f; +} anc_ecc_p_chien_early_interrupt_t; + +typedef union anc_ecc_p_offset4_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t chien_last_fix_byte:13; //Access: write-only + uint32_t rsvd0:19; //Access: read-as-zero + }f; +} anc_ecc_p_offset4_t; + +typedef union anc_ecc_p_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t status:1; //Access: read-only + uint32_t rsvd0:7; //Access: read-as-zero + uint32_t number_of_found_error:7; //Access: read-only + uint32_t rsvd1:1; //Access: read-as-zero + uint32_t bch_ce:2; //Access: read-only + uint32_t rsvd2:14; //Access: read-as-zero + }f; +} anc_ecc_p_status_t; + +typedef union anc_ecc_p_bch_dir_cntrs_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t zero_to_one_cntr:7; //Access: read-only + uint32_t rsvd0:9; //Access: read-as-zero + uint32_t one_to_zero_cntr:7; //Access: read-only + uint32_t rsvd1:9; //Access: read-as-zero + }f; +} anc_ecc_p_bch_dir_cntrs_t; + +typedef union anc_ecc_p_bma_status_t { //RRV: + uint32_t all; //RRM: + struct { + uint32_t bma_degree:7; //Access: read-only + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t bma_early_termination_indication:1; //Access: read-only + uint32_t rsvd1:23; //Access: read-as-zero + }f; +} anc_ecc_p_bma_status_t; + + +/******************************************************************************/ +/* Registers typedef structs */ +/******************************************************************************/ +/* errors in perl template and spds required these to be commented out + + +typedef union anc_chan_t { + uint32_t all[192]; + struct { + anc_chan_version_t VERSION ; // 0x00000000 + anc_chan_config_t CONFIG ; // 0x00000004 + anc_chan_int_status_t INT_STATUS ; // 0x00000008 + anc_chan_int_enable_t INT_ENABLE ; // 0x0000000c + anc_chan_dma_watermarks_t DMA_WATERMARKS ; // 0x00000010 + anc_chan_link_watermarks_t LINK_WATERMARKS ; // 0x00000014 + anc_chan_status_watermarks_t STATUS_WATERMARKS ; // 0x00000018 + anc_chan_dma_cmdq_fifo_status_t DMA_CMDQ_FIFO_STATUS ; // 0x0000001c + anc_chan_link_cmdq_fifo_status_t LINK_CMDQ_FIFO_STATUS ; // 0x00000020 + anc_chan_link_bypass_fifo_status_t LINK_BYPASS_FIFO_STATUS ; // 0x00000024 + anc_chan_link_pio_read_fifo_status_t LINK_PIO_READ_FIFO_STATUS ; // 0x00000028 + anc_chan_dma_debug_fifo_status_t DMA_DEBUG_FIFO_STATUS ; // 0x0000002c + anc_chan_link_debug_fifo_status_t LINK_DEBUG_FIFO_STATUS ; // 0x00000030 + anc_chan_link_ecc_status_fifo_status_t LINK_ECC_STATUS_FIFO_STATUS ; // 0x00000034 + uint32_t rsvd0[50]; + anc_chan_dma_cmdq_fifo_t DMA_CMDQ_FIFO ; // 0x00000100 + uint32_t rsvd1[15]; + anc_chan_link_cmdq_fifo_t LINK_CMDQ_FIFO ; // 0x00000140 + uint32_t rsvd2[15]; + anc_chan_link_bypass_fifo_t LINK_BYPASS_FIFO ; // 0x00000180 + uint32_t rsvd3[15]; + anc_chan_link_pio_read_fifo_t LINK_PIO_READ_FIFO ; // 0x000001c0 + uint32_t rsvd4[15]; + anc_chan_dma_debug_fifo_t DMA_DEBUG_FIFO ; // 0x00000200 + uint32_t rsvd5[15]; + anc_chan_link_debug_fifo_t LINK_DEBUG_FIFO ; // 0x00000240 + uint32_t rsvd6[15]; + anc_chan_link_ecc_status_fifo_t LINK_ECC_STATUS_FIFO ; // 0x00000280 + }r; +} anc_chan_t; + + +typedef union anc_dma_t { + uint32_t all[192]; + struct { + anc_dma_config_t CONFIG ; // 0x00001000 + anc_dma_control_t CONTROL ; // 0x00001004 + anc_dma_status_t STATUS ; // 0x00001008 + anc_dma_aes_status_t AES_STATUS ; // 0x0000100c + anc_dma_cmdq_count_t CMDQ_COUNT ; // 0x00001010 + anc_dma_cmd_timeout_t CMD_TIMEOUT ; // 0x00001014 + anc_dma_cmdq_int_code_t CMDQ_INT_CODE ; // 0x00001018 + anc_dma_axi_t AXI ; // 0x0000101c + anc_dma_axi_next_t AXI_NEXT ; // 0x00001020 + anc_dma_axi_next_address_t AXI_NEXT_ADDRESS ; // 0x00001024 + anc_dma_axi_dma_count_t AXI_DMA_COUNT ; // 0x00001028 + anc_dma_axi_count_t DMA_AXI_COUNT ; // 0x0000102c + anc_dma_dlfifo_count_t DMA_DLFIFO_COUNT ; // 0x00001030 + anc_dma_dlfifo_dma_count_t DLFIFO_DMA_COUNT ; // 0x00001034 + anc_dma_axi_dma_last_count_t AXI_DMA_LAST_COUNT ; // 0x00001038 + anc_dma_axi_last_count_t DMA_AXI_LAST_COUNT ; // 0x0000103c + anc_dma_dlfifo_last_count_t DMA_DLFIFO_LAST_COUNT ; // 0x00001040 + anc_dma_dlfifo_dma_last_count_t DLFIFO_DMA_LAST_COUNT ; // 0x00001044 + }r; +} anc_dma_t; + + +typedef union anc_link_t { + uint32_t all[64]; + struct { + anc_link_config_t CONFIG ; // 0x00002000 + anc_link_control_t CONTROL ; // 0x00002004 + anc_link_status_t STATUS ; // 0x00002008 + anc_link_chip_enable_t CHIP_ENABLE ; // 0x0000200c + anc_link_read_status_config_t READ_STATUS_CONFIG ; // 0x00002010 + anc_link_command_address_pulse_timing_t COMMAND_ADDRESS_PULSE_TIMING ; // 0x00002014 + anc_link_sdr_timing_t SDR_TIMING ; // 0x00002018 + anc_link_sdr_data_timing_t SDR_DATA_TIMING ; // 0x0000201c + anc_link_ddr_data_timing_t DDR_DATA_TIMING ; // 0x00002020 + anc_link_ddr_read_timing_t DDR_READ_TIMING ; // 0x00002024 + anc_link_ddr_write_timing_t DDR_WRITE_TIMING ; // 0x00002028 + anc_link_dqs_timing_t DQS_TIMING ; // 0x0000202c + anc_link_cmdq_count_t CMDQ_COUNT ; // 0x00002030 + anc_link_bypass_count_t BYPASS_COUNT ; // 0x00002034 + anc_link_cmd_timeout_t CMD_TIMEOUT ; // 0x00002038 + anc_link_cmdq_int_code_t CMDQ_INT_CODE ; // 0x0000203c + anc_link_timer_t TIMER ; // 0x00002040 + anc_link_crc_t CRC ; // 0x00002044 + anc_link_npl_interface_t NPL_INTERFACE ; // 0x00002048 + anc_link_macro_status_t MACRO_STATUS ; // 0x0000204c + anc_link_bypass_macro_status_t BYPASS_MACRO_STATUS ; // 0x00002050 + anc_link_nand_status_t NAND_STATUS ; // 0x00002054 + anc_link_dlfifo_link_count_t DLFIFO_LINK_COUNT ; // 0x00002058 + anc_link_dlfifo_count_t LINK_DLFIFO_COUNT ; // 0x0000205c + anc_link_pio_link_count_t PIO_LINK_COUNT ; // 0x00002060 + anc_link_pio_count_t LINK_PIO_COUNT ; // 0x00002064 + anc_link_phy_count_t LINK_PHY_COUNT ; // 0x00002068 + anc_link_phy_link_count_t PHY_LINK_COUNT ; // 0x0000206c + anc_link_fsm_counts_t FSM_COUNTS ; // 0x00002070 + anc_link_ecc_watermark_t ECC_WATERMARK ; // 0x00002074 + anc_link_ecc_config_t ECC_CONFIG ; // 0x00002078 + }r; +} anc_link_t; + + +typedef union anc_ecc_t { + uint32_t all[64]; + struct { + anc_ecc_p_chien_clock_config_t P_CHIEN_CLOCK_CONFIG ; // 0x00002200 + uint32_t rsvd0[2]; + anc_ecc_p_config_t P_CONFIG ; // 0x0000220c + anc_ecc_p_offset1_t P_OFFSET1 ; // 0x00002210 + uint32_t rsvd1[1]; + anc_ecc_p_bch_direction_cnfg_t P_BCH_DIRECTION_CNFG ; // 0x00002218 + anc_ecc_p_page_idx_t P_PAGE_IDX ; // 0x0000221c + anc_ecc_p_page_structure_t P_PAGE_STRUCTURE ; // 0x00002220 + anc_ecc_p_ecc_clk_cnfg_t P_ECC_CLK_CNFG ; // 0x00002224 + anc_ecc_p_offset3_t P_OFFSET3 ; // 0x00002228 + anc_ecc_p_chien_start_offset_t P_CHIEN_START_OFFSET ; // 0x0000222c + anc_ecc_p_chien_early_interrupt_t P_CHIEN_EARLY_INTERRUPT ; // 0x00002230 + uint32_t rsvd2[2]; + anc_ecc_p_offset4_t P_OFFSET4 ; // 0x0000223c + uint32_t rsvd3[24]; + anc_ecc_p_status_t P_STATUS ; // 0x000022a0 + anc_ecc_p_bch_dir_cntrs_t P_BCH_DIR_CNTRS ; // 0x000022a4 + uint32_t rsvd4[3]; + anc_ecc_p_bma_status_t P_BMA_STATUS ; // 0x000022b4 + }r; +} anc_ecc_t; + + +typedef union anc_regs_s{ + struct { + anc_chan_t CHAN; // 0x00000000 + uint32_t rsvd0[832]; + anc_dma_t DMA; // 0x00001000 + uint32_t rsvd1[832]; + anc_link_t LINK; // 0x00002000 + uint32_t rsvd2[64]; + anc_ecc_t ECC; // 0x00002200 + }ab; + uint32_t all[2240]; + }; +}anc_regs_t; +*/ + +/******************************************************************************/ +/* Registers enum */ +/******************************************************************************/ +/* errors in perl template and spds required these to be commented out + + +typedef enum anc_chan_regenum { + version = 0, + config = 1, + int_status = 2, + int_enable = 3, + dma_watermarks = 4, + link_watermarks = 5, + status_watermarks = 6, + dma_cmdq_fifo_status = 7, + link_cmdq_fifo_status = 8, + link_bypass_fifo_status = 9, + link_pio_read_fifo_status = 10, + dma_debug_fifo_status = 11, + link_debug_fifo_status = 12, + link_ecc_status_fifo_status = 13, + rsvd_anc_chan_0_50 = 63, + dma_cmdq_fifo = 64, + rsvd_anc_chan_1_15 = 79, + link_cmdq_fifo = 80, + rsvd_anc_chan_2_15 = 95, + link_bypass_fifo = 96, + rsvd_anc_chan_3_15 = 111, + link_pio_read_fifo = 112, + rsvd_anc_chan_4_15 = 127, + dma_debug_fifo = 128, + rsvd_anc_chan_5_15 = 143, + link_debug_fifo = 144, + rsvd_anc_chan_6_15 = 159, + link_ecc_status_fifo = 160, +}anc_chan_regenum; + + +typedef enum anc_dma_regenum { + config = 0, + control = 1, + status = 2, + aes_status = 3, + cmdq_count = 4, + cmd_timeout = 5, + cmdq_int_code = 6, + axi = 7, + axi_next = 8, + axi_next_address = 9, + axi_dma_count = 10, + dma_axi_count = 11, + dma_dlfifo_count = 12, + dlfifo_dma_count = 13, + axi_dma_last_count = 14, + dma_axi_last_count = 15, + dma_dlfifo_last_count = 16, + dlfifo_dma_last_count = 17, +}anc_dma_regenum; + + +typedef enum anc_link_regenum { + config = 0, + control = 1, + status = 2, + chip_enable = 3, + read_status_config = 4, + command_address_pulse_timing = 5, + sdr_timing = 6, + sdr_data_timing = 7, + ddr_data_timing = 8, + ddr_read_timing = 9, + ddr_write_timing = 10, + dqs_timing = 11, + cmdq_count = 12, + bypass_count = 13, + cmd_timeout = 14, + cmdq_int_code = 15, + timer = 16, + crc = 17, + npl_interface = 18, + macro_status = 19, + bypass_macro_status = 20, + nand_status = 21, + dlfifo_link_count = 22, + link_dlfifo_count = 23, + pio_link_count = 24, + link_pio_count = 25, + link_phy_count = 26, + phy_link_count = 27, + fsm_counts = 28, + ecc_watermark = 29, + ecc_config = 30, +}anc_link_regenum; + + +typedef enum anc_ecc_regenum { + p_chien_clock_config = 0, + rsvd_anc_ecc_0_2 = 2, + p_config = 3, + p_offset1 = 4, + rsvd_anc_ecc_1_1 = 5, + p_bch_direction_cnfg = 6, + p_page_idx = 7, + p_page_structure = 8, + p_ecc_clk_cnfg = 9, + p_offset3 = 10, + p_chien_start_offset = 11, + p_chien_early_interrupt = 12, + rsvd_anc_ecc_2_2 = 14, + p_offset4 = 15, + rsvd_anc_ecc_3_24 = 39, + p_status = 40, + p_bch_dir_cntrs = 41, + rsvd_anc_ecc_4_3 = 44, + p_bma_status = 45, +}anc_ecc_regenum; + + + + + + + + + + +*/ +#endif +#endif diff --git a/drivers/apple/anc/anc_llb.c b/drivers/apple/anc/anc_llb.c new file mode 100644 index 0000000..39f2668 --- /dev/null +++ b/drivers/apple/anc/anc_llb.c @@ -0,0 +1,659 @@ + +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include "anc_bootrom.h" +#include "anc_llb.h" +#include "anc_bootrom_private.h" +#include "util_boot.h" + +anc_ppn_device_params_t *anc_geom; + +#define NUM_DIP 256UL +#define NUM_BUS 2UL + +dip_info_t dip_info[NUM_DIP]; +int anc_num_channel; // number of populated channels + +static bool anc_llb_set_normal_mode(void); +static bool anc_llb_set_feature(anc_t *anc, uint16_t feature, const uint8_t *data, uint32_t len); +static bool anc_llb_get_geometry(void); +static bool anc_llb_read_chip_ids(void); +static bool anc_llb_read_chip_id(anc_t *anc, anc_chip_id_t *chip_id); +static bool anc_llb_read_device_parameters(anc_t *anc, + anc_ppn_device_params_t *params); +static void anc_llb_handle_geb(anc_t *anc); + +int anc_llb_init(void) +{ + unsigned int dip; + unsigned int die; + unsigned int plane; + unsigned int bus; + unsigned int cau_per_die; + unsigned int numDip; + unsigned int numPlane; + unsigned int die_per_channel; + + anc_geom = memalign(NUM_BUS * sizeof(anc_ppn_device_params_t), CPU_CACHELINE_SIZE); + if (!anc_geom) panic("Unable to allocate anc_geom"); + + // Initialize ANC, but don't reset the NANDs - they're already good to go + // in low-power mode coming out of SecureROM. + if (anc_bootrom_init(false, ANC_BOOT_MODE_RESET_ALL_CONTROLLERS) != 0) + { + dprintf(DEBUG_CRITICAL, "Failed to init ANC"); + return -1; + } + + if (!anc_llb_read_chip_ids()) + { + dprintf(DEBUG_CRITICAL, "Failed to read chip IDs"); + return -1; + } + + if (!anc_llb_set_normal_mode()) + { + dprintf(DEBUG_CRITICAL, "Failed to enter normal mode"); + return -1; + } + + if (!anc_llb_get_geometry()) + { + dprintf(DEBUG_CRITICAL, "Failed to get geometry"); + return -1; + } + + if (anc_geom[0].caus_per_channel > (NUM_DIP / NUM_BUS)) + { + dprintf(DEBUG_CRITICAL, "caus_per_channel out of range: %d max %ld\n", anc_geom[0].caus_per_channel, NUM_DIP / NUM_BUS); + return -1; + } + + die_per_channel = anc_geom[0].dies_per_channel; + cau_per_die = (anc_geom[0].caus_per_channel / die_per_channel); + dip = 0; + die = 0; + bus = 0; + plane = 0; + + // PAIRING_SCHEME_TWO_BY_TWO_PAIRING + if (4 == cau_per_die && PPN_BLOCK_PAIRING__FOUR_PLANE == anc_geom[0].block_pairing_scheme) { + numDip = (anc_geom[0].caus_per_channel * anc_num_channel) / 2; + numPlane = cau_per_die / 2; + } else { // PAIRING_SCHEME_ODD_EVEN_PAIRING, PAIRING_SCHEME_NO_PAIRING + numDip = anc_geom[0].caus_per_channel * anc_num_channel; + numPlane = cau_per_die; + } + + while (dip < numDip) { + dip_info[dip].cau = plane + (die * cau_per_die); + dip_info[dip].bus = bus; + dip++; + + plane++; + + if (plane >= numPlane) { + plane = 0; + bus++; + + if ((int) bus >= anc_num_channel) { + bus = 0; + die++; + } + } + } + + if (4 == cau_per_die && PPN_BLOCK_PAIRING__FOUR_PLANE == anc_geom[0].block_pairing_scheme) { + die = 0; + bus = 0; + plane = 2; + numDip = anc_geom[0].caus_per_channel * anc_num_channel; + numPlane = cau_per_die; + + while (dip < numDip) { + dip_info[dip].cau = plane + (die * cau_per_die); + dip_info[dip].bus = bus; + dip++; + + plane++; + + if (plane >= numPlane) { + plane = 2; + bus++; + + if ((int) bus >= anc_num_channel) { + bus = 0; + die++; + } + } + } + } + + return 0; +} + +uint32_t anc_get_dip(uint32_t bus, uint32_t cau) { + uint32_t dip; + uint32_t num_dip; + + num_dip = anc_geom[0].caus_per_channel * anc_num_channel; + + for (dip = 0; dip < num_dip; dip++) { + if (cau == dip_info[dip].cau && bus == dip_info[dip].bus) { + break; + } + } + + return dip; +} + +uint32_t anc_get_dies_per_channel() { + return anc_geom[0].dies_per_channel; +} + +static bool anc_llb_set_normal_mode(void) +{ + int channel; + + for (channel = 0; channel < anc_num_channel; channel++) + { + anc_t *anc = &g_boot_anc[channel]; + uint32_t power_state = PPN_FEATURE__POWER_STATE__NORMAL_ASYNC; + + if (!anc_llb_set_feature(anc, + PPN_FEATURE__POWER_STATE, + (const uint8_t *)&power_state, + sizeof(uint32_t))) + { + return false; + } + anc_wr(anc, R_ANC_LINK_SDR_DATA_TIMING, 0x04040404); + anc_wr(anc, R_ANC_LINK_SDR_TIMING, 0x00000F0F); + anc_wr(anc, R_ANC_LINK_COMMAND_ADDRESS_PULSE_TIMING, 0x00000302); + anc_wr(anc, R_ANC_LINK_READ_STATUS_CONFIG, 0x00F04040); + } + + return true; +} + +static bool anc_llb_get_geometry(void) +{ + int channel; + + for (channel = 0; channel < anc_num_channel; channel++) + { + anc_t *anc = &g_boot_anc[channel]; + + if (!anc_llb_read_device_parameters(anc, &anc_geom[channel])) + { + return false; + } + } + return true; +} + +static bool anc_llb_read_chip_ids(void) +{ + int channel; + + anc_num_channel=0; + for (channel = 0; channel < ANC_BOOT_CONTROLLERS; channel++) + { + anc_t *anc = &g_boot_anc[channel]; + + if (!anc_llb_read_chip_id(anc, &anc->chip_id)) + { + return false; + } + else if (anc->chip_id[0]=='P' && anc->chip_id[1]=='P' && anc->chip_id[2]=='N') + { + anc_num_channel++; + } + } + return true; +} + +static bool anc_llb_read_chip_id(anc_t *anc, anc_chip_id_t *chip_id) +{ + bool ret = false; + const uint32_t int_mask = (M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG | + M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT); + uint32_t int_status; + + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__READ_ID)); + anc_boot_put_link_command(anc, LINK_COMMAND__ADDR1(CHIPID_ADDR)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_PIO(ANC_NAND_ID_SIZE, false, false)); + anc_boot_put_link_command(anc, LINK_COMMAND__SEND_INTERRUPT(0, 0)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(0)); + + int_status = anc_boot_wait_interrupt(anc, int_mask); + if (!int_status || (int_status & M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT)) + { + dprintf(DEBUG_CRITICAL, "Timeout waiting for CHAN_INT_STATUS - 0x%08x\n", int_status); + return false; + } + + if (G_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG(int_status)) + { + uint32_t id_word; + uint8_t *ptr = (uint8_t *)chip_id; + + // Chip ID is now available in Link PIO Read FIFO + id_word = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + ptr[0] = (id_word >> 0) & 0xFF; + ptr[1] = (id_word >> 8) & 0xFF; + ptr[2] = (id_word >> 16) & 0xFF; + ptr[3] = (id_word >> 24) & 0xFF; + id_word = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + ptr[4] = (id_word >> 0) & 0xFF; + ptr[5] = (id_word >> 8) & 0xFF; + + ret = true; + } + + return ret; +} + +static bool anc_llb_set_feature(anc_t *anc, + uint16_t feature, + const uint8_t *data, + uint32_t len) +{ + bool ret; + uint32_t i; + const uint32_t int_mask = (M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG | + M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE | + M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT); + uint32_t int_status; + + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__SET_FEATURES)); + anc_boot_put_link_command(anc, LINK_COMMAND__ADDR2(feature & 0xFF, + (feature & 0xFF00) >> 8)); + anc_boot_put_link_command(anc, LINK_COMMAND__WRITE_PIO(len, false, false)); + for (i = 0; i < len / sizeof(uint32_t); i++) + { + anc_boot_put_link_command(anc, data[i]); + } + + anc_boot_put_link_command(anc, LINK_COMMAND__CMD3(NAND_CMD__SET_GET_FEATURES_CONFIRM, + NAND_CMD__GET_NEXT_OPERATION_STATUS, + NAND_CMD__OPERATION_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(32)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_STATUS(0, 0x40, 0x40)); + anc_boot_put_link_command(anc, LINK_COMMAND__SEND_INTERRUPT(0, 0)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(32)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__GET_NEXT_OPERATION_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(0)); + + int_status = anc_boot_wait_interrupt(anc, int_mask); + if (!int_status || (int_status & M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT)) + { + panic("Timeout waiting for CHAN_INT_STATUS - 0x%08x\n", int_status); + return false; + } + + if (G_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG(int_status)) + { + ret = true; + } + else + { + ret = false; + } + + return ret; +} + +static bool anc_llb_read_device_parameters(anc_t *anc, + anc_ppn_device_params_t *params) +{ + const uint32_t intmask = (M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG | + M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT | + M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT | + M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE); + uint32_t intstatus; + bool ret; + uint64_t paddr = mem_static_map_physical((uintptr_t)params); + + anc_boot_put_dma_command(anc, DMA_COMMAND_CONFIG(DMA_DIRECTION_N2M, false)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__READ_DEVICE_PARAMETERS)); + anc_boot_put_link_command(anc, LINK_COMMAND__ADDR1(0x00)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD3(NAND_CMD__READ_DEVICE_PARAMETERS_CONFIRM, + NAND_CMD__GET_NEXT_OPERATION_STATUS, + NAND_CMD__OPERATION_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(32)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_STATUS(0, 0x40, 0x40)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__READ_SERIAL_OUTPUT)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(32)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_DMA(sizeof(anc_ppn_device_params_t), false, false)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__GET_NEXT_OPERATION_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(0)); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN, params, sizeof(anc_ppn_device_params_t)); +#endif + + anc_boot_put_dma_command(anc, DMA_COMMAND_BUFDESC(sizeof(anc_ppn_device_params_t), + paddr)); + + anc_boot_put_dma_command(anc, DMA_COMMAND_FLAG(0, 0)); + + intstatus = anc_boot_wait_interrupt(anc, intmask); + if (!intstatus || (intstatus & M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT)) + { + panic("Timeout waiting for CHAN_INT_STATUS - 0x%08x\n", intstatus); + return false; + } + + if (intstatus & M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT) + { + dprintf(DEBUG_CRITICAL, "Timeout waiting for DMA to complete"); + ret = false; + } + else if (intstatus & M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) + { + dprintf(DEBUG_INFO, "Unexpected NAND status\n"); + ret = false; + } + else + { + ret = true; + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, params, sizeof(anc_ppn_device_params_t)); +#endif + + return ret; +} + +static uint32_t make_physical_page(uint32_t dip, uint32_t band, uint16_t page) +{ + const unsigned int block_bits = anc_geom[0].block_bits; + const unsigned int page_bits = anc_geom[0].page_address_bits; + const unsigned int cau_bits = anc_geom[0].cau_bits; + unsigned int mode; + + if((dip_info[dip].cau == 0) && (band == 0)) { + mode = 0; + } else { + if (anc_geom[0].address_bits_bits_per_cell > 1) { + // Device supports high-endurance SLC + mode = 3; + } else { + // Device only supports regular SLC/MLC modes. Treat this high-endurance + // work as regular SLC + mode = 1; + } + } + + // LLB will always use SLC (but the PPN spec requires we not set the mode bit on CAU 0, block 0) + return (page | + (band << page_bits) | + (dip_info[dip].cau << (page_bits + block_bits)) | + (mode << (page_bits + block_bits + cau_bits))); +} + + +uint32_t anc_llb_read_phys_page(uint32_t band, // returns # of valid pages + uint32_t dip, + uint32_t page, + uint32_t num_lbas, + void *data, + uint32_t *meta) +{ + anc_t *anc = &g_boot_anc[dip_info[dip].bus]; + const uint32_t intmask = (M_ANC_CHAN_INT_STATUS_LINK_CMD_FLAG | + M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT | + M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE); + uint32_t intstatus; + unsigned int lba; + addr_t paddr; + uint32_t ret = num_lbas; + uint32_t ppage = make_physical_page(dip, band, page); + bool encrypted = false; + uint8_t nand_status; + + paddr = mem_static_map_physical((addr_t)data); + if (!paddr) + { + dprintf(DEBUG_INFO, "No buffer\n"); + return 0; + } + if (!meta) + { + dprintf(DEBUG_INFO, "No meta buffer\n"); + return 0; + } + if (num_lbas == 0) + { + dprintf(DEBUG_INFO, "Invalid num_lbas %d\n", num_lbas); + return 0; + } + + if ((platform_get_chip_id() == 0x8960) && (platform_get_chip_revision() == 0)) + { + // On Alcatraz A0, we encrypt everything but dip 0, block 0 (due to rdar://problem/11247422) + if ((dip == 0) && (band == 0)) + { + encrypted = false; + } + else + { + encrypted = true; + } + } + else + { + encrypted = false; + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, data, num_lbas * NAND_BOOT_LOGICAL_PAGE_SIZE); +#endif + + anc_boot_put_dma_command(anc, DMA_COMMAND_CONFIG(DMA_DIRECTION_N2M, encrypted)); + if (encrypted) + { + anc_boot_put_dma_command(anc, DMA_COMMAND_AES_KEY_IV(DMA_COMMAND_AESKEY_256_BITS, false)); + // Key of all zeroes + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + // IV of all zeroes + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + } + + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__MULTIPAGE_READ_LAST)); + + if (anc_geom[dip_info[dip].bus].bytes_per_row_address != 4) + { + anc_boot_put_link_command(anc, LINK_COMMAND__OPCODE(LINK_CMD_OP_ADDR3_OP) | (page & 0xFFFFFF)); + } + else + { + anc_boot_put_link_command(anc, LINK_COMMAND__OPCODE(LINK_CMD_OP_ADDR4) | (ppage & 0xFFFFFF)); + anc_boot_put_link_command(anc, (ppage & 0xFF000000) >> 24); + } + + + anc_boot_put_link_command(anc, LINK_COMMAND__CMD3(NAND_CMD__MULTIPAGE_READ_CONFIRM, + NAND_CMD__GET_NEXT_OPERATION_STATUS, + NAND_CMD__OPERATION_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(32)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_STATUS(0x00, + 0x50, + 0x40)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_REGISTER(R_ANC_LINK_NAND_STATUS - A_ANC_LINK_BASE)); + + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__READ_SERIAL_OUTPUT)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(32)); + for (lba = 0; lba < num_lbas; lba++) + { + anc_boot_put_link_command(anc, LINK_COMMAND__READ_PIO(NAND_BOOT_BYTES_PER_META, false, false)); + if (lba == (num_lbas - 1)) + { + anc_boot_put_link_command(anc, LINK_COMMAND__SEND_INTERRUPT(0, 0)); + } + anc_boot_put_link_command(anc, LINK_COMMAND__READ_DMA(NAND_BOOT_LOGICAL_PAGE_SIZE, false, false)); + if (encrypted && (lba != 0)) + { + anc_boot_put_dma_command(anc, DMA_COMMAND__OPCODE(DMA_COMMAND__OPCODE__AES_IV)); + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + anc_boot_put_dma_command(anc, 0x0000000000000000ULL); + } + anc_boot_put_dma_command(anc, DMA_COMMAND_BUFDESC(NAND_BOOT_LOGICAL_PAGE_SIZE, + (uint64_t)paddr + lba * NAND_BOOT_LOGICAL_PAGE_SIZE)); + } + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(32)); + + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__GET_NEXT_OPERATION_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(0)); + + anc_boot_put_dma_command(anc, DMA_COMMAND_FLAG(0, 0)); + + intstatus = anc_boot_wait_interrupt(anc, intmask); + if (!intstatus) + { + dprintf(DEBUG_CRITICAL, "Timeout waiting for CHAN_INT_STATUS != 0\n"); + return 0; + } + + // We've either timed out or gotten our status by now + if (intstatus & M_ANC_CHAN_INT_STATUS_LINK_CMD_TIMEOUT) + { + // Timeout waiting for status: flush LINK CmdQ and return error + dprintf(DEBUG_CRITICAL, "Timeout waiting for NAND status\n"); + anc_wr(anc, R_ANC_LINK_CONTROL, M_ANC_LINK_CONTROL_RESET_CMDQ); + return 0; + } + else if (intstatus & M_ANC_CHAN_INT_STATUS_READ_STATUS_ERR_RESPONSE) + { + uint8_t status = anc_rd(anc, R_ANC_LINK_NAND_STATUS); + // Invalid status (probably has error bit set due to a clean or uncorrectable page) + if (BOOT_LBA_TOKEN_UNKNOWN != meta[0]) // scanning blocks - may be clean or uecc + { + dprintf(DEBUG_CRITICAL, "Invalid NAND status 0x%02X\n", status); + } + anc_wr(anc, R_ANC_LINK_CONTROL, M_ANC_LINK_CONTROL_START); + ret = 0; + meta[0] = BOOT_ERR_BLANK; + } + + nand_status = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + if (nand_status != 0x40) + { + if (BOOT_LBA_TOKEN_UNKNOWN != meta[0]) // scanning blocks - may be clean or uecc + { + dprintf(DEBUG_CRITICAL, "Invalid NAND status: 0x%02X\n", nand_status); + } + ret = 0; + meta[0] = BOOT_ERR_BLANK; + } + + for (lba = 0; lba < num_lbas; lba++) + { + uint32_t meta_index; + for (meta_index = 0; meta_index < (NAND_BOOT_BYTES_PER_META / sizeof(uint32_t)); meta_index++) + { + uint32_t meta_word = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + if ((meta_index == 0) && (meta_word != meta[0])) + { + if (BOOT_LBA_TOKEN_UNKNOWN == meta[0]) + { + meta[0] = meta_word; + } + else if (BOOT_ERR_BLANK != meta[0]) + { + if (lba==0) { + dprintf(DEBUG_CRITICAL, "Invalid meta: expected 0x%08X got 0x%08x\n", meta[0], meta_word); + } + ret = lba; + } + } + } + } + + intstatus = anc_boot_wait_interrupt(anc, M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG | M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT); + if (!intstatus || (intstatus & M_ANC_CHAN_INT_STATUS_DMA_CMD_TIMEOUT)) + { + dprintf(DEBUG_CRITICAL, "Timeout waiting for DMA to complete - 0x%08x\n", intstatus); + ret = 0; + } + + anc_wr(anc, R_ANC_CHAN_INT_STATUS, M_ANC_CHAN_INT_STATUS_DMA_CMD_FLAG); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, data, num_lbas * NAND_BOOT_LOGICAL_PAGE_SIZE); +#endif + + return ret; +} + +typedef struct +{ + uint16_t failure_type; + uint32_t start_page; + uint8_t page_len[3]; + uint8_t checksum; +} anc_ppn_failure_info_t; + + +static void anc_llb_handle_geb(anc_t *anc) +{ + uint32_t buffer[3]; + dprintf(DEBUG_CRITICAL, "General Error Dected on Bus %d, attempting to pull failure info", anc->bus_id); + + anc_wr(anc, R_ANC_CHAN_INT_ENABLE, 0); + anc_wr(anc, R_ANC_DMA_CONTROL, V_ANC_DMA_CONTROL_RESET(1) | V_ANC_DMA_CONTROL_START(1)); + anc_wr(anc, R_ANC_LINK_CONTROL, (V_ANC_LINK_CONTROL_RESET_CMDQ(1) | + V_ANC_LINK_CONTROL_RESET_PIO_READ(1) | + V_ANC_LINK_CONTROL_START(1))); + + anc_boot_put_link_command(anc, LINK_COMMAND__CE(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__GET_DEBUG_DATA)); + anc_boot_put_link_command(anc, LINK_COMMAND__ADDR3(0xFF, 0xFF, 0xFF)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__SET_GET_FEATURES_CONFIRM)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(129000)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__OPERATION_STATUS)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_STATUS(0, 0x40, 0x40)); + anc_boot_put_link_command(anc, LINK_COMMAND__CMD1(NAND_CMD__READ_SERIAL_OUTPUT)); + anc_boot_put_link_command(anc, LINK_COMMAND__WAIT_TIME(1)); + anc_boot_put_link_command(anc, LINK_COMMAND__READ_PIO(10, false, false)); + anc_boot_put_link_command(anc, LINK_COMMAND__CE(0)); + + while (G_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS_LEVEL(anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO_STATUS)) < 3) + { + ; + } + + buffer[0] = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + buffer[1] = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + buffer[2] = anc_rd(anc, R_ANC_CHAN_LINK_PIO_READ_FIFO); + + panic("GEB detected failure type 0x%04X start page 0x%08X", + ((anc_ppn_failure_info_t *)buffer)->failure_type, ((anc_ppn_failure_info_t *)buffer)->start_page); +} + + diff --git a/drivers/apple/anc/anc_llb.h b/drivers/apple/anc/anc_llb.h new file mode 100644 index 0000000..4c4bfb9 --- /dev/null +++ b/drivers/apple/anc/anc_llb.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef ANC_LLB_H +#define ANC_LLB_H + +typedef struct dip_info_t +{ + uint32_t cau; + uint32_t bus; +} dip_info_t; + +typedef struct _anc_ppn_device_params_t +{ + char header[16]; + uint32_t caus_per_channel; + uint32_t cau_bits; + uint32_t blocks_per_cau; + uint32_t block_bits; + uint32_t pages_per_block; + uint32_t pages_per_block_slc; + uint32_t page_address_bits; + uint32_t address_bits_bits_per_cell; + uint32_t default_bits_per_cell; + uint32_t page_size; + uint32_t dies_per_channel; + uint32_t block_pairing_scheme; + uint32_t bytes_per_row_address; + uint8_t reserved[92]; + uint8_t tRC; + uint8_t tREA; + uint8_t tREH; + uint8_t tRHOH; + uint8_t tRHZ; + uint8_t tRLOH; + uint8_t tRP; + uint8_t reserved2; + uint8_t tWC; + uint8_t tWH; + uint8_t tWP; + uint8_t reserved3[53]; + uint32_t read_queue_size; + uint32_t program_queue_size; + uint32_t erase_queue_size; + uint32_t prep_function_buffer_size; + uint32_t tRST; + uint32_t tPURST; + uint32_t tSCE; + uint32_t tCERDY; + uint8_t reserved4[256]; +} anc_ppn_device_params_t; + +int anc_llb_init(void); +uint32_t anc_get_dip(uint32_t bus, uint32_t cau); +uint32_t anc_get_dies_per_channel(); +uint32_t anc_llb_read_phys_page(uint32_t band, + uint32_t dip, + uint32_t page, + uint32_t num_lbas, + void *data, + uint32_t *meta); + + +#endif // ANC_LLB_H + diff --git a/drivers/apple/anc/ppn_npl_regs.h b/drivers/apple/anc/ppn_npl_regs.h new file mode 100644 index 0000000..4ce25b1 --- /dev/null +++ b/drivers/apple/anc/ppn_npl_regs.h @@ -0,0 +1,1528 @@ + +// +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form +// in whole or in part, without the express written permission of +// Apple Inc. +// +#ifndef __PPNNPL_H__ +#define __PPNNPL_H__ + +/******************************************************************************/ +/* Addresses */ +/******************************************************************************/ +#define A_PPNNPL_BASE 0x00000000 +#define A_PPNNPL_REG(REG) (REG) + +/******************************************************************************/ +/* Registers */ +/******************************************************************************/ +#define R_PPNNPL_VERSION 0x00000000 +#define RRV_PPNNPL_VERSION 0x00000000 +#define RRM_PPNNPL_VERSION 0x00000000 +#define R_PPNNPL_CONFIG 0x00000004 +#define RRV_PPNNPL_CONFIG 0x00000000 +#define RRM_PPNNPL_CONFIG 0x00000000 +#define R_PPNNPL_DQS_TIMING 0x00000008 +#define RRV_PPNNPL_DQS_TIMING 0x003f003f +#define RRM_PPNNPL_DQS_TIMING 0x00000000 +#define R_PPNNPL_DLL_CODES 0x0000000c +#define RRV_PPNNPL_DLL_CODES 0x00000000 +#define RRM_PPNNPL_DLL_CODES 0x00000000 +#define R_PPNNPL_DQS_ADJUST 0x00000010 +#define RRV_PPNNPL_DQS_ADJUST 0x00400040 +#define RRM_PPNNPL_DQS_ADJUST 0x00000000 +#define R_PPNNPL_AMPMCDLL_CONTROL 0x00000014 +#define RRV_PPNNPL_AMPMCDLL_CONTROL 0x00000000 +#define RRM_PPNNPL_AMPMCDLL_CONTROL 0x00000000 +#define R_PPNNPL_AMPSLV_CONTROL 0x00000018 +#define RRV_PPNNPL_AMPSLV_CONTROL 0x00000000 +#define RRM_PPNNPL_AMPSLV_CONTROL 0x00000000 +#define R_PPNNPL_AMPDLL_STATUS 0x0000001c +#define RRV_PPNNPL_AMPDLL_STATUS 0x00000000 +#define RRM_PPNNPL_AMPDLL_STATUS 0x00000000 +#define R_PPNNPL_ANC0_AMPSLV0 0x00000020 +#define RRV_PPNNPL_ANC0_AMPSLV0 0x00000000 +#define RRM_PPNNPL_ANC0_AMPSLV0 0x00000000 +#define R_PPNNPL_ANC0_AMPSLV1 0x00000024 +#define RRV_PPNNPL_ANC0_AMPSLV1 0x00000000 +#define RRM_PPNNPL_ANC0_AMPSLV1 0x00000000 +#define R_PPNNPL_ANC1_AMPSLV0 0x00000028 +#define RRV_PPNNPL_ANC1_AMPSLV0 0x00000000 +#define RRM_PPNNPL_ANC1_AMPSLV0 0x00000000 +#define R_PPNNPL_ANC1_AMPSLV1 0x0000002c +#define RRV_PPNNPL_ANC1_AMPSLV1 0x00000000 +#define RRM_PPNNPL_ANC1_AMPSLV1 0x00000000 +#define R_PPNNPL_TRAIN_CONTROL 0x00000030 +#define RRV_PPNNPL_TRAIN_CONTROL 0x00000000 +#define RRM_PPNNPL_TRAIN_CONTROL 0x00000000 +#define R_PPNNPL_PERIODIC_TRAINING 0x00000034 +#define RRV_PPNNPL_PERIODIC_TRAINING 0x00000000 +#define RRM_PPNNPL_PERIODIC_TRAINING 0x00000000 +#define R_PPNNPL_DEBUG_DLL_CONTROL 0x00000038 +#define RRV_PPNNPL_DEBUG_DLL_CONTROL 0x4c000034 +#define RRM_PPNNPL_DEBUG_DLL_CONTROL 0x00000000 +#define R_PPNNPL_DEBUG_DATA_CAPTURE 0x0000003c +#define RRV_PPNNPL_DEBUG_DATA_CAPTURE 0x00000000 +#define RRM_PPNNPL_DEBUG_DATA_CAPTURE 0x00000000 +#define R_PPNNPL_PPN0_CLE 0x00000040 +#define RRV_PPNNPL_PPN0_CLE 0x00000000 +#define RRM_PPNNPL_PPN0_CLE 0x00000000 +#define R_PPNNPL_PPN0_ALE 0x00000044 +#define RRV_PPNNPL_PPN0_ALE 0x00000000 +#define RRM_PPNNPL_PPN0_ALE 0x00000000 +#define R_PPNNPL_PPN0_REN 0x00000048 +#define RRV_PPNNPL_PPN0_REN 0x00000000 +#define RRM_PPNNPL_PPN0_REN 0x00000000 +#define R_PPNNPL_PPN0_WEN 0x0000004c +#define RRV_PPNNPL_PPN0_WEN 0x00000000 +#define RRM_PPNNPL_PPN0_WEN 0x00000000 +#define R_PPNNPL_PPN0_CEN 0x00000050 +#define RRV_PPNNPL_PPN0_CEN 0x00000000 +#define RRM_PPNNPL_PPN0_CEN 0x00000000 +#define R_PPNNPL_PPN0_DQS 0x00000054 +#define RRV_PPNNPL_PPN0_DQS 0x00000000 +#define RRM_PPNNPL_PPN0_DQS 0x00000000 +#define R_PPNNPL_PPN0_IO 0x00000058 +#define RRV_PPNNPL_PPN0_IO 0x00000000 +#define RRM_PPNNPL_PPN0_IO 0x00000000 +#define R_PPNNPL_PPN0_ZQ 0x0000005c +#define RRV_PPNNPL_PPN0_ZQ 0x00000000 +#define RRM_PPNNPL_PPN0_ZQ 0x00000000 +#define R_PPNNPL_PPN0_DS 0x00000060 +#define RRV_PPNNPL_PPN0_DS 0x00000000 +#define RRM_PPNNPL_PPN0_DS 0x00000000 +#define R_PPNNPL_PPN0_INPUT_SELECT 0x00000064 +#define RRV_PPNNPL_PPN0_INPUT_SELECT 0x00000000 +#define RRM_PPNNPL_PPN0_INPUT_SELECT 0x00000000 +#define R_PPNNPL_PPN1_CLE 0x00000068 +#define RRV_PPNNPL_PPN1_CLE 0x00000000 +#define RRM_PPNNPL_PPN1_CLE 0x00000000 +#define R_PPNNPL_PPN1_ALE 0x0000006c +#define RRV_PPNNPL_PPN1_ALE 0x00000000 +#define RRM_PPNNPL_PPN1_ALE 0x00000000 +#define R_PPNNPL_PPN1_REN 0x00000070 +#define RRV_PPNNPL_PPN1_REN 0x00000000 +#define RRM_PPNNPL_PPN1_REN 0x00000000 +#define R_PPNNPL_PPN1_WEN 0x00000074 +#define RRV_PPNNPL_PPN1_WEN 0x00000000 +#define RRM_PPNNPL_PPN1_WEN 0x00000000 +#define R_PPNNPL_PPN1_CEN 0x00000078 +#define RRV_PPNNPL_PPN1_CEN 0x00000000 +#define RRM_PPNNPL_PPN1_CEN 0x00000000 +#define R_PPNNPL_PPN1_DQS 0x0000007c +#define RRV_PPNNPL_PPN1_DQS 0x00000000 +#define RRM_PPNNPL_PPN1_DQS 0x00000000 +#define R_PPNNPL_PPN1_IO 0x00000080 +#define RRV_PPNNPL_PPN1_IO 0x00000000 +#define RRM_PPNNPL_PPN1_IO 0x00000000 +#define R_PPNNPL_PPN1_ZQ 0x00000084 +#define RRV_PPNNPL_PPN1_ZQ 0x00000000 +#define RRM_PPNNPL_PPN1_ZQ 0x00000000 +#define R_PPNNPL_PPN1_DS 0x00000088 +#define RRV_PPNNPL_PPN1_DS 0x00000000 +#define RRM_PPNNPL_PPN1_DS 0x00000000 +#define R_PPNNPL_PPN1_INPUT_SELECT 0x0000008c +#define RRV_PPNNPL_PPN1_INPUT_SELECT 0x00000000 +#define RRM_PPNNPL_PPN1_INPUT_SELECT 0x00000000 +#define R_PPNNPL_LAST 0x0000008c + +/******************************************************************************/ +/* Registers2 */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ +#define rPPNNPL_VERSION +#define rPPNNPL_CONFIG +#define rPPNNPL_DQS_TIMING +#define rPPNNPL_DLL_CODES +#define rPPNNPL_DQS_ADJUST +#define rPPNNPL_AMPMCDLL_CONTROL +#define rPPNNPL_AMPSLV_CONTROL +#define rPPNNPL_AMPDLL_STATUS +#define rPPNNPL_ANC0_AMPSLV0 +#define rPPNNPL_ANC0_AMPSLV1 +#define rPPNNPL_ANC1_AMPSLV0 +#define rPPNNPL_ANC1_AMPSLV1 +#define rPPNNPL_TRAIN_CONTROL +#define rPPNNPL_PERIODIC_TRAINING +#define rPPNNPL_DEBUG_DLL_CONTROL +#define rPPNNPL_DEBUG_DATA_CAPTURE +#define rPPNNPL_PPN0_CLE +#define rPPNNPL_PPN0_ALE +#define rPPNNPL_PPN0_REN +#define rPPNNPL_PPN0_WEN +#define rPPNNPL_PPN0_CEN +#define rPPNNPL_PPN0_DQS +#define rPPNNPL_PPN0_IO +#define rPPNNPL_PPN0_ZQ +#define rPPNNPL_PPN0_ZQ_IN +#define rPPNNPL_PPN0_ZCPD +#define rPPNNPL_PPN0_ZCPU +#define rPPNNPL_PPN0_DS +#define rPPNNPL_PPN0_INPUT_SELECT +#define rPPNNPL_PPN1_CLE +#define rPPNNPL_PPN1_ALE +#define rPPNNPL_PPN1_REN +#define rPPNNPL_PPN1_WEN +#define rPPNNPL_PPN1_CEN +#define rPPNNPL_PPN1_DQS +#define rPPNNPL_PPN1_IO +#define rPPNNPL_PPN1_ZQ +#define rPPNNPL_PPN1_ZQ_IN +#define rPPNNPL_PPN1_ZCPD +#define rPPNNPL_PPN1_ZCPU +#define rPPNNPL_PPN1_DS +#define rPPNNPL_PPN1_INPUT_SELECT +#define rPPNNPL_LAST +#endif + +/******************************************************************************/ +/* Register Fields defines */ +/******************************************************************************/ +#define S_PPNNPL_VERSION_REVISION 0 //Access: read-only +#define M_PPNNPL_VERSION_REVISION _MM_MAKEMASK(16,S_PPNNPL_VERSION_REVISION) +#define V_PPNNPL_VERSION_REVISION(V) _MM_MAKEVALUE((V),S_PPNNPL_VERSION_REVISION) +#define G_PPNNPL_VERSION_REVISION(V) _MM_GETVALUE((V),S_PPNNPL_VERSION_REVISION,M_PPNNPL_VERSION_REVISION) + +#define S_PPNNPL_VERSION_VERSION 16 //Access: read-only +#define M_PPNNPL_VERSION_VERSION _MM_MAKEMASK(16,S_PPNNPL_VERSION_VERSION) +#define V_PPNNPL_VERSION_VERSION(V) _MM_MAKEVALUE((V),S_PPNNPL_VERSION_VERSION) +#define G_PPNNPL_VERSION_VERSION(V) _MM_GETVALUE((V),S_PPNNPL_VERSION_VERSION,M_PPNNPL_VERSION_VERSION) + + +#define S_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN 0 //Access: read-write +#define M_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN _MM_MAKEMASK(1,S_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN) +#define V_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN(V) _MM_MAKEVALUE((V),S_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN) +#define G_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN(V) _MM_GETVALUE((V),S_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN,M_PPNNPL_CONFIG_AUTO_DISABLE_DQS_PULLDOWN) + +#define S_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN 1 //Access: read-write +#define M_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN _MM_MAKEMASK(1,S_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN) +#define V_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN(V) _MM_MAKEVALUE((V),S_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN) +#define G_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN(V) _MM_GETVALUE((V),S_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN,M_PPNNPL_CONFIG_AUTO_DISABLE_IO_PULLDOWN) + +#define S_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE 0 //Access: read-write +#define M_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE _MM_MAKEMASK(9,S_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE) +#define V_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE) +#define G_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE,M_PPNNPL_DQS_TIMING_ANC0_DEFAULT_DELAY_CODE) + +#define S_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE 9 //Access: read-write +#define M_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE _MM_MAKEMASK(1,S_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE) +#define V_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE) +#define G_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE,M_PPNNPL_DQS_TIMING_ANC0_USE_DEFAULT_DELAY_CODE) + +#define S_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT 10 //Access: read-write +#define M_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT _MM_MAKEMASK(1,S_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT) +#define V_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT) +#define G_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT,M_PPNNPL_DQS_TIMING_ANC0_DLL_SELECT) + +#define S_PPNNPL_DQS_TIMING_RSVD0 11 //Access: read-as-zero +#define M_PPNNPL_DQS_TIMING_RSVD0 _MM_MAKEMASK(5,S_PPNNPL_DQS_TIMING_RSVD0) +#define V_PPNNPL_DQS_TIMING_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_RSVD0) +#define G_PPNNPL_DQS_TIMING_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_RSVD0,M_PPNNPL_DQS_TIMING_RSVD0) + +#define S_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE 16 //Access: read-write +#define M_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE _MM_MAKEMASK(9,S_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE) +#define V_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE) +#define G_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE,M_PPNNPL_DQS_TIMING_ANC1_DEFAULT_DELAY_CODE) + +#define S_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE 25 //Access: read-write +#define M_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE _MM_MAKEMASK(1,S_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE) +#define V_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE) +#define G_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE,M_PPNNPL_DQS_TIMING_ANC1_USE_DEFAULT_DELAY_CODE) + +#define S_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT 26 //Access: read-write +#define M_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT _MM_MAKEMASK(1,S_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT) +#define V_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT) +#define G_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT,M_PPNNPL_DQS_TIMING_ANC1_DLL_SELECT) + +#define S_PPNNPL_DQS_TIMING_RSVD1 27 //Access: read-as-zero +#define M_PPNNPL_DQS_TIMING_RSVD1 _MM_MAKEMASK(5,S_PPNNPL_DQS_TIMING_RSVD1) +#define V_PPNNPL_DQS_TIMING_RSVD1(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_TIMING_RSVD1) +#define G_PPNNPL_DQS_TIMING_RSVD1(V) _MM_GETVALUE((V),S_PPNNPL_DQS_TIMING_RSVD1,M_PPNNPL_DQS_TIMING_RSVD1) + + +#define S_PPNNPL_DLL_CODES_MASTER_DELAY_OUT 0 //Access: read-only +#define M_PPNNPL_DLL_CODES_MASTER_DELAY_OUT _MM_MAKEMASK(7,S_PPNNPL_DLL_CODES_MASTER_DELAY_OUT) +#define V_PPNNPL_DLL_CODES_MASTER_DELAY_OUT(V) _MM_MAKEVALUE((V),S_PPNNPL_DLL_CODES_MASTER_DELAY_OUT) +#define G_PPNNPL_DLL_CODES_MASTER_DELAY_OUT(V) _MM_GETVALUE((V),S_PPNNPL_DLL_CODES_MASTER_DELAY_OUT,M_PPNNPL_DLL_CODES_MASTER_DELAY_OUT) + +#define S_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN 7 //Access: read-only +#define M_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN _MM_MAKEMASK(9,S_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN) +#define V_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN(V) _MM_MAKEVALUE((V),S_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN) +#define G_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN(V) _MM_GETVALUE((V),S_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN,M_PPNNPL_DLL_CODES_SLAVE0_DELAY_CODE_IN) + +#define S_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN 16 //Access: read-only +#define M_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN _MM_MAKEMASK(9,S_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN) +#define V_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN(V) _MM_MAKEVALUE((V),S_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN) +#define G_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN(V) _MM_GETVALUE((V),S_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN,M_PPNNPL_DLL_CODES_SLAVE1_DELAY_CODE_IN) + +#define S_PPNNPL_DLL_CODES_RSVD0 25 //Access: read-as-zero +#define M_PPNNPL_DLL_CODES_RSVD0 _MM_MAKEMASK(7,S_PPNNPL_DLL_CODES_RSVD0) +#define V_PPNNPL_DLL_CODES_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_DLL_CODES_RSVD0) +#define G_PPNNPL_DLL_CODES_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_DLL_CODES_RSVD0,M_PPNNPL_DLL_CODES_RSVD0) + + +#define S_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO 0 //Access: read-write +#define M_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO _MM_MAKEMASK(8,S_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO) +#define V_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO) +#define G_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO(V) _MM_GETVALUE((V),S_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO,M_PPNNPL_DQS_ADJUST_ANC0_FREQUENCY_RATIO) + +#define S_PPNNPL_DQS_ADJUST_ANC0_OFFSET 8 //Access: read-write +#define M_PPNNPL_DQS_ADJUST_ANC0_OFFSET _MM_MAKEMASK(7,S_PPNNPL_DQS_ADJUST_ANC0_OFFSET) +#define V_PPNNPL_DQS_ADJUST_ANC0_OFFSET(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_ADJUST_ANC0_OFFSET) +#define G_PPNNPL_DQS_ADJUST_ANC0_OFFSET(V) _MM_GETVALUE((V),S_PPNNPL_DQS_ADJUST_ANC0_OFFSET,M_PPNNPL_DQS_ADJUST_ANC0_OFFSET) + +#define S_PPNNPL_DQS_ADJUST_RSVD0 15 //Access: read-as-zero +#define M_PPNNPL_DQS_ADJUST_RSVD0 _MM_MAKEMASK(1,S_PPNNPL_DQS_ADJUST_RSVD0) +#define V_PPNNPL_DQS_ADJUST_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_ADJUST_RSVD0) +#define G_PPNNPL_DQS_ADJUST_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_DQS_ADJUST_RSVD0,M_PPNNPL_DQS_ADJUST_RSVD0) + +#define S_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO 16 //Access: read-write +#define M_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO _MM_MAKEMASK(8,S_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO) +#define V_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO) +#define G_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO(V) _MM_GETVALUE((V),S_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO,M_PPNNPL_DQS_ADJUST_ANC1_FREQUENCY_RATIO) + +#define S_PPNNPL_DQS_ADJUST_ANC1_OFFSET 24 //Access: read-write +#define M_PPNNPL_DQS_ADJUST_ANC1_OFFSET _MM_MAKEMASK(7,S_PPNNPL_DQS_ADJUST_ANC1_OFFSET) +#define V_PPNNPL_DQS_ADJUST_ANC1_OFFSET(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_ADJUST_ANC1_OFFSET) +#define G_PPNNPL_DQS_ADJUST_ANC1_OFFSET(V) _MM_GETVALUE((V),S_PPNNPL_DQS_ADJUST_ANC1_OFFSET,M_PPNNPL_DQS_ADJUST_ANC1_OFFSET) + +#define S_PPNNPL_DQS_ADJUST_RSVD1 31 //Access: read-as-zero +#define M_PPNNPL_DQS_ADJUST_RSVD1 _MM_MAKEMASK(1,S_PPNNPL_DQS_ADJUST_RSVD1) +#define V_PPNNPL_DQS_ADJUST_RSVD1(V) _MM_MAKEVALUE((V),S_PPNNPL_DQS_ADJUST_RSVD1) +#define G_PPNNPL_DQS_ADJUST_RSVD1(V) _MM_GETVALUE((V),S_PPNNPL_DQS_ADJUST_RSVD1,M_PPNNPL_DQS_ADJUST_RSVD1) + + +#define S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN 0 //Access: read-write +#define M_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN _MM_MAKEMASK(1,S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN) +#define V_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN) +#define G_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN(V) _MM_GETVALUE((V),S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN,M_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_IN) + +#define S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL 1 //Access: read-write +#define M_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL _MM_MAKEMASK(1,S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL) +#define V_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL) +#define G_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL(V) _MM_GETVALUE((V),S_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL,M_PPNNPL_AMPMCDLL_CONTROL_STEPSIZE_SEL) + +#define S_PPNNPL_AMPMCDLL_CONTROL_RSVD0 2 //Access: read-as-zero +#define M_PPNNPL_AMPMCDLL_CONTROL_RSVD0 _MM_MAKEMASK(30,S_PPNNPL_AMPMCDLL_CONTROL_RSVD0) +#define V_PPNNPL_AMPMCDLL_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPMCDLL_CONTROL_RSVD0) +#define G_PPNNPL_AMPMCDLL_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_AMPMCDLL_CONTROL_RSVD0,M_PPNNPL_AMPMCDLL_CONTROL_RSVD0) + + +#define S_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE 0 //Access: read-write +#define M_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE _MM_MAKEMASK(2,S_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE) +#define V_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE) +#define G_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE(V) _MM_GETVALUE((V),S_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE,M_PPNNPL_AMPSLV_CONTROL_ANC0_BYPASS_MODE) + +#define S_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE 2 //Access: read-write +#define M_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE _MM_MAKEMASK(2,S_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE) +#define V_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE) +#define G_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE(V) _MM_GETVALUE((V),S_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE,M_PPNNPL_AMPSLV_CONTROL_ANC1_BYPASS_MODE) + +#define S_PPNNPL_AMPSLV_CONTROL_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_AMPSLV_CONTROL_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_AMPSLV_CONTROL_RSVD0) +#define V_PPNNPL_AMPSLV_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPSLV_CONTROL_RSVD0) +#define G_PPNNPL_AMPSLV_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_AMPSLV_CONTROL_RSVD0,M_PPNNPL_AMPSLV_CONTROL_RSVD0) + + +#define S_PPNNPL_AMPDLL_STATUS_DLL_LOCKED 0 //Access: read-only +#define M_PPNNPL_AMPDLL_STATUS_DLL_LOCKED _MM_MAKEMASK(1,S_PPNNPL_AMPDLL_STATUS_DLL_LOCKED) +#define V_PPNNPL_AMPDLL_STATUS_DLL_LOCKED(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPDLL_STATUS_DLL_LOCKED) +#define G_PPNNPL_AMPDLL_STATUS_DLL_LOCKED(V) _MM_GETVALUE((V),S_PPNNPL_AMPDLL_STATUS_DLL_LOCKED,M_PPNNPL_AMPDLL_STATUS_DLL_LOCKED) + +#define S_PPNNPL_AMPDLL_STATUS_RSVD0 1 //Access: read-as-zero +#define M_PPNNPL_AMPDLL_STATUS_RSVD0 _MM_MAKEMASK(31,S_PPNNPL_AMPDLL_STATUS_RSVD0) +#define V_PPNNPL_AMPDLL_STATUS_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_AMPDLL_STATUS_RSVD0) +#define G_PPNNPL_AMPDLL_STATUS_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_AMPDLL_STATUS_RSVD0,M_PPNNPL_AMPDLL_STATUS_RSVD0) + + +#define S_PPNNPL_ANC0_AMPSLV0_SLV_SEL 0 //Access: read-only +#define M_PPNNPL_ANC0_AMPSLV0_SLV_SEL _MM_MAKEMASK(12,S_PPNNPL_ANC0_AMPSLV0_SLV_SEL) +#define V_PPNNPL_ANC0_AMPSLV0_SLV_SEL(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC0_AMPSLV0_SLV_SEL) +#define G_PPNNPL_ANC0_AMPSLV0_SLV_SEL(V) _MM_GETVALUE((V),S_PPNNPL_ANC0_AMPSLV0_SLV_SEL,M_PPNNPL_ANC0_AMPSLV0_SLV_SEL) + +#define S_PPNNPL_ANC0_AMPSLV0_RSVD0 12 //Access: read-as-zero +#define M_PPNNPL_ANC0_AMPSLV0_RSVD0 _MM_MAKEMASK(20,S_PPNNPL_ANC0_AMPSLV0_RSVD0) +#define V_PPNNPL_ANC0_AMPSLV0_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC0_AMPSLV0_RSVD0) +#define G_PPNNPL_ANC0_AMPSLV0_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_ANC0_AMPSLV0_RSVD0,M_PPNNPL_ANC0_AMPSLV0_RSVD0) + + +#define S_PPNNPL_ANC0_AMPSLV1_SLV_SEL 0 //Access: read-only +#define M_PPNNPL_ANC0_AMPSLV1_SLV_SEL _MM_MAKEMASK(12,S_PPNNPL_ANC0_AMPSLV1_SLV_SEL) +#define V_PPNNPL_ANC0_AMPSLV1_SLV_SEL(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC0_AMPSLV1_SLV_SEL) +#define G_PPNNPL_ANC0_AMPSLV1_SLV_SEL(V) _MM_GETVALUE((V),S_PPNNPL_ANC0_AMPSLV1_SLV_SEL,M_PPNNPL_ANC0_AMPSLV1_SLV_SEL) + +#define S_PPNNPL_ANC0_AMPSLV1_RSVD0 12 //Access: read-as-zero +#define M_PPNNPL_ANC0_AMPSLV1_RSVD0 _MM_MAKEMASK(20,S_PPNNPL_ANC0_AMPSLV1_RSVD0) +#define V_PPNNPL_ANC0_AMPSLV1_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC0_AMPSLV1_RSVD0) +#define G_PPNNPL_ANC0_AMPSLV1_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_ANC0_AMPSLV1_RSVD0,M_PPNNPL_ANC0_AMPSLV1_RSVD0) + + +#define S_PPNNPL_ANC1_AMPSLV0_SLV_SEL 0 //Access: read-only +#define M_PPNNPL_ANC1_AMPSLV0_SLV_SEL _MM_MAKEMASK(12,S_PPNNPL_ANC1_AMPSLV0_SLV_SEL) +#define V_PPNNPL_ANC1_AMPSLV0_SLV_SEL(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC1_AMPSLV0_SLV_SEL) +#define G_PPNNPL_ANC1_AMPSLV0_SLV_SEL(V) _MM_GETVALUE((V),S_PPNNPL_ANC1_AMPSLV0_SLV_SEL,M_PPNNPL_ANC1_AMPSLV0_SLV_SEL) + +#define S_PPNNPL_ANC1_AMPSLV0_RSVD0 12 //Access: read-as-zero +#define M_PPNNPL_ANC1_AMPSLV0_RSVD0 _MM_MAKEMASK(20,S_PPNNPL_ANC1_AMPSLV0_RSVD0) +#define V_PPNNPL_ANC1_AMPSLV0_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC1_AMPSLV0_RSVD0) +#define G_PPNNPL_ANC1_AMPSLV0_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_ANC1_AMPSLV0_RSVD0,M_PPNNPL_ANC1_AMPSLV0_RSVD0) + + +#define S_PPNNPL_ANC1_AMPSLV1_SLV_SEL 0 //Access: read-only +#define M_PPNNPL_ANC1_AMPSLV1_SLV_SEL _MM_MAKEMASK(12,S_PPNNPL_ANC1_AMPSLV1_SLV_SEL) +#define V_PPNNPL_ANC1_AMPSLV1_SLV_SEL(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC1_AMPSLV1_SLV_SEL) +#define G_PPNNPL_ANC1_AMPSLV1_SLV_SEL(V) _MM_GETVALUE((V),S_PPNNPL_ANC1_AMPSLV1_SLV_SEL,M_PPNNPL_ANC1_AMPSLV1_SLV_SEL) + +#define S_PPNNPL_ANC1_AMPSLV1_RSVD0 12 //Access: read-as-zero +#define M_PPNNPL_ANC1_AMPSLV1_RSVD0 _MM_MAKEMASK(20,S_PPNNPL_ANC1_AMPSLV1_RSVD0) +#define V_PPNNPL_ANC1_AMPSLV1_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_ANC1_AMPSLV1_RSVD0) +#define G_PPNNPL_ANC1_AMPSLV1_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_ANC1_AMPSLV1_RSVD0,M_PPNNPL_ANC1_AMPSLV1_RSVD0) + + +#define S_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING 0 //Access: read-write +#define M_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING _MM_MAKEMASK(1,S_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING) +#define V_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING(V) _MM_MAKEVALUE((V),S_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING) +#define G_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING(V) _MM_GETVALUE((V),S_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING,M_PPNNPL_TRAIN_CONTROL_DISABLE_CONTINUOUS_TRAINING) + +#define S_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY 1 //Access: read-write +#define M_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY _MM_MAKEMASK(1,S_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY) +#define V_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY(V) _MM_MAKEVALUE((V),S_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY) +#define G_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY(V) _MM_GETVALUE((V),S_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY,M_PPNNPL_TRAIN_CONTROL_TRAIN_PERIODICALLY) + +#define S_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE 2 //Access: write-auto-clear +#define M_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE _MM_MAKEMASK(1,S_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE) +#define V_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE(V) _MM_MAKEVALUE((V),S_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE) +#define G_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE(V) _MM_GETVALUE((V),S_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE,M_PPNNPL_TRAIN_CONTROL_TRAIN_ONCE) + +#define S_PPNNPL_TRAIN_CONTROL_RSVD0 3 //Access: read-as-zero +#define M_PPNNPL_TRAIN_CONTROL_RSVD0 _MM_MAKEMASK(29,S_PPNNPL_TRAIN_CONTROL_RSVD0) +#define V_PPNNPL_TRAIN_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_TRAIN_CONTROL_RSVD0) +#define G_PPNNPL_TRAIN_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_TRAIN_CONTROL_RSVD0,M_PPNNPL_TRAIN_CONTROL_RSVD0) + + +#define S_PPNNPL_PERIODIC_TRAINING_DELAY 0 //Access: read-write +#define M_PPNNPL_PERIODIC_TRAINING_DELAY _MM_MAKEMASK(32,S_PPNNPL_PERIODIC_TRAINING_DELAY) +#define V_PPNNPL_PERIODIC_TRAINING_DELAY(V) _MM_MAKEVALUE((V),S_PPNNPL_PERIODIC_TRAINING_DELAY) +#define G_PPNNPL_PERIODIC_TRAINING_DELAY(V) _MM_GETVALUE((V),S_PPNNPL_PERIODIC_TRAINING_DELAY,M_PPNNPL_PERIODIC_TRAINING_DELAY) + + +#define S_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY 0 //Access: read-write +#define M_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY _MM_MAKEMASK(3,S_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY) +#define V_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY) +#define G_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY,M_PPNNPL_DEBUG_DLL_CONTROL_START_DELAY) + +#define S_PPNNPL_DEBUG_DLL_CONTROL_RSVD0 3 //Access: read-as-zero +#define M_PPNNPL_DEBUG_DLL_CONTROL_RSVD0 _MM_MAKEMASK(1,S_PPNNPL_DEBUG_DLL_CONTROL_RSVD0) +#define V_PPNNPL_DEBUG_DLL_CONTROL_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_RSVD0) +#define G_PPNNPL_DEBUG_DLL_CONTROL_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_RSVD0,M_PPNNPL_DEBUG_DLL_CONTROL_RSVD0) + +#define S_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE 4 //Access: read-write +#define M_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE _MM_MAKEMASK(3,S_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE) +#define V_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE) +#define G_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE,M_PPNNPL_DEBUG_DLL_CONTROL_STEP_SIZE) + +#define S_PPNNPL_DEBUG_DLL_CONTROL_RSVD1 7 //Access: read-as-zero +#define M_PPNNPL_DEBUG_DLL_CONTROL_RSVD1 _MM_MAKEMASK(9,S_PPNNPL_DEBUG_DLL_CONTROL_RSVD1) +#define V_PPNNPL_DEBUG_DLL_CONTROL_RSVD1(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_RSVD1) +#define G_PPNNPL_DEBUG_DLL_CONTROL_RSVD1(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_RSVD1,M_PPNNPL_DEBUG_DLL_CONTROL_RSVD1) + +#define S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN 16 //Access: read-write +#define M_PPNNPL_DEBUG_DLL_CONTROL_TRAIN _MM_MAKEMASK(1,S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN) +#define V_PPNNPL_DEBUG_DLL_CONTROL_TRAIN(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN) +#define G_PPNNPL_DEBUG_DLL_CONTROL_TRAIN(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN,M_PPNNPL_DEBUG_DLL_CONTROL_TRAIN) + +#define S_PPNNPL_DEBUG_DLL_CONTROL_RSVD2 17 //Access: read-as-zero +#define M_PPNNPL_DEBUG_DLL_CONTROL_RSVD2 _MM_MAKEMASK(7,S_PPNNPL_DEBUG_DLL_CONTROL_RSVD2) +#define V_PPNNPL_DEBUG_DLL_CONTROL_RSVD2(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_RSVD2) +#define G_PPNNPL_DEBUG_DLL_CONTROL_RSVD2(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_RSVD2,M_PPNNPL_DEBUG_DLL_CONTROL_RSVD2) + +#define S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY 24 //Access: read-write +#define M_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY _MM_MAKEMASK(4,S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY) +#define V_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY) +#define G_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY,M_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PREPARE_DELAY) + +#define S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY 28 //Access: read-write +#define M_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY _MM_MAKEMASK(4,S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY) +#define V_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY) +#define G_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY,M_PPNNPL_DEBUG_DLL_CONTROL_TRAIN_PAUSE_DELAY) + + +#define S_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA 0 //Access: read-only +#define M_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA _MM_MAKEMASK(8,S_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA) +#define V_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA) +#define G_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA,M_PPNNPL_DEBUG_DATA_CAPTURE_ANC0_POSEDGE_DATA) + +#define S_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA 8 //Access: read-only +#define M_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA _MM_MAKEMASK(8,S_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA) +#define V_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA) +#define G_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA,M_PPNNPL_DEBUG_DATA_CAPTURE_ANC1_POSEDGE_DATA) + +#define S_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0 16 //Access: read-as-zero +#define M_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0 _MM_MAKEMASK(16,S_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0) +#define V_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0) +#define G_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0,M_PPNNPL_DEBUG_DATA_CAPTURE_RSVD0) + + +#define S_PPNNPL_PPN0_CLE_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN0_CLE_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_CLE_INPUT_ENABLE) +#define V_PPNNPL_PPN0_CLE_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CLE_INPUT_ENABLE) +#define G_PPNNPL_PPN0_CLE_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CLE_INPUT_ENABLE,M_PPNNPL_PPN0_CLE_INPUT_ENABLE) + +#define S_PPNNPL_PPN0_CLE_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN0_CLE_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_CLE_OUTPUT_ENABLE) +#define V_PPNNPL_PPN0_CLE_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CLE_OUTPUT_ENABLE) +#define G_PPNNPL_PPN0_CLE_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CLE_OUTPUT_ENABLE,M_PPNNPL_PPN0_CLE_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN0_CLE_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN0_CLE_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_CLE_PULL_ENABLE) +#define V_PPNNPL_PPN0_CLE_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CLE_PULL_ENABLE) +#define G_PPNNPL_PPN0_CLE_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CLE_PULL_ENABLE,M_PPNNPL_PPN0_CLE_PULL_ENABLE) + +#define S_PPNNPL_PPN0_CLE_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN0_CLE_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN0_CLE_PULL_SELECT) +#define V_PPNNPL_PPN0_CLE_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CLE_PULL_SELECT) +#define G_PPNNPL_PPN0_CLE_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CLE_PULL_SELECT,M_PPNNPL_PPN0_CLE_PULL_SELECT) + +#define S_PPNNPL_PPN0_CLE_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_CLE_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN0_CLE_RSVD0) +#define V_PPNNPL_PPN0_CLE_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CLE_RSVD0) +#define G_PPNNPL_PPN0_CLE_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CLE_RSVD0,M_PPNNPL_PPN0_CLE_RSVD0) + + +#define S_PPNNPL_PPN0_ALE_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN0_ALE_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_ALE_INPUT_ENABLE) +#define V_PPNNPL_PPN0_ALE_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ALE_INPUT_ENABLE) +#define G_PPNNPL_PPN0_ALE_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ALE_INPUT_ENABLE,M_PPNNPL_PPN0_ALE_INPUT_ENABLE) + +#define S_PPNNPL_PPN0_ALE_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN0_ALE_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_ALE_OUTPUT_ENABLE) +#define V_PPNNPL_PPN0_ALE_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ALE_OUTPUT_ENABLE) +#define G_PPNNPL_PPN0_ALE_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ALE_OUTPUT_ENABLE,M_PPNNPL_PPN0_ALE_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN0_ALE_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN0_ALE_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_ALE_PULL_ENABLE) +#define V_PPNNPL_PPN0_ALE_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ALE_PULL_ENABLE) +#define G_PPNNPL_PPN0_ALE_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ALE_PULL_ENABLE,M_PPNNPL_PPN0_ALE_PULL_ENABLE) + +#define S_PPNNPL_PPN0_ALE_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN0_ALE_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN0_ALE_PULL_SELECT) +#define V_PPNNPL_PPN0_ALE_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ALE_PULL_SELECT) +#define G_PPNNPL_PPN0_ALE_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ALE_PULL_SELECT,M_PPNNPL_PPN0_ALE_PULL_SELECT) + +#define S_PPNNPL_PPN0_ALE_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_ALE_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN0_ALE_RSVD0) +#define V_PPNNPL_PPN0_ALE_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ALE_RSVD0) +#define G_PPNNPL_PPN0_ALE_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ALE_RSVD0,M_PPNNPL_PPN0_ALE_RSVD0) + + +#define S_PPNNPL_PPN0_REN_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN0_REN_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_REN_INPUT_ENABLE) +#define V_PPNNPL_PPN0_REN_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_REN_INPUT_ENABLE) +#define G_PPNNPL_PPN0_REN_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_REN_INPUT_ENABLE,M_PPNNPL_PPN0_REN_INPUT_ENABLE) + +#define S_PPNNPL_PPN0_REN_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN0_REN_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_REN_OUTPUT_ENABLE) +#define V_PPNNPL_PPN0_REN_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_REN_OUTPUT_ENABLE) +#define G_PPNNPL_PPN0_REN_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_REN_OUTPUT_ENABLE,M_PPNNPL_PPN0_REN_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN0_REN_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN0_REN_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_REN_PULL_ENABLE) +#define V_PPNNPL_PPN0_REN_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_REN_PULL_ENABLE) +#define G_PPNNPL_PPN0_REN_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_REN_PULL_ENABLE,M_PPNNPL_PPN0_REN_PULL_ENABLE) + +#define S_PPNNPL_PPN0_REN_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN0_REN_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN0_REN_PULL_SELECT) +#define V_PPNNPL_PPN0_REN_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_REN_PULL_SELECT) +#define G_PPNNPL_PPN0_REN_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_REN_PULL_SELECT,M_PPNNPL_PPN0_REN_PULL_SELECT) + +#define S_PPNNPL_PPN0_REN_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_REN_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN0_REN_RSVD0) +#define V_PPNNPL_PPN0_REN_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_REN_RSVD0) +#define G_PPNNPL_PPN0_REN_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_REN_RSVD0,M_PPNNPL_PPN0_REN_RSVD0) + + +#define S_PPNNPL_PPN0_WEN_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN0_WEN_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_WEN_INPUT_ENABLE) +#define V_PPNNPL_PPN0_WEN_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_WEN_INPUT_ENABLE) +#define G_PPNNPL_PPN0_WEN_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_WEN_INPUT_ENABLE,M_PPNNPL_PPN0_WEN_INPUT_ENABLE) + +#define S_PPNNPL_PPN0_WEN_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN0_WEN_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_WEN_OUTPUT_ENABLE) +#define V_PPNNPL_PPN0_WEN_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_WEN_OUTPUT_ENABLE) +#define G_PPNNPL_PPN0_WEN_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_WEN_OUTPUT_ENABLE,M_PPNNPL_PPN0_WEN_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN0_WEN_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN0_WEN_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_WEN_PULL_ENABLE) +#define V_PPNNPL_PPN0_WEN_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_WEN_PULL_ENABLE) +#define G_PPNNPL_PPN0_WEN_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_WEN_PULL_ENABLE,M_PPNNPL_PPN0_WEN_PULL_ENABLE) + +#define S_PPNNPL_PPN0_WEN_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN0_WEN_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN0_WEN_PULL_SELECT) +#define V_PPNNPL_PPN0_WEN_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_WEN_PULL_SELECT) +#define G_PPNNPL_PPN0_WEN_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_WEN_PULL_SELECT,M_PPNNPL_PPN0_WEN_PULL_SELECT) + +#define S_PPNNPL_PPN0_WEN_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_WEN_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN0_WEN_RSVD0) +#define V_PPNNPL_PPN0_WEN_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_WEN_RSVD0) +#define G_PPNNPL_PPN0_WEN_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_WEN_RSVD0,M_PPNNPL_PPN0_WEN_RSVD0) + + +#define S_PPNNPL_PPN0_CEN_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN0_CEN_INPUT_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN0_CEN_INPUT_ENABLE) +#define V_PPNNPL_PPN0_CEN_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CEN_INPUT_ENABLE) +#define G_PPNNPL_PPN0_CEN_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CEN_INPUT_ENABLE,M_PPNNPL_PPN0_CEN_INPUT_ENABLE) + +#define S_PPNNPL_PPN0_CEN_OUTPUT_ENABLE 8 //Access: read-write +#define M_PPNNPL_PPN0_CEN_OUTPUT_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN0_CEN_OUTPUT_ENABLE) +#define V_PPNNPL_PPN0_CEN_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CEN_OUTPUT_ENABLE) +#define G_PPNNPL_PPN0_CEN_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CEN_OUTPUT_ENABLE,M_PPNNPL_PPN0_CEN_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN0_CEN_PULL_ENABLE 16 //Access: read-write +#define M_PPNNPL_PPN0_CEN_PULL_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN0_CEN_PULL_ENABLE) +#define V_PPNNPL_PPN0_CEN_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CEN_PULL_ENABLE) +#define G_PPNNPL_PPN0_CEN_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CEN_PULL_ENABLE,M_PPNNPL_PPN0_CEN_PULL_ENABLE) + +#define S_PPNNPL_PPN0_CEN_PULL_SELECT 24 //Access: read-write +#define M_PPNNPL_PPN0_CEN_PULL_SELECT _MM_MAKEMASK(8,S_PPNNPL_PPN0_CEN_PULL_SELECT) +#define V_PPNNPL_PPN0_CEN_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_CEN_PULL_SELECT) +#define G_PPNNPL_PPN0_CEN_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_CEN_PULL_SELECT,M_PPNNPL_PPN0_CEN_PULL_SELECT) + + +#define S_PPNNPL_PPN0_DQS_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN0_DQS_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_DQS_INPUT_ENABLE) +#define V_PPNNPL_PPN0_DQS_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_DQS_INPUT_ENABLE) +#define G_PPNNPL_PPN0_DQS_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_DQS_INPUT_ENABLE,M_PPNNPL_PPN0_DQS_INPUT_ENABLE) + +#define S_PPNNPL_PPN0_DQS_RSVD0 1 //Access: read-as-zero +#define M_PPNNPL_PPN0_DQS_RSVD0 _MM_MAKEMASK(1,S_PPNNPL_PPN0_DQS_RSVD0) +#define V_PPNNPL_PPN0_DQS_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_DQS_RSVD0) +#define G_PPNNPL_PPN0_DQS_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_DQS_RSVD0,M_PPNNPL_PPN0_DQS_RSVD0) + +#define S_PPNNPL_PPN0_DQS_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN0_DQS_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN0_DQS_PULL_ENABLE) +#define V_PPNNPL_PPN0_DQS_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_DQS_PULL_ENABLE) +#define G_PPNNPL_PPN0_DQS_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_DQS_PULL_ENABLE,M_PPNNPL_PPN0_DQS_PULL_ENABLE) + +#define S_PPNNPL_PPN0_DQS_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN0_DQS_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN0_DQS_PULL_SELECT) +#define V_PPNNPL_PPN0_DQS_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_DQS_PULL_SELECT) +#define G_PPNNPL_PPN0_DQS_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_DQS_PULL_SELECT,M_PPNNPL_PPN0_DQS_PULL_SELECT) + +#define S_PPNNPL_PPN0_DQS_RSVD1 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_DQS_RSVD1 _MM_MAKEMASK(28,S_PPNNPL_PPN0_DQS_RSVD1) +#define V_PPNNPL_PPN0_DQS_RSVD1(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_DQS_RSVD1) +#define G_PPNNPL_PPN0_DQS_RSVD1(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_DQS_RSVD1,M_PPNNPL_PPN0_DQS_RSVD1) + + +#define S_PPNNPL_PPN0_IO_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN0_IO_INPUT_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN0_IO_INPUT_ENABLE) +#define V_PPNNPL_PPN0_IO_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_IO_INPUT_ENABLE) +#define G_PPNNPL_PPN0_IO_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_IO_INPUT_ENABLE,M_PPNNPL_PPN0_IO_INPUT_ENABLE) + +#define S_PPNNPL_PPN0_IO_RSVD0 8 //Access: read-as-zero +#define M_PPNNPL_PPN0_IO_RSVD0 _MM_MAKEMASK(8,S_PPNNPL_PPN0_IO_RSVD0) +#define V_PPNNPL_PPN0_IO_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_IO_RSVD0) +#define G_PPNNPL_PPN0_IO_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_IO_RSVD0,M_PPNNPL_PPN0_IO_RSVD0) + +#define S_PPNNPL_PPN0_IO_PULL_ENABLE 16 //Access: read-write +#define M_PPNNPL_PPN0_IO_PULL_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN0_IO_PULL_ENABLE) +#define V_PPNNPL_PPN0_IO_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_IO_PULL_ENABLE) +#define G_PPNNPL_PPN0_IO_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_IO_PULL_ENABLE,M_PPNNPL_PPN0_IO_PULL_ENABLE) + +#define S_PPNNPL_PPN0_IO_PULL_SELECT 24 //Access: read-write +#define M_PPNNPL_PPN0_IO_PULL_SELECT _MM_MAKEMASK(8,S_PPNNPL_PPN0_IO_PULL_SELECT) +#define V_PPNNPL_PPN0_IO_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_IO_PULL_SELECT) +#define G_PPNNPL_PPN0_IO_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_IO_PULL_SELECT,M_PPNNPL_PPN0_IO_PULL_SELECT) + + +#define S_PPNNPL_PPN0_ZQ_OEPD 0 //Access: read-write +#define M_PPNNPL_PPN0_ZQ_OEPD _MM_MAKEMASK(1,S_PPNNPL_PPN0_ZQ_OEPD) +#define V_PPNNPL_PPN0_ZQ_OEPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_OEPD) +#define G_PPNNPL_PPN0_ZQ_OEPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_OEPD,M_PPNNPL_PPN0_ZQ_OEPD) + +#define S_PPNNPL_PPN0_ZQ_OEPU 1 //Access: read-write +#define M_PPNNPL_PPN0_ZQ_OEPU _MM_MAKEMASK(1,S_PPNNPL_PPN0_ZQ_OEPU) +#define V_PPNNPL_PPN0_ZQ_OEPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_OEPU) +#define G_PPNNPL_PPN0_ZQ_OEPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_OEPU,M_PPNNPL_PPN0_ZQ_OEPU) + +#define S_PPNNPL_PPN0_ZQ_ZCPD 2 //Access: read-write +#define M_PPNNPL_PPN0_ZQ_ZCPD _MM_MAKEMASK(4,S_PPNNPL_PPN0_ZQ_ZCPD) +#define V_PPNNPL_PPN0_ZQ_ZCPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_ZCPD) +#define G_PPNNPL_PPN0_ZQ_ZCPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_ZCPD,M_PPNNPL_PPN0_ZQ_ZCPD) + +#define S_PPNNPL_PPN0_ZQ_ZCPU 6 //Access: read-write +#define M_PPNNPL_PPN0_ZQ_ZCPU _MM_MAKEMASK(4,S_PPNNPL_PPN0_ZQ_ZCPU) +#define V_PPNNPL_PPN0_ZQ_ZCPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_ZCPU) +#define G_PPNNPL_PPN0_ZQ_ZCPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_ZCPU,M_PPNNPL_PPN0_ZQ_ZCPU) + +#define S_PPNNPL_PPN0_ZQ_RSVD0 10 //Access: read-as-zero +#define M_PPNNPL_PPN0_ZQ_RSVD0 _MM_MAKEMASK(22,S_PPNNPL_PPN0_ZQ_RSVD0) +#define V_PPNNPL_PPN0_ZQ_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_RSVD0) +#define G_PPNNPL_PPN0_ZQ_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_RSVD0,M_PPNNPL_PPN0_ZQ_RSVD0) + + +#define S_PPNNPL_PPN0_ZQ_IN_YPD 0 //Access: read-only +#define M_PPNNPL_PPN0_ZQ_IN_YPD _MM_MAKEMASK(1,S_PPNNPL_PPN0_ZQ_IN_YPD) +#define V_PPNNPL_PPN0_ZQ_IN_YPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_IN_YPD) +#define G_PPNNPL_PPN0_ZQ_IN_YPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_IN_YPD,M_PPNNPL_PPN0_ZQ_IN_YPD) + +#define S_PPNNPL_PPN0_ZQ_IN_YPU 1 //Access: read-only +#define M_PPNNPL_PPN0_ZQ_IN_YPU _MM_MAKEMASK(1,S_PPNNPL_PPN0_ZQ_IN_YPU) +#define V_PPNNPL_PPN0_ZQ_IN_YPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_IN_YPU) +#define G_PPNNPL_PPN0_ZQ_IN_YPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_IN_YPU,M_PPNNPL_PPN0_ZQ_IN_YPU) + +#define S_PPNNPL_PPN0_ZQ_IN_RSVD0 2 //Access: read-as-zero +#define M_PPNNPL_PPN0_ZQ_IN_RSVD0 _MM_MAKEMASK(30,S_PPNNPL_PPN0_ZQ_IN_RSVD0) +#define V_PPNNPL_PPN0_ZQ_IN_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZQ_IN_RSVD0) +#define G_PPNNPL_PPN0_ZQ_IN_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZQ_IN_RSVD0,M_PPNNPL_PPN0_ZQ_IN_RSVD0) + + +#define S_PPNNPL_PPN0_ZCPD_ZCPD 0 //Access: read-write +#define M_PPNNPL_PPN0_ZCPD_ZCPD _MM_MAKEMASK(4,S_PPNNPL_PPN0_ZCPD_ZCPD) +#define V_PPNNPL_PPN0_ZCPD_ZCPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZCPD_ZCPD) +#define G_PPNNPL_PPN0_ZCPD_ZCPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZCPD_ZCPD,M_PPNNPL_PPN0_ZCPD_ZCPD) + +#define S_PPNNPL_PPN0_ZCPD_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_ZCPD_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN0_ZCPD_RSVD0) +#define V_PPNNPL_PPN0_ZCPD_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZCPD_RSVD0) +#define G_PPNNPL_PPN0_ZCPD_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZCPD_RSVD0,M_PPNNPL_PPN0_ZCPD_RSVD0) + + +#define S_PPNNPL_PPN0_ZCPU_ZCPU 0 //Access: read-write +#define M_PPNNPL_PPN0_ZCPU_ZCPU _MM_MAKEMASK(4,S_PPNNPL_PPN0_ZCPU_ZCPU) +#define V_PPNNPL_PPN0_ZCPU_ZCPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZCPU_ZCPU) +#define G_PPNNPL_PPN0_ZCPU_ZCPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZCPU_ZCPU,M_PPNNPL_PPN0_ZCPU_ZCPU) + +#define S_PPNNPL_PPN0_ZCPU_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_ZCPU_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN0_ZCPU_RSVD0) +#define V_PPNNPL_PPN0_ZCPU_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_ZCPU_RSVD0) +#define G_PPNNPL_PPN0_ZCPU_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_ZCPU_RSVD0,M_PPNNPL_PPN0_ZCPU_RSVD0) + + +#define S_PPNNPL_PPN0_DS_DRIVE_STRENGTH 0 //Access: read-write +#define M_PPNNPL_PPN0_DS_DRIVE_STRENGTH _MM_MAKEMASK(4,S_PPNNPL_PPN0_DS_DRIVE_STRENGTH) +#define V_PPNNPL_PPN0_DS_DRIVE_STRENGTH(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_DS_DRIVE_STRENGTH) +#define G_PPNNPL_PPN0_DS_DRIVE_STRENGTH(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_DS_DRIVE_STRENGTH,M_PPNNPL_PPN0_DS_DRIVE_STRENGTH) + +#define S_PPNNPL_PPN0_DS_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN0_DS_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN0_DS_RSVD0) +#define V_PPNNPL_PPN0_DS_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_DS_RSVD0) +#define G_PPNNPL_PPN0_DS_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_DS_RSVD0,M_PPNNPL_PPN0_DS_RSVD0) + + +#define S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT 0 //Access: read-write +#define M_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT) +#define V_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT) +#define G_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT,M_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT) + +#define S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT 1 //Access: read-write +#define M_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT _MM_MAKEMASK(1,S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT) +#define V_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT) +#define G_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT,M_PPNNPL_PPN0_INPUT_SELECT_INPUT_SELECT_SCHMITT) + +#define S_PPNNPL_PPN0_INPUT_SELECT_RSVD0 2 //Access: read-as-zero +#define M_PPNNPL_PPN0_INPUT_SELECT_RSVD0 _MM_MAKEMASK(30,S_PPNNPL_PPN0_INPUT_SELECT_RSVD0) +#define V_PPNNPL_PPN0_INPUT_SELECT_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN0_INPUT_SELECT_RSVD0) +#define G_PPNNPL_PPN0_INPUT_SELECT_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN0_INPUT_SELECT_RSVD0,M_PPNNPL_PPN0_INPUT_SELECT_RSVD0) + + +#define S_PPNNPL_PPN1_CLE_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN1_CLE_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_CLE_INPUT_ENABLE) +#define V_PPNNPL_PPN1_CLE_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CLE_INPUT_ENABLE) +#define G_PPNNPL_PPN1_CLE_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CLE_INPUT_ENABLE,M_PPNNPL_PPN1_CLE_INPUT_ENABLE) + +#define S_PPNNPL_PPN1_CLE_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN1_CLE_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_CLE_OUTPUT_ENABLE) +#define V_PPNNPL_PPN1_CLE_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CLE_OUTPUT_ENABLE) +#define G_PPNNPL_PPN1_CLE_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CLE_OUTPUT_ENABLE,M_PPNNPL_PPN1_CLE_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN1_CLE_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN1_CLE_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_CLE_PULL_ENABLE) +#define V_PPNNPL_PPN1_CLE_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CLE_PULL_ENABLE) +#define G_PPNNPL_PPN1_CLE_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CLE_PULL_ENABLE,M_PPNNPL_PPN1_CLE_PULL_ENABLE) + +#define S_PPNNPL_PPN1_CLE_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN1_CLE_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN1_CLE_PULL_SELECT) +#define V_PPNNPL_PPN1_CLE_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CLE_PULL_SELECT) +#define G_PPNNPL_PPN1_CLE_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CLE_PULL_SELECT,M_PPNNPL_PPN1_CLE_PULL_SELECT) + +#define S_PPNNPL_PPN1_CLE_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_CLE_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN1_CLE_RSVD0) +#define V_PPNNPL_PPN1_CLE_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CLE_RSVD0) +#define G_PPNNPL_PPN1_CLE_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CLE_RSVD0,M_PPNNPL_PPN1_CLE_RSVD0) + + +#define S_PPNNPL_PPN1_ALE_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN1_ALE_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_ALE_INPUT_ENABLE) +#define V_PPNNPL_PPN1_ALE_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ALE_INPUT_ENABLE) +#define G_PPNNPL_PPN1_ALE_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ALE_INPUT_ENABLE,M_PPNNPL_PPN1_ALE_INPUT_ENABLE) + +#define S_PPNNPL_PPN1_ALE_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN1_ALE_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_ALE_OUTPUT_ENABLE) +#define V_PPNNPL_PPN1_ALE_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ALE_OUTPUT_ENABLE) +#define G_PPNNPL_PPN1_ALE_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ALE_OUTPUT_ENABLE,M_PPNNPL_PPN1_ALE_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN1_ALE_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN1_ALE_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_ALE_PULL_ENABLE) +#define V_PPNNPL_PPN1_ALE_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ALE_PULL_ENABLE) +#define G_PPNNPL_PPN1_ALE_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ALE_PULL_ENABLE,M_PPNNPL_PPN1_ALE_PULL_ENABLE) + +#define S_PPNNPL_PPN1_ALE_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN1_ALE_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN1_ALE_PULL_SELECT) +#define V_PPNNPL_PPN1_ALE_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ALE_PULL_SELECT) +#define G_PPNNPL_PPN1_ALE_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ALE_PULL_SELECT,M_PPNNPL_PPN1_ALE_PULL_SELECT) + +#define S_PPNNPL_PPN1_ALE_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_ALE_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN1_ALE_RSVD0) +#define V_PPNNPL_PPN1_ALE_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ALE_RSVD0) +#define G_PPNNPL_PPN1_ALE_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ALE_RSVD0,M_PPNNPL_PPN1_ALE_RSVD0) + + +#define S_PPNNPL_PPN1_REN_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN1_REN_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_REN_INPUT_ENABLE) +#define V_PPNNPL_PPN1_REN_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_REN_INPUT_ENABLE) +#define G_PPNNPL_PPN1_REN_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_REN_INPUT_ENABLE,M_PPNNPL_PPN1_REN_INPUT_ENABLE) + +#define S_PPNNPL_PPN1_REN_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN1_REN_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_REN_OUTPUT_ENABLE) +#define V_PPNNPL_PPN1_REN_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_REN_OUTPUT_ENABLE) +#define G_PPNNPL_PPN1_REN_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_REN_OUTPUT_ENABLE,M_PPNNPL_PPN1_REN_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN1_REN_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN1_REN_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_REN_PULL_ENABLE) +#define V_PPNNPL_PPN1_REN_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_REN_PULL_ENABLE) +#define G_PPNNPL_PPN1_REN_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_REN_PULL_ENABLE,M_PPNNPL_PPN1_REN_PULL_ENABLE) + +#define S_PPNNPL_PPN1_REN_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN1_REN_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN1_REN_PULL_SELECT) +#define V_PPNNPL_PPN1_REN_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_REN_PULL_SELECT) +#define G_PPNNPL_PPN1_REN_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_REN_PULL_SELECT,M_PPNNPL_PPN1_REN_PULL_SELECT) + +#define S_PPNNPL_PPN1_REN_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_REN_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN1_REN_RSVD0) +#define V_PPNNPL_PPN1_REN_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_REN_RSVD0) +#define G_PPNNPL_PPN1_REN_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_REN_RSVD0,M_PPNNPL_PPN1_REN_RSVD0) + + +#define S_PPNNPL_PPN1_WEN_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN1_WEN_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_WEN_INPUT_ENABLE) +#define V_PPNNPL_PPN1_WEN_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_WEN_INPUT_ENABLE) +#define G_PPNNPL_PPN1_WEN_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_WEN_INPUT_ENABLE,M_PPNNPL_PPN1_WEN_INPUT_ENABLE) + +#define S_PPNNPL_PPN1_WEN_OUTPUT_ENABLE 1 //Access: read-write +#define M_PPNNPL_PPN1_WEN_OUTPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_WEN_OUTPUT_ENABLE) +#define V_PPNNPL_PPN1_WEN_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_WEN_OUTPUT_ENABLE) +#define G_PPNNPL_PPN1_WEN_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_WEN_OUTPUT_ENABLE,M_PPNNPL_PPN1_WEN_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN1_WEN_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN1_WEN_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_WEN_PULL_ENABLE) +#define V_PPNNPL_PPN1_WEN_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_WEN_PULL_ENABLE) +#define G_PPNNPL_PPN1_WEN_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_WEN_PULL_ENABLE,M_PPNNPL_PPN1_WEN_PULL_ENABLE) + +#define S_PPNNPL_PPN1_WEN_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN1_WEN_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN1_WEN_PULL_SELECT) +#define V_PPNNPL_PPN1_WEN_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_WEN_PULL_SELECT) +#define G_PPNNPL_PPN1_WEN_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_WEN_PULL_SELECT,M_PPNNPL_PPN1_WEN_PULL_SELECT) + +#define S_PPNNPL_PPN1_WEN_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_WEN_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN1_WEN_RSVD0) +#define V_PPNNPL_PPN1_WEN_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_WEN_RSVD0) +#define G_PPNNPL_PPN1_WEN_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_WEN_RSVD0,M_PPNNPL_PPN1_WEN_RSVD0) + + +#define S_PPNNPL_PPN1_CEN_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN1_CEN_INPUT_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN1_CEN_INPUT_ENABLE) +#define V_PPNNPL_PPN1_CEN_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CEN_INPUT_ENABLE) +#define G_PPNNPL_PPN1_CEN_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CEN_INPUT_ENABLE,M_PPNNPL_PPN1_CEN_INPUT_ENABLE) + +#define S_PPNNPL_PPN1_CEN_OUTPUT_ENABLE 8 //Access: read-write +#define M_PPNNPL_PPN1_CEN_OUTPUT_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN1_CEN_OUTPUT_ENABLE) +#define V_PPNNPL_PPN1_CEN_OUTPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CEN_OUTPUT_ENABLE) +#define G_PPNNPL_PPN1_CEN_OUTPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CEN_OUTPUT_ENABLE,M_PPNNPL_PPN1_CEN_OUTPUT_ENABLE) + +#define S_PPNNPL_PPN1_CEN_PULL_ENABLE 16 //Access: read-write +#define M_PPNNPL_PPN1_CEN_PULL_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN1_CEN_PULL_ENABLE) +#define V_PPNNPL_PPN1_CEN_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CEN_PULL_ENABLE) +#define G_PPNNPL_PPN1_CEN_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CEN_PULL_ENABLE,M_PPNNPL_PPN1_CEN_PULL_ENABLE) + +#define S_PPNNPL_PPN1_CEN_PULL_SELECT 24 //Access: read-write +#define M_PPNNPL_PPN1_CEN_PULL_SELECT _MM_MAKEMASK(8,S_PPNNPL_PPN1_CEN_PULL_SELECT) +#define V_PPNNPL_PPN1_CEN_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_CEN_PULL_SELECT) +#define G_PPNNPL_PPN1_CEN_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_CEN_PULL_SELECT,M_PPNNPL_PPN1_CEN_PULL_SELECT) + + +#define S_PPNNPL_PPN1_DQS_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN1_DQS_INPUT_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_DQS_INPUT_ENABLE) +#define V_PPNNPL_PPN1_DQS_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_DQS_INPUT_ENABLE) +#define G_PPNNPL_PPN1_DQS_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_DQS_INPUT_ENABLE,M_PPNNPL_PPN1_DQS_INPUT_ENABLE) + +#define S_PPNNPL_PPN1_DQS_RSVD0 1 //Access: read-as-zero +#define M_PPNNPL_PPN1_DQS_RSVD0 _MM_MAKEMASK(1,S_PPNNPL_PPN1_DQS_RSVD0) +#define V_PPNNPL_PPN1_DQS_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_DQS_RSVD0) +#define G_PPNNPL_PPN1_DQS_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_DQS_RSVD0,M_PPNNPL_PPN1_DQS_RSVD0) + +#define S_PPNNPL_PPN1_DQS_PULL_ENABLE 2 //Access: read-write +#define M_PPNNPL_PPN1_DQS_PULL_ENABLE _MM_MAKEMASK(1,S_PPNNPL_PPN1_DQS_PULL_ENABLE) +#define V_PPNNPL_PPN1_DQS_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_DQS_PULL_ENABLE) +#define G_PPNNPL_PPN1_DQS_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_DQS_PULL_ENABLE,M_PPNNPL_PPN1_DQS_PULL_ENABLE) + +#define S_PPNNPL_PPN1_DQS_PULL_SELECT 3 //Access: read-write +#define M_PPNNPL_PPN1_DQS_PULL_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN1_DQS_PULL_SELECT) +#define V_PPNNPL_PPN1_DQS_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_DQS_PULL_SELECT) +#define G_PPNNPL_PPN1_DQS_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_DQS_PULL_SELECT,M_PPNNPL_PPN1_DQS_PULL_SELECT) + +#define S_PPNNPL_PPN1_DQS_RSVD1 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_DQS_RSVD1 _MM_MAKEMASK(28,S_PPNNPL_PPN1_DQS_RSVD1) +#define V_PPNNPL_PPN1_DQS_RSVD1(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_DQS_RSVD1) +#define G_PPNNPL_PPN1_DQS_RSVD1(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_DQS_RSVD1,M_PPNNPL_PPN1_DQS_RSVD1) + + +#define S_PPNNPL_PPN1_IO_INPUT_ENABLE 0 //Access: read-write +#define M_PPNNPL_PPN1_IO_INPUT_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN1_IO_INPUT_ENABLE) +#define V_PPNNPL_PPN1_IO_INPUT_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_IO_INPUT_ENABLE) +#define G_PPNNPL_PPN1_IO_INPUT_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_IO_INPUT_ENABLE,M_PPNNPL_PPN1_IO_INPUT_ENABLE) + +#define S_PPNNPL_PPN1_IO_RSVD0 8 //Access: read-as-zero +#define M_PPNNPL_PPN1_IO_RSVD0 _MM_MAKEMASK(8,S_PPNNPL_PPN1_IO_RSVD0) +#define V_PPNNPL_PPN1_IO_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_IO_RSVD0) +#define G_PPNNPL_PPN1_IO_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_IO_RSVD0,M_PPNNPL_PPN1_IO_RSVD0) + +#define S_PPNNPL_PPN1_IO_PULL_ENABLE 16 //Access: read-write +#define M_PPNNPL_PPN1_IO_PULL_ENABLE _MM_MAKEMASK(8,S_PPNNPL_PPN1_IO_PULL_ENABLE) +#define V_PPNNPL_PPN1_IO_PULL_ENABLE(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_IO_PULL_ENABLE) +#define G_PPNNPL_PPN1_IO_PULL_ENABLE(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_IO_PULL_ENABLE,M_PPNNPL_PPN1_IO_PULL_ENABLE) + +#define S_PPNNPL_PPN1_IO_PULL_SELECT 24 //Access: read-write +#define M_PPNNPL_PPN1_IO_PULL_SELECT _MM_MAKEMASK(8,S_PPNNPL_PPN1_IO_PULL_SELECT) +#define V_PPNNPL_PPN1_IO_PULL_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_IO_PULL_SELECT) +#define G_PPNNPL_PPN1_IO_PULL_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_IO_PULL_SELECT,M_PPNNPL_PPN1_IO_PULL_SELECT) + + +#define S_PPNNPL_PPN1_ZQ_OEPD 0 //Access: read-write +#define M_PPNNPL_PPN1_ZQ_OEPD _MM_MAKEMASK(1,S_PPNNPL_PPN1_ZQ_OEPD) +#define V_PPNNPL_PPN1_ZQ_OEPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_OEPD) +#define G_PPNNPL_PPN1_ZQ_OEPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_OEPD,M_PPNNPL_PPN1_ZQ_OEPD) + +#define S_PPNNPL_PPN1_ZQ_OEPU 1 //Access: read-write +#define M_PPNNPL_PPN1_ZQ_OEPU _MM_MAKEMASK(1,S_PPNNPL_PPN1_ZQ_OEPU) +#define V_PPNNPL_PPN1_ZQ_OEPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_OEPU) +#define G_PPNNPL_PPN1_ZQ_OEPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_OEPU,M_PPNNPL_PPN1_ZQ_OEPU) + +#define S_PPNNPL_PPN1_ZQ_ZCPD 2 //Access: read-write +#define M_PPNNPL_PPN1_ZQ_ZCPD _MM_MAKEMASK(4,S_PPNNPL_PPN1_ZQ_ZCPD) +#define V_PPNNPL_PPN1_ZQ_ZCPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_ZCPD) +#define G_PPNNPL_PPN1_ZQ_ZCPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_ZCPD,M_PPNNPL_PPN1_ZQ_ZCPD) + +#define S_PPNNPL_PPN1_ZQ_ZCPU 6 //Access: read-write +#define M_PPNNPL_PPN1_ZQ_ZCPU _MM_MAKEMASK(4,S_PPNNPL_PPN1_ZQ_ZCPU) +#define V_PPNNPL_PPN1_ZQ_ZCPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_ZCPU) +#define G_PPNNPL_PPN1_ZQ_ZCPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_ZCPU,M_PPNNPL_PPN1_ZQ_ZCPU) + +#define S_PPNNPL_PPN1_ZQ_RSVD0 10 //Access: read-as-zero +#define M_PPNNPL_PPN1_ZQ_RSVD0 _MM_MAKEMASK(22,S_PPNNPL_PPN1_ZQ_RSVD0) +#define V_PPNNPL_PPN1_ZQ_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_RSVD0) +#define G_PPNNPL_PPN1_ZQ_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_RSVD0,M_PPNNPL_PPN1_ZQ_RSVD0) + + +#define S_PPNNPL_PPN1_ZQ_IN_YPD 0 //Access: read-only +#define M_PPNNPL_PPN1_ZQ_IN_YPD _MM_MAKEMASK(1,S_PPNNPL_PPN1_ZQ_IN_YPD) +#define V_PPNNPL_PPN1_ZQ_IN_YPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_IN_YPD) +#define G_PPNNPL_PPN1_ZQ_IN_YPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_IN_YPD,M_PPNNPL_PPN1_ZQ_IN_YPD) + +#define S_PPNNPL_PPN1_ZQ_IN_YPU 1 //Access: read-only +#define M_PPNNPL_PPN1_ZQ_IN_YPU _MM_MAKEMASK(1,S_PPNNPL_PPN1_ZQ_IN_YPU) +#define V_PPNNPL_PPN1_ZQ_IN_YPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_IN_YPU) +#define G_PPNNPL_PPN1_ZQ_IN_YPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_IN_YPU,M_PPNNPL_PPN1_ZQ_IN_YPU) + +#define S_PPNNPL_PPN1_ZQ_IN_RSVD0 2 //Access: read-as-zero +#define M_PPNNPL_PPN1_ZQ_IN_RSVD0 _MM_MAKEMASK(30,S_PPNNPL_PPN1_ZQ_IN_RSVD0) +#define V_PPNNPL_PPN1_ZQ_IN_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZQ_IN_RSVD0) +#define G_PPNNPL_PPN1_ZQ_IN_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZQ_IN_RSVD0,M_PPNNPL_PPN1_ZQ_IN_RSVD0) + + +#define S_PPNNPL_PPN1_ZCPD_ZCPD 0 //Access: read-write +#define M_PPNNPL_PPN1_ZCPD_ZCPD _MM_MAKEMASK(4,S_PPNNPL_PPN1_ZCPD_ZCPD) +#define V_PPNNPL_PPN1_ZCPD_ZCPD(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZCPD_ZCPD) +#define G_PPNNPL_PPN1_ZCPD_ZCPD(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZCPD_ZCPD,M_PPNNPL_PPN1_ZCPD_ZCPD) + +#define S_PPNNPL_PPN1_ZCPD_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_ZCPD_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN1_ZCPD_RSVD0) +#define V_PPNNPL_PPN1_ZCPD_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZCPD_RSVD0) +#define G_PPNNPL_PPN1_ZCPD_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZCPD_RSVD0,M_PPNNPL_PPN1_ZCPD_RSVD0) + + +#define S_PPNNPL_PPN1_ZCPU_ZCPU 0 //Access: read-write +#define M_PPNNPL_PPN1_ZCPU_ZCPU _MM_MAKEMASK(4,S_PPNNPL_PPN1_ZCPU_ZCPU) +#define V_PPNNPL_PPN1_ZCPU_ZCPU(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZCPU_ZCPU) +#define G_PPNNPL_PPN1_ZCPU_ZCPU(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZCPU_ZCPU,M_PPNNPL_PPN1_ZCPU_ZCPU) + +#define S_PPNNPL_PPN1_ZCPU_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_ZCPU_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN1_ZCPU_RSVD0) +#define V_PPNNPL_PPN1_ZCPU_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_ZCPU_RSVD0) +#define G_PPNNPL_PPN1_ZCPU_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_ZCPU_RSVD0,M_PPNNPL_PPN1_ZCPU_RSVD0) + + +#define S_PPNNPL_PPN1_DS_DRIVE_STRENGTH 0 //Access: read-write +#define M_PPNNPL_PPN1_DS_DRIVE_STRENGTH _MM_MAKEMASK(4,S_PPNNPL_PPN1_DS_DRIVE_STRENGTH) +#define V_PPNNPL_PPN1_DS_DRIVE_STRENGTH(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_DS_DRIVE_STRENGTH) +#define G_PPNNPL_PPN1_DS_DRIVE_STRENGTH(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_DS_DRIVE_STRENGTH,M_PPNNPL_PPN1_DS_DRIVE_STRENGTH) + +#define S_PPNNPL_PPN1_DS_RSVD0 4 //Access: read-as-zero +#define M_PPNNPL_PPN1_DS_RSVD0 _MM_MAKEMASK(28,S_PPNNPL_PPN1_DS_RSVD0) +#define V_PPNNPL_PPN1_DS_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_DS_RSVD0) +#define G_PPNNPL_PPN1_DS_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_DS_RSVD0,M_PPNNPL_PPN1_DS_RSVD0) + + +#define S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT 0 //Access: read-write +#define M_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT _MM_MAKEMASK(1,S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT) +#define V_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT) +#define G_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT,M_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT) + +#define S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT 1 //Access: read-write +#define M_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT _MM_MAKEMASK(1,S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT) +#define V_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT) +#define G_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT,M_PPNNPL_PPN1_INPUT_SELECT_INPUT_SELECT_SCHMITT) + +#define S_PPNNPL_PPN1_INPUT_SELECT_RSVD0 2 //Access: read-as-zero +#define M_PPNNPL_PPN1_INPUT_SELECT_RSVD0 _MM_MAKEMASK(30,S_PPNNPL_PPN1_INPUT_SELECT_RSVD0) +#define V_PPNNPL_PPN1_INPUT_SELECT_RSVD0(V) _MM_MAKEVALUE((V),S_PPNNPL_PPN1_INPUT_SELECT_RSVD0) +#define G_PPNNPL_PPN1_INPUT_SELECT_RSVD0(V) _MM_GETVALUE((V),S_PPNNPL_PPN1_INPUT_SELECT_RSVD0,M_PPNNPL_PPN1_INPUT_SELECT_RSVD0) + + + +/******************************************************************************/ +/* Register Fields typedef structs */ +/******************************************************************************/ +#ifndef __ASSEMBLY__ + +typedef union ppnnpl_version_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t revision:16; //Access: read-only + uint32_t version:16; //Access: read-only + }f; +} ppnnpl_version_t; + +typedef union ppnnpl_config_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t auto_pulldone_enable:1; //Access: read-write + uint32_t rsvd0:31; //Access: read-as-zero + }f; +} ppnnpl_config_t; + +typedef union ppnnpl_dqs_timing_t { //RRV:0x003f003f + uint32_t all; //RRM:0x00000000 + struct { + uint32_t anc0_default_delay_code:9; //Access: read-write + uint32_t anc0_use_default_delay_code:1; //Access: read-write + uint32_t anc0_dll_select:1; //Access: read-write + uint32_t rsvd0:5; //Access: read-as-zero + uint32_t anc1_default_delay_code:9; //Access: read-write + uint32_t anc1_use_default_delay_code:1; //Access: read-write + uint32_t anc1_dll_select:1; //Access: read-write + uint32_t rsvd1:5; //Access: read-as-zero + }f; +} ppnnpl_dqs_timing_t; + +typedef union ppnnpl_dll_codes_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t master_delay_out:7; //Access: read-only + uint32_t slave0_delay_code_in:9; //Access: read-only + uint32_t slave1_delay_code_in:9; //Access: read-only + uint32_t rsvd0:7; //Access: read-as-zero + }f; +} ppnnpl_dll_codes_t; + +typedef union ppnnpl_dqs_adjust_t { //RRV:0x00400040 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t anc0_frequency_ratio:8; //Access: read-write + uint32_t anc0_offset:7; //Access: read-write + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t anc1_frequency_ratio:8; //Access: read-write + uint32_t anc1_offset:7; //Access: read-write + uint32_t rsvd1:1; //Access: read-as-zero + }f; +} ppnnpl_dqs_adjust_t; + +typedef union ppnnpl_ampmcdll_control_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t stepsize_in:1; //Access: read-write + uint32_t stepsize_sel:1; //Access: read-write + uint32_t rsvd0:30; //Access: read-as-zero + }f; +} ppnnpl_ampmcdll_control_t; + +typedef union ppnnpl_ampslv_control_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t anc0_bypass_mode:2; //Access: read-write + uint32_t anc1_bypass_mode:2; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ampslv_control_t; + +typedef union ppnnpl_ampdll_status_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t dll_locked:1; //Access: read-only + uint32_t rsvd0:31; //Access: read-as-zero + }f; +} ppnnpl_ampdll_status_t; + +typedef union ppnnpl_anc0_ampslv0_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t slv_sel:12; //Access: read-only + uint32_t rsvd0:20; //Access: read-as-zero + }f; +} ppnnpl_anc0_ampslv0_t; + +typedef union ppnnpl_anc0_ampslv1_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t slv_sel:12; //Access: read-only + uint32_t rsvd0:20; //Access: read-as-zero + }f; +} ppnnpl_anc0_ampslv1_t; + +typedef union ppnnpl_anc1_ampslv0_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t slv_sel:12; //Access: read-only + uint32_t rsvd0:20; //Access: read-as-zero + }f; +} ppnnpl_anc1_ampslv0_t; + +typedef union ppnnpl_anc1_ampslv1_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t slv_sel:12; //Access: read-only + uint32_t rsvd0:20; //Access: read-as-zero + }f; +} ppnnpl_anc1_ampslv1_t; + +typedef union ppnnpl_train_control_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t disable_continuous_training:1; //Access: read-write + uint32_t train_periodically:1; //Access: read-write + uint32_t train_once:1; //Access: write-auto-clear + uint32_t rsvd0:29; //Access: read-as-zero + }f; +} ppnnpl_train_control_t; + +typedef union ppnnpl_periodic_training_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t delay:32; //Access: read-write + }f; +} ppnnpl_periodic_training_t; + +typedef union ppnnpl_debug_dll_control_t { //RRV:0x4c000034 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t start_delay:3; //Access: read-write + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t step_size:3; //Access: read-write + uint32_t rsvd1:9; //Access: read-as-zero + uint32_t train:1; //Access: read-write + uint32_t rsvd2:7; //Access: read-as-zero + uint32_t train_prepare_delay:4; //Access: read-write + uint32_t train_pause_delay:4; //Access: read-write + }f; +} ppnnpl_debug_dll_control_t; + +typedef union ppnnpl_debug_data_capture_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t anc0_posedge_data:8; //Access: read-only + uint32_t anc1_posedge_data:8; //Access: read-only + uint32_t rsvd0:16; //Access: read-as-zero + }f; +} ppnnpl_debug_data_capture_t; + +typedef union ppnnpl_ppn0_cle_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_cle_t; + +typedef union ppnnpl_ppn0_ale_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_ale_t; + +typedef union ppnnpl_ppn0_ren_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_ren_t; + +typedef union ppnnpl_ppn0_wen_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_wen_t; + +typedef union ppnnpl_ppn0_cen_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:8; //Access: read-write + uint32_t output_enable:8; //Access: read-write + uint32_t pull_enable:8; //Access: read-write + uint32_t pull_select:8; //Access: read-write + }f; +} ppnnpl_ppn0_cen_t; + +typedef union ppnnpl_ppn0_dqs_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd1:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_dqs_t; + +typedef union ppnnpl_ppn0_io_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:8; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + uint32_t pull_enable:8; //Access: read-write + uint32_t pull_select:8; //Access: read-write + }f; +} ppnnpl_ppn0_io_t; + +typedef union ppnnpl_ppn0_zq_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t oepd:1; //Access: read-write + uint32_t oepu:1; //Access: read-write + uint32_t zcpd:4; //Access: read-write + uint32_t zcpu:4; //Access: read-write + uint32_t rsvd0:22; //Access: read-as-zero + }f; +} ppnnpl_ppn0_zq_t; + +typedef union ppnnpl_ppn0_zq_in_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t ypd:1; //Access: read-only + uint32_t ypu:1; //Access: read-only + uint32_t rsvd0:30; //Access: read-as-zero + }f; +} ppnnpl_ppn0_zq_in_t; + +typedef union ppnnpl_ppn0_zcpd_t { //RRV:0x00000008 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t zcpd:4; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_zcpd_t; + +typedef union ppnnpl_ppn0_zcpu_t { //RRV:0x00000008 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t zcpu:4; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_zcpu_t; + +typedef union ppnnpl_ppn0_ds_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t drive_strength:4; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn0_ds_t; + +typedef union ppnnpl_ppn0_input_select_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_select:1; //Access: read-write + uint32_t input_select_schmitt:1; //Access: read-write + uint32_t rsvd0:30; //Access: read-as-zero + }f; +} ppnnpl_ppn0_input_select_t; + +typedef union ppnnpl_ppn1_cle_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_cle_t; + +typedef union ppnnpl_ppn1_ale_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_ale_t; + +typedef union ppnnpl_ppn1_ren_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_ren_t; + +typedef union ppnnpl_ppn1_wen_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t output_enable:1; //Access: read-write + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_wen_t; + +typedef union ppnnpl_ppn1_cen_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:8; //Access: read-write + uint32_t output_enable:8; //Access: read-write + uint32_t pull_enable:8; //Access: read-write + uint32_t pull_select:8; //Access: read-write + }f; +} ppnnpl_ppn1_cen_t; + +typedef union ppnnpl_ppn1_dqs_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:1; //Access: read-write + uint32_t rsvd0:1; //Access: read-as-zero + uint32_t pull_enable:1; //Access: read-write + uint32_t pull_select:1; //Access: read-write + uint32_t rsvd1:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_dqs_t; + +typedef union ppnnpl_ppn1_io_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_enable:8; //Access: read-write + uint32_t rsvd0:8; //Access: read-as-zero + uint32_t pull_enable:8; //Access: read-write + uint32_t pull_select:8; //Access: read-write + }f; +} ppnnpl_ppn1_io_t; + +typedef union ppnnpl_ppn1_zq_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t oepd:1; //Access: read-write + uint32_t oepu:1; //Access: read-write + uint32_t zcpd:4; //Access: read-write + uint32_t zcpu:4; //Access: read-write + uint32_t rsvd0:22; //Access: read-as-zero + }f; +} ppnnpl_ppn1_zq_t; + +typedef union ppnnpl_ppn1_zq_in_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t ypd:1; //Access: read-only + uint32_t ypu:1; //Access: read-only + uint32_t rsvd0:30; //Access: read-as-zero + }f; +} ppnnpl_ppn1_zq_in_t; + +typedef union ppnnpl_ppn1_zcpd_t { //RRV:0x00000008 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t zcpd:4; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_zcpd_t; + +typedef union ppnnpl_ppn1_zcpu_t { //RRV:0x00000008 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t zcpu:4; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_zcpu_t; + +typedef union ppnnpl_ppn1_ds_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t drive_strength:4; //Access: read-write + uint32_t rsvd0:28; //Access: read-as-zero + }f; +} ppnnpl_ppn1_ds_t; + +typedef union ppnnpl_ppn1_input_select_t { //RRV:0x00000000 + uint32_t all; //RRM:0x00000000 + struct { + uint32_t input_select:1; //Access: read-write + uint32_t input_select_schmitt:1; //Access: read-write + uint32_t rsvd0:30; //Access: read-as-zero + }f; +} ppnnpl_ppn1_input_select_t; + + +/******************************************************************************/ +/* Registers typedef structs */ +/******************************************************************************/ +/* errors in perl template and spds required these to be commented out + + +typedef union ppnnpl_t { + uint32_t all[1024]; + struct { + ppnnpl_version_t VERSION ; // 0x00000000 + ppnnpl_config_t CONFIG ; // 0x00000004 + ppnnpl_dqs_timing_t DQS_TIMING ; // 0x00000008 + ppnnpl_dll_codes_t DLL_CODES ; // 0x0000000c + ppnnpl_dqs_adjust_t DQS_ADJUST ; // 0x00000010 + ppnnpl_ampmcdll_control_t AMPMCDLL_CONTROL ; // 0x00000014 + ppnnpl_ampslv_control_t AMPSLV_CONTROL ; // 0x00000018 + ppnnpl_ampdll_status_t AMPDLL_STATUS ; // 0x0000001c + ppnnpl_anc0_ampslv0_t ANC0_AMPSLV0 ; // 0x00000020 + ppnnpl_anc0_ampslv1_t ANC0_AMPSLV1 ; // 0x00000024 + ppnnpl_anc1_ampslv0_t ANC1_AMPSLV0 ; // 0x00000028 + ppnnpl_anc1_ampslv1_t ANC1_AMPSLV1 ; // 0x0000002c + ppnnpl_train_control_t TRAIN_CONTROL ; // 0x00000030 + ppnnpl_periodic_training_t PERIODIC_TRAINING ; // 0x00000034 + ppnnpl_debug_dll_control_t DEBUG_DLL_CONTROL ; // 0x00000038 + ppnnpl_debug_data_capture_t DEBUG_DATA_CAPTURE ; // 0x0000003c + ppnnpl_ppn0_cle_t PPN0_CLE ; // 0x00000040 + ppnnpl_ppn0_ale_t PPN0_ALE ; // 0x00000044 + ppnnpl_ppn0_ren_t PPN0_REN ; // 0x00000048 + ppnnpl_ppn0_wen_t PPN0_WEN ; // 0x0000004c + ppnnpl_ppn0_cen_t PPN0_CEN ; // 0x00000050 + ppnnpl_ppn0_dqs_t PPN0_DQS ; // 0x00000054 + ppnnpl_ppn0_io_t PPN0_IO ; // 0x00000058 + ppnnpl_ppn0_zq_t PPN0_ZQ ; // 0x0000005c + ppnnpl_ppn0_zq_in_t PPN0_ZQ_IN ; // 0x00000060 + ppnnpl_ppn0_zcpd_t PPN0_ZCPD ; // 0x00000064 + ppnnpl_ppn0_zcpu_t PPN0_ZCPU ; // 0x00000068 + ppnnpl_ppn0_ds_t PPN0_DS ; // 0x0000006c + ppnnpl_ppn0_input_select_t PPN0_INPUT_SELECT ; // 0x00000070 + ppnnpl_ppn1_cle_t PPN1_CLE ; // 0x00000074 + ppnnpl_ppn1_ale_t PPN1_ALE ; // 0x00000078 + ppnnpl_ppn1_ren_t PPN1_REN ; // 0x0000007c + ppnnpl_ppn1_wen_t PPN1_WEN ; // 0x00000080 + ppnnpl_ppn1_cen_t PPN1_CEN ; // 0x00000084 + ppnnpl_ppn1_dqs_t PPN1_DQS ; // 0x00000088 + ppnnpl_ppn1_io_t PPN1_IO ; // 0x0000008c + ppnnpl_ppn1_zq_t PPN1_ZQ ; // 0x00000090 + ppnnpl_ppn1_zq_in_t PPN1_ZQ_IN ; // 0x00000094 + ppnnpl_ppn1_zcpd_t PPN1_ZCPD ; // 0x00000098 + ppnnpl_ppn1_zcpu_t PPN1_ZCPU ; // 0x0000009c + ppnnpl_ppn1_ds_t PPN1_DS ; // 0x000000a0 + ppnnpl_ppn1_input_select_t PPN1_INPUT_SELECT ; // 0x000000a4 + }r; +} ppnnpl_t; + + +typedef union ppnnpl_regs_s{ + struct { + ppnnpl_t ppnNpl; // 0x00000000 + }ab; + uint32_t all[1024]; + }; +}ppnnpl_regs_t; +*/ + +/******************************************************************************/ +/* Registers enum */ +/******************************************************************************/ +/* errors in perl template and spds required these to be commented out + + +typedef enum ppnnpl_regenum { + version = 0, + config = 1, + dqs_timing = 2, + dll_codes = 3, + dqs_adjust = 4, + ampmcdll_control = 5, + ampslv_control = 6, + ampdll_status = 7, + anc0_ampslv0 = 8, + anc0_ampslv1 = 9, + anc1_ampslv0 = 10, + anc1_ampslv1 = 11, + train_control = 12, + periodic_training = 13, + debug_dll_control = 14, + debug_data_capture = 15, + ppn0_cle = 16, + ppn0_ale = 17, + ppn0_ren = 18, + ppn0_wen = 19, + ppn0_cen = 20, + ppn0_dqs = 21, + ppn0_io = 22, + ppn0_zq = 23, + ppn0_zq_in = 24, + ppn0_zcpd = 25, + ppn0_zcpu = 26, + ppn0_ds = 27, + ppn0_input_select = 28, + ppn1_cle = 29, + ppn1_ale = 30, + ppn1_ren = 31, + ppn1_wen = 32, + ppn1_cen = 33, + ppn1_dqs = 34, + ppn1_io = 35, + ppn1_zq = 36, + ppn1_zq_in = 37, + ppn1_zcpd = 38, + ppn1_zcpu = 39, + ppn1_ds = 40, + ppn1_input_select = 41, +}ppnnpl_regenum; + + +*/ +#endif +#endif diff --git a/drivers/apple/anc/rules.mk b/drivers/apple/anc/rules.mk new file mode 100644 index 0000000..24336e4 --- /dev/null +++ b/drivers/apple/anc/rules.mk @@ -0,0 +1,46 @@ +# Copyright (C) 2011-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) +GLOBAL_INCLUDES += $(LOCAL_DIR) + +ifeq ($(PRODUCT),LLB) +OPTIONS += WITH_ANC_FIRMWARE=1 +ALL_OBJS += \ + $(LOCAL_DIR)/anc_bootrom.o \ + $(LOCAL_DIR)/anc_llb.o \ + $(LOCAL_DIR)/util_boot.o +endif + +ifeq ($(IBOOT_ANC_NVRAM), true) +ifeq ($(PRODUCT),iBoot) + +# Some targets like M7 can boot into chargetrap faster +# by skipping ANS in iBoot and instead relying on ANC +# for firmware and NVRAM access. These targets set +# IBOOT_ANC_NVRAM to true and ANC support is only conditionally +# active in iBoot. + +OPTIONS += WITH_ANC_FIRMWARE=1 +ALL_OBJS += \ + $(LOCAL_DIR)/anc_bootrom.o \ + $(LOCAL_DIR)/anc_llb.o \ + $(LOCAL_DIR)/util_boot.o +endif +endif + + +ifeq ($(APPLICATION),SecureROM) +OPTIONS += WITH_ANC_BOOT=1 +ALL_OBJS += \ + $(LOCAL_DIR)/anc_bootrom.o \ + $(LOCAL_DIR)/util_boot.o +endif + diff --git a/drivers/apple/anc/util_boot.c b/drivers/apple/anc/util_boot.c new file mode 100644 index 0000000..7b5eff4 --- /dev/null +++ b/drivers/apple/anc/util_boot.c @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util_boot.h" +#include "anc_bootrom.h" +#include "anc_llb.h" + + +#define BOOT_NUM_ELEMENT (12) +#define BOOT_NUM_PSLOTS (32) +typedef struct { + uint32_t page : 8; + uint32_t slot : 8; + uint32_t pslot : 8; + uint32_t RFU : 8; +} UtilBoot_location_t; + +typedef struct { + UtilBoot_location_t location[UTIL_NUM_ELEMENT]; + uint32_t prevUtilDMversion; + uint32_t prevUtilDMslot; + bool BCopyPresent; + uint8_t minorVersion; +} UtilBoot_t; + +typedef struct { + UtilBootDM_t s; + uint32_t version; + uint32_t RFU; // was used by mxcfg + uint16_t erases[UTIL_NUM_PSLOTS]; + uint8_t clogMajor; + uint8_t clogMinor; + uint8_t pendDefect; // defect pending (shuffle in progress). + uint8_t pad[4096 - sizeof(UtilBootDM_t) - 11 - UTIL_NUM_PSLOTS*2]; +}UtilDM_t; + +extern anc_ppn_device_params_t *anc_geom; +#define CASSERT(x, name) typedef char __ASP_CASSERT_##name[(x) ? 1 : -1] + +CASSERT(sizeof(UtilDM_t)==4096, sizeUtilDMcorrect); + +extern int anc_num_channel; + +#define quantup(num, gran) (((num) + (gran) - 1) / (gran)) +#define ROUNDUPTO(num, gran) ((((num) + (gran) - 1) / (gran)) * (gran)) + +static UtilDM_t* UtilDM; +static UtilDM_t* UtilDM_backup; + +static UtilBoot_t Util; + +#define META_LBA_INDEX 0 +static uint32_t meta[4]; + +// prototypes +uint32_t Boot_Slip (uint32_t slot); +void Boot_BandDip (uint32_t pslot, uint32_t* band, uint32_t* dip); +static int anc_read_fw_block (struct blockdev *_dev, void *data, block_addr req_offset, uint32_t max_size); +bool Boot_PostProcessDM(UtilDM_t *p, uint32_t slot, uint32_t page, uint32_t *meta); +#if WITH_LLB_NVRAM +bool Boot_Read(void *buffer, uint32_t page, uint32_t slot, uint32_t *meta); +uint32_t Boot_Find_Fast_Scan(void *buffer, uint32_t page, uint32_t slot); +void Boot_Find_Fast(void *buffer); +void Boot_Find_UtilDM(void *buffer); +static int anc_read_nvram_block (struct blockdev *_dev, void *data, block_addr req_offset, uint32_t max_size); +#endif +#if WITH_LLB_BLKDEV +static int anc_read_llb_block (struct blockdev *_dev, void *data, block_addr req_offset, uint32_t max_size); +#endif + +// POR equivalent. Resets the Nand but does not do discovery. Zeros out the UtilDM->s.utilMajor to indicate UtilDM not loaded. +bool anc_reset(int resetMode) { + bool err; + + UtilDM->s.utilMajor = 0; // indicate UtilDM not loaded. + meta[1]=0; + meta[2]=0; + meta[3]=0; + err = anc_bootrom_init(true, resetMode); + if (err != 0) + { + return false; + } + else + { + return true; + } +} + +// Entry point from LLB +bool anc_firmware_init(void) +{ + bool err; + struct blockdev *bdev; +#if WITH_LLB_NVRAM + struct blockdev *nv_bdev; +#endif +#if WITH_LLB_BLKDEV + struct blockdev *llb_bdev; +#endif + + + UtilDM = memalign(sizeof(UtilDM_t), CPU_CACHELINE_SIZE); + UtilDM_backup = memalign(sizeof(UtilDM_t), CPU_CACHELINE_SIZE); + + if (!UtilDM) { + dprintf(DEBUG_CRITICAL, "Failed to malloc UtilDM\n"); + return false; + } + + if (!UtilDM_backup) { + dprintf(DEBUG_CRITICAL, "Failed to malloc UtilDM_backup\n"); + return false; + } + + bzero(UtilDM, sizeof(UtilDM_t)); + bzero(UtilDM_backup, sizeof(UtilDM_t)); + + uint32_t block_size; + uint32_t size; + + err = anc_llb_init(); + if (err != 0) + { + dprintf(DEBUG_CRITICAL,"Failed to reset ANC\n"); + return false; + } + + // Load UtilDM + meta[META_LBA_INDEX] = BOOT_LBA_TOKEN_UTILDM; + if (anc_llb_read_phys_page(BOOT_BAND_UTILDM, BOOT_DIP_UTILDM, BOOT_PAGE_UTILDM, BOOT_SIZE_UTILDM, UtilDM_backup, &meta[0])!=BOOT_SIZE_UTILDM) { + UtilDM->s.utilMajor = 0; + return(false); + } + + Boot_PostProcessDM(UtilDM_backup,0,0,meta); + dprintf(DEBUG_CRITICAL,"Loaded UtilDM revision = %2d.%2d\n",UtilDM->s.utilMajor, UtilDM->s.utilMinor); + + if (UtilDM->s.eSize[BOOT_ELEMENT_FW] == 0) + { + dprintf(DEBUG_CRITICAL,"No firmware region programmed; not creating block device\n"); + return false; + } + + bdev = malloc(sizeof(struct blockdev)); + if (!bdev) + { + dprintf(DEBUG_CRITICAL,"Failed to allocate blockdev\n"); + return false; + } + + block_size = BOOT_BYTES_PER_SEC * UtilDM->s.secPerPage; + size = ROUNDUPTO(UtilDM->s.eSize[BOOT_ELEMENT_FW] * BOOT_BYTES_PER_SEC, block_size); + + if (construct_blockdev(bdev, + "anc_firmware", + size, + block_size) != 0) + { + dprintf(DEBUG_CRITICAL,"Failed to construct block device\n"); + free(bdev); + return false; + } + + bdev->read_block_hook = &anc_read_fw_block; + if (register_blockdev(bdev) != 0) + { + dprintf(DEBUG_CRITICAL,"Failed to register bdev\n"); + free(bdev); + return false; + } + + // ANC DMA has a minimum 16byte alignment requirement + // But if the CPU isn't coherent with ANC, we need to increase the alignment requirement + #if WITH_NON_COHERENT_DMA + blockdev_set_buffer_alignment(bdev, __max(ANC_MIN_ALIGNMENT, CPU_CACHELINE_SIZE)); + #else + blockdev_set_buffer_alignment(bdev, ANC_MIN_ALIGNMENT); + #endif + + +#if 0 + uint32_t *buf; + uint32_t i; + buf = (uint32_t *)INSECURE_MEMORY_BASE; + dprintf(DEBUG_CRITICAL,"Starting test at %p\n", buf); + memset(buf, 0, 520192); + anc_read_fw_block(NULL, buf, 0, 127); + for (i = 0; i < 520192 / 4; i++) + { + if (buf[i] != i) + { + panic("Miscompare at 0x%08X got 0x%08X", i, buf[i]); + } + } + dprintf(DEBUG_CRITICAL,"compare passed\n"); + + anc_read_fw_block(NULL, buf, 126, 1); + i = 126 * 1024; + uint32_t j; + for (j = 0; j < 1024; j++, i++) + { + if (buf[j] != i) + { + panic("Miscompare expected 0x%08X got 0x%08X", i, buf[j]); + } + } +#endif + +#if WITH_LLB_NVRAM + // keep trying to find the latest + Boot_Find_UtilDM(UtilDM_backup); + Boot_Find_Fast(UtilDM_backup); + nv_bdev = malloc(sizeof(struct blockdev)); + if (!nv_bdev) + { + dprintf(DEBUG_CRITICAL,"Failed to allocate nvram blockdev\n"); + return false; + } + + + if (construct_blockdev(nv_bdev, + "nvram", + 8192, + 8192) != 0) + { + dprintf(DEBUG_CRITICAL,"Failed to construct block device\n"); + free(nv_bdev); + return false; + } + + nv_bdev->read_block_hook = &anc_read_nvram_block; + if (register_blockdev(nv_bdev) != 0) + { + dprintf(DEBUG_CRITICAL,"Failed to register bdev\n"); + free(nv_bdev); + return false; + } +#endif +#if WITH_LLB_BLKDEV + llb_bdev = malloc(sizeof(struct blockdev)); + if (!llb_bdev) + { + dprintf(DEBUG_CRITICAL,"Failed to allocate LLB blockdev\n"); + return false; + } + + block_size = BOOT_BYTES_PER_SEC * UtilDM->s.secPerPage; + size = ROUNDUPTO(UtilDM->s.eSize[BOOT_ELEMENT_LLB] * BOOT_BYTES_PER_SEC, block_size); + + if (construct_blockdev(llb_bdev, + "anc_llb", + size, + block_size) != 0) + { + dprintf(DEBUG_CRITICAL,"Failed to construct block device\n"); + free(llb_bdev); + return false; + } + + llb_bdev->read_block_hook = &anc_read_llb_block; + + // ANC DMA has a minimum 16byte alignment requirement + // But if the CPU isn't coherent with ANC, we need to increase the alignment requirement + #if WITH_NON_COHERENT_DMA + blockdev_set_buffer_alignment(llb_bdev, __max(ANC_MIN_ALIGNMENT, CPU_CACHELINE_SIZE)); + #else + blockdev_set_buffer_alignment(llb_bdev, ANC_MIN_ALIGNMENT); + #endif + + + if (register_blockdev(llb_bdev) != 0) + { + dprintf(DEBUG_CRITICAL,"Failed to register bdev\n"); + free(llb_bdev); + return false; + } +#endif + + return true; +} + + +// LLB loader. Will load UtilDM on first read request which will reset the UtilDM->s.utilMajor to be current. +size_t anc_read_llb(void* data, size_t max_size) { + uint32_t page; + uint32_t size, thisSize; + uint32_t secPerPage; + bool err; + + if(0 == UtilDM->s.utilMajor) { + err = anc_bootrom_init(false, 0); // do discovery + if(err) { + return(0); + } + meta[META_LBA_INDEX] = BOOT_LBA_TOKEN_UTILDM; + if (!anc_bootrom_read_phys_page(BOOT_BAND_UTILDM, BOOT_DIP_UTILDM, BOOT_PAGE_UTILDM, BOOT_SIZE_UTILDM, UtilDM, &meta[0])) { + UtilDM->s.utilMajor = 0; + return(false); + } + dprintf(DEBUG_CRITICAL,"Loaded UtilDM revision = %2d.%2d\n",UtilDM->s.utilMajor, UtilDM->s.utilMinor); + } + + + meta[META_LBA_INDEX] = BOOT_LBA_TOKEN_LLB; + secPerPage = UtilDM->s.secPerPage; + page = BOOT_PAGE_LLB; // LLB doesn't start at page=0 + + size = (uint32_t) max_size / BOOT_BYTES_PER_SEC; + dprintf(DEBUG_CRITICAL,"Reading LLB for size=%d\n", size); + if(size > UtilDM->s.eSize[BOOT_ELEMENT_LLB]) { + size = UtilDM->s.eSize[BOOT_ELEMENT_LLB]; + dprintf(DEBUG_CRITICAL,"Trimmed size to written size of %5d\n", size); + } + + max_size = size; // record for result to caller + + while(size) { + if(size > secPerPage) { + thisSize = secPerPage; + } else { + thisSize = size; + } + + if(!anc_bootrom_read_phys_page(BOOT_BAND_LLB, BOOT_DIP_LLB, page, thisSize, data, &meta[0])) { + break; + } + size -= thisSize; + page++; + data += thisSize * BOOT_BYTES_PER_SEC; + } + + return( (max_size - size) * BOOT_BYTES_PER_SEC ); +} + + +// the code below this comment is required for loading the FW element. + + + + + +// clone of UtilDM_Slip from product code +uint32_t Boot_Slip(uint32_t pslot) { + uint32_t i; + + i = 0; + while(i < UtilDM->s.numDefects && (pslot >= UtilDM->s.defects[i]) ) { + pslot++; + i++; + } + return(pslot); +} + + + +// clone of UtilDM_BandDip +// Converts the physical slot to a band,dip that is consistent with Nand engine's usage. returns dip and writes band to bandPtr +void Boot_BandDip(uint32_t pslot, uint32_t* bandPtr, uint32_t* dipPtr) { + uint32_t bus; + uint32_t die; + uint32_t plane; + uint32_t cau; + + uint32_t slot_itr; + uint32_t band; + uint32_t num_bus; + uint32_t die_per_bus; + uint32_t cau_per_die; + + if (anc_get_dies_per_channel() * anc_num_channel == UtilDM->s.numDie) { + num_bus = anc_num_channel; + } else { + // geom_num_bus is incorrect because a bus didn't come up. + num_bus = UtilDM->s.numDie / anc_get_dies_per_channel(); + } + die_per_bus = UtilDM->s.numDie / anc_num_channel; + cau_per_die = UtilDM->s.numPlanes; + + bus = 0; + die = 0; + plane = 0; + band = 0; + for (slot_itr = 0; slot_itr < pslot; slot_itr++) { + bus++; + + if(bus >= num_bus) { + bus = 0; + die++; + + if (die >= die_per_bus){ + die = 0; + plane++; + + if (plane >= cau_per_die) { + plane=0; + band++; + } + } + } + } + cau = (die * cau_per_die) + plane; + + *bandPtr = band; + *dipPtr = anc_get_dip(bus, cau); +} + + + +// leveraged core UtilDM_PostProcess +bool Boot_PostProcessDM(UtilDM_t *p, uint32_t page, uint32_t slot, uint32_t *meta) +{ + uint32_t wasGrownDef; + uint32_t newV; + uint32_t currV; + bool result = false; + + if (meta[0] == BOOT_ERR_BLANK) { + dprintf(DEBUG_INFO,"UTIL - [%2d,%2d] BLANK! \n", slot, page); + } + else if (p->s.utilMajor != BOOT_UTIL_MAJOR) { + dprintf(DEBUG_INFO,"UTIL - [%2d,%2d] !!!!! Found UtilDM with different major version =0x%08x ", slot, page, + p->s.utilMajor); + return false; + } else if (p->s.utilMinor < Util.minorVersion) { + dprintf(DEBUG_INFO,"UTIL - [%2d,%2d] !!!!! Found UtilDM with major version 0x%08x but minor version 0x%08x (less than minimum 0x%08x)", + slot, page, p->s.utilMajor, p->s.utilMinor, Util.minorVersion); + return false; + } else { + newV = p->version; + currV = UtilDM->version; + + if (newV >= currV) { + Util.prevUtilDMversion = currV; + Util.prevUtilDMslot = Util.location[BOOT_ELEMENT_UTILDM].slot; + Util.location[BOOT_ELEMENT_UTILDM].slot = slot; + Util.location[BOOT_ELEMENT_UTILDM].page = page; + + dprintf(DEBUG_INFO,"UTIL - [%2d,%2d] Adopting version=0x%08x numDefects=%2d numSlots=%2d\n", slot, + page, newV, p->s.numDefects, + p->s.numSlots); + wasGrownDef = UtilDM->s.numDefects; + memcpy(UtilDM, p, sizeof(UtilDM_t)); + + if (wasGrownDef != UtilDM->s.numDefects) { + result = true; + } + + if (slot == BOOT_SLOT_FAST_B) { + Util.BCopyPresent = true; + } else { + Util.BCopyPresent = false; // Always expect a B copy on the right of A + } + } else if (!Util.BCopyPresent && (slot == BOOT_SLOT_FAST_B) && ((currV == (newV + 1)))) { + + // This is the case where we have a newer copy on the left of the older copy + // accept B copy if it's version is 1 less than A copy, consider B slot, the previous slot + Util.prevUtilDMversion = newV; + Util.prevUtilDMslot = slot; + + dprintf(DEBUG_INFO,"UTIL - [%2d,%2d] Adopting B copy version=0x%08x numDefects=%2d numSlots=%2d", slot, + page, newV, p->s.numDefects, + p->s.numSlots); + Util.BCopyPresent = true; + + } else { + dprintf(DEBUG_INFO,"UTIL - [%2d,%2d] Ignoring version=0x%08x numDefects=%2d numSlots=%2d", slot, + page, newV, p->s.numDefects, + p->s.numSlots); + } + } + + return result; +} + +static int anc_read_fw_block (struct blockdev *_dev, void *data, block_addr offset, uint32_t sectors) { + + uint32_t slot; + uint32_t slotB; // offset for the B copy of FW. 0 indicates not doing retry + uint32_t pslot; + uint32_t page; + uint32_t band; + uint32_t dip; + uint32_t thisSize; + uint32_t secPerPage; + uint32_t pagePerSlot; + uint32_t err; + uint32_t max_size; + + // Incoming sectors are in terms of page size (to prevent the client from + // attempting a sub-page read). + sectors *= UtilDM->s.secPerPage; + offset *= UtilDM->s.secPerPage; + + dprintf(DEBUG_INFO,"Reading sectors from FW element from offset=%4d for a size=%4d\n", offset, sectors);; + + if(BOOT_UTIL_MAJOR != UtilDM->s.utilMajor) { + dprintf(DEBUG_CRITICAL,"Exiting anc_read_fw because UtilDM->s.utilMajor is incorrect\n"); + return(0); + } + if(offset > UtilDM->s.eSize[BOOT_ELEMENT_FW]) { + dprintf(DEBUG_CRITICAL,"Requested offset exceeds size of firmware\n"); + return(0); + } + + if(sectors + offset > UtilDM->s.eSize[BOOT_ELEMENT_FW]) { + dprintf(DEBUG_CRITICAL,"Attempt to read past end of firmware\n"); + return(0); + } + + meta[META_LBA_INDEX] = BOOT_LBA_TOKEN_FW; + secPerPage = UtilDM->s.secPerPage; + pagePerSlot = UtilDM->s.numPages; + + page = BOOT_PAGE_FW; // starting location for FW in [slot,page] + slot = BOOT_SLOT_FW; + + while(offset >= secPerPage) { + offset -= secPerPage; + page++; + if(page >= pagePerSlot) { + page = 0; + slot++; + } + } + // lba now converted to page/slot + + err = 0; + slotB = 0; + + max_size = sectors; // save for result + while(sectors) { + pslot = Boot_Slip(slot+slotB); + Boot_BandDip(pslot, &band, &dip); + + thisSize = sectors; + if(thisSize > secPerPage) { + thisSize = secPerPage; + } + + if (anc_llb_read_phys_page(band, dip, page, thisSize, data, &meta[0])!=secPerPage) { + dprintf(DEBUG_CRITICAL,"Failed to read page\n"); + if(!slotB) { + slotB = UtilDM->s.sizeFWslots; + } else { + break; + } + } else { + slotB = 0; + sectors -= thisSize; + data += thisSize * BOOT_BYTES_PER_SEC; + page++; + if(page >= pagePerSlot) { + page = 0; + slot++; + } + } + } + if(err) { + dprintf(DEBUG_CRITICAL,"Encountered error = %d\n", err); + } + + return (max_size - sectors) / secPerPage; +} + +#if WITH_LLB_BLKDEV +// LLB loader. Will load UtilDM on first read request which will reset the UtilDM->s.utilMajor to be current. +static int anc_read_llb_block (struct blockdev *_dev, void *data, block_addr offset, uint32_t sectors) { + uint32_t page; + uint32_t size, thisSize, max_size, secRead; + uint32_t secPerPage; + bool err; + + if(0 == UtilDM->s.utilMajor) { + err = anc_bootrom_init(false, 0); // do discovery + if(err) { + return(0); + } + meta[META_LBA_INDEX] = BOOT_LBA_TOKEN_UTILDM; + if (anc_llb_read_phys_page(BOOT_BAND_UTILDM, BOOT_DIP_UTILDM, BOOT_PAGE_UTILDM, BOOT_SIZE_UTILDM, UtilDM, &meta[0])!=BOOT_SIZE_UTILDM) { + UtilDM->s.utilMajor = 0; + return(false); + } + dprintf(DEBUG_CRITICAL,"Loaded UtilDM revision = %2d.%2d\n",UtilDM->s.utilMajor, UtilDM->s.utilMinor); + } + + + meta[META_LBA_INDEX] = BOOT_LBA_TOKEN_LLB; + secPerPage = UtilDM->s.secPerPage; + page = BOOT_PAGE_LLB + offset; + + size = sectors * secPerPage; + dprintf(DEBUG_SPEW,"Reading LLB for size=%d, page=%u\n", sectors, (unsigned int)page); + if(size > UtilDM->s.eSize[BOOT_ELEMENT_LLB]) { + size = UtilDM->s.eSize[BOOT_ELEMENT_LLB]; + dprintf(DEBUG_CRITICAL,"Trimmed size to written size of %5d\n", size); + } + + max_size = size; // record for result to caller + + while(size) { + if(size > secPerPage) { + thisSize = secPerPage; + } else { + thisSize = size; + } + + secRead = anc_llb_read_phys_page(BOOT_BAND_LLB, BOOT_DIP_LLB, page, thisSize, data, &meta[0]); + if ((secRead == 0) || (secReadsecPerPage)) { // only allow partial NAND page at the end of read + break; + } + size -= thisSize; + page++; + data += thisSize * BOOT_BYTES_PER_SEC; + } + + return( (max_size - size) / secPerPage ); +} +#endif + +#if WITH_LLB_NVRAM +static int anc_read_nvram_block (struct blockdev *_dev, void *data, block_addr offset, uint32_t sectors) { + + uint32_t slot; + uint32_t slotB; // offset for the B copy of FW. 0 indicates not doing retry + uint32_t pslot; + uint32_t page; + uint32_t band; + uint32_t dip; + uint32_t thisSize; + uint32_t secPerPage; + uint32_t pagePerSlot; + uint32_t err; + uint32_t max_size; + + // Incoming sectors are in terms of page size (to prevent the client from + // attempting a sub-page read). + sectors *= 2; // blocksize is 8k not 4k + + dprintf(DEBUG_INFO,"Reading sectors from NVRAM element from offset=%4d for a size=%4d\n", offset, sectors); + + if(BOOT_UTIL_MAJOR != UtilDM->s.utilMajor) { + dprintf(DEBUG_CRITICAL,"Exiting anc_read_fw because UtilDM->s.utilMajor is incorrect\n"); + return(0); + } + if(offset > 0) { + dprintf(DEBUG_CRITICAL,"Requested offset exceeds size of nvram\n"); + return(0); + } + + if(sectors + offset > UtilDM->s.eSize[BOOT_ELEMENT_NVRAM]) { + dprintf(DEBUG_CRITICAL,"Attempt to read past end of nvram\n"); + return(0); + } + + meta[META_LBA_INDEX] = BOOT_LBA_TOKEN_NVRAM; + secPerPage = UtilDM->s.secPerPage; + pagePerSlot = UtilDM->s.numPages; + + page = Util.location[BOOT_ELEMENT_NVRAM].page; // starting location for NVRAM in [slot,page] + slot = Util.location[BOOT_ELEMENT_NVRAM].slot; + + err = 0; + slotB = 0; + + max_size = sectors; // save for result + if (page==0 && slot==0) {// NVRAM not populated + sectors=0; + } + while(sectors) { + pslot = Boot_Slip(slot+slotB); + Boot_BandDip(pslot, &band, &dip); + + thisSize = sectors; + if(thisSize > secPerPage) { + thisSize = secPerPage; + } + + if(!anc_llb_read_phys_page(band, dip, page, thisSize, data, &meta[0])) { + dprintf(DEBUG_CRITICAL,"Failed to read page\n"); + if(!slotB) { + slotB = 1; + } else { + break; + } + } else { + slotB = 0; + sectors -= thisSize; + + data += thisSize * BOOT_BYTES_PER_SEC; + page++; + if(page >= pagePerSlot) { + page=0; + slot++; + if (sectors) { // still more to read? + err=1; + break; + } + } + } + } + if(err) { + dprintf(DEBUG_CRITICAL,"Encountered error = %d\n", err); + } + + return (max_size - sectors) / 2; +} + + + + +uint32_t Boot_Find_Fast_Scan(void *buffer, uint32_t page, uint32_t slot) { + uint32_t element; + uint32_t ElementSizePages; + + if (0 == page) { + UtilDM->version = 1; + } + + for (; page < UtilDM->s.numPages;) { + meta[0] = BOOT_LBA_TOKEN_UNKNOWN; + if (Boot_Read(buffer,page,slot,meta)) { + if ((meta[0] >= BOOT_LBA_TOKEN_FAST_FIRST) && (meta[0] <= BOOT_LBA_TOKEN_FAST_LAST)) { + + element = meta[0] - BOOT_LBA_TOKEN_ELEMENTS; + dprintf(DEBUG_INFO,"UTIL_MINOR - [%2d,%2d] Found %d\n", slot, page, element); + + if (0 == UtilDM->s.eSize[element]) { + dprintf(DEBUG_CRITICAL,"UTIL - Element of unknown size!!! \n"); + page++; + } else { + if (element == BOOT_ELEMENT_UTILDM) { + Boot_PostProcessDM(buffer,page,slot,meta); + } else { + Util.location[element].slot = slot; + Util.location[element].page = page; + dprintf(DEBUG_INFO,"UTIL_MINOR - Found location [%2d,%2d] for element %d\n", Util.location[element].slot, + Util.location[element].page,element); + } + + page += quantup(UtilDM->s.eSize[element], UtilDM->s.secPerPage); + } + } else if (!((meta[0] >= BOOT_LBA_TOKEN_FAST_FIRST) && (meta[0] <= BOOT_LBA_TOKEN_FAST_LAST)) && (meta[0] < BOOT_LBA_TOKEN_UNKNOWN)) { + element = meta[0] - BOOT_LBA_TOKEN_ELEMENTS; + ElementSizePages = 0; + + if (element < UTIL_NUM_ELEMENT) { + ElementSizePages = quantup(UtilDM->s.eSize[element], UtilDM->s.secPerPage); + } + + if ((ElementSizePages == 0) || ((page + ElementSizePages) > UtilDM->s.numPages)) { + dprintf(DEBUG_CRITICAL,"UTIL - [%2d,%2d] Something Broken, UtilDM->s.eSize[%d]=%d!!\n", slot, page, element, + ElementSizePages); + page = 0; + break; + + } else { + dprintf(DEBUG_CRITICAL,"Skipping unknown element %d\n", element); + } + + page += ElementSizePages; + } + } + else + { + if ( BOOT_ERR_BLANK != meta[0]) { // something ugly ?, either unknown LBA value or unc + dprintf(DEBUG_CRITICAL,"UTIL - [%2d,%2d] Something Broken !! meta=%x\n", slot, page, meta[0]); + page = 0; + } else { + dprintf(DEBUG_INFO,"UTIL_MINOR - [%2d,%2d] Blank !!\n", slot, page); + } + break; + } + } + return page; +} + + +// passed in a single sector seg with buffer allocated +void Boot_Find_Fast(void *buffer) { + uint32_t page; + uint32_t slot, tmpslot; + uint32_t element; + + tmpslot = slot = Util.location[BOOT_ELEMENT_UTILDM].slot;// slot with the highest version UtilDM + if ((BOOT_SLOT_FAST_B == slot) && (BOOT_SLOT_FAST_A == Util.prevUtilDMslot) && (Util.prevUtilDMversion == UtilDM->version)) { // NORMAL state + slot = BOOT_SLOT_FAST_A; + page = Boot_Find_Fast_Scan(buffer, 1, slot); + + if (page) { + slot = BOOT_SLOT_FAST_B; // read copy B + meta[0] = BOOT_LBA_TOKEN_UNKNOWN; + + if (!Boot_Read(buffer,page-1,slot,meta)) { + dprintf(DEBUG_INFO,"UTIL - Fast Copy B last page broken!\n"); + page = 0; + } else if (page < UtilDM->s.numPages) { // last written page of B is ok, check next page is blank + slot = BOOT_SLOT_FAST_B; + meta[0] = BOOT_LBA_TOKEN_UNKNOWN; + if (!Boot_Read(buffer,page,slot,meta) && meta[0]!=BOOT_ERR_BLANK) { + dprintf(DEBUG_CRITICAL,"UTIL - Fast Copy B next location not Blank!!\n"); + page = 0; + } + } + } + } else { + // spew enough data to know why we failed the IF term. + dprintf(DEBUG_CRITICAL,"UTIL - FastA:%2d slot:%2d prevSlot:%2d prevV:%08x currV:%08x\n", + BOOT_SLOT_FAST_A, slot, Util.prevUtilDMslot, + Util.prevUtilDMversion, UtilDM->version); + + + if ((BOOT_SLOT_LLB != Util.prevUtilDMslot) && !(!Util.BCopyPresent && (BOOT_SLOT_FAST_B == Util.prevUtilDMslot))) { + /*Scan the older copy first*/ + slot = Util.prevUtilDMslot; + Boot_Find_Fast_Scan(buffer, 0, slot); + } + + slot = tmpslot; + Boot_Find_Fast_Scan(buffer, 0, slot); + page = 0; + } + + for (element = BOOT_ELEMENT_FAST_FIRST; element <= BOOT_ELEMENT_FAST_LAST; element++) { + dprintf(DEBUG_INFO,"UTIL - Location [%2d,%2d] for element %d\n", Util.location[element].slot, Util.location[element].page, + element); + } +} + + + +bool Boot_Read(void *buffer, uint32_t page, uint32_t slot, uint32_t *meta) +{ + uint32_t band, dip; + uint32_t pslot = Boot_Slip(slot);//+slotB); + Boot_BandDip(pslot, &band, &dip); + + return (anc_llb_read_phys_page(band, dip, page, 1, buffer, &meta[0])); +} + +void Boot_Find_UtilDM(void *buffer) +{ + + uint32_t firstSlot = Util.location[BOOT_ELEMENT_UTILDM].slot; + uint32_t slot, page; + + UtilDM->s.numSlots = 32; //UTIL_BLIND_SEARCH; + page=0; + + for (slot = BOOT_SLOT_FAST_A; slot < UtilDM->s.numSlots;) { + + if (slot == UtilDM->pendDefect) { + slot++; + continue; + } + meta[0]=BOOT_LBA_TOKEN_UNKNOWN; + Boot_Read(buffer,page,slot,meta); + + if (Boot_PostProcessDM(buffer,page,slot,meta)) { + dprintf(DEBUG_INFO,"UTIL - defect growth\n"); // don't assume that we're aligned. + slot = BOOT_SLOT_FAST_A; // start over + Util.location[BOOT_ELEMENT_UTILDM].slot = firstSlot; // and assimlate again. + } else { + slot++; + } + } + + if (0 == UtilDM->version) { // found nothing? + dprintf(DEBUG_CRITICAL,"UTIL - Found no UtilDM!!! Nand should be blank\n"); + UtilDM->s.numSlots = 0; // then reset numSlots + UtilDM->s.numDefects = 0; + } +} + +#endif diff --git a/drivers/apple/anc/util_boot.h b/drivers/apple/anc/util_boot.h new file mode 100644 index 0000000..70761d2 --- /dev/null +++ b/drivers/apple/anc/util_boot.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef ASPsim_utilBoot_h +#define ASPsim_utilBoot_h + + + +#define UTIL_NUM_ELEMENT (12) +#define UTIL_NUM_PSLOTS (128) +#define UTIL_NO_DEFECT (0xff) +typedef struct { + uint8_t utilMajor; + uint8_t utilMinor; + uint16_t eSize[UTIL_NUM_ELEMENT]; // element size in sectors, 0 if never written. + uint8_t defects[UTIL_NUM_PSLOTS]; + uint16_t numDefects; + uint16_t numPages; + uint8_t secPerPage; + uint8_t numPlanes; + uint8_t numDie; + uint8_t numSlots; + uint8_t sizeFWslots; // size of the firmware element in slot granularity + uint8_t RFU[8]; // reserved for future use +}UtilBootDM_t; + +#define BOOT_NO_DEFECT (0xff) + +#define BOOT_LBA_TOKEN_BASE 0xFF00000 +#define BOOT_LBA_TOKEN_UTILNOP (BOOT_LBA_TOKEN_BASE + 1) +#define BOOT_LBA_TOKEN_ELEMENTS (BOOT_LBA_TOKEN_BASE + 2) +#define BOOT_LBA_TOKEN_LLB (BOOT_LBA_TOKEN_BASE + 2) +#define BOOT_LBA_TOKEN_FW (BOOT_LBA_TOKEN_BASE + 3) +#define BOOT_LBA_TOKEN_UTILDM (BOOT_LBA_TOKEN_BASE + 4) +#define BOOT_LBA_TOKEN_DM (BOOT_LBA_TOKEN_BASE + 0x05) +#define BOOT_LBA_TOKEN_CTRLBITS (BOOT_LBA_TOKEN_BASE + 0x06) +#define BOOT_LBA_TOKEN_EFFACEABLE (BOOT_LBA_TOKEN_BASE + 0x07) +#define BOOT_LBA_TOKEN_NVRAM (BOOT_LBA_TOKEN_BASE + 0x08) +#define BOOT_LBA_TOKEN_SYSCFG (BOOT_LBA_TOKEN_BASE + 0x09) +#define BOOT_LBA_TOKEN_PANICLOG (BOOT_LBA_TOKEN_BASE + 0x0A) +#define BOOT_LBA_TOKEN_UNKNOWN (BOOT_LBA_TOKEN_BASE + 0x10) + +#define BOOT_LBA_TOKEN_FAST_FIRST BOOT_LBA_TOKEN_UTILDM +#define BOOT_LBA_TOKEN_FAST_LAST BOOT_LBA_TOKEN_PANICLOG + + +#define BOOT_ELEMENT_UTILDM (2) +#define BOOT_BAND_UTILDM (0) +#define BOOT_DIP_UTILDM (0) +#define BOOT_PAGE_UTILDM (0) +#define BOOT_SIZE_UTILDM (1) + +#define BOOT_ELEMENT_LLB (0) +#define BOOT_BAND_LLB (0) +#define BOOT_DIP_LLB (0) +#define BOOT_PAGE_LLB (1) +#define BOOT_SIZE_LLB (UtilDM->s.eSize[BOOT_ELEMENT_LLB]) + +#define BOOT_ELEMENT_FW (1) +#define BOOT_SLOT_FW (1) +#define BOOT_PAGE_FW (0) +#define BOOT_SIZE_FW (UtilDM->s.eSize[BOOT_ELEMENT_FW]) + +#define BOOT_ELEMENT_NVRAM (6) +#define BOOT_BYTES_PER_SEC (4096) + +#define BOOT_NO_ERROR (0) +#define BOOT_ERR_ABORT (10) +#define BOOT_UTIL_MAJOR (8) // MUST match AppleStorageProcessor/src/aspcore/core/format.h + +#define BOOT_ELEMENT_FAST_FIRST BOOT_ELEMENT_UTILDM +#define BOOT_ELEMENT_FAST_LAST BOOT_ELEMENT_NVRAM + +#define BOOT_SLOT_LLB 0 + +#define BOOT_SLOT_FW_A_FIRST 1 +#define BOOT_SLOT_FW_A_LAST (BOOT_SLOT_FW_A_FIRST + (1 * UtilDM->s.sizeFWslots) - 1) +#define BOOT_SLOT_FW_B_LAST (BOOT_SLOT_FW_A_FIRST + (2 * UtilDM->s.sizeFWslots) - 1) + + +#define BOOT_SLOT_SYSCFG_A (BOOT_SLOT_FW_B_LAST + 1) +#define BOOT_SLOT_SYSCFG_B (BOOT_SLOT_SYSCFG_A + 1) + +#define BOOT_SLOT_FAST_A (BOOT_SLOT_SYSCFG_B + 1) +#define BOOT_SLOT_FAST_B (BOOT_SLOT_FAST_A + 1) + +#define BOOT_SLOT_PANICLOG (BOOT_SLOT_FAST_B + 1) + +#define BOOT_ERR_BLANK 0xffffffff +#endif + diff --git a/drivers/apple/apcie/apcie.c b/drivers/apple/apcie/apcie.c new file mode 100644 index 0000000..bc88855 --- /dev/null +++ b/drivers/apple/apcie/apcie.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef APCIE_DEBUG_LEVEL +#define DEBUG_LEVEL APCIE_DEBUG_LEVEL +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct apcie_link_status apcie_link_statuses[APCIE_NUM_LINKS]; +struct apcie_link_config *apcie_link_configs; + +static pci_device_t host_bridge; +static pci_device_t port_bridges[APCIE_NUM_LINKS]; + +void apcie_config_read_raw(void *dst, uint32_t bdfo, int size) +{ + uintptr_t addr = PCI_CONFIG_BASE | bdfo; + uint32_t value; + + dprintf(DEBUG_SPEW, "apcie_config_read[0x%lx, %d]", addr, size); + + switch (size) { + case 1: + *(uint8_t *)dst = *(volatile uint8_t *)addr; + value = *(uint8_t *)dst; + break; + case 2: + *(uint16_t *)dst = *(volatile uint16_t *)addr; + value = *(uint16_t *)dst; + break; + case 4: + *(uint32_t *)dst = *(volatile uint32_t *)addr; + value = *(uint32_t *)dst; + break; + default: + panic("apcie_config_read: invalid size %d", size); + } + + dprintf(DEBUG_SPEW, " = 0x%x\n", value); +} + +static void apcie_config_read(void *priv, void *dst, uint32_t bdfo, int size) +{ + struct apcie_link_status *link_status = (struct apcie_link_status *)priv; + + if (link_status == NULL && apcie_get_link_enable_count() == 0) { + panic("apcie: config read with no links enabled"); + memset(dst, 0xff, size); + return; + } + if (link_status != NULL && !link_status->enabled) { + panic("apcie: config read from disabled link"); + memset(dst, 0xff, size); + return; + } + + apcie_config_read_raw(dst, bdfo, size); +} + +void apcie_config_write_raw(const void *src, uint32_t bdfo, int size) +{ + uintptr_t addr = PCI_CONFIG_BASE | bdfo; + switch (size) { + case 1: + dprintf(DEBUG_SPEW, "apcie_config_write[0x%lx, %d] = 0x%x\n", + addr, size, *(uint8_t *)src); + *(volatile uint8_t *)addr = *(uint8_t *)src; + break; + case 2: + dprintf(DEBUG_SPEW, "apcie_config_write[0x%lx, %d] = 0x%x\n", + addr, size, *(uint16_t *)src); + *(volatile uint16_t *)addr = *(uint16_t *)src; + break; + case 4: + dprintf(DEBUG_SPEW, "apcie_config_write[0x%lx, %d] = 0x%x\n", + addr, size, *(uint32_t *)src); + *(volatile uint32_t *)addr = *(uint32_t *)src; + break; + default: + panic("apcie_config_read: invalid size %d", size); + } +} + +static void apcie_config_write(void *priv, const void *src, uint32_t bdfo, int size) +{ + struct apcie_link_status *link_status = (struct apcie_link_status *)priv; + + if (link_status == NULL && apcie_get_link_enable_count() == 0) { + panic("apcie: config write with no links enabled"); + } + if (link_status != NULL && !link_status->enabled) { + panic("apcie: config write to disabled link"); + } + + apcie_config_write_raw(src, bdfo, size); +} + +/* Configure the virtual PCI2PCI bridge associated with the port. */ +void apcie_setup_root_port_bridge(uint32_t link, struct apcie_link_config *config) +{ + pci_device_t bridge; + uint8_t header_type; + + dprintf(DEBUG_INFO, "apcie: Probing port bridge for link %d\n", link); + + ASSERT(port_bridges[link] == 0); + + bridge = pci_bridge_probe(host_bridge, link, 100); + if (bridge == NULL) { + panic("apcie: failed to probe port bridge on link %u\n", link); + } + + header_type = pci_get_header_type(bridge); + if (header_type != 1) { + panic("PCI2PCI bridge has wrong header type %d (expected 1)", header_type); + } + + pci_bridge_assign_secondary_bus(bridge); + + pci_bus_master_enable(bridge, true); + pci_memory_space_enable(bridge, true); + pci_bridge_serr_enable(bridge, true); + + port_bridges[link] = bridge; +} + +void apcie_disable_all(void) +{ + for (int i = 0; i < APCIE_NUM_LINKS; i++) + apcie_disable_link(i); +} + +void apcie_init(void) +{ + uint32_t memory_base; + // At some point, we may allow targets to override the PCI + // configuration, but this will do for now + apcie_link_configs = platform_apcie_link_configs; + + memory_base = platform_map_host_to_pci_addr(PCI_32BIT_BASE); + host_bridge = pci_create_host_bridge("host bridge", 0, memory_base, PCI_32BIT_LEN, + NULL, apcie_config_read, apcie_config_write); +} + +pci_device_t apcie_get_port_bridge(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + return port_bridges[link]; +} + +void apcie_free_port_bridge(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + if (port_bridges[link] != NULL) { + pci_free(port_bridges[link]); + port_bridges[link] = NULL; + } +} + +static int do_apcie_debug_cmd(int argc, struct cmd_arg *args) +{ + int result = -1; + int link; + const char *cmd = args[1].str; + + if (cmd == NULL) { + result = -1; + } else { + if (strcmp(cmd, "enable") == 0 && argc == 3) { + link = args[2].n; + if (link >= 0 && link < APCIE_NUM_LINKS) { + apcie_enable_link(link); + result = 0; + } + } else if (strcmp(cmd, "disable") == 0 && argc == 3) { + link = args[2].n; + if (link >= 0 && link < APCIE_NUM_LINKS) { + apcie_disable_link(link); + result = 0; + } + } else if (strcmp(cmd, "counters") == 0 && argc == 4) { + link = args[3].n; + if (strcmp(args[2].str, "read") == 0 && + link >= 0 && link < APCIE_NUM_LINKS) { + if (apcie_link_statuses[link].enabled) { + rAPCIE_COUNTER_COMMAND(link) = APCIE_COUNTER_ENABLE | APCIE_COUNTER_CAPTURE; + printf("time_L0:\t%u\n", rAPCIE_COUNTER_VALUE(link, 0)); + printf("time_L1:\t%u\n", rAPCIE_COUNTER_VALUE(link, 1)); + printf("time_L1.1:\t%u\n", rAPCIE_COUNTER_VALUE(link, 2)); + printf("time_L1.2:\t%u\n", rAPCIE_COUNTER_VALUE(link, 3)); + printf("entry_L0:\t%u\n", rAPCIE_COUNTER_VALUE(link, 4)); + printf("entry_L1:\t%u\n", rAPCIE_COUNTER_VALUE(link, 5)); + printf("entry_L1.1:\t%u\n", rAPCIE_COUNTER_VALUE(link, 6)); + printf("entry_L1.2:\t%u\n", rAPCIE_COUNTER_VALUE(link, 7)); + } else { + printf("link not enabled\n"); + } + result = 0; + } else if(strcmp(args[2].str, "reset") == 0 && + link >= 0 && link < APCIE_NUM_LINKS) { + if (apcie_link_statuses[link].enabled) { + rAPCIE_COUNTER_COMMAND(link) = APCIE_COUNTER_ENABLE | APCIE_COUNTER_CLEAR; + } else { + printf("link not enabled\n"); + } + result = 0; + } + + } + } + + if (result < 0) { + printf("Usage:\n"); + printf("\tenable \t\t - Enables the specified link\n"); + printf("\tdisable \t\t - Disables the specified link\n"); + printf("\tcounters read \t - Reads counters for the specified link\n"); + printf("\tcounters reset \t - Resets counters for the specified link\n"); + } + + return result; +} + +MENU_COMMAND_DEBUG(apcie, do_apcie_debug_cmd, "APCIe debug commands", NULL); diff --git a/drivers/apple/apcie/rules.mk b/drivers/apple/apcie/rules.mk new file mode 100644 index 0000000..a931171 --- /dev/null +++ b/drivers/apple/apcie/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_APCIE=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/apcie.o diff --git a/drivers/apple/asp/asp.c b/drivers/apple/asp/asp.c new file mode 100644 index 0000000..b429a9e --- /dev/null +++ b/drivers/apple/asp/asp.c @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define ASP_TARGET_RTXC 1 +#define CASSERT(x, name) typedef char __ASP_CASSERT_##name[(x) ? 1 : -1] +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !SUPPORT_FPGA +#include +#endif +#include "common_util.h" + + +// +// Defines +// +#define MY_ASP_PROTOCOL_VERSION 10 +CASSERT(ASP_PROTOCOL_VERSION == MY_ASP_PROTOCOL_VERSION, protocol_versions_match); + +// +// Prototypes +// + +static bool asp_get_nand_info(void); + +// +// Globals +// + +asp_t asp; +aspproto_nand_geom_t nand_info; +struct blockdev *asp_nand_dev; +struct blockdev *asp_nvram_dev; +struct blockdev *asp_firmware_dev; +struct blockdev *asp_llb_dev; +struct blockdev *asp_effaceable_dev; +struct blockdev *asp_syscfg_dev; +struct blockdev *asp_paniclog_dev; + +static int asp_set_atv(void) +{ + aspproto_cmd_t * command; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_SETOPTIONS; + command->opts.isATV = true; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to set atv mode\n"); + return -1; + } + return 0; +} + +int asp_init(void) +{ + + csi_status_t result; + + asp.state = ASP_STATE_INITIALIZING; + asp.writable = false; + asp_nand_dev = NULL; + asp_nvram_dev = NULL; + asp_firmware_dev = NULL; + asp_llb_dev = NULL; + asp_effaceable_dev = NULL; + asp_syscfg_dev = NULL; + asp_paniclog_dev = NULL; + + + event_init(&asp.msg_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + result = csi_register_endpoint(CSI_COPROC_ANS, IPC_ENDPOINT_ASP, &asp.msg_event, &asp.csi_token, &asp.ep_name); + + if (result != CSI_STATUS_OK) + { + asp.state = ASP_STATE_ERROR_CRITICAL; + dprintf(DEBUG_CRITICAL, "Failed to register ASP endpoint"); + return -1; + } + +#if !ASP_ENABLE_TIMEOUTS + dprintf(DEBUG_CRITICAL, "ASP Timeouts disabled!\n"); +#endif + + if (!asp_wait_for_ready()) + { + asp.state = ASP_STATE_ERROR_CRITICAL; + return -1; + } + + if (!asp_init_tags()) + { + asp.state = ASP_STATE_ERROR_CRITICAL; + return -1; + } + + if (!asp_get_geometry()) + { + // need to create dummy NVRAM device anyways to prevet iBoot panic + asp_create_block_device(ASP_NVRAM); + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + return -1; + } + + if (!asp_get_nand_info()) + { + dprintf(DEBUG_CRITICAL, "asp_get_nand_info failed\n"); + } + + asp_reinit(); + + if (!asp_create_block_device(ASP_NVRAM)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + return -1; + } + +#if TARGET_POWER_NO_BATTERY + if (asp_set_atv() != 0) { + return -1; + } +#endif + + asp_create_block_device(ASP_FIRMWARE); + + asp_create_block_device(ASP_LLB); + + asp_create_block_device(ASP_EFFACEABLE); + + asp_create_block_device(ASP_SYSCFG); + + asp_create_block_device(ASP_PANICLOG); + + asp.state = ASP_STATE_READY; + + return 0; + +} + +bool asp_wait_for_ready(void) +{ + + msg_payload_t msg; + uint32_t tag; + csi_status_t result; + +#if ASP_ENABLE_TIMEOUTS +if (!event_wait_timeout(&asp.msg_event, ASP_READY_TIMEOUT_US)) + { + dprintf(DEBUG_CRITICAL, "ASP timed out waiting for hardware to become ready!"); + asp.state = ASP_STATE_TIMEOUT; + return false; + } +#else + event_wait(&asp.msg_event); +#endif + + result = csi_receive_message(asp.csi_token, &msg); + if (result != CSI_STATUS_OK) + { + return false; + } + + tag = ASPMBOX_FIN_GET_TAG(msg); + if (tag != ASPMBOX_TAG_AWAKE) + { + return false; + } + + else + { + if (ASPMBOX_FIN_GET_ERRCODE(msg) != ASP_PROTOCOL_VERSION) + { + dprintf(DEBUG_CRITICAL, "iBoot ASP protocol version %d aspcore protocol version %lld", + ASP_PROTOCOL_VERSION, ASPMBOX_FIN_GET_ERRCODE(msg)); + return false; + } + } + + return true; + +} + + +bool asp_init_tags(void) +{ + + addr_t paddr; + uint64_t payload; + uint32_t i; + + asp.asp_command = csi_allocate_shared_memory(asp.csi_token, + ASP_NUM_TAGS * ASPPROTO_CMD_LINES * CACHELINE_BYTES); + + if (!asp.asp_command) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate ASP command memory"); + asp.asp_command = NULL; + return false; + } + + paddr = mem_static_map_physical((addr_t)asp.asp_command); + + payload = ASPMBOX_MAKE_CMD_SETBASE((uint64_t)paddr, ASP_NUM_TAGS * ASPPROTO_CMD_LINES); + + dprintf(DEBUG_CRITICAL, "Using paddr %p, setbase message 0x%016llx\n", (void *)paddr, payload); + + if (csi_send_message(asp.csi_token, payload) != CSI_STATUS_OK) + { + dprintf(DEBUG_CRITICAL, "Unable to send ASPMBOX_MASK_CMD_SETBASE message\n"); + return false; + } + + for (i = 0; i < ASP_NUM_TAGS; i++) + { + aspproto_cmd_t *cmd; + + payload = ASPMBOX_MAKE_CMD_SETADDR(i, (i * ASPPROTO_CMD_LINES), ASPPROTO_CMD_LINES); + + if (csi_send_message(asp.csi_token, payload) != CSI_STATUS_OK) + { + dprintf(DEBUG_CRITICAL, "Unable to send ASPMBOX_MAKE_CMD_SETADDR message\n"); + return false; + } + + cmd = asp_get_cmd_for_tag(i); + cmd->tag = i; + } + + return true; + +} + + +static bool asp_get_nand_info(void) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASP_PROTO_CMD_DEVICE_INFO; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to read ASP device info\n"); + return false; + } + + if(command->nand_info.size > sizeof(nand_info)) + { + panic ("nand info size exceeded\n"); + } + memcpy(&nand_info, command->nand_info.data, command->nand_info.size); + + return true; +} + +bool asp_send_open(void) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + int status; + + command->op = ASPPROTO_CMD_OPEN; + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to open ASP: 0x%08x\n", status); + return false; + } + + return true; +} + +int asp_nand_open(void) +{ + if (asp.state != ASP_STATE_READY) + { + return -1; + } + + if (!asp_send_open()) + { + return -1; + } + + // NOTE: Need to get NAND geometry again after sending an OPEN + // command to ASP to ensure that the lbaFormatted field is + // correctly updated after CLOG replay + if (!asp_get_geometry()) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + return -1; + } + + if (!asp_create_block_device(ASP_NAND)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + return -1; + } + + partition_scan_and_publish_subdevices("asp_nand"); + + return 0; + +} + +int asp_set_default_dies_in_parallel(void) +{ + asp_set_dies_in_parallel(ASPNAND_SLC_WRITE_DIES_IN_PARALLEL, + ASPNAND_READ_DIES_IN_PARALLEL, + ASPNAND_ERASE_DIES_IN_PARALLEL, + ASPNAND_MLC_WRITE_DIES_IN_PARALLEL, + ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL, + ASPNAND_TLC_READ_DIES_IN_PARALLEL, + ASPNAND_TLC_ERASE_DIES_IN_PARALLEL, + ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL, + CORE_POWERSTATE_HIGH_POWER); + + asp_set_dies_in_parallel(ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL, + ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL, + ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL, + ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL, + ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL, + ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL, + ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL, + ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL, + CORE_POWERSTATE_LOW_POWER); + + asp_set_power_state(CORE_POWERSTATE_HIGH_POWER); + + return 0; +} + +int asp_disable_uid(void) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_DISABLE_UID; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = (1 << ANC_MAX_BUSSES) - 1; + + dprintf(DEBUG_CRITICAL, "Disabling ANS UID keys\n"); + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to disable UID keys\n"); + return -1; + } + return 0; +} + diff --git a/drivers/apple/asp/common_util.c b/drivers/apple/asp/common_util.c new file mode 100644 index 0000000..67ff683 --- /dev/null +++ b/drivers/apple/asp/common_util.c @@ -0,0 +1,1258 @@ + /* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define ASP_TARGET_RTXC 1 +#define CASSERT(x, name) typedef char __ASP_CASSERT_##name[(x) ? 1 : -1] +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common_util.h" +#include + +extern asp_t asp; +extern aspproto_nand_geom_t nand_info; +extern struct blockdev *asp_nand_dev; +extern struct blockdev *asp_nvram_dev; +extern struct blockdev *asp_firmware_dev; +extern struct blockdev *asp_llb_dev; +extern struct blockdev *asp_effaceable_dev; +extern struct blockdev *asp_syscfg_dev; +extern struct blockdev *asp_paniclog_dev; + +char *asp_names[] = {"unknown", "NAND", "NVRAM", "FIRMWARE", "LLB", "EFFACEABLE", "SYSCFG", "PANICLOG"}; + + +aspproto_cmd_t * asp_get_cmd_for_tag(uint32_t tag) +{ + + uint8_t * base = (uint8_t *) asp.asp_command; + uint8_t * offset = NULL; + + if (tag > ASP_NUM_TAGS) + { + panic("Invalid tag %d given to asp_get_cmd_for_tag!\n", tag); + } + + offset = base + (tag * ASPPROTO_CMD_LINES * CACHELINE_BYTES); + + memset(offset, 0x00, ASPPROTO_CMD_LINES * CACHELINE_BYTES); + ((aspproto_cmd_t *)offset)->tag = tag; + + return ((aspproto_cmd_t *)offset); + +} + +#if WITH_NON_COHERENT_DMA + +int asp_send_command(uint32_t tag) +{ + uint32_t cmd_mem_size; + void *cmd_mem_base; + int return_val; + + cmd_mem_size = ASPPROTO_CMD_LINES * CACHELINE_BYTES; + cmd_mem_base = (void*)((uintptr_t)asp.asp_command + (tag * cmd_mem_size)); + + platform_cache_operation(CACHE_CLEAN, cmd_mem_base, cmd_mem_size); + + if (csi_send_message(asp.csi_token, ASPMBOX_MAKE_CMD_NEW1(tag)) != CSI_STATUS_OK) + { + return ASPPROTO_CMD_STATUS_TIMEOUT; + } + + return_val = asp_wait_for_completion(tag); + platform_cache_operation(CACHE_INVALIDATE, cmd_mem_base, cmd_mem_size); + + return return_val; +} + +#else + +int asp_send_command(uint32_t tag) +{ + uint64_t payload; + + payload = ASPMBOX_MAKE_CMD_NEW1(tag); + + if (csi_send_message(asp.csi_token, payload) != CSI_STATUS_OK) + { + return ASPPROTO_CMD_STATUS_TIMEOUT; + } + + return asp_wait_for_completion(tag); +} +#endif + + +int asp_wait_for_completion(uint32_t tag) +{ + + msg_payload_t msg; + uint32_t rx_type; + uint32_t rx_tag; + uint32_t status; + csi_status_t result; + +again: + +#if ASP_ENABLE_TIMEOUTS + if (!event_wait_timeout(&asp.msg_event, ASP_IO_TIMEOUT_US)) + { + dprintf(DEBUG_CRITICAL, "ASP - I/O timed out for tag %d!", tag); + asp.state = ASP_STATE_TIMEOUT; + return ASPPROTO_CMD_STATUS_TIMEOUT; + } +#else + event_wait(&asp.msg_event); +#endif + + result = csi_receive_message(asp.csi_token, &msg); + + if (result != CSI_STATUS_OK) + { + // REVISIT - Change this after defining ASPPROTO_CMD_STATUS_ERROR + return -1; + } + + rx_type = ASPMBOX_GET_TYPE(msg); + + switch (rx_type) + { + case ASPMBOX_TYPE_CMD_FIN : + { + rx_tag = ASPMBOX_FIN_GET_TAG(msg); + + if (tag != rx_tag) + { + // REVISIT - Change this after defining ASPPROTO_CMD_STATUS_ERROR + status = -1; + } + else + { + status = ASPMBOX_FIN_GET_ERRCODE(msg); + } + + break; + } + + case ASPMBOX_TYPE_CMD_UNSOLICITED : + { + // ignore and try again + goto again; + break; + } + + default : + { + dprintf(DEBUG_CRITICAL, "Invalid message type %d received", rx_type); + status = -1; + } + } + + return status; + +} + +bool asp_set_writable(void) +{ + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_SETWRITABLE; + + asp.writable = false; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + + dprintf(DEBUG_CRITICAL, "ASP setWritable Failed\n"); + return false; + + } + + asp.writable = true; + printf("******IMPORTANT NOTE: IBOOT CAN NOW WRITE TO NAND AND POTENTIALLY CHANGE STATE OF THE DRIVE\n"); + printf(" REBOOT IF THIS IS NOT WHAT YOU INTENDED\n"); + + return true; + +} + +bool asp_get_geometry(void) +{ + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_GET_GEOM; + + while ( 1 ) + { + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to read ASP geometry\n"); + return false; + } + + if ( command->geom.pendingLoad != 0 ) + { + dprintf(DEBUG_CRITICAL, "ASP: Pending load is set in geometry. Will retry in 50ms\n" ); + task_sleep ( 50 * 1000 ); // sleep for 50mS. + } + + else + { + break; + } + } + + asp.num_lbas = command->geom.num_lbas; + asp.bytes_per_lba = command->geom.bytes_per_lba; + asp.lastUserBand = command->geom.lastUserBand; + asp.lastBand = command->geom.lastBand; + asp.numVirtualSLCBonfireBands = command->geom.numVirtualSLCBonfireBands; + asp.firstIntermediateBand = command->geom.firstIntermediateBand; + asp.lastIntermediateBand = command->geom.lastIntermediateBand; + if (command->geom.utilFormatted) asp.util_formatted = true; + if (command->geom.lbaFormatted) asp.lba_formatted = true; + + memcpy(asp.chip_id, command->geom.chip_id, ANC_MAX_BUSSES * ANC_NAND_ID_SIZE); + memcpy(asp.mfg_id, command->geom.mfg_id, ANC_MAX_BUSSES * ANC_NAND_ID_SIZE); + dprintf(DEBUG_CRITICAL, "ASP Block Device %d lbas, %d bytes per lba, utilFormatted:%d lbaFormatted:%d\n", + asp.num_lbas, asp.bytes_per_lba, asp.util_formatted, asp.lba_formatted); + + if (command->geom.total_user_lbas == 0) + return false; //asp init failed, don't publish a block device + + if (asp.state != ASP_STATE_READY) asp.state = ASP_STATE_INITIALIZED; + + return true; + +} + +bool asp_create_block_device(uint8_t type) +{ + + struct blockdev * blkdevice; + uint32_t result; + + if (((asp.util_formatted == false) && (type!=ASP_NVRAM)) || + ((asp.lba_formatted == false) && (type==ASP_NAND))) + { + dprintf(DEBUG_CRITICAL, "Cannot create blockdevice(%d) as media is not formatted!\n",type); + return false; + } + + blkdevice = calloc(1, sizeof(struct blockdev)); + + if (!blkdevice) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate blockdev\n"); + return false; + } + + switch (type) + { + + case ASP_NAND: + result = construct_blockdev(blkdevice, "asp_nand", (uint64_t)asp.num_lbas * asp.bytes_per_lba, asp.bytes_per_lba); + break; + + case ASP_NVRAM: + result = construct_blockdev(blkdevice, "nvram", (uint64_t)ASP_NVRAM_NUMBLKS * ASP_NVRAM_BLKSZ, ASP_NVRAM_BLKSZ); + break; + + case ASP_FIRMWARE: + result = construct_blockdev(blkdevice, "asp_fw", (uint64_t)ASP_FIRMWARE_NUMBLKS * ASP_FIRMWARE_BLKSZ, ASP_FIRMWARE_BLKSZ); + break; + + case ASP_LLB: + result = construct_blockdev(blkdevice, "asp_llb", (uint64_t)ASP_LLB_NUMBLKS * ASP_LLB_BLKSZ, ASP_LLB_BLKSZ); + break; + + case ASP_EFFACEABLE: + result = construct_blockdev(blkdevice, "asp_effaceable", (uint64_t)ASP_EFFACEABLE_NUMBLKS * ASP_EFFACEABLE_BLKSZ, ASP_EFFACEABLE_BLKSZ); + break; + + case ASP_SYSCFG: + result = construct_blockdev(blkdevice, "nand_syscfg", (uint64_t)ASP_SYSCFG_NUMBLKS * ASP_SYSCFG_BLKSZ, ASP_SYSCFG_BLKSZ); + break; + + case ASP_PANICLOG: + result = construct_blockdev(blkdevice, "paniclog", (uint64_t)ASP_PANICLOG_NUMBLKS * ASP_PANICLOG_BLKSZ, ASP_PANICLOG_BLKSZ); + break; + + default: + result = -1; + break; + + } + + if (result != 0) + { + dprintf(DEBUG_CRITICAL, "Failed to contruct blockdev\n"); + free(blkdevice); + return false; + } + + blkdevice->read_block_hook = &asp_read_block; + + if (type == ASP_NVRAM) + { + blkdevice->write_block_hook = &asp_write_block; + } + +#if !RELEASE_BUILD + if (type == ASP_LLB) + { + blkdevice->erase_hook = &asp_erase_block; + } +#endif + + if (type == ASP_PANICLOG) + { + blkdevice->write_block_hook = &asp_write_block; + } + +#if ASP_ENABLE_WRITES + else + { + blkdevice->write_block_hook = &asp_write_block; + + } +#endif + + if (register_blockdev(blkdevice) != 0) + { + dprintf(DEBUG_CRITICAL, "Failed to register blockdev\n"); + free(blkdevice); + return false; + } + + asp_set_blkdev_for_type(type, blkdevice); + + return true; + +} + +bool asp_set_photoflow_mode(core_flow_mode_e slc_mode) +{ + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_SET_PHOTOFLOW_MODE; + command->tunnel.options.value = (uint32_t) slc_mode; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to asp_enable_slc\n"); + return false; + } + return true; +} + +bool asp_enable_bg(void) +{ + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_ENABLE_BG; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to asp_enable_bg\n"); + return false; + } + return true; +} + +bool asp_disable_bg(void) +{ + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_DISABLE_BG; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to asp_disable_bg\n"); + return false; + } + return true; +} + +bool asp_set_dies_in_parallel(uint32_t mlc_slc_write_dies, + uint32_t mlc_read_dies, + uint32_t mlc_erase_dies, + uint32_t mlc_mlc_write_dies, + uint32_t tlc_slc_write_dies, + uint32_t tlc_read_dies, + uint32_t tlc_erase_dies, + uint32_t tlc_tlc_write_dies, + CorePowerState_e power_level) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + if (nand_info.num_bus==0) + { + return false; + } + + if (CORE_POWERSTATE_HIGH_POWER == power_level) { + command->tunnel.core_opcode = CORE_DEBUG_SET_MAX_DIES_IN_PARALLEL; + dprintf(DEBUG_SPEW, "setting for MLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,MLC_WRITE=%d) high power parallel per channel\n", + mlc_slc_write_dies / nand_info.num_bus, + mlc_read_dies / nand_info.num_bus, + mlc_erase_dies / nand_info.num_bus, + mlc_mlc_write_dies / nand_info.num_bus); + + dprintf(DEBUG_SPEW, "setting for TLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,TLC_WRITE=%d) high power parallel per channel\n", + tlc_slc_write_dies / nand_info.num_bus, + tlc_read_dies / nand_info.num_bus, + tlc_erase_dies / nand_info.num_bus, + tlc_tlc_write_dies / nand_info.num_bus); + } else if (CORE_POWERSTATE_LOW_POWER == power_level) { + command->tunnel.core_opcode = CORE_DEBUG_SET_LOW_POWER_MAX_DIES_IN_PARALLEL; + dprintf(DEBUG_SPEW, "setting for MLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,MLC_WRITE=%d) low power parallel per channel\n", + mlc_slc_write_dies / nand_info.num_bus, + mlc_read_dies / nand_info.num_bus, + mlc_erase_dies / nand_info.num_bus, + mlc_mlc_write_dies / nand_info.num_bus); + + dprintf(DEBUG_SPEW, "setting for TLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,TLC_WRITE=%d) low power parallel per channel\n", + tlc_slc_write_dies / nand_info.num_bus, + tlc_read_dies / nand_info.num_bus, + tlc_erase_dies / nand_info.num_bus, + tlc_tlc_write_dies / nand_info.num_bus); + } else { + dprintf(DEBUG_CRITICAL, "Powerlevel 0x%x is not configurable\n", power_level); + return false; + } + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = (1 << ANC_MAX_BUSSES) - 1; + command->tunnel.options.dies_in_parallel.mlc_mlc_write_dies = mlc_mlc_write_dies / nand_info.num_bus; + command->tunnel.options.dies_in_parallel.mlc_slc_write_dies = mlc_slc_write_dies / nand_info.num_bus; + command->tunnel.options.dies_in_parallel.mlc_erase_dies = mlc_erase_dies / nand_info.num_bus; + command->tunnel.options.dies_in_parallel.mlc_read_dies = mlc_read_dies / nand_info.num_bus; + command->tunnel.options.dies_in_parallel.tlc_tlc_write_dies = tlc_tlc_write_dies / nand_info.num_bus; + command->tunnel.options.dies_in_parallel.tlc_slc_write_dies = tlc_slc_write_dies / nand_info.num_bus; + command->tunnel.options.dies_in_parallel.tlc_erase_dies = tlc_erase_dies / nand_info.num_bus; + command->tunnel.options.dies_in_parallel.tlc_read_dies = tlc_read_dies / nand_info.num_bus; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to set dies in parallel\n"); + return false; + } + return true; +} + +bool asp_set_power_state(CorePowerState_e powerState) { + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_SET_POWER_STATE; + command->tunnel.options.value = powerState; + + dprintf(DEBUG_CRITICAL, "setting asp to high power mode\n"); + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "setting asp to high power failed\n"); + return false; + } + return true; +} + +bool asp_set_indirection_memory(uint32_t indirection_memory, uint32_t legacy_memory) { + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_SET_INDIRECTION_MEMORY; + command->tunnel.options.indirection_memory.heapIndMemory = indirection_memory; + command->tunnel.options.indirection_memory.legacyIndMemory = legacy_memory; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "setting indirection memory failed\n"); + return false; + } + return true; +} + +bool asp_test_scratchpad(void) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_TEST_SCRATCHPAD; + command->tunnel.options.mask = (1<tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "scratchpad failed\n"); + return false; + } + return true; +} + +#if !RELEASE_BUILD && WITH_MENU +int asp_update_ppn_firmware(const void *fw_buffer, size_t fw_length) +{ + int err = 0; + void *fw_buffer_aligned = NULL; + + asp_disable_bg(); + + //allocate buffer + fw_buffer_aligned = memalign(fw_length, 4096); + if(!fw_buffer_aligned) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate data_buffer\n"); + return -1; + } + memcpy(fw_buffer_aligned, fw_buffer, fw_length); + + //set up the tunnel command + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_PPN_FIRMWARE_UPDATE; + command->tunnel.buffer_paddr = VADDR_TO_PADDR32(fw_buffer_aligned); + command->tunnel.bufferLen = fw_length; + command->tunnel.options.mask = (1 << ANC_MAX_BUSSES) - 1; + command->tunnel.options.value = 0; + + dprintf(DEBUG_CRITICAL, "Begin PPN firmware update\n"); + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: PPN firmware update failed\n\n"); + asp.state = ASP_STATE_ERROR_INVALID_PPNFW; + err = -1; + } + else + { + if (asp.state == ASP_STATE_ERROR_INVALID_PPNFW) + { + dprintf(DEBUG_CRITICAL, "PPN firmware successfully recovered, reboot required\n\n"); + } + else + { + dprintf(DEBUG_CRITICAL, "PPN firmware update succeeded\n\n"); + } + asp_set_default_dies_in_parallel(); + } + + asp_enable_bg(); + + free(fw_buffer_aligned); + return err; +} +#endif // #if !RELEASE_BUILD && WITH_MENU + +#if !RELEASE_BUILD +int asp_erase_block(struct blockdev * _dev, off_t offset, uint64_t len) +{ + block_addr start_block = 0; + uint32_t num_blocks = 0, returned_blocks = 0, blk_size = 0; + uint8_t *data_buffer = NULL; + int type = -1; + + if(len == 0) + { + len = _dev->total_len; + printf("len = 0 will erase entire dev.\n"); + } + if((offset + len) > _dev->total_len) + { + printf("Invalid parameter. Size should be > 0 and (Size + Offset) should be < %lld\n", _dev->total_len); + return -1; + } + + type = asp_type_from_blkdev(_dev); + switch (type) + { + case ASP_LLB: + blk_size = ASP_LLB_BLKSZ; + break; + +#if ASP_ENABLE_WRITES + case ASP_NVRAM: + blk_size = ASP_NVRAM_BLKSZ; + break; + + case ASP_NAND: + blk_size = ASP_NAND_BLKSZ; + break; + + case ASP_FIRMWARE: + blk_size = ASP_FIRMWARE_BLKSZ; + break; + + case ASP_EFFACEABLE: + blk_size = ASP_EFFACEABLE_BLKSZ; + break; + + case ASP_SYSCFG: + blk_size = ASP_SYSCFG_BLKSZ; + break; +#endif // ASP_ENABLE_WRITES + + default: + dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_erase_block!\n", type); + return -1; + break; + } + + if((0 != (len % blk_size)) || (0 != (offset % blk_size))) + { + printf("len and offset are expected to be multiple of block sizez: %d\n", blk_size); + return -1; + } + start_block = offset / blk_size; + num_blocks = len / blk_size; + + data_buffer = memalign(num_blocks * blk_size, 4096); + if(!data_buffer) + { + printf("Could not allocate data buffer\n"); + return -1; + } + //erasing is actually writing out 0's. + memset(data_buffer, 0x00, num_blocks * blk_size); + + returned_blocks = asp_write_block(_dev, data_buffer, start_block, num_blocks); + + if (returned_blocks != num_blocks) + { + printf("Error. Expected to erase %d blocks. Erased %d blocks\n", num_blocks, returned_blocks); + free(data_buffer); + return -1; + } + + free(data_buffer); + return len; +} +#endif + + +int asp_read_block(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count) +{ + + uintptr_t paddr = mem_static_map_physical((addr_t)ptr); + uint32_t paddr32 = paddr >> ASP_NAND_BLK_ALIGN_SHIFT; + int type = -1; + aspproto_cmd_t * command; + uint8_t * bounce_buffer = NULL; + uint32_t num_blks_allowed; + uint32_t blk_size; + int total_count; + int return_count; + void *vaddr; + + type = asp_type_from_blkdev(_dev); + if (asp.state != ASP_STATE_READY && type != ASP_NVRAM) + { + dprintf(DEBUG_CRITICAL, "ASP is not ready! Current state is %d\n", asp.state); + return_count = -1; + goto ReadBlockCleanUp; + } + else if (csi_is_panic_recovery(asp.coproc)) + { + asp_panic_recover(); + dprintf(DEBUG_CRITICAL, "ASP is panicked; ignoring read\n"); + return_count = -1; + goto ReadBlockCleanUp; + } + + vaddr = ptr; + + switch (type) + { + + case ASP_NAND: + command = asp_get_cmd_for_tag(ASP_TAG_NAND); + command->op = ASPPROTO_CMD_READ; + num_blks_allowed = asp.num_lbas; + blk_size = ASP_NAND_BLKSZ; + break; + + case ASP_NVRAM: + command = asp_get_cmd_for_tag(ASP_TAG_NVRAM); + command->op = ASPPROTO_CMD_READ_NVRAM; + num_blks_allowed = ASP_NVRAM_NUMBLKS; + blk_size = ASP_NVRAM_BLKSZ; + break; + + case ASP_FIRMWARE: + command = asp_get_cmd_for_tag(ASP_TAG_FIRMWARE); + command->op = ASPPROTO_CMD_READ_FW; + num_blks_allowed = ASP_FIRMWARE_NUMBLKS; + blk_size = ASP_FIRMWARE_BLKSZ; + break; + + case ASP_LLB: + command = asp_get_cmd_for_tag(ASP_TAG_LLB); + command->op = ASPPROTO_CMD_READ_LLB; + num_blks_allowed = ASP_LLB_NUMBLKS; + blk_size = ASP_LLB_BLKSZ; + break; + + case ASP_EFFACEABLE: + command = asp_get_cmd_for_tag(ASP_TAG_EFFACEABLE); + command->op = ASPPROTO_CMD_READ_EFFACEABLE; + num_blks_allowed = ASP_EFFACEABLE_NUMBLKS; + blk_size = ASP_EFFACEABLE_BLKSZ; + break; + + case ASP_SYSCFG: + command = asp_get_cmd_for_tag(ASP_TAG_SYSCFG); + command->op = ASPPROTO_CMD_READ_SYSCFG; + num_blks_allowed = ASP_SYSCFG_NUMBLKS; + blk_size = ASP_SYSCFG_BLKSZ; + // syscfg starts at block 2 + if (block != 2) + { + dprintf(DEBUG_CRITICAL, "Attempted to read nand syscfg at non-zero offset\n"); + return_count = -1; + goto ReadBlockCleanUp; + } + block = 0; // Real Syscfg is always the 1st block in the blockdevice + break; + + case ASP_PANICLOG: + command = asp_get_cmd_for_tag(ASP_TAG_PANICLOG); + command->op = ASPPROTO_CMD_READ_PANICLOG; + num_blks_allowed = ASP_PANICLOG_NUMBLKS; + blk_size = ASP_PANICLOG_BLKSZ; + + if(block != 0) { + return_count = -1; + goto ReadBlockCleanUp; + } + break; + + default: + dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_read_block!\n", type); + return_count = -1; + goto ReadBlockCleanUp; + break; + + } + + if ((paddr & (4096 - 1)) != 0) + { + bounce_buffer = memalign(count * blk_size, 4096); + + if (!bounce_buffer) + { + dprintf(DEBUG_CRITICAL, "Failed to allocate bounce buffer\n"); + return_count = -1; + goto ReadBlockCleanUp; + } + + paddr32 = VADDR_TO_PADDR32(bounce_buffer); + vaddr = bounce_buffer; + } + + command->flags.all = 0; + command->flags.noAesKey = 1; + + if (count > num_blks_allowed) + { + dprintf(DEBUG_CRITICAL, "Trimming supported read size of %d 4KB blks to " + "%d 4KB blocks for NAND dev type %d\n", count, num_blks_allowed, type); + count = num_blks_allowed; + } + + total_count = count; + + if (type == ASP_NVRAM || type == ASP_SYSCFG) + { + count = count * 2; //Since NVRAM and SYSCFG blkdev publishes 8KB while NAND blksz is 4KB + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, vaddr, count * ASP_NAND_BLKSZ); +#endif + + if (type != ASP_PANICLOG) + { + return_count = total_count; + } + else + { + return_count = 0; + } + + while (count) + { + uint32_t lbas = MIN(count, MAX_SGL_ENTRIES); + uint32_t lba; + int ret; + command->lba = block; + + for (lba = 0; lba < lbas; lba++) + { + command->sglAndIv[lba] = paddr32++; + } + + command->count = lbas; + count -= lbas; + block += lbas; + + if (type == ASP_NVRAM && !asp.util_formatted) + { + ; // ignore writes + } + else if ((ret=asp_send_command(command->tag)) != ASPPROTO_CMD_STATUS_SUCCESS) + { + if (type == ASP_NVRAM || type == ASP_SYSCFG) // failed NVRAM reads return all FFs, not errors + { + memset(ptr, 0xff, total_count * blk_size); + } + else + { + dprintf(DEBUG_CRITICAL, "Failed to read LBA %d from bdev %s, return code=%d\n", command->lba, asp_names[type],ret); + return_count = -1; + goto ReadBlockCleanUp; + } + } + else if (type == ASP_PANICLOG) + { + return_count += command->count; + } + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, vaddr, total_count * ASP_NAND_BLKSZ); +#endif + + if (type == ASP_NVRAM && !asp.util_formatted) + { + // fake reads return all 0xffs + memset(ptr, 0xff, total_count * blk_size); + } + +ReadBlockCleanUp: + + if (bounce_buffer) + { + // Buffer wasn't 4KB-aligned + memcpy(ptr, bounce_buffer, total_count * blk_size); + free(bounce_buffer); + } + + return return_count; + +} + + +int asp_write_block(struct blockdev *_dev, const void *ptr, block_addr block, uint32_t count) +{ + + uintptr_t paddr = mem_static_map_physical((addr_t)ptr); + uint32_t paddr32 = paddr >> ASP_NAND_BLK_ALIGN_SHIFT; + int total_count; + int type = -1; + aspproto_cmd_t * command; + uint32_t num_blks_allowed; + uint32_t blk_size; + uint8_t *bounce_buffer = NULL; + void *vaddr = (void *)ptr; + + type = asp_type_from_blkdev(_dev); + if (asp.state != ASP_STATE_READY && type != ASP_NVRAM) + { + dprintf(DEBUG_CRITICAL, "ASP is not ready! Current state is %d\n", asp.state); + return -1; + } + else if (csi_is_panic_recovery(asp.coproc)) + { + asp_panic_recover(); + + dprintf(DEBUG_CRITICAL, "ASP is panicked; ignoring read\n"); + return -1; + } + + switch (type) + { + + case ASP_NVRAM: + command = asp_get_cmd_for_tag(ASP_TAG_NVRAM); + command->op = ASPPROTO_CMD_WRITE_NVRAM; + num_blks_allowed = ASP_NVRAM_NUMBLKS; + blk_size = ASP_NVRAM_BLKSZ; + break; + + case ASP_LLB: + command = asp_get_cmd_for_tag(ASP_TAG_LLB); + command->op = ASPPROTO_CMD_WRITE_LLB; + num_blks_allowed = ASP_LLB_NUMBLKS; + blk_size = ASP_LLB_BLKSZ; + break; + +#if ASP_ENABLE_WRITES + case ASP_NAND: + command = asp_get_cmd_for_tag(ASP_TAG_NAND); + command->op = ASPPROTO_CMD_WRITE; + num_blks_allowed = asp.num_lbas; + blk_size = ASP_NAND_BLKSZ; + break; + + case ASP_FIRMWARE: + command = asp_get_cmd_for_tag(ASP_TAG_FIRMWARE); + command->op = ASPPROTO_CMD_WRITE_FW; + num_blks_allowed = ASP_FIRMWARE_NUMBLKS; + blk_size = ASP_FIRMWARE_BLKSZ; + break; + + case ASP_EFFACEABLE: + command = asp_get_cmd_for_tag(ASP_TAG_EFFACEABLE); + command->op = ASPPROTO_CMD_WRITE_EFFACEABLE; + num_blks_allowed = ASP_EFFACEABLE_NUMBLKS; + blk_size = ASP_EFFACEABLE_BLKSZ; + break; +#endif + case ASP_PANICLOG: + command = asp_get_cmd_for_tag(ASP_TAG_PANICLOG); + command->op = ASPPROTO_CMD_WRITE_PANICLOG; + num_blks_allowed = ASP_PANICLOG_NUMBLKS; + blk_size = ASP_PANICLOG_BLKSZ; + break; + + default: + dprintf(DEBUG_CRITICAL, "Unsupported type %d for asp_write_block!\n", type); + return -1; + break; + + } + +#if ASP_ENABLE_WRITES + if ((type != ASP_NVRAM) + && (asp.writable == false)) + { + printf("Need to make system writable. Execute 'asp setwritable' first\n"); + return -1; + } +#endif + + if ((paddr & (4096 - 1)) != 0) + { + bounce_buffer = memalign(count * blk_size, 4096); + + if (!bounce_buffer) + { + dprintf(DEBUG_CRITICAL, "Failed to allocate bounce buffer\n"); + return -1; + } + + paddr32 = VADDR_TO_PADDR32(bounce_buffer); + memcpy(bounce_buffer, ptr, count * blk_size); + vaddr = bounce_buffer; + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN, vaddr, count * blk_size); +#endif + + command->flags.all = 0; + command->flags.noAesKey = 1; + + if (count > num_blks_allowed) + { + dprintf(DEBUG_CRITICAL, "Trimming supported read size of %d 4KB blks to " + "%d 4KB blocks for NAND dev type %d\n", count, num_blks_allowed, type); + count = num_blks_allowed; + } + + total_count = count; + + if (type == ASP_NVRAM) + { + count = count * 2; //Since NVRAM blkdev publishes 8KB while NAND blksz is 4KB + } + + while (count) + { + uint32_t lbas = MIN(count, MAX_SGL_ENTRIES); + uint32_t lba; + command->lba = block; + + for (lba = 0; lba < lbas; lba++) + { + command->sglAndIv[lba] = paddr32++; + } + + command->count = lbas; + count -= lbas; + block += lbas; + + if (type == ASP_NVRAM && !asp.util_formatted) + { + ; // ignore writes + } + else if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to write LBA %d\n", block); + return -1; + } + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, vaddr, total_count * blk_size); +#endif + + if (bounce_buffer) + { + // Buffer wasn't 4KB-aligned + free(bounce_buffer); + } + + return total_count; + +} + + +bool asp_sync(void) +{ + + uint32_t status; + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_SHUTDOWNNOTIFY; + + status = asp_send_command(command->tag); + + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to sync: 0x%08x\n", status); + return false; + } + + dprintf(DEBUG_INFO, "ASP sync complete\n"); + return true; + +} + + +#if defined(ASP_ENABLE_NEURALIZE) && ASP_ENABLE_NEURALIZE +bool asp_neuralize(void) +{ + + uint32_t status; + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NEURALIZE; + + status = asp_send_command(command->tag); + + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to neuralize: 0x%08x\n", status); + return false; + } + + dprintf(DEBUG_INFO, "ASP neuralize complete\n"); + return true; +} +#endif + + +int asp_type_from_blkdev (struct blockdev *device) +{ + + int type = -1; + + if (device == asp_nand_dev) + { + type = ASP_NAND; + } + + else if (device == asp_nvram_dev) + { + type = ASP_NVRAM; + } + + else if (device == asp_firmware_dev) + { + type = ASP_FIRMWARE; + } + + else if (device == asp_llb_dev) + { + type = ASP_LLB; + } + + else if (device == asp_effaceable_dev) + { + type = ASP_EFFACEABLE; + } + + else if (device == asp_syscfg_dev) + { + type = ASP_SYSCFG; + } + + else if (device == asp_paniclog_dev) + { + type = ASP_PANICLOG; + } + + else + { + dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_type_from_blkdev!\n", type); + type = -1; + } + + return type; + +} + + +struct blockdev * asp_get_blkdev_for_type (int type) +{ + + struct blockdev * device = NULL; + + switch (type) + { + + case ASP_NAND: + device = asp_nand_dev; + break; + + case ASP_NVRAM: + device = asp_nvram_dev; + break; + + case ASP_FIRMWARE: + device = asp_firmware_dev; + break; + + case ASP_LLB: + device = asp_llb_dev; + break; + + case ASP_EFFACEABLE: + device = asp_effaceable_dev; + break; + + case ASP_SYSCFG: + device = asp_syscfg_dev; + break; + + case ASP_PANICLOG: + device = asp_paniclog_dev; + break; + + default: + dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_blktype_from_dev!\n", type); + device = NULL; + break; + + } + + return device; + +} + + +int asp_set_blkdev_for_type (int type, struct blockdev * device) +{ + + switch (type) + { + + case ASP_NAND: + asp_nand_dev = device; + break; + + case ASP_NVRAM: + asp_nvram_dev = device; + break; + + case ASP_FIRMWARE: + asp_firmware_dev = device; + break; + + case ASP_LLB: + asp_llb_dev = device; + break; + + case ASP_EFFACEABLE: + asp_effaceable_dev = device; + break; + + case ASP_SYSCFG: + asp_syscfg_dev = device; + break; + + case ASP_PANICLOG: + asp_paniclog_dev = device; + break; + + default: + dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_set_blkdev_for_type!\n", type); + return -1; + + } + + return 0; + +} + +int asp_panic_recover(void) +{ + if (asp.state != ASP_STATE_PANIC_RECOVERY) + { + asp.state = ASP_STATE_PANIC_RECOVERY; + dprintf(DEBUG_CRITICAL, "Initializing tags\n"); + if (!asp_init_tags()) + { + dprintf(DEBUG_CRITICAL, "Unable to init tags\n"); + return -1; + } + + asp_reinit(); + + dprintf(DEBUG_CRITICAL, "Opening ASP\n"); + if (!asp_send_open()) + { + dprintf(DEBUG_CRITICAL, "Unable to open ASP\n"); + return -1; + } + } + return 0; +} + +void asp_reinit(void) { + + asp_set_indirection_memory(ASPNAND_INDIRECTION_MEMORY, ASPNAND_LEGACY_INDIRECTION_MEMORY); + asp_set_default_dies_in_parallel(); +} diff --git a/drivers/apple/asp/common_util.h b/drivers/apple/asp/common_util.h new file mode 100644 index 0000000..1afbcc9 --- /dev/null +++ b/drivers/apple/asp/common_util.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __common_util_h__ +#define __common_util_h__ + +//#define ASP_ENABLE_NEURALIZE 1 + +#define ASP_ENABLE_WRITES 0 + +#if !SUPPORT_FPGA +#define ASP_ENABLE_TIMEOUTS 1 +#else +#define ASP_ENABLE_TIMEOUTS 0 +#endif + +#define ASP_READY_TIMEOUT_US (90 * 1000 * 1000) +#define ASP_IO_TIMEOUT_US (90 * 1000 * 1000) + + +typedef struct +{ + csi_coproc_t coproc; + struct task_event msg_event; + void * csi_token; + void * asp_command; + uint32_t num_lbas; + uint32_t bytes_per_lba; + bool lba_formatted; + bool util_formatted; + int state; + bool writable; + const char * ep_name; + uint32_t lastUserBand; + uint32_t lastBand; + uint32_t numVirtualSLCBonfireBands; + uint32_t firstIntermediateBand; + uint32_t lastIntermediateBand; + uint8_t chip_id[ANC_MAX_BUSSES][ANC_NAND_ID_SIZE]; + uint8_t mfg_id[ANC_MAX_BUSSES][ANC_NAND_ID_SIZE]; +} asp_t; + +enum +{ + ASP_TAG_GENERIC = 0, + ASP_TAG_NAND, + ASP_TAG_NVRAM, + ASP_TAG_FIRMWARE, + ASP_TAG_LLB, + ASP_TAG_EFFACEABLE, + ASP_TAG_SYSCFG, + ASP_TAG_PANICLOG, + ASP_NUM_TAGS +}; + +// +// Definitions +// + +enum +{ + ASP_NAND_BLKSZ = (4 * 1024), + ASP_NVRAM_BLKSZ = (8 * 1024), + ASP_FIRMWARE_BLKSZ = (4 * 1024), + ASP_LLB_BLKSZ = (4 * 1024), + ASP_EFFACEABLE_BLKSZ = (4 * 1024), + ASP_SYSCFG_BLKSZ = (8 * 1024), + ASP_PANICLOG_BLKSZ = (4 * 1024), +}; + + +enum +{ + ASP_NAND_NUMBLKS = 0, // For general NAND, size should be looked up from geometry + ASP_NVRAM_NUMBLKS = 1, + ASP_FIRMWARE_NUMBLKS = 2048, +#if defined (ASP_LLB_OVERRIDE_NUM_BLKS) + ASP_LLB_NUMBLKS = ASP_LLB_OVERRIDE_NUM_BLKS, +# else + ASP_LLB_NUMBLKS = 253, +#endif + ASP_EFFACEABLE_NUMBLKS = 1, + ASP_SYSCFG_NUMBLKS = 18, + ASP_PANICLOG_NUMBLKS = 256, +}; + + +enum +{ + ASP_NAND = 1, + ASP_NVRAM, + ASP_FIRMWARE, + ASP_LLB, + ASP_EFFACEABLE, + ASP_SYSCFG, + ASP_PANICLOG, +}; + + +enum +{ + ASP_STATE_INITIALIZING = 0, + ASP_STATE_INITIALIZED, + ASP_STATE_READY, + ASP_STATE_TIMEOUT, + ASP_STATE_ERROR_NOT_REGISTERED, + ASP_STATE_ERROR_NOT_WRITABLE, + ASP_STATE_ERROR_NEURALIZE, + ASP_STATE_ERROR_INVALID_PPNFW, + ASP_STATE_ERROR_CRITICAL, + ASP_STATE_PANIC_RECOVERY, +}; + + +enum +{ + ASP_FORMAT_UTIL, + ASP_FORMAT_LBA, + ASP_FORMAT_ALL, +}; + +#define MAX_SGL_ENTRIES (512) +//Calculate number of cache lines needed for the command and round them up +#define ASPPROTO_CMD_LINES ((((MAX_SGL_ENTRIES * sizeof(uint32_t)) + sizeof(aspproto_cmd_t))/CACHELINE_BYTES) + 1) + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define MAX(a,b) (((a) < (b)) ? (b) : (a)) + +#define ASP_NAND_BLK_ALIGN_SHIFT (12) +#define ASP_NAND_BLK_ALIGNMENT (1 << ASP_NAND_BLK_ALIGN_SHIFT) +#define VADDR_TO_PADDR32(buffer) (mem_static_map_physical((addr_t)(buffer)) >> ASP_NAND_BLK_ALIGN_SHIFT) + +#define ALIGN_UP(val, n) ((((val) + (n) - 1) / (n)) * (n)) + +int asp_send_command(uint32_t tag); +int asp_wait_for_completion(uint32_t tag); +bool asp_set_writable(void); +bool asp_get_geometry(void); +bool asp_create_block_device(uint8_t type); +bool asp_set_dies_in_parallel(uint32_t mlc_slc_write_dies, + uint32_t mlc_read_dies, + uint32_t mlc_erase_dies, + uint32_t mlc_write_dies, + uint32_t tlc_slc_write_dies, + uint32_t tlc_read_dies, + uint32_t tlc_erase_dies, + uint32_t tlc_tlc_write_dies, + CorePowerState_e power_level); +bool asp_set_power_state(CorePowerState_e powerState); +bool asp_set_indirection_memory(uint32_t indirection_memory, uint32_t legacy_memory); +bool asp_test_scratchpad(void); +#if !RELEASE_BUILD && WITH_MENU +int asp_update_ppn_firmware(const void *fw_buffer, size_t fw_length); +#endif // #if !RELEASE_BUILD && WITH_MENU +aspproto_cmd_t * asp_get_cmd_for_tag(uint32_t tag); +int asp_read_block(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count); +int asp_write_block(struct blockdev *_dev, const void *ptr, block_addr block, uint32_t count); +#if !RELEASE_BUILD +int asp_erase_block(struct blockdev * _dev, off_t offset, uint64_t len); +#endif +bool asp_sync(void); +int asp_type_from_blkdev (struct blockdev *device); +struct blockdev * asp_get_blkdev_for_type (int type); +int asp_set_blkdev_for_type (int type, struct blockdev * device); +bool asp_set_photoflow_mode(core_flow_mode_e slc_mode); +bool asp_enable_bg(void); +bool asp_disable_bg(void); +bool asp_send_open(void); +int asp_panic_recover(void); +bool asp_init_tags(void); +void asp_reinit(void); +bool asp_wait_for_ready(void); +#if defined(ASP_ENABLE_NEURALIZE) && ASP_ENABLE_NEURALIZE +bool asp_neuralize(void); +#endif // ASP_ENABLE_NEURALIZE + +#endif // __common_util_h__ + diff --git a/drivers/apple/asp/debug.c b/drivers/apple/asp/debug.c new file mode 100644 index 0000000..5ecc1f0 --- /dev/null +++ b/drivers/apple/asp/debug.c @@ -0,0 +1,4207 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define ASP_TARGET_RTXC 1 +#define CASSERT(x, name) typedef char __ASP_CASSERT_##name[(x) ? 1 : -1] +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // ticks +#include "common_util.h" +#include + +#if DEBUG_BUILD && WITH_MENU + +#define METADATA_PER_LBA (16) +#define LBA_TOKEN_SIZE (4) +#define TOKEN_TERMINATOR (0xFFFFFFFF) +#define LBA_TOKEN_BASE (0x0FF00000) +#define LBA_TOKEN_BLOG (LBA_TOKEN_BASE + 0x13) +#define BYTES_PER_SEC (4096) +#define BLOG_NUM_ENTRY (BYTES_PER_SEC / sizeof(BlogE_t)) +#define MAX_RMA_CHUNK_PAGES (1024) +#define PERFECT_PAGE_SIZE (4112) +#define VENDOR_CODE__MICRON (0x2C) +#define VENDOR_CODE__HYNIX (0xAD) +#define VENDOR_CODE__SANDISK (0x45) +#define SIZE_OF_WFALL_TBL_ENTRY (4) + +#define TEST_DATA_PATTERN (0xA5) +#define WATERMARK_PATTERN (0xFF) + +#define FLOW_DEAD 12 +#define FLOW_UTIL 13 +extern aspproto_nand_geom_t nand_info; +extern asp_t asp; +extern struct blockdev *asp_nand_dev; + +typedef enum { + NOB_TOKEN_UNMAPPED = 0, + NOB_TOKEN_W_UNC = 1, + NOB_TOKEN_W_UNC_LOG = 2, + NOB_TOKEN_GC_UNC = 3, + NOB_TOKEN_GC_BLANK = 4, + NOB_TOKEN_TRANSLATE = 5, + NUM_NOB_TOKENS = 6, + NOB_TOKEN_MAX = 7 +} NOB_TOKEN_e; + +#define NOB_BAND_BITS 12 +#define NOB_BOFF_BITS (32 - NOB_BAND_BITS) +typedef union { + struct { + uint32_t boff : NOB_BOFF_BITS; + uint32_t band : NOB_BAND_BITS; + }; + uint32_t all; // note that the all field is used to acclerate math on the boff field which is assumed to be the least significant bits without risk of roll over. + NOB_TOKEN_e token; +} nob_t; + +typedef struct { + uint32_t lba; + uint32_t size; +} BlogE_t; + +typedef enum { + BONFIRE_SLC_STATE_NONE = 0, + BONFIRE_SLC_STATE_A = 1, + BONFIRE_SLC_STATE_B = 2 +} BONFIRE_SLC_STATE_e; + +BONFIRE_SLC_STATE_e bonfire_slc_state = BONFIRE_SLC_STATE_NONE; + +typedef enum { + ASP_USER_PARTITION, + ASP_INTERMEDIATE_PARTITION, + NUM_ASP_PARITIONS +} asp_partitions_e; + +char partition_names[NUM_ASP_PARITIONS][30] = { + "USER PARTITION", + "INTERMEDIATE PARTITION" +}; + +#define ROUNDUPTO(num, gran) ((((num) + (gran) - 1) / (gran)) * (gran)) + +static void usage(void) +{ + printf("usage:\n"); + printf("asp sync\n"); +#if defined(ASP_ENABLE_NEURALIZE) && ASP_ENABLE_NEURALIZE + printf("asp neuralize\n"); +#endif + printf("asp readid\n"); + printf("asp info\n"); + printf("asp debug_counter_supported \n"); + printf("asp get_debug_counter \n"); + printf("asp reset_debug_counter \n"); + printf("asp dies_in_parallel \n"); + printf("asp dies_in_parallel (for MLC device: ) (for TLC device: )\n"); + printf("asp test_scratchpad\n"); + printf("asp bonfirereadband < no. of stripes to be issued during 1 read transaction> \n", CELL_TYPE_IS_MLC, CELL_TYPE_IS_SLC, CELL_TYPE_IS_TLC); + printf("asp readrandom \n", CELL_TYPE_IS_MLC, CELL_TYPE_IS_SLC, CELL_TYPE_IS_TLC, CELL_TYPE_IS_MIXED); + printf("asp readmixedsuperpage < no. of stripes to be issued during 1 read transaction> \n"); + printf("asp secperband \n"); + printf("asp v2p \n"); + printf("asp getburnincode\n"); + printf("asp cbp2r \n"); + printf("asp dbp2r \n"); + printf("asp r2cbp \n"); + printf("asp l2dbp \n"); + printf("asp getlastfailure\n"); + printf("asp set_photoflow_slc\n"); + printf("asp set_photoflow_mlc\n"); + printf("asp enable_bg\n"); + printf("asp disable_bg\n"); + printf("asp bbt\n"); + printf("asp dm\n"); + printf("asp dipinfo\n"); + printf("asp read <0/1/2 for bit flips or in-depth health monitoring> \n", ASP_NAND_BLKSZ, CELL_TYPE_IS_MLC, CELL_TYPE_IS_SLC, CELL_TYPE_IS_TLC); + printf("asp readpagemeta \n"); + printf("asp readbandmeta \n"); + printf("asp vthsweep \n"); + printf("asp rma_configure \n"); + printf("asp rma_set \n"); + printf("asp rma_get [file_path]\n"); + printf("asp rma_delete \n"); + printf("asp ppn_recover\n"); + printf("asp ppn_get_calibration \n"); + printf("asp waterfall_size\n"); + printf("asp waterfall\n"); + printf("asp devparam\n"); + printf("asp testbdevread\n"); + printf("asp setTLCwritestripes \n"); + printf("asp readverify \n"); + printf("asp istlc\n"); + printf("asp getlinkclkfreq\n"); + printf("asp resetperfticks\n"); + printf("asp getperfticks\n"); + printf("asp printslcbonfirebands\n"); +#if ASP_ENABLE_WRITES + printf("asp setwritable\n"); + printf("asp utilFormat\n"); + printf("asp lbaFormat\n"); + printf("asp register\n"); + printf("asp bonfireeraseband \n"); + printf("asp bonfirewriteband \n", CELL_TYPE_IS_MLC, CELL_TYPE_IS_SLC, CELL_TYPE_IS_TLC); + printf("asp setburnincode \n"); + printf("asp eraseband \n", CELL_TYPE_IS_MLC, CELL_TYPE_IS_SLC, CELL_TYPE_IS_TLC); + printf("asp writeband \n", CELL_TYPE_IS_MLC, CELL_TYPE_IS_SLC, CELL_TYPE_IS_TLC); + printf("asp eploop ", CELL_TYPE_IS_MLC, CELL_TYPE_IS_SLC, CELL_TYPE_IS_TLC); + printf("asp testwaterfall\n"); + printf("asp testbdevwrite\n"); + printf("asp groupaslc \n"); + printf("asp groupbslc\n"); + printf("asp ungroup\n"); +#endif //ASP_ENABLE_WRITES +} + +static int asp_nand_info(void) +{ + printf("ce_per_bus = %d\n", nand_info.ce_per_bus); + printf("cau_per_die = %d\n", nand_info.cau_per_die); + printf("num_bus = %d\n", nand_info.num_bus); + printf("die_per_bus = %d\n", nand_info.die_per_bus); + printf("num_dip = %d\n", nand_info.num_dip); + printf("num_bands = %d\n", nand_info.num_bands); + printf("sec_per_page = %d\n", nand_info.sec_per_page); + printf("sec_per_full_band = %d\n", nand_info.sec_per_full_band); + printf("sec_per_full_band_slc = %d\n", nand_info.sec_per_full_band_slc); + printf("bytes_per_sec_meta = %d\n", nand_info.bytes_per_sec_meta); + printf("pages_per_block = %d\n", nand_info.pages_per_block); + printf("pages_per_block_slc = %d\n", nand_info.pages_per_block_slc); + printf("cell type = %d. (%d for MLC, %d for TLC)\n", nand_info.cell_type, CELL_TYPE_IS_MLC, CELL_TYPE_IS_TLC); + printf("lastUserBand = %d\n", asp.lastUserBand); + printf("lastBand = %d\n", asp.lastBand); + printf("numVirtualSLCBonfireBands = %d\n", asp.numVirtualSLCBonfireBands); + printf("firstIntermediateBand = %d\n", asp.firstIntermediateBand); + printf("lastIntermediateBand = %d\n", asp.lastIntermediateBand); + + return 0; +} + +static void asp_print_status_key() { + + printf("\nType key: \n0:Success, \n3:UECC/Efail/Pfail, \n5:Refresh, \n6: clean, \n8:Unknown\n\n"); +} + +static bool asp_format(uint8_t type) +{ + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + if(!asp.writable) + { + printf("Need to make system writable. Execute 'asp setwritable' first\n"); + return false; + } + + if ((asp.state != ASP_STATE_INITIALIZED) + && (asp.state != ASP_STATE_READY) + && (asp.state != ASP_STATE_ERROR_NOT_REGISTERED)) + { + dprintf(DEBUG_CRITICAL, "ASP is not initialized/ready! Current state is %d\n", asp.state); + return false; + } + + if ((type == ASP_FORMAT_UTIL) + || (type == ASP_FORMAT_ALL)) + { + command->op = ASPPROTO_CMD_UTIL_FORMAT; + } + + else + { + command->op = ASPPROTO_CMD_LBA_FORMAT; + } + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + // NOTE: If format fails, we maintain the last formatted + // status from asp_get_geomtry() + dprintf(DEBUG_CRITICAL, "ASP Format Failed\n"); + return false; + } + + if (command->op == ASPPROTO_CMD_UTIL_FORMAT) + { + asp.util_formatted = true; + } + + asp.lba_formatted = true; + + return true; + +} + +static void output_nand_die_uid(uint8_t *buffer) +{ + uint32_t die_idx, bus_idx, byteIdx; + + for(bus_idx = 0; bus_idx < nand_info.num_bus; bus_idx++) + { + for(die_idx = 0; die_idx < nand_info.die_per_bus; die_idx++) + { + printf("CE %d: ", bus_idx); + for(byteIdx = 0; byteIdx < ASPPROTO_DEV_ID_LEN_PPN; byteIdx++) + { + printf("%02X ", buffer[(ASPPROTO_DEV_ID_LEN_PPN*(die_idx + bus_idx * nand_info.die_per_bus)) + byteIdx]); + } + printf("\n"); + } + } +} + +static void output_nand_uid (uint8_t *buffer, uint32_t size, uint32_t parameter) +{ + uint32_t Idx, byteIdx; + + for(Idx = 0; Idx < size/ASPPROTO_DEV_ID_LEN_PPN; Idx++) + { + printf("CE %d: ", Idx); + for(byteIdx = 0; byteIdx < ASPPROTO_DEV_ID_LEN_PPN; byteIdx++) + { + if(parameter == ASPPROTO_CMD_FW_VERSION) + { + printf("%c", buffer[(ASPPROTO_DEV_ID_LEN_PPN*Idx) + byteIdx]); + } + else + { + printf("%02X ", buffer[(ASPPROTO_DEV_ID_LEN_PPN*Idx) + byteIdx]); + } + } + printf("\n"); + } +} + +static int asp_nand_get_uid() +{ + aspproto_cmd_t * command; + int status; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_PKG_ASSEMBLY_CODE; + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get package assembly code: %d\n", status); + return -1; + } + printf("\nPackage Assembly Code:\n"); + output_nand_uid(command->device_id.id, command->device_id.size, ASPPROTO_CMD_PKG_ASSEMBLY_CODE); + + command->op = ASPPROTO_CMD_CONTROLLER_UID; + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get controller uid: %d\n", status); + return -1; + } + printf("\nController UID:\n"); + output_nand_uid(command->device_id.id, command->device_id.size, ASPPROTO_CMD_CONTROLLER_UID); + + command->op = ASPPROTO_CMD_CONTROLLER_HWID; + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get controller hwid: %d\n", status); + return -1; + } + printf("\nController HWID:\n"); + output_nand_uid(command->device_id.id, command->device_id.size, ASPPROTO_CMD_CONTROLLER_HWID); + + command->op = ASPPROTO_CMD_FW_VERSION; + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get fw version: %d\n", status); + return -1; + } + printf("\nFW Version:\n"); + output_nand_uid(command->device_id.id, command->device_id.size, ASPPROTO_CMD_FW_VERSION); + + command->op = ASPPROTO_CMD_DIE_UID; + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get die uid: %d\n", status); + return -1; + } + printf("\nDie UID:\n"); + output_nand_die_uid(command->device_id.id); + + return 0; +} + +static uint32_t asp_get_link_clk_freq(bool verbose, uint64_t *freq_ptr) { + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + uint8_t *bounce_buffer; + uint32_t paddr32; + + bounce_buffer = memalign(sizeof(uint64_t), ASP_NAND_BLK_ALIGNMENT); + if(!bounce_buffer) + { + printf("unable to allocate bounce buffer\n"); + return -1; + } + + paddr32 = VADDR_TO_PADDR32(bounce_buffer); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_LINK_CLK_FREQ; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = sizeof(uint64_t); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, bounce_buffer, CPU_CACHELINE_SIZE); +#endif + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to get link clk freq\n"); + return -1; + } else { + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN, bounce_buffer, CPU_CACHELINE_SIZE); +#endif + + if(verbose) + { + printf("link clk freq: %lld\n", *(uint64_t *)bounce_buffer); + } + } + + if(freq_ptr) + { + *freq_ptr = *(uint64_t *)bounce_buffer; + } + return 0; +} + +static uint32_t asp_get_perf_ticks(bool verbose, uint64_t *ticks_ptr, uint32_t channel) { + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + uint8_t *bounce_buffer; + uint32_t paddr32; + + bounce_buffer = memalign(sizeof(uint64_t), ASP_NAND_BLK_ALIGNMENT); + if(!bounce_buffer) + { + printf("unable to allocate bounce buffer\n"); + return -1; + } + + paddr32 = VADDR_TO_PADDR32(bounce_buffer); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_PERF_TICKS; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = sizeof(uint64_t); + command->tunnel.options.mask = 1 << channel; + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, bounce_buffer, CPU_CACHELINE_SIZE); +#endif + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to get perf ticks\n"); + return -1; + } else { + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN, bounce_buffer, CPU_CACHELINE_SIZE); +#endif + + if(verbose) + { + printf("For channel %d, ticks: %lld\n", channel, *(uint64_t *)bounce_buffer); + } + if(verbose && (0 == (*(uint64_t *)bounce_buffer))) + { + printf("Got 0 ticks. Is ANC_ENABLE_TUNNEL_PERF_COUNTER turned ON?\n"); + } + } + + if(ticks_ptr) + { + *ticks_ptr = *(uint64_t *)bounce_buffer; + } + return 0; +} + + +static int asp_get_bonfire_get_phy_band_num(uint32_t virtual_band) { + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_BONFIRE_GET_PHY_BAND_NUM; + command->tunnel.options.value = virtual_band; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to get actual band number\n"); + return -1; + } + return command->tunnel.options.value; +} + + +static uint32_t asp_print_slc_bonfire_bands() { + uint32_t i; + + for(i = 0; i < asp.numVirtualSLCBonfireBands; i++) { + printf("virtual band: %d -> actual band: %d\n", i, asp_get_bonfire_get_phy_band_num(i)); + } + return 0; +} + + +static uint32_t asp_reset_perf_ticks() { + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_RESET_PERF_TICKS; + command->tunnel.options.mask = (1 << 0) | (1 << 1); + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to reset perf ticks\n"); + return -1; + } + return 0; +} + +static int asp_cbp2r(uint32_t cau, uint32_t block, uint32_t page) +{ + aspproto_cmd_t * command; + int status; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CBP_TO_ROW_ADDR; + command->addr_xlate.cau = cau; + command->addr_xlate.block = block; + command->addr_xlate.page = page; + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get row address: %d\n", status); + return -1; + } + printf("cau: %d, blk: %d, page: %d --> row_addr: 0x%X\n", cau, block, page, command->addr_xlate.row_addr); + return 0; +} + +static int asp_l2dbp(uint32_t lba) +{ + nand_debug_lba_map_t *lbaMap; + uint32_t paddr32; + uint32_t lbaMapSize; + aspproto_cmd_t * command; + int status; + + lbaMap = NULL; + command = NULL; + lbaMapSize = sizeof(nand_debug_lba_map_t); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + if(!command) + { + return -1; + } + + lbaMap = memalign(lbaMapSize, ASP_NAND_BLK_ALIGNMENT); + if(!lbaMap) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate data_buffer\n"); + return -1; + } + memset(lbaMap, 0x00, lbaMapSize); + paddr32 = VADDR_TO_PADDR32(lbaMap); + lbaMap->lba = lba; + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, lbaMap, ROUNDUPTO(lbaMapSize,CPU_CACHELINE_SIZE)); +#endif + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_LBA_TO_PADDR; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = lbaMapSize; + + status = asp_send_command(command->tag); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, lbaMap, ROUNDUPTO(lbaMapSize,CPU_CACHELINE_SIZE)); +#endif + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get Physical Address for lba: %d\n", lbaMap->lba); + return -1; + } + + printf("lba: 0x%x --> band: 0x%x dip: %d bork: 0x%x page: 0x%x\n", lbaMap->lba, lbaMap->band, lbaMap->dip, lbaMap->bork, lbaMap->page); + return 0; +} + +static int asp_r2cbp(uint32_t row_addr) +{ + aspproto_cmd_t * command; + int status; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_ROW_ADDR_TO_CBP; + command->addr_xlate.row_addr = row_addr; + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get row address: %d\n", status); + return -1; + } + printf("row_addr: 0x%X --> cau: %d, block: %d, page: %d\n", row_addr, command->addr_xlate.cau, command->addr_xlate.block, command->addr_xlate.page); + return 0; +} + +static int asp_set_burnin_code(uint32_t burnin_code) +{ + aspproto_cmd_t * command; + int status; + + if(!asp.writable) + { + printf("Need to make system writable. Execute 'asp setwritable' first\n"); + return -1; + } + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_SET_BURNIN_CODE; + command->lba = burnin_code; + + status = asp_send_command(command->tag); + return 0; +} + +static int asp_set_tlcwritestripes(uint32_t write_stripes) +{ + aspproto_cmd_t * command; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_SETOPTIONS; + command->opts.TLCwriteStripes = write_stripes; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to set tlc writes stripes\n"); + return -1; + } + return 0; +} + +static int asp_get_burnin_code() +{ + aspproto_cmd_t * command; + int status; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_GET_BURNIN_CODE; + + status = asp_send_command(command->tag); + printf("Burnin Code: %d. Status: 0x%X\n", command->lba, status); + return 0; +} + +static int asp_get_last_failure() +{ + aspproto_cmd_t * command; + int status; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_GET_LAST_FAILURE; + + status = asp_send_command(command->tag); + printf("Type: %d CE: %d, page: 0x%X\n\n", command->last_failure.failure_mode, command->last_failure.ce, command->last_failure.physical_page); + return 0; +} + +static int asp_sectors_per_band(uint32_t band, bool verbose) +{ + aspproto_cmd_t * command; + int status; + + if((band < 1) || (band > asp.lastBand)) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_SECTORS_PER_BAND; + command->lba = band; + + status = asp_send_command(command->tag); + if(verbose) + { + printf("Band: %d has %d sectors.\n", band, command->count); + } + return (int)command->count; +} + +static int asp_nand_get_addr(uint32_t vba, uint32_t *bus, uint32_t *row_addr, bool verbose) +{ + aspproto_cmd_t * command; + int status; + + if(vba < nand_info.sec_per_full_band) + { + printf("Cannot decode vba in band 0: should be >= %d\n", nand_info.sec_per_full_band); + return -1; + } + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_GET_ADDR; + command->addr.vba = vba; + + status = asp_send_command(command->tag); + if(verbose) + { + printf("vba: %d -> ce: %d, row_addr: 0x%X, cau: %d, column: %d\n", vba, command->addr.ce, command->addr.row_addr, command->addr.cau, command->addr.column); + } + + if(bus) + { + *bus = command->addr.ce; + } + if(row_addr) + { + *row_addr = command->addr.row_addr; + } + return 0; +} + +static uint32_t get_num_pages_for_sectors(uint32_t sector_offset, uint32_t num_sectors) +{ + uint32_t last_sector = (sector_offset + num_sectors); + uint32_t leading_sectors = 0; + uint32_t trailing_sectors = 0; + uint32_t intermediate_sectors = 0; + + if(last_sector >= nand_info.sec_per_page) + { + leading_sectors = sector_offset ? (nand_info.sec_per_page - sector_offset) : 0; + } + else + { + leading_sectors = sector_offset ? (last_sector - sector_offset) : 0; + } + if((!sector_offset) || (last_sector > nand_info.sec_per_page)) + { + trailing_sectors = last_sector % nand_info.sec_per_page; + } + intermediate_sectors = num_sectors - (leading_sectors + trailing_sectors); + assert(!(intermediate_sectors % nand_info.sec_per_page)); + + return (leading_sectors ? 1 : 0) + (trailing_sectors ? 1 : 0) + (intermediate_sectors / nand_info.sec_per_page); +} + +/* + Description: + Does a physical NAND read without encryption. + Reads are done one physical page at a time. + Output data is arranged as first all data followed by all metadata. + Metadata will be available only at a full page boundary - even for partial page reads. + For partial page reads, output data is arranged as follows: + Example - For a 16k page with a read of 2 4k sectors starting from offset 1, + data will be available as the first 8k, meta will be available at a 16k offset. + +*/ +static int asp_physical_read(uint32_t bus, + uint32_t ce, + uint32_t row_addr, + uint32_t sector_offset, + uint32_t num_sectors, + nand_debug_health_monitoring_e health_monitoring, + aspproto_cell_type_t cell_type, + uint8_t * buffer, + bool verbose, + int *status_ptr) +{ + aspproto_cmd_t *command = 0; + int status = 0; + uint8_t *bounce_buffer = NULL; + uint32_t paddr32 = 0; + const uint32_t main_size = ASP_NAND_BLKSZ * nand_info.sec_per_page; + const uint32_t meta_size = nand_info.sec_per_page * METADATA_PER_LBA; + const uint32_t num_pages = get_num_pages_for_sectors(sector_offset, num_sectors); + const uint32_t kB_sectors_per_page = main_size / 1024; + uint32_t bytes_per_read = main_size + meta_size; + uint32_t sectors_remaining = num_sectors; + uint32_t offset_cursor = sector_offset; + uint32_t sectors_for_current_page; + uint8_t *data_cursor = buffer; + uint8_t *meta_cursor = buffer + (num_pages * main_size); + uint32_t current_row_addr = row_addr; + uint8_t *buf_stats_cursor = NULL; + uint32_t idx = 0; + uint8_t *value_ptr; + uint64_t perf_ticks; + uint64_t link_clk_freq; + + if(0 != asp_reset_perf_ticks()) + { + return -1; + } + + if((sector_offset > (nand_info.sec_per_page - 1))) + { + printf("sector offset allowed to be only between 0 and %d\n", nand_info.sec_per_page - 1); + return -1; + } + if((NAND_DEBUG_HEALTH_MONITORING_NONE != health_monitoring) && ((sector_offset != 0) || (num_sectors % nand_info.sec_per_page))) + { + printf("health monitoring reads are allowed only for full pages\n"); + return -1; + } + if(NAND_DEBUG_HEALTH_MONITORING_COUNT <= health_monitoring) + { + printf("invalid health monitoring option\n"); + return -1; + } + + if(NAND_DEBUG_HEALTH_MONITORING_NONE != health_monitoring) + { + if (!security_allow_memory(buffer, num_pages * kB_sectors_per_page)) + { + printf("Permission Denied\n"); + return -1; + } + memset(buffer, 0xA5, num_pages * kB_sectors_per_page); + bytes_per_read = kB_sectors_per_page; + } + else + { + if (!security_allow_memory(buffer, num_pages * bytes_per_read)) + { + printf("Permission Denied\n"); + return -1; + } + memset(buffer, 0xA5, num_pages * bytes_per_read); + } + + bounce_buffer = memalign(bytes_per_read, 4096); + if(!bounce_buffer) + { + dprintf(DEBUG_CRITICAL, "Failed to allocate data buffer\n"); + return -1; + } + paddr32 = VADDR_TO_PADDR32(bounce_buffer); + + while(sectors_remaining) + { + if (NAND_DEBUG_HEALTH_MONITORING_IN_DEPTH == health_monitoring) { + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_ENABLE_IN_DEPTH_HEALTH; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Error enabling depth health monitoring for channel %d rowAddr: 0x%x\n", bus, current_row_addr); + } + } + + if((offset_cursor % nand_info.sec_per_page) && ((sector_offset + sectors_remaining) > nand_info.sec_per_page)) + { + sectors_for_current_page = (offset_cursor % nand_info.sec_per_page) ? (nand_info.sec_per_page - sector_offset) : 0; + } + else + { + sectors_for_current_page = ((sectors_remaining < nand_info.sec_per_page) ? sectors_remaining : nand_info.sec_per_page); + } + memset(bounce_buffer, 0xC7, bytes_per_read); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, bounce_buffer, ROUNDUPTO(bytes_per_read,CPU_CACHELINE_SIZE)); +#endif + + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_READ; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = bytes_per_read; + command->tunnel.options.debug_epr_info.bus = bus; + command->tunnel.options.debug_epr_info.ce = ce; + command->tunnel.options.debug_epr_info.row_addr = current_row_addr; + command->tunnel.options.debug_epr_info.num_sectors = sectors_for_current_page; + command->tunnel.options.debug_epr_info.sector_offset = offset_cursor % nand_info.sec_per_page; + command->tunnel.options.debug_epr_info.health_monitoring = health_monitoring; + command->tunnel.options.debug_epr_info.cell_type = cell_type; + command->tunnel.options.mask = 1 << bus; + command->flags.all = 0; + command->flags.noAesKey = 1; + + status = asp_send_command(command->tag); + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, bounce_buffer, ROUNDUPTO(bytes_per_read,CPU_CACHELINE_SIZE)); +#endif + if(verbose) + { + printf("Bus: %01d, ce: %02d, row_addr: 0x%08X, num_sectors: %02d, sector_offset: %02d. Status: %02d\t", bus, ce, current_row_addr, sectors_for_current_page, (offset_cursor % nand_info.sec_per_page), status); + } + + if(status_ptr) + { + *status_ptr = status; + } + + if(NAND_DEBUG_HEALTH_MONITORING_SECTOR_STATS == health_monitoring) + { + // display sector stats + printf("Bitflips: "); + buf_stats_cursor = bounce_buffer; + for(idx = 0; idx < kB_sectors_per_page; idx++) + { + printf("%02X ", *buf_stats_cursor); + buf_stats_cursor++; + } + + memcpy(data_cursor, bounce_buffer, kB_sectors_per_page); + data_cursor += kB_sectors_per_page; + + } + else if (NAND_DEBUG_HEALTH_MONITORING_IN_DEPTH == health_monitoring) + { + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_IN_DEPTH_HEALTH; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tunnel.options.value = 0; + + if ((asp_send_command(command->tag) == ASPPROTO_CMD_STATUS_SUCCESS)) { + value_ptr = (uint8_t*) &(command->tunnel.options.value); + printf("Correctability: 0x%x tR-Status: 0x%x",value_ptr[0], value_ptr[1]); + } else { + dprintf(DEBUG_CRITICAL, "Error pulling in depth health monitoring for channel %d rowAddr: 0x%x\n", bus, current_row_addr); + } + } + else + { + memcpy(data_cursor, bounce_buffer, main_size); + memcpy(meta_cursor, (bounce_buffer + main_size), meta_size); + data_cursor += main_size; + meta_cursor += meta_size; + } + if(verbose) + { + printf("\n"); + } + + sectors_remaining -= sectors_for_current_page; + offset_cursor += sectors_for_current_page; + current_row_addr++; + } + + if(verbose) + { + asp_print_status_key(); + } + + if(0 != asp_get_perf_ticks(false, &perf_ticks, bus)) + { + return -1; + } + + if(0 != asp_get_link_clk_freq(false, &link_clk_freq)) + { + return -1; + } + + printf("%u bytes transferred in %llu ticks @ %llu Hz\n\n", (num_sectors * ASP_NAND_BLKSZ), + perf_ticks, + link_clk_freq); + + printf("To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (num_sectors * ASP_NAND_BLKSZ), + link_clk_freq, + perf_ticks); + + printf("Total time taken in us: (%llu) / (%llu / 1000000)\n\n", perf_ticks, link_clk_freq); + + printf("Note: This is actual bus utilization with very minimal SW overhead. This command uses only 1 channel at a time\n"); + + + free(bounce_buffer); + return 0; +} + +static int asp_read_pagemeta(uint32_t bus, uint32_t ce, uint32_t row_addr, uint32_t num_pages, uint8_t * buffer) +{ + uint32_t page_idx = 0; + const uint32_t main_size = ASP_NAND_BLKSZ * nand_info.sec_per_page; + const uint32_t meta_size = nand_info.sec_per_page * METADATA_PER_LBA; + uint8_t *meta_cursor = buffer + (num_pages * main_size); + + asp_physical_read(bus, ce, row_addr, 0, (num_pages * nand_info.sec_per_page), false, CELL_TYPE_IS_MLC, buffer, false, NULL); + + printf("LBA tokens:\n"); + for(page_idx = row_addr; page_idx < row_addr + num_pages; page_idx++) + { + printf("Bus:%01d, ce:%02d, row_addr:0x%08X\t", bus, ce, page_idx); + printf("Meta: %08X %08X %08X %08X\n", *((uint32_t*)meta_cursor), *((uint32_t*)meta_cursor + 4), *((uint32_t*)meta_cursor + 8), *((uint32_t*)meta_cursor + 12)); + meta_cursor += meta_size; + } + return 0; +} + +static int asp_read_bandmeta(uint32_t band, uint8_t * buffer, bool verbose) +{ + uint32_t page_idx = 0; + const uint32_t main_size = ASP_NAND_BLKSZ * nand_info.sec_per_page; + const uint32_t meta_size = nand_info.sec_per_page * METADATA_PER_LBA; + const uint32_t sectors_per_band = asp_sectors_per_band(band, false); + const uint32_t pages_per_band = sectors_per_band / nand_info.sec_per_page; + uint32_t vba = band * nand_info.sec_per_full_band; + uint8_t *meta_cursor = buffer; + uint32_t row_addr = 0; + uint32_t bus = 0; + uint8_t *page_buffer = NULL; + + if (!security_allow_memory(buffer, meta_size * pages_per_band)) + { + printf("Permission Denied\n"); + return -1; + } + memset(buffer, 0xA5, meta_size * pages_per_band); + + page_buffer = memalign((main_size + meta_size), 4096); + if(!page_buffer) + { + printf("could not allocate page buffer\n"); + return -1; + } + + if(verbose) + { + printf("LBA tokens:\n"); + } + for(page_idx = 0; page_idx < pages_per_band; page_idx++) + { + asp_nand_get_addr (vba, &bus, &row_addr, false); + asp_physical_read(bus, 0, row_addr, 0, nand_info.sec_per_page, false, CELL_TYPE_IS_MLC, page_buffer, false, NULL); + memcpy(meta_cursor, page_buffer + main_size, meta_size); + if(verbose) + { + printf("Bus:%01d, ce:%02d, row_addr:0x%08X\t", bus, 0, row_addr); + printf("Meta: %08X %08X %08X %08X\n", *((uint32_t*)meta_cursor), *((uint32_t*)meta_cursor + (1 * LBA_TOKEN_SIZE)), *((uint32_t*)meta_cursor + (2 * LBA_TOKEN_SIZE)), *((uint32_t*)meta_cursor + (3 * LBA_TOKEN_SIZE))); + } + vba += nand_info.sec_per_page; + meta_cursor += meta_size; + } + free(page_buffer); + return 0; +} + +static int audit_blog(uint32_t band, uint8_t *buffer, uint32_t num_leafs, bool verbose) +{ + const uint32_t sectors_per_band = asp_sectors_per_band(band, false); + const uint32_t pages_per_band = sectors_per_band / nand_info.sec_per_page; + BlogE_t *blog_buffer = (BlogE_t *)buffer; + uint32_t current_lba_token; + uint32_t current_size; + uint32_t *lba_token_buffer = NULL; + uint32_t max_blog_entries = 0; + uint32_t blog_entry_idx = 0; + uint32_t *lba_token_cursor = NULL; + uint32_t size_idx; + uint32_t boff_idx = 0; + int status = 0; + + assert(buffer); + + printf("Auditing Blog entries against LBA's in NAND...\n"); + lba_token_buffer = (uint32_t *)malloc(nand_info.sec_per_page * METADATA_PER_LBA * pages_per_band); + if(!lba_token_buffer) + { + printf("Unable to allocate memory for lba token buffer\n"); + return -1; + } + + if(asp_read_bandmeta(band, (uint8_t *)lba_token_buffer, false)) + { + free(lba_token_buffer); + return -1; + } + + lba_token_cursor = lba_token_buffer; + + max_blog_entries = (num_leafs * ASP_NAND_BLKSZ) / sizeof(BlogE_t); + for(blog_entry_idx = 0; blog_entry_idx < max_blog_entries; blog_entry_idx++) + { + current_lba_token = blog_buffer[blog_entry_idx].lba; + current_size = blog_buffer[blog_entry_idx].size; + + if((blog_entry_idx % (ASP_NAND_BLKSZ / sizeof(BlogE_t))) == ((ASP_NAND_BLKSZ / sizeof(BlogE_t)) - 1)) + { + if(verbose) + { + printf("End of leaf.\n"); + } + assert(current_lba_token == TOKEN_TERMINATOR); + continue; + } + else if(current_lba_token == TOKEN_TERMINATOR) + { + if(verbose) + { + printf("End of blog.\n"); + } + break; + } + + assert(current_size <= sectors_per_band); + for(size_idx = 0; size_idx < current_size; size_idx++) + { + if(verbose) + { + printf("Blog Entry idx: %04d, Blog Entry LBA: 0x%08X, LBA in NAND: 0x%08X. Boff: %04d\n", blog_entry_idx, current_lba_token, *lba_token_cursor, boff_idx); + } + if((current_lba_token >= LBA_TOKEN_BASE) && (current_lba_token != LBA_TOKEN_BLOG)) + { + //Page pads are written slightly differently in NAND and Blog + current_lba_token = LBA_TOKEN_BASE; + } + if(current_lba_token != *lba_token_cursor) + { + printf("Audit failed. Blog says LBA: 0x%08X. NAND says LBA: 0x%08X. boff: %d (vba: %d)\n", current_lba_token, *lba_token_cursor, boff_idx, ((band * nand_info.sec_per_full_band) + boff_idx)); + status = -1; + } + lba_token_cursor += LBA_TOKEN_SIZE; + current_lba_token++; + boff_idx++; + } + } + if(status) + { + printf("Audit failed\n"); + } + else + { + printf("Audit passed\n"); + } + free(lba_token_buffer); + + return status; +} + +//Dumps the blog and optionally audits if all LBA's in band correspond to blog entries. +static int asp_dump_blog(uint32_t band, uint8_t * buffer, bool audit, bool verbose) +{ + const uint32_t main_size = ASP_NAND_BLKSZ * nand_info.sec_per_page; + const uint32_t meta_size = nand_info.sec_per_page * METADATA_PER_LBA; + const uint32_t sectors_per_band = asp_sectors_per_band(band, true); + const uint32_t max_blog_size = sectors_per_band * sizeof(BlogE_t); + const uint32_t max_possible_leafs = (max_blog_size / ASP_NAND_BLKSZ) + 1; + uint32_t *leaf_ptr; + uint32_t vba = band * nand_info.sec_per_full_band; + uint32_t blogdir_vba; + uint32_t row_addr = 0; + uint32_t bus = 0; + uint32_t lba_token; + uint32_t expected_lba_offset = 0; + uint32_t num_leafs = 0; + uint32_t status = 0; + uint8_t *page_buffer = NULL; + bool audit_allowed = true; + int lba_status = ASPPROTO_CMD_STATUS_SUCCESS; + + + if (!security_allow_memory(buffer, max_blog_size)) + { + printf("Permission Denied\n"); + return -1; + } + memset(buffer, 0xA5, max_blog_size); + page_buffer = memalign((main_size + meta_size), 4096); + if(!page_buffer) + { + printf("Could not allocate page buffer\n"); + return -1; + } + leaf_ptr = malloc(max_possible_leafs * sizeof(uint32_t)); + if(!leaf_ptr) + { + printf("Could not allocate leaf pointer array\n"); + return -1; + } + //Blog always starts at last sector of band. + vba = vba + sectors_per_band - 1; + blogdir_vba = vba; + + asp_nand_get_addr(vba , &bus, &row_addr, false); + expected_lba_offset = vba % nand_info.sec_per_page; + + //Physical read of the Blog sector + asp_physical_read(bus, 0, row_addr, expected_lba_offset, 1, false, CELL_TYPE_IS_MLC, page_buffer, false, &lba_status); + if(lba_status != ASPPROTO_CMD_STATUS_SUCCESS) + { + printf("Received a non-success status: %d when reading bus: %d, ce: %d, row_addr: 0x%X, lba offset: %d\n", lba_status, bus, 0, row_addr, expected_lba_offset); + asp_print_status_key(); + audit_allowed = false; + goto FreeMemory; + } + + lba_token = *((uint32_t*)(page_buffer + main_size)); + if(lba_token < LBA_TOKEN_BASE) + { + BlogE_t *ptr = (BlogE_t *)page_buffer; + + ptr[0].lba = lba_token - (sectors_per_band - 1); + ptr[0].size = sectors_per_band; + ptr[1].lba = TOKEN_TERMINATOR; + ptr[1].size = 0; + num_leafs = 1; + printf("No blog. The entrire band was written sequentially. lba 0x%x size 0x%x\n ", ptr[0].lba, ptr[0].size); + memcpy(buffer, page_buffer, ASP_NAND_BLKSZ); + } + else + { + if (LBA_TOKEN_BLOG == lba_token) + { + BlogE_t *ptr = (BlogE_t *)page_buffer; + nob_t *nobPtr; + uint32_t i, j; + + ptr += BLOG_NUM_ENTRY; + nobPtr = (nob_t*)ptr; + nobPtr--; + i = nobPtr->all; + nobPtr -= i; + printf("Number of leafs is %d\n",i); + num_leafs = i; + if(i == 1) + { + ptr -= BLOG_NUM_ENTRY; + memcpy(buffer, page_buffer, ASP_NAND_BLKSZ); + j = 0; + while (( ptr[j].lba != TOKEN_TERMINATOR) && (ptr[j].size != 0)) + { + printf("lba 0x%x count 0x%x\n", ptr[j].lba,ptr[j].size); + j++; + } + } + else + { + nob_t *dir = malloc(sizeof(nob_t) * i); + uint32_t dir_no = i; + + if(dir) + { + memcpy(dir, nobPtr, sizeof(nob_t) * dir_no); + } + else + { + printf("cannot allocate memory . getting out\n"); + goto FreeMemory; + } + for(j = 0; j < num_leafs; j ++) + { + vba = (dir[j].band * nand_info.sec_per_full_band) + dir[j].boff; + asp_nand_get_addr(vba , &bus, &row_addr, false); + expected_lba_offset = vba % nand_info.sec_per_page; + + //Physical read of the Blog sector + asp_physical_read(bus, 0, row_addr, expected_lba_offset, 1, false, CELL_TYPE_IS_MLC, page_buffer, false, &lba_status); + if(lba_status != ASPPROTO_CMD_STATUS_SUCCESS) + { + printf("Received a non-success status: %d when reading bus: %d, ce: %d, row_addr: 0x%X, lba offset: %d\n", lba_status, bus, 0, row_addr, expected_lba_offset); + asp_print_status_key(); + audit_allowed = false; + free(dir); + goto FreeMemory; + } + memcpy(buffer + (j * ASP_NAND_BLKSZ), page_buffer, ASP_NAND_BLKSZ); + ptr = (BlogE_t *)page_buffer; + while (( ptr[i].lba != TOKEN_TERMINATOR) && (ptr[i].size != 0)) + { + printf("lba 0x%x count 0x%x\n", ptr[i].lba,ptr[i].size); + i++; + } + } + + free(dir); + } + } + else + { + goto FreeMemory; + } + } + + printf("%d bytes of Blog dumped to %p\n", (num_leafs * ASP_NAND_BLKSZ), buffer); + + if(audit && audit_allowed) + { + status = audit_blog(band, buffer, num_leafs, verbose); + } + +FreeMemory : + + free(page_buffer); + free(leaf_ptr); + return status; +} + +static uint32_t asp_istlc(bool verbose) { + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_ISTLC; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to get if device is TLC\n"); + return -1; + } else { + if(verbose) + { + printf("istlc: %d\n", command->tunnel.options.value); + } + return command->tunnel.options.value; + } +} + +static uint32_t get_rma_chunk(uint32_t channel, uint32_t startPage, uint8_t *bounceBuffer, uint32_t buffLen) { + uint32_t paddr32; + + paddr32 = VADDR_TO_PADDR32(bounceBuffer); + memset(bounceBuffer, 0xA5, buffLen); + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_RMA_DATA; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = buffLen; + command->tunnel.options.mask = ((1<tunnel.options.value = startPage; + + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, bounceBuffer, ROUNDUPTO(buffLen,CPU_CACHELINE_SIZE)); +#endif + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)){ + dprintf(DEBUG_CRITICAL, "Unable to pull rma data for channel %d\n",channel); + return -1; + } +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, bounceBuffer, ROUNDUPTO(buffLen,CPU_CACHELINE_SIZE)); +#endif + + return 0; +} + +static uint32_t asp_recover() { + aspproto_cmd_t * command; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_RECOVER; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Unable to recover NAND\n"); + return -1; + } + + printf("NAND recovered\n"); + return 0; +} + +static uint32_t asp_rma_delete(uint32_t channel) { + aspproto_cmd_t * command; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_DELETE_RMA_DATA; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Unable to delete rma data for channel %d\n",channel); + return -1; + } + + printf("RMA deleted from channel %d\n",channel); + return 0; +} + +static uint32_t asp_rma_configure(uint32_t channel, uint32_t mask) { + aspproto_cmd_t * command; + + mask &= 0x0F; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_CONFIGURE_RMA_DATA; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tunnel.options.value = mask; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Unable to configure rma data for channel %d with mask 0x%x\n", channel, mask); + return -1; + } + + printf("RMA configured on channel %d with mask 0x%x\n",channel,mask); + return 0; +} + +static uint32_t asp_rma_set(uint32_t channel) { + aspproto_cmd_t * command; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_TRIGGER_RMA_DATA; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Unable to set RMA data for channel %d\n", channel); + return -1; + } + + printf("Set RMA data with address FFh FFh FFh on channel %d\n",channel); + return 0; +} + +static uint32_t asp_rma_get(uint32_t channel, char *destFile, uint32_t *failure_type) { + aspproto_cmd_t * command; + uint8_t *bounceBuffer; + uint32_t buffLen; + uint32_t startPage; + uint32_t totalPages; + uint32_t pagesRemaining; + uint32_t numPages; + uint32_t chunkSize; + uint32_t paddr32; + uint32_t status; + + buffLen = sizeof(nand_debug_failure_info_t); + bounceBuffer = memalign(buffLen, 4096); + if(!bounceBuffer) + { + dprintf(DEBUG_CRITICAL, "Failed to allocate data buffer\n"); + return -1; + } + paddr32 = VADDR_TO_PADDR32(bounceBuffer); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_FAILURE_INFO; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = buffLen; + command->tunnel.options.mask = ((1<tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Unable to trigger Debug Data for channel %d\n",channel); + free(bounceBuffer); + return -1; + } +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, bounceBuffer, ROUNDUPTO(buffLen,CPU_CACHELINE_SIZE)); +#endif + + if (NULL != destFile) { + startPage = ((nand_debug_failure_info_t *)bounceBuffer)->start_page; + totalPages = ((nand_debug_failure_info_t *)bounceBuffer)->page_len; + if (NULL != failure_type) { + *failure_type = ((nand_debug_failure_info_t *)bounceBuffer)->failure_type; + } + + //pull the debug data pages + buffLen = MAX_RMA_CHUNK_PAGES * PERFECT_PAGE_SIZE; + free(bounceBuffer); + bounceBuffer = memalign(buffLen, 4096); + if(!bounceBuffer) { + dprintf(DEBUG_CRITICAL, "Failed to allocate data buffer\n"); + return -1; + } + + + printf("\033[1;31m"); // change font color to red & bold + for (pagesRemaining = totalPages; pagesRemaining > 0; pagesRemaining -= numPages) { + printf("Status: %d%%, Pages: %d/%d ", (totalPages - pagesRemaining) * 100 / totalPages, totalPages - pagesRemaining, totalPages); + + numPages = MIN(pagesRemaining,MAX_RMA_CHUNK_PAGES); + chunkSize = numPages * PERFECT_PAGE_SIZE; + + if (get_rma_chunk(channel, startPage, bounceBuffer, chunkSize) != 0) { + break; + } + addr_t loadAddr = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + memcpy( ((void*)loadAddr),bounceBuffer,chunkSize); + + status = usb_send_data_to_file(destFile, chunkSize, loadAddr, 0); + if (status) { + printf("usb_cmd_put failed ret = 0x%x\n", status); + printf("\033[0m\n"); // change font color back to default + free(bounceBuffer); + return -1; + } + + startPage += numPages; + printf("\033[0E\033[2K"); // go to start of line and erase the line respectively + } + + printf("Status: %d%%, Pages: %d/%d", (totalPages - pagesRemaining) * 100 / totalPages, totalPages - pagesRemaining, totalPages); + printf("\033[0m\n"); // change font color back to default + + } + + asp_recover(); + free(bounceBuffer); + + return 0; +} + +static uint32_t asp_ppn_get_calibration(char *destFile) { + aspproto_cmd_t * command; + uint8_t *bounceBuffer; + uint32_t buffLen; + uint32_t paddr32; + uint32_t status; + + buffLen = PERFECT_PAGE_SIZE; + bounceBuffer = memalign(buffLen, 4096); + if(!bounceBuffer) + { + dprintf(DEBUG_CRITICAL, "Failed to allocate data buffer\n"); + return -1; + } + paddr32 = VADDR_TO_PADDR32(bounceBuffer); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_CALIBRATION; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = buffLen; + command->tunnel.options.mask = ((1<tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Unable to get calibration data\n"); + free(bounceBuffer); + return -1; + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, bounceBuffer, buffLen); +#endif + + addr_t loadAddr = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + memcpy( ((void*)loadAddr),bounceBuffer,buffLen); + + if (NULL != destFile) { + status = usb_send_data_to_file(destFile, buffLen, loadAddr, 0); + if (status) { + printf("usb_cmd_put failed ret = 0x%x\n", status); + free(bounceBuffer); + return -1; + } + } else { + printf("PPN calibration data extraced to address %p. Save to host by running 'usb put %u'\n", + (void *)loadAddr, buffLen); + } + + free(bounceBuffer); + + return 0; +} + +static uint32_t asp_vth_sweep(uint32_t channel, uint32_t cau, uint32_t block, char *destFile) +{ + aspproto_cmd_t * command; + uint32_t rowAddr; + uint32_t status; + uint32_t failure_type; + + // bounds check the parameters + if (channel >= nand_info.num_bus || cau >= (nand_info.cau_per_die * nand_info.die_per_bus) || block >= nand_info.num_bands) { + printf("Invalid parameter. Max bus=%d \n", nand_info.num_bus); + return -1; + } + + // get manufID to check for supported vendor + if ((asp.mfg_id[0][0] != VENDOR_CODE__HYNIX) && (asp.mfg_id[0][0] != VENDOR_CODE__SANDISK) && (asp.mfg_id[0][0] != VENDOR_CODE__MICRON)) { + printf("Vendor 0x%x not supported!\n", asp.mfg_id[0][0]); + return -1; + } + + // get the row address + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CBP_TO_ROW_ADDR; + command->addr_xlate.cau = cau; + command->addr_xlate.block = block; + command->addr_xlate.page = 0; + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) { + dprintf(DEBUG_CRITICAL, "Failed to get row address: %d\n", status); + return -1; + } + rowAddr = command->addr_xlate.row_addr; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_VTH_SWEEP; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tunnel.options.value = rowAddr; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)) { + dprintf(DEBUG_CRITICAL, "Unable to perform Vth sweep for channel %d\n",channel); + return -1; + } + + status = asp_rma_get(channel, destFile, &failure_type); + if (0 != status) { + printf("Vth sweep failed to get RMA data\n"); + return -1; + } + + if (PPN_GEB_TYPE_VTHSWEEP != failure_type) { + printf("Vth sweep expected failure type 0x%X, received 0x%X\n", PPN_GEB_TYPE_VTHSWEEP, failure_type); + return -1; + } + + return 0; +} + +static uint32_t find_sectors_per_stripe (uint32_t sectors_per_band) +{ + const uint32_t sec_per_dip = nand_info.sec_per_full_band / nand_info.num_dip; + + return (sectors_per_band / sec_per_dip) * nand_info.sec_per_page; +} + +#define DEBUG_LARGE_HEAP_HACK (0) + +#if DEBUG_LARGE_HEAP_HACK +//***HACK: iBoot does not support such a large heap. +// However it has a large hole of free unmanaged memory below IBOOT_BASE (defined in memmap.h) +// Define IBOOT_HACK_ADDR well below IBOOT_BASE and use it. +#define IBOOT_HACK_ADDR (0x8397FB000) //currently set to 64MB below IBOOT_BASE +#endif // #if DEBUG_LARGE_HEAP_HACK + +static int asp_bonfire_write_band(uint32_t band, aspproto_cell_type_t cell_type, bool random_pattern, uint32_t data_pattern) +{ + uint8_t *dataBuf = NULL; + uint32_t paddr32; + aspproto_cmd_t * command; + int status; + uint32_t sectors_per_band; + uint32_t band_size; + uint32_t i; + + if((band < 1) || (band > asp.lastBand)) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + sectors_per_band = (uint32_t) asp_sectors_per_band(band, false); + if(0 == sectors_per_band) + { + printf("Cannot program band - It has 0 good sectors.\n"); + return -1; + } + + band_size = sectors_per_band * ASP_NAND_BLKSZ; + +#if DEBUG_LARGE_HEAP_HACK + dataBuf = (uint8_t *)IBOOT_HACK_ADDR; +#else + // Provide a 4k buffer which will be written for the entire band. + band_size = ASP_NAND_BLKSZ; + dataBuf = memalign(band_size, ASP_NAND_BLK_ALIGNMENT); +#endif //#if DEBUG_LARGE_HEAP_HACK + + if(!dataBuf) + { + printf("could not allocate stats buffer\n"); + return -1; + } + + assert((band_size % sizeof(data_pattern)) == 0); + for(i = 0; i < band_size / sizeof(data_pattern); i++) + { + if(!random_pattern) + { + ((uint32_t *)dataBuf)[i] = data_pattern; + } + else + { + ((uint32_t *)dataBuf)[i] = rand(); + } + } + + paddr32 = VADDR_TO_PADDR32(dataBuf); + + command = asp_get_cmd_for_tag(ASP_TAG_NAND); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_WRITE_BAND; + command->tunnel.buffer_paddr = (uint64_t) paddr32; + command->tunnel.bufferLen = band_size; + command->tunnel.options.outputLen = 0; + command->tunnel.options.debug_epr_info.band = band; + command->tunnel.options.debug_epr_info.cell_type = cell_type; + command->flags.all = 0; + command->flags.noAesKey = 1; + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not write band. Error: %d\n\n", status); + asp_print_status_key(); + return -1; + } + +#if !DEBUG_LARGE_HEAP_HACK + free(dataBuf); +#endif //#if DEBUG_LARGE_HEAP_HACK + + return 0; +} + +static int asp_bonfire_erase_band(uint32_t band) +{ + aspproto_cmd_t * command; + int status; + + if((band < 1) || (band > asp.lastBand)) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + if(!asp.writable) + { + printf("Need to make system writable. Execute 'asp setwritable' first\n"); + return -1; + } + + command = asp_get_cmd_for_tag(ASP_TAG_NAND); + + command->op = ASPPROTO_CMD_BONFIRE_ERASE; + command->lba = band; + + status = asp_send_command(command->tag); + printf("Band: %d erase status: 0x%X. \n", band, status); + return 0; + +} + +static aspproto_nand_col_t asp_get_single_dip_info(uint32_t dip) +{ + aspproto_cmd_t * command; + int status; + + command = asp_get_cmd_for_tag(ASP_TAG_NAND); + + command->op = ASPPROTO_CMD_GET_DIP_INFO; + command->lba = dip; + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + printf("Error getting info for dip %d. status: 0x%X\n", dip, status); + } + return command->dip_info; +} + +static int asp_get_all_dip_info(void) +{ + uint32_t i = 0; + aspproto_nand_col_t dip_info; + + for(i = 0; i < nand_info.num_dip; i++) + { + dip_info = asp_get_single_dip_info(i); + printf("dip: %d - bus: %d, ce: %d, cau: %d\n", i, dip_info.bus, dip_info.ce, dip_info.cau); + } + return 0; +} + +static int asp_dbp2r(uint32_t dip, uint32_t bork, uint32_t page) +{ + aspproto_nand_col_t dip_info; + aspproto_cmd_t * command; + int status; + + if(dip < nand_info.num_dip) + { + dip_info = asp_get_single_dip_info(dip); + } + else + { + dprintf(DEBUG_CRITICAL, "dip: %d exceeds maximum number of dips: %d\n", dip, nand_info.num_dip); + return -1; + } + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_CBP_TO_ROW_ADDR; + command->addr_xlate.cau = dip_info.cau; + command->addr_xlate.block = bork; + command->addr_xlate.page = page; + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get row address: %d\n", status); + printf("ce: %d cau: %d, blk: %d, page: %d\n", dip_info.ce, dip_info.cau, bork, page); + return -1; + } + printf("dip: %d, bork: %d, page: %d --> bus: %d row_addr: 0x%X\n", + dip, bork, page, dip_info.bus, command->addr_xlate.row_addr); + + return 0; +} + +static int asp_get_waterfall_table_size() +{ + uint32_t table_size = 0; + aspproto_cmd_t * command; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_WATERFALL_TBL_SIZE; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not get waterfall table size.\n\n"); + return -1; + } + + table_size = command->tunnel.options.outputLen; + assert(!(table_size % SIZE_OF_WFALL_TBL_ENTRY)); + printf("Waterfall table size: %d bytes\n", table_size); + return table_size; +} + +static int asp_erase_band(uint32_t band, aspproto_cell_type_t cell_type, bool verbose) +{ + aspproto_cmd_t * command; + int status; + + if((band < 1) || (band > asp.lastBand)) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_ERASE_BAND; + command->tunnel.options.debug_epr_info.band = band; + command->tunnel.options.debug_epr_info.cell_type = cell_type; + + status = asp_send_command(command->tag); + if(verbose) + { + printf("Band: %d erase status: 0x%X. \n", band, status); + } + + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + asp_print_status_key(); + dprintf(DEBUG_CRITICAL, "ERROR: Could not erase band %d\n\n", band); + return -1; + } + return 0; +} + +static int asp_read_verify(uint32_t band) +{ + aspproto_cmd_t * command; + uint64_t perf_ticks0; + uint64_t perf_ticks1; + uint64_t link_clk_freq; + uint32_t pages_verified = 0; + + if((band < 1) || (band > asp.lastBand)) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + if(0 != asp_reset_perf_ticks()) + { + return -1; + } + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_READ_VERIFY_BAND; + command->tunnel.options.debug_epr_info.band = band; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not read verify band.\n\n"); + return -1; + } + pages_verified += command->tunnel.options.debug_epr_info.output_value; + + if(0 != asp_get_perf_ticks(false, &perf_ticks0, 0)) + { + return -1; + } + if(0 != asp_get_perf_ticks(false, &perf_ticks1, 1)) + { + return -1; + } + + if(0 != asp_get_link_clk_freq(false, &link_clk_freq)) + { + return -1; + } + + printf("Ch0: %u bytes verified in %llu ticks @ %llu Hz\n\n", (pages_verified * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks0, + link_clk_freq); + printf("Ch1: %u bytes verified in %llu ticks @ %llu Hz\n\n", (pages_verified * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks1, + link_clk_freq); + + printf("Ch0: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (pages_verified * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks0); + printf("Ch1: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (pages_verified * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks1); + + printf("Note: This is actual bus utilization with negligible overhead.\n"); + + return 0; +} + + +static int asp_get_timing_parameters(aspproto_nand_timing_params_t *buf) +{ + uint32_t paddr32; + aspproto_nand_timing_params_t *timing_params = NULL; + aspproto_cmd_t *command; + + timing_params = memalign(sizeof(aspproto_nand_timing_params_t), ASP_NAND_BLK_ALIGNMENT); + if(!timing_params) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate data_buffer\n"); + return -1; + } + + memset(timing_params, 0x00, sizeof(aspproto_nand_timing_params_t)); + paddr32 = VADDR_TO_PADDR32(timing_params); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_PPN_TIMING; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = sizeof(aspproto_nand_timing_params_t); + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not get timing parameters.\n\n"); + free(timing_params); + return -1; + } + + memcpy(buf, timing_params, sizeof(aspproto_nand_timing_params_t)); + + free(timing_params); + return 0; +} + +static int asp_get_device_parameters(aspproto_ppn_device_params_t *buf) +{ + uint32_t paddr32; + aspproto_ppn_device_params_t *device_params = NULL; + aspproto_cmd_t * command; + + device_params = memalign(sizeof(aspproto_ppn_device_params_t), ASP_NAND_BLK_ALIGNMENT); + if(!device_params) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate data_buffer\n"); + return -1; + } + memset(device_params, 0x00, sizeof(aspproto_ppn_device_params_t)); + paddr32 = VADDR_TO_PADDR32(device_params); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_PPN_GEOM; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = sizeof(aspproto_ppn_device_params_t); + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not get waterfall table.\n\n"); + free(device_params); + return -1; + } + + memcpy(buf, device_params, sizeof(aspproto_ppn_device_params_t)); + + free(device_params); + return 0; +} + + +static int asp_print_ppn_parameters(void) +{ + aspproto_ppn_device_params_t device_params; + aspproto_nand_timing_params_t timing_params; + int status; + + status = asp_get_device_parameters(&device_params); + status |= asp_get_timing_parameters(&timing_params); + + if(!status) + { + printf("Device parameters:\n"); + printf("caus_per_channel: %d\n", device_params.caus_per_channel); + printf("cau_bits: %d\n", device_params.cau_bits); + printf("blocks_per_cau: %d\n", device_params.blocks_per_cau); + printf("block_bits: %d\n", device_params.block_bits); + printf("pages_per_block: %d\n", device_params.pages_per_block); + printf("pages_per_block_slc: %d\n", device_params.pages_per_block_slc); + printf("page_address_bits: %d\n", device_params.page_address_bits); + printf("address_bits_bits_per_cell: %d\n", device_params.address_bits_bits_per_cell); + printf("default_bits_per_cell: %d\n", device_params.default_bits_per_cell); + printf("page_size: %d\n", device_params.page_size); + printf("dies_per_channel: %d\n", device_params.dies_per_channel); + printf("block_pairing_scheme: %d\n", device_params.block_pairing_scheme); + printf("bytes_per_row_address: %d\n", device_params.bytes_per_row_address); + printf("pages_in_block0: %d\n", device_params.pages_in_block0); + printf("pages_in_read_verify: %d\n", device_params.pages_in_read_verify); + printf("multi_cau_bits: %d\n", device_params.multi_cau_bits); + printf("pattern_bits: %d\n", device_params.pattern_bits); + printf("channel0_die: %d\n",device_params.channel0_die); + printf("package_blocks_at_EOL: %d\n", device_params.package_blocks_at_EOL); + printf("tRC: %d\n", timing_params.tRC_ns); + printf("tREA: %d\n", timing_params.tREA_ns); + printf("tREH: %d\n", timing_params.tREH_ns); + printf("tRHOH: %d\n", timing_params.tRHOH_ns); + printf("tRHZ: %d\n", timing_params.tRHZ_ns); + printf("tRLOH: %d\n", timing_params.tRLOH_ns); + printf("tRP: %d\n", timing_params.tRP_ns); + printf("tWC: %d\n", timing_params.tWC_ns); + printf("tWH: %d\n", timing_params.tWH_ns); + printf("tWP: %d\n", timing_params.tWP_ns); + printf("read_queue_size: %d\n", device_params.read_queue_size); + printf("program_queue_size: %d\n", device_params.program_queue_size); + printf("erase_queue_size: %d\n", device_params.erase_queue_size); + printf("prep_function_buffer_size: %d\n", device_params.prep_function_buffer_size); + printf("tRST: %d\n", timing_params.tRST_ms); + printf("tPURST: %d\n", timing_params.tPURST_ms); + printf("tSCE: %d\n", timing_params.tSCE_ms); + printf("tCERDY: %d\n", timing_params.tCERDY_us); + printf("caus_per_package: %d\n", device_params.caus_per_package); + printf("dies_per_package: %d\n", device_params.dies_per_package); + printf("tRC_ddr: %d\n", timing_params.tRC_ddr_ns); + printf("tREH_ddr: %d\n", timing_params.tREH_ddr_ns); + printf("tRP_ddr: %d\n", timing_params.tRP_ddr_ns); + printf("tDQSL: %d\n", timing_params.tDQSL_ps); + printf("tDQSH: %d\n", timing_params.tDQSH_ps); + printf("tDSC: %d\n", timing_params.tDSC_ps); + printf("tDQSRE: %d\n", timing_params.tDQSRE_ps); + printf("tDQSQ: %d\n", timing_params.tDQSQ_ps); + printf("tDVW: %d\n", timing_params.tDVW_ps); + printf("max_interface_speed: %d\n", timing_params.max_interface_speed_mhz); + printf("\n"); + printf("num_bus: %d\n", device_params.num_bus); + printf("ces_per_bus: %d\n", device_params.ces_per_bus); + printf("logical_page_size: %d\n", device_params.logical_page_size); + } + + return status; +} + +static uint32_t tlc_pattern = 0; + +static int get_tlc_pattern(void) +{ + aspproto_ppn_device_params_t *device_params; + + device_params = NULL; + device_params = (aspproto_ppn_device_params_t *) malloc(sizeof(aspproto_ppn_device_params_t)); + assert(device_params); + asp_get_device_parameters(device_params); + + if((tlc_pattern >= (uint32_t)((1 << device_params->pattern_bits) - 1))) + { + tlc_pattern = 0; + } else { + tlc_pattern++; + } + return tlc_pattern; +} + +static uint32_t test_pattern = 0; + +static int asp_bonfire_group_a_slc(uint32_t seed) +{ + aspproto_cmd_t * command; + + printf("Opening ASP\n"); + if (!asp_send_open()) + { + dprintf(DEBUG_CRITICAL, "Unable to open ASP\n"); + return false; + } + + printf("Setting writable\n"); + if (!asp_set_writable()) + { + asp.state = ASP_STATE_ERROR_NOT_WRITABLE; + printf("Unable to set writable\n"); + return false; + } + + assert(bonfire_slc_state == BONFIRE_SLC_STATE_NONE); + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_BONFIRE_SLC_GROUP_A; + command->tunnel.options.value = seed; + command->flags.all = 0; + command->flags.noAesKey = 1; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not group A for SLC Bonfire.\n\n"); + return -1; + } + + bonfire_slc_state = BONFIRE_SLC_STATE_A; + + asp_get_geometry(); + + return 0; +} + +static int asp_bonfire_group_b_slc(void) +{ + aspproto_cmd_t * command; + + assert(bonfire_slc_state == BONFIRE_SLC_STATE_A); + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_BONFIRE_SLC_GROUP_B; + command->flags.all = 0; + command->flags.noAesKey = 1; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not group A for SLC Bonfire.\n\n"); + return -1; + } + + bonfire_slc_state = BONFIRE_SLC_STATE_B; + + asp_get_geometry(); + + return 0; +} + +static int asp_bonfire_ungroup(void) +{ + aspproto_cmd_t * command; + + assert(bonfire_slc_state == BONFIRE_SLC_STATE_B); + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_BONFIRE_SLC_UNGROUP; + command->flags.all = 0; + command->flags.noAesKey = 1; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not group A for SLC Bonfire.\n\n"); + return -1; + } + + bonfire_slc_state = BONFIRE_SLC_STATE_NONE; + + asp_get_geometry(); + + return 0; +} + +static int asp_write_band(uint32_t band, aspproto_cell_type_t cell_type, bool verbose, bool random_pattern, uint32_t data_pattern) +{ + aspproto_cmd_t * command; + uint8_t * dataBuf; + uint32_t paddr32; + uint64_t perf_ticks0; + uint64_t perf_ticks1; + uint64_t link_clk_freq; + uint32_t pages_written = 0; + uint32_t pages_in_block; + uint32_t join_program_pages; + aspproto_cmd_status_e status; + uint32_t i; + uint32_t band_size = 0; + uint32_t buffer_length = 0; + uint32_t sectors_per_band; + + if((band < 1) || (band > asp.lastBand)) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + sectors_per_band = (uint32_t) asp_sectors_per_band(band, false); + if(0 == sectors_per_band) + { + printf("Cannot program band - It has 0 good sectors.\n"); + return -1; + } + + band_size = sectors_per_band * ASP_NAND_BLKSZ; + + join_program_pages = (cell_type == CELL_TYPE_IS_TLC) ? 3 : 1; + pages_in_block = (cell_type == CELL_TYPE_IS_SLC) ? nand_info.pages_per_block_slc : nand_info.pages_per_block; + + if(0 != asp_reset_perf_ticks()) + { + return -1; + } + +#if DEBUG_LARGE_HEAP_HACK + buffer_length = band_size; + dataBuf = (uint8_t *)IBOOT_HACK_ADDR; +#else + buffer_length = ASP_NAND_BLKSZ; + dataBuf = memalign(buffer_length, ASP_NAND_BLK_ALIGNMENT); +#endif //#if DEBUG_LARGE_HEAP_HACK + if(!dataBuf) + { + printf("could not allocate data buffer\n"); + return -1; + } + + assert((buffer_length % sizeof(data_pattern)) == 0); + for(i = 0; i < buffer_length / sizeof(data_pattern); i++) + { + if(!random_pattern) + { + ((uint32_t *)dataBuf)[i] = data_pattern; + } + else + { + ((uint32_t *)dataBuf)[i] = rand(); + } + } + + paddr32 = VADDR_TO_PADDR32(dataBuf); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_WRITE_BAND; + command->tunnel.options.debug_epr_info.band = band; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = buffer_length; + command->tunnel.options.debug_epr_info.cell_type = cell_type; + command->flags.all = 0; + command->flags.noAesKey = 1; + if(cell_type == CELL_TYPE_IS_TLC) + { + command->tunnel.options.debug_epr_info.tlc_pattern = test_pattern++; + } + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not write band. Error: %d\n\n", status); + asp_print_status_key(); + return -1; + } + pages_written = command->tunnel.options.debug_epr_info.output_value; + + if(0 != asp_get_perf_ticks(false, &perf_ticks0, 0)) + { + return -1; + } + if(0 != asp_get_perf_ticks(false, &perf_ticks1, 1)) + { + return -1; + } + + if(0 != asp_get_link_clk_freq(false, &link_clk_freq)) + { + return -1; + } + + if(verbose) + { + printf("Ch0: %u bytes transferred in %llu ticks @ %llu Hz\n\n", (pages_written * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks0, + link_clk_freq); + printf("Ch1: %u bytes transferred in %llu ticks @ %llu Hz\n\n", (pages_written * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks1, + link_clk_freq); + + printf("Ch0: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (pages_written * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks0); + printf("Ch1: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (pages_written * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks1); + + printf("Ch0: Time for each superstripe in us: (%llu / %d) / (%llu / 1000000)\n\n", perf_ticks0, (pages_in_block / join_program_pages), link_clk_freq); + printf("Ch1: Time for each superstripe in us: (%llu / %d) / (%llu / 1000000)\n\n", perf_ticks1, (pages_in_block / join_program_pages), link_clk_freq); + + printf("Note: This is actual bus utilization with negligible overhead.\n"); + } + return 0; +} + +static int asp_eploop_band(uint32_t band, aspproto_cell_type_t cell_type, uint32_t seconds, bool random_pattern, uint32_t data_pattern) +{ + uint64_t start_ticks; + uint32_t iterations; + + start_ticks = system_time(); + + if((band < 1) || (band > asp.lastBand)) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + if(seconds) + { + printf("Going to erase+program band: %d for %d seconds. cell_type: %d\n", band, seconds, cell_type); + } + else + { + printf("Going to erase+program band: %d once. cell_type: %d\n", band, cell_type); + } + + iterations = 0; + while(1) + { + if(-1 == asp_erase_band(band, cell_type, false)) + { + printf("error erasing band. returning\n"); + return -1; + } + if(-1 == asp_write_band(band, cell_type, false, random_pattern, data_pattern)) + { + printf("error programming band. returning\n"); + return -1; + } + iterations++; + + if(0 == seconds) + { + break; + } + else if(time_has_elapsed(start_ticks, (uint64_t)seconds * 1000000)) + { + break; + } + } + printf("Completed %d iterations.\n", iterations); + return 0; +} + +static int asp_get_waterfall_table(uint8_t *buffer) +{ + uint32_t paddr32; + uint32_t table_size = 0; + uint8_t *table = NULL; + aspproto_cmd_t * command; + + table_size = asp_get_waterfall_table_size(); + + if (!security_allow_memory(buffer, table_size)) + { + printf("Permission Denied\n"); + return -1; + } + memset(buffer, 0xA5, table_size); + + table = memalign(table_size, ASP_NAND_BLK_ALIGNMENT); + if(!table) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate data_buffer\n"); + return -1; + } + memset(table, 0x00, table_size); + paddr32 = VADDR_TO_PADDR32(table); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_WATERFALL_TABLE; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = table_size; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not get waterfall table.\n\n"); + return -1; + } + + memcpy(buffer, table, table_size); + + printf("Waterfall table available at address: %p\n", buffer); + + free(table); + return 0; +} + +static int asp_get_dm(void) +{ + uint8_t *dmBuf = NULL; + ExportDefects_t *defects = NULL; + uint32_t dmBufSize; + uint32_t paddr32; + aspproto_cmd_t * command; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_EXPORT_BAND_DEFECTS; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.outputLen = 0; + command->tunnel.options.flags.forceExport = 1; + command->tunnel.options.flags.sizeOnly = 1; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: no defect management list found\n\n"); + asp.state = ASP_STATE_ERROR_INVALID_PPNFW; + return -1; + } + dmBufSize = command->tunnel.options.outputLen; + + if (dmBufSize == 0){ + dprintf(DEBUG_CRITICAL, "ERROR: defect management list returned size 0"); + return -1; + } + + //get the defect list + dmBuf = memalign(dmBufSize, ASP_NAND_BLK_ALIGNMENT); + if(!dmBuf) + { + dprintf(DEBUG_CRITICAL, "Unable to allocate data_buffer\n"); + return -1; + } + memset(dmBuf, 0x00, dmBufSize); + paddr32 = VADDR_TO_PADDR32(dmBuf); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_EXPORT_BAND_DEFECTS; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = dmBufSize; + command->tunnel.options.flags.forceExport = 1; + command->tunnel.options.flags.sizeOnly = 0; + + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS){ + dprintf(DEBUG_CRITICAL, "ERROR: failed to get the defect management list\n\n"); + asp.state = ASP_STATE_ERROR_INVALID_PPNFW; + free(dmBuf); + return -1; + } + defects = (ExportDefects_t *)dmBuf; + + //ensure that grownBadCount doesn't exceed the buffersize + if(defects->grownBadCount * sizeof(ExportDefectEntry_t) + sizeof(ExportDefects_t) - sizeof(uint32_t) > dmBufSize){ + dprintf(DEBUG_CRITICAL, "ERROR: number of defects, %d, exceeds buffersize of %d bytes\n",defects->grownBadCount, dmBufSize); + free(dmBuf); + return -1; + } + + //print the dm list + if (defects->grownBadCount == 0){ + printf("No Grown Bad Blocks Found\n"); + } else { + printf("Grown Bad Blocks:\n"); + ExportDefectEntry_t * exportDefectEntries = (ExportDefectEntry_t *) &defects->exportDefectEntriesPtr; + for(uint32_t i=0; i < defects->grownBadCount; i++) + { + printf("bus: %d, ce: %d, cau: %d -> block: %d cycles: %d reason: 0x%x\n", + exportDefectEntries[i].bus, + exportDefectEntries[i].ce, + exportDefectEntries[i].cau, + exportDefectEntries[i].band, + exportDefectEntries[i].cycles, + exportDefectEntries[i].reason); + } + } + + free(dmBuf); + return 0; +} + +static int asp_get_bbt(void) +{ + uint8_t *bbtBuf = NULL; + uint32_t paddr32; + uint32_t numSec = 0; + uint32_t numDip = 0; + uint32_t numBand = 0; + uint32_t dip = 0; + uint32_t band = 0; + uint32_t mask = 0; + uint32_t statsBufSize = 0; + uint8_t *dipPtr = NULL; + uint8_t *bandPtr = NULL; + aspproto_nand_col_t dip_info; + aspproto_cmd_t * command; + int status; + + numSec = (nand_info.num_bands + 7) / 8; // bit per band round up to number of bytes. + numSec = (numSec + (ASP_NAND_BLKSZ-1)) / ASP_NAND_BLKSZ; // then round number of bytes up to number of sector + numDip = nand_info.num_dip; + numBand = nand_info.num_bands; + statsBufSize = numDip * numSec * ASP_NAND_BLKSZ; + + bbtBuf = memalign(statsBufSize, ASP_NAND_BLK_ALIGNMENT); + if(!bbtBuf) + { + printf("could not allocate BBT buffer\n"); + return -1; + } + memset(bbtBuf, 0x00, statsBufSize); + paddr32 = VADDR_TO_PADDR32(bbtBuf); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_GET_BBT; + command->count = numDip * numSec; + command->sglAndIv[0] = paddr32; + + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get BBT: %d\n", status); + return -1; + } + + printf("BBT:\n"); + for(dip = 0; dip < numDip; dip++) + { + dip_info = asp_get_single_dip_info(dip); + + dipPtr = bbtBuf + (dip *numSec * ASP_NAND_BLKSZ); + for(band=0; band < numBand; band++) + { + bandPtr = dipPtr + (band/8); + mask = (0x80 >> (band % 8)); + if (0 == (*bandPtr & mask)) + { + printf("bus: %d, ce: %d, cau: %d -> block: %d\n", dip_info.bus, dip_info.ce, dip_info.cau, band); + } + } + printf("\n"); + } + + free(bbtBuf); + return 0; +} + +static void output_band_stats(uint32_t *buf32) +{ + uint32_t numBands; + uint32_t band; + uint32_t flags; + uint32_t flow; + uint32_t valid; + uint32_t eraseCycles; + uint32_t age; + uint32_t GCcan; + uint32_t GCmust; + uint32_t GCdone; + uint32_t pFail; + uint32_t mode; + uint32_t maxEraseCnt[NUM_ASP_PARITIONS] = {0, 0}; + uint32_t minEraseCnt[NUM_ASP_PARITIONS] = {~0, ~0}; + uint32_t avgEraseCnt[NUM_ASP_PARITIONS] = {0, 0}; + uint32_t maxAge[NUM_ASP_PARITIONS] = {0, 0}; + uint32_t firstBand[NUM_ASP_PARITIONS]; + uint32_t lastBand[NUM_ASP_PARITIONS]; + uint32_t * statsPtr; + uint32_t partitions = 0; + uint32_t partition; + + printf ( "Band stats:\n" ); + printf ( "===========\n" ); + + numBands = *buf32++; + partitions = *buf32++; + + assert(partitions <= NUM_ASP_PARITIONS); + + for(partition = 0; partition < partitions; partition++) { + firstBand[partition] = *buf32++; + lastBand[partition] = *buf32++; + } + + statsPtr = buf32; + + for (band = 0; band < numBands; band++) + { + flags = *buf32++; + flow = *buf32++; + valid = *buf32++; + eraseCycles = *buf32++; + age = *buf32++; + + for(partition = 0; partition < partitions; partition++) { + if((band >= firstBand[partition]) && (band <= lastBand[partition])) + { + if(band == firstBand[partition]) + { + printf("\n%s:\n", partition_names[partition]); + } + break; + } + } + + if(partition < partitions) + { + maxAge[partition] = MAX(maxAge[partition], age); + maxEraseCnt[partition] = MAX(maxEraseCnt[partition], eraseCycles); + minEraseCnt[partition] = MIN(minEraseCnt[partition], eraseCycles); + avgEraseCnt[partition] += eraseCycles; + } + + GCcan = flags & 1; + GCmust = (flags >> 1) & 1; + GCdone = (flags >> 2) & 1; + pFail = (flags >> 3) & 1; + mode = (flags >> 4) & 0x3; + + if (~0U != valid) + { + printf("band:%4d\tflow:%2d\tvalid:%5d\terases:%5d\tage:%5d\tGCcan:%d GCmust:%d GCDone: %d pFail: %d mode:%d\n", + band, flow, valid, eraseCycles, age, GCcan, GCmust, GCdone, pFail, mode); + } + else + { + printf("band:%4d\tflow:%2d\tvalid: NA\terases:%5d\tage:%5d\tGCcan:%d GCmust:%d GCDone: %d pFail: %d mode:%d\n", + band, flow, eraseCycles, age, GCcan, GCmust, GCdone, pFail, mode); + } + + } + + for(partition = 0; partition < partitions; partition++) { + if(lastBand[partition] >= firstBand[partition]) { + avgEraseCnt[partition] = avgEraseCnt[partition] / (lastBand[partition] + 1 - firstBand[partition]); + printf("%s : Erase Cycles: Max ( %d ) Min ( %d ) Avg ( %d )\n", partition_names[partition], + maxEraseCnt[partition], minEraseCnt[partition], avgEraseCnt[partition]); + printf(" Max band age: ( %d )\n", maxAge[partition]); + } + } +} + +static int asp_get_band_stats(void) +{ + uint8_t *buffer = NULL; + uint32_t paddr32; + uint32_t statsBufSize = 0; + aspproto_cmd_t * command = NULL; + int status; + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + if(!command) + { + return -1; + } + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_READ_BAND_STATS; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.outputLen = 0; + command->tunnel.options.flags.forceExport = 0; + command->tunnel.options.flags.sizeOnly = 1; + + status = asp_send_command(command->tag); + + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get Band Stats 0x%08X\n", status); + return -1; + } + + statsBufSize = command->tunnel.options.outputLen; + + statsBufSize = ALIGN_UP(statsBufSize, ASP_NAND_BLKSZ); + + buffer = memalign(statsBufSize, ASP_NAND_BLK_ALIGNMENT); + if(!buffer) + { + printf("could not allocate Band Stats buffer\n"); + return -1; + } + memset(buffer, 0x00, statsBufSize); + paddr32 = VADDR_TO_PADDR32(buffer); + + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_READ_BAND_STATS; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = statsBufSize; + command->tunnel.options.flags.forceExport = 0; + command->tunnel.options.flags.sizeOnly = 0; + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, buffer, statsBufSize); +#endif + status = asp_send_command(command->tag); + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Failed to get Band Stats 0x%08X\n", status); + free(buffer); + return -1; + } + +#if WITH_NON_COHERENT_DMA + platform_cache_operation(CACHE_INVALIDATE, buffer, statsBufSize); +#endif + output_band_stats((uint32_t *)buffer); + + free(buffer); + return 0; +} + +static bool debug_counter_supported(uint32_t channel) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_DEBUG_COUNTER_SUPPORTED; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tunnel.options.value = 0; + + if ((asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) || (command->tunnel.options.value == 0)) + { + dprintf(DEBUG_CRITICAL, "Unable to get debug counter for channel %d\n",channel); + return false; + } + else + { + dprintf(DEBUG_CRITICAL, "channel %d debug counter supported: %d\n", channel, command->tunnel.options.value); + } + return true; +} + +static bool get_debug_counter(uint32_t channel, uint8_t * buffer) +{ + uint8_t *bounce_buffer = NULL; + uint32_t buffer_size = ASP_NAND_BLKSZ; + bool status = false; + + if (nand_info.num_bus==0) + { + return false; + } + + if (!security_allow_memory(buffer, buffer_size)) + { + printf("Permission Denied\n"); + return -1; + } + memset(buffer, 0xA5, buffer_size); + + bounce_buffer = memalign(buffer_size, ASP_NAND_BLK_ALIGNMENT); + if(!bounce_buffer) + { + dprintf(DEBUG_CRITICAL, "Failed to allocate data buffer\n"); + return -1; + } + memset(bounce_buffer, 0xC7, buffer_size); + + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_GET_DEBUG_COUNTER; + command->tunnel.buffer_paddr = VADDR_TO_PADDR32(bounce_buffer); + command->tunnel.bufferLen = buffer_size; + command->tunnel.options.mask = ((1<tunnel.options.value = 0; + + if (asp_send_command(command->tag) == ASPPROTO_CMD_STATUS_SUCCESS) + { + memcpy(buffer, bounce_buffer, buffer_size); + status = true; + printf("Debug Counter Buffer extracted for ch %d. Save to host by running 'usb put %d'\n", + channel, ASP_NAND_BLKSZ); + } + else + { + dprintf(DEBUG_CRITICAL, "Unable to get debug counter for channel %d\n",channel); + } + + free(bounce_buffer); + return status; +} + +static bool reset_debug_counter(uint32_t channel) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + + command->op = ASPPROTO_CMD_NAND_DEBUG; + command->tunnel.opcode = NAND_DEBUG_RESET_DEBUG_COUNTER; + command->tunnel.buffer_paddr = 0; + command->tunnel.bufferLen = 0; + command->tunnel.options.mask = ((1<tunnel.options.value = 0; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "Unable to reset debug counter for channel %d\n",channel); + return false; + } + else + { + dprintf(DEBUG_CRITICAL, "debug counter reset for channel %d\n",channel); + } + return true; +} + +/*NOTE: This command does not read actual data to host buffer. + It just overwrites a placeholder sector data buffer. + If you need actual data, use 'asp read' + If you need bitflips, use 'asp bonfirereadband' +*/ +static int asp_read_band(uint32_t band, aspproto_cell_type_t cell_type, uint32_t num_stripes, uint32_t seconds) +{ + aspproto_cmd_t * command; + uint8_t * scratch_buffer; //placeholder for putting in page data. every sector. + uint32_t paddr32; + uint64_t start_ticks; + uint64_t perf_ticks0; + uint64_t perf_ticks1; + uint64_t link_clk_freq; + uint64_t pages_read = 0; + uint32_t pages_in_block; + uint32_t join_program_pages; + int status; + + if(band > asp.lastBand) + { + printf("Band %d not allowed. Please choose a band between 1 and %d\n", band, asp.lastBand); + return -1; + } + + join_program_pages = (cell_type == CELL_TYPE_IS_TLC) ? 3 : 1; + pages_in_block = (cell_type == CELL_TYPE_IS_SLC) ? nand_info.pages_per_block_slc : nand_info.pages_per_block; + + if(0 != asp_reset_perf_ticks()) + { + return -1; + } + + scratch_buffer = memalign(ASP_NAND_BLKSZ, ASP_NAND_BLK_ALIGNMENT); + paddr32 = VADDR_TO_PADDR32(scratch_buffer); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_READ_BAND; + command->tunnel.options.debug_epr_info.band = band; + command->tunnel.options.debug_epr_info.cell_type = cell_type; + command->tunnel.options.debug_epr_info.num_stripes = num_stripes; + command->flags.all = 0; + command->flags.noAesKey = 1; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = ASP_NAND_BLKSZ; + start_ticks = system_time(); + + while(1) + { + status = asp_send_command(command->tag); + printf("Finished Band read with status: %d\n", status); + + if (status != ASPPROTO_CMD_STATUS_SUCCESS) + { + asp_print_status_key(); + dprintf(DEBUG_CRITICAL, "ERROR: Could not read band.\n\n"); + return -1; + } + pages_read += command->tunnel.options.debug_epr_info.output_value; + + if(0 == seconds) + { + break; + } + else if(time_has_elapsed(start_ticks, (uint64_t)seconds * 1000000)) + { + break; + } + } + if(0 != asp_get_perf_ticks(false, &perf_ticks0, 0)) + { + return -1; + } + if(0 != asp_get_perf_ticks(false, &perf_ticks1, 1)) + { + return -1; + } + + if(0 != asp_get_link_clk_freq(false, &link_clk_freq)) + { + return -1; + } + + printf("Ch0: %llu bytes transferred in %llu ticks @ %llu Hz\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks0, + link_clk_freq); + printf("Ch1: %llu bytes transferred in %llu ticks @ %llu Hz\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks1, + link_clk_freq); + + printf("Ch0: To calculate total throughput in MiB/s: (%llu * %llu) / (%llu * 1024 * 1024)\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks0); + printf("Ch1: To calculate total throughput in MiB/s: (%llu * %llu) / (%llu * 1024 * 1024)\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks1); + + printf("Ch0: Time for each superstripe in us: (%llu / %d) / (%llu / 1000000)\n\n", perf_ticks0, (pages_in_block / join_program_pages), link_clk_freq); + printf("Ch1: Time for each superstripe in us: (%llu / %d) / (%llu / 1000000)\n\n", perf_ticks1, (pages_in_block / join_program_pages), link_clk_freq); + + printf("Note: This is actual bus utilization with negligible overhead.\n"); + + return 0; +} + +//Make sure these macros are the same in AppleStorageProcessor/src/aspcore/core/cmd.c +#define SLC_TEST_BAND_START 101 +#define SLC_TEST_BAND_END 110 +#define MBC_TEST_BAND_START 111 +#define MBC_TEST_BAND_END 120 + +static bool prefill_complete_slc = false; +static bool prefill_complete_mbc = false; + +static void asp_prefill_bands(aspproto_cell_type_t cell_type) +{ + uint32_t band_idx; + uint32_t start_band; + uint32_t end_band; + + if(cell_type == CELL_TYPE_IS_SLC) + { + if (prefill_complete_slc) + { + return; + } + start_band = SLC_TEST_BAND_START; + end_band = SLC_TEST_BAND_END; + } + else + { + if (prefill_complete_mbc) + { + return; + } + start_band = MBC_TEST_BAND_START; + end_band = MBC_TEST_BAND_END; + } + + printf("Prefilling band: %d to band: %d\n", start_band, end_band); + for(band_idx = start_band; band_idx <= end_band; band_idx++) + { + if(-1 == asp_erase_band(band_idx, cell_type, false)) + { + panic("error erasing band"); + } + if(-1 == (asp_write_band(band_idx, cell_type, false, true, 0))) + { + panic("error writing band"); + } + } + + //Do prefill only once + if(cell_type == CELL_TYPE_IS_SLC) + { + prefill_complete_slc = true; + } + else + { + prefill_complete_mbc = true; + } + printf("Prefill complete\n"); +} + +/* This command does superpage reads in a hard coded range of bands. + It goes dip-by-dip and enqueues a page read. Each of that read may be either SLC or TLC/MLC. + NOTE: This command does not read actual data to host buffer. + It just overwrites a placeholder data buffer. + If you need actual data, use 'asp read' + If you need bitflips, use 'asp bonfirereadband' + The band range is first erassed and programmed. +*/ +static int asp_read_mixed_superpage(uint32_t num_superpages, uint32_t num_stripes, uint32_t seconds) +{ + aspproto_cmd_t * command; + uint8_t * scratch_buffer; //placeholder for putting in page data. every sector. + uint32_t paddr32; + uint64_t start_ticks; + uint32_t iterations = 0; + uint64_t perf_ticks0; + uint64_t perf_ticks1; + uint64_t link_clk_freq; + uint32_t pages_read = 0; + + asp_prefill_bands(CELL_TYPE_IS_SLC); + + if(asp_istlc(false)) + { + asp_prefill_bands(CELL_TYPE_IS_TLC); + } + else + { + asp_prefill_bands(CELL_TYPE_IS_MLC); + } + + printf("Will now start the reads\n"); + + if(0 != asp_reset_perf_ticks()) + { + return -1; + } + + scratch_buffer = memalign(ASP_NAND_BLKSZ, ASP_NAND_BLK_ALIGNMENT); + paddr32 = VADDR_TO_PADDR32(scratch_buffer); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_READ_MIXED_SUPERPAGE; + command->tunnel.options.debug_epr_info.num_sectors = num_superpages; + command->tunnel.options.debug_epr_info.num_stripes = num_stripes; + command->flags.all = 0; + command->flags.noAesKey = 1; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = ASP_NAND_BLKSZ; + + start_ticks = system_time(); + + while(1) + { + iterations++; + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not read band.\n\n"); + return -1; + } + pages_read += command->tunnel.options.debug_epr_info.output_value; + + if(0 == seconds) + { + break; + } + else if(time_has_elapsed(start_ticks, (uint64_t)seconds * 1000000)) + { + break; + } + } + + if(0 != asp_get_perf_ticks(false, &perf_ticks0, 0)) + { + return -1; + } + if(0 != asp_get_perf_ticks(false, &perf_ticks1 , 1)) + { + return -1; + } + + if(0 != asp_get_link_clk_freq(false, &link_clk_freq)) + { + return -1; + } + + printf("Ch0: %u bytes transferred in %llu ticks @ %llu Hz\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks0, + link_clk_freq); + printf("Ch1: %u bytes transferred in %llu ticks @ %llu Hz\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + perf_ticks1, + link_clk_freq); + + printf("Ch0: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks0); + printf("Ch1: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (pages_read * nand_info.sec_per_page * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks1); + + printf("Note: This is actual bus utilization with negligible overhead.\n"); + + return 0; +} + +/* This command does random reads in a hard coded range of bands. + For every page address, 'sectors_per_page' is the number of sectors of that page that is read. + 'num_sectors' is the number of page addresses sent to the NAND. + 'num_stripes' is the number of stripes done in one read transaction. + 'same_die' determines if in a stripe, pages on the same die are read, or not, or if its random. + NOTE: This command does not read actual data to host buffer. + It just overwrites a placeholder sector data buffer. + If you need actual data, use 'asp read' + If you need bitflips, use 'asp bonfirereadband' + The band range is first erassed and programmed. +*/ +static int asp_read_random(aspproto_cell_type_t cell_type, uint32_t num_sectors, uint32_t num_stripes, uint32_t sectors_per_page, uint32_t same_die ,uint32_t seconds) +{ + aspproto_cmd_t * command; + uint8_t * scratch_buffer; //placeholder for putting in page data. every sector. + uint32_t paddr32; + uint64_t start_ticks; + uint32_t iterations = 0; + uint64_t perf_ticks0; + uint64_t perf_ticks1; + uint64_t link_clk_freq; + + if(sectors_per_page > nand_info.sec_per_page) + { + printf("unit_size (%d) should be < sectors per page (%d)\n", sectors_per_page, nand_info.sec_per_page); + return -1; + } + + asp_prefill_bands(cell_type); + printf("Will now start the reads\n"); + + if(0 != asp_reset_perf_ticks()) + { + return -1; + } + + scratch_buffer = memalign(ASP_NAND_BLKSZ, ASP_NAND_BLK_ALIGNMENT); + paddr32 = VADDR_TO_PADDR32(scratch_buffer); + + command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + command->op = ASPPROTO_CMD_CORE_DEBUG; + command->tunnel.core_opcode = CORE_DEBUG_READ_RANDOM; + command->tunnel.options.debug_epr_info.cell_type = cell_type; + command->tunnel.options.debug_epr_info.num_sectors = num_sectors; + command->tunnel.options.debug_epr_info.num_stripes = num_stripes; + command->tunnel.options.debug_epr_info.same_die = same_die; + command->tunnel.options.debug_epr_info.sectors_per_page = sectors_per_page; + command->flags.all = 0; + command->flags.noAesKey = 1; + command->tunnel.buffer_paddr = paddr32; + command->tunnel.bufferLen = ASP_NAND_BLKSZ; + if(cell_type == CELL_TYPE_IS_MIXED) + { + command->tunnel.options.flags.mixedMode = 1; + } + + start_ticks = system_time(); + + while(1) + { + iterations++; + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + dprintf(DEBUG_CRITICAL, "ERROR: Could not read band.\n\n"); + return -1; + } + + if(0 == seconds) + { + break; + } + else if(time_has_elapsed(start_ticks, (uint64_t)seconds * 1000000)) + { + break; + } + } + + if(0 != asp_get_perf_ticks(false, &perf_ticks0, 0)) + { + return -1; + } + if(0 != asp_get_perf_ticks(false, &perf_ticks1, 1)) + { + return -1; + } + + if(0 != asp_get_link_clk_freq(false, &link_clk_freq)) + { + return -1; + } + + printf("Ch 0: %u bytes transferred in %llu ticks @ %llu Hz\n\n", (iterations * num_sectors * ASP_NAND_BLKSZ) / 2, + perf_ticks0, + link_clk_freq); + printf("Ch 1: %u bytes transferred in %llu ticks @ %llu Hz\n\n", (iterations * num_sectors * ASP_NAND_BLKSZ) / 2, + perf_ticks1, + link_clk_freq); + + + printf("Ch 0: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (iterations * num_sectors * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks0); + printf("Ch 1: To calculate total throughput in MiB/s: (%u * %llu) / (%llu * 1024 * 1024)\n\n", (iterations * num_sectors * ASP_NAND_BLKSZ) / 2, + link_clk_freq, + perf_ticks1); + + printf("Ch 0: Time taken for %d 4k sector in us: (%llu / %d) / (%llu / 1000000)\n\n", sectors_per_page, perf_ticks0, ((iterations * num_sectors) / 2), link_clk_freq); // Divide by 2 is because 2 buses are active at a time + printf("Ch 1: Time taken for %d 4k sector in us: (%llu / %d) / (%llu / 1000000)\n\n", sectors_per_page, perf_ticks1, ((iterations * num_sectors) / 2), link_clk_freq); // Divide by 2 is because 2 buses are active at a time + + printf("Note: This is actual bus utilization with negligible overhead.\n"); + + return 0; +} + +static int asp_bonfire_read_band(uint32_t band, aspproto_cell_type_t cell_type, bool stats) +{ + uint8_t *statsBuf = NULL; + uint32_t paddr32 = 0; + aspproto_cmd_t * command; + int status; + uint32_t sectors_per_band; + + if((band > asp.lastBand)) + { + printf("Enter valid band: <= %d.\n", asp.lastBand); + return -1; + } + + sectors_per_band = (uint32_t) asp_sectors_per_band(band, false); + if(0 == sectors_per_band) + { + printf("Cannot program band - It has 0 good sectors.\n"); + return -1; + } + + statsBuf = memalign(sectors_per_band * nand_info.bytes_per_sec_meta, ASP_NAND_BLK_ALIGNMENT); + if(!statsBuf) + { + printf("could not allocate stats buffer\n"); + return -1; + } + memset(statsBuf, 0xFF, sectors_per_band * nand_info.bytes_per_sec_meta); + if(stats) + { + paddr32 = VADDR_TO_PADDR32(statsBuf); + } + command = asp_get_cmd_for_tag(ASP_TAG_NAND); + + command->flags.all = 0; + command->flags.noAesKey = 1; + command->op = ASPPROTO_CMD_BONFIRE_READ; + command->bonfire_info.num_vpn = sectors_per_band / nand_info.sec_per_page; + + if(cell_type == CELL_TYPE_IS_SLC) { + command->bonfire_info.start_vpn = band * (nand_info.sec_per_full_band_slc / nand_info.sec_per_page); + } else { + command->bonfire_info.start_vpn = band * (nand_info.sec_per_full_band / nand_info.sec_per_page); + } + command->bonfire_info.stats_buf32 = paddr32; + command->bonfire_info.cell_type = cell_type; + + status = asp_send_command(command->tag); + + + if(stats) + { + printf("Sector Stats:\n"); + uint8_t *page_cursor = statsBuf; + uint8_t *buf_stats_cursor = page_cursor; + bool zero_flips = true; + uint32_t idx = 0, pageIdx = 0; + uint32_t sectors_per_page = 16; + + for(pageIdx = 0; pageIdx < command->bonfire_info.num_vpn; pageIdx++) + { + buf_stats_cursor = page_cursor; + for(idx = 0; idx < sectors_per_page; idx++) + { + if(*buf_stats_cursor != 0) + { + zero_flips = false; + break; + } + buf_stats_cursor++; + } + if(!zero_flips) + { + buf_stats_cursor = page_cursor ; + printf("vpn: %d: ", pageIdx); + for(idx = 0; idx < sectors_per_page; idx++) + { + printf("%02X ", *buf_stats_cursor); + buf_stats_cursor++; + } + printf("\n"); + } + page_cursor = page_cursor + 16; + } + } + + printf("Finished Band read with status: %d\n", status); + + asp_print_status_key(); + + free(statsBuf); + return 0; +} + +static int asp_nand_read_id(void) +{ + uint32_t i = 0; + printf("\nChip ID:\n"); + for(i = 0; i < nand_info.num_bus; i++) + { + printf("Bus %d: %02X %02X %02X %02X %02X %02X\n", + i, + asp.chip_id[i][0], asp.chip_id[i][1], asp.chip_id[i][2], + asp.chip_id[i][3], asp.chip_id[i][4], asp.chip_id[i][5]); + } + + printf("\nMfg ID:\n"); + for(i = 0; i < nand_info.num_bus; i++) + { + printf("Bus %d: %02X %02X %02X %02X %02X %02X\n", + i, + asp.mfg_id[i][0], asp.mfg_id[i][1], asp.mfg_id[i][2], + asp.mfg_id[i][3], asp.mfg_id[i][4], asp.mfg_id[i][5]); + } + + asp_nand_get_uid(); + return 0; +} + +void asp_test_write_bdev(uint32_t start_lba, int num_lbas) +{ + uint8_t *write_ptr; + int result; + + if(!asp.writable) + { + panic("Need to make system writable. Execute 'asp setwritable' first\n"); + } + + printf("Going to do a bdev write\n"); + + write_ptr = malloc(num_lbas * ASP_NAND_BLKSZ); + if(!write_ptr) + { + panic("Could not allocate memory\n"); + } + + asp.state = ASP_STATE_READY; + memset(write_ptr, TEST_DATA_PATTERN, num_lbas * ASP_NAND_BLKSZ); + result = asp_write_block(asp_nand_dev, write_ptr, start_lba, num_lbas); + printf("bdev write returned %d\n", result); + + if(num_lbas != result) + { + panic("bdev write returned %d instead of %d\n", result, num_lbas); + } + free(write_ptr); +} + +void asp_test_read_bdev(uint32_t start_lba, int num_lbas) +{ + int result; + uint8_t *read_ptr = (uint8_t *) env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + int i; + + printf("Going to do a bdev read\n"); + + if (!security_allow_memory(read_ptr, num_lbas * ASP_NAND_BLKSZ)) + { + panic("Permission Denied\n"); + } + + asp.state = ASP_STATE_READY; + memset(read_ptr, WATERMARK_PATTERN, num_lbas * ASP_NAND_BLKSZ); + result = asp_read_block(asp_nand_dev, read_ptr, start_lba, num_lbas); + + if(num_lbas != result) + { + panic("bdev read returned %d instead of %d\n", result, num_lbas); + } + + for(i = 0; i < num_lbas * ASP_NAND_BLKSZ; i++) + { + if(TEST_DATA_PATTERN != read_ptr[i]) + { + panic("expected data: 0x%X, read data: 0x%X, byte offset in buffer: %d\n", TEST_DATA_PATTERN, read_ptr[i], i); + } + } + printf("bdev read returned %d\n", result); +} + +void asp_test_waterfall_start(void) +{ + aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC); + printf("Going to start waterfall\n"); + command->op = ASPPROTO_CMD_WATERFALL_START; + + if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS) + { + panic("ASP waterfall table start Failed\n"); + } +} + +bool asp_test_waterfall(void) +{ + uint32_t lba = 0; + int count = 256; + + printf("Opening ASP\n"); + if (!asp_send_open()) + { + dprintf(DEBUG_CRITICAL, "Unable to open ASP\n"); + return false; + } + + printf("Setting writable\n"); + if (!asp_set_writable()) + { + asp.state = ASP_STATE_ERROR_NOT_WRITABLE; + printf("Unable to set writable\n"); + return false; + } + + printf("Going to util format\n"); + if (!asp_format(ASP_FORMAT_UTIL)) + { + printf("Failed to do util format\n"); + return false; + } + + asp_get_geometry(); + + asp_test_write_bdev(lba, count); + + asp_test_waterfall_start(); + + asp_test_read_bdev(lba, count); + + lba += count; + asp_test_write_bdev(lba, count); + + asp_test_waterfall_start(); + + asp_test_read_bdev(lba, count); + + lba += count; + asp_test_write_bdev(lba, count); + + asp_test_waterfall_start(); + + asp_test_read_bdev(lba, count); + + return true; +} + +static int do_asp(int argc, struct cmd_arg *args) +{ + void *buffer; + size_t buffer_len; + int err = 0; + const char *cmd; + + if (argc < 2) + { + printf("Not enough arguments\n"); + usage(); + return 0; + } + + buffer = (void *) env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + buffer_len = (size_t) env_get_uint("filesize", 0); + cmd = args[1].str; + + if (asp.state == ASP_STATE_ERROR_CRITICAL) + { + printf("Error - ASP has failed to initialize successfully!\n"); + return -1; + } + + if (!strcmp(args[1].str, "sync")) + { + if (!asp_sync()) + { + printf("Failed to sync ASP\n"); + return -1; + } + } +#if defined(ASP_ENABLE_NEURALIZE) && ASP_ENABLE_NEURALIZE + else if (!strcmp(args[1].str, "neuralize")) + { + if (!asp_set_writable()) + { + asp.state = ASP_STATE_ERROR_NOT_WRITABLE; + printf("Unable to neuralize device; media is not writable\n"); + return -1; + } + + if (!asp_neuralize()) + { + printf("Failed to neuralize\n"); + asp.state = ASP_STATE_ERROR_NEURALIZE; + return -1; + } + } +#endif + else if (!strcmp(cmd, "info")) + { + printf("nand info: \n"); + err = asp_nand_info(); + } + else if (!strcmp(cmd, "readid")) + { + err = asp_nand_read_id(); + } + else if (!strcmp(cmd, "istlc")) + { + err = asp_istlc(true); + } + else if(!strcmp(cmd, "getlinkclkfreq")) + { + err = asp_get_link_clk_freq(true, NULL); + } + else if(!strcmp(cmd, "resetperfticks")) + { + err = asp_reset_perf_ticks(); + } + else if(!strcmp(cmd, "getperfticks")) + { + err = asp_get_perf_ticks(true, NULL, 0); + err = asp_get_perf_ticks(true, NULL, 1); + } + else if(!strcmp(cmd, "printslcbonfirebands")) + { + err = asp_print_slc_bonfire_bands(); + } + else if (!strcmp(cmd, "test_scratchpad")) + { + err = asp_test_scratchpad(); + } + else if (!strcmp(cmd, "dies_in_parallel") && argc>=3) + { + if (argc==3) + { + err = asp_set_dies_in_parallel(args[2].u,args[2].u, + args[2].u,args[2].u, + args[2].u,args[2].u, + args[2].u,args[2].u, + CORE_POWERSTATE_HIGH_POWER); + asp_set_power_state(CORE_POWERSTATE_HIGH_POWER); + } + else if (argc == 10) + { + err = asp_set_dies_in_parallel(args[2].u,args[3].u, + args[4].u,args[5].u, + args[6].u,args[7].u, + args[8].u,args[9].u, + CORE_POWERSTATE_HIGH_POWER); + asp_set_power_state(CORE_POWERSTATE_HIGH_POWER); + } + else + { + usage(); + return 0; + } + } + else if (!strcmp(cmd, "set_photoflow_slc")) + { + err = asp_set_photoflow_mode(CORE_FLOW_MODE_SLC); + } + else if (!strcmp(cmd, "set_photoflow_mlc")) + { + err = asp_set_photoflow_mode(CORE_FLOW_MODE_MLC); + } + else if (!strcmp(cmd, "enable_bg")) + { + err = asp_enable_bg(); + } + else if (!strcmp(cmd, "disable_bg")) + { + err = asp_disable_bg(); + } + else if (!strcmp(cmd, "debug_counter_supported")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = debug_counter_supported(args[2].u); + } + else if (!strcmp(cmd, "get_debug_counter")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = get_debug_counter(args[2].u, (uint8_t *)buffer); + } + else if (!strcmp(cmd, "reset_debug_counter")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = reset_debug_counter(args[2].u); + } + else if (!strcmp(cmd, "bonfirereadband")) + { + if(argc < 5) + { + usage(); + return 0; + } + err = asp_bonfire_read_band(args[2].u, args[3].u, args[4].u); + } + else if (!strcmp(cmd, "readband")) + { + if(argc < 5) + { + usage(); + return 0; + } + if(argc == 5) + { + err = asp_read_band(args[2].u, args[3].u, args[4].u, 0); + } + else + { + err = asp_read_band(args[2].u, args[3].u, args[4].u, args[5].u); + } + } + else if (!strcmp(cmd, "readrandom")) + { + if(argc < 7) + { + usage(); + return 0; + } + if(argc == 7) + { + err = asp_read_random(args[2].u, args[3].u, args[4].u, args[5].u, args[6].u, 0); + } + else + { + err = asp_read_random(args[2].u, args[3].u, args[4].u, args[5].u, args[6].u, args[7].u); + } + } + else if (!strcmp(cmd, "readmixedsuperpage")) + { + if(argc < 4) + { + usage(); + return 0; + } + if(argc == 4) + { + err = asp_read_mixed_superpage(args[2].u, args[3].u, 0); + } + else + { + err = asp_read_mixed_superpage(args[2].u, args[3].u, args[4].u); + } + } + else if (!strcmp(cmd, "v2p")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_nand_get_addr(args[2].u, NULL, NULL, true); + } + else if (!strcmp(cmd, "l2dbp")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_l2dbp(args[2].u); + } + else if (!strcmp(cmd, "r2cbp")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_r2cbp(args[2].u); + } + else if (!strcmp(cmd, "cbp2r")) + { + if(argc < 5) + { + usage(); + return 0; + } + err = asp_cbp2r(args[2].u, args[3].u, args[4].u); + } + else if (!strcmp(cmd, "dbp2r")) + { + if(argc < 5) + { + usage(); + return 0; + } + err = asp_dbp2r(args[2].u, args[3].u, args[4].u); + } + else if (!strcmp(cmd, "secperband")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_sectors_per_band(args[2].u, true); + } + else if (!strcmp(cmd, "getburnincode")) + { + err = asp_get_burnin_code(); + } + else if (!strcmp(cmd, "setTLCwritestripes")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_set_tlcwritestripes(args[2].u); + } + else if (!strcmp(cmd, "getlastfailure")) + { + err = asp_get_last_failure(); + } + else if (!strcmp(cmd, "bbt")) + { + err = asp_get_bbt(); + } + else if (!strcmp(cmd, "dm")) + { + err = asp_get_dm(); + } + else if (!strcmp(cmd, "waterfall_size")) + { + err = asp_get_waterfall_table_size(); + } + else if (!strcmp(cmd, "waterfall")) + { + err = asp_get_waterfall_table((uint8_t *)buffer); + } + else if (!strcmp(cmd, "devparam")) + { + err = asp_print_ppn_parameters(); + } + else if (!strcmp(cmd, "readverify")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_read_verify(args[2].u); + } + else if (!strcmp(cmd, "dipinfo")) + { + err = asp_get_all_dip_info(); + } + else if (!strcmp(cmd, "read")) + { + if(argc < 9) + { + usage(); + return 0; + } + err = asp_physical_read(args[2].u, args[3].u, args[4].u, args[5].u, args[6].u, args[7].u, args[8].u, (uint8_t *)buffer, true, NULL); + } + else if (!strcmp(cmd, "readpagemeta")) + { + if(argc < 6) + { + usage(); + return 0; + } + err = asp_read_pagemeta(args[2].u, args[3].u, args[4].u, args[5].u, (uint8_t *)buffer); + } + else if (!strcmp(cmd, "readbandmeta")) + { + if(argc < 4) + { + usage(); + return 0; + } + err = asp_read_bandmeta(args[2].u, (uint8_t *)buffer, args[3].u); + } + else if (!strcmp(cmd, "bandstat")) + { + err = asp_get_band_stats(); + } + else if (!strcmp(cmd, "disableuid")) + { + err = asp_disable_uid(); + } + else if (!strcmp(cmd, "dumpblog")) + { + if(argc < 5) + { + usage(); + return 0; + } + err = asp_dump_blog(args[2].u, (uint8_t *)buffer, args[3].u, args[4].u); + } + else if (!strcmp(cmd, "vthsweep")) + { + if(argc < 6) + { + usage(); + return 0; + } + err = asp_vth_sweep(args[2].u, args[3].u, args[4].u, args[5].str); + } + else if (!strcmp(cmd, "rma_delete")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_rma_delete(args[2].u); + } + else if (!strcmp(cmd, "rma_configure")) + { + if(argc < 4) + { + usage(); + return 0; + } + err = asp_rma_configure(args[2].u, args[3].u); + } + else if (!strcmp(cmd, "rma_set")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_rma_set(args[2].u); + err &= asp_recover(); + } + else if (!strcmp(cmd, "rma_get")) + { + if(argc < 3) + { + usage(); + return 0; + } else if(argc == 3) { + err = asp_rma_get(args[2].u, NULL, NULL); + } else { + err = asp_rma_get(args[2].u, args[3].str, NULL); + } + } + else if (!strcmp(cmd, "ppn_recover")) + { + err = asp_recover(); + } + else if (!strcmp(cmd, "ppn_get_calibration")) + { + if(argc < 2) + { + usage(); + return 0; + } else if(argc == 2) { + err = asp_ppn_get_calibration(NULL); + } else { + err = asp_ppn_get_calibration(args[2].str); + } + } + else if (!strcmp(cmd, "testbdevread")) + { + if(argc < 4) + { + usage(); + return 0; + } + asp_test_read_bdev(args[2].u, args[3].u); + } +#if ASP_ENABLE_WRITES + else if (!strcmp(args[1].str, "utilFormat")) + { + if (!asp_format(ASP_FORMAT_UTIL)) + { + printf("Failed to format media\n"); + return -1; + } + return 0; + } + else if (!strcmp(args[1].str, "lbaFormat")) + { + if (!asp_format(ASP_FORMAT_LBA)) + { + printf("Failed to format media\n"); + return -1; + } + return 0; + } + else if (!strcmp(args[1].str, "register")) + { + if(!asp.writable) + { + printf("Need to make system writable. Execute 'asp setwritable' first\n"); + return -1; + } + + if (!asp_get_geometry()) + { + asp.state = ASP_STATE_ERROR_CRITICAL; + printf("Unable to register device; media is unformatted\n"); + return -1; + } + + if (!asp_create_block_device(ASP_NVRAM)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + printf("Failed to create ASP_NVRAM block device\n"); + return -1; + } + + if (!asp_create_block_device(ASP_NAND)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + printf("Failed to create ASP_NAND block device\n"); + return -1; + } + + if (!asp_create_block_device(ASP_FIRMWARE)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + printf("Failed to create ASP_FIRMWARE block device\n"); + return -1; + } + + if (!asp_create_block_device(ASP_LLB)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + printf("Failed to create ASP_LLB block device\n"); + return -1; + } + + if (!asp_create_block_device(ASP_EFFACEABLE)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + printf("Failed to create ASP_EFFACEABLE block device\n"); + return -1; + } + + if (!asp_create_block_device(ASP_SYSCFG)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + printf("Failed to create ASP_SYSCFG block device\n"); + return -1; + } + + if (!asp_create_block_device(ASP_PANICLOG)) + { + asp.state = ASP_STATE_ERROR_NOT_REGISTERED; + printf("Failed to create ASP_PANICLOG block device\n"); + return -1; + } + + asp.state = ASP_STATE_READY; + + partition_scan_and_publish_subdevices("asp_nand"); + + return 0; + } + else if (!strcmp(cmd, "bonfirewriteband")) + { + bool random_pattern = true; + uint32_t data_pattern = 0; + if(argc < 4) + { + usage(); + return 0; + } + if(argc > 4) + { + data_pattern = args[4].u; + random_pattern = false; + } + + err = asp_bonfire_write_band(args[2].u, args[3].u, random_pattern, data_pattern); + } + else if (!strcmp(cmd, "bonfireeraseband")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_bonfire_erase_band(args[2].u); + } + else if (!strcmp(cmd, "groupaslc")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_bonfire_group_a_slc(args[2].u); + } + else if (!strcmp(cmd, "groupbslc")) + { + err = asp_bonfire_group_b_slc(); + } + else if (!strcmp(cmd, "ungroup")) + { + err = asp_bonfire_ungroup(); + } + else if (!strcmp(cmd, "writeband")) + { + bool random_pattern = true; + uint32_t data_pattern = 0; + if(argc < 4) + { + usage(); + return 0; + } + if(argc > 4) + { + data_pattern = args[4].u; + random_pattern = false; + } + + err = asp_write_band(args[2].u, args[3].u, true, random_pattern, data_pattern); + } + else if (!strcmp(cmd, "eploop")) + { + bool random_pattern = true; + uint32_t data_pattern = 0; + if(argc < 5) + { + usage(); + return 0; + } + if(argc > 5) + { + data_pattern = args[5].u; + random_pattern = false; + } + + err = asp_eploop_band(args[2].u, args[3].u, args[4].u, random_pattern, data_pattern); + } + else if (!strcmp(cmd, "eraseband")) + { + if(argc < 4) + { + usage(); + return 0; + } + err = asp_erase_band(args[2].u, args[3].u, true); + } + else if (!strcmp(cmd, "testwaterfall")) + { + err = asp_test_waterfall(); + } + else if (!strcmp(cmd, "testbdevwrite")) + { + if(argc < 4) + { + usage(); + return 0; + } + asp_test_write_bdev(args[2].u, args[3].u); + } + else if (!strcmp(cmd, "setwritable")) + { + err = asp_set_writable(); + } + else if (!strcmp(cmd, "setburnincode")) + { + if(argc < 3) + { + usage(); + return 0; + } + err = asp_set_burnin_code(args[2].u); + } +#endif // ASP_ENABLE_WRITES + else + { + printf("invalid command\n"); + usage(); + err = -1; + } + + return err; +} + +MENU_COMMAND_DEVELOPMENT(asp, do_asp, "ASP maintenance and failure analysis commands", NULL); +#endif // DEBUG_BUILD && WITH_MENU + +#if !RELEASE_BUILD && WITH_MENU +static bool find_blobs(void *src_buffer, UInt32 src_length, void **fw, UInt32 *fw_len) +{ + DERReturn drtn; + DERSequence rdn; + DERItem seq, top = { src_buffer, src_length }; + DERDecodedInfo topDecode, keyC, valC; + + if (DR_Success != DERDecodeItem(&top, &topDecode)) { + printf("couldn't crack top level\n"); + return false; + } + + if ((ASN1_CONSTRUCTED|ASN1_APPLICATION) != ((ASN1_CONSTRUCTED|ASN1_APPLICATION) & topDecode.tag)) { + printf("top should be cons app\n"); + return false; + } + + seq.length = topDecode.content.length; + seq.data = topDecode.content.data; + + if (DR_Success != DERDecodeSeqContentInit(&seq, &rdn)) { + printf("could not initialize DER decode\n"); + return false; + } + + while ((drtn = DERDecodeSeqNext(&rdn, &keyC)) == DR_Success) { + // Got key UTF8-str, check + if (ASN1_UTF8_STRING != keyC.tag) { + printf("key invalid: %lld\n", keyC.tag); + return false; + } + + // Get value Octet-str + if (DR_Success != ((drtn = DERDecodeSeqNext(&rdn, &valC)))) { + printf("no value found for key %lld\n", keyC.tag); + return false; + } + + // Check value tag + if (ASN1_OCTET_STRING != valC.tag) { + printf("value invalid: %lld\n", valC.tag); + return false; + } + + // Decode + if ((6 == keyC.content.length) && (0 == strncmp((char*)keyC.content.data, "ppn-fw", 6))) { + *fw = valC.content.data; + *fw_len = valC.content.length; + } else { + printf("unknown key\n"); + return false; + } + } + + return true; +} + +static int do_ppnfw(int argc, struct cmd_arg *args) +{ + addr_t buf_ptr; + size_t buf_len; + void *fw_buffer = NULL; + uint32_t fw_length; + + if (argc > 3) + { + return -1; + } + + buf_ptr = (argc > 1) ? args[1].u : env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + buf_len = (argc > 2) ? args[2].u : env_get_uint("filesize", 0); + + if (!security_allow_memory((void*)buf_ptr, buf_len)) + { + return -2; + } + + fw_buffer = NULL; + fw_length = 0; + find_blobs((void*)buf_ptr, buf_len, &fw_buffer, &fw_length); + + if ((NULL == fw_buffer)) + { + printf("couldn't find the fw payload\n"); + return -3; + } + + return asp_update_ppn_firmware(fw_buffer, fw_length); +} + +MENU_COMMAND_DEVELOPMENT(ppnfw, do_ppnfw, "Update PPN controller firmware", NULL); +#endif // #if !RELEASE_BUILD && WITH_MENU diff --git a/drivers/apple/asp/rules.mk b/drivers/apple/asp/rules.mk new file mode 100644 index 0000000..817dd61 --- /dev/null +++ b/drivers/apple/asp/rules.mk @@ -0,0 +1,23 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include \ + $(DSTROOT)/usr/local/standalone/firmware \ + $(SDKROOT)/../../../usr/local/standalone/firmware + +ALL_OBJS += \ + $(LOCAL_DIR)/asp.o \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/common_util.o + +OPTIONS += \ + WITH_HW_ASP=1 \ + WITH_NAND_BOOT=1 diff --git a/drivers/apple/audio/audio.c b/drivers/apple/audio/audio.c new file mode 100644 index 0000000..0cfab9c --- /dev/null +++ b/drivers/apple/audio/audio.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * AE2 Decrementer + * + * Note that for absolute time, we rely on externally defined timer_get_ticks and + * it is assumed that the tick rate matches our decrementer's. + */ + +static void timer_deadline(void *arg); +static void (* timer_deadline_func)(void); + +#define DECR_MAX_COUNT (0x7fffffffULL) + +static uint32_t timer_count = 0; +static uint32_t timer_late_count = 0; + +int timer_init(u_int32_t timer) +{ + if (timer) return -1; + + /* Disable timer */ + rAE2_ADECSR = 0; + + /* Install handler but mask for now */ + install_int_handler(AE2_INT_DEC, (int_handler)timer_deadline, NULL); + set_int_type(AE2_INT_DEC, INT_TYPE_IRQ | INT_TYPE_LEVEL); + mask_int(AE2_INT_DEC); + + return 0; +} + +void timer_deadline_enter(u_int64_t deadline, void (* func)(void)) +{ + uint64_t ticks; + uint32_t decr; + + timer_deadline_func = func; + if (func) { + /* convert absolute deadline to relative time */ + ticks = timer_get_ticks(); + timer_count++; + if (deadline < ticks) { + timer_late_count++; + deadline = 0; + } else { + deadline -= ticks; + } + + /* clamp the deadline to our maximum, which is about 89 seconds */ + decr = (deadline > DECR_MAX_COUNT) ? DECR_MAX_COUNT : deadline; + + /* + * Stop the decrementer and clear the value to ensure + * no pending interrupts. Load the value and go. + */ + rAE2_ADECSR = 0; + rAE2_ADECTR = 0; + unmask_int(AE2_INT_DEC); + rAE2_ADECTR = decr; + rAE2_ADECSR = 1; + } else { + /* no deadline, disable the decrementer and its interrupt */ + dprintf(DEBUG_INFO, "timer off\n"); + mask_int(AE2_INT_DEC); + rAE2_ADECSR = 0; + } +} + +static void +timer_deadline(void *arg) +{ + /* acknowledge the interrupt and disable the decrementer */ + mask_int(AE2_INT_DEC); + + /* if we have a callback, invoke it now */ + if (timer_deadline_func) + timer_deadline_func(); +} + +#if OSC_FREQ == 24000000 + +utime_t timer_ticks_to_usecs(uint64_t ticks) +{ + return ticks / 24; +} + +uint64_t timer_usecs_to_ticks(utime_t usecs) +{ + return usecs * 24; +} + +#endif + +uint32_t timer_get_tick_rate(void) +{ + return OSC_FREQ; +} + +uint64_t timer_get_ticks(void) +{ + extern uint64_t aic_get_ticks(); + return aic_get_ticks(); +} + +/* + * AE2 interrupts + */ + +static struct interrupt_entry handlers[AE2_MAX_INTS]; + +#if SUPPORT_SLEEP +struct ae2_int_state { + u_int32_t irqs; + u_int32_t fiqs; +} ae2_saved_state; +#endif + +int interrupt_init(void) +{ + rAE2_AIRQCR = 0xffffffff; + rAE2_AFIQCR = 0xffffffff; + +#if SUPPORT_SLEEP + rAE2_AIRQSR = ae2_saved_state.irqs; + rAE2_AFIQSR = ae2_saved_state.fiqs; +#endif + + /* also enable it */ + exit_critical_section(); + + return 0; +} + +void unmask_int(uint32_t vector) +{ + if (handlers[vector].edge) + rAE2_AFIQSR = 1 << vector; + else + rAE2_AIRQSR = 1 << vector; +#if SUPPORT_SLEEP + ae2_saved_state.irqs = rAE2_AIRQER; + ae2_saved_state.fiqs = rAE2_AFIQER; +#endif +} + +void mask_int(uint32_t vector) +{ + if (handlers[vector].edge) + rAE2_AFIQCR = 1 << vector; + else + rAE2_AIRQCR = 1 << vector; +#if SUPPORT_SLEEP + ae2_saved_state.irqs = rAE2_AIRQER; + ae2_saved_state.fiqs = rAE2_AFIQER; +#endif +} + +void set_int_type(uint32_t vector, int type) +{ + /* Overload the "edge" member to indicate FIQ */ + handlers[vector].edge = (type & INT_TYPE_FIQ) != 0; + if (type & INT_TYPE_FIQ) + arm_enable_fiqs(); +} + +int install_int_handler(uint32_t vector, int_handler handler, void *arg) +{ + ASSERT(vector < AE2_MAX_INTS); + + enter_critical_section(); + + handlers[vector].handler = handler; + handlers[vector].arg = arg; + + exit_critical_section(); + + return 0; +} + +void platform_irq(void) +{ + u_int32_t pending, vector; + + if (0 == (pending = (rAE2_AIRQRR & rAE2_AIRQER))) { + return; + } + vector = __builtin_ctz(pending); + if (handlers[vector].handler) + handlers[vector].handler(handlers[vector].arg); +} + +void platform_fiq(void) +{ + u_int32_t pending, vector; + + if (0 == (pending = (rAE2_AFIQRR & rAE2_AFIQER))) { + return; + } + vector = __builtin_ctz(pending); + if (handlers[vector].handler) + handlers[vector].handler(handlers[vector].arg); +} + +void interrupt_generate_ipc(u_int32_t vector) +{ + rAE2_ASFISR = 1 << vector; +} + +void interrupt_clear_ipc(u_int32_t vector) +{ + rAE2_ASFICR = 1 << vector; +} diff --git a/drivers/apple/audio/debug.c b/drivers/apple/audio/debug.c new file mode 100644 index 0000000..9e51b27 --- /dev/null +++ b/drivers/apple/audio/debug.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include + +#if WITH_MENU +#if DEBUG_BUILD + +#define AE2_ALIGN (1 << 12) +#define AE2_ALIGN_MASK (AE2_ALIGN - 1) + +int do_ae2_go(int argc, struct cmd_arg *args) +{ + addr_t addr; + + addr = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + + if (addr & AE2_ALIGN_MASK) { + dprintf(DEBUG_CRITICAL, "load address not on a page boundary, cannot remap\n"); + return(-1); + } + dprintf(DEBUG_INFO, "configuring AE2 for image @ 0x%08x\n", addr); + + /* reset the AE2 processor */ + rAE2_MCSCSR = 0; + + /* set up translation */ + rAE2_MCSATB = addr; + + /* release reset */ + rAE2_MCSCSR = 1; + + return(0); +} + +MENU_COMMAND_DEBUG(ae2_go, do_ae2_go, "start AE2 with a downloaded image", NULL); + +int do_ae2_stop(int argc, struct cmd_arg *args) +{ + /* reset the AE2 processor */ + rAE2_MCSCSR = 0; + + return(0); +} + +MENU_COMMAND_DEBUG(ae2_stop, do_ae2_stop, "stop the AE2 processor", NULL); + +#endif /* DEBUG_BUILD */ +#endif /* WITH_MENU */ diff --git a/drivers/apple/audio/include/drivers/audio/audio.h b/drivers/apple/audio/include/drivers/audio/audio.h new file mode 100644 index 0000000..3fa6b7b --- /dev/null +++ b/drivers/apple/audio/include/drivers/audio/audio.h @@ -0,0 +1,60 @@ + +#ifndef __APPLE_AUDIO_H +#define __APPLE_AUDIO_H + +#include + +#define rAE2_MCSVER (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e0000)) +#define rAE2_MCSCSR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e0004)) +#define rAE2_MCSATB (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e0008)) + +#define rAE2_MIRQRR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1000)) +#define rAE2_MIRQER (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1004)) +#define rAE2_MIRQSR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1008)) +#define rAE2_MIRQCR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e100c)) +#define rAE2_MFIQRR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1010)) +#define rAE2_MFIQER (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1014)) +#define rAE2_MFIQSR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1018)) +#define rAE2_MFIQCR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e101c)) +#define rAE2_MSFISR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1020)) +#define rAE2_MSFICR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001e1024)) + +#define rAE2_ACSCSR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a0000)) + +#define rAE2_AIRQRR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1000)) +#define rAE2_AIRQER (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1004)) +#define rAE2_AIRQSR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1008)) +#define rAE2_AIRQCR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a100c)) +#define rAE2_AFIQRR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1010)) +#define rAE2_AFIQER (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1014)) +#define rAE2_AFIQSR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1018)) +#define rAE2_AFIQCR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a101c)) +#define rAE2_ASFISR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1020)) +#define rAE2_ASFICR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a1024)) + +#define rAE2_ADECSR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a2000)) +#define rAE2_ADECTR (*(volatile u_int32_t *)(AUDIO_BASE_ADDR + 0x001a2004)) + +#define AE2_INT_DEC 0 // Decrementer +#define AE2_INT_DMACINTERR 1 // PL080 error +#define AE2_INT_DMACINTTC 2 // PL080 transaction completion +#define AE2_INT_SW0 4 // Software interrupt 0 +#define AE2_INT_SW1 5 // Software interrupt 1 +#define AE2_INT_SW2 6 // Software interrupt 2 +#define AE2_INT_SW3 7 // Software interrupt 3 +#define AE2_INT_BCZ0 8 // Ring buffer 0 byte count exhausted +#define AE2_INT_BCZ1 9 // Ring buffer 1 byte count exhausted +#define AE2_INT_BCZ2 10 // Ring buffer 2 byte count exhausted +#define AE2_INT_BCZ3 11 // Ring buffer 3 byte count exhausted +#define AE2_INT_I2S0 16 // I2S 0 interrupt +#define AE2_INT_I2S1 17 // I2S 1 interrupt +#define AE2_INT_I2S2 18 // I2S 2 interrupt +#define AE2_INT_I2S3 19 // I2S 3 interrupt +#define AE2_INT_SPDIF 20 // SPDIF interrupt +#define AE2_INT_DP0 21 // DisplayPort 0 interrupt +#define AE2_INT_DP1 22 // DisplayPort 1 interrupt +#define AE2_INT_MCA0 23 // MCA0 interrupt + +#define AE2_MAX_INTS 24 + +#endif /* !__APPLE_AUDIO_H */ diff --git a/drivers/apple/audio/rules.mk b/drivers/apple/audio/rules.mk new file mode 100644 index 0000000..ea115c1 --- /dev/null +++ b/drivers/apple/audio/rules.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2009-2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifeq ($(PLATFORM_VARIANT),Audio) +ALL_OBJS += ${LOCAL_DIR}/audio.o +OPTIONS += \ + WITH_HW_TIMER=1 +else +ALL_OBJS += ${LOCAL_DIR}/debug.o +endif + +GLOBAL_INCLUDES += ${LOCAL_DIR}/include diff --git a/drivers/apple/ausb/ausb.c b/drivers/apple/ausb/ausb.c new file mode 100644 index 0000000..f62bcb2 --- /dev/null +++ b/drivers/apple/ausb/ausb.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ausb.h" + +// USB Widget related constants +#if !AUSB_USB20PHY_ONLY_VERSION + #if APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) + static const uint32_t high_addr_bits = (1 << 8) | ((SDRAM_BASE >> 32) & 0xf); + #elif APPLICATION_SECUREROM || (APPLICATION_IBOOT && WITH_DFU_MODE) + static const uint32_t high_addr_bits = (1 << 8) | ((SRAM_BASE >> 32) & 0xf); + #else + #error Not Supported + #endif +#endif + +/////////////////////////////////////////////////////////// +// +// USB PHY Control +// +/////////////////////////////////////////////////////////// + +static bool usbphy_powered; + +void usbphy_power_up(void) +{ + if (usbphy_powered) + return; + + clock_gate(CLK_USB, true); + clock_gate(CLK_USBCTLREG, true); + clock_gate(CLK_USB_OTG, true); + +#if !AUSB_USB20PHY_ONLY_VERSION + // Set the USB OTG Widget register + rAUSB_WIDGET_OTG_ADDR = high_addr_bits; +#endif + + // * expects SIDDQ and VBUSVLDEXTSEL set to 1 out of reset. + + // * program tuning values + rAUSB_USB20PHY_CFG0 = USBPHY_OTGTUNE0; + +#if defined(USBPHY_OTGTUNE1) + rAUSB_USB20PHY_CFG1 = USBPHY_OTGTUNE1; +#endif + + // ECO_216: Add register control to FSEL of USB PiCOPHY to get better jitter performance + // The bit USB20PHY_CFG1::PLLBTUNE needs to be set for Fiji revisions > A0 and all Capri revisions +#if defined(SUB_PLATFORM_T7000) || defined(SUB_PLATFORM_T7001) + rAUSB_USB20PHY_CFG1 |= (1 << 2); +#endif + + // Fiji >= B1 and Capri >= A1 need to adjust USB20PHY_CFG1:PLLITUNE +#if defined(SUB_PLATFORM_T7000) + if(platform_get_chip_revision() >= CHIP_REVISION_B1) + rAUSB_USB20PHY_CFG1 |= (2 << 4); +#endif +#if defined(SUB_PLATFORM_T7001) + if(platform_get_chip_revision() >= CHIP_REVISION_A1) + rAUSB_USB20PHY_CFG1 |= (2 << 4); +#endif + + // Maui A0/A1 uses different tunable than >= B0 +#if defined(SUB_PLATFORM_S8000) + if(platform_get_chip_revision() <= CHIP_REVISION_A1) + rAUSB_USB20PHY_CFG0 = USBPHY_OTGTUNE0_AX; +#endif + + // * assert PHY_RESET + rAUSB_USB20PHY_CTL |= (1 << 0); + + // * clear analog power-down (SIDDQ) and otg-block power-down bits + rAUSB_USB20PHY_CTL &= ~((1 << 3) | (1 << 2)); + + // * wait 10us delay + spin(10); + + // * de-assert PHY_RESET + rAUSB_USB20PHY_CTL &= ~(1 << 0); + + // * wait 1000us delay: This wait for PLL to be locked after POR. + spin(1000); + + usbphy_powered = true; +} + +void usbphy_enable_pullup(void) +{ + if (!usbphy_powered) + return; + + // Enable D+ PU + rAUSB_USB20PHY_OTGSIG |= (1 << 1); +} + +void usbphy_power_down(void) +{ + if (!usbphy_powered) + return; + + // * Assert PHY_RESET + rAUSB_USB20PHY_CTL |= (1 << 0); + + // * disable D+ PU + rAUSB_USB20PHY_OTGSIG &= ~(1 << 1); + + // * wait 10us delay + spin(10); + + // * De-assert PHY_RESET + rAUSB_USB20PHY_CTL &= ~(1 << 0); + + // * wait 1000us delay: This wait for PLL to be locked after POR. + spin(1000); + + // * set analog and otg block power down bits + rAUSB_USB20PHY_CTL |= ((1 << 3) | (1 << 2)); + + clock_gate(CLK_USB_OTG, false); + clock_gate(CLK_USBCTLREG, false); + clock_gate(CLK_USB, false); + + usbphy_powered = false; +} + +bool usbphy_is_cable_connected(void) +{ + bool connected; + + if (!usbphy_powered) { + clock_gate(CLK_USB, true); + clock_gate(CLK_USBCTLREG, true); + } + + connected = (rAUSB_USB20PHY_OTGSIG & (1 << 8)) != 0; + + if (!usbphy_powered) { + clock_gate(CLK_USBCTLREG, false); + clock_gate(CLK_USB, false); + } + + return connected; +} + +bool usbphy_set_dpdm_monitor(int select) +{ + // XXX IBOOT64_TODO + return false; +} + +#if WITH_DEVICETREE + +void update_devicetree_property(DTNode *node, char * propName, uint32_t value, bool doOR) +{ + void *propData; + uint32_t propSize; + + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(uint32_t)) { + if(doOR) { + *(uint32_t *)propData |= value; + } + else { + *(uint32_t *)propData = value; + } + } + } +} + +void usbphy_update_device_tree(DTNode *node) +{ + uint32_t phy_tuning_val; + + phy_tuning_val = 0; + +#ifdef USBPHY_UOTGTUNE + phy_tuning_val = USBPHY_UOTGTUNE; +#endif + + // Fill in the phy-tuning-val property + update_devicetree_property(node, "phy-tuning-val", phy_tuning_val, false); + + // ECO_216: Add register control to FSEL of USB PiCOPHY to get better jitter performance + // The bit USB20PHY_CFG1::PLLBTUNE needs to be set for Fiji revisions > A0 and all Capri revisions +#if defined(SUB_PLATFORM_T7000) || defined(SUB_PLATFORM_T7001) + update_devicetree_property(node, "cfg1-device", (1 << 2), true); + update_devicetree_property(node, "cfg1-host", (1 << 2), true); +#endif + + // Fiji >= B1 and Capri >= A1 need to adjust USB20PHY_CFG1:PLLITUNE +#if defined(SUB_PLATFORM_T7000) + if(platform_get_chip_revision() >= CHIP_REVISION_B1) { + update_devicetree_property(node, "cfg1-device", (2 << 4), true); + update_devicetree_property(node, "cfg1-host", (2 << 4), true); + } +#endif +#if defined(SUB_PLATFORM_T7001) + if(platform_get_chip_revision() >= CHIP_REVISION_A1) { + update_devicetree_property(node, "cfg1-device", (2 << 4), true); + update_devicetree_property(node, "cfg1-host", (2 << 4), true); + } +#endif + + // Maui A0/A1 uses different tunable than >= B0 +#if defined(SUB_PLATFORM_S8000) + if(platform_get_chip_revision() <= CHIP_REVISION_A1) { + update_devicetree_property(node, "cfg0-device", USBPHY_OTGTUNE0_AX, false); + } +#endif +} +#endif + +/////////////////////////////////////////////////////////// +// +// USB Widgets Control +// +/////////////////////////////////////////////////////////// + +#if !AUSB_USB20PHY_ONLY_VERSION +void ausb_setup_widgets() +{ + clock_gate(CLK_USB, true); + + // USB_CTL clock should be enabled + rAUSB_WIDGET_OTG_ADDR = high_addr_bits; + rAUSB_WIDGET_OHCI0_ADDR = high_addr_bits; + + // Only if EHCI is NOT capable of 64 bit addressing ... +#if (USBEHCI_ADDR_EXT_WIDGET_EN == 1) + rAUSB_WIDGET_EHCI0_ADDR = high_addr_bits; + rAUSB_WIDGET_EHCI1_ADDR = high_addr_bits; +#endif + + clock_gate(CLK_USB, false); +} +#endif diff --git a/drivers/apple/ausb/ausb.h b/drivers/apple/ausb/ausb.h new file mode 100644 index 0000000..a542c4a --- /dev/null +++ b/drivers/apple/ausb/ausb.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AUSB_H +#define __AUSB_H + +#include + +#define rAUSB_USB20PHY_CTL (*(volatile uint32_t *)(AUSB_CTL_REG_BASE_ADDR + AUSB_CTL_USB20PHY_REG_OFFSET + 0x00)) +#define rAUSB_USB20PHY_OTGSIG (*(volatile uint32_t *)(AUSB_CTL_REG_BASE_ADDR + AUSB_CTL_USB20PHY_REG_OFFSET + 0x04)) +#define rAUSB_USB20PHY_CFG0 (*(volatile uint32_t *)(AUSB_CTL_REG_BASE_ADDR + AUSB_CTL_USB20PHY_REG_OFFSET + 0x08)) +#define rAUSB_USB20PHY_CFG1 (*(volatile uint32_t *)(AUSB_CTL_REG_BASE_ADDR + AUSB_CTL_USB20PHY_REG_OFFSET + 0x0C)) +#define rAUSB_USB20PHY_BATCTL (*(volatile uint32_t *)(AUSB_CTL_REG_BASE_ADDR + AUSB_CTL_USB20PHY_REG_OFFSET + 0x10)) +#define rAUSB_USB20PHY_TEST (*(volatile uint32_t *)(AUSB_CTL_REG_BASE_ADDR + AUSB_CTL_USB20PHY_REG_OFFSET + 0x1C)) + + +#if !AUSB_USB20PHY_ONLY_VERSION +#define rAUSB_WIDGET_OTG_QOS (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x14)) +#define rAUSB_WIDGET_OTG_CACHE (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x18)) +#define rAUSB_WIDGET_OTG_ADDR (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x1C)) +#define rAUSB_WIDGET_EHCI0_QOS (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x34)) +#define rAUSB_WIDGET_EHCI0_CACHE (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x38)) +#define rAUSB_WIDGET_EHCI0_ADDR (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x3C)) +#define rAUSB_WIDGET_OHCI0_QOS (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x54)) +#define rAUSB_WIDGET_OHCI0_CACHE (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x58)) +#define rAUSB_WIDGET_OHCI0_ADDR (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x5C)) +#define rAUSB_WIDGET_EHCI1_QOS (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x74)) +#define rAUSB_WIDGET_EHCI1_CACHE (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x78)) +#define rAUSB_WIDGET_EHCI1_ADDR (*(volatile uint32_t *)(AUSB_PL301_WIDGET_BASE_ADDR + 0x7C)) +#endif + +// Errata bits +enum +{ + ERRATA_PHY_JITTER_IMPROVEMENT = 1 +}; + +#endif /* __AUSB_H */ diff --git a/drivers/apple/ausb/rules.mk b/drivers/apple/ausb/rules.mk new file mode 100644 index 0000000..f055421 --- /dev/null +++ b/drivers/apple/ausb/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_USBPHY=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/ausb.o diff --git a/drivers/apple/ccc/ccc.c b/drivers/apple/ccc/ccc.c new file mode 100644 index 0000000..db162ee --- /dev/null +++ b/drivers/apple/ccc/ccc.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +void ccc_override_and_lock_iorvbar(addr_t base_address) +{ + rCCC_CPU0_IMPL_IORVBAR = ((base_address >> 11) << 11) | (1 << 0); + rCCC_CPU1_IMPL_IORVBAR = ((base_address >> 11) << 11) | (1 << 0); + +#if SUB_PLATFORM_T7001 + rCCC_CPU2_IMPL_IORVBAR = ((base_address >> 11) << 11) | (1 << 0); + + dprintf(DEBUG_INFO, "IORVBAR:: CPU0:0x%016llx CPU1:0x%016llx CPU2:0x%016llx\n", + rCCC_CPU0_IMPL_IORVBAR, rCCC_CPU1_IMPL_IORVBAR, rCCC_CPU2_IMPL_IORVBAR); +#else + dprintf(DEBUG_INFO, "IORVBAR:: CPU0:0x%016llx CPU1:0x%016llx\n", rCCC_CPU0_IMPL_IORVBAR, rCCC_CPU1_IMPL_IORVBAR); +#endif /* SUB_PLATFORM_T7001 */ +} + +void ccc_handle_asynchronous_exception(void) +{ + dprintf(DEBUG_CRITICAL, "CPU0_IMPL: \n"); + dprintf(DEBUG_CRITICAL, "\tFED_ERR_STS:0x%016llx LSU_ERR_STS:0x%016llx MMU_ERR_STS:0x%016llx\n", + rCCC_CPU0_IMPL_FED_ERR_STS, rCCC_CPU0_IMPL_LSU_ERR_STS, rCCC_CPU0_IMPL_MMU_ERR_STS); +#if defined(rCCC_CPU0_IMPL_MIGSTS_EL1) + dprintf(DEBUG_CRITICAL, "\tE_FED_ERR_STS:0x%016llx E_LSU_ERR_STS:0x%016llx MIGSTS_EL1:0x%016llx\n", + rCCC_CPU0_IMPL_E_FED_ERR_STS, rCCC_CPU0_IMPL_E_LSU_ERR_STS, rCCC_CPU0_IMPL_MIGSTS_EL1); +#endif + dprintf(DEBUG_CRITICAL, "\tL2C_ERR_STS:0x%016llx L2C_ERR_ADR:0x%016llx L2C_ERR_INF:0x%016llx\n", + rCCC_CCC_IMPL_L2C_ERR_STS, rCCC_CCC_IMPL_L2C_ERR_ADR, rCCC_CCC_IMPL_L2C_ERR_INF); +} + +void ccc_enable_custom_errors(void) +{ + // rCCC_CPU0_IMPL_CPU_IOACC_CTL_EL3 |= (0x1ULL << 0); /* enable ns access to CPU_IMPL and HID */ + // rCCC_CCC_IMPL_CPM_IOACC_CTL_EL3 |= (0x7ULL << 0); /* enable ns access to CPM IMPL, HID, CNTCTL, and CNTRD + // CPM Thermal, CPM APSC, DVFM, PLL, and PSW */ + rCCC_CCC_IMPL_L2C_ERR_STS &= ~(0xffffffffULL); /* clear old status bits */ + rCCC_CCC_IMPL_L2C_ERR_ADR = 0; /* clear */ + rCCC_CCC_IMPL_L2C_ERR_INF = 0; /* clear */ + rCCC_CCC_IMPL_L2C_ERR_STS |= (1ULL << 41); /* enable PIOErr */ +} + +void ccc_disable_custom_errors(void) +{ + rCCC_CCC_IMPL_L2C_ERR_STS &= ~(1ULL << 41); /* disable PIOErr */ +} + +void ccc_dump_registers(void) +{ +// dprintf(DEBUG_INFO, "CPU_IOACC_CTL_EL3:0x%016llx, CPM_IOACC_CTL_EL3:0x%016llx\n", rCCC_CPU0_IMPL_CPU_IOACC_CTL_EL3, rCCC_CCC_IMPL_CPM_IOACC_CTL_EL3); + dprintf(DEBUG_INFO, "FED_ERR_STS:0x%016llx LSU_ERR_STS:0x%016llx MMU_ERR_STS:0x%016llx\n", + rCCC_CPU0_IMPL_FED_ERR_STS, rCCC_CPU0_IMPL_LSU_ERR_STS, rCCC_CPU0_IMPL_MMU_ERR_STS); + dprintf(DEBUG_INFO, "L2C_ERR_STS:0x%016llx L2C_ERR_ADR:0x%016llx L2C_ERR_INF:0x%016llx\n", + rCCC_CCC_IMPL_L2C_ERR_STS, rCCC_CCC_IMPL_L2C_ERR_ADR, rCCC_CCC_IMPL_L2C_ERR_INF); + dprintf(DEBUG_INFO, "CPU0_IORVBAR:0x%016llx CPU1_IORVBAR:0x%016llx\n", rCCC_CPU0_IMPL_IORVBAR, rCCC_CPU1_IMPL_IORVBAR); +} diff --git a/drivers/apple/ccc/include/drivers/ccc/ccc.h b/drivers/apple/ccc/include/drivers/ccc/ccc.h new file mode 100644 index 0000000..834ea25 --- /dev/null +++ b/drivers/apple/ccc/include/drivers/ccc/ccc.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012-2013, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_CCC_H +#define __APPLE_CCC_H + +#include + +void ccc_override_and_lock_iorvbar(addr_t base_address); +void ccc_handle_asynchronous_exception(void); +void ccc_enable_custom_errors(void); +void ccc_disable_custom_errors(void); +void ccc_dump_registers(void); + +#endif /* __APPLE_CCC_H */ diff --git a/drivers/apple/ccc/rules.mk b/drivers/apple/ccc/rules.mk new file mode 100644 index 0000000..a3e1cde --- /dev/null +++ b/drivers/apple/ccc/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/ccc.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/cdma/cdma.c b/drivers/apple/cdma/cdma.c new file mode 100644 index 0000000..cd5c375 --- /dev/null +++ b/drivers/apple/cdma/cdma.c @@ -0,0 +1,1104 @@ +/* + * Copyright (C) 2008-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cdma.h" + +#define kCDMASuccess (0) +#define kCDMAErrorNegativeSegment (-1) +#define kCDMAErrorSegmentsTooLong (-2) +#define kCDMAErrorEarlyZeroSegment (-3) +#define kCDMAErrorInvalidWordSize (-4) +#define kCDMAErrorInvalidBurstSize (-5) +#define kCDMAErrorNotIdle (-6) +#define kCDMAErrorNegativeLength (-7) +#define kCDMAErrorBadFifoAddress (-8) +#define kCDMAErrorLargeSegment (-9) + +/* + * Tunable: how many commands to allocate for a channel when it is set up. + */ +#ifndef CDMA_CHANNEL_CMDS +# define CDMA_CHANNEL_CMDS 32 +#endif + +typedef enum { + st_NONE, + st_REWIND, + st_CONT +} CHANNEL_INTERRUPT_STATE; + +struct cdma_channel { + int c_status; +#define CDMA_STATUS_UNINIT 0 +#define CDMA_STATUS_IDLE 1 +#define CDMA_STATUS_BUSY 2 +#define CDMA_STATUS_BUSY_UNINIT 3 + + bool c_is_read; + + u_int32_t c_fifo_address; + u_int32_t c_request_id_bits; + u_int32_t c_ccache_c; + u_int32_t c_ccache_r; + u_int32_t c_ccache_w; + + struct cdma_command *c_chain; + + /* state for longer multi-segment operations */ + u_int32_t c_index; + u_int32_t c_resid; + struct dma_segment *c_sgl; + + /* state for re-configuring after a peripheral stops us prematurely */ + u_int32_t c_segment_offset; + u_int32_t c_previous_offset; + u_int32_t c_previous_index; + u_int32_t c_previous_resid; + + /* callback for async operations */ + dma_completion_function c_callback; + void *c_callback_arg; + + /* saved for debugging */ + u_int32_t c_length; + + /* channel crypto config */ + struct dma_aes_config *c_aes; + u_int32_t c_filter; + u_int32_t c_chunk; + + /* Debugging - remove later */ + CHANNEL_INTERRUPT_STATE irqState; +}; + +static struct cdma_channel dma_channel_softc[DMA_CHANNEL_COUNT]; +#define CDMA_SOFTC(_x) (&dma_channel_softc[(_x) - 1]) /* NB: channels are 1-based */ + +static void dma_init_channel(int dma_channel, bool want_interrupt); +static void dma_continue_async(u_int32_t dma_channel); +static u_int32_t dma_generate_segments(int dma_channel); +static u_int32_t dma_generate_aes_segments(int dma_channel); +static void dma_int_handler(void *arg); + +static void cdma_dump_channel(int channel); + +/* filter contexts in use - context 1 is owned by the AES driver and not represented here */ +static u_int32_t cdma_fc_inuse = 0; + +#if CDMA_VERSION > 1 +/* + * The platform is required to provide a table of associations between channels, + * request IDs and FIFO addresses. + */ +struct cdma_channel_config { + u_int32_t channel_low; + u_int32_t channel_high; + bool aes_ok; + u_int32_t request_id; + u_int32_t fifo_address; +}; + +static struct cdma_channel_config cdma_channel_configs[] = DMA_CHANNEL_CONFIG; +#define CDMA_CHANNEL_CONFIG_COUNT (sizeof(cdma_channel_configs) / sizeof(struct cdma_channel_config)) +#endif + +void dma_init(void) +{ + dprintf(DEBUG_CRITICAL, "cdma_init()\n"); + clock_gate(CLK_CDMA, true); + +#if CDMA_VERSION >= 4 + rCDMA_CLOCK_ON(1) = ((1 << CDMA_CLOCK_AES_WRAP) | (1 << CDMA_CLOCK_AES_CORE)); +#endif /* CDMA_VERSION >= 4 */ +} + +static void dma_init_channel(int dma_channel, bool want_interrupt) +{ + struct cdma_channel *cp; + u_int32_t vector; + int i; + + cp = CDMA_SOFTC(dma_channel); + + /* is the channel already set up? */ + if (unlikely(cp->c_status == CDMA_STATUS_BUSY_UNINIT)) { + + dprintf(DEBUG_SPEW, "CDMA: setting up channel %d\n", dma_channel); + + /* allocate command chain */ + cp->c_chain = memalign(sizeof(struct cdma_command) * CDMA_CHANNEL_CMDS, 32); + + /* initialise segment linkage */ + for (i = 0; i < (CDMA_CHANNEL_CMDS - 1); i++) + cp->c_chain[i].nxt = mem_static_map_physical((uintptr_t)&cp->c_chain[i + 1]); + + /* mark channel as busy */ + cp->c_status = CDMA_STATUS_BUSY; + + /* invalidate fifo:request ID cache */ + cp->c_fifo_address = 0; + cp->c_request_id_bits = 0; + +#if CDMA_VERSION < 3 + cp->c_ccache_c = 0; + cp->c_ccache_r = 0; + cp->c_ccache_w = 0; + +#elif CDMA_VERSION < 5 + /* Force shared by requesting cached for reads and writes */ + cp->c_ccache_c = CDMA_CACHE_CACHE; + cp->c_ccache_r = CDMA_CACHE_CACHE; + cp->c_ccache_w = CDMA_CACHE_CACHE; +#else + /* Force shared by request write allocate for reads */ + /* and read allocate for writes */ + cp->c_ccache_c = CDMA_CACHE_BUFFER | CDMA_CACHE_CACHE | CDMA_CACHE_WALLOC; + cp->c_ccache_r = CDMA_CACHE_BUFFER | CDMA_CACHE_CACHE | CDMA_CACHE_WALLOC; + cp->c_ccache_w = CDMA_CACHE_CACHE | CDMA_CACHE_RALLOC; +#endif + + /* install interrupt handler */ + /* NB: assumes channels allocated in linear order */ + vector = INT_CDMA_DMAC1 + dma_channel - 1; + if (want_interrupt) { + set_int_type(vector, INT_TYPE_IRQ | INT_TYPE_LEVEL); + install_int_handler(vector, dma_int_handler, (void *)dma_channel); + unmask_int(vector); + } else { + mask_int(vector); + } + } + cp->irqState = st_NONE; +} + +int +dma_execute_cmd( + u_int32_t cmd, + int dma_channel, + void *src, + void *dst, + u_int32_t length, + u_int32_t word_size, + u_int32_t burst_size) +{ + struct task_event event; + struct dma_segment seg; + void *fifo; + int32_t ret; + + /* build an SGL for the one segment */ + switch (cmd & DMA_CMD_DIR_MASK) { + case DMA_CMD_DIR_TX: + seg.paddr = (u_int32_t)src; + fifo = dst; + break; + case DMA_CMD_DIR_RX: + seg.paddr = (u_int32_t)dst; + fifo = src; + break; + default: + case DMA_CMD_DIR_MEM : /* XXX not legitimate here, to be removed */ + return EINVAL; + } + seg.length = length; + + /* run the operation */ + event_init(&event, EVENT_FLAG_AUTO_UNSIGNAL, false); + ret = dma_execute_async( + cmd, + dma_channel, + &seg, + fifo, + length, + word_size, + burst_size, + (dma_completion_function)event_signal, + (void *)&event); + + if (!ret) { + /* and block waiting for it to complete */ + event_wait(&event); + } + + return ret; +} + +int +dma_execute_async( + u_int32_t cmd, + int dma_channel, + struct dma_segment *sgl, + void *fifo, + u_int32_t length, + u_int32_t word_size, + u_int32_t burst_size, + dma_completion_function completion, + void *completion_arg) +{ + struct dma_segment *cur_sgl; + struct cdma_channel *cp; + u_int32_t dw_fld, dbs_fld; + u_int32_t seg_length = 0; + + ASSERT(sgl); + ASSERT((dma_channel > 2) && (dma_channel <= DMA_CHANNEL_COUNT)); + ASSERT(length > 0); + ASSERT((length % word_size) == 0); + + /* + * Verify that the total lenght of the transfer < 2GB(neg) because the DBR cannot be negative! + * Any number this big would be wrong anyways. We don't want to assert because there is + * calling logic that spits out some useful information upon error. + */ + if ((int32_t)length <= 0) { + dprintf(DEBUG_CRITICAL, "kCDMAErrorNegativeLength: %d", (int32_t)length); + return kCDMAErrorNegativeLength; + } + + cp = CDMA_SOFTC(dma_channel); + + enter_critical_section(); + + if (cp->c_status != CDMA_STATUS_IDLE && cp->c_status != CDMA_STATUS_UNINIT) { + exit_critical_section(); + dprintf(DEBUG_CRITICAL, "kCDMAErrorNotIdle"); + return kCDMAErrorNotIdle; + } + + /* mark channel as busy */ + cp->c_status = (cp->c_status == CDMA_STATUS_UNINIT) ? + CDMA_STATUS_BUSY_UNINIT : CDMA_STATUS_BUSY; + + exit_critical_section(); + + /* do channel state init */ + dma_init_channel(dma_channel, true); + + /* turn on channel clock */ + cdma_clock_enable(dma_channel, true); + +#if CDMA_VERSION > 1 + /* + * Check the channel request ID cache. + * + * For CDMA_VERSION == 1, these bits are always zero. + */ + if (unlikely((u_int32_t)fifo != cp->c_fifo_address)) { + u_int32_t i; + for (i = 0; i < CDMA_CHANNEL_CONFIG_COUNT; i++) { + if (cdma_channel_configs[i].fifo_address == (u_int32_t)fifo) { + + /* sanity */ + ASSERT((unsigned)dma_channel >= cdma_channel_configs[i].channel_low); + ASSERT((unsigned)dma_channel <= cdma_channel_configs[i].channel_high); + if (NULL != cp->c_aes) { + ASSERT(true == cdma_channel_configs[i].aes_ok); + } + + /* cache the request ID */ + cp->c_fifo_address = cdma_channel_configs[i].fifo_address; + cp->c_request_id_bits = CDMA_DCR_REQ(cdma_channel_configs[i].request_id); + + /* and done */ + break; + } + } + /* sanity */ + ASSERT((u_int32_t)fifo == cp->c_fifo_address); + if (unlikely((u_int32_t)fifo != cp->c_fifo_address)) + return kCDMAErrorBadFifoAddress; + } +#endif + + /* initialise the channel sgl state */ + cp->c_index = 0; + cp->c_sgl = sgl; + cp->c_resid = cp->c_length = length; + cp->c_segment_offset = 0; + + /* Validate segments length match out length */ + cur_sgl = sgl; + while(1) { + /* Check that the sgl->length is less than 2GB (neg). + * Also verify that a segment is no larger than 16mb. + * It is highly unlikely that this will ever occur. + */ + if ((int32_t)cur_sgl->length < 0 ) { + dprintf(DEBUG_CRITICAL, "kCDMAErrorNegativeSegment: 0x%08x", cur_sgl->length); + return kCDMAErrorNegativeSegment; + } + if (cur_sgl->length > (16 * 1024 * 1024)) { + dprintf(DEBUG_CRITICAL, "kCDMAErrorLargeSegment: 0x%08x", cur_sgl->length); + return kCDMAErrorLargeSegment; + } + + seg_length += cur_sgl->length; + + /* + * Check that we haven't gone over the length. + * Check that we dont have a zero length segment before we get to the end. + */ + if (seg_length > length) return kCDMAErrorSegmentsTooLong; + if (seg_length < length && cur_sgl->length == 0) return kCDMAErrorEarlyZeroSegment; + + /* Finished the check */ + if (seg_length == length) break; + + cur_sgl++; + } + + /* save the completion */ + cp->c_callback = completion; + cp->c_callback_arg = completion_arg; + + /* determine the command direction */ + cp->c_is_read = (cmd == DMA_CMD_DIR_TX); + + /* configure the channel */ + switch (word_size) { + case 1 : dw_fld = CDMA_DCR_DW_1; break; + case 2 : dw_fld = CDMA_DCR_DW_2; break; + case 4 : dw_fld = CDMA_DCR_DW_4; break; + default : + return kCDMAErrorInvalidWordSize; + } + + switch (burst_size) { + case 1 : dbs_fld = CDMA_DCR_DBS_1; break; + case 2 : dbs_fld = CDMA_DCR_DBS_2; break; + case 4 : dbs_fld = CDMA_DCR_DBS_4; break; + case 8 : dbs_fld = CDMA_DCR_DBS_8; break; + case 16 : dbs_fld = CDMA_DCR_DBS_16; break; + case 32 : dbs_fld = CDMA_DCR_DBS_32; break; + default : + return kCDMAErrorInvalidBurstSize; + } + + /* + * Must always abort the channel before configuring it in order to reset the state machine. + * Note that moving from IDLE (which looks like HALTED) to HALTED, or even from HALTED to + * HALTED can generate a spurious HALT interrupt, so mask everything. + */ + rCDMA_CHANNEL_CSR(dma_channel) = CDMA_CSR_ABT; + + /* configure channel config */ + rCDMA_CHANNEL_DCR(dma_channel) = + (cp->c_is_read ? CDMA_DCR_DTD_TX : CDMA_DCR_DTD_RX) | + dw_fld | + dbs_fld | + cp->c_request_id_bits; + +#if CDMA_CHANNEL_ARASAN_QUIRKS + if ((1 << dma_channel) & CDMA_CHANNEL_ARASAN_QUIRKS) { + /* for Arasan, TX direction must be streaming mode */ + if (cp->c_is_read) + rCDMA_CHANNEL_DCR(dma_channel) |= CDMA_DCR_ST; + } +#endif + + rCDMA_CHANNEL_DAR(dma_channel) = (u_int32_t)fifo; + rCDMA_CHANNEL_DBR(dma_channel) = length; + + /* init for AES if required */ + if (cp->c_aes) { + ASSERT(0 == (length % cp->c_aes->chunk_size)); + cp->c_chunk = 0; + } + + /* configure for initial data and start the channel */ + dma_continue_async(dma_channel); + + return kCDMASuccess; +} + +void +dma_use_int(int dma_channel, bool use) +{ + u_int32_t vector = INT_CDMA_DMAC1 + dma_channel - 1; + + if (use) + { + unmask_int(vector); + } + else + { + mask_int(vector); + } +} + +bool +dma_poll(int dma_channel) +{ + bool ret = false; + struct cdma_channel *cp; + u_int32_t csr; + + cp = CDMA_SOFTC(dma_channel); + + if (CDMA_STATUS_IDLE == cp->c_status) + { + ret = true; + goto exit; + } + + enter_critical_section(); + + csr = rCDMA_CHANNEL_CSR(dma_channel); + + if (((0 != (CDMA_CSR_CIE & csr)) && + (0 != (CDMA_CSR_CIR & csr))) || + ((0 != (CDMA_CSR_HIE & csr)) && + (0 != (CDMA_CSR_HIR & csr)))) + { + dma_int_handler((void *)dma_channel); + } + + exit_critical_section(); + + if (CDMA_STATUS_IDLE == cp->c_status) + { + ret = true; + goto exit; + } + +exit: + + return ret; +} + +static void +dma_continue_async(u_int32_t dma_channel) +{ + struct cdma_channel *cp; + u_int32_t count; + + cp = CDMA_SOFTC(dma_channel); + + RELEASE_ASSERT(0 < cp->c_resid); + + /* save state for restart */ + cp->c_previous_index = cp->c_index; + cp->c_previous_resid = cp->c_resid; + cp->c_previous_offset = cp->c_segment_offset; + + if (NULL == cp->c_aes) { + count = dma_generate_segments(dma_channel); + } else { + count = dma_generate_aes_segments(dma_channel); + } + + /* we're done with messing with the command chain, make sure it's in memory */ + ASSERT(count > 0); + platform_cache_operation(CACHE_CLEAN, cp->c_chain, sizeof(*cp->c_chain) * count); + + /* clear and enable interrupts and (re)start the channel */ + rCDMA_CHANNEL_CAR(dma_channel) = mem_static_map_physical((uintptr_t)cp->c_chain); + rCDMA_CHANNEL_CSR(dma_channel) = + CDMA_CSR_GO | + CDMA_CSR_HIE | + CDMA_CSR_ERR | + CDMA_CSR_HIR | + CDMA_CSR_CIR | + (cp->c_aes ? CDMA_CSR_FC(cp->c_filter) : 0) | + CDMA_CSR_CCACHE(cp->c_ccache_c); +} + +static u_int32_t +dma_generate_segments(int dma_channel) +{ + struct cdma_channel *cp; + struct cdma_command *cc; + struct dma_segment *sge; + int i; + u_int32_t segment_length; + + cp = CDMA_SOFTC(dma_channel); + + /* generate segment commands */ + for (i = 0; i < (CDMA_CHANNEL_CMDS - 1); i++) { + + /* get the next command */ + cc = cp->c_chain + i; + + /* get the next segment */ + sge = cp->c_sgl + cp->c_index++; + + /* + * Make a memory command for this segment. + * + * The segment offset may be nonzero for the first + * segment only, and is used to compensate for operations + * that are terminated presumptively by the peripheral in + * the middle of a segment. + */ + segment_length = sge->length - cp->c_segment_offset; + + cc->ctrl = CDMA_CTRL_CMD_MEM | CDMA_CTRL_CACHE(cp->c_is_read ? cp->c_ccache_r : cp->c_ccache_w); + cc->addr = sge->paddr + cp->c_segment_offset; + cc->length = segment_length; + if ( 0==cc->length ) + { + panic("Caught trying to generate zero-length cdma segment on channel %d, irqState: %d",dma_channel,(int)cp->irqState); + } + + cp->c_segment_offset = 0; + + if (segment_length < cp->c_resid) { + + /* account for this segment */ + cp->c_resid -= segment_length; + } else { + ASSERT(segment_length == cp->c_resid); + cp->c_resid = 0; + break; + } + } + + /* barrier the last MEM command to ensure that data drains before we reach the HLT and interrupt */ + cc->ctrl |= CDMA_CTRL_BAR; + + /* always make the next command a HALT */ + (cc + 1)->ctrl = CDMA_CTRL_CMD_HLT; + + return(i + 2); +} + +static u_int32_t +dma_generate_aes_segments(int dma_channel) +{ + struct cdma_channel *cp; + struct cdma_command *cc; + struct dma_segment *sge; + int i; + u_int32_t segment_length; + u_int32_t chunk_done; + + cp = CDMA_SOFTC(dma_channel); + + i = 0; + cc = cp->c_chain; + sge = cp->c_sgl + cp->c_index; + + /* loop emitting pairs of LDIV and chunk-sized transfers */ + for (; cp->c_resid > 0; cp->c_resid -= cp->c_aes->chunk_size) { + /* + * Assuming a virtually contiguous input buffer, in the worst case + * we will emit three commands here, make sure there is room for them + * plus the terminating HLT. + */ + if ((i + 4) >= CDMA_CHANNEL_CMDS) + break; + + /* + * We will always come here at the beginning of a chunk, so + * emit an LDIV and get the supplier to fill in the IV. + */ + cc->ctrl = CDMA_CTRL_CMD_LDIV; + cp->c_aes->iv_func(cp->c_aes->iv_func_arg, cp->c_chunk, &cc->iv0); + cc++; + i++; + cp->c_chunk++; + chunk_done = 0; + + /* + * Emit part or all of a chunk. We may run out of bytes in this + * segment, which is OK (we'll make another one). + */ + while (chunk_done < cp->c_aes->chunk_size) { + ASSERT(i < (CDMA_CHANNEL_CMDS - 1)); + + /* find the space left in this sge */ + segment_length = sge->length - cp->c_segment_offset; + + /* limit the segment to completing one chunk */ + if ((chunk_done + segment_length) > cp->c_aes->chunk_size) + segment_length = (cp->c_aes->chunk_size - chunk_done); + + /* make the command */ + cc->ctrl = CDMA_CTRL_CMD_MEM | CDMA_CTRL_CACHE(cp->c_is_read ? cp->c_ccache_r : cp->c_ccache_w) | CDMA_CTRL_FE | ((chunk_done == 0) ? CDMA_CTRL_FR : 0); + cc->addr = sge->paddr + cp->c_segment_offset; + cc->length = segment_length; + if ( 0==cc->length ) + { + panic("Caught trying to generate zero-length cdma segment on channel %d, irqState: %d",dma_channel,(int)cp->irqState); + } + + /* update running state */ + chunk_done += segment_length; + cp->c_segment_offset += segment_length; + cc++; + i++; + + /* did we just finish that sge? */ + if (cp->c_segment_offset >= sge->length) { + sge++; + cp->c_index++; + cp->c_segment_offset = 0; + } + } + } + + if (0 == cp->c_resid) { + /* we must have generated at least two segments... */ + ASSERT(cc != cp->c_chain); + } + + /* barrier the last MEM command to ensure that data drains before we reach the HLT and interrupt */ + (cc - 1)->ctrl |= CDMA_CTRL_BAR; + + /* make the next command a HALT */ + cc->ctrl = CDMA_CTRL_CMD_HLT; + + return(i + 2); +} + +static void +dma_int_handler(void *arg) +{ + u_int32_t dma_channel = (u_int32_t)arg; + struct cdma_channel *cp; + int i; + u_int32_t scan_resid; + u_int32_t csr; + struct dma_segment *sge; + + cp = CDMA_SOFTC(dma_channel); + csr = rCDMA_CHANNEL_CSR(dma_channel); + + ASSERT(CDMA_CSR_RUN(csr) != CDMA_CSR_RUN_RUNNING); + + if (unlikely(csr & CDMA_CSR_ERR)) { +#if CDMA_VERSION > 1 + panic("CDMA: channel %d error interrupt, error status 0x%0x", dma_channel, + rCDMA_CHANNEL_ERR(dma_channel) & rCDMA_CHANNEL_ERR_MASK); +#else + panic("CDMA: channel %d error interrupt", dma_channel); +#endif + } + if (unlikely(csr & CDMA_CSR_CIR)) + panic("CDMA: channel %d spurious CIR, status 0x%0x", dma_channel, csr); + + if (unlikely(!(csr & CDMA_CSR_HIR))) + panic("CDMA: channel %d spurious interrupt, status 0x%0x", dma_channel, csr); + + /* clear interrupt status, mask further interrupts */ + rCDMA_CHANNEL_CSR(dma_channel) = CDMA_CSR_HIR; + + /* + * Is the channel done? + * Note that we maintain the DBR even if the channel is quirked for + * streaming mode so that this test is valid in either case. + */ + if (cp->c_resid == 0 && rCDMA_CHANNEL_DBR(dma_channel) <= 0) { + + /* clear AES config */ + dma_set_aes(dma_channel, NULL); + + /* turn off the channel clock */ + cdma_clock_enable(dma_channel, false); + + /* mark as idle so that the channel can be re-used in the callback */ + cp->c_status = CDMA_STATUS_IDLE; + + /* call the user-supplied callback */ + if (cp->c_callback != NULL) + cp->c_callback(cp->c_callback_arg); + + } else if (CDMA_CSR_RUN_HALTED == CDMA_CSR_RUN(rCDMA_CHANNEL_CSR(dma_channel))) { + /* Check that hardware and software are in agreement about how much data is left to + * transfer. We never expect to encounter an interrupt where the hardware hasn't + * consumed the entire segment list we last provided. This check relies on a BAR to + * have drained the FIFO towards memory (but the DBR can get ahead on an RX by up + * to one FIFO length - hence the inequality). */ + int32_t dbr = rCDMA_CHANNEL_DBR(dma_channel); + if (dbr > (int32_t)cp->c_resid) { + panic("Failed DBR/resid check: ch%d, c_resid=0x%08x DBR=0x%08x\n", dma_channel, cp->c_resid, dbr); + } + + /* the channel has hit the halt terminating the current segment set */ + cp->irqState = st_CONT; + /* re-configure & restart the channel */ + dma_continue_async(dma_channel); + } else { + /* the channel has been stopped by the peripheral */ + ASSERT(CDMA_CSR_RUN_STOPPED == CDMA_CSR_RUN(rCDMA_CHANNEL_CSR(dma_channel))); + + /* fix up residual count and work out where we ended up in the current segment set */ + /* XXX this should probably just be cp->c_resid = rCDMA_CHANNEL_DBR(dma_channel) */ + cp->c_resid += rCDMA_CHANNEL_DBR(dma_channel); + scan_resid = cp->c_previous_resid - cp->c_resid; + + /* walk up the segment list trying to work out where the peripheral stopped */ + for (i = 0; i < CDMA_CHANNEL_CMDS; i++) { + /* get the next segment */ + sge = cp->c_sgl + cp->c_previous_index + i; + + /* did it stop in this segment? */ + if ((sge->length - cp->c_previous_offset) >= scan_resid) + break; + + /* account for the segment */ + scan_resid -= (sge->length - cp->c_previous_offset); + cp->c_previous_offset = 0; + } + + /* it should be impossible to not find the terminating case in the segments we loaded */ + ASSERT(i < CDMA_CHANNEL_CMDS); + + /* rewind the DMA state back to the segment in which it stopped */ + if (((sge->length - cp->c_previous_offset) == scan_resid)) { + /* current segment is finished, so skip it b4 reconfigure the DMA */ + cp->c_index = cp->c_previous_index + i + 1; + cp->c_segment_offset = 0; + } else { + /* re-configure the CDMA */ + cp->c_index = cp->c_previous_index + i; + cp->c_segment_offset = cp->c_previous_offset + scan_resid; + } + + cp->irqState = st_REWIND; + + /* now we can re-configure the CDMA */ + dma_continue_async(dma_channel); + } +} + +void +dma_cancel(int dma_channel) +{ + struct cdma_channel *cp; + utime_t start_time; + + cp = CDMA_SOFTC(dma_channel); + ASSERT((dma_channel > 0) && (dma_channel <= DMA_CHANNEL_COUNT)); + + /* it's legal but not interesting to cancel a channel that hasn't been initialised */ + if (CDMA_STATUS_UNINIT == cp->c_status) + return; + + dprintf(DEBUG_INFO, "CDMA: cancelling channel\n"); + + /* + * Abort the channel. + * + * In the general case, we would also have to wait for the CDMA to either be + * processing a MEM command (in which case ABORT is effective immediately) or + * stopped for some other reason. Since we know that our command lists are always + * MEM or HLT, we can be sure this will be immediately effective. + */ + start_time = system_time(); + + cdma_clock_enable(dma_channel, true); + + if (CDMA_CSR_RUN_RUNNING == CDMA_CSR_RUN(rCDMA_CHANNEL_CSR(dma_channel))) { + +#if CDMA_VERSION < 2 + /* version 1 CDMA requires pause before abort */ + rCDMA_CHANNEL_CSR(dma_channel) = CDMA_CSR_PS; + while (!(rCDMA_CHANNEL_CSR(dma_channel) & CDMA_CSR_PSD)) { + if (time_has_elapsed(start_time, 10)) + panic("CDMA: channel %d pause timeout during abort", dma_channel); + } +#endif + + rCDMA_CHANNEL_CSR(dma_channel) = CDMA_CSR_ABT; + while (CDMA_CSR_RUN_RUNNING == CDMA_CSR_RUN(rCDMA_CHANNEL_CSR(dma_channel))) { + if (time_has_elapsed(start_time, 10000)) + panic("CDMA: channel %d timeout during abort", dma_channel); + } + } + + /* clear the crypto config */ + dma_set_aes(dma_channel, NULL); + + /* turn off the channel clock */ + cdma_clock_enable(dma_channel, false); + + /* mark the channel idle */ + cp->c_status = CDMA_STATUS_IDLE; +} + +/* + * Set the AES configuration for (dma_channel). + * + * If (config) is NULL, AES is disabled for the channel. + */ +int +dma_set_aes(int dma_channel, struct dma_aes_config *config) +{ + struct cdma_channel *cp; + int i; + u_int32_t fcsr; + bool clock_state; + + + ASSERT((dma_channel > 0) && (dma_channel <= DMA_CHANNEL_COUNT)); + cp = CDMA_SOFTC(dma_channel); + + cp->c_aes = config; + + if (NULL != config) { + + /* + * For v2+ we must turn on at least one AES-using channel before + * the AES block will be clocked. Since we can't be sure whether + * one is on or not, turn this one on and remember whether it was + * already on so that we don't turn it off inadvertently. + */ + clock_state = cdma_clock_enable(dma_channel, true); + + /* assign an AES filter context */ + if (0 == cp->c_filter) { + enter_critical_section(); + for (i = 2; i < CDMA_FILTER_CONTEXTS; i++) { + if (!(cdma_fc_inuse & (1 << i))) { + cp->c_filter = i; + cdma_fc_inuse |= (1 << i); + break; + } + } + exit_critical_section(); + } + if (0 == cp->c_filter) + panic("CDMA: no AES filter contexts: 0x%08x", cdma_fc_inuse); + + /* invariants */ + fcsr = CDMA_FCSR_CHANNEL(dma_channel) | CDMA_FCSR_CBC; + + /* direction */ + if ((cp->c_aes->command & AES_CMD_DIR_MASK) == AES_CMD_ENC) + fcsr |= CDMA_FCSR_ENC; + + /* key size */ + switch (cp->c_aes->keying & AES_KEY_SIZE_MASK) { + case AES_KEY_SIZE_128: + fcsr |= CDMA_FCSR_KL_128; + break; + case AES_KEY_SIZE_192: + fcsr |= CDMA_FCSR_KL_192; + break; + case AES_KEY_SIZE_256: + fcsr |= CDMA_FCSR_KL_256; + break; + default: + ASSERT(false); + return(-1); + } + + /* key selection/load */ + switch (cp->c_aes->keying & AES_KEY_TYPE_MASK) { + case AES_KEY_TYPE_USER: + fcsr |= CDMA_FCSR_KS_VARIABLE; + ASSERT(NULL != cp->c_aes->key); + switch (cp->c_aes->keying & AES_KEY_SIZE_MASK) { + case AES_KEY_SIZE_256: + rCDMA_FILTER_KBR7(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[7]; + rCDMA_FILTER_KBR6(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[6]; + case AES_KEY_SIZE_192: + rCDMA_FILTER_KBR5(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[5]; + rCDMA_FILTER_KBR4(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[4]; + case AES_KEY_SIZE_128: + rCDMA_FILTER_KBR3(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[3]; + rCDMA_FILTER_KBR2(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[2]; + rCDMA_FILTER_KBR1(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[1]; + rCDMA_FILTER_KBR0(cp->c_filter) = ((u_int32_t *)cp->c_aes->key)[0]; + break; + default: + ASSERT(false); + return(-1); + } + break; + case AES_KEY_TYPE_UID0: + fcsr |= CDMA_FCSR_KEY(0); + break; + case AES_KEY_TYPE_GID0: + fcsr |= CDMA_FCSR_KEY(1); + break; + case AES_KEY_TYPE_GID1: + fcsr |= CDMA_FCSR_KEY(2); + break; + default: + ASSERT(false); + return(-1); + } + + /* and configure */ + rCDMA_FILTER_CSR(cp->c_filter) = fcsr; + + /* + * It's safe to turn the channel clock off now if it was off when we started. + */ + cdma_clock_enable(dma_channel, clock_state); + } + + return(0); +} + +bool +cdma_clock_enable(int channel, bool state) +{ + bool previous = true; +#if CDMA_VERSION > 1 + int bank; + int bit; + + bank = channel / 32; + bit = channel % 32; + + /* save the previous state for our caller */ + previous = rCDMA_CLOCK_STATUS(bank) & (1 << bit); + + /* frob clock as requested */ + if (state != previous) { + if (state) { + rCDMA_CLOCK_ON(bank) = 1 << bit; + } else { + rCDMA_CLOCK_OFF(bank) = 1 << bit; + } + } +#endif + return(previous); +} + +static void +cdma_dump_channel(int channel) +{ + struct cdma_channel *cp; + struct cdma_command *cmd; + struct dma_segment *seg; + int i; + u_int32_t resid; + int filter; + bool clock_state; + + cp = CDMA_SOFTC(channel); + if (CDMA_STATUS_UNINIT == cp->c_status) { + dprintf(DEBUG_CRITICAL, "CDMA: channel %d not set up\n", channel); + return; + } + + clock_state = cdma_clock_enable(channel, true); + dprintf(DEBUG_CRITICAL, "CDMA: channel %d %s(%d), index %d resid 0x%x\n", + channel, + ((cp->c_status == CDMA_STATUS_IDLE) ? "idle" : ((cp->c_status == CDMA_STATUS_BUSY) ? "busy" : "unknown")), + cp->c_status, cp->c_index, cp->c_resid); + if (cp->c_status != CDMA_STATUS_IDLE) { + dprintf(DEBUG_CRITICAL, "CDMA: channel %d length 0x%x\n", channel, cp->c_length); + resid = cp->c_length; + seg = cp->c_sgl; + dprintf(DEBUG_CRITICAL, "CDMA: seg addr/seg length\n"); + for (i = 0; ; i++) { + dprintf(DEBUG_CRITICAL, "CDMA: 0x%08x/0x%x\n", seg->paddr, seg->length); + if (seg->length >= resid) + break; + resid -= seg->length; + seg++; + } + cmd = cp->c_chain; + resid = cp->c_length; + for (i = 0; i < CDMA_CHANNEL_CMDS; i++) { + dprintf(DEBUG_CRITICAL, "CDMA: NXT 0x%08x CMD 0x%08x ADDR 0x%08x LEN 0x%08x\n", + cmd->nxt, cmd->ctrl, cmd->addr, cmd->length); + if ((cmd->ctrl & CDMA_CTRL_CMD_MASK) == CDMA_CTRL_CMD_MEM) { + if (cmd->length >= resid) + break; + resid -= cmd->length; + } + cmd++; + } + } +#if CDMA_VERSION > 1 + dprintf(DEBUG_CRITICAL, "CDMA: CSR 0x%08x DCR 0x%08x DAR 0x%08x DBR 0x%08x MAR 0x%08x CAR 0x%08x ERR 0x%08x\n", + rCDMA_CHANNEL_CSR(channel), rCDMA_CHANNEL_DCR(channel), rCDMA_CHANNEL_DAR(channel), + rCDMA_CHANNEL_DBR(channel), rCDMA_CHANNEL_MAR(channel), rCDMA_CHANNEL_CAR(channel), + rCDMA_CHANNEL_ERR(channel) & rCDMA_CHANNEL_ERR_MASK); +#else + dprintf(DEBUG_CRITICAL, "CDMA: CSR 0x%08x DCR 0x%08x DAR 0x%08x DBR 0x%08x MAR 0x%08x CAR 0x%08x\n", + rCDMA_CHANNEL_CSR(channel), rCDMA_CHANNEL_DCR(channel), rCDMA_CHANNEL_DAR(channel), + rCDMA_CHANNEL_DBR(channel), rCDMA_CHANNEL_MAR(channel), rCDMA_CHANNEL_CAR(channel)); +#endif + dprintf(DEBUG_CRITICAL, "CDMA: CMD_NXT 0x%08x CMD_CMD 0x%08x CMD_ADDR 0x%08x CMD_LEN 0x%08x\n", + rCDMA_CHANNEL_CMND0(channel), rCDMA_CHANNEL_CMND1(channel), rCDMA_CHANNEL_CMND2(channel), + rCDMA_CHANNEL_CMND3(channel)); + + filter = (rCDMA_CHANNEL_CSR(channel) >> 8) & 0xff; + if (filter > 0) { + dprintf(DEBUG_CRITICAL, "FILT: CSR 0x%08x\n", rCDMA_FILTER_CSR(filter)); + dprintf(DEBUG_CRITICAL, "FILT: IV 0x%08x 0x%08x 0x%08x 0x%08x\n", + rCDMA_FILTER_IVR0(filter), + rCDMA_FILTER_IVR1(filter), + rCDMA_FILTER_IVR2(filter), + rCDMA_FILTER_IVR3(filter)); + dprintf(DEBUG_CRITICAL, "FILT: KEY 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", + rCDMA_FILTER_KBR0(filter), + rCDMA_FILTER_KBR1(filter), + rCDMA_FILTER_KBR2(filter), + rCDMA_FILTER_KBR3(filter), + rCDMA_FILTER_KBR4(filter), + rCDMA_FILTER_KBR5(filter), + rCDMA_FILTER_KBR6(filter), + rCDMA_FILTER_KBR7(filter)); + } + cdma_clock_enable(channel, clock_state); +} + +static int +do_cdma(int argc, struct cmd_arg *args) +{ + int i; + + if (argc != 2) { + dprintf(DEBUG_CRITICAL, "not enough arguments\n"); +usage: + dprintf(DEBUG_CRITICAL, "usage:\n"); + dprintf(DEBUG_CRITICAL, "%s list - list CDMA channels in use\n", args[0].str); + dprintf(DEBUG_CRITICAL, "%s - print status for \n", args[0].str); + return(-1); + } + + if (!strcmp(args[1].str, "list")) { + dprintf(DEBUG_CRITICAL, "CDMA channels in use:"); + for (i = 1; i <= DMA_CHANNEL_COUNT; i++) + if (CDMA_STATUS_UNINIT != CDMA_SOFTC(i)->c_status) + dprintf(DEBUG_CRITICAL, " %d", i); + dprintf(DEBUG_CRITICAL, "\n"); + } else if ((args[1].u > 0) && (args[1].u <= DMA_CHANNEL_COUNT)) { + cdma_dump_channel(args[1].u); + } else { + goto usage; + } + return(0); +} + +MENU_COMMAND_DEBUG(cdma, do_cdma, "CDMA status", NULL); + +static void +do_cdma_panic(void *arg __unused) +{ + int i; + + for (i = 1; i <= DMA_CHANNEL_COUNT; i++) + if (CDMA_STATUS_UNINIT != CDMA_SOFTC(i)->c_status) + cdma_dump_channel(i); +} + +PANIC_HOOK(cdma, do_cdma_panic, NULL); diff --git a/drivers/apple/cdma/cdma.h b/drivers/apple/cdma/cdma.h new file mode 100644 index 0000000..58392e4 --- /dev/null +++ b/drivers/apple/cdma/cdma.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_CDMA_H +#define __APPLE_CDMA_H + +#include +#include + +__BEGIN_DECLS + +#define rCDMA_CHANNEL_CSR(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000000 + (n) * 0x1000)) + +#define CDMA_CSR_GO (1<<0) +#define CDMA_CSR_ABT (1<<1) +#define CDMA_CSR_PS (1<<2) +#define CDMA_CSR_HIE (1<<3) +#define CDMA_CSR_CIE (1<<4) +#define CDMA_CSR_MTM (1<<7) +#define CDMA_CSR_FC(_x) (((_x) & 0xff) << 8) +#define CDMA_CSR_FC_NONE 0 +#define CDMA_CSR_RUN(_x) (((_x) >> 16) & 3) +#define CDMA_CSR_RUN_HALTED 0 +#define CDMA_CSR_RUN_RUNNING 1 +#define CDMA_CSR_RUN_STOPPED 2 +#define CDMA_CSR_ERR (1<<18) +#define CDMA_CSR_HIR (1<<19) +#define CDMA_CSR_CIR (1<<20) +#define CDMA_CSR_PSD (1<<21) +#define CDMA_CSR_HIGH (1<<22) +#define CDMA_CSR_SMALL (1<<23) +#define CDMA_CSR_CCACHE(_x) (((_x) & 0xf) << 24) + +#define CDMA_CACHE_BUFFER (1<<0) +#define CDMA_CACHE_CACHE (1<<1) +#define CDMA_CACHE_RALLOC (1<<2) +#define CDMA_CACHE_WALLOC (1<<3) + +#define rCDMA_CHANNEL_DCR(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000004 + (n) * 0x1000)) + +#define CDMA_DCR_DL (1<<0) +#define CDMA_DCR_DTD_RX (0<<1) +#define CDMA_DCR_DTD_TX (1<<1) +#define CDMA_DCR_DW_1 (0<<2) +#define CDMA_DCR_DW_2 (1<<2) +#define CDMA_DCR_DW_4 (2<<2) +#define CDMA_DCR_DBS_1 (0<<4) +#define CDMA_DCR_DBS_2 (1<<4) +#define CDMA_DCR_DBS_4 (2<<4) +#define CDMA_DCR_DBS_8 (3<<4) +#define CDMA_DCR_DBS_16 (4<<4) +#define CDMA_DCR_DBS_32 (5<<4) +#define CDMA_DCR_ST (1<<7) +#define CDMA_DCR_REQ(_x) (((_x) & 0x3f) << 16) + +#define rCDMA_CHANNEL_DAR(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000008 + (n) * 0x1000)) +#define rCDMA_CHANNEL_DBR(n) (*(volatile int32_t *)(CDMA_BASE_ADDR + 0x00000C + (n) * 0x1000)) +#define rCDMA_CHANNEL_MAR(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000010 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CAR(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000014 + (n) * 0x1000)) +#define rCDMA_CHANNEL_ERR(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000018 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND0(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000020 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND1(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000024 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND2(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000028 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND3(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x00002C + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND4(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000030 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND5(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000034 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND6(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000038 + (n) * 0x1000)) +#define rCDMA_CHANNEL_CMND7(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x00003C + (n) * 0x1000)) +#define rCDMA_CHANNEL_FIFOST(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000040 + (n) * 0x1000)) +#define rCDMA_CHANNEL_FIFODT(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000400 + (n) * 0x1000)) + +#define rCDMA_CLOCK_ON(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000000 + (n) * 0x4)) +#define rCDMA_CLOCK_OFF(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000008 + (n) * 0x4)) +#define rCDMA_CLOCK_STATUS(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x000010 + (n) * 0x4)) + +#define rCDMA_CHANNEL_ERR_MASK (0xFF) + +// v4+ +#define CDMA_CLOCK_AES_CORE (30) +#define CDMA_CLOCK_AES_WRAP (31) + +#define rCDMA_FILTER_KEYDIS (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800000)) + +#define rCDMA_FILTER_CSR(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800000 + (n) * 0x1000)) + +#define CDMA_FCSR_LCK (1<<0) +#define CDMA_FCSR_CHANNEL(_x) (((_x) & 0xff) << 8) +#define CDMA_FCSR_ENC (1<<16) +#define CDMA_FCSR_CBC (1<<17) +#define CDMA_FCSR_KL_128 (0<<18) +#define CDMA_FCSR_KL_192 (1<<18) +#define CDMA_FCSR_KL_256 (2<<18) +#define CDMA_FCSR_KS_VARIABLE (1<<20) +#define CDMA_FCSR_KEY(_x) (((_x) & 0x0f) << 21) + +#define rCDMA_FILTER_IVR0(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800010 + (n) * 0x1000)) +#define rCDMA_FILTER_IVR1(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800014 + (n) * 0x1000)) +#define rCDMA_FILTER_IVR2(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800018 + (n) * 0x1000)) +#define rCDMA_FILTER_IVR3(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x80001C + (n) * 0x1000)) +#define rCDMA_FILTER_KBR0(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800020 + (n) * 0x1000)) +#define rCDMA_FILTER_KBR1(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800024 + (n) * 0x1000)) +#define rCDMA_FILTER_KBR2(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800028 + (n) * 0x1000)) +#define rCDMA_FILTER_KBR3(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x80002C + (n) * 0x1000)) +#define rCDMA_FILTER_KBR4(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800030 + (n) * 0x1000)) +#define rCDMA_FILTER_KBR5(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800034 + (n) * 0x1000)) +#define rCDMA_FILTER_KBR6(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800038 + (n) * 0x1000)) +#define rCDMA_FILTER_KBR7(n) (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x80003C + (n) * 0x1000)) + +#define CDMA_FILTER_CONTEXTS 8 +#define CDMA_FILTER_CONTEXT_NORMAL_M2M 1 +#define CDMA_FILTER_CONTEXT_DESCRAMBLER 8 + +// v4+ +#define rCDMA_FILTER_SKGCNTL (*(volatile u_int32_t *)(CDMA_BASE_ADDR + 0x800428)) + +#define CDMA_FSKGCNTL_SKGDIS (1 << 1) + +struct cdma_command { + u_int32_t nxt; + u_int32_t ctrl; +#define CDMA_CTRL_CMD_HLT 0 +#define CDMA_CTRL_CMD_NOP 1 +#define CDMA_CTRL_CMD_LDIV 2 +#define CDMA_CTRL_CMD_MEM 3 +#define CDMA_CTRL_CMD_STP 4 +#define CDMA_CTRL_CMD_MASK 0xf +#define CDMA_CTRL_BAR (1 << 8) +#define CDMA_CTRL_CIR (1 << 9) +#define CDMA_CTRL_FE (1 << 16) +#define CDMA_CTRL_FR (1 << 17) +#define CDMA_CTRL_QOS(_x) (((_x) & 0xf) << 20) +#define CDMA_CTRL_CACHE(_x) (((_x) & 0xf) << 24) + u_int32_t addr; + u_int32_t length; + u_int32_t iv0; + u_int32_t iv1; + u_int32_t iv2; + u_int32_t iv3; +}; + +bool cdma_clock_enable(int channel, bool state); + +__END_DECLS + +#endif /* ! __APPLE_CDMA_H */ diff --git a/drivers/apple/cdma/cdma_aes.c b/drivers/apple/cdma/cdma_aes.c new file mode 100644 index 0000000..6ad83ec --- /dev/null +++ b/drivers/apple/cdma/cdma_aes.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cdma.h" + +#define CDMA_AES_UID_MASK (1 << 0) +#define CDMA_AES_UID_PLUS_MASK (1 << 1) // v4+ + +static int dma_setup_channel(u_int32_t cmd_dir, int dma_channel, + u_int32_t mem_addr, u_int32_t dev_addr, u_int32_t length, + u_int32_t word_size, u_int32_t burst_size, bool filter); + +static void dma_wait_channel_halted(int dma_channel); +static void cdma_dump_aes_channel(int channel); + +static struct cdma_command cdma_aes_command[4] __attribute__((aligned(32))); + +void +platform_disable_keys(u_int32_t gid, u_int32_t uid) +{ + u_int32_t keydis = ((gid << 1) | (uid & CDMA_AES_UID_MASK)) & 0x0000FFFF; + + cdma_clock_enable(DMA_MEMORY_TX, true); + rCDMA_FILTER_KEYDIS = keydis; + cdma_clock_enable(DMA_MEMORY_TX, false); + + // SKG disable feature is broken. + // To workaroud, UID+ will tag along UID. If UID is disabled, we assume UID+ is also disabled +#if CDMA_VERSION >= 4 + if (uid & CDMA_AES_UID_MASK) { + rCDMA_FILTER_SKGCNTL = CDMA_FSKGCNTL_SKGDIS; + } +#endif /* CDMA_VERSION >= 4 */ +} + +int +aes_hw_crypto_cmd(u_int32_t cmd, void *src, void *dst, size_t len, u_int32_t opts, const void *key, void *iv) +{ + u_int32_t cbc_val, dec_val, kl_val, ks_val, kx_val; + + clock_gate(CLK_CDMA, true); + cdma_clock_enable(DMA_MEMORY_TX, true); + cdma_clock_enable(DMA_MEMORY_RX, true); + + /* clip length to multiple of 16 bytes */ + if (len & 0xf) + goto fail; + + switch (cmd & AES_CMD_MODE_MASK) { + case AES_CMD_ECB : cbc_val = 0; break; + case AES_CMD_CBC : cbc_val = 1; break; + default : goto fail; + } + + switch (cmd & AES_CMD_DIR_MASK) { + case AES_CMD_ENC : dec_val = 1; break; + case AES_CMD_DEC : dec_val = 0; break; + default : goto fail; + } + + /* Set the IV */ + if (iv != 0) { + rCDMA_FILTER_IVR0(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)iv)[0]; + rCDMA_FILTER_IVR1(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)iv)[1]; + rCDMA_FILTER_IVR2(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)iv)[2]; + rCDMA_FILTER_IVR3(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)iv)[3]; + } else { + rCDMA_FILTER_IVR0(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_IVR1(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_IVR2(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_IVR3(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + } + + /* Get the key length */ + kl_val = 0; + switch (opts & AES_KEY_SIZE_MASK) { + case AES_KEY_SIZE_128 : kl_val = 0; break; + case AES_KEY_SIZE_192 : kl_val = 1; break; + case AES_KEY_SIZE_256 : kl_val = 2; break; + default : goto fail; + } + + /* Set the key */ + ks_val = 0; + kx_val = 0; + switch (opts & AES_KEY_TYPE_MASK) { + case AES_KEY_TYPE_USER : + + ks_val = 1; + + switch (kl_val) { + default: + rCDMA_FILTER_KBR7(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[7]; + rCDMA_FILTER_KBR6(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[6]; + case 1: + rCDMA_FILTER_KBR5(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[5]; + rCDMA_FILTER_KBR4(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[4]; + case 0: + rCDMA_FILTER_KBR3(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[3]; + rCDMA_FILTER_KBR2(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[2]; + rCDMA_FILTER_KBR1(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[1]; + rCDMA_FILTER_KBR0(CDMA_FILTER_CONTEXT_NORMAL_M2M) = ((u_int32_t *)key)[0]; + } + + case AES_KEY_TYPE_UID0 : kx_val = 0; break; + case AES_KEY_TYPE_GID0 : kx_val = 1; break; + case AES_KEY_TYPE_GID1 : kx_val = 2; break; + } + + /* make sure the requested key is available */ + if ((0 == ks_val) && (rCDMA_FILTER_KEYDIS & (1 << kx_val))) { + dprintf(DEBUG_INFO, "CDMA: requested AES key has been disabled\n"); + return -1; + } + + rCDMA_FILTER_CSR(CDMA_FILTER_CONTEXT_NORMAL_M2M) = + ((DMA_MEMORY_TX << 8) | // DMA Channel + (dec_val << 16) | // decode / encode + (cbc_val << 17) | // cbc / ecb + (kl_val << 18) | // key length + (ks_val << 20) | // key select: fixed / variable + (kx_val << 21)); // key index + + if (0 != dma_setup_channel(DMA_CMD_DIR_MEM, DMA_MEMORY_TX, (u_int32_t)src, 0, len, 0, 0, true)) + goto fail; + + if (0 != dma_setup_channel(DMA_CMD_DIR_MEM, DMA_MEMORY_RX, (u_int32_t)dst, 0, len, 0, 0, false)) + goto fail; + + platform_cache_operation(CACHE_CLEAN, src, len); + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, dst, len); + + /* Start the channel */ + rCDMA_CHANNEL_CSR(DMA_MEMORY_TX) |= (1 << 0); + rCDMA_CHANNEL_CSR(DMA_MEMORY_RX) |= (1 << 0); + + /* Wait for both channels to halt (this ensures both are marked idle) */ + dma_wait_channel_halted(DMA_MEMORY_TX); + dma_wait_channel_halted(DMA_MEMORY_RX); + +#if CDMA_IS_INCOHERENT + /* If core did any speculative prefetching during DMA, invalidate the cache lines again */ + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, dst, len); +#endif + + /* Clear user key from the registers */ + if (ks_val != 0) { + rCDMA_FILTER_KBR0(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_KBR1(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_KBR2(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_KBR3(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_KBR4(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_KBR5(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_KBR6(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + rCDMA_FILTER_KBR7(CDMA_FILTER_CONTEXT_NORMAL_M2M) = 0; + } + + cdma_clock_enable(DMA_MEMORY_TX, false); + cdma_clock_enable(DMA_MEMORY_RX, false); + + return 0; +fail: + panic("CDMA AES: bad arguments"); +} + +static int +dma_setup_channel(u_int32_t cmd_dir, int dma_channel, + u_int32_t mem_addr, u_int32_t dev_addr, u_int32_t length, + u_int32_t word_size, u_int32_t burst_size, bool filter) +{ + struct cdma_command *cdma_cmd; + u_int32_t dw_val, dbs_val, dcr_val, ccache_val = 0; + int result = -1; + + /* must always abort the channel before configuring it */ + rCDMA_CHANNEL_CSR(dma_channel) = CDMA_CSR_ABT; + + cdma_cmd = &cdma_aes_command[(dma_channel * 2) - 2]; + cdma_cmd->ctrl = (filter ? CDMA_CTRL_FE | CDMA_CTRL_FR : 0) | CDMA_CTRL_BAR | CDMA_CTRL_CMD_MEM; +#if (CDMA_VERSION == 3) || (CDMA_VERSION == 4) + ccache_val = CDMA_CTRL_CACHE(CDMA_CACHE_CACHE); + cdma_cmd->ctrl |= CDMA_CTRL_CACHE(CDMA_CACHE_CACHE); +#elif CDMA_VERSION >= 5 + ccache_val = CDMA_CTRL_CACHE(CDMA_CACHE_BUFFER | CDMA_CACHE_CACHE | CDMA_CACHE_WALLOC); + cdma_cmd->ctrl |= CDMA_CTRL_CACHE(CDMA_CACHE_BUFFER | CDMA_CACHE_CACHE); + if (dma_channel == DMA_MEMORY_TX) + cdma_cmd->ctrl |= CDMA_CTRL_CACHE(CDMA_CACHE_WALLOC); + else + cdma_cmd->ctrl |= CDMA_CTRL_CACHE(CDMA_CACHE_RALLOC); +#endif + cdma_cmd->addr = mem_addr; + cdma_cmd->length = length; + + /* terminate the chain */ + cdma_cmd->nxt = (u_int32_t)(cdma_cmd + 1); + (cdma_cmd + 1)->ctrl = CDMA_CTRL_CMD_HLT; + + if (cmd_dir == DMA_CMD_DIR_MEM) { + dcr_val = CDMA_CSR_MTM; + } else { + dcr_val = 0; /* ! CDMA_CSR_MTM */ + + switch (word_size) { + case 1 : dw_val = 0; break; + case 2 : dw_val = 1; break; + case 4 : dw_val = 2; break; + default : goto exit; break; + } + + switch (burst_size) { + case 1 : dbs_val = 0; break; + case 2 : dbs_val = 1; break; + case 4 : dbs_val = 2; break; + case 8 : dbs_val = 3; break; + case 16 : dbs_val = 4; break; + case 32 : dbs_val = 5; break; + default : goto exit; break; + } + + rCDMA_CHANNEL_DCR(dma_channel) = + ((cmd_dir == DMA_CMD_DIR_TX) ? CDMA_DCR_DTD_TX : CDMA_DCR_DTD_RX) | + (dw_val << 2) | + (dbs_val << 4); + + rCDMA_CHANNEL_DAR(dma_channel) = dev_addr; + } + + platform_cache_operation(CACHE_CLEAN , cdma_cmd, sizeof(struct cdma_command)); + + rCDMA_CHANNEL_DBR(dma_channel) = length; + rCDMA_CHANNEL_CAR(dma_channel) = (u_int32_t)cdma_cmd; + + /* Clear channel status and configure */ + rCDMA_CHANNEL_CSR(dma_channel) = CDMA_CSR_CIR | CDMA_CSR_HIR | CDMA_CSR_ERR | (filter << 8) | dcr_val | ccache_val; + + result = 0; + +exit: + return result; +} + +static void +dma_wait_channel_halted(int dma_channel) +{ + while (CDMA_CSR_RUN(rCDMA_CHANNEL_CSR(dma_channel)) == CDMA_CSR_RUN_RUNNING) + task_yield(); +} + +static void +cdma_dump_aes_channel(int channel) +{ + int filter; + bool clock_state; + + clock_state = cdma_clock_enable(channel, true); + printf("CDMA: CSR 0x%08x DCR 0x%08x DAR 0x%08x DBR 0x%08x MAR 0x%08x CAR 0x%08x\n", + rCDMA_CHANNEL_CSR(channel), rCDMA_CHANNEL_DCR(channel), rCDMA_CHANNEL_DAR(channel), + rCDMA_CHANNEL_DBR(channel), rCDMA_CHANNEL_MAR(channel), rCDMA_CHANNEL_CAR(channel)); + printf("CDMA: CMD_NXT 0x%08x CMD_CMD 0x%08x CMD_ADDR 0x%08x CMD_LEN 0x%08x\n", + rCDMA_CHANNEL_CMND0(channel), rCDMA_CHANNEL_CMND1(channel), rCDMA_CHANNEL_CMND2(channel), + rCDMA_CHANNEL_CMND3(channel)); + + filter = (rCDMA_CHANNEL_CSR(channel) >> 8) & 0xff; + if (filter > 0) { + printf("FILT: CSR 0x%08x\n", rCDMA_FILTER_CSR(filter)); + printf("FILT: IV 0x%08x 0x%08x 0x%08x 0x%08x\n", + rCDMA_FILTER_IVR0(filter), + rCDMA_FILTER_IVR1(filter), + rCDMA_FILTER_IVR2(filter), + rCDMA_FILTER_IVR3(filter)); + printf("FILT: KEY 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", + rCDMA_FILTER_KBR0(filter), + rCDMA_FILTER_KBR1(filter), + rCDMA_FILTER_KBR2(filter), + rCDMA_FILTER_KBR3(filter), + rCDMA_FILTER_KBR4(filter), + rCDMA_FILTER_KBR5(filter), + rCDMA_FILTER_KBR6(filter), + rCDMA_FILTER_KBR7(filter)); + } + cdma_clock_enable(channel, clock_state); +} diff --git a/drivers/apple/cdma/rules.mk b/drivers/apple/cdma/rules.mk new file mode 100644 index 0000000..b651be8 --- /dev/null +++ b/drivers/apple/cdma/rules.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DMA=1 \ + WITH_HW_AES=1 + +MODULES += \ + drivers/aes + +ALL_OBJS += \ + $(LOCAL_DIR)/cdma.o \ + $(LOCAL_DIR)/cdma_aes.o diff --git a/drivers/apple/consistent_debug/consistent_debug.c b/drivers/apple/consistent_debug/consistent_debug.c new file mode 100644 index 0000000..5b1bd69 --- /dev/null +++ b/drivers/apple/consistent_debug/consistent_debug.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static dbg_registry_t * consistent_debug_registry = NULL; +static dbg_cpr_t* ap_cpr; + + +static dbg_registry_t* init_consistent_debug_registry(void *consistent_debug_base); +static dbg_record_header_t* consistent_debug_allocate_entry(); +static void consistent_debug_register_root_pointer(void); + +static void consistent_debug_ensure_visibility() +{ + platform_memory_barrier(); +#if WITH_NON_COHERENT_DMA + // On platforms without coherent DMA, JTAG access is likely incoherent as well. + platform_cache_operation(CACHE_CLEAN, consistent_debug_registry, sizeof(dbg_registry_t)); +#endif +} + +int consistent_debug_resume(void) +{ + // When resuming from hibernate, assume we have a valid Consistent Debug Registry, and + // put the root address back in the PMGR scratch (which gets cleared on hibernate) + dprintf(DEBUG_SPEW, "Restoring consistent debug state, preserving existing entries...\n"); + consistent_debug_registry = (dbg_registry_t*)((void*)CONSISTENT_DEBUG_BASE); + ap_cpr = &consistent_debug_registry->ap_cpr_region; + // Ensure the header is visible before publishing it in the scratch register. + consistent_debug_ensure_visibility(); + consistent_debug_register_root_pointer(); + return 0; +} + +int consistent_debug_init(void) +{ + dprintf(DEBUG_SPEW, "Enabling consistent debug...\n"); + ASSERT(CONSISTENT_DEBUG_SIZE >= sizeof(dbg_registry_t)); + consistent_debug_registry = init_consistent_debug_registry((void*)CONSISTENT_DEBUG_BASE); + + + // Set up the CPR + dbg_record_header_t ap_progress_report; + ap_progress_report.record_id = kDbgIdCPRHeaderAP; + ap_progress_report.physaddr = (uint64_t)(mem_static_map_physical((uintptr_t)(&consistent_debug_registry->ap_cpr_region))); + ap_progress_report.length = sizeof(dbg_cpr_t); + ap_cpr = &consistent_debug_registry->ap_cpr_region; + consistent_debug_update_ap_cpr(DBG_CPR_STATE_BOOTING, 0); + + // Set up the XNU PANIC_BASE pointer, so once booted Astris can still unpack the panic string. + dbg_record_header_t panic_region; + panic_region.record_id = kDbgIdXNUPanicRegion; + panic_region.physaddr = (uint64_t)(PANIC_BASE); + panic_region.length = (uint64_t)(PANIC_SIZE); + if(!consistent_debug_register_header(panic_region)) + { + dprintf(DEBUG_INFO, "Unable to register XNU panic region in consistent debug.\n"); + } + + dbg_record_header_t* hdr = (dbg_record_header_t*)consistent_debug_register_header(ap_progress_report); + RELEASE_ASSERT(hdr); + // Ensure the header is visible before publishing it in the scratch register. + consistent_debug_ensure_visibility(); + consistent_debug_register_root_pointer(); + return 0; +} + +static void consistent_debug_register_root_pointer(void) +{ + uint32_t root; + uintptr_t consistent_debug_addr = mem_static_map_physical((uintptr_t)consistent_debug_registry); + root = consistent_debug_encode_root_pointer(consistent_debug_addr, 0); + platform_set_consistent_debug_root_pointer(root); + dprintf(DEBUG_SPEW, "Registered consistent debug root pointer (encoded as 0x%x)\n", (unsigned int)root); +} + + +dbg_registry_t* consistent_debug_get_registry(void) +{ + return consistent_debug_registry; +} + +void consistent_debug_update_ap_cpr(cp_state_t state, int arg) +{ + if(ap_cpr) { + enter_critical_section(); + if(ap_cpr->rdptr + 1 == ap_cpr->wrptr) + { + dprintf(DEBUG_SPEW, "AP CPR is full, advancing rdptr\n"); + // Eat the oldest entry if buffer gets full. + ap_cpr->rdptr++; + consistent_debug_ensure_visibility(); + } + dbg_cpr_state_entry_t* entry = &ap_cpr->cp_state_entries[ap_cpr->wrptr]; + entry->cp_state = state; + entry->cp_state_arg = arg; + entry->timestamp = timer_get_ticks(); + consistent_debug_ensure_visibility(); + ap_cpr->wrptr++; + exit_critical_section(); + dprintf(DEBUG_SPEW, "AP CPR updated at time %llu with state %d (argument %d)\n", entry->timestamp, entry->cp_state, entry->cp_state_arg); + } + +} + +static dbg_registry_t* init_consistent_debug_registry(void* consistent_debug_base) +{ + dbg_registry_t* reg = (dbg_registry_t*)(consistent_debug_base); + memset(reg, 0, sizeof(dbg_registry_t)); + reg->top_level_header.record_id = kDbgIdTopLevelHeader; + reg->top_level_header.num_records = DEBUG_REGISTRY_MAX_RECORDS; + reg->top_level_header.record_size_bytes = sizeof(dbg_record_header_t); + + + return reg; +} + +/** + * Finds a free entry in the Consistent Debug Registry and + * reserves it. + * + * @author jdong (12/7/2012) + * + * @return NULL if unsuccessful, otherwise a pointer to a + * reserved entry (where the record_id is set to + * kDbgIdReservedEntry) + */ +static dbg_record_header_t* consistent_debug_allocate_entry(void) { + if (!consistent_debug_registry) { + enter_critical_section(); + if(!consistent_debug_registry) { + // Check again to make sure someone else didn't enable it already + consistent_debug_init(); + } + exit_critical_section(); + return consistent_debug_allocate_entry(); + } + + for (unsigned int i = 0; i < consistent_debug_registry->top_level_header.num_records; i++) { + dbg_record_header_t *record = &consistent_debug_registry->records[i]; + if (__sync_bool_compare_and_swap(&record->record_id, kDbgIdUnusedEntry, kDbgIdReservedEntry)) { + // Reserved an entry at position i. + return (dbg_record_header_t*)record; + } + } + return NULL; +} + + +dbg_record_header_t* consistent_debug_register_header(dbg_record_header_t hdr) { + dbg_record_header_t *allocated_header = consistent_debug_allocate_entry(); + if (allocated_header) { + allocated_header->length = hdr.length; + allocated_header->physaddr = hdr.physaddr; + consistent_debug_ensure_visibility(); + // Make sure the hdr/length are visible before the record_id. + allocated_header->record_id = hdr.record_id; + consistent_debug_ensure_visibility(); + } + return allocated_header; +} + + +int consistent_debug_unregister_header(dbg_record_header_t *hdr) +{ + if (!consistent_debug_registry) { + return -1; + } + if ((hdr < &consistent_debug_registry->records[0]) || + (hdr >= &consistent_debug_registry->records[consistent_debug_registry->top_level_header.num_records])) { + // Out of range + return -1; + } + // The record ID may be modified by the JTAG observer, and the caller + // loops on the value changing to kDbgIdUnusedEntry. Make sure we read it from memory. + switch (*(volatile uint64_t*)(&hdr->record_id)) { + case kDbgIdUnusedEntry: + return -1; + case kDbgIdFreeReqEntry: + return 0; + case kDbgIdFreeAckEntry: + hdr->record_id = kDbgIdUnusedEntry; + return 1; + default: + hdr->record_id = kDbgIdFreeReqEntry; + return 0; + } +} diff --git a/drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_helper_fns.h b/drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_helper_fns.h new file mode 100644 index 0000000..d23f516 --- /dev/null +++ b/drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_helper_fns.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __CONSISTENT_DEBUG_HELPER_FNS__ +#define __CONSISTENT_DEBUG_HELPER_FNS__ + +#include "consistent_debug_registry.h" + +// C Helper functions that should serve as a pseudo-library +// for other codebases that use Consistent Debug + + +// Root Pointer encoder/decoder + +/** + * Encode 64-bit physical address of root pointer into a + * suitable 32-bit format. + * + * @param root_pointer 64-bit pointer to the physical address of + * the consistent debug registry + * @param pointer_type One of the types documented in "Debug + * Root Pointer Scratch Register Format" of + * consistent_debug_registry.h + * + * @return uint32_t 0: Cannot encode address with specified + * type, or invalid type. Otherwise, returns a 32-bit + * representation of the address. + */ +static inline uint32_t consistent_debug_encode_root_pointer(uint64_t root_pointer, unsigned int pointer_type) +{ + if (pointer_type != 0) { + return 0; // Only type 0 is supported currently + } + + if (root_pointer & 0xFFF) { + return 0; // Not page-aligned, truncation would lose information + } + root_pointer >>= 12; + + if (root_pointer >= 0x3FFFFFFFF) { + return 0; // Too large to represent + } + + return (uint32_t)root_pointer; +} + +/** + * opposite of consistent_debug_encode_root_pointer; decodes a root + * pointer encoded in that manner. + * + * @return uint64_t 0 if cannot be decoded, otherwise the + * physical address. + */ +static inline uint64_t consistent_debug_decode_root_pointer(uint32_t encoded_value) +{ + if (encoded_value & 0xC0000000) { + return 0; // Can't decode anything other than a "type 0" address + } + uint64_t ret = encoded_value; + ret <<= 12; + return ret; +} + + +#endif // __CONSISTENT_DEBUG_HELPER_FNS__ diff --git a/drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_registry.h b/drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_registry.h new file mode 100644 index 0000000..138bb64 --- /dev/null +++ b/drivers/apple/consistent_debug/include/consistent_debug/consistent_debug_registry.h @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_CONSISTENT_DEBUG_REGISTRY_H +#define __DRIVERS_CONSISTENT_DEBUG_REGISTRY_H + + +// Consistent Debugging Root Structure Definition. +// See documentation at + + +// Debug Root Pointer Definitions: +// +// The Debug Root Pointer is used to find the location of the +// Debug Registry. It is currently implemented as a 32-bit PMGR +// scratch register that's reset on boot. + + + +// Debug Root Pointer Scratch Register Format: +// We have 64 bit addresses but a 32-bit scratch register, so +// do a bit of encoding to at least futureproof the use of a +// 32-bit register to the foreseeable future. +// +// Bit: ---31..30-|---- 29...0 ----- +// | TYPE | ADDR | +// ------------------------- +// +// TYPE: +// 0b00: ADDR is (physical address >> 12). This is good as +// long as our physical address space is within 42 bits, +// which like it will be true for a while. +// +// -other-: Reserved for future encodings. Expected use +// cases are for larger-sized granularity, or indexing off +// another known location like SRAM_BASE/SDRAM_BASE. +// +// Helper functions for producing these encodings are in +// consistent_debug_helper_fns.h + + +// Debug Registry Definitions: + +typedef enum { + DBG_PROCESSOR_AP = 1, + DBG_COPROCESSOR_ANS, + DBG_COPROCESSOR_SEP, + DBG_COPROCESSOR_SIO, + DBG_COPROCESSOR_ISP, + DBG_COPROCESSOR_OSCAR, + DBG_NUM_PROCESSORS +} dbg_processor_t; + +#define DEBUG_REGISTRY_MAX_RECORDS 512 + +#define DEBUG_RECORD_ID_LONG(a, b,c ,d, e, f, g, h) ( ((unsigned long long)((((h) << 24) & 0xFF000000) | (((g) << 16) & 0x00FF0000) | (((f) << 8) & 0x0000FF00) | ((e) & 0x00FF)) << 32) | \ + (unsigned long long)((((d) << 24) & 0xFF000000) | (((c) << 16) & 0x00FF0000) | (((b) << 8) & 0x0000FF00) | ((a) & 0x00FF)) ) +#define DEBUG_RECORD_ID_SHORT(a,b,c,d) DEBUG_RECORD_ID_LONG(a,b,c,d,0,0,0,0) +/* The Debug Registry lives near the top of SDRAM in a reserved + region. Its size is fixed at compile time and defined as + DEBUG_REGISTRY_MAX_RECORDS. This region holds pointers to + where the actual structures are. This allows more costly data + structures to be allocated at runtime and as needed. + + iOS and iBoot will provide APIs for registering records here. + Note that ONLY the AP will be allowed to register entries in + the Consistent Debug Registry. An IOP that wishes to have an + entry have an AP-side handler reserve a record. Once a record + is reserved, anyone may own it. + + * |---------------------------| + * | record_id | + * |---------------------------| + * | length | + * |---------------------------| + * | physaddr | + * |---------------------------| + * | next_record_id | + ....... + */ +typedef struct { + uint64_t record_id; // 64-bit unique ID identifying the record + uint64_t length; // Length of the payload + uint64_t physaddr; // System physical address of entry +} dbg_record_header_t; + +// Life cycle of a record_id: +// Starts out as DbgIdUnusedEntry. When reserved, it becomes +// kDbgIdReservedEntry. Once the correct address/length has been +// filled in, the owner can write the appropriate record ID. +// +// When freeing an entry, the agent should write +// kDbgIdFreeReqEntry to the field. Then, the external reader is +// expected to notice the record_id change and stop using this +// debug region. After the reader no longer is using these +// resources, it will write in kDbgIdFreeAckEntry. Then, the +// consistent debug driver will respond by zeroing the entry. + +#define kDbgIdUnusedEntry 0x0ULL +#define kDbgIdReservedEntry DEBUG_RECORD_ID_LONG('R','E','S','E','R','V','E', 'D') +#define kDbgIdFreeReqEntry DEBUG_RECORD_ID_LONG('F','R','E','E','-','R','E','Q') +#define kDbgIdFreeAckEntry DEBUG_RECORD_ID_LONG('F','R','E','E','-','A','C','K') + + +#define kDbgIdTopLevelHeader DEBUG_RECORD_ID_SHORT('D','B','G','H') + +/* + The first entry in the debug area is a "top level header", + which has a different layout than following records. It + describes the size and number of records. Although these + parameters are derivable by looking up the top level + header's magic record ID, this approach lends to more robust + code run-time parsing of the debug area that doesn't have to + be constantly updated for minor format changes. +*/ +typedef struct { + uint64_t record_id; // = kDbgIdTopLevelHeader + uint32_t num_records; // = DEBUG_REGISTRY_MAX_RECORDS + uint32_t record_size_bytes; // = sizeof(dbg_record_header_t) +} dbg_top_level_header_t; + + +/* + * Shared Memory Console Descriptors: + * Record ID: One per SHMConsole + */ + +#define DbgIdConsoleHeaderForIOP(which_dbg_processor, which_num) (DEBUG_RECORD_ID_LONG('C','O','N',0,0,0,which_dbg_processor,which_num)) + +#define kDbgIdConsoleHeaderAP DbgIdConsoleHeaderForIOP(DBG_PROCESSOR_AP, 0) +#define kDbgIdConsoleHeaderANS DbgIdConsoleHeaderForIOP(DBG_COPROCESSOR_ANS, 0) +#define kDbgIdConsoleHeaderSIO DbgIdConsoleHeaderForIOP(DBG_COPROCESSOR_SIO, 0) +#define kDbgIdConsoleHeaderSEP DbgIdConsoleHeaderForIOP(DBG_COPROCESSOR_SEP, 0) +#define kDbgIdConsoleHeaderISP DbgIdConsoleHeaderForIOP(DBG_COPROCESSOR_ISP, 0) +#define kDbgIdConsoleHeaderOscar DbgIdConsoleHeaderForIOP(DBG_COPROCESSOR_OSCAR, 0) + + +/* + * Coprocessor Progress Reports + * + * The CPR is a standardized structure across all coprocessors + * that gives brief info as to its state. + * + * Each coprocessor is responsible for updating its state. The + ring buffer is supposed to wrap around when full, ensuring + that the current state is always present. + +*/ + +#define DbgIdCPRHeaderForIOP(which_dbg_processor, which_num) (DEBUG_RECORD_ID_LONG('C','P','R',0,0,0,which_dbg_processor,which_num)) + +#define kDbgIdCPRHeaderBase DbgIdCPRHeaderForIOP(0, 0) +#define kDbgIdCPRHeaderAP DbgIdCPRHeaderForIOP(DBG_PROCESSOR_AP, 0) +#define kDbgIdCPRHeaderANS DbgIdCPRHeaderForIOP(DBG_COPROCESSOR_ANS, 0) +#define kDbgIdCPRHeaderSIO DbgIdCPRHeaderForIOP(DBG_COPROCESSOR_SIO, 0) +#define kDbgIdCPRHeaderSEP DbgIdCPRHeaderForIOP(DBG_COPROCESSOR_SEP, 0) +#define kDbgIdCPRHeaderISP DbgIdCPRHeaderForIOP(DBG_COPROCESSOR_ISP, 0) +#define kDbgIdCPRHeaderOscar DbgIdCPRHeaderForIOP(DBG_COPROCESSOR_OSCAR, 0) + +typedef enum { + DBG_CPR_STATE_POWEROFF, + DBG_CPR_STATE_BOOTING, // In the bootloader + DBG_CPR_STATE_RUNNING, // Somewhere in the kernel + DBG_CPR_STATE_QUIESCING, + DBG_CPR_STATE_ASLEEP, + DBG_CPR_STATE_CRASHED // Panicked / Crashed +} cp_state_t; + +typedef enum { + DBG_CPR_AP_PANICKED_IN_IBOOT, + DBG_CPR_AP_PANICKED_IN_DARWIN, +} cp_ap_crash_arg_t; + +typedef struct { + uint64_t timestamp; + uint32_t cp_state; // One of the cp_state_t enumerations + uint32_t cp_state_arg; // IOP-defined supplemental value +} dbg_cpr_state_entry_t; + +#define CPR_MAX_STATE_ENTRIES 16 // Arbitrary value + +// This second-level struct should be what the Debug Registry record (e.g. kDbgIdCPRHeaderANS) points to. +typedef struct { + uint32_t rdptr; + uint32_t wrptr; + uint32_t num_cp_state_entries; + uint32_t checksum; + dbg_cpr_state_entry_t cp_state_entries[CPR_MAX_STATE_ENTRIES]; +} dbg_cpr_t; + +/* + * Panic String Locator + * + * Points to the location / length of the panic string. +*/ + +#define DbgIdPanicHeaderForIOP(which_dbg_processor, which_num) (DEBUG_RECORD_ID_LONG('P','A','N','I','C',0,which_dbg_processor,which_num)) + + +#define kDbgIdPanicHeaderAP DbgIdPanicHeaderForIOP(DBG_PROCESSOR_AP, 0) + + +/* + * Memory Map Hints: + * + * Useful regions (such as those defined in platform/memmap.h) start with magic "MAP" + * +*/ + +// XNU's PANIC_BASE will be recorded here. This can allow Astris to read the kernel's +#define kDbgIdXNUPanicRegion (DEBUG_RECORD_ID_LONG('M','A','P','P','A','N','I','C')) +// XNU's physical load address for Astris's use in coredumps +#define kDbgIdXNUKernelRegion (DEBUG_RECORD_ID_LONG('M','A','P','K','E','R','N','L')) + +typedef struct { + dbg_top_level_header_t top_level_header; + dbg_record_header_t records[DEBUG_REGISTRY_MAX_RECORDS]; + + // Stuff the AP's Progress Report buffer at the end of this + // structure. It's currently the only processor that doesn't + // have some easier form of persistent memory that survives the + // iBoot->iOS handoff (e.g. ANS has its private heap) + dbg_cpr_t ap_cpr_region; +} dbg_registry_t; + + +#endif + diff --git a/drivers/apple/consistent_debug/rules.mk b/drivers/apple/consistent_debug/rules.mk new file mode 100644 index 0000000..bc1bc4e --- /dev/null +++ b/drivers/apple/consistent_debug/rules.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2011-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_CONSISTENT_DBG=1 + +MODULES += \ + drivers/apple/consistent_debug + +ALL_OBJS += \ + $(LOCAL_DIR)/consistent_debug.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/csi/csi.c b/drivers/apple/csi/csi.c new file mode 100644 index 0000000..cacc91b --- /dev/null +++ b/drivers/apple/csi/csi.c @@ -0,0 +1,747 @@ +/* + * Copyright (C) 2011-2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" + +// protocol files +#include + +#include "endpoints/management_ep.h" +#include "endpoints/syslog_ep.h" +#include "endpoints/console_ep.h" +#include "endpoints/crashlog_ep.h" + +#include +#include +#include + +// XXX addresses the need for a common copy of this file +#include "queue.h" + + +static const MailboxEndpointConfig endpoint_config[] = MAILBOX_ENDPOINT_INITIALIZERS; + +#define MAILBOX_ENDPOINT_INITIALIZER_COUNT (int)(sizeof(endpoint_config)/sizeof(*endpoint_config)) + +#define EP_QUEUE_ADVANCE(_index, _size) ((_index) = ((((_index) + 1) >= _size) ? 0 : ((_index) + 1))) + + +// A simple mechanism to put a governor on potentially high volume log scenarios +#define LOG_GOV_PERIOD_USEC 5000000 + +typedef struct { + int occ_count; + u_int64_t last_log; +} log_governor_t; + + +typedef struct { + bool registered; + csi_coproc_t coproc; + uint32_t index; + const char *name; + uint32_t rcv_queue_size; + msg_payload_t *rcv_queue; + uint32_t next_in; + uint32_t next_out; + uint32_t sm_alignment; + struct task_event *rcv_not_empty_event; +} endpoint_desc_t; + + +typedef enum { + COPROC_STATE_RESET = 0, + COPROC_STATE_ERROR_FW, + COPROC_STATE_ERROR_STARTING, + COPROC_STATE_RUNNING, + COPROC_STATE_STOPPED, +} coproc_state_t; + +typedef struct { + csi_coproc_t coproc; + coproc_state_t state; + coproc_feature_t feature; + uint32_t send_timeout; + uint32_t endpoint_count; + endpoint_desc_t endpoints[CSI_MAX_ENDPOINTS]; + fw_desc_t fw_desc; + struct task_event power_state_event; + log_governor_t gov_ep_queue_ovflw; + log_governor_t gov_ep_not_reg; +} csi_desc_t; + +static csi_desc_t *csi_descs[CSI_COPROC_MAX] = {NULL}; + + +// +// Private functions +// + +static endpoint_desc_t *find_endpoint(csi_coproc_t which_coproc, ipc_endpoint_t which_ep); + +static int inbox_not_empty_task(void *arg); + +static void message_dispatcher(endpoint_desc_t *ep, msg_payload_t msg_payload); + +static void *allocate_shared_memory(uint32_t capacity, uint32_t alignment); + +static bool check_log_gov(log_governor_t *gov, csi_coproc_t which_coproc); + + +// +// csi_init +// +csi_status_t +csi_init (csi_coproc_t which_coproc) +{ + int j; + csi_desc_t *csi; + csi_status_t status; + endpoint_desc_t *next_ep; + + if (which_coproc >= CSI_COPROC_MAX) { + return CSI_STATUS_UNSUPPORTED; + } + + // enforce single instance + REQUIRE(csi_descs[which_coproc]==NULL); + csi_descs[which_coproc] = malloc(sizeof(csi_desc_t)); + REQUIRE(csi_descs[which_coproc]!=NULL); + + csi = csi_descs[which_coproc]; + + csi->coproc = which_coproc; + csi->state = COPROC_STATE_RESET; + csi->send_timeout = CSI_SEND_MESSAGE_TIMEOUT; + + csi->gov_ep_queue_ovflw.occ_count = 0; + csi->gov_ep_not_reg.occ_count = 0; + + csi->feature = COPROC_FEATURE_NONE; + + // Create all endpoint structures - all are inactive until registered. + + csi->endpoint_count = 0; + next_ep = csi->endpoints; + + for (j=CSI_MAX_ENDPOINTS; --j>=0;) { + next_ep->registered = false; + next_ep->coproc = csi->coproc; + next_ep->index = 0; + next_ep->name = "none"; + next_ep->rcv_queue_size = 0; + next_ep->rcv_queue = NULL; + next_ep->next_in = 0; + next_ep->next_out = 0; + next_ep->rcv_not_empty_event = NULL; + next_ep++; + } + + next_ep = csi->endpoints; + + for (j=0; (jendpoint_countindex = endpoint_config[j].index; + next_ep->name = endpoint_config[j].name; + next_ep->rcv_queue_size = endpoint_config[j].rcv_queue_size; + next_ep->rcv_queue = malloc(sizeof(*next_ep->rcv_queue) * endpoint_config[j].rcv_queue_size); + REQUIRE(next_ep->rcv_queue!=NULL); + next_ep->next_in = 0; + next_ep->next_out = ~(0); + + next_ep++; + csi->endpoint_count++; + } + } + + // create built-in endpoints + bi_ep_mgmt_create(csi->coproc, &(csi->power_state_event)); + bi_ep_crashlog_create(csi->coproc); + bi_ep_console_create(csi->coproc); + bi_ep_syslog_create(csi->coproc); + + // Find the firmware, prep it, start the coprocessor. + if (CSI_COPROC_ANS == which_coproc) { + // region is provided by iBoot + csi->fw_desc.region_base = ASP_BASE; + csi->fw_desc.region_size = (uint32_t)(ASP_SIZE); + } else { + // Allocate region for all other corpoc + // XXX: what size is needed - to be added later when/if other coproc are supported. + csi->fw_desc.region_base = 0x00; + csi->fw_desc.region_size = 0x00; + + return CSI_STATUS_UNSUPPORTED; + } + + status = fw_fixup_and_relocate(csi->coproc, &csi->fw_desc); + if (status != CSI_STATUS_OK) { + CSI_LOG(CRITICAL, which_coproc, "fw_fixup_and_relocate() error (%s)\n", CSI_STATUS_STR(status)); + csi->state = COPROC_STATE_ERROR_FW; + return status; + } + + status = csi_start (which_coproc); + if (status != CSI_STATUS_OK) { + return status; + } + + // create the power state event + event_init(&(csi->power_state_event), EVENT_FLAG_AUTO_UNSIGNAL, false); + + return CSI_STATUS_OK; +} + + +csi_status_t +csi_start (csi_coproc_t which_coproc) +{ + csi_desc_t *csi; + addr_t remap_base; + uint64_t remap_size; + int status; + + csi = csi_descs[which_coproc]; + + remap_base = (const addr_t)csi->fw_desc.region_base; + remap_size = (const uint64_t)csi->fw_desc.region_size; + + status = akf_start(KFW(csi->coproc), remap_base, remap_size); + if (status != 0) { + CSI_LOG(CRITICAL, which_coproc, "akf_start() error: %d\n", status); + csi->state = COPROC_STATE_ERROR_STARTING; + return CSI_STATUS_ERROR; + } + csi_clr_feature (which_coproc, COPROC_FEATURE_SHUTDOWN_IN_PROGRESS); + + CSI_LOG(DEBUG_SPEW, which_coproc, "coproc started: remap base = %p, size = 0x%llx (feature=%x)\n", (void *)remap_base, remap_size, csi_get_feature(which_coproc)); + csi->state = COPROC_STATE_RUNNING; + + // start the message reading task + task_start(task_create("csi inbox_not_empty_task", inbox_not_empty_task, (void*)csi, kTaskStackSize_inbox_not_empty)); + + task_yield(); // give them a chance to run + + return CSI_STATUS_OK; +} + + +csi_status_t +csi_panic_recover (csi_coproc_t which_coproc) +{ + csi_desc_t *csi; + csi_status_t status; + + csi = csi_descs[which_coproc]; + + // stop the AKF to reset it. + csi_stop (which_coproc); + + // destroy all the allocated shared memory + // force a power state change to off. + handle_power_state_ack (mgmt_descs[which_coproc], CSI_PS_OFF); + + clock_reset_device(CLK_ANS); + + // give a chance to all other task to terminate + task_yield(); + + // reset the memory + status = fw_fixup_and_relocate (csi->coproc, &csi->fw_desc); + if (status != CSI_STATUS_OK) { + CSI_LOG(CRITICAL, which_coproc, "panic recovery failed: fw_fixup_and_relocate() error (%s)\n", CSI_STATUS_STR(status)); + csi->state = COPROC_STATE_ERROR_FW; + return status; + } + + // restart the AKF + return csi_start (which_coproc); +} + + +csi_status_t +csi_late_init (void) { +#if APPLICATION_IBOOT + const char *boot_args; + char *arg_str; + uint32_t verbosity; + + verbosity = 9999; + + boot_args = env_get("boot-args"); + + if (boot_args != NULL) { + arg_str = strstr(boot_args, "csi_syslog_verbosity="); + if (arg_str != NULL) { + verbosity = arg_str[strlen("csi_syslog_verbosity=")] - '0'; + } + } + + for (int j = 0; j < CSI_COPROC_MAX; j++) { + bi_ep_syslog_verbosity(j, verbosity); + } +#endif + + return CSI_STATUS_OK; +} + +csi_status_t +csi_stop (csi_coproc_t which_coproc) +{ + csi_desc_t *csi; + + csi = csi_descs[which_coproc]; + + akf_stop (KFW(csi->coproc)); + csi->state = COPROC_STATE_STOPPED; + + return CSI_STATUS_OK; +} + + +csi_status_t +csi_quiesce (enum boot_target target) +{ + csi_status_t status = CSI_STATUS_OK; + + for (int j = 0; j < CSI_COPROC_MAX; j++) { + csi_desc_t *csi = csi_descs[j]; + + if (NULL != csi) { + if (csi->state == COPROC_STATE_RUNNING) { + // put the coproc in suspend to ram for all state + status = hibernate_iop (csi->coproc); + } + } + } + + return status; +} + + +csi_status_t +request_iop_power_state (csi_coproc_t which_coproc, csi_power_state_t ps) +{ + csi_desc_t *csi; + + csi = csi_descs[which_coproc]; + + // if the power state event was previously signaled (panic recovery for example) + // unsignal it was we need to wait for a new transition + event_unsignal (&(csi->power_state_event)); + + // Request the IOP to transition to the specified power state + // power message are always send thru the management channel + bi_ep_mgmt_send_ps (which_coproc, ps); + + // Wait for the acknowledge message. + event_wait (&(csi->power_state_event)); + + // make sure the power state is the one we want + if (bi_ep_mgmt_get_power_state(csi->coproc) != ps) { + return CSI_STATUS_ERROR; + } + + return CSI_STATUS_OK; +} + + +csi_status_t +quiesce_iop (csi_coproc_t which_coproc) +{ + csi_desc_t *csi; + csi_status_t status; + + csi = csi_descs[which_coproc]; + + // Request the new power state + status = request_iop_power_state (which_coproc, CSI_PS_QUIESCE); + if (CSI_STATUS_OK != status) { + CSI_LOG(CRITICAL, csi->coproc, "Failed to quiesce\n"); + return CSI_STATUS_ERROR; + } + + CSI_LOG(CRITICAL, csi->coproc, "quiesced\n"); + + return CSI_STATUS_OK; +} + + +csi_status_t +hibernate_iop (csi_coproc_t which_coproc) +{ + csi_desc_t *csi; + csi_status_t status; + + csi = csi_descs[which_coproc]; + + // Request the new power state + csi_set_feature (which_coproc, COPROC_FEATURE_SHUTDOWN_IN_PROGRESS); + status = request_iop_power_state (which_coproc, CSI_PS_SLEEP); + if (CSI_STATUS_OK != status) { + CSI_LOG(CRITICAL, csi->coproc, "Failed to hibernate\n"); + return CSI_STATUS_ERROR; + } + + CSI_LOG(CRITICAL, csi->coproc, "in suspend to RAM\n"); + + // now turn off the iop + return csi_stop (which_coproc); +} + + +csi_status_t +set_send_timeout (csi_coproc_t which_coproc, uint32_t timeout) +{ + csi_desc_t *csi = csi_descs[which_coproc]; + + csi->send_timeout = timeout; + + return CSI_STATUS_OK; +} + +uint32_t +get_send_timeout (csi_coproc_t which_coproc) +{ + csi_desc_t *csi = csi_descs[which_coproc]; + + return csi->send_timeout; +} + + +csi_status_t +csi_set_feature (csi_coproc_t which_coproc, coproc_feature_t feature) +{ + csi_desc_t *csi = csi_descs[which_coproc]; + + csi->feature = feature; + + return CSI_STATUS_OK; +} + +coproc_feature_t +csi_get_feature (csi_coproc_t which_coproc) +{ + csi_desc_t *csi = csi_descs[which_coproc]; + + return csi->feature; +} + + +csi_status_t +csi_clr_feature (csi_coproc_t which_coproc, coproc_feature_t feature) +{ + csi_desc_t *csi = csi_descs[which_coproc]; + + csi->feature &= ~(feature); + + return CSI_STATUS_OK; +} + + +void +csi_info (csi_coproc_t which_coproc) +{ + fw_print_version (which_coproc, &(csi_descs[which_coproc]->fw_desc)); +} + +//////////////////////////////////////////////////////////////////////////////// +// allocate shared memory +// +static void * +allocate_shared_memory(uint32_t capacity, uint32_t alignment) +{ + uint32_t actual_capacity; + void *sm; + + // We always allocate page-aligned and with multiples of the page size for alignment + actual_capacity = roundup(capacity, PAGE_SIZE); + alignment = roundup(alignment, PAGE_SIZE); + + // allocate + sm = memalign(actual_capacity, alignment); + maybe_do_cache_operation(CACHE_CLEAN, sm, actual_capacity); + + return sm; +} + + +static void +free_shared_memory(void *sm) +{ + free(sm); +} + +static endpoint_desc_t * +find_endpoint(csi_coproc_t which_coproc, ipc_endpoint_t which_ep) +{ + int j; + csi_desc_t *this_csi; + endpoint_desc_t *next_ep; + + if (which_coproc < CSI_COPROC_MAX) { + this_csi = csi_descs[which_coproc]; + if (this_csi != NULL) { + next_ep = this_csi->endpoints; + for (j=this_csi->endpoint_count; --j>=0; next_ep++) { + if (next_ep->index == which_ep) { + return next_ep; + } + } + } + } + + return NULL; +} + + +//////////////////////////////////////////////////////////////////////////////// +// inbox_not_empty_task +// +// Wait for and dispatch incoming messages from the IOP. +// Get all the pending message in the mailbox and dispatch them to the appropriate +// endpoint. Message to non existent endpoint are silently discarded. +// +static int +inbox_not_empty_task(void *token) +{ + volatile csi_desc_t *csi; + int status; + msg_payload_t msg; + endpoint_desc_t *ep; + + REQUIRE (NULL != (csi = (csi_desc_t*)token)); + + if (csi->state != COPROC_STATE_RUNNING) { + CSI_LOG(CRITICAL, (csi_coproc_t)csi->coproc, "error: inbox_not_empty_task() coproc not running\n"); + return 1; + } + + // we should only be trying to read message when the AKF is running otherwise data abort can happen. + while (COPROC_STATE_RUNNING == csi->state) { + // check the coproc status every 100ms + while ((status = akf_recv_mbox(KFW(csi->coproc), &msg, 100000)) == 0) { + + // queue the message, the endpoint will ignore it if disabled. + ep = find_endpoint(csi->coproc, ipc_msg_get_endpoint(&msg)); + + if (ep) { + message_dispatcher(ep, (msg&IPC_MSG_PAYLOAD_MASK)); + } else { + CSI_LOG(CRITICAL, (csi_coproc_t)csi->coproc, "error: message received for unknown endpoint => message discarded (%d, 0x%llx)\n", ipc_msg_get_endpoint(&msg), msg); + } + } + } + + // coproc has stopped running, terminate task + return 0; +} + +static void +message_dispatcher(endpoint_desc_t *ep, msg_payload_t msg) +{ + // do some basic filtering before signaling + if (!ep->registered) { + if (check_log_gov(&csi_descs[ep->coproc]->gov_ep_not_reg, ep->coproc)) { + CSI_LOG(CRITICAL, ep->coproc, "error: %s endpoint not registered => message discarded\n", ep->name); + } + + } else { + + // add the message to the queue + + ep->rcv_queue[ep->next_in] = msg; + EP_QUEUE_ADVANCE(ep->next_in, ep->rcv_queue_size); + + // check for overflow. discard oldest message if it happens. + if (ep->next_in == ep->next_out) { + if (check_log_gov(&csi_descs[ep->coproc]->gov_ep_queue_ovflw, ep->coproc)) { + CSI_LOG(CRITICAL, ep->coproc, "error: %s endpoint queue overflow\n", ep->name); + } + EP_QUEUE_ADVANCE(ep->next_out, ep->rcv_queue_size); + } + + // if this was the first message move the _nextOut pointer to the newly received message + if ((uint32_t)~(0) == ep->next_out) { + ep->next_out = 0; + } + + // signal the endpoint that its rcv queue is not empty + REQUIRE(ep->rcv_not_empty_event!=NULL); + event_signal(ep->rcv_not_empty_event); + } +} + + +// endpoint support + +// NOTE: an unregister method could be added if necessary + +csi_status_t +csi_register_endpoint(csi_coproc_t which_coproc, uint32_t which_ep, struct task_event *event, void **return_token, const char **name) +{ + endpoint_desc_t *ep; + + ep = find_endpoint(which_coproc, (ipc_endpoint_t)which_ep); + + if (ep==NULL) { + CSI_LOG(CRITICAL, which_coproc, "csi_register_endpoint(): no knowledge of endpoint #%d\n", which_ep); + return CSI_STATUS_UNSUPPORTED; + } + + if (ep->registered) { + CSI_LOG(CRITICAL, which_coproc, "csi_register_endpoint(): %s endpoint already registered\n", ep->name); + return CSI_STATUS_ERROR; + } + + if (name != NULL) { + *name = ep->name; + } + + ep->rcv_not_empty_event = event; + ep->registered = true; + ep->sm_alignment = csi_descs[which_coproc]->fw_desc.alignment_req; + *return_token = (void*)ep; + + return CSI_STATUS_OK; +} + + +void * +csi_allocate_shared_memory(void *token, uint32_t capacity) +{ + endpoint_desc_t *ep = (endpoint_desc_t*)token; + void *sm; + + sm = allocate_shared_memory(capacity, ep->sm_alignment); + + return sm; +} + + +void +csi_free_shared_memory(void *sm) +{ + free_shared_memory (sm); + + // remove element from the list +} + + +csi_status_t +csi_receive_message(void *token, msg_payload_t *msg_payload) +{ + endpoint_desc_t *ep = (endpoint_desc_t*)token; + + REQUIRE(ep != NULL); + + if (!ep->registered) { + return CSI_STATUS_ERROR; + } + + // make sure we have a message available + if (((uint32_t)~(0) == ep->next_out) || (ep->next_out == ep->next_in)) { + return CSI_STATUS_UNAVAILABLE; + } + + // get the message from ep input queue and return it. + *msg_payload = ep->rcv_queue[ep->next_out]; + EP_QUEUE_ADVANCE(ep->next_out, ep->rcv_queue_size); + + return CSI_STATUS_OK; +} + + +csi_status_t +csi_send_message (void *token, msg_payload_t msg_payload) +{ + endpoint_desc_t *ep; + ipc_msg_t msg_out; + int status; + csi_desc_t *csi; + + REQUIRE(token != NULL); + + ep = (endpoint_desc_t*)token; + msg_out = (ipc_msg_t)msg_payload; + + if (!ep->registered) { + return CSI_STATUS_ERROR; + } + + // FixMe - some clients already put in the endpoint field - others expect it to be done for them + if ((msg_out & IPC_MSG_ENDPOINT_MASK) == 0) { + ipc_msg_set_endpoint(&msg_out, ep->index); + } + + if (ipc_msg_get_endpoint(&msg_out) != ep->index) { + return CSI_STATUS_ERROR; + } + + ipc_msg_set_endpoint(&msg_out, ep->index); + + csi = csi_descs[ep->coproc]; + + status = akf_send_mbox(KFW(ep->coproc), msg_out, csi->send_timeout); + if (-2 == status) { + // timeout + CSI_LOG(CRITICAL, ep->coproc, "csi_send_message(): failed to send message %llx in %dus, AKF hanged?\n", msg_payload, csi->send_timeout); + return CSI_STATUS_TIMEOUT; + } + // all other errors are non fatal + if (0 != status) { + return CSI_STATUS_ERROR; + } + return CSI_STATUS_OK; +} + + +static bool +check_log_gov(log_governor_t *gov, csi_coproc_t which_coproc) +{ + gov->occ_count++; + + if ((gov->occ_count == 1) || (timer_ticks_to_usecs(timer_get_ticks() - gov->last_log) >= LOG_GOV_PERIOD_USEC)) { + if (gov->occ_count > 2) { + CSI_LOG(CRITICAL, which_coproc, "WARNING: The condition logged below has occurred %d times\n", (gov->occ_count-1)); + } + gov->occ_count = 1; + gov->last_log = timer_get_ticks(); + return true; + } + + return false; +} + + +void maybe_do_cache_operation(int operation, void *address, u_int32_t length) +{ +#if WITH_NON_COHERENT_DMA + void *aligned_address; + u_int32_t aligned_length; + + aligned_address = (void*)((uintptr_t)address & ~(CPU_CACHELINE_SIZE-1)); + aligned_length = roundup((length + (address - aligned_address)), CPU_CACHELINE_SIZE); + + platform_cache_operation(operation, aligned_address, aligned_length); +#endif +} diff --git a/drivers/apple/csi/debug.c b/drivers/apple/csi/debug.c new file mode 100644 index 0000000..758e7a9 --- /dev/null +++ b/drivers/apple/csi/debug.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "csi_private.h" +#include "endpoints/management_ep.h" +#include "endpoints/syslog_ep.h" +#include "endpoints/console_ep.h" +#include "endpoints/crashlog_ep.h" + + +#if defined(WITH_MENU) && WITH_MENU + +static int csi_debug_main(int argc, struct cmd_arg *args); + +MENU_COMMAND_DEBUG(csi, csi_debug_main, "Test CSI driver", NULL); + +static void usage() { + printf("usage: csi ans| \n" + " info\n" + " crashlog|cl nmi|ml|mc\n" + " ping [count]\n" + " syslog|sl [1|0|on|off]\n" + " state|st\n" + " quiesce|qs\n" + " hibernate|hb\n" + " resume|rs\n" + " powerstate|ps [ps]\n" + " console ...\n" + " ... v \n" + " ... c \n" + " timebase|tb\n" + " stimeout|sto [timeout in us]\n"); +} + + +static inline uint64_t read_akf_timebase(uint64_t regs_base) +{ + uint32_t hi1 = rAKF_KIC_GLB_TIME_BASE_HI(regs_base); + uint32_t lo = rAKF_KIC_GLB_TIME_BASE_LO(regs_base); + uint32_t hi2 = rAKF_KIC_GLB_TIME_BASE_HI(regs_base); + return ((((uint64_t)hi2) << 32) | ((hi1!=hi2) ? rAKF_KIC_GLB_TIME_BASE_LO(regs_base) : lo)); +} + + +static int +csi_debug_main (int argc, struct cmd_arg *args) +{ + csi_coproc_t which_coproc; + const char *s; + csi_status_t status; + uint64_t akf_base_addr = 0; + + if (argc < 3) { + usage(); + return -1; + } + + // + // Find the targeted coproc + // + + s = args[1].str; + if (strnicmp(s, "ans", strlen(s)) == 0) { + which_coproc = CSI_COPROC_ANS; + akf_base_addr = ANS_AKF_BASE_ADDR; + } else if (strnicmp(s, "sep", strlen(s)) == 0) { + which_coproc = CSI_COPROC_SEP; +#if ASEP_AKF_BASE_ADDR + akf_base_addr = ASEP_AKF_BASE_ADDR; +#endif + } else if (strnicmp(s, "isp", strlen(s)) == 0) { + which_coproc = CSI_COPROC_ISP; +#if ISP_AKF_BASE_ADDR + akf_base_addr = ISP_AKF_BASE_ADDR; +#endif + } else if (strnicmp(s, "sio", strlen(s)) == 0) { + which_coproc = CSI_COPROC_SIO; +#if ASIO_AKF_BASE_ADDR + akf_base_addr = ASIO_AKF_BASE_ADDR; +#endif + } else { + printf("csi: %s unknown\n", s); + usage(); + return -1; + } + + if (akf_base_addr == 0) { + printf("csi: %s not supported\n", IOP_NAME(which_coproc)); + usage(); + return -1; + } + + // + // Parse command + // + + status = CSI_STATUS_OK; + s = args[2].str; + + // information + if (strnicmp(s, "info", strlen(s)) == 0) { + csi_info (which_coproc); + return 0; + } + + // crashlog + if ((strnicmp(s, "crashlog", strlen(s)) == 0) || (strcmp(s, "cl") == 0)) { + csi_crashlog_t cl; + + if (argc < 4) { + usage(); + return -1; + } + + s = args[3].str; + if (strnicmp(s, "nmi", strlen(s)) == 0) { + cl = CSI_CRASHLOG_TYPE_NMI; + } else if (strnicmp(s, "ml", strlen(s)) == 0) { + cl = CSI_CRASHLOG_TYPE_MSG_LOG; + } else if (strnicmp(s, "mc", strlen(s)) == 0) { + cl = CSI_CRASHLOG_TYPE_MSG_CRASH; + } else { + usage(); + return -1; + } + + printf("csi: force crashlog from %s iop\n", IOP_NAME(which_coproc)); + status = bi_ep_crashlog_force_event(which_coproc, cl); + + } + // ping + else if (strnicmp(s, "ping", strlen(s)) == 0) { + + int ping_count = 1; + + if (argc >= 4) { + ping_count = atoi(args[3].str); + if (ping_count<=0) { + ping_count = 1; + } + } + + status = bi_ep_mgmt_send_ping(which_coproc, ping_count); + + } + // syslog + else if ((strnicmp(s, "syslog", strlen(s)) == 0) || (strcmp(s, "sl") == 0)) { + + if (argc < 4) { + usage(); + return -1; + } + + status = bi_ep_syslog_verbosity(which_coproc, atoi(args[3].str)); + + } + // state + else if ((strnicmp(s, "state", strlen(s)) == 0) || (strcmp(s, "st") == 0)) { + + mgmt_state_t state = bi_ep_mgmt_get_state(which_coproc); + csi_power_state_t ps = bi_ep_mgmt_get_power_state(which_coproc); + + printf("csi: %s state - %s - ps=0x%x\n", IOP_NAME(which_coproc), COPROC_STATE(state), ps); + + } + // quiesce + else if ((strnicmp(s, "quiesce", strlen(s)) == 0) || (strcmp(s, "qs") == 0)) { + + status = quiesce_iop (which_coproc); + + } + // start + else if ((strnicmp(s, "hibernate", strlen(s)) == 0) || (strcmp(s, "hb") == 0)) { + + status = hibernate_iop (which_coproc); + + } + // start + else if ((strnicmp(s, "resume", strlen(s)) == 0) || (strcmp(s, "rs") == 0)) { + + // restart the IOP + status = csi_start (which_coproc); + + } + // powerstate + else if ((strnicmp(s, "powerstate", strlen(s)) == 0) || (strcmp(s, "ps") == 0)) { + + if (argc < 4) { + printf("powerstate requires a powerstate argument\n"); + return -1; + } + + csi_power_state_t ps = strtol(args[3].str, (char **)NULL, 0); + status = request_iop_power_state (which_coproc, ps); + + } + // console + else if (strnicmp(s, "console", strlen(s)) == 0) { + + if (argc != 5) { + usage(); + return -1; + } + + if (args[3].str[0] == 'v') { + status = bi_ep_console_set_verbosity(which_coproc, strtol(args[4].str, (char **)NULL, 0)); + } else if (args[3].str[0] == 'c') { + status = bi_ep_console_send_custom_cmd(which_coproc, strtol(args[4].str, (char **)NULL, 0)); + } else { + usage(); + return -1; + } + } + // timebase + else if ((strnicmp(s, "timebase", strlen(s)) == 0) || (strcmp(s, "tb") == 0)) { + + uint64_t tb_host_1, tb_host_2, tb_iop_1, tb_iop_2; + + tb_host_1 = timer_get_ticks(); + tb_iop_1 = read_akf_timebase(akf_base_addr); + tb_iop_2 = read_akf_timebase(akf_base_addr); + tb_host_2 = timer_get_ticks(); + + printf("csi: host vs %s timebase\n", IOP_NAME(which_coproc)); + printf("\thost:\t 0x%llx\n", tb_host_1); + printf("\tiop:\t 0x%llx (%llu)\n", tb_iop_1, (tb_iop_1-tb_host_1)); + printf("\tiop:\t 0x%llx (%llu)\n", tb_iop_2, (tb_iop_2-tb_iop_1)); + printf("\thost:\t 0x%llx (%llu)\n", tb_host_2, (tb_host_2-tb_iop_2)); + } + // send timeout + else if ((strnicmp(s, "stimeout", strlen(s)) == 0) || (strcmp(s, "sto") == 0)) { + + if (argc < 4) { + printf("current send timeout for %s: %uus\n", IOP_NAME(which_coproc), get_send_timeout(which_coproc)); + return 0; + } + + uint32_t timeout = strtol(args[3].str, (char **)NULL, 0); + if (0 == timeout) { + // the A7 express no timeout as a wait forever. + timeout = A7IOP_WAIT_FOREVER; + printf("csi: %s send timeout disabled (%u)\n", IOP_NAME(which_coproc), timeout); + } else { + printf("csi: setting %s send timeout to %uus\n", IOP_NAME(which_coproc), timeout); + } + + status = set_send_timeout (which_coproc, timeout); + } + // unknown command + else { + printf("unknown command %s\n", s); + usage(); + return -1; + } + + if (status != CSI_STATUS_OK) { + printf("csi %s %s - error reported: %s\n", IOP_NAME(which_coproc), args[2].str, CSI_STATUS_STR(status)); + } + + return 0; +} + +#endif // defined(WITH_MENU) && WITH_MENU diff --git a/drivers/apple/csi/endpoints/builtin.c b/drivers/apple/csi/endpoints/builtin.c new file mode 100644 index 0000000..1a7bfe4 --- /dev/null +++ b/drivers/apple/csi/endpoints/builtin.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" + +// +// Private Data +// + +static volatile csi_status_t last_error = CSI_STATUS_OK; + + +// +// bi_ep_send_message +// +// Send message for the built-in endpoint. If the IOP becomes unreachable +// at some point stop sending message and instead directly fails to avoid +// multiple timeout error. +// +csi_status_t +bi_ep_send_message (void *token, msg_payload_t msg_payload) +{ + csi_status_t status; + + // make sure the previous send was not a timeout + if (CSI_STATUS_OK != last_error) { + // the IOP is not responding, error out right away + return last_error; + } + + // send the message + status = csi_send_message (token, msg_payload); + if (CSI_STATUS_TIMEOUT == status) { + // the IOP is not responding, save the error status + last_error = CSI_STATUS_TIMEOUT; + } + + return status; +} diff --git a/drivers/apple/csi/endpoints/console_ep.c b/drivers/apple/csi/endpoints/console_ep.c new file mode 100644 index 0000000..6cdea25 --- /dev/null +++ b/drivers/apple/csi/endpoints/console_ep.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" +#include "endpoints/console_ep.h" + +#include +#include +#include + + +// +// Global Data +// + +static ep_console_desc_t *console_descs[CSI_COPROC_MAX] = {NULL}; + +// +// Private functions +// + +int ep_console_task (void *arg); +void console_msg_handler (ep_console_desc_t *console, msg_payload_t msg); + + +// +// bi_ep_console_create +// +void +bi_ep_console_create (csi_coproc_t which_coproc) +{ + // enforce single instance + REQUIRE(console_descs[which_coproc]==NULL); + console_descs[which_coproc] = malloc(sizeof(ep_console_desc_t)); + REQUIRE(console_descs[which_coproc]!=NULL); + + console_descs[which_coproc]->coproc = which_coproc; + + task_start(task_create("csi ep console", ep_console_task, console_descs[which_coproc], kTaskStackSize_endpoints)); +} + + +csi_status_t +console_quiesce (csi_coproc_t which_coproc, csi_power_state_t ps) +{ + ep_console_desc_t *console = console_descs[which_coproc]; + + // free the sahred memory + if (!(ps & CSI_PS_SHARED_PRESERVED) && (NULL != console->buffers)) { + csi_free_shared_memory(console->buffers); + console->buffers = NULL; + console->allocated = 0; + } + + return CSI_STATUS_OK; +} + + +// +// bi_ep_console_send_custom_cmd +// +csi_status_t +bi_ep_console_send_custom_cmd (csi_coproc_t which_coproc, uint32_t payload) +{ + ep_console_desc_t *console; + ipc_msg_t resp; + + console = console_descs[which_coproc]; + + if (console == NULL) { + return CSI_STATUS_UNAVAILABLE; + } + + ipc_console_create_custom_cmd(&resp, payload); + + return bi_ep_send_message (console->csi_token, resp); +} + + +// +// bi_ep_console_set_verbosity +// +csi_status_t +bi_ep_console_set_verbosity (csi_coproc_t which_coproc, uint32_t verbosity) +{ + ep_console_desc_t *console; + ipc_msg_t resp; + + console = console_descs[which_coproc]; + + if (console == NULL) { + return CSI_STATUS_UNAVAILABLE; + } + + console->verbosity = verbosity; + ipc_console_create_flow_enable_cmd(&resp, console->verbosity); + + return bi_ep_send_message (console->csi_token, resp); +} + + +// +// Console Message handler +// + +int +ep_console_task (void *arg) +{ + csi_status_t result; + msg_payload_t rcv_msg; + + ep_console_desc_t *console = (ep_console_desc_t*)arg; + + event_init(&console->msg_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + result = csi_register_endpoint(console->coproc, IPC_ENDPOINT_BUILT_IN_CONSOLE, &console->msg_event, &console->csi_token, &console->name); + REQUIRE(result==CSI_STATUS_OK); + + console->verbosity = 1; + console->buffers = NULL; + console->allocated = 0; + console->scratch = malloc(CONSOLE_BUFFER_SIZE+1); + REQUIRE(console->scratch!=NULL); + + for (;;) { + event_wait(&console->msg_event); + + // empty the rcv queue + while (csi_receive_message(console->csi_token, &rcv_msg) == CSI_STATUS_OK) { + console_msg_handler(console, rcv_msg); + } + } + + return 0; +} + + +void +console_msg_handler (ep_console_desc_t *console, msg_payload_t msg) +{ + uint64_t paddr; + ipc_msg_t resp; + uint32_t cmd; + uint32_t rd_off; + uint32_t wr_off; + uint32_t size; + console_buffer_t *buffer_desc; + csi_status_t status; + + // the console endpoint use the reserved 2 bits of the buffer message to encode commands + // decode the command and respond to it + cmd = ipc_msg_extract(msg, IPC_MSG_BUFF_MSG_FLAG_RV_LEN, IPC_MSG_BUFF_MSG_FLAG_RV_POS); + + switch (cmd) { + + case REQUEST_NEW_BUFFER: + // allocate a console buffer of the requested size. + console->allocated = ipc_buff_msg_get_size(msg); + console->buffers = csi_allocate_shared_memory(console->csi_token, console->allocated); + REQUIRE(console->buffers!=NULL); + paddr = mem_static_map_physical((uintptr_t)console->buffers); + + // send the new buffer response back to the IOP + ipc_buff_create_msg(&resp, paddr, console->allocated); + resp |= ipc_msg_set(HERE_IS_A_NEW_BUFFER, IPC_MSG_BUFF_MSG_FLAG_RV_LEN, IPC_MSG_BUFF_MSG_FLAG_RV_POS); + status = bi_ep_send_message (console->csi_token, resp); + if (CSI_STATUS_OK != status) { + CSI_EP_LOG(CRITICAL, console->coproc, console->name, "unable to reply to REQUEST_NEW_BUFFER: %x\n", status); + break; + } + + // this transaction occurs when the console endpoint is initially up and ready + // and so is an appropriate time to communicate console verbosity to the IOP + ipc_console_create_flow_enable_cmd(&resp, console->verbosity); + status = bi_ep_send_message (console->csi_token, resp); + if (CSI_STATUS_OK != status) { + CSI_EP_LOG(CRITICAL, console->coproc, console->name, "unable to send console verbosity: %x\n", status); + } + break; + + case OUTPUT_BUFFER: + buffer_desc = &((console_buffer_t*)(console->buffers))[ipc_console_iocmd_get_channel(&msg)]; + + rd_off = ipc_console_iocmd_get_rdptr(&msg); + wr_off = ipc_console_iocmd_get_wrptr(&msg); + + if (rd_off<=wr_off) { + size = wr_off - rd_off; + REQUIRE(size<=CONSOLE_BUFFER_SIZE); + maybe_do_cache_operation(CACHE_INVALIDATE, &buffer_desc->buffer[rd_off], size); + memcpy(console->scratch, &buffer_desc->buffer[rd_off], size); + } else { + size = CONSOLE_BUFFER_SIZE - rd_off; + REQUIRE((size+wr_off)<=CONSOLE_BUFFER_SIZE); + maybe_do_cache_operation(CACHE_INVALIDATE, &buffer_desc->buffer[rd_off], size); + memcpy(console->scratch, &buffer_desc->buffer[rd_off], size); + maybe_do_cache_operation(CACHE_INVALIDATE, buffer_desc->buffer, wr_off); + memcpy((console->scratch+size), buffer_desc->buffer, wr_off); + size += wr_off; + } + console->scratch[size] = '\0'; + + CSI_EP_LOG(CONSOLE, console->coproc, console->name, "%s\n", console->scratch); + + // only send message if the other side is not shutting down. Otherwise this + // might create a lock up in suspend to RAM situation. + if (!csi_is_shutdown_in_progress(console->coproc)) { + ipc_console_create_iocmd(&resp, DONE_WITH_BUFFER, ipc_console_iocmd_get_channel(&msg), wr_off, wr_off); + status = bi_ep_send_message (console->csi_token, resp); + } + break; + + case BUFFER_OVERFLOWED: + CSI_EP_LOG(CONSOLE, console->coproc, console->name, "Console buffer overflow - message truncated\n"); + break; + + default: + CSI_EP_LOG(CRITICAL, console->coproc, console->name, "unimplemented console command: %x\n", cmd); + break; + } +} diff --git a/drivers/apple/csi/endpoints/crashlog_ep.c b/drivers/apple/csi/endpoints/crashlog_ep.c new file mode 100644 index 0000000..7b4b357 --- /dev/null +++ b/drivers/apple/csi/endpoints/crashlog_ep.c @@ -0,0 +1,666 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" +#include "endpoints/crashlog_ep.h" + +#include +#include +#include + + +// +// Global Data +// + +static ep_crashlog_desc_t *crashlog_descs[CSI_COPROC_MAX] = {NULL}; + +// +// Private functions +// + +int ep_crashlog_task (void *arg); +void crashlog_msg_handler (ep_crashlog_desc_t *clog, msg_payload_t msg); + +csi_status_t cl_print (ep_crashlog_desc_t *clog); +void cl_print_register_frame (CrashLogDataHeader_t *section); +void cl_print_os_info (CrashLogDataHeader_t *section); +void cl_print_string (CrashLogDataHeader_t *section); +void cl_print_mailbox (CrashLogDataHeader_t *section); +void cl_print_call_stack (CrashLogDataHeader_t *section); + +static const char* get_signature_string (CrashLogSignature_t sig); + + +// +// bi_ep_crashlog_create +// +void bi_ep_crashlog_create (csi_coproc_t which_coproc) +{ + // enforce single instance + REQUIRE(crashlog_descs[which_coproc]==NULL); + crashlog_descs[which_coproc] = malloc(sizeof(ep_crashlog_desc_t)); + REQUIRE(crashlog_descs[which_coproc]!=NULL); + + crashlog_descs[which_coproc]->coproc = which_coproc; + + task_start(task_create("csi ep crashlog", ep_crashlog_task, crashlog_descs[which_coproc], kTaskStackSize_endpoints)); +} + + +csi_status_t +crashlog_quiesce (csi_coproc_t which_coproc, csi_power_state_t ps) +{ + ep_crashlog_desc_t *clog = crashlog_descs[which_coproc]; + + // free all shared memory if we are not preserving it + if (!(ps & CSI_PS_SHARED_PRESERVED) && (NULL != clog->buffer)) { + csi_free_shared_memory(clog->buffer); + clog->buffer = NULL; + clog->allocated = 0; + } + + return CSI_STATUS_OK; +} + + +// +// bi_ep_crashlog_force_event +// +// force a crashlog generation through various means +// +csi_status_t +bi_ep_crashlog_force_event (csi_coproc_t which_coproc, csi_crashlog_t crashlog_type) +{ + if (crashlog_descs[which_coproc]==NULL) { + return CSI_STATUS_UNAVAILABLE; + } + + switch (crashlog_type) { + default: + return CSI_STATUS_ERROR; + + case CSI_CRASHLOG_TYPE_NMI: + akf_send_nmi(KFW(which_coproc)); + break; + + case CSI_CRASHLOG_TYPE_MSG_CRASH: + case CSI_CRASHLOG_TYPE_MSG_LOG: + return bi_ep_send_message (crashlog_descs[which_coproc]->csi_token, (msg_payload_t)((crashlog_type==CSI_CRASHLOG_TYPE_MSG_CRASH) ? CL_NMI_MSG_CRASH : CL_NMI_MSG_LOG)); + break; + } + + return CSI_STATUS_OK; +} + + +// +// Crashlog Message Handler +// + +int +ep_crashlog_task(void *arg) +{ + csi_status_t result; + msg_payload_t rcv_msg; + + ep_crashlog_desc_t *clog = (ep_crashlog_desc_t*)arg; + + event_init(&clog->msg_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + result = csi_register_endpoint(clog->coproc, IPC_ENDPOINT_BUILT_IN_CRASHLOG, &clog->msg_event, &clog->csi_token, &clog->name); + REQUIRE(result==CSI_STATUS_OK); + + clog->buffer = NULL; + clog->allocated = 0; + + for (;;) { + event_wait(&clog->msg_event); + + // empty the rcv queue + while(csi_receive_message(clog->csi_token, &rcv_msg) == CSI_STATUS_OK) { + crashlog_msg_handler(clog, rcv_msg); + } + } + + return 0; +} + + +// +// crashlog_msg_handler +// +// handle an asynchronous message from the coproc +// +// All message are using the buffer protocol. +// If a zero address is received this is a shared buffer allocation request and a new buffer +// physical address is returned. +// Otherwise this is interpreted as a crash log and it is displayed on the screen/saved for +// future use as appropriate +// +void +crashlog_msg_handler (ep_crashlog_desc_t *clog, msg_payload_t msg) +{ + uint64_t paddr; + ipc_msg_t resp; + csi_status_t status; + + // the first message is a buffer request, identified by a NULL address in the upper portion + // of the payload + if (ipc_buff_msg_get_address(msg) == 0x00) { + + // allocate a console buffer of the requested size. + clog->allocated = ipc_buff_msg_get_size(msg); + clog->buffer = csi_allocate_shared_memory(clog->csi_token, clog->allocated); + REQUIRE(clog->buffer!=NULL); + paddr = mem_static_map_physical((uintptr_t)clog->buffer); + CSI_EP_LOG(DEBUG_SPEW, clog->coproc, clog->name, "buffer request of size %u bytes, allocated @ physical 0x%llx (AP %p)\n", + clog->allocated, paddr, clog->buffer); + + // send the response back to the IOP + ipc_buff_create_msg(&resp, paddr, clog->allocated); + status = bi_ep_send_message (clog->csi_token, resp); + if (CSI_STATUS_OK != status) { + + } + + } else { + // A crash log has been received, decode it + maybe_do_cache_operation(CACHE_INVALIDATE, clog->buffer, clog->allocated); + status = cl_print(clog); + if (CSI_STATUS_PANIC_RECOVER == status) { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "Recoverable panic, reseting\n"); + status = csi_panic_recover (clog->coproc); + } + else if (status != CSI_STATUS_OK) { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "data is corrupt or unrecognizable (%x)\n", status); + } + } +} + + +// +// *** Crashlog Decoder *** +// + +#define RUN_IF_COMPATIBLE(version, version_expected, expr) \ + do { \ + if(LOG_MAJOR_VERSION(version) == LOG_MAJOR_VERSION(version_expected)) \ + expr; \ + else \ + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "Not executing " #expr " because version %u.%u is not compatible with expected version %u.%u\n", \ + LOG_PRINT_VERSION(version), LOG_PRINT_VERSION(version_expected)); \ + } while(0) + +static const char* +get_exc_type_str(uint16_t exc_type) +{ + switch (exc_type & CL_TYPE_MASK) { + case CL_ARM_EXCEPTION_UNDEF: return "UNDEF exception"; + case CL_ARM_EXCEPTION_PREFETCH_ABORT: return "PREFETCH ABORT"; + case CL_ARM_EXCEPTION_DATA_ABORT: return "DATA ABORT"; + case CL_KERNEL_PANIC: return "PANIC"; + case CL_NMI: return "NMI FIQ"; + case CL_NMI_MSG_LOG: return "forced log msg"; + case CL_NMI_MSG_CRASH: return "forced crash msg"; + case CL_STACK_GUARD_FAULT: return "Stack guard fault"; + case CL_FLOW_ERROR: return "Mailbox error"; + case CL_PANIC_RECOVERY: return "Recoverable PANIC"; + } + + return NULL; +} + +// +// cl_print +// +// Decode and print the crash log using the registered section decoders. +// Make sure the section version match the supported version before +// decoding them. +// +csi_status_t +cl_print (ep_crashlog_desc_t *clog) +{ + uint8_t *cl_buffer; + CrashLogHeader_t *cl_header; + uint32_t cl_size; + CrashLogHeader_t *end_header; + const char *cl_type_str; + uint8_t *log; + + cl_buffer = clog->buffer; + cl_header = (CrashLogHeader_t*)cl_buffer; + cl_size = cl_header->size - sizeof (CrashLogHeader_t); + + // validate the signature + if (CRASH_LOG_HEADER_SIGNATURE != cl_header->signature) { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "invalid log signature: 0x%x, should be 0x%x.\n", cl_header->signature, CRASH_LOG_HEADER_SIGNATURE); + return CSI_STATUS_ERROR; + } + + // ensure the version is compatible + if (LOG_MAJOR_VERSION(CRASH_LOG_VERSION) != LOG_MAJOR_VERSION(cl_header->version)) { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "invalid log major version: %u, should be %u.\n", + LOG_MAJOR_VERSION(cl_header->version), LOG_MAJOR_VERSION(CRASH_LOG_VERSION)); + return CSI_STATUS_ERROR; + } + + // If this is neither a partial nor nested log make sure the header at + // the beginning of the log match the one at the end. + // Issue a warning if they don't and still try to decode the log. + end_header = (CrashLogHeader_t*)(cl_buffer + cl_size); + + if (cl_header->exception & CL_LOG_INITIAL_FLAG) { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "partial log, log might be incomplete\n"); + // revert size to the one in the header, as we don't know what is at the end. + cl_size = cl_header->size; + } + else if (memcmp (cl_header, end_header, sizeof (CrashLogHeader_t))) { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "end header does not match log header, log might be corrupted (cl_size=%d %p %p)\n", cl_size, cl_header, end_header); + // revert size to the one in the header, as we don't know what is at the end. + cl_size = cl_header->size; + } + + // validate the checksum + // TBD + +#if !RELEASE_BUILD + // Print the log + cl_type_str = get_exc_type_str(cl_header->exception); + if (cl_type_str != NULL) { + CSI_EP_LOG(CRASHLOG, clog->coproc, clog->name, "%s\n", cl_type_str); + } else { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "crash log of unexpected type 0x%0x\n", cl_header->exception); + } + if (cl_header->exception & CL_LOG_NESTED_FLAG) { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "a nested %s occured @ 0x%08x\n", + get_exc_type_str(cl_header->nestedException), cl_header->nestedLr); + } + + // Decode the data section + // A duplicate log header is placed at the end of the data section, ignore it. + log = (cl_buffer + sizeof (CrashLogHeader_t)); + + while (log < (uint8_t*)end_header) { + CrashLogDataHeader_t *header = (CrashLogDataHeader_t*)log; + switch (header->signature) { + case CRASH_LOG_DATA_REGISTER_SIGNATURE: + RUN_IF_COMPATIBLE(header->version, CRASH_LOG_DATA_REGISTER_VERSION, cl_print_register_frame(header)); + break; + case CRASH_LOG_DATA_OS_INFO_SIGNATURE: + RUN_IF_COMPATIBLE(header->version, CRASH_LOG_DATA_OS_INFO_VERSION, cl_print_os_info(header)); + break; + case CRASH_LOG_DATA_STRING_SIGNATURE: + RUN_IF_COMPATIBLE(header->version, CRASH_LOG_DATA_STRING_VERSION, cl_print_string(header)); + break; + case CRASH_LOG_DATA_MAILBOX_SIGNATURE: + RUN_IF_COMPATIBLE(header->version, CRASH_LOG_DATA_MAILBOX_VERSION, cl_print_mailbox(header)); + break; + case CRASH_LOG_DATA_CALL_STACK_SIGNATURE: + RUN_IF_COMPATIBLE(header->version, CRASH_LOG_DATA_CALL_STACK_VERSION, cl_print_call_stack(header)); + break; + default: + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "found unknown %s section of size %d, version %x.%x\n", + get_signature_string(header->signature), header->size, LOG_PRINT_VERSION(header->version)); + break; + } + log += header->size; + } +#else + // silence all warnings + (void)cl_type_str; + (void)log; +#endif + + // if we received a recoverable panic reset the IOP + if (CL_PANIC_RECOVERY == cl_header->exception) { + // if we are not already in panic recovery and one was requested try it + if (!csi_is_panic_recovery(clog->coproc)) { + csi_set_feature (clog->coproc, COPROC_FEATURE_PANIC_RECOVERY); + return CSI_STATUS_PANIC_RECOVER; + } else { + CSI_EP_LOG(CRITICAL, clog->coproc, clog->name, "failed panic recovery, hanging...\n"); + } + } + return CSI_STATUS_OK; +} + + +// +// *** Register section *** +// + +typedef struct _fsr_entry_t { + const uint32_t value; + const char* const reason; +} fsr_entry_t; + +static const fsr_entry_t fsr_short_descriptor_table[] = { // From DDI0406C Table B3-23: VMSAv7 Short-descriptor format FSR encodings + {1, "Alignment fault"}, + {4, "Instruction cache maintenance fault"}, + {12, "Translation table walk synchronous external abort (1st level)"}, + {14, "Translation table walk synchronous external abort (2nd level)"}, + {28, "Translation table walk synchronous parity error (1st level)"}, + {30, "Translation table walk synchronous parity error (2nd level)"}, + {5, "Translation fault (section)"}, + {7, "Translation fault (page)"}, + {3, "Access Flag fault (section)"}, + {6, "Access Flag fault (page)"}, + {9, "Domain fault (section)"}, + {11, "Domain fault (page)"}, + {13, "Permission fault (section)"}, + {15, "Permission fault (page)"}, + {2, "Debug event"}, + {8, "Synchronous external abort"}, + {16, "TLB conflict abort"}, + {20, "Implementation defined (Lockdown)"}, + {26, "Implementation defined (Coprocessor abort)"}, + {25, "Memory access synchronous parity error"}, + {22, "Asynchronous external abort"}, + {24, "Memory access asynchronous parity error"}, + {(uint32_t)-1, "Unknown"} // Terminated by value = (unsigned int)-1, which is never a valid encoding +}; + +static const fsr_entry_t fsr_long_descriptor_table[] = { // From DDI0406C Table B3-24: VMSAv7 Long-descriptor format FSR encodings + {4, "Translation fault level %u"}, + {8, "Access flag fault level %u"}, + {12, "Permission fault level %u"}, + {20, "Synchronous external abort on translation table walk level %u"}, + {28, "Synchronous parity error on memory access on translation table walk level %u"}, + {60, "Domain fault level %u"}, + {16, "Synchronous external abort"}, + {24, "Synchronous parity error on memory access"}, + {17, "Asynchronous external abort"}, + {25, "Asynchronous parity error on memory access"}, + {33, "Alignment fault"}, + {34, "Debug event"}, + {48, "TLB conflict abort"}, + {52, "Implementation defined (Lockdown)"}, + {58, "Implementation defined (Coprocessor abort)"}, + {(uint32_t)-1, "Unknown"} // Terminated by value = (unsigned int)-1, which is never a valid encoding +}; + + +static const char* +cl_decode_fsr(uint32_t fsr_val) +{ + // holder for the processed lookup level FSR entries + static char fsr_status_string[80]; + + uint32_t fault_status; + uint32_t fault_lookup_level = 0; + uint32_t fault_status_ll = 0; + + const fsr_entry_t *fsr_table; + + // Check the LPAE bit to see if this is short or long descriptor + if ((fsr_val & (1u<<9)) == 0 ) + { + // Non-LPAE, using short-descriptor format + fault_status = ((fsr_val & (1u<<10)) >> 6 ) | (fsr_val & 0xf); // [10, 3:0] + fsr_table = fsr_short_descriptor_table; + } + else + { + // LPAE, using long-descriptor format + fault_status = (fsr_val & 0x3f); // [5:0] + fault_lookup_level = (fsr_val & 0x03); // [1:0] + fault_status_ll = (fsr_val & 0x3c); // [5:2] + fsr_table = fsr_long_descriptor_table; + } + + while (1) + { + // if a match for non-lookup level entry or the terminator + if( (fault_status == fsr_table->value) + || (fault_status_ll == fsr_table->value) + || (fsr_table->value == (uint32_t)-1) ) + { + snprintf(fsr_status_string, sizeof(fsr_status_string), fsr_table->reason, fault_lookup_level); + return fsr_status_string; + } + + fsr_table++; + } + + // Control should never reach here since fsr tables are terminated by value = -1 + return NULL; +} + + +// +// cl_print_register_frame +// +// Decode and print the register frame section +// +void +cl_print_register_frame (CrashLogDataHeader_t *section) +{ + CrashLogRegisterSection_t *regSection = (CrashLogRegisterSection_t*) section; + + CSI_LOG_RAW(CRASHLOG, "Failing task register frame:\n"); + CSI_LOG_RAW(CRASHLOG, " Faulting PC=0x%08x\n", regSection->registerFrame.pc); + + // print additional information register data + switch (regSection->exception) { + case CL_ARM_EXCEPTION_PREFETCH_ABORT: + CSI_LOG_RAW(CRASHLOG, " ifsr=0x%08x (%s) ifar=0x%08x\n", + regSection->registerFrame.extra_info1, cl_decode_fsr(regSection->registerFrame.extra_info1), + regSection->registerFrame.extra_info2); + break; + + case CL_STACK_GUARD_FAULT: + case CL_ARM_EXCEPTION_DATA_ABORT: + CSI_LOG_RAW(CRASHLOG, " dfsr=0x%08x (%s) dfar=0x%08x\n", + regSection->registerFrame.extra_info1, cl_decode_fsr(regSection->registerFrame.extra_info1), + regSection->registerFrame.extra_info2); + break; + + default: + break; + } + + // print faulting task registers + CSI_LOG_RAW(CRASHLOG, " r00=0x%08x r01=0x%08x r02=0x%08x r03=0x%08x\n" + " r04=0x%08x r05=0x%08x r06=0x%08x r07=0x%08x\n" + " r08=0x%08x r09=0x%08x r10=0x%08x r11=0x%08x\n" + " r12=0x%08x sp=0x%08x lr=0x%08x pc=0x%08x\n" + " spsr=0x%08x\n", + regSection->registerFrame.r0, regSection->registerFrame.r1, regSection->registerFrame.r2, regSection->registerFrame.r3, + regSection->registerFrame.r4, regSection->registerFrame.r5, regSection->registerFrame.r6, regSection->registerFrame.r7, + regSection->registerFrame.r8, regSection->registerFrame.r9, regSection->registerFrame.r10, regSection->registerFrame.r11, + regSection->registerFrame.r12, regSection->registerFrame.sp, regSection->registerFrame.lr, regSection->registerFrame.pc, + regSection->registerFrame.spsr); +} + + +// +// *** OS Section *** +// + +const char* +cl_decode_task_status(uint32_t status) +{ + if (status & 0x100) return "INACTIVE"; + if (status & 0x080) return "QUEUE_WAIT"; + if (status & 0x040) return "SEMAPHORE_WAIT"; + if (status & 0x020) return "MSG_WAIT"; + if (status & 0x010) return "BLOCK_WAIT"; + if (status & 0x008) return "RESOURCE_WAIT"; + if (status & 0x004) return "DELAY_WAIT"; + if (status & 0x002) return "PARTITION_WAIT"; + if ((status & 0xffe) == 0x000) return "READY"; + if ((status & 0x001) == 0x001) return "SUSPENDED"; + return "unknown"; +} + +// +// cl_print_os_info +// +// Decode the OS section +// +void +cl_print_os_info (CrashLogDataHeader_t *section) +{ + CrashLogRtxcSection_t *rtxcSection = (CrashLogRtxcSection_t*) section; + + // display the current task list + CSI_LOG_RAW(CRASHLOG, "RTXC Task List:\n" + " name | pri | lr | stack use | status\n"); + + CrashLogRtxcTask_t *taskLog = (CrashLogRtxcTask_t*)((uint8_t*)(section) + sizeof (CrashLogRtxcSection_t)); + + for (int i = 0; i < (int)rtxcSection->numTask; i++) { + // add a '*' in front of the hipri task + if (taskLog->id == rtxcSection->taskId) { + CSI_LOG_RAW(CRASHLOG, "*"); + } else { + CSI_LOG_RAW(CRASHLOG, " "); + } + + CSI_LOG_RAW(CRASHLOG, "%2d %-15s | %03d | 0x%08x | %04u/%04u | %s\n", + taskLog->id, taskLog->name, taskLog->priority, + taskLog->lr, taskLog->stackUsed, taskLog->stackSize, + cl_decode_task_status(taskLog->status)); + taskLog++; + } +} + + +// +// *** string section *** +// + +void +cl_print_string (CrashLogDataHeader_t *section) +{ + // this section is a header with a NULL terminated string + CrashLogStringSection_t *stringSection = (CrashLogStringSection_t*) section; + + // make sure the string is NULL terminated, force it if not + char *str = &(stringSection->data.string); + size_t len = section->size - sizeof (CrashLogStringSection_t) - 1; // length of the string without the null termination + + if ('\0' != str[len]) { + str[len] = '\0'; + } + + // print the section + CSI_LOG_RAW(CRASHLOG, "%s\n", str); +} + + +// +// *** Mailbox Section *** +// + +void +cl_print_mailbox (CrashLogDataHeader_t *section) +{ + CrashLogMailboxData_t *mailSection = &(((CrashLogMailboxSection_t*)section)->data); + + if (CL_MAILBOX_NO_ERROR == mailSection->error) { + CSI_LOG_RAW(CRASHLOG, "Mailbox status:\n"); + } else { + CSI_LOG_RAW(CRASHLOG, "Mailbox status: (error = 0x%x\n", mailSection->error); + } + CSI_LOG_RAW(CRASHLOG, " Inbox AKF_KIC_INBOX_CTRL = 0x%08x, AKF_KIC_MAILBOX_SET = 0x%08x\n" + " Outbox AKF_AP_OUTBOX_CTRL = 0x%08x, AKF_AP_MAILBOX_SET = 0x%08x\n", + mailSection->inboxCtrl, mailSection->inboxInt, + mailSection->outboxCtrl, mailSection->outboxInt); +} + + +// +// *** Call Stack section *** +// + +static const char * +get_call_stack_error_string(uint32_t error_code) +{ + const char *error_string; + + switch (error_code) { + default: + case CL_CALL_STACK_NO_ERROR: + error_string = ""; + break; + case CL_CALL_STACK_OVERFLOW: + error_string = "error: stack too big for crash log"; + break; + case CL_CALL_STACK_FP_NULL: + error_string = "error: fp is null => possible stack corruption"; + break; + case CL_CALL_STACK_FP_INVALID: + error_string = "error: fp is invalid => possible stack corruption"; + break; + } + + return error_string; +} + + +// +// cl_print_call_stack +// +// Print the call stack of a task. +// There is one of these section per task. +// +void +cl_print_call_stack (CrashLogDataHeader_t *section) +{ + bool isAPanic; + CrashLogCallStackSection_t *callStackSection; + uint32_t *callStack; + + callStackSection = (CrashLogCallStackSection_t*) section; + isAPanic = ((callStackSection->panickingFuncIndex>0) && (callStackSection->panickingFuncIndexstackDepth)); + callStack = (uint32_t*)(callStackSection+1); + + CSI_LOG_RAW(CRASHLOG, "Task %2u Call Stack:%s%s - ", + callStackSection->taskId, + (isAPanic?" (@=>panicking function)":""), + get_call_stack_error_string(callStackSection->error)); + + for ( uint32_t j=0; jstackDepth; j++ ) { + CSI_LOG_RAW(CRASHLOG, " %s0x%08x", ((isAPanic&&(j==callStackSection->panickingFuncIndex))?"@":" "), *callStack++); + } + + CSI_LOG_RAW(CRASHLOG, "\n"); +} + + +// +// Private utility function +// + +const char* +get_signature_string (CrashLogSignature_t sig) +{ + static char sig_str[5]; + // signature are 4 ascii bytes packed into a 32 bit word + // extract and print + sig_str[0] = (char)((sig >> 24) & 0x00FF); + sig_str[1] = (char)((sig >> 16) & 0x00FF); + sig_str[2] = (char)((sig >> 8) & 0x00FF); + sig_str[3] = (char)(sig & 0x00FF); + sig_str[4] = (char)('\0'); + + return sig_str; +} diff --git a/drivers/apple/csi/endpoints/management_ep.c b/drivers/apple/csi/endpoints/management_ep.c new file mode 100644 index 0000000..339a9d0 --- /dev/null +++ b/drivers/apple/csi/endpoints/management_ep.c @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" +#include "endpoints/management_ep.h" +#include "endpoints/crashlog_ep.h" +#include "endpoints/console_ep.h" +#include "endpoints/syslog_ep.h" + + +// +// Global Data +// + +ep_mgmt_desc_t *mgmt_descs[CSI_COPROC_MAX] = {NULL}; + + +// +// Private functions +// + +int ep_mgmt_task (void *arg); + +csi_status_t mgmt_msg_handler (ep_mgmt_desc_t *mgmt, msg_payload_t msg); +csi_status_t handle_hello (ep_mgmt_desc_t *mgmt, ipc_msg_t msg_in); +csi_status_t handle_power_state (ep_mgmt_desc_t *mgmt, ipc_msg_t msg_in); +csi_status_t handle_power_state_ack (ep_mgmt_desc_t *mgmt, ipc_msg_t msg_in); +csi_status_t validate_protocol (ep_mgmt_desc_t *mgmt, csi_protocol_version_t protocol_version); + + +// +// bi_ep_mgmt_create +// +// create a new management endpoint. +// +void +bi_ep_mgmt_create (csi_coproc_t which_coproc, struct task_event *ps_event) +{ + ep_mgmt_desc_t *mgmt; + + // enforce single instance + REQUIRE(mgmt_descs[which_coproc] == NULL); + + mgmt = malloc(sizeof(ep_mgmt_desc_t)); + REQUIRE(mgmt != NULL); + + mgmt->coproc = which_coproc; + mgmt->ps_event = ps_event; + mgmt->power_state = CSI_PS_OFF; + + mgmt_descs[which_coproc] = mgmt; + + task_start(task_create("csi ep mgmt", ep_mgmt_task, mgmt_descs[which_coproc], kTaskStackSize_endpoints)); +} + +mgmt_state_t +bi_ep_mgmt_get_state (csi_coproc_t which_coproc) +{ + if (mgmt_descs[which_coproc] == NULL) { + return MGMT_NONEXISTENT; + } + + return mgmt_descs[which_coproc]->state; +} + +csi_power_state_t +bi_ep_mgmt_get_power_state (csi_coproc_t which_coproc) +{ + if (mgmt_descs[which_coproc] == NULL) { + return CSI_PS_OFF; + } + + return mgmt_descs[which_coproc]->power_state; +} + +csi_status_t +bi_ep_mgmt_send_ps (csi_coproc_t which_coproc, csi_power_state_t ps) +{ + ep_mgmt_desc_t *mgmt; + msg_payload_t ps_msg; + + mgmt = mgmt_descs[which_coproc]; + + csi_mgmt_create_msg (&ps_msg, MGMT_MSG_POWER_STATE, csi_mgmt_create_ps_msg(ps)); + + return csi_send_message (mgmt->csi_token, ps_msg); +} + +// +// mgmt endpoint: task +// +int +ep_mgmt_task (void *arg) +{ + csi_status_t result; + msg_payload_t rcv_msg; + + ep_mgmt_desc_t *mgmt = (ep_mgmt_desc_t*)arg; + + event_init(&mgmt->msg_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + result = csi_register_endpoint(mgmt->coproc, IPC_ENDPOINT_BUILT_IN_MGMT, &mgmt->msg_event, &mgmt->csi_token, &mgmt->name); + REQUIRE(result==CSI_STATUS_OK); + + mgmt->state = MGMT_QUIESCED; + mgmt->remoteVersion = MGMT_UNSUPPORTED_VERSION; + + // FixMe - pinger_init(&mgmt->pinger); + + mgmt->ping_test_waiting = false; + mgmt->ping_test_seqnum = (csi_ping_seqnum_t)0x1234; + + + for (;;) { + event_wait(&mgmt->msg_event); + // empty the rcv queue + while(csi_receive_message(mgmt->csi_token, &rcv_msg) == CSI_STATUS_OK) { + mgmt_msg_handler(mgmt, rcv_msg); + } + } + + return 0; +} + + +csi_status_t +mgmt_msg_handler (ep_mgmt_desc_t *mgmt, msg_payload_t msg) +{ + csi_mgmt_msg_t type; + csi_status_t status; + + type = csi_mgmt_get_type(msg); + status = CSI_STATUS_OK; + + // get the type and dispatch to the appropriate handler + switch (type) { + case MGMT_MSG_HELLO: + status = handle_hello(mgmt, msg); + break; + + case MGMT_MSG_HELLO_ACK: + CSI_EP_LOG(CRITICAL, mgmt->coproc, mgmt->name, "unsupported HELLO_ACK message received: %llx\n", msg); + break; + + case MGMT_MSG_PING: + CSI_EP_LOG(CRITICAL, mgmt->coproc, mgmt->name, "unsupported PING message received: %llx\n", msg); + break; + + case MGMT_MSG_PING_ACK: + // in lieu of autonomous pinger + if (!mgmt->ping_test_waiting) { + CSI_EP_LOG(CRITICAL, mgmt->coproc, mgmt->name, "unexpected ping ack received\n"); + } + mgmt->ping_test_ack = msg; + mgmt->ping_test_waiting = false; + break; + + case MGMT_MSG_POWER_STATE: + status = handle_power_state(mgmt, msg); + break; + + case MGMT_MSG_POWER_STATE_ACK: + status = handle_power_state_ack(mgmt, msg); + break; + + case MGMT_MSG_NOP: + // nop message are silently discarded + status = CSI_STATUS_OK; + break; + + case MGMT_MSG_ENDPOINT_STATUS: + // these should never happen + + default: + // all other message type are currently unsupported + // ignore them to support upward compatibility + CSI_EP_LOG(CRITICAL, mgmt->coproc, mgmt->name, "invalid or unsupported message type received: %d\n", type); + break; + } + + if (CSI_STATUS_OK != status) { + CSI_EP_LOG(CRITICAL, mgmt->coproc, mgmt->name, "failed to process message of type %d\n", type); + } + + return status; +} + + +csi_status_t +handle_hello (ep_mgmt_desc_t *mgmt, ipc_msg_t msg_in) +{ + csi_status_t status; + msg_payload_t msg_out; + + // Check status of the endpoint. + // If we are not waiting for a hello message (quiesced state) ignore it + if ((MGMT_QUIESCED != mgmt->state) && (MGMT_UNSUPPORTED_PROTOCOL_VERSION != mgmt->state)) { + return CSI_STATUS_ERROR; + } + mgmt->power_state = CSI_PS_ON; + + // Validate the other side protocol version + status = validate_protocol(mgmt, csi_mgmt_get_prot(msg_in)); + if (CSI_STATUS_OK == status) { + // supported version - send our version in the ACK message + if (csi_is_panic_recovery(mgmt->coproc)) { + // set the panic recovery feature flag + csi_mgmt_create_msg (&msg_out, MGMT_MSG_HELLO_ACK, csi_mgmt_create_hello_msg (CSI_FEATURE_PANIC_RECOVERY, APPLE_CSI_PROTOCOL_VERSION)); + } else { + // no feature support by default. + csi_mgmt_create_msg (&msg_out, MGMT_MSG_HELLO_ACK, csi_mgmt_create_hello_msg (CSI_FEATURE_NONE, APPLE_CSI_PROTOCOL_VERSION)); + } + + CSI_EP_LOG (DEBUG_SPEW, mgmt->coproc, mgmt->name, "coproc running, protocol version %x.%x\n", + csi_mgmt_get_prot_major(mgmt->remoteVersion), csi_mgmt_get_prot_minor(mgmt->remoteVersion)); + + } else { + // unsupported version - signal the other side we do not support them + CSI_EP_LOG (CRITICAL, mgmt->coproc, mgmt->name, "coproc running unsupported version %x.%x\n", + csi_mgmt_get_prot_major(mgmt->remoteVersion), csi_mgmt_get_prot_minor(mgmt->remoteVersion)); + + csi_mgmt_create_msg (&msg_out, MGMT_MSG_HELLO_ACK, MGMT_UNSUPPORTED_VERSION); + } + + return bi_ep_send_message (mgmt->csi_token, msg_out); +} + + +csi_status_t +handle_power_state (ep_mgmt_desc_t *mgmt, ipc_msg_t msg_in) +{ + msg_payload_t ps_msg; + csi_power_state_t ps; + + // the IOP is requesting a power state change. + // Used for debugging purpose, might be removed later. + ps = csi_mgmt_get_ps_state (msg_in); + + csi_mgmt_create_msg (&ps_msg, MGMT_MSG_POWER_STATE, csi_mgmt_create_ps_msg(ps)); + + return bi_ep_send_message (mgmt->csi_token, ps_msg); +} + + +csi_status_t +handle_power_state_ack (ep_mgmt_desc_t *mgmt, ipc_msg_t msg_in) +{ + csi_power_state_t ps = csi_mgmt_get_ps_state (msg_in); + + // transition to ON means the IOP is now running + // not used in iBoot. + if (CSI_PS_ON == ps) { + return CSI_STATUS_OK; + } + + // if the power state is not ON quiesce built in endpoints. + syslog_quiesce(mgmt->coproc, ps); + console_quiesce(mgmt->coproc, ps); + crashlog_quiesce(mgmt->coproc, ps); + + // set the new power state + mgmt->power_state = ps; + mgmt->state = MGMT_QUIESCED; + + CSI_EP_LOG(DEBUG, mgmt->coproc, mgmt->name, "IOP state changed to 0x%x (mgmt state=%x)\n", mgmt->power_state, mgmt->state); + + // signal the power state change event + event_signal(mgmt->ps_event); + + return CSI_STATUS_OK; +} + + +csi_status_t +validate_protocol (ep_mgmt_desc_t *mgmt, csi_protocol_version_t protocol_version) +{ + // store the remote protocol version for future use. + mgmt->remoteVersion = protocol_version; + + // Validate the protocol version + // Current version support: major has to match. + if (APPLE_CSI_PROTOCOL_VERSION == protocol_version) { + // valid version + mgmt->state = MGMT_VERSION_OK; + return CSI_STATUS_OK; + } else { + // unsupported version + mgmt->state = MGMT_UNSUPPORTED_PROTOCOL_VERSION; + return CSI_STATUS_UNSUPPORTED; + } +} + + +csi_status_t +bi_ep_mgmt_send_ping(csi_coproc_t which_coproc, int ping_count) +{ + int j; + ep_mgmt_desc_t *mgmt; + u_int64_t cum_start_ticks; + u_int64_t per_ping_start_ticks; + ipc_msg_t ping_msg; + csi_status_t status; + + mgmt = mgmt_descs[which_coproc]; + + if (mgmt==NULL) { + return CSI_STATUS_UNAVAILABLE; + } + + cum_start_ticks = timer_get_ticks(); + + for ( j=ping_count; --j>=0; ) { + mgmt->ping_test_waiting = true; + mgmt->ping_test_seqnum++; + + csi_mgmt_create_msg (&ping_msg, MGMT_MSG_PING, csi_mgmt_create_ping_msg(mgmt->ping_test_seqnum, (csi_ping_timestamp_t)timer_get_ticks())); + status = bi_ep_send_message (mgmt->csi_token, ping_msg); + if (CSI_STATUS_OK != status) { + return status; + } + + per_ping_start_ticks = timer_get_ticks(); + + while (mgmt->ping_test_waiting) { + if (timer_ticks_to_usecs(timer_get_ticks()-per_ping_start_ticks) >= 500000) { + // ping ack not received within expected period + // FixMe - expected period is warped for fastsim's notion of time + mgmt->ping_test_waiting = false; + return CSI_STATUS_TIMEOUT; + } + task_yield(); + } + + if (csi_mgmt_get_ping_seqnum(mgmt->ping_test_ack) != mgmt->ping_test_seqnum) { + return CSI_STATUS_ERROR; + } + } + + if (ping_count == 1) { + CSI_EP_LOG(CRITICAL, mgmt->coproc, mgmt->name, "ping rtt: %lld usec\n", timer_ticks_to_usecs(timer_get_ticks()-cum_start_ticks)); + } else { + CSI_EP_LOG(CRITICAL, mgmt->coproc, mgmt->name, "%d pings cumulative rtt: %lld usec\n", ping_count, timer_ticks_to_usecs(timer_get_ticks()-cum_start_ticks)); + } + + return CSI_STATUS_OK; +} diff --git a/drivers/apple/csi/endpoints/syslog_ep.c b/drivers/apple/csi/endpoints/syslog_ep.c new file mode 100644 index 0000000..5baefe5 --- /dev/null +++ b/drivers/apple/csi/endpoints/syslog_ep.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" +#include "endpoints/syslog_ep.h" + +#include +#include +#include + + +// +// Syslog Object +// + +typedef struct { + csi_coproc_t coproc; + struct task_event msg_event; + void *csi_token; + const char *name; + uint32_t verbosity; + syslog_database_t *buffer; + uint32_t allocated; +} ep_syslog_desc_t; + +// +// Global Data +// + +static ep_syslog_desc_t *syslog_descs[CSI_COPROC_MAX] = {NULL}; + +const char* syslog_priority_names[] = SYSLOG_PRIORITY_NAMES; +const char* syslog_facility_names[] = SYSLOG_FACILITY_NAMES; + +// +// Private functions +// + +int ep_syslog_task (void *arg); +void syslog_msg_handler (ep_syslog_desc_t *syslog, msg_payload_t msg); + + +// +// bi_ep_syslog_create +// +// Create a new syslog endpoint +// +void +bi_ep_syslog_create (csi_coproc_t which_coproc) +{ + // enforce single instance + REQUIRE(syslog_descs[which_coproc]==NULL); + syslog_descs[which_coproc] = malloc(sizeof(ep_syslog_desc_t)); + REQUIRE(syslog_descs[which_coproc]!=NULL); + + syslog_descs[which_coproc]->coproc = which_coproc; + + task_start(task_create("csi ep syslog", ep_syslog_task, syslog_descs[which_coproc], kTaskStackSize_endpoints)); +} + + +csi_status_t +syslog_quiesce (csi_coproc_t which_coproc, csi_power_state_t ps) +{ + ep_syslog_desc_t *syslog = syslog_descs[which_coproc]; + + // free all shared memory if we are not preserving it + if (!(ps & CSI_PS_SHARED_PRESERVED) && (NULL != syslog->buffer)) { + csi_free_shared_memory(syslog->buffer); + syslog->buffer = NULL; + syslog->allocated = 0; + } + + return CSI_STATUS_OK; +} + + +// +// bi_ep_syslog_verbosity +// +// Set the syslog endpoint verbosity +// +csi_status_t +bi_ep_syslog_verbosity (csi_coproc_t which_coproc, uint32_t verbosity) +{ + + ep_syslog_desc_t *syslog = syslog_descs[which_coproc]; + + if (syslog==NULL) { + return CSI_STATUS_UNAVAILABLE; + } + + if (verbosity > LOG_DEBUG) { + return CSI_STATUS_ERROR; + } + + syslog->verbosity = verbosity; + + return CSI_STATUS_OK; +} + + +// +// syslog endpoint: task +// + +int +ep_syslog_task(void *arg) +{ + csi_status_t result; + msg_payload_t rcv_msg; + + ep_syslog_desc_t *syslog = (ep_syslog_desc_t*)arg; + + event_init(&syslog->msg_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + result = csi_register_endpoint(syslog->coproc, IPC_ENDPOINT_BUILT_IN_SYSLOG, &syslog->msg_event, &syslog->csi_token, &syslog->name); + REQUIRE(result==CSI_STATUS_OK); + + syslog->verbosity = LOG_DEFAULT; + + syslog->buffer = NULL; + syslog->allocated = 0; + + for (;;) { + event_wait(&syslog->msg_event); + + // empty the rcv queue + while (csi_receive_message(syslog->csi_token, &rcv_msg) == CSI_STATUS_OK) { + syslog_msg_handler(syslog, rcv_msg); + } + } + + return 0; +} + +void +syslog_msg_handler(ep_syslog_desc_t *syslog, msg_payload_t msg) +{ + uint32_t cmd; + uint32_t entry; + uint32_t type; + uint32_t size; + csi_status_t status; + + cmd = syslog_get_cmd(&msg); + + switch (cmd) { + + case REQUEST_SYSLOGDB_BUFFER: + + syslog->allocated = ipc_buff_msg_get_size(msg); + REQUIRE(syslog->buffer==NULL); + syslog->buffer = csi_allocate_shared_memory(syslog->csi_token, syslog->allocated); + REQUIRE(syslog->buffer!=NULL); + + // send the response back to the coproc + uint64_t buffer_phys = mem_static_map_physical((uintptr_t)syslog->buffer); + status = bi_ep_send_message (syslog->csi_token, syslog_construct_msg(HERE_IS_YOUR_SYSLOGDB_BUFFER, buffer_phys, ipc_buff_msg_get_size(msg))); + if (status == CSI_STATUS_OK) { + CSI_EP_LOG(DEBUG_SPEW, syslog->coproc, syslog->name, "buffer request of size %u bytes, allocated @ physical 0x%llx (AP %p)\n", + syslog->allocated, buffer_phys, syslog->buffer); + } else { + CSI_EP_LOG(CRITICAL, syslog->coproc, syslog->name, "unable to reply to REQUEST_SYSLOGDB_BUFFER cmd.\n"); + } + break; + + case OUTPUT_SYSLOG_ENTRY: + entry = (uint32_t)syslog_get_address(&msg); + maybe_do_cache_operation(CACHE_INVALIDATE, &syslog->buffer->entries[entry], sizeof(syslog_entry_t)); + type = syslog->buffer->entries[entry].type; + if (LOG_PRI(type) <= syslog->verbosity) { + if (LOG_FAC(type) != LOG_KERN) { + CSI_EP_LOG (SYSLOG, syslog->coproc, syslog->name, "%s: %s\n", syslog_get_facility_name(type), syslog->buffer->entries[entry].message); + } else { + CSI_EP_LOG (SYSLOG, syslog->coproc, syslog->name, "task #%d, file: %s: %s\n", + syslog->buffer->entries[entry].taskid, syslog->buffer->entries[entry].filename, syslog->buffer->entries[entry].message); + } + } + status = bi_ep_send_message (syslog->csi_token, syslog_construct_msg(OUTPUTTED_SYSLOG_ENTRY, entry, 0)); + break; + + case SYSLOG_ENTRY_TRUNCATED: + size = (uint32_t)syslog_get_address(&msg); // in this message the address field is used to report the log entry length + CSI_EP_LOG(CRITICAL, syslog->coproc, syslog->name, "coproc tried to print a 0x%x byte message, but message buffer is only %d bytes long.\n", size, SYSLOG_MESSAGE_SIZE); + break; + + case SYSLOGDB_OVERFLOW: + CSI_EP_LOG(CRITICAL, syslog->coproc, syslog->name, "coproc database overflowed.\n"); + break; + + default: + CSI_EP_LOG(CRITICAL, syslog->coproc, syslog->name, "unimplemented syslog command: %x\n", cmd); + break; + } +} diff --git a/drivers/apple/csi/firmware/csi_firmware.c b/drivers/apple/csi/firmware/csi_firmware.c new file mode 100644 index 0000000..642195e --- /dev/null +++ b/drivers/apple/csi/firmware/csi_firmware.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" +#include "csi_firmware.h" + +#include +#include +#include +#include + + +extern const get_fw_info_t fw_info_ans; + +static const get_fw_info_t *fw_info_getters[CSI_COPROC_MAX] = { + &fw_info_ans, + NULL, + NULL, + NULL, +}; + + +csi_status_t +fw_fixup_and_relocate (csi_coproc_t coproc, fw_desc_t *fw_desc) +{ + const get_fw_info_t *fw_info; + void *heap_base; + uint32_t heap_size_max; + volatile CsiConfig_t *csi_config; + + fw_info = fw_info_getters[coproc]; + + if (fw_info == NULL) { + return CSI_STATUS_NO_FIRMWARE; + } + + // Get the csi configuration structure and validate it. + // This structure contain all the relevant firmware information needed for relocation. + // Use it as read only until the firmware has been relocated + if (fw_info->get_csi_config_offset() == VALUE_NOT_FOUND) { + CSI_LOG (CRITICAL, coproc, "coproc firmware does not specifiy a fix-up location for the csi configuration structure\n"); + return CSI_STATUS_BAD_FIRMWARE; + } + csi_config = (volatile CsiConfig_t*)(fw_info->get_fw_image() + fw_info->get_csi_config_offset()); + if (CSI_CONFIG_SIGNATURE != csi_config->signature) { + CSI_LOG (CRITICAL, coproc, "Invalid csi config signature: 0x%x != 0x%x\n", csi_config->signature, CSI_CONFIG_SIGNATURE); + return CSI_STATUS_BAD_FIRMWARE; + } + if (CSI_CONFIG_VERSION != csi_config->version) { + CSI_LOG (CRITICAL, coproc, "Invalid csi config version: 0x%x != 0x%x\n", csi_config->version, CSI_CONFIG_VERSION); + return CSI_STATUS_BAD_FIRMWARE; + } + + // Validate the firmware size + fw_desc->fw_address = (void*)(fw_desc->region_base); + fw_desc->fw_size = csi_config->fwRuntimeSize; + if (fw_desc->fw_size > fw_desc->region_size) { + CSI_LOG (CRITICAL, coproc, "firmware size (0x%x) is too large (max size=0x%x)\n", fw_desc->fw_size, fw_desc->region_size); + return CSI_STATUS_OUT_OF_RESSOURCES; + } + + // Validate the alignment. We only support up to a page size, adjust if needed. + if (!is_power_of_2(csi_config->fwAlignmentRequired)) { + CSI_LOG (CRITICAL, coproc, "firmware alignment requirement (0x%x) is not a power of 2\n", csi_config->fwAlignmentRequired); + return CSI_STATUS_BAD_FIRMWARE; + } + if (csi_config->fwAlignmentRequired > PAGE_SIZE) { + fw_desc->alignment_req = PAGE_SIZE; + CSI_LOG (DEBUG, coproc, "Requested alignment (0x%x) is greater than a page size (0x%x) - adjusting to 0x%x\n", + csi_config->fwAlignmentRequired, PAGE_SIZE, fw_desc->alignment_req); + } else { + fw_desc->alignment_req = csi_config->fwAlignmentRequired; + } + + // copy the fixed up firmware, zero'ing the targeted memory first. + memset (fw_desc->fw_address, 0, fw_desc->fw_size); + memcpy (fw_desc->fw_address, fw_info->get_fw_image(), fw_info->get_fw_image_size()); + + CSI_LOG (CRITICAL, coproc, "firmware: %s-%s %s\n", fw_info->get_name_str(), fw_info->get_build_str(), fw_info->get_version_str()); + CSI_LOG (DEBUG_SPEW, coproc, " @phys = %p, image size = 0x%x, binary size = 0x%x\n", + (void *)mem_static_map_physical((uintptr_t)fw_desc->fw_address), fw_info->get_fw_image_size(), fw_desc->fw_size); + + // Get the relocated config structure and validate it. + // It is now read write + csi_config = (volatile CsiConfig_t*)(fw_desc->fw_address + fw_info->get_csi_config_offset()); + if (CSI_CONFIG_SIGNATURE != csi_config->signature) { + CSI_LOG (CRITICAL, coproc, "Invalid csi config signature after relocation: %x != %x\n", csi_config->signature, CSI_CONFIG_SIGNATURE); + return CSI_STATUS_ERROR; + } + + // Fix up the soc information + csi_config->soc = chipid_get_chip_id(); + csi_config->socRevision = chipid_get_chip_revision(); + csi_config->nClock = clock_get_frequency (CLK_NCLK); + csi_config->ancLinkClock = clock_get_frequency (CLK_ANS_LINK); + + // determine base and max size of heap + heap_base = (void*)roundup(((uint64_t)fw_desc->fw_address + fw_desc->fw_size), fw_desc->alignment_req); + heap_size_max = (uint32_t)(fw_desc->region_size - (uint32_t)(heap_base - fw_desc->fw_address)); + + fw_desc->heap_address = NULL; + fw_desc->heap_size = 0; + + // Set up the heap + if (csi_config->heapMap.numHeap > 0) { + // Initialize heap map. + for (int j = 1; j < (int)csi_config->heapMap.numHeap; j++) { + csi_config->heapMap.heap[j].pbase = 0; + csi_config->heapMap.heap[j].size = 0; + } + + if (heap_size_max < csi_config->heapRequired) { + CSI_LOG (DEBUG_SPEW, coproc, "requested heap size of (0x%x) exceeds available size (0x%x) - proceeding with smaller heap!\n", csi_config->heapRequired, heap_size_max); + } + + // the IOP takes remapped address for its heap so substract the region base + csi_config->heapMap.heap[0].pbase = (uint64_t)(heap_base - fw_desc->region_base); + csi_config->heapMap.heap[0].size = ((heap_size_max < csi_config->heapRequired) ? heap_size_max : csi_config->heapRequired); + + // store real address for the iBoot side + fw_desc->heap_address = (void*)heap_base; + fw_desc->heap_size = csi_config->heapMap.heap[0].size; + + CSI_LOG (DEBUG_SPEW, coproc, "Heap @ physical %p (remapped %p), size= 0x%x\n", fw_desc->heap_address, (void *)csi_config->heapMap.heap[0].pbase, csi_config->heapMap.heap[0].size); + } + + // Fix up whether early-boot tracing is enabled + uint8_t iboot_debug = 0; + power_get_nvram(kPowerNVRAMiBootDebugKey, &iboot_debug); + uint32_t early_debug_val = ((iboot_debug & kPowerNVRAMiBootDebugEarlyTracing) ? 1:0); + + if (early_debug_val) { + CSI_LOG (CRITICAL, coproc, "Enabling early boot tracing as requested via powernvram.\n"); + } + csi_config->kDebugEarlyDebug = early_debug_val; + + maybe_do_cache_operation(CACHE_CLEAN, fw_desc->fw_address, fw_desc->fw_size); + maybe_do_cache_operation(CACHE_CLEAN, heap_base, fw_desc->heap_size); + + return CSI_STATUS_OK; +} + + +void +fw_print_version (csi_coproc_t coproc, fw_desc_t *fw_desc) +{ + const get_fw_info_t *fw_info; + const CsiConfig_t *csi_config; + + // print version information + fw_info = fw_info_getters[coproc]; + csi_config = (CsiConfig_t*)(fw_desc->fw_address + fw_info->get_csi_config_offset()); + + CSI_LOG (CRITICAL, coproc, "firmware: %s-%s %s @phys = %p\n", + fw_info->get_name_str(), fw_info->get_build_str(), fw_info->get_version_str(), + (void *)mem_static_map_physical((uintptr_t)fw_desc->fw_address)); + CSI_LOG (CRITICAL, coproc, "protocol version %x.%x on soc %x.%x\n", + csi_mgmt_get_prot_major(csi_config->version), csi_mgmt_get_prot_minor(csi_config->version), + csi_config->soc, csi_config->socRevision); +} diff --git a/drivers/apple/csi/firmware/csi_firmware.h b/drivers/apple/csi/firmware/csi_firmware.h new file mode 100644 index 0000000..4875955 --- /dev/null +++ b/drivers/apple/csi/firmware/csi_firmware.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "csi_private.h" + + +#define VALUE_NOT_FOUND ((uint32_t)-1) + +typedef const char* (*get_name_str_t)(void); +typedef const char* (*get_build_str_t)(void); +typedef const char* (*get_version_str_t)(void); +typedef const char* (*get_fw_image_t)(void); +typedef uint32_t (*get_fw_image_size_t)(void); +typedef uint32_t (*get_csi_config_offset_t)(void); +typedef uint32_t (*get_fw_mem_req_t)(void); +typedef void* (*get_reloc_address_t)(void); +typedef uint32_t (*get_reloc_size_t)(void); + +typedef struct { + get_name_str_t get_name_str; + get_build_str_t get_build_str; + get_version_str_t get_version_str; + get_fw_image_t get_fw_image; + get_fw_image_size_t get_fw_image_size; + get_csi_config_offset_t get_csi_config_offset; + get_fw_mem_req_t get_fw_memory_required; + get_reloc_address_t get_reloc_address; + get_reloc_size_t get_reloc_size; +} get_fw_info_t; diff --git a/drivers/apple/csi/firmware/fw_ans.c b/drivers/apple/csi/firmware/fw_ans.c new file mode 100644 index 0000000..0d310c4 --- /dev/null +++ b/drivers/apple/csi/firmware/fw_ans.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "csi_firmware.h" + +#if SUB_PLATFORM_S7002 +#include +//#include +#elif SUB_PLATFORM_T8002 +// XXX +// T8002SIM: ASP support +#include +#else +#include +//#include +#endif + +// Validate the IOP protocol against the one required by the firmware file +#if !defined(ANS_PROTOCOL_VER_MAJOR) || !defined(ANS_PROTOCOL_VER_MINOR) +#error ERROR: ANS firmware does not specify protocol version +#else +#if (!(ANS_PROTOCOL_VER_MAJOR == APPLE_CSI_PROTOCOL_VER_MAJOR) || (!(ANS_PROTOCOL_VER_MINOR == APPLE_CSI_PROTOCOL_VER_MINOR))) +#error ERROR: the CSI protocol version does not match the one required by the ANS firmware. +#endif +#endif + +static const char* fw_ans_get_name_str() { return fwFirmwareTarget; } +static const char* fw_ans_get_build_str() { return fwFirmwareBuild; } +static const char* fw_ans_get_version_str() { return fwFirmwareVersion; } +static const char* fw_ans_get_fw_image() { return (const char*)&fwFirmwareImage[0]; } +static uint32_t fw_ans_get_fw_image_size() { return sizeof(fwFirmwareImage); } +static uint32_t fw_ans_get_csi_config_offset() { return ((fwConfigurationOffset!=SYMBOL_NOT_FOUND) ? fwConfigurationOffset : VALUE_NOT_FOUND); } +static uint32_t fw_ans_get_memory_required() { return fwAspRequiredMemory; } +static void* fw_ans_get_reloc_address() { return (void*)ASP_BASE; } +static uint32_t fw_ans_get_reloc_size() { return ASP_SIZE; } + +const get_fw_info_t fw_info_ans = { + fw_ans_get_name_str, + fw_ans_get_build_str, + fw_ans_get_version_str, + fw_ans_get_fw_image, + fw_ans_get_fw_image_size, + fw_ans_get_csi_config_offset, + fw_ans_get_memory_required, + fw_ans_get_reloc_address, + fw_ans_get_reloc_size, +}; diff --git a/drivers/apple/csi/include/csi_private.h b/drivers/apple/csi/include/csi_private.h new file mode 100644 index 0000000..25b82cf --- /dev/null +++ b/drivers/apple/csi/include/csi_private.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __CSI_PRIVATE_H +#define __CSI_PRIVATE_H + +#include +#include + +// NOTE: The following header file is expected to be found via the search paths expressed in +// rules.mk via the GLOBAL_INCLUDES macro. +#include +#include +#include + +// build-time CSI protocol version range check +// Make sure you could this in sync with the protoc +#define EXPECTED_RANGE_MIN_PROTOCOL_VER_MAJOR 9 +#define EXPECTED_RANGE_MAX_PROTOCOL_VER_MAJOR 9 + +#if !((EXPECTED_RANGE_MIN_PROTOCOL_VER_MAJOR <= APPLE_CSI_PROTOCOL_VER_MAJOR) && (EXPECTED_RANGE_MAX_PROTOCOL_VER_MAJOR >= APPLE_CSI_PROTOCOL_VER_MAJOR)) +#error ERROR: This iBoot is not compatible with your AppleStorageProcessor firmware +#endif + + +// explicitly specify task stack sizes +// empirically derived stack high watermark measurements +// csi inbox_not_e: 512 +// csi ep mgmt: 416 +// csi ep crashlog: 1728 +// csi ep console: 448 +// csi ep syslog: 1424 + +// request 8 kb to cover with a healthy margin +// further tuning will be handled with Analyze stack usage and tune stack size for csi iBoot tasks + +#define kTaskStackSize_inbox_not_empty 0x2000 +#define kTaskStackSize_endpoints 0x2000 + + + + +// default send message time out +#define CSI_SEND_MESSAGE_TIMEOUT (10 * 1000 * 1000) // 10s + + +#define roundup(x,y) ((((x)+(y)-1)/(y))*(y)) + +#define is_power_of_2(x) (((x)==((x)&~((x)-1)))&&((x)!=0)) + + +#ifndef REQUIRE +#define REQUIRE(_expr) \ + do { \ + if (__builtin_expect(!(_expr), 0)) \ + panic("%s:%s:%u: REQUIRE failed: %s\n", \ + __FILE__, \ + __PRETTY_FUNCTION__, \ + __LINE__, #_expr); \ + } while(0); +#endif + + +#define COPROC_STATE(s) \ + (((s)==MGMT_INITIALIZED) ? "Initialized" : \ + (((s)==MGMT_QUIESCED) ? "Quiesced" : \ + (((s)==MGMT_WAITING_FOR_ACK) ? "Waiting For Hello" : \ + (((s)==MGMT_VERSION_OK) ? "Running" : \ + (((s)==MGMT_UNSUPPORTED_PROTOCOL_VERSION) ? "Running - Unsupported Protocol Version" : \ + (((s)==MGMT_NONEXISTENT) ? "Uninitialized" : "???")))))) + + + + // CS_LOG levels are passed through to dprintf() and compared against DEBUG_LEVEL. + // defines { DEBUG_SILENT DEBUG_CRITICAL DEBUG_INFO DEBUG_SPEW } + // one may use DEBUG_LEVEL to enable output and (DEBUG_LEVEL+1) to stifle output + + // these levels should probably be enabled by default +#define CSI_LOG_LEVEL_CRITICAL DEBUG_CRITICAL // indication of a serious problem + + // these levels *may* be enabled by default +#define CSI_LOG_LEVEL_CRASHLOG DEBUG_CRITICAL // coproc crashlog output +#define CSI_LOG_LEVEL_CONSOLE DEBUG_INFO // coproc console output +#define CSI_LOG_LEVEL_SYSLOG DEBUG_CRITICAL // coproc syslog output +#define CSI_LOG_LEVEL_DEBUG_SPEW DEBUG_SPEW // verbose debug output + + // these levels are disabled by default +#if DEBUG_BUILD +#define CSI_LOG_LEVEL_DEBUG DEBUG_INFO +#else +#define CSI_LOG_LEVEL_DEBUG DEBUG_CRITICAL // every little operational detail - TMI - useful for debugging only +#endif + + + // csi log formatting macros +#define CSI_LOG_RAW(lev, x...) \ + do { dprintf(CSI_LOG_LEVEL_##lev, x); } while(0) + +#define CSI_LOG(lev, cop, x...) \ + do { dprintf(CSI_LOG_LEVEL_##lev, "%s: ", IOP_NAME(cop)); dprintf(CSI_LOG_LEVEL_##lev, x); } while(0) + +#define CSI_EP_LOG(lev, cop, ep_name, x...) \ + do { dprintf(CSI_LOG_LEVEL_##lev, "[%s %s] ", IOP_NAME(cop), ep_name); dprintf(CSI_LOG_LEVEL_##lev, x); } while(0) + + + // firmware api + +typedef struct { + uint32_t alignment_req; + void *fw_address; + uint32_t fw_size; + void *heap_address; + uint32_t heap_size; + addr_t region_base; + uint32_t region_size; +} fw_desc_t; + +csi_status_t fw_fixup_and_relocate (csi_coproc_t which_coproc, fw_desc_t *fw_desc); +void fw_print_version (csi_coproc_t coproc, fw_desc_t *fw_desc); + +csi_status_t csi_start (csi_coproc_t which_coproc); +csi_status_t csi_stop (csi_coproc_t which_coproc); +csi_status_t csi_panic_recover (csi_coproc_t which_coproc); +csi_status_t quiesce_iop (csi_coproc_t which_coproc); +csi_status_t hibernate_iop (csi_coproc_t which_coproc); +csi_status_t request_iop_power_state (csi_coproc_t which_coproc, csi_power_state_t ps); +csi_status_t set_send_timeout (csi_coproc_t which_coproc, uint32_t timeout); +uint32_t get_send_timeout (csi_coproc_t which_coproc); +void csi_info (csi_coproc_t which_coproc); + + +csi_status_t csi_set_feature (csi_coproc_t which_coproc, coproc_feature_t feature); +csi_status_t csi_clr_feature (csi_coproc_t which_coproc, coproc_feature_t feature); + +void maybe_do_cache_operation(int operation, void *address, u_int32_t length); + + +// +// built-in endpoint api +// + +csi_status_t bi_ep_send_message (void *token, msg_payload_t msg_payload); + +#endif /* !defined(__CSI_PRIVATE_H) */ diff --git a/drivers/apple/csi/include/endpoints/console_ep.h b/drivers/apple/csi/include/endpoints/console_ep.h new file mode 100644 index 0000000..fad7225 --- /dev/null +++ b/drivers/apple/csi/include/endpoints/console_ep.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#pragma once + +// +// Console object +// + +typedef struct { + csi_coproc_t coproc; + struct task_event msg_event; + void *csi_token; + const char *name; + uint32_t verbosity; + void *buffers; + uint32_t allocated; + char *scratch; +} ep_console_desc_t; + + +// +// Console APIs +// + +void bi_ep_console_create (csi_coproc_t which_coproc); +csi_status_t bi_ep_console_send_custom_cmd (csi_coproc_t which_coproc, uint32_t payload); +csi_status_t bi_ep_console_set_verbosity (csi_coproc_t which_coproc, uint32_t verbosity); + +csi_status_t console_quiesce (csi_coproc_t which_coproc, csi_power_state_t ps); diff --git a/drivers/apple/csi/include/endpoints/crashlog_ep.h b/drivers/apple/csi/include/endpoints/crashlog_ep.h new file mode 100644 index 0000000..a1a746b --- /dev/null +++ b/drivers/apple/csi/include/endpoints/crashlog_ep.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#pragma once + +// crash log type +typedef enum { + CSI_CRASHLOG_TYPE_NMI = 0, + CSI_CRASHLOG_TYPE_MSG_CRASH, + CSI_CRASHLOG_TYPE_MSG_LOG, +} csi_crashlog_t; + +// +// Crashlog Object +// +typedef struct { + csi_coproc_t coproc; + struct task_event msg_event; + void *csi_token; + const char *name; + void *buffer; + uint32_t allocated; +} ep_crashlog_desc_t; + + +// +// Public API +// + +void bi_ep_crashlog_create (csi_coproc_t which_coproc); +csi_status_t bi_ep_crashlog_force_event (csi_coproc_t which_coproc, csi_crashlog_t crashlog_type); + +csi_status_t crashlog_quiesce (csi_coproc_t which_coproc, csi_power_state_t ps); diff --git a/drivers/apple/csi/include/endpoints/management_ep.h b/drivers/apple/csi/include/endpoints/management_ep.h new file mode 100644 index 0000000..f05f30b --- /dev/null +++ b/drivers/apple/csi/include/endpoints/management_ep.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#pragma once + +#include +#include + + +// FixMe - auto-pinger not implemented +// pinger +typedef enum { + PINGER_DISABLED = 0x0000, + PINGER_OK = 0x0001, + PINGER_TIMEOUT = 0x1000, + PINGER_SEQ_ERR = 0x1001, + PINGER_XMIT_ERR = 0x1002, +} pinger_status_t; + +typedef struct { + uint32_t xmt_count; + uint32_t replied_to_count; + uint32_t xmt_err_count; + uint32_t rcv_err_count; + uint32_t timeout_err_count; +} ping_stats_t; + +typedef struct { + uint32_t ping_period_usec; + uint32_t report_period_usec; + pinger_status_t status; + + csi_ping_seqnum_t xmt_seq_number; + csi_ping_seqnum_t expected_rcv_seq_number; + csi_ping_seqnum_t rcv_seq_number; + + ping_stats_t stats; +} pinger_t; + + +// +// Management Object +// + +typedef enum { + MGMT_INITIALIZED = 0, + MGMT_QUIESCED, + MGMT_WAITING_FOR_ACK, + MGMT_VERSION_OK, + + // error status + MGMT_NONEXISTENT = 0x1000, + MGMT_UNSUPPORTED_PROTOCOL_VERSION = 0x1001, + MGMT_MBOX_ERROR = 0x1002, +} mgmt_state_t; + +typedef struct { + csi_coproc_t coproc; + struct task_event msg_event; + void *csi_token; + const char *name; + + csi_protocol_version_t remoteVersion; + mgmt_state_t state; + + // pinger + pinger_t pinger; + + volatile bool ping_test_waiting; + volatile csi_ping_seqnum_t ping_test_seqnum; + volatile ipc_msg_t ping_test_ack; + + // power + struct task_event *ps_event; + csi_power_state_t power_state; +} ep_mgmt_desc_t; + +extern ep_mgmt_desc_t *mgmt_descs[]; + + +// +// Endpoint API +// + +void bi_ep_mgmt_create (csi_coproc_t which_coproc, struct task_event *ps_event); +csi_status_t bi_ep_mgmt_send_ps (csi_coproc_t which_coproc, csi_power_state_t ps); +csi_status_t bi_ep_mgmt_send_ping (csi_coproc_t which_coproc, int ping_count); +mgmt_state_t bi_ep_mgmt_get_state (csi_coproc_t which_coproc); + +csi_power_state_t bi_ep_mgmt_get_power_state (csi_coproc_t which_coproc); + +// to support panic recovery +csi_status_t handle_power_state_ack (ep_mgmt_desc_t *mgmt, ipc_msg_t msg_in); diff --git a/drivers/apple/csi/include/endpoints/syslog_ep.h b/drivers/apple/csi/include/endpoints/syslog_ep.h new file mode 100644 index 0000000..9755a18 --- /dev/null +++ b/drivers/apple/csi/include/endpoints/syslog_ep.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#pragma once + +#if DEBUG_BUILD +#define LOG_DEFAULT LOG_DEBUG +#else +#define LOG_DEFAULT LOG_WARNING +#endif + + +// +// Endpoint APIs +// + +void bi_ep_syslog_create (csi_coproc_t which_coproc); +csi_status_t bi_ep_syslog_verbosity (csi_coproc_t which_coproc, uint32_t verbosity); + +csi_status_t syslog_quiesce (csi_coproc_t which_coproc, csi_power_state_t ps); diff --git a/drivers/apple/csi/include/queue.h b/drivers/apple/csi/include/queue.h new file mode 100644 index 0000000..9ccb63e --- /dev/null +++ b/drivers/apple/csi/include/queue.h @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines five types of data structures: singly-linked lists, + * singly-linked tail queues, lists, tail queues, and circular queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * Note that circle queues are deprecated, because, as the removal log + * in FreeBSD states, "CIRCLEQs are a disgrace to everything Knuth taught + * us in Volume 1 Chapter 2. [...] Use TAILQ instead, it provides the same + * functionality." Code using them will continue to compile, but they + * are no longer documented on the man page. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ CIRCLEQ + * _HEAD + + + + + + * _HEAD_INITIALIZER + + + + - + * _ENTRY + + + + + + * _INIT + + + + + + * _EMPTY + + + + + + * _FIRST + + + + + + * _NEXT + + + + + + * _PREV - - - + + + * _LAST - - + + + + * _FOREACH + + + + + + * _FOREACH_SAFE + + + + - + * _FOREACH_REVERSE - - - + - + * _FOREACH_REVERSE_SAFE - - - + - + * _INSERT_HEAD + + + + + + * _INSERT_BEFORE - + - + + + * _INSERT_AFTER + + + + + + * _INSERT_TAIL - - + + + + * _CONCAT - - + + - + * _REMOVE_AFTER + - + - - + * _REMOVE_HEAD + - + - - + * _REMOVE_HEAD_UNTIL - - + - - + * _REMOVE + + + + + + * _SWAP - + + + - + * + */ +#ifdef QUEUE_MACRO_DEBUG +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + char * lastfile; + int lastline; + char * prevfile; + int prevline; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRASHIT(x) +#endif /* QUEUE_MACRO_DEBUG */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_REMOVE_AFTER(curelm, field); \ + } \ + TRASHIT((elm)->field.sle_next); \ +} while (0) + +#define SLIST_REMOVE_AFTER(elm, field) do { \ + SLIST_NEXT(elm, field) = \ + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + STAILQ_REMOVE_AFTER(head, curelm, field); \ + } \ + TRASHIT((elm)->field.stqe_next); \ +} while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_SWAP(head1, head2, type) do { \ + struct type *swap_first = STAILQ_FIRST(head1); \ + struct type **swap_last = (head1)->stqh_last; \ + STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_FIRST(head2) = swap_first; \ + (head2)->stqh_last = swap_last; \ + if (STAILQ_EMPTY(head1)) \ + (head1)->stqh_last = &STAILQ_FIRST(head1); \ + if (STAILQ_EMPTY(head2)) \ + (head2)->stqh_last = &STAILQ_FIRST(head2); \ +} while (0) + + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#if (defined(_KERNEL) && defined(INVARIANTS)) || defined(QUEUE_MACRO_DEBUG) +#define QMD_LIST_CHECK_HEAD(head, field) do { \ + if (LIST_FIRST((head)) != NULL && \ + LIST_FIRST((head))->field.le_prev != \ + &LIST_FIRST((head))) \ + panic("Bad list head %p first->prev != head", (head)); \ +} while (0) + +#define QMD_LIST_CHECK_NEXT(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL && \ + LIST_NEXT((elm), field)->field.le_prev != \ + &((elm)->field.le_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (0) + +#define QMD_LIST_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.le_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (0) +#else +#define QMD_LIST_CHECK_HEAD(head, field) +#define QMD_LIST_CHECK_NEXT(elm, field) +#define QMD_LIST_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) || QUEUE_MACRO_DEBUG */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + QMD_LIST_CHECK_NEXT(listelm, field); \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_LIST_CHECK_PREV(listelm, field); \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + QMD_LIST_CHECK_HEAD((head), field); \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + QMD_LIST_CHECK_NEXT(elm, field); \ + QMD_LIST_CHECK_PREV(elm, field); \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ + TRASHIT((elm)->field.le_next); \ + TRASHIT((elm)->field.le_prev); \ +} while (0) + +#define LIST_SWAP(head1, head2, type, field) do { \ + struct type *swap_tmp = LIST_FIRST((head1)); \ + LIST_FIRST((head1)) = LIST_FIRST((head2)); \ + LIST_FIRST((head2)) = swap_tmp; \ + if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ + if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ +} while (0) + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + QMD_TRACE_HEAD(head1); \ + QMD_TRACE_HEAD(head2); \ + } \ +} while (0) + +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else { \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT((elm)->field.tqe_next); \ + TRASHIT((elm)->field.tqe_prev); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_SWAP(head1, head2, type, field) do { \ + struct type *swap_first = (head1)->tqh_first; \ + struct type **swap_last = (head1)->tqh_last; \ + (head1)->tqh_first = (head2)->tqh_first; \ + (head1)->tqh_last = (head2)->tqh_last; \ + (head2)->tqh_first = swap_first; \ + (head2)->tqh_last = swap_last; \ + if ((swap_first = (head1)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head1)->tqh_first; \ + else \ + (head1)->tqh_last = &(head1)->tqh_first; \ + if ((swap_first = (head2)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head2)->tqh_first; \ + else \ + (head2)->tqh_last = &(head2)->tqh_first; \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue functions. + */ +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) + +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = (head)->cqh_first; \ + (var) != (void *)(head); \ + (var) = (var)->field.cqe_next) + +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = (void *)(head); \ + (head)->cqh_last = (void *)(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = (void *)(head); \ + if ((head)->cqh_last == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = (void *)(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_LAST(head) ((head)->cqh_last) + +#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) + +#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#ifdef _KERNEL + +#if NOTFB31 + +/* + * XXX insque() and remque() are an old way of handling certain queues. + * They bogusly assumes that all queue heads look alike. + */ + +struct quehead { + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +#ifdef __GNUC__ + +static __inline void +insque(void *a, void *b) +{ + struct quehead *element = (struct quehead *)a, + *head = (struct quehead *)b; + + element->qh_link = head->qh_link; + element->qh_rlink = head; + head->qh_link = element; + element->qh_link->qh_rlink = element; +} + +static __inline void +remque(void *a) +{ + struct quehead *element = (struct quehead *)a; + + element->qh_link->qh_rlink = element->qh_rlink; + element->qh_rlink->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +#else /* !__GNUC__ */ + +void insque(void *a, void *b); +void remque(void *a); + +#endif /* __GNUC__ */ + +#endif +#endif /* _KERNEL */ + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/drivers/apple/csi/rules.mk b/drivers/apple/csi/rules.mk new file mode 100644 index 0000000..b9bda05 --- /dev/null +++ b/drivers/apple/csi/rules.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2011-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_CSI=1 + +# The additional paths below are used to find the ans iop firmware +# file, "AppleCSI.*.h" and a protocol definition file, +# "AppleCSIProtocol.h" which defines communications between coproc firmware +# and the csi driver. The $(DSTROOT) path is useful only during development. +GLOBAL_INCLUDES += $(LOCAL_DIR)/include \ + $(DSTROOT)/usr/local/standalone/firmware \ + $(SDKROOT)/../../../usr/local/standalone/firmware + +ALL_OBJS += $(LOCAL_DIR)/csi.o \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/endpoints/builtin.o \ + $(LOCAL_DIR)/endpoints/management_ep.o \ + $(LOCAL_DIR)/endpoints/syslog_ep.o \ + $(LOCAL_DIR)/endpoints/console_ep.o \ + $(LOCAL_DIR)/endpoints/crashlog_ep.o \ + $(LOCAL_DIR)/firmware/csi_firmware.o \ + $(LOCAL_DIR)/firmware/fw_ans.o \ diff --git a/drivers/apple/dart_lpae/dart.c b/drivers/apple/dart_lpae/dart.c new file mode 100644 index 0000000..13ec4a2 --- /dev/null +++ b/drivers/apple/dart_lpae/dart.c @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include "dart_regs.h" + +#if DART_PAGE_SIZE != DART_TT_PGSIZE +#error "The generic header's idea of the page size doesn't agree with this driver" +#endif + +typedef uint64_t dart_ent; + +typedef struct dart_l2_tt { + dart_ent *tt_base; + uintptr_t tt_phys; + + dart_ent *l3_tt_bases[DART_TTE_PGENTRIES]; +} dart_l2_tt_t; + +typedef struct dart { + uintptr_t regs; + dart_l2_tt_t *l2_tts[DART_NUM_TTBR]; + dart_iovm_addr_t addr_mask; +} dart_t; + +dart_t darts[NUM_DARTS]; + +static void *alloc_tt_page(void) +{ + void *result; + result = memalign(DART_TT_PGSIZE, DART_TT_PGSIZE); + bzero(result, DART_TT_PGSIZE); + + return result; +} + +static void flush_tlb(dart_t *dart) +{ + arm_memory_barrier(); + + // Flush SID 0 + rDART_TLB_OP(dart->regs) = DART_TLB_OP_FLUSH | DART_TLB_OP_SID_MASK0; + + while(rDART_TLB_OP(dart->regs) & DART_TLB_OP_BUSY) + ; +} + +// Clear out any L3 entries in the DART so that nothing is mapped into IO virtual +// space. Don't clear out the mappings at the L2 level, just at L3. The DART +// doesn't support block mappings, so L2 entries can never cause a mapping +// without a subsequent L3 entry. +static void clear_mappings(dart_t *dart) +{ + unsigned int i, j; + dart_l2_tt_t *l2_tt; + dart_ent *l3_tt_base; + + for (i = 0; i < DART_NUM_TTBR; i++) { + + l2_tt = dart->l2_tts[i]; + if (l2_tt == NULL) + continue; + + for (j = 0; j < DART_TTE_PGENTRIES; j++) { + l3_tt_base = l2_tt->l3_tt_bases[j]; + + if (l3_tt_base != NULL) + memset(l3_tt_base, 0, DART_TT_PGSIZE); + } + } +} + +void dart_init(unsigned int dart_id) +{ + dart_t *dart; + uint32_t reg; + + ASSERT(dart_id < NUM_DARTS); + dart = &darts[dart_id]; + + switch (dart_id) + { +#ifdef DART0_BASE_ADDR + case 0: + dart->regs = DART0_BASE_ADDR; + dart->addr_mask = DART0_ADDR_MASK; + break; +#endif +#ifdef DART1_BASE_ADDR + case 1: + dart->regs = DART1_BASE_ADDR; + dart->addr_mask = DART1_ADDR_MASK; + break; +#endif +#ifdef DART2_BASE_ADDR + case 2: + dart->regs = DART2_BASE_ADDR; + dart->addr_mask = DART2_ADDR_MASK; + break; +#endif +#ifdef DART3_BASE_ADDR + case 3: + dart->regs = DART3_BASE_ADDR; + dart->addr_mask = DART3_ADDR_MASK; + break; +#endif + default: + panic("Unknown DART index %d", dart_id); + break; + } + + // If the DART has previously been initialized, we need to clear out all mappings + // This will be a quick no-op if the DART hasn't been initialized + clear_mappings(dart); + + // If for some reason translation gets disabled, bypass to an invalid + // address instead of DRAM + rDART_BYPASS_ADDR(dart->regs) = 0; + + rDART_DIAG_BOGUS_ACCESS(dart->regs) = ERR_REFLECTION_BASE_ADDR >> 12; + + // Tunables + rDART_DIAG_CONFIG(dart->regs) |= DART_DIAG_CONFIG_PTE_FETCH_PROMOTE_QOS; + reg = rDART_FETCH_REQ_CONFIG(dart->regs); + reg &= ~DART_FETCH_REQ_CONFIG_STE(0xf); + reg |= DART_FETCH_REQ_CONFIG_STE(0x3); + reg &= ~DART_FETCH_REQ_CONFIG_PTE(0xf); + reg |= DART_FETCH_REQ_CONFIG_PTE(0x3); + reg &= ~DART_FETCH_REQ_CONFIG_PTE_PREFETCH(0xf); + reg |= DART_FETCH_REQ_CONFIG_PTE_PREFETCH(0xe); + rDART_FETCH_REQ_CONFIG(dart->regs) = reg; + + // Restore TTBRs if we were previously enabled, otherwise initialize + // all the TTBRs to 0 + dart_enable_translation(dart_id); + + // Enable translation and exceptions for SID 0 + rDART_CONFIG(dart->regs) = 0x80; +} + +/* Disables all TTBRs and flushes the TLB, but leaves translation enabled. This will + * make sure that all translation attempts result in an error. If we disabled translation, + * all translation attempts would go to the bypass address, which is not what we want */ +void dart_disable_translation(unsigned int dart_id) +{ + dart_t *dart; + int i; + + ASSERT(dart_id < NUM_DARTS); + dart = &darts[dart_id]; + + for (i = 0; i < DART_NUM_TTBR; i++) + rDART_TTBR(dart->regs, i) = 0; + + flush_tlb(dart); +} + +/* Re-enables mappings that were previously created with dart_map_page_range by reprogramming + * the DART's TTBRs with the previously created translation tables */ +void dart_enable_translation(unsigned int dart_id) +{ + uint32_t i; + uint32_t ttbr; + dart_t *dart; + dart_l2_tt_t *l2_tt; + + ASSERT(dart_id < NUM_DARTS); + dart = &darts[dart_id]; + + for (i = 0; i < DART_NUM_TTBR; i++) { + l2_tt = dart->l2_tts[i]; + + if (l2_tt == NULL) { + ttbr = 0; + } else { + ttbr = (l2_tt->tt_phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID; + } + + rDART_TTBR(dart->regs, i) = ttbr; + } + + flush_tlb(dart); +} + +void dart_map_page_range(unsigned int dart_id, uintptr_t paddr, dart_iovm_addr_t vaddr, uint32_t pages, bool write_protect) +{ + uint32_t ttbr; + uint32_t i; + dart_iovm_addr_t page_vaddr; + uintptr_t page_paddr; + dart_ent ent; + dart_t *dart; + + ASSERT(dart_id < NUM_DARTS); + dart = &darts[dart_id]; + + ASSERT((vaddr & DART_TT_L3_OFFMASK) == 0); + ASSERT((paddr & DART_TT_L3_OFFMASK) == 0); + + page_vaddr = vaddr & dart->addr_mask; + page_paddr = paddr; + + dprintf(DEBUG_SPEW, "dart%d: mapped 0x%04x pages at iovm 0x%08x to phys %p\n", dart_id, pages, vaddr, (void *)paddr); + + for (i = 0; i < pages; i++) { + uint32_t l1_index = (page_vaddr & DART_TT_L1_INDEX_MASK) >> DART_TT_L1_SHIFT; + uint32_t l2_index = (page_vaddr & DART_TT_L2_INDEX_MASK) >> DART_TT_L2_SHIFT; + uint32_t l3_index = (page_vaddr & DART_TT_L3_INDEX_MASK) >> DART_TT_L3_SHIFT; + dart_l2_tt_t *l2_tt; + dart_ent *l3_tt; + + if (dart->l2_tts[l1_index] == NULL) { + dart_ent *new_tt; + uintptr_t new_tt_phys; + + new_tt = alloc_tt_page(); + new_tt_phys = mem_static_map_physical((uintptr_t)new_tt); + dart->l2_tts[l1_index] = calloc(1, sizeof(dart_l2_tt_t)); + dart->l2_tts[l1_index]->tt_base = new_tt; + dart->l2_tts[l1_index]->tt_phys = new_tt_phys; + + ttbr = (new_tt_phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID; + rDART_TTBR(dart->regs, l1_index) = ttbr; + } + l2_tt = dart->l2_tts[l1_index]; + + if (l2_tt->l3_tt_bases[l2_index] == NULL) { + dart_ent *new_tt = alloc_tt_page(); + l2_tt->l3_tt_bases[l2_index] = new_tt; + + ent = ((uintptr_t)mem_static_map_physical((uintptr_t)new_tt)) | DART_TTE_TABLE | DART_TTE_VALID; + l2_tt->tt_base[l2_index] = ent; + } + l3_tt = l2_tt->l3_tt_bases[l2_index]; + + RELEASE_ASSERT(l3_tt[l3_index] == 0); + + ent = page_paddr | DART_PTE_WRPROT(write_protect) | DART_PTE_TYPE_VALID; + l3_tt[l3_index] = ent; + + page_vaddr += DART_TT_L3_SIZE; + page_paddr += DART_TT_L3_SIZE; + } + + flush_tlb(dart); +} + +void dart_unmap_page_range(unsigned int dart_id, dart_iovm_addr_t vaddr, uint32_t pages) +{ + uint32_t i; + dart_iovm_addr_t page_vaddr; + dart_t *dart; + + ASSERT(dart_id < NUM_DARTS); + dart = &darts[dart_id]; + + ASSERT((vaddr & DART_TT_L3_OFFMASK) == 0); + + dprintf(DEBUG_SPEW, "dart%d: unmapped 0x%04x pages at iovm 0x%08x\n", dart_id, pages, vaddr); + + page_vaddr = vaddr & dart->addr_mask; + + for (i = 0; i < pages; i++) { + uint32_t l1_index = (page_vaddr & DART_TT_L1_INDEX_MASK) >> DART_TT_L1_SHIFT; + uint32_t l2_index = (page_vaddr & DART_TT_L2_INDEX_MASK) >> DART_TT_L2_SHIFT; + uint32_t l3_index = (page_vaddr & DART_TT_L3_INDEX_MASK) >> DART_TT_L3_SHIFT; + dart_l2_tt_t *l2_tt; + dart_ent *l3_tt; + + l2_tt = dart->l2_tts[l1_index]; + RELEASE_ASSERT(l2_tt != NULL); + + l3_tt = l2_tt->l3_tt_bases[l2_index]; + RELEASE_ASSERT(l3_tt != NULL); + + l3_tt[l3_index] = 0; + + page_vaddr += DART_TT_L3_SIZE; + } + + flush_tlb(dart); +} + +void dart_write_protect_page_range(unsigned int dart_id, dart_iovm_addr_t vaddr, uint32_t pages, bool write_protect) +{ + uint32_t i; + dart_iovm_addr_t page_vaddr; + dart_ent ent; + dart_t *dart; + + ASSERT(dart_id < NUM_DARTS); + dart = &darts[dart_id]; + + ASSERT((vaddr & DART_TT_L3_OFFMASK) == 0); + + page_vaddr = vaddr; + + for (i = 0; i < pages; i++) { + uint32_t l1_index = (page_vaddr & DART_TT_L1_INDEX_MASK) >> DART_TT_L1_SHIFT; + uint32_t l2_index = (page_vaddr & DART_TT_L2_INDEX_MASK) >> DART_TT_L2_SHIFT; + uint32_t l3_index = (page_vaddr & DART_TT_L3_INDEX_MASK) >> DART_TT_L3_SHIFT; + dart_l2_tt_t *l2_tt; + dart_ent *l3_tt; + + l2_tt = dart->l2_tts[l1_index]; + RELEASE_ASSERT(l2_tt != NULL); + + l3_tt = l2_tt->l3_tt_bases[l2_index]; + RELEASE_ASSERT(l3_tt != NULL); + + ent = l3_tt[l3_index]; + ent &= DART_PTE_PAGE_MASK; + ent |= DART_PTE_WRPROT(write_protect); + l3_tt[l3_index] = ent; + + page_vaddr += DART_TT_L3_SIZE; + } + + flush_tlb(dart); +} + +// Verifies that all mappings have been removed from the DART. This is used +// to verify that drivers aren't leaking mappings, as leaked mappings could +// lead to a security hole +void dart_assert_unmapped(unsigned int dart_id) +{ + dart_t *dart; + unsigned int i, j, k; + dart_l2_tt_t *l2_tt; + dart_ent *l3_tt_base; + + ASSERT(dart_id < NUM_DARTS); + dart = &darts[dart_id]; + + for (i = 0; i < DART_NUM_TTBR; i++) { + // If the driver isn't tracking an L2 table under the given TTBR, + // then, the TTBR needs to be 0 + l2_tt = dart->l2_tts[i]; + if (l2_tt == NULL) { + RELEASE_ASSERT(rDART_TTBR(dart->regs, i) == 0); + continue; + } + + // For each L2 table, verify each entry is either 0 or points + // to an L3 table filled with 0s + for (j = 0; j < DART_TTE_PGENTRIES; j++) { + l3_tt_base = l2_tt->l3_tt_bases[j]; + + if (l3_tt_base != NULL) { + for (k = 0; k < DART_TTE_PGENTRIES; k++) { + RELEASE_ASSERT(l3_tt_base[k] == 0); + } + } else { + RELEASE_ASSERT(l2_tt->tt_base[j] == 0); + } + } + } +} diff --git a/drivers/apple/dart_lpae/dart_regs.h b/drivers/apple/dart_lpae/dart_regs.h new file mode 100644 index 0000000..abe7696 --- /dev/null +++ b/drivers/apple/dart_lpae/dart_regs.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef DART_REGS_H +#define DART_REGS_H + +#define DART_TT_PGSIZE 4096 +#define DART_TTE_SHIFT 3 +#define DART_TTE_PGENTRIES (DART_TT_PGSIZE >> DART_TTE_SHIFT) + +#define DART_TTE_VALID (1 << 0) +#define DART_TTE_TABLE (1 << 1) + +#define DART_NUM_TTBR 4 +#define DART_NUM_SID 4 + +#define rDART_TLB_OP(base) (*(volatile uint32_t *)((base) + 0x00)) +#define rDART_CONFIG(base) (*(volatile uint32_t *)((base) + 0x0c)) +#define rDART_DIAG_CONFIG(base) (*(volatile uint32_t *)((base) + 0x20)) +#define rDART_DIAG_BOGUS_ACCESS(base) (*(volatile uint32_t *)((base) + 0x24)) +#define rDART_BYPASS_ADDR(base) (*(volatile uint32_t *)((base) + 0x2c)) +#define rDART_FETCH_REQ_CONFIG(base) (*(volatile uint32_t *)((base) + 0x30)) +#define rDART_TTBR(base, idx) (*(volatile uint32_t *)((base) + 0x40 + 4 * (idx))) + +#define DART_TLB_OP_FLUSH (2) +#define DART_TLB_OP_BUSY (1 << 3) +#define DART_TLB_OP_SID_MASK0 (1 << 8) +#define DART_TLB_OP_SID_MASK1 (1 << 9) +#define DART_TLB_OP_SID_MASK2 (1 << 10) +#define DART_TLB_OP_SID_MASK3 (1 << 11) + +#define DART_DIAG_CONFIG_PTE_FETCH_PROMOTE_QOS (1 << 8) + +#define DART_FETCH_REQ_CONFIG_STE(x) (((x) & 0xf) << 0) +#define DART_FETCH_REQ_CONFIG_PTE(x) (((x) & 0xf) << 8) +#define DART_FETCH_REQ_CONFIG_PTE_PREFETCH(x) (((x) & 0xf) << 16) + +#define DART_TTBR_VALID (1 << 31) +#define DART_TTBR_SHIFT (12) + +/* + * L1 Translation table (stored in registers) + * + * There are DART_NUM_TTBR entries in the L1 table + * DART_NUM_TTBR entries of 1GB (2^30) of address space. + */ +#define DART_TT_L1_SIZE 0x0000000040000000ULL /* size of area covered by a tte */ +#define DART_TT_L1_OFFMASK 0x000000003fffffffULL /* offset within an L2 entry */ +#define DART_TT_L1_SHIFT 30 +#define DART_TT_L1_INDEX_MASK 0x0000000070000000ULL /* mask for getting index in L1 table from virtual address */ + +/* + * L2 Translation table + * + * Each translation table is 4KB + * 512 64-bit entries of 2MB (2^21) of address space. + */ + +#define DART_TT_L2_SIZE 0x0000000000200000ULL /* size of area covered by a tte */ +#define DART_TT_L2_OFFMASK 0x00000000001fffffULL /* offset within an L2 entry */ +#define DART_TT_L2_SHIFT 21 /* page descriptor shift */ +#define DART_TT_L2_INDEX_MASK 0x000000003fe00000ULL /* mask for getting index in L2 table from virtual address */ + +/* + * L3 Translation table + * + * Each translation table is 4KB + * 512 64-bit entries of 4KB (2^12) of address space. + */ + +#define DART_TT_L3_SIZE 0x0000000000001000ULL /* size of area covered by a tte */ +#define DART_TT_L3_OFFMASK 0x0000000000000fffULL /* offset within L3 PTE */ +#define DART_TT_L3_SHIFT 12 /* page descriptor shift */ +#define DART_TT_L3_INDEX_MASK 0x00000000001ff000ULL /* mask for page descriptor index */ + +/* + * L3 Page table entries + * + * The following page table entry types are possible: + * + * fault page entry + * 63 2 0 + * +------------------------------+--+ + * | ignored |00| + * +------------------------------+--+ + * + * + * 63 52 51 36 35 12 11 8 7 6 2 1 0 + * +-----+------+----------------------+-----+-+-----+-+-+ + * | ign | zero | OutputAddress[35:12] | ign |W| ign |1|V| + * +-----+------+----------------------+-----+-+-----+-+-+ + * + * where: + * 'W' Write orotect bit + * 'V' Valid bit + */ + +#define DART_PTE_SHIFT 3 +#define DART_PTE_PGENTRIES (DART_TT_PGSIZE >> DART_PTE_SHIFT) + +#define DART_PTE_EMPTY 0x0000000000000000ULL /* unasigned - invalid entry */ + +#define DART_PTE_TYPE_VALID 0x0000000000000003ULL /* valid L3 entry: includes bit #1 (counterintuitively) */ + +#define DART_PTE_PAGE_MASK 0x0000FFFFFFFFF000ULL /* mask for 4KB page */ +#define DART_PTE_PAGE_SHIFT 12 /* page shift for 4KB page */ + +#define DART_PTE_WRPROT(enable) ((enable) ? (1 << 7) : 0) /* write protect */ + +#endif // DART_REGS_H diff --git a/drivers/apple/dart_lpae/rules.mk b/drivers/apple/dart_lpae/rules.mk new file mode 100644 index 0000000..ed242c3 --- /dev/null +++ b/drivers/apple/dart_lpae/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DART=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dart.o diff --git a/drivers/apple/dcs/dcs.c b/drivers/apple/dcs/dcs.c new file mode 100644 index 0000000..fb2627a --- /dev/null +++ b/drivers/apple/dcs/dcs.c @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void mcu_late_init(void) +{ +} + +uint32_t density_to_Gb(int density) +{ + switch (density) { + case JEDEC_LPDDR4_DENSITY_4Gb: + return 4; + case JEDEC_LPDDR4_DENSITY_6Gb: + return 6; + case JEDEC_LPDDR4_DENSITY_8Gb: + return 8; + case JEDEC_LPDDR4_DENSITY_12Gb: + return 12; + case JEDEC_LPDDR4_DENSITY_16Gb: + return 16; + case JEDEC_LPDDR4_DENSITY_24Gb: + return 24; + case JEDEC_LPDDR4_DENSITY_32Gb: + return 32; + default: + panic("unknown LPDDR4 density %d", density); + } +} + +static struct dcs_memory_device_info _dcs_device_info; +static bool _dcs_device_info_inited; + +const struct dcs_memory_device_info *dcs_get_memory_device_info(void) +{ + // if memory is not inited, device info is unknown, spin here ... + if (false == _dcs_device_info_inited) + panic("DCS Memory Device Info grab has jumped the gun"); + + return ((const struct dcs_memory_device_info *)&_dcs_device_info); +} + +// Returns memory size per amcc block +uint64_t dcs_get_memory_size(void) +{ + // if memory is not inited, density is unknown, spin here ... + if (false == _dcs_device_info_inited) + panic("DCS Memory Size grab has jumped the gun"); + + // device density (in MBytes) * ( / 2 due to x16 lpddr4 devices) * num of channels * num of ranks + return (density_to_Gb(_dcs_device_info.density) * (1024 / 8 / 2) * DCS_NUM_CHANNELS * DCS_NUM_RANKS); +} + +uint32_t dcs_get_memory_info(void) +{ + uint8_t config_id = 0; + + // Read device info: vendor, revision, and configuration info + // Configuration info: device width, device type, device density + // We are assuming all of our devices are identical + dcs_mrcmd(MR_READ, 1, 1, 0x5, (uintptr_t)&_dcs_device_info.vendor_id); + dcs_mrcmd(MR_READ, 1, 1, 0x6, (uintptr_t)&_dcs_device_info.rev_id); + dcs_mrcmd(MR_READ, 1, 1, 0x7, (uintptr_t)&_dcs_device_info.rev_id2); + dcs_mrcmd(MR_READ, 1, 1, 0x8, (uintptr_t)&config_id); + + if ((_dcs_device_info.vendor_id == 0) || (config_id == 0)) + panic("failed to read vendor-id/config-id, vid:%08x, config:%08x, rev:%08x\n", + _dcs_device_info.vendor_id, config_id, _dcs_device_info.rev_id); + + _dcs_device_info.width = (32 >> ((config_id >> JEDEC_MR8_WIDTH_SHIFT) & JEDEC_MR8_WIDTH_MASK)) >> 3; + _dcs_device_info.density = ((config_id >> JEDEC_MR8_DENSITY_SHIFT) & JEDEC_MR8_DENSITY_MASK); + _dcs_device_info.type = ((config_id >> JEDEC_MR8_TYPE_SHIFT) & JEDEC_MR8_TYPE_MASK); + + _dcs_device_info_inited = true; + + uint32_t device_size_Gbits = density_to_Gb(_dcs_device_info.density); + uint32_t total_size_Mbytes = dcs_get_memory_size(); + + dprintf(DEBUG_INFO, "sdram vendor id:0x%02x rev id:0x%02x rev id2:%02x\n", + _dcs_device_info.vendor_id, _dcs_device_info.rev_id, _dcs_device_info.rev_id2); + dprintf(DEBUG_INFO, "sdram config: width %d/%d Gbit/type %d\n", _dcs_device_info.width << 3, + device_size_Gbits, _dcs_device_info.type); + + // Check against Hardware Register Min/Max + if (total_size_Mbytes < 128 || total_size_Mbytes > (16 * 1024) ) + panic("unsupported DRAM density: %d Gbit (with Chan==%d x Rank==%d yields %d MB)", + device_size_Gbits, DCS_NUM_CHANNELS, DCS_NUM_RANKS, total_size_Mbytes); + + return 0; +} + +//================================================================================ +void dcs_change_freq(uint32_t freq_bin) +{ + // Change the MCU Clk Frequency to the new Frequency + dbgprintf(DCS_DBG_FREQ, "Changing Frequency to Bin %d\n", freq_bin); + + // Make the actual Change by sending the appropriate message to the PMGR + uint32_t perf_level = (freq_bin == 0)? kPerformanceMemoryFull: + (freq_bin == 1)? kPerformanceMemoryMid: + (freq_bin == 3)? kPerformanceMemoryLow: + DCS_NONVAL; + if (perf_level == DCS_NONVAL) { + shim_panic("Unsupported Frequency Bin Request: %d\n", freq_bin); + } + + clocks_set_performance(perf_level); +} + +//================================================================================ +void dcs_store_memory_calibration(void *cal_values, uint32_t cal_size) +{ + // Save the calibration array to PMU nvram +#if 0 + if (power_store_memory_calibration(cal_values, cal_size) == 0) + shim_panic("Unable to save memory calibration values to PMU nvram\n"); +#endif +} + +void dcs_load_memory_calibration(void *cal_values, uint32_t cal_size) +{ + // Retrieve calibration array from PMU nvram +#if 0 + if (power_load_memory_calibration(cal_values, cal_size) == 0) + shim_panic("Unable to load memory calibration values from PMU nvram\n"); +#endif +} + +// To dump calibration results from iBoot menu command +static int dump_mem_calibration_info(int argc, struct cmd_arg *args) +{ + dcs_init_debug_enable(DCS_DBG_CAL); + debug_level_dcs = DEBUG_CRITICAL; + calibration_cfg_params_init(false, DCS_NUM_CHANNELS, DCS_NUM_RANKS); + calibration_dump_results(SELECT_CAL_ALL, false); + return 0; +} +MENU_COMMAND_DEBUG(memcal_info, dump_mem_calibration_info, "Prints memory calibration results", NULL); + +//================================================================================ +//////////////////////////////////////////////////////////// +// +// DCS Init Sequence +// Incorporates these specs from SEG + +// Maui: Init_A1.html dated Mar 2, 2015, Init_B0.html dated May 20, 2015, Init_B0_1200.html dated June 2, 2015, Init_1200.html dated Oct 29, 2015 + +// Elba: Init.html dated March 04, 2016, Init_A0.html dated July 14 15, 2015 + +// s8003: Init_A0.html dated May 20, 2015, Init_A0_1200.html dated June 17, 2015, Init_1200.html dated Oct 29, 2015 + +// M8: Init.html dated Apr 2, 2015 + +// Cayman: Init.html dated Feb 18, 2015 + +//////////////////////////////////////////////////////////// + +int32_t dcs_init(dcs_boottype_t boot_type) +{ + uint32_t num_dcs = DCS_NUM_CHANNELS; + uint32_t num_rnk = DCS_NUM_RANKS; + dcs_config_params_t *param_table; +#ifndef DCS_RUN_AT_50MHZ + volatile uint32_t *cal_results_save_addr = (volatile uint32_t *) MEMORY_CALIB_SAVE_BASE_ADDR; +#if DCS_DO_CALIBRATION + struct amp_calibration_params *cal_cfg = NULL; +#endif // #if DCS_DO_CALIBRATION +#endif // #ifndef DCS_RUN_AT_50MHZ + + dprintf(DEBUG_INFO, "dcs_init() ... !\n"); + + // Config our boot type and note the ChipID/Rev + if (!dcs_init_config(boot_type, platform_get_chip_id(), platform_get_chip_revision(), + num_dcs, num_rnk)) { + panic("DCS Init Config is NOT RIGHT"); + } + + dcs_init_debug_enable(DCS_DBG_OVERVIEW); + dcs_init_debug_enable(DCS_DBG_MILESTONE); + // dcs_init_debug_enable(DCS_DBG_REG_ACCESS); + // dcs_init_debug_enable(DCS_DBG_CHAN_DETAIL); + // dcs_init_debug_enable(DCS_DBG_SPIN); + // dcs_init_debug_enable(DCS_DBG_MR_READ); + // dcs_init_debug_enable(DCS_DBG_CAL); + dcs_init_debug_enable(DCS_DBG_CAL_MILESTONE); + + dcs_init_debug_enable(DCS_DBG_FREQ); + + // Initialize the DCS Parameter Table (uses platform-specific callout) + param_table = dcs_init_param_table(); + +// Maui/Malta/Elba: Reset DRAM during panic reboot in LLB to avoid problems with init sequence +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 || SUB_PLATFORM_S8001 +#if WITH_HW_POWER + int result; + uint8_t boot_stage; + + // If we rebooted to save panic log, try resetting the DRAM to reset the FSP on the DRAM + result = power_get_nvram(kPowerNVRAMiBootErrorStageKey, &boot_stage); + + // if we properly read the PMU NVRAM and it says we are booting to save panic log ... + if(result == 0 && boot_stage == kPowerNVRAMiBootStagePanicSave) { + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0); + // Leave reset asserted for 200 us + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + // Wait 2 ms before starting mem init sequence + delay_for_us(2000); + } +#endif +#endif + + //================================================================================ + // Step 0: AMC Prolog + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 0, "Prolog"); + dcs_init_Prolog(); + + //================================================================================ + // Step 1: AMC Initial Configuration + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 1, "Initial AMC Config"); + dcs_init_AMC_Initial_Config(); + + //================================================================================ + // Step 2: AMP Initial Configuration + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 2, "AMP Initial Config"); + dcs_init_AMP_Initial_Config(); + + //================================================================================ + // Step 3: Self-Refresh Exit + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 3, "Self-Refresh Exit"); + dcs_init_Self_Refresh_Exit_a(); + + if (izColdBoot && !izFPGA) { + // Change MCU Clk --> 50Mz + dcs_change_freq(3); + + // Wait 5 us after Switch to 50MHz to avoid race condition + dcs_spin(5, "after 50MHz\n"); + } + + dcs_init_Self_Refresh_Exit_b(); + + //================================================================================ + // Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only) + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 4, "ZQ Calibration & Configuration"); + dcs_init_ZQ_Cal_Cfg(); + + //================================================================================ + // Step 5: Topology-specific configuration + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 5, "Memory Topology Config"); + dcs_init_AddrCfg_Cfg(); + + dcs_get_memory_info(); + uint32_t total_size_Mbytes = dcs_get_memory_size(); + + dcs_init_TotalSize_Cfg(total_size_Mbytes); + + // DRAM vendor-specific workarounds + dcs_dram_workarounds(boot_type); + + //================================================================================ + // Step 6: Prepare for switch from boot-clock speed to normal operation speed + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 6, "Reenable_AMC_Scheduler"); + dcs_init_Reenable_AMC_Scheduler(); + +#if DCS_RUN_AT_50MHZ + dprintf(DEBUG_CRITICAL, "DCS Init: memory frequency fixed to 50 MHz\n"); +#else + +#if DCS_DO_CALIBRATION + cal_cfg = calibration_cfg_params_init(izResume, num_dcs, num_rnk); + + // Override the chip_id and chip_rev default values with actual values + cal_cfg->chip_id = platform_get_chip_id(); + cal_cfg->chip_rev = platform_get_chip_revision(); + + // Coarse CS training disabled on Maui A0/A1 + if(cal_cfg->chip_id == 0x8000 && cal_cfg->chip_rev < CHIP_REVISION_B0) + cal_cfg->disable_coarse_cs_training = true; + + cal_cfg->clk_period_bin0 = param_table->freq[0].clk_period; + cal_cfg->clk_period_bin1 = param_table->freq[1].clk_period; + + // Note if we will use Widest-Eye for calculating Optimal Vref + if (dcs_init_variant_enable(0) & DCS_VARIANT_VREF_USES_WIDEST) { + cal_cfg->opt_vref_mode = DCS_CAL_OPT_VREF_MODE_WIDEST; + } + + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: Config Init'd\n"); +#endif + + // Only perform steps 7-10 if frequequency bucket 1 is supported + if(param_table->supported_freqs & DCS_FREQ(1)) { + + //================================================================================ + // Step 7: Setup registers for CA calibration for bucket 1 + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 7, "CA Calibration Setup--800MHz"); + dcs_init_CA_Cal_Setup_Freq1(); + + //================================================================================ + // Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 8, "CA Vref Calibration--800MHz, Vmin"); + +#if DCS_DO_CALIBRATION + // Use these values for 800MHz + cal_cfg->RL = 16; + cal_cfg->WL = 12; + // We will be calibrating for @800MHz (FreqBin 1) + cal_cfg->freq_bin = 1; + + if (izColdBoot) { + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d CA Cal\n", cal_cfg->freq_bin); + calibrate_ca(); + } else { + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d Cal Regs Restore\n", cal_cfg->freq_bin); + // Restore Calibration Parameters from PMU + calibration_save_restore_ca_wrlvl_regs(CALIB_RESTORE, num_dcs, cal_cfg->freq_bin); + } +#else + dbgprintf(DCS_DBG_MILESTONE, "DCS is Skipping Calibration, per Build Config\n"); +#endif + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 8, "Post CA Vref Calibration"); + dcs_init_CA_Cal_Freq1(); + + //================================================================================ + // Step 9: Setup registers for DQ calibration for bucket 1 + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 9, "DQ Calibration Setup--800MHz"); + dcs_init_DQ_Cal_Setup_Freq1_a(); + + // Change MCU Clk --> bucket 1 + if(!izFPGA) + dcs_change_freq(1); + + dcs_init_DQ_Cal_Setup_Freq1_b(); + + //================================================================================ + // Step 10: PHY write DQ calibration + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 10, "Wr DQ Cal--800MHz"); + +#if DCS_DO_CALIBRATION + if (izColdBoot) { + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d WrLvl\n", cal_cfg->freq_bin); + calibrate_wrlvl(); + + dcs_init_post_wrlvl(); + + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d Cal Regs Save\n", cal_cfg->freq_bin); + // Save Calibration Parameters (so far) to Memory Stash + calibration_save_restore_ca_wrlvl_regs(CALIB_SAVE, num_dcs, cal_cfg->freq_bin); + + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d RdDQ Cal\n", cal_cfg->freq_bin); + calibrate_rddq(); + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d WrDQ Cal\n", cal_cfg->freq_bin); + calibrate_wrdq(); + } +#else + dbgprintf(DCS_DBG_MILESTONE, "DCS is Skipping Calibration, per Build Config\n"); +#endif + + dcs_init_wrdq_skew(); + + cal_results_save_addr = dcs_save_calibration_results(cal_results_save_addr, DCS_FREQ(1)); + } // if(param_table->supported_freqs & DCS_FREQ1) { + + //================================================================================ + // Step 11: Setup registers for CA calibration for bucket 0 + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 11, "CA Vref Calibration Setup--1200MHz"); + dcs_init_CA_Cal_Setup_Freq0(); + + //================================================================================ + // Step 12: AMP Dynamic CA Timing Calibration + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 12, "CA Vref Calibration--1200MHz, Vnom"); + +#if DCS_DO_CALIBRATION + + if(param_table->freq[0].clk_period == CLK_PERIOD_1600) { + // Use these values for 1600MHz + cal_cfg->RL = 28; + cal_cfg->WL = 14; + } else if(param_table->freq[0].clk_period == CLK_PERIOD_800) { + // Use these values for 800MHz + cal_cfg->RL = 14; + cal_cfg->WL = 12; + } else { + // Use these values for 1200MHz + cal_cfg->RL = 24; + cal_cfg->WL = 12; + } + + // We will be calibrating for FreqBin 0 + cal_cfg->freq_bin = 0; + + if (izColdBoot) { + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d CA Cal\n", cal_cfg->freq_bin); + calibrate_ca(); +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + dcs_dram_workarounds_step12(); +#endif + } +#else + dbgprintf(DCS_DBG_MILESTONE, "DCS is Skipping Calibration, per Build Config\n"); +#endif + + //================================================================================ + // Step 13: Setup registers for DQ calibration for bucket 0 + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 13, "DQ Calibration Setup--1200MHz"); + dcs_init_DQ_Cal_Setup_Freq0_a(); + + // Change MCU Clk --> bucket 0 + if(!izFPGA) + dcs_change_freq(0); + + dcs_init_DQ_Cal_Setup_Freq0_b(); + + //================================================================================ + // Step 14: AMP Dynamic DQ Calibration + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 14, "Wr DQ Cal--1200MHz, Vmin"); + +#if DCS_DO_CALIBRATION + if (izColdBoot) { + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d WrLvl\n", cal_cfg->freq_bin); + calibrate_wrlvl(); + + dcs_init_post_wrlvl(); + + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d Cal Regs Save\n", cal_cfg->freq_bin); + // Save Calibration Parameters (all the rest) to Memory Stash & then copy Stash to PMU + calibration_save_restore_ca_wrlvl_regs(CALIB_SAVE, num_dcs, cal_cfg->freq_bin); + + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d RdDQ Cal\n", cal_cfg->freq_bin); + calibrate_rddq(); + dbgprintf(DCS_DBG_CAL_MILESTONE, "DCS Cal: FreqBin %d WrDQ Cal\n", cal_cfg->freq_bin); + calibrate_wrdq(); + + // Save off any applicable freq 0 registers + cal_results_save_addr = dcs_save_calibration_results(cal_results_save_addr, DCS_FREQ(0)); + } +#else + dbgprintf(DCS_DBG_MILESTONE, "DCS is Skipping Calibration, per Build Config\n"); +#endif + +#endif // #if DCS_RUN_AT_50MHZ ... #else + + //================================================================================ + // Step 15: Setup Registers for Boot + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 15, "Setup Registers for Boot"); + dcs_init_Reg_for_Boot(); + + //================================================================================ + // Step 16: Enable Other Features + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 16, "Enable Other Features"); + dcs_init_MoreFeatures(); + + //================================================================================ + // Step 17: Enable Fast Critical Word Forwarding Feature + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 17, "Fast Critical Word Forwarding"); + dcs_init_Fast_Critical_Word_Forwarding(); + + //================================================================================ + // Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 18, "Gating and Global Timers"); + dcs_init_Gating_Global_Timers(); + + //================================================================================ + // Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Step %2d: %s\n", 19, "ODTS & Die Temp"); + dcs_init_ODTS(); + +// rdar://problem/23244578, : Allow zqctimer value to be saved at this point to reconfig sequence +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 || SUB_PLATFORM_S8001 +#ifndef DCS_RUN_AT_50MHZ + cal_results_save_addr = dcs_save_calibration_results(cal_results_save_addr, 0); +#endif +#endif + + //================================================================================ + // Program tunables at the end + //================================================================================ + dbgprintf(DCS_DBG_MILESTONE, "DCS Init Tunables\n"); + dcs_init_apply_tunables(); + + //================================================================================ + // Restore clock frequency to bucket 1 if it is supported + //================================================================================ + if(!izFPGA) + if(param_table->supported_freqs & DCS_FREQ(1)) + dcs_change_freq(1); + + // cache memory info for later + platform_set_memory_info_with_revids(_dcs_device_info.vendor_id, dcs_get_memory_size(), _dcs_device_info.rev_id, _dcs_device_info.rev_id2); + + dbgprintf(DCS_DBG_MILESTONE, "DCS Init DONE!!\n"); + return 0; +} + +//================================================================================ diff --git a/drivers/apple/dcs/dcs_calibration.c b/drivers/apple/dcs/dcs_calibration.c new file mode 100644 index 0000000..dcf6c0b --- /dev/null +++ b/drivers/apple/dcs/dcs_calibration.c @@ -0,0 +1,5070 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef ENV_IBOOT +#include +#elif defined ENV_DV +#include "dcs_shim.h" +#elif defined ENV_CFE +#include "cfe/amp_v3_shim.h" +#else +#error "Unidentified compilation environment for shared memory calibration code" +#endif + +#define MAX(X,Y) ((X > Y) ? X : Y) +#define MIN(X,Y) ((X < Y) ? X : Y) +#define NEGATE(X) (-1 * X) +#define POS(X) ((X < 0) ? 0 : X) + +// In non-DV environments, ROMCODE_SEGMENT & MCODE_SEGMENT prefixes would be empty +#ifdef ENV_DV + #ifndef AMS_SIM_ENV + #define _ROMCODE_SEGMENT_PREFIX ROMCODE_SEGMENT + #define _MCODE_SEGMENT_PREFIX MCODE_SEGMENT + #else + #define _ROMCODE_SEGMENT_PREFIX + #define _MCODE_SEGMENT_PREFIX + #endif +#else + #define _ROMCODE_SEGMENT_PREFIX + #define _MCODE_SEGMENT_PREFIX +#endif + +// PRBS7 patterns used for ca calibration. cfg_params.cacalib_sw_loops * cfg_params.cacalib_hw_loops must equal 64 +// We extend the size by 8 and repeat the first 8 values because when swloop=64, we don't go outside the array for programming CACALPAT1-7 +// CP : Maui Change- What would be the random CA patterns for Maui?? +// CP : Fix these arrays later + +// Used to store the values of DqsPdEn for frequency buckets 0-3 +_MCODE_SEGMENT_PREFIX static uint8_t DqsPdEn[DCS_NUM_CHANNELS][DQ_NUM_BYTES][4]; + +/* +_MCODE_SEGMENT_PREFIX static const uint32_t CA_PRBS7_PATTERNS[CA_NUM_PATTERNS + 8] = { + 0x2550B, 0xCF135, 0xC4342, 0x67BFF, 0x825A0, 0x1487E, 0x984EF, 0xEA43E, + 0x0B277, 0xA388D, 0xE5E5F, 0x96DDe, 0x8CC91, 0x720D1, 0xE1649, 0xA8ACA, + 0x466E2, 0x73381, 0x1A14F, 0xFEC40, 0x93698, 0x49C83, 0xEEC28, 0x35563, + 0x692CE, 0xE4D0F, 0x6DAD8, 0xDAA1B, 0xA70AB, 0xDB94B, 0x5C7AD, 0x8DFC1, + 0x897D7, 0xB70C3, 0x7DAB0, 0x7C9E0, 0x87EE6, 0xD186C, 0x04816, 0x3E714, + 0xCAA73, 0x01350, 0xFB706, 0x5668A, 0xD507A, 0x3AF02, 0xF4D67, 0xCB923, + 0xFA456, 0xAD18C, 0x836F0, 0xEEF78, 0xCE265, 0x3F444, 0x31D75, 0x575DA, + 0x2E77C, 0x6C988, 0x21D1D, 0xF1621, 0x0E931, 0x668AF, 0x792A6, 0x42EF4, + 0x2550B, 0xCF135, 0xC4342, 0x67BFF, 0x825A0, 0x1487E, 0x984EF, 0xEA43E, +}; +*/ + +// TODO TODO : What would be the final +// 1. Vref values & ranges for CA, RDDQ & WRDQ +// 2. Patter and invert masks for PRBS4I. + +_MCODE_SEGMENT_PREFIX static uint32_t mdllcode[DCS_NUM_CHANNELS][3]; // 1 for each AMP_DQ, and 1 for AMP_CA +_MCODE_SEGMENT_PREFIX static uint32_t mdllcode_freq_bin_1[DCS_NUM_CHANNELS]; // Save MDLL code used for Bin 1 CA calibration. +_MCODE_SEGMENT_PREFIX static uint32_t cacal_patterns_mask[CA_NUM_PATTERNS]; + +// This array will hold the calibration values to be saved for resume boot. +// Size is CALIB_PMU_BYTES, as this is the max space available in PMU for calibration, in iBoot environment +_MCODE_SEGMENT_PREFIX static uint8_t cal_bits[CALIB_PMU_BYTES] = { 0 }; + +/* + * Following global arrays will record passing points for calibration operations + */ + +// Used to save calibration values for each bit per channel and rank for every iteration +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_loopchrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_VREF_MAX][CA_NUM_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_loopchrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_VREF_MAX][CA_NUM_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_loopchrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_loopchrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; + +// Used to record values from CS training which will be used in CA training +_MCODE_SEGMENT_PREFIX static uint32_t cksdll_cscal[CA_NUM_VREF_MAX]; +_MCODE_SEGMENT_PREFIX static uint32_t cssdll_cscal[CA_NUM_VREF_MAX]; +_MCODE_SEGMENT_PREFIX static uint32_t casdll_cscal[CA_NUM_VREF_MAX]; + +// cs data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// ca data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS][CA_NUM_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS][CA_NUM_BITS]; + +// wrlvl data aggregated over all iterations, we save value for 4 byte lanes + the ca value +_MCODE_SEGMENT_PREFIX static uint32_t wrlvlcal_per_chrnk_rise[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES + 1]; +_MCODE_SEGMENT_PREFIX static uint32_t wrlvlcal_per_chrnk_fall[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES + 1]; + +// rddq data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t rddqcal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS][RDDQ_NUM_VREF_MAX][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t rddqcal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS][RDDQ_NUM_VREF_MAX][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + +// wrdq data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t wrdqcal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS][WRDQ_NUM_VREF][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t wrdqcal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS][WRDQ_NUM_VREF][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + +// Indicates the optimal Vref value for CA calibration +// Along with Vref value, also save Vref range here +_MCODE_SEGMENT_PREFIX static uint32_t vref_opt_ca[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; + +// Indicates the optimal Vref value for RDDQ calibration +// Along with Vref value, also save Vref range here +_MCODE_SEGMENT_PREFIX static uint32_t vref_opt_rddq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the optimal Vref value for WRDQ calibration +// Along with Vref value, also save Vref range here +_MCODE_SEGMENT_PREFIX static uint32_t vref_opt_wrdq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the final center values for CA calibration +_MCODE_SEGMENT_PREFIX static int32_t cntr_opt_ca[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; + +// Indicates the final center values for RDDQ calibration +_MCODE_SEGMENT_PREFIX static int32_t cntr_opt_rddq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the final center values for WRDQ calibration +_MCODE_SEGMENT_PREFIX static int32_t cntr_opt_wrdq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the value of CAWRLVL SDLL after Write Leveling is done and before WRDQ calibration +_MCODE_SEGMENT_PREFIX static uint32_t cawrlvl_sdll_wrlvl[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the value of WRDQWRLVL SDLL before Write Leveling is done. +_MCODE_SEGMENT_PREFIX static uint32_t dqwrlvl_sdll_before_wrlvl[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES] = { { 0 } }; + +// Indicates the value of WRDQWRLVL SDLL after Write Leveling is done and before WRDQ calibration +_MCODE_SEGMENT_PREFIX static uint32_t dqwrlvl_sdll_after_wrlvl[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES]; + +// Indicates the final CA/CS calibrated values in Bucket1 +_MCODE_SEGMENT_PREFIX static uint32_t cksdll_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS] = { 0 }; +_MCODE_SEGMENT_PREFIX static uint32_t cssdll_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS] = { 0 }; +_MCODE_SEGMENT_PREFIX static uint32_t casdll_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS] = { 0 }; +_MCODE_SEGMENT_PREFIX static uint32_t cadeskew_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS][CA_NUM_BITS] = {{ 0 }}; + +// Indicates if there was any panic at a given Vref setting +_MCODE_SEGMENT_PREFIX static int32_t cacal_vref_panic[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_VREF_MAX] = { { 0 } }; +_MCODE_SEGMENT_PREFIX static int32_t rddqcal_vref_panic[DCS_NUM_CHANNELS * DCS_NUM_RANKS][RDDQ_NUM_VREF_MAX] = { { 0 } }; +_MCODE_SEGMENT_PREFIX static int32_t wrdqcal_vref_panic[DCS_NUM_CHANNELS * DCS_NUM_RANKS][WRDQ_NUM_VREF] = { { 0 } }; + +// Static local function declarations +static void amp_do_mdll_calib(uint32_t ch); +static void amp_setup_ca_cal(uint32_t ch, uint32_t rnk, uint32_t swloop); +static void run_soc_upd(uint32_t ch); +static void amp_init_ca_deskew(uint32_t ch); +static void amp_init_ca_cs_ck_sdll(uint32_t ch); +static void amp_init_wr_deskew(uint32_t ch); +static void amp_push_casdll_out(uint32_t ch, uint32_t casdll_ovr_val); +static void amp_push_cksdll_out(uint32_t ch, uint32_t cksdll_ovr_val); +static void amp_push_cssdll_out(uint32_t ch, uint32_t cssdll_ovr_val); +static void amp_program_ca_sdll(uint32_t ch, uint32_t casdll_val); +static void amp_program_ck_sdll(uint32_t ch, uint32_t cksdll_val); +static void amp_program_cs_sdll(uint32_t ch, uint32_t cssdll_val); +#if DCS_REG_VERSION == 1 +static void amp_set_dqs_idle_active(uint32_t ch, uint8_t byte); +static void amp_reset_dqs_idle_active(uint32_t ch, uint8_t byte); +#else +static void amp_set_dqs_idle_active(uint32_t ch, uint32_t freq_bin); +static void amp_reset_dqs_idle_active(uint32_t ch, uint32_t freq_bin); +#endif +static void amp_set_dqs_weak_pden(uint32_t ch, uint8_t freq_bin); +static void amp_reset_dqs_weak_pden(uint32_t ch, uint8_t freq_bin); +static void amp_enter_cacal_mode(uint32_t ch); +static void amp_exit_cacal_mode(uint32_t ch); +static void amp_run_cacal_vref(uint32_t ch); +static uint32_t amp_run_cacal(uint32_t ch, uint32_t training_mode); +static void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk); +static void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_ovr_val); +static void amp_program_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_wr_val); +static void amp_run_rddqcal(uint32_t ch); +static void amp_wrlvl_init(void); +static void amp_wrlvl_entry(uint32_t ch); +static void amp_wrlvl_exit(uint32_t ch, uint8_t freq_bin); +static void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset); +static void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset); +static void amp_program_cawrlvl_sdll(uint32_t ch, uint32_t cawrlvl_offset, uint32_t cawrlvlmax_offset); +static void amp_program_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t dqwrlvl_offset, uint32_t dqwrlvlmax_offset); +static void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun); +static void cacal_init_registers(); +static void cacal_generate_patterns_mask(void); +static void cacal_run_sequence(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t mask_bits, uint32_t swloop, uint32_t vref); +static void cacal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_program_cs_training_values(void); +static void cacal_program_final_values(void); +static void rddqcal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal); +static void rddqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal); +static void rddqcal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal); +static void rddqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal); +static void rddqcal_program_final_values(void); +static void wrlvlcal_push_to_0s_region(uint32_t ch, uint32_t rnk); +static void wrlvlcal_find_0to1_transition(uint32_t ch, uint32_t rnk); +static void wrlvlcal_find_1to0_transition(uint32_t ch, uint32_t rnk); +static void wrlvlcal_program_final_values(void); +static void amp_compute_opt_vref_cacal(uint32_t ch, uint32_t rnk, uint32_t swloop, uint32_t bitMax); +static void amp_compute_opt_vref_rddqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax); +static uint32_t rddqcal_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val); +static void amp_program_ca_vref(uint32_t ch, uint32_t vref, uint32_t vref_pulse_cnt); +static void amp_program_rddq_vref(uint32_t ch, uint32_t vref, uint32_t vref_pulse_cnt, uint8_t freq_bin); +static void amp_program_wrdq_vref(uint8_t chan, uint8_t rank, uint32_t vref, uint32_t vref_pulse_cnt); +static void wrdqcal_init_regs(uint8_t chan, uint8_t rank); +static int wrdqcal_set_half_clk_delay(uint32_t byte, uint32_t val); +static int wrdqcal_set_delay_point(uint32_t chan, uint32_t byte, int32_t point, bool result); +static int wrdqcal_set_delay_point_ovr(uint32_t chan, uint32_t byte, int32_t point); +static int wrdqcal_set_delay_point_res(uint32_t chan, uint32_t byte, int32_t point); +static uint32_t wrdqcal_assess_position(); +static uint8_t wrdqcal_solid_pass(uint32_t byte, int32_t point, int step, uint8_t max); +static uint8_t wrdqcal_all_bits_fail(uint32_t byte, int32_t point, int step, uint8_t max); +static void wrdqcal_find_perbit_skew(uint32_t byte, int edge, int step, int limit, int16_t *bit_edge); +static void wrdqcal_sequence(uint8_t chan, uint8_t rank); +static void amp_compute_opt_vref_wrdqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax); +static void wrdqcal_program_final_values(void); +static void amp_save_ca_bucket1(uint32_t ch); +static void amp_program_ca_bucket1(uint32_t ch); + +// Helper functions +static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val); +static int32_t find_wrdq_center_of_eye(int32_t left_pos_val, int32_t right_pos_val); +static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t left_or_right); +static void cal_save_value(uint8_t data, uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos); +static uint8_t cal_retrieve_value(uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos); +void amp_save_masterdll_values(); + +/////////////////////////////////////////////////////////////////////////////// +/* Global configuration parameters for calibration, setup is different for iBoot, DV, SiVal, PE */ +/////////////////////////////////////////////////////////////////////////////// +_MCODE_SEGMENT_PREFIX static struct amp_calibration_params cfg_params; + +/////////////////////////////////////////////////////////////////////////////// +////// Global functions +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX +struct amp_calibration_params *calibration_cfg_params_init( + int bootMode, int numChans, int numRanksPerChn) +{ + uint32_t i; + + // Set the calibration params. + + // chip_id and chip_rev are by default set to Maui B0 for SEG-DV, since they don't perform run time check + // iBoot will override with correct values at run time to support A1 and B0 + cfg_params.chip_id = 0x8000; + cfg_params.chip_rev = CHIP_REVISION_B0; + + cfg_params.num_channels = numChans; + cfg_params.num_ranks = numRanksPerChn; +#if ENV_DV + // Run one channel calibration in DV environment. + cfg_params.num_channels_runCalib = 1; // Only Calibrate one Channel +#else + cfg_params.num_channels_runCalib = numChans; // Calibrate All Channels +#endif + + // Maui Defaults + cfg_params.clk_period_bin0 = CLK_PERIOD_1200; + cfg_params.clk_period_bin1 = CLK_PERIOD_800; + + // + cfg_params.ca_num_vref_f0 = CA_NUM_VREF_F0; + cfg_params.rddq_num_vref_f0 = RDDQ_NUM_VREF_F0; + + cfg_params.ca_num_vref_f1 = CA_NUM_VREF_F1; + cfg_params.rddq_num_vref_f1 = RDDQ_NUM_VREF_F1; + cfg_params.wrdq_num_vref = WRDQ_NUM_VREF; + + cfg_params.wrdq_apply_NC_algorithm = false; + + for(i=0;i< cfg_params.ca_num_vref_f0;i++) { + cfg_params.ca_vref_values_f0[i] = 0xC + i; + } + + for(i=0;i< cfg_params.rddq_num_vref_f0;i++) { + cfg_params.rddq_vref_values_f0[i] = 0xBE + i; + } + + for(i=0;i< cfg_params.ca_num_vref_f1;i++) { + // Vref Range is 0x1 (Bit 6 of Vref). + cfg_params.ca_vref_values_f1[i] = (1 << 6) + 0x5 + i; + } + +#if DCS_REG_VERSION == 1 + for(i=0;i< cfg_params.rddq_num_vref_f1;i++) { + cfg_params.rddq_vref_values_f1[i] = 0xD1 + i; + } +#else + for(i=0;i< cfg_params.rddq_num_vref_f1;i++) { + cfg_params.rddq_vref_values_f1[i] = 0xD5 + i; + } +#endif + + for(i=0;i< cfg_params.wrdq_num_vref;i++) { + cfg_params.wrdq_vref_values[i] = 0xC + i; + } + + // This is to take care of bit/byte swizzling +#ifdef AMS_SIM_ENV + for(i=0;i<8;i++) { + cfg_params.cacal_bit_sel[i] = ((CSR_READ(rAMP_CACALBITSELECT(0)) >> (4 * i)) & 0x7); + } +#else + for(i=0;i<8;i++) { + cfg_params.cacal_bit_sel[i] = i; + } +#endif + +#ifdef AMS_SIM_ENV + cfg_params.cacal_rd_byte_sel = ((CSR_READ(rAMP_CACALCTRL(0)) >> 28) & 0x1); +#else + cfg_params.cacal_rd_byte_sel = 1; +#endif + + cfg_params.resume = (bootMode)? true : false; + cfg_params.disable_coarse_cs_training = false; // Coarse CS training enabled on B0 + cfg_params.cacalib_hw_loops = 15; + cfg_params.cacalib_sw_loops = 1; + cfg_params.rddq_cal_loopcnt = 1; + cfg_params.wrdq_cal_loopcnt = 1; + + cfg_params.freq_bin = 1; + cfg_params.RL = 16; + cfg_params.WL = 12; + + cfg_params.dv_params_valid = false; + cfg_params.dv_randomize = false; + cfg_params.dbg_calib_mode = 0; + cfg_params.opt_vref_mode = DCS_CAL_OPT_VREF_MODE_COM; + + // Giving a margin of 2 clocks from JEDEC spec to account for propagation delays from AMPS to DDR pins. + // cfg_params.tWLO = 15; // max = 20ns + cfg_params.tWLO = 18; // max = 20ns + cfg_params.tWLMRD = 21; // min = 40 tCK + cfg_params.tWLDQSEN = 11; // max = 20 tCK + + // TODO : What should tCKCEH be programmed to. Currently programming it to 2CK or 1 MCU clock. + // TODO : What should tDSTrain be programmed to. + // tCKCKEH = 2nCK,tVref,Long=200ns tVref,Short=80ns, tCAENT=10ns. The register fields are in terms of number of MCU clocks(1.66ns) + cfg_params.tDSTrain = 2; + cfg_params.tCKCKEH = 2; + cfg_params.tVREF_LONG = 121; + cfg_params.tCAENT = 7; + + cfg_params.tADR = 15; // max = 20ns + cfg_params.tMRD = 9; // max = 14ns + cfg_params.tDQSCKE = 7; // min = 10ns + cfg_params.tCKEHCMD = 6; + + cfg_params.WrLvlDqsPulseCnt = 0; // This sets the number of pulses to 2. + + cfg_params.ca_prbs4_pattern = 0x5E26; + cfg_params.ca_invert_mask = 0x2A; + + cfg_params.CsStopCycleCnt = 1; + cfg_params.CsActiveCycleCnt = 2; + + // Returning this allows Clients of this Calibration Library to + // modify the configuration beyond this default setup + return &cfg_params; +} + +/////////////////////////////////////////////////////////////////////////////// +////// Standard way to calculate the correct index for results arrays +////// Based on Chan, Rank, SW-Loop ... degenerates appropriately when +////// one of the the configured "number of" parameters is ONE, or when +////// one of the passed parameters is ZERO. +/////////////////////////////////////////////////////////////////////////////// +static inline +uint32_t loopchrnk_index_calc(uint32_t ch, uint32_t rnk, uint32_t swloop) +{ + return (rnk + (cfg_params.num_ranks * (ch + (cfg_params.num_channels * swloop)))); +} + +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void cal_pmgr_change_mcu_clk(uint32_t bucket) +{ +#ifdef ENV_DV +uint32_t pmgr_src_sel; + + #ifdef AMS_SIM_ENV + // Call custom API provided in PMGR_Xactor.h for PMGR changing mcu_clk to indicated Freq Bucket + pmgr_special_cmd(PMGR_CMD_FREQ_CHANGE, bucket, 0); + #else + // Call custom API provided in mcu_helper_fxns.c for PMGR changing mcu_clk to 800Mhz + pmgr_src_sel = (bucket == 3) ? 8 : 5; + pmgr_amc_clk_cfg(pmgr_src_sel, bucket, 0); + #endif +#else + // Call shim function to ask the PMGR to change the mcu_clk to indicated Freq Bucket + shim_change_freq(bucket); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void amp_save_masterdll_values() +{ + uint8_t ch; + + for(ch = 0; ch < cfg_params.num_channels ; ch++) { + mdllcode[ch][AMP_DQ0] = (CSR_READ(rAMP_MDLLCODE(AMP_DQ0, ch)) & DLLVAL_BITS); + mdllcode[ch][AMP_DQ1] = (CSR_READ(rAMP_MDLLCODE(AMP_DQ1, ch)) & DLLVAL_BITS); + // Since there is no CA MDLL for Maui, pick the maximum of DQ0 MDLL & DQ1 MDLL + mdllcode[ch][AMP_CA] = (mdllcode[ch][AMP_DQ0] > mdllcode[ch][AMP_DQ1]) ? mdllcode[ch][AMP_DQ0] : mdllcode[ch][AMP_DQ1]; + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_save_ca_bucket1(uint32_t ch) +{ + uint8_t bit; + + cksdll_bucket1[ch] = (CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & 0xFF; + cssdll_bucket1[ch] = (CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & 0xFF; + casdll_bucket1[ch] = (CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & 0xFF; + shim_printf("DEBUG - amp_save_ca_bucket1:: Saving %d for CKSDLL, %d for CSSDLL, %d for CASDLL for Channel %d\n", cksdll_bucket1[ch], cssdll_bucket1[ch], casdll_bucket1[ch], ch); + + for(bit = 0; bit < CA_NUM_BITS; bit++) { + cadeskew_bucket1[ch][bit] = CSR_READ(rAMP_CADESKEW_CTRL(ch,bit)) & 0x3F; + shim_printf("DEBUG - amp_save_ca_bucket1:: Saving %d for CA deskew bit %d for Channel %d \n", cadeskew_bucket1[ch][bit], bit, ch); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_ca_bucket1(uint32_t ch) +{ + uint8_t bit; + + amp_push_cksdll_out(ch, cksdll_bucket1[ch]); + amp_push_cssdll_out(ch, cssdll_bucket1[ch]); + amp_push_casdll_out(ch, casdll_bucket1[ch]); + + for(bit = 0; bit < CA_NUM_BITS; bit++) { + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit), cadeskew_bucket1[ch][bit] | RUNDESKEWUPD); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, bit)) & RUNDESKEWUPD); + } +} + +// Save or restore ca and wrlvl registers for resume boot +_ROMCODE_SEGMENT_PREFIX void calibration_save_restore_ca_wrlvl_regs(uint32_t save_or_restore, uint32_t channels, bool freq_bin) +{ + + _MCODE_SEGMENT_PREFIX static uint32_t bit_pos = 0; + _MCODE_SEGMENT_PREFIX static uint32_t byte_pos = 0; + uint32_t ch, bit_indx, byte; + uint8_t casdll[DCS_NUM_CHANNELS], cksdll[DCS_NUM_CHANNELS], cssdll[DCS_NUM_CHANNELS], ca_deskew[DCS_NUM_CHANNELS][CA_NUM_BITS]; + //uint8_t ca_vref_f0, ca_vref_f1; + //uint8_t rddq_vref_f0, rddq_vref_f1; + //uint8_t wrdq_vref_f0, wrdq_vref_f1; + //uint8_t wrlvlsdll[DCS_NUM_CHANNELS]; + uint32_t camdll_vtscl_refcntl, rdmdll_vtscl_refcntl, wrmdll_vtscl_refcntl; + uint16_t camdll_vtscl_ref_ovrcode, rdmdll_vtscl_ref_ovrcode, wrmdll_vtscl_ref_ovrcode; + uint8_t ca_vref_f1, wrdq_vref_f1, rddq_vref_f1; + uint8_t ca_vref_f0, wrdq_vref_f0, rddq_vref_f0; + uint32_t freqchngctl0, freqchngctl1; + + if (save_or_restore == CALIB_SAVE) { + if(freq_bin) { + + // Save only write leveling registers when the save function is called first. + // Save function needs to be called after write leveling because the register fields + // being saved here would be over-written after WRDQ calibration is done. + if((bit_pos == 0) && (byte_pos == 0)) { + for (ch = 0; ch < channels; ch++) { + // save the WrLvl registers for this channel (2 DQ SDLLs and 1 CA SDLL) + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // cawrlvlsdll is stored as the "3rd" byte + if (byte == DQ_NUM_BYTES) + cal_save_value(CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + else + cal_save_value(CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + } + } + else { + for (ch = 0; ch < channels; ch++) { + + // save the CA registers for this channel + // Save CA SDLL + cal_save_value(CSR_READ(rAMP_CASDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + + // Save CK SDLL + cal_save_value(CSR_READ(rAMP_CKSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + + // Save CS SDLL + cal_save_value(CSR_READ(rAMP_CSSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + + // Save CA deskews + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + cal_save_value(CSR_READ(rAMP_CADESKEW_CTRL(ch, bit_indx)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + + + // Save CA, WR and RD VT reference codes + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value((CSR_READ(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) & 0xFF, 8, &bit_pos, &byte_pos); + cal_save_value((((CSR_READ(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) >> 8) & 0x3), VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos); + cal_save_value((CSR_READ(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) & 0xFF, 8, &bit_pos, &byte_pos); + cal_save_value((((CSR_READ(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) >> 8) & 0x3), VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos); + cal_save_value((CSR_READ(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) & 0xFF, 8, &bit_pos, &byte_pos); + cal_save_value((((CSR_READ(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) >> 8) & 0x3), VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos); + } + + // Save optimal vref for CA/CS + cal_save_value(cfg_params.ca_vref_values_f1[vref_opt_ca[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for RDDQ + cal_save_value(cfg_params.rddq_vref_values_f1[vref_opt_rddq[ch]] & RDDQ_VREF_CTRL_BITS, RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for WRDQ + cal_save_value(cfg_params.wrdq_vref_values[vref_opt_wrdq[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + } + + for (ch = 0; ch < channels; ch++) { + // Save WR DQS SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value((CSR_READ(rAMP_WRDQSDQ_SDLLCODE(byte, ch)) >> WR_DQS_SDLL_CODE_OFFSET) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_WRDQSDQ_SDLLCODE(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQS deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_WRDQSDESKEW_CTRL(byte, ch)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_save_value(CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save WR DM deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_WRDMDESKEW_CTRL(byte, ch)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_DQSDLLCODE_RD(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD DQ deskew codes + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_save_value(CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save RD DMI deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save CAWRLVL & DQ WRLVL SDLL values after WRDQ calibration is done + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // cawrlvlsdll is stored as the "5th" byte + if (byte == DQ_NUM_BYTES) + cal_save_value(CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + else + cal_save_value(CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + } + } + } + else { + + for (ch = 0; ch < channels; ch++) { + // Save optimal vref for CA/CS + cal_save_value(cfg_params.ca_vref_values_f1[vref_opt_ca[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for RDDQ + cal_save_value(cfg_params.rddq_vref_values_f1[vref_opt_rddq[ch]] & RDDQ_VREF_CTRL_BITS, RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for WRDQ + cal_save_value(cfg_params.wrdq_vref_values[vref_opt_wrdq[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save the cal_bits array + shim_store_memory_calibration((void *) cal_bits, CALIB_NUM_BYTES_TO_SAVE); + } + } else { + // Retrieve cal_bits array + shim_load_memory_calibration((void *) cal_bits, CALIB_NUM_BYTES_TO_SAVE); + + // Reset bit & byte positions for the first call + bit_pos = 0; + byte_pos = 0; + + for (ch = 0; ch < channels; ch++) { + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + // cawrlvlsdll is stored as the "3rd" byte + if (byte == DQ_NUM_BYTES) + amp_program_cawrlvl_sdll(ch, cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos), 0); + else + amp_program_dqwrlvl_sdll(ch, byte, cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos), 0); + } + } + + for (ch = 0; ch < channels; ch++) { + casdll[ch] = cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + amp_program_ca_sdll(ch, casdll[ch]); + + cksdll[ch] = cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + amp_program_ck_sdll(ch, cksdll[ch]); + + cssdll[ch] = cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + amp_program_cs_sdll(ch, cssdll[ch]); + + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + ca_deskew[ch][bit_indx] = cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit_indx), ca_deskew[ch][bit_indx] | RUNDESKEWUPD); + SPIN_W_TMO_WHILE ( CSR_READ(rAMP_CADESKEW_CTRL(ch, bit_indx)) & RUNDESKEWUPD); + } + + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + camdll_vtscl_refcntl = CSR_READ(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch)); + camdll_vtscl_ref_ovrcode = cal_retrieve_value(8, &bit_pos, &byte_pos); + camdll_vtscl_ref_ovrcode |= (cal_retrieve_value(VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos) << 8); + CSR_WRITE(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch), (camdll_vtscl_refcntl & VT_SCL_REF_MASK) | (camdll_vtscl_ref_ovrcode << VT_SCL_OVR_OFFSET) | (1 << VT_SCL_REF_UPD_OFFSET)); + + rdmdll_vtscl_refcntl = CSR_READ(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch)); + rdmdll_vtscl_ref_ovrcode = cal_retrieve_value(8, &bit_pos, &byte_pos); + rdmdll_vtscl_ref_ovrcode |= (cal_retrieve_value(VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos) << 8); + CSR_WRITE(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch), (rdmdll_vtscl_refcntl & VT_SCL_REF_MASK) | (rdmdll_vtscl_ref_ovrcode << VT_SCL_OVR_OFFSET) | (1 << VT_SCL_REF_UPD_OFFSET)); + + wrmdll_vtscl_refcntl = CSR_READ(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch)); + wrmdll_vtscl_ref_ovrcode = cal_retrieve_value(8, &bit_pos, &byte_pos); + wrmdll_vtscl_ref_ovrcode |= (cal_retrieve_value(VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos) << 8); + CSR_WRITE(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch), (wrmdll_vtscl_refcntl & VT_SCL_REF_MASK) | (wrmdll_vtscl_ref_ovrcode << VT_SCL_OVR_OFFSET) | (1 << VT_SCL_REF_UPD_OFFSET)); + } + + ca_vref_f1 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + rddq_vref_f1 = cal_retrieve_value(RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + wrdq_vref_f1 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) { + // Program CA and WRDQ optimal Vref's + freqchngctl0 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(ch), (freqchngctl0 & 0xFFFF) | (0xE << 16) | (wrdq_vref_f1 << 24)); + + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0xFFFF0000) | (0xC) | (ca_vref_f1 << 8)); + } else { + // Program CA and WRDQ optimal Vref's + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0xFFFF0000) | (0xE) | (wrdq_vref_f1 << 8)); + + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0xFFFF) | (0xC << 16) | (ca_vref_f1 << 24)); + } + + // Program AMPS register with optimal RDDQ Vref + amp_program_rddq_vref(ch, rddq_vref_f1, 0, 1); + } + + // Simply retrieve WRDQ /RDDQ delays as they are not planned to be used. These delays would be recomputed by Full scan + // hardware calibration. + for (ch = 0; ch < channels; ch++) { + // Save WR DQS SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQS deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save WR DM deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD DQ deskew codes + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save RD DMI deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save CAWRLVL & DQ WRLVL SDLL values after WRDQ calibration is done + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + // cawrlvlsdll is stored as the "5th" byte + if (byte == DQ_NUM_BYTES) + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + else + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Retrieve optimal Vref values for Bucket 0. + for (ch = 0; ch < channels; ch++) { + ca_vref_f0 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + rddq_vref_f0 = cal_retrieve_value(RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + wrdq_vref_f0 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) { + // Program CA and WRDQ optimal Vref's + freqchngctl0 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(ch), (freqchngctl0 & 0xFFFF) | (0xE << 16) | (wrdq_vref_f0 << 24)); + + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0xFFFF0000) | (0xC) | (ca_vref_f0 << 8)); + } else { + // Program CA and WRDQ optimal Vref's + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0xFFFF0000) | (0xE) | (wrdq_vref_f0 << 8)); + + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0xFFFF) | (0xC << 16) | (ca_vref_f0 << 24)); + } + + // Program AMPS register with optimal RDDQ Vref + amp_program_rddq_vref(ch, rddq_vref_f0, 0, 0); + } + } +} + +_ROMCODE_SEGMENT_PREFIX void calibration_dump_results(uint32_t operations, bool dump_passing_window) +{ + uint32_t ch, rnk, chrnk_indx, bit, byte, tmp; + + if ((operations & (SELECT_CAL_ALL)) == 0) + // Nothing selected + return; + + shim_printf("LPDDR4 DCS Calibration final results"); + + if (dump_passing_window) + shim_printf(" with passing points per rank in brackets"); + + shim_printf(":\n"); + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + shim_printf("DCS Channel %d\n", ch); + + if (operations & SELECT_CACAL) { + shim_printf("\tCA SDLL: %d\n", CSR_READ(rAMP_CASDLLCODE(ch))); + shim_printf("\tCS SDLL: %d\n", CSR_READ(rAMP_CSSDLLCODE(ch))); + shim_printf("\tCK SDLL: %d\n", CSR_READ(rAMP_CKSDLLCODE(ch))); + + shim_printf("\t\tPer Bit Deskew: "); + for (bit = 0; bit < CA_NUM_BITS; bit++) { + shim_printf("%d ", CSR_READ(rAMP_CADESKEW_CTRL(ch, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_window && !cfg_params.resume) { + + shim_printf("["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + + + shim_printf("%d ", cacal_per_chrnk_right[chrnk_indx][bit]); + shim_printf("%d", cacal_per_chrnk_left[chrnk_indx][bit]); + } + + shim_printf("] "); + } + + } + shim_printf("\n\t\tCS Deskew: %d", CSR_READ(rAMP_CSDESKEW_CTRL(ch)) & DESKEW_CTRL_BITS); + shim_printf("\n\t\tCK Deskew: %d", CSR_READ(rAMP_CKDESKEW_CTRL(ch)) & DESKEW_CTRL_BITS); + shim_printf("\n"); + } + + if (operations & SELECT_WRLVLCAL) { + + shim_printf("\tCA WrLvlSDLL: %d", CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS); + + if (dump_passing_window && !cfg_params.resume) { + shim_printf(" ["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + + + shim_printf("%d ", wrlvlcal_per_chrnk_rise[chrnk_indx][DQ_NUM_BYTES]); + shim_printf("%d", wrlvlcal_per_chrnk_fall[chrnk_indx][DQ_NUM_BYTES]); + } + + shim_printf("]"); + } + + shim_printf("\n"); + + shim_printf("\tDQ WrLvlSDLL: "); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + shim_printf("%d ", CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & DLLVAL_BITS); + + if (dump_passing_window && !cfg_params.resume) { + shim_printf("["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + + + shim_printf("%d ", wrlvlcal_per_chrnk_rise[chrnk_indx][byte]); + shim_printf("%d", wrlvlcal_per_chrnk_fall[chrnk_indx][byte]); + } + + shim_printf("] "); + } + } + + shim_printf("\n"); + } + + if (operations & SELECT_RDDQCAL) { + + shim_printf("\tRead DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + shim_printf("\t\tByte %d SDLL: %d\n", byte, CSR_READ(rAMP_DQSDLLCODE_RD(byte, ch)) & DLLVAL_BITS); + + shim_printf("\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + shim_printf("%d ", CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_window) { + shim_printf("["); + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + shim_printf("%d ", rddqcal_per_chrnk_right[chrnk_indx][vref_opt_rddq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + shim_printf("%d", rddqcal_per_chrnk_left[chrnk_indx][vref_opt_rddq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + } + shim_printf("] "); + } + } + + shim_printf("\n"); + } + } + + if (operations & SELECT_WRDQCAL) { + + shim_printf("\tWrite DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tmp = CSR_READ(rAMP_WRDQSDQ_SDLLCODE(byte, ch)); + shim_printf("\t\tByte %d DQ SDLL: %d\n", byte, (tmp >> 0) & DLLVAL_BITS); + shim_printf("\t\tByte %d DQS SDLL: %d\n", byte, (tmp >> 8) & DLLVAL_BITS); + + shim_printf("\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + shim_printf("%d ", CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_window) { + shim_printf(" ["); + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + shim_printf("%d ", wrdqcal_per_chrnk_right[chrnk_indx][vref_opt_wrdq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + shim_printf("%d", wrdqcal_per_chrnk_left[chrnk_indx][vref_opt_wrdq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + } + shim_printf("] "); + } + } + + shim_printf("\n"); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// CA Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +// CP : Use the following settings for Maui +// cfg_params.sw_loops = 1 +// cfg_params.num_ranks = 1 +// Number of HW Loops >= 16 ****ALWAYS**** +// NOTE: cfg_params.hw_loops is "number of loops less one", so (cfg_params.hw_loops >= 15) +_ROMCODE_SEGMENT_PREFIX void calibrate_ca(void) +{ + uint32_t ch, rnk, swloop, mask_bits, vref; + + uint32_t loopchrnk0_indx; + uint32_t cs_sdll_precal_bin0, ck_sdll_precal_bin0; + uint32_t vt_scl_factor; + uint32_t good_vref_not_found; + uint32_t ca_vref_value; + uint32_t ca_num_vref = (cfg_params.freq_bin == 0) ? cfg_params.ca_num_vref_f0 : cfg_params.ca_num_vref_f1; + + // Initialize registers for CA calibration + cacal_init_registers(); + + // CP : Maui Change + // CP : Masks will change for Maui + cacal_generate_patterns_mask(); + + mask_bits = 0; + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + + // CP : Maui Change + amp_setup_ca_cal(ch, rnk, swloop); + + // Enter CA training mode + amp_enter_cacal_mode(ch); + + // Switch to target Freq (800Mz or 1200MHz) + if(cfg_params.freq_bin < 2) + cal_pmgr_change_mcu_clk(cfg_params.freq_bin); + + // Update SOC Drive Strengths to match DRAM's FSP (not for Maui A0/A1) + if((cfg_params.chip_id != 0x8000) || (cfg_params.chip_id == 0x8000 && cfg_params.chip_rev >= CHIP_REVISION_B0)) + run_soc_upd(ch); + + // Saving Bucket 1 calibration results at the end of Bin1 calibration + if(cfg_params.freq_bin == 0) { + amp_save_ca_bucket1(ch); + } + + // Clear all CA, CS and CK registers before starting CS/CA calibration. + amp_init_ca_deskew(ch); + amp_init_ca_cs_ck_sdll(ch); + + // If we are going to frequency Bin 0 from Bin 1, Software initiated MDLL calibration must be done + // to lock in the new MDLL code + if(cfg_params.freq_bin == 0) { + amp_do_mdll_calib(ch); + } + + // Required since the dll values may change slightly during calibration + amp_save_masterdll_values(); + + // Scale Bin1 CK and CS SDLL based on MDLL values at Bin 1 and Bin 0 calibrations. + if(cfg_params.freq_bin == 0 && (cfg_params.disable_coarse_cs_training == true)) { + + shim_printf("DEBUG - ClkPeriod for Bin0=%d, mdllcode_freq_bin_1[ch]=%d, ClkPeriod for Bin1=%d, mdllcode[ch][AMP_CA]=%d \n", + cfg_params.clk_period_bin0, mdllcode_freq_bin_1[ch], cfg_params.clk_period_bin1, mdllcode[ch][AMP_CA]); + + if (cfg_params.clk_period_bin0 == 0) { + shim_panic("Clock Period for Freq Bin 0 should not be ZERO"); + } + + vt_scl_factor = (cfg_params.clk_period_bin1 * mdllcode[ch][AMP_CA] * 100)/(cfg_params.clk_period_bin0 * mdllcode_freq_bin_1[ch]); + shim_printf("DEBUG - Computed vt_scl_factor for Bin 0 as %d \n", vt_scl_factor); + + cs_sdll_precal_bin0 = (cssdll_bucket1[ch] * vt_scl_factor + (100 >> 1))/100; + shim_printf("DEBUG - Computed cs_sdll_precal_bin0 value as %d \n", cs_sdll_precal_bin0); + + ck_sdll_precal_bin0 = (cksdll_bucket1[ch] * vt_scl_factor + (100 >> 1))/100; + shim_printf("DEBUG - Computed ck_sdll_precal_bin0 value as %d \n", ck_sdll_precal_bin0); + + // Program the scaled value into CK and CS SDLL registers. + amp_program_ck_sdll(ch, ck_sdll_precal_bin0); + amp_program_cs_sdll(ch, cs_sdll_precal_bin0); + + // Save MDLL code during Bin 1 calibration. + if(cfg_params.freq_bin == 1) { + mdllcode_freq_bin_1[ch] = mdllcode[ch][AMP_CA]; + shim_printf("DEBUG - Saving a value of %d for frequency bin 1 mdll code for channel %d \n",mdllcode_freq_bin_1[ch], ch); + } + } + + // Calibration sequence is to be run for each Vref setting for each rank in each channel, cfg_params.cacalib_sw_loops number of times + for (vref = 0; vref < ca_num_vref; vref++) { + + ca_vref_value = (cfg_params.freq_bin == 0) ? cfg_params.ca_vref_values_f0[vref] : cfg_params.ca_vref_values_f1[vref]; + + // Program Vref setting + amp_program_ca_vref(ch, ca_vref_value, 0); //vref_pulse_cnt=0 + + // Set the Vref run bit + amp_run_cacal_vref(ch); + + cksdll_cscal[vref] = 0; + cssdll_cscal[vref] = 0; + if(cfg_params.disable_coarse_cs_training == false) { + // CS Training + cacal_run_sequence(ch, rnk, CS_TRAINING, mask_bits, swloop, vref); + + // Program delay values calculated from CS training + cacal_program_cs_training_values(); + + } + cksdll_cscal[vref] = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll_cscal[vref] = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + //shim_printf("DEBUG - After CS training for ch=%d, vref=%d, CKSDLL=0x%x, CSSDLL=0x%x \n", ch, vref, cksdll_cscal[vref], cssdll_cscal[vref]); + + // Training of CA Bits 0-5 + cacal_run_sequence(ch, rnk, CA_TRAINING, mask_bits, swloop, vref); + + // Clear all CA, CS and CK registers before proceeding to the next Vref value + amp_init_ca_deskew(ch); + amp_init_ca_cs_ck_sdll(ch); + } + + if(cfg_params.freq_bin == 1) { + cal_pmgr_change_mcu_clk(3); // switch to 50MHz + } else { + // Restore 800Mhz calibrated values + amp_program_ca_bucket1(ch); + cal_pmgr_change_mcu_clk(1); // switch to 800MHz + } + + // Set DQS weak pull down enable before CA cal exit. This is a SW workaround for Maui A0. + // + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) + amp_set_dqs_weak_pden(ch, cfg_params.freq_bin); + // Update SOC Drive Strengths to match DRAM's FSP + else + run_soc_upd(ch); + + // Exit CA Training mode + amp_exit_cacal_mode(ch); + + // Reset DQS weak pull down enable after CA cal exit. This is a SW workaround for Maui A0. + // + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) + amp_reset_dqs_weak_pden(ch, cfg_params.freq_bin); + + // Find if there is even a single Vref which did not panic. + good_vref_not_found = 1; + for (vref = 0; vref < ca_num_vref; vref++) { + good_vref_not_found &= cacal_vref_panic[ch][vref]; + } + if(good_vref_not_found == 1) { + shim_panic("Memory CA calibration: Unable to find any Vref which did not panic for channel %d\n", ch); + } + + // Compute the optimal Vref index + amp_compute_opt_vref_cacal(ch, rnk, swloop, CA_NUM_BITS); + } + } + } + + // By now, we have compiled right and left edges of passing window for all CA bits over a number of iterations + // Aggregate the results, and find the center point of the window, and program it + // Make sure CS trained values are not messed up because of CA training programing + // Make sure final CK SDLL value is same for both CS & CA trainings. + + cacal_program_final_values(); + + // Do a second stage CS training at the optimal Vref. + // Once we figure out the final window and optimal Vref values, do CS training again. + // We need to move CK & CA together in this step. The final CSSDLL value from this step + // will be programmed into CS SDLL. + //***** Fine tune CS calibration *******// + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + + // Enter CA training mode + amp_enter_cacal_mode(ch); + + if(cfg_params.freq_bin < 2) + cal_pmgr_change_mcu_clk(cfg_params.freq_bin); // switch to target Freq (800Mz or 1200MHz) + + if((cfg_params.chip_id != 0x8000) || (cfg_params.chip_id == 0x8000 && cfg_params.chip_rev >= CHIP_REVISION_B0)) + run_soc_upd(ch); + + // Program optimal Vref setting + loopchrnk0_indx = loopchrnk_index_calc(ch, rnk, swloop); + uint32_t vref_ch = vref_opt_ca[loopchrnk0_indx]; + ca_vref_value = (cfg_params.freq_bin == 0) ? cfg_params.ca_vref_values_f0[vref_ch] : cfg_params.ca_vref_values_f1[vref_ch]; + amp_program_ca_vref(ch, ca_vref_value, 0); //vref_pulse_cnt=0 + + // Set the Vref run bit + amp_run_cacal_vref(ch); + + cksdll_cscal[vref_ch] = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll_cscal[vref_ch] = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + casdll_cscal[vref_ch] = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + // Training of CA Bits 0-5 + cacal_run_sequence(ch, rnk, CS_FINE_TRAINING, mask_bits, swloop, vref_ch); + + // Program delay values calculated from fine CS training + cacal_program_cs_training_values(); + + cksdll_cscal[vref_ch] = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll_cscal[vref_ch] = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + casdll_cscal[vref_ch] = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + if(cfg_params.freq_bin == 1) { + cal_pmgr_change_mcu_clk(3); // switch to 50MHz + } else { + // Restore 800Mhz calibrated values + amp_program_ca_bucket1(ch); + cal_pmgr_change_mcu_clk(1); // switch to 800MHz + } + + // Set DQS weak pull down enable before CA cal exit. This is a SW workaround for Maui A0. + // + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) + amp_set_dqs_weak_pden(ch, cfg_params.freq_bin); + // Update SOC Drive Strengths to match DRAM's FSP + else + run_soc_upd(ch); + + // Exit CA Training mode + amp_exit_cacal_mode(ch); + + // Reset DQS weak pull down enable after CA cal exit. This is a SW workaround for Maui A0. + // + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) + amp_reset_dqs_weak_pden(ch, cfg_params.freq_bin); + } + } + } + + // Program CA calibration results again after fine tune CS training. + cacal_program_final_values(); + +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// RdDQ Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void calibrate_rddq() +{ + uint32_t ch, rnk, vref; + uint32_t good_vref_not_found; + uint32_t rddq_num_vref = (cfg_params.freq_bin == 0) ? cfg_params.rddq_num_vref_f0 : cfg_params.rddq_num_vref_f1; + uint32_t rddq_vref_value; + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + amp_setup_rddq_cal(ch, rnk); + + for(vref = 0; vref < rddq_num_vref; vref++) { + + rddq_vref_value = (cfg_params.freq_bin == 0) ? cfg_params.rddq_vref_values_f0[vref] : cfg_params.rddq_vref_values_f1[vref]; + + // Program RDDQ Vref setting + amp_program_rddq_vref(ch, rddq_vref_value, 0, cfg_params.freq_bin); + + // Find the left and right edges of the eye + // CP : Maui Change + // Find Left failing point first. Then, move on to finding right failing point. + rddqcal_find_left_failing_point(ch, rnk, vref, false); + rddqcal_find_right_failing_point(ch, rnk, vref, false); + } + + // Find if there is even a single Vref which did not panic. + good_vref_not_found = 1; + for(vref = 0; vref < rddq_num_vref; vref++) { + good_vref_not_found &= rddqcal_vref_panic[ch][vref]; + } + if(good_vref_not_found == 1) { + shim_panic("Memory RDDQ calibration: Unable to find any Vref which did not panic for channel %d\n", ch); + } + + // Compute the optimal Vref index + amp_compute_opt_vref_rddqcal(ch, rnk, (DQ_TOTAL_BITS + DMI_TOTAL_BITS)); + } + } + + // Now that we have per bit left and right endpoints for each channel and rank, aggregate and program final values + rddqcal_program_final_values(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// WrLvl Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +// Align the clock signal with the DQ signals +_ROMCODE_SEGMENT_PREFIX void calibrate_wrlvl(void) +{ + uint32_t ch, rnk; + uint8_t byte; + + amp_wrlvl_init(); + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + + // Set up MRW-1 & MRW-2 for Write leveling entry + // Set RunWrlvlEntry bit + amp_wrlvl_entry(ch); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + // Program CAWRLVL to 0. + // Program WR WRLVL fields to the value before Write Leveling. + // + amp_program_cawrlvl_sdll(ch, 0, 0); + for(byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + // find the region where all bits return a 0 + wrlvlcal_push_to_0s_region(ch, rnk); + + // push out the clock signal until all bits return a 1 + wrlvlcal_find_0to1_transition(ch, rnk); + + // now go back towards the transition edge found earlier, but from this side of the edge + wrlvlcal_find_1to0_transition(ch, rnk); + } + + // Set up MRW-1 & MRW-2 for Write leveling exit + // Set RunWrlvlExit bit + amp_wrlvl_exit(ch, cfg_params.freq_bin); + } + + // Program the final wrlvl values + wrlvlcal_program_final_values(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// WrDQ Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void calibrate_wrdq(void) +{ + uint32_t ch, rnk; + uint32_t chrnk_indx; + uint32_t byte; + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + wrdqcal_init_regs(ch, rnk); + + // Clear deskew registers + amp_init_wr_deskew(ch); + + // Read the value of CAWRLVL SDLL code obtained from Write Leveling + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + cawrlvl_sdll_wrlvl[chrnk_indx] = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & 0xFF; + shim_printf("DEBUG - calibrate_wrdq:: chrnk_indx=%d, cawrlvl_sdll_wrlvl[chrnk_indx]=0x%x \n",chrnk_indx, cawrlvl_sdll_wrlvl[chrnk_indx]); + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++) { + dqwrlvl_sdll_after_wrlvl[chrnk_indx][byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & 0xFF; + shim_printf("DEBUG - calibrate_wrdq:: chrnk_indx=%d, byte=%d, dqwrlvl_sdll_after_wrlvl[chrnk_indx][byte]=0x%x \n", chrnk_indx, byte, dqwrlvl_sdll_after_wrlvl[chrnk_indx][byte]); + } + + wrdqcal_sequence(ch, rnk); + } + } + + wrdqcal_program_final_values(); +} + +/////////////////////////////////////////////////////////////////////////////// +////// Local functions +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void amp_do_mdll_calib(uint32_t ch) +{ + uint8_t byte; + // POR is to program DLL update for both bytes and then poll for update to clear + // on both bytes. + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++) { + CSR_WRITE(rAMP_DLLUPDTCMD(byte, ch), 1 << RUN_DLL_UPDT); + } + + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++) { + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DLLUPDTCMD(byte, ch)) & (1 << RUN_DLL_UPDT)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_setup_ca_cal(uint32_t ch, uint32_t rnk, uint32_t swloop) +{ + uint32_t cacalctrl; + + // Map the CA bits to appropriate dq byte lanes, accounting for swizzling. + // Bytes 0 and 2 from DDR are hooked to AMPDQ0, and are bit swizzled (i.e., bit 0 from DDR connected to bit 7 on AMPDQ, and so on). + // Bytes 1 and 3 are hooked to AMPDQ1, and are NOT bit swizzled. + // For the 10 CA bits, that means CA0-3 (MR41) and CA4 (MR48) come back from DDR on AMPDQ0, + // and CA5-8 (MR41) and CA9 (MR48) on AMPDQ1. + + CSR_WRITE(rAMP_CACALBITSELECT(ch), ((cfg_params.cacal_bit_sel[7] << 28)|(cfg_params.cacal_bit_sel[6] << 24)|(cfg_params.cacal_bit_sel[5] << 20)|(cfg_params.cacal_bit_sel[4] << 16)|(cfg_params.cacal_bit_sel[3] << 12)|(cfg_params.cacal_bit_sel[2] << 8)|(cfg_params.cacal_bit_sel[1]<< 4)|(cfg_params.cacal_bit_sel[0] << 0))); + + // Program rank, hardware loop count, and timing params + // Timing params are taken from lpddr4 jedec spec + // Program DQ Byte on which to expect CA data during calibration + cacalctrl = (cfg_params.cacal_rd_byte_sel << 28) | (rnk << 24) | (cfg_params.cacalib_hw_loops << 16) | (cfg_params.tADR << 8) | (cfg_params.tMRD << 0); + + CSR_WRITE(rAMP_CACALCTRL(ch), cacalctrl); + + // CP: Maui Change + // Also Program rAMP_CACALCTRL2 register + CSR_WRITE(rAMP_CACALCTRL2(ch),(cfg_params.tDSTrain << 24) | (cfg_params.tCKCKEH << 16) | (cfg_params.tVREF_LONG << 8) | (cfg_params.tCAENT)); + + // Program rAMP_CACALCTRL3 register + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) + CSR_WRITE(rAMP_CACALCTRL3(ch),(cfg_params.tDQSCKE << 8) | (cfg_params.tCKEHCMD)); + // Also, Program Fine CS parameters + else + CSR_WRITE(rAMP_CACALCTRL3(ch), (cfg_params.CsActiveCycleCnt << 24) | (cfg_params.CsStopCycleCnt << 16) | (cfg_params.tDQSCKE << 8) | (cfg_params.tCKEHCMD)); + + CSR_WRITE(rAMP_CACALPAT(ch), (cfg_params.ca_invert_mask<<16)|(cfg_params.ca_prbs4_pattern)); +} + +_ROMCODE_SEGMENT_PREFIX void run_soc_upd(uint32_t ch) +{ + uint32_t freqchngctl; + + // Save the value of freqchngctl register + freqchngctl = CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch), (freqchngctl & 0xFFFEFFFF) | 0x10000); + + // Add some delay here. Do dummy reads + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); +} + +// CP : Maui Change +_ROMCODE_SEGMENT_PREFIX void amp_program_ca_vref(uint32_t ch, uint32_t vref, uint32_t vref_pulse_cnt) +{ + uint32_t cacacalvref; + + // Program + // 1.Vref setting at which CA calibration is to be run + // 2.Vref pulse count + cacacalvref = CSR_READ(rAMP_CACACALVREF(ch)); + + CSR_WRITE(rAMP_CACACALVREF(ch),(cacacalvref & 0xFFF00000) | (vref_pulse_cnt << 16) | (vref)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_rddq_vref(uint32_t ch, uint32_t vref, uint32_t vref_pulse_cnt, uint8_t freq_bin) +{ + uint32_t rddqcalvref; + uint32_t byte; + + // Program + // 1.Vref setting at which RDDQ calibration is to be run + // 2.Vref pulse count + + if(freq_bin == 0) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + rddqcalvref = CSR_READ(rAMP_RDDQCALVREF_f0(byte, ch)); + if(cfg_params.chip_id == 0x8000) + CSR_WRITE(rAMP_RDDQCALVREF_f0(byte, ch),(rddqcalvref & 0xFFFFFF00) | (vref)); + else + CSR_WRITE(rAMP_RDDQCALVREF_f0(byte, ch),(rddqcalvref & 0xFFFFFF00) | (1 << 7)| (vref)); + } + } + else if(freq_bin == 1) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + rddqcalvref = CSR_READ(rAMP_RDDQCALVREF_f1(byte, ch)); + if(cfg_params.chip_id == 0x8000) + CSR_WRITE(rAMP_RDDQCALVREF_f1(byte, ch),(rddqcalvref & 0xFFFFFF00) | (vref)); + else + CSR_WRITE(rAMP_RDDQCALVREF_f1(byte, ch),(rddqcalvref & 0xFFFFFF00) | (1 << 7) | (vref)); + } + } +} + +// CP : Maui Change +_ROMCODE_SEGMENT_PREFIX void amp_program_wrdq_vref(uint8_t chan, uint8_t rank, uint32_t vref, uint32_t vref_pulse_cnt) +{ + uint32_t mr14_data; + + shim_mrcmd_to_ch_rnk(MR_READ, chan, rank, MR14, (uintptr_t)&mr14_data); + + mr14_data = (mr14_data &0x80) | (vref); + + shim_mrcmd_to_ch_rnk(MR_WRITE, chan, rank, MR14, mr14_data); +} + +// (Re-)Initialize CA deskew registers +_ROMCODE_SEGMENT_PREFIX void amp_init_ca_deskew(uint32_t ch) +{ + uint32_t d; + + // Clear cadeskewctrl registers + for (d = 0; d < CA_NUM_BITS; d++) { + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, d), 0 | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, d)) & RUNDESKEWUPD); + } +} + +// (Re-)Initialize CA, CS and CK SDLL registers +_ROMCODE_SEGMENT_PREFIX void amp_init_ca_cs_ck_sdll(uint32_t ch) +{ + // Clear casdll register + CSR_WRITE(rAMP_CASDLLCTRL(ch), (0 << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CASDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); + + // Clear cssdll register + CSR_WRITE(rAMP_CSSDLLCTRL(ch), (0 << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CSSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); + + // Clear cksdll register + CSR_WRITE(rAMP_CKSDLLCTRL(ch), (0 << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CKSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); + +} + +_ROMCODE_SEGMENT_PREFIX void amp_init_wr_deskew(uint32_t ch) +{ + uint8_t byte, bit_indx; + + for(byte = 0; byte < DQ_NUM_BYTES; byte++) { + // Clear DQS deskew + CSR_WRITE(rAMP_WRDQSDESKEW_CTRL(byte, ch), 0 | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQSDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + + // Clear DM deskew + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(byte, ch), 0 | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + + // Clear DQ deskew + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx), 0 | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + } + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_push_casdll_out(uint32_t ch, uint32_t casdll_ovr_val) +{ + uint32_t ca_bit; + uint32_t casdll_tap; + uint32_t cadeskewcode; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + if (casdll_ovr_val > (3 * mdllcode[ch][AMP_CA] + 1 )) { + casdll_tap = (3 * mdllcode[ch][AMP_CA]); + + if ((casdll_ovr_val - casdll_tap) >= MAX_DESKEW_PROGRAMMED) + cadeskewcode = MAX_DESKEW_PROGRAMMED; + else + cadeskewcode = casdll_ovr_val - casdll_tap; + + // Adjust deskew registers for each ca bit + for (ca_bit = 0; ca_bit < CA_NUM_BITS; ca_bit++) { + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, ca_bit), cadeskewcode | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, ca_bit)) & RUNDESKEWUPD); + } + + casdll_ovr_val = (3 * mdllcode[ch][AMP_CA]); + + } + + CSR_WRITE(rAMP_CASDLLCTRL(ch), (casdll_ovr_val << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CASDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_ca_sdll(uint32_t ch, uint32_t casdll_val) +{ + CSR_WRITE(rAMP_CASDLLCTRL(ch), (casdll_val << SDLLOFFSET) | (1 << RUN_SDLLUPDWRRES)); + + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CASDLLCTRL(ch)) & (1 << RUN_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_push_cksdll_out(uint32_t ch, uint32_t cksdll_ovr_val) +{ + uint32_t cksdll_tap; + uint32_t ckdeskewcode; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + if (cksdll_ovr_val > (3 * mdllcode[ch][AMP_CA]) + 1) { + cksdll_tap = (3 * mdllcode[ch][AMP_CA]); + + if ((cksdll_ovr_val - cksdll_tap) >= MAX_DESKEW_PROGRAMMED) + ckdeskewcode = MAX_DESKEW_PROGRAMMED; + else + ckdeskewcode = cksdll_ovr_val - cksdll_tap; + + // Adjust deskew registers for each ck bit + CSR_WRITE(rAMP_CKDESKEW_CTRL(ch), ckdeskewcode | RUNDESKEWUPD); + if(cfg_params.chip_id == 0x8000) + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CKDESKEW_CTRL(ch)) & RUNDESKEWUPD); + + cksdll_ovr_val = (3 * mdllcode[ch][AMP_CA]); + } + + CSR_WRITE(rAMP_CKSDLLCTRL(ch), (cksdll_ovr_val << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CKSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_ck_sdll(uint32_t ch, uint32_t cksdll_val) +{ + CSR_WRITE(rAMP_CKSDLLCTRL(ch), (cksdll_val << SDLLOFFSET) | (1 << RUN_SDLLUPDWRRES)); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CKSDLLCTRL(ch)) & (1 << RUN_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_push_cssdll_out(uint32_t ch, uint32_t cssdll_ovr_val) +{ + uint32_t cssdll_tap; + uint32_t csdeskewcode; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + if (cssdll_ovr_val > (3 * mdllcode[ch][AMP_CA]) + 1) { + cssdll_tap = (3 * mdllcode[ch][AMP_CA]); + + if ((cssdll_ovr_val - cssdll_tap) >= MAX_DESKEW_PROGRAMMED) + csdeskewcode = MAX_DESKEW_PROGRAMMED; + else + csdeskewcode = cssdll_ovr_val - cssdll_tap; + + // Adjust deskew register for CS + CSR_WRITE(rAMP_CSDESKEW_CTRL(ch), csdeskewcode | RUNDESKEWUPD); + //SPIN_W_TMO_WHILE (CSR_READ(rAMP_CSDESKEW_CTRL(ch)) & RUNDESKEWUPD); + + cssdll_ovr_val = (3 * mdllcode[ch][AMP_CA]); + } + + CSR_WRITE(rAMP_CSSDLLCTRL(ch), (cssdll_ovr_val << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CSSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_cs_sdll(uint32_t ch, uint32_t cssdll_val) +{ + CSR_WRITE(rAMP_CSSDLLCTRL(ch), (cssdll_val << SDLLOFFSET) | (1 << RUN_SDLLUPDWRRES)); + + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CSSDLLCTRL(ch)) & (1 << RUN_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_dqs_weak_pden(uint32_t ch, uint8_t freq_bin) +{ + uint8_t byte, freq; + uint32_t rdcapcfg_freq; + uint32_t dqspdenalwayson; + + for(freq=0; freq < 4; freq++) { + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + DqsPdEn[ch][byte][freq] = (CSR_READ(rAMP_RDCAPCFG_FREQ(ch, byte, freq)) >> DQS_PDEN_OFFSET) & 0x1; + } + } + + if(freq_bin == 1) { + // Zero out all PdEn's except for Bin 3 + for(freq=0; freq < 4; freq++) { + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + if(freq != 3) { + rdcapcfg_freq = CSR_READ(rAMP_RDCAPCFG_FREQ(ch, byte, freq)); + CSR_WRITE(rAMP_RDCAPCFG_FREQ(ch, byte, freq), (rdcapcfg_freq & DQS_PDEN_MASK) | (0 << DQS_PDEN_OFFSET)); + } + } + } + } + else if(freq_bin == 0) { + // Zero out all PdEn's except for Bin 1 + for(freq=0; freq < 4; freq++) { + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + if(freq != 1) { + rdcapcfg_freq = CSR_READ(rAMP_RDCAPCFG_FREQ(ch, byte, freq)); + CSR_WRITE(rAMP_RDCAPCFG_FREQ(ch, byte, freq), (rdcapcfg_freq & DQS_PDEN_MASK) | (0 << DQS_PDEN_OFFSET)); + } + } + } + } + + // Set DQS PD EN ALWAYSON. + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + dqspdenalwayson = CSR_READ(rAMP_DQSPDENALWAYSON(ch, byte)); + CSR_WRITE(rAMP_DQSPDENALWAYSON(ch, byte), (dqspdenalwayson & ~DQSPDEN_ALWAYSON_MASK) | (1 << DQSPDEN_ALWAYSON_OFFSET)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_reset_dqs_weak_pden(uint32_t ch, uint8_t freq_bin) +{ + uint8_t byte, freq; + uint32_t rdcapcfg_freq; + uint32_t dqspdenalwayson; + + // Reset DQS PD EN ALWAYSON. + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + dqspdenalwayson = CSR_READ(rAMP_DQSPDENALWAYSON(ch, byte)); + CSR_WRITE(rAMP_DQSPDENALWAYSON(ch, byte), (dqspdenalwayson & ~DQSPDEN_ALWAYSON_MASK) | (0 << DQSPDEN_ALWAYSON_OFFSET)); + } + + if(freq_bin == 1) { + // Restore all PdEn's except for Bin 3 + for(freq=0; freq < 4; freq++) { + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + if(freq != 3) { + rdcapcfg_freq = CSR_READ(rAMP_RDCAPCFG_FREQ(ch, byte, freq)); + CSR_WRITE(rAMP_RDCAPCFG_FREQ(ch, byte, freq), (rdcapcfg_freq & DQS_PDEN_MASK) | (DqsPdEn[ch][byte][freq] << DQS_PDEN_OFFSET)); + } + } + } + } + else if(freq_bin == 0) { + // Restore all PdEn's except for Bin 1 + for(freq=0; freq < 4; freq++) { + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + if(freq != 1) { + rdcapcfg_freq = CSR_READ(rAMP_RDCAPCFG_FREQ(ch, byte, freq)); + CSR_WRITE(rAMP_RDCAPCFG_FREQ(ch, byte, freq), (rdcapcfg_freq & DQS_PDEN_MASK) | (DqsPdEn[ch][byte][freq] << DQS_PDEN_OFFSET)); + } + } + } + } +} + +#if DCS_REG_VERSION == 1 +_ROMCODE_SEGMENT_PREFIX void amp_set_dqs_idle_active(uint32_t ch, uint8_t byte) +{ + uint32_t dqfltctrl; + dqfltctrl = CSR_READ(rAMP_AMPSDQIOCFG_DQFLTCTRL(byte, ch)); + + dqfltctrl = (dqfltctrl & DQS_IDLE_ACTIVE_MASK) | (1 << DQS_IDLE_ACTIVE_OFFSET); + + CSR_WRITE(rAMP_AMPSDQIOCFG_DQFLTCTRL(byte, ch), dqfltctrl); +} + +_ROMCODE_SEGMENT_PREFIX void amp_reset_dqs_idle_active(uint32_t ch, uint8_t byte) +{ + uint32_t dqfltctrl; + dqfltctrl = CSR_READ(rAMP_AMPSDQIOCFG_DQFLTCTRL(byte, ch)); + + dqfltctrl = (dqfltctrl & DQS_IDLE_ACTIVE_MASK) | (0 << DQS_IDLE_ACTIVE_OFFSET); + + CSR_WRITE(rAMP_AMPSDQIOCFG_DQFLTCTRL(byte, ch), dqfltctrl); +} +#else +_ROMCODE_SEGMENT_PREFIX void amp_set_dqs_idle_active(uint32_t ch, uint32_t freq_bin) +{ + + uint32_t amph_cfgh_dqs0_wkpupd, amph_cfgh_dqs1_wkpupd; + + amph_cfgh_dqs0_wkpupd = CSR_READ(rAMPH_CFGH_DQS0_WKPUPD(ch)); + amph_cfgh_dqs1_wkpupd = CSR_READ(rAMPH_CFGH_DQS1_WKPUPD(ch)); + + + if(freq_bin == 0) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F0_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (1 << F0_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F0_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (1 << F0_IDLE_ACTIVE_OFFSET)); + } + else if(freq_bin == 1) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F1_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (1 << F1_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F1_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (1 << F1_IDLE_ACTIVE_OFFSET)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_reset_dqs_idle_active(uint32_t ch, uint32_t freq_bin) +{ + uint32_t amph_cfgh_dqs0_wkpupd, amph_cfgh_dqs1_wkpupd; + + amph_cfgh_dqs0_wkpupd = CSR_READ(rAMPH_CFGH_DQS0_WKPUPD(ch)); + amph_cfgh_dqs1_wkpupd = CSR_READ(rAMPH_CFGH_DQS1_WKPUPD(ch)); + + + // Also make sure that PDPWK_F1 is set. + if(freq_bin == 0) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F0_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (0 << F0_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F0_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (0 << F0_IDLE_ACTIVE_OFFSET)); + } + else if(freq_bin == 1) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F1_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (0 << F1_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F1_IDLE_ACTIVE_MASK) | (1 << F1_PDPWK_OFFSET) | (0 << F1_IDLE_ACTIVE_OFFSET)); + } +} +#endif + +_ROMCODE_SEGMENT_PREFIX void amp_enter_cacal_mode(uint32_t ch) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALENTRY); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALENTRY); +} + +_ROMCODE_SEGMENT_PREFIX void amp_exit_cacal_mode(uint32_t ch) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALEXIT); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALEXIT); +} + +_ROMCODE_SEGMENT_PREFIX void amp_run_cacal_vref(uint32_t ch) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + + // Set RunCaCalVref bit + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALVREF); + // Poll for RunCaCalVref to go low. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALVREF); +} + +_ROMCODE_SEGMENT_PREFIX static uint32_t amp_run_cacal(uint32_t ch, uint32_t training_mode) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + + if(training_mode == CS_TRAINING) { + // Set RunCaCalCS bit + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALCS); + + // Poll on the RunCaCalCS bit + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALCS); + } + + if((training_mode == CA_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Set RunCaCalCA bit + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALCA); + + // Poll on the RunCaCalCA bit + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALCA); + } + + return ((CSR_READ(rAMP_CACALRESULT(ch)) & CA_ALL_BITS)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk) +{ + // Program tWL, tRL for frequency bins 0-3 --> Should be part of the init sequence + + uint32_t rdwr_dqcal_loopcnt = CSR_READ(rAMP_RDWRDQCALLOOPCNT(ch)); + uint32_t rdwrdqcaltiming_f0 = CSR_READ(rAMP_RdWrDqCalTiming_f0(ch)); + uint32_t rdwrdqcaltiming_f1 = CSR_READ(rAMP_RdWrDqCalTiming_f1(ch)); + uint8_t tRL, tWL; + + // Program SWRDDQCAL Loop count + CSR_WRITE(rAMP_RDWRDQCALLOOPCNT(ch), (rdwr_dqcal_loopcnt & 0xFFFFFF00) | (cfg_params.rddq_cal_loopcnt & 0xFF)); + + // Init sequence sets up pattern & Invert mask registers (MR15, MR20, MR32 & MR40) + + // Set up tRL values for each frequency bucket + tRL = ((cfg_params.RL)/2) - 6; + tWL = ((cfg_params.WL)/2) - 4; + + if(cfg_params.freq_bin == 0) { + CSR_WRITE(rAMP_RdWrDqCalTiming_f0(ch), (rdwrdqcaltiming_f0 & 0xFFFFFF00) | (tWL << 4) | tRL); + } + else if(cfg_params.freq_bin == 1) { + shim_printf("amp_setup_rddq_cal:: Writing a value of 0x%x into rAMP_RdWrDqCalTiming_f1 \n", (rdwrdqcaltiming_f1 & 0xFFFFFF00) | (tWL << 4) | tRL); + CSR_WRITE(rAMP_RdWrDqCalTiming_f1(ch), (rdwrdqcaltiming_f1 & 0xFFFFFF00) | (tWL << 4) | tRL); + } + //CSR_WRITE(rAMP_RdWrDqCalTiming_f3(ch), (rdwrdqcaltiming_f3 & 0xFFFFFF00) | (0x0 << 4) | (0x0)); +} + +// This functions set the slave dll for a particular byte lane of RDDQ as specified in the offset parameter +_ROMCODE_SEGMENT_PREFIX void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_ovr_val) +{ + uint32_t rd_clk_dlysel; + + rd_clk_dlysel = rddqcal_encode_dlyval(ch, ((byte == 0) ? AMP_DQ0 : AMP_DQ1), rddqs_sdll_ovr_val); + + // Program RDDLYSEL + CSR_WRITE(rAMP_RDCLKDLYSEL(byte, ch), rd_clk_dlysel); + + // CP : Maui change + CSR_WRITE(rAMP_DQSDLLCTRL_RD(byte, ch), (rddqs_sdll_ovr_val << 16) | (1 << RUN_SDLLUPDOVR)); + + // Wait for Run bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) & (1 << RUN_SDLLUPDOVR)); + +} + +// This functions set the slave dll for a particular byte lane of RDDQ as specified in the offset parameter +_ROMCODE_SEGMENT_PREFIX void amp_program_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_wr_val) +{ + uint32_t rd_clk_dlysel; + + rd_clk_dlysel = rddqcal_encode_dlyval(ch, ((byte == 0) ? AMP_DQ0 : AMP_DQ1), rddqs_sdll_wr_val); + //shim_printf("DEBUG - rddqs_sdll_wr_val = %d, Phy = %d, rd_clk_dlysel = %d \n", rddqs_sdll_wr_val, ((byte == 0) ? AMP_DQ0 : AMP_DQ1), rd_clk_dlysel); + + // Program RDDLYSEL + CSR_WRITE(rAMP_RDCLKDLYSEL(byte, ch), rd_clk_dlysel); + + // CP : Maui change + CSR_WRITE(rAMP_DQSDLLCTRL_RD(byte, ch), (rddqs_sdll_wr_val << 16) | (1 << RUN_SDLLUPDWRRES)); + + // Wait for Run bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) & (1 << RUN_SDLLUPDWRRES)); + +} + +_ROMCODE_SEGMENT_PREFIX void amp_run_rddqcal(uint32_t ch) +{ + // CP : Maui Change + uint32_t dq_cal_run = CSR_READ(rAMP_DQCALRUN(ch)); + + CSR_WRITE(rAMP_DQCALRUN(ch), (dq_cal_run & 0xFFFFFFFE) | (1 << 0)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQCALRUN(ch)) & 1); +} + +_ROMCODE_SEGMENT_PREFIX void amp_wrlvl_init(void) +{ + uint32_t ch; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + // Write Leveling Timing Control Registers to program tMRD and tWLO timing params + CSR_WRITE(rAMP_CAWRLVLTIM(ch), (cfg_params.tWLO << 16) | (cfg_params.tWLMRD << 8) | (cfg_params.tWLDQSEN << 0)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_wrlvl_entry(uint32_t ch) +{ + uint32_t mr2_data, ca_run_wrlvl; + uint8_t wrlvl, wls, wl, rl; + uint8_t byte; + + // Setup MRW-1 & MRW-2 for write leveling entry + // rAMP_CAWRLVLENTRYCMD : (MRW_2[11:0] << 16) | (MRW_1[11:0] <<0) + // MRW_1[5:0] = {WR_LVL, 5'b00110} = 6'b100110 + // MRW_1[11:6] = MA[5:0] = 6'b000010 + // MRW_1[11:0] = 12'b000010100110=0x0A6 + // MRW_2[5:0] = {OP[6], 5'b10110} = {mr2_data[6], 5'b10110} + // MRW_2[11:6] = {OP[5:0]} = {mr2_data[5:0] + // Hence, rAMP_CAWRLVLENTRYCMD = {(mr2_data[5:0] << 18) | (mr2_data[6] << 17) | (0x16 << 16) | (0x0A6 << 0) + wrlvl = 1; + wls = 0; + + if(cfg_params.freq_bin == 0) { + if(cfg_params.WL == 12) { + wls = 0; + } + else if(cfg_params.WL == 22) { + wls = 1; + } + wl = 4; // 'b100 + rl = 4; // 'b100 + } + else { + if(cfg_params.WL == 8) { + wls = 0; + } + else if(cfg_params.WL == 12) { + wls = 1; + } + wl = 2; // 'b010 + rl = 2; // 'b010 + } + + mr2_data = (wrlvl << 7) | (wls << 6) | (wl << 3) | (rl << 0); + + CSR_WRITE(rAMP_CAWRLVLENTRYCMD(ch), ((mr2_data & 0x3F) << 22) | (((mr2_data & 0x40)>> 6) << 21) | (0x16 << 16) | (0x0A6 << 0)); + + + // + // DQS IdleActive should be set while write leveling is going on + for(byte = 0; byte < DQ_NUM_BYTES; byte++ ) { + amp_set_dqs_idle_active(ch, byte); + } + + // Set write leveling entry bit + ca_run_wrlvl = CSR_READ(rAMP_CARUNWRLVL(ch)); + CSR_WRITE(rAMP_CARUNWRLVL(ch), (ca_run_wrlvl & 0xFFFFFFFE) | (1 << RUNWRLVLENTRY_OFFSET)); + + // Poll for the RUNWRLVLENTRY bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CARUNWRLVL(ch)) & (1 << RUNWRLVLENTRY_OFFSET)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_wrlvl_exit(uint32_t ch, uint8_t freq_bin) +{ + uint32_t mr2_data, ca_run_wrlvl; + uint8_t wrlvl, wls, wl, rl; + uint32_t byte; + + // Setup MRW-1 & MRW-2 for write leveling exit + // rAMP_CAWRLVLEXITCMD : (MRW_2[11:0] << 16) | (MRW_1[11:0] <<0) + // MRW_1[5:0] = {WR_LVL=0, 5'b00110} = 6'b000110 + // MRW_1[11:6] = MA[5:0] = 6'b000010 + // MRW_1[11:0] = 12'b000010000110=0x086 + // MRW_2[5:0] = {OP[6], 5'b10110} = {mr2_data[6], 5'b10110} + // MRW_2[11:6] = {OP[5:0]} = {mr2_data[5:0] + // Hence, rAMP_CAWRLVLEXITCMD = {(mr2_data[5:0] << 18) | (mr2_data[6] << 17) | (0x16 << 16) | (0x086 << 0) + wrlvl = 0; + wls = 0; + + if(cfg_params.freq_bin == 0) { + if(cfg_params.WL == 12) { + wls = 0; + } + else if(cfg_params.WL == 22) { + wls = 1; + } + wl = 4; // 'b100 + rl = 4; // 'b100 + } + else { + if(cfg_params.WL == 8) { + wls = 0; + } + else if(cfg_params.WL == 12) { + wls = 1; + } + wl = 2; // 'b010 + rl = 2; // 'b010 + } + + mr2_data = (wrlvl << 7) | (wls << 6) | (wl << 3) | (rl << 0); + + CSR_WRITE(rAMP_CAWRLVLEXITCMD(ch), ((mr2_data & 0x3F) << 22) | (((mr2_data & 0x40)>> 6) << 21) | (0x16 << 16) | (0x086 << 0)); + + // Set write leveling exit bit + ca_run_wrlvl = CSR_READ(rAMP_CARUNWRLVL(ch)); + CSR_WRITE(rAMP_CARUNWRLVL(ch), (ca_run_wrlvl & 0xFFFFFFF7) | (1 << RUNWRLVLEXIT_OFFSET)); + + // Poll for the RUNWRLVLEXIT bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CARUNWRLVL(ch)) & (1 << RUNWRLVLEXIT_OFFSET)); + + // + // DQS IdleActive should be reset after write leveling is done. + for(byte = 0; byte < DQ_NUM_BYTES; byte++ ) { + amp_reset_dqs_idle_active(ch, byte); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t cawrlvl_code = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + cawrlvl_code = (cawrlvl_code & WRLVL_SDLLCODE_MASK) | (offset << WRLVL_SDLLCODE_OFFSET); + + CSR_WRITE(rAMP_CAWRLVLSDLLCODE(ch), cawrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_wrlvlmax_cawrlvl_sdll(uint32_t ch, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t cawrlvl_code = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + cawrlvl_code = (cawrlvl_code & WRLVLMAX_SDLLCODE_MASK) | (offset << WRLVLMAX_SDLLCODE_OFFSET); + + CSR_WRITE(rAMP_CAWRLVLSDLLCODE(ch), cawrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t dqwrlvl_code = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvl_code = (dqwrlvl_code & WRLVL_SDLLCODE_MASK) | (offset << WRLVL_SDLLCODE_OFFSET); + + // Byte 0 corresponds to DQ0, Byte 1 corresponds to DQ1 + CSR_WRITE(rAMP_DQWRLVLSDLLCODE(byte, ch), dqwrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_wrlvlmax_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t dqwrlvl_code = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvl_code = (dqwrlvl_code & WRLVLMAX_SDLLCODE_MASK) | (offset << WRLVLMAX_SDLLCODE_OFFSET); + + // Byte 0 corresponds to DQ0, Byte 1 corresponds to DQ1 + CSR_WRITE(rAMP_DQWRLVLSDLLCODE(byte, ch), dqwrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +// Must ensure that WrLvL SDLLs are stepped by 1 to their final value to avoid glitch on clock signals +_ROMCODE_SEGMENT_PREFIX void amp_program_cawrlvl_sdll(uint32_t ch, uint32_t cawrlvl_offset, uint32_t cawrlvlmax_offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t cawrlvl_code = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + //shim_printf("DEBUG - amp_program_cawrlvl_sdll:: cawrlvl_code=0x%x, cawrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK=0x%x , cawrlvl_offset = 0x%x, cawrlvlmax_offset=0x%x \n", cawrlvl_code, cawrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK, cawrlvl_offset, cawrlvlmax_offset); + cawrlvl_code = (cawrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK) | (cawrlvl_offset << WRLVL_SDLLCODE_OFFSET) | (cawrlvlmax_offset << WRLVLMAX_SDLLCODE_OFFSET); + + //shim_printf("DEBUG - amp_program_cawrlvl_sdll:: cawrlvl_code = 0x%x \n", cawrlvl_code); + + CSR_WRITE(rAMP_CAWRLVLSDLLCODE(ch), cawrlvl_code | (1 << RUNWRLVL_SDLLUPDWRRES)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & (1 << RUNWRLVL_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t dqwrlvl_offset, uint32_t dqwrlvlmax_offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t dqwrlvl_code = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvl_code = (dqwrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK) | (dqwrlvl_offset << WRLVL_SDLLCODE_OFFSET) | (dqwrlvlmax_offset << WRLVLMAX_SDLLCODE_OFFSET); + + //shim_printf("DEBUG - amp_program_dqwrlvl_sdll:: dqwrlvl_code = 0x%x \n", dqwrlvl_code); + + // Byte 0 corresponds to DQ0, Byte 1 corresponds to DQ1 + CSR_WRITE(rAMP_DQWRLVLSDLLCODE(byte, ch), dqwrlvl_code | (1 << RUNWRLVL_SDLLUPDWRRES)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & (1 << RUNWRLVL_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun) +{ + CSR_WRITE(rAMP_CARUNWRLVL(ch), ((wrlvlrun & 0x3) << RUNWRLVLDQ_OFFSET)); + SPIN_W_TMO_WHILE ((CSR_READ(rAMP_CARUNWRLVL(ch)) >> RUNWRLVLDQ_OFFSET) & 0x3); +} + +_ROMCODE_SEGMENT_PREFIX void cacal_init_registers() +{ + uint32_t ch; + for(ch=0;ch> CA_NUM_BITS; + //mask = patr ^ patf; + //cacal_patterns_mask[index] = mask; + cacal_patterns_mask[index] = 0x3F; + } +} + +// CP : Maui Change -> Pass an argument which tells if we are in CA or CS training. +// Use this argument to update CA or CS delay lines. +// Hardware loop for CS should always be > 1. +_ROMCODE_SEGMENT_PREFIX void cacal_run_sequence(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t mask_bits, uint32_t swloop, uint32_t vref) +{ + + uint32_t combined_mask, hwloop; + uint32_t pat_mask = 0; + + for (hwloop = 0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + pat_mask |= cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // This represents the bits that don't have a transition on any of the patterns used during the hwloop calibration + // PRBS4I pattern guarantees that there would be a 1->0 and 0->1 transition on every CA bit. Hence the combined + // mask can be set to 0x0 + combined_mask = 0; + + + // To find the FAIL <-> PASS <-> FAIL window + cacal_find_right_failing_point(ch, rnk, training_mode, combined_mask, swloop, vref); + cacal_find_left_failing_point(ch, rnk, training_mode, combined_mask, swloop, vref); +} + +// Establish the right edge of the window by finding the point where all CA bits fail +_ROMCODE_SEGMENT_PREFIX void cacal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + bool all_bits_fail = false; + uint32_t cacalresult = CA_ALL_BITS; + + // With an SDLL code of '0', CA is centered wrt CK. So to get to the right failing point, push CK by 180 degrees + // Increment CKSDLL & CSSDLL by 2*MDLL. In CA training, initial values of CKSDLL & CSSDLL would be the final CS center point values. + uint32_t push_ck_out = 2 * mdllcode[ch][AMP_CA] + cksdll_cscal[vref]; + uint32_t push_cs_out = 2 * mdllcode[ch][AMP_CA] + cssdll_cscal[vref]; + uint32_t push_ca_out = 2 * mdllcode[ch][AMP_CA] + casdll_cscal[vref]; + + uint32_t max_caright_point_val; + uint32_t max_caright_point_reached; + uint32_t step_size = COARSE_STEP_SZ; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + max_caright_point_val = (3 * mdllcode[ch][AMP_CA]) + 1; + max_caright_point_reached = 0; + + // If we skip CS training, clear CS & CA deskew registers during CA training + if(training_mode == CS_TRAINING) { + amp_init_ca_deskew(ch); + } + + // Increase delay to the right until all bits fail + do { + // Update CK signal delay + //shim_printf("DEBUG - cacal_find_right_failing_point:: Programming a value of 0x%x into CKSDLL \n",push_ck_out); + amp_push_cksdll_out(ch, push_ck_out); + + // CS training would align CK and CS correctly. To maintain that alignment, CK and CS should be delayed by the same amount + // during CA training + if(training_mode == CA_TRAINING) { + //shim_printf("DEBUG - cacal_find_right_failing_point:: Programming a value of 0x%x into CSSDLL \n",push_cs_out); + amp_push_cssdll_out(ch, push_cs_out); + } + // Maintain CK and CA alignment during fine tuned CS training. + else if(training_mode == CS_FINE_TRAINING) { + //shim_printf("DEBUG - cacal_find_right_failing_point:: Programming a value of 0x%x into CASDLL \n",push_ca_out); + amp_push_casdll_out(ch, push_ca_out); + } + + cacalresult = cacalresult & amp_run_cacal(ch, training_mode); + //shim_printf("DEBUG - cacal_find_right_failing_point:: CA cal result is 0x%x \n",cacalresult); + + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = false; + + // If the next increment of tap value is over the maximum allowed tap value, switch + // from coarse stepping to fine stepping. + if(((push_ck_out + step_size) > max_caright_point_val) || ((push_cs_out + step_size) > max_caright_point_val) || ((push_ca_out + step_size) > max_caright_point_val)) { + step_size = FINER_STEP_SZ; + } + + push_ck_out = push_ck_out + step_size; + if(training_mode == CA_TRAINING) { + push_cs_out = push_cs_out + step_size; + } + else if(training_mode == CS_FINE_TRAINING) { + push_ca_out = push_ca_out + step_size; + } + + } else { + all_bits_fail = true; + //shim_printf("DEBUG - cacal_find_right_failing_point:: All bits failed. Moved on to cacal_find_right_passing_point \n"); + + // Do a per bit calculation of when they start passing again + cacal_find_right_passing_point(ch, rnk, training_mode, combined_mask, swloop, vref); + break; + } + + max_caright_point_reached = (training_mode == CA_TRAINING) ? ((push_ck_out > max_caright_point_val) || (push_cs_out > max_caright_point_val)) + : (training_mode == CS_FINE_TRAINING) ? ((push_ck_out > max_caright_point_val) || (push_ca_out > max_caright_point_val)) : (push_ck_out > max_caright_point_val); + } while (max_caright_point_reached == 0); + + if (all_bits_fail == false) { + //shim_panic("Memory CA calibration: Unable to find right side failing point for channel %d\n", ch); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: Unable to find right side failing point for channel %d\n", ch); + cacal_vref_panic[ch][vref] = 1; + } + + // Ok from Rakesh to set to cksdll_cscal directly instead of decrementing by 1 + amp_push_cksdll_out(ch, cksdll_cscal[vref]); + + if(training_mode == CA_TRAINING) { + amp_push_cssdll_out(ch, cssdll_cscal[vref]); + } + else if(training_mode == CS_FINE_TRAINING) { + amp_push_casdll_out(ch, casdll_cscal[vref]); + } +} + +// Finds the passing region on the right edge of window +_ROMCODE_SEGMENT_PREFIX void cacal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + bool switch_from_cktoca; + uint32_t tap_value, tap_value_cs, tap_value_ca; + uint32_t cacalresult; + uint32_t saved_val; + uint32_t all_bits_pass; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + uint32_t bit_indx; + uint32_t ckdeskew, cksdll, cssdll, csdeskew, casdll; + uint32_t loopchrnk_indx; + //uint32_t casdllcode_casdllovrval; + + all_bits_pass = 0; + ckdeskew = CSR_READ(rAMP_CKDESKEW_CTRL(ch)); + csdeskew = CSR_READ(rAMP_CSDESKEW_CTRL(ch)); + cksdll = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + casdll = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + // For every swloop, we'll save passing values for each channel & rank + loopchrnk_indx = loopchrnk_index_calc(ch, rnk, swloop); + + // CP : Maui Change + // CK SDLL will always be > 0. Also, given the range of CK SDLL, i assume that we never had to + // increment CK Deskew to find the right side failing point. + tap_value = cksdll; + tap_value_cs = cssdll; + tap_value_ca = casdll; + switch_from_cktoca = false; + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those done + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + // Finding Right side passing point on per bit level. Moving Right to Left to find point where it turns from FAIL TO PASS + do { + if (switch_from_cktoca == false) { + + // Update CK signal delays + //shim_printf("DEBUG - cacal_find_right_passing_point:: Programming a value of 0x%x into CKSDLL \n",tap_value); + amp_push_cksdll_out(ch, tap_value); + + // CS training would align CK and CS correctly. To maintain that alignment, CK and CS should be delayed by the same amount + // during CA training + if(training_mode == CA_TRAINING) { + amp_push_cssdll_out(ch, tap_value_cs); + } + else if(training_mode == CS_FINE_TRAINING) { + amp_push_casdll_out(ch, tap_value_ca); + } + } else { + if(training_mode == CA_TRAINING) { + amp_push_casdll_out(ch, tap_value); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + amp_push_cssdll_out(ch, tap_value); + } + } + + // Run the ca/cs calibration in hw + cacalresult = amp_run_cacal(ch, training_mode); + + //shim_printf("DEBUG - cacal_find_right_passing_point:: CA cal result is 0x%x \n",cacalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + // For bits that are not masked, need to check pass/fail + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // Bit has passed for SOLID_PASS_DETECT number of times, consider it done. + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // This is the first time this bit has passed, save this point in the array + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + saved_val = tap_value; + if (switch_from_cktoca == false) { + if(training_mode == CA_TRAINING) { + cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx] = saved_val; + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CA right passing point for vref=%d, loopchrnk_indx=%d, bit_indx=%d, saved_val = %d \n",vref,loopchrnk_indx,bit_indx,cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx]); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Subtract cssdll to take into account the case where CS sdll is non-zero, before starting CS calibration. + cscal_per_loopchrnk_right[loopchrnk_indx] = (saved_val - cssdll); + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CS right passing point for loopchrnk_indx=%d, saved_val = %d \n",loopchrnk_indx,cscal_per_loopchrnk_right[loopchrnk_indx]); + } + } else { + if(training_mode == CA_TRAINING) { + cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx] = -1 * saved_val; + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CA right passing point for vref=%d, loopchrnk_indx=%d, bit_indx=%d, saved_val = %d \n",vref,loopchrnk_indx,bit_indx,cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx]); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Subtract cksdll to take into account the case where CK sdll is non-zero, before starting CS calibration. + cscal_per_loopchrnk_right[loopchrnk_indx] = -1 * (saved_val - cksdll_cscal[vref]); + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CS right passing point for loopchrnk_indx=%d, saved_val = %d \n",loopchrnk_indx,cscal_per_loopchrnk_right[loopchrnk_indx]); + } + } + } + } else { + // Bit failed to pass calibration, reset the SolidBitPass value to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // If ALL bits are not passing - keep moving ca/cs signals from Right to Left + if (all_bits_pass == 0) { + // CP : Maui Change + if ((tap_value == cksdll_cscal[vref]) && (switch_from_cktoca == false)) { + switch_from_cktoca = true; + + // Make tap_value '0' just in case cksdll_cscal > 0 + tap_value = 0; + } + + if (switch_from_cktoca == false) { + tap_value = tap_value - FINER_STEP_SZ; + if(training_mode == CA_TRAINING) { + tap_value_cs = tap_value_cs - FINER_STEP_SZ; + } + else if(training_mode == CS_FINE_TRAINING) { + tap_value_ca = tap_value_ca - FINER_STEP_SZ; + } + + } else { + tap_value = tap_value + FINER_STEP_SZ; + } + } + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + } while ((tap_value <= (3 * mdllcode[ch][AMP_CA] + 1)) && (all_bits_pass == 0)); + + if (all_bits_pass == 0) { + //shim_panic("Memory CA calibration: Unable to find passing point for all bits on the right side \n"); + shim_printf("PANIC during Vref scan.Record and move forward:Memory CA calibration: Unable to find passing point for all bits on the right side \n"); + cacal_vref_panic[ch][vref] = 1; + } +} + +_ROMCODE_SEGMENT_PREFIX void cacal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + // At this point, we've already played with all possible CK delays. At the end of cacal_find_right_failing_point routine, + // we reset the CK delays to 0. + // Loop through CaSDLLOvrVal from -MasterDLL to +Max until all failing points on the left side are found + + uint32_t all_bits_fail; + uint32_t push_ca_out; + uint32_t push_cs_out; + uint32_t cacalresult; + uint32_t max_caleft_point_reached; + uint32_t max_casdll_reached; + uint32_t max_caleft_point_val; + uint32_t casdllcode, ca0deskewctrl; + uint32_t cssdllcode, csdeskewctrl; + uint32_t step_size = COARSE_STEP_SZ; + + all_bits_fail = 0; + cacalresult = CA_ALL_BITS; + max_caleft_point_reached = 0; + max_casdll_reached = 0; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + max_caleft_point_val = (3 * mdllcode[ch][AMP_CA] + 1); + + casdllcode = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + ca0deskewctrl = CSR_READ(rAMP_CADESKEW_CTRL(ch, 0)); + + cssdllcode = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + csdeskewctrl = CSR_READ(rAMP_CSDESKEW_CTRL(ch)); + + push_ca_out = casdllcode + ca0deskewctrl; + push_cs_out = cssdllcode + csdeskewctrl; + + // Increment CaSDLL/CsSDLL from 0 to max_caleft_point_reached + do { + + if(training_mode == CA_TRAINING) { + // Push out this new ca offset + //shim_printf("DEBUG - cacal_find_left_failing_point:: Pushing out CASDLL by 0x%x taps \n",push_ca_out); + // Push out this new ca offset + amp_push_casdll_out(ch, push_ca_out); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Push out this new cs offset + //shim_printf("DEBUG - cacal_find_left_failing_point:: Pushing out CSSDLL by 0x%x taps \n",push_cs_out); + amp_push_cssdll_out(ch, push_cs_out); + } + + // Run the CA/CS calibration + cacalresult = amp_run_cacal(ch, training_mode); + + //shim_printf("DEBUG - cacal_find_left_failing_point:: CA cal result is 0x%x \n",cacalresult); + + // combined mask has don't care bits (based on pattern) and masked bits (based on MR41 or MR48) that we should ignore + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = 0; + } else { + all_bits_fail = 1; + + // Now, we have found the left edge of window. Find the passing point for all bits + cacal_find_left_passing_point(ch, rnk, training_mode, combined_mask, swloop, vref); + break; + } + + if (all_bits_fail == 0) { + if(training_mode == CA_TRAINING) { + + // If the next increment of tap value is over the maximum allowed tap value, switch + // from coarse stepping to fine stepping. + if(push_ca_out + step_size > max_caleft_point_val) { + step_size = FINER_STEP_SZ; + } + + push_ca_out = push_ca_out + step_size; + + if ((push_ca_out > max_caleft_point_val) && (all_bits_fail == 0)) { + //shim_panic("Memory CA calibration: Unable to find failing point for all bits on the left side"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: Unable to find failing point for all bits on the left side"); + cacal_vref_panic[ch][vref] = 1; + } + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + if(push_cs_out + step_size > max_caleft_point_val) { + step_size = FINER_STEP_SZ; + } + + push_cs_out = push_cs_out + step_size; + + if ((push_cs_out > max_caleft_point_val) && (all_bits_fail == 0)) { + //shim_panic("Memory CS calibration: Unable to find failing point for all bits on the left side"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CS calibration: Unable to find failing point for all bits on the left side"); + cacal_vref_panic[ch][vref] = 1; + } + } + } + if(training_mode == CA_TRAINING) { + if (push_ca_out > max_caleft_point_val) { + max_caleft_point_reached = 1; + } + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + if (push_cs_out > max_caleft_point_val) { + max_caleft_point_reached = 1; + } + } + + // Panic if there are no more sdll taps left to proceed ahead + if (max_caleft_point_reached && (all_bits_fail == 0)) + { + //shim_panic("Memory CA calibration: SDLL ran out of taps when trying to find left side failing point\n"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: SDLL ran out of taps when trying to find left side failing point\n"); + cacal_vref_panic[ch][vref] = 1; + + } + } while ((all_bits_fail == 0) && (max_caleft_point_reached == 0)); +} + +_ROMCODE_SEGMENT_PREFIX void cacal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + uint32_t loopchrnk_indx; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + uint32_t tap_value; + uint32_t cacalresult; + uint32_t camdllcode; + uint32_t casdllcode; + uint32_t ca0deskewctrl; + uint32_t cssdllcode; + uint32_t csdeskew; + uint32_t saved_val; + uint32_t all_bits_pass; + uint32_t bit_indx; + + loopchrnk_indx = loopchrnk_index_calc(ch, rnk, swloop); + + casdllcode = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + ca0deskewctrl = CSR_READ(rAMP_CADESKEW_CTRL(ch, 0)); + camdllcode = mdllcode[ch][AMP_CA]; + csdeskew = CSR_READ(rAMP_CSDESKEW_CTRL(ch)); + cssdllcode = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + all_bits_pass = 0; + + // CP : Maui Change + if(training_mode == CA_TRAINING) { + tap_value = casdllcode; + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + tap_value = cssdllcode; + } + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those passed + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + + // Finding Left side passing point on per bit level. Move Left to Right to find point where it turns from FAIL TO PASS + do { + // Push out this new CA/CS offset + if(training_mode == CA_TRAINING) { + // Push out this new ca offset + amp_push_casdll_out(ch, tap_value); + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Push out this new cs offset + //shim_printf("DEBUG - cacal_find_left_passing_point:: Pushing out CSSDLL by 0x%x taps \n",tap_value); + amp_push_cssdll_out(ch, tap_value); + } + + // Run the CA/CS calibration + cacalresult = amp_run_cacal(ch, training_mode); + + //shim_printf("DEBUG - cacal_find_left_passing_point:: CA cal result is 0x%x \n",cacalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + // check pass/fail for bits not masked + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // bit has passed SOLID_PASS_DETECT straight times, consider it done + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // first time bit has passed, record this value + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + saved_val = tap_value; + if(training_mode == CA_TRAINING) { + // Effective CA tap value would be saved_val - (CK SDLL value after CS calibration). + cacal_per_loopchrnk_left[loopchrnk_indx][vref][bit_indx] = -1 * (saved_val - cksdll_cscal[vref]) ; + //shim_printf("DEBUG - cacal_find_left_passing_point:: Found CA left passing point for vref=%d, loopchrnk_indx=%d, bit_indx=%d, saved_val = %d \n",vref,loopchrnk_indx,bit_indx,cacal_per_loopchrnk_left[loopchrnk_indx][vref][bit_indx]); + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Effective CS tap value would be saved_val - (CK SDLL value after CS calibration). + cscal_per_loopchrnk_left[loopchrnk_indx] = -1 * (saved_val - cksdll_cscal[vref]); + //shim_printf("DEBUG - cacal_find_left_passing_point:: Found CS left passing point for loopchrnk_indx=%d, saved_val = %d \n",loopchrnk_indx,cscal_per_loopchrnk_left[loopchrnk_indx]); + } + } + } else { + // bit failed calibration, reset the SolidBitPass value back to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // TODO TODO: Make (tap_value < FINER_STEP_SZ) change at other places too + if ((tap_value < FINER_STEP_SZ) && (all_bits_pass == 0)) { + // print error message as Left Passing Point cannot be found + //shim_panic("Memory CA calibration: Unable to find passing point for all bits on the left side \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: Unable to find passing point for all bits on the left side \n"); + cacal_vref_panic[ch][vref] = 1; + break; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window + if (all_bits_pass == 0) { + tap_value -= FINER_STEP_SZ; + } + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + } while ((tap_value <= (3 * mdllcode[ch][AMP_CA] + 1)) && (all_bits_pass == 0)); +} + +_ROMCODE_SEGMENT_PREFIX void cacal_program_final_values(void) +{ + uint32_t ch; + uint32_t bit_indx; + int32_t arr_CaBitCenterPoint[CA_NUM_BITS]; + //uint32_t arr_CaBitDeSkew[CA_NUM_BITS]; + int32_t tmp_left_pos_val, tmp_right_pos_val; + int32_t left_pos_val; + int32_t right_pos_val; + uint32_t camdllcode; + int32_t max_CaBitCenterPoint_val; + int32_t ckcs_diff,cabit_deskew; + uint32_t casdllcode; + uint8_t byte; + uint32_t freqchngctl1; + int32_t ckcs_diff_opt; + + int32_t rank_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t swloop; + uint32_t loopchrnk0_indx, chrnk0_indx; + uint32_t vref_ch; + uint32_t ca_vref_value; +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + uint32_t vref0 = vref_opt_ca[loopchrnk000]; + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + loopchrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_ca[loopchrnk0_indx] = vref0; + + //shim_printf("DEBUG - cacal_program_final_values:: loopchrnk0_indx = %d, vref_ch=%d \n", loopchrnk0_indx, vref_ch); + + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx] = cacal_per_loopchrnk_left[loopchrnk000][vref0][bit_indx]; + cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx] = cacal_per_loopchrnk_right[loopchrnk000][vref0][bit_indx]; + + //shim_printf("DEBUG - cacal_program_final_values:: cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx] = %d \n", cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx]); + //shim_printf("DEBUG - cacal_program_final_values:: cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx] = %d \n", cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx]); + } + } +#endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + casdllcode = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + camdllcode = mdllcode[ch][AMP_CA]; + + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_ca[chrnk0_indx]; + // Calculate the Center Points for each CA bit + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + //comb_mask = 0x0; + //mask_txn_detect = 0x0; + //tmp_mask = 0x0; + + // Compute the aggr eye over multiple swloop and hwloop for all ranks + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + loopchrnk0_indx = loopchrnk_index_calc(ch, 0, swloop); + //mask = 0x0; + //for (hwloop=0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + // mask = mask | cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // An explanation of the masks is below. Note that we only recorded result for a bit from a particular iteration if the bit had a transition. + // mask: for pattern(s) sent in this swloop, indicates if the bit had a transition + // tmp_mask: aggregates mask over all loops, including current swloop + // comb_mask: aggregates mask over all loops, upto the last iteration of the swloop. After it is used to generate mask_txn_detect, it catches upto same value as tmp_mask + // mask_txn_detect: indicates the first time a bit transitioned was in this swloop + //tmp_mask = tmp_mask | mask; + //mask_txn_detect = tmp_mask ^ comb_mask; + //comb_mask = comb_mask | mask; + + /* + * Rank 0 + */ + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[0] = cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx]; + tmp_left_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + //if (mask_txn_detect & (1 << bit_indx)) { + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + //} else if (mask & (1 << bit_indx)) { + // // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // // to compare with, find the value that would cover both points and put that in the array + // left_pos_val = cacal_per_chrnk_left[chrnk0_indx][bit_indx]; + // left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + //} else { + // // + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + //} + + if(swloop == 0) { + left_pos_val = tmp_left_pos_val; + cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = cacal_per_chrnk_left[chrnk0_indx][bit_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MAX_ENDPT); + cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } + + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[0] = cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx]; + tmp_right_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + //if (mask_txn_detect & (1 << bit_indx)) { + // right_pos_val = tmp_right_pos_val; + // cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + //} else if (mask & (1 << bit_indx)) { + // // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // // to compare with, find the value that would cover both points and put that in the array + // right_pos_val = cacal_per_chrnk_right[chrnk0_indx][bit_indx]; + // right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MIN_ENDPT); + // cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + //} else { + // // + // right_pos_val = tmp_right_pos_val; + // cacal_per_chrnk_right[chrnk0_indx][bit_indx] = 0; + //} + + if(swloop == 0) { + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cacal_per_chrnk_right[chrnk0_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MIN_ENDPT); + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } + + } + + // At this point, the left edge and the right edge of the eye for this channel and bit are defined by left_pos_val and right_pos_val + // Find the center of the eye + arr_CaBitCenterPoint[bit_indx] = find_center_of_eye(cacal_per_chrnk_left[chrnk0_indx][bit_indx],cacal_per_chrnk_right[chrnk0_indx][bit_indx]); + } + + // Since center for each bit may be different, find the max val + // Max val will get programmed to the ckdll (if Max >=0) or to casdll (if Max <0), while the other bits will require deskew + max_CaBitCenterPoint_val = arr_CaBitCenterPoint[0]; + + for (bit_indx = 1; bit_indx < CA_NUM_BITS; bit_indx++) { + + if(arr_CaBitCenterPoint[bit_indx] > max_CaBitCenterPoint_val) { + max_CaBitCenterPoint_val = arr_CaBitCenterPoint[bit_indx]; + } + } + + /* + * Finally, program the values + * Adjust CKSDLL, CSSDLL and CASDLL such that + 1. Their relative difference is maintained + 2. None of the SDLL values are negative + */ + + // Calculate our delay point for CK SDLL and CS SDLL + ckcs_diff = cksdll_cscal[vref_ch] - cssdll_cscal[vref_ch]; + + if (max_CaBitCenterPoint_val >= 0) { + if (ckcs_diff > 0) { + if (max_CaBitCenterPoint_val > ckcs_diff) { + amp_program_ck_sdll(ch, max_CaBitCenterPoint_val); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = max_CaBitCenterPoint_val; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, max_CaBitCenterPoint_val - ckcs_diff); + amp_program_ca_sdll(ch, 0); + + } + else { + amp_program_ck_sdll(ch, max_CaBitCenterPoint_val + (ckcs_diff - max_CaBitCenterPoint_val)); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = max_CaBitCenterPoint_val + (ckcs_diff - max_CaBitCenterPoint_val); + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, 0); + amp_program_ca_sdll(ch, (ckcs_diff - max_CaBitCenterPoint_val)); + } + shim_printf("DEBUG - cacal_program_final_values:: ch = %d, max_CaBitCenterPoint_val = %d \n ", ch, max_CaBitCenterPoint_val); + } + else { + amp_program_ck_sdll(ch, max_CaBitCenterPoint_val); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = max_CaBitCenterPoint_val; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, max_CaBitCenterPoint_val - ckcs_diff); + amp_program_ca_sdll(ch, 0); + shim_printf("DEBUG - cacal_program_final_values:: ch = %d, max_CaBitCenterPoint_val = %d \n ", ch, max_CaBitCenterPoint_val); + } + } + else { + ckcs_diff_opt = cksdll_cscal[vref_opt_ca[loopchrnk0_indx]] - cssdll_cscal[vref_opt_ca[loopchrnk0_indx]]; + + if(cfg_params.chip_id == 0x8000 && ckcs_diff > 0) { + amp_program_ck_sdll(ch, ckcs_diff); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = ckcs_diff; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte] , 0); + } + + amp_program_cs_sdll(ch, 0); + amp_program_ca_sdll(ch, __abs(max_CaBitCenterPoint_val) + ckcs_diff); + } else if(cfg_params.chip_id != 0x8000 && ckcs_diff_opt > 0) { + amp_program_ck_sdll(ch, ckcs_diff_opt); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = ckcs_diff_opt; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte] , 0); + } + + amp_program_cs_sdll(ch, 0); + amp_program_ca_sdll(ch, __abs(max_CaBitCenterPoint_val) + ckcs_diff_opt); + } else { + amp_program_ck_sdll(ch, 0); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = 0; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, -ckcs_diff); + amp_program_ca_sdll(ch, __abs(max_CaBitCenterPoint_val)); + } + } + + // Push the remainder of the delay on CA deskew signals + // Since the max value of all bits was chosen for sdll, if the rest of the bits need more delay, compute their deskew + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + // We need not use __abs(max_CaBitCenterPoint_val) here + cabit_deskew = max_CaBitCenterPoint_val - arr_CaBitCenterPoint[bit_indx]; + + if(cabit_deskew < 0) { + //shim_panic("Memory CA Calibration: cabit_deskew for bit_indx:%d is negative \n", bit_indx); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA Calibration: cabit_deskew for bit_indx:%d is negative \n", bit_indx); + cacal_vref_panic[ch][vref_ch] = 1; + } + + // Program the CA Deskew values for each bit + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit_indx), cabit_deskew | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, bit_indx)) & RUNDESKEWUPD); + } + + // Set up DRAM mode register with the optimal CA Vref. + ca_vref_value = (cfg_params.freq_bin == 0) ? cfg_params.ca_vref_values_f0[vref_ch] : cfg_params.ca_vref_values_f1[vref_ch]; + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, 0, MR12, ca_vref_value); + + // Program MCU registers for optimal CA Vref + if(cfg_params.freq_bin == 1) { + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch)); + + if(cfg_params.chip_id ==0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0xFFFF0000) | (0xC) | (ca_vref_value << 8)); + else + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0xFFFF) | (0xC << 16) | (ca_vref_value << 24)); + } + else if(cfg_params.freq_bin == 0) { + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch)); + + if(cfg_params.chip_id ==0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0xFFFF0000) | (0xC) | (ca_vref_value << 8)); + else + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0xFFFF) | (0xC << 16) | (ca_vref_value << 24)); + } + } +} + +_ROMCODE_SEGMENT_PREFIX void cacal_program_cs_training_values(void) +{ + uint32_t loopchrnk0_indx, chrnk0_indx, ch; + // Center point of CS training + int32_t arr_CsBitCenterPoint; + int32_t tmp_left_pos_val, tmp_right_pos_val; + int32_t left_pos_val; + int32_t right_pos_val; + uint8_t byte; + + int32_t rank_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t swloop; + +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + + cscal_per_loopchrnk_left[chrnk0_indx] = cscal_per_loopchrnk_left[loopchrnk000]; + cscal_per_loopchrnk_right[chrnk0_indx] = cscal_per_loopchrnk_right[loopchrnk000]; + + //shim_printf("DEBUG - cscal_program_final_values:: cscal_per_loopchrnk_left[%d] = %d , cscal_per_loopchrnk_right[%d] = %d \n", loopchrnk0_indx, cscal_per_loopchrnk_left[loopchrnk0_indx], loopchrnk0_indx, cscal_per_loopchrnk_right[loopchrnk0_indx]); + + } +#endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + // Calculate the Center Points for CK bit + //comb_mask = 0x0; + //mask_txn_detect = 0x0; + //tmp_mask = 0x0; + + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + // Compute the aggr eye over multiple swloop and hwloop for all ranks + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + loopchrnk0_indx = loopchrnk_index_calc(ch, 0, swloop); + //mask = 0x0; + //for (hwloop=0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + // mask = mask | cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // An explanation of the masks is below. Note that we only recorded result for a bit from a particular iteration if the bit had a transition. + // mask: for pattern(s) sent in this swloop, indicates if the bit had a transition + // tmp_mask: aggregates mask over all loops, including current swloop + // comb_mask: aggregates mask over all loops, upto the last iteration of the swloop. After it is used to generate mask_txn_detect, it catches upto same value as tmp_mask + // mask_txn_detect: indicates the first time a bit transitioned was in this swloop + //tmp_mask = tmp_mask | mask; + //mask_txn_detect = tmp_mask ^ comb_mask; + //comb_mask = comb_mask | mask; + + /* + * Rank 0 + */ + + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[0] = cscal_per_loopchrnk_left[loopchrnk0_indx]; + tmp_left_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + // if (mask_txn_detect & (1 << bit_indx)) { + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + // } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + // left_pos_val = cacal_per_chrnk_left[chrnk0_indx][bit_indx]; + // left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + // } else { + // // + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + // } + + if(swloop == 0) { + left_pos_val = tmp_left_pos_val; + cscal_per_chrnk_left[chrnk0_indx] = left_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = cscal_per_chrnk_left[chrnk0_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MAX_ENDPT); + cscal_per_chrnk_left[chrnk0_indx] = left_pos_val; + } + + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[0] = cscal_per_loopchrnk_right[loopchrnk0_indx]; + tmp_right_pos_val = rank_val[0]; + + /* // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cacal_per_chrnk_right[chrnk0_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MAX_ENDPT); + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else { + // + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = 0; + } + */ + + if(swloop == 0) { + right_pos_val = tmp_right_pos_val; + cscal_per_chrnk_right[chrnk0_indx] = right_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cscal_per_chrnk_right[chrnk0_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MIN_ENDPT); + cscal_per_chrnk_right[chrnk0_indx] = right_pos_val; + } + + } + // At this point, the left edge and the right edge of the eye for this channel and bit are defined by left_pos_val and right_pos_val + // Find the center of the eye + arr_CsBitCenterPoint = find_center_of_eye(cscal_per_chrnk_left[chrnk0_indx], cscal_per_chrnk_right[chrnk0_indx]); + + /* + * Finally, program the values + * If the center point is positive, put the magnitude on CKSDLL. + * If the center point is negative, put the magnitude on CSSDLL. + */ + if(arr_CsBitCenterPoint >= 0) { + // Program the CK SDLL with the center point value + amp_program_ck_sdll(ch, arr_CsBitCenterPoint); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = arr_CsBitCenterPoint; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, 0); + } else { + // Program the CS SDLL with the center point value + amp_program_cs_sdll(ch, __abs(arr_CsBitCenterPoint)); + amp_program_ck_sdll(ch, 0); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = 0; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + } + } +} + +// Loop through PerBitDeskewCode ranges for rddq until failing points for each byte (& bit) are found. +// Maui Change: Right failing to left failing. +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal) +{ + uint32_t dq_deskew; + uint32_t all_bits_fail; + uint32_t bits_fail_b[DQ_NUM_BYTES] = { 0 }; + // CP : Maui Change + uint32_t rddqcalresult, result_swiz; + uint32_t mask_b[DQ_NUM_BYTES]; + uint32_t start_b[DQ_NUM_BYTES]; + uint32_t byte, bit;//, dqbyte; + uint32_t step_size = COARSE_STEP_SZ; + + all_bits_fail = 0; + dq_deskew = 0; + + // set the rddq sdll to 0. + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // CP : Maui Change + amp_set_rddq_sdll(ch, byte, 0); + + // initialize the mask for each byte lane (Including DMI) + mask_b[byte] = (0xFF << (byte * 8)) | (0x1 << (byte + 16)); + } + + rddqcalresult = 0x3FFFF; + + // PerBit Deskew lines cannot be pushed beyond DQ_MAX_DESKEW_PER_BIT value + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) { + + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit), dq_deskew | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit)) & RUNDESKEWUPD); + } + + // Also move DMI for the byte here + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), dq_deskew | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + } + } + + // Call Basic run Dq Cal Commands + amp_run_rddqcal(ch); + //shim_printf("DEBUG - rddqcal_find_left_failing_point:: Running RDDQ cal with DQ deskew=0x%x \n",dq_deskew); + rddqcalresult = (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + //shim_printf("DEBUG - rddqcal_find_left_failing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + + result_swiz = rddqcalresult; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if all bits haven't failed yet and this run shows all bits failing, we have found the failing point for this byte + if ((bits_fail_b[byte] == 0) && ((result_swiz & mask_b[byte]) == 0)) { + bits_fail_b[byte] = 1; + start_b[byte] = dq_deskew; + } + } + + // FIMXE + all_bits_fail = bits_fail_b[0]; + for (byte = 1; byte < DQ_NUM_BYTES; byte++) { + all_bits_fail &= bits_fail_b[byte]; + } + + if (all_bits_fail == 1) { + // If failing point has been found for all bits, find the passing point now + // CP : Maui Change + rddqcal_find_left_passing_point(ch, rnk, vref, start_b, after_wrddqcal); + break; + } else { + // To find right failing point, make more negative adjustment to the sdll (same as incrementing deskew) + + // If the next increment of tap value is over the maximum allowed tap value, switch + // from coarse stepping to fine stepping. + if((dq_deskew + step_size) > DQ_MAX_DESKEW_PER_BIT) { + step_size = FINER_STEP_SZ; + } + + dq_deskew = dq_deskew + step_size; + } + + } while ((dq_deskew <= DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)); + + if (all_bits_fail == 0) { + // print error message as Left Failing Point cannot be found + //shim_panic("Memory Rddq cal: Left side failing point not found, max deskew limit reach for channel %d", ch); + shim_printf("PANIC during Vref scan. Record and move forward:Memory Rddq cal: Left side failing point not found, max deskew limit reach for channel %d", ch); + rddqcal_vref_panic[ch][vref] = 1; + } + + // Reset deskew for all bits to 0 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit), 0 | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit)) & RUNDESKEWUPD); + } + + // Also reset DMI deskew + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), 0 | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + } +} + +// Purpose of this function is to start from left side failing point and find locations for every DQ bit +// until the start of passing window for that bit is found +// Save all this locations to compute the center of window +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + uint32_t tap_value_b[DQ_NUM_BYTES]; + bool switch_from_dqtodqs, max_tap_value_reached; + uint32_t BitPass[DQ_TOTAL_BITS+DMI_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS+DMI_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + uint32_t dqmdllcode; + uint32_t saved_val; + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + all_bits_pass = 0; + switch_from_dqtodqs = false; + max_tap_value_reached = false; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Moving Right to Left to find point where each bit turns from FAIL TO PASS + do { + if (switch_from_dqtodqs == false) { + // continue to update per bit deskew until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx), tap_value_b[byte] | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + } + + // Also program DMI here + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), tap_value_b[byte] | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + + //shim_printf("DEBUG - rddqcal_find_left_passing_point:: Pushing byte %d by a DQ deskew of 0x%x \n",byte,tap_value_b[byte]); + } + } + } else { + // adjust rddqs sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + amp_set_rddq_sdll(ch, byte, tap_value_b[byte]); + //shim_printf("DEBUG - rddqcal_find_left_passing_point:: Pushing byte %d by DQS sdll of 0x%x \n",byte,tap_value_b[byte]); + } + } + } + + // Run rddq calibration in hw + amp_run_rddqcal(ch); + rddqcalresult = (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + //shim_printf("DEBUG - rddqcal_find_left_passing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (switch_from_dqtodqs == false) { + dqmdllcode = mdllcode[ch][byte+1]; + + saved_val = tap_value_b[byte]; + + // If saved_val is in terms of DQ deskew, save it as a negative number. + // If saved_val is in terms of DQS SDLL, save it as a positive number. + rddqcal_per_chrnk_left[chrnk_indx][vref][bit_indx] = -1 * saved_val; + } else { + saved_val = tap_value_b[byte]; + rddqcal_per_chrnk_left[chrnk_indx][vref][bit_indx] = saved_val; + } + shim_printf("DEBUG - rddqcal_find_left_passing_point:: Found Left edge for channel %d bit %d at tap value %d \n",chrnk_indx,bit_indx,rddqcal_per_chrnk_left[chrnk_indx][vref][bit_indx]); + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Right to Left Side of window (by adding less negative adjustment to mdll) + if (all_bits_pass == 0) { + // Even if one of the byte lanes arrives early to tap_value = 0. Remain here until all byte lane catch up before proceeding to pushing out dq + + // check for all bytes reaching 0 on the tap value (could be deskew or sdll) + uint32_t all_bytes_tap = tap_value_b[0]; + for (byte = 1; (byte < DQ_NUM_BYTES) && (all_bytes_tap == 0); byte++) { + all_bytes_tap += tap_value_b[byte]; + } + + // if the tap_value for all bytes has reached 0 on the deskew, make the transition to SDLL + if ((all_bytes_tap == 0) && (switch_from_dqtodqs == false)) { + switch_from_dqtodqs = true; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + tap_value_b[byte] = ((CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) >> SDLLOFFSET) & DLLVAL_BITS); + } + } + // CP : Maui Change + //else if (switch_from_dqtodqs == true) { + // If any of the failing bytes has reached tap_value of 0, clear sign bit for that byte lane + // for (byte = 0; byte < DQ_NUM_BYTES; byte++) + //if ((all_bits_pass_b[byte]) == 0 && (tap_value_b[byte] == 0)) + // sgn_bit_b[byte] = 0; + //} + + // To find left side passing point, add positive adjustment to mdll (same as decrementing deskew) + + // For deskew taps, we just decrement by FINER_STEP_SZ if we haven't reached 0 yet + if (switch_from_dqtodqs == false) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (tap_value_b[byte] > 0) + tap_value_b[byte] -= FINER_STEP_SZ; + } else { + // For sdll taps, increment by FINER_STEP_SZ + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + //if (sgn_bit_b[byte]) { + // if (tap_value_b[byte] <= FINER_STEP_SZ) { + // tap_value_b[byte] = 0; + // sgn_bit_b[byte] = 0; + // } else + // tap_value_b[byte] -= FINER_STEP_SZ; + //} + //else + // CP : Maui Change + tap_value_b[byte] += FINER_STEP_SZ; + } + } + } + } + + // trigger for loop to end if any of the bytes reach max tap value + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) { + max_tap_value_reached = (tap_value_b[byte] > (3 * mdllcode[ch][1 + byte])); + shim_printf("DEBUG - rddqcal_find_left_passing_point:: tap_value_b[%d] = %d, mdllcode[%d][%d] = %d , max_tap_value_reached = %d \n",byte,tap_value_b[byte],ch,1 + byte,mdllcode[ch][1 + byte],max_tap_value_reached); + } + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Unable to find left side passing point, max tap value reached"); + + rddqcal_vref_panic[ch][vref] = 1; + + break; + } + } + + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +// Purpose of this function is to start push DQS out till right side failing point of Data window is found +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal) +{ + uint32_t rddqsdll[DQ_NUM_BYTES]; + // CP : Maui Change + uint32_t rddqcalresult, result_swiz; + uint32_t all_bits_fail; + uint32_t all_bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t mask_b[DQ_NUM_BYTES]; + uint32_t start_b[DQ_NUM_BYTES]; + uint32_t byte; + bool max_tap_value_reached = false; + uint32_t step_size = COARSE_STEP_SZ; + + all_bits_fail = 0; + rddqcalresult = 0x3FFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // initialize the mask for each byte lane (Including DMI) + mask_b[byte] = (0xFF << (byte * 8)) | (0x1 << (byte + 16)); + + // Get the starting values for RD DQS SDLL + rddqsdll[byte] = ((CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) >> SDLLOFFSET) & DLLVAL_BITS); + } + + // To find left failing point, keep adding less negative adjustment to mdll + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // set the new sdll for this byte lane if all bits are not yet failing + if (all_bits_fail_b[byte] == 0) { + amp_set_rddq_sdll(ch, byte, rddqsdll[byte]); + //shim_printf("DEBUG - rddqcal_find_right_failing_point:: Pushing byte %d by DQS sdll of 0x%x \n",byte,rddqsdll[byte]); + } + } + + // Run rddqcal in hw + amp_run_rddqcal(ch); + rddqcalresult &= (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + //shim_printf("DEBUG - rddqcal_find_right_failing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + + // Account for swizzled bits and bytes of the result + // + result_swiz = rddqcalresult; + + + // If the result of all bits in this byte show a fail, record this as the failing point + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((all_bits_fail_b[byte] == 0) && ((result_swiz & mask_b[byte]) == 0)) { + all_bits_fail_b[byte] = 1; + start_b[byte] = rddqsdll[byte]; + } + + all_bits_fail &= all_bits_fail_b[byte]; + } + + // all bytes fail, call the function to find right passing point + if (all_bits_fail == 1) { + rddqcal_find_right_passing_point(ch, rnk, vref, start_b, after_wrddqcal); + } else { + // if the byte has not yet failed, find the next sdll value to be set + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) { + if((rddqsdll[byte] + step_size) > (3 * mdllcode[ch][1 + byte])) { + step_size = FINER_STEP_SZ; + } + + rddqsdll[byte] += step_size; + } + } + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // none of the previous bytes reached max_tap_value, then update the boolean + if (!max_tap_value_reached) + max_tap_value_reached = (rddqsdll[byte] > (3 * mdllcode[ch][1 + byte])); + + if (max_tap_value_reached) { + if (all_bits_fail_b[byte] == 0) { + //shim_panic("Memory rddq calibration: Unable to find right failing point, max tap value reached for ch %d byte %d", ch, byte); + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Unable to find right failing point, max tap value reached for ch %d byte %d", ch, byte); + rddqcal_vref_panic[ch][vref] = 1; + } + } + } + } while ((!max_tap_value_reached) && (all_bits_fail == 0)); +} + +// Purpose of this function is to start from left side failing point and find passing locations for every DQ bit on left side of window +// Save all the locations to compute the center of window later +// To find left passing point, move to the right from the failing point, which means keep adding more negative adjustment to mdll +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + bool max_tap_value_reached = false; + uint32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + uint32_t saved_val; + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + all_bits_pass = 0; + rddqcalresult = 0x3FFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Finding Left side passing point on per bit level. Moving Left to Right (keep adding more negative adj to mdll) to find point where it turns from FAIL TO PASS + do { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if we haven't found all bits passing for this byte, push out new sdll value + if (all_bits_pass_b[byte] == 0) { + amp_set_rddq_sdll(ch, byte, tap_value_b[byte]); + //shim_printf("DEBUG - rddqcal_find_right_passing_point:: Pushing byte %d by DQS sdll of 0x%x \n",byte,tap_value_b[byte]); + } + } + + // Run rddqcal in hw + amp_run_rddqcal(ch); + rddqcalresult = (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + //shim_printf("DEBUG - rddqcal_find_right_passing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the left edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + saved_val = tap_value_b[byte]; + + rddqcal_per_chrnk_right[chrnk_indx][vref][bit_indx] = saved_val; + shim_printf("DEBUG - rddqcal_find_right_passing_point:: Found right edge for channel %d bit %d at tap value %d \n",chrnk_indx,bit_indx,rddqcal_per_chrnk_right[chrnk_indx][vref][bit_indx]); + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window (by adding more negative adjustment to mdll) + if (all_bits_pass == 0) { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + // if this byte lane does not have all passing bits, adjust this byte's sdll + if (all_bits_pass_b[byte] == 0) { + // for negative value, increase the magnitude + //if (sgn_bit_b[byte] == 1) + // tap_value_b[byte] += FINER_STEP_SZ; + //else { + // if we're at 0, increase the magnitude and change sign + // if (tap_value_b[byte] == 0) { + // tap_value_b[byte] += FINER_STEP_SZ; + // sgn_bit_b[byte] = 1; + // } + // // for positive value, decrease the magnitude + // else + tap_value_b[byte] -= FINER_STEP_SZ; + } + } + } + + // check for end of loop condition + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] > (3 * mdllcode[ch][1 + byte])); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) { + //shim_panic("Memory rddq calibration: Unable to find right passing point, max tap value reached"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Unable to find right passing point, max tap value reached"); + rddqcal_vref_panic[ch][vref] = 1; + } + break; + } + + // panic if we get beyond -dqmdllcode, since we really shouldn't have to go that far + if ((all_bits_pass == 0) && (tap_value_b[byte] == 0)) { + //shim_panic("Memory rddq calibration: Not yet found right passing point but SDLL = 0 for ch %d byte %d", ch, byte); + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Not yet found right passing point but SDLL = 0 for ch %d byte %d", ch, byte); + rddqcal_vref_panic[ch][vref] = 1; + } + } + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +_ROMCODE_SEGMENT_PREFIX void rddqcal_program_final_values(void) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx; + int32_t arr_RdDqBitCenterPoint[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + uint32_t arr_RdDqBitDeSkew[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t max_RdDqCenterPoint_val_b[DQ_NUM_BYTES]; + uint32_t vref_ch; + uint32_t rddq_vref_value; +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + uint32_t vref0 = vref_opt_rddq[loopchrnk000]; + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_rddq[chrnk0_indx] = vref0; + + for (bit_indx=0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + rddqcal_per_chrnk_left[chrnk0_indx][vref_ch][bit_indx] = rddqcal_per_chrnk_left[loopchrnk000][vref0][bit_indx]; + rddqcal_per_chrnk_right[chrnk0_indx][vref_ch][bit_indx] = rddqcal_per_chrnk_right[loopchrnk000][vref0][bit_indx]; + } + } +#endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_rddq[chrnk0_indx]; + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + left_pos_val = rddqcal_per_chrnk_left[chrnk0_indx][vref_ch][bit_indx]; + right_pos_val = rddqcal_per_chrnk_right[chrnk0_indx][vref_ch][bit_indx]; + + // find center of the eye for this bit + arr_RdDqBitCenterPoint[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + shim_printf("DEBUG - rddqcal_program_final_values:: Center value for bit %d in Channel %d = %d \n", bit_indx, ch, arr_RdDqBitCenterPoint[bit_indx]); + + } + + // initialize the max centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + max_RdDqCenterPoint_val_b[byte] = arr_RdDqBitCenterPoint[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the maximum CenterPoint per byte lane given each bit's center point + for (bit_indx=0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // REVIEW + // if this bit's center point is greater than current max, make it the new max (we'll program this to sdll, and other values will require deskew) + max_RdDqCenterPoint_val_b[byte] = find_common_endpoint(max_RdDqCenterPoint_val_b[byte], arr_RdDqBitCenterPoint[bit_indx], MAX_ENDPT); + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + shim_printf("DEBUG - rddqcal_program_final_values:: Maximum center value for byte %d = %d \n", byte, max_RdDqCenterPoint_val_b[byte]); + } + + // Compute the individual deskew values: any bits with center point < max for its byte lane will require deskew + // Each bit's center is guaranteed to be <= max for its byte lane + // Deskewing means adding more negative adjustment for this bit in addition to the sdll, which is clamped on the negative side to -dqmdllcode + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + arr_RdDqBitDeSkew[bit_indx] = max_RdDqCenterPoint_val_b[byte] - arr_RdDqBitCenterPoint[bit_indx]; + } + + // Program the SDLL and deskew per bit for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + // If max_RdDqCenterPoint_val_b[byte] < 0, program a value of 0 into RD DQS SDLL. + if(max_RdDqCenterPoint_val_b[byte] >= 0) { + amp_program_rddq_sdll(ch, byte, max_RdDqCenterPoint_val_b[byte]); + } + else { + amp_program_rddq_sdll(ch, byte, 0); + } + + // per bit deskew for this byte lane + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + + // If max_RdDqCenterPoint_val_b[byte] < 0, add the absolute value of max_RdDqCenterPoint_val_b[byte] to deskew on each bit. + if(max_RdDqCenterPoint_val_b[byte] < 0) { + arr_RdDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] += __abs(max_RdDqCenterPoint_val_b[byte]); + } + + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx), arr_RdDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] | RUNDESKEWUPD); + + // Poll for Deskew code to be updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + + } + + // If max_RdDqCenterPoint_val_b[byte] < 0, add the absolute value of max_RdDqCenterPoint_val_b[byte] to deskew on each bit. + if(max_RdDqCenterPoint_val_b[byte] < 0) { + arr_RdDqBitDeSkew[DQ_TOTAL_BITS + byte] += __abs(max_RdDqCenterPoint_val_b[byte]); + } + + // Also program DMI deskew here + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), arr_RdDqBitDeSkew[DQ_TOTAL_BITS + byte] | RUNDESKEWUPD); + + // Poll for Deskew code to be updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + } + + rddq_vref_value = (cfg_params.freq_bin == 0) ? cfg_params.rddq_vref_values_f0[vref_ch] : cfg_params.rddq_vref_values_f1[vref_ch]; + + // Also, program AMPS register for optimal RDDQ Vref + amp_program_rddq_vref(ch, rddq_vref_value, 0, cfg_params.freq_bin); + } // for (ch = 0; ch < cfg_params.num_channels; ch++) +} + +_ROMCODE_SEGMENT_PREFIX static uint32_t rddqcal_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val) +{ + uint32_t ret_val, mdll; + + mdll = mdllcode[ch][phy_type]; + + //shim_printf("DEBUG - rddqcal_encode_dlyval:: mdll=%d, phy_type = %d, val = %d \n", mdll, phy_type, val); + + if (val > ( 1.75 * mdll )) { + ret_val = 3; + } else if (val > ( 1.5 * mdll )) { + ret_val = 2; + } else if (val > ( 1.0 * mdll )) { + ret_val = 1; + } else { + ret_val = 0; + } + + return ret_val; +} + +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_push_to_0s_region(uint32_t ch, uint32_t rnk) +{ + uint32_t byte; + uint32_t cawrlvlcode = 0; + bool max_tap_value_reached = false; + uint32_t wrlvlrun = 0x3; + uint32_t wrlvlresult = 0x3; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + + // Note that incrementing cawrlvl sdll has opposite effect of incrementing dqwrlvl + + // Also program DQS SDLL to zero here. Because DQS SDLL is MDLL code at this point. + // This will make CK-DQS worst case skew as MDLL code + 200ps which cannot be calibrated. + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + // Set the DQ/DQS SDLL (RESULT) both to ZERO for this channel/byte + wrdqcal_set_delay_point_res(ch, 1 << byte, 0); + } + + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvlcode[byte] = dqwrlvl_sdll_before_wrlvl[ch][byte]; + } + + do { + // If any byte lane shows that it returned a value of 1 - push ca wrlvl sdll out by 1 tap + amp_set_cawrlvl_sdll(ch, cawrlvlcode); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte already showed a 0 during last run, push dqwrlvl sdll by 1 tap + // this is done to ensure this byte remains at 0 despite cawrlvl sdll being incremented above + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + + // Run Wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLRESULT register + wrlvlresult = ((CSR_READ(rAMP_CAWRLVLRESULT(ch)) >> WRLVL_RESULT) & 0x3); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if((wrlvlresult & (1 << byte)) == 0) { + wrlvlrun &= ~(1 << byte); + } + } + + //shim_printf("DEBUG - wrlvlcal_push_to_0s_region:: Write leveling result for ch=%d, with cawrlvlcode=%d is 0x%x \n",ch,cawrlvlcode, wrlvlresult); + + // Exit if ca or dq wrlvl sdlls reach max tap value + if (cawrlvlcode == MAX_CAWRLVL_CODE) { + max_tap_value_reached = true; + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: CAWRLVL sdll reached max tap value, yet all bytes not all 0s"); + } else { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 0s", byte); + max_tap_value_reached = true; + break; + } + } + } + // Start write leveling run with CAWRLVL code of 0. + cawrlvlcode++; + } while (wrlvlrun && !max_tap_value_reached); +} + +// Keep incrementing dqsdll until the byte shows 1s again. This counters the casdll that was incremented previously in order to show 0s +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_find_0to1_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte; + uint32_t wrlvlrun; + uint32_t wrlvlresult; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + + wrlvlrun = 0x3; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dqwrlvlcode[byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + } + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte is still showing a 0, increment the sdll + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLRESULT register + wrlvlresult = ((CSR_READ(rAMP_CAWRLVLRESULT(ch)) >> WRLVL_RESULT) & 0x3); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if(wrlvlresult & (1 << byte)) { + wrlvlrun &= ~(1 << byte); + } + } + + //shim_printf("DEBUG - wrlvlcal_find_0to1_transition:: Write leveling result for ch=%d, with cawrlvlcode=%d, dqwrlvlcode[%d] = %d, dqwrlvlcode[%d] = %d is %d \n",ch,cawrlvlcode,0,dqwrlvlcode[0],1,dqwrlvlcode[1],wrlvlresult); + + // Exit if any of the byte lane's sdll reaches max + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 1s", byte); + max_tap_value_reached = true; + break; + } + } + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvlcal_per_chrnk_rise[chrnk_indx][byte] = dqwrlvlcode[byte]; + // in the "3rd byte" entry, save the cawrlvl code + wrlvlcal_per_chrnk_rise[chrnk_indx][byte] = cawrlvlcode; +} + +// Go back towards the 0s region (that was found earlier). Note: not trying to find the next edge, just the previous edge that was found already +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_find_1to0_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte; + uint32_t wrlvlrun; + uint32_t wrlvlresult; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + bool incr_cawrlvl = false; + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + wrlvlrun = 0x3; + + // jump ahead by SOLID_PASS_DETECT into the 1s region + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dqwrlvlcode[byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvlcode[byte] += (SOLID_PASS_DETECT + 1); // + 1 because code is decremented before programming the sdll + } + + do { + // Make sure dqwrlvlsdll > 0, otherwise switch to cawrlvlsdll + for (byte = 0; (byte < DQ_NUM_BYTES) && !incr_cawrlvl; byte++) { + // Move to incrementing CAWRLVL SDLL only if the DQWRLVL code for the + // byte which hasn't moved to 0's reached a zero code. + if ((dqwrlvlcode[byte] == 0) && (wrlvlrun & (1 << byte)) ) + incr_cawrlvl = true; + } + + // if we've reached 0 on any dqwrlvlsdll that were being decremented, switch to incrementing the cawrlvlsdll (same effect) + if (incr_cawrlvl) { + cawrlvlcode++; + amp_set_cawrlvl_sdll(ch, cawrlvlcode); + + // In order to keep bytes that have transitioned to 0 to stay there, increment dqwrlvlsdll (counters effect of incrementing cawrlvlsdll) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + } else { + // if run bit is set for this byte, push out the new sdll value after decrementing by 1 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]--; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLRESULT register + wrlvlresult = ((CSR_READ(rAMP_CAWRLVLRESULT(ch)) >> WRLVL_RESULT) & 0x3); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if((wrlvlresult & (1 << byte)) == 0) { + wrlvlrun &= ~(1 << byte); + } + } + + //shim_printf("DEBUG - wrlvlcal_find_1to0_transition:: Write leveling result for ch=%d, with cawrlvlcode=%d, dqwrlvlcode[%d] = %d, dqwrlvlcode[%d] = %d is %d \n",ch,cawrlvlcode,0,dqwrlvlcode[0],1,dqwrlvlcode[1],wrlvlresult); + // check if we've reached max tap value + if (incr_cawrlvl && (cawrlvlcode == MAX_CAWRLVL_CODE)) { + max_tap_value_reached = true; + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: max tap value reached, yet all bytes not back to 0s"); + } + + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvlcal_per_chrnk_fall[chrnk_indx][byte] = dqwrlvlcode[byte]; + + // in the "3rd byte" entry, save the cawrlvl code + wrlvlcal_per_chrnk_fall[chrnk_indx][byte] = cawrlvlcode; +} + +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_program_final_values(void) +{ + uint32_t ch, chrnk0_indx, chrnk1_indx; + uint32_t rank_rise_val[AMP_MAX_RANKS_PER_CHAN], rank_fall_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t edge_pos[AMP_MAX_RANKS_PER_CHAN]; + uint32_t common_edge_pos, min_edge_pos; + uint32_t byte; + uint32_t saved_val[DQ_NUM_BYTES + 1]; +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + wrlvlcal_per_chrnk_rise[chrnk0_indx][byte] = wrlvlcal_per_chrnk_rise[loopchrnk000][byte]; + wrlvlcal_per_chrnk_fall[chrnk0_indx][byte] = wrlvlcal_per_chrnk_fall[loopchrnk000][byte]; + } + } +#endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + // we go upto DQ_NUM_BYTES + 1 to also take into account the cawrlvlcode that is stored in the 5th element + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + // Rank 0 + rank_rise_val[0] = wrlvlcal_per_chrnk_rise[chrnk0_indx][byte]; + rank_fall_val[0] = wrlvlcal_per_chrnk_fall[chrnk0_indx][byte]; + // average of 2 values is the edge for this rank + edge_pos[0] = (rank_rise_val[0] + rank_fall_val[0]) >> 1; + common_edge_pos = edge_pos[0]; + + // Adjust for Dual ranks + if (cfg_params.num_ranks > 1) { + chrnk1_indx = loopchrnk_index_calc(ch, 1, 0); + rank_rise_val[1] = wrlvlcal_per_chrnk_rise[chrnk1_indx][byte]; + rank_fall_val[1] = wrlvlcal_per_chrnk_fall[chrnk1_indx][byte]; + edge_pos[1] = (rank_rise_val[1] + rank_fall_val[1]) >> 1; + + // common_edge_pos between both ranks is simply their average + common_edge_pos = (edge_pos[0] + edge_pos[1]) >> 1; + } + + // save the wrlvlsdll for each byte (and the ca) + saved_val[byte] = common_edge_pos; + } + + // Find the min among all bytes (and the ca) + min_edge_pos = saved_val[DQ_NUM_BYTES]; // initialize min as the cawrlvlsdll + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (saved_val[byte] < min_edge_pos) + min_edge_pos = saved_val[byte]; + + // We'll subtract the min from all 3 sdlls, including ca + // so the byte sdlls which are in opposite direction also need to be adjusted + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + saved_val[byte] -= min_edge_pos; + + // Program the values into the registers + if (byte == DQ_NUM_BYTES) { + // cawrlvl (use dlysel, which will require phyupdt and forceckelow) + // CP : + // Make sure WrLvl max field is set to zero before updating CAWRLVL SDLL code. + amp_program_cawrlvl_sdll(ch, saved_val[byte], 0); + shim_printf("wrlvlcal_program_final_values:: Saving 0x%x into CA WRLVL SDLL \n", saved_val[byte]); + } else { + // dqwrlvl (use dlysel, which will require phyupdt and forceckelow) + // CP : + // Make sure WrLvl max field is set to zero before updating CAWRLVL SDLL code. + amp_program_dqwrlvl_sdll(ch, byte, saved_val[byte], 0); + shim_printf("wrlvlcal_program_final_values:: Saving 0x%x into DQWRLVL%d SDLL\n", saved_val[byte], byte); + } + } + } +} + +/* +================================================================================ +During the search for R/L pass/fail points, I notice this about each loop: + 1) Set the HW Parameters to reflect the current search point + (This is often a combination of WrLvL, per-byte DQ/DQS SDLL) + 2) Assess the per-bit pass/fail status + 3) determine from the results of (2) whether or not we have found our desired skew + (e.g. when looking for 'pass' do all bits pass? when looking for 'fail' do all bits fail?) + 4) if not all bits have been satisfied, nudge the search point and repeat from (1) + 5) if all bits have been satisfied, + Mark (per-bit) the skew at which that bit has notably found its left- or right- window_edge + +We search in a +skew direction for the failing point (in Coarse Steps), +then search in a -skew direction from *there* for the passing point (in Fine Steps) + +…and, when the (skew < 0) we program DQS SDLL instead of DQ SDLL + (and in that case, WrLvL does not tract DQS…it only ever tracks DQ) + +…the net result is, of course, that we end up with an array of left- and right- window-edges for each bit + +The Maui twist is: we execute this process for each vref +The WRDQ speciality is: within each vref loop iteration, we will first set "n" == 0 or 1, as appropriate + +After finding all the L/R window_edges (for each vref), we can pass this info through the CoM +(Center of Mass) algorithm, as we did for CA and RDDQ, to get the optimal vref and the ideal SDLL +along with the individual bit skews. + +So…how's the summary? + +Some thoughts: +(A) I'm planning to create an encapsulated function that will program WrLvl, DQ, DQS as appropriate for a given + skew. Using this within the Loops will clean up a lot of the code in the loop. + So…..for a given skew (and an initial value of WrLvL), the function can do this: + if (skew >= 0) + WrLvL + skew --> WrLvL Reg + skew --> each Byte DQ Reg + else // (skew < 0) + abs(skew) --> each Byte DQS Reg + …making it an easy matter to call this from the various search loops + Feedback? does that feel like the right logic? + +(B) I'm still examining the "How do I know I'm done searching" logic in each loop. + I suspect I can get this into an easy-to-use encapsulated function also. +================================================================================ +*/ + +_MCODE_SEGMENT_PREFIX static uint8_t wrdqcal_chan = 0; +_MCODE_SEGMENT_PREFIX static uint8_t wrdqcal_rank = 0; +_MCODE_SEGMENT_PREFIX static uint8_t wrdqcal_vref = 0; + +// Initialize Registers for the start of WR DQ Calibration +_ROMCODE_SEGMENT_PREFIX void wrdqcal_init_regs(uint8_t chan, uint8_t rank) +{ + // Program tWL, tRL for frequency bins 0-3 --> Should be part of the init sequence + uint32_t rdwr_dqcal_loopcnt = CSR_READ(rAMP_RDWRDQCALLOOPCNT(chan)); + + wrdqcal_chan = chan; + wrdqcal_rank = rank; + + // Program SWRDDQCAL Loop count + CSR_WRITE(rAMP_RDWRDQCALLOOPCNT(chan), (rdwr_dqcal_loopcnt & 0xFFFF00FF) | ((cfg_params.wrdq_cal_loopcnt & 0xFF) << 8)); + + // Pattern and invert mask are programmed from init sequence. This includes setting Mode registers + // MR15, MR20, MR32 and MR40 +} + +// 'byte' is used in a number of these functions to indicate *which* byte lane's registers are being affected. +// (byte & 0x1) indicates usage for DQ0 +// (byte & 0x2) indicates usage for DQ1 +#define byteN(_N) (0x1 << (_N)) +#define isforbyte(_N,byte) ((byte) & byteN(_N)) + +static inline _ROMCODE_SEGMENT_PREFIX uint32_t wrdqcal_bitmask(uint32_t byte) +{ + uint32_t wr_bits_pass = 0x0; + + if (isforbyte(0,byte)) wr_bits_pass |= 0x100FF; + if (isforbyte(1,byte)) wr_bits_pass |= 0x2FF00; + + return wr_bits_pass; +} + +// Write Value to 'n' To Add (or not Add) a 1/2 Clk Delay +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_half_clk_delay(uint32_t byte, uint32_t val) +{ + val = (val)? 1:0; + + // TODO (MAUI_WAIVE) : What Reg? + //if (isforbyte(0, byte)) + // rREG_SET_N(wrdqcal_chan, 0) = val; + //if (isforbyte(1, byte)) + // rREG_SET_N(wrdqcal_chan, 1) = val; + + return 0; +} + +// Set DQS SDLL and DQ SDLL +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_dqs_dq_sdll_type(uint32_t chan, uint32_t byte, uint32_t dq_val, uint32_t dqs_val, bool result) +{ + uint32_t wrdqsdq_sdllcode; + uint32_t shyfted_bit = 1 << (result? WR_SDLLUPDWRRES:WR_SDLLUPDOVR); + uint32_t update = (dqs_val << WR_DQS_SDLL_OFFSET) | (dq_val << WR_DQ_SDLL_OFFSET) | shyfted_bit; + + // Range Check DQ, DQS ... if outside of max range, issue a panic + if ((dqs_val > MAX_SDLL_VAL) || (dq_val > MAX_SDLL_VAL)) { + //shim_panic("Trying to set WR %s SDLL (code == %d) which is more than (max == %d)", + // (dqs_val > MAX_SDLL_VAL)? "DQS":"DQ", dq_val + dqs_val, MAX_SDLL_VAL); + shim_printf("PANIC during Vref scan. Record and move forward:Trying to set WR %s SDLL (code == %d) which is more than (max == %d)", + (dqs_val > MAX_SDLL_VAL)? "DQS":"DQ", dq_val + dqs_val, MAX_SDLL_VAL); + + wrdqcal_vref_panic[chan][wrdqcal_vref] = 1; + return -1; + } + + // First, update each byte + if (isforbyte(0, byte)) { + wrdqsdq_sdllcode = CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(0, chan)); + wrdqsdq_sdllcode &= 0x0000FFFF; + wrdqsdq_sdllcode |= update; + CSR_WRITE(rAMP_WRDQSDQ_SDLLCTRL(0, chan), wrdqsdq_sdllcode); + } + if (isforbyte(1, byte)) { + wrdqsdq_sdllcode = CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(1, chan)); + wrdqsdq_sdllcode &= 0x0000FFFF; + wrdqsdq_sdllcode |= update; + CSR_WRITE(rAMP_WRDQSDQ_SDLLCTRL(1, chan), wrdqsdq_sdllcode); + } + + // Then, poll each byte for update to finish + if (isforbyte(0, byte)) + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(0, chan)) & shyfted_bit); + if (isforbyte(1, byte)) + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(1, chan)) & shyfted_bit); + + return 0; +} + +// Set DQ/DQS SDLL (per-byte) as a RESULT (true) or OVERRIDE (false) +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_delay_point(uint32_t chan, uint32_t byte, int32_t point, bool result) +{ + uint32_t dq = 0; + uint32_t dqs = 0; + + // if point is outside of range (min,max), return error code (+/- 1) + if ((point > MAX_SDLL_VAL) || (point < -MAX_SDLL_VAL)) { + //shim_panic("Trying to set a WR DQ/DQS code which is more than maximum allowed (%d vs. [%d,%d])", + // point, -MAX_SDLL_VAL, MAX_SDLL_VAL); + shim_printf("PANIC during Vref scan. Record and move forward:Trying to set a WR DQ/DQS code which is more than maximum allowed (%d vs. [%d,%d])", + point, -MAX_SDLL_VAL, MAX_SDLL_VAL); + wrdqcal_vref_panic[chan][wrdqcal_vref] = 1; + return -1; + } + + if (point >= 0) { // (+point) --> DQ SDLL; ZERO --> DQS SDLL + dq = point; + } else { // (-point) --> DQS SDLL; ZERO --> DQ SDLL + dqs = -point; + } + + return wrdqcal_set_dqs_dq_sdll_type(chan, byte, dq, dqs, result); +} + +// Set DQS SDLL and DQ SDLL as OVERRIDE +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_delay_point_ovr(uint32_t chan, uint32_t byte, int32_t point) +{ + return wrdqcal_set_delay_point(chan, byte, point, false); +} + +// Set DQS SDLL and DQ SDLL as RESULT +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_delay_point_res(uint32_t chan, uint32_t byte, int32_t point) +{ + return wrdqcal_set_delay_point(chan, byte, point, true); +} + +// Program DQ deskew code. +_ROMCODE_SEGMENT_PREFIX int wrdqcal_program_dq_deskew(uint32_t chan, uint32_t byte, uint32_t val) +{ + uint32_t bit_indx; + + if (isforbyte(0, byte)) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(0, chan, bit_indx), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQDESKEW_CTRL(0, chan, bit_indx)) & RUNDESKEWUPD); + } + // Also program DMI deskew here. + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(0, chan), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDMDESKEW_CTRL(0, chan)) & RUNDESKEWUPD); + } + + if (isforbyte(1, byte)) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(1, chan, bit_indx), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQDESKEW_CTRL(1, chan, bit_indx)) & RUNDESKEWUPD); + } + // Also program DMI deskew here. + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(1, chan), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDMDESKEW_CTRL(1, chan)) & RUNDESKEWUPD); + } + + return 0; +} + +// +// WrLvl value and dq_sdll (per-byte) array +#if DCS_REG_VERSION == 1 +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_search_point(uint32_t byte, int32_t point) +{ + // Set DQ/DQS for this search point as OVERRIDE (range check included) for the Channel we are calibrating + wrdqcal_set_delay_point_ovr(wrdqcal_chan, byte, point); + + if (point >= 0) { + amp_set_cawrlvl_sdll(wrdqcal_chan, cawrlvl_sdll_wrlvl[wrdqcal_chan]); + } else { + amp_set_cawrlvl_sdll(wrdqcal_chan, cawrlvl_sdll_wrlvl[wrdqcal_chan] + (uint16_t)(-point)); + } + return 0; +} +#else +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_search_point(uint32_t byte, int32_t point) +{ + uint32_t chrnk_indx; + uint32_t mdllcode_byte; + uint32_t min_of_4mdll_maxsdll = MAX_SDLL_VAL; + uint32_t deskew_val; + + // if point is outside of 4*MDLL range, return error code (+/- 1) + mdllcode_byte = (isforbyte(1, byte)) ? mdllcode[wrdqcal_chan][AMP_DQ1] : mdllcode[wrdqcal_chan][AMP_DQ0]; + if (((point < 0) && (((uint32_t)__abs(point)) > (4 * mdllcode_byte) || ((uint32_t)__abs(point)) > MAX_SDLL_VAL))) { + shim_printf("Trying to set a WR DQS code which is more than 4*MDLL, Code=%d, Limit=%d \n", __abs(point), (4 * mdllcode_byte)); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + return -1; + } else { + if (((uint32_t)__abs(point)) > (5 * mdllcode_byte)) { + shim_printf("Trying to set a WR DQ code which is more than 4*MDLL (DQ deskew can hold a code of MDLL), Code=%d, Limit=%d \n", __abs(point), (4 * mdllcode_byte)); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + return -1; + } + } + + + if (point >= 0) { + // (+point) --> DQ SDLL; ZERO --> DQS SDLL + + if ( (((uint32_t)point) > (MAX_SDLL_VAL + MAX_DESKEW_PROGRAMMED) ) || (((uint32_t)point) > (5*mdllcode_byte)) ) { + shim_panic("Trying to set a WR DQ/DQS code which is more than maximum allowed \n"); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + return -1; + } + else { + // Compute Min(4*MDLL, 248) + if ((4*mdllcode_byte) < MAX_SDLL_VAL) { + min_of_4mdll_maxsdll = 4*mdllcode_byte; + } + else if ((4*mdllcode_byte) >= MAX_SDLL_VAL){ + min_of_4mdll_maxsdll = MAX_SDLL_VAL; + } + if(((uint32_t)point) > min_of_4mdll_maxsdll) { + deskew_val = point - min_of_4mdll_maxsdll; + wrdqcal_set_delay_point_ovr(wrdqcal_chan, byte, min_of_4mdll_maxsdll); + wrdqcal_program_dq_deskew(wrdqcal_chan, byte, deskew_val); + + } + else if (((uint32_t)point) <= min_of_4mdll_maxsdll) { + wrdqcal_set_delay_point_ovr(wrdqcal_chan, byte, point); + } + } + + chrnk_indx = (wrdqcal_chan * cfg_params.num_ranks) + wrdqcal_rank; + + amp_set_cawrlvl_sdll(wrdqcal_chan, cawrlvl_sdll_wrlvl[wrdqcal_chan]); + } else { + // if (point < 0), (-point) --> DQS SDLL; ZERO --> DQ SDLL + wrdqcal_set_delay_point_ovr(wrdqcal_chan, byte, point); + + chrnk_indx = (wrdqcal_chan * cfg_params.num_ranks) + wrdqcal_rank; + + amp_set_cawrlvl_sdll(wrdqcal_chan, cawrlvl_sdll_wrlvl[wrdqcal_chan] + (uint16_t)(-point)); + } + return 0; +} +#endif + +// Assess completion (pass/fail) for the hardware with current settings +_ROMCODE_SEGMENT_PREFIX uint32_t wrdqcal_assess_position() +{ + uint32_t wrdqcalresult; + uint32_t wrdqcalrun; + + wrdqcalrun = CSR_READ(rAMP_WRDQ_CAL_RUN(wrdqcal_chan)); + + // Run SW WRDQ calibration + CSR_WRITE(rAMP_WRDQ_CAL_RUN(wrdqcal_chan), (wrdqcalrun & 0xFFFFFFFE) | (1 << WR_CALIB_RUN)); + + // Poll for WRDQ cal run to finish + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQ_CAL_RUN(wrdqcal_chan)) & (1 << WR_CALIB_RUN)); + + // Determine Pass/Fail for each bit of each Byte + wrdqcalresult = (CSR_READ(rAMP_WRDQ_CAL_RESULT(wrdqcal_chan)) & 0x3FFFF); + + return wrdqcalresult; +} + +// Return number of consequetive PASS positions from the indicated position that can be found (up to max) +_ROMCODE_SEGMENT_PREFIX uint8_t wrdqcal_solid_pass(uint32_t byte, int32_t point, int step, uint8_t max) +{ + uint8_t swatch_size = 0; + uint32_t result; + uint32_t wr_bits_pass = wrdqcal_bitmask(byte); + uint8_t pass; + + // Determine Pass/Fail for each bit of each Byte + while (wrdqcal_set_search_point(byte, point) == 0) { + result = wrdqcal_assess_position(); + shim_printf("DEBUG - wrdqcal_solid_pass:: result = 0x%x \n", result); + if (((result & wr_bits_pass) != wr_bits_pass) || (++swatch_size >= max)) + break; + point += step; + } + pass = (swatch_size == max) ? 1 : 0; + + return pass; +} + +// Return number of consecutive all bit fail positions from the indicated position that can be found (up to max) +_ROMCODE_SEGMENT_PREFIX uint8_t wrdqcal_all_bits_fail(uint32_t byte, int32_t point, int step, uint8_t max) +{ + uint8_t swatch_size = 0; + uint32_t result; + uint32_t wr_bits_mask = wrdqcal_bitmask(byte); + uint32_t wr_bits_fail = 0x00000; + uint8_t pass; + + // Determine Pass/Fail for each bit of each Byte + while (wrdqcal_set_search_point(byte, point) == 0) { + result = wrdqcal_assess_position(); + shim_printf("DEBUG - wrdqcal_all_bits_fail:: result = 0x%x \n", result); + if (((result & wr_bits_mask) != wr_bits_fail) || (++swatch_size >= max)) + break; + point += step; + } + + pass = (swatch_size == max) ? 1 : 0; + + return pass; +} + +// Find SOLID pass point (and skew) for each bit from the current "All-Fail" (both bytes) Point +#define WITHIN_BOUNDS(_p,_s,_lim) ((_s < 0)? (_p > _lim):(_p < _lim)) +_ROMCODE_SEGMENT_PREFIX void wrdqcal_find_perbit_skew(uint32_t byte, int edge, int step, int limit, int16_t *bit_edge) +{ + uint32_t per_bit_pass; + uint32_t pass_result; + uint32_t bit,bitval; + int skew; + uint32_t SolidBitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint32_t BitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint8_t all_bits_pass = 0; + + per_bit_pass = wrdqcal_bitmask(byte); + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: per_bit_pass=0x%x \n",per_bit_pass); + + // the 'edge' is the extreme position for All-Bits-Pass + // how far can we push it to find failures on each bit? + for(skew = edge + step; WITHIN_BOUNDS(skew, step, limit); skew += step) { + // Determine Pass/Fail for each bit of each Byte + wrdqcal_set_search_point(byte, skew); + pass_result = wrdqcal_assess_position(); + + per_bit_pass = wrdqcal_bitmask(byte) & pass_result; + + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: pass_result=0x%x, per_bit_pass=0x%x, skew = %d \n", pass_result, per_bit_pass, skew); + + + for(bit=0, bitval=0x01; bit < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit++,bitval<<=1) { + if((per_bit_pass & bitval) && (BitPass[bit] == 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit] == SOLID_PASS_DETECT) { + BitPass[bit] = 1; + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: Found solid pass for bit %d at sdll=%d \n",bit, bit_edge[bit]); + } else if (SolidBitPass[bit] > 0) { + SolidBitPass[bit] = SolidBitPass[bit] + 1; + } else { + // bit passed for the first time, record this value in the global array as the left edge + SolidBitPass[bit] = SolidBitPass[bit] + 1; + + bit_edge[bit] = skew; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit] = 0; + } + } + + all_bits_pass = 1; + for(bit = 0 ; bit < DQ_TOTAL_BITS + DMI_TOTAL_BITS ; bit++) { + all_bits_pass &= BitPass[bit]; + } + + if(all_bits_pass) { + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: Found passing point for all bits \n"); + break; + } + } + + // Always return ZERO UNLESS we hit the Max/Min Bounds + if (all_bits_pass == 0) { + //shim_panic("Unable to find passing point in WRDQ calibration \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Unable to find passing point in WRDQ calibration \n"); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// Do the WrDQ Calibration +//////////////////////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void wrdqcal_sequence(uint8_t chan, uint8_t rank) +{ + int32_t point = 0; + int32_t SDLL_threshold_n; + int32_t zone, left_allfail, right_allfail; + int16_t left_edge[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = {0}; + int16_t right_edge[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = {0}; + + uint32_t both_bytes = 0x3; + uint32_t vref, bit; + int chrnk_indx; + uint32_t good_vref_not_found; + + // Initialize HW Parameters for the WR DQ Calibration + wrdqcal_init_regs(chan, rank); + chrnk_indx = loopchrnk_index_calc(chan, rank, 0); + + if(cfg_params.wrdq_apply_NC_algorithm) { + + // Program initial Vref setting + amp_program_wrdq_vref(chan, rank, cfg_params.wrdq_vref_values[0], 0); //vref_pulse_cnt=0 + + + // ============================================================ + // Determine the correct value for 'n': 1/2 Clk offset or not? + // Set n = 0 for both bytes + wrdqcal_set_half_clk_delay(both_bytes, 0); + + shim_printf("DEBUG - wrdqcal_sequence:: Starting to determine the value of N \n"); + + // determine the threshold to switch to n = 1 + // MAUI_WAIVE : Making threshold as 10*MDLL to aviod having N=1 + SDLL_threshold_n = (10 * mdllcode[chan][AMP_CA]); + + // Search for Passing Zone + // Find Passing Zone: Start @ZERO & Coarse-Step Left (+) ... Find "enough" Consecutive Pass-Points + for(point = 0; point < SDLL_threshold_n; point += COARSE_STEP_SZ) { + // FIXME (MAUI_WAIVE): should be 8-in-a-row? or 2-in-a-row? + if (wrdqcal_solid_pass(both_bytes, point, 1, 2)) { + // In Phase 2, swtch to fine stepping once we reach point=3*MDLL-8 + for(; point < SDLL_threshold_n; point += COARSE_STEP_SZ) { + if (!wrdqcal_solid_pass(both_bytes, point, 1, 1)) + break; + } + break; + } + } + + // If we exceeded the Threshold, then set 'n' to ONE + if (point >= SDLL_threshold_n) { + // Set n = 1 + wrdqcal_set_half_clk_delay(both_bytes, 1); + shim_printf("DEBUG - wrdqcal_sequence:: Determined the value of N to be 1 \n"); + } + else { + shim_printf("DEBUG - wrdqcal_sequence:: Determined the value of N to be 0 \n"); + } + + } + + // Reset deskews before calibrating. + if(cfg_params.chip_id != 0x8000) + wrdqcal_program_dq_deskew(chan, both_bytes, 0); + + // per Vref: + for(vref=0; vref < cfg_params.wrdq_num_vref; vref++) { + + // Set global vref. + wrdqcal_vref = vref; + + // Program Vref setting + amp_program_wrdq_vref(chan, rank, cfg_params.wrdq_vref_values[vref], 0); //vref_pulse_cnt=0 + + shim_printf("DEBUG - wrdqcal_sequence:: Done programming Vref value \n"); + + // ============================================================ + // ZERO the arrays to hold Skew (Left and Right) + for(bit=0; bit < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit++) + left_edge[bit] = right_edge[bit] = 0; // ZERO all the skews (Left & Right) + + // ============================================================ + // Find Passing Zone for both bytes: Start @ZERO & Coarse-Step Left (+) ... Find "enough" Consecutive Pass-Points + point = 0; + // Once a passing point is found, go back a coarse step and switch to fine stepping. + for(; point <= MAX_SDLL_VAL; point += COARSE_STEP_SZ) { + if (wrdqcal_solid_pass(both_bytes, point, 1, 1)) { + // Found a passing point. Now go back a coarse step and switch to fine stepping. + point -= COARSE_STEP_SZ; + + for(; point <= MAX_SDLL_VAL; point += FINER_STEP_SZ) { + if (wrdqcal_solid_pass(both_bytes, point, 1, SOLID_PASS_ZONE_DETECT)) { + // Good Solid Pass on both bytes + break; + } + } + break; + } + } + + if (point > MAX_SDLL_VAL) { + // We have failed to find any PASSing Zone at all! + //shim_panic("Unable to find any passing zone in WRDQ calibration \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Unable to find any passing zone in WRDQ calibration \n"); + wrdqcal_vref_panic[chan][vref] = 1; + } + // No Error...We found the Zone! + zone = point; + + // ============================================================ + // From Passing Zone: Coarse-Step Left (+) until find Fail Zone + // Record, per Bit, the location of the Left-Edge of the Passing Zone + point = zone; +#if DCS_REG_VERSION == 1 + for(; point <= MAX_SDLL_VAL; point += COARSE_STEP_SZ) { +#else + for(; point <= (MAX_SDLL_VAL + MAX_DESKEW_PROGRAMMED); point += COARSE_STEP_SZ) { +#endif + if (wrdqcal_all_bits_fail(both_bytes, point, 1, SOLID_FAIL)) { + // Found all bits Fail Point + break; + } + } + + if (point <= zone) { + // Inexplicably, despite having already found one PASSing zone, we have failed to find any PASSing Zone at all! + //shim_panic("Cannot find any PASSing Zone in WRDQ calibration \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Cannot find any PASSing Zone in WRDQ calibration \n"); + wrdqcal_vref_panic[chan][vref] = 1; + } + + // No Error...We found the all fail point on the Left side! + left_allfail = point; + + // Next: Assess the skews for the various bits + // REVIEW + wrdqcal_find_perbit_skew(both_bytes, left_allfail, -1, -MAX_SDLL_VAL, left_edge); + + // Reset deskews before calibrating. + if(cfg_params.chip_id != 0x8000) + wrdqcal_program_dq_deskew(chan, both_bytes, 0); + + // ============================================================ + // From Passing Zone: Coarse-Step Right (-) until find Fail Zone + // Record, per Bit, the location of the Right-Edge of the Passing Zone + point = zone; + for(; point >= -MAX_SDLL_VAL; point -= COARSE_STEP_SZ) { + if (wrdqcal_all_bits_fail(both_bytes, point, -1, SOLID_FAIL)) { + // Found all Fail Point + break; + } + } + + if (point > zone) { + // Inexplicably, despite having already found one PASSing zone, we have failed to find any PASSing Zone at all! + //shim_panic("Cannot find any PASSing Zone \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Cannot find any PASSing Zone \n"); + wrdqcal_vref_panic[chan][vref] = 1; + } + // No Error...We found the Right Edge! + right_allfail = point; + + shim_printf("DEBUG - Found the right edge at %d \n", point); + + // Next: Assess the skews for the various bits + wrdqcal_find_perbit_skew(both_bytes, right_allfail, 1, MAX_SDLL_VAL, right_edge); + + // ============================================================ + // Note these values in the result array + for(bit=0; bit < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit++) { + wrdqcal_per_chrnk_left[chrnk_indx][vref][bit] = left_edge[bit]; + wrdqcal_per_chrnk_right[chrnk_indx][vref][bit] = right_edge[bit]; + } + + // ============================================================ + } // Done with all Vref + + // ============================================================ + // Find if there is even a single Vref which did not panic. + good_vref_not_found = 1; + for(vref=0; vref < cfg_params.wrdq_num_vref; vref++) { + good_vref_not_found &= wrdqcal_vref_panic[chrnk_indx][vref]; + } + if(good_vref_not_found == 1) { + shim_panic("Memory WRDQ calibration: Unable to find any Vref which did not panic for channel %d\n", chrnk_indx); + } + + // ============================================================ + // Find Optimal Vref, CoM + // Can we use the known skews to allow a more optimal 'optimal vref'? + amp_compute_opt_vref_wrdqcal(chan, rank, DQ_TOTAL_BITS + DMI_TOTAL_BITS); + + // ============================================================ + // Considering the Left and Right Skew: + // per DQ Byte, normalize the SDLL vs. perBit deskew so that at least *one* of the perBit deskews is ZERO + + // ============================================================ + // Program Final Values + // cntr_opt_wrdq[chrnk_indx] = optimal.center; + // optimal.center --> SDLL + wrdqcal_set_search_point(1 << 0, cntr_opt_wrdq[chrnk_indx]); + wrdqcal_set_search_point(1 << 1, cntr_opt_wrdq[chrnk_indx]); +} + + +_ROMCODE_SEGMENT_PREFIX void wrdqcal_program_final_values(void) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx; + int32_t arr_WrDqBitCenterPoint[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + int32_t arr_WrDqBitDeSkew[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t min_WrDqCenterPoint_val_b[DQ_NUM_BYTES]; + int32_t max_of_min_WrDqCenterPoint_val_b; + int32_t arr_WrDmiDeSkew[DQ_NUM_BYTES] = { 0 }; + uint32_t freqchngctl0, freqchngctl1; + uint32_t vref_ch; +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + uint32_t vref0 = vref_opt_wrdq[loopchrnk000]; + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_wrdq[chrnk0_indx] = vref0; + + for (bit_indx=0; bit_indx < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit_indx++) { + wrdqcal_per_chrnk_left[chrnk0_indx][vref_opt_wrdq[chrnk0_indx]][bit_indx] = wrdqcal_per_chrnk_left[loopchrnk000][vref0][bit_indx]; + wrdqcal_per_chrnk_right[chrnk0_indx][vref_opt_wrdq[chrnk0_indx]][bit_indx] = wrdqcal_per_chrnk_right[loopchrnk000][vref0][bit_indx]; + } + + cawrlvl_sdll_wrlvl[ch] = cawrlvl_sdll_wrlvl[0]; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dqwrlvl_sdll_after_wrlvl[ch][byte] = dqwrlvl_sdll_after_wrlvl[0][byte]; + } + } +#endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_wrdq[chrnk0_indx]; + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit_indx++) { + + left_pos_val = wrdqcal_per_chrnk_left[chrnk0_indx][vref_ch][bit_indx]; + right_pos_val = wrdqcal_per_chrnk_right[chrnk0_indx][vref_ch][bit_indx]; + + // find center of the eye for this bit + arr_WrDqBitCenterPoint[bit_indx] = find_wrdq_center_of_eye(left_pos_val, right_pos_val); + shim_printf("DEBUG - wrdqcal_program_final_values:: Center value for bit %d in Channel %d = %d \n", bit_indx, ch, arr_WrDqBitCenterPoint[bit_indx]); + } + + // initialize the min centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + min_WrDqCenterPoint_val_b[byte] = arr_WrDqBitCenterPoint[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the min CenterPoint per byte lane given each bit's center point + for (bit_indx=0; bit_indx < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // if this bit's center point is less than current min, make it the new min + min_WrDqCenterPoint_val_b[byte] = find_common_endpoint(min_WrDqCenterPoint_val_b[byte], arr_WrDqBitCenterPoint[bit_indx], MIN_ENDPT); + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + shim_printf("DEBUG - wrdqcal_program_final_values:: Minimum center value for byte %d = %d \n", byte, min_WrDqCenterPoint_val_b[byte]); + } + + // Compute the individual deskew values: any bits with center point > min for its byte lane will require deskew + // Each bit's center is guaranteed to be >= min for its byte lane + // Deskewing means adding more positive adjustment for this bit in addition to the sdll, which is clamped on the negative side to -dqmdllcode + // and clamped on the positive side to (mdllcode - DELIMIT_POS_ADJ_WRDQSDLL) + + // Also push CA WRLVL SDLL here + // CA WRLVLMax value should be with the max DQS SDLL of the two bytes + // 1. DQS SDLL will be the negation of min_WrDqCenterPoint_val_b. Negate using macro NEGATE + // 2. If negation turns out to be -ve, make it zero, since DQS SDLL can only be >=0. + max_of_min_WrDqCenterPoint_val_b = MAX(POS(NEGATE(min_WrDqCenterPoint_val_b[0])), POS(NEGATE(min_WrDqCenterPoint_val_b[1]))); + amp_program_cawrlvl_sdll(ch, cawrlvl_sdll_wrlvl[ch], max_of_min_WrDqCenterPoint_val_b); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into CA WRLVLMAX \n", max_of_min_WrDqCenterPoint_val_b); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into CA WRLVL \n", cawrlvl_sdll_wrlvl[ch]); + + // Program SDLL for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // Set the DQ/DQS SDLL (RESULT) for this channel/byte + wrdqcal_set_delay_point_res(ch, 1 << byte, min_WrDqCenterPoint_val_b[byte]); + shim_printf("DEBUG - %s:: Programming (for byte %d) final DQ/DQS point to: %5d\n", __PRETTY_FUNCTION__, + min_WrDqCenterPoint_val_b[byte], byte); + + // DQS WRLVL SDLL should be incremented by difference between MAX DQS SDLL & DQS SDLL of the bytes in question. + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into DQ byte %d WRLVLMAX \n",max_of_min_WrDqCenterPoint_val_b - POS(NEGATE(min_WrDqCenterPoint_val_b[byte])), byte); + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_after_wrlvl[ch][byte], max_of_min_WrDqCenterPoint_val_b - POS(NEGATE(min_WrDqCenterPoint_val_b[byte]))); + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + arr_WrDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] = arr_WrDqBitCenterPoint[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] - min_WrDqCenterPoint_val_b[byte]; + + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx), arr_WrDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] | RUNDESKEWUPD); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into DQ byte %d bit %d \n", arr_WrDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx], byte, bit_indx); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + } + + // Program DMI deskew + arr_WrDmiDeSkew[byte] = arr_WrDqBitCenterPoint[DQ_TOTAL_BITS + byte] - min_WrDqCenterPoint_val_b[byte]; + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(byte, ch), arr_WrDmiDeSkew[byte] | RUNDESKEWUPD); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into DMI deskew for byte %d \n", arr_WrDmiDeSkew[byte], byte); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + } + + // Program DRAM with optimal WRDQ Vref + amp_program_wrdq_vref(ch, 0, cfg_params.wrdq_vref_values[vref_ch], 0); //vref_pulse_cnt=0 + + // Also program MCU registers with optimal WRDQ Vref value. + if(cfg_params.chip_id == 0x8000 && cfg_params.chip_rev < CHIP_REVISION_B0) { + if(cfg_params.freq_bin == 1) { + freqchngctl0 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(ch), (freqchngctl0 & 0xFFFF) | (0xE << 16) | (cfg_params.wrdq_vref_values[vref_ch] << 24)); + } + else if(cfg_params.freq_bin == 0) { + freqchngctl0 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(ch), (freqchngctl0 & 0xFFFF) | (0xE << 16) | (cfg_params.wrdq_vref_values[vref_ch] << 24)); + } + } else { + if(cfg_params.freq_bin == 1) { + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0xFFFF0000) | (0xE) | (cfg_params.wrdq_vref_values[vref_ch] << 8)); + } + else if(cfg_params.freq_bin == 0) { + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0xFFFF0000) | (0xE) | (cfg_params.wrdq_vref_values[vref_ch] << 8)); + } + } + + + } // for (ch = 0; ch < cfg_params.num_channels; ch++) +} + +_ROMCODE_SEGMENT_PREFIX static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val) +{ + // CP : Maui Change + if (left_pos_val > right_pos_val) + shim_panic("Memory calibration: find_center_of_eye: Left value (0x%x) is > right value (0x%x) \n", left_pos_val, right_pos_val); + + // center of 2 signed integers is simply their average + return ((left_pos_val + right_pos_val) / 2); +} + +_ROMCODE_SEGMENT_PREFIX static int32_t find_wrdq_center_of_eye(int32_t left_pos_val, int32_t right_pos_val) +{ + // CP : Maui Change + if (left_pos_val < right_pos_val) + shim_panic("Memory calibration: find_wrdq_center_of_eye: Left value (0x%x) is < right value (0x%x) \n", left_pos_val, right_pos_val); + + // center of 2 signed integers is simply their average + return ((left_pos_val + right_pos_val) / 2); +} + +// Select the value that would include the other value in the eye +_ROMCODE_SEGMENT_PREFIX static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t left_or_right) +{ + int32_t retVal = val0; + + // For the left endpoint, select the rightmost value on the number line (max value) + if (left_or_right == MAX_ENDPT) { + if (val0 > val1) + retVal = val0; + else + retVal = val1; + } + // For the right endpoint, select the leftmost value (min value) + else { + if (val0 < val1) + retVal = val0; + else + retVal = val1; + } + + return retVal; +} + +// Inserts the data at given byte and bit position in the cal_bits array +// Assumes that num_bits is always <= 8 +_ROMCODE_SEGMENT_PREFIX void cal_save_value(uint8_t data, uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos) +{ + uint32_t space_in_this_byte; + uint8_t mask; + + if (((*bit_pos) > 7) || ((*byte_pos) >= CALIB_PMU_BYTES)) + shim_panic("Error! bit position %d > 7 or byte position %d > capacity (%d)\n", *bit_pos, *byte_pos, CALIB_PMU_BYTES); + + // how many bits left in this byte? + space_in_this_byte = 8 - (*bit_pos); + + // we'll grab as many bits from the data as there is space in this byte + if (space_in_this_byte >= num_bits) + mask = (1 << num_bits) - 1; + else + mask = (1 << space_in_this_byte) - 1; + + // Set the data value at given byte (only as many bits as space and making sure to preserve the other bits in this byte) + cal_bits[*byte_pos] |= ((data & mask) << *bit_pos); + + if (space_in_this_byte < num_bits) { + // any remainder bits get saved to the next byte + cal_bits[(*byte_pos) + 1] = (data >> space_in_this_byte); + (*byte_pos)++; + *bit_pos = num_bits - space_in_this_byte; + } else if (space_in_this_byte == num_bits) { + (*byte_pos)++; + *bit_pos = 0; + } else { + (*bit_pos) += num_bits; + } +} + +// Retrieve the data at given byte and bit position in the cal_bits array +// Assumes that num_bits is always <= 8 +_ROMCODE_SEGMENT_PREFIX static uint8_t cal_retrieve_value(uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos) +{ + uint32_t space_in_this_byte; + uint8_t mask, remainder_mask, ret_val; + + if (((*bit_pos) > 7) || ((*byte_pos) >= CALIB_PMU_BYTES)) + shim_panic("Error! bit position %d > 7 or byte position %d > capacity (%d)\n", *bit_pos, *byte_pos, CALIB_PMU_BYTES); + + // how many bits left in this byte? + space_in_this_byte = 8 - (*bit_pos); + + // we'll grab as many bits from the array as there is space in this byte (max of num_bits) + if (space_in_this_byte >= num_bits) + mask = (1 << num_bits) - 1; + else { + mask = (1 << space_in_this_byte) - 1; + remainder_mask = (1 << (num_bits - space_in_this_byte)) - 1; + } + + // Get the data value at given byte (only as many bits as space) + ret_val = (cal_bits[*byte_pos] >> *bit_pos) & mask; + + if (space_in_this_byte < num_bits) { + // any remainder bits get loaded from the next byte + ret_val |= (cal_bits[(*byte_pos) + 1] & remainder_mask) << space_in_this_byte; + (*byte_pos)++; + *bit_pos = num_bits - space_in_this_byte; + } else if (space_in_this_byte == num_bits) { + (*byte_pos)++; + *bit_pos = 0; + } else { + (*bit_pos) += num_bits; + } + + return ret_val; +} + +// ================================================================================ +typedef struct +{ + uint32_t sum; // Number of "Mass" objects recorded + int32_t sum_mass_ave; // Sum of the Average "Mass" position + uint32_t sum_mass; // Sum of the "Mass" + uint32_t sum_mass_h; // Sum of the "Mass" * "height" + int32_t center; // Center-of-Mass + uint32_t center_h; // Center-of-Mass WRT height +} opt_center_accum_t; + +// ================================================================================ +_ROMCODE_SEGMENT_PREFIX void amp_opt_center_init(opt_center_accum_t *opt) +{ + uint32_t *ptr = (uint32_t *)opt; + uint32_t *end = (uint32_t *)(opt + 1); + + // ZERO everything + while (ptr < end) *ptr++ = 0; +} + +// ================================================================================ +_ROMCODE_SEGMENT_PREFIX void amp_opt_center_add(opt_center_accum_t *opt, uint32_t height, int shift, int32_t hi, int32_t lo) +{ + if (hi < lo) + shim_panic("Error! Non-sensical (hi < lo) in calculating center [hi==%d, lo==%d]\n", hi, lo); + + // Apply the Shift (could be ZERO) + hi += shift; + lo += shift; + + opt->sum += 1; + opt->sum_mass_ave += (hi + lo); // NOTE: "divide by two" handled at finalization + opt->sum_mass += (hi - lo); + opt->sum_mass_h += (hi - lo) * height; +} + +// ================================================================================ +_ROMCODE_SEGMENT_PREFIX void amp_opt_center_final(opt_center_accum_t *opt) +{ + if (opt->sum > 0) + // Find the Average Center (Rounding off to nearest) + opt->center = (opt->sum_mass_ave + ((int32_t)opt->sum)) / (2 * ((int32_t)opt->sum)); + + if (opt->sum_mass > 0) + // Find the Weighted-Average Height Center (Rounding off to nearest) + opt->center_h = (opt->sum_mass_h + (opt->sum_mass / 2)) / (opt->sum_mass); +} + +// ================================================================================ +// Compute the optimal Vref index across multiple vref and multiple bits +// Used by CA, RdDQ, WrDQ +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref(char *descr, uint32_t vrefMax, uint32_t bitMax, + int32_t *right, int32_t *left, int32_t *vref_panic, int32_t *skewR, int32_t *skewL, + int32_t *opt_cent_solution, uint32_t *opt_vref_solution) +{ + uint32_t vref,bit; + int32_t L,R; + int32_t panic; + int32_t deskew = 0; + int32_t maxL,minR; + uint32_t span,max_span = 0; + uint32_t opt_vref = 0; + int32_t opt_center = 0; + opt_center_accum_t optimal; + bool use_com = (cfg_params.opt_vref_mode == DCS_CAL_OPT_VREF_MODE_COM); + + if (use_com) { + // Init the "optimal center" calculation + amp_opt_center_init(&optimal); + } + + for(vref = 0; vref < vrefMax; vref++) { + + panic = *vref_panic++; + + shim_printf("DEBUG - OptVref (%s) [vref=%d] Panic flag is %d \n", descr, vref, panic); + + // Only consider this Vref if it did not panic. + if(!panic) { + + maxL = -MAX_SDLL_VAL; + minR = MAX_SDLL_VAL; + for(bit = 0; bit < bitMax; bit++) { + // Grab the Values + L = *left++; + R = *right++; + if (skewL && skewR) + deskew = *skewL++ - *skewR++; + + shim_printf("DEBUG - OptVref (%s) [vref=%d][bit=%d]: L=%d, R=%d, deskew=%d\n", + descr, vref, bit, L, R, deskew); + + if (use_com) { + // Add this info to the "optimal center" calculation + amp_opt_center_add(&optimal, vref, deskew, R, L); + } else { + // Find the minimum Right and find the maximum Left + if (minR > R) minR = R; + if (maxL < L) maxL = L; + } + } + + if (!use_com) { + // Calculate the Span for this vref + span = minR - maxL; + // Remember the Maximum span (and record its vref and its center point) + if (max_span < span) { + max_span = span; + opt_vref = vref; + opt_center = (maxL + minR) / 2; + } + } + } + } + + if (use_com) { + // Finalize the "optimal center" calculation + amp_opt_center_final(&optimal); + opt_vref = optimal.center_h; + opt_center = optimal.center; + } + + shim_printf("DEBUG - OptVref (%s) OptimalVref=%d, OptimalCenter=%d\n", descr, opt_vref, opt_center); + + // Copy our results to caller + if (opt_vref_solution) *opt_vref_solution = opt_vref; + if (opt_cent_solution) *opt_cent_solution = opt_center; +} + +// ================================================================================ +// Compute the optimal Vref index for CA calibration +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref_cacal(uint32_t ch, uint32_t rnk, uint32_t swloop, uint32_t bitMax) +{ + // Calc the index for this Loop/Ch/Rnk + uint32_t loopchrnk_indx = loopchrnk_index_calc(ch, rnk, swloop); + uint32_t ca_num_vref = (cfg_params.freq_bin == 0) ? cfg_params.ca_num_vref_f0 : cfg_params.ca_num_vref_f1; + + // Run the Calculation for the Optimal VRef and Optimal Center + amp_compute_opt_vref("CA", ca_num_vref, bitMax, + (int32_t *)(cacal_per_loopchrnk_right[loopchrnk_indx]), + (int32_t *)(cacal_per_loopchrnk_left[loopchrnk_indx]), + (int32_t *)(cacal_vref_panic[loopchrnk_indx]), + 0, 0, + &(cntr_opt_ca[loopchrnk_indx]), + &(vref_opt_ca[loopchrnk_indx])); +} + +// ================================================================================ +// Compute the optimal Vref index for RdDQ calibration +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref_rddqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax) +{ + // Calc the index for this Loop/Ch/Rnk + uint32_t loopchrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + uint32_t rddq_num_vref = (cfg_params.freq_bin == 0) ? cfg_params.rddq_num_vref_f0 : cfg_params.rddq_num_vref_f1; + + // Run the Calculation for the Optimal VRef and Optimal Center + amp_compute_opt_vref("RdDQ", rddq_num_vref, bitMax, + (int32_t *)(rddqcal_per_chrnk_right[loopchrnk_indx]), + (int32_t *)(rddqcal_per_chrnk_left[loopchrnk_indx]), + (int32_t *)(rddqcal_vref_panic[loopchrnk_indx]), + 0, 0, + &(cntr_opt_rddq[loopchrnk_indx]), + &(vref_opt_rddq[loopchrnk_indx])); +} + +// ================================================================================ +// Compute the optimal Vref index for WrDQ calibration +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref_wrdqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax) +{ + // Calc the index for this Loop/Ch/Rnk + uint32_t loopchrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + + // Run the Calculation for the Optimal VRef and Optimal Center + amp_compute_opt_vref("WrDQ", cfg_params.wrdq_num_vref, bitMax, + // NOTE: for WRDQ, Left and Right have been Swapped! + (int32_t *)(wrdqcal_per_chrnk_left[loopchrnk_indx]), + (int32_t *)(wrdqcal_per_chrnk_right[loopchrnk_indx]), + (int32_t *)(wrdqcal_vref_panic[loopchrnk_indx]), + // ======================================================= + 0, 0, + &(cntr_opt_wrdq[loopchrnk_indx]), + &(vref_opt_wrdq[loopchrnk_indx])); +} +// ================================================================================ diff --git a/drivers/apple/dcs/dcs_calibration_v2.c b/drivers/apple/dcs/dcs_calibration_v2.c new file mode 100644 index 0000000..adb0ec4 --- /dev/null +++ b/drivers/apple/dcs/dcs_calibration_v2.c @@ -0,0 +1,5106 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef ENV_IBOOT +#include +#elif defined ENV_DV +#include "dcs_shim.h" +#elif defined ENV_CFE +#include "cfe/amp_v3_shim.h" +#else +#error "Unidentified compilation environment for shared memory calibration code" +#endif + +#define MAX(X,Y) ((X > Y) ? X : Y) +#define MIN(X,Y) ((X < Y) ? X : Y) +#define NEGATE(X) (-1 * X) +#define POS(X) ((X < 0) ? 0 : X) + +// In non-DV environments, ROMCODE_SEGMENT & MCODE_SEGMENT prefixes would be empty +#ifdef ENV_DV + #ifndef AMS_SIM_ENV + #define _ROMCODE_SEGMENT_PREFIX ROMCODE_SEGMENT + #define _MCODE_SEGMENT_PREFIX MCODE_SEGMENT + #else + #define _ROMCODE_SEGMENT_PREFIX + #define _MCODE_SEGMENT_PREFIX + #endif +#else + #define _ROMCODE_SEGMENT_PREFIX + #define _MCODE_SEGMENT_PREFIX +#endif + + +/* + * DQ_PRBS7_PATTERNS: Currently unused + */ +#if 0 +// PRBS7 patterns used for ca calibration. cfg_params.cacalib_sw_loops * cfg_params.cacalib_hw_loops must equal 64 +// We extend the size by 8 and repeat the first 8 values because when swloop=64, we don't go outside the array for programming CACALPAT1-7 + + +// TODO TODO : What would be the final +// 1. Vref values & ranges for CA, RDDQ & WRDQ +// 2. Patter and invert masks for PRBS4I. + +// PRBS patterns for Wrdq and Rddq (for the one after Wrdq) calibration +_MCODE_SEGMENT_PREFIX static const uint32_t DQ_PRBS7_PATTERNS[DQ_NUM_PATTERNS] = { + 0x85858585, 0x4a4a4a4a, 0x9a9a9a9a, 0x9e9e9e9e, 0xa1a1a1a1, 0x88888888, 0xffffffff, 0xcfcfcfcf, + 0xd0d0d0d0, 0x04040404, 0x3f3f3f3f, 0x29292929, 0x77777777, 0x30303030, 0x1f1f1f1f, 0xd4d4d4d4, + 0x3b3b3b3b, 0x16161616, 0x5e5e5e5e, 0x47474747, 0x2f2f2f2f, 0xcbcbcbcb, 0xefefefef, 0x2d2d2d2d, + 0x48484848, 0x19191919, 0x68686868, 0xe4e4e4e4, 0x24242424, 0xc2c2c2c2, 0x65656565, 0x51515151, + 0x71717171, 0x8c8c8c8c, 0xc0c0c0c0, 0xe6e6e6e6, 0xa7a7a7a7, 0x34343434, 0x20202020, 0xfdfdfdfd, + 0x4c4c4c4c, 0x26262626, 0x41414141, 0x93939393, 0x14141414, 0xdddddddd, 0xb1b1b1b1, 0x6a6a6a6a, + 0x67676767, 0xd2d2d2d2, 0x87878787, 0xc9c9c9c9, 0x6c6c6c6c, 0xdbdbdbdb, 0x0d0d0d0d, 0xb5b5b5b5, + 0x55555555, 0x4e4e4e4e, 0xa5a5a5a5, 0xb7b7b7b7, 0xd6d6d6d6, 0xb8b8b8b8, 0xe0e0e0e0, 0x1b1b1b1b, + 0xebebebeb, 0x12121212, 0x61616161, 0x6e6e6e6e, 0x58585858, 0xfbfbfbfb, 0xf0f0f0f0, 0xf9f9f9f9, + 0x73737373, 0x0f0f0f0f, 0x36363636, 0xa3a3a3a3, 0x0b0b0b0b, 0x09090909, 0x8a8a8a8a, 0x7c7c7c7c, + 0x39393939, 0x95959595, 0xa8a8a8a8, 0x02020202, 0x83838383, 0xf6f6f6f6, 0x45454545, 0xacacacac, + 0x3d3d3d3d, 0xaaaaaaaa, 0x81818181, 0x75757575, 0xb3b3b3b3, 0xe9e9e9e9, 0x91919191, 0x97979797, + 0x2b2b2b2b, 0xf4f4f4f4, 0xc6c6c6c6, 0x5a5a5a5a, 0x78787878, 0x06060606, 0xbcbcbcbc, 0xdfdfdfdf, + 0x32323232, 0x9c9c9c9c, 0x22222222, 0x7e7e7e7e, 0xbabababa, 0x63636363, 0xedededed, 0xaeaeaeae, + 0xbebebebe, 0x5c5c5c5c, 0xc4c4c4c4, 0xd9d9d9d9, 0x8e8e8e8e, 0x43434343, 0x10101010, 0xe2e2e2e2, + 0x98989898, 0x1d1d1d1d, 0x57575757, 0xcdcdcdcd, 0x53535353, 0xf2f2f2f2, 0x7a7a7a7a, 0x85858585 +}; +#endif + +_MCODE_SEGMENT_PREFIX static uint32_t mdllcode[DCS_NUM_CHANNELS][3]; // 1 for each AMP_DQ, and 1 for AMP_CA +_MCODE_SEGMENT_PREFIX static uint32_t cacal_patterns_mask[CA_NUM_PATTERNS]; + +// This array will hold the calibration values to be saved for resume boot. +// Size is CALIB_PMU_BYTES, as this is the max space available in PMU for calibration, in iBoot environment +_MCODE_SEGMENT_PREFIX static uint8_t cal_bits[CALIB_PMU_BYTES] = { 0 }; + +/* + * Following global arrays will record passing points for calibration operations + */ + +// Used to save calibration values for each bit per channel and rank for every iteration +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_loopchrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_VREF][CA_NUM_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_loopchrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_VREF][CA_NUM_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_loopchrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_loopchrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; + +// Used to record values from CS training which will be used in CA training +_MCODE_SEGMENT_PREFIX static uint32_t cksdll_cscal[CA_NUM_VREF]; +_MCODE_SEGMENT_PREFIX static uint32_t cssdll_cscal[CA_NUM_VREF]; +_MCODE_SEGMENT_PREFIX static uint32_t casdll_cscal[CA_NUM_VREF]; + +// cs data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; +_MCODE_SEGMENT_PREFIX static int32_t cscal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// ca data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS][CA_NUM_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t cacal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS][CA_NUM_BITS]; + +// wrlvl data aggregated over all iterations, we save value for 4 byte lanes + the ca value +_MCODE_SEGMENT_PREFIX static uint32_t wrlvlcal_per_chrnk_rise[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES + 1]; +_MCODE_SEGMENT_PREFIX static uint32_t wrlvlcal_per_chrnk_fall[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES + 1]; + +// rddq data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t rddqcal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS][RDDQ_NUM_VREF][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t rddqcal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS][RDDQ_NUM_VREF][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + +// wrdq data aggregated over all iterations +_MCODE_SEGMENT_PREFIX static int32_t wrdqcal_per_chrnk_right[DCS_NUM_CHANNELS * DCS_NUM_RANKS][WRDQ_NUM_VREF][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; +_MCODE_SEGMENT_PREFIX static int32_t wrdqcal_per_chrnk_left[DCS_NUM_CHANNELS * DCS_NUM_RANKS][WRDQ_NUM_VREF][DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + +// Indicates the optimal Vref value for CA calibration +// Along with Vref value, also save Vref range here +_MCODE_SEGMENT_PREFIX static uint32_t vref_opt_ca[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; + +// Indicates the optimal Vref value for RDDQ calibration +// Along with Vref value, also save Vref range here +_MCODE_SEGMENT_PREFIX static uint32_t vref_opt_rddq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the optimal Vref value for WRDQ calibration +// Along with Vref value, also save Vref range here +_MCODE_SEGMENT_PREFIX static uint32_t vref_opt_wrdq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the final center values for CA calibration +_MCODE_SEGMENT_PREFIX static int32_t cntr_opt_ca[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS]; + +// Indicates the final center values for RDDQ calibration +_MCODE_SEGMENT_PREFIX static int32_t cntr_opt_rddq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the final center values for WRDQ calibration +_MCODE_SEGMENT_PREFIX static int32_t cntr_opt_wrdq[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the value of CAWRLVL SDLL after Write Leveling is done and before WRDQ calibration +_MCODE_SEGMENT_PREFIX static uint32_t cawrlvl_sdll_wrlvl[DCS_NUM_CHANNELS * DCS_NUM_RANKS]; + +// Indicates the value of WRDQWRLVL SDLL before Write Leveling is done. +_MCODE_SEGMENT_PREFIX static uint32_t dqwrlvl_sdll_before_wrlvl[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES] = { { 0 } }; + +// Indicates the value of WRDQWRLVL SDLL after Write Leveling is done and before WRDQ calibration +_MCODE_SEGMENT_PREFIX static uint32_t dqwrlvl_sdll_after_wrlvl[DCS_NUM_CHANNELS * DCS_NUM_RANKS][DQ_NUM_BYTES]; + +// Indicates the final CA/CS calibrated values in Bucket1 +_MCODE_SEGMENT_PREFIX static uint32_t cksdll_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS] = { 0 }; +_MCODE_SEGMENT_PREFIX static uint32_t cssdll_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS] = { 0 }; +_MCODE_SEGMENT_PREFIX static uint32_t casdll_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS] = { 0 }; +_MCODE_SEGMENT_PREFIX static uint32_t cadeskew_bucket1[DCS_NUM_CHANNELS * DCS_NUM_RANKS][CA_NUM_BITS] = {{ 0 }}; + +// Indicates if there was any panic at a given Vref setting +_MCODE_SEGMENT_PREFIX static int32_t cacal_vref_panic[DCS_NUM_CHANNELS * DCS_NUM_RANKS * CACAL_MAX_SWLOOPS][CA_NUM_VREF] = { { 0 } }; +_MCODE_SEGMENT_PREFIX static int32_t rddqcal_vref_panic[DCS_NUM_CHANNELS * DCS_NUM_RANKS][RDDQ_NUM_VREF] = { { 0 } }; +_MCODE_SEGMENT_PREFIX static int32_t wrdqcal_vref_panic[DCS_NUM_CHANNELS * DCS_NUM_RANKS][WRDQ_NUM_VREF] = { { 0 } }; + +#ifdef ENV_DV +// Force initialization of cfg_params (used by DV) +void calibration_init_cfg_params(); +#endif + +// +void calibrate_ca(void); +void calibrate_rddq(void); +void calibrate_wrlvl(void); +void calibrate_wrdq(void); + +// Static local function declarations +static void amp_do_mdll_calib(uint32_t ch); +static void amp_do_imp_calib(uint32_t ch); +static void amp_setup_ca_cal(uint32_t ch, uint32_t rnk, uint32_t swloop); +static void run_soc_upd(uint32_t ch); +static void amp_init_ca_deskew(uint32_t ch); +static void amp_init_ca_cs_ck_sdll(uint32_t ch); +static void amp_init_wr_deskew(uint32_t ch); +static void amp_push_casdll_out(uint32_t ch, uint32_t casdll_ovr_val); +static void amp_push_cksdll_out(uint32_t ch, uint32_t cksdll_ovr_val); +static void amp_push_cssdll_out(uint32_t ch, uint32_t cssdll_ovr_val); +static void amp_program_ca_sdll(uint32_t ch, uint32_t casdll_val); +static void amp_program_ck_sdll(uint32_t ch, uint32_t cksdll_val); +static void amp_program_cs_sdll(uint32_t ch, uint32_t cssdll_val); +static void amp_set_dqs_weak_pd(uint32_t ch, uint32_t freq_bin); +static void amp_reset_dqs_weak_pd(uint32_t ch, uint32_t freq_bin); +static void amp_set_dqs_idle_active(uint32_t ch, uint32_t freq_bin); +static void amp_reset_dqs_idle_active(uint32_t ch, uint32_t freq_bin); +static void amp_enter_cacal_mode(uint32_t ch); +static void amp_exit_cacal_mode(uint32_t ch); +static void amp_run_cacal_vref(uint32_t ch); +static uint32_t amp_run_cacal(uint32_t ch, uint32_t training_mode); +static void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk); +static void amp_rddq_cal_wrfifo(uint32_t ch, uint32_t rnk); +static void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_ovr_val); +static void amp_program_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_wr_val); +static void amp_run_rddqcal(uint32_t ch); +static void amp_wrlvl_init(void); +static void amp_wrlvl_entry(uint32_t ch); +static void amp_wrlvl_exit(uint32_t ch, uint8_t freq_bin); +static void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset); +static void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset); +static void amp_program_cawrlvl_sdll(uint32_t ch, uint32_t cawrlvl_offset, uint32_t cawrlvlmax_offset); +static void amp_program_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t dqwrlvl_offset, uint32_t dqwrlvlmax_offset); +static void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun); +static void cacal_init_registers(); +static void cacal_generate_patterns_mask(void); +static void cacal_run_sequence(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t mask_bits, uint32_t swloop, uint32_t vref); +static void cacal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref); +static void cacal_program_cs_training_values(void); +static void cacal_program_final_values(void); +static void rddqcal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal); +static void rddqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal); +static void rddqcal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal); +static void rddqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal); +static void rddqcal_program_final_values(void); +static void wrlvlcal_push_to_0s_region(uint32_t ch, uint32_t rnk); +static void wrlvlcal_find_0to1_transition(uint32_t ch, uint32_t rnk); +static void wrlvlcal_find_1to0_transition(uint32_t ch, uint32_t rnk); +static void wrlvlcal_program_final_values(void); +static void amp_compute_opt_vref_cacal(uint32_t ch, uint32_t rnk, uint32_t swloop, uint32_t bitMax); +static void amp_compute_opt_vref_rddqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax); +static uint32_t rddqcal_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val); +static void amp_program_ca_vref(uint32_t ch, uint32_t vref, uint32_t cacalib_dqs_pulse_cnt, uint32_t cacalib_dqs_pulse_width); +static void amp_program_rddq_vref(uint32_t ch, uint32_t vref, uint32_t vref_pulse_cnt, uint8_t freq_bin); +static void amp_program_wrdq_vref(uint8_t chan, uint8_t rank, uint32_t vref, uint32_t vref_pulse_cnt); +static void wrdqcal_init_regs(uint8_t chan, uint8_t rank); +static int wrdqcal_set_half_clk_delay(uint32_t byte, uint32_t val); +static int wrdqcal_set_delay_point(uint32_t chan, uint32_t byte, int32_t point, bool result); +static int wrdqcal_set_delay_point_ovr(uint32_t chan, uint32_t byte, int32_t point); +static int wrdqcal_set_delay_point_res(uint32_t chan, uint32_t byte, int32_t point); +static int wrdqcal_program_dq_deskew(uint32_t chan, uint32_t byte, uint32_t val); +static int wrdqcal_set_search_point(uint32_t byte, int point); +static uint32_t wrdqcal_assess_position(); +static uint8_t wrdqcal_solid_pass(uint32_t byte, int32_t point, int step, uint8_t max); +static uint8_t wrdqcal_all_bits_fail(uint32_t byte, int32_t point, int step, uint8_t max); +static void wrdqcal_find_perbit_skew(uint32_t byte, int edge, int step, int limit, int16_t *bit_edge); +static void wrdqcal_sequence(uint8_t chan, uint8_t rank); +static void amp_compute_opt_vref_wrdqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax); +static void wrdqcal_program_final_values(void); +static void amp_save_ca_bucket1(uint32_t ch); +static void amp_program_ca_bucket1(uint32_t ch); + +// Helper functions +static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val); +static int32_t find_wrdq_center_of_eye(int32_t left_pos_val, int32_t right_pos_val); +static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t left_or_right); +static void cal_save_value(uint8_t data, uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos); +static uint8_t cal_retrieve_value(uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos); +void amp_save_masterdll_values(); + +/////////////////////////////////////////////////////////////////////////////// +/* Global configuration parameters for calibration, setup is different for iBoot, DV, SiVal, PE */ +/////////////////////////////////////////////////////////////////////////////// +_MCODE_SEGMENT_PREFIX static struct amp_calibration_params cfg_params; + +/////////////////////////////////////////////////////////////////////////////// +////// Global functions +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX +struct amp_calibration_params *calibration_cfg_params_init( + int bootMode, int numChans, int numRanksPerChn) +{ + uint32_t i; + + // Set the calibration params. + + // chip_id and chip_rev are by default set to ELBA A0 for SEG-DV, since they don't perform run time check + // iBoot will override with correct values at run time + cfg_params.chip_id = 0x8001; + cfg_params.chip_rev = CHIP_REVISION_B0; + + cfg_params.num_channels = numChans; + cfg_params.num_ranks = numRanksPerChn; +#if ENV_DV + // Run one channel calibration in DV environment. + cfg_params.num_channels_runCalib = 1; // Only Calibrate one Channel +#else + cfg_params.num_channels_runCalib = numChans; // Calibrate All Channels +#endif + + // Elba Defaults + cfg_params.clk_period_bin0 = CLK_PERIOD_1600; + cfg_params.clk_period_bin1 = CLK_PERIOD_800; + + // + cfg_params.ca_num_vref = CA_NUM_VREF; + cfg_params.rddq_num_vref = RDDQ_NUM_VREF; + cfg_params.wrdq_num_vref = WRDQ_NUM_VREF; + + cfg_params.wrdq_apply_NC_algorithm = true; + + for(i=0;i< cfg_params.ca_num_vref;i++) { + cfg_params.ca_vref_values[i] = 0xC + i; + } + + for(i=0;i< cfg_params.rddq_num_vref;i++) { + cfg_params.rddq_vref_values[i] = 0xBE + i; + } + + for(i=0;i< cfg_params.wrdq_num_vref;i++) { + cfg_params.wrdq_vref_values[i] = 0xC + i; + } + + // This is to take care of bit/byte swizzling +#ifdef AMS_SIM_ENV + for(i=0;i<8;i++) { + cfg_params.cacal_bit_sel[i] = ((CSR_READ(rAMP_CACALBITSELECT(0)) >> (4 * i)) & 0x7); + } +#else + for(i=0;i<8;i++) { + cfg_params.cacal_bit_sel[i] = i; + } +#endif + +#ifdef AMS_SIM_ENV + cfg_params.cacal_rd_byte_sel = ((CSR_READ(rAMP_CACALCTRL(0)) >> 28) & 0x1); +#else + cfg_params.cacal_rd_byte_sel = 1; +#endif + + cfg_params.resume = (bootMode)? true : false; + cfg_params.disable_coarse_cs_training = true; + cfg_params.cacalib_hw_loops = 15; + cfg_params.cacalib_sw_loops = 1; + cfg_params.cacalib_dqs_pulse_cnt = 0; + cfg_params.cacalib_dqs_pulse_width = 2; + cfg_params.rddq_cal_loopcnt = 1; + cfg_params.wrdq_cal_loopcnt = 1; + + cfg_params.rddq_legacy_mode = false; + cfg_params.wrdq_legacy_mode = false; + + cfg_params.freq_bin = 0; + cfg_params.RL = 28; // This is Bin 0 value, with DBI_RD disabled. + cfg_params.WL = 14; // This is Bin 0 value, with WL Set A. + + cfg_params.dv_params_valid = false; + cfg_params.dv_randomize = false; + cfg_params.dbg_calib_mode = 0; + cfg_params.opt_vref_mode = DCS_CAL_OPT_VREF_MODE_COM; + + // Giving a margin of 2 clocks from JEDEC spec to account for propagation delays from AMPS to DDR pins. + // cfg_params.tWLO = 15; // max = 20ns + cfg_params.tWLO = 15; // max = 20ns + cfg_params.tWLMRD = 21; // min = 40 tCK + cfg_params.tWLDQSEN = 11; // max = 20 tCK + + cfg_params.tDSTrain = 2; + cfg_params.tCKCKEH = 2; + cfg_params.tVREF_LONG = 160; + cfg_params.tCAENT = 9; + + cfg_params.tADR = 20; // max = 20ns + propagation delay from AMPS-DRAM + receiver delays. + cfg_params.tMRD = 13; // min = 14ns + cfg_params.tDQSCKE = 9; // min = 10ns + cfg_params.tCKEHCMD = 7; + + cfg_params.WrLvlDqsPulseCnt = 0; // This sets the number of pulses to 2. + + cfg_params.prbs7_pattern_0 = 0x70F20C28; + cfg_params.prbs7_pattern_1 = 0x634BB995; + cfg_params.prbs7_pattern_2 = 0x00006D6F; + cfg_params.prbs7_pattern_3 = 0x00000000; + cfg_params.ca_invert_mask = 0x65; + cfg_params.CsStopCycleCnt = 1; + cfg_params.CsActiveCycleCnt = 2; + + for(int i = 0; i < CA_NUM_BITS; i++) { + cfg_params.ca_prbs_seed_bit[i] = i; + } + + for(int i = 0; i < DQ_NUM_BYTES; i++) { + for(int j = 0; j < DQ_NUM_BITS_PER_BYTE + DMI_NUM_BITS_PER_BYTE; j++) { + cfg_params.wrdq_prbs_seed[i][j] = (i * DQ_NUM_BITS_PER_BYTE + j); + } + } + + // Returning this allows Clients of this Calibration Library to + // modify the configuration beyond this default setup + return &cfg_params; +} + +/////////////////////////////////////////////////////////////////////////////// +////// Standard way to calculate the correct index for results arrays +////// Based on Chan, Rank, SW-Loop ... degenerates appropriately when +////// one of the the configured "number of" parameters is ONE, or when +////// one of the passed parameters is ZERO. +/////////////////////////////////////////////////////////////////////////////// +static inline +uint32_t loopchrnk_index_calc(uint32_t ch, uint32_t rnk, uint32_t swloop) +{ + return (rnk + (cfg_params.num_ranks * (ch + (cfg_params.num_channels * swloop)))); +} + +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void cal_pmgr_change_mcu_clk(uint32_t bucket) +{ +#ifdef ENV_DV +uint32_t pmgr_src_sel; + + #ifdef AMS_SIM_ENV + // Call custom API provided in PMGR_Xactor.h for PMGR changing mcu_clk to indicated Freq Bucket + pmgr_special_cmd(PMGR_CMD_FREQ_CHANGE, bucket, 0); + #else + // Call custom API provided in mcu_helper_fxns.c for PMGR changing mcu_clk to 1600Mhz, 800Mhz or 50Mhz. + pmgr_src_sel = (bucket == 1) ? 5 : (bucket == 0) ? 5 : 8; + pmgr_amc_clk_cfg(pmgr_src_sel, bucket, 0); + #endif +#else + // Call shim function to ask the PMGR to change the mcu_clk to indicated Freq Bucket + shim_change_freq(bucket); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void amp_save_masterdll_values() +{ + uint8_t ch; + + for(ch = 0; ch < cfg_params.num_channels ; ch++) { + mdllcode[ch][AMP_DQ0] = (CSR_READ(rAMP_MDLLCODE(AMP_DQ0, ch)) & DLLVAL_BITS); + mdllcode[ch][AMP_DQ1] = (CSR_READ(rAMP_MDLLCODE(AMP_DQ1, ch)) & DLLVAL_BITS); + // Since there is no CA MDLL for Maui, pick the maximum of DQ0 MDLL & DQ1 MDLL + mdllcode[ch][AMP_CA] = (mdllcode[ch][AMP_DQ0] > mdllcode[ch][AMP_DQ1]) ? mdllcode[ch][AMP_DQ0] : mdllcode[ch][AMP_DQ1]; + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_save_ca_bucket1(uint32_t ch) +{ + uint8_t bit; + + cksdll_bucket1[ch] = (CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & 0xFF; + cssdll_bucket1[ch] = (CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & 0xFF; + casdll_bucket1[ch] = (CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & 0xFF; + shim_printf("DEBUG - amp_save_ca_bucket1:: Saving %d for CKSDLL, %d for CSSDLL, %d for CASDLL for Channel %d\n", cksdll_bucket1[ch], cssdll_bucket1[ch], casdll_bucket1[ch], ch); + + for(bit = 0; bit < CA_NUM_BITS; bit++) { + cadeskew_bucket1[ch][bit] = CSR_READ(rAMP_CADESKEW_CTRL(ch,bit)) & 0x3F; + shim_printf("DEBUG - amp_save_ca_bucket1:: Saving %d for CA deskew bit %d for Channel %d \n", cadeskew_bucket1[ch][bit], bit, ch); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_ca_bucket1(uint32_t ch) +{ + uint8_t bit; + + amp_push_cksdll_out(ch, cksdll_bucket1[ch]); + amp_push_cssdll_out(ch, cssdll_bucket1[ch]); + amp_push_casdll_out(ch, casdll_bucket1[ch]); + + for(bit = 0; bit < CA_NUM_BITS; bit++) { + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit), cadeskew_bucket1[ch][bit] | RUNDESKEWUPD); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, bit)) & RUNDESKEWUPD); + } +} + +// Save or restore ca and wrlvl registers for resume boot +_ROMCODE_SEGMENT_PREFIX void calibration_save_restore_ca_wrlvl_regs(uint32_t save_or_restore, uint32_t channels, bool freq_bin) +{ + + _MCODE_SEGMENT_PREFIX static uint32_t bit_pos = 0; + _MCODE_SEGMENT_PREFIX static uint32_t byte_pos = 0; + uint32_t ch, bit_indx, byte; + uint8_t casdll[DCS_NUM_CHANNELS], cksdll[DCS_NUM_CHANNELS], cssdll[DCS_NUM_CHANNELS], ca_deskew[DCS_NUM_CHANNELS][CA_NUM_BITS]; + //uint8_t ca_vref_f0, ca_vref_f1; + //uint8_t rddq_vref_f0, rddq_vref_f1; + //uint8_t wrdq_vref_f0, wrdq_vref_f1; + //uint8_t wrlvlsdll[DCS_NUM_CHANNELS]; + uint32_t camdll_vtscl_refcntl, rdmdll_vtscl_refcntl, wrmdll_vtscl_refcntl; + uint16_t camdll_vtscl_ref_ovrcode, rdmdll_vtscl_ref_ovrcode, wrmdll_vtscl_ref_ovrcode; + uint8_t ca_vref_f1, wrdq_vref_f1, rddq_vref_f1; + uint8_t ca_vref_f0, wrdq_vref_f0, rddq_vref_f0; + uint32_t wrdqcalvrefcodecontrol; + uint32_t freqchngctl1; + + if (save_or_restore == CALIB_SAVE) { + if(freq_bin) { + + // Save only write leveling registers when the save function is called first. + // Save function needs to be called after write leveling because the register fields + // being saved here would be over-written after WRDQ calibration is done. + if((bit_pos == 0) && (byte_pos == 0)) { + for (ch = 0; ch < channels; ch++) { + // save the WrLvl registers for this channel (2 DQ SDLLs and 1 CA SDLL) + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // cawrlvlsdll is stored as the "3rd" byte + if (byte == DQ_NUM_BYTES) + cal_save_value(CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + else + cal_save_value(CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + } + } + else { + for (ch = 0; ch < channels; ch++) { + + // save the CA registers for this channel + // Save CA SDLL + cal_save_value(CSR_READ(rAMP_CASDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + + // Save CK SDLL + cal_save_value(CSR_READ(rAMP_CKSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + + // Save CS SDLL + cal_save_value(CSR_READ(rAMP_CSSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + + // Save CA deskews + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + cal_save_value(CSR_READ(rAMP_CADESKEW_CTRL(ch, bit_indx)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + + + // Save CA, WR and RD VT reference codes + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value((CSR_READ(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) & 0xFF, 8, &bit_pos, &byte_pos); + cal_save_value((((CSR_READ(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) >> 8) & 0x3), VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos); + cal_save_value((CSR_READ(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) & 0xFF, 8, &bit_pos, &byte_pos); + cal_save_value((((CSR_READ(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) >> 8) & 0x3), VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos); + cal_save_value((CSR_READ(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) & 0xFF, 8, &bit_pos, &byte_pos); + cal_save_value((((CSR_READ(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch)) & VT_SCL_REF_MASK) >> 8) & 0x3), VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos); + } + + // Save optimal vref for CA/CS + cal_save_value(cfg_params.ca_vref_values[vref_opt_ca[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for RDDQ + cal_save_value(cfg_params.rddq_vref_values[vref_opt_rddq[ch]] & RDDQ_VREF_CTRL_BITS, RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for WRDQ + cal_save_value(cfg_params.wrdq_vref_values[vref_opt_wrdq[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + } + + for (ch = 0; ch < channels; ch++) { + // Save WR DQS SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value((CSR_READ(rAMP_WRDQSDQ_SDLLCODE(byte, ch)) >> WR_DQS_SDLL_CODE_OFFSET) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_WRDQSDQ_SDLLCODE(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQS deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_WRDQSDESKEW_CTRL(byte, ch)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_save_value(CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save WR DM deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_WRDMDESKEW_CTRL(byte, ch)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_DQSDLLCODE_RD(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD DQ deskew codes + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_save_value(CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save RD DMI deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_save_value(CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & DESKEW_CTRL_BITS, DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save CAWRLVL & DQ WRLVL SDLL values after WRDQ calibration is done + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // cawrlvlsdll is stored as the "5th" byte + if (byte == DQ_NUM_BYTES) + cal_save_value(CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + else + cal_save_value(CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & DLLVAL_BITS, SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + } + } + } + else { + + for (ch = 0; ch < channels; ch++) { + // Save optimal vref for CA/CS + cal_save_value(cfg_params.ca_vref_values[vref_opt_ca[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for RDDQ + cal_save_value(cfg_params.rddq_vref_values[vref_opt_rddq[ch]] & RDDQ_VREF_CTRL_BITS, RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Save optimal Vref for WRDQ + cal_save_value(cfg_params.wrdq_vref_values[vref_opt_wrdq[ch]] & CA_WRDQ_VREF_CTRL_BITS, CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save the cal_bits array + shim_store_memory_calibration((void *) cal_bits, CALIB_NUM_BYTES_TO_SAVE); + } + } else { + // Retrieve cal_bits array + shim_load_memory_calibration((void *) cal_bits, CALIB_NUM_BYTES_TO_SAVE); + + // Reset bit & byte positions for the first call + bit_pos = 0; + byte_pos = 0; + + for (ch = 0; ch < channels; ch++) { + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + // cawrlvlsdll is stored as the "3rd" byte + if (byte == DQ_NUM_BYTES) + amp_program_cawrlvl_sdll(ch, cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos), 0); + else + amp_program_dqwrlvl_sdll(ch, byte, cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos), 0); + } + } + + for (ch = 0; ch < channels; ch++) { + casdll[ch] = cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + amp_program_ca_sdll(ch, casdll[ch]); + + cksdll[ch] = cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + amp_program_ck_sdll(ch, cksdll[ch]); + + cssdll[ch] = cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + amp_program_cs_sdll(ch, cssdll[ch]); + + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + ca_deskew[ch][bit_indx] = cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit_indx), ca_deskew[ch][bit_indx] | RUNDESKEWUPD); + SPIN_W_TMO_WHILE ( CSR_READ(rAMP_CADESKEW_CTRL(ch, bit_indx)) & RUNDESKEWUPD); + } + + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + camdll_vtscl_refcntl = CSR_READ(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch)); + camdll_vtscl_ref_ovrcode = cal_retrieve_value(8, &bit_pos, &byte_pos); + camdll_vtscl_ref_ovrcode |= (cal_retrieve_value(VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos) << 8); + CSR_WRITE(rAMP_CAMDLL_VTSCL_REFCNTL(byte, ch), (camdll_vtscl_refcntl & VT_SCL_REF_MASK) | (camdll_vtscl_ref_ovrcode << VT_SCL_OVR_OFFSET) | (1 << VT_SCL_REF_UPD_OFFSET)); + + rdmdll_vtscl_refcntl = CSR_READ(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch)); + rdmdll_vtscl_ref_ovrcode = cal_retrieve_value(8, &bit_pos, &byte_pos); + rdmdll_vtscl_ref_ovrcode |= (cal_retrieve_value(VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos) << 8); + CSR_WRITE(rAMP_RDMDLL_VTSCL_REFCNTL(byte, ch), (rdmdll_vtscl_refcntl & VT_SCL_REF_MASK) | (rdmdll_vtscl_ref_ovrcode << VT_SCL_OVR_OFFSET) | (1 << VT_SCL_REF_UPD_OFFSET)); + + wrmdll_vtscl_refcntl = CSR_READ(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch)); + wrmdll_vtscl_ref_ovrcode = cal_retrieve_value(8, &bit_pos, &byte_pos); + wrmdll_vtscl_ref_ovrcode |= (cal_retrieve_value(VT_SCL_REF_BITS - 8, &bit_pos, &byte_pos) << 8); + CSR_WRITE(rAMP_WRMDLL_VTSCL_REFCNTL(byte, ch), (wrmdll_vtscl_refcntl & VT_SCL_REF_MASK) | (wrmdll_vtscl_ref_ovrcode << VT_SCL_OVR_OFFSET) | (1 << VT_SCL_REF_UPD_OFFSET)); + } + + ca_vref_f1 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + rddq_vref_f1 = cal_retrieve_value(RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + wrdq_vref_f1 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Program CA and WRDQ optimal Vref's + wrdqcalvrefcodecontrol = CSR_READ(rAMP_WRDQCALVREFCODESTATUS(ch)); + CSR_WRITE(rAMP_WRDQCALVREFCODECONTROL(ch), (wrdqcalvrefcodecontrol & WRDQ_VREF_F1_MASK) | (wrdq_vref_f1 << WRDQ_VREF_F1_OFFSET)); + + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0x00C0FFFF) | (0xC << 16) | (ca_vref_f1 << 24)); + + // Program AMPS register with optimal RDDQ Vref + amp_program_rddq_vref(ch, rddq_vref_f1, 0, 1); + } + + // Simply retrieve WRDQ /RDDQ delays as they are not planned to be used. These delays would be recomputed by Full scan + // hardware calibration. + for (ch = 0; ch < channels; ch++) { + // Save WR DQS SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQS deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save WR DQ deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save WR DM deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD SDLL + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save RD DQ deskew codes + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Save RD DMI deskew + for (byte = 0; byte < DQ_NUM_BYTES ; byte++) { + cal_retrieve_value(DESKEW_NUM_BITS, &bit_pos, &byte_pos); + } + + // Save CAWRLVL & DQ WRLVL SDLL values after WRDQ calibration is done + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + // cawrlvlsdll is stored as the "5th" byte + if (byte == DQ_NUM_BYTES) + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + else + cal_retrieve_value(SDLL_NUM_BITS, &bit_pos, &byte_pos); + } + } + + // Retrieve optimal Vref values for Bucket 0. + for (ch = 0; ch < channels; ch++) { + ca_vref_f0 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + rddq_vref_f0 = cal_retrieve_value(RDDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + wrdq_vref_f0 = cal_retrieve_value(CA_WRDQ_VREF_NUM_BITS, &bit_pos, &byte_pos); + + // Program CA and WRDQ optimal Vref's + wrdqcalvrefcodecontrol = CSR_READ(rAMP_WRDQCALVREFCODESTATUS(ch)); + CSR_WRITE(rAMP_WRDQCALVREFCODECONTROL(ch), (wrdqcalvrefcodecontrol & WRDQ_VREF_F0_MASK) | (wrdq_vref_f0 << WRDQ_VREF_F0_OFFSET)); + + + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0x00C0FFFF) | (0xC << 16) | (ca_vref_f0 << 24)); + + // Program AMPS register with optimal RDDQ Vref + amp_program_rddq_vref(ch, rddq_vref_f0, 0, 0); + } + } +} + +_ROMCODE_SEGMENT_PREFIX void calibration_dump_results(uint32_t operations, bool dump_passing_window) +{ + uint32_t ch, rnk, chrnk_indx, bit, byte, tmp; + + if ((operations & (SELECT_CAL_ALL)) == 0) + // Nothing selected + return; + + shim_printf("LPDDR4 DCS Calibration final results"); + + if (dump_passing_window) + shim_printf(" with passing points per rank in brackets"); + + shim_printf(":\n"); + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + shim_printf("DCS Channel %d\n", ch); + + if (operations & SELECT_CACAL) { + shim_printf("\tCA SDLL: %d\n", CSR_READ(rAMP_CASDLLCODE(ch))); + shim_printf("\tCS SDLL: %d\n", CSR_READ(rAMP_CSSDLLCODE(ch))); + shim_printf("\tCK SDLL: %d\n", CSR_READ(rAMP_CKSDLLCODE(ch))); + + shim_printf("\t\tPer Bit Deskew: "); + for (bit = 0; bit < CA_NUM_BITS; bit++) { + shim_printf("%d ", CSR_READ(rAMP_CADESKEW_CTRL(ch, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_window && !cfg_params.resume) { + + shim_printf("["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + + + shim_printf("%d ", cacal_per_chrnk_right[chrnk_indx][bit]); + shim_printf("%d", cacal_per_chrnk_left[chrnk_indx][bit]); + } + + shim_printf("] "); + } + + } + shim_printf("\n\t\tCS Deskew: %d", CSR_READ(rAMP_CSDESKEW_CTRL(ch)) & DESKEW_CTRL_BITS); + shim_printf("\n\t\tCK Deskew: %d", CSR_READ(rAMP_CKDESKEW_CTRL(ch)) & DESKEW_CTRL_BITS); + shim_printf("\n"); + } + + if (operations & SELECT_WRLVLCAL) { + + shim_printf("\tCA WrLvlSDLL: %d", CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & DLLVAL_BITS); + + if (dump_passing_window && !cfg_params.resume) { + shim_printf(" ["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + + + shim_printf("%d ", wrlvlcal_per_chrnk_rise[chrnk_indx][DQ_NUM_BYTES]); + shim_printf("%d", wrlvlcal_per_chrnk_fall[chrnk_indx][DQ_NUM_BYTES]); + } + + shim_printf("]"); + } + + shim_printf("\n"); + + shim_printf("\tDQ WrLvlSDLL: "); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + shim_printf("%d ", CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & DLLVAL_BITS); + + if (dump_passing_window && !cfg_params.resume) { + shim_printf("["); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + + + shim_printf("%d ", wrlvlcal_per_chrnk_rise[chrnk_indx][byte]); + shim_printf("%d", wrlvlcal_per_chrnk_fall[chrnk_indx][byte]); + } + + shim_printf("] "); + } + } + + shim_printf("\n"); + } + + if (operations & SELECT_RDDQCAL) { + + shim_printf("\tRead DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + shim_printf("\t\tByte %d SDLL: %d\n", byte, CSR_READ(rAMP_DQSDLLCODE_RD(byte, ch)) & DLLVAL_BITS); + + shim_printf("\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + shim_printf("%d ", CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_window) { + shim_printf("["); + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + shim_printf("%d ", rddqcal_per_chrnk_right[chrnk_indx][vref_opt_rddq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + shim_printf("%d", rddqcal_per_chrnk_left[chrnk_indx][vref_opt_rddq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + } + shim_printf("] "); + } + } + + shim_printf("\n"); + } + } + + if (operations & SELECT_WRDQCAL) { + + shim_printf("\tWrite DQ:\n"); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tmp = CSR_READ(rAMP_WRDQSDQ_SDLLCODE(byte, ch)); + shim_printf("\t\tByte %d DQ SDLL: %d\n", byte, (tmp >> 0) & DLLVAL_BITS); + shim_printf("\t\tByte %d DQS SDLL: %d\n", byte, (tmp >> 8) & DLLVAL_BITS); + + shim_printf("\t\t\tPer Bit Deskew: "); + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + shim_printf("%d ", CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit)) & DESKEW_CTRL_BITS); + + if (dump_passing_window) { + shim_printf(" ["); + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + if (rnk > 0) + shim_printf(", "); + + shim_printf("%d ", wrdqcal_per_chrnk_right[chrnk_indx][vref_opt_wrdq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + shim_printf("%d", wrdqcal_per_chrnk_left[chrnk_indx][vref_opt_wrdq[chrnk_indx]][bit + DQ_NUM_BITS_PER_BYTE * byte]); + } + shim_printf("] "); + } + } + + shim_printf("\n"); + } + } + } +} + +#ifdef ENV_DV +// Force initialization of cfg_params (used by DV) +_ROMCODE_SEGMENT_PREFIX void calibration_init_cfg_params() +{ + // Allow shim layer to change parameters as needed + shim_init_calibration_params(&cfg_params); +} +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////// +// CA Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +// CP : Use the following settings for Maui +// cfg_params.sw_loops = 1 +// cfg_params.num_ranks = 1 +// Number of HW Loops >= 16 ****ALWAYS**** +// NOTE: cfg_params.hw_loops is "number of loops less one", so (cfg_params.hw_loops >= 15) +_ROMCODE_SEGMENT_PREFIX void calibrate_ca(void) +{ + uint32_t ch, rnk, swloop, mask_bits, vref; + + uint32_t loopchrnk0_indx; + uint32_t curr_freq_bin; + uint32_t good_vref_not_found; + + // Initialize registers for CA calibration + cacal_init_registers(); + + // CP : Maui Change + // CP : Masks will change for Maui + cacal_generate_patterns_mask(); + + mask_bits = 0; + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + + // CP : Maui Change + amp_setup_ca_cal(ch, rnk, swloop); + + // Reset DQS weak pull-down before CA entry + curr_freq_bin = 3; + amp_reset_dqs_weak_pd(ch, curr_freq_bin); + + // Enter CA training mode + amp_enter_cacal_mode(ch); + + // Switch to target Freq (800Mz or 1200MHz) + if(cfg_params.freq_bin < 2) + cal_pmgr_change_mcu_clk(cfg_params.freq_bin); + + // Update SOC Drive Strengths to match DRAM's FSP + run_soc_upd(ch); + + // Apply Samsung work-around. + if(shim_apply_samsung_workaround()) { + // Perform Impedance calibration. + amp_do_imp_calib(ch); + } + + + // Saving Bucket 1 calibration results at the end of Bin1 calibration + // Don't save in Elba, since there is no frequency bin 1. + //if(cfg_params.freq_bin == 0) { + // amp_save_ca_bucket1(ch); + //} + + // Clear all CA, CS and CK registers before starting CS/CA calibration. + amp_init_ca_deskew(ch); + amp_init_ca_cs_ck_sdll(ch); + + // Clear WrLvl SDLL before starting CA calibration. + // + amp_program_cawrlvl_sdll(ch, 0, 0); + + // If we are going to frequency Bin 0 from Bin 1, Software initiated MDLL calibration must be done + // to lock in the new MDLL code + // FIXME_ELBA: Is this required for Elba?? + if(cfg_params.freq_bin == 0) { + amp_do_mdll_calib(ch); + } + + // Required since the dll values may change slightly during calibration + amp_save_masterdll_values(); + + // Following scaling is not applicable to Elba, since Bin 1 is not supported. + ////////******************************************************************************* + /* + // Scale Bin1 CK and CS SDLL based on MDLL values at Bin 1 and Bin 0 calibrations. + if(cfg_params.freq_bin == 0 && (cfg_params.disable_coarse_cs_training == true)) { + + shim_printf("DEBUG - ClkPeriod for Bin0=%d, mdllcode_freq_bin_1[ch]=%d, ClkPeriod for Bin1=%d, mdllcode[ch][AMP_CA]=%d \n", + cfg_params.clk_period_bin0, mdllcode_freq_bin_1[ch], cfg_params.clk_period_bin1, mdllcode[ch][AMP_CA]); + + if (cfg_params.clk_period_bin0 == 0) { + shim_panic("Clock Period for Freq Bin 0 should not be ZERO"); + } + + vt_scl_factor = (cfg_params.clk_period_bin1 * mdllcode[ch][AMP_CA] * 100)/(cfg_params.clk_period_bin0 * mdllcode_freq_bin_1[ch]); + shim_printf("DEBUG - Computed vt_scl_factor for Bin 0 as %d \n", vt_scl_factor); + + cs_sdll_precal_bin0 = (cssdll_bucket1[ch] * vt_scl_factor + (100 >> 1))/100; + shim_printf("DEBUG - Computed cs_sdll_precal_bin0 value as %d \n", cs_sdll_precal_bin0); + + ck_sdll_precal_bin0 = (cksdll_bucket1[ch] * vt_scl_factor + (100 >> 1))/100; + shim_printf("DEBUG - Computed ck_sdll_precal_bin0 value as %d \n", ck_sdll_precal_bin0); + + // Program the scaled value into CK and CS SDLL registers. + amp_program_ck_sdll(ch, ck_sdll_precal_bin0); + amp_program_cs_sdll(ch, cs_sdll_precal_bin0); + + // Save MDLL code during Bin 1 calibration. + if(cfg_params.freq_bin == 1) { + mdllcode_freq_bin_1[ch] = mdllcode[ch][AMP_CA]; + shim_printf("DEBUG - Saving a value of %d for frequency bin 1 mdll code for channel %d \n",mdllcode_freq_bin_1[ch], ch); + } + } + */ + ////////******************************************************************************* + + // Calibration sequence is to be run for each Vref setting for each rank in each channel, cfg_params.cacalib_sw_loops number of times + for (vref = 0; vref < cfg_params.ca_num_vref; vref++) { + + // Program Vref setting + amp_program_ca_vref(ch, cfg_params.ca_vref_values[vref], cfg_params.cacalib_dqs_pulse_cnt, cfg_params.cacalib_dqs_pulse_width); + + // Set the Vref run bit + amp_run_cacal_vref(ch); + + cksdll_cscal[vref] = 0; + cssdll_cscal[vref] = 0; + + // Coarse CS calibration is done for Elba + // CS Training + cacal_run_sequence(ch, rnk, CS_TRAINING, mask_bits, swloop, vref); + + // Program delay values calculated from CS training + cacal_program_cs_training_values(); + + cksdll_cscal[vref] = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll_cscal[vref] = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + //shim_printf("DEBUG - After CS training for ch=%d, vref=%d, CKSDLL=0x%x, CSSDLL=0x%x \n", ch, vref, cksdll_cscal[vref], cssdll_cscal[vref]); + + // Training of CA Bits 0-5 + cacal_run_sequence(ch, rnk, CA_TRAINING, mask_bits, swloop, vref); + + // Clear all CA, CS and CK registers before proceeding to the next Vref value + amp_init_ca_deskew(ch); + amp_init_ca_cs_ck_sdll(ch); + } + + if(cfg_params.freq_bin == 1) { + cal_pmgr_change_mcu_clk(3); // switch to 50MHz + } else { + // DON'T restore for Elba since there is no Bin 1 calibration. + // Restore 800Mhz calibrated values + // amp_program_ca_bucket1(ch); + + cal_pmgr_change_mcu_clk(3); // switch to 50MHz + } + // Update SOC Drive Strengths to match DRAM's FSP + run_soc_upd(ch); + + // Exit CA Training mode + amp_exit_cacal_mode(ch); + + // Set DQS weak pull-down after CA entry + curr_freq_bin = 3; + amp_set_dqs_weak_pd(ch, curr_freq_bin); + + // Find if there is even a single Vref which did not panic. + good_vref_not_found = 1; + for (vref = 0; vref < cfg_params.ca_num_vref; vref++) { + good_vref_not_found &= cacal_vref_panic[ch][vref]; + } + if(good_vref_not_found == 1) { + shim_panic("Memory CA calibration: Unable to find any Vref which did not panic for channel %d\n", ch); + } + + // Compute the optimal Vref index + amp_compute_opt_vref_cacal(ch, rnk, swloop, CA_NUM_BITS); + } + } + } + + // By now, we have compiled right and left edges of passing window for all CA bits over a number of iterations + // Aggregate the results, and find the center point of the window, and program it + // Make sure CS trained values are not messed up because of CA training programing + // Make sure final CK SDLL value is same for both CS & CA trainings. + + cacal_program_final_values(); + + // Do a second stage CS training at the optimal Vref. + // Once we figure out the final window and optimal Vref values, do CS training again. + // We need to move CK & CA together in this step. The final CSSDLL value from this step + // will be programmed into CS SDLL. + //***** Fine tune CS calibration *******// + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + + // Reset DQS weak pull-down before CA entry + curr_freq_bin = 3; + amp_reset_dqs_weak_pd(ch, curr_freq_bin); + + // Enter CA training mode + amp_enter_cacal_mode(ch); + + if(cfg_params.freq_bin < 2) + cal_pmgr_change_mcu_clk(cfg_params.freq_bin); // switch to target Freq (800Mz or 1200MHz) + + // Update SOC Drive Strengths to match DRAM's FSP + run_soc_upd(ch); + + // Apply Samsung work-around. + if(shim_apply_samsung_workaround()) { + // Perform Impedance calibration. + amp_do_imp_calib(ch); + } + + // Program optimal Vref setting + loopchrnk0_indx = loopchrnk_index_calc(ch, rnk, swloop); + uint32_t vref_ch = vref_opt_ca[loopchrnk0_indx]; + amp_program_ca_vref(ch, cfg_params.ca_vref_values[vref_ch], cfg_params.cacalib_dqs_pulse_cnt, cfg_params.cacalib_dqs_pulse_width); //vref_pulse_cnt=0 + + // Set the Vref run bit + amp_run_cacal_vref(ch); + + cksdll_cscal[vref_ch] = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll_cscal[vref_ch] = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + casdll_cscal[vref_ch] = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + // Training of CA Bits 0-5 + cacal_run_sequence(ch, rnk, CS_FINE_TRAINING, mask_bits, swloop, vref_ch); + + // Program delay values calculated from fine CS training + cacal_program_cs_training_values(); + + cksdll_cscal[vref_ch] = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll_cscal[vref_ch] = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + casdll_cscal[vref_ch] = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + if(cfg_params.freq_bin == 1) { + cal_pmgr_change_mcu_clk(3); // switch to 50MHz + } else { + // Don't restore for Elba since there is no Bin 1 calibration. + // Restore 800Mhz calibrated values + //amp_program_ca_bucket1(ch); + + cal_pmgr_change_mcu_clk(3); // switch to 50MHz + } + // Update SOC Drive Strengths to match DRAM's FSP + run_soc_upd(ch); + + // Exit CA Training mode + amp_exit_cacal_mode(ch); + + // Set DQS weak pull-down after CA entry + curr_freq_bin = 3; + amp_set_dqs_weak_pd(ch, curr_freq_bin); + } + } + } + + // Program CA calibration results again after fine tune CS training. + cacal_program_final_values(); + + if(cfg_params.freq_bin == 1) { + amp_save_ca_bucket1(ch); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// RdDQ Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void calibrate_rddq(void) +{ + uint32_t ch, rnk, vref; + uint32_t good_vref_not_found; + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + amp_setup_rddq_cal(ch, rnk); + + // Populate FIFO in Bin 3 by sending MPC Wr-FIFO command + if(cfg_params.rddq_legacy_mode == false) { + // Switch to Bin 3 + cal_pmgr_change_mcu_clk(3); // switch to 50MHz + + // Send Wr-FIFO commands + amp_rddq_cal_wrfifo(ch, rnk); + + // Switch back to Bin 0 + cal_pmgr_change_mcu_clk(0); // switch to 1600MHz + } + + for(vref = 0; vref < cfg_params.rddq_num_vref; vref++) { + + // Program RDDQ Vref setting + amp_program_rddq_vref(ch, cfg_params.rddq_vref_values[vref], 0, cfg_params.freq_bin); + + // Find the left and right edges of the eye + // CP : Maui Change + // Find Left failing point first. Then, move on to finding right failing point. + rddqcal_find_left_failing_point(ch, rnk, vref, false); + rddqcal_find_right_failing_point(ch, rnk, vref, false); + + } + // Find if there is even a single Vref which did not panic. + good_vref_not_found = 1; + for(vref = 0; vref < cfg_params.rddq_num_vref; vref++) { + good_vref_not_found &= rddqcal_vref_panic[ch][vref]; + } + if(good_vref_not_found == 1) { + shim_panic("Memory RDDQ calibration: Unable to find any Vref which did not panic for channel %d\n", ch); + } + + // Compute the optimal Vref index + amp_compute_opt_vref_rddqcal(ch, rnk, (DQ_TOTAL_BITS + DMI_TOTAL_BITS)); + } + } + + // Now that we have per bit left and right endpoints for each channel and rank, aggregate and program final values + rddqcal_program_final_values(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// WrLvl Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +// Align the clock signal with the DQ signals +_ROMCODE_SEGMENT_PREFIX void calibrate_wrlvl(void) +{ + uint32_t ch, rnk; + uint8_t byte; + + amp_wrlvl_init(); + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + + // Set up MRW-1 & MRW-2 for Write leveling entry + // Set RunWrlvlEntry bit + amp_wrlvl_entry(ch); + + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + // Program CAWRLVL to 0. + // Program WR WRLVL fields to the value before Write Leveling. + // + amp_program_cawrlvl_sdll(ch, 0, 0); + for(byte = 0; byte < DQ_NUM_BYTES; byte++) { + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + // find the region where all bits return a 0 + wrlvlcal_push_to_0s_region(ch, rnk); + + // push out the clock signal until all bits return a 1 + wrlvlcal_find_0to1_transition(ch, rnk); + + // now go back towards the transition edge found earlier, but from this side of the edge + wrlvlcal_find_1to0_transition(ch, rnk); + } + + // Set up MRW-1 & MRW-2 for Write leveling exit + // Set RunWrlvlExit bit + amp_wrlvl_exit(ch, cfg_params.freq_bin); + } + + // Program the final wrlvl values + wrlvlcal_program_final_values(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// WrDQ Sequence +//////////////////////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void calibrate_wrdq(void) +{ + uint32_t ch, rnk; + uint32_t chrnk_indx; + uint32_t byte; + + for (ch = 0; ch < cfg_params.num_channels_runCalib; ch++) { + for (rnk = 0; rnk < cfg_params.num_ranks; rnk++) { + + wrdqcal_init_regs(ch, rnk); + + // Clear deskew registers + amp_init_wr_deskew(ch); + + // Read the value of CAWRLVL SDLL code obtained from Write Leveling + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + cawrlvl_sdll_wrlvl[chrnk_indx] = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & 0xFF; + shim_printf("DEBUG - calibrate_wrdq:: chrnk_indx=%d, cawrlvl_sdll_wrlvl[chrnk_indx]=0x%x \n",chrnk_indx, cawrlvl_sdll_wrlvl[chrnk_indx]); + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++) { + dqwrlvl_sdll_after_wrlvl[chrnk_indx][byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & 0xFF; + shim_printf("DEBUG - calibrate_wrdq:: chrnk_indx=%d, byte=%d, dqwrlvl_sdll_after_wrlvl[chrnk_indx][byte]=0x%x \n", chrnk_indx, byte, dqwrlvl_sdll_after_wrlvl[chrnk_indx][byte]); + } + + wrdqcal_sequence(ch, rnk); + } + } + + wrdqcal_program_final_values(); +} + +/////////////////////////////////////////////////////////////////////////////// +////// Local functions +/////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void amp_do_mdll_calib(uint32_t ch) +{ + uint8_t byte; + // POR is to program DLL update for both bytes and then poll for update to clear + // on both bytes. + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++) { + CSR_WRITE(rAMP_DLLUPDTCMD(byte, ch), 1 << RUN_DLL_UPDT); + } + + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++) { + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DLLUPDTCMD(byte, ch)) & (1 << RUN_DLL_UPDT)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_do_imp_calib(uint32_t ch) +{ + uint32_t ImpCalCmd; + + ImpCalCmd = CSR_READ(rAMP_CA_IMPCALCMD(ch)); + + ImpCalCmd = (ImpCalCmd & RUNIMPCAL_MASK) | (1 << RUNIMPCAL_OFFSET); + + CSR_WRITE(rAMP_CA_IMPCALCMD(ch), ImpCalCmd); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CA_IMPCALCMD(ch)) & (1 << RUNIMPCAL_OFFSET)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_setup_ca_cal(uint32_t ch, uint32_t rnk, uint32_t swloop) +{ + uint32_t cacalctrl; + + // Map the CA bits to appropriate dq byte lanes, accounting for swizzling. + // Bytes 0 and 2 from DDR are hooked to AMPDQ0, and are bit swizzled (i.e., bit 0 from DDR connected to bit 7 on AMPDQ, and so on). + // Bytes 1 and 3 are hooked to AMPDQ1, and are NOT bit swizzled. + // For the 10 CA bits, that means CA0-3 (MR41) and CA4 (MR48) come back from DDR on AMPDQ0, + // and CA5-8 (MR41) and CA9 (MR48) on AMPDQ1. + + CSR_WRITE(rAMP_CACALBITSELECT(ch), ((cfg_params.cacal_bit_sel[7] << 28)|(cfg_params.cacal_bit_sel[6] << 24)|(cfg_params.cacal_bit_sel[5] << 20)|(cfg_params.cacal_bit_sel[4] << 16)|(cfg_params.cacal_bit_sel[3] << 12)|(cfg_params.cacal_bit_sel[2] << 8)|(cfg_params.cacal_bit_sel[1]<< 4)|(cfg_params.cacal_bit_sel[0] << 0))); + + // Program rank, hardware loop count, and timing params + // Timing params are taken from lpddr4 jedec spec + // Program DQ Byte on which to expect CA data during calibration + cacalctrl = (cfg_params.cacal_rd_byte_sel << 28) | (rnk << 24) | (cfg_params.cacalib_hw_loops << 16) | (cfg_params.tADR << 8) | (cfg_params.tMRD << 0); + + CSR_WRITE(rAMP_CACALCTRL(ch), cacalctrl); + + // CP: Maui Change + // Also Program rAMP_CACALCTRL2 register + CSR_WRITE(rAMP_CACALCTRL2(ch),(cfg_params.tDSTrain << 24) | (cfg_params.tCKCKEH << 16) | (cfg_params.tVREF_LONG << 8) | (cfg_params.tCAENT)); + + // Program rAMP_CACALCTRL3 register + CSR_WRITE(rAMP_CACALCTRL3(ch),(cfg_params.CsActiveCycleCnt << 24) | (cfg_params.CsStopCycleCnt << 16) | (cfg_params.tDQSCKE << 8) | (cfg_params.tCKEHCMD)); + + // Program CA invert mask + CSR_WRITE(rAMP_CACALPAT(ch), (cfg_params.ca_invert_mask<<16)|(0)); + + // Program PRBS7I patterns + CSR_WRITE(rAMP_CALPATPRBS7_0(ch), cfg_params.prbs7_pattern_0); + CSR_WRITE(rAMP_CALPATPRBS7_1(ch), cfg_params.prbs7_pattern_1); + CSR_WRITE(rAMP_CALPATPRBS7_2(ch), cfg_params.prbs7_pattern_2); + CSR_WRITE(rAMP_CALPATPRBS7_3(ch), cfg_params.prbs7_pattern_3); + + // Program start points in PRBS7I patterns for all CA bits + CSR_WRITE(rAMP_CACALPATSEED_0(ch), (cfg_params.ca_prbs_seed_bit[3] << 24) | (cfg_params.ca_prbs_seed_bit[2] << 16) | (cfg_params.ca_prbs_seed_bit[1] << 8) | (cfg_params.ca_prbs_seed_bit[0] << 0)); + CSR_WRITE(rAMP_CACALPATSEED_1(ch), (cfg_params.ca_prbs_seed_bit[5] << 8) | (cfg_params.ca_prbs_seed_bit[4] << 0)); +} + +_ROMCODE_SEGMENT_PREFIX void run_soc_upd(uint32_t ch) +{ + uint32_t freqchngctl; + + // Save the value of freqchngctl register + freqchngctl = CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch), (freqchngctl & 0xFFFEFFFF) | 0x10000); + + // Add some delay here. Do dummy reads + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); + CSR_READ(rAMCX_DRAMCFG_FREQCHNGMRWCNT(ch)); +} + +// CP : Maui Change +_ROMCODE_SEGMENT_PREFIX void amp_program_ca_vref(uint32_t ch, uint32_t vref, uint32_t cacalib_dqs_pulse_cnt, uint32_t cacalib_dqs_pulse_width) +{ + uint32_t cacacalvref; + uint32_t vref_swizzled; + + // This is required if there is any bit swizzling. + vref_swizzled = (((vref & 0x40) >> 6) << cfg_params.cacal_bit_sel[6]) | ( ((vref & 0x20) >> 5) << cfg_params.cacal_bit_sel[5]) | (((vref & 0x10) >> 4) << cfg_params.cacal_bit_sel[4]) | (((vref & 0x8) >> 3) << cfg_params.cacal_bit_sel[3]) + | (((vref & 0x4) >> 2) << cfg_params.cacal_bit_sel[2]) | (((vref & 0x2) >> 1) << cfg_params.cacal_bit_sel[1]) | (((vref & 0x1) >> 0) << cfg_params.cacal_bit_sel[0]); + + // Program + // 1.Vref setting at which CA calibration is to be run + // 2.Vref pulse count + cacacalvref = CSR_READ(rAMP_CACACALVREF(ch)); + + CSR_WRITE(rAMP_CACACALVREF(ch),(cacacalvref & 0xFF000000) | (cacalib_dqs_pulse_width << CACAL_DQS_PULSE_WIDTH_OFFSET) | (cacalib_dqs_pulse_cnt << CACAL_DQS_PULSE_CNT_OFFSET) | (vref_swizzled)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_rddq_vref(uint32_t ch, uint32_t vref, uint32_t vref_pulse_cnt, uint8_t freq_bin) +{ + uint32_t rddqcalvrefcodecontrol; + + // Program + // 1.Vref setting at which RDDQ calibration is to be run + // 2.Vref pulse count + + if(freq_bin == 0) { + // Program AMPS register with optimal RDDQ Vref + rddqcalvrefcodecontrol = CSR_READ(rAMP_RDDQCALVREFCODESTATUS(ch)); + CSR_WRITE(rAMP_RDDQCALVREFCODECONTROL(ch), (rddqcalvrefcodecontrol & RDDQ_VREF_F0_MASK) | (1 << 7) | (vref << RDDQ_VREF_F0_OFFSET)); + } + else if(freq_bin == 1) { + // Program AMPS register with optimal RDDQ Vref + rddqcalvrefcodecontrol = CSR_READ(rAMP_RDDQCALVREFCODESTATUS(ch)); + CSR_WRITE(rAMP_RDDQCALVREFCODECONTROL(ch), (rddqcalvrefcodecontrol & RDDQ_VREF_F1_MASK) | (1 << 7) | (vref << RDDQ_VREF_F1_OFFSET)); + } +} + +// CP : Maui Change +_ROMCODE_SEGMENT_PREFIX void amp_program_wrdq_vref(uint8_t chan, uint8_t rank, uint32_t vref, uint32_t vref_pulse_cnt) +{ + uint32_t mr14_data; + + shim_mrcmd_to_ch_rnk(MR_READ, chan, rank, MR14, (uintptr_t)&mr14_data); + + mr14_data = (mr14_data &0x80) | (vref); + + shim_mrcmd_to_ch_rnk(MR_WRITE, chan, rank, MR14, mr14_data); +} + +// (Re-)Initialize CA & CS deskew registers +_ROMCODE_SEGMENT_PREFIX void amp_init_ca_deskew(uint32_t ch) +{ + uint32_t d; + + // Clear cadeskewctrl registers + for (d = 0; d < CA_NUM_BITS; d++) { + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, d), 0 | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, d)) & RUNDESKEWUPD); + } +} + +// (Re-)Initialize CA, CK and CS SDLL registers +_ROMCODE_SEGMENT_PREFIX void amp_init_ca_cs_ck_sdll(uint32_t ch) +{ + // Clear casdll register + CSR_WRITE(rAMP_CASDLLCTRL(ch), (0 << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CASDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); + + // Clear cssdll register + CSR_WRITE(rAMP_CSSDLLCTRL(ch), (0 << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CSSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); + + // Clear cksdll register + CSR_WRITE(rAMP_CKSDLLCTRL(ch), (0 << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CKSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); + +} + +_ROMCODE_SEGMENT_PREFIX void amp_init_wr_deskew(uint32_t ch) +{ + uint8_t byte, bit_indx; + + for(byte = 0; byte < DQ_NUM_BYTES; byte++) { + // Clear DQS deskew + CSR_WRITE(rAMP_WRDQSDESKEW_CTRL(byte, ch), 0 | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQSDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + + // Clear DM deskew + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(byte, ch), 0 | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + + // Clear DQ deskew + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx), 0 | RUNDESKEWUPD); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + } + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_push_casdll_out(uint32_t ch, uint32_t casdll_ovr_val) +{ + uint32_t ca_bit; + uint32_t casdll_tap; + uint32_t cadeskewcode; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + if (casdll_ovr_val > (3 * mdllcode[ch][AMP_CA] + 1 )) { + casdll_tap = (3 * mdllcode[ch][AMP_CA]); + + if ((casdll_ovr_val - casdll_tap) >= MAX_DESKEW_PROGRAMMED) + cadeskewcode = MAX_DESKEW_PROGRAMMED; + else + cadeskewcode = casdll_ovr_val - casdll_tap; + + // Adjust deskew registers for each ca bit + for (ca_bit = 0; ca_bit < CA_NUM_BITS; ca_bit++) { + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, ca_bit), cadeskewcode | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, ca_bit)) & RUNDESKEWUPD); + } + + casdll_ovr_val = (3 * mdllcode[ch][AMP_CA]); + + } + + CSR_WRITE(rAMP_CASDLLCTRL(ch), (casdll_ovr_val << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CASDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_ca_sdll(uint32_t ch, uint32_t casdll_val) +{ + CSR_WRITE(rAMP_CASDLLCTRL(ch), (casdll_val << SDLLOFFSET) | (1 << RUN_SDLLUPDWRRES)); + + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CASDLLCTRL(ch)) & (1 << RUN_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_push_cksdll_out(uint32_t ch, uint32_t cksdll_ovr_val) +{ + uint32_t cksdll_tap; + uint32_t ckdeskewcode; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + if (cksdll_ovr_val > (3 * mdllcode[ch][AMP_CA]) + 1) { + cksdll_tap = (3 * mdllcode[ch][AMP_CA]); + + if ((cksdll_ovr_val - cksdll_tap) >= MAX_DESKEW_PROGRAMMED) + ckdeskewcode = MAX_DESKEW_PROGRAMMED; + else + ckdeskewcode = cksdll_ovr_val - cksdll_tap; + + // Adjust deskew registers for each ck bit + CSR_WRITE(rAMP_CKDESKEW_CTRL(ch), ckdeskewcode | RUNDESKEWUPD); + + cksdll_ovr_val = (3 * mdllcode[ch][AMP_CA]); + } + + CSR_WRITE(rAMP_CKSDLLCTRL(ch), (cksdll_ovr_val << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CKSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_ck_sdll(uint32_t ch, uint32_t cksdll_val) +{ + CSR_WRITE(rAMP_CKSDLLCTRL(ch), (cksdll_val << SDLLOFFSET) | (1 << RUN_SDLLUPDWRRES)); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CKSDLLCTRL(ch)) & (1 << RUN_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_push_cssdll_out(uint32_t ch, uint32_t cssdll_ovr_val) +{ + uint32_t cssdll_tap; + uint32_t csdeskewcode; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + if (cssdll_ovr_val > (3 * mdllcode[ch][AMP_CA]) + 1) { + cssdll_tap = (3 * mdllcode[ch][AMP_CA]); + + if ((cssdll_ovr_val - cssdll_tap) >= MAX_DESKEW_PROGRAMMED) + csdeskewcode = MAX_DESKEW_PROGRAMMED; + else + csdeskewcode = cssdll_ovr_val - cssdll_tap; + + // Adjust deskew register for CS + CSR_WRITE(rAMP_CSDESKEW_CTRL(ch), csdeskewcode | RUNDESKEWUPD); + + cssdll_ovr_val = (3 * mdllcode[ch][AMP_CA]); + } + + CSR_WRITE(rAMP_CSSDLLCTRL(ch), (cssdll_ovr_val << SDLLOFFSET) | (1 << RUN_SDLLUPDOVR)); + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CSSDLLCTRL(ch)) & (1 << RUN_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_cs_sdll(uint32_t ch, uint32_t cssdll_val) +{ + CSR_WRITE(rAMP_CSSDLLCTRL(ch), (cssdll_val << SDLLOFFSET) | (1 << RUN_SDLLUPDWRRES)); + + // Poll for SDLL RunOverride bit to go low + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CSSDLLCTRL(ch)) & (1 << RUN_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_dqs_weak_pd(uint32_t ch, uint32_t freq_bin) +{ + uint32_t amph_cfgh_dqs0_wkpupd, amph_cfgh_dqs1_wkpupd; + + amph_cfgh_dqs0_wkpupd = CSR_READ(rAMPH_CFGH_DQS0_WKPUPD(ch)); + amph_cfgh_dqs1_wkpupd = CSR_READ(rAMPH_CFGH_DQS1_WKPUPD(ch)); + + + if(freq_bin == 0) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F0_WEAK_PD_MASK) | (1 << F0_WEAK_PD_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F0_WEAK_PD_MASK) | (1 << F0_WEAK_PD_OFFSET)); + } + else if(freq_bin == 1) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F1_WEAK_PD_MASK) | (1 << F1_WEAK_PD_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F1_WEAK_PD_MASK) | (1 << F1_WEAK_PD_OFFSET)); + } + else if(freq_bin == 3) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F3_WEAK_PD_MASK) | (1 << F3_WEAK_PD_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F3_WEAK_PD_MASK) | (1 << F3_WEAK_PD_OFFSET)); + } + + +} + +_ROMCODE_SEGMENT_PREFIX void amp_reset_dqs_weak_pd(uint32_t ch, uint32_t freq_bin) +{ + uint32_t amph_cfgh_dqs0_wkpupd, amph_cfgh_dqs1_wkpupd; + + amph_cfgh_dqs0_wkpupd = CSR_READ(rAMPH_CFGH_DQS0_WKPUPD(ch)); + amph_cfgh_dqs1_wkpupd = CSR_READ(rAMPH_CFGH_DQS1_WKPUPD(ch)); + + + if(freq_bin == 0) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F0_WEAK_PD_MASK) | (0 << F0_WEAK_PD_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F0_WEAK_PD_MASK) | (0 << F0_WEAK_PD_OFFSET)); + } + else if(freq_bin == 1) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F1_WEAK_PD_MASK) | (0 << F1_WEAK_PD_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F1_WEAK_PD_MASK) | (0 << F1_WEAK_PD_OFFSET)); + } + else if(freq_bin == 3) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F3_WEAK_PD_MASK) | (0 << F3_WEAK_PD_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F3_WEAK_PD_MASK) | (0 << F3_WEAK_PD_OFFSET)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_dqs_idle_active(uint32_t ch, uint32_t freq_bin) +{ + uint32_t amph_cfgh_dqs0_wkpupd, amph_cfgh_dqs1_wkpupd; + + amph_cfgh_dqs0_wkpupd = CSR_READ(rAMPH_CFGH_DQS0_WKPUPD(ch)); + amph_cfgh_dqs1_wkpupd = CSR_READ(rAMPH_CFGH_DQS1_WKPUPD(ch)); + + + if(freq_bin == 0) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F0_IDLE_ACTIVE_MASK) | (1 << F0_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F0_IDLE_ACTIVE_MASK) | (1 << F0_IDLE_ACTIVE_OFFSET)); + } + else if(freq_bin == 1) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F1_IDLE_ACTIVE_MASK) | (1 << F1_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F1_IDLE_ACTIVE_MASK) | (1 << F1_IDLE_ACTIVE_OFFSET)); + } + else if(freq_bin == 3) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F3_IDLE_ACTIVE_MASK) | (1 << F3_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F3_IDLE_ACTIVE_MASK) | (1 << F3_IDLE_ACTIVE_OFFSET)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_reset_dqs_idle_active(uint32_t ch, uint32_t freq_bin) +{ + uint32_t amph_cfgh_dqs0_wkpupd, amph_cfgh_dqs1_wkpupd; + + amph_cfgh_dqs0_wkpupd = CSR_READ(rAMPH_CFGH_DQS0_WKPUPD(ch)); + amph_cfgh_dqs1_wkpupd = CSR_READ(rAMPH_CFGH_DQS1_WKPUPD(ch)); + + + if(freq_bin == 0) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F0_IDLE_ACTIVE_MASK) | (0 << F0_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F0_IDLE_ACTIVE_MASK) | (0 << F0_IDLE_ACTIVE_OFFSET)); + } + else if(freq_bin == 1) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F1_IDLE_ACTIVE_MASK) | (0 << F1_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F1_IDLE_ACTIVE_MASK) | (0 << F1_IDLE_ACTIVE_OFFSET)); + } + else if(freq_bin == 3) { + CSR_WRITE(rAMPH_CFGH_DQS0_WKPUPD(ch), (amph_cfgh_dqs0_wkpupd & F3_IDLE_ACTIVE_MASK) | (0 << F3_IDLE_ACTIVE_OFFSET)); + CSR_WRITE(rAMPH_CFGH_DQS1_WKPUPD(ch), (amph_cfgh_dqs1_wkpupd & F3_IDLE_ACTIVE_MASK) | (0 << F3_IDLE_ACTIVE_OFFSET)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_enter_cacal_mode(uint32_t ch) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALENTRY); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALENTRY); +} + +_ROMCODE_SEGMENT_PREFIX void amp_exit_cacal_mode(uint32_t ch) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + uint32_t cabist_bistrdfifoctrl = CSR_READ(rAMPH_CFGH_CABIST_BISTRDFIFOCTRL(ch)); + + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALEXIT); + + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALEXIT); + + // Toggle Read FIFO pointer reset. + CSR_WRITE(rAMPH_CFGH_CABIST_BISTRDFIFOCTRL(ch), (cabist_bistrdfifoctrl & BIST_RDFIFO_RESET_MASK) | (1 << BIST_RDFIFO_RESET_OFFSET)); + + SPIN_W_TMO_WHILE ((CSR_READ(rAMPH_CFGH_CABIST_BISTRDFIFOCTRL(ch)) & (1 << BIST_RDFIFO_RESET_OFFSET)) == 0); + + CSR_WRITE(rAMPH_CFGH_CABIST_BISTRDFIFOCTRL(ch), (cabist_bistrdfifoctrl & BIST_RDFIFO_RESET_MASK) | (0 << BIST_RDFIFO_RESET_OFFSET)); + + SPIN_W_TMO_WHILE ((CSR_READ(rAMPH_CFGH_CABIST_BISTRDFIFOCTRL(ch)) & (1 << BIST_RDFIFO_RESET_OFFSET)) == 1); +} + +_ROMCODE_SEGMENT_PREFIX void amp_run_cacal_vref(uint32_t ch) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + + // Set RunCaCalVref bit + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALVREF); + // Poll for RunCaCalVref to go low. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALVREF); +} + +_ROMCODE_SEGMENT_PREFIX static uint32_t amp_run_cacal(uint32_t ch, uint32_t training_mode) +{ + uint32_t cacalrun = CSR_READ(rAMP_CACALRUN(ch)); + + if(training_mode == CS_TRAINING) { + // Set RunCaCalCS bit + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALCS); + + // Poll on the RunCaCalCS bit + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALCS); + } + + if((training_mode == CA_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Set RunCaCalCA bit + CSR_WRITE(rAMP_CACALRUN(ch), cacalrun | CACALRUN_RUNCACALCA); + + // Poll on the RunCaCalCA bit + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CACALRUN(ch)) & CACALRUN_RUNCACALCA); + } + + return ((CSR_READ(rAMP_CACALRESULT(ch)) & CA_ALL_BITS)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_setup_rddq_cal(uint32_t ch, uint32_t rnk) +{ + // Program tWL, tRL for frequency bins 0-3 --> Should be part of the init sequence + + uint32_t rdwr_dqcal_loopcnt = CSR_READ(rAMP_RDWRDQCALLOOPCNT(ch)); + uint32_t rdwrdqcaltiming_f0 = CSR_READ(rAMP_RdWrDqCalTiming_f0(ch)); + uint32_t rdwrdqcaltiming_f1 = CSR_READ(rAMP_RdWrDqCalTiming_f1(ch)); + uint32_t dqcal_burst_len_mode = CSR_READ(rAMP_DQCAL_BURSTLEN_MODE(ch)); + uint8_t tRL, tWL; + + // Program SWRDDQCAL Loop count + CSR_WRITE(rAMP_RDWRDQCALLOOPCNT(ch), (rdwr_dqcal_loopcnt & 0xFFFFFF00) | (cfg_params.rddq_cal_loopcnt & 0xFF)); + + // Init sequence sets up pattern & Invert mask registers (MR15, MR20, MR32 & MR40) + + // Set up tRL values for each frequency bucket + tRL = ((cfg_params.RL)/2) - 6; + tWL = ((cfg_params.WL)/2) - 2; + + if(cfg_params.freq_bin == 0) { + CSR_WRITE(rAMP_RdWrDqCalTiming_f0(ch), (rdwrdqcaltiming_f0 & 0xFFFF0000) | (tWL << 8) | tRL); + } + else if(cfg_params.freq_bin == 1) { + shim_printf("amp_setup_rddq_cal:: Writing a value of 0x%x into rAMP_RdWrDqCalTiming_f1 \n", (rdwrdqcaltiming_f1 & 0xFFFF0000) | (tWL << 8) | tRL); + CSR_WRITE(rAMP_RdWrDqCalTiming_f1(ch), (rdwrdqcaltiming_f1 & 0xFFFF0000) | (tWL << 8) | tRL); + } + //CSR_WRITE(rAMP_RdWrDqCalTiming_f3(ch), (rdwrdqcaltiming_f3 & 0xFFFFFF00) | (0x0 << 4) | (0x0)); + + // Program PRBS7I patterns + CSR_WRITE(rAMP_CALPATPRBS7_0(ch), cfg_params.prbs7_pattern_0); + CSR_WRITE(rAMP_CALPATPRBS7_1(ch), cfg_params.prbs7_pattern_1); + CSR_WRITE(rAMP_CALPATPRBS7_2(ch), cfg_params.prbs7_pattern_2); + CSR_WRITE(rAMP_CALPATPRBS7_3(ch), cfg_params.prbs7_pattern_3); + + // Program start points in PRBS7I patterns for all CA bits + CSR_WRITE(rAMP_WRDQCALPATSEED_B0_0(ch), (cfg_params.wrdq_prbs_seed[0][3] << 24) | (cfg_params.wrdq_prbs_seed[0][2] << 16) | (cfg_params.wrdq_prbs_seed[0][1] << 8) | (cfg_params.wrdq_prbs_seed[0][0] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B0_1(ch), (cfg_params.wrdq_prbs_seed[0][7] << 24) | (cfg_params.wrdq_prbs_seed[0][6] << 16) | (cfg_params.wrdq_prbs_seed[0][5] << 8) | (cfg_params.wrdq_prbs_seed[0][4] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B0_2(ch), (cfg_params.wrdq_prbs_seed[0][8] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B1_0(ch), (cfg_params.wrdq_prbs_seed[1][3] << 24) | (cfg_params.wrdq_prbs_seed[1][2] << 16) | (cfg_params.wrdq_prbs_seed[1][1] << 8) | (cfg_params.wrdq_prbs_seed[1][0] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B1_1(ch), (cfg_params.wrdq_prbs_seed[1][7] << 24) | (cfg_params.wrdq_prbs_seed[1][6] << 16) | (cfg_params.wrdq_prbs_seed[1][5] << 8) | (cfg_params.wrdq_prbs_seed[1][4] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B1_2(ch), (cfg_params.wrdq_prbs_seed[1][8] << 0)); + + if(cfg_params.rddq_legacy_mode == true) { + CSR_WRITE(rAMP_DQCAL_BURSTLEN_MODE(ch), (dqcal_burst_len_mode & RDDQCAL_BURSTLEN_MODE_MASK) | (1 << RDDQCAL_BURSTLEN_MODE_OFFSET)); + } + else { + CSR_WRITE(rAMP_DQCAL_BURSTLEN_MODE(ch), (dqcal_burst_len_mode & RDDQCAL_BURSTLEN_MODE_MASK) | (0 << RDDQCAL_BURSTLEN_MODE_OFFSET)); + } +} + +// This functions sends WR-FIFO commands to populate FIFO for RDDQ calibration +_ROMCODE_SEGMENT_PREFIX void amp_rddq_cal_wrfifo(uint32_t ch, uint32_t rnk) +{ + uint32_t dq_cal_run = CSR_READ(rAMP_DQCALRUN(ch)); + + CSR_WRITE(rAMP_DQCALRUN(ch), (dq_cal_run & RUNRDDQCAL_WRFIFO_MASK) | (1 << RUNRDDQCAL_WRFIFO_OFFSET)); + while (CSR_READ(rAMP_DQCALRUN(ch)) & ~RUNRDDQCAL_WRFIFO_MASK); +} + +// This functions set the slave dll for a particular byte lane of RDDQ as specified in the offset parameter +_ROMCODE_SEGMENT_PREFIX void amp_set_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_ovr_val) +{ + uint32_t rd_clk_dlysel; + + rd_clk_dlysel = rddqcal_encode_dlyval(ch, ((byte == 0) ? AMP_DQ0 : AMP_DQ1), rddqs_sdll_ovr_val); + + // Program RDDLYSEL + CSR_WRITE(rAMP_RDCLKDLYSEL(byte, ch), rd_clk_dlysel); + + // CP : Maui change + CSR_WRITE(rAMP_DQSDLLCTRL_RD(byte, ch), (rddqs_sdll_ovr_val << 16) | (1 << RUN_SDLLUPDOVR)); + + // Wait for Run bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) & (1 << RUN_SDLLUPDOVR)); + +} + +// This functions set the slave dll for a particular byte lane of RDDQ as specified in the offset parameter +_ROMCODE_SEGMENT_PREFIX void amp_program_rddq_sdll(uint32_t ch, uint32_t byte, uint32_t rddqs_sdll_wr_val) +{ + uint32_t rd_clk_dlysel; + + rd_clk_dlysel = rddqcal_encode_dlyval(ch, ((byte == 0) ? AMP_DQ0 : AMP_DQ1), rddqs_sdll_wr_val); + //shim_printf("DEBUG - rddqs_sdll_wr_val = %d, Phy = %d, rd_clk_dlysel = %d \n", rddqs_sdll_wr_val, ((byte == 0) ? AMP_DQ0 : AMP_DQ1), rd_clk_dlysel); + + // Program RDDLYSEL + CSR_WRITE(rAMP_RDCLKDLYSEL(byte, ch), rd_clk_dlysel); + + // CP : Maui change + CSR_WRITE(rAMP_DQSDLLCTRL_RD(byte, ch), (rddqs_sdll_wr_val << 16) | (1 << RUN_SDLLUPDWRRES)); + + // Wait for Run bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) & (1 << RUN_SDLLUPDWRRES)); + +} + +_ROMCODE_SEGMENT_PREFIX void amp_run_rddqcal(uint32_t ch) +{ + // CP : Maui Change + uint32_t dq_cal_run = CSR_READ(rAMP_DQCALRUN(ch)); + + CSR_WRITE(rAMP_DQCALRUN(ch), (dq_cal_run & 0xFFFFFFFE) | (1 << 0)); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQCALRUN(ch)) & 1); +} + +_ROMCODE_SEGMENT_PREFIX void amp_wrlvl_init(void) +{ + uint32_t ch; + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + // Write Leveling Timing Control Registers to program tMRD and tWLO timing params + CSR_WRITE(rAMP_CAWRLVLTIM(ch), (cfg_params.tWLO << 16) | (cfg_params.tWLMRD << 8) | (cfg_params.tWLDQSEN << 0)); + } +} + +_ROMCODE_SEGMENT_PREFIX void amp_wrlvl_entry(uint32_t ch) +{ + uint32_t mr2_data, ca_run_wrlvl; + uint8_t wrlvl, wls, wl, rl; + + // Setup MRW-1 & MRW-2 for write leveling entry + // rAMP_CAWRLVLENTRYCMD : (MRW_2[11:0] << 16) | (MRW_1[11:0] <<0) + // MRW_1[5:0] = {WR_LVL, 5'b00110} = 6'b100110 + // MRW_1[11:6] = MA[5:0] = 6'b000010 + // MRW_1[11:0] = 12'b000010100110=0x0A6 + // MRW_2[5:0] = {OP[6], 5'b10110} = {mr2_data[6], 5'b10110} + // MRW_2[11:6] = {OP[5:0]} = {mr2_data[5:0] + // Hence, rAMP_CAWRLVLENTRYCMD = {(mr2_data[5:0] << 18) | (mr2_data[6] << 17) | (0x16 << 16) | (0x0A6 << 0) + wrlvl = 1; + wls = 0; + + if(cfg_params.freq_bin == 0) { + if(cfg_params.WL == 14) { + wls = 0; + } + else if(cfg_params.WL == 26) { + wls = 1; + } + wl = 5; // 'b101 + rl = 5; // 'b101 + } + else { + if(cfg_params.WL == 8) { + wls = 0; + } + else if(cfg_params.WL == 12) { + wls = 1; + } + wl = 2; // 'b010 + rl = 2; // 'b010 + } + + mr2_data = (wrlvl << 7) | (wls << 6) | (wl << 3) | (rl << 0); + + CSR_WRITE(rAMP_CAWRLVLENTRYCMD(ch), ((mr2_data & 0x3F) << 22) | (((mr2_data & 0x40)>> 6) << 21) | (0x16 << 16) | (0x0A6 << 0)); + + + // + // DQS IdleActive should be set while write leveling is going on + amp_set_dqs_idle_active(ch, cfg_params.freq_bin); + + // Set write leveling entry bit + ca_run_wrlvl = CSR_READ(rAMP_CARUNWRLVL(ch)); + CSR_WRITE(rAMP_CARUNWRLVL(ch), (ca_run_wrlvl & 0xFFFFFFFE) | (1 << RUNWRLVLENTRY_OFFSET)); + + // Poll for the RUNWRLVLENTRY bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CARUNWRLVL(ch)) & (1 << RUNWRLVLENTRY_OFFSET)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_wrlvl_exit(uint32_t ch, uint8_t freq_bin) +{ + uint32_t mr2_data, ca_run_wrlvl; + uint8_t wrlvl, wls, wl, rl; + + // Setup MRW-1 & MRW-2 for write leveling exit + // rAMP_CAWRLVLEXITCMD : (MRW_2[11:0] << 16) | (MRW_1[11:0] <<0) + // MRW_1[5:0] = {WR_LVL=0, 5'b00110} = 6'b000110 + // MRW_1[11:6] = MA[5:0] = 6'b000010 + // MRW_1[11:0] = 12'b000010000110=0x086 + // MRW_2[5:0] = {OP[6], 5'b10110} = {mr2_data[6], 5'b10110} + // MRW_2[11:6] = {OP[5:0]} = {mr2_data[5:0] + // Hence, rAMP_CAWRLVLEXITCMD = {(mr2_data[5:0] << 18) | (mr2_data[6] << 17) | (0x16 << 16) | (0x086 << 0) + wrlvl = 0; + wls = 0; + + if(cfg_params.freq_bin == 0) { + if(cfg_params.WL == 14) { + wls = 0; + } + else if(cfg_params.WL == 26) { + wls = 1; + } + wl = 5; // 'b101 + rl = 5; // 'b101 + } + else { + if(cfg_params.WL == 8) { + wls = 0; + } + else if(cfg_params.WL == 12) { + wls = 1; + } + wl = 2; // 'b010 + rl = 2; // 'b010 + } + + mr2_data = (wrlvl << 7) | (wls << 6) | (wl << 3) | (rl << 0); + + CSR_WRITE(rAMP_CAWRLVLEXITCMD(ch), ((mr2_data & 0x3F) << 22) | (((mr2_data & 0x40)>> 6) << 21) | (0x16 << 16) | (0x086 << 0)); + + // Set write leveling exit bit + ca_run_wrlvl = CSR_READ(rAMP_CARUNWRLVL(ch)); + CSR_WRITE(rAMP_CARUNWRLVL(ch), (ca_run_wrlvl & 0xFFFFFFF7) | (1 << RUNWRLVLEXIT_OFFSET)); + + // Poll for the RUNWRLVLEXIT bit to clear + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CARUNWRLVL(ch)) & (1 << RUNWRLVLEXIT_OFFSET)); + + // + // DQS IdleActive should be reset after write leveling is done. + amp_reset_dqs_idle_active(ch, cfg_params.freq_bin); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_cawrlvl_sdll(uint32_t ch, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t cawrlvl_code = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + cawrlvl_code = (cawrlvl_code & WRLVL_SDLLCODE_MASK) | (offset << WRLVL_SDLLCODE_OFFSET); + + CSR_WRITE(rAMP_CAWRLVLSDLLCODE(ch), cawrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_wrlvlmax_cawrlvl_sdll(uint32_t ch, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t cawrlvl_code = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + cawrlvl_code = (cawrlvl_code & WRLVLMAX_SDLLCODE_MASK) | (offset << WRLVLMAX_SDLLCODE_OFFSET); + + CSR_WRITE(rAMP_CAWRLVLSDLLCODE(ch), cawrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t dqwrlvl_code = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvl_code = (dqwrlvl_code & WRLVL_SDLLCODE_MASK) | (offset << WRLVL_SDLLCODE_OFFSET); + + // Byte 0 corresponds to DQ0, Byte 1 corresponds to DQ1 + CSR_WRITE(rAMP_DQWRLVLSDLLCODE(byte, ch), dqwrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_set_wrlvlmax_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t dqwrlvl_code = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvl_code = (dqwrlvl_code & WRLVLMAX_SDLLCODE_MASK) | (offset << WRLVLMAX_SDLLCODE_OFFSET); + + // Byte 0 corresponds to DQ0, Byte 1 corresponds to DQ1 + CSR_WRITE(rAMP_DQWRLVLSDLLCODE(byte, ch), dqwrlvl_code | (1 << RUNWRLVL_SDLLUPDOVR)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & (1 << RUNWRLVL_SDLLUPDOVR)); +} + +// Must ensure that WrLvL SDLLs are stepped by 1 to their final value to avoid glitch on clock signals +_ROMCODE_SEGMENT_PREFIX void amp_program_cawrlvl_sdll(uint32_t ch, uint32_t cawrlvl_offset, uint32_t cawrlvlmax_offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t cawrlvl_code = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + //shim_printf("DEBUG - amp_program_cawrlvl_sdll:: cawrlvl_code=0x%x, cawrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK=0x%x , cawrlvl_offset = 0x%x, cawrlvlmax_offset=0x%x \n", cawrlvl_code, cawrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK, cawrlvl_offset, cawrlvlmax_offset); + cawrlvl_code = (cawrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK) | (cawrlvl_offset << WRLVL_SDLLCODE_OFFSET) | (cawrlvlmax_offset << WRLVLMAX_SDLLCODE_OFFSET); + + //shim_printf("DEBUG - amp_program_cawrlvl_sdll:: cawrlvl_code = 0x%x \n", cawrlvl_code); + + CSR_WRITE(rAMP_CAWRLVLSDLLCODE(ch), cawrlvl_code | (1 << RUNWRLVL_SDLLUPDWRRES)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)) & (1 << RUNWRLVL_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_program_dqwrlvl_sdll(uint32_t ch, uint32_t byte, uint32_t dqwrlvl_offset, uint32_t dqwrlvlmax_offset) +{ + // Maui changes + // 1. No need to increment CA Wrlvl SDLL once step at a step. + // 2. No delay select programming is required + // 3. No need to force CKE to low. + uint32_t dqwrlvl_code = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvl_code = (dqwrlvl_code & WRLVL_SDLLCODE_MASK & WRLVLMAX_SDLLCODE_MASK) | (dqwrlvl_offset << WRLVL_SDLLCODE_OFFSET) | (dqwrlvlmax_offset << WRLVLMAX_SDLLCODE_OFFSET); + + //shim_printf("DEBUG - amp_program_dqwrlvl_sdll:: dqwrlvl_code = 0x%x \n", dqwrlvl_code); + + // Byte 0 corresponds to DQ0, Byte 1 corresponds to DQ1 + CSR_WRITE(rAMP_DQWRLVLSDLLCODE(byte, ch), dqwrlvl_code | (1 << RUNWRLVL_SDLLUPDWRRES)); + + // Poll for SDLL to get updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)) & (1 << RUNWRLVL_SDLLUPDWRRES)); +} + +_ROMCODE_SEGMENT_PREFIX void amp_run_wrlvlcal(uint32_t ch, uint32_t wrlvlrun) +{ + CSR_WRITE(rAMP_CARUNWRLVL(ch), ((wrlvlrun & 0x3) << RUNWRLVLDQ_OFFSET)); + SPIN_W_TMO_WHILE ((CSR_READ(rAMP_CARUNWRLVL(ch)) >> RUNWRLVLDQ_OFFSET) & 0x3); +} + +_ROMCODE_SEGMENT_PREFIX void cacal_init_registers() +{ + uint32_t ch; + for(ch=0;ch> CA_NUM_BITS; + //mask = patr ^ patf; + //cacal_patterns_mask[index] = mask; + cacal_patterns_mask[index] = 0x3F; + } +} + +// CP : Maui Change -> Pass an argument which tells if we are in CA or CS training. +// Use this argument to update CA or CS delay lines. +// Hardware loop for CS should always be > 1. +_ROMCODE_SEGMENT_PREFIX void cacal_run_sequence(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t mask_bits, uint32_t swloop, uint32_t vref) +{ + + uint32_t combined_mask, hwloop; + uint32_t pat_mask = 0; + + for (hwloop = 0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + pat_mask |= cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // This represents the bits that don't have a transition on any of the patterns used during the hwloop calibration + // PRBS4I pattern guarantees that there would be a 1->0 and 0->1 transition on every CA bit. Hence the combined + // mask can be set to 0x0 + combined_mask = 0; + + + // To find the FAIL <-> PASS <-> FAIL window + cacal_find_right_failing_point(ch, rnk, training_mode, combined_mask, swloop, vref); + cacal_find_left_failing_point(ch, rnk, training_mode, combined_mask, swloop, vref); +} + +// Establish the right edge of the window by finding the point where all CA bits fail +_ROMCODE_SEGMENT_PREFIX void cacal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + bool all_bits_fail = false; + uint32_t cacalresult = CA_ALL_BITS; + + // With an SDLL code of '0', CA is centered wrt CK. So to get to the right failing point, push CK by 180 degrees + // Increment CKSDLL & CSSDLL by 2*MDLL. In CA training, initial values of CKSDLL & CSSDLL would be the final CS center point values. + uint32_t push_ck_out = 2 * mdllcode[ch][AMP_CA] + cksdll_cscal[vref]; + uint32_t push_cs_out = 2 * mdllcode[ch][AMP_CA] + cssdll_cscal[vref]; + uint32_t push_ca_out = 2 * mdllcode[ch][AMP_CA] + casdll_cscal[vref]; + + uint32_t max_caright_point_val; + uint32_t max_caright_point_reached; + uint32_t step_size = COARSE_STEP_SZ; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + max_caright_point_val = (3 * mdllcode[ch][AMP_CA]) + 1; + max_caright_point_reached = 0; + + // If we skip CS training, clear CS & CA deskew registers during CA training + if(training_mode == CS_TRAINING) { + amp_init_ca_deskew(ch); + } + + // Increase delay to the right until all bits fail + do { + // Update CK signal delay + //shim_printf("DEBUG - cacal_find_right_failing_point:: Programming a value of 0x%x into CKSDLL \n",push_ck_out); + amp_push_cksdll_out(ch, push_ck_out); + + // CS training would align CK and CS correctly. To maintain that alignment, CK and CS should be delayed by the same amount + // during CA training + if(training_mode == CA_TRAINING) { + //shim_printf("DEBUG - cacal_find_right_failing_point:: Programming a value of 0x%x into CSSDLL \n",push_cs_out); + amp_push_cssdll_out(ch, push_cs_out); + } + // Maintain CK and CA alignment during fine tuned CS training. + else if(training_mode == CS_FINE_TRAINING) { + //shim_printf("DEBUG - cacal_find_right_failing_point:: Programming a value of 0x%x into CASDLL \n",push_ca_out); + amp_push_casdll_out(ch, push_ca_out); + } + + cacalresult = cacalresult & amp_run_cacal(ch, training_mode); + //shim_printf("DEBUG - cacal_find_right_failing_point:: CA cal result is 0x%x \n",cacalresult); + + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = false; + + // If the next increment of tap value is over the maximum allowed tap value, switch + // from coarse stepping to fine stepping. + if(((push_ck_out + step_size) > max_caright_point_val) || ((push_cs_out + step_size) > max_caright_point_val) || ((push_ca_out + step_size) > max_caright_point_val)) { + step_size = FINER_STEP_SZ; + } + + push_ck_out = push_ck_out + step_size; + if(training_mode == CA_TRAINING) { + push_cs_out = push_cs_out + step_size; + } + else if(training_mode == CS_FINE_TRAINING) { + push_ca_out = push_ca_out + step_size; + } + + } else { + all_bits_fail = true; + //shim_printf("DEBUG - cacal_find_right_failing_point:: All bits failed. Moved on to cacal_find_right_passing_point \n"); + + // Do a per bit calculation of when they start passing again + cacal_find_right_passing_point(ch, rnk, training_mode, combined_mask, swloop, vref); + break; + } + + max_caright_point_reached = (training_mode == CA_TRAINING) ? ((push_ck_out > max_caright_point_val) || (push_cs_out > max_caright_point_val)) + : (training_mode == CS_FINE_TRAINING) ? ((push_ck_out > max_caright_point_val) || (push_ca_out > max_caright_point_val)) : (push_ck_out > max_caright_point_val); + } while (max_caright_point_reached == 0); + + if (all_bits_fail == false) { + //shim_panic("Memory CA calibration: Unable to find right side failing point for channel %d\n", ch); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: Unable to find right side failing point for channel %d\n", ch); + cacal_vref_panic[ch][vref] = 1; + } + + // Ok from Rakesh to set to cksdll_cscal directly instead of decrementing by 1 + amp_push_cksdll_out(ch, cksdll_cscal[vref]); + + if(training_mode == CA_TRAINING) { + amp_push_cssdll_out(ch, cssdll_cscal[vref]); + } + else if(training_mode == CS_FINE_TRAINING) { + amp_push_casdll_out(ch, casdll_cscal[vref]); + } +} + +// Finds the passing region on the right edge of window +_ROMCODE_SEGMENT_PREFIX void cacal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + bool switch_from_cktoca; + uint32_t tap_value, tap_value_cs, tap_value_ca; + uint32_t cacalresult; + uint32_t saved_val; + uint32_t all_bits_pass; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + uint32_t bit_indx; + uint32_t ckdeskew, cksdll, cssdll, csdeskew, casdll; + uint32_t loopchrnk_indx; + //uint32_t casdllcode_casdllovrval; + + all_bits_pass = 0; + ckdeskew = CSR_READ(rAMP_CKDESKEW_CTRL(ch)); + csdeskew = CSR_READ(rAMP_CSDESKEW_CTRL(ch)); + cksdll = ((CSR_READ(rAMP_CKSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + cssdll = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + casdll = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + // For every swloop, we'll save passing values for each channel & rank + loopchrnk_indx = loopchrnk_index_calc(ch, rnk, swloop); + + // CP : Maui Change + // CK SDLL will always be > 0. Also, given the range of CK SDLL, i assume that we never had to + // increment CK Deskew to find the right side failing point. + tap_value = cksdll; + tap_value_cs = cssdll; + tap_value_ca = casdll; + switch_from_cktoca = false; + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those done + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + // Finding Right side passing point on per bit level. Moving Right to Left to find point where it turns from FAIL TO PASS + do { + if (switch_from_cktoca == false) { + + // Update CK signal delays + //shim_printf("DEBUG - cacal_find_right_passing_point:: Programming a value of 0x%x into CKSDLL \n",tap_value); + amp_push_cksdll_out(ch, tap_value); + + // CS training would align CK and CS correctly. To maintain that alignment, CK and CS should be delayed by the same amount + // during CA training + if(training_mode == CA_TRAINING) { + amp_push_cssdll_out(ch, tap_value_cs); + } + else if(training_mode == CS_FINE_TRAINING) { + amp_push_casdll_out(ch, tap_value_ca); + } + } else { + if(training_mode == CA_TRAINING) { + amp_push_casdll_out(ch, tap_value); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + amp_push_cssdll_out(ch, tap_value); + } + } + + // Run the ca/cs calibration in hw + cacalresult = amp_run_cacal(ch, training_mode); + + //shim_printf("DEBUG - cacal_find_right_passing_point:: CA cal result is 0x%x \n",cacalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + // For bits that are not masked, need to check pass/fail + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // Bit has passed for SOLID_PASS_DETECT number of times, consider it done. + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // This is the first time this bit has passed, save this point in the array + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + saved_val = tap_value; + if (switch_from_cktoca == false) { + if(training_mode == CA_TRAINING) { + cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx] = saved_val; + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CA right passing point for vref=%d, loopchrnk_indx=%d, bit_indx=%d, saved_val = %d \n",vref,loopchrnk_indx,bit_indx,cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx]); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Subtract cssdll to take into account the case where CS sdll is non-zero, before starting CS calibration. + cscal_per_loopchrnk_right[loopchrnk_indx] = saved_val - cssdll; + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CS right passing point for loopchrnk_indx=%d, saved_val = %d \n",loopchrnk_indx,cscal_per_loopchrnk_right[loopchrnk_indx]); + } + } else { + if(training_mode == CA_TRAINING) { + cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx] = -1 * saved_val; + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CA right passing point for vref=%d, loopchrnk_indx=%d, bit_indx=%d, saved_val = %d \n",vref,loopchrnk_indx,bit_indx,cacal_per_loopchrnk_right[loopchrnk_indx][vref][bit_indx]); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Subtract cksdll to take into account the case where CK sdll is non-zero, before starting CS calibration. + cscal_per_loopchrnk_right[loopchrnk_indx] = -1 * (saved_val - cksdll_cscal[vref]); + //shim_printf("DEBUG - cacal_find_right_passing_point:: Found CS right passing point for loopchrnk_indx=%d, saved_val = %d \n",loopchrnk_indx,cscal_per_loopchrnk_right[loopchrnk_indx]); + } + } + } + } else { + // Bit failed to pass calibration, reset the SolidBitPass value to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // If ALL bits are not passing - keep moving ca/cs signals from Right to Left + if (all_bits_pass == 0) { + // CP : Maui Change + if ((tap_value == cksdll_cscal[vref]) && (switch_from_cktoca == false)) { + switch_from_cktoca = true; + + // Make tap_value '0' just in case cksdll_cscal > 0 + tap_value = 0; + } + + if (switch_from_cktoca == false) { + tap_value = tap_value - FINER_STEP_SZ; + if(training_mode == CA_TRAINING) { + tap_value_cs = tap_value_cs - FINER_STEP_SZ; + } + else if(training_mode == CS_FINE_TRAINING) { + tap_value_ca = tap_value_ca - FINER_STEP_SZ; + } + + } else { + tap_value = tap_value + FINER_STEP_SZ; + } + } + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + } while ((tap_value <= (3 * mdllcode[ch][AMP_CA] + 1)) && (all_bits_pass == 0)); + + if (all_bits_pass == 0) { + //shim_panic("Memory CA calibration: Unable to find passing point for all bits on the right side \n"); + shim_printf("PANIC during Vref scan.Record and move forward:Memory CA calibration: Unable to find passing point for all bits on the right side \n"); + cacal_vref_panic[ch][vref] = 1; + } +} + +_ROMCODE_SEGMENT_PREFIX void cacal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + // At this point, we've already played with all possible CK delays. At the end of cacal_find_right_failing_point routine, + // we reset the CK delays to 0. + // Loop through CaSDLLOvrVal from -MasterDLL to +Max until all failing points on the left side are found + + uint32_t all_bits_fail; + uint32_t push_ca_out; + uint32_t push_cs_out; + uint32_t cacalresult; + uint32_t max_caleft_point_reached; + uint32_t max_casdll_reached; + uint32_t max_caleft_point_val; + uint32_t casdllcode, ca0deskewctrl; + uint32_t cssdllcode, csdeskewctrl; + uint32_t step_size = COARSE_STEP_SZ; + + all_bits_fail = 0; + cacalresult = CA_ALL_BITS; + max_caleft_point_reached = 0; + max_casdll_reached = 0; + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + max_caleft_point_val = (3 * mdllcode[ch][AMP_CA] + 1); + + casdllcode = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + ca0deskewctrl = CSR_READ(rAMP_CADESKEW_CTRL(ch, 0)); + + cssdllcode = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + csdeskewctrl = CSR_READ(rAMP_CSDESKEW_CTRL(ch)); + + push_ca_out = casdllcode + ca0deskewctrl; + push_cs_out = cssdllcode + csdeskewctrl; + + // Increment CaSDLL/CsSDLL from 0 to max_caleft_point_reached + do { + + if(training_mode == CA_TRAINING) { + // Push out this new ca offset + //shim_printf("DEBUG - cacal_find_left_failing_point:: Pushing out CASDLL by 0x%x taps \n",push_ca_out); + // Push out this new ca offset + amp_push_casdll_out(ch, push_ca_out); + } + if((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Push out this new cs offset + //shim_printf("DEBUG - cacal_find_left_failing_point:: Pushing out CSSDLL by 0x%x taps \n",push_cs_out); + amp_push_cssdll_out(ch, push_cs_out); + } + + // Run the CA/CS calibration + cacalresult = amp_run_cacal(ch, training_mode); + + //shim_printf("DEBUG - cacal_find_left_failing_point:: CA cal result is 0x%x \n",cacalresult); + + // combined mask has don't care bits (based on pattern) and masked bits (based on MR41 or MR48) that we should ignore + if ((cacalresult & (CA_ALL_BITS ^ combined_mask)) != 0) { + all_bits_fail = 0; + } else { + all_bits_fail = 1; + + // Now, we have found the left edge of window. Find the passing point for all bits + cacal_find_left_passing_point(ch, rnk, training_mode, combined_mask, swloop, vref); + break; + } + + if (all_bits_fail == 0) { + if(training_mode == CA_TRAINING) { + + // If the next increment of tap value is over the maximum allowed tap value, switch + // from coarse stepping to fine stepping. + if(push_ca_out + step_size > max_caleft_point_val) { + step_size = FINER_STEP_SZ; + } + + push_ca_out = push_ca_out + step_size; + + if ((push_ca_out > max_caleft_point_val) && (all_bits_fail == 0)) { + //shim_panic("Memory CA calibration: Unable to find failing point for all bits on the left side"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: Unable to find failing point for all bits on the left side"); + cacal_vref_panic[ch][vref] = 1; + } + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + if(push_cs_out + step_size > max_caleft_point_val) { + step_size = FINER_STEP_SZ; + } + + push_cs_out = push_cs_out + step_size; + + if ((push_cs_out > max_caleft_point_val) && (all_bits_fail == 0)) { + //shim_panic("Memory CS calibration: Unable to find failing point for all bits on the left side"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CS calibration: Unable to find failing point for all bits on the left side"); + cacal_vref_panic[ch][vref] = 1; + } + } + } + if(training_mode == CA_TRAINING) { + if (push_ca_out > max_caleft_point_val) { + max_caleft_point_reached = 1; + } + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + if (push_cs_out > max_caleft_point_val) { + max_caleft_point_reached = 1; + } + } + + // Panic if there are no more sdll taps left to proceed ahead + if (max_caleft_point_reached && (all_bits_fail == 0)) + { + //shim_panic("Memory CA calibration: SDLL ran out of taps when trying to find left side failing point\n"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: SDLL ran out of taps when trying to find left side failing point\n"); + cacal_vref_panic[ch][vref] = 1; + + } + } while ((all_bits_fail == 0) && (max_caleft_point_reached == 0)); +} + +_ROMCODE_SEGMENT_PREFIX void cacal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t training_mode, uint32_t combined_mask, uint32_t swloop, uint32_t vref) +{ + uint32_t loopchrnk_indx; + uint32_t BitPass[CA_NUM_BITS] = { 0 }; + uint32_t SolidBitPass[CA_NUM_BITS] = { 0 }; + uint32_t tap_value; + uint32_t cacalresult; + uint32_t camdllcode; + uint32_t casdllcode; + uint32_t ca0deskewctrl; + uint32_t cssdllcode; + uint32_t csdeskew; + uint32_t saved_val; + uint32_t all_bits_pass; + uint32_t bit_indx; + + loopchrnk_indx = loopchrnk_index_calc(ch, rnk, swloop); + + casdllcode = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + ca0deskewctrl = CSR_READ(rAMP_CADESKEW_CTRL(ch, 0)); + camdllcode = mdllcode[ch][AMP_CA]; + csdeskew = CSR_READ(rAMP_CSDESKEW_CTRL(ch)); + cssdllcode = ((CSR_READ(rAMP_CSSDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + + all_bits_pass = 0; + + // CP : Maui Change + if(training_mode == CA_TRAINING) { + tap_value = casdllcode; + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + tap_value = cssdllcode; + } + + // combined_mask contains don't care bits (due to pattern) or masked bits (MR41 or MR48), so consider those passed + for (bit_indx = 0; bit_indx < CA_NUM_BITS; bit_indx++) + if ((combined_mask & (1 << bit_indx)) != 0) + BitPass[bit_indx] = 1; + + + // Finding Left side passing point on per bit level. Move Left to Right to find point where it turns from FAIL TO PASS + do { + // Push out this new CA/CS offset + if(training_mode == CA_TRAINING) { + // Push out this new ca offset + amp_push_casdll_out(ch, tap_value); + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Push out this new cs offset + //shim_printf("DEBUG - cacal_find_left_passing_point:: Pushing out CSSDLL by 0x%x taps \n",tap_value); + amp_push_cssdll_out(ch, tap_value); + } + + // Run the CA/CS calibration + cacalresult = amp_run_cacal(ch, training_mode); + + //shim_printf("DEBUG - cacal_find_left_passing_point:: CA cal result is 0x%x \n",cacalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on CaCalresult Register + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + // check pass/fail for bits not masked + if ((combined_mask & (1 << bit_indx)) == 0) { + if ((BitPass[bit_indx] == 0) && ((cacalresult & (1 << bit_indx)) != 0)) { + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + // bit has passed SOLID_PASS_DETECT straight times, consider it done + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // first time bit has passed, record this value + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + saved_val = tap_value; + if(training_mode == CA_TRAINING) { + // Effective CA tap value would be saved_val - (CK SDLL value after CS calibration). + cacal_per_loopchrnk_left[loopchrnk_indx][vref][bit_indx] = -1 * (saved_val - cksdll_cscal[vref]) ; + //shim_printf("DEBUG - cacal_find_left_passing_point:: Found CA left passing point for vref=%d, loopchrnk_indx=%d, bit_indx=%d, saved_val = %d \n",vref,loopchrnk_indx,bit_indx,cacal_per_loopchrnk_left[loopchrnk_indx][vref][bit_indx]); + } + if ((training_mode == CS_TRAINING) || (training_mode == CS_FINE_TRAINING)) { + // Effective CS tap value would be saved_val - (CK SDLL value after CS calibration). + cscal_per_loopchrnk_left[loopchrnk_indx] = -1 * (saved_val - cksdll_cscal[vref]); + //shim_printf("DEBUG - cacal_find_left_passing_point:: Found CS left passing point for loopchrnk_indx=%d, saved_val = %d \n",loopchrnk_indx,cscal_per_loopchrnk_left[loopchrnk_indx]); + } + } + } else { + // bit failed calibration, reset the SolidBitPass value back to 0 + SolidBitPass[bit_indx] = 0; + } + } + } + + all_bits_pass = 1; + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + if (all_bits_pass == 0) + break; + } + + // TODO TODO: Make (tap_value < FINER_STEP_SZ) change at other places too + if ((tap_value < FINER_STEP_SZ) && (all_bits_pass == 0)) { + // print error message as Left Passing Point cannot be found + //shim_panic("Memory CA calibration: Unable to find passing point for all bits on the left side \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA calibration: Unable to find passing point for all bits on the left side \n"); + cacal_vref_panic[ch][vref] = 1; + break; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window + if (all_bits_pass == 0) { + tap_value -= FINER_STEP_SZ; + } + + // For Max skew slow corner, SDLL may have to go upto 3*MDLL+1. + } while ((tap_value <= (3 * mdllcode[ch][AMP_CA] + 1)) && (all_bits_pass == 0)); +} + +_ROMCODE_SEGMENT_PREFIX void cacal_program_final_values(void) +{ + uint32_t ch; + uint32_t bit_indx; + int32_t arr_CaBitCenterPoint[CA_NUM_BITS]; + //uint32_t arr_CaBitDeSkew[CA_NUM_BITS]; + int32_t tmp_left_pos_val, tmp_right_pos_val; + int32_t left_pos_val; + int32_t right_pos_val; + uint32_t camdllcode; + int32_t max_CaBitCenterPoint_val; + int32_t ckcs_diff,cabit_deskew; + uint32_t casdllcode; + uint8_t byte; + uint32_t freqchngctl1; + + int32_t rank_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t swloop; + uint32_t loopchrnk0_indx, chrnk0_indx; + uint32_t vref_ch; +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + uint32_t vref0 = vref_opt_ca[loopchrnk000]; + + shim_printf("DEBUG - cacal_program_final_values:: Preloading non-calibrated channels with channel 0's calibration results \n"); + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + loopchrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_ca[loopchrnk0_indx] = vref0; + + //shim_printf("DEBUG - cacal_program_final_values:: loopchrnk0_indx = %d, vref_ch=%d \n", loopchrnk0_indx, vref_ch); + + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx] = cacal_per_loopchrnk_left[loopchrnk000][vref0][bit_indx]; + cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx] = cacal_per_loopchrnk_right[loopchrnk000][vref0][bit_indx]; + + //shim_printf("DEBUG - cacal_program_final_values:: cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx] = %d \n", cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx]); + //shim_printf("DEBUG - cacal_program_final_values:: cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx] = %d \n", cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx]); + } + + cksdll_cscal[vref_ch] = cksdll_cscal[vref0]; + cssdll_cscal[vref_ch] = cssdll_cscal[vref0]; + + + //shim_printf("DEBUG - cacal_program_final_values:: cksdll_cscal[vref_opt_ca[loopchrnk0_indx]] = %d, cssdll_cscal[vref_opt_ca[loopchrnk0_indx]] = %d \n", cksdll_cscal[vref_opt_ca[loopchrnk0_indx]], cssdll_cscal[vref_opt_ca[loopchrnk0_indx]] ); + + } +#endif + + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + casdllcode = ((CSR_READ(rAMP_CASDLLCTRL(ch)) >> SDLLOFFSET) & DLLVAL_BITS); + camdllcode = mdllcode[ch][AMP_CA]; + + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_ca[chrnk0_indx]; + // Calculate the Center Points for each CA bit + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + //comb_mask = 0x0; + //mask_txn_detect = 0x0; + //tmp_mask = 0x0; + + // Compute the aggr eye over multiple swloop and hwloop for all ranks + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + loopchrnk0_indx = loopchrnk_index_calc(ch, 0, swloop); + //mask = 0x0; + //for (hwloop=0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + // mask = mask | cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // An explanation of the masks is below. Note that we only recorded result for a bit from a particular iteration if the bit had a transition. + // mask: for pattern(s) sent in this swloop, indicates if the bit had a transition + // tmp_mask: aggregates mask over all loops, including current swloop + // comb_mask: aggregates mask over all loops, upto the last iteration of the swloop. After it is used to generate mask_txn_detect, it catches upto same value as tmp_mask + // mask_txn_detect: indicates the first time a bit transitioned was in this swloop + //tmp_mask = tmp_mask | mask; + //mask_txn_detect = tmp_mask ^ comb_mask; + //comb_mask = comb_mask | mask; + + /* + * Rank 0 + */ + + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[0] = cacal_per_loopchrnk_left[loopchrnk0_indx][vref_ch][bit_indx]; + tmp_left_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + //if (mask_txn_detect & (1 << bit_indx)) { + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + //} else if (mask & (1 << bit_indx)) { + // // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // // to compare with, find the value that would cover both points and put that in the array + // left_pos_val = cacal_per_chrnk_left[chrnk0_indx][bit_indx]; + // left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + //} else { + // // + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + //} + + if(swloop == 0) { + left_pos_val = tmp_left_pos_val; + cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = cacal_per_chrnk_left[chrnk0_indx][bit_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MAX_ENDPT); + cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + } + + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[0] = cacal_per_loopchrnk_right[loopchrnk0_indx][vref_ch][bit_indx]; + tmp_right_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + //if (mask_txn_detect & (1 << bit_indx)) { + // right_pos_val = tmp_right_pos_val; + // cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + //} else if (mask & (1 << bit_indx)) { + // // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // // to compare with, find the value that would cover both points and put that in the array + // right_pos_val = cacal_per_chrnk_right[chrnk0_indx][bit_indx]; + // right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MIN_ENDPT); + // cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + //} else { + // // + // right_pos_val = tmp_right_pos_val; + // cacal_per_chrnk_right[chrnk0_indx][bit_indx] = 0; + //} + + if(swloop == 0) { + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cacal_per_chrnk_right[chrnk0_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MIN_ENDPT); + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } + + } + + // At this point, the left edge and the right edge of the eye for this channel and bit are defined by left_pos_val and right_pos_val + // Find the center of the eye + arr_CaBitCenterPoint[bit_indx] = find_center_of_eye(cacal_per_chrnk_left[chrnk0_indx][bit_indx],cacal_per_chrnk_right[chrnk0_indx][bit_indx]); + } + + // Since center for each bit may be different, find the max val + // Max val will get programmed to the ckdll (if Max >=0) or to casdll (if Max <0), while the other bits will require deskew + max_CaBitCenterPoint_val = arr_CaBitCenterPoint[0]; + + for (bit_indx = 1; bit_indx < CA_NUM_BITS; bit_indx++) { + + if(arr_CaBitCenterPoint[bit_indx] > max_CaBitCenterPoint_val) { + max_CaBitCenterPoint_val = arr_CaBitCenterPoint[bit_indx]; + } + } + + /* + * Finally, program the values + * Adjust CKSDLL, CSSDLL and CASDLL such that + 1. Their relative difference is maintained + 2. None of the SDLL values are negative + */ + // Calculate our delay point for CK SDLL and CS SDLL + ckcs_diff = cksdll_cscal[vref_ch] - cssdll_cscal[vref_ch]; + + if(max_CaBitCenterPoint_val >= 0) { + if (ckcs_diff > 0) { + if(max_CaBitCenterPoint_val > ckcs_diff) { + amp_program_ck_sdll(ch, max_CaBitCenterPoint_val); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = max_CaBitCenterPoint_val; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, max_CaBitCenterPoint_val - ckcs_diff); + amp_program_ca_sdll(ch, 0); + + } + else { + amp_program_ck_sdll(ch, ckcs_diff); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = ckcs_diff; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, 0); + amp_program_ca_sdll(ch, (ckcs_diff - max_CaBitCenterPoint_val)); + } + shim_printf("DEBUG - cacal_program_final_values:: ch = %d, max_CaBitCenterPoint_val = %d \n ", ch, max_CaBitCenterPoint_val); + } + else { + amp_program_ck_sdll(ch, max_CaBitCenterPoint_val); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = max_CaBitCenterPoint_val; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, max_CaBitCenterPoint_val - ckcs_diff); + amp_program_ca_sdll(ch, 0); + shim_printf("DEBUG - cacal_program_final_values:: ch = %d, max_CaBitCenterPoint_val = %d \n ", ch, max_CaBitCenterPoint_val); + } + } + else { + if (ckcs_diff > 0) { + amp_program_ck_sdll(ch, ckcs_diff); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = ckcs_diff; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte] , 0); + } + + amp_program_cs_sdll(ch, 0); + amp_program_ca_sdll(ch, __abs(max_CaBitCenterPoint_val) + ckcs_diff); + } + else { + amp_program_ck_sdll(ch, 0); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = 0; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, -ckcs_diff); + amp_program_ca_sdll(ch, __abs(max_CaBitCenterPoint_val)); + } + } + + // Push the remainder of the delay on CA deskew signals + // Since the max value of all bits was chosen for sdll, if the rest of the bits need more delay, compute their deskew + for (bit_indx=0; bit_indx < CA_NUM_BITS; bit_indx++) { + // We need not use __abs(max_CaBitCenterPoint_val) here + cabit_deskew = max_CaBitCenterPoint_val - arr_CaBitCenterPoint[bit_indx]; + + if(cabit_deskew < 0) { + //shim_panic("Memory CA Calibration: cabit_deskew for bit_indx:%d is negative \n", bit_indx); + shim_printf("PANIC during Vref scan. Record and move forward:Memory CA Calibration: cabit_deskew for bit_indx:%d is negative \n", bit_indx); + cacal_vref_panic[ch][vref_ch] = 1; + } + + // Program the CA Deskew values for each bit + CSR_WRITE(rAMP_CADESKEW_CTRL(ch, bit_indx), cabit_deskew | RUNDESKEWUPD); + + // Poll for Run deskew to go low. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_CADESKEW_CTRL(ch, bit_indx)) & RUNDESKEWUPD); + } + + // Set up DRAM mode register with the optimal CA Vref. + shim_mrcmd_to_ch_rnk(MR_WRITE, ch, 0, MR12, cfg_params.ca_vref_values[vref_ch]); + + // Program MCU registers for optimal CA Vref + if(cfg_params.freq_bin == 1) { + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(ch), (freqchngctl1 & 0x00C0FFFF) | (0xC << 16) | (cfg_params.ca_vref_values[vref_opt_ca[ch]] << 24)); + } + else if(cfg_params.freq_bin == 0) { + freqchngctl1 = CSR_READ(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch)); + CSR_WRITE(rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(ch), (freqchngctl1 & 0x00C0FFFF) | (0xC << 16) | (cfg_params.ca_vref_values[vref_opt_ca[ch]] << 24)); + } + } +} + +_ROMCODE_SEGMENT_PREFIX void cacal_program_cs_training_values(void) +{ + uint32_t loopchrnk0_indx, chrnk0_indx, ch; + // Center point of CS training + int32_t arr_CsBitCenterPoint; + int32_t tmp_left_pos_val, tmp_right_pos_val; + int32_t left_pos_val; + int32_t right_pos_val; + uint8_t byte; + + int32_t rank_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t swloop; + + #ifdef ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + + cscal_per_loopchrnk_left[chrnk0_indx] = cscal_per_loopchrnk_left[loopchrnk000]; + cscal_per_loopchrnk_right[chrnk0_indx] = cscal_per_loopchrnk_right[loopchrnk000]; + + //shim_printf("DEBUG - cscal_program_final_values:: cscal_per_loopchrnk_left[%d] = %d , cscal_per_loopchrnk_right[%d] = %d \n", loopchrnk0_indx, cscal_per_loopchrnk_left[loopchrnk0_indx], loopchrnk0_indx, cscal_per_loopchrnk_right[loopchrnk0_indx]); + + } + #endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + // Calculate the Center Points for CK bit + //comb_mask = 0x0; + //mask_txn_detect = 0x0; + //tmp_mask = 0x0; + + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + // Compute the aggr eye over multiple swloop and hwloop for all ranks + for (swloop = 0; swloop < cfg_params.cacalib_sw_loops; swloop++) { + loopchrnk0_indx = loopchrnk_index_calc(ch, 0, swloop); + //mask = 0x0; + //for (hwloop=0; hwloop < cfg_params.cacalib_hw_loops; hwloop++) + // mask = mask | cacal_patterns_mask[(swloop * cfg_params.cacalib_hw_loops) + hwloop]; + + // An explanation of the masks is below. Note that we only recorded result for a bit from a particular iteration if the bit had a transition. + // mask: for pattern(s) sent in this swloop, indicates if the bit had a transition + // tmp_mask: aggregates mask over all loops, including current swloop + // comb_mask: aggregates mask over all loops, upto the last iteration of the swloop. After it is used to generate mask_txn_detect, it catches upto same value as tmp_mask + // mask_txn_detect: indicates the first time a bit transitioned was in this swloop + //tmp_mask = tmp_mask | mask; + //mask_txn_detect = tmp_mask ^ comb_mask; + //comb_mask = comb_mask | mask; + + /* + * Rank 0 + */ + + /* Left side */ + + // lookup the value in the left side for this bit given loop, ch, and rnk + rank_val[0] = cscal_per_loopchrnk_left[loopchrnk0_indx]; + tmp_left_pos_val = rank_val[0]; + + // If this is the first time this bit transitioned, just put it in the aggregate result array + // if (mask_txn_detect & (1 << bit_indx)) { + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + // } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + // left_pos_val = cacal_per_chrnk_left[chrnk0_indx][bit_indx]; + // left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MIN_ENDPT); + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + // } else { + // // + // left_pos_val = tmp_left_pos_val; + // cacal_per_chrnk_left[chrnk0_indx][bit_indx] = left_pos_val; + // } + + if(swloop == 0) { + left_pos_val = tmp_left_pos_val; + cscal_per_chrnk_left[chrnk0_indx] = left_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + left_pos_val = cscal_per_chrnk_left[chrnk0_indx]; + left_pos_val = find_common_endpoint(tmp_left_pos_val, left_pos_val, MAX_ENDPT); + cscal_per_chrnk_left[chrnk0_indx] = left_pos_val; + } + + + /* Right side */ + + // lookup the value in the right side for this bit given loop, ch, and rnk + rank_val[0] = cscal_per_loopchrnk_right[loopchrnk0_indx]; + tmp_right_pos_val = rank_val[0]; + + /* // If this is the first time this bit transitioned, just put it in the aggregate result array + if (mask_txn_detect & (1 << bit_indx)) { + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else if (mask & (1 << bit_indx)) { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cacal_per_chrnk_right[chrnk0_indx][bit_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MAX_ENDPT); + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = right_pos_val; + } else { + // + right_pos_val = tmp_right_pos_val; + cacal_per_chrnk_right[chrnk0_indx][bit_indx] = 0; + } + */ + + if(swloop == 0) { + right_pos_val = tmp_right_pos_val; + cscal_per_chrnk_right[chrnk0_indx] = right_pos_val; + } else { + // This is not the 1st time this bit transitioned so there is a recorded result already, but since we have a new result + // to compare with, find the value that would cover both points and put that in the array + right_pos_val = cscal_per_chrnk_right[chrnk0_indx]; + right_pos_val = find_common_endpoint(tmp_right_pos_val, right_pos_val, MIN_ENDPT); + cscal_per_chrnk_right[chrnk0_indx] = right_pos_val; + } + + } + // At this point, the left edge and the right edge of the eye for this channel and bit are defined by left_pos_val and right_pos_val + // Find the center of the eye + arr_CsBitCenterPoint = find_center_of_eye(cscal_per_chrnk_left[chrnk0_indx], cscal_per_chrnk_right[chrnk0_indx]); + + /* + * Finally, program the values + * If the center point is positive, put the magnitude on CKSDLL. + * If the center point is negative, put the magnitude on CSSDLL. + */ + if(arr_CsBitCenterPoint >= 0) { + // Program the CK SDLL with the center point value + amp_program_ck_sdll(ch, arr_CsBitCenterPoint); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = arr_CsBitCenterPoint; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + amp_program_cs_sdll(ch, 0); + } else { + // Program the CS SDLL with the center point value + amp_program_cs_sdll(ch, __abs(arr_CsBitCenterPoint)); + amp_program_ck_sdll(ch, 0); + + // Since CK SDLL is moved, also program DQS WRLVL SDLL here + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvl_sdll_before_wrlvl[ch][byte] = 0; + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_before_wrlvl[ch][byte], 0); + } + + } + } +} + +// Loop through PerBitDeskewCode ranges for rddq until failing points for each byte (& bit) are found. +// Maui Change: Right failing to left failing. +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_left_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal) +{ + uint32_t dq_deskew; + uint32_t all_bits_fail; + uint32_t bits_fail_b[DQ_NUM_BYTES] = { 0 }; + // CP : Maui Change + uint32_t rddqcalresult, result_swiz; + uint32_t mask_b[DQ_NUM_BYTES]; + uint32_t start_b[DQ_NUM_BYTES]; + uint32_t byte, bit;//, dqbyte; + uint32_t step_size = COARSE_STEP_SZ; + + all_bits_fail = 0; + dq_deskew = 0; + + // set the rddq sdll to 0. + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // CP : Maui Change + amp_set_rddq_sdll(ch, byte, 0); + + // initialize the mask for each byte lane (Including DMI) + mask_b[byte] = (0xFF << (byte * 8)) | (0x1 << (byte + 16)); + } + + rddqcalresult = 0x3FFFF; + + // PerBit Deskew lines cannot be pushed beyond DQ_MAX_DESKEW_PER_BIT value + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (bits_fail_b[byte] == 0) { + + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit), dq_deskew | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit)) & RUNDESKEWUPD); + } + + // Also move DMI for the byte here + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), dq_deskew | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + } + } + + amp_run_rddqcal(ch); + //shim_printf("DEBUG - rddqcal_find_left_failing_point:: Running RDDQ cal with DQ deskew=0x%x \n",dq_deskew); + + rddqcalresult = (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + + //shim_printf("DEBUG - rddqcal_find_left_failing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + result_swiz = rddqcalresult; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if all bits haven't failed yet and this run shows all bits failing, we have found the failing point for this byte + if ((bits_fail_b[byte] == 0) && ((result_swiz & mask_b[byte]) == 0)) { + bits_fail_b[byte] = 1; + start_b[byte] = dq_deskew; + } + } + + // FIMXE + all_bits_fail = bits_fail_b[0]; + for (byte = 1; byte < DQ_NUM_BYTES; byte++) { + all_bits_fail &= bits_fail_b[byte]; + } + + if (all_bits_fail == 1) { + // If failing point has been found for all bits, find the passing point now + // CP : Maui Change + rddqcal_find_left_passing_point(ch, rnk, vref, start_b, after_wrddqcal); + break; + } else { + // To find right failing point, make more negative adjustment to the sdll (same as incrementing deskew) + + // If the next increment of tap value is over the maximum allowed tap value, switch + // from coarse stepping to fine stepping. + if((dq_deskew + step_size) > DQ_MAX_DESKEW_PER_BIT) { + step_size = FINER_STEP_SZ; + } + + dq_deskew = dq_deskew + step_size; + } + + } while ((dq_deskew <= DQ_MAX_DESKEW_PER_BIT) && (all_bits_fail == 0)); + + if (all_bits_fail == 0) { + // print error message as Left Failing Point cannot be found + //shim_panic("Memory Rddq cal: Left side failing point not found, max deskew limit reach for channel %d", ch); + shim_printf("PANIC during Vref scan. Record and move forward:Memory Rddq cal: Left side failing point not found, max deskew limit reach for channel %d", ch); + rddqcal_vref_panic[ch][vref] = 1; + } + + // Reset deskew for all bits to 0 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit), 0 | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit)) & RUNDESKEWUPD); + } + + // Also reset DMI deskew + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), 0 | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + } +} + +// Purpose of this function is to start from left side failing point and find locations for every DQ bit +// until the start of passing window for that bit is found +// Save all this locations to compute the center of window +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_left_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + uint32_t tap_value_b[DQ_NUM_BYTES]; + bool switch_from_dqtodqs, max_tap_value_reached; + uint32_t BitPass[DQ_TOTAL_BITS+DMI_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS+DMI_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + uint32_t dqmdllcode; + uint32_t saved_val; + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + all_bits_pass = 0; + switch_from_dqtodqs = false; + max_tap_value_reached = false; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Moving Right to Left to find point where each bit turns from FAIL TO PASS + do { + if (switch_from_dqtodqs == false) { + // continue to update per bit deskew until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx), tap_value_b[byte] | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + } + + // Also program DMI here + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), tap_value_b[byte] | RUNDESKEWUPD); + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + + //shim_printf("DEBUG - rddqcal_find_left_passing_point:: Pushing byte %d by a DQ deskew of 0x%x \n",byte,tap_value_b[byte]); + } + } + } else { + // adjust rddqs sdll until all bits pass for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + amp_set_rddq_sdll(ch, byte, tap_value_b[byte]); + //shim_printf("DEBUG - rddqcal_find_left_passing_point:: Pushing byte %d by DQS sdll of 0x%x \n",byte,tap_value_b[byte]); + } + } + } + + // Run rddq calibration in hw + amp_run_rddqcal(ch); + + // CP : Maui Change + rddqcalresult = (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + + //shim_printf("DEBUG - rddqcal_find_left_passing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the right edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + if (switch_from_dqtodqs == false) { + dqmdllcode = mdllcode[ch][byte+1]; + + saved_val = tap_value_b[byte]; + + // If saved_val is in terms of DQ deskew, save it as a negative number. + // If saved_val is in terms of DQS SDLL, save it as a positive number. + rddqcal_per_chrnk_left[chrnk_indx][vref][bit_indx] = -1 * saved_val; + } else { + saved_val = tap_value_b[byte]; + rddqcal_per_chrnk_left[chrnk_indx][vref][bit_indx] = saved_val; + } + shim_printf("DEBUG - rddqcal_find_left_passing_point:: Found Left edge for channel %d bit %d at tap value %d \n",chrnk_indx,bit_indx,rddqcal_per_chrnk_left[chrnk_indx][vref][bit_indx]); + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Right to Left Side of window (by adding less negative adjustment to mdll) + if (all_bits_pass == 0) { + // Even if one of the byte lanes arrives early to tap_value = 0. Remain here until all byte lane catch up before proceeding to pushing out dq + + // check for all bytes reaching 0 on the tap value (could be deskew or sdll) + uint32_t all_bytes_tap = tap_value_b[0]; + for (byte = 1; (byte < DQ_NUM_BYTES) && (all_bytes_tap == 0); byte++) { + all_bytes_tap += tap_value_b[byte]; + } + + // if the tap_value for all bytes has reached 0 on the deskew, make the transition to SDLL + if ((all_bytes_tap == 0) && (switch_from_dqtodqs == false)) { + switch_from_dqtodqs = true; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + tap_value_b[byte] = ((CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) >> SDLLOFFSET) & DLLVAL_BITS); + } + } + // CP : Maui Change + //else if (switch_from_dqtodqs == true) { + // If any of the failing bytes has reached tap_value of 0, clear sign bit for that byte lane + // for (byte = 0; byte < DQ_NUM_BYTES; byte++) + //if ((all_bits_pass_b[byte]) == 0 && (tap_value_b[byte] == 0)) + // sgn_bit_b[byte] = 0; + //} + + // To find left side passing point, add positive adjustment to mdll (same as decrementing deskew) + + // For deskew taps, we just decrement by FINER_STEP_SZ if we haven't reached 0 yet + if (switch_from_dqtodqs == false) { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (tap_value_b[byte] > 0) + tap_value_b[byte] -= FINER_STEP_SZ; + } else { + // For sdll taps, increment by FINER_STEP_SZ + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_pass_b[byte] == 0) { + //if (sgn_bit_b[byte]) { + // if (tap_value_b[byte] <= FINER_STEP_SZ) { + // tap_value_b[byte] = 0; + // sgn_bit_b[byte] = 0; + // } else + // tap_value_b[byte] -= FINER_STEP_SZ; + //} + //else + // CP : Maui Change + tap_value_b[byte] += FINER_STEP_SZ; + } + } + } + } + + // trigger for loop to end if any of the bytes reach max tap value + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) { + max_tap_value_reached = (tap_value_b[byte] > (3 * mdllcode[ch][1 + byte])); + shim_printf("DEBUG - rddqcal_find_left_passing_point:: tap_value_b[%d] = %d, mdllcode[%d][%d] = %d , max_tap_value_reached = %d \n",byte,tap_value_b[byte],ch,1 + byte,mdllcode[ch][1 + byte],max_tap_value_reached); + } + + if (max_tap_value_reached) { + if (all_bits_pass == 0) + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Unable to find left side passing point, max tap value reached"); + rddqcal_vref_panic[ch][vref] = 1; + break; + } + } + + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +// Purpose of this function is to start push DQS out till right side failing point of Data window is found +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_right_failing_point(uint32_t ch, uint32_t rnk, uint32_t vref, bool after_wrddqcal) +{ + uint32_t rddqsdll[DQ_NUM_BYTES]; + // CP : Maui Change + uint32_t rddqcalresult, result_swiz; + uint32_t all_bits_fail; + uint32_t all_bits_fail_b[DQ_NUM_BYTES] = { 0 }; + uint32_t mask_b[DQ_NUM_BYTES]; + uint32_t start_b[DQ_NUM_BYTES]; + uint32_t byte; + bool max_tap_value_reached = false; + uint32_t step_size = COARSE_STEP_SZ; + + all_bits_fail = 0; + rddqcalresult = 0x3FFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // initialize the mask for each byte lane (Including DMI) + mask_b[byte] = (0xFF << (byte * 8)) | (0x1 << (byte + 16)); + + // Get the starting values for RD DQS SDLL + rddqsdll[byte] = ((CSR_READ(rAMP_DQSDLLCTRL_RD(byte, ch)) >> SDLLOFFSET) & DLLVAL_BITS); + } + + // To find left failing point, keep adding less negative adjustment to mdll + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // set the new sdll for this byte lane if all bits are not yet failing + if (all_bits_fail_b[byte] == 0) { + amp_set_rddq_sdll(ch, byte, rddqsdll[byte]); + //shim_printf("DEBUG - rddqcal_find_right_failing_point:: Pushing byte %d by DQS sdll of 0x%x \n",byte,rddqsdll[byte]); + } + } + + // Run rddqcal in hw + amp_run_rddqcal(ch); + rddqcalresult &= (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + //shim_printf("DEBUG - rddqcal_find_right_failing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + // Account for swizzled bits and bytes of the result + // + // result_swiz = dqcal_handle_swizzle(rddqcalresult, after_wrddqcal); + result_swiz = rddqcalresult; + + + // If the result of all bits in this byte show a fail, record this as the failing point + all_bits_fail = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((all_bits_fail_b[byte] == 0) && ((result_swiz & mask_b[byte]) == 0)) { + all_bits_fail_b[byte] = 1; + start_b[byte] = rddqsdll[byte]; + } + + all_bits_fail &= all_bits_fail_b[byte]; + } + + // all bytes fail, call the function to find right passing point + if (all_bits_fail == 1) { + rddqcal_find_right_passing_point(ch, rnk, vref, start_b, after_wrddqcal); + } else { + // if the byte has not yet failed, find the next sdll value to be set + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (all_bits_fail_b[byte] == 0) { + if((rddqsdll[byte] + step_size) > (3 * mdllcode[ch][1 + byte])) { + step_size = FINER_STEP_SZ; + } + + rddqsdll[byte] += step_size; + } + } + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // none of the previous bytes reached max_tap_value, then update the boolean + if (!max_tap_value_reached) + max_tap_value_reached = (rddqsdll[byte] > (3 * mdllcode[ch][1 + byte])); + + if (max_tap_value_reached) { + if (all_bits_fail_b[byte] == 0) { + //shim_panic("Memory rddq calibration: Unable to find right failing point, max tap value reached for ch %d byte %d", ch, byte); + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Unable to find right failing point, max tap value reached for ch %d byte %d", ch, byte); + rddqcal_vref_panic[ch][vref] = 1; + } + } + } + } while ((!max_tap_value_reached) && (all_bits_fail == 0)); +} + +// Purpose of this function is to start from left side failing point and find passing locations for every DQ bit on left side of window +// Save all the locations to compute the center of window later +// To find left passing point, move to the right from the failing point, which means keep adding more negative adjustment to mdll +_ROMCODE_SEGMENT_PREFIX void rddqcal_find_right_passing_point(uint32_t ch, uint32_t rnk, uint32_t vref, uint32_t *start_b, bool after_wrddqcal) +{ + uint32_t chrnk_indx; + bool max_tap_value_reached = false; + uint32_t tap_value_b[DQ_NUM_BYTES]; + uint32_t BitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint32_t SolidBitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint32_t rddqcalresult; + uint32_t all_bits_pass; + uint32_t all_bits_pass_b[DQ_NUM_BYTES] = { 0 }; + uint32_t bit_indx, byte; + uint32_t saved_val; + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + all_bits_pass = 0; + rddqcalresult = 0x3FFFF; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + tap_value_b[byte] = start_b[byte]; + } + + // Finding Left side passing point on per bit level. Moving Left to Right (keep adding more negative adj to mdll) to find point where it turns from FAIL TO PASS + do { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if we haven't found all bits passing for this byte, push out new sdll value + if (all_bits_pass_b[byte] == 0) { + amp_set_rddq_sdll(ch, byte, tap_value_b[byte]); + //shim_printf("DEBUG - rddqcal_find_right_passing_point:: Pushing byte %d by DQS sdll of 0x%x \n",byte,tap_value_b[byte]); + } + } + + // Run rddqcal in hw + amp_run_rddqcal(ch); + rddqcalresult = (CSR_READ(rAMP_DQCALRESULT(ch)) & 0x3FFFF); + //shim_printf("DEBUG - rddqcal_find_right_passing_point:: RDDQ cal result=0x%x \n",rddqcalresult); + + // Make sure that each Bit sees a transition from 0 to 1 on DqCalresult Register + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + // Check if this bit passed during the calibration (not necessarily for first time) + if ((BitPass[bit_indx] == 0) && ((rddqcalresult & (1 << bit_indx)) != 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit_indx] == SOLID_PASS_DETECT) { + BitPass[bit_indx] = 1; + } else if (SolidBitPass[bit_indx] > 0) { + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + } else { + // bit passed for the first time, record this value in the global array as the left edge + SolidBitPass[bit_indx] = SolidBitPass[bit_indx] + 1; + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + saved_val = tap_value_b[byte]; + + rddqcal_per_chrnk_right[chrnk_indx][vref][bit_indx] = saved_val; + shim_printf("DEBUG - rddqcal_find_right_passing_point:: Found right edge for channel %d bit %d at tap value %d \n",chrnk_indx,bit_indx,rddqcal_per_chrnk_right[chrnk_indx][vref][bit_indx]); + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit_indx] = 0; + } + } + + all_bits_pass = 1; + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + all_bits_pass_b[byte] = 1; + + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // Did all the bits pass (SOLID_PASS_DETECT number of times) in this byte lane? + // If anyone of the bits failed, then the byte flag is cleared + all_bits_pass_b[byte] = all_bits_pass_b[byte] & BitPass[bit_indx]; + + // Did all bits in all byte lanes pass? + all_bits_pass = all_bits_pass & BitPass[bit_indx]; + } + + // If ALL bits are not passing - keep moving from Left to Right Side of window (by adding more negative adjustment to mdll) + if (all_bits_pass == 0) { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + // if this byte lane does not have all passing bits, adjust this byte's sdll + if (all_bits_pass_b[byte] == 0) { + // for negative value, increase the magnitude + //if (sgn_bit_b[byte] == 1) + // tap_value_b[byte] += FINER_STEP_SZ; + //else { + // if we're at 0, increase the magnitude and change sign + // if (tap_value_b[byte] == 0) { + // tap_value_b[byte] += FINER_STEP_SZ; + // sgn_bit_b[byte] = 1; + // } + // // for positive value, decrease the magnitude + // else + tap_value_b[byte] -= FINER_STEP_SZ; + } + } + } + + // check for end of loop condition + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (!max_tap_value_reached) + max_tap_value_reached = (tap_value_b[byte] > (3 * mdllcode[ch][1 + byte])); + + if (max_tap_value_reached) { + if (all_bits_pass == 0) { + //shim_panic("Memory rddq calibration: Unable to find right passing point, max tap value reached"); + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Unable to find right passing point, max tap value reached"); + rddqcal_vref_panic[ch][vref] = 1; + } + break; + } + + // panic if we get beyond -dqmdllcode, since we really shouldn't have to go that far + if ((all_bits_pass == 0) && (tap_value_b[byte] == 0)) { + //shim_panic("Memory rddq calibration: Not yet found right passing point but SDLL = 0 for ch %d byte %d", ch, byte); + shim_printf("PANIC during Vref scan. Record and move forward:Memory rddq calibration: Not yet found right passing point but SDLL = 0 for ch %d byte %d", ch, byte); + rddqcal_vref_panic[ch][vref] = 1; + } + } + } while ((!max_tap_value_reached) && (all_bits_pass == 0)); +} + +_ROMCODE_SEGMENT_PREFIX void rddqcal_program_final_values(void) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx; + int32_t arr_RdDqBitCenterPoint[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + uint32_t arr_RdDqBitDeSkew[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t max_RdDqCenterPoint_val_b[DQ_NUM_BYTES]; + uint32_t vref_ch; +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + uint32_t vref0 = vref_opt_rddq[loopchrnk000]; + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_rddq[chrnk0_indx] = vref0; + + for (bit_indx=0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + rddqcal_per_chrnk_left[chrnk0_indx][vref_ch][bit_indx] = rddqcal_per_chrnk_left[loopchrnk000][vref0][bit_indx]; + rddqcal_per_chrnk_right[chrnk0_indx][vref_ch][bit_indx] = rddqcal_per_chrnk_right[loopchrnk000][vref0][bit_indx]; + } + } + +#endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_rddq[chrnk0_indx]; + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + left_pos_val = rddqcal_per_chrnk_left[chrnk0_indx][vref_ch][bit_indx]; + right_pos_val = rddqcal_per_chrnk_right[chrnk0_indx][vref_ch][bit_indx]; + + // find center of the eye for this bit + arr_RdDqBitCenterPoint[bit_indx] = find_center_of_eye(left_pos_val, right_pos_val); + shim_printf("DEBUG - rddqcal_program_final_values:: Center value for bit %d in Channel %d = %d \n", bit_indx, ch, arr_RdDqBitCenterPoint[bit_indx]); + + } + + // initialize the max centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + max_RdDqCenterPoint_val_b[byte] = arr_RdDqBitCenterPoint[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the maximum CenterPoint per byte lane given each bit's center point + for (bit_indx=0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // REVIEW + // if this bit's center point is greater than current max, make it the new max (we'll program this to sdll, and other values will require deskew) + max_RdDqCenterPoint_val_b[byte] = find_common_endpoint(max_RdDqCenterPoint_val_b[byte], arr_RdDqBitCenterPoint[bit_indx], MAX_ENDPT); + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + shim_printf("DEBUG - rddqcal_program_final_values:: Maximum center value for byte %d = %d \n", byte, max_RdDqCenterPoint_val_b[byte]); + } + + // Compute the individual deskew values: any bits with center point < max for its byte lane will require deskew + // Each bit's center is guaranteed to be <= max for its byte lane + // Deskewing means adding more negative adjustment for this bit in addition to the sdll, which is clamped on the negative side to -dqmdllcode + for (bit_indx = 0; bit_indx < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + arr_RdDqBitDeSkew[bit_indx] = max_RdDqCenterPoint_val_b[byte] - arr_RdDqBitCenterPoint[bit_indx]; + } + + // Program the SDLL and deskew per bit for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + + // If max_RdDqCenterPoint_val_b[byte] < 0, program a value of 0 into RD DQS SDLL. + if(max_RdDqCenterPoint_val_b[byte] >= 0) { + amp_program_rddq_sdll(ch, byte, max_RdDqCenterPoint_val_b[byte]); + } + else { + amp_program_rddq_sdll(ch, byte, 0); + } + + // per bit deskew for this byte lane + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + + // If max_RdDqCenterPoint_val_b[byte] < 0, add the absolute value of max_RdDqCenterPoint_val_b[byte] to deskew on each bit. + if(max_RdDqCenterPoint_val_b[byte] < 0) { + arr_RdDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] += __abs(max_RdDqCenterPoint_val_b[byte]); + } + + CSR_WRITE(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx), arr_RdDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] | RUNDESKEWUPD); + + // Poll for Deskew code to be updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + + } + + // If max_RdDqCenterPoint_val_b[byte] < 0, add the absolute value of max_RdDqCenterPoint_val_b[byte] to deskew on each bit. + if(max_RdDqCenterPoint_val_b[byte] < 0) { + arr_RdDqBitDeSkew[DQ_TOTAL_BITS + byte] += __abs(max_RdDqCenterPoint_val_b[byte]); + } + + // Also program DMI deskew here + CSR_WRITE(rAMP_RDDMDESKEW_CTRL(byte, ch), arr_RdDqBitDeSkew[DQ_TOTAL_BITS + byte] | RUNDESKEWUPD); + + // Poll for Deskew code to be updated + SPIN_W_TMO_WHILE (CSR_READ(rAMP_RDDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + + // Also, program AMPS register for optimal RDDQ Vref + if(cfg_params.freq_bin == 1) { + amp_program_rddq_vref(ch, cfg_params.rddq_vref_values[vref_opt_rddq[ch]], 0, 1); + } else if(cfg_params.freq_bin == 0) { + amp_program_rddq_vref(ch, cfg_params.rddq_vref_values[vref_opt_rddq[ch]], 0, 0); + } + } + } // for (ch = 0; ch < cfg_params.num_channels; ch++) +} + +_ROMCODE_SEGMENT_PREFIX static uint32_t rddqcal_encode_dlyval(uint32_t ch, uint32_t phy_type, uint32_t val) +{ + uint32_t ret_val, mdll; + + mdll = mdllcode[ch][phy_type]; + + //shim_printf("DEBUG - rddqcal_encode_dlyval:: mdll=%d, phy_type = %d, val = %d \n", mdll, phy_type, val); + + if (val > ( 1.75 * mdll )) { + ret_val = 3; + } else if (val > ( 1.5 * mdll )) { + ret_val = 2; + } else if (val > ( 1.0 * mdll )) { + ret_val = 1; + } else { + ret_val = 0; + } + + return ret_val; +} + +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_push_to_0s_region(uint32_t ch, uint32_t rnk) +{ + uint32_t byte; + uint32_t cawrlvlcode = 0; + bool max_tap_value_reached = false; + uint32_t wrlvlrun = 0x3; + uint32_t wrlvlresult = 0x3; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + + // Note that incrementing cawrlvl sdll has opposite effect of incrementing dqwrlvl + + // Also program DQS SDLL to zero here. Because DQS SDLL is MDLL code at this point. + // This will make CK-DQS worst case skew as MDLL code + 200ps which cannot be calibrated. + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + // Set the DQ/DQS SDLL (RESULT) both to ZERO for this channel/byte + wrdqcal_set_delay_point_res(ch, 1 << byte, 0); + } + + for(byte = 0 ; byte < DQ_NUM_BYTES; byte++ ) { + dqwrlvlcode[byte] = dqwrlvl_sdll_before_wrlvl[ch][byte]; + } + + do { + // If any byte lane shows that it returned a value of 1 - push ca wrlvl sdll out by 1 tap + amp_set_cawrlvl_sdll(ch, cawrlvlcode); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte already showed a 0 during last run, push dqwrlvl sdll by 1 tap + // this is done to ensure this byte remains at 0 despite cawrlvl sdll being incremented above + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + + // Run Wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLRESULT register + wrlvlresult = ((CSR_READ(rAMP_CAWRLVLRESULT(ch)) >> WRLVL_RESULT) & 0x3); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if((wrlvlresult & (1 << byte)) == 0) { + wrlvlrun &= ~(1 << byte); + } + } + + //shim_printf("DEBUG - wrlvlcal_push_to_0s_region:: Write leveling result for ch=%d, with cawrlvlcode=%d is 0x%x \n",ch,cawrlvlcode, wrlvlresult); + + // Exit if ca or dq wrlvl sdlls reach max tap value + if (cawrlvlcode == MAX_CAWRLVL_CODE) { + max_tap_value_reached = true; + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: CAWRLVL sdll reached max tap value, yet all bytes not all 0s"); + } else { + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 0s", byte); + max_tap_value_reached = true; + break; + } + } + } + // Start write leveling run with CAWRLVL code of 0. + cawrlvlcode++; + } while (wrlvlrun && !max_tap_value_reached); +} + +// Keep incrementing dqsdll until the byte shows 1s again. This counters the casdll that was incremented previously in order to show 0s +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_find_0to1_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte; + uint32_t wrlvlrun; + uint32_t wrlvlresult; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + + wrlvlrun = 0x3; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dqwrlvlcode[byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + } + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + + do { + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // if this byte is still showing a 0, increment the sdll + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLRESULT register + wrlvlresult = ((CSR_READ(rAMP_CAWRLVLRESULT(ch)) >> WRLVL_RESULT) & 0x3); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if(wrlvlresult & (1 << byte)) { + wrlvlrun &= ~(1 << byte); + } + } + + //shim_printf("DEBUG - wrlvlcal_find_0to1_transition:: Write leveling result for ch=%d, with cawrlvlcode=%d, dqwrlvlcode[%d] = %d, dqwrlvlcode[%d] = %d is %d \n",ch,cawrlvlcode,0,dqwrlvlcode[0],1,dqwrlvlcode[1],wrlvlresult); + + // Exit if any of the byte lane's sdll reaches max + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (dqwrlvlcode[byte] == MAX_DQWRLVL_CODE) { + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: DQ%d sdll reached max tap value, yet all bytes not all 1s", byte); + max_tap_value_reached = true; + break; + } + } + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvlcal_per_chrnk_rise[chrnk_indx][byte] = dqwrlvlcode[byte]; + // in the "3rd byte" entry, save the cawrlvl code + wrlvlcal_per_chrnk_rise[chrnk_indx][byte] = cawrlvlcode; +} + +// Go back towards the 0s region (that was found earlier). Note: not trying to find the next edge, just the previous edge that was found already +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_find_1to0_transition(uint32_t ch, uint32_t rnk) +{ + uint32_t chrnk_indx, byte; + uint32_t wrlvlrun; + uint32_t wrlvlresult; + bool max_tap_value_reached = false; + uint32_t dqwrlvlcode[DQ_NUM_BYTES]; + uint32_t cawrlvlcode = CSR_READ(rAMP_CAWRLVLSDLLCODE(ch)); + bool incr_cawrlvl = false; + + chrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + wrlvlrun = 0x3; + + // jump ahead by SOLID_PASS_DETECT into the 1s region + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dqwrlvlcode[byte] = CSR_READ(rAMP_DQWRLVLSDLLCODE(byte, ch)); + dqwrlvlcode[byte] += (SOLID_PASS_DETECT + 1); // + 1 because code is decremented before programming the sdll + } + + do { + // Make sure dqwrlvlsdll > 0, otherwise switch to cawrlvlsdll + for (byte = 0; (byte < DQ_NUM_BYTES) && !incr_cawrlvl; byte++) { + // Move to incrementing CAWRLVL SDLL only if the DQWRLVL code for the + // byte which hasn't moved to 0's reached a zero code. + if ((dqwrlvlcode[byte] == 0) && (wrlvlrun & (1 << byte)) ) + incr_cawrlvl = true; + } + + // if we've reached 0 on any dqwrlvlsdll that were being decremented, switch to incrementing the cawrlvlsdll (same effect) + if (incr_cawrlvl) { + cawrlvlcode++; + amp_set_cawrlvl_sdll(ch, cawrlvlcode); + + // In order to keep bytes that have transitioned to 0 to stay there, increment dqwrlvlsdll (counters effect of incrementing cawrlvlsdll) + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if ((wrlvlrun & (1 << byte)) == 0) { + dqwrlvlcode[byte]++; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + } else { + // if run bit is set for this byte, push out the new sdll value after decrementing by 1 + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if (wrlvlrun & (1 << byte)) { + dqwrlvlcode[byte]--; + amp_set_dqwrlvl_sdll(ch, byte, dqwrlvlcode[byte]); + } + } + } + + // run the wrlvl calibration in hw + amp_run_wrlvlcal(ch, wrlvlrun); + + // result in reported in AMPWRLVLRESULT register + wrlvlresult = ((CSR_READ(rAMP_CAWRLVLRESULT(ch)) >> WRLVL_RESULT) & 0x3); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + if((wrlvlresult & (1 << byte)) == 0) { + wrlvlrun &= ~(1 << byte); + } + } + + //shim_printf("DEBUG - wrlvlcal_find_1to0_transition:: Write leveling result for ch=%d, with cawrlvlcode=%d, dqwrlvlcode[%d] = %d, dqwrlvlcode[%d] = %d is %d \n",ch,cawrlvlcode,0,dqwrlvlcode[0],1,dqwrlvlcode[1],wrlvlresult); + // check if we've reached max tap value + if (incr_cawrlvl && (cawrlvlcode == MAX_CAWRLVL_CODE)) { + max_tap_value_reached = true; + if (wrlvlrun) + shim_panic("Memory Wrlvl calibration: max tap value reached, yet all bytes not back to 0s"); + } + + } while (wrlvlrun && !max_tap_value_reached); + + // save the per byte codes for this channel and rank + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + wrlvlcal_per_chrnk_fall[chrnk_indx][byte] = dqwrlvlcode[byte]; + + // in the "3rd byte" entry, save the cawrlvl code + wrlvlcal_per_chrnk_fall[chrnk_indx][byte] = cawrlvlcode; +} + +_ROMCODE_SEGMENT_PREFIX void wrlvlcal_program_final_values(void) +{ + uint32_t ch, chrnk0_indx, chrnk1_indx; + uint32_t rank_rise_val[AMP_MAX_RANKS_PER_CHAN], rank_fall_val[AMP_MAX_RANKS_PER_CHAN]; + uint32_t edge_pos[AMP_MAX_RANKS_PER_CHAN]; + uint32_t common_edge_pos, min_edge_pos; + uint32_t byte; + uint32_t saved_val[DQ_NUM_BYTES + 1]; + +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + wrlvlcal_per_chrnk_rise[chrnk0_indx][byte] = wrlvlcal_per_chrnk_rise[loopchrnk000][byte]; + wrlvlcal_per_chrnk_fall[chrnk0_indx][byte] = wrlvlcal_per_chrnk_fall[loopchrnk000][byte]; + } + } +#endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + // we go upto DQ_NUM_BYTES + 1 to also take into account the cawrlvlcode that is stored in the 5th element + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + + // Rank 0 + rank_rise_val[0] = wrlvlcal_per_chrnk_rise[chrnk0_indx][byte]; + rank_fall_val[0] = wrlvlcal_per_chrnk_fall[chrnk0_indx][byte]; + // average of 2 values is the edge for this rank + edge_pos[0] = (rank_rise_val[0] + rank_fall_val[0]) >> 1; + common_edge_pos = edge_pos[0]; + + // Adjust for Dual ranks + if (cfg_params.num_ranks > 1) { + chrnk1_indx = loopchrnk_index_calc(ch, 1, 0); + rank_rise_val[1] = wrlvlcal_per_chrnk_rise[chrnk1_indx][byte]; + rank_fall_val[1] = wrlvlcal_per_chrnk_fall[chrnk1_indx][byte]; + edge_pos[1] = (rank_rise_val[1] + rank_fall_val[1]) >> 1; + + // common_edge_pos between both ranks is simply their average + common_edge_pos = (edge_pos[0] + edge_pos[1]) >> 1; + } + + // save the wrlvlsdll for each byte (and the ca) + saved_val[byte] = common_edge_pos; + } + + // Find the min among all bytes (and the ca) + min_edge_pos = saved_val[DQ_NUM_BYTES]; // initialize min as the cawrlvlsdll + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + if (saved_val[byte] < min_edge_pos) + min_edge_pos = saved_val[byte]; + + // We'll subtract the min from all 3 sdlls, including ca + // so the byte sdlls which are in opposite direction also need to be adjusted + for (byte = 0; byte < (DQ_NUM_BYTES + 1); byte++) { + saved_val[byte] -= min_edge_pos; + + // Program the values into the registers + if (byte == DQ_NUM_BYTES) { + // cawrlvl (use dlysel, which will require phyupdt and forceckelow) + // CP : + // Make sure WrLvl max field is set to zero before updating CAWRLVL SDLL code. + amp_program_cawrlvl_sdll(ch, saved_val[byte], 0); + shim_printf("wrlvlcal_program_final_values:: Saving 0x%x into CA WRLVL SDLL \n", saved_val[byte]); + } else { + // dqwrlvl (use dlysel, which will require phyupdt and forceckelow) + // CP : + // Make sure WrLvl max field is set to zero before updating CAWRLVL SDLL code. + amp_program_dqwrlvl_sdll(ch, byte, saved_val[byte], 0); + shim_printf("wrlvlcal_program_final_values:: Saving 0x%x into DQWRLVL%d SDLL\n", saved_val[byte], byte); + } + } + } +} + +/* +================================================================================ +During the search for R/L pass/fail points, I notice this about each loop: + 1) Set the HW Parameters to reflect the current search point + (This is often a combination of WrLvL, per-byte DQ/DQS SDLL) + 2) Assess the per-bit pass/fail status + 3) determine from the results of (2) whether or not we have found our desired skew + (e.g. when looking for 'pass' do all bits pass? when looking for 'fail' do all bits fail?) + 4) if not all bits have been satisfied, nudge the search point and repeat from (1) + 5) if all bits have been satisfied, + Mark (per-bit) the skew at which that bit has notably found its left- or right- window_edge + +We search in a +skew direction for the failing point (in Coarse Steps), +then search in a -skew direction from *there* for the passing point (in Fine Steps) + +…and, when the (skew < 0) we program DQS SDLL instead of DQ SDLL + (and in that case, WrLvL does not tract DQS…it only ever tracks DQ) + +…the net result is, of course, that we end up with an array of left- and right- window-edges for each bit + +The Maui twist is: we execute this process for each vref +The WRDQ speciality is: within each vref loop iteration, we will first set "n" == 0 or 1, as appropriate + +After finding all the L/R window_edges (for each vref), we can pass this info through the CoM +(Center of Mass) algorithm, as we did for CA and RDDQ, to get the optimal vref and the ideal SDLL +along with the individual bit skews. + +So…how's the summary? + +Some thoughts: +(A) I'm planning to create an encapsulated function that will program WrLvl, DQ, DQS as appropriate for a given + skew. Using this within the Loops will clean up a lot of the code in the loop. + So…..for a given skew (and an initial value of WrLvL), the function can do this: + if (skew >= 0) + WrLvL + skew --> WrLvL Reg + skew --> each Byte DQ Reg + else // (skew < 0) + abs(skew) --> each Byte DQS Reg + …making it an easy matter to call this from the various search loops + Feedback? does that feel like the right logic? + +(B) I'm still examining the "How do I know I'm done searching" logic in each loop. + I suspect I can get this into an easy-to-use encapsulated function also. +================================================================================ +*/ + +_MCODE_SEGMENT_PREFIX static uint8_t wrdqcal_chan = 0; +_MCODE_SEGMENT_PREFIX static uint8_t wrdqcal_rank = 0; +_MCODE_SEGMENT_PREFIX static uint8_t wrdqcal_vref = 0; + +// Initialize Registers for the start of WR DQ Calibration +_ROMCODE_SEGMENT_PREFIX void wrdqcal_init_regs(uint8_t chan, uint8_t rank) +{ + // Program tWL, tRL for frequency bins 0-3 --> Should be part of the init sequence + uint32_t rdwr_dqcal_loopcnt = CSR_READ(rAMP_RDWRDQCALLOOPCNT(chan)); + + wrdqcal_chan = chan; + wrdqcal_rank = rank; + + // Program SWRDDQCAL Loop count + CSR_WRITE(rAMP_RDWRDQCALLOOPCNT(chan), (rdwr_dqcal_loopcnt & 0xFFFF00FF) | ((cfg_params.wrdq_cal_loopcnt & 0xFF) << 8)); + + // Pattern and invert mask are programmed from init sequence. This includes setting Mode registers + // MR15, MR20, MR32 and MR40 + + // Program PRBS7I patterns + CSR_WRITE(rAMP_CALPATPRBS7_0(chan), cfg_params.prbs7_pattern_0); + CSR_WRITE(rAMP_CALPATPRBS7_1(chan), cfg_params.prbs7_pattern_1); + CSR_WRITE(rAMP_CALPATPRBS7_2(chan), cfg_params.prbs7_pattern_2); + CSR_WRITE(rAMP_CALPATPRBS7_3(chan), cfg_params.prbs7_pattern_3); + + // Program start points in PRBS7I patterns for all CA bits + CSR_WRITE(rAMP_WRDQCALPATSEED_B0_0(chan), (cfg_params.wrdq_prbs_seed[0][3] << 24) | (cfg_params.wrdq_prbs_seed[0][2] << 16) | (cfg_params.wrdq_prbs_seed[0][1] << 8) | (cfg_params.wrdq_prbs_seed[0][0] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B0_1(chan), (cfg_params.wrdq_prbs_seed[0][7] << 24) | (cfg_params.wrdq_prbs_seed[0][6] << 16) | (cfg_params.wrdq_prbs_seed[0][5] << 8) | (cfg_params.wrdq_prbs_seed[0][4] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B0_2(chan), (cfg_params.wrdq_prbs_seed[0][8] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B1_0(chan), (cfg_params.wrdq_prbs_seed[1][3] << 24) | (cfg_params.wrdq_prbs_seed[1][2] << 16) | (cfg_params.wrdq_prbs_seed[1][1] << 8) | (cfg_params.wrdq_prbs_seed[1][0] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B1_1(chan), (cfg_params.wrdq_prbs_seed[1][7] << 24) | (cfg_params.wrdq_prbs_seed[1][6] << 16) | (cfg_params.wrdq_prbs_seed[1][5] << 8) | (cfg_params.wrdq_prbs_seed[1][4] << 0)); + CSR_WRITE(rAMP_WRDQCALPATSEED_B1_2(chan), (cfg_params.wrdq_prbs_seed[1][8] << 0)); +} + +// 'byte' is used in a number of these functions to indicate *which* byte lane's registers are being affected. +// (byte & 0x1) indicates usage for DQ0 +// (byte & 0x2) indicates usage for DQ1 +#define byteN(_N) (0x1 << (_N)) +#define isforbyte(_N,byte) ((byte) & byteN(_N)) + +static inline _ROMCODE_SEGMENT_PREFIX uint32_t wrdqcal_bitmask(uint32_t byte) +{ + uint32_t wr_bits_pass = 0x0; + + if (isforbyte(0,byte)) wr_bits_pass |= 0x100FF; + if (isforbyte(1,byte)) wr_bits_pass |= 0x2FF00; + + return wr_bits_pass; +} + +// Write Value to 'n' To Add (or not Add) a 1/2 Clk Delay +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_half_clk_delay(uint32_t byte, uint32_t val) +{ + uint32_t wrdqsdq_sdllcode; + if (isforbyte(0, byte)) { + wrdqsdq_sdllcode = CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(0, wrdqcal_chan)); + wrdqsdq_sdllcode = (wrdqsdq_sdllcode & HALF_CLK_OVRVAL_MASK) | (val << HALF_CLK_OVRVAL_OFFSET) | (1 << RUN_SDLLUPDWRRES); + CSR_WRITE(rAMP_WRDQSDQ_SDLLCTRL(0, wrdqcal_chan), wrdqsdq_sdllcode); + while(CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(0, wrdqcal_chan)) & (1 << RUN_SDLLUPDWRRES)); + } + if (isforbyte(1, byte)) { + wrdqsdq_sdllcode = CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(1, wrdqcal_chan)); + wrdqsdq_sdllcode = (wrdqsdq_sdllcode & HALF_CLK_OVRVAL_MASK) | (val << HALF_CLK_OVRVAL_OFFSET) | (1 << RUN_SDLLUPDWRRES); + CSR_WRITE(rAMP_WRDQSDQ_SDLLCTRL(1, wrdqcal_chan), wrdqsdq_sdllcode); + while(CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(1, wrdqcal_chan)) & (1 << RUN_SDLLUPDWRRES)); + } + + return 0; +} + +// Set DQS SDLL and DQ SDLL +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_dqs_dq_sdll_type(uint32_t chan, uint32_t byte, uint32_t dq_val, uint32_t dqs_val, bool result) +{ + uint32_t wrdqsdq_sdllcode; + uint32_t shyfted_bit = 1 << (result? WR_SDLLUPDWRRES:WR_SDLLUPDOVR); + uint32_t update = (dqs_val << WR_DQS_SDLL_OFFSET) | (dq_val << WR_DQ_SDLL_OFFSET) | shyfted_bit; + + // Range Check DQ, DQS ... if outside of max range, issue a panic + if ((dqs_val > MAX_SDLL_VAL) || (dq_val > MAX_SDLL_VAL)) { + //shim_panic("Trying to set WR %s SDLL (code == %d) which is more than (max == %d)", + // (dqs_val > MAX_SDLL_VAL)? "DQS":"DQ", dq_val + dqs_val, MAX_SDLL_VAL); + shim_printf("PANIC during Vref scan. Record and move forward:Trying to set WR %s SDLL (code == %d) which is more than (max == %d)", + (dqs_val > MAX_SDLL_VAL)? "DQS":"DQ", dq_val + dqs_val, MAX_SDLL_VAL); + + wrdqcal_vref_panic[chan][wrdqcal_vref] = 1; + return -1; + } + + // First, update each byte + if (isforbyte(0, byte)) { + wrdqsdq_sdllcode = CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(0, chan)); + wrdqsdq_sdllcode &= 0x0000FFFF; + wrdqsdq_sdllcode |= update; + CSR_WRITE(rAMP_WRDQSDQ_SDLLCTRL(0, chan), wrdqsdq_sdllcode); + } + if (isforbyte(1, byte)) { + wrdqsdq_sdllcode = CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(1, chan)); + wrdqsdq_sdllcode &= 0x0000FFFF; + wrdqsdq_sdllcode |= update; + CSR_WRITE(rAMP_WRDQSDQ_SDLLCTRL(1, chan), wrdqsdq_sdllcode); + } + + // Then, poll each byte for update to finish + if (isforbyte(0, byte)) + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(0, chan)) & shyfted_bit); + if (isforbyte(1, byte)) + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(1, chan)) & shyfted_bit); + + return 0; +} + +// Set DQ/DQS SDLL (per-byte) as a RESULT (true) or OVERRIDE (false) +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_delay_point(uint32_t chan, uint32_t byte, int32_t point, bool result) +{ + uint32_t dq = 0; + uint32_t dqs = 0; + + // if point is outside of range (min,max), return error code (+/- 1) + if ((point > MAX_SDLL_VAL) || (point < -MAX_SDLL_VAL)) { + //shim_panic("Trying to set a WR DQ/DQS code which is more than maximum allowed (%d vs. [%d,%d])", + // point, -MAX_SDLL_VAL, MAX_SDLL_VAL); + shim_printf("PANIC during Vref scan. Record and move forward:Trying to set a WR DQ/DQS code which is more than maximum allowed (%d vs. [%d,%d])", + point, -MAX_SDLL_VAL, MAX_SDLL_VAL); + wrdqcal_vref_panic[chan][wrdqcal_vref] = 1; + return -1; + } + + if (point >= 0) { // (+point) --> DQ SDLL; ZERO --> DQS SDLL + dq = point; + } else { // (-point) --> DQS SDLL; ZERO --> DQ SDLL + dqs = -point; + } + + return wrdqcal_set_dqs_dq_sdll_type(chan, byte, dq, dqs, result); +} + +// Program DQ deskew code. +_ROMCODE_SEGMENT_PREFIX int wrdqcal_program_dq_deskew(uint32_t chan, uint32_t byte, uint32_t val) +{ + uint32_t bit_indx; + + if (isforbyte(0, byte)) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(0, chan, bit_indx), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + while(CSR_READ(rAMP_WRDQDESKEW_CTRL(0, chan, bit_indx)) & RUNDESKEWUPD); + } + + // Also program DMI deskew here. + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(0, chan), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + while(CSR_READ(rAMP_WRDMDESKEW_CTRL(0, chan)) & RUNDESKEWUPD); + } + if (isforbyte(1, byte)) { + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(1, chan, bit_indx), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + while(CSR_READ(rAMP_WRDQDESKEW_CTRL(1, chan, bit_indx)) & RUNDESKEWUPD); + } + + // Also program DMI deskew here. + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(1, chan), (val) | RUNDESKEWUPD); + + // Poll for deskew update to be done. + while(CSR_READ(rAMP_WRDMDESKEW_CTRL(1, chan)) & RUNDESKEWUPD); + } + + return 0; +} + +// Set DQS SDLL and DQ SDLL as OVERRIDE +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_delay_point_ovr(uint32_t chan, uint32_t byte, int32_t point) +{ + return wrdqcal_set_delay_point(chan, byte, point, false); +} + +// Set DQS SDLL and DQ SDLL as RESULT +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_delay_point_res(uint32_t chan, uint32_t byte, int32_t point) +{ + return wrdqcal_set_delay_point(chan, byte, point, true); +} + +// WrLvl value and dq_sdll (per-byte) array +_ROMCODE_SEGMENT_PREFIX int wrdqcal_set_search_point(uint32_t byte, int32_t point) +{ + uint32_t chrnk_indx; + uint32_t mdllcode_byte; + uint32_t min_of_4mdll_maxsdll; + uint32_t deskew_val; + + // if point is outside of 4*MDLL range, return error code (+/- 1) + mdllcode_byte = (isforbyte(1, byte)) ? mdllcode[wrdqcal_chan][AMP_DQ1] : mdllcode[wrdqcal_chan][AMP_DQ0]; + if ((point < 0) && (((uint32_t)__abs(point)) > (4 * mdllcode_byte) || __abs(point) > MAX_SDLL_VAL)) { + shim_printf("PANIC during Vref scan. Trying to set a WR DQS code which is more than 4*MDLL, Code=%d, Limit=%d \n", __abs(point), MAX(4 * mdllcode_byte, MAX_SDLL_VAL)); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + return -1; + } else { + if (((uint32_t)__abs(point)) > (5 * mdllcode_byte)) { + shim_printf("PANIC during Vref scan. Trying to set a WR DQ SDLL + WR DQ deskew code more than 5*MDLL (DQ deskew can hold a code of MDLL), Code=%d, Limit=%d \n", __abs(point), (5 * mdllcode_byte)); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + return -1; + } + } + + if (point >= 0) { + // (+point) --> DQ SDLL; ZERO --> DQS SDLL + + if ( (point > (MAX_SDLL_VAL + MAX_DESKEW_PROGRAMMED) ) || (((uint32_t)point) > (5*mdllcode_byte)) ) { + shim_printf("PANIC during Vref scan. Trying to set a WR DQ SDLL + WR DQ deskew code which is more than maximum allowed \n"); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + return -1; + } + else { + // Compute Min(4*MDLL, 248) + min_of_4mdll_maxsdll = MIN(4*mdllcode_byte, MAX_SDLL_VAL); + + if(((uint32_t)point) > min_of_4mdll_maxsdll) { + deskew_val = point - min_of_4mdll_maxsdll; + wrdqcal_set_delay_point_ovr(wrdqcal_chan, byte, min_of_4mdll_maxsdll); + wrdqcal_program_dq_deskew(wrdqcal_chan, byte, deskew_val); + } + else if (((uint32_t)point) <= min_of_4mdll_maxsdll) { + wrdqcal_set_delay_point_ovr(wrdqcal_chan, byte, point); + } + } + + chrnk_indx = (wrdqcal_chan * cfg_params.num_ranks) + wrdqcal_rank; + + amp_set_cawrlvl_sdll(wrdqcal_chan, cawrlvl_sdll_wrlvl[wrdqcal_chan]); + } else { + // if (point < 0), (-point) --> DQS SDLL; ZERO --> DQ SDLL + wrdqcal_set_delay_point_ovr(wrdqcal_chan, byte, point); + + chrnk_indx = (wrdqcal_chan * cfg_params.num_ranks) + wrdqcal_rank; + + amp_set_cawrlvl_sdll(wrdqcal_chan, cawrlvl_sdll_wrlvl[wrdqcal_chan] + (uint16_t)(-point)); + } + return 0; +} + +// Assess completion (pass/fail) for the hardware with current settings +_ROMCODE_SEGMENT_PREFIX uint32_t wrdqcal_assess_position() +{ + uint32_t wrdqcalresult; + uint32_t wrdqcalrun; + + wrdqcalrun = CSR_READ(rAMP_WRDQ_CAL_RUN(wrdqcal_chan)); + + // Run SW WRDQ calibration + CSR_WRITE(rAMP_WRDQ_CAL_RUN(wrdqcal_chan), (wrdqcalrun & 0xFFFFFFFE) | (1 << WR_CALIB_RUN)); + + // Poll for WRDQ cal run to finish + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQ_CAL_RUN(wrdqcal_chan)) & (1 << WR_CALIB_RUN)); + + // Determine Pass/Fail for each bit of each Byte + wrdqcalresult = (CSR_READ(rAMP_WRDQ_CAL_RESULT(wrdqcal_chan)) & 0x3FFFF); + + return wrdqcalresult; +} + +// Return number of consequetive PASS positions from the indicated position that can be found (up to max) +_ROMCODE_SEGMENT_PREFIX uint8_t wrdqcal_solid_pass(uint32_t byte, int32_t point, int step, uint8_t max) +{ + uint8_t swatch_size = 0; + uint32_t result; + uint32_t wr_bits_pass = wrdqcal_bitmask(byte); + uint8_t pass; + + // Determine Pass/Fail for each bit of each Byte + while (wrdqcal_set_search_point(byte, point) == 0) { + result = wrdqcal_assess_position(); + shim_printf("DEBUG - wrdqcal_solid_pass:: result = 0x%x \n", result); + if (((result & wr_bits_pass) != wr_bits_pass) || (++swatch_size >= max)) + break; + point += step; + } + pass = (swatch_size == max) ? 1 : 0; + + return pass; +} + +// Return number of consecutive all bit fail positions from the indicated position that can be found (up to max) +_ROMCODE_SEGMENT_PREFIX uint8_t wrdqcal_all_bits_fail(uint32_t byte, int32_t point, int step, uint8_t max) +{ + uint8_t swatch_size = 0; + uint32_t result; + uint32_t wr_bits_mask = wrdqcal_bitmask(byte); + uint32_t wr_bits_fail = 0x00000; + uint8_t pass; + + // Determine Pass/Fail for each bit of each Byte + while (wrdqcal_set_search_point(byte, point) == 0) { + result = wrdqcal_assess_position(); + shim_printf("DEBUG - wrdqcal_all_bits_fail:: result = 0x%x \n", result); + if (((result & wr_bits_mask) != wr_bits_fail) || (++swatch_size >= max)) + break; + point += step; + } + + pass = (swatch_size == max) ? 1 : 0; + + return pass; +} + +// Find SOLID pass point (and skew) for each bit from the current "All-Fail" (both bytes) Point +#define WITHIN_BOUNDS(_p,_s,_lim) ((_s < 0)? (_p > _lim):(_p < _lim)) +_ROMCODE_SEGMENT_PREFIX void wrdqcal_find_perbit_skew(uint32_t byte, int edge, int step, int limit, int16_t *bit_edge) +{ + uint32_t per_bit_pass; + uint32_t pass_result; + uint32_t bit,bitval; + int skew; + uint32_t SolidBitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint32_t BitPass[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = { 0 }; + uint8_t all_bits_pass = 0; + + per_bit_pass = wrdqcal_bitmask(byte); + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: per_bit_pass=0x%x \n",per_bit_pass); + + // the 'edge' is the extreme position for All-Bits-Pass + // how far can we push it to find failures on each bit? + for(skew = edge + step; WITHIN_BOUNDS(skew, step, limit); skew += step) { + // Determine Pass/Fail for each bit of each Byte + wrdqcal_set_search_point(byte, skew); + pass_result = wrdqcal_assess_position(); + + per_bit_pass = wrdqcal_bitmask(byte) & pass_result; + + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: pass_result=0x%x, per_bit_pass=0x%x, skew = %d \n", pass_result, per_bit_pass, skew); + + + for(bit=0, bitval=0x01; bit < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit++,bitval<<=1) { + if((per_bit_pass & bitval) && (BitPass[bit] == 0)) { + // Has this bit passed SOLID_PASS_DETECT number of times? Then consider it done + if (SolidBitPass[bit] == SOLID_PASS_DETECT) { + BitPass[bit] = 1; + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: Found solid pass for bit %d at sdll=%d \n",bit, bit_edge[bit]); + } else if (SolidBitPass[bit] > 0) { + SolidBitPass[bit] = SolidBitPass[bit] + 1; + } else { + // bit passed for the first time, record this value in the global array as the left edge + SolidBitPass[bit] = SolidBitPass[bit] + 1; + + bit_edge[bit] = skew; + } + } else { + // bit failed calibration, reset the pass count to 0 + SolidBitPass[bit] = 0; + } + } + + all_bits_pass = 1; + for(bit = 0 ; bit < DQ_TOTAL_BITS + DMI_TOTAL_BITS ; bit++) { + all_bits_pass &= BitPass[bit]; + } + + if(all_bits_pass) { + shim_printf("DEBUG - wrdqcal_find_perbit_skew:: Found passing point for all bits \n"); + break; + } + } + + // Always return ZERO UNLESS we hit the Max/Min Bounds + if (all_bits_pass == 0) { + //shim_panic("Unable to find passing point in WRDQ calibration \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Unable to find passing point in WRDQ calibration \n"); + wrdqcal_vref_panic[wrdqcal_chan][wrdqcal_vref] = 1; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// Do the WrDQ Calibration +//////////////////////////////////////////////////////////////////////////////////////////////// +_ROMCODE_SEGMENT_PREFIX void wrdqcal_sequence(uint8_t chan, uint8_t rank) +{ + int32_t point = 0; + int32_t zone, left_allfail, right_allfail; + int16_t left_edge[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = {0}; + int16_t right_edge[DQ_TOTAL_BITS + DMI_TOTAL_BITS] = {0}; + + uint32_t both_bytes = 0x3; + uint32_t vref, bit; + uint32_t SDLL_threshold_n_1; + uint32_t SDLL_threshold_n_2; + int chrnk_indx; + uint32_t good_vref_not_found; + + // Initialize HW Parameters for the WR DQ Calibration + wrdqcal_init_regs(chan, rank); + chrnk_indx = loopchrnk_index_calc(chan, rank, 0); + + // Initialize DQ and DQS SDLL's to zero before starting + wrdqcal_set_search_point(both_bytes, 0); + + if(cfg_params.wrdq_apply_NC_algorithm) { + + // Program initial Vref setting + amp_program_wrdq_vref(chan, rank, cfg_params.wrdq_vref_values[0], 0); //vref_pulse_cnt=0 + + // ============================================================ + // Determine the correct value for 'n': 1/2 Clk offset or not? + // Set n = 0 for both bytes + wrdqcal_set_half_clk_delay(both_bytes, 0); + + shim_printf("DEBUG - wrdqcal_sequence:: Starting to determine the value of N \n"); + + // N=0 threshold is set to 3*MDLL. N=1 threshold is set to 5*MDLL. + // Also, make sure that DQ SDLL never exceeds 4*MDLL. + SDLL_threshold_n_1 = (3.0 * mdllcode[chan][AMP_CA]); + SDLL_threshold_n_2 = (5.0 * mdllcode[chan][AMP_CA]); + + shim_printf("DEBUG - wrdqcal_sequence:: SDLL_threshold_n_1=0x%x, SDLL_threshold_n_2=0x%x \n",SDLL_threshold_n_1, SDLL_threshold_n_2); + + // Keep incrementing in coarse steps until a P->F transition is found. + for(point = 0; ((uint32_t)point) < SDLL_threshold_n_2; point += COARSE_STEP_SZ) { + + + // Look for one pass on all bits. + if (wrdqcal_solid_pass(both_bytes, point, 1, 1)) { + // In Phase 2, look for a fail on any of the DQ/DM bits. + for(; ((uint32_t)point) < SDLL_threshold_n_2; point += COARSE_STEP_SZ) { + if (!wrdqcal_solid_pass(both_bytes, point, 1, 1)) + break; + } + break; + } + } + + // If we exceeded the Threshold, then set 'n' to ONE + if (((uint32_t)point) >= SDLL_threshold_n_2) { + // Set n = 2 + wrdqcal_set_half_clk_delay(both_bytes, 2); + shim_printf("DEBUG - wrdqcal_sequence:: Determined the value of N to be 2 \n"); + } + else if (((uint32_t)point) >= SDLL_threshold_n_1) { + // Set n = 1 + wrdqcal_set_half_clk_delay(both_bytes, 1); + shim_printf("DEBUG - wrdqcal_sequence:: Determined the value of N to be 1 \n"); + } + else { + shim_printf("DEBUG - wrdqcal_sequence:: Determined the value of N to be 0 \n"); + } + + } + // Reset deskews before calibrating. + wrdqcal_program_dq_deskew(chan, both_bytes, 0); + + // per Vref: + for(vref=0; vref < cfg_params.wrdq_num_vref; vref++) { + + // Set global vref. + wrdqcal_vref = vref; + + // Program Vref setting + amp_program_wrdq_vref(chan, rank, cfg_params.wrdq_vref_values[vref], 0); //vref_pulse_cnt=0 + + shim_printf("DEBUG - wrdqcal_sequence:: Done programming Vref value \n"); + + // ============================================================ + // ZERO the arrays to hold Skew (Left and Right) + for(bit=0; bit < (DQ_TOTAL_BITS + DMI_TOTAL_BITS); bit++) + left_edge[bit] = right_edge[bit] = 0; // ZERO all the skews (Left & Right) + + // ============================================================ + // Find Passing Zone for both bytes: Start @ZERO & Coarse-Step Left (+) ... Find "enough" Consecutive Pass-Points + point = 0; + // Once a passing point is found, go back a coarse step and switch to fine stepping. + for(; point <= MAX_SDLL_VAL; point += COARSE_STEP_SZ) { + if (wrdqcal_solid_pass(both_bytes, point, 1, 1)) { + // Found a passing point. Now go back a coarse step and switch to fine stepping. + point -= COARSE_STEP_SZ; + + for(; point <= MAX_SDLL_VAL; point += FINER_STEP_SZ) { + if (wrdqcal_solid_pass(both_bytes, point, 1, SOLID_PASS_ZONE_DETECT)) { + // Good Solid Pass on both bytes + break; + } + } + break; + } + } + + if (point > MAX_SDLL_VAL) { + // We have failed to find any PASSing Zone at all! + //shim_panic("Unable to find any passing zone in WRDQ calibration \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Unable to find any passing zone in WRDQ calibration \n"); + wrdqcal_vref_panic[chan][vref] = 1; + } + // No Error...We found the Zone! + zone = point; + + // ============================================================ + // From Passing Zone: Coarse-Step Left (+) until find Fail Zone + // Record, per Bit, the location of the Left-Edge of the Passing Zone + point = zone; + for(; point <= (MAX_SDLL_VAL + MAX_DESKEW_PROGRAMMED); point += COARSE_STEP_SZ) { + if (wrdqcal_all_bits_fail(both_bytes, point, 1, SOLID_FAIL)) { + // Found all bits Fail Point + break; + } + } + + if (point <= zone) { + // Inexplicably, despite having already found one PASSing zone, we have failed to find any PASSing Zone at all! + //shim_panic("Cannot find any PASSing Zone in WRDQ calibration \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Cannot find any PASSing Zone in WRDQ calibration \n"); + wrdqcal_vref_panic[chan][vref] = 1; + } + + // No Error...We found the all fail point on the Left side! + left_allfail = point; + + // Next: Assess the skews for the various bits + // REVIEW + wrdqcal_find_perbit_skew(both_bytes, left_allfail, -1, -MAX_SDLL_VAL, left_edge); + + // ============================================================ + // From Passing Zone: Coarse-Step Right (-) until find Fail Zone + // Record, per Bit, the location of the Right-Edge of the Passing Zone + point = zone; + for(; point >= -MAX_SDLL_VAL; point -= COARSE_STEP_SZ) { + if (wrdqcal_all_bits_fail(both_bytes, point, -1, SOLID_FAIL)) { + // Found all Fail Point + break; + } + } + + if (point > zone) { + // Inexplicably, despite having already found one PASSing zone, we have failed to find any PASSing Zone at all! + //shim_panic("Cannot find any PASSing Zone \n"); + shim_printf("PANIC during Vref scan. Record and move forward:Cannot find any PASSing Zone \n"); + wrdqcal_vref_panic[chan][vref] = 1; + } + // No Error...We found the Right Edge! + right_allfail = point; + + shim_printf("DEBUG - Found the right edge at %d \n", point); + + // Next: Assess the skews for the various bits + wrdqcal_find_perbit_skew(both_bytes, right_allfail, 1, MAX_SDLL_VAL, right_edge); + + // ============================================================ + // Note these values in the result array + for(bit=0; bit < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit++) { + wrdqcal_per_chrnk_left[chrnk_indx][vref][bit] = left_edge[bit]; + wrdqcal_per_chrnk_right[chrnk_indx][vref][bit] = right_edge[bit]; + } + + // ============================================================ + } // Done with all Vref + + // Find if there is even a single Vref which did not panic. + good_vref_not_found = 1; + for(vref=0; vref < cfg_params.wrdq_num_vref; vref++) { + good_vref_not_found &= wrdqcal_vref_panic[chrnk_indx][vref]; + } + if(good_vref_not_found == 1) { + shim_panic("Memory WRDQ calibration: Unable to find any Vref which did not panic for channel %d\n", chrnk_indx); + } + + // ============================================================ + // Find Optimal Vref, CoM + // Can we use the known skews to allow a more optimal 'optimal vref'? + amp_compute_opt_vref_wrdqcal(chan, rank, DQ_TOTAL_BITS + DMI_TOTAL_BITS); + + // ============================================================ + // Considering the Left and Right Skew: + // per DQ Byte, normalize the SDLL vs. perBit deskew so that at least *one* of the perBit deskews is ZERO + + // ============================================================ + // Program Final Values + // cntr_opt_wrdq[chrnk_indx] = optimal.center; + // optimal.center --> SDLL + wrdqcal_set_search_point(1 << 0, cntr_opt_wrdq[chrnk_indx]); + wrdqcal_set_search_point(1 << 1, cntr_opt_wrdq[chrnk_indx]); +} + + +_ROMCODE_SEGMENT_PREFIX void wrdqcal_program_final_values(void) +{ + uint32_t ch, bit_indx, byte; + uint32_t chrnk0_indx; + int32_t arr_WrDqBitCenterPoint[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + int32_t arr_WrDqBitDeSkew[DQ_TOTAL_BITS + DMI_TOTAL_BITS]; + int32_t left_pos_val; + int32_t right_pos_val; + int32_t min_WrDqCenterPoint_val_b[DQ_NUM_BYTES]; + int32_t max_of_min_WrDqCenterPoint_val_b; + int32_t arr_WrDmiDeSkew[DQ_NUM_BYTES] = { 0 }; + uint32_t wrdqcalvrefcodecontrol; + uint32_t vref_ch; +#if ENV_DV + uint32_t loopchrnk000 = loopchrnk_index_calc(0, 0, 0); + uint32_t vref0 = vref_opt_wrdq[loopchrnk000]; + + uint32_t N; + uint32_t wrdqsdq_sdllcode; + + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + if (ch == cfg_params.num_channels_runCalib) + shim_printf("DEBUG - %s:: Preloading non-calibrated channels " + "with channel 0's calibration results \n", __PRETTY_FUNCTION__); + // For channels on which calibration was not done, load calibration results from channel 0. + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_wrdq[chrnk0_indx] = vref0; + + for (bit_indx=0; bit_indx < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit_indx++) { + wrdqcal_per_chrnk_left[chrnk0_indx][vref_opt_wrdq[chrnk0_indx]][bit_indx] = wrdqcal_per_chrnk_left[loopchrnk000][vref0][bit_indx]; + wrdqcal_per_chrnk_right[chrnk0_indx][vref_opt_wrdq[chrnk0_indx]][bit_indx] = wrdqcal_per_chrnk_right[loopchrnk000][vref0][bit_indx]; + } + + cawrlvl_sdll_wrlvl[ch] = cawrlvl_sdll_wrlvl[0]; + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + dqwrlvl_sdll_after_wrlvl[ch][byte] = dqwrlvl_sdll_after_wrlvl[0][byte]; + } + } + + // Also program value of N for all channels correctly. + shim_printf("DEBUG - wrdqcal_program_final_values:: Preloading non-calibrated channels with channel 0's N value \n"); + for(ch = cfg_params.num_channels_runCalib; ch < cfg_params.num_channels; ch++) { + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + N = (CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(byte, loopchrnk000)) >> HALF_CLK_OVRVAL_OFFSET) & 0x3; + wrdqsdq_sdllcode = CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(byte, chrnk0_indx)); + wrdqsdq_sdllcode = (wrdqsdq_sdllcode & HALF_CLK_OVRVAL_MASK) | (N << HALF_CLK_OVRVAL_OFFSET) | (1 << RUN_SDLLUPDWRRES); + CSR_WRITE(rAMP_WRDQSDQ_SDLLCTRL(byte, chrnk0_indx), wrdqsdq_sdllcode); + while(CSR_READ(rAMP_WRDQSDQ_SDLLCTRL(byte, chrnk0_indx)) & (1 << RUN_SDLLUPDWRRES)); + } + } + #endif + + for (ch = 0; ch < cfg_params.num_channels; ch++) { + chrnk0_indx = loopchrnk_index_calc(ch, 0, 0); + vref_ch = vref_opt_wrdq[chrnk0_indx]; + + // find the center point of passing window for each bit over all ranks + for (bit_indx = 0; bit_indx < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit_indx++) { + + left_pos_val = wrdqcal_per_chrnk_left[chrnk0_indx][vref_ch][bit_indx]; + right_pos_val = wrdqcal_per_chrnk_right[chrnk0_indx][vref_ch][bit_indx]; + + // find center of the eye for this bit + arr_WrDqBitCenterPoint[bit_indx] = find_wrdq_center_of_eye(left_pos_val, right_pos_val); + shim_printf("DEBUG - wrdqcal_program_final_values:: Center value for bit %d in Channel %d = %d \n", bit_indx, ch, arr_WrDqBitCenterPoint[bit_indx]); + } + + // initialize the min centerpoint to the 1st bit's center point in each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + min_WrDqCenterPoint_val_b[byte] = arr_WrDqBitCenterPoint[byte * DQ_NUM_BITS_PER_BYTE]; + + // Find the min CenterPoint per byte lane given each bit's center point + for (bit_indx=0; bit_indx < DQ_TOTAL_BITS + DMI_TOTAL_BITS; bit_indx++) { + + byte = (bit_indx < DQ_TOTAL_BITS) ? (bit_indx >> 3) : (bit_indx - DQ_TOTAL_BITS); // bit_indx / DQ_NUM_BITS_PER_BYTE + + // if this bit's center point is less than current min, make it the new min + min_WrDqCenterPoint_val_b[byte] = find_common_endpoint(min_WrDqCenterPoint_val_b[byte], arr_WrDqBitCenterPoint[bit_indx], MIN_ENDPT); + } + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + shim_printf("DEBUG - wrdqcal_program_final_values:: Minimum center value for byte %d = %d \n", byte, min_WrDqCenterPoint_val_b[byte]); + } + + // Compute the individual deskew values: any bits with center point > min for its byte lane will require deskew + // Each bit's center is guaranteed to be >= min for its byte lane + // Deskewing means adding more positive adjustment for this bit in addition to the sdll, which is clamped on the negative side to -dqmdllcode + // and clamped on the positive side to (mdllcode - DELIMIT_POS_ADJ_WRDQSDLL) + + // Also push CA WRLVL SDLL here + // CA WRLVLMax value should be with the max DQS SDLL of the two bytes + // 1. DQS SDLL will be the negation of min_WrDqCenterPoint_val_b. Negate using macro NEGATE + // 2. If negation turns out to be -ve, make it zero, since DQS SDLL can only be >=0. + max_of_min_WrDqCenterPoint_val_b = MAX(POS(NEGATE(min_WrDqCenterPoint_val_b[0])), POS(NEGATE(min_WrDqCenterPoint_val_b[1]))); + amp_program_cawrlvl_sdll(ch, cawrlvl_sdll_wrlvl[ch], max_of_min_WrDqCenterPoint_val_b); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into CA WRLVLMAX \n", max_of_min_WrDqCenterPoint_val_b); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into CA WRLVL \n", cawrlvl_sdll_wrlvl[ch]); + + // Program SDLL for each byte lane + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + // Set the DQ/DQS SDLL (RESULT) for this channel/byte + wrdqcal_set_delay_point_res(ch, 1 << byte, min_WrDqCenterPoint_val_b[byte]); + shim_printf("DEBUG - %s:: Programming (for byte %d) final DQ/DQS point to: %5d\n", __PRETTY_FUNCTION__, + min_WrDqCenterPoint_val_b[byte], byte); + + // DQS WRLVL SDLL should be incremented by difference between MAX DQS SDLL & DQS SDLL of the bytes in question. + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into DQ byte %d WRLVLMAX \n",max_of_min_WrDqCenterPoint_val_b - POS(NEGATE(min_WrDqCenterPoint_val_b[byte])), byte); + amp_program_dqwrlvl_sdll(ch, byte, dqwrlvl_sdll_after_wrlvl[ch][byte], max_of_min_WrDqCenterPoint_val_b - POS(NEGATE(min_WrDqCenterPoint_val_b[byte]))); + + for (bit_indx = 0; bit_indx < DQ_NUM_BITS_PER_BYTE; bit_indx++) { + arr_WrDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] = arr_WrDqBitCenterPoint[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] - min_WrDqCenterPoint_val_b[byte]; + + CSR_WRITE(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx), arr_WrDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx] | RUNDESKEWUPD); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into DQ byte %d bit %d \n", arr_WrDqBitDeSkew[(byte * DQ_NUM_BITS_PER_BYTE) + bit_indx], byte, bit_indx); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDQDESKEW_CTRL(byte, ch, bit_indx)) & RUNDESKEWUPD); + } + + // Program DMI deskew + arr_WrDmiDeSkew[byte] = arr_WrDqBitCenterPoint[DQ_TOTAL_BITS + byte] - min_WrDqCenterPoint_val_b[byte]; + CSR_WRITE(rAMP_WRDMDESKEW_CTRL(byte, ch), arr_WrDmiDeSkew[byte] | RUNDESKEWUPD); + shim_printf("DEBUG - wrdqcal_program_final_values:: Programming a value of %d into DMI deskew for byte %d \n", arr_WrDmiDeSkew[byte], byte); + + // Poll for deskew update to be done. + SPIN_W_TMO_WHILE (CSR_READ(rAMP_WRDMDESKEW_CTRL(byte, ch)) & RUNDESKEWUPD); + } + + // Program DRAM with optimal WRDQ Vref + amp_program_wrdq_vref(ch, 0, cfg_params.wrdq_vref_values[vref_ch], 0); //vref_pulse_cnt=0 + + // Also program MCU registers with optimal WRDQ Vref value. + if(cfg_params.freq_bin == 1) { + wrdqcalvrefcodecontrol = CSR_READ(rAMP_WRDQCALVREFCODESTATUS(ch)); + CSR_WRITE(rAMP_WRDQCALVREFCODECONTROL(ch), (wrdqcalvrefcodecontrol & WRDQ_VREF_F1_MASK) | (cfg_params.wrdq_vref_values[vref_ch] << WRDQ_VREF_F1_OFFSET)); + } + else if(cfg_params.freq_bin == 0) { + wrdqcalvrefcodecontrol = CSR_READ(rAMP_WRDQCALVREFCODESTATUS(ch)); + CSR_WRITE(rAMP_WRDQCALVREFCODECONTROL(ch), (wrdqcalvrefcodecontrol & WRDQ_VREF_F0_MASK) | (cfg_params.wrdq_vref_values[vref_ch] << WRDQ_VREF_F0_OFFSET)); + } + + + } // for (ch = 0; ch < cfg_params.num_channels; ch++) +} + +_ROMCODE_SEGMENT_PREFIX static int32_t find_center_of_eye(int32_t left_pos_val, int32_t right_pos_val) +{ + // CP : Maui Change + if (left_pos_val > right_pos_val) + shim_panic("Memory calibration: find_center_of_eye: Left value (0x%x) is > right value (0x%x) \n", left_pos_val, right_pos_val); + + // center of 2 signed integers is simply their average + return ((left_pos_val + right_pos_val) / 2); +} + +_ROMCODE_SEGMENT_PREFIX static int32_t find_wrdq_center_of_eye(int32_t left_pos_val, int32_t right_pos_val) +{ + // CP : Maui Change + if (left_pos_val < right_pos_val) + shim_panic("Memory calibration: find_wrdq_center_of_eye: Left value (0x%x) is < right value (0x%x) \n", left_pos_val, right_pos_val); + + // center of 2 signed integers is simply their average + return ((left_pos_val + right_pos_val) / 2); +} + +// Select the value that would include the other value in the eye +_ROMCODE_SEGMENT_PREFIX static int32_t find_common_endpoint(int32_t val0, int32_t val1, uint32_t left_or_right) +{ + int32_t retVal = val0; + + // For the left endpoint, select the rightmost value on the number line (max value) + if (left_or_right == MAX_ENDPT) { + if (val0 > val1) + retVal = val0; + else + retVal = val1; + } + // For the right endpoint, select the leftmost value (min value) + else { + if (val0 < val1) + retVal = val0; + else + retVal = val1; + } + + return retVal; +} + +// Inserts the data at given byte and bit position in the cal_bits array +// Assumes that num_bits is always <= 8 +_ROMCODE_SEGMENT_PREFIX void cal_save_value(uint8_t data, uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos) +{ + uint32_t space_in_this_byte; + uint8_t mask; + + if (((*bit_pos) > 7) || ((*byte_pos) >= CALIB_PMU_BYTES)) + shim_panic("Error! bit position %d > 7 or byte position %d > capacity (%d)\n", *bit_pos, *byte_pos, CALIB_PMU_BYTES); + + // how many bits left in this byte? + space_in_this_byte = 8 - (*bit_pos); + + // we'll grab as many bits from the data as there is space in this byte + if (space_in_this_byte >= num_bits) + mask = (1 << num_bits) - 1; + else + mask = (1 << space_in_this_byte) - 1; + + // Set the data value at given byte (only as many bits as space and making sure to preserve the other bits in this byte) + cal_bits[*byte_pos] |= ((data & mask) << *bit_pos); + + if (space_in_this_byte < num_bits) { + // any remainder bits get saved to the next byte + cal_bits[(*byte_pos) + 1] = (data >> space_in_this_byte); + (*byte_pos)++; + *bit_pos = num_bits - space_in_this_byte; + } else if (space_in_this_byte == num_bits) { + (*byte_pos)++; + *bit_pos = 0; + } else { + (*bit_pos) += num_bits; + } +} + +// Retrieve the data at given byte and bit position in the cal_bits array +// Assumes that num_bits is always <= 8 +_ROMCODE_SEGMENT_PREFIX static uint8_t cal_retrieve_value(uint32_t num_bits, uint32_t *bit_pos, uint32_t *byte_pos) +{ + uint32_t space_in_this_byte; + uint8_t mask, remainder_mask, ret_val; + + if (((*bit_pos) > 7) || ((*byte_pos) >= CALIB_PMU_BYTES)) + shim_panic("Error! bit position %d > 7 or byte position %d > capacity (%d)\n", *bit_pos, *byte_pos, CALIB_PMU_BYTES); + + // how many bits left in this byte? + space_in_this_byte = 8 - (*bit_pos); + + // we'll grab as many bits from the array as there is space in this byte (max of num_bits) + if (space_in_this_byte >= num_bits) + mask = (1 << num_bits) - 1; + else { + mask = (1 << space_in_this_byte) - 1; + remainder_mask = (1 << (num_bits - space_in_this_byte)) - 1; + } + + // Get the data value at given byte (only as many bits as space) + ret_val = (cal_bits[*byte_pos] >> *bit_pos) & mask; + + if (space_in_this_byte < num_bits) { + // any remainder bits get loaded from the next byte + ret_val |= (cal_bits[(*byte_pos) + 1] & remainder_mask) << space_in_this_byte; + (*byte_pos)++; + *bit_pos = num_bits - space_in_this_byte; + } else if (space_in_this_byte == num_bits) { + (*byte_pos)++; + *bit_pos = 0; + } else { + (*bit_pos) += num_bits; + } + + return ret_val; +} + +// ================================================================================ +typedef struct +{ + uint32_t sum; // Number of "Mass" objects recorded + int32_t sum_mass_ave; // Sum of the Average "Mass" position + uint32_t sum_mass; // Sum of the "Mass" + uint32_t sum_mass_h; // Sum of the "Mass" * "height" + int32_t center; // Center-of-Mass + uint32_t center_h; // Center-of-Mass WRT height +} opt_center_accum_t; + +// ================================================================================ +_ROMCODE_SEGMENT_PREFIX void amp_opt_center_init(opt_center_accum_t *opt) +{ + uint32_t *ptr = (uint32_t *)opt; + uint32_t *end = (uint32_t *)(opt + 1); + + // ZERO everything + while (ptr < end) *ptr++ = 0; +} + +// ================================================================================ +_ROMCODE_SEGMENT_PREFIX void amp_opt_center_add(opt_center_accum_t *opt, uint32_t height, int shift, int32_t hi, int32_t lo) +{ + if (hi < lo) + shim_panic("Error! Non-sensical (hi < lo) in calculating center [hi==%d, lo==%d]\n", hi, lo); + + // Apply the Shift (could be ZERO) + hi += shift; + lo += shift; + + opt->sum += 1; + opt->sum_mass_ave += (hi + lo); // NOTE: "divide by two" handled at finalization + opt->sum_mass += (hi - lo); + opt->sum_mass_h += (hi - lo) * height; +} + +// ================================================================================ +_ROMCODE_SEGMENT_PREFIX void amp_opt_center_final(opt_center_accum_t *opt) +{ + if (opt->sum > 0) + // Find the Average Center (Rounding off to nearest) + opt->center = (opt->sum_mass_ave + ((int32_t)opt->sum)) / (2 * ((int32_t)opt->sum)); + + if (opt->sum_mass > 0) + // Find the Weighted-Average Height Center (Rounding off to nearest) + opt->center_h = (opt->sum_mass_h + (opt->sum_mass / 2)) / (opt->sum_mass); +} + +// ================================================================================ +// Compute the optimal Vref index across multiple vref and multiple bits +// Used by CA, RdDQ, WrDQ +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref(char *descr, uint32_t vrefMax, uint32_t bitMax, + int32_t *right, int32_t *left, int32_t *vref_panic, int32_t *skewR, int32_t *skewL, + int32_t *opt_cent_solution, uint32_t *opt_vref_solution) +{ + uint32_t vref,bit; + int32_t L,R; + int32_t panic; + int32_t deskew = 0; + int32_t maxL,minR; + uint32_t span,max_span = 0; + uint32_t opt_vref = 0; + int32_t opt_center = 0; + opt_center_accum_t optimal; + bool use_com = (cfg_params.opt_vref_mode == DCS_CAL_OPT_VREF_MODE_COM); + + if (use_com) { + // Init the "optimal center" calculation + amp_opt_center_init(&optimal); + } + + for(vref = 0; vref < vrefMax; vref++) { + + panic = *vref_panic++; + + shim_printf("DEBUG - OptVref (%s) [vref=%d] Panic flag is %d \n", descr, vref, panic); + + // Only consider this Vref if it did not panic. + if(!panic) { + + maxL = -MAX_SDLL_VAL; + minR = MAX_SDLL_VAL; + for(bit = 0; bit < bitMax; bit++) { + // Grab the Values + L = *left++; + R = *right++; + if (skewL && skewR) + deskew = *skewL++ - *skewR++; + + shim_printf("DEBUG - OptVref (%s) [vref=%d][bit=%d]: L=%d, R=%d, deskew=%d\n", + descr, vref, bit, L, R, deskew); + + if (use_com) { + // Add this info to the "optimal center" calculation + amp_opt_center_add(&optimal, vref, deskew, R, L); + } else { + // Find the minimum Right and find the maximum Left + if (minR > R) minR = R; + if (maxL < L) maxL = L; + } + } + + if (!use_com) { + // Calculate the Span for this vref + span = minR - maxL; + // Remember the Maximum span (and record its vref and its center point) + if (max_span < span) { + max_span = span; + opt_vref = vref; + opt_center = (maxL + minR) / 2; + } + } + } + } + + if (use_com) { + // Finalize the "optimal center" calculation + amp_opt_center_final(&optimal); + opt_vref = optimal.center_h; + opt_center = optimal.center; + } + + shim_printf("DEBUG - OptVref (%s) OptimalVref=%d, OptimalCenter=%d\n", descr, opt_vref, opt_center); + + // Copy our results to caller + if (opt_vref_solution) *opt_vref_solution = opt_vref; + if (opt_cent_solution) *opt_cent_solution = opt_center; +} + +// ================================================================================ +// Compute the optimal Vref index for CA calibration +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref_cacal(uint32_t ch, uint32_t rnk, uint32_t swloop, uint32_t bitMax) +{ + // Calc the index for this Loop/Ch/Rnk + uint32_t loopchrnk_indx = loopchrnk_index_calc(ch, rnk, swloop); + + // Run the Calculation for the Optimal VRef and Optimal Center + amp_compute_opt_vref("CA", cfg_params.ca_num_vref, bitMax, + (int32_t *)(cacal_per_loopchrnk_right[loopchrnk_indx]), + (int32_t *)(cacal_per_loopchrnk_left[loopchrnk_indx]), + (int32_t *)(cacal_vref_panic[loopchrnk_indx]), + 0, 0, + &(cntr_opt_ca[loopchrnk_indx]), + &(vref_opt_ca[loopchrnk_indx])); +} + +// ================================================================================ +// Compute the optimal Vref index for RdDQ calibration +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref_rddqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax) +{ + // Calc the index for this Loop/Ch/Rnk + uint32_t loopchrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + + // Run the Calculation for the Optimal VRef and Optimal Center + amp_compute_opt_vref("RdDQ", cfg_params.rddq_num_vref, bitMax, + (int32_t *)(rddqcal_per_chrnk_right[loopchrnk_indx]), + (int32_t *)(rddqcal_per_chrnk_left[loopchrnk_indx]), + (int32_t *)(rddqcal_vref_panic[loopchrnk_indx]), + 0, 0, + &(cntr_opt_rddq[loopchrnk_indx]), + &(vref_opt_rddq[loopchrnk_indx])); +} + +// ================================================================================ +// Compute the optimal Vref index for WrDQ calibration +_ROMCODE_SEGMENT_PREFIX void amp_compute_opt_vref_wrdqcal(uint32_t ch, uint32_t rnk, uint32_t bitMax) +{ + // Calc the index for this Loop/Ch/Rnk + uint32_t loopchrnk_indx = loopchrnk_index_calc(ch, rnk, 0); + + // Run the Calculation for the Optimal VRef and Optimal Center + amp_compute_opt_vref("WrDQ", cfg_params.wrdq_num_vref, bitMax, + // NOTE: for WRDQ, Left and Right have been Swapped! + (int32_t *)(wrdqcal_per_chrnk_left[loopchrnk_indx]), + (int32_t *)(wrdqcal_per_chrnk_right[loopchrnk_indx]), + (int32_t *)(wrdqcal_vref_panic[loopchrnk_indx]), + // ======================================================= + 0, 0, + &(cntr_opt_wrdq[loopchrnk_indx]), + &(vref_opt_wrdq[loopchrnk_indx])); +} +// ================================================================================ diff --git a/drivers/apple/dcs/dcs_init_lib.c b/drivers/apple/dcs/dcs_init_lib.c new file mode 100644 index 0000000..4f22724 --- /dev/null +++ b/drivers/apple/dcs/dcs_init_lib.c @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Init Sequence Library for use in: + * Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block + */ + +/* +Summary of Steps from the Spec (Spreadsheet) + + + (Aa) Steps 0,1,2,3a [need to identify parameterization] + + (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait] + + (Ac) Steps 3c,4,5 [need to identify parameterization] + + (B) Step 6 [Change Clk Speed] + + (C) Step 7 [include delay-wait from early Step 8] + + (D) Step 8a [Cal: CA 800MHz Vmin] + + (E) Step 8b [Write Regs] + + (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?) + + (G) Step 8d [Write Regs] + + (H) Step 9 [Write Regs] + + (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin] + + (J) Step 11 [Write Regs] + + (K) Step 12 [Cal: CA 1200MHz Vnom] + + (L) Step 13 [Write Regs] + + (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin] + + (N) Steps 15,16,17,18,19,20 [need to identify parameterization] + +Between these steps there is possibly a need/desire for: +- Frequency Changes (PMGR) +- PMU save/restore +- debug messages +- register dumps (DV, SiVal) +- anything else! + +CONFIG Table: + Compile-Time Known: + Type of Execution Environment CoreOS, DV, SiVal + Type of Target SoC, FPGA, Palladium + ChipID 0x8000, 0x8001, etc. + Revision A0, B0, B1, etc. + Num DCS 4, 8, etc. (Derived...!) + Variant Flags Work-arounds, RADAR Ref., et al. + + (Config Info know at Compile time can be subject to #if) + + Run-Time Known: + Type of Init ColdBoot, AOP_DDR, AOP_AWAKE + Debug Flags Low-Level, Milestone, et al. + +RegValue Table + Much like today's: various values for various registers + Sensitive to ChipID (also Target type?) + (Internal static alloc (Complete Table Fill-in within Init function): + Fill in Values (per ChipID/Rev & Target-type) + return pointer to caller + (Allows customization by caller before use) + +TODO: +- Convert to using SPDS for register names, et al + +*/ + +//================================================================================ +// API Definitions +#include + +dcs_config_t dcs_cfg; +extern dcs_config_params_t dcs_params; + +#if izIBOOT +int debug_level_dcs = DEBUG_SPEW; +#endif + +//================================================================================ +// Configure the Library for use for the current Boot Type, Chip Type, etc. +//================================================================================ +bool dcs_init_config(dcs_boottype_t boot_type, uint32_t chipID, uint32_t chipRev, + uint32_t num_dcs, uint32_t num_rank) +{ + dcs_cfg.valid = false; + // TODO: Get a little noisy about failures in this function + + // Validate that Build Environment is one that we support + if (!(izIBOOT || izSIVAL || izDV || izPERTOS)) { + return false; + } + // Validate that Target Type is one that we support + if (!(izSOC || izFPGA || izPAL)) + return false; + + dcs_cfg.boot_type = boot_type; + // Validate that the Boot Type is one that we support + if (!(izColdBoot || izResume || izAOP_DDR || izAOP_Awake)) + return false; + // Validate that we can support the requested number of channels/ranks + if ((num_dcs > DCS_NUM_CHANNELS) || (num_rank > DCS_NUM_RANKS)) + return false; +#if izIBOOT + // Validate the Chip ID provided against the actual (only for iBoot) + if (chipID != platform_get_chip_id()) + return false; +#endif + dcs_cfg.chipID = chipID; + dcs_cfg.chipRev = chipRev; + dcs_cfg.num_dcs = num_dcs; + dcs_cfg.num_rank = num_rank; + + dcs_cfg.debugBitz = DCS_DBG_DEFAULT; // Default include Overview + dcs_cfg.variantBitz = DCS_VARIANT_NONE; // Default: No variant flags enabled + +#if 1 // Very useful indicator that we have built this library correctly + dbgprintf(DCS_DBG_OVERVIEW, "DCS Init Lib Built for: " +#if izIBOOT + "iBoot " +#endif +#if izSIVAL + "SiVal " +#endif +#if izDV + "DV " +#endif +#if izPERTOS + "PERTOS " +#endif +#if izSOC + "SOC" +#endif +#if izFPGA + "FPGA" +#endif +#if izPAL + "PAL" +#endif + "\n"); +#endif + dbgprintf(DCS_DBG_OVERVIEW, + "DCS Init [%s Build] for ChipID==0x%04x chipRev %c%c (#DCS==%d, #Rank==%d) [%s] using %s\n", + (izIBOOT)? "iBoot":(izSIVAL)? "SiVal":(izDV)? "DV":(izPERTOS)? "PERTOS":"??Build??", + chipID, ((chipRev >> 4) & 0xF) + 'A', ((chipRev >> 0) & 0xF) + '0', + dcs_cfg.num_dcs, dcs_cfg.num_rank, + (izSOC)? "SoC":(izFPGA)? "FPGA":(izPAL)? "Palladium":"??Target??", + (izColdBoot)? "Coldboot":(izResume)? "Resume":(izAOP_DDR)? "AOP_DDR":(izAOP_Awake)? "AOP_Awake":"??BootType??"); + + // We're good to go! + dcs_cfg.valid = true; + return dcs_cfg.valid; +} + +//================================================================================ +// Alter the Debug or the Variant Bits, returning the value-before-modifcation +//================================================================================ +uint32_t dcs_init_debug_enable(uint32_t bit) +{ + uint32_t ret = dcs_cfg.debugBitz; + dcs_cfg.debugBitz |= bit; + return ret; +} + +uint32_t dcs_init_debug_disable(uint32_t bit) +{ + uint32_t ret = dcs_cfg.debugBitz; + dcs_cfg.debugBitz &= ~bit; + return ret; +} + +uint32_t dcs_init_variant_enable(uint32_t bit) +{ + uint32_t ret = dcs_cfg.variantBitz; + dcs_cfg.variantBitz |= bit; + return ret; +} + +uint32_t dcs_init_variant_disable(uint32_t bit) +{ + uint32_t ret = dcs_cfg.variantBitz; + dcs_cfg.variantBitz &= ~bit; + return ret; +} + + +//================================================================================ +// Set up the Config Parameter Table (specifc to Platform, using target type) +//================================================================================ +dcs_config_params_t *dcs_init_param_table(void) +{ + // Call (platform-specific) function to initialize values to be used during DCS Init + dcs_init_config_params(&dcs_params, DCS_TARGET_TYPE); + + // Return pointer to the table + // (allows caller to optionally modify values for possible experimentation) + return &dcs_params; +} + +//================================================================================ +// Basic Register Write/Poll Functions, including MR Cmds +//================================================================================ +void dcs_reg_write(uintptr_t reg_addr, uint32_t reg_value) +{ + dbgprintf(DCS_DBG_REG_ACCESS, "DCS Init REG(%p) <- 0x%08X (Single-Reg-Write)\n", + (void *)reg_addr, reg_value); + DCS_REG_ACCESS(reg_addr) = reg_value; +} + +void dcs_reg_poll(uintptr_t reg_addr, uint32_t mask_value, uint32_t required_value) +{ + dbgprintf(DCS_DBG_REG_ACCESS, "DCS Init REG(%p) Poll: Mask (0x%08X) == 0x%08x (Single-Reg-Poll)\n", + (void *)reg_addr, mask_value, required_value); + SPIN_W_TMO_WHILE((DCS_REG_ACCESS(reg_addr) & mask_value) != required_value); +} + +void dcs_reg_write_all_chan(uintptr_t reg_addr, uint32_t reg_value) +{ + uint32_t channel; + + dbgprintf(DCS_DBG_REG_ACCESS, "DCS Init REG(%p) <- 0x%08X (x%d)", + (void *)reg_addr, reg_value, dcs_cfg.num_dcs); + for(channel = 0; channel < dcs_cfg.num_dcs; channel++) { + DCS_REG_ACCESS(reg_addr + (channel * DCS_SPACING)) = reg_value; + dbgprintf(DCS_DBG_CHAN_DETAIL, "%d ", channel); + } + dbgprintf(DCS_DBG_REG_ACCESS, "\n"); +} + +void dcs_reg_poll_all_chan(uintptr_t reg_addr, uint32_t mask_value, uint32_t required_value) +{ + uint32_t channel; + + dbgprintf(DCS_DBG_REG_ACCESS, "DCS Init REG(%p) Poll: Mask (0x%08X) == 0x%08x ...", + (void *)reg_addr, mask_value, required_value); + for(channel = 0; channel < dcs_cfg.num_dcs; channel++) { + dbgprintf(DCS_DBG_CHAN_DETAIL, " %d", channel); + SPIN_W_TMO_WHILE((DCS_REG_READ_CH(channel, reg_addr) & mask_value) != required_value); + dbgprintf(DCS_DBG_CHAN_DETAIL, "!"); + } + dbgprintf(DCS_DBG_REG_ACCESS, "\n"); +} + +// To determine whether to use dcs_reg_write_all_chan or dcs_reg_write, +// because regs within a dcs hw block will be duplicated per channel, while those outside the block will not +bool dcs_reg_is_outside_dcs_block(uintptr_t reg_addr) +{ + if((reg_addr >= DCS_BASE_ADDR) && (reg_addr < (DCS_BASE_ADDR + DCS_SPACING))) + return false; + + return true; +} + +// Only send the cmd to specific channel and rank (no poll afterward) +static void dcs_mrcmd_send_specific_ch_rnk(uint32_t cmd, uint8_t channel, uint8_t rank) +{ + cmd |= (rank << MRCMD_RANK_SHIFT); + rDCS_MCU_MRINITCMD(channel) = cmd; +} + +// Only poll the specific channel and rank (return cmd word) +static uint32_t dcs_mrcmd_poll_specific_ch_rnk(uint32_t cmd, uint8_t channel, uint8_t rank) +{ + SPIN_W_TMO_WHILE((cmd = rDCS_MCU_MRINITSTS(channel)) & MRCMD_POLL_BIT); + return cmd; +} + +// Only send the cmd to specific channel and rank +static uint32_t dcs_mrcmd_to_specific_ch_rnk(uint32_t cmd, uint8_t channel, uint8_t rank) +{ + dcs_mrcmd_send_specific_ch_rnk(cmd, channel, rank); + return dcs_mrcmd_poll_specific_ch_rnk(cmd, channel, rank); +} + +// Send the cmd to channel and rank as indicated (used during calibration on H6 and later) +static uint32_t dcs_form_mrcmd_word(dcs_mrcmd_op_t op, int reg, uintptr_t val) +{ + uint32_t cmd; + + if (op == MR_READ) + cmd = MRCMD_TYPE_READ | (reg << MRCMD_REG_SHIFT); + else if (op == MR_WRITE) + cmd = MRCMD_TYPE_WRITE | (reg << MRCMD_REG_SHIFT) | (((uint32_t)val) << MRCMD_DATA_SHIFT); + // MPC + else + cmd = MRCMD_TYPE_MPC | (reg << MRCMD_REG_SHIFT) | (((uint32_t)val) << MRCMD_DATA_SHIFT); + + return cmd; +} + +// Send the cmd to channel and rank as indicated (used during calibration on H6 and later) +void dcs_mrcmd_to_ch_rnk(dcs_mrcmd_op_t op, uint8_t channel, uint8_t rank, int reg, uintptr_t val) +{ + uint32_t cmd, regval; + uint8_t *buffer = (uint8_t *) val; + + cmd = dcs_form_mrcmd_word(op, reg, val); + regval = dcs_mrcmd_to_specific_ch_rnk(cmd, channel, rank); + if (op == MR_READ) { + dbgprintf(DCS_DBG_MR_READ, " [data==0x%02x] ", (regval >> MRCMD_DATA_SHIFT) & 0xff); + *buffer++ = (regval >> MRCMD_DATA_SHIFT) & 0xff; + } +} + +void dcs_mrcmd(dcs_mrcmd_op_t op, uint8_t channels, uint8_t ranks, int reg, uintptr_t val) +{ + uint8_t ch, r; + uint32_t cmd, regval; + uint8_t *buffer = (uint8_t *) val; + + cmd = dcs_form_mrcmd_word(op, reg, val); + dbgprintf(DCS_DBG_REG_ACCESS, "DCS Init MRCMD(0x%08X)[%dx chan][%dx rank]", + cmd, channels, ranks); + dbgprintf(DCS_DBG_CHAN_DETAIL, " SEND: "); + for (ch = 0; ch < channels; ch++) { + for (r = 0; r < ranks; r++) { + dbgprintf(DCS_DBG_CHAN_DETAIL, "->%d%d ", ch, r); + dcs_mrcmd_send_specific_ch_rnk(cmd, ch, r); + } + } + dbgprintf(DCS_DBG_CHAN_DETAIL, " POLL: "); + for (ch = 0; ch < channels; ch++) { + for (r = 0; r < ranks; r++) { + regval = dcs_mrcmd_poll_specific_ch_rnk(cmd, ch, r); + dbgprintf(DCS_DBG_CHAN_DETAIL, "%d%d! ", ch, r); + if (op == MR_READ) { + dbgprintf(DCS_DBG_MR_READ, " [data==0x%02x] ", (regval >> MRCMD_DATA_SHIFT) & 0xff); + *buffer++ = (regval >> MRCMD_DATA_SHIFT) & 0xff; + } + } + } + dbgprintf(DCS_DBG_REG_ACCESS, "\n"); +} + +//================================================================================ +// Utility Functions +//================================================================================ +void dcs_spin(uint32_t duration_us, char *reason) +{ + if (reason == NULL) reason = ""; + dbgprintf(DCS_DBG_SPIN, "DCS Init Spin %d us %s\n", duration_us, reason); + delay_for_us(duration_us); +} + + + +//================================================================================ +// Apply Tunables (uses callout that is specifc to Platform) +//================================================================================ +void dcs_init_apply_tunables(void) +{ + volatile uintptr_t regptr = 0; + uint32_t regval; + uint32_t i,numtune = 0; + const struct dcs_tunable *dcs_tune; + + dcs_tune = dcs_init_tunable_table(&numtune); + // Check that we have a table + if ((dcs_tune == NULL) || (numtune == 0)) + return; + + for (i = 0; i < numtune; i++, dcs_tune++) { + // end of list? + if (dcs_tune->reg == 0) + break; + // Check if we are now looking at a new register + if (dcs_tune->reg != regptr) { + // Write out regval to previous register (if there was one) + if (regptr) { + if(dcs_reg_is_outside_dcs_block(regptr)) + dcs_reg_write(regptr, regval); + else + dcs_reg_write_all_chan(regptr, regval); + } + // read in the current register value (READ from CHAN zero, write to ALL CHAN) + regptr = dcs_tune->reg; + regval = *((uint32_t *)regptr); + } + // Modify the regval for the Bits indicated in the Mask + regval &= ~dcs_tune->mask; + regval |= dcs_tune->value; + } + // (Final) Write out regval to previous register (if there was one) + if (regptr) { + if(dcs_reg_is_outside_dcs_block(regptr)) + dcs_reg_write(regptr, regval); + else + dcs_reg_write_all_chan(regptr, regval); + } +#if SUB_PLATFORM_S8001 + if (dcs_cfg.chipRev < CHIP_REVISION_B0) + { + dcs_reg_write_all_chan(rDCS_MCU_ROWHAM_CTL(1), 0x4A3822D4); + } +#endif +} + + + + diff --git a/drivers/apple/dcs/include/drivers/dcs/dcs.h b/drivers/apple/dcs/include/drivers/dcs/dcs.h new file mode 100644 index 0000000..20f2d52 --- /dev/null +++ b/drivers/apple/dcs/include/drivers/dcs/dcs.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DCS_H +#define __DCS_H + +#include + +/* DRAM Control Subsystem (DCS) */ + +#define DCS_MAX_FREQUENCY_SLOTS 4 +#define DCS_NUM_FREQCHNGCTLREGS 6 + +#define DCS_FREQ(n) (1 << n) + +#define EXEC(_instructions) do { _instructions ; } while(0) +#define __abs(x) (((x) < 0) ? -(x) : (x)) + +typedef enum { + DCS_BOOT_COLDBOOT, + DCS_BOOT_RESUME, // "Classic Resume" is (AOP_DDR | AOP_AWAKE) + DCS_BOOT_AOP_DDR, + DCS_BOOT_AOP_AWAKE, +} dcs_boottype_t; + +typedef enum { + MR_READ, + MR_WRITE, + MR_MPC +} dcs_mrcmd_op_t; + +struct dcs_per_freq { + uint32_t clk_period; + uint32_t freqchngctl[DCS_NUM_FREQCHNGCTLREGS]; + uint32_t freqchngtim; + uint32_t lat; + uint32_t phyrdwrtim; + uint32_t caspch; + uint32_t act; + uint32_t autoref; + uint32_t selfref; + uint32_t pdn; + uint32_t derate; + uint32_t lat2; + uint32_t tat; + uint32_t mifqmaxctrl; + uint32_t nondqdspd; + uint32_t nondqds; + uint32_t cavref; + uint32_t odt_enable; + uint32_t dqds; + uint32_t dqdqsds; + uint32_t dqvref; + uint32_t cadficaltiming; + uint32_t dqdficaltiming; + uint32_t rddqcalwindow; + uint32_t wrdqcalwindow; + uint32_t caoutdllscl; + uint32_t dqsindllscl; + uint32_t rdcapcfg; + uint32_t autoref2; +}; + +typedef struct dcs_config_params { + uint32_t flags; + uint32_t supported_freqs; + uint32_t num_freqchngctl_regs; + uint32_t spllctrl_vco_1; + uint32_t spllctrl_vco_2; + uint32_t wrdqcalvrefcodecontrol; + uint32_t rddqcalvrefcodecontrol; + uint32_t rwcfg; + uint32_t phyupdatetimers; + uint32_t dllupdtctrl; + uint32_t dllupdtctrl1; + uint32_t pdn1; + uint32_t modereg; + uint32_t modereg1; + uint32_t autoref_params; + uint32_t autoref_params2; + uint32_t pdn; + uint32_t rnkcfg; + uint32_t cackcswkds; + uint32_t dqspdres; + uint32_t casdllupdatectrl; + uint32_t dqsdllupdatectrl; + uint32_t rdsdllctrl_step2; + uint32_t wrdqdqssdllctrl_step2; + uint32_t cawrlvlsdllcode; + uint32_t dlllocktim; + uint32_t dficaltiming; + uint32_t rdwrdqcaltiming_f0; + uint32_t rdwrdqcalseglen_f0; + uint32_t rdwrdqcaltiming_f1; + uint32_t rdwrdqcalseglen_f1; + uint32_t rdwrdqcaltiming_f3; + uint32_t rdwrdqcaltimingctrl1; + uint32_t rdwrdqcaltimingctrl2; + uint32_t rddqcalpatprbs4i; + uint32_t wrdqcalpatprbs4i; + uint32_t maxrddqssdllmulfactor; + uint32_t maxwrdqssdllmulfactor; + uint32_t dllupdtintvl; + uint32_t dcccontrol; + uint32_t dcccal; + uint32_t cbdrivestr; + uint32_t cbioctl; + uint32_t ckdrivestr; + uint32_t ckioctl; + uint32_t b0drivestr; + uint32_t b0ioctl; + uint32_t b0odt; + uint32_t b0odtctrl; + uint64_t b0dyniselasrtime; + uint64_t b0dynisel; + uint64_t b1dynisel; + uint32_t b1drivestr; + uint32_t b1ioctl; + uint32_t b1odt; + uint32_t b1odtctrl; + uint32_t dqs0drivestr; + uint32_t dqs0ioctl; + uint32_t dqs0odt; + uint32_t dqs0odtctrl; + uint32_t dqs0zdetbiasen; + uint32_t dqs1drivestr; + uint32_t dqs1ioctl; + uint32_t dqs1odt; + uint32_t dqs1odtctrl; + uint32_t dqs1zdetbiasen; + uint32_t zcalfsm0; + uint32_t zcalfsm1; + uint32_t spare0; + uint32_t hwrddqcaltvref; + uint32_t hwwrdqcaltvref; + uint32_t arefparam; + uint32_t odtszqc; + uint32_t longsr; + uint32_t freqchngctl_step3; + uint32_t mr3cmd; + uint32_t mr13cmd; + uint32_t addrcfg; + uint32_t aiuprtbaddr; + uint32_t chnldec; + uint32_t arefparam2; + uint32_t mr13cmd_step7; + uint32_t mr3cmd_step7; + uint32_t mr22cmd; + uint32_t mr11cmd; + uint32_t mr13cmd_step9; + uint32_t freqchngctl_step9; + uint32_t dqs0wkpupd; + uint32_t dqs1wkpupd; + uint32_t mr13cmd_step11; + uint32_t mr2cmd_step11; + uint32_t mr1cmd_step11; + uint32_t mr3cmd_step11; + uint32_t mr22cmd_step11; + uint32_t mr11cmd_step11; + uint32_t mr12cmd_step11; + uint32_t mr14cmd_step11; + uint32_t mr13cmd_step13; + uint32_t mr13cmd_step15; + uint32_t freqchngctl_step15; + uint32_t rdsdllctrl_step15; + uint32_t odtszqc2; + uint32_t qbren_step16; + uint32_t qbrparam; + uint32_t qbren; + uint32_t mccgen; + uint32_t caampclk; + uint32_t dqampclk; + uint32_t pwrmngten; + uint32_t odtszqc3; + struct dcs_per_freq freq[DCS_MAX_FREQUENCY_SLOTS]; +} dcs_config_params_t; + +typedef struct dcs_tunable { + volatile uintptr_t reg; + uint32_t mask; + uint32_t value; +} dcs_tunable_t; + +struct dcs_memory_device_info { + uint32_t vendor_id; + uint32_t rev_id; + uint32_t rev_id2; + uint32_t type; + uint32_t width; // Device width in Bytes + uint32_t density; // Device density in MBytes +}; + +// to write the same value to the register in all channels +void dcs_reg_write_all_chan(uintptr_t reg_addr, uint32_t reg_value); +bool dcs_reg_is_outside_dcs_block(uintptr_t reg_addr); +void dcs_mrcmd(dcs_mrcmd_op_t op, uint8_t channels, uint8_t ranks, int32_t reg, uintptr_t val); +void dcs_enable_slow_boot (bool enable); +void dcs_enable_autorefresh(void); +uint64_t dcs_get_memory_size(void); +const struct dcs_memory_device_info *dcs_get_memory_device_info(void); +volatile uint32_t *dcs_save_calibration_results(volatile uint32_t *save_region, uint32_t freq); +void dcs_restore_calibration_results(volatile uint32_t *save_region); +void dcs_lock_down_mcc(void); + +int32_t dcs_init(dcs_boottype_t boot_type); +#endif /* ! __DCS_H */ diff --git a/drivers/apple/dcs/include/drivers/dcs/dcs_cal.h b/drivers/apple/dcs/include/drivers/dcs/dcs_cal.h new file mode 100644 index 0000000..5f5ba26 --- /dev/null +++ b/drivers/apple/dcs/include/drivers/dcs/dcs_cal.h @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _DCS_CAL_H +#define _DCS_CAL_H + +#define AMP_FREQUENCY_SLOTS (4) + +/* _t: type, DQ0, DQ1, or CA */ +/* _c: channel, 0 or 1 */ +#define AMP_CA (0) +#define AMP_DQ0 (1) +#define AMP_DQ1 (2) + +#define rAMP_AMPEN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x000) +#define rAMP_AMPCLK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x004) +#define rAMP_AMPINIT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x008) +#define rAMP_AMPVER(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x00C) + +#define rAMP_IMPCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x080) +#define rAMP_IMPOVRRD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x084) +#define rAMP_IMPAUTOCAL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x088) +#define rAMP_IMPCALPHYUPDT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x08C) +#define rAMP_IMPCALCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x090) +#define rAMP_DRAMSIGDLY(_t,_c,_n) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x094 + ((_n) * 4)) +#define rAMP_NONDQDS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x098) +#define rAMP_DQDQSDS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x09C) +#define rAMP_DIFFMODE_FREQ(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x0A0 + ((_f) * 4)) +#define rAMP_DQFLTCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x0B0) + +#define rAMP_DQSPDENALWYSON(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x110) +#define rAMP_DQSPDRES(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x114) +#define rAMP_RDFIFOPTRSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x118) +#define rAMP_CALDQMSK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x11C) +#define rAMP_DQTRNCFG(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x124 - ((_t >> 1) * 0x10)) +#define rAMP_DQTRNCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x128 - ((_t >> 1) * 0x10)) +#define rAMP_DQTRNSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x12C - ((_t >> 1) * 0x10)) + +#define rAMP_DLLEN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x180) +#define rAMP_MDLLOVRRD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x188 + ((_t >> 1) * 4)) + +#define rAMP_DLLLOCKTIM(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x198) +#define rAMP_DLLLOCKCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x19C) +#define rAMP_DLLUPDTINTVL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1A0) +#define rAMP_DLLUPDTCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1A4) +#define rAMP_DLLSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1A8) +#define rAMP_DQSINDLLSCL_FREQ(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1C0 + ((_f) * 4)) +#define rAMP_CAOUTDLLSCL_FREQ(_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x1C0 + ((_f) * 4)) +// +#define rAMP_TESTMODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x200 + ((_t >> 1) * 0x180)) + +#define rAMP_CKEDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x52C) + +#define rAMP_DQWRLVLDLYCHAINCTRL(_t,_c,_b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x704 + ((_b)*0x04)) +#define rAMP_DQWRLVLRUN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x714) +#define rAMP_DQWRLVLDATA(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x718) + + +#define rAMP_CACALMASK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x804) +#define rAMP_CACALCABYTESEL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x808) +#define rAMP_CACALCAMAP0(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x80C) +#define rAMP_CACALCAMAP1(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x810) +#define rAMP_CACALCAMAP2(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x814) +//#define rAMP_CACALRUN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x838 + ((_t >> 1) * 0xEC)) +// CP : Maui Change +//#define rAMP_CACALRESULT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x83C) + + +#define rAMP_CAPHYUPDTREQ(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xB00) +#define rAMP_CAPHYUPDTSTATUS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xB04) +#define rAMP_DLLUPDTCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x18C) + +// Some bit definitions +// CP : Maui Change +#define CACALRUN_CACALMODE 1 +#define rAMP_CACACALVREF(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x908) +#define rAMP_CACALBITSELECT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x918) +#define CS_TRAINING 0 +#define CA_TRAINING 1 +#define CS_FINE_TRAINING 2 +#define RUN_DLL_UPDT 0 + +#define CACALRUN_RUNCACALENTRY (1 << 0) +#define CACALRUN_RUNCACALCS (1 << 4) +#define CACALRUN_RUNCACALCA (1 << 8) +#define CACALRUN_RUNCACALEXIT (1 << 12) +#define CACALRUN_RUNCACALVREF (1 << 16) +#define rAMP_CACALRESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x91C) +#define rAMP_CACALRUN(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x924) +#define rAMP_CACALCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x900) +#define rAMP_CACALCTRL2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x904) +#define rAMP_CACALCTRL3(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x928) +#define rAMP_CACALPAT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x90C) +#define rAMP_CASDLLCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x700) +#define rAMP_CASDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x704) +#define rAMP_CKSDLLCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x710) +#define rAMP_CKSDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x714) +#define rAMP_CSSDLLCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x708) +#define rAMP_CSSDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x70C) +#define rAMP_AMPCACALENTRYCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x910) +#define rAMP_AMPCACALEXITCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x914) +#define rAMP_MDLLCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x194) +#define rAMP_CKDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x51C) +#define rAMP_CADESKEW_CTRL(_c,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x500 + ((_d)*4)) +#define rAMP_CSDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x518) +#define rAMP_RDWRDQCALLOOPCNT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE20) +#define rAMP_RUNRDDQCAL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE58) +#define rAMP_CALPATCFG(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x110) +#define rAMP_DQSDLLCTRL_RD(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x608) +#define rAMP_DQSDLLCODE_RD(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x60C) +#define rAMP_RDDQDESKEW_CTRL(_b,_c,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x428 + ((_d)*4)) +#define rAMP_RDDQSDESKEW_CTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x448) +#define rAMP_RDDMDESKEW_CTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x44C) +#define rAMP_DQCALCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x900) +#define rAMP_DQCALRUN(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE58) +#define rAMP_DQCALRESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE5C) +#define rAMP_RDCLKDLYSEL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x618) + +#define rAMP_RDDQCALPAT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE2C) +#define rAMP_RdWrDqCalTiming_f0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE00) +#define rAMP_RdWrDqCalTiming_f1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE08) +#define rAMP_RdWrDqCalTiming_f2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE10) +#define rAMP_RdWrDqCalTiming_f3(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE18) +#define rAMP_RdWrDqCalTimingCtrl2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE28) +#define rAMP_RDDQCALVREF_f0(_t, _c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0xB00) +#define rAMP_RDDQCALVREF_f1(_t, _c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0xB04) + +#define rAMP_CAWRLVLSDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x800) +#define rAMP_CAWRLVLENTRYCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB00) +#define rAMP_CAWRLVLEXITCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB04) +#define rAMP_CAWRLVLTIM(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB08) +#define rAMP_CARUNWRLVL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB0C) +#define rAMP_CAWRLVLRESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB10) +#define rAMP_AMPSDQIOCFG_DQFLTCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0xA4) + +#define rAMP_DQWRLVLSDLLCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x704) + +#define rAMCX_DRAMCFG_FREQCHNGMRWCNT(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x44C) + +#define rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x450) +#define rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x454) + +#define rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x468) +#define rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x46C) + +#define RUNDESKEWUPD (1 << 8) + +#define rAMP_WRDQCALPAT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE30) +#define rAMP_WRDQSDQ_SDLLCTRL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x600) +#define rAMP_WRDQSDQ_SDLLCODE(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x604) +#define rAMP_WRDQ_CAL_RUN(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE60) +#define rAMP_WRDQ_CAL_RESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE64) +#define rAMP_WRDQCALVREF(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x908) +#define rAMP_WRDQDESKEW_CTRL(_b,_c,_t) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x400 + ((_t)*4)) +#define rAMP_WRDQSDESKEW_CTRL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x420) +#define rAMP_WRDMDESKEW_CTRL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x424) + +#define rAMP_CAMDLL_VTSCL_REFCNTL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x1D4) +#define rAMP_RDMDLL_VTSCL_REFCNTL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x1D8) +#define rAMP_WRMDLL_VTSCL_REFCNTL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x1D8) + +#define rAMP_RDCAPCFG_FREQ(_c, _b, _f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x100 + ((_f) * 4)) +#define rAMP_DQSPDENALWAYSON(_c, _b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x110) + +#if DCS_REG_VERSION == 2 +#define rAMPH_CFGH_DQS0_WKPUPD(_c) (AMP_H_BASE_ADDR + ((_c)*AMP_SPACING)+ 0x0C8) +#define rAMPH_CFGH_DQS1_WKPUPD(_c) (AMP_H_BASE_ADDR + ((_c)*AMP_SPACING)+ 0x138) + +#define F0_IDLE_ACTIVE_MASK 0xFFFEFFF7 +#define F0_IDLE_ACTIVE_OFFSET 16 +#define F1_IDLE_ACTIVE_MASK 0xFFFDFFF7 +#define F1_IDLE_ACTIVE_OFFSET 17 +#define F1_PDPWK_OFFSET 3 +#define DESKEW_CODE_MASK 0x3F +#endif // #if DCS_REG_VERSION == 2 + +#define RUNWRLVLENTRY_OFFSET 0 +#define RUNWRLVLDQ_OFFSET 1 +#define RUNWRLVLEXIT_OFFSET 3 +#define RUNWRLVLLOOPCNT_OFFSET 8 +#define RUNWRLVLMASK_OFFSET 16 +#define RUNWRLVL_SDLLUPDOVR 8 +#define RUNWRLVL_SDLLUPDWRRES 9 +#define WRLVL_SDLLCODE_MASK 0xFFFFFF00 +#define WRLVLMAX_SDLLCODE_MASK 0xFF00FFFF +#define WRLVL_SDLLCODE_OFFSET 0 +#define WRLVLMAX_SDLLCODE_OFFSET 16 +#define DQS_IDLE_ACTIVE_MASK 0xFFFFFFEF +#define DQS_IDLE_ACTIVE_OFFSET 4 + +#define WRLVL_RESULT 0 +#define WRLVL_CNT0_OFFSET 8 +#define WRLVL_CNT1_OFFSET 16 + +#define SDLLOFFSET 16 +#define RUN_SDLLUPDOVR 1 +#define RUN_SDLLUPDWRRES 2 + +#define WR_DQ_SDLL_OFFSET 16 +#define WR_DQS_SDLL_OFFSET 24 +#define WR_SDLLUPDOVR 1 +#define WR_SDLLUPDWRRES 2 +#define WR_ALL_BITS_PASS 0xFFFF +#define WR_ALL_BITS_FAIL 0x0 +#define WR_CALIB_RUN 0 +#define WR_DQS_SDLL_CODE_OFFSET 8 + +#define VT_SCL_REF_MASK 0x3FF +#define VT_SCL_REF_BITS 10 +#define VT_SCL_OVR_OFFSET 16 +#define VT_SCL_REF_UPD_OFFSET 28 + +#define DQS_PDEN_OFFSET 24 +#define DQS_PDEN_MASK 0xFEFFFFFF +#define DQSPDEN_ALWAYSON_OFFSET 0 +#define DQSPDEN_ALWAYSON_MASK 0x1 + +#define MAX_SDLL_OFFSET + +#define TESTMODE_FORCECKELOW (1 << 8) + +#define SIGN_BIT_POS (6) + +#define AMP_MAX_RANKS_PER_CHAN (2) + +#endif /* _DCS_CAL_H */ diff --git a/drivers/apple/dcs/include/drivers/dcs/dcs_cal_v2.h b/drivers/apple/dcs/include/drivers/dcs/dcs_cal_v2.h new file mode 100644 index 0000000..c098aac --- /dev/null +++ b/drivers/apple/dcs/include/drivers/dcs/dcs_cal_v2.h @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _DCS_CAL_H +#define _DCS_CAL_H + +#define AMP_FREQUENCY_SLOTS (4) + +/* _t: type, DQ0, DQ1, or CA */ +/* _c: channel, 0 or 1 */ +#define AMP_CA (0) +#define AMP_DQ0 (1) +#define AMP_DQ1 (2) + +#define rAMP_AMPEN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x000) +#define rAMP_AMPCLK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x004) +#define rAMP_AMPINIT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x008) +#define rAMP_AMPVER(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x00C) + +#define rAMP_IMPCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x080) +#define rAMP_IMPOVRRD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x084) +#define rAMP_IMPAUTOCAL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x088) +#define rAMP_IMPCALPHYUPDT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x08C) +#define rAMP_IMPCALCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x090) +#define rAMP_DRAMSIGDLY(_t,_c,_n) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x094 + ((_n) * 4)) +#define rAMP_NONDQDS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x098) +#define rAMP_DQDQSDS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x09C) +#define rAMP_DIFFMODE_FREQ(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x0A0 + ((_f) * 4)) +#define rAMP_DQFLTCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x0B0) + +#define rAMP_DQSPDENALWYSON(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x110) +#define rAMP_DQSPDRES(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x114) +#define rAMP_RDFIFOPTRSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x118) +#define rAMP_CALDQMSK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x11C) +#define rAMP_DQTRNCFG(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x124 - ((_t >> 1) * 0x10)) +#define rAMP_DQTRNCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x128 - ((_t >> 1) * 0x10)) +#define rAMP_DQTRNSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x12C - ((_t >> 1) * 0x10)) + +#define rAMP_DLLEN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x180) +#define rAMP_MDLLOVRRD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x188 + ((_t >> 1) * 4)) + +#define rAMP_DLLLOCKTIM(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x198) +#define rAMP_DLLLOCKCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x19C) +#define rAMP_DLLUPDTINTVL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1A0) +#define rAMP_DLLUPDTCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1A4) +#define rAMP_DLLSTS(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1A8) +#define rAMP_DQSINDLLSCL_FREQ(_t,_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x1C0 + ((_f) * 4)) +#define rAMP_CAOUTDLLSCL_FREQ(_c,_f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x1C0 + ((_f) * 4)) +// +#define rAMP_TESTMODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x200 + ((_t >> 1) * 0x180)) + +#define rAMP_CKEDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0x52C) + +#define rAMP_DQWRLVLDLYCHAINCTRL(_t,_c,_b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x704 + ((_b)*0x04)) +#define rAMP_DQWRLVLRUN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x714) +#define rAMP_DQWRLVLDATA(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x718) + + +#define rAMP_CACALMASK(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x804) +#define rAMP_CACALCABYTESEL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x808) +#define rAMP_CACALCAMAP0(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x80C) +#define rAMP_CACALCAMAP1(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x810) +#define rAMP_CACALCAMAP2(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x814) +//#define rAMP_CACALRUN(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x838 + ((_t >> 1) * 0xEC)) +// CP : Maui Change +//#define rAMP_CACALRESULT(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x83C) + + +#define rAMP_CAPHYUPDTREQ(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xB00) +#define rAMP_CAPHYUPDTSTATUS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + AMP_CA_SPACING + 0xB04) +#define rAMP_DLLUPDTCMD(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x18C) + +// Some bit definitions +// CP : Maui Change +#define CACALRUN_CACALMODE 1 +#define rAMP_CACACALVREF(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x908) +#define rAMP_CACALBITSELECT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x918) +#define CS_TRAINING 0 +#define CA_TRAINING 1 +#define CS_FINE_TRAINING 2 +#define RUN_DLL_UPDT 0 + +#define CACALRUN_RUNCACALENTRY (1 << 0) +#define CACALRUN_RUNCACALCS (1 << 4) +#define CACALRUN_RUNCACALCA (1 << 8) +#define CACALRUN_RUNCACALEXIT (1 << 12) +#define CACALRUN_RUNCACALVREF (1 << 16) +#define rAMP_CACALRESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x91C) +#define rAMP_CACALRUN(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x924) +#define rAMP_CACALCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x900) +#define rAMP_CACALCTRL2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x904) +#define rAMP_CACALCTRL3(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x928) +#define rAMP_CACALPAT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x90C) +#define rAMP_CASDLLCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x700) +#define rAMP_CASDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x704) +#define rAMP_CKSDLLCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x710) +#define rAMP_CKSDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x714) +#define rAMP_CSSDLLCTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x708) +#define rAMP_CSSDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x70C) +#define rAMP_AMPCACALENTRYCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x910) +#define rAMP_AMPCACALEXITCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x914) +#define rAMP_MDLLCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t)*AMP_DQ_SPACING) + 0x194) +#define rAMP_CKDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x51C) +#define rAMP_CADESKEW_CTRL(_c,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x500 + ((_d)*4)) +#define rAMP_CSDESKEW_CTRL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x518) +#define rAMP_RDWRDQCALLOOPCNT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE20) +#define rAMP_RUNRDDQCAL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE58) +#define rAMP_CALPATCFG(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x110) +#define rAMP_DQSDLLCTRL_RD(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x608) +#define rAMP_DQSDLLCODE_RD(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x60C) +#define rAMP_RDDQDESKEW_CTRL(_b,_c,_d) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x428 + ((_d)*4)) +#define rAMP_RDDQSDESKEW_CTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x448) +#define rAMP_RDDMDESKEW_CTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x44C) +#define rAMP_DQCALCTRL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x900) +#define rAMP_DQCALRUN(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE58) +#define rAMP_DQCALRESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE5C) +#define rAMP_RDCLKDLYSEL(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x618) + +#define rAMP_RDDQCALPAT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE2C) +#define rAMP_RdWrDqCalTiming_f0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE00) +#define rAMP_RdWrDqCalTiming_f1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE08) +#define rAMP_RdWrDqCalTiming_f2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE10) +#define rAMP_RdWrDqCalTiming_f3(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE18) +#define rAMP_RdWrDqCalTimingCtrl2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE28) +#define rAMP_RDDQCALVREF_f0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xD10) +#define rAMP_RDDQCALVREF_f1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xD14) + +#define rAMP_DQCAL_BURSTLEN_MODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xF10) + +#define rAMP_CAWRLVLSDLLCODE(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x800) +#define rAMP_CAWRLVLENTRYCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB00) +#define rAMP_CAWRLVLEXITCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB04) +#define rAMP_CAWRLVLTIM(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB08) +#define rAMP_CARUNWRLVL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB0C) +#define rAMP_CAWRLVLRESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xB10) +#define rAMPH_CFGH_DQS0_WKPUPD(_c) (AMP_H_BASE_ADDR + ((_c)*AMP_SPACING)+ 0x0C8) +#define rAMPH_CFGH_DQS1_WKPUPD(_c) (AMP_H_BASE_ADDR + ((_c)*AMP_SPACING)+ 0x138) +#define rAMPH_CFGH_CABIST_BISTRDFIFOCTRL(_c) (AMP_H_BASE_ADDR + ((_c)*AMP_SPACING)+ 0x164) +#define rAMP_CACALPATSEED_0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x92C) +#define rAMP_CACALPATSEED_1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x930) + +#define rAMP_DQWRLVLSDLLCODE(_t,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_t + 1)*AMP_DQ_SPACING) + 0x704) + +#define rAMCX_DRAMCFG_FREQCHNGMRWCNT(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x44C) + +#define rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x450) +#define rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x454) + +#define rAMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x468) +#define rAMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(_c) (DCS_BASE_ADDR + ((_c)*DCS_SPACING) + 0x46C) + +#define RUNDESKEWUPD (1 << 8) + +#define rAMP_WRDQCALPAT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE30) +#define rAMP_WRDQSDQ_SDLLCTRL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x600) +#define rAMP_WRDQSDQ_SDLLCODE(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x604) +#define rAMP_WRDQ_CAL_RUN(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE60) +#define rAMP_WRDQ_CAL_RESULT(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xE64) +#define rAMP_WRDQCALVREF(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x908) +#define rAMP_WRDQDESKEW_CTRL(_b,_c,_t) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x400 + ((_t)*4)) +#define rAMP_WRDQSDESKEW_CTRL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x420) +#define rAMP_WRDMDESKEW_CTRL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x424) + +#define rAMP_CAMDLL_VTSCL_REFCNTL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x1D4) +#define rAMP_RDMDLL_VTSCL_REFCNTL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x1D8) +#define rAMP_WRMDLL_VTSCL_REFCNTL(_b,_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x1D8) + +#define rAMP_RDCAPCFG_FREQ(_c, _b, _f) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x100 + ((_f) * 4)) +#define rAMP_DQSPDENALWAYSON(_c, _b) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + ((_b + 1)*AMP_DQ_SPACING) + 0x110) + +#define rAMP_CALPATPRBS7_0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEA0) +#define rAMP_CALPATPRBS7_1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEA4) +#define rAMP_CALPATPRBS7_2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEA8) +#define rAMP_CALPATPRBS7_3(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEAC) + +#define rAMP_CACALPATSEED_0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x92C) +#define rAMP_CACALPATSEED_1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x930) + +#define rAMP_WRDQCALPATSEED_B0_0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEB4) +#define rAMP_WRDQCALPATSEED_B0_1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEB8) +#define rAMP_WRDQCALPATSEED_B0_2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEBC) +#define rAMP_WRDQCALPATSEED_B1_0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEC0) +#define rAMP_WRDQCALPATSEED_B1_1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEC4) +#define rAMP_WRDQCALPATSEED_B1_2(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xEC8) +#define rAMP_WRDQCAL_NC_CONVERSION_THRESHOLD_F0(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xED0) +#define rAMP_WRDQCAL_NC_CONVERSION_THRESHOLD_F1(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xED4) +#define rAMP_WRDQCALVREFCODECONTROL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xF20) +#define rAMP_WRDQCALVREFCODESTATUS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xF24) +#define rAMP_RDDQCALVREFCODECONTROL(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xF18) +#define rAMP_RDDQCALVREFCODESTATUS(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0xF1C) +#define rAMP_CA_IMPCALCMD(_c) (AMP_BASE_ADDR + ((_c)*AMP_SPACING) + 0x094) + +#define RUNIMPCAL_OFFSET 0 +#define RUNIMPCAL_MASK 0xFFFFFFFE + +#define RUNWRLVLENTRY_OFFSET 0 +#define RUNWRLVLDQ_OFFSET 1 +#define RUNWRLVLEXIT_OFFSET 3 +#define RUNWRLVLLOOPCNT_OFFSET 8 +#define RUNWRLVLMASK_OFFSET 16 +#define RUNWRLVL_SDLLUPDOVR 8 +#define RUNWRLVL_SDLLUPDWRRES 9 +#define WRLVL_SDLLCODE_MASK 0xFFFFFF00 +#define WRLVLMAX_SDLLCODE_MASK 0xFF00FFFF +#define WRLVL_SDLLCODE_OFFSET 0 +#define WRLVLMAX_SDLLCODE_OFFSET 16 +#define DQS_IDLE_ACTIVE_MASK 0xFFFFFFEF +#define DQS_IDLE_ACTIVE_OFFSET 4 +#define RUNRDDQCAL_WRFIFO_MASK 0xFFFFEFFF +#define RUNRDDQCAL_WRFIFO_OFFSET 12 +#define HALF_CLK_OVRVAL_MASK 0xFFFFF3FF +#define HALF_CLK_OVRVAL_OFFSET 10 +#define NC_THRESHOLD0_OFFSET 0 +#define NC_THRESHOLD1_OFFSET 8 +#define NC_THRESHOLD_MASK 0x3F +#define WRLVL_RESULT 0 +#define WRDQ_VREF_F1_OFFSET 8 +#define WRDQ_VREF_F0_OFFSET 0 +#define WRDQ_VREF_F1_MASK 0xFFFF00FF +#define WRDQ_VREF_F0_MASK 0xFFFFFF00 +#define RDDQ_VREF_F1_OFFSET 8 +#define RDDQ_VREF_F0_OFFSET 0 +#define RDDQ_VREF_F1_MASK 0xFFFF00FF +#define RDDQ_VREF_F0_MASK 0xFFFFFF00 + +#define WRLVL_CNT0_OFFSET 8 +#define WRLVL_CNT1_OFFSET 16 + +#define SDLLOFFSET 16 +#define RUN_SDLLUPDOVR 1 +#define RUN_SDLLUPDWRRES 2 + +#define WR_DQ_SDLL_OFFSET 16 +#define WR_DQS_SDLL_OFFSET 24 +#define WR_SDLLUPDOVR 1 +#define WR_SDLLUPDWRRES 2 +#define WR_ALL_BITS_PASS 0xFFFF +#define WR_ALL_BITS_FAIL 0x0 +#define WR_CALIB_RUN 0 +#define WR_DQS_SDLL_CODE_OFFSET 8 + +#define VT_SCL_REF_MASK 0x3FF +#define VT_SCL_REF_BITS 10 +#define VT_SCL_OVR_OFFSET 16 +#define VT_SCL_REF_UPD_OFFSET 28 + +#define DQS_PDEN_OFFSET 24 +#define DQS_PDEN_MASK 0xFEFFFFFF +#define DQSPDEN_ALWAYSON_OFFSET 0 +#define DQSPDEN_ALWAYSON_MASK 0x1 +#define DESKEW_CODE_MASK 0x3F + +#define RDDQCAL_BURSTLEN_MODE_MASK 0xFFFFFFFE +#define RDDQCAL_BURSTLEN_MODE_OFFSET 0 + +#define F0_IDLE_ACTIVE_MASK 0xFFFEFFFF +#define F0_IDLE_ACTIVE_OFFSET 16 +#define F1_IDLE_ACTIVE_MASK 0xFFFDFFFF +#define F1_IDLE_ACTIVE_OFFSET 17 +#define F3_IDLE_ACTIVE_MASK 0xFFF7FFFF +#define F3_IDLE_ACTIVE_OFFSET 19 + +#define F0_WEAK_PD_MASK 0xFFFFFFFD +#define F0_WEAK_PD_OFFSET 1 +#define F1_WEAK_PD_MASK 0xFFFFFFF7 +#define F1_WEAK_PD_OFFSET 3 +#define F3_WEAK_PD_MASK 0xFFFFFF7F +#define F3_WEAK_PD_OFFSET 7 + +#define CACAL_DQS_PULSE_CNT_OFFSET 16 +#define CACAL_DQS_PULSE_WIDTH_OFFSET 20 + +#define BIST_RDFIFO_RESET_MASK 0xFFFFFFFD +#define BIST_RDFIFO_RESET_OFFSET 1 + +#define MAX_SDLL_OFFSET + +#define TESTMODE_FORCECKELOW (1 << 8) + +#define SIGN_BIT_POS (6) + +#define AMP_MAX_RANKS_PER_CHAN (2) + +#endif /* _DCS_CAL_H */ diff --git a/drivers/apple/dcs/include/drivers/dcs/dcs_calibration.h b/drivers/apple/dcs/include/drivers/dcs/dcs_calibration.h new file mode 100644 index 0000000..9a53001 --- /dev/null +++ b/drivers/apple/dcs/include/drivers/dcs/dcs_calibration.h @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCS_CALIBRATION_H +#define __DCS_CALIBRATION_H + +#ifdef ENV_IBOOT + +// Calibration registers +#if DCS_REG_VERSION < 3 +#include +#else +#include +#endif + +#endif + +// Chip rev definitions for non-iBoot environments +#ifndef ENV_IBOOT +#define CHIP_REVISION_A0 0x00 +#define CHIP_REVISION_A1 0x01 +#define CHIP_REVISION_B0 0x10 +#define CHIP_REVISION_B1 0x11 +#define CHIP_REVISION_C0 0x20 +#define CHIP_REVISION_C1 0x21 +#endif + +#define AMP_DQ_PER_CHAN 2 + +#define AMP_MAX_PATTERNS 8 + +#define CALIB_SAVE 0 +#define CALIB_RESTORE 1 +#define CALIB_PMU_BYTES 400 +// 1 CASDLL (8 bits), 1 CKSDLL (8 bits), 1 CSSDLL (8 bits), 6 CA bit deskews (6 bits * 6), CK/CS deskew (6 bits * 2), 3 WrLvl SDLLs (8 bits * 3) +// WRDQ SDLLs (2 * 8 bits), WRDQS SDLLs (2 * 8 bits), WR DQ deskew (2 * 8 * 6 bits), WR DQS deskew ( 2 * 6 bits), WR DM deskew (2 * 6 bits) +// 3 WrLvl SDLLs (8 bits * 3) after WRDQ calibration +// RD SDLLs (2 * 8 bits), RD deskew (2 * 8 * 6 bits), RD DMI deskew (2 * 6 bits) +// Optimal Vref for CA, RD & WR for bins 0 & 1 (3 * 2 * 6 bits) +// VT scaling refence codes for CA, RD and WR for both DQ splits ( 3 * 2 * 10 bits) +// Total bits per channel = 24 +36 + 12 + 24 + 16 + 16 + 96 + 12 + 12 + 24 + 16 + 96 + 12 + 36 + 60 = 492 bits + +// TODO: Recalculate this (somehow! --> better: sizeof(struct) ) +#define CALIB_NUM_BYTES_TO_SAVE (DCS_NUM_CHANNELS * (62)) + +// CP Changed +#define CA_NUM_BITS 6 +#define CA_ALL_BITS ((1 << CA_NUM_BITS) - 1) + +#if DCS_REG_VERSION < 3 +#define CA_NUM_VREF_F0 10 +#define RDDQ_NUM_VREF_F0 10 +#define CA_NUM_VREF_F1 21 +#define RDDQ_NUM_VREF_F1 26 +#define CA_NUM_VREF_MAX ((CA_NUM_VREF_F0 > CA_NUM_VREF_F1) ? CA_NUM_VREF_F0 : CA_NUM_VREF_F1) +#define RDDQ_NUM_VREF_MAX ((RDDQ_NUM_VREF_F0 > RDDQ_NUM_VREF_F1) ? RDDQ_NUM_VREF_F0 : RDDQ_NUM_VREF_F1) + +#else +#define CA_NUM_VREF 10 +#define RDDQ_NUM_VREF 10 +#endif // #if DCS_REG_VERSION < 3 + +#define WRDQ_NUM_VREF 10 + +#define CA_NUM_PATTERNS 64 +// +#define DELIMIT_POS_ADJ_CASDLL 6 +#define DELIMIT_POS_ADJ_WRDQSDLL 6 + +#define MR_READ 0 +#define MR_WRITE 1 + +#define MR0 0x0 +#define MR2 0x02 +#define MR5 0x05 +#define MR12 0x0C +#define MR13 0x0D +#define MR14 0x0E +#define MR15 0x0F +#define MR20 0x14 +#define MR32 0x20 +#define MR40 0x28 +#define MR41 0x29 +#define MR42 0x2A +#define MR48 0x30 + +#define MIN_ENDPT 0 +#define MAX_ENDPT 1 + +#if DCS_REG_VERSION == 1 +#define MAX_DESKEW_PROGRAMMED 31 +#define MAX_SDLL_VAL 203 +#else +#define MAX_DESKEW_PROGRAMMED 55 +#if DCS_REG_VERSION == 2 +#define MAX_SDLL_VAL 248 +#else +#define MAX_SDLL_VAL 204 +#endif // #if DCS_REG_VERSION == 2 +#endif // #if DCS_REG_VERSION == 1 + +#define MIN_SDLL_VAL 0 +#define FINER_STEP_SZ 1 +#define COARSE_STEP_SZ 4 +#define SOLID_PASS_DETECT 8 +#define SOLID_PASS_ZONE_DETECT 4 +#define SOLID_FAIL 2 +#define DLLVAL_BITS 0xFF +#define DESKEW_CTRL_BITS 0x3F +#define SDLL_NUM_BITS 8 +#define DESKEW_NUM_BITS 6 +#define CA_WRDQ_VREF_CTRL_BITS 0x7F +#define CA_WRDQ_VREF_NUM_BITS 7 +#define RDDQ_VREF_CTRL_BITS 0xFF +#define RDDQ_VREF_NUM_BITS 8 +#define RD_LATENCY_ENCODE 26 + +#define MAX_DQWRLVL_CODE 127 +#define DQ_NUM_PATTERNS 128 +// The number of bytes below is consecutive for a given ch, rnk, bank, and row (interleaving starts after these bytes) +//#define DQ_CONSECUTIVE_BYTES_PER_CHRNK 256 +#define DQ_BYTES_PER_COL 4 // That makes for 64 consecutive columns (or words) +// the bank and row numbers where patterns will be written +#define DQ_ROW 0 +#define DQ_BANK 0 +#define DQ_ADDR_RANK_BIT 16 // RIBI2 addressing for dual rank devices + +// Calibration operation selection +#define SELECT_CACAL 0x1 +#define SELECT_WRLVLCAL 0x2 +#define SELECT_RDDQCAL 0x4 +#define SELECT_WRDQCAL 0x8 +#define SELECT_CAL_ALL 0xF + +// This defintion is put here for non-iBoot compilation environments +#ifndef __abs +#define __abs(x) (((x) < 0) ? -(x) : (x)) +#endif + +#if DCS_REG_VERSION < 2 +#define DQ_MAX_DESKEW_PER_BIT 47 +#else +#define DQ_MAX_DESKEW_PER_BIT 55 +#endif + +// maximum possible loops in the hw +#define RDDQ_LOOPCNT 16 +#define DQ_NUM_BYTES 2 +#define DQ_NUM_BYTES_PER_DQ 1 +#define DQ_NUM_BITS_PER_BYTE 8 +#define DQ_TOTAL_BITS (DQ_NUM_BYTES * DQ_NUM_BITS_PER_BYTE) +#define DMI_TOTAL_BITS 2 +#define DMI_NUM_BITS_PER_BYTE 1 + +#if DCS_REG_VERSION == 2 +#define MAX_CAWRLVL_CODE 52 +#else +#define MAX_CAWRLVL_CODE 47 +#endif // #if DCS_REG_VERSION == 2 + +#define CLK_PERIOD_NUMER (1000000) +#define CLK_PERIOD_OF(_freq_in_mhz) (CLK_PERIOD_NUMER / (_freq_in_mhz)) + +#define CLK_PERIOD_1600 CLK_PERIOD_OF(1600) // 625 +#define CLK_PERIOD_1200 CLK_PERIOD_OF(1200) // 833 +#define CLK_PERIOD_800 CLK_PERIOD_OF(800) // 1250 + +void calibration_ca_rddq_wrlvl(bool resume); +void calibration_wrdq_rddq(bool resume); +void calibration_save_restore_ca_wrlvl_regs(uint32_t save_or_restore, uint32_t channels, bool freq_bin); +void calibration_dump_results(uint32_t operations, bool dump_passing_window); + +struct amp_calibration_params { + uint32_t chip_id; + uint32_t chip_rev; + uint32_t num_channels; + uint32_t num_channels_runCalib; + uint32_t num_ranks; + uint32_t clk_period_bin0; + uint32_t clk_period_bin1; + +#if DCS_REG_VERSION < 3 + uint32_t ca_num_vref_f0; + uint32_t rddq_num_vref_f0; + uint32_t ca_num_vref_f1; + uint32_t rddq_num_vref_f1; +#else + uint32_t ca_num_vref; + uint32_t rddq_num_vref; +#endif // #if DCS_REG_VERSION < 3 + + uint32_t wrdq_num_vref; + + bool wrdq_apply_NC_algorithm; + +#if DCS_REG_VERSION < 3 + uint32_t ca_vref_values_f0[CA_NUM_VREF_F0]; + uint32_t rddq_vref_values_f0[RDDQ_NUM_VREF_F0]; + uint32_t ca_vref_values_f1[CA_NUM_VREF_F1]; + uint32_t rddq_vref_values_f1[RDDQ_NUM_VREF_F1]; +#else + uint32_t ca_vref_values[CA_NUM_VREF]; + uint32_t rddq_vref_values[RDDQ_NUM_VREF]; +#endif + + uint32_t wrdq_vref_values[WRDQ_NUM_VREF]; + + bool resume; + bool disable_coarse_cs_training; + uint32_t opt_vref_mode; // Use CoM or "Widest Span" method? + uint32_t cacalib_hw_loops; + uint32_t cacalib_sw_loops; + uint32_t cacalib_dqs_pulse_cnt; + uint32_t cacalib_dqs_pulse_width; + uint32_t rddq_cal_loopcnt; + uint32_t wrdq_cal_loopcnt; + uint32_t rddq_legacy_mode; + uint32_t wrdq_legacy_mode; + uint32_t cacal_bit_sel[8]; + uint32_t cacal_rd_byte_sel; + uint32_t ca_prbs4_pattern; + uint32_t prbs7_pattern_0; + uint32_t prbs7_pattern_1; + uint32_t prbs7_pattern_2; + uint32_t prbs7_pattern_3; + uint32_t ca_prbs_seed_bit[CA_NUM_BITS]; + uint32_t wrdq_prbs_seed[DQ_NUM_BYTES][DQ_NUM_BITS_PER_BYTE + DMI_NUM_BITS_PER_BYTE]; + uint32_t ca_invert_mask; + uint32_t CsStopCycleCnt; + uint32_t CsActiveCycleCnt; + uint32_t tADR, tMRD, tCAENT, tVREF_LONG, tCKELCK, tCKCKEH, tDSTrain; + uint32_t tWLO; + uint32_t tWLMRD; + uint32_t tWLDQSEN; + uint32_t tDQSCKE; + uint32_t tCKEHCMD; + uint32_t WrLvlDqsPulseCnt; + int freq_bin; + int RL; + int WL; + + // SEG specific flags + bool dv_params_valid; // DV flag + bool dv_randomize; // flag to be used by DV to randomize some register values for DV purposes + uint32_t dbg_calib_mode; // flag to be used by SEG to skip calibration operations for debug purposes +}; + +#define DCS_CAL_OPT_VREF_MODE_WIDEST 0 +#define DCS_CAL_OPT_VREF_MODE_COM 1 + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// API Functions +//////////////////////////////////////////////////////////////////////////////////////////////////////// +struct amp_calibration_params *calibration_cfg_params_init(int bootMode, int numChans, int numRanksPerChn); + +void calibrate_ca(void); +void calibrate_wrlvl(void); +void calibrate_wrdq(void); +void calibrate_rddq(void); + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +#endif /* ! __DCS_CALIBRATION_H */ +//////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/drivers/apple/dcs/include/drivers/dcs/dcs_init_lib.h b/drivers/apple/dcs/include/drivers/dcs/dcs_init_lib.h new file mode 100644 index 0000000..6b30c3d --- /dev/null +++ b/drivers/apple/dcs/include/drivers/dcs/dcs_init_lib.h @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DCS_INIT_LIB_H +#define __DCS_INIT_LIB_H + +/* DRAM Control Subsystem (DCS) Initialization Library API Definitions */ + +//================================================================================ +// Build (Environment) Type: iBoot, SiVal, DV, PE-RTOS +//================================================================================ +#define DCS_BUILD_ENV_IBOOT (0) +#define DCS_BUILD_ENV_SIVAL (1) +#define DCS_BUILD_ENV_DV (2) +#define DCS_BUILD_ENV_PERTOS (3) + +#define izIBOOT (DCS_BUILD_ENV_TYPE == DCS_BUILD_ENV_IBOOT) +#define izSIVAL (DCS_BUILD_ENV_TYPE == DCS_BUILD_ENV_SIVAL) +#define izDV (DCS_BUILD_ENV_TYPE == DCS_BUILD_ENV_DV) +#define izPERTOS (DCS_BUILD_ENV_TYPE == DCS_BUILD_ENV_PERTOS) + +//================================================================================ +// Target Type: SoC, FPGA, Palladium +//================================================================================ +#define DCS_TARGET_SOC (0) +#define DCS_TARGET_FPGA (1) +#define DCS_TARGET_PALLADIUM (2) + +#define izSOC (DCS_TARGET_TYPE == DCS_TARGET_SOC) +#define izFPGA (DCS_TARGET_TYPE == DCS_TARGET_FPGA) +#define izPAL (DCS_TARGET_TYPE == DCS_TARGET_PALLADIUM) + +//================================================================================ +// What Build Environment? +#ifndef DCS_BUILD_ENV_TYPE +#define DCS_BUILD_ENV_TYPE DCS_BUILD_ENV_IBOOT +#endif + +//================================================================================ +#if izIBOOT +//================================================================================ + +#define AMP_H_BASE_ADDR AMPH_BASE_ADDR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define delay_for_us(_us_delay) spin(_us_delay) + +extern int debug_level_dcs; +#define do_printf(x...) dprintf(debug_level_dcs, x) + +#define dcs_panic(x...) \ + EXEC( \ + debug_level_dcs = DEBUG_CRITICAL; \ + dcs_cfg.debugBitz |= DCS_DBG_CAL; \ + calibration_dump_results(SELECT_CAL_ALL, true); \ + panic(x); \ + ) + +#if SUPPORT_FPGA +#define DCS_TARGET_TYPE DCS_TARGET_FPGA +#endif + +// iBoot gets these definitions via the make command line +// Maximum channels/ranks supported by the target +//#define DCS_NUM_CHANNELS 4 +//#define DCS_NUM_RANKS 1 + +// iBoot gets this definition via the make command line +#ifdef AMP_CALIBRATION_SKIP +#define DCS_DO_CALIBRATION 0 +#else +#define DCS_DO_CALIBRATION 1 +#endif + +//================================================================================ +#elif izSIVAL +//================================================================================ +#include "drivers/dcs/dcs_sival.h" + +//================================================================================ +#elif izDV +//================================================================================ + +//================================================================================ +#elif izPERTOS +//================================================================================ + +//================================================================================ +#else // other than iBoot (examples: SiVal, DV, etc.) +//================================================================================ +// iBoot has a special version of a tight SpinLoop with Timeout +// Other build environments may use the following simple definition (no Timeout), +// or else provide their own by modifying this definition +#define SPIN_W_TMO_WHILE(__expr) while(__expr) + +// iBoot defines this function to delay for N microseconds +// Other build environments may use the following degenerate definition (no delay), +// or else provide their own by modifying this definition +#define delay_for_us(_us_delay) EXEC(;) + +// iBoot defines this function to optionally print out debug messages +// Other build environments may use the following simple definition (printf), +// or else provide their own by modifying this definition +#define do_printf(x...) printf(x) + +// iBoot defines this function to halt execution and terminate because of a fatal error +// Other build environments may use the following similar definition (panic), +// or else provide their own by modifying this definition +#define dcs_panic(x...) \ + EXEC( \ + debug_level_dcs = DEBUG_CRITICAL; \ + dcs_cfg.debugBitz |= DCS_DBG_CAL; \ + calibration_dump_results(SELECT_CAL_ALL, true); \ + panic(x); \ + ) + +// iBoot derives this definition from other definitions provided via the make command line +// Other build environments may explicitly define the target type here, +// or use any other desired method +//#define DCS_TARGET_TYPE DCS_TARGET_SOC +//#define DCS_TARGET_TYPE DCS_TARGET_FPGA +//#define DCS_TARGET_TYPE DCS_TARGET_PALLADIUM + +// Maximum channels/ranks supported by the target +#define DCS_NUM_CHANNELS 4 +#define DCS_NUM_RANKS 1 + +#define DCS_DO_CALIBRATION 1 // ZERO to Skip Calibration + +//================================================================================ +#endif +//================================================================================ +#ifndef DCS_TARGET_TYPE +#define DCS_TARGET_TYPE DCS_TARGET_SOC +#endif + +typedef uint32_t dcs_buildtype_t; +typedef uint32_t dcs_target_t; + +#define CACAL_MAX_SWLOOPS 1 + +//================================================================================ +// Config Sturcture +//================================================================================ +typedef struct { + bool valid; + dcs_boottype_t boot_type; + uint32_t chipID; // Supported ChipID values listed below + uint32_t chipRev; // A0, B0, B1, etc. + uint32_t num_dcs; // Number of DCS Blocks for this Chip + uint32_t num_rank; // Number of Ranks for the DRAM + uint32_t debugBitz; // Bit Field to control various debug behaviors + uint32_t variantBitz; // Bit Field to control variant behavior (workaround, per RADAR) +} dcs_config_t; + +// Supported Chip Revision Codes +#define DCS_CHIP_REV_A0 0x00 +#define DCS_CHIP_REV_A1 0x01 +#define DCS_CHIP_REV_A2 0x02 +#define DCS_CHIP_REV_B0 0x10 +#define DCS_CHIP_REV_B1 0x11 +#define DCS_CHIP_REV_B2 0x12 +#define DCS_CHIP_REV_C0 0x20 +#define DCS_CHIP_REV_C1 0x21 +#define DCS_CHIP_REV_C2 0x22 + +//================================================================================ +#define BIT_N(_N) (1 << (_N)) + +// Defined debug Bitz +#define DCS_DBG_NONE 0x00000000 +#define DCS_DBG_REG_ACCESS BIT_N(0) +#define DCS_DBG_CHAN_DETAIL BIT_N(1) +#define DCS_DBG_SPIN BIT_N(2) +#define DCS_DBG_MR_READ BIT_N(3) +#define DCS_DBG_MILESTONE BIT_N(4) +#define DCS_DBG_CAL BIT_N(5) +#define DCS_DBG_CAL_MILESTONE BIT_N(6) +#define DCS_DBG_FREQ BIT_N(7) + +#define DCS_DBG_OVERVIEW BIT_N(8) +#define DCS_DBG_ASSESS_CONFIG BIT_N(9) + +#define DCS_DBG_DEFAULT (DCS_DBG_OVERVIEW | DCS_DBG_ASSESS_CONFIG) + +// Defined variant Bitz +#define DCS_VARIANT_NONE 0x00000000 +#define DCS_VARIANT_SKIP_MCC BIT_N(0) +#define DCS_VARIANT_VREF_USES_WIDEST BIT_N(1) // Use Widest-Eye Algorithm for Optimal Vref + +#define DCS_NONVAL (0xF82BDEAD) + +//================================================================================ +extern dcs_config_t dcs_cfg; +// extern dcs_config_params_t dcs_params; + +#define izColdBoot (dcs_cfg.boot_type == DCS_BOOT_COLDBOOT) +#define izResume (dcs_cfg.boot_type == DCS_BOOT_RESUME) +#define izAOP_DDR (dcs_cfg.boot_type == DCS_BOOT_AOP_DDR) +#define izAOP_Awake (dcs_cfg.boot_type == DCS_BOOT_AOP_AWAKE) + +//================================================================================ +#define ifbit_printf(_b, _f, x...) EXEC(if ((_b) & (_f)) do_printf(x)) +#define dbgprintf(_b, x...) ifbit_printf(_b, dcs_cfg.debugBitz, x) + +//================================================================================ +// These are used by the Calibration Functions ... provided by dcs_init_lib + +// Save SRAM space in iBoot by removing calibration debug printfs +#if izIBOOT +#define shim_printf(x...) do { } while(0) +#else +#define shim_printf(x...) dbgprintf(DCS_DBG_CAL, x) +#endif + +#define shim_panic(x...) dcs_panic(x) +#define shim_mrcmd_to_ch_rnk(x...) dcs_mrcmd_to_ch_rnk(x) + +//================================================================================ +// Callouts Required by this Library. +// Must be Provided externally (build environment, platform, target, etc.) +//================================================================================ +void dcs_dram_workarounds(dcs_boottype_t boot_type); +void dcs_dram_workarounds_step12(void); +void dcs_init_config_params(dcs_config_params_t *use_dcs_params, dcs_target_t targtype); +const dcs_tunable_t *dcs_init_tunable_table(uint32_t *table_len); +void dcs_change_freq(uint32_t freq_bin); +void dcs_store_memory_calibration(void *cal_values, uint32_t cal_size); +void dcs_load_memory_calibration(void *cal_values, uint32_t cal_size); + +//================================================================================ +// These are used by the Calibration Functions ... must be provided by build environment +#define shim_change_freq(_bin) dcs_change_freq(_bin) +#define shim_store_memory_calibration dcs_store_memory_calibration +#define shim_load_memory_calibration dcs_load_memory_calibration + +//================================================================================ +// API Functions provided by this Library and available for use +//================================================================================ +bool dcs_init_config(dcs_boottype_t boot_type, uint32_t chipID, uint32_t chipRev, + uint32_t num_dcs, uint32_t num_rank); +uint32_t dcs_init_debug_enable(uint32_t bit); +uint32_t dcs_init_debug_disable(uint32_t bit); +uint32_t dcs_init_variant_enable(uint32_t bit); +uint32_t dcs_init_variant_disable(uint32_t bit); +dcs_config_params_t *dcs_init_param_table(void); + +void dcs_mrcmd_to_ch_rnk(dcs_mrcmd_op_t op, uint8_t channel, uint8_t rank, int reg, uintptr_t val); +void dcs_mrcmd(dcs_mrcmd_op_t op, uint8_t channels, uint8_t ranks, int reg, uintptr_t val); + +void dcs_spin(uint32_t duration_us, char *reason); +void dcs_enable_autorefresh(void); +void dcs_init_apply_tunables(void); + +// Step 0: AMC Prolog +void dcs_init_Prolog(void); +// Step 1: AMC Initial Configuration +void dcs_init_AMC_Initial_Config(void); +// Step 2: AMP Initial Configuration +void dcs_init_AMP_Initial_Config(void); +// Step 3: Self-Refresh Exit +void dcs_init_Self_Refresh_Exit_a(void); +void dcs_init_Self_Refresh_Exit_b(void); +// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only) +void dcs_init_ZQ_Cal_Cfg(void); +// Step 5a: AddrConfig Configuration +void dcs_init_AddrCfg_Cfg(void); +void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes); +// Step 6: Switch from boot-clock speed to normal operation speed +void dcs_init_Reenable_AMC_Scheduler(void); +// Step 7: Setup registers for CA calibration for bucket 1 +void dcs_init_CA_Cal_Setup_Freq1(void); +// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz +void dcs_init_CA_Cal_Freq1(void); +// Step 9: Setup registers for DQ calibration for bucket 1 +void dcs_init_DQ_Cal_Setup_Freq1_a(void); +void dcs_init_DQ_Cal_Setup_Freq1_b(void); +// Step 10: PHY write DQ calibration +void dcs_init_wrdq_skew(void); +void dcs_init_post_wrlvl(void); +// Step 11: Setup registers for CA calibration for bucket 0 +void dcs_init_CA_Cal_Setup_Freq0(void); +// Step 12: AMP Dynamic CA Timing Calibration +// NO PROVIDED FUNCTION +// Step 13: Setup registers for DQ calibration for bucket 0 +void dcs_init_DQ_Cal_Setup_Freq0_a(void); +void dcs_init_DQ_Cal_Setup_Freq0_b(void); +// Step 14: AMP Dynamic DQ Calibration +// NO PROVIDED FUNCTION +// Step 15: Setup Registers for Boot +void dcs_init_Reg_for_Boot(void); +// Step 16: Enable Other Features +void dcs_init_MoreFeatures(void); +// Step 17: Enable Fast Critical Word Forwarding Feature +void dcs_init_Fast_Critical_Word_Forwarding(void); +// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers +void dcs_init_Gating_Global_Timers(void); +// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading +void dcs_init_ODTS(void); + +// Elba: Samsung DRAM workaround: disable hw zqcal +bool shim_apply_samsung_workaround(void); + +void dcs_reg_write(uintptr_t reg_addr, uint32_t reg_value); +void dcs_reg_poll(uintptr_t reg_addr, uint32_t mask_value, uint32_t required_value); +void dcs_reg_write_all_chan(uintptr_t reg_addr, uint32_t reg_value); +void dcs_reg_poll_all_chan(uintptr_t reg_addr, uint32_t mask_value, uint32_t required_value); + +#endif /* ! __DCS_INIT_LIB_H */ diff --git a/drivers/apple/dcs/include/drivers/dcs/dcs_regs.h b/drivers/apple/dcs/include/drivers/dcs/dcs_regs.h new file mode 100644 index 0000000..125be43 --- /dev/null +++ b/drivers/apple/dcs/include/drivers/dcs/dcs_regs.h @@ -0,0 +1,676 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _DCS_S8000_H +#define _DCS_S8000_H + +#include +#include +#include +#include + +/* + * DCS_REG_VERSION mapping used in iBoot for various platforms + * Maui: 1 + * s8003: 2 + * Elba: 3 + * Cayman: 4 + * + * SoCs with "dcsh" block to have bit 4 set + * M8: 0x10 + */ + +#ifndef DCS_REG_VERSION +#define DCS_REG_VERSION (1) +#endif + +#ifndef NUM_AMCCS +#define NUM_AMCCS (1) +#endif + +/* Macro to read a register in a particular DCS channel */ +#define DCS_REG_ACCESS(reg) (*(volatile uint32_t *)(reg)) +#define DCS_REG_READ_CH(_c,reg) DCS_REG_ACCESS((reg) + ((_c)*DCS_SPACING)) + +// Used by Calibration Code +#define CSR_READ(addr) DCS_REG_ACCESS(addr) +#define CSR_WRITE(addr, val) EXEC(DCS_REG_ACCESS(addr) = val) + + +#define KAY (1024) +#define MEG (KAY*KAY) + +#define DCS_FREQUENCY_SLOTS (4) + +#if DCS_REG_VERSION >= 0x10 +// PIOWRAP registers +#define rAMC_PIO_ACCESS_CFG (PIO_BASE_ADDR + 0x02C) + +// AMCSYS registers +#define rAMC_AMCEN (AMC_BASE_ADDR + 0x000) +#define rAMC_CLKGATE (AMC_BASE_ADDR + 0x004) +#define rAMC_AIUPRT_RD_CWF (AMC_BASE_ADDR + 0x084) +#define rAMC_AIUPRT_RD_GEN (AMC_BASE_ADDR + 0x088) +#define rAMC_AIUPRTBADDR (AMC_BASE_ADDR + 0x0A0) +#define rAMC_AIUCHNLDEC (AMC_BASE_ADDR + 0x0A4) +#define rAMC_AIUADDRBANKHASH(_n) (AMC_BASE_ADDR + (_n * 4) + 0x0B0) + +#define rAMC_AIUCHNLCRD (AMC_BASE_ADDR + 0x100) +#define rAMC_AIUCHNLTM (AMC_BASE_ADDR + 0x104) +#define rAMC_AIURDBRSTLEN (AMC_BASE_ADDR + 0x108) +#define rAMC_AIURDMAXCRD (AMC_BASE_ADDR + 0x10C) +#define rAMC_AIURDMINCRD (AMC_BASE_ADDR + 0x110) +#define rAMC_AIURDREFL (AMC_BASE_ADDR + 0x114) +#define rAMC_AIUWRBRSTLEN (AMC_BASE_ADDR + 0x118) +#define rAMC_AIUWRMAXCRD (AMC_BASE_ADDR + 0x11C) +#define rAMC_AIUWRMINCRD (AMC_BASE_ADDR + 0x120) +#define rAMC_AIUWRREFL (AMC_BASE_ADDR + 0x124) +#define rAMC_AIUCPUSPCREQ (AMC_BASE_ADDR + 0x128) +#define rAMC_AIUGRXSPCREQ (AMC_BASE_ADDR + 0x12C) +#define rAMC_AIUNRTSPCREQ (AMC_BASE_ADDR + 0x130) +#define rAMC_AIURLTSPCREQ (AMC_BASE_ADDR + 0x134) +#define rAMC_AIUWPQSCH (AMC_BASE_ADDR + 0x138) +#define rAMC_AIUTHOTLEN (AMC_BASE_ADDR + 0x13C) +#define rAMC_AIUTHOTLCPUPARAM (AMC_BASE_ADDR + 0x140) +#define rAMC_AIUTHOTLRLTPARAM (AMC_BASE_ADDR + 0x144) +#define rAMC_AIUTHOTLNRTPARAM (AMC_BASE_ADDR + 0x148) +#define rAMC_AIUTHOTLGRXPARAM (AMC_BASE_ADDR + 0x14C) +#define rAMC_AIUPUSHEN (AMC_BASE_ADDR + 0x150) +#define rAMC_AIUTHOTLCPUPARAM2 (AMC_BASE_ADDR + 0x154) +#define rAMC_AIUTHOTLRLTPARAM2 (AMC_BASE_ADDR + 0x158) +#define rAMC_AIUTHOTLNRTPARAM2 (AMC_BASE_ADDR + 0x15C) +#define rAMC_AIUTHOTLGRXPARAM2 (AMC_BASE_ADDR + 0x160) +#define rAMC_AIULLTSCHCTL (AMC_BASE_ADDR + 0x164) +#define rAMC_AIURDMAXCRD2 (AMC_BASE_ADDR + 0x168) +#define rAMC_AIURDMINCRD2 (AMC_BASE_ADDR + 0x16C) +#define rAMC_AIURDREFL2 (AMC_BASE_ADDR + 0x170) +#define rAMC_AIUWRMAXCRD2 (AMC_BASE_ADDR + 0x174) +#define rAMC_AIUWRMINCRD2 (AMC_BASE_ADDR + 0x178) +#define rAMC_AIUWRREFL2 (AMC_BASE_ADDR + 0x17C) +#define rAMC_AIUMEDSPCREQ (AMC_BASE_ADDR + 0x180) +#define rAMC_AIUTHOTLMEDPARAM (AMC_BASE_ADDR + 0x184) +#define rAMC_AIUTHOTLMEDPARAM2 (AMC_BASE_ADDR + 0x188) + +#define rAMC_QBREN (AMC_BASE_ADDR + 0x200) +#define rAMC_PSQRQCTL0 (AMC_BASE_ADDR + 0x208) +#define rAMC_PSQRQCTL1 (AMC_BASE_ADDR + 0x20C) +#define rAMC_PSQRQTIMER(_n) (AMC_BASE_ADDR + (_n * 4) + 0x210) +#define rAMC_PSQRQBRST (AMC_BASE_ADDR + 0x21C) +#define rAMC_PSQRQSCHCRD (AMC_BASE_ADDR + 0x220) +#define rAMC_PSQWQCTL1 (AMC_BASE_ADDR + 0x228) +#define rAMC_PSQWQBRST (AMC_BASE_ADDR + 0x230) +#define rAMC_PSQWQSCHCRD (AMC_BASE_ADDR + 0x234) +#define rAMC_MCUQOS (AMC_BASE_ADDR + 0x238) +#define rAMC_MCUQOSLLT (AMC_BASE_ADDR + 0x23C) + +#define rAMC_ADDRMAPMODE (AMC_BASE_ADDR + 0x400) +#define rAMC_ADDRCFG (AMC_BASE_ADDR + 0x404) +#define rAMC_PWRMNGTPARAM (AMC_BASE_ADDR + 0x408) + +// AMCSYS_AON +#define rAMC_IDLE2BCG_CONTROL (AMC_BASE_ADDR + 0x8014) + +// DCSH_AON +#define rDCS_AON_IDLE2BCG_CONTROL (DCS_BASE_ADDR + DCSH_AON_SPACING + 0x004) +#endif // #if DCS_REG_VERSION >= 0x10 + +#if NUM_AMCCS == 2 + +/* AMCC0 registers */ +#define rAMCC_MCCCHNLDEC_ADDR (AMCC_BASE_ADDR(0) + 0x4A4) +#define rAMCC_MCUCHNHASH_ADDR (AMCC_BASE_ADDR(0) + 0x4A8) +#define rAMCC_DRAMACCCTRL_ADDR (AMCC_BASE_ADDR(0) + 0x4B8) +#define rAMCC_ADDRCFG_ADDR (AMCC_BASE_ADDR(0) + 0x4CC) +#define rAMCC_MCC0QPROPCTRL_ADDR (AMCC_BASE_ADDR(0) + 0x648) +#define rAMCC_MCC1QPROPCTRL_ADDR (AMCC_BASE_ADDR(0) + 0x64C) +#define rAMCC_MCCGEN_ADDR (AMCC_BASE_ADDR(0) + 0x780) +#define rAMCC_MCCCFG_TAG_RD_DIS_ADDR (AMCC_BASE_ADDR(0) + 0x794) +#define rAMCC_MCCPWRONWAYCNTSTATUS_ADDR (AMCC_BASE_ADDR(0) + 0x79C) + +#define rAMCC_MCCCHNLDEC DCS_REG_ACCESS(rAMCC_MCCCHNLDEC_ADDR) +#define rAMCC_DRAMACCCTRL DCS_REG_ACCESS(rAMCC_DRAMACCCTRL_ADDR) +#define rAMCC_ADDRCFG DCS_REG_ACCESS(rAMCC_ADDRCFG_ADDR) +#define rAMCC_MCC0QPROPCTRL DCS_REG_ACCESS(rAMCC_MCC0QPROPCTRL_ADDR) +#define rAMCC_MCC1QPROPCTRL DCS_REG_ACCESS(rAMCC_MCC1QPROPCTRL_ADDR) +#define rAMCC_MCCGEN DCS_REG_ACCESS(rAMCC_MCCGEN_ADDR) +#define rAMCC_MCCCFG_TAG_RD_DIS DCS_REG_ACCESS(rAMCC_MCCCFG_TAG_RD_DIS_ADDR) +#define rAMCC_MCCPWRONWAYCNTSTATUS DCS_REG_ACCESS(rAMCC_MCCPWRONWAYCNTSTATUS_ADDR) + +/* AMCC1 registers */ +#define rAMCC1_MCCCHNLDEC_ADDR (AMCC_BASE_ADDR(1) + 0x4A4) +#define rAMCC1_MCUCHNHASH_ADDR (AMCC_BASE_ADDR(1) + 0x4A8) +#define rAMCC1_DRAMACCCTRL_ADDR (AMCC_BASE_ADDR(1) + 0x4B8) +#define rAMCC1_ADDRCFG_ADDR (AMCC_BASE_ADDR(1) + 0x4CC) +#define rAMCC1_MCC0QPROPCTRL_ADDR (AMCC_BASE_ADDR(1) + 0x648) +#define rAMCC1_MCC1QPROPCTRL_ADDR (AMCC_BASE_ADDR(1) + 0x64C) +#define rAMCC1_MCCGEN_ADDR (AMCC_BASE_ADDR(1) + 0x780) +#define rAMCC1_MCCCFG_TAG_RD_DIS_ADDR (AMCC_BASE_ADDR(1) + 0x794) +#define rAMCC1_MCCPWRONWAYCNTSTATUS_ADDR (AMCC_BASE_ADDR(1) + 0x79C) + +#define rAMCC1_MCCCHNLDEC DCS_REG_ACCESS(rAMCC1_MCCCHNLDEC_ADDR) +#define rAMCC1_DRAMACCCTRL DCS_REG_ACCESS(rAMCC1_DRAMACCCTRL_ADDR) +#define rAMCC1_ADDRCFG DCS_REG_ACCESS(rAMCC1_ADDRCFG_ADDR) +#define rAMCC1_MCC0QPROPCTRL DCS_REG_ACCESS(rAMCC1_MCC0QPROPCTRL_ADDR) +#define rAMCC1_MCC1QPROPCTRL DCS_REG_ACCESS(rAMCC1_MCC1QPROPCTRL_ADDR) +#define rAMCC1_MCCGEN DCS_REG_ACCESS(rAMCC1_MCCGEN_ADDR) +#define rAMCC1_MCCCFG_TAG_RD_DIS DCS_REG_ACCESS(rAMCC1_MCCCFG_TAG_RD_DIS_ADDR) +#define rAMCC1_MCCPWRONWAYCNTSTATUS DCS_REG_ACCESS(rAMCC1_MCCPWRONWAYCNTSTATUS_ADDR) + +#elif NUM_AMCCS == 1 + +/* AMCC registers */ +#define rAMCC_MCCCHNLDEC_ADDR (AMCC_BASE_ADDR(0) + 0x4A4) +#define rAMCC_DRAMACCCTRL_ADDR (AMCC_BASE_ADDR(0) + 0x4B4) +#define rAMCC_ADDRCFG_ADDR (AMCC_BASE_ADDR(0) + 0x4C8) +#define rAMCC_MCC0QPROPCTRL_ADDR (AMCC_BASE_ADDR(0) + 0x648) +#define rAMCC_MCC1QPROPCTRL_ADDR (AMCC_BASE_ADDR(0) + 0x64C) +#define rAMCC_MCCGEN_ADDR (AMCC_BASE_ADDR(0) + 0x780) +#define rAMCC_MCCCFG_TAG_RD_DIS_ADDR (AMCC_BASE_ADDR(0) + 0x794) +#define rAMCC_MCCPWRONWAYCNTSTATUS_ADDR (AMCC_BASE_ADDR(0) + 0x79C) + +#define rAMCC_MCCCHNLDEC DCS_REG_ACCESS(rAMCC_MCCCHNLDEC_ADDR) +#define rAMCC_DRAMACCCTRL DCS_REG_ACCESS(rAMCC_DRAMACCCTRL_ADDR) +#define rAMCC_ADDRCFG DCS_REG_ACCESS(rAMCC_ADDRCFG_ADDR) +#define rAMCC_MCC0QPROPCTRL DCS_REG_ACCESS(rAMCC_MCC0QPROPCTRL_ADDR) +#define rAMCC_MCC1QPROPCTRL DCS_REG_ACCESS(rAMCC_MCC1QPROPCTRL_ADDR) +#define rAMCC_MCCGEN DCS_REG_ACCESS(rAMCC_MCCGEN_ADDR) +#define rAMCC_MCCCFG_TAG_RD_DIS DCS_REG_ACCESS(rAMCC_MCCCFG_TAG_RD_DIS_ADDR) +#define rAMCC_MCCPWRONWAYCNTSTATUS DCS_REG_ACCESS(rAMCC_MCCPWRONWAYCNTSTATUS_ADDR) + +#endif // #if NUM_AMCCS == 2 + +#define AMCC_MCCCFG_TAG_RD_DIS_ADDR(i) (AMCC_BASE_ADDR(i) + 0x794) + +#define AMCC_MCCGEN_MCC_RAM_EN (1 << 1) +#define AMCC_MCCGEN_MCC_RAM_EN_LOCK (1 << 16) + +#define DCS_NUM_MEG_IN_DRAM_BLK (128) + +/* MCU registers */ +#define rDCS_MCU_AMCCTRL (DCS_BASE_ADDR + 0x000) +#define rDCS_MCU_CLKGATE (DCS_BASE_ADDR + 0x004) +#define rDCS_MCU_AMCCLKPWRGATE (DCS_BASE_ADDR + 0x010) +#define rDCS_MCU_AMCCLKPWRGATE2 (DCS_BASE_ADDR + 0x014) + +#if DCS_REG_VERSION >= 0x10 +#define rDCS_MCU_IDLE_EXTEND_CONTROL (DCS_BASE_ADDR + 0x018) +#define rDCS_MCU_DIV_CLK_SELECT (DCS_BASE_ADDR + 0x020) +#endif + +#define rDCS_MCU_OPIDLETMR (DCS_BASE_ADDR + 0x180) +#define rDCS_MCU_OPTMRADJEN (DCS_BASE_ADDR + 0x184) +#define rDCS_MCU_OPTMRADJPARAM (DCS_BASE_ADDR + 0x188) +#define rDCS_MCU_MIFNRTAGE (DCS_BASE_ADDR + 0x18C) +#define rDCS_MCU_MIFRTAGE (DCS_BASE_ADDR + 0x190) +#define rDCS_MCU_MIFPCAGE (DCS_BASE_ADDR + 0x194) +#define rDCS_MCU_QBREN (DCS_BASE_ADDR + 0x198) +#define rDCS_MCU_QBRPARAM (DCS_BASE_ADDR + 0x19C) + +#if DCS_REG_VERSION >= 0x10 +#define rDCS_MCU_QBRPARAM2 (DCS_BASE_ADDR + 0x1A0) +#endif + +#define rDCS_MCU_PSQRQCTL0 (DCS_BASE_ADDR + 0x1A4) + +#define rDCS_MCU_PSQCPU0LLT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 0xC) + 0x1A8) +#define rDCS_MCU_PSQCPU1LLT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 0xC) + 0x1AC) +#define rDCS_MCU_PSQSOCLLT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 0xC) + 0x1B0) + +#define rDCS_MCU_PSQRQTIMER0 (DCS_BASE_ADDR + 0x1D8) +#define rDCS_MCU_PSQRQTIMER1 (DCS_BASE_ADDR + 0x1DC) +#define rDCS_MCU_PSQRQBRST (DCS_BASE_ADDR + 0x1E0) +#define rDCS_MCU_PSQRQSCHCRD (DCS_BASE_ADDR + 0x1E4) + +#define rDCS_MCU_PSQWQ_CTL(_n) (DCS_BASE_ADDR + ((_n) * 4) + 0x1E8) +#define rDCS_MCU_PSQWQCTL0 rDCS_MCU_PSQWQ_CTL(0) +#define rDCS_MCU_PSQWQCTL1 rDCS_MCU_PSQWQ_CTL(1) +#define rDCS_MCU_PSQWQCTL2 rDCS_MCU_PSQWQ_CTL(2) +#define rDCS_MCU_PSQWQTHR (DCS_BASE_ADDR + 0x1F4) +#define rDCS_MCU_PSQWQBRST (DCS_BASE_ADDR + 0x1F8) +#define rDCS_MCU_PSQWQSCHCRD (DCS_BASE_ADDR + 0x1FC) + +#define rDCS_MCU_QOSLLT (DCS_BASE_ADDR + 0x200) +#define rDCS_MCU_SBQOSUPGCTL (DCS_BASE_ADDR + 0x204) +#define rDCS_MCU_SBQOSUPGISPAIDS (DCS_BASE_ADDR + 0x208) + +#define rDCS_MCU_PHYRDWRTIM_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x280) +#define rDCS_MCU_PHYUPDATETIMERS (DCS_BASE_ADDR + 0x300) + +#if (DCS_REG_VERSION >= 4 && DCS_REG_VERSION < 0x10) +#define rDCS_MCU_LAT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x340) +#define rDCS_MCU_CASPCH_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x350) +#define rDCS_MCU_ACT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x360) +#define rDCS_MCU_AUTOREF_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x370) +#define rDCS_MCU_SELFREF_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x380) +#define rDCS_MCU_PDN (DCS_BASE_ADDR + 0x390) +#define rDCS_MCU_MODEREG (DCS_BASE_ADDR + 0x394) +#define rDCS_MCU_DERATE_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x398) +#define rDCS_MCU_TAT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x3A8) +#define rDCS_MCU_AUTOREF_PARAMS (DCS_BASE_ADDR + 0x3BC) +#define rDCS_MCU_PDN1 (DCS_BASE_ADDR + 0x3C0) +#define rDCS_MCU_MODEREG1 (DCS_BASE_ADDR + 0x3C4) +#define rDCS_MCU_PDN_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x3C8) +#else +#define rDCS_MCU_LAT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x380) +#define rDCS_MCU_CASPCH_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x390) +#define rDCS_MCU_ACT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x3A0) +#define rDCS_MCU_AUTOREF_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x3B0) +#define rDCS_MCU_SELFREF_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x3C0) +#define rDCS_MCU_PDN (DCS_BASE_ADDR + 0x3D0) +#define rDCS_MCU_MODEREG (DCS_BASE_ADDR + 0x3D4) +#define rDCS_MCU_DERATE_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x3D8) +#define rDCS_MCU_TAT_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x3E8) +#define rDCS_MCU_AUTOREF_PARAMS (DCS_BASE_ADDR + 0x3FC) +#endif + +#define rDCS_MCU_RWCFG (DCS_BASE_ADDR + 0x400) +#define rDCS_MCU_RNKCFG (DCS_BASE_ADDR + 0x404) +#define rDCS_MCU_AREFEN_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x408) +#define rDCS_MCU_AREFPARAM (DCS_BASE_ADDR + 0x418) + +#if (DCS_REG_VERSION >= 4 && DCS_REG_VERSION < 0x10) +#define rDCS_MCU_LONGSR (DCS_BASE_ADDR + 0x420) +#define rDCS_MCU_ODTSZQC (DCS_BASE_ADDR + 0x424) +#define rDCS_MCU_PWRMNGTEN (DCS_BASE_ADDR + 0x428) +#define rDCS_MCU_PWRMNGTPARAM_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x42C) +#define rDCS_MCU_MCPHYUPDTPARAM (DCS_BASE_ADDR + 0x440) +#define rDCS_MCU_READLEVELING (DCS_BASE_ADDR + 0x444) +#define rDCS_MCU_FREQCHNGCTL (DCS_BASE_ADDR + 0x450) +#define rDCS_MCU_FREQCHNGCTL_FREQ(_n,_f) (DCS_BASE_ADDR + ((_n) * 4) + ((_f) * 0x18) + 0x454) +#define rDCS_MCU_FREQCHNGTIM_FREQ(_n) (DCS_BASE_ADDR + ((_n) * 4) + 0x4B4) +#define rDCS_MCU_LS3B_QUIES_CTRL (DCS_BASE_ADDR + 0x838) + +#else +#define rDCS_MCU_LONGSR (DCS_BASE_ADDR + 0x41C) +#define rDCS_MCU_ODTSZQC (DCS_BASE_ADDR + 0x420) +#define rDCS_MCU_PWRMNGTEN (DCS_BASE_ADDR + 0x424) +#define rDCS_MCU_PWRMNGTPARAM_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x428) +#define rDCS_MCU_MCPHYUPDTPARAM (DCS_BASE_ADDR + 0x43C) +#define rDCS_MCU_READLEVELING (DCS_BASE_ADDR + 0x440) +#define rDCS_MCU_FREQCHNGCTL (DCS_BASE_ADDR + 0x44C) +#define rDCS_MCU_ROWHAM_CTL(_n) (DCS_BASE_ADDR + ((_n) * 4) + 0x4B0) +#define rDCS_MCU_FREQCHNGCTL_FREQ(_n,_f) (DCS_BASE_ADDR + ((_n) * 4) + ((_f) * 0x18) + 0x450) +#if DCS_REG_VERSION < 3 +#define rDCS_MCU_FREQCHNGTIM_FREQ(_n) (DCS_BASE_ADDR + ((_n) * 4) + 0x4C0) +#else +#define rDCS_MCU_FREQCHNGTIM_FREQ(_n) (DCS_BASE_ADDR + ((_n) * 4) + 0x4C4) +#endif // #if DCS_REG_VERSION < 3 +#endif // #if (DCS_REG_VERSION >= 4 && DCS_REG_VERSION < 0x10) + +#define rDCS_MCU_MRINITCMD_0 (DCS_BASE_ADDR + 0x500) +#define rDCS_MCU_MRINITSTS_0 (DCS_BASE_ADDR + 0x504) +#define rDCS_MCU_INTSTS_0 (DCS_BASE_ADDR + 0x708) +#define rDCS_MCU_MIFQMAXCTRL_FREQ(_f) (DCS_BASE_ADDR + ((_f) * 4) + 0x780) +#define rDCS_MCU_MRINITCMD(_c) DCS_REG_READ_CH(_c,rDCS_MCU_MRINITCMD_0) +#define rDCS_MCU_MRINITSTS(_c) DCS_REG_READ_CH(_c,rDCS_MCU_MRINITSTS_0) +#define rDCS_MCU_INTSTS(_c) DCS_REG_READ_CH(_c,rDCS_MCU_INTSTS_0) + +#define MRCMD_POLL_BIT (0x100) + +#define MRCMD_RANK_SHIFT (13) +#define MRCMD_CMDTYPE_SHIFT (8) +#define MRCMD_REG_SHIFT (16) +#define MRCMD_DATA_SHIFT (24) + +#define MRCMD_TYPE(_h) (((_h) & 0xFF) << MRCMD_CMDTYPE_SHIFT) +#define MRCMD_TYPE_READ MRCMD_TYPE(0x11) +#define MRCMD_TYPE_WRITE MRCMD_TYPE(0x01) +#define MRCMD_TYPE_MPC MRCMD_TYPE(0x41) + +/* SPLLCTRL registers */ +#define rDCS_SPLLCTRL_MODEREG (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x000) +#define rDCS_SPLLCTRL_CHARGEPUMP (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x01C) +#define rDCS_SPLLCTRL_VCO (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x020) +#define rDCS_SPLLCTRL_LDO (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x024) +#define rDCS_SPLLCTRL_SPLLPWRDNCFG (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x05C) +#define rDCS_SPLLCTRL_SPLLDIVCFG (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x060) + +#if DCS_REG_VERSION >= 2 +#define rDCS_SPLLCTRL_MDLLPWRDNCFG(_n) (DCS_BASE_ADDR + SPLLCTRL_SPACING + ((_n) * 4) + 0x064) +#endif + +#if DCS_REG_VERSION >= 0x10 +#define rDCS_SPLLCTRL_RECONFIGSWRESETTRIGGER (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x074) +#define rDCS_SPLLCTRL_RECONFIGSWRESETCONTROL (DCS_BASE_ADDR + SPLLCTRL_SPACING + 0x078) +#endif + +/* AMP registers */ + +/* _t: type, DQ0, DQ1, or CA */ +/* _c: channel, 0 or 1 */ +#define AMP_CA (0) +#define AMP_DQ0 (1) +#define AMP_DQ1 (2) +#define DCS_AMP_NUM_PHYS (3) + +#define AMP_IFF(__t,_t,_off) (((__t) == (_t))? _off:0) + +#define rDCS_AMP_AMPEN(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x000) +#define rDCS_AMP_AMPCLK(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x004) +#define rDCS_AMP_AMPINIT(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x008) +#define rDCS_AMP_DRAM_RESETN(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x00C) // Only for AMPCA +#define rDCS_AMP_AMPVER(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + AMP_IFF(_t,0,4) + 0x00C) + +// for AMPCA Only +#define rDCS_AMP_IMPCODE (AMP_BASE_ADDR + 0x080) + +#if (DCS_REG_VERSION >= 4 && DCS_REG_VERSION < 0x10) +#define rDCS_AMP_IMPAUTOCAL (AMP_BASE_ADDR + 0x084) +#define rDCS_AMP_IMPCALCONTROL (AMP_BASE_ADDR + 0x088) +#define rDCS_AMP_IMPCALPHYUPDT (AMP_BASE_ADDR + 0x08C) +#define rDCS_AMP_IMPCALCMD (AMP_BASE_ADDR + 0x090) + +#else +#define rDCS_AMP_IMPOVRRD (AMP_BASE_ADDR + 0x084) +#define rDCS_AMP_IMPAUTOCAL (AMP_BASE_ADDR + 0x088) +#define rDCS_AMP_IMPCALCONTROL (AMP_BASE_ADDR + 0x08C) +#define rDCS_AMP_IMPCALPHYUPDT (AMP_BASE_ADDR + 0x090) +#define rDCS_AMP_IMPCALCMD (AMP_BASE_ADDR + 0x094) +#define rDCS_AMP_NONDQDSPD_F(_f) (AMP_BASE_ADDR + 0x09C + ((_f) * 4)) +#define rDCS_AMP_NONDQDS_F(_f) (AMP_BASE_ADDR + 0x0AC + ((_f) * 4)) +#define rDCS_AMP_CACKCSWKPD_F(_f) (AMP_BASE_ADDR + 0x0BC + ((_f) * 4)) +#define rDCS_AMP_CACKCSWKDS (AMP_BASE_ADDR + 0x0CC) +#define rDCS_AMP_BISTRXMODE (AMP_BASE_ADDR + 0x0D4) +#endif + +#if (DCS_REG_VERSION == 3 || DCS_REG_VERSION >= 0x10) +#define rDCS_AMP_DCCCONTROL (AMP_BASE_ADDR + 0x0DC) +#define rDCS_AMP_DCCTIMER (AMP_BASE_ADDR + 0x0E0) +#define rDCS_AMP_IMPCALCONTROL2 (AMP_BASE_ADDR + 0x0E8) +#if DCS_REG_VERSION >= 0x10 +#define rDCS_AMP_IMPCALCONTROL3 (AMP_BASE_ADDR + 0x0EC) +#endif // #if DCS_REG_VERSION >= 0x10 + +#elif (DCS_REG_VERSION >= 4 && DCS_REG_VERSION < 0x10) +#define rDCS_AMP_DCCCONTROL (AMP_BASE_ADDR + 0x098) +#define rDCS_AMP_DCCTIMER (AMP_BASE_ADDR + 0x09C) +#endif + +// For AMPDQn +#define rDCS_AMP_DRAMSIGDLY(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x080 + AMP_IFF(_t,0,0x18)) +#define rDCS_AMP_DQDQSDS_F(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x084 + ((_f) * 4)) +#define rDCS_AMP_DIFFMODE_FREQ(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x094 + ((_f) * 4)) +#define rDCS_AMP_DQFLTCTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x0A4) // For AMPDQn only +#define rDCS_AMP_DCC(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x0A8 + AMP_IFF(_t,0,0x28)) + +#if DCS_REG_VERSION < 4 +#define rDCS_AMP_DQDS_F(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x0AC + ((_f) * 4)) +#endif + +#define rDCS_AMP_RDCAPCFG_FREQ(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x100 + ((_f) * 4)) +#define rDCS_AMP_DQSPDENALWYSON(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x110) +#define rDCS_AMP_DQSPDRES(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x114) +#define rDCS_AMP_RDFIFOPTRSTS(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x118) +#define rDCS_AMP_CALDQMSK(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x11C) +#define rDCS_AMP_CALPATCFG(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x120 - AMP_IFF(_t,0,0x10)) +#define rDCS_AMP_DQTRNCFG(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x124 - AMP_IFF(_t,0,0x10)) +#define rDCS_AMP_DQTRNCMD(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x128 - AMP_IFF(_t,0,0x10)) +#define rDCS_AMP_DQTRNSTS(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x12C - AMP_IFF(_t,0,0x10)) + +#define rDCS_AMP_DLLEN(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x180) +#define rDCS_AMP_MDLLFREQBINDIS(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x184) +#define rDCS_AMP_MDLLFREQSCALE(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x188) +#define rDCS_AMP_DLLUPDTCMD(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x18C) +#define rDCS_AMP_MDLLOVRRD(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x190 + AMP_IFF(_t,0,4)) +#define rDCS_AMP_MDLLCODE(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x194 - AMP_IFF(_t,0,4)) +#define rDCS_AMP_DLLLOCKTIM(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x198) +#define rDCS_AMP_DLLLOCKCTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x19C) + +#if (DCS_REG_VERSION >= 4 && DCS_REG_VERSION < 0x10) +#define rDCS_AMP_DLLUPDTINTVL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1A0 - AMP_IFF(_t,0,4)) +#define rDCS_AMP_DLLUPDTCTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1A4 - AMP_IFF(_t,0,4)) +#define rDCS_AMP_CAOUTDLLSCL_FREQ(_f) (AMP_BASE_ADDR + 0x1A4 + ((_f) * 4)) // For AMPCA Only +#define rDCS_AMP_MDLLCODE_CAP_CNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1BC) +#define rDCS_AMP_MDLL_VTSCALE_CNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1C0) +#define rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1C4) +#define rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1C8) +#define rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1CC) +#define rDCS_AMP_CA_VTSCALE_FACTOR_STAT(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1D0) +#define rDCS_AMP_RD_VTSCALE_FACTOR_STAT(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1D4) +#define rDCS_AMP_WR_VTSCALE_FACTOR_STAT(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1D8) + +#else +#define rDCS_AMP_DLLUPDTINTVL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1A0) +#define rDCS_AMP_DLLUPDTCTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1A4) +#define rDCS_AMP_DQSINDLLSCL_FREQ(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1BC + ((_f) * 4)) +#define rDCS_AMP_CAOUTDLLSCL_FREQ(_f) (AMP_BASE_ADDR + 0x1C0 + ((_f) * 4)) // For AMPCA Only +#define rDCS_AMP_MDLLCODE_CAP_CNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1CC) +#define rDCS_AMP_MDLL_VTSCALE_CNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1D0) +#define rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1D4) +#define rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1D8) +#define rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1DC) +#define rDCS_AMP_CA_VTSCALE_FACTOR_STAT(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1E0) +#define rDCS_AMP_RD_VTSCALE_FACTOR_STAT(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1E4) +#define rDCS_AMP_WR_VTSCALE_FACTOR_STAT(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x1E8) +#endif + +#define rDCS_AMP_TESTMODE(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x200 + AMP_IFF(_t,0,0x180)) + +// For AMPDQn Only +#define rDCS_AMP_WRDQDESKEW_CTRL(_t,_d) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x400 + ((_d) * 4)) +#define rDCS_AMP_WRDQSDESKEW_CTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x420) +#define rDCS_AMP_WRDMDESKEW_CTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x424) +#define rDCS_AMP_RDDQDESKEW_CTRL(_t,_d) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x428 + ((_d) * 4)) +#define rDCS_AMP_RDDQSDESKEW_CTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x448) +#define rDCS_AMP_RDDMDESKEW_CTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x44C) + +#define rDCS_AMP_WRDQDQSSDLLCTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x600) +#define rDCS_AMP_WRDQDQSSDLLCODE(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x604) +#define rDCS_AMP_RDSDLLCTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x608) +#define rDCS_AMP_RDSDLLCODE(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x60C) +#define rDCS_AMP_RDCAPSDLLCTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x610) +#define rDCS_AMP_RDCAPSDLLCODE(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x614) +#define rDCS_AMP_RDDQSDLL_DLYSEL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x618) +#define rDCS_AMP_SDLL_UPDATE_CNTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x61c + AMP_IFF(_t,0,0xFC)) +#define rDCS_AMP_DQSDQ_SKEWCTL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x620) +#define rDCS_AMP_DQSDQ_SKEW(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x624) +#define rDCS_AMP_SDLL_UPDATE_DEFER_EN(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x628 + AMP_IFF(_t,0,0xF4)) + +#define rDCS_AMP_WRLVL_DLYCHAIN_CTRL(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x700) +#define rDCS_AMP_WRLVL_SDLL_CODE0(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0x704) + +// For AMPCA Only +#define rDCS_AMP_CADESKEW_CTRL(_d) (AMP_BASE_ADDR + 0x500 + ((_d) * 4)) +#define rDCS_AMP_CSDESKEW_CTRL (AMP_BASE_ADDR + 0x518) +#define rDCS_AMP_CKDESKEW_CTRL (AMP_BASE_ADDR + 0x51C) + +#define rDCS_AMP_CASDLLCTRL (AMP_BASE_ADDR + 0x700) +#define rDCS_AMP_CASDLLCODE (AMP_BASE_ADDR + 0x704) +#define rDCS_AMP_CSSDLLCTRL (AMP_BASE_ADDR + 0x708) +#define rDCS_AMP_CSSDLLCODE (AMP_BASE_ADDR + 0x70C) +#define rDCS_AMP_CKSDLLCTRL (AMP_BASE_ADDR + 0x710) +#define rDCS_AMP_CKSDLLCODE (AMP_BASE_ADDR + 0x714) + +// Some bit definitions +#define RUNSDLLUPDWRRESULT (1 << 2) +#define SDLLOVRVAL_MASK (0x00FF0000) +#define WRLVLRUNUPDWRRESULT (1 << 9) +#define WRLVLSDLLCODE_MASK (0x000000FF) +#define RUNDESKEWUPD (1 << 8) +#define DESKEWCODE_MASK (0x0000003F) +#define VREFSEL_MASK (0x000000FF) +#define DQSVREFSEL_MASK (0x00FF0000) +#define VTSCALEREFUPDATE (1 << 28) +#define VTSCALEREFSTATUS_MASK (0x000003FF) +#define VTSCALEREFSTATUS_SHIFT (0) +#define VTSCALEREFOVERRIDEVAL_MASK (0x03FF0000) +#define VTSCALEREFOVERRIDEVAL_SHIFT (16) + +// #define rDCS_AMP_SDLL_UPDATE_CNTL rDCS_AMP_SDLL_UPDATE_CNTL(0) // 0x718 +// #define rDCS_AMP_SDLL_UPDATE_DEFER_EN rDCS_AMP_SDLL_UPDATE_DEFER_EN(0) // 0x71C +#define rDCS_AMP_MCCPWRONWAYCNTCTRL (AMP_BASE_ADDR + 0x798) +#define rDCS_AMP_MCCPWRONWAYCNTSTAT (AMP_BASE_ADDR + 0x79c) +#define rDCS_AMP_MCCALCHINT (AMP_BASE_ADDR + 0x7c8) + +#define rDCS_AMP_CAWRLVLSDLLCODE (AMP_BASE_ADDR + 0x800) + +#define rDCS_AMP_ODTENABLE_F(_f) (AMP_BASE_ADDR + 0xD00 + ((_f) * 4)) + +#if (DCS_REG_VERSION >= 4 && DCS_REG_VERSION < 0x10) +#define rDCS_AMP_VREF_F(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0xB00 + AMP_IFF(_t,0,0x200) + ((_f) * 4)) +#else +#define rDCS_AMP_VREF_F(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0xB00 + AMP_IFF(_t,0,0x210) + ((_f) * 4)) +#endif + +#define rDCS_AMPDQ_RDDQSMULFACTOR(_t) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0xD00) +#define rDCS_AMPDQ_DFICALTIMING_F(_t,_f) (AMP_BASE_ADDR + ((_t)*AMP_DQ_SPACING) + 0xD80 + ((_f) * 4)) +#define rDCS_AMP_RDWRDQCALTIMING_F(_f) (AMP_BASE_ADDR + 0xE00 + ((_f) * 8)) +#define rDCS_AMP_RDWRDQCALSEGLEN_F(_f) (AMP_BASE_ADDR + 0xE04 + ((_f) * 8)) +#define rDCS_AMP_HWRDWRDQCALTIMINGCTRL(_n) (AMP_BASE_ADDR + 0xE20 + ((_n) * 4)) +#define rDCS_AMP_HWRDDQCALPATPRBS4I (AMP_BASE_ADDR + 0xE2C) +#define rDCS_AMP_HWWRDQCALPATPRBS4I (AMP_BASE_ADDR + 0xE30) +#define rDCS_AMP_HWRDWRDQCALFULLSCANEN (AMP_BASE_ADDR + 0xE34) +#define rDCS_AMP_RDDQCALWINDOW_F(_f) (AMP_BASE_ADDR + 0xE38 + ((_f) * 8)) +#define rDCS_AMP_WRDQCALWINDOW_F(_f) (AMP_BASE_ADDR + 0xE3C + ((_f) * 8)) + +#define rDCS_AMP_DFICALTIMING (AMP_BASE_ADDR + 0xE74) +#define rDCS_AMP_MAXWRDQ_SDLL_MULFACTOR (AMP_BASE_ADDR + 0xE78) +#define rDCS_AMP_MAXRDDQS_SDLL_MULFACTOR (AMP_BASE_ADDR + 0xE7C) +#define rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR (AMP_BASE_ADDR + 0xE80) +#define rDCS_AMPCA_DFICALTIMING_F(_f) (AMP_BASE_ADDR + 0xF80 + ((_f - 1) * 4)) +#define rDCS_AMPCA_DFICALTIMING_RDDQCAL2 (AMP_BASE_ADDR + 0xF90 ) + +#if DCS_REG_VERSION >= 3 +#define rDCS_AMP_HWWRDQCALPATPRBS7(_n) (AMP_BASE_ADDR + 0xEA0 + ((_n) * 4)) +#define rDCS_AMP_HWWRDQCALPATINVERTMASK (AMP_BASE_ADDR + 0xEB0) +#define rDCS_AMP_HWWRDQCALDYNHALFCLKDLYCTRL (AMP_BASE_ADDR + 0xECC) +#define rDCS_AMP_HWRDDQCALVREFCONTROL (AMP_BASE_ADDR + 0xED8) +#define rDCS_AMP_HWRDDQCALTVREF (AMP_BASE_ADDR + 0xEDC) +#define rDCS_AMP_HWRDDQCALVREFOFFSETCONTROL(_n) (AMP_BASE_ADDR + 0xEE0 + ((_n - 1) * 4)) +#define rDCS_AMP_HWWRDQCALVREFCONTROL (AMP_BASE_ADDR + 0xEE8) +#define rDCS_AMP_HWWRDQCALTVREF (AMP_BASE_ADDR + 0xEEC) +#define rDCS_AMP_HWWRDQCALVREFOFFSETCONTROL(_n) (AMP_BASE_ADDR + 0xEF0 + ((_n - 1) * 4)) +#define rDCS_AMP_DQCALBURSTLENMODE (AMP_BASE_ADDR + 0xF10) +#define rDCS_AMP_RDDQCALVREFCODECONTROL (AMP_BASE_ADDR + 0xF18) +#define rDCS_AMP_RDDQCALVREFCODESTATUS (AMP_BASE_ADDR + 0xF1C) +#define rDCS_AMP_WRDQCALVREFCODECONTROL (AMP_BASE_ADDR + 0xF20) +#define rDCS_AMP_WRDQCALVREFCODESTATUS (AMP_BASE_ADDR + 0xF24) +#endif + +#if DCS_REG_VERSION >= 2 +// AMPH +#define rDCS_AMPH_ZCAL_FSM(_n) (AMPH_BASE_ADDR + (_n * 4) + 0x008) +#define rDCS_AMPH_DBG_REG0 (AMPH_BASE_ADDR + 0x024) +#define rDCS_AMPH_CB_DRIVESTR (AMPH_BASE_ADDR + 0x028) +#define rDCS_AMPH_CB_IMPCTL (AMPH_BASE_ADDR + 0x02C) +#define rDCS_AMPH_CB_WKPUPD (AMPH_BASE_ADDR + 0x030) +#define rDCS_AMPH_CB_IOCTL (AMPH_BASE_ADDR + 0x044) +#define rDCS_AMPH_CK_DRIVESTR (AMPH_BASE_ADDR + 0x050) +#define rDCS_AMPH_CK_WKPUPD (AMPH_BASE_ADDR + 0x058) +#define rDCS_AMPH_CK_IOCTL (AMPH_BASE_ADDR + 0x060) +#define rDCS_AMPH_CK_ZDETBIASEN (AMPH_BASE_ADDR + 0x068) +#define rDCS_AMPH_B0_DRIVESTR (AMPH_BASE_ADDR + 0x078) +#define rDCS_AMPH_B0_IMPCTL (AMPH_BASE_ADDR + 0x07C) +#define rDCS_AMPH_B0_WKPUPD (AMPH_BASE_ADDR + 0x080) +#define rDCS_AMPH_B0_DYN_ISEL (AMPH_BASE_ADDR + 0x098) +#define rDCS_AMPH_B0_DYN_ISEL_ASRTIME (AMPH_BASE_ADDR + 0x09C) +#define rDCS_AMPH_B0_IOCTL (AMPH_BASE_ADDR + 0x0A0) +#define rDCS_AMPH_B0_ODT (AMPH_BASE_ADDR + 0x0B0) +#define rDCS_AMPH_B0_ODTCTRL (AMPH_BASE_ADDR + 0x0B4) +#define rDCS_AMPH_DQS0_DRIVESTR (AMPH_BASE_ADDR + 0x0C0) +#define rDCS_AMPH_DQS0_IMPCTL (AMPH_BASE_ADDR + 0x0C4) +#define rDCS_AMPH_DQS0_WKPUPD (AMPH_BASE_ADDR + 0x0C8) +#define rDCS_AMPH_DQS0_DCD_IOCTL (AMPH_BASE_ADDR + 0x0CC) +#define rDCS_AMPH_DQS0_IOCTL (AMPH_BASE_ADDR + 0x0D0) +#define rDCS_AMPH_DQS0_ODT (AMPH_BASE_ADDR + 0x0D8) +#define rDCS_AMPH_DQS0_ZDETBIASEN (AMPH_BASE_ADDR + 0x0DC) +#define rDCS_AMPH_DQS0_ODTCTRL (AMPH_BASE_ADDR + 0x0E0) +#define rDCS_AMPH_B1_DRIVESTR (AMPH_BASE_ADDR + 0x0E8) +#define rDCS_AMPH_B1_IMPCTL (AMPH_BASE_ADDR + 0x0EC) +#define rDCS_AMPH_B1_WKPUPD (AMPH_BASE_ADDR + 0x0F0) +#define rDCS_AMPH_B1_DYN_ISEL (AMPH_BASE_ADDR + 0x108) +#define rDCS_AMPH_B1_IOCTL (AMPH_BASE_ADDR + 0x10C) +#define rDCS_AMPH_B1_ODT (AMPH_BASE_ADDR + 0x11C) +#define rDCS_AMPH_B1_ODTCTRL (AMPH_BASE_ADDR + 0x120) +#define rDCS_AMPH_DQS1_DRIVESTR (AMPH_BASE_ADDR + 0x130) +#define rDCS_AMPH_DQS1_IMPCTL (AMPH_BASE_ADDR + 0x134) +#define rDCS_AMPH_DQS1_WKPUPD (AMPH_BASE_ADDR + 0x138) +#define rDCS_AMPH_DQS1_DCD_IOCTL (AMPH_BASE_ADDR + 0x13C) +#define rDCS_AMPH_DQS1_IOCTL (AMPH_BASE_ADDR + 0x140) +#define rDCS_AMPH_DQS1_ODT (AMPH_BASE_ADDR + 0x148) +#define rDCS_AMPH_DQS1_ODTCTRL (AMPH_BASE_ADDR + 0x14C) +#define rDCS_AMPH_DQS1_ZDETBIASEN (AMPH_BASE_ADDR + 0x150) +#define rDCS_AMPH_DCC_CAL (AMPH_BASE_ADDR + 0x290) +#define rDCS_AMPH_SPARE(_n) (AMPH_BASE_ADDR + (_n * 4) + 0x2FC) +#define rDCS_AMPH_DCC_BYPCA (AMPH_BASE_ADDR + 0x29C) +#define rDCS_AMPH_DCC_BYPCK (AMPH_BASE_ADDR + 0x2A0) +#define rDCS_AMPH_DCC_BYPCS (AMPH_BASE_ADDR + 0x2A4) +#define rDCS_AMPH_DCC_BYPB0 (AMPH_BASE_ADDR + 0x2A8) +#define rDCS_AMPH_DCC_BYPDQS0 (AMPH_BASE_ADDR + 0x2AC) +#define rDCS_AMPH_DCC_BYPB1 (AMPH_BASE_ADDR + 0x2B0) +#define rDCS_AMPH_DCC_BYPDQS1 (AMPH_BASE_ADDR + 0x2B4) + +#else +#define rDCS_AMPH_SLC_REG(_n) (AMPH_BASE_ADDR + (_n * 4) + 0x080) +#endif // #if DCS_REG_VERSION >= 2 + +#define AMP_MAX_RANKS_PER_CHAN (2) +#define DQ_NUM_BITS_PER_BYTE 8 + +// Global Timer Registers +#define rGLBTIMER_MDLLTIMER (GLBTIMER_BASE_ADDR + 0x000) +#define rGLBTIMER_MDLLVOLTRAMPTIMER (GLBTIMER_BASE_ADDR + 0x004) +#define rGLBTIMER_CTRLUPDMASKTIMER (GLBTIMER_BASE_ADDR + 0x008) +#define rGLBTIMER_IDTTIMER (GLBTIMER_BASE_ADDR + 0x00c) +#define rGLBTIMER_RDCALTIMER (GLBTIMER_BASE_ADDR + 0x010) +#define rGLBTIMER_WRCALTIMER (GLBTIMER_BASE_ADDR + 0x014) +#define rGLBTIMER_ZQCTIMER (GLBTIMER_BASE_ADDR + 0x018) + +#if DCS_REG_VERSION >= 0x10 +#define rGLBTIMER_FREQCHNG_ACTIVE (GLBTIMER_BASE_ADDR + 0x094) +#endif + +#if DCS_REG_VERSION >= 3 + +#define rGLBTIMER_DCCTIMER (GLBTIMER_BASE_ADDR + 0x01c) +#define rGLBTIMER_PERCAL_FREQCHNGTIMER (GLBTIMER_BASE_ADDR + 0x020) +#define rGLBTIMER_VOLTRAMPTIMER (GLBTIMER_BASE_ADDR + 0x024) +#define rGLBTIMER_IMPCALTIMER (GLBTIMER_BASE_ADDR + 0x028) +#define rGLBTIMER_PERWRCALCFG (GLBTIMER_BASE_ADDR + 0x02c) +#define rGLBTIMER_PERRDCALCFG (GLBTIMER_BASE_ADDR + 0x030) +#define rGLBTIMER_VOLTRAMPCFG (GLBTIMER_BASE_ADDR + 0x034) +#define rGLBTIMER_FREQCHNGCFG (GLBTIMER_BASE_ADDR + 0x038) +#define rGLBTIMER_PMGRWAKEUPCFG (GLBTIMER_BASE_ADDR + 0x03c) +#define rGLBTIMER_FREQBIN3CALCFG (GLBTIMER_BASE_ADDR + 0x040) +#define rGLBTIMER_CHEN (GLBTIMER_BASE_ADDR + 0x044) +#define rGLBTIMER_CAL2PREFREQCHNGDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x048) +#define rGLBTIMER_PREFREQ2ALLBANKDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x050) +#define rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x058) +#define rGLBTIMER_FREQCHNG2PSTCALDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x060) +#define rGLBTIMER_VOLTRAMP2ALLBANKDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x068) +#define rGLBTIMER_ALLBANK2PMGRACKDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x070) +#define rGLBTIMER_PRECALWAITPERIOD (GLBTIMER_BASE_ADDR + 0x078) +#define rGLBTIMER_CALSEG2ALLBANK(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x07C) +#define rGLBTIMER_ALLBANK2CALSEG(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x084) +#define rGLBTIMER_VREFCNTRL (GLBTIMER_BASE_ADDR + 0x08C) +#define rGLBTIMER_PERVREFCALCFG (GLBTIMER_BASE_ADDR + 0x090) + +#else + +#define rGLBTIMER_PERCAL_FREQCHNGTIMER (GLBTIMER_BASE_ADDR + 0x01c) +#define rGLBTIMER_VOLTRAMPTIMER (GLBTIMER_BASE_ADDR + 0x020) +#define rGLBTIMER_IMPCALTIMER (GLBTIMER_BASE_ADDR + 0x024) +#define rGLBTIMER_PERWRCALCFG (GLBTIMER_BASE_ADDR + 0x028) +#define rGLBTIMER_PERRDCALCFG (GLBTIMER_BASE_ADDR + 0x02c) +#define rGLBTIMER_VOLTRAMPCFG (GLBTIMER_BASE_ADDR + 0x030) +#define rGLBTIMER_FREQCHNGCFG (GLBTIMER_BASE_ADDR + 0x034) +#define rGLBTIMER_PMGRWAKEUPCFG (GLBTIMER_BASE_ADDR + 0x038) +#define rGLBTIMER_FREQBIN3CALCFG (GLBTIMER_BASE_ADDR + 0x03c) +#define rGLBTIMER_CHEN (GLBTIMER_BASE_ADDR + 0x040) +#define rGLBTIMER_CAL2PREFREQCHNGDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x044) +#define rGLBTIMER_PREFREQ2ALLBANKDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x04C) +#define rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x054) +#define rGLBTIMER_FREQCHNG2PSTCALDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x05C) +#define rGLBTIMER_VOLTRAMP2ALLBANKDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x064) +#define rGLBTIMER_ALLBANK2PMGRACKDLY(_n) (GLBTIMER_BASE_ADDR + ((_n) * 4) + 0x06C) + +#endif // #if DCS_REG_VERSION >= 3 + +#endif /* _DCS_S8000_H */ diff --git a/drivers/apple/dcs/rules.mk b/drivers/apple/dcs/rules.mk new file mode 100644 index 0000000..ebe0a0f --- /dev/null +++ b/drivers/apple/dcs/rules.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# Set ENV_IBOOT for calibration code that is shared with SEG +OPTIONS += ENV_IBOOT + +ALL_OBJS += \ + $(LOCAL_DIR)/dcs.o \ + $(LOCAL_DIR)/dcs_init_lib.o + +DCS_CAL_LIB_V1_PLATFORMS := s8000 s8003 + +ifneq ($(filter $(SUB_PLATFORM),$(DCS_CAL_LIB_V1_PLATFORMS)),) + ALL_OBJS += $(LOCAL_DIR)/dcs_calibration.o +else + ALL_OBJS += $(LOCAL_DIR)/dcs_calibration_v2.o +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/displaypipe/displaypipe.c b/drivers/apple/displaypipe/displaypipe.c new file mode 100644 index 0000000..54fad14 --- /dev/null +++ b/drivers/apple/displaypipe/displaypipe.c @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2009-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//Front End +#if WITH_DFE_ADFE +# include +#elif WITH_DFE_ADFE_V2 +# include +#else +# error "unknown displayfrontend" +#endif // WITH_DFE_ADFE + +//Back End +#if WITH_DBE_CLCD +# include +#elif WITH_DBE_RGBOUT +# include +#elif WITH_DBE_ADBE +# include +#else +# error "unknown display-backend" +#endif + +//Transport +#if WITH_HW_DISPLAY_HDMI +#include +#elif (WITH_HW_DISPLAY_EDP || WITH_HW_DISPLAY_DISPLAYPORT) +#include +#include +#endif + +#include + +#ifndef LINEAR_STRIDE_ALIGNMENT +#define LINEAR_STRIDE_ALIGNMENT 64 +#endif + +#define LINEAR_STRIDE_ALIGNMENT_MASK (LINEAR_STRIDE_ALIGNMENT - 1) + +#ifndef TARGET_FB_MULT +#define TARGET_FB_MULT 30 +#endif + +static u_int32_t display_default_color; +static u_int64_t display_frame_us = 16667; +static bool display_enabled; +static bool display_enabled_valid; + +static struct display_window *main_window; +static u_int32_t *red_lut = NULL, *green_lut = NULL, *blue_lut = NULL; + +static struct display_timing *timing_info; + +static const int32_t timing_list_size = sizeof(timing_list) / sizeof(struct display_timing); + +static void display_backend_enable_clocks(bool enable); +static void display_backend_init(struct display_timing *timing); +static void display_backend_enable_timing_generator(bool enable); +static void display_backend_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl); +static int display_set_timings(struct display_timing *timing); +static void display_set_timing_info(); + +static void display_set_timing_info() +{ + const char *env; + int32_t cnt; + + if (timing_info != NULL) + return; + + env = env_get("display-timing"); + if (env == 0) env = ""; + + for (cnt = 0; cnt < timing_list_size; cnt++) { + if (strcmp(env, timing_list[cnt].display_name)) continue; + + timing_info = timing_list + cnt; + timing_info->display_config = target_get_display_configuration(); + } +} + +int display_init(void) +{ + const char *env; + enum colorspace color = CS_4BPP; + int result; + u_int32_t display_id; + int32_t cnt, stride; + struct syscfg_wpcl display_wpcl; + u_int64_t tmp = 1; + + dprintf(DEBUG_SPEW, "display_init()\n"); + + /* clear the display memory */ + bzero((void *)DISPLAY_BASE, DISPLAY_SIZE); + + display_set_timing_info(); + + if (timing_info == 0) { + dprintf(DEBUG_INFO, "Failed to find display timing info, bailing display_init()\n"); + return -1; + } + + // Make sure clocks (both display front-end and back-end) are on + display_backend_enable_clocks(true); + + display_set_timings(timing_info); + + adfe_init(timing_info); + + // Setup back-end (includes dither, color-manager) + display_backend_init(timing_info); + + if (timing_info->pixel_clock) { + // Calculate display frame interval (in usecs) based on timing info + tmp = 1000000ULL; + tmp *= (timing_info->v_back_porch + timing_info->v_front_porch + timing_info->v_pulse_width + timing_info->v_active); + tmp *= (timing_info->h_back_porch + timing_info->h_front_porch + timing_info->h_pulse_width + timing_info->h_active); + tmp /= timing_info->pixel_clock; + } + + display_frame_us = tmp; + env = env_get("display-color-space"); + if (env == 0) env = "RGB888"; + + if (!strcmp(env, "RGB888")) color = CS_RGB888; + else if (!strcmp(env, "RGB565")) color = CS_RGB565; + else if (!strcmp(env, "ARGB8101010")) color = CS_ARGB8101010; + + main_window = display_create_window(0, 0, timing_info->h_active, timing_info->v_active, color); + if (main_window == 0) return -1; + + /* add an environment variable with the address of the framebuffer */ + env_set_uint("framebuffer", (uintptr_t)main_window->c.fb_phys, 0); + + // request the desired pixel clock + clock_set_frequency(timing_info->host_clock_id, 0, 0, 0, 0, timing_info->pixel_clock); + + switch (timing_info->display_type) { +#if WITH_HW_DISPLAY_PINOT + case DISPLAY_TYPE_PINOT : + { + extern int pinot_init(struct display_timing *timing, enum colorspace color, u_int32_t *display_id); + result = pinot_init(timing_info, main_window->cs, &display_id); + break; + } +#endif + +#if WITH_HW_DISPLAY_SUMMIT + case DISPLAY_TYPE_SUMMIT : + { + extern int summit_init(struct display_timing *timing, enum colorspace color, u_int32_t *display_id); + result = summit_init(timing_info, main_window->cs, &display_id); + break; + } +#endif + +#if WITH_HW_DISPLAY_EDP + case DISPLAY_TYPE_EDP : + { + extern int edp_init(struct display_timing *timing, enum colorspace color, u_int32_t *display_id); + result = edp_init(timing_info, main_window->cs, &display_id); + break; + } +#endif + +#if (WITH_HW_DISPLAY_DISPLAYPORT && !WITH_HW_MCU) + + case DISPLAY_TYPE_DP : + { + result = displayport_init_with_timing_info(timing_info); + break; + } +#endif +#if WITH_HW_DISPLAY_HDMI + case DISPLAY_TYPE_HDMI : + { + result = hdmi_init_with_timing_info(timing_info); + break; + } +#endif + + default : + display_id = 0; + result = 0; + } + + if (result == 0) { + if (!display_enabled_valid) + display_enabled = display_get_enable(); + + if (!display_enabled) { + display_set_enable(true, &display_default_color); + } + + red_lut = (u_int32_t *)malloc(257 * sizeof(u_int32_t)); + green_lut = (u_int32_t *)malloc(257 * sizeof(u_int32_t)); + blue_lut = (u_int32_t *)malloc(257 * sizeof(u_int32_t)); + + // Generate linear LUT + stride = 256 >> (10 - (timing_info->display_depth / 3)); + red_lut[0] = 1; + for (cnt = 1; cnt < 257; cnt++) { + if ((cnt % stride) == 1) red_lut[cnt - 1]--; + red_lut[cnt] = red_lut[cnt - 1] + 4; + green_lut[cnt - 1] = blue_lut[cnt - 1] = red_lut[cnt - 1]; + } + green_lut[cnt - 1] = blue_lut[cnt - 1] = red_lut[cnt - 1]; + +#if PRODUCT_IBOOT + paint_install_gamma_table(display_id, 257, red_lut, green_lut, blue_lut); +#endif + paint_get_syscfg_wpcl(&display_wpcl); + dprintf(DEBUG_SPEW, "paint_install_gamma_table: Found WpCl version = 0x%08x, red = 0x%08x, green = 0x%08x, blue = 0x%08x\n", display_wpcl.version, display_wpcl.red, display_wpcl.green, display_wpcl.blue); + + display_backend_install_gamma_table(red_lut, green_lut, blue_lut, &display_wpcl); + + } else { + display_set_enable(false, NULL); + timing_info = NULL; + } + + return result; +} + +void display_clear(void) +{ + if (main_window) { + fill_rect(&main_window->c, 0, 0, main_window->width, main_window->height, display_default_color); + } +} + + +int display_quiesce(bool clear_display) +{ + int result = 0; + + //enable clocks + display_backend_enable_clocks(true); + if (!display_get_enable()) { + //disable the clock + display_backend_enable_clocks(false); + return ENXIO; + } + + display_set_timing_info(); + + if (timing_info == NULL) return result; + + if (clear_display) { + display_clear(); + + display_delay_frames(2); + } + adfe_disable_error_handler(); + + if (red_lut) + free(red_lut); + if (green_lut) + free(green_lut); + if (blue_lut) + free(blue_lut); + + red_lut = NULL; + green_lut = NULL; + blue_lut = NULL; + +#if WITH_HW_DISPLAY_PINOT + if (timing_info->display_type == DISPLAY_TYPE_PINOT) { + extern int pinot_quiesce(void); + result = pinot_quiesce(); + if (result != 0) return result; + } +#endif + +#if WITH_HW_DISPLAY_SUMMIT + if (timing_info->display_type == DISPLAY_TYPE_SUMMIT) { + extern int summit_quiesce(void); + result = summit_quiesce(); + if (result != 0) return result; + } +#endif + +#if WITH_HW_DISPLAY_EDP + if (timing_info->display_type == DISPLAY_TYPE_EDP) { + extern int edp_quiesce(void); + result = edp_quiesce(); + result = 0; + if (result != 0) return result; + } +#endif + +#if WITH_HW_DISPLAY_DISPLAYPORT + if (timing_info->display_type == DISPLAY_TYPE_DP) { + displayport_quiesce(); + result = 0; + } +#endif + +#if WITH_HW_DISPLAY_HDMI + if (timing_info->display_type == DISPLAY_TYPE_HDMI) { + hdmi_quiesce(); + result = 0; + } +#endif + + display_set_enable(false, NULL); + + if (main_window) { + free(main_window); + main_window = NULL; + } + + return result; +} + +bool display_get_enable(void) +{ + bool display_enable; + +#if WITH_DBE_CLCD + display_enable = clcd_get_enable_timing_generator(); +#elif WITH_DBE_RGBOUT + display_enable = rgbout_get_enable_timing_generator(); +#elif WITH_DBE_ADBE + display_enable = adbe_get_enable_timing_generator(); +#else +# error "missing display_backend_enable_timing_generator" +#endif + display_enabled_valid = true; + + return display_enable; +} + +void display_set_enable(bool enable, u_int32_t *color) +{ + if (!display_enabled_valid) + display_enabled = display_get_enable(); + + if (enable == display_enabled) return; + + if (enable) { + if (color != NULL) { + display_default_color = *color; + } + + fill_rect(&main_window->c, 0, 0, main_window->width, main_window->height, display_default_color); + + display_backend_enable_timing_generator(true); + + display_enabled = true; + + } else { + + display_backend_enable_timing_generator(false); + + display_enabled = false; + } +} + +bool display_set_rotation(bool rotate180) +{ + #if WITH_DFE_ADFE_V2 + adfe_set_axis_flip(0, rotate180, rotate180); + return true; + #else + return false; + #endif +} + +void display_delay_frames(u_int32_t frames) +{ + task_sleep(frames * display_frame_us); +} + +/////////////////////////////////////////////////////////////////////////////////// +//With iBoot inside display memory (1 plane Color) +// PANIC_BASE ------------------------------- +// | iBoot | +// |-----------------------------| +// | (unused) | +// |-----------------------------| +// | db_virt (draw) | +// |-----------------------------| +// | fb | +// |-----------------------------|<---- region_valid +// | images | +// |-----------------------------|<---- scratch_base + 4K +// | flatten images | +// DISPLAY_BASE --> ------------------------------ <---- scratch_base +//With iBoot outside display memory (1 plane Color) +// PANIC_BASE ------------------------------- +// | (unused) | +// |-----------------------------| +// | db_virt (draw) | +// |-----------------------------| +// | fb | +// |-----------------------------|<---- region_valid +// | images | +// |-----------------------------|<---- scratch_base + 4K +// | flatten images | +// DISPLAY_BASE --> ------------------------------ <---- scratch_base +//With iBoot outside display memory (2 plane Color) +// PANIC_BASE ------------------------------- +// | (unused) | +// |-----------------------------| +// | plane 1 db_virt (draw) | +// |-----------------------------| +// | plane 0 db_virt (draw) | +// |-----------------------------| +// | plane 1 fb | +// |-----------------------------| +// | plane 0 fb | +// |-----------------------------|<---- region_valid +// | images | +// |-----------------------------|<---- scratch_base + 4K +// | flatten images | +// DISPLAY_BASE --> ------------------------------ <---- scratch_base +/////////////////////////////////////////////////////////////////////////////////// +struct display_window *display_create_window(u_int32_t x, u_int32_t y, u_int32_t width, u_int32_t height, enum colorspace color) +{ + struct display_window *w; + u_int32_t stridelen_in_pixels = width, depth; + uint32_t stridelen_in_bytes; + addr_t fb_base; + size_t fb_size; + size_t fb_region, region_valid; + uint32_t num_of_planes; + uint32_t plane1_depth; + + switch (color) { + case CS_RGB565 : + depth = 16; + num_of_planes = 1; + break; + + case CS_RGB888 : + depth = 32; + num_of_planes = 1; + break; + + case CS_ARGB8101010 : + //the RGB plane is 32 + depth = 32; + num_of_planes = 2; + //Alpha plane is 8 + plane1_depth = 8; + break; + + default : + return 0; + } + + w = malloc(sizeof(struct display_window)); + + w->active = false; + w->cs = color; + w->depth = depth; + w->pos_x = x; + w->pos_y = y; + w->width = width; + w->height = height; + stridelen_in_bytes = (width * depth) / 8; + stridelen_in_bytes = (stridelen_in_bytes + LINEAR_STRIDE_ALIGNMENT_MASK) & ~LINEAR_STRIDE_ALIGNMENT_MASK; + w->stride = stridelen_in_bytes; + stridelen_in_pixels = stridelen_in_bytes / (depth/8); + + // Calculate the frame buffer size rounded up to a page + fb_size = (w->height * w->stride + 0xFFF) & ~0xFFF; + + //If we have more planes, more region_valid memory is required. Adjust the size accordingly + if (num_of_planes > 1) { + size_t plane1_stride_in_bytes = (width * (plane1_depth/8)); + plane1_stride_in_bytes = (plane1_stride_in_bytes + LINEAR_STRIDE_ALIGNMENT_MASK) & ~LINEAR_STRIDE_ALIGNMENT_MASK; + size_t plane1_fb_size = (plane1_stride_in_bytes + 0xFFF) & ~0xFFF; + fb_size += plane1_fb_size; + } + + + //on 32 bit systems, the fb_base has to account for 1 fb + iBoot region. The iBoot region goes away for OS purposes yet the fb remains + region_valid = fb_region = (fb_size * TARGET_FB_MULT)/10; +#ifdef PROTECTED_REGION_SIZE + if(fb_region < fb_size * 2 + PROTECTED_REGION_SIZE) fb_region = fb_size * 2 + PROTECTED_REGION_SIZE ; + region_valid = fb_region - PROTECTED_REGION_SIZE; +#endif + // Calculate the frame buffer base assuming multiple buffers (as defined by TARGET_FB_MULT) from PANIC_BASE + // N.B We use PANIC_BASE since DISPLAY_BASE is used for image manipulation region + fb_base = PANIC_BASE - fb_region; + + platform_init_display_mem(&fb_base, &fb_size); +#ifdef DISPLAY_BASE_NONALIGNED + set_canvas(&w->c, (void *)(PANIC_BASE - fb_region), region_valid, width, height, stridelen_in_pixels, color); +#else + set_canvas(&w->c, (void *)fb_base, region_valid, width, height, stridelen_in_pixels, color); +#endif + paint_init(w, DISPLAY_BASE, fb_base - DISPLAY_BASE); + + adfe_set_ui_layer(0, color, get_plane(0), get_plane(1), width, height); + + display_activate_window(w); + + return w; +} + +void display_set_background_color(u_int32_t color) +{ + adfe_set_background_color(color); +} + +void display_activate_window(struct display_window *win) +{ + u_int32_t layer = 0; + + if (layer > 1) return; + + win->active = true; + + adfe_activate_window(); +} + +static int display_set_timings(struct display_timing *timing) +{ + int result = 0; +#if WITH_HW_DISPLAY_DISPLAYPORT + result = displayport_set_timings(timing); +#endif +#if WITH_HW_DISPLAY_HDMI + result = hdmi_set_timings(timing); +#endif + return result; +} + + +static void display_backend_enable_clocks(bool enable) +{ +#if WITH_DBE_CLCD + clcd_enable_clocks(enable); +#elif WITH_DBE_RGBOUT + rgbout_enable_clocks(enable); +#elif WITH_DBE_ADBE + adbe_enable_clocks(enable); +#else +# error "missing display_backend_enable_clocks" +#endif +} + +static void display_backend_init(struct display_timing *timing) +{ +#if WITH_DBE_CLCD + clcd_init(timing); +#elif WITH_DBE_RGBOUT + rgbout_init(timing); +#elif WITH_DBE_ADBE + adbe_init(timing); +#else +# error "missing display_backend_init" +#endif +} + +static void display_backend_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl) +{ +#if WITH_DBE_CLCD + clcd_install_gamma_table(red_lut, green_lut, blue_lut, wpcl); +#elif WITH_DBE_RGBOUT + rgbout_install_gamma_table(red_lut, green_lut, blue_lut, wpcl); +#elif WITH_DBE_ADBE + adbe_install_gamma_table(red_lut, green_lut, blue_lut, wpcl); +#else +# error "missing display_backend_load_gamma_table" +#endif +} + +static void display_backend_enable_timing_generator(bool enable) +{ +#if WITH_DBE_CLCD + clcd_enable_timing_generator(enable); +#elif WITH_DBE_RGBOUT + rgbout_enable_timing_generator(enable); +#elif WITH_DBE_ADBE + adbe_enable_timing_generator(enable); +#else +# error "missing display_backend_enable_timing_generator" +#endif +} diff --git a/drivers/apple/displaypipe/displaypipe.h b/drivers/apple/displaypipe/displaypipe.h new file mode 100644 index 0000000..1f4ea34 --- /dev/null +++ b/drivers/apple/displaypipe/displaypipe.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAYPIPE_H +#define __APPLE_DISPLAYPIPE_H + +#include + +#define rDPCVERSION (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1018)) +#define rDPCSTATE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x101C)) +#define rDPCGO (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1020)) +#define rDPCRESTART (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1024)) +#define rDPCIRQENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1028)) +#define DPCIRQ_MSTRERR (1<<11) +#define rDPCIRQ (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x102C)) +#define rDPCSIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1030)) +#define rDPCFRMCNT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1034)) +#define rDPCENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1038)) +#if DISP_VERSION < 5 +#define rDPCPFTOP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x103C)) +#endif +#define rDPCPFSIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1040)) +#define rDPCPFSTAT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1044)) +#define rDPCPFHEAD (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1048)) +#if DISP_VERSION < 5 +#define rDPCPFDMA (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104C)) +#define DPCPFDMA_AUTOMODE (1 << 4) +#define DPCPFDMA_BURSTSIZE_1WORD (0 << 8) +#define DPCPFDMA_BURSTSIZE_2WORDS (1 << 8) +#define DPCPFDMA_BURSTSIZE_4WORDS (2 << 8) +#define DPCPFDMA_BURSTSIZE_8WORDS (3 << 8) +#define DPCPFDMA_BURSTSIZE_16WORDS (4 << 8) +#define DPCPFDMA_BURSTSIZE_MASK (7 << 8) +#define DPCPFDMA_WATERMARK(n) ((n) << 16) +#define DPCPFDMA_WATERMARK_MASK (0x7FF << 16) +#else +#define rDPCPFMODE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x104C)) +#define DPCPFMODE_WBEN (1 << 1) +#define DPCPFMODE_AUTOEN (1 << 0) +#endif +#define rDPCPFFLUSH (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1050)) +#define rDPCCLKCNTL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1054)) +#define DPCCLKCNTL_FLOOR(n) ((n && 0xFFFF) << 16) +#define DPCCLKCNTL_PIPE_ENABLE (1 << 12) +#define DPCCLKCNTL_LB_ENABLE (1 << 8) +#define DPCCLKCNTL_V_ENABLE (1 << 4) +#define DPCCLKCNTL_GATEENAB (1 << 0) +#define rDPCMEMACC (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x1058)) + +#if (DISP_VERSION < 3) +#define rDPCPANCNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x105C)) +#define DPCPANCNFG_PANENAB (1 << 0) +#define DPCPANCNFG_PANU0ENAB (1 << 8) +#define DPCPANCNFG_PANU1ENAB (1 << 9) +#define DPCPANCNFG_PANVENAB (1 << 10) +#define DPCPANCNFG_PANBENAB (1 << 11) +#define DPCPANCNFG_PANTIMER(n) ((n) << 16) +#define DPCPANCNFG_PANTIMER_MASK (0xFFFF << 16) +#else +#define rDPCQOSCNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x105C)) +#define DPCQOSCNFG_QOS_ENABLE (1 << 0) +#define DPCQOSCNFG_UIFIFO_ENABLE (1 << 1) +#define DPCQOSCNFG_VIDFIFO_ENABLE (1 << 2) +#if (DISP_VERSION < 4) +#define DPCQOSCNFG_QOS_OPTIMISTIC (1 << 3) +#else +#define DPCQOSCNFG_QOS_OPTIMISTIC (1 << 4) +#endif +#define DPCQOSCNFG_PIPE_ENABLE (1 << 8) +#define DPCQOSCNFG_QOS_TIMER(n) ((n) << 16) +#endif + +#define rDPBBACKCOLOR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x203C)) +#define rDPBLAY1CNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2040)) +#define rDPBLAY2CNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2044)) +#define rDPBLAY3CNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2048)) +#define rDPBCRCENAB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x204C)) +#define rDPBCRCDATA (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2050)) +#define rDPBCRCSNAP (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2054)) +#define rDPBOUTSIZE (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2058)) +#define rDPBCLKLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x205C)) +#define DPBCLKLVL_OFFLVL(n) ((n) << 0) +#define DPBCLKLVL_ONLVL(n) ((n) << 16) +#define rDPBUNDRCNFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2064)) +#if (DISP_VERSION < 3) +#define rDPBPANLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2060)) +#else +#define rDPBQOSLVL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2060)) +#define DPBQOSLVL_MED_WATERMARK(n) ((n) << 0) +#define DPBQOSLVL_HIGH_WATERMARK(n) ((n) << 16) +#define rDPBCSCCOEFR(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x2068)) +#define rDPBCSCCOEFG(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x2074)) +#define rDPBCSCCOEFB(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x4 * (n)) + 0x2080)) +#define rDPBCSCCOFFR (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x208C)) +#define rDPBCSCCOFFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2090)) +#define rDPBCSCCOFFB (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x2094)) +#endif + +#if (DISP_VERSION > 4) +#define rDPUREQCFG (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x403C)) +#define DPUREQCFG_REQ_CNT(_n) ((_n) & 0xFF) +#endif +#define rDPUSRCFMT(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4040)) +#define rDPUSRCBASE(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4044)) +#define rDPUSRCSTRD(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4048)) +#define DPUSRCSTRD_SRCBURST_1BLOCK (0 << 0) +#define DPUSRCSTRD_SRCBURST_2BLOCKS (1 << 0) +#define DPUSRCSTRD_SRCBURST_4BLOCKS (2 << 0) +#define DPUSRCSTRD_SRCBURST_8BLOCKS (3 << 0) +#define DPUSRCSTRD_SRCBURST_MASK (3 << 0) +#define DPUSRCSTRD_SRCSTRIDE_MASK (~0x3F) +#if (DISP_VERSION < 3) +#define rDPUSRCRGNENAB(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x404C)) +#define rDPUOUTSIZE(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4070)) +#define rDPUCLKLVL(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4074)) +#define rDPUPANLVL(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4078)) +#define rDPUSRCSTRXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4050 + (4 * (r)))) +#define rDPUSRCENDXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4060 + (4 * (r)))) +#else +#define rDPUSRCXY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x404C)) +#define rDPUSRCWH(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4050)) +#define rDPUDSTXY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4054)) +#define rDPUDSTWH(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4058)) +#define rDPUSRCRGN(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x405C)) +#define rDPUSRCSTRXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4060 + (4 * (r)))) +#define rDPUSRCENDXY(n, r) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4070 + (4 * (r)))) +#define rDPUDDAINITX(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4080)) +#define rDPUDDAINITY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4084)) +#define rDPUDDASTEPX(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4088)) +#define rDPUDDASTEPY(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x408C)) +#define rDPUMMUCNTL(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + (0x1000 * (n)) + 0x4090)) +#endif + +#define rDPCPERFCNTL (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6008)) +#define rDPCPERFSTAT (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x600C)) +#define rDPCPERFCNFG(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6010 + (4 * (n)))) +#define rDPCPERFDATA(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6020 + (4 * (n)))) +#define rDPCPERFSNAP(n) (*(volatile u_int32_t *)(DISPLAYPIPE_BASE_ADDR + 0x6030 + (4 * (n)))) + +#endif /* ! __APPLE_DISPLAYPIPE_H */ diff --git a/drivers/apple/displaypipe/rules.mk b/drivers/apple/displaypipe/rules.mk new file mode 100644 index 0000000..2d694e1 --- /dev/null +++ b/drivers/apple/displaypipe/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2009-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DISPLAYPIPE=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/displaypipe.o diff --git a/drivers/apple/dither/dither.c b/drivers/apple/dither/dither.c new file mode 100644 index 0000000..c4eaeb5 --- /dev/null +++ b/drivers/apple/dither/dither.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if DITHER_VERSION == 2 +#include "dither_v2.h" +#elif DITHER_VERSION == 3 +#include "dither_v3.h" +#else +#include "dither_v4.h" +#endif + +#ifndef DITHER_BASE_ADDR +#error "DITHER base addr for AppleDither Block is not defined" +#endif + +static uint8_t dither_type; + +#if DITHER_VERSION == 4 +#ifndef TARGET_DITHER_INBITSREDUCTION +#define TARGET_DITHER_INBITSREDUCTION 2 +#endif + +#ifndef TARGET_DITHER_EDOUTTOSTINWIDTH +#define TARGET_DITHER_EDOUTTOSTINWIDTH 3 +#endif + +#ifndef TARGET_DITHER_DITHEROUTWIDTH +#define TARGET_DITHER_DITHEROUTWIDTH 3 +#endif + +#ifndef TARGET_DITHER_ST_METHOD_MAX +#define TARGET_DITHER_ST_METHOD_MAX 3 +#endif + +#ifndef TARGET_DITHER_ST_METHOD_POP +#define TARGET_DITHER_ST_METHOD_POP 0 +#endif + +#ifndef TARGET_DITHER_ST_PHASE +#define TARGET_DITHER_ST_PHASE 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC0 +#define TARGET_DITHER_ST_SKEWLOC0 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC1 +#define TARGET_DITHER_ST_SKEWLOC1 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC2 +#define TARGET_DITHER_ST_SKEWLOC2 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC3 +#define TARGET_DITHER_ST_SKEWLOC3 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC4 +#define TARGET_DITHER_ST_SKEWLOC4 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC5 +#define TARGET_DITHER_ST_SKEWLOC5 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC6 +#define TARGET_DITHER_ST_SKEWLOC6 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC7 +#define TARGET_DITHER_ST_SKEWLOC7 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC8 +#define TARGET_DITHER_ST_SKEWLOC8 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC9 +#define TARGET_DITHER_ST_SKEWLOC9 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC10 +#define TARGET_DITHER_ST_SKEWLOC10 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC11 +#define TARGET_DITHER_ST_SKEWLOC11 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC12 +#define TARGET_DITHER_ST_SKEWLOC12 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC13 +#define TARGET_DITHER_ST_SKEWLOC13 0 +#endif + +#ifndef TARGET_DITHER_ST_SKEWLOC14 +#define TARGET_DITHER_ST_SKEWLOC14 0 +#endif + +void dither_init(uint32_t display_width, uint32_t display_height, uint32_t display_depth) +#else +void dither_init(uint32_t display_depth) +#endif +{ + //Fixing the value for now. When the request comes to use a Blue noise, please ask how to make + //the decision: Based on Target or based on number of dithering bits + dither_type = DITHER_SPATIO_TEMPORAL; + +#ifdef TARGET_DITHER_TYPE + dither_type = TARGET_DITHER_TYPE; +#endif //TARGET_DITHER_TYPE + +#if DITHER_VERSION == 2 + //Number of bits reduced by the dithering algorithm core. + rDITHER_METHOD = (4 << 4) | ((display_depth <= 18) ? 0x3 : 0x2); + rDITHER_BOOST_POP = (display_depth <= 18) ? 0x1 : 0x0; + rDITHER_OUTPUT_WIDTH = (display_depth <=18) ? 0x0 : 0x1; +#endif + +#if DITHER_VERSION == 3 + switch(dither_type) { + case DITHER_SPATIO_TEMPORAL: + dprintf(DEBUG_SPEW, "Spatial_temporal Dither\n"); + //Bypass BN + // [FPGA DEBUG]: Disabling certains backend blocks via ADBE0:MODE_CTL doesn't disable them + rDITHER_BN_OP_CFG = (1 << 29); + + rDITHER_ST_METHOD = (0x4 << 4); + if (display_depth == 24) + rDITHER_ST_METHOD |= (0x1 << 13) | (0x2 << 0); + else if (display_depth <= 18) + rDITHER_ST_METHOD |= (0x1 << 13) | (0x3 << 0); + else + panic("unexpected display depth"); + + break; + + case DITHER_BLUE_NOISE: + // Note: If bn_dither_enable is set and st_dither_enable is cleared, the + // spatio/temporal dither stage must also be disabled internally + // (see DITHER Register Spec.) by setting SPAT_TEMP_METHOD.mode to 0x4 and + // SPAT_TEMP_METHOD.depth to 0x0 + dprintf(DEBUG_SPEW, "Blue_noise Dither\n"); + rDITHER_ST_METHOD |= (0x4 << 13); + rDITHER_ST_METHOD &= ~(0xf); //clear depth + rDITHER_BN_OP_CFG = 1; + uint32_t thr_bit; + switch(display_depth) { + case 24: + thr_bit = DITHER_BN_CONST_THR2BIT; + break; + case 18: + thr_bit = DITHER_BN_CONST_THR4BIT; + rDITHER_BN_OP_CFG |= (0x1 << 24) | (0x1 << 20) | (0x1 << 16); + break; + default: + panic("unexpected display depth"); + } + rDITHER_BN_CONST = (thr_bit << 16 | thr_bit << 8 | thr_bit << 0); + break; + + case DITHER_NONE: + default: + dprintf(DEBUG_SPEW, "%d is not a supported dithering type. Disabling dithering\n", dither_type); + //bypassed and clock-gated if both st_dither_enable and bn_dither_enable are + //cleared + rDITHER_ST_METHOD = 0; + rDITHER_BN_OP_CFG = (1 << 29); + break; + } +#endif + +#if DITHER_VERSION == 4 + rDITHER_ACTIVEREGIONSTART = 0 << 16 | 0; //Set active region start + rDITHER_ACTIVEREGIONSIZE = display_height << 16 | display_width; //Set Active Region + + // Setup for 8-bit panel with VRR + rDITHER_INBITSREDUCTION = TARGET_DITHER_INBITSREDUCTION; + rDITHER_EDOUTTOSTINWIDTH = TARGET_DITHER_EDOUTTOSTINWIDTH; + rDITHER_DITHEROUTWIDTH = TARGET_DITHER_DITHEROUTWIDTH; + + switch(dither_type) { + case DITHER_SPATIO_TEMPORAL: + dprintf(DEBUG_SPEW, "Spatial_temporal Dither\n"); + + rDITHER_ST_METHOD |= (TARGET_DITHER_ST_METHOD_MAX << 13) | (TARGET_DITHER_ST_METHOD_POP << 8); + if (display_depth == 24) + rDITHER_ST_METHOD |= (0x2 << 0); + else if (display_depth <= 18) + rDITHER_ST_METHOD |= (0x3 << 0); + else + panic("unexpected display depth"); + + rDITHER_ST_PHASE = TARGET_DITHER_ST_PHASE; + rDITHER_ST_SKEWLOC0 = TARGET_DITHER_ST_SKEWLOC0; + rDITHER_ST_SKEWLOC1 = TARGET_DITHER_ST_SKEWLOC1; + rDITHER_ST_SKEWLOC2 = TARGET_DITHER_ST_SKEWLOC2; + rDITHER_ST_SKEWLOC3 = TARGET_DITHER_ST_SKEWLOC3; + rDITHER_ST_SKEWLOC4 = TARGET_DITHER_ST_SKEWLOC4; + rDITHER_ST_SKEWLOC5 = TARGET_DITHER_ST_SKEWLOC5; + rDITHER_ST_SKEWLOC6 = TARGET_DITHER_ST_SKEWLOC6; + rDITHER_ST_SKEWLOC7 = TARGET_DITHER_ST_SKEWLOC7; + rDITHER_ST_SKEWLOC8 = TARGET_DITHER_ST_SKEWLOC8; + rDITHER_ST_SKEWLOC9 = TARGET_DITHER_ST_SKEWLOC9; + rDITHER_ST_SKEWLOC10 = TARGET_DITHER_ST_SKEWLOC10; + rDITHER_ST_SKEWLOC11 = TARGET_DITHER_ST_SKEWLOC11; + rDITHER_ST_SKEWLOC12 = TARGET_DITHER_ST_SKEWLOC12; + rDITHER_ST_SKEWLOC13 = TARGET_DITHER_ST_SKEWLOC13; + rDITHER_ST_SKEWLOC14 = TARGET_DITHER_ST_SKEWLOC14; + + rDITHER_ENABLE |= (1 << 1); + break; + + case DITHER_ERROR_DIFFUSION: + dprintf(DEBUG_SPEW, "Error Diffusion Dither\n"); + + rDITHER_ED_THRESHOLDRED = (8192 << 2); + rDITHER_ED_THRESHOLDGREEN = (8192 << 2); + rDITHER_ED_THRESHOLDBLUE = (8192 << 2); + + rDITHER_ENABLE |= (1 << 0); + break; + + case DITHER_NONE: + default: + dprintf(DEBUG_SPEW, "%d is not a supported dithering type. Disabling dithering\n", dither_type); + //bypassed and clock-gated if both st_dither_enable and bn_dither_enable are + //cleared + rDITHER_ST_METHOD = 0; + break; + + } + //double buffer registers. force them to update + rDITHER_UPDATECONTROL = DITHER_UPDATECONTROL_UPDATEENABLETIMING | + DITHER_UPDATECONTROL_UPDATEREQTIMING ; +#endif +} + + +void dither_set_enable(bool enable) +{ +#if DITHER_VERSION == 2 + if (enable) { + rDITHER_ENABLE = (dither_type == DITHER_SPATIO_TEMPORAL)? (1 << 0) : (1 << 1); + } else { + rDITHER_ENABLE = 0; + } +#endif +} diff --git a/drivers/apple/dither/dither_v2.h b/drivers/apple/dither/dither_v2.h new file mode 100644 index 0000000..bd6d7a4 --- /dev/null +++ b/drivers/apple/dither/dither_v2.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DITHER_V2_H +#define __DITHER_V2_H + +#define rDITHER_ENABLE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0000)) //Enable Dither block +#define rDITHER_METHOD (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0004)) //Main dithering method setting +#define rDITHER_VERSION (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0008)) //Block revision number +#define rDITHER_BOOST_POP (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x000c)) //Bit-popping and bit-boost +#define rDITHER_OUTPUT_WIDTH (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0010)) //Output bit-width setting +#define rDITHER_ST_OFFSET (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0014)) //Phase offset for Blue/Red wrt green +#define rDITHER_ST_SEQUENCE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0018)) //Phase sequence for over 4 frames +#define rDITHER_ST_KERNEL0 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x001c)) //Kernel0 +#define rDITHER_ST_KERNEL1 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0020)) //Kernel1 +#define rDITHER_ST_KERNEL2 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0024)) //Kernel2 +#define rDITHER_ST_KERNEL3 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0028)) //Kernel3 +#define rDITHER_ST_KERNEL4 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x002c)) //Kernel4 +#define rDITHER_ST_KERNEL5 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0030)) //Kernel5 +#define rDITHER_ST_KERNEL6 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0034)) //Kernel6 +#define rDITHER_ST_KERNEL7 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0038)) //Kernel7 +#define rDITHER_SKEWLOC0 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x003c)) //Skew location0 +#define rDITHER_SKEWLOC1 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0040)) //Skew location1 +#define rDITHER_SKEWLOC2 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0044)) //Skew location2 +#define rDITHER_SKEWLOC3 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0048)) //Skew location3 +#define rDITHER_SKEWLOC4 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x004c)) //Skew location4 +#define rDITHER_SKEWLOC5 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0050)) //Skew location5 +#define rDITHER_SKEWLOC6 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0054)) //Skew location6 +#define rDITHER_SKEWLOC7 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0058)) //Skew location7 +#define rDITHER_SKEWLOC8 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x005c)) //Skew location8 +#define rDITHER_SKEWLOC9 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0060)) //Skew location9 +#define rDITHER_SKEWLOC10 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0064)) //Skew location10 +#define rDITHER_SKEWLOC11 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0068)) //Skew location11 +#define rDITHER_SKEWLOC12 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x006c)) //Skew location12 +#define rDITHER_SKEWLOC13 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0070)) //Skew location13 +#define rDITHER_SKEWLOC14 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0074)) //Skew location14 +#define rDITHER_REG_UPDATE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0078)) //Register Update Control +#define rDITHER_CRC_CON (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x007c)) //CRC Control Register +#define rDITHER_CRC_R (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0080)) //CRC for R component +#define rDITHER_CRC_G (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0084)) //CRC for G component +#define rDITHER_CRC_B (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0088)) //CRC for B component +#define rDITHER_HACTIVE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x008c)) //Dither Horizontal Active Width +#define rDITHER_SPARE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0090)) //Spare Register + +#endif /* ! __DITHER_V2_H */ diff --git a/drivers/apple/dither/dither_v3.h b/drivers/apple/dither/dither_v3.h new file mode 100644 index 0000000..351df26 --- /dev/null +++ b/drivers/apple/dither/dither_v3.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _DITHER_V3_H +#define _DITHER_V3_H + +//Space-Temporal Dither Registers +#define rDITHER_ST_VERSION (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0000)) //Version (major and minor revision number) +#define rDITHER_ST_METHOD (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0004)) //Dither method setting +#define rDITHER_ST_PHASE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0008)) //Sequence of dither matrix rotation phases +#define rDITHER_ST_KERNEL0 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x000c)) //Kernel bit pattern for input pixel[2:0] == 0 +#define rDITHER_ST_KERNEL1 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0010)) //Kernel bit pattern for input pixel[2:0] == 1 +#define rDITHER_ST_KERNEL2 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0014)) //Kernel bit pattern for input pixel[2:0] == 2 +#define rDITHER_ST_KERNEL3 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0018)) //Kernel bit pattern for input pixel[2:0] == 3 +#define rDITHER_ST_KERNEL4 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x001c)) //Kernel bit pattern for input pixel[2:0] == 4 +#define rDITHER_ST_KERNEL5 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0020)) //Kernel bit pattern for input pixel[2:0] == 5 +#define rDITHER_ST_KERNEL6 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0024)) //Kernel bit pattern for input pixel[2:0] == 6 +#define rDITHER_ST_KERNEL7 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0028)) //Kernel bit pattern for input pixel[2:0] == 7 +#define rDITHER_ST_SKEWLOC0 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x002c)) //Skew location0 +#define rDITHER_ST_SKEWLOC1 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0030)) //Skew location1 +#define rDITHER_ST_SKEWLOC2 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0034)) //Skew location2 +#define rDITHER_ST_SKEWLOC3 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0038)) //Skew location3 +#define rDITHER_ST_SKEWLOC4 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x003c)) //Skew location4 +#define rDITHER_ST_SKEWLOC5 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0040)) //Skew location5 +#define rDITHER_ST_SKEWLOC6 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0044)) //Skew location6 +#define rDITHER_ST_SKEWLOC7 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0048)) //Skew location7 +#define rDITHER_ST_SKEWLOC8 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x004c)) //Skew location8 +#define rDITHER_ST_SKEWLOC9 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0050)) //Skew location9 +#define rDITHER_ST_SKEWLOC10 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0054)) //Skew location10 +#define rDITHER_ST_SKEWLOC11 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0058)) //Skew location11 +#define rDITHER_ST_SKEWLOC12 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x005c)) //Skew location12 +#define rDITHER_ST_SKEWLOC13 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0060)) //Skew location13 +#define rDITHER_ST_SKEWLOC14 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0064)) //Skew location14 +#define rDITHER_ST_CRC_CON (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0068)) //CRC Control Register +#define rDITHER_ST_CRC_R (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x006c)) //CRC for R component +#define rDITHER_ST_CRC_G (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0070)) //CRC for G component +#define rDITHER_ST_CRC_B (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0074)) //CRC for B component + +//Blue-noise +#define rDITHER_BN_VERSION (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0080)) //Version (major and minor revision number) +#define rDITHER_BN_OP_CFG (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0084)) //Configuration of Dither Operation +#define rDITHER_BN_CONST (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0088)) //Constant Threshold for Blue Noise Dither +#define DITHER_BN_CONST_THR2BIT 0x2 +#define DITHER_BN_CONST_THR4BIT 0x8 +#define DITHER_BN_CONST_THR5BIT 0x10 + +#endif /* ! _DITHER_V3_H */ diff --git a/drivers/apple/dither/dither_v4.h b/drivers/apple/dither/dither_v4.h new file mode 100644 index 0000000..8bc6043 --- /dev/null +++ b/drivers/apple/dither/dither_v4.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _DITHER_V4_H +#define _DITHER_V4_H + +#define rDITHER_ENABLE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0000)) //Enable register for pipeline blocks +#define rDITHER_UPDATECONTROL (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0004)) //Synchronize LUT and register updates to next vertical blank interval +#define DITHER_UPDATECONTROL_UPDATEENABLETIMING (1 << 1) +#define DITHER_UPDATECONTROL_UPDATEREQTIMING (1 << 0) + +#define rDITHER_ACTIVEREGIONSTART (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0008)) //Pixel Coordinates of Upper Left Hand of Active Window +#define rDITHER_ACTIVEREGIONSIZE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x000C)) //Width and Height of Active Region +#define rDITHER_INBITSREDUCTION (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0010)) //Reduce input pixel width +#define rDITHER_EDOUTTOSTINWIDTH (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0014)) //Pixel width between ED and ST +#define rDITHER_DITHEROUTWIDTH (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0018)) //Output width of dither pipeline. Unused bits will be 0. + +//ED Dither +#define rDITHER_ED_THRESHOLDRED (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0080)) //Per Channel Threshold Registers. This is typically set to equivalent pixel value of .5 +#define rDITHER_ED_THRESHOLDGREEN (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0084)) //Per Channel Threshold Registers. This is typically set to equivalent pixel value of .5 +#define rDITHER_ED_THRESHOLDBLUE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0088)) //Per Channel Threshold Registers. This is typically set to equivalent pixel value of .5 + +// XXX - Are these right??? +#define DITHER_BN_CONST_THR2BIT 0x2 +#define DITHER_BN_CONST_THR4BIT 0x8 +#define DITHER_BN_CONST_THR5BIT 0x10 + +//Space-Temporal Dither Registers +#define rDITHER_ST_METHOD (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0100)) //Dither method setting +#define rDITHER_ST_PHASE (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0104)) //Sequence of dither matrix rotation phases +#define rDITHER_ST_KERNEL0 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0108)) //Kernel bit pattern for input pixel[2:0] == 0 +#define rDITHER_ST_KERNEL1 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x010C)) //Kernel bit pattern for input pixel[2:0] == 1 +#define rDITHER_ST_KERNEL2 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0110)) //Kernel bit pattern for input pixel[2:0] == 2 +#define rDITHER_ST_KERNEL3 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0114)) //Kernel bit pattern for input pixel[2:0] == 3 +#define rDITHER_ST_KERNEL4 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0118)) //Kernel bit pattern for input pixel[2:0] == 4 +#define rDITHER_ST_KERNEL5 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x011C)) //Kernel bit pattern for input pixel[2:0] == 5 +#define rDITHER_ST_KERNEL6 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0120)) //Kernel bit pattern for input pixel[2:0] == 6 +#define rDITHER_ST_KERNEL7 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0124)) //Kernel bit pattern for input pixel[2:0] == 7 +#define rDITHER_ST_SKEWLOC0 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0128)) //Skew location0 +#define rDITHER_ST_SKEWLOC1 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x012C)) //Skew location1 +#define rDITHER_ST_SKEWLOC2 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0130)) //Skew location2 +#define rDITHER_ST_SKEWLOC3 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0134)) //Skew location3 +#define rDITHER_ST_SKEWLOC4 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0138)) //Skew location4 +#define rDITHER_ST_SKEWLOC5 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x013C)) //Skew location5 +#define rDITHER_ST_SKEWLOC6 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0140)) //Skew location6 +#define rDITHER_ST_SKEWLOC7 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0144)) //Skew location7 +#define rDITHER_ST_SKEWLOC8 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0148)) //Skew location8 +#define rDITHER_ST_SKEWLOC9 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x014C)) //Skew location9 +#define rDITHER_ST_SKEWLOC10 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0150)) //Skew location10 +#define rDITHER_ST_SKEWLOC11 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0154)) //Skew location11 +#define rDITHER_ST_SKEWLOC12 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0158)) //Skew location12 +#define rDITHER_ST_SKEWLOC13 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x015C)) //Skew location13 +#define rDITHER_ST_SKEWLOC14 (*(volatile u_int32_t *)(DITHER_BASE_ADDR + 0x0160)) //Skew location14 + +#endif /* ! _DITHER_V4_H */ diff --git a/drivers/apple/dither/rules.mk b/drivers/apple/dither/rules.mk new file mode 100644 index 0000000..af2bbe6 --- /dev/null +++ b/drivers/apple/dither/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DITHER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dither.o diff --git a/drivers/apple/dockchannel/dockchannel_regs.h b/drivers/apple/dockchannel/dockchannel_regs.h new file mode 100644 index 0000000..43acf25 --- /dev/null +++ b/drivers/apple/dockchannel/dockchannel_regs.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_DOCKCHANNEL_H +#define __APPLE_DOCKCHANNEL_H + +#include +#include SUB_PLATFORM_SPDS_HEADER(dock_channels) + +#define DOCKCHANNEL_STRIDE (0x10000) + +// Macro names in SPDS are pretty bad for readability +// rdar://problem/20455612 + +#define rDOCKCHANNELS_GLOBAL(_p) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + DOCK_CHANNELS_DOCKCHANNELS_GLOBAL_OFFSET + _p) + +#define rDOCKCHANNELS_AGENT_AP_INTR_CTRL *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + DOCK_CHANNELS_DOCKCHANNELS_AGENT1_AGENT1_INTR_CONTROL_OFFSET) +#define rDOCKCHANNELS_AGENT_AP_INTR_STATUS *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + DOCK_CHANNELS_DOCKCHANNELS_AGENT1_AGENT1_INTR_STATUS_OFFSET) +#define rDOCKCHANNELS_AGENT_AP_ERR_INTR_CTRL *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + DOCK_CHANNELS_DOCKCHANNELS_AGENT1_AGENT1_ERR_INTR_CONTROL_OFFSET) +#define rDOCKCHANNELS_AGENT_AP_ERR_INTR_STATUS *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + DOCK_CHANNELS_DOCKCHANNELS_AGENT1_AGENT1_ERR_INTR_STATUS_OFFSET) +#define rDOCKCHANNELS_AGENT_AP_ERR_CAUSE0 *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + DOCK_CHANNELS_DOCKCHANNELS_AGENT1_AGENT1_ERR_CAUSE0_OFFSET) +#define rDOCKCHANNELS_AGENT_AP_ERR_CAUSE1 *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + DOCK_CHANNELS_DOCKCHANNELS_AGENT1_AGENT1_ERR_CAUSE1_OFFSET) + +// Device side config registers +#define rDOCKCHANNELS_DEV_CONFIG_WR_WATERMARK(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_CONFIG_DEV_WR_WATERMARK_OFFSET) +#define rDOCKCHANNELS_DEV_CONFIG_RD_WATERMARK(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_CONFIG_DEV_RD_WATERMARK_OFFSET) +#define rDOCKCHANNELS_DEV_DRAIN_CFG(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_CONFIG_DEV_DRAIN_CFG_OFFSET) +#define rDOCKCHANNELS_DEV_ERROR_CFG(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_CONFIG_DEV_ERROR_CFG_OFFSET) +#define rDOCKCHANNELS_DEV_FIFO_CTRL(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_CONFIG_DEV_FIFO_CTRL_OFFSET) + +// Device side fifo registers +#define rDOCKCHANNELS_DEV_WDATA1(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_WDATA_1_OFFSET) +#define rDOCKCHANNELS_DEV_WDATA2(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_WDATA_2_OFFSET) +#define rDOCKCHANNELS_DEV_WDATA3(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_WDATA_3_OFFSET) +#define rDOCKCHANNELS_DEV_WDATA4(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_WDATA_4_OFFSET) +#define rDOCKCHANNELS_DEV_WSTAT(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_WSTAT_OFFSET) +#define rDOCKCHANNELS_DEV_RDATA1(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_RDATA_1_OFFSET) +#define rDOCKCHANNELS_DEV_RDATA2(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_RDATA_2_OFFSET) +#define rDOCKCHANNELS_DEV_RDATA3(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_RDATA_3_OFFSET) +#define rDOCKCHANNELS_DEV_RDATA4(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_RDATA_4_OFFSET) +#define rDOCKCHANNELS_DEV_RSTAT(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DEV_DATA_DEV_RSTAT_OFFSET) + +// Dock side config registers +#define rDOCKCHANNELS_DOCK_CONFIG_WR_WATERMARK(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DOCK_CONFIG_DOCK_WR_WATERMARK_OFFSET) +#define rDOCKCHANNELS_DOCK_CONFIG_RD_WATERMARK(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DOCK_CONFIG_DOCK_RD_WATERMARK_OFFSET) +#define rDOCKCHANNELS_DOCK_DRAIN_CFG(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DOCK_CONFIG_DOCK_DRAIN_CFG_OFFSET) +#define rDOCKCHANNELS_DOCK_ERROR_CFG(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DOCK_CONFIG_DOCK_ERROR_CFG_OFFSET) +#define rDOCKCHANNELS_DOCK_FIFO_CTRL(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DOCK_CONFIG_DOCK_FIFO_CTRL_OFFSET) + +// Dock side fifo registers +#define rDOCKCHANNELS_DOCK_RDATA1(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DOCK_DATA_DOCK_RDATA_1_OFFSET) +#define rDOCKCHANNELS_DOCK_RDATA3(_ch) *(volatile uint32_t *)(DOCKCHANNELS_BASE_ADDR + ((_ch) * DOCKCHANNEL_STRIDE) + DOCK_CHANNELS_DOCKCHANNELS_CHANNEL0_DOCK_DATA_DOCK_RDATA_3_OFFSET) +#endif /* __APPLE_DOCKCHANNEL_H */ diff --git a/drivers/apple/dockchannel/dockchannel_uart.c b/drivers/apple/dockchannel/dockchannel_uart.c new file mode 100644 index 0000000..a1ae994 --- /dev/null +++ b/drivers/apple/dockchannel/dockchannel_uart.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dockchannel_regs.h" + +extern int DebugUartReady; + +#define DOCKCHANNEL_UART_RX_LEN (16) + +// Allow a 30ms stall of wall clock time before DockFIFO starts dropping characters +#define DOCKCHANNEL_WR_MAX_STALL_US (60*1000) + +static CBUFFER dockchannel_uart_rx_cbuf; +static struct task_event dockchannel_uart_rx_event; + +static uint64_t prev_dockchannel_drained_time; // Last time we've seen the DockFIFO drained by an external agent +static uint64_t prev_dockchannel_spaces; // Previous w_stat level of the DockFIFO. +static uint32_t dockchannel_capacity; + + +#define INSTRUMENT_DOCKCHANNEL_DRAIN_COUNTER 1 + +#if INSTRUMENT_DOCKCHANNEL_DRAIN_COUNTER + +#define DOCKCHANNEL_STAT_INCR(x) ((x)++) + +static unsigned int dockchannel_stat_active_stall_loops; +static unsigned int dockchannel_stat_dropped_characters; + +#else +#define DOCKCHANNEL_STAT_INCR(x) +#endif + +//======================= +// Local funtions +//======================= + +// M8: Remove drain timer logic in DockChannel driver after verifying on silicon +static int dockchannel_drain_on_stall() +{ + // Called when DockFIFO runs out of spaces. + // Check if the DockFIFO reader has stalled. If so, empty the DockFIFO ourselves. + // Return number of bytes drained. + + if (timer_ticks_to_usecs(timer_get_ticks() - prev_dockchannel_drained_time) >= DOCKCHANNEL_WR_MAX_STALL_US) { + // It's been more than DOCKFIFO_WR_MAX_STALL_US and nobody read from the FIFO + // Drop a character. + DOCKCHANNEL_STAT_INCR(dockchannel_stat_dropped_characters); + + (void)rDOCKCHANNELS_DOCK_RDATA1(DOCKCHANNEL_UART); + prev_dockchannel_spaces++; + return 1; + } + return 0; +} + +static int32_t dockchannel_uart_write_byte(uint8_t byte) +{ + + /** + * DockFIFO Draining algorithm: + * + * We want DockFIFO UART to try hard to preserve characters as long as someone is + * listening to the DockFIFO. But we also want DockFIFO to drop characters rapidly + * when the FIFO is full and nobody is listening. + * + * So, when the DockFIFO is full, we will hang and poll for a max of DOCKFIFO_WR_MAX_STALL_US + * If this time expires, we will begin instantly dropping the oldest character when we notice + * the DockFIFO to be full (e.g. nobody is listening to DockFIFO). + * + * But, the moment we see someone start emptying the DockFIFO, the timer resets. + * This will achieve a good balance between making sure we don't drop chars when the host is listening, + * and making sure UART write overhead is low when nobody is attached to it. + * + **/ + + // Atomically check for free space in write fifo and enqueue a byte. + + enter_critical_section(); + for (;;) { + uint32_t spaces = rDOCKCHANNELS_DEV_WSTAT(DOCKCHANNEL_UART) & 0x1ff; + + if (spaces >= dockchannel_capacity || spaces > prev_dockchannel_spaces) { + // More spaces showed up. That can only mean someone read the FIFO. + // Note that if the DockFIFO is empty we cannot tell if someone is listening, + // we can only give them the benefit of the doubt. + + prev_dockchannel_drained_time = timer_get_ticks(); + } + prev_dockchannel_spaces = spaces; + + if (spaces > 0 || dockchannel_drain_on_stall()) { + // We either had spaces, or just kicked out a stale byte on a stalled DockFIFO. + break; + } + exit_critical_section(); + + // If we reached here, the DockFIFO is still full, probably due to heavy UART + // traffic with an active reader. + DOCKCHANNEL_STAT_INCR(dockchannel_stat_active_stall_loops); + + enter_critical_section(); + } + rDOCKCHANNELS_DEV_WDATA1(DOCKCHANNEL_UART) = byte; + prev_dockchannel_spaces--; // After writing a byte we have one fewer space than previously expected. + exit_critical_section(); + return 0; +} + +static int32_t dockchannel_uart_write(const uint8_t *data, size_t count, bool wait) +{ + RELEASE_ASSERT(data != NULL); + int32_t ret = 0; + for (size_t i = 0; ret == 0 && i < count; ++i) { + ret = dockchannel_uart_write_byte(data[i]); + } + return ret; +} + +static int32_t dockchannel_uart_read(uint8_t *data, size_t count, bool wait) +{ + int32_t bytes_read = 0; + + RELEASE_ASSERT(data != NULL); + +retry_read: + if (wait && (!cb_readable_size(&dockchannel_uart_rx_cbuf))) + event_wait(&dockchannel_uart_rx_event); + + /* disable rx interrupt */ + rDOCKCHANNELS_AGENT_AP_INTR_CTRL &= ~(1<<1); + mask_int(INT_DOCKCHANNELS_AP); + + bytes_read += cb_read_unsafe(&dockchannel_uart_rx_cbuf, data + bytes_read, count - bytes_read); + + /* enable rx interrupt */ + rDOCKCHANNELS_AGENT_AP_INTR_CTRL |= (1<<1); + unmask_int(INT_DOCKCHANNELS_AP); + + if (((size_t)bytes_read < count) && wait) + goto retry_read; + + return bytes_read; +} + +static int dockchannel_uart_reader_task(void *arg) +{ + for(;;) { + char c; + int32_t len; + + len = dockchannel_uart_read((uint8_t *)&c, 1, true); + if ((len > 0) && ((DebugUartReady & kPowerNVRAMiBootDebugIAPSerial) != 0)) + debug_pushchar(c); + } + return 0; +} + +static void dockchannel_uart_interrupt(void *arg) +{ + uint32_t intr_status = rDOCKCHANNELS_AGENT_AP_INTR_STATUS; + + // Clear status to deassert interrupt + rDOCKCHANNELS_AGENT_AP_INTR_STATUS = (1<<1); + + // Disable interrupts and mask so that we dont get interrupted while processing + // this data + rDOCKCHANNELS_AGENT_AP_INTR_CTRL &= ~(1<<1); + mask_int(INT_DOCKCHANNELS_AP); + + // Read watermark interrupt + if ((intr_status >> 1) & 1) { // Rx + + + while (((rDOCKCHANNELS_DEV_RSTAT(DOCKCHANNEL_UART) & 0x1ff) != 0) && cb_free_space(&dockchannel_uart_rx_cbuf)) + cb_putc_unsafe(&dockchannel_uart_rx_cbuf, (rDOCKCHANNELS_DEV_RDATA1(DOCKCHANNEL_UART) >> 8) & 0xff); + + /* signal reader */ + event_signal(&dockchannel_uart_rx_event); + } else { + // Spurious interrupt since we only enable the dock channel 0 read watermark interrupt + // Unmask interrupts and continue + rDOCKCHANNELS_AGENT_AP_INTR_CTRL |= (1<<1); + unmask_int(INT_DOCKCHANNELS_AP); + } +} + +//======================= +// Global funtions +//======================= + +int32_t dockchannel_uart_init() +{ + // Setup clock + clock_gate(CLK_AOP, true); + + // reset fifos + rDOCKCHANNELS_DEV_FIFO_CTRL(DOCKCHANNEL_UART) = 1; + rDOCKCHANNELS_DOCK_FIFO_CTRL(DOCKCHANNEL_UART) = 1; + + // Empty the DockChannel by draining it until OCCUPANCY is 0, then measure its capacity + while (rDOCKCHANNELS_DOCK_RDATA3(DOCKCHANNEL_UART) & 0x7F); + + dockchannel_capacity = rDOCKCHANNELS_DEV_WSTAT(DOCKCHANNEL_UART) & 0xffff; + + // Setup drain timer + // Each tick is an AOP clock cycle and we want the period to be 30 ms + // which is ~ twice the kanzi sampling time + uint32_t period = clock_get_frequency(CLK_AOP) * (0.003); + + if (period == 0) + dprintf(DEBUG_CRITICAL, "Disabling DockChannel Drain Timer. This can lead to loss of data. \n"); + + rDOCKCHANNELS_DOCK_DRAIN_CFG(DOCKCHANNEL_UART) = period; + + dprintf(DEBUG_SPEW, "%s: Drain timer period %d \n", __FUNCTION__, period); + + cb_create(&dockchannel_uart_rx_cbuf, DOCKCHANNEL_UART_RX_LEN); + event_init(&dockchannel_uart_rx_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + // Using watermark for the purpose of signalling not empty fifo + rDOCKCHANNELS_DEV_CONFIG_RD_WATERMARK(DOCKCHANNEL_UART) = 1; + rDOCKCHANNELS_AGENT_AP_INTR_CTRL = (1<<1); + + // AP has a shared interrupt for all channels. We only enable the relevant interrupts (read watermark) + // for dock channel in iBoot. If there are multiple dockchannel clients we will need an interrupt filter + // type function. + install_int_handler(INT_DOCKCHANNELS_AP, &dockchannel_uart_interrupt, (void *)NULL); + unmask_int(INT_DOCKCHANNELS_AP); + + task_start(task_create("dockchannel_uart reader", dockchannel_uart_reader_task, NULL, 0x200)); + + dprintf(DEBUG_SPEW, "%s\n", __FUNCTION__); + + return 0; +} + +int32_t dockchannel_uart_putc(char c) +{ + return dockchannel_uart_write((uint8_t *)&c, 1, true); +} + +int32_t dockchannel_uart_getc(bool wait) /* returns -1 if no data available */ +{ + char c; + int32_t len; + + len = dockchannel_uart_read((uint8_t *)&c, 1, wait); + if (len == 0) + return -1; + + return c; +} + +void dockchannel_enable_clock_gating(uint32_t channel) +{ + rDOCKCHANNELS_GLOBAL(DOCK_CHANNELS_DOCKCHANNELS_GLOBAL_DC_CFG_OFFSET) |= (1 << (4 * (channel + 1))); +} + +void dockchannel_enable_top_clock_gating() +{ + rDOCKCHANNELS_GLOBAL(DOCK_CHANNELS_DOCKCHANNELS_GLOBAL_DC_CFG_OFFSET) |= 1; +} + +void dockchannel_access_enable(uint32_t enable_flags) +{ + uint32_t curr_value = rDOCKCHANNELS_GLOBAL(DOCK_CHANNELS_DOCKCHANNELS_GLOBAL_DOCK_ACCESS_OFFSET); + + dprintf(DEBUG_SPEW, "%s: dockchannel_access_reg:0x%08x, requested:0x%08x\n", __FUNCTION__, curr_value, enable_flags); + + // XXX Easy WA but bug (18708180) should have been fixed. Decide whether to keep or not. + if (curr_value) + panic("dockchannel_access_enable already nonzero (0x%08x), this can cause a hang due to ", curr_value); + + rDOCKCHANNELS_GLOBAL(DOCK_CHANNELS_DOCKCHANNELS_GLOBAL_DOCK_ACCESS_OFFSET) = enable_flags; + + dprintf(DEBUG_SPEW, "%s: finished, dockchannel_access_reg:0x%08x \n", __FUNCTION__, rDOCKCHANNELS_GLOBAL(DOCK_CHANNELS_DOCKCHANNELS_GLOBAL_DOCK_ACCESS_OFFSET)); +} diff --git a/drivers/apple/dockchannel/include/drivers/dockchannel/dockchannel.h b/drivers/apple/dockchannel/include/drivers/dockchannel/dockchannel.h new file mode 100644 index 0000000..21532cc --- /dev/null +++ b/drivers/apple/dockchannel/include/drivers/dockchannel/dockchannel.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DOCKCHANNEL_H +#define __DOCKCHANNEL_H + +int32_t dockchannel_uart_init(); +int32_t dockchannel_uart_putc(char c); +int32_t dockchannel_uart_getc(bool wait); + +void dockchannel_enable_clock_gating(uint32_t num); +void dockchannel_enable_top_clock_gating(); +void dockchannel_access_enable(uint32_t enable_flags); + +#endif /* __DOCKCHANNEL_H */ diff --git a/drivers/apple/dockchannel/rules.mk b/drivers/apple/dockchannel/rules.mk new file mode 100644 index 0000000..fb26df1 --- /dev/null +++ b/drivers/apple/dockchannel/rules.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2013-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifneq ($(filter $(DOCKCHANNELS), uart),) + OPTIONS += \ + WITH_HW_DOCKCHANNEL_UART=1 \ + + ALL_OBJS += \ + $(LOCAL_DIR)/dockchannel_uart.o +endif + +ifneq ($(DOCKCHANNELS),) + ALL_OBJS += \ + + GLOBAL_INCLUDES += $(LOCAL_DIR)/include +endif \ No newline at end of file diff --git a/drivers/apple/dockfifo/cobs.c b/drivers/apple/dockfifo/cobs.c new file mode 100644 index 0000000..750c1d1 --- /dev/null +++ b/drivers/apple/dockfifo/cobs.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +#if defined(TEST) +# include +# define DEBUG_INFO 0 +# define DEBUG_SPEW 0 +#endif + +#include "cobs.h" + +bool cobs_encode(void *out_buf, size_t out_buf_bytes, + const void *in_buf, size_t in_buf_bytes, + size_t *out_buf_used) +{ + // Output buffer iterator, skipping first code byte. + uint8_t *restrict out = (uint8_t *) out_buf; + size_t out_pos = 1; + + // Input buffer iterator, starting at beginning of buffer. + const uint8_t *restrict in = (const uint8_t *) in_buf; + size_t in_pos = 0; + + // Position of the code prefixing the current non-zero run of data. + size_t code_pos = 0; + uint8_t code = 1; + if (out_buf_bytes < 1) { + dprintf(DEBUG_INFO, + "COBS-encoding always has at least one byte output\n"); + return false; + } + + // Copy non-zero runs of data + while (in_pos < in_buf_bytes) { + uint8_t byte = in[in_pos++]; + if (byte != 0) { + // Copy non-0x00 byte across. + if (out_pos >= out_buf_bytes - 1) { + // Must be space for this data byte, + // and then at least one more code byte. + dprintf(DEBUG_INFO, + "COBS-encode ran out of space\n"); + return false; + } + out[out_pos++] = byte; + // Increment code. 8 bit limit checked below. + ++code; + } + if (byte == 0 || code >= 0xff) { + // Input is 0x00 byte, or we just hit the max code. + // Fill in the skipped code byte before the run. + out[code_pos] = code; + code = 1; + // Already checked for code byte space above. + code_pos = out_pos++; + } + } + // Output final code assuming an implicit 0x00 terminator. + // Invariant: code_pos < out_buf_bytes. + out[code_pos] = code; + *out_buf_used = out_pos; + return true; +} + +bool cobs_decode(void *out_buf, size_t out_buf_bytes, + const void *in_buf, size_t in_buf_bytes, + size_t *out_buf_used) +{ + // Output buffer iterator. + uint8_t *restrict out = (uint8_t *) out_buf; + size_t out_pos = 0; + + // Input buffer iterator. + const uint8_t *restrict in = (const uint8_t *) in_buf; + size_t in_pos = 0; + + while (in_pos < in_buf_bytes) { + uint8_t code = in[in_pos++]; + if (code == 0) { + dprintf(DEBUG_INFO, + "COBS-decode found illegal 0x00 byte\n"); + return false; + } + // Copy one less data bytes than the code. + for (uint8_t i = 1; i < code; ++i) { + if (in_pos >= in_buf_bytes) { + dprintf(DEBUG_INFO, + "COBS-decode found truncated input\n"); + return false; + } else if (out_pos >= out_buf_bytes) { + dprintf(DEBUG_INFO, + "COBS-decode ran out of space %d/%d\n", + (int) out_pos, (int) out_buf_bytes); + return false; + } + out[out_pos++] = in[in_pos++]; + } + // Output trailing 0x00, unless it's the implicit terminator, + // or it was the max value code. + if (code != 0xff && in_pos < in_buf_bytes) { + if (out_pos >= out_buf_bytes) { + dprintf(DEBUG_INFO, + "COBS-decode ran out of space\n"); + return false; + } + out[out_pos++] = 0x00; + } + } + *out_buf_used = out_pos; + return true; +} + +#ifdef TEST + +#include +#include + +static void dump_buf(const uint8_t *buf, size_t bytes) { + for (size_t i = 0; i < bytes; ++i) { + printf(" %02x", buf[i]); + } + printf("\n"); +} + +static void test_case(const uint8_t *in_buf, size_t in_buf_size, + const uint8_t *expect_buf, size_t expect_buf_size) +{ + uint8_t out_buf[1024]; + uint8_t out_buf2[1024]; + assert(sizeof(out_buf) == sizeof(out_buf2)); + assert(in_buf_size <= sizeof(out_buf) && + expect_buf_size <= sizeof(out_buf)); + size_t out_used = 0; + + // Test forward encoding matches expected output. + bool ok = cobs_encode(out_buf, sizeof(out_buf), + in_buf, in_buf_size, + &out_used); + assert(ok); + if (out_used != expect_buf_size) { + printf("Encode generated %d bytes instead of %d\n", + (int) out_used, (int) expect_buf_size); + dump_buf(out_buf, out_used); + abort(); + } + assert(memcmp(out_buf, expect_buf, expect_buf_size) == 0); + + // Test round-trip decoding matches original input. + ok = cobs_decode(out_buf2, sizeof(out_buf2), + out_buf, expect_buf_size, + &out_used); + assert(ok); + if (out_used != in_buf_size) { + printf("Decode generated %d bytes instead of %d\n", + (int) out_used, (int) in_buf_size); + dump_buf(out_buf2, out_used); + abort(); + } + assert(memcmp(out_buf2, in_buf, in_buf_size) == 0); +} + +int main() +{ + printf("COBS test\n"); + + { + // Empty packet encodes a single 0x01. + static const uint8_t expect[1] = { 0x01 }; + test_case(NULL, 0, expect, sizeof(expect)); + } + + { + // Short run, no zeroes. + static const uint8_t in_buf[3] = { 0x01, 0x02, 0x03 }; + static const uint8_t expect[4] = { 0x04, 0x01, 0x02, 0x03 }; + test_case(in_buf, sizeof(in_buf), expect, sizeof(expect)); + } + + { + // Single zero encodes to a double 0x01. + static const uint8_t in_buf[1] = { 0x00 }; + static const uint8_t expect[2] = { 0x01, 0x01 }; + test_case(in_buf, sizeof(in_buf), expect, sizeof(expect)); + } + + { + // 254 bytes encode to 0xff 0x01 + uint8_t in_buf[254]; + memset(in_buf, 0xff, sizeof(in_buf)); + uint8_t expect[256]; + expect[0] = 0xff; + memset(expect + 1, 0xff, sizeof(expect) - 2); + expect[sizeof(expect) - 1] = 0x01; + test_case(in_buf, sizeof(in_buf), expect, sizeof(expect)); + } + + { + // 254 bytes and a zero encode to 0xff 0x01 0x01 + uint8_t in_buf[255]; + memset(in_buf, 0xff, sizeof(in_buf)); + in_buf[sizeof(in_buf) - 1] = 0x00; + uint8_t expect[257]; + expect[0] = 0xff; + memset(expect + 1, 0xff, sizeof(expect) - 3); + expect[sizeof(expect) - 2] = 0x01; + expect[sizeof(expect) - 1] = 0x01; + test_case(in_buf, sizeof(in_buf), expect, sizeof(expect)); + } + + printf("COBS test passed\n"); + return 0; +} + +#endif // defined(TEST) diff --git a/drivers/apple/dockfifo/cobs.h b/drivers/apple/dockfifo/cobs.h new file mode 100644 index 0000000..82f1d0b --- /dev/null +++ b/drivers/apple/dockfifo/cobs.h @@ -0,0 +1,38 @@ +#ifndef COBS_H +#define COBS_H 1 + +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +// COBS-encode from an input buffer to an output buffer. +// Input and output must not be the same or overlap. +// The byte stuffing algorithm may grow the data size. +// Returns true if the output fits in out_buf_bytes, and sets +// *out_buf_used to the new length. +// Returns false if the output does not fit. Output buffer is clobbered. +bool cobs_encode(void *out_buf, size_t out_buf_bytes, + const void *in_buf, size_t in_buf_bytes, + size_t *out_buf_used); + +// COBS-decode from an input buffer to an output buffer. +// Input and output must not be the same or overlap. +// The byte stuffing algorithm may shrink the data size. +// Returns true if properly COBS-encoded data was decoded successfully, +// and sets *out_buf_used to the new length. +// Returns false if illegal COBS codes are present, or are inconsistent +// with the input buffer size. Output buffer clobbered. +bool cobs_decode(void *out_buf, size_t out_buf_bytes, + const void *in_buf, size_t in_buf_bytes, + size_t *out_buf_used); + +#endif // defined(COBS_H) diff --git a/drivers/apple/dockfifo/dockfifo_bulk.c b/drivers/apple/dockfifo/dockfifo_bulk.c new file mode 100644 index 0000000..2f203ab --- /dev/null +++ b/drivers/apple/dockfifo/dockfifo_bulk.c @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "cobs.h" +#include "dockfifo_regs.h" +#include "endian_tools.h" +#include "lib/cksum.h" + +// #undef DEBUG_LEVEL +// #define DEBUG_LEVEL DEBUG_SPEW + +// Slowest rate of polling write fifo when full. +#define MAX_CHECK_INTERVAL 100000 + +// Maximum size of frame before stuffing bytes inserted, not including CRC. +#define MAX_UNSTUFFED_FRAME (DOCKFIFO_BULK_MRU + 4) + +// Maximum size of frame after stuffing bytes inserted (growing its size). +// Worst case need 1 extra coding byte per 254 byte segment. +#define MAX_STUFFED_FRAME (MAX_UNSTUFFED_FRAME + \ + (MAX_UNSTUFFED_FRAME + 253) / 254) + +// Small buffer to help speed up RX transfers. +#define RX_CBUF_SIZE 256 + +struct PacketBuffer { + uint8_t stuffed_buf[MAX_STUFFED_FRAME]; + uint8_t unstuffed_buf[MAX_UNSTUFFED_FRAME]; +}; + +static struct task_event dockfifo_bulk_rx_event; + +static struct PacketBuffer rx_packet; +static struct PacketBuffer tx_packet; + +// When not in sync, we need a framing byte before accepting input. +static bool rx_sync = true; + +// Small cbuffer to accelerate reading from the DBGFIFO. +static CBUFFER rx_cbuf; + + +//======================= +// Local funtions +//======================= + +static void dockfifo_bulk_fill_rx_cbuf(void) +{ + size_t min_occupancy = 0; + size_t bytes = cb_free_space(&rx_cbuf); + while (bytes > 0) { + if ((min_occupancy >= 4) && (bytes >= 4)) { + dprintf(DEBUG_SPEW, + "dockfifo_bulk_fill_rx_cbuf 4B %d %d\n", + (int) min_occupancy, (int) bytes); + // At least 4 bytes available and 4 bytes to read. + uint32_t rdata_4 = + rDBGFIFO_R_DATA(DOCKFIFO_BULK_READ, 4); + cb_write_unsafe(&rx_cbuf, + (const uint8_t *) &rdata_4, 4); + bytes -= 4; + min_occupancy -= 4; + } else { + // Read between 1 and 3 bytes, including FIFO status. + uint32_t to_read = bytes; + if (to_read > 3) { + to_read = 3; + } + uint32_t rdata_n = + rDBGFIFO_R_DATA(DOCKFIFO_BULK_READ, to_read); + // Get FIFO status *before* read took place. + uint32_t occupancy = rdata_n & 0x7f; + dprintf(DEBUG_SPEW, + "dockfifo_bulk_fill_rx_cbuf occ:%d %d %d\n", + (int) occupancy, + (int) min_occupancy, + (int) bytes); + if (occupancy == 0) { + // If no bytes were available, break + // the loop instead of busy polling. + break; + } + // Between 1 and 3 inclusive bytes were pumped + // from the FIFO. + uint32_t got_bytes = to_read; + if (got_bytes > occupancy) { + got_bytes = occupancy; + } + cb_write_unsafe(&rx_cbuf, + ((const uint8_t *) &rdata_n) + 1, + got_bytes); + bytes -= got_bytes; + min_occupancy = occupancy - got_bytes; + } + } +} + +static uint8_t dockfifo_bulk_read_byte(void) +{ + // Grab a byte from the rx cbuffer if possible. + int c = cb_getc_unsafe(&rx_cbuf); + if (c >= 0) { + return (uint8_t) c; + } + // Otherwise, try to fill up the cbuffer. + for (;;) { + // Fill cbuffer from DBGFIFO. + dockfifo_bulk_fill_rx_cbuf(); + // Try again. + c = cb_getc_unsafe(&rx_cbuf); + if (c >= 0) { + return (uint8_t) c; + } + // Still nothing - wait for interrupt. + dprintf(DEBUG_SPEW, + "dbgfifo_bulk_read_byte wait IRQ avail %d\n", + (int) (rDBGFIFO_R_STAT(DOCKFIFO_BULK_WRITE) & 0xffff)); + unmask_int(dockfifo_configs[DOCKFIFO_BULK_READ].irq); + event_wait(&dockfifo_bulk_rx_event); + dprintf(DEBUG_SPEW, + "dbgfifo_bulk_read_byte got IRQ avail %d\n", + (int) (rDBGFIFO_R_STAT(DOCKFIFO_BULK_WRITE) & 0xffff)); + } +} + +static void dockfifo_bulk_write_byte(uint8_t byte) +{ + // Wait until the FIFO has at least one byte available. + uint32_t check_interval = 1; + while ((rDBGFIFO_W_STAT(DOCKFIFO_BULK_WRITE) & 0xffff) == 0) { + task_sleep(check_interval); + check_interval *= 2; + if (check_interval > MAX_CHECK_INTERVAL) { + check_interval = MAX_CHECK_INTERVAL; + } + } + rDBGFIFO_W_DATA(DOCKFIFO_BULK_WRITE, 1) = byte; +} + +static void dockfifo_bulk_write_bytes(const uint8_t *data, size_t count) +{ + while (count > 0) { + // Wait until the FIFO has available space. + uint32_t check_interval = 1; + uint16_t avail; + for (;;) { + avail = rDBGFIFO_W_STAT(DOCKFIFO_BULK_WRITE) & 0xffff; + if (avail > 0) { + break; + } + task_sleep(check_interval); + check_interval *= 2; + if (check_interval > MAX_CHECK_INTERVAL) { + check_interval = MAX_CHECK_INTERVAL; + } + } + // Fill the available space up to the remaining count. + size_t fill = (avail < count) ? avail : count; + // Use 32 bit writes as much as possible. + for (size_t i = 0; i < fill / sizeof(uint32_t); ++i) { + uint32_t word; + memcpy(&word, data, sizeof(word)); + data += sizeof(word); + rDBGFIFO_W_DATA(DOCKFIFO_BULK_WRITE, 4) = word; + } + // Write remaining bits out in a single transaction. + size_t remainder = fill % sizeof(uint32_t); + if (remainder > 0) { + uint32_t word = 0; + memcpy(&word, data, remainder); + data += remainder; + rDBGFIFO_W_DATA(DOCKFIFO_BULK_WRITE, remainder) = word; + } + count -= fill; + } +} + +static void dockfifo_bulk_interrupt_handler(void *arg) +{ + int32_t which_bulk = (int32_t) arg; + if (which_bulk != DOCKFIFO_BULK_READ) { + panic("dockfifo_bulk_interrupt_handler wrong arg: %d", + (int) which_bulk); + } + // Just mask the interrupt and defer to a task. The hardware + // FIFO is large and has pacing. + uint16_t avail = rDBGFIFO_R_STAT(DOCKFIFO_BULK_READ) & 0xffff; + if (avail > 0) { + //dprintf(DEBUG_SPEW, "irq with %d data\n", (int) avail); + mask_int(dockfifo_configs[DOCKFIFO_BULK_READ].irq); + event_signal(&dockfifo_bulk_rx_event); + } else { + dprintf(DEBUG_INFO, "Spurious DBGFIFO bulk irq\n"); + } +} + +//======================= +// Global funtions +//======================= + +int32_t dockfifo_bulk_read_frame(void *buf, size_t bytes, size_t *received) +{ + *received = 0; + + // Get into sync if necessary. + while (!rx_sync) { + uint8_t byte = dockfifo_bulk_read_byte(); + if (byte == 0) { + dprintf(DEBUG_INFO, "Found sync byte\n"); + rx_sync = true; + } else { + dprintf(DEBUG_INFO, "Bulk re-sync, dropping 0x%02x\n", + byte); + } + } + + // Block reading bytes until we have a complete frame. + size_t pos = 0; + for (;;) { + uint8_t byte = dockfifo_bulk_read_byte(); + if (byte == 0) { + if (pos > 0) { + // Got non-empty frame. + dprintf(DEBUG_SPEW, "Got frame, %d bytes\n", + (int) pos); + break; + } else { + // Allowed to have EOF-SOF combinations. + dprintf(DEBUG_SPEW, "Ignoring empty frame\n"); + } + } else if (pos < MAX_STUFFED_FRAME) { + // Got a data byte, and room to insert it. + dprintf(DEBUG_SPEW, "Data[%d] = 0x%02x\n", + (int) pos, byte); + rx_packet.stuffed_buf[pos] = byte; + ++pos; + } else { + // MRU overflow. + dprintf(DEBUG_INFO, "Bulk overflow 0x%02x\n", byte); + rx_sync = false; + break; + } + } + if (!rx_sync) { + // Bad framing. + return -1; + } + + // COBS decode. + size_t unstuffed_bytes = 0; + if (!cobs_decode(rx_packet.unstuffed_buf, + sizeof(rx_packet.unstuffed_buf), + rx_packet.stuffed_buf, pos, + &unstuffed_bytes)) { + // Abandon dispatch if the COBS encoding is bad. + dprintf(DEBUG_INFO, "Bad COBS data\n"); + return -1; + } + + // Must be at least enough space for a CRC. + if (unstuffed_bytes < 4) { + dprintf(DEBUG_INFO, "Runt packet len %d\n", + (int) unstuffed_bytes); + return -1; + } + + size_t payload_size = unstuffed_bytes - 4; + + // Must be enough room to receive the buffer up to the CRC. + if (payload_size > bytes) { + dprintf(DEBUG_INFO, "Frame payload too large: %d vs %d\n", + (int) payload_size, (int) bytes); + return -1; + } + + // Check CRC-32 is good. + uint32_t computed_crc = crc32(rx_packet.unstuffed_buf, payload_size); + uint32_t sent_crc = read_le_32(rx_packet.unstuffed_buf, payload_size); + if (computed_crc != sent_crc) { + dprintf(DEBUG_INFO, + "Bad CRC %d: computed 0x%08x received 0x%08x\n", + (int) payload_size, computed_crc, sent_crc); + return -1; + } + dprintf(DEBUG_SPEW, "Received frame with CRC 0x%08x\n", sent_crc); + + // Success - we have a correctly received frame. + memcpy(buf, rx_packet.unstuffed_buf, payload_size); + *received = payload_size; + return 0; +} + +int32_t dockfifo_bulk_write_frame(const void *buf, size_t bytes) +{ + // Need room for pipe number and CRC-32. + if (bytes > sizeof(tx_packet.unstuffed_buf) - 4) { + dprintf(DEBUG_INFO, "No room to serialize packet\n"); + return -1; + } + + // Copy packet to unstuffed packet buffer, append with CRC-32. + memcpy(tx_packet.unstuffed_buf, buf, bytes); + uint32_t crc = crc32(tx_packet.unstuffed_buf, bytes); + write_le_32(tx_packet.unstuffed_buf, bytes, crc); + + // COBS byte-stuffing. + size_t stuffed_size = 0; + if (!cobs_encode(tx_packet.stuffed_buf, sizeof(tx_packet.stuffed_buf), + tx_packet.unstuffed_buf, bytes + 4, + &stuffed_size)) { + dprintf(DEBUG_INFO, "No room to serialize framing\n"); + return -1; + } + + dprintf(DEBUG_SPEW, "Send frame with CRC 0x%08x\n", crc); + // SOF. + dprintf(DEBUG_SPEW, "Send SOF\n"); + dockfifo_bulk_write_byte(0x00); + // COBS stuffed data. + dprintf(DEBUG_SPEW, "Send %d data\n", (int) stuffed_size); + dockfifo_bulk_write_bytes(tx_packet.stuffed_buf, stuffed_size); + // EOF. + dprintf(DEBUG_SPEW, "Send EOF\n"); + dockfifo_bulk_write_byte(0x00); + + return 0; +} + +int32_t dockfifo_bulk_init() +{ + dprintf(DEBUG_SPEW, "dockfifo_bulk_init\n"); + + // Initialize rx cbuffer. + cb_create(&rx_cbuf, RX_CBUF_SIZE); + + // Setup hardware. + clock_gate(CLK_SPU, true); + clock_gate(CLK_DOCKFIFO, true); + + // Reset fifos. + rDBGFIFO_CNFG(DOCKFIFO_BULK_READ) = (1 << 31); + rDBGFIFO_CNFG(DOCKFIFO_BULK_WRITE) = (1 << 31); + spin(1); + rDBGFIFO_CNFG(DOCKFIFO_BULK_READ) = (0 << 31); + rDBGFIFO_CNFG(DOCKFIFO_BULK_WRITE) = (0 << 31); + + // Initialize local events. + event_init(&dockfifo_bulk_rx_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + dprintf(DEBUG_SPEW, "interrupt: %d\n", + (int) dockfifo_configs[DOCKFIFO_BULK_READ].irq); + install_int_handler(dockfifo_configs[DOCKFIFO_BULK_READ].irq, + &dockfifo_bulk_interrupt_handler, + (void *)DOCKFIFO_BULK_READ); + + // Enable access to fifo + platform_dockfifo_access_enable(DOCKFIFO_BULK_READ, true); + platform_dockfifo_access_enable(DOCKFIFO_BULK_WRITE, true); + + return 0; +} + +int32_t dockfifo_bulk_quiesce() +{ + dprintf(DEBUG_SPEW, "dockfifo_bulk_quiesce\n"); + + mask_int(dockfifo_configs[DOCKFIFO_BULK_READ].irq); + + // Disable access to fifo + platform_dockfifo_access_enable(DOCKFIFO_BULK_READ, false); + platform_dockfifo_access_enable(DOCKFIFO_BULK_WRITE, false); + + // Reset rx cbuffer. + cb_reset(&rx_cbuf); + + // Reset fifos. + rDBGFIFO_CNFG(DOCKFIFO_BULK_READ) = (1 << 31); + rDBGFIFO_CNFG(DOCKFIFO_BULK_WRITE) = (1 << 31); + spin(1); + rDBGFIFO_CNFG(DOCKFIFO_BULK_READ) = (0 << 31); + rDBGFIFO_CNFG(DOCKFIFO_BULK_WRITE) = (0 << 31); + + clock_gate(CLK_DOCKFIFO, false); + clock_gate(CLK_SPU, false); + + return 0; +} diff --git a/drivers/apple/dockfifo/dockfifo_regs.h b/drivers/apple/dockfifo/dockfifo_regs.h new file mode 100644 index 0000000..a27019f --- /dev/null +++ b/drivers/apple/dockfifo/dockfifo_regs.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_DOCKFIFO_H +#define __APPLE_DOCKFIFO_H + +#include + +#define DBGFIFO_W_SPACING (0x1000) +#define DBGFIFO_CNFG_CG_ENA (0x1) + +#define rDBGFIFO_R_DATA(_f, _n) (*(volatile uint32_t *)(DBGFIFO_0_BASE_ADDR + ((_f) * DBGFIFO_SPACING) + ((_n) * 4))) +#define rDBGFIFO_R_STAT(_f) (*(volatile uint32_t *)(DBGFIFO_0_BASE_ADDR + ((_f) * DBGFIFO_SPACING) + 0x14)) +#define rDBGFIFO_W_DATA(_f, _n) (*(volatile uint32_t *)(DBGFIFO_0_BASE_ADDR + ((_f) * DBGFIFO_SPACING) + DBGFIFO_W_SPACING + ((_n) * 4))) +#define rDBGFIFO_W_STAT(_f) (*(volatile uint32_t *)(DBGFIFO_0_BASE_ADDR + ((_f) * DBGFIFO_SPACING) + DBGFIFO_W_SPACING + 0x14)) +#define rDBGFIFO_CNFG(_f) (*(volatile uint32_t *)(DBGFIFO_0_BASE_ADDR + ((_f) * DBGFIFO_SPACING) + 0x2000)) +#define rDBGFIFO_DRAIN(_f) (*(volatile uint32_t *)(DBGFIFO_0_BASE_ADDR + ((_f) * DBGFIFO_SPACING) + 0x2004)) +#define rDBGFIFO_INTMASK(_f) (*(volatile uint32_t *)(DBGFIFO_0_BASE_ADDR + ((_f) * DBGFIFO_SPACING) + 0x2008)) + +#endif /* __APPLE_DOCKFIFO_H */ diff --git a/drivers/apple/dockfifo/dockfifo_uart.c b/drivers/apple/dockfifo/dockfifo_uart.c new file mode 100644 index 0000000..0265f3b --- /dev/null +++ b/drivers/apple/dockfifo/dockfifo_uart.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dockfifo_regs.h" + +extern int DebugUartReady; + +#define DOCKFIFO_UART_RX_LEN (16) + +// Allow a 30ms stall of wall clock time before DockFIFO starts dropping characters +#define DOCKFIFO_WR_MAX_STALL_US (30*1000) + +static CBUFFER dockfifo_uart_rx_cbuf; +static struct task_event dockfifo_uart_rx_event; + +static uint64_t prev_dockfifo_drained_time; // Last time we've seen the DockFIFO drained by an external agent +static uint64_t prev_dockfifo_spaces; // Previous w_stat level of the DockFIFO. +static uint32_t dockfifo_capacity; + + +#define INSTRUMENT_DOCKFIFO_DRAIN_COUNTER 1 + +#if INSTRUMENT_DOCKFIFO_DRAIN_COUNTER + +#define DOCKFIFO_STAT_INCR(x) ((x)++) + +static unsigned int dockfifo_stat_active_stall_loops; +static unsigned int dockfifo_stat_dropped_characters; + +#else +#define DOCKFIFO_STAT_INCR(x) +#endif + +//======================= +// Local funtions +//======================= + +static int dockfifo_drain_on_stall() +{ + // Called when DockFIFO runs out of spaces. + // Check if the DockFIFO reader has stalled. If so, empty the DockFIFO ourselves. + // Return number of bytes drained. + + if (timer_ticks_to_usecs(timer_get_ticks() - prev_dockfifo_drained_time) >= DOCKFIFO_WR_MAX_STALL_US) { + // It's been more than DOCKFIFO_WR_MAX_STALL_US and nobody read from the FIFO + // Drop a character. + DOCKFIFO_STAT_INCR(dockfifo_stat_dropped_characters); + + (void)rDBGFIFO_R_DATA(DOCKFIFO_UART_READ, 1); + prev_dockfifo_spaces++; + return 1; + } + return 0; +} + +static int32_t dockfifo_uart_write_byte(uint8_t byte) +{ + + /** + * DockFIFO Draining algorithm: + * + * We want DockFIFO UART to try hard to preserve characters as long as someone is + * listening to the DockFIFO. But we also want DockFIFO to drop characters rapidly + * when the FIFO is full and nobody is listening. + * + * So, when the DockFIFO is full, we will hang and poll for a max of DOCKFIFO_WR_MAX_STALL_US + * If this time expires, we will begin instantly dropping the oldest character when we notice + * the DockFIFO to be full (e.g. nobody is listening to DockFIFO). + * + * But, the moment we see someone start emptying the DockFIFO, the timer resets. + * This will achieve a good balance between making sure we don't drop chars when the host is listening, + * and making sure UART write overhead is low when nobody is attached to it. + * + **/ + + // Atomically check for free space in write fifo and enqueue a byte. + enter_critical_section(); + for (;;) { + uint32_t spaces = rDBGFIFO_W_STAT(DOCKFIFO_UART_WRITE) & 0xffff; + + if (spaces >= dockfifo_capacity || spaces > prev_dockfifo_spaces) { + // More spaces showed up. That can only mean someone read the FIFO. + // Note that if the DockFIFO is empty we cannot tell if someone is listening, + // we can only give them the benefit of the doubt. + + prev_dockfifo_drained_time = timer_get_ticks(); + } + prev_dockfifo_spaces = spaces; + + if (spaces > 0 || dockfifo_drain_on_stall()) { + // We either had spaces, or just kicked out a stale byte on a stalled DockFIFO. + break; + } + exit_critical_section(); + + // If we reached here, the DockFIFO is still full, probably due to heavy UART + // traffic with an active reader. + DOCKFIFO_STAT_INCR(dockfifo_stat_active_stall_loops); + + enter_critical_section(); + } + rDBGFIFO_W_DATA(DOCKFIFO_UART_WRITE, 1) = byte; + prev_dockfifo_spaces--; // After writing a byte we have one fewer space than previously expected. + exit_critical_section(); + return 0; +} + +static int32_t dockfifo_uart_write(const uint8_t *data, size_t count, bool wait) +{ + RELEASE_ASSERT(data != NULL); + int32_t ret = 0; + for (size_t i = 0; ret == 0 && i < count; ++i) { + ret = dockfifo_uart_write_byte(data[i]); + } + return ret; +} + +static int32_t dockfifo_uart_read(uint8_t *data, size_t count, bool wait) +{ + int32_t bytes_read = 0; + + RELEASE_ASSERT(data != NULL); + +retry_read: + if (wait && (!cb_readable_size(&dockfifo_uart_rx_cbuf))) + event_wait(&dockfifo_uart_rx_event); + + /* disable rx interrupt */ + mask_int(dockfifo_configs[DOCKFIFO_UART_READ].irq); + + bytes_read += cb_read_unsafe(&dockfifo_uart_rx_cbuf, data + bytes_read, count - bytes_read); + + /* enable rx interrupt */ + unmask_int(dockfifo_configs[DOCKFIFO_UART_READ].irq); + + if (((size_t)bytes_read < count) && wait) + goto retry_read; + + return bytes_read; +} + +static int dockfifo_uart_reader_task(void *arg) +{ + for(;;) { + char c; + int32_t len; + + len = dockfifo_uart_read((uint8_t *)&c, 1, true); + if ((len > 0) && ((DebugUartReady & kPowerNVRAMiBootDebugIAPSerial) != 0)) + debug_pushchar(c); + } + return 0; +} + +static void dockfifo_uart_interrupt(void *arg) +{ + int32_t which_uart = (int32_t)arg; + + if (which_uart == DOCKFIFO_UART_READ) { // Rx + while (((rDBGFIFO_R_STAT(DOCKFIFO_UART_READ) & 0xffff) != 0) && cb_free_space(&dockfifo_uart_rx_cbuf)) + cb_putc_unsafe(&dockfifo_uart_rx_cbuf, (rDBGFIFO_R_DATA(DOCKFIFO_UART_READ, 1) >> 8) & 0xff); + + /* signal reader */ + event_signal(&dockfifo_uart_rx_event); + } +} + +//======================= +// Global funtions +//======================= + +int32_t dockfifo_uart_init() +{ + // Setup hardware + clock_gate(CLK_SPU, true); + clock_gate(CLK_DOCKFIFO, true); + + // reset fifos + rDBGFIFO_CNFG(DOCKFIFO_UART_READ) = (1 << 31); + rDBGFIFO_CNFG(DOCKFIFO_UART_WRITE) = (1 << 31); + spin(1); + rDBGFIFO_CNFG(DOCKFIFO_UART_READ) = (0 << 31); + rDBGFIFO_CNFG(DOCKFIFO_UART_WRITE) = (0 << 31); + + // Disable autodraining of the FIFO. We now purely manage it in software. + rDBGFIFO_DRAIN(DOCKFIFO_UART_WRITE) = 0; + + // Empty the DockFIFO by draining it until OCCUPANCY is 0, then measure its capacity + while (rDBGFIFO_R_DATA(DOCKFIFO_UART_WRITE, 3) & 0x7F); + + dockfifo_capacity = rDBGFIFO_W_STAT(DOCKFIFO_UART_WRITE) & 0xffff; + + cb_create(&dockfifo_uart_rx_cbuf, DOCKFIFO_UART_RX_LEN); + event_init(&dockfifo_uart_rx_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + install_int_handler(dockfifo_configs[DOCKFIFO_UART_READ].irq, &dockfifo_uart_interrupt, (void *)DOCKFIFO_UART_READ); + unmask_int(dockfifo_configs[DOCKFIFO_UART_READ].irq); + + task_start(task_create("dockfifo_uart reader", dockfifo_uart_reader_task, NULL, 0x200)); + + return 0; +} + +int32_t dockfifo_uart_putc(char c) +{ + return dockfifo_uart_write((uint8_t *)&c, 1, true); +} + +int32_t dockfifo_uart_getc(bool wait) /* returns -1 if no data available */ +{ + char c; + int32_t len; + + len = dockfifo_uart_read((uint8_t *)&c, 1, wait); + if (len == 0) + return -1; + + return c; +} + +void dockfifo_enable_clock_gating(int num) +{ + rDBGFIFO_CNFG(num) |= DBGFIFO_CNFG_CG_ENA; +} \ No newline at end of file diff --git a/drivers/apple/dockfifo/include/drivers/dockfifo/dockfifo.h b/drivers/apple/dockfifo/include/drivers/dockfifo/dockfifo.h new file mode 100644 index 0000000..91890ed --- /dev/null +++ b/drivers/apple/dockfifo/include/drivers/dockfifo/dockfifo.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DOCKFIFO_H +#define __DOCKFIFO_H + +struct dockfifo_config { + uint8_t type; + uint8_t clk; + uint8_t irq; + const char fifo_name[256]; +}; + +#define DOCKFIFO_W (1) +#define DOCKFIFO_R (0) + +#define DOCKFIFO_0 (0) +#define DOCKFIFO_1 (1) +#define DOCKFIFO_2 (2) +#define DOCKFIFO_3 (3) +#define DOCKFIFO_4 (4) +#define DOCKFIFO_5 (5) +#define DOCKFIFO_6 (6) +#define DOCKFIFO_7 (7) + +// Maximum frame size that can be handled by dockfifo_bulk_read_frame. +#define DOCKFIFO_BULK_MRU 576 + +int32_t dockfifo_uart_init(); +int32_t dockfifo_uart_putc(char c); +int32_t dockfifo_uart_getc(bool wait); + +int32_t dockfifo_bulk_init(); +int32_t dockfifo_bulk_quiesce(); +int32_t dockfifo_bulk_read_frame(void *buf, size_t bytes, size_t *received); +int32_t dockfifo_bulk_write_frame(const void *buf, size_t bytes); + +void dockfifo_enable_clock_gating(int num); + +#endif /* __DOCKFIFO_H */ diff --git a/drivers/apple/dockfifo/rules.mk b/drivers/apple/dockfifo/rules.mk new file mode 100644 index 0000000..5bc80c7 --- /dev/null +++ b/drivers/apple/dockfifo/rules.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifneq ($(filter $(DOCKFIFOS), uart),) + OPTIONS += \ + WITH_HW_DOCKFIFO_UART=1 \ + + ALL_OBJS += \ + $(LOCAL_DIR)/dockfifo_uart.o +endif + +ifneq ($(filter $(DOCKFIFOS), bulk),) + OPTIONS += \ + WITH_HW_DOCKFIFO_BULK=1 \ + +OPTIONS += \ + WITH_HW_USB=1 + + ALL_OBJS += \ + $(LOCAL_DIR)/cobs.o \ + $(LOCAL_DIR)/dockfifo_bulk.o +endif + +ifneq ($(DOCKFIFOS),) + ALL_OBJS += \ + + GLOBAL_INCLUDES += $(LOCAL_DIR)/include +endif \ No newline at end of file diff --git a/drivers/apple/dpb/dpb.c b/drivers/apple/dpb/dpb.c new file mode 100644 index 0000000..fa2a014 --- /dev/null +++ b/drivers/apple/dpb/dpb.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include "dpb.h" + +static void dpb_load_gamma_table(u_int32_t lut_id, u_int32_t *lut_data); +static void dpb_convert_gamma_tables(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, u_int32_t *mod_red_lut, u_int32_t *mod_green_lut, u_int32_t *mod_blue_lut, struct syscfg_wpcl *wpcl); + +#define DPB_LUT_SIZE_PER_CHANNEL 129 + +void dpb_init(void) +{ + //do not bypass any of the blocks + // Leave LUT bypass config in default state in DPB::CONTROL_REG + +#ifdef DPB_DETECT_VIB_CONTROL_TUNABLE + rDPB_DETECT_VBI_CONTROL_REG = DPB_DETECT_VIB_CONTROL_TUNABLE; +#endif +} + +bool dpb_get_enable(void) +{ + return false; +} + +void dpb_set_enable(bool enable) +{ + if (enable) { + rDPB_CONTROL_REG |= DPB_CTRL_ENABLE_CFG; + } else { + rDPB_CONTROL_REG &= ~DPB_CTRL_ENABLE_CFG; + } +} + +void dpb_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl) +{ + u_int32_t mod_red_lut[DPB_LUT_SIZE_PER_CHANNEL], mod_green_lut[DPB_LUT_SIZE_PER_CHANNEL], mod_blue_lut[DPB_LUT_SIZE_PER_CHANNEL]; + + dpb_convert_gamma_tables(red_lut, green_lut, blue_lut, mod_red_lut, mod_green_lut, mod_blue_lut, wpcl); + + // Load the Gamma Correction Table + dpb_load_gamma_table(DPB_RED, mod_red_lut); + dpb_load_gamma_table(DPB_GREEN, mod_green_lut); + dpb_load_gamma_table(DPB_BLUE, mod_blue_lut); + + // Turn on Gamma Correction + rDPB_CONTROL_REG |= DPB_CTRL_CGM_ENABLE_CFG; + + // Load the Gamma Correction Table + dpb_load_gamma_table(DPB_RED, mod_red_lut); + dpb_load_gamma_table(DPB_GREEN, mod_green_lut); + dpb_load_gamma_table(DPB_BLUE, mod_blue_lut); + + rDPB_TABLE_CONTROL_REG |= DPB_UPDATE_REGISTERS | DPB_IMMEDIATE_UPDATE | DPB_UPDATE_CGM_GREEN_TABLE | DPB_UPDATE_CGM_RED_TABLE | DPB_UPDATE_CGM_BLUE_TABLE; + + //Wait till HW is cleared + while ((rDPB_TABLE_CONTROL_REG & DPB_UPDATE_CGM_GREEN_TABLE) && (rDPB_TABLE_CONTROL_REG & DPB_UPDATE_CGM_RED_TABLE) && (rDPB_TABLE_CONTROL_REG & DPB_UPDATE_CGM_BLUE_TABLE)); + + // Load the Gamma Correction Table again since the OS reads them (double buffered registers) + dpb_load_gamma_table(DPB_RED, mod_red_lut); + dpb_load_gamma_table(DPB_GREEN, mod_green_lut); + dpb_load_gamma_table(DPB_BLUE, mod_blue_lut); +} + +static void dpb_load_gamma_table(u_int32_t lut_id, u_int32_t *lut_data) +{ + u_int32_t cnt; + u_int32_t lut_size = DPB_LUT_SIZE_PER_CHANNEL; + volatile u_int32_t * lut_addr; + + switch(lut_id) { + case DPB_RED: + lut_addr = &DPB_CGM_RED; + break; + case DPB_GREEN: + lut_addr = &DPB_CGM_GREEN; + break; + case DPB_BLUE: + lut_addr = &DPB_CGM_BLUE; + break; + default: + panic("invalid gamma lut id"); + } + + for (cnt = 0; cnt < lut_size; cnt++, lut_addr++) { + *lut_addr = lut_data[cnt]; + } +} + +//Gamma table is passed in the old clcd format, which is not compatible "as is" with dpb HW format. +// The table provided has the following charasteristics: +// 1. its values are compressed +// 2. the layout is linear layout 1..n +// For H6 , we need the following table charasterictics: +// 1. decompress +// 2. layout is bankbased entry = (2N+1) << 16 | 2N +static void dpb_convert_gamma_tables(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, u_int32_t *mod_red_lut, u_int32_t *mod_green_lut, u_int32_t *mod_blue_lut, struct syscfg_wpcl *wpcl) +{ + int i, j; + u_int32_t oddValue, evenValue; + u_int32_t reg; + const u_int32_t *orig_luts[3]; + u_int32_t *mod_luts[3]; + uint32_t coeffs[3]; + + orig_luts[0] = red_lut; + orig_luts[1] = green_lut; + orig_luts[2] = blue_lut; + mod_luts[0] = mod_red_lut; + mod_luts[1] = mod_green_lut; + mod_luts[2] = mod_blue_lut; + coeffs[0] = wpcl->red; + coeffs[1] = wpcl->green; + coeffs[2] = wpcl->blue; + + // For H6, there are 129 10-bit entries on 2 banks, totalling 258: + // RESERVED1 BANK 1 RESERVED0 BANK 0 + // [31:26] [25:16] [15:10] [9:0] + // X 1 X 0 + // X 3 X 2 + // ... + // X 257 X 256 + for (i = 0; i < DPB_LUT_SIZE_PER_CHANNEL; i++) + { + for (j = 0; j < 3; j++) + { + //extract 2n+1 + oddValue = (2*i+1 >= 257) ? 0 : orig_luts[j][2*i+1]; + //decompress + oddValue = ((oddValue * coeffs[j]) >> WpCl_Quotation_Denominator) & 0x03FF; + + //extract 2n + evenValue = orig_luts[j][2*i]; + //decompress + evenValue = ((evenValue * coeffs[j]) >> WpCl_Quotation_Denominator) & 0x03FF; + + reg = (oddValue << 16) | evenValue; + mod_luts[j][i] = reg; + } + } +} diff --git a/drivers/apple/dpb/dpb.h b/drivers/apple/dpb/dpb.h new file mode 100644 index 0000000..9b96f25 --- /dev/null +++ b/drivers/apple/dpb/dpb.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DPB_H +#define __APPLE_DPB_H + +#include + +#ifdef DISP0_DPB_BASE_ADDR +#define DPB_BASE_ADDR DISP0_DPB_BASE_ADDR +#endif +#ifndef DPB_BASE_ADDR +#error "DPB base addr for AppleDynamicPixelBackligh (DPB) Block is not defined" +#endif + +#define DPB_RED 0 +#define DPB_GREEN 1 +#define DPB_BLUE 2 + +#define rDPB_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0000)) //Main Control Register + +#define DPB_CTRL_CGM_BYPASSCFG (1 << 9) +#define DPB_CTRL_TMF_BYPASS_CFG (1 << 8) +#define DPB_CTRL_PMR_BYPASS_CFG (1 << 7) +#define DPB_CTRL_MIN_PIXEL_MASK_ENABLE_CFG (1 << 6) +#define DPB_CTRL_CGM_ENABLE_CFG (1 << 5) +#define DPB_CTRL_PMR_ENABLE_CFG (1 << 4) +#define DPB_CTRL_LOW_PASS_FILTER_BYPASS_CFG (1 << 3) +#define DPB_CTRL_SMOOTH_OFF_CFG (1 << 2) +#define DPB_CTRL_DYNAMIC_TMF_CFG (1 << 1) +#define DPB_CTRL_ENABLE_CFG (1 << 0) + +#define DPB_CTRL_BCL_ENABLE (1 << 7) +#define DPB_CTRL_DYNAMIC_BACKLIGHT (1 << 6) +#define DPB_CTRL_TMF_BYPASS (1 << 5) +#define DPB_CTRL_MIN_PIXEL_MASK_ENABLE (1 << 4) +#define DPB_CTRL_TEMPORTAL_FILTER_BYPASS (1 << 3) +#define DPB_CTRL_SMOOTH_OFF (1 << 2) +#define DPB_CTRL_DPB_DYNAMIC_TMF (1 << 1) + +#define rDPB_HISTOGRAM_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0004)) //Definition of luminance calculation for histogram +#define rDPB_WINDOW_UPPER_LEFT_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0008)) //Register defining top and left boundaries of active pixel window +#define rDPB_WINDOW_BOTTOM_RIGHT_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x000c)) //Register defining bottom and right boundaries of active pixel window +#define rDPB_LOW_PASS_FILTER_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0010)) //Temporal Filter Control Register 1 +#define rDPB_LOW_PASS_FILTER_CONTROL2_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0014)) //Temporal Filter Control Register 2 +#define rDPB_SLOPE_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0018)) //Slope Control Register +#define DPB_SLOPEM2_SHIFT (20) +#define DPB_SLOPEM2_MASK (0x1FF << DPB_SLOPEM2_SHIFT) + +#define rDPB_TABLE_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x001c)) //Synchronize LUT and register updates to next vertical blank interval +#define DPB_IMMEDIATE_UPDATE (1 << 15) +#define DPB_DUMP_HISTOGRAM (1 << 14) +#define DPB_UPDATE_REGISTERS (1 << 13) +#define DPB_UPDATE_CGM_BLUE_TABLE (1 << 12) +#define DPB_UPDATE_CGM_GREEN_TABLE (1 << 11) +#define DPB_UPDATE_CGM_RED_TABLE (1 << 10) +#define DPB_UPDATE_PMR_BLUE_TABLE (1 << 9) +#define DPB_UPDATE_PMR_GREEN_TABLE (1 << 8) +#define DPB_UPDATE_PMR_RED_TABLE (1 << 7) +#define DPB_UPDATE_ENGAMMA_BLUE_TABLE (1 << 6) +#define DPB_UPDATE_ENGAMMA_GREEN_TABLE (1 << 5) +#define DPB_UPDATE_ENGAMMA_RED_TABLE (1 << 4) +#define DPB_UPDATE_DEGAMMA_BLUE_TABLE (1 << 2) +#define DPB_UPDATE_DEGAMMA_GREEN_TABLE (1 << 1) +#define DPB_UPDATE_DEGAMMA_RED_TABLE (1 << 0) + +#define rDPB_DETECT_VBI_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0020)) //Detect VBI Register +#define rDPB_MAX_SLOPE_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0024)) //Max Slope Control Register +#define rDPB_SLOPE_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0028)) //Slope Status Register +#define rDPB_HISTOGRAM_BIN_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x002c)) //Histogram Bin Status Register +#define rDPB_HISTOGRAM_PIXEL_CNT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0030)) //Histogram Pixel Count Status Register +#define rDPB_BACK_LIGHT_LEVEL_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0034)) //Backlight Level Status Register +#define rDPB_FRAME_COUNTER_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0038)) //Frame Counter Register +#define rDPB_HISTOGRAM_MIN_PIXEL_CNT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x003c)) //Histogram Min Pixel Count Status Register +#define rDPB_MIN_PIXEL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0040)) //Minimum Pixel Threshold Register +#define rDPB_CLIP_PIXEL_CNT_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0044)) //Pixel Count Register +#define rDPB_MAX_KNEE_POINT_DELTA_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0048)) //Max Kneepoint Delta Register +#define rDPB_CRC_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x004c)) //CRC Control Register +#define rDPB_CRC_WINDOW_START_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0050)) //CRC Window Start Register +#define rDPB_CRC_WINDOW_END_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0054)) //CRC Window End Register +#define rDPB_CRC0_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0058)) //CRC0 Status Register +#define rDPB_CRC1_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x005c)) //CRC1 Status Register (reserved) +#define rDPB_BACK_LIGHT_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0060)) //Back light control register used to override computed back light value +#define rDPB_INTERRUPT_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0064)) //DPB Interrupt Control Register +#define rDPB_INTERRUPT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0068)) //DPB Interrupt Status Register +#define rDPB_DEGAMMA_KNEE_POINT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x006c)) //Knee Point values in gamma decoded domain +#define rDPB_DEGAMMA_MAX_BRIGHT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0070)) //Maximum Brightness value in gamma decoded domain +#define rDPB_VERSION_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0074)) //DPB Version + + +//DPB_MEMORY Register +#define DPB_HISTOGRAM_STATS (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0400)) // [32][256] Histogram of binned brightness values over one frame +#define DPB_TMF_RED (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x1000)) // [32][33] Tone Modifier LUT, Red component +#define DPB_TMF_GREEN (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x1400)) // [32][33] Tone Modifier LUT, Green component +#define DPB_TMF_BLUE (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x1800)) // [32][33] Tone Modifier LUT, Blue component +#define DPB_PMR_RED (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x2000)) // [32][129] Pixel Manager LUT, Red component +#define DPB_PMR_GREEN (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x2400)) // [32][129] Pixel Manager LUT, Green component +#define DPB_PMR_BLUE (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x2800)) // [32][129] Pixel Manager LUT, Blue component +#define DPB_CGM_RED (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x3000)) // [32][129] Gamma Correction LUT, Red component +#define DPB_CGM_GREEN (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x3400)) // [32][129] Gamma Correction LUT, Green component +#define DPB_CGM_BLUE (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x3800)) // [32][129] Gamma Correction LUT, Blue component +#define DPB_DEGAMMA_RED (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x4000)) // [32][65] Gamma Decode LUT, Red component +#define DPB_DEGAMMA_GREEN (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x4400)) // [32][65] Gamma Decode LUT, Green component +#define DPB_DEGAMMA_BLUE (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x4800)) // [32][65] Gamma Decode LUT, Blue component +#define DPB_DEGAMMA_SLOPE (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x4c00)) // [32][65] Slope LUT in gamma-decoded domain +#define DPB_ENGAMMA_RED (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x5000)) // [32][113] Gamma encode LUT, Red component +#define DPB_ENGAMMA_GREEN (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x5400)) // [32][113] Gamma encode LUT, Green component +#define DPB_ENGAMMA_BLUE (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x5800)) // [32][113] Gamma encode LUT, Blue component + +#endif /* ! __APPLE_DPB_H */ diff --git a/drivers/apple/dpb/rules.mk b/drivers/apple/dpb/rules.mk new file mode 100644 index 0000000..e3a4991 --- /dev/null +++ b/drivers/apple/dpb/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_DPB=1 \ + DPB_VERSION=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dpb.o diff --git a/drivers/apple/dpb_v2/dpb_v2.c b/drivers/apple/dpb_v2/dpb_v2.c new file mode 100644 index 0000000..44d434c --- /dev/null +++ b/drivers/apple/dpb_v2/dpb_v2.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include "dpb_v2.h" + +void dpb_init(uint32_t display_width, uint32_t display_height) +{ + uint32_t control; + + // ELBA: ADBE::DPB: Missing enable in DPB (WA to disable DPB) + control = rDPB_CONTROL_REG; + + control |= DPB_CTRL_TMF_BYPASS; + control &= ~DPB_CTRL_DPB_DYNAMIC_TMF; + control |= DPB_CTRL_TEMPORTAL_FILTER_BYPASS; + control &= ~DPB_CTRL_DYNAMIC_BACKLIGHT; + control &= ~DPB_CTRL_BCL_ENABLE; + + rDPB_CONTROL_REG = control; + + rDPB_ACTIVE_REGION_SIZE_REG = 0x00010001; + + // Tell the DPB double buffered registers to update immediatly. + rDPB_UPDATE_CONTROL_REG |= (1 << 2); +} + + +void dpb_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl) +{ + // Do Nothing.. DPB is bypassed +} \ No newline at end of file diff --git a/drivers/apple/dpb_v2/dpb_v2.h b/drivers/apple/dpb_v2/dpb_v2.h new file mode 100644 index 0000000..90b50b5 --- /dev/null +++ b/drivers/apple/dpb_v2/dpb_v2.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DPB_H +#define __APPLE_DPB_H + +#include + +#ifdef DISP0_DPB_BASE_ADDR +#define DPB_BASE_ADDR DISP0_DPB_BASE_ADDR +#endif +#ifndef DPB_BASE_ADDR +#error "DPB base addr for AppleDynamicPixelBackligh (DPB) Block is not defined" +#endif + +#define rDPB_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0000)) //Main Control Register + +#define DPB_CTRL_BCL_ENABLE (1 << 7) +#define DPB_CTRL_DYNAMIC_BACKLIGHT (1 << 6) +#define DPB_CTRL_TMF_BYPASS (1 << 5) +#define DPB_CTRL_MIN_PIXEL_MASK_ENABLE (1 << 4) +#define DPB_CTRL_TEMPORTAL_FILTER_BYPASS (1 << 3) +#define DPB_CTRL_SMOOTH_OFF (1 << 2) +#define DPB_CTRL_DPB_DYNAMIC_TMF (1 << 1) + +#define rDPB_HISTOGRAM_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0004)) //Definition of luminance calculation for histogram +#define rDPB_ACTIVE_REGION_START_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0008)) //Register defining top and left boundaries of active pixel window +#define rDPB_ACTIVE_REGION_SIZE_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x000c)) //Register defining bottom and right boundaries of active pixel window +#define rDPB_TEMPORAL_FILTER_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0010)) //Temporal Filter Control Register 1 +#define rDPB_TEMPORAL_FILTER_CONTROL2_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0014)) //Temporal Filter Control Register 2 +#define rDPB_SLOPE_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0018)) //Slope Control Register +#define DPB_SLOPEM2_SHIFT (20) +#define DPB_SLOPEM2_MASK (0x1FF << DPB_SLOPEM2_SHIFT) + +#define rDPB_UPDATE_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x001c)) //Synchronize LUT and register updates to next vertical blank interval + +#define rDPB_DETECT_VBI_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0020)) //Detect VBI Register +#define rDPB_MAX_SLOPE_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0024)) //Max Slope Control Register +#define rDPB_SLOPE_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0028)) //Slope Status Register +#define rDPB_HISTOGRAM_BIN_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x002c)) //Histogram Bin Status Register +#define rDPB_HISTOGRAM_PIXEL_CNT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0030)) //Histogram Pixel Count Status Register +#define rDPB_BACK_LIGHT_LEVEL_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0034)) //Backlight Level Status Register + +#define rDPB_HISTOGRAM_MIN_PIXEL_CNT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0038)) //Histogram Min Pixel Count Status Register +#define rDPB_MIN_PIXEL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x003c)) //Minimum Pixel Threshold Register +#define rDPB_CLIP_PIXEL_CNT_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0040)) //Pixel Count Register +#define rDPB_MAX_KNEE_POINT_DELTA_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0044)) //Max Kneepoint Delta Register +#define rDPB_BACK_LIGHT_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0048)) //Back light control register used to override computed back light value +#define rDPB_BACK_LIGHT_SELECT_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x004c)) +#define rDPB_DIMMING_DELAY_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0050)) +#define rDPB_INTERRUPT_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0054)) //DPB Interrupt Control Register +#define rDPB_INTERRUPT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0058)) //DPB Interrupt Status Register +#define rDPB_DEGAMMA_KNEE_POINT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x005c)) //Knee Point values in gamma decoded domain +#define rDPB_TF_DEGAMMA_KNEE_POINT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0060)) +#define rDPB_DEGAMMA_MAX_BRIGHT_STATUS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0064)) //Maximum Brightness value in gamma decoded domain +#define rDPB_FIXED_SLOPE_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0068)) + +#define rDPB_TF_FIFO_PTRS_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x006c)) +#define rDPB_EXCLUDE_CONTROL_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0070)) +#define rDPB_EXCLUDE_REGION_START_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0074)) +#define rDPB_EXCLUDE_REGION_SIZE_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x0088)) +#define rDPB_TF_DEBUG_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x009c)) +#define rDPB_ENGAMMA_LAST_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x00a0)) +#define rDPB_DEGAMMA_LAST_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x00a4)) +#define rDPB_BCL_LUT_LAST_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x00a8)) +#define rDPB_ENGAMMA_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x00ac)) +#define rDPB_DEGAMMA_REG (*(volatile u_int32_t *)(DPB_BASE_ADDR + 0x042c)) + +#endif /* ! __APPLE_DPB_H */ \ No newline at end of file diff --git a/drivers/apple/dpb_v2/rules.mk b/drivers/apple/dpb_v2/rules.mk new file mode 100644 index 0000000..07979c1 --- /dev/null +++ b/drivers/apple/dpb_v2/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_DPB=1 \ + DPB_VERSION=2 + +ALL_OBJS += \ + $(LOCAL_DIR)/dpb_v2.o diff --git a/drivers/apple/dwi/dwi.c b/drivers/apple/dwi/dwi.c new file mode 100644 index 0000000..a6ac5ca --- /dev/null +++ b/drivers/apple/dwi/dwi.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#include "dwi.h" + +#ifndef TARGET_DWI_FREQUENCY +#error TARGET_DWI_FREQUENCY not defined by the target +#endif + +#ifndef TARGET_DWI_TRANSFER_GAP_US +#error TARGET_DWI_TRANSFER_GAP_US not defined by the target +#endif + +int dwi_init(void) +{ + u_int32_t dwi_divider, dwi_transfer_gap; + + clock_gate(CLK_DWI, true); + + dwi_divider = (clock_get_frequency(CLK_NCLK) + TARGET_DWI_FREQUENCY - 1) / TARGET_DWI_FREQUENCY; + dwi_transfer_gap = (clock_get_frequency(CLK_NCLK) * TARGET_DWI_TRANSFER_GAP_US) / 1000000; + + rDWI_CLOCK_CONFIG = DWI_CLOCK_CONFIG_CLOCK_SCALER(dwi_divider) | DWI_CLOCK_CONFIG_TX_CPHA_1; + rDWI_TRANSFER_GAP = dwi_transfer_gap; + + return 0; +} + +int dwi_send_backlight_command(uint32_t backlight_command, uint32_t backlight_level) +{ + rDWI_ITR0_TX_DATA = (backlight_command << 28) | (backlight_level & 0x7FF); + rDWI_ITR0_CONTROL = DWI_TR_CTRL_BYTE_SWAP | DWI_TR_CTRL_BYTE_CNT(4) | DWI_TR_CTRL_TRAN_EN | DWI_TR_CTRL_SLAVE_DWI; + + return 0; +} diff --git a/drivers/apple/dwi/dwi.h b/drivers/apple/dwi/dwi.h new file mode 100644 index 0000000..29a3a6d --- /dev/null +++ b/drivers/apple/dwi/dwi.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_DWI_H +#define __APPLE_DWI_H + +#include +#include SUB_PLATFORM_SPDS_HEADER(dwi) + +#define rDWI_CLOCK_CONFIG (*(volatile u_int32_t *)(DWI_BASE_ADDR + DWI_BLK_CLOCK_CONFIG_OFFSET)) +#define DWI_CLOCK_CONFIG_TX_CPHA_1 (DWI_BLK_CLOCK_CONFIG_TX_CPHA_INSRT(1) << 0) +#define DWI_CLOCK_CONFIG_TX_CPHA_2 (DWI_BLK_CLOCK_CONFIG_TX_CPHA_INSRT(0) << 0) +#define DWI_CLOCK_CONFIG_RX_CPHA_1 (DWI_BLK_CLOCK_CONFIG_TX_CPHA_INSRT(1) << 1) +#define DWI_CLOCK_CONFIG_RX_CPHA_2 (DWI_BLK_CLOCK_CONFIG_TX_CPHA_INSRT(0) << 1) +#define DWI_CLOCK_CONFIG_CPOL_LOW (DWI_BLK_CLOCK_CONFIG_CPOL_INSRT(0) << 2) +#define DWI_CLOCK_CONFIG_CPOL_HIGH (DWI_BLK_CLOCK_CONFIG_CPOL_INSRT(1) << 2) +#define DWI_CLOCK_CONFIG_CLOCK_SCALER(_x) (DWI_BLK_CLOCK_CONFIG_CLOCK_SCALER_INSRT(_x - 1)) +#define rDWI_TRANSFER_GAP (*(volatile u_int32_t *)(DWI_BASE_ADDR + DWI_BLK_TRANSFER_GAP_OFFSET)) +#define rDWI_ITR0_CONTROL (*(volatile u_int32_t *)(DWI_BASE_ADDR + DWI_BLK_ITR0_CONTROL_OFFSET)) +#define DWI_TR_CTRL_TRAN_EN (1 << DWI_BLK_ITR0_CONTROL_ITR0_TRAN_EN_SHIFT) +#define DWI_TR_CTRL_BYTE_CNT(_c) (DWI_BLK_ITR0_CONTROL_ITR0_BYTE_COUNT_INSRT(_c - 1)) +#define DWI_TR_CTRL_BYTE_SWAP (1 << DWI_BLK_ITR0_CONTROL_ITR0_BYTE_SWAP_SHIFT) +#define DWI_TR_CTRL_BIT_ORDER (1 << DWI_BLK_ITR0_CONTROL_ITR0_BIT_ORDER_SHIFT) +#define DWI_TR_CTRL_SLAVE_PSPI (DWI_BLK_ITR0_CONTROL_SLAVE_SEL_INSRT(0)) +#define DWI_TR_CTRL_SLAVE_DWI (DWI_BLK_ITR0_CONTROL_SLAVE_SEL_INSRT(1)) +#define rDWI_ITR0_TX_DATA (*(volatile u_int32_t *)(DWI_BASE_ADDR + DWI_BLK_ITR0_TX_DATA_OFFSET)) + +#endif /* ! __APPLE_DWI_H */ diff --git a/drivers/apple/dwi/rules.mk b/drivers/apple/dwi/rules.mk new file mode 100644 index 0000000..cd4c486 --- /dev/null +++ b/drivers/apple/dwi/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DWI=1 + +ALL_OBJS += $(LOCAL_DIR)/dwi.o diff --git a/drivers/apple/gpio/gpio.c b/drivers/apple/gpio/gpio.c new file mode 100644 index 0000000..244b8e3 --- /dev/null +++ b/drivers/apple/gpio/gpio.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#if GPIO_VERSION > 5 +#include +#endif + +static const struct { + uintptr_t base_addr; + uint32_t pin_count; +} gpio_cfgs[GPIOC_COUNT] = { +#if GPIOC_COUNT > 0 + { GPIO_BASE_ADDR, GPIO_GROUP_COUNT * GPIOPADPINS }, +#endif +#if GPIOC_COUNT > 1 + { GPIO_1_BASE_ADDR, GPIO_1_GROUP_COUNT * GPIOPADPINS }, +#endif +}; + +uint32_t gpio_read(gpio_t gpio) +{ + uint8_t gpioc = GPIO2CONTROLLER(gpio); + uint8_t pad = GPIO2PAD(gpio); + uint8_t pin = GPIO2PIN(gpio); + uint8_t gpion = pad * GPIOPADPINS + pin; + +#if WITH_HW_SPI && defined(GPIO_PAD_SPI) + if (pad == GPIO_PAD_SPI) return spi_gpio_read(pin); +#endif + + return (rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) & 1) ? 1UL : 0UL; +} + +void gpio_write(gpio_t gpio, uint32_t val) +{ + uint32_t cfg_val, cfg_mask; + uint8_t gpioc = GPIO2CONTROLLER(gpio); + uint8_t pad = GPIO2PAD(gpio); + uint8_t pin = GPIO2PIN(gpio); + uint8_t gpion = pad * GPIOPADPINS + pin; + +#if WITH_HW_SPI && defined(GPIO_PAD_SPI) + if (pad == GPIO_PAD_SPI) { + spi_gpio_write(pin, val); + return; + } +#endif + + cfg_val = (val) ? CFG_OUT_1 : CFG_OUT_0; + cfg_mask = INPUT_ENABLE | FUNC_MASK | INT_MASKED | CFG_MASK | DATA_1; + + rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) = (rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) & ~cfg_mask) | (cfg_val & cfg_mask); +} + +void gpio_safe_reconfigure(uint8_t gpioc, uint8_t gpion, uint32_t config) +{ + uint32_t old_config; + uint32_t new_input_enable; + uint32_t old_input_enable; + + old_config = rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion); + new_input_enable = config & INPUT_ENABLE; + + if (new_input_enable == 0) { + rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) = old_config & ~INPUT_ENABLE; + old_input_enable = 0; + } else { + old_input_enable = old_config & INPUT_ENABLE; + } + + rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) = (config & ~INPUT_ENABLE) | old_input_enable; + + if (new_input_enable != 0 && old_input_enable == 0) + rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) = config; +} + +void gpio_configure(gpio_t gpio, uint32_t config) +{ + uint32_t cfg_val, cfg_mask; + uint8_t gpioc = GPIO2CONTROLLER(gpio); + uint8_t pad = GPIO2PAD(gpio); + uint8_t pin = GPIO2PIN(gpio); + uint8_t gpion = pad * GPIOPADPINS + pin; + +#if WITH_HW_SPI && defined(GPIO_PAD_SPI) + if (pad == GPIO_PAD_SPI) { + spi_gpio_configure(pin, config); + return; + } +#endif + + cfg_mask = INPUT_ENABLE | FUNC_MASK | INT_MASKED | CFG_MASK; + + switch (config) { + case GPIO_CFG_IN : cfg_val = CFG_IN; break; + case GPIO_CFG_OUT_0 : cfg_val = CFG_OUT_0; cfg_mask |= DATA_1; break; + case GPIO_CFG_OUT_1 : cfg_val = CFG_OUT_1; cfg_mask |= DATA_1; break; + case GPIO_CFG_OUT : cfg_val = CFG_OUT; break; + case GPIO_CFG_FUNC0 : cfg_val = CFG_FUNC0; break; + case GPIO_CFG_FUNC1 : cfg_val = CFG_FUNC1; break; + case GPIO_CFG_FUNC2 : cfg_val = CFG_FUNC2; break; + case GPIO_CFG_DFLT : + cfg_val = platform_get_default_gpio_cfg(gpioc)[gpion]; cfg_mask |= PULL_MASK | DATA_1; break; + default : return; + } + + gpio_safe_reconfigure(gpioc, gpion, (rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) & ~cfg_mask) | (cfg_val & cfg_mask)); +} + +void gpio_configure_pupdn(gpio_t gpio, int32_t pupdn) +{ + uint8_t gpioc = GPIO2CONTROLLER(gpio); + uint8_t pad = GPIO2PAD(gpio); + uint8_t pin = GPIO2PIN(gpio); + uint8_t gpion = pad * GPIOPADPINS + pin; + uint32_t cfg_val; + + if (pupdn < GPIO_NO_PUPDN) { + cfg_val = PULL_DOWN; + } else if (pupdn > GPIO_NO_PUPDN) { + #if GPIO_VERSION < 5 + cfg_val = PULL_UP; + #else + cfg_val = (pupdn > GPIO_PUP) ? PULL_UP_STRONG : PULL_UP; + #endif + } else { + /* GPIO_NO_PUPDN */ + cfg_val = PULL_NONE; + } + + rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) = (rGPIOCFG(gpio_cfgs[gpioc].base_addr, gpion) & ~PULL_MASK) | (cfg_val & PULL_MASK); +} + + +int gpio_init_pinconfig(void) +{ + uint8_t cnt, gpioc; + + for (gpioc = 0; gpioc < GPIOC_COUNT; gpioc++) { + const uint32_t *pin_config = platform_get_default_gpio_cfg(gpioc); + + for (cnt = 0; cnt < gpio_cfgs[gpioc].pin_count; cnt++) { + gpio_safe_reconfigure(gpioc, cnt, pin_config[cnt]); + } + +#ifdef FMI_SLEW_RATE + // Adjust global FMI pads slew rate. + rGPIO_SR_EN(gpio_cfgs[gpioc].base_addr) = (rGPIO_SR_EN(gpio_cfgs[gpioc].base_addr) & ~1) | (FMI_SLEW_RATE & 1); +#endif + +#ifdef FMI_DIFF_SEL + // Configure FMI differential pin selection + rGPIO_FMI_DIFF_SEL(gpio_cfgs[gpioc].base_addr) = FMI_DIFF_SEL; +#endif + +#if GPIO_VERSION > 0 + // Enable interrupt when pin not configured as GPIO + rGPIO_NPL_IN_EN(gpio_cfgs[gpioc].base_addr) = 1; +#endif + } + +#if GPIO_VERSION > 6 +#if !APPLICATION_SECUREROM + // The GPIO Micro-Architecture Specification v1.3, section 4.1 (5) says: + // + // "To control the XTAL_DRIVE strength software needs to program + // the GPIO_MISC_CTRL[XTAL_DRIVE_STRENGTH] bit. This should be + // programmed only after 140,000 24MHZ clocks to allow the xtal + // to lock to 24MHz. Once this change is made we should allow + // 20,000 clocks for a stable duty cycle. + // + // Since we're not doing this in the SecureROM we're definitely far + // enough along here that we've met the 140K cycles requirement. + rGPIO_MISC_CTRL(gpio_cfgs[0].base_addr) = 0; +#endif +#endif + + return 0; +} + +void gpio_fixup_pinconfig(const uint32_t *fixup_list) { + int32_t i; + + for (i = 0; fixup_list[i * 2] != UINT32_MAX; i ++) { + gpio_t gpio = fixup_list[(i * 2) + 0]; + uint8_t gpioc = GPIO2CONTROLLER(gpio); + uint8_t pad = GPIO2PAD(gpio); + uint8_t pin = GPIO2PIN(gpio); + uint8_t gpion = pad * GPIOPADPINS + pin; + + gpio_safe_reconfigure(gpioc, gpion, fixup_list[(i * 2) + 1]); + } +} + +int gpio_init_memory(uint32_t drive_strength) +{ + gpio_t gpio; + uint32_t pin, pad, gpion, config; + int32_t cnt, pin_count = sizeof(memory_interface_gpios) / sizeof(memory_interface_gpios[0]); + + /* + * XXXX only one gpio controller is supported + */ + + config = CFG_IN; +#if GPIO_VERSION < 5 + switch (drive_strength) { + case GPIO_DRIVE_X1 : config |= DRIVE_X1; break; + case GPIO_DRIVE_X2 : config |= DRIVE_X2; break; + case GPIO_DRIVE_X3 : config |= DRIVE_X3; break; + case GPIO_DRIVE_X4 : config |= DRIVE_X4; break; + case GPIO_DRIVE_X6 : config |= DRIVE_X6; break; + } +#else + switch (drive_strength) { + case GPIO_DRIVE_S0 : config |= DRIVE_S0; break; + case GPIO_DRIVE_S1 : config |= DRIVE_S1; break; + case GPIO_DRIVE_S2 : config |= DRIVE_S2; break; + case GPIO_DRIVE_S3 : config |= DRIVE_S3; break; + case GPIO_DRIVE_S4 : config |= DRIVE_S4; break; + case GPIO_DRIVE_S5 : config |= DRIVE_S5; break; + case GPIO_DRIVE_S6 : config |= DRIVE_S6; break; + case GPIO_DRIVE_S7 : config |= DRIVE_S7; break; + case GPIO_DRIVE_S8 : config |= DRIVE_S8; break; + case GPIO_DRIVE_S9 : config |= DRIVE_S9; break; + case GPIO_DRIVE_S10 : config |= DRIVE_S10; break; + case GPIO_DRIVE_S11 : config |= DRIVE_S11; break; + case GPIO_DRIVE_S12 : config |= DRIVE_S12; break; + case GPIO_DRIVE_S13 : config |= DRIVE_S13; break; + case GPIO_DRIVE_S14 : config |= DRIVE_S14; break; + case GPIO_DRIVE_S15 : config |= DRIVE_S15; break; + } +#endif + + for (cnt = 0; cnt < pin_count; cnt++) { + gpio = memory_interface_gpios[cnt]; + pad = GPIO2PAD(gpio); + pin = GPIO2PIN(gpio); + gpion = pad * GPIOPADPINS + pin; + + gpio_safe_reconfigure(0, gpion, config); + } + + return 0; +} + +uint32_t gpio_get_board_id(void) +{ +#if GPIO_VERSION > 5 + // The board ID pins must have been sampled by the time this request is made. + RELEASE_ASSERT(rGPIO_PINSTRAPS_VALID(gpio_cfgs[0].base_addr) & 1); + + // Return the sampled board ID value. + return MINIPMGR_SECURITY_GPIO_STRAPS_BOARD_ID_XTRCT(rMINIPMGR_SECURITY_GPIO_STRAPS); +#else + panic("gpio_get_board_id() not supported for this platform"); +#endif +} + +#if APPLICATION_IBOOT + +int gpio_diag_pinconfig(void) +{ + return 0; +} + +#endif /* APPLICATION_IBOOT */ diff --git a/drivers/apple/gpio/include/drivers/apple/gpio.h b/drivers/apple/gpio/include/drivers/apple/gpio.h new file mode 100644 index 0000000..3e1224e --- /dev/null +++ b/drivers/apple/gpio/include/drivers/apple/gpio.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_GPIO_H +#define __APPLE_GPIO_H + +#include + +#if !defined(GPIOC_COUNT) +# define GPIOC_COUNT (1) +#endif // GPIOC_COUNT + +/* Register Offsets for Apple GPIOs */ +#define rGPIOCFG(_b, _n) (*(volatile u_int32_t *)((_b) + 0x000 + (_n) * 4)) +#define rGPIOINT(_b, _n) (*(volatile u_int32_t *)((_b) + 0x800 + (_n) * 4)) +#if GPIO_VERSION < 3 +#define rGPIO_SR_EN(_b) (*(volatile u_int32_t *)((_b) + 0xC4C)) +#define rGPIO_FMI_DIFF_SEL(_b) (*(volatile u_int32_t *)((_b) + 0xC4C)) +#endif +#define rGPIO_NPL_IN_EN(_b) (*(volatile u_int32_t *)((_b) + 0xC48)) +#if GPIO_VERSION > 5 +#define rGPIO_PINSTRAPS_VALID(_b) (*(volatile u_int32_t *)((_b) + 0xC4C)) +#define rGPIO_MISC_CTRL(_b) (*(volatile u_int32_t *)((_b) + 0xC50)) +#endif + +/* Base Pin Defines for Apple GPIOs */ + +#define GPIOPADPINS (8) + +#define GPIO2PIN(gpio) ((gpio) & (GPIOPADPINS - 1)) +#define GPIO2PAD(gpio) (((gpio) >> 8) & 0xFF) +#define GPIO2CONTROLLER(gpio) (((gpio) >> 24) & 0xFF) + +#define DATA_0 (0 << 0) +#define DATA_1 (1 << 0) + +#define CFG_GP_IN (0 << 1) +#define CFG_GP_OUT (1 << 1) +#define CFG_INT_LVL_HI (2 << 1) +#define CFG_INT_LVL_LO (3 << 1) +#define CFG_INT_EDG_RIS (4 << 1) +#define CFG_INT_EDG_FAL (5 << 1) +#define CFG_INT_EDG_ANY (6 << 1) +#define CFG_DISABLE (7 << 1) +#define CFG_MASK (7 << 1) + +#if GPIO_VERSION < 3 +#define INT_MASKED (1 << 4) +#endif + +#define FUNC_GPIO (0 << 5) +#define FUNC_ALT0 (1 << 5) +#define FUNC_ALT1 (2 << 5) +#define FUNC_ALT2 (3 << 5) +#define FUNC_MASK (3 << 5) + +#define PULL_NONE (0 << 7) +#if GPIO_VERSION == 0 +#define PULL_UP (1 << 7) +#define PULL_DOWN (2 << 7) +#else +#define PULL_UP (3 << 7) +#if GPIO_VERSION > 4 +#define PULL_UP_STRONG (2 << 7) +#endif +#define PULL_DOWN (1 << 7) +#endif +#define PULL_MASK (3 << 7) + +#define INPUT_ENABLE (1 << 9) + +#if GPIO_VERSION < 5 +#define DRIVE_X1 (0 << 10) +#define DRIVE_X2 (1 << 10) +#if GPIO_VERSION < 2 +#define DRIVE_X3 (2 << 10) +#define DRIVE_X4 (3 << 10) +#define DRIVE_X6 DRIVE_X4 +#else +#define DRIVE_X3 DRIVE_X2 +#define DRIVE_X4 (2 << 10) +#define DRIVE_X6 (3 << 10) +#endif +#else +#define DRIVE_S0 (0 << 10 | 0 << 22) +#define DRIVE_S1 (1 << 10 | 0 << 22) +#define DRIVE_S2 (2 << 10 | 0 << 22) +#define DRIVE_S3 (3 << 10 | 0 << 22) +#define DRIVE_S4 (0 << 10 | 1 << 22) +#define DRIVE_S5 (1 << 10 | 1 << 22) +#define DRIVE_S6 (2 << 10 | 1 << 22) +#define DRIVE_S7 (3 << 10 | 1 << 22) +#define DRIVE_S8 (0 << 10 | 2 << 22) +#define DRIVE_S9 (1 << 10 | 2 << 22) +#define DRIVE_S10 (2 << 10 | 2 << 22) +#define DRIVE_S11 (3 << 10 | 2 << 22) +#define DRIVE_S12 (0 << 10 | 3 << 22) +#define DRIVE_S13 (1 << 10 | 3 << 22) +#define DRIVE_S14 (2 << 10 | 3 << 22) +#define DRIVE_S15 (3 << 10 | 3 << 22) +#endif + +#if GPIO_VERSION < 3 +#define BUS_HOLD (1 << 12) +#endif + +#if GPIO_VERSION < 5 +#define FAST_SLEW (0 << 13) +#define SLOW_SLEW (1 << 13) +#else +#define VERY_FAST_SLEW (0 << 15 | 0 << 13) +#define FAST_SLEW (0 << 15 | 1 << 13) +#define SLOW_SLEW (1 << 15 | 0 << 13) +#endif + +#if GPIO_VERSION > 3 +#define INPUT_CMOS (0 << 14) +#define INPUT_SCHMITT (1 << 14) +#endif + +#if GPIO_VERSION > 2 +#define INTR_GRP_SEL0 (0 << 16) +#define INTR_GRP_SEL1 (1 << 16) +#define INTR_GRP_SEL2 (2 << 16) +#define INTR_GRP_SEL3 (3 << 16) +#define INTR_GRP_SEL4 (4 << 16) +#define INTR_GRP_SEL5 (5 << 16) +#define INTR_GRP_SEL6 (6 << 16) +#define INT_MASKED (7 << 16) +#endif + +#define CFG_DISABLED ( FUNC_GPIO | CFG_DISABLE | INT_MASKED) +#define CFG_IN (INPUT_ENABLE | FUNC_GPIO | CFG_GP_IN | INT_MASKED) +#define CFG_OUT (INPUT_ENABLE | FUNC_GPIO | CFG_GP_OUT | INT_MASKED) +#define CFG_OUT_0 (INPUT_ENABLE | FUNC_GPIO | CFG_GP_OUT | DATA_0 | INT_MASKED) +#define CFG_OUT_1 (INPUT_ENABLE | FUNC_GPIO | CFG_GP_OUT | DATA_1 | INT_MASKED) +#define CFG_FUNC0 (INPUT_ENABLE | FUNC_ALT0 | INT_MASKED) +#define CFG_FUNC1 (INPUT_ENABLE | FUNC_ALT1 | INT_MASKED) +#define CFG_FUNC2 (INPUT_ENABLE | FUNC_ALT2 | INT_MASKED) + +/* Global slew rate adjustment, for hardware which supports it */ + +#define SLEW_RATE_FAST 0 +#define SLEW_RATE_SLOW 1 + +#endif /* ! __APPLE_GPIO_H */ diff --git a/drivers/apple/gpio/rules.mk b/drivers/apple/gpio/rules.mk new file mode 100644 index 0000000..328df5e --- /dev/null +++ b/drivers/apple/gpio/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_GPIO=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/gpio.o + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/include diff --git a/drivers/apple/h2fmi/H2FIL.c b/drivers/apple/h2fmi/H2FIL.c new file mode 100644 index 0000000..cd2d22c --- /dev/null +++ b/drivers/apple/h2fmi/H2FIL.c @@ -0,0 +1,192 @@ +// ***************************************************************************** +// +// File: H2FIL.c +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi.h" +#include "H2fmi_ppn.h" +#include +#include +#include + +/*****************************************************************************/ +/* Static variables definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ + +static LowFuncTbl stLowFuncTbl = +{ + .GetDeviceInfo = h2fmiGetDeviceInfo, + .Reset = h2fmiReset, + .CalcCurrentTiming = h2fmiCalcCurrentTimings, + .SetWhiteningState = h2fmiSetWhiteningState, + .SetWhiteningMetadataState = h2fmiSetWhiteningMetadataState, + .RegisterCurrentTransaction = h2fmiRegisterCurrentTransaction, + +#if (defined(AND_SUPPORT_BLOCK_STORAGE) && AND_SUPPORT_BLOCK_STORAGE) + .SetDeviceInfo = h2fmiSetDeviceInfo, + .ReadWithECC = h2fmiReadSinglePage, + .ReadNoECC = h2fmiReadNoECC, + .ReadMultiplePages = h2fmiReadSequentialPages, + .ReadScatteredPages = h2fmiReadScatteredPages, +#endif + +#if (AND_FPART_ONLY || AND_SUPPORT_BLOCK_STORAGE) + .ReadMaxECC = h2fmiReadSinglePageMaxECC, +#endif + +#if ((defined(AND_SUPPORT_NVRAM) && AND_SUPPORT_NVRAM) || (defined(AND_SUPPORT_FW_AREA) && AND_SUPPORT_FW_AREA)) + .ReadBLPage = h2fmiReadBootpage, +#endif + +#if !H2FMI_READONLY + .WriteMultiplePages = h2fmiWriteMultiplePages, + .Write = h2fmiWriteSinglePage, + .WriteScatteredPages = h2fmiWriteScatteredPages, + .WriteMaxECC = h2fmiWriteSinglePageMaxECC, +#endif // !H2FMI_READONLY + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + .Erase = h2fmiEraseSingleBlock, + .EraseMultiple = NULL, + .WriteBLPage = h2fmiWriteBootpage, +#endif // !defined(AND_READONLY) +}; + +#if WITH_PPN +static LowFuncTbl stLowFuncTblPpn = { + +#if (AND_SUPPORT_BLOCK_STORAGE || AND_SUPPORT_NVRAM || AND_SUPPORT_FW_AREA) + .GetDeviceInfo = h2fmiGetDeviceInfo, + .Reset = h2fmiReset, + .CalcCurrentTiming = h2fmiCalcCurrentTimings, + .SetWhiteningState = h2fmiSetWhiteningState, + .SetWhiteningMetadataState = h2fmiSetWhiteningMetadataState, + .RegisterCurrentTransaction = h2fmiRegisterCurrentTransaction, + .ReadWithECC = h2fmiPpnReadSinglePage, +#endif + +#if (defined(AND_SUPPORT_BLOCK_STORAGE) && AND_SUPPORT_BLOCK_STORAGE) + .SetDeviceInfo = h2fmiSetDeviceInfo, + .ReadNoECC = NULL, + .ReadMultiplePages = NULL, + .ReadScatteredPages = NULL, + .ReadMaxECC = NULL, +#elif (defined(AND_FPART_ONLY) && AND_FPART_ONLY) + .ReadNoECC = NULL, + .ReadMaxECC = NULL, +#endif + +#if ((defined(AND_SUPPORT_NVRAM) && AND_SUPPORT_NVRAM) || (defined(AND_SUPPORT_FW_AREA) && AND_SUPPORT_FW_AREA)) + .ReadBLPage = h2fmiPpnReadBootpage, +#endif + +#if !H2FMI_READONLY + .WriteMultiplePages = NULL, + .Write = h2fmiPpnWriteSinglePage, + .WriteScatteredPages = NULL, + .WriteMaxECC = NULL, +#endif // !H2FMI_READONLY + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + .Erase = h2fmiPpnEraseSingleBlock, + .EraseMultiple = NULL, + .WriteBLPage = h2fmiPpnWriteBootpage, +#endif + .PerformCommandList = h2fmiPpnPerformCommandList, +}; +#endif //WITH_PPN + +extern h2fmi_t g_fmi0; + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ +Int32 +FIL_Init(void) +{ + Int32 nFILRet; + static BOOL32 bInitDone = FALSE32; + + if (TRUE32 == bInitDone) + { + h2fmiPrintConfig(); + return FIL_SUCCESS; + } + + nFILRet = h2fmiInit(); + if (nFILRet != FIL_SUCCESS) + { + return nFILRet; + } + +#if !WITH_PPN + if (g_fmi0.is_ppn) + { + WMR_PRINT(ERROR, "[FIL:ERR] Build does not support PPN!\n"); + return FIL_UNSUPPORTED_ERROR; + } +#endif // WITH_PPN + + bInitDone = TRUE32; + return FIL_SUCCESS; +} + +LowFuncTbl* +FIL_GetFuncTbl() +{ + LowFuncTbl *ppn = NULL; + +#if WITH_PPN + ppn = &stLowFuncTblPpn; +#endif // WITH_PPN + + return (g_fmi0.is_ppn ? ppn : &stLowFuncTbl); +} + +BOOL32 FIL_GetStruct(UInt32 dwStructType, void* pvoidStructBuffer, UInt32* pdwStructSize) +{ + WMR_PRINT(INF, "[FIL:INF] FIL_GetStruct(0x%08X)\n", dwStructType); + + return h2fmiGetStruct(dwStructType, pvoidStructBuffer, pdwStructSize); +} + +#if AND_SUPPORT_BLOCK_STORAGE +BOOL32 FIL_SetStruct(UInt32 dwStructType, void* pvoidStructBuffer, UInt32 dwStructSize) +{ + WMR_PRINT(INF, + "[FIL:INF] FIL_SetStruct(0x%08X, %d)\n", dwStructType, dwStructSize); + + return h2fmiSetStruct(dwStructType, pvoidStructBuffer, dwStructSize); +} +#endif //AND_SUPPORT_BLOCK_STORAGE + +void FIL_Close(void) +{ + // do nothing +} +/* +void FIL_SwitchToPpn(void) +{ + stLowFuncTbl.GetDeviceInfo = h2fmi_ppn_get_device_info; +} +*/ diff --git a/drivers/apple/h2fmi/H2fmi.c b/drivers/apple/h2fmi/H2fmi.c new file mode 100644 index 0000000..7b2ebfe --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi.c @@ -0,0 +1,2934 @@ +// ***************************************************************************** +// +// File: H2fmi.c +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2008-2009 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "WMROAM.h" +#include +#include + +#include "H2fmi_private.h" +#include "H2fmi.h" +#if WMR_BUILDING_IBOOT +#include "nandid.h" +#else +#include "NandSpec.h" +#endif + +#include "H2fmi_ppn.h" + +// ============================================================================= +// external global variable definitions +// ============================================================================= +extern UInt8 nand_whitening_key[16]; + + +#if (defined (AND_COLLECT_FIL_STATISTICS) && AND_COLLECT_FIL_STATISTICS) +#define AND_FIL_STAT(x) (x) +FILStatistics stFILStatistics; +#else +#define AND_FIL_STAT(x) +#endif + + +// ============================================================================= +// private global variable definitions +// ============================================================================= + +UInt32* g_pScratchBuf = NULL; + +h2fmi_t g_fmi0; +h2fmi_t g_fmi1; + +static BOOL32 useWhitening = TRUE32; +static BOOL32 useWhiteningMetadata = FALSE32; + +static h2fmi_virt_to_phys_map_t virtPhysMap[ NAND_MAX_CE_COUNT_TOTAL ]; + +static const UInt8 kPpnChipId[] = { 0x50, 0x50, 0x4E }; + + +// ============================================================================= +// private local variable definitions +// ============================================================================= +static FILDeviceInfo stDeviceInfo; + +static UInt8 nand_default_key[16] = { 0xf6, 0x5d, 0xae, 0x95, + 0x0e, 0x90, 0x6c, 0x42, + 0xb2, 0x54, 0xcc, 0x58, + 0xfc, 0x78, 0xee, 0xce }; + +static UInt64 fmi_current_lba_base = 0; +static UInt8* fmi_current_dest_ptr = 0; +static UInt32 fmi_current_num_blks = 0; + +static UInt32 metaLookupTable[METADATA_LOOKUP_SIZE]; +static UInt32 metaContent; + +#if SUPPORT_PPN +static ppn_feature_entry_t _ppnFeatureList[] = +{ +#if H2FMI_PPN_VERIFY_SET_FEATURES + { + PPN_VERSION_1_0_0 , + PPN_FEATURE__DRIVE_STRENGTH , + 2 , + 1 , + } , +#endif // H2FMI_PPN_VERIFY_SET_FEATURES +}; +#endif + +// ============================================================================= +// private implementation function declarations +// ============================================================================= + +static void h2fmi_setup_whitening(BOOL32 encrypt, h2fmi_t* fmi, UInt32* seeds); +static void h2fmi_setup_default_encryption(BOOL32 encrypt, void* destPtr, h2fmi_t* fmi); +static void h2fmi_choose_aes(BOOL32 enable, BOOL32 encrypt, void* destPtr, h2fmi_t* fmi, UInt32* seeds); +static void h2fmi_calc_default_iv(void* arg, UInt32 chunk_index, void* iv_buffer); +static UInt32 h2fmi_generate_meta_content(void); +static void h2fmi_generate_meta_table(void); +static void h2fmi_encrypt_metadata(UInt32 page, UInt8* pabMetaBuf); +static void h2fmi_decrypt_metadata(UInt32 page, UInt8* pabMetaBuf); +static BOOL32 h2fmi_get_nand_layout(void * buffer, UInt32 *size); +static BOOL32 h2fmiGetChipIdStruct(void * buffer, UInt32 *size, UInt8 addr); +static void h2fmiMapVirtualCEToBusAndEnable( UInt32 virtualCE, UInt32 bus, UInt32 enable); +static BOOL32 h2fmi_init_minimal(h2fmi_t* fmi, UInt32 interface); +static void h2fmi_set_initial_timings(h2fmi_t* fmi); +static void h2fmi_init_raw_state(h2fmi_t *fmi, const NandInfo* nandInfo, NandRequiredTimings *requiredTiming); +static Int32 _initRawNand(h2fmi_t **fmi_list, const UInt32 num_fmi, const NandChipId *id_list, NandFmcSettings *actual); +static void _init_whimory_state(h2fmi_t* fmi, const NandInfo *nandInfo, UInt32 numDataBus, UInt16 ceCount); +#if (defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) +static BOOL32 h2fmiGetPPNUID(PpnUIDReadRequest* ppnUIDRead, UInt32* pdwStructSize, BOOL32* setPattern, BOOL32* toBreak); +static BOOL32 h2fmiGetRAWUID(GenericReadRequest* genericRead, UInt32* pdwStructSize, BOOL32* setPattern, BOOL32* toBreak); +#endif //(defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) +#if SUPPORT_PPN +static Int32 _initPPN(h2fmi_t **fmi_list, const UInt32 num_fmi, const NandChipId *id_list, NandFmcSettings *actual, UInt32 ppn_version); +static BOOL32 h2fmiPpnFirmwareIsBlacklisted(const UInt8 *mfg_id, const UInt8 *fw_version); +static void checkForWorkarounds(UInt8* mfg_id, h2fmi_t **fmi_list, const UInt32 num_fmi); +static void setPpnFeatures(h2fmi_t **fmiList, const UInt32 fmiCount); +#endif + +// ============================================================================= +// Nand info macros +// ============================================================================= + +#define _GetPagesPerBlock() (stDeviceInfo.wPagesPerBlock) +#define _SetPagesPerBlock(_x) do { stDeviceInfo.wPagesPerBlock = _x; } while (0) +#define _GetBlocksPerCS() (stDeviceInfo.wBlocksPerCS) +#define _SetBlocksPerCS(_x) do { stDeviceInfo.wBlocksPerCS = _x; } while (0) +#define _GetPagesPerCS() (_GetPagesPerBlock() * _GetBlocksPerCS()) +#define _GetNumOfCS() (stDeviceInfo.wNumOfCS) +#define _SetNumOfCS(_x) do { stDeviceInfo.wNumOfCS = _x; } while (0) +#define _GetDiesPerCS() (stDeviceInfo.wDiesPerCS) +#define _SetDiesPerCS(_x) do { stDeviceInfo.wDiesPerCS = _x; } while (0) +#define _GetBanksPerCS() (stDeviceInfo.wBanksPerCS) +#define _SetBanksPerCS(_x) do { stDeviceInfo.wBanksPerCS = _x; } while (0) +#define _GetNumOfBanks() (_GetNumOfCS() * _GetBanksPerCS()) +#define _GetBytesPerPageSpare() (stDeviceInfo.wSpareBytesPerPage) +#define _SetBytesPerPageSpare(_x) do { stDeviceInfo.wSpareBytesPerPage = _x; } while (0) +#define _GetSectorsPerPage() (stDeviceInfo.wSectorsPerPage) +#define _SetSectorsPerPage(_x) do { stDeviceInfo.wSectorsPerPage = _x; } while (0) +#define _GetBytesPerPageMain() (_GetSectorsPerPage() * H2FMI_BYTES_PER_SECTOR) +#define _GetPagesPerSuBlk() (_GetNumOfBanks() * _GetPagesPerBlock()) +#define _GetInitialBadType() (stDeviceInfo.checkInitialBadType) +#define _SetInitialBadType(_x) do { stDeviceInfo.checkInitialBadType = _x; } while (0) +#define _GetECCThresholdBits() (stDeviceInfo.bECCThresholdBits) +#define _SetECCThresholdBits(_x) do { stDeviceInfo.bECCThresholdBits = _x; } while (0) +#define _GetECCCorrectableBits() (stDeviceInfo.bECCCorrectableBits) +#define _SetECCCorrectableBits(_x) do { stDeviceInfo.bECCCorrectableBits = _x; } while (0) +#define _GetVendorSpecificType() (stDeviceInfo.vendorSpecificType) +#define _SetVendorSpecificType(_x) do { stDeviceInfo.vendorSpecificType = _x; } while (0) +#define DUMP_VAR(variable) _WMR_PRINT("%s : %u\n", #variable, (UInt32)(variable)) + +// ============================================================================= +// public interface function definitions +// ============================================================================= +typedef struct +{ + UInt8 mfg_id[NAND_DEV_PARAM_LEN_PPN]; + UInt8 fw_version[NAND_DEV_PARAM_LEN_PPN]; +}ControllerInfo; + +struct { + h2fmi_chipid_t chipId; + ControllerInfo contInfo; +}gConfigInfo; + +Int32 h2fmiInit(void) +{ + Int32 nRet = FIL_SUCCESS; + Int32 tmpRet; + BOOL32 have_fmi0; + BOOL32 have_fmi1; + h2fmi_chipid_t* fmi0ChipIds; + h2fmi_chipid_t* fmi1ChipIds; + UInt16 wIdx; + UInt16 numDataBus; + UInt16 ceCount; + BOOL32 is_ppn; + h2fmi_t *fmi_list[H2FMI_MAX_NUM_BUS] = {0}; + UInt32 fmi_idx; + NandFmcSettings actual; + + + WMR_PRINT(LOG, "[FIL:LOG] h2fmiInit()\n"); + + // initialize scratch space + if (g_pScratchBuf == NULL) + { + UInt32 bufSize = WMR_MAX(NAND_MAX_CE_COUNT_TOTAL * sizeof(h2fmi_chipid_t) * H2FMI_MAX_NUM_BUS, + H2FMI_BYTES_PER_SECTOR); + bufSize = WMR_MAX(bufSize, PPN_MAX_PAGES * H2FMI_MAX_META_PER_LBA * H2FMI_MAX_LBA_PER_PAGE); + g_pScratchBuf = WMR_MALLOC(bufSize); + if (g_pScratchBuf == NULL) + { + nRet = FIL_CRITICAL_ERROR; + return nRet; + } + } + + fmi0ChipIds = (h2fmi_chipid_t*)g_pScratchBuf; + fmi1ChipIds = fmi0ChipIds + NAND_MAX_CE_COUNT_TOTAL; + + // perform minimum initialization on specified FMI interface + h2fmi_init_minimal(&g_fmi0, 0); + h2fmi_init_minimal(&g_fmi1, 1); + +// Only for H5X - // Software workaround for Samsung reset and bad chip ID isssue +#if FMI_VERSION >= 5 + { + have_fmi0 = h2fmi_nand_reset_all(&g_fmi0); + have_fmi1 = h2fmi_nand_reset_all(&g_fmi1); + + if(have_fmi0) + { + have_fmi0 = h2fmi_nand_read_id_all(&g_fmi0, fmi0ChipIds, CHIPID_ADDR); + } + if(have_fmi1) + { + have_fmi1 = h2fmi_nand_read_id_all(&g_fmi1, fmi1ChipIds, CHIPID_ADDR); + } + } +#else + { + have_fmi0 = h2fmi_reset_and_read_chipids(&g_fmi0, fmi0ChipIds, CHIPID_ADDR); + have_fmi1 = h2fmi_reset_and_read_chipids(&g_fmi1, fmi1ChipIds, CHIPID_ADDR); + } +#endif // FMI_VERSION >= 5 + + WMR_MEMCPY(&(gConfigInfo.chipId), &fmi0ChipIds[0], sizeof(h2fmi_chipid_t)); + + // record chip IDs in the devicetree if we fail + reportDbgChipIds(g_pScratchBuf, NAND_MAX_CE_COUNT_TOTAL * sizeof(h2fmi_chipid_t) * H2FMI_MAX_NUM_BUS); + + // fail if any one of the FMI interfaces could not be initialized + if (!have_fmi0 || !have_fmi1) + { + nRet = FIL_CRITICAL_ERROR; + return nRet; + } + + if (WMR_MEMCMP(&fmi0ChipIds[0], kPpnChipId, sizeof(kPpnChipId)) == 0) + { + WMR_PRINT(INIT, "[FIL] PPN Device Detected\n"); +#if !SUPPORT_PPN + nRet = FIL_CRITICAL_ERROR; + return nRet; +#else //!SUPPORT_PPN + is_ppn = TRUE32; +#endif //!SUPPORT_PPN + } + else + { + is_ppn = FALSE32; + } + + + h2fmi_build_ce_bitmask(&g_fmi0, fmi0ChipIds, &fmi0ChipIds[0], CHIPID_ADDR); + h2fmi_build_ce_bitmask(&g_fmi1, fmi1ChipIds, &fmi0ChipIds[0], CHIPID_ADDR); + + // Add FMI1 chip IDs to FMI0 + for (wIdx = 0; wIdx < H2FMI_MAX_CE_TOTAL; ++wIdx) + { + if (g_fmi1.valid_ces & (1 << wIdx)) + { + WMR_MEMCPY(&fmi0ChipIds[wIdx], &fmi1ChipIds[wIdx], sizeof(h2fmi_chipid_t)); + } + else if (!(g_fmi0.valid_ces & (1 << wIdx))) + { + WMR_MEMSET(&fmi0ChipIds[wIdx], 0x0, sizeof(h2fmi_chipid_t)); + } + } + + ceCount = g_fmi0.num_of_ce + g_fmi1.num_of_ce; + numDataBus = 0; + if (g_fmi0.num_of_ce) + { + fmi_list[numDataBus] = &g_fmi0; + numDataBus += 1; + } + if (g_fmi1.num_of_ce) + { + fmi_list[numDataBus] = &g_fmi1; + numDataBus += 1; + } + + // We need to initialize the CE map on errors in case the PPN firmware was + // horked. We can't update the firmware properly without the CE map. + tmpRet = h2fmiInitVirtToPhysMap(numDataBus, ceCount); + +#if SUPPORT_PPN + if (is_ppn) + { + UInt32 ppn_version = ((fmi0ChipIds[0][3] << 16) | + (fmi0ChipIds[0][4] << 8) | + (fmi0ChipIds[0][5] << 0)); + + if (PPN_VERSION_BAD_FW == ppn_version) + { + // This device has missing or corrupted firmware: build the virtual CE map + // so we can update the firmware properly, but don't bring up any more of + // the stack. All it'll do is GEB from here. + WMR_PRINT(ERROR, "PPN device has missing or corrupted firmware\n"); + nRet = FIL_CRITICAL_ERROR; + } + else if (PPN_VERSION_ERROR == ppn_version) + { + WMR_PRINT(ERROR, "PPN device reported an error PPN version 0x%06lx\n", ppn_version); + nRet = FIL_CRITICAL_ERROR; + } + else if (PPN_VERSION_UNSUPPORTED <= ppn_version) + { + WMR_PRINT(ERROR, "PPN device reported unsupported PPN version 0x%06lx\n", ppn_version); + nRet = FIL_CRITICAL_ERROR; + } + else + { + const NandChipId *id_list = (const NandChipId*)fmi0ChipIds; + +#if SUPPORT_TOGGLE_NAND + if (PPN_VERSION_1_5_0 <= ppn_version) + { + if (targetSupportsToggle()) + { + for(fmi_idx = 0; fmi_idx < numDataBus; ++fmi_idx) + { + h2fmi_t *fmi = fmi_list[fmi_idx]; + fmi->is_toggle_system = TRUE32; + fmi->useDiffDQS = targetSupportsDiffDQS(); + fmi->useDiffRE = targetSupportsDiffRE(); + fmi->useVREF = targetSupportsVREF(); + } + setToggleMode(); + WMR_PRINT(INIT, "[FIL] Using DDR mode.\n"); + } + else + { + WMR_PRINT(INIT, "[FIL] Using SDR mode.\n"); + } + } + +#endif // SUPPORT_TOGGLE_NAND + + nRet = _initPPN(fmi_list, numDataBus, id_list, &actual, ppn_version); + } + } + else +#endif // SUPPORT_PPN + { + const NandChipId *id_list = (const NandChipId*)fmi0ChipIds; + nRet = _initRawNand(fmi_list, numDataBus, id_list, &actual); + } + + if (FIL_SUCCESS == nRet) + { + // Setup the full-speed bus timings that we will use + for(fmi_idx = 0; fmi_idx < numDataBus; ++fmi_idx) + { + h2fmi_t *fmi = fmi_list[fmi_idx]; + + fmi->if_ctrl = (FMC_IF_CTRL__DCCYCLE(actual.read_dccycle_clocks) | + FMC_IF_CTRL__REB_SETUP(actual.read_setup_clocks) | + FMC_IF_CTRL__REB_HOLD(actual.read_hold_clocks) | + FMC_IF_CTRL__WEB_SETUP(actual.write_setup_clocks) | + FMC_IF_CTRL__WEB_HOLD(actual.write_hold_clocks)); + fmi->if_ctrl_normal = fmi->if_ctrl; + +#if SUPPORT_TOGGLE_NAND + if (fmi->is_toggle_system) + { +#if SUPPORT_NAND_DLL + UInt32 dllLock; + + if (!h2fmiTrainDLL(&dllLock)) + { + nRet = FIL_CRITICAL_ERROR; + fmi->dqs_ctrl = FMC_DQS_TIMING_CTRL__DEFAULT_VAL; + } + else + { + fmi->dqs_ctrl = FMC_DQS_TIMING_CTRL__USE_DLL | + FMC_DQS_TIMING_CTRL__DELTAV_SUSPENDS_READS; + } +#else + fmi->dqs_ctrl = FMC_DQS_TIMING_CTRL__DEFAULT_VAL; +#endif + fmi->timing_ctrl_1 = (FMC_TOGGLE_CTRL_1_DDR_RD_PRE_TIME(actual.read_pre_clocks) | + FMC_TOGGLE_CTRL_1_DDR_RD_POST_TIME(actual.read_post_clocks) | + FMC_TOGGLE_CTRL_1_DDR_WR_PRE_TIME(actual.write_pre_clocks) | + FMC_TOGGLE_CTRL_1_DDR_WR_POST_TIME(actual.write_post_clocks)); + fmi->timing_ctrl_2 = (FMC_TOGGLE_CTRL_2_CE_SETUP_TIME(actual.ce_setup_clocks) | + FMC_TOGGLE_CTRL_2_CE_HOLD_TIME(actual.ce_hold_clocks) | + FMC_TOGGLE_CTRL_2_NAND_TIMING_ADL(actual.adl_clocks) | + FMC_TOGGLE_CTRL_2_NAND_TIMING_WHR(actual.whr_clocks)); + fmi->toggle_if_ctrl = (FMC_IF_CTRL__DCCYCLE(0) | + FMC_IF_CTRL__REB_SETUP(actual.ddr_half_cycle_clocks) | + FMC_IF_CTRL__REB_HOLD(0) | + FMC_IF_CTRL__WEB_SETUP(actual.write_setup_clocks) | + FMC_IF_CTRL__WEB_HOLD(actual.write_hold_clocks)); + + WMR_PRINT(ALWAYS, "FMC_DQS_TIMING_CTRL = 0x%x\n", fmi->dqs_ctrl); + WMR_PRINT(ALWAYS, "FMC_TOGGLE_CTRL_1 = 0x%x\n", fmi->timing_ctrl_1); + WMR_PRINT(ALWAYS, "FMC_TOGGLE_CTRL_2 = 0x%x\n", fmi->timing_ctrl_2); + WMR_PRINT(ALWAYS, "FMC_IF_CTRL = 0x%x\n", fmi->if_ctrl); + WMR_PRINT(ALWAYS, "FMC_IF_CTRL [DDR] = 0x%x\n", fmi->toggle_if_ctrl); + } +#endif // SUPPORT_TOGGLE_NAND + + restoreTimingRegs(fmi); + } + +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + reportToggleModeFMCTimingValues(actual.ddr_half_cycle_clocks, + actual.ce_setup_clocks, + actual.ce_hold_clocks, + actual.adl_clocks, + actual.whr_clocks, + actual.read_pre_clocks, + actual.read_post_clocks, + actual.write_pre_clocks, + actual.write_post_clocks, + g_fmi0.dqs_ctrl); + } +#endif + // Tell the target OS what values to use + reportFMCTimingValues(actual.read_setup_clocks, + actual.read_hold_clocks, + actual.read_dccycle_clocks, + actual.write_setup_clocks, + actual.write_hold_clocks); + } + + nRet = (FIL_SUCCESS == nRet ? tmpRet : nRet); + h2fmi_generate_meta_table(); + + if (FIL_SUCCESS == nRet) + { + // no need to record chip IDs, and the scratch buffer will be reused + reportDbgChipIds(NULL, 0); + } + + return nRet; +} + +#if SUPPORT_NAND_DLL +BOOL32 h2fmiTrainDLL(UInt32 *lock) +{ + UInt64 startTicks; + UInt64 timeoutTicks = H2FMI_DEFAULT_TIMEOUT_MICROS * WMR_GET_TICKS_PER_US(); + UInt32 status; + BOOL32 ret = TRUE32; + + WMR_DLL_CLOCK_GATE(TRUE32); + + // Need to implement SW workaround for H5P DLL lock status bug + //Due to the above bug, we need to wait till locked bit clears + startTicks = WMR_CLOCK_TICKS(); + do + { + if (WMR_HAS_TIME_ELAPSED_TICKS(startTicks, timeoutTicks)) + { + WMR_PRINT(ERROR, "Timed out waiting for DLL LOCKED bit to clear!\n"); + ret = FALSE32; + break; + } + else + { + // There is a bug in H5P, whereby we have to read timeout register before we can read the status register + h2fmi_dll_rd(NAND_DLL_TIMEOUT_DELAY); + } + status = h2fmi_dll_rd(NAND_DLL_STATUS); + }while(NAND_DLL_STATUS__DLL_LOCKED_GET(status)); + + if (ret) + { + UInt32 nand_dll_control = NAND_DLL_CONTROL__REFERENCE(NAND_DLL_CONTROL__REFERENCE_DEFAULT) | + NAND_DLL_CONTROL__STEP_SIZE(NAND_DLL_CONTROL__STEP_SIZE_DEFAULT) | + NAND_DLL_CONTROL__START_POINT(NAND_DLL_CONTROL__START_POINT_DEFAULT) | + NAND_DLL_CONTROL__HALF | + NAND_DLL_CONTROL__VOLTAGE_SHIFT_START | + NAND_DLL_CONTROL__SOFTWARE_START | + NAND_DLL_CONTROL__ENABLE; + + // start training + h2fmi_dll_wr(NAND_DLL_CONTROL, nand_dll_control); + + WMR_SLEEP_US(NAND_DLL_TRAIN_TIME_US); + + // There is a bug in H5P, whereby we have to read timeout register before we can read the status register + (void)h2fmi_dll_rd(NAND_DLL_TIMEOUT_DELAY); + status = h2fmi_dll_rd(NAND_DLL_STATUS); + + if (ret) + { + *lock = NAND_DLL_STATUS__LOCK_VALUE_GET(status); + + // The lock value should never be less than the start point. It will also help + // us in detecting FMI Master DLL unstable at low voltage + if (*lock < NAND_DLL_CONTROL__START_POINT_DEFAULT) + { + WMR_PRINT(ERROR, "DLL lock < start point!\n"); + ret = FALSE32; + } + } + } + + return ret; +} +#endif + +void h2fmiPrintConfig(void) +{ + h2fmi_chipid_t *id = &(gConfigInfo.chipId); + h2fmi_t* fmi; + UInt32 ce; + + for (ce = 0 ; ce < H2FMI_MAX_CE_TOTAL ; ce++) + { + if ( 0 != ((1UL << ce) & g_fmi0.valid_ces)) + { + fmi = &g_fmi0; + } + else if ( 0 != ((1UL << ce) & g_fmi1.valid_ces)) + { + fmi = &g_fmi1; + } + else + { + continue; + } + + WMR_PRINT(INIT, "Chip ID %02X %02X %02X %02X %02X %02X on FMI%d:CE%d\n", + (*id)[0], (*id)[1], (*id)[2], (*id)[3], (*id)[4], (*id)[5], + fmi->bus_id, + ce); + } + +#if SUPPORT_PPN + + if (g_fmi0.is_ppn) + { + UInt8 *mfgId = gConfigInfo.contInfo.mfg_id; + UInt8 *fwVer = gConfigInfo.contInfo.fw_version; + WMR_PRINT(INIT, "PPN Manufacturer ID: %02X %02X %02X %02X %02X %02X\n", + mfgId[0], mfgId[1], mfgId[2], mfgId[3], mfgId[4], mfgId[5]); + + WMR_PRINT(INIT, "PPN Controller Version: %16.16s\n", fwVer); + } + +#endif //SUPPORT_PPN + +} + +void +_init_whimory_state(h2fmi_t* fmi, const NandInfo *nandInfo, UInt32 numDataBus, UInt16 ceCount) +{ + UInt32 roundedBlocksPerDie; + UInt32 roundedPagesPerBlock; + + WMR_MEMSET(&stDeviceInfo, 0, sizeof(stDeviceInfo)); + + stDeviceInfo.wNumOfBusses = numDataBus; + stDeviceInfo.wNumOfCS = ceCount; + + stDeviceInfo.wBlocksPerCS = fmi->blocks_per_ce; + stDeviceInfo.wPagesPerBlock = fmi->pages_per_block; + stDeviceInfo.wSectorsPerPage = fmi->sectors_per_page; + stDeviceInfo.wSpareBytesPerPage = fmi->bytes_per_spare; + + stDeviceInfo.wBanksPerCS = fmi->banks_per_ce; + stDeviceInfo.wDiesPerCS = fmi->dies_per_cs; + stDeviceInfo.wBlocksPerDie = fmi->blocks_per_ce / fmi->dies_per_cs; + + if (stDeviceInfo.wBlocksPerCS & (stDeviceInfo.wBlocksPerCS - 1)) // non-pow2 blocks per cs + { + roundedBlocksPerDie = 1 << WMR_LOG2(stDeviceInfo.wBlocksPerDie); + stDeviceInfo.wDieStride = (stDeviceInfo.wBlocksPerDie % roundedBlocksPerDie)? (roundedBlocksPerDie << 1) : roundedBlocksPerDie; + stDeviceInfo.wLastBlock = (stDeviceInfo.wDiesPerCS - 1) * stDeviceInfo.wDieStride + stDeviceInfo.wBlocksPerDie; + stDeviceInfo.wUserBlocksPerCS = 1 << WMR_LOG2(stDeviceInfo.wBlocksPerCS); + } + else + { + stDeviceInfo.wDieStride = stDeviceInfo.wBlocksPerDie; + stDeviceInfo.wLastBlock = stDeviceInfo.wBlocksPerCS; + stDeviceInfo.wUserBlocksPerCS = stDeviceInfo.wBlocksPerCS; + } + roundedPagesPerBlock = 1 << WMR_LOG2(stDeviceInfo.wPagesPerBlock); + // MSB, or MSBx2 if non-pow2 + stDeviceInfo.wBlockStride = (stDeviceInfo.wPagesPerBlock % roundedPagesPerBlock)? (roundedPagesPerBlock << 1) : roundedPagesPerBlock; + + if (fmi->is_ppn) + { + stDeviceInfo.dwBlocksPerCAU = fmi->ppn->device_params.blocks_per_cau; + stDeviceInfo.dwCAUsPerCE = fmi->ppn->device_params.caus_per_channel; + stDeviceInfo.dwSLCPagesPerBlock = fmi->ppn->device_params.pages_per_block_slc; + stDeviceInfo.dwMLCPagesPerBlock = fmi->ppn->device_params.pages_per_block; + stDeviceInfo.dwMatchOddEvenCAUs = fmi->ppn->device_params.block_pairing_scheme; + stDeviceInfo.dwBitsPerCAUAddress = fmi->ppn->device_params.cau_bits; + stDeviceInfo.dwBitsPerPageAddress = fmi->ppn->device_params.page_address_bits; + stDeviceInfo.dwBitsPerBlockAddress = fmi->ppn->device_params.block_bits; + stDeviceInfo.ppn = 1; +#if SUPPORT_TOGGLE_NAND + stDeviceInfo.toggle = fmi->is_toggle_system ? 1 : 0; +#endif + stDeviceInfo.dwMaxTransactionSize = fmi->ppn->device_params.prep_function_buffer_size; + + stDeviceInfo.checkInitialBadType = INIT_BBT_PPN; + stDeviceInfo.vendorSpecificType = 0; + stDeviceInfo.bAddrBitsForBitsPerCell = fmi->ppn->device_params.address_bits_bits_per_cell; + } + else + { + stDeviceInfo.dwBlocksPerCAU = stDeviceInfo.wBlocksPerDie; + stDeviceInfo.dwCAUsPerCE = stDeviceInfo.wDiesPerCS; + stDeviceInfo.dwSLCPagesPerBlock = stDeviceInfo.wPagesPerBlock; + stDeviceInfo.dwMLCPagesPerBlock = stDeviceInfo.wPagesPerBlock; + stDeviceInfo.dwMatchOddEvenCAUs = 0; + stDeviceInfo.dwBitsPerCAUAddress = 1; + stDeviceInfo.dwBitsPerPageAddress = WMR_LOG2(stDeviceInfo.wPagesPerBlock - 1) + 1; + stDeviceInfo.dwBitsPerBlockAddress = WMR_LOG2(stDeviceInfo.wPagesPerBlock - 1) + 1; + stDeviceInfo.ppn = 0; + stDeviceInfo.dwMaxTransactionSize = stDeviceInfo.wBanksPerCS * stDeviceInfo.wPagesPerBlock; + + stDeviceInfo.checkInitialBadType = nandInfo->geometry->initialBBType; + stDeviceInfo.vendorSpecificType = nandInfo->boardSupport->vsType; + stDeviceInfo.bAddrBitsForBitsPerCell = 0; + } + + stDeviceInfo.dwValidMetaPerLogicalPage = nandInfo->format->validMetaPerLogicalPage; + stDeviceInfo.dwTotalMetaPerLogicalPage = nandInfo->format->metaPerLogicalPage; + stDeviceInfo.dwLogicalPageSize = nandInfo->format->logicalPageSize; + + + stDeviceInfo.bECCThresholdBits = fmi->refresh_threshold_bits; + stDeviceInfo.bECCCorrectableBits = fmi->correctable_bits; +} + +Int32 +_initRawNand(h2fmi_t **fmi_list, const UInt32 num_fmi, const NandChipId *id_list, NandFmcSettings *actual) +{ + NandInfo nandInfo; + h2fmi_t *fmi; + UInt32 fmi_idx; + NandRequiredTimings required; + Int32 ret = FIL_SUCCESS; + UInt32 ce_count = 0; + + if (findNandInfo(id_list, &nandInfo, num_fmi)) + { + for(fmi_idx = 0; fmi_idx < num_fmi; ++fmi_idx) + { + fmi = fmi_list[fmi_idx]; + fmi->is_ppn = FALSE32; + ce_count += fmi->num_of_ce; + h2fmi_init_raw_state(fmi, &nandInfo, &required); + } + // Tell the chip ID library these numbers so it can pass them + // to the device tree + setECCLevels(fmi_list[0]->correctable_bits, fmi_list[0]->refresh_threshold_bits); + +#if FMI_VERSION > 2 + if (!NandRequirementToIFCTRL(&required, actual)) + { + ret = FIL_CRITICAL_ERROR; + } +#else + if (!Legacy_NandRequirementToIFCTRL(&required, actual)) + { + ret = FIL_CRITICAL_ERROR; + } +#endif + + _init_whimory_state(fmi_list[0], &nandInfo, num_fmi, ce_count); + } + else + { + WMR_PRINT(ERROR, + "[FIL:ERR] FMI - No recognized NAND found!\n"); + ret = FIL_CRITICAL_ERROR; + } + return ret; +} + +#if SUPPORT_PPN +Int32 +_initPPN(h2fmi_t **fmi_list, const UInt32 num_fmi, const NandChipId *id_list, NandFmcSettings *actual, UInt32 ppn_version) +{ + NandInfo nandInfo; + NandRequiredTimings required; + const h2fmi_t *first_fmi = fmi_list[0]; + UInt32 fmi_idx; + UInt32 ce_count = 0; + UInt32 ceMap = 0; + + if (!h2fmi_ppn_fil_init()) + { + return FIL_CRITICAL_ERROR; + } + + // Strict check CE and bus symmetry + if (((num_fmi != 1) || !targetSupportsSingleCE()) && + (num_fmi != 2) && (num_fmi != 4)) + { + WMR_PRINT(ERROR, "Invalid fmi count: %d\n", num_fmi); + return FIL_CRITICAL_ERROR; + } + for (fmi_idx = 0; fmi_idx < num_fmi; fmi_idx++) + { + h2fmi_t *current_fmi = fmi_list[fmi_idx]; + if (current_fmi->num_of_ce != first_fmi->num_of_ce) + { + return FIL_CRITICAL_ERROR; + } + // Verify that no two buses claim the same CE + if (current_fmi->valid_ces & ceMap) + { + return FIL_CRITICAL_ERROR; + } + + ceMap |= current_fmi->valid_ces; + } + if (!checkPpnLandingMap(ceMap)) + { + return FIL_CRITICAL_ERROR; + } + + WMR_MEMSET(&nandInfo, 0, sizeof(nandInfo)); + // Fetch device info for all channels + // before issuing Normal-Mode on any of them + for(fmi_idx = 0; fmi_idx < num_fmi; ++fmi_idx) + { + h2fmi_t *current_fmi = fmi_list[fmi_idx]; + current_fmi->is_ppn = TRUE32; + current_fmi->clock_speed_khz = WMR_BUS_FREQ_HZ() / 1000; + + if (!h2fmi_ppn_init_channel(current_fmi, FALSE32, 0, FALSE32, 0, 0, ppn_version)) + { + WMR_PRINT(ERROR, "h2fmi_ppn_init_channel for channel %d failed!\n", fmi_idx); + return FIL_CRITICAL_ERROR; + } + ce_count += current_fmi->num_of_ce; + + h2fmi_ppn_post_rst_pre_pwrstate_operations(current_fmi); + + if (0 != current_fmi->valid_ces) + { + if (!h2fmi_ppn_get_device_params(current_fmi, + (h2fmi_ce_t)WMR_LSB1(current_fmi->valid_ces), + ¤t_fmi->ppn->device_params)) + { + return FIL_CRITICAL_ERROR; + } + } + } + + h2fmiPpnGetControllerInfo(0, gConfigInfo.contInfo.mfg_id, gConfigInfo.contInfo.fw_version); + if (!h2fmiPpnValidateManufacturerIds(gConfigInfo.contInfo.mfg_id, ce_count)) + { + WMR_PRINT(ERROR, "Inconsistent PPN controller manufacturer ids\n"); + return FIL_CRITICAL_ERROR; + } + else if (!h2fmiPpnValidateFirmwareVersions(gConfigInfo.contInfo.fw_version, ce_count)) + { + WMR_PRINT(ERROR, "Inconsistent PPN controller firmware versions\n"); + return FIL_CRITICAL_ERROR; + } + else if (h2fmiPpnFirmwareIsBlacklisted(gConfigInfo.contInfo.mfg_id, gConfigInfo.contInfo.fw_version)) + { + WMR_PRINT(ERROR, "PPN Device FW is unsupported.\n"); + return FIL_CRITICAL_ERROR; + } + + checkForWorkarounds(gConfigInfo.contInfo.mfg_id, fmi_list, num_fmi); + + // Set all channels to Normal Mode without sending + // any other commands to any other channels + for(fmi_idx = 0; fmi_idx < num_fmi; ++fmi_idx) + { + h2fmi_t *current_fmi = fmi_list[fmi_idx]; + if (!h2fmi_ppn_set_channel_power_state(current_fmi, +#if SUPPORT_TOGGLE_NAND + (current_fmi->is_toggle_system) ? PPN_PS_TRANS_LOW_POWER_TO_DDR : +#endif + PPN_PS_TRANS_LOW_POWER_TO_ASYNC)) + { + WMR_PRINT(ERROR, "Setting power state failed on FMI %d!\n", fmi_idx); + return FIL_CRITICAL_ERROR; + } + +#if SUPPORT_TOGGLE_NAND + if (current_fmi->is_toggle_system) + { + current_fmi->is_toggle = TRUE32; + turn_on_fmc(current_fmi); + restoreTimingRegs(current_fmi); + } +#endif + + // Parse device parameters into FMI structures + h2fmi_ppn_fill_nandinfo(current_fmi, &nandInfo, &required); + nandInfo.ppn = ¤t_fmi->ppn->nandPpn; + } + +#if H2FMI_PPN_VERIFY_SET_FEATURES + for(fmi_idx = 0; fmi_idx < num_fmi; ++fmi_idx) + { + h2fmi_t *current_fmi = fmi_list[fmi_idx]; + h2fmi_ppn_verify_feature_shadow(current_fmi); + } +#endif // H2FMI_PPN_VERIFY_SET_FEATURES + +#if SUPPORT_TOGGLE_NAND + if (fmi_list[0]->is_toggle_system) + { + if (!Toggle_NandRequirementToIFCTRL(&required, actual)) + { + WMR_PRINT(ERROR, "Unable to derive toggle bus timings\n"); + return FIL_CRITICAL_ERROR; + } + WMR_PRINT(INIT, "ddr_rs %d rpre %d rpst %d wpre %d wpst %d cs %d ch %d adl %d whr %d\n", + actual->ddr_half_cycle_clocks, + actual->read_pre_clocks, + actual->read_post_clocks, + actual->write_pre_clocks, + actual->write_post_clocks, + actual->ce_setup_clocks, + actual->ce_hold_clocks, + actual->adl_clocks, + actual->whr_clocks); + } +#endif //SUPPORT_TOGGLE_NAND + if (!NandRequirementToIFCTRL(&required, actual)) + { + WMR_PRINT(ERROR, "Unable to derive bus timings\n"); + return FIL_CRITICAL_ERROR; + } + WMR_PRINT(INIT, "rs %d rh %d dc %d ws %d wh %d\n", + actual->read_setup_clocks, + actual->read_hold_clocks, + actual->read_dccycle_clocks, + actual->write_setup_clocks, + actual->write_hold_clocks); + + setPpnFeatures(fmi_list, num_fmi); + + for(fmi_idx = 0; fmi_idx < num_fmi; ++fmi_idx) + { + h2fmi_t *current_fmi = fmi_list[fmi_idx]; + if (nandInfo.format->logicalPageSize == 0) + { + current_fmi->logical_page_size = current_fmi->bytes_per_page; + if (current_fmi->logical_page_size > 8 * 1024) + { + // lba is > 8KB + WMR_PRINT(ERROR, "%d sized LBAs are not supported\n", current_fmi->logical_page_size); + return FIL_UNSUPPORTED_ERROR; + } + } + else + { + current_fmi->logical_page_size = nandInfo.format->logicalPageSize; + } + current_fmi->valid_bytes_per_meta = nandInfo.format->validMetaPerLogicalPage; + current_fmi->total_bytes_per_meta = nandInfo.format->metaPerLogicalPage; + current_fmi->fmi_config_reg = h2fmi_ppn_calculate_fmi_config(current_fmi); +#if FMI_VERSION > 0 + current_fmi->fmi_data_size_reg = h2fmi_ppn_calculate_fmi_data_size(current_fmi); +#endif /* FMI_VERSION > 0*/ + } + + // Only setup the device tree if our firmware version passes validation. + // But we still need to call _init_whimory_state() to get our CE map right to + // make the firmware update stuff work to fix the busted part later. + setNandIdPpnConfig(id_list, &nandInfo, num_fmi, ce_count); + + _init_whimory_state(fmi_list[0], &nandInfo, num_fmi, ce_count); + + return FIL_SUCCESS; +} + +static const ControllerInfo _ppn_fw_blacklist[] = +{ + { {0xEC, 0x00, 0x05, 0x49, 0x11, 0x02,}, "040201E01050108F" }, //rdar://9072970 + { {0xEC, 0x00, 0x05, 0x49, 0x11, 0x03,}, "040201E01050108F" }, //rdar://9072970 +#if TARGET_IPAD3 + { {0xAD, 0x82, 0x01, 0x22, 0x01, 0x44,}, {0x30, 0x32, 0x30, 0x30, 0x37, 0x36, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, //rdar://9528679 + { {0xEC, 0x00, 0x05, 0x49, 0x11, 0x02,}, "040601P01090108F" }, //rdar://9498342 + { {0xEC, 0x00, 0x05, 0x49, 0x11, 0x03,}, "040601P01090108F" }, //rdar://9498342 +#endif +}; + + +BOOL32 h2fmiPpnFirmwareIsBlacklisted(const UInt8 *mfg_id, const UInt8 *fw_version) +{ + const ControllerInfo *entry; + UInt32 idx; + for (idx = 0; idx < sizeof(_ppn_fw_blacklist) / sizeof(ControllerInfo); ++idx) + { + entry = &_ppn_fw_blacklist[idx]; + if ((0 == WMR_MEMCMP(entry->mfg_id, mfg_id, PPN_DEVICE_ID_LEN)) && + (0 == WMR_MEMCMP(entry->fw_version, fw_version, NAND_DEV_PARAM_LEN_PPN))) + { + return TRUE32; + } + } + return FALSE32; +} + +void checkForWorkarounds(UInt8* mfg_id, h2fmi_t **fmi_list, const UInt32 num_fmi) +{ + static const ControllerInfo _toshiba_24[] = // rdar://10543574 + { + {{0x98, 0x00, 0x04, 0x16, 0x14, 0x01}, {} }, //24nm 64GB + {{0x98, 0x00, 0x04, 0x18, 0x14, 0x02}, {} }, //24nm 32GB + {{0x98, 0x00, 0x04, 0x1A, 0x14, 0x04}, {} }, //24nm 16GB + {{0x98, 0x00, 0x04, 0x14, 0x10, 0x01}, {} }, //24nm 8GB + }; + + UInt32 info_idx; + UInt32 fmi_idx; + + BOOL32 match = FALSE32; + for (info_idx = 0; info_idx < sizeof(_toshiba_24) / sizeof(ControllerInfo); ++info_idx) + { + if (0 == WMR_MEMCMP(_toshiba_24[info_idx].mfg_id, mfg_id, PPN_DEVICE_ID_LEN)) + { + match = TRUE32; + break; + } + } + + for(fmi_idx = 0; fmi_idx < num_fmi; ++fmi_idx) + { + fmi_list[fmi_idx]->retire_on_invalid_refresh = match; + } + + setPPNOptions(match); +} + +static void setPpnFeatures(h2fmi_t **fmiList, const UInt32 fmiCount) +{ + UInt32 featCount = NUMELEMENTS(_ppnFeatureList); + UInt32 fmiIdx, featIdx; + + // special handling + for (featIdx = 0 ; featIdx < featCount ; featIdx++) + { + ppn_feature_entry_t *entry = &_ppnFeatureList[featIdx]; + + switch (entry->feature) + { + case PPN_FEATURE__NUM_DIE_PROGRAM_PARALLEL : + // fall-through + case PPN_FEATURE__NUM_DIE_READ_PARALLEL : + // fall-through + case PPN_FEATURE__NUM_DIE_ERASE_PARALLEL : + { + entry->value = WMR_MIN(entry->value, fmiList[0]->ppn->device_params.dies_per_channel); + break; + } + + default: + // do nothing + break; + } + } + + for(fmiIdx = 0; fmiIdx < fmiCount; ++fmiIdx) + { + h2fmi_t *fmi = fmiList[fmiIdx]; + h2fmi_ppn_set_feature_list(fmi, _ppnFeatureList, featCount); + } + + reportPpnFeatures(_ppnFeatureList, sizeof(_ppnFeatureList)); +} + +#endif //SUPPORT_PPN + +Int32 +h2fmiInitVirtToPhysMap(UInt16 busCount, UInt16 ceCount) +{ + UInt32 ce; + UInt32 bus; + h2fmi_ce_t enable[H2FMI_MAX_CE_TOTAL]; + UInt8 busIndex[H2FMI_MAX_NUM_BUS] = {0, 0}; + BOOL32 mapped = FALSE32; + h2fmi_t* fmi; + + enable[ 0 ] = 0; + enable[ 1 ] = 8; + + WMR_MEMSET(virtPhysMap, 0xFF, sizeof(virtPhysMap)); + + WMR_PRINT(INF, "[FIL:INF] Mapping %d bus and %d CE\n", (UInt32)busCount, (UInt32)ceCount); + for (ce = 0; ce < ceCount;) + { + mapped = FALSE32; + + // in order to best interleave across busses, map the next + // virtual CE to the next active enable from each bus that + // has any remaining active enables (i.e. stripe across busses) + for (bus = 0; (bus < H2FMI_MAX_NUM_BUS) && (ce < ceCount); bus++) + { + // if there is still an active enable available on this bus, + // assign it the next virtual CE to this bus and enable + fmi = (bus == 0) ? &g_fmi0 : &g_fmi1; + if (fmi->valid_ces & (1 << enable[bus])) + { + h2fmiMapVirtualCEToBusAndEnable(ce, bus, enable[bus]); + fmi->ceMap[busIndex[bus]] = enable[bus]; + ce++; + busIndex[bus]++; + mapped = TRUE32; + } + enable[bus]++; + } + } + + // at least one CE must be mapped per stripe + if(!mapped) + { + WMR_PRINT(ERROR, "CE Map failed!\n"); + return FIL_CRITICAL_ERROR; + } + else + { + return FIL_SUCCESS; + } +} + +void +h2fmiMapVirtualCEToBusAndEnable( UInt32 virtualCE, UInt32 bus, UInt32 enable ) +{ + WMR_PRINT(INF, "[FIL:INF] Map virtual ce %d to bus %d, ce %d\n", virtualCE, bus, enable ); + + virtPhysMap[ virtualCE ].ce = enable; + virtPhysMap[ virtualCE ].bus = bus; +} + +h2fmi_t* +h2fmiTranslateVirtualCEToBus( UInt32 virtualCE ) +{ + UInt32 bus = virtPhysMap[virtualCE].bus; + switch(bus) + { + case 0: + return &g_fmi0; + case 1: + return &g_fmi1; + default: + return NULL; + } +} + +h2fmi_ce_t +h2fmiTranslateVirtualCEToCe( UInt32 virtualCE ) +{ + return virtPhysMap[virtualCE].ce; +} + +#if !(AND_FPART_ONLY) +void +h2fmiSetDeviceInfo(UInt32 dwParamType, UInt32 dwVal) +{ + WMR_PRINT(LOG, "[FIL:LOG] h2fmiSetDeviceInfo()\n"); + + switch(dwParamType) + { + case AND_DEVINFO_VENDOR_SPECIFIC_TYPE: + // VS writes are not implemented in boot context + break; + + case AND_DEVINFO_BANKS_PER_CS: + g_fmi0.banks_per_ce = dwVal; + g_fmi1.banks_per_ce = dwVal; + stDeviceInfo.wBanksPerCS = ((UInt16)dwVal); + break; + + default: + WMR_PANIC("unsupported 0x%08x\n", dwParamType); + break; + } +} +#endif //!AND_FPART_ONLY + +UInt32 +h2fmiGetDeviceInfo(UInt32 dwParamType) +{ + UInt32 dwRetVal = 0xFFFFFFFF; + + WMR_PRINT(LOG, "[FIL:LOG] h2fmiGetDeviceInfo()\n"); + + switch(dwParamType) + { + + case AND_DEVINFO_DIES_PER_CS: + dwRetVal = (UInt32)stDeviceInfo.wDiesPerCS; + break; + + case AND_DEVINFO_BLOCKS_PER_DIE: + dwRetVal = (UInt32)stDeviceInfo.wBlocksPerDie; + break; + + case AND_DEVINFO_DIE_STRIDE: + dwRetVal = (UInt32)stDeviceInfo.wDieStride; + break; + + case AND_DEVINFO_BLOCK_STRIDE: + dwRetVal = (UInt32)stDeviceInfo.wBlockStride; + break; + + case AND_DEVINFO_LAST_BLOCK: + dwRetVal = (UInt32)stDeviceInfo.wLastBlock; + break; + + case AND_DEVINFO_USER_BLOCKS_PER_CS: + dwRetVal = (UInt32)stDeviceInfo.wUserBlocksPerCS; + break; + + case AND_DEVINFO_PAGES_PER_BLOCK: + dwRetVal = (UInt32)stDeviceInfo.wPagesPerBlock; + break; + + case AND_DEVINFO_NUM_OF_CS: + dwRetVal = (UInt32)stDeviceInfo.wNumOfCS; + break; + + case AND_DEVINFO_BBT_TYPE: + dwRetVal = (UInt32)stDeviceInfo.checkInitialBadType; + break; + + case AND_DEVINFO_BLOCKS_PER_CS: + dwRetVal = (UInt32)stDeviceInfo.wBlocksPerCS; + break; + + case AND_DEVINFO_BYTES_PER_PAGE: + dwRetVal = (UInt32)(stDeviceInfo.wSectorsPerPage * H2FMI_BYTES_PER_SECTOR); + break; + + case AND_DEVINFO_BYTES_PER_SPARE: + dwRetVal = (UInt32)stDeviceInfo.wSpareBytesPerPage; + break; + + case AND_DEVINFO_VENDOR_SPECIFIC_TYPE: + dwRetVal = (UInt32)stDeviceInfo.vendorSpecificType; + break; + + case AND_DEVINFO_REFRESH_THRESHOLD: + dwRetVal = (UInt32)stDeviceInfo.bECCThresholdBits; + break; + + case AND_DEVINFO_CORRECTABLE_SIZE: + dwRetVal = (UInt32)H2FMI_BYTES_PER_SECTOR; + break; + + case AND_DEVINFO_BYTES_PER_BL_PAGE: + dwRetVal = H2FMI_BOOT_BYTES_PER_PAGE; + break; + + case AND_DEVINFO_CORRECTABLE_BITS: + dwRetVal = g_fmi0.correctable_bits; + break; + + case AND_DEVINFO_NUM_OF_BANKS: + dwRetVal = (UInt32)stDeviceInfo.wNumOfCS * stDeviceInfo.wBanksPerCS; + break; + + case AND_DEVINFO_BLOCKS_PER_CAU: + dwRetVal = stDeviceInfo.dwBlocksPerCAU; + break; + + case AND_DEVINFO_CAUS_PER_CE: + dwRetVal = stDeviceInfo.dwCAUsPerCE; + break; + + case AND_DEVINFO_SLC_PAGES_PER_BLOCK: + dwRetVal = stDeviceInfo.dwSLCPagesPerBlock; + break; + + case AND_DEVINFO_MLC_PAGES_PER_BLOCK: + dwRetVal = stDeviceInfo.dwMLCPagesPerBlock; + break; + + case AND_DEVINFO_MATCH_ODDEVEN_CAUS: + dwRetVal = stDeviceInfo.dwMatchOddEvenCAUs; + break; + + case AND_DEVINFO_BITS_PER_CAU_ADDRESS: + dwRetVal = stDeviceInfo.dwBitsPerCAUAddress; + break; + + case AND_DEVINFO_BITS_PER_PAGE_ADDRESS: + dwRetVal = stDeviceInfo.dwBitsPerPageAddress; + break; + + case AND_DEVINFO_BITS_PER_BLOCK_ADDRESS: + dwRetVal = stDeviceInfo.dwBitsPerBlockAddress; + break; + + case AND_DEVINFO_NUM_OF_CHANNELS: + dwRetVal = stDeviceInfo.wNumOfBusses; + break; + + case AND_DEVINFO_NUM_OF_CES_PER_CHANNEL: + if (stDeviceInfo.wNumOfBusses > 0) + { + dwRetVal = stDeviceInfo.wNumOfCS / stDeviceInfo.wNumOfBusses; + } + else + { + dwRetVal = 0; + } + break; + + case AND_DEVINFO_PPN_DEVICE: + dwRetVal = stDeviceInfo.ppn; + break; + + case AND_DEVINFO_TOGGLE_DEVICE: +#if SUPPORT_TOGGLE_NAND + dwRetVal = stDeviceInfo.toggle; +#else + dwRetVal = 0; +#endif + break; + + case AND_DEVINFO_BANKS_PER_CS: + dwRetVal = stDeviceInfo.wBanksPerCS; + break; + + case AND_DEVINFO_FIL_LBAS_PER_PAGE: + if (stDeviceInfo.dwLogicalPageSize == 0) + { + dwRetVal = 1; + } + else + { + dwRetVal = (stDeviceInfo.wSectorsPerPage * H2FMI_BYTES_PER_SECTOR) / stDeviceInfo.dwLogicalPageSize; + } + + break; + + case AND_DEVINFO_FIL_META_VALID_BYTES: + dwRetVal = stDeviceInfo.dwValidMetaPerLogicalPage; + break; + + case AND_DEVINFO_FIL_META_BUFFER_BYTES: + dwRetVal = stDeviceInfo.dwTotalMetaPerLogicalPage; + break; + + case AND_DEVINFO_FIL_PREP_BUFFER_ENTRIES: + dwRetVal = stDeviceInfo.dwMaxTransactionSize; + break; + + case AND_DEVINFO_ADDR_BITS_BITS_PER_CELL: + dwRetVal = stDeviceInfo.bAddrBitsForBitsPerCell; + break; + + case AND_DEVINFO_STREAM_BUFFER_MAX: + dwRetVal= 0; + break; + + default: + WMR_PANIC("unsupported 0x%08x\n", dwParamType); + break; + } + return dwRetVal; +} + +static BOOL32 h2fmi_get_nand_layout(void * buffer, UInt32 *size) +{ + ANDNandLayoutStruct * pLayout = (ANDNandLayoutStruct*) buffer; + UInt32 idx; + UInt32 cursor; + const UInt32 dwParityBytes = h2fmi_calculate_ecc_output_bytes(&g_fmi0); + + if (!size) + { + return FALSE32; + } + else if (pLayout && (*size < sizeof(ANDNandLayoutStruct))) + { + // It's OK just to ask the size + return FALSE32; + } + + *size = sizeof(ANDNandLayoutStruct); + + if (!pLayout) + { + return TRUE32; + } + + WMR_ASSERT((_GetSectorsPerPage() + 1UL) <= sizeof(pLayout->pastrSegments)); + + // Meta data is at the end of the first envelope + pLayout->dwMetaSegmentIndex = 1; + pLayout->dwNumSegments = _GetSectorsPerPage() + 1; + + pLayout->pastrSegments[0].dwOffset = 0; + pLayout->pastrSegments[0].dwLength = H2FMI_BYTES_PER_SECTOR; + cursor = H2FMI_BYTES_PER_SECTOR; + + pLayout->pastrSegments[1].dwOffset = cursor; + pLayout->pastrSegments[1].dwLength = g_fmi0.valid_bytes_per_meta; + cursor += g_fmi0.valid_bytes_per_meta + dwParityBytes; + + for (idx = 2; idx < pLayout->dwNumSegments; ++idx) + { + pLayout->pastrSegments[idx].dwOffset = cursor; + pLayout->pastrSegments[idx].dwLength = H2FMI_BYTES_PER_SECTOR; + cursor += H2FMI_BYTES_PER_SECTOR + dwParityBytes; + } + + return TRUE32; +} + +static BOOL32 h2fmiGetChipIdStruct(void * buffer, UInt32 *size, UInt8 addr) +{ + BOOL32 boolRes; + h2fmi_chipid_t* fmi0ChipIds, * fmi1ChipIds; + UInt16 wIdx; + UInt32 valid_ces; + const UInt32 dwRequiredBufferSize = H2FMI_MAX_CE_TOTAL * sizeof(UInt64); + + if (!size) + { + boolRes = FALSE32; + } + else if (buffer && (*size < dwRequiredBufferSize)) + { + // It's OK just to ask the size + boolRes = FALSE32; + } + else if (!buffer) + { + *size = dwRequiredBufferSize; + boolRes = TRUE32; + } + else + { + fmi0ChipIds = (h2fmi_chipid_t*)g_pScratchBuf; + fmi1ChipIds = fmi0ChipIds + H2FMI_MAX_CE_TOTAL; + WMR_MEMSET(g_pScratchBuf, 0, sizeof(h2fmi_chipid_t) * NAND_MAX_CE_COUNT_TOTAL * 2); + +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + WMR_ASSERT(g_fmi1.is_toggle_system || (0 == g_fmi1.num_of_ce)); + g_fmi0.is_toggle = FALSE32; + g_fmi1.is_toggle = FALSE32; + } +#endif + + h2fmi_reset(&g_fmi0); + h2fmi_reset(&g_fmi1); + +// Only for H5X - // Software workaround for Samsung reset and bad chip ID isssue +#if FMI_VERSION >= 5 + { + BOOL32 reset_result_ch0, reset_result_ch1; + reset_result_ch0 = h2fmi_nand_reset_all(&g_fmi0); + reset_result_ch1 = h2fmi_nand_reset_all(&g_fmi1); + + if(reset_result_ch0) + { + h2fmi_nand_read_id_all(&g_fmi0, fmi0ChipIds, addr); + } + if(reset_result_ch1) + { + h2fmi_nand_read_id_all(&g_fmi1, fmi1ChipIds, addr); + } + } +#else + { + h2fmi_reset_and_read_chipids(&g_fmi0, fmi0ChipIds, addr); + h2fmi_reset_and_read_chipids(&g_fmi1, fmi1ChipIds, addr); + } +#endif // FMI_VERSION >= 5 + + h2fmi_build_ce_bitmask(&g_fmi0, fmi0ChipIds, &fmi0ChipIds[0], addr); + h2fmi_build_ce_bitmask(&g_fmi1, fmi1ChipIds, &fmi0ChipIds[0], addr); + + valid_ces = g_fmi0.valid_ces | g_fmi1.valid_ces; + +#if SUPPORT_PPN + if (g_fmi0.is_ppn) + { + WMR_ASSERT(g_fmi1.is_ppn || (0 == g_fmi1.num_of_ce)); + h2fmi_ppn_post_rst_pre_pwrstate_operations(&g_fmi0); + if(g_fmi1.num_of_ce) + { + h2fmi_ppn_post_rst_pre_pwrstate_operations(&g_fmi1); + } + } +#endif + + WMR_MEMSET(buffer, 0, H2FMI_MAX_CE_TOTAL * sizeof(UInt64)); + + for (wIdx = 0; wIdx < H2FMI_MAX_CE_TOTAL; ++wIdx) + { + h2fmi_chipid_t* srcID = &fmi0ChipIds[0]; + *((UInt64 *)srcID) = (*(UInt64 *)srcID) & MAX_ID_SIZE_MASK; + UInt64* destID = ((UInt64*)buffer) + wIdx; + if( valid_ces & (1 << wIdx)) + { + WMR_MEMCPY(destID, srcID, sizeof(UInt64)); + } + } + *size = dwRequiredBufferSize; + + // There's probably a better way to do this, but FMI currently resets all devices in the same path that reads the chip ID. + // On a PPN device, that'll kick us back into low-power mode. Force it back to ASYNC/DDR mode... +#if SUPPORT_PPN + if (g_fmi0.is_ppn) + { + h2fmi_ppn_set_channel_power_state(&g_fmi0, +#if SUPPORT_TOGGLE_NAND + (g_fmi0.is_toggle_system) ? PPN_PS_TRANS_LOW_POWER_TO_DDR : +#endif + PPN_PS_TRANS_LOW_POWER_TO_ASYNC); + + if(g_fmi1.num_of_ce) + { + WMR_ASSERT(g_fmi1.is_ppn); + h2fmi_ppn_set_channel_power_state(&g_fmi1, +#if SUPPORT_TOGGLE_NAND + (g_fmi1.is_toggle_system) ? PPN_PS_TRANS_LOW_POWER_TO_DDR : +#endif + PPN_PS_TRANS_LOW_POWER_TO_ASYNC); + } + +#if H2FMI_PPN_VERIFY_SET_FEATURES + if(g_fmi0.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi0); + } + if(g_fmi1.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi1); + } +#endif // H2FMI_PPN_VERIFY_SET_FEATURES + +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + g_fmi0.is_toggle = TRUE32; + + h2fmi_reset(&g_fmi0); + if(g_fmi1.num_of_ce) + { + WMR_ASSERT(g_fmi1.is_toggle_system); + g_fmi1.is_toggle = TRUE32; + } + h2fmi_reset(&g_fmi1); + } +#endif + + } +#endif //SUPPORT_PPN + boolRes = TRUE32; + } + return boolRes; +} + +void h2fmi_write_bus_timings(NandTimingParams *timing) +{ +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + g_fmi0.toggle_if_ctrl &= (~FMC_IF_CTRL__REB_SETUP_MASK); + g_fmi0.toggle_if_ctrl |= FMC_IF_CTRL__REB_SETUP(timing->ddr_tHALFCYCLE); + + g_fmi1.toggle_if_ctrl &= (~FMC_IF_CTRL__REB_SETUP_MASK); + g_fmi1.toggle_if_ctrl |= FMC_IF_CTRL__REB_SETUP(timing->ddr_tHALFCYCLE); + + h2fmi_set_if_ctrl(&g_fmi0, g_fmi0.toggle_if_ctrl); + h2fmi_set_if_ctrl(&g_fmi1, g_fmi1.toggle_if_ctrl); + } + else + { +#endif + g_fmi0.if_ctrl = ((FMC_IF_CTRL__WPB & (g_fmi0.if_ctrl)) | + (FMC_IF_CTRL__RBBEN & (g_fmi0.if_ctrl)) | + FMC_IF_CTRL__DCCYCLE(timing->sdrTimings.DCCYCLE) | + FMC_IF_CTRL__REB_SETUP(timing->sdrTimings.tRP) | + FMC_IF_CTRL__REB_HOLD(timing->sdrTimings.tREH) | + FMC_IF_CTRL__WEB_SETUP(timing->sdrTimings.tWP) | + FMC_IF_CTRL__WEB_HOLD(timing->sdrTimings.tWH)); + g_fmi0.if_ctrl_normal = g_fmi0.if_ctrl; + + g_fmi1.if_ctrl = ((FMC_IF_CTRL__WPB & (g_fmi1.if_ctrl)) | + (FMC_IF_CTRL__RBBEN & (g_fmi1.if_ctrl)) | + FMC_IF_CTRL__DCCYCLE(timing->sdrTimings.DCCYCLE) | + FMC_IF_CTRL__REB_SETUP(timing->sdrTimings.tRP) | + FMC_IF_CTRL__REB_HOLD(timing->sdrTimings.tREH) | + FMC_IF_CTRL__WEB_SETUP(timing->sdrTimings.tWP) | + FMC_IF_CTRL__WEB_HOLD(timing->sdrTimings.tWH)); + g_fmi1.if_ctrl_normal = g_fmi1.if_ctrl; + + h2fmi_set_if_ctrl(&g_fmi0, g_fmi0.if_ctrl); + h2fmi_set_if_ctrl(&g_fmi1, g_fmi1.if_ctrl); +#if SUPPORT_TOGGLE_NAND + } +#endif +} + +void h2fmi_read_bus_timings(NandTimingParams *timing) +{ +#if SUPPORT_TOGGLE_NAND +#if APPLICATION_EMBEDDEDIOP + if (g_fmi0.is_toggle) +#else + if (g_fmi0.is_toggle_system) +#endif + { + timing->ddr_tHALFCYCLE = FMC_IF_CTRL__GET_REB_SETUP(g_fmi0.toggle_if_ctrl); + } + else + { +#endif + timing->sdrTimings.DCCYCLE = FMC_IF_CTRL__GET_DCCYCLE(g_fmi0.if_ctrl); + timing->sdrTimings.tRP = FMC_IF_CTRL__GET_REB_SETUP(g_fmi0.if_ctrl); + timing->sdrTimings.tREH = FMC_IF_CTRL__GET_REB_HOLD(g_fmi0.if_ctrl); + timing->sdrTimings.tWP = FMC_IF_CTRL__GET_WEB_SETUP(g_fmi0.if_ctrl); + timing->sdrTimings.tWH = FMC_IF_CTRL__GET_WEB_HOLD(g_fmi0.if_ctrl); +#if SUPPORT_TOGGLE_NAND + } +#endif +} + + + +BOOL32 h2fmiSetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 dwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType & AND_STRUCT_FIL_MASK) + { + case AND_STRUCT_FIL_SET_TIMINGS: + { + NandTimingParams *timing = pvoidStructBuffer; + if((dwStructSize != sizeof(NandTimingParams)) || (NULL == pvoidStructBuffer)) + { + boolRes = FALSE32; + break; + } + h2fmi_write_bus_timings(timing); + boolRes = TRUE32; + break; + } + + default: + { + break; + } + } + return boolRes; +} + +#if SUPPORT_PPN +static BOOL32 h2fmiGetDeviceParameters(UInt32 dwStructType, void* pvoidStructBuffer, UInt32* pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + UInt16 ceIdx; + UInt8 phyCE; + const UInt32 requiredSize = NAND_DEV_PARAM_LEN_PPN * _GetNumOfCS(); + UInt8 *cursor = (UInt8*)pvoidStructBuffer; + + if ((pvoidStructBuffer == NULL) || (pdwStructSize == NULL) || (*pdwStructSize < requiredSize)) + { + return FALSE32; + } + else + { + for(ceIdx = 0; ceIdx< _GetNumOfCS(); ceIdx++) + { + phyCE = h2fmiTranslateVirtualCEToCe(ceIdx); + h2fmi_t *whichFmi = h2fmiTranslateVirtualCEToBus(ceIdx); + + if(whichFmi) + { + switch (dwStructType & AND_STRUCT_FIL_MASK) + { + case AND_STRUCT_FIL_FW_VERSION: + { + boolRes = h2fmi_ppn_get_fw_version(whichFmi, phyCE, cursor); + break; + } + + case AND_STRUCT_FIL_PKG_ASSEMBLY_CODE: + { + boolRes = h2fmi_ppn_get_package_assembly_code(whichFmi, phyCE, cursor); + break; + } + + case AND_STRUCT_FIL_CONTROLLER_UID: + { + boolRes = h2fmi_ppn_get_controller_unique_id(whichFmi, phyCE, cursor); + break; + } + + case AND_STRUCT_FIL_CONTROLLER_HW_ID: + { + boolRes = h2fmi_ppn_get_controller_hw_id(whichFmi, phyCE, cursor); + break; + } + default: + WMR_PRINT(ERROR, "[FIL:DBG] FNAND_h2fmiGetDeviceParameters 0x%X is not identified as FIL data struct identifier!\n", dwStructType); + boolRes = FALSE32; + } + + cursor += NAND_DEV_PARAM_LEN_PPN; + } + } + *pdwStructSize = NAND_DEV_PARAM_LEN_PPN * _GetNumOfCS(); + } + return boolRes; +} +#endif //SUPPORT_PPN + +BOOL32 h2fmiGetStruct(UInt32 dwStructType, void* pvoidStructBuffer, UInt32* pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType & AND_STRUCT_FIL_MASK) + { +#if !(AND_FPART_ONLY) +#if AND_COLLECT_FIL_STATISTICS + case AND_STRUCT_FIL_STATISTICS: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stFILStatistics, sizeof(stFILStatistics)); + break; + } +#endif + + case AND_STRUCT_FIL_CHIPID: + { + boolRes = h2fmiGetChipIdStruct(pvoidStructBuffer, pdwStructSize, CHIPID_ADDR); + break; + } + + case AND_STRUCT_FIL_MFG_ID: + { + boolRes = h2fmiGetChipIdStruct(pvoidStructBuffer, pdwStructSize, MfgID_ADDR); + break; + } + +#if (defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) + case AND_STRUCT_FIL_UNIQUEID: + { + BOOL32 setPattern = FALSE32; + BOOL32 toBreak = FALSE32; + PpnUIDReadRequest *ppnUIDRead = pvoidStructBuffer; + GenericReadRequest *genericRead = pvoidStructBuffer; + + if(stDeviceInfo.ppn) + { + boolRes = h2fmiGetPPNUID(ppnUIDRead, pdwStructSize, &setPattern, &toBreak); + } + else + { + boolRes = h2fmiGetRAWUID(genericRead, pdwStructSize, &setPattern, &toBreak); + } + + if(toBreak == TRUE32) + { + break; + } + + if(setPattern) + { + UInt32 i; + UInt8 pattern = 0x0; // UID is stored as data followed by (!data), so this is just checking that + for (i=0; i<((stDeviceInfo.ppn)?(NAND_UID_PPN_BYTES_TO_READ):(NAND_UID_RAW_PAGE_BYTES_TO_READ)); i+=((stDeviceInfo.ppn)?(NAND_UID_LEN_PPN):(NAND_UID_LEN_RAW))) + { + WMR_MEMSET( ( (stDeviceInfo.ppn)?(&((ppnUIDRead->buf[i]))):(&((genericRead->buf[i]))) ), pattern, ((stDeviceInfo.ppn)?(NAND_UID_LEN_PPN):(NAND_UID_LEN_RAW)) ); + pattern = ~pattern; + } + boolRes = TRUE32; + } + break; + } + +#endif // (defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) + + case AND_STRUCT_FIL_NAND_LAYOUT: + { + boolRes = h2fmi_get_nand_layout(pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_FIL_SPARE_SIZE: + { + UInt32 dwSpareSize = _GetBytesPerPageSpare(); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwSpareSize, sizeof(dwSpareSize)); + break; + } + + case AND_STRUCT_FIL_BITS_PER_CELL: + { + UInt32 dwBitsPerCell; + if (_GetPagesPerBlock() < 128) + { + dwBitsPerCell = 1; + } + else if (0 == (_GetPagesPerBlock() % 3)) + { + dwBitsPerCell = 3; + } + else + { + dwBitsPerCell = 2; + } + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwBitsPerCell, sizeof(dwBitsPerCell)); + break; + } + + case AND_STRUCT_FIL_LBAS_PER_PAGE: + { + UInt32 dwLbasPerPage; + if (stDeviceInfo.dwLogicalPageSize == 0) + { + dwLbasPerPage = 1; + } + else + { + dwLbasPerPage = (stDeviceInfo.wSectorsPerPage * H2FMI_BYTES_PER_SECTOR) / stDeviceInfo.dwLogicalPageSize; + } + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwLbasPerPage, sizeof(dwLbasPerPage)); + break; + } + + case AND_STRUCT_FIL_DIES_PER_CE: + { + UInt32 diesPerCE = _GetDiesPerCS(); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &diesPerCE, sizeof(diesPerCE)); + break; + } + + case AND_STRUCT_FIL_BLOCKS_PER_CE: + { + UInt32 blocksPerCE = _GetBlocksPerCS(); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &blocksPerCE, sizeof(blocksPerCE)); + break; + } + + case AND_STRUCT_FIL_GET_TIMINGS: + { + NandTimingParams timing; + if (*pdwStructSize != sizeof(NandTimingParams)) + { + boolRes = FALSE32; + break; + } + h2fmi_read_bus_timings(&timing); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &timing, sizeof(timing)); + break; + } +#endif // !(AND_FPART_ONLY) + case AND_STRUCT_FIL_GET_CE_INFO: + { + PPNChipEnableStruct *ceInfo; + h2fmi_t *fmi; + + ceInfo = (PPNChipEnableStruct *)pvoidStructBuffer; + fmi = (ceInfo->channel == 0) ? &g_fmi0 : &g_fmi1; + + ceInfo->physical_chip_enable = fmi->ceMap[ceInfo->chip_enable_idx]; + boolRes = TRUE32; + break; + } +#if SUPPORT_PPN + case AND_STRUCT_FIL_FW_VERSION: + case AND_STRUCT_FIL_PKG_ASSEMBLY_CODE: + case AND_STRUCT_FIL_CONTROLLER_UID: + case AND_STRUCT_FIL_CONTROLLER_HW_ID: + { + boolRes = h2fmiGetDeviceParameters(dwStructType, pvoidStructBuffer, pdwStructSize); + break; + } +#endif + default: + WMR_PRINT(ERROR, "[FIL:DBG] FNAND_GetStruct 0x%X is not identified as FIL data struct identifier!\n", dwStructType); + boolRes = FALSE32; + } + return boolRes; +} + +void h2fmiReset(void) +{ + WMR_PRINT(LOG, "[FIL:LOG] h2fmiReset()\n"); + + AND_FIL_STAT(stFILStatistics.ddwResetCallCnt++); + + // do nothing +} + +Int32 h2fmiReadNoECC(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabDataBuf, + UInt8* pabSpareBuf) +{ + Int32 nRet = FIL_SUCCESS; + + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe(wVirtualCE); + + WMR_PRINT(READ, "[FIL:LOG] h2fmiReadNoEcc()\n"); + + WMR_PREPARE_READ_BUFFER(pabDataBuf, fmi->bytes_per_page); + WMR_PREPARE_READ_BUFFER(pabSpareBuf, fmi->bytes_per_spare); + + AND_FIL_STAT(stFILStatistics.ddwReadNoECCCallCnt++); + AND_FIL_STAT(stFILStatistics.ddwPagesReadCnt++); + + h2fmi_choose_aes(FALSE32, FALSE32, pabDataBuf, fmi, &dwPpn); + + if (!h2fmi_read_raw_page(fmi, + ce, + dwPpn, + pabDataBuf, + pabSpareBuf)) + { + nRet = FIL_CRITICAL_ERROR; + } + + WMR_COMPLETE_READ_BUFFER(pabDataBuf, fmi->bytes_per_page); + WMR_COMPLETE_READ_BUFFER(pabSpareBuf, fmi->bytes_per_spare); + + return nRet; +} + +Int32 h2fmiReadSequentialPages(UInt32* padwPpn, + UInt8* pabDataBuf, + UInt8* pabMetaBuf, + UInt16 wNumOfPagesToRead, + UInt8* pbMaxCorrectedBits, + UInt8* pdwaSectorStats, + BOOL32 bDisableWhitening) +{ + Int32 nRet = FIL_SUCCESS; + + const UInt32 banks_total = _GetNumOfBanks(); + + UInt16 wBankIdx; + UInt32 wIdx; + UInt8* dataPtr; + UInt8* metaPtr; + UInt32 cleanCount = 0; + + WMR_PRINT(READ, "[FIL:LOG] h2fmiReadSequentialPages()\n"); + + if (pbMaxCorrectedBits) + { + *pbMaxCorrectedBits = 0; + } + + dataPtr = pabDataBuf; + metaPtr = pabMetaBuf; + + // It is assumed by the caller that ReadSequential will operate on a multiple of + // bankCount and the CE's of the padwPpn array will be paired with ascending + // CE's generated by looping through banks sequentially + for (wIdx = 0; wIdx < wNumOfPagesToRead; wIdx += banks_total) + { + for (wBankIdx = 0; wBankIdx < banks_total; wBankIdx++) + { + const UInt32 dwCurrentPpn = padwPpn[wBankIdx] + (wIdx / banks_total); + const UInt16 wVirtualCE = wBankIdx % banks_total; + + UInt8 maxCorrectedBits = 0; + Int32 singleStatus; + + singleStatus = h2fmiReadSinglePage(wVirtualCE, + dwCurrentPpn, + dataPtr, + metaPtr, + &maxCorrectedBits, + pdwaSectorStats, + bDisableWhitening); + + switch (singleStatus) + { + case FIL_SUCCESS: + // don't overwrite previous failures + break; + case FIL_U_ECC_ERROR: + nRet = FIL_U_ECC_ERROR; + WMR_PRINT(ERROR, "[FIL:ERR] Uncorrectable page detected during scattered read; continuing.\n"); + break; + case FIL_SUCCESS_CLEAN: + nRet = FIL_SUCCESS_CLEAN; + cleanCount++; + break; + default: + nRet = FIL_CRITICAL_ERROR; + WMR_PRINT(ERROR, "[FIL:ERR] Hardware error detected during scattered read: 0x%08x\n", singleStatus); + break; + } + + if (pbMaxCorrectedBits && (maxCorrectedBits > *pbMaxCorrectedBits)) + { + // Trace max corrected bits accross all pages in this operation + *pbMaxCorrectedBits = maxCorrectedBits; + } + + if (pdwaSectorStats) + { + pdwaSectorStats += _GetSectorsPerPage(); + } + + dataPtr += _GetBytesPerPageMain(); + metaPtr += g_fmi0.total_bytes_per_meta; + } + } + + if (cleanCount && (cleanCount != wNumOfPagesToRead)) + { + // Mix of valid and clean pages. Treat this like a UECC error + nRet = FIL_U_ECC_ERROR; + } + + return nRet; +} + +Int32 h2fmiReadScatteredPages(UInt16* pawCEs, + UInt32* padwPpn, + UInt8* pabDataBuf, + UInt8* pabMetaBuf, + UInt16 wNumOfPagesToRead, + UInt8* pbMaxCorrectedBits, + UInt8* pdwaSectorStats, + BOOL32 bDisableWhitening) +{ + Int32 nRet = FIL_SUCCESS; + UInt32 idx; + UInt8* dataPtr; + UInt8* metaPtr; + UInt32 cleanCount = 0; + + WMR_PRINT(READ, "[FIL:LOG] h2fmiReadScatteredPages()\n"); + + if (pbMaxCorrectedBits) + { + *pbMaxCorrectedBits = 0; + } + + dataPtr = pabDataBuf; + metaPtr = pabMetaBuf; + + for (idx = 0; idx < wNumOfPagesToRead; idx++) + { + UInt8 maxCorrectedBits = 0; + Int32 singleStatus; + + singleStatus = h2fmiReadSinglePage(pawCEs[idx], + padwPpn[idx], + dataPtr, + metaPtr, + &maxCorrectedBits, + pdwaSectorStats, + bDisableWhitening); + + switch (singleStatus) + { + case FIL_SUCCESS: + // don't overwrite previous failures + break; + case FIL_U_ECC_ERROR: + nRet = FIL_U_ECC_ERROR; + WMR_PRINT(ERROR, "[FIL:ERR] Uncorrectable page detected during scattered read; continuing.\n"); + break; + case FIL_SUCCESS_CLEAN: + nRet = FIL_SUCCESS_CLEAN; + cleanCount++; + break; + default: + nRet = FIL_CRITICAL_ERROR; + WMR_PRINT(ERROR, "[FIL:ERR] Hardware error detected during scattered read: 0x%08x\n", singleStatus); + break; + } + + if (pbMaxCorrectedBits && (maxCorrectedBits > *pbMaxCorrectedBits)) + { + // Trace max corrected bits accross all pages in this operation + *pbMaxCorrectedBits = maxCorrectedBits; + } + + if (pdwaSectorStats) + { + pdwaSectorStats += _GetSectorsPerPage(); + } + + dataPtr += _GetBytesPerPageMain(); + metaPtr += g_fmi0.total_bytes_per_meta; + } + + if (cleanCount && (cleanCount != wNumOfPagesToRead)) + { + nRet = FIL_U_ECC_ERROR; + } + + return nRet; +} + +Int32 h2fmiReadBootpage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabData) +{ + Int32 nRet; + UInt32 status; + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus( wVirtualCE ); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe( wVirtualCE ); + + WMR_ASSERT(WMR_CHECK_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE)); + WMR_PREPARE_READ_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE); + + status = h2fmi_read_bootpage_pio(fmi, ce, dwPpn, pabData, NULL); + + switch (status) + { + case _kIOPFMI_STATUS_BLANK: + WMR_PRINT(READ, "[FIL:LOG] Clean Page\n"); + nRet = FIL_SUCCESS_CLEAN; + break; + case _kIOPFMI_STATUS_SUCCESS: + WMR_PRINT(READ, "[FIL:LOG] Good page\n"); + nRet = FIL_SUCCESS; + break; + case _kIOPFMI_STATUS_AT_LEAST_ONE_UECC: + WMR_PRINT(ERROR, "UECC ce %d page 0x%08x\n", (UInt32) wVirtualCE, dwPpn); + nRet = FIL_U_ECC_ERROR; + break; + case _kIOPFMI_STATUS_FUSED: + case _kIOPFMI_STATUS_NOT_ALL_CLEAN: + nRet = FIL_U_ECC_ERROR; + break; + default: + WMR_PRINT(ERROR, "[FIL:ERR] Hardware error: 0x%08x\n", status); + nRet = FIL_CRITICAL_ERROR; + break; + } + + WMR_COMPLETE_READ_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE); + + return nRet; + +} + + +Int32 h2fmiReadSinglePage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabDataBuf, + UInt8* pabMetaBuf, + UInt8* pbMaxCorrectedBits, + UInt8* pdwaSectorStats, + BOOL32 bDisableWhitening) +{ + Int32 nRet = FIL_SUCCESS; + UInt32 status; + UInt32 fringe_idx; + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus( wVirtualCE ); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe( wVirtualCE ); + const UInt32 fringe_count = fmi->total_bytes_per_meta - fmi->valid_bytes_per_meta; + UInt8 *pabMetaBounceBuffer = (UInt8*) g_pScratchBuf; + + WMR_PRINT(READ, "[FIL:LOG] h2fmiReadSinglePage()\n"); + + AND_FIL_STAT(stFILStatistics.ddwReadWithECCCallCnt++); + AND_FIL_STAT(stFILStatistics.ddwPagesReadCnt++); + + if (pbMaxCorrectedBits) + { + *pbMaxCorrectedBits = 0; + } + + WMR_ASSERT(WMR_CHECK_BUFFER(pabDataBuf, fmi->bytes_per_page)); + WMR_PREPARE_READ_BUFFER(pabDataBuf, fmi->bytes_per_page); + WMR_PREPARE_READ_BUFFER(pabMetaBounceBuffer, fmi->total_bytes_per_meta); + + h2fmi_choose_aes((useWhitening && !bDisableWhitening), FALSE32, pabDataBuf, fmi, &dwPpn); + + status = h2fmi_read_page(fmi, + ce, + dwPpn, + pabDataBuf, + pabMetaBounceBuffer, + pbMaxCorrectedBits, + pdwaSectorStats); + + WMR_MEMCPY(pabMetaBuf, pabMetaBounceBuffer, fmi->total_bytes_per_meta); + if (useWhiteningMetadata) + { + h2fmi_decrypt_metadata(dwPpn, pabMetaBuf); + } + + switch (status) + { + case _kIOPFMI_STATUS_BLANK: + WMR_PRINT(READ, "[FIL:LOG] Clean Page\n"); + nRet = FIL_SUCCESS_CLEAN; + break; + case _kIOPFMI_STATUS_SUCCESS: + WMR_PRINT(READ, "[FIL:LOG] Good page\n"); + // this allows compatibility of newer 10-byte metadata + // region with code expecting older 12-byte metadata + for (fringe_idx = 0; fringe_idx < fringe_count; fringe_idx++) + { + pabMetaBuf[fmi->valid_bytes_per_meta + fringe_idx] = 0xFF; + } + break; + case _kIOPFMI_STATUS_AT_LEAST_ONE_UECC: + WMR_PRINT(ERROR, "UECC ce %d page 0x%08x\n", (UInt32) wVirtualCE, dwPpn); + nRet = FIL_U_ECC_ERROR; + break; + case _kIOPFMI_STATUS_FUSED: + case _kIOPFMI_STATUS_NOT_ALL_CLEAN: + nRet = FIL_U_ECC_ERROR; + break; + default: + WMR_PRINT(ERROR, "[FIL:ERR] Hardware error: 0x%08x\n", status); + nRet = FIL_CRITICAL_ERROR; + break; + } + + WMR_COMPLETE_READ_BUFFER(pabDataBuf, fmi->bytes_per_page); + WMR_COMPLETE_READ_BUFFER(pabMetaBounceBuffer, fmi->total_bytes_per_meta); + + return nRet; +} + +Int32 h2fmiReadSinglePageMaxECC(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabDataBuf) +{ + Int32 nRet = FIL_SUCCESS; + + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus( wVirtualCE ); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe( wVirtualCE ); + UInt32 status; + + WMR_PRINT(READ, "[FIL:LOG] h2fmiReadSinglePageMaxECC()\n"); + + AND_FIL_STAT(stFILStatistics.ddwReadMaxECCCallCnt++); + + WMR_PREPARE_READ_BUFFER(pabDataBuf, fmi->bytes_per_page); + + h2fmi_choose_aes(useWhitening, FALSE32, pabDataBuf, fmi, &dwPpn); + + status = h2fmi_read_page(fmi, + ce, + dwPpn, + pabDataBuf, + (UInt8*)g_pScratchBuf, + NULL, + NULL); + + switch (status) + { + case _kIOPFMI_STATUS_SUCCESS: + nRet = FIL_SUCCESS; + break; + case _kIOPFMI_STATUS_FUSED: + case _kIOPFMI_STATUS_AT_LEAST_ONE_UECC: + case _kIOPFMI_STATUS_NOT_ALL_CLEAN: + nRet = FIL_U_ECC_ERROR; + break; + case _kIOPFMI_STATUS_BLANK: + nRet = FIL_SUCCESS_CLEAN; + break; + default: + nRet = FIL_CRITICAL_ERROR; + break; + } + + WMR_COMPLETE_READ_BUFFER(pabDataBuf, fmi->bytes_per_page); + + return nRet; +} + +void h2fmiCalcCurrentTimings() +{ +/* + h2fmi_calc_bus_timings(......); + + h2fmi_calc_bus_timings(fmi, + stDEVInfo[wDevIdx].wReadCycleTime, + stDEVInfo[wDevIdx].wReadSetupTime, + stDEVInfo[wDevIdx].wReadHoldTime, + stDEVInfo[wDevIdx].wWriteCycleTime, + stDEVInfo[wDevIdx].wWriteSetupTime, + stDEVInfo[wDevIdx].wWriteHoldTime) + */ +} + +void h2fmiSetWhiteningState(BOOL32 enable) +{ + useWhitening = enable; +} + +void h2fmiSetWhiteningMetadataState(BOOL32 enable) +{ + useWhiteningMetadata = enable; +} + +Int32 h2fmiPrintParameters(void){ + + h2fmi_t *iter[] = {&g_fmi0, &g_fmi1, NULL}; + h2fmi_ppn_device_params_t *params; + int i; + Int32 err = 0; + + for(i=0; iter[i] != NULL; i++){ + if (iter[i]->num_of_ce && iter[i]->is_ppn){ + + params = &(iter[i]->ppn->device_params); + + _WMR_PRINT("Channel: %d\n",i); + DUMP_VAR(params->caus_per_channel); + DUMP_VAR(params->cau_bits); + DUMP_VAR(params->blocks_per_cau); + DUMP_VAR(params->block_bits); + DUMP_VAR(params->pages_per_block); + DUMP_VAR(params->pages_per_block_slc); + DUMP_VAR(params->page_address_bits); + DUMP_VAR(params->address_bits_bits_per_cell); + DUMP_VAR(params->default_bits_per_cell); + DUMP_VAR(params->page_size); + DUMP_VAR(params->dies_per_channel); + DUMP_VAR(params->block_pairing_scheme); + DUMP_VAR(params->bytes_per_row_address); + + DUMP_VAR(params->tRC); + DUMP_VAR(params->tREA); + DUMP_VAR(params->tREH); + DUMP_VAR(params->tRHOH); + DUMP_VAR(params->tRHZ); + DUMP_VAR(params->tRLOH); + DUMP_VAR(params->tRP); + DUMP_VAR(params->tWC); + DUMP_VAR(params->tWH); + DUMP_VAR(params->tWP); + + DUMP_VAR(params->read_queue_size); + DUMP_VAR(params->program_queue_size); + DUMP_VAR(params->erase_queue_size); + DUMP_VAR(params->prep_function_buffer_size); + + DUMP_VAR(params->tRST_ms); + DUMP_VAR(params->tPURST_ms); + DUMP_VAR(params->tSCE_ms); + DUMP_VAR(params->tCERDY_us); + + DUMP_VAR(params->cau_per_channel2); + DUMP_VAR(params->dies_per_channel2); + DUMP_VAR(params->ddr_tRC); + DUMP_VAR(params->ddr_tREH); + DUMP_VAR(params->ddr_tRP); + DUMP_VAR(params->tDQSL_ps); + DUMP_VAR(params->tDQSH_ps); + DUMP_VAR(params->tDSC_ps); + DUMP_VAR(params->tDQSRE_ps); + DUMP_VAR(params->tDQSQ_ps); + DUMP_VAR(params->tDVW_ps); + DUMP_VAR(params->max_interface_speed); + } + } + return err; +} + + +// ============================================================================= +// non-readonly public interface function definitions (not normally +// enabled in iBoot) +// ============================================================================= +#if (!H2FMI_READONLY) +Int32 h2fmiWriteMultiplePages(UInt32* padwPpn, + UInt8* pabDataBuf, + UInt8* pabMetaBuf, + UInt16 wNumOfPagesToWrite, + BOOL32 boolAligned, + BOOL32 boolCorrectBank, + UInt16* pwFailingCE, + BOOL32 bDisableWhitening, + UInt32* pwFailingPageNum) +{ + UInt16 wIdx, wBankIdx, wVirtualCEIdx; + Int32 errStatus = FIL_SUCCESS; + + WMR_PRINT(WRITE, "[FIL:LOG] h2fmiWriteMultiplePages()\n"); + + AND_FIL_STAT(stFILStatistics.ddwWriteMultipleCallCnt++); + + // It is assumed by the caller that WriteMultiple will operate on a multiple of + // bankCount and the controller will write to a bank on each CE before writing + // to the second bank on the first CE. + // Note that this swizzling is meant to optimize the overlap case, so the + // loop (performed via singles) below is a bit redundant + for (wIdx = 0; wIdx < wNumOfPagesToWrite; wIdx += _GetNumOfBanks()) + { + for (wBankIdx = 0; wBankIdx < _GetBanksPerCS(); wBankIdx++) + { + for (wVirtualCEIdx = 0; wVirtualCEIdx < _GetNumOfCS(); wVirtualCEIdx++) + { + const UInt16 wAddrIdx = wIdx + (wBankIdx * _GetNumOfCS()) + wVirtualCEIdx; + const h2fmi_t *fmi = h2fmiTranslateVirtualCEToBus(wVirtualCEIdx); + UInt8* tmpDataBuf = pabDataBuf + (wAddrIdx * _GetBytesPerPageMain()); + UInt8* tmpMetaBuf = pabMetaBuf + (wAddrIdx * fmi->total_bytes_per_meta); + + errStatus = h2fmiWriteSinglePage(wVirtualCEIdx, + padwPpn[wBankIdx * _GetNumOfCS() + wVirtualCEIdx] + (wIdx / _GetNumOfBanks()), + tmpDataBuf, + tmpMetaBuf, + bDisableWhitening); + + if (FIL_SUCCESS != errStatus) + { + if (pwFailingCE) + { + *pwFailingCE = wVirtualCEIdx; + } + if (pwFailingPageNum) + { + *pwFailingPageNum = padwPpn[wBankIdx * _GetNumOfCS() + wVirtualCEIdx] + (wIdx / _GetNumOfBanks()); + } + return errStatus; + } + } + } + } + + return errStatus; +} + +Int32 h2fmiWriteScatteredPages(UInt16 *pawBanks, + UInt32 *padwPpn, + UInt8 *pabDataBuf, + UInt8 *pabMetaBuf, + UInt16 wNumOfPagesToWrite, + UInt16 *pawFailingCE, + BOOL32 bDisableWhitening, + UInt32 *pwFailingPageNum) +{ + UInt32 i; + Int32 ret = FIL_SUCCESS; + + for (i = 0; i < wNumOfPagesToWrite; i++) + { + const UInt16 bank = pawBanks[i]; + const UInt32 page = padwPpn[i]; + const h2fmi_t *fmi = h2fmiTranslateVirtualCEToBus(bank); + UInt8 *dataPtr = pabDataBuf + (i * _GetBytesPerPageMain()); + UInt8 *metaPtr = pabMetaBuf + (i * fmi->total_bytes_per_meta); + + ret = h2fmiWriteSinglePage(bank, + page, + dataPtr, + metaPtr, + bDisableWhitening); + if (ret != FIL_SUCCESS) + { + if (pawFailingCE) + { + *pawFailingCE = bank; + } + if (pwFailingPageNum) + { + *pwFailingPageNum = page; + } + return ret; + } + } + + return ret; +} + + +Int32 h2fmiWriteSinglePage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabDataBuf, + UInt8* pabMetaBuf, + BOOL32 bDisableWhitening) +{ + UInt8 *pabMetaBounceBuffer = (UInt8*) g_pScratchBuf; + Int32 result = FIL_SUCCESS; + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus( wVirtualCE ); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe( wVirtualCE ); + BOOL32 status_failed = FALSE32; + const UInt32 bytes_per_page = fmi->sectors_per_page * H2FMI_BYTES_PER_SECTOR; + + WMR_PRINT(WRITE, "[FIL:LOG] h2fmiWriteSinglePage(%d, 0x%06X, ...)\n", wVirtualCE, dwPpn); + + AND_FIL_STAT(stFILStatistics.ddwPagesWrittenCnt++); + AND_FIL_STAT(stFILStatistics.ddwWriteSingleCallCnt++); + + WMR_ASSERT(WMR_CHECK_BUFFER(pabDataBuf, fmi->bytes_per_page)); + + // Don't touch the caller's buffer + WMR_MEMCPY(pabMetaBounceBuffer, pabMetaBuf, fmi->valid_bytes_per_meta); + + if (useWhiteningMetadata) + { + h2fmi_encrypt_metadata(dwPpn, pabMetaBounceBuffer); + } + + h2fmi_choose_aes((useWhitening && !bDisableWhitening), TRUE32, pabDataBuf, fmi, &dwPpn); + + WMR_PREPARE_WRITE_BUFFER(pabDataBuf, bytes_per_page); + WMR_PREPARE_WRITE_BUFFER(pabMetaBounceBuffer, fmi->valid_bytes_per_meta); + + + if (!h2fmi_write_page(fmi, + ce, + dwPpn, + pabDataBuf, + pabMetaBounceBuffer, + &status_failed)) + { + if (status_failed) + { + result = FIL_WRITE_FAIL_ERROR; + } + else + { + result = FIL_CRITICAL_ERROR; + } + } + + return result; +} + +Int32 h2fmiWriteSinglePageMaxECC(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabDataBuf) +{ + const h2fmi_t *fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + UInt8 *pabMaxECCMeta = (UInt8*) g_pScratchBuf; + AND_FIL_STAT(stFILStatistics.ddwWriteMaxECCCallCnt++); + + // g_pScratchBuf is re-used for metadata whitening, but we dont really care + // what this data ends up being + WMR_MEMSET(pabMaxECCMeta, 0xA5, fmi->total_bytes_per_meta); + + return h2fmiWriteSinglePage(wVirtualCE, dwPpn,pabDataBuf, pabMaxECCMeta, FALSE32); +} + +#endif // !H2FMI_READONLY + +// ============================================================================= +// non-readonly public interface function definitions that must be available +// to support NAND-backed NVRAM implementation +// ============================================================================= + +#if (!H2FMI_READONLY || AND_SUPPORT_NVRAM) + +Int32 h2fmiWriteBootpage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabData) +{ + Int32 result = FIL_SUCCESS; + UInt32 status; + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus( wVirtualCE ); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe( wVirtualCE ); + + WMR_ASSERT(WMR_CHECK_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE)); + WMR_PREPARE_WRITE_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE); + + status = h2fmi_write_bootpage(fmi, ce, dwPpn, pabData); + switch (status) + { + case _kIOPFMI_STATUS_SUCCESS: + result = FIL_SUCCESS; + break; + + case _kIOPFMI_STATUS_PGM_ERROR: + WMR_PRINT(ERROR, "WSF ce %d page 0x%08x\n", (UInt32) wVirtualCE, dwPpn); + result = FIL_WRITE_FAIL_ERROR; + break; + + default: + result = FIL_CRITICAL_ERROR; + break; + } + + return result; +} + +Int32 h2fmiEraseSingleBlock(UInt16 wVirtualCE, + UInt32 wPbn) +{ + Int32 result = FIL_SUCCESS; + BOOL32 status_failed = FALSE32; + + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus( wVirtualCE ); + UInt16 ce = (UInt16)h2fmiTranslateVirtualCEToCe( wVirtualCE ); + + WMR_PRINT(ERASE, "[FIL:LOG] h2fmiEraseSingleBlock()\n"); + + AND_FIL_STAT( stFILStatistics.ddwSingleEraseCallCnt++); + AND_FIL_STAT( stFILStatistics.ddwBlocksErasedCnt++); + + fmi->failureDetails.wCEStatusArray = &fmi->failureDetails.wSingleCEStatus; + + if (!h2fmi_erase_blocks(fmi, 1, &ce, &wPbn, &status_failed)) + { + if (status_failed) + { + WMR_PRINT(ERROR, "ESF ce %d block %d\n", (UInt32) wVirtualCE, wPbn); + AND_FIL_STAT( stFILStatistics.ddwEraseNANDErrCnt++); + result = FIL_WRITE_FAIL_ERROR; + } + else + { + result = FIL_CRITICAL_ERROR; + } + } + + return result; +} + +#endif // (!H2FMI_READONLY || AND_SUPPORT_NVRAM) + +// ============================================================================= +// private implementation function definitions +// ============================================================================= + +static BOOL32 h2fmi_init_minimal(h2fmi_t* fmi, + UInt32 interface) +{ + BOOL32 result = TRUE32; + + // only interface numbers 0 and 1 are valid + if ((interface != 0) && (interface != 1)) + { + h2fmi_fail(result); + } + else + { +#if SUPPORT_PPN + if (NULL != fmi->ppn) + { + WMR_FREE(fmi->ppn, sizeof(*fmi->ppn)); + } +#endif + WMR_MEMSET(fmi, 0, sizeof(*fmi)); + // record which interface is being used + fmi->regs = (interface == 0) ? FMI0 : FMI1; + fmi->bus_id = interface; +#if SUPPORT_TOGGLE_NAND + fmi->is_toggle_system = FALSE32; + fmi->is_toggle = FALSE32; +#endif + + // "get the clock rolling" for the dedicated HCLK clock domain + WMR_CLOCK_GATE(h2fmi_get_gate(fmi), TRUE32); + + // configure safe initial bus timings + h2fmi_set_initial_timings(fmi); + fmi->activeCe = ~0; + + // reset the FMI block (not NAND) + h2fmi_reset(fmi); + + h2fmi_init_sys(fmi); + } + + return result; +} + +static void h2fmi_set_initial_timings(h2fmi_t* fmi) +{ + fmi->if_ctrl = H2FMI_IF_CTRL_LOW_POWER; + fmi->if_ctrl_normal = fmi->if_ctrl; + +#if SUPPORT_TOGGLE_NAND + fmi->dqs_ctrl = FMC_DQS_TIMING_CTRL__DEFAULT_VAL; + fmi->timing_ctrl_1 = (FMC_TOGGLE_CTRL_1_DDR_RD_PRE_TIME(FMC_TOGGLE_CTRL_1__TIMING_MAX_CLOCKS) | + FMC_TOGGLE_CTRL_1_DDR_RD_POST_TIME(FMC_TOGGLE_CTRL_1__TIMING_MAX_CLOCKS) | + FMC_TOGGLE_CTRL_1_DDR_WR_PRE_TIME(FMC_TOGGLE_CTRL_1__TIMING_MAX_CLOCKS) | + FMC_TOGGLE_CTRL_1_DDR_WR_POST_TIME(FMC_TOGGLE_CTRL_1__TIMING_MAX_CLOCKS)); + fmi->timing_ctrl_2 = (FMC_TOGGLE_CTRL_2_CE_SETUP_TIME(FMC_TOGGLE_CTRL_2__TIMING_MAX_CLOCKS) | + FMC_TOGGLE_CTRL_2_CE_HOLD_TIME(FMC_TOGGLE_CTRL_2__TIMING_MAX_CLOCKS) | + FMC_TOGGLE_CTRL_2_NAND_TIMING_ADL(FMC_TOGGLE_CTRL_2__TIMING_MAX_CLOCKS) | + FMC_TOGGLE_CTRL_2_NAND_TIMING_WHR(FMC_TOGGLE_CTRL_2__TIMING_MAX_CLOCKS)); + fmi->toggle_if_ctrl = (FMC_IF_CTRL__REB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS)); +#endif + + restoreTimingRegs(fmi); +} + +static void +h2fmi_init_raw_state(h2fmi_t* fmi, + const NandInfo* nandInfo, + NandRequiredTimings *requiredTiming) +{ + fmi->blocks_per_ce = nandInfo->geometry->blocksPerCS; + fmi->banks_per_ce = 1; // updated later by SetStruct + fmi->sectors_per_page = nandInfo->geometry->dataBytesPerPage / H2FMI_BYTES_PER_SECTOR; + fmi->pages_per_block = nandInfo->geometry->pagesPerBlock; + fmi->bytes_per_spare = nandInfo->geometry->spareBytesPerPage; + fmi->valid_bytes_per_meta = nandInfo->format->validMetaPerLogicalPage; + fmi->total_bytes_per_meta = nandInfo->format->metaPerLogicalPage; + fmi->bytes_per_page = nandInfo->geometry->dataBytesPerPage; + fmi->dies_per_cs = nandInfo->geometry->diesPerCS; + fmi->clock_speed_khz = WMR_BUS_FREQ_HZ() / 1000; + if (nandInfo->format->logicalPageSize == 0) + { + fmi->logical_page_size = fmi->bytes_per_page; + } + else + { + fmi->logical_page_size = nandInfo->format->logicalPageSize; + } + + WMR_MEMSET(requiredTiming, 0, sizeof(*requiredTiming)); + + requiredTiming->clock_hz = WMR_BUS_FREQ_HZ(); + + requiredTiming->soc_tx_prop_ns = FMI_TX_PROP_DELAY_NS; + requiredTiming->soc_rx_prop_ns = FMI_RX_PROP_DELAY_NS; + + requiredTiming->soc_to_nand_rise_ns = nandInfo->boardInfo->socToNandRiseNanosecs; + requiredTiming->soc_to_nand_fall_ns = nandInfo->boardInfo->socToNandFallNanosecs; + requiredTiming->nand_to_soc_rise_ns = nandInfo->boardInfo->nandToSocRiseNanosecs; + requiredTiming->nand_to_soc_fall_ns = nandInfo->boardInfo->nandToSocFallNanosecs; + + requiredTiming->tRC_ns = nandInfo->configTiming->readCycleNanosecs; + requiredTiming->tRP_ns = nandInfo->configTiming->readSetupNanosecs; + requiredTiming->tREH_ns = nandInfo->configTiming->readHoldNanosecs; + requiredTiming->tREA_ns = nandInfo->configTiming->readDelayNanosecs; + requiredTiming->tRHOH_ns = nandInfo->configTiming->readValidNanosecs; + requiredTiming->tRLOH_ns = 0; + + requiredTiming->tWC_ns = nandInfo->configTiming->writeCycleNanosecs; + requiredTiming->tWP_ns = nandInfo->configTiming->writeSetupNanosecs; + requiredTiming->tWH_ns = nandInfo->configTiming->writeHoldNanosecs; + + // Cache ECC configuration + fmi->correctable_bits = h2fmi_calculate_ecc_bits(fmi); + if (fmi->correctable_bits > 8) + { + fmi->refresh_threshold_bits = (fmi->correctable_bits * 8) / 10; + } + else + { + fmi->refresh_threshold_bits = 8; + } + + fmi->fmi_config_reg = h2fmi_calculate_fmi_config(fmi); +#if FMI_VERSION > 0 + fmi->fmi_data_size_reg = h2fmi_calculate_fmi_data_size(fmi); +#endif /* FMI_VERSION > 0*/ + +#if FMISS_ENABLED + fmiss_raw_init_sequences(fmi); +#endif /* FMISS_ENABLED */ +} + +void +h2fmiRegisterCurrentTransaction(UInt64 ddwLba, UInt32 dwNum, void* pDest) +{ + fmi_current_lba_base = ddwLba; + fmi_current_dest_ptr = (UInt8*)pDest; + fmi_current_num_blks = dwNum; + WMR_PRINT(CRYPTO, "Registered %lld %d %p\n", ddwLba, dwNum, pDest); +} + +static void h2fmi_choose_aes(BOOL32 enable, BOOL32 encrypt, void* destPtr, h2fmi_t* fmi, UInt32* seeds) +{ + const UInt8* endPtr = fmi_current_dest_ptr + (fmi_current_num_blks * fmi->bytes_per_page); + const UInt8* pabDestPtr = (UInt8*)destPtr; + if (!enable) + { + fmi->current_aes_cxt = NULL; + } + else if (IS_ADDRESS_IN_RANGE(pabDestPtr, fmi_current_dest_ptr, endPtr)) + { + WMR_PRINT(CRYPTO, "default enc dest: 0x%08x range: 0x%08x - 0x%08x\n", pabDestPtr, fmi_current_dest_ptr, endPtr); + h2fmi_setup_default_encryption(encrypt, destPtr, fmi); + } + else + { + WMR_PRINT(CRYPTO, "dest: 0x%08x range: 0x%08x - 0x%08x\n", pabDestPtr, fmi_current_dest_ptr, endPtr); + h2fmi_setup_whitening(encrypt, fmi, seeds); + } +} + +static void +h2fmi_setup_default_encryption(BOOL32 encrypt, void* destPtr, h2fmi_t* fmi) +{ + + fmi->aes_cxt.chunk_size = fmi->logical_page_size; + fmi->aes_cxt.iv_func_arg = destPtr; + fmi->aes_cxt.iv_func = h2fmi_calc_default_iv; + fmi->aes_cxt.keying = (AES_KEY_TYPE_USER | AES_KEY_SIZE_128); + fmi->aes_cxt.key = nand_default_key; + fmi->aes_cxt.command = encrypt ? AES_CMD_ENC : AES_CMD_DEC; + + fmi->current_aes_iv_array = NULL; + + fmi->current_aes_cxt = &fmi->aes_cxt; + +} + +#define LFSR32(seed) ((seed) & 1) ? ((seed) >> 1) ^ 0x80000061 : ((seed) >> 1) +void h2fmi_calc_default_iv(void* arg, UInt32 chunk_index, void* iv_buffer) +{ + UInt32* iv = (UInt32*)iv_buffer; + UInt8* dest_addr = (UInt8*)arg; + const UInt32 offset = (dest_addr - fmi_current_dest_ptr) / (stDeviceInfo.wSectorsPerPage * H2FMI_BYTES_PER_SECTOR); + const UInt32 current_lba = fmi_current_lba_base + offset; + + WMR_PRINT(CRYPTO, "Decrypting lba %d\n", current_lba); + + iv[0] = LFSR32(current_lba); + iv[1] = LFSR32(iv[0]); + iv[2] = LFSR32(iv[1]); + iv[3] = LFSR32(iv[2]); +} + +static void +h2fmi_setup_whitening(BOOL32 encrypt, h2fmi_t* fmi, UInt32* seeds) +{ + + fmi->aes_cxt.chunk_size = fmi->logical_page_size; + fmi->aes_cxt.iv_func_arg = fmi; + fmi->aes_cxt.iv_func = h2fmi_aes_iv; + fmi->aes_cxt.keying = (AES_KEY_TYPE_USER | AES_KEY_SIZE_128); + fmi->aes_cxt.key = nand_whitening_key; + fmi->aes_cxt.command = encrypt ? AES_CMD_ENC : AES_CMD_DEC; + + fmi->current_aes_iv_array = NULL; + fmi->iv_seed_array = seeds; + + fmi->current_aes_cxt = &fmi->aes_cxt; + +} + +static UInt32 +h2fmi_generate_meta_content(void) +{ + UInt32 idx; + for (idx = 0; idx < METADATA_ITERATIONS_TABLE; idx++) + { + metaContent = (METADATA_MULTIPLY * metaContent) + METADATA_INCREMENT; + } + return metaContent; +} + +static void +h2fmi_generate_meta_table(void) +{ + UInt32 i; + metaContent = 0x50F4546A; // randomly chosen by a fair roll of ssh-keygen + + for (i = 0; i < METADATA_LOOKUP_SIZE; i++) + { + metaLookupTable[i] = h2fmi_generate_meta_content(); + } +} + +static void +h2fmi_encrypt_metadata(UInt32 page, UInt8* pabMetaBuf) +{ + UInt8 i; + for (i = 0; i < METADATA_ITERATIONS_CRYPT; i++) + { + ((UInt32*)pabMetaBuf)[i] ^= metaLookupTable[(page + i) % METADATA_LOOKUP_SIZE]; + } +} + +static void +h2fmi_decrypt_metadata(UInt32 page, UInt8* pabMetaBuf) +{ + UInt8 i; + for (i = 0; i < METADATA_ITERATIONS_CRYPT; i++) + { + ((UInt32*)pabMetaBuf)[i] ^= metaLookupTable[(page + i) % METADATA_LOOKUP_SIZE]; + } +} + +#if (defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) +static BOOL32 h2fmiGetPPNUID(PpnUIDReadRequest* ppnUIDRead, UInt32* pdwStructSize, BOOL32* setPattern, BOOL32* toBreak) +{ + BOOL32 boolRes = FALSE32; + if ((ppnUIDRead==NULL) || (ppnUIDRead->buf==NULL) || (pdwStructSize==NULL) || (*pdwStructSize < sizeof(PpnUIDReadRequest))) + { + *toBreak = TRUE32; + return FALSE32; + } + else if((ppnUIDRead->ce < _GetNumOfCS()) && (ppnUIDRead->die < _GetDiesPerCS())) + { + UInt8 phyCE = h2fmiTranslateVirtualCEToCe(ppnUIDRead->ce); + h2fmi_t *whichFmi = h2fmiTranslateVirtualCEToBus(ppnUIDRead->ce); + + if(whichFmi) + { + boolRes = h2fmi_ppn_get_uid(whichFmi, phyCE, ppnUIDRead->die, ppnUIDRead->buf); + } + *pdwStructSize = sizeof(PpnUIDReadRequest); + } + else + { + *setPattern = TRUE32; + } + return boolRes; +} + +static BOOL32 h2fmiGetRAWUID(GenericReadRequest* genericRead, UInt32* pdwStructSize, BOOL32* setPattern, BOOL32* toBreak) +{ + BOOL32 boolRes = FALSE32; + if ((genericRead==NULL) || (genericRead->buf==NULL) || (pdwStructSize==NULL) || (*pdwStructSize < sizeof(GenericReadRequest))) + { + *toBreak = TRUE32; + return FALSE32; + } + if (genericRead->ce >= _GetNumOfCS()) + { + *setPattern = TRUE32; + } + else + { + UInt8 phyCE = h2fmiTranslateVirtualCEToCe(genericRead->ce); + h2fmi_t *whichFmi = h2fmiTranslateVirtualCEToBus(genericRead->ce); + boolRes = h2fmiGenericNandReadSequence(whichFmi, phyCE, genericRead); + } + *pdwStructSize = sizeof(GenericReadRequest); + return boolRes; +} +#endif //(defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) + +void h2fmi_ppn_all_channel_power_state_transition(UInt32 ps_tran) +{ + if (g_fmi0.num_of_ce) + { + h2fmi_ppn_set_channel_power_state(&g_fmi0, ps_tran); + } + if (g_fmi1.num_of_ce) + { + h2fmi_ppn_set_channel_power_state(&g_fmi1, ps_tran); + } +} + + +#if SUPPORT_TOGGLE_NAND +void transitionWorldFromDDR(UInt32 powerstate_to) +{ + WMR_ASSERT(g_fmi0.is_toggle || (0 == g_fmi0.num_of_ce)); + WMR_ASSERT(g_fmi1.is_toggle || (0 == g_fmi1.num_of_ce)); + WMR_ASSERT(g_fmi0.is_toggle_system || (0 == g_fmi0.num_of_ce)); + WMR_ASSERT(g_fmi1.is_toggle_system || (0 == g_fmi1.num_of_ce)); + + h2fmi_ppn_all_channel_power_state_transition(PPN_PS_TRANS_DDR_TO_LOW_POWER); + + if (0 != g_fmi0.num_of_ce) + { + g_fmi0.is_toggle = FALSE32; + h2fmi_reset(&g_fmi0); + } + if (0 != g_fmi1.num_of_ce) + { + g_fmi1.is_toggle = FALSE32; + h2fmi_reset(&g_fmi1); + } + + if (powerstate_to == PPN_FEATURE__POWER_STATE__ASYNC) + { + h2fmi_ppn_all_channel_power_state_transition(PPN_PS_TRANS_LOW_POWER_TO_ASYNC);; + } + +#if H2FMI_PPN_VERIFY_SET_FEATURES + if(g_fmi0.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi0); + } + if(g_fmi1.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi1); + } +#endif // H2FMI_PPN_VERIFY_SET_FEATURES +} + +void transitionWorldToDDR(UInt32 powerstate_from) +{ + WMR_ASSERT(!g_fmi0.is_toggle || (0 == g_fmi0.num_of_ce)); + WMR_ASSERT(!g_fmi1.is_toggle || (0 == g_fmi1.num_of_ce)); + WMR_ASSERT(g_fmi0.is_toggle_system || (0 == g_fmi0.num_of_ce)); + WMR_ASSERT(g_fmi1.is_toggle_system || (0 == g_fmi1.num_of_ce)); + + if (powerstate_from == PPN_FEATURE__POWER_STATE__ASYNC) + { + h2fmi_ppn_all_channel_power_state_transition(PPN_PS_TRANS_ASYNC_TO_LOW_POWER); + } + + h2fmi_ppn_all_channel_power_state_transition(PPN_PS_TRANS_LOW_POWER_TO_DDR); + + if (0 != g_fmi0.num_of_ce) + { + g_fmi0.is_toggle = TRUE32; + h2fmi_reset(&g_fmi0); + } + if (0 != g_fmi1.num_of_ce) + { + g_fmi1.is_toggle = TRUE32; + h2fmi_reset(&g_fmi1); + } + +#if H2FMI_PPN_VERIFY_SET_FEATURES + if(g_fmi0.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi0); + } + if(g_fmi1.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi1); + } +#endif // H2FMI_PPN_VERIFY_SET_FEATURES +} +#endif + + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi.h b/drivers/apple/h2fmi/H2fmi.h new file mode 100644 index 0000000..b75f290 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi.h @@ -0,0 +1,69 @@ +// ***************************************************************************** +// +// File: H2fmi.h +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#ifndef _H2FMI_H_ +#define _H2FMI_H_ + +#include + +// ============================================================================= +// public interface function declarations +// ============================================================================= + +Int32 h2fmiInit(void); +void h2fmiPrintConfig(void); +BOOL32 h2fmi_ppn_fil_init(void); +void h2fmi_ppn_recover_nand(void); //PPN + +void h2fmiSetDeviceInfo(UInt32 dwParamType, UInt32 dwVal); +UInt32 h2fmiGetDeviceInfo(UInt32 dwParamType); +void h2fmiSetWhiteningState(BOOL32 enable); +void h2fmiSetWhiteningMetadataState(BOOL32 enable); + +void h2fmiReset(void); + +Int32 h2fmiReadNoECC(UInt16 wBank, UInt32 dwPpn, UInt8* pabDataBuf, UInt8* pabSpareBuf); + +Int32 h2fmiReadSequentialPages(UInt32* padwPpn, UInt8* pabDataBuf, UInt8* pabMetaBuf, UInt16 wNumOfPagesToRead, UInt8* pbMaxCorrectedBits, UInt8* pdwaSectorStats, BOOL32 bDisableWhitening); +Int32 h2fmiReadScatteredPages(UInt16* pawBanks, UInt32* padwPpn, UInt8* pabDataBuf, UInt8* pabMetaBuf, UInt16 wNumOfPagesToRead, UInt8* pbMaxCorrectedBits, UInt8* pdwaSectorStats, BOOL32 bDisableWhitening); +Int32 h2fmiReadSinglePage(UInt16 wBank, UInt32 dwPpn, UInt8* pabDataBuf, UInt8* pabMetaBuf, UInt8* pbMaxCorrectedBits, UInt8* pdwaSectorStats, BOOL32 bDisableWhitening); +Int32 h2fmiReadSinglePageMaxECC(UInt16 wBank, UInt32 dwPpn, UInt8* pabDataBuf); +Int32 h2fmiPrintParameters(void); + +Int32 h2fmiWriteMultiplePages(UInt32* padwPpn, UInt8* pabDataBuf, UInt8* pabMetaBuf, UInt16 wNumOfPagesToWrite, BOOL32 boolAligned, BOOL32 boolCorrectBank, UInt16* pwFailingCE, BOOL32 bDisableWhitening, UInt32 *pwFailingPageNum); +Int32 h2fmiWriteScatteredPages(UInt16 *pawBanks, UInt32 *padwPpn, UInt8 *pabDataBuf, UInt8 *pabMetaBuf, UInt16 wNumOfPagesToWrite, UInt16 *pawFailingCE, BOOL32 bDisableWhitening, UInt32 *pwFailingPageNum); +Int32 h2fmiWriteSinglePage(UInt16 wBank, UInt32 dwPpn, UInt8* pabDataBuf, UInt8* pabMetaBuf, BOOL32 bDisableWhitening); +Int32 h2fmiWriteSinglePageMaxECC(UInt16 wBank, UInt32 dwPpn, UInt8* pabDataBuf); + +Int32 h2fmiEraseSingleBlock(UInt16 wBank, UInt32 wPbn); +void h2fmiCalcCurrentTimings(void); +BOOL32 h2fmiGetStruct(UInt32 dwStructType, void* pvoidStructBuffer, UInt32* pdwStructSize); +BOOL32 h2fmiSetStruct(UInt32 dwStructType, void* pvoidStructBuffer, UInt32 pdwStructSize); +void h2fmiRegisterCurrentTransaction(UInt64 ddwLba, UInt32 dwNum, void* pDest); + +Int32 h2fmiWriteBootpage(UInt16 wCS, UInt32 dwPpn, UInt8 *pabData); +Int32 h2fmiReadBootpage(UInt16 wCS, UInt32 dwPpn, UInt8* pabData); +Int32 h2fmiReadBootpagePio(UInt16 wCS, UInt32 dwPpn, UInt8* pabData); + + +#endif // _H2FMI_H_ + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_8920regs.h b/drivers/apple/h2fmi/H2fmi_8920regs.h new file mode 100644 index 0000000..e46f6d0 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_8920regs.h @@ -0,0 +1,502 @@ +// ***************************************************************************** +// +// File: H2fmi_regs.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position +// +// - consider adding definitions for extracting value from register position +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "WMRFeatures.h" +#if defined(H2FMI_EFI) && H2FMI_EFI +#include "SoC.h" +#else +#include +#endif + +#include + +#ifndef _H2FMI_8920REGS_H_ +#define _H2FMI_8922REGS_H_ +// ============================================================================= +// register bases and offsets +// ============================================================================= + +#define FMI0 ((UInt32*)FMI0_BASE_ADDR) +#define FMI1 ((UInt32*)FMI1_BASE_ADDR) + +#define FMI_OFFSET (0x000) +#define FMC_OFFSET (0x400) +#define ECC_OFFSET (0x800) + +#define FMC0 ((volatile UInt32*)((UInt32)FMI0 + FMC_OFFSET)) +#define FMC1 ((volatile UInt32*)((UInt32)FMI1 + FMC_OFFSET)) + +#define FMI_BA(offset) ((UInt32)(FMI_OFFSET + offset)) +#define FMC_BA(offset) ((UInt32)(FMC_OFFSET + offset)) +#define ECC_BA(offset) ((UInt32)(ECC_OFFSET + offset)) + +#define FMI_CONFIG FMI_BA(0x00) +#define FMI_CONTROL FMI_BA(0x04) +#define FMI_STATUS FMI_BA(0x08) +#define FMI_INT_PEND FMI_BA(0x0C) +#define FMI_INT_EN FMI_BA(0x10) +#define FMI_DATA_BUF FMI_BA(0x14) +#define FMI_META_FIFO FMI_BA(0x18) +#define FMI_DEBUG0 FMI_BA(0x1C) +#define FMI_DEBUG1 FMI_BA(0x20) +#define FMI_DEBUG2 FMI_BA(0x24) + +#define FMC_ON FMC_BA(0x00) +#define FMC_VER FMC_BA(0x04) +#define FMC_IF_CTRL FMC_BA(0x08) +#define FMC_CE_CTRL FMC_BA(0x0C) +#define FMC_RW_CTRL FMC_BA(0x10) +#define FMC_CMD FMC_BA(0x14) +#define FMC_ADDR0 FMC_BA(0x18) +#define FMC_ADDR1 FMC_BA(0x1C) +#define FMC_ADDRNUM FMC_BA(0x20) +#define FMC_DATANUM FMC_BA(0x24) +#define FMC_UNDEF0 FMC_BA(0x28) +#define FMC_UNDEF1 FMC_BA(0x2C) +#define FMC_TO_CTRL FMC_BA(0x30) +#define FMC_TO_CNT FMC_BA(0x34) +#define FMC_UNDEF2 FMC_BA(0x38) +#define FMC_UNDEF3 FMC_BA(0x3C) +#define FMC_INTMASK FMC_BA(0x40) +#define FMC_STATUS FMC_BA(0x44) +#define FMC_NAND_STATUS FMC_BA(0x48) +#define FMC_RBB_CONFIG FMC_BA(0x4C) +#define FMC_LOCK0_L FMC_BA(0x50) +#define FMC_LOCK0_H FMC_BA(0x54) +#define FMC_LOCK1_L FMC_BA(0x58) +#define FMC_LOCK1_H FMC_BA(0x5C) +#define FMC_LOCK2_L FMC_BA(0x60) +#define FMC_LOCK2_H FMC_BA(0x64) +#define FMC_ALARMCMD FMC_BA(0x68) +#define FMC_REJECTCMD FMC_BA(0x6C) + +#define ECC_VERSION ECC_BA(0x00) +#define ECC_CON0 ECC_BA(0x04) +#define ECC_CON1 ECC_BA(0x08) +#define ECC_RESULT ECC_BA(0x0C) +#define ECC_PND ECC_BA(0x10) +#define ECC_MASK ECC_BA(0x14) +#define ECC_HISTORY ECC_BA(0x18) +#define ECC_CORE_SW_RESET ECC_BA(0x1C) +#define ECC_LOC0 ECC_BA(0x20) +#define ECC_LOC1 ECC_BA(0x24) +#define ECC_LOC2 ECC_BA(0x28) +#define ECC_LOC3 ECC_BA(0x2C) +#define ECC_LOC4 ECC_BA(0x30) +#define ECC_LOC5 ECC_BA(0x34) +#define ECC_LOC6 ECC_BA(0x38) +#define ECC_UNDEF0 ECC_BA(0x3C) +#define ECC_PARITY0 ECC_BA(0x40) +#define ECC_PARITY1 ECC_BA(0x44) +#define ECC_PARITY2 ECC_BA(0x48) +#define ECC_PARITY3 ECC_BA(0x4C) +#define ECC_PARITY4 ECC_BA(0x50) +#define ECC_PARITY5 ECC_BA(0x54) +#define ECC_PARITY6 ECC_BA(0x58) + +// ============================================================================= +// FMI_CONFIG bitfields +// ============================================================================= + +#define FMI_CONFIG__DMA_BURST(n) (((n) & 0x7) << 17) +#define FMI_CONFIG__LBA_MODE(v) (((v) & 0x3) << 15) +#define FMI_CONFIG__ECC_MODE(m) (((m) & 0x1) << 14) +#define FMI_CONFIG__META_PER_ENVELOPE(n) (((n) & 0x3F) << 8) +#define FMI_CONFIG__META_PER_PAGE(n) (((n) & 0x3F) << 2) +#define FMI_CONFIG__PAGE_SIZE(n) (((n) & 0x03) << 0) + +#define FMI_CONFIG__DMA_BURST__32_CYCLES FMI_CONFIG__DMA_BURST(5) +#define FMI_CONFIG__DMA_BURST__16_CYCLES FMI_CONFIG__DMA_BURST(4) +#define FMI_CONFIG__DMA_BURST__8_CYCLES FMI_CONFIG__DMA_BURST(3) +#define FMI_CONFIG__DMA_BURST__4_CYCLES FMI_CONFIG__DMA_BURST(2) +#define FMI_CONFIG__DMA_BURST__2_CYCLES FMI_CONFIG__DMA_BURST(1) +#define FMI_CONFIG__DMA_BURST__1_CYCLES FMI_CONFIG__DMA_BURST(0) + +#define FMI_CONFIG__LBA_MODE__NORMAL FMI_CONFIG__LBA_MODE(0) +#define FMI_CONFIG__LBA_MODE__BYPASS_ECC FMI_CONFIG__LBA_MODE(1) +#define FMI_CONFIG__LBA_MODE__LBA_TYPE_AB FMI_CONFIG__LBA_MODE(2) +#define FMI_CONFIG__LBA_MODE__LBA_TYPE_C FMI_CONFIG__LBA_MODE(3) + +#define FMI_CONFIG__ECC_MODE__16BIT FMI_CONFIG__ECC_MODE(1) +#define FMI_CONFIG__ECC_MODE__8BIT FMI_CONFIG__ECC_MODE(0) + +#define FMI_CONFIG__PAGE_SIZE__2K FMI_CONFIG__PAGE_SIZE(0) +#define FMI_CONFIG__PAGE_SIZE__4K FMI_CONFIG__PAGE_SIZE(1) +#define FMI_CONFIG__PAGE_SIZE__8K FMI_CONFIG__PAGE_SIZE(2) +#define FMI_CONFIG__PAGE_SIZE__512 FMI_CONFIG__PAGE_SIZE(3) + +// ============================================================================= +// FMI_CONTROL bitfields +// ============================================================================= + +#define FMI_CONTROL__MODE(m) (((m) & 0x3) << 1) +#define FMI_CONTROL__START_BIT (0x1UL << 0) + +#define FMI_CONTROL__MODE__IDLE FMI_CONTROL__MODE(0) +#define FMI_CONTROL__MODE__READ FMI_CONTROL__MODE(1) +#define FMI_CONTROL__MODE__WRITE FMI_CONTROL__MODE(2) +#define FMI_CONTROL__MODE__UNDEF FMI_CONTROL__MODE(3) + +// ============================================================================= +// FMI_STATUS bitfields +// ============================================================================= + +#define FMI_STATUS__FMC_ACTIVE (0x1UL << 3) +#define FMI_STATUS__ECC_ACTIVE (0x1UL << 2) +#define FMI_STATUS__DMA_ACTIVE (0x1UL << 1) +#define FMI_STATUS__BUS_ACTIVE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_PEND bitfields +// ============================================================================= + +#define FMI_INT_PEND__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_PEND__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_PEND__ECC_DONE (0x1UL << 19) +#define FMI_INT_PEND__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_PEND__FMC_READY_BUSY(n) (((n) & 0xFF) << 10) +#define FMI_INT_PEND__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_PEND__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_PEND__FMC_NSERR (0x1UL << 7) +#define FMI_INT_PEND__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_PEND__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_PEND__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_PEND__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_PEND__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_PEND__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_PEND__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_EN bitfields +// ============================================================================= + +#define FMI_INT_EN__ECC_INTERRUPT (0x1UL << 14) +#define FMI_INT_EN__ECC_READY_BUSY (0x1UL << 13) +#define FMI_INT_EN__ECC_DONE (0x1UL << 12) +#define FMI_INT_EN__FMC_INTERRUPT (0x1UL << 11) +#define FMI_INT_EN__FMC_READY_BUSY (0x1UL << 10) +#define FMI_INT_EN__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_EN__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_EN__FMC_NSERR (0x1UL << 7) +#define FMI_INT_EN__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_EN__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_EN__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_EN__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_EN__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_EN__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_EN__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_DEBUG0 bitfields +// ============================================================================= + +#define FMI_DEBUG0__DMA_BLOCK_COUNT(n) (((n) & 0x1F) << 24) +#define FMI_DEBUG0__DATA_TC_RECEIVED (0x1UL << 23) +#define FMI_DEBUG0__DATA_DMA_DONE (0x1UL << 22) +#define FMI_DEBUG0__DMA_DATA_RW_PTR(n) (((n) & 0x7F) << 15) +#define FMI_DEBUG0__META_BYTE_COUNT(n) (((n) & 0x3F) << 9) +#define FMI_DEBUG0__FMC_TASKS_PENDING(n) (((n) & 0x3) << 7) +#define FMI_DEBUG0__ECC_TASKS_PENDING(n) (((n) & 0x3) << 5) +#define FMI_DEBUG0__DMA_TASKS_PENDING(n) (((n) & 0x3) << 3) +#define FMI_DEBUG0__FMC_TARGET_BUFFER(b) (((b) & 0x1) << 2) +#define FMI_DEBUG0__ECC_TARGET_BUFFER(b) (((b) & 0x1) << 1) +#define FMI_DEBUG0__DMA_TARGET_BUFFER(b) (((b) & 0x1) << 0) + +// ============================================================================= +// FMI_DEBUG1 bitfields +// ============================================================================= + +#define FMI_DEBUG1__META_TC_RECEIVED (0x1UL << 28) +#define FMI_DEBUG1__NEXT_META_LOCATION(n) (((n) & 0x3F) << 22) +#define FMI_DEBUG1__FMC_PAGE_DONE (0x1UL << 21) +#define FMI_DEBUG1__FMC_BLOCK_COUNT(n) (((n) & 0x1F) << 16) +#define FMI_DEBUG1__META_FIFO_LEVEL(n) (((n) & 0x3F) << 10) +#define FMI_DEBUG1__META_FIFO_WRITE_PTR(n) (((n) & 0x1F) << 5) +#define FMI_DEBUG1__META_FIFO_READ_PTR(n) (((n) & 0x1F) << 0) + +// ============================================================================= +// FMI_DEBUG2 bitfields +// ============================================================================= + +#define FMI_DEBUG2__BUFFER_1_META_BYTES(n) (((n) & 0x3F) << 24) +#define FMI_DEBUG2__BUFFER_0_META_BYTES(n) (((n) & 0x3F) << 18) +#define FMI_DEBUG2__META_BYTES_REMAINING(n) (((n) & 0x3F) << 12) +#define FMI_DEBUG2__PAUSED_AHB_ADDRESS(n) (((n) & 0xFF) << 4) +#define FMI_DEBUG2__AHB_STATE(n) (((n) & 0x3) << 1) +#define FMI_DEBUG2__PAUSED_AHB_BUS (0x1UL << 0) + +// ============================================================================= +// FMC_ON bitfields +// ============================================================================= + +#define FMC_ON__SWRST (0x1UL << 8) +#define FMC_ON__LOCK_ON (0x1UL << 4) +#define FMC_ON__CLKGATING_RDY (0x1UL << 1) +#define FMC_ON__ENABLE (0x1UL << 0) +#define FMC_ON__DISABLE (!FMC_ON__ENABLE) + +// ============================================================================= +// FMC_IF_CTRL bitfields +// ============================================================================= + +#define FMC_IF_CTRL__WPB (0x1UL << 21) +#define FMC_IF_CTRL__RBBEN (0x1UL << 20) +#define FMC_IF_CTRL__DCCYCLE(v) (((v) & 0xF) << 16) +#define FMC_IF_CTRL__REB_SETUP(v) (((v) & 0xF) << 12) +#define FMC_IF_CTRL__REB_HOLD(v) (((v) & 0xF) << 8) +#define FMC_IF_CTRL__WEB_SETUP(v) (((v) & 0xF) << 4) +#define FMC_IF_CTRL__WEB_HOLD(v) (((v) & 0xF) << 0) +#define FMC_IF_CTRL__GET_DCCYCLE(v) (((v) & 0xF0000) >> 16) +#define FMC_IF_CTRL__GET_REB_SETUP(v) (((v) & 0x0F000) >> 12) +#define FMC_IF_CTRL__GET_REB_HOLD(v) (((v) & 0x00F00) >> 8) +#define FMC_IF_CTRL__GET_WEB_SETUP(v) (((v) & 0x000F0) >> 4) +#define FMC_IF_CTRL__GET_WEB_HOLD(v) (((v) & 0x0000F) >> 0) + +#define FMC_IF_CTRL__TIMING_MAX_CLOCKS (0xFUL) + +// ============================================================================= +// FMC_CE_CTRL bitfields +// ============================================================================= + +#define FMC_CE_CTRL__CE_COUNT (8) +#define FMC_CE_CTRL__CEB(n) (0x1UL << ((n) & 0x7)) + +#define FMC_CE_CTRL__CEB7 FMC_CE_CTRL__CEB(7) +#define FMC_CE_CTRL__CEB6 FMC_CE_CTRL__CEB(6) +#define FMC_CE_CTRL__CEB5 FMC_CE_CTRL__CEB(5) +#define FMC_CE_CTRL__CEB4 FMC_CE_CTRL__CEB(4) +#define FMC_CE_CTRL__CEB3 FMC_CE_CTRL__CEB(3) +#define FMC_CE_CTRL__CEB2 FMC_CE_CTRL__CEB(2) +#define FMC_CE_CTRL__CEB1 FMC_CE_CTRL__CEB(1) +#define FMC_CE_CTRL__CEB0 FMC_CE_CTRL__CEB(0) + +// ============================================================================= +// FMC_RW_CTRL bitfields +// ============================================================================= + +#define FMC_RW_CTRL__REBHOLD (0x1UL << 6) +#define FMC_RW_CTRL__WR_MODE (0x1UL << 5) +#define FMC_RW_CTRL__RD_MODE (0x1UL << 4) +#define FMC_RW_CTRL__ADDR_MODE (0x1UL << 3) +#define FMC_RW_CTRL__CMD3_MODE (0x1UL << 2) +#define FMC_RW_CTRL__CMD2_MODE (0x1UL << 1) +#define FMC_RW_CTRL__CMD1_MODE (0x1UL << 0) + +// ============================================================================= +// FMC_CMD bitfields +// ============================================================================= + +#define FMC_CMD__CMD3(c) (((c) & 0xFF) << 16) +#define FMC_CMD__CMD2(c) (((c) & 0xFF) << 8) +#define FMC_CMD__CMD1(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR0 bitfields +// ============================================================================= + +#define FMC_ADDR0__SEQ3(a) (((a) & 0xFF) << 24) +#define FMC_ADDR0__SEQ2(a) (((a) & 0xFF) << 16) +#define FMC_ADDR0__SEQ1(a) (((a) & 0xFF) << 8) +#define FMC_ADDR0__SEQ0(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR1 bitfields +// ============================================================================= + +#define FMC_ADDR1__SEQ7(a) (((a) & 0xFF) << 24) +#define FMC_ADDR1__SEQ6(a) (((a) & 0xFF) << 16) +#define FMC_ADDR1__SEQ5(a) (((a) & 0xFF) << 8) +#define FMC_ADDR1__SEQ4(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDRNUM bitfields +// ============================================================================= + +#define FMC_ADDRNUM__NUM(n) (((n) & 0x7) << 0) + +// ============================================================================= +// FMC_DATANUM bitfields +// ============================================================================= + +#define FMC_DATANUM__NUM(n) (((n) & 0x3F) << 0) + +// ============================================================================= +// FMC_TO_CTRL bitfields +// ============================================================================= + +#define FMC_TO_CTRL__EN (0x1UL << 12) +#define FMC_TO_CTRL__DIV(d) (((d) & 0xF) << 8) +#define FMC_TO_CTRL__VAL(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_TO_CNT bitfields +// ============================================================================= + +#define FMC_TO_CNT__CNT(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_INTMASK bitfields +// ============================================================================= + +#define FMC_INTMASK__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_INTMASK__RBBDONE7 FMC_INTMASK__RBBDONE(7) +#define FMC_INTMASK__RBBDONE6 FMC_INTMASK__RBBDONE(6) +#define FMC_INTMASK__RBBDONE5 FMC_INTMASK__RBBDONE(5) +#define FMC_INTMASK__RBBDONE4 FMC_INTMASK__RBBDONE(4) +#define FMC_INTMASK__RBBDONE3 FMC_INTMASK__RBBDONE(3) +#define FMC_INTMASK__RBBDONE2 FMC_INTMASK__RBBDONE(2) +#define FMC_INTMASK__RBBDONE1 FMC_INTMASK__RBBDONE(1) +#define FMC_INTMASK__RBBDONE0 FMC_INTMASK__RBBDONE(0) +#define FMC_INTMASK__TIMEOUT (0x1UL << 7) +#define FMC_INTMASK__NSERR (0x1UL << 6) +#define FMC_INTMASK__NSRBBDONE (0x1UL << 5) +#define FMC_INTMASK__TRANSDONE (0x1UL << 4) +#define FMC_INTMASK__ADDRESSDONE (0x1UL << 3) +#define FMC_INTMASK__CMD3DONE (0x1UL << 2) +#define FMC_INTMASK__CMD2DONE (0x1UL << 1) +#define FMC_INTMASK__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_STATUS bitfields +// ============================================================================= + +#define FMC_STATUS__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_STATUS__EMERGENCY2 (0x1UL << 21) +#define FMC_STATUS__EMERGENCY01 (0x1UL << 20) +#define FMC_STATUS__RDATADIRTY (0x1UL << 16) +#define FMC_STATUS__RBBDONE7 FMC_STATUS__RBBDONE(7) +#define FMC_STATUS__RBBDONE6 FMC_STATUS__RBBDONE(6) +#define FMC_STATUS__RBBDONE5 FMC_STATUS__RBBDONE(5) +#define FMC_STATUS__RBBDONE4 FMC_STATUS__RBBDONE(4) +#define FMC_STATUS__RBBDONE3 FMC_STATUS__RBBDONE(3) +#define FMC_STATUS__RBBDONE2 FMC_STATUS__RBBDONE(2) +#define FMC_STATUS__RBBDONE1 FMC_STATUS__RBBDONE(1) +#define FMC_STATUS__RBBDONE0 FMC_STATUS__RBBDONE(0) +#define FMC_STATUS__TIMEOUT (0x1UL << 7) +#define FMC_STATUS__NSERR (0x1UL << 6) +#define FMC_STATUS__NSRBBDONE (0x1UL << 5) +#define FMC_STATUS__TRANSDONE (0x1UL << 4) +#define FMC_STATUS__ADDRESSDONE (0x1UL << 3) +#define FMC_STATUS__CMD3DONE (0x1UL << 2) +#define FMC_STATUS__CMD2DONE (0x1UL << 1) +#define FMC_STATUS__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_RBB_CONFIG bitfields +// ============================================================================= + +#define FMC_RBB_CONFIG__POL(v) (((v) & 0xFF) << 8) +#define FMC_RBB_CONFIG__POS(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_ALARMCMD bitfields +// ============================================================================= + +#define FMC_ALARMCMD__READ1(v) (((v) & 0xFF) << 16) +#define FMC_ALARMCMD__PROG1(v) (((v) & 0xFF) << 8) +#define FMC_ALARMCMD__ERASE1(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_REJECTCMD bitfields +// ============================================================================= + +#define FMC_REJECTCMD__READ2(v) (((v) & 0xFF) << 16) +#define FMC_REJECTCMD__PROG2(v) (((v) & 0xFF) << 8) +#define FMC_REJECTCMD__ERASE2(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// ECC_CON0 bitfields +// ============================================================================= + +#define ECC_CON0__META_LENGTH(n) (((n) & 0x1F) << 8) +#define ECC_CON0__MODE_SEL(m) (((m) & 0x1) << 2) +#define ECC_CON0__START_ENC (0x1UL << 1) +#define ECC_CON0__START_DEC (0x1UL << 0) + +#define ECC_CON0__MODE_SEL__16BIT ECC_CON0__MODE_SEL(1) +#define ECC_CON0__MODE_SEL__8BIT ECC_CON0__MODE_SEL(0) + +// ============================================================================= +// ECC_CON1 bitfields +// ============================================================================= + +#define ECC_CON1__ERROR_ALERT_LEVEL(n) (((n) & 0x1F) << 8) +#define ECC_CON1__INT_ENABLE(b) (((b) & 0x1) << 7) + +#define ECC_CON1__INT_ENABLE__ENABLE ECC_CON1__INT_ENABLE(1) +#define ECC_CON1__INT_ENABLE__DISABLE ECC_CON1__INT_ENABLE(0) + +// ============================================================================= +// ECC_RESULT bitfields +// ============================================================================= + +#define ECC_RESULT__ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_RESULT__ERROR_FLAG (0x1UL << 0) + +// ============================================================================= +// ECC_PND bitfields +// ============================================================================= + +#define ECC_PND__BCH_ALL_FF (0x1UL << 6) +#define ECC_PND__SECTOR_ERROR_ALERT (0x1UL << 5) +#define ECC_PND__READY_BUSY (0x1UL << 4) +#define ECC_PND__UNCORRECTABLE (0x1UL << 3) +#define ECC_PND__DEC_DONE (0x1UL << 2) +#define ECC_PND__ENC_DONE (0x1UL << 1) +#define ECC_PND__ENC_DEC_DONE (0x1UL << 0) + +// ============================================================================= +// ECC_MASK bitfields +// ============================================================================= + +#define ECC_MASK__SECTOR_ERR_ALERT_MASK (0x1UL << 5) +#define ECC_MASK__UNCORRECTABLE_MASK (0x1UL << 3) +#define ECC_MASK__DEC_DONE_MASK (0x1UL << 2) +#define ECC_MASK__ENC_DONE_MASK (0x1UL << 1) +#define ECC_MASK__ENC_DEC_DONE_MASK (0x1UL << 0) + +// ============================================================================= +// ECC_HISTORY bitfields +// ============================================================================= + +#define ECC_HISTORY__ERROR_COUNT_CLEAR (0x1UL << 24) +#define ECC_HISTORY__ERROR_COUNT(n) (((n) & 0x1FFF) << 11) +#define ECC_HISTORY__DECODING_NUMBER_CLEAR (0x1UL << 10) +#define ECC_HISTORY__DECODING_NUMBER(n) (((n) & 0x3FF) << 0) + +// ============================================================================= +// SoC-Specific Tuning +// ============================================================================= + +// These values have not been validated, but they are not used for H2P products +#define FMI_TX_PROP_DELAY_NS (15) +#define FMI_RX_PROP_DELAY_NS (15) + +#endif // _H2FMI_8920REGS_H_ + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_8922regs.h b/drivers/apple/h2fmi/H2fmi_8922regs.h new file mode 100644 index 0000000..df3431a --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_8922regs.h @@ -0,0 +1,535 @@ +// ***************************************************************************** +// +// File: H2fmi_regs.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position +// +// - consider adding definitions for extracting value from register position +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "WMRFeatures.h" +#if defined(H2FMI_EFI) && H2FMI_EFI +#include "SoC.h" +#else +#include +#endif + +#include + +#ifndef _H2FMI_8922REGS_H_ +#define _H2FMI_8922REGS_H_ +// ============================================================================= +// register bases and offsets +// ============================================================================= + +#define FMI0 ((UInt32*)FMI0_BASE_ADDR) +#define FMI1 ((UInt32*)FMI1_BASE_ADDR) + +#define FMI_OFFSET (0x00000) +#define FMC_OFFSET (0x40000) +#define ECC_OFFSET (0x80000) + +#define FMC0 ((volatile UInt32*)((UInt32)FMI0 + FMC_OFFSET)) +#define FMC1 ((volatile UInt32*)((UInt32)FMI1 + FMC_OFFSET)) + +#define FMI_BA(offset) ((UInt32)(FMI_OFFSET + offset)) +#define FMC_BA(offset) ((UInt32)(FMC_OFFSET + offset)) +#define ECC_BA(offset) ((UInt32)(ECC_OFFSET + offset)) + +#define FMI_CONFIG FMI_BA(0x00) +#define FMI_CONTROL FMI_BA(0x04) +#define FMI_STATUS FMI_BA(0x08) +#define FMI_INT_PEND FMI_BA(0x0C) +#define FMI_INT_EN FMI_BA(0x10) +#define FMI_DATA_BUF FMI_BA(0x14) +#define FMI_META_FIFO FMI_BA(0x18) +#define FMI_DEBUG0 FMI_BA(0x1C) +#define FMI_DEBUG1 FMI_BA(0x20) +#define FMI_DEBUG2 FMI_BA(0x24) +#define FMI_DEBUG3 FMI_BA(0x28) +#define FMI_HW_VERSION FMI_BA(0x30) +#define FMI_DATA_SIZE FMI_BA(0x34) + +#define FMI_BUFFER_0_BASE FMI_BA(0x1000) +#define FMI_BUFFER_1_BASE FMI_BA(0x1800) +#define FMI_BUFFER_LEN (0x45F) + +#define FMC_ON FMC_BA(0x00) +#define FMC_VER FMC_BA(0x04) +#define FMC_IF_CTRL FMC_BA(0x08) +#define FMC_CE_CTRL FMC_BA(0x0C) +#define FMC_RW_CTRL FMC_BA(0x10) +#define FMC_CMD FMC_BA(0x14) +#define FMC_ADDR0 FMC_BA(0x18) +#define FMC_ADDR1 FMC_BA(0x1C) +#define FMC_ADDRNUM FMC_BA(0x20) +#define FMC_DATANUM FMC_BA(0x24) +#define FMC_UNDEF0 FMC_BA(0x28) +#define FMC_UNDEF1 FMC_BA(0x2C) +#define FMC_TO_CTRL FMC_BA(0x30) +#define FMC_TO_CNT FMC_BA(0x34) +#define FMC_UNDEF2 FMC_BA(0x38) +#define FMC_UNDEF3 FMC_BA(0x3C) +#define FMC_INTMASK FMC_BA(0x40) +#define FMC_STATUS FMC_BA(0x44) +#define FMC_NAND_STATUS FMC_BA(0x48) +#define FMC_RBB_CONFIG FMC_BA(0x4C) +#define FMC_LOCK0_L FMC_BA(0x50) +#define FMC_LOCK0_H FMC_BA(0x54) +#define FMC_LOCK1_L FMC_BA(0x58) +#define FMC_LOCK1_H FMC_BA(0x5C) +#define FMC_LOCK2_L FMC_BA(0x60) +#define FMC_LOCK2_H FMC_BA(0x64) +#define FMC_ALARMCMD FMC_BA(0x68) +#define FMC_REJECTCMD FMC_BA(0x6C) + +#define ECC_VERSION ECC_BA(0x00) +#define ECC_CON0 ECC_BA(0x04) +#define ECC_CON1 ECC_BA(0x08) +#define ECC_RESULT ECC_BA(0x0C) +#define ECC_PND ECC_BA(0x10) +#define ECC_MASK ECC_BA(0x14) +#define ECC_HISTORY ECC_BA(0x18) +#define ECC_CORE_SW_RESET ECC_BA(0x1C) +#define ECC_LOC0 ECC_BA(0x20) +#define ECC_LOC1 ECC_BA(0x24) +#define ECC_LOC2 ECC_BA(0x28) +#define ECC_LOC3 ECC_BA(0x2C) +#define ECC_LOC4 ECC_BA(0x30) +#define ECC_LOC5 ECC_BA(0x34) +#define ECC_LOC6 ECC_BA(0x38) +#define ECC_UNDEF0 ECC_BA(0x3C) +#define ECC_PARITY0 ECC_BA(0x40) +#define ECC_PARITY1 ECC_BA(0x44) +#define ECC_PARITY2 ECC_BA(0x48) +#define ECC_PARITY3 ECC_BA(0x4C) +#define ECC_PARITY4 ECC_BA(0x50) +#define ECC_PARITY5 ECC_BA(0x54) +#define ECC_PARITY6 ECC_BA(0x58) + +// ============================================================================= +// FMI_CONFIG bitfields +// ============================================================================= + +#define FMI_CONFIG__DMA_BURST(n) (((n) & 0x7) << 0) +#define FMI_CONFIG__ECC_CORRECTABLE_BITS(m) (((m) & 0x1f) << 3) + +#define FMI_CONFIG__DMA_BURST__32_CYCLES FMI_CONFIG__DMA_BURST(5) +#define FMI_CONFIG__DMA_BURST__16_CYCLES FMI_CONFIG__DMA_BURST(4) +#define FMI_CONFIG__DMA_BURST__8_CYCLES FMI_CONFIG__DMA_BURST(3) +#define FMI_CONFIG__DMA_BURST__4_CYCLES FMI_CONFIG__DMA_BURST(2) +#define FMI_CONFIG__DMA_BURST__2_CYCLES FMI_CONFIG__DMA_BURST(1) +#define FMI_CONFIG__DMA_BURST__1_CYCLES FMI_CONFIG__DMA_BURST(0) + + +// ============================================================================= +// FMI_CONTROL bitfields +// ============================================================================= + +#define FMI_CONTROL__ECC_PAUSE (0x1UL << 7) +#define FMI_CONTROL__BUFFER_1_LOCK(m) (((m) & 0x3) << 5) +#define FMI_CONTROL__BUFFER_0_LOCK(m) (((m) & 0x3) << 3) +#define FMI_CONTROL__MODE(m) (((m) & 0x3) << 1) +#define FMI_CONTROL__START_BIT (0x1UL << 0) + +#define FMI_CONTROL__MODE__IDLE FMI_CONTROL__MODE(0) +#define FMI_CONTROL__MODE__READ FMI_CONTROL__MODE(1) +#define FMI_CONTROL__MODE__WRITE FMI_CONTROL__MODE(2) +#define FMI_CONTROL__MODE__SOFTWARE_RESET FMI_CONTROL__MODE(3) + +#define FMI_CONTROL__BUFFER_0_LOCK_FREE FMI_CONTROL__BUFFER_0_LOCK(0) +#define FMI_CONTROL__BUFFER_0_LOCK_DMA FMI_CONTROL__BUFFER_0_LOCK(1) +#define FMI_CONTROL__BUFFER_0_LOCK_ECC FMI_CONTROL__BUFFER_0_LOCK(2) +#define FMI_CONTROL__BUFFER_0_LOCK_FMC FMI_CONTROL__BUFFER_0_LOCK(3) + +#define FMI_CONTROL_BUFFER_1_LOCK_FREE FMI_CONTROL__BUFFER_1_LOCK(0) +#define FMI_CONTROL_BUFFER_1_LOCK_DMA FMI_CONTROL__BUFFER_1_LOCK(1) +#define FMI_CONTROL_BUFFER_1_LOCK_ECC FMI_CONTROL__BUFFER_1_LOCK(2) +#define FMI_CONTROL_BUFFER_1_LOCK_FMC FMI_CONTROL__BUFFER_1_LOCK(3) + +// ============================================================================= +// FMI_STATUS bitfields +// ============================================================================= + +#define FMI_STATUS__FMC_ACTIVE (0x1UL << 3) +#define FMI_STATUS__ECC_ACTIVE (0x1UL << 2) +#define FMI_STATUS__DMA_ACTIVE (0x1UL << 1) +#define FMI_STATUS__BUS_ACTIVE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_PEND bitfields +// ============================================================================= + +#define FMI_INT_PEND__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_PEND__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_PEND__ECC_DONE (0x1UL << 19) +#define FMI_INT_PEND__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_PEND__FMC_READY_BUSY(n) (((n) & 0xFF) << 10) +#define FMI_INT_PEND__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_PEND__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_PEND__FMC_NSERR (0x1UL << 7) +#define FMI_INT_PEND__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_PEND__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_PEND__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_PEND__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_PEND__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_PEND__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_PEND__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_EN bitfields +// ============================================================================= +#define FMI_INT_EN__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_EN__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_EN__ECC_DONE (0x1UL << 19) +#define FMI_INT_EN__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_EN__FMC_READY_BUSY (0x1UL << 10) +#define FMI_INT_EN__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_EN__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_EN__FMC_NSERR (0x1UL << 7) +#define FMI_INT_EN__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_EN__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_EN__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_EN__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_EN__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_EN__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_EN__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_DEBUG0 bitfields +// ============================================================================= + +#define FMI_DEBUG0__DMA_SECTOR_COUNT(n) (((n) & 0x7F) << 25) +#define FMI_DEBUG0__DATA_TC_RECEIVED (0x1UL << 24) +#define FMI_DEBUG0__DMA_WORD_COUNT(n) (((n) & 0x1FF) << 15) +#define FMI_DEBUG0__META_BYTE_COUNT(n) (((n) & 0x3F) << 9) +#define FMI_DEBUG0__FMC_TASKS_PENDING(n) (((n) & 0x3) << 7) +#define FMI_DEBUG0__ECC_TASKS_PENDING(n) (((n) & 0x3) << 5) +#define FMI_DEBUG0__DMA_TASKS_PENDING(n) (((n) & 0x3) << 3) +#define FMI_DEBUG0__FMC_TARGET_BUFFER(b) (((b) & 0x1) << 2) +#define FMI_DEBUG0__ECC_TARGET_BUFFER(b) (((b) & 0x1) << 1) +#define FMI_DEBUG0__DMA_TARGET_BUFFER(b) (((b) & 0x1) << 0) + +// ============================================================================= +// FMI_DEBUG1 bitfields +// ============================================================================= + +#define FMI_DEBUG1__METADATA_TC_RECEIVED(n) (0x1UL << 27) +#define FMI_DEBUG1__METADATA_ADDRESS(n) (((n) & 0x7FF) << 16) +#define FMI_DEBUG1__META_FIFO_LEVEL(n) (((n) & 0x3F) << 10) +#define FMI_DEBUG1__META_FIFO_WRITE_PTR(n) (((n) & 0x1F) << 5) +#define FMI_DEBUG1__META_FIFO_READ_PTR(n) (((n) & 0x1F) << 0) + +// ============================================================================= +// FMI_DEBUG2 bitfields +// ============================================================================= + +#define FMI_DEBUG2__BUFFER_1_META_BYTES(n) (((n) & 0x3F) << 19) +#define FMI_DEBUG2__BUFFER_0_META_BYTES(n) (((n) & 0x3F) << 13) +#define FMI_DEBUG2__META_BYTES_REMAINING(n) (((n) & 0x3F) << 7) +#define FMI_DEBUG2__DATA_STATE(n) (((n) & 0xF) << 3) +#define FMI_DEBUG2__AHB_STATE(n) (((n) & 0x7) << 0) + +// ============================================================================= +// FMI_DEBUG3 bitfields +// ============================================================================= + +#define FMI_DEBUG3__PAUSED_AHB_ADDRESS(n) (((n) & 0xFF) << 9) +#define FMI_DEBUG3__PAUSE_AHB_BUS (0x1UL << 8) +#define FMI_DEBUG3__FMC_PAGE_DONE (0x1UL << 7) +#define FMI_DEBUG3__FMC_BLOCK_COUNT(n) (((n) & 0x7F) << 0) + +// ============================================================================= +// FMI_DATA_SIZE bifields +// ============================================================================= + +#define FMI_DATA_SIZE__META_BYTES_PER_SECTOR(n) (((n) & 0x3F) << 25) +#define FMI_DATA_SIZE__META_BYTES_PER_PAGE(n) (((n) & 0x3F) << 19) +#define FMI_DATA_SIZE__BYTES_PER_SECTOR(n) (((n) & 0x7FF) << 8) +#define FMI_DATA_SIZE__SECTORS_PER_PAGE(n) (((n) & 0xFF) << 0) + +// ============================================================================= +// FMC_ON bitfields +// ============================================================================= + +#define FMC_ON__SWRST (0x1UL << 8) +#define FMC_ON__LOCK_ON (0x1UL << 4) +#define FMC_ON__CLKGATING_RDY (0x1UL << 1) +#define FMC_ON__ENABLE (0x1UL << 0) +#define FMC_ON__DISABLE (!FMC_ON__ENABLE) + +// ============================================================================= +// FMC_IF_CTRL bitfields +// ============================================================================= + +#define FMC_IF_CTRL__WPB (0x1UL << 21) +#define FMC_IF_CTRL__RBBEN (0x1UL << 20) +#define FMC_IF_CTRL__DCCYCLE(v) (WMR_MIN((v), 0xF) << 16) +#define FMC_IF_CTRL__REB_SETUP(v) (WMR_MIN((v), 0xF) << 12) +#define FMC_IF_CTRL__REB_HOLD(v) (WMR_MIN((v), 0xF) << 8) +#define FMC_IF_CTRL__WEB_SETUP(v) (WMR_MIN((v), 0xF) << 4) +#define FMC_IF_CTRL__WEB_HOLD(v) (WMR_MIN((v), 0xF) << 0) +#define FMC_IF_CTRL__GET_DCCYCLE(v) (((v) & 0xF0000) >> 16) +#define FMC_IF_CTRL__GET_REB_SETUP(v) (((v) & 0x0F000) >> 12) +#define FMC_IF_CTRL__GET_REB_HOLD(v) (((v) & 0x00F00) >> 8) +#define FMC_IF_CTRL__GET_WEB_SETUP(v) (((v) & 0x000F0) >> 4) +#define FMC_IF_CTRL__GET_WEB_HOLD(v) (((v) & 0x0000F) >> 0) + +#define FMC_IF_CTRL__TIMING_MAX_CLOCKS (0xFUL) + +// ============================================================================= +// FMC_CE_CTRL bitfields +// ============================================================================= + +#define FMC_CE_CTRL__CE_COUNT (8) +#define FMC_CE_CTRL__CEB(n) (0x1UL << ((n) & 0x7)) + +#define FMC_CE_CTRL__CEB7 FMC_CE_CTRL__CEB(7) +#define FMC_CE_CTRL__CEB6 FMC_CE_CTRL__CEB(6) +#define FMC_CE_CTRL__CEB5 FMC_CE_CTRL__CEB(5) +#define FMC_CE_CTRL__CEB4 FMC_CE_CTRL__CEB(4) +#define FMC_CE_CTRL__CEB3 FMC_CE_CTRL__CEB(3) +#define FMC_CE_CTRL__CEB2 FMC_CE_CTRL__CEB(2) +#define FMC_CE_CTRL__CEB1 FMC_CE_CTRL__CEB(1) +#define FMC_CE_CTRL__CEB0 FMC_CE_CTRL__CEB(0) + +// ============================================================================= +// FMC_RW_CTRL bitfields +// ============================================================================= + +#define FMC_RW_CTRL__REBHOLD (0x1UL << 6) +#define FMC_RW_CTRL__WR_MODE (0x1UL << 5) +#define FMC_RW_CTRL__RD_MODE (0x1UL << 4) +#define FMC_RW_CTRL__ADDR_MODE (0x1UL << 3) +#define FMC_RW_CTRL__CMD3_MODE (0x1UL << 2) +#define FMC_RW_CTRL__CMD2_MODE (0x1UL << 1) +#define FMC_RW_CTRL__CMD1_MODE (0x1UL << 0) + +// ============================================================================= +// FMC_CMD bitfields +// ============================================================================= + +#define FMC_CMD__CMD3(c) (((c) & 0xFF) << 16) +#define FMC_CMD__CMD2(c) (((c) & 0xFF) << 8) +#define FMC_CMD__CMD1(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR0 bitfields +// ============================================================================= + +#define FMC_ADDR0__SEQ3(a) (((a) & 0xFF) << 24) +#define FMC_ADDR0__SEQ2(a) (((a) & 0xFF) << 16) +#define FMC_ADDR0__SEQ1(a) (((a) & 0xFF) << 8) +#define FMC_ADDR0__SEQ0(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR1 bitfields +// ============================================================================= + +#define FMC_ADDR1__SEQ7(a) (((a) & 0xFF) << 24) +#define FMC_ADDR1__SEQ6(a) (((a) & 0xFF) << 16) +#define FMC_ADDR1__SEQ5(a) (((a) & 0xFF) << 8) +#define FMC_ADDR1__SEQ4(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDRNUM bitfields +// ============================================================================= + +#define FMC_ADDRNUM__NUM(n) (((n) & 0x7) << 0) + +// ============================================================================= +// FMC_DATANUM bitfields +// ============================================================================= + +#define FMC_DATANUM__NUM(n) (((n) & 0x3FF) << 0) + +// ============================================================================= +// FMC_TO_CTRL bitfields +// ============================================================================= + +#define FMC_TO_CTRL__EN (0x1UL << 12) +#define FMC_TO_CTRL__DIV(d) (((d) & 0xF) << 8) +#define FMC_TO_CTRL__VAL(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_TO_CNT bitfields +// ============================================================================= + +#define FMC_TO_CNT__CNT(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_INTMASK bitfields +// ============================================================================= + +#define FMC_INTMASK__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_INTMASK__RBBDONE7 FMC_INTMASK__RBBDONE(7) +#define FMC_INTMASK__RBBDONE6 FMC_INTMASK__RBBDONE(6) +#define FMC_INTMASK__RBBDONE5 FMC_INTMASK__RBBDONE(5) +#define FMC_INTMASK__RBBDONE4 FMC_INTMASK__RBBDONE(4) +#define FMC_INTMASK__RBBDONE3 FMC_INTMASK__RBBDONE(3) +#define FMC_INTMASK__RBBDONE2 FMC_INTMASK__RBBDONE(2) +#define FMC_INTMASK__RBBDONE1 FMC_INTMASK__RBBDONE(1) +#define FMC_INTMASK__RBBDONE0 FMC_INTMASK__RBBDONE(0) +#define FMC_INTMASK__TIMEOUT (0x1UL << 7) +#define FMC_INTMASK__NSERR (0x1UL << 6) +#define FMC_INTMASK__NSRBBDONE (0x1UL << 5) +#define FMC_INTMASK__TRANSDONE (0x1UL << 4) +#define FMC_INTMASK__ADDRESSDONE (0x1UL << 3) +#define FMC_INTMASK__CMD3DONE (0x1UL << 2) +#define FMC_INTMASK__CMD2DONE (0x1UL << 1) +#define FMC_INTMASK__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_STATUS bitfields +// ============================================================================= + +#define FMC_STATUS__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_STATUS__EMERGENCY2 (0x1UL << 21) +#define FMC_STATUS__EMERGENCY01 (0x1UL << 20) +#define FMC_STATUS__RDATADIRTY (0x1UL << 16) +#define FMC_STATUS__RBBDONE7 FMC_STATUS__RBBDONE(7) +#define FMC_STATUS__RBBDONE6 FMC_STATUS__RBBDONE(6) +#define FMC_STATUS__RBBDONE5 FMC_STATUS__RBBDONE(5) +#define FMC_STATUS__RBBDONE4 FMC_STATUS__RBBDONE(4) +#define FMC_STATUS__RBBDONE3 FMC_STATUS__RBBDONE(3) +#define FMC_STATUS__RBBDONE2 FMC_STATUS__RBBDONE(2) +#define FMC_STATUS__RBBDONE1 FMC_STATUS__RBBDONE(1) +#define FMC_STATUS__RBBDONE0 FMC_STATUS__RBBDONE(0) +#define FMC_STATUS__TIMEOUT (0x1UL << 7) +#define FMC_STATUS__NSERR (0x1UL << 6) +#define FMC_STATUS__NSRBBDONE (0x1UL << 5) +#define FMC_STATUS__TRANSDONE (0x1UL << 4) +#define FMC_STATUS__ADDRESSDONE (0x1UL << 3) +#define FMC_STATUS__CMD3DONE (0x1UL << 2) +#define FMC_STATUS__CMD2DONE (0x1UL << 1) +#define FMC_STATUS__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_RBB_CONFIG bitfields +// ============================================================================= + +#define FMC_RBB_CONFIG__POL(v) (((v) & 0xFF) << 8) +#define FMC_RBB_CONFIG__POS(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_ALARMCMD bitfields +// ============================================================================= + +#define FMC_ALARMCMD__READ1(v) (((v) & 0xFF) << 16) +#define FMC_ALARMCMD__PROG1(v) (((v) & 0xFF) << 8) +#define FMC_ALARMCMD__ERASE1(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_REJECTCMD bitfields +// ============================================================================= + +#define FMC_REJECTCMD__READ2(v) (((v) & 0xFF) << 16) +#define FMC_REJECTCMD__PROG2(v) (((v) & 0xFF) << 8) +#define FMC_REJECTCMD__ERASE2(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// ECC_CON0 bitfields +// ============================================================================= + +#define ECC_CON0__INFORMATION_LENGTH(n) (((n) & 0x7FF) << 16) +#define ECC_CON0__ECC_CORRECTION_MODE(m) (((m) & 0x1F) << 4) +#define ECC_CON0__START_ENC (0x1UL << 1) +#define ECC_CON0__START_DEC (0x1UL << 0) + +// ============================================================================= +// ECC_CON1 bitfields +// ============================================================================= + +#define ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(n) (((n) & 0x1F) << 16) +#define ECC_CON1__ERROR_ALERT_LEVEL(n) (((n) & 0x1F) << 8) +#define ECC_CON1__INT_ENABLE(b) (((b) & 0x1) << 7) + +#define ECC_CON1__INT_ENABLE__ENABLE ECC_CON1__INT_ENABLE(1) +#define ECC_CON1__INT_ENABLE__DISABLE ECC_CON1__INT_ENABLE(0) + +// ============================================================================= +// ECC_RESULT bitfields +// ============================================================================= + +#define ECC_RESULT__ERROR_ALERT (0x1UL << 21) +#define ECC_RESULT__ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_RESULT__ERROR_CNT_SHIFT (16) +#define ECC_RESULT__ERROR_CNT_MASK (0x1FUL << ECC_RESULT__ERROR_CNT_SHIFT) +#define ECC_RESULT__STUCK_BIT_EXCEEDED (0x1UL << 14) +#define ECC_RESULT__STUCK_BIT_CNT(n) (((n) & 0x3F) << 8) +#define ECC_RESULT__ALL_FF (0x1UL << 3) +#define ECC_RESULT__ALL_ZERO (0x1UL << 2) +#define ECC_RESULT__FREE_PAGE (0x1UL << 1) +#define ECC_RESULT__UNCORRECTABLE (0x1UL << 0) +#define ECC_RESULT__FIFO_RESET (0x1UL << 0) // Same as uncorrectable bit + +// ============================================================================= +// ECC_PND bitfields +// ============================================================================= + +#define ECC_PND__MAX_STUCK_BIT_CNT(n) (((n) & 0x3F) << 24) +#define ECC_PND__MAX_ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_PND__MAX_ERROR_CNT_SHIFT (16) +#define ECC_PND__MAX_ERROR_CNT_MASK (0x1FUL << ECC_PND__MAX_ERROR_CNT_SHIFT) +#define ECC_PND__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_PND__SOME_ALL_FF (0x1UL << 8) +#define ECC_PND__SOME_ALL_ZERO (0x1UL << 7) +#define ECC_PND__ALL_FREE_PAGE (0x1UL << 6) +#define ECC_PND__SOME_ERROR_ALERT (0x1UL << 5) +#define ECC_PND__READY_BUSY (0x1UL << 4) +#define ECC_PND__ANY_UNCORRECTABLE (0x1UL << 3) +#define ECC_PND__ENC_DONE (0x1UL << 2) +#define ECC_PND__DEC_DONE (0x1UL << 1) +#define ECC_PND__ENC_DEC_DONE (0x1UL << 0) + +// ============================================================================= +// ECC_MASK bitfields +// ============================================================================= + +#define ECC_MASK__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_MASK__SOME_ALL_FF_MASK (0x1UL << 8) +#define ECC_MASK__SOME_ALL_ZERO_MASK (0x1UL << 7) +#define ECC_MASK__SOME_ERROR_ALERT_MASK (0x1UL << 5) +#define ECC_MASK__ANY_UNCORRECTABLE_MASK (0x1UL << 3) +#define ECC_MASK__ENC_DONE_MASK (0x1UL << 2) +#define ECC_MASK__DEC_DONE_MASK (0x1UL << 1) +#define ECC_MASK__ENC_DEC_DONE_MASK (0x1UL << 0) + +// ============================================================================= +// ECC_HISTORY bitfields +// ============================================================================= + +#define ECC_HISTORY__ERROR_COUNT_CLEAR (0x1UL << 26) +#define ECC_HISTORY__ERROR_COUNT(n) (((n) & 0x7FFF) << 11) +#define ECC_HISTORY__DECODING_NUMBER_CLEAR (0x1UL << 10) +#define ECC_HISTORY__DECODING_NUMBER(n) (((n) & 0x1FF) << 0) + +// ============================================================================= +// SoC-Specific Tuning +// ============================================================================= + +#define FMI_TX_PROP_DELAY_NS (6) +#define FMI_RX_PROP_DELAY_NS (6) + +#endif // _H2FMI_8922REGS_H_ + +// ********************************** EOF ************************************* diff --git a/drivers/apple/h2fmi/H2fmi_8940regs.h b/drivers/apple/h2fmi/H2fmi_8940regs.h new file mode 100644 index 0000000..ac820a4 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_8940regs.h @@ -0,0 +1,767 @@ +// ***************************************************************************** +// +// File: H2fmi_regs.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position +// +// - consider adding definitions for extracting value from register position +// +// ***************************************************************************** +// +// Copyright (C) 2009 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "WMRFeatures.h" +#if defined(H2FMI_EFI) && H2FMI_EFI +#include "SoC.h" +#else +#include +#endif + +#include + +#ifndef _H2FMI_8940REGS_H_ +#define _H2FMI_8940REGS_H_ +// ============================================================================= +// register bases and offsets +// ============================================================================= + +#define FMI0 ((UInt32*)FMI0_BASE_ADDR) +#define FMI1 ((UInt32*)FMI1_BASE_ADDR) +#define FMI2 ((UInt32*)FMI2_BASE_ADDR) +#define FMI3 ((UInt32*)FMI3_BASE_ADDR) + +#define FMI_OFFSET (0x00000) +#define FMC_OFFSET (0x40000) +#define ECC_OFFSET (0x80000) +#define CMD_OFFSET (0xC0000) + +#define FMC0 ((volatile UInt32*)((UInt32)FMI0 + FMC_OFFSET)) +#define FMC1 ((volatile UInt32*)((UInt32)FMI1 + FMC_OFFSET)) +#define FMC2 ((volatile UInt32*)((UInt32)FMI2 + FMC_OFFSET)) +#define FMC3 ((volatile UInt32*)((UInt32)FMI3 + FMC_OFFSET)) + +#define FMI_BA(offset) ((UInt32)(FMI_OFFSET + offset)) +#define FMC_BA(offset) ((UInt32)(FMC_OFFSET + offset)) +#define ECC_BA(offset) ((UInt32)(ECC_OFFSET + offset)) +#define CMD_BA(offset) ((UInt32)(CMD_OFFSET + offset)) + +#define FMI_CONFIG FMI_BA(0x00) +#define FMI_CONTROL FMI_BA(0x04) +#define FMI_STATUS FMI_BA(0x08) +#define FMI_INT_PEND FMI_BA(0x0C) +#define FMI_INT_EN FMI_BA(0x10) +#define FMI_DATA_BUF FMI_BA(0x14) +#define FMI_META_FIFO FMI_BA(0x18) +#define FMI_DEBUG0 FMI_BA(0x1C) +#define FMI_HW_VERSION FMI_BA(0x30) +#define FMI_DATA_SIZE FMI_BA(0x34) +#define FMI_RAW_PAGE_SIZE FMI_BA(0x38) +#define FMI_SCRAMBLER_SEED_FIFO FMI_BA(0x3C) +#define FMI_SEED_FIFO_LOW_LEVEL FMI_BA(0x40) +#define FMI_METADATA_FIFO_PTR FMI_BA(0x44) +#define FMI_SEED_FIFO_PTR FMI_BA(0x48) +#define FMI_RANDOMIZER_VERSION FMI_BA(0x4C) + +#define FMI_BUFFER_0_BASE FMI_BA(0x1000) +#define FMI_BUFFER_1_BASE FMI_BA(0x1800) +#define FMI_BUFFER_LEN (0x45F) + +#define FMC_ON FMC_BA(0x00) +#define FMC_VER FMC_BA(0x04) +#define FMC_IF_CTRL FMC_BA(0x08) +#define FMC_CE_CTRL FMC_BA(0x0C) +#define FMC_RW_CTRL FMC_BA(0x10) +#define FMC_CMD FMC_BA(0x14) +#define FMC_ADDR0 FMC_BA(0x18) +#define FMC_ADDR1 FMC_BA(0x1C) +#define FMC_ADDRNUM FMC_BA(0x20) +#define FMC_DATANUM FMC_BA(0x24) +#define FMC_UNDEF0 FMC_BA(0x28) +#define FMC_UNDEF1 FMC_BA(0x2C) +#define FMC_TO_CTRL FMC_BA(0x30) +#define FMC_TO_CNT FMC_BA(0x34) +#define FMC_UNDEF2 FMC_BA(0x38) +#define FMC_UNDEF3 FMC_BA(0x3C) +#define FMC_INTMASK FMC_BA(0x40) +#define FMC_STATUS FMC_BA(0x44) +#define FMC_NAND_STATUS FMC_BA(0x48) +#define FMC_RBB_CONFIG FMC_BA(0x4C) +#define FMC_LOCK0_L FMC_BA(0x50) +#define FMC_LOCK0_H FMC_BA(0x54) +#define FMC_LOCK1_L FMC_BA(0x58) +#define FMC_LOCK1_H FMC_BA(0x5C) +#define FMC_LOCK2_L FMC_BA(0x60) +#define FMC_LOCK2_H FMC_BA(0x64) +#define FMC_ALARMCMD FMC_BA(0x68) +#define FMC_REJECTCMD FMC_BA(0x6C) +#define FMC_DQS_TIMING_CTRL FMC_BA(0x70) +#define FMC_TOGGLE_CTRL_1 FMC_BA(0x74) +#define FMC_TOGGLE_CTRL_2 FMC_BA(0x78) +#define FMC_TOGGLE_CTRL_3 FMC_BA(0x7C) + +#define ECC_VERSION ECC_BA(0x00) +#define ECC_CON0 ECC_BA(0x04) +#define ECC_CON1 ECC_BA(0x08) +#define ECC_RESULT ECC_BA(0x0C) +#define ECC_PND ECC_BA(0x10) +#define ECC_MASK ECC_BA(0x14) +#define ECC_HISTORY ECC_BA(0x18) +#define ECC_CORE_SW_RESET ECC_BA(0x1C) +#define ECC_PAGE_ERROR_FIFO ECC_BA(0x24) +#define ECC_PAGE_ERROR_FIFO_PTR ECC_BA(0x28) +#define ECC_RESULTS_FIFO_PTR ECC_BA(0x2C) + +#define COMMAND_FIFO CMD_BA(0x00) +#define COMMAND_FIFO_PTR CMD_BA(0x04) +#define COMMAND_FIFO_LOW CMD_BA(0x08) +#define COMMAND_COUNT CMD_BA(0x0C) +#define COMMAND_INT_CODE CMD_BA(0x10) +#define OPERAND_FIFO CMD_BA(0x14) +#define OPERAND_FIFO_PTR CMD_BA(0x18) +#define OPERAND_FIFO_LOW CMD_BA(0x1C) +#define SEQ_INT_PEND CMD_BA(0x20) +#define SEQ_INT_EN CMD_BA(0x24) +#define SEQ_MACRO_CONTROL CMD_BA(0x28) +#define TIMEOUT_VALUE CMD_BA(0x2C) +#define SEQUENCER_MACROS(n) CMD_BA(0x1000 + ((n) & 0xFF)) +#define SEQUENCER_COMMANDS(n) CMD_BA(0x2000 + ((n) & 0x7F)) +#define SEQUENCER_OPERANDS(n) CMD_BA(0x3000 + ((n) & 0x7F)) + +// ============================================================================= +// FMI_CONFIG bitfields +// ============================================================================= + +#define FMI_CONFIG__DMA_BURST(n) (((n) & 0x7) << 0) +#define FMI_CONFIG__ECC_CORRECTABLE_BITS(m) (((m) & 0x1f) << 3) +#define FMI_CONFIG__ENABLE_WHITENING (0x1UL << 8) + +#define FMI_CONFIG__DMA_BURST__32_CYCLES FMI_CONFIG__DMA_BURST(5) +#define FMI_CONFIG__DMA_BURST__16_CYCLES FMI_CONFIG__DMA_BURST(4) +#define FMI_CONFIG__DMA_BURST__8_CYCLES FMI_CONFIG__DMA_BURST(3) +#define FMI_CONFIG__DMA_BURST__4_CYCLES FMI_CONFIG__DMA_BURST(2) +#define FMI_CONFIG__DMA_BURST__2_CYCLES FMI_CONFIG__DMA_BURST(1) +#define FMI_CONFIG__DMA_BURST__1_CYCLES FMI_CONFIG__DMA_BURST(0) + + +// ============================================================================= +// FMI_CONTROL bitfields +// ============================================================================= + +#define FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE (0x1UL << 12) +#define FMI_CONTROL__RESET_SEED (0x1UL << 11) +#define FMI_CONTROL__RAW_READ_MODE (0x1UL << 10) +#define FMI_CONTROL__RESET_SEQUENCER (0x1UL << 9) +#define FMI_CONTROL__ENABLE_SEQUENCER (0x1UL << 8) +#define FMI_CONTROL__ECC_PAUSE (0x1UL << 7) +#define FMI_CONTROL__BUFFER_1_LOCK(m) (((m) & 0x3) << 5) +#define FMI_CONTROL__BUFFER_0_LOCK(m) (((m) & 0x3) << 3) +#define FMI_CONTROL__MODE(m) (((m) & 0x3) << 1) +#define FMI_CONTROL__START_BIT (0x1UL << 0) + +#define FMI_CONTROL__MODE__IDLE FMI_CONTROL__MODE(0) +#define FMI_CONTROL__MODE__READ FMI_CONTROL__MODE(1) +#define FMI_CONTROL__MODE__WRITE FMI_CONTROL__MODE(2) +#define FMI_CONTROL__MODE__SOFTWARE_RESET FMI_CONTROL__MODE(3) + +#define FMI_CONTROL__BUFFER_0_LOCK_FREE FMI_CONTROL__BUFFER_0_LOCK(0) +#define FMI_CONTROL__BUFFER_0_LOCK_DMA FMI_CONTROL__BUFFER_0_LOCK(1) +#define FMI_CONTROL__BUFFER_0_LOCK_ECC FMI_CONTROL__BUFFER_0_LOCK(2) +#define FMI_CONTROL__BUFFER_0_LOCK_FMC FMI_CONTROL__BUFFER_0_LOCK(3) + +#define FMI_CONTROL_BUFFER_1_LOCK_FREE FMI_CONTROL__BUFFER_1_LOCK(0) +#define FMI_CONTROL_BUFFER_1_LOCK_DMA FMI_CONTROL__BUFFER_1_LOCK(1) +#define FMI_CONTROL_BUFFER_1_LOCK_ECC FMI_CONTROL__BUFFER_1_LOCK(2) +#define FMI_CONTROL_BUFFER_1_LOCK_FMC FMI_CONTROL__BUFFER_1_LOCK(3) + +// ============================================================================= +// FMI_STATUS bitfields +// ============================================================================= + +#define FMI_STATUS__FMC_ACTIVE (0x1UL << 3) +#define FMI_STATUS__ECC_ACTIVE (0x1UL << 2) +#define FMI_STATUS__DMA_ACTIVE (0x1UL << 1) +#define FMI_STATUS__BUS_ACTIVE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_PEND bitfields +// ============================================================================= + +#define FMI_INT_PEND__SEQUENCER_INTERRUPT (0x1UL << 28) +#define FMI_INT_PEND__SEED_FIFO_EMPTY (0x1UL << 27) +#define FMI_INT_PEND__SEED_FIFO_LOW (0x1UL << 26) +#define FMI_INT_PEND__SEED_FIFO_OVERFLOW (0x1UL << 25) +#define FMI_INT_PEND__ECC_RESULTS_FIFO_UNDERFLOW (0x1UL << 24) +#define FMI_INT_PEND__ECC_RESULTS_FIFO_OVERFLOW (0x1UL << 23) +#define FMI_INT_PEND__LAST_ECC_DONE (0x1UL << 22) +#define FMI_INT_PEND__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_PEND__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_PEND__ECC_DONE (0x1UL << 19) +#define FMI_INT_PEND__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_PEND__FMC_READY_BUSY(n) (((n) & 0xFF) << 10) +#define FMI_INT_PEND__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_PEND__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_PEND__FMC_NSERR (0x1UL << 7) +#define FMI_INT_PEND__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_PEND__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_PEND__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_PEND__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_PEND__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_PEND__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_PEND__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_EN bitfields +// ============================================================================= +#define FMI_INT_EN__SEQUENCER_INTERRUPT (0x1UL << 28) +#define FMI_INT_EN__SEED_FIFO_EMPTY (0x1UL << 27) +#define FMI_INT_EN__SEED_FIFO_LOW (0x1UL << 26) +#define FMI_INT_EN__SEED_FIFO_OVERFLOW (0x1UL << 25) +#define FMI_INT_EN__ECC_RESULTS_FIFO_UNDERFLOW (0x1UL << 24) +#define FMI_INT_EN__ECC_RESULTS_FIFO_OVERFLOW (0x1UL << 23) +#define FMI_INT_EN__LAST_ECC_DONE (0x1UL << 22) +#define FMI_INT_EN__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_EN__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_EN__ECC_DONE (0x1UL << 19) +#define FMI_INT_EN__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_EN__FMC_READY_BUSY (0x1UL << 10) +#define FMI_INT_EN__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_EN__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_EN__FMC_NSERR (0x1UL << 7) +#define FMI_INT_EN__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_EN__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_EN__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_EN__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_EN__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_EN__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_EN__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_DEBUG0 bitfields +// ============================================================================= + +#define FMI_DEBUG0__FMC_TASKS_PENDING(n) (((n) & 0x3) << 7) +#define FMI_DEBUG0__ECC_TASKS_PENDING(n) (((n) & 0x3) << 5) +#define FMI_DEBUG0__DMA_TASKS_PENDING(n) (((n) & 0x3) << 3) +#define FMI_DEBUG0__FMC_TARGET_BUFFER(b) (((b) & 0x1) << 2) +#define FMI_DEBUG0__ECC_TARGET_BUFFER(b) (((b) & 0x1) << 1) +#define FMI_DEBUG0__DMA_TARGET_BUFFER(b) (((b) & 0x1) << 0) + +// ============================================================================= +// FMI_DATA_SIZE bifields +// ============================================================================= + +#define FMI_DATA_SIZE__META_BYTES_PER_SECTOR(n) (((n) & 0x3F) << 25) +#define FMI_DATA_SIZE__META_BYTES_PER_PAGE(n) (((n) & 0x3F) << 19) +#define FMI_DATA_SIZE__BYTES_PER_SECTOR(n) (((n) & 0x7FF) << 8) +#define FMI_DATA_SIZE__SECTORS_PER_PAGE(n) (((n) & 0xFF) << 0) + +// ============================================================================= +// FMI_SEED_FIFO_LOW_LEVEL bitfields +// ============================================================================= + +#define FMI_SEED_FIFO_LOW_LEVEL__LEVEL(x) (((x) & 0x7) << 0) + +// ============================================================================= +// METADATA_FIFO_PTR bitfields +// ============================================================================= + +#define METADATA_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define METADATA_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define METADATA_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// SEED_FIFO_PTR bitfields +// ============================================================================= + +#define SEED_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x7) +#define SEED_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x7) +#define SEED_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0xF) + +// ============================================================================= +// FMC_ON bitfields +// ============================================================================= + +#define FMC_ON__SWRST (0x1UL << 8) +#define FMC_ON__ASYNC_DRIVE_DQS (0x1UL << 6) +#define FMC_ON__ASYNC_CEB_AUTO_DISABLE (0x1UL << 5) +#define FMC_ON__LOCK_ON (0x1UL << 4) +#define FMC_ON__DDR_NAND_TYPE_TOGGLE (0x0UL << 3) +#define FMC_ON__DDR_NAND_TYPE_ONFI (0x1UL << 3) +#define FMC_ON__DDR_ENABLE (0x1UL << 2) +#define FMC_ON__CLKGATING_RDY (0x1UL << 1) +#define FMC_ON__ENABLE (0x1UL << 0) +#define FMC_ON__DISABLE (!FMC_ON__ENABLE) + +// ============================================================================= +// FMC_IF_CTRL bitfields +// ============================================================================= + +#define FMC_IF_CTRL__WPB (0x1UL << 21) +#define FMC_IF_CTRL__RBBEN (0x1UL << 20) +// Change DCCycle calculation for h4p due to silicon bug +#define FMC_IF_CTRL__DCCYCLE(v) (((v) & 0xF) << 16) +#define FMC_IF_CTRL__REB_SETUP(v) (((v) & 0xF) << 12) +#define FMC_IF_CTRL__REB_HOLD(v) (((v) & 0xF) << 8) +#define FMC_IF_CTRL__WEB_SETUP(v) (((v) & 0xF) << 4) +#define FMC_IF_CTRL__WEB_HOLD(v) (((v) & 0xF) << 0) +#define FMC_IF_CTRL__GET_DCCYCLE(v) (((v) & 0xF0000) >> 16) +#define FMC_IF_CTRL__GET_REB_SETUP(v) (((v) & 0x0F000) >> 12) +#define FMC_IF_CTRL__GET_REB_HOLD(v) (((v) & 0x00F00) >> 8) +#define FMC_IF_CTRL__GET_WEB_SETUP(v) (((v) & 0x000F0) >> 4) +#define FMC_IF_CTRL__GET_WEB_HOLD(v) (((v) & 0x0000F) >> 0) + +#define FMC_IF_CTRL__REB_SETUP_MASK (0x0000000F << 12) + +#define FMC_IF_CTRL__TIMING_MAX_CLOCKS (0xFUL) + +// ============================================================================= +// FMC_CE_CTRL bitfields +// ============================================================================= + +#define FMC_CE_CTRL__CE_COUNT (8) +#define FMC_CE_CTRL__CEB(n) (0x1UL << ((n) & 0x7)) + +#define FMC_CE_CTRL__CEB7 FMC_CE_CTRL__CEB(7) +#define FMC_CE_CTRL__CEB6 FMC_CE_CTRL__CEB(6) +#define FMC_CE_CTRL__CEB5 FMC_CE_CTRL__CEB(5) +#define FMC_CE_CTRL__CEB4 FMC_CE_CTRL__CEB(4) +#define FMC_CE_CTRL__CEB3 FMC_CE_CTRL__CEB(3) +#define FMC_CE_CTRL__CEB2 FMC_CE_CTRL__CEB(2) +#define FMC_CE_CTRL__CEB1 FMC_CE_CTRL__CEB(1) +#define FMC_CE_CTRL__CEB0 FMC_CE_CTRL__CEB(0) + +// ============================================================================= +// FMC_RW_CTRL bitfields +// ============================================================================= + +#define FMC_RW_CTRL__NAND_TIMING_USER_TAT(x) (((x) & 0xFFFF) << 24) +#define FMC_RW_CTRL__RD_DONE_REB_CEB_HOLD (0x1UL << 7) +#define FMC_RW_CTRL__REBHOLD (0x1UL << 6) +#define FMC_RW_CTRL__WR_MODE (0x1UL << 5) +#define FMC_RW_CTRL__RD_MODE (0x1UL << 4) +#define FMC_RW_CTRL__ADDR_MODE (0x1UL << 3) +#define FMC_RW_CTRL__CMD3_MODE (0x1UL << 2) +#define FMC_RW_CTRL__CMD2_MODE (0x1UL << 1) +#define FMC_RW_CTRL__CMD1_MODE (0x1UL << 0) + +// ============================================================================= +// FMC_CMD bitfields +// ============================================================================= + +#define FMC_CMD__CMD3(c) (((c) & 0xFF) << 16) +#define FMC_CMD__CMD2(c) (((c) & 0xFF) << 8) +#define FMC_CMD__CMD1(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR0 bitfields +// ============================================================================= + +#define FMC_ADDR0__SEQ3(a) (((a) & 0xFF) << 24) +#define FMC_ADDR0__SEQ2(a) (((a) & 0xFF) << 16) +#define FMC_ADDR0__SEQ1(a) (((a) & 0xFF) << 8) +#define FMC_ADDR0__SEQ0(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR1 bitfields +// ============================================================================= + +#define FMC_ADDR1__SEQ7(a) (((a) & 0xFF) << 24) +#define FMC_ADDR1__SEQ6(a) (((a) & 0xFF) << 16) +#define FMC_ADDR1__SEQ5(a) (((a) & 0xFF) << 8) +#define FMC_ADDR1__SEQ4(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDRNUM bitfields +// ============================================================================= + +#define FMC_ADDRNUM__NUM(n) (((n) & 0x7) << 0) + +// ============================================================================= +// FMC_DATANUM bitfields +// ============================================================================= + +#define FMC_DATANUM__NUM(n) (((n) & 0x3FF) << 0) + +// ============================================================================= +// FMC_TO_CTRL bitfields +// ============================================================================= + +#define FMC_TO_CTRL__EN (0x1UL << 12) +#define FMC_TO_CTRL__DIV(d) (((d) & 0xF) << 8) +#define FMC_TO_CTRL__VAL(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_TO_CNT bitfields +// ============================================================================= + +#define FMC_TO_CNT__CNT(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_INTMASK bitfields +// ============================================================================= + +#define FMC_INTMASK__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_INTMASK__RBBDONE7 FMC_INTMASK__RBBDONE(7) +#define FMC_INTMASK__RBBDONE6 FMC_INTMASK__RBBDONE(6) +#define FMC_INTMASK__RBBDONE5 FMC_INTMASK__RBBDONE(5) +#define FMC_INTMASK__RBBDONE4 FMC_INTMASK__RBBDONE(4) +#define FMC_INTMASK__RBBDONE3 FMC_INTMASK__RBBDONE(3) +#define FMC_INTMASK__RBBDONE2 FMC_INTMASK__RBBDONE(2) +#define FMC_INTMASK__RBBDONE1 FMC_INTMASK__RBBDONE(1) +#define FMC_INTMASK__RBBDONE0 FMC_INTMASK__RBBDONE(0) +#define FMC_INTMASK__TIMEOUT (0x1UL << 7) +#define FMC_INTMASK__NSERR (0x1UL << 6) +#define FMC_INTMASK__NSRBBDONE (0x1UL << 5) +#define FMC_INTMASK__TRANSDONE (0x1UL << 4) +#define FMC_INTMASK__ADDRESSDONE (0x1UL << 3) +#define FMC_INTMASK__CMD3DONE (0x1UL << 2) +#define FMC_INTMASK__CMD2DONE (0x1UL << 1) +#define FMC_INTMASK__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_STATUS bitfields +// ============================================================================= + +#define FMC_STATUS__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_STATUS__EMERGENCY2 (0x1UL << 21) +#define FMC_STATUS__EMERGENCY01 (0x1UL << 20) +#define FMC_STATUS__RDATADIRTY (0x1UL << 16) +#define FMC_STATUS__RBBDONE7 FMC_STATUS__RBBDONE(7) +#define FMC_STATUS__RBBDONE6 FMC_STATUS__RBBDONE(6) +#define FMC_STATUS__RBBDONE5 FMC_STATUS__RBBDONE(5) +#define FMC_STATUS__RBBDONE4 FMC_STATUS__RBBDONE(4) +#define FMC_STATUS__RBBDONE3 FMC_STATUS__RBBDONE(3) +#define FMC_STATUS__RBBDONE2 FMC_STATUS__RBBDONE(2) +#define FMC_STATUS__RBBDONE1 FMC_STATUS__RBBDONE(1) +#define FMC_STATUS__RBBDONE0 FMC_STATUS__RBBDONE(0) +#define FMC_STATUS__TIMEOUT (0x1UL << 7) +#define FMC_STATUS__NSERR (0x1UL << 6) +#define FMC_STATUS__NSRBBDONE (0x1UL << 5) +#define FMC_STATUS__TRANSDONE (0x1UL << 4) +#define FMC_STATUS__ADDRESSDONE (0x1UL << 3) +#define FMC_STATUS__CMD3DONE (0x1UL << 2) +#define FMC_STATUS__CMD2DONE (0x1UL << 1) +#define FMC_STATUS__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_RBB_CONFIG bitfields +// ============================================================================= + +#define FMC_RBB_CONFIG__POL(v) (((v) & 0xFF) << 8) +#define FMC_RBB_CONFIG__POS(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_ALARMCMD bitfields +// ============================================================================= + +#define FMC_ALARMCMD__READ1(v) (((v) & 0xFF) << 16) +#define FMC_ALARMCMD__PROG1(v) (((v) & 0xFF) << 8) +#define FMC_ALARMCMD__ERASE1(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_REJECTCMD bitfields +// ============================================================================= + +#define FMC_REJECTCMD__READ2(v) (((v) & 0xFF) << 16) +#define FMC_REJECTCMD__PROG2(v) (((v) & 0xFF) << 8) +#define FMC_REJECTCMD__ERASE2(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_DQS_TIMING_CTRL bitfields +// ============================================================================= + +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL(x) (((x) & 0x1FF) << 16) +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL_GET(x) (((x) & 0x01FF0000) >> 16) +#define FMC_DQS_TIMING_CTRL__DQS_WRITE_FINE_TIMING(x) (((x) & 0xF) << 4) +#define FMC_DQS_TIMING_CTRL__DQS_WRITE_COARSE_DIRECTION (0x1UL << 3) +#define FMC_DQS_TIMING_CTRL__WR_DQS_COARSE_TIMING (((x) & 0x7) << 0) + +#define FMC_DQS_TIMING_CTRL__DEFAULT_VAL (0x00C40000) + +// ============================================================================= +// FMC_TOGGLE_CTRL_1 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_1_DDR_RD_PRE_TIME(x) (((x) & 0xFF) << 24) +#define FMC_TOGGLE_CTRL_1_DDR_RD_POST_TIME(x) (((x) & 0xFF) << 16) +#define FMC_TOGGLE_CTRL_1_DDR_WR_PRE_TIME(x) (((x) & 0xFF) << 8) +#define FMC_TOGGLE_CTRL_1_DDR_WR_POST_TIME(x) (((x) & 0xFF) << 0) + +#define FMC_TOGGLE_CTRL_1__TIMING_MAX_CLOCKS (0xFF) + +// ============================================================================= +// FMC_TOGGLE_CTRL_2 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_2_CE_SETUP_TIME(x) (((x) & 0xFF) << 24) +#define FMC_TOGGLE_CTRL_2_CE_HOLD_TIME(x) (((x) & 0xFF) << 16) +#define FMC_TOGGLE_CTRL_2_NAND_TIMING_ADL(x) (((x) & 0xFF) << 8) +#define FMC_TOGGLE_CTRL_2_NAND_TIMING_WHR(x) (((x) & 0xFF) << 0) + +#define FMC_TOGGLE_CTRL_2__TIMING_MAX_CLOCKS (0xFF) + +// ============================================================================= +// FMC_TOGGLE_CTRL_2 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_3_ONFI_WR_CLK_STOP_EN (0x1UL << 31) +#define FMC_TOGGLE_CTRL_3_ONFI_TIMING_CAD (((x) & 0xF) << 0) + +// ============================================================================= +// ECC_CON0 bitfields +// ============================================================================= + +#define ECC_CON0__INFORMATION_LENGTH(n) (((n) & 0x7FF) << 16) +#define ECC_CON0__ECC_CORRECTION_MODE(m) (((m) & 0x1F) << 4) +#define ECC_CON0__START_ENC (0x1UL << 1) +#define ECC_CON0__START_DEC (0x1UL << 0) + +// ============================================================================= +// ECC_CON1 bitfields +// ============================================================================= +#define ECC_CON1__IMPLICIT_WRITE_MARK (1UL << 31) +#define ECC_CON1__SLAVE_MODE (1UL << 29) +#define ECC_CON1__SKIP_FREE_PAGE_FLD (1UL << 25) +#define ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(n) (((n) & 0x1F) << 16) +#define ECC_CON1__ERROR_ALERT_LEVEL(n) (((n) & 0x1F) << 8) +#define ECC_CON1__INT_ENABLE(b) (((b) & 0x1) << 7) + +#define ECC_CON1__INT_ENABLE__ENABLE ECC_CON1__INT_ENABLE(1) +#define ECC_CON1__INT_ENABLE__DISABLE ECC_CON1__INT_ENABLE(0) + +// ============================================================================= +// ECC_RESULT bitfields +// ============================================================================= + +#define ECC_RESULT__ERROR_ALERT (0x1UL << 21) +#define ECC_RESULT__ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_RESULT__ERROR_CNT_SHIFT (16) +#define ECC_RESULT__ERROR_CNT_MASK (0x1FUL << ECC_RESULT__ERROR_CNT_SHIFT) +#define ECC_RESULT__STUCK_BIT_EXCEEDED (0x1UL << 14) +#define ECC_RESULT__STUCK_BIT_CNT(n) (((n) & 0x3F) << 8) +#define ECC_RESULT__DECODED_BUFFER_IDX (0x1UL << 6) +#define ECC_RESULT__ALL_FF (0x1UL << 3) +#define ECC_RESULT__ALL_ZERO (0x1UL << 2) +#define ECC_RESULT__FREE_PAGE (0x1UL << 1) +#define ECC_RESULT__UNCORRECTABLE (0x1UL << 0) +#define ECC_RESULT__FIFO_RESET (0x1UL << 0) // Same as uncorrectable bit + +// ============================================================================= +// ECC_PND bitfields +// ============================================================================= + +#define ECC_PND__MAX_STUCK_BIT_CNT(n) (((n) & 0x3F) << 24) +#define ECC_PND__MAX_ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_PND__MAX_ERROR_CNT_SHIFT (16) +#define ECC_PND__MAX_ERROR_CNT_MASK (0x1FUL << ECC_PND__MAX_ERROR_CNT_SHIFT) +#define ECC_PND__DETECTOR_DONE (0x1UL << 14) +#define ECC_PND__B1_DEC_DONE (0x1UL << 13) +#define ECC_PND__B0_DEC_DONE (0x1UL << 12) +#define ECC_PND__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_PND__SOME_ALL_FF (0x1UL << 8) +#define ECC_PND__SOME_ALL_ZERO (0x1UL << 7) +#define ECC_PND__ALL_FREE_PAGE (0x1UL << 6) +#define ECC_PND__SOME_ERROR_ALERT (0x1UL << 5) +#define ECC_PND__READY_BUSY (0x1UL << 4) +#define ECC_PND__ANY_UNCORRECTABLE (0x1UL << 3) +#define ECC_PND__ENC_DONE (0x1UL << 2) +#define ECC_PND__DEC_DONE (0x1UL << 1) +#define ECC_PND__ENC_DEC_DONE (0x1UL << 0) + +// ============================================================================= +// ECC_MASK bitfields +// ============================================================================= + +#define ECC_MASK__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_MASK__SOME_ALL_FF_MASK (0x1UL << 8) +#define ECC_MASK__SOME_ALL_ZERO_MASK (0x1UL << 7) +#define ECC_MASK__SOME_ERROR_ALERT_MASK (0x1UL << 5) +#define ECC_MASK__ANY_UNCORRECTABLE_MASK (0x1UL << 3) +#define ECC_MASK__ENC_DONE_MASK (0x1UL << 2) +#define ECC_MASK__DEC_DONE_MASK (0x1UL << 1) +#define ECC_MASK__ENC_DEC_DONE_MASK (0x1UL << 0) + +// ============================================================================= +// ECC_HISTORY bitfields +// ============================================================================= + +#define ECC_HISTORY__ERROR_COUNT_CLEAR (0x1UL << 26) +#define ECC_HISTORY__ERROR_COUNT(n) (((n) & 0x7FFF) << 11) +#define ECC_HISTORY__DECODING_NUMBER_CLEAR (0x1UL << 10) +#define ECC_HISTORY__DECODING_NUMBER(n) (((n) & 0x1FF) << 0) + +// ============================================================================= +// RESULT_FIFO_PTR bitfields +// ============================================================================= + +#define ECC_RESULTS_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define ECC_RESULTS_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define ECC_RESULTS_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// COMMAND_FIFO bitfields +// ============================================================================= + +#define COMMAND_FIFO_SIZE (32) +#define OPERAND_FIFO_SIZE (32) + +#define COMMAND_FIFO__COMMAND(cmd) ((cmd) << 24) +#define COMMAND_FIFO__OPERAND(op) (((op) & 0xFFFFFF) << 0) + +#if 0 // DEPRECATED +#define OPCODE_ADDR(n) (n) +#endif // DEPRECATED +#define OPCODE_COMMAND (0x08) +#define OPCODE_ENABLE_CE (0x09) +#define OPCODE_WAIT_FOR_READY (0x0A) +#define OPCODE_TX_PAGE (0x0B) +#define OPCODE_SEND_INTERRUPT (0x0C) +#define OPCODE_PAUSE (0x0D) +#define OPCODE_TIMED_WAIT (0x0E) +#define OPCODE_LOAD_NEXT_WORD (0x0F) +#define OPCODE_LOAD_FROM_FIFO (0x10) +#define OPCODE_MACRO (0x11) +#define OPCODE_POLL (0x12) +#define OPCODE_WAIT_FOR_INT (0x13) + +#define CMD_ADDRESS(bytes, addr) (COMMAND_FIFO__COMMAND(OPCODE_ADDR(bytes)) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFFF)) + +#define CMD_COMMAND(cmd) (COMMAND_FIFO__COMMAND(OPCODE_COMMAND) | \ + COMMAND_FIFO__OPERAND((cmd) & 0xFF)) + +#define CMD_ENABLE_CHIP(mask) (COMMAND_FIFO__COMMAND(OPCODE_ENABLE_CE) | \ + COMMAND_FIFO__OPERAND((mask) & 0xFF)) + +#define CMD_WAIT_FOR_READY(code,mask,cond) (COMMAND_FIFO__COMMAND(OPCODE_WAIT_FOR_READY) | \ + COMMAND_FIFO__OPERAND((code) << 16 | (mask) << 8 | (cond) << 0)) + +#define CMD_TX_PAGE (COMMAND_FIFO__COMMAND(OPCODE_TX_PAGE)) + +#define CMD_SEND_INTERRUPT(code) (COMMAND_FIFO__COMMAND(OPCODE_SEND_INTERRUPT) | \ + COMMAND_FIFO__OPERAND(code)) + +#define CMD_PAUSE (COMMAND_FIFO__COMMAND(OPCODE_PAUSE)) + +#define CMD_TIMED_WAIT(clks) (COMMAND_FIFO__COMMAND(OPCODE_TIMED_WAIT) | \ + COMMAND_FIFO__OPERAND(clks)) + +#define CMD_LOAD_NEXT_WORD(addr) (COMMAND_FIFO__COMMAND(OPCODE_LOAD_NEXT_WORD) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_LOAD_FROM_FIFO(addr) (COMMAND_FIFO__COMMAND(OPCODE_LOAD_FROM_FIFO) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_MACRO(seq,len) (COMMAND_FIFO__COMMAND(OPCODE_MACRO) | \ + COMMAND_FIFO__OPERAND(((seq) << 8) | (len))) + +#define CMD_POLL(addr) (COMMAND_FIFO__COMMAND(OPCODE_POLL) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_WAIT_FOR_INT(irq,bit) (COMMAND_FIFO__COMMAND(OPCODE_WAIT_FOR_INT) | \ + COMMAND_FIFO__OPERAND((irq) << 8 | (bit) << 0)) + + +// ============================================================================= +// COMMAND_FIFO_PTR bitfields +// ============================================================================= + +#define COMMAND_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define COMMAND_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define COMMAND_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// COMMAND_FIFO_LOW bitfields +// ============================================================================= + +#define COMMAND_FIFO_LOW__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// COMMAND_COUNT bitfields +// ============================================================================= + +#define COMMAND_COUNT__MAX_COUNT (32) + +// ============================================================================= +// COMMAND_INT_CODE bitfields +// ============================================================================= + +#define COMMAND_INT_CODE__READ(regval) ((regval) & 0xFFFFFF) +#define COMMAND_INT_CODE__WAIT_FOR_READY_CODE(regval) ((regval >> 16) & 0xFF) +#define COMMAND_INT_CODE__WAIT_FOR_READY_STATUS(regval) ((regval >> 0) & 0xFF) + +// ============================================================================= +// OPERAND_FIFO_PTR bitfields +// ============================================================================= + +#define OPERAND_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define OPERAND_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define OPERAND_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// OPERAND_FIFO_LOW bitfields +// ============================================================================= + +#define OPERAND_FIFO_LOW__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// SEQ_INT_PEND bitfields +// ============================================================================= + +#define SEQ_INT_PEND__TIMEOUT (0x1UL << 7) +#define SEQ_INT_PEND__OPERAND_FIFO_EMPTY (0x1UL << 6) +#define SEQ_INT_PEND__OPERAND_FIFO_LOW (0x1UL << 5) +#define SEQ_INT_PEND__OPERAND_FIFO_OVERFLOW (0x1UL << 4) +#define SEQ_INT_PEND__COMMAND_FIFO_EMPTY (0x1UL << 3) +#define SEQ_INT_PEND__COMMAND_FIFO_LOW (0x1UL << 2) +#define SEQ_INT_PEND__COMMAND_FIFO_OVERFLOW (0x1UL << 1) +#define SEQ_INT_PEND__SEQUENCER_SIGNAL (0x1UL << 0) + +// ============================================================================= +// SEQ_INT_EN bitfields +// ============================================================================= + +#define SEQ_INT_EN__TIMEOUT (0x1UL << 7) +#define SEQ_INT_EN__OPERAND_FIFO_EMPTY (0x1UL << 6) +#define SEQ_INT_EN__OPERAND_FIFO_LOW (0x1UL << 5) +#define SEQ_INT_EN__OPERAND_FIFO_OVERFLOW (0x1UL << 4) +#define SEQ_INT_EN__COMMAND_FIFO_EMPTY (0x1UL << 3) +#define SEQ_INT_EN__COMMAND_FIFO_LOW (0x1UL << 2) +#define SEQ_INT_EN__COMMAND_FIFO_OVERFLOW (0x1UL << 1) +#define SEQ_INT_EN__SEQUENCER_SIGNAL (0x1UL << 0) + +// ============================================================================= +// SEQ_MACRO_CONTROL bitfields +// ============================================================================= + +#define SEQ_MACRO_CONTROL__WORD_COUNT(cnt) (((cnt) & 0x3F) << 8) +#define SEQ_MACRO_CONTROL__MACRO_ADDRESS(addr) (((addr) & 0x3F) << 0) +#define SEQ_MACRO_CONTROL__GET_WORD_COUNT(regval) (((regval) >> 8) & 0x3F) +#define SEQ_MACRO_CONTROL__GET_MACRO_ADDRESS(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// SoC-Specific Tuning +// ============================================================================= + +#define FMI_TX_PROP_DELAY_NS (6) +#define FMI_RX_PROP_DELAY_NS (6) + +#endif // _H2FMI_8940REGS_H_ + +// ********************************** EOF ************************************* diff --git a/drivers/apple/h2fmi/H2fmi_8945regs.h b/drivers/apple/h2fmi/H2fmi_8945regs.h new file mode 100644 index 0000000..2fdde1e --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_8945regs.h @@ -0,0 +1,799 @@ +// ***************************************************************************** +// +// File: H2fmi_regs.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position +// +// - consider adding definitions for extracting value from register position +// +// ***************************************************************************** +// +// Copyright (C) 2010 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "WMRFeatures.h" +#if defined(H2FMI_EFI) && H2FMI_EFI +#include "SoC.h" +#else +#include +#endif + +#include + +#ifndef _H2FMI_8945REGS_H_ +#define _H2FMI_8945REGS_H_ +// ============================================================================= +// register bases and offsets +// ============================================================================= + +#define FMI0 ((UInt32*)FMI0_BASE_ADDR) +#define FMI1 ((UInt32*)FMI1_BASE_ADDR) +#define FMI2 ((UInt32*)FMI2_BASE_ADDR) +#define FMI3 ((UInt32*)FMI3_BASE_ADDR) + +#define FMI_OFFSET (0x00000) +#define FMC_OFFSET (0x40000) +#define ECC_OFFSET (0x80000) +#define CMD_OFFSET (0xC0000) + +#define FMC0 ((volatile UInt32*)((UInt32)FMI0 + FMC_OFFSET)) +#define FMC1 ((volatile UInt32*)((UInt32)FMI1 + FMC_OFFSET)) +#define FMC2 ((volatile UInt32*)((UInt32)FMI2 + FMC_OFFSET)) +#define FMC3 ((volatile UInt32*)((UInt32)FMI3 + FMC_OFFSET)) + +#define FMI_BA(offset) ((UInt32)(FMI_OFFSET + offset)) +#define FMC_BA(offset) ((UInt32)(FMC_OFFSET + offset)) +#define ECC_BA(offset) ((UInt32)(ECC_OFFSET + offset)) +#define CMD_BA(offset) ((UInt32)(CMD_OFFSET + offset)) + +#define FMI_CONFIG FMI_BA(0x00) +#define FMI_CONTROL FMI_BA(0x04) +#define FMI_STATUS FMI_BA(0x08) +#define FMI_INT_PEND FMI_BA(0x0C) +#define FMI_INT_EN FMI_BA(0x10) +#define FMI_DATA_BUF FMI_BA(0x14) +#define FMI_META_FIFO FMI_BA(0x18) +#define FMI_DEBUG0 FMI_BA(0x1C) +#define FMI_HW_VERSION FMI_BA(0x30) +#define FMI_DATA_SIZE FMI_BA(0x34) +#define FMI_RAW_PAGE_SIZE FMI_BA(0x38) +#define FMI_SCRAMBLER_SEED_FIFO FMI_BA(0x3C) +#define FMI_SEED_FIFO_LOW_LEVEL FMI_BA(0x40) +#define FMI_METADATA_FIFO_PTR FMI_BA(0x44) +#define FMI_SEED_FIFO_PTR FMI_BA(0x48) +#define FMI_RANDOMIZER_VERSION FMI_BA(0x4C) + +#define FMI_BUFFER_0_BASE FMI_BA(0x1000) +#define FMI_BUFFER_1_BASE FMI_BA(0x1800) +#define FMI_BUFFER_LEN (0x45F) +#define FMI_META_FIFO_BASE FMI_BA(0x2000) +#define FMI_META_FIFO_LENGTH (32) +#define FMI_SEED_FIFO_BASE FMI_BA(0x3000) +#define FMI_SEED_FIFO_LENGTH (8) +#define FMI_ECC_RESULT_FIFO_BASE FMI_BA(0x81000) +#define FMI_ECC_RESULT_FIFO_LENGTH (32) +#define FMI_ECC_PAGE_FIFO_BASE FMI_BA(0xC1000) +#define FMI_ECC_PAGE_FIFO_LENGTH (32) + +#define FMC_ON FMC_BA(0x00) +#define FMC_VER FMC_BA(0x04) +#define FMC_IF_CTRL FMC_BA(0x08) +#define FMC_CE_CTRL FMC_BA(0x0C) +#define FMC_RW_CTRL FMC_BA(0x10) +#define FMC_CMD FMC_BA(0x14) +#define FMC_ADDR0 FMC_BA(0x18) +#define FMC_ADDR1 FMC_BA(0x1C) +#define FMC_ADDRNUM FMC_BA(0x20) +#define FMC_DATANUM FMC_BA(0x24) +#define FMC_UNDEF0 FMC_BA(0x28) +#define FMC_UNDEF1 FMC_BA(0x2C) +#define FMC_TO_CTRL FMC_BA(0x30) +#define FMC_TO_CNT FMC_BA(0x34) +#define FMC_UNDEF2 FMC_BA(0x38) +#define FMC_UNDEF3 FMC_BA(0x3C) +#define FMC_INTMASK FMC_BA(0x40) +#define FMC_STATUS FMC_BA(0x44) +#define FMC_NAND_STATUS FMC_BA(0x48) +#define FMC_RBB_CONFIG FMC_BA(0x4C) +#define FMC_DQS_TIMING_CTRL FMC_BA(0x70) +#define FMC_TOGGLE_CTRL_1 FMC_BA(0x74) +#define FMC_TOGGLE_CTRL_2 FMC_BA(0x78) +#define FMC_TOGGLE_CTRL_3 FMC_BA(0x7C) + +#define ECC_VERSION ECC_BA(0x00) +#define ECC_CON0 ECC_BA(0x04) +#define ECC_CON1 ECC_BA(0x08) +#define ECC_RESULT ECC_BA(0x0C) +#define ECC_PND ECC_BA(0x10) +#define ECC_MASK ECC_BA(0x14) +#define ECC_HISTORY ECC_BA(0x18) +#define ECC_CORE_SW_RESET ECC_BA(0x1C) +#define ECC_PAGE_ERROR_FIFO ECC_BA(0x24) +#define ECC_PAGE_ERROR_FIFO_PTR ECC_BA(0x28) +#define ECC_RESULTS_FIFO_PTR ECC_BA(0x2C) + +#define COMMAND_FIFO CMD_BA(0x00) +#define COMMAND_FIFO_PTR CMD_BA(0x04) +#define COMMAND_FIFO_LOW CMD_BA(0x08) +#define COMMAND_COUNT CMD_BA(0x0C) +#define COMMAND_INT_CODE CMD_BA(0x10) +#define OPERAND_FIFO CMD_BA(0x14) +#define OPERAND_FIFO_PTR CMD_BA(0x18) +#define OPERAND_FIFO_LOW CMD_BA(0x1C) +#define SEQ_INT_PEND CMD_BA(0x20) +#define SEQ_INT_EN CMD_BA(0x24) +#define SEQ_MACRO_CONTROL CMD_BA(0x28) +#define TIMEOUT_VALUE CMD_BA(0x2C) + +#define STORE_FIFO CMD_BA(0x30) +#define STORE_FIFO_PTR CMD_BA(0x34) +#define STORE_FIFO_HIGH CMD_BA(0x38) + +#define SEQUENCER_MACROS(n) CMD_BA(0x1000 + ((n) & 0xFF)) +#define SEQUENCER_COMMANDS(n) CMD_BA(0x2000 + ((n) & 0x7F)) +#define SEQUENCER_OPERANDS(n) CMD_BA(0x3000 + ((n) & 0x7F)) +#define SEQUENCER_STORES(n) CMD_BA(0x4000 + ((n) & 0x7F)) + +// ============================================================================= +// FMI_CONFIG bitfields +// ============================================================================= + +#define FMI_CONFIG__DMA_BURST(n) (((n) & 0x7) << 0) +#define FMI_CONFIG__ECC_CORRECTABLE_BITS(m) (((m) & 0x1f) << 3) +#define FMI_CONFIG__META_DMA_BURST_SIZE(n) (((n) & 0x7) << 9) +#define FMI_CONFIG__META_DMA_BURST_WIDTH(n) (((n) & 0x3) << 12) +#define FMI_CONFIG__SCRAMBLE_SEED (0x1UL << 14) +#define FMI_CONFIG__ENABLE_WHITENING (0x1UL << 8) + +#define FMI_CONFIG__DMA_BURST__32_CYCLES FMI_CONFIG__DMA_BURST(5) +#define FMI_CONFIG__DMA_BURST__16_CYCLES FMI_CONFIG__DMA_BURST(4) +#define FMI_CONFIG__DMA_BURST__8_CYCLES FMI_CONFIG__DMA_BURST(3) +#define FMI_CONFIG__DMA_BURST__4_CYCLES FMI_CONFIG__DMA_BURST(2) +#define FMI_CONFIG__DMA_BURST__2_CYCLES FMI_CONFIG__DMA_BURST(1) +#define FMI_CONFIG__DMA_BURST__1_CYCLES FMI_CONFIG__DMA_BURST(0) + +#define FMI_CONFIG__META_DMA_BURST__32_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(5) +#define FMI_CONFIG__META_DMA_BURST__16_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(4) +#define FMI_CONFIG__META_DMA_BURST__8_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(3) +#define FMI_CONFIG__META_DMA_BURST__4_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(2) +#define FMI_CONFIG__META_DMA_BURST__2_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(1) +#define FMI_CONFIG__META_DMA_BURST__1_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(0) + +#define FMI_CONFIG__META_DMA_BURST__4_BYTES FMI_CONFIG__META_DMA_BURST_WIDTH(2) +#define FMI_CONFIG__META_DMA_BURST__2_BYTES FMI_CONFIG__META_DMA_BURST_WIDTH(1) +#define FMI_CONFIG__META_DMA_BURST__1_BYTES FMI_CONFIG__META_DMA_BURST_WIDTH(0) + +// ============================================================================= +// FMI_CONTROL bitfields +// ============================================================================= + +#define FMI_CONTROL__PAUSE_WHEN_STORE_FIFO_FULL (0x1UL << 14) +#define FMI_CONTROL__DISABLE_STREAMING (0x1UL << 13) +#define FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE (0x1UL << 12) +#define FMI_CONTROL__RESET_SEED (0x1UL << 11) +#define FMI_CONTROL__RAW_READ_MODE (0x1UL << 10) +#define FMI_CONTROL__RESET_SEQUENCER (0x1UL << 9) +#define FMI_CONTROL__ENABLE_SEQUENCER (0x1UL << 8) +#define FMI_CONTROL__ECC_PAUSE (0x1UL << 7) +#define FMI_CONTROL__BUFFER_1_LOCK(m) (((m) & 0x3) << 5) +#define FMI_CONTROL__BUFFER_0_LOCK(m) (((m) & 0x3) << 3) +#define FMI_CONTROL__MODE(m) (((m) & 0x3) << 1) +#define FMI_CONTROL__START_BIT (0x1UL << 0) + +#define FMI_CONTROL__MODE__IDLE FMI_CONTROL__MODE(0) +#define FMI_CONTROL__MODE__READ FMI_CONTROL__MODE(1) +#define FMI_CONTROL__MODE__WRITE FMI_CONTROL__MODE(2) +#define FMI_CONTROL__MODE__SOFTWARE_RESET FMI_CONTROL__MODE(3) + +#define FMI_CONTROL__BUFFER_0_LOCK_FREE FMI_CONTROL__BUFFER_0_LOCK(0) +#define FMI_CONTROL__BUFFER_0_LOCK_DMA FMI_CONTROL__BUFFER_0_LOCK(1) +#define FMI_CONTROL__BUFFER_0_LOCK_ECC FMI_CONTROL__BUFFER_0_LOCK(2) +#define FMI_CONTROL__BUFFER_0_LOCK_FMC FMI_CONTROL__BUFFER_0_LOCK(3) + +#define FMI_CONTROL_BUFFER_1_LOCK_FREE FMI_CONTROL__BUFFER_1_LOCK(0) +#define FMI_CONTROL_BUFFER_1_LOCK_DMA FMI_CONTROL__BUFFER_1_LOCK(1) +#define FMI_CONTROL_BUFFER_1_LOCK_ECC FMI_CONTROL__BUFFER_1_LOCK(2) +#define FMI_CONTROL_BUFFER_1_LOCK_FMC FMI_CONTROL__BUFFER_1_LOCK(3) + +// ============================================================================= +// FMI_STATUS bitfields +// ============================================================================= + +#define FMI_STATUS__FMC_ACTIVE (0x1UL << 3) +#define FMI_STATUS__ECC_ACTIVE (0x1UL << 2) +#define FMI_STATUS__DMA_ACTIVE (0x1UL << 1) +#define FMI_STATUS__BUS_ACTIVE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_PEND bitfields +// ============================================================================= + +#define FMI_INT_PEND__SEQUENCER_INTERRUPT (0x1UL << 28) +#define FMI_INT_PEND__SEED_FIFO_EMPTY (0x1UL << 27) +#define FMI_INT_PEND__SEED_FIFO_LOW (0x1UL << 26) +#define FMI_INT_PEND__SEED_FIFO_OVERFLOW (0x1UL << 25) +#define FMI_INT_PEND__ECC_RESULTS_FIFO_UNDERFLOW (0x1UL << 24) +#define FMI_INT_PEND__ECC_RESULTS_FIFO_OVERFLOW (0x1UL << 23) +#define FMI_INT_PEND__LAST_ECC_DONE (0x1UL << 22) +#define FMI_INT_PEND__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_PEND__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_PEND__ECC_DONE (0x1UL << 19) +#define FMI_INT_PEND__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_PEND__FMC_READY_BUSY(n) (((n) & 0xFF) << 10) +#define FMI_INT_PEND__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_PEND__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_PEND__FMC_NSERR (0x1UL << 7) +#define FMI_INT_PEND__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_PEND__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_PEND__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_PEND__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_PEND__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_PEND__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_PEND__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_EN bitfields +// ============================================================================= +#define FMI_INT_EN__SEQUENCER_INTERRUPT (0x1UL << 28) +#define FMI_INT_EN__SEED_FIFO_EMPTY (0x1UL << 27) +#define FMI_INT_EN__SEED_FIFO_LOW (0x1UL << 26) +#define FMI_INT_EN__SEED_FIFO_OVERFLOW (0x1UL << 25) +#define FMI_INT_EN__ECC_RESULTS_FIFO_UNDERFLOW (0x1UL << 24) +#define FMI_INT_EN__ECC_RESULTS_FIFO_OVERFLOW (0x1UL << 23) +#define FMI_INT_EN__LAST_ECC_DONE (0x1UL << 22) +#define FMI_INT_EN__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_EN__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_EN__ECC_DONE (0x1UL << 19) +#define FMI_INT_EN__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_EN__FMC_READY_BUSY (0x1UL << 10) +#define FMI_INT_EN__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_EN__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_EN__FMC_NSERR (0x1UL << 7) +#define FMI_INT_EN__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_EN__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_EN__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_EN__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_EN__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_EN__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_EN__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_DEBUG0 bitfields +// ============================================================================= + +#define FMI_DEBUG0__FMC_TASKS_PENDING(n) (((n) & 0x3) << 7) +#define FMI_DEBUG0__ECC_TASKS_PENDING(n) (((n) & 0x3) << 5) +#define FMI_DEBUG0__DMA_TASKS_PENDING(n) (((n) & 0x3) << 3) +#define FMI_DEBUG0__FMC_TARGET_BUFFER(b) (((b) & 0x1) << 2) +#define FMI_DEBUG0__ECC_TARGET_BUFFER(b) (((b) & 0x1) << 1) +#define FMI_DEBUG0__DMA_TARGET_BUFFER(b) (((b) & 0x1) << 0) + +// ============================================================================= +// FMI_DATA_SIZE bifields +// ============================================================================= + +#define FMI_DATA_SIZE__META_BYTES_PER_SECTOR(n) (((n) & 0x3F) << 25) +#define FMI_DATA_SIZE__META_BYTES_PER_PAGE(n) (((n) & 0x3F) << 19) +#define FMI_DATA_SIZE__BYTES_PER_SECTOR(n) (((n) & 0x7FF) << 8) +#define FMI_DATA_SIZE__SECTORS_PER_PAGE(n) (((n) & 0xFF) << 0) + +// ============================================================================= +// FMI_SEED_FIFO_LOW_LEVEL bitfields +// ============================================================================= + +#define FMI_SEED_FIFO_LOW_LEVEL__LEVEL(x) (((x) & 0x7) << 0) + +// ============================================================================= +// METADATA_FIFO_PTR bitfields +// ============================================================================= + +#define METADATA_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define METADATA_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define METADATA_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// SEED_FIFO_PTR bitfields +// ============================================================================= + +#define SEED_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x7) +#define SEED_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x7) +#define SEED_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0xF) + +// ============================================================================= +// FMC_ON bitfields +// ============================================================================= + +#define FMC_ON__SWRST (0x1UL << 8) +#define FMC_ON__ASYNC_DRIVE_DQS (0x1UL << 6) +#define FMC_ON__ASYNC_CEB_AUTO_DISABLE (0x1UL << 5) +#define FMC_ON__DDR_NAND_TYPE_TOGGLE (0x0UL << 3) +#define FMC_ON__DDR_NAND_TYPE_ONFI (0x1UL << 3) +#define FMC_ON__DDR_ENABLE (0x1UL << 2) +#define FMC_ON__CLKGATING_RDY (0x1UL << 1) +#define FMC_ON__ENABLE (0x1UL << 0) +#define FMC_ON__DISABLE (!FMC_ON__ENABLE) + +// ============================================================================= +// FMC_IF_CTRL bitfields +// ============================================================================= + +#define FMC_IF_CTRL__WPB (0x1UL << 21) +#define FMC_IF_CTRL__RBBEN (0x1UL << 20) +#define FMC_IF_CTRL__DCCYCLE(v) (((v) & 0xF) << 16) +#define FMC_IF_CTRL__REB_SETUP(v) (((v) & 0xF) << 12) +#define FMC_IF_CTRL__REB_HOLD(v) (((v) & 0xF) << 8) +#define FMC_IF_CTRL__WEB_SETUP(v) (((v) & 0xF) << 4) +#define FMC_IF_CTRL__WEB_HOLD(v) (((v) & 0xF) << 0) +#define FMC_IF_CTRL__GET_DCCYCLE(v) (((v) & 0xF0000) >> 16) +#define FMC_IF_CTRL__GET_REB_SETUP(v) (((v) & 0x0F000) >> 12) +#define FMC_IF_CTRL__GET_REB_HOLD(v) (((v) & 0x00F00) >> 8) +#define FMC_IF_CTRL__GET_WEB_SETUP(v) (((v) & 0x000F0) >> 4) +#define FMC_IF_CTRL__GET_WEB_HOLD(v) (((v) & 0x0000F) >> 0) + +#define FMC_IF_CTRL__REB_SETUP_MASK (0x0000000F << 12) + +#define FMC_IF_CTRL__TIMING_MAX_CLOCKS (0xFUL) + +// ============================================================================= +// FMC_CE_CTRL bitfields +// ============================================================================= + +#define FMC_CE_CTRL__CE_COUNT (8) +#define FMC_CE_CTRL__CEB(n) (0x1UL << ((n) & 0x7)) + +#define FMC_CE_CTRL__CEB7 FMC_CE_CTRL__CEB(7) +#define FMC_CE_CTRL__CEB6 FMC_CE_CTRL__CEB(6) +#define FMC_CE_CTRL__CEB5 FMC_CE_CTRL__CEB(5) +#define FMC_CE_CTRL__CEB4 FMC_CE_CTRL__CEB(4) +#define FMC_CE_CTRL__CEB3 FMC_CE_CTRL__CEB(3) +#define FMC_CE_CTRL__CEB2 FMC_CE_CTRL__CEB(2) +#define FMC_CE_CTRL__CEB1 FMC_CE_CTRL__CEB(1) +#define FMC_CE_CTRL__CEB0 FMC_CE_CTRL__CEB(0) + +// ============================================================================= +// FMC_RW_CTRL bitfields +// ============================================================================= + +#define FMC_RW_CTRL__NAND_TIMING_USER_TAT(x) (((x) & 0xFF) << 24) +#define FMC_RW_CTRL__CMD1_5_MODE (0x1UL << 9) +#define FMC_RW_CTRL__WAIT_NSRBB_FLD (0x1UL << 8) +#define FMC_RW_CTRL__RD_DONE_REB_CEB_HOLD (0x1UL << 7) +#define FMC_RW_CTRL__REBHOLD (0x1UL << 6) +#define FMC_RW_CTRL__WR_MODE (0x1UL << 5) +#define FMC_RW_CTRL__RD_MODE (0x1UL << 4) +#define FMC_RW_CTRL__ADDR_MODE (0x1UL << 3) +#define FMC_RW_CTRL__CMD3_MODE (0x1UL << 2) +#define FMC_RW_CTRL__CMD2_MODE (0x1UL << 1) +#define FMC_RW_CTRL__CMD1_MODE (0x1UL << 0) + +// ============================================================================= +// FMC_CMD bitfields +// ============================================================================= + +#define FMC_CMD__CMD1_5(c) (((c) & 0xFF) << 24) +#define FMC_CMD__CMD3(c) (((c) & 0xFF) << 16) +#define FMC_CMD__CMD2(c) (((c) & 0xFF) << 8) +#define FMC_CMD__CMD1(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR0 bitfields +// ============================================================================= + +#define FMC_ADDR0__SEQ3(a) (((a) & 0xFF) << 24) +#define FMC_ADDR0__SEQ2(a) (((a) & 0xFF) << 16) +#define FMC_ADDR0__SEQ1(a) (((a) & 0xFF) << 8) +#define FMC_ADDR0__SEQ0(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR1 bitfields +// ============================================================================= + +#define FMC_ADDR1__SEQ7(a) (((a) & 0xFF) << 24) +#define FMC_ADDR1__SEQ6(a) (((a) & 0xFF) << 16) +#define FMC_ADDR1__SEQ5(a) (((a) & 0xFF) << 8) +#define FMC_ADDR1__SEQ4(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDRNUM bitfields +// ============================================================================= + +#define FMC_ADDRNUM__NUM(n) (((n) & 0x7) << 0) + +// ============================================================================= +// FMC_DATANUM bitfields +// ============================================================================= + +#define FMC_DATANUM__NUM(n) (((n) & 0x3FF) << 0) + +// ============================================================================= +// FMC_TO_CTRL bitfields +// ============================================================================= + +#define FMC_TO_CTRL__EN (0x1UL << 12) +#define FMC_TO_CTRL__DIV(d) (((d) & 0xF) << 8) +#define FMC_TO_CTRL__VAL(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_TO_CNT bitfields +// ============================================================================= + +#define FMC_TO_CNT__CNT(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_INTMASK bitfields +// ============================================================================= + +#define FMC_INTMASK__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_INTMASK__CMD1_5DONE (0x1UL << 17) +#define FMC_INTMASK__RBBDONE7 FMC_INTMASK__RBBDONE(7) +#define FMC_INTMASK__RBBDONE6 FMC_INTMASK__RBBDONE(6) +#define FMC_INTMASK__RBBDONE5 FMC_INTMASK__RBBDONE(5) +#define FMC_INTMASK__RBBDONE4 FMC_INTMASK__RBBDONE(4) +#define FMC_INTMASK__RBBDONE3 FMC_INTMASK__RBBDONE(3) +#define FMC_INTMASK__RBBDONE2 FMC_INTMASK__RBBDONE(2) +#define FMC_INTMASK__RBBDONE1 FMC_INTMASK__RBBDONE(1) +#define FMC_INTMASK__RBBDONE0 FMC_INTMASK__RBBDONE(0) +#define FMC_INTMASK__TIMEOUT (0x1UL << 7) +#define FMC_INTMASK__NSERR (0x1UL << 6) +#define FMC_INTMASK__NSRBBDONE (0x1UL << 5) +#define FMC_INTMASK__TRANSDONE (0x1UL << 4) +#define FMC_INTMASK__ADDRESSDONE (0x1UL << 3) +#define FMC_INTMASK__CMD3DONE (0x1UL << 2) +#define FMC_INTMASK__CMD2DONE (0x1UL << 1) +#define FMC_INTMASK__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_STATUS bitfields +// ============================================================================= + +#define FMC_STATUS__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_STATUS__EMERGENCY2 (0x1UL << 21) +#define FMC_STATUS__EMERGENCY01 (0x1UL << 20) +#define FMC_STATUS__RDATADIRTY (0x1UL << 16) +#define FMC_STATUS__RBBDONE7 FMC_STATUS__RBBDONE(7) +#define FMC_STATUS__RBBDONE6 FMC_STATUS__RBBDONE(6) +#define FMC_STATUS__RBBDONE5 FMC_STATUS__RBBDONE(5) +#define FMC_STATUS__RBBDONE4 FMC_STATUS__RBBDONE(4) +#define FMC_STATUS__RBBDONE3 FMC_STATUS__RBBDONE(3) +#define FMC_STATUS__RBBDONE2 FMC_STATUS__RBBDONE(2) +#define FMC_STATUS__RBBDONE1 FMC_STATUS__RBBDONE(1) +#define FMC_STATUS__RBBDONE0 FMC_STATUS__RBBDONE(0) +#define FMC_STATUS__TIMEOUT (0x1UL << 7) +#define FMC_STATUS__NSERR (0x1UL << 6) +#define FMC_STATUS__NSRBBDONE (0x1UL << 5) +#define FMC_STATUS__TRANSDONE (0x1UL << 4) +#define FMC_STATUS__ADDRESSDONE (0x1UL << 3) +#define FMC_STATUS__CMD3DONE (0x1UL << 2) +#define FMC_STATUS__CMD2DONE (0x1UL << 1) +#define FMC_STATUS__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_RBB_CONFIG bitfields +// ============================================================================= + +#define FMC_RBB_CONFIG__POL(v) (((v) & 0xFF) << 8) +#define FMC_RBB_CONFIG__POS(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_DQS_TIMING_CTRL bitfields +// ============================================================================= + +#define FMC_DQS_TIMING_CTRL__USE_DLL (0x1UL << 31) +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL(x) (((x) & 0x1FF) << 16) +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL_GET(x) (((x) & 0x01FF0000) >> 16) +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_COARSE_CTRL(x) (((x) & 0x7F) << 18) +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_FINE_CTRL(x) (((x) & 0x3) << 16) +#define FMC_DQS_TIMING_CTRL__DQS_WRITE_DELAY_TIMING(x) (((x) & 0xF) << 0) + +#define FMC_DQS_TIMING_CTRL__DEFAULT_VAL (0x00800000) + +// ============================================================================= +// FMC_TOGGLE_CTRL_1 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_1_DDR_RD_PRE_TIME(x) (((x) & 0xFF) << 24) +#define FMC_TOGGLE_CTRL_1_DDR_RD_POST_TIME(x) (((x) & 0xFF) << 16) +#define FMC_TOGGLE_CTRL_1_DDR_WR_PRE_TIME(x) (((x) & 0xFF) << 8) +#define FMC_TOGGLE_CTRL_1_DDR_WR_POST_TIME(x) (((x) & 0xFF) << 0) + +#define FMC_TOGGLE_CTRL_1__TIMING_MAX_CLOCKS (0xFF) + +// ============================================================================= +// FMC_TOGGLE_CTRL_2 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_2_CE_SETUP_TIME(x) (((x) & 0xFF) << 24) +#define FMC_TOGGLE_CTRL_2_CE_HOLD_TIME(x) (((x) & 0xFF) << 16) +#define FMC_TOGGLE_CTRL_2_NAND_TIMING_ADL(x) (((x) & 0xFF) << 8) +#define FMC_TOGGLE_CTRL_2_NAND_TIMING_WHR(x) (((x) & 0xFF) << 0) + +#define FMC_TOGGLE_CTRL_2__TIMING_MAX_CLOCKS (0xFF) + +// ============================================================================= +// FMC_TOGGLE_CTRL_2 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_3_ONFI_WR_CLK_STOP_EN (0x1UL << 31) +#define FMC_TOGGLE_CTRL_3_DISABLE_ONFI_READ_STATUS_CLE_ALE_HOLD (0x1UL << 30) +#define FMC_TOGGLE_CTRL_3_DISABLE_ONFI_ONFI_IDLE_CLOCK_ON (0x1UL << 29) +#define FMC_TOGGLE_CTRL_3_ONFI_TIMING_CAD (((x) & 0xF) << 0) + +// ============================================================================= +// ECC_CON0 bitfields +// ============================================================================= + +#define ECC_CON0__INFORMATION_LENGTH(n) (((n) & 0x7FF) << 16) +#define ECC_CON0__ECC_CORRECTION_MODE(m) (((m) & 0x1F) << 4) +#define ECC_CON0__START_ENC (0x1UL << 1) +#define ECC_CON0__START_DEC (0x1UL << 0) + +// ============================================================================= +// ECC_CON1 bitfields +// ============================================================================= +#define ECC_CON1__IMPLICIT_WRITE_MARK (1UL << 31) +#define ECC_CON1__SLAVE_MODE (1UL << 29) +#define ECC_CON1__SKIP_FREE_PAGE_FLD (1UL << 25) +#define ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(n) (((n) & 0x1F) << 16) +#define ECC_CON1__ERROR_ALERT_LEVEL(n) (((n) & 0x1F) << 8) +#define ECC_CON1__INT_ENABLE(b) (((b) & 0x1) << 7) + +#define ECC_CON1__INT_ENABLE__ENABLE ECC_CON1__INT_ENABLE(1) +#define ECC_CON1__INT_ENABLE__DISABLE ECC_CON1__INT_ENABLE(0) + +// ============================================================================= +// ECC_RESULT bitfields +// ============================================================================= + +#define ECC_RESULT__ERROR_ALERT (0x1UL << 21) +#define ECC_RESULT__ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_RESULT__ERROR_CNT_SHIFT (16) +#define ECC_RESULT__ERROR_CNT_MASK (0x1FUL << ECC_RESULT__ERROR_CNT_SHIFT) +#define ECC_RESULT__STUCK_BIT_EXCEEDED (0x1UL << 14) +#define ECC_RESULT__STUCK_BIT_CNT(n) (((n) & 0x3F) << 8) +#define ECC_RESULT__DECODED_BUFFER_IDX (0x1UL << 6) +#define ECC_RESULT__ALL_FF (0x1UL << 3) +#define ECC_RESULT__ALL_ZERO (0x1UL << 2) +#define ECC_RESULT__FREE_PAGE (0x1UL << 1) +#define ECC_RESULT__UNCORRECTABLE (0x1UL << 0) +#define ECC_RESULT__FIFO_RESET (0x1UL << 0) // Same as uncorrectable bit + +// ============================================================================= +// ECC_PND bitfields +// ============================================================================= + +#define ECC_PND__MAX_STUCK_BIT_CNT(n) (((n) & 0x3F) << 24) +#define ECC_PND__MAX_ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_PND__MAX_ERROR_CNT_SHIFT (16) +#define ECC_PND__MAX_ERROR_CNT_MASK (0x1FUL << ECC_PND__MAX_ERROR_CNT_SHIFT) +#define ECC_PND__DETECTOR_DONE (0x1UL << 14) +#define ECC_PND__B1_DEC_DONE (0x1UL << 13) +#define ECC_PND__B0_DEC_DONE (0x1UL << 12) +#define ECC_PND__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_PND__SOME_ALL_FF (0x1UL << 8) +#define ECC_PND__SOME_ALL_ZERO (0x1UL << 7) +#define ECC_PND__ALL_FREE_PAGE (0x1UL << 6) +#define ECC_PND__SOME_ERROR_ALERT (0x1UL << 5) +#define ECC_PND__READY_BUSY (0x1UL << 4) +#define ECC_PND__ANY_UNCORRECTABLE (0x1UL << 3) +#define ECC_PND__ENC_DONE (0x1UL << 2) +#define ECC_PND__DEC_DONE (0x1UL << 1) +#define ECC_PND__ENC_DEC_DONE (0x1UL << 0) + +// ============================================================================= +// ECC_MASK bitfields +// ============================================================================= + +#define ECC_MASK__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_MASK__SOME_ALL_FF_MASK (0x1UL << 8) +#define ECC_MASK__SOME_ALL_ZERO_MASK (0x1UL << 7) +#define ECC_MASK__SOME_ERROR_ALERT_MASK (0x1UL << 5) +#define ECC_MASK__ANY_UNCORRECTABLE_MASK (0x1UL << 3) +#define ECC_MASK__ENC_DONE_MASK (0x1UL << 2) +#define ECC_MASK__DEC_DONE_MASK (0x1UL << 1) +#define ECC_MASK__ENC_DEC_DONE_MASK (0x1UL << 0) + +// ============================================================================= +// ECC_HISTORY bitfields +// ============================================================================= + +#define ECC_HISTORY__ERROR_COUNT_CLEAR (0x1UL << 26) +#define ECC_HISTORY__ERROR_COUNT(n) (((n) & 0x7FFF) << 11) +#define ECC_HISTORY__DECODING_NUMBER_CLEAR (0x1UL << 10) +#define ECC_HISTORY__DECODING_NUMBER(n) (((n) & 0x1FF) << 0) + +// ============================================================================= +// RESULT_FIFO_PTR bitfields +// ============================================================================= + +#define ECC_RESULTS_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define ECC_RESULTS_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define ECC_RESULTS_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// COMMAND_FIFO bitfields +// ============================================================================= + +#define COMMAND_FIFO_SIZE (32) +#define OPERAND_FIFO_SIZE (32) +#define STORE_FIFO_SIZE (32) + +#define COMMAND_FIFO__COMMAND(cmd) ((cmd) << 24) +#define COMMAND_FIFO__OPERAND(op) (((op) & 0xFFFFFF) << 0) + +#define OPCODE_ADDR(n) (n) +#define OPCODE_COMMAND (0x08) +#define OPCODE_ENABLE_CE (0x09) +#define OPCODE_WAIT_FOR_READY (0x0A) +#define OPCODE_TX_PAGE (0x0B) +#define OPCODE_SEND_INTERRUPT (0x0C) +#define OPCODE_PAUSE (0x0D) +#define OPCODE_TIMED_WAIT (0x0E) +#define OPCODE_LOAD_NEXT_WORD (0x0F) +#define OPCODE_LOAD_FROM_FIFO (0x10) +#define OPCODE_MACRO (0x11) +#define OPCODE_POLL (0x12) +#define OPCODE_WAIT_FOR_INT (0x13) +#define OPCODE_STORE_TO_FIFO (0x14) + +#define CMD_ADDRESS(bytes, addr) (COMMAND_FIFO__COMMAND(OPCODE_ADDR(bytes)) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFFF)) + +#define CMD_COMMAND(cmd) (COMMAND_FIFO__COMMAND(OPCODE_COMMAND) | \ + COMMAND_FIFO__OPERAND((cmd) & 0xFF)) + +#define CMD_ENABLE_CHIP(mask) (COMMAND_FIFO__COMMAND(OPCODE_ENABLE_CE) | \ + COMMAND_FIFO__OPERAND((mask) & 0xFF)) + +#define CMD_WAIT_FOR_READY(code,mask,cond) (COMMAND_FIFO__COMMAND(OPCODE_WAIT_FOR_READY) | \ + COMMAND_FIFO__OPERAND((code) << 16 | (mask) << 8 | (cond) << 0)) + +#define CMD_TX_PAGE (COMMAND_FIFO__COMMAND(OPCODE_TX_PAGE)) + +#define CMD_SEND_INTERRUPT(code) (COMMAND_FIFO__COMMAND(OPCODE_SEND_INTERRUPT) | \ + COMMAND_FIFO__OPERAND(code)) + +#define CMD_PAUSE (COMMAND_FIFO__COMMAND(OPCODE_PAUSE)) + +#define CMD_TIMED_WAIT(clks) (COMMAND_FIFO__COMMAND(OPCODE_TIMED_WAIT) | \ + COMMAND_FIFO__OPERAND(clks)) + +#define CMD_LOAD_NEXT_WORD(addr) (COMMAND_FIFO__COMMAND(OPCODE_LOAD_NEXT_WORD) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_LOAD_FROM_FIFO(addr) (COMMAND_FIFO__COMMAND(OPCODE_LOAD_FROM_FIFO) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_MACRO(seq,len) (COMMAND_FIFO__COMMAND(OPCODE_MACRO) | \ + COMMAND_FIFO__OPERAND(((seq) << 8) | (len))) + +#define CMD_POLL(addr) (COMMAND_FIFO__COMMAND(OPCODE_POLL) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_WAIT_FOR_INT(irq,bit) (COMMAND_FIFO__COMMAND(OPCODE_WAIT_FOR_INT) | \ + COMMAND_FIFO__OPERAND((irq) << 8 | (bit) << 0)) + +#define CMD_STORE_TO_FIFO(reg) (COMMAND_FIFO__COMMAND(OPCODE_STORE_TO_FIFO) | \ + COMMAND_FIFO__OPERAND((reg) & 0xFFFFF)) + + +// ============================================================================= +// COMMAND_FIFO_PTR bitfields +// ============================================================================= + +#define COMMAND_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define COMMAND_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define COMMAND_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// COMMAND_FIFO_LOW bitfields +// ============================================================================= + +#define COMMAND_FIFO_LOW__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// COMMAND_COUNT bitfields +// ============================================================================= + +#define COMMAND_COUNT__MAX_COUNT (32) + +// ============================================================================= +// COMMAND_INT_CODE bitfields +// ============================================================================= + +#define COMMAND_INT_CODE__READ(regval) ((regval) & 0xFFFFFF) +#define COMMAND_INT_CODE__WAIT_FOR_READY_CODE(regval) ((regval >> 16) & 0xFF) +#define COMMAND_INT_CODE__WAIT_FOR_READY_STATUS(regval) ((regval >> 0) & 0xFF) + +// ============================================================================= +// OPERAND_FIFO_PTR bitfields +// ============================================================================= + +#define OPERAND_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define OPERAND_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define OPERAND_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// OPERAND_FIFO_LOW bitfields +// ============================================================================= + +#define OPERAND_FIFO_LOW__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// STORE_FIFO_PTR bitfields +// ============================================================================= + +#define STORE_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define STORE_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define STORE_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// STORE_FIFO_HIGH bitfields +// ============================================================================= + +#define STORE_FIFO_HIGH__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// SEQ_INT_PEND bitfields +// ============================================================================= + +#define SEQ_INT_PEND__STORE_FIFO_FULL (0x1UL << 10) +#define SEQ_INT_PEND__STORE_FIFO_HIGH (0x1UL << 9) +#define SEQ_INT_PEND__STORE_FIFO_OVERFLOW (0x1UL << 8) +#define SEQ_INT_PEND__TIMEOUT (0x1UL << 7) +#define SEQ_INT_PEND__OPERAND_FIFO_EMPTY (0x1UL << 6) +#define SEQ_INT_PEND__OPERAND_FIFO_LOW (0x1UL << 5) +#define SEQ_INT_PEND__OPERAND_FIFO_OVERFLOW (0x1UL << 4) +#define SEQ_INT_PEND__COMMAND_FIFO_EMPTY (0x1UL << 3) +#define SEQ_INT_PEND__COMMAND_FIFO_LOW (0x1UL << 2) +#define SEQ_INT_PEND__COMMAND_FIFO_OVERFLOW (0x1UL << 1) +#define SEQ_INT_PEND__SEQUENCER_SIGNAL (0x1UL << 0) + +// ============================================================================= +// SEQ_INT_EN bitfields +// ============================================================================= + +#define SEQ_INT_EN__TIMEOUT (0x1UL << 7) +#define SEQ_INT_EN__OPERAND_FIFO_EMPTY (0x1UL << 6) +#define SEQ_INT_EN__OPERAND_FIFO_LOW (0x1UL << 5) +#define SEQ_INT_EN__OPERAND_FIFO_OVERFLOW (0x1UL << 4) +#define SEQ_INT_EN__COMMAND_FIFO_EMPTY (0x1UL << 3) +#define SEQ_INT_EN__COMMAND_FIFO_LOW (0x1UL << 2) +#define SEQ_INT_EN__COMMAND_FIFO_OVERFLOW (0x1UL << 1) +#define SEQ_INT_EN__SEQUENCER_SIGNAL (0x1UL << 0) + +// ============================================================================= +// SEQ_MACRO_CONTROL bitfields +// ============================================================================= + +#define SEQ_MACRO_CONTROL__WORD_COUNT(cnt) (((cnt) & 0x3F) << 8) +#define SEQ_MACRO_CONTROL__MACRO_ADDRESS(addr) (((addr) & 0x3F) << 0) +#define SEQ_MACRO_CONTROL__GET_WORD_COUNT(regval) (((regval) >> 8) & 0x3F) +#define SEQ_MACRO_CONTROL__GET_MACRO_ADDRESS(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// SoC-Specific Tuning +// ============================================================================= + +#define FMI_TX_PROP_DELAY_NS (7) +#define FMI_RX_PROP_DELAY_NS (5) + +#define FMI_USE_WRITE_CYCLE_BALANCING (1) + +#endif // _H2FMI_8945REGS_H_ + +// ********************************** EOF ************************************* diff --git a/drivers/apple/h2fmi/H2fmi_8950regs.h b/drivers/apple/h2fmi/H2fmi_8950regs.h new file mode 100644 index 0000000..38e506e --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_8950regs.h @@ -0,0 +1,840 @@ +// ***************************************************************************** +// +// File: H2fmi_regs.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position +// +// - consider adding definitions for extracting value from register position +// +// ***************************************************************************** +// +// Copyright (C) 2010 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "WMRFeatures.h" +#if defined(H2FMI_EFI) && H2FMI_EFI +#include "SoC.h" +#else +#include +#endif + +#include + +#ifndef _H2FMI_8945REGS_H_ +#define _H2FMI_8945REGS_H_ +// ============================================================================= +// register bases and offsets +// ============================================================================= + +#define FMI0 ((UInt32*)FMI0_BASE_ADDR) +#define FMI1 ((UInt32*)FMI1_BASE_ADDR) + +#define FMI_OFFSET (0x00000) +#define FMC_OFFSET (0x40000) +#define ECC_OFFSET (0x80000) +#define CMD_OFFSET (0xC0000) + +#define FMC0 ((volatile UInt32*)((UInt32)FMI0 + FMC_OFFSET)) +#define FMC1 ((volatile UInt32*)((UInt32)FMI1 + FMC_OFFSET)) + +#define FMI_BA(offset) ((UInt32)(FMI_OFFSET + offset)) +#define FMC_BA(offset) ((UInt32)(FMC_OFFSET + offset)) +#define ECC_BA(offset) ((UInt32)(ECC_OFFSET + offset)) +#define CMD_BA(offset) ((UInt32)(CMD_OFFSET + offset)) +#define NAND_DLL_REG(offset) ((volatile UInt32*)(NAND_DLL_BASE_ADDR + (offset))) + +#define FMI_CONFIG FMI_BA(0x00) +#define FMI_CONTROL FMI_BA(0x04) +#define FMI_STATUS FMI_BA(0x08) +#define FMI_INT_PEND FMI_BA(0x0C) +#define FMI_INT_EN FMI_BA(0x10) +#define FMI_DATA_BUF FMI_BA(0x14) +#define FMI_META_FIFO FMI_BA(0x18) +#define FMI_DEBUG0 FMI_BA(0x1C) +#define FMI_HW_VERSION FMI_BA(0x30) +#define FMI_DATA_SIZE FMI_BA(0x34) +#define FMI_RAW_PAGE_SIZE FMI_BA(0x38) +#define FMI_SCRAMBLER_SEED_FIFO FMI_BA(0x3C) +#define FMI_SEED_FIFO_LOW_LEVEL FMI_BA(0x40) +#define FMI_METADATA_FIFO_PTR FMI_BA(0x44) +#define FMI_SEED_FIFO_PTR FMI_BA(0x48) +#define FMI_RANDOMIZER_VERSION FMI_BA(0x4C) + +#define FMI_BUFFER_0_BASE FMI_BA(0x1000) +#define FMI_BUFFER_1_BASE FMI_BA(0x1800) +#define FMI_BUFFER_LEN (0x45F) +#define FMI_META_FIFO_BASE FMI_BA(0x2000) +#define FMI_META_FIFO_LENGTH (32) +#define FMI_SEED_FIFO_BASE FMI_BA(0x3000) +#define FMI_SEED_FIFO_LENGTH (8) +#define FMI_ECC_RESULT_FIFO_BASE FMI_BA(0x81000) +#define FMI_ECC_RESULT_FIFO_LENGTH (32) +#define FMI_ECC_PAGE_FIFO_BASE FMI_BA(0xC1000) +#define FMI_ECC_PAGE_FIFO_LENGTH (32) + +#define FMC_ON FMC_BA(0x00) +#define FMC_VER FMC_BA(0x04) +#define FMC_IF_CTRL FMC_BA(0x08) +#define FMC_CE_CTRL FMC_BA(0x0C) +#define FMC_RW_CTRL FMC_BA(0x10) +#define FMC_CMD FMC_BA(0x14) +#define FMC_ADDR0 FMC_BA(0x18) +#define FMC_ADDR1 FMC_BA(0x1C) +#define FMC_ADDRNUM FMC_BA(0x20) +#define FMC_DATANUM FMC_BA(0x24) +#define FMC_UNDEF0 FMC_BA(0x28) +#define FMC_UNDEF1 FMC_BA(0x2C) +#define FMC_TO_CTRL FMC_BA(0x30) +#define FMC_TO_CNT FMC_BA(0x34) +#define FMC_UNDEF2 FMC_BA(0x38) +#define FMC_UNDEF3 FMC_BA(0x3C) +#define FMC_INTMASK FMC_BA(0x40) +#define FMC_STATUS FMC_BA(0x44) +#define FMC_NAND_STATUS FMC_BA(0x48) +#define FMC_RBB_CONFIG FMC_BA(0x4C) +#define FMC_DQS_TIMING_CTRL FMC_BA(0x70) +#define FMC_TOGGLE_CTRL_1 FMC_BA(0x74) +#define FMC_TOGGLE_CTRL_2 FMC_BA(0x78) +#define FMC_TOGGLE_CTRL_3 FMC_BA(0x7C) + +#define ECC_VERSION ECC_BA(0x00) +#define ECC_CON0 ECC_BA(0x04) +#define ECC_CON1 ECC_BA(0x08) +#define ECC_RESULT ECC_BA(0x0C) +#define ECC_PND ECC_BA(0x10) +#define ECC_MASK ECC_BA(0x14) +#define ECC_HISTORY ECC_BA(0x18) +#define ECC_CORE_SW_RESET ECC_BA(0x1C) +#define ECC_PAGE_ERROR_FIFO ECC_BA(0x24) +#define ECC_PAGE_ERROR_FIFO_PTR ECC_BA(0x28) +#define ECC_RESULTS_FIFO_PTR ECC_BA(0x2C) + +#define COMMAND_FIFO CMD_BA(0x00) +#define COMMAND_FIFO_PTR CMD_BA(0x04) +#define COMMAND_FIFO_LOW CMD_BA(0x08) +#define COMMAND_COUNT CMD_BA(0x0C) +#define COMMAND_INT_CODE CMD_BA(0x10) +#define OPERAND_FIFO CMD_BA(0x14) +#define OPERAND_FIFO_PTR CMD_BA(0x18) +#define OPERAND_FIFO_LOW CMD_BA(0x1C) +#define SEQ_INT_PEND CMD_BA(0x20) +#define SEQ_INT_EN CMD_BA(0x24) +#define SEQ_MACRO_CONTROL CMD_BA(0x28) +#define TIMEOUT_VALUE CMD_BA(0x2C) +#define STORE_FIFO CMD_BA(0x30) +#define STORE_FIFO_PTR CMD_BA(0x34) +#define STORE_FIFO_HIGH CMD_BA(0x38) + +#define SEQUENCER_MACROS(n) CMD_BA(0x1000 + ((n) & 0xFF)) +#define SEQUENCER_COMMANDS(n) CMD_BA(0x2000 + ((n) & 0x7F)) +#define SEQUENCER_OPERANDS(n) CMD_BA(0x3000 + ((n) & 0x7F)) +#define SEQUENCER_STORES(n) CMD_BA(0x4000 + ((n) & 0x7F)) + +#define NAND_DLL_CONTROL NAND_DLL_REG(0x00) +#define NAND_DLL_TIMEOUT_DELAY NAND_DLL_REG(0x04) +#define NAND_DLL_STATUS NAND_DLL_REG(0x08) +#define NAND_DLL_FORCE_VALUE NAND_DLL_REG(0x0C) + +#define h2fmi_dll_wr(reg, val) (*(reg) = (val)) +#define h2fmi_dll_rd(reg) (*(reg)) + +// ============================================================================= +// FMI_CONFIG bitfields +// ============================================================================= + +#define FMI_CONFIG__DMA_BURST(n) (((n) & 0x7) << 0) +#define FMI_CONFIG__META_DMA_BURST_SIZE(n) (((n) & 0x7) << 9) +#define FMI_CONFIG__META_DMA_BURST_WIDTH(n) (((n) & 0x3) << 12) +#define FMI_CONFIG__ECC_CORRECTABLE_BITS(m) (((m) & 0x1f) << 3) +#define FMI_CONFIG__SCRAMBLE_SEED (0x1UL << 14) +#define FMI_CONFIG__ENABLE_WHITENING (0x1UL << 8) + +#define FMI_CONFIG__DMA_BURST__32_CYCLES FMI_CONFIG__DMA_BURST(5) +#define FMI_CONFIG__DMA_BURST__16_CYCLES FMI_CONFIG__DMA_BURST(4) +#define FMI_CONFIG__DMA_BURST__8_CYCLES FMI_CONFIG__DMA_BURST(3) +#define FMI_CONFIG__DMA_BURST__4_CYCLES FMI_CONFIG__DMA_BURST(2) +#define FMI_CONFIG__DMA_BURST__2_CYCLES FMI_CONFIG__DMA_BURST(1) +#define FMI_CONFIG__DMA_BURST__1_CYCLES FMI_CONFIG__DMA_BURST(0) + +#define FMI_CONFIG__META_DMA_BURST__32_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(5) +#define FMI_CONFIG__META_DMA_BURST__16_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(4) +#define FMI_CONFIG__META_DMA_BURST__8_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(3) +#define FMI_CONFIG__META_DMA_BURST__4_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(2) +#define FMI_CONFIG__META_DMA_BURST__2_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(1) +#define FMI_CONFIG__META_DMA_BURST__1_CYCLES FMI_CONFIG__META_DMA_BURST_SIZE(0) + +#define FMI_CONFIG__META_DMA_BURST__4_BYTES FMI_CONFIG__META_DMA_BURST_WIDTH(2) +#define FMI_CONFIG__META_DMA_BURST__2_BYTES FMI_CONFIG__META_DMA_BURST_WIDTH(1) +#define FMI_CONFIG__META_DMA_BURST__1_BYTES FMI_CONFIG__META_DMA_BURST_WIDTH(0) + +// ============================================================================= +// FMI_CONTROL bitfields +// ============================================================================= + +#define FMI_CONTROL__PAUSE_WHEN_STORE_FIFO_FULL (0x1UL << 14) +#define FMI_CONTROL__DISABLE_STREAMING (0x1UL << 13) +#define FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE (0x1UL << 12) +#define FMI_CONTROL__RESET_SEED (0x1UL << 11) +#define FMI_CONTROL__RAW_READ_MODE (0x1UL << 10) +#define FMI_CONTROL__RESET_SEQUENCER (0x1UL << 9) +#define FMI_CONTROL__ENABLE_SEQUENCER (0x1UL << 8) +#define FMI_CONTROL__ECC_PAUSE (0x1UL << 7) +#define FMI_CONTROL__BUFFER_1_LOCK(m) (((m) & 0x3) << 5) +#define FMI_CONTROL__BUFFER_0_LOCK(m) (((m) & 0x3) << 3) +#define FMI_CONTROL__MODE(m) (((m) & 0x3) << 1) +#define FMI_CONTROL__START_BIT (0x1UL << 0) + +#define FMI_CONTROL__MODE__IDLE FMI_CONTROL__MODE(0) +#define FMI_CONTROL__MODE__READ FMI_CONTROL__MODE(1) +#define FMI_CONTROL__MODE__WRITE FMI_CONTROL__MODE(2) +#define FMI_CONTROL__MODE__SOFTWARE_RESET FMI_CONTROL__MODE(3) + +#define FMI_CONTROL__BUFFER_0_LOCK_FREE FMI_CONTROL__BUFFER_0_LOCK(0) +#define FMI_CONTROL__BUFFER_0_LOCK_DMA FMI_CONTROL__BUFFER_0_LOCK(1) +#define FMI_CONTROL__BUFFER_0_LOCK_ECC FMI_CONTROL__BUFFER_0_LOCK(2) +#define FMI_CONTROL__BUFFER_0_LOCK_FMC FMI_CONTROL__BUFFER_0_LOCK(3) + +#define FMI_CONTROL_BUFFER_1_LOCK_FREE FMI_CONTROL__BUFFER_1_LOCK(0) +#define FMI_CONTROL_BUFFER_1_LOCK_DMA FMI_CONTROL__BUFFER_1_LOCK(1) +#define FMI_CONTROL_BUFFER_1_LOCK_ECC FMI_CONTROL__BUFFER_1_LOCK(2) +#define FMI_CONTROL_BUFFER_1_LOCK_FMC FMI_CONTROL__BUFFER_1_LOCK(3) + +// ============================================================================= +// FMI_STATUS bitfields +// ============================================================================= + +#define FMI_STATUS__FMC_ACTIVE (0x1UL << 3) +#define FMI_STATUS__ECC_ACTIVE (0x1UL << 2) +#define FMI_STATUS__DMA_ACTIVE (0x1UL << 1) +#define FMI_STATUS__BUS_ACTIVE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_PEND bitfields +// ============================================================================= + +#define FMI_INT_PEND__SEQUENCER_INTERRUPT (0x1UL << 28) +#define FMI_INT_PEND__SEED_FIFO_EMPTY (0x1UL << 27) +#define FMI_INT_PEND__SEED_FIFO_LOW (0x1UL << 26) +#define FMI_INT_PEND__SEED_FIFO_OVERFLOW (0x1UL << 25) +#define FMI_INT_PEND__ECC_RESULTS_FIFO_UNDERFLOW (0x1UL << 24) +#define FMI_INT_PEND__ECC_RESULTS_FIFO_OVERFLOW (0x1UL << 23) +#define FMI_INT_PEND__LAST_ECC_DONE (0x1UL << 22) +#define FMI_INT_PEND__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_PEND__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_PEND__ECC_DONE (0x1UL << 19) +#define FMI_INT_PEND__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_PEND__FMC_READY_BUSY(n) (((n) & 0xFF) << 10) +#define FMI_INT_PEND__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_PEND__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_PEND__FMC_NSERR (0x1UL << 7) +#define FMI_INT_PEND__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_PEND__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_PEND__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_PEND__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_PEND__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_PEND__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_PEND__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_INT_EN bitfields +// ============================================================================= +#define FMI_INT_EN__SEQUENCER_INTERRUPT (0x1UL << 28) +#define FMI_INT_EN__SEED_FIFO_EMPTY (0x1UL << 27) +#define FMI_INT_EN__SEED_FIFO_LOW (0x1UL << 26) +#define FMI_INT_EN__SEED_FIFO_OVERFLOW (0x1UL << 25) +#define FMI_INT_EN__ECC_RESULTS_FIFO_UNDERFLOW (0x1UL << 24) +#define FMI_INT_EN__ECC_RESULTS_FIFO_OVERFLOW (0x1UL << 23) +#define FMI_INT_EN__LAST_ECC_DONE (0x1UL << 22) +#define FMI_INT_EN__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_EN__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_EN__ECC_DONE (0x1UL << 19) +#define FMI_INT_EN__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_EN__FMC_READY_BUSY (0x1UL << 10) +#define FMI_INT_EN__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_EN__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_EN__FMC_NSERR (0x1UL << 7) +#define FMI_INT_EN__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_EN__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_EN__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_EN__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_EN__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_EN__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_EN__TRANSACTION_COMPLETE (0x1UL << 0) + +// ============================================================================= +// FMI_DEBUG0 bitfields +// ============================================================================= + +#define FMI_DEBUG0__FMC_TASKS_PENDING(n) (((n) & 0x3) << 7) +#define FMI_DEBUG0__ECC_TASKS_PENDING(n) (((n) & 0x3) << 5) +#define FMI_DEBUG0__DMA_TASKS_PENDING(n) (((n) & 0x3) << 3) +#define FMI_DEBUG0__FMC_TARGET_BUFFER(b) (((b) & 0x1) << 2) +#define FMI_DEBUG0__ECC_TARGET_BUFFER(b) (((b) & 0x1) << 1) +#define FMI_DEBUG0__DMA_TARGET_BUFFER(b) (((b) & 0x1) << 0) + +// ============================================================================= +// FMI_DATA_SIZE bifields +// ============================================================================= + +#define FMI_DATA_SIZE__META_BYTES_PER_SECTOR(n) (((n) & 0x3F) << 25) +#define FMI_DATA_SIZE__META_BYTES_PER_PAGE(n) (((n) & 0x3F) << 19) +#define FMI_DATA_SIZE__BYTES_PER_SECTOR(n) (((n) & 0x7FF) << 8) +#define FMI_DATA_SIZE__SECTORS_PER_PAGE(n) (((n) & 0xFF) << 0) + +// ============================================================================= +// FMI_SEED_FIFO_LOW_LEVEL bitfields +// ============================================================================= + +#define FMI_SEED_FIFO_LOW_LEVEL__LEVEL(x) (((x) & 0x7) << 0) + +// ============================================================================= +// METADATA_FIFO_PTR bitfields +// ============================================================================= + +#define METADATA_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define METADATA_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define METADATA_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// SEED_FIFO_PTR bitfields +// ============================================================================= + +#define SEED_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x7) +#define SEED_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x7) +#define SEED_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0xF) + +// ============================================================================= +// FMC_ON bitfields +// ============================================================================= + +#define FMC_ON__SWRST (0x1UL << 8) +#define FMC_ON__ASYNC_DRIVE_DQS (0x1UL << 6) +#define FMC_ON__ASYNC_CEB_AUTO_DISABLE (0x1UL << 5) +#define FMC_ON__DDR_NAND_TYPE_TOGGLE (0x0UL << 3) +#define FMC_ON__DDR_NAND_TYPE_ONFI (0x1UL << 3) +#define FMC_ON__DDR_ENABLE (0x1UL << 2) +#define FMC_ON__CLKGATING_RDY (0x1UL << 1) +#define FMC_ON__ENABLE (0x1UL << 0) +#define FMC_ON__DISABLE (!FMC_ON__ENABLE) + +// ============================================================================= +// FMC_IF_CTRL bitfields +// ============================================================================= + +#define FMC_IF_CTRL__WPB (0x1UL << 21) +#define FMC_IF_CTRL__RBBEN (0x1UL << 20) +#define FMC_IF_CTRL__DCCYCLE(v) (((v) & 0xF) << 16) +#define FMC_IF_CTRL__REB_SETUP(v) (((v) & 0xF) << 12) +#define FMC_IF_CTRL__REB_HOLD(v) (((v) & 0xF) << 8) +#define FMC_IF_CTRL__WEB_SETUP(v) (((v) & 0xF) << 4) +#define FMC_IF_CTRL__WEB_HOLD(v) (((v) & 0xF) << 0) +#define FMC_IF_CTRL__GET_DCCYCLE(v) (((v) & 0xF0000) >> 16) +#define FMC_IF_CTRL__GET_REB_SETUP(v) (((v) & 0x0F000) >> 12) +#define FMC_IF_CTRL__GET_REB_HOLD(v) (((v) & 0x00F00) >> 8) +#define FMC_IF_CTRL__GET_WEB_SETUP(v) (((v) & 0x000F0) >> 4) +#define FMC_IF_CTRL__GET_WEB_HOLD(v) (((v) & 0x0000F) >> 0) + +#define FMC_IF_CTRL__REB_SETUP_MASK (0x0000000F << 12) + +#define FMC_IF_CTRL__TIMING_MAX_CLOCKS (0xFUL) + +// ============================================================================= +// FMC_CE_CTRL bitfields +// ============================================================================= + +#define FMC_CE_CTRL__CE_COUNT (8) +#define FMC_CE_CTRL__CEB(n) (0x1UL << ((n) & 0x7)) + +#define FMC_CE_CTRL__CEB7 FMC_CE_CTRL__CEB(7) +#define FMC_CE_CTRL__CEB6 FMC_CE_CTRL__CEB(6) +#define FMC_CE_CTRL__CEB5 FMC_CE_CTRL__CEB(5) +#define FMC_CE_CTRL__CEB4 FMC_CE_CTRL__CEB(4) +#define FMC_CE_CTRL__CEB3 FMC_CE_CTRL__CEB(3) +#define FMC_CE_CTRL__CEB2 FMC_CE_CTRL__CEB(2) +#define FMC_CE_CTRL__CEB1 FMC_CE_CTRL__CEB(1) +#define FMC_CE_CTRL__CEB0 FMC_CE_CTRL__CEB(0) + +// ============================================================================= +// FMC_RW_CTRL bitfields +// ============================================================================= + +#define FMC_RW_CTRL__NAND_TIMING_USER_TAT(x) (((x) & 0xFF) << 24) +#define FMC_RW_CTRL__CMD1_5_MODE (0x1UL << 9) +#define FMC_RW_CTRL__WAIT_NSRBB_FLD (0x1UL << 8) +#define FMC_RW_CTRL__RD_DONE_REB_CEB_HOLD (0x1UL << 7) +#define FMC_RW_CTRL__REBHOLD (0x1UL << 6) +#define FMC_RW_CTRL__WR_MODE (0x1UL << 5) +#define FMC_RW_CTRL__RD_MODE (0x1UL << 4) +#define FMC_RW_CTRL__ADDR_MODE (0x1UL << 3) +#define FMC_RW_CTRL__CMD3_MODE (0x1UL << 2) +#define FMC_RW_CTRL__CMD2_MODE (0x1UL << 1) +#define FMC_RW_CTRL__CMD1_MODE (0x1UL << 0) + +// ============================================================================= +// FMC_CMD bitfields +// ============================================================================= + +#define FMC_CMD__CMD1_5(c) (((c) & 0xFF) << 24) +#define FMC_CMD__CMD3(c) (((c) & 0xFF) << 16) +#define FMC_CMD__CMD2(c) (((c) & 0xFF) << 8) +#define FMC_CMD__CMD1(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR0 bitfields +// ============================================================================= + +#define FMC_ADDR0__SEQ3(a) (((a) & 0xFF) << 24) +#define FMC_ADDR0__SEQ2(a) (((a) & 0xFF) << 16) +#define FMC_ADDR0__SEQ1(a) (((a) & 0xFF) << 8) +#define FMC_ADDR0__SEQ0(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDR1 bitfields +// ============================================================================= + +#define FMC_ADDR1__SEQ7(a) (((a) & 0xFF) << 24) +#define FMC_ADDR1__SEQ6(a) (((a) & 0xFF) << 16) +#define FMC_ADDR1__SEQ5(a) (((a) & 0xFF) << 8) +#define FMC_ADDR1__SEQ4(a) (((a) & 0xFF) << 0) + +// ============================================================================= +// FMC_ADDRNUM bitfields +// ============================================================================= + +#define FMC_ADDRNUM__NUM(n) (((n) & 0x7) << 0) + +// ============================================================================= +// FMC_DATANUM bitfields +// ============================================================================= + +#define FMC_DATANUM__NUM(n) (((n) & 0x3FF) << 0) + +// ============================================================================= +// FMC_TO_CTRL bitfields +// ============================================================================= + +#define FMC_TO_CTRL__EN (0x1UL << 12) +#define FMC_TO_CTRL__DIV(d) (((d) & 0xF) << 8) +#define FMC_TO_CTRL__VAL(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_TO_CNT bitfields +// ============================================================================= + +#define FMC_TO_CNT__CNT(c) (((c) & 0xFF) << 0) + +// ============================================================================= +// FMC_INTMASK bitfields +// ============================================================================= + +#define FMC_INTMASK__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_INTMASK__CMD1_5DONE (0x1UL << 17) +#define FMC_INTMASK__RBBDONE7 FMC_INTMASK__RBBDONE(7) +#define FMC_INTMASK__RBBDONE6 FMC_INTMASK__RBBDONE(6) +#define FMC_INTMASK__RBBDONE5 FMC_INTMASK__RBBDONE(5) +#define FMC_INTMASK__RBBDONE4 FMC_INTMASK__RBBDONE(4) +#define FMC_INTMASK__RBBDONE3 FMC_INTMASK__RBBDONE(3) +#define FMC_INTMASK__RBBDONE2 FMC_INTMASK__RBBDONE(2) +#define FMC_INTMASK__RBBDONE1 FMC_INTMASK__RBBDONE(1) +#define FMC_INTMASK__RBBDONE0 FMC_INTMASK__RBBDONE(0) +#define FMC_INTMASK__TIMEOUT (0x1UL << 7) +#define FMC_INTMASK__NSERR (0x1UL << 6) +#define FMC_INTMASK__NSRBBDONE (0x1UL << 5) +#define FMC_INTMASK__TRANSDONE (0x1UL << 4) +#define FMC_INTMASK__ADDRESSDONE (0x1UL << 3) +#define FMC_INTMASK__CMD3DONE (0x1UL << 2) +#define FMC_INTMASK__CMD2DONE (0x1UL << 1) +#define FMC_INTMASK__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_STATUS bitfields +// ============================================================================= + +#define FMC_STATUS__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_STATUS__EMERGENCY2 (0x1UL << 21) +#define FMC_STATUS__EMERGENCY01 (0x1UL << 20) +#define FMC_STATUS__RDATADIRTY (0x1UL << 16) +#define FMC_STATUS__RBBDONE7 FMC_STATUS__RBBDONE(7) +#define FMC_STATUS__RBBDONE6 FMC_STATUS__RBBDONE(6) +#define FMC_STATUS__RBBDONE5 FMC_STATUS__RBBDONE(5) +#define FMC_STATUS__RBBDONE4 FMC_STATUS__RBBDONE(4) +#define FMC_STATUS__RBBDONE3 FMC_STATUS__RBBDONE(3) +#define FMC_STATUS__RBBDONE2 FMC_STATUS__RBBDONE(2) +#define FMC_STATUS__RBBDONE1 FMC_STATUS__RBBDONE(1) +#define FMC_STATUS__RBBDONE0 FMC_STATUS__RBBDONE(0) +#define FMC_STATUS__TIMEOUT (0x1UL << 7) +#define FMC_STATUS__NSERR (0x1UL << 6) +#define FMC_STATUS__NSRBBDONE (0x1UL << 5) +#define FMC_STATUS__TRANSDONE (0x1UL << 4) +#define FMC_STATUS__ADDRESSDONE (0x1UL << 3) +#define FMC_STATUS__CMD3DONE (0x1UL << 2) +#define FMC_STATUS__CMD2DONE (0x1UL << 1) +#define FMC_STATUS__CMD1DONE (0x1UL << 0) + +// ============================================================================= +// FMC_RBB_CONFIG bitfields +// ============================================================================= + +#define FMC_RBB_CONFIG__POL(v) (((v) & 0xFF) << 8) +#define FMC_RBB_CONFIG__POS(v) (((v) & 0xFF) << 0) + +// ============================================================================= +// FMC_DQS_TIMING_CTRL bitfields +// ============================================================================= + +#define FMC_DQS_TIMING_CTRL__USE_DLL (0x1UL << 31) +#define FMC_DQS_TIMING_CTRL__DELTAV_SUSPENDS_READS (0x1UL << 30) +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL(x) (((x) & 0x1FF) << 16) +#define FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL_GET(x) (((x) & 0x01FF0000) >> 16) +#define FMC_DQS_TIMING_CTRL__DQS_WRITE_TIMING_DIR_POS (0 << 3) +#define FMC_DQS_TIMING_CTRL__DQS_WRITE_TIMING_DIR_NEG (1 << 3) +#define FMC_DQS_TIMING_CTRL__DQS_WRITE_DELAY_TIMING(x) (((x) & 0x7) << 0) + +#define FMC_DQS_TIMING_CTRL__DEFAULT_VAL (0x01FF0000) + +// ============================================================================= +// FMC_TOGGLE_CTRL_1 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_1_DDR_RD_PRE_TIME(x) (((x) & 0xFF) << 24) +#define FMC_TOGGLE_CTRL_1_DDR_RD_POST_TIME(x) (((x) & 0xFF) << 16) +#define FMC_TOGGLE_CTRL_1_DDR_WR_PRE_TIME(x) (((x) & 0xFF) << 8) +#define FMC_TOGGLE_CTRL_1_DDR_WR_POST_TIME(x) (((x) & 0xFF) << 0) + +#define FMC_TOGGLE_CTRL_1__TIMING_MAX_CLOCKS (0xFF) + +// ============================================================================= +// FMC_TOGGLE_CTRL_2 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_2_CE_SETUP_TIME(x) (((x) & 0xFF) << 24) +#define FMC_TOGGLE_CTRL_2_CE_HOLD_TIME(x) (((x) & 0xFF) << 16) +#define FMC_TOGGLE_CTRL_2_NAND_TIMING_ADL(x) (((x) & 0xFF) << 8) +#define FMC_TOGGLE_CTRL_2_NAND_TIMING_WHR(x) (((x) & 0xFF) << 0) + +#define FMC_TOGGLE_CTRL_2__TIMING_MAX_CLOCKS (0xFF) + +// ============================================================================= +// FMC_TOGGLE_CTRL_2 bitfields +// ============================================================================= + +#define FMC_TOGGLE_CTRL_3_ONFI_WR_CLK_STOP_EN (0x1UL << 31) +#define FMC_TOGGLE_CTRL_3_DISABLE_ONFI_READ_STATUS_CLE_ALE_HOLD (0x1UL << 30) +#define FMC_TOGGLE_CTRL_3_DISABLE_ONFI_ONFI_IDLE_CLOCK_ON (0x1UL << 29) +#define FMC_TOGGLE_CTRL_3_ONFI_TIMING_CAD (((x) & 0xF) << 0) + +// ============================================================================= +// ECC_CON0 bitfields +// ============================================================================= + +#define ECC_CON0__INFORMATION_LENGTH(n) (((n) & 0x7FF) << 16) +#define ECC_CON0__ECC_CORRECTION_MODE(m) (((m) & 0x1F) << 4) +#define ECC_CON0__START_ENC (0x1UL << 1) +#define ECC_CON0__START_DEC (0x1UL << 0) + +// ============================================================================= +// ECC_CON1 bitfields +// ============================================================================= +#define ECC_CON1__IMPLICIT_WRITE_MARK (1UL << 31) +#define ECC_CON1__SLAVE_MODE (1UL << 29) +#define ECC_CON1__SKIP_FREE_PAGE_FLD (1UL << 25) +#define ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(n) (((n) & 0x1F) << 16) +#define ECC_CON1__ERROR_ALERT_LEVEL(n) (((n) & 0x1F) << 8) +#define ECC_CON1__INT_ENABLE(b) (((b) & 0x1) << 7) + +#define ECC_CON1__INT_ENABLE__ENABLE ECC_CON1__INT_ENABLE(1) +#define ECC_CON1__INT_ENABLE__DISABLE ECC_CON1__INT_ENABLE(0) + +// ============================================================================= +// ECC_RESULT bitfields +// ============================================================================= + +#define ECC_RESULT__ERROR_ALERT (0x1UL << 21) +#define ECC_RESULT__ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_RESULT__ERROR_CNT_SHIFT (16) +#define ECC_RESULT__ERROR_CNT_MASK (0x1FUL << ECC_RESULT__ERROR_CNT_SHIFT) +#define ECC_RESULT__STUCK_BIT_EXCEEDED (0x1UL << 14) +#define ECC_RESULT__STUCK_BIT_CNT(n) (((n) & 0x3F) << 8) +#define ECC_RESULT__DECODED_BUFFER_IDX (0x1UL << 6) +#define ECC_RESULT__ALL_FF (0x1UL << 3) +#define ECC_RESULT__ALL_ZERO (0x1UL << 2) +#define ECC_RESULT__FREE_PAGE (0x1UL << 1) +#define ECC_RESULT__UNCORRECTABLE (0x1UL << 0) +#define ECC_RESULT__FIFO_RESET (0x1UL << 0) // Same as uncorrectable bit + +// ============================================================================= +// ECC_PND bitfields +// ============================================================================= + +#define ECC_PND__MAX_STUCK_BIT_CNT(n) (((n) & 0x3F) << 24) +#define ECC_PND__MAX_ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_PND__MAX_ERROR_CNT_SHIFT (16) +#define ECC_PND__MAX_ERROR_CNT_MASK (0x1FUL << ECC_PND__MAX_ERROR_CNT_SHIFT) +#define ECC_PND__DETECTOR_DONE (0x1UL << 14) +#define ECC_PND__B1_DEC_DONE (0x1UL << 13) +#define ECC_PND__B0_DEC_DONE (0x1UL << 12) +#define ECC_PND__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_PND__SOME_ALL_FF (0x1UL << 8) +#define ECC_PND__SOME_ALL_ZERO (0x1UL << 7) +#define ECC_PND__ALL_FREE_PAGE (0x1UL << 6) +#define ECC_PND__SOME_ERROR_ALERT (0x1UL << 5) +#define ECC_PND__READY_BUSY (0x1UL << 4) +#define ECC_PND__ANY_UNCORRECTABLE (0x1UL << 3) +#define ECC_PND__ENC_DONE (0x1UL << 2) +#define ECC_PND__DEC_DONE (0x1UL << 1) +#define ECC_PND__ENC_DEC_DONE (0x1UL << 0) + +// ============================================================================= +// ECC_MASK bitfields +// ============================================================================= + +#define ECC_MASK__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_MASK__SOME_ALL_FF_MASK (0x1UL << 8) +#define ECC_MASK__SOME_ALL_ZERO_MASK (0x1UL << 7) +#define ECC_MASK__SOME_ERROR_ALERT_MASK (0x1UL << 5) +#define ECC_MASK__ANY_UNCORRECTABLE_MASK (0x1UL << 3) +#define ECC_MASK__ENC_DONE_MASK (0x1UL << 2) +#define ECC_MASK__DEC_DONE_MASK (0x1UL << 1) +#define ECC_MASK__ENC_DEC_DONE_MASK (0x1UL << 0) + +// ============================================================================= +// ECC_HISTORY bitfields +// ============================================================================= + +#define ECC_HISTORY__ERROR_COUNT_CLEAR (0x1UL << 26) +#define ECC_HISTORY__ERROR_COUNT(n) (((n) & 0x7FFF) << 11) +#define ECC_HISTORY__DECODING_NUMBER_CLEAR (0x1UL << 10) +#define ECC_HISTORY__DECODING_NUMBER(n) (((n) & 0x1FF) << 0) + +// ============================================================================= +// RESULT_FIFO_PTR bitfields +// ============================================================================= + +#define ECC_RESULTS_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define ECC_RESULTS_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define ECC_RESULTS_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// COMMAND_FIFO bitfields +// ============================================================================= + +#define COMMAND_FIFO_SIZE (32) +#define OPERAND_FIFO_SIZE (32) +#define STORE_FIFO_SIZE (32) + +#define COMMAND_FIFO__COMMAND(cmd) ((cmd) << 24) +#define COMMAND_FIFO__OPERAND(op) (((op) & 0xFFFFFF) << 0) + +#define OPCODE_ADDR(n) (n) +#define OPCODE_COMMAND (0x08) +#define OPCODE_ENABLE_CE (0x09) +#define OPCODE_WAIT_FOR_READY (0x0A) +#define OPCODE_TX_PAGE (0x0B) +#define OPCODE_SEND_INTERRUPT (0x0C) +#define OPCODE_PAUSE (0x0D) +#define OPCODE_TIMED_WAIT (0x0E) +#define OPCODE_LOAD_NEXT_WORD (0x0F) +#define OPCODE_LOAD_FROM_FIFO (0x10) +#define OPCODE_MACRO (0x11) +#define OPCODE_POLL (0x12) +#define OPCODE_WAIT_FOR_INT (0x13) +#define OPCODE_STORE_TO_FIFO (0x14) + +#define CMD_ADDRESS(bytes, addr) (COMMAND_FIFO__COMMAND(OPCODE_ADDR(bytes)) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFFF)) + +#define CMD_COMMAND(cmd) (COMMAND_FIFO__COMMAND(OPCODE_COMMAND) | \ + COMMAND_FIFO__OPERAND((cmd) & 0xFF)) + +#define CMD_ENABLE_CHIP(mask) (COMMAND_FIFO__COMMAND(OPCODE_ENABLE_CE) | \ + COMMAND_FIFO__OPERAND((mask) & 0xFF)) + +#define CMD_WAIT_FOR_READY(code,mask,cond) (COMMAND_FIFO__COMMAND(OPCODE_WAIT_FOR_READY) | \ + COMMAND_FIFO__OPERAND((code) << 16 | (mask) << 8 | (cond) << 0)) + +#define CMD_TX_PAGE (COMMAND_FIFO__COMMAND(OPCODE_TX_PAGE)) + +#define CMD_SEND_INTERRUPT(code) (COMMAND_FIFO__COMMAND(OPCODE_SEND_INTERRUPT) | \ + COMMAND_FIFO__OPERAND(code)) + +#define CMD_PAUSE (COMMAND_FIFO__COMMAND(OPCODE_PAUSE)) + +#define CMD_TIMED_WAIT(clks) (COMMAND_FIFO__COMMAND(OPCODE_TIMED_WAIT) | \ + COMMAND_FIFO__OPERAND(clks)) + +#define CMD_LOAD_NEXT_WORD(addr) (COMMAND_FIFO__COMMAND(OPCODE_LOAD_NEXT_WORD) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_LOAD_FROM_FIFO(addr) (COMMAND_FIFO__COMMAND(OPCODE_LOAD_FROM_FIFO) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_MACRO(seq,len) (COMMAND_FIFO__COMMAND(OPCODE_MACRO) | \ + COMMAND_FIFO__OPERAND(((seq) << 8) | (len))) + +#define CMD_POLL(addr) (COMMAND_FIFO__COMMAND(OPCODE_POLL) | \ + COMMAND_FIFO__OPERAND((addr) & 0xFFFFF)) + +#define CMD_WAIT_FOR_INT(irq,bit) (COMMAND_FIFO__COMMAND(OPCODE_WAIT_FOR_INT) | \ + COMMAND_FIFO__OPERAND((irq) << 8 | (bit) << 0)) + +#define CMD_STORE_TO_FIFO(reg) (COMMAND_FIFO__COMMAND(OPCODE_STORE_TO_FIFO) | \ + COMMAND_FIFO__OPERAND((reg) & 0xFFFFF)) + + +// ============================================================================= +// COMMAND_FIFO_PTR bitfields +// ============================================================================= + +#define COMMAND_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define COMMAND_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define COMMAND_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// COMMAND_FIFO_LOW bitfields +// ============================================================================= + +#define COMMAND_FIFO_LOW__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// COMMAND_COUNT bitfields +// ============================================================================= + +#define COMMAND_COUNT__MAX_COUNT (32) + +// ============================================================================= +// COMMAND_INT_CODE bitfields +// ============================================================================= + +#define COMMAND_INT_CODE__READ(regval) ((regval) & 0xFFFFFF) +#define COMMAND_INT_CODE__WAIT_FOR_READY_CODE(regval) ((regval >> 16) & 0xFF) +#define COMMAND_INT_CODE__WAIT_FOR_READY_STATUS(regval) ((regval >> 0) & 0xFF) + +// ============================================================================= +// OPERAND_FIFO_PTR bitfields +// ============================================================================= + +#define OPERAND_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define OPERAND_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define OPERAND_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// OPERAND_FIFO_LOW bitfields +// ============================================================================= + +#define OPERAND_FIFO_LOW__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// STORE_FIFO_PTR bitfields +// ============================================================================= + +#define STORE_FIFO_PTR__READ(regval) (((regval) >> 16) & 0x1F) +#define STORE_FIFO_PTR__WRITE(regval) (((regval) >> 8) & 0x1F) +#define STORE_FIFO_PTR__LEVEL(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// STORE_FIFO_HIGH bitfields +// ============================================================================= + +#define STORE_FIFO_HIGH__LEVEL(x) (((x) & 0x3F) << 0) + +// ============================================================================= +// SEQ_INT_PEND bitfields +// ============================================================================= + +#define SEQ_INT_PEND__STORE_FIFO_FULL (0x1UL << 10) +#define SEQ_INT_PEND__STORE_FIFO_HIGH (0x1UL << 9) +#define SEQ_INT_PEND__STORE_FIFO_OVERFLOW (0x1UL << 8) +#define SEQ_INT_PEND__TIMEOUT (0x1UL << 7) +#define SEQ_INT_PEND__OPERAND_FIFO_EMPTY (0x1UL << 6) +#define SEQ_INT_PEND__OPERAND_FIFO_LOW (0x1UL << 5) +#define SEQ_INT_PEND__OPERAND_FIFO_OVERFLOW (0x1UL << 4) +#define SEQ_INT_PEND__COMMAND_FIFO_EMPTY (0x1UL << 3) +#define SEQ_INT_PEND__COMMAND_FIFO_LOW (0x1UL << 2) +#define SEQ_INT_PEND__COMMAND_FIFO_OVERFLOW (0x1UL << 1) +#define SEQ_INT_PEND__SEQUENCER_SIGNAL (0x1UL << 0) + +// ============================================================================= +// SEQ_INT_EN bitfields +// ============================================================================= + +#define SEQ_INT_EN__TIMEOUT (0x1UL << 7) +#define SEQ_INT_EN__OPERAND_FIFO_EMPTY (0x1UL << 6) +#define SEQ_INT_EN__OPERAND_FIFO_LOW (0x1UL << 5) +#define SEQ_INT_EN__OPERAND_FIFO_OVERFLOW (0x1UL << 4) +#define SEQ_INT_EN__COMMAND_FIFO_EMPTY (0x1UL << 3) +#define SEQ_INT_EN__COMMAND_FIFO_LOW (0x1UL << 2) +#define SEQ_INT_EN__COMMAND_FIFO_OVERFLOW (0x1UL << 1) +#define SEQ_INT_EN__SEQUENCER_SIGNAL (0x1UL << 0) + +// ============================================================================= +// SEQ_MACRO_CONTROL bitfields +// ============================================================================= + +#define SEQ_MACRO_CONTROL__WORD_COUNT(cnt) (((cnt) & 0x3F) << 8) +#define SEQ_MACRO_CONTROL__MACRO_ADDRESS(addr) (((addr) & 0x3F) << 0) +#define SEQ_MACRO_CONTROL__GET_WORD_COUNT(regval) (((regval) >> 8) & 0x3F) +#define SEQ_MACRO_CONTROL__GET_MACRO_ADDRESS(regval) (((regval) >> 0) & 0x3F) + +// ============================================================================= +// NAND_DLL_CONTROL bitfields +// ============================================================================= + +#define NAND_DLL_CONTROL__REFERENCE(x) (((x) & 0xF) << 24) +#define NAND_DLL_CONTROL__STEP_SIZE(x) (((x) & 0xFF) << 16) +#define NAND_DLL_CONTROL__START_POINT(x) (((x) & 0xFF) << 8) +#define NAND_DLL_CONTROL__HALF (1 << 7) +#define NAND_DLL_CONTROL__OVERRIDE (1 << 5) +#define NAND_DLL_CONTROL__CHANNEL_ACTIVE_START (1 << 4) +#define NAND_DLL_CONTROL__VOLTAGE_SHIFT_START (1 << 3) +#define NAND_DLL_CONTROL__TIMEOUT_START (1 << 2) +#define NAND_DLL_CONTROL__SOFTWARE_START (1 << 1) +#define NAND_DLL_CONTROL__ENABLE (1 << 0) + +#define NAND_DLL_CONTROL__REFERENCE_DEFAULT (0x8) +#define NAND_DLL_CONTROL__STEP_SIZE_DEFAULT (0x01) +#define NAND_DLL_CONTROL__START_POINT_DEFAULT (0x10) + +#define NAND_DLL_TRAIN_TIME_US (1) + +// ============================================================================= +// NAND_DLL_TIMEOUT bitfields +// ============================================================================= + +// ============================================================================= +// NAND_DLL_STATUS bitfields +// ============================================================================= + +#define NAND_DLL_STATUS__LOCK_VALUE_GET(x) (((x) >> 3) & 0x3FF) +#define NAND_DLL_STATUS__COARSE_LOCK_ON_GET(x) (((x) >> 2) & 0x1) +#define NAND_DLL_STATUS__FINE_LOCK_ON_GET(x) (((x) >> 1) & 0x1) +#define NAND_DLL_STATUS__DLL_LOCKED_GET(x) (((x) >> 0) & 0x1) + +// ============================================================================= +// NAND_DLL_FORCE_VALUE bitfields +// ============================================================================= + +// ============================================================================= +// SoC-Specific Tuning +// ============================================================================= + +#define FMI_TX_PROP_DELAY_NS (6) +#define FMI_RX_PROP_DELAY_NS (6) + +#endif // _H2FMI_8945REGS_H_ + +// ********************************** EOF ************************************* diff --git a/drivers/apple/h2fmi/H2fmi_boot.c b/drivers/apple/h2fmi/H2fmi_boot.c new file mode 100644 index 0000000..a2bc024 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_boot.c @@ -0,0 +1,483 @@ +// ***************************************************************************** +// +// File: H2fmi_boot.c +// +// ***************************************************************************** +// +// Notes: +// +// - This file contains initialization functions for iBoot and IOP +// +// +// ***************************************************************************** +// +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** +#include "H2fmi_private.h" +#include "H2fmi_ppn.h" +#if WMR_BUILDING_EFI +#include "SoC.h" +#else +#include "soc.h" +#endif // WMR_BUILDING_EFI +#include "WMROAM.h" + +// ============================================================================= +// implementation function declarations shared between SecureROM and iBoot +// ============================================================================= +static BOOL32 h2fmi_wait_ready(h2fmi_t* fmi, UInt8 io_mask, UInt8 io_val); + + +BOOL32 h2fmi_is_chipid_invalid(h2fmi_chipid_t* const id) +{ + const h2fmi_chipid_t Zeroes = { 0x00, 0x00, 0x00, 0x00, 0x00 }; + const h2fmi_chipid_t Ones = { 0xff, 0xff, 0xff, 0xff, 0xff }; + + if (WMR_MEMCMP(id, Zeroes, sizeof(h2fmi_chipid_t)) && + WMR_MEMCMP(id, Ones, sizeof(h2fmi_chipid_t))) + { + return FALSE32; + } + else + { + return TRUE32; + } +} + +void h2fmi_reset(h2fmi_t* fmi) +{ + // reset the specified FMI subsystem + WMR_CLOCK_RESET_DEVICE(h2fmi_get_gate(fmi)); + +#if FMI_VERSION > 0 + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__SOFTWARE_RESET); +#endif + + turn_on_fmc(fmi); + restoreTimingRegs(fmi); +} + +BOOL32 h2fmi_wait_done(h2fmi_t* fmi, + UInt32 reg, + UInt32 mask, + UInt32 bits) +{ + BOOL32 result = TRUE32; + + UInt64 check_time = H2FMI_DEFAULT_TIMEOUT_MICROS * WMR_GET_TICKS_PER_US(); + UInt64 start_time = WMR_CLOCK_TICKS(); + + // wait for specified bits to be set + while ((h2fmi_rd(fmi, reg) & mask) != bits) + { + if (WMR_HAS_TIME_ELAPSED_TICKS(start_time, check_time)) + { + h2fmi_fail(result); + break; + } + + WMR_YIELD(); + } + + // clear specified bits + h2fmi_wr(fmi, reg, bits); + + return result; +} + +BOOL32 h2fmi_wait_dma_task_pending(h2fmi_t* fmi) +{ + BOOL32 result = TRUE32; + + UInt64 check_time = H2FMI_DEFAULT_TIMEOUT_MICROS * WMR_GET_TICKS_PER_US(); + UInt64 start_time = WMR_CLOCK_TICKS(); + + // wait for FMI to complete transfer of sector to fifo + const uint32_t msk = FMI_DEBUG0__DMA_TASKS_PENDING(0x3); + + // wait for FMI to to be ready for at least one dma task + while ((h2fmi_rd(fmi, FMI_DEBUG0) & msk) == 0) + { + if (WMR_HAS_TIME_ELAPSED_TICKS(start_time, check_time)) + { + h2fmi_fail(result); + break; + } + + WMR_YIELD(); + } + + return result; +} + +void h2fmi_config_page_addr(h2fmi_t* fmi, + UInt32 page) +{ + const UInt32 page_addr_size = 5; + + const UInt32 page_addr_2 = (page >> 16) & 0xFF; + const UInt32 page_addr_1 = (page >> 8) & 0xFF; + const UInt32 page_addr_0 = (page >> 0) & 0xFF; + + h2fmi_wr(fmi, FMC_ADDR1, (FMC_ADDR1__SEQ7(0x00) | + FMC_ADDR1__SEQ6(0x00) | + FMC_ADDR1__SEQ5(0x00) | + FMC_ADDR1__SEQ4(page_addr_2))); + h2fmi_wr(fmi, FMC_ADDR0, (FMC_ADDR0__SEQ3(page_addr_1) | + FMC_ADDR0__SEQ2(page_addr_0) | + FMC_ADDR0__SEQ1(0x00) | + FMC_ADDR0__SEQ0(0x00))); + + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(page_addr_size - 1)); +} + +void h2fmi_clean_ecc(h2fmi_t* fmi) +{ + // clean status bits by setting them +#if FMI_VERSION == 0 + // S5L9820X + h2fmi_wr(fmi, ECC_PND, (ECC_PND__BCH_ALL_FF | + ECC_PND__SECTOR_ERROR_ALERT | + ECC_PND__UNCORRECTABLE)); + +#else + // S5L8922X and later + h2fmi_wr(fmi, ECC_PND, (ECC_PND__SOME_ALL_ZERO | + ECC_PND__SOME_ALL_FF | + ECC_PND__SOME_ERROR_ALERT | + ECC_PND__ANY_UNCORRECTABLE)); +#endif +} + +void h2fmi_fmc_read_data(h2fmi_t* fmi, + UInt32 size, + UInt8* data) +{ + register UInt32 idx; + UInt32 delay_ticks; + UInt32 if_ctrl; + + // Force-clear FMC timings. We're manually hitting /RE and the I/O lines + // so we can take care of timings ourselves. + if_ctrl = h2fmi_rd(fmi, FMC_IF_CTRL); + h2fmi_set_if_ctrl(fmi, 0); + + delay_ticks = WMR_GET_TICKS_PER_US() / 8; //(125ns) + + // employ REBHOLD to hold nRD low so that each byte on the bus can + // be read, one at a time, from NAND_STATUS + h2fmi_wr(fmi, FMC_DATANUM, FMC_DATANUM__NUM(0)); + for (idx = 0; idx < size; idx++) + { + UInt64 start; + + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__REBHOLD | + FMC_RW_CTRL__RD_MODE)); + + // FMC requires 8 + REBSETUP cycles between asserting REBHOLD and reading FMC_NAND_STATUS. + start = WMR_CLOCK_TICKS(); + while(!WMR_HAS_TIME_ELAPSED_TICKS(start, delay_ticks)); + + data[idx] = (UInt8)h2fmi_rd(fmi, FMC_NAND_STATUS); + + // clear FMC_RW_CTRL, thereby releasing REBHOLD and completing + // current read cycle + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + } + + h2fmi_set_if_ctrl(fmi, if_ctrl); +} + +BOOL32 h2fmi_nand_reset(h2fmi_t* fmi, + h2fmi_ce_t ce) +{ + BOOL32 result = TRUE32; + + // enable specified nand device + h2fmi_fmc_enable_ce(fmi, ce); + +// Only for H5X - // Software workaround for Samsung reset and bad chip ID isssue +#if FMI_VERSION >= 5 + WMR_SLEEP_US(H2FMI_EXTRA_CE_SETUP_TIME_US); +#endif // FMI_VERSION >= 5 + + // perform reset command + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__RESET)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + // wait until cmd sent on bus + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__CMD1DONE, + FMC_STATUS__CMD1DONE)) + { + h2fmi_fail(result); + } + + // disable all nand devices + h2fmi_fmc_disable_ce(fmi, ce); + +#if SUPPORT_PPN && H2FMI_PPN_VERIFY_SET_FEATURES + if (fmi->is_ppn) + { + h2fmi_ppn_reset_feature_shadow(fmi); + } +#endif // SUPPORT_PPN && H2FMI_PPN_VERIFY_SET_FEATURES + + return result; +} + +BOOL32 h2fmi_nand_read_id(h2fmi_t* fmi, + h2fmi_ce_t ce, + h2fmi_chipid_t* id, + UInt8 addr) +{ + const UInt32 cmd1_addr_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD1DONE); + BOOL32 result = TRUE32; + +#if SUPPORT_TOGGLE_NAND + WMR_ASSERT(!fmi->is_toggle); +#endif + // enable specified nand device + h2fmi_fmc_enable_ce(fmi, ce); + + // set up Read Id command and address cycles + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ_ID)); + h2fmi_wr(fmi, FMC_ADDR0, FMC_ADDR0__SEQ0(addr)); + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(0)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD1_MODE)); + + // wait until cmd & addr completion + if (!h2fmi_wait_done(fmi, FMC_STATUS, + cmd1_addr_done, + cmd1_addr_done)) + { + h2fmi_fail(result); + } + else + { +#if FMI_VERSION == 0 + // read correct number of id bytes into local temporary + h2fmi_fmc_read_data(fmi, H2FMI_NAND_ID_SIZE, *id); +#else + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_wr(fmi, FMI_CONFIG, 0); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__BYTES_PER_SECTOR( ROUNDUPTO( sizeof(h2fmi_chipid_t), sizeof(UInt32) ) ) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1))); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + if (!h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE)) + { + h2fmi_fail(result); + } + else + { + h2fmi_pio_read_sector(fmi, id, sizeof(h2fmi_chipid_t)); + } + + h2fmi_reset(fmi); +#endif + } + + // disable all nand devices + h2fmi_fmc_disable_ce(fmi, ce); + + return result; +} + +BOOL32 h2fmi_pio_write_sector(h2fmi_t* fmi, + const void* buf, + UInt32 len) +{ + BOOL32 result = TRUE32; + UInt32* ptr = (UInt32*)buf; + UInt32 i; + + if (!h2fmi_wait_dma_task_pending(fmi)) + { + // timed out + WMR_PANIC(); + + h2fmi_fail(result); + } + else + { + for( i = 0; i < len / sizeof(UInt32); i++ ) + { + h2fmi_wr(fmi, FMI_DATA_BUF, *ptr++); + } + } + + return result; +} + +BOOL32 h2fmi_pio_read_sector(h2fmi_t* fmi, + void* buf, + UInt32 len) +{ + BOOL32 result = TRUE32; + UInt32 *word_ptr = (UInt32*)buf; + UInt8 *byte_ptr; + int i; + + // wait for FMI to be ready with data in fifo for DMA to transfer out + if (!h2fmi_wait_dma_task_pending(fmi)) + { + // timed out + h2fmi_fail(result); + } + else + { + if (((UInt32)word_ptr & 0xF) == 0) + { + // Our buffers (particularly boot pages) are generally aligned. + // Do as many 32 bit operations as we can. + while (len >= sizeof(UInt32)) + { + *word_ptr++ = h2fmi_rd(fmi, FMI_DATA_BUF); + len -= sizeof(UInt32); + } + } + + byte_ptr = (UInt8*)word_ptr; + while (len) + { + UInt8 bytes = WMR_MIN(sizeof(UInt32), len); + UInt32 tmp = h2fmi_rd(fmi, FMI_DATA_BUF); + + for (i = 0; i < bytes; i++) + { + *byte_ptr++ = (tmp >> (i*8)) & 0xFF; + } + + len -= bytes; + } + } + + return result; +} + +UInt32 h2fmi_get_gate(h2fmi_t* fmi) +{ + return h2fmi_select_by_bus(fmi, 0, 1 ); +} + +// ============================================================================= +// static implementation function definitions used by both SecureROM and iBoot +// ============================================================================= + +BOOL32 h2fmi_start_nand_page_read(h2fmi_t* fmi, + UInt32 page) +{ + const UInt32 cmd1_addr_cmd2_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD2DONE | + FMC_STATUS__CMD1DONE); + + BOOL32 result = TRUE32; + + // configure FMC for cmd1/addr/cmd2 sequence + h2fmi_config_page_addr(fmi, page); + h2fmi_wr(fmi, FMC_CMD, (FMC_CMD__CMD2(NAND_CMD__READ_CONFIRM) | + FMC_CMD__CMD1(NAND_CMD__READ))); + + // start cmd1/addr/cmd2 sequence + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD2_MODE | + FMC_RW_CTRL__CMD1_MODE)); + + // wait until cmd1/addr/cmd2 sequence completed + if (!h2fmi_wait_done(fmi, FMC_STATUS, + cmd1_addr_cmd2_done, + cmd1_addr_cmd2_done)) + { + h2fmi_fail(result); + } + // wait for ready using Read Status command + else if (!h2fmi_wait_ready(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY)) + { + h2fmi_fail(result); + } + else + { + // reissue cmd1 and wait until completed + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__CMD1DONE, + FMC_STATUS__CMD1DONE)) + { + h2fmi_fail(result); + } + } + + return result; +} + +static BOOL32 h2fmi_wait_ready(h2fmi_t* fmi, + UInt8 io_mask, + UInt8 io_val) +{ + BOOL32 result = TRUE32; + + // turn off RBBEN and configure it to use look for I/O bit 6 (0x40) + h2fmi_set_if_ctrl(fmi, (~FMC_IF_CTRL__RBBEN & h2fmi_rd(fmi, FMC_IF_CTRL))); + h2fmi_wr(fmi, FMC_RBB_CONFIG, (FMC_RBB_CONFIG__POL(io_val) | + FMC_RBB_CONFIG__POS(io_mask))); + + // exec Read Status command cycle + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ_STATUS)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + // wait until command cycle completed + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__CMD1DONE, + FMC_STATUS__CMD1DONE)) + { + h2fmi_fail(result); + } + else + { + // clear the FMC_STATUS__NSRBBDONE bit in FMC_STATUS + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__NSRBBDONE); + + // set up read cycle with REBHOLD to wait for ready bit to be + // set on I/O lines + h2fmi_wr(fmi, FMC_DATANUM, FMC_DATANUM__NUM(0)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__REBHOLD | FMC_RW_CTRL__RD_MODE)); + + // wait until NSRBB done signaled + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__NSRBBDONE, + FMC_STATUS__NSRBBDONE)) + { + h2fmi_fail(result); + } + + // clear FMC_RW_CTRL, thereby releasing REBHOLD and completing + // current read cycle + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + } + + return result; +} + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_debug.c b/drivers/apple/h2fmi/H2fmi_debug.c new file mode 100644 index 0000000..31f91c7 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_debug.c @@ -0,0 +1,249 @@ +// ***************************************************************************** +// +// File: H2fmi_debug.c +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" + +// ============================================================================= +// public implementation function definitions +// ============================================================================= + +#if (H2FMI_TRACE_REG_WRITES) +UInt32 h2fmi_trace_wr(h2fmi_t* fmi, + UInt32 reg, + UInt32 val) +{ + const UInt32 offset = reg >> 2; + + WMR_PRINT(MISC, "*%p = 0x%08X\n", ((UInt32)fmi->regs) + reg, val); + fmi->regs[offset] = val; + return val; +} + +UInt8 h2fmi_trace_wr8(h2fmi_t* fmi, + UInt32 reg, + UInt8 val) +{ + const UInt32 offset = reg; + + WMR_PRINT(MISC, "*%p = 0x%02X\n", ((UInt32)fmi->regs) + reg, val); + ((UInt8*)fmi->regs)[offset] = val; + return val; +} + +UInt32 h2fmc_trace_wr(volatile UInt32* h2fmc_regs, + UInt32 reg, + UInt32 val) +{ + const UInt32 offset = reg >> 2; + + WMR_PRINT(MISC, "*%p = 0x%08X\n", ((UInt32)h2fmc_regs) + reg, val); + h2fmc_regs[offset] = val; + return val; +} +#endif // H2FMI_TRACE_REG_WRITES + +#if (H2FMI_TRACE_REG_READS) +UInt32 h2fmi_trace_rd(h2fmi_t* fmi, + UInt32 reg) +{ + const UInt32 offset = reg >> 2; + const UInt32 val = fmi->regs[offset]; + + WMR_PRINT(MISC, "*%p == 0x%08X\n", ((UInt32)fmi->regs) + reg, val); + return val; +} + +UInt8 h2fmi_trace_rd8(h2fmi_t* fmi, + UInt32 reg) +{ + const UInt32 offset = reg; + const UInt8 val = ((volatile UInt8*)fmi->regs)[offset]; + + WMR_PRINT(MISC, "*%p == 0x%02X\n", ((UInt32)fmi->regs) + reg, val); + return val; +} +#endif // H2FMI_TRACE_REG_READS + +#if (H2FMI_DEBUG) + +void h2fmi_spew_config(h2fmi_t* fmi) +{ + WMR_PRINT(INF, "fmi->regs: %p\n", fmi->regs); + WMR_PRINT(INF, "fmi->num_of_ce: %p\n", fmi->num_of_ce); + WMR_PRINT(INF, "fmi->pages_per_block: %p\n", fmi->pages_per_block); + WMR_PRINT(INF, "fmi->sectors_per_page: %p\n", fmi->sectors_per_page); + WMR_PRINT(INF, "fmi->bytes_per_spare: %p\n", fmi->bytes_per_spare); + WMR_PRINT(INF, "fmi->blocks_per_ce: %p\n", fmi->blocks_per_ce); + WMR_PRINT(INF, "fmi->total_bytes_per_meta: %p\n", fmi->total_bytes_per_meta); + WMR_PRINT(INF, "fmi->valid_bytes_per_meta: %p\n", fmi->valid_bytes_per_meta); + WMR_PRINT(INF, "fmi->if_ctrl: %p\n", fmi->if_ctrl); +#if SUPPORT_TOGGLE_NAND + WMR_PRINT(INF, "fmi->toggle_if_ctrl: %p\n", fmi->toggle_if_ctrl); +#endif + WMR_PRINT(INF, "fmi->bytes_per_page : %p\n", fmi->bytes_per_page); +} + +void h2fmi_spew_status_regs(h2fmi_t* fmi, + const char* prefix) +{ + WMR_PRINT(INF, "%sFMI_INT_PEND: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_INT_PEND)); + WMR_PRINT(INF, "%sFMC_STATUS: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_STATUS)); + + // ECC might be clocked off for PPN + if (!fmi->is_ppn) + { + WMR_PRINT(INF, "%sECC_PND: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PND)); + } + else + { + WMR_PRINT(INF, "%s: omitting ecc registers for ppn device\n", prefix); + } +} + +void h2fmi_spew_fmi_regs(h2fmi_t* fmi, + const char* prefix) +{ + WMR_PRINT(INF, "%sFMI_CONFIG: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_CONFIG)); + WMR_PRINT(INF, "%sFMI_CONTROL: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_CONTROL)); + WMR_PRINT(INF, "%sFMI_STATUS: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_STATUS)); + WMR_PRINT(INF, "%sFMI_INT_PEND: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_INT_PEND)); + WMR_PRINT(INF, "%sFMI_INT_EN: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_INT_EN)); + + // can't read from fifos, since that would alter state of block + + WMR_PRINT(INF, "%sFMI_DEBUG0: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_DEBUG0)); +#if FMI_VERSION <= 2 + WMR_PRINT(INF, "%sFMI_DEBUG1: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_DEBUG1)); + WMR_PRINT(INF, "%sFMI_DEBUG2: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_DEBUG2)); +#endif + +#if FMI_VERSION > 0 + + WMR_PRINT(INF, "%sFMI_HW_VERSION: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_HW_VERSION)); +#if FMI_VERSION <= 2 + WMR_PRINT(INF, "%sFMI_DEBUG3: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_DEBUG3)); +#endif + WMR_PRINT(INF, "%sFMI_DATA_SIZE: 0x%08X\n", prefix, h2fmi_rd(fmi, FMI_DATA_SIZE)); +#endif +} + +void h2fmi_spew_fmc_regs(h2fmi_t* fmi, + const char* prefix) +{ + WMR_PRINT(INF, "%sFMC_ON: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_ON)); + WMR_PRINT(INF, "%sFMC_VER: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_VER)); + WMR_PRINT(INF, "%sFMC_IF_CTRL: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_IF_CTRL)); + WMR_PRINT(INF, "%sFMC_CE_CTRL: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_CE_CTRL)); + WMR_PRINT(INF, "%sFMC_RW_CTRL: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_RW_CTRL)); + WMR_PRINT(INF, "%sFMC_CMD: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_CMD)); + WMR_PRINT(INF, "%sFMC_ADDR0: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_ADDR0)); + WMR_PRINT(INF, "%sFMC_ADDR1: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_ADDR1)); + WMR_PRINT(INF, "%sFMC_ADDRNUM: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_ADDRNUM)); + WMR_PRINT(INF, "%sFMC_DATANUM: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_DATANUM)); + WMR_PRINT(INF, "%sFMC_TO_CTRL: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_TO_CTRL)); + WMR_PRINT(INF, "%sFMC_TO_CNT: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_TO_CNT)); + WMR_PRINT(INF, "%sFMC_INTMASK: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_INTMASK)); + WMR_PRINT(INF, "%sFMC_STATUS: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_STATUS)); + WMR_PRINT(INF, "%sFMC_NAND_STATUS: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_NAND_STATUS)); + WMR_PRINT(INF, "%sFMC_RBB_CONFIG: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_RBB_CONFIG)); +#if SUPPORT_TOGGLE_NAND + WMR_PRINT(INF, "%sFMC_DQS_TIMING_CTRL:0x%08X\n", prefix, h2fmi_rd(fmi, FMC_DQS_TIMING_CTRL)); + WMR_PRINT(INF, "%sFMC_TOGGLE_CTRL_1: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_TOGGLE_CTRL_1)); + WMR_PRINT(INF, "%sFMC_TOGGLE_CTRL_2: 0x%08X\n", prefix, h2fmi_rd(fmi, FMC_TOGGLE_CTRL_2)); +#endif +} + +void h2fmi_spew_ecc_regs(h2fmi_t* fmi, + const char* prefix) +{ + // ECC might be clocked off for PPN + if (!fmi->is_ppn) + { + WMR_PRINT(INF, "%sECC_VERSION: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_VERSION)); + WMR_PRINT(INF, "%sECC_CON0: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_CON0)); + WMR_PRINT(INF, "%sECC_CON1: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_CON1)); + + // ECC_RESULT is a fifo head; reading from it changes state, and therefore it won't be + // included in the spew function + //WMR_PRINT(INF, "%sECC_RESULT: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_RESULT)); + + WMR_PRINT(INF, "%sECC_PND: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PND)); + WMR_PRINT(INF, "%sECC_MASK: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_MASK)); + WMR_PRINT(INF, "%sECC_HISTORY: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_HISTORY)); + WMR_PRINT(INF, "%sECC_CORE_SW_RESET: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_CORE_SW_RESET)); +#if FMI_VERSION <= 2 + WMR_PRINT(INF, "%sECC_LOC0: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_LOC0)); + WMR_PRINT(INF, "%sECC_LOC1: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_LOC1)); + WMR_PRINT(INF, "%sECC_LOC2: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_LOC2)); + WMR_PRINT(INF, "%sECC_LOC3: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_LOC3)); + WMR_PRINT(INF, "%sECC_LOC4: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_LOC4)); + WMR_PRINT(INF, "%sECC_LOC5: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_LOC5)); + WMR_PRINT(INF, "%sECC_LOC6: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_LOC6)); + WMR_PRINT(INF, "%sECC_PARITY0: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PARITY0)); + WMR_PRINT(INF, "%sECC_PARITY1: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PARITY1)); + WMR_PRINT(INF, "%sECC_PARITY2: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PARITY2)); + WMR_PRINT(INF, "%sECC_PARITY3: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PARITY3)); + WMR_PRINT(INF, "%sECC_PARITY4: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PARITY4)); + WMR_PRINT(INF, "%sECC_PARITY5: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PARITY5)); + WMR_PRINT(INF, "%sECC_PARITY6: 0x%08X\n", prefix, h2fmi_rd(fmi, ECC_PARITY6)); +#endif + } + else + { + WMR_PRINT(INF, "%s: omitting ecc registers for ppn device\n", prefix); + } +} + +void h2fmi_spew_regs(h2fmi_t* fmi, + const char* prefix) +{ + h2fmi_spew_fmi_regs(fmi, prefix); + h2fmi_spew_fmc_regs(fmi, prefix); + h2fmi_spew_ecc_regs(fmi, prefix); +} + +void h2fmi_spew_buffer(UInt8* buf, + UInt32 size) +{ + UInt32 idx; + + for (idx = 0; idx < size; idx++) + { + if (!idx) + { + WMR_PRINT(INF, "0x%08X: ", (UInt32)buf); + } + else if (!(idx % 16)) + { + WMR_PRINT(INF, "\n0x%08X: ", ((UInt32)buf) + idx); + } + else if (!(idx % 4)) + { + WMR_PRINT(INF, " "); + } + WMR_PRINT(INF, "%02X", buf[idx]); + } + WMR_PRINT(INF, "\n"); +} + +#endif // H2FMI_DEBUG + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_dma.h b/drivers/apple/h2fmi/H2fmi_dma.h new file mode 100644 index 0000000..85d37ef --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_dma.h @@ -0,0 +1,45 @@ +// ***************************************************************************** +// +// File: H2fmi_dma.h +// +// ***************************************************************************** +// +// Notes: +// +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** +#include "H2fmi_private.h" +#include "H2fmi_dma_types.h" + +#ifndef _H2FMI_DMA_H_ +#define _H2FMI_DMA_H_ + +BOOL32 h2fmi_dma_execute_cmd(UInt32 cmd, int dma_channel, + void *src, void *dst, UInt32 length, + UInt32 word_size, UInt32 burst_size, + struct dma_aes_config *config); + + +BOOL32 h2fmi_dma_execute_async(UInt32 cmd, Int32 dma_channel, + struct dma_segment *sgl, void *fifo, UInt32 length, + UInt32 word_size, UInt32 burst_size, + struct dma_aes_config *config); + +BOOL32 h2fmi_dma_wait(int dma_channel, UInt32 timeoutUs); + +void h2fmi_dma_cancel(int dma_channel); + +#endif //_H2FMI_DMA_H_ + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_dma_iboot.c b/drivers/apple/h2fmi/H2fmi_dma_iboot.c new file mode 100644 index 0000000..45f71dc --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_dma_iboot.c @@ -0,0 +1,198 @@ +// ***************************************************************************** +// +// File: H2fmi_dma_iboot.c +// +// ***************************************************************************** +// +// Notes: +// +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_dma.h" +#include +#include +#include +#include "WMROAM.h" + +#define H2FMI_DMA_POLLING_ENABLED (1) + +#if !H2FMI_DMA_POLLING_ENABLED + +static struct task_event dma_events[DMA_CHANNEL_COUNT]; +static BOOL32 first_time = TRUE32; + + +static void h2fmi_dma_done_handler(void *arg) +{ + UInt32 channel = (UInt32)arg; + + event_signal(&dma_events[channel]); +} + +#endif // !H2FMI_DMA_POLLING_ENABLED + + +// no timeout - rdar://6403538 +BOOL32 h2fmi_dma_execute_cmd(UInt32 cmd, int dma_channel, + void *src, void *dst, UInt32 length, + UInt32 word_size, UInt32 burst_size, + struct dma_aes_config *config) +{ + struct dma_segment sgl; + BOOL32 ret; + + sgl.paddr = (UInt32)src; + sgl.length = length; + + ret = h2fmi_dma_execute_async(cmd, + dma_channel, + &sgl, + dst, + length, + word_size, + burst_size, + config); + if( !ret ) + { + return FALSE32; + } + + h2fmi_dma_wait(dma_channel, 0); + + return TRUE32; +} + + +BOOL32 h2fmi_dma_execute_async(UInt32 cmd, Int32 dma_channel, + struct dma_segment *sgl, void *fifo, UInt32 length, + UInt32 word_size, UInt32 burst_size, + struct dma_aes_config *config) +{ + int ret; + +#if !H2FMI_DMA_POLLING_ENABLED + + if (first_time ) + { + UInt32 i; + first_time = FALSE32; + + for (i = 0; i < DMA_CHANNEL_COUNT; i++) + { + event_init(&dma_events[i], EVENT_FLAG_AUTO_UNSIGNAL, false); + } + } + + WMR_ASSERT(!dma_events[dma_channel].signalled); + if (dma_events[dma_channel].signalled) + { + /* This dma channel already has a completion pending. Clear it now so things + * don't get out of sync, but if this happens it's because sometime in the past + * someone called h2fmi_dma_execute_async without calling either h2fmi_dma_wait or h2fmi_dma_cancel. + */ + WMR_PRINT(ERROR, "%s called when completion already pending. Recovering, but this is a bug.", __FUNCTION__); + event_unsignal(&dma_events[dma_channel]); + } + +#endif // !H2FMI_DMA_POLLING_ENABLED + + dma_set_aes(dma_channel, config); + + ret = dma_execute_async(cmd, + dma_channel, + sgl, + fifo, + length, + word_size, + burst_size, +#if H2FMI_DMA_POLLING_ENABLED + NULL, + NULL); +#else // H2FMI_DMA_POLLING_ENABLED + h2fmi_dma_done_handler, + (void*)dma_channel); +#endif // !H2FMI_DMA_POLLING_ENABLED + + if (ret != 0) + { + WMR_PRINT(ERROR, "WMR_DMA_START_ASYNC_FAILED: direction=%d, channel=%d, length=%d\n", + cmd, dma_channel, length); + return FALSE32; + } + else + { + return TRUE32; + } +} + + +BOOL32 h2fmi_dma_wait(int dma_channel, UInt32 timeoutUs) +{ + BOOL32 ret = TRUE32; + +#if H2FMI_DMA_POLLING_ENABLED + + const UInt64 startUs = WMR_CLOCK_NATIVE(); + + dma_use_int(dma_channel, FALSE32); + + while (!dma_poll(dma_channel)) + { + if ((0 != timeoutUs) && WMR_HAS_TIME_ELAPSED_US(startUs, timeoutUs)) + { + ret = dma_poll(dma_channel); + break; + } + + WMR_YIELD(); + } + + dma_use_int(dma_channel, TRUE32); + +#else // H2FMI_DMA_POLLING_ENABLED + + if (timeoutUs ) + { + ret = event_wait_timeout(&dma_events[dma_channel], timeoutUs); + } + else + { + // Wait forever if timeout is zero + event_wait(&dma_events[dma_channel]); + ret = TRUE32; + } + +#endif // !H2FMI_DMA_POLLING_ENABLED + + if (!ret) + { + WMR_PRINT(ERROR, "Timeout waiting for DMA: channel=%d\n", dma_channel); + WMR_PANIC("dma timeout"); + } + + return ret; +} + +void h2fmi_dma_cancel(int dma_channel) +{ + dma_cancel(dma_channel); +#if !H2FMI_DMA_POLLING_ENABLED + event_unsignal(&dma_events[dma_channel]); +#endif // !H2FMI_DMA_POLLING_ENABLED +} + + +// ********************************** EOF ************************************** + diff --git a/drivers/apple/h2fmi/H2fmi_dma_types.h b/drivers/apple/h2fmi/H2fmi_dma_types.h new file mode 100644 index 0000000..c3545c8 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_dma_types.h @@ -0,0 +1,81 @@ +// ***************************************************************************** +// +// File: H2fmi_dma.h +// +// ***************************************************************************** +// +// Notes: +// +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "WMRFeatures.h" + +#ifndef _H2FMI_DMA_TYPES_H_ +#define _H2FMI_DMA_TYPES_H_ + +#if H2FMI_EFI + +#include "SoC.h" + +// These should match iBoot include/drivers/aes.h +#define AES_CMD_ENC (0x00000000) +#define AES_CMD_DEC (0x00000001) +#define AES_CMD_DIR_MASK (0x0000000F) +#define AES_CMD_ECB (0x00000000) +#define AES_CMD_CBC (0x00000010) +#define AES_CMD_MODE_MASK (0x000000F0) + +#define AES_KEY_TYPE_USER (0x00000000) +#define AES_KEY_TYPE_UID0 (0x00000100) +#define AES_KEY_TYPE_GID0 (0x00000200) +#define AES_KEY_TYPE_GID1 (0x00000201) +#define AES_KEY_TYPE_MASK (0x00000FFF) + +#define AES_KEY_SIZE_128 (0x00000000) +#define AES_KEY_SIZE_192 (0x10000000) +#define AES_KEY_SIZE_256 (0x20000000) +#define AES_KEY_SIZE_MASK (0xF0000000) + +// This should match iBoot include/drivers/dma.h +struct dma_aes_config { + /* AES configuration */ + UInt32 command; /* AES_CMD bits from */ + UInt32 keying; /* AES_KEY bits from */ + void *key; /* AES key for AES_KEY_TYPE_USER */ + + /* IV generation */ + UInt32 chunk_size; /* AES chunk size */ + void (* iv_func)(void *arg, UInt32 chunk_index, void *iv_buffer); + void *iv_func_arg; +}; + + +struct dma_segment { + UInt32 paddr; + UInt32 length; +}; +typedef void (* dma_completion_function)(void *); + +#else //!H2FMI_EFI + +#include +#include +#include + +#endif //!H2FMI_EFI + +#endif //_H2FMI_DMA_TYPES_H_ + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_erase.c b/drivers/apple/h2fmi/H2fmi_erase.c new file mode 100644 index 0000000..4a85452 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_erase.c @@ -0,0 +1,303 @@ +// ***************************************************************************** +// +// File: H2fmi_erase.c +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" + +/** + * Define the following to simulate erase status failures. + */ +//??#define SIMULATE_ERASE_FAILURES + +#if defined(SIMULATE_ERASE_FAILURES) +#define ERASE_FAILURE_MAGIC_NUMBER 1301 +static unsigned long ulFailureCount = 0; +#endif + +// ============================================================================= +// private implementation function declarations +// ============================================================================= + +static void h2fmi_start_nand_block_erase(h2fmi_t* fmi, UInt32 page); +static void h2fmi_config_erase_page_addr(h2fmi_t* fmi, UInt32 page); + +/** + * Same as h2fmi_wait_status except also tests to ensure + * the write protect bit is off. Used for erase mode as a + * sanity check as some NAND have been known to fail with + * 'stuck' write protects. + * + * @param fmi + * + * @return CE_STATE + */ +static BOOL32 h2fmi_wait_erase_status(h2fmi_t* fmi, + UInt8 io_mask, + UInt8 io_cond, + UInt8* status) +{ + UInt8 bStatus; + BOOL32 bResult = h2fmi_wait_status(fmi,io_mask,io_cond,&bStatus); + + if ( bResult ) + { + const UInt32 bWPDisabled = (bStatus & NAND_STATUS__WRITE_PROTECT); + + WMR_ASSERT(bWPDisabled); + } + + if ( NULL!=status ) + { + *status = bStatus; + } + + return bResult; +} + + +// ============================================================================= +// public interface function definitions +// ============================================================================= + +BOOL32 h2fmi_erase_blocks(h2fmi_t* fmi, + UInt32 num_elements, + UInt16* ce, + UInt32* block, + BOOL32* status_failed) +{ + enum { + st_IDLE, + st_ERASING, + st_TIMEOUT, + st_ERROR + } ceState[ H2FMI_MAX_CE_TOTAL ]; + UInt8 nand_status; + UInt32 k; + UInt32 wIndex; + BOOL32 result = TRUE32; + + for ( k=0; k<( sizeof(ceState)/sizeof(ceState[0]) ); k++ ) + { + ceState[k] = st_IDLE; + } + + // remember initial FMC_IF_CTRL setting + const UInt32 fmc_if_ctrl = h2fmi_rd(fmi, FMC_IF_CTRL); + + // disable write protect + h2fmi_set_if_ctrl(fmi, FMC_IF_CTRL__WPB | fmc_if_ctrl); + + fmi->failureDetails.wNumCE_Executed = fmi->failureDetails.wOverallOperationFailure = 0; + fmi->failureDetails.wFirstFailingCE = ~0; + for ( wIndex=0; wIndexfailureDetails.wFirstFailingCE = wCurrentCE; + /** + * Early failure -- break out of this loop as soon as we see a + * failure occur. + */ + break; + } + else + { + const UInt32 status1 = (nand_status & NAND_STATUS__CHIP_STATUS1); + + ceState[wCurrentCE] = ( 0==status1 ? st_IDLE : st_ERROR ); +#if defined(SIMULATE_ERASE_FAILURES) + if ( (ulFailureCount++)>=ERASE_FAILURE_MAGIC_NUMBER ) + { + ulFailureCount = 0; + ceState[wCurrentCE] = st_ERROR; + WMR_PRINT(ALWAYS,"Simulated erase failure on ce %d\n",wCurrentCE); + } +#endif + if ( st_ERROR==ceState[wCurrentCE] ) + { + h2fmi_fail(result); + fmi->failureDetails.wFirstFailingCE = wCurrentCE; + break; + } + } + } + else + { + /** + * Kick off as many as we can -- we know the first one will work + * given the above test (if it were in an error state we would + * have already exited the top-level for loop). + */ + for ( k=wIndex; kpages_per_block; + + // enable specified nand device + h2fmi_fmc_enable_ce(fmi, wThisCE); + + // start nand erase operation + h2fmi_start_nand_block_erase(fmi, wThisPage); + + ceState[wThisCE] = st_ERASING; + fmi->failureDetails.wNumCE_Executed++; + } + } + } + } + + /** + * We're out of the above loop -- for better or for worse. + * Ensure we wait until all CE's have completed. + */ + for ( k=wIndex; kfailureDetails.wFirstFailingCE ) + { + fmi->failureDetails.wFirstFailingCE = wThisCE; + } + } + else + { + const UInt32 status1 = (nand_status & NAND_STATUS__CHIP_STATUS1); + ceState[wThisCE] = ( 0==status1 ? st_IDLE : st_ERROR ); +#if defined(SIMULATE_ERASE_FAILURES) + if ( (ulFailureCount++)>=ERASE_FAILURE_MAGIC_NUMBER ) + { + ulFailureCount = 0; + ceState[wThisCE] = st_ERROR; + WMR_PRINT(ALWAYS,"Simulated erase failure on ce %d\n",wThisCE); + } +#endif + if ( st_ERROR==ceState[wThisCE] ) + { + h2fmi_fail(result); + if ( (UInt32)~0 == fmi->failureDetails.wFirstFailingCE ) + { + fmi->failureDetails.wFirstFailingCE = wThisCE; + } + } + } + } + } + + + // return write protect to previous state + h2fmi_set_if_ctrl(fmi, fmc_if_ctrl); + + // disable all nand devices + h2fmi_fmc_disable_all_ces(fmi); + + // possibly return by reference whether Read Status indicated failure + if (NULL != status_failed) + { + *status_failed = ( TRUE32==result ? FALSE32 : TRUE32 ); + } + + return result; +} + +// ============================================================================= +// private implementation function definitions +// ============================================================================= + +static void h2fmi_start_nand_block_erase(h2fmi_t* fmi, + UInt32 page) +{ + const UInt32 cmd1_addr_cmd2_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD2DONE | + FMC_STATUS__CMD1DONE); + + // configure FMC for cmd1/addr/cmd2 sequence + h2fmi_config_erase_page_addr(fmi, page); + h2fmi_wr(fmi, FMC_CMD, (FMC_CMD__CMD1(NAND_CMD__ERASE) | + FMC_CMD__CMD2(NAND_CMD__ERASE_CONFIRM))); + + // start cmd1/addr/cmd2 sequence + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD2_MODE | + FMC_RW_CTRL__CMD1_MODE)); + + // busy wait until cmd1/addr/cmd2 sequence completed + h2fmi_busy_wait(fmi, FMC_STATUS, cmd1_addr_cmd2_done, cmd1_addr_cmd2_done); + h2fmi_wr(fmi, FMC_STATUS, cmd1_addr_cmd2_done); +} + +static void h2fmi_config_erase_page_addr(h2fmi_t* fmi, + UInt32 page) +{ + const UInt32 page_addr_size = 3; + const UInt32 page_addr_2 = (page >> 16) & 0xFF; + const UInt32 page_addr_1 = (page >> 8) & 0xFF; + const UInt32 page_addr_0 = (page >> 0) & 0xFF; + + h2fmi_wr(fmi, FMC_ADDR0, (FMC_ADDR0__SEQ3(0x00) | + FMC_ADDR0__SEQ2(page_addr_2) | + FMC_ADDR0__SEQ1(page_addr_1) | + FMC_ADDR0__SEQ0(page_addr_0))); + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(page_addr_size - 1)); +} + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_iop.c b/drivers/apple/h2fmi/H2fmi_iop.c new file mode 100644 index 0000000..5ad88d4 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_iop.c @@ -0,0 +1,902 @@ +// ***************************************************************************** +// +// File: H2fmi_iop.c +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_iop.h" +#include "H2fmi_private.h" +#include "H2fmi_ppn.h" +#include "fmiss.h" + +#include +#include +#include +#include +#include +#include +#include + +// ============================================================================= +// external global variable definitions +// ============================================================================= + +extern UInt8 nand_whitening_key[16]; + +// ============================================================================= +// private function declarations +// ============================================================================= + + +bool h2fmi_setup_aes(h2fmi_t* fmi, IOPFMI* cmd, hfmi_aes_iv* aes_iv_array, UInt32 aes_chain_size, UInt32 aes_key_type, UInt32* aes_key, UInt32* seeds) +{ + if (cmd->flags & (kIOPFMI_FLAGS_USE_AES | kIOPFMI_FLAGS_HOMOGENIZE)) + { + switch (cmd->opcode) + { + case kIOPFMI_OPCODE_WRITE_SINGLE: + case kIOPFMI_OPCODE_WRITE_MULTIPLE: + case kIOPFMI_OPCODE_PPN_WRITE: + fmi->aes_cxt.command = AES_CMD_ENC; + break; + case kIOPFMI_OPCODE_READ_SINGLE: + case kIOPFMI_OPCODE_READ_MULTIPLE: + case kIOPFMI_OPCODE_PPN_READ: + fmi->aes_cxt.command = AES_CMD_DEC; + break; + default: + ASSERT(false); + return false; + break; + } + if (cmd->flags & kIOPFMI_FLAGS_USE_AES) + { + fmi->current_aes_iv_array = (hfmi_aes_iv*)aes_iv_array; + switch (aes_key_type) + { + case kIOPFMI_AES_KEY_TYPE_USER128: + fmi->aes_cxt.keying = AES_KEY_TYPE_USER | AES_KEY_SIZE_128; + fmi->aes_cxt.key = aes_key; + WMR_PRINT(CRYPTO, "Using HW key IV: 0x%08x 0x%08x 0x%08x 0x%08x\n", + aes_key[0], aes_key[1], aes_key[2], aes_key[3]); + break; + case kIOPFMI_AES_KEY_TYPE_USER192: + fmi->aes_cxt.keying = AES_KEY_TYPE_USER | AES_KEY_SIZE_192; + fmi->aes_cxt.key = aes_key; + WMR_PRINT(CRYPTO, "Using HW key IV: 0x%08x 0x%08x 0x%08x 0x%08x 0X%08x 0x%08x\n", + aes_key[0], aes_key[1], aes_key[2], aes_key[3], aes_key[4], aes_key[5]); + break; + case kIOPFMI_AES_KEY_TYPE_USER256: + fmi->aes_cxt.keying = AES_KEY_TYPE_USER | AES_KEY_SIZE_256; + fmi->aes_cxt.key = aes_key; + WMR_PRINT(CRYPTO, "Using HW key IV: 0x%08x 0x%08x 0x%08x 0x%08x 0X%08x 0x%08x 0X%08x 0x%08x\n", + aes_key[0], aes_key[1], aes_key[2], aes_key[3], aes_key[4], aes_key[5], aes_key[6], aes_key[7]); + break; + case kIOPFMI_AES_KEY_TYPE_UID0: + fmi->aes_cxt.keying = AES_KEY_TYPE_UID0; + fmi->aes_cxt.key = NULL; + WMR_PRINT(CRYPTO, "Using HW UID0\n"); + break; + case kIOPFMI_AES_KEY_TYPE_GID0: + fmi->aes_cxt.keying = AES_KEY_TYPE_GID0; + fmi->aes_cxt.key = NULL; + WMR_PRINT(CRYPTO, "Using HW GID0\n"); + break; + case kIOPFMI_AES_KEY_TYPE_GID1: + fmi->aes_cxt.keying = AES_KEY_TYPE_GID1; + fmi->aes_cxt.key = NULL; + WMR_PRINT(CRYPTO, "Using HW GID1\n"); + break; + default: + ASSERT(false); + return false; + break; + } + fmi->aes_cxt.chunk_size = aes_chain_size; + } + else + { + fmi->aes_cxt.keying = (AES_KEY_TYPE_USER | AES_KEY_SIZE_128); + fmi->aes_cxt.key = nand_whitening_key; + fmi->current_aes_iv_array = NULL; + fmi->aes_cxt.chunk_size = fmi->logical_page_size; + WMR_PRINT(CRYPTO, "Using constant AES for whitening\n"); + } + + fmi->aes_cxt.chunk_size = aes_chain_size; + fmi->aes_cxt.iv_func = h2fmi_aes_iv; + fmi->aes_cxt.iv_func_arg = fmi; + fmi->iv_seed_array = seeds; + + fmi->current_aes_cxt = &fmi->aes_cxt; + } + else + { + //WMR_PRINT(CRYPTO, "Disabling AES\n"); + fmi->current_aes_cxt = NULL; + fmi->current_aes_iv_array = NULL; + } + return true; +} + +void h2fmi_restoreFmiRegs(h2fmi_t *fmi) +{ + // Restore any register state that may have been lost + // due to power gating +#if FMI_VERSION > 2 + restoreTimingRegs(fmi); + turn_on_fmc(fmi); +#endif + +#if FMISS_ENABLED + if (!fmi->is_ppn) + { + fmiss_raw_init_sequences(fmi); + } + else + { + fmiss_init_sequences(fmi); + } +#endif +} + +// ============================================================================= +// implementation function declarations +// ============================================================================= + +void h2fmi_iop_set_config(h2fmi_t* fmi, IOPFMI_SetConfig* cmd) +{ + // record which interface is being used + dprintf(DEBUG_SPEW, "configuring FMI%d\n", cmd->fmi); + fmi->regs = (cmd->fmi == 0) ? FMI0 : FMI1; + fmi->bus_id = cmd->fmi; + + // record necessary device geometry information + fmi->bytes_per_spare = cmd->bytes_per_spare; + fmi->num_of_ce = cmd->num_of_ce; + fmi->pages_per_block = cmd->pages_per_block; + fmi->blocks_per_ce = cmd->blocks_per_ce; + fmi->total_bytes_per_meta = cmd->total_bytes_per_meta; + fmi->valid_bytes_per_meta = cmd->valid_bytes_per_meta; + fmi->bytes_per_page = cmd->bytes_per_page; + fmi->sectors_per_page = fmi->bytes_per_page / H2FMI_BYTES_PER_SECTOR; + fmi->valid_ces = cmd->valid_ces; + fmi->is_ppn = cmd->ppn; + fmi->logical_page_size = cmd->logical_page_size; + fmi->clock_speed_khz = cmd->clock_speed_khz; + + // TODO: decide on appropriate infrastructure in support of + // vendor-specific superblock formats and command sequences + fmi->banks_per_ce = 1; + + // calculate and store bus interface timing control + WMR_PRINT(INF, "cmd->read_sample_cycles : %d\n", cmd->read_sample_cycles); + WMR_PRINT(INF, "cmd->read_setup_cycles : %d\n", cmd->read_setup_cycles); + WMR_PRINT(INF, "cmd->read_hold_cycles : %d\n", cmd->read_hold_cycles); + WMR_PRINT(INF, "cmd->write_setup_cycles : %d\n", cmd->write_setup_cycles); + WMR_PRINT(INF, "cmd->write_hold_cycles : %d\n", cmd->write_hold_cycles); + + fmi->if_ctrl = (FMC_IF_CTRL__DCCYCLE(cmd->read_sample_cycles) | + FMC_IF_CTRL__REB_SETUP(cmd->read_setup_cycles) | + FMC_IF_CTRL__REB_HOLD(cmd->read_hold_cycles) | + FMC_IF_CTRL__WEB_SETUP(cmd->write_setup_cycles) | + FMC_IF_CTRL__WEB_HOLD(cmd->write_hold_cycles)); + + WMR_PRINT(INF, "cmd->retire_on_invalid_refresh : %d\n", cmd->retire_on_invalid_refresh); + fmi->retire_on_invalid_refresh = cmd->retire_on_invalid_refresh; + +#if SUPPORT_TOGGLE_NAND + fmi->is_toggle_system = cmd->toggle_system; + fmi->is_toggle = cmd->toggle; + + if (fmi->is_toggle) + { + WMR_PRINT(INF, "cmd->ce_hold_cycles : %d\n", cmd->ce_hold_cycles); + WMR_PRINT(INF, "cmd->ce_setup_cycles : %d\n", cmd->ce_setup_cycles); + WMR_PRINT(INF, "cmd->adl_cycles : %d\n", cmd->adl_cycles); + WMR_PRINT(INF, "cmd->whr_cycles : %d\n", cmd->whr_cycles); + WMR_PRINT(INF, "cmd->read_pre_cycles : %d\n", cmd->read_pre_cycles); + WMR_PRINT(INF, "cmd->read_post_cycles : %d\n", cmd->read_post_cycles); + WMR_PRINT(INF, "cmd->write_pre_cycles : %d\n", cmd->write_pre_cycles); + WMR_PRINT(INF, "cmd->write_post_cycles : %d\n", cmd->write_post_cycles); + WMR_PRINT(INF, "cmd->enable_diff_DQS : %d\n", cmd->enable_diff_DQS); + WMR_PRINT(INF, "cmd->enable_diff_RE : %d\n", cmd->enable_diff_RE); + WMR_PRINT(INF, "cmd->enable_VREF : %d\n", cmd->enable_VREF); + + fmi->dqs_ctrl = cmd->reg_dqs_delay; + fmi->timing_ctrl_1 = (FMC_TOGGLE_CTRL_1_DDR_RD_PRE_TIME(cmd->read_pre_cycles) | + FMC_TOGGLE_CTRL_1_DDR_RD_POST_TIME(cmd->read_post_cycles) | + FMC_TOGGLE_CTRL_1_DDR_WR_PRE_TIME(cmd->write_pre_cycles) | + FMC_TOGGLE_CTRL_1_DDR_WR_POST_TIME(cmd->write_post_cycles)); + fmi->timing_ctrl_2 = (FMC_TOGGLE_CTRL_2_CE_SETUP_TIME(cmd->ce_setup_cycles) | + FMC_TOGGLE_CTRL_2_CE_HOLD_TIME(cmd->ce_hold_cycles) | + FMC_TOGGLE_CTRL_2_NAND_TIMING_ADL(cmd->adl_cycles) | + FMC_TOGGLE_CTRL_2_NAND_TIMING_WHR(cmd->whr_cycles)); + fmi->toggle_if_ctrl = (FMC_IF_CTRL__DCCYCLE(0) | + FMC_IF_CTRL__REB_SETUP(cmd->dqs_half_cycles) | + FMC_IF_CTRL__REB_HOLD(0) | + FMC_IF_CTRL__WEB_SETUP(cmd->write_setup_cycles) | + FMC_IF_CTRL__WEB_HOLD(cmd->write_hold_cycles)); + fmi->useDiffDQS = cmd->enable_diff_DQS; + fmi->useDiffRE = cmd->enable_diff_RE; + fmi->useVREF = cmd->enable_VREF; + } +#endif + + h2fmi_restoreFmiRegs(fmi); + + // always report config information + WMR_PRINT(INF, "fmi->regs : %p\n", fmi->regs); + WMR_PRINT(INF, "fmi->valid_ces : %p\n", fmi->valid_ces); + WMR_PRINT(INF, "fmi->num_of_ce : %p\n", fmi->num_of_ce); + WMR_PRINT(INF, "fmi->banks_per_ce : %p\n", fmi->banks_per_ce); + WMR_PRINT(INF, "fmi->pages_per_block : %p\n", fmi->pages_per_block); + WMR_PRINT(INF, "fmi->sectors_per_page : %p\n", fmi->sectors_per_page); + WMR_PRINT(INF, "fmi->bytes_per_spare : %p\n", fmi->bytes_per_spare); + WMR_PRINT(INF, "fmi->blocks_per_ce : %p\n", fmi->blocks_per_ce); + WMR_PRINT(INF, "fmi->valid_bytes_per_meta : %p\n", fmi->valid_bytes_per_meta); + WMR_PRINT(INF, "fmi->total_bytes_per_meta : %p\n", fmi->total_bytes_per_meta); + WMR_PRINT(INF, "fmi->if_ctrl : %p\n", fmi->if_ctrl); +#if SUPPORT_TOGGLE_NAND + if (fmi->is_toggle) + { + WMR_PRINT(INF, "fmi->dqs_ctrl : %p\n", fmi->dqs_ctrl); + WMR_PRINT(INF, "fmi->timing_ctrl_1 : %p\n", fmi->timing_ctrl_1); + WMR_PRINT(INF, "fmi->timing_ctrl_2 : %p\n", fmi->timing_ctrl_2); + WMR_PRINT(INF, "fmi->toggle_if_ctrl : %p\n", fmi->toggle_if_ctrl); + WMR_PRINT(INF, "fmi->is_toggle : %p\n", fmi->is_toggle); + } +#endif + WMR_PRINT(INF, "fmi->bytes_per_page : %p\n", fmi->bytes_per_page); + WMR_PRINT(INF, "fmi->is_ppn : %p\n", fmi->is_ppn); + + // these steps are only taken when fmi is first configured + if (!fmi->initialized) + { + // Make certain the FMC is enabled upon init. + turn_on_fmc(fmi); + + // Perform system-specific initialization. + h2fmi_init_sys(fmi); + + // indicate that fmi is initialized + fmi->initialized = TRUE32; + + fmi->stateMachine.currentMode = fmiNone; + fmi->wMaxOutstandingCEWriteOperations = cmd->wMaxOutstandingCEWriteOperations; + } + + fmi->activeCe = ~0; + if (fmi->is_ppn && (!fmi->is_ppn_channel_init)) + { +#if SUPPORT_PPN + if (!h2fmi_ppn_init_channel(fmi, + cmd->ppn_debug_flags_valid, + cmd->ppn_debug_flags, + cmd->ppn_vs_debug_flags_valid, + cmd->ppn_vs_debug_flags, + cmd->ppn_allow_saving_debug_data, + cmd->ppn_version)) + { + WMR_PANIC("[FIL:ERR] Unable to initialize PPN device\n"); + cmd->iopfmi.status = kIOPFMI_STATUS_FAILURE; + return; + } + fmi->is_ppn_channel_init = TRUE32; +#else + WMR_PANIC("!SUPPORT_PPN"); +#endif + } + + // Cache page config registers + if (fmi->is_ppn) + { +#if SUPPORT_PPN + fmi->fmi_config_reg = h2fmi_ppn_calculate_fmi_config(fmi); + +#if FMI_VERSION > 0 + fmi->fmi_data_size_reg = h2fmi_ppn_calculate_fmi_data_size(fmi); +#endif /* FMI_VERSION > 0*/ +#else //SUPPORT_PPN + WMR_PANIC("!SUPPORT_PPN"); +#endif //SUPPORT_PPN + } + else + { + // Cache ECC configuration + fmi->correctable_bits = h2fmi_calculate_ecc_bits(fmi); + + fmi->fmi_config_reg = h2fmi_calculate_fmi_config(fmi); +#if FMI_VERSION > 0 + fmi->fmi_data_size_reg = h2fmi_calculate_fmi_data_size(fmi); +#endif /* FMI_VERSION > 0*/ + } + // record success status in command structure + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; +} + +void h2fmi_iop_read_chip_ids(h2fmi_t* fmi, IOPFMI_ReadChipIDs* cmd) +{ + IOPFMI_chipid_t* ids_buf = (IOPFMI_chipid_t*)mem_static_map_cached(cmd->chip_id_buffer); + IOPFMI_status_t status = kIOPFMI_STATUS_SUCCESS; + UInt32 valid_ces; + UInt32 ce; + + WMR_ASSERT(ids_buf != MAP_FAILED); + + valid_ces = fmi->valid_ces; + fmi->valid_ces = 0xffff; + + for (ce = 0; ce < H2FMI_MAX_CE_TOTAL; ce++) + { + h2fmi_chipid_t* chipid = (h2fmi_chipid_t*)&ids_buf[ce]; + UInt8 *ptr = (UInt8 *)&ids_buf[ce]; + + if (!h2fmi_nand_read_id(fmi, ce, chipid, CHIPID_ADDR)) + { + status = kIOPFMI_STATUS_FAILED_READ_ID; + break; + } + + WMR_PRINT(INF, "Read Chip ID %02X %02X %02X %02X %02X %02X to %p\n", + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], chipid); + } + fmi->valid_ces = valid_ces; + cmd->iopfmi.status = status; + + WMR_PREPARE_WRITE_BUFFER(ids_buf, H2FMI_MAX_CE_TOTAL * sizeof(IOPFMI_chipid_t)); +} + + +void h2fmi_iop_reset_everything(h2fmi_t* fmi, IOPFMI_ResetEverything* cmd) +{ + IOPFMI_status_t status = kIOPFMI_STATUS_SUCCESS; + BOOL32 ret = TRUE32; + + h2fmi_reset(fmi); + + h2fmi_init_sys(fmi); + + ret = h2fmi_nand_reset_all(fmi); + if (!ret) + { + status = kIOPFMI_STATUS_FAILED_RESET_ALL; + } +} + +void h2fmi_iop_erase_multiple(h2fmi_t* fmi, IOPFMI_EraseMultiple* cmd) +{ + BOOL32 erase_failed = FALSE32; + + WMR_PRINT(ERASE, "IOP received Multi-Erase command %d elements\n", cmd->number_of_elements); + + if (!h2fmi_erase_blocks(fmi, + cmd->number_of_elements, + cmd->ce, + cmd->block_number, + &erase_failed)) + { + cmd->iopfmi.status = kIOPFMI_STATUS_FAILED_ERASE_BLOCK; + } + else if (erase_failed) + { + cmd->iopfmi.status = kIOPFMI_STATUS_DEVICE_ERROR; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } + + /** + * Copy erase status back out ... + */ + cmd->failure_details.wNumCE_Executed = fmi->failureDetails.wNumCE_Executed; + cmd->failure_details.wFirstFailingCE = fmi->failureDetails.wFirstFailingCE; +} + +void h2fmi_iop_erase_single(h2fmi_t* fmi, IOPFMI_EraseSingle* cmd) +{ + BOOL32 erase_failed = FALSE32; + + WMR_PRINT(ERASE, "IOP received Erase command CE %d Block %d\n", cmd->ce, cmd->block_number); + + fmi->failureDetails.wCEStatusArray = &fmi->failureDetails.wSingleCEStatus; + fmi->failureDetails.wCEStatusArrayModulusMask = 0; + + if (!h2fmi_erase_blocks(fmi, + 1, + &cmd->ce, + &cmd->block_number, + &erase_failed)) + { + cmd->iopfmi.status = kIOPFMI_STATUS_FAILED_ERASE_BLOCK; + } + else if (erase_failed) + { + cmd->iopfmi.status = kIOPFMI_STATUS_DEVICE_ERROR; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } + /** + * Copy erase status back out ... + */ + cmd->failure_details.wNumCE_Executed = fmi->failureDetails.wNumCE_Executed; + cmd->failure_details.wSingleCEStatus = fmi->failureDetails.wSingleCEStatus; +} + +void h2fmi_iop_read_single(h2fmi_t* fmi, IOPFMI_IOSingle* cmd) +{ + BOOL32 gather_corrections = (0 != cmd->correction_address); + + UInt8* correct_buf = (gather_corrections + ? (UInt8*)mem_static_map_cached(cmd->correction_address) + : NULL); + + UInt8* data_buf = (UInt8*)cmd->data_address; + UInt8* meta_buf = (UInt8*)cmd->meta_address; + hfmi_aes_iv* aes_iv_array = NULL; + + WMR_ASSERT(correct_buf != MAP_FAILED); + + WMR_PRINT(READ, "IOP received Read Single command CE %d Block %d\n", cmd->ce, cmd->page_number); + + if (cmd->aes_iv_array) + { + aes_iv_array = (hfmi_aes_iv*)mem_static_map_cached(cmd->aes_iv_array); + WMR_ASSERT(aes_iv_array != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(aes_iv_array, cmd->aes_num_chains * sizeof(hfmi_aes_iv)); + } + + h2fmi_setup_aes(fmi, &cmd->iopfmi, aes_iv_array, cmd->aes_chain_size, cmd->aes_key_type, (UInt32*)cmd->aes_key_bytes, &cmd->page_number); + + cmd->iopfmi.status = h2fmi_read_page(fmi, + cmd->ce, + cmd->page_number, + data_buf, + meta_buf, + correct_buf, + NULL); + + // clean corrections buffer, if not NULL + if (gather_corrections) + { + WMR_PREPARE_WRITE_BUFFER(correct_buf, + fmi->sectors_per_page * sizeof(IOPFMI_correction_t)); + } +} + +void h2fmi_iop_read_multiple(h2fmi_t* fmi, IOPFMI_IOMultiple* cmd) +{ + const UInt32 page_count = cmd->page_count; + + BOOL32 gather_corrections = (0 != cmd->corrections_array); + UInt8* corrections_array = (gather_corrections + ? (UInt8*)mem_static_map_cached(cmd->corrections_array) + : NULL); + + h2fmi_ce_t* chip_enable_array = (h2fmi_ce_t*)mem_static_map_cached(cmd->chip_enable_array); + UInt32* page_number_array = (UInt32*)mem_static_map_cached(cmd->page_number_array); + hfmi_aes_iv* aes_iv_array = NULL; + + + WMR_ASSERT(corrections_array != MAP_FAILED); + WMR_ASSERT(chip_enable_array != MAP_FAILED); + WMR_ASSERT(page_number_array != MAP_FAILED); + + if (cmd->aes_iv_array) + { + aes_iv_array = (hfmi_aes_iv*)mem_static_map_cached(cmd->aes_iv_array); + WMR_ASSERT(aes_iv_array != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(aes_iv_array, cmd->aes_num_chains * sizeof(hfmi_aes_iv)); + } + + // Invalidate control arrays, ensuring that these values are + // re-read from physical memory. + WMR_PREPARE_READ_BUFFER(chip_enable_array, page_count * sizeof(UInt32)); + WMR_PREPARE_READ_BUFFER(page_number_array, page_count * sizeof(UInt32)); + + UInt32* data_segments_array = (UInt32*)mem_static_map_cached(cmd->data_segments_array); + UInt32* meta_segments_array = (UInt32*)mem_static_map_cached(cmd->meta_segments_array); + WMR_ASSERT(data_segments_array != MAP_FAILED); + WMR_ASSERT(meta_segments_array != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(data_segments_array, cmd->data_segment_array_length_in_bytes); + WMR_PREPARE_READ_BUFFER(meta_segments_array, cmd->meta_segment_array_length_in_bytes); + + h2fmi_setup_aes(fmi, &cmd->iopfmi, aes_iv_array, cmd->aes_chain_size, cmd->aes_key_type, (UInt32*)cmd->aes_key_bytes, page_number_array); + + WMR_PRINT(READ, "IOP received Read Multiple command NumPages %d\n", page_count); + + // perform multi-read + cmd->iopfmi.status = h2fmi_read_multi(fmi, + page_count, + chip_enable_array, + page_number_array, + (void*)data_segments_array, + (void*)meta_segments_array, + corrections_array, + NULL); + + // clean corrections buffer, if not NULL + if (gather_corrections) + { + WMR_PREPARE_WRITE_BUFFER(corrections_array, + page_count * fmi->sectors_per_page * sizeof(IOPFMI_correction_t)); + } + /** + * Copy failure data. + */ + cmd->failure_details.wNumCE_Executed = fmi->failureDetails.wNumCE_Executed; + cmd->failure_details.wOverallOperationFailure = fmi->failureDetails.wOverallOperationFailure; + cmd->failure_details.wFirstFailingCE = fmi->failureDetails.wFirstFailingCE; +#if (defined (WMR_DEBUG) && WMR_DEBUG) + if ( (kIOPFMI_STATUS_SUCCESS != cmd->iopfmi.status) && + (kIOPFMI_STATUS_BLANK != cmd->iopfmi.status) && + (kIOPFMI_STATUS_FUSED != cmd->iopfmi.status)) + { + unsigned k = fmi->failureDetails.wCEStatusArrayModulusMask; + WMR_PRINT(ERROR, "IOP --> err 0x%08x, %d completed on %d\n",cmd->iopfmi.status, fmi->failureDetails.wNumCE_Executed,fmi->bus_id); + while ( k>0 ) + { + WMR_PRINT(ERROR, "Status[%d] = 0x%x\n",k,fmi->failureDetails.wCEStatusArray[k]); + k--; + } + } +#endif +} + +void h2fmi_iop_write_single(h2fmi_t* fmi, IOPFMI_IOSingle* cmd) +{ + UInt8* data_buf = (UInt8*)cmd->data_address; + UInt8* meta_buf = (UInt8*)cmd->meta_address; + BOOL32 write_failed = FALSE32; + hfmi_aes_iv* aes_iv_array = NULL; + + if (cmd->aes_iv_array) + { + aes_iv_array = (hfmi_aes_iv*)mem_static_map_cached(cmd->aes_iv_array); + WMR_ASSERT(aes_iv_array != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(aes_iv_array, cmd->aes_num_chains * sizeof(hfmi_aes_iv)); + } + WMR_PRINT(WRITE, "IOP received Write Single command CE %d Block %d\n", cmd->ce, cmd->page_number); + + h2fmi_setup_aes(fmi, &cmd->iopfmi, aes_iv_array, cmd->aes_chain_size, cmd->aes_key_type, (UInt32*)cmd->aes_key_bytes, &cmd->page_number); + + if (!h2fmi_write_page(fmi, + cmd->ce, + cmd->page_number, + data_buf, + meta_buf, + &write_failed)) + { + cmd->iopfmi.status = kIOPFMI_STATUS_FAILED_WRITE_PAGE; + } + else if (write_failed) + { + cmd->iopfmi.status = kIOPFMI_STATUS_DEVICE_ERROR; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } +} + +void h2fmi_iop_write_multiple(h2fmi_t* fmi, IOPFMI_IOMultiple* cmd) +{ + const UInt32 page_count = cmd->page_count; + + h2fmi_ce_t* chip_enable_array = (h2fmi_ce_t*)mem_static_map_cached(cmd->chip_enable_array); + UInt32* page_number_array = (UInt32*)mem_static_map_cached(cmd->page_number_array); + + BOOL32 write_failed = FALSE32; + hfmi_aes_iv* aes_iv_array = NULL; + + WMR_ASSERT(chip_enable_array != MAP_FAILED); + WMR_ASSERT(page_number_array != MAP_FAILED); + + if (cmd->aes_iv_array) + { + aes_iv_array = (hfmi_aes_iv*)mem_static_map_cached(cmd->aes_iv_array); + WMR_ASSERT(aes_iv_array != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(aes_iv_array, cmd->aes_num_chains * sizeof(hfmi_aes_iv)); + } + // Invalidate control arrays, ensuring that these values are + // re-read from physical memory. + WMR_PREPARE_READ_BUFFER(chip_enable_array, page_count * sizeof(UInt32)); + WMR_PREPARE_READ_BUFFER(page_number_array, page_count * sizeof(UInt32)); + + UInt32* data_segments_array = (UInt32*)mem_static_map_cached(cmd->data_segments_array); + UInt32* meta_segments_array = (UInt32*)mem_static_map_cached(cmd->meta_segments_array); + + WMR_ASSERT(data_segments_array != MAP_FAILED); + WMR_ASSERT(meta_segments_array != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(data_segments_array, cmd->data_segment_array_length_in_bytes); + WMR_PREPARE_READ_BUFFER(meta_segments_array, cmd->meta_segment_array_length_in_bytes); + + WMR_PRINT(WRITE, "IOP received Write Multiple command NumPages %d\n", page_count); + + h2fmi_setup_aes(fmi, &cmd->iopfmi, aes_iv_array, cmd->aes_chain_size, cmd->aes_key_type, (UInt32*)cmd->aes_key_bytes, page_number_array); + + // perform multi-write + if (!h2fmi_write_multi(fmi, + page_count, + chip_enable_array, + page_number_array, + (void*)data_segments_array, + (void*)meta_segments_array, + &write_failed, + cmd->vendorProtocol)) + { + cmd->iopfmi.status = kIOPFMI_STATUS_FAILED_WRITE_MULTI; + } + else if (write_failed) + { + cmd->iopfmi.status = kIOPFMI_STATUS_DEVICE_ERROR; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } + /** + * Copy failure data. + */ + cmd->failure_details.wNumCE_Executed = fmi->failureDetails.wNumCE_Executed; + cmd->failure_details.wFirstFailingCE = fmi->failureDetails.wFirstFailingCE; +} + +void h2fmi_iop_read_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd) +{ + UInt8* page_buf = (UInt8*)(cmd->buffer_address); + + UInt8* data_buf = page_buf + 0; + UInt8* spare_buf = page_buf + fmi->bytes_per_page; + + fmi->current_aes_cxt = NULL; + + WMR_PRINT(READ, "IOP received Read Raw command CE %d Page %d\n", cmd->ce, cmd->page_number); + + if (!h2fmi_read_raw_page(fmi, + cmd->ce, + cmd->page_number, + data_buf, + spare_buf)) + { + cmd->iopfmi.status = kIOPFMI_STATUS_FAILED_READ_RAW; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } +} + +void h2fmi_iop_write_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd) +{ + const UInt32 data_bytes_per_page = (fmi->sectors_per_page * H2FMI_BYTES_PER_SECTOR); + const UInt32 bytes_per_page = data_bytes_per_page + fmi->bytes_per_spare; + UInt8* page_buf = (UInt8*)cmd->buffer_address; + UInt8* data_buf = page_buf; + + // deal with cache coherency issues + const UInt32 data_clean_size = bytes_per_page; + + fmi->current_aes_cxt = NULL; + + WMR_PRINT(WRITE, "IOP sending write raw ce %d page %d data_buf %08x size %d\n", + cmd->ce, + cmd->page_number, + data_buf, + bytes_per_page); + + // Invalidate data and meta buffers, ensuring their + // contents are re-read from physical memory + WMR_PREPARE_READ_BUFFER(data_buf, data_clean_size); + + cmd->iopfmi.status = h2fmi_write_raw_page(fmi, + cmd->ce, + cmd->page_number, + data_buf); +} + +void h2fmi_iop_read_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd) +{ + BOOL32 gather_corrections = (0 != cmd->corrections_array); + + UInt8* corrections_array = (gather_corrections + ? (UInt8*)mem_static_map_cached(cmd->corrections_array) + : NULL); + + UInt8* page_buf = (UInt8*)cmd->buffer_address; + + WMR_ASSERT(corrections_array != MAP_FAILED); + + fmi->current_aes_cxt = NULL; + + WMR_PRINT(READ, "IOP received Read Boot Page command CE %d Page %d\n", cmd->ce, cmd->page_number); + + cmd->iopfmi.status = h2fmi_read_bootpage(fmi, + cmd->ce, + cmd->page_number, + page_buf, + corrections_array); + + // clean corrections buffer, if not NULL + if (gather_corrections) + { + WMR_PREPARE_WRITE_BUFFER(corrections_array, + fmi->sectors_per_page * sizeof(IOPFMI_correction_t)); + } +} + +void h2fmi_iop_write_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd) +{ + UInt8* page_buf = (UInt8*)mem_static_map_cached(cmd->buffer_address); + + WMR_ASSERT(page_buf != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(page_buf, H2FMI_BOOT_BYTES_PER_PAGE); + + fmi->current_aes_cxt = NULL; + + WMR_PRINT(WRITE, "IOP received Write Boot Page command CE %d Page %d\n", cmd->ce, cmd->page_number); + + cmd->iopfmi.status = h2fmi_write_bootpage(fmi, + cmd->ce, + cmd->page_number, + page_buf); +} + + + +void h2fmi_iop_sleep(h2fmi_t* fmi) +{ + dprintf(DEBUG_CRITICAL, "sleeping FMI%d\n", h2fmi_bus_index(fmi)); +} + +void h2fmi_iop_wake(h2fmi_t* fmi) +{ + dprintf(DEBUG_CRITICAL, "waking FMI%d\n", h2fmi_bus_index(fmi)); +} + +void dump_fmi_state(h2fmi_t *pFMI, uint32_t index, BOOL32 withHWRegs, BOOL32 withECC) +{ + /** + * Dump 'important' parts of state machine ... + */ + printf("FMI[%u] - stateMachine{mode:%d, state: %d, CEsav: %d, page_idx: %d, page_count: %d, currentCE: %d, currentPage: 0x%x, fSuccessful: %d, lastCE: %d, needsPrepare: %d, cleanPages: %d, uecc_pages: %d, cmdStartTick: 0x%llx, wVendorType: %d}\n", + index, + (int)pFMI->stateMachine.currentMode, + (int)pFMI->stateMachine.state.rd, + pFMI->stateMachine.savedCurrentCE, + pFMI->stateMachine.page_idx, + pFMI->stateMachine.page_count, + pFMI->stateMachine.currentCE, + pFMI->stateMachine.currentPage, + (int)pFMI->stateMachine.fSuccessful, + pFMI->stateMachine.lastCE, + pFMI->stateMachine.needs_prepare, + pFMI->stateMachine.clean_pages, + pFMI->stateMachine.uecc_pages, + pFMI->stateMachine.wCmdStartTicks, + pFMI->stateMachine.wVendorType); + + /** + * Dump failure details. + */ + printf("FMI[%u] - failureDetails{wNumCEexec:%d, hldoff: %d, outstd: %d/%d, overall: 0x%x, firstFailingCE: 0x%x, wSingleCEStatus: 0x%x}\n", + index, + pFMI->failureDetails.wNumCE_Executed, + pFMI->stateMachine.wNumTimesHoldoffExecuted, + pFMI->stateMachine.wOutstandingCEWriteOperations, + pFMI->stateMachine.wMaxOutstandingCEWriteOperations, + pFMI->failureDetails.wOverallOperationFailure, + pFMI->failureDetails.wFirstFailingCE, + pFMI->failureDetails.wSingleCEStatus + ); + + if (withHWRegs) + { + /** + * Dump important FMI registers ... + */ +#if FMI_VERSION <=2 + printf("FMI[%u] - fmi{bus: %d, CFG: 0x%x, CTRL: 0x%x, STAT: 0x%x, INTPND: 0x%x, INT_EN: 0x%x, DBG0: 0x%x, DBG1: 0x%x, DBG2: 0x%x}\n", + index, + pFMI->bus_id, + h2fmi_rd(pFMI,FMI_CONFIG), + h2fmi_rd(pFMI,FMI_CONTROL), + h2fmi_rd(pFMI,FMI_STATUS), + h2fmi_rd(pFMI,FMI_INT_PEND), + h2fmi_rd(pFMI,FMI_INT_EN), + h2fmi_rd(pFMI,FMI_DEBUG0), + h2fmi_rd(pFMI,FMI_DEBUG1), + h2fmi_rd(pFMI,FMI_DEBUG2) + ); +#else + printf("FMI[%u] - fmi{bus: %d, CFG: 0x%x, CTRL: 0x%x, STAT: 0x%x, INTPND: 0x%x, INT_EN: 0x%x, DBG0: 0x%x, DATSIZ: 0x%x}\n", + index, + pFMI->bus_id, + h2fmi_rd(pFMI,FMI_CONFIG), + h2fmi_rd(pFMI,FMI_CONTROL), + h2fmi_rd(pFMI,FMI_STATUS), + h2fmi_rd(pFMI,FMI_INT_PEND), + h2fmi_rd(pFMI,FMI_INT_EN), + h2fmi_rd(pFMI,FMI_DEBUG0), + h2fmi_rd(pFMI,FMI_DATA_SIZE) + ); +#endif + +#if ((FMI_VERSION > 0) && (FMI_VERSION <= 2)) + printf("FMI[%u] - fmi{DBG3: 0x%x, DATSIZ: 0x%x}\n",index,h2fmi_rd(pFMI,FMI_DEBUG3),h2fmi_rd(pFMI,FMI_DATA_SIZE)); +#endif + /** + * Dump important FMC registers ... + */ + printf("FMI[%u] - fmc{ON: 0x%x, IFCTRL: 0x%x, CECTRL: 0x%x, RWCTRL: 0x%x, CMD: 0x%x, ADDR0: 0x%x, ADDR1: 0x%x, ANUM: 0x%x, DNUM: 0x%x, FSTATUS: 0x%x, NSTATUS: 0x%x, RBB_CFG: 0x%x}\n", + index, + h2fmi_rd(pFMI,FMC_ON), + h2fmi_rd(pFMI,FMC_IF_CTRL), + h2fmi_rd(pFMI,FMC_CE_CTRL), + h2fmi_rd(pFMI,FMC_RW_CTRL), + h2fmi_rd(pFMI,FMC_CMD), + h2fmi_rd(pFMI,FMC_ADDR0), + h2fmi_rd(pFMI,FMC_ADDR1), + h2fmi_rd(pFMI,FMC_ADDRNUM), + h2fmi_rd(pFMI,FMC_DATANUM), + h2fmi_rd(pFMI,FMC_STATUS), + h2fmi_rd(pFMI,FMC_NAND_STATUS), + h2fmi_rd(pFMI,FMC_RBB_CONFIG) + ); + +#if FMI_VERSION > 2 + printf("FMI[%u] - fmc{DQST: 0x%x, NANDT1: 0x%x, NANDT2: 0x%x, NANDT3: 0x%x}\n", + index, + h2fmi_rd(pFMI,FMC_DQS_TIMING_CTRL), + h2fmi_rd(pFMI,FMC_TOGGLE_CTRL_1), + h2fmi_rd(pFMI,FMC_TOGGLE_CTRL_2), + h2fmi_rd(pFMI,FMC_TOGGLE_CTRL_3) + ); +#endif // FMI_VERSION > 2 + + // ECC might be clocked off for PPN + if (withECC) + { + /** + * Dump important ECC registers ... + */ + printf("FMI[%u] - ecc{PND: 0x%x, MASK: 0x%x}\n", + index, + h2fmi_rd(pFMI,ECC_PND), + h2fmi_rd(pFMI,ECC_MASK) + ); + } + else + { + printf("FMI[%u} - omitting ecc registers for ppn device\n", index); + } + +#if FMISS_DUMP_ENABLED + // FMISS + if (0 != (FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE & h2fmi_rd(pFMI, FMI_CONTROL))) + { + fmiss_dump(pFMI); + } +#endif // FMISS_DUMP_ENABLED + } +} diff --git a/drivers/apple/h2fmi/H2fmi_iop.h b/drivers/apple/h2fmi/H2fmi_iop.h new file mode 100644 index 0000000..ee0cee7 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_iop.h @@ -0,0 +1,70 @@ +// ***************************************************************************** +// +// File: H2fmi_iop.h +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#ifndef _H2FMI_IOP_H +#define _H2FMI_IOP_H + +// TODO: fix this by moving referenced header into common include directory +#include "../../../apps/EmbeddedIOP/function_fmi/iop_fmi_protocol.h" + +#include "H2fmi_private.h" +bool h2fmi_setup_aes(h2fmi_t* fmi, IOPFMI* cmd, hfmi_aes_iv* aes_iv_array, UInt32 aes_chain_size, UInt32 aes_key_type, UInt32* aes_key, UInt32* seeds); +void h2fmi_iop_set_config(h2fmi_t* fmi, IOPFMI_SetConfig* config); +void h2fmi_iop_reset_everything(h2fmi_t* fmi, IOPFMI_ResetEverything* cmd); +void h2fmi_iop_read_chip_ids(h2fmi_t* fmi, IOPFMI_ReadChipIDs* cmd); +void h2fmi_iop_erase_single(h2fmi_t* fmi, IOPFMI_EraseSingle* cmd); +void h2fmi_iop_erase_multiple(h2fmi_t* fmi, IOPFMI_EraseMultiple* cmd); +void h2fmi_iop_read_single(h2fmi_t* fmi, IOPFMI_IOSingle* cmd); +void h2fmi_iop_write_single(h2fmi_t* fmi, IOPFMI_IOSingle* cmd); +void h2fmi_iop_read_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd); +void h2fmi_iop_write_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd); +void h2fmi_iop_read_multiple(h2fmi_t* fmi, IOPFMI_IOMultiple* cmd); +void h2fmi_iop_write_multiple(h2fmi_t* fmi, IOPFMI_IOMultiple* cmd); +void h2fmi_iop_write_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd); +void h2fmi_iop_read_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd); +void h2fmi_iop_sleep(h2fmi_t* fmi); +void h2fmi_iop_wake(h2fmi_t* fmi); + +void h2fmi_ppn_iop_reset_everything(h2fmi_t *fmi, IOPFMI_ResetEverything* cmd); +void h2fmi_ppn_iop_erase_multiple(h2fmi_t *fmi, IOPFMI_IOPpn* cmd); +void h2fmi_ppn_iop_erase_single(h2fmi_t *fmi, IOPFMI_EraseSingle *cmd); +void h2fmi_ppn_iop_read_single(h2fmi_t *fmi, IOPFMI_IOSingle* cmd); +void h2fmi_ppn_iop_read_multiple(h2fmi_t *fmi, IOPFMI_IOPpn* cmd); +void h2fmi_ppn_iop_write_single(h2fmi_t *fmi, IOPFMI_IOSingle* cmd); +void h2fmi_ppn_iop_write_multiple(h2fmi_t *fmi, IOPFMI_IOPpn* cmd); +void h2fmi_ppn_iop_read_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd); +void h2fmi_ppn_iop_write_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd); +void h2fmi_ppn_iop_read_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd); +void h2fmi_ppn_iop_write_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd); +void h2fmi_ppn_iop_read_cau_bbt(h2fmi_t* fmi, IOPFMI_IOPpn* cmd); +void h2fmi_ppn_iop_update_firmware(h2fmi_t* fmi, IOPFMI_UpdateFirmware* cmd); +void h2fmi_ppn_iop_post_rst_pre_pwrstate_operations(h2fmi_t* fmi, IOPFMI_PostResetOperations *cmd); +void h2fmi_ppn_iop_set_power(h2fmi_t* fmi, IOPFMI_SetPower* cmd); +void h2fmi_ppn_iop_get_failure_info(h2fmi_t* fmi, IOPFMI_GetFailureInfo* cmd); +void h2fmi_ppn_iop_get_controller_info(h2fmi_t* fmi, IOPFMI_GetControllerInfo* cmd); +void h2fmi_ppn_iop_get_temperature(h2fmi_t *fmi, IOPFMI_GetTemperature* cmd); +void h2fmi_ppn_iop_get_die_info(h2fmi_t* fmi, IOPFMI_GetDieInfo* cmd); +void h2fmi_ppn_iop_set_feature_list(h2fmi_t *fmi, IOPFMI_SetFeatures* cmd); +void h2fmi_ppn_iop_power_state_changed(h2fmi_t* fmi); + +void dump_fmi_state(h2fmi_t *pFMI, uint32_t index, BOOL32 withHWRegs, BOOL32 withECC); + +#endif // _H2FMI_IOP_H diff --git a/drivers/apple/h2fmi/H2fmi_misc.c b/drivers/apple/h2fmi/H2fmi_misc.c new file mode 100644 index 0000000..9aee52a --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_misc.c @@ -0,0 +1,984 @@ +// ***************************************************************************** +// +// File: H2fmi_misc.c +// +// ***************************************************************************** +// +// Notes: +// +// - Add a global for FMC_IF_CTRL values and avoid reading it on the +// fly to get the values. +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" +#include "H2fmi_dma.h" +#if SUPPORT_PPN +#include "H2fmi_ppn.h" +#endif + +#if (H2FMI_WAIT_USING_ISR) +#include +#include +#endif + + +// ============================================================================= +// global variable declarations +// ============================================================================= + +//AES_KEY_SIZE_128 +UInt8 nand_whitening_key[16] = {0x92, 0xa7, 0x42, 0xab, 0x08, 0xc9, 0x69, 0xbf, 0x00, 0x6c, 0x94, 0x12, 0xd3, 0xcc, 0x79, 0xa5}; + +// ============================================================================= +// static implementation function declarations +// ============================================================================= + +#if (H2FMI_WAIT_USING_ISR) +static void h2fmi_init_isr(h2fmi_t* fmi); +static void h2fmi_isr_handler(void* arg); +#endif + +// ============================================================================= +// public implementation function definitions +// ============================================================================= + +void h2fmi_init_sys(h2fmi_t* fmi) +{ +#if (H2FMI_WAIT_USING_ISR) + h2fmi_init_isr(fmi); +#endif + +#if (H2FMI_WAIT_USING_ISR) + // init state machine event + event_init(&fmi->stateMachine.stateMachineDoneEvent, EVENT_FLAG_AUTO_UNSIGNAL, false); +#endif + + // FMI manages ECC interaction, so make certain we aren't + // unmasking any interrupt sources + h2fmi_wr(fmi, ECC_MASK, 0x0); + + fmi->h2fmi_ppn_panic_on_status_timeout = TRUE32; +} + +void h2fmi_prepare_wait_status(h2fmi_t* fmi, UInt8 io_mask, UInt8 io_cond) +{ + UInt32 wReadStatusCmd; + + // turn off RBBEN and configure it to use look for mask value on I/O lines + h2fmi_set_if_ctrl(fmi, (~FMC_IF_CTRL__RBBEN & h2fmi_rd(fmi, FMC_IF_CTRL))); + h2fmi_wr(fmi, FMC_RBB_CONFIG, (FMC_RBB_CONFIG__POL(io_cond) | + FMC_RBB_CONFIG__POS(io_mask))); + + if ( fmiWrite==fmi->stateMachine.currentMode ) + { + switch ( fmi->stateMachine.wVendorType ) + { + case _kVS_TOSHIBA_2P: + wReadStatusCmd = NAND_CMD__TOS_STATUS_71h; + break; + case _kVS_SAMSUNG_2P_2D: + wReadStatusCmd = ( 0==(fmi->stateMachine.page_idx&2) ? NAND_CMD__READ_SS_DIE1 : NAND_CMD__READ_SS_DIE2 ); + break; + case _kVS_SAMSUNG_2D: + wReadStatusCmd = ( 0==(fmi->stateMachine.page_idx&1) ? NAND_CMD__READ_SS_DIE1 : NAND_CMD__READ_SS_DIE2 ); + break; + case _kVS_NONE: + default: + wReadStatusCmd = NAND_CMD__READ_STATUS; + break; + } + + } + else + { + wReadStatusCmd = NAND_CMD__READ_STATUS; + } + + // exec Read Status command cycle + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(wReadStatusCmd)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + // busy wait until command cycle completed + h2fmi_busy_wait(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE, FMC_STATUS__CMD1DONE); + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE); + + // clear the FMC_STATUS__NSRBBDONE bit in FMC_STATUS + h2fmi_clear_interrupts_and_reset_masks(fmi); + + // set up read cycle with REBHOLD to wait for ready bit to be + // set on I/O lines + h2fmi_wr(fmi, FMC_DATANUM, FMC_DATANUM__NUM(0)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__REBHOLD | FMC_RW_CTRL__RD_MODE)); + +} + +BOOL32 h2fmi_wait_status(h2fmi_t* fmi, + UInt8 io_mask, + UInt8 io_cond, + UInt8* status) +{ + BOOL32 result = TRUE32; + + h2fmi_prepare_wait_status(fmi, io_mask, io_cond); + +#if (H2FMI_WAIT_USING_ISR) + { + // use NSRBBDone interrupt source to wait for I/O ready state + h2fmi_wr(fmi, FMC_INTMASK, FMC_INTMASK__NSRBBDONE); + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__FMC_NSRBBDONE); + if (!event_wait_timeout(&fmi->isr_event, H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_fail(result); + } + else if (!(fmi->isr_condition & FMI_INT_PEND__FMC_NSRBBDONE)) + { + h2fmi_fail(result); + } + } +#else + { + // wait until NSRBB done signaled + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__NSRBBDONE, + FMC_STATUS__NSRBBDONE)) + { + h2fmi_fail(result); + } + } +#endif + + // if status collection desired, grab it while REBHOLD still active + if (NULL != status) + { + *status = (UInt8)h2fmi_rd(fmi, FMC_NAND_STATUS); + } + + // clear FMC_RW_CTRL, thereby releasing REBHOLD and completing + // current read cycle + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + + return result; +} +void h2fmi_nand_read_chipid(h2fmi_t* fmi, + h2fmi_ce_t ce, + h2fmi_chipid_t* id) +{ + UInt32 if_ctrl; + const UInt32 cmd1_addr_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD1DONE); + + if_ctrl = h2fmi_rd(fmi, FMC_IF_CTRL); + + h2fmi_set_if_ctrl(fmi, (FMC_IF_CTRL__DCCYCLE(0) | + FMC_IF_CTRL__REB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__REB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS))); + + // enable specified nand device + h2fmi_fmc_enable_ce(fmi, ce); + + // set up Read Id command and address cycles + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ_ID)); + h2fmi_wr(fmi, FMC_ADDR0, FMC_ADDR0__SEQ0(0x00)); + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(0)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD1_MODE)); + + // wait until cmd & addr completion + h2fmi_busy_wait(fmi, FMC_STATUS, cmd1_addr_done, cmd1_addr_done); + h2fmi_wr(fmi, FMC_STATUS, cmd1_addr_done); + + // read correct number of id bytes + h2fmi_fmc_read_data(fmi, H2FMI_NAND_ID_SIZE, (UInt8*)id); + + // disable all nand devices + h2fmi_fmc_disable_all_ces(fmi); + + h2fmi_set_if_ctrl(fmi, if_ctrl); +} + +// Builds the valid_ces bitmask for all chip IDs that match id_filter +void h2fmi_build_ce_bitmask(h2fmi_t* fmi, + h2fmi_chipid_t* ids, + h2fmi_chipid_t* id_filter, + UInt8 addr) +{ + UInt32 wIdx; + h2fmi_chipid_t all_zeros = {0}; + + // skip it if the filter is zeroes + if (!WMR_MEMCMP(all_zeros, id_filter, sizeof(h2fmi_chipid_t))) + { + return; + } + + + for (wIdx = 0; wIdx < H2FMI_MAX_CE_TOTAL; ++wIdx) + { + if (WMR_MEMCMP(ids[wIdx], *id_filter, H2FMI_NAND_ID_COMPARISON_SIZE) == 0) + { + // Chip ID matches + if(CHIPID_ADDR == addr) + { + _WMR_PRINT("[NAND] Found Chip ID %02X %02X %02X %02X %02X %02X on FMI%d:CE%d\n", + (UInt32)ids[wIdx][0], + (UInt32)ids[wIdx][1], + (UInt32)ids[wIdx][2], + (UInt32)ids[wIdx][3], + (UInt32)ids[wIdx][4], + (UInt32)ids[wIdx][5], + fmi->bus_id, + wIdx); + } + fmi->valid_ces |= (1UL << wIdx); + fmi->num_of_ce += 1; + } + else if(!h2fmi_is_chipid_invalid(&ids[wIdx])) + { + _WMR_PRINT("[NAND] Ignoring mismatched Chip ID %02X %02X %02X %02X %02X %02X on FMI%d:CE%d\n", + (UInt32)ids[wIdx][0], + (UInt32)ids[wIdx][1], + (UInt32)ids[wIdx][2], + (UInt32)ids[wIdx][3], + (UInt32)ids[wIdx][4], + (UInt32)ids[wIdx][5], + fmi->bus_id, + wIdx); + } + } +} + +BOOL32 h2fmi_nand_read_id_all(h2fmi_t* fmi, + h2fmi_chipid_t* ids, + UInt8 addr) +{ + UInt32 wIdx; + BOOL32 result = TRUE32; + + WMR_MEMSET(ids, 0, (sizeof(h2fmi_chipid_t) * H2FMI_MAX_CE_TOTAL)); + fmi->valid_ces = 0; + fmi->num_of_ce = 0; + + for (wIdx = 0; wIdx < H2FMI_MAX_CE_TOTAL; wIdx++) + { + if (!h2fmi_nand_read_id(fmi, wIdx, &ids[wIdx], addr)) + { + h2fmi_fail(result); + break; + } + } + + return result; +} + +BOOL32 h2fmi_reset_and_read_chipids(h2fmi_t* fmi, + h2fmi_chipid_t* ids, + UInt8 addr) +{ + BOOL32 result = TRUE32; + + if (!h2fmi_nand_reset_all(fmi)) + { + h2fmi_fail(result); + } + else + { + result = h2fmi_nand_read_id_all(fmi, ids, addr); + } + + return result; +} + +BOOL32 h2fmi_nand_reset_all(h2fmi_t* fmi) +{ + BOOL32 result = TRUE32; + + UInt32 ce_idx; + + for (ce_idx = 0; ce_idx < H2FMI_MAX_CE_TOTAL; ce_idx++) + { + // reset next device + if (!h2fmi_nand_reset(fmi, ce_idx)) + { + // fail, but continue on to next device regardless + h2fmi_fail(result); + } + } + + // Fix wait periods for initial reset + // wait 50 ms to allow nand to reset + WMR_SLEEP_US(H2FMI_MAX_RESET_DELAY); + +#if SUPPORT_PPN +#if !H2FMI_IOP + if (fmi->is_ppn) + { + fmi->if_ctrl = H2FMI_IF_CTRL_LOW_POWER; + restoreTimingRegs(fmi); + } +#endif // !H2FMI_IOP +#endif // SUPPORT_PPN + + return result; +} + +#if FMI_VERSION == 0 +UInt32 h2fmi_config_sectors_to_page_size(h2fmi_t* fmi) +{ + UInt32 fmi_config = 0xFFFFFFFF; + + // configure page size based device id table + switch (fmi->sectors_per_page) + { + case (4): + fmi_config = FMI_CONFIG__PAGE_SIZE__2K; + break; + + case (8): + fmi_config = FMI_CONFIG__PAGE_SIZE__4K; + break; + + case (16): + fmi_config = FMI_CONFIG__PAGE_SIZE__8K; + break; + + case (1): + fmi_config = FMI_CONFIG__PAGE_SIZE__512; + break; + + default: + WMR_PRINT(ERROR, + "[FIL:ERR] (512 x %d)-byte page size unsupported\n", + fmi->sectors_per_page); + } + + return fmi_config; +} +#endif // S5L8920X + +void h2fmi_set_raw_write_data_format(h2fmi_t* fmi, UInt32 spare_per_sector) +{ +#if FMI_VERSION == 0 + // Use 512 bytes per page when writing. The H2P FMI_CONFIG register doesn't give us enough + // bits in the META_PER_PAGE field to do an entire 4KB page's worth of spare so we'll + // do four 512 byte reads in a row instead. + // + // If we have no spare, use LBA_AB rather than BYPASS_ECC. Otherwise FMI will hang waiting + // for a DMA operation on the meta channel that'll never come. + h2fmi_wr(fmi, FMI_CONFIG, ((spare_per_sector ? FMI_CONFIG__LBA_MODE__BYPASS_ECC : FMI_CONFIG__LBA_MODE__LBA_TYPE_AB) | + FMI_CONFIG__META_PER_ENVELOPE(spare_per_sector) | + FMI_CONFIG__META_PER_PAGE(spare_per_sector) | + FMI_CONFIG__PAGE_SIZE__512)); +#else + // With H2A and later we have arbitrary control over page and sector size. We can make our life easier + // by just setting the sector size to be sector_data_size + sector_spare_size and pusing + // everything through the data FIFO. + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_CORRECTABLE_BITS( 0 ) | FMI_CONFIG__DMA_BURST__32_CYCLES); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR( spare_per_sector ) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE( spare_per_sector ) | + FMI_DATA_SIZE__BYTES_PER_SECTOR( 1024 ) | + FMI_DATA_SIZE__SECTORS_PER_PAGE( 1 ))); +#endif +} + +void h2fmi_set_bootpage_data_format(h2fmi_t* fmi) +{ +#if FMI_VERSION == 0 + h2fmi_wr(fmi, FMI_CONFIG, (FMI_CONFIG__LBA_MODE__NORMAL | + FMI_CONFIG__META_PER_ENVELOPE(0) | + FMI_CONFIG__META_PER_PAGE(0) | + FMI_CONFIG__PAGE_SIZE__512 | + FMI_CONFIG__ECC_MODE__16BIT | + FMI_CONFIG__DMA_BURST__32_CYCLES)); +#elif FMI_VERSION <= 2 + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_CORRECTABLE_BITS( MAX_ECC_CORRECTION )); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(512) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1))); +#elif FMI_VERSION <= 3 + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_CORRECTABLE_BITS( MAX_ECC_CORRECTION )); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(512) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1))); + // Do not use written-mark + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(0) | + ECC_CON1__INT_ENABLE(0) | + ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(MAX_ECC_CORRECTION))); +#else + // Use randomizer + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_CORRECTABLE_BITS( MAX_ECC_CORRECTION ) | + FMI_CONFIG__SCRAMBLE_SEED | + FMI_CONFIG__ENABLE_WHITENING); + + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(512) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1))); + // Fewer stuck bits are allowed + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(0) | + ECC_CON1__INT_ENABLE(0) | + ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(2))); +#endif +} + + +void h2fmi_set_page_format(h2fmi_t* fmi) +{ + h2fmi_wr(fmi, FMI_CONFIG, fmi->fmi_config_reg); +# if FMI_VERSION > 0 + h2fmi_wr(fmi, FMI_DATA_SIZE, fmi->fmi_data_size_reg); +#endif +} + + +typedef struct +{ + UInt32 eccBytesPerSector; + UInt32 eccCorrectableBits; +} h2fmi_spare_layout; + +#if FMI_VERSION > 0 +// H2A, H3P +static const h2fmi_spare_layout _h2fmi_spare_layout [] = +{ + { 53, 30 }, + { 51, 29 }, + { 44, 25 }, + { 28, 16 }, + { 27, 15 }, + { 0, 0 } +}; +#else +// H2P +static const h2fmi_spare_layout _h2fmi_spare_layout [] = +{ + { 26, 16 }, + { 13, 8 }, + { 0, 0 } +}; +#endif + +UInt32 h2fmi_calculate_ecc_bits(h2fmi_t* fmi) +{ + UInt32 eccMode = 0; + const h2fmi_spare_layout* layout = _h2fmi_spare_layout; + const UInt32 bytesForEccPerSector = ((fmi->bytes_per_spare - fmi->valid_bytes_per_meta) / + (fmi->bytes_per_page / H2FMI_BYTES_PER_SECTOR)); + for( ; layout->eccBytesPerSector != 0; layout++ ) + { + if( layout->eccBytesPerSector <= bytesForEccPerSector ) + { + eccMode = layout->eccCorrectableBits; + break; + } + } + + WMR_ASSERT(eccMode != 0); + + return eccMode; + +} + +UInt32 h2fmi_calculate_ecc_output_bytes(h2fmi_t* fmi) +{ + const h2fmi_spare_layout* layout = _h2fmi_spare_layout; + const UInt32 bytesForEccPerSector = ((fmi->bytes_per_spare - fmi->valid_bytes_per_meta) / + (fmi->bytes_per_page / H2FMI_BYTES_PER_SECTOR)); + for( ; layout->eccBytesPerSector != 0; layout++ ) + { + if( layout->eccBytesPerSector <= bytesForEccPerSector ) + { + return layout->eccBytesPerSector; + } + } + + return 0; +} + +UInt32 h2fmi_calculate_fmi_config(h2fmi_t* fmi) +{ + UInt32 ret; + +#if FMI_VERSION == 0 + UInt32 eccMode; + eccMode = (fmi->correctable_bits == 16) ? FMI_CONFIG__ECC_MODE__16BIT : + FMI_CONFIG__ECC_MODE__8BIT; + + ret = (FMI_CONFIG__LBA_MODE__NORMAL | + FMI_CONFIG__META_PER_ENVELOPE(fmi->valid_bytes_per_meta) | + FMI_CONFIG__META_PER_PAGE(fmi->valid_bytes_per_meta) | + h2fmi_config_sectors_to_page_size(fmi) | + FMI_CONFIG__DMA_BURST__8_CYCLES | + eccMode); +#else + ret = (FMI_CONFIG__ECC_CORRECTABLE_BITS( fmi->correctable_bits ) | + FMI_CONFIG__DMA_BURST__32_CYCLES); +#endif + return ret; +} + +#if FMI_VERSION > 0 +UInt32 h2fmi_calculate_fmi_data_size(h2fmi_t* fmi) +{ + UInt32 ret; + + ret = (FMI_DATA_SIZE__META_BYTES_PER_SECTOR( fmi->valid_bytes_per_meta ) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE( fmi->valid_bytes_per_meta ) | + FMI_DATA_SIZE__BYTES_PER_SECTOR( H2FMI_BYTES_PER_SECTOR ) | + FMI_DATA_SIZE__SECTORS_PER_PAGE( fmi->sectors_per_page )); + return ret; +} +#endif + + +// ============================================================================= +// isr-only static implementation function definitions +// ============================================================================= + +#if (H2FMI_WAIT_USING_ISR) + +static void h2fmi_init_isr(h2fmi_t* fmi) +{ + WMR_PRINT(IRQ, "initializing interrupts for FMI%d\n", + h2fmi_bus_index(fmi)); + + // lookup fmi interrupt vector to use based upon fmi block + UInt32 vector = h2fmi_select_by_bus(fmi, INT_FMI0, INT_FMI1); + + // init isr event and condition + event_init(&fmi->isr_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + fmi->isr_condition = 0; +#if FMISS_ENABLED + fmi->isr_handler = NULL; +#endif // FMISS_ENABLED + + // clear out any preexisting interrupts and mask sources + h2fmi_clear_interrupts_and_reset_masks(fmi); + + // install interrupt handler + set_int_type(vector, INT_TYPE_IRQ | INT_TYPE_LEVEL); + install_int_handler(vector, h2fmi_isr_handler, (void*)fmi); + unmask_int(vector); +} + + +static void h2fmi_default_isr_handler(h2fmi_t* fmi) +{ + // capture condition triggering isr + fmi->isr_condition = h2fmi_rd(fmi, FMI_INT_PEND); + + // clear all interrupts and mask sources + h2fmi_clear_interrupts_and_reset_masks(fmi); + + // signal isr event + event_signal(&fmi->isr_event); +} + +typedef void (*h2fmi_dispatch_handler)(h2fmi_t* fmi); + +static const h2fmi_dispatch_handler h2fmi_isr_dispatchTable[] = { + h2fmi_default_isr_handler, // fmiNone + h2fmi_handle_read_ISR_state_machine, // fmiRead + h2fmi_handle_write_ISR_state_machine // fmiWrite +}; + +static void h2fmi_isr_handler(void* arg) +{ + h2fmi_t* fmi = (h2fmi_t*)arg; + +#if FMISS_ENABLED + if (NULL != fmi->isr_handler) + { + fmi->isr_handler(fmi); + } + else +#endif // FMISS_ENABLED + { + WMR_ASSERT( fmi->stateMachine.currentMode <= fmiWrite ); + h2fmi_isr_dispatchTable[ fmi->stateMachine.currentMode ]( fmi ); + } +} + +#endif + +void h2fmi_clear_interrupts_and_reset_masks(h2fmi_t* fmi) +{ + // mask further interrupts + h2fmi_wr(fmi, FMC_INTMASK, 0x0); + h2fmi_wr(fmi, FMI_INT_EN, 0x0); + + // clear interrupt source flags + h2fmi_wr(fmi, FMC_STATUS, (FMC_STATUS__EMERGENCY2 | + FMC_STATUS__EMERGENCY01 | + FMC_STATUS__RDATADIRTY | + FMC_STATUS__RBBDONE7 | + FMC_STATUS__RBBDONE6 | + FMC_STATUS__RBBDONE5 | + FMC_STATUS__RBBDONE4 | + FMC_STATUS__RBBDONE3 | + FMC_STATUS__RBBDONE2 | + FMC_STATUS__RBBDONE1 | + FMC_STATUS__RBBDONE0 | + FMC_STATUS__TIMEOUT | + FMC_STATUS__NSERR | + FMC_STATUS__NSRBBDONE | + FMC_STATUS__TRANSDONE | + FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD3DONE | + FMC_STATUS__CMD2DONE | + FMC_STATUS__CMD1DONE)); + h2fmi_wr(fmi, FMI_INT_PEND, (FMI_INT_PEND__META_FIFO_OVERFLOW | + FMI_INT_PEND__META_FIFO_UNDERFLOW | + FMI_INT_PEND__LAST_FMC_DONE | + FMI_INT_PEND__TRANSACTION_COMPLETE)); +} + + +/** + * Maps the absolute CE to the required register bit # and + * provides which bus number that CE is on. + * + * Note that CE's are absolute on our system -- CE0 is ALWAYS + * from FMC0, regardless of which bus we are dealing with. CE8 + * is ALWAYS bit zero of FMC1 as well. + * + * @param ce - desired absolute CE # + * @param p_wTargetBus pointer to store translated bus number. + * @param p_targetCE - pointer to store translated CE bit. + */ +static inline void h2fmi_calc_bus_ce(h2fmi_ce_t ce, + UInt32* p_wTargetBus, + h2fmi_ce_t* p_targetCE) +{ + *p_wTargetBus = ( ce >> H2FMI_MAX_CE_PER_BUS_POW2 ); + *p_targetCE = ( ce & (H2FMI_MAX_CE_PER_BUS - 1) ); +} + + +/** + * Enable the specified CE while ensuring that only one CE is + * enabled at a time on the given bus. + * + * @param fmi - context + * @param ce - Absolute CE # + */ +void h2fmi_fmc_enable_ce(h2fmi_t* fmi, h2fmi_ce_t ce) +{ + h2fmi_ce_t targetCE; + UInt32 wTargetBus; + + h2fmi_calc_bus_ce(ce, &wTargetBus, &targetCE); + + if(wTargetBus == fmi->bus_id) + { + h2fmi_wr(fmi, FMC_CE_CTRL, FMC_CE_CTRL__CEB(targetCE)); + } + else + { + h2fmi_fmc_disable_all_ces(fmi); + } +} + +/** + * Disable ONLY the specified CE (using read/modify/write). + * + * @param ce - Absolute CE # + */ +void h2fmi_fmc_disable_ce(h2fmi_t* fmi, h2fmi_ce_t ce) +{ + h2fmi_ce_t targetCE; + UInt32 wTargetBus; + + h2fmi_calc_bus_ce(ce, &wTargetBus, &targetCE); + + if(wTargetBus == fmi->bus_id) + { + UInt32 val = h2fmi_rd(fmi, FMC_CE_CTRL); + h2fmi_wr(fmi, FMC_CE_CTRL, val & ~FMC_CE_CTRL__CEB(targetCE)); + } +} + +void h2fmi_fmc_disable_all_ces(h2fmi_t* fmi) +{ + h2fmi_wr(fmi, FMC_CE_CTRL, 0); +} + +void h2fmi_prepare_for_ready_busy_interrupt(h2fmi_t* fmi) +{ + h2fmi_prepare_wait_status(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY); + + // use NSRBBDone interrupt source to wait for I/O ready state + h2fmi_wr(fmi, FMC_INTMASK, FMC_INTMASK__NSRBBDONE); + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__FMC_NSRBBDONE); + +} + +void h2fmi_set_page_format_and_ECC_level(h2fmi_t* fmi, UInt32 wErrorAlertLevel) +{ + // configure FMI with page format + h2fmi_set_page_format(fmi); + +#if FMI_VERSION == 0 + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(wErrorAlertLevel) | + ECC_CON1__INT_ENABLE(0))); +#elif FMI_VERSION <= 2 + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(wErrorAlertLevel) | + ECC_CON1__INT_ENABLE(0) | + ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(fmi->correctable_bits))); +#else + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(wErrorAlertLevel) | + ECC_CON1__INT_ENABLE(0) | + ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(fmi->correctable_bits) | + ECC_CON1__IMPLICIT_WRITE_MARK)); +#endif +} + + +/** + * Checks the current state of the (previously selected) CE, + * looking to see if it is ready or busy. Uses the + * stateMachine's "waitStartTick" and "wPageTimeoutTicks" to + * determine if the wait has timed out. Note that both of these + * fields must be initialized before calling this function. + * + * @param fmi + * + * @return CE_STATE + */ +CE_STATE h2fmi_get_current_CE_state( h2fmi_t* fmi ) +{ + CE_STATE ceState = CE_BUSY; + + if (!(h2fmi_rd(fmi, FMI_INT_PEND) & FMI_INT_PEND__FMC_NSRBBDONE)) + { + BOOL32 fTimeout = WMR_HAS_TIME_ELAPSED_TICKS( fmi->stateMachine.waitStartTicks, fmi->stateMachine.wPageTimeoutTicks ); + + if ( fTimeout ) + { + ceState = CE_TIMEOUT; + } + } + else + { + ceState = CE_IDLE; + } + + return ceState ; +} + +#if ( H2FMI_INSTRUMENT_BUS_1 ) +/** + * Sets the specified CE on FMI1. + * + * @param iBit - CE, zero is the first. + */ +void h2fmi_instrument_bit_set(int iBit) +{ + iBit &= 0x03; + volatile UInt32* wFMCValue = ( 0 == (iBit & 0x02) ? FMI0 : FMI1 ); + iBit = ( 0 == (iBit & 0x01) ? 2 : 3 ); + UInt32 wCurrentValue = h2fmc_rd(wFMCValue, FMC_CE_CTRL); + wCurrentValue &= ~( 1 << iBit ); + h2fmc_wr(wFMCValue, FMC_CE_CTRL, wCurrentValue ); +} + +/** + * Clears the specified CE on FMI1. + * + * @param iBit - CE, zero is the first. + */ +void h2fmi_instrument_bit_clear(int iBit) +{ + iBit &= 0x03; + volatile UInt32* wFMCValue = ( 0 == (iBit & 0x02) ? FMI0 : FMI1 ); + iBit = ( 0 == (iBit & 0x01) ? 2 : 3 ); + UInt32 wCurrentValue = h2fmc_rd(wFMCValue, FMC_CE_CTRL); + wCurrentValue |= ( 1 << iBit ); + h2fmc_wr(wFMCValue, FMC_CE_CTRL, wCurrentValue ); +} +#endif + +static void h2fmi_rx_prep(h2fmi_t* fmi) +{ + h2fmi_set_page_format_and_ECC_level(fmi, 15); +} + +static void h2fmi_tx_prep(h2fmi_t* fmi) +{ + // undocumented silicon "feature": on write, program error alert + // level greater than bit correction capability to avoid spurious + // ECC error + // regardless, I was advised to disable interrupt to FMI from ECC + h2fmi_set_page_format_and_ECC_level(fmi, fmi->correctable_bits + 1); + // clean up any ECC block state before starting transfer + h2fmi_clean_ecc(fmi); + +#if (H2FMI_WAIT_USING_ISR) + // enable appropriate interrupt source + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__LAST_FMC_DONE); +#endif +} + + +BOOL32 h2fmi_common_idle_handler( h2fmi_t* fmi ) +{ + /** + * Called initially from client in non-interrupt context to let + * us set everything up and start the process. + */ + BOOL32 bSuccessful = TRUE32; + + fmi->failureDetails.wNumCE_Executed = 0; + fmi->failureDetails.wOverallOperationFailure = 0; + + fmi->failureDetails.wFirstFailingCE = ~0; + + fmi->stateMachine.wPageTimeoutTicks = H2FMI_PAGE_TIMEOUT_MICROS * WMR_GET_TICKS_PER_US(); + fmi->stateMachine.wQuarterPageTimeoutTicks = fmi->stateMachine.wPageTimeoutTicks / 4; + + if ( fmiRead == fmi->stateMachine.currentMode) + { + h2fmi_rx_prep(fmi); + } + else + { + h2fmi_tx_prep(fmi); + } + + return bSuccessful; +} + +BOOL32 h2fmi_start_dma( h2fmi_t* fmi ) +{ + BOOL32 bSuccessful = TRUE32; + + bSuccessful = h2fmi_dma_execute_async( + ( fmiRead == fmi->stateMachine.currentMode ? DMA_CMD_DIR_RX : DMA_CMD_DIR_TX ), + h2fmi_dma_data_chan(fmi), + fmi->stateMachine.data_segment_array, + h2fmi_dma_data_fifo(fmi), + fmi->bytes_per_page * fmi->stateMachine.page_count, + sizeof(UInt32), + 8, + fmi->current_aes_cxt); + + if (bSuccessful) + { + // use CDMA to feed meta buffer to FMI + bSuccessful = h2fmi_dma_execute_async( + ( fmiRead == fmi->stateMachine.currentMode ? DMA_CMD_DIR_RX : DMA_CMD_DIR_TX ), + h2fmi_dma_meta_chan(fmi), + fmi->stateMachine.meta_segment_array, + h2fmi_dma_meta_fifo(fmi), + fmi->valid_bytes_per_meta * fmi->stateMachine.page_count, + sizeof(UInt8), + 1, + NULL); + } + + return bSuccessful; +} + +#define LFSR32(seed) ((seed) & 1) ? ((seed) >> 1) ^ 0x80000061 : ((seed) >> 1) +void h2fmi_aes_iv(void* arg, UInt32 chunk_index, void* iv_buffer) +{ + const h2fmi_t* fmi = (h2fmi_t*)arg; + if (fmi->current_aes_iv_array) + { + const UInt8* chunk_iv = fmi->current_aes_iv_array[chunk_index].aes_iv_bytes; + + WMR_MEMCPY(iv_buffer, chunk_iv, 16); + WMR_PRINT(CRYPTO, "IV: 0x%08x 0x%08x 0x%08x 0x%08x\n", + ((UInt32*)chunk_iv)[0], + ((UInt32*)chunk_iv)[1], + ((UInt32*)chunk_iv)[2], + ((UInt32*)chunk_iv)[3]); + } + else + { + const UInt32 pPage = fmi->iv_seed_array[chunk_index]; + UInt32* iv = (UInt32*)iv_buffer; + WMR_PRINT(CRYPTO, "Whitening chunk %d\n", chunk_index); + + iv[0] = LFSR32(pPage); + iv[1] = LFSR32(iv[0]); + iv[2] = LFSR32(iv[1]); + iv[3] = LFSR32(iv[2]); + } +} + +void h2fmi_set_if_ctrl(h2fmi_t* fmi, UInt32 if_ctrl) +{ +#if FMI_VERSION == 4 + // there are currently limitations on timings that can be used in H4G, + // some of which can be over come by disabling streaming () +#if SUPPORT_TOGGLE_NAND + if (fmi->is_toggle) + { + const UInt32 reb_setup = FMC_IF_CTRL__GET_REB_SETUP(if_ctrl); + + fmi->read_stream_disable = (3 < reb_setup) ? TRUE32 : FALSE32; + } + else +#endif // SUPPORT_TOGGLE_NAND + { + fmi->read_stream_disable = TRUE32; + } +#endif // FMI_VERSION == 4 + +#if FMI_VERSION >= 5 +#if SUPPORT_TOGGLE_NAND + if (fmi->is_toggle) + { + fmi->read_tx_page_delay = 0; + } + else +#endif // SUPPORT_TOGGLE_NAND + { + const UInt32 dccycle = FMC_IF_CTRL__GET_DCCYCLE(if_ctrl); + const UInt32 reb_hold = FMC_IF_CTRL__GET_REB_HOLD(if_ctrl); + + // Timeout during flash data transfer in SDR mode with slow timings + fmi->read_tx_page_delay = (reb_hold > (dccycle + 4) ? reb_hold - (dccycle + 4) : 0); + } +#endif // FMI_VERSION >= 5 + + h2fmi_wr(fmi, FMC_IF_CTRL, if_ctrl); +} + +void restoreTimingRegs(h2fmi_t* fmi) +{ +#if SUPPORT_TOGGLE_NAND + if (fmi->is_toggle) + { + h2fmi_wr(fmi, FMC_DQS_TIMING_CTRL, fmi->dqs_ctrl); + h2fmi_wr(fmi, FMC_TOGGLE_CTRL_1, fmi->timing_ctrl_1); + h2fmi_wr(fmi, FMC_TOGGLE_CTRL_2, fmi->timing_ctrl_2); + h2fmi_set_if_ctrl(fmi, fmi->toggle_if_ctrl); + } + else + { +#endif + h2fmi_set_if_ctrl(fmi, fmi->if_ctrl); +#if SUPPORT_TOGGLE_NAND + } +#endif +} +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_ppn.c b/drivers/apple/h2fmi/H2fmi_ppn.c new file mode 100644 index 0000000..36372b4 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_ppn.c @@ -0,0 +1,2725 @@ +// ***************************************************************************** +// +// File: H2fmi_ppn.c +// +// Copyright (C) 2009 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" +#include "H2fmi_dma.h" +#include "H2fmi_ppn.h" +#include +#include +#include "WMRFeatures.h" + +#if WMR_BUILDING_IBOOT +#include +#if !APPLICATION_EMBEDDEDIOP +#include "nandid.h" +#endif /* !APPLICATION_EMBEDDEDIOP */ +#else +#include "NandSpecTables.h" +#endif /* WMR_BUILDING_IBOOT */ + +#if FMI_VERSION > 0 + +#if H2FMI_PPN_VERIFY_SET_FEATURES + +typedef struct +{ + UInt16 feature; + UInt32 states; +} h2fmi_ppn_feature_states_t; + +typedef struct +{ + UInt32 count; + UInt32 state; + struct + { + UInt16 feature; + UInt32 length;; + UInt32 value; + } list[PPN_MAX_FEATURE_COUNT]; +} h2fmi_ppn_feature_shadow_t; + +static h2fmi_ppn_feature_states_t _ppn_feature_states[] = +{ + { PPN_FEATURE__VREF_ENABLE , (1UL << PPN_FEATURE__POWER_STATE__LOW_POWER) } , +}; + +static h2fmi_ppn_feature_shadow_t _ppn_feature_shadow[PPN_MAX_CES_PER_BUS]; + +#endif // H2FMI_PPN_VERIFY_SET_FEATURES + +static void h2fmi_send_cmd(h2fmi_t *fmi, UInt8 cmd); +static void h2fmi_send_cmd_addr(h2fmi_t *fmi, UInt8 cmd, UInt8 *address, UInt32 address_bytes); +static void h2fmi_ppn_set_format(h2fmi_t *fmi, UInt32 sector_len, UInt32 sector_count, BOOL32 bootpage); +static void h2fmi_ppn_get_page_data(h2fmi_t *fmi, UInt32 length); +static void h2fmi_send_cmd_addr_cmd(h2fmi_t *fmi, UInt8 cmd1, UInt8 cmd2, const UInt8 *address, UInt32 address_bytes); +static BOOL32 h2fmi_ppn_prep_read(h2fmi_t *fmi, const RowColLenAddressType *page, BOOL32 last); +static void h2fmi_ppn_prep_write_multi(h2fmi_t *fmi, const PPNCommandStruct *ppnCommand); +static void h2fmi_ppn_program_page(h2fmi_t *fmi, UInt32 page, BOOL32 lastPage, UInt32 lbas); +static BOOL32 h2fmi_get_nand_status(h2fmi_t *fmi, UInt8 *status); +static void h2fmi_ppn_read_serial_output(h2fmi_t *fmi, UInt8 *buf, UInt32 len); +static BOOL32 h2fmi_ppn_switch_ce(h2fmi_t *fmi, h2fmi_ce_t ce); +static void h2fmi_ppn_disable_all_ces(h2fmi_t *fmi); +static void h2fmi_ppn_start_fmi_write_and_wait(h2fmi_t *fmi); +static void h2fmi_ppn_start_fmi_read_and_wait(h2fmi_t *fmi); +static BOOL32 h2fmi_ppn_get_next_operation_status_with_addr(h2fmi_t *fmi, UInt8 *addr, UInt8 *operation_status); +static void h2fmi_prepare_for_fmi_interrupt(h2fmi_t *fmi, UInt32 condition); +static BOOL32 h2fmi_wait_for_fmi_interrupt(h2fmi_t *fmi, UInt32 condition); +static BOOL32 h2fmi_ppn_set_generic_debug_data(h2fmi_t *fmi, h2fmi_ce_t ce, UInt32 flags); +static BOOL32 _validate_device_parameters(h2fmi_ppn_t *ppn); +#if H2FMI_PPN_VERIFY_SET_FEATURES +static void _update_feature_shadow(h2fmi_t *fmi, UInt16 feature, UInt8 *value, UInt32 len); +#endif // H2FMI_PPN_VERIFY_SET_FEATURES + +static h2fmi_ce_t h2fmi_ppn_ce_index_to_physical(const PPNCommandStruct *command, UInt32 index) +{ + return command->ceInfo[index].ce; +} + +BOOL32 h2fmi_ppn_get_uid(h2fmi_t *fmi, UInt8 ce, UInt8 die, UInt8 *buf) +{ + UInt8 status; + + h2fmi_reset(fmi); + + return h2fmi_ppn_get_feature(fmi, + ce, + (PPN_FEATURE__NAND_DIE_UNIQUE_ID | (die << 8)), + buf, + NAND_UID_PPN_BYTES_TO_READ, + &status); +} + +Int32 h2fmi_ppn_read_multi(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + struct dma_segment *data_segment_array, + struct dma_segment *meta_segment_array) +{ + const UInt32 page_count = ppnCommand->num_pages; + UInt32 prepPage; + UInt32 readPage; + BOOL32 ret; + UInt32 queueDepth; + const UInt32 readQueueSize = fmi->ppn->device_params.read_queue_size; + UInt32 overallStatus; + UInt32 i; + UInt32 cePageCount[PPN_MAX_CES_PER_BUS] = {0}; + UInt8 setFeaturesBuffer[PPN_FEATURE_LENGTH_ENABLE_BITFLIPS_DATA_COLLECTION]; + UInt32 iopfmiStatus; + BOOL32 timeout; + UInt8 opStatus; + + timeout = FALSE32; + prepPage = 0; + readPage = 0; + queueDepth = 0; + overallStatus = 0; + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + WMR_ASSERT(page_count > 0); + + h2fmi_reset(fmi); + + if(ppnCommand->options & PPN_OPTIONS_GET_PAGE_RMA_INFO) + { +// h2fmi_ce_t ce = h2fmi_ppn_ce_index_to_physical(ppnCommand, 0); + + WMR_PANIC("Get RMA data not yet implemented with new PPN_FIL"); +// WMR_PRINT(ALWAYS, "Attempting to pull RMA data for CE %d\n", ce); +// h2fmi_ppn_force_geb_address(fmi, ce, ppnCommand->pages[0]); + return _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + + if(ppnCommand->options & PPN_OPTIONS_REPORT_HEALTH) + { + setFeaturesBuffer[0] = 1; // To enable Bitflips/1KB data collection feature + setFeaturesBuffer[1] = 0; + setFeaturesBuffer[2] = 0; + setFeaturesBuffer[3] = 0; + } + + for (i = 0; i < PPN_MAX_CES_PER_BUS; i++) + { + if (ppnCommand->ceInfo[i].pages > 0) + { + h2fmi_ce_t ce = h2fmi_ppn_ce_index_to_physical(ppnCommand, i); + if(ppnCommand->options & PPN_OPTIONS_REPORT_HEALTH) + { + if (FIL_SUCCESS != h2fmi_ppn_set_features(fmi, + ce, + PPN_FEATURE__ENABLE_BITFLIPS_DATA_COLLECTION, + setFeaturesBuffer, + PPN_FEATURE_LENGTH_ENABLE_BITFLIPS_DATA_COLLECTION, + FALSE32, + NULL)) + { + WMR_PANIC("Set Features failed on CE index %d (physical %d)", i, ce); + } + } + } + } + + for( readPage = 0; (readPage < page_count) && !timeout; readPage++) + { + const UInt8 readPageCeIndex = ppnCommand->entry[readPage].ceIdx; + const h2fmi_ce_t readPagePhysCe = h2fmi_ppn_ce_index_to_physical(ppnCommand, + readPageCeIndex); + UInt32 lba; + + while((queueDepth < readQueueSize) && (prepPage < page_count)) + { + const UInt8 ceIndex = ppnCommand->entry[prepPage].ceIdx; + const h2fmi_ce_t physCe = h2fmi_ppn_ce_index_to_physical(ppnCommand, + ceIndex); + + WMR_ASSERT(ceIndex < PPN_MAX_CES_PER_BUS); + h2fmi_ppn_switch_ce(fmi, physCe); + ret = h2fmi_ppn_prep_read(fmi, + &ppnCommand->entry[prepPage].addr, + cePageCount[ceIndex] + 1 == ppnCommand->ceInfo[ceIndex].pages); + + WMR_ASSERT( ret == TRUE32); + cePageCount[ceIndex]++; + prepPage++; + queueDepth++; + } + + if (0 == readPage) { + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + data_segment_array, + h2fmi_dma_data_fifo(fmi), + ppnCommand->lbas * fmi->logical_page_size, + sizeof(UInt32), + H2FMI_DMA_BURST_CYCLES, + fmi->current_aes_cxt); + + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_meta_chan(fmi), + meta_segment_array, + h2fmi_dma_meta_fifo(fmi), + ppnCommand->lbas * fmi->valid_bytes_per_meta, +#if FMI_VERSION >= 4 + sizeof(UInt32), + 4, +#else // FMI_VERSION < 4 + sizeof(UInt8), + 1, +#endif // FMI_VERSION < 4 + NULL); + } + + h2fmi_ppn_switch_ce(fmi, readPagePhysCe); + ret = h2fmi_ppn_get_next_operation_status(fmi, &opStatus); + if (!ret) + { + ppnCommand->entry[readPage].status = 0; + timeout = TRUE32; + break; + } + else if (fmi->retire_on_invalid_refresh && + ((PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR) == + (opStatus & (PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR)))) + { + // Remap 0x43 (refresh + invalid) to 0x45 (retire + invalid) + opStatus = (opStatus & ~(PPN_OPERATION_STATUS__REFRESH)) | PPN_OPERATION_STATUS__RETIRE; + } + + ppnCommand->entry[readPage].status = opStatus; + overallStatus |= opStatus; + + h2fmi_send_cmd(fmi, NAND_CMD__READ_SERIAL_OUTPUT); + for (lba = 0; lba < ppnCommand->entry[readPage].lbas; lba++) + { + h2fmi_ppn_get_page_data(fmi, fmi->logical_page_size); + } + queueDepth--; + } + + if (timeout || + !h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + } + + for (i = 0; i < PPN_MAX_CES_PER_BUS; i++) + { + if (ppnCommand->ceInfo[i].pages > 0) + { + h2fmi_ce_t physCe = ppnCommand->ceInfo[i].ce; + + h2fmi_ppn_switch_ce(fmi, physCe); + h2fmi_send_cmd(fmi, NAND_CMD__GET_NEXT_OPERATION_STATUS); + } + } + + h2fmi_ppn_disable_all_ces(fmi); + + ppnCommand->page_status_summary = overallStatus; + if (timeout) + { + iopfmiStatus = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if (overallStatus & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + iopfmiStatus = _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + WMR_PRINT(ERROR, "IOP returning kIOPFMI_STATUS_PPN_GENERAL_ERROR\n"); + } + else + { + iopfmiStatus = _kIOPFMI_STATUS_SUCCESS; + } + + return iopfmiStatus; +} + +Int32 h2fmi_ppn_read_bootpage(h2fmi_t *fmi, + UInt16 ce, + UInt32 page, + UInt8 *buf, + UInt8 *max_corrected) +{ + Int32 ret = _kIOPFMI_STATUS_SUCCESS; + UInt8 operationStatus; + UInt8 i; + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if SUPPORT_TOGGLE_NAND && !APPLICATION_EMBEDDEDIOP + if (fmi->is_toggle_system) + { + transitionWorldFromDDR(PPN_FEATURE__POWER_STATE__ASYNC); + } +#endif + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + + h2fmi_ppn_switch_ce(fmi, ce); + + h2fmi_send_cmd_addr_cmd(fmi, + NAND_CMD__MULTIPAGE_READ_LAST, + NAND_CMD__MULTIPAGE_READ_CONFIRM, + (UInt8 *)&page, + fmi->ppn->bytes_per_row_address); + + ret = h2fmi_ppn_get_next_operation_status(fmi, &operationStatus); + if (!ret) + { + WMR_PRINT(ERROR, "Timeout reading operation status in Read Bootpage\n"); + ret = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if (operationStatus != PPN_OPERATION_STATUS__READY) + { + if (operationStatus & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + WMR_PRINT(ERROR, "General Error bit asserted during Read Boot Page\n"); + ret = _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + else if (operationStatus & PPN_OPERATION_STATUS__CLEAN) + { + ret = _kIOPFMI_STATUS_BLANK; + } + else + { + WMR_PRINT(ERROR, "Error 0x%02x bus: %d ce: %d p:0x%08x\n", (UInt32)operationStatus, (UInt32) fmi->bus_id, (UInt32) ce, page); + ret = _kIOPFMI_STATUS_AT_LEAST_ONE_UECC; + } + } + + if (buf != NULL) + { + h2fmi_clean_ecc(fmi); + h2fmi_send_cmd(fmi, NAND_CMD__READ_SERIAL_OUTPUT); + + h2fmi_ppn_set_format(fmi, H2FMI_BYTES_PER_BOOT_SECTOR, 1, TRUE32); + for (i = 0; i < H2FMI_BOOT_SECTORS_PER_PAGE; i++) + { +#if FMI_ECC_DEBUG + h2fmi_wr(fmi, ECC_PND, ~0UL); +#endif // FMI_ECC_DEBUG + +#if FMI_VERSION > 3 + h2fmi_wr(fmi, FMI_SCRAMBLER_SEED_FIFO, page + i); +#endif // FMI_VERSION > 3 + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + if (!h2fmi_pio_read_sector(fmi, buf, H2FMI_BYTES_PER_BOOT_SECTOR)) + { +#if FMI_ECC_DEBUG + WMR_PANIC("PIO on bus %lu of sector %lu failed - %lu previous successes\n", + fmi->bus_id, i, fmi->ppn->ecc_sectors_read); +#endif // FMI_ECC_DEBUG + ret = _kIOPFMI_STATUS_DMA_DONE_TIMEOUT; + break; + } + buf += H2FMI_BYTES_PER_BOOT_SECTOR; + +#if FMI_ECC_DEBUG + fmi->ppn->ecc_sectors_read++; +#endif // FMI_ECC_DEBUG + } + + if (_kIOPFMI_STATUS_SUCCESS == ret) + { + ret = h2fmi_rx_check_page_ecc(fmi, 0, NULL, NULL, H2FMI_BOOT_SECTORS_PER_PAGE); + if (_kIOPFMI_STATUS_SUCCESS != ret) + { + WMR_PRINT(ERROR, "PPN status check reported success, but ECC status check reported 0x%08x!\n", ret); + } + } + } + h2fmi_send_cmd(fmi, NAND_CMD__GET_NEXT_OPERATION_STATUS); + + h2fmi_ppn_disable_all_ces(fmi); + h2fmi_reset(fmi); + +#if SUPPORT_TOGGLE_NAND && !APPLICATION_EMBEDDEDIOP + if (fmi->is_toggle_system) + { + transitionWorldToDDR(PPN_FEATURE__POWER_STATE__ASYNC); + } +#endif + + return ret; +} + +Int32 h2fmi_ppn_read_cau_bbt(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + UInt8 *buf) +{ + UInt8 *status = &ppnCommand->entry[0].status; + const UInt16 ceIndex = ppnCommand->entry[0].ceIdx; + const UInt32 pageAddr = ppnCommand->entry[0].addr.row; + const h2fmi_ppn_device_params_t *dev = &fmi->ppn->device_params; + const UInt32 cau = (pageAddr >> (dev->page_address_bits + dev->block_bits)) & ((1 << dev->cau_bits) - 1); + const h2fmi_ce_t physCe = h2fmi_ppn_ce_index_to_physical(ppnCommand, ceIndex); + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + WMR_ASSERT(cau < fmi->ppn->device_params.caus_per_channel); + + //WMR_PRINT(ALWAYS, "Read CAU BBT: bus %d, ce %d, CAU 0x%08x\n", fmi->bus_id, physCe, cau); + + h2fmi_ppn_get_feature(fmi, + physCe, + PPN_FEATURE__BAD_BLOCK_BITMAP_ARRAY | (cau << 8), + buf, + fmi->ppn->device_params.blocks_per_cau / 8, + status); + + ppnCommand->page_status_summary = status[0]; + + if (ppnCommand->page_status_summary & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + return _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + else + { + return _kIOPFMI_STATUS_SUCCESS; + } +} + +UInt8 h2fmi_ppn_get_idle_counter(h2fmi_t *fmi, + h2fmi_ce_t ce) +{ + UInt32 counter; + UInt8 status; + + if (!h2fmi_ppn_get_feature(fmi, + ce, + PPN_FEATURE__IDLE_COUNTER, + (UInt8 *)&counter, + 4, + &status)) + { + WMR_PANIC("Unexpected status or timeout reading PPN idle counter"); + } + + h2fmi_reset(fmi); + + return counter & 0xFF; +} + + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM +Int32 h2fmi_ppn_write_multi(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + struct dma_segment *data_segment_array, + struct dma_segment *meta_segment_array) +{ + const UInt32 page_count = ppnCommand->num_pages; + BOOL32 ret = TRUE32; + UInt32 pageIndex = 0; + BOOL32 error = FALSE32; + h2fmi_ce_t errorCe; + UInt8 overallStatus = 0; + UInt32 cePageCount[PPN_MAX_CES_PER_BUS] = {0}; + BOOL32 timeout = FALSE32; + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + WMR_ASSERT(page_count > 0); + WMR_ASSERT(page_count <= fmi->ppn->device_params.prep_function_buffer_size); + + h2fmi_reset(fmi); + + if (page_count > 1) + { + h2fmi_ppn_prep_write_multi(fmi, ppnCommand); + } + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_data_chan(fmi), + data_segment_array, + h2fmi_dma_data_fifo(fmi), + ppnCommand->lbas * fmi->logical_page_size, + sizeof(UInt32), + H2FMI_DMA_BURST_CYCLES, + fmi->current_aes_cxt); + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_meta_chan(fmi), + meta_segment_array, + h2fmi_dma_meta_fifo(fmi), + ppnCommand->lbas * fmi->valid_bytes_per_meta, +#if FMI_VERSION >= 4 + sizeof(UInt32), + 4, +#else // FMI_VERSION < 4 + sizeof(UInt8), + 1, +#endif // FMI_VERSION < 4 + NULL); + + for (pageIndex = 0; (ret && + (pageIndex < page_count) && + !timeout && + !error); + pageIndex++) + { + const UInt8 ceIndex = ppnCommand->entry[pageIndex].ceIdx; + const h2fmi_ce_t physCe = h2fmi_ppn_ce_index_to_physical(ppnCommand, ceIndex); + UInt8 status; + + h2fmi_ppn_switch_ce(fmi, physCe); + h2fmi_ppn_program_page(fmi, + ppnCommand->entry[pageIndex].addr.row, + cePageCount[ceIndex] + 1 == ppnCommand->ceInfo[ceIndex].pages, + ppnCommand->entry[pageIndex].lbas); + + ret = h2fmi_ppn_get_controller_status(fmi, &status); + if (!ret) + { + // Don't look at op status at all if we timed out - it could have bogus bits set. + status = 0; + } + + // Always mark the program as good here - if there was a program error or if the page was + // kicked off but not completed, we'll fix up the status when we pull the program error + // lists. + ppnCommand->entry[pageIndex].status = PPN_CONTROLLER_STATUS__READY; + overallStatus |= status; + + if (!ret) + { + WMR_PRINT(ERROR, "Timeout waiting for controller status after multi write\n"); + timeout = TRUE32; + } + else if (status & PPN_CONTROLLER_STATUS__PENDING_ERRORS) + { + error = TRUE32; + errorCe = ceIndex; + WMR_PRINT(ERROR, "Bailing out due to program error\n"); + } + else if (status & PPN_CONTROLLER_STATUS__GENERAL_ERROR) + { + WMR_PRINT(ERROR, "Terminating program due to General Error\n"); + break; + } + + cePageCount[ceIndex]++; + } + h2fmi_ppn_disable_all_ces(fmi); + + if (error || timeout || fmi->ppn->general_error || + !h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + WMR_PRINT(ERROR, "Cancelling DMA\n"); + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_reset(fmi); + ret = FALSE32; + } + + if (!timeout && error && !fmi->ppn->general_error) + { + UInt32 temp = 1; + UInt8 status = 0; + h2fmi_ce_t physCe = h2fmi_ppn_ce_index_to_physical(ppnCommand, errorCe); + + // Find failed pages... + h2fmi_ppn_get_feature(fmi, + physCe, + PPN_FEATURE__PROGRAM_FAILED_PAGES, + (UInt8 *)fmi->error_list, + PPN_ERROR_LIST_SIZE, + &status); + + WMR_PRINT(ERROR, "PPN device reports %d pages failed program\n", fmi->error_list[0]); + h2fmi_ppn_process_error_list(fmi, ppnCommand, errorCe, fmi->error_list, PPN_PROGRAM_STATUS_FAIL); + + // Find pending pages... + h2fmi_ppn_get_feature(fmi, + physCe, + PPN_FEATURE__PROGRAM_IGNORED_PAGES, + (UInt8 *)fmi->error_list, + PPN_ERROR_LIST_SIZE, + &status); + + WMR_PRINT(ERROR, "PPN device reports %d pages pending after program failure\n", fmi->error_list[0]); + h2fmi_ppn_process_error_list(fmi, ppnCommand, errorCe, fmi->error_list, PPN_PROGRAM_STATUS_NOT_PROGRAMMED); + + + // Find pages to retire... + h2fmi_ppn_get_feature(fmi, + physCe, + PPN_FEATURE__PROGRAM_RETIRED_PAGES, + (UInt8 *)fmi->error_list, + PPN_ERROR_LIST_SIZE, + &status); + + WMR_PRINT(ERROR, "PPN device reports %d pages should be retired after program failure\n", fmi->error_list[0]); + h2fmi_ppn_process_error_list(fmi, ppnCommand, errorCe, fmi->error_list, PPN_PROGRAM_STATUS_FAIL); + + // Clear Program error lists + h2fmi_ppn_set_features(fmi, + physCe, + PPN_FEATURE__CLEAR_PROGRAM_ERROR_LISTS, + (UInt8 *)&temp, + 4, + FALSE32, + NULL); + + } + + ppnCommand->page_status_summary = overallStatus; + if (timeout) + { + return _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if (overallStatus & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + return _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + else + { + return _kIOPFMI_STATUS_SUCCESS; + } +} +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + +void h2fmi_ppn_process_error_list(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + UInt8 ceIdx, + UInt32 *list, + UInt8 status) +{ + const UInt32 count = list[0]; + UInt32 listIdx; + + if (!count) + { + return; + } + + for (listIdx = 1; listIdx <= count; listIdx++) + { + const UInt32 page = list[listIdx]; + UInt16 cmdIdx; + + for (cmdIdx = 0; cmdIdx < ppnCommand->num_pages; cmdIdx++) + { + if ((ppnCommand->entry[cmdIdx].addr.row == page) && + (ppnCommand->entry[cmdIdx].ceIdx == ceIdx)) + { + WMR_PRINT(ALWAYS, "Bus %d ceIdx %d setting index %d (page 0x%08x) status to 0x%02x\n", + fmi->bus_id, ceIdx, cmdIdx, page, status); + + ppnCommand->entry[cmdIdx].status |= status; + break; + } + } + + if (cmdIdx >= ppnCommand->num_pages) + { + WMR_PRINT(ERROR, "CE 0x%x Page 0x%08x is not in the command structure!", ppnCommand->ceInfo[ceIdx].ce, page); + } + } +} + + +Int32 h2fmi_ppn_write_bootpage(h2fmi_t *fmi, + UInt16 ce, + UInt32 dwPpn, + const UInt8 *pabData) +{ + Int32 ret = _kIOPFMI_STATUS_SUCCESS; + UInt8 controller_status = 0; + struct dma_segment sgl; + BOOL32 timeout = FALSE32; + UInt8 i; + +#if SUPPORT_TOGGLE_NAND && !APPLICATION_EMBEDDEDIOP + if (fmi->is_toggle_system) + { + transitionWorldFromDDR(PPN_FEATURE__POWER_STATE__ASYNC); + } +#endif + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + h2fmi_reset(fmi); + h2fmi_ppn_switch_ce(fmi, ce); + + sgl.paddr = (UInt32)pabData; + sgl.length = H2FMI_BOOT_BYTES_PER_PAGE; + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_data_chan(fmi), + &sgl, + h2fmi_dma_data_fifo(fmi), + H2FMI_BOOT_BYTES_PER_PAGE, + sizeof(UInt32), + 32, + NULL); + + h2fmi_send_cmd_addr(fmi, + NAND_CMD__MULTIPAGE_PROGRAM_LAST, + (UInt8 *)&dwPpn, + fmi->ppn->bytes_per_row_address); + + h2fmi_ppn_set_format(fmi, H2FMI_BYTES_PER_BOOT_SECTOR, 1, TRUE32); + for (i = 0; i < H2FMI_BOOT_SECTORS_PER_PAGE; i++) + { +#if FMI_VERSION > 3 + h2fmi_wr(fmi, FMI_SCRAMBLER_SEED_FIFO, dwPpn + i); +#endif // FMI_VERSION > 3 + h2fmi_ppn_start_fmi_write_and_wait(fmi); + } + + h2fmi_send_cmd(fmi, NAND_CMD__MULTIPAGE_PROGRAM_CONFIRM); + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + WMR_PANIC("Timeout waiting for CDMA channel %d to complete\n", + h2fmi_dma_data_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + } + + ret = h2fmi_ppn_get_controller_status(fmi, &controller_status); + if (!ret) + { + WMR_PRINT(ERROR, "Timeout waiting for controller status in Write bootpage\n"); + timeout = TRUE32; + } + + h2fmi_ppn_disable_all_ces(fmi); + + if (timeout) + { + ret = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if (controller_status & PPN_CONTROLLER_STATUS__GENERAL_ERROR) + { + ret = _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + else if (controller_status & PPN_CONTROLLER_STATUS__PENDING_ERRORS) + { + UInt32 temp = 1; + + WMR_PRINT(ERROR, "PPN device reports program error (0x%02x) on write boot page 0x%08x\n", + controller_status, dwPpn); + + h2fmi_ppn_set_features(fmi, + ce, + PPN_FEATURE__CLEAR_PROGRAM_ERROR_LISTS, + (UInt8 *)&temp, + 4, + FALSE32, + NULL); + + ret = _kIOPFMI_STATUS_PGM_ERROR; + } + +#if SUPPORT_TOGGLE_NAND && !APPLICATION_EMBEDDEDIOP + if (fmi->is_toggle_system) + { + transitionWorldToDDR(PPN_FEATURE__POWER_STATE__ASYNC); + } +#endif + + return ret; +} + +Int32 h2fmi_ppn_erase_blocks(h2fmi_t *fmi, PPNCommandStruct *ppnCommand) +{ + const UInt32 queueSize = fmi->ppn->device_params.erase_queue_size; + BOOL32 ret; + UInt16 ceIndex; + UInt8 overallStatus = 0; + BOOL32 timeout = FALSE32; + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + + for (ceIndex = 0; ceIndex < PPN_MAX_CES_PER_BUS; ceIndex++) + { + const h2fmi_ce_t physCe = h2fmi_ppn_ce_index_to_physical(ppnCommand, ceIndex); + const UInt32 numBlocks = ppnCommand->ceInfo[ceIndex].pages; + const UInt32 ceOffset = ppnCommand->ceInfo[ceIndex].offset; + UInt32 prepBlock = 0; + UInt32 eraseBlock = 0; + UInt8 controllerStatus = 0; + UInt32 currentQueueLevel = 0; + + if (numBlocks == 0) + { + continue; + } + + h2fmi_ppn_switch_ce(fmi, physCe); + + for (eraseBlock = 0; eraseBlock < numBlocks; eraseBlock++) + { + while((currentQueueLevel < queueSize) && (prepBlock < numBlocks)) + { + UInt8 cmd; + + cmd = (prepBlock == (numBlocks - 1)) ? + NAND_CMD__MULTIBLOCK_ERASE_LAST : + NAND_CMD__MULTIBLOCK_ERASE; + + h2fmi_send_cmd_addr_cmd(fmi, + cmd, + NAND_CMD__MULTIBLOCK_ERASE_CONFIRM, + (UInt8 *)&ppnCommand->entry[ceOffset + prepBlock].addr.row, + fmi->ppn->bytes_per_row_address); + + if (!h2fmi_ppn_get_controller_status(fmi, &controllerStatus)) + { + timeout = TRUE32; + goto done; + } + + currentQueueLevel++; + prepBlock++; + } + + // How do I find the right place for this op status if I'm striping across CEs...? + ret = h2fmi_ppn_get_next_operation_status(fmi, + &ppnCommand->entry[ceOffset + eraseBlock].status); + if (!ret) + { + timeout = TRUE32; + goto done; + } + currentQueueLevel--; + overallStatus |= ppnCommand->entry[ceOffset + eraseBlock].status; + } + + h2fmi_send_cmd(fmi, NAND_CMD__GET_NEXT_OPERATION_STATUS); + } + + done: + h2fmi_ppn_disable_all_ces(fmi); + ppnCommand->page_status_summary = overallStatus; + + if (timeout) + { + return _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if (overallStatus & PPN_CONTROLLER_STATUS__GENERAL_ERROR) + { + return _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + else + { + return _kIOPFMI_STATUS_SUCCESS; + } +} + + +/** + * Send a multipage read PPN command for a particular page + * + * Send a: + * MULTIPAGE_READ / page / MULTIPAGE_READ_CONFIRM + * CONTROLLER_STATUS / wait for 0x42 + * + * sequence to the NAND device + * + * @param fmi Pointer to FMI bus sturucture + * @param page Value to send as NAND page address + * @param last TRUE32 if last page in operation + * + * @return + * - TRUE32 if operation completed with expected status + * - FALSE32 on timeout waiting for expected status + */ +static BOOL32 h2fmi_ppn_prep_read(h2fmi_t *fmi, const RowColLenAddressType *page, BOOL32 last) +{ + UInt8 cmd = (last == TRUE32) ? NAND_CMD__MULTIPAGE_READ_LAST : NAND_CMD__MULTIPAGE_READ; + + if (fmi->logical_page_size == fmi->bytes_per_page) + { + h2fmi_send_cmd_addr_cmd(fmi, + cmd, + NAND_CMD__MULTIPAGE_READ_CONFIRM, + (UInt8 *)&page->row, + fmi->ppn->bytes_per_row_address); + } + else + { + h2fmi_send_cmd_addr_cmd(fmi, + cmd, + NAND_CMD__MULTIPAGE_READ_CONFIRM, + (UInt8 *)page, + fmi->ppn->bytes_per_full_address); + } + + return TRUE32; +} + +static void h2fmi_ppn_prep_pages(h2fmi_t *fmi, + UInt16 physCe, + UInt32 cePageCount) +{ + UInt32 writePrepCount = (cePageCount << 8) | 0x87; + UInt32 fullSectors = 0; + UInt32 address_bytes = cePageCount * sizeof(UInt32); + + h2fmi_ppn_switch_ce(fmi, physCe); + + h2fmi_send_cmd_addr(fmi, + NAND_CMD__MULTIPAGE_PREP, + (UInt8 *)&writePrepCount, + 3); + + // First fill as many 1KB sectors as possible - note that it's the client's responsibility + // to have started a DMA for the page address buffer. + fullSectors = address_bytes / H2FMI_BYTES_PER_SECTOR; + if (fullSectors > 0) + { + h2fmi_ppn_set_format(fmi, H2FMI_BYTES_PER_SECTOR, fullSectors, FALSE32); + h2fmi_ppn_start_fmi_write_and_wait(fmi); + address_bytes -= (H2FMI_BYTES_PER_SECTOR * fullSectors); + } + + if (address_bytes > 0) + { + h2fmi_ppn_set_format(fmi, address_bytes, 1, FALSE32); + h2fmi_ppn_start_fmi_write_and_wait(fmi); + } + + h2fmi_send_cmd(fmi, NAND_CMD__MULTIPAGE_PREP__CONFIRM); +} + +static void h2fmi_ppn_prep_write_multi(h2fmi_t *fmi, + const PPNCommandStruct *ppnCommand) +{ + const UInt32 totalPages = ppnCommand->num_pages; + UInt16 ceIndex; + UInt32 pageIndex; + struct dma_segment dma_segment; + + for (pageIndex = 0 ; pageIndex < totalPages ; pageIndex++) + { + const PPNCommandEntry *entry = &ppnCommand->entry[pageIndex]; + + *fmi->ppn->prep_buffer[entry->ceIdx]++ = entry->addr.row; + } + + + // If we ever get DMA chaining in EFI we could make a SGL out of this and use + // a single DMA for all CEs.. + for (ceIndex = 0; ceIndex < PPN_MAX_CES_PER_BUS; ceIndex++) + { + const UInt32 numPages = ppnCommand->ceInfo[ceIndex].pages; + const h2fmi_ce_t physCe = h2fmi_ppn_ce_index_to_physical(ppnCommand, ceIndex); + + fmi->ppn->prep_buffer[ceIndex] -= numPages; + + if (numPages > 0) + { + const UInt32 prepBuffer = (UInt32)fmi->ppn->prep_buffer[ceIndex]; + + WMR_PREPARE_WRITE_BUFFER(fmi->ppn->prep_buffer[ceIndex], numPages * sizeof(**fmi->ppn->prep_buffer)); + +#if WMR_BUILDING_IBOOT + dma_segment.paddr = mem_static_map_physical(prepBuffer); +#else + dma_segment.paddr = prepBuffer; +#endif /* WMR_BUILDING_IBOOT */ + dma_segment.length = numPages * sizeof(UInt32); + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_data_chan(fmi), + &dma_segment, + h2fmi_dma_data_fifo(fmi), + numPages * sizeof(UInt32), + sizeof(UInt32), + 1, + NULL); + + h2fmi_ppn_prep_pages(fmi, physCe, numPages); + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + WMR_PANIC("Timeout waiting for CDMA channel %d to complete multi prep: ce %d, %d pages", h2fmi_dma_data_chan(fmi), physCe, numPages); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + WMR_PRINT(ERROR, "Timeout waiting for CDMA to complete multi prep\n"); + } + } + } +} + +Int32 h2fmi_ppn_set_features(h2fmi_t *fmi, UInt32 ce, UInt16 feature, UInt8 *data, UInt32 len, BOOL32 optFeature, UInt8 *stat) +{ + UInt8 operation_status = 0; + Int32 ret = FIL_SUCCESS; + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__START_BIT); + UInt32 pos; + UInt32 sector_len; + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + h2fmi_ppn_switch_ce(fmi, ce); + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__SOFTWARE_RESET); + + h2fmi_send_cmd_addr(fmi, NAND_CMD__SET_FEATURES, (UInt8 *)&feature, 2); + h2fmi_clear_interrupts_and_reset_masks(fmi); + + for(pos = 0; pos < len; pos += sector_len) + { + UInt32 bounce = 0; + void *cursor = &data[pos]; + + sector_len = WMR_MIN(H2FMI_BYTES_PER_SECTOR, len - pos); + if (sizeof(bounce) > sector_len) + { + WMR_MEMCPY(&bounce, cursor, sector_len); + cursor = &bounce; + sector_len = sizeof(bounce); + } + else + { + sector_len = ROUNDDOWNTO(sector_len, sizeof(bounce)); + } + + h2fmi_ppn_set_format(fmi, sector_len, 1, FALSE32); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_pio_write_sector(fmi, cursor, sector_len); + h2fmi_busy_wait(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE); + h2fmi_wr(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE); + } + + h2fmi_send_cmd(fmi, NAND_CMD__SET_GET_FEATURES_CONFIRM); + if (!h2fmi_ppn_get_next_operation_status(fmi, &operation_status) || (operation_status != PPN_FEAT_OPERATION_STATUS__SUCCESS)) + { + if ((operation_status == PPN_FEAT_OPERATION_STATUS__UNSUPPORTED_BY_CH) || (operation_status == PPN_FEAT_OPERATION_STATUS__UNSUPPORTED)) + { + if (!optFeature) + { + WMR_PRINT(ERROR, "PPN feature 0x%04x is unsupported on CH %d: status = 0x%02x\n", feature, fmi->bus_id, operation_status); + } + ret = FIL_UNSUPPORTED_ERROR; + } + else + { + WMR_PRINT(ERROR, "Unable to set PPN feature 0x%04x: status = 0x%02x\n", feature, operation_status); + ret = FIL_CRITICAL_ERROR; + } + } + h2fmi_send_cmd(fmi, NAND_CMD__GET_NEXT_OPERATION_STATUS); + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__SOFTWARE_RESET); + h2fmi_ppn_disable_all_ces(fmi); + h2fmi_reset(fmi); + +#if H2FMI_PPN_VERIFY_SET_FEATURES + if (FIL_SUCCESS == ret) + { + _update_feature_shadow(fmi, feature, data, len); + } +#endif // H2FMI_PPN_VERIFY_SET_FEATURES + + if (stat) + { + *stat = operation_status; + } + + return ret; +} + +BOOL32 h2fmi_ppn_get_feature(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt32 feature, + UInt8 *buffer, + UInt32 len, + UInt8 *status) +{ + BOOL32 ret = TRUE32; + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + UInt32 pos; + UInt32 sector_len; + UInt8 operation_status = 0; + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_ppn_switch_ce(fmi, ce); + + h2fmi_clear_interrupts_and_reset_masks(fmi); + + h2fmi_send_cmd_addr_cmd(fmi, + NAND_CMD__GET_FEATURES, + NAND_CMD__SET_GET_FEATURES_CONFIRM, + (UInt8 *)&feature, + 2); + if (!h2fmi_ppn_get_next_operation_status(fmi, &operation_status) || (operation_status != 0x40)) + { + WMR_PRINT(ERROR, "Unable to get PPN feature 0x%04x: status = 0x%02x\n", feature, (UInt32) operation_status); + ret = FALSE32; + } + h2fmi_send_cmd(fmi, NAND_CMD__READ_SERIAL_OUTPUT); + + for(pos = 0; pos < len; pos += sector_len) + { + UInt32 bounce = 0; + void *cursor = &buffer[pos]; + + sector_len = WMR_MIN(H2FMI_BYTES_PER_SECTOR, len - pos); + if (sizeof(bounce) > sector_len) + { + cursor = &bounce; + sector_len = sizeof(bounce); + } + else + { + sector_len = ROUNDDOWNTO(sector_len, sizeof(bounce)); + } + + h2fmi_ppn_set_format(fmi, sector_len, 1, FALSE32); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_pio_read_sector(fmi, cursor, sector_len); + + if (&bounce == cursor) + { + WMR_MEMCPY(&buffer[pos], cursor, WMR_MIN(H2FMI_BYTES_PER_SECTOR, len - pos)); + } + } + + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__SOFTWARE_RESET); + h2fmi_send_cmd(fmi, NAND_CMD__GET_NEXT_OPERATION_STATUS); + h2fmi_ppn_disable_all_ces(fmi); + + if (status) + { + *status = operation_status; + } + + return ret; +} + + +static void h2fmi_ppn_set_format(h2fmi_t *fmi, UInt32 sector_len, UInt32 sector_count, BOOL32 bootpage) +{ + UInt32 fmi_config; + + if (bootpage) + { + fmi_config = FMI_CONFIG__ECC_CORRECTABLE_BITS(30) | + FMI_CONFIG__DMA_BURST__32_CYCLES; +#if FMI_VERSION > 3 + fmi_config |= FMI_CONFIG__SCRAMBLE_SEED | + FMI_CONFIG__ENABLE_WHITENING; +#endif + } + else + { + fmi_config = FMI_CONFIG__ECC_CORRECTABLE_BITS(0) | + FMI_CONFIG__DMA_BURST__32_CYCLES; + } + + h2fmi_wr(fmi, FMI_CONFIG, fmi_config); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(sector_len) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(sector_count))); +#if FMI_VERSION > 3 + if (bootpage) + { + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__RESET_SEED); + } +#endif // FMI_VERSION > 3 +} + +static void h2fmi_ppn_start_fmi_read_and_wait(h2fmi_t *fmi) +{ + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_clear_interrupts_and_reset_masks(fmi); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_busy_wait(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE); + h2fmi_wr(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE); +} + +static void h2fmi_ppn_start_fmi_write_and_wait(h2fmi_t *fmi) +{ + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__START_BIT); + + h2fmi_clear_interrupts_and_reset_masks(fmi); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_busy_wait(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE); + h2fmi_wr(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE); +} + +static void h2fmi_ppn_get_page_data(h2fmi_t *fmi, UInt32 length) +{ + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_prepare_for_fmi_interrupt(fmi, FMI_INT_EN__LAST_FMC_DONE); + h2fmi_wr(fmi, FMI_CONFIG, fmi->fmi_config_reg); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__BYTES_PER_SECTOR(H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(length / H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__META_BYTES_PER_SECTOR(fmi->valid_bytes_per_meta) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(fmi->valid_bytes_per_meta))); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + if (!h2fmi_wait_for_fmi_interrupt(fmi, FMI_INT_PEND__LAST_FMC_DONE)) + { + WMR_PANIC("Timeout waiting for LAST_FMC_DONE interrupt"); + } +} + +static void h2fmi_ppn_program_page(h2fmi_t *fmi, UInt32 page, BOOL32 lastPage, UInt32 lbas) +{ + UInt32 lba; + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__START_BIT); + + h2fmi_send_cmd_addr(fmi, + lastPage ? NAND_CMD__MULTIPAGE_PROGRAM_LAST : NAND_CMD__MULTIPAGE_PROGRAM, + (UInt8 *)&page, + fmi->ppn->bytes_per_row_address); + + for (lba = 0; lba < lbas; lba++) + { + h2fmi_prepare_for_fmi_interrupt(fmi, FMI_INT_EN__LAST_FMC_DONE); + h2fmi_wr(fmi, FMI_CONFIG, fmi->fmi_config_reg); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__BYTES_PER_SECTOR(H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(fmi->logical_page_size / H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__META_BYTES_PER_SECTOR(fmi->valid_bytes_per_meta) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(fmi->valid_bytes_per_meta))); + + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + if (!h2fmi_wait_for_fmi_interrupt(fmi, FMI_INT_PEND__LAST_FMC_DONE)) + { + WMR_PANIC("Timeout waiting for LAST_FMC_DONE interrupt"); + } + } + + h2fmi_send_cmd(fmi, NAND_CMD__MULTIPAGE_PROGRAM_CONFIRM); +} + +BOOL32 h2fmi_ppn_get_debug_data(h2fmi_t *fmi, h2fmi_ce_t ce, UInt32 type, UInt8 *buffer, UInt32 len) +{ + UInt8 operation_status = 0; + h2fmi_ppn_switch_ce(fmi, ce); + + h2fmi_send_cmd_addr_cmd(fmi, + NAND_CMD__GET_DEBUG_DATA, + NAND_CMD__SET_GET_FEATURES_CONFIRM, + (UInt8 *)&type, + 3); + + WMR_SLEEP_US(20000); + + h2fmi_send_cmd(fmi, NAND_CMD__OPERATION_STATUS); + h2fmi_get_nand_status(fmi, &operation_status); + //WMR_ASSERT(operation_status == 0x50); + h2fmi_ppn_read_serial_output(fmi, buffer, len); + h2fmi_ppn_disable_all_ces(fmi); + return TRUE32; +} + +BOOL32 h2fmi_ppn_set_debug_data(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt32 type, + UInt8 *buffer, + UInt32 len) +{ + UInt8 operationStatus = 0; + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__START_BIT); + + h2fmi_ppn_switch_ce(fmi, ce); + + h2fmi_send_cmd_addr(fmi, + NAND_CMD__SET_DEBUG_DATA, + (UInt8 *)&type, + 3); + + h2fmi_prepare_for_fmi_interrupt(fmi, FMI_INT_EN__LAST_FMC_DONE); + h2fmi_ppn_set_format(fmi, len, 1, FALSE32); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_pio_write_sector(fmi, buffer, len); + if (!h2fmi_wait_for_fmi_interrupt(fmi, FMI_INT_PEND__LAST_FMC_DONE)) + { + h2fmi_ppn_disable_all_ces(fmi); + WMR_PANIC("Timeout waiting for LAST_FMC_DONE interrupt"); + } + + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__SOFTWARE_RESET); + + h2fmi_send_cmd(fmi, NAND_CMD__SET_GET_FEATURES_CONFIRM); + + WMR_SLEEP_US(10000); + + h2fmi_send_cmd(fmi, NAND_CMD__OPERATION_STATUS); + if (!h2fmi_get_nand_status(fmi, &operationStatus)) + { + WMR_PRINT(ERROR, "Timeout reading operation status in SetDebugData - don't trust any debug data you pull from here.\n"); + } + + h2fmi_ppn_disable_all_ces(fmi); + return TRUE32; +} + +BOOL32 h2fmi_ppn_get_fw_version(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt8 *buffer) +{ + BOOL32 ret; + UInt8 operationStatus = 0; + + h2fmi_reset(fmi); + + ret = h2fmi_ppn_get_feature(fmi, + ce, + PPN_FEATURE__FW_VERSION, + buffer, + NAND_DEV_PARAM_LEN_PPN, + &operationStatus); + + if (!ret) + { + WMR_PRINT(ERROR, "failed CE %d\n", ce); + } + return ret; +} + +BOOL32 h2fmi_ppn_get_package_assembly_code(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt8 *buffer) +{ + BOOL32 ret; + UInt8 operationStatus = 0; + + h2fmi_reset(fmi); + ret = h2fmi_ppn_get_feature(fmi, + ce, + PPN_FEATURE__PACKAGE_ASSEMBLY_CODE, + buffer, + NAND_DEV_PARAM_LEN_PPN, + &operationStatus); + return ret; +} + +BOOL32 h2fmi_ppn_get_controller_unique_id(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt8 *buffer) +{ + BOOL32 ret; + UInt8 operationStatus = 0; + + h2fmi_reset(fmi); + + ret = h2fmi_ppn_get_feature(fmi, + ce, + PPN_FEATURE__CONTROLLER_UNIQUE_ID, + buffer, + NAND_DEV_PARAM_LEN_PPN, + &operationStatus); + return ret; +} + +BOOL32 h2fmi_ppn_get_controller_hw_id(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt8 *buffer) +{ + BOOL32 ret; + UInt8 operationStatus = 0; + + h2fmi_reset(fmi); + + ret = h2fmi_ppn_get_feature(fmi, + ce, + PPN_FEATURE__CONTROLLER_HW_ID, + buffer, + NAND_DEV_PARAM_LEN_PPN, + &operationStatus); + return ret; +} + +BOOL32 h2fmi_ppn_get_marketing_name(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt8 *buffer) +{ + BOOL32 ret; + UInt8 operationStatus = 0; + + h2fmi_reset(fmi); + + ret = h2fmi_ppn_get_feature(fmi, + ce, + PPN_FEATURE__NAND_MARKETING_NAME, + buffer, + PPN_NAND_MARKETING_NAME_LENGTH, + &operationStatus); + return ret; +} + +BOOL32 h2fmi_ppn_get_manufacturer_id(h2fmi_t *fmi, h2fmi_ce_t ce, UInt8 *buffer) +{ + UInt8 addr; + const UInt32 len = 8; + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if SUPPORT_TOGGLE_NAND + // assert that SoC is in non-toggle (async) mode + WMR_ASSERT(!(fmi->is_toggle)); +#endif + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_reset(fmi); + + h2fmi_ppn_switch_ce(fmi, ce); + + addr = MfgID_ADDR; + + h2fmi_send_cmd_addr(fmi, + NAND_CMD__READ_ID, + (UInt8 *)&addr, + 1); + + h2fmi_ppn_set_format(fmi, len, 1, FALSE32); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_pio_read_sector(fmi, buffer, len); + + h2fmi_ppn_disable_all_ces(fmi); + h2fmi_reset(fmi); + return TRUE32; +} + +BOOL32 h2fmi_ppn_get_die_chip_id(h2fmi_t *fmi, h2fmi_ce_t ce, UInt32 die, UInt8 *buffer) +{ + BOOL32 ret; + UInt8 operationStatus = 0; + + h2fmi_reset(fmi); + + ret = h2fmi_ppn_get_feature(fmi, + ce, + PPN_FEATURE__NAND_DIE_CHIP_ID | (die << 8), + buffer, + PPN_FEATURE_LENGTH_DIE_CHIP_ID, + &operationStatus); + return ret; +} + + +BOOL32 h2fmi_ppn_get_general_error_info(h2fmi_t *fmi, + h2fmi_ce_t ce, + h2fmi_ppn_failure_info_t *buffer, + UInt32 *dataLength, + struct dma_segment *sgl) +{ + BOOL32 ret; + UInt32 structLength; + + WMR_ASSERT(buffer != NULL); + WMR_ASSERT(dataLength != NULL); + + h2fmi_reset(fmi); + + if(fmi->ppn->bytes_per_row_address == PPN_1_5_ROW_ADDR_BYTES) + { + structLength = sizeof(h2fmi_ppn_failure_info_ppn1_5_t); + } + else + { + structLength = sizeof(h2fmi_ppn_failure_info_ppn1_0_t); + } + ret = h2fmi_ppn_get_debug_data(fmi, + ce, + PPN_GET_DEBUG_DATA__GET_FAILURE_TYPE, + (UInt8 *)buffer, + structLength); + + if (ret) + { + UInt32 failureInfoPage; + UInt32 failureInfoPageCount; + + if(fmi->ppn->bytes_per_row_address == PPN_1_5_ROW_ADDR_BYTES) + { + h2fmi_ppn_failure_info_ppn1_5_t *tempBuffer = &(buffer->failure_info_1_5); + WMR_PRINT(ERROR, "General Failure Info - failure: 0x%04x page 0x%02x%02x%02x%02x count 0x%02x%02x%02x checksum %02x\n", + tempBuffer->type, + tempBuffer->startPage[3], tempBuffer->startPage[2], tempBuffer->startPage[1], tempBuffer->startPage[0], + tempBuffer->pageCount[2], tempBuffer->pageCount[1], tempBuffer->pageCount[0], + tempBuffer->checksum); + + failureInfoPage = (tempBuffer->startPage[0] | + (tempBuffer->startPage[1] << 8) | + (tempBuffer->startPage[2] << 16) | + (tempBuffer->startPage[3] << 24)); + + failureInfoPageCount = (((tempBuffer->pageCount[0]) | + (tempBuffer->pageCount[1] << 8) | + (tempBuffer->pageCount[2] << 16))); + } + else + { + h2fmi_ppn_failure_info_ppn1_0_t *tempBuffer = &(buffer->failure_info_1_0); + WMR_PRINT(ERROR, "General Failure Info - failure: 0x%04x page 0x%02x%02x%02x count 0x%02x%02x%02x checksum %02x\n", + tempBuffer->type, + tempBuffer->startPage[2], tempBuffer->startPage[1], tempBuffer->startPage[0], + tempBuffer->pageCount[2], tempBuffer->pageCount[1], tempBuffer->pageCount[0], + tempBuffer->checksum); + + failureInfoPage = (tempBuffer->startPage[0] | + (tempBuffer->startPage[1] << 8) | + (tempBuffer->startPage[2] << 16)); + + failureInfoPageCount = (((tempBuffer->pageCount[0]) | + (tempBuffer->pageCount[1] << 8) | + (tempBuffer->pageCount[2] << 16))); + } + + *dataLength = failureInfoPageCount * PPN_PERFECT_PAGE_SIZE; + + if ((failureInfoPageCount > 0) && + (NULL != sgl)) + { + // Pull the full Debug Data + h2fmi_ppn_dma_debug_data_payload(fmi, + ce, + failureInfoPage, + failureInfoPageCount, + sgl, + TRUE32); + } + } + else + { + *dataLength = 0; + WMR_PRINT(ERROR, "Timeout reading Failure Info Debug Data\n"); + } + + h2fmi_ppn_disable_all_ces(fmi); + return ret; +} + +static Int32 h2fmi_ppn_update_fw_chunk(h2fmi_t *fmi, + UInt32 chunk, + UInt32 length) +{ + Int32 ret; + UInt8 operation_status = 0; + + h2fmi_send_cmd_addr(fmi, NAND_CMD__UPDATE_FW, (UInt8 *)&chunk, 2); + + h2fmi_ppn_set_format(fmi, PPN_PERFECT_FMI_SECTOR_SIZE, PPN_PERFECT_FMI_SECTORS_PER_PERFECT_PAGE, FALSE32); + h2fmi_ppn_start_fmi_write_and_wait(fmi); + + h2fmi_send_cmd(fmi, NAND_CMD__SET_GET_FEATURES_CONFIRM); + ret = h2fmi_ppn_get_next_operation_status_with_addr(fmi, (UInt8 *)&chunk, &operation_status); + if (!ret) + { + WMR_PRINT(ERROR, "Timeout reading operation status on firmware chunk %d\n", chunk); + ret = FIL_CRITICAL_ERROR; + } + else if (operation_status == PPN_OPERATION_STATUS__READY) + { + ret = FIL_SUCCESS; + } + else if (operation_status == (PPN_OPERATION_STATUS__READY | + PPN_OPERATION_STATUS__CLEAN | + PPN_OPERATION_STATUS__ERROR)) + { + // 0x49 indicates channel not updateable + WMR_PRINT(ERROR, "Channel doesn't support firmware updates - skipping\n"); + ret = FIL_UNSUPPORTED_ERROR; + } + else + { + WMR_PRINT(ERROR, "Unexpected status 0x%02x on firmware chunk %d\n", + operation_status, chunk); + ret = FIL_CRITICAL_ERROR; + } + + h2fmi_send_cmd(fmi, NAND_CMD__GET_NEXT_OPERATION_STATUS); + + return ret; +} + + +Int32 h2fmi_ppn_fw_update(h2fmi_t *fmi, + h2fmi_ce_t ce, + struct dma_segment *sgl, + UInt32 fw_size, + h2fmi_ppn_fw_type fw_type) +{ + UInt32 start_signature = PPN_FW_START_SIGNATURE; + UInt32 end_signature = PPN_FW_END_SIGNATURE; + UInt32 chunk = 0; + UInt32 max_chunk_size = PPN_PERFECT_PAGE_SIZE; + Int32 ret = FIL_SUCCESS; + UInt16 feature; + UInt8 operStat = 0; + + if (fw_type == ppnFwTypeFw) + { + feature = PPN_FEATURE__FW_UPDATE; + } + else if (fw_type == ppnFwTypeFwa) + { + feature = PPN_FEATURE__FWA_UPDATE; + } + else + { + WMR_PANIC("Invalid firmware type"); + } + + h2fmi_reset(fmi); + + h2fmi_set_if_ctrl(fmi, (FMC_IF_CTRL__REB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__REB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__DCCYCLE(0))); + + //rdar://problem/11286520 Allow timeout on FW update for channel 1 +#if !APPLICATION_EMBEDDEDIOP + if (fmi->bus_id != 0) + { + fmi->h2fmi_ppn_panic_on_status_timeout = FALSE32; + } +#endif + + if (FIL_SUCCESS != h2fmi_ppn_set_features(fmi, ce, feature, (UInt8 *)&start_signature, 4, FALSE32, &operStat)) + { + if (operStat == (PPN_OPERATION_STATUS__READY | PPN_OPERATION_STATUS__CLEAN | PPN_OPERATION_STATUS__ERROR)) + { + WMR_PRINT(ERROR, "CH %d, CE %d doesn't support entering firmware updates!\n", fmi->bus_id, ce); + +#if !APPLICATION_EMBEDDEDIOP + fmi->h2fmi_ppn_panic_on_status_timeout = TRUE32; +#endif + return FIL_UNSUPPORTED_ERROR; + } + else + { + WMR_PRINT(ERROR, "Error entering PPN firmware update mode\n"); +#if !APPLICATION_EMBEDDEDIOP + if (fmi->h2fmi_ppn_panic_on_status_timeout == FALSE32){ + fmi->h2fmi_ppn_panic_on_status_timeout = TRUE32; + return FIL_UNSUPPORTED_ERROR; + } +#endif + return FIL_CRITICAL_ERROR; + } + } +#if !APPLICATION_EMBEDDEDIOP + else + { + fmi->h2fmi_ppn_panic_on_status_timeout = TRUE32; + } +#endif + + h2fmi_ppn_switch_ce(fmi, ce); + + // We may be coming in here from a corrupted image, etc. Go as slow + // as possible through the update. + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_data_chan(fmi), + sgl, + h2fmi_dma_data_fifo(fmi), + fw_size, + sizeof(UInt32), + 1, + NULL); + + while( fw_size ) + { + const UInt32 chunk_len = WMR_MIN(max_chunk_size, fw_size); + Int32 status; + + status = h2fmi_ppn_update_fw_chunk(fmi, chunk, chunk_len); + if (status != FIL_SUCCESS) + { + ret = status; + goto done; + } + chunk++; + fw_size -= chunk_len; + } + + h2fmi_ppn_disable_all_ces(fmi); + + operStat = 0; + if (FIL_SUCCESS != h2fmi_ppn_set_features(fmi, ce, feature, (UInt8 *)&end_signature, 4, FALSE32, &operStat)) + { + if (operStat == (PPN_OPERATION_STATUS__READY | PPN_OPERATION_STATUS__CLEAN | PPN_OPERATION_STATUS__ERROR)) + { + WMR_PRINT(ERROR, "CH %d, CE %d doesn't support exiting firmware updates!\n", fmi->bus_id, ce); + ret = FIL_UNSUPPORTED_ERROR; + } + else + { + WMR_PRINT(ERROR, "Error exiting PPN firmware update mode\n"); + ret = FIL_CRITICAL_ERROR; + } + } + + done: + h2fmi_ppn_disable_all_ces(fmi); + + if (ret == FIL_SUCCESS) + { + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + WMR_PRINT(ERROR, "Timeout waiting for CDMA channel %d to complete\n", + h2fmi_dma_data_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + ret = FIL_CRITICAL_ERROR; + } + } + else + { + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + } + + return ret; +} + + +void h2fmi_ppn_poweron(h2fmi_t *fmi) +{ + // Enable Vcc + // Enable VccQ +} + +void h2fmi_ppn_poweroff(h2fmi_t *fmi) +{ + // Will we ever even do this? + WMR_PANIC("Called h2fmi_ppn_poweroff"); +} + +void h2fmi_ppn_set_power_low_power(h2fmi_t *fmi) +{ + // Only valid from NORMAL state - maybe STANDBY? + // From ReadyForReset, we should come in through h2fmi_ppn_reset() + + // SetFeatures(PowerState, Low Power) +} + +void h2fmi_ppn_set_power_standby(h2fmi_t *fmi) +{ + // Disable Vcc, leave VccQ enabled +} + +static void h2fmi_send_cmd(h2fmi_t *fmi, UInt8 cmd) +{ + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(cmd)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + h2fmi_busy_wait(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE, FMC_STATUS__CMD1DONE); + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE); +} + +static void h2fmi_send_cmd_addr(h2fmi_t *fmi, UInt8 cmd, UInt8 *address, UInt32 address_bytes) +{ + const UInt32 cmd1_addr_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD1DONE); + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(cmd)); + h2fmi_wr(fmi, FMC_ADDR0, (FMC_ADDR0__SEQ0(address[0]) | + FMC_ADDR0__SEQ1(address[1]) | + FMC_ADDR0__SEQ2(address[2]) | + FMC_ADDR0__SEQ3(address[3]))); + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(address_bytes - 1)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD1_MODE)); + h2fmi_busy_wait(fmi, FMC_STATUS, cmd1_addr_done, cmd1_addr_done); + h2fmi_wr(fmi, FMC_STATUS, cmd1_addr_done); +} + +static void h2fmi_send_cmd_addr_cmd(h2fmi_t *fmi, UInt8 cmd1, UInt8 cmd2, const UInt8 *address, UInt32 address_bytes) +{ + const UInt32 cmd1_cmd2_addr_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD1DONE | + FMC_STATUS__CMD2DONE); + + h2fmi_wr(fmi, FMC_CMD, (FMC_CMD__CMD1(cmd1) | + FMC_CMD__CMD2(cmd2))); + h2fmi_wr(fmi, FMC_ADDR0, (FMC_ADDR0__SEQ0(address[0]) | + FMC_ADDR0__SEQ1(address[1]) | + FMC_ADDR0__SEQ2(address[2]) | + FMC_ADDR0__SEQ3(address[3]))); + + if (address_bytes > 4) + { + h2fmi_wr(fmi, FMC_ADDR1, (FMC_ADDR1__SEQ4(address[4]) | + FMC_ADDR1__SEQ5(address[5]) | + FMC_ADDR1__SEQ6(address[6]) | + FMC_ADDR1__SEQ7(address[7]))); + } + + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(address_bytes - 1)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD1_MODE | + FMC_RW_CTRL__CMD2_MODE)); + + h2fmi_busy_wait(fmi, FMC_STATUS, cmd1_cmd2_addr_done, cmd1_cmd2_addr_done); + h2fmi_wr(fmi, FMC_STATUS, cmd1_cmd2_addr_done); +} + +static void h2fmi_ppn_read_serial_output(h2fmi_t *fmi, UInt8 *buf, UInt32 len) +{ + UInt32 fullSectors; + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_send_cmd(fmi, NAND_CMD__READ_SERIAL_OUTPUT); + + fullSectors = len / H2FMI_BYTES_PER_SECTOR; + + if (fullSectors > 0) + { + h2fmi_ppn_set_format(fmi, H2FMI_BYTES_PER_SECTOR, fullSectors, FALSE32); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + while(fullSectors) + { + h2fmi_pio_read_sector(fmi, buf, H2FMI_BYTES_PER_SECTOR); + buf += H2FMI_BYTES_PER_SECTOR; + fullSectors--; + len -= H2FMI_BYTES_PER_SECTOR; + } + } + + if (len > 0) + { + h2fmi_ppn_set_format(fmi, len, 1, FALSE32); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_pio_read_sector(fmi, buf, len); + } + +} + +static BOOL32 h2fmi_get_nand_status(h2fmi_t *fmi, UInt8 *status) +{ + BOOL32 ret; + + h2fmi_prepare_for_fmi_interrupt(fmi, FMI_INT_EN__FMC_NSRBBDONE); + + h2fmi_set_if_ctrl(fmi, (~FMC_IF_CTRL__RBBEN & h2fmi_rd(fmi, FMC_IF_CTRL))); + h2fmi_wr(fmi, FMC_RBB_CONFIG, (FMC_RBB_CONFIG__POL(0x40) | + FMC_RBB_CONFIG__POS(0x40))); + h2fmi_wr(fmi, FMC_DATANUM, FMC_DATANUM__NUM(0)); + h2fmi_wr(fmi, FMC_INTMASK, FMC_INTMASK__NSRBBDONE); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__REBHOLD | FMC_RW_CTRL__RD_MODE)); + + ret = h2fmi_wait_for_fmi_interrupt(fmi, FMI_INT_PEND__FMC_NSRBBDONE); + *status = (UInt8)h2fmi_rd(fmi, FMC_NAND_STATUS); + + if (!ret) + { + +//rdar://problem/11286520 Allow timeout on FW update for channel 1 +#if !APPLICATION_EMBEDDEDIOP + if (!fmi->h2fmi_ppn_panic_on_status_timeout) + { + return FALSE32; + } +#endif + // Don't panic in iBSS - we want to at least get to a prompt on errors. + WMR_PANIC("Timeout waiting for NAND status: 0x%02x\n", *status); + } + else if (*status & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + fmi->ppn->general_error = TRUE32; + } + + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + return TRUE32; +} + +BOOL32 h2fmi_ppn_get_next_operation_status(h2fmi_t *fmi, UInt8 *operation_status) +{ + BOOL32 ret; + const UInt32 cmd1_cmd2_done = (FMC_STATUS__CMD1DONE | + FMC_STATUS__CMD2DONE); + + h2fmi_wr(fmi, FMC_CMD, (FMC_CMD__CMD1(NAND_CMD__GET_NEXT_OPERATION_STATUS) | + FMC_CMD__CMD2(NAND_CMD__OPERATION_STATUS))); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__CMD1_MODE | + FMC_RW_CTRL__CMD2_MODE)); + h2fmi_busy_wait(fmi, FMC_STATUS, cmd1_cmd2_done, cmd1_cmd2_done); + h2fmi_wr(fmi, FMC_STATUS, cmd1_cmd2_done); + + ret = h2fmi_get_nand_status(fmi, operation_status); + if (ret && (*operation_status & PPN_OPERATION_STATUS__GENERAL_ERROR)) + { + fmi->ppn->general_error = TRUE32; + fmi->ppn->general_error_ce = fmi->activeCe; + } + return ret; +} + +BOOL32 h2fmi_ppn_get_next_operation_status_with_addr(h2fmi_t *fmi, UInt8 *addr, UInt8 *operation_status) +{ + h2fmi_send_cmd_addr_cmd(fmi, + NAND_CMD__GET_NEXT_OPERATION_STATUS, + NAND_CMD__OPERATION_STATUS, + addr, + 3); + return h2fmi_get_nand_status(fmi, operation_status); +} + + +BOOL32 h2fmi_ppn_get_controller_status(h2fmi_t *fmi, UInt8 *controller_status) +{ + BOOL32 ret; + + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__CONTROLLER_STATUS)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + h2fmi_busy_wait(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE, FMC_STATUS__CMD1DONE); + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE); + + ret = h2fmi_get_nand_status(fmi, controller_status); + + return ret; +} + +#if 0 +#define DUMP_VAR(variable) _WMR_PRINT("%s : %u\n", #variable, (UInt32)(variable)) +#else +#define DUMP_VAR(variable) +#endif +BOOL32 h2fmi_ppn_get_device_params(h2fmi_t *fmi, h2fmi_ce_t ce, h2fmi_ppn_device_params_t *params) +{ + UInt8 address[3] = {0, 0, 0}; + UInt8 operation_status = 0; + BOOL32 result = TRUE32; + + WMR_ASSERT(fmi->activeCe == (h2fmi_ce_t)~0); + + h2fmi_set_if_ctrl(fmi, (FMC_IF_CTRL__REB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__REB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__WEB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | + FMC_IF_CTRL__DCCYCLE(0))); + + h2fmi_ppn_switch_ce(fmi, ce); + + h2fmi_send_cmd_addr_cmd(fmi, + NAND_CMD__READ_DEVICE_PARAMETERS, + NAND_CMD__READ_DEVICE_PARAMETERS_CONFIRM, + address, + 1); + + if (!h2fmi_ppn_get_next_operation_status(fmi, &operation_status)) + { + WMR_PRINT(ERROR, "Timeout waiting for operation status\n"); + result = FALSE32; + } + + if (operation_status != 0x40) + { + WMR_PRINT(ERROR, "Invalid operation status reading PPN device parameters: 0x%02x\n", + operation_status); + result = FALSE32; + } + + if (result) + { + h2fmi_ppn_read_serial_output(fmi, (UInt8 *)params, 512); + h2fmi_send_cmd(fmi, NAND_CMD__GET_NEXT_OPERATION_STATUS); + } + + h2fmi_ppn_disable_all_ces(fmi); + + if (result) + { + DUMP_VAR(params->caus_per_channel); + DUMP_VAR(params->cau_bits); + DUMP_VAR(params->blocks_per_cau); + DUMP_VAR(params->block_bits); + DUMP_VAR(params->pages_per_block); + DUMP_VAR(params->pages_per_block_slc); + DUMP_VAR(params->page_address_bits); + DUMP_VAR(params->address_bits_bits_per_cell); + DUMP_VAR(params->default_bits_per_cell); + DUMP_VAR(params->page_size); + DUMP_VAR(params->dies_per_channel); + + DUMP_VAR(params->tRC); + DUMP_VAR(params->tREA); + DUMP_VAR(params->tREH); + DUMP_VAR(params->tRHOH); + DUMP_VAR(params->tRHZ); + DUMP_VAR(params->tRLOH); + DUMP_VAR(params->tRP); + DUMP_VAR(params->tWC); + DUMP_VAR(params->tWH); + DUMP_VAR(params->tWP); + + DUMP_VAR(params->read_queue_size); + DUMP_VAR(params->program_queue_size); + DUMP_VAR(params->erase_queue_size); + DUMP_VAR(params->prep_function_buffer_size); + + DUMP_VAR(params->tRST_ms); + DUMP_VAR(params->tPURST_ms); + DUMP_VAR(params->tSCE_ms); + DUMP_VAR(params->tCERDY_us); + + DUMP_VAR(params->cau_per_channel2); + DUMP_VAR(params->dies_per_channel2); + DUMP_VAR(params->ddr_tRC); + DUMP_VAR(params->ddr_tREH); + DUMP_VAR(params->ddr_tRP); + DUMP_VAR(params->tDQSL_ps); + DUMP_VAR(params->tDQSH_ps); + DUMP_VAR(params->tDSC_ps); + DUMP_VAR(params->tDQSRE_ps); + DUMP_VAR(params->tDQSQ_ps); + DUMP_VAR(params->tDVW_ps); + DUMP_VAR(params->max_interface_speed); + + if (fmi->ppn->spec_version < PPN_VERSION_1_5_0) + { + // PPN 1.0.x device + fmi->ppn->bytes_per_row_address = (params->cau_bits + params->block_bits + params->page_address_bits + + params->address_bits_bits_per_cell + 8 - 1) / 8; + fmi->ppn->bytes_per_full_address = 7; + WMR_ASSERT(sizeof(h2fmi_ppn_failure_info_ppn1_0_t) == PPN_1_0_FAILURE_INFO_EXPCT_LEN); + } + else + { + fmi->ppn->bytes_per_row_address = 4; + fmi->ppn->bytes_per_full_address = 8; + WMR_ASSERT(sizeof(h2fmi_ppn_failure_info_ppn1_5_t) == PPN_1_5_FAILURE_INFO_EXPCT_LEN); + } + + result = _validate_device_parameters(fmi->ppn); + } + + h2fmi_set_if_ctrl(fmi, fmi->if_ctrl); + return result; +} + +BOOL32 h2fmi_ppn_init_channel(h2fmi_t *fmi, + BOOL32 debug_flags_valid, + UInt32 debug_flags, + BOOL32 vs_debug_flags_valid, + UInt32 vs_debug_flags, + BOOL32 allow_saving_debug_data, + UInt32 spec_version) +{ + h2fmi_ppn_t *ppn; + h2fmi_ce_t ce; + +#if !APPLICATION_EMBEDDEDIOP + fmi->h2fmi_ppn_panic_on_status_timeout = TRUE32; +#endif + + if (!fmi->ppn) + { + fmi->ppn = (h2fmi_ppn_t *)WMR_MALLOC(sizeof(h2fmi_ppn_t)); + for (ce = 0 ; ce < PPN_MAX_CES_PER_BUS ; ce++) + { + fmi->ppn->prep_buffer[ce] = (UInt32*)WMR_MALLOC(PPN_MAX_PAGES_PER_CE * sizeof(*fmi->ppn->prep_buffer)); + } + //initialize error list for ppn + fmi->error_list = (UInt32 *)WMR_MALLOC(PPN_ERROR_LIST_SIZE); + WMR_ASSERT(fmi->error_list != NULL); + } + ppn = fmi->ppn; + + ppn->debug_flags_valid = debug_flags_valid; + ppn->debug_flags = debug_flags; + ppn->vs_debug_flags_valid = vs_debug_flags_valid; + ppn->vs_debug_flags = vs_debug_flags; + ppn->allow_saving_debug_data = allow_saving_debug_data; + ppn->spec_version = spec_version; + +#if FMISS_ENABLED + fmiss_init_sequences(fmi); +#endif /* FMISS_ENABLED */ + + return TRUE32; +} + +// validate the value argument is between (inclusive) min and max +#define _validate_item(value_param, min_param, max_param) \ + { \ + if (((value_param) < (min_param)) || ((value_param) > (max_param))) \ + { \ + WMR_PRINT(ERROR, "failure with %s = %d\n", #value_param , value_param); \ + return FALSE32; \ + } \ + } + + +BOOL32 _validate_device_parameters(h2fmi_ppn_t *ppn) +{ + // check the device params + _validate_item(ppn->device_params.caus_per_channel, 1, 64); + _validate_item(ppn->device_params.cau_bits, 1, 7); + _validate_item(ppn->device_params.blocks_per_cau, 1024, 8500); + _validate_item(ppn->device_params.block_bits, 10, 15); + _validate_item(ppn->device_params.pages_per_block, 64, 512); + _validate_item(ppn->device_params.pages_per_block_slc, 64, 256); + _validate_item(ppn->device_params.page_address_bits, 5, 9); + _validate_item(ppn->device_params.address_bits_bits_per_cell, 1, 2); + _validate_item(ppn->device_params.default_bits_per_cell, 1, 4); + _validate_item(ppn->device_params.page_size, (8 * 1028), (16 * 1028)); // page size includes meta area (4 bytes per KB) + _validate_item(ppn->device_params.tRC, 1, 254); + _validate_item(ppn->device_params.tREA, 1, 254); + _validate_item(ppn->device_params.tREH, 1, 254); + _validate_item(ppn->device_params.tRHOH, 1, 254); + _validate_item(ppn->device_params.tRHZ, 1, 254); + _validate_item(ppn->device_params.tRLOH, 1, 254); + _validate_item(ppn->device_params.tRP, 1, 254); + _validate_item(ppn->device_params.tWC, 1, 254); + _validate_item(ppn->device_params.tWH, 1, 254); + _validate_item(ppn->device_params.tWP, 1, 254); + _validate_item(ppn->device_params.read_queue_size, 4, (8 * 1024)); + _validate_item(ppn->device_params.program_queue_size, 2, (8 * 1024)); + _validate_item(ppn->device_params.erase_queue_size, 4, (8 * 1024)); + _validate_item(ppn->device_params.prep_function_buffer_size, 4, (8 * 1024)); + _validate_item(ppn->device_params.tRST_ms, 1, 50); + _validate_item(ppn->device_params.tPURST_ms, 1, 50); + _validate_item(ppn->device_params.tSCE_ms, 1, 200); + _validate_item(ppn->device_params.tCERDY_us, 1, 200); + _validate_item(ppn->bytes_per_row_address, 3, 4); + _validate_item(ppn->bytes_per_full_address, 7, 8); + + if ((ppn->device_params.blocks_per_cau % 8) != 0) + { + WMR_PRINT(ERROR, "%d blocks per cau - rdar://8426007\n", ppn->device_params.blocks_per_cau); + return FALSE32; + } + + if ((UInt32)(1 << ppn->device_params.page_address_bits) != ppn->device_params.pages_per_block) + { + WMR_PRINT(ERROR, "pages_per_block:%d != 1 << page_address_bits:%d\n", + ppn->device_params.pages_per_block, ppn->device_params.page_address_bits); + return FALSE32; + } + + return TRUE32; +} + +BOOL32 h2fmi_ppn_post_rst_pre_pwrstate_operations(h2fmi_t* fmi) +{ + BOOL32 result = TRUE32; + UInt32 ce_idx; + + for(ce_idx = 0; ce_idx < H2FMI_MAX_CE_TOTAL; ce_idx++) + { + if (fmi->valid_ces & (1 << ce_idx)) + { + h2fmi_ppn_configure_debug_data(fmi, ce_idx); + +#if SUPPORT_TOGGLE_NAND + if (fmi->is_toggle_system) + { + if (!h2fmi_ppn15_enable_optional_signals(fmi, ce_idx)) + { + result = FALSE32; + } + } +#endif // SUPPORT_TOGGLE_NAND + + } + } + + return result; +} + +BOOL32 h2fmi_ppn_set_channel_power_state(h2fmi_t *fmi, UInt32 ps_tran) +{ + h2fmi_ce_t ce; + Int32 result; + UInt32 ps; + +#if SUPPORT_TOGGLE_NAND + if (!fmi->is_toggle_system) + { +#endif + WMR_ASSERT(ps_tran == PPN_PS_TRANS_LOW_POWER_TO_ASYNC); +#if SUPPORT_TOGGLE_NAND + } +#endif + + ps = PS_TRANS_GET_TO(ps_tran); + + for( ce = 0; ce < H2FMI_MAX_CE_TOTAL; ce++) + { + if (fmi->valid_ces & (1 << ce)) + { + WMR_PRINT(MISC, "Setting PPN Power State: 0x%x\n", ps); + result = h2fmi_ppn_set_features(fmi, ce, PPN_FEATURE__POWER_STATE, (UInt8 *)&ps, 1, FALSE32, NULL); + +#if APPLICATION_EMBEDDEDIOP + WMR_ASSERT(result == FIL_SUCCESS); +#endif + if (result != FIL_SUCCESS) + { + WMR_PRINT(ERROR, "failed setting power state on ce %d\n", ce); + return FALSE32; + } + } + } + +#if !H2FMI_IOP + if (PPN_FEATURE__POWER_STATE__LOW_POWER == ps) + { + fmi->if_ctrl = H2FMI_IF_CTRL_LOW_POWER; + } + else + { + fmi->if_ctrl = fmi->if_ctrl_normal; + } + restoreTimingRegs(fmi); +#endif // !H2FMI_IOP + + return TRUE32; +} + +#if !APPLICATION_EMBEDDEDIOP +void h2fmi_ppn_fill_nandinfo(h2fmi_t *fmi, NandInfo *nandInfo, NandRequiredTimings *requiredTiming) +{ + h2fmi_ppn_t *ppn = fmi->ppn; + h2fmi_ppn_device_params_t *params = &ppn->device_params; + NandPpn *nandPpn = &ppn->nandPpn; + + nandPpn->blocksPerCau = params->blocks_per_cau; + nandPpn->causPerCe = params->caus_per_channel; + nandPpn->slcPagesPerBlock = params->pages_per_block_slc; + nandPpn->mlcPagesPerBlock = params->pages_per_block; + nandPpn->matchOddEvenCaus = params->block_pairing_scheme; + nandPpn->bitsPerCau = params->cau_bits; + nandPpn->bitsPerPage = params->page_address_bits; + nandPpn->bitsPerBlock = params->block_bits; + nandPpn->maxTransactionSize = params->prep_function_buffer_size; + nandPpn->specVersion = ppn->spec_version; + + fmi->blocks_per_ce = params->blocks_per_cau * params->caus_per_channel; + fmi->banks_per_ce = params->caus_per_channel; // Banks are CAUs in PPN + fmi->bytes_per_page = 1 << WMR_LOG2(params->page_size); + fmi->sectors_per_page = fmi->bytes_per_page / H2FMI_BYTES_PER_SECTOR; + fmi->pages_per_block = params->pages_per_block; + fmi->bytes_per_spare = params->page_size - fmi->bytes_per_page; + fmi->dies_per_cs = params->dies_per_channel; + + // Cache page config registers + fmi->correctable_bits = 30; // only used for Bonfire reporting + fmi->refresh_threshold_bits = 0; + + WMR_MEMSET(requiredTiming, 0, sizeof(*requiredTiming)); + + requiredTiming->clock_hz = WMR_BUS_FREQ_HZ(); +#if FMI_USE_WRITE_CYCLE_BALANCING + requiredTiming->balance_write_cycle = TRUE32; +#endif + + requiredTiming->soc_tx_prop_ns = FMI_TX_PROP_DELAY_NS; + requiredTiming->soc_rx_prop_ns = FMI_RX_PROP_DELAY_NS; + + requiredTiming->tRC_ns = params->tRC; + requiredTiming->tRP_ns = params->tRP; + requiredTiming->tREH_ns = params->tREH; + requiredTiming->tREA_ns = params->tREA; + requiredTiming->tRHOH_ns = params->tRHOH; + requiredTiming->tRLOH_ns = params->tRLOH; + + requiredTiming->tWC_ns = params->tWC; + requiredTiming->tWP_ns = params->tWP; + requiredTiming->tWH_ns = params->tWH; + +#if SUPPORT_TOGGLE_NAND + if (fmi->is_toggle_system) + { + requiredTiming->ddr_tRC_ps = params->ddr_tRC * PS_PER_NS; + requiredTiming->ddr_tREH_ps = params->ddr_tREH * PS_PER_NS; + requiredTiming->ddr_tRP_ps = params->ddr_tRP * PS_PER_NS; + + requiredTiming->tDSC_ps = params->tDSC_ps; + requiredTiming->tDQSH_ps = params->tDQSH_ps; + requiredTiming->tDQSL_ps = params->tDQSL_ps; + } +#endif + + fmi->ppn->boardSupport.vsType = FIL_VS_UNKNOWN; + nandInfo->boardSupport = &fmi->ppn->boardSupport; + + nandInfo->format = getPPNFormat(); + + nandInfo->geometry = &fmi->ppn->geometry; + + fmi->ppn->geometry.blocksPerCS = fmi->blocks_per_ce; + fmi->ppn->geometry.pagesPerBlock = fmi->pages_per_block; + fmi->ppn->geometry.dataBytesPerPage = fmi->bytes_per_page; + fmi->ppn->geometry.spareBytesPerPage = fmi->bytes_per_spare; + fmi->ppn->geometry.eccPer512Bytes = 0; + fmi->ppn->geometry.initialBBType = INIT_BBT_PPN; + fmi->ppn->geometry.diesPerCS = fmi->dies_per_cs; + +} +#endif /* !APPLICATION_EMBEDDEDIOP */ + +UInt32 h2fmi_ppn_calculate_fmi_config(h2fmi_t *fmi) +{ + UInt32 fmi_config = FMI_CONFIG__ECC_CORRECTABLE_BITS(0) | + FMI_CONFIG__DMA_BURST(WMR_LOG2(H2FMI_DMA_BURST_CYCLES)); + +#if FMI_VERSION >= 4 + fmi_config |= FMI_CONFIG__META_DMA_BURST__4_CYCLES | + FMI_CONFIG__META_DMA_BURST__4_BYTES; +#endif // FMI_VERSION >= 4 + + return fmi_config; +} + +UInt32 h2fmi_ppn_calculate_fmi_data_size(h2fmi_t *fmi) +{ + return (FMI_DATA_SIZE__META_BYTES_PER_SECTOR( fmi->valid_bytes_per_meta) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE( fmi->valid_bytes_per_meta) | + FMI_DATA_SIZE__BYTES_PER_SECTOR( H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__SECTORS_PER_PAGE( fmi->sectors_per_page)); +} + +static BOOL32 h2fmi_ppn_switch_ce(h2fmi_t *fmi, h2fmi_ce_t ce) +{ + if (fmi->activeCe != ce) + { + h2fmi_fmc_disable_all_ces(fmi); + h2fmi_fmc_enable_ce(fmi, ce); + fmi->activeCe = ce; + return TRUE32; + } + + return FALSE32; +} + +static void h2fmi_ppn_disable_all_ces(h2fmi_t *fmi) +{ + h2fmi_fmc_disable_all_ces(fmi); + fmi->activeCe = (h2fmi_ce_t)~0; +} + +static void h2fmi_prepare_for_fmi_interrupt(h2fmi_t *fmi, UInt32 condition) +{ + h2fmi_clear_interrupts_and_reset_masks(fmi); +#if H2FMI_WAIT_USING_ISR + h2fmi_wr(fmi, FMI_INT_EN, condition); +#endif /* H2FMI_WAIT_USING_ISR */ +} + +static BOOL32 h2fmi_wait_for_fmi_interrupt(h2fmi_t *fmi, UInt32 condition) +{ +#if H2FMI_WAIT_USING_ISR + if (!event_wait_timeout(&fmi->isr_event, H2FMI_PAGE_TIMEOUT_MICROS) || + !(fmi->isr_condition & condition)) + { + return FALSE32; + } + else + { + return TRUE32; + } +#else + BOOL32 ret; + + ret = h2fmi_wait_done(fmi, FMI_INT_PEND, condition, condition); + h2fmi_wr(fmi, FMI_INT_PEND, condition); + return ret; +#endif /* H2FMI_WAIT_USING_ISR */ +} + +#if SUPPORT_TOGGLE_NAND +BOOL32 h2fmi_ppn15_get_temperature(h2fmi_t *fmi, h2fmi_ce_t ce, Int16 *temperature) +{ + UInt8 status; + + if (!h2fmi_ppn_get_feature(fmi, ce, PPN_FEATURE__GET_DEVICE_TEMPERATURE, (UInt8*)temperature, PPN_FEATURE_LENGTH_TEMPERATURE, &status)) + { + WMR_PRINT(ERROR, "Get Temperature failed FMI %d CE %d, Status: 0x%x\n", fmi->bus_id, ce, status); + return FALSE32; + } + + *temperature -= 273; // convert to Celsius + + return TRUE32; +} + +BOOL32 h2fmi_ppn15_enable_optional_signals(h2fmi_t *fmi, h2fmi_ce_t ce) +{ + const UInt32 enable = 1; + BOOL32 ret = TRUE32; + + if (fmi->useDiffDQS) + { + WMR_PRINT(ALWAYS, "Enabling Diff DQS on CE %d\n", ce); + if (FIL_SUCCESS != h2fmi_ppn_set_features(fmi, ce, PPN_FEATURE__DQS_COMPLEMENT_ENABLE, (UInt8 *)&enable, PPN_FEATURE_LENGTH_DEFAULT, FALSE32, NULL)) + { + WMR_PRINT(ERROR, "Enabling Diff DQS failed on CE %d\n", ce); + ret = FALSE32; + } + } + + if (fmi->useDiffRE) + { + WMR_PRINT(ALWAYS, "Enabling Diff RE on CE %d\n", ce); + if (FIL_SUCCESS != h2fmi_ppn_set_features(fmi, ce, PPN_FEATURE__RE_COMPLEMENT_ENABLE, (UInt8 *)&enable, PPN_FEATURE_LENGTH_DEFAULT, FALSE32, NULL)) + { + WMR_PRINT(ERROR, "Enabling Diff RE failed on CE %d\n", ce); + ret = FALSE32; + } + } + + if (fmi->useVREF) + { + Int32 ret; + WMR_PRINT(ALWAYS, "Enabling VREF on CE %d\n", ce); + if(FIL_SUCCESS != (ret = h2fmi_ppn_set_features(fmi, ce, PPN_FEATURE__VREF_ENABLE, (UInt8 *)&enable, PPN_FEATURE_LENGTH_DEFAULT, (fmi->bus_id == 1) ? TRUE32 : FALSE32, NULL))) + { + if(!((fmi->bus_id == 1) && (ret == FIL_UNSUPPORTED_ERROR))) + { + WMR_PRINT(ERROR, "Enabling VREF failed on CE %d\n", ce); + ret = FALSE32; + } + } + } + + return ret; +} +#endif + +Int32 h2fmi_ppn_configure_debug_data(h2fmi_t *fmi, + h2fmi_ce_t ce) +{ + if (fmi->ppn->allow_saving_debug_data) + { + const UInt32 debugInfo = PPN_FEATURE__ALLOW_SAVING_DEBUG_DATA_ENABLE; + + h2fmi_ppn_set_features(fmi, + ce, + PPN_FEATURE__ALLOW_SAVING_DEBUG_DATA, + (UInt8 *)&debugInfo, + PPN_FEATURE_LENGTH_DEFAULT, + FALSE32, + NULL); + } + + if (fmi->ppn->debug_flags_valid) + { + WMR_PRINT(ALWAYS, "Enabling PPN generic debug flags 0x%08x on CE %d\n", + fmi->ppn->debug_flags, ce); + + h2fmi_ppn_set_features(fmi, + ce, + PPN_FEATURE__SET_DEBUG_DATA_GENERIC_CONFIG, + (UInt8*) &fmi->ppn->debug_flags, + PPN_FEATURE_LENGTH_DEFAULT, + FALSE32, + NULL); + } + + if (fmi->ppn->vs_debug_flags_valid) + { + WMR_PRINT(ALWAYS, "Enabling PPN vendor-specific debug flags 0x%08x on CE %d\n", + fmi->ppn->vs_debug_flags, ce); + + h2fmi_ppn_set_features(fmi, + ce, + PPN_FEATURE__SET_DEBUG_DATA_VENDOR_SPECIFIC, + (UInt8 *)&fmi->ppn->vs_debug_flags, + PPN_FEATURE_LENGTH_DEFAULT, + FALSE32, + NULL); + } + + return FIL_SUCCESS; +} + +void h2fmi_ppn_dma_debug_data_payload(h2fmi_t *fmi, + h2fmi_ce_t ce, + UInt32 page, + UInt32 pageCount, + struct dma_segment *sgl, + BOOL32 waitFortGDD) +{ + UInt32 i; + UInt8 status = 0; + + h2fmi_reset(fmi); + + h2fmi_ppn_switch_ce(fmi, ce); + +/* Sometimes Hynix PPN parts need a reset (particularly when dealing with timeouts), but + generally we shouldn't need to. + + h2fmi_ppn_reset(fmi); + + h2fmi_send_cmd(fmi, NAND_CMD__LOW_POWER_READ_STATUS); + h2fmi_get_nand_status(fmi, &status); + WMR_ASSERT(status == (PPN_LOW_POWER_STATUS__WRITE_PROTECT_BAR | PPN_LOW_POWER_STATUS__READY)); +*/ + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + sgl, + h2fmi_dma_data_fifo(fmi), + pageCount * PPN_PERFECT_PAGE_SIZE, + sizeof(UInt32), + 32, + NULL); + + for (i = page; i < page + pageCount; i++) + { + h2fmi_send_cmd_addr_cmd(fmi, + NAND_CMD__GET_DEBUG_DATA, + NAND_CMD__SET_GET_FEATURES_CONFIRM, + (UInt8 *)&i, + fmi->ppn->bytes_per_row_address); + + if (waitFortGDD) + { + WMR_SLEEP_US(fmi->ppn->spec_version < PPN_VERSION_1_5_0 ? PPN_tGDD_1_0_US : PPN_tGDD_1_5_US); + } + + h2fmi_send_cmd(fmi, NAND_CMD__OPERATION_STATUS); + if (!h2fmi_get_nand_status(fmi, &status)) + { + WMR_PANIC("Timeout getting nand status"); + } + + h2fmi_send_cmd(fmi, NAND_CMD__READ_SERIAL_OUTPUT); + + h2fmi_ppn_set_format(fmi, PPN_PERFECT_FMI_SECTOR_SIZE, PPN_PERFECT_FMI_SECTORS_PER_PERFECT_PAGE, FALSE32); + h2fmi_ppn_start_fmi_read_and_wait(fmi); + } + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + WMR_PRINT(ERROR, "Timeout waiting for CDMA channel %d to complete\n", + h2fmi_dma_data_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + } + + h2fmi_ppn_disable_all_ces(fmi); +} + +void h2fmi_ppn_force_geb_address(h2fmi_t *fmi, h2fmi_ce_t ce, PageAddressType addr) +{ + h2fmi_reset(fmi); + + WMR_PRINT(ERROR, "Sending SET_DEBUG_DATA to collect page on bus %d ce %d page 0x%08x\n", + fmi->bus_id, ce, addr); + h2fmi_ppn_set_debug_data(fmi, ce, PPN_SET_DEBUG_DATA__FORCE_ADDRESS, (UInt8 *)&addr, 4); + WMR_PRINT(ERROR, "Sent command to force GEB\n"); + + fmi->ppn->general_error = TRUE32; + fmi->ppn->general_error_ce = ce; +} + +void h2fmi_ppn_set_feature_list(h2fmi_t *fmi, ppn_feature_entry_t *list, UInt32 size) +{ + UInt32 i; + + for (i = 0 ; i < size ; i++) + { + ppn_feature_entry_t entry; + h2fmi_ce_t ce; + + WMR_MEMCPY(&entry, &list[i], sizeof(entry)); + + if (entry.version > fmi->ppn->spec_version) + { + continue; + } + + for (ce = 0 ; (ce < H2FMI_MAX_CE_TOTAL) && (ce <= fmi->valid_ces) ; ce++) + { + if (0 != (fmi->valid_ces & (1 << ce))) + { + Int32 result; + result = h2fmi_ppn_set_features(fmi, ce, entry.feature, (UInt8*)&entry.value, entry.bytes, TRUE32, NULL); + WMR_ASSERT((FIL_SUCCESS == result) || (FIL_UNSUPPORTED_ERROR == result)); + } + } + } +} + +#if H2FMI_PPN_VERIFY_SET_FEATURES + +static void _update_feature_shadow(h2fmi_t *fmi, UInt16 feature, UInt8 *value, UInt32 len) +{ + UInt32 i; + + for (i = 0 ; i < _ppn_feature_shadow[fmi->bus_id].count ; i++) + { + if (feature == _ppn_feature_shadow[fmi->bus_id].list[i].feature) + { + break; + } + } + + if (i >= _ppn_feature_shadow[fmi->bus_id].count) + { + WMR_ASSERT(i < NUMELEMENTS(_ppn_feature_shadow[fmi->bus_id].list)); + _ppn_feature_shadow[fmi->bus_id].list[i].feature = feature; + _ppn_feature_shadow[fmi->bus_id].count++; + } + + _ppn_feature_shadow[fmi->bus_id].list[i].length = WMR_MIN(sizeof(_ppn_feature_shadow[fmi->bus_id].list[i].value), len); + WMR_MEMCPY(&_ppn_feature_shadow[fmi->bus_id].list[i].value, value, _ppn_feature_shadow[fmi->bus_id].list[i].length); + + if (PPN_FEATURE__POWER_STATE == feature) + { + _ppn_feature_shadow[fmi->bus_id].state = 1UL << *value; + } +} + +void h2fmi_ppn_verify_feature_shadow(h2fmi_t *fmi) +{ + UInt32 ce_mask = fmi->valid_ces; + BOOL32 failed = FALSE32; + + while (0 != ce_mask) + { + const h2fmi_ce_t ce = WMR_LOG2(ce_mask); + UInt32 i; + + for (i = 0 ; i < _ppn_feature_shadow[fmi->bus_id].count ; i++) + { + UInt8 status; + UInt8 value[sizeof(_ppn_feature_shadow[fmi->bus_id].list[i].value)]; + UInt32 statesIdx; + + for (statesIdx = 0 ; statesIdx < NUMELEMENTS(_ppn_feature_states) ; statesIdx++) + { + if (_ppn_feature_states[statesIdx].feature == _ppn_feature_shadow[fmi->bus_id].list[i].feature) + { + break; + } + } + if ((statesIdx < NUMELEMENTS(_ppn_feature_states)) && + (0 == (_ppn_feature_states[statesIdx].states & _ppn_feature_shadow[fmi->bus_id].state))) + { + continue; + } + + if (!h2fmi_ppn_get_feature(fmi, ce, _ppn_feature_shadow[fmi->bus_id].list[i].feature, value, _ppn_feature_shadow[fmi->bus_id].list[i].length, &status)) + { + if ((PPN_FEAT_OPERATION_STATUS__UNSUPPORTED != status) && (PPN_FEAT_OPERATION_STATUS__UNSUPPORTED_BY_CH != status)) + { + WMR_PRINT(ERROR, "Verify set feature of 0x%04x failed for FMI %d CE %d, Status: 0x%02x\n", _ppn_feature_shadow[fmi->bus_id].list[i].feature, fmi->bus_id, ce, status); + failed = TRUE32; + } + } + else if (0 != WMR_MEMCMP(&_ppn_feature_shadow[fmi->bus_id].list[i].value, value, _ppn_feature_shadow[fmi->bus_id].list[i].length)) + { + UInt32 j; + WMR_PRINT(ERROR, "Verify set feature of 0x%04x failed for FMI %d CE %d,\n", _ppn_feature_shadow[fmi->bus_id].list[i].feature, fmi->bus_id, ce); + WMR_PRINT(ERROR, "Expected: Actual:\n"); + for (j = 0 ; j < _ppn_feature_shadow[fmi->bus_id].list[i].length ; j++) + { + UInt8 expected = ((UInt8 *)&_ppn_feature_shadow[fmi->bus_id].list[i].value)[j]; + WMR_PRINT(ERROR, "0x%02x 0x%02x\n", expected, value[j]); + } + failed = TRUE32; + } + } + + ce_mask &= ~(1UL << ce); + } + + WMR_ASSERT(!failed); +} + +void h2fmi_ppn_reset_feature_shadow(h2fmi_t *fmi) +{ + _ppn_feature_shadow[fmi->bus_id].count = 0; +} + +#endif // H2FMI_PPN_VERIFY_SET_FEATURES + +#endif //FMI_VERSION > 0 diff --git a/drivers/apple/h2fmi/H2fmi_ppn.h b/drivers/apple/h2fmi/H2fmi_ppn.h new file mode 100644 index 0000000..7f1e999 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_ppn.h @@ -0,0 +1,512 @@ +// ***************************************************************************** +// +// File: H2fmi_ppn.h +// +// Copyright (C) 2009 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** +#ifndef _H2FMI_PPN_H_ +#define _H2FMI_PPN_H_ + +#include "H2fmi_private.h" +#include "H2fmi_timing.h" +#include "PPN_FIL.h" + +#if defined(APPLICATION_IBOOT) +#include "nandid.h" +#elif WMR_BUILDING_EFI +#include "NandSpec.h" +#endif + +#define H2FMI_PPN_VERIFY_SET_FEATURES (0) +#define PPN_MAX_FEATURE_COUNT (32) + +#define NAND_CMD__MULTIPAGE_READ ((UInt8)0x07) +#define NAND_CMD__MULTIPAGE_READ_LAST ((UInt8)0x0A) +#define NAND_CMD__MULTIPAGE_READ_CONFIRM ((UInt8)0x37) +#define NAND_CMD__MULTIPAGE_PROGRAM ((UInt8)0x87) +#define NAND_CMD__MULTIPAGE_PROGRAM_LAST ((UInt8)0x8A) +#define NAND_CMD__MULTIPAGE_PROGRAM_CONFIRM ((UInt8)0x17) +#define NAND_CMD__MULTIPAGE_PREP ((UInt8)0xB0) +#define NAND_CMD__MULTIPAGE_PREP__CONFIRM ((UInt8)0xB8) +#define NAND_CMD__MULTIBLOCK_ERASE ((UInt8)0x67) +#define NAND_CMD__MULTIBLOCK_ERASE_LAST ((UInt8)0x6A) +#define NAND_CMD__MULTIBLOCK_ERASE_CONFIRM ((UInt8)0xD7) +#define NAND_CMD__LOW_POWER_READ_STATUS ((UInt8)0x70) +#define NAND_CMD__GET_NEXT_OPERATION_STATUS ((UInt8)0x77) +#define NAND_CMD__OPERATION_STATUS ((UInt8)0x7D) +#define NAND_CMD__READ_SERIAL_OUTPUT ((UInt8)0x7A) +#define NAND_CMD__CONTROLLER_STATUS ((UInt8)0x79) +#define NAND_CMD__READ_DEVICE_PARAMETERS ((UInt8)0x92) +#define NAND_CMD__READ_DEVICE_PARAMETERS_CONFIRM ((UInt8)0x97) +#define NAND_CMD__SET_FEATURES ((UInt8)0xEF) +#define NAND_CMD__GET_FEATURES ((UInt8)0xEE) +#define NAND_CMD__SET_GET_FEATURES_CONFIRM ((UInt8)0xE7) +#define NAND_CMD__SET_DEBUG_DATA ((UInt8)0xE9) +#define NAND_CMD__GET_DEBUG_DATA ((UInt8)0xE8) +#define NAND_CMD__UPDATE_FW ((UInt8)0xED) +#define NAND_CMD__PPN_STATUS_CONFIRM ((UInt8)0xED) +#define NAND_CMD__RESET ((UInt8)0xFF) + +#define PPN_FEATURE__POWER_STATE ((UInt16)0x0180) +#define PPN_FEATURE__SCRATCH_PAD ((UInt16)0x0380) +#define PPN_FEATURE__ALLOW_SAVING_DEBUG_DATA ((UInt16)0x0480) +#define PPN_FEATURE__IDLE_COUNTER ((UInt16)0x0580) +#define PPN_FEATURE__FW_UPDATE ((UInt16)0x1080) +#define PPN_FEATURE__FWA_UPDATE ((UInt16)0x1180) +#define PPN_FEATURE__DRIVE_STRENGTH ((UInt16)0x2080) +#define PPN_FEATURE__DEVICE_TIMING ((UInt16)0x2180) +#define PPN_FEATURE__PROGRAM_FAILED_PAGES ((UInt16)0x3080) +#define PPN_FEATURE__PROGRAM_RETIRED_PAGES ((UInt16)0x3180) +#define PPN_FEATURE__PROGRAM_IGNORED_PAGES ((UInt16)0x3280) +#define PPN_FEATURE__CLEAR_PROGRAM_ERROR_LISTS ((UInt16)0x3380) +#define PPN_FEATURE__DQS_COMPLEMENT_ENABLE ((UInt16)0x4080) +#define PPN_FEATURE__RE_COMPLEMENT_ENABLE ((UInt16)0x4180) +#define PPN_FEATURE__VREF_ENABLE ((UInt16)0x4280) +#define PPN_FEATURE__NUM_DIE_PROGRAM_PARALLEL ((UInt16)0x5080) +#define PPN_FEATURE__NUM_DIE_READ_PARALLEL ((UInt16)0x5180) +#define PPN_FEATURE__NUM_DIE_ERASE_PARALLEL ((UInt16)0x5280) +#define PPN_FEATURE__PHYSICAL_PAGE_SIZE ((UInt16)0x8080) +#define PPN_FEATURE__ECC_CHUNK_SIZE ((UInt16)0x8180) +#define PPN_FEATURE__ECC_CODE_SIZE ((UInt16)0x8280) +#define PPN_FEATURE__FW_VERSION ((UInt16)0x9080) +#define PPN_FEATURE__PACKAGE_ASSEMBLY_CODE ((UInt16)0xA080) +#define PPN_FEATURE__CONTROLLER_UNIQUE_ID ((UInt16)0xA180) +#define PPN_FEATURE__CONTROLLER_HW_ID ((UInt16)0xA181) +#define PPN_FEATURE__NAND_DIE_UNIQUE_ID ((UInt16)0x0082) +#define PPN_FEATURE__NAND_DIE_CHIP_ID ((UInt16)0x0083) +#define PPN_FEATURE__BAD_BLOCK_BITMAP_ARRAY ((UInt16)0x0084) +#define PPN_FEATURE__NAND_MARKETING_NAME ((UInt16)0x0085) +#define PPN_FEATURE__ENABLE_BITFLIPS_DATA_COLLECTION ((UInt16)0x0090) +#define PPN_FEATURE__ENABLE_HEALTH_MONITORING ((UInt16)0x1090) +#define PPN_FEATURE__GET_HEALTH_MONTIORING_GRADES ((UInt16)0x1190) +#define PPN_FEATURE__GET_DEVICE_TEMPERATURE ((UInt16)0x2090) +#define PPN_FEATURE__SET_DEBUG_DATA_GENERIC_CONFIG ((UInt16)0x00A0) +#define PPN_FEATURE__SET_DEBUG_DATA_VENDOR_SPECIFIC ((UInt16)0x01A0) +#define PPN_FEATURE__DELETE_DEBUG_DATA ((UInt16)0x08A0) + +// another copy lives in iop_fmi_protocol.h (changes should be made to both places) +#define PPN_FEATURE__POWER_STATE__LOW_POWER (0x1) +#define PPN_FEATURE__POWER_STATE__ASYNC (0x2) +#define PPN_FEATURE__POWER_STATE__STANDBY (0x4) +#define PPN_FEATURE__POWER_STATE__DDR (0xA) + +// Power State transition unique identifiers and accessors +// another copy lives in iop_fmi_protocol.h (changes should be made to both places) +#define PPN_PS_TRANS_LOW_POWER_TO_ASYNC PS_TRANS_SET(PPN_FEATURE__POWER_STATE__LOW_POWER, PPN_FEATURE__POWER_STATE__ASYNC) +#define PPN_PS_TRANS_STDBY_TO_ASYNC PS_TRANS_SET(PPN_FEATURE__POWER_STATE__STDBY, PPN_FEATURE__POWER_STATE__ASYNC) +#define PPN_PS_TRANS_ASYNC_TO_LOW_POWER PS_TRANS_SET(PPN_FEATURE__POWER_STATE__ASYNC, PPN_FEATURE__POWER_STATE__LOW_POWER) +#define PPN_PS_TRANS_DDR_TO_LOW_POWER PS_TRANS_SET(PPN_FEATURE__POWER_STATE__DDR, PPN_FEATURE__POWER_STATE__LOW_POWER) +#define PPN_PS_TRANS_ASYNC_TO_STDBY PS_TRANS_SET(PPN_FEATURE__POWER_STATE__ASYNC, PPN_FEATURE__POWER_STATE__STDBY) +#define PPN_PS_TRANS_DDR_TO_STDBY PS_TRANS_SET(PPN_FEATURE__POWER_STATE__DDR, PPN_FEATURE__POWER_STATE__STDBY) +#define PPN_PS_TRANS_LOW_POWER_TO_DDR PS_TRANS_SET(PPN_FEATURE__POWER_STATE__LOW_POWER, PPN_FEATURE__POWER_STATE__DDR) +#define PPN_PS_TRANS_STDBY_TO_DDR PS_TRANS_SET(PPN_FEATURE__POWER_STATE__STDBY, PPN_FEATURE__POWER_STATE__DDR) +#define PS_TRANS_SET(from, to) ((((UInt32)(from)) << 16) | ((UInt32)(to))) +#define PS_TRANS_GET_FROM(ps) ((ps) >> 16) +#define PS_TRANS_GET_TO(ps) ((ps) & 0xFFFF) + +#define PPN_FEATURE_LENGTH_ENABLE_BITFLIPS_DATA_COLLECTION 4 +#define PPN_FEATURE_LENGTH_DIE_CHIP_ID 8 +#define PPN_FEATURE_LENGTH_TEMPERATURE 2 +#define PPN_FEATURE_LENGTH_DEFAULT 4 + +#define PPN_FEATURE__ALLOW_SAVING_DEBUG_DATA_ENABLE (1) +#define PPN_FEATURE__ALLOW_SAVING_DEBUG_DATA_DISABLE (0) +#define PPN_FEATURE__DEBUG_DATA_CONFIGURATION_GEB (1 << 0) +#define PPN_FEATURE__DEBUG_DATA_CONFIGURATION_READ (1 << 1) +#define PPN_FEATURE__DEBUG_DATA_CONFIGURATION_PROGRAM (1 << 2) +#define PPN_FEATURE__DEBUG_DATA_CONFIGURATION_ERASE (1 << 3) + +#define PPN_OPERATION_STATUS__ERROR (1 << 0) +#define PPN_OPERATION_STATUS__REFRESH (1 << 1) +#define PPN_OPERATION_STATUS__RETIRE (1 << 2) +#define PPN_OPERATION_STATUS__CLEAN (1 << 3) +#define PPN_OPERATION_STATUS__GENERAL_ERROR (1 << 4) +#define PPN_OPERATION_STATUS__READY (1 << 6) + +#define PPN_FEAT_OPERATION_STATUS__ERROR (1 << 0) +#define PPN_FEAT_OPERATION_STATUS__FW_UPDATE_ERROR (1 << 1) +#define PPN_FEAT_OPERATION_STATUS__NOT_SUPPORTED (1 << 2) +#define PPN_FEAT_OPERATION_STATUS__NOT_SUPPORTED_BY_CH (1 << 3) +#define PPN_FEAT_OPERATION_STATUS__GENERAL_ERROR (1 << 4) +#define PPN_FEAT_OPERATION_STATUS__READY (1 << 6) + +#define PPN_FEAT_OPERATION_STATUS__SUCCESS (PPN_FEAT_OPERATION_STATUS__READY) +#define PPN_FEAT_OPERATION_STATUS__FAILURE (PPN_FEAT_OPERATION_STATUS__READY | PPN_FEAT_OPERATION_STATUS__ERROR) +#define PPN_FEAT_OPERATION_STATUS__FW_UPDATE_FAILURE (PPN_FEAT_OPERATION_STATUS__READY | PPN_FEAT_OPERATION_STATUS__FW_UPDATE_ERROR | PPN_FEAT_OPERATION_STATUS__ERROR) +#define PPN_FEAT_OPERATION_STATUS__UNSUPPORTED (PPN_FEAT_OPERATION_STATUS__READY | PPN_FEAT_OPERATION_STATUS__ERROR | PPN_FEAT_OPERATION_STATUS__NOT_SUPPORTED) +#define PPN_FEAT_OPERATION_STATUS__UNSUPPORTED_BY_CH (PPN_FEAT_OPERATION_STATUS__READY | PPN_FEAT_OPERATION_STATUS__ERROR | PPN_FEAT_OPERATION_STATUS__NOT_SUPPORTED_BY_CH) +#define PPN_FEAT_OPERATION_STATUS__SUCCESS_WITH_GEB (PPN_FEAT_OPERATION_STATUS__READY | PPN_FEAT_OPERATION_STATUS__GENERAL_ERROR) +#define PPN_FEAT_OPERATION_STATUS__FAILURE_WITH_GEB (PPN_FEAT_OPERATION_STATUS__READY | PPN_FEAT_OPERATION_STATUS__ERROR | PPN_FEAT_OPERATION_STATUS__GENERAL_ERROR) + +#define PPN_CONTROLLER_STATUS__PENDING_ERRORS (1 << 0) +#define PPN_CONTROLLER_STATUS__READY_FOR_OPERATIONS (1 << 1) +#define PPN_CONTROLLER_STATUS__OPERATION_STATUS_AVAILABLE (1 << 2) +#define PPN_CONTROLLER_STATUS__GENERAL_ERROR (1 << 4) +#define PPN_CONTROLLER_STATUS__QUEUE_EMPTY (1 << 5) +#define PPN_CONTROLLER_STATUS__READY (1 << 6) + +#define PPN_LOW_POWER_STATUS__FAIL (1 << 0) +#define PPN_LOW_POWER_STATUS__READY (1 << 6) +#define PPN_LOW_POWER_STATUS__WRITE_PROTECT_BAR (1 << 7) + +#define PPN_GET_DEBUG_DATA__GET_FAILURE_TYPE 0xFFFFFFul +#define PPN_tGDD_1_5_US (20*1000) +#define PPN_tGDD_1_0_US (10*1000) + +#define PPN_SET_DEBUG_DATA__FORCE_ADDRESS (0xF0FFFF) +#define PPN_SET_DEBUG_DATA__EMB_SWEEP_ADDRESS (0x540000) + +#define PPN_GEB_TYPE__EMB_SWEEP_GEB_TYPE (0x07C0) + +#define PPN_DELETE_DEBUG_DATA__ENABLE (1) + +#define PPN_ERROR_LIST_SIZE (512) +#define PPN_DEVICE_ID_LEN (6) +#define PPN_NAND_MARKETING_NAME_LENGTH (10) + +#define PPN_PERFECT_PAGE_SIZE (4112) +#define PPN_PERFECT_FMI_SECTORS_PER_PERFECT_PAGE ((UInt32)(PPN_PERFECT_PAGE_SIZE / H2FMI_BYTES_PER_SECTOR)) // rounds down +#define PPN_PERFECT_FMI_SECTOR_SIZE (PPN_PERFECT_PAGE_SIZE / PPN_PERFECT_FMI_SECTORS_PER_PERFECT_PAGE) + +#define PPN_TIMING_MIN_TRHW_NS (100) +#define PPN_TIMING_MIN_TWHR_NS (60) + +#define PPN_FW_START_SIGNATURE (0x72617453) +#define PPN_FW_END_SIGNATURE (0x00646E45) + +#define PPN_1_5_ROW_ADDR_BYTES (4) +#define PPN_1_5_FAILURE_INFO_EXPCT_LEN (14) +#define PPN_1_0_FAILURE_INFO_EXPCT_LEN (12) + +typedef enum +{ + ppnFwTypeFw, + ppnFwTypeFwa +} h2fmi_ppn_fw_type; + +//update PPN_1_0_FAILURE_INFO_EXPCT_LEN if this struct is updated +typedef struct _h2fmi_ppn_failure_info_ppn1_0_t +{ + UInt16 type; + UInt8 startPage[3]; + UInt8 pageCount[3]; + UInt8 checksum; + UInt8 reserved1; + UInt8 reserved2; + UInt8 reserved3; +} h2fmi_ppn_failure_info_ppn1_0_t; + +//update PPN_1_5_FAILURE_INFO_EXPCT_LEN if this struct is updated +typedef struct _h2fmi_ppn_failure_info_ppn1_5_t +{ + UInt16 type; + UInt8 startPage[4]; + UInt8 pageCount[3]; + UInt8 checksum; + UInt8 reserved1; + UInt8 reserved2; + UInt8 reserved3; +} h2fmi_ppn_failure_info_ppn1_5_t; + +typedef union _h2fmi_ppn_failure_info_t +{ + h2fmi_ppn_failure_info_ppn1_5_t failure_info_1_5; + h2fmi_ppn_failure_info_ppn1_0_t failure_info_1_0; +} h2fmi_ppn_failure_info_t; + +#define FAIL_INFO_GET_START_PAGE(bytesPerRowAddr, failInfo) (((bytesPerRowAddr) == PPN_1_5_ROW_ADDR_BYTES) ? \ + (((failInfo).failure_info_1_5.startPage[0]) | \ + ((failInfo).failure_info_1_5.startPage[1] << 8) | \ + ((failInfo).failure_info_1_5.startPage[2] << 16) | \ + ((failInfo).failure_info_1_5.startPage[3] << 24)) : \ + (((failInfo).failure_info_1_0.startPage[0]) |\ + ((failInfo).failure_info_1_0.startPage[1] << 8) |\ + ((failInfo).failure_info_1_0.startPage[2] << 16))) + +#define FAIL_INFO_GET_PAGE_COUNT(bytesPerRowAddr, failInfo) (((bytesPerRowAddr) == PPN_1_5_ROW_ADDR_BYTES) ? \ + (((failInfo).failure_info_1_5.pageCount[0]) | \ + ((failInfo).failure_info_1_5.pageCount[1] << 8) | \ + ((failInfo).failure_info_1_5.pageCount[2] << 16)) : \ + (((failInfo).failure_info_1_0.pageCount[0]) | \ + ((failInfo).failure_info_1_0.pageCount[1] << 8) | \ + ((failInfo).failure_info_1_0.pageCount[2] << 16))) + +#define FAIL_INFO_GET_TYPE(bytesPerRowAddr, failInfo) (((bytesPerRowAddr) == PPN_1_5_ROW_ADDR_BYTES) ? \ + ((failInfo).failure_info_1_5.type) : \ + ((failInfo).failure_info_1_0.type)) + +typedef enum +{ + powerStateOff, + powerStateReadyForReset, + powerStateLowPower, + powerStateNormal, + powerStateStandby +} PPN_POWER_STATE; + + +typedef struct _h2fmi_ppn_device_params_t +{ + char header[16]; + UInt32 caus_per_channel; + UInt32 cau_bits; + UInt32 blocks_per_cau; + UInt32 block_bits; + UInt32 pages_per_block; + UInt32 pages_per_block_slc; + UInt32 page_address_bits; + UInt32 address_bits_bits_per_cell; + UInt32 default_bits_per_cell; + UInt32 page_size; + UInt32 dies_per_channel; + UInt32 block_pairing_scheme; + UInt32 bytes_per_row_address; + UInt8 reserved[92]; + UInt8 tRC; + UInt8 tREA; + UInt8 tREH; + UInt8 tRHOH; + UInt8 tRHZ; + UInt8 tRLOH; + UInt8 tRP; + UInt8 reserved2; + UInt8 tWC; + UInt8 tWH; + UInt8 tWP; + UInt8 reserved3[53]; + UInt32 read_queue_size; + UInt32 program_queue_size; + UInt32 erase_queue_size; + UInt32 prep_function_buffer_size; + UInt32 tRST_ms; + UInt32 tPURST_ms; + UInt32 tSCE_ms; + UInt32 tCERDY_us; + UInt8 reserved4[4]; + UInt32 cau_per_channel2; + UInt32 dies_per_channel2; + UInt8 reserved5[4]; + UInt8 ddr_tRC; + UInt8 ddr_tREH; + UInt8 ddr_tRP; + UInt8 reserved6; + UInt32 tDQSL_ps; + UInt32 tDQSH_ps; + UInt32 tDSC_ps; + UInt32 tDQSRE_ps; + UInt32 tDQSQ_ps; + UInt32 tDVW_ps; + UInt8 max_interface_speed; + UInt8 reserved7[211]; +} h2fmi_ppn_device_params_t; + +typedef struct _h2fmi_ppn_t +{ + h2fmi_ppn_device_params_t device_params; + UInt32 spec_version; +#if !defined(APPLICATION_EMBEDDEDIOP) + NandGeometry geometry; + NandBoardSupport boardSupport; + NandPpn nandPpn; +#endif /* !APPLICATION_EMBEDDEDIOP */ + UInt8 bytes_per_row_address; + UInt8 bytes_per_full_address; + BOOL32 general_error; + UInt32 general_error_ce; + UInt32 debug_flags; + BOOL32 debug_flags_valid; + UInt32 vs_debug_flags; + BOOL32 vs_debug_flags_valid; + UInt32 allow_saving_debug_data; + PageAddressType *prep_buffer[PPN_MAX_CES_PER_BUS]; + +#if FMI_ECC_DEBUG + UInt32 ecc_sectors_read; +#endif // FMI_ECC_DEBUG + +} h2fmi_ppn_t; + +typedef struct _ppn_feature_entry_t +{ + UInt32 version; + UInt16 feature; + UInt32 value; + UInt32 bytes; +} ppn_feature_entry_t; + +void h2fmiPpnPerformCommandList(PPNCommandStruct **commands, UInt32 num_commands); + +Int32 h2fmiPpnReadNoEcc(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabDataBuf, + UInt8 *pabSpareBuf); + +Int32 h2fmiPpnReadSequentialPages(UInt32 *padwPpn, + UInt8 *pabDataBuf, + UInt8 *pabMetaBuf, + UInt16 wNumOfPagesToRead, + UInt8 *pbMaxCorrectedBits, + UInt8 *pdwaSectorStats, + BOOL32 bDisableWhitening); + +Int32 h2fmiPpnReadScatteredPages(UInt16 *pawCEs, + UInt32 *padwPpn, + UInt8 *pabDataBuf, + UInt8 *pabMetaBuf, + UInt16 wNumOfPagesToRead, + UInt8 *pbMaxCorrectedBits, + UInt8 *pdwaSectorStats, + BOOL32 bDisableWhitening); + +Int32 h2fmiPpnReadSinglePage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabDataBuf, + UInt8* pabMetaBuf, + UInt8* pbMaxCorrectedBits, + UInt8* pdwaSectorStats, + BOOL32 bDisableWhitening); + +Int32 h2fmiPpnReadBootpage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabData); + +Int32 h2fmiPpnReadSinglePageMaxECC(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabDataBuf); + +Int32 h2fmiPpnEraseSingleBlock(UInt16 wVirtualCE, + UInt32 wPbn); + +Int32 h2fmiPpnWriteScatteredPages(UInt16 *pawBanks, + UInt32 *padwPpn, + UInt8 *pabDataBuf, + UInt8 *pabMetaBuf, + UInt16 wNumOfPagesToWrite, + UInt16 *pawFailingCE, + BOOL32 bDisableWhitening, + UInt32 *pwFailingPageNum); + +Int32 h2fmiPpnWriteSinglePage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabDataBuf, + UInt8 *pabMetaBuf, + BOOL32 disableWhitening); + +Int32 h2fmiPpnWriteSinglePageMaxECC(UInt16 wBank, + UInt32 nPpn, + UInt8 *pdBuf); + +Int32 h2fmiPpnWriteBootpage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabData); + +Int32 h2fmiPpnReadCauBbt(UInt16 wCS, UInt32 wCAU, UInt8 *pData); + +Int32 h2fmiPpnUpdateFw(UInt16 wVirtualCE, + UInt8 *fw, + UInt32 fw_length, + UInt8 *fwa, + UInt32 fwa_length); + +Int32 h2fmiPpnGetFirmwareVersion(UInt16 virtualCE, + UInt8 *buffer); +BOOL32 h2fmiPpnValidateFirmwareVersions(UInt8 *buffer, UInt32 ce_count); +Int32 h2fmiPpnGetControllerHwId(UInt16 virtualCE, UInt8 *buffer); +Int32 h2fmiPpnGetManufacturerId(UInt16 virtualCE, UInt8 *buffer); +BOOL32 h2fmiPpnValidateManufacturerIds(UInt8 *expected, UInt32 ce_count); +Int32 h2fmiPpnGetControllerInfo(UInt16 virtualCE, UInt8 *mfg_id, UInt8 *fw_version); +Int32 h2fmiVthSweepSetup(UInt8 virCE, UInt32 blk, h2fmi_ppn_failure_info_t *failInfo, UInt32 *totalDataToRead); +Int32 h2fmiDmaDebugData(UInt8 virCE, UInt32 page, UInt32 pageCount, struct dma_segment *sgl, BOOL32 waitFortGDD); + +void h2fmi_ppn_dma_debug_data_payload(h2fmi_t *fmi, h2fmi_ce_t ce, UInt32 page, UInt32 pageCount, struct dma_segment *sgl, BOOL32 waitFortGDD); +UInt32 h2fmi_ppn_get_general_error_info(h2fmi_t *fmi, h2fmi_ce_t ce, h2fmi_ppn_failure_info_t *buffer, UInt32 *dataLength, struct dma_segment *sgl); +Int32 h2fmi_ppn_configure_debug_data(h2fmi_t *fmi, h2fmi_ce_t ce); + +#if SUPPORT_TOGGLE_NAND +BOOL32 h2fmi_ppn15_get_temperature(h2fmi_t *fmi, h2fmi_ce_t ce, Int16 *temperature); +BOOL32 h2fmi_ppn15_enable_optional_signals(h2fmi_t *fmi, h2fmi_ce_t ce); +#endif + +Int32 h2fmi_ppn_write_bootpage(h2fmi_t *fmi, + UInt16 ce, + UInt32 dwPpn, + const UInt8 *pabData); + +Int32 h2fmi_ppn_read_multi(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + struct dma_segment *data_segment_array, + struct dma_segment *meta_segment_array); + +Int32 h2fmi_ppn_write_multi(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + struct dma_segment *data_segment_array, + struct dma_segment *meta_segment_array); + +Int32 h2fmi_ppn_read_bootpage(h2fmi_t *fmi, + UInt16 ce, + UInt32 page, + UInt8 *data, + UInt8 *max_corrected); + +Int32 h2fmi_ppn_erase_blocks(h2fmi_t *fmi, PPNCommandStruct *ppnCommand); + +Int32 h2fmi_ppn_read_cau_bbt(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + UInt8 *buffer); + +Int32 h2fmi_ppn_fw_update(h2fmi_t *fmi, h2fmi_ce_t ce, struct dma_segment *sgl, UInt32 fw_size, h2fmi_ppn_fw_type fw_type); +BOOL32 h2fmi_ppn_get_fw_version(h2fmi_t *fmi, h2fmi_ce_t ce, UInt8 *buffer); +BOOL32 h2fmi_ppn_get_package_assembly_code(h2fmi_t *fmi, h2fmi_ce_t ce, UInt8 *buffer); +BOOL32 h2fmi_ppn_get_controller_unique_id(h2fmi_t *fmi, h2fmi_ce_t ce, UInt8 *buffer); +BOOL32 h2fmi_ppn_get_controller_hw_id(h2fmi_t *fmi, h2fmi_ce_t ce, UInt8 *buffer); +BOOL32 h2fmi_ppn_get_controller_status(h2fmi_t *fmi, UInt8 *controller_status); +BOOL32 h2fmi_ppn_get_manufacturer_id(h2fmi_t *fmi, h2fmi_ce_t ce, UInt8 *buffer); +BOOL32 h2fmi_ppn_get_die_chip_id(h2fmi_t *fmi, h2fmi_ce_t ce, UInt32 die, UInt8 *buffer); +BOOL32 h2fmi_ppn_get_marketing_name(h2fmi_t *fmi, h2fmi_ce_t ce, UInt8 *buffer); +BOOL32 h2fmi_ppn_set_debug_data(h2fmi_t *fmi, h2fmi_ce_t ce, UInt32 type, UInt8 *buffer, UInt32 len); + +void h2fmi_ppn_poweron(h2fmi_t *fmi); +void h2fmi_ppn_poweroff(h2fmi_t *fmi); +void h2fmi_ppn_set_power_low_power(h2fmi_t *fmi); + +void h2fmi_ppn_set_power_standby(h2fmi_t *fmi); +BOOL32 h2fmi_ppn_init_channel(h2fmi_t *fmi, BOOL32 debug_flags_valid, UInt32 debug_flags, BOOL32 vs_debug_flags_valid, UInt32 vs_debug_flags, BOOL32 allow_saving_debug_data, UInt32 spec_version); +BOOL32 h2fmi_ppn_set_channel_power_state(h2fmi_t *fmi, UInt32 ps_tran); +BOOL32 h2fmi_ppn_post_rst_pre_pwrstate_operations(h2fmi_t* fmi); +BOOL32 h2fmi_ppn_get_device_params(h2fmi_t *fmi, h2fmi_ce_t ce, h2fmi_ppn_device_params_t *params); +BOOL32 h2fmi_ppn_get_next_operation_status(h2fmi_t *fmi, UInt8 *operation_status); +UInt32 h2fmi_ppn_get_device_info(UInt32 dwParamType); +UInt32 h2fmi_ppn_calculate_fmi_config(h2fmi_t *fmi); +UInt32 h2fmi_ppn_calculate_fmi_data_size(h2fmi_t *fmi); +UInt8 h2fmi_ppn_get_idle_counter(h2fmi_t *fmi, h2fmi_ce_t ce); +void h2fmi_ppn_force_geb_address(h2fmi_t *fmi, h2fmi_ce_t ce, PageAddressType addr); +void h2fmi_ppn_set_feature_list(h2fmi_t *fmi, ppn_feature_entry_t *list, UInt32 size); + +BOOL32 h2fmi_ppn_get_uid(h2fmi_t *fmi, UInt8 ce, UInt8 die, UInt8 *buf); + +Int32 h2fmi_ppn_set_features(h2fmi_t *fmi, UInt32 ce, UInt16 feature, UInt8 *data, UInt32 len, BOOL32 optFeature, UInt8 *status); +BOOL32 h2fmi_ppn_get_feature(h2fmi_t *fmi, h2fmi_ce_t ce, UInt32 feature, UInt8 *buffer, UInt32 len, UInt8 *status); +void h2fmi_ppn_process_error_list(h2fmi_t *fmi, PPNCommandStruct *ppnCommand, UInt8 ceIndex, UInt32 *list, UInt8 status); + +#if !defined(APPLICATION_EMBEDDEDIOP) +void h2fmi_ppn_fill_nandinfo(h2fmi_t *fmi, NandInfo *nandInfo, NandRequiredTimings *requiredTiming); +#endif /* !APPLICATIONS_EMBEDDEDIOP */ + +void fmiss_init_sequences(h2fmi_t *fmi); +Int32 fmiss_ppn_read_multi(h2fmi_t *fmi, PPNCommandStruct *ppnCommand, struct dma_segment *data_segment_array, struct dma_segment *meta_segment_array); +Int32 fmiss_ppn_write_multi(h2fmi_t *fmi, PPNCommandStruct *ppnCommand, struct dma_segment *data_segment_array, struct dma_segment *meta_segment_array); + +#if H2FMI_PPN_VERIFY_SET_FEATURES +void h2fmi_ppn_verify_feature_shadow(h2fmi_t *fmi); +void h2fmi_ppn_reset_feature_shadow(h2fmi_t *fmi); +#endif // H2FMI_PPN_VERIFY_SET_FEATURES + +#endif /* _H2FMI_PPN_H_ */ diff --git a/drivers/apple/h2fmi/H2fmi_ppn_fil.c b/drivers/apple/h2fmi/H2fmi_ppn_fil.c new file mode 100644 index 0000000..2f22956 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_ppn_fil.c @@ -0,0 +1,997 @@ +// ***************************************************************************** +// +// File: H2fmi_ppn_fil.c +// +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// ***************************************************************************** + +#include "WMROAM.h" +#include +#include +#include "H2fmi_private.h" +#include "H2fmi.h" +#include "H2fmi_ppn.h" + +#if SUPPORT_PPN + +extern UInt32 *g_pScratchBuf; + +extern h2fmi_t g_fmi0; +extern h2fmi_t g_fmi1; + +#if (defined(AND_COLLECT_FIL_STATISTICS) && AND_COLLECT_FIL_STATISTICS) +#define AND_FIL_STAT(x) (x) +extern FILStatistics stFILStatistics; +#else +#define AND_FIL_STAT(x) +#endif /* AND_COLLECT_FIL_STATISTICS */ + +void h2fmi_ppn_recover_nand(void); +static Int32 h2fmiPpnReadMulti(h2fmi_t *fmi, PPNCommandStruct *ppnCommand); +static Int32 h2fmiPpnReadMultiWithSingles(h2fmi_t *fmi, PPNCommandStruct *ppnCommand); +static PPNCommandStruct *topLevelSingle = NULL; +static PPNCommandStruct *lowLevelSingle = NULL; +static struct dma_segment *dataSegments = NULL; +static struct dma_segment *metaSegments = NULL; + +#if (defined(AND_SUPPORT_BLOCK_STORAGE) && AND_SUPPORT_BLOCK_STORAGE) +static Int32 h2fmiPpnWriteMulti(h2fmi_t *fmi, PPNCommandStruct *ppnCommand); +#endif + +BOOL32 h2fmi_ppn_fil_init(void) +{ + if (NULL == lowLevelSingle) + { + lowLevelSingle = WMR_MALLOC(sizeof(*lowLevelSingle)); + if (NULL == lowLevelSingle) + { + return FALSE32; + } + } + if (NULL == topLevelSingle) + { + topLevelSingle = WMR_MALLOC(sizeof(*topLevelSingle)); + if (NULL == topLevelSingle) + { + return FALSE32; + } + } + if (NULL == dataSegments) + { + dataSegments = WMR_MALLOC(PPN_MAX_PAGES * sizeof(struct dma_segment)); + if (NULL == dataSegments) + { + return FALSE32; + } + } + if (NULL == metaSegments) + { + metaSegments = WMR_MALLOC(PPN_MAX_PAGES * sizeof(struct dma_segment)); + if (NULL == metaSegments) + { + return FALSE32; + } + } + return TRUE32; +} + +void h2fmiPpnPerformCommandList(PPNCommandStruct **commands, UInt32 num_commands) +{ + UInt32 i; + + for (i = 0; i < num_commands; i++) + { + PPNCommandStruct *command = commands[i]; + h2fmi_t *fmi = (command->context.bus_num == 1) ? &g_fmi1 : &g_fmi0; + Int32 status; + + if (command->num_pages == 0) + { + continue; + } + + switch(command->command) + { + case PPN_COMMAND_READ: +#if (defined(H2FMI_ALLOW_MULTIS) && H2FMI_ALLOW_MULTIS) + if (!(command->options & PPN_OPTIONS_REPORT_HEALTH)) + { + status = h2fmiPpnReadMulti(fmi, command); + } + else +#endif + { + status = h2fmiPpnReadMultiWithSingles(fmi, command); + } + break; + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM +#if (defined(AND_SUPPORT_BLOCK_STORAGE) && AND_SUPPORT_BLOCK_STORAGE) + case PPN_COMMAND_PROGRAM: + status = h2fmiPpnWriteMulti(fmi, command); + break; +#endif + + case PPN_COMMAND_ERASE: + status = h2fmi_ppn_erase_blocks(fmi, command); + break; +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + + case PPN_COMMAND_CAUBBT: + status = h2fmi_ppn_read_cau_bbt(fmi, command, command->mem_buffers[0].data); + break; + + default: + WMR_PANIC("Invalid PPN FIL command: %d", command->command); + break; + } + + switch(status) + { + case _kIOPFMI_STATUS_PPN_GENERAL_ERROR: + WMR_PRINT(ERROR, "Command type 0x%08x failed due to PPN Controller General Error on bus %lu ce %lu\n", + command->command, fmi->bus_id, fmi->ppn->general_error_ce); + + h2fmi_ppn_recover_nand(); + break; + + case _kIOPFMI_STATUS_READY_BUSY_TIMEOUT: + WMR_PRINT(ERROR, "Command type 0x%08x failed due to PPN controller status timeout on bus %lu\n", + command->command, fmi->bus_id); + + h2fmi_ppn_recover_nand(); + break; + } + } +} + +Int32 h2fmiPpnReadMulti(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand) +{ + const UInt32 numPages = ppnCommand->num_pages; + UInt32 page; + Int32 ret; + UInt8 *metaBounceBuffer; + UInt8 *metaSrc; + + WMR_ASSERT(metaSegments != NULL); + WMR_ASSERT(dataSegments != NULL); + + WMR_MEMSET(dataSegments, 0, PPN_MAX_PAGES * sizeof(struct dma_segment)); + WMR_MEMSET(metaSegments, 0, PPN_MAX_PAGES * sizeof(struct dma_segment)); + + metaBounceBuffer = (UInt8 *)g_pScratchBuf; + + WMR_MEMSET(metaBounceBuffer, 0xAB, ppnCommand->lbas * fmi->valid_bytes_per_meta); + + metaSegments[0].paddr = (UInt32)metaBounceBuffer; + metaSegments[0].length = ppnCommand->lbas * fmi->valid_bytes_per_meta; + + WMR_PREPARE_READ_BUFFER(metaBounceBuffer, ppnCommand->lbas * fmi->valid_bytes_per_meta); + + for (page = 0; page < numPages; page++) + { + const PPNCommandEntry *entry = &ppnCommand->entry[page]; + const PPNMemoryIndex *memIndex = &ppnCommand->mem_index[page]; + const PPNMemoryEntry *memoryEntry = &ppnCommand->mem_buffers[memIndex->idx]; + UInt8 *dataPtr; + UInt32 dataLength; + + dataPtr = (UInt8 *)memoryEntry->data + (memIndex->offset * fmi->logical_page_size); + dataLength = entry->lbas * fmi->logical_page_size; + + WMR_PREPARE_READ_BUFFER(dataPtr, dataLength); + + dataSegments[page].paddr = (UInt32)dataPtr; + dataSegments[page].length = dataLength; + } + +#if FMISS_ENABLED + ret = fmiss_ppn_read_multi(fmi, ppnCommand, dataSegments, metaSegments); +#else + ret = h2fmi_ppn_read_multi(fmi, ppnCommand, dataSegments, metaSegments); +#endif + + WMR_COMPLETE_READ_BUFFER(metaBounceBuffer, ppnCommand->lbas * fmi->valid_bytes_per_meta); + + metaSrc = metaBounceBuffer; + for (page = 0; page < ppnCommand->num_pages; page++) + { + const PPNCommandEntry *entry = &ppnCommand->entry[page]; + const PPNMemoryIndex *memIndex = &ppnCommand->mem_index[page]; + const PPNMemoryEntry *memoryEntry = &ppnCommand->mem_buffers[memIndex->idx]; + + WMR_COMPLETE_READ_BUFFER((void *)dataSegments[page].paddr, dataSegments[page].length); + if (memoryEntry->meta) + { + UInt8 *metaDest; + + metaDest = (UInt8 *)memoryEntry->meta + (memIndex->offset * fmi->total_bytes_per_meta); + + WMR_MEMCPY(metaDest, + metaSrc, + entry->lbas * fmi->valid_bytes_per_meta); + metaSrc += entry->lbas * fmi->valid_bytes_per_meta; + } + } + + return ret; +} + +static Int32 h2fmiPpnReadMultiWithSingles(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand) +{ + UInt32 i; + UInt8 *metaBounceBuffer; + Int32 status = _kIOPFMI_STATUS_SUCCESS; + + metaBounceBuffer = (UInt8 *)g_pScratchBuf; + + ppnCommand->page_status_summary = 0; + + for (i = 0; (i < ppnCommand->num_pages) && (status == _kIOPFMI_STATUS_SUCCESS); i++) + { + const PPNCommandEntry *entry = &ppnCommand->entry[i]; + const PPNCommandCeInfo *ceInfo = &ppnCommand->ceInfo[entry->ceIdx]; + const PPNMemoryIndex *memIndex = &ppnCommand->mem_index[i]; + const PPNMemoryEntry *memEntry = &ppnCommand->mem_buffers[memIndex->idx]; + struct dma_segment dataSegment; + struct dma_segment metaSegment; + UInt8 *dataPtr; + UInt8 *metaPtr = NULL; + + WMR_MEMSET(lowLevelSingle, 0, sizeof(*lowLevelSingle)); + + lowLevelSingle->context = ppnCommand->context; + lowLevelSingle->command = PPN_COMMAND_READ; + lowLevelSingle->options = ppnCommand->options; + lowLevelSingle->entry[0].addr = entry->addr; + lowLevelSingle->entry[0].ceIdx = 0; + lowLevelSingle->entry[0].lbas = entry->lbas; + lowLevelSingle->ceInfo[0].pages = 1; + lowLevelSingle->ceInfo[0].ce = ceInfo->ce; + lowLevelSingle->mem_index[0] = *memIndex; + + dataPtr = (UInt8 *)memEntry->data + (memIndex->offset * fmi->logical_page_size); + if (memEntry->meta) + { + metaPtr = (UInt8 *)memEntry->meta + (memIndex->offset * fmi->total_bytes_per_meta); + } + + WMR_PREPARE_READ_BUFFER(dataPtr, entry->lbas * fmi->logical_page_size); + WMR_PREPARE_READ_BUFFER(metaBounceBuffer, entry->lbas * fmi->total_bytes_per_meta); + + dataSegment.paddr = (UInt32)dataPtr; + dataSegment.length = entry->lbas * fmi->logical_page_size; + metaSegment.paddr = (UInt32)metaBounceBuffer; + metaSegment.length = entry->lbas * fmi->valid_bytes_per_meta; + + lowLevelSingle->num_pages = 1; + lowLevelSingle->lbas = entry->lbas; + +#if FMISS_ENABLED + status = fmiss_ppn_read_multi(fmi, lowLevelSingle, &dataSegment, &metaSegment); +#else + status = h2fmi_ppn_read_multi(fmi, lowLevelSingle, &dataSegment, &metaSegment); +#endif + WMR_COMPLETE_READ_BUFFER(metaBounceBuffer, entry->lbas * fmi->total_bytes_per_meta); + WMR_COMPLETE_READ_BUFFER(dataPtr, entry->lbas * fmi->logical_page_size); + + if ( NULL != metaPtr ) + { + WMR_MEMCPY(metaPtr, metaBounceBuffer, entry->lbas * fmi->total_bytes_per_meta); + } + + ppnCommand->entry[i].status = lowLevelSingle->entry[0].status; + ppnCommand->page_status_summary |= lowLevelSingle->page_status_summary; + } + + return status; +} + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM +#if (defined(AND_SUPPORT_BLOCK_STORAGE) && AND_SUPPORT_BLOCK_STORAGE) +static Int32 h2fmiPpnWriteMulti(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand) +{ + UInt32 i; + UInt8 *metaBounceBuffer; + Int32 status; + + status = _kIOPFMI_STATUS_SUCCESS; + metaBounceBuffer = (UInt8 *)g_pScratchBuf; + + ppnCommand->page_status_summary = 0; + + for (i = 0; (i < ppnCommand->num_pages) && (status == _kIOPFMI_STATUS_SUCCESS); i++) + { + const PPNCommandEntry *entry = &ppnCommand->entry[i]; + const PPNCommandCeInfo *ceInfo = &ppnCommand->ceInfo[entry->ceIdx]; + const PPNMemoryIndex *memIndex = &ppnCommand->mem_index[i]; + const PPNMemoryEntry *memEntry = &ppnCommand->mem_buffers[memIndex->idx]; + struct dma_segment dataSegment; + struct dma_segment metaSegment; + UInt8 *dataPtr; + UInt8 *metaPtr = NULL; + + WMR_MEMSET(lowLevelSingle, 0, sizeof(*lowLevelSingle)); + + lowLevelSingle->context = ppnCommand->context; + lowLevelSingle->command = PPN_COMMAND_PROGRAM; + lowLevelSingle->options = ppnCommand->options; + lowLevelSingle->entry[0].addr = entry->addr; + lowLevelSingle->entry[0].ceIdx = 0; + lowLevelSingle->entry[0].lbas = entry->lbas; + lowLevelSingle->ceInfo[0].pages = 1; + lowLevelSingle->ceInfo[0].ce = ceInfo->ce; + lowLevelSingle->mem_index[0] = *memIndex; + + dataPtr = (UInt8 *)memEntry->data + (memIndex->offset * fmi->logical_page_size); + if (memEntry->meta) + { + metaPtr = (UInt8 *)memEntry->meta + (memIndex->offset * fmi->total_bytes_per_meta); + WMR_MEMCPY(metaBounceBuffer, metaPtr, entry->lbas * fmi->total_bytes_per_meta); + } + else + { + WMR_MEMSET(metaBounceBuffer, 0xA5, entry->lbas * fmi->total_bytes_per_meta); + } + + WMR_PREPARE_WRITE_BUFFER(dataPtr, entry->lbas * fmi->logical_page_size); + WMR_PREPARE_WRITE_BUFFER(metaBounceBuffer, entry->lbas * fmi->total_bytes_per_meta); + + dataSegment.paddr = (UInt32)dataPtr; + dataSegment.length = entry->lbas * fmi->logical_page_size; + metaSegment.paddr = (UInt32)metaBounceBuffer; + metaSegment.length = entry->lbas * fmi->valid_bytes_per_meta; + + lowLevelSingle->num_pages = 1; + lowLevelSingle->lbas = entry->lbas; + +#if FMISS_ENABLED + status = fmiss_ppn_write_multi(fmi, lowLevelSingle, &dataSegment, &metaSegment); +#else + status = h2fmi_ppn_write_multi(fmi, lowLevelSingle, &dataSegment, &metaSegment); +#endif + ppnCommand->entry[i].status = lowLevelSingle->entry[0].status; + ppnCommand->page_status_summary |= lowLevelSingle->page_status_summary; + } + + return status; +} +#endif +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + +Int32 h2fmiPpnReadSinglePage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8* pabDataBuf, + UInt8* pabMetaBuf, + UInt8* pbMaxCorrectedBits, + UInt8* pdwaSectorStats, + BOOL32 bDisableWhitening) +{ + PPNCommandStruct *ppnCommand; + h2fmi_t *fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + UInt16 ce = h2fmiTranslateVirtualCEToCe(wVirtualCE); + Int32 ret; + + WMR_ASSERT(NULL != fmi); + + ppnCommand = topLevelSingle; + WMR_MEMSET(ppnCommand, 0, sizeof(PPNCommandStruct)); + + if (pbMaxCorrectedBits) + { + *pbMaxCorrectedBits = 0; + } + + ppnCommand->context.device_info = NULL; + ppnCommand->context.handle = NULL; + ppnCommand->context.bus_num = fmi->bus_id; + ppnCommand->command = PPN_COMMAND_READ; + ppnCommand->options = 0; + ppnCommand->entry[0].ceIdx = 0; + ppnCommand->entry[0].addr.length = fmi->bytes_per_page + fmi->total_bytes_per_meta; + ppnCommand->entry[0].addr.column = 0; + ppnCommand->entry[0].addr.row = dwPpn; + ppnCommand->ceInfo[0].pages = 1; + ppnCommand->ceInfo[0].ce = ce; + ppnCommand->mem_index[0].offset = 0; + ppnCommand->mem_index[0].idx = 0; + ppnCommand->entry[0].lbas = fmi->bytes_per_page / fmi->logical_page_size; + ppnCommand->mem_buffers[0].data = pabDataBuf; + ppnCommand->mem_buffers[0].meta = pabMetaBuf; + ppnCommand->mem_buffers[0].num_of_lbas = 1; + ppnCommand->num_pages = 1; + ppnCommand->lbas = fmi->bytes_per_page / fmi->logical_page_size; + + if(pdwaSectorStats != NULL) + { + ppnCommand->options = PPN_OPTIONS_REPORT_HEALTH; + } + + h2fmiPpnPerformCommandList(&ppnCommand, 1); + + if(pdwaSectorStats != NULL) + { + WMR_MEMCPY(pdwaSectorStats, pabDataBuf, fmi->sectors_per_page); + } + + switch (ppnCommand->page_status_summary) + { + case 0x40: + ret = FIL_SUCCESS; + break; + + case 0x42: + ret = FIL_SUCCESS; + WMR_PRINT(ERROR, "Single Page PPN Read saw refresh - read status: 0x%02X, CE: %d, Page: 0x%08X\n", + ppnCommand->page_status_summary, wVirtualCE, dwPpn); + break; + + case 0x44: + case 0x43: + case 0x45: + ret = FIL_U_ECC_ERROR; + break; + + case 0x49: + ret = FIL_SUCCESS_CLEAN; + break; + + default: + WMR_PRINT(ALWAYS, "Single Page PPN Read failed - overall NAND status 0x%02x\n", + ppnCommand->page_status_summary); + ret = FIL_CRITICAL_ERROR; + break; + } + + return ret; +} + +Int32 h2fmiPpnReadBootpage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabData) +{ + Int32 nRet = FIL_SUCCESS; + UInt32 status; + + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe(wVirtualCE); + + WMR_ASSERT(NULL != fmi); + WMR_ASSERT(WMR_CHECK_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE)); + WMR_PREPARE_READ_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE); + + status = h2fmi_ppn_read_bootpage(fmi, ce, dwPpn, pabData, NULL); + + switch (status) + { + case _kIOPFMI_STATUS_BLANK: + WMR_PRINT(READ, "[FIL:LOG] Clean Page\n"); + AND_FIL_STAT(stFILStatistics.ddwReadCleanCnt++); + nRet = FIL_SUCCESS_CLEAN; + break; + case _kIOPFMI_STATUS_SUCCESS: + WMR_PRINT(READ, "[FIL:LOG] Good page\n"); + nRet = FIL_SUCCESS; + break; + case _kIOPFMI_STATUS_AT_LEAST_ONE_UECC: + WMR_PRINT(ERROR, "UECC ce: %d p:0x%08x\n", (UInt32) wVirtualCE, dwPpn); + AND_FIL_STAT(stFILStatistics.ddwReadECCErrorCnt++); + nRet = FIL_U_ECC_ERROR; + break; + case _kIOPFMI_STATUS_PPN_GENERAL_ERROR: + WMR_PRINT(ERROR, "GEB ce: %d p:0x%08x\n", (UInt32) wVirtualCE, dwPpn); + nRet = FIL_CRITICAL_ERROR; + h2fmi_ppn_recover_nand(); + break; + default: + WMR_PRINT(ERROR, "Error status: 0x%08x ce: %d p:0x%08x\n", status, (UInt32) wVirtualCE, dwPpn); + AND_FIL_STAT(stFILStatistics.ddwReadHWErrorCnt++); + nRet = FIL_CRITICAL_ERROR; + h2fmi_ppn_recover_nand(); + break; + } + + AND_FIL_STAT(stFILStatistics.ddwPagesReadCnt++); + + WMR_COMPLETE_READ_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE); + + return nRet; +} + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM || !H2FMI_READONLY +Int32 h2fmiPpnWriteSinglePage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabDataBuf, + UInt8 *pabMetaBuf, + BOOL32 disableWhitening) +{ + PPNCommandStruct *ppnCommand; + Int32 result; + h2fmi_t *fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + UInt16 ce = h2fmiTranslateVirtualCEToCe(wVirtualCE); + + WMR_ASSERT(NULL != fmi); + ppnCommand = topLevelSingle; + WMR_ASSERT(ppnCommand != NULL); + + WMR_MEMSET(ppnCommand, 0, sizeof(PPNCommandStruct)); + + ppnCommand->context.device_info = NULL; + ppnCommand->context.handle = NULL; + ppnCommand->context.bus_num = fmi->bus_id; + ppnCommand->command = PPN_COMMAND_PROGRAM; + ppnCommand->options = 0; + ppnCommand->entry[0].ceIdx = 0; + ppnCommand->entry[0].addr.row = dwPpn; + ppnCommand->ceInfo[0].pages = 1; + ppnCommand->ceInfo[0].ce = ce; + ppnCommand->mem_index[0].offset = 0; + ppnCommand->mem_index[0].idx = 0; + ppnCommand->entry[0].lbas = (fmi->sectors_per_page * H2FMI_BYTES_PER_SECTOR) / fmi->logical_page_size; + ppnCommand->mem_buffers[0].data = pabDataBuf; + ppnCommand->mem_buffers[0].meta = pabMetaBuf; + ppnCommand->mem_buffers[0].num_of_lbas = 1; + ppnCommand->num_pages = 1; + + h2fmiPpnPerformCommandList(&ppnCommand, 1); + + if (ppnCommand->page_status_summary & PPN_CONTROLLER_STATUS__PENDING_ERRORS) + { + result = FIL_WRITE_FAIL_ERROR; + } + else if (ppnCommand->page_status_summary & PPN_CONTROLLER_STATUS__GENERAL_ERROR) + { + result = FIL_CRITICAL_ERROR; + } + else + { + result = FIL_SUCCESS; + } + + return result; +} +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM || !H2FMI_READONLY + +Int32 h2fmiPpnWriteBootpage(UInt16 wVirtualCE, + UInt32 dwPpn, + UInt8 *pabData) +{ + Int32 nRet; + UInt32 status; + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + h2fmi_ce_t ce = h2fmiTranslateVirtualCEToCe(wVirtualCE); + + WMR_ASSERT(NULL != fmi); + WMR_ASSERT(WMR_CHECK_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE)); + WMR_PREPARE_READ_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE); + + status = h2fmi_ppn_write_bootpage(fmi, ce, dwPpn, pabData); + + switch (status) + { + case _kIOPFMI_STATUS_PGM_ERROR: + WMR_PRINT(ERROR, "[FIL:LOG] Error programming boot page\n"); + AND_FIL_STAT(stFILStatistics.ddwWriteNANDErrCnt++); + nRet = FIL_WRITE_FAIL_ERROR; + break; + case _kIOPFMI_STATUS_SUCCESS: + WMR_PRINT(READ, "[FIL:LOG] Wrote Good Boot page\n"); + nRet = FIL_SUCCESS; + break; + case _kIOPFMI_STATUS_PPN_GENERAL_ERROR: + WMR_PRINT(ERROR, "[FIL:ERR] General Error writing bootpage\n"); + nRet = FIL_CRITICAL_ERROR; + h2fmi_ppn_recover_nand(); + break; + default: + WMR_PRINT(ERROR, "[FIL:ERR] Hardware error: 0x%08x\n", status); + AND_FIL_STAT(stFILStatistics.ddwWriteHWErrCnt++); + nRet = FIL_CRITICAL_ERROR; + h2fmi_ppn_recover_nand(); + break; + } + + AND_FIL_STAT(stFILStatistics.ddwPagesWrittenCnt++); + + WMR_COMPLETE_READ_BUFFER(pabData, H2FMI_BOOT_BYTES_PER_PAGE); + + return nRet; +} + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM +Int32 h2fmiPpnEraseSingleBlock(UInt16 wVirtualCE, + UInt32 wPbn) +{ + PPNCommandStruct *ppnCommand; + h2fmi_t* fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + UInt16 ce = h2fmiTranslateVirtualCEToCe(wVirtualCE); + UInt32 wPpn = (wPbn << fmi->ppn->device_params.page_address_bits); + Int32 ret; + + WMR_ASSERT(NULL != fmi); + ppnCommand = topLevelSingle; + WMR_ASSERT(ppnCommand != NULL); + + WMR_MEMSET(ppnCommand, 0, sizeof(PPNCommandStruct)); + + ppnCommand->context.device_info = NULL; + ppnCommand->context.handle = NULL; + ppnCommand->context.bus_num = fmi->bus_id; + ppnCommand->command = PPN_COMMAND_ERASE; + ppnCommand->options = 0; + ppnCommand->entry[0].ceIdx = 0; + ppnCommand->entry[0].addr.row = wPpn; + ppnCommand->ceInfo[0].pages = 1; + ppnCommand->ceInfo[0].ce = ce; + ppnCommand->num_pages = 1; + + h2fmiPpnPerformCommandList(&ppnCommand, 1); + + switch(ppnCommand->page_status_summary) + { + case 0x40: + ret = FIL_SUCCESS; + break; + case 0x45: + ret = FIL_WRITE_FAIL_ERROR; + break; + default: + ret = FIL_CRITICAL_ERROR; + break; + } + + return ret; +} +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + +Int32 h2fmiPpnGetFirmwareVersion(UInt16 virtualCe, UInt8 *buffer) +{ + h2fmi_t *fmi; + h2fmi_ce_t ce; + BOOL32 ret = FALSE32; + + fmi = h2fmiTranslateVirtualCEToBus(virtualCe); + ce = h2fmiTranslateVirtualCEToCe(virtualCe); + + if (NULL != fmi) + { + ret = h2fmi_ppn_get_fw_version(fmi, ce, buffer); + } + + return (ret ? FIL_SUCCESS : FIL_CRITICAL_ERROR); +} + +BOOL32 h2fmiPpnValidateFirmwareVersions(UInt8 *expected, UInt32 ce_count) +{ + UInt8 buffer[NAND_DEV_PARAM_LEN_PPN]; + UInt32 virtualCe; + Int32 ret; + BOOL32 mismatch = FALSE32; + + for(virtualCe = 0; virtualCe < ce_count; virtualCe++) + { + ret = h2fmiPpnGetFirmwareVersion(virtualCe, buffer); + if (ret == FIL_SUCCESS) + { + if (WMR_MEMCMP(buffer, expected, NAND_DEV_PARAM_LEN_PPN) != 0) + { + WMR_PRINT(ERROR, "Bank %d reports incorrect PPN firmware version: expected \"%16s\", got \"%16s\"\n", + virtualCe, expected, buffer); + mismatch = TRUE32; + } + } + else + { + WMR_PRINT(ERROR, "Failed to retrieve PPN firmware version from bank %d\n", virtualCe); + mismatch = TRUE32; + } + } + + return mismatch ? FALSE32 : TRUE32; +} + +Int32 h2fmiPpnGetControllerHwId(UInt16 virtualCe, UInt8 *buffer) +{ + h2fmi_t *fmi; + h2fmi_ce_t ce; + BOOL32 ret = FALSE32; + + fmi = h2fmiTranslateVirtualCEToBus(virtualCe); + ce = h2fmiTranslateVirtualCEToCe(virtualCe); + + if (fmi) + { + ret = h2fmi_ppn_get_controller_hw_id(fmi, ce, buffer); + } + + return (ret ? FIL_SUCCESS : FIL_CRITICAL_ERROR); +} + +Int32 h2fmiPpnGetManufacturerId(UInt16 virtualCe, UInt8 *buffer) +{ + h2fmi_t *fmi; + h2fmi_ce_t ce; + BOOL32 ret = FALSE32; + + fmi = h2fmiTranslateVirtualCEToBus(virtualCe); + ce = h2fmiTranslateVirtualCEToCe(virtualCe); + + if (fmi) + { + ret = h2fmi_ppn_get_manufacturer_id(fmi, ce, buffer); + } + return (ret ? FIL_SUCCESS : FIL_CRITICAL_ERROR); +} + +BOOL32 h2fmiPpnValidateManufacturerIds(UInt8 *expected, UInt32 ce_count) +{ + UInt8 buffer[NAND_DEV_PARAM_LEN_PPN]; + UInt32 virtualCe; + Int32 ret; + BOOL32 mismatch = FALSE32; + + for(virtualCe = 0; virtualCe < ce_count; virtualCe++) + { + ret = h2fmiPpnGetManufacturerId(virtualCe, buffer); + if (ret == FIL_SUCCESS) + { + if (WMR_MEMCMP(buffer, expected, PPN_DEVICE_ID_LEN) != 0) + { + WMR_PRINT(ERROR, "Bank %d reports incorrect PPN manufacturer id: expected %02X %02X %02X %02X %02X %02X, got %02X %02X %02X %02X %02X %02X\n", + virtualCe, + expected[0], expected[1], expected[2], expected[3], expected[4], expected[5], + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); + mismatch = TRUE32; + } + } + else + { + WMR_PRINT(ERROR, "Failed to retrieve PPN manufacturer id from bank %d\n", virtualCe); + mismatch = TRUE32; + } + } + + return mismatch ? FALSE32 : TRUE32; +} + +Int32 h2fmiPpnGetControllerInfo(UInt16 virtualCe, UInt8 *mfg_id, UInt8 *fw_version) +{ + Int32 ret = FIL_SUCCESS; + + if (FIL_SUCCESS == h2fmiPpnGetManufacturerId(0, mfg_id)) + { + WMR_PRINT(INIT, "PPN Manufacturer ID: %02X %02X %02X %02X %02X %02X\n", + mfg_id[0], mfg_id[1], mfg_id[2], mfg_id[3], mfg_id[4], mfg_id[5]); + } + else + { + WMR_PRINT(ERROR, "Retrieving PPN Manufacturer ID failed!\n"); + ret = FIL_CRITICAL_ERROR; + } + + if (FIL_SUCCESS == h2fmiPpnGetFirmwareVersion(0, fw_version)) + { + WMR_PRINT(INIT, "PPN Controller Version: %16.16s\n", fw_version); + } + else + { + WMR_PRINT(ERROR, "Retrieving PPN Controller Version failed!\n"); + ret = FIL_CRITICAL_ERROR; + } + + return ret; +} + +#define MAX_ATTEMPTS (3) +Int32 h2fmiPpnUpdateFw(UInt16 wVirtualCE, UInt8 *fw, UInt32 fw_length, UInt8 *fwa, UInt32 fwa_length) +{ + h2fmi_t *fmi; + h2fmi_ce_t ce; + struct dma_segment sgl; + int i; + Int32 status; + Int32 ret_val = FIL_CRITICAL_ERROR; + + fmi = h2fmiTranslateVirtualCEToBus(wVirtualCE); + ce = h2fmiTranslateVirtualCEToCe(wVirtualCE); + + if (NULL == fmi) + { + return FIL_UNSUPPORTED_ERROR; + } + + for( i = 0; (i < MAX_ATTEMPTS) && (ret_val != FIL_SUCCESS); i++) + { + if (NULL != fw) + { + WMR_PRINT(ALWAYS, "Updating fw on fmi %d, ce %d\n", fmi->bus_id, ce); + sgl.paddr = (UInt32)fw; + sgl.length = fw_length; + + status = h2fmi_ppn_fw_update(fmi, ce, &sgl, fw_length, ppnFwTypeFw); + if (status == FIL_SUCCESS) + { + ret_val = FIL_SUCCESS; + } + else if (status == FIL_UNSUPPORTED_ERROR) + { + return status; + } + else + { + ret_val = status; + WMR_PRINT(ERROR, "Firmware Update Failed: attempt %d/%d\n", i+1, MAX_ATTEMPTS); + continue; + } + } + if (NULL != fwa) + { + WMR_PRINT(ALWAYS, "Updating fw args on fmi %d, ce %d\n", fmi->bus_id, ce); + sgl.paddr = (UInt32)fwa; + sgl.length = fwa_length; + + status = h2fmi_ppn_fw_update(fmi, ce, &sgl, fwa_length, ppnFwTypeFwa); + if (status == FIL_SUCCESS) + { + ret_val = FIL_SUCCESS; + } + else if (status == FIL_UNSUPPORTED_ERROR) + { + return status; + } + else + { + ret_val = status; + WMR_PRINT(ERROR, "Firmware Arguments Update Failed: attempt %d/%d\n", i+1, MAX_ATTEMPTS); + continue; + } + } + } + + return ret_val; +} + +void h2fmi_ppn_recover_nand(void) +{ + h2fmi_nand_reset_all(&g_fmi0); + if(g_fmi1.num_of_ce) + { + h2fmi_nand_reset_all(&g_fmi1); + } + +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + g_fmi0.is_toggle = FALSE32; + h2fmi_reset(&g_fmi0); + + if (g_fmi1.num_of_ce) + { + WMR_ASSERT(g_fmi1.is_toggle_system); + g_fmi1.is_toggle = FALSE32; + h2fmi_reset(&g_fmi1); + } + } +#endif + + h2fmi_ppn_post_rst_pre_pwrstate_operations(&g_fmi0); + if (g_fmi1.num_of_ce) + { + h2fmi_ppn_post_rst_pre_pwrstate_operations(&g_fmi1); + } + + h2fmi_ppn_set_channel_power_state(&g_fmi0, +#if SUPPORT_TOGGLE_NAND + (g_fmi0.is_toggle_system) ? PPN_PS_TRANS_LOW_POWER_TO_DDR : +#endif + PPN_PS_TRANS_LOW_POWER_TO_ASYNC); + + if (g_fmi1.num_of_ce) + { + h2fmi_ppn_set_channel_power_state(&g_fmi1, +#if SUPPORT_TOGGLE_NAND + (g_fmi1.is_toggle_system) ? PPN_PS_TRANS_LOW_POWER_TO_DDR : +#endif + PPN_PS_TRANS_LOW_POWER_TO_ASYNC); + } + +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + g_fmi0.is_toggle = TRUE32; + h2fmi_reset(&g_fmi0); + if(g_fmi1.num_of_ce) + { + WMR_ASSERT(g_fmi1.is_toggle_system); + g_fmi1.is_toggle = TRUE32; + h2fmi_reset(&g_fmi1); + } + } +#endif + g_fmi0.ppn->general_error = FALSE32; + g_fmi1.ppn->general_error = FALSE32; + +#if H2FMI_PPN_VERIFY_SET_FEATURES + if(g_fmi0.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi0); + } + if(g_fmi1.num_of_ce) + { + h2fmi_ppn_verify_feature_shadow(&g_fmi1); + } +#endif // H2FMI_PPN_VERIFY_SET_FEATURES +} + +Int32 h2fmiDmaDebugData(UInt8 virCE, UInt32 page, UInt32 pageCount, struct dma_segment *sgl, BOOL32 waitFortGDD) +{ + h2fmi_t *fmi; + h2fmi_ce_t ce; + + WMR_ASSERT(sgl != NULL); + + fmi = h2fmiTranslateVirtualCEToBus(virCE); + ce = h2fmiTranslateVirtualCEToCe(virCE); + + if (!fmi) + { + return FIL_UNSUPPORTED_ERROR; + } + + h2fmi_ppn_dma_debug_data_payload(fmi, ce, page, pageCount, sgl, waitFortGDD); + + return FIL_SUCCESS; +} + +Int32 h2fmiVthSweepSetup(UInt8 virCE, UInt32 blk, h2fmi_ppn_failure_info_t *failInfo, UInt32 *totalDataToRead) +{ + h2fmi_t *fmi; + h2fmi_ce_t ce; + UInt32 rowAddr; + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 block_shift = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_PAGE_ADDRESS); + + if (!failInfo || !totalDataToRead) + { + return FIL_CRITICAL_ERROR; + } + + fmi = h2fmiTranslateVirtualCEToBus(virCE); + ce = h2fmiTranslateVirtualCEToCe(virCE); + + if (!fmi) + { + return FIL_UNSUPPORTED_ERROR; + } + + rowAddr = blk << block_shift; + h2fmi_ppn_set_debug_data(fmi, ce, PPN_SET_DEBUG_DATA__EMB_SWEEP_ADDRESS, (UInt8*)&rowAddr, sizeof(rowAddr)); + + if (!fmi->ppn->general_error) + { + WMR_PRINT(ERROR, "No GEB during Vth Setup!\n"); + return FIL_CRITICAL_ERROR; + } + + if (h2fmi_ppn_get_general_error_info(fmi, ce, failInfo, totalDataToRead, NULL)) + { + return FIL_SUCCESS; + } + else + { + return FIL_CRITICAL_ERROR; + } +} + +#endif //SUPPORT_PPN diff --git a/drivers/apple/h2fmi/H2fmi_ppn_iop.c b/drivers/apple/h2fmi/H2fmi_ppn_iop.c new file mode 100644 index 0000000..6e3d6fd --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_ppn_iop.c @@ -0,0 +1,603 @@ +#include "H2fmi_iop.h" +#include "H2fmi_private.h" +#include "H2fmi_ppn.h" + +#include +#include +#include +#include +#include + +#include "PPN_FIL.h" + +#if SUPPORT_PPN + +void h2fmi_ppn_iop_reset_everything(h2fmi_t* fmi, IOPFMI_ResetEverything* cmd) +{ + h2fmi_restoreFmiRegs(fmi); + + h2fmi_iop_reset_everything(fmi, cmd); + fmi->ppn->general_error = FALSE32; +} + +void h2fmi_ppn_iop_erase_multiple(h2fmi_t *fmi, IOPFMI_IOPpn* cmd) +{ + PPNCommandStruct *ppnCommand; + + ppnCommand = (PPNCommandStruct *)mem_static_map_cached(cmd->ppn_fil_command); + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + WMR_ASSERT(ppnCommand != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(ppnCommand, cmd->ppn_fil_size); + + h2fmi_ppn_erase_blocks(fmi, ppnCommand); + + WMR_PREPARE_WRITE_BUFFER(ppnCommand, cmd->ppn_fil_size); + cmd->geb_ce = fmi->ppn->general_error_ce; + //WMR_PRINT(ALWAYS, "Erase Multiple: status 0x%02x\n", ppnCommand->page_status_summary); +} + +static PPNCommandStruct singlePpnCommands[kIOPFMI_MAX_NUM_OF_CHANNELS]; + +void h2fmi_ppn_iop_erase_single(h2fmi_t *fmi, IOPFMI_EraseSingle* cmd) +{ + PPNCommandStruct *ppnCommand; + const UInt32 pageAddr = cmd->block_number << fmi->ppn->device_params.page_address_bits; + Int32 status; + + // We shouldn't use this command going forward - it's a legacy command supported + // for boot-from-NAND code only. + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + ppnCommand = &singlePpnCommands[fmi->bus_id]; + + WMR_MEMSET(ppnCommand, 0, sizeof(PPNCommandStruct)); + + ppnCommand->context.device_info = NULL; + ppnCommand->context.handle = NULL; + ppnCommand->context.bus_num = fmi->bus_id; + + ppnCommand->command = PPN_COMMAND_ERASE; + ppnCommand->options = 0; + ppnCommand->entry[0].ceIdx = 0; + ppnCommand->entry[0].addr.row = pageAddr; + ppnCommand->mem_index[0].offset = 0; + ppnCommand->mem_index[0].idx = 0; + ppnCommand->entry[0].lbas = 0; + ppnCommand->ceInfo[0].pages = 1; + ppnCommand->ceInfo[0].ce = cmd->ce; + ppnCommand->num_pages = 1; + + status = h2fmi_ppn_erase_blocks(fmi, ppnCommand); + if (status != kIOPFMI_STATUS_SUCCESS) + { + cmd->iopfmi.status = status; + } + else if (ppnCommand->page_status_summary == 0x40) + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_ERASE_ERROR; + } +} + +void h2fmi_ppn_iop_read_single(h2fmi_t *fmi, IOPFMI_IOSingle* cmd) +{ + PPNCommandStruct *ppnCommand; + const UInt32 pageAddr = cmd->page_number; + UInt8 *dataBuf = (UInt8 *)mem_static_map_physical(cmd->data_address); + UInt8 *metaBuf = (UInt8 *)mem_static_map_physical(cmd->meta_address); + struct dma_segment dataSegment; + struct dma_segment metaSegment; + + WMR_ASSERT(dataBuf != MAP_FAILED); + WMR_ASSERT(metaBuf != MAP_FAILED); + + // We shouldn't use this command going forward - it's a legacy command supported + // for boot-from-NAND code only. + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + fmi->current_aes_cxt = NULL; + + ppnCommand = &singlePpnCommands[fmi->bus_id]; + + WMR_MEMSET(ppnCommand, 0, sizeof(PPNCommandStruct)); + + ppnCommand->context.device_info = NULL; + ppnCommand->context.handle = NULL; + ppnCommand->context.bus_num = fmi->bus_id; + + ppnCommand->command = PPN_COMMAND_READ; + ppnCommand->options = 0; + + ppnCommand->entry[0].ceIdx = 0; + ppnCommand->entry[0].addr.length = fmi->bytes_per_page + fmi->valid_bytes_per_meta; + ppnCommand->entry[0].addr.column = 0; + ppnCommand->entry[0].addr.row = pageAddr; + ppnCommand->mem_index[0].offset = 0; + ppnCommand->mem_index[0].idx = 0; + ppnCommand->entry[0].lbas = fmi->bytes_per_page / fmi->logical_page_size; + ppnCommand->ceInfo[0].pages = 1; + ppnCommand->ceInfo[0].ce = cmd->ce; + ppnCommand->num_pages = 1; + ppnCommand->lbas = fmi->bytes_per_page / fmi->logical_page_size; + + dataSegment.paddr = (UInt32)dataBuf; + dataSegment.length = fmi->bytes_per_page; + metaSegment.paddr = (UInt32)metaBuf; + metaSegment.length = ppnCommand->lbas * fmi->valid_bytes_per_meta; + +#if FMISS_ENABLED + cmd->iopfmi.status = fmiss_ppn_read_multi(fmi, ppnCommand, &dataSegment, &metaSegment); +#else + cmd->iopfmi.status = h2fmi_ppn_read_multi(fmi, ppnCommand, &dataSegment, &metaSegment); +#endif +} + +void h2fmi_ppn_iop_read_multiple(h2fmi_t *fmi, IOPFMI_IOPpn* cmd) +{ + PPNCommandStruct *ppnCommand; + UInt32 *data_segments_array; + UInt32 *meta_segments_array; + hfmi_aes_iv *aes_iv_array = NULL; + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + ppnCommand = (PPNCommandStruct *)mem_static_map_cached(cmd->ppn_fil_command); + data_segments_array = (UInt32 *)mem_static_map_cached(cmd->data_segments_array); + meta_segments_array = (UInt32 *)mem_static_map_cached(cmd->meta_segments_array); + + WMR_ASSERT(ppnCommand != MAP_FAILED); + WMR_ASSERT(data_segments_array != MAP_FAILED); + WMR_ASSERT(meta_segments_array != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(ppnCommand, cmd->ppn_fil_size); + WMR_PREPARE_READ_BUFFER(data_segments_array, cmd->data_segments_array_length); + WMR_PREPARE_READ_BUFFER(meta_segments_array, cmd->meta_segments_array_length); + + if (cmd->aes_iv_array) + { + aes_iv_array = (hfmi_aes_iv *)mem_static_map_cached(cmd->aes_iv_array); + WMR_ASSERT(aes_iv_array != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(aes_iv_array, cmd->aes_num_chains * sizeof(hfmi_aes_iv)); + } + h2fmi_setup_aes(fmi, &cmd->iopfmi, aes_iv_array, cmd->aes_chain_size, cmd->aes_key_type, (UInt32 *)cmd->aes_key_bytes, NULL); + +#if FMISS_ENABLED + cmd->iopfmi.status = fmiss_ppn_read_multi(fmi, + ppnCommand, + (void *)data_segments_array, + (void *)meta_segments_array); +#else + cmd->iopfmi.status = h2fmi_ppn_read_multi(fmi, + ppnCommand, + (void *)data_segments_array, + (void *)meta_segments_array); +#endif + cmd->geb_ce = fmi->ppn->general_error_ce; + + WMR_PREPARE_WRITE_BUFFER(ppnCommand, cmd->ppn_fil_size); +} + + +void h2fmi_ppn_iop_write_single(h2fmi_t *fmi, IOPFMI_IOSingle* cmd) +{ + PPNCommandStruct *ppnCommand; + const UInt32 pageAddr = cmd->page_number; + UInt8 *dataBuf = (UInt8 *)mem_static_map_physical(cmd->data_address); + UInt8 *metaBuf = (UInt8 *)mem_static_map_physical(cmd->meta_address); + struct dma_segment dataSegment; + struct dma_segment metaSegment; + + WMR_ASSERT(dataBuf != MAP_FAILED); + WMR_ASSERT(metaBuf != MAP_FAILED); + + // We shouldn't use this command going forward - it's a legacy command supported + // for boot-from-NAND code only. + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + fmi->current_aes_cxt = NULL; + + ppnCommand = &singlePpnCommands[fmi->bus_id]; + + WMR_MEMSET(ppnCommand, 0, sizeof(PPNCommandStruct)); + + ppnCommand->context.device_info = NULL; + ppnCommand->context.handle = NULL; + ppnCommand->context.bus_num = fmi->bus_id; + ppnCommand->command = PPN_COMMAND_PROGRAM; + ppnCommand->options = 0; + ppnCommand->entry[0].ceIdx = 0; + ppnCommand->entry[0].addr.row = pageAddr; + ppnCommand->mem_index[0].offset = 0; + ppnCommand->mem_index[0].idx = 0; + ppnCommand->entry[0].lbas = fmi->bytes_per_page / fmi->logical_page_size; + ppnCommand->ceInfo[0].pages = 1; + ppnCommand->ceInfo[0].ce = cmd->ce; + ppnCommand->num_pages = 1; + ppnCommand->lbas = fmi->bytes_per_page / fmi->logical_page_size; + dataSegment.paddr = (UInt32)dataBuf; + dataSegment.length = fmi->bytes_per_page; + metaSegment.paddr = (UInt32)metaBuf; + metaSegment.length = ppnCommand->lbas * fmi->valid_bytes_per_meta; + +#if FMISS_ENABLED + cmd->iopfmi.status = fmiss_ppn_write_multi(fmi, ppnCommand, &dataSegment, &metaSegment); +#else + cmd->iopfmi.status = h2fmi_ppn_write_multi(fmi, ppnCommand, &dataSegment, &metaSegment); +#endif +} + +void h2fmi_ppn_iop_write_multiple(h2fmi_t *fmi, IOPFMI_IOPpn* cmd) +{ + PPNCommandStruct *ppnCommand; + UInt32 *data_segments_array; + UInt32 *meta_segments_array; + hfmi_aes_iv *aes_iv_array = NULL; + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + ppnCommand = (PPNCommandStruct *)mem_static_map_cached(cmd->ppn_fil_command); + data_segments_array = (UInt32 *)mem_static_map_cached(cmd->data_segments_array); + meta_segments_array = (UInt32 *)mem_static_map_cached(cmd->meta_segments_array); + + WMR_ASSERT(ppnCommand != MAP_FAILED); + WMR_ASSERT(data_segments_array != MAP_FAILED); + WMR_ASSERT(meta_segments_array != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(ppnCommand, cmd->ppn_fil_size); + WMR_PREPARE_READ_BUFFER(data_segments_array, cmd->data_segments_array_length); + WMR_PREPARE_READ_BUFFER(meta_segments_array, cmd->meta_segments_array_length); + + if (cmd->aes_iv_array) + { + aes_iv_array = (hfmi_aes_iv *)mem_static_map_cached(cmd->aes_iv_array); + WMR_ASSERT(aes_iv_array != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(aes_iv_array, cmd->aes_num_chains * sizeof(hfmi_aes_iv)); + } + h2fmi_setup_aes(fmi, &cmd->iopfmi, aes_iv_array, cmd->aes_chain_size, cmd->aes_key_type, (UInt32 *)cmd->aes_key_bytes, NULL); + +#if FMISS_ENABLED + cmd->iopfmi.status = fmiss_ppn_write_multi(fmi, + ppnCommand, + (void *)data_segments_array, + (void *)meta_segments_array); +#else + cmd->iopfmi.status = h2fmi_ppn_write_multi(fmi, + ppnCommand, + (void *)data_segments_array, + (void *)meta_segments_array); +#endif + cmd->geb_ce = fmi->ppn->general_error_ce; + WMR_PREPARE_WRITE_BUFFER(ppnCommand, cmd->ppn_fil_size); +} + +void h2fmi_ppn_iop_read_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd) +{ + UInt8 *page_buf = (UInt8 *)cmd->buffer_address; + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + WMR_MEMSET(page_buf, 0xFF, fmi->bytes_per_page + fmi->bytes_per_spare); + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; +} + +void h2fmi_ppn_iop_write_raw(h2fmi_t* fmi, IOPFMI_IORaw* cmd) +{ + panic("Write Raw means nothing on PPN"); +} + +void h2fmi_ppn_iop_read_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd) +{ + const BOOL32 gather_corrections = (0 != cmd->corrections_array); + UInt8 *corrections_array = (gather_corrections + ? (UInt8 *)mem_static_map_cached(cmd->corrections_array) + : NULL); + UInt8 *page_buf = (UInt8 *)mem_static_map_cached(cmd->buffer_address); + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + WMR_ASSERT(corrections_array != MAP_FAILED); + fmi->current_aes_cxt = NULL; + + cmd->iopfmi.status = h2fmi_ppn_read_bootpage(fmi, + cmd->ce, + cmd->page_number, + page_buf, + corrections_array); + + WMR_PREPARE_WRITE_BUFFER(page_buf, H2FMI_BOOT_BYTES_PER_PAGE); + + if (gather_corrections) + { + WMR_PREPARE_WRITE_BUFFER(corrections_array, + fmi->sectors_per_page * sizeof(IOPFMI_correction_t)); + } +} + +void h2fmi_ppn_iop_write_bootpage(h2fmi_t* fmi, IOPFMI_IOBootPage* cmd) +{ + UInt8 *page_buf; + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + page_buf = (UInt8 *)mem_static_map_physical(cmd->buffer_address); + WMR_ASSERT(page_buf != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(page_buf, H2FMI_BOOT_BYTES_PER_PAGE); + + fmi->current_aes_cxt = NULL; + + cmd->iopfmi.status = h2fmi_ppn_write_bootpage(fmi, + cmd->ce, + cmd->page_number, + page_buf); +} + +void h2fmi_ppn_iop_read_cau_bbt(h2fmi_t *fmi, IOPFMI_IOPpn* cmd) +{ + PPNCommandStruct *ppnCommand; + struct dma_segment *sgl; + UInt8 *buf; + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + ppnCommand = (PPNCommandStruct *)mem_static_map_cached(cmd->ppn_fil_command); + sgl = (struct dma_segment *)mem_static_map_cached(cmd->data_segments_array); + WMR_ASSERT(ppnCommand != MAP_FAILED); + WMR_ASSERT(sgl != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(ppnCommand, cmd->ppn_fil_size); + WMR_PREPARE_READ_BUFFER(sgl, cmd->data_segments_array_length); + + buf = (UInt8 *)mem_static_map_cached(sgl[0].paddr); + WMR_ASSERT(buf != MAP_FAILED); + + cmd->iopfmi.status = h2fmi_ppn_read_cau_bbt(fmi, ppnCommand, buf); + cmd->geb_ce = fmi->ppn->general_error_ce; + + WMR_PREPARE_WRITE_BUFFER(buf, fmi->ppn->device_params.blocks_per_cau / 8); + WMR_PREPARE_WRITE_BUFFER(ppnCommand, cmd->ppn_fil_size); +} + +void h2fmi_ppn_iop_get_temperature(h2fmi_t *fmi, IOPFMI_GetTemperature* cmd) +{ + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + +#if SUPPORT_TOGGLE_NAND + if (h2fmi_ppn15_get_temperature(fmi, 0, &(cmd->temperature_celsius))) + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_FAILURE; + } +#else + cmd->iopfmi.status = kIOPFMI_STATUS_FAILURE; +#endif +} + +void h2fmi_ppn_iop_get_controller_info(h2fmi_t *fmi, IOPFMI_GetControllerInfo* cmd) +{ + h2fmi_ppn_device_params_t *params = &fmi->ppn->device_params; + BOOL32 result; + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + h2fmi_ppn_get_fw_version(fmi, cmd->ce, cmd->fw_version); + h2fmi_ppn_get_package_assembly_code(fmi, cmd->ce, cmd->package_assembly_code); + h2fmi_ppn_get_controller_unique_id(fmi, cmd->ce, cmd->controller_unique_id); + h2fmi_ppn_get_controller_hw_id(fmi, cmd->ce, cmd->controller_hw_id); + h2fmi_ppn_get_manufacturer_id(fmi, cmd->ce, cmd->manufacturer_id); + result = h2fmi_ppn_get_device_params(fmi, cmd->ce, params); + WMR_ASSERT(result); + + if (fmi->ppn->spec_version >= PPN_VERSION_1_5_0) + { + h2fmi_ppn_get_marketing_name(fmi, cmd->ce, cmd->marketing_name); + } + + cmd->caus = params->caus_per_channel; + cmd->cau_bits = params->cau_bits; + cmd->blocks_per_cau = params->blocks_per_cau; + cmd->block_bits = params->block_bits; + cmd->pages_per_block_mlc = params->pages_per_block; + cmd->pages_per_block_slc = params->pages_per_block_slc; + cmd->page_address_bits = params->page_address_bits; + cmd->bits_per_cell_bits = params->address_bits_bits_per_cell; + cmd->default_bits_per_cell = params->default_bits_per_cell; + cmd->page_size = params->page_size; + cmd->dies = params->dies_per_channel; + cmd->tRC = params->tRC; + cmd->tREA = params->tREA; + cmd->tREH = params->tREH; + cmd->tRHOH = params->tRHOH; + cmd->tRHZ = params->tRHZ; + cmd->tRLOH = params->tRLOH; + cmd->tRP = params->tRP; + cmd->tWC = params->tWC; + cmd->tWH = params->tWH; + cmd->tWP = params->tWP; + cmd->read_queue_size = params->read_queue_size; + cmd->program_queue_size = params->program_queue_size; + cmd->erase_queue_size = params->erase_queue_size; + cmd->prep_function_buffer_size = params->prep_function_buffer_size; + cmd->tRST = params->tRST_ms; + cmd->tPURST = params->tPURST_ms; + cmd->tSCE = params->tSCE_ms; + cmd->tCERDY = params->tCERDY_us; + + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; +} + +void h2fmi_ppn_iop_get_die_info(h2fmi_t *fmi, IOPFMI_GetDieInfo *cmd) +{ + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + h2fmi_ppn_get_uid(fmi, cmd->ce, cmd->die, cmd->unique_id); + h2fmi_ppn_get_die_chip_id(fmi, cmd->ce, cmd->die, cmd->chip_id); + + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; +} + +void h2fmi_ppn_iop_update_firmware(h2fmi_t *fmi, IOPFMI_UpdateFirmware* cmd) +{ + UInt32 *sgl; + UInt8 fwVerBuffer[NAND_DEV_PARAM_LEN_PPN]; + h2fmi_ce_t ce; + + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + sgl = (UInt32 *)mem_static_map_cached(cmd->sgl); + WMR_ASSERT(sgl != MAP_FAILED); + + WMR_PREPARE_READ_BUFFER(sgl, cmd->sgl_length_in_bytes); + + for (ce = 0; ce < H2FMI_MAX_CE_TOTAL; ce++) + { + if (h2fmi_ppn_get_fw_version(fmi, ce, fwVerBuffer) == TRUE32) + { + cmd->iopfmi.status = h2fmi_ppn_fw_update(fmi, ce, (void *)sgl, cmd->fw_size, ppnFwTypeFw); + } + } +} + +void h2fmi_ppn_iop_post_rst_pre_pwrstate_operations(h2fmi_t* fmi, IOPFMI_PostResetOperations *cmd) +{ + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + if (h2fmi_ppn_post_rst_pre_pwrstate_operations(fmi)) + { + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; + } + else + { + cmd->iopfmi.status = kIOPFMI_STATUS_FAILURE; + } +} + +void h2fmi_ppn_iop_set_power(h2fmi_t *fmi, IOPFMI_SetPower* cmd) +{ + if (fmi->ppn->general_error) + { + cmd->iopfmi.status = kIOPFMI_STATUS_IOP_NOT_READY; + return; + } + + h2fmi_ppn_set_channel_power_state(fmi, cmd->power_state_trans); + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; +} + +void h2fmi_ppn_iop_get_failure_info(h2fmi_t *fmi, IOPFMI_GetFailureInfo* cmd) +{ + h2fmi_ppn_failure_info_t failureInfo; + struct dma_segment *sgl = NULL; + + WMR_ASSERT(fmi->ppn->general_error); + + if (cmd->sgl) + { + sgl = (struct dma_segment *)mem_static_map_cached(cmd->sgl); + WMR_ASSERT(sgl != MAP_FAILED); + WMR_PREPARE_READ_BUFFER(sgl, cmd->sgl_length); + } + + h2fmi_ppn_get_general_error_info(fmi, cmd->ce, &failureInfo, &cmd->rma_buffer_length, sgl); + + if(fmi->ppn->bytes_per_row_address == PPN_1_5_ROW_ADDR_BYTES) + { + cmd->type = failureInfo.failure_info_1_5.type; + } + else + { + cmd->type = failureInfo.failure_info_1_0.type; + } + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; +} + +void h2fmi_ppn_iop_set_feature_list(h2fmi_t *fmi, IOPFMI_SetFeatures* cmd) +{ + void *list = mem_static_map_cached(cmd->list); + UInt32 size = cmd->size; + + h2fmi_ppn_set_feature_list(fmi, list, size / sizeof(ppn_feature_entry_t)); + + cmd->iopfmi.status = kIOPFMI_STATUS_SUCCESS; +} + +void h2fmi_ppn_iop_power_state_changed(h2fmi_t* fmi) +{ +#if H2FMI_PPN_VERIFY_SET_FEATURES + h2fmi_ppn_verify_feature_shadow(fmi); +#endif // H2FMI_PPN_VERIFY_SET_FEATURES +} + +#endif //SUPPORT_PPN diff --git a/drivers/apple/h2fmi/H2fmi_private.h b/drivers/apple/h2fmi/H2fmi_private.h new file mode 100644 index 0000000..35020e6 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_private.h @@ -0,0 +1,718 @@ + +// ***************************************************************************** +// +// File: H2fmi_private.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position; add definitions for extracting value from register +// position +// +// ***************************************************************************** +// +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#ifndef _H2FMI_PRIVATE_H_ +#define _H2FMI_PRIVATE_H_ + +#include "WMRFeatures.h" +#include "WMROAM.h" + +#if (H2FMI_WAIT_USING_ISR) +#include +#endif //H2FMI_WAIT_USING_ISR + +#if H2FMI_EFI +#include "SoC.h" +#else //!H2FMI_EFI +#include +#endif + +#if FMI_VERSION == 0 +#include "H2fmi_8920regs.h" +#elif FMI_VERSION <= 2 +#include "H2fmi_8922regs.h" +#elif FMI_VERSION <= 3 +#include "H2fmi_8940regs.h" +#elif FMI_VERSION <= 4 +#include "H2fmi_8945regs.h" +#elif FMI_VERSION <= 5 +#include "H2fmi_8950regs.h" +#endif + +#if FMI_VERSION > 0 +#define SUPPORT_PPN (1) +#endif + +#if FMI_VERSION > 2 +#define SUPPORT_TOGGLE_NAND (1) +#endif + +#if FMI_VERSION >= 5 +#define SUPPORT_NAND_DLL (1) +#endif + +#include "H2fmi_dma_types.h" + +// ============================================================================= +// preprocessor constants +// ============================================================================= +#define H2FMI_EARLY_EXIT_ARBITRARY_LOOP_CONST 1000 + +#define H2FMI_MAX_RESET_DELAY (50 * 1000) +#define H2FMI_MAX_CE_PER_BUS_POW2 (3UL) +#define H2FMI_MAX_CE_PER_BUS (1UL << H2FMI_MAX_CE_PER_BUS_POW2) +#define H2FMI_MAX_NUM_BUS (2UL) +#define H2FMI_MAX_CE_TOTAL (H2FMI_MAX_CE_PER_BUS * H2FMI_MAX_NUM_BUS) +#define H2FMI_MAX_BANKS_PER_CE (4) +#define H2FMI_MAX_BANKS_TOTAL (H2FMI_MAX_CE_TOTAL * H2FMI_MAX_BANKS_PER_CE) + +#if FMI_VERSION == 0 +#define H2FMI_BYTES_PER_SECTOR (512UL) +#define H2FMI_MAX_META_PER_ENVELOPE (32) +#define H2FMI_MAX_META_PER_LBA (32) +#define H2FMI_MAX_LBA_PER_PAGE (1) +#else +#define H2FMI_BYTES_PER_SECTOR (1024UL) +#define H2FMI_MAX_META_PER_ENVELOPE (63) +#define H2FMI_MAX_META_PER_LBA (16) +#define H2FMI_MAX_LBA_PER_PAGE (4) +#endif +#define H2FMI_WORDS_PER_SECTOR (H2FMI_BYTES_PER_SECTOR / sizeof(UInt32)) + +#define H2FMI_BOOT_SECTORS_PER_PAGE (3UL) +#define H2FMI_BYTES_PER_BOOT_SECTOR (512) +#define H2FMI_BOOT_BYTES_PER_PAGE (H2FMI_BYTES_PER_BOOT_SECTOR * H2FMI_BOOT_SECTORS_PER_PAGE) +#define H2FMI_MAX_SGL_SEGMENTS_PER_RAW (20) + +#define H2FMI_DEFAULT_TIMEOUT_MICROS ((100 * 1000)) +#define H2FMI_PAGE_TIMEOUT_MICROS ((2 * 1000 * 1000)) + +#define H2FMI_NAND_ID_SIZE (8) +#define H2FMI_NAND_ID_COMPARISON_SIZE (4) + +#define UNIQUE_ID_LEN (16) + +#if FMI_VERSION == 0 +#define MAX_ECC_CORRECTION (16) +#else +#define MAX_ECC_CORRECTION (30) +#endif + +#define H2FMI_ALLOWED_STUCK_BITS_IN_FP (2) + +// conservative bus timings used for boot and Read Id during init +#define H2FMI_INIT_READ_CYCLE_NANOS (200) +#define H2FMI_INIT_READ_SETUP_NANOS (200) +#define H2FMI_INIT_READ_HOLD_NANOS (200) +#define H2FMI_INIT_READ_DELAY_NANOS (0) +#define H2FMI_INIT_WRITE_CYCLE_NANOS (200) +#define H2FMI_INIT_WRITE_SETUP_NANOS (200) +#define H2FMI_INIT_WRITE_HOLD_NANOS (200) + +#define H2FMI_INIT_SOC_TO_NAND_RISE_NANOS (10) +#define H2FMI_INIT_SOC_TO_NAND_FALL_NANOS (10) +#define H2FMI_INIT_NAND_TO_SOC_RISE_NANOS (10) +#define H2FMI_INIT_NAND_TO_SOC_FALL_NANOS (10) + +#define METADATA_LOOKUP_SIZE (256) +#define METADATA_MULTIPLY (1664525) +#define METADATA_INCREMENT (1013904223) +#define METADATA_ITERATIONS_TABLE (763) +#define METADATA_ITERATIONS_CRYPT (3) + +#if (FMI_VERSION <= 2) || ((FMI_VERSION == 3) && (FMI_VERSION_MINOR == 0)) +#define H2FMI_DMA_BURST_CYCLES (32) +#else // ((FMI_VERSION == 3) && (FMI_VERSION_MINOR != 0)) || (FMI_VERSION >= 4) +#define H2FMI_DMA_BURST_CYCLES (8) +#endif // ((FMI_VERSION == 3) && (FMI_VERSION_MINOR != 0)) || (FMI_VERSION >= 4) + +#if FMI_VERSION >= 3 +#define FMISS_ENABLED (1) +#endif + +#if FMI_VERSION >= 5 +#define H2FMI_EXTRA_CE_SETUP_TIME_US (10) +#endif // FMI_VERSION >= 5 + +#define H2FMI_IF_CTRL_LOW_POWER \ + (FMC_IF_CTRL__DCCYCLE(0) | \ + FMC_IF_CTRL__REB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | \ + FMC_IF_CTRL__REB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | \ + FMC_IF_CTRL__WEB_SETUP(FMC_IF_CTRL__TIMING_MAX_CLOCKS) | \ + FMC_IF_CTRL__WEB_HOLD(FMC_IF_CTRL__TIMING_MAX_CLOCKS)) + +// ============================================================================= +// type declarations +// ============================================================================= + +typedef UInt16 h2fmi_ce_t; + +typedef UInt8 h2fmi_chipid_t[H2FMI_NAND_ID_SIZE]; + +typedef enum +{ + writeIdle = 0, + writeSetup, + writeWaitForCE, + writeXferData, + writeEndingWrite, + writeEndingWriteWaitCE, + writeDone, + writeWaitingForNumCELimit +} WRITE_STATE; + +typedef enum +{ + readIdle = 0, + readSetup = 1, + readStartWait = 2, + readXferData = 3, + readWaitECCDone = 4, + readDone = 5, +} READ_STATE; + + +typedef enum +{ + fmiNone = 0, + fmiRead = 1, + fmiWrite = 2 +} FMI_MODE; + +#define INVALID_CE_INDEX ( (UInt32)~0 ) + +typedef struct tagFMI_ISR_STATE_MACHINE +{ + FMI_MODE currentMode; + + union + { + WRITE_STATE wr; + READ_STATE rd; + } state; + + UInt32 dirty_ce_mask; + UInt32 page_idx; + UInt32 page_count; + UInt32 currentCE; + UInt32 savedCurrentCE; + UInt32 wMaxOutstandingCEWriteOperations; + UInt32 wOutstandingCEWriteOperations; + struct + { + UInt32 head,tail,count; + UInt32 previousCEIndex[ H2FMI_MAX_CE_PER_BUS ]; + } ceCommitQueue; + + UInt32 lastPageIndex[ H2FMI_MAX_CE_TOTAL ]; + UInt32 currentWriteDie; + UInt32 wVendorType; + UInt32 currentPage; + UInt32 wNumTimesHoldoffExecuted; + + h2fmi_ce_t* chip_enable_array; + UInt32* page_number_array; + + struct dma_segment* data_segment_array; + struct dma_segment* meta_segment_array; + + UInt64 wCmdStartTicks; + UInt64 waitStartTicks; + UInt64 wPageTimeoutTicks; + UInt64 wQuarterPageTimeoutTicks; + + BOOL32 fSuccessful; + + BOOL32 needs_prepare; + UInt32 lastCE; + UInt8* max_corrected_array; + UInt32 clean_pages; + UInt32 fused_pages; + UInt32 uecc_pages; + UInt8* sector_stats; + +#if (H2FMI_WAIT_USING_ISR) + struct task_event stateMachineDoneEvent; +#endif + +} FMI_ISR_STATE_MACHINE, * PFMI_ISR_STATE_MACHINE; + +struct _hfmi_aes_iv +{ + UInt8 aes_iv_bytes[16]; +}; +typedef struct _hfmi_aes_iv hfmi_aes_iv; + +#define _kIOPFMI_STATUS_UNKNOWN ((UInt32) 0) +#define _kIOPFMI_STATUS_SUCCESS ((UInt32) 1) +#define _kIOPFMI_STATUS_BLANK ((UInt32) 2) +#define _kIOPFMI_STATUS_PARAM_INVALID ((UInt32) 0x80000004) +#define _kIOPFMI_STATUS_FMC_DONE_TIMEOUT ((UInt32) 0x8000001C) +#define _kIOPFMI_STATUS_READY_BUSY_TIMEOUT ((UInt32) 0x8000001D) +#define _kIOPFMI_STATUS_ECC_CLEANUP ((UInt32) 0x8000001E) +#define _kIOPFMI_STATUS_ECC_DONE_TIMEOUT ((UInt32) 0x8000001F) +#define _kIOPFMI_STATUS_PPN_GENERAL_ERROR ((UInt32) 0x80000020) +/** + * Special status -- status code from NAND is in lower 16-bits. + */ +#define _kIOPFMI_STATUS_PGM_ERROR ((UInt32) 0x80200000) +#define _kIOPFMI_STATUS_ERASE_ERROR ((UInt32) 0x80210000) +#define _kIOPFMI_STATUS_DMA_DONE_TIMEOUT ((UInt32) 0x80000022) +#define _kIOPFMI_STATUS_NOT_ALL_CLEAN ((UInt32) 0x80000023) +#define _kIOPFMI_STATUS_AT_LEAST_ONE_UECC ((UInt32) 0x80000024) +#define _kIOPFMI_STATUS_FUSED ((UInt32) 0x80000025) + +/** + * Vendor-specific codes ... + */ +#define _kVS_NONE 0 +#define _kVS_HYNIX_2P 1 +#define _kVS_TOSHIBA_2P 2 +#define _kVS_MICRON_2P 3 +#define _kVS_SAMSUNG_2D 4 +#define _kVS_SAMSUNG_2P_2D 5 + +typedef struct _h2fmi_t +{ + UInt32 bus_id; + + UInt32* regs; + + UInt32 clock_speed_khz; + + UInt32 num_of_ce; + UInt32 valid_ces; + BOOL32 is_ppn; + BOOL32 is_ppn_channel_init; + + UInt32 pages_per_block; + UInt32 sectors_per_page; + UInt32 bytes_per_spare; + UInt32 blocks_per_ce; + UInt32 banks_per_ce; + UInt32 total_bytes_per_meta; + UInt32 valid_bytes_per_meta; + UInt32 bytes_per_page; + UInt32 logical_page_size; + UInt32 dies_per_cs; + + UInt32 if_ctrl; +#if !H2FMI_IOP + UInt32 if_ctrl_normal; +#endif // !H2FMI_IOP + UInt32 fmi_config_reg; + UInt32 fmi_data_size_reg; + +#if FMI_VERSION == 4 + BOOL32 read_stream_disable; +#endif // FMI_VERSION == 4 +#if FMI_VERSION >= 5 + UInt32 read_tx_page_delay; +#endif // FMI_VERSION >= 5 + BOOL32 retire_on_invalid_refresh; + + UInt8 correctable_bits; + +#if SUPPORT_TOGGLE_NAND + BOOL32 is_toggle_system; // primary mode of operation (DDR or SDR) + BOOL32 is_toggle; // current state of FMI (DDR or SDR) + UInt32 toggle_if_ctrl; + UInt32 dqs_ctrl; + UInt32 timing_ctrl_1; + UInt32 timing_ctrl_2; + UInt32 useDiffDQS; + UInt32 useDiffRE; + UInt32 useVREF; +#endif // SUPPORT_TOGGLE_NAND + + UInt8 refresh_threshold_bits; + + UInt32 isr_condition; + + struct dma_aes_config aes_cxt; + struct dma_aes_config* current_aes_cxt; + + hfmi_aes_iv* current_aes_iv_array; + UInt32* iv_seed_array; + +#if (H2FMI_WAIT_USING_ISR) + struct task_event isr_event; +#endif + + FMI_ISR_STATE_MACHINE stateMachine; + + struct + { + UInt32 wNumCE_Executed; + UInt32 wOverallOperationFailure; + UInt32 wSingleCEStatus; + UInt32* wCEStatusArray; + UInt32 wCEStatusArrayModulusMask; + UInt32 wFirstFailingCE; + } failureDetails; + + UInt32 wMaxOutstandingCEWriteOperations; + + BOOL32 h2fmi_ppn_panic_on_status_timeout; + + BOOL32 initialized; + struct _h2fmi_ppn_t *ppn; + h2fmi_ce_t activeCe; + UInt8 ceMap[H2FMI_MAX_CE_PER_BUS]; + +#if FMISS_ENABLED + void *fmiss_cxt; + void (*isr_handler)(void *arg); +#endif // FMISS_ENABLED + + UInt32 * error_list; +} h2fmi_t; + +struct _h2fmi_virt_to_phys_map_t +{ + UInt32 bus; + h2fmi_ce_t ce; +}; +typedef struct _h2fmi_virt_to_phys_map_t h2fmi_virt_to_phys_map_t; + +// ============================================================================= +// general fail macro +// ============================================================================= + +#define h2fmi_fail(b) \ + do { \ + WMR_PRINT(ERROR, \ + "[FIL:ERR] FAIL -> %s@%d\n", \ + "", __LINE__); \ + b = FALSE32; \ + } while (0) + +// ============================================================================= +// fmi bus selection macros +// +// Note: this doesn't scale nicely past two buses +// ============================================================================= + +#define h2fmi_select_by_bus(fmi, sel0, sel1) ((fmi->regs == FMI0) ? sel0 : sel1) +#define h2fmi_bus_index(fmi) h2fmi_select_by_bus(fmi, 0, 1) + +// ============================================================================= +// dma-related macros +// ============================================================================= + +#define h2fmi_dma_data_chan(fmi) h2fmi_select_by_bus(fmi, DMA_FMI0DATA, DMA_FMI1DATA) +#define h2fmi_dma_meta_chan(fmi) h2fmi_select_by_bus(fmi, DMA_FMI0CHECK, DMA_FMI1CHECK) + +#define h2fmi_dma_meta_fifo(fmi) ((void*)(((UInt32)fmi->regs) + FMI_META_FIFO)) +#define h2fmi_dma_data_fifo(fmi) ((void*)(((UInt32)fmi->regs) + FMI_DATA_BUF)) + +// ============================================================================= +// busy wait macro +// +// this should only be used for very short waits that should never halt +// during code sequences where performance matters +// ============================================================================= + +#define h2fmi_busy_wait(fmi, reg, mask, cond) \ + do { \ + UInt32 val; \ + do { \ + val = h2fmi_rd(fmi, reg); \ + } while ((val & (mask)) != (cond)); \ + } while (0) + +// ============================================================================= +// register access macros +// ============================================================================= + +#if (H2FMI_TRACE_REG_WRITES) +UInt32 h2fmi_trace_wr(h2fmi_t* fmi, UInt32 reg, UInt32 val); +UInt8 h2fmi_trace_wr8(h2fmi_t* fmi, UInt32 reg, UInt8 val); +UInt32 h2fmc_trace_wr(volatile UInt32* h2fmc_regs, UInt32 reg, UInt32 val); +#define h2fmi_wr(fmi, reg, val) h2fmi_trace_wr(fmi, reg, val) +#define h2fmi_wr8(fmi, reg, val) h2fmi_trace_wr8(fmi, reg, val) +#if H2FMI_INSTRUMENT_BUS_1 +#define h2fmc_wr(fmc_regs, reg, val) h2fmc_trace_wr(fmc_regs, reg, val) +#endif // H2FMI_INSTRUMENT_BUS_1 +#else +#define h2fmi_wr(fmi, reg, val) (*((fmi)->regs + ((reg) >> 2)) = (val)) +#define h2fmi_wr8(fmi, reg, val) (((volatile UInt8*)fmi->regs)[(UInt32)reg] = (UInt8)val) +#if H2FMI_INSTRUMENT_BUS_1 +#define h2fmc_wr(fmc_regs, reg, val) (fmc_regs[((UInt32)reg) >> 2] = (UInt32)val) +#endif // H2FMI_INSTRUMENT_BUS_1 +#endif + +#if (H2FMI_TRACE_REG_READS) +UInt32 h2fmi_trace_rd(h2fmi_t* fmi, UInt32 reg); +UInt8 h2fmi_trace_rd8(h2fmi_t* fmi, UInt32 reg); +#define h2fmi_rd(fmi, reg) h2fmi_trace_rd(fmi, reg) +#define h2fmi_rd8(fmi, reg) h2fmi_trace_rd8(fmi, reg) +#if H2FMI_INSTRUMENT_BUS_1 +#define h2fmc_rd(fmc_regs, reg) h2fmc_trace_rd(fmc_regs, reg) +#endif // H2FMI_INSTRUMENT_BUS_1 +#else +#define h2fmi_rd(fmi, reg) (*(volatile UInt32*)((UInt8*)((fmi)->regs) + (reg))) +#define h2fmi_rd8(fmi, reg) (((volatile UInt8*)fmi->regs)[(UInt32)reg]) +#if H2FMI_INSTRUMENT_BUS_1 +#define h2fmc_rd(fmc_regs, reg) (fmc_regs[((UInt32)reg) >> 2]) +#endif // H2FMI_INSTRUMENT_BUS_1 +#endif + +// ============================================================================= +// nand device command bytes +// ============================================================================= + +#define NAND_CMD__RESET ((UInt8)0xFF) +#define NAND_CMD__READ_ID ((UInt8)0x90) +#define NAND_CMD__READ_STATUS ((UInt8)0x70) +#define NAND_CMD__READ_SS_DIE1 ((UInt8)0xF1) +#define NAND_CMD__READ_SS_DIE2 ((UInt8)0xF2) +#define NAND_CMD__READ_MICRON_DIE_STATUS ((UInt8)0x78) +#define NAND_CMD__READ ((UInt8)0x00) +#define NAND_CMD__READ_CONFIRM ((UInt8)0x30) +#define NAND_CMD__ERASE ((UInt8)0x60) +#define NAND_CMD__ERASE_CONFIRM ((UInt8)0xD0) +#define NAND_CMD__WRITE ((UInt8)0x80) +#define NAND_CMD__WRITE2_HYNIX ((UInt8)0x81) +#define NAND_CMD__WRITE2_SAMSUNG ((UInt8)0x81) +#define NAND_CMD__WRITE_CONFIRM ((UInt8)0x10) +#define NAND_CMD__DUMMY_CONFIRM_HYNIX ((UInt8)0x11) +#define NAND_CMD__DUMMY_CONFIRM_MICRON ((UInt8)0x11) +#define NAND_CMD__DUMMY_CONFIRM_TOSHIBA ((UInt8)0x11) +#define NAND_CMD__DUMMY_CONFIRM_SAMSUNG ((UInt8)0x11) +#define NAND_CMD__CONFIRM_TOSHIBA ((UInt8)0x15) +#define NAND_CMD__TOS_STATUS_71h ((UInt8)0x71) + +#define CHIPID_ADDR (0x00) +#define MfgID_ADDR (0x30) +//Mask corresponding to max of ChipId size and MfgID size +#define MAX_ID_SIZE_MASK (0x0000FFFFFFFFFFFF) +// ============================================================================= +// nand operations timeout specifications +// ============================================================================= + +#define TIMEOUT_MICROSEC_READ ((UInt32)1000) +#define TIMEOUT_MICROSEC_WRITE ((UInt32)5000) +#define TIMEOUT_MICROSEC_ERASE ((UInt32)15000) + +// ============================================================================= +// nand operations status specifications +// ============================================================================= + +#define NAND_STATUS__CHIP_STATUS1 ((UInt8)1 << 0) +#define NAND_STATUS__CHIP_STATUS1_FAIL ((UInt8)1 << 0) +#define NAND_STATUS__CHIP_STATUS1_PASS ((UInt8)0 << 0) +#define NAND_STATUS__TOS_CHIP_STATUS_MASK ((UInt8)0x1f) +#define NAND_STATUS__TOS_CHIP_STATUS_D0 ((UInt8)0x0a) +#define NAND_STATUS__TOS_CHIP_STATUS_D1 ((UInt8)0x014) +#define NAND_STATUS__SS_CHIP_STATUS_P0 ((UInt8)0x2) +#define NAND_STATUS__CHIP_STATUS2 ((UInt8)1 << 1) +#define NAND_STATUS__CHIP_STATUS2_FAIL ((UInt8)1 << 1) +#define NAND_STATUS__CHIP_STATUS2_PASS ((UInt8)0 << 1) +// bits 2-4 are not used +#define NAND_STATUS__PAGE_BUFFER_RB ((UInt8)1 << 5) +#define NAND_STATUS__PAGE_BUFFER_RB_READY ((UInt8)1 << 5) +#define NAND_STATUS__PAGE_BUFFER_RB_BUSY ((UInt8)0 << 5) +#define NAND_STATUS__DATA_CACHE_RB ((UInt8)1 << 6) +#define NAND_STATUS__DATA_CACHE_RB_READY ((UInt8)1 << 6) +#define NAND_STATUS__DATA_CACHE_RB_BUSY ((UInt8)0 << 6) +#define NAND_STATUS__WRITE_PROTECT ((UInt8)1 << 7) +#define NAND_STATUS__WRITE_PROTECT_NOT_PROTECTED ((UInt8)1 << 7) +#define NAND_STATUS__WRITE_PROTECT_PROTECTED ((UInt8)0 << 7) + +// ============================================================================= +// implementation function declarations shared between SecureROM and iBoot +// ============================================================================= + +void h2fmi_reset(h2fmi_t* fmi); + +BOOL32 h2fmi_is_chipid_invalid(h2fmi_chipid_t* const id); + +BOOL32 h2fmi_wait_done(h2fmi_t* fmi, UInt32 reg, UInt32 mask, UInt32 bits); +BOOL32 h2fmi_wait_dma_task_pending(h2fmi_t* fmi); + +void h2fmi_clean_ecc(h2fmi_t* fmi); +void h2fmi_fmc_read_data(h2fmi_t* fmi, UInt32 size, UInt8* data); + +BOOL32 h2fmi_nand_reset(h2fmi_t* fmi, h2fmi_ce_t ce); +BOOL32 h2fmi_nand_read_id(h2fmi_t* fmi, h2fmi_ce_t ce, h2fmi_chipid_t* id, UInt8 addr); + +BOOL32 h2fmi_pio_write_sector(h2fmi_t* fmi, const void* buf, UInt32 len); +BOOL32 h2fmi_pio_read_sector(h2fmi_t* fmi, void* buf, UInt32 len); + +// ============================================================================= +// implementation function declarations not used by SecureROM +// ============================================================================= + +UInt32 h2fmi_get_gate(h2fmi_t* fmi); + +void h2fmi_init_sys(h2fmi_t* fmi); + +#if (!H2FMI_READONLY || AND_SUPPORT_NVRAM) +BOOL32 h2fmi_erase_blocks(h2fmi_t* fmi, UInt32 num_elements, UInt16* ce, UInt32* block, BOOL32* status_failed); +UInt32 h2fmi_write_bootpage(h2fmi_t* fmi, UInt32 ce, UInt32 page, UInt8* data_buf); +#endif //!H2FMI_READONLY + +#if (!H2FMI_READONLY) +BOOL32 h2fmi_write_page(h2fmi_t* fmi, UInt16 ce, UInt32 page, UInt8* data_buf, UInt8* meta_buf, BOOL32* status_failed); +UInt32 h2fmi_write_raw_page(h2fmi_t* fmi, UInt32 ce, UInt32 page, UInt8* data_buf); +#endif //!H2FMI_READONLY + +UInt32 h2fmi_read_page(h2fmi_t* fmi, h2fmi_ce_t ce, UInt32 page, UInt8* data_buf, UInt8* meta_buf, UInt8* max_corrected, UInt8* sector_stats); + +BOOL32 h2fmi_read_multi(h2fmi_t* fmi, UInt32 page_count, h2fmi_ce_t* chip_enable_array, UInt32* page_number_array, struct dma_segment* data_segment_array, struct dma_segment* meta_segment_array, UInt8* max_corrected_array, UInt8* sector_stats); + +#if (defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) +BOOL32 h2fmiGenericNandReadSequence(h2fmi_t *whichFmi, UInt8 phyCE, GenericReadRequest *genericRead); +#endif //(defined(ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) + +BOOL32 h2fmi_reset_and_read_chipids(h2fmi_t* fmi, h2fmi_chipid_t* ids, UInt8 addr); +BOOL32 h2fmi_nand_read_id_all(h2fmi_t* fmi, h2fmi_chipid_t* ids, UInt8 addr); +BOOL32 h2fmi_nand_reset_all(h2fmi_t* fmi); + +BOOL32 h2fmi_write_multi(h2fmi_t* fmi, UInt32 page_count, h2fmi_ce_t* chip_enable_array, UInt32* page_number_array, struct dma_segment* data_segment_array, struct dma_segment* meta_segment_array, BOOL32* status_failed, UInt32 wVendorType); + +void h2fmi_nand_read_chipid(h2fmi_t* fmi, h2fmi_ce_t ce, h2fmi_chipid_t* id); +void h2fmi_build_ce_bitmask(h2fmi_t* fmi, h2fmi_chipid_t* ids, h2fmi_chipid_t* id_filter, UInt8 addr); + +void h2fmi_set_bootpage_data_format(h2fmi_t* fmi); +void h2fmi_set_raw_write_data_format(h2fmi_t* fmi, UInt32 spare_per_sector); +void h2fmi_set_page_format(h2fmi_t* fmi); +void h2fmi_config_page_addr(h2fmi_t* fmi, UInt32 page); + +UInt32 h2fmi_calculate_ecc_bits(h2fmi_t* fmi); +UInt32 h2fmi_calculate_ecc_output_bytes(h2fmi_t* fmi); + +BOOL32 h2fmi_read_raw_page(h2fmi_t* fmi, UInt32 ce, UInt32 page, UInt8* data_buf, UInt8* spare_buf); +UInt32 h2fmi_read_bootpage(h2fmi_t* fmi, UInt32 ce, UInt32 page, UInt8* data_buf, UInt8* max_corrected); +UInt32 h2fmi_read_bootpage_pio(h2fmi_t* fmi, UInt32 ce, UInt32 page, UInt8* data_buf, UInt8* max_corrected); + +void h2fmi_prepare_wait_status(h2fmi_t* fmi, UInt8 io_mask, UInt8 io_cond); +BOOL32 h2fmi_wait_status(h2fmi_t* fmi, UInt8 io_mask, UInt8 io_cond, UInt8* status); + +h2fmi_t *h2fmiTranslateVirtualCEToBus(UInt32 virtualCE); +h2fmi_ce_t h2fmiTranslateVirtualCEToCe(UInt32 virutalCE); + +void h2fmi_set_if_ctrl(h2fmi_t* fmi, UInt32 if_ctrl); +void restoreTimingRegs(h2fmi_t* fmi); + +// ============================================================================= +// implementation function declarations +// ============================================================================= +BOOL32 h2fmi_init(h2fmi_t* fmi, UInt32 interface, h2fmi_chipid_t* ids); +Int32 h2fmiInitVirtToPhysMap(UInt16 busCount, UInt16 bankCount); +void h2fmiMapBankToBusAndEnable(UInt32 bank, UInt32 bus, h2fmi_ce_t enable); +h2fmi_t* h2fmiTranslateBankToBus(UInt32 bank); +h2fmi_ce_t h2fmiTranslateBankToCe(UInt32 bank); +void h2fmi_fmc_enable_ce(h2fmi_t* fmi, h2fmi_ce_t ce); +void h2fmi_fmc_disable_ce(h2fmi_t* fmi, h2fmi_ce_t ce); +void h2fmi_fmc_disable_all_ces(h2fmi_t* fmi); +void h2fmi_aes_iv(void* arg, UInt32 chunk_index, void* iv_buffer); +void h2fmi_whitening_iv(void* arg, UInt32 chunk_index, void* iv_buffer); + +// ============================================================================= +// implementation function declarations used only for debug during development +// +// note that these are designed so that the calls will disappear when +// not compiling for debug +// ============================================================================= + +#if (H2FMI_DEBUG) + +BOOL32 h2fmi_test_hook(h2fmi_t* fmi); + +void h2fmi_dump_config(h2fmi_t* fmi); +void h2fmi_dump_status_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_dump_fmi_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_dump_fmc_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_dump_ecc_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_dump_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_dump_buffer(UInt8* buf, UInt32 size); +void h2fmi_spew_regs(h2fmi_t* fmi, const char* prefix); + +#else // H2FMI_DEBUG + +#define h2fmi_test_hook(fmi_ignored) (TRUE32) + +#define h2fmi_dump_config(fmi_ignored) +#define h2fmi_dump_status_regs(fmi_ignored, prefix_ignored) +#define h2fmi_dump_fmi_regs(fmi_ignored, prefix_ignored) +#define h2fmi_dump_fmc_regs(fmi_ignored, prefix_ignored) +#define h2fmi_dump_ecc_regs(fmi_ignored, prefix_ignored) +#define h2fmi_dump_regs(fmi_ignored, prefix_ignored) +#define h2fmi_dump_buffer(buf_ignored, size_ignored) + +#endif // H2FMI_DEBUG + +#if SUPPORT_TOGGLE_NAND +#define turn_on_fmc(fmi) (h2fmi_wr((fmi), FMC_ON, FMC_ON__ENABLE | (((fmi)->is_toggle) ? (FMC_ON__DDR_NAND_TYPE_TOGGLE | FMC_ON__DDR_ENABLE) : 0))) +#else +#define turn_on_fmc(fmi) (h2fmi_wr((fmi), FMC_ON, FMC_ON__ENABLE)) +#endif + +void h2fmi_handle_write_ISR_state_machine( h2fmi_t* fmi ); +void h2fmi_handle_read_ISR_state_machine( h2fmi_t* fmi ); + +typedef enum +{ + CE_TIMEOUT, + CE_BUSY, + CE_IDLE +} CE_STATE; + +CE_STATE h2fmi_get_current_CE_state( h2fmi_t* fmi ); +BOOL32 h2fmi_tick_delta_timeout(UInt64 wStartTick, UInt64 wMaxDeltaTick); + +void h2fmi_clear_interrupts_and_reset_masks(h2fmi_t* fmi); +void h2fmi_prepare_for_ready_busy_interrupt(h2fmi_t* fmi); +void h2fmi_set_page_format_and_ECC_level(h2fmi_t* fmi, UInt32 wErrorAlertLevel); +BOOL32 h2fmi_common_idle_handler( h2fmi_t* fmi ); + +BOOL32 h2fmi_start_dma( h2fmi_t* fmi ); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) +extern void h2fmi_instrument_bit_set(int iBit); +extern void h2fmi_instrument_bit_clear(int iBit); +#endif + +UInt32 h2fmi_calculate_fmi_config(h2fmi_t* fmi); +UInt32 h2fmi_calculate_fmi_data_size(h2fmi_t* fmi); + +void h2fmi_restoreFmiRegs(h2fmi_t *fmi); +void fmiss_init_sequences(h2fmi_t *fmi); +UInt32 h2fmi_rx_check_page_ecc(h2fmi_t* fmi, UInt32 ecc_pnd, UInt8* max_corrected, UInt8* sector_stats, UInt32 sectors_per_page); + +#if FMISS_ENABLED +void fmiss_raw_init_sequences(h2fmi_t *fmi); +#endif // FMISS_ENABLED + +#if SUPPORT_TOGGLE_NAND && !APPLICATION_EMBEDDEDIOP +void transitionWorldFromDDR(UInt32 powerstate_to); +void transitionWorldToDDR(UInt32 powerstate_from); +#endif + +#if !APPLICATION_EMBEDDEDIOP +void h2fmi_ppn_all_channel_power_state_transition(UInt32 ps_tran); +#endif // !APPLICATION_EMBEDDEDIOP + + +#if SUPPORT_NAND_DLL +BOOL32 h2fmiTrainDLL(UInt32 *lock); +#endif + +#endif // _H2FMI_PRIVATE_H_ + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_read.c b/drivers/apple/h2fmi/H2fmi_read.c new file mode 100644 index 0000000..d9b09b6 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_read.c @@ -0,0 +1,1514 @@ +// ***************************************************************************** +// +// File: H2fmi_read.c +// +// ***************************************************************************** +// +// Notes: +// +// - DMA_FMI0CHECK & DMA_FMI1CHECK names in hwdmachannels.h is a bit funny; +// consider getting changed to DMA_FMI0META & DMA_FMI1META +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" +#include "H2fmi.h" +#include +#include "H2fmi_dma.h" + +/** + * Define the following to 'simulate' NAND read errors. + * ( and select an error type below ) + */ +//??#define SIMULATE_READ_FAILURES + +#if defined(SIMULATE_READ_FAILURES) +#define STICKY_READ_FAILURES +#define READ_FAILURE_MAGIC_NUMBER (159871/10) +static unsigned long ulFailureCount = 0; +static UInt32 ulSimulatedFailingCE = ~0;; +static UInt32 ulSimulatedFailingPage = ~0; +#define READ_FAILURE_STATUS_TYPE _kIOPFMI_STATUS_AT_LEAST_ONE_UECC +//??#define READ_FAILURE_STATUS_TYPE _kIOPFMI_STATUS_BLANK +//??#define READ_FAILURE_STATUS_TYPE _kIOPFMI_STATUS_FUSED +//??#define READ_FAILURE_STATUS_TYPE _kIOPFMI_STATUS_ECC_DONE_TIMEOUT +#endif + +#if (defined (AND_COLLECT_FIL_STATISTICS) && AND_COLLECT_FIL_STATISTICS) +extern FILStatistics stFILStatistics; +#endif + +// ============================================================================= +// private implementation function declarations +// ============================================================================= +typedef struct +{ + enum + { + kh2fmi_sector_status_normal, + kh2fmi_sector_status_clean, + kh2fmi_sector_status_clean_with_stuck, + kh2fmi_sector_status_fused, + kh2fmi_sector_status_uecc + } status; + + UInt32 error_cnt; +} h2fmi_sector_status; + +static void h2fmi_read_page_start(h2fmi_t* fmi, UInt32 page); +static void h2fmi_prepare_read(h2fmi_t* fmi, UInt32 page_idx, h2fmi_ce_t* chip_enable_array, UInt32* page_number_array ); +static BOOL32 h2fmi_complete_read_page_start(h2fmi_t* fmi); +static BOOL32 h2fmi_rx_raw(h2fmi_t* fmi, UInt8* data_buf, UInt8* spare_buf); +#if FMI_VERSION == 0 +static void read_raw_sgl_prep(struct dma_segment* data_sgl, struct dma_segment* meta_sgl, UInt8* buf1, UInt8* buf2, UInt32 bytes_per_page, UInt32 bytes_per_spare); +#endif //FMI_VERSION == 0 + +#if FMI_VERSION > 0 +static h2fmi_sector_status h2fmi_rx_check_sector_ecc(h2fmi_t* fmi); +#endif + +static UInt32 h2fmi_dma_rx_complete(h2fmi_t* fmi, UInt32 ecc_pend, UInt8* max_corrected, UInt8* sector_stats); +static void h2fmi_reset_ecc(h2fmi_t* fmi); + +// ============================================================================= +// extern implementation function definitions +// ============================================================================= +UInt32 h2fmi_read_bootpage_pio(h2fmi_t* fmi, + UInt32 ce, + UInt32 page, + UInt8* buf, + UInt8* max_corrected) +{ + UInt32 result; + UInt32 i; + UInt32 ecc_pend; + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_reset_ecc(fmi); + + // enable specified NAND device + h2fmi_fmc_enable_ce(fmi, ce); + + // start a nand page read operation + h2fmi_read_page_start(fmi, page); + if (!h2fmi_complete_read_page_start(fmi)) + { + h2fmi_fail(result); + } + else + { + // Set page format to enable seed scrambling before pushing seeds into FIFO + h2fmi_set_bootpage_data_format(fmi); + +#if FMI_VERSION > 3 + UInt32 sector; + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__RESET_SEED); + // Fill randomizer seeds based on page address + for (sector = 0; sector < H2FMI_BOOT_SECTORS_PER_PAGE; sector++) + { + h2fmi_wr(fmi, FMI_SCRAMBLER_SEED_FIFO, page + sector); + } +#endif + + // Since we're transferring a strange page size, we'll still make FMI deal with this + // operation by individual sectors by just looping over all sectors, starting an FMI operation, + // and waiting for a LAST_FMC_DONE interrupt. + + for (i = 0; i < H2FMI_BOOT_SECTORS_PER_PAGE; i++) + { + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + if (!h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE)) + { + h2fmi_fail(result); + } + else + { + h2fmi_pio_read_sector(fmi, buf, H2FMI_BYTES_PER_BOOT_SECTOR); + buf += H2FMI_BYTES_PER_BOOT_SECTOR; + } + } + } + + // disable NAND device + h2fmi_fmc_disable_ce(fmi, ce); + + // Get ECC stats + ecc_pend = h2fmi_rd(fmi, ECC_PND); + h2fmi_wr(fmi, ECC_PND, ecc_pend); + result = h2fmi_rx_check_page_ecc(fmi, ecc_pend, max_corrected, NULL, H2FMI_BOOT_SECTORS_PER_PAGE); + + h2fmi_clear_interrupts_and_reset_masks(fmi); + + h2fmi_reset(fmi); + + return result; +} + + +UInt32 h2fmi_read_bootpage(h2fmi_t* fmi, + UInt32 ce, + UInt32 page, + UInt8* buf, + UInt8* max_corrected) +{ + UInt32 result; + UInt32 i; + struct dma_segment sgl; + UInt32 ecc_pend; + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + // enable specified NAND device + h2fmi_fmc_enable_ce(fmi, ce); + + sgl.paddr = (UInt32)buf; + sgl.length = H2FMI_BOOT_BYTES_PER_PAGE; + + // start a nand page read operation + h2fmi_read_page_start(fmi, page); + if (!h2fmi_complete_read_page_start(fmi)) + { + h2fmi_fail(result); + } + else + { + // Start DMA for entire operation (regardless of FMI sector/page size capabilities) + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + &sgl, + h2fmi_dma_data_fifo(fmi), + H2FMI_BOOT_BYTES_PER_PAGE, + sizeof(UInt32), + 32, + NULL); + + // Since we're transferring a strange page size, we'll still make FMI deal with this + // operation by individual sectors by just looping over all sectors, starting an FMI operation, + // and waiting for a LAST_FMC_DONE interrupt. + h2fmi_set_bootpage_data_format(fmi); + +#if FMI_VERSION > 3 + UInt32 sector; + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__RESET_SEED); + // Fill randomizer seeds based on page address + for (sector = 0; sector < H2FMI_BOOT_SECTORS_PER_PAGE; sector++) + { + h2fmi_wr(fmi, FMI_SCRAMBLER_SEED_FIFO, page + sector); + } +#endif + + for (i = 0; i < H2FMI_BOOT_SECTORS_PER_PAGE; i++) + { + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + if (!h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE)) + { + h2fmi_fail(result); + } + } + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_fail(result); + } + } + + // disable NAND device + h2fmi_fmc_disable_ce(fmi, ce); + + // Get ECC stats + ecc_pend = h2fmi_rd(fmi, ECC_PND); + h2fmi_wr(fmi, ECC_PND, ecc_pend); + result = h2fmi_rx_check_page_ecc(fmi, ecc_pend, max_corrected, NULL, H2FMI_BOOT_SECTORS_PER_PAGE); + + h2fmi_clear_interrupts_and_reset_masks(fmi); + + h2fmi_reset(fmi); + + return result; +} + +BOOL32 h2fmi_read_raw_page(h2fmi_t* fmi, + UInt32 ce, + UInt32 page, + UInt8* data_buf, + UInt8* spare_buf) +{ + BOOL32 result = TRUE32; + + // enable specified nand device + h2fmi_fmc_enable_ce(fmi, ce); + + // start a nand page read operation + h2fmi_read_page_start(fmi, page); + if (!h2fmi_complete_read_page_start(fmi)) + { + h2fmi_fail(result); + } + else + { + result = h2fmi_rx_raw(fmi,data_buf,spare_buf); + } + + // disable all nand devices + h2fmi_fmc_disable_ce(fmi, ce); + + h2fmi_clear_interrupts_and_reset_masks(fmi); + + return result; +} + + +BOOL32 h2fmi_rx_raw(h2fmi_t* fmi, + UInt8* data_buf, + UInt8* spare_buf) +{ +#if FMI_VERSION == 0 + const UInt32 kReadChunks = fmi->bytes_per_page / H2FMI_BYTES_PER_SECTOR; // varies by FMI version + UInt32 i = 0; + UInt32 spareBytesLeft; + struct dma_segment data_sgl[H2FMI_MAX_SGL_SEGMENTS_PER_RAW]; + struct dma_segment meta_sgl[H2FMI_MAX_SGL_SEGMENTS_PER_RAW]; + BOOL32 result = TRUE32; + + read_raw_sgl_prep(data_sgl, + meta_sgl, + data_buf, + spare_buf, + fmi->bytes_per_page, + fmi->bytes_per_spare); + + // use CDMA to feed meta buffer to FMI + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_meta_chan(fmi), + meta_sgl, + h2fmi_dma_meta_fifo(fmi), + fmi->bytes_per_spare, + sizeof(UInt8), + 1, + NULL); + + // use CDMA to suck data buffer from FMI + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + data_sgl, + h2fmi_dma_data_fifo(fmi), + fmi->bytes_per_page, + sizeof(UInt32), + 32, + NULL); + + spareBytesLeft = fmi->bytes_per_spare; + + for (i = 0; i < kReadChunks; i++) + { + + UInt32 metaBytesThisEnvelope = WMR_MIN(H2FMI_MAX_META_PER_ENVELOPE, spareBytesLeft); + + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__DMA_BURST__32_CYCLES | + FMI_CONFIG__LBA_MODE__BYPASS_ECC | + FMI_CONFIG__META_PER_ENVELOPE(metaBytesThisEnvelope) | + FMI_CONFIG__META_PER_PAGE(metaBytesThisEnvelope) | + FMI_CONFIG__PAGE_SIZE__512); + + h2fmi_wr(fmi, FMI_CONTROL, (FMI_CONTROL__MODE__READ | FMI_CONTROL__START_BIT)); + h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE); + + spareBytesLeft = spareBytesLeft - metaBytesThisEnvelope; + } + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_fail(result); + } + return result; + +#else // FMI_VERSION == 0 + const UInt32 kFMIMainSectorsToRead = fmi->bytes_per_page / H2FMI_BYTES_PER_SECTOR; + struct dma_segment data_sgl; + BOOL32 result = TRUE32; + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + data_sgl.paddr = (UInt32) data_buf; + data_sgl.length = fmi->bytes_per_page; + + // use CDMA to suck data buffer from FMI + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + &data_sgl, + h2fmi_dma_data_fifo(fmi), + fmi->bytes_per_page, + sizeof(UInt32), + 32, + NULL); + + // First read the main data + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_CORRECTABLE_BITS(0) | FMI_CONFIG__DMA_BURST__32_CYCLES); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(kFMIMainSectorsToRead))); + + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE); + + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_fail(result); + } + if (result) + { + // Now pick up the spare - we'll round this up to the nearest DWORD because the DMA will hang otherwise + UInt32 rounded_len = ROUNDUPTO(fmi->bytes_per_spare, sizeof(UInt32)); + + data_sgl.paddr = (UInt32) spare_buf; + data_sgl.length = rounded_len; + + // use CDMA to suck data buffer from FMI + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + &data_sgl, + h2fmi_dma_data_fifo(fmi), + rounded_len, + sizeof(UInt32), + 1, + NULL); + + + + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_CORRECTABLE_BITS(0) | FMI_CONFIG__DMA_BURST__1_CYCLES); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(rounded_len) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1))); + + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE); + + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_fail(result); + } + } + return result; + +#endif //FMI_VERSION != 0 +} + +#if FMI_VERSION == 0 +static void read_raw_sgl_prep(struct dma_segment* data_sgl, + struct dma_segment* meta_sgl, + UInt8* data_buf, + UInt8* spare_buf, + UInt32 bytes_per_page, + UInt32 bytes_per_spare) +{ + UInt32 metaChannelBytesLeft = bytes_per_spare; + UInt32 dataChannelBytesLeft = bytes_per_page; + UInt32 bytesHandled; + UInt32 data_index, meta_index; + BOOL32 inBuf1, skipData, skipMeta; + + data_index = 0; + meta_index = 0; + inBuf1 = TRUE32; // tells if we are populating buf1 or buf2 + + // The following code has 2 divisions: one for data channel other for meta channel. + // When we reach the boundary of buf1 we will have to skip one of the division. + skipData = FALSE32; + skipMeta = FALSE32; + + bytesHandled = 0; + while(dataChannelBytesLeft > 0 || metaChannelBytesLeft > 0) + { + if (!skipData) + { + if (bytesHandled != bytes_per_page) + { + data_sgl[data_index].paddr = ((data_index == 0 && meta_index == 0) ? (UInt32)data_buf : meta_sgl[meta_index - 1].paddr + meta_sgl[meta_index - 1].length); + data_sgl[data_index].length = WMR_MIN(H2FMI_BYTES_PER_SECTOR, dataChannelBytesLeft); + } + else // transitioning from buf1 to buf2 + { + data_sgl[data_index].paddr = (UInt32)spare_buf; + if (skipMeta) + { + // data from one envelope got split into the end of buf1 and beginning of buf2 + // here we making sure that begining of buf2 gets the remaining data of that envelope + // setting length to the remaining data in that envelope + data_sgl[data_index].length = WMR_MIN(H2FMI_BYTES_PER_SECTOR, dataChannelBytesLeft + data_sgl[data_index - 1].length) - data_sgl[data_index - 1].length; + } + else + { + // this happens when buf1 boundary coincides with the end of meta data from the envelope i.e. no splitting happens + data_sgl[data_index].length = WMR_MIN(H2FMI_BYTES_PER_SECTOR, dataChannelBytesLeft); + } + inBuf1 = FALSE32; + } + if (skipMeta) + { + skipMeta = FALSE32; + } + + bytesHandled += data_sgl[data_index].length; + if (inBuf1 && bytesHandled > bytes_per_page) // if we have overshot buf1 boundary + { + bytesHandled -= data_sgl[data_index].length; // undo the last increment in bytesHandled + data_sgl[data_index].length = bytes_per_page - bytesHandled; // set up the length correctly + bytesHandled += data_sgl[data_index].length; // now increment bytesHandled with the correct value + skipMeta = TRUE32; + } + dataChannelBytesLeft -= data_sgl[data_index].length; + data_index++; + + } + + if (!skipMeta) + { + if (bytesHandled != bytes_per_page) + { + meta_sgl[meta_index].paddr = data_sgl[data_index - 1].paddr + data_sgl[data_index - 1].length; + meta_sgl[meta_index].length = WMR_MIN(H2FMI_MAX_META_PER_ENVELOPE, metaChannelBytesLeft); + } + else // transitioning from buf1 to buf2 + { + meta_sgl[meta_index].paddr = (UInt32)spare_buf; + if (skipData) + { + // meta data from one envelope got split into the end of buf1 and beginning of buf2 + // here we making sure that begining of buf2 gets the remaining meta data of that envelope + // setting length to the remaining meta data in that envelope + meta_sgl[meta_index].length = WMR_MIN(H2FMI_MAX_META_PER_ENVELOPE, metaChannelBytesLeft + meta_sgl[meta_index - 1].length) - meta_sgl[meta_index - 1].length; + } + else + { + // this happens when buf1 boundary coincides with the end of data from the envelope i.e. no splitting happens + meta_sgl[meta_index].length = WMR_MIN(H2FMI_MAX_META_PER_ENVELOPE, metaChannelBytesLeft); + } + inBuf1 = FALSE32; + } + if (skipData) + { + skipData = FALSE32; + } + + bytesHandled += meta_sgl[meta_index].length; + if (inBuf1 && bytesHandled > bytes_per_page) // if we have overshot buf1 boundary + { + bytesHandled -= meta_sgl[meta_index].length; // undo the last increment in bytesHandled + meta_sgl[meta_index].length = bytes_per_page - bytesHandled; // set up the length correctly + bytesHandled += meta_sgl[meta_index].length; // now increment bytesHandled with the correct value + skipData = TRUE32; + } + metaChannelBytesLeft -= meta_sgl[meta_index].length; + meta_index++; + } + } +} +#endif //FMI_VERSION == 0 + +void h2fmi_prepare_read( h2fmi_t* fmi, UInt32 page_idx, + h2fmi_ce_t* chip_enable_array, + UInt32* page_number_array ) +{ + const h2fmi_ce_t chip_enable = chip_enable_array[page_idx]; + const UInt32 page_number = page_number_array[page_idx]; + + h2fmi_fmc_enable_ce(fmi, chip_enable); + + // start a nand page read operation, but don't wait for ready + h2fmi_read_page_start(fmi, page_number); + + fmi->failureDetails.wNumCE_Executed++; + fmi->stateMachine.currentCE = chip_enable; +} + +void _nandCmd(h2fmi_t* fmi, UInt8 cmd) +{ + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(cmd)); + + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + h2fmi_busy_wait(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE, FMC_STATUS__CMD1DONE); + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE); +} + +void _nandAddrSingleCycle(h2fmi_t* fmi, UInt8 addr) +{ + h2fmi_wr(fmi, FMC_ADDR0, FMC_ADDR0__SEQ0(addr)); + + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(0)); + + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__ADDR_MODE); + + h2fmi_busy_wait(fmi, FMC_STATUS, FMC_STATUS__ADDRESSDONE, FMC_STATUS__ADDRESSDONE); + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__ADDRESSDONE); +} + +#if (defined (ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) +BOOL32 h2fmiGenericNandReadSequence(h2fmi_t* fmi, UInt8 ce, GenericReadRequest *genericRead) +{ + UInt8 i; + BOOL32 result = TRUE32; + h2fmi_reset(fmi); + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + h2fmi_nand_reset(fmi, ce); + h2fmi_fmc_enable_ce(fmi, ce); + if (!h2fmi_wait_status(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY, + NULL)) + { + h2fmi_fail(result); + h2fmi_fmc_disable_ce(fmi, ce); + return result; + } + + if (genericRead->arrCmd != NULL) + { + for (i=0; icmdSize; i++) + { + _nandCmd(fmi, genericRead->arrCmd[i]); + } + } + if (genericRead->arrAddr != NULL) + { + for (i=0; iaddrSize; i++) + { + _nandAddrSingleCycle(fmi, genericRead->arrAddr[i]); + } + } + if (genericRead->arrConfirmCmd != NULL) + { + for (i=0; iconfirmCmdSize; i++) + { + _nandCmd(fmi, genericRead->arrConfirmCmd[i]); + } + } + + if (!h2fmi_complete_read_page_start(fmi)) + { + h2fmi_fail(result); + } + else + { +#if FMI_VERSION == 0 + h2fmi_wr(fmi, FMI_CONFIG, (FMI_CONFIG__LBA_MODE__BYPASS_ECC | + FMI_CONFIG__META_PER_ENVELOPE(0) | + FMI_CONFIG__META_PER_PAGE(0) | + FMI_CONFIG__PAGE_SIZE__512)); +#else + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_CORRECTABLE_BITS( 0 )); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_SECTOR(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(genericRead->bytesToRead) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1))); +#endif + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + if (!h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE)) + { + h2fmi_fail(result); + } + else + { + result = h2fmi_pio_read_sector(fmi, genericRead->buf, genericRead->bytesToRead); + } + } + h2fmi_fmc_disable_ce(fmi, ce); + h2fmi_clear_interrupts_and_reset_masks(fmi); + h2fmi_nand_reset(fmi, ce); + h2fmi_fmc_enable_ce(fmi, ce); + if (!h2fmi_wait_status(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY, + NULL)) + { + h2fmi_fail(result); + } + + h2fmi_fmc_disable_ce(fmi, ce); + return result; +} +#endif //(defined (ENABLE_VENDOR_UNIQUE_QUERIES) && ENABLE_VENDOR_UNIQUE_QUERIES) + + +#if !FMISS_ENABLED + +UInt32 h2fmi_read_multi(h2fmi_t* fmi, + UInt32 page_count, + h2fmi_ce_t* chip_enable_array, + UInt32* page_number_array, + struct dma_segment* data_segment_array, + struct dma_segment* meta_segment_array, + UInt8* max_corrected_array, + UInt8* sector_stats) +{ + BOOL32 result = TRUE32; + UInt32 clean_pages = 0; + UInt32 fused_pages = 0; + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_set(0); + // TODO: figure out why this PIO-specific workaround seems to + // also be needed for DMA-based operation + h2fmi_instrument_bit_clear(0); + h2fmi_instrument_bit_set(0); +#endif + + WMR_ENTER_CRITICAL_SECTION(); + { + fmi->stateMachine.chip_enable_array = chip_enable_array; + fmi->stateMachine.page_number_array = page_number_array; + fmi->stateMachine.data_segment_array = data_segment_array; + fmi->stateMachine.meta_segment_array = meta_segment_array; + fmi->stateMachine.max_corrected_array = max_corrected_array; + fmi->stateMachine.sector_stats = sector_stats; + fmi->stateMachine.clean_pages = 0; + fmi->stateMachine.uecc_pages = 0; + fmi->stateMachine.fused_pages = 0; + fmi->stateMachine.state.rd = readIdle; + fmi->stateMachine.page_count = page_count; + + h2fmi_reset(fmi); + + fmi->stateMachine.currentMode = fmiRead; + } + WMR_EXIT_CRITICAL_SECTION(); + + h2fmi_reset_ecc(fmi); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_set(1); +#endif +#if (H2FMI_WAIT_USING_ISR) + static const utime_t clockDelay_uSec = 50000; // every 50 mSec +#endif + volatile READ_STATE* pState = &fmi->stateMachine.state.rd; +#if (H2FMI_WAIT_USING_ISR) + event_unsignal(&fmi->stateMachine.stateMachineDoneEvent); +#endif + do + { + if ( readDone == (*pState) ) + { + break; + } + WMR_ENTER_CRITICAL_SECTION(); + h2fmi_handle_read_ISR_state_machine(fmi); + WMR_EXIT_CRITICAL_SECTION(); + +#if !(H2FMI_WAIT_USING_ISR) + WMR_YIELD(); + } + while ( readDone != (*pState) ); +#else + } + while ( !event_wait_timeout(&fmi->stateMachine.stateMachineDoneEvent, clockDelay_uSec) ); +/** + * Allow for early wakeup + */ + { + UInt32 iLoopCount = 0; + while ( readDone != (*pState) ) + { + WMR_YIELD(); + if ( ++iLoopCount>H2FMI_EARLY_EXIT_ARBITRARY_LOOP_CONST ) + { + iLoopCount = 0; + /** + * Allow the state machine a timeslice in case the HW gets + * stuck. + */ + WMR_ENTER_CRITICAL_SECTION(); + h2fmi_handle_read_ISR_state_machine(fmi); + WMR_EXIT_CRITICAL_SECTION(); + } + } + } +#endif +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_clear(1); +#endif + + /** + * Finally check the outcome from our state machine + */ + result = fmi->stateMachine.fSuccessful; + + if ( result ) + { + /** + * ensure that system DMA is complete -- note that if we already + * are in an error state we skip this test as it adds an + * addition H2FMI_PAGE_TIMEOUT_MICROS to the overall operation. + */ + // both dma streams should be complete now + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_fail(result); + + WMR_PANIC("Timeout waiting for CDMA during successful NAND read operation"); + + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + + fmi->failureDetails.wOverallOperationFailure = _kIOPFMI_STATUS_DMA_DONE_TIMEOUT; + } + else + { + fmi->failureDetails.wOverallOperationFailure = _kIOPFMI_STATUS_SUCCESS; + } + } + else + { + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + + // Whoever set the FSM fSuccessful flag to FALSE is responsible + // for telling Darwin why. + WMR_ASSERT(fmi->failureDetails.wOverallOperationFailure != _kIOPFMI_STATUS_UNKNOWN); + } + + /** + * Reset our current mode so that interrupts are not re-directed + * to our state machine. + */ + fmi->stateMachine.currentMode = fmiNone; + + clean_pages = fmi->stateMachine.clean_pages; + fused_pages = fmi->stateMachine.fused_pages; + + if (fmi->failureDetails.wOverallOperationFailure == _kIOPFMI_STATUS_SUCCESS) + { + // Only bother to check for ECC/clean/etc pages if we didn't get any sort of hardware error + if( clean_pages > 0 ) + { + // We have at least one clean page. If ALL are clean, return a clean result. + // Otherwise (if there was a mix of clean and non-clean pages), treat this like + // an uncorrectable ECC error. + fmi->failureDetails.wOverallOperationFailure = (clean_pages < page_count) ? _kIOPFMI_STATUS_NOT_ALL_CLEAN : _kIOPFMI_STATUS_BLANK; + } + else if (fused_pages) + { + fmi->failureDetails.wOverallOperationFailure = (fused_pages < page_count) ? _kIOPFMI_STATUS_AT_LEAST_ONE_UECC : _kIOPFMI_STATUS_FUSED; + } + else if (fmi->stateMachine.uecc_pages > 0) + { + result = FALSE32; + fmi->failureDetails.wOverallOperationFailure = _kIOPFMI_STATUS_AT_LEAST_ONE_UECC; + } + } + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_clear(0); +#endif + + h2fmi_clear_interrupts_and_reset_masks(fmi); + + return fmi->failureDetails.wOverallOperationFailure; +} + +#endif /* !FMISS_ENABLED */ + +// ============================================================================= +// static implementation function definitions +// ============================================================================= + +static void h2fmi_read_page_start(h2fmi_t* fmi, + UInt32 page) +{ + const UInt32 cmd1_addr_cmd2_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD2DONE | + FMC_STATUS__CMD1DONE); + + // configure FMC for cmd1/addr/cmd2 sequence + h2fmi_config_page_addr(fmi, page); + h2fmi_wr(fmi, FMC_CMD, (FMC_CMD__CMD2(NAND_CMD__READ_CONFIRM) | + FMC_CMD__CMD1(NAND_CMD__READ))); + + // start cmd1/addr/cmd2 sequence + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD2_MODE | + FMC_RW_CTRL__CMD1_MODE)); + + // busy wait until cmd1/addr/cmd2 sequence completed; this should + // be very short and should always complete, so no timeout or + // yielding is being done to improve performance + h2fmi_busy_wait(fmi, FMC_STATUS, cmd1_addr_cmd2_done, cmd1_addr_cmd2_done); + h2fmi_wr(fmi, FMC_STATUS, cmd1_addr_cmd2_done); +} + +static BOOL32 h2fmi_complete_read_page_start(h2fmi_t* fmi) +{ + + BOOL32 result = TRUE32; + + // wait for ready using Read Status command + if (!h2fmi_wait_status(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY, + NULL)) + { + h2fmi_fail(result); + } + else + { + // reissue cmd1 + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ)); + h2fmi_wr(fmi, FMC_RW_CTRL, 0); // An intermediate state is needed to meet tRHW + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + // busy wait until completed + h2fmi_busy_wait(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE, FMC_STATUS__CMD1DONE); + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE); + } + + return result; +} +// ============================================================================= +// pio-only static implementation function definitions +// ============================================================================= + +static UInt32 h2fmi_dma_rx_complete(h2fmi_t* fmi, + UInt32 ecc_pnd, + UInt8* max_corrected, + UInt8* sector_stats) +{ + return h2fmi_rx_check_page_ecc(fmi, ecc_pnd, max_corrected, sector_stats, fmi->sectors_per_page); +} + +UInt32 h2fmi_rx_check_page_ecc(h2fmi_t* fmi, + UInt32 ecc_pend, + UInt8* max_corrected, + UInt8* sector_stats, + UInt32 sectors_per_page) +{ +#if FMI_VERSION == 0 + // S5L8920X + UInt32 status = _kIOPFMI_STATUS_SUCCESS; + BOOL32 clean = FALSE32; + UInt32 sector_idx; + + if (ecc_pend & ECC_PND__BCH_ALL_FF) + { +#if (defined (AND_COLLECT_FIL_STATISTICS) && AND_COLLECT_FIL_STATISTICS) + stFILStatistics.ddwReadCleanCnt++; +#endif + // All pages are clean. Set all sector stats to 0xFE to tell the client. + if( sector_stats ) + { + WMR_MEMSET(sector_stats, 0xFE, sectors_per_page); + } + + status = _kIOPFMI_STATUS_BLANK; + clean = TRUE32; + } + else if (ecc_pend & ECC_PND__UNCORRECTABLE) + { +#if (defined (AND_COLLECT_FIL_STATISTICS) && AND_COLLECT_FIL_STATISTICS) + stFILStatistics.ddwReadECCErrorCnt++; +#endif + status = _kIOPFMI_STATUS_AT_LEAST_ONE_UECC; + } + + if (!clean && max_corrected) + { + // Page is not entirely clean and the client is interested in the + // max number of corrected bits/sector. Pull per-sector ECC stats + // from the ECC FIFO. + for (sector_idx = 0; sector_idx < sectors_per_page; sector_idx++) + { + // collect ECC corrected bits results for this sector + const UInt32 ecc_result = h2fmi_rd(fmi, ECC_RESULT); + const UInt8 error_cnt = (ecc_result >> 16) & 0x1F; + +#if (defined (AND_COLLECT_FIL_STATISTICS) && AND_COLLECT_FIL_STATISTICS) + stFILStatistics.addwReadBitFlipsCnt[error_cnt]++; +#endif + if( error_cnt > *max_corrected ) + { + *max_corrected = error_cnt; + } + + if( sector_stats ) + { + if( ecc_result & ECC_RESULT__ERROR_FLAG ) + { + // UECC Error + sector_stats[ sector_idx ] = 0xFF; + } + else + { + sector_stats[ sector_idx ] = error_cnt; + } + } + } + } + + return status; +#else + // S5L8922X and later + UInt32 sector_idx; + BOOL32 first_sector_good = FALSE32; + UInt8 is_clean_count = 0; + UInt8 is_clean_with_stuck_count = 0; + UInt8 is_fused_count = 0; + UInt8 is_uecc_count = 0; + UInt32 result = _kIOPFMI_STATUS_SUCCESS; + h2fmi_sector_status status; + + if (max_corrected) + { + *max_corrected = (ecc_pend & ECC_PND__MAX_ERROR_CNT_MASK) >> ECC_PND__MAX_ERROR_CNT_SHIFT; + } + + for (sector_idx = 0; sector_idx < sectors_per_page; sector_idx++) + { + status = h2fmi_rx_check_sector_ecc(fmi); + if (sector_stats) + { + sector_stats[sector_idx] = status.error_cnt; + } + + if (status.status == kh2fmi_sector_status_fused) + { + // This sector was all zeroes, but we'll only consider it truely + // fused if all sectors are zero. + is_fused_count++; + } + else if (status.status == kh2fmi_sector_status_clean) + { + // This sector was clean, but we'll only set is_clean for real + // a little later if all sectors in this page were clean. + is_clean_count++; + } + else if (status.status == kh2fmi_sector_status_clean_with_stuck) + { + is_clean_with_stuck_count++; + } + else if (status.status == kh2fmi_sector_status_uecc) + { + is_uecc_count++; + } + else if (0 == sector_idx) + { + first_sector_good = TRUE32; + } + } + +#if FMI_VERSION < 3 + // With H4P the PAUSE_ECC bit does not need to be cleared + // as it only take affect when the ECC_RESULT FIFO is full. + if ((fmiRead == fmi->stateMachine.currentMode) && (fmi->stateMachine.page_idx < fmi->stateMachine.page_count)) + { + // Clear the PAUSE_ECC bit for all but the last page. It should have already been cleared + // when gathering ECC results for the previous page. Also, unnecessarily clearing it here causes + // a race with FMI trying to go to idle mode during the read-modify-write. + h2fmi_wr(fmi, FMI_CONTROL, h2fmi_rd(fmi, FMI_CONTROL) & ~FMI_CONTROL__ECC_PAUSE); + } + + // Since 0xFF sectors generate 0xFF ECC, sector 0 indicates if the page is expected to be clean. + if (first_sector_good) + { + is_clean_count += is_clean_with_stuck_count; + } + else +#endif // FMI_VERSION < 3 + { + is_uecc_count += is_clean_with_stuck_count; + } + + if (is_clean_count == sectors_per_page) + { + // All sectors in this page were clean; mark the whole page as clean + result = _kIOPFMI_STATUS_BLANK; + } + else if (is_fused_count == sectors_per_page) + { + // All sectors in this page were zeroes; mark the whole page as fused and treat + // it like an uncorrectable ECC error + result = _kIOPFMI_STATUS_FUSED; + } + else if (0 != is_uecc_count) + { + result = _kIOPFMI_STATUS_AT_LEAST_ONE_UECC; + } + + return result; +#endif // SUB_PLATFORM_S5L8922X +} + +#if FMI_VERSION > 0 +static h2fmi_sector_status h2fmi_rx_check_sector_ecc(h2fmi_t* fmi) +{ + const UInt32 ecc_result = h2fmi_rd(fmi, ECC_RESULT); + const BOOL32 all_ff = (ecc_result & ECC_RESULT__FREE_PAGE) ? TRUE32 : FALSE32; + const BOOL32 all_zeros = (ecc_result & ECC_RESULT__ALL_ZERO) ? TRUE32 : FALSE32; + const BOOL32 uecc = (ecc_result & ECC_RESULT__UNCORRECTABLE) ? TRUE32 : FALSE32; + const UInt32 stuck_bits_shifted = (ecc_result & ECC_RESULT__STUCK_BIT_CNT(~0)); + h2fmi_sector_status ret; + + if (all_ff) + { + if (ECC_RESULT__STUCK_BIT_CNT(H2FMI_ALLOWED_STUCK_BITS_IN_FP) < stuck_bits_shifted) + { + ret.status = kh2fmi_sector_status_clean_with_stuck; + } + else + { + ret.status = kh2fmi_sector_status_clean; + } + ret.error_cnt = 0xFE; + } + else if (all_zeros) + { + ret.status = kh2fmi_sector_status_fused; + ret.error_cnt = 0xFF; + } + else if (uecc) + { + ret.status = kh2fmi_sector_status_uecc; + ret.error_cnt = 0xFF; + } + else + { + ret.status = kh2fmi_sector_status_normal; + ret.error_cnt = (ecc_result & ECC_RESULT__ERROR_CNT_MASK) >> ECC_RESULT__ERROR_CNT_SHIFT; + } + + // We'll check for per-page UECC in ECC_PND, not per-sector from the FIFO to save some time + return ret; +} +#endif + +UInt32 h2fmi_read_page(h2fmi_t* fmi, + h2fmi_ce_t ce, + UInt32 page, + UInt8* data_buf, + UInt8* meta_buf, + UInt8* max_corrected, + UInt8* sector_stats) +{ + struct dma_segment data_sgl; + struct dma_segment meta_sgl; + + data_sgl.paddr = (UInt32)data_buf; + data_sgl.length = fmi->bytes_per_page; + meta_sgl.paddr = (UInt32)meta_buf; + meta_sgl.length = fmi->valid_bytes_per_meta; + + UInt32 result = h2fmi_read_multi(fmi, 1, &ce, &page, &data_sgl, &meta_sgl, max_corrected, sector_stats); + + return result; +} + +static void h2fmi_ISR_cleanup_ECC( h2fmi_t* fmi, UInt32 ecc_pnd ) +{ + FMI_ISR_STATE_MACHINE* fsm = &fmi->stateMachine; + UInt8 max_corrected = 0; + const UInt32 currentIndex = fsm->page_idx - 1; + UInt32 status; + + // Collect ECC stats from the previous page while we're DMAing the + // current one. + status = h2fmi_dma_rx_complete(fmi, + ecc_pnd, + &max_corrected, + fsm->sector_stats); + +#if defined(SIMULATE_READ_FAILURES) + if ( ++ulFailureCount>=READ_FAILURE_MAGIC_NUMBER ) + { + /** + * Don't 'mask' real read errors ... only muck with 'successful' + * reads. + */ + if ( _kIOPFMI_STATUS_SUCCESS == status ) + { + ulFailureCount = 0; + status = READ_FAILURE_STATUS_TYPE; + + { + ulSimulatedFailingCE = fsm->chip_enable_array[ currentIndex ]; + ulSimulatedFailingPage = fsm->page_number_array[ currentIndex ]; + } + } + } + else + { +#ifdef STICKY_READ_FAILURES + if ( (ulSimulatedFailingCE == fsm->chip_enable_array[ currentIndex ]) + &&(ulSimulatedFailingPage == fsm->page_number_array[ currentIndex ]) ) + { + status = READ_FAILURE_STATUS_TYPE; + } +#endif + } +#endif + switch (status) + { + case _kIOPFMI_STATUS_AT_LEAST_ONE_UECC: + fsm->uecc_pages++; + break; + case _kIOPFMI_STATUS_BLANK: + fsm->clean_pages++; + break; + case _kIOPFMI_STATUS_FUSED: + fsm->fused_pages++; + break; + } + + if ( (_kIOPFMI_STATUS_AT_LEAST_ONE_UECC==status) + ||(_kIOPFMI_STATUS_BLANK==status) + ||(_kIOPFMI_STATUS_FUSED==status) ) + { + if ( ((UInt32) ~0) == fmi->failureDetails.wFirstFailingCE ) + { + fmi->failureDetails.wFirstFailingCE = fsm->chip_enable_array[ currentIndex ]; + } + } + if (fsm->max_corrected_array) + { + fsm->max_corrected_array[fsm->page_idx - 1] = max_corrected; + } + + if (fsm->sector_stats) + { + fsm->sector_stats += fmi->sectors_per_page; + } +} + +static void h2fmi_reset_ecc(h2fmi_t* fmi) +{ + // Reset the ECC_RESULT FIFO + // clear any results fifo by setting the error flag +#if FMI_VERSION == 0 + h2fmi_wr(fmi, ECC_RESULT, ECC_RESULT__ERROR_FLAG); +#else + h2fmi_wr(fmi, ECC_RESULT, ECC_RESULT__FIFO_RESET); +#endif + + // clean status bits by setting them + h2fmi_clean_ecc(fmi); +} + + +static void h2fmi_read_done_handler( h2fmi_t* fmi ) +{ + h2fmi_clear_interrupts_and_reset_masks(fmi); + h2fmi_fmc_disable_all_ces( fmi ); +#if (H2FMI_WAIT_USING_ISR) + event_signal( &fmi->stateMachine.stateMachineDoneEvent ); +#endif +} + +static void h2fmi_read_setup_handler( h2fmi_t* fmi ); +static void h2fmi_read_start_wait_handler( h2fmi_t* fmi ); + +static void h2fmi_read_wait_ECC_done_handler( h2fmi_t* fmi ) +{ + // Wait for fmc tasks pending to be two, indicating that FMI + // buffers are available -- prevents us from re-programming FMI + // HW before it has completely finished. + if ((0 != ( h2fmi_rd(fmi, FMI_STATUS) & (FMI_STATUS__ECC_ACTIVE)))) + { + BOOL32 fTimeout = WMR_HAS_TIME_ELAPSED_TICKS(fmi->stateMachine.waitStartTicks, fmi->stateMachine.wQuarterPageTimeoutTicks); + + if ( fTimeout ) + { + fmi->stateMachine.fSuccessful = FALSE32; + fmi->failureDetails.wOverallOperationFailure = _kIOPFMI_STATUS_ECC_DONE_TIMEOUT; + // We failed to get what we wanted -- goto error state and complete. + fmi->stateMachine.state.rd = readDone; + h2fmi_read_done_handler(fmi); + } + + } + else + { + if (fmi->stateMachine.page_idx >= fmi->stateMachine.page_count) + { + const UInt32 ecc_pnd = h2fmi_rd(fmi, ECC_PND); + h2fmi_wr(fmi, ECC_PND, ecc_pnd); + + h2fmi_ISR_cleanup_ECC(fmi, ecc_pnd); + fmi->stateMachine.state.rd = readDone; + h2fmi_read_done_handler(fmi); + } + else + { + h2fmi_prepare_for_ready_busy_interrupt(fmi); + + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + fmi->stateMachine.state.rd = readStartWait; + + h2fmi_read_start_wait_handler(fmi); + } + } +} + +static void h2fmi_read_Xfer_data_handler( h2fmi_t* fmi ) +{ + fmi->isr_condition = h2fmi_rd(fmi, FMI_INT_PEND); + if (FMI_INT_PEND__LAST_FMC_DONE != (fmi->isr_condition & FMI_INT_PEND__LAST_FMC_DONE)) + { + BOOL32 fTimeout = WMR_HAS_TIME_ELAPSED_TICKS( fmi->stateMachine.waitStartTicks, fmi->stateMachine.wPageTimeoutTicks); + + if ( fTimeout ) + { + fmi->stateMachine.fSuccessful = FALSE32; + fmi->failureDetails.wOverallOperationFailure = _kIOPFMI_STATUS_FMC_DONE_TIMEOUT; + // We failed to get what we wanted -- goto error state and complete. + fmi->stateMachine.state.rd = readDone; + h2fmi_read_done_handler(fmi); + } + } + else + { + h2fmi_wr(fmi, FMI_INT_EN, 0); + fmi->stateMachine.page_idx++; + fmi->stateMachine.state.rd = readSetup; + h2fmi_read_setup_handler( fmi ); + } +} + +static void h2fmi_read_start_wait_handler( h2fmi_t* fmi ) +{ + const UInt32 page_idx = fmi->stateMachine.page_idx; + CE_STATE ceState = h2fmi_get_current_CE_state(fmi); + UInt32 fmi_control = (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT); + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + if ( CE_TIMEOUT == ceState ) + { + h2fmi_wr(fmi, FMC_RW_CTRL, 0); // Turn off RE if we timeout. + h2fmi_fmc_disable_all_ces( fmi ); + fmi->stateMachine.fSuccessful = FALSE32; + fmi->failureDetails.wOverallOperationFailure = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + fmi->stateMachine.state.rd = readDone; + h2fmi_read_done_handler(fmi); + } + else if ( CE_BUSY != ceState ) + { +#if FMI_VERSION == 0 + // Store and clear ECC_PND state before we kick off the next page to eliminate any + // possible races between software clearing the ECC status and hardware changing it. + // But to keep performance up, we'll only process this information after we've started + // the next page. + const UInt32 ecc_pend = h2fmi_rd(fmi, ECC_PND); + h2fmi_wr(fmi, ECC_PND, ecc_pend); +#endif + + h2fmi_clear_interrupts_and_reset_masks(fmi); + + // reissue cmd1 + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ)); + h2fmi_wr(fmi, FMC_RW_CTRL, 0); // An intermediate state is needed to meet tRHW + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + // busy wait until completed + h2fmi_busy_wait(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE, FMC_STATUS__CMD1DONE); + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__CMD1DONE); + + fmi->stateMachine.state.rd = readXferData; + // enable appropriate interrupt source + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__LAST_FMC_DONE); + +#if FMI_VERSION > 0 + if( page_idx > 0 ) + { + // Don't let the ECC block do anything for the next page until we've had a chance to pull + // out the previous page's ECC status + fmi_control |= FMI_CONTROL__ECC_PAUSE; + } +#endif + + // start FMI read of next page. This starts the big delay while the data is actually + // transferred over the bus. + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + if ( page_idx == 0) + { + h2fmi_start_dma(fmi); + } + + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + + if( page_idx > 0 ) + { +#if FMI_VERSION > 0 + UInt32 ecc_pend; + + ecc_pend = h2fmi_rd(fmi, ECC_PND); + h2fmi_wr(fmi, ECC_PND, ecc_pend); +#endif + h2fmi_ISR_cleanup_ECC(fmi, ecc_pend); + } + } +} + +static void h2fmi_read_setup_handler( h2fmi_t* fmi ) +{ + BOOL32 fNeedsChipSelect = ( (fmi->stateMachine.page_idx < fmi->stateMachine.page_count) ? TRUE32 : FALSE32 ); + + if (fmi->stateMachine.needs_prepare) + { + // We'll generally try to overlap reads (by taking care of this while the previous + // page was being transferred). But we'll have to setup the read here on the first + // page and if we get two pages on the same CE in a row. + fmi->stateMachine.needs_prepare = FALSE32; + h2fmi_prepare_read(fmi, + fmi->stateMachine.page_idx, + fmi->stateMachine.chip_enable_array, + fmi->stateMachine.page_number_array); + fNeedsChipSelect = FALSE32; + } + // Setup the next page while we're waiting for this one to complete... + if ( (fmi->stateMachine.page_idx + 1) < fmi->stateMachine.page_count ) + { + if( fmi->stateMachine.chip_enable_array[ fmi->stateMachine.page_idx + 1 ] == fmi->stateMachine.lastCE ) + { + // Two consecutive operations on the same CE: it's not safe to + // prepare the second one yet... + fmi->stateMachine.needs_prepare = TRUE32; + } + else + { + fmi->stateMachine.needs_prepare = FALSE32; + h2fmi_prepare_read(fmi, + fmi->stateMachine.page_idx + 1, + fmi->stateMachine.chip_enable_array, + fmi->stateMachine.page_number_array); + fNeedsChipSelect = TRUE32; + } + fmi->stateMachine.lastCE = fmi->stateMachine.chip_enable_array[ fmi->stateMachine.page_idx + 1 ]; + } + // We've setup page_idx+1 (if we could). Time to deal with page_idx again. + if ( fNeedsChipSelect ) + { + h2fmi_fmc_enable_ce( fmi, fmi->stateMachine.chip_enable_array[ fmi->stateMachine.page_idx ] ); + fmi->stateMachine.currentCE = fmi->stateMachine.chip_enable_array[ fmi->stateMachine.page_idx ]; + } + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__ECC_READY_BUSY); + + fmi->stateMachine.state.rd = readWaitECCDone; + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + + h2fmi_read_wait_ECC_done_handler(fmi); +} + +static void h2fmi_read_idle_handler( h2fmi_t* fmi ) +{ + /** + * Called initially from client in non-interrupt context to let + * us set everything up and start the process. + */ + + fmi->stateMachine.page_idx = 0; + fmi->stateMachine.fSuccessful = TRUE32; + fmi->stateMachine.needs_prepare = TRUE32; + fmi->stateMachine.lastCE = fmi->stateMachine.chip_enable_array[0]; + + BOOL32 bSuccess = h2fmi_common_idle_handler(fmi); + + WMR_ASSERT(bSuccess == TRUE32); + + fmi->stateMachine.state.rd = readSetup; + h2fmi_read_setup_handler(fmi); +} + +typedef void (*h2fmi_isrReadStateHandler)( h2fmi_t* fmi ); + +static const h2fmi_isrReadStateHandler readStateHandlerTable[] = { + h2fmi_read_idle_handler, // readIdle = 0, + h2fmi_read_setup_handler, // readSetup = 1, + h2fmi_read_start_wait_handler, // readStartWait = 2, + h2fmi_read_Xfer_data_handler, // readXferData = 3, + h2fmi_read_wait_ECC_done_handler, // readWaitECCDone = 4, + h2fmi_read_done_handler, // readDone = 5, +}; + +void h2fmi_handle_read_ISR_state_machine( h2fmi_t* fmi ) +{ + WMR_ASSERT(fmi->stateMachine.currentMode == fmiRead); + WMR_ASSERT(fmi->stateMachine.state.rd <= readDone); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + { + int k = (int)fmi->stateMachine.state.rd; + h2fmi_instrument_bit_set(2); + while (k-- > 0) + { + h2fmi_instrument_bit_clear(2); + h2fmi_instrument_bit_set(2); + } + } +#endif + + readStateHandlerTable[ fmi->stateMachine.state.rd ]( fmi ); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_clear(2); +#endif +} + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_test.c b/drivers/apple/h2fmi/H2fmi_test.c new file mode 100644 index 0000000..c142c1e --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_test.c @@ -0,0 +1,490 @@ +// ***************************************************************************** +// +// File: H2fmi_test.c +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" + +#if (H2FMI_TEST_HOOK) + +#include "H2fmi.h" + +#include + +#include +#include + +// ============================================================================= +// preprocessor compilation control +// ============================================================================= + +#define TEST_WRITE_WITH_CORRUPTED_BITS true +#define TEST_WRITE_WITH_CORRUPT_META true +#define TEST_WRITE_WITH_CORRUPT_MAIN true + +#define TESTING_BASIC_OPS true + +#define DUMP_BUFS false +#define DUMP_ERASE_BUFS true +#define DUMP_WRITE_BUFS true +#define DUMP_CORRUPTED_BUFS true + +#define ERASE_DIRTY_THRESHOLD 10 + +// TODO: fix this some other way +#define FIL_SUCCESS ((int32_t)0) +#define FIL_SUCCESS_CLEAN ((int32_t)1) + +// ============================================================================= +// external function declarations +// ============================================================================= + +extern int nand_read_bootblock(u_int8_t interface, uint8_t cs, void* address, size_t* size); + +// ============================================================================= +// private implementation function declarations +// ============================================================================= + +static bool h2fmi_test_erase(h2fmi_t* fmi, uint32_t ce, uint32_t block, uint32_t page); +static bool h2fmi_test_write(h2fmi_t* fmi, uint32_t ce, uint32_t page); + +static bool h2fmi_test_read_bootblock(void); + +// ============================================================================= +// externally visible test function definitions +// ============================================================================= + +bool h2fmi_test_hook(h2fmi_t* fmi) +{ + bool result = false; + + dprintf(DEBUG_CRITICAL, "running test hook\n"); + + h2fmi_spew_config(fmi); + + if (TESTING_BASIC_OPS) + { + const uint32_t ce = 0; + const uint32_t block = 517; + const uint32_t page = (block * fmi->pages_per_block); + + result = h2fmi_test_erase(fmi, ce, block, page); + result = h2fmi_test_write(fmi, ce, page); + } + else + { + result = h2fmi_test_read_bootblock(); + } + + return result; +} + +// ============================================================================= +// static test function definitions +// ============================================================================= + +static bool h2fmi_test_read_bootblock(void) +{ + const uint32_t bootpage_size = 3 * 512; + const uint32_t bootblock_max_size = 128 * bootpage_size; + + uint8_t* boot_buf = (uint8_t*)malloc(bootblock_max_size); + + bool result = false; + + uint32_t interface; + uint32_t ce; + + for (interface = 0; interface < 2; interface++) + { + for (ce = 0; ce < 8; ce++) + { + size_t bootblock_size = bootblock_max_size; + + dprintf(DEBUG_INFO, + "attempting boot from NAND %d CS %d\n", + interface, ce); + + // clean read buffer + memset(boot_buf, 0x00, bootblock_max_size); + + // attempt to read bootblock + if (nand_read_bootblock(interface, ce, boot_buf, &bootblock_size) == 0) + { + // TODO: do minimal verification of bootblock by checking + // for known pattern + if ((boot_buf[0] == '3') && + (boot_buf[1] == 'g') && + (boot_buf[2] == 'm') && + (boot_buf[3] == 'I')) + { + dprintf(DEBUG_INFO, "loaded boot image\n"); + result = true; + } + } + else + { + dprintf(DEBUG_SPEW, "load failed\n"); + } + + if (DUMP_BUFS) + { + dprintf(DEBUG_SPEW, "boot_buf\n"); + h2fmi_spew_buffer(boot_buf, bootpage_size); + } + } + } + + // TODO: free allocated buffers + + if (!result) + { + dprintf(DEBUG_CRITICAL, "ERROR: failed to load any boot images!\n"); + } + + return result; +} + +static bool h2fmi_test_erase(h2fmi_t* fmi, + uint32_t ce, + uint32_t block, + uint32_t page) +{ + bool result = true; + + const uint32_t bytes_per_page = fmi->bytes_per_page; + const uint32_t bytes_per_spare = fmi->bytes_per_spare; + const uint32_t bytes_per_meta = fmi->bytes_per_meta; + + uint8_t* data_buf_0 = (uint8_t*)malloc(bytes_per_page); + uint8_t* spare_buf_0 = (uint8_t*)malloc(bytes_per_spare); + + uint8_t* data_buf_1 = (uint8_t*)malloc(bytes_per_page); + uint8_t* meta_buf_1 = (uint8_t*)malloc(bytes_per_meta); + + dprintf(DEBUG_INFO, "h2fmi_test_erase()...\n"); + + uint32_t byte_idx; + uint32_t dirty_count = 0; + uint8_t bCorrectedBits = 0; + + // clean read buffers + memset(data_buf_0, 0x00, bytes_per_page); + memset(spare_buf_0, 0x00, bytes_per_spare); + memset(data_buf_1, 0x00, bytes_per_page); + memset(meta_buf_1, 0x00, bytes_per_meta); + + if (FIL_SUCCESS != h2fmiEraseSingleBlock(ce, block)) + { + dprintf(DEBUG_CRITICAL, "ERROR: failed erase\n"); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_SPEW, "h2fmiEraseSingleBlock succeeded\n"); + } + + // read back with ECC, verifying that page is reported as "clean" + if (FIL_SUCCESS_CLEAN != h2fmiReadSinglePage(ce, page, + data_buf_1, + meta_buf_1, + &bCorrectedBits, + NULL)) + { + dprintf(DEBUG_CRITICAL, "ERROR: failed read single of erased page without detecting clean\n"); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_SPEW, "h2fmiReadSinglePage correctly reported FIL_SUCCESS_CLEAN\n"); + } + + // read back raw contents of page (i.e. with no ECC) + if (FIL_SUCCESS != h2fmiReadNoECC(ce, page, + data_buf_0, + spare_buf_0)) + { + dprintf(DEBUG_CRITICAL, "ERROR: failed raw readback from erased page\n"); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_SPEW, "h2fmiReadNoECC succeeded\n"); + } + + // verify that raw readback buffer is mostly all 0xFF + for (byte_idx = 0; byte_idx < bytes_per_page; byte_idx++) + { + if (0xFF != data_buf_0[byte_idx]) + { + dirty_count++; + } + } + for (byte_idx = 0; byte_idx < bytes_per_spare; byte_idx++) + { + if (0xFF != spare_buf_0[byte_idx]) + { + dirty_count++; + } + } + if (dirty_count > ERASE_DIRTY_THRESHOLD) + { + dprintf(DEBUG_CRITICAL, + "ERROR: %d bytes reported not 0xFF by ReadNoECC after Erase\n", + dirty_count); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_INFO, "%d bytes reported dirty\n", dirty_count); + } + + if (!result && DUMP_ERASE_BUFS) + { + dprintf(DEBUG_INFO, "data_buf_0\n"); + h2fmi_spew_buffer(data_buf_0, bytes_per_page); + dprintf(DEBUG_INFO, "spare_buf_0\n"); + h2fmi_spew_buffer(spare_buf_0, bytes_per_spare); + + dprintf(DEBUG_INFO, "data_buf_1\n"); + h2fmi_spew_buffer(data_buf_1, bytes_per_page); + dprintf(DEBUG_INFO, "meta_buf_1\n"); + h2fmi_spew_buffer(meta_buf_1, bytes_per_meta); + } + + // using free causes panic with error... + + //free(data_buf_0); + //free(spare_buf_0); + //free(data_buf_1); + //free(meta_buf_1); + + dprintf(DEBUG_INFO, "...%s\n", result ? "succeeded" : "failed"); + + return result; +} + +static bool h2fmi_test_write(h2fmi_t* fmi, uint32_t ce, uint32_t page) +{ + bool result = true; + + const uint32_t bytes_per_page = fmi->bytes_per_page; + const uint32_t bytes_per_meta = fmi->bytes_per_meta; + + uint8_t* data_buf_2 = (uint8_t*)malloc(bytes_per_page); + uint8_t* meta_buf_2 = (uint8_t*)malloc(bytes_per_meta); + + uint8_t* data_buf_3 = (uint8_t*)malloc(bytes_per_page); + uint8_t* meta_buf_3 = (uint8_t*)malloc(bytes_per_meta); + + uint8_t* data_buf_4 = (uint8_t*)malloc(bytes_per_page); + uint8_t* meta_buf_4 = (uint8_t*)malloc(bytes_per_meta); + + uint8_t* data_buf_5 = (uint8_t*)malloc(bytes_per_page); + uint8_t* meta_buf_5 = (uint8_t*)malloc(bytes_per_meta); + + dprintf(DEBUG_INFO, "h2fmi_test_write()...\n"); + + const uint32_t row_addr = (page << 16); + + uint32_t word_idx; + uint32_t byte_idx; + + uint8_t max_corrected = 0; + + // clean read buffers + memset(data_buf_4, 0xA5, bytes_per_page); + memset(meta_buf_4, 0x81, bytes_per_meta); + memset(data_buf_5, 0x5A, bytes_per_page); + memset(meta_buf_5, 0x18, bytes_per_meta); + + // watermark metadata buffers + for (byte_idx = 0; (int32_t)byte_idx < bytes_per_meta; byte_idx++) + { + uint8_t marker = (uint8_t)(0xC0 | byte_idx); + meta_buf_2[byte_idx] = marker; + +#if (TEST_WRITE_WITH_CORRUPT_META) + meta_buf_3[byte_idx] = ~marker; +#else + meta_buf_3[byte_idx] = marker; +#endif + } + + // watermark both data buffers identically + for (word_idx = 0; word_idx < (bytes_per_page >> 2); word_idx++) + { + const uint32_t col_addr = (word_idx << 2); + const uint32_t marker = (row_addr | col_addr) + 1; + uint32_t* page_words_2 = (uint32_t*)data_buf_2; + uint32_t* page_words_3 = (uint32_t*)data_buf_3; + page_words_2[word_idx] = marker; + page_words_3[word_idx] = marker; + } + +#if (TEST_WRITE_WITH_CORRUPT_MAIN) + // corrupt second data buffer + for (word_idx = 0; word_idx < 24; word_idx++) + { + uint32_t* page_words_3 = (uint32_t*)data_buf_3; + page_words_3[word_idx] ^= 0xFFFFFFFF; + } +#endif + + // write to erased page + if (FIL_SUCCESS != h2fmiWriteSinglePage(ce, + page, + data_buf_2, + meta_buf_2)) + { + dprintf(DEBUG_CRITICAL, "ERROR: failed write of page\n"); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_SPEW, "h2fmiWriteSinglePage succeeded\n"); + } + + // read back page, expecting it to not have uncorrectable ECC errors + if (FIL_SUCCESS != h2fmiReadSinglePage(ce, + page, + data_buf_4, + meta_buf_4, + &max_corrected, + NULL)) + { + dprintf(DEBUG_CRITICAL, "ERROR: failed read of written page\n"); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_SPEW, "h2fmiReadSinglePage succeeded\n"); + } + +#if (TEST_WRITE_WITH_CORRUPTED_BITS) + // write again to same page, with significant bit toggles in main data (and possibly meta data) + if (FIL_SUCCESS != h2fmiWriteSinglePage(ce, + page, + data_buf_3, + meta_buf_3)) + { + dprintf(DEBUG_CRITICAL, "ERROR: failed second (corrupting) write\n"); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_SPEW, "h2fmiWriteSinglePage (corrupting) succeeded\n"); + } + + // read back page, expecting it to fail due to uncorrectable ECC errors + if (FIL_SUCCESS == h2fmiReadSinglePage(ce, + page, + data_buf_5, + meta_buf_5, + &max_corrected, + NULL)) + { + // yell if we did NOT get an error + dprintf(DEBUG_CRITICAL, "ERROR: succeeded read of corrupted page\n"); + h2fmi_fail(result); + } + else + { + dprintf(DEBUG_SPEW, "h2fmiReadSinglePage (corrupting) failed as expected\n"); + } +#endif // TEST_WRITE_WITH_CORRUPTED_BITS + + // TODO: check fail with blank check as well + + // verify clean readback buffer + // + // TODO: add quick memcmp for initial failure detection and + // then scan byte by byte only if failed + for (byte_idx = 0; byte_idx < bytes_per_page; byte_idx++) + { + const uint8_t wrote = data_buf_2[byte_idx]; + const uint8_t read = data_buf_4[byte_idx]; + if (wrote != read) + { + dprintf(DEBUG_CRITICAL, + "ERROR: failed main data verify at byte %d, 0x%02X != 0x%02X\n", + byte_idx, wrote, read); + h2fmi_fail(result); + } + } + for (byte_idx = 0; (int32_t)byte_idx < fmi->bytes_per_meta; byte_idx++) + { + const uint8_t wrote = meta_buf_2[byte_idx]; + const uint8_t read = meta_buf_4[byte_idx]; + if (wrote != read) + { + dprintf(DEBUG_CRITICAL, + "ERROR: failed meta data verify at byte %d, 0x%02X != 0x%02X\n", + byte_idx, wrote, read); + h2fmi_fail(result); + } + } + + // TODO: verify corrupted readback buffer (using raw read) + + if (!result && DUMP_WRITE_BUFS) + { + dprintf(DEBUG_INFO, "data_buf_2\n"); + h2fmi_spew_buffer(data_buf_2, bytes_per_page); + dprintf(DEBUG_INFO, "meta_buf_2\n"); + h2fmi_spew_buffer(meta_buf_2, bytes_per_meta); + + dprintf(DEBUG_INFO, "data_buf_4\n"); + h2fmi_spew_buffer(data_buf_4, bytes_per_page); + dprintf(DEBUG_INFO, "meta_buf_4\n"); + h2fmi_spew_buffer(meta_buf_4, bytes_per_meta); + } + + if (!result && DUMP_CORRUPTED_BUFS) + { + dprintf(DEBUG_INFO, "data_buf_3\n"); + h2fmi_spew_buffer(data_buf_3, bytes_per_page); + dprintf(DEBUG_INFO, "meta_buf_3\n"); + h2fmi_spew_buffer(meta_buf_3, bytes_per_meta); + + dprintf(DEBUG_INFO, "data_buf_5\n"); + h2fmi_spew_buffer(data_buf_5, bytes_per_page); + dprintf(DEBUG_INFO, "meta_buf_5\n"); + h2fmi_spew_buffer(meta_buf_5, bytes_per_meta); + } + + // using free causes panic with error... + + //free(data_buf_2); + //free(meta_buf_2); + //free(data_buf_3); + //free(meta_buf_3); + //free(data_buf_4); + //free(meta_buf_4); + //free(data_buf_5); + //free(meta_buf_5); + + dprintf(DEBUG_INFO, "...%s\n", result ? "succeeded" : "failed"); + + return result; +} + +#endif // H2FMI_TEST_HOOK + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/H2fmi_timing.c b/drivers/apple/h2fmi/H2fmi_timing.c new file mode 100644 index 0000000..0ed7e43 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_timing.c @@ -0,0 +1,288 @@ +// Copyright (C) 2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// +// Note: This file is intended to compile for an iBoot and x86 host target + +#include "H2fmi_timing.h" +#include "WMROAM.h" // WMR_MAX, ROUNDUPTO, + + +#if 0 +#define DUMP_VAR(variable) WMR_PRINT(ALWAYS, "%s:%d %s : %u\n", \ + __FUNCTION__, __LINE__, #variable, (UInt32)(variable)) +#else +#define DUMP_VAR(variable) +#endif + +// timings required by PPN 1.5 spec +#define FPGA_TIMINGS (0) + +#if FPGA_TIMINGS // Based on SAMSUNG PPN 1.5 FPGA (will be removed once we get PPN 1.5 Si) + +#define WH_MIN_NS (35) +#define WP_MIN_NS (65) +#define WC_MIN_NS (100) + +#define RPRE_MIN_NS (116) +#define WPRE_MIN_NS (76) +#define WPST_MIN_PS (1888000) +#define DQSRE_MAX_PS (50 * 1000) + +#define CS_MIN_NS (383) +#define CH_MIN_NS (5) +#define ADL_MIN_NS (300) +#define WHR_MIN_NS (120) + +#else // these are timings specified by PPN 1.5 spec + +#define RPRE_MIN_NS (35) +#define WPRE_MIN_NS (15) +#define WPST_MIN_PS (6500) +#define DQSRE_MAX_PS (25 * 1000) + +#define CS_MIN_NS (20) +#define CH_MIN_NS (5) +#define ADL_MIN_NS (300) +#define WHR_MIN_NS (120) + +#define RPSTH_MIN_NS (15) +#endif + +#if FMI_VERSION >= 5 +#define RPST_MAX_CYCLES (5) +#endif // FMI_VERSION >= 5 + +Int32 HertzToPicoseconds + (UInt64 hertz) +{ + const UInt32 KHz = hertz / 1000; + + const UInt32 ps = ((UInt32)1000000000) / KHz; + + return ps; +} + +UInt32 +NandRequirementToIFCTRL ( + const NandRequiredTimings *required, + NandFmcSettings *actual) +{ + DUMP_VAR(required->clock_hz); + DUMP_VAR(required->tRC_ns); + DUMP_VAR(required->tRP_ns); + DUMP_VAR(required->tREH_ns); + DUMP_VAR(required->tREA_ns); + DUMP_VAR(required->tRHOH_ns); + DUMP_VAR(required->tRLOH_ns); + DUMP_VAR(required->tWC_ns); + DUMP_VAR(required->tWP_ns); + DUMP_VAR(required->tWH_ns); + + // avoid using + const Int32 ps_per_clock = HertzToPicoseconds(required->clock_hz); + + // Minimum time from SoC falling edge until first possible data sample + const Int32 data_sample_time = ROUNDUPTO((required->tREA_ns + required->soc_tx_prop_ns + required->soc_rx_prop_ns) * PS_PER_NS, ps_per_clock); + const Int32 data_sample_clocks = data_sample_time / ps_per_clock; + DUMP_VAR(data_sample_clocks); + + const Int32 reb_setup_time = ROUNDUPTO(WMR_MAX((required->tRP_ns * PS_PER_NS), (data_sample_time - (required->tRHOH_ns * PS_PER_NS))), ps_per_clock); + Int32 reb_setup_clocks = reb_setup_time / ps_per_clock; + DUMP_VAR(reb_setup_clocks); + + Int32 reb_high_estimate_clocks = 0; + + // Minimum cycle time as determined by actual setup plus required hold vs. tRC + const Int32 reb_adjusted_cycle_time = ROUNDUPTO(WMR_MAX((required->tREH_ns * PS_PER_NS) + reb_setup_time, (required->tRC_ns * PS_PER_NS)), ps_per_clock); + DUMP_VAR(reb_adjusted_cycle_time); + + const Int32 tRLOH_clocks = ROUNDUPTO(required->tRLOH_ns * PS_PER_NS, ps_per_clock) / ps_per_clock; + // Check for EDO mode (data ready time > actual cycle + tRLOH) + if (data_sample_time > (reb_adjusted_cycle_time + ROUNDUPTO(required->tRLOH_ns * PS_PER_NS, ps_per_clock))) + { + WMR_ASSERT(data_sample_clocks > (tRLOH_clocks + reb_setup_clocks)); + reb_high_estimate_clocks = data_sample_clocks - tRLOH_clocks - reb_setup_clocks; + } + else + { + reb_high_estimate_clocks = ROUNDUPTO(WMR_MAX((required->tREH_ns * PS_PER_NS), ((required->tRC_ns * PS_PER_NS) - reb_setup_time)), ps_per_clock) / ps_per_clock; + } + DUMP_VAR(reb_high_estimate_clocks); + + Int32 reb_high_revised_clocks = 0; + + // data sampling is done with a delay relative to the risine edge of REB + // thus, the sampling cannot occur past the rising edge of the subsequent cycle + if (((data_sample_clocks - reb_setup_clocks) <= (reb_setup_clocks + reb_high_estimate_clocks - 1))) + { + reb_high_revised_clocks = reb_high_estimate_clocks; + } + else + { + reb_setup_clocks = data_sample_clocks; + } + + DUMP_VAR(reb_high_revised_clocks); + + Int32 reb_setup_final_clocks = reb_setup_clocks; + Int32 reb_high_final_clocks = reb_high_revised_clocks; + + // Shift extra cycles to setup phase if possible + if ((reb_high_revised_clocks > 1) && (((reb_high_revised_clocks - 1) * ps_per_clock) > (required->tREH_ns * PS_PER_NS))) + { + reb_high_final_clocks -= 1; + reb_setup_final_clocks += 1; + } + + actual->read_setup_clocks = reb_setup_final_clocks > 0 ? reb_setup_final_clocks - 1 : 0; + actual->read_hold_clocks = reb_high_final_clocks > 0 ? reb_high_final_clocks - 1 : 0; + actual->read_dccycle_clocks = data_sample_clocks > reb_setup_final_clocks ? data_sample_clocks - reb_setup_final_clocks : 0; + + // Some chips cannot sample after the next byte's /RE - rdar://7063954 + if (required->edo_limit && + ((actual->read_setup_clocks + actual->read_hold_clocks + 1) < actual->read_dccycle_clocks)) + { + return FALSE32; + } + + const Int32 write_hold_time = ROUNDUPTO(required->tWH_ns * PS_PER_NS, ps_per_clock); + + const Int32 write_setup_time = ROUNDUPTO(WMR_MAX(((required->tWC_ns * PS_PER_NS) - write_hold_time), (required->tWP_ns * PS_PER_NS)), ps_per_clock); + + Int32 write_hold_revised_time = write_hold_time; + Int32 write_setup_revised_time = write_setup_time; + + // Balance write setup and hold if balance_write_cycle is set + if (required->balance_write_cycle && + ((write_setup_time - ps_per_clock) > (required->tWP_ns * PS_PER_NS))) + { + write_hold_revised_time += ps_per_clock; + write_setup_revised_time -= ps_per_clock; + } + + actual->write_setup_clocks = (write_setup_revised_time / ps_per_clock) - 1; + actual->write_hold_clocks = (write_hold_revised_time / ps_per_clock) - 1; + + return TRUE32; +} + +static UInt32 +h2fmi_nanos_to_clocks(UInt8 nsPerClock, + UInt8 nsPerOperation) +{ + UInt8 rawValue = (nsPerOperation / nsPerClock) + ((nsPerOperation % nsPerClock) ? 1 : 0); + UInt8 registerValue = (rawValue ? rawValue - 1 : 0); + + return registerValue; +} + + +BOOL32 +Legacy_NandRequirementToIFCTRL ( + const NandRequiredTimings *required, + NandFmcSettings *actual) +{ + +#define timing_nanos(cycles, hz) ((((UInt64)1000000000) * cycles) / hz) +#define SUB_MIN_ZERO(minuend, subtrahend) (((minuend) > (subtrahend)) ? ((minuend) - (subtrahend)) : 0) + UInt32 nsAdjustedWriteSetup; + UInt32 nsAdjustedWriteHold; + UInt32 nsWriteCycleRemainder; + UInt32 nsAdjustedReadSetup; + UInt32 nsAdjustedReadHold; + UInt32 nsActualReadSetup; + UInt32 nsAdjustedReadCycle; + UInt32 nsReadCycleRemainder; + UInt32 nsAdjustedReadSample; + + UInt32 write_setup_clocks; + UInt32 write_hold_clocks; + UInt32 read_setup_clocks; + UInt32 read_hold_clocks; + UInt32 edo_delay; + + const UInt32 nsNandRiseTime = required->nand_to_soc_rise_ns; + const UInt32 nsSocRiseTime = required->soc_to_nand_rise_ns; + const UInt32 nsSocFallTime = required->soc_to_nand_fall_ns; + + Int32 nsPerClock; + + nsPerClock = HertzToPicoseconds(required->clock_hz) / 1000; + + nsAdjustedWriteSetup = required->tWP_ns + nsSocFallTime; + write_setup_clocks = h2fmi_nanos_to_clocks(nsPerClock, nsAdjustedWriteSetup); + + // Check if cycle time remaining or write hold requirement is greater + nsWriteCycleRemainder = SUB_MIN_ZERO((UInt32)required->tWC_ns,(write_setup_clocks * nsPerClock)); + nsAdjustedWriteHold = WMR_MAX(nsWriteCycleRemainder, required->tWH_ns + nsSocRiseTime); + write_hold_clocks = h2fmi_nanos_to_clocks(nsPerClock, nsAdjustedWriteHold); + + nsAdjustedReadSetup = required->tRP_ns + nsSocFallTime; + read_setup_clocks = h2fmi_nanos_to_clocks(nsPerClock, nsAdjustedReadSetup); + nsActualReadSetup = (read_setup_clocks + 1) * nsPerClock; + + // Since read has round-trip rise/fall delays, account for both + nsAdjustedReadCycle = WMR_MAX((UInt32)required->tRC_ns, + nsSocFallTime + required->tREA_ns + nsNandRiseTime); + nsReadCycleRemainder = SUB_MIN_ZERO((UInt32)nsAdjustedReadCycle, nsActualReadSetup); + + nsAdjustedReadHold = WMR_MAX(nsReadCycleRemainder, required->tREH_ns + nsSocRiseTime); + read_hold_clocks = h2fmi_nanos_to_clocks(nsPerClock, nsAdjustedReadHold); + + // Make sure we sample tREA from fall, but before tRHOH from rise + nsAdjustedReadSample = SUB_MIN_ZERO(nsSocFallTime + required->tREA_ns+ nsNandRiseTime, + nsActualReadSetup); + edo_delay = ROUNDUPTO(nsAdjustedReadSample, nsPerClock) / nsPerClock; // how many cycles after the falling edge to sample + + + actual->read_setup_clocks = read_setup_clocks; + actual->read_hold_clocks = read_hold_clocks; + actual->read_dccycle_clocks = edo_delay; + actual->write_setup_clocks = write_setup_clocks; + actual->write_hold_clocks = write_hold_clocks; + + return TRUE32; +} + +#if SUPPORT_TOGGLE_NAND +BOOL32 Toggle_NandRequirementToIFCTRL ( + const NandRequiredTimings *required, + NandFmcSettings *actual +) +{ + + UInt64 clk_Hz = required->clock_hz; + UInt32 toggleCycleTimePS = WMR_MAX(WMR_MAX(WMR_MAX(required->ddr_tREH_ps * 2, required->ddr_tRP_ps * 2), + WMR_MAX(required->tDQSH_ps * 2, required->tDQSL_ps * 2)), + WMR_MAX(required->tDSC_ps, required->ddr_tRC_ps)); + + actual->ddr_half_cycle_clocks = CEIL_DIV(toggleCycleTimePS * clk_Hz, 2 * PS_PER_S) - 1; + + actual->read_pre_clocks = CEIL_DIV(RPRE_MIN_NS * clk_Hz, NS_PER_S) - 1; +#if FMI_VERSION < 5 + actual->read_post_clocks = CEIL_DIV((DQSRE_MAX_PS + toggleCycleTimePS / 2) * clk_Hz, PS_PER_S) - 1; +#else // FMI_VERSION >= 5 + // Change the read post amble delay to workaround Read dma timeout with DQS_TIMING_CTRL::DELTAV_SUSPENDS_READS + actual->read_post_clocks = RPST_MAX_CYCLES; +#endif // FMI_VERSION >= 5 + actual->write_pre_clocks = CEIL_DIV(WPRE_MIN_NS * clk_Hz, NS_PER_S) - 1; + actual->write_post_clocks = CEIL_DIV(WPST_MIN_PS * clk_Hz, PS_PER_S) - 1; + + actual->ce_setup_clocks = CEIL_DIV(CS_MIN_NS * clk_Hz, NS_PER_S) - 1; + //H5P violates tRPSTH. SoC team recommends increasing CE Hold Time as a workaround + //to increase tRPSTH: PPN1.5: tRPSTH is being violated + actual->ce_hold_clocks = CEIL_DIV(WMR_MAX(CH_MIN_NS, RPSTH_MIN_NS) * clk_Hz, NS_PER_S) - 1; + actual->adl_clocks = CEIL_DIV(ADL_MIN_NS * clk_Hz, NS_PER_S) - 1; + actual->whr_clocks = CEIL_DIV(WHR_MIN_NS * clk_Hz, NS_PER_S) - 1; + + return TRUE32; + +} +#endif diff --git a/drivers/apple/h2fmi/H2fmi_timing.h b/drivers/apple/h2fmi/H2fmi_timing.h new file mode 100644 index 0000000..c8faa62 --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_timing.h @@ -0,0 +1,110 @@ +// Copyright (C) 2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// +// Note: This file is intended to compile for an iBoot and x86 host target + +#ifndef _H2FMI_TIMING_H_ +#define _H2FMI_TIMING_H_ + +#include "WMRTypes.h" +#include "H2fmi_private.h" + + +#define CEIL_DIV(a,b) (((a)/(b)) + (((a) % (b)) ? 1 : 0)) + +#define PS_PER_NS (1000) +#define NS_PER_S ((UInt64)1000000000) +#define PS_PER_S ((UInt64)1000000000000) + +typedef struct _NandRequiredTimings +{ + UInt64 clock_hz; + + Int32 soc_tx_prop_ns; + Int32 soc_rx_prop_ns; + BOOL32 edo_limit; // TRUE32 if using H2P/H2A/H3P for rdar://7063954 + BOOL32 balance_write_cycle; + + // -- Legacy only + Int32 soc_to_nand_rise_ns; + Int32 soc_to_nand_fall_ns; + Int32 nand_to_soc_rise_ns; + Int32 nand_to_soc_fall_ns; + // -- End Legacy only + + Int32 tRC_ns; + Int32 tRP_ns; + Int32 tREH_ns; + Int32 tREA_ns; + Int32 tRHOH_ns; + Int32 tRLOH_ns; + + Int32 tWC_ns; + Int32 tWP_ns; + Int32 tWH_ns; + +#if SUPPORT_TOGGLE_NAND + UInt32 ddr_tRC_ps; + UInt32 ddr_tREH_ps; + UInt32 ddr_tRP_ps; + + UInt32 tDSC_ps; + UInt32 tDQSH_ps; + UInt32 tDQSL_ps; +#endif + + +} NandRequiredTimings; + +typedef struct _NandFmcSettings +{ + UInt8 read_setup_clocks; // 0 is one cycle + UInt8 read_hold_clocks; // 0 is one cycle + UInt8 read_dccycle_clocks; // 0 means rising edge of /RE + + UInt8 write_setup_clocks; // 0 is one cycle + UInt8 write_hold_clocks; // 0 is one cycle + +#if SUPPORT_TOGGLE_NAND + UInt8 ddr_half_cycle_clocks; + + UInt8 read_pre_clocks; + UInt8 read_post_clocks; + UInt8 write_pre_clocks; + UInt8 write_post_clocks; + + UInt8 ce_setup_clocks; + UInt8 ce_hold_clocks; + UInt8 adl_clocks; + UInt8 whr_clocks; +#endif +} NandFmcSettings; + +BOOL32 +NandRequirementToIFCTRL ( + const NandRequiredTimings *required, + NandFmcSettings *actual +); + +BOOL32 +Legacy_NandRequirementToIFCTRL ( + const NandRequiredTimings *required, + NandFmcSettings *actual +); + +#if SUPPORT_TOGGLE_NAND +BOOL32 +Toggle_NandRequirementToIFCTRL ( + const NandRequiredTimings *required, + NandFmcSettings *actual +); +#endif + +#endif // _H2FMI_TIMING_H_ diff --git a/drivers/apple/h2fmi/H2fmi_write.c b/drivers/apple/h2fmi/H2fmi_write.c new file mode 100644 index 0000000..7153a5d --- /dev/null +++ b/drivers/apple/h2fmi/H2fmi_write.c @@ -0,0 +1,1214 @@ +// ***************************************************************************** +// +// File: H2fmi_write.c +// +// ***************************************************************************** +// +// Notes: +// +// ***************************************************************************** +// +// Copyright (C) 2008-2013 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" +#include "H2fmi_dma.h" + +/** + * Define the following to 'simulate' NAND programming errors. + */ +//??#define SIMULATE_WRITE_FAILURES +//??#define SIMULATE_WRITE_TIMEOUTS +//??#define SIMULATE_WRITE_LOCKUP + +#if defined(SIMULATE_WRITE_TIMEOUTS) +#define WRITE_TIMEOUT_MAGIC_NUMBER ( 159871/2 ) +static unsigned long ulWriteTimeoutCount = 0; +#endif + +#if defined(SIMULATE_WRITE_FAILURES) +#define WRITE_FAILURE_MAGIC_NUMBER 159871 +static unsigned long ulFailureCount = 0; +static unsigned long _gForcedFailure[H2FMI_MAX_NUM_BUS] = { 0, 0 }; +#endif + +#if defined(SIMULATE_WRITE_LOCKUP) +#define WRITE_LOCKUP_COUNT_TRIGGER 1000 +static unsigned long ulWriteLockoutCount = 0; +#endif + +// ============================================================================= +// private implementation function declarations +// ============================================================================= + +static void h2fmi_start_nand_page_program(h2fmi_t* fmi, UInt32 page); +static void h2fmi_send_write_confirm(h2fmi_t* fmi); +static BOOL32 h2fmi_tx_raw_page(h2fmi_t* fmi, UInt8* data_buf, h2fmi_ce_t ce); +static BOOL32 h2fmi_tx_wait_page_done(h2fmi_t* fmi); +static BOOL32 h2fmi_tx_bootpage_pio(h2fmi_t* fmi, UInt8* data_buf, h2fmi_ce_t ce); +static void h2fmi_prepare_write_confirm(h2fmi_t* fmi); +static void h2fmi_write_Xfer_data_handler2(h2fmi_t * fmi); + +/** + * Same as h2fmi_get_current_CE_state except also tests to + * ensure the write protect bit is off. Used for write + * mode as a sanity check as some NAND have been known to fail + * with 'stuck' write protects. + * + * @param fmi + * + * @return CE_STATE + */ +static CE_STATE h2fmi_get_current_writable_CE_state( h2fmi_t* fmi ) +{ + CE_STATE ceState = h2fmi_get_current_CE_state(fmi); + + const UInt8 bNandStatus = (UInt8)h2fmi_rd(fmi, FMC_NAND_STATUS); + const UInt32 bWPDisabled = (bNandStatus & NAND_STATUS__WRITE_PROTECT); + + WMR_ASSERT(bWPDisabled); + + return ceState; +} + +/** + * Called when a general failure has been detected. This is + * either a timeout (in which case the status pointer is NULL) + * or a valid pointer to a 'generic' status is passed in. + * + * It is up to this routine to report the correct failing CE + * + */ +static void h2fmi_recordFirstFailingCE( h2fmi_t *fmi ) +{ + if ( ((UInt32) ~0) == fmi->failureDetails.wFirstFailingCE ) + { + /** + * Only record the FIRST failing CE ... + */ + fmi->failureDetails.wFirstFailingCE = fmi->stateMachine.currentCE; + } +} + + +// ============================================================================= +// public implementation function definitions +// ============================================================================= + +BOOL32 h2fmi_write_page(h2fmi_t* fmi, + UInt16 ce, + UInt32 page, + UInt8* data_buf, + UInt8* meta_buf, + BOOL32* status_failed) +{ + BOOL32 result = TRUE32; + struct dma_segment data_sgl; + struct dma_segment meta_sgl; + + data_sgl.paddr = (UInt32)data_buf; + data_sgl.length = fmi->bytes_per_page; + meta_sgl.paddr = (UInt32)meta_buf; + meta_sgl.length = fmi->valid_bytes_per_meta; + + result = h2fmi_write_multi(fmi, 1, &ce, &page, &data_sgl, &meta_sgl, status_failed, _kVS_NONE); + + return result; +} + +BOOL32 h2fmi_write_multi(h2fmi_t* fmi, + UInt32 page_count, + h2fmi_ce_t* chip_enable_array, + UInt32* page_number_array, + struct dma_segment* data_segment_array, + struct dma_segment* meta_segment_array, + BOOL32* write_failed, + UInt32 wVendorType) +{ + BOOL32 result = TRUE32; + +#if defined(SIMULATE_WRITE_LOCKUP) + if ( ++ulWriteLockoutCount >= WRITE_LOCKUP_COUNT_TRIGGER ) + { + volatile int iHoldForLockup = 1; + while ( iHoldForLockup ) + { + } + + } +#endif + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_clear(0); + h2fmi_instrument_bit_clear(1); + h2fmi_instrument_bit_clear(2); + h2fmi_instrument_bit_clear(3); +#endif + + WMR_ASSERT(fmi->stateMachine.currentMode == fmiNone); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_set(0); + h2fmi_instrument_bit_clear(0); + h2fmi_instrument_bit_set(0); + h2fmi_instrument_bit_clear(0); + h2fmi_instrument_bit_set(0); +#endif + const UInt32 fmc_if_ctrl = h2fmi_rd(fmi, FMC_IF_CTRL); + + WMR_ENTER_CRITICAL_SECTION(); + { + fmi->stateMachine.chip_enable_array = chip_enable_array; + fmi->stateMachine.page_number_array = page_number_array; + fmi->stateMachine.data_segment_array = data_segment_array; + fmi->stateMachine.meta_segment_array = meta_segment_array; + fmi->stateMachine.state.wr = writeIdle; + fmi->stateMachine.page_count = page_count; + fmi->stateMachine.wVendorType = wVendorType; + + h2fmi_reset(fmi); + + // disable write protect + h2fmi_set_if_ctrl(fmi, FMC_IF_CTRL__WPB | fmc_if_ctrl); + + fmi->stateMachine.currentMode = fmiWrite; + } + WMR_EXIT_CRITICAL_SECTION(); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_set(1); +#endif +#if (H2FMI_WAIT_USING_ISR) + static const utime_t clockDelay_uSec = 50000; // every 50 mSec +#endif + volatile WRITE_STATE* pState = &fmi->stateMachine.state.wr; +#if (H2FMI_WAIT_USING_ISR) + event_unsignal(&fmi->stateMachine.stateMachineDoneEvent); +#endif + do + { + if ( writeDone == (*pState) ) + { + break; + } + + WMR_ENTER_CRITICAL_SECTION(); + h2fmi_handle_write_ISR_state_machine(fmi); + WMR_EXIT_CRITICAL_SECTION(); + +#if !(H2FMI_WAIT_USING_ISR) + WMR_YIELD(); + } + while ( writeDone != (*pState) ); +#else + } + while ( !event_wait_timeout(&fmi->stateMachine.stateMachineDoneEvent, clockDelay_uSec) ); + /** + * Allow for early wakeup + */ + { + UInt32 iLoopCount = 0; + while ( writeDone != (*pState) ) + { + WMR_YIELD(); + if ( ++iLoopCount>H2FMI_EARLY_EXIT_ARBITRARY_LOOP_CONST ) + { + iLoopCount = 0; + /** + * Allow the state machine a timeslice in case the HW gets + * stuck. + */ + WMR_ENTER_CRITICAL_SECTION(); + h2fmi_handle_write_ISR_state_machine(fmi); + WMR_EXIT_CRITICAL_SECTION(); + } + } + } +#endif + /** + * Finally check the outcome from our state machine + */ + result = fmi->stateMachine.fSuccessful; + + if ( result ) + { + /** + * ensure that system DMA is complete -- note that if we already + * are in an error state we skip this test as it adds an + * addition H2FMI_PAGE_TIMEOUT_MICROS to the overall operation. + * + * This wouldn't strictly be necessary on a write (since the DMA had to have completed + * for the FMC operation to complete), but we need to make sure the event is consumed + * otherwise it'll stay pending and casue the next DMA to appear to have completed + * immediately. + */ + // both dma streams should be complete now + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_fail(result); + + // If the write operation succeeded, but we never get a CDMA completion event, + // something is broken in the FMI or CDMA layers - no legit NAND problem should case this. + WMR_PANIC("Timeout waiting for CDMA during successful NAND write operation"); + + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + fmi->failureDetails.wOverallOperationFailure = _kIOPFMI_STATUS_DMA_DONE_TIMEOUT; + } + } + else + { + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + } + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_clear(1); +#endif + + // return write protect to previous state + h2fmi_set_if_ctrl(fmi, fmc_if_ctrl); + + /** + * Reset our current mode so that interrupts are not re-directed + * to our state machine. + */ + fmi->stateMachine.currentMode = fmiNone; + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_clear(0); +#endif + + // presume all write operations will succeed + if (NULL != write_failed) + { + *write_failed = ( result ? FALSE32 : TRUE32 ); + } + +#if defined(SIMULATE_WRITE_FAILURES) + if ( _gForcedFailure[ fmi->bus_id ] ) + { + /** + * Since our simulated failures may fail the dummy commit within + * a VS operation we need to reset our NAND back to a known good + * state... We could (should?) try to be more intelligent about + * this but for now we just do a reset any time we generate a + * failure. + */ + h2fmi_nand_reset_all(fmi); + _gForcedFailure[ fmi->bus_id ] = 0; + } +#endif + + return result; +} + +static BOOL32 h2fmi_tx_wait_page_done(h2fmi_t* fmi) +{ + BOOL32 result = TRUE32; + +#if H2FMI_WAIT_USING_ISR + if (!event_wait_timeout(&fmi->isr_event, H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_fail(result); + } + + if (result && (!(fmi->isr_condition & FMI_INT_PEND__LAST_FMC_DONE))) + { + h2fmi_fail(result); + } + +#else + result = h2fmi_wait_done(fmi, FMI_INT_PEND, FMI_INT_PEND__LAST_FMC_DONE, FMI_INT_PEND__LAST_FMC_DONE); +#endif + + if (!result ) + { + h2fmi_fmc_disable_all_ces(fmi); + } + + return result; +} + + +UInt32 h2fmi_write_bootpage(h2fmi_t* fmi, + UInt32 ce, + UInt32 page, + UInt8* data_buf) +{ + UInt32 fmc_if_ctrl = h2fmi_rd(fmi, FMC_IF_CTRL); + UInt8 nand_status; + UInt32 result = _kIOPFMI_STATUS_SUCCESS; +#if FMI_VERSION > 3 + UInt32 sector; +#endif + + // Enable specified NAND device + h2fmi_fmc_enable_ce(fmi, ce); + + // Disable write protection + h2fmi_set_if_ctrl(fmi, FMC_IF_CTRL__WPB | fmc_if_ctrl); + + // Prep for program (all steps prior to data transfer) + h2fmi_start_nand_page_program(fmi, page); + h2fmi_prepare_write_confirm(fmi); + + h2fmi_set_bootpage_data_format(fmi); + +#if FMI_VERSION > 3 + // Set page format first to enable seed scrambling + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__RESET_SEED); + // Fill randomizer seeds based on page address + for (sector = 0; sector < H2FMI_BOOT_SECTORS_PER_PAGE; sector++) + { + h2fmi_wr(fmi, FMI_SCRAMBLER_SEED_FIFO, page + sector); + } +#endif + + // Transfer data for page to FMI + if (!h2fmi_tx_bootpage_pio(fmi, data_buf, ce)) + { + result = _kIOPFMI_STATUS_FMC_DONE_TIMEOUT; + } + else + { + // End program operation + h2fmi_send_write_confirm(fmi); + + // wait for the program to complete + if (!h2fmi_wait_status(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY, + &nand_status)) + { + result = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if ((nand_status & NAND_STATUS__CHIP_STATUS1) == NAND_STATUS__CHIP_STATUS1_FAIL) + { + // NAND reported Program Failed + result = _kIOPFMI_STATUS_PGM_ERROR; + } + } + + // disable all FMI interrupt sources + h2fmi_wr(fmi, FMI_INT_EN, 0); + + // restore write-protect + h2fmi_set_if_ctrl(fmi, fmc_if_ctrl); + + // Disable NAND device + h2fmi_fmc_disable_ce(fmi, ce); + + // Hardware still thinks there should be a meta DMA complete signal here somewhere. + // It'll never come, so reset the core to move on. + h2fmi_reset(fmi); + + return result; +} + +static BOOL32 h2fmi_tx_bootpage_pio(h2fmi_t* fmi, + UInt8* buf, + h2fmi_ce_t ce) +{ + BOOL32 result = TRUE32; + UInt32 i; + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__START_BIT); + + for (i = 0; i < H2FMI_BOOT_SECTORS_PER_PAGE; i++) + { + // Start FMI write +#if !WMR_BUILDING_EFI + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__LAST_FMC_DONE); +#endif + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + h2fmi_pio_write_sector(fmi, buf, H2FMI_BYTES_PER_BOOT_SECTOR); + buf += H2FMI_BYTES_PER_BOOT_SECTOR; + + // wait for the page to finish transferring + if (!h2fmi_tx_wait_page_done(fmi)) + { + h2fmi_fail(result); + break; + } + } + + return result; +} + + +UInt32 h2fmi_write_raw_page(h2fmi_t* fmi, + UInt32 ce, + UInt32 page, + UInt8* data_buf) +{ + UInt32 result = _kIOPFMI_STATUS_SUCCESS; + UInt8 nand_status; + UInt32 fmc_if_ctrl = h2fmi_rd(fmi, FMC_IF_CTRL); + + // If using PIO, make certain that the FMI subsystem gets reset + // between each write to read transition; might want to do this on + // read to write to just be safe, so I'm taking the most + // pessimistic option and doing it before each PIO-based + // operation). + // + // TODO: This workaround appears to also make dma-based write function correctly, + // which is unexpected and should be tracked down to root cause soon. + h2fmi_reset(fmi); + + // enable specified nand device + h2fmi_fmc_enable_ce(fmi, ce); + + // disable write protect + h2fmi_set_if_ctrl(fmi, FMC_IF_CTRL__WPB | fmc_if_ctrl); + + h2fmi_wr(fmi, ECC_MASK, 0 ); + + // prep for program (all the step prior to xfer). + h2fmi_start_nand_page_program(fmi, page); + h2fmi_prepare_write_confirm(fmi); + + // transfer data for page and meta to FMI + if (!h2fmi_tx_raw_page(fmi, data_buf, ce)) + { + result = _kIOPFMI_STATUS_DMA_DONE_TIMEOUT; + h2fmi_fail(result); + } + else + { + // end program operation + h2fmi_send_write_confirm(fmi); + + // wait for the device to come back + if (!h2fmi_wait_status(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY, + &nand_status)) + { + result = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if ((nand_status & NAND_STATUS__CHIP_STATUS1) == NAND_STATUS__CHIP_STATUS1_FAIL) + { + result = _kIOPFMI_STATUS_PGM_ERROR; + } + } + + // disable all FMI interrupt sources + h2fmi_wr(fmi, FMI_INT_EN, 0); + + // return write protect to previous state + h2fmi_set_if_ctrl(fmi, fmc_if_ctrl); + + // disable all nand devices + h2fmi_fmc_disable_ce(fmi, ce); + + if( result != _kIOPFMI_STATUS_SUCCESS) + { + h2fmi_fmc_disable_all_ces(fmi); + } + + return result; +} + +static BOOL32 h2fmi_tx_raw_page(h2fmi_t* fmi, + UInt8* buf, + h2fmi_ce_t ce) +{ + BOOL32 result = TRUE32; + UInt32 i; + UInt32 spare = fmi->bytes_per_spare; + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__START_BIT); + + for( i = 0; i < fmi->sectors_per_page; i++ ) + { + const UInt32 spare_per_sector = WMR_MIN(spare, H2FMI_MAX_META_PER_ENVELOPE); + + h2fmi_set_raw_write_data_format(fmi, spare_per_sector); + + // start FMI write + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__LAST_FMC_DONE); + + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + h2fmi_dma_execute_cmd(DMA_CMD_DIR_TX, + h2fmi_dma_data_chan(fmi), + buf, + h2fmi_dma_data_fifo(fmi), + H2FMI_BYTES_PER_SECTOR, + sizeof(UInt32), + 1, + NULL); + + buf += H2FMI_BYTES_PER_SECTOR; + + if( spare_per_sector ) + { + h2fmi_dma_execute_cmd(DMA_CMD_DIR_TX, + h2fmi_dma_meta_chan(fmi), + buf, + h2fmi_dma_meta_fifo(fmi), + spare_per_sector, + sizeof(UInt8), + 1, + NULL); + + buf += spare_per_sector; + spare -= spare_per_sector; + } + + // wait for the page to finish transferring + if ( !h2fmi_tx_wait_page_done(fmi) ) + { + h2fmi_fail(result); + break; + } + } + + if (!result) + { + h2fmi_fmc_disable_all_ces(fmi); + } + + return result; +} + +// ============================================================================= +// private implementation function definitions +// ============================================================================= + +static void h2fmi_start_nand_page_program(h2fmi_t* fmi, + UInt32 page) +{ + UInt32 wCmd1; + + const UInt32 cmd1_addr_done = (FMC_STATUS__CMD1DONE | + FMC_STATUS__ADDRESSDONE); + + // configure FMC for cmd1/addr sequence + h2fmi_config_page_addr(fmi, page); + + if ( fmiNone == fmi->stateMachine.currentMode ) + { + wCmd1 = NAND_CMD__WRITE; + } + else + { + switch ( fmi->stateMachine.wVendorType ) + { + case _kVS_SAMSUNG_2P_2D: + wCmd1 = ( 0==(fmi->stateMachine.page_idx & 1) ? NAND_CMD__WRITE : NAND_CMD__WRITE2_SAMSUNG ); + break; + case _kVS_HYNIX_2P: + wCmd1 = ( 0==(fmi->stateMachine.page_idx & 1) ? NAND_CMD__WRITE : NAND_CMD__WRITE2_HYNIX ); + break; + case _kVS_TOSHIBA_2P: + case _kVS_MICRON_2P: + case _kVS_SAMSUNG_2D: + default: + wCmd1 = NAND_CMD__WRITE; + break; + } + } + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(wCmd1)); + + // start cmd1/addr/cmd2 sequence + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__CMD1_MODE | + FMC_RW_CTRL__ADDR_MODE)); + + // busy wait until cmd1/addr/cmd2 sequence completed + h2fmi_busy_wait(fmi, FMC_STATUS, cmd1_addr_done, cmd1_addr_done); + h2fmi_wr(fmi, FMC_STATUS, cmd1_addr_done); +} + +static void h2fmi_incrementOutstandingOperations(h2fmi_t* fmi) +{ + if ( (_kVS_NONE == fmi->stateMachine.wVendorType ) || ( 1 == ( fmi->stateMachine.page_idx & 1 ) ) ) + { + const UInt32 maxQueueElements = sizeof(fmi->stateMachine.ceCommitQueue.previousCEIndex)/sizeof(fmi->stateMachine.ceCommitQueue.previousCEIndex[0]); + + /** + * Only increment count on "terminal" commits -- we assume here + * that VS will only be 2P or 2D, not 2D+2P. + */ + fmi->stateMachine.wOutstandingCEWriteOperations++; + /** + * Save the working index in case we need it for holdoff + * processing. + */ + fmi->stateMachine.ceCommitQueue.previousCEIndex[ fmi->stateMachine.ceCommitQueue.head++ ] = fmi->stateMachine.page_idx; + if ( fmi->stateMachine.ceCommitQueue.head >= maxQueueElements ) + { + fmi->stateMachine.ceCommitQueue.head = 0; + } + if ( fmi->stateMachine.ceCommitQueue.count < maxQueueElements ) + { + fmi->stateMachine.ceCommitQueue.count++; + } + } +} + +static void h2fmi_decrementOutstandingOperations(h2fmi_t* fmi) +{ + + const UInt32 lastIndex = fmi->stateMachine.lastPageIndex[ fmi->stateMachine.currentCE ]; + + if ( (_kVS_NONE == fmi->stateMachine.wVendorType ) || ( 0 == ( (lastIndex+1) & 1 ) ) ) + { + /** + * Only decrement count on "terminal" waits -- we assume here + * that VS will only be 2P or 2D, not 2D+2P. + */ + fmi->stateMachine.wOutstandingCEWriteOperations--; + } + WMR_ASSERT( ( (Int32)fmi->stateMachine.wOutstandingCEWriteOperations ) >= 0 ); +} + +static void h2fmi_send_write_confirm(h2fmi_t* fmi) +{ + // CMD1 should have been filled out already in h2fmi_prep_program_confirm(). + // start cmd1 + const UInt32 cmd2_done = FMC_STATUS__CMD2DONE; + + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD2_MODE); + + // wait until cmd1 sequence completed + h2fmi_busy_wait(fmi, FMC_STATUS, cmd2_done, cmd2_done); + h2fmi_wr(fmi, FMC_STATUS, cmd2_done); +} + +// ============================================================================= +// dma-only private implementation function definitions +// ============================================================================= + +BOOL32 h2fmi_do_write_setup( h2fmi_t* fmi ) +{ + BOOL32 fContinue = TRUE32; + fmi->stateMachine.currentCE = fmi->stateMachine.chip_enable_array[ fmi->stateMachine.page_idx ]; + + // enable specified nand device + h2fmi_fmc_enable_ce(fmi, fmi->stateMachine.currentCE); + + if (fmi->stateMachine.dirty_ce_mask & (0x1U << fmi->stateMachine.currentCE)) + { + // We must wait for the device to become ready as we have already started a write to it from + // a previous pass. + h2fmi_prepare_for_ready_busy_interrupt(fmi); + + fContinue = FALSE32; + } + + return fContinue ; +} + +void h2fmi_ISR_state_machine_start_page( h2fmi_t* fmi ) +{ + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__START_BIT); + + fmi->stateMachine.currentPage = fmi->stateMachine.page_number_array[ fmi->stateMachine.page_idx ]; + + // mark the current chip enable dirty so that it will be + // checked for ready before next use + fmi->stateMachine.dirty_ce_mask |= (0x1UL << fmi->stateMachine.currentCE); + + // prep for program (all the step prior to xfer). + h2fmi_start_nand_page_program(fmi, fmi->stateMachine.currentPage); + + // enable appropriate interrupt source + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_EN__LAST_FMC_DONE); + + // start FMI write of next page + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + + // Mark when we started out wait ... + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + // Increment the # of pages 'started' across the bus ... + fmi->failureDetails.wNumCE_Executed++; + + h2fmi_prepare_write_confirm(fmi); +} + +static void h2fmi_prepare_write_confirm(h2fmi_t *fmi) +{ + UInt32 wCmd2; + + if ( fmiNone == fmi->stateMachine.currentMode ) + { + wCmd2 = NAND_CMD__WRITE_CONFIRM; + } + else + { + switch ( fmi->stateMachine.wVendorType ) + { + case _kVS_HYNIX_2P: + wCmd2 = ( 0 == (fmi->stateMachine.page_idx & 1) ? NAND_CMD__DUMMY_CONFIRM_HYNIX : NAND_CMD__WRITE_CONFIRM ); + break; + case _kVS_MICRON_2P: + wCmd2 = ( 0 == (fmi->stateMachine.page_idx & 1) ? NAND_CMD__DUMMY_CONFIRM_MICRON : NAND_CMD__WRITE_CONFIRM ); + break; + case _kVS_SAMSUNG_2P_2D: + wCmd2 = ( 0 == (fmi->stateMachine.page_idx & 1) ? NAND_CMD__DUMMY_CONFIRM_SAMSUNG : NAND_CMD__WRITE_CONFIRM ); + break; + case _kVS_TOSHIBA_2P: + wCmd2 = ( 0 == (fmi->stateMachine.page_idx & 1) ? NAND_CMD__DUMMY_CONFIRM_TOSHIBA : NAND_CMD__WRITE_CONFIRM ); + break; + default: + wCmd2 = NAND_CMD__WRITE_CONFIRM; + break; + } + } + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD2(wCmd2)); +} + + +static void h2fmi_write_done_handler( h2fmi_t* fmi ) +{ + h2fmi_clear_interrupts_and_reset_masks(fmi); + h2fmi_fmc_disable_all_ces( fmi ); +#if (H2FMI_WAIT_USING_ISR) + event_signal( &fmi->stateMachine.stateMachineDoneEvent ); +#endif +} + +static void h2fmi_write_ending_write_handler( h2fmi_t* fmi ); + +static void h2fmi_write_wait_for_CE_handlerImpl( h2fmi_t* fmi, const BOOL32 fContinue ) +{ + CE_STATE ceState = h2fmi_get_current_writable_CE_state(fmi); +#if defined(SIMULATE_WRITE_TIMEOUTS) + if ( ++ulWriteTimeoutCount > WRITE_TIMEOUT_MAGIC_NUMBER ) + { + ulWriteTimeoutCount = 0; + ceState = CE_TIMEOUT; + } +#endif + if ( CE_IDLE == ceState ) + { + h2fmi_clear_interrupts_and_reset_masks(fmi); + + const UInt8 bNandStatus = (UInt8)h2fmi_rd(fmi, FMC_NAND_STATUS); + UInt32 status1; + BOOL32 fSuccess; + + switch ( fmi->stateMachine.wVendorType ) + { + case _kVS_TOSHIBA_2P: + status1 = (bNandStatus & NAND_STATUS__TOS_CHIP_STATUS_MASK); + break; + default: + status1 = (bNandStatus & NAND_STATUS__CHIP_STATUS1); + break; + } + + // clear FMC_RW_CTRL, thereby releasing REBHOLD and completing + // current cycle + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + +#if defined(SIMULATE_WRITE_FAILURES) + if ( (ulFailureCount++)>=WRITE_FAILURE_MAGIC_NUMBER ) + { + ulFailureCount = 0; + status1 = ~NAND_STATUS__CHIP_STATUS1_PASS; + WMR_PRINT(ALWAYS,"Simulated write failure on ce %d, index: %d\n", + fmi->stateMachine.currentCE, fmi->stateMachine.page_idx); + _gForcedFailure[ fmi->bus_id ] = 1; + } +#endif + + switch ( fmi->stateMachine.wVendorType ) + { + default: + fSuccess = ( NAND_STATUS__CHIP_STATUS1_PASS == status1 ); + break; + } + + fmi->stateMachine.dirty_ce_mask &= ~(0x1U << fmi->stateMachine.currentCE); + if ( !fSuccess ) + { + // Failed our write -- indicate such ... + fmi->stateMachine.fSuccessful = FALSE32; + // and now go to the exiting handler to wait for dirty CE's to complete. + fmi->stateMachine.state.wr = writeEndingWrite; + h2fmi_recordFirstFailingCE(fmi); +#if (H2FMI_WAIT_USING_ISR) + event_signal( &fmi->stateMachine.stateMachineDoneEvent ); +#endif + h2fmi_write_ending_write_handler( fmi ); + } + else + { + fmi->stateMachine.state.wr = writeXferData; + if ( fContinue ) + { + h2fmi_ISR_state_machine_start_page(fmi); + } + } + h2fmi_decrementOutstandingOperations( fmi ); + fmi->stateMachine.lastPageIndex[ fmi->stateMachine.currentCE ] = INVALID_CE_INDEX; + } + else if ( CE_TIMEOUT == ceState ) + { + // We failed to get what we wanted -- signal error state and move to ending write stage to wait + // for additional CE's to complete. Also clear this CE to indicate that we are no longer waiting on + // it as we timed out. + fmi->stateMachine.fSuccessful = FALSE32; + fmi->stateMachine.state.wr = writeEndingWrite; + fmi->stateMachine.dirty_ce_mask &= ~(0x1U << fmi->stateMachine.currentCE); + h2fmi_recordFirstFailingCE(fmi); + h2fmi_decrementOutstandingOperations( fmi ); + fmi->stateMachine.lastPageIndex[ fmi->stateMachine.currentCE ] = INVALID_CE_INDEX; +#if (H2FMI_WAIT_USING_ISR) + event_signal( &fmi->stateMachine.stateMachineDoneEvent ); +#endif + h2fmi_write_ending_write_handler(fmi); + } +} + +static void h2fmi_write_wait_for_CE_handler( h2fmi_t* fmi ) +{ + h2fmi_write_wait_for_CE_handlerImpl(fmi,TRUE32); +} + +static void h2fmi_write_wait_for_CE_holdOff_handler( h2fmi_t* fmi ) +{ + fmi->stateMachine.wNumTimesHoldoffExecuted++; + + h2fmi_write_wait_for_CE_handlerImpl(fmi,FALSE32); + if ( writeXferData == fmi->stateMachine.state.wr ) + { + /** + * Return the HW to our current CE... + */ + h2fmi_fmc_enable_ce(fmi, fmi->stateMachine.savedCurrentCE); + h2fmi_prepare_write_confirm(fmi); + fmi->stateMachine.currentCE = fmi->stateMachine.savedCurrentCE; + h2fmi_write_Xfer_data_handler2(fmi); + } +} + + +static void h2fmi_write_ending_write_wait_CE_handler( h2fmi_t* fmi ) +{ + CE_STATE ceState = h2fmi_get_current_writable_CE_state(fmi); + if ( CE_IDLE == ceState ) + { + h2fmi_clear_interrupts_and_reset_masks(fmi); + + const UInt8 bNandStatus = (UInt8)h2fmi_rd(fmi, FMC_NAND_STATUS); + const UInt32 status1 = (bNandStatus & NAND_STATUS__CHIP_STATUS1); + + if (NAND_STATUS__CHIP_STATUS1_PASS != status1) + { + fmi->stateMachine.fSuccessful = FALSE32; + // We will still wait for Ready/Busy CE's to complete ... + h2fmi_recordFirstFailingCE(fmi); + } + + // clear FMC_RW_CTRL, thereby releasing REBHOLD and completing + // current cycle + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + UInt32 wCEIndex = 0; + // Find the CE that was dirty ... (we only enter this state when dirty_ce_mask is non-zero) + while ( 0 == (fmi->stateMachine.dirty_ce_mask & (1 << wCEIndex)) ) + { + wCEIndex++; + } + switch ( fmi->stateMachine.wVendorType ) + { + case _kVS_SAMSUNG_2D: + case _kVS_SAMSUNG_2P_2D: + if ( 0 == fmi->stateMachine.currentWriteDie ) + { + fmi->stateMachine.currentWriteDie++; + } + else + { + fmi->stateMachine.currentWriteDie = 0; + fmi->stateMachine.dirty_ce_mask &= ~(1 << wCEIndex); + } + fmi->stateMachine.page_idx++; + break; + default: + fmi->stateMachine.dirty_ce_mask &= ~(1 << wCEIndex); + break; + } + + fmi->stateMachine.currentCE = wCEIndex; + fmi->stateMachine.state.wr = writeEndingWrite; + h2fmi_write_ending_write_handler(fmi); + } + else if ( CE_TIMEOUT == ceState ) + { + // We failed to get what we wanted -- signal error state but continue to wait for any + // other CE's that have not been completed. + h2fmi_recordFirstFailingCE(fmi); + fmi->stateMachine.fSuccessful = FALSE32; + fmi->stateMachine.dirty_ce_mask &= ~(0x1U << fmi->stateMachine.currentCE); + fmi->stateMachine.state.wr = writeEndingWrite; + h2fmi_write_ending_write_handler(fmi); + } +} + +static void h2fmi_write_ending_write_handler( h2fmi_t* fmi ) +{ + if (0 == fmi->stateMachine.dirty_ce_mask) + { + /** + * We're done waiting -- indicate that we're done and break. + */ + h2fmi_fmc_disable_all_ces(fmi); + fmi->stateMachine.state.wr = writeDone; + } + else + { + UInt32 wCEIndex = 0; + // Find the CE that is dirty ... (we only enter this state when dirty_ce_mask is non-zero) + while ( 0 == (fmi->stateMachine.dirty_ce_mask & (1 << wCEIndex)) ) + { + wCEIndex++; + } + h2fmi_fmc_enable_ce(fmi, wCEIndex); + fmi->stateMachine.currentCE = wCEIndex; + switch ( fmi->stateMachine.wVendorType ) + { + case _kVS_SAMSUNG_2P_2D: + case _kVS_SAMSUNG_2D: + fmi->stateMachine.page_idx++; + break; + default: + break; + } + + h2fmi_prepare_for_ready_busy_interrupt(fmi); + + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + fmi->stateMachine.state.wr = writeEndingWriteWaitCE; + // *should* execute writeEndingWriteWaitCE state. + } +} + + +static void h2fmi_write_Xfer_data_handler2(h2fmi_t * fmi) +{ + const BOOL32 contExec = (0 == fmi->wMaxOutstandingCEWriteOperations) + || ( fmi->stateMachine.wOutstandingCEWriteOperations < fmi->stateMachine.wMaxOutstandingCEWriteOperations ) + || ( (_kVS_NONE != fmi->stateMachine.wVendorType) && ( 0 == ( fmi->stateMachine.page_idx & 1 ) ) ); + + if ( contExec ) + { + h2fmi_send_write_confirm(fmi); + h2fmi_incrementOutstandingOperations(fmi); + WMR_ASSERT( fmi->stateMachine.currentCE == fmi->stateMachine.chip_enable_array[ fmi->stateMachine.page_idx ] ); + WMR_ASSERT( fmi->stateMachine.currentCE < ( sizeof(fmi->stateMachine.lastPageIndex) / sizeof(fmi->stateMachine.lastPageIndex[0]) ) ); + fmi->stateMachine.lastPageIndex[ fmi->stateMachine.currentCE ] = fmi->stateMachine.page_idx++; + + if ( fmi->stateMachine.page_idx < fmi->stateMachine.page_count ) + { + /** + * More to do -- loop back and do this again! + */ + if (!h2fmi_do_write_setup(fmi)) + { + /** + * We have to wait for a dirty CE -- our state machine will + * continue to cycle thru in the writeWaitForCE state below when + * it gets called from the FMC_NSRBBDONE interrupt. + */ + fmi->stateMachine.state.wr = writeWaitForCE; + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + } + else + { + /** + * else start a page xfer and break, waiting for our + * LAST_FMC_DONE interrupt again in this state. + */ + h2fmi_ISR_state_machine_start_page(fmi); + } + } + else + { + /** + * We need to finish up waiting on any and all dirty CE's ... + * signal our main routine that we are finishing up so that it + * is (hopefully) ready by the time we really complete. + * + * Fall through to endingWrite stage. + */ + fmi->stateMachine.state.wr = writeEndingWrite; +#if (H2FMI_WAIT_USING_ISR) + event_signal( &fmi->stateMachine.stateMachineDoneEvent ); +#endif + h2fmi_write_ending_write_handler(fmi); + } + } + else + { + const UInt32 maxQueueElements = sizeof(fmi->stateMachine.ceCommitQueue.previousCEIndex)/sizeof(fmi->stateMachine.ceCommitQueue.previousCEIndex[0]); + /** + * We need to hang out and wait on older CE's until enough + * finish to allow us to continue. + */ + fmi->stateMachine.savedCurrentCE = fmi->stateMachine.currentCE; + WMR_ASSERT( fmi->stateMachine.ceCommitQueue.count > 0 ); + + fmi->stateMachine.currentCE = fmi->stateMachine.chip_enable_array[ fmi->stateMachine.ceCommitQueue.previousCEIndex[ fmi->stateMachine.ceCommitQueue.tail++ ] ]; + if ( fmi->stateMachine.ceCommitQueue.tail >= maxQueueElements ) + { + fmi->stateMachine.ceCommitQueue.tail = 0; + } + fmi->stateMachine.ceCommitQueue.count--; + + /** + * Enable oldest CE and set up to wait for status interrupt. + */ + h2fmi_fmc_enable_ce(fmi, fmi->stateMachine.currentCE); + + h2fmi_prepare_for_ready_busy_interrupt(fmi); + fmi->stateMachine.state.wr = writeWaitingForNumCELimit; + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + } +} + +static void h2fmi_write_Xfer_data_handler( h2fmi_t* fmi ) +{ + fmi->isr_condition = h2fmi_rd(fmi, FMI_INT_PEND); + if (FMI_INT_PEND__LAST_FMC_DONE != (fmi->isr_condition & FMI_INT_PEND__LAST_FMC_DONE)) + { + BOOL32 fTimeout = WMR_HAS_TIME_ELAPSED_TICKS(fmi->stateMachine.waitStartTicks, fmi->stateMachine.wPageTimeoutTicks); + + if ( fTimeout ) + { + fmi->stateMachine.fSuccessful = FALSE32; + // We failed to get what we wanted -- goto error state and complete. + fmi->stateMachine.state.wr = writeEndingWrite; + h2fmi_write_ending_write_handler(fmi); + } + } + else + { + h2fmi_clear_interrupts_and_reset_masks(fmi); + h2fmi_write_Xfer_data_handler2(fmi); + } +} + +static void h2fmi_write_setup_handler( h2fmi_t* fmi ) +{ + if (!h2fmi_do_write_setup(fmi)) + { + /** + * We have to wait for a dirty CE -- break so that our state + * machine continues to cycle thru in the writeWaitForCE state + * below. + */ + fmi->stateMachine.state.wr = writeWaitForCE; + fmi->stateMachine.waitStartTicks = WMR_CLOCK_TICKS(); + } + else + { + /** + * else start a page xfer and fall through to the xfer data + * stage below. + */ + h2fmi_ISR_state_machine_start_page(fmi); + fmi->stateMachine.state.wr = writeXferData; + h2fmi_write_Xfer_data_handler(fmi); + } +} + +static void h2fmi_write_idle_handler( h2fmi_t* fmi ) +{ + UInt32 Idx = 0; + + fmi->stateMachine.dirty_ce_mask = 0; + fmi->stateMachine.currentWriteDie = 0; + fmi->stateMachine.page_idx = 0; + fmi->stateMachine.fSuccessful = TRUE32; + fmi->stateMachine.wNumTimesHoldoffExecuted = 0; + fmi->stateMachine.wOutstandingCEWriteOperations = 0; + fmi->stateMachine.wMaxOutstandingCEWriteOperations = ( 0 == fmi->stateMachine.wVendorType ? + fmi->wMaxOutstandingCEWriteOperations : 1*fmi->wMaxOutstandingCEWriteOperations ); + + for(Idx = 0; Idx < H2FMI_MAX_CE_TOTAL; Idx++) + { + fmi->stateMachine.lastPageIndex[Idx] = INVALID_CE_INDEX; + } + + fmi->stateMachine.ceCommitQueue.count = 0; + fmi->stateMachine.ceCommitQueue.head = 0; + fmi->stateMachine.ceCommitQueue.tail = 0; + + BOOL32 bSuccess = h2fmi_common_idle_handler(fmi); + WMR_ASSERT(bSuccess == TRUE32); + + // Enter write mode so DMA transfer can start early +#if FMI_VERSION >= 3 + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__WRITE); +#endif // FMI_VERSION >= 3 + + bSuccess = h2fmi_start_dma(fmi); + WMR_ASSERT(bSuccess == TRUE32); + + fmi->stateMachine.state.wr = writeSetup; + h2fmi_write_setup_handler(fmi); +} + +typedef void (*h2fmi_isrWriteStateHandler)( h2fmi_t* fmi ); + +#if (!H2FMI_READONLY) +static const h2fmi_isrWriteStateHandler writeStateHandlerTable[] = { + h2fmi_write_idle_handler, // writeIdle = 0, + h2fmi_write_setup_handler, // writeSetup, + h2fmi_write_wait_for_CE_handler, // writeWaitForCE, + h2fmi_write_Xfer_data_handler, // writeXferData, + h2fmi_write_ending_write_handler, // writeEndingWrite, + h2fmi_write_ending_write_wait_CE_handler, // writeEndingWriteWaitCE, + h2fmi_write_done_handler, // writeDone + h2fmi_write_wait_for_CE_holdOff_handler // writeWaitingForNumCELimit +}; + +void h2fmi_handle_write_ISR_state_machine( h2fmi_t* fmi ) +{ + WMR_ASSERT(fmi->stateMachine.currentMode == fmiWrite); + WMR_ASSERT(fmi->stateMachine.state.wr <= writeWaitingForNumCELimit); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + { + int k = (int)fmi->stateMachine.state.wr; + h2fmi_instrument_bit_set(2); + while (k-- > 0) + { + h2fmi_instrument_bit_clear(2); + h2fmi_instrument_bit_set(2); + } + } +#endif + + writeStateHandlerTable[ fmi->stateMachine.state.wr ]( fmi ); + +#if ( H2FMI_INSTRUMENT_BUS_1 ) + h2fmi_instrument_bit_clear(2); +#endif +} +#else +void h2fmi_handle_write_ISR_state_machine( h2fmi_t* fmi ) +{ + // Someone's trying to write in a read-only config... + WMR_ASSERT(0); +} +#endif /* !H2FMI_READONLY */ + + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/boot/H2fmi_bootrom.c b/drivers/apple/h2fmi/boot/H2fmi_bootrom.c new file mode 100644 index 0000000..8fafeed --- /dev/null +++ b/drivers/apple/h2fmi/boot/H2fmi_bootrom.c @@ -0,0 +1,1018 @@ +// ***************************************************************************** +// +// File: H2fmi_bootrom.c +// +// ***************************************************************************** +// +// Notes: +// +// - all code implementing the SecureROM nand boot are contained in this +// file and the headers "H2fmi_regs.h" and "H2fmi_private.h" +// +// +// - care has been taken to make certain that SecureROM-only code will only +// get compiled when building SecureROM or when building for debug in +// order to facilitate testing +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#include "H2fmi_private.h" + +#include +#include +#include + +#include + +#include + + +// ============================================================================= +// SecureROM-only preprocessor constants +// ============================================================================= + +// this symbol normally comes from , but +// it is not normally available outside of SecureROM builds; for our +// testing purposes, make certain it is present for the moment +#if (!defined(NAND_BOOTBLOCK_OFFSET)) +#define NAND_BOOTBLOCK_OFFSET 2 +#endif + + +// ============================================================================= +// SecureROM-only static variable declarations +// ============================================================================= + +h2fmi_t g_boot_fmi; + + +// ============================================================================= +// implementation function declarations shared between SecureROM and iBoot +// ============================================================================= + +static int h2fmi_get_clock(h2fmi_t* fmi); +static int h2fmi_get_gate(h2fmi_t* fmi); +static int h2fmi_get_bch_gate(h2fmi_t* fmi); +static uint32_t h2fmi_nanos_to_clocks(uint64_t nanos_per_clock, uint32_t min_nanos); +static void h2fmi_calc_init_timings(h2fmi_t* fmi); +static void h2fmi_calc_timing_clocks(uint64_t nanos_per_clock, uint32_t min_cycle_nanos, uint32_t min_setup_nanos, uint32_t min_hold_nanos, uint32_t* setup_clocks, uint32_t* hold_clocks); +static uint32_t h2fmi_calc_read_capture(uint32_t hold_clocks); +static uint32_t h2fmi_min(uint32_t first, uint32_t second); +static bool h2fmi_start_nand_page_read(h2fmi_t* fmi, uint32_t page); +static bool h2fmi_wait_ready(h2fmi_t* fmi, uint8_t io_mask, uint8_t io_val); +static void h2fmi_wait_millis(uint32_t millis); + + +// ============================================================================= +// implementation function declarations used by SecureROM only +// ============================================================================= + +static bool h2fmi_setup_bootpage_read(h2fmi_t* fmi, uint32_t cs, uint32_t page); +static bool h2fmi_pio_read_bootpage(h2fmi_t* fmi, uint32_t cs, uint32_t page, uint8_t* buf); +static bool h2fmi_pio_discard_bootpage(h2fmi_t* fmi, uint32_t cs, uint32_t page); + + +// ============================================================================= +// SecureROM-only public interface function definitions +// ============================================================================= + +int nand_read_bootblock(u_int8_t interface, + u_int8_t ce, + void* address, + size_t* size) +{ + uint8_t* buffer = (uint8_t*)address; + size_t resid; + uint32_t page; + uint32_t chipid; + h2fmi_t* fmi = &g_boot_fmi; + + dprintf(DEBUG_INFO, "reading bootcode from FMI%d:CE%d to %p\n", + interface, ce, buffer); + + // check range of interface parameter + if ((0 != interface) && (1 != interface)) + { + dprintf(DEBUG_INFO, "failed: invalid interface, %d\n", interface); + return -1; + } + + // check range of chip enable parameter + if (ce >= H2FMI_MAX_DEVICE) + { + dprintf(DEBUG_INFO, "failed: invalid ce, %d\n", ce); + return -1; + } + + // perform minimum FMI initialization + if (!h2fmi_init_minimal(fmi, interface)) + { + dprintf(DEBUG_INFO, "failed: unable to initialize FMI%d\n", interface); + return -1; + } + + // reset the nand device + if (!h2fmi_nand_reset(fmi, ce)) + { + dprintf(DEBUG_INFO, "failed: unable to reset nand device on CE%d\n", ce); + return -1; + } + + // read id from nand device + if (!h2fmi_nand_read_id(fmi, ce, &chipid)) + { + dprintf(DEBUG_INFO, "failed: unable to read chip id\n"); + return -1; + } + + // confirm that chipid is not invalid + if (h2fmi_is_chipid_invalid(chipid)) + { + dprintf(DEBUG_INFO, "failed: invalid chip id, 0x%08X\n", chipid); + return -1; + } + + // skip a couple of initial pages in the bootblock + for (page = 0; page < NAND_BOOTBLOCK_OFFSET; page++) + { + dprintf(DEBUG_SPEW, "discarding page %d\n", page); + if (!h2fmi_pio_discard_bootpage(fmi, ce, page)) + { + dprintf(DEBUG_INFO, "failed: unable to discard initial page, %d\n", page); + return -1; + } + } + + // read out the pages... + for (resid = *size; + resid >= H2FMI_BOOT_BYTES_PER_PAGE; + resid -= H2FMI_BOOT_BYTES_PER_PAGE) + { + dprintf(DEBUG_SPEW, "reading page %d to %p\n", page, buffer); + if (!h2fmi_pio_read_bootpage(fmi, ce, page, buffer)) + break; + + page++; + buffer += H2FMI_BOOT_BYTES_PER_PAGE; + } + + // gate the FMI subsystem and gate its dedicated HCLK clock domain + h2fmi_gate(fmi); + + // compute transferred size + *size = (page - NAND_BOOTBLOCK_OFFSET) * H2FMI_BOOT_BYTES_PER_PAGE; + + if (0 == *size) + { + dprintf(DEBUG_INFO, "failed: read 0 bytes\n"); + return -1; + } + + dprintf(DEBUG_INFO, "read %u bytes\n", *size); + return 0; +} + + +// ============================================================================= +// implementation function definitions shared between SecureROM and iBoot +// ============================================================================= + +bool h2fmi_init_minimal(h2fmi_t* fmi, + uint32_t interface) +{ + bool result = true; + + // only interface numbers 0 and 1 are valid + if ((interface != 0) && (interface != 1)) + { + h2fmi_fail(result); + } + else + { + // record which interface is being used + fmi->regs = (interface == 0) ? FMI0 : FMI1; + + // "get the clock rolling" for the dedicated HCLK clock domain + h2fmi_ungate(fmi); + + // reset the FMI subsystem + h2fmi_reset(fmi); + + // configure safe initial bus timings + h2fmi_calc_init_timings(fmi); + + // configure geometry as a "least common denominator" device + fmi->num_of_ce = 1; + fmi->pages_per_block = 128; + fmi->sectors_per_page = 4; + fmi->bytes_per_spare = 64; + fmi->blocks_per_ce = 1; + fmi->bytes_per_meta = 0; + fmi->banks_per_ce = 1; + } + + return result; +} + + +bool h2fmi_is_chipid_invalid(uint32_t id) +{ + return (id == 0x00000000) || (id == 0xFFFFFFFF); +} + + +void h2fmi_ungate(h2fmi_t* fmi) +{ + // enable the general FMI clock + clock_gate(h2fmi_get_gate(fmi), true); + +#if FMI_VERSION >= 2 + // H3 needs the BCH clock enabled as well + clock_gate(h2fmi_get_bch_gate(fmi), true); +#endif +} + + +void h2fmi_gate(h2fmi_t* fmi) +{ + // disable the specified FMI block + clock_gate(h2fmi_get_gate(fmi), false); + +#if FMI_VERSION >= 2 + clock_gate(h2fmi_get_bch_gate(fmi), false); +#endif +} + + +void h2fmi_reset(h2fmi_t* fmi) +{ + // reset the specified FMI subsystem + clock_reset_device(h2fmi_get_gate(fmi)); + + // turn the FMC on + h2fmi_wr(fmi, FMC_ON, FMC_ON__ENABLE); + + // restore interface timings + h2fmi_wr(fmi, FMC_IF_CTRL, fmi->if_ctrl); +} + + +#define timing_nanos(cycles, hz) ((((uint64_t)1000000000) * cycles) / hz) + +void h2fmi_calc_bus_timings(h2fmi_t* fmi, + uint32_t min_read_cycle_nanos, + uint32_t min_read_setup_nanos, + uint32_t min_read_hold_nanos, + uint32_t min_write_cycle_nanos, + uint32_t min_write_setup_nanos, + uint32_t min_write_hold_nanos) +{ + uint32_t read_setup_clocks; + uint32_t read_hold_clocks; + uint32_t read_capture_clocks; + uint32_t read_dccycle_clocks; + uint32_t write_setup_clocks; + uint32_t write_hold_clocks; + + // Get nand subsystem clock speed in Hz, and use that to + // calculate how many nanoseconds per clock. + const uint64_t fmi_clock_hz = clock_get_frequency(h2fmi_get_clock(fmi)); + const uint64_t fmi_nanos_per_clock = timing_nanos(1, fmi_clock_hz); + + // Calculate setup and hold clocks to meet write timings. + h2fmi_calc_timing_clocks(fmi_nanos_per_clock, + min_write_cycle_nanos, min_write_setup_nanos, min_write_hold_nanos, + &write_setup_clocks, &write_hold_clocks); + + // Calculate setup and hold clocks as well as capture clocks to meet read timings. + h2fmi_calc_timing_clocks(fmi_nanos_per_clock, + min_read_cycle_nanos, min_read_setup_nanos, min_read_hold_nanos, + &read_setup_clocks, &read_hold_clocks); + read_capture_clocks = h2fmi_calc_read_capture(read_hold_clocks); + + // since we are using very slow cycles use FMC_IF_CTRL__DCCYCLE = 0 + read_dccycle_clocks = 0; + + // Calculate and record FMC_IF_CTRL setting from these calculated timings. + fmi->if_ctrl = (FMC_IF_CTRL__DCCYCLE(read_dccycle_clocks) | + FMC_IF_CTRL__REB_SETUP(read_setup_clocks) | + FMC_IF_CTRL__REB_HOLD(read_hold_clocks) | + FMC_IF_CTRL__WEB_SETUP(write_setup_clocks) | + FMC_IF_CTRL__WEB_HOLD(write_hold_clocks)); + + // When debugging, report the timing values that were calculated. + if (H2FMI_DEBUG) + { + const uint64_t read_setup_nanos = timing_nanos(read_setup_clocks, + fmi_clock_hz); + const uint64_t read_hold_nanos = timing_nanos(read_hold_clocks, + fmi_clock_hz); + const uint64_t read_sample_nanos = timing_nanos(read_dccycle_clocks, + fmi_clock_hz); + const uint64_t write_setup_nanos = timing_nanos(write_setup_clocks, + fmi_clock_hz); + const uint64_t write_hold_nanos = timing_nanos(write_hold_clocks, + fmi_clock_hz); + + dprintf(DEBUG_SPEW, "FMI clock is %d Hz.\n", fmi_clock_hz); + dprintf(DEBUG_SPEW, "read: setup = %d ns; hold = %d ns; sample = %d ns\n", + read_setup_nanos, read_hold_nanos, read_sample_nanos); + dprintf(DEBUG_SPEW, "write: setup = %d ns; hold = %d ns\n", + write_setup_nanos, write_hold_nanos); + dprintf(DEBUG_SPEW, "FMC_IF_CTRL__DCCYCLE = %d\n", read_dccycle_clocks); + dprintf(DEBUG_SPEW, "FMC_IF_CTRL__REB_SETUP = %d\n", read_setup_clocks); + dprintf(DEBUG_SPEW, "FMC_IF_CTRL__REB_HOLD = %d\n", read_hold_clocks); + dprintf(DEBUG_SPEW, "FMC_IF_CTRL__WEB_SETUP = %d\n", write_setup_clocks); + dprintf(DEBUG_SPEW, "FMC_IF_CTRL__WEB_HOLD = %d\n", write_hold_clocks); + } + + // NOTE: hard code timing for temporary workaround...investigation to be continued + fmi->if_ctrl = 0x2121; + + // Apply calculated bus timings. + h2fmi_wr(fmi, FMC_IF_CTRL, fmi->if_ctrl); +} + + +bool h2fmi_wait_done(h2fmi_t* fmi, + uint32_t reg, + uint32_t mask, + uint32_t bits) +{ + bool result = true; + + utime_t check_time = H2FMI_DEFAULT_TIMEOUT_MICROS; + utime_t start_time = system_time(); + + // wait for specified bits to be set + while ((h2fmi_rd(fmi, reg) & mask) != bits) + { + if (time_has_elapsed(start_time, check_time)) + { + h2fmi_fail(result); + break; + } + + task_yield(); + } + + // clear specified bits + h2fmi_wr(fmi, reg, bits); + + return result; +} + + +bool h2fmi_wait_dma_task_pending(h2fmi_t* fmi) +{ + bool result = true; + + utime_t check_time = H2FMI_DEFAULT_TIMEOUT_MICROS; + utime_t start_time = system_time(); + + // wait for FMI to complete transfer of sector to fifo + const uint32_t msk = FMI_DEBUG0__DMA_TASKS_PENDING(0x3); + + // wait for FMI to to be ready for at least one dma task + while ((h2fmi_rd(fmi, FMI_DEBUG0) & msk) == 0) + { + if (time_has_elapsed(start_time, check_time)) + { + h2fmi_fail(result); + break; + } + + task_yield(); + } + + return result; +} + + +void h2fmi_config_page_addr(h2fmi_t* fmi, + uint32_t page) +{ + const uint32_t page_addr_size = 5; + + const uint32_t page_addr_2 = (page >> 16) & 0xFF; + const uint32_t page_addr_1 = (page >> 8) & 0xFF; + const uint32_t page_addr_0 = (page >> 0) & 0xFF; + + h2fmi_wr(fmi, FMC_ADDR1, (FMC_ADDR1__SEQ7(0x00) | + FMC_ADDR1__SEQ6(0x00) | + FMC_ADDR1__SEQ5(0x00) | + FMC_ADDR1__SEQ4(page_addr_2))); + h2fmi_wr(fmi, FMC_ADDR0, (FMC_ADDR0__SEQ3(page_addr_1) | + FMC_ADDR0__SEQ2(page_addr_0) | + FMC_ADDR0__SEQ1(0x00) | + FMC_ADDR0__SEQ0(0x00))); + + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(page_addr_size - 1)); +} + + +void h2fmi_clean_ecc(h2fmi_t* fmi) +{ + // clean status bits by setting them +#if FMI_VERSION == 0 + h2fmi_wr(fmi, ECC_PND, (ECC_PND__BCH_ALL_FF | + ECC_PND__SECTOR_ERROR_ALERT | + ECC_PND__UNCORRECTABLE)); + + // clean all sector results by setting the error flag + h2fmi_wr(fmi, ECC_RESULT, ECC_RESULT__ERROR_FLAG); +#else + h2fmi_wr(fmi, ECC_PND, (ECC_PND__SOME_ALL_FF | + ECC_PND__SOME_ERROR_ALERT | + ECC_PND__UNCORRECTABLE)); + + h2fmi_wr(fmi, ECC_RESULT, ECC_RESULT_FIFO__RESET_FIFO); +#endif +} + + +void h2fmi_fmc_read_data(h2fmi_t* fmi, + uint32_t size, + uint8_t* data) +{ + register uint32_t idx; + + // employ REBHOLD to hold nRD low so that each byte on the bus can + // be read, one at a time, from NAND_STATUS + h2fmi_wr(fmi, FMC_DATANUM, FMC_DATANUM__NUM(0)); + for (idx = 0; idx < size; idx++) + { + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__REBHOLD | + FMC_RW_CTRL__RD_MODE)); + + data[idx] = (uint8_t)h2fmi_rd(fmi, FMC_NAND_STATUS); + + // clear FMC_RW_CTRL, thereby releasing REBHOLD and completing + // current read cycle + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + } +} + + +bool h2fmi_nand_reset(h2fmi_t* fmi, + h2fmi_ce_t ce) +{ + bool result = true; + + // enable specified nand device + h2fmi_wr(fmi, FMC_CE_CTRL, FMC_CE_CTRL__CEB(ce)); + + // perform reset command + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__RESET)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + // wait until cmd sent on bus + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__CMD1DONE, + FMC_STATUS__CMD1DONE)) + { + h2fmi_fail(result); + } + + // wait 20 ms to allow nand to reset + h2fmi_wait_millis(20); + + // disable all nand devices + h2fmi_wr(fmi, FMC_CE_CTRL, 0x0); + + return result; +} + + +bool h2fmi_nand_read_id(h2fmi_t* fmi, + h2fmi_ce_t ce, + uint32_t* id) +{ + const uint32_t cmd1_addr_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD1DONE); + bool result = true; + + uint8_t tmp[H2FMI_NAND_ID_SIZE]; + + // enable specified nand device + h2fmi_wr(fmi, FMC_CE_CTRL, FMC_CE_CTRL__CEB(ce)); + + // set up Read Id command and address cycles + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ_ID)); + h2fmi_wr(fmi, FMC_ADDR0, FMC_ADDR0__SEQ0(0x00)); + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(0)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD1_MODE)); + + // wait until cmd & addr completion + if (!h2fmi_wait_done(fmi, FMC_STATUS, + cmd1_addr_done, + cmd1_addr_done)) + { + h2fmi_fail(result); + } + else + { + // read correct number of id bytes into local temporary + h2fmi_fmc_read_data(fmi, H2FMI_NAND_ID_SIZE, tmp); + + // drop last byte and endian flop the rest to get condensed + // 32-bit id format + *id = ((((uint32_t)tmp[3]) << 24) | + (((uint32_t)tmp[2]) << 16) | + (((uint32_t)tmp[1]) << 8) | + (((uint32_t)tmp[0]) << 0)); + } + + // disable all nand devices + h2fmi_wr(fmi, FMC_CE_CTRL, 0x0); + + return result; +} + + +bool h2fmi_pio_read_sector(h2fmi_t* fmi, + void* buf) +{ + bool result = true; + + const uint32_t words_per_loop = 8; + register uint32_t* dest = (uint32_t*)buf; + register uint32_t word_idx = (H2FMI_WORDS_PER_SECTOR / words_per_loop); + + // wait for FMI to be ready with data in fifo for DMA to transfer out + if (!h2fmi_wait_dma_task_pending(fmi)) + { + // timed out + h2fmi_fail(result); + } + else + { + // read data from the fifo + do + { + register uint32_t tmp0; + register uint32_t tmp1; + register uint32_t tmp2; + register uint32_t tmp3; + register uint32_t tmp4; + register uint32_t tmp5; + register uint32_t tmp6; + register uint32_t tmp7; + + tmp0 = h2fmi_rd(fmi, FMI_DATA_BUF); + tmp1 = h2fmi_rd(fmi, FMI_DATA_BUF); + tmp2 = h2fmi_rd(fmi, FMI_DATA_BUF); + tmp3 = h2fmi_rd(fmi, FMI_DATA_BUF); + tmp4 = h2fmi_rd(fmi, FMI_DATA_BUF); + tmp5 = h2fmi_rd(fmi, FMI_DATA_BUF); + tmp6 = h2fmi_rd(fmi, FMI_DATA_BUF); + tmp7 = h2fmi_rd(fmi, FMI_DATA_BUF); + + *dest++ = tmp0; + *dest++ = tmp1; + *dest++ = tmp2; + *dest++ = tmp3; + *dest++ = tmp4; + *dest++ = tmp5; + *dest++ = tmp6; + *dest++ = tmp7; + } + while (--word_idx); + } + + return result; +} + + +// ============================================================================= +// static implementation function definitions used by both SecureROM and iBoot +// ============================================================================= + +static int h2fmi_get_clock(h2fmi_t* fmi) +{ + return CLK_PCLK; +} + + +static int h2fmi_get_gate(h2fmi_t* fmi) +{ + return (FMI0 == fmi->regs) ? CLK_FMI0 : CLK_FMI1; +} + +#if FMI_VERSION >= 2 +static int h2fmi_get_bch_gate(h2fmi_t* fmi) +{ + return (FMI0 == fmi->regs) ? CLK_FMI0BCH : CLK_FMI1BCH; +} +#endif + +static uint32_t h2fmi_nanos_to_clocks(uint64_t nanos_per_clock, + uint32_t min_nanos) +{ + return (uint32_t)(((uint64_t)min_nanos / nanos_per_clock) + + ((uint64_t)min_nanos % nanos_per_clock ? 1 : 0)); +} + + +static void h2fmi_calc_init_timings(h2fmi_t* fmi) +{ + h2fmi_calc_bus_timings(fmi, + H2FMI_INIT_READ_CYCLE_NANOS, + H2FMI_INIT_READ_SETUP_NANOS, + H2FMI_INIT_READ_HOLD_NANOS, + H2FMI_INIT_WRITE_CYCLE_NANOS, + H2FMI_INIT_WRITE_SETUP_NANOS, + H2FMI_INIT_WRITE_HOLD_NANOS); +} + + +static void h2fmi_calc_timing_clocks(uint64_t nanos_per_clock, + uint32_t min_cycle_nanos, + uint32_t min_setup_nanos, + uint32_t min_hold_nanos, + uint32_t* setup_clocks, + uint32_t* hold_clocks) +{ + // Calculate clock cycle counts from the nand's specified parameters. + uint32_t cycle = h2fmi_nanos_to_clocks(nanos_per_clock, min_cycle_nanos); + uint32_t setup = h2fmi_nanos_to_clocks(nanos_per_clock, min_setup_nanos); + uint32_t hold = h2fmi_nanos_to_clocks(nanos_per_clock, min_hold_nanos); + + // If setup and hold combined are less than minimum cycle time, extend the hold time. + if ((hold + setup) < cycle) + { + hold = cycle - setup; + } + + // Hold and setup clock counts are expressed zero based. + hold--; + setup--; + + // Don't allow single clock setup or hold times. As observed + // using a scope, such timings create degenerate sawtooth + // waveforms that fall short of reaching Vmax. + if (hold == 0) + { + hold = 1; + } + if (setup == 0) + { + setup = 1; + } + + // Pass the calculated values back up by reference, making certain + // that none exceed the maximum timing clock counts H2 can use. + *setup_clocks = h2fmi_min(setup, FMC_IF_CTRL__TIMING_MAX_CLOCKS); + *hold_clocks = h2fmi_min(hold, FMC_IF_CTRL__TIMING_MAX_CLOCKS); +} + + +static uint32_t h2fmi_min(uint32_t first, + uint32_t second) +{ + return (first < second) ? first : second; +} + + +static bool h2fmi_start_nand_page_read(h2fmi_t* fmi, + uint32_t page) +{ + const uint32_t cmd1_addr_cmd2_done = (FMC_STATUS__ADDRESSDONE | + FMC_STATUS__CMD2DONE | + FMC_STATUS__CMD1DONE); + + bool result = true; + + // configure FMC for cmd1/addr/cmd2 sequence + h2fmi_config_page_addr(fmi, page); + h2fmi_wr(fmi, FMC_CMD, (FMC_CMD__CMD2(NAND_CMD__READ_CONFIRM) | + FMC_CMD__CMD1(NAND_CMD__READ))); + + // start cmd1/addr/cmd2 sequence + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__ADDR_MODE | + FMC_RW_CTRL__CMD2_MODE | + FMC_RW_CTRL__CMD1_MODE)); + + // wait until cmd1/addr/cmd2 sequence completed + if (!h2fmi_wait_done(fmi, FMC_STATUS, + cmd1_addr_cmd2_done, + cmd1_addr_cmd2_done)) + { + h2fmi_fail(result); + } + // wait for ready using Read Status command + else if (!h2fmi_wait_ready(fmi, + NAND_STATUS__DATA_CACHE_RB, + NAND_STATUS__DATA_CACHE_RB_READY)) + { + h2fmi_fail(result); + } + else + { + // reissue cmd1 and wait until completed + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__CMD1DONE, + FMC_STATUS__CMD1DONE)) + { + h2fmi_fail(result); + } + } + + return result; +} + + +static uint32_t h2fmi_calc_read_capture(uint32_t hold_clocks) +{ + // As long as max timing clock count is not exceeded, set it to + // one greater than hold_clocks. + return h2fmi_min(hold_clocks + 1, FMC_IF_CTRL__TIMING_MAX_CLOCKS); +} + + +static bool h2fmi_wait_ready(h2fmi_t* fmi, + uint8_t io_mask, + uint8_t io_val) +{ + bool result = true; + + // turn off RBBEN and configure it to use look for I/O bit 6 (0x40) + h2fmi_wr(fmi, FMC_IF_CTRL, (~FMC_IF_CTRL__RBBEN & h2fmi_rd(fmi, FMC_IF_CTRL))); + h2fmi_wr(fmi, FMC_RBB_CONFIG, (FMC_RBB_CONFIG__POL(io_val) | + FMC_RBB_CONFIG__POS(io_mask))); + + // exec Read Status command cycle + h2fmi_wr(fmi, FMC_CMD, FMC_CMD__CMD1(NAND_CMD__READ_STATUS)); + h2fmi_wr(fmi, FMC_RW_CTRL, FMC_RW_CTRL__CMD1_MODE); + + // wait until command cycle completed + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__CMD1DONE, + FMC_STATUS__CMD1DONE)) + { + h2fmi_fail(result); + } + else + { + // clear the FMC_STATUS__NSRBBDONE bit in FMC_STATUS + h2fmi_wr(fmi, FMC_STATUS, FMC_STATUS__NSRBBDONE); + + // set up read cycle with REBHOLD to wait for ready bit to be + // set on I/O lines + h2fmi_wr(fmi, FMC_DATANUM, FMC_DATANUM__NUM(0)); + h2fmi_wr(fmi, FMC_RW_CTRL, (FMC_RW_CTRL__REBHOLD | FMC_RW_CTRL__RD_MODE)); + + // wait until NSRBB done signaled + if (!h2fmi_wait_done(fmi, FMC_STATUS, + FMC_STATUS__NSRBBDONE, + FMC_STATUS__NSRBBDONE)) + { + h2fmi_fail(result); + } + + // clear FMC_RW_CTRL, thereby releasing REBHOLD and completing + // current read cycle + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + } + + return result; +} + + +static void h2fmi_wait_millis(uint32_t millis) +{ + // task_sleep for millis * 1000 us. + task_sleep(millis * 1000); +} + + +// ============================================================================= +// static implementation function definitions used by SecureROM only +// ============================================================================= + +static bool h2fmi_setup_bootpage_read(h2fmi_t* fmi, + uint32_t ce, + uint32_t page) +{ + bool result = true; +#if FMI_VERSION > 3 + uint32_t sector_idx; +#endif + // enable specified nand device + h2fmi_wr(fmi, FMC_CE_CTRL, FMC_CE_CTRL__CEB(ce)); + + // start a nand page read operation + if (!h2fmi_start_nand_page_read(fmi, page)) + { + h2fmi_fail(result); + } + else + { +#if FMI_VERSION == 0 + // configure bootblock sector format: 512 bytes, no meta, 16-bit ECC + h2fmi_wr(fmi, FMI_CONFIG, (FMI_CONFIG__LBA_MODE__NORMAL | + FMI_CONFIG__META_PER_ENVELOPE(0) | + FMI_CONFIG__META_PER_PAGE(0) | + FMI_CONFIG__PAGE_SIZE__512 | + FMI_CONFIG__ECC_MODE__16BIT)); + + // we don't care about sector error alerts + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(17) | + ECC_CON1__INT_ENABLE(0))); +#elif FMI_VERSION <= 3 + // configure bootblock ecc: 30-bit ECC + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_MAX_CORRECTION); + + // configure bootblock sector format: 512 bytes, no meta + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__BYTES_PER_SECTOR(512) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1) | + FMI_DATA_SIZE__META_BYTES_PER_ENVELOPE(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0))); + + // we don't care about sector error alerts + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(0) | + ECC_CON1__INT_ENABLE(0))); +#else + // Use randomizer + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__ECC_MAX_CORRECTION | + FMI_CONFIG__SCRAMBLE_SEED | + FMI_CONFIG__ENABLE_WHITENING); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__META_BYTES_PER_ENVELOPE(0) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(0) | + FMI_DATA_SIZE__BYTES_PER_SECTOR(512) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1))); + // Use written-mark, so fewer stuck bits are allowed + h2fmi_wr(fmi, ECC_CON1, (ECC_CON1__ERROR_ALERT_LEVEL(0) | + ECC_CON1__INT_ENABLE(0))); + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__RESET_SEED); + for (sector_idx = 0; sector_idx < H2FMI_BOOT_SECTORS_PER_PAGE; sector_idx++) + { + h2fmi_wr(fmi, FMI_SCRAMBLER_SEED_FIFO, (page + sector_idx)); + } +#endif + + // FMI manages ECC interaction, so make certain we aren't + // unmasking any interrupt sources + h2fmi_wr(fmi, ECC_MASK, 0x0); + } + + return result; +} + + +static bool h2fmi_pio_read_bootpage(h2fmi_t* fmi, + uint32_t ce, + uint32_t page, + uint8_t* buf) +{ +#if FMI_VERSION > 0 + bool foundDirty = false; +#endif + bool result = true; + + uint32_t sector_idx; + + // setup a nand bootpage read operation + if (!h2fmi_setup_bootpage_read(fmi, ce, page)) + { + h2fmi_fail(result); + } + else + { + // for each sector... + for (sector_idx = 0; sector_idx < H2FMI_BOOT_SECTORS_PER_PAGE; sector_idx++) + { + const uint32_t buf_offset = sector_idx * H2FMI_BYTES_PER_SECTOR; + + // clean up any ECC block state before starting transfer + h2fmi_clean_ecc(fmi); + + // start FMI read + h2fmi_wr(fmi, FMI_CONTROL, (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT)); + + // read boot sector data from fifo + if (!h2fmi_pio_read_sector(fmi, &buf[buf_offset])) + { + h2fmi_fail(result); + break; + } + // handle interesting ECC conditions + else + { + const uint32_t ecc_pnd = h2fmi_rd(fmi, ECC_PND); + + if (ecc_pnd & ECC_PND__UNCORRECTABLE) + { + h2fmi_fail(result); + break; + } +#if FMI_VERSION == 0 + else if (ecc_pnd & ECC_PND__BCH_ALL_FF) +#else + else if (ecc_pnd & ECC_PND__SOME_ALL_FF) +#endif + { +#if FMI_VERSION == 0 + // return false, but don't necessarily "fail" + result = false; + break; +#else + dprintf(DEBUG_SPEW, "clean sector page %d sector %d\n", page, sector_idx); +#endif + } +#if FMI_VERSION > 0 + else + { + // since BCH of 0xFF is 0xFF, check all sectors for clean + foundDirty = true; + } +#endif + } + } + } + + // disable all nand devices + h2fmi_wr(fmi, FMC_CE_CTRL, 0x0); + +#if FMI_VERSION > 0 + if (result && !foundDirty) + { + // page is clean + result = false; + } +#endif + + return result; +} + + +static bool h2fmi_pio_discard_bootpage(h2fmi_t* fmi, + uint32_t ce, + uint32_t page) +{ + bool result = true; + + uint32_t sector_idx; + + // setup a nand bootpage read operation + if (!h2fmi_setup_bootpage_read(fmi, ce, page)) + { + h2fmi_fail(result); + } + else + { + // for each sector... + for (sector_idx = 0; sector_idx < H2FMI_BOOT_SECTORS_PER_PAGE; sector_idx++) + { + // clean up any ECC block state before starting transfer + h2fmi_clean_ecc(fmi); + + // start FMI read + h2fmi_wr(fmi, FMI_CONTROL, (FMI_CONTROL__MODE__READ | + FMI_CONTROL__START_BIT)); + + // wait for FMI to be ready with data in fifo for DMA to transfer out + if (!h2fmi_wait_dma_task_pending(fmi)) + { + // timed out + h2fmi_fail(result); + } + else + { + register uint32_t word_idx = H2FMI_WORDS_PER_SECTOR; + register uint32_t tmp0 = 0; + + do + { + // read each word from the fifo, discarding it + tmp0 |= h2fmi_rd(fmi, FMI_DATA_BUF); + } + while (--word_idx); + } + } + } + + // disable all nand devices + h2fmi_wr(fmi, FMC_CE_CTRL, 0x0); + + return result; +} + + + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/boot/H2fmi_private.h b/drivers/apple/h2fmi/boot/H2fmi_private.h new file mode 100644 index 0000000..3cadc03 --- /dev/null +++ b/drivers/apple/h2fmi/boot/H2fmi_private.h @@ -0,0 +1,387 @@ +// ***************************************************************************** +// +// File: H2fmi_private.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position; add definitions for extracting value from register +// position +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#ifndef _H2FMI_PRIVATE_H_ +#define _H2FMI_PRIVATE_H_ + +#include + +#include "H2fmi_regs.h" + + +// ============================================================================= +// preprocessor platform identification +// ============================================================================= + +#if (defined(APPLICATION_SECUREROM) && APPLICATION_SECUREROM) +#define H2FMI_BOOTROM true +#else +#define H2FMI_BOOTROM false +#endif + +#if (defined(APPLICATION_EMBEDDEDIOP) && APPLICATION_EMBEDDEDIOP) +#define H2FMI_IOP true +#else +#define H2FMI_IOP false +#endif + +#if (defined(APPLICATION_IBOOT) && APPLICATION_IBOOT) +#define H2FMI_IBOOT true +#else +#define H2FMI_IBOOT false +#endif + +// TODO: add EFI platform identification + + +// ============================================================================= +// configurable preprocessor compilation control +// ============================================================================= + +// Set H2FMI_DEBUG below to true if you want to build with extra +// debugging features (default to false). +#define H2FMI_DEBUG false + +// Set H2FMI_TEST_HOOK below to true if you want to insert tests at the end +// of FIL_Init in iBoot (default to false). +#define H2FMI_TEST_HOOK false + +// Set H2FMI_DMA_SYNC_READ and/or H2FMI_DMA_SYNC_WRITE to true in order to +// force read and/or write operations to only use the synchronous interface +// to the CDMA. This is a workaround for a problem with async dma that is +// currently under investigation. +#define H2FMI_DMA_SYNC_READ false +#define H2FMI_DMA_SYNC_WRITE false + +// Set H2FMI_WAIT_USING_ISR to true if you want operations to wait for +// dma and bus events by hooking an interrupt service routine to the +// FMI interrupt vector; set to false for waiting using register +// polling with yield (default to true). +#define H2FMI_WAIT_USING_ISR true + + +// ============================================================================= +// fixed preprocessor compilation control +// ============================================================================= + +// Always build SecureROM read-only. +#if (H2FMI_BOOTROM) +#define H2FMI_READONLY true +// Also, EmbeddedIOP builds should always be read/write. +#elif (H2FMI_IOP) +#define H2FMI_READONLY false +// Otherwise, ignore nand driver read-only configuration in iBoot +// debug builds so that erase/write are available for use in testing +// read operations. +#elif (H2FMI_IBOOT && defined(AND_READONLY) && H2FMI_DEBUG) +#define H2FMI_READONLY false +// Otherwise, mirror nand driver configuration in iBoot. +#elif (defined(AND_READONLY)) +#define H2FMI_READONLY true +#else +#define H2FMI_READONLY false +#endif + + +// ============================================================================= +// preprocessor constant definitions +// ============================================================================= + +#define H2FMI_META_PER_ENVELOPE 10 +#define H2FMI_BYTES_PER_META 10 + +#define H2FMI_MAX_DEVICE 8UL +#define H2FMI_BYTES_PER_SECTOR 512UL +#define H2FMI_WORDS_PER_SECTOR (H2FMI_BYTES_PER_SECTOR / sizeof(uint32_t)) + +#define H2FMI_BOOT_SECTORS_PER_PAGE 3UL +#define H2FMI_BOOT_BYTES_PER_PAGE (H2FMI_BYTES_PER_SECTOR * H2FMI_BOOT_SECTORS_PER_PAGE) + +#define H2FMI_DEFAULT_TIMEOUT_MICROS ((utime_t)(2 * 1000 * 1000)) +#define H2FMI_PAGE_TIMEOUT_MICROS ((utime_t)(2 * 1000 * 1000)) + +#define H2FMI_NAND_ID_SIZE 5 + +// conservative bus timings used for boot and Read Id during init +#define H2FMI_INIT_READ_CYCLE_NANOS 200 +#define H2FMI_INIT_READ_SETUP_NANOS 100 +#define H2FMI_INIT_READ_HOLD_NANOS 100 +#define H2FMI_INIT_WRITE_CYCLE_NANOS 200 +#define H2FMI_INIT_WRITE_SETUP_NANOS 100 +#define H2FMI_INIT_WRITE_HOLD_NANOS 100 + + +// ============================================================================= +// type declarations +// ============================================================================= + +typedef uint32_t h2fmi_ce_t; + +typedef uint32_t h2fmi_chipid_t; + +struct _h2fmi_t +{ + volatile uint32_t* regs; + + uint32_t num_of_ce; + uint32_t pages_per_block; + uint32_t sectors_per_page; + uint32_t bytes_per_spare; + uint32_t blocks_per_ce; + uint32_t banks_per_ce; + uint32_t bytes_per_meta; + uint32_t if_ctrl; + + uint32_t isr_condition; + + struct task_event dma_data_done_event; + struct task_event dma_meta_done_event; + + struct task_event isr_event; + + bool initialized; +}; +typedef struct _h2fmi_t h2fmi_t; + +struct _h2fmi_virt_to_phys_map_t +{ + uint32_t bus; + h2fmi_ce_t ce; +}; +typedef struct _h2fmi_virt_to_phys_map_t h2fmi_virt_to_phys_map_t; + +// ============================================================================= +// general fail macro +// ============================================================================= + +#define h2fmi_fail(b) \ + do { \ + dprintf(DEBUG_CRITICAL, \ + "[FIL:ERR] FAIL -> %s@%d\n", \ + __FILE__, __LINE__); \ + b = false; \ + } while (0) + + +// ============================================================================= +// fmi bus selection macros +// +// Note: this doesn't scale nicely past two buses +// ============================================================================= + +#define h2fmi_select_by_bus(fmi, sel0, sel1) ((fmi->regs == FMI0) ? sel0 : sel1) +#define h2fmi_bus_index(fmi) h2fmi_select_by_bus(fmi, 0, 1) + + +// ============================================================================= +// dma-related macros +// ============================================================================= + +#define h2fmi_dma_data_chan(fmi) h2fmi_select_by_bus(fmi, DMA_FMI0DATA, DMA_FMI1DATA) +#define h2fmi_dma_meta_chan(fmi) h2fmi_select_by_bus(fmi, DMA_FMI0CHECK, DMA_FMI1CHECK) + +#define h2fmi_dma_meta_fifo(fmi) ((void*)(((uint32_t)fmi->regs) + FMI_META_FIFO)) +#define h2fmi_dma_data_fifo(fmi) ((void*)(((uint32_t)fmi->regs) + FMI_DATA_BUF)) + + +// ============================================================================= +// busy wait macro +// +// this should only be used for very short waits that should never halt +// during code sequences where performance matters +// ============================================================================= + +#define h2fmi_busy_wait(fmi, reg, mask, cond) \ + do { \ + uint32_t val; \ + do { \ + val = h2fmi_rd(fmi, reg); \ + } while ((val & (mask)) != (cond)); \ + h2fmi_wr(fmi, reg, (val & ~(mask)) | (~(cond) & (mask))); \ + } while (0) + + +// ============================================================================= +// cache operation size macro +// ============================================================================= + +// TODO: refactor this cache line rounding functionality +#if (H2FMI_IOP) +#define cache_op_size(buf_size) (((buf_size) + (CPU_CACHELINE_SIZE-1)) & ~(CPU_CACHELINE_SIZE-1)) +#else +#define cache_op_size(buf_size) buf_size +#endif + + +// ============================================================================= +// nand device command bytes +// ============================================================================= + +#define NAND_CMD__RESET ((uint8_t)0xFF) +#define NAND_CMD__READ_ID ((uint8_t)0x90) +#define NAND_CMD__READ_STATUS ((uint8_t)0x70) +#define NAND_CMD__READ ((uint8_t)0x00) +#define NAND_CMD__READ_CONFIRM ((uint8_t)0x30) +#define NAND_CMD__ERASE ((uint8_t)0x60) +#define NAND_CMD__ERASE_CONFIRM ((uint8_t)0xD0) +#define NAND_CMD__WRITE ((uint8_t)0x80) +#define NAND_CMD__WRITE_CONFIRM ((uint8_t)0x10) + + +// ============================================================================= +// nand operations timeout specifications +// ============================================================================= + +#define TIMEOUT_MICROSEC_READ ((uint32_t)1000) +#define TIMEOUT_MICROSEC_WRITE ((uint32_t)5000) +#define TIMEOUT_MICROSEC_ERASE ((uint32_t)15000) + + +// ============================================================================= +// nand operations status specifications +// ============================================================================= + +#define NAND_STATUS__CHIP_STATUS1 ((uint8_t)1 << 0) +#define NAND_STATUS__CHIP_STATUS1_FAIL ((uint8_t)1 << 0) +#define NAND_STATUS__CHIP_STATUS1_PASS ((uint8_t)0 << 0) +#define NAND_STATUS__CHIP_STATUS2 ((uint8_t)1 << 1) +#define NAND_STATUS__CHIP_STATUS2_FAIL ((uint8_t)1 << 1) +#define NAND_STATUS__CHIP_STATUS2_PASS ((uint8_t)0 << 1) +// bits 2-4 are not used +#define NAND_STATUS__PAGE_BUFFER_RB ((uint8_t)1 << 5) +#define NAND_STATUS__PAGE_BUFFER_RB_READY ((uint8_t)1 << 5) +#define NAND_STATUS__PAGE_BUFFER_RB_BUSY ((uint8_t)0 << 5) +#define NAND_STATUS__DATA_CACHE_RB ((uint8_t)1 << 6) +#define NAND_STATUS__DATA_CACHE_RB_READY ((uint8_t)1 << 6) +#define NAND_STATUS__DATA_CACHE_RB_BUSY ((uint8_t)0 << 6) +#define NAND_STATUS__WRITE_PROTECT ((uint8_t)1 << 7) +#define NAND_STATUS__WRITE_PROTECT_NOT_PROTECTED ((uint8_t)1 << 7) +#define NAND_STATUS__WRITE_PROTECT_PROTECTED ((uint8_t)0 << 7) + + +// ============================================================================= +// implementation function declarations shared between SecureROM and iBoot +// ============================================================================= + +bool h2fmi_init_minimal(h2fmi_t* fmi, uint32_t interface); + +void h2fmi_ungate(h2fmi_t* fmi); +void h2fmi_gate(h2fmi_t* fmi); +void h2fmi_reset(h2fmi_t* fmi); + +void h2fmi_calc_bus_timings(h2fmi_t* fmi, uint32_t min_read_cycle_nanos, uint32_t min_read_setup_nanos, uint32_t min_read_hold_nanos, uint32_t min_write_cycle_nanos, uint32_t min_write_setup_nanos, uint32_t min_write_hold_nanos); + +bool h2fmi_is_chipid_invalid(uint32_t id); + +bool h2fmi_wait_done(h2fmi_t* fmi, uint32_t reg, uint32_t mask, uint32_t bits); +bool h2fmi_wait_dma_task_pending(h2fmi_t* fmi); + +void h2fmi_clean_ecc(h2fmi_t* fmi); +void h2fmi_fmc_read_data(h2fmi_t* fmi, uint32_t size, uint8_t* data); + +bool h2fmi_nand_reset(h2fmi_t* fmi, h2fmi_ce_t ce); +bool h2fmi_nand_read_id(h2fmi_t* fmi, h2fmi_ce_t ce, uint32_t* id); + +bool h2fmi_pio_read_sector(h2fmi_t* fmi, void* buf); + + +// ============================================================================= +// implementation function declarations not used by SecureROM +// ============================================================================= + +#if (!H2FMI_BOOTROM) + +bool h2fmi_init_fil(h2fmi_t* fmi, uint32_t interface, void* scratch_buf); + +void h2fmi_init_sys(h2fmi_t* fmi); + +bool h2fmi_erase_blocks(h2fmi_t* fmi, uint32_t ce, uint32_t block, bool* status_failed); +bool h2fmi_write_page(h2fmi_t* fmi, uint32_t ce, uint32_t page, uint8_t* data_buf, uint8_t* meta_buf, bool* status_failed); +bool h2fmi_read_page(h2fmi_t* fmi, uint32_t ce, uint32_t page, uint8_t* data_buf, uint8_t* meta_buf, uint8_t* max_corrected, bool* is_clean); + +bool h2fmi_write_multi(h2fmi_t* fmi, uint32_t page_count, uint32_t* chip_enable_array, uint32_t* page_number_array, uint8_t** data_buf_array, uint8_t** meta_buf_array, bool* status_failed); + +bool h2fmi_reset_and_read_chipids(h2fmi_t* fmi, h2fmi_chipid_t* ids); +bool h2fmi_nand_reset_all(h2fmi_t* fmi); + +void h2fmi_nand_read_chipid(h2fmi_t* fmi, h2fmi_ce_t ce, h2fmi_chipid_t* id); + +uint32_t h2fmi_config_raw_data_format(h2fmi_t* fmi); +uint32_t h2fmi_config_raw_spare_format(void); +uint32_t h2fmi_config_page_format(h2fmi_t* fmi); +void h2fmi_config_page_addr(h2fmi_t* fmi, uint32_t page); + +bool h2fmi_using_16bit_ecc(h2fmi_t* fmi); + +bool h2fmi_read_raw_page(h2fmi_t* fmi, uint32_t ce, uint32_t page, uint8_t* data_buf, uint8_t* spare_buf); + +bool h2fmi_wait_status(h2fmi_t* fmi, uint8_t io_mask, uint8_t io_cond, uint8_t* status); + +void h2fmi_dma_data_done_handler(void* arg); +void h2fmi_dma_meta_done_handler(void* arg); + +void h2fmiInitVirtToPhysMap(void); +void h2fmiMapBankToBusAndEnable(uint32_t bank, uint32_t bus, h2fmi_ce_t enable); +h2fmi_t* h2fmiTranslateBankToBus(uint32_t bank); +h2fmi_ce_t h2fmiTranslateBankToCe(uint32_t bank); + +#endif // !H2FMI_BOOTROM + + +// ============================================================================= +// implementation function declarations used only for debug during development +// +// note that these are designed so that the calls will disappear when +// not compiling for debug +// ============================================================================= + +#if (H2FMI_DEBUG) + +bool h2fmi_test_hook(h2fmi_t* fmi); +void h2fmi_spew_config(h2fmi_t* fmi); +void h2fmi_spew_status_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_spew_fmi_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_spew_fmc_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_spew_ecc_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_spew_regs(h2fmi_t* fmi, const char* prefix); +void h2fmi_spew_buffer(uint8_t* buf, size_t size); + +#else + +#define h2fmi_test_hook(fmi_ignored) true +#define h2fmi_spew_config(fmi_ignored) +#define h2fmi_spew_status_regs(fmi_ignored, prefix_ignored) +#define h2fmi_spew_fmi_regs(fmi_ignored, prefix_ignored) +#define h2fmi_spew_fmc_regs(fmi_ignored, prefix_ignored) +#define h2fmi_spew_ecc_regs(fmi_ignored, prefix_ignored) +#define h2fmi_spew_regs(fmi_ignored, prefix_ignored) +#define h2fmi_spew_buffer(buf_ignored, size_ignored) + +#endif + + +#endif // _H2FMI_PRIVATE_H_ + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/boot/H2fmi_regs.h b/drivers/apple/h2fmi/boot/H2fmi_regs.h new file mode 100644 index 0000000..cb70204 --- /dev/null +++ b/drivers/apple/h2fmi/boot/H2fmi_regs.h @@ -0,0 +1,761 @@ +// ***************************************************************************** +// +// File: H2fmi_regs.h +// +// ***************************************************************************** +// +// Notes: +// +// - register bitfield definitions are only good for creating bitfield in +// register position +// +// - consider adding definitions for extracting value from register position +// +// ***************************************************************************** +// +// Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Computer, Inc. +// +// ***************************************************************************** + +#ifndef _H2FMI_REGS_H_ +#define _H2FMI_REGS_H_ + +#include + +#include + +// ============================================================================= +// preprocessor compilation control +// ============================================================================= + +// Change the constant below to true if you want to see all FMI +// subsystem register writes; note that doing so is likely to change +// timing and therefore behavior, so it should be a rare case that you +// would ever want to do this. +#define H2FMI_TRACE_REG_WRITES false + + +// ============================================================================= +// register access macros +// ============================================================================= + +#define h2fmi_wr(fmi, reg, val) ((fmi)->regs[(reg) >> 2] = (val)) +#define h2fmi_rd(fmi, reg) ((fmi)->regs[(reg) >> 2]) +#define h2fmi_rd8(fmi, reg) (((volatile uint8_t*)((fmi)->regs))[reg]) + + +// ============================================================================= +// register bases and offsets +// ============================================================================= + +#define FMI0 ((volatile uint32_t*)FMI0_BASE_ADDR) +#define FMI1 ((volatile uint32_t*)FMI1_BASE_ADDR) + +#if FMI_VERSION == 0 + +#define FMI_BA(offset) ((uint32_t)(0x000 + offset)) +#define FMC_BA(offset) ((uint32_t)(0x400 + offset)) +#define ECC_BA(offset) ((uint32_t)(0x800 + offset)) + +#else + +#define FMI_BA(offset) ((uint32_t)(0x00000 + offset)) +#define FMC_BA(offset) ((uint32_t)(0x40000 + offset)) +#define ECC_BA(offset) ((uint32_t)(0x80000 + offset)) + +#endif + +#define FMI_CONFIG FMI_BA(0x00) +#define FMI_CONTROL FMI_BA(0x04) +#define FMI_STATUS FMI_BA(0x08) +#define FMI_INT_PEND FMI_BA(0x0C) +#define FMI_INT_EN FMI_BA(0x10) +#define FMI_DATA_BUF FMI_BA(0x14) +#define FMI_META_FIFO FMI_BA(0x18) +#define FMI_DEBUG0 FMI_BA(0x1C) +#define FMI_DEBUG1 FMI_BA(0x20) +#define FMI_DEBUG2 FMI_BA(0x24) +#if FMI_VERSION > 2 +#define FMI_SCRAMBLER_SEED_FIFO FMI_BA(0x3C) +#endif + +#if FMI_VERSION > 0 + +#define FMI_DEBUG3 FMI_BA(0x28) +#define FMI_HW_VERSION FMI_BA(0x30) +#define FMI_DATA_SIZE FMI_BA(0x34) + +#endif + +#define FMC_ON FMC_BA(0x00) +#define FMC_VER FMC_BA(0x04) +#define FMC_IF_CTRL FMC_BA(0x08) +#define FMC_CE_CTRL FMC_BA(0x0C) +#define FMC_RW_CTRL FMC_BA(0x10) +#define FMC_CMD FMC_BA(0x14) +#define FMC_ADDR0 FMC_BA(0x18) +#define FMC_ADDR1 FMC_BA(0x1C) +#define FMC_ADDRNUM FMC_BA(0x20) +#define FMC_DATANUM FMC_BA(0x24) +#define FMC_UNDEF0 FMC_BA(0x28) +#define FMC_UNDEF1 FMC_BA(0x2C) +#define FMC_TO_CTRL FMC_BA(0x30) +#define FMC_TO_CNT FMC_BA(0x34) +#define FMC_UNDEF2 FMC_BA(0x38) +#define FMC_UNDEF3 FMC_BA(0x3C) +#define FMC_INTMASK FMC_BA(0x40) +#define FMC_STATUS FMC_BA(0x44) +#define FMC_NAND_STATUS FMC_BA(0x48) +#define FMC_RBB_CONFIG FMC_BA(0x4C) +#define FMC_LOCK0_L FMC_BA(0x50) +#define FMC_LOCK0_H FMC_BA(0x54) +#define FMC_LOCK1_L FMC_BA(0x58) +#define FMC_LOCK1_H FMC_BA(0x5C) +#define FMC_LOCK2_L FMC_BA(0x60) +#define FMC_LOCK2_H FMC_BA(0x64) +#define FMC_ALARMCMD FMC_BA(0x68) +#define FMC_REJECTCMD FMC_BA(0x6C) + +#define ECC_VERSION ECC_BA(0x00) +#define ECC_CON0 ECC_BA(0x04) +#define ECC_CON1 ECC_BA(0x08) +#define ECC_RESULT ECC_BA(0x0C) +#define ECC_PND ECC_BA(0x10) +#define ECC_MASK ECC_BA(0x14) +#define ECC_HISTORY ECC_BA(0x18) +#define ECC_CORE_SW_RESET ECC_BA(0x1C) +#define ECC_LOC0 ECC_BA(0x20) +#define ECC_LOC1 ECC_BA(0x24) +#define ECC_LOC2 ECC_BA(0x28) +#define ECC_LOC3 ECC_BA(0x2C) +#define ECC_LOC4 ECC_BA(0x30) +#define ECC_LOC5 ECC_BA(0x34) +#define ECC_LOC6 ECC_BA(0x38) +#define ECC_UNDEF0 ECC_BA(0x3C) +#define ECC_PARITY0 ECC_BA(0x40) +#define ECC_PARITY1 ECC_BA(0x44) +#define ECC_PARITY2 ECC_BA(0x48) +#define ECC_PARITY3 ECC_BA(0x4C) +#define ECC_PARITY4 ECC_BA(0x50) +#define ECC_PARITY5 ECC_BA(0x54) +#define ECC_PARITY6 ECC_BA(0x58) + + +// ============================================================================= +// FMI_CONFIG bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define FMI_CONFIG__DMA_BURST(n) (((n) & 0x7) << 17) +#define FMI_CONFIG__LBA_MODE(v) (((v) & 0x3) << 15) +#define FMI_CONFIG__ECC_MODE(m) (((m) & 0x1) << 14) +#define FMI_CONFIG__META_PER_ENVELOPE(n) (((n) & 0x3F) << 8) +#define FMI_CONFIG__META_PER_PAGE(n) (((n) & 0x3F) << 2) +#define FMI_CONFIG__PAGE_SIZE(n) (((n) & 0x03) << 0) + +#else + +#define FMI_CONFIG__ECC_CORRECTABLE_BITS(m) (((m) & 0x1F) << 3) +#define FMI_CONFIG__DMA_BURST(n) (((n) & 0x7) << 0) + +#endif + +#define FMI_CONFIG__DMA_BURST__32_CYCLES FMI_CONFIG__DMA_BURST(5) +#define FMI_CONFIG__DMA_BURST__16_CYCLES FMI_CONFIG__DMA_BURST(4) +#define FMI_CONFIG__DMA_BURST__8_CYCLES FMI_CONFIG__DMA_BURST(3) +#define FMI_CONFIG__DMA_BURST__4_CYCLES FMI_CONFIG__DMA_BURST(2) +#define FMI_CONFIG__DMA_BURST__2_CYCLES FMI_CONFIG__DMA_BURST(1) +#define FMI_CONFIG__DMA_BURST__1_CYCLES FMI_CONFIG__DMA_BURST(0) + +#if FMI_VERSION == 0 + +#define FMI_CONFIG__LBA_MODE__NORMAL FMI_CONFIG__LBA_MODE(0) +#define FMI_CONFIG__LBA_MODE__BYPASS_ECC FMI_CONFIG__LBA_MODE(1) +#define FMI_CONFIG__LBA_MODE__LBA_TYPE_AB FMI_CONFIG__LBA_MODE(2) +#define FMI_CONFIG__LBA_MODE__LBA_TYPE_C FMI_CONFIG__LBA_MODE(3) + +#define FMI_CONFIG__ECC_MODE__16BIT FMI_CONFIG__ECC_MODE(1) +#define FMI_CONFIG__ECC_MODE__8BIT FMI_CONFIG__ECC_MODE(0) + +#define FMI_CONFIG__PAGE_SIZE__2K FMI_CONFIG__PAGE_SIZE(0) +#define FMI_CONFIG__PAGE_SIZE__4K FMI_CONFIG__PAGE_SIZE(1) +#define FMI_CONFIG__PAGE_SIZE__8K FMI_CONFIG__PAGE_SIZE(2) +#define FMI_CONFIG__PAGE_SIZE__512 FMI_CONFIG__PAGE_SIZE(3) + +#else + +#define FMI_CONFIG__ECC_MAX_CORRECTION FMI_CONFIG__ECC_CORRECTABLE_BITS(30) + +#endif + +#if FMI_VERSION > 2 +#define FMI_CONFIG__ENABLE_WHITENING (0x1UL << 8) +#endif + +#if FMI_VERSION > 3 +#define FMI_CONFIG__SCRAMBLE_SEED (0x1UL << 14) +#endif + +// ============================================================================= +// FMI_CONTROL bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define FMI_CONTROL__MODE(m) (((m) & 0x3) << 1) +#define FMI_CONTROL__START_BIT (0x1UL << 0) + +#define FMI_CONTROL__MODE__IDLE FMI_CONTROL__MODE(0) +#define FMI_CONTROL__MODE__READ FMI_CONTROL__MODE(1) +#define FMI_CONTROL__MODE__WRITE FMI_CONTROL__MODE(2) +#define FMI_CONTROL__MODE__UNDEF FMI_CONTROL__MODE(3) + +#else + +#if FMI_VERSION > 3 +#define FMI_CONTROL__RESET_SEED (0x1UL << 11) +#endif + +#define FMI_CONTROL__BUFFER_1_LOCK(m) (((m) & 0x3) << 5) +#define FMI_CONTROL__BUFFER_0_LOCK(m) (((m) & 0x3) << 3) +#define FMI_CONTROL__MODE(m) (((m) & 0x3) << 1) +#define FMI_CONTROL__START_BIT (0x1UL << 0) + +#define FMI_CONTROL__MODE__IDLE FMI_CONTROL__MODE(0) +#define FMI_CONTROL__MODE__READ FMI_CONTROL__MODE(1) +#define FMI_CONTROL__MODE__WRITE FMI_CONTROL__MODE(2) +#define FMI_CONTROL__MODE__SOFTWARE_RESET FMI_CONTROL__MODE(3) + +#define FMI_CONTROL__BUFFER_0_LOCK_FREE FMI_CONTROL__BUFFER_0_LOCK(0) +#define FMI_CONTROL__BUFFER_0_LOCK_DMA FMI_CONTROL__BUFFER_0_LOCK(1) +#define FMI_CONTROL__BUFFER_0_LOCK_ECC FMI_CONTROL__BUFFER_0_LOCK(2) +#define FMI_CONTROL__BUFFER_0_LOCK_FMC FMI_CONTROL__BUFFER_0_LOCK(3) + +#define FMI_CONTROL_BUFFER_1_LOCK_FREE FMI_CONTROL__BUFFER_1_LOCK(0) +#define FMI_CONTROL_BUFFER_1_LOCK_DMA FMI_CONTROL__BUFFER_1_LOCK(1) +#define FMI_CONTROL_BUFFER_1_LOCK_ECC FMI_CONTROL__BUFFER_1_LOCK(2) +#define FMI_CONTROL_BUFFER_1_LOCK_FMC FMI_CONTROL__BUFFER_1_LOCK(3) + +#endif + + +// ============================================================================= +// FMI_STATUS bitfields +// ============================================================================= + +#define FMI_STATUS__FMC_ACTIVE (0x1UL << 3) +#define FMI_STATUS__ECC_ACTIVE (0x1UL << 2) +#define FMI_STATUS__DMA_ACTIVE (0x1UL << 1) +#define FMI_STATUS__BUS_ACTIVE (0x1UL << 0) + + +// ============================================================================= +// FMI_INT_PEND bitfields +// ============================================================================= + + +#if FMI_VERSION == 0 + +#define FMI_INT_PEND__ECC_INTERRUPT (0x1UL << 14) +#define FMI_INT_PEND__ECC_READY_BUSY (0x1UL << 13) +#define FMI_INT_PEND__ECC_DONE (0x1UL << 12) +#define FMI_INT_PEND__FMC_INTERRUPT (0x1UL << 11) +#define FMI_INT_PEND__FMC_READY_BUSY (0x1UL << 10) + +#else + +#define FMI_INT_PEND__ECC_INTERRUPT (0x1UL << 21) +#define FMI_INT_PEND__ECC_READY_BUSY (0x1UL << 20) +#define FMI_INT_PEND__ECC_DONE (0x1UL << 19) +#define FMI_INT_PEND__FMC_INTERRUPT (0x1UL << 18) +#define FMI_INT_PEND__FMC_READY_BUSY(n) (((n) & 0xFF << 10) + +#endif + +#define FMI_INT_PEND__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_PEND__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_PEND__FMC_NSERR (0x1UL << 7) +#define FMI_INT_PEND__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_PEND__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_PEND__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_PEND__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_PEND__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_PEND__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_PEND__TRANSACTION_COMPLETE (0x1UL << 0) + + + +// ============================================================================= +// FMI_INT_EN bitfields +// ============================================================================= + +#define FMI_INT_EN__ECC_INTERRUPT (0x1UL << 14) +#define FMI_INT_EN__ECC_READY_BUSY (0x1UL << 13) +#define FMI_INT_EN__ECC_DONE (0x1UL << 12) +#define FMI_INT_EN__FMC_INTERRUPT (0x1UL << 11) +#define FMI_INT_EN__FMC_READY_BUSY (0x1UL << 10) +#define FMI_INT_EN__FMC_TIMEOUT (0x1UL << 9) +#define FMI_INT_EN__FMC_NSRBBDONE (0x1UL << 8) +#define FMI_INT_EN__FMC_NSERR (0x1UL << 7) +#define FMI_INT_EN__FMC_TRANSDONE (0x1UL << 6) +#define FMI_INT_EN__FMC_ADDRESSDONE (0x1UL << 5) +#define FMI_INT_EN__FMC_CMDDONE (0x1UL << 4) +#define FMI_INT_EN__META_FIFO_OVERFLOW (0x1UL << 3) +#define FMI_INT_EN__META_FIFO_UNDERFLOW (0x1UL << 2) +#define FMI_INT_EN__LAST_FMC_DONE (0x1UL << 1) +#define FMI_INT_EN__TRANSACTION_COMPLETE (0x1UL << 0) + + +// ============================================================================= +// FMI_DEBUG0 bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define FMI_DEBUG0__DMA_BLOCK_COUNT(n) (((n) & 0x1F) << 24) +#define FMI_DEBUG0__DATA_TC_RECEIVED (0x1UL << 23) +#define FMI_DEBUG0__DATA_DMA_DONE (0x1UL << 22) +#define FMI_DEBUG0__DMA_DATA_RW_PTR(n) (((n) & 0x7F) << 15) + +#else + +#define FMI_DEBUG0__DMA_SECTOR_COUNT(n) (((n) & 0x7F) << 25) +#define FMI_DEBUG0__DATA_TC_RECEIVED (0x1UL << 24) +#define FMI_DEBUG0__DMA_WORD_COUNT(n) (((n) & 0x1FF << 15) + +#endif + +#define FMI_DEBUG0__META_BYTE_COUNT(n) (((n) & 0x3F) << 9) +#define FMI_DEBUG0__FMC_TASKS_PENDING(n) (((n) & 0x3) << 7) +#define FMI_DEBUG0__ECC_TASKS_PENDING(n) (((n) & 0x3) << 5) +#define FMI_DEBUG0__DMA_TASKS_PENDING(n) (((n) & 0x3) << 3) +#define FMI_DEBUG0__FMC_TARGET_BUFFER(b) (((b) & 0x1) << 2) +#define FMI_DEBUG0__ECC_TARGET_BUFFER(b) (((b) & 0x1) << 1) +#define FMI_DEBUG0__DMA_TARGET_BUFFER(b) (((b) & 0x1) << 0) + + +// ============================================================================= +// FMI_DEBUG1 bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define FMI_DEBUG1__META_TC_RECEIVED (0x1UL << 28) +#define FMI_DEBUG1__NEXT_META_LOCATION(n) (((n) & 0x3F) << 22) +#define FMI_DEBUG1__FMC_PAGE_DONE (0x1UL << 21) +#define FMI_DEBUG1__FMC_BLOCK_COUNT(n) (((n) & 0x1F) << 16) + +#else + +#define FMI_DEBUG1__METADATA_TC_RECEIVED (0x1UL << 27) +#define FMI_DEBUG1__METADATA_ADDRESS(n) (((n) & 0x7FF) << 16) + +#endif + +#define FMI_DEBUG1__META_FIFO_LEVEL(n) (((n) & 0x3F) << 10) +#define FMI_DEBUG1__META_FIFO_WRITE_PTR(n) (((n) & 0x1F) << 5) +#define FMI_DEBUG1__META_FIFO_READ_PTR(n) (((n) & 0x1F) << 0) + +// ============================================================================= +// FMI_DEBUG2 bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define FMI_DEBUG2__BUFFER_1_META_BYTES(n) (((n) & 0x3F) << 24) +#define FMI_DEBUG2__BUFFER_0_META_BYTES(n) (((n) & 0x3F) << 18) +#define FMI_DEBUG2__META_BYTES_REMAINING(n) (((n) & 0x3F) << 12) +#define FMI_DEBUG2__PAUSED_AHB_ADDRESS(n) (((n) & 0xFF) << 4) +#define FMI_DEBUG2__AHB_STATE(n) (((n) & 0x3) << 1) +#define FMI_DEBUG2__PAUSED_AHB_BUS (0x1UL << 0) + +#else + +#define FMI_DEBUG2__BUFFER_1_META_BYTES(n) (((n) & 0x3F) << 19) +#define FMI_DEBUG2__BUFFER_0_META_BYTES(n) (((n) & 0x3F) << 13) +#define FMI_DEBUG2__META_BYTES_REMAINING(n) (((n) & 0x3F) << 7) +#define FMI_DEBUG2__DATA_STATE(n) (((n) & 0xF) << 3) +#define FMI_DEBUG2__AHB_STATE(n) (((n) & 0x7) << 0) + +#endif + +// ============================================================================= +// FMI_DEBUG3 bitfields +// ============================================================================= + +#if FMI_VERSION > 0 + +#define FMI_DEBUG3__PAUSED_AHB_ADDRESS(n) (((n) & 0xFF) << 9) +#define FMI_DEBUG3__PAUSE_AHB_BUS (0x1UL << 8) +#define FMI_DEBUG3__FMC_PAGE_DONE (0x1UL << 7) +#define FMI_DEBUG3__FMC_BLOCK_COUNT(n) (((n) & 0x7F) << 0) + +#endif + +// ============================================================================= +// FMI_DATA_SIZE bitfields +// ============================================================================= + +#if FMI_VERSION > 0 + +#define FMI_DATA_SIZE__META_BYTES_PER_ENVELOPE(n) (((n) & 0x3F) << 25) +#define FMI_DATA_SIZE__META_BYTES_PER_PAGE(n) (((n) & 0x3F) << 19) +#define FMI_DATA_SIZE__BYTES_PER_SECTOR(n) (((n) & 0x7FF) << 8) +#define FMI_DATA_SIZE__SECTORS_PER_PAGE(n) (((n) & 0xFF) << 0) + +#endif + +// ============================================================================= +// FMC_ON bitfields +// ============================================================================= + +#define FMC_ON__SWRST (0x1UL << 8) +#define FMC_ON__LOCK_ON (0x1UL << 4) +#define FMC_ON__CLKGATING_RDY (0x1UL << 1) +#define FMC_ON__ENABLE (0x1UL << 0) +#define FMC_ON__DISABLE (!FMC_ON__ENABLE) + + +// ============================================================================= +// FMC_IF_CTRL bitfields +// ============================================================================= + +#define FMC_IF_CTRL__WPB (0x1UL << 21) +#define FMC_IF_CTRL__RBBEN (0x1UL << 20) +#define FMC_IF_CTRL__DCCYCLE(v) (((v) & 0xF) << 16) +#define FMC_IF_CTRL__REB_SETUP(v) (((v) & 0xF) << 12) +#define FMC_IF_CTRL__REB_HOLD(v) (((v) & 0xF) << 8) +#define FMC_IF_CTRL__WEB_SETUP(v) (((v) & 0xF) << 4) +#define FMC_IF_CTRL__WEB_HOLD(v) (((v) & 0xF) << 0) + +#define FMC_IF_CTRL__TIMING_MAX_CLOCKS (0xFUL) + + +// ============================================================================= +// FMC_CE_CTRL bitfields +// ============================================================================= + +#define FMC_CE_CTRL__CE_COUNT (8) +#define FMC_CE_CTRL__CEB(n) (0x1UL << ((n) & 0x7)) + +#define FMC_CE_CTRL__CEB7 FMC_CE_CTRL__CEB(7) +#define FMC_CE_CTRL__CEB6 FMC_CE_CTRL__CEB(6) +#define FMC_CE_CTRL__CEB5 FMC_CE_CTRL__CEB(5) +#define FMC_CE_CTRL__CEB4 FMC_CE_CTRL__CEB(4) +#define FMC_CE_CTRL__CEB3 FMC_CE_CTRL__CEB(3) +#define FMC_CE_CTRL__CEB2 FMC_CE_CTRL__CEB(2) +#define FMC_CE_CTRL__CEB1 FMC_CE_CTRL__CEB(1) +#define FMC_CE_CTRL__CEB0 FMC_CE_CTRL__CEB(0) + + +// ============================================================================= +// FMC_RW_CTRL bitfields +// ============================================================================= + +#define FMC_RW_CTRL__REBHOLD (0x1UL << 6) +#define FMC_RW_CTRL__WR_MODE (0x1UL << 5) +#define FMC_RW_CTRL__RD_MODE (0x1UL << 4) +#define FMC_RW_CTRL__ADDR_MODE (0x1UL << 3) +#define FMC_RW_CTRL__CMD3_MODE (0x1UL << 2) +#define FMC_RW_CTRL__CMD2_MODE (0x1UL << 1) +#define FMC_RW_CTRL__CMD1_MODE (0x1UL << 0) + + +// ============================================================================= +// FMC_CMD bitfields +// ============================================================================= + +#define FMC_CMD__CMD3(c) (((c) & 0xFF) << 16) +#define FMC_CMD__CMD2(c) (((c) & 0xFF) << 8) +#define FMC_CMD__CMD1(c) (((c) & 0xFF) << 0) + + +// ============================================================================= +// FMC_ADDR0 bitfields +// ============================================================================= + +#define FMC_ADDR0__SEQ3(a) (((a) & 0xFF) << 24) +#define FMC_ADDR0__SEQ2(a) (((a) & 0xFF) << 16) +#define FMC_ADDR0__SEQ1(a) (((a) & 0xFF) << 8) +#define FMC_ADDR0__SEQ0(a) (((a) & 0xFF) << 0) + + +// ============================================================================= +// FMC_ADDR1 bitfields +// ============================================================================= + +#define FMC_ADDR1__SEQ7(a) (((a) & 0xFF) << 24) +#define FMC_ADDR1__SEQ6(a) (((a) & 0xFF) << 16) +#define FMC_ADDR1__SEQ5(a) (((a) & 0xFF) << 8) +#define FMC_ADDR1__SEQ4(a) (((a) & 0xFF) << 0) + + +// ============================================================================= +// FMC_ADDRNUM bitfields +// ============================================================================= + +#define FMC_ADDRNUM__NUM(n) (((n) & 0x7) << 0) + + +// ============================================================================= +// FMC_DATANUM bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define FMC_DATANUM__NUM(n) (((n) & 0x3F) << 0) + +#else + +#define FMC_DATANUM__NUM(n) (((n) & 0x3FF) << 0) + +#endif + + +// ============================================================================= +// FMC_TO_CTRL bitfields +// ============================================================================= + +#define FMC_TO_CTRL__EN (0x1UL << 12) +#define FMC_TO_CTRL__DIV(d) (((d) & 0xF) << 8) +#define FMC_TO_CTRL__VAL(v) (((v) & 0xFF) << 0) + + +// ============================================================================= +// FMC_TO_CNT bitfields +// ============================================================================= + +#define FMC_TO_CNT__CNT(c) (((c) & 0xFF) << 0) + + +// ============================================================================= +// FMC_INTMASK bitfields +// ============================================================================= + +#define FMC_INTMASK__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_INTMASK__RBBDONE7 FMC_INTMASK__RBBDONE(7) +#define FMC_INTMASK__RBBDONE6 FMC_INTMASK__RBBDONE(6) +#define FMC_INTMASK__RBBDONE5 FMC_INTMASK__RBBDONE(5) +#define FMC_INTMASK__RBBDONE4 FMC_INTMASK__RBBDONE(4) +#define FMC_INTMASK__RBBDONE3 FMC_INTMASK__RBBDONE(3) +#define FMC_INTMASK__RBBDONE2 FMC_INTMASK__RBBDONE(2) +#define FMC_INTMASK__RBBDONE1 FMC_INTMASK__RBBDONE(1) +#define FMC_INTMASK__RBBDONE0 FMC_INTMASK__RBBDONE(0) +#define FMC_INTMASK__TIMEOUT (0x1UL << 7) +#define FMC_INTMASK__NSERR (0x1UL << 6) +#define FMC_INTMASK__NSRBBDONE (0x1UL << 5) +#define FMC_INTMASK__TRANSDONE (0x1UL << 4) +#define FMC_INTMASK__ADDRESSDONE (0x1UL << 3) +#define FMC_INTMASK__CMD3DONE (0x1UL << 2) +#define FMC_INTMASK__CMD2DONE (0x1UL << 1) +#define FMC_INTMASK__CMD1DONE (0x1UL << 0) + + +// ============================================================================= +// FMC_STATUS bitfields +// ============================================================================= + +#define FMC_STATUS__RBBDONE(n) (0x1UL << (((n) & 0x7) + 8)) + +#define FMC_STATUS__EMERGENCY2 (0x1UL << 21) +#define FMC_STATUS__EMERGENCY01 (0x1UL << 20) +#define FMC_STATUS__RDATADIRTY (0x1UL << 16) +#define FMC_STATUS__RBBDONE7 FMC_STATUS__RBBDONE(7) +#define FMC_STATUS__RBBDONE6 FMC_STATUS__RBBDONE(6) +#define FMC_STATUS__RBBDONE5 FMC_STATUS__RBBDONE(5) +#define FMC_STATUS__RBBDONE4 FMC_STATUS__RBBDONE(4) +#define FMC_STATUS__RBBDONE3 FMC_STATUS__RBBDONE(3) +#define FMC_STATUS__RBBDONE2 FMC_STATUS__RBBDONE(2) +#define FMC_STATUS__RBBDONE1 FMC_STATUS__RBBDONE(1) +#define FMC_STATUS__RBBDONE0 FMC_STATUS__RBBDONE(0) +#define FMC_STATUS__TIMEOUT (0x1UL << 7) +#define FMC_STATUS__NSERR (0x1UL << 6) +#define FMC_STATUS__NSRBBDONE (0x1UL << 5) +#define FMC_STATUS__TRANSDONE (0x1UL << 4) +#define FMC_STATUS__ADDRESSDONE (0x1UL << 3) +#define FMC_STATUS__CMD3DONE (0x1UL << 2) +#define FMC_STATUS__CMD2DONE (0x1UL << 1) +#define FMC_STATUS__CMD1DONE (0x1UL << 0) + + +// ============================================================================= +// FMC_RBB_CONFIG bitfields +// ============================================================================= + +#define FMC_RBB_CONFIG__POL(v) (((v) & 0xFF) << 8) +#define FMC_RBB_CONFIG__POS(v) (((v) & 0xFF) << 0) + + +// ============================================================================= +// FMC_ALARMCMD bitfields +// ============================================================================= + +#define FMC_ALARMCMD__READ1(v) (((v) & 0xFF) << 16) +#define FMC_ALARMCMD__PROG1(v) (((v) & 0xFF) << 8) +#define FMC_ALARMCMD__ERASE1(v) (((v) & 0xFF) << 0) + + +// ============================================================================= +// FMC_REJECTCMD bitfields +// ============================================================================= + +#define FMC_REJECTCMD__READ2(v) (((v) & 0xFF) << 16) +#define FMC_REJECTCMD__PROG2(v) (((v) & 0xFF) << 8) +#define FMC_REJECTCMD__ERASE2(v) (((v) & 0xFF) << 0) + + +// ============================================================================= +// ECC_CON0 bitfields +// ============================================================================= + +#define ECC_CON0__START_ENC (0x1UL << 1) +#define ECC_CON0__START_DEC (0x1UL << 0) + +#if FMI_VERSION == 0 + +#define ECC_CON0__META_LENGTH(n) (((n) & 0x1F) << 8) +#define ECC_CON0__MODE_SEL(m) (((m) & 0x1) << 2) +#define ECC_CON0__MODE_SEL__16BIT ECC_CON0__MODE_SEL(1) +#define ECC_CON0__MODE_SEL__8BIT ECC_CON0__MODE_SEL(0) + +#else + +#define ECC_CON0__INFORMATION_LENGTH(n) (((n) & 0x7FF) << 16) +#define ECC_CON0__MODE_SEL(m) (((m) & 0x1F) << 4) +#define ECC_CON0__MAX_CORRECTION ECC_CON0__MODE_SEL(30) + +#endif + + +// ============================================================================= +// ECC_CON1 bitfields +// ============================================================================= + +#if FMI_VERSION > 0 + +#define ECC_CON1__ALLOWED_STUCK_BIT_IN_FP(n) (((n) & 0x1F) << 16) + +#endif + +#if FMI_VERSION > 2 +#define ECC_CON1__IMPLICIT_WRITE_MARK (1UL << 31) +#endif + +#define ECC_CON1__ERROR_ALERT_LEVEL(n) (((n) & 0x1F) << 8) +#define ECC_CON1__INT_ENABLE(b) (((b) & 0x1) << 7) + +#define ECC_CON1__INT_ENABLE__ENABLE ECC_CON1__INT_ENABLE(1) +#define ECC_CON1__INT_ENABLE__DISABLE ECC_CON1__INT_ENABLE(0) + + +// ============================================================================= +// ECC_RESULT bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define ECC_RESULT__ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_RESULT__ERROR_FLAG (0x1UL << 0) + +#else + +#define ECC_RESULT_FIFO__ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_RESULT_FIFO__STUCK_BIT_EXCEEDED (0x1UL << 14) +#define ECC_RESULT_FIFO__STUCK_BIT_CNT(n) (((n) & 0x3F) << 8) +#define ECC_RESULT_FIFO__ALL_FF (0x1UL << 3) +#define ECC_RESULT_FIFO__ALL_ZERO (0x1UL << 2) +#define ECC_RESULT_FIFO__FREE_PAGE (0x1UL << 1) +#define ECC_RESULT_FIFO__UNCORRECTABLE (0x1UL << 0) +#define ECC_RESULT_FIFO__RESET_FIFO (0x1UL << 0) + +#endif + +// ============================================================================= +// ECC_PND bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define ECC_PND__BCH_ALL_FF (0x1UL << 6) +#define ECC_PND__SECTOR_ERROR_ALERT (0x1UL << 5) +#define ECC_PND__READY_BUSY (0x1UL << 4) +#define ECC_PND__UNCORRECTABLE (0x1UL << 3) +#define ECC_PND__DEC_DONE (0x1UL << 2) +#define ECC_PND__ENC_DONE (0x1UL << 1) +#define ECC_PND__ENC_DEC_DONE (0x1UL << 0) + +#else + +#define ECC_PND__MAX_STUCK_BIT_CNT(n) (((n) & 0x3F) << 24) +#define ECC_PND__MAX_ERROR_CNT(n) (((n) & 0x1F) << 16) +#define ECC_PND__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_PND__SOME_ALL_FF (0x1UL << 8) +#define ECC_PND__SOME_ALL_ZERO (0x1UL << 7) +#define ECC_PND__ALL_FREE_PAGE (0x1UL << 6) +#define ECC_PND__SOME_ERROR_ALERT (0x1UL << 5) +#define ECC_PND__READY_BUSY (0x1UL << 4) +#define ECC_PND__UNCORRECTABLE (0x1UL << 3) +#define ECC_PND__ENC_DONE (0x1UL << 2) // note swap from 8920 +#define ECC_PND__DEC_DONE (0x1UL << 1) // note swap from 8920 +#define ECC_PND__ENC_DEC_DONE (0x1UL << 0) + +#endif + +// ============================================================================= +// ECC_MASK bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define ECC_MASK__SECTOR_ERR_ALERT_MASK (0x1UL << 5) +#define ECC_MASK__UNCORRECTABLE_MASK (0x1UL << 3) +#define ECC_MASK__DEC_DONE_MASK (0x1UL << 2) +#define ECC_MASK__ENC_DONE_MASK (0x1UL << 1) +#define ECC_MASK__ENC_DEC_DONE_MASK (0x1UL << 0) + +#else + +#define ECC_MASK__SOME_STUCK_BIT_EXCEEDED (0x1UL << 9) +#define ECC_MASK__SOME_ALL_FF_MASK (0x1UL << 8) +#define ECC_MASK__SOME_ALL_ZERO_MASK (0x1UL << 7) +#define ECC_MASK__SOME_ERROR_ALERT_MASK (0x1UL << 5) +#define ECC_MASK__ANY_UNCORRECTABLE_MASK (0x1UL << 3) +#define ECC_MASK__ENC_DONE_MASK (0x1UL << 2) // note swap from 8920 +#define ECC_MASK__DEC_DONE_MASK (0x1UL << 1) // note swap from 8920 +#define ECC_MASK__ENC_DEC_DONE_MASK (0x1UL << 0) + +#endif + +// ============================================================================= +// ECC_HISTORY bitfields +// ============================================================================= + +#if FMI_VERSION == 0 + +#define ECC_HISTORY__ERROR_COUNT_CLEAR (0x1UL << 24) +#define ECC_HISTORY__ERROR_COUNT(n) (((n) & 0x1FFF) << 11) +#define ECC_HISTORY__DECODING_NUMBER_CLEAR (0x1UL << 10) +#define ECC_HISTORY__DECODING_NUMBER(n) (((n) & 0x3FF) << 0) + +#else + +#define ECC_HISTORY__ERROR_COUNT_CLEAR (0x1UL << 26) +#define ECC_HISTORY__ERROR_COUNT(n) (((n) & 0x7FFF) << 11) +#define ECC_HISTORY__DECODING_NUMBER_CLEAR (0x1UL << 10) +#define ECC_HISTORY__DECODING_NUMBER(n) (((n) & 0x3FF) << 0) + +#endif + + +#endif // _H2FMI_REGS_H_ + +// ********************************** EOF ************************************** diff --git a/drivers/apple/h2fmi/boot/rules.mk b/drivers/apple/h2fmi/boot/rules.mk new file mode 100644 index 0000000..c105c87 --- /dev/null +++ b/drivers/apple/h2fmi/boot/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_HW_BOOTROM_NAND=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/H2fmi_bootrom.o diff --git a/drivers/apple/h2fmi/debug.c b/drivers/apple/h2fmi/debug.c new file mode 100644 index 0000000..92ff952 --- /dev/null +++ b/drivers/apple/h2fmi/debug.c @@ -0,0 +1,865 @@ +// ***************************************************************************** +// +// File: debug.c +// +// Copyright (C) 2010-2012, 2014 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// ***************************************************************************** + +#include +#include +#include +#include "WMROAM.h" +#include +#include +#include "H2fmi_private.h" +#include "H2fmi.h" +#include "H2fmi_ppn.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if SUPPORT_PPN + +extern UInt32 *g_pScratchBuf; + +extern h2fmi_t g_fmi0; +extern h2fmi_t g_fmi1; + +static int do_vthsweep(int argc, struct cmd_arg *argv); +static int do_ppnfw(int argc, struct cmd_arg *argv); +static int do_ppnver(int argc, struct cmd_arg *argv); +static int do_ppnrma(int argc, struct cmd_arg *args); +static int do_ppnscratchpad(int argc, struct cmd_arg *argv); +#if SUPPORT_TOGGLE_NAND +static int do_nand_dqs_delay(int argc, struct cmd_arg *args); +#endif // SUPPORT_TOGGLE_NAND + +MENU_COMMAND_DEVELOPMENT(ppnfw, do_ppnfw, "Update PPN controller firmware", NULL); +MENU_COMMAND_DEVELOPMENT(ppnver, do_ppnver, "Get PPN controller firmware version", NULL); +MENU_COMMAND_DEVELOPMENT(ppnrma, do_ppnrma, "Get PPN RMA data for a particular page", NULL); +MENU_COMMAND_DEVELOPMENT(ppnscratchpad, do_ppnscratchpad, "Perform a PPN Scratch Pad test", NULL); +MENU_COMMAND_DEVELOPMENT(vthsweep, do_vthsweep, "Performs Vth sweep on a block of a given CE and dumps the data to a file", NULL); + +#define VTHSWEEP_ARGC (4) +#define VENDOR_CODE__MICRON (0x2C) +#define VENDOR_CODE__HYNIX (0xAD) +#define VENDOR_CODE__SANDISK (0x45) +#define DMA_TRANSFER_LIMIT (16 * 1024 * 1024) +#define SCRATCHPAD_LEN (2 << 10) // there is currently a 2KB limit with Toshiba: rdar://problem/10134035 +#define DUMPLEN (8) +#define PREFILL (0xa5) +static UInt8 scratchpad_buf_get[SCRATCHPAD_LEN]; +static UInt8 scratchpad_buf_set[SCRATCHPAD_LEN]; + +#if SUPPORT_TOGGLE_NAND +MENU_COMMAND_DEVELOPMENT(nand_dqs_delay, do_nand_dqs_delay, "NAND DQS read delay test (see \"nand_dqs_delay help\")", NULL); + +#if SUPPORT_NAND_DLL +static void dll_lock_sweep(UInt32 vdd_min, UInt32 vdd_max, UInt32 vdd_step){ + UInt32 vdd; + UInt32 lock; + char pbuf[16]; + + printf("DLL lock sweep:\n"); + printf("SOC voltage: "); + for (vdd = vdd_min; vdd <= vdd_max; vdd += vdd_step) + { + snprintf(pbuf, sizeof(pbuf), "%u mV", vdd); + printf("%-7s ", pbuf); + } + printf("\nDLL lock: "); + for (vdd = vdd_min; vdd <= vdd_max; vdd += vdd_step) + { + power_set_soc_voltage(vdd, true); + WMR_DLL_CLOCK_GATE(TRUE32); + h2fmi_dll_wr(NAND_DLL_CONTROL, NAND_DLL_CONTROL__REFERENCE(0)); + WMR_DLL_CLOCK_GATE(FALSE32); + h2fmiTrainDLL(&lock); + printf("%-7u ", lock); + } + printf("\n"); + power_set_soc_voltage(platform_get_base_soc_voltage(), true); +} +#endif // SUPPORT_NAND_DLL + +static int do_nand_dqs_delay(int argc, struct cmd_arg *args) +{ + h2fmi_ce_t ce; + UInt8 status; + UInt32 *errors; + Int32 e_min; + Int32 e_max; + Int32 e0_min; + Int32 e0_max; + Int32 i; + UInt32 ei = 0; + UInt32 di; + UInt32 iter; + UInt32 dqsd; + UInt32 vdd; + UInt32 fq ; + UInt32 fmi_mask = 3; + UInt32 freq_mask; + UInt32 vdd_min; + UInt32 vdd_max; + UInt32 vdd_step = 50; + UInt32 dqsd_min = 8; + UInt32 dqsd_max = 511; + UInt32 fmi_freq; + UInt32 rd_freq; + UInt32 tHALF_CYCLE_ori; + UInt32 def_dqsd; + UInt32 timing_size; + UInt32 errors_size; + UInt32 num_freq = 0; + UInt32 num_ce = 0; + UInt32 num_iter = 5; + UInt32 num_vdd; + UInt32 num_dqsd; + Int32 num_arg; + BOOL32 vdd_ok; + NandTimingParams timing; + + if (!g_fmi0.is_toggle || !g_fmi1.is_toggle) + { + printf("Not in toggle mode.\n"); + return -1; + } + + memset(&timing, 0xFF, sizeof(timing)); + timing_size = sizeof(timing); + FIL_GetStruct(AND_STRUCT_FIL_GET_TIMINGS, &timing, &timing_size); + freq_mask = (1 << timing.ddr_tHALFCYCLE); + + vdd_min = chipid_get_soc_voltage(CHIPID_SOC_VOLTAGE_LOW); + vdd_max = chipid_get_soc_voltage(CHIPID_SOC_VOLTAGE_HIGH); + + for (i = 1; i < argc; i += num_arg + 1){ + if (!strcmp(args[i].str, "iter") && (argc-i > (num_arg = 1))) + { + if (args[i+1].u == 0) + { + printf("Invalid number of iterations.\n"); + return -1; + } + num_iter = args[i+1].u; + } + else if (!strcmp(args[i].str, "vdd") && (argc-i > (num_arg = 3))) + { + vdd_ok = ((power_set_soc_voltage(args[i+1].u, true) == 0) && (power_set_soc_voltage(args[i+2].u, true) == 0)); + power_set_soc_voltage(platform_get_base_soc_voltage(), true); + if (!vdd_ok || (args[i+1].u > args[i+2].u)) + { + printf("Invalid vdd range.\n"); + return -1; + } + vdd_min = args[i+1].u; + vdd_max = args[i+2].u; + vdd_step = (args[i+3].u == 0) ? 1 : args[i+3].u; + } + else if (!strcmp(args[i].str, "freq") && (argc-i > (num_arg = 1))) + { + if ((args[i+1].u < 1) || (args[i+1].u > 0xFFFF)) + { + printf("Invalid 16-bit bitmask of read frequencies to test.\n"); + return -1; + } + freq_mask = args[i+1].u; + } + else if (!strcmp(args[i].str, "fmi") && (argc-i > (num_arg = 1))) + { + if ((args[i+1].u < 1) || (args[i+1].u > 3)) + { + printf("Invalid 2-bit bitmask of FMI channels to use.\n"); + return -1; + } + fmi_mask = args[i+1].u; + } + else if (!strcmp(args[i].str, "dqsdel") && (argc-i > (num_arg = 2))) + { + if ((args[i+1].u < dqsd_min) || (args[i+2].u > dqsd_max) || (args[i+1].u > args[i+2].u)) + { + printf("Invalid DQS delay range (must be between %u and %u).\n", dqsd_min, dqsd_max); + return -1; + } + dqsd_min = args[i+1].u; + dqsd_max = args[i+2].u; + } + else + { + printf("Usage: nand_dqs_delay [iter ] [vdd ] "); + printf("[freq ] [fmi ] [dqsdel ]\n"); + return -1; + } + } + + for(ce = 0; ce < H2FMI_MAX_CE_TOTAL; ce++) + { + if (g_fmi0.valid_ces & (1 << ce)) + { + if(FIL_SUCCESS != h2fmi_ppn_set_features(&g_fmi0, ce, PPN_FEATURE__SCRATCH_PAD, (UInt8 *) scratchpad_buf_set, SCRATCHPAD_LEN, FALSE32, NULL)) + { + printf("Unable to access scratch pad.\n"); + return -1; + } + } + } + + num_vdd = (vdd_max - vdd_min) / vdd_step + 1; + num_dqsd = dqsd_max - dqsd_min + 1; + for(fq = 0; fq < 16; fq++) + { + if (freq_mask & (1 << fq)) + { + num_freq++; + } + } + for(ce = 0; ce < H2FMI_MAX_CE_TOTAL; ce++) + { + if (((fmi_mask & 1) && (g_fmi0.valid_ces & (1 << ce))) || + ((fmi_mask & 2) && (g_fmi1.valid_ces & (1 << ce)))) + { + num_ce++; + } + } + errors_size = num_ce * num_freq * num_vdd * num_dqsd; + errors = calloc(errors_size, sizeof(errors[0])); + + fmi_freq = clock_get_frequency(CLK_FMI); + def_dqsd = FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL_GET(g_fmi0.dqs_ctrl); + printf("NAND DQS read delay test\n"); + printf("Data per iteration: %u bytes\n", SCRATCHPAD_LEN); + printf("DQS delay test range: %u - %u\n", dqsd_min, dqsd_max); + printf("FMI clock frequency: %u.%06u MHz\n", fmi_freq / 1000000, fmi_freq % 1000000); + printf("Current (default) SOC voltage: %u mV\n", platform_get_base_soc_voltage()); + #if SUPPORT_NAND_DLL + dll_lock_sweep(vdd_min, vdd_max, vdd_step); + #else + printf("Current (default) DQS read delay value: %u\n", def_dqsd); + printf("Using DLL: no\n"); + #endif // SUPPORT_NAND_DLL + + printf("Generating random data "); + for (i = 0; i < SCRATCHPAD_LEN; i += 1000){ + random_get_bytes(&scratchpad_buf_set[i], WMR_MIN(1000, SCRATCHPAD_LEN - i)); + printf("."); + } + printf("\nInterface Freq [Mhz] Vdd [mV] Iter Zero error range\n"); + printf("Bytes per test setting,%u\n\n", num_iter * SCRATCHPAD_LEN); + printf(",Byte errors\nDQS Delay"); + + tHALF_CYCLE_ori = timing.ddr_tHALFCYCLE; + + for(ce = 0; ce < H2FMI_MAX_CE_TOTAL; ce++) + { + h2fmi_t* fmi; + UInt32 dqs_ctrl_ori; + + if ((fmi_mask & 1) && (g_fmi0.valid_ces & (1 << ce))) + { + fmi = &g_fmi0; + } + else if ((fmi_mask & 2) && (g_fmi1.valid_ces & (1 << ce))) + { + fmi = &g_fmi1; + } + else + { + continue; + } + + h2fmi_ppn_set_features(fmi, ce, PPN_FEATURE__SCRATCH_PAD, (UInt8 *) scratchpad_buf_set, SCRATCHPAD_LEN, FALSE32, NULL); + + dqs_ctrl_ori = fmi->dqs_ctrl; + + for(fq = 0; fq < 16; fq++) + { + if (!(freq_mask & (1 << fq))) continue; + + timing.ddr_tHALFCYCLE = fq; + FIL_SetStruct(AND_STRUCT_FIL_SET_TIMINGS, &timing, timing_size); + rd_freq = fmi_freq / (timing.ddr_tHALFCYCLE + 1) / 2; + + for (vdd = vdd_min; vdd <= vdd_max; vdd += vdd_step) + { + printf(",\"FMI%d:CE%d, %u.%06uMhz, %umV\"", fmi->bus_id, ce, rd_freq / 1000000, rd_freq % 1000000, vdd); + power_set_soc_voltage(vdd, true); + for (iter = 0; iter < num_iter; iter++) + { + e_min = 0; + e_max = -1; + e0_min = 0; + e0_max = -1; + for (di = 0; di < num_dqsd; di++) + { + dqsd = dqsd_min + di; + fmi->dqs_ctrl = FMC_DQS_TIMING_CTRL__DQS_READ_DELAY_CTRL(dqsd); + h2fmi_wr(fmi, FMC_DQS_TIMING_CTRL, fmi->dqs_ctrl); + + h2fmi_ppn_get_feature(fmi, ce, PPN_FEATURE__SCRATCH_PAD, (UInt8 *) scratchpad_buf_get, SCRATCHPAD_LEN, &status); + + WMR_ASSERT((ei+di) < errors_size); + for (i = 0; i < SCRATCHPAD_LEN; i++) + { + if (scratchpad_buf_set[i] != scratchpad_buf_get[i]) + { + errors[ei+di]++; + } + } + + if (!errors[ei+di]) + { + e0_max = dqsd; + } + if (!errors[ei+di] && (di == 0 || errors[ei+di-1])) + { + e0_min = dqsd; + } + if ((e0_max-e0_min) > (e_max-e_min)) + { + e_max = e0_max; + e_min = e0_min; + } + } + } + printf("\n"); + ei += num_dqsd; + } + } + + fmi->dqs_ctrl = dqs_ctrl_ori; + h2fmi_wr(fmi, FMC_DQS_TIMING_CTRL, fmi->dqs_ctrl); + } + + printf("\n"); + for (di = 0; di < num_dqsd; di++) + { + printf("%u", di + dqsd_min); + for (ei = 0; ei < errors_size; ei += num_dqsd) + { + printf(",%u", errors[ei+di]); + } + printf("\n"); + } + + power_set_soc_voltage(platform_get_base_soc_voltage(), true); + timing.ddr_tHALFCYCLE = tHALF_CYCLE_ori; + FIL_SetStruct(AND_STRUCT_FIL_SET_TIMINGS, &timing, timing_size); + free(errors); + + return 0; +} +#endif // SUPPORT_TOGGLE_NAND + +static bool find_blobs(void *src_buffer, UInt32 src_length, void **fw, UInt32 *fw_len, void **fwa, UInt32 *fwa_len) +{ + DERReturn drtn; + DERSequence rdn; + DERItem seq, top = { src_buffer, src_length }; + DERDecodedInfo topDecode, keyC, valC; + + if (DR_Success != DERDecodeItem(&top, &topDecode)) { + printf("couldn't crack top level\n"); + return false; + } + + if ((ASN1_CONSTRUCTED|ASN1_APPLICATION) != ((ASN1_CONSTRUCTED|ASN1_APPLICATION) & topDecode.tag)) { + printf("top should be cons app\n"); + return false; + } + + seq.length = topDecode.content.length; + seq.data = topDecode.content.data; + + if (DR_Success != DERDecodeSeqContentInit(&seq, &rdn)) { + printf("could not initialize DER decode\n"); + return false; + } + + while ((drtn = DERDecodeSeqNext(&rdn, &keyC)) == DR_Success) { + // Got key UTF8-str, check + if (ASN1_UTF8_STRING != keyC.tag) { + printf("key invalid: %lld\n", keyC.tag); + return false; + } + + // Get value Octet-str + if (DR_Success != ((drtn = DERDecodeSeqNext(&rdn, &valC)))) { + printf("no value found for key %lld\n", keyC.tag); + return false; + } + + // Check value tag + if (ASN1_OCTET_STRING != valC.tag) { + printf("value invalid: %lld\n", valC.tag); + return false; + } + + // Decode + if ((11 == keyC.content.length) && (0 == strncmp((char*)keyC.content.data, "ppn-fw-args", 11))) { + *fwa = valC.content.data; + *fwa_len = valC.content.length; + } else if ((6 == keyC.content.length) && (0 == strncmp((char*)keyC.content.data, "ppn-fw", 6))) { + *fw = valC.content.data; + *fw_len = valC.content.length; + } else { + printf("unknown key\n"); + return false; + } + } + + return true; +} + +static int do_vthsweep(int argc, struct cmd_arg *args) +{ + // investigate if there's an easy way to limit which ppn fw can run this cmd + // Limit Vth sweep cmd to firmware that support it + + UInt8 virtual_ce; + UInt32 blk; + UInt32 numPerfPagesThatFit = DEFAULT_RAMDISK_SIZE / PPN_PERFECT_PAGE_SIZE; + struct dma_segment sgl; + h2fmi_ppn_failure_info_t failInfo; + UInt32 pagesRead = 0; + UInt32 totalPagesToRead; + UInt32 startPage; + UInt32 bytesToRead; + UInt16 gebType; + Int32 ret; + UInt8 mfgID[H2FMI_NAND_ID_SIZE]; + int thisFuncRet = -1; + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 blocks_per_cau = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU); + const UInt32 block_bits = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_BLOCK_ADDRESS); + const UInt32 block_shift = 0; + const UInt32 block_mask = (1UL << block_bits) - 1; + const UInt32 caus_per_ce = fil->GetDeviceInfo(AND_DEVINFO_CAUS_PER_CE); + const UInt32 cau_bits = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_CAU_ADDRESS); + const UInt32 cau_shift = block_bits + block_shift; + const UInt32 cau_mask = (1UL << cau_bits) - 1; + const UInt32 slc_bits = 1; + const UInt32 slc_shift = cau_bits + cau_shift; + const UInt32 slc_mask = (1UL << slc_bits) - 1; + const UInt32 invalid_shift = slc_bits + slc_shift; + + if (argc != VTHSWEEP_ARGC) + { + printf("Usage: vthsweep \n"); + return -1; + } + + if ((virtual_ce = args[1].u) >= g_fmi0.num_of_ce + g_fmi1.num_of_ce) + { + printf("Invalid ce = %d. ce < %d\n", virtual_ce, g_fmi0.num_of_ce + g_fmi1.num_of_ce); + return -1; + } + + blk = args[2].u; + if ((0 != (blk >> invalid_shift)) || + (blocks_per_cau <= ((blk >> block_shift) & block_mask)) || + (caus_per_ce <= ((blk >> cau_shift) & cau_mask))) + { + printf("Invalid address: block %u (max %u). cau %u (max %u), slc %u, reserved %u\n", + ((blk >> block_shift) & block_mask), blocks_per_cau - 1, + ((blk >> cau_shift) & cau_mask), caus_per_ce - 1, + ((blk >> slc_shift) & slc_mask), + blk >> invalid_shift); + return -1; + } + +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + transitionWorldFromDDR(PPN_PS_TRANS_DDR_TO_LOW_POWER); + } + else + { +#endif + h2fmi_ppn_all_channel_power_state_transition(PPN_PS_TRANS_ASYNC_TO_LOW_POWER); +#if SUPPORT_TOGGLE_NAND + } +#endif + + ret = h2fmiPpnGetManufacturerId(virtual_ce, mfgID); + if (ret != FIL_SUCCESS) + { + printf("Failed to read Mfg ID! ret = 0x%x\n", ret); + goto finish; + } + + if ((mfgID[0] != VENDOR_CODE__HYNIX) && (mfgID[0] != VENDOR_CODE__SANDISK) && (mfgID[0] != VENDOR_CODE__MICRON)) + { + printf("Vendor 0x%x not supported!\n", mfgID[0]); + goto finish; + } + + if ((ret = h2fmiVthSweepSetup(virtual_ce, blk, &failInfo, &bytesToRead)) != FIL_SUCCESS) + { + printf("h2fmiVthSweepSetup failed! ret = 0x%x, bytesToRead = 0x%x\n", ret, bytesToRead); + goto finish; + } + totalPagesToRead = FAIL_INFO_GET_PAGE_COUNT(g_fmi0.ppn->bytes_per_row_address, failInfo); + startPage = FAIL_INFO_GET_START_PAGE(g_fmi0.ppn->bytes_per_row_address, failInfo); + gebType = FAIL_INFO_GET_TYPE(g_fmi0.ppn->bytes_per_row_address, failInfo); + + WMR_ASSERT(gebType == PPN_GEB_TYPE__EMB_SWEEP_GEB_TYPE); + WMR_ASSERT(bytesToRead == totalPagesToRead * PPN_PERFECT_PAGE_SIZE); + + sgl.paddr = (UInt32)env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + + printf("\033[1;31m"); // change font color to red & bold + while (pagesRead < totalPagesToRead) + { + UInt32 currentPagesToRead = WMR_MIN(WMR_MIN(numPerfPagesThatFit, totalPagesToRead - pagesRead), DMA_TRANSFER_LIMIT / PPN_PERFECT_PAGE_SIZE); + sgl.length = currentPagesToRead * PPN_PERFECT_PAGE_SIZE; + + printf("Status: %d%%, Pages: %d/%d", pagesRead * 100 / totalPagesToRead, pagesRead, totalPagesToRead); + if ((ret = h2fmiDmaDebugData(virtual_ce, startPage + pagesRead, currentPagesToRead, &sgl, FALSE32)) != FIL_SUCCESS) + { + printf("h2fmiDmaDebugData failed ret = 0x%x\n", ret); + goto finish; + } + pagesRead += currentPagesToRead; + + if ((ret = usb_send_data_to_file(args[3].str, sgl.length, sgl.paddr, 0))) + { + printf("usb_cmd_put failed ret = 0x%x\n", ret); + goto finish; + } + printf("\033[0E\033[2K"); // go to start of line and erase the line respectively + } + printf("Status: %d%%, Pages: %d/%d\n", pagesRead * 100 / totalPagesToRead, pagesRead, totalPagesToRead); + printf("\033[0m"); // change font color back to default + thisFuncRet = 0; + +finish: + + // not going back to normal/DDR mode because the nand needs to be reset + h2fmi_ppn_recover_nand(); + + return thisFuncRet; +} + +static int do_ppnfw(int argc, struct cmd_arg *args) +{ + addr_t buf_ptr; + size_t buf_len; + UInt32 virtualCe; + Int32 status; + void *fw_buffer = NULL; + UInt32 fw_length; + void *fwa_buffer = NULL; + UInt32 fwa_length; + int ret = 0; + + if (argc > 3) + { + return -1; + } + + buf_ptr = (argc > 1) ? args[1].u : env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + buf_len = (argc > 2) ? args[2].u : env_get_uint("filesize", 0); + + if (!security_allow_memory((void*)buf_ptr, buf_len)) + { + return -2; + } + + fw_buffer = NULL; + fw_length = 0; + fwa_buffer = NULL; + fwa_length = 0; + find_blobs((void*)buf_ptr, buf_len, &fw_buffer, &fw_length, &fwa_buffer, &fwa_length); + if ((NULL == fw_buffer) && (NULL == fwa_buffer)) + { + printf("couldn't find both fw and fwa payloads\n"); + return -3; + } + +#if SUPPORT_TOGGLE_NAND + if (g_fmi0.is_toggle_system) + { + transitionWorldFromDDR(PPN_FEATURE__POWER_STATE__LOW_POWER); + } +#endif + + // reset device to ensure clean initial state (and ensure PPN 1.0 device is in LP mode) + h2fmi_nand_reset_all(&g_fmi0); + h2fmi_nand_reset_all(&g_fmi1); + h2fmi_ppn_post_rst_pre_pwrstate_operations(&g_fmi0); + h2fmi_ppn_post_rst_pre_pwrstate_operations(&g_fmi1); + + for (virtualCe = 0; virtualCe < H2FMI_MAX_CE_TOTAL; virtualCe++) + { + printf("Updating virtual CE %d\n", virtualCe); + + status = h2fmiPpnUpdateFw(virtualCe, fw_buffer, fw_length, fwa_buffer, fwa_length); + if (status == FIL_SUCCESS) + { + printf("Firmware successfully updated on virtual CE %d\n", + virtualCe); + } + else if (status == FIL_UNSUPPORTED_ERROR) + { + printf("Virtual CE %d doesn't support firmware updates; skipping\n", + virtualCe); + } + else + { + printf("PPN Firmware Update failed\n"); + ret = -10; + goto done; + } + + } + +done: + + // issue FF reset after the firmware update to allow the device to transition to the new firmware + // on monodie parts running invalid fw, fmi1 may not be valid + // a reboot is required to sync up the system with the new firmware + printf("System running in low power mode, reboot required after firmware update\n"); + h2fmi_nand_reset_all(&g_fmi0); + h2fmi_nand_reset_all(&g_fmi1); + + return ret; +} + +static int do_ppnver(int argc, struct cmd_arg *argv) +{ + UInt32 virtualCe; + UInt8 buffer[NAND_DEV_PARAM_LEN_PPN]; + + if (!g_fmi0.is_ppn) + { + WMR_PRINT(ERROR, "Target is not a PPN device\n"); + return -1; + } + + for (virtualCe = 0; virtualCe < H2FMI_MAX_CE_TOTAL; virtualCe++) + { + if (FIL_SUCCESS == h2fmiPpnGetFirmwareVersion(virtualCe, buffer)) + { + printf("PPN Version for virtual CE %d: %16.16s\n", virtualCe, buffer); + } + } + return 0; +} + +static void rma_usage(void) +{ + printf("Usage: \n"); + printf(" ppnrma get []\n"); + printf(" ppnrma delete \n"); + printf(" ppnrma configure \n"); + printf(" ppnrma recover\n"); +} + +static int do_ppnrma(int argc, struct cmd_arg *args) +{ + h2fmi_t *fmi; + UInt32 virtualCe; + UInt32 ce; + UInt32 page; + h2fmi_ppn_failure_info_t failureInfo; + UInt32 failureLength; + void *buffer; + struct dma_segment sgl; + + if ((argc != 2) && (argc != 3) && (argc != 4)) + { + rma_usage(); + return -1; + } + + virtualCe = args[2].u; + page = argc > 3 ? args[3].u : 0; + + fmi = h2fmiTranslateVirtualCEToBus(virtualCe); + ce = h2fmiTranslateVirtualCEToCe(virtualCe); + + if (!strcmp(args[1].str, "get")) + { + buffer = (void *)env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + + if (argc == 4) + { + // Force Debug Data for a particular page + h2fmi_ppn_force_geb_address(fmi, ce, (PageAddressType)page); + } + + // Get general error info and additional data length + if ( h2fmi_ppn_get_general_error_info(fmi, ce, &failureInfo, &failureLength, NULL) && + (failureLength > 0)) + { + printf("Reading %d bytes of Debug Data to %p\n", failureLength, buffer); + + sgl.paddr = (UInt32)buffer; + sgl.length = failureLength; + WMR_PREPARE_READ_BUFFER(buffer, failureLength); + // Get full buffer + h2fmi_ppn_get_general_error_info(fmi, ce, &failureInfo, &failureLength, &sgl); + WMR_COMPLETE_READ_BUFFER(buffer, failureLength); + printf("Debug Data buffer extracted. Save to host by running 'usb put %d'\n", failureLength); + } + } + else if (!strcmp(args[1].str, "delete")) + { + UInt32 feature_data = PPN_DELETE_DEBUG_DATA__ENABLE; + + if (FIL_SUCCESS != h2fmi_ppn_set_features(fmi, + ce, + PPN_FEATURE__DELETE_DEBUG_DATA, + (UInt8*) &feature_data, + PPN_FEATURE_LENGTH_DEFAULT, + FALSE32, + NULL)) + { + printf("delete debug data failed\n"); + return -1; + } + else + { + printf("Debug data deleted\n"); + } + } + else if (!strcmp(args[1].str, "configure")) + { + if (argc < 4) + { + rma_usage(); + return -1; + } + fmi->ppn->allow_saving_debug_data = TRUE32; + fmi->ppn->debug_flags_valid = TRUE32; + fmi->ppn->debug_flags = args[3].u; + fmi->ppn->vs_debug_flags_valid = FALSE32; + + if (FIL_SUCCESS != h2fmi_ppn_configure_debug_data(fmi, ce)) + { + printf("configuration failed\n"); + return -1; + } + } + else if (!strcmp(args[1].str, "recover")) + { + h2fmi_ppn_recover_nand(); + } + else + { + rma_usage(); + return -1; + } + + return 0; +} + +static int do_ppnscratchpad(int argc, struct cmd_arg *argv) +{ + int ret = 0; + int argi = 1; + uint32_t len = (argi < argc ? argv[argi++].u : SCRATCHPAD_LEN); + void *src = (argi < argc ? (void *)argv[argi++].u : NULL); + + uint32_t ce; + + if (SCRATCHPAD_LEN < len) + { + printf("truncating length (%u) to maximum (%u)\n", len, SCRATCHPAD_LEN); + len = SCRATCHPAD_LEN; + } + + if (NULL != src) + { + memcpy(scratchpad_buf_set, src, len); + } + else + { + random_get_bytes(scratchpad_buf_set, len); + } + + for(ce = 0; ce < H2FMI_MAX_CE_TOTAL; ce++) + { + h2fmi_t* fmi; + Int32 status; + UInt32 i; + + if (0 != (g_fmi0.valid_ces & (1 << ce))) + { + fmi = &g_fmi0; + } + else if (0 != (g_fmi1.valid_ces & (1 << ce))) + { + fmi = &g_fmi1; + } + else + { + continue; + } + + status = h2fmi_ppn_set_features(fmi, ce, PPN_FEATURE__SCRATCH_PAD, scratchpad_buf_set, len, FALSE32, NULL); + if (FIL_SUCCESS != status) + { + printf("scratch pad write returned %i on bus %u, ce %u\n", status, fmi->bus_id, ce); + ret = -1; + continue; + } + + memset(scratchpad_buf_get, PREFILL, len); + if (!h2fmi_ppn_get_feature(fmi, ce, PPN_FEATURE__SCRATCH_PAD, scratchpad_buf_get, len, NULL)) + { + printf("scratch pad read returned %i on bus %u, ce %u\n", status, fmi->bus_id, ce); + ret = -1; + continue; + } + + for (i = 0; i < len; i++) + { + if (scratchpad_buf_set[i] != scratchpad_buf_get[i]) + { + UInt32 j, k; + + j = ROUNDDOWNTO(i, DUMPLEN); + printf("Expected @ 0x%08x:", j); + for (k = 0 ; DUMPLEN > k ; k++) + { + printf(" %02x", scratchpad_buf_set[j++]); + } + printf("\n"); + + j = ROUNDDOWNTO(i, DUMPLEN); + printf("Actual @ 0x%08x:", j); + for (k = 0 ; DUMPLEN > k ; k++) + { + printf(" %02x", scratchpad_buf_get[j++]); + } + printf("\n"); + + i = ROUNDUPTO(i, DUMPLEN); + + ret = -1; + } + } + } + + return ret; +} + +#endif //SUPPORT_PPN + diff --git a/drivers/apple/h2fmi/fmiss.c b/drivers/apple/h2fmi/fmiss.c new file mode 100644 index 0000000..ac05c61 --- /dev/null +++ b/drivers/apple/h2fmi/fmiss.c @@ -0,0 +1,131 @@ +// ***************************************************************************** +// +// File: fmiss.c +// +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// ***************************************************************************** +#include "fmiss.h" + + +#if FMISS_ENABLED + +#if FMISS_DUMP_ENABLED + +static void fmiss_fifo_print(UInt32 val, UInt32 cur, UInt32 ptr, UInt32 lev, UInt32 len, BOOL32 err) +{ + BOOL32 is_head = FALSE32; + BOOL32 is_edge = FALSE32; + BOOL32 is_queued = FALSE32; + + if (ptr > cur) + { + cur += len; + } + + if (ptr + lev == cur) + { + is_edge = TRUE32; + } + else if (ptr == cur) + { + is_head = TRUE32; + is_edge = TRUE32; + } + else if (ptr + lev > cur) + { + is_queued = TRUE32; + } + + printf("0x%08x %c %c%c ", val, + (err ? '!' : ' '), + (is_head ? '<' : ' '), + (is_edge ? '-' : (is_queued ? '|' : ' '))); +} + +void fmiss_dump(h2fmi_t *fmi) +{ + const UInt32 mLength = SEQUENCER_MACROS(~0) - SEQUENCER_MACROS(0) + 1; + const UInt32 mControl = h2fmi_rd(fmi, SEQ_MACRO_CONTROL); + const UInt32 mHead = SEQ_MACRO_CONTROL__GET_MACRO_ADDRESS(mControl); + const UInt32 mLevel = SEQ_MACRO_CONTROL__GET_WORD_COUNT(mControl); + const UInt32 cLength = SEQUENCER_COMMANDS(~0) - SEQUENCER_COMMANDS(0) + 1; + const UInt32 cPointer = h2fmi_rd(fmi, COMMAND_FIFO_PTR); + const UInt32 cHead = COMMAND_FIFO_PTR__READ(cPointer); + const UInt32 cLevel = COMMAND_FIFO_PTR__LEVEL(cPointer); + const UInt32 oLength = SEQUENCER_OPERANDS(~0) - SEQUENCER_OPERANDS(0) + 1; + const UInt32 oPointer = h2fmi_rd(fmi, OPERAND_FIFO_PTR); + const UInt32 oHead = OPERAND_FIFO_PTR__READ(oPointer); + const UInt32 oLevel = OPERAND_FIFO_PTR__LEVEL(oPointer); +#if FMI_VERSION >= 4 + const UInt32 sLength = SEQUENCER_STORES(~0) - SEQUENCER_STORES(0) + 1; + const UInt32 sPointer = h2fmi_rd(fmi, STORE_FIFO_PTR); + const UInt32 sHead = STORE_FIFO_PTR__READ(sPointer); + const UInt32 sLevel = STORE_FIFO_PTR__LEVEL(sPointer); +#else // FMI_VERSION < 4 + const UInt32 sLength = 0; + const UInt32 sPointer = 0; +#endif // FMI_VERSION < 4 + const UInt32 maxLength = WMR_MAX(WMR_MAX(mLength, cLength), WMR_MAX(oLength, sLength)); + UInt32 *macros; + UInt32 macro_count = 0; + UInt32 reg, i, j; + + printf("SEQ_MACRO_CONTROL: 0x%08x, COMMAND_FIFO_PTR: 0x%08x, OPERAND_FIFO_PTR: 0x%08x, STORE_FIFO_PTR: 0x%08x\n", + mControl, cPointer, oPointer, sPointer); + + printf("SEQ_INT_PND: 0x%08x, TIMEOUT_VALUE: 0x%08x, COMMAND_INT_CODE: 0x%08x\n", + h2fmi_rd(fmi, SEQ_INT_PEND), + h2fmi_rd(fmi, TIMEOUT_VALUE), + h2fmi_rd(fmi, COMMAND_INT_CODE)); + + macros = (fmi->is_ppn ? fmiss_ppn_macros(¯o_count) : fmiss_raw_macros(¯o_count)); + + printf(" %-18s%-18s%-18s%-18s", "Seq Macros:", "Seq Commands:", "Seq Operands:", "Seq Stores:"); + + for (i = 0, j = 0 ; i < maxLength; i += sizeof(UInt32), j++) + { + printf("\n%-3d: ", j); + + if (i < mLength) + { + reg = h2fmi_rd(fmi, SEQUENCER_MACROS(i)); + fmiss_fifo_print(reg, j, mHead, mLevel, mLength / sizeof(UInt32), + (j < macro_count ? reg != macros[j] : FALSE32)); + } + + if (i < cLength) + { + reg = h2fmi_rd(fmi, SEQUENCER_COMMANDS(i)); + fmiss_fifo_print(reg, j, cHead, cLevel, cLength / sizeof(UInt32), FALSE32); + + } + + if (i < oLength) + { + reg = h2fmi_rd(fmi, SEQUENCER_OPERANDS(i)); + fmiss_fifo_print(reg, j, oHead, oLevel, oLength / sizeof(UInt32), FALSE32); + } + +#if FMI_VERSION >= 4 + if (i < sLength) + { + reg = h2fmi_rd(fmi, SEQUENCER_STORES(i)); + fmiss_fifo_print(reg, j, sHead, sLevel, sLength / sizeof(UInt32), FALSE32); + } +#endif // FMI_VERSION >= 4 + } + + printf("\n"); +} + +#endif // FMISS_DUMP_ENABLED + +#endif // FMISS_ENABLED diff --git a/drivers/apple/h2fmi/fmiss.h b/drivers/apple/h2fmi/fmiss.h new file mode 100644 index 0000000..95ed5e6 --- /dev/null +++ b/drivers/apple/h2fmi/fmiss.h @@ -0,0 +1,42 @@ +// ***************************************************************************** +// +// File: fmiss.h +// +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// ***************************************************************************** +#ifndef _FMISS_H_ +#define _FMISS_H_ + +#include "H2fmi_private.h" + +#if FMISS_ENABLED + +#if H2FMI_IOP +#define FMISS_DUMP_ENABLED (1) +#endif // H2FMI_IOP + + +// Common + +#if FMISS_DUMP_ENABLED +void fmiss_dump(h2fmi_t *fmi); +#endif // FMISS_DUMP_ENABLED + +// Raw + +UInt32 *fmiss_raw_macros(UInt32 *count); + +// PPN +// +UInt32 *fmiss_ppn_macros(UInt32 *count); + +#endif // FMISS_ENABLED +#endif // _FMISS_H_ diff --git a/drivers/apple/h2fmi/fmiss_ppn.c b/drivers/apple/h2fmi/fmiss_ppn.c new file mode 100644 index 0000000..8147593 --- /dev/null +++ b/drivers/apple/h2fmi/fmiss_ppn.c @@ -0,0 +1,1342 @@ +// ***************************************************************************** +// +// File: fmiss_ppn.c +// +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// ***************************************************************************** +#include "H2fmi_private.h" +#include "H2fmi_dma.h" +#include "H2fmi_ppn.h" +#include +#include + +#if FMISS_ENABLED + +#define FMISS_TIMEOUT_VALUE(f) (1 * 1000 * f->clock_speed_khz) +#define FMISS_NS_TO_CLKS(f, t) (t * f->clock_speed_khz / (1000 * 1000)) + +// sequencer "wait_for_ready" command interrupt codes +#define SEQ_WFR_CODE_UNUSED (0x00) +#define SEQ_WFR_CODE_WRITE_STATUS (0x01) +#define SEQ_WFR_CODE_INVALID (0xFF) + +// sequencer "send_interrupt" command interrupt codes +#define SEQ_INT_CODE_UNUSED (0xFF0000) +#define SEQ_INT_CODE_DRAIN_STATUS (0xFF0001) + +#define MACRO_LENGTH(s) \ + (sizeof((UInt32[]){s})/sizeof(UInt32)) + +#if FMI_VERSION <= 3 + +#define GET_OPERATION_STATUS_SEQUENCE \ + CMD_COMMAND(NAND_CMD__GET_NEXT_OPERATION_STATUS), \ + CMD_COMMAND(NAND_CMD__OPERATION_STATUS), \ + CMD_TIMED_WAIT(0), \ + CMD_WAIT_FOR_READY(SEQ_WFR_CODE_UNUSED, 0x40, 0x40), \ + CMD_SEND_INTERRUPT(SEQ_INT_CODE_UNUSED), \ + CMD_PAUSE + +#else // FMI_VERSION <= 3 + +#define GET_OPERATION_STATUS_SEQUENCE \ + CMD_COMMAND(NAND_CMD__GET_NEXT_OPERATION_STATUS), \ + CMD_COMMAND(NAND_CMD__OPERATION_STATUS), \ + CMD_TIMED_WAIT(0), \ + CMD_WAIT_FOR_READY(SEQ_WFR_CODE_UNUSED, 0x40, 0x40), \ + CMD_STORE_TO_FIFO(FMC_NAND_STATUS) + +#define STORE_CONTROLLER_STATUS_SEQUENCE \ + CMD_COMMAND(NAND_CMD__CONTROLLER_STATUS), \ + CMD_TIMED_WAIT(0), \ + CMD_WAIT_FOR_READY(SEQ_WFR_CODE_WRITE_STATUS, 0x51, 0x40), \ + CMD_STORE_TO_FIFO(FMC_NAND_STATUS) + +#endif // FMI_VERSION <= 3 + +#define GET_CONTROLLER_STATUS_SEQUENCE \ + CMD_COMMAND(NAND_CMD__CONTROLLER_STATUS), \ + CMD_TIMED_WAIT(0), \ + CMD_WAIT_FOR_READY(SEQ_WFR_CODE_UNUSED, 0x40, 0x40), \ + CMD_SEND_INTERRUPT(SEQ_INT_CODE_UNUSED), \ + CMD_PAUSE + +#define PREP_READ_SEQUENCE \ + CMD_LOAD_FROM_FIFO(FMC_ADDRNUM), \ + CMD_LOAD_FROM_FIFO(FMC_ADDR0), \ + CMD_LOAD_FROM_FIFO(FMC_ADDR1), \ + CMD_LOAD_FROM_FIFO(FMC_CMD), \ + CMD_LOAD_NEXT_WORD(FMC_RW_CTRL), \ + FMC_RW_CTRL__CMD1_MODE | FMC_RW_CTRL__ADDR_MODE | FMC_RW_CTRL__CMD2_MODE, \ + CMD_POLL(FMC_STATUS), \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE | FMC_STATUS__CMD2DONE, \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE | FMC_STATUS__CMD2DONE, \ + CMD_LOAD_NEXT_WORD(FMC_STATUS), \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE | FMC_STATUS__CMD2DONE, \ + CMD_TIMED_WAIT(1) + +#define START_WRITE_PAGE_SEQUENCE \ + CMD_LOAD_FROM_FIFO(FMC_ADDR0), \ + CMD_LOAD_FROM_FIFO(FMC_CMD), \ + CMD_LOAD_NEXT_WORD(FMC_RW_CTRL), \ + FMC_RW_CTRL__CMD1_MODE | FMC_RW_CTRL__ADDR_MODE, \ + CMD_POLL(FMC_STATUS), \ + FMC_STATUS__CMD1DONE | FMC_STATUS__ADDRESSDONE, \ + FMC_STATUS__CMD1DONE | FMC_STATUS__ADDRESSDONE, \ + CMD_LOAD_NEXT_WORD(FMC_STATUS), \ + FMC_STATUS__CMD1DONE | FMC_STATUS__ADDRESSDONE + +#define PREP_WRITE_SEQUENCE \ + CMD_LOAD_NEXT_WORD(FMC_CMD), \ + NAND_CMD__MULTIPAGE_PREP, \ + CMD_LOAD_FROM_FIFO(FMC_ADDR0), \ + CMD_LOAD_NEXT_WORD(FMC_ADDRNUM), \ + 2, \ + CMD_LOAD_NEXT_WORD(FMC_RW_CTRL), \ + FMC_RW_CTRL__CMD1_MODE | FMC_RW_CTRL__ADDR_MODE, \ + CMD_POLL(FMC_STATUS), \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE, \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE, \ + CMD_LOAD_NEXT_WORD(FMC_STATUS), \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE, + +// fmiss_put_* APIs implemented as macros so "value" can be a conditional statement evaluated at push-time + +#define fmiss_put_command(fmi, value, level, timeout) \ + do \ + { \ + BOOL32 first = TRUE32; \ + \ + while ((COMMAND_FIFO_SIZE <= *(level)) && (!*(timeout)) && \ + ((NULL == (fmi)->fmiss_cxt) || _kIOPFMI_STATUS_SUCCESS == *((fmiss_cxt_t *)(fmi)->fmiss_cxt)->fmi_status)) \ + { \ + \ + if (!first) \ + { \ + if (!fmiss_yield(fmi)) \ + { \ + *(timeout) = TRUE32; \ + break; \ + } \ + } \ + else \ + { \ + first = FALSE32; \ + } \ + *(level) = COMMAND_FIFO_PTR__LEVEL(h2fmi_rd(fmi, COMMAND_FIFO_PTR)); \ + } \ + \ + if (COMMAND_FIFO_SIZE > *(level)) \ + { \ + h2fmi_wr(fmi, COMMAND_FIFO, value); \ + (*(level))++; \ + } \ + \ + } \ + while(0) + +#define fmiss_put_operand(fmi, value, level, timeout) \ + do \ + { \ + BOOL32 first = TRUE32; \ + \ + while ((OPERAND_FIFO_SIZE <= *(level)) && (!*(timeout)) && \ + ((NULL == (fmi)->fmiss_cxt) || _kIOPFMI_STATUS_SUCCESS == *((fmiss_cxt_t *)(fmi)->fmiss_cxt)->fmi_status)) \ + { \ + \ + if (!first) \ + { \ + if (!fmiss_yield(fmi)) \ + { \ + *(timeout) = TRUE32; \ + break; \ + } \ + } \ + else \ + { \ + first = FALSE32; \ + } \ + *(level) = OPERAND_FIFO_PTR__LEVEL(h2fmi_rd(fmi, OPERAND_FIFO_PTR)); \ + } \ + \ + if (OPERAND_FIFO_SIZE > *(level)) \ + { \ + h2fmi_wr(fmi, OPERAND_FIFO, value); \ + (*(level))++; \ + } \ + \ + } \ + while(0) + + +static UInt32 sequencer_macros[] = +{ + GET_OPERATION_STATUS_SEQUENCE, + GET_CONTROLLER_STATUS_SEQUENCE, +#if FMI_VERSION >= 4 + STORE_CONTROLLER_STATUS_SEQUENCE, +#endif // FMI_VERSION >= 4 + PREP_READ_SEQUENCE, + START_WRITE_PAGE_SEQUENCE, + PREP_WRITE_SEQUENCE +}; + +static const UInt32 sequencer_macro_count = sizeof(sequencer_macros) / sizeof(sequencer_macros[0]); + +static const UInt32 timed_wait_ns[] = +{ + PPN_TIMING_MIN_TRHW_NS, + PPN_TIMING_MIN_TWHR_NS, +}; + +static const UInt32 timed_wait_count = sizeof(timed_wait_ns) / sizeof(timed_wait_ns[0]); + +typedef enum +{ + kGetOperationStatusHead, + kGetOperationStatusLength = MACRO_LENGTH(GET_OPERATION_STATUS_SEQUENCE), + kGetOperationStatusTail = kGetOperationStatusHead + kGetOperationStatusLength - 1, + + kGetControllerStatusHead, + kGetControllerStatusLength = MACRO_LENGTH(GET_CONTROLLER_STATUS_SEQUENCE), + kGetControllerStatusTail = kGetControllerStatusHead + kGetControllerStatusLength - 1, + +#if FMI_VERSION >= 4 + kStoreControllerStatusHead, + kStoreControllerStatusLength = MACRO_LENGTH(STORE_CONTROLLER_STATUS_SEQUENCE), + kStoreControllerStatusTail = kStoreControllerStatusHead + kStoreControllerStatusLength - 1, +#endif // FMI_VERSION >= 4 + + kPrepReadHead, + kPrepReadLength = MACRO_LENGTH(PREP_READ_SEQUENCE), + kPrepReadTail = kPrepReadHead + kPrepReadLength - 1, + + kStartWritePageHead, + kStartWritePageLength = MACRO_LENGTH(START_WRITE_PAGE_SEQUENCE), + kStartWritePageTail = kStartWritePageHead + kStartWritePageLength - 1, + + kPrepWriteHead, + kPrepWriteLength = MACRO_LENGTH(PREP_WRITE_SEQUENCE), + kPrepWriteTail = kPrepWriteHead + kPrepWriteLength - 1 +} sequence_entry_t; + +typedef struct +{ + PPNCommandStruct *command; + UInt32 *fmi_status; + UInt8 *ppn_status; + UInt32 *status_page; + UInt32 *store_level; + BOOL32 *error; +} fmiss_cxt_t; + + +static UInt8 fmiss_ce_index_to_physical(const PPNCommandStruct *ppnCommand, h2fmi_ce_t ceIndex); +static UInt32 fmiss_ce_reg_to_logical(h2fmi_t *fmi, UInt32 ceCtrl); +static UInt8 fmiss_get_controller_status(h2fmi_t *fmi, UInt32 *command_level, BOOL32 *timeout); +#if FMI_VERSION <= 3 +static UInt8 fmiss_get_next_operation_status(h2fmi_t *fmi, UInt32 *command_level, BOOL32 *timeout); +#endif // FMI_VERSION <= 3 +static BOOL32 fmiss_ppn_prep_write_multi(h2fmi_t *fmi, const PPNCommandStruct *ppnCommand, UInt32 *command_level, UInt32 *operand_level); + +void fmiss_init_sequences(h2fmi_t *fmi) +{ + static BOOL32 initialized = FALSE32; + UInt32 i, j; + + if (!initialized) + { + for (i = 0; i < sequencer_macro_count; i++) + { + if (CMD_TIMED_WAIT(0) != (COMMAND_FIFO__COMMAND(~0UL) & sequencer_macros[i])) + { + continue; + } + for (j = 0; j < timed_wait_count; j++) + { + if (CMD_TIMED_WAIT(j) == sequencer_macros[i]) + { + const UInt32 clks = FMISS_NS_TO_CLKS(fmi, timed_wait_ns[j]); + sequencer_macros[i] = CMD_TIMED_WAIT(clks); + break; + } + } + } + initialized = TRUE32; + } + + for (i = 0, j = 0 ; i < sequencer_macro_count ; i++, j += sizeof(*sequencer_macros)) + { + h2fmi_wr(fmi, SEQUENCER_MACROS(j), sequencer_macros[i]); + } +} + +#if FMI_VERSION >= 4 + +static void fmiss_ppn_handle_drain_status(h2fmi_t *fmi, UInt32 count) +{ + fmiss_cxt_t *cxt = fmi->fmiss_cxt; + PPNCommandEntry *entry = &cxt->command->entry[*cxt->status_page]; + + *cxt->store_level = STORE_FIFO_PTR__LEVEL(h2fmi_rd(fmi, STORE_FIFO_PTR)); + + if ((0 == count) || (*cxt->store_level < count)) + { + count = *cxt->store_level; + } + + while (((0 < count) || cxt->error[entry->ceIdx]) && + (cxt->command->num_pages > *cxt->status_page)) + { + if (!cxt->error[entry->ceIdx]) + { + UInt32 status = h2fmi_rd(fmi, STORE_FIFO); + (*cxt->store_level)--; + count--; + *cxt->ppn_status |= status; + entry->status = status; + } + (*cxt->status_page)++; + entry++; + } +} + +static void fmiss_ppn_handle_command_fixup(h2fmi_t *fmi) +{ + const UInt32 fmc_ce_ctrl = h2fmi_rd(fmi, FMC_CE_CTRL); + const UInt32 operand_fifo_ptr = h2fmi_rd(fmi, OPERAND_FIFO_PTR); + const UInt32 command_fifo_ptr = h2fmi_rd(fmi, COMMAND_FIFO_PTR); + const UInt32 operand_count = OPERAND_FIFO_PTR__LEVEL(operand_fifo_ptr); + const UInt32 command_count = COMMAND_FIFO_PTR__LEVEL(command_fifo_ptr); + UInt32 operand_list[OPERAND_FIFO_SIZE]; + UInt32 command_list[COMMAND_FIFO_SIZE]; + BOOL32 failingCe = TRUE32; + UInt32 i; + + WMR_ASSERT(OPERAND_FIFO_SIZE >= operand_count); + WMR_ASSERT(COMMAND_FIFO_SIZE >= command_count); + + for (i = 0 ; i < operand_count ; i++) + { + const UInt32 fifoIdx = (OPERAND_FIFO_PTR__READ(operand_fifo_ptr) + i) % OPERAND_FIFO_SIZE * sizeof(UInt32); + operand_list[i] = h2fmi_rd(fmi, SEQUENCER_OPERANDS(fifoIdx)); + } + + for (i = 0 ; i < command_count ; i++) + { + const UInt32 fifoIdx = (COMMAND_FIFO_PTR__READ(command_fifo_ptr) + i) % COMMAND_FIFO_SIZE * sizeof(UInt32); + command_list[i] = h2fmi_rd(fmi, SEQUENCER_COMMANDS(fifoIdx)); + } + + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__RESET_SEQUENCER | FMI_CONTROL__ENABLE_SEQUENCER | h2fmi_rd(fmi, FMI_CONTROL)); + + // unfortunately, the sequencer reset does not propagate to the macro execution block: rdar://problem/10188242 + // wait for and discard the pending status store operation + + while (0 == STORE_FIFO_PTR__LEVEL(h2fmi_rd(fmi, STORE_FIFO_PTR))) + { + WMR_YIELD(); + } + h2fmi_rd(fmi, STORE_FIFO); + + for (i = 0 ; i < operand_count ; i++) + { + h2fmi_wr(fmi, OPERAND_FIFO, operand_list[i]); + } + + // fix-up outstanding "enable_chip" and "get_controller_status" commands for failing CE + + for (i = 0 ; i < command_count ; i++) + { + if (CMD_ENABLE_CHIP(fmc_ce_ctrl) == command_list[i]) + { + failingCe = TRUE32; + command_list[i] = CMD_ENABLE_CHIP(0); + } + else if (CMD_ENABLE_CHIP(0) == (COMMAND_FIFO__COMMAND(~0UL) & command_list[i])) + { + failingCe = FALSE32; + } + else if (failingCe && + (CMD_MACRO(kStoreControllerStatusHead, kStoreControllerStatusLength) == command_list[i])) + { + continue; + } + + h2fmi_wr(fmi, COMMAND_FIFO, command_list[i]); + } +} + +static void fmiss_ppn_handle_write_error(h2fmi_t *fmi, UInt8 status) +{ + fmiss_cxt_t *cxt = fmi->fmiss_cxt; + PPNCommandEntry *entry; + + fmiss_ppn_handle_drain_status(fmi, 0); + + entry = &cxt->command->entry[*cxt->status_page]; + + *cxt->ppn_status |= status; + entry->status = status; + (*cxt->status_page)++; + + if (0 == status) + { + *cxt->fmi_status = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if (0 != (status & PPN_CONTROLLER_STATUS__GENERAL_ERROR)) + { + fmi->ppn->general_error = TRUE32; + fmi->ppn->general_error_ce = fmiss_ce_reg_to_logical(fmi, h2fmi_rd(fmi, FMC_CE_CTRL)); + + *cxt->fmi_status = _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + else if (0 != (status & PPN_CONTROLLER_STATUS__PENDING_ERRORS)) + { + // we don't actually know which page on this CE failed yet + entry->status = PPN_CONTROLLER_STATUS__READY; + cxt->error[entry->ceIdx] = TRUE32; + } + else + { + WMR_PANIC("Unhandled NAND status: 0x%02x!\n", status); + } + + if (_kIOPFMI_STATUS_SUCCESS == *cxt->fmi_status) + { + fmiss_ppn_handle_command_fixup(fmi); + } + + return; +} + +#endif // FMI_VERSION >= 4 + +static BOOL32 fmiss_yield(h2fmi_t *fmi) +{ + BOOL32 ret = TRUE32; + const UInt32 seq_int_pend = h2fmi_rd(fmi, SEQ_INT_PEND); + + if (0 != (SEQ_INT_PEND__TIMEOUT & seq_int_pend)) + { +#if H2FMI_IOP + WMR_PANIC("Sequencer Timeout!"); +#endif // H2FMI_IOP + +#if FMI_VERSION >= 4 + fmiss_ppn_handle_write_error(fmi, 0); +#endif // FMI_VERSION >= 4 + + ret = FALSE32; + goto exit; + } + +#if FMI_VERSION >= 4 + + if ((NULL != fmi->fmiss_cxt) && (0 != (SEQ_INT_PEND__SEQUENCER_SIGNAL & seq_int_pend))) + { + const UInt32 code = h2fmi_rd(fmi, COMMAND_INT_CODE); + + h2fmi_wr(fmi, SEQ_INT_PEND, SEQ_INT_PEND__SEQUENCER_SIGNAL); + if (SEQ_WFR_CODE_INVALID != COMMAND_INT_CODE__WAIT_FOR_READY_CODE(code)) + { + switch (COMMAND_INT_CODE__WAIT_FOR_READY_CODE(code)) + { + case SEQ_WFR_CODE_WRITE_STATUS: + fmiss_ppn_handle_write_error(fmi, COMMAND_INT_CODE__WAIT_FOR_READY_STATUS(code)); + break; + + default: + WMR_PANIC("Unexpected sequencer interrupt: 0x%08x!\n", code); + } + } + else + { + switch (COMMAND_INT_CODE__READ(code)) + { + case SEQ_INT_CODE_DRAIN_STATUS: + fmiss_ppn_handle_drain_status(fmi, 0); + break; + + default: + WMR_PANIC("Unexpected sequencer interrupt: 0x%08x!\n", code); + } + } + } + else if (NULL != fmi->fmiss_cxt) + { + fmiss_ppn_handle_drain_status(fmi, 1); + } + +#endif // FMI_VERSION >= 4 + + WMR_YIELD(); + +exit: + + return ret; +} + +#if FMI_VERSION >= 4 +static UInt32 fmiss_get_store(h2fmi_t *fmi, UInt32 *level, BOOL32 *timeout) +{ + UInt32 ret = 0; + BOOL32 first = TRUE32; + + while ((0 >= *level) && (!*timeout) && + ((NULL == fmi->fmiss_cxt) || _kIOPFMI_STATUS_SUCCESS == *((fmiss_cxt_t *)fmi->fmiss_cxt)->fmi_status)) + { + if (!first) + { + if (!fmiss_yield(fmi)) + { + *timeout = TRUE32; + break; + } + } + else + { + first = FALSE32; + } + *level = STORE_FIFO_PTR__LEVEL(h2fmi_rd(fmi, STORE_FIFO_PTR)); + } + + if (0 < *level) + { + ret = h2fmi_rd(fmi, STORE_FIFO); + (*level)--; + } + + return ret; +} +#endif // FMI_VERSION >= 4 + + +Int32 fmiss_ppn_read_multi(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + struct dma_segment *data_segment_array, + struct dma_segment *meta_segment_array) +{ + const UInt32 page_count = ppnCommand->num_pages; + const UInt32 read_queue_size = fmi->ppn->device_params.read_queue_size; + UInt32 overall_status; + UInt32 prep_page; + UInt32 read_page; + UInt32 i; + UInt32 queue_depth[PPN_MAX_CES_PER_BUS] = {0}; + UInt32 ce_page_count[PPN_MAX_CES_PER_BUS] = {0}; + UInt32 iopfmiStatus; + BOOL32 timeout; + UInt32 command_level = 0; + UInt32 operand_level = 0; +#if FMI_VERSION >= 4 + UInt32 status_page = 0; + UInt32 store_level = 0; +#endif // FMI_VERSION >= 4 + UInt32 fmi_control = (FMI_CONTROL__RESET_SEQUENCER | + FMI_CONTROL__ENABLE_SEQUENCER | + FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE | + FMI_CONTROL__MODE__READ); + UInt8 op_status; + +#if FMI_VERSION >= 4 + fmi_control |= FMI_CONTROL__PAUSE_WHEN_STORE_FIFO_FULL; +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 +#endif // FMI_VERSION >= 4 + + timeout = FALSE32; + overall_status = 0; + prep_page = 0; + read_page = 0; + + WMR_ASSERT(page_count > 0); + + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__SOFTWARE_RESET); + + if(ppnCommand->options & PPN_OPTIONS_GET_PAGE_RMA_INFO) + { + h2fmi_ce_t ce = fmiss_ce_index_to_physical(ppnCommand, 0); + + WMR_PRINT(ALWAYS, "Attempting to pull RMA data for CE %d page 0x%08x\n", + ce, ppnCommand->entry[0].addr.row); + + h2fmi_ppn_force_geb_address(fmi, ce, ppnCommand->entry[0].addr.row); + return _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + + if (ppnCommand->options & PPN_OPTIONS_REPORT_HEALTH) + { + UInt32 feature = 1; + + for (i = 0; i < PPN_MAX_CES_PER_BUS; i++) + { + if (ppnCommand->ceInfo[i].pages > 0) + { + h2fmi_ce_t ce = ppnCommand->ceInfo[i].ce; + + if (FIL_SUCCESS != h2fmi_ppn_set_features(fmi, + ce, + PPN_FEATURE__ENABLE_BITFLIPS_DATA_COLLECTION, + (UInt8 *)&feature, + PPN_FEATURE_LENGTH_ENABLE_BITFLIPS_DATA_COLLECTION, + FALSE32, + NULL)) + { + WMR_PANIC("Failed to enable bitflip collection on CE index %d (physical %d)", i, ce); + } + } + } + } + + h2fmi_wr(fmi, FMI_CONFIG, fmi->fmi_config_reg); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__BYTES_PER_SECTOR(H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(fmi->logical_page_size / H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__META_BYTES_PER_SECTOR(fmi->valid_bytes_per_meta) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(fmi->valid_bytes_per_meta))); + h2fmi_wr(fmi, TIMEOUT_VALUE, FMISS_TIMEOUT_VALUE(fmi)); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + h2fmi_wr(fmi, SEQ_INT_PEND, 0xFFFFFFFF); + + for (read_page = 0; read_page < page_count; read_page++) + { + const UInt8 read_page_ce_index = ppnCommand->entry[read_page].ceIdx; + const h2fmi_ce_t read_page_phys_ce = fmiss_ce_index_to_physical(ppnCommand, + read_page_ce_index); + UInt32 lba; + + while ((queue_depth[ppnCommand->entry[prep_page].ceIdx] < read_queue_size) && (prep_page < page_count)) + { + const UInt8 ce_index = ppnCommand->entry[prep_page].ceIdx; + const h2fmi_ce_t phys_ce = fmiss_ce_index_to_physical(ppnCommand, ce_index); + UInt32 *page_addr = (UInt32 *)&ppnCommand->entry[prep_page].addr; + + if (ce_index > PPN_MAX_CES_PER_BUS) + { + WMR_PRINT(ERROR, "ce_index (%d) < PPN_MAX_CES_PER_BUS (%d)\n", ce_index, PPN_MAX_CES_PER_BUS); + return _kIOPFMI_STATUS_PARAM_INVALID; + } + + fmiss_put_command(fmi, CMD_ENABLE_CHIP(phys_ce), &command_level, &timeout); + // in Async mode, we are currently meeting tCS requirements because the command FIFO + // is empty on initial CE assertion and register writes from the IOP are relatively slow + // if the location of the CE assertion command changes, this will have to be reevaluated + if (fmi->logical_page_size == fmi->bytes_per_page) + { + fmiss_put_operand(fmi, fmi->ppn->bytes_per_row_address - 1, &operand_level, &timeout); + fmiss_put_operand(fmi, ppnCommand->entry[prep_page].addr.row, &operand_level, &timeout); + fmiss_put_operand(fmi, 0, &operand_level, &timeout); + } + else + { + fmiss_put_operand(fmi, fmi->ppn->bytes_per_full_address - 1, &operand_level, &timeout); + fmiss_put_operand(fmi, page_addr[0], &operand_level, &timeout); + fmiss_put_operand(fmi, page_addr[1], &operand_level, &timeout); + } + + if (ce_page_count[ce_index] + 1 == ppnCommand->ceInfo[ce_index].pages) + { + fmiss_put_operand(fmi, (FMC_CMD__CMD1(NAND_CMD__MULTIPAGE_READ_LAST) | + FMC_CMD__CMD2(NAND_CMD__MULTIPAGE_READ_CONFIRM)), &operand_level, &timeout); + } + else + { + fmiss_put_operand(fmi, (FMC_CMD__CMD1(NAND_CMD__MULTIPAGE_READ) | + FMC_CMD__CMD2(NAND_CMD__MULTIPAGE_READ_CONFIRM)), &operand_level, &timeout); + } + fmiss_put_command(fmi, CMD_MACRO(kPrepReadHead, kPrepReadLength), &command_level, &timeout); + if (timeout) + { + break; + } + + ce_page_count[ce_index]++; + prep_page++; + queue_depth[ce_index]++; + } + + if (0 == read_page) + { + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + data_segment_array, + h2fmi_dma_data_fifo(fmi), + ppnCommand->lbas * fmi->logical_page_size, + sizeof(UInt32), + H2FMI_DMA_BURST_CYCLES, + fmi->current_aes_cxt); + + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_meta_chan(fmi), + meta_segment_array, + h2fmi_dma_meta_fifo(fmi), + ppnCommand->lbas * fmi->valid_bytes_per_meta, +#if FMI_VERSION >= 4 + sizeof(UInt32), + 4, +#else // FMI_VERSION < 4 + sizeof(UInt8), + 1, +#endif // FMI_VERSION < 4 + NULL); + } + + fmiss_put_command(fmi, CMD_ENABLE_CHIP(read_page_phys_ce), &command_level, &timeout); +#if FMI_VERSION <= 3 + op_status = fmiss_get_next_operation_status(fmi, &command_level, &timeout); + + if (fmi->retire_on_invalid_refresh && + ((PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR) == + (op_status & (PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR)))) + { + // Remap 0x43 (refresh + invalid) to 0x45 (retire + invalid) + op_status = (op_status & ~(PPN_OPERATION_STATUS__REFRESH)) | PPN_OPERATION_STATUS__RETIRE; + } + ppnCommand->entry[read_page].status = op_status; + overall_status |= op_status; +#else // FMI_VERSION <= 3 + if (STORE_FIFO_SIZE <= read_page) + { + op_status = fmiss_get_store(fmi, &store_level, &timeout); + + if (fmi->retire_on_invalid_refresh && + ((PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR) == + (op_status & (PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR)))) + { + // Remap 0x43 (refresh + invalid) to 0x45 (retire + invalid) + op_status = (op_status & ~(PPN_OPERATION_STATUS__REFRESH)) | PPN_OPERATION_STATUS__RETIRE; + } + ppnCommand->entry[status_page].status = op_status; + overall_status |= op_status; + + if (0 != (overall_status & PPN_OPERATION_STATUS__GENERAL_ERROR)) + { + const PPNCommandEntry *entry = &ppnCommand->entry[status_page]; + const PPNCommandCeInfo *ceInfo = &ppnCommand->ceInfo[entry->ceIdx]; + + fmi->ppn->general_error = TRUE32; + fmi->ppn->general_error_ce = ceInfo->ce; + } + status_page++; + } + fmiss_put_command(fmi, CMD_MACRO(kGetOperationStatusHead, kGetOperationStatusLength), &command_level, &timeout); +#endif // FMI_VERSION <= 3 + + if (overall_status & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + WMR_PRINT(ERROR, "Aborting read due to general error\n"); + break; + } + + fmiss_put_command(fmi, CMD_TIMED_WAIT(FMISS_NS_TO_CLKS(fmi, PPN_TIMING_MIN_TRHW_NS)), &command_level, &timeout); + fmiss_put_command(fmi, CMD_COMMAND(NAND_CMD__READ_SERIAL_OUTPUT), &command_level, &timeout); + fmiss_put_command(fmi, CMD_TIMED_WAIT(FMISS_NS_TO_CLKS(fmi, PPN_TIMING_MIN_TWHR_NS)), &command_level, &timeout); + for (lba = 0; lba < ppnCommand->entry[read_page].lbas; lba++) + { +#if FMI_VERSION >= 5 + if ((0 < fmi->read_tx_page_delay) && (0 < lba)) + { + fmiss_put_command(fmi, CMD_TIMED_WAIT(fmi->read_tx_page_delay - 1), &command_level, &timeout); + } +#endif // FMI_VERSION >= 5 + fmiss_put_command(fmi, CMD_TX_PAGE, &command_level, &timeout); + } + fmiss_put_command(fmi, CMD_TIMED_WAIT(FMISS_NS_TO_CLKS(fmi, PPN_TIMING_MIN_TRHW_NS)), &command_level, &timeout); + + if (timeout) + { + break; + } + + queue_depth[read_page_ce_index]--; + } + + for (i = 0; i < PPN_MAX_CES_PER_BUS; i++) + { + if (ppnCommand->ceInfo[i].pages > 0) + { + h2fmi_ce_t phys_ce = 1 << (ppnCommand->ceInfo[i].ce & (H2FMI_MAX_CE_PER_BUS -1)); + fmiss_put_command(fmi, CMD_ENABLE_CHIP(phys_ce), &command_level, &timeout); + fmiss_put_command(fmi, CMD_COMMAND(NAND_CMD__GET_NEXT_OPERATION_STATUS), &command_level, &timeout); + } + } + fmiss_put_command(fmi, CMD_ENABLE_CHIP(0), &command_level, &timeout); + +#if FMI_VERSION >= 4 + while (!fmi->ppn->general_error && (status_page < page_count)) + { + op_status = fmiss_get_store(fmi, &store_level, &timeout); + + if (fmi->retire_on_invalid_refresh && + ((PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR) == + (op_status & (PPN_OPERATION_STATUS__REFRESH | PPN_OPERATION_STATUS__ERROR)))) + { + // Remap 0x43 (refresh + invalid) to 0x45 (retire + invalid) + op_status = (op_status & ~(PPN_OPERATION_STATUS__REFRESH)) | PPN_OPERATION_STATUS__RETIRE; + } + ppnCommand->entry[status_page].status = op_status; + + if (timeout) + { + break; + } + + overall_status |= op_status; + + if (0 != (overall_status & PPN_OPERATION_STATUS__GENERAL_ERROR)) + { + const PPNCommandEntry *entry = &ppnCommand->entry[status_page]; + const PPNCommandCeInfo *ceInfo = &ppnCommand->ceInfo[entry->ceIdx]; + + fmi->ppn->general_error = TRUE32; + fmi->ppn->general_error_ce = ceInfo->ce; + } + status_page++; + } +#endif // FMI_VERSION >= 4 + ppnCommand->page_status_summary = overall_status; + if (timeout) + { + iopfmiStatus = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + } + else if (overall_status & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + iopfmiStatus = _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + + h2fmi_wr(fmi, FMI_CONTROL, (FMI_CONTROL__RESET_SEQUENCER | + FMI_CONTROL__ENABLE_SEQUENCER)); + WMR_PRINT(ERROR, "IOP returning kIOPFMI_STATUS_PPN_GENERAL_ERROR\n"); + } + else + { + iopfmiStatus = _kIOPFMI_STATUS_SUCCESS; + + if (!h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + iopfmiStatus = _kIOPFMI_STATUS_DMA_DONE_TIMEOUT; + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + } + } + + return iopfmiStatus; +} + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM +Int32 fmiss_ppn_write_multi(h2fmi_t *fmi, + PPNCommandStruct *ppnCommand, + struct dma_segment *data_segment_array, + struct dma_segment *meta_segment_array) +{ + const UInt32 page_count = ppnCommand->num_pages; + UInt32 pageIndex = 0; + BOOL32 error[PPN_MAX_CES_PER_BUS] = {FALSE32}; + UInt8 overall_status = 0; + UInt32 ce_page_count[PPN_MAX_CES_PER_BUS] = {0}; + UInt32 command_level = 0; + UInt32 operand_level = 0; + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__ENABLE_SEQUENCER | + FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE); + UInt32 program_status = _kIOPFMI_STATUS_SUCCESS; + BOOL32 timeout = FALSE32; + UInt8 errorCeIndex; +#if FMI_VERSION >= 4 + UInt32 status_page = 0; + UInt32 store_level = 0; + fmiss_cxt_t cxt; +#endif // FMI_VERSION >= 4 + +#if FMI_VERSION >= 4 + fmi_control |= FMI_CONTROL__PAUSE_WHEN_STORE_FIFO_FULL; +#endif // FMI_VERSION >= 4 + + WMR_ASSERT(page_count > 0); + WMR_ASSERT(page_count <= fmi->ppn->device_params.prep_function_buffer_size); + + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__MODE__SOFTWARE_RESET); + h2fmi_wr(fmi, TIMEOUT_VALUE, FMISS_TIMEOUT_VALUE(fmi)); + h2fmi_wr(fmi, FMI_CONTROL, FMI_CONTROL__ENABLE_SEQUENCER); + h2fmi_wr(fmi, SEQ_INT_PEND, 0xFFFFFFFF); + + if (page_count > 1) + { + if (!fmiss_ppn_prep_write_multi(fmi, ppnCommand, &command_level, &operand_level)) + { + return _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + } + +#if FMI_VERSION >= 4 + cxt.command = ppnCommand; + cxt.fmi_status = &program_status; + cxt.ppn_status = &overall_status; + cxt.store_level = &store_level; + cxt.status_page = &status_page; + cxt.error = error; + fmi->fmiss_cxt = &cxt; +#endif // FMI_VERSION >= 4 + + h2fmi_wr(fmi, FMI_CONFIG, fmi->fmi_config_reg); + h2fmi_wr(fmi, FMI_DATA_SIZE, (FMI_DATA_SIZE__BYTES_PER_SECTOR(H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(fmi->logical_page_size / H2FMI_BYTES_PER_SECTOR) | + FMI_DATA_SIZE__META_BYTES_PER_SECTOR(fmi->valid_bytes_per_meta) | + FMI_DATA_SIZE__META_BYTES_PER_PAGE(fmi->valid_bytes_per_meta))); + h2fmi_wr(fmi, FMC_ADDRNUM, fmi->ppn->bytes_per_row_address - 1); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_data_chan(fmi), + data_segment_array, + h2fmi_dma_data_fifo(fmi), + ppnCommand->lbas * fmi->logical_page_size, + sizeof(UInt32), + H2FMI_DMA_BURST_CYCLES, + fmi->current_aes_cxt); + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_meta_chan(fmi), + meta_segment_array, + h2fmi_dma_meta_fifo(fmi), + ppnCommand->lbas * fmi->valid_bytes_per_meta, +#if FMI_VERSION >= 4 + sizeof(UInt32), + 4, +#else // FMI_VERSION < 4 + sizeof(UInt8), + 1, +#endif // FMI_VERSION < 4 + NULL); + + do + { + const UInt8 ceIndex = ppnCommand->entry[pageIndex].ceIdx; + const h2fmi_ce_t physCe = fmiss_ce_index_to_physical(ppnCommand, ceIndex); + UInt32 lba; + + fmiss_put_command(fmi, CMD_ENABLE_CHIP(error[ceIndex] ? 0 : physCe), &command_level, &timeout); + // in Async mode, we are currently meeting tCS requirements because the command FIFO + // is empty on initial CE assertion and register writes from the IOP are relatively slow + // if the location of the CE assertion command changes, this will have to be reevaluated + fmiss_put_operand(fmi, ppnCommand->entry[pageIndex].addr.row, &operand_level, &timeout); + + if (ce_page_count[ceIndex] + 1 == ppnCommand->ceInfo[ceIndex].pages) + { + fmiss_put_operand(fmi, FMC_CMD__CMD1(NAND_CMD__MULTIPAGE_PROGRAM_LAST), &operand_level, &timeout); + } + else + { + fmiss_put_operand(fmi, FMC_CMD__CMD1(NAND_CMD__MULTIPAGE_PROGRAM), &operand_level, &timeout); + } + fmiss_put_command(fmi, CMD_MACRO(kStartWritePageHead, kStartWritePageLength), &command_level, &timeout); + for (lba = 0; lba < ppnCommand->entry[pageIndex].lbas; lba++) + { + fmiss_put_command(fmi, CMD_TX_PAGE, &command_level, &timeout); + } + fmiss_put_command(fmi, CMD_COMMAND(NAND_CMD__MULTIPAGE_PROGRAM_CONFIRM), &command_level, &timeout); + +#if FMI_VERSION < 4 + + if (!error[ceIndex]) + { + UInt8 pageStatus = fmiss_get_controller_status(fmi, &command_level, &timeout); + + if (timeout) + { + // Don't look at pageStatus at all if we timed out - it could have bogus bits set. + pageStatus = 0; + } + + // Always mark the program as good here - if there was a program error or if the page was + // kicked off but not completed, we'll fix up the status when we pull the program error + // lists. + ppnCommand->entry[pageIndex].status = PPN_CONTROLLER_STATUS__READY; + + overall_status |= pageStatus; + if (timeout) + { + // Timeout reading page status + program_status = _kIOPFMI_STATUS_READY_BUSY_TIMEOUT; + } + else if (pageStatus & PPN_CONTROLLER_STATUS__GENERAL_ERROR) + { + program_status = _kIOPFMI_STATUS_PPN_GENERAL_ERROR; + } + else if (pageStatus & PPN_CONTROLLER_STATUS__PENDING_ERRORS) + { + error[ceIndex] = TRUE32; + } + } + else + { + // If we've seen a program error on a particular CE, we don't want to issue any more commands to it. + // But we need to keep the DMA moving so we can complete the programs on other CEs. So we kick off the + // program op with the CE disabled and just don't pull status. + ppnCommand->entry[pageIndex].status = 0; + } + +#else // FMI_VERSION >= 4 + + if (!error[ceIndex]) + { + fmiss_put_command(fmi, error[ceIndex] ? CMD_TIMED_WAIT(0) : CMD_MACRO(kStoreControllerStatusHead, kStoreControllerStatusLength), + &command_level, &timeout); + } + + if (page_count - 1 == pageIndex) + { + fmiss_put_command(fmi, CMD_SEND_INTERRUPT(SEQ_INT_CODE_DRAIN_STATUS), &command_level, &timeout); + } + +#endif // FMI_VERSION >= 4 + + ce_page_count[ceIndex]++; + pageIndex++; + } while ((program_status == _kIOPFMI_STATUS_SUCCESS) && (pageIndex < page_count)); + + fmiss_put_command(fmi, CMD_ENABLE_CHIP(0), &command_level, &timeout); + +#if FMI_VERSION >= 4 + + while ((program_status == _kIOPFMI_STATUS_SUCCESS) && (status_page < page_count)) + { + fmiss_yield(fmi); + } + +#endif // FMI_VERSION >= 4 + + if ((program_status != _kIOPFMI_STATUS_SUCCESS) || timeout || + !h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + } + + for (errorCeIndex = 0; errorCeIndex < PPN_MAX_CES_PER_BUS; errorCeIndex++) + { + UInt32 temp = 1; + UInt8 status = 0; + + if (error[errorCeIndex]) + { + const h2fmi_ce_t physCe = ppnCommand->ceInfo[errorCeIndex].ce; + + program_status = _kIOPFMI_STATUS_PGM_ERROR; + + // Program terminated early - reset sequencer + h2fmi_wr(fmi, FMI_CONTROL, (FMI_CONTROL__RESET_SEQUENCER | + FMI_CONTROL__ENABLE_SEQUENCER)); + + h2fmi_reset(fmi); + + // Find failed pages... + h2fmi_ppn_get_feature(fmi, + physCe, + PPN_FEATURE__PROGRAM_FAILED_PAGES, + (UInt8 *)fmi->error_list, + PPN_ERROR_LIST_SIZE, + &status); + + WMR_PRINT(ERROR, "PPN device reports %d pages failed program\n", fmi->error_list[0]); + h2fmi_ppn_process_error_list(fmi, + ppnCommand, + errorCeIndex, + fmi->error_list, + PPN_PROGRAM_STATUS_FAIL); + + // Find pending pages... + h2fmi_ppn_get_feature(fmi, + physCe, + PPN_FEATURE__PROGRAM_IGNORED_PAGES, + (UInt8 *)fmi->error_list, + PPN_ERROR_LIST_SIZE, + &status); + + WMR_PRINT(ERROR, "PPN device reports %d pages pending after program failure\n", fmi->error_list[0]); + h2fmi_ppn_process_error_list(fmi, + ppnCommand, + errorCeIndex, + fmi->error_list, + PPN_PROGRAM_STATUS_NOT_PROGRAMMED); + + // Find pages to retire... + h2fmi_ppn_get_feature(fmi, + physCe, + PPN_FEATURE__PROGRAM_RETIRED_PAGES, + (UInt8 *)fmi->error_list, + PPN_ERROR_LIST_SIZE, + &status); + + WMR_PRINT(ERROR, "PPN device reports %d pages should be retired after program failure\n", fmi->error_list[0]); + h2fmi_ppn_process_error_list(fmi, + ppnCommand, + errorCeIndex, + fmi->error_list, + PPN_PROGRAM_STATUS_FAIL); + + // Clear Program error lists + h2fmi_ppn_set_features(fmi, + physCe, + PPN_FEATURE__CLEAR_PROGRAM_ERROR_LISTS, + (UInt8 *)&temp, + 4, + FALSE32, + NULL); + + } + } + + ppnCommand->page_status_summary = overall_status; + + if (program_status == _kIOPFMI_STATUS_PPN_GENERAL_ERROR) + { + WMR_PRINT(ERROR, "Program aborted due to GEB - resetting sequencer\n"); + h2fmi_wr(fmi, FMI_CONTROL, (FMI_CONTROL__RESET_SEQUENCER | + FMI_CONTROL__ENABLE_SEQUENCER)); + } + +#if FMI_VERSION >= 4 + fmi->fmiss_cxt = NULL; +#endif // FMI_VERSION >= 4 + + return program_status; +} +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + +static BOOL32 fmiss_ppn_prep_write_multi(h2fmi_t *fmi, + const PPNCommandStruct *ppnCommand, + UInt32 *command_level, + UInt32 *operand_level) +{ + const UInt32 totalPages = ppnCommand->num_pages; + UInt16 ceIndex; + UInt32 pageIndex; + struct dma_segment dma_segment; + UInt32 fmi_control = (FMI_CONTROL__MODE__WRITE | + FMI_CONTROL__ENABLE_SEQUENCER | + FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE); + BOOL32 timeout = FALSE32; + +#if FMI_VERSION >= 4 + fmi_control |= FMI_CONTROL__PAUSE_WHEN_STORE_FIFO_FULL; +#endif // FMI_VERSION >= 4 + + for (pageIndex = 0 ; pageIndex < totalPages ; pageIndex++) + { + const PPNCommandEntry *entry = &ppnCommand->entry[pageIndex]; + + *fmi->ppn->prep_buffer[entry->ceIdx]++ = entry->addr.row; + } + + for (ceIndex = 0; ceIndex < PPN_MAX_CES_PER_BUS; ceIndex++) + { + const UInt32 numPages = ppnCommand->ceInfo[ceIndex].pages; + UInt32 addrBytes = numPages * sizeof(UInt32); + const h2fmi_ce_t physCe = fmiss_ce_index_to_physical(ppnCommand, ceIndex); + UInt32 fullSectors; + + fmi->ppn->prep_buffer[ceIndex] -= numPages; + + if (numPages) + { + const UInt32 prepBuffer = (UInt32)fmi->ppn->prep_buffer[ceIndex]; + + WMR_PREPARE_WRITE_BUFFER(fmi->ppn->prep_buffer[ceIndex], numPages * sizeof(**fmi->ppn->prep_buffer)); + +#if WMR_BUILDING_IBOOT + dma_segment.paddr = mem_static_map_physical(prepBuffer); +#else + dma_segment.paddr = prepBuffer; +#endif + dma_segment.length = numPages * sizeof(UInt32); + + h2fmi_dma_execute_async(DMA_CMD_DIR_TX, + h2fmi_dma_data_chan(fmi), + &dma_segment, + h2fmi_dma_data_fifo(fmi), + numPages * sizeof(UInt32), + sizeof(UInt32), + 32, + NULL); + h2fmi_wr(fmi, FMI_CONFIG, FMI_CONFIG__DMA_BURST__32_CYCLES); + fmiss_put_command(fmi, CMD_ENABLE_CHIP(physCe), command_level, &timeout); + // in Async mode, we are currently meeting tCS requirements because the command FIFO + // is empty on initial CE assertion and register writes from the IOP are relatively slow + // if the location of the CE assertion command changes, this will have to be reevaluated + fmiss_put_operand(fmi, (numPages << 8) | 0x87, operand_level, &timeout); + fmiss_put_command(fmi, CMD_MACRO(kPrepWriteHead, kPrepWriteLength), command_level, &timeout); + + fullSectors = addrBytes / H2FMI_BYTES_PER_SECTOR; + if (fullSectors > 0) + { + fmiss_put_command(fmi, CMD_LOAD_NEXT_WORD(FMI_DATA_SIZE), command_level, &timeout); + fmiss_put_command(fmi, (FMI_DATA_SIZE__BYTES_PER_SECTOR(H2FMI_BYTES_PER_SECTOR)| + FMI_DATA_SIZE__SECTORS_PER_PAGE(fullSectors)), command_level, &timeout); + fmiss_put_command(fmi, CMD_LOAD_FROM_FIFO(FMI_CONTROL), command_level, &timeout); + fmiss_put_operand(fmi, fmi_control, operand_level, &timeout); + // there must be one command spacer between FMI_CONTROL writes and CMD_TX_PAGE, + // which writes the start bit in FMI_CONTROL () + fmiss_put_command(fmi, CMD_TIMED_WAIT(0), command_level, &timeout); + fmiss_put_command(fmi, CMD_TX_PAGE, command_level, &timeout); + + addrBytes -= fullSectors * H2FMI_BYTES_PER_SECTOR; + } + + if (addrBytes > 0) + { + fmiss_put_command(fmi, CMD_LOAD_NEXT_WORD(FMI_DATA_SIZE), command_level, &timeout); + fmiss_put_command(fmi, (FMI_DATA_SIZE__BYTES_PER_SECTOR(addrBytes) | + FMI_DATA_SIZE__SECTORS_PER_PAGE(1)), command_level, &timeout); + fmiss_put_command(fmi, CMD_LOAD_FROM_FIFO(FMI_CONTROL), command_level, &timeout); + fmiss_put_operand(fmi, fmi_control, operand_level, &timeout); + // there must be one command spacer between FMI_CONTROL writes and CMD_TX_PAGE, + // which writes the start bit in FMI_CONTROL () + fmiss_put_command(fmi, CMD_TIMED_WAIT(0), command_level, &timeout); + fmiss_put_command(fmi, CMD_TX_PAGE, command_level, &timeout); + } + + fmiss_put_command(fmi, CMD_COMMAND(NAND_CMD__MULTIPAGE_PREP__CONFIRM), command_level, &timeout); + + fmiss_get_controller_status(fmi, command_level, &timeout); + + if ((timeout) || !h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { +#if H2FMI_IOP + WMR_PANIC("Timeout waiting for CDMA channel %d to complete multi prep: ce %d, %d pages", + h2fmi_dma_data_chan(fmi), physCe, numPages); +#endif // H2FMI_IOP + break; + } + } + } + + return !timeout; +} + + +static UInt8 fmiss_ce_index_to_physical(const PPNCommandStruct *ppnCommand, h2fmi_ce_t ceIndex) +{ + UInt8 physCe = ppnCommand->ceInfo[ceIndex].ce; + return 1 << (physCe & (H2FMI_MAX_CE_PER_BUS - 1)); +} + +static UInt32 fmiss_ce_reg_to_logical(h2fmi_t *fmi, UInt32 ceCtrl) +{ + return WMR_LOG2(ceCtrl) + (fmi->bus_id * H2FMI_MAX_CE_PER_BUS); +} + +static UInt8 fmiss_get_controller_status(h2fmi_t *fmi, UInt32 *command_level, BOOL32 *timeout) +{ + UInt32 seq_int; + UInt8 status = 0; + + fmiss_put_command(fmi, CMD_MACRO(kGetControllerStatusHead, + kGetControllerStatusLength), command_level, timeout); + + seq_int = h2fmi_rd(fmi, SEQ_INT_PEND) & (SEQ_INT_PEND__TIMEOUT | SEQ_INT_PEND__SEQUENCER_SIGNAL); + + while ((seq_int == 0) && !*timeout) + { + WMR_YIELD(); + seq_int = h2fmi_rd(fmi, SEQ_INT_PEND) & (SEQ_INT_PEND__TIMEOUT | SEQ_INT_PEND__SEQUENCER_SIGNAL); + } + h2fmi_wr(fmi, SEQ_INT_PEND, seq_int); + + if (seq_int & SEQ_INT_PEND__SEQUENCER_SIGNAL) + { + status = h2fmi_rd(fmi, FMC_NAND_STATUS); + if (status & PPN_CONTROLLER_STATUS__GENERAL_ERROR) + { + fmi->ppn->general_error = TRUE32; + fmi->ppn->general_error_ce = fmiss_ce_reg_to_logical(fmi, h2fmi_rd(fmi, FMC_CE_CTRL)); + } + } + else if (seq_int & SEQ_INT_PEND__TIMEOUT) + { + *timeout = TRUE32; +#if H2FMI_IOP + WMR_PANIC("Timeout reading controller status"); +#endif // !H2FMI_IOP + } + + if (!*timeout) + { + h2fmi_wr(fmi, FMI_CONTROL, h2fmi_rd(fmi, FMI_CONTROL) | FMI_CONTROL__ENABLE_SEQUENCER); + } + + return status; +} + + +#if FMI_VERSION <= 3 +static UInt8 fmiss_get_next_operation_status(h2fmi_t *fmi, UInt32 *command_level, BOOL32 *timeout) +{ + UInt32 seq_int; + UInt8 operation_status = 0; + + fmiss_put_command(fmi, CMD_MACRO(kGetOperationStatusHead, + kGetOperationStatusLength), command_level, timeout); + seq_int = h2fmi_rd(fmi, SEQ_INT_PEND) & (SEQ_INT_PEND__TIMEOUT | SEQ_INT_PEND__SEQUENCER_SIGNAL); + while ((seq_int == 0) && !*timeout) + { + WMR_YIELD(); + seq_int = h2fmi_rd(fmi, SEQ_INT_PEND) & (SEQ_INT_PEND__TIMEOUT | SEQ_INT_PEND__SEQUENCER_SIGNAL); + } + + h2fmi_wr(fmi, SEQ_INT_PEND, seq_int); + + if (seq_int & SEQ_INT_PEND__SEQUENCER_SIGNAL) + { + operation_status = h2fmi_rd(fmi, FMC_NAND_STATUS); + if (operation_status & PPN_OPERATION_STATUS__GENERAL_ERROR) + { + fmi->ppn->general_error = TRUE32; + fmi->ppn->general_error_ce = fmiss_ce_reg_to_logical(fmi, h2fmi_rd(fmi, FMC_CE_CTRL)); + } + h2fmi_wr(fmi, FMI_CONTROL, h2fmi_rd(fmi, FMI_CONTROL) | FMI_CONTROL__ENABLE_SEQUENCER); + } + else if (seq_int & SEQ_INT_PEND__TIMEOUT) + { + *timeout = TRUE32; +#if H2FMI_IOP + WMR_PANIC("Timeout"); +#endif // H2FMI_IOP + } + else + { + WMR_PANIC("Unexpected SEQ_INT status: 0x%08x\n", seq_int); + } + + return operation_status; +} +#endif // FMI_VERSION <= 3 + +UInt32 *fmiss_ppn_macros(UInt32 *count) +{ + if (NULL != count) + { + *count = sequencer_macro_count; + } + + return sequencer_macros; +} + +#endif /* FMISS_ENABLED */ diff --git a/drivers/apple/h2fmi/fmiss_raw.c b/drivers/apple/h2fmi/fmiss_raw.c new file mode 100644 index 0000000..35532ad --- /dev/null +++ b/drivers/apple/h2fmi/fmiss_raw.c @@ -0,0 +1,553 @@ +// ***************************************************************************** +// +// File: fmiss_raw.c +// +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Computer, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// ***************************************************************************** +#include "H2fmi_private.h" +#include "H2fmi_dma.h" +#include +#include + + +#if FMISS_ENABLED + +#define FMISS_TIMEOUT_VALUE(f) (1 * 1000 * f->clock_speed_khz) +#define FMISS_NS_TO_CLKS(f, t) (t * f->clock_speed_khz / (1000 * 1000)) + +#define FMI_INT_ENABLE \ + (FMI_INT_EN__LAST_ECC_DONE | \ + FMI_INT_EN__SEQUENCER_INTERRUPT | \ + FMI_INT_EN__ECC_RESULTS_FIFO_OVERFLOW | \ + FMI_INT_EN__ECC_RESULTS_FIFO_UNDERFLOW) + +#define FMI_INT_EXPECTED \ + (FMI_INT_PEND__LAST_ECC_DONE | \ + FMI_INT_PEND__SEQUENCER_INTERRUPT) + +#define FMI_INT_ERRORS \ + (FMI_INT_PEND__ECC_RESULTS_FIFO_OVERFLOW | \ + FMI_INT_PEND__ECC_RESULTS_FIFO_UNDERFLOW) + +#define SEQ_INT_ENABLE \ + (SEQ_INT_EN__TIMEOUT | \ + SEQ_INT_EN__COMMAND_FIFO_OVERFLOW | \ + SEQ_INT_EN__OPERAND_FIFO_OVERFLOW) + +#define SEQ_INT_ERRORS \ + (SEQ_INT_PEND__TIMEOUT | \ + SEQ_INT_PEND__COMMAND_FIFO_OVERFLOW | \ + SEQ_INT_PEND__OPERAND_FIFO_OVERFLOW) + +#define MACRO_LENGTH(s) \ + (sizeof((UInt32[]){s})/sizeof(UInt32)) + +#define PREP_PAGE_SEQ \ + CMD_LOAD_FROM_FIFO(FMC_ADDR1), \ + CMD_LOAD_FROM_FIFO(FMC_ADDR0), \ + CMD_LOAD_NEXT_WORD(FMC_CMD), \ + FMC_CMD__CMD1(NAND_CMD__READ) | FMC_CMD__CMD2(NAND_CMD__READ_CONFIRM), \ + CMD_LOAD_NEXT_WORD(FMC_RW_CTRL), \ + FMC_RW_CTRL__ADDR_MODE | FMC_RW_CTRL__CMD1_MODE | FMC_RW_CTRL__CMD2_MODE, \ + CMD_POLL(FMC_STATUS), \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE | FMC_STATUS__CMD2DONE, \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE | FMC_STATUS__CMD2DONE, \ + CMD_LOAD_NEXT_WORD(FMC_STATUS), \ + FMC_STATUS__ADDRESSDONE | FMC_STATUS__CMD1DONE | FMC_STATUS__CMD2DONE + +// CMD_TIMED_WAIT() takes an index into timed_wait_ns[] +#define READ_PAGE_SEQ \ + CMD_COMMAND(NAND_CMD__READ_STATUS), \ + CMD_WAIT_FOR_READY(0x01, 0x40, 0x40), \ + CMD_TIMED_WAIT(0), \ + CMD_COMMAND(NAND_CMD__READ), \ + CMD_TIMED_WAIT(1), \ + CMD_TX_PAGE + + +typedef struct +{ + h2fmi_ce_t *chip_enable_array; + UInt8 *max_corrected_array; + UInt8 *sector_stats; + UInt32 clean_pages; + UInt32 fused_pages; + UInt32 uecc_pages; + UInt32 ecc_idx; + BOOL32 timeout; +} fmiss_cxt_t; + + +static UInt32 sequencer_macros[] = +{ + PREP_PAGE_SEQ, + READ_PAGE_SEQ, +}; + +static const UInt32 sequencer_macro_count = sizeof(sequencer_macros)/sizeof(sequencer_macros[0]); + +static const UInt32 timed_wait_ns[] = +{ + 100, // tRHW + 60, // tWHR +}; + +static const UInt32 timed_wait_count = sizeof(timed_wait_ns)/sizeof(timed_wait_ns[0]); + +typedef enum +{ + kPrepPageHead, + kPrepPageLength = MACRO_LENGTH(PREP_PAGE_SEQ), + kPrepPageTail = kPrepPageHead + kPrepPageLength - 1, + + kReadPageHead, + kReadPageLength = MACRO_LENGTH(READ_PAGE_SEQ), + kReadPageTail = kReadPageHead + kReadPageLength - 1, +} sequence_entry_t; + + +static void fmiss_raw_init(h2fmi_t *fmi) +{ + BOOL32 initialized = FALSE32; + + if (!initialized) + { + UInt32 i, j; + + for (i = 0 ; i < sequencer_macro_count ; i++) + { + if (CMD_TIMED_WAIT(0) != (COMMAND_FIFO__COMMAND(~0UL) & sequencer_macros[i])) + { + continue; + } + for (j = 0 ; j < timed_wait_count ; j++) + { + if (CMD_TIMED_WAIT(j) == sequencer_macros[i]) + { + const UInt32 clks = FMISS_NS_TO_CLKS(fmi, timed_wait_ns[j]); + sequencer_macros[i] = CMD_TIMED_WAIT(clks); + break; + } + } + } + + initialized = TRUE32; + } +} + +void fmiss_raw_init_sequences(h2fmi_t *fmi) +{ + UInt32 i, j; + + fmiss_raw_init(fmi); + + for (i = 0, j = 0 ; i < sequencer_macro_count ; i++, j += sizeof(*sequencer_macros)) + { + h2fmi_wr(fmi, SEQUENCER_MACROS(j), sequencer_macros[i]); + } +} + +static UInt8 fmiss_ce_to_mask(h2fmi_ce_t ce) +{ + return FMC_CE_CTRL__CEB(ce & (H2FMI_MAX_CE_PER_BUS - 1)); +} + +static BOOL32 fmiss_process_ecc(h2fmi_t *fmi) +{ + BOOL32 ret = FALSE32; + fmiss_cxt_t *cxt = fmi->fmiss_cxt; + UInt32 sector_idx = 0; + BOOL32 clean = TRUE32; + BOOL32 fused = TRUE32; + BOOL32 uecc = FALSE32; + + if (cxt->max_corrected_array) + { + *cxt->max_corrected_array = 0; + } + + for (sector_idx = 0; sector_idx < fmi->sectors_per_page; sector_idx++) + { + const UInt32 ecc_result = h2fmi_rd(fmi, ECC_RESULT); + const BOOL32 free_page = (ecc_result & ECC_RESULT__FREE_PAGE) ? TRUE32 : FALSE32; + const BOOL32 all_zero = (ecc_result & ECC_RESULT__ALL_ZERO) ? TRUE32 : FALSE32; + const BOOL32 uncorrectable = (ecc_result & ECC_RESULT__UNCORRECTABLE) ? TRUE32 : FALSE32; + const BOOL32 stuck_bit_err = ((ecc_result & ECC_RESULT__STUCK_BIT_CNT(~0)) > + ECC_RESULT__STUCK_BIT_CNT(H2FMI_ALLOWED_STUCK_BITS_IN_FP)) ? + TRUE32 : FALSE32; + UInt32 err_cnt = (ecc_result & ECC_RESULT__ERROR_CNT_MASK) >> ECC_RESULT__ERROR_CNT_SHIFT; + + if (free_page) + { + if (stuck_bit_err) + { + clean = FALSE32; + fused = FALSE32; + uecc = TRUE32; + err_cnt = 0xFF; + } + else + { + fused = FALSE32; + err_cnt = 0xFE; + } + } + else if (all_zero) + { + clean = FALSE32; + err_cnt = 0xFF; + } + else if (uncorrectable) + { + clean = FALSE32; + fused = FALSE32; + uecc = TRUE32; + err_cnt = 0xFF; + } + else + { + clean = FALSE32; + fused = FALSE32; + } + + if (cxt->sector_stats) + { + *cxt->sector_stats = err_cnt; + cxt->sector_stats++; + } + + if (cxt->max_corrected_array && (err_cnt > *cxt->max_corrected_array)) + { + *cxt->max_corrected_array = err_cnt; + } + } + cxt->max_corrected_array++; + + if (clean) + { + cxt->clean_pages++; + } + else if (fused) + { + cxt->fused_pages++; + } + else if (uecc) + { + cxt->uecc_pages++; + } + else + { + ret = TRUE32; + } + + if (!ret && (((UInt32) ~0) == fmi->failureDetails.wFirstFailingCE)) + { + fmi->failureDetails.wFirstFailingCE = *cxt->chip_enable_array; + } + cxt->chip_enable_array++; + cxt->ecc_idx++; + + return ret; +} + +static void fmiss_interrupt_handler(void *arg) +{ + h2fmi_t* fmi = (h2fmi_t*)arg; + const UInt32 fmi_int_pend = h2fmi_rd(fmi, FMI_INT_PEND); + + h2fmi_wr(fmi, FMI_INT_PEND, fmi_int_pend & (FMI_INT_EXPECTED | FMI_INT_ERRORS)); + + if (0 != (FMI_INT_ERRORS & fmi_int_pend)) + { + WMR_PANIC("Unexpected FMI interrupt: 0x%08x", (uint32_t)(FMI_INT_ERRORS & fmi_int_pend)); + } + + if (0 != (FMI_INT_PEND__SEQUENCER_INTERRUPT & fmi_int_pend)) + { + const UInt32 seq_int_pend = h2fmi_rd(fmi, SEQ_INT_PEND); + + h2fmi_wr(fmi, SEQ_INT_PEND, seq_int_pend & SEQ_INT_ERRORS); + + if (0 != (SEQ_INT_ERRORS & seq_int_pend)) + { +#if H2FMI_IOP + if (0 != (SEQ_INT_PEND__TIMEOUT & seq_int_pend)) + { + fmiss_cxt_t *cxt = fmi->fmiss_cxt; + cxt->timeout = TRUE32; + } + else +#endif // H2FMI_IOP + { + WMR_PANIC("Unexpected SEQ interrupt: 0x%08x", (uint32_t)(SEQ_INT_ERRORS & seq_int_pend)); + } + } + } + + if (0 != (FMI_INT_PEND__LAST_ECC_DONE & fmi_int_pend)) + { + while (fmi->sectors_per_page <= ECC_RESULTS_FIFO_PTR__LEVEL(h2fmi_rd(fmi, ECC_RESULTS_FIFO_PTR))) + { + fmiss_process_ecc(fmi); + } + } +} + +static void fmiss_yield(h2fmi_t* fmi) +{ + WMR_YIELD(); + +#if !(H2FMI_WAIT_USING_ISR) + fmiss_interrupt_handler(fmi); +#endif // !H2FMI_WAIT_USING_ISR +} + + +static void fmiss_put_command(h2fmi_t *fmi, UInt32 value, UInt8 *level) +{ + const fmiss_cxt_t *cxt = fmi->fmiss_cxt; + BOOL32 first = TRUE32; + + while ((COMMAND_FIFO_SIZE <= *level) && !cxt->timeout) + { + if (!first) + { + fmiss_yield(fmi); + } + else + { + first = FALSE32; + } + *level = COMMAND_FIFO_PTR__LEVEL(h2fmi_rd(fmi, COMMAND_FIFO_PTR)); + } + + if (!cxt->timeout) + { + h2fmi_wr(fmi, COMMAND_FIFO, value); + (*level)++; + } +} + +static void fmiss_put_operand(h2fmi_t *fmi, UInt32 value, UInt8 *level) +{ + const fmiss_cxt_t *cxt = fmi->fmiss_cxt; + BOOL32 first = TRUE32; + + while ((OPERAND_FIFO_SIZE <= *level) && !cxt->timeout) + { + if (!first) + { + fmiss_yield(fmi); + } + else + { + first = FALSE32; + } + *level = OPERAND_FIFO_PTR__LEVEL(h2fmi_rd(fmi, OPERAND_FIFO_PTR)); + } + + if (!cxt->timeout) + { + h2fmi_wr(fmi, OPERAND_FIFO, value); + (*level)++; + } +} + +UInt32 h2fmi_read_multi(h2fmi_t* fmi, + UInt32 page_count, + h2fmi_ce_t* chip_enable_array, + UInt32* page_number_array, + struct dma_segment* data_segment_array, + struct dma_segment* meta_segment_array, + UInt8* max_corrected_array, + UInt8* sector_stats) +{ + UInt32 ret = _kIOPFMI_STATUS_SUCCESS; + UInt32 prep_idx = 0; + UInt32 read_idx = 0; + UInt32 prep_ce_mask = 0; + UInt32 last_ce = 0; + UInt8 command_level = 0; + UInt8 operand_level = 0; + UInt32 fmi_control = (FMI_CONTROL__RESET_SEQUENCER | + FMI_CONTROL__ENABLE_SEQUENCER | + FMI_CONTROL__SEQUENCER_TIMEOUT_ENABLE | + FMI_CONTROL__MODE__READ); + fmiss_cxt_t cxt; + +#if FMI_VERSION == 4 + if (fmi->read_stream_disable) + { + fmi_control |= FMI_CONTROL__DISABLE_STREAMING; + } +#endif // FMI_VERSION == 4 + + // Updated by the ECC interrupt handler + cxt.chip_enable_array = chip_enable_array; + cxt.max_corrected_array = max_corrected_array; + cxt.sector_stats = sector_stats; + cxt.clean_pages = 0; + cxt.fused_pages = 0; + cxt.uecc_pages = 0; + cxt.ecc_idx = 0; + cxt.timeout = FALSE32; + fmi->fmiss_cxt = &cxt; + + // Used by IOP layer + fmi->failureDetails.wNumCE_Executed = 0; + fmi->failureDetails.wOverallOperationFailure = 0; + fmi->failureDetails.wFirstFailingCE = ~0; + + fmi->isr_handler = fmiss_interrupt_handler; + + h2fmi_reset(fmi); + h2fmi_set_page_format_and_ECC_level(fmi, fmi->correctable_bits + 1); + + h2fmi_wr(fmi, TIMEOUT_VALUE, FMISS_TIMEOUT_VALUE(fmi)); + h2fmi_wr(fmi, FMI_CONTROL, fmi_control); + + h2fmi_wr(fmi, SEQ_INT_EN, SEQ_INT_ENABLE); + h2fmi_wr(fmi, FMI_INT_EN, FMI_INT_ENABLE); + h2fmi_wr(fmi, SEQ_INT_PEND, 0xFFFFFFFF); + h2fmi_wr(fmi, FMI_INT_PEND, 0xFFFFFFFF); + + h2fmi_wr(fmi, FMC_RW_CTRL, 0); + h2fmi_wr(fmi, ECC_RESULT, ECC_RESULT__FIFO_RESET); + h2fmi_wr(fmi, FMC_ADDRNUM, FMC_ADDRNUM__NUM(4)); + + for (read_idx = 0 ; page_count > read_idx ; read_idx++) + { + const UInt8 read_ce = fmiss_ce_to_mask(chip_enable_array[read_idx]); + + while (page_count > prep_idx) + { + const UInt8 prep_ce = fmiss_ce_to_mask(chip_enable_array[prep_idx]); + const UInt32 prep_page = page_number_array[prep_idx]; + + if (0 != (prep_ce_mask & prep_ce)) + { + break; + } + + if (last_ce != prep_ce) + { + fmiss_put_command(fmi, CMD_ENABLE_CHIP(prep_ce), &command_level); + last_ce = prep_ce; + } + + fmiss_put_operand(fmi, FMC_ADDR1__SEQ4((prep_page >> 16) & 0xFF), &operand_level); + fmiss_put_operand(fmi, FMC_ADDR0__SEQ3((prep_page >> 8) & 0xFF) | + FMC_ADDR0__SEQ2((prep_page >> 0) & 0xFF), &operand_level); + fmiss_put_command(fmi, CMD_MACRO(kPrepPageHead, kPrepPageLength), &command_level); + + if (cxt.timeout) + { + break; + } + + prep_ce_mask |= prep_ce; + prep_idx++; + fmi->failureDetails.wNumCE_Executed++; + } + + if (last_ce != read_ce) + { + fmiss_put_command(fmi, CMD_ENABLE_CHIP(read_ce), &command_level); + last_ce = read_ce; + } + fmiss_put_command(fmi, CMD_MACRO(kReadPageHead, kReadPageLength), &command_level); + + if (cxt.timeout) + { + break; + } + + if (0 == read_idx) + { + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_data_chan(fmi), + data_segment_array, + h2fmi_dma_data_fifo(fmi), + page_count * fmi->bytes_per_page, + sizeof(UInt32), + 8, + fmi->current_aes_cxt); + + h2fmi_dma_execute_async(DMA_CMD_DIR_RX, + h2fmi_dma_meta_chan(fmi), + meta_segment_array, + h2fmi_dma_meta_fifo(fmi), + page_count * fmi->valid_bytes_per_meta, + sizeof(UInt8), + 1, + NULL); + } + + prep_ce_mask &= ~read_ce; + } + fmiss_put_command(fmi, CMD_ENABLE_CHIP(0), &command_level); + + while (page_count > cxt.ecc_idx) + { + fmiss_yield(fmi); + if (cxt.timeout) + { + break; + } + } + + if (cxt.timeout || + !h2fmi_dma_wait(h2fmi_dma_data_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS) || + !h2fmi_dma_wait(h2fmi_dma_meta_chan(fmi), H2FMI_PAGE_TIMEOUT_MICROS)) + { + h2fmi_dma_cancel(h2fmi_dma_meta_chan(fmi)); + h2fmi_dma_cancel(h2fmi_dma_data_chan(fmi)); + ret = _kIOPFMI_STATUS_DMA_DONE_TIMEOUT; + } + + if (_kIOPFMI_STATUS_SUCCESS == ret) + { + if(0 < cxt.clean_pages) + { + ret = (page_count > cxt.clean_pages ) ? _kIOPFMI_STATUS_NOT_ALL_CLEAN : _kIOPFMI_STATUS_BLANK; + } + else if (0 < cxt.fused_pages) + { + ret = (page_count > cxt.fused_pages ) ? _kIOPFMI_STATUS_AT_LEAST_ONE_UECC : _kIOPFMI_STATUS_FUSED; + } + else if (0 < cxt.uecc_pages) + { + ret = _kIOPFMI_STATUS_AT_LEAST_ONE_UECC; + } + } + + h2fmi_wr(fmi, SEQ_INT_EN, 0); + h2fmi_wr(fmi, FMI_INT_EN, 0); + + fmi->isr_handler = NULL; + fmi->fmiss_cxt = NULL; + + fmi->failureDetails.wOverallOperationFailure = ret; + + return ret; +} + +UInt32 *fmiss_raw_macros(UInt32 *count) +{ + if (NULL != count) + { + *count = sequencer_macro_count; + } + + return sequencer_macros; +} + +#endif /* FMISS_ENABLED */ diff --git a/drivers/apple/h2fmi/rules.mk b/drivers/apple/h2fmi/rules.mk new file mode 100644 index 0000000..1a3844a --- /dev/null +++ b/drivers/apple/h2fmi/rules.mk @@ -0,0 +1,78 @@ +# Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += \ + drivers/flash_nand/raw/Whimory/Inc \ + lib \ + $(LOCAL_DIR) + +MODULES += \ + drivers/flash_nand/OAM + +ifeq ($(APPLICATION),EmbeddedIOP) + +# we need the CDMA +MODULES += \ + drivers/apple/cdma + +ALL_OBJS += \ + $(LOCAL_DIR)/H2fmi_iop.o \ + $(LOCAL_DIR)/H2fmi_boot.o \ + $(LOCAL_DIR)/H2fmi_debug.o \ + $(LOCAL_DIR)/H2fmi_erase.o \ + $(LOCAL_DIR)/H2fmi_misc.o \ + $(LOCAL_DIR)/H2fmi_read.o \ + $(LOCAL_DIR)/H2fmi_write.o \ + $(LOCAL_DIR)/H2fmi_dma_iboot.o \ + $(LOCAL_DIR)/fmiss.o \ + $(LOCAL_DIR)/fmiss_raw.o + +#ppn modules +ALL_OBJS += \ + $(LOCAL_DIR)/H2fmi_ppn.o \ + $(LOCAL_DIR)/H2fmi_ppn_iop.o \ + $(LOCAL_DIR)/fmiss_ppn.o + +# Regular support for the FMI +else + +MODULES += \ + drivers/flash_nand/id + +OPTIONS += \ + WITH_HW_FLASH_NAND=1 \ + WITH_FMI=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/H2FIL.o \ + $(LOCAL_DIR)/H2fmi.o \ + $(LOCAL_DIR)/H2fmi_boot.o \ + $(LOCAL_DIR)/H2fmi_debug.o \ + $(LOCAL_DIR)/H2fmi_erase.o \ + $(LOCAL_DIR)/H2fmi_misc.o \ + $(LOCAL_DIR)/H2fmi_read.o \ + $(LOCAL_DIR)/H2fmi_write.o \ + $(LOCAL_DIR)/H2fmi_dma_iboot.o \ + $(LOCAL_DIR)/H2fmi_test.o \ + $(LOCAL_DIR)/H2fmi_timing.o \ + $(LOCAL_DIR)/fmiss.o \ + $(LOCAL_DIR)/fmiss_raw.o + +#ppn modules +ALL_OBJS += \ + $(LOCAL_DIR)/H2fmi_ppn.o \ + $(LOCAL_DIR)/H2fmi_ppn_fil.o \ + $(LOCAL_DIR)/fmiss_ppn.o + +ALL_OBJS += \ + $(LOCAL_DIR)/debug.o + +endif diff --git a/drivers/apple/h2fmi/soc.h b/drivers/apple/h2fmi/soc.h new file mode 100644 index 0000000..d1b6ee3 --- /dev/null +++ b/drivers/apple/h2fmi/soc.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef _H_SOC_ +#define _H_SOC_ 1 + +#define SAMSUNG 0 + +#define PROC_REG_UCHAR_RW(a) ((volatile unsigned char *) (a)) +#define PROC_REG_UCHAR_RO(a) ((volatile const unsigned char *) (a)) +#define PROC_REG_USHORT_RW(a) ((volatile unsigned short *) (a)) +#define PROC_REG_USHORT_RO(a) ((volatile const unsigned short *) (a)) +#define PROC_REG_ULONG_RW(a) ((volatile unsigned long *) (a)) +#define PROC_REG_ULONG_RO(a) ((volatile const unsigned long *) (a)) + +#define FLD_SHIFT(abc, ab) (abc << (0? ab)) +// This returns a mask for m:n where only bits m to n are set +// Yes, this could be expressed perhaps with fewer characters, but this version is very readable +// and it is evaluated at compile time anyway... Are you sure you want to optimize it? 02/10/2006 sjb +#define NET_MASK(a) (0xffffffffUL >> (0?a) << (0?a) << (31-(1?a)) >> (31-(1?a))) +#define NET_SHIFT(a) ((0?a) % 32) + +// Macros for regular registers +// Read or write entire register +#define mmioReg_Val(a) (mmioReg(a)) +/// Read or write a particular field +#define mmioReg_ReadFld(a, b) ((mmioReg(a) & NET_MASK(a ## b)) >> NET_SHIFT(a ## b)) +#define mmioReg_WriteFld(a, b, c) ((mmioReg(a) = ((mmioReg(a) & ~NET_MASK(a ## b))) | FLD_SHIFT(a ## b ## c, a ## b))) +// Write a value to a particular field +#define mmioReg_WriteFldVal(a, b, c) ((mmioReg(a) = ((mmioReg(a) & ~NET_MASK(a ## b))) | c)) + +// I turned these off because they are not used yet, and because I'm not sure they're correct. +// Feel free to turn them on when you're ready to test them too... 02/10/2006 sjb +#if 1 +// Macros for registers with base offsets +// Read or write entire register +#define mmioReg_Val_Base(a, d) (mmioReg(a(d))) +/// Read or write a particular field +#define mmioReg_ReadFld_Base(a, b, d) ((mmioReg(a(d)) & NET_MASK(a ## b)) >> NET_SHIFT(a ## b)) +#define mmioReg_WriteFld_Base(a, b, c, d) ((mmioReg(a(d)) = ((mmioReg(a(d)) & ~NET_MASK(a ## b))) | FLD_SHIFT(a ## b ## c, a ## b))) +// Write a value to a particular field +#define mmioReg_WriteFldVal_Base(a, b, c, d) ((mmioReg(a(d)) = ((mmioReg(a(d)) & ~NET_MASK(a ## b))) | c)) +#endif + +// Macros for setting fields +#define SetFld(a, b, c) (NET_MASK(a ## b) & FLD_SHIFT(a ## b ## c, a ## b)) +#define SetFldVal(a, b, c) (NET_MASK(a ## b) & FLD_SHIFT(c, a ## b)) + +#if 0 +#ifdef SAMSUNG +#include "samsung/soc8900.h" +#else +// Include soc files for other platforms +#endif +#endif + +#endif // _H_SOC_ diff --git a/drivers/apple/iic/iic.c b/drivers/apple/iic/iic.c new file mode 100644 index 0000000..c5293c6 --- /dev/null +++ b/drivers/apple/iic/iic.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2010 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iic.h" + +#ifndef IICS_MASK +#define IICS_MASK ((1 << IICS_COUNT) - 1) +#endif + +static struct iic_device *get_iic_device(int port); +static void iic_setup(struct iic_device *dev); +static void iic_set_clock(struct iic_device *dev, u_int32_t period); +static void iic_reset_bus(struct iic_device *dev); + +void iic_init(void) +{ + int iic; + + dprintf(DEBUG_INFO, "iic_init()\n"); + + for (iic = 0; iic < IICS_COUNT; iic++) { + if (!((1 << iic) & IICS_MASK)) + continue; + iic_setup(get_iic_device(iic)); + } +} + +void iic_set_filter(int iic, uint32_t value) { + rFILTER(iic) = value; +} + +void iic_set_frequency(int iic, u_int32_t frequency) +{ + struct iic_device *dev; + u_int32_t period = 1000000000/frequency; + + dev = get_iic_device(iic); + if (dev == 0) return; + + iic_set_clock(dev, period); +} + +int iic_read(int iic, u_int8_t address, const void *send_data, size_t send_len, void *data, size_t len, iic_fmt_t fmt) +{ + struct iic_device *dev = get_iic_device(iic); + u_int8_t *dptr = (u_int8_t *)send_data; + u_int32_t dat, to_send; + int ret = 0; + + if (!dev) return -1; + if (!(IICS_MASK & (1 << iic))) return -1; + if (len < 1) return 0; + + while (dev->busy) task_yield(); + dev->busy = true; + + /* Possibilities: + - no sub-address + N bytes + - sub-address + N bytes + - sub-address + N bytes combined (restarted read) + */ + + rSMSTA(iic) = kS5L8940XIICSMSTAxen | kS5L8940XIICSMSTAmtn; + + to_send = send_len; + if (send_len) { + to_send++; + enter_critical_section(); + dat = (kS5L8940XIICMTXFIFOWrite | + kS5L8940XIICMTXFIFOStart | + kS5L8940XIICMTXFIFOData(address&~1)); + rMTXFIFO(iic) = dat; + while (send_len--) { + dat = kS5L8940XIICMTXFIFOData(*dptr); + if ((fmt == IIC_NORMAL) && (send_len == 0)) + dat |= kS5L8940XIICMTXFIFOStop; + rMTXFIFO(iic) = dat; + dptr++; + } + exit_critical_section(); + } + dptr = data; + enter_critical_section(); + rMTXFIFO(iic) = dat = (kS5L8940XIICMTXFIFOStart | + kS5L8940XIICMTXFIFOData(address|1)); + rMTXFIFO(iic) = dat = (kS5L8940XIICMTXFIFORead | kS5L8940XIICMTXFIFOStop | + kS5L8940XIICMTXFIFOData(len)); + exit_critical_section(); + while (len--) { + while ((dat = rMRXFIFO(iic)) & kS5L8940XIICMRXFIFOEmpty) { + if (rSMSTA(iic) & kS5L8940XIICSMSTAmtn) { + dprintf(DEBUG_INFO, "iic_read(%d) NAK\n", iic); + rCTL(iic) = rCTL(iic) | kS5L8940XIICCTLMTR; /* clear the FIFO first */ + rSMSTA(iic) = kS5L8940XIICSMSTAmtn; /* now blast the NAK bit */ + ret = -1; + goto out; + } + } + *dptr++ = kS5L8940XIICMRXFIFOData(dat); + } + + out: + dev->busy = false; + return ret; +} + +int iic_write(int iic, u_int8_t address, const void *data, size_t len) +{ + struct iic_device *dev = get_iic_device(iic); + const u_int8_t *dptr = data; + u_int32_t dat; + int ret = 0; + + if (!dev) return -1; + if (!(IICS_MASK & (1 << iic))) return -1; + + /* Don't support "quick command" */ + if (len < 1) return -1; + + while (dev->busy) task_yield(); + dev->busy = true; + + rSMSTA(iic) = kS5L8940XIICSMSTAxen | kS5L8940XIICSMSTAmtn; + + address &= ~1; + enter_critical_section(); + rMTXFIFO(iic) = (kS5L8940XIICMTXFIFOWrite | kS5L8940XIICMTXFIFOStart | + kS5L8940XIICMTXFIFOData(address)); + /* XXX bust out early if NAK observed? */ + while (len--) { + dat = kS5L8940XIICMTXFIFOData(*dptr); + if (len == 0) + dat |= kS5L8940XIICMTXFIFOStop; + rMTXFIFO(iic) = dat; + dptr++; + } + exit_critical_section(); + /* Spin til the transaction is ended or standard 1-second timeout */ + SPIN_W_TMO_WHILE(!(rSMSTA(iic) & kS5L8940XIICSMSTAxen)); + /* Check for a NAK and clean up if necessary */ + if (rSMSTA(iic) & kS5L8940XIICSMSTAmtn) { + dprintf(DEBUG_INFO, "iic_write(%d) NAK\n", iic); + rCTL(iic) = rCTL(iic) | kS5L8940XIICCTLMTR; /* clear the FIFO first */ + rSMSTA(iic) = kS5L8940XIICSMSTAmtn; /* now blast the NAK bit */ + ret = -1; + } + + dev->busy = false; + return ret; +} + +bool iic_probe(int iic, u_int8_t address) +{ + /* might be nice to implement this */ + return false; +} + +// private + +static struct iic_device _iic_device[] = { +#if IICS_COUNT > 0 + { + .bus = 0, + .clk = CLK_I2C0, + .irq = INT_IIC0, + .gpio_scl = GPIO_IIC0_SCL, + .gpio_sda = GPIO_IIC0_SDA, + }, +#endif +#if IICS_COUNT > 1 + { + .bus = 1, + .clk = CLK_I2C1, + .irq = INT_IIC1, + .gpio_scl = GPIO_IIC1_SCL, + .gpio_sda = GPIO_IIC1_SDA, + }, +#endif +#if IICS_COUNT > 2 + { + .bus = 2, + .clk = CLK_I2C2, + .irq = INT_IIC2, + .gpio_scl = GPIO_IIC2_SCL, + .gpio_sda = GPIO_IIC2_SDA, + }, +#endif +#if IICS_COUNT > 3 + { + .bus = 3, + .clk = CLK_I2C3, + .irq = INT_IIC3, + .gpio_scl = GPIO_IIC3_SCL, + .gpio_sda = GPIO_IIC3_SDA, + }, +#endif +}; + +static struct iic_device *get_iic_device(int port) +{ + if (!((1 << port) & IICS_MASK)) return 0; + + return &_iic_device[port]; +} + +static void iic_setup(struct iic_device *dev) +{ + if (dev == 0) return; + + /* make sure the clock is enabled for iic */ + clock_gate(dev->clk, true); + + /* Set for 400KHz */ + iic_set_clock(dev, 2500); + + iic_reset_bus(dev); + + rSMSTA(dev->bus) = 0xffffffff; + rIMASK(dev->bus) = 0; +} + +static void iic_set_clock(struct iic_device *dev, u_int32_t period) +{ + u_int32_t source; + u_int32_t target_Hz; + unsigned div; + + /* Obey the minimum supported by the block */ + div = kS5L8940XIICMIXDIV; + /* There's a built-in divide by 16 */ + source = (clock_get_frequency(dev->clk)) >> 4; + target_Hz = 1000000000 / period; + while (source > (target_Hz * div)) + div++; + rCTL(dev->bus) = kS5L8940XIICCTLCLK(div) | kS5L8940XIICCTLUJM; + dprintf(DEBUG_INFO, "iic_set_clock(%d) = %d\n", dev->bus, div); +} + +static void iic_reset_bus(struct iic_device *dev) +{ + u_int32_t cnt; + + // Write 00 so all devices will complete any partial transaction + // SDA starts low and goes high after the loop + // SCL start and ends the loop high + // The first and last iterations of the loop produce the + // start and stop conditions + + gpio_configure(dev->gpio_sda, GPIO_CFG_OUT_0); + + for (cnt = 0; cnt < (2 * 9 + 1); cnt++) { + gpio_configure(dev->gpio_scl, (cnt & 1) ? GPIO_CFG_OUT_0 : GPIO_CFG_IN); + spin(5); + } + + gpio_configure(dev->gpio_scl, GPIO_CFG_FUNC0); + gpio_configure(dev->gpio_sda, GPIO_CFG_FUNC0); + + rCTL(dev->bus) = rCTL(dev->bus) | kS5L8940XIICCTLMRR | kS5L8940XIICCTLMTR; +} diff --git a/drivers/apple/iic/iic.h b/drivers/apple/iic/iic.h new file mode 100644 index 0000000..4d3fbd2 --- /dev/null +++ b/drivers/apple/iic/iic.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __APPLE_IIC_H +#define __APPLE_IIC_H + +#include +#include + +#define rMTXFIFO(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x00)) +#define rMRXFIFO(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x04)) +#define rMCNT(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x08)) +#define rXFSTA(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x0C)) +#define rSMSTA(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x14)) +#define rIMASK(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x18)) +#define rCTL(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x1C)) +#define rVERSION(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x28)) +#define rFILTER(_i) (*(volatile u_int32_t *)(IIC_BASE_ADDR + ((_i) * IIC_SPACING) + 0x38)) + +#define kS5L8940XIICMTXFIFOWrite (0 << 10) +#define kS5L8940XIICMTXFIFORead (1 << 10) +#define kS5L8940XIICMTXFIFOStop (1 << 9) +#define kS5L8940XIICMTXFIFOStart (1 << 8) +#define kS5L8940XIICMTXFIFOData(_d) (((_d) & 0xff) << 0) + +#define kS5L8940XIICMRXFIFOEmpty (1 << 8) +#define kS5L8940XIICMRXFIFOData(_v) (((_v) >> 0) & 0xff) + +#define kS5L8940XIICMCNTRxCnt(_v) (((_v) >> 8) & 0xff) +#define kS5L8940XIICMCNTTxCnt(_v) (((_v) >> 0) & 0xff) + +#define kS5L8940XIICXFSTAmst(_v) (((_v) >> 28) & 0xf) +#define kS5L8940XIIC_IDLE 0 +#define kS5L8940XIICXFSTAxfifo(_v) (((_v) >> 21) & 0x3) +#define kS5L8940XIICXFSTAxcnt(_v) (((_v) >> 0) & 0xfffff) + +#define kS5L8940XIICSMSTAxip (1 << 28) +#define kS5L8940XIICSMSTAxen (1 << 27) +#define kS5L8940XIICSMSTAujf (1 << 26) +#define kS5L8940XIICSMSTAjmd (1 << 25) +#define kS5L8940XIICSMSTAjam (1 << 24) +#define kS5L8940XIICSMSTAmto (1 << 23) +#define kS5L8940XIICSMSTAmtn (1 << 21) +#define kS5L8940XIICSMSTAmrf (1 << 20) +#define kS5L8940XIICSMSTAmrne (1 << 19) +#define kS5L8940XIICSMSTAmtr (1 << 18) +#define kS5L8940XIICSMSTAmtf (1 << 17) +#define kS5L8940XIICSMSTAmte (1 << 16) +#define kS5L8940XIICSMSTAtom (1 << 6) + +#define kS5L8940XIICCTLMRR (1 << 10) +#define kS5L8940XIICCTLMTR (1 << 9) +#define kS5L8940XIICCTLUJM (1 << 8) +#define kS5L8940XIICCTLCLK(_c) (((_c) & 0xff) << 0) + +#define kS5L8940XIICMIXDIV 4 + +struct iic_device { + int bus; + int clk; + int irq; + bool busy; + gpio_t gpio_scl; + gpio_t gpio_sda; +}; + +#endif /* ! __APPLE_IIC_H */ diff --git a/drivers/apple/iic/rules.mk b/drivers/apple/iic/rules.mk new file mode 100644 index 0000000..0284962 --- /dev/null +++ b/drivers/apple/iic/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_IIC=1 + +MODULES += \ + drivers/iic + +ALL_OBJS += \ + $(LOCAL_DIR)/iic.o diff --git a/drivers/apple/lpdp_phy/include/drivers/lpdp_phy/lpdp_phy.h b/drivers/apple/lpdp_phy/include/drivers/lpdp_phy/lpdp_phy.h new file mode 100644 index 0000000..c718852 --- /dev/null +++ b/drivers/apple/lpdp_phy/include/drivers/lpdp_phy/lpdp_phy.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _LPDP_PHY_H +#define _LPDP_PHY_H + +int lpdp_init(const char *dt_path); +void lpdp_quiesce(void); +int lpdp_initialize_phy_and_pll(); +void lpdp_init_finalize(); +void lpdp_phy_reset(); +int lpdp_set_link_rate(uint32_t lr); +int lpdp_get_link_rate(uint32_t *link_rate); +int lpdp_phy_set_adjustment_levels(uint32_t lane, uint32_t voltage_swing, uint32_t eq, + bool *voltage_max_reached, bool *eq_max_reached); +bool lpdp_get_supports_downspread(); +int lpdp_set_downspread(bool value); +int lpdp_get_downspread(void); +int lpdp_phy_get_adjustment_levels(uint32_t lane, uint32_t *voltage_swing, uint32_t *eq); +void lpdp_phy_set_lane_count(const uint32_t lane_count); +void lpdp_phy_configure_alpm(bool enable); + +#endif //_LPDP_PHY_H diff --git a/drivers/apple/lpdp_phy/lpdp_v1.c b/drivers/apple/lpdp_phy/lpdp_v1.c new file mode 100644 index 0000000..cd27a72 --- /dev/null +++ b/drivers/apple/lpdp_phy/lpdp_v1.c @@ -0,0 +1,809 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "regs_v1.h" + +#if WITH_DEVICETREE +#include +#endif + +///////////////////////////////////////// +////////// debug support + +#define LPDP_DEBUG_MASK ( \ + LPDP_DEBUG_INIT | \ + LPDP_DEBUG_ERROR | \ + LPDP_DEBUG_INFO | \ + LPDP_DEBUG_PLL | \ + LPDP_DEBUG_PHY | \ + 0) + +#undef LPDP_DEBUG_MASK +#define LPDP_DEBUG_MASK (LPDP_DEBUG_INIT | LPDP_DEBUG_ERROR) + +#define LPDP_DEBUG_INIT (1<<16) // initialisation +#define LPDP_DEBUG_ERROR (1<<17) // errors +#define LPDP_DEBUG_INFO (1<<18) // info +#define LPDP_DEBUG_PLL (1<<24) // PLL +#define LPDP_DEBUG_PHY (1<<25) // PLL +#define LPDP_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((LPDP_DEBUG_ ## _fac) & (LPDP_DEBUG_MASK | LPDP_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "DP: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +#define kMaxLaneCount 4 +#define kLinkRatePhysical_162gbpsi 1620000000ULL +#define kLinkRatePhysical_270gps 2700000000ULL + +//ERRORS +#define RET_SUCCESS 0 +#define RET_ERROR -1 + +///////////////////////////////////////// +////////// typedefs, enums, structs + +enum { + kDPAuxTranscationStatus_None = -1, + kDPAuxTranscationStatus_Success, + kDPAuxTranscationStatus_IODefer, + kDPAuxTranscationStatus_IOError, + kDPAuxTranscationStatus_OtherError +}; + +enum { + kBaseVoltageType_Neg_120mV, + kBaseVoltageType_Neg_80mV, + kBaseVoltageType_Neg_40mV, + kBaseVoltageType_Pos_0mV, + kBaseVoltageType_Pos_40mV, + kBaseVoltageType_Pos_80mV, + kBaseVoltageType_Pos_120mV, + kBaseVoltageType_Pos_160mV +}; + +/* + Device tree calibration data formats: + + link-calibration-type: t700x-fixed + link-calibration-data: ${ VS DE } + + link-calibration-type: t700x-training-table + link-calibration-data: ${ VS DE VS DE VS DE VS DE } // voltage swing level 0, pre-emphasis levels 0~3 + link-calibration-data: ${ VS DE VS DE VS DE 00 00 } // voltage swing level 1, pre-emphasis levels 0~3 + link-calibration-data: ${ VS DE VS DE 00 00 00 00 } // voltage swing level 2, pre-emphasis levels 0~3 + link-calibration-data: ${ VS DE 00 00 00 00 00 00 } // voltage swing level 3, pre-emphasis level 0~3 +*/ + +struct lpdp_port_calibration { + uint8_t swing; + uint8_t deemphasis; +} __attribute__((packed)); + +#if WITH_HW_DISPLAY_EDP +#include + +#ifndef LPDP_PORT_CALIBRATION_TABLE_FIXED +#error LPDP_PORT_CALIBRATION_TABLE_FIXED not defined +#endif + +#else +static struct lpdp_port_calibration lpdp_port_calibration_table[kDPVoltageLevelMax+1][kDPEQLevelMax+1]; +#endif + +struct pll_timing { + // reference clock frequency in MHz + unsigned int ref_mhz; + + // sequencer configuration + unsigned int ref_div : 5; // sequencer divisor + unsigned int setup_count : 8; // sequencer ticks + unsigned int start_count : 8; // sequencer ticks + unsigned int pwrdn_count : 14; // sequencer ticks + unsigned int reset_count : 8; // sequencer ticks + unsigned int update_count : 8; // sequencer ticks + unsigned int finish_count : 8; // sequencer ticks +}; + +typedef enum { + lpdp_pll_state_off = 0, + lpdp_pll_state_on = 1, + lpdp_pll_state_unknown = 2, +} lpdp_pll_state_t; + +///////////////////////////////////////// +////////// PHY local variables +static uint32_t _linkRate; +static bool lpdp_pll_state = true; +static uint32_t lpdp_voltage_levels[kMaxLaneCount]; +static uint32_t lpdp_voltage_base[kMaxLaneCount]; +static uint32_t lpdp_eq_levels[kMaxLaneCount]; +static uint32_t lpdp_voltage_levels[kMaxLaneCount]; +static bool lpdp_port_calibration_table_fixed; +static uint32_t pll_vco_rctrl; +static struct pll_timing lpdp_pll_timing; +static uint32_t t_cal_duration_microseconds; + +///////////////////////////////////////// +////////// PHY local functions +static void set_bias_power_enable(bool enable); +static void set_aux_power_enable(bool enable); +static void set_lane_power_controls(unsigned int first, unsigned int limit, uint32_t mask, uint32_t bits); +static void set_lane_power_enable(bool enable); +static bool lpdp_get_pll_is_locked(); +static void set_aux_voltage_swing(uint32_t vreg_adj); +static void set_lane_adjustment_levels(unsigned int lane, uint8_t vreg_adj, uint8_t eq); +static int update_pll_dividers(uint32_t lr); +static int lpdp_power_pll(bool poweron); +static int lpdp_power_down_pll(); +static int lpdp_power_up_pll(); +static int lpdp_phy_impedance_calibration(void); +static unsigned int micro_seconds_for_count(struct pll_timing *tm, unsigned int count); +static unsigned int get_sleep_to_power_down_duration(struct pll_timing *tm); +static unsigned int get_power_down_duration(struct pll_timing *tm); +static unsigned int get_reset_duration(struct pll_timing *tm); +static unsigned int get_reset_to_update_duration(struct pll_timing *tm); +static unsigned int get_lock_duration(struct pll_timing *tm); + +///////////////////////////////////////// +////////// PHY global functions + +int lpdp_init(const char *dt_path) +{ + int i; + + for (i = 0; i < kMaxLaneCount; i++) + lpdp_voltage_base[i] = kBaseVoltageType_Pos_0mV; + + t_cal_duration_microseconds = 1000; // 1ms + + lpdp_pll_state = lpdp_pll_state_unknown; + + // Note: 200uS is the worst-case from pll_pwrdn to PLL locked under all + // conditions and settings per . + // The period from pll_pwrdn to PLL locked is: + // reset_count + update_count + finish_count + + lpdp_pll_timing.ref_mhz = 24; + lpdp_pll_timing.ref_div = 24; // ref clock ticks per (1µs) sequencer tick + lpdp_pll_timing.setup_count = 4; // µs + lpdp_pll_timing.start_count = 1; // µs + lpdp_pll_timing.pwrdn_count = 10; // µs + lpdp_pll_timing.reset_count = 100; // µs + lpdp_pll_timing.update_count = 5; // µs + lpdp_pll_timing.finish_count = 50; // µs + +#if WITH_HW_DISPLAY_EDP + lpdp_port_calibration_table_fixed = LPDP_PORT_CALIBRATION_TABLE_FIXED; +#else +#if WITH_DEVICETREE + DTNodePtr node; + char * prop_name; + void * prop_data; + uint32_t prop_size; + + // Copy DT settings in to local copy + if ( FindNode(0, dt_path, &node) ) { + + prop_name = "link-calibration-type"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + if (strcmp("t700x-training-table", prop_data) == 0) { + lpdp_port_calibration_table_fixed = false; + } else if (strcmp("t700x-fixed", prop_data) != 0) { + lpdp_port_calibration_table_fixed = true; + } else { + panic("Unknown DT LPDP Calibration Table Type."); + } + } else { + panic("Missing DT LPDP Calibration Table Type."); + } + + // gather calibration data from DeviceTree + prop_name = "link-calibration-data"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + uint32_t table_size = (lpdp_port_calibration_table_fixed) ? + sizeof(struct lpdp_port_calibration) : sizeof(struct lpdp_port_calibration) * 16; + if ( prop_size != table_size ) { + debug(ERROR, "calibration-data size mismatch, expected:%d, read:%d \n", + table_size, prop_size); + return -1; + } + + bcopy(prop_data, (void *)lpdp_port_calibration_table, prop_size); + } else { + panic("Missing DT LPDP Calibration Table Data."); + } + } else +#endif + + { + debug(ERROR, "Missing DT LPDP Calibration Table. Using Defaults"); + lpdp_port_calibration_table_fixed = true; + lpdp_port_calibration_table[0][0].swing = LPDP_PHY_LANE_x_VREG_ADJ_MAX; + lpdp_port_calibration_table[0][0].deemphasis = 0; + } +#endif + + //the block should had been properly reset. validating such assumption + assert(rLPDP_PHY_GEN_CTRL & (LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_LANE_PD_OW)); + assert(rLPDP_PLL_GEN & LPDP_PLL_GEN_RST); + + //extract Configuration of PLL + //PMGR should have programmed correctly + //we save the value to pass to the OS. + pll_vco_rctrl = rLPDP_PLL_CLK; + if (pll_vco_rctrl & LPDP_PLL_CLK_VCO_RCTRL_SEL_ENABLE) + pll_vco_rctrl = ((pll_vco_rctrl >> LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT) & LPDP_PLL_CLK_VCO_RCTRL_OW_MASK); + else + pll_vco_rctrl = 0; + + return RET_SUCCESS; +} + +int lpdp_initialize_phy_and_pll(void) +{ + int ret = RET_SUCCESS; + int i; + + // ensure lane_pd_ow=1 (default) to allow software control of lane power + rLPDP_PHY_GEN_CTRL |= (LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_SLEEP_SW | LPDP_PHY_GEN_CTRL_LANE_PD_OW); + + // perform PHY impedance calibration + ret = lpdp_phy_impedance_calibration(); + // panic if impedance calibration procedure failed + if ( ret != 0 ) { + panic("lpdp impedance calibration failed\n"); + } + + for (i = 0 ; i < kMaxLaneCount; i++) { + set_lane_adjustment_levels(i, LPDP_PHY_LANE_VREG_ADJ_360_mV, 0); + } + + //TODO!! + set_aux_voltage_swing(0xC); + + // power up all lanes [LANE_x.hi_z=0, LANE_x.ldo_pwrdn=0, LANE_x.pwrdn=0] + set_lane_power_enable(true); + + //configure PLL to an initial value + //the pll vco's value should have been set by the PMGR since it depends on fuses. + lpdp_set_link_rate(kLinkRate162Gbps); + + + return ret; +} + +void lpdp_init_finalize(void) +{ + //remove the overrides + rLPDP_PHY_GEN_CTRL &= ~(LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_LANE_PD_OW); +} + +void lpdp_quiesce() +{ + // power down all lanes [LANE_x.hi_z=1, LANE_x.ldo_pwrdn=1, LANE_x.pwrdn=1] + set_lane_power_enable(false); + + // power down AUX channel [AUX_CTRL.pwrdn=1] + set_aux_power_enable(false); + + // power down PHY's central bias [GEN_CTRL.bias_pwrdn=1] + set_bias_power_enable(false); + + // assert lpdp_sleep, pll_pwrdn, and pll_reset + lpdp_power_pll(false); + +} + +int lpdp_set_link_rate(uint32_t lr) +{ + int ret = 0; + + debug(PHY, "Setting link rate to 0x%02x\n", (uint8_t)lr); + + // Block clock output during PLL setup + rLPDP_PLL_CLK |= LPDP_PLL_CLK_VCO_BLK_VCLK; + + // assert lpdp_sleep, pll_pwrdn, and pll_reset + lpdp_power_pll(false); + + // initialize link rate to 0 + _linkRate = kLinkRate000Gbps; + + // if the target link rate is nonzero, reconfigure and power up the PLL + if ( lr > kLinkRate000Gbps ) { + + // update PLL dividers for new link rate + if (update_pll_dividers(lr)) { + ret = -1; + goto exit; + } + + + + // power up PLL and wait for lock, + // if this fails, power it back down and leave link rate at 0 + if (lpdp_power_pll(true)) { + ret = -1; + lpdp_power_pll(false); + goto exit; + } + + // finally, update the current link rate + _linkRate = lr; + } + +exit: + return ret; +} + +int lpdp_get_link_rate(uint32_t *link_rate) +{ + *link_rate = _linkRate; + return RET_SUCCESS; +} + +int lpdp_phy_set_adjustment_levels(uint32_t lane, uint32_t voltage_swing, uint32_t eq, + bool *voltage_max_reached, bool *eq_max_reached) +{ + int ret = 0; + + if ( lane > kMaxLaneCount ) + return -1; + + debug(PHY, "lane=%d voltage=%d eq=%d\n", lane, voltage_swing, eq); + + if (voltage_swing > kDPVoltageLevelMax) { + voltage_swing = kDPVoltageLevelMax; + } + + if (eq > kDPEQLevelMax) { + eq = kDPEQLevelMax; + } + + if (lpdp_port_calibration_table_fixed) { + set_lane_adjustment_levels(lane, + lpdp_port_calibration_table[0][0].swing, + lpdp_port_calibration_table[0][0].deemphasis); + } else { + set_lane_adjustment_levels(lane, + lpdp_port_calibration_table[voltage_swing][eq].swing, + lpdp_port_calibration_table[voltage_swing][eq].deemphasis); + } + + if (voltage_max_reached) { + *voltage_max_reached = (voltage_swing == kDPVoltageLevelMax); + } + + if (eq_max_reached) { + *eq_max_reached = (eq == kDPEQLevelMax); + } + + return ret; +} + +void lpdp_phy_reset() +{ + lpdp_phy_impedance_calibration(); +} + +bool lpdp_get_supports_downspread() +{ + return false; +} + +int lpdp_set_downspread(bool value) +{ + //not supported but needs to succeed.. hence noop + return RET_SUCCESS; +} + +int lpdp_get_downspread(void) +{ + //not supported but needs to succeed.. hence noop + return RET_SUCCESS; +} + +int lpdp_phy_get_adjustment_levels(uint32_t lane, uint32_t *voltage_swing, uint32_t *eq) +{ + if (eq) + *eq = lpdp_eq_levels[lane]; + + if (voltage_swing) + *voltage_swing = lpdp_voltage_levels[lane]; + + return RET_SUCCESS; +} + +void lpdp_phy_set_lane_count(const uint32_t lane_count) +{ + // enable active lanes + set_lane_power_controls(0, lane_count, LPDP_PHY_LANE_HI_Z, 0); + + // disable inactive lanes + set_lane_power_controls(lane_count, kMaxLaneCount, LPDP_PHY_LANE_HI_Z, LPDP_PHY_LANE_HI_Z); +} + +#if WITH_DEVICETREE + +#include + +int lpdp_phy_update_device_tree(DTNode *lpdp_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + + if (lpdp_node == NULL) { + return RET_ERROR; + } + propName = "pll_vco_rctrl"; + if (FindProperty(lpdp_node, &propName, &propData, &propSize)) { + if (pll_vco_rctrl == 0) { + ((char **)propData)[0] = "~"; + } else { + ((u_int32_t *)propData)[0] = pll_vco_rctrl; + } + } + +#if WITH_HW_DISPLAY_EDP + // Copy local settings to the DT + propName = "link-calibration-type"; + if ( FindProperty(lpdp_node, &propName, &propData, &propSize) ) { + memset(propData, 0, propSize); + if (lpdp_port_calibration_table_fixed) { + if (propSize < strlen("t700x-fixed") + 1) { + panic("link-calibration-type DT entry too small."); + } + snprintf(propData, propSize, "t700x-fixed"); + } else { + if (propSize < strlen("t700x-training-table") + 1) { + panic("link-calibration-type DT entry too small."); + } + snprintf(propData, propSize, "t700x-training-table"); + } + } else { + panic("Missing DT LPDP Calibration Table Type."); + } + + propName = "link-calibration-data"; + if ( FindProperty(lpdp_node, &propName, &propData, &propSize) ) { + memset(propData, 0, propSize); + uint32_t table_size = (lpdp_port_calibration_table_fixed) ? + sizeof(struct lpdp_port_calibration) : sizeof(struct lpdp_port_calibration) * 16; + if (propSize < table_size) { + panic("link-calibration-data table too small."); + } + bcopy((void *)lpdp_port_calibration_table, propData, table_size); + } else { + panic("Missing DT LPDP Calibration Table Data."); + } +#endif + + return RET_SUCCESS; +} +#endif //WITH_DEVICETREE + +///////////////////////////////////////// +////////// PHY local functions + +static int lpdp_phy_impedance_calibration( void ) +{ + int i; + uint32_t calibration_result = 0; + bool complete; + unsigned int pd, pu; + int result = RET_SUCCESS; + + //start calibration pull down first + rLPDP_PHY_CAL_CTRL |= LPDP_PHY_CAL_CTRL_AUTOZERO_BYP | LPDP_PHY_CAL_CTRL_RST; + + // clear cal_pwrdn + rLPDP_PHY_CAL_CTRL &= ~LPDP_PHY_CAL_CTRL_PWRDN; + + for (i = 0 ; i < kMaxLaneCount; i++) { + set_lane_adjustment_levels(i, LPDP_PHY_LANE_x_VREG_ADJ_MAX, 0); + } + + set_aux_voltage_swing(LPDP_PHY_AUX_CTRL_VREG_ADJ_MAX); + + // Wait at least 1ms + spin( 1000 ); + + // Wait at least 21us + spin( 21 ); + + // Let the pull down calibration start + rLPDP_PHY_CAL_CTRL &= ~LPDP_PHY_CAL_CTRL_RST; + + // Wait for calibration to complete + spin(t_cal_duration_microseconds); + + calibration_result = rLPDP_PHY_CAL_RESULT; + complete = (calibration_result & LPDP_PHY_CAL_RESULT_COMPLETE) != 0; + pd = LPDP_PHY_CAL_RESULT_PD(calibration_result); + pu = LPDP_PHY_CAL_RESULT_PU(calibration_result); + + if (!complete || pd < 6 || pu < 6) + result = RET_ERROR; + + // Set cal_pwrdn to 1 + rLPDP_PHY_CAL_CTRL |= LPDP_PHY_CAL_CTRL_PWRDN; + + return result; +} + +static void set_bias_power_enable(bool enable) +{ + uint32_t rmw = rLPDP_PHY_GEN_CTRL; + rmw &= ~( LPDP_PHY_GEN_CTRL_BIAS_PWRDN); + rmw |= ( enable ? 0 : LPDP_PHY_GEN_CTRL_BIAS_PWRDN); + rLPDP_PHY_GEN_CTRL = rmw; +} + +static void set_aux_power_enable(bool enable) +{ + uint32_t rmw = rLPDP_PHY_AUX_CTRL; + rmw &= ~(LPDP_PHY_AUX_CTRL_PWRDN); + rmw |= ( enable ? 0 : LPDP_PHY_AUX_CTRL_PWRDN); + rLPDP_PHY_AUX_CTRL = rmw; +} + +static void set_lane_power_enable(bool enable) +{ + uint32_t bits = enable ? 0 : LPDP_PHY_LANE_x_FULL_DISABLE; + + // Reference: + // Asg_lpdptx Specification: + // • "Theory of Operations" subsection "Shutdown" + + // Note that LPDP_PHY.GEN_CTRL.lane_pd_ow must be 1 for this to work + set_lane_power_controls(0, kMaxLaneCount, LPDP_PHY_LANE_x_FULL_DISABLE, bits); +} + +static void set_lane_power_controls(unsigned int first, unsigned int limit, uint32_t mask, uint32_t bits) +{ + // Reference: + // Asg_lpdptx Specification: + // • "Theory of Operations" subsection "Lane enable and disable" + + for (unsigned int i = first; i < limit; i++) { + // allow at least 5ns between lane power/enable state changes + spin(1); + + // set power state of lane 'i' + uint32_t rmw = rLPDP_PHY_LANE(i); + rmw &= ~mask; + rmw |= bits; + rLPDP_PHY_LANE(i) = rmw; + } +} + +static bool lpdp_get_pll_is_locked() +{ + return (rLPDP_PLL_LOCK & LPDP_PLL_LOCK_OUT_ON); +} + +static void set_aux_voltage_swing(uint32_t vreg_adj) +{ + uint32_t rmw = rLPDP_PHY_AUX_CTRL; + rmw &= ~LPDP_PHY_AUX_CTRL_VREG_ADJ_MASK; + rmw |= vreg_adj << LPDP_PHY_AUX_CTRL_VREG_ADJ_SHIFT; + rLPDP_PHY_AUX_CTRL = rmw; +} + +static void set_lane_adjustment_levels(unsigned int lane, uint8_t voltage_swing, uint8_t eq) +{ + uint32_t rmw = rLPDP_PHY_LANE(lane); + rmw &= ~(LPDP_PHY_LANE_DE_ENABLE | LPDP_PHY_LANE_x_VREG_ADJ_MASK); + rmw |= (LPDP_PHY_LANE_VREG_ADJ(voltage_swing) | ((eq) ? LPDP_PHY_LANE_DE_ENABLE : 0)); + rLPDP_PHY_LANE(lane) = rmw; + + lpdp_voltage_levels[lane] = voltage_swing; + lpdp_eq_levels[lane] = eq; +} + +//TODO: Get the correct values for gclk_div +static int update_pll_dividers(uint32_t lr) +{ + int ret = 0; + uint32_t fb; + uint32_t pre; + + // determine feedback and pre-divider ratios + switch ( lr ) { + case kLinkRate000Gbps: + fb = pre = 0; + break; + + case kLinkRate162Gbps: + fb = 135; + pre = 4; + break; + + case kLinkRate270Gbps: + fb = 225; + pre = 4; + break; + + case kLinkRate324Gbps: + fb = 135; + pre = 2; + break; + + case kLinkRate540Gbps: // Not supported on Fiji/Capri + fb = 225; + pre = 2; + break; + + default: + debug(ERROR, "unsupported link rate: %u", lr); + ret = -1; + goto exit; + } + + // Set new PLL divider ratios + uint32_t rmw = rLPDP_PLL_IDIV; + rmw &= ~LPDP_PLL_IDIV_FB_MASK; + rmw |= (fb << LPDP_PLL_IDIV_FB_SHIFT); + rmw &= ~LPDP_PLL_IDIV_PRE_MASK; + rmw |= (pre << LPDP_PLL_IDIV_PRE_SHIFT); + rLPDP_PLL_IDIV = rmw; + +exit: + return ret; +} + +static int lpdp_power_pll(bool poweron) +{ + int result = RET_ERROR; + + if ((lpdp_pll_state != lpdp_pll_state_unknown) && (lpdp_pll_state == poweron)) + return RET_SUCCESS; + + lpdp_pll_state = poweron; + if (poweron) + result = lpdp_power_up_pll(); + else + result = lpdp_power_down_pll(); + return result; +} + +static int lpdp_power_down_pll() +{ + rLPDP_PHY_GEN_CTRL |= (LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_SLEEP_SW); + + spin(31); //> 30 ns + + rLPDP_PLL_GEN |= (LPDP_PLL_GEN_PWRDN | LPDP_PLL_GEN_RST); + + return RET_SUCCESS; +} + +static int lpdp_power_up_pll() +{ + // Note: powerDownPll() must be called first + assert(rLPDP_PHY_GEN_CTRL & LPDP_PHY_GEN_CTRL_SEQ_OW); + assert(rLPDP_PHY_GEN_CTRL & LPDP_PHY_GEN_CTRL_SLEEP_SW); + assert(rLPDP_PLL_GEN & LPDP_PLL_GEN_PWRDN); + assert(rLPDP_PLL_GEN & LPDP_PLL_GEN_RST); + + //spin(get_power_down_duration(&lpdp_pll_timing)); + spin(10); + + // de-assert pll_pwrdn after at least 10µS + rLPDP_PLL_GEN &= ~LPDP_PLL_GEN_PWRDN; + + //spin(get_reset_duration(&lpdp_pll_timing)); + spin(100); + + // de-assert pll_reset after at least 100µS + rLPDP_PLL_GEN &= ~LPDP_PLL_GEN_RST; + + //spin(get_reset_to_update_duration(&lpdp_pll_timing)); + spin(5); + + // assert pll_update_divn for at least 1µS + rLPDP_PLL_IDIV |= LPDP_PLL_IDIV_UPDT; + spin(1); + rLPDP_PLL_IDIV &= ~LPDP_PLL_IDIV_UPDT; + + // wait for PLL lock + //spin(get_lock_duration(&lpdp_pll_timing)); + spin(50); + + // check for PLL lock, bail if not locked + if (!lpdp_get_pll_is_locked()) { + printf("failed to lock lpdp pll\n"); + return RET_ERROR; + } + + // Enable clock output after PLL is locked + rLPDP_PLL_CLK &= ~LPDP_PLL_CLK_VCO_BLK_VCLK; + + // de-assert lpdp_sleep + + // Note: The sleep signal is used by the LPDP PHY to gate-off PLL clock; + // see . + rLPDP_PHY_GEN_CTRL &= ~LPDP_PHY_GEN_CTRL_SLEEP_SW; + + // wait at least 1µS for output driver ready + spin(2); + + return RET_SUCCESS; +} + +void lpdp_phy_configure_alpm(bool enable) +{ + + if (enable) { + // Clear Sequencer overwrite and Lane power-down overwrite + rLPDP_PHY_GEN_CTRL &= ~(LPDP_PHY_GEN_CTRL_SLEEP_SW | LPDP_PHY_GEN_CTRL_LANE_PD_OW); + + // Program ALPM PHY Sequence Timers + rLPDP_GEN_SEQ_1 = LPDP_GEN_SEQ_1_START_COUNT(lpdp_pll_timing.start_count); + rLPDP_GEN_SEQ_1 |= LPDP_GEN_SEQ_1_SETUP_COUNT(lpdp_pll_timing.setup_count); + //Hardcodede value to be fixed in Make display_config a void * for future flexibility + rLPDP_GEN_SEQ_2 = 1873; + rLPDP_GEN_SEQ_3 = lpdp_pll_timing.reset_count; + rLPDP_GEN_SEQ_4 = LPDP_GEN_SEQ_4_FINISH_COUNT(lpdp_pll_timing.finish_count); + rLPDP_GEN_SEQ_4 |= LPDP_GEN_SEQ_4_UPDATE_COUNT(lpdp_pll_timing.update_count); + } +} + +// convenience methods for conversion to µs (for software use) + +static unsigned int micro_seconds_for_count(struct pll_timing *tm, unsigned int count) { + // Note: Normally, ref_mhz == ref_div, but it is not assumed. + // Values are rounded up. + return ((count * tm->ref_div) + tm->ref_mhz - 1) / tm->ref_mhz; +} + +static unsigned int get_sleep_to_power_down_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->start_count); +} + +static unsigned int get_power_down_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->pwrdn_count); +} + +static unsigned int get_reset_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->reset_count); +} + +static unsigned int get_reset_to_update_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->update_count); +} + +static unsigned int get_lock_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->finish_count); +} diff --git a/drivers/apple/lpdp_phy/lpdp_v2.c b/drivers/apple/lpdp_phy/lpdp_v2.c new file mode 100644 index 0000000..4a3040e --- /dev/null +++ b/drivers/apple/lpdp_phy/lpdp_v2.c @@ -0,0 +1,996 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "regs_v2.h" + +#if WITH_DEVICETREE +#include +#endif + +///////////////////////////////////////// +////////// debug support + +#define LPDP_DEBUG_MASK ( \ + LPDP_DEBUG_INIT | \ + LPDP_DEBUG_ERROR | \ + LPDP_DEBUG_INFO | \ + LPDP_DEBUG_PLL | \ + LPDP_DEBUG_PHY | \ + 0) + +#undef LPDP_DEBUG_MASK +#define LPDP_DEBUG_MASK (LPDP_DEBUG_INIT | LPDP_DEBUG_ERROR) + +#define LPDP_DEBUG_INIT (1<<16) // initialisation +#define LPDP_DEBUG_ERROR (1<<17) // errors +#define LPDP_DEBUG_INFO (1<<18) // info +#define LPDP_DEBUG_PLL (1<<24) // PLL +#define LPDP_DEBUG_PHY (1<<25) // PLL +#define LPDP_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((LPDP_DEBUG_ ## _fac) & (LPDP_DEBUG_MASK | LPDP_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "DP: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +#define kMaxLaneCount 4 +#define kLinkRatePhysical_162gbpsi 1620000000ULL +#define kLinkRatePhysical_270gps 2700000000ULL + +//ERRORS +#define RET_SUCCESS 0 +#define RET_ERROR -1 + +#ifndef LPDP_PHY_VERSION +#error LPDP_PHY_VERSION undefined +#endif + +#ifndef LPDP_LINK_CAL_TABLE_VERSION +#error LPDP_LINK_CAL_TABLE_VERSION undefined +#endif + +///////////////////////////////////////// +////////// typedefs, enums, structs + +enum { + kDPAuxTranscationStatus_None = -1, + kDPAuxTranscationStatus_Success, + kDPAuxTranscationStatus_IODefer, + kDPAuxTranscationStatus_IOError, + kDPAuxTranscationStatus_OtherError +}; + +enum { + kBaseVoltageType_Neg_120mV, + kBaseVoltageType_Neg_80mV, + kBaseVoltageType_Neg_40mV, + kBaseVoltageType_Pos_0mV, + kBaseVoltageType_Pos_40mV, + kBaseVoltageType_Pos_80mV, + kBaseVoltageType_Pos_120mV, + kBaseVoltageType_Pos_160mV +}; + +/* + Device tree calibration data formats: + + link-calibration-type: t700x-fixed + link-calibration-data: ${ VS DE } + + link-calibration-type: t700x-training-table + link-calibration-data: ${ VS DE VS DE VS DE VS DE } // voltage swing level 0, pre-emphasis levels 0~3 + link-calibration-data: ${ VS DE VS DE VS DE 00 00 } // voltage swing level 1, pre-emphasis levels 0~3 + link-calibration-data: ${ VS DE VS DE 00 00 00 00 } // voltage swing level 2, pre-emphasis levels 0~3 + link-calibration-data: ${ VS DE 00 00 00 00 00 00 } // voltage swing level 3, pre-emphasis level 0~3 + + link-calibration-type: s800x-fixed + link-calibration-data: $VS $R + + link-calibration-type: s800x-training-table + link-calibration-data: $VS $R $VS $R $VS $R $VS $R // voltage swing level 0, pre-emphasis levels 0~3 + link-calibration-data: $VS $R $VS $R $VS $R $00 $00 // voltage swing level 1, pre-emphasis levels 0~3 + link-calibration-data: $VS $R $VS $R $00 $00 $00 $00 // voltage swing level 2, pre-emphasis levels 0~3 + link-calibration-data: $VS $R $00 $00 $00 $00 $00 $00 // voltage swing level 3, pre-emphasis level 0~3 +*/ + +#if LPDP_LINK_CAL_TABLE_VERSION < 2 +struct lpdp_port_calibration { + uint8_t swing; + uint8_t deemphasis; +} __attribute__((packed)); + +static const char *training_table_text = "t700x-training-table"; +static const char *fixed_text = "t700x-fixed"; +#else +struct lpdp_port_calibration { + uint32_t swing; + uint32_t r; +} __attribute__((packed)); + +static const char *training_table_text = "s800x-training-table"; +static const char *fixed_text = "s800x-fixed"; +#endif + +#if WITH_HW_DISPLAY_EDP +#include + +#ifndef LPDP_PORT_CALIBRATION_TABLE_FIXED +#error LPDP_PORT_CALIBRATION_TABLE_FIXED not defined +#endif + +#else +static struct lpdp_port_calibration lpdp_port_calibration_table[kDPVoltageLevelMax+1][kDPEQLevelMax+1]; +#endif + +struct pll_timing { + // reference clock frequency in MHz + unsigned int ref_mhz; + + // sequencer configuration + unsigned int ref_div : 5; // sequencer divisor + unsigned int setup_count : 8; // sequencer ticks + unsigned int start_count : 8; // sequencer ticks + unsigned int pwrdn_count : 14; // sequencer ticks + unsigned int reset_count : 8; // sequencer ticks + unsigned int update_count : 8; // sequencer ticks + unsigned int finish_count : 8; // sequencer ticks + unsigned int wakeup_count : 8; // sequencer ticks + unsigned int hold_count : 8; // sequencer ticks +}; + +typedef enum { + lpdp_pll_state_off = 0, + lpdp_pll_state_on = 1, + lpdp_pll_state_unknown = 2, +} lpdp_pll_state_t; + +///////////////////////////////////////// +////////// PHY local variables +static addr_t __base_address = LPDP_PHY_BASE_ADDR; +static uint32_t _linkRate; +static bool lpdp_pll_state = true; +static uint32_t lpdp_voltage_levels[kMaxLaneCount]; +static uint32_t lpdp_voltage_base[kMaxLaneCount]; +static uint32_t lpdp_eq_levels[kMaxLaneCount]; +static uint32_t lpdp_voltage_levels[kMaxLaneCount]; +static bool lpdp_port_calibration_table_fixed; +static uint32_t pll_vco_rctrl; +static struct pll_timing lpdp_pll_timing; +static uint32_t t_cal_duration_microseconds; + +///////////////////////////////////////// +////////// PHY local functions +static void set_bias_power_enable(bool enable); +static void set_aux_power_enable(bool enable); +static void set_lane_power_controls(unsigned int first, unsigned int limit, uint32_t mask, uint32_t bits); +static void set_lane_power_enable(bool enable); +static bool lpdp_get_pll_is_locked(); +static void set_aux_voltage_swing(uint32_t vreg_adj); +#if LPDP_PHY_VERSION < 2 +static void set_phy_configure_ldos(uint32_t ldopre_vreg_adj, uint32_t ldoclk_vreg_adj, uint32_t auxvreg_adj); +#endif +static void enable_phy_ldos(); +#if LPDP_LINK_CAL_TABLE_VERSION < 2 +static void set_lane_adjustment_levels(unsigned int lane, uint8_t vreg_adj, uint8_t eq); +#else +static void set_lane_adjustment_levels(unsigned int lane, uint32_t vreg_adj, uint32_t r); +#endif +static int update_pll_dividers(uint32_t lr); +static int lpdp_power_pll(bool poweron); +static int lpdp_power_down_pll(); +static int lpdp_power_up_pll(); +static int lpdp_phy_impedance_calibration(void); +static unsigned int micro_seconds_for_count(struct pll_timing *tm, unsigned int count); +static unsigned int get_sleep_to_power_down_duration(struct pll_timing *tm); +static unsigned int get_power_down_duration(struct pll_timing *tm); +static unsigned int get_reset_duration(struct pll_timing *tm); +static unsigned int get_reset_to_update_duration(struct pll_timing *tm); +static unsigned int get_lock_duration(struct pll_timing *tm); +static uint32_t read_reg(uint32_t offset); +static void write_reg(uint32_t offset, uint32_t val); +static void and_reg(uint32_t offset, uint32_t val); +static void or_reg(uint32_t offset, uint32_t val); +static void set_bits_in_reg(uint32_t offset, uint32_t pos, uint32_t mask, uint32_t value); + +///////////////////////////////////////// +////////// PHY global functions + +int lpdp_init(const char *dt_path) +{ + int i; + + for (i = 0; i < kMaxLaneCount; i++) + lpdp_voltage_base[i] = kBaseVoltageType_Pos_0mV; + + t_cal_duration_microseconds = 1000; // 1ms + + lpdp_pll_state = lpdp_pll_state_unknown; + + // Note: 200uS is the worst-case from pll_pwrdn to PLL locked under all + // conditions and settings per . + // The period from pll_pwrdn to PLL locked is: + // reset_count + update_count + finish_count + + lpdp_pll_timing.ref_mhz = 24; + lpdp_pll_timing.ref_div = 24; // ref clock ticks per (1µs) sequencer tick + lpdp_pll_timing.setup_count = 4; // µs + lpdp_pll_timing.start_count = 1; // µs + lpdp_pll_timing.pwrdn_count = 10; // µs + lpdp_pll_timing.reset_count = 100; // µs + lpdp_pll_timing.update_count = 5; // µs + lpdp_pll_timing.finish_count = 50; // µs + +#if WITH_HW_DISPLAY_EDP + lpdp_port_calibration_table_fixed = LPDP_PORT_CALIBRATION_TABLE_FIXED; +#else +#if WITH_DEVICETREE + DTNodePtr node; + char * prop_name; + void * prop_data; + uint32_t prop_size; + + // Copy DT settings in to local copy + if ( FindNode(0, dt_path, &node) ) { + + prop_name = "link-calibration-type"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + if (strcmp(training_table_text, prop_data) == 0) { + lpdp_port_calibration_table_fixed = false; + } else if (strcmp(fixed_text, prop_data) == 0) { + lpdp_port_calibration_table_fixed = true; + } else { + panic("Unknown DT LPDP Calibration Table Type."); + } + } else { + panic("Missing DT LPDP Calibration Table Type."); + } + + // gather calibration data from DeviceTree + prop_name = "link-calibration-data"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + uint32_t table_size = (lpdp_port_calibration_table_fixed) ? + sizeof(struct lpdp_port_calibration) : sizeof(struct lpdp_port_calibration) * 16; + if ( prop_size != table_size ) { + debug(ERROR, "calibration-data size mismatch, expected:%d, read:%d \n", + table_size, prop_size); + return -1; + } + + bcopy(prop_data, (void *)lpdp_port_calibration_table, prop_size); + } else { + panic("Missing DT LPDP Calibration Table Data."); + } + } else +#endif + + { + debug(ERROR, "Missing DT LPDP Calibration Table. Using Defaults\n"); + lpdp_port_calibration_table_fixed = true; +#if LPDP_LINK_CAL_TABLE_VERSION < 2 + lpdp_port_calibration_table[0][0].swing = LPDP_PHY_LANE_x_VREG_ADJ_MAX; + lpdp_port_calibration_table[0][0].deemphasis = 0; +#else + lpdp_port_calibration_table[0][0].swing = LPDP_PHY_LANE_x_VREG_ADJ_MAX; + lpdp_port_calibration_table[0][0].r = 0; +#endif + } +#endif + + //the block should had been properly reset. validating such assumption + assert(read_reg(rLPDP_PHY_GEN_CTRL) & (LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_LANE_PD_OW)); + assert(read_reg(rLPDP_PLL_GEN) & LPDP_PLL_GEN_RST); + + //extract Configuration of PLL + //PMGR should have programmed correctly + //we save the value to pass to the OS. + pll_vco_rctrl = read_reg(rLPDP_PLL_CLK); + if (pll_vco_rctrl & LPDP_PLL_CLK_VCO_RCTRL_SEL_ENABLE) + pll_vco_rctrl = ((pll_vco_rctrl >> LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT) & LPDP_PLL_CLK_VCO_RCTRL_OW_MASK); + else + pll_vco_rctrl = 0; + + return RET_SUCCESS; +} + +int lpdp_initialize_phy_and_pll(void) +{ + int ret = RET_SUCCESS; + int i; + + // ensure lane_pd_ow=1 (default) to allow software control of lane power + or_reg(rLPDP_PHY_GEN_CTRL, (LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_SLEEP_SW )); + +#if LPDP_PHY_VERSION < 2 + for (i = 0 ; i < kMaxLaneCount; i++) { + set_lane_adjustment_levels(i, LPDP_PHY_LANE_VREG_ADJ_420_mV, 0); + } + + //TODO!! + set_aux_voltage_swing(0xA); + + set_phy_configure_ldos(0x4, 0x4, 0x3); +#elif LPDP_PHY_VERSION == 2 + for (i = 0 ; i < kMaxLaneCount; i++) { + set_lane_adjustment_levels(i, LPDP_PHY_LANE_VREG_ADJ_450_mV, 0); + } + + //TODO!! + set_aux_voltage_swing(0x6); +#endif + + //reset calibration + write_reg(rLPDP_PHY_CAL, 0); + +#if LPDP_PHY_VERSION < 2 + write_reg(rLPDP_PHY_RESERVED, (1 << 4)); +#endif + + write_reg(rLPDP_PHY_CLK_CTRL, LPDP_PHY_CLK_CTRL_CLK_ENABLE | LPDP_PHY_CLK_CTRL_CLKDIV5_RESET); + + or_reg(rLPDP_PHY_GEN_CTRL, LPDP_PHY_GEN_CTRL_LANE_PD_OW); + + set_bias_power_enable(true); + + // power up all lanes + set_lane_power_enable(true); + + enable_phy_ldos(); + + set_aux_power_enable(true); + +#if LPDP_PHY_VERSION < 2 + and_reg(rLPDP_PHY_BIST, ~LPDP_PHY_BIST_LOOPBACK_SRC_SEL(LPDP_PHY_BIST_LOOPBACK_SRC_SEL_MASK)); +#endif + + spin(1000); //1 ms + spin(10); //10 us + + write_reg(rLPDP_PHY_CAL, LPDP_PHY_CAL_RESET_N); +#if LPDP_PHY_VERSION < 2 + and_reg(rLPDP_PHY_RESERVED, ~(1 << 4)); +#endif + and_reg(rLPDP_PHY_CLK_CTRL, ~LPDP_PHY_CLK_CTRL_CLKDIV5_RESET); + + spin(10); //10 us + + // perform PHY impedance calibration + ret = lpdp_phy_impedance_calibration(); + + // panic if impedance calibration procedure failed + if ( ret != 0 ) { + panic("lpdp impedance calibration failed\n"); + } + + set_lane_power_controls(0, kMaxLaneCount, LPDP_PHY_LANE_HI_Z, 0); + + //configure PLL to an initial value + lpdp_set_link_rate(kLinkRate162Gbps); + +#if LPDP_PHY_VERSION < 2 + write_reg(rLPDP_GEN_DISPLAY_SPLIT, 0); +#endif + + return ret; +} + +void lpdp_init_finalize(void) +{ + //remove the overrides + and_reg(rLPDP_PHY_GEN_CTRL, ~(LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_LANE_PD_OW)); +} + +void lpdp_quiesce() +{ + // power down all lanes [LANE_x.hi_z=1, LANE_x.ldo_pwrdn=1, LANE_x.pwrdn=1] + set_lane_power_enable(false); + + // power down AUX channel [AUX_CTRL.pwrdn=1] + set_aux_power_enable(false); + + // power down PHY's central bias [GEN_CTRL.bias_pwrdn=1] + set_bias_power_enable(false); + + // assert lpdp_sleep, pll_pwrdn, and pll_reset + lpdp_power_pll(false); + +} + +int lpdp_set_link_rate(uint32_t lr) +{ + int ret = 0; + + debug(PHY, "Setting link rate to 0x%02x\n", (uint8_t)lr); + +#if LPDP_PHY_VERSION == 2 + // Bug Fix for Default Register Value of asg_adppll Calibration Reset + or_reg(rLPDP_PLL_FCAL, LPDP_PLL_FCAL_RESET); +#endif + // Block clock output during PLL setup + or_reg(rLPDP_PLL_CLK, LPDP_PLL_CLK_VCO_BLK_VCLK); + + // assert lpdp_sleep, pll_pwrdn, and pll_reset + lpdp_power_pll(false); + + // initialize link rate to 0 + _linkRate = kLinkRate000Gbps; + + // if the target link rate is nonzero, reconfigure and power up the PLL + if ( lr > kLinkRate000Gbps ) { + + // update PLL dividers for new link rate + if (update_pll_dividers(lr)) { + ret = -1; + goto exit; + } + + // power up PLL and wait for lock, + // if this fails, power it back down and leave link rate at 0 + if (lpdp_power_pll(true)) { + ret = -1; + lpdp_power_pll(false); + goto exit; + } + + // finally, update the current link rate + _linkRate = lr; + } + +exit: + return ret; +} + +int lpdp_get_link_rate(uint32_t *link_rate) +{ + *link_rate = _linkRate; + return RET_SUCCESS; +} + +int lpdp_phy_set_adjustment_levels(uint32_t lane, uint32_t voltage_swing, uint32_t eq, + bool *voltage_max_reached, bool *eq_max_reached) +{ + int ret = 0; + + if ( lane > kMaxLaneCount ) + return -1; + + debug(PHY, "lane=%d voltage=%d eq=%d\n", lane, voltage_swing, eq); + + if (voltage_swing > kDPVoltageLevelMax) { + voltage_swing = kDPVoltageLevelMax; + } + + if (eq > kDPEQLevelMax) { + eq = kDPEQLevelMax; + } + + if (lpdp_port_calibration_table_fixed) { +#if LPDP_LINK_CAL_TABLE_VERSION < 2 + set_lane_adjustment_levels(lane, + lpdp_port_calibration_table[0][0].swing, + lpdp_port_calibration_table[0][0].deemphasis); +#else + set_lane_adjustment_levels(lane, + lpdp_port_calibration_table[0][0].swing, + lpdp_port_calibration_table[0][0].r); +#endif + } else { +#if LPDP_LINK_CAL_TABLE_VERSION < 2 + set_lane_adjustment_levels(lane, + lpdp_port_calibration_table[voltage_swing][eq].swing, + lpdp_port_calibration_table[voltage_swing][eq].deemphasis); +#else + set_lane_adjustment_levels(lane, + lpdp_port_calibration_table[voltage_swing][eq].swing, + lpdp_port_calibration_table[voltage_swing][eq].r); +#endif + } + + if (voltage_max_reached) { + *voltage_max_reached = (voltage_swing == kDPVoltageLevelMax); + } + + if (eq_max_reached) { + *eq_max_reached = (eq == kDPEQLevelMax); + } + + return ret; +} + +void lpdp_phy_reset() +{ + lpdp_phy_impedance_calibration(); +} + +bool lpdp_get_supports_downspread() +{ + return false; +} + +int lpdp_set_downspread(bool value) +{ + //not supported but needs to succeed.. hence noop + return RET_SUCCESS; +} + +int lpdp_get_downspread(void) +{ + //not supported but needs to succeed.. hence noop + return RET_SUCCESS; +} + +int lpdp_phy_get_adjustment_levels(uint32_t lane, uint32_t *voltage_swing, uint32_t *eq) +{ + if (eq) + *eq = lpdp_eq_levels[lane]; + + if (voltage_swing) + *voltage_swing = lpdp_voltage_levels[lane]; + + return RET_SUCCESS; +} + +void lpdp_phy_set_lane_count(const uint32_t lane_count) +{ + // enable active lanes + set_lane_power_controls(0, lane_count, LPDP_PHY_LANE_HI_Z, 0); + + // disable inactive lanes + set_lane_power_controls(lane_count, kMaxLaneCount, LPDP_PHY_LANE_HI_Z, LPDP_PHY_LANE_HI_Z); +} + +#if WITH_DEVICETREE + +#include + +int lpdp_phy_update_device_tree(DTNode *lpdp_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + + if (lpdp_node == NULL) { + return RET_ERROR; + } + propName = "pll_vco_rctrl"; + if (FindProperty(lpdp_node, &propName, &propData, &propSize)) { + if (pll_vco_rctrl == 0) { + ((char **)propData)[0] = "~"; + } else { + ((u_int32_t *)propData)[0] = pll_vco_rctrl; + } + } + +#if WITH_HW_DISPLAY_EDP + // Copy local settings to the DT + propName = "link-calibration-type"; + if ( FindProperty(lpdp_node, &propName, &propData, &propSize) ) { + memset(propData, 0, propSize); + if (lpdp_port_calibration_table_fixed) { + if (propSize < strlen(fixed_text) + 1) { + panic("link-calibration-type DT entry too small."); + } + snprintf(propData, propSize, "%s", fixed_text); + } else { + if (propSize < strlen(training_table_text) + 1) { + panic("link-calibration-type DT entry too small."); + } + snprintf(propData, propSize, "%s", training_table_text); + } + } else { + panic("Missing DT LPDP Calibration Table Type."); + } + + propName = "link-calibration-data"; + if ( FindProperty(lpdp_node, &propName, &propData, &propSize) ) { + memset(propData, 0, propSize); + uint32_t table_size = (lpdp_port_calibration_table_fixed) ? + sizeof(struct lpdp_port_calibration) : sizeof(struct lpdp_port_calibration) * 16; + if (propSize < table_size) { + panic("link-calibration-data table too small."); + } + bcopy((void *)lpdp_port_calibration_table, propData, table_size); + } else { + panic("Missing DT LPDP Calibration Table Data."); + } +#endif + + return RET_SUCCESS; +} +#endif //WITH_DEVICETREE + +///////////////////////////////////////// +////////// PHY local functions + +static int lpdp_phy_impedance_calibration( void ) +{ + int result = RET_SUCCESS; + uint32_t reg; + + // Let the pull down calibration start + or_reg(rLPDP_PHY_CAL, LPDP_PHY_CAL_START); + + // Wait for calibration to complete + spin(t_cal_duration_microseconds); + + reg = read_reg(rLPDP_PHY_CAL); + if (!(reg & LPDP_PHY_CAL_DONE) || (reg & LPDP_PHY_CAL_FAIL)) { + printf("impedance Calibration failed rLPDP_PHY_CAL 0x%x\n", reg); + result = RET_ERROR; + } + + spin(1); + + and_reg(rLPDP_PHY_CAL, ~LPDP_PHY_CAL_START); + + return result; +} + +static void set_bias_power_enable(bool enable) +{ + uint32_t rmw = read_reg(rLPDP_PHY_GEN_CTRL); + rmw &= ~( LPDP_PHY_GEN_CTRL_BIAS_PWRDN); + rmw |= ( enable ? 0 : LPDP_PHY_GEN_CTRL_BIAS_PWRDN); + write_reg(rLPDP_PHY_GEN_CTRL, rmw); +} + +static void set_aux_power_enable(bool enable) +{ + uint32_t rmw = read_reg(rLPDP_PHY_AUX_CTRL); + rmw &= ~(LPDP_PHY_AUX_CTRL_PWRDN); + rmw |= ( enable ? 0 : LPDP_PHY_AUX_CTRL_PWRDN); + write_reg(rLPDP_PHY_AUX_CTRL, rmw); +} + +static void set_lane_power_enable(bool enable) +{ + uint32_t bits = enable ? 0 : LPDP_PHY_LANE_x_FULL_DISABLE; + + set_lane_power_controls(0, kMaxLaneCount, LPDP_PHY_LANE_x_FULL_DISABLE, bits); +} + +static void set_lane_power_controls(unsigned int first, unsigned int limit, uint32_t mask, uint32_t bits) +{ + for (unsigned int i = first; i < limit; i++) { + // allow at least 5ns between lane power/enable state changes + spin(1); + + // set power state of lane 'i' + uint32_t rmw = read_reg(rLPDP_PHY_LANE(i)); + rmw &= ~mask; + rmw |= bits; + write_reg(rLPDP_PHY_LANE(i), rmw); + } +} + +static bool lpdp_get_pll_is_locked() +{ + return (read_reg(rLPDP_PLL_LOCK) & LPDP_PLL_LOCK_OUT_ON); +} + +#if LPDP_PHY_VERSION < 2 +static void set_phy_configure_ldos(uint32_t ldopre_vreg_adj, uint32_t ldoclk_vreg_adj, uint32_t auxvreg_adj) +{ + uint32_t reg; + + reg = read_reg(rLPDP_PHY_PRE_LDO_CTRL); + reg &= ~(LPDP_PHY_PRE_LDO_CTR_LDOPRE_VREG_ADJ(0xf)); + reg |= LPDP_PHY_PRE_LDO_CTR_LDOPRE_VREG_ADJ(ldopre_vreg_adj); + write_reg(rLPDP_PHY_PRE_LDO_CTRL, reg); + + reg = read_reg(rLPDP_PHY_CLK_LDO_CTRL); + reg &= ~LPDP_PHY_CLK_LDO_CTRL_LDOCLK_VREG_ADJ(0xf); + reg |= LPDP_PHY_CLK_LDO_CTRL_LDOCLK_VREG_ADJ(ldoclk_vreg_adj); + write_reg(rLPDP_PHY_CLK_LDO_CTRL, reg); + + reg = read_reg(rLPDP_PHY_AUX_LDO_CTRL); + reg &= ~LPDP_PHY_AUX_LDO_CTRL_AUXVREG_ADJ(0xf); + reg |= LPDP_PHY_AUX_LDO_CTRL_AUXVREG_ADJ(auxvreg_adj); + write_reg(rLPDP_PHY_AUX_LDO_CTRL, reg); +} +#endif + +static void enable_phy_ldos() +{ +#if LPDP_PHY_VERSION < 2 + and_reg(rLPDP_PHY_CLK_LDO_CTRL, ~LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN(LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN_MAX)); + and_reg(rLPDP_PHY_PRE_LDO_CTRL, ~LPDP_PHY_PRE_LDO_CTR_LDOPRE_PWRDN(LPDP_PHY_PRE_LDO_CTR_LDOPRE_PWRDN_MAX)); + and_reg(rLPDP_PHY_AUX_LDO_CTRL, ~LPDP_PHY_AUX_LDO_CTRL_AUXLDO_PWRDN); +#elif LPDP_PHY_VERSION == 2 + and_reg(rLPDP_PHY_CLK_LDO_CTRL, ~(LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN_SML(LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN_SML_MAX)| + LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN(LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN_MAX))); + and_reg(rLPDP_PHY_AUX_LDO_CTRL, ~(LPDP_PHY_AUX_LDO_CTRL_LDOPOST_PWRDN_SML|LPDP_PHY_AUX_LDO_CTRL_LDOCLK_PWRDN_SML| + LPDP_PHY_AUX_LDO_CTRL_LDOPOST_PWRDN_BIG|LPDP_PHY_AUX_LDO_CTRL_LDOCLK_PWRDN_BIG)); +#endif +} + +static void set_aux_voltage_swing(uint32_t vreg_adj) +{ + uint32_t rmw = read_reg(rLPDP_PHY_AUX_CTRL); + rmw &= ~LPDP_PHY_AUX_CTRL_VREG_ADJ_MASK; + rmw |= vreg_adj << LPDP_PHY_AUX_CTRL_VREG_ADJ_SHIFT; + write_reg(rLPDP_PHY_AUX_CTRL, rmw); +} + + +#if LPDP_LINK_CAL_TABLE_VERSION < 2 +static void set_lane_adjustment_levels(unsigned int lane, uint8_t voltage_swing, uint8_t eq) +#else +static void set_lane_adjustment_levels(unsigned int lane, uint32_t voltage_swing, uint32_t r) +#endif +{ + uint32_t rmw = read_reg(rLPDP_PHY_LANE(lane)); + rmw &= ~(LPDP_PHY_LANE_x_VREG_ADJ_MASK); + rmw |= LPDP_PHY_LANE_VREG_ADJ(voltage_swing); + write_reg(rLPDP_PHY_LANE(lane), rmw); + + lpdp_voltage_levels[lane] = voltage_swing; +#if LPDP_LINK_CAL_TABLE_VERSION < 2 + lpdp_eq_levels[lane] = eq; +#else +#if LPDP_LINK_CAL_TABLE_VERSION < 3 + // Maui + lpdp_eq_levels[lane] = (((((rLPDP_PHY_CAL_TX & LPDP_PHY_CAL_TX_CODE_FSM_MASK) >> LPDP_PHY_CAL_TX_CODE_FSM_SHIFT) * r) / 2) + (1 << 15)) >> 16; +#else + // Elba/Malta + + lpdp_eq_levels[lane] = ((((((rLPDP_PHY_CAL_TX & LPDP_PHY_CAL_TX_CODE_FSM_MASK) >> LPDP_PHY_CAL_TX_CODE_FSM_SHIFT) + 24) * r) / 2) + (1 << 15)) >> 16; +#endif +#endif +} + +//TODO: Get the correct values for gclk_div +static int update_pll_dividers(uint32_t lr) +{ + int ret = 0; + uint32_t fb; + uint32_t pre; + + // determine feedback and pre-divider ratios + switch ( lr ) { + case kLinkRate000Gbps: + fb = pre = 0; + break; + + case kLinkRate162Gbps: + fb = 135; + pre = 4; + break; + + case kLinkRate270Gbps: + fb = 225; + pre = 4; + break; + + case kLinkRate324Gbps: + fb = 135; + pre = 2; + break; + + case kLinkRate540Gbps: // Not supported on Fiji/Capri + fb = 225; + pre = 2; + break; + + default: + debug(ERROR, "unsupported link rate: %u", lr); + ret = -1; + goto exit; + } + + // Set new PLL divider ratios + uint32_t rmw = read_reg(rLPDP_PLL_IDIV); + rmw &= ~LPDP_PLL_IDIV_FB_MASK; + rmw |= (fb << LPDP_PLL_IDIV_FB_SHIFT); + rmw &= ~LPDP_PLL_IDIV_PRE_MASK; + rmw |= (pre << LPDP_PLL_IDIV_PRE_SHIFT); + write_reg(rLPDP_PLL_IDIV, rmw); + and_reg(rLPDP_PLL_GEN, ~(LPDP_PLL_GEN_GCLK_DIV(LPDP_PLL_GEN_GCLK_DIV_MASK))); + +exit: + return ret; +} + +static int lpdp_power_pll(bool poweron) +{ + int result = RET_ERROR; + + if ((lpdp_pll_state != lpdp_pll_state_unknown) && (lpdp_pll_state == poweron)) + return RET_SUCCESS; + + lpdp_pll_state = poweron; + if (poweron) + result = lpdp_power_up_pll(); + else + result = lpdp_power_down_pll(); + return result; +} + +static int lpdp_power_down_pll() +{ + or_reg(rLPDP_PHY_GEN_CTRL, (LPDP_PHY_GEN_CTRL_SEQ_OW | LPDP_PHY_GEN_CTRL_SLEEP_SW)); + + spin(31); //> 30 ns + + // de-assert pll_pwrdn after at least 10µS + and_reg(rLPDP_PLL_GEN, ~LPDP_PLL_GEN_PWRDN); + + //spin(get_reset_duration(&lpdp_pll_timing)); + spin(100); + + or_reg(rLPDP_PLL_CLK, LPDP_PLL_CLK_VCO_BLK_VCLK); + // de-assert pll_reset after at least 100µS + and_reg(rLPDP_PLL_GEN, ~LPDP_PLL_GEN_RST); + or_reg(rLPDP_PLL_GEN, (LPDP_PLL_GEN_PWRDN | LPDP_PLL_GEN_RST)); + + return RET_SUCCESS; +} + +static int lpdp_power_up_pll() +{ + // Note: powerDownPll() must be called first + assert(read_reg(rLPDP_PHY_GEN_CTRL & LPDP_PHY_GEN_CTRL_SEQ_OW)); + assert(read_reg(rLPDP_PHY_GEN_CTRL & LPDP_PHY_GEN_CTRL_SLEEP_SW)); + assert(read_reg(rLPDP_PLL_GEN & LPDP_PLL_GEN_PWRDN)); + assert(read_reg(rLPDP_PLL_GEN & LPDP_PLL_GEN_RST)); + + //spin(get_power_down_duration(&lpdp_pll_timing)); + spin(10); + + // de-assert pll_pwrdn after at least 10µS + and_reg(rLPDP_PLL_GEN, ~LPDP_PLL_GEN_PWRDN); + + //spin(get_reset_duration(&lpdp_pll_timing)); + spin(100); + + // de-assert pll_reset after at least 100µS + and_reg(rLPDP_PLL_GEN, ~LPDP_PLL_GEN_RST); + + //spin(get_reset_to_update_duration(&lpdp_pll_timing)); + spin(5); + + // assert pll_update_divn for at least 1µS + or_reg(rLPDP_PLL_IDIV, LPDP_PLL_IDIV_UPDT); + spin(1); + and_reg(rLPDP_PLL_IDIV, ~LPDP_PLL_IDIV_UPDT); + + // wait for PLL lock + //spin(get_lock_duration(&lpdp_pll_timing)); + spin(50); + + // check for PLL lock, bail if not locked + if (!lpdp_get_pll_is_locked()) { + printf("failed to lock lpdp pll\n"); + return RET_ERROR; + } + + // Enable clock output after PLL is locked + and_reg(rLPDP_PLL_CLK, ~LPDP_PLL_CLK_VCO_BLK_VCLK); + + // de-assert lpdp_sleep + + // Note: The sleep signal is used by the LPDP PHY to gate-off PLL clock; + // see . + and_reg(rLPDP_PHY_GEN_CTRL, ~LPDP_PHY_GEN_CTRL_SLEEP_SW); + + // wait at least 1µS for output driver ready + spin(2); + + or_reg(rLPDP_PLL_GEN, LPDP_PLL_GEN_CLKDIV2_RESET_N); + + return RET_SUCCESS; +} + +void lpdp_phy_configure_alpm(bool enable) +{ + + if (enable) { + // Clear Sequencer overwrite and Lane power-down overwrite + and_reg(rLPDP_PHY_GEN_CTRL, ~(LPDP_PHY_GEN_CTRL_SLEEP_SW | LPDP_PHY_GEN_CTRL_LANE_PD_OW)); + + // Program ALPM PHY Sequence Timers + write_reg(rLPDP_GEN_SEQ_1, LPDP_GEN_SEQ_1_START_COUNT(lpdp_pll_timing.start_count)); + or_reg(rLPDP_GEN_SEQ_1, LPDP_GEN_SEQ_1_SETUP_COUNT(lpdp_pll_timing.setup_count)); + //Hardcodede value to be fixed in Make display_config a void * for future flexibility + write_reg(rLPDP_GEN_SEQ_2, 1873); + write_reg(rLPDP_GEN_SEQ_3, lpdp_pll_timing.reset_count); + write_reg(rLPDP_GEN_SEQ_4, LPDP_GEN_SEQ_4_HOLD_COUNT(lpdp_pll_timing.hold_count)); + write_reg(rLPDP_GEN_SEQ_5, LPDP_GEN_SEQ_5_FINISH_COUNT(lpdp_pll_timing.finish_count)); + or_reg(rLPDP_GEN_SEQ_4, LPDP_GEN_SEQ_4_UPDATE_COUNT(lpdp_pll_timing.update_count)); + write_reg(rLPDP_GEN_SEQ_5, LPDP_GEN_SEQ_5_WAKEUP_COUNT(lpdp_pll_timing.wakeup_count)); + } + +} + +// convenience methods for conversion to µs (for software use) + +static unsigned int micro_seconds_for_count(struct pll_timing *tm, unsigned int count) { + // Note: Normally, ref_mhz == ref_div, but it is not assumed. + // Values are rounded up. + return ((count * tm->ref_div) + tm->ref_mhz - 1) / tm->ref_mhz; +} + +static unsigned int get_sleep_to_power_down_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->start_count); +} + +static unsigned int get_power_down_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->pwrdn_count); +} + +static unsigned int get_reset_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->reset_count); +} + +static unsigned int get_reset_to_update_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->update_count); +} + +static unsigned int get_lock_duration(struct pll_timing *tm) { + return micro_seconds_for_count(tm, tm->finish_count); +} + +static uint32_t read_reg(uint32_t offset) +{ + volatile uint32_t reg; + + reg = (*(volatile uint32_t *)(__base_address + offset)); + return reg; +} + +static void write_reg(uint32_t offset, uint32_t value) +{ + *(volatile uint32_t *)(__base_address + offset) = value; +} + +static void and_reg(uint32_t offset, uint32_t value) +{ + uint32_t reg; + reg = read_reg(offset); + reg &= value; + write_reg(offset, reg); +} + +static void or_reg(uint32_t offset, uint32_t value) +{ + uint32_t reg; + reg = read_reg(offset); + reg |= value; + write_reg(offset, reg); +} + +static void set_bits_in_reg(uint32_t offset, uint32_t pos, uint32_t mask, uint32_t value) +{ + uint32_t set = read_reg(offset); + + set &= ~mask; + set |= (value << pos); + + write_reg(offset, set); +} diff --git a/drivers/apple/lpdp_phy/regs_v1.h b/drivers/apple/lpdp_phy/regs_v1.h new file mode 100644 index 0000000..c09cf3d --- /dev/null +++ b/drivers/apple/lpdp_phy/regs_v1.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _LPDP_PHY_REGS_H +#define _LPDP_PHY_REGS_H + +#define rLPDP_GEN_VERSION (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00000)) +#define rLPDP_GEN_SEQ_0 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00004)) + +#define rLPDP_GEN_SEQ_1 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00008)) +#define LPDP_GEN_SEQ_1_START_COUNT(n) ((n) << 8) +#define LPDP_GEN_SEQ_1_SETUP_COUNT(n) ((n) << 0) + +#define rLPDP_GEN_SEQ_2 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0000c)) +#define rLPDP_GEN_SEQ_3 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00010)) + +#define rLPDP_GEN_SEQ_4 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00014)) +#define LPDP_GEN_SEQ_4_FINISH_COUNT(n) ((n) << 8) +#define LPDP_GEN_SEQ_4_UPDATE_COUNT(n) ((n) << 0) + +#define rLPDP_GEN_LINE_COUNTER (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00018)) +#define rLPDP_GEN_SPARE_CONFIG (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0001c)) +#define rLPDP_GEN_SPARE_STATUS (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00020)) +#define rLPDP_GEN_AUX_DRIVER (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00024)) +#define LPDP_GEN_AUX_DRIVER_EXT_SEL (1 << 15) + +#define rLPDP_PHY_GEN_CTRL (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00040)) +#define LPDP_PHY_GEN_CTRL_SEQ_OW (1 << 7) +#define LPDP_PHY_GEN_CTRL_SLEEP_SW (1 << 6) +#define LPDP_PHY_GEN_CTRL_LANE_PD_OW (1 << 2) +#define LPDP_PHY_GEN_CTRL_BIAS_PWRDN (1 << 0) + +#define rLPDP_PHY_LANE(n) (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00044 + ((n) << 2))) +#define rLPDP_PHY_LANE_0 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00044)) +#define LPDP_PHY_LANE_CM_PRECHARGE_SLEEP(n) ((n) << 13) +#define LPDP_PHY_LANE_CM_PRECHARGE_NORMAL(n) ((n) << 11) +#define LPDP_PHY_LANE_LDO_PWRDN (1 << 10) +#define LPDP_PHY_LANE_PWRDN (1 << 9) +#define LPDP_PHY_LANE_HI_Z (1 << 8) +#define LPDP_PHY_LANE_DE_ENABLE (1 << 7) +#define LPDP_PHY_LANE_PASSMOS_CTRL(n) ((n) << 4) +#define LPDP_PHY_LANE_VREG_ADJ(n) ((n) << 0) +#define LPDP_PHY_LANE_x_VREG_ADJ_MAX 0xF +#define LPDP_PHY_LANE_x_VREG_ADJ_SHIFT 0 +#define LPDP_PHY_LANE_x_VREG_ADJ_MASK (0xF << LPDP_PHY_LANE_x_VREG_ADJ_SHIFT) +#define LPDP_PHY_LANE_VREG_ADJ_420_mV (15) +#define LPDP_PHY_LANE_VREG_ADJ_400_mV (14) +#define LPDP_PHY_LANE_VREG_ADJ_380_mV (13) +#define LPDP_PHY_LANE_VREG_ADJ_360_mV (12) +#define LPDP_PHY_LANE_VREG_ADJ_340_mV (11) +#define LPDP_PHY_LANE_VREG_ADJ_320_mV (10) +#define LPDP_PHY_LANE_VREG_ADJ_300_mV (9) +#define LPDP_PHY_LANE_VREG_ADJ_280_mV (8) +#define LPDP_PHY_LANE_VREG_ADJ_260_mV (7) +#define LPDP_PHY_LANE_VREG_ADJ_240_mV (6) +#define LPDP_PHY_LANE_VREG_ADJ_220_mV (5) +#define LPDP_PHY_LANE_VREG_ADJ_200_mV (4) +#define LPDP_PHY_LANE_VREG_ADJ_180_mV (3) +#define LPDP_PHY_LANE_VREG_ADJ_160_mV (2) +#define LPDP_PHY_LANE_VREG_ADJ_140_mV (1) +#define LPDP_PHY_LANE_VREG_ADJ_120_mV (0) +#define LPDP_PHY_LANE_x_FULL_DISABLE (LPDP_PHY_LANE_LDO_PWRDN | \ + LPDP_PHY_LANE_PWRDN | \ + LPDP_PHY_LANE_HI_Z) + +#define rLPDP_PHY_LANE_1 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00048)) +#define rLPDP_PHY_LANE_2 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0004c)) +#define rLPDP_PHY_LANE_3 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00050)) +#define rLPDP_PHY_PRBS_0 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00054)) +#define rLPDP_PHY_PRBS_1 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00058)) +#define rLPDP_PHY_PRBS_2 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0005c)) +#define rLPDP_PHY_PRBS_3 (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00060)) +#define rLPDP_PHY_PRBS_ERR (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00064)) +#define rLPDP_PHY_TEST (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00068)) +#define rLPDP_PHY_BIST (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0006c)) + +#define rLPDP_PHY_CAL_CTRL (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00070)) +#define LPDP_PHY_CAL_CTRL_AUTOZERO_BYP (1 << 3) +#define LPDP_PHY_CAL_CTRL_TYPE_SEL_UP (1 << 2) +#define LPDP_PHY_CAL_CTRL_RST (1 << 1) +#define LPDP_PHY_CAL_CTRL_PWRDN (1 << 0) + +#define rLPDP_PHY_CAL_EXT (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00074)) +#define LPDP_PHY_CAL_EXT_CTRL_SEL (1 << 15) + +#define rLPDP_PHY_CAL_RESULT (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00078)) +#define LPDP_PHY_CAL_RESULT_COMPLETE (1 << 15) +#define LPDP_PHY_CAL_RESULT_CO_PD (1 << 14) +#define LPDP_PHY_CAL_RESULT_PD(n) (((n) >> 8) & 0x3F) +#define LPDP_PHY_CAL_RESULT_CO_PU (1 << 7) +#define LPDP_PHY_CAL_RESULT_PU(n) (n & 0x7F) +#define rLPDP_PHY_AUX_CTRL (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0007C)) +#define LPDP_PHY_AUX_CTRL_PWRDN (1 << 4) +#define LPDP_PHY_AUX_CTRL_VREG_ADJ_SHIFT 0 +#define LPDP_PHY_AUX_CTRL_VREG_ADJ_MASK (0xF << LPDP_PHY_AUX_CTRL_VREG_ADJ_SHIFT) +#define LPDP_PHY_AUX_CTRL_VREG_ADJ_MAX 0xF + + + +#define rLPDP_PLL_GEN (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00080)) +#define LPDP_PLL_GEN_TEST_SEL_VSSA (0 << 10) +#define LPDP_PLL_GEN_TEST_SEL_VDD_SOC (1 << 10) +#define LPDP_PLL_GEN_TEST_SEL_VREG_1VA (2 << 10) +#define LPDP_PLL_GEN_TEST_SEL_PLL_LOCK_OUT (3 << 10) +#define LPDP_PLL_GEN_TEST_SEL_CP_OUT (4 << 10) +#define LPDP_PLL_GEN_TEST_SEL_VCO_TOP (5 << 10) +#define LPDP_PLL_GEN_TEST_SEL_VREF_CAL (6 << 10) +#define LPDP_PLL_GEN_TEST_SEL_VBTST (7 << 10) +#define LPDP_PLL_GEN_TEST_EN (1 << 9) +#define LPDP_PLL_GEN_GCLK_SEL_VCLK (1 << 8) +#define LPDP_PLL_GEN_GCLK_DIV(n) (n << 4) +#define LPDP_PLL_GEN_STOP_CLK (1 << 3) +#define LPDP_PLL_GEN_BYPASS (1 << 2) +#define LPDP_PLL_GEN_RST (1 << 1) +#define LPDP_PLL_GEN_PWRDN (1 << 0) + +#define rLPDP_PLL_CLK (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00084)) +#define LPDP_PLL_CLK_FLIN_SEL (1 << 12) +#define LPDP_PLL_CLK_BG_START_SEL (1 << 11) +#define LPDP_PLL_CLK_PFDCP_RST_SEL (1 << 10) +#define LPDP_PLL_CLK_VCLK_SEL_VCO (1 << 9) +#define LPDP_PLL_CLK_VCO_BLK_RSTPD (1 << 8) +#define LPDP_PLL_CLK_VCO_BLK_SCLK (1 << 7) +#define LPDP_PLL_CLK_VCO_BLK_VCLK (1 << 6) +#define LPDP_PLL_CLK_VCO_RCTRL_SEL_ENABLE (1 << 5) +#define LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT 2 +#define LPDP_PLL_CLK_VCO_RCTRL_OW_MASK (0x7 << LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT) +#define LPDP_PLL_CLK_VCO_PCTRL(n) ((n) << 0) + +#define rLPDP_PLL_IDIV (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00088)) +#define LPDP_PLL_IDIV_UPDT (1 << 14) +#define LPDP_PLL_IDIV_FB(n) (n << 5) +#define LPDP_PLL_IDIV_PRE(n) (n << 0) +#define LPDP_PLL_IDIV_FB_SHIFT 5 +#define LPDP_PLL_IDIV_FB_MASK (0x1FF << LPDP_PLL_IDIV_FB_SHIFT) +#define LPDP_PLL_IDIV_PRE_SHIFT 0 +#define LPDP_PLL_IDIV_PRE_MASK (0x1F << LPDP_PLL_IDIV_PRE_SHIFT) + + +#define rLPDP_PLL_CP (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0008C)) +#define LPDP_PLL_CP_BOOST_MODE (1 << 14) +#define LPDP_PLL_CP_BOOST_EN (1 << 13) +#define LPDP_PLL_CP_ENABLE (1 << 12) +#define LPDP_PLL_CP_RSTN (1 << 11) +#define LPDP_PLL_CP_LIN_EN (1 << 10) +#define LPDP_PLL_CP_R_SET(n) (n << 3) +#define LPDP_PLL_CP_I_SET(n) (n << 0) + +#define rLPDP_PLL_LOCK (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00090)) +#define LPDP_PLL_LOCK_OUT_OFF (0 << 9) +#define LPDP_PLL_LOCK_OUT_ON (1 << 9) +#define LPDP_PLL_LOCK_RST_OFF (0 << 8) +#define LPDP_PLL_LOCK_RST_ON (1 << 8) +#define LPDP_PLL_LOCK_POR_OFF (0 << 7) +#define LPDP_PLL_LOCK_POR_ON (1 << 7) +#define LPDP_PLL_LOCK_DIV(n) ((n) << 0) + +#define rLPDP_PLL_VCO (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00094)) +#define LPDP_PLL_VCO_BUF_PWRDN_OFF (0 << 14) +#define LPDP_PLL_VCO_BUF_PWRDN_ON (1 << 14) +#define LPDP_PLL_VCO_DEC_BYPASS_OFF (0 << 13) +#define LPDP_PLL_VCO_DEC_BYPASS_ON (1 << 13) +#define LPDP_PLL_VCO_REG_PWRDN_OFF (0 << 12) +#define LPDP_PLL_VCO_REG_PWRDN_ON (1 << 12) +#define LPDP_PLL_VCO_REG_BYPASS_OFF (0 << 11) +#define LPDP_PLL_VCO_REG_BYPASS_ON (1 << 11) +#define LPDP_PLL_VCO_VREG_ADJ(n) ((n) << 8) +#define LPDP_PLL_VCO_K_VCO_CTRL(n) ((n) << 4) +#define LPDP_PLL_VCO_RESDIV_SEL(n) ((n) << 1) +#define LPDP_PLL_VCO_RESDIV_VREF_EN_OFF (0 << 0) +#define LPDP_PLL_VCO_RESDIV_VREF_EN_ON (1 << 0) + +#define rLPDP_PLL_SDM (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00098)) +#define rLPDP_PLL_SSC (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x0009c)) +#define rLPDP_PLL_FMC (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x000a0)) +#define rLPDP_PLL_SPARE (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x000a4)) +#endif //_LPDP_PHY_REGS_H diff --git a/drivers/apple/lpdp_phy/regs_v2.h b/drivers/apple/lpdp_phy/regs_v2.h new file mode 100644 index 0000000..14e804f --- /dev/null +++ b/drivers/apple/lpdp_phy/regs_v2.h @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _LPDP_PHY_REGS_V2_H +#define _LPDP_PHY_REGS_V2_H + +#define rLPDP_GEN_VERSION (0x00000) +#define rLPDP_GEN_SEQ_0 (0x00004) + +#define rLPDP_GEN_SEQ_1 (0x00008) +#define LPDP_GEN_SEQ_1_START_COUNT(n) ((n) << 8) +#define LPDP_GEN_SEQ_1_SETUP_COUNT(n) ((n) << 0) + +#define rLPDP_GEN_SEQ_2 (0x0000c) +#define rLPDP_GEN_SEQ_3 (0x00010) + +#define rLPDP_GEN_SEQ_4 (0x00014) +#define LPDP_GEN_SEQ_4_HOLD_COUNT(n) ((n) << 8) +#define LPDP_GEN_SEQ_4_UPDATE_COUNT(n) ((n) << 0) + +#define rLPDP_GEN_SEQ_5 (0x00018) +#define LPDP_GEN_SEQ_5_FINISH_COUNT(n) ((n) << 8) +#define LPDP_GEN_SEQ_5_WAKEUP_COUNT(n) ((n) << 0) + +#define rLPDP_GEN_LINE_COUNTER (0x0001c) +#if LPDP_PHY_VERSION < 2 +#define rLPDP_GEN_DISPLAY_SPLIT (0x00020) +#define rLPDP_GEN_SPARE_CONFIG (0x00024) +#define rLPDP_GEN_SPARE_STATUS (0x00028) +#elif LPDP_PHY_VERSION == 2 +#define rLPDP_GEN_SPARE_CONFIG (0x00020) +#define rLPDP_GEN_SPARE_STATUS (0x00024) +#endif + +#define rLPDP_PHY_GEN_CTRL (0x00100) +#define LPDP_PHY_GEN_CTRL_BIAS_START_PULSE_EXT (1 << 12) +#define LPDP_PHY_GEN_CTRLBIAS_EXT_START_SEL (1 << 11) +#define LPDP_PHY_GEN_CTRL_WAKEUP_SW (1 << 10) +#define LPDP_PHY_GEN_CTRL_FIFO_RST_MASK (1 << 9) +#define LPDP_PHY_GEN_CTRL_FIFO_RST_HW (1 << 8) +#define LPDP_PHY_GEN_CTRL_SEQ_OW (1 << 7) +#define LPDP_PHY_GEN_CTRL_SLEEP_SW (1 << 6) +#define LPDP_PHY_GEN_CTRL_LANE_PD_OW (1 << 2) +#define LPDP_PHY_GEN_CTRL_BIAS_PWRDN (1 << 0) + +#define rLPDP_PHY_LANE(n) (0x00104 + ((n) << 2)) +#define rLPDP_PHY_LANE_0 (0x00104) +#define LPDP_PHY_LANE_CM_PRECHARGE_SLEEP(n) ((n) << 13) +#define LPDP_PHY_LANE_CM_PRECHARGE_NORMAL(n) ((n) << 11) +#define LPDP_PHY_LANE_LDO_PWRDN (1 << 10) +#define LPDP_PHY_LANE_PWRDN (1 << 9) +#define LPDP_PHY_LANE_HI_Z (1 << 8) +#define LPDP_PHY_LANE_VREG_ADJ(n) ((n) << 0) +#define LPDP_PHY_LANE_x_VREG_ADJ_MAX 0xF +#define LPDP_PHY_LANE_x_VREG_ADJ_SHIFT 0 +#define LPDP_PHY_LANE_x_VREG_ADJ_MASK (0xF << LPDP_PHY_LANE_x_VREG_ADJ_SHIFT) + +#if LPDP_PHY_VERSION < 2 +#define LPDP_PHY_LANE_VREG_ADJ_570_mV (15) +#define LPDP_PHY_LANE_VREG_ADJ_540_mV (14) +#define LPDP_PHY_LANE_VREG_ADJ_510_mV (13) +#define LPDP_PHY_LANE_VREG_ADJ_480_mV (12) +#define LPDP_PHY_LANE_VREG_ADJ_450_mV (11) +#define LPDP_PHY_LANE_VREG_ADJ_420_mV (10) +#define LPDP_PHY_LANE_VREG_ADJ_390_mV (9) +#define LPDP_PHY_LANE_VREG_ADJ_360_mV (8) +#define LPDP_PHY_LANE_VREG_ADJ_330_mV (7) +#define LPDP_PHY_LANE_VREG_ADJ_300_mV (6) +#define LPDP_PHY_LANE_VREG_ADJ_270_mV (5) +#define LPDP_PHY_LANE_VREG_ADJ_240_mV (4) +#define LPDP_PHY_LANE_VREG_ADJ_210_mV (3) +#define LPDP_PHY_LANE_VREG_ADJ_180_mV (2) +#define LPDP_PHY_LANE_VREG_ADJ_150_mV (1) +#define LPDP_PHY_LANE_VREG_ADJ_120_mV (0) +#define LPDP_PHY_LANE_x_FULL_DISABLE (LPDP_PHY_LANE_LDO_PWRDN | \ + LPDP_PHY_LANE_PWRDN) +#elif LPDP_PHY_VERSION == 2 +#define LPDP_PHY_LANE_VREG_ADJ_530_mV (7) +#define LPDP_PHY_LANE_VREG_ADJ_450_mV (6) +#define LPDP_PHY_LANE_VREG_ADJ_390_mV (5) +#define LPDP_PHY_LANE_VREG_ADJ_310_mV (4) +#define LPDP_PHY_LANE_VREG_ADJ_250_mV (3) +#define LPDP_PHY_LANE_VREG_ADJ_210_mV (2) +#define LPDP_PHY_LANE_VREG_ADJ_190_mV (1) +#define LPDP_PHY_LANE_VREG_ADJ_170_mV (0) +#define LPDP_PHY_LANE_PWRDN_SML (1 << 7) +#define LPDP_PHY_LANE_x_FULL_DISABLE (LPDP_PHY_LANE_LDO_PWRDN | \ + LPDP_PHY_LANE_PWRDN | \ + LPDP_PHY_LANE_PWRDN_SML) +#endif + +#define rLPDP_PHY_LANE_1 (0x00108) +#define rLPDP_PHY_LANE_2 (0x0010c) +#define rLPDP_PHY_LANE_3 (0x00110) +#define rLPDP_PHY_PRBS_0 (0x00114) +#define rLPDP_PHY_PRBS_1 (0x00118) +#define rLPDP_PHY_PRBS_2 (0x0011c) +#define rLPDP_PHY_PRBS_3 (0x00120) +#define rLPDP_PHY_PRBS_ERR (0x00124) +#define rLPDP_PHY_TEST (0x00128) + +#define rLPDP_PHY_BIST (0x0012c) +#define LPDP_PHY_BIST_DEMUX_RST (1 << 8) +#define LPDP_PHY_BIST_LOOPBACK_SRC_SEL(n) ((n) << 3) +#define LPDP_PHY_BIST_LOOPBACK_SRC_SEL_MASK (0x1f) +#define LPDP_PHY_BIST_NONE 0x0 +#define LPDP_PHY_BIST_LANE0 0x1 +#define LPDP_PHY_BIST_LANE1 0x2 +#define LPDP_PHY_BIST_LANE2 0x4 +#define LPDP_PHY_BIST_LANE3 0x8 +#define LPDP_PHY_BIST_DEMUX 0x10 +#define LPDP_PHY_BIST_DEMUX_SEL(n) ((n) << 1) +#define LPDP_PHY_BIST_SEL0 0x0 +#define LPDP_PHY_BIST_SEL1 0x1 +#define LPDP_PHY_BIST_SEL2 0x2 +#define LPDP_PHY_BIST_SEL3 0x3 +#define LPDP_PHY_BIST_ENABLE (1 << 0) + +#define rLPDP_PHY_CAL (0x00130) +#define LPDP_PHY_CAL_COMP_OUT (1 << 8) +#define LPDP_PHY_CAL_FAIL (1 << 7) +#define LPDP_PHY_CAL_DONE (1 << 6) +#define LPDP_PHY_CAL_AZ_BYP (1 << 5) +#define LPDP_PHY_CAL_MODE_FORCE(n) ((n) << 3) +#define LPDP_PHY_CAL_FORCE_EN (1 << 2) +#define LPDP_PHY_CAL_START (1 << 1) +#define LPDP_PHY_CAL_RESET_N (1 << 0) + +#define rLPDP_PHY_CAL_PD (0x00134) +#define LPDP_PHY_CAL_PD_CODE_ERR (1 << 13) +#define LPDP_PHY_CAL_PD_EXT_SEL (1 << 12) +#define LPDP_PHY_CAL_PD_CODE_FSM(n) ((n) << 6) +#define LPDP_PHY_CAL_PD_CODE_EXT(n) ((n) << 0) + +#define rLPDP_PHY_CAL_PU (0x00138) +#define LPDP_PHY_CAL_P_CODE_ERR (1 << 13) +#define LPDP_PHY_CAL_P_EXT_SEL (1 << 12) +#define LPDP_PHY_CAL_P_CODE_FSM(n) ((n) << 6) +#define LPDP_PHY_CAL_P_CODE_EXT(n) ((n) << 0) + +#define rLPDP_PHY_CAL_TX (0x0013C) +#define LPDP_PHY_CAL_TX_EXT_SEL (1 << 12) +#define LPDP_PHY_CAL_TX_CODE_FSM_SHIFT (6) +#define LPDP_PHY_CAL_TX_CODE_FSM(n) ((n) << LPDP_PHY_CAL_TX_CODE_FSM_SHIFT) +#define LPDP_PHY_CAL_TX_CODE_FSM_MASK ((0x3F) << LPDP_PHY_CAL_TX_CODE_FSM_SHIFT) +#define LPDP_PHY_CAL_TX_CODE_EXT(n) ((n) << 0) + +#define rLPDP_PHY_AUX_CTRL (0x00140) +#define LPDP_PHY_AUX_CTRL_TX_AUX_ENABLE (1 << 5) +#define LPDP_PHY_AUX_CTRL_PWRDN (1 << 4) +#define LPDP_PHY_AUX_CTRL_VREG_ADJ(n) ((n) << 0) +#define LPDP_PHY_AUX_CTRL_VREG_ADJ_SHIFT 0 +#define LPDP_PHY_AUX_CTRL_VREG_ADJ_MASK (0xF << LPDP_PHY_AUX_CTRL_VREG_ADJ_SHIFT) +#define LPDP_PHY_AUX_CTRL_VREG_ADJ_MAX 0xF + +#define rLPDP_PHY_AUX_DRIVER (0x00144) +#define LPDP_PHY_AUX_DRIVER_EXT_SEL (1 << 15) +#define LPDP_PHY_AUX_DRIVER_EXT_PD(n) ((n) << 8) +#define LPDP_PHY_AUX_DRIVER_EXT_PU(n) ((n) << 0) + +#define rLPDP_PHY_CLK_CTRL (0x00148) +#define LPDP_PHY_CLK_CTRL_CLKDIV_SHFTEN (1 << 2) +#define LPDP_PHY_CLK_CTRL_CLK_ENABLE (1 << 1) +#define LPDP_PHY_CLK_CTRL_CLKDIV5_RESET (1 << 0) + +#define rLPDP_PHY_CLK_LDO_CTRL (0x0014c) +#if LPDP_PHY_VERSION == 2 +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_REF_ADJ(n) ((n) << 15) +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN_SML(n) ((n) << 11) +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN_SML_MAX (0xf) +#endif +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_SB_EN (1 << 10) +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_BGREF_BYPASS (1 << 9) +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_BYPASS (1 << 8) +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_VREG_ADJ(n) ((n) << 4) +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN(n) ((n) << 0) +#define LPDP_PHY_CLK_LDO_CTRL_LDOCLK_PWRDN_MAX (0xf) + +#define rLPDP_PHY_PRE_LDO_CTRL (0x00150) +#define LPDP_PHY_PRE_LDO_CTR_LDOPRE_SB_EN (1 << 10) +#define LPDP_PHY_PRE_LDO_CTR_LDOPRE_BGREF_BYPASS (1 << 9) +#define LPDP_PHY_PRE_LDO_CTR_LDOPRE_BYPASS (1 << 8) +#define LPDP_PHY_PRE_LDO_CTR_LDOPRE_VREG_ADJ(n) ((n) << 4) +#define LPDP_PHY_PRE_LDO_CTR_LDOPRE_PWRDN(n) ((n) << 0) +#define LPDP_PHY_PRE_LDO_CTR_LDOPRE_PWRDN_MAX (0xf) + +#define rLPDP_PHY_POST_LDO_CTRL (0x00154) +#define LPDP_PHY_POST_LDO_CTRL_LDOPOST_VR_TEST_EN (1 << 12) +#define LPDP_PHY_POST_LDO_CTRL_LDOPOST_LEAKEN (1 << 11) +#define LPDP_PHY_POST_LDO_CTRL_LDOPOST_SB_EN (1 << 10) +#define LPDP_PHY_POST_LDO_CTRL_LDOPOST_BGREF_BYPASS (1 << 9) +#if LPDP_PHY_VERSION == 2 +#define LPDP_PHY_POST_LDO_CTRL_LDOPOST_BYPASS (1 << 0) +#endif + +#define rLPDP_PHY_AUX_LDO_CTRL (0x00158) +#if LPDP_PHY_VERSION < 2 +#define LPDP_PHY_AUX_LDO_CTRL_AUXVREG_BGREF_BYPASS (1 << 9) +#define LPDP_PHY_AUX_LDO_CTRL_AUXVREG_BYPASS (1 << 8) +#define LPDP_PHY_AUX_LDO_CTRL_AUXVREG_ADJ(n) ((n) << 4) +#elif LPDP_PHY_VERSION == 2 +#define LPDP_PHY_AUX_LDO_CTRL_LDOPOST_REF_ADJ(n) ((n) << 27) +#define LPDP_PHY_AUX_LDO_CTRL_LDOPOST_PWRDN_BIG (1 << 26) +#define LPDP_PHY_AUX_LDO_CTRL_LDOPOST_PWRDN_SML (1 << 25) +#define LPDP_PHY_AUX_LDO_CTRL_LDOCLK_VREG_ADJ(n) ((n) << 21) +#define LPDP_PHY_AUX_LDO_CTRL_LDOCLK_REF_ADJ(n) ((n) << 18) +#define LPDP_PHY_AUX_LDO_CTRL_LDOCLK_PWRDN_BIG (1 << 17) +#define LPDP_PHY_AUX_LDO_CTRL_LDOCLK_PWRDN_SML (1 << 16) +#endif +#define LPDP_PHY_AUX_LDO_CTRL_AUX_CM_CTRL(n) ((n) << 1) +#if LPDP_PHY_VERSION < 2 +#define LPDP_PHY_AUX_LDO_CTRL_AUXLDO_PWRDN (1 << 0) +#endif + +#define rLPDP_PHY_DE_CTRL (0x0015c) +#if LPDP_PHY_VERSION < 2 +#define LPDP_PHY_DE_CTRL_DE_EN (1 << 2) +#elif LPDP_PHY_VERSION == 2 +#define LPDP_PHY_DE_CTRL_DE2_EN (1 << 6) +#define LPDP_PHY_DE_CTRL_DE1_EN (1 << 2) +#endif +#define LPDP_PHY_DE_CTRL_DE_EN_LSB(n) ((n) << 0) + +#define rLPDP_PHY_RESERVED (0x00160) + +#define rLPDP_PLL_GEN (0x00180) +#define LPDP_PLL_GEN_CLKDIV2_RESET_N (1 << 15) +#define LPDP_PLL_GEN_TEST_SEL(n) ((n) << 10) +#define LPDP_PLL_GEN_VSSA 0x0 +#define LPDP_PLL_GEN_VDD_SOC 0x1 +#define LPDP_PLL_GEN_VREG_1VA 0x2 +#define LPDP_PLL_GEN_PLL_LOCK_OUT 0x3 +#define LPDP_PLL_GEN_CP_OUT 0x4 +#define LPDP_PLL_GEN_VCO_TOP 0x5 +#define LPDP_PLL_GEN_VREF_CAL 0x6 +#define LPDP_PLL_GEN_VBTST 0x7 +#define LPDP_PLL_GEN_TEST_EN (1 << 9) +#define LPDP_PLL_GEN_GCLK_SEL (1 << 8) +#define LPDP_PLL_GEN_GCLK_DIV(n) ((n) << 4) +#define LPDP_PLL_GEN_GCLK_DIV_MASK (0xf) +#define LPDP_PLL_GEN_STOP_CLK (1 << 3) +#define LPDP_PLL_GEN_BYPASS (1 << 2) +#define LPDP_PLL_GEN_RST (1 << 1) +#define LPDP_PLL_GEN_PWRDN (1 << 0) + +#define rLPDP_PLL_CLK (0x00184) +#define LPDP_PLL_CLK_FLIN_SEL (1 << 12) +#define LPDP_PLL_CLK_BG_START_SEL (1 << 11) +#define LPDP_PLL_CLK_PFDCP_RST_SEL (1 << 10) +#define LPDP_PLL_CLK_VCLK_SEL_VCO (1 << 9) +#define LPDP_PLL_CLK_VCO_BLK_RSTPD (1 << 8) +#define LPDP_PLL_CLK_VCO_BLK_SCLK (1 << 7) +#define LPDP_PLL_CLK_VCO_BLK_VCLK (1 << 6) +#define LPDP_PLL_CLK_VCO_RCTRL_SEL_ENABLE (1 << 5) +#define LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT 2 +#define LPDP_PLL_CLK_VCO_RCTRL_OW_MASK (0x7 << LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT) +#define LPDP_PLL_CLK_VCO_PCTRL(n) ((n) << 0) + +#define rLPDP_PLL_IDIV (0x00188) +#define LPDP_PLL_IDIV_UPDT (1 << 14) +#define LPDP_PLL_IDIV_FB(n) (n << 5) +#define LPDP_PLL_IDIV_PRE(n) (n << 0) +#define LPDP_PLL_IDIV_FB_SHIFT 5 +#define LPDP_PLL_IDIV_FB_MASK (0x1FF << LPDP_PLL_IDIV_FB_SHIFT) +#define LPDP_PLL_IDIV_PRE_SHIFT 0 +#define LPDP_PLL_IDIV_PRE_MASK (0x1F << LPDP_PLL_IDIV_PRE_SHIFT) + +#define rLPDP_PLL_CP (0x0018C) +#define LPDP_PLL_CP_BOOST_MODE (1 << 14) +#define LPDP_PLL_CP_BOOST_EN (1 << 13) +#define LPDP_PLL_CP_ENABLE (1 << 12) +#define LPDP_PLL_CP_RSTN (1 << 11) +#define LPDP_PLL_CP_LIN_EN (1 << 10) +#define LPDP_PLL_CP_R_SET(n) (n << 3) +#define LPDP_PLL_CP_I_SET(n) (n << 0) + +#define rLPDP_PLL_LOCK (0x00190) +#define LPDP_PLL_LOCK_OUT_OFF (0 << 9) +#define LPDP_PLL_LOCK_OUT_ON (1 << 9) +#define LPDP_PLL_LOCK_RST_OFF (0 << 8) +#define LPDP_PLL_LOCK_RST_ON (1 << 8) +#define LPDP_PLL_LOCK_POR_OFF (0 << 7) +#define LPDP_PLL_LOCK_POR_ON (1 << 7) +#define LPDP_PLL_LOCK_DIV(n) ((n) << 0) + +#define rLPDP_PLL_VCO (0x00194) +#define LPDP_PLL_VCO_BUF_PWRDN_OFF (0 << 14) +#define LPDP_PLL_VCO_BUF_PWRDN_ON (1 << 14) +#define LPDP_PLL_VCO_DEC_BYPASS_OFF (0 << 13) +#define LPDP_PLL_VCO_DEC_BYPASS_ON (1 << 13) +#define LPDP_PLL_VCO_REG_PWRDN_OFF (0 << 12) +#define LPDP_PLL_VCO_REG_PWRDN_ON (1 << 12) +#define LPDP_PLL_VCO_REG_BYPASS_OFF (0 << 11) +#define LPDP_PLL_VCO_REG_BYPASS_ON (1 << 11) +#define LPDP_PLL_VCO_VREG_ADJ(n) ((n) << 8) +#define LPDP_PLL_VCO_K_VCO_CTRL(n) ((n) << 4) +#define LPDP_PLL_VCO_RESDIV_SEL(n) ((n) << 1) +#define LPDP_PLL_VCO_RESDIV_VREF_EN_OFF (0 << 0) +#define LPDP_PLL_VCO_RESDIV_VREF_EN_ON (1 << 0) + +#define rLPDP_PLL_SDM (0x00198) +#define rLPDP_PLL_SSC (0x0019c) +#define rLPDP_PLL_FMC (0x001a0) + +#define rLPDP_PLL_SEL (0x001a4) +#define RLPDP_PLL_SEL_REF_OUT (1 << 7) +#define RLPDP_PLL_SEL_VCO_OUT (1 << 6) +#define RLPDP_PLL_SEL_PLL_OUT (1 << 5) +#define RLPDP_PLL_SEL_TESTWRAPPER (1 << 4) +#define RLPDP_PLL_SEL_CK_DFT (1 << 3) +#define RLPDP_PLL_SEL_REF_DFT (1 << 2) +#define RLPDP_PLL_SEL_VCO_DFT (1 << 1) +#define RLPDP_PLL_SEL_PLL_DFT (1 << 0) + +#if LPDP_PHY_VERSION < 2 +#define rLPDP_PLL_SPARE (0x001a8) +#elif LPDP_PHY_VERSION == 2 +#define rLPDP_PLL_LPF (0x001a8) +#define rLPDP_PLL_FCAL (0x001ac) +#define LPDP_PLL_FCAL_RESET (1 << 18) +#define rLPDP_PLL_SPARE (0x001b0) +#endif +#endif //_LPDP_PHY_REGS_V2_H diff --git a/drivers/apple/lpdp_phy/rules.mk b/drivers/apple/lpdp_phy/rules.mk new file mode 100644 index 0000000..1dca828 --- /dev/null +++ b/drivers/apple/lpdp_phy/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2013-2014 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifeq ($(LPDP_VERSION),) + $(error "LPDP_VERSION not set") +else + ALL_OBJS += \ + $(LOCAL_DIR)/lpdp_v$(LPDP_VERSION).o +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/mcu/mcu.c b/drivers/apple/mcu/mcu.c new file mode 100644 index 0000000..af211cb --- /dev/null +++ b/drivers/apple/mcu/mcu.c @@ -0,0 +1,625 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +// TI MSP430F2350 MCU Serial Packet Format +// +// 0 1 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +0 +// | 'S' | 't' | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +2 +// | OpCode | Seq No | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +4 +// | Length High | Length Low | +// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +6 +// | | +// | | +// | | +// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +// | CRC-16 High | CRC-16 Low | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Sequence number is even for MCU->CPU packets and odd for CPU->MCU packets. +// CRC is a CRC-16 CCITT (polynomial 0x1021, init value is 0xFFFF). + +typedef uint8_t MCUOpCode; + +// Commands requiring acks. + +#define kMCUOpCode_NoOp 0x00 +#define kMCUOpCode_PowerOnReset 0x01 +#define kMCUOpCode_GetVersion 0x02 // Response: <2:major>.<2:minor>[.<4:revision>] +#define kMCUOpCode_SILControl 0x04 // Request: <1:action> + + #define kMCUSILAction_Invalid 0xFF + + #define kMCUSILAction_Off 0 + #define kMCUSILAction_OffStr "off" + + #define kMCUSILAction_On 1 + #define kMCUSILAction_OnStr "on" + + #define kMCUSILAction_SlowFlash 2 + #define kMCUSILAction_SlowStr "slow" + + #define kMCUSILAction_FastFlash 3 + #define kMCUSILAction_FastStr "fast" + + #define kMCUSILAction_1Blink 4 + #define kMCUSILAction_1BlinkStr "1blink" + + #define kMCUSILAction_3Blinks 5 + #define kMCUSILAction_3BlinksStr "3blinks" + +#define kMCUOpCode_PairControl 0x05 // Request: <1:0=unpair, 1=pair> <1:remote UID> + + #define kMCUPairAction_Unpair 0x00 + #define kMCUPairAction_Pair 0x01 + +#define kMCUOpCode_BlueSteelControl 0x06 // Request: <1:mode> <1:subMode> + + #define kMCUBSControl_Invalid 0xff + + #define kMCUBSControl_Reset 0 + #define kMCUBSControl_ResetStr "reset" + #define kMCUBSControl_EnterTestMode 1 + #define kMCUBSControl_EnterTestModeStr "testmode" + #define kMCUBSControl_PassthroughMode 2 + #define kMCUBSControl_PassthroughModeStr "passthru" + #define kMCUBSControl_InfoFrameEnable 5 + #define kMCUBSControl_InfoFrameEnableStr "info" + +#define kMCUOpCode_SystemState 0x07 // Request: <1:state> + + #define kMCUSystemState_NoChange 0x00 + #define kMCUSystemState_Standby 0x01 + #define kMCUSystemState_Normal 0x02 + +#define kMCUOpCode_AppleIRData 0x10 +#define kMCUOpCode_Repeat 0x11 +#define kMCUOpCode_3rdPartyIRData 0x12 + +// Acks to commands. + +#define kMCUOpCode_Ack 0x80 +#define kMCUOpCode_NakUnknown 0x81 +#define kMCUOpCode_NakUnsupported 0x82 +#define kMCUOpCode_NakBadCRC 0x83 +#define kMCUOpCode_NakNotNow 0x84 +#define kMCUOpCode_NakMessageTooLong 0x85 +#define kMCUOpCode_NakOther 0x9F + +#define MCUOpCode_IsAckOrNak( X ) \ + ( ( (X) == kMCUOpCode_Ack ) || \ + ( (X) == kMCUOpCode_NakUnknown ) || \ + ( (X) == kMCUOpCode_NakUnsupported ) || \ + ( (X) == kMCUOpCode_NakBadCRC ) || \ + ( (X) == kMCUOpCode_NakNotNow ) || \ + ( (X) == kMCUOpCode_NakMessageTooLong ) || \ + ( (X) == kMCUOpCode_NakOther ) ) + +// No response necessary. + +#define kMCUOpCode_DebugData 0xFF + +// Set to 1 to print text contents of MCU debug packets +#define PRINT_MCU_DEBUG 0 + +// Constants + +#define kMCUResponseTimeout 4000000 +#define kMCUTaskStackSize 8192 +#define kMCUMaxRecvSize 32 + +#define kMCUBaudRate 250000 +#define kMCUWordPeriodUS (1000000 / (kMCUBaudRate/10)) +#define kMCUFifoSize 1024 + +#define kMCUNotNowDelayUS 100000 +#define kMCUNotNowAttempts 100 +#define kMCUReadTimeoutUS 1000000 +#define kMCUSendAttempts 5 + +#define kMCUFifoLatencyUS (kMCUWordPeriodUS * kMCUFifoSize) +#define kMCUReadSleepUS (kMCUFifoLatencyUS / 4) + +struct McuRecvPacket { + uint8_t opcode; + uint8_t buf[kMCUMaxRecvSize]; + size_t len; +}; + +static bool gIsMCUInitialized = false; +static struct task_event mcu_gate; +static struct task_event mcu_packet_arrived; +static struct task_event mcu_packet_consumed; +static bool mcu_recv_valid; +static struct McuRecvPacket mcu_recv; + +static int mcu_send_command(int opcode, uint8_t *data, size_t data_len); +static int mcu_set_sil(int action); +static int mcu_set_bs(int data0, int data1); // data1 == -1 if unused. +static int mcu_get_version(char *version, size_t length); + +static int mcu_task(void *arg); +static int mcu_send_packet(MCUOpCode opcode, uint8_t *data, size_t length); +static int mcu_read_packet(MCUOpCode *outOpcode, uint8_t *outData, size_t maxLen, size_t *outLen); +static int mcu_read_response(MCUOpCode *outOpcode, uint8_t *outData, size_t maxLen, size_t *outLen); +static unsigned long crc_ccitt(unsigned long crc, unsigned char* p, unsigned long len); + +int mcu_init(void) +{ + int ret = -1; + char version[kMCUMaxRecvSize]; + + uart_hw_init_extended(MCU_SERIAL_PORT, kMCUBaudRate, 8, PARITY_NONE, 1); + ret = uart_hw_set_rx_buf(MCU_SERIAL_PORT, true, kMCUFifoSize); + if (ret != 0) panic("mcu_init() uart_hw_set_rx_buf failed"); + + // send break to resync stream + uart_send_break(MCU_SERIAL_PORT, true); + task_sleep(kMCUWordPeriodUS * 2); // at least one word + uart_send_break(MCU_SERIAL_PORT, false); + + event_init(&mcu_gate, EVENT_FLAG_AUTO_UNSIGNAL, true); + event_init(&mcu_packet_arrived, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(&mcu_packet_consumed, EVENT_FLAG_AUTO_UNSIGNAL, false); + task_start(task_create("mcu", &mcu_task, NULL, kMCUTaskStackSize)); + + // first, retrieve MCU version string + ret = mcu_get_version(version, sizeof(version)); + + // constant slow-blink: device is booting + if (ret == 0) { + ret = mcu_set_sil(kMCUSILAction_SlowFlash); + } + + // record and report whether MCU was successfully initialized + gIsMCUInitialized = (ret == 0); + if (gIsMCUInitialized) { + dprintf(DEBUG_INFO, "MCU version: %s\n", version); + } else { + dprintf(DEBUG_CRITICAL, "mcu_init() failed\n"); + } + + return ret; +} + +int mcu_start_recover(void) +{ + int ret = -1; + + event_wait(&mcu_gate); + // constant fast-blink: plug into iTunes + if (gIsMCUInitialized) { + ret = mcu_set_sil(kMCUSILAction_FastFlash); + } + event_signal(&mcu_gate); + + return ret; +} + +int mcu_start_boot(void) +{ + int ret = -1; + + event_wait(&mcu_gate); + // constant slow-blink: device is booting + if (gIsMCUInitialized) { + ret = mcu_set_sil(kMCUSILAction_SlowFlash); + } + event_signal(&mcu_gate); + + return ret; +} + +int mcu_set_passthrough_mode(bool on) +{ + int ret = -1; + + if (gIsMCUInitialized) { + event_wait(&mcu_gate); + if (on) { + ret = mcu_set_bs(kMCUBSControl_EnterTestMode, -1); + if (ret != 0) goto exit; + ret = mcu_set_bs(kMCUBSControl_PassthroughMode, -1); + if (ret != 0) goto exit; + } else { + ret = mcu_set_bs(kMCUBSControl_Reset, -1); + } + exit: + if (ret != 0) { + dprintf(DEBUG_CRITICAL, "mcu_set_passthrough_mode %d failed\n", on); + } + event_signal(&mcu_gate); + } + + return ret; +} + +int mcu_send_info_frames(bool on) +{ + int ret = -1; + + if (gIsMCUInitialized) { + event_wait(&mcu_gate); + ret = mcu_set_bs(kMCUBSControl_InfoFrameEnable, on ? 1 : 0); + event_signal(&mcu_gate); + if (ret != 0) { + dprintf(DEBUG_CRITICAL, "mcu_send_info_farmes %d failed\n", on); + } + } + + return ret; +} + +int mcu_quiesce_uart(void) +{ + int ret = -1; + + ret = uart_hw_set_rx_buf(MCU_SERIAL_PORT, false, kMCUFifoSize); + if (ret != 0) + panic("uart can not be put into polling mode!"); + return ret; +} +static int mcu_send_command(int command, uint8_t *data, size_t data_len) +{ + int retries = kMCUSendAttempts; + int not_now_retries = kMCUNotNowAttempts; + int ret = -1; + + do { + ret = mcu_send_packet(command, data, data_len); + if (ret != 0) continue; + + uint8_t opcode; + ret = mcu_read_response(&opcode, NULL, 0, NULL); + if (ret != 0) continue; + if (opcode != kMCUOpCode_Ack) ret = -1; + if (opcode == kMCUOpCode_NakNotNow) { + // MCU isn't in the right state for this command. Allow + // more time than usual for this transient state to pass. + if (--not_now_retries > 0) { + task_sleep(kMCUNotNowDelayUS); + continue; + } else { + break; + } + } + } while ((ret != 0) && (--retries > 0)); + + return ret; +} + +static int mcu_set_sil(int action) +{ + uint8_t data = action; + return mcu_send_command(kMCUOpCode_SILControl, &data, 1); +} + +static int mcu_set_bs(int data0, int data1) +{ + uint8_t buf[2] = { data0, data1 }; + return mcu_send_command(kMCUOpCode_BlueSteelControl, buf, data1 >= 0 ? 2 : 1); +} + +static int mcu_get_version(char *version, size_t length) +{ + int ret; + + ret = mcu_send_packet(kMCUOpCode_GetVersion, NULL, 0); + if (ret != 0) return ret; + + uint8_t opcode; + size_t outLength; + ret = mcu_read_response(&opcode, (uint8_t *)version, length, &outLength); + if (ret != 0) return ret; + if (opcode != kMCUOpCode_Ack) return -1; + + if (version) version[outLength-1] = 0; + + return 0; +} + +static int mcu_task(void *arg) +{ + struct McuRecvPacket new_recv; + bzero(&new_recv, sizeof(new_recv)); + for (;;) { + int ret = mcu_read_packet(&new_recv.opcode, + new_recv.buf, + sizeof(new_recv.buf), + &new_recv.len); + if (ret != 0) continue; + // Process uninteresting packets here. + if (new_recv.opcode == kMCUOpCode_DebugData) { +#if PRINT_MCU_DEBUG + size_t i; + dprintf(DEBUG_INFO, "mcu: \""); + for (i = 0; i < new_recv.len; ++i) + dprintf(DEBUG_INFO, "%c", new_recv.buf[i]); + dprintf(DEBUG_INFO, "\"\n"); +#endif + continue; + } + if (!MCUOpCode_IsAckOrNak(new_recv.opcode)) continue; + // Signal packet arrival. + memcpy(&mcu_recv, &new_recv, sizeof(mcu_recv)); + mcu_recv_valid = true; + event_signal(&mcu_packet_arrived); + // Wait for packet consumption. + while (mcu_recv_valid) { + event_wait(&mcu_packet_consumed); + } + } + return 0; +} + +static int mcu_send_packet(MCUOpCode opcode, uint8_t *payload, size_t length) +{ + if (length > 0xFFFF) return -1; + + uint16_t crc = 0xffff; + uint8_t header[6] = { 'S', 't', opcode, 0x01, (length >> 8) & 0xFF, length & 0xFF }; + + dprintf(DEBUG_SPEW, "mcu_send_packet 0x%02x\n", opcode); + + for (unsigned i = 0; i < sizeof(header); i++) { + uart_putc(MCU_SERIAL_PORT, header[i]); + } + for (unsigned i = 0; i < length; i++) { + uart_putc(MCU_SERIAL_PORT, payload[i]); + } + + crc = crc_ccitt(crc, header, sizeof(header)); + crc = crc_ccitt(crc, payload, length); + + uart_putc(MCU_SERIAL_PORT, (crc >> 8) & 0xFF); + uart_putc(MCU_SERIAL_PORT, crc & 0xFF); + + return 0; +} + +static int mcu_read_response(MCUOpCode *outOpcode, uint8_t *outData, size_t maxLen, size_t *outLen) +{ + // wait at most a second + utime_t timeout = system_time() + kMCUResponseTimeout; + + // Wait for a packet. + while (!mcu_recv_valid) { + utime_t now = system_time(); + if (now >= timeout) { + dprintf(DEBUG_INFO, "mcu response timeout\n"); + return -1; + } + event_wait_timeout(&mcu_packet_arrived, timeout - now); + } + + dprintf(DEBUG_SPEW, "received mcu packet type %#x\n", mcu_recv.opcode); + if (outOpcode != NULL) *outOpcode = mcu_recv.opcode; + if (outData) memcpy(outData, mcu_recv.buf, maxLen < mcu_recv.len ? maxLen : mcu_recv.len); + if (outLen) *outLen = mcu_recv.len; + if (mcu_recv.len > maxLen) { + dprintf(DEBUG_SPEW, "mcu packet exceeds maxLen (%d vs %d)\n", + (int) mcu_recv.len, (int) maxLen); + } + mcu_recv_valid = false; + event_signal(&mcu_packet_consumed); + return 0; +} + +static int mcu_read_packet(MCUOpCode *outOpcode, uint8_t *outData, size_t maxLen, size_t *outLen) +{ + utime_t timeout = system_time() + kMCUReadTimeoutUS; + int ret = -1; + size_t offset = 0; + size_t length = 0; + uint16_t crc = 0xffff; + + for (;;) { + int ch; + for (;;) { + ch = uart_getc(MCU_SERIAL_PORT, false); + if (ch >= 0) break; + if (system_time() >= timeout) goto exit; + task_sleep(kMCUReadSleepUS); + } + + if (offset == 0) { + if (ch != 'S') continue; + } else if (offset == 1) { + if (ch != 't') { + offset = (ch == 'S') ? 1 : 0; + continue; + } + } else if (offset == 2) { + if (outOpcode != NULL) *outOpcode = ch; + } else if (offset == 3) { + // ignore sequence number + } else if (offset == 4) { + length = (ch & 0xFF) << 8; + } else if (offset == 5) { + length |= (ch & 0xFF); + } else if (offset < (length + 6)) { + if ((maxLen + 6) > offset) { + outData[offset-6] = ch; + } + } else if ((offset - (length + 6)) == 0) { + if (((crc >> 8) & 0xFF) != ch) { + dprintf(DEBUG_INFO, "mcu checksum failure\n"); + goto exit; + } + } else if ((offset - (length + 6)) == 1) { + if ((crc & 0xFF) != ch) { + dprintf(DEBUG_INFO, "mcu checksum failure\n"); + goto exit; + } + + if (outLen != NULL) *outLen = (maxLen < length) ? maxLen : length; + ret = 0; + goto exit; + } + + if (offset < (length + 6)) { + uint8_t b = ch; + crc = crc_ccitt(crc, &b, sizeof(b)); + } + offset++; + } + + dprintf(DEBUG_INFO, "mcu read timeout\n"); + + exit: + return ret; +} + +const int order = 16; +const unsigned long polynom = 0x1021; + +static unsigned long crc_ccitt(unsigned long crc, unsigned char* p, unsigned long len) +{ + // fast bit by bit algorithm without augmented zero bytes. + // does not use lookup table, suited for polynom orders between 1...32. + + unsigned long i, j, c, bit; + + unsigned long crchighbit = (unsigned long)1<<(order-1); + + for (i=0; i>=1) { + + bit = crc & crchighbit; + crc<<= 1; + if (c & j) + bit ^= crchighbit; + if (bit) + crc ^= polynom; + } + } + + return crc; +} + +#if WITH_MENU + +static int mcu_send_raw(int command, uint8_t *data, int data_len) +{ + int ret; + uint8_t opcode; + ret = mcu_send_packet(command, data, data_len); + if (ret != 0) { + printf("mcu_send_packet failed: %d\n", ret); + return ret; + } + ret = mcu_read_response(&opcode, NULL, 0, NULL); + if (ret != 0) { + printf("mcu_read_response failed: %d\n", ret); + return ret; + } + return 0; +} + +static int do_mcu(int argc, struct cmd_arg *args) +{ + if (!gIsMCUInitialized) { + if (0 == mcu_init()) { + printf("WARNING: mcu not previously initialized"); + } else { + printf("ERROR: unable to initialize mcu"); + return -1; + } + } + + if ((argc > 1) && !strcmp(args[1].str, "version")) + { + char version[32]; + if (mcu_get_version(version, sizeof(version)) == 0) { + printf("%s\n", version); + } + return 0; + } + + if ((argc > 2) && !strcmp(args[1].str, "sil")) + { + int action = kMCUSILAction_Invalid; + + if (!strcmp(args[2].str, kMCUSILAction_OffStr)) action = kMCUSILAction_Off; + else if (!strcmp(args[2].str, kMCUSILAction_OnStr)) action = kMCUSILAction_On; + else if (!strcmp(args[2].str, kMCUSILAction_SlowStr)) action = kMCUSILAction_SlowFlash; + else if (!strcmp(args[2].str, kMCUSILAction_FastStr)) action = kMCUSILAction_FastFlash; + else if (!strcmp(args[2].str, kMCUSILAction_1BlinkStr)) action = kMCUSILAction_1Blink; + else if (!strcmp(args[2].str, kMCUSILAction_3BlinksStr)) action = kMCUSILAction_3Blinks; + + if (action != kMCUSILAction_Invalid) + { + return mcu_set_sil(action); + } + } + + if ((argc > 2) && !strcmp(args[1].str, "bs")) + { + int action = kMCUBSControl_Invalid; + int extra = -1; + + if (!strcmp(args[2].str, kMCUBSControl_ResetStr)) action = kMCUBSControl_Reset; + else if (!strcmp(args[2].str, kMCUBSControl_EnterTestModeStr)) action = kMCUBSControl_EnterTestMode; + else if (!strcmp(args[2].str, kMCUBSControl_PassthroughModeStr)) action = kMCUBSControl_PassthroughMode; + else if (!strcmp(args[2].str, kMCUBSControl_InfoFrameEnableStr) && argc > 3) { + action = kMCUBSControl_InfoFrameEnable; + extra = args[3].u; + } + + if (action != kMCUBSControl_Invalid) + { + return mcu_set_bs(action, extra); + } + + } + + if ((argc > 2) && !strcmp(args[1].str, "raw")) + { + int i; + uint8_t command = args[2].u; + uint8_t data[8]; + size_t data_len = argc - 3; + if (data_len > sizeof(data)) { + printf("Max %zu raw bytes\n", sizeof(data) + 1); + return -1; + } + for (i = 3; i < argc; ++i) data[i - 3] = args[i].u; + return mcu_send_raw(command, data, data_len); + } + + printf("%s version\n", args[0].str); + printf("%s sil [%s|%s|%s|%s|%s|%s]\n", args[0].str, + kMCUSILAction_OffStr, kMCUSILAction_OnStr, kMCUSILAction_SlowStr, kMCUSILAction_FastStr, + kMCUSILAction_1BlinkStr, kMCUSILAction_3BlinksStr); + printf("%s bs [%s|%s|%s|%s]\n", args[0].str, + kMCUBSControl_ResetStr, kMCUBSControl_EnterTestModeStr, kMCUBSControl_PassthroughModeStr, kMCUBSControl_InfoFrameEnableStr); + printf("%s raw ...\n", args[0].str); + + return -1; +} + +MENU_COMMAND_DEVELOPMENT(mcu, do_mcu, "MCU control", NULL); + +#endif diff --git a/drivers/apple/mcu/rules.mk b/drivers/apple/mcu/rules.mk new file mode 100644 index 0000000..27fe76d --- /dev/null +++ b/drivers/apple/mcu/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2009 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MCU=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/mcu.o + diff --git a/drivers/apple/oscar/include/drivers/oscar/oscar.h b/drivers/apple/oscar/include/drivers/oscar/oscar.h new file mode 100644 index 0000000..56cf9c6 --- /dev/null +++ b/drivers/apple/oscar/include/drivers/oscar/oscar.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#pragma once + +#define OSCAR_ROM_BAUDRATE 1500000 +#define OSCAR_CONSOLE_BAUDRATE (OSCAR_ROM_BAUDRATE / 26) /* close to 57600 */ + +/* N56 dev */ +#define POWER_GPIO_OSCAR_RESET (5) /* GPIO6 */ +#define OSCAR_SERIAL_PORT (8) diff --git a/drivers/apple/oscar/oscar.c b/drivers/apple/oscar/oscar.c new file mode 100644 index 0000000..e9696cc --- /dev/null +++ b/drivers/apple/oscar/oscar.c @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +static int oscar_main(int argc, struct cmd_arg *args); +static int oscar_validate(addr_t addres, size_t length); +static int oscar_init(void); +static int oscar_upload(addr_t addres, size_t length); +static void oscar_console(void); + +MENU_COMMAND_DEBUG(oscar, oscar_main, "Boot an attached Oscar coprocessor", NULL); + + +static int +oscar_main(int argc, struct cmd_arg *args) +{ + addr_t addr = 0; + size_t len = 0; + + addr = env_get_uint("loadaddr", (uintptr_t)DEFAULT_LOAD_ADDRESS); + len = env_get_uint("filesize", 0); + + if (len == 0) { + printf("must upload firmware first\n"); + return -1; + } + if (oscar_validate(addr, len) < 0) { + return -1; + } + + /* XXX sanity-check firmware header image bytes */ + + if (oscar_init() != 0) + return -1; + + if (oscar_upload(addr, len) != 0) + return -1; + + oscar_console(); + + return 0; +} + +static int +oscar_validate(addr_t address, size_t length) +{ + /* image must be at least header + vector table long */ + if (length <= (16 + 64)) { + printf("firmware too small\n"); + return -1; + } + + /* check magic numbers */ + if ((*(uint8_t *)address & 0x3f) != 0x1a) { + printf("bad firmware magic number\n"); + return -1; + } + + unsigned crc_len = *(uint32_t *)(address + 4) * 4; + if ((crc_len + 16) > length) { + printf("firmware truncated (header says %d, received %zu)\n", crc_len + 128, length); + return -1; + } + return 0; +} + +static int +oscar_init(void) +{ + unsigned limit; + + /* DEBUG_EN should be high already */ + + /* assert oscar reset */ + power_set_gpio(POWER_GPIO_OSCAR_RESET, 1 /* output */, 0 /* reset active low */); + + /* wait 100us */ + spin(100); + + /* configure serial port for upload */ + uart_hw_init_extended(OSCAR_SERIAL_PORT, OSCAR_ROM_BAUDRATE, 8, PARITY_NONE, 1); + + /* drain FIFO */ + for (limit = 0; limit < 1000; limit++) + if (uart_getc(OSCAR_SERIAL_PORT, false) < 0) + break; + + /* power should be on already */ + + /* release oscar reset */ + power_set_gpio(POWER_GPIO_OSCAR_RESET, 1 /* output */, 1 /* reset inactive high */); + + /* spin sending 0x80 and waiting for 0x3f */ + for (limit = 0; limit < 100000; limit++) { + + /* this will stall once the FIFO is full, so we will be paced by the port */ + uart_putc(OSCAR_SERIAL_PORT, 0x80); + + /* look for a character */ + int c = uart_getc(OSCAR_SERIAL_PORT, false); + if (c == 0x3f) + return 0; + if (c != -1) + printf("oscar: ignoring 0x%02x\n", c); + } + printf("failed to get handshake from Oscar ROM\n"); + return -1; +} + +static int +oscar_check(void) +{ + /* + * ROM sends Fx if it's unhappy, where + * x is normally 0..5. + */ + int c = uart_getc(OSCAR_SERIAL_PORT, false); + + /* no response, but keep waiting */ + if (c == -1) + return 0; + + switch (c) { + case -1: + /* no data */ + case 'O': + case 'K': + case '\r': + /* the ROM sends these after a successful upload */ + default: + return 0; /* keep waiting */ + + case 'X': + /* app has started */ + return 1; + + case 'F': + /* ROM error message */ + break; + } + + /* decode the ROM error */ + int reason = -1; + for (unsigned limit = 0; limit < 5000; limit++) { + reason = uart_getc(OSCAR_SERIAL_PORT, false); + if (reason != -1) + break; + task_yield(); + } + printf("upload failed: "); + switch (reason) { + case '0': + printf("invalid magic number\n"); + break; + case '1': + printf("invalid image size\n"); + break; + case '2': + printf("invalid header CRC\n"); + break; + case '3': + printf("invalid image CRC\n"); + break; + case '4': + printf("invalid image base address\n"); + break; + case -1: + printf("error code not received\n"); + break; + default: + /* not a recognised error, must be application data */ + return 1; + } + return -1; +} + +static int +oscar_upload(addr_t address, size_t length) +{ + const uint8_t *p = (const uint8_t *)address; + + printf("sending %zu bytes...\n", length); + + /* upload */ + while (length--) { + + uart_putc(OSCAR_SERIAL_PORT, *p++); + + if (oscar_check() < 0) + return -1; + task_yield(); + + } + + /* wait a little while for a late error, and to let the firmware start */ + for (unsigned i = 0; i < 1000000; i++) { + switch (oscar_check()) { + case 0: + break; + case 1: + goto done; + default: + case -1: + return -1; + } + task_yield(); + } + + printf("timed out waiting for app handshake\n"); + return -1; + +done: + /* enable clk32 - cannot be done safely until firmware on Oscar2 disables the reset function */ + power_set_gpio(POWER_GPIO_OSCAR_RESET, 2 /* 32kHz */, 0); + + return 0; +} + +static void +oscar_console(void) +{ + /* configure serial port for console */ + uart_hw_init_extended(OSCAR_SERIAL_PORT, OSCAR_CONSOLE_BAUDRATE, 8, PARITY_NONE, 1); + + printf("\nOscar console log - hit any key to exit.\n\n"); + + for (;;) { + task_yield(); + if (debug_getchar_nowait() != -1) { + printf("\n\n"); + return; + } + int c = uart_getc(OSCAR_SERIAL_PORT, false); + if (c != -1) + putchar(c); + } +} + + +#endif // defined(WITH_MENU) && WITH_MENU diff --git a/drivers/apple/oscar/rules.mk b/drivers/apple/oscar/rules.mk new file mode 100644 index 0000000..5d84d18 --- /dev/null +++ b/drivers/apple/oscar/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/oscar.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/apple/prc/prc.c b/drivers/apple/prc/prc.c new file mode 100644 index 0000000..31ff773 --- /dev/null +++ b/drivers/apple/prc/prc.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include "prc.h" + + +static const uint32_t prc_prcLUT[256] = + {0, 64, 128, 192, 256, 320, 384, 448, + 512, 576, 640, 704, 768, 832, 896, 960, + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, + 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984, + 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, + 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, + 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, + 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, + 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, + 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, + 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, + 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, + 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, + 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, + 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, + 8192, 8256, 8320, 8384, 8448, 8512, 8576, 8640, + 8704, 8768, 8832, 8896, 8960, 9024, 9088, 9152, + 9216, 9280, 9344, 9408, 9472, 9536, 9600, 9664, + 9728, 9792, 9856, 9920, 9984, 10048, 10112, 10176, + 10240, 10304, 10368, 10432, 10496, 10560, 10624, 10688, + 10752, 10816, 10880, 10944, 11008, 11072, 11136, 11200, + 11264, 11328, 11392, 11456, 11520, 11584, 11648, 11712, + 11776, 11840, 11904, 11968, 12032, 12096, 12160, 12224, + 12288, 12352, 12416, 12480, 12544, 12608, 12672, 12736, + 12800, 12864, 12928, 12992, 13056, 13120, 13184, 13248, + 13312, 13376, 13440, 13504, 13568, 13632, 13696, 13760, + 13824, 13888, 13952, 14016, 14080, 14144, 14208, 14272, + 14336, 14400, 14464, 14528, 14592, 14656, 14720, 14784, + 14848, 14912, 14976, 15040, 15104, 15168, 15232, 15296, + 15360, 15424, 15488, 15552, 15616, 15680, 15744, 15808, + 15872, 15936, 16000, 16064, 16128, 16192, 16256, 16320 }; + +void prc_write_reg(uint32_t reg, uint32_t value); +uint32_t prc_read_reg(uint32_t reg); + +void prc_init(uint32_t display_width, uint32_t display_height) +{ + // WPC Configuration defined in ADBE TRM v0.1.14. Section 4.4 + + // Active Region Start + prc_write_reg(PRC_CONFIG_ACTIVE_REGION_START_OFFSET, + PRC_CONFIG_ACTIVE_REGION_START_START_X_INSRT(0) | + PRC_CONFIG_ACTIVE_REGION_START_START_Y_INSRT(0)); + + // Active Region Size + prc_write_reg(PRC_CONFIG_ACTIVE_REGION_SIZE_OFFSET, + PRC_CONFIG_ACTIVE_REGION_SIZE_WIDTH_INSRT(display_width) | + PRC_CONFIG_ACTIVE_REGION_SIZE_HEIGHT_INSRT(display_height)); + + //force update due to double buffer registers + prc_write_reg(PRC_CONFIG_UPDATE_CONTROL_OFFSET, 0x3); +} + +void prc_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl) +{ + for (int i = 0; i < PRC_LUT_REG_COUNT; i++) { + prc_write_reg(PRC_LUT_REG_OFFSET(i), prc_prcLUT[i % 256]); + } + + for (int i = 0; i < PRC_LUT_LAST_COUNT; i ++) { + prc_write_reg(PRC_LUT_LAST_OFFSET_V1(i), 16384); + } +} + +void prc_write_reg(uint32_t reg, uint32_t value) +{ + (*(volatile u_int32_t *)(PRC_BASE_ADDR + reg)) = value; +} + +uint32_t prc_read_reg(uint32_t reg) +{ + return (*(volatile u_int32_t *)(PRC_BASE_ADDR + reg)); +} diff --git a/drivers/apple/prc/prc.h b/drivers/apple/prc/prc.h new file mode 100644 index 0000000..34f6e65 --- /dev/null +++ b/drivers/apple/prc/prc.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_PRC_H +#define __APPLE_PRC_H + +#include +#include + +#ifdef DISP0_PRC_BASE_ADDR +#define PRC_BASE_ADDR DISP0_PRC_BASE_ADDR +#endif +#ifndef PRC_BASE_ADDR +#error "PRC base addr for AppleWhitePointCorrection (PRC) Block is not defined" +#endif + +#include SUB_PLATFORM_SPDS_HEADER(prc) + +#endif //__APPLE_PRC_H \ No newline at end of file diff --git a/drivers/apple/prc/rules.mk b/drivers/apple/prc/rules.mk new file mode 100644 index 0000000..90be16c --- /dev/null +++ b/drivers/apple/prc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PRC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/prc.o \ No newline at end of file diff --git a/drivers/apple/reconfig/reconfig.c b/drivers/apple/reconfig/reconfig.c new file mode 100644 index 0000000..18f6ddf --- /dev/null +++ b/drivers/apple/reconfig/reconfig.c @@ -0,0 +1,491 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(aop_global) +#include + +static const uint64_t *reconfig_bases; + +static const uint64_t reconfig_bases_darwin[MAX_STAGE] = { + [AWAKE_AOP_DDR_PRE] = AWAKE_AOP_DDR_PRE_BASE_ADDR, + [AWAKE_AOP_DDR_POST] = AWAKE_AOP_DDR_POST_BASE_ADDR, + [AOP_DDR_S2R_AOP_PRE] = AOP_DDR_S2R_AOP_PRE_BASE_ADDR, + [AOP_DDR_S2R_AOP_POST] = AOP_DDR_S2R_AOP_POST_BASE_ADDR, + [S2R_AOP_AOP_DDR_PRE] = S2R_AOP_AOP_DDR_PRE_BASE_ADDR, + [S2R_AOP_AOP_DDR_POST] = S2R_AOP_AOP_DDR_POST_BASE_ADDR, + [AOP_DDR_AWAKE_PRE] = AOP_DDR_AWAKE_PRE_BASE_ADDR, + [AOP_DDR_AWAKE_POST] = AOP_DDR_AWAKE_POST_BASE_ADDR +}; + +static const uint64_t reconfig_bases_diags[MAX_STAGE] = { + [AWAKE_AOP_DDR_PRE] = AWAKE_AOP_DDR_PRE_DIAGS_BASE_ADDR, + [AWAKE_AOP_DDR_POST] = AWAKE_AOP_DDR_POST_DIAGS_BASE_ADDR, + [AOP_DDR_S2R_AOP_PRE] = AOP_DDR_S2R_AOP_PRE_DIAGS_BASE_ADDR, + [AOP_DDR_S2R_AOP_POST] = AOP_DDR_S2R_AOP_POST_DIAGS_BASE_ADDR, + [S2R_AOP_AOP_DDR_PRE] = S2R_AOP_AOP_DDR_PRE_DIAGS_BASE_ADDR, + [S2R_AOP_AOP_DDR_POST] = S2R_AOP_AOP_DDR_POST_DIAGS_BASE_ADDR, + [AOP_DDR_AWAKE_PRE] = AOP_DDR_AWAKE_PRE_DIAGS_BASE_ADDR, + [AOP_DDR_AWAKE_POST] = AOP_DDR_AWAKE_POST_DIAGS_BASE_ADDR +}; + +static const uint64_t reconfig_max_size[MAX_STAGE] = { + [AWAKE_AOP_DDR_PRE] = AWAKE_AOP_DDR_PRE_MAX_SIZE, + [AWAKE_AOP_DDR_POST] = AWAKE_AOP_DDR_POST_MAX_SIZE, + [AOP_DDR_S2R_AOP_PRE] = AOP_DDR_S2R_AOP_PRE_MAX_SIZE, + [AOP_DDR_S2R_AOP_POST] = AOP_DDR_S2R_AOP_POST_MAX_SIZE, + [S2R_AOP_AOP_DDR_PRE] = S2R_AOP_AOP_DDR_PRE_MAX_SIZE, + [S2R_AOP_AOP_DDR_POST] = S2R_AOP_AOP_DDR_POST_MAX_SIZE, + [AOP_DDR_AWAKE_PRE] = AOP_DDR_AWAKE_PRE_MAX_SIZE, + [AOP_DDR_AWAKE_POST] = AOP_DDR_AWAKE_POST_MAX_SIZE +}; + +static const char *reconfig_stage_names[] = { + [AWAKE_AOP_DDR_PRE] = "AWAKE_AOP_DDR_PRE", + [AWAKE_AOP_DDR_POST] = "AWAKE_AOP_DDR_POST", + [AOP_DDR_S2R_AOP_PRE] = "AOP_DDR_S2R_AOP_PRE", + [AOP_DDR_S2R_AOP_POST] = "AOP_DDR_S2R_AOP_POST", + [S2R_AOP_AOP_DDR_PRE] = "S2R_AOP_AOP_DDR_PRE", + [S2R_AOP_AOP_DDR_POST] = "S2R_AOP_AOP_DDR_POST", + [AOP_DDR_AWAKE_PRE] = "AOP_DDR_AWAKE_PRE", + [AOP_DDR_AWAKE_POST] = "AOP_DDR_AWAKE_POST", + [MAX_STAGE] = "MAX_STAGE" +}; + +static write_command_t write_commands[MAX_STAGE]; +static uint32_t reconfig_count[MAX_STAGE] = {0}; +static bool reconfig_committed[MAX_STAGE]; +static bool reconfig_locked; + +static void validate_stage(reconfig_stage_t stage) +{ + ASSERT(stage < MAX_STAGE); + ASSERT(!reconfig_committed[stage]); + ASSERT(!reconfig_locked); +} + +static void bounds_check_stage(reconfig_stage_t stage) +{ + dprintf(DEBUG_SPEW, "%s: Stage %d, Count 0x%x, Max 0x%x\n", __FUNCTION__, stage, reconfig_count[stage]*4, (unsigned int)reconfig_max_size[stage]); + + if (reconfig_count[stage] * 4 >= reconfig_max_size[stage]) { + panic("Writing past the reserved region for config sequence, Stage %d, Count 0x%x, Max 0x%x", + stage, reconfig_count[stage]*4, reconfig_max_size[stage]); + } +} + +static void reconfig_write_pending(reconfig_stage_t stage) +{ + write_command_t *wc = &write_commands[stage]; + + if (wc->in_progress) { + commit_write_command(stage, wc); + } +} + +/* Write Command: + Cmd, Offsets, Data + Cmd + 31 6 5 2 1 0 + | Base Address[35:10] | Regs | D | 1 | + Offset0 + | Offset i+3[9:2] | Offset i+2[9:2] | Offset i+1[9:2] | Offset i+0[9:2] | + Offset1 + | Offset i+3[9:2] | Offset i+2[9:2] | Offset i+1[9:2] | Offset i+0[9:2] | + Offset2 + | Offset i+3[9:2] | Offset i+2[9:2] | Offset i+1[9:2] | Offset i+0[9:2] | + Offset3 + | Offset i+3[9:2] | Offset i+2[9:2] | Offset i+1[9:2] | Offset i+0[9:2] | + Data0 + . + . + . + . + Data15 (64 bit data requires 64 bit alignment) +*/ +static void commit_write_command(reconfig_stage_t stage, write_command_t *wc) +{ + uint32_t cmd = WRITE_COMMAND; + cmd |= ((wc->address >> 10) << 6); + cmd |= ((wc->is_reg64 & 0x1)<<1); + cmd |= RECONFIG_NUMBER_OF_REGS(wc->value_count); + + dprintf(DEBUG_SPEW, "%s: cmd 0x%x\n", __FUNCTION__, cmd); + + // Store the command + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = cmd; + + // Store the address offsets + uint32_t ii = 0; + while (ii <= (wc->value_count-1)/4 ) + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = wc->offsets[ii++]; + + // 8 byte alignment + if (wc->is_reg64 && !ALIGNED_64(reconfig_count[stage])) { + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = ALIGNMENT_MARKER; + } + + // Store the write values + ii = 0; + while (ii < wc->value_count) { + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)wc->values[ii]; + if (wc->is_reg64) { + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)(wc->values[ii] >> 32); + } + ii++; + } + bounds_check_stage(stage); + + // Clear out structure and use for next write command + memset((void *)wc, 0, sizeof(write_command_t)); +} + +/* Queue up individual write commands into a data structure. When we get to 16 entries or + need to enter different type of command such as POLL, DELAY... commit the structure + in the write command format required for reconfig engine into memory + + - Check if valid stage + - If we have a valid write data struct check if the new command fits into it + - If it doesnt fit (i.e not in the 1 KB block), commit the previous sequence + to memory, and clean up the data structure + - If it does fit continue + - Check if the write command is going to be first one + - If it is setup the data structure + - If not add the value to the data structure, and check if the struture is full + (i.e 16 values). If full commmit the sequence to memory, and clean up for + next usage. +*/ +void reconfig_command_write(reconfig_stage_t stage, uint64_t addr, uint64_t value, uint32_t is_reg64) +{ + ASSERT(is_reg64 || value <= UINT32_MAX); + ASSERT((addr & 0x3) == 0); + validate_stage(stage); + write_command_t *wc = &write_commands[stage]; + + dprintf(DEBUG_SPEW, "%s: Stage %s, Address 0x%llx, Value 0x%llx, reg64 %s\n", __FUNCTION__, reconfig_stage_names[stage], addr, value, is_reg64 ? "true":"false"); + + if (wc->in_progress) { + // if address and new address are not in a 1 KB range commit + if ((wc->address & ALIGNMENT_MASK_1KB) != (addr & ALIGNMENT_MASK_1KB)) { + commit_write_command(stage, wc); + } else if (wc->is_reg64 != is_reg64) { + // Also check if the sizes are the same + commit_write_command(stage, wc); + } + } + + if (!wc->in_progress) { + // setting up the first time + wc->in_progress = true; + wc->address = addr; + wc->is_reg64 = is_reg64; + wc->offsets[wc->value_count] = WRITE_OFFSETS(addr, wc->value_count); + wc->values[wc->value_count] = value; + wc->value_count++; + } else { + wc->values[wc->value_count] = value; + wc->offsets[wc->value_count / 4] |= WRITE_OFFSETS(addr, wc->value_count); + wc->value_count++; + + if (wc->value_count == MAX_WRITE_REGS) { + commit_write_command(stage, wc); + } + } +} + + +/* Read Command: + Cmd, Offset, Data Mask, Expected Data + Cmd + 31 6 5 4 3 2 1 0 + | Base Address[35:10] | D | 0 0 0 1 0 | + Offset0 + 31 17 16 15 8 7 0 + | XXXX XXXX | E | Re-try Cnt | Offset [9:2] | + Data Mask (64 bit data requires 64 bit alignment) + Expected Data (64 bit data requires 64 bit alignment) +*/ +void reconfig_command_read(reconfig_stage_t stage, uint64_t addr, uint64_t value, uint64_t mask, uint32_t retry_cnt, uint32_t is_reg64) +{ + ASSERT(is_reg64 || value <= UINT32_MAX); + ASSERT((retry_cnt & ~0xff) == 0); + ASSERT((addr & 0x3) == 0); + validate_stage(stage); + reconfig_write_pending(stage); + + dprintf(DEBUG_SPEW, "%s: Stage %s, Address 0x%llx, Value 0x%llx, Mask 0x%llx, Retry Cnt 0x%x, Retry Enable %s, is_reg64 %s\n", __FUNCTION__, reconfig_stage_names[stage], addr, value, mask, retry_cnt, retry_cnt ? "true":"false", is_reg64 ? "true":"false"); + + uint32_t cmd = READ_COMMAND; + uint32_t retry_enable = retry_cnt ? 1:0; + cmd |= ((is_reg64 & 0x1) << 5); + cmd |= ((addr >> 10) << 6); // 1 KB Base address + + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = cmd; + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = ((retry_enable & 0x1) << 16) | ((retry_cnt & 0xff) << 8) | ((addr & 0x3FF) >> 2); + + if (is_reg64) { + if (!ALIGNED_64(reconfig_count[stage])) { + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = ALIGNMENT_MARKER; + } + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)(mask); + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)(mask>32); + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)(value); + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)(value>>32); + } else { + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)mask; + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = (uint32_t)(value); + } + bounds_check_stage(stage); +} + +/* Delay Command: + Cmd + 31 6 5 4 3 2 1 0 + | Count[25:0] | 0 0 0 1 0 0 | +*/ +void reconfig_command_delay(reconfig_stage_t stage, uint32_t delay) +{ + ASSERT((delay & ~0x3FFFFFF) == 0); + validate_stage(stage); + reconfig_write_pending(stage); + + dprintf(DEBUG_SPEW, "%s: Stage %s, Delay 0x%x cycles\n", __FUNCTION__, reconfig_stage_names[stage], delay); + + uint32_t cmd = DELAY_COMMAND; + cmd |= ((delay & 0x3FFFFFF) << 6); + + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = cmd; + bounds_check_stage(stage); +} + +/* "NOP" Command: + Cmd: 0x44, same as delay cmd +*/ +void reconfig_command_nop(reconfig_stage_t stage) +{ + validate_stage(stage); + reconfig_write_pending(stage); + + dprintf(DEBUG_SPEW, "%s: Stage %s NOP command\n", __FUNCTION__, reconfig_stage_names[stage]); + + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = 0x00000040 | NOP_COMMAND; + bounds_check_stage(stage); +} + +void reconfig_command_raw(reconfig_stage_t stage, const uint32_t *cmd, uint32_t cmdItems) +{ + validate_stage(stage); + reconfig_write_pending(stage); + + // align to 64 bits. The config sequences script also makes an assumption + // that it starts on a 64 bit aligned location + if (reconfig_count[stage] % 2) + reconfig_command_nop(stage); + + for (uint32_t jj = 0; jj < cmdItems; jj++) { + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = cmd[jj]; + } + bounds_check_stage(stage); + + dprintf(DEBUG_SPEW, "%s: Committed raw command to memory\n", __FUNCTION__); +} + +void reconfig_init(enum boot_target target) +{ + addr_t table_base; + + switch (target) { + case BOOT_DARWIN: + reconfig_bases = reconfig_bases_darwin; + table_base = AOP_CFG_TABLE; + break; + case BOOT_DIAGS: + reconfig_bases = reconfig_bases_diags; + table_base = AOP_CFG_TABLE_DIAGS; + break; + default: + panic("unknown target: %d", target); + } + + // Set the CFG table pointer and CFG table entries + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_TABLE_BASE_OFFSET) = (uint32_t)(table_base & AOP_GLOBAL_SOC_CFG_TABLE_BASE_ADDR_UMASK); + volatile uint32_t *aop_cfg_base = (volatile uint32_t *)table_base; + *aop_cfg_base++ = (uint32_t)(reconfig_bases[AWAKE_AOP_DDR_PRE] >> 4); + *aop_cfg_base++ = (uint32_t)(reconfig_bases[AWAKE_AOP_DDR_POST] >> 4); + *aop_cfg_base++ = (uint32_t)(reconfig_bases[AOP_DDR_S2R_AOP_PRE] >> 4); + *aop_cfg_base++ = (uint32_t)(reconfig_bases[AOP_DDR_S2R_AOP_POST] >> 4); + *aop_cfg_base++ = (uint32_t)(reconfig_bases[S2R_AOP_AOP_DDR_PRE] >> 4); + *aop_cfg_base++ = (uint32_t)(reconfig_bases[S2R_AOP_AOP_DDR_POST] >> 4); + *aop_cfg_base++ = (uint32_t)(reconfig_bases[AOP_DDR_AWAKE_PRE] >> 4); + *aop_cfg_base++ = (uint32_t)(reconfig_bases[AOP_DDR_AWAKE_POST] >> 4); + + dprintf(DEBUG_SPEW, "Initialize Config table and bases for reconfig stages\n"); +} + +void reconfig_commit(reconfig_stage_t stage) +{ + validate_stage(stage); + reconfig_write_pending(stage); + + uint32_t params = 0; + + switch (stage) { + case AWAKE_AOP_DDR_PRE: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_PREAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_PREAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_PREAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_PREAMBLE_INSRT(AWAKE_AOP_DDR_PRE); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_OFFSET) = params; + break; + case AWAKE_AOP_DDR_POST: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_POSTAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_POSTAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_POSTAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_POSTAMBLE_INSRT(AWAKE_AOP_DDR_POST); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AWAKE_TO_AOP_DDR_OFFSET) = params; + break; + case AOP_DDR_S2R_AOP_PRE: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_PREAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_PREAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_PREAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_PREAMBLE_INSRT(AOP_DDR_S2R_AOP_PRE); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_OFFSET) = params; + break; + case AOP_DDR_S2R_AOP_POST: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_POSTAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_POSTAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_POSTAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_POSTAMBLE_INSRT(AOP_DDR_S2R_AOP_POST); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_S2R_AOP_OFFSET) = params; + break; + case S2R_AOP_AOP_DDR_PRE: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_PREAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_PREAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_PREAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_PREAMBLE_INSRT(S2R_AOP_AOP_DDR_PRE); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_OFFSET) = params; + break; + case S2R_AOP_AOP_DDR_POST: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_POSTAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_POSTAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_POSTAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_POSTAMBLE_INSRT(S2R_AOP_AOP_DDR_POST); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_S2R_AOP_TO_AOP_DDR_OFFSET) = params; + break; + case AOP_DDR_AWAKE_PRE: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_PREAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_PREAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_PREAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_PREAMBLE_INSRT(AOP_DDR_AWAKE_PRE); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_OFFSET) = params; + break; + case AOP_DDR_AWAKE_POST: + params = rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_OFFSET); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_POSTAMBLE_ENABLE_UMASK); + params &= (~AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_POSTAMBLE_UMASK); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_POSTAMBLE_ENABLE_INSRT(1); + params |= AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_POSTAMBLE_INSRT(AOP_DDR_AWAKE_POST); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_AOP_DDR_TO_AWAKE_OFFSET) = params; + break; + case MAX_STAGE: panic("Unknown reconfig stage"); + } + // End Command + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = 0; + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = SEQUENCE_END; + rRECONFIG_RAM_BASE(reconfig_bases[stage], reconfig_count[stage]++) = SEQUENCE_END; + + // XXX Lock entries + // + + reconfig_committed[stage] = true; + + dprintf(DEBUG_SPEW, "%s: Enabled and committed stage %s, using 0x%x of 0x%llx bytes\n", + __FUNCTION__, reconfig_stage_names[stage], reconfig_count[stage] * 4, reconfig_max_size[stage]); +} + +void reconfig_lock(enum boot_target target) +{ + uint32_t lock_reg; + addr_t lock_base; + addr_t lock_limit; + + // Can't lock twice + ASSERT(!reconfig_locked); + ASSERT(rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_WRITE_LOCK_OFFSET) == 0); + + // It's possible to lock down a sub-region of the reconfig program. Since we aren't + // currently modifying any of the sequences after iBoot finishes, we're locking down + // the entire portion of SRAM used for reconfig engine tables and programs. + // Details on locking down a portion of the program are in section 2.1.8 of + // https://seg-docs.ecs.apple.com/projects/maui//release/specs/Apple/Top/Maui_boot_sequences.pdf + switch (target) { + case BOOT_DARWIN: + lock_base = AOP_RECONFIG_REGION_BASE_ADDR; + lock_limit = lock_base + AOP_RECONFIG_REGION_USED - 1; + break; + case BOOT_DIAGS: + lock_base = AOP_RECONFIG_REGION_DIAGS_BASE_ADDR; + lock_limit = lock_base + AOP_RECONFIG_REGION_DIAGS_USED - 1; + break; + default: + panic("unknown target %d", target); + } + + lock_reg = AOP_GLOBAL_SOC_CFG_LOCKABLE_SRAM_BASE_INSRT(lock_base >> 6); + lock_reg |= AOP_GLOBAL_SOC_CFG_LOCKABLE_SRAM_LIMIT_INSRT(lock_limit >> 6); + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_LOCKABLE_SRAM_OFFSET) = lock_reg; + + // Disable writes to the lock region register + rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_WRITE_LOCK_OFFSET) = 1; + RELEASE_ASSERT(rAOP_GLOBAL(AOP_GLOBAL_SOC_CFG_WRITE_LOCK_OFFSET) == 1); +} + +void dump_reconfig(reconfig_dump_t option) +{ + if ((option == REGION_ONLY) || (option == REGION_AND_COMMAND)) { + dprintf(DEBUG_INFO, "\nReconfig region bases\n"); + dprintf(DEBUG_INFO, "~~~~~~~~~~~~~~~~~~~~~~\n"); + dprintf(DEBUG_INFO, "AOP_CFG_TABLE 0x%9llx\n", AOP_CFG_TABLE); + dprintf(DEBUG_INFO, "AWAKE_AOP_DDR_PRE_BASE_ADDR 0x%9llx\n", reconfig_bases[AWAKE_AOP_DDR_PRE]); + dprintf(DEBUG_INFO, "AWAKE_AOP_DDR_POST_BASE_ADDR 0x%9llx\n", reconfig_bases[AWAKE_AOP_DDR_POST]); + dprintf(DEBUG_INFO, "AOP_DDR_S2R_AOP_PRE_BASE_ADDR 0x%9llx\n", reconfig_bases[AOP_DDR_S2R_AOP_PRE]); + dprintf(DEBUG_INFO, "AOP_DDR_S2R_AOP_POST_BASE_ADDR 0x%9llx\n", reconfig_bases[AOP_DDR_S2R_AOP_POST]); + dprintf(DEBUG_INFO, "S2R_AOP_AOP_DDR_PRE_BASE_ADDR 0x%9llx\n", reconfig_bases[S2R_AOP_AOP_DDR_PRE]); + dprintf(DEBUG_INFO, "S2R_AOP_AOP_DDR_POST_BASE_ADDR 0x%9llx\n", reconfig_bases[S2R_AOP_AOP_DDR_POST]); + dprintf(DEBUG_INFO, "AOP_DDR_AWAKE_PRE_BASE_ADDR 0x%9llx\n", reconfig_bases[AOP_DDR_AWAKE_PRE]); + dprintf(DEBUG_INFO, "AOP_DDR_AWAKE_POST_BASE_ADDR 0x%9llx\n", reconfig_bases[AOP_DDR_AWAKE_POST]); + } + + if ((option == COMMAND_ONLY) || (option == REGION_AND_COMMAND)) { + for (uint32_t ii = 0; ii < MAX_STAGE; ii++) { + dprintf(DEBUG_INFO, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + dprintf(DEBUG_INFO, "\n%s\n", reconfig_stage_names[ii]); + for (uint32_t jj = 0; jj < reconfig_count[ii]; jj++) { + dprintf(DEBUG_INFO, "0x%08x ", rRECONFIG_RAM_BASE(reconfig_bases[ii], jj++)); + dprintf(DEBUG_INFO, "0x%08x ", rRECONFIG_RAM_BASE(reconfig_bases[ii], jj++)); + dprintf(DEBUG_INFO, "0x%08x ", rRECONFIG_RAM_BASE(reconfig_bases[ii], jj++)); + dprintf(DEBUG_INFO, "0x%08x\n", rRECONFIG_RAM_BASE(reconfig_bases[ii], jj++)); + } + dprintf(DEBUG_INFO, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); + } + } +} diff --git a/drivers/apple/reconfig/rules.mk b/drivers/apple/reconfig/rules.mk new file mode 100644 index 0000000..fc1470d --- /dev/null +++ b/drivers/apple/reconfig/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_RECONFIG=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/reconfig.o diff --git a/drivers/apple/sep/include/drivers/sep/sep_client.h b/drivers/apple/sep/include/drivers/sep/sep_client.h new file mode 100644 index 0000000..de06016 --- /dev/null +++ b/drivers/apple/sep/include/drivers/sep/sep_client.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _SEP_CLIENT_H +#define _SEP_CLIENT_H + +#define SEP_NONCE_SIZE (20) /* in bytes */ + +int32_t sep_client_get_nonce(uint8_t *buffer); +int32_t sep_client_seed_aes(); + +#endif /* _SEP_CLIENT_H */ diff --git a/drivers/apple/sep/rules.mk b/drivers/apple/sep/rules.mk new file mode 100644 index 0000000..82d33c0 --- /dev/null +++ b/drivers/apple/sep/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_HW_SEP=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/sep_client.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include \ No newline at end of file diff --git a/drivers/apple/sep/sep_client.c b/drivers/apple/sep/sep_client.c new file mode 100644 index 0000000..da65c9d --- /dev/null +++ b/drivers/apple/sep/sep_client.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2012, 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include + +#ifdef DEBUG +#define print(x,y...) dprintf(DEBUG_INFO,x,##y) +#else +#define print(x,y...) (void)0 +#endif + +#define PING_TIMEOUT (1 * 1000 * 1000) /* in usecs */ +#define GEN_NONC_TIMEOUT (1 * 1000 * 1000) /* in usecs */ +#define GET_NONC_TIMEOUT (1 * 1000 * 1000) /* in usecs */ +#define NONC_HSH_TIMEOUT (2 * 1000 * 1000) /* in usecs */ +#define GEN_DPA_TIMEOUT (2 * 1000 * 1000) /* in usecs */ + +/* XXX Endpoint and Opcode defines goes away once we have a header in SDK */ +#define kEndpoint_SEPROM (255) + +enum { + kOpCode_Ping = 1, + kOpCode_GenerateNonce = 3, + kOpCode_GetNonceWord = 4, + kOpCode_SendDpa = 15, + kOpCode_Ack = 101, + kOpCode_ReportGeneratedNonce = 103, + kOpCode_ReportNonceWord = 104, + kOpCode_ReportSentDpa = 115, + kOpCode_LogRaw = 201, + kOpCode_LogPrintable = 202, + kOpCode_AnnouceStatus = 210, + kOpCode_ReportPanic = 255 +}; + +enum { + kMsg_Ping = 0, + kMsg_Ack, + kMsg_GenerateNonce, + kMsg_ReportGeneratedNonce, + kMsg_GetNonceWord, + kMsg_ReportNonceWord, + kMsg_LogRaw, + kMsg_LogPrintable, + kMsg_AnnounceStatus, + kMsg_ReportPanic, + kMsg_SendDpa, + kMsg_ReportSentDpa, +}; + +static const struct sep_message_info { + uint8_t opcode; + uint8_t tag; + const char opcode_string[255]; +} _sep_msgs_info[] = { + [kMsg_Ping] = { kOpCode_Ping, 'p', "Ping" }, + [kMsg_Ack] = { kOpCode_Ack, 'a', "Ack" }, + [kMsg_GenerateNonce] = { kOpCode_GenerateNonce, 'g', "GenerateNonce" }, + [kMsg_ReportGeneratedNonce] = { kOpCode_ReportGeneratedNonce, 'r', "ReportGeneratedNonce" }, + [kMsg_GetNonceWord] = { kOpCode_GetNonceWord, 'n', "GetNonceWord" }, + [kMsg_ReportNonceWord] = { kOpCode_ReportNonceWord, 0, "ReportNonceWord" }, + [kMsg_LogRaw] = { kOpCode_LogRaw, 0, "LogRaw" }, + [kMsg_LogPrintable] = { kOpCode_LogPrintable, 0, "LogPrintable" }, + [kMsg_AnnounceStatus] = { kOpCode_AnnouceStatus, 0, "AnnouceStatus" }, + [kMsg_ReportPanic] = { kOpCode_ReportPanic, 0, "ReportPanic" }, + [kMsg_SendDpa] = { kOpCode_SendDpa, 0, "SendDpa" }, + [kMsg_ReportSentDpa] = { kOpCode_ReportSentDpa, 0, "ReportSentDpa" }, +}; + +/* SEP mbox message format */ +struct sep_message { + uint8_t endpoint; + uint8_t tag; + uint8_t opcode; + uint8_t param; + uint32_t data; +} __attribute__((packed)); + +static struct sep_message _sep_recv_msg; +static struct sep_message _sep_send_msg; +static struct sep_message _sep_pending_recv_msg; +static uint8_t _sep_nonce_buffer[SEP_NONCE_SIZE] __attribute__((aligned(4))); +static int _sep_client_reader(uint32_t wait_timeout); +static int _sep_client_seed_aes(); + +static const char * _sep_get_opcode_string(uint8_t opcode) +{ + uint32_t i; + + for(i = 0; i < sizeof(_sep_msgs_info)/sizeof(_sep_msgs_info[0]); i++) { + if (opcode == _sep_msgs_info[i].opcode) return _sep_msgs_info[i].opcode_string; + } + + return NULL; +} + +static void _sep_create_message(struct sep_message *msg, uint8_t msg_type, uint8_t tag, uint8_t param) +{ + msg->endpoint = kEndpoint_SEPROM; + msg->opcode = _sep_msgs_info[msg_type].opcode; + msg->tag = ((tag != 0) ? tag : _sep_msgs_info[msg_type].tag); + msg->param = param; + msg->data = 0; + print("%s: msg %x %s(%d) %d\n", __FUNCTION__, msg->endpoint, _sep_get_opcode_string(msg->opcode), msg->opcode, msg->param); +} + +static int _sep_client_get_nonce() +{ + uint32_t idx; + uint32_t zero = 0; + int ret = -1; + bool is_zero = true; + + /* Setup AKF SEP */ + print("sep_client: starting akf\n"); + akf_start_sep(); + + /* Generate SEP Nonce */ + print("sep_client: sending generate nonce\n"); + _sep_create_message(&_sep_send_msg, kMsg_GenerateNonce, 0, 0); + if (akf_send_mbox(KFW_SEP, *((uint64_t *)&_sep_send_msg), A7IOP_NO_WAIT)) { + dprintf(DEBUG_CRITICAL, "Unable to send GEN_NONCE to SEP mailbox, abandoning...\n"); + goto exit; + } + if (_sep_client_reader(GEN_NONC_TIMEOUT)) { + dprintf(DEBUG_CRITICAL, "SEP not respoding to GEN_NONCE, abandoning...\n"); + goto exit; + } + + print("sep_client: nonce size: %d\n", _sep_pending_recv_msg.data); + RELEASE_ASSERT(_sep_pending_recv_msg.data == (SEP_NONCE_SIZE * 8)); + if (_sep_pending_recv_msg.data != (SEP_NONCE_SIZE * 8)) { + dprintf(DEBUG_CRITICAL, "Invalid nonce size: %d, abandoning...\n", _sep_pending_recv_msg.data); + goto exit; + } + + /* Retrieve SEP Nonce, word by word */ + for (idx = 0; idx < (SEP_NONCE_SIZE/sizeof(uint32_t)); idx++) { + print("sep_client: sending get nonce word %d\n", idx); + _sep_create_message(&_sep_send_msg, kMsg_GetNonceWord, 0, idx); + if (akf_send_mbox(KFW_SEP, *((uint64_t *)&_sep_send_msg), A7IOP_NO_WAIT)) { + dprintf(DEBUG_CRITICAL, "Unable to send GET_NONCE to SEP mailbox, abandoning...\n"); + goto exit; + } + if (_sep_client_reader(GET_NONC_TIMEOUT)) { + dprintf(DEBUG_CRITICAL, "SEP not respoding to GET_NONCE, abandoning...\n"); + goto exit; + } + print("sep_client: got nonce word %d: %08x\n", idx, _sep_pending_recv_msg.data); + memcpy(&_sep_nonce_buffer[idx * sizeof(_sep_pending_recv_msg.data)], (void *)&_sep_pending_recv_msg.data, sizeof(_sep_pending_recv_msg.data)); + if (memcmp(&_sep_pending_recv_msg.data, &zero, sizeof(zero))) { + is_zero = false; + } + } + + if (is_zero) { + panic("SEP sent all 0's as nonce"); + } + + ret = 0; +exit: + print("sep_client: stopping akf\n"); + + /* Cleanup */ + akf_stop(KFW_SEP); + + print("sep_client: finished\n"); + + return ret; +} + +static int _sep_client_seed_aes() +{ + int ret = -1; + /* Setup AKF SEP */ + print("sep_client: starting akf\n"); + akf_start_sep(); + + /* Send Dpa*/ + print("sep_client: sending dpa\n"); + _sep_create_message(&_sep_send_msg, kMsg_SendDpa, 0, 0); + if (akf_send_mbox(KFW_SEP, *((uint64_t *)&_sep_send_msg), A7IOP_NO_WAIT)) { + dprintf(DEBUG_CRITICAL, "Unable to send SendDpa to SEP mailbox, abandoning...\n"); + goto exit; + } + if (_sep_client_reader(GEN_DPA_TIMEOUT)) { + dprintf(DEBUG_CRITICAL, "SEP not respoding to SendDpa, abandoning...\n"); + goto exit; + } + + ret = 0; +exit: + print("sep_client: stopping akf\n"); + + /* Cleanup */ + akf_stop(KFW_SEP); + + print("sep_client: finished\n"); + + return ret; +} + +static int _sep_client_reader(uint32_t wait_timeout) +{ + uint32_t ret; + bool received_message = false; + + for (;;) { + ret = akf_recv_mbox(KFW_SEP, (uint64_t *)&_sep_recv_msg, wait_timeout); + + print("%s: msg %x %s(%d) %d 0x%08x\n", __FUNCTION__, _sep_recv_msg.endpoint, _sep_get_opcode_string(_sep_recv_msg.opcode), _sep_recv_msg.opcode, _sep_recv_msg.param, _sep_recv_msg.data); + + switch(_sep_recv_msg.opcode) { + case kOpCode_LogRaw: + case kOpCode_LogPrintable: + case kOpCode_AnnouceStatus: + case kOpCode_ReportPanic: + break; + + default: + memcpy(&_sep_pending_recv_msg, &_sep_recv_msg, sizeof(_sep_pending_recv_msg)); + received_message = true; + break; + } + bzero(&_sep_recv_msg, sizeof(_sep_recv_msg)); + + if (received_message) + break; + } + + return ret; +} + + +/* sep_client_get_nonce + * + * Sends a mbox to SEP to generate a nonce. + * It then sends multile mboxs to retrieve nonce (word by word) + * + * Return 0 for success, -1 for fail + */ +int32_t sep_client_get_nonce(uint8_t *buffer) +{ + RELEASE_ASSERT(buffer != NULL); + + if (_sep_client_get_nonce()) { + dprintf(DEBUG_CRITICAL, "Failed to retrieve SEP nonce\n"); + return -1; + } + + memcpy(buffer, _sep_nonce_buffer, SEP_NONCE_SIZE); + + return 0; +} + +/* sep_client_seed_aes + * + * Send DPA command to SEP in order to seed the various AES blocks + * + * Return 0 for success, -1 for fail + */ +int32_t sep_client_seed_aes() +{ + if (_sep_client_seed_aes()) { + dprintf(DEBUG_CRITICAL, "Failed to seed AES block\n"); + return -1; + } + + return 0; +} diff --git a/drivers/apple/sha2/rules.mk b/drivers/apple/sha2/rules.mk new file mode 100644 index 0000000..ddc1e17 --- /dev/null +++ b/drivers/apple/sha2/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_SHA1=1 + +MODULES += \ + drivers/sha1 + +ALL_OBJS += \ + $(LOCAL_DIR)/sha2.o diff --git a/drivers/apple/sha2/sha2.c b/drivers/apple/sha2/sha2.c new file mode 100644 index 0000000..2657d20 --- /dev/null +++ b/drivers/apple/sha2/sha2.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#include "sha2.h" + +#if (BYTE_ORDER != LITTLE_ENDIAN) +#error "Sha2 driver currently requires a little endian machine" +#endif + +#define SHA2_BYTE_REVERSE 0 + +/* Eventually these move to a global header, but for now we're not + * exporting anything beyond sha1_hw_calculate */ +#define SHA_160 160 +#define SHA_224 224 +#define SHA_256 256 +#define SHA_384 384 +#define SHA_512 512 + +static void sha_hw_calculate(int sha_type, const void *buf, size_t len, + u_int32_t *result) +{ + const u_int32_t *wptr; + const u_int8_t *bptr; + u_int32_t cmd = SHA2_MSGCTL_FIRST, final[3]; + size_t blkwords = (sha_type < SHA_384) ? 16 : 32, hashsize; + unsigned datawords, words, cur_word, index, type, blocks=0; + u_int64_t totalbits = len*8; + + clock_gate(CLK_SHA2, true); + + /* XXX use CDMA? */ + + /* PIO sequence: + - configure the registers + - load the first block + - issue rdy command with first flag + - loop: + - load next block + - issue rdy command + - poll til rdy clears + - wait for hash idle + - read hash value + */ + switch (sha_type) { + case SHA_160: + type = SHA_TYPE_160; + hashsize = 5; + break; + case SHA_224: + type = SHA_TYPE_224; + hashsize = 7; + break; + case SHA_256: + type = SHA_TYPE_256; + hashsize = 8; + break; + case SHA_384: + type = SHA_TYPE_384; + hashsize = 12; + break; + case SHA_512: + type = SHA_TYPE_512; + hashsize = 16; + break; + default: + panic("Unknown sha type\n"); + } + + rSHA2_CONFIG = SHA2_CONFIG_TYPE(type) | SHA2_PIO_MODE; + + datawords = len / 4; + final[0] = 0x80; + if (len & 3) { + bptr = (const u_int8_t *)(buf + (datawords*4)); + int leftover = len & 3; + if (leftover == 1) + final[0] = bptr[0] | (1 << 15); + else if (leftover == 2) + final[0] = bptr[0] | ((unsigned)bptr[1] << 8) | (1 << 23); + else if (leftover == 3) + final[0] = bptr[0] | ((unsigned)bptr[1] << 8) | ((unsigned)bptr[2] << 16) | (1 << 31); + } +#if SHA2_BYTE_REVERSE + final[0] = swap32(final[0]); + final[1] = totalbits >> 32; + final[2] = totalbits & 0xffffffff; +#else + /* Big endian 64-bit bit-length */ + final[1] = swap32(totalbits >> 32); + final[2] = swap32(totalbits & 0xffffffff); +#endif + + wptr = (u_int32_t *)buf; + /* This loop takes care of all the complete words in the data, + performing the SHA on any complete message blocks along the + way. */ + words = (datawords + 3 + (blkwords - 1)) & ~(blkwords - 1); + for (index = 0, cur_word = 0; cur_word < words; cur_word++, buf+=4) { + if (cur_word < datawords) { +#if WITH_UNALIGNED_MEM +#if SHA2_BYTE_REVERSE + rSHA2_MSGBLK(index) = swap32(*wptr); + wptr++; +#else + rSHA2_MSGBLK(index) = *wptr++; /* rely on little endianness */ +#endif +#else + rSHA2_MSGBLK(index) = (buf[0] << 0)|(buf[1] << 8)|(buf[2] << 16)|(buf[3] << 24); +#endif + } else { + if (cur_word == datawords) + rSHA2_MSGBLK(index) = final[0]; + else if (cur_word == words-2) + rSHA2_MSGBLK(index) = final[1]; + else if (cur_word == words-1) + rSHA2_MSGBLK(index) = final[2]; + else + rSHA2_MSGBLK(index) = 0; + } + if (++index == blkwords) { + index = 0; + rSHA2_MSGCTL = SHA2_MSGCTL_RDY | cmd; + if (cmd) + cmd = 0; + else + while (rSHA2_MSGCTL & SHA2_MSGCTL_RDY); + blocks++; + } + } + + while (rSHA2_STATUS & SHA2_HASH_BUSY); + + for (index = 0; index < hashsize; index++, result++) +#if SHA2_BYTE_REVERSE + *result = swap32(rSHA2_HASH(index)); +#else + *result = rSHA2_HASH(index); /* again exploit little endianness */ +#endif + + clock_gate(CLK_SHA2, false); +} + +void sha1_hw_calculate(const void *buf, size_t len, u_int32_t *result) +{ + sha_hw_calculate(SHA_160, buf, len, result); +} + +#if 0 +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +int do_sha(int argc, struct cmd_arg *args) +{ + u_int8_t hash[64]; + u_int32_t cnt, algo = SHA_160; + void *buf; + size_t len; + + if (argc < 3) { + printf("not enough arguments.\n"); + printf("%s [160,224,256,384,512]
\n", args[0].str); + printf(" default is SHA-1 (160)\n"); + return -1; + } + + if (argc == 4) { + algo = args[1].u; + buf = (void *)args[2].u; + len = args[3].u; + } else { + buf = (void *)args[1].u; + len = args[2].u; + } + if (!security_allow_memory(buf, len)) { + printf("Permission Denied\n"); + return -1; + } + + memset(hash, 0, sizeof(hash)); + sha_hw_calculate(algo, buf, len, (u_int32_t *)hash); + printf("sha-%d of %p for 0x%08lx bytes: ", algo, buf, len); + for (cnt = 0; cnt < (algo/8); cnt++) + printf("%02x%s", hash[cnt]); + printf("\n"); + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(sha, do_sha, "SHA hash of memory", NULL); + +#endif +#endif diff --git a/drivers/apple/sha2/sha2.h b/drivers/apple/sha2/sha2.h new file mode 100644 index 0000000..1c110e8 --- /dev/null +++ b/drivers/apple/sha2/sha2.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_SHA2_H +#define __APPLE_SHA2_H + +#include + +#define rSHA2_VERSION (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x04)) +#define rSHA2_CONFIG (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x08)) + +#define SHA2_PIO_MODE (0 << 0) +#define SHA2_DMA_MODE (1 << 0) +#define SHA2_CONFIG_TYPE(_t) (((_t) & 0x7) << 4) + +#define SHA_TYPE_160 (1) +#define SHA_TYPE_224 (2) +#define SHA_TYPE_256 (3) +#define SHA_TYPE_384 (4) +#define SHA_TYPE_512 (5) + +#define rSHA2_MSGCTL (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x0C)) + +#define SHA2_MSGCTL_RDY (1 << 0) +#define SHA2_MSGCTL_FIRST (1 << 1) +#define SHA2_MSGCTL_LAST (1 << 2) + +#define rSHA2_STATUS (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x10)) + +#define SHA2_HASH_BUSY (1 << 0) + +#define rSHA2_IRQ (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x14)) + +#define SHA2_IRQ_DONE (1 << 0) +#define SHA2_IRQ_LAST (1 << 1) + +#define rSHA2_IRQEN (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x18)) + +#define SHA2_IRQEN_DONE (1 << 0) +#define SHA2_IRQEN_LAST (1 << 1) + +#define rSHA2_DMACTL (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x1C)) + +#define SHA2_DMACTL_START (1 << 0) +#define SHA2_DMACTL_BURSTSIZE(_s) (((_s) & 0x7) << 4) + +#define rSHA2_DMATOP (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x20)) +#define rSHA2_HASH(_h) (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x40 + ((_h) * 4))) +#define rSHA2_MSGBLK(_m) (*(volatile u_int32_t *)(SHA2_BASE_ADDR + 0x80 + ((_m) * 4))) + +#endif /* ! __APPLE_SHA2_H */ diff --git a/drivers/apple/shmcon/rules.mk b/drivers/apple/shmcon/rules.mk new file mode 100644 index 0000000..ee669ab --- /dev/null +++ b/drivers/apple/shmcon/rules.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +ifeq ($(filter $(PRODUCT),LLB iBSS),) + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_SHM_CONSOLE=1 + +MODULES += \ + drivers/apple/shmcon + +ALL_OBJS += \ + $(LOCAL_DIR)/shmcon.o + +endif + diff --git a/drivers/apple/shmcon/shmcon.c b/drivers/apple/shmcon/shmcon.c new file mode 100644 index 0000000..1b2fddb --- /dev/null +++ b/drivers/apple/shmcon/shmcon.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#if WITH_CONSISTENT_DBG +#include +#endif +#include +#include +#include +#include +#include + +#ifndef COHERENT_JTAG +/* Default to coherent, should be true for most AP's */ +#define COHERENT_JTAG 1 +#endif + +#ifndef SHARED_CONSOLE_BASE +#define SHARED_CONSOLE_BASE PANIC_BASE +#define SHARED_CONSOLE_SIZE PANIC_SIZE +#endif + +#ifndef SHMCON_NAME +#define SHMCON_NAME "AP-iBoot" +#endif + +#define SHMCON_MAGIC 'SHMC' +#define SHMCON_VERSION 2 +#define CBUF_IN 0 +#define CBUF_OUT 1 +#define INBUF_SIZE (SHARED_CONSOLE_SIZE / 16) +#define FULL_ALIGNMENT (64) + +#define FLAG_CACHELINE_32 1 +#define FLAG_CACHELINE_64 2 + +/* Defines to clarify the master/slave fields' use as circular buffer pointers */ +#define head_in sidx[CBUF_IN] +#define tail_in midx[CBUF_IN] +#define head_out midx[CBUF_OUT] +#define tail_out sidx[CBUF_OUT] + +/* TODO: get from device tree/target */ +#define NUM_CHILDREN 5 + +#define shmcon_barrier() arm_memory_barrier() + +#define WRAP_INCR(l, x) do{ (x)++; if((x) >= (l)) (x) = 0; } while(0) + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +struct shm_buffer_info { + uint64_t base; + uint32_t unused; + uint32_t magic; +}; + +struct shmcon_header { + uint32_t magic; + uint8_t version; + uint8_t children; /* number of child entries in child_ent */ + uint16_t flags; + uint64_t buf_paddr[2]; /* Physical address for buffers (in, out) */ + uint32_t buf_len[2]; + uint8_t name[8]; + + /* Slave-modified data - invalidate before read */ + uint32_t sidx[2] __attribute__((aligned (FULL_ALIGNMENT))); /* In head, out tail */ + + /* Master-modified data - clean after write */ + uint32_t midx[2] __attribute__((aligned (FULL_ALIGNMENT))); /* In tail, out head */ + + uint64_t child[0]; /* Physical address of child header pointers */ +}; + +static volatile struct shmcon_header *shmcon = NULL; +static uint8_t *shmbuf[2]; + +/* + * WARNING: This function invalidates all cache lines spanned + * by the range provided. It should only be used on memory + * that can safely be invalidated up to cache line rounding size. + */ +static void cache_line_invalidate(void *addr, size_t size) +{ + uintptr_t address = (uintptr_t)addr; + size_t shift; + + shift = address & ((1 << CPU_CACHELINE_SHIFT)-1); + address -= shift; + size += shift; + platform_cache_operation(CACHE_INVALIDATE, (void *)address, ROUNDUP(size, CPU_CACHELINE_SIZE)); +} + +int shmcon_getc(int port, bool wait) +{ + int c; + uint32_t head, tail, len; + + if (shmcon == NULL) + return -1; + + tail = shmcon->tail_in; + len = shmcon->buf_len[CBUF_IN]; + +#if !COHERENT_JTAG + cache_line_invalidate((void *)&shmcon->head_in, sizeof(shmcon->head_in)); +#endif + head = shmcon->head_in; + + if (head == tail) { + if (!wait) + return -1; + do { + task_yield(); +#if !COHERENT_JTAG + cache_line_invalidate((void *)&shmcon->head_in, sizeof(shmcon->head_in)); +#endif + head = shmcon->head_in; + } while (head == tail); + } +#if !COHERENT_JTAG + cache_line_invalidate(&shmbuf[CBUF_IN][tail], CPU_CACHELINE_SIZE); +#endif + c = shmbuf[CBUF_IN][tail]; + shmcon_barrier(); + WRAP_INCR(len, tail); + shmcon->tail_in = tail; +#if !COHERENT_JTAG + platform_cache_operation(CACHE_CLEAN, (void *)&shmcon->tail_in, ROUNDUP(sizeof(shmcon->tail_in), CPU_CACHELINE_SIZE)); +#endif + return c; + +} + +int shmcon_putc(int port, char c) +{ + uint32_t head, len; + + if (shmcon == NULL) + return -1; + + head = shmcon->head_out; + len = shmcon->buf_len[CBUF_OUT]; + + shmbuf[CBUF_OUT][head] = c; + shmcon_barrier(); +#if !COHERENT_JTAG + platform_cache_operation(CACHE_CLEAN, &shmbuf[CBUF_OUT][head], CPU_CACHELINE_SIZE); +#endif + WRAP_INCR(len, head); + shmcon->head_out = head; +#if !COHERENT_JTAG + platform_cache_operation(CACHE_CLEAN, (void *)&shmcon->head_out, ROUNDUP(sizeof(shmcon->head_out), CPU_CACHELINE_SIZE)); +#endif + return 0; +} + +int shmcon_puts(int port, const char *s) +{ + for ( ; *s; s++) + if (shmcon_putc(port, *s)) + break; + return 0; +} + +static int shmcon_reader_task(void *arg) +{ + for ( ; ; ) { + int c; + + c = shmcon_getc(0, true); + if (((DebugUartReady & kPowerNVRAMiBootDebugJtag) != 0) && (c >= 0)) { + debug_pushchar((char)c); + } + } + return 0; +} + +int shmcon_init(void) +{ + volatile struct shm_buffer_info *end; + size_t i, header_size; + uintptr_t buffer_base, buffer_end; + uint32_t num_children = NUM_CHILDREN; + + if (shmcon != NULL) + return 0; + + shmcon = (struct shmcon_header *)SHARED_CONSOLE_BASE; + header_size = sizeof(*shmcon) + (num_children * sizeof(shmcon->child[0])); + buffer_base = ROUNDUP((uintptr_t)(shmcon) + header_size, CPU_CACHELINE_SIZE); + buffer_end = SHARED_CONSOLE_BASE + SHARED_CONSOLE_SIZE - (sizeof(*end)); + + shmcon->magic = 0; + shmcon_barrier(); + platform_cache_operation(CACHE_CLEAN, (void *)&shmcon->magic, + ROUNDUP(sizeof(shmcon->magic), CPU_CACHELINE_SIZE)); + shmcon->buf_len[CBUF_IN] = INBUF_SIZE; + shmcon->buf_paddr[CBUF_IN] = buffer_base; + shmcon->buf_paddr[CBUF_OUT] = ROUNDUP(buffer_base + INBUF_SIZE, CPU_CACHELINE_SIZE); + for (i = 0; i < 2; i++) { + shmcon->midx[i] = 0; + shmcon->sidx[i] = 0; + shmbuf[i] = (uint8_t *)(uintptr_t)shmcon->buf_paddr[i]; + } + shmcon->buf_len[CBUF_OUT] = SHARED_CONSOLE_SIZE - ((uintptr_t)shmbuf[CBUF_OUT] - SHARED_CONSOLE_BASE) + - (sizeof(struct shm_buffer_info)); + memset((void *)shmcon->name, ' ', sizeof(shmcon->name)); + memcpy((void *)shmcon->name, SHMCON_NAME, MIN(sizeof(shmcon->name), strlen(SHMCON_NAME))); + cache_line_invalidate(shmbuf[CBUF_IN], INBUF_SIZE); + shmcon->version = SHMCON_VERSION; + shmcon->children = num_children; + for (i = 0; i < num_children; i++) + shmcon->child[i] = 0; +#if COHERENT_JTAG + shmcon->flags = 0; +#else + shmcon->flags = (CPU_CACHELINE_SIZE == 32) ? (FLAG_CACHELINE_32) : (FLAG_CACHELINE_64); +#endif + shmcon_barrier(); + shmcon->magic = SHMCON_MAGIC; + platform_cache_operation(CACHE_CLEAN, (void *)shmcon, ROUNDUP(header_size, CPU_CACHELINE_SIZE)); + end = (volatile struct shm_buffer_info *)buffer_end; + end->base = SHARED_CONSOLE_BASE; + end->unused = 0; + shmcon_barrier(); + end->magic = SHMCON_MAGIC; + platform_cache_operation(CACHE_CLEAN, (void *)end, ROUNDUP(sizeof(struct shm_buffer_info), CPU_CACHELINE_SIZE)); + +#if DEBUG_UART_ENABLE_DEFAULT + DebugUartReady |= kPowerNVRAMiBootDebugJtag; +#endif + + task_start(task_create("shmcon reader", shmcon_reader_task, (void *)NULL, 0x200)); + +#ifdef WITH_CONSISTENT_DBG + dbg_record_header_t hdr; + hdr.length = SHARED_CONSOLE_SIZE; + hdr.physaddr = SHARED_CONSOLE_BASE; + hdr.record_id = kDbgIdConsoleHeaderAP; + dbg_record_header_t *dbghdr = consistent_debug_register_header(hdr); + if (!dbghdr) { + dprintf(DEBUG_SPEW, "Unable to allocate consistent debug header for console.\n"); + } +#endif + return 0; +} + +int shmcon_set_child(uint64_t phys_address, uint32_t num) +{ + if (shmcon == NULL || num >= shmcon->children) + return -1; + + shmcon->child[num] = phys_address; + return 0; +} + diff --git a/drivers/apple/swifterpmu/power.c b/drivers/apple/swifterpmu/power.c new file mode 100644 index 0000000..38b59bc --- /dev/null +++ b/drivers/apple/swifterpmu/power.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include + +#include "power.h" + +static uint32_t boot_flags; + +static void write_pmu(uint32_t offset, uint32_t data) +{ + volatile uint32_t *addr = (uint32_t *)(SWIFTER_PMU_BASE + offset); + *addr = data; +} + +static uint32_t read_pmu(uint32_t offset) +{ + volatile uint32_t *addr = (uint32_t *)(SWIFTER_PMU_BASE + offset); + return *addr; +} + +bool charger_has_usb(int dock) +{ + return false; +} + +bool charger_has_firewire(int dock) +{ + return false; +} + +bool charger_has_external(int dock) +{ + return false; +} + +bool charger_has_batterypack(int dock) +{ + return false; +} + +void charger_clear_usb_state(void) +{ +} + +uint32_t charger_get_max_charge_current(int dock) +{ + return 1500; +} + +void charger_set_charging(int dock, uint32_t input_current_limit, uint32_t *charge_current_ma) +{ +} + +void charger_clear_alternate_usb_current_limit(void) +{ +} + +int charger_read_battery_level(uint32_t *milliVolts) +{ + return 5000; +} + +bool charger_charge_done(int dock) +{ + return true; +} + +void power_clr_events(int wake) +{ +} + +u_int32_t pmu_read_brick_id_level(void) +{ + return 5000; +} + +int power_get_rail_value(int rail, unsigned mv, u_int32_t *buffer) +{ + return -1; +} + +int power_get_buck_value(int buck, uint32_t mv, uint32_t *val) +{ + return -1; +} + +int power_convert_dwi_to_mv(int buck, u_int32_t dwival) +{ + return -1; +} + +void pmu_early_init(void) +{ + // Latch the power-on event(s) + boot_flags = read_pmu(SWIFTER_PMU_EVENT_REG); + // [or could we just let the OS driver recover them?] + dprintf(DEBUG_SPEW, "swifterpmu: boot_flags = %x\n", boot_flags); +} + +void pmu_setup(void) +{ + // Probably nothing to do for simulation +} + +void pmu_late_init(void) +{ + // Probably nothing to do for simulation +} + +void pmu_check_events(bool *powersupply_change_event, bool *button_event, bool *other_wake_event) +{ + *powersupply_change_event = false; + *button_event = false; + *other_wake_event = false; +} + +int power_get_boot_flag(void) +{ + return (boot_flags & SWIFTER_PMU_EVENT_HIB) ? kPowerBootFlagWarm : kPowerBootFlagCold; +} + +void pmu_will_resume(void) +{ + // store boot flag for OS use (re-use same NVRAM byte used for voltage between LLB and iBoot) + power_set_nvram(kPowerNVRAMiBootBootFlags0Key, boot_flags); +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +void pmu_set_backlight_enable(uint32_t backlight_level) +{ +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + if (key >= kPowerNVRAMPropertyCount) return -1; + + *data = read_pmu(SWIFTER_PMU_NVRAM_START + (key*4)) & 0xff; + return 0; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + if (key >= kPowerNVRAMPropertyCount) return -1; + + write_pmu(SWIFTER_PMU_NVRAM_START + (key*4), data); + return 0; +} + +void pmu_shutdown(void) +{ + // Write the "shutdown" register + write_pmu(SWIFTER_PMU_SHUTDOWN_REG, 1); +} + +void pmu_suspend(void) +{ + // Write the "suspend" register + write_pmu(SWIFTER_PMU_SUSPEND_REG, 1); +} + +utime_t power_get_calendar_time(void) +{ + return 0; +} + +void charger_print_status(void) +{ + +} diff --git a/drivers/apple/swifterpmu/power.h b/drivers/apple/swifterpmu/power.h new file mode 100644 index 0000000..3c06f66 --- /dev/null +++ b/drivers/apple/swifterpmu/power.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __SWIFTER_PMU_H +#define __SWIFTER_PMU_H + +#define SWIFTER_PMU_SHUTDOWN_REG 0x010 +#define SWIFTER_PMU_SUSPEND_REG 0x018 +#define SWIFTER_PMU_RESTART_REG 0x020 + +#define SWIFTER_PMU_NVRAM_START 0x100 + +#define SWIFTER_PMU_EVENT_REG 0x200 +#define SWIFTER_PMU_EVENT_HIB (1 << 0) +#define SWFITER_PMU_EVENT_HOME (1 << 1) + +#endif diff --git a/drivers/apple/swifterpmu/rules.mk b/drivers/apple/swifterpmu/rules.mk new file mode 100644 index 0000000..0420984 --- /dev/null +++ b/drivers/apple/swifterpmu/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_POWER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/power.o + +MODULES += \ + lib/power diff --git a/drivers/apple/voltage_knobs/include/drivers/voltage_knobs/knobs.h b/drivers/apple/voltage_knobs/include/drivers/voltage_knobs/knobs.h new file mode 100644 index 0000000..a3e5a05 --- /dev/null +++ b/drivers/apple/voltage_knobs/include/drivers/voltage_knobs/knobs.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_KNOBS_H +#define __APPLE_KNOBS_H + +#if defined(SUB_PLATFORM_S7002) +// PMU knobs only for M7 +#define CPU_KNOB_MAX 0 +#define GPU_KNOB_MAX 0 +#define SOC_KNOB_MAX 0 +#define PMU_KNOB_MAX 3 +#elif defined(SUB_PLATFORM_T7001) +// Last voltage, V5 could be unused, +// but all arrays in pmgr and cpuid +// have a value for it. +#define CPU_KNOB_MAX 6 +#define GPU_KNOB_MAX 4 +#define SOC_KNOB_MAX 2 +#define PMU_KNOB_MAX 3 +#else +#define CPU_KNOB_MAX 5 +#define GPU_KNOB_MAX 4 +#define SOC_KNOB_MAX 2 +#define PMU_KNOB_MAX 3 +#endif + + +#define KNOB_SIZE_BITS 10 + +// we are not expecting more than 8 knobs per unit +#define KNOBINDEX_ABSOLUTE_MAX 7 + +// buffer size to prepare NVRAM knob name +#define KNOB_NAME_MAXLEN 7 + +// the way knob is stored in PMU register (and in NVRAM too) +typedef struct +{ + union + { + struct + { + unsigned int knobVal : 8; + int isNegative : 1; + int isAbsolute : 1; + } bit; + uint16_t intval; + } u; +} knob_as_binary_t; + +#ifndef __abs +#define __abs(x) (((x) < 0) ? -(x) : (x)) +#endif + +// Note: a knob has 10 bits ASVVVVVVVV value +// A [0 - offset, 1 - absolute value] +// S [if A = 0, S = 1 means negative offset] +// VVVVVVVV - 8 bit knob value to apply + +#define KNOBNAMEPREFIX "knob" +#define KNOBNAMEFORMAT "knob%X%c" +#define KNOB_ABSOLUTE_CHAR "@" +// KNOB NVRAM variable format is name=value +// where name is knobIP +// I - knob index in hexadecimal [0...F] +// P - nameprefix from knob type definition + +// Knobs defined so far including their T7000 aliases: +// CPU 0 - kDVFM_STATE_IBOOT (2) * for CPU skippint kDVFM_STATE_BYPASS and kDVFM_STATE_SECUREROM as we have no control there +// CPU 1 - V0 +// CPU 2 - V1 kDVFM_STATE_VNOM +// CPU 3 - V2 +// CPU 4 - V3 kDVFM_STATE_VMAX / kDVFM_STATE_VBOOST +// +// CPU 0 +// CPU 1 +// +// GPU 0 +// GPU 1 +// GPU 2 +// GPU 3 +// +// PMU 0 - BUCK3 (1.8V) * DRAM 1.8V +// PMU 1 - BUCK4 (1.2V) * DRAM 1.2V +// PMU 2 - BUCK5 (0.95V) * SoC fixed rail + + +typedef enum +{ + kKnobTypeUnknown = 0, + kKnobTypeCPU, + kKnobTypeGPU, + kKnobTypeSOC, + kKnobTypePMU, + kKnobTypeInvalid, +} knob_types_e; + +typedef struct +{ + const char *visible_name; + char nameprefix; + knob_types_e defined_type; + uint32_t max_index; +} knob_type_description_t; + +// PMU has specific knobs.. +#define KNOB_PMU_DRAM_1V8 0 +#define KNOB_PMU_DRAM_1V2 1 +#define KNOB_PMU_SOC_FIXED 2 + +// array index should match enum value for indexed access +extern const knob_type_description_t all_knobs[]; + +// clean up PMU scratch registers on a cold boot as their state should be undefined +// it may be called from LLB or iBSS +void knobs_prepare_standby_storage(void); + +// called from LLB on a warm boot only +// for loading and appying voltage knobs from a standby storage +void knobs_load_from_standby_storage(void); + +// get knobs from NVRAM variables, convert them, and store in PMU scratch registers +// or do nothing if we are in LLB or iBSS +void knobs_update_PMU_registers(bool apply_to_hw); + +// request default value of a knob in units +bool knobs_get_default_val(knob_types_e type, uint8_t index, uint8_t *defaultValueUnits); + +// convert units to millivolts for specific knob +int knobs_convert_dwi_to_mv(knob_types_e type, uint8_t index, u_int32_t dwival); +// converts millivolts to units for specific knob +int knobs_convert_mv_to_dwi(knob_types_e type, uint8_t index, u_int32_t mv, u_int32_t *dwival); + +// search and load single knob from NV storage +bool knobs_load_knob_from_NVRAM(const char* knobName, knob_as_binary_t *knobValue); +// store single knob into NV storage +bool knobs_store_knob_in_NVRAM(const char* knobName, knob_as_binary_t *knobValue); +// remove single knob from NV storage +bool knobs_remove_knob_from_NVRAM(const char* knobName); + +// write PMU buck voltage (use KNOB_PMU_BUCKn as index) +void knobs_pmu_set_data(uint8_t index, uint8_t value); + +// * Platform specific stuff * + +// Get/Set GPU/CPU/SoC voltage for specific performance state in units +uint8_t knobs_platform_get_gfx_perf_voltage(uint32_t perfStateNo); +void knobs_platform_set_gfx_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage); + +uint8_t knobs_platform_get_cpu_perf_voltage(uint32_t perfStateNo); +void knobs_platform_set_cpu_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage); + +uint8_t knobs_platform_get_soc_perf_voltage(uint32_t perfStateNo); +void knobs_platform_set_soc_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage); + +#endif diff --git a/drivers/apple/voltage_knobs/knobs.c b/drivers/apple/voltage_knobs/knobs.c new file mode 100644 index 0000000..4229b6f --- /dev/null +++ b/drivers/apple/voltage_knobs/knobs.c @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this code should be included and debug and development builds only +#if !RELEASE_BUILD + +#include + +#if SUB_PLATFORM_T7000 || SUB_PLATFORM_T7001 +#include "knobs_t7000.h" +#elif SUB_PLATFORM_S7002 +#include "knobs_s7002.h" +#elif SUB_PLATFORM_S8000 || SUB_PLATFORM_S8001 || SUB_PLATFORM_S8003 +#include "knobs_s8000.h" +#else +#error This platform is not supported +#endif + +// a number of bytes used in PMU scratch RAM +#define VOLTAGE_KNOBS_SIZE 32 + +// A "master switch" bit position in the PMU bitfield. 0 in this bit means feature not activated +#define MASTER_SWITCH_BIT (VOLTAGE_KNOBS_SIZE * 8 - 1) + +// do not reorder the knobs in list as this array is used for iteration through all knobs, +// and the code below assumes the knobs order +const knob_type_description_t all_knobs[] = +{ + {NULL , ' ', kKnobTypeUnknown, -1}, + {"cpu", 'C', kKnobTypeCPU, CPU_KNOB_MAX}, + {"gpu", 'G', kKnobTypeGPU, GPU_KNOB_MAX}, + {"soc", 'S', kKnobTypeSOC, SOC_KNOB_MAX}, + {"pmu", 'P', kKnobTypePMU, PMU_KNOB_MAX}, + {NULL , ' ', kKnobTypeInvalid, -1}, +}; + +// -========================================================================================- +// - NV Storage operations - +// It could be done using standalone persistent environment variables or being a part of +// boot-args. +// Value formatting: +// * Offset (-)[intValue] - just plain decimal number in units, may be negative +// * Absolute @[intValue] - symbol '@'+ plain decimal number in units. Always positive + +#define BOOT_ARGS_NAME "boot-args" + +// Utility function to store a knob value by its name into a non-volatile storage +bool knobs_store_knob_in_NVRAM(const char* knobName, knob_as_binary_t *knobValue) +{ + bool result = false; + const char* existingBootArgs = NULL; + char knobValStr[KNOB_NAME_MAXLEN + 20] = {0}; + + // remove any existing one, ignore errors + knobs_remove_knob_from_NVRAM(knobName); + + // fetch up existing set of boot-args + existingBootArgs = env_get(BOOT_ARGS_NAME); + if (existingBootArgs) + { + size_t newBootArgsLen = 0; + char *newBootArgs = NULL; + + // format name=value pair to append to boot-args, it should contain a leading space + snprintf(knobValStr, sizeof(knobValStr), " %s=%s%d", + knobName, + knobValue->u.bit.isAbsolute ? KNOB_ABSOLUTE_CHAR : "", + knobValue->u.bit.isNegative ? -knobValue->u.bit.knobVal : knobValue->u.bit.knobVal); + // allocate buffer for both strings and a trailing zero + newBootArgsLen = strlen(existingBootArgs) + strlen(knobValStr) + 1; + newBootArgs = malloc(newBootArgsLen); + if (newBootArgs) + { + strlcpy(newBootArgs, existingBootArgs, newBootArgsLen); + strlcat(newBootArgs, knobValStr, newBootArgsLen); + + // store updated boot-args + env_set(BOOT_ARGS_NAME, newBootArgs, ENV_PERSISTENT); + if (nvram_save() == 0) + { + result = true; + } + free(newBootArgs); + } + } + + return result; +} + +// Remove knob from NV storage +bool knobs_remove_knob_from_NVRAM(const char* knobName) +{ + bool result = false; + const char* existingBootArgs = NULL; + + // fetch up existing set of boot-args + existingBootArgs = env_get(BOOT_ARGS_NAME); + if (existingBootArgs) + { + const char *findNamePtr = strstr(existingBootArgs, knobName); + if (findNamePtr) + { + // found one, removing + char *newBootArgs = strdup(existingBootArgs); + if (newBootArgs) + { + // break-up the string by injecting a zero at the beginning of the value to remove + newBootArgs[findNamePtr - existingBootArgs] = 0; + // find next space and append the rest of boot-args string to the end + char *nextSpcPtr = strstr(findNamePtr, " "); + if (nextSpcPtr) + { + // skip the whitespace just found as it belongs to the key/value pair we removing + nextSpcPtr ++; + if (strlen(newBootArgs) == 0) + { + // removed one was the first in string, so remove any spaces may be + while (*nextSpcPtr == ' ') nextSpcPtr ++; + } + strlcat(newBootArgs, nextSpcPtr, strlen(existingBootArgs) + 1); + } + + // clean up any trailing spaces may left + nextSpcPtr = &newBootArgs[strlen(newBootArgs)]; + while ((nextSpcPtr >= newBootArgs) && (*nextSpcPtr == ' ' || *nextSpcPtr == 0)) + { + *nextSpcPtr = 0; + nextSpcPtr --; + } + + // store updated boot-args + env_set(BOOT_ARGS_NAME, newBootArgs, ENV_PERSISTENT); + if (nvram_save() == 0) + { + result = true; + } + free(newBootArgs); + } + } + } + + return result; +} + +// Utility function to extract a knob value by its name from non-volatile storage +bool knobs_load_knob_from_NVRAM(const char* knobName, knob_as_binary_t *knobValue) +{ + bool result = false; + const char* existingBootArgs = NULL; + + // fetch up existing set of boot-args + existingBootArgs = env_get(BOOT_ARGS_NAME); + if (existingBootArgs) + { + const char *findNamePtr = strstr(existingBootArgs, knobName); + if (findNamePtr) + { + // found one, processing + const char *findValPtr= strstr(findNamePtr, "="); + if (findValPtr) + { + // skip the equal sign and move ahead by making a copy + findValPtr ++; + char *valueCopy = strdup(findValPtr); + if (valueCopy) + { + // find the end by searching space, may not find if it was the last in boot-args + char *findValueCopyEnd = strstr(valueCopy, " "); + if (findValueCopyEnd) + { + // this will be the end of string, safe as we made a copy + *findValueCopyEnd = 0; + } + + // we have a knob value isolated for processing + result = true; + if (valueCopy[0] == KNOB_ABSOLUTE_CHAR[0]) + { + // absolute value + knobValue->u.bit.isAbsolute = 1; + knobValue->u.bit.isNegative = 0; + knobValue->u.bit.knobVal = atoi(&valueCopy[1]); + } + else + { + // offset + knobValue->u.bit.isAbsolute = 0; + int numValue = atoi(valueCopy); + if (numValue < 0) + { + knobValue->u.bit.isNegative = 1; + numValue = -numValue; + } + else + { + knobValue->u.bit.isNegative = 0; + } + knobValue->u.bit.knobVal = numValue; + } + + free(valueCopy); + } + } + } + } + + return result; +} +// -========================================================================================- + +void knobs_prepare_standby_storage(void) +{ + uint8_t pmu_bytes[VOLTAGE_KNOBS_SIZE] = {0}; + +#if DEBUG_BUILD + printf("Voltage knobs: initializing PMU scratch registers\n"); +#endif + + // save zeroes into PMU Scratch registers + power_store_voltage_knobs(pmu_bytes, VOLTAGE_KNOBS_SIZE); +} + +#if PRODUCT_IBOOT || PRODUCT_IBEC +// get knobs from NVRAM variables, convert them, and store in PMU scratch registers +// this will not be available in 2nd stage bootloaders as no access to NVRAM env vars there +void knobs_update_PMU_registers(bool apply_to_hw) +{ + const knob_type_description_t *currentDesc = &all_knobs[1]; + char knobName[KNOB_NAME_MAXLEN] = {0}; + uint8_t pmu_bytes[VOLTAGE_KNOBS_SIZE] = {0}; + bool featureActivated = false; + +#if DEBUG_BUILD + printf("Voltage knobs: storing knobs into PMU scratch registers\n"); +#endif + + // try all possible names for building the list + while(currentDesc->visible_name) + { + for (uint32_t idx = 0; idx < currentDesc->max_index; idx ++) + { + knob_as_binary_t actual_value; + + snprintf(knobName, sizeof(knobName), KNOBNAMEFORMAT, idx, currentDesc->nameprefix); + + // found one??? + actual_value.u.intval = 0; + if (knobs_load_knob_from_NVRAM(knobName, &actual_value)) + { + // at least one knob is set, so we are using this feature + featureActivated = true; + + // now, find the knob bit position in pmu_bytes and place them... + uint32_t bit_no = (idx + 1) * KNOB_SIZE_BITS; + switch (currentDesc->defined_type) + { + case kKnobTypeCPU: + break; + case kKnobTypeGPU: + bit_no += KNOB_SIZE_BITS * CPU_KNOB_MAX; + break; + case kKnobTypeSOC: + bit_no += KNOB_SIZE_BITS * GPU_KNOB_MAX + KNOB_SIZE_BITS * CPU_KNOB_MAX; + break; + case kKnobTypePMU: + bit_no += KNOB_SIZE_BITS * GPU_KNOB_MAX + KNOB_SIZE_BITS * CPU_KNOB_MAX + KNOB_SIZE_BITS * SOC_KNOB_MAX; + break; + default: + break; + } + + // set the bits. we may need up to use up to three bytes + uint32_t byte_idx = (bit_no - 1) >> 3; + uint32_t bits_byte2 = bit_no & 0x07; + uint32_t bits_byte1 = 0; + uint32_t bits_byte0 = 0; + + if (bits_byte2 == 0) + { + bits_byte2 = 8; + } + bits_byte1 = KNOB_SIZE_BITS - bits_byte2; + if (bits_byte1 > 8) + { + bits_byte1 = 8; + bits_byte0 = KNOB_SIZE_BITS - bits_byte2 - 8; + } + + pmu_bytes[byte_idx] |= (actual_value.u.intval >> (KNOB_SIZE_BITS - bits_byte2)); + pmu_bytes[byte_idx - 1] |= actual_value.u.intval << (8 - bits_byte1); + if (bits_byte0) + { + pmu_bytes[byte_idx - 2] |= actual_value.u.intval << (8 - bits_byte0); + } + } + } + + currentDesc ++; + } + + if (featureActivated) + { + // Turn master switch on + pmu_bytes[MASTER_SWITCH_BIT / 8] |= (1 << (MASTER_SWITCH_BIT % 8)); + + // save the bits into PMU + power_store_voltage_knobs(pmu_bytes, sizeof(pmu_bytes) / sizeof(pmu_bytes[0])); + + if (apply_to_hw) + { + knobs_load_from_standby_storage(); + } + } +} +#else +// empty stub for the 2nd stage bootloaders +void knobs_update_PMU_registers(bool apply_to_hw) +{ +} +#endif + +// find a bit in a byte array by its number. returns 0 or 1 only +uint8_t get_bit(uint8_t *pmu_bytes, uint32_t bit_no) +{ + uint32_t byte_idx = bit_no >> 3; + uint32_t bit_idx = bit_no & 0x07; + + return ((pmu_bytes[byte_idx] & (1 << bit_idx)) == 0) ? 0 : 1; +} + +// Get knob bits (KNOB_SIZE_BITS) from a byte array starting from bit_no +// @pre: KNOB_SIZE_BITS < 16 +uint32_t get_knob_bits(uint8_t *pmu_bytes, uint32_t bit_no) +{ + uint32_t byte_idx = (bit_no - 1) >> 3; + uint32_t bits_byte2 = 0; + int32_t bits_byte1 = 0; + int32_t bits_byte0 = 0; + uint32_t result = 0; + + bits_byte2 = bit_no & 0x07; + if (bits_byte2 == 0) + { + bits_byte2 = 8; + } + bits_byte1 = KNOB_SIZE_BITS - bits_byte2; + if (bits_byte1 > 8) + { + bits_byte1 = 8; + bits_byte0 = KNOB_SIZE_BITS - bits_byte2 - 8; + } + + check(KNOB_SIZE_BITS < 16); + check(byte_idx > (bits_byte0 ? 1 : 0)); + check(byte_idx < VOLTAGE_KNOBS_SIZE); + + // load first chunk + result |= (pmu_bytes[byte_idx] & (0xFF >> (8 - bits_byte2))); + // now, make some room for next chunk on right + result <<= bits_byte1; + // move next chunk right and merge with previous chunk + result |= (pmu_bytes[byte_idx - 1] >> (8 - bits_byte1)); + if (bits_byte0) + { + // clean up some bit space for the last chunk + result <<= bits_byte0; + // append last chunk + result |= (pmu_bytes[byte_idx - 2] >> (8 - bits_byte0)); + } + + return result; +} + +// This function loads voltage knobs from PMU scratch registers and applies them +// into related SoC registers +void knobs_load_from_standby_storage(void) +{ + bool success = false; + uint8_t pmu_bytes[VOLTAGE_KNOBS_SIZE] = {0}; + uint32_t consumed_bits = 0; + knob_as_binary_t knobPMUVal; + + // load PMU bit blob from PMU scratch registers + success = power_load_voltage_knobs(pmu_bytes, VOLTAGE_KNOBS_SIZE); + if (!success) + { + // do not printf any error to save limited LLB codespace + return; + } + + // check if master switch is on + if (get_bit(pmu_bytes, MASTER_SWITCH_BIT) == 0) + { + // nope, feature is not activated + return; + } + +#if (CPU_KNOB_MAX > 0) + // extract and apply CPU voltage throught DVFM state registers + for (uint32_t knob = 0 ; knob < CPU_KNOB_MAX; knob ++) + { + uint8_t voltage = 0; + + // advance bit pointer and extract knob from PMU bit blob + consumed_bits += KNOB_SIZE_BITS; + knobPMUVal.u.intval = get_knob_bits(pmu_bytes, consumed_bits); + + if (knobPMUVal.u.intval == 0) + { + // Knob is not defined. + continue; + } + + if (knobPMUVal.u.bit.isAbsolute) + { + voltage = knobPMUVal.u.bit.knobVal; + } + else + { + // Extract pre-set safe voltage. + voltage = knobs_platform_get_cpu_perf_voltage(knob + kDVFM_STATE_IBOOT); + + // Modify safe voltage with offset provided. + if (knobPMUVal.u.bit.isNegative) + { + voltage -= knobPMUVal.u.bit.knobVal; + } + else + { + voltage += knobPMUVal.u.bit.knobVal; + } + } + + // Update selected CPU power state with adjusted safe voltage. + knobs_platform_set_cpu_perf_voltage(knob + kDVFM_STATE_IBOOT, voltage); + } +#endif // (CPU_KNOB_MAX > 0) + +#if (GPU_KNOB_MAX > 0) + // extract and apply GPU voltage adjustments + for (uint32_t knob = 0 ; knob < GPU_KNOB_MAX; knob ++) + { + consumed_bits += KNOB_SIZE_BITS; + knobPMUVal.u.intval = get_knob_bits(pmu_bytes, consumed_bits); + + if (knobPMUVal.u.intval == 0) + { + continue; + } + + // GFX perf states are not defined in PMGR, so I am assuming that state0 is reserved for SecureROM + uint8_t voltage = knobs_platform_get_gfx_perf_voltage(knob + 1); + if (knobPMUVal.u.bit.isAbsolute) + { + // For absolute voltage override it completely. + voltage = knobPMUVal.u.bit.knobVal; + } + else + { + // Otherwise, offset the voltage with knob value. + if (knobPMUVal.u.bit.isNegative) + { + voltage -= knobPMUVal.u.bit.knobVal; + } + else + { + voltage += knobPMUVal.u.bit.knobVal; + } + } + + // Apply new voltage. + knobs_platform_set_gfx_perf_voltage(knob + 1, voltage); + } +#endif + +#if (SOC_KNOB_MAX > 0) + // extract and apply SoC voltage through SoC perf state PMGR registers + for (uint32_t knob = 0 ; knob < SOC_KNOB_MAX; knob ++) + { + consumed_bits += KNOB_SIZE_BITS; + knobPMUVal.u.intval = get_knob_bits(pmu_bytes, consumed_bits); + + if (knobPMUVal.u.intval == 0) + { + continue; + } + + uint8_t soc_voltage = knobs_platform_get_soc_perf_voltage(kSOC_PERF_STATE_IBOOT + knob); + + if (knobPMUVal.u.bit.isAbsolute) + { + soc_voltage = knobPMUVal.u.bit.knobVal; + } + else + { + if (knobPMUVal.u.bit.isNegative) + { + soc_voltage -= knobPMUVal.u.bit.knobVal; + } + else + { + soc_voltage += knobPMUVal.u.bit.knobVal; + } + } + + knobs_platform_set_soc_perf_voltage(kSOC_PERF_STATE_IBOOT + knob, soc_voltage); + } +#endif + +#if (PMU_KNOB_MAX > 0) + // Extract and apply PMU voltages thorough it's IIC registers. + for (uint32_t knob = 0 ; knob < PMU_KNOB_MAX; knob ++) + { + consumed_bits += KNOB_SIZE_BITS; + knobPMUVal.u.intval = get_knob_bits(pmu_bytes, consumed_bits); + + if (knobPMUVal.u.intval == 0) + { + continue; + } + + if (knobPMUVal.u.bit.isAbsolute) + { + knobs_pmu_set_data(knob, knobPMUVal.u.bit.knobVal); + } + else + { + // Some of PMU knobs are not handled by iBoot somewhere else, and they are + // preserved through sleep cycles as PMU never sleeps + // so read - offset - write scheme is not acceptable here. + // Using default value instead. + uint8_t pmu_knob_val = 0x00; + knobs_get_default_val(kKnobTypePMU, knob, &pmu_knob_val); + + if (knobPMUVal.u.bit.isNegative) + { + pmu_knob_val -= knobPMUVal.u.bit.knobVal; + } + else + { + pmu_knob_val += knobPMUVal.u.bit.knobVal; + } + + knobs_pmu_set_data(knob, pmu_knob_val); + } + } +#endif + + check(consumed_bits <= MASTER_SWITCH_BIT); +} + +#ifndef SUB_PLATFORM_S7002 +// request default value of a knob in units +bool knobs_get_default_val(knob_types_e type, uint8_t index, uint8_t *defaultValueUnits) +{ +#if (CPU_KNOB_MAX > 0) + u_int32_t num_dvfm_states = kDVFM_STATE_IBOOT_CNT; + u_int32_t cpu_vid[num_dvfm_states]; +#endif +#if (GPU_KNOB_MAX > 0) + u_int32_t gpu_vid[kPMGR_GFX_STATE_MAX]; +#endif + + if (defaultValueUnits == NULL || type >= kKnobTypeInvalid || index >= all_knobs[type].max_index) + { + // Invalid parameter. + return false; + } + + switch (type) + { + case kKnobTypeCPU: +#if (CPU_KNOB_MAX > 0) + platform_get_cpu_voltages(num_dvfm_states, cpu_vid); + if (platform_convert_voltages(BUCK_CPU, num_dvfm_states, cpu_vid) == -1) + { + return false; + } + + *defaultValueUnits = cpu_vid[index + kDVFM_STATE_IBOOT]; + break; +#else + return false; +#endif + case kKnobTypeGPU: +#if (GPU_KNOB_MAX > 0) + { + const u_int32_t buckCount = __min(kPMGR_GFX_STATE_MAX, GPU_KNOB_MAX); + + platform_get_gpu_voltages(buckCount, gpu_vid); + if (platform_convert_voltages(BUCK_GPU, buckCount, gpu_vid) == -1) + { + return false; + } + } + + // skip securerom state. this is not defined in platform support code + *defaultValueUnits = gpu_vid[index + 1]; + break; +#else + return false; +#endif + case kKnobTypeSOC: +#if (SOC_KNOB_MAX > 0) + // no API for that, so values are hardcoded until platform code will be extended to full support of SoC voltages + if (index == 0) *defaultValueUnits = 0x60; + if (index == 1) *defaultValueUnits = 0x70; + break; +#else + return false; +#endif + case kKnobTypePMU: + if (index == 0) *defaultValueUnits = KNOB_PMU_BUCK3_POR; + if (index == 1) *defaultValueUnits = KNOB_PMU_BUCK4_POR; + if (index == 2) + { + uint32_t dwiVal = 0; + knobs_convert_mv_to_dwi(type, index, platform_get_base_ram_voltage(), &dwiVal); + *defaultValueUnits = dwiVal; + } + break; + + default: + return false; + } + + return true; +} +#endif // SUB_PLATFORM_S7002 + +#endif diff --git a/drivers/apple/voltage_knobs/knobs_s7002.c b/drivers/apple/voltage_knobs/knobs_s7002.c new file mode 100644 index 0000000..2c6308a --- /dev/null +++ b/drivers/apple/voltage_knobs/knobs_s7002.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "knobs_s7002.h" + +// this code should be included and debug and development builds only +#if !RELEASE_BUILD + +#include + +// **** PMU platform-specific code **** + +// For M7 SoC with D2238(Tanzanite) PMU +// * 0.6V + 3.125mV * BUCK0_VSEL, so BUCK0_MIN = 0.6V, BUCK0_MAX = 1.396V +// * 0.6V + 3.125mV * BUCK2_VSEL, so BUCK2_MIN = 0.6V, BUCK2_MAX = 1.396V +// * 1.1V + 3.125mV * BUCK3_VSEL, so BUCK3_MIN = 1.1V, BUCK3_MAX = 1.896V +#define KNOBS_BUCKn_MV_PER_UNIT 3125 + +#define KNOBS_BUCK3_VMIN (1100) +#define KNOBS_BUCK3_VMAX (1896) +#define KNOBS_BUCK3_BUCKOUT(mv) (((mv - KNOBS_BUCK3_VMIN) * 1000) + (KNOBS_BUCKn_MV_PER_UNIT - 1)) / KNOBS_BUCKn_MV_PER_UNIT +#define KNOBS_BUCK3_BUCKMV(vsel) (KNOBS_BUCK3_VMIN + ((((vsel) * KNOBS_BUCKn_MV_PER_UNIT)) / 1000)) + +#define kDIALOG_BUCK0_VSEL 0x0100 +#define kDIALOG_BUCK2_VSEL 0x0140 +#define kDIALOG_BUCK3_VSEL 0x0160 + +// defined in drivers/dialog/pmu/power.c +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + +void knobs_pmu_set_data(uint8_t index, uint8_t value) +{ + switch(index) + { + case KNOB_PMU_DRAM_1V8: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK3_VSEL, value, false); + break; + case KNOB_PMU_DRAM_1V2: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK2_VSEL, value, false); + break; + case KNOB_PMU_SOC_FIXED: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK0_VSEL, value, false); + break; + } +} + +// convert units to millivolts for specific knob +int knobs_convert_dwi_to_mv(knob_types_e type, uint8_t index, u_int32_t dwival) +{ + int buck_type = 0; + switch(type) + { + case kKnobTypePMU: + switch(index) + { + case KNOB_PMU_DRAM_1V8: + return KNOBS_BUCK3_BUCKMV(dwival); + default: + return power_convert_dwi_to_mv(buck_type, dwival); + } + default: + return power_convert_dwi_to_mv(buck_type, dwival); + } +} + +// converts millivolts to units for specific knob +int knobs_convert_mv_to_dwi(knob_types_e type, uint8_t index, u_int32_t mv, u_int32_t *dwival) +{ + int buck_type = 0; + switch(type) + { + case kKnobTypePMU: + switch(index) + { + case KNOB_PMU_DRAM_1V8: + *dwival = KNOBS_BUCK3_BUCKOUT(mv); + return 0; + default: + return power_get_buck_value(buck_type, mv, dwival); + } + default: + return power_get_buck_value(buck_type, mv, dwival); + } +} + +// Request default value for a knob in units. +bool knobs_get_default_val(knob_types_e type, uint8_t index, uint8_t *defaultValueUnits) +{ + if (defaultValueUnits == NULL || type >= kKnobTypeInvalid || index >= all_knobs[type].max_index) + { + // Invalid parameter. + return false; + } + + switch (type) + { + case kKnobTypePMU: + switch(index) + { + case KNOB_PMU_DRAM_1V8: + *defaultValueUnits = KNOB_PMU_BUCK3_POR; + break; + case KNOB_PMU_DRAM_1V2: + *defaultValueUnits = KNOB_PMU_BUCK2_POR; + break; + case KNOB_PMU_SOC_FIXED: + { + uint32_t dwiVal = 0; + knobs_convert_mv_to_dwi(type, index, platform_get_base_ram_voltage(), &dwiVal); + *defaultValueUnits = dwiVal; + break; + } + default: + return false; + } + break; + + default: + return false; + } + + return true; +} + +#endif diff --git a/drivers/apple/voltage_knobs/knobs_s7002.h b/drivers/apple/voltage_knobs/knobs_s7002.h new file mode 100644 index 0000000..be40794 --- /dev/null +++ b/drivers/apple/voltage_knobs/knobs_s7002.h @@ -0,0 +1,10 @@ +#ifndef __APPLE_KNOBS_S7002_H +#define __APPLE_KNOBS_S7002_H + +// from Tanzanite PMU spec +#define KNOB_PMU_BUCK0_POR (0x4C) // 0.8375V +#define KNOB_PMU_BUCK2_POR (0xC0) // 1.2V +#define KNOB_PMU_BUCK3_POR (0xE0) // 1.8V + +#endif + diff --git a/drivers/apple/voltage_knobs/knobs_s8000.c b/drivers/apple/voltage_knobs/knobs_s8000.c new file mode 100644 index 0000000..eaaaf41 --- /dev/null +++ b/drivers/apple/voltage_knobs/knobs_s8000.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this code should be included and debug and development builds only +#if !RELEASE_BUILD + +#include + +uint8_t knobs_platform_get_gfx_perf_voltage(uint32_t perfStateNo) +{ + uint32_t gpu_perf_state_a = rPMGR_GFX_PERF_STATE_ENTRY_A(perfStateNo); + return PMGR_GFX_PERF_STATE_ENTRY0A_VOLTAGE_XTRCT(gpu_perf_state_a); +} + +void knobs_platform_set_gfx_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage) +{ + uint32_t gpu_perf_state_a = rPMGR_GFX_PERF_STATE_ENTRY_A(perfStateNo); + gpu_perf_state_a &= ~PMGR_GFX_PERF_STATE_ENTRY0A_VOLTAGE_UMASK; + rPMGR_GFX_PERF_STATE_ENTRY_A(perfStateNo) = gpu_perf_state_a | PMGR_GFX_PERF_STATE_ENTRY0A_VOLTAGE_INSRT(newVoltage); +} + + +uint8_t knobs_platform_get_cpu_perf_voltage(uint32_t perfStateNo) +{ + uint64_t dvfm_state = rACC_DVFM_ST(perfStateNo); + return ACC_PWRCTL_DVFM_ST0_SAFE_VOL_XTRCT(dvfm_state); +} + +void knobs_platform_set_cpu_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage) +{ + uint64_t dvfm_state = rACC_DVFM_ST(perfStateNo); + + // clean volAdjX as we want to disable temperature adjustments when voltage is explicitly specified + dvfm_state &= ~ACC_PWRCTL_DVFM_ST0_VOL_ADJ0_UMASK; + dvfm_state &= ~ACC_PWRCTL_DVFM_ST0_VOL_ADJ1_UMASK; + dvfm_state &= ~ACC_PWRCTL_DVFM_ST0_VOL_ADJ2_UMASK; + dvfm_state &= ~ACC_PWRCTL_DVFM_ST0_VOL_ADJ3_UMASK; + + // Clean safe voltage as well. + dvfm_state &= ~ACC_PWRCTL_DVFM_ST0_SAFE_VOL_UMASK; + + // Update selected CPU power state with new voltage. + rACC_DVFM_ST(perfStateNo) = dvfm_state | ACC_DVFM_ST_SAFE_VOL(newVoltage); +} + +uint8_t knobs_platform_get_soc_perf_voltage(uint32_t perfStateNo) +{ + return PMGR_SOC_PERF_STATE_ENTRY_0C_VOLTAGE_XTRCT(rPMGR_SOC_PERF_STATE_ENTRY_C(perfStateNo)); +} + +void knobs_platform_set_soc_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage) +{ + uint32_t perf_state_entry_c = rPMGR_SOC_PERF_STATE_ENTRY_C(perfStateNo); + perf_state_entry_c &= ~PMGR_SOC_PERF_STATE_ENTRY_0C_VOLTAGE_UMASK; + rPMGR_SOC_PERF_STATE_ENTRY_C(perfStateNo) = perf_state_entry_c | PMGR_SOC_PERF_STATE_ENTRY_0C_VOLTAGE_INSRT(newVoltage); +} + + +// For Maui SoC with D2255 (Antigua) PMU +// * 1.1V + 3.125mV * BUCK3_VSEL, so BUCK3_MIN = 1.1V, BUCK3_MAX = 1.896V +// * 0.6V + 3.125mV * BUCK4_VSEL, so BUCK4_MIN = 0.6V, BUCK4_MAX = 1.396V +// * 0.6V + 3.125mV * BUCK5_VSEL, so BUCK5_MIN = 0.6V, BUCK5_MAX = 1.396V + + +// KNOB_PMU_DRAM_1V8 >> BUCK3 (1.8V) +// KNOB_PMU_DRAM_1V2 >> BUCK4 (1.1V) +// KNOB_PMU_SOC_FIXED >> BUCK5 (0.85V) + +#define kDIALOG_BUCK3_VSEL 0x1301 +#define kDIALOG_BUCK4_VSEL 0x1401 +#define kDIALOG_BUCK5_VSEL 0x1501 + +#define KNOBS_BUCKn_MV_PER_UNIT 3125 + +#define KNOBS_BUCK3_VMIN (1100) +#define KNOBS_BUCK3_VMAX (1896) +#define KNOBS_BUCK3_BUCKOUT(mv) (((mv - KNOBS_BUCK3_VMIN) * 1000) + (KNOBS_BUCKn_MV_PER_UNIT - 1)) / KNOBS_BUCKn_MV_PER_UNIT +#define KNOBS_BUCK3_BUCKMV(vsel) (KNOBS_BUCK3_VMIN + ((((vsel) * KNOBS_BUCKn_MV_PER_UNIT)) / 1000)) + +// defined in drivers/dialog/pmu/power.c +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + +void knobs_pmu_set_data(uint8_t index, uint8_t value) +{ + switch(index) + { + case KNOB_PMU_DRAM_1V8: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK3_VSEL, value, false); + break; + case KNOB_PMU_DRAM_1V2: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK4_VSEL, value, false); + break; + case KNOB_PMU_SOC_FIXED: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK5_VSEL, value, false); + break; + } +} + +// Power rail value conversion is based on target_rails[] array in +// target/iphone8/include/target/powerconfig.h +// However, it does not have entries for BUCK3 and BUCK4 yet. +// Therefore, I need to have my own macro for BUCK3. +// BUCK4 is similar to BUCK2, so reuse its value for now. + +// Convert units to millivolts for specific knob. +int knobs_convert_dwi_to_mv(knob_types_e type, uint8_t index, u_int32_t dwival) +{ + switch(type) + { + case kKnobTypeCPU: + return power_convert_dwi_to_mv(POWER_RAIL_CPU, dwival); + case kKnobTypeGPU: + return power_convert_dwi_to_mv(POWER_RAIL_GPU, dwival); + case kKnobTypeSOC: + return power_convert_dwi_to_mv(POWER_RAIL_SOC, dwival); + case kKnobTypePMU: + switch(index) + { + case KNOB_PMU_DRAM_1V8: + return KNOBS_BUCK3_BUCKMV(dwival); + case KNOB_PMU_SOC_FIXED: + return power_convert_dwi_to_mv(POWER_RAIL_VDD_FIXED, dwival); + case KNOB_PMU_DRAM_1V2: + return power_convert_dwi_to_mv(POWER_RAIL_SOC, dwival); + default: + printf("%s: unknown PMU knob index %d\n", __FUNCTION__, index); + return -1; + } + default: + printf("%s: unknown knob type %d\n", __FUNCTION__, type); + return -1; + } +} + +// Converts millivolts to units for specific knob. +int knobs_convert_mv_to_dwi(knob_types_e type, uint8_t index, u_int32_t mv, u_int32_t *dwival) +{ + switch(type) + { + case kKnobTypeCPU: + return power_get_rail_value(POWER_RAIL_CPU, mv, dwival); + case kKnobTypeGPU: + return power_get_rail_value(POWER_RAIL_GPU, mv, dwival); + case kKnobTypeSOC: + return power_get_rail_value(POWER_RAIL_SOC, mv, dwival); + case kKnobTypePMU: + switch(index) + { + case KNOB_PMU_DRAM_1V8: + *dwival = KNOBS_BUCK3_BUCKOUT(mv); + return 0; + case KNOB_PMU_SOC_FIXED: + return power_get_rail_value(POWER_RAIL_VDD_FIXED, mv, dwival); + case KNOB_PMU_DRAM_1V2: + return power_get_rail_value(POWER_RAIL_SOC, mv, dwival); + default: + printf("%s: unknown PMU knob index %d\n", __FUNCTION__, index); + return -1; + } + default: + printf("%s: unknown knob type %d\n", __FUNCTION__, type); + return -1; + } +} + +#endif diff --git a/drivers/apple/voltage_knobs/knobs_s8000.h b/drivers/apple/voltage_knobs/knobs_s8000.h new file mode 100644 index 0000000..9c981b9 --- /dev/null +++ b/drivers/apple/voltage_knobs/knobs_s8000.h @@ -0,0 +1,10 @@ +#ifndef __APPLE_KNOBS_S8000_H +#define __APPLE_KNOBS_S8000_H + +// from Antigua PMU spec as iBoot is not touching them +// Check latest OTP settings for POR values +#define KNOB_PMU_BUCK3_POR (0xE0) // 1.8V +#define KNOB_PMU_BUCK4_POR (0xA0) // 1.1V +#define KNOB_PMU_BUCK5_POR (0x50) // 0.85V + +#endif diff --git a/drivers/apple/voltage_knobs/knobs_t7000.c b/drivers/apple/voltage_knobs/knobs_t7000.c new file mode 100644 index 0000000..9d486da --- /dev/null +++ b/drivers/apple/voltage_knobs/knobs_t7000.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this code should be included and debug and development builds only +#if !RELEASE_BUILD + +#include + +// for some reasons these are not defined for t7000 platform +#ifndef CCC_DVFM_ST_SAFE_VOL_MASK +#define CCC_DVFM_ST_SAFE_VOL_MASK (0xFF00000000000000ull) +#endif + +#ifndef CCC_DVFM_ST_SAFE_VOL_ADJ_MASK +#define CCC_DVFM_ST_SAFE_VOL_ADJ_MASK (0xFF3FFFFFC0000000ull) +#endif + +#ifndef CCC_DVFM_ST_SAFE_VOL_SHIFT +#define CCC_DVFM_ST_SAFE_VOL_SHIFT (56) +#endif + +#ifndef PMGR_GFX_PERF_STATE_VOLTAGE_SHIFT +#define PMGR_GFX_PERF_STATE_VOLTAGE_SHIFT (24) +#endif + +#if (GPU_KNOB_MAX > 0) +uint8_t knobs_platform_get_gfx_perf_voltage(uint32_t perfStateNo) +{ + uint32_t gpu_perf_state = rPMGR_GFX_PERF_STATE_ENTRY(perfStateNo); + return (gpu_perf_state >> PMGR_GFX_PERF_STATE_VOLTAGE_SHIFT); +} + +void knobs_platform_set_gfx_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage) +{ + uint32_t gpu_perf_state = rPMGR_GFX_PERF_STATE_ENTRY(perfStateNo); + gpu_perf_state &= 0x00FFFFFF; + rPMGR_GFX_PERF_STATE_ENTRY(perfStateNo) = gpu_perf_state | (newVoltage << PMGR_GFX_PERF_STATE_VOLTAGE_SHIFT); +} +#endif + +#if (CPU_KNOB_MAX > 0) +uint8_t knobs_platform_get_cpu_perf_voltage(uint32_t perfStateNo) +{ + uint64_t dvfm_state = rCCC_DVFM_ST(perfStateNo); + return ((dvfm_state & CCC_DVFM_ST_SAFE_VOL_MASK) >> CCC_DVFM_ST_SAFE_VOL_SHIFT); +} + +void knobs_platform_set_cpu_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage) +{ + uint64_t dvfm_state = rCCC_DVFM_ST(perfStateNo); + + // Clean safe_vol and volAdj[0-3] as we want to disable temperature adjustment + // when voltage is explicitly specified. + dvfm_state &= ~CCC_DVFM_ST_SAFE_VOL_ADJ_MASK; + + // clean safe voltage out of state register + dvfm_state &= ~CCC_DVFM_ST_SAFE_VOL_MASK; + + // Update selected CPU power state with new voltage. + rCCC_DVFM_ST(perfStateNo) = dvfm_state | CCC_DVFM_ST_SAFEVOL(newVoltage); +} +#endif + +#if (SOC_KNOB_MAX > 0) +uint8_t knobs_platform_get_soc_perf_voltage(uint32_t perfStateNo) +{ + return rPMGR_SOC_PERF_STATE_ENTRY_C(perfStateNo); +} + +void knobs_platform_set_soc_perf_voltage(uint32_t perfStateNo, uint8_t newVoltage) +{ + rPMGR_SOC_PERF_STATE_ENTRY_C(perfStateNo) = newVoltage; +} +#endif + +// **** PMU platform-specific code **** + +// For FIJI SoC with D2186 PMU +// * 1.1V + 3.125mV * BUCK3_VSEL, so BUCK3_MIN = 1.1V, BUCK3_MAX = 1.896V +// * 0.6V + 3.125mV * BUCK4_VSEL, so BUCK4_MIN = 0.6V, BUCK4_MAX = 1.396V +// * 0.6V + 3.125mV * BUCK5_VSEL, so BUCK5_MIN = 0.6V, BUCK5_MAX = 1.396V +#define KNOBS_BUCKn_MV_PER_UNIT 3125 + +#define KNOBS_BUCK3_VMIN (1100) +#define KNOBS_BUCK3_VMAX (1896) +#define KNOBS_BUCK3_BUCKOUT(mv) (((mv - KNOBS_BUCK3_VMIN) * 1000) + (KNOBS_BUCKn_MV_PER_UNIT - 1)) / KNOBS_BUCKn_MV_PER_UNIT +#define KNOBS_BUCK3_BUCKMV(vsel) (KNOBS_BUCK3_VMIN + ((((vsel) * KNOBS_BUCKn_MV_PER_UNIT)) / 1000)) + +#define kDIALOG_BUCK3_VSEL 0x0160 +#define kDIALOG_BUCK4_VSEL 0x0180 +#define kDIALOG_BUCK5_VSEL 0x01a0 + +// defined in drivers/dialog/pmu/power.c +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + +void knobs_pmu_set_data(uint8_t index, uint8_t value) +{ + switch(index) + { + case KNOB_PMU_DRAM_1V8: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK3_VSEL, value, false); + break; + case KNOB_PMU_DRAM_1V2: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK4_VSEL, value, false); + break; + case KNOB_PMU_SOC_FIXED: + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK5_VSEL, value, false); + break; + } +} + +// convert units to millivolts for specific knob +int knobs_convert_dwi_to_mv(knob_types_e type, uint8_t index, u_int32_t dwival) +{ +#if BUCK_CPU && BUCK_GPU + int buck_type = (type == kKnobTypeGPU) ? BUCK_GPU : BUCK_CPU; +#else + int buck_type = 0; +#endif + switch(type) + { + case kKnobTypePMU: + switch(index) + { + case KNOB_PMU_DRAM_1V8: + return KNOBS_BUCK3_BUCKMV(dwival); + default: + return power_convert_dwi_to_mv(buck_type, dwival); + } + default: + return power_convert_dwi_to_mv(buck_type, dwival); + } +} + +// converts millivolts to units for specific knob +int knobs_convert_mv_to_dwi(knob_types_e type, uint8_t index, u_int32_t mv, u_int32_t *dwival) +{ +#if BUCK_CPU && BUCK_GPU + int buck_type = (type == kKnobTypeGPU) ? BUCK_GPU : BUCK_CPU; +#else + int buck_type = 0; +#endif + switch(type) + { + case kKnobTypePMU: + switch(index) + { + case KNOB_PMU_DRAM_1V8: + *dwival = KNOBS_BUCK3_BUCKOUT(mv); + return 0; + default: + return power_get_buck_value(buck_type, mv, dwival); + } + default: + return power_get_buck_value(buck_type, mv, dwival); + } +} + + +#endif diff --git a/drivers/apple/voltage_knobs/knobs_t7000.h b/drivers/apple/voltage_knobs/knobs_t7000.h new file mode 100644 index 0000000..9513089 --- /dev/null +++ b/drivers/apple/voltage_knobs/knobs_t7000.h @@ -0,0 +1,9 @@ +#ifndef __APPLE_KNOBS_T7000_H +#define __APPLE_KNOBS_T7000_H + +// from ADI PMU spec as iBoot is not touching them +#define KNOB_PMU_BUCK3_POR (0xE0) // 1.8V +#define KNOB_PMU_BUCK4_POR (0xC0) // 1.2V + +#endif + diff --git a/drivers/apple/voltage_knobs/menu_commands.c b/drivers/apple/voltage_knobs/menu_commands.c new file mode 100644 index 0000000..568878a --- /dev/null +++ b/drivers/apple/voltage_knobs/menu_commands.c @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + Short feature description: + + ** Voltage knobs are set as NVRAM variables using menu provided or any other way + ** Knobs are stored in PMU units (~3.1 mv) even if they been provided in mV in menu + ** LLB has no access to NVRAM, so we need to use some PMU scratch registers to support sleep/wake cycle + ** On a cold boot PMU registers used for temp. storage are cleared as their initial state is undefined + ** On a cold boot knobs are loaded from NVRAM, copied to PMU Scratch registers, and applied to hardware + ** On a worm boot knobs are loaded from PMU Scratch registers + ** DISABLE temperature adjustments if knob has absolute voltage (DVFM only) + ** Knobs are either absolute or offset; offsets may be negative + ** PMU scratch registers have master switch bit +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if WITH_VOLTAGE_KNOBS +#include +#endif + +#define MENUCMD knobs +#define MENUCMDSTR "knobs" + +#define LISTKNOBSCMD "list" +#define ADDKNOBCMD "add" +#define REMOVEKNOBCMD "remove" +#define DEFAULTSCMD "defaults" + +// this code should be included and debug and development builds only +#if !RELEASE_BUILD && WITH_MENU + +static int usage(void) +{ + printf("usage:\n"); + printf(MENUCMDSTR " " LISTKNOBSCMD "\n"); + printf(MENUCMDSTR " " ADDKNOBCMD " \n"); + printf(MENUCMDSTR " " REMOVEKNOBCMD " \n"); + printf(MENUCMDSTR " " DEFAULTSCMD " list default voltages when knobs are not defined\n"); + printf("\nNew voltages will be used on a next boot.\n"); + printf("\nAbsolute voltage below 600mv may be handled not correctly.\n"); + + return 0; +} + +knob_types_e knob_type_by_name(char* knobname) +{ + const knob_type_description_t *currentDesc = &all_knobs[1]; + + while(currentDesc->visible_name) + { + if (!strcmp(knobname, currentDesc->visible_name)) + { + return currentDesc->defined_type; + } + currentDesc ++; + } + + return kKnobTypeInvalid; +} + +// TODO! move to separate function, so those defaults may be used in 'add' function for validating user input +static void knobs_defaults(void) +{ + uint8_t base_vol = 0xff; + +#if (CPU_KNOB_MAX > 0) + for (uint32_t knob = 0 ; knob < CPU_KNOB_MAX; knob ++) + { + const char *prefix = ""; + + switch (knob + kDVFM_STATE_IBOOT) + { + case kDVFM_STATE_VNOM: + prefix = "-- Vnom"; + break; +#ifdef kDVFM_STATE_VMAX + case kDVFM_STATE_VMAX: + prefix = "-- Vmax"; + break; +#endif + default: + break; + } + +#ifdef DVFM_STATE_VMAX + u_int32_t chip_rev = chipid_get_chip_revision(); + if ((knob + kDVFM_STATE_IBOOT) == DVFM_STATE_VMAX(chip_rev)) + { + prefix = "-- Vmax"; + } +#endif + + if (knobs_get_default_val(kKnobTypeCPU, knob, &base_vol)) + { + printf("cpu %d abs %d units (%d mV) %s\n", knob, base_vol, knobs_convert_dwi_to_mv(kKnobTypeCPU, knob, base_vol), prefix); + } + } +#endif + + for (uint32_t knob = 0 ; knob < GPU_KNOB_MAX; knob ++) + { + if (knobs_get_default_val(kKnobTypeGPU, knob, &base_vol)) + { + printf("gpu %d abs %d units (%d mV)\n", knob, base_vol, knobs_convert_dwi_to_mv(kKnobTypeGPU, knob, base_vol)); + } + } + + for (uint32_t knob = 0 ; knob < SOC_KNOB_MAX; knob ++) + { + if (knobs_get_default_val(kKnobTypeSOC, knob, &base_vol)) + { + printf("soc %d abs %d units (%d mV)\n", knob, base_vol, knobs_convert_dwi_to_mv(kKnobTypeSOC, knob, base_vol)); + } + } + + for (uint32_t knob = 0 ; knob < PMU_KNOB_MAX; knob ++) + { + const char *prefix = ""; + + switch (knob) + { + case KNOB_PMU_DRAM_1V8: + prefix = "-- DRAM 1.8V"; + break; + case KNOB_PMU_DRAM_1V2: + prefix = "-- DRAM 1.2V"; + break; + case KNOB_PMU_SOC_FIXED: + prefix = "-- SoC Fixed Rail"; + break; + default: + break; + } + + if (knobs_get_default_val(kKnobTypePMU, knob, &base_vol)) + { + printf("pmu %d abs %d units (%d mV) %s\n", knob, base_vol, knobs_convert_dwi_to_mv(kKnobTypePMU, knob, base_vol), prefix); + } + } +} + +static void knobs_list(void) +{ + const knob_type_description_t *currentDesc = &all_knobs[1]; + char knobName[KNOB_NAME_MAXLEN] = {0}; + + // try all possible names for building the list + while(currentDesc->visible_name) + { + for (uint32_t idx = 0; idx < currentDesc->max_index; idx ++) + { + knob_as_binary_t actualValue; + + snprintf(knobName, sizeof(knobName), KNOBNAMEFORMAT, idx, currentDesc->nameprefix); + + // found one??? + if (knobs_load_knob_from_NVRAM(knobName, &actualValue)) + { + int mvValue = knobs_convert_dwi_to_mv(currentDesc->defined_type, idx, actualValue.u.bit.knobVal); + + if (actualValue.u.bit.isAbsolute == 0) + { + // apply correction for offset to get correct value in mV + int minPossibleValue = knobs_convert_dwi_to_mv(currentDesc->defined_type, idx, 0); + mvValue -= minPossibleValue; + } + + + printf("knob %s %d: %s %c%d units (%c%d mV)\n", currentDesc->visible_name, idx, + actualValue.u.bit.isAbsolute ? "abs" : "offset", + actualValue.u.bit.isNegative ? '-' : ' ', + actualValue.u.bit.knobVal, + actualValue.u.bit.isNegative ? '-' : ' ', + mvValue); + } + } + + currentDesc ++; + } +} + +#define KNOB_MAX_UNITS 255 +#define WARNING_TRESHOLD_MV 100 +#define WARNING_DELTA_TRESHOLD_MV 5 +static void knobs_add(knob_types_e knob_type, uint32_t knob_index, bool absolute, int32_t knob_value, bool in_mv) +{ + char knobName[KNOB_NAME_MAXLEN] = {0}; + knob_as_binary_t actualKnobValue; + const knob_type_description_t *currentDesc = &all_knobs[knob_type]; + + if (knob_index >= currentDesc->max_index) + { + printf("Knob index out of range.\n"); + return; + } + + snprintf(knobName, sizeof(knobName), KNOBNAMEFORMAT, knob_index, all_knobs[knob_type].nameprefix); + + // query minimal possible value in mV by converting 0 units to millivolts + // for validation new value requested + int minPossibleValue = knobs_convert_dwi_to_mv(knob_type, knob_index, 0); + int maxPossibleValue = knobs_convert_dwi_to_mv(knob_type, knob_index, KNOB_MAX_UNITS); + + if (in_mv) + { + // * Setting knob in millivolts * + u_int32_t knobValueUnits = 0; + + if (absolute) + { + // requested absolute value in millivolts should not be less than minimal possible + if (knob_value < minPossibleValue) + { + printf("Unable to set absolute value less than %d mV for this hardware.\n", minPossibleValue); + return; + } + if (knob_value > maxPossibleValue) + { + printf("Unable to set absolute value more than %d mV for this hardware.\n", maxPossibleValue); + return; + } + + // convert value to PMU units + knobs_convert_mv_to_dwi(knob_type, knob_index, knob_value, &knobValueUnits); + // read it back to verify + int actualVoltage = knobs_convert_dwi_to_mv(knob_type, knob_index, knobValueUnits); + printf("Actual absolute voltage is %d mV\n", actualVoltage); + int delta = __abs(actualVoltage - knob_value); + if (delta > WARNING_DELTA_TRESHOLD_MV) + { + printf("WARNING!!! Actual voltage is different from requested by %d mV.\n", delta); + } + + // check if new absolute value within 100mV ballpark from default value + uint8_t defaultValUnits = 0; + if (knobs_get_default_val(knob_type, knob_index, &defaultValUnits)) + { + int defaultValMV = knobs_convert_dwi_to_mv(knob_type, knob_index, defaultValUnits); + int delta = __abs(defaultValMV - knob_value); + if (delta > WARNING_TRESHOLD_MV) + { + printf("WARNING!!! New knob value is differ from its default value for more than 100mV.\n"); + } + } + } + else + { + // as voltage scale starts not from 0, we must get initial point first for calculating offsets + knobs_convert_mv_to_dwi(knob_type, knob_index, __abs(knob_value) + minPossibleValue, &knobValueUnits); + if (__abs(knob_value) > WARNING_TRESHOLD_MV) + { + printf("WARNING!!! Your offsett is above %d mV.\n", WARNING_TRESHOLD_MV); + } + } + printf("Knob value is %d mV (%d units)\n", knob_value, knobValueUnits); + + actualKnobValue.u.bit.knobVal = knobValueUnits; + } + else + { + // * Setting knob in Units * + int knobValueinMV = 0; + uint8_t defaultValUnits = 0; + knobs_get_default_val(knob_type, knob_index, &defaultValUnits); + int defaultValMV = knobs_convert_dwi_to_mv(knob_type, knob_index, defaultValUnits); + + if (absolute) + { + knobValueinMV = knobs_convert_dwi_to_mv(knob_type, knob_index, knob_value); + + if (knob_value > KNOB_MAX_UNITS) + { + printf("Unable to set absolute value more than %d units for this hardware.\n", KNOB_MAX_UNITS); + return; + } + + int delta = __abs(defaultValMV - knobValueinMV); + if (delta > WARNING_TRESHOLD_MV) + { + printf("WARNING!!! New knob value is differ from its default value for more than %d mV.\n", WARNING_TRESHOLD_MV); + } + } + else + { + if (knob_value < 0 && __abs(knob_value) > defaultValUnits) + { + // negative offset should not be greater than default value + printf("ERROR: negative offset is exceeeding default valie, so it cannot be set.\n"); + return; + } + + if (knob_value > 0 && (knob_value + defaultValUnits) > KNOB_MAX_UNITS) + { + // positive offset will overflow 8 bit HW register + printf("ERROR: positive offset will make voltage to exceed %d units, and it cannot be done.\n", KNOB_MAX_UNITS); + return; + } + + int newValInMV = knobs_convert_dwi_to_mv(knob_type, knob_index, defaultValUnits + knob_value); + knobValueinMV = newValInMV - defaultValMV; + if (__abs(knobValueinMV) > WARNING_TRESHOLD_MV) + { + printf("WARNING!!! Your offset is exceeding %d mV.\n", WARNING_TRESHOLD_MV); + } + } + + printf("Knob value is %d mV (%d units)\n", knobValueinMV, knob_value); + + // already in PMU DIALOG_CORE_BUCKOUTunits + actualKnobValue.u.bit.knobVal = __abs(knob_value); + } + + actualKnobValue.u.bit.isNegative = (knob_value < 0) ? 1 : 0; + actualKnobValue.u.bit.isAbsolute = absolute ? 1 : 0; + + if (knobs_store_knob_in_NVRAM(knobName, &actualKnobValue) == false) + { + printf("Unable to store knob into NV storage\n"); + } + + // and update volatile PMU registers + knobs_update_PMU_registers(false); +} + +static void knobs_remove(knob_types_e knob_type, uint32_t knob_index) +{ + char knobName[KNOB_NAME_MAXLEN] = {0}; + const knob_type_description_t *currentDesc = &all_knobs[knob_type]; + + if (knob_index >= currentDesc->max_index) + { + printf("Knob index out of range.\n"); + return; + } + + snprintf(knobName, sizeof(knobName), KNOBNAMEFORMAT, knob_index, all_knobs[knob_type].nameprefix); + +#if DEBUG_BUILD + printf("removing '%s' from env.\n", knobName); +#endif + + if (knobs_remove_knob_from_NVRAM(knobName) == false) + { + printf("Unable to remove knob from NV storage\n"); + } + + // and update volatile PMU registers + knobs_update_PMU_registers(false); +} + +static int do_voltage_knobs(int argc, struct cmd_arg *args) +{ + knob_types_e knob_type = kKnobTypeUnknown; + + if (argc < 2) + { + printf("Not enough arguments\n"); + return usage(); + } + + + if (!strcmp(args[1].str, LISTKNOBSCMD)) + { + knobs_list(); + } + else if (!strcmp(args[1].str, ADDKNOBCMD)) + { + bool absolute = false; + bool in_mv = false; + + if (argc==7) + { + knob_type = knob_type_by_name(args[2].str); + if (knob_type == kKnobTypeUnknown || knob_type == kKnobTypeInvalid) + { + return usage(); + } + + if (!strcmp(args[4].str, "abs")) + { + absolute = true; + } + else if (!strcmp(args[4].str, "offset")) + { + absolute = false; + } + else + { + printf("parameter 4 shoud be abs or offset\n"); + return usage(); + } + + if (!strcmp(args[6].str, "mv")) + { + in_mv = true; + } + else if (!strcmp(args[6].str, "units")) + { + in_mv = false; + } + else + { + printf("parameter 6 shoud be mv or units\n"); + return usage(); + } + + knobs_add(knob_type, args[3].u, absolute, args[5].u, in_mv); + } + else + { + return usage(); + } + } + else if (!strcmp(args[1].str, REMOVEKNOBCMD)) + { + if (argc==4) + { + knob_type = knob_type_by_name(args[2].str); + if (knob_type == kKnobTypeUnknown || knob_type == kKnobTypeInvalid) + { + return usage(); + } + + knobs_remove(knob_type, args[3].u); + } + else + { + return usage(); + } + } + else if (!strcmp(args[1].str, DEFAULTSCMD)) + { + knobs_defaults(); + } + else + { + printf("unlknown argument 1\n"); + return usage(); + } + + return 0; +} + +// _command, _function, _help, _meta +MENU_COMMAND_DEVELOPMENT(MENUCMD, do_voltage_knobs, "Platform voltage knobs adjustment commands", NULL); + +#endif // !RELEASE_BUILD && WITH_MENU diff --git a/drivers/apple/voltage_knobs/rules.mk b/drivers/apple/voltage_knobs/rules.mk new file mode 100644 index 0000000..6c4a434 --- /dev/null +++ b/drivers/apple/voltage_knobs/rules.mk @@ -0,0 +1,32 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ifneq ($(BUILD),RELEASE) +ALL_OBJS += \ + $(LOCAL_DIR)/knobs.o \ + $(LOCAL_DIR)/menu_commands.o + +ifeq ($(PLATFORM),t7000) +ALL_OBJS += $(LOCAL_DIR)/knobs_t7000.o +else ifeq ($(PLATFORM),s7002) +ALL_OBJS += $(LOCAL_DIR)/knobs_s7002.o +else ifeq ($(PLATFORM),s8000) +ALL_OBJS += $(LOCAL_DIR)/knobs_s8000.o +else +$(error unknown platform) +endif + +OPTIONS += \ + WITH_VOLTAGE_KNOBS=1 +endif + diff --git a/drivers/apple/wpc/rules.mk b/drivers/apple/wpc/rules.mk new file mode 100644 index 0000000..7ac19e4 --- /dev/null +++ b/drivers/apple/wpc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_WPC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/wpc.o \ No newline at end of file diff --git a/drivers/apple/wpc/wpc.c b/drivers/apple/wpc/wpc.c new file mode 100644 index 0000000..eea9c4a --- /dev/null +++ b/drivers/apple/wpc/wpc.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include "wpc.h" + +static const uint32_t wpcConfig_DeGamma[WPC_CONFIG_DE_GAMMA_COUNT] = { + 0, 159, 317, 476, 634, 793, 960, + 1146, 1352, 1577, 1824, 2091, 2380, 2691, + 3025, 3382, 3762, 4166, 4594, 5046, 5524, + 6027, 6556, 7111, 7692, 8300, 8936, 9599, + 10289, 11008, 11755, 12532, 13337, 14172, 15036, + 15930, 16855, 17810, 18796, 19813, 20862, 21942, + 23054, 24199, 25376, 26585, 27828, 29104, 30413, + 31756, 33133, 34544, 35990, 37470, 38986, 40536, + 42122, 43743, 45401, 47094, 48824, 50590, 52393, + 54233, 56110, 58024, 59976, 61965, 63993, 66059, + 68163, 70306, 72487, 74708, 76968, 79267, 81606, + 83984, 86402, 88861, 91360, 93899, 96479, 99100, + 101762, 104466, 107211, 109997, 112825, 115695, 118607, + 121562, 124559, 127599, 130681, 133807, 136976, 140188, + 143444, 146743, 150086, 153473, 156905, 160380, 163901, + 167466, 171075, 174730, 178430, 182175, 185966, 189802, + 193684, 197612, 201586, 205606, 209672, 213786, 217945, + 222152, 226406, 230706, 235054, 239450, 243893, 248384, + 252922, 257509, +}; + +static const uint32_t wpcConfig_EnGamma[WPC_CONFIG_EN_GAMMA_COUNT] = { + 0, 103, 207, 310, 413, 517, 620, 721, + 814, 900, 981, 1057, 1129, 1198, 1264, 1327, + 1388, 1447, 1503, 1558, 1611, 1663, 1713, 1762, + 1809, 1856, 1901, 1946, 1989, 2032, 2073, 2114, + 2154, 2194, 2233, 2271, 2308, 2345, 2381, 2417, + 2452, 2487, 2521, 2555, 2588, 2621, 2653, 2685, + 2717, 2748, 2779, 2809, 2840, 2869, 2899, 2928, + 2957, 2985, 3014, 3042, 3069, 3097, 3124, 3151, + 3178, 3230, 3282, 3333, 3383, 3432, 3480, 3528, + 3575, 3621, 3667, 3712, 3756, 3800, 3843, 3886, + 3928, 3970, 4011, 4052, 4092, 4132, 4171, 4210, + 4249, 4287, 4325, 4362, 4399, 4436, 4472, 4508, + 4543, 4614, 4683, 4750, 4817, 4883, 4947, 5011, + 5074, 5136, 5197, 5257, 5316, 5374, 5432, 5489, + 5545, 5601, 5656, 5710, 5764, 5817, 5870, 5922, + 5973, 6024, 6074, 6124, 6174, 6222, 6271, 6319, + 6366, 6460, 6552, 6643, 6732, 6820, 6906, 6991, + 7074, 7157, 7238, 7318, 7398, 7476, 7553, 7629, + 7704, 7778, 7852, 7924, 7996, 8067, 8137, 8206, + 8275, 8343, 8410, 8477, 8542, 8608, 8672, 8736, + 8800, 8925, 9048, 9169, 9288, 9405, 9520, 9633, + 9745, 9855, 9964, 10071, 10176, 10281, 10383, 10485, + 10585, 10684, 10782, 10879, 10975, 11069, 11163, 11256, + 11347, 11438, 11528, 11617, 11705, 11792, 11878, 11963, + 12048, 12215, 12379, 12541, 12699, 12856, 13009, 13161, + 13310, 13457, 13602, 13745, 13886, 14025, 14162, 14298, + 14431, 14564, 14694, 14824, 14951, 15078, 15203, 15326, + 15449, 15570, 15689, 15808, 15925, 16042, 16157, 16271, +}; + +void wpc_write_reg(uint32_t reg, uint32_t value); +uint32_t wpc_read_reg(uint32_t reg); + +void wpc_init(uint32_t display_width, uint32_t display_height) +{ + // WPC Configuration defined in ADBE TRM v0.1.14. Section 4.4 + + // Active Region Start + wpc_write_reg(WPC_CONFIG_ACTIVE_REGION_START_OFFSET, + WPC_CONFIG_ACTIVE_REGION_START_START_X_INSRT(0) | + WPC_CONFIG_ACTIVE_REGION_START_START_Y_INSRT(0)); + + // Active Region Size + wpc_write_reg(WPC_CONFIG_ACTIVE_REGION_SIZE_OFFSET, + WPC_CONFIG_ACTIVE_REGION_SIZE_WIDTH_INSRT(display_width) | + WPC_CONFIG_ACTIVE_REGION_SIZE_HEIGHT_INSRT(display_height)); + + // Pixel Gain + for (int i = 0; i < WPC_CONFIG_PIXEL_GAIN_COUNT; i ++) { + wpc_write_reg(WPC_CONFIG_PIXEL_GAIN_OFFSET(i), 1 << 19); + } + + // GainStep (Round using 48.16 Fixed Point) + wpc_write_reg(WPC_CONFIG_GAIN_STEP_X_OFFSET, (uint32_t)((((16777216ULL << 16) / display_width) + (1<<15)) >> 16)); + wpc_write_reg(WPC_CONFIG_GAIN_STEP_Y_OFFSET, (uint32_t)((((16777216ULL << 16) / display_height) + (1<<15)) >> 16)); + + // Kick the values in to the registers. + wpc_write_reg(WPC_CONFIG_UPDATE_CONTROL_OFFSET, 0x3); +} + +void wpc_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl) +{ + // DeGamma + for (int i = 0; i < WPC_CONFIG_DE_GAMMA_COUNT; i ++) { + wpc_write_reg(WPC_CONFIG_DE_GAMMA_OFFSET(i), wpcConfig_DeGamma[i]); + } + + // DeGamma Last + wpc_write_reg(WPC_CONFIG_DE_GAMMA_LAST_OFFSET, 262144); + + // EnGamma + for (int i = 0; i < WPC_CONFIG_EN_GAMMA_COUNT; i ++) { + wpc_write_reg(WPC_CONFIG_EN_GAMMA_OFFSET(i), wpcConfig_EnGamma[i]); + } + + // EnGamma Last + wpc_write_reg(WPC_CONFIG_EN_GAMMA_LAST_OFFSET, 16384); +} + +void wpc_write_reg(uint32_t reg, uint32_t value) +{ + (*(volatile u_int32_t *)(WPC_BASE_ADDR + reg)) = value; +} + +uint32_t wpc_read_reg(uint32_t reg) +{ + return (*(volatile u_int32_t *)(WPC_BASE_ADDR + reg)); +} \ No newline at end of file diff --git a/drivers/apple/wpc/wpc.h b/drivers/apple/wpc/wpc.h new file mode 100644 index 0000000..95083b7 --- /dev/null +++ b/drivers/apple/wpc/wpc.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_WPC_H +#define __APPLE_WPC_H + +#include +#include + +#ifdef DISP0_WPC_BASE_ADDR +#define WPC_BASE_ADDR DISP0_WPC_BASE_ADDR +#endif +#ifndef WPC_BASE_ADDR +#error "WPC base addr for AppleWhitePointCorrection (WPC) Block is not defined" +#endif + +#include SUB_PLATFORM_SPDS_HEADER(wpc) + +#endif //__APPLE_WPC_H \ No newline at end of file diff --git a/drivers/arasan/sdio/rules.mk b/drivers/arasan/sdio/rules.mk new file mode 100644 index 0000000..5cf5a07 --- /dev/null +++ b/drivers/arasan/sdio/rules.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifeq ($(APPLICATION),EmbeddedIOP) + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/sdiodrv_config.o \ + $(LOCAL_DIR)/sdiodrv_command.o \ + $(LOCAL_DIR)/sdiodrv_transfer.o \ + $(LOCAL_DIR)/sdiocommon/sdhc_debug.o \ + $(LOCAL_DIR)/sdiocommon/sdhc_registers.o \ + $(LOCAL_DIR)/sdiocommon/sdio_cmdprop.o + +endif diff --git a/drivers/arasan/sdio/sdiocommon/sdhc_debug.c b/drivers/arasan/sdio/sdiocommon/sdhc_debug.c new file mode 100644 index 0000000..62545f3 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdhc_debug.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "sdhc_debug.h" + +#ifdef PLATFORM_VARIANT_IOP +#include +#else +#include +#endif + + +void +sdhc_dumpRegisterFile(const SDHCRegisters_t *sdhc) +{ + printf("SDHC @ %p, size = %lu\n", sdhc, sizeof(*sdhc)); + printf(" SD Command Generation:\n"); + printf(" sdmaSystemAddr = 0x%08X\n", (uint32_t)sdhc->sdmaSystemAddr); + printf(" blockSize = 0x%04X\n", sdhc->blockSize); + printf(" blockCount = 0x%04X\n", sdhc->blockCount); + printf(" argument = 0x%08X\n", (uint32_t)sdhc->argument); + printf(" transferMode = 0x%04X\n", sdhc->transferMode); + printf(" command = 0x%04X\n", sdhc->command); + + printf(" Response:\n"); + for(unsigned i=0; i<4; i++) { + printf(" response[%u] = 0x%08X\n", i, (uint32_t)sdhc->response[i]); + } + + printf(" Buffer Data Port:\n"); + printf(" bufferDataPort = 0x%08X\n", (uint32_t)sdhc->bufferDataPort); + + printf(" Host Controls:\n"); + printf(" presentState = 0x%08X\n", (uint32_t)sdhc->presentState); + printf(" hostControl = 0x%02X\n", sdhc->hostControl); + printf(" powerControl = 0x%02X\n", sdhc->powerControl); + printf(" blockGapControl = 0x%02X\n", sdhc->blockGapControl); + printf(" wakeupControl = 0x%02X\n", sdhc->wakeupControl); + printf(" clockControl = 0x%04X\n", sdhc->clockControl); + printf(" timeoutControl = 0x%02X\n", sdhc->timeoutControl); + printf(" softwareReset = 0x%02X\n", sdhc->softwareReset); + + printf(" Interrupt Controls:\n"); + printf(" normalInterruptStatus = 0x%04X\n", sdhc->normalInterruptStatus); + printf(" errorInterruptStatus = 0x%04X\n", sdhc->errorInterruptStatus); + printf(" normalInterruptStatusEnable = 0x%04X\n", sdhc->normalInterruptStatusEnable); + printf(" errorInterruptStatusEnable = 0x%04X\n", sdhc->errorInterruptStatusEnable); + printf(" normalInterruptSignalEnable = 0x%04X\n", sdhc->normalInterruptSignalEnable); + printf(" errorInterruptSignalEnable = 0x%04X\n", sdhc->errorInterruptSignalEnable); + printf(" autoCmd12ErrorStatus = 0x%04X\n", sdhc->autoCmd12ErrorStatus); + + printf(" Capabilities:\n"); + printf(" capabilities = 0x%016llX\n", sdhc->capabilities); + printf(" maxCurrentCapabilities = 0x%016llX\n", sdhc->maxCurrentCapabilities); + + printf(" Force Event:\n"); + printf(" forceEventAutoCmd12ErrorStatus = 0x%04X\n", sdhc->forceEventAutoCmd12ErrorStatus); + printf(" forceEventErrorInterruptStatus = 0x%04X\n", sdhc->forceEventErrorInterruptStatus); + + printf(" ADMA:\n"); + printf(" admaErrorStatus = 0x%02X\n", sdhc->admaErrorStatus); + printf(" admaSystemAddr = 0x%016llX\n", sdhc->admaSystemAddr); + + printf(" Common:\n"); + printf(" slotInterruptStatus = 0x%04X\n", sdhc->slotInterruptStatus); + printf(" hostControllerVersion = 0x%04X\n", sdhc->hostControllerVersion); +} + diff --git a/drivers/arasan/sdio/sdiocommon/sdhc_debug.h b/drivers/arasan/sdio/sdiocommon/sdhc_debug.h new file mode 100644 index 0000000..eab58c6 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdhc_debug.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef _SDHC_DEBUG_H +#define _SDHC_DEBUG_H + + +#ifdef PLATFORM_VARIANT_IOP +#include +#else +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +void sdhc_dumpRegisterFile(const SDHCRegisters_t *sdhc); + + +#ifdef __cplusplus +} +#endif + +#endif /* _SDHC_DEBUG_H */ diff --git a/drivers/arasan/sdio/sdiocommon/sdhc_registers.c b/drivers/arasan/sdio/sdiocommon/sdhc_registers.c new file mode 100644 index 0000000..f19fceb --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdhc_registers.c @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + + +#include "sdhc_registers.h" + + +// TODO: Endianness + +#pragma mark - +#pragma mark Macros + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + + + +#pragma mark - +#pragma mark Capabilities + +enum SDHCCapabilitiesFieldOffset +{ + kSDHCCapabilityBaseClockRateOffset = 8, + kSDHCCapabilityMaxBlockLengthOffset = 16, + kSDHCCapabilityHighSpeedSupportOffset = 21, + kSDHCCapabilitySuspendResumeSupportOffset = 23 +}; + +enum SDHCCapabilitiesField +{ + kSDHCCapabilityBaseClockRate = (0x3F << kSDHCCapabilityBaseClockRateOffset), + kSDHCCapabilityMaxBlockLength = (0x3 << kSDHCCapabilityMaxBlockLengthOffset), + kSDHCCapabilityHighSpeedSupport = (1 << kSDHCCapabilityHighSpeedSupportOffset), + kSDHCCapabilitySuspendResumeSupport = (1 << kSDHCCapabilitySuspendResumeSupportOffset), +}; + + + +UInt16 +sdhc_getMaxBlockLength(const SDHCRegisters_t *sdhc) +{ + static UInt16 mapBlkLenCapToLen[] = {512, 1024, 2048, 0}; + + UInt8 cap = (sdhc->capabilities & kSDHCCapabilityMaxBlockLength) >> kSDHCCapabilityMaxBlockLengthOffset; + + return mapBlkLenCapToLen[cap]; +} + +UInt32 +sdhc_getBaseClockFrequencyHz(const SDHCRegisters_t *sdhc) +{ + UInt32 rateMHz = (sdhc->capabilities & kSDHCCapabilityBaseClockRate) >> kSDHCCapabilityBaseClockRateOffset; + return rateMHz * 1000000; +} + +bool +sdhc_isSuspendResumeSupported(const SDHCRegisters_t *sdhc) +{ + return sdhc->capabilities & kSDHCCapabilitySuspendResumeSupport; +} + +bool +sdhc_isHighSpeedSupported(const SDHCRegisters_t *sdhc) +{ + return sdhc->capabilities & kSDHCCapabilityHighSpeedSupport; +} + + + +#pragma mark - +#pragma mark Present State + +enum PresentStateFieldOffsets +{ + kCmdInhibitOffset = 0, + kDataInhibitOffset = 1, +}; + +enum PresentStateField +{ + kCmdInhibit = (1 << kCmdInhibitOffset), + kDataInhibit = (1 << kDataInhibitOffset), +}; + + +bool +sdhc_isCommandInhibitedOnCmd(const SDHCRegisters_t *sdhc) +{ + return sdhc->presentState & kCmdInhibit; +} + +bool +sdhc_isCommandInhibitedOnData(const SDHCRegisters_t *sdhc) +{ + return sdhc->presentState & kDataInhibit; +} + + + +#pragma mark - +#pragma mark Clocks + + +#define kMaxClockDivisor (256) + +enum ClkControlFieldOffsets +{ + kInternalClkEnableOffset = 0, + kInternalClkStableOffset = 1, + kSDClkEnableOffset = 2, + kSDClkFrequencySelectOffset = 8 +}; + +enum ClkControlFields +{ + kInternalClkEnable = (1 << kInternalClkEnableOffset), + kInternalClkStable = (1 << kInternalClkStableOffset), + kSDClkEnable = (1 << kSDClkEnableOffset), + kSDClkFrequencySelect = (0xFF << kSDClkFrequencySelectOffset) +}; + +UInt32 +sdhc_setClockDividerRate(SDHCRegisters_t *sdhc, UInt32 targetSDClkRateHz, UInt32 inputClkRateHz) +{ + UInt16 divisor = 1; + + while(inputClkRateHz / divisor > targetSDClkRateHz) { + divisor *= 2; + } + + divisor = min(divisor, kMaxClockDivisor); + + sdhc_setClockDivider(sdhc, divisor); + + return inputClkRateHz / divisor; +} + +void +sdhc_setClockDivider(SDHCRegisters_t *sdhc, UInt16 divisor) +{ + divisor >>= 1; // divisor is offset, 0x00 == clk / 1 + divisor <<= kSDClkFrequencySelectOffset; // shift to correct offset + + sdhc->clockControl &= ~kSDClkFrequencySelect; + + // Note: must enable internal clock here or SDIO block will lock up + sdhc->clockControl |= (divisor | kInternalClkEnable); +} + +UInt16 +sdhc_getClockDivider(const SDHCRegisters_t *sdhc) +{ + UInt16 clkControl = sdhc->clockControl & kSDClkFrequencySelect; + + clkControl >>= kSDClkFrequencySelectOffset; // shift to correct offset + + // divisor is offset, 0x00 == clk / 1 + clkControl <<= 1; + if(0 == clkControl) { + clkControl = 1; + } + + return clkControl; +} + +void +sdhc_enableInternalClock(SDHCRegisters_t *sdhc, bool enable) +{ + UInt16 clkControl = sdhc->clockControl; + + if(enable) { + clkControl |= kInternalClkEnable; + } else { + clkControl &= ~kInternalClkEnable; + } + + sdhc->clockControl = clkControl; +} + +bool +sdhc_isInternalClockStable(const SDHCRegisters_t *sdhc) +{ + return sdhc->clockControl & kInternalClkStable; +} + +void +sdhc_enableSDClock(SDHCRegisters_t *sdhc, bool enable) +{ + UInt16 clkControl = sdhc->clockControl; + + if(enable) { + clkControl |= kSDClkEnable; + } else { + clkControl &= ~kSDClkEnable; + } + + sdhc->clockControl = clkControl; +} + +bool +sdhc_isSDClockEnabled(const SDHCRegisters_t *sdhc) +{ + return sdhc->clockControl & kSDClkEnable; +} + + + +#pragma mark - +#pragma mark Block Size + + +enum SDHCBlockSizeOffset +{ + kSDHCTransferSizeOffset = 0, + kSDHCHostSDMABufferSizeOffset = 12, + kSDHCTransferSizeHighOffset = 15, +}; + +enum SDHCBlockSizeMask +{ + kSDHCTransferSize = (0xFFF << kSDHCTransferSizeOffset), + kSDHCHostSDMABufferSize = (0x7 << kSDHCTransferSizeOffset), + kSDHCTransferSizeHigh = (1 << kSDHCTransferSizeHighOffset), + +}; + + +void +sdhc_setBlockSize(SDHCRegisters_t *sdhc, UInt16 size) +{ + UInt16 blockSize = sdhc->blockSize & ~(kSDHCTransferSizeHigh | kSDHCTransferSize); + + + blockSize |= size & kSDHCTransferSize; + + // High bit + blockSize |= (size & (1 << kSDHCHostSDMABufferSizeOffset)) + << (kSDHCTransferSizeHighOffset - kSDHCHostSDMABufferSizeOffset); + + sdhc->blockSize = blockSize; +} + + + +#pragma mark - +#pragma mark Commands + +void +sdhc_copyCommandResponse(const SDHCRegisters_t *sdhc, struct SDIOCommandResponse *response) +{ + for(UInt16 i=0; i < 4; ++i) { + response->response[i] = sdhc->response[i]; + } +} + + + +#pragma mark - +#pragma mark Command State + + +enum NormalIntFieldOffsets +{ + kCmdCompleteIntOffset = 0, + kTransferCompleteIntOffset = 1, + kBlockGapIntOffset = 2, + kDMAIntOffset = 3, + kBufferWriteReadyIntOffset = 4, + kBufferReadReadyIntOffset = 5, + kCardInsertionIntOffset = 6, + kCardRemovalIntOffset = 7, + kCardIntOffset = 8, + + kErrorIntOffset = 15 +}; + +enum NormalIntFields +{ + kCmdCompleteInt = (1 << kCmdCompleteIntOffset), + kTransferCompleteInt = (1 << kTransferCompleteIntOffset), + kBlockGapInt = (1 << kBlockGapIntOffset), + kDMAInt = (1 << kDMAIntOffset), + kBufferWriteReadyInt = (1 << kBufferWriteReadyIntOffset), + kBufferReadReadyInt = (1 << kBufferReadReadyIntOffset), + kCardInsertionInt = (1 << kCardInsertionIntOffset), + kCardRemovalInt = (1 << kCardRemovalIntOffset), + kCardInt = (1 << kCardIntOffset), + + kErrorInt = (1 << kErrorIntOffset), +}; + +enum ErrorIntFieldOffsets +{ + kCmdTimeoutErrorIntOffset = 0, + kCmdCRCErrorIntOffset = 1, + kCmdEndBitErrorIntOffset = 2, + kCmdIndexErrorIntOffset = 3, + kDataTimeoutErrorIntOffset = 4, + kDataCRCErrorIntOffset = 5, + kDataEndBitErrorIntOffset = 6, + kCurrentLimitErrorIntOffset = 7, + kAutoCmd12ErrorIntOffset = 8, + kADMAErrorIntOffset = 9 +}; + +enum ErrorIntFields +{ + kCmdTimeoutErrorInt = (1 << kCmdTimeoutErrorIntOffset), + kCmdCRCErrorInt = (1 << kCmdCRCErrorIntOffset), + kCmdEndBitErrorInt = (1 << kCmdEndBitErrorIntOffset), + kCmdIndexErrorInt = (1 << kCmdIndexErrorIntOffset), + kDataTimeoutErrorInt = (1 << kDataTimeoutErrorIntOffset), + kDataCRCErrorInt = (1 << kDataCRCErrorIntOffset), + kDataEndBitErrorInt = (1 << kDataEndBitErrorIntOffset), + kCurrentLimitErrorInt = (1 << kCurrentLimitErrorIntOffset), + kAutoCmd12ErrorInt = (1 << kAutoCmd12ErrorIntOffset), + kADMAErrorInt = (1 << kADMAErrorIntOffset) +}; + + +void +sdhc_enableCommandStatus(SDHCRegisters_t *sdhc, bool enable) +{ + if(enable) { + sdhc->normalInterruptStatusEnable |= kCmdCompleteInt; + sdhc->errorInterruptStatusEnable |= (kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt); + } else { + sdhc->normalInterruptStatusEnable &= ~kCmdCompleteInt; + sdhc->errorInterruptStatusEnable &= ~(kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt); + } +} + +bool +sdhc_isCommandComplete(const SDHCRegisters_t *sdhc) +{ + return (sdhc->normalInterruptStatus & kCmdCompleteInt) + || (sdhc->errorInterruptStatus + & (kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt)); +} + +SDIOReturn_t +sdhc_getCommandStatus(const SDHCRegisters_t *sdhc) +{ + const UInt16 state = kCmdTimeoutErrorInt | kCmdCRCErrorInt; + const UInt16 errorStatus = sdhc->errorInterruptStatus; + + if((errorStatus & state) == state) { + return kSDIOReturnCmdLineConflict; + } else if(errorStatus & kCmdTimeoutErrorInt) { + return kSDIOReturnCmdTimeout; + } else if(errorStatus & kCmdCRCErrorInt) { + return kSDIOReturnCmdCRCError; + } else if(errorStatus & kCmdEndBitErrorInt) { + return kSDIOReturnCmdEndBitError; + } else if(errorStatus & kCmdIndexErrorInt) { + return kSDIOReturnCmdIndexError; + } else { + return kSDIOReturnSuccess; + } +} + +void +sdhc_clearCommandStatus(SDHCRegisters_t *sdhc) +{ + sdhc->normalInterruptStatus = kCmdCompleteInt; + sdhc->errorInterruptStatus = (kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt); +} + + + +#pragma mark - +#pragma mark Transfer State + +void +sdhc_enableTransferStatus(SDHCRegisters_t *sdhc, bool enable) +{ + if(enable) { + sdhc->normalInterruptStatusEnable |= kTransferCompleteInt; + sdhc->errorInterruptStatusEnable |= (kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt); + } else { + sdhc->normalInterruptStatusEnable &= ~kTransferCompleteInt; + sdhc->errorInterruptStatusEnable &= ~(kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt); + } +} + +bool +sdhc_isTransferComplete(const SDHCRegisters_t *sdhc) +{ + return (sdhc->normalInterruptStatus & kTransferCompleteInt) + || (sdhc->errorInterruptStatus + & (kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt)); +} + +SDIOReturn_t +sdhc_getTransferStatus(const SDHCRegisters_t *sdhc) +{ + const UInt16 errorStatus = sdhc->errorInterruptStatus; + + if((errorStatus & kDataTimeoutErrorInt) + && !(sdhc->normalInterruptStatus & kTransferCompleteInt)) { + return kSDIOReturnDataTimeout; + } else if(errorStatus & kDataCRCErrorInt) { + return kSDIOReturnDataCRCError; + } else if(errorStatus & kDataEndBitErrorInt) { + return kSDIOReturnDataEndBitError; + } else { + return kSDIOReturnSuccess; + } +} + +void +sdhc_clearTransferStatus(SDHCRegisters_t *sdhc) +{ + sdhc->normalInterruptStatus = kTransferCompleteInt; + sdhc->errorInterruptStatus = (kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt); +} + + + +#pragma mark - +#pragma mark PIO + +bool +sdhc_isBufferReadReady(const SDHCRegisters_t *sdhc) +{ + return sdhc->normalInterruptStatus & kBufferReadReadyInt; +} + +void +sdhc_enableBufferReadReady(SDHCRegisters_t *sdhc, bool enable) +{ + if(enable) { + sdhc->normalInterruptStatusEnable |= kBufferReadReadyInt; + } else { + sdhc->normalInterruptStatusEnable &= ~kBufferReadReadyInt; + } +} + +void +sdhc_clearBufferReadReady(SDHCRegisters_t *sdhc) +{ + sdhc->normalInterruptStatus = kBufferReadReadyInt; +} + +bool +sdhc_isBufferWriteReady(const SDHCRegisters_t *sdhc) +{ + return sdhc->normalInterruptStatus & kBufferWriteReadyInt; +} + +void +sdhc_enableBufferWriteReady(SDHCRegisters_t *sdhc, bool enable) +{ + if(enable) { + sdhc->normalInterruptStatusEnable |= kBufferWriteReadyInt; + } else { + sdhc->normalInterruptStatusEnable &= ~kBufferWriteReadyInt; + } +} + +void +sdhc_clearBufferWriteReady(SDHCRegisters_t *sdhc) +{ + sdhc->normalInterruptStatus = kBufferWriteReadyInt; +} + + + +#pragma mark - +#pragma mark Data Timeout + + +enum SDHCTimeoutControlOffset +{ + kSDHCDataTimeoutCounterOffset = 0, +}; + +enum SDHCTimeoutControl +{ + kSDHCDataTimeoutCounter = (0xF << kSDHCDataTimeoutCounterOffset), +}; + + +void +sdhc_setDataTimeoutCounter(SDHCRegisters_t *sdhc) +{ + UInt16 divisor = sdhc->clockControl & kSDClkFrequencySelect; + + // BCOM algorithm + UInt8 timeout = 7; + while(timeout && (divisor & 1) == 0) { + timeout--; + divisor >>= 1; + } + + bool on = sdhc->errorInterruptStatusEnable & kDataTimeoutErrorInt; + sdhc->errorInterruptStatusEnable &= ~kDataTimeoutErrorInt; + + sdhc->timeoutControl |= (divisor & kSDHCDataTimeoutCounter); + + if(on) { + sdhc->errorInterruptStatusEnable |= kDataTimeoutErrorInt; + } +} + + + +#pragma mark - +#pragma mark Reset + + +void +sdhc_reset(SDHCRegisters_t *sdhc, SDHCResetFlags_t flags) +{ + sdhc->softwareReset |= (flags & (kSDHCResetDataLine | kSDHCResetCmdLine | kSDHCResetAll)); +} + +SDHCResetFlags_t +sdhc_isResetting(const SDHCRegisters_t *sdhc) +{ + return sdhc->softwareReset & (kSDHCResetDataLine | kSDHCResetCmdLine | kSDHCResetAll); +} + + + +#pragma mark - +#pragma mark Interrupts + + +bool +sdhc_isSignalingInterrupt(const SDHCRegisters_t *sdhc) +{ + return (sdhc->normalInterruptStatus & sdhc->normalInterruptSignalEnable) + || (sdhc->errorInterruptStatus & sdhc->errorInterruptSignalEnable); +} + + +void +sdhc_clearInterruptSignals(SDHCRegisters_t *sdhc) +{ + UInt16 clear; + + sdhc->forceEventAutoCmd12ErrorStatus = 0; + sdhc->forceEventErrorInterruptStatus = 0; + + clear = sdhc->errorInterruptSignalEnable & sdhc->errorInterruptStatus; + + if(clear & kAutoCmd12ErrorInt) { + UInt16 cmd12Clear = sdhc->autoCmd12ErrorStatus; + sdhc->autoCmd12ErrorStatus = cmd12Clear; + } + + sdhc->errorInterruptStatus = clear; + + clear = sdhc->normalInterruptSignalEnable & sdhc->normalInterruptStatus; + sdhc->normalInterruptStatus = clear; +} + + + +#pragma mark - +#pragma mark Card Interrupt + + +bool +sdhc_isCardInterrupt(const SDHCRegisters_t *sdhc) +{ + return sdhc->normalInterruptStatus & kCardInt; +} + +void +sdhc_enableCardInterrupt(SDHCRegisters_t *sdhc, bool enable) +{ + if(enable) { + sdhc->normalInterruptStatusEnable |= kCardInt; + sdhc->normalInterruptSignalEnable |= kCardInt; + } else { + sdhc->normalInterruptStatusEnable &= ~kCardInt; + sdhc->normalInterruptSignalEnable &= ~kCardInt; + } +} + +bool +sdhc_isCardInterruptEnabled(const SDHCRegisters_t *sdhc) +{ + return sdhc->normalInterruptStatusEnable & kCardInt + && sdhc->normalInterruptSignalEnable & kCardInt; +} + + + +#pragma mark - +#pragma mark Host Control + + +enum HostControlFieldOffsets +{ + kDataTransferWidthOffset = 1, + kHighSpeedEnableOffset = 2, +}; + +enum HostControlFields +{ + kDataTransferWidth = (1 << kDataTransferWidthOffset), // 1 == 4 bit, 0 == 1 bit + kHighSpeedEnable = (1 << kHighSpeedEnableOffset), +}; + + +void +sdhc_setHighSpeedMode(SDHCRegisters_t *sdhc, bool enabled) +{ + if(enabled) { + sdhc->hostControl |= kHighSpeedEnable; + } else { + sdhc->hostControl &= ~kHighSpeedEnable; + } +} + +void +sdhc_setDataTransferWidth(SDHCRegisters_t *sdhc, UInt8 width) +{ + bool cardIntOn = sdhc_isCardInterruptEnabled(sdhc); + + sdhc_enableCardInterrupt(sdhc, false); + + if(width == 4) { + sdhc->hostControl |= kDataTransferWidth; + } else { + sdhc->hostControl &= ~kDataTransferWidth; + } + + sdhc_enableCardInterrupt(sdhc, cardIntOn); +} + + + + diff --git a/drivers/arasan/sdio/sdiocommon/sdhc_registers.h b/drivers/arasan/sdio/sdiocommon/sdhc_registers.h new file mode 100644 index 0000000..4ec8c54 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdhc_registers.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef _SDIO_SDHC_H +#define _SDIO_SDHC_H + + +#ifdef PLATFORM_VARIANT_IOP +#include +#include +#else +#include +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#pragma mark - +#pragma mark SDHC Register File + +/** Safe typedef for use of SDHCRegisters register file. */ +typedef volatile struct SDHCRegisters SDHCRegisters_t; + +/** Standard SDIO Host Controller 2.0 Register File. */ +struct SDHCRegisters +{ +// SD Command Generation: 0x00 - 0x0F + volatile UInt32 sdmaSystemAddr; + volatile UInt16 blockSize; + volatile UInt16 blockCount; + volatile UInt32 argument; + volatile UInt16 transferMode; + volatile UInt16 command; + +// Response: 0x10 - 0x1F + volatile UInt32 response[4]; + +// Buffer Data Port: 0x20 - 0x23 + volatile UInt32 bufferDataPort; + +// Host Controls: 0x24 - 0x2F + volatile UInt32 presentState; + volatile UInt8 hostControl; + volatile UInt8 powerControl; + volatile UInt8 blockGapControl; + volatile UInt8 wakeupControl; + volatile UInt16 clockControl; + volatile UInt8 timeoutControl; + volatile UInt8 softwareReset; + +// Interrupt Controls: 0x30 - 0x3D + volatile UInt16 normalInterruptStatus; + volatile UInt16 errorInterruptStatus; + volatile UInt16 normalInterruptStatusEnable; + volatile UInt16 errorInterruptStatusEnable; + volatile UInt16 normalInterruptSignalEnable; + volatile UInt16 errorInterruptSignalEnable; + volatile UInt16 autoCmd12ErrorStatus; + volatile UInt8 __reservedIntArea[2] SDIO_RESERVED; // Do not use, will change + +// Capabilities: 0x40 - 0x4F + volatile UInt64 capabilities; + volatile UInt64 maxCurrentCapabilities; + +// Force Event: 0x50 - 0x53 + volatile UInt16 forceEventAutoCmd12ErrorStatus; + volatile UInt16 forceEventErrorInterruptStatus; + +// ADMA: 0x54 - 0x5F + volatile UInt8 admaErrorStatus; + volatile UInt8 __reservedCapArea[3] SDIO_RESERVED; // Do not use, will change + volatile UInt64 admaSystemAddr; + +// Reserved: 0x60 - 0xEF + volatile UInt8 __reserved[0x90] SDIO_RESERVED; // Do not use, will change + +// Common Area: 0xF0 - 0xFF + volatile UInt8 __reservedCommonArea[0xC] SDIO_RESERVED; // Do not use, will change + volatile UInt16 slotInterruptStatus; + volatile UInt16 hostControllerVersion; +}; + + +#pragma mark - +#pragma mark SDHC Register Bits + +enum SDIOTransferModeField +{ + kSDIOTransferEnableDMA = (1 << 0), + kSDIOTransferEnableBlockCount = (1 << 1), + kSDIOTransferEnableAutoCmd12 = (1 << 2), + + kSDIOTransferReadFromCard = (1 << 4), + kSDIOTransferMultipleBlocks = (1 << 5), +}; + + +#pragma mark - +#pragma mark Capabilities + +UInt16 sdhc_getMaxBlockLength(const SDHCRegisters_t *sdhc); + +UInt32 sdhc_getBaseClockFrequencyHz(const SDHCRegisters_t *sdhc); + +bool sdhc_isSuspendResumeSupported(const SDHCRegisters_t *sdhc); + +bool sdhc_isHighSpeedSupported(const SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Present State + +bool sdhc_isCommandInhibitedOnCmd(const SDHCRegisters_t *sdhc); + +bool sdhc_isCommandInhibitedOnData(const SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Clocks + +/** @brief Sets the SD Clock rate. + * @param[in] hcReg + * Target SDIO Host Controller. + * @param[in] targetSDClkRateHz + * Desired SD Clock rate, in Hz + * @param[in] inputClkRateHz + * SD Block's input clock rate, in Hz + * @return + * The actual clock rate set, in Hz. + */ +UInt32 sdhc_setClockDividerRate(SDHCRegisters_t *sdhc, UInt32 targetSDClkRateHz, UInt32 inputClkRateHz); + +void sdhc_setClockDivider(SDHCRegisters_t *sdhc, UInt16 divider); + +UInt16 sdhc_getClockDivider(const SDHCRegisters_t *sdhc); + +void sdhc_enableInternalClock(SDHCRegisters_t *sdhc, bool enable); + +bool sdhc_isInternalClockStable(const SDHCRegisters_t *sdhc); + +void sdhc_enableSDClock(SDHCRegisters_t *sdhc, bool enable); + +bool sdhc_isSDClockEnabled(const SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Block Size + +void sdhc_setBlockSize(SDHCRegisters_t *sdhc, UInt16 size); + + +#pragma mark - +#pragma mark Commands + +void sdhc_copyCommandResponse(const SDHCRegisters_t *sdhc, struct SDIOCommandResponse *response); + + +#pragma mark - +#pragma mark Command State + +/** @brief Enable/Disable status bits needed for command completion and error checking. */ +void sdhc_enableCommandStatus(SDHCRegisters_t *sdhc, bool enable); + +/** @brief True if the command has completed for any reason. */ +bool sdhc_isCommandComplete(const SDHCRegisters_t *sdhc); + +/** @brief Gets the command status after completion. */ +SDIOReturn_t sdhc_getCommandStatus(const SDHCRegisters_t *sdhc); + +/** @brief Clear status bits needed for command completion and error checking. */ +void sdhc_clearCommandStatus(SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Transfer State + +/** @brief Enable/Disable status bits needed for transfer completion and error checking. */ +void sdhc_enableTransferStatus(SDHCRegisters_t *sdhc, bool enable); + +/** @brief True if the transfer has completed for any reason. */ +bool sdhc_isTransferComplete(const SDHCRegisters_t *sdhc); + +/** @brief Gets the current transfer status after completion. */ +SDIOReturn_t sdhc_getTransferStatus(const SDHCRegisters_t *sdhc); + +/** @brief Clear status bits needed for transfer completion and error checking. */ +void sdhc_clearTransferStatus(SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark PIO + +bool sdhc_isBufferReadReady(const SDHCRegisters_t *sdhc); + +void sdhc_enableBufferReadReady(SDHCRegisters_t *sdhc, bool enable); + +void sdhc_clearBufferReadReady(SDHCRegisters_t *sdhc); + +bool sdhc_isBufferWriteReady(const SDHCRegisters_t *sdhc); + +void sdhc_enableBufferWriteReady(SDHCRegisters_t *sdhc, bool enable); + +void sdhc_clearBufferWriteReady(SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Data Timeout + +void sdhc_setDataTimeoutCounter(SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Reset + +enum SDHCResetFlags +{ + kSDHCResetAll = (1 << 0), + kSDHCResetCmdLine = (1 << 1), + kSDHCResetDataLine = (1 << 2), +}; +typedef UInt8 SDHCResetFlags_t; + +void sdhc_reset(SDHCRegisters_t *sdhc, SDHCResetFlags_t flags); + +SDHCResetFlags_t sdhc_isResetting(const SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Interrupts + +bool sdhc_isSignalingInterrupt(const SDHCRegisters_t *sdhc); + +/** @brief Clear all interrupt signals. + * Only the status fields that are signaling an interrupt are cleared. + */ +void sdhc_clearInterruptSignals(SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Card Interrupt + +bool sdhc_isCardInterrupt(const SDHCRegisters_t *sdhc); + +void sdhc_enableCardInterrupt(SDHCRegisters_t *sdhc, bool enable); + +bool sdhc_isCardInterruptEnabled(const SDHCRegisters_t *sdhc); + + +#pragma mark - +#pragma mark Host Control + +void sdhc_setHighSpeedMode(SDHCRegisters_t *sdhc, bool enabled); + +void sdhc_setDataTransferWidth(SDHCRegisters_t *sdhc, UInt8 width); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _SDIO_SDHC_H */ + diff --git a/drivers/arasan/sdio/sdiocommon/sdio_cccr.h b/drivers/arasan/sdio/sdiocommon/sdio_cccr.h new file mode 100644 index 0000000..d50b943 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdio_cccr.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef _SDIO_CCCR_H_ +#define _SDIO_CCCR_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +enum SDIOCccrRegisterAddress +{ + kSDIOCccrRevisionAddr = 0x00, + kSDIOCccrSpecRevAddr = 0x01, + kSDIOCccrIOEnableAddr = 0x02, + kSDIOCccrIOReadyAddr = 0x03, + kSDIOCccrIntEnableAddr = 0x04, + kSDIOCccrIntPendingAddr = 0x05, + kSDIOCccrIOAbortAddr = 0x06, + kSDIOCccrBusInterfaceControlAddr= 0x07, + kSDIOCccrCardCapabilityAddr = 0x08, + kSDIOCccrCommonCISPtrLowAddr = 0x09, + kSDIOCccrCommonCISPtrMidAddr = 0x0A, + kSDIOCccrCommonCISPtrHighAddr = 0x0B, + kSDIOCccrBusSuspendAddr = 0x0C, + kSDIOCccrFunctionSelectAddr = 0x0D, + kSDIOCccrExecFlagsAddr = 0x0E, + kSDIOCccrReadyFlagsAddr = 0x0F, + kSDIOCccrFn0BlockSizeLSBAddr = 0x10, + kSDIOCccrFn0BlockSizeMSBAddr = 0x11, + kSDIOCccrPowerControlAddr = 0x12, + kSDIOCccrHighSpeedAddr = 0x13, +}; + + +// Bus Interface Control +enum SDIOCccrBusInterfaceControlMask +{ + kSDIOCccrBusWidthMask = (1 << 1) | (1 << 0), +}; + +enum SDIOCccrBusInterfaceControl +{ + kSDIOCccrBusIfWidth1Bit = ((0 << 1)|(0 << 0)), + kSDIOCccrBusIfWidth4Bit = ((1 << 1)|(0 << 0)), + + kSDIOCccrBusIfContinuousSPIIntEnabled = (1 << 5), + kSDIOCccrBusIfContinuousSPIInt = (1 << 6), + kSDIOCccrBusIfCardDetectDisable = (1 << 7), +}; + + +// Card Capabilities + +enum SDIOCccrCardCapability +{ + kSDIOCccrCapDirectCommands = (1 << 0), + kSDIOCccrCapMultiBlock = (1 << 1), + kSDIOCccrCapReadWait = (1 << 2), + kSDIOCccrCapSuspendResume = (1 << 3), + kSDIOCccrCap4BitIntraBlockInt = (1 << 4), + kSDIOCccrCap4BitIntraBlockIntEnable = (1 << 5), + kSDIOCccrCapLowSpeed = (1 << 6), + kSDIOCccrCap4BitLowSpeed = (1 << 7), +}; + + +// High Speed + +enum SDIOCccrHighSpeed +{ + kSDIOCccrHighSpeedSupported = (1 << 0), + kSDIOCccrHighSpeedEnabled = (1 << 1), +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* _SDIO_CCCR_H_ */ diff --git a/drivers/arasan/sdio/sdiocommon/sdio_cis.h b/drivers/arasan/sdio/sdiocommon/sdio_cis.h new file mode 100644 index 0000000..82e89d6 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdio_cis.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef _SDIO_CIS_H +#define _SDIO_CIS_H + + +#ifdef PLATFORM_VARIANT_IOP +#include +#include +#else +#include +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +enum SDIOCISTupleCode { + kSDIOCISTupleNull = 0x00, + kSDIOCISTupleChecksum = 0x10, + kSDIOCISTupleVers1 = 0x15, + kSDIOCISTupleManfID = 0x20, + kSDIOCISTupleFuncID = 0x21, + kSDIOCISTupleFuncE = 0x22, + + kSDIOCISTupleSDIOStd = 0x91, + kSDIOCISTupleSDIOExt = 0x92, + kSDIOCISTupleEnd = 0xFF, + + kSDIOCISTupleVendor80 = 0x80, + kSDIOCISTupleVendor81 = 0x81, + kSDIOCISTupleVendor82 = 0x82, + kSDIOCISTupleVendor83 = 0x83, + kSDIOCISTupleVendor84 = 0x84, + kSDIOCISTupleVendor85 = 0x85, + kSDIOCISTupleVendor86 = 0x86, + kSDIOCISTupleVendor87 = 0x87, + kSDIOCISTupleVendor88 = 0x88, + kSDIOCISTupleVendor89 = 0x89, + kSDIOCISTupleVendor8A = 0x8A, + kSDIOCISTupleVendor8B = 0x8B, + kSDIOCISTupleVendor8C = 0x8C, + kSDIOCISTupleVendor8D = 0x8D, + kSDIOCISTupleVendor8E = 0x8E, + kSDIOCISTupleVendor8F = 0x8F, +}; + +enum SDIOCISTupleHeaderSize +{ + kSDIOCISTupleSpecialHeaderSize = 1 * sizeof(UInt8), + kSDIOCISTupleStandardHeaderSize = 2 * sizeof(UInt8), +}; + + +struct SDIOCISTupleChecksum +{ + UInt16 address; + UInt16 length; + UInt8 checksum; +} SDIO_PACKED; + + +struct SDIOCISTupleVers1 +{ + UInt8 major; + UInt8 minor; + UInt8 strings[0]; +} SDIO_PACKED; + +enum +{ + kSDIOCISTupleVers1NumStrings = 4, + + /** Minimum size of the Vers1 body. + * This is: major + minor + NULL for each string + end of chain + */ + kSDIOCISTupleVers1MinBodySize = 2 + kSDIOCISTupleVers1NumStrings + 1, +}; + + +struct SDIOCISTupleManfID +{ + UInt16 manufacturerID; + UInt16 cardID; +} SDIO_PACKED; + +struct SDIOCISTupleFuncID +{ + UInt8 functionCode; + UInt8 sysVInitMask; +} SDIO_PACKED; + +struct SDIOCISTupleFunc0E +{ + UInt8 type; + UInt16 fn0BlockSize; + UInt8 maxTransferSpeed; +} SDIO_PACKED; + +struct SDIOCISTupleFuncE +{ + UInt8 type; + UInt8 functionInfo; + UInt8 stdIORev; + UInt32 cardPSN; + UInt32 csaSize; + UInt8 csaProperty; + UInt16 maxBlockSize; + UInt32 ocr; + UInt8 operatingMinPower; + UInt8 operatingpAvgPower; + UInt8 operatingMaxPower; + UInt8 standbyMinPower; + UInt8 standbyAvgPower; + UInt8 standbyMaxPower; + UInt16 minBandwidth; + UInt16 optimalBandwidth; + UInt16 enableTimeoutValue; + UInt16 spAvgPower33; + UInt16 spMaxPower33; + UInt16 highCurrentAvgPower33; + UInt16 highCurrentMaxPower33; + UInt16 lowCurrentAvgPower33; + UInt16 lowCurrentMaxPower33; +} SDIO_PACKED; + +struct SDIOCISTupleStd +{ + UInt8 stdID; + UInt8 stdType; + UInt8 stdData[0]; +} SDIO_PACKED; + +struct SDIOCISTupleExt +{ + UInt8 extData[0]; +} SDIO_PACKED; + + +struct SDIOCisTupleHeader +{ + UInt8 code; + UInt8 link; +} SDIO_PACKED; + +union SDIOCisTupleBody +{ + struct SDIOCISTupleChecksum checksumTpl; + struct SDIOCISTupleVers1 vers1Tpl; + struct SDIOCISTupleManfID manfIDTpl; + struct SDIOCISTupleFuncID funcIDTpl; + struct SDIOCISTupleFunc0E func0ETpl; + struct SDIOCISTupleFuncE funcETpl; + struct SDIOCISTupleStd stdTpl; + struct SDIOCISTupleExt extTpl; + UInt8 byte[0]; +} SDIO_PACKED; + +struct SDIOCISTuple +{ + struct SDIOCisTupleHeader header; + union SDIOCisTupleBody body; +} SDIO_PACKED; + + +#ifdef __cplusplus +} +#endif + + +#endif /* _SDIO_CIS_H */ + diff --git a/drivers/arasan/sdio/sdiocommon/sdio_cmdfields.c b/drivers/arasan/sdio/sdiocommon/sdio_cmdfields.c new file mode 100644 index 0000000..dd3686e --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdio_cmdfields.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "sdio_cmdfields.h" + + +#pragma mark - +#pragma mark Common + +enum CommandOffset +{ + kSDIOCmdAddressOffset = 9, + kSDIOCmdFunctionOffset = 28, +}; + +enum CommandMask +{ + kSDIOCmdFunctionMask = 0x7, + kSDIOCmdAddressMask = 0x1FFFF, +}; + +enum SDIOCmdDirection +{ + kSDIOCmdDirectionRead = (0 << 31), + kSDIOCmdDirectionWrite = (1 << 31), +}; + + +static inline UInt32 +convertFunctionToArg(UInt8 function) +{ + return (function & kSDIOCmdFunctionMask) << kSDIOCmdFunctionOffset; +} + +static inline UInt32 +convertAddressToArg(UInt32 address) +{ + return (address & kSDIOCmdAddressMask) << kSDIOCmdAddressOffset; +} + + + +enum SDIODirection +sdio_getCommandDirection(enum SDIOCommandIndex index, UInt32 argument) +{ + switch (index) { + case kSDIOCmd52_IORWDirect: + case kSDIOCmd53_IORWExtended: + return (argument & kSDIOCmdDirectionWrite) ? kSDIODirectionWrite : kSDIODirectionRead; + default: + return kSDIODirectionNone; + } +} + + +#pragma mark - +#pragma mark Cmd5 + +UInt32 +sdio_getOCR(const struct SDIOCommandResponse *cmd5Response) +{ + return cmd5Response->response[0] & 0x00fffff; +} + +bool +sdio_getNumIOFunctions(const struct SDIOCommandResponse *cmd5Response) +{ + return (cmd5Response->response[0] & 0x70000000) >> 28; +} + +bool +sdio_isMemoryPresent(const struct SDIOCommandResponse *cmd5Response) +{ + return cmd5Response->response[0] & 0x08000000; // >> 27 +} + +bool +sdio_isIOReady(const struct SDIOCommandResponse *cmd5Response) +{ + return cmd5Response->response[0] & 0x80000000; // >> 31 +} + + + + +#pragma mark - +#pragma mark Cmd52 + + +UInt32 +sdio_generateCmd52Arg(enum SDIODirection direction, + UInt8 sdioFunction, UInt32 cardAddress, UInt8 data, + SDIOCmd52Flags flags) +{ + UInt32 dir = (direction & kSDIODirectionWrite) ? kSDIOCmdDirectionWrite : kSDIOCmdDirectionRead; + + return dir | convertFunctionToArg(sdioFunction) | flags + | convertAddressToArg(cardAddress) | data; +} + + + +#pragma mark - +#pragma mark Cmd53 + +enum SDIOCmd53Mask +{ + kSDIOCmd53CountMask = 0x1FF +}; + + +static inline UInt32 +convertCmd53CountToArg(UInt32 count) +{ + return (count & kSDIOCmd53CountMask); +} + + +UInt32 +sdio_generateCmd53Arg(enum SDIODirection direction, + UInt8 sdioFunction, UInt32 cardAddress, UInt16 count, + SDIOCmd53Flags flags) +{ + UInt32 dir = (direction & kSDIODirectionWrite) ? kSDIOCmdDirectionWrite : kSDIOCmdDirectionRead; + + return dir | convertFunctionToArg(sdioFunction) | flags + | convertAddressToArg(cardAddress) | convertCmd53CountToArg(count); +} + +UInt16 +sdio_getCmd53Count(UInt32 cmdArg) +{ + return cmdArg & kSDIOCmd53CountMask; +} + + diff --git a/drivers/arasan/sdio/sdiocommon/sdio_cmdfields.h b/drivers/arasan/sdio/sdiocommon/sdio_cmdfields.h new file mode 100644 index 0000000..8b05ff3 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdio_cmdfields.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef _SDIO_CMDFIELDS_H_ +#define _SDIO_CMDFIELDS_H_ + + +#ifdef PLATFORM_VARIANT_IOP +#include +#include +#else +#include +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#pragma mark - +#pragma mark Common + +enum SDIODirection sdio_getCommandDirection(enum SDIOCommandIndex index, UInt32 argument); + + + +#pragma mark - +#pragma mark Cmd 5 + +enum SDIOCmd5OperationConditions { + kSDIOOpCond_None = (0x000000), + + kSDIOOpCond_20_21 = (1 << 8), + kSDIOOpCond_21_22 = (1 << 9), + kSDIOOpCond_22_23 = (1 << 10), + kSDIOOpCond_23_24 = (1 << 11), + kSDIOOpCond_24_25 = (1 << 12), + kSDIOOpCond_25_26 = (1 << 13), + kSDIOOpCond_26_27 = (1 << 14), + kSDIOOpCond_27_28 = (1 << 15), + kSDIOOpCond_28_29 = (1 << 16), + kSDIOOpCond_29_30 = (1 << 17), + kSDIOOpCond_30_31 = (1 << 18), + kSDIOOpCond_31_32 = (1 << 19), + kSDIOOpCond_32_33 = (1 << 20), + kSDIOOpCond_33_34 = (1 << 21), + kSDIOOpCond_34_35 = (1 << 22), + kSDIOOpCond_35_36 = (1 << 23), + + kSDIOOpCond_All = (0xFFFF00) +}; + +UInt32 sdio_getOCR(const struct SDIOCommandResponse *cmd5Response); + +bool sdio_getNumIOFunctions(const struct SDIOCommandResponse *cmd5Response); + +bool sdio_isMemoryPresent(const struct SDIOCommandResponse *cmd5Response); + +bool sdio_isIOReady(const struct SDIOCommandResponse *cmd5Response); + + + +#pragma mark - +#pragma mark Cmd 52 + + +enum SDIOCmd52Flag +{ + kSDIOCmd52RAW = (1 << 27), +}; + +typedef UInt32 SDIOCmd52Flags; + + +UInt32 sdio_generateCmd52Arg(enum SDIODirection direction, + UInt8 sdioFunction, UInt32 cardAddress, UInt8 data, + SDIOCmd52Flags flags); + + + +#pragma mark - +#pragma mark Cmd 53 + + +enum SDIOCmd53Flag +{ + kSDIOCmd53ByteMode = (0 << 27), + kSDIOCmd53BlockMode = (1 << 27), + kSDIOCmd53FixedAddress = (0 << 26), + kSDIOCmd53IncrementAddress = (1 << 26), +}; + +typedef UInt32 SDIOCmd53Flags; + + +UInt32 sdio_generateCmd53Arg(enum SDIODirection direction, + UInt8 sdioFunction, UInt32 cardAddress, UInt16 count, + SDIOCmd53Flags flags); + +UInt16 sdio_getCmd53Count(UInt32 cmdArg); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _SDIO_CMDFIELDS_H_ */ + diff --git a/drivers/arasan/sdio/sdiocommon/sdio_cmdprop.c b/drivers/arasan/sdio/sdiocommon/sdio_cmdprop.c new file mode 100644 index 0000000..522615d --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdio_cmdprop.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "sdio_cmdprop.h" + +#include "sdio_types.h" + + +enum CommandRegFieldOffsets +{ + kResponseTypeOffset = 0, + kCmdCRCCheckEnabledOffset = 3, + kCmdIndexCheckEnabledOffset = 4, + kDataPresentSelectOffset = 5, + kCommandTypeOffset = 6, + kCommandIndexOffset = 8, +}; + +enum CommandRegFieldMasks +{ + kResponseTypeSelectMask = (0x3 << kResponseTypeOffset), + kCmdCRCCheckEnabled = (1 << kCmdCRCCheckEnabledOffset), + kCmdIndexCheckEnabled = (1 << kCmdIndexCheckEnabledOffset), + kDataPresentSelect = (1 << kDataPresentSelectOffset), + kCommandTypeMask = (0x3 << kCommandTypeOffset), + kCommandIndexMask = (0x3F << kCommandIndexOffset), +}; + +enum CommandRegCommandType +{ + kSDIOCommandNormal = (0x0 << kCommandTypeOffset), + kSDIOCommandSuspend = (0x1 << kCommandTypeOffset), + kSDIOCommandResume = (0x2 << kCommandTypeOffset), + kSDIOCommandAbort = (0x3 << kCommandTypeOffset), +}; + +enum CommandRegResponseTypeSelect +{ + kNoResponse = (0x0 << kResponseTypeOffset), + kResponseLength136 = (0x1 << kResponseTypeOffset), + kResponseLength48 = (0x2 << kResponseTypeOffset), + kResponseLength48CheckBusy = (0x3 << kResponseTypeOffset), +}; + + +bool +sdio_isDataPresent(UInt16 cmdIndex) +{ + // TODO: Support other data commands + return kSDIOCmd53_IORWExtended == cmdIndex; +} + +static bool +sdio_shouldCheckIndex(UInt16 cmdIndex) +{ + return cmdIndex != kSDIOCmd5_IOSendOpCond; +} + +static bool +sdio_shouldCheckCRC(UInt16 cmdIndex) +{ + return cmdIndex != kSDIOCmd5_IOSendOpCond; +} + +static enum CommandRegResponseTypeSelect +sdio_getResponseType(UInt16 cmdIndex) +{ + // TODO: Support other response types + return kResponseLength48; +} + +UInt16 sdio_generateCommand(UInt16 cmdIndex) +{ + UInt16 cmd = 0; + + // Command Index + cmd |= (cmdIndex << kCommandIndexOffset) & kCommandIndexMask; + + // Command Type + // TODO: Support abort & suspend / resume commands + cmd |= kSDIOCommandNormal; + + // Data present select + if(sdio_isDataPresent(cmdIndex)) { + cmd |= kDataPresentSelect; + } + + // Command Index Check + if(sdio_shouldCheckIndex(cmdIndex)) { + cmd |= kCmdIndexCheckEnabled; + } + + // Command CRC Check + if(sdio_shouldCheckCRC(cmdIndex)) { + cmd |= kCmdCRCCheckEnabled; + } + + // Response type select + cmd |= sdio_getResponseType(cmdIndex); + + return cmd; +} + + + diff --git a/drivers/arasan/sdio/sdiocommon/sdio_cmdprop.h b/drivers/arasan/sdio/sdiocommon/sdio_cmdprop.h new file mode 100644 index 0000000..c6b01b9 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdio_cmdprop.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef _SDIO_CMDPROP_H +#define _SDIO_CMDPROP_H + + +#ifdef PLATFORM_VARIANT_IOP +#include +#else +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief true if the command has an associated data transfer. */ +bool sdio_isDataPresent(UInt16 cmdIndex); + +/** @brief Generates the value for the command register. */ +UInt16 sdio_generateCommand(UInt16 cmdIndex); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _SDIO_CMDPROP_H */ + diff --git a/drivers/arasan/sdio/sdiocommon/sdio_types.h b/drivers/arasan/sdio/sdiocommon/sdio_types.h new file mode 100644 index 0000000..87242f2 --- /dev/null +++ b/drivers/arasan/sdio/sdiocommon/sdio_types.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef _SDIO_TYPES_H_ +#define _SDIO_TYPES_H_ + + +#ifdef PLATFORM_VARIANT_IOP +#include +#else +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ +#define SDIO_PACKED __attribute__((packed)) +#define SDIO_DEPRECATED __attribute__((deprecated)) +#define SDIO_RESERVED __attribute__((deprecated)) +#else +#error Unknown Compiler +#endif + + +typedef UInt32 IOSDIOClockRate; + +enum +{ + kIOSDIOMaxClockRate = 50000000 +}; + +enum IOSDIOClockMode +{ + kIOSDIOClockOff = -1, + kIOSDIOClockOn = +1 +}; + +enum IOSDIOBusWidth +{ + kIOSDIO1BitMode = 1, + kIOSDIO4BitMode = 4 +}; + +enum IOSDIOBusSpeedMode +{ + kIOSDIONormalSpeed = 1, + kIOSDIOHighSpeed = 2 +}; + + +enum SDIOCommandIndex +{ + kSDIOCmd0_GoIdleState = 0, + kSDIOCmd1_SendOpCond = 1, + kSDIOCmd2_AllSendCID = 2, + kSDIOCmd3_SendRelativeAddr = 3, + kSDIOCmd4_SetDSR = 4, + kSDIOCmd5_IOSendOpCond = 5, + kSDIOCmd6_SwitchFunc = 6, + kSDIOCmd7_SelectDeselectCard = 7, + kSDIOCmd9_SendCSD = 9, + kSDIOCmd10_SendCID = 10, + kSDIOCmd12_StopTransmission = 12, + kSDIOCmd13_SendStatus = 13, + kSDIOCmd15_GoInactiveState = 15, + kSDIOCmd16_SetBlockLength = 16, + kSDIOCmd17_ReadSingleBlock = 17, + kSDIOCmd18_ReadMultipleBlock = 18, + kSDIOCmd24_WriteBlock = 24, + kSDIOCmd25_WriteMultipleBlock = 25, + kSDIOCmd27_ProgramCSD = 27, + kSDIOCmd28_SetWriteProt = 28, + kSDIOCmd29_ClearWriteProt = 29, + kSDIOCmd30_SendWriteProt = 30, + kSDIOCmd32_EraseWrBlkStart = 32, + kSDIOCmd33_EraseWrBlkEnd = 33, + kSDIOCmd38_Erase = 38, + kSDIOCmd42_LockUnlock = 42, + kSDIOCmd52_IORWDirect = 52, + kSDIOCmd53_IORWExtended = 53, + kSDIOCmd55_AppCmd = 55, + kSDIOCmd56_GenCmd = 56, + kSDIOCmd58_ReadOCR = 58, + kSDIOCmd59_CRCOnOff = 59, + + kSDIOAcmd6_SetBusWidth = 6, + kSDIOAcmd13_SDStatus = 13, + kSDIOAcmd22_SendNumWrBlocks = 22, + kSDIOAcmd23_SetWrBlkEraseCount = 23, + kSDIOAcmd41_SDAppOpCond = 41, + kSDIOAcmd42_SetClrCardDetect = 42, + kSDIOAcmd51_SendSCR = 51, +}; + +enum SDIODirection +{ + kSDIODirectionNone = 0, // Same as kIODirectionNone + kSDIODirectionRead = (1 << 0), // Same as kIODirectionIn + kSDIODirectionWrite = (1 << 1), // Same as kIODirectionOut +}; + +struct SDIOCommand +{ + UInt16 index; // SDIOCommandIndex + UInt32 argument; +}; + +struct SDIOCommandResponse +{ + UInt32 response[4]; +}; + +struct SDIOMemorySegments +{ + UInt64 dataLength; + UInt32 segmentCount; + void *segmentList; +}; + +struct SDIOTransfer +{ + struct SDIOCommand command; + UInt8 direction; // SDIODirection + UInt16 blockSize; + UInt16 blockCount; +}; + + + +enum SDIOReturn +{ + /** @brief Success. */ + kSDIOReturnSuccess = 0, + +// Generic IOReturn-derived Errors + + /** @brief Invalid Argument. */ + kSDIOReturnBadArgument = 0x2c2, + + /** @brief Can't allocate memory. */ + kSDIOReturnNoMemory = 0x2bd, + + +// General SDIO Errors + + /** @brief General SDIO Error. */ + kSDIOReturnSDIOError = 0x300, + + +// Host Controller Errors + + /** @brief General Host Controller Error. */ + kSDIOReturnSDHCError = 0x400, + + /** @brief Host controller physical address invalid. */ + kSDIOReturnNoHostController = 0x401, + + /** @brief Couldn't perform command because SD Clock is disabled. */ + kSDIOReturnInternalClockUnstable= 0x402, + + /** @brief Couldn't perform command because SD Clock is disabled. */ + kSDIOReturnSDClockDisabled = 0x403, + + /** @brief Failed due to errors in ADMA transfer. */ + kSDIOReturnADMAError = 0x404, + + /** @brief Failed due to errors in SDMA transfer. */ + kSDIOReturnSDMAError = 0x405, + + /** @brief Error performing Auto CMD12. */ + kSDIOReturnAutoCMD12Error = 0x406, + + /** @brief HC not supplying power to card. */ + kSDIOReturnCurrentLimitError = 0x407, + + /** @brief Vendor-specific error. */ + kSDIOReturnVendorError = 0x408, + + /** @brief Device in reset. */ + kSDIOReturnInReset = 0x409, + + /** @brief Block never signaled command complete. */ + kSDIOReturnNoCmdComplete = 0x40A, + + /** @brief Block never signaled transfer complete. */ + kSDIOReturnNoTransferComplete = 0x40B, + + /** @brief DMA transfer timed out. */ + kSDIOReturnDMATimeout = 0x40C, + + +// Card Errors + + /** @brief General Card Error. */ + kSDIOReturnCardError = 0x500, + + /** @brief Failed because no card is inserted. */ + kSDIOReturnNoCard = 0x501, + + /** @brief Failed because the card was ejected. */ + kSDIOReturnCardEjected = 0x502, + + /** @brief Failed because card is write protected. */ + kSDIOReturnWriteProtected = 0x503, + + +// Problems on SDIO Command Line + + /** @brief General SDIO Cmd line error. */ + kSDIOReturnCmdError = 0x600, + + /** @brief SDIO Cmd line is busy. */ + kSDIOReturnCmdLineBusy = 0x601, + + /** @brief SDIO Cmd line's signal level is incorrect. */ + kSDIOReturnCmdSignalInvalid = 0x602, + + /** @brief Command index error in response. */ + kSDIOReturnCmdIndexError = 0x603, + + /** @brief Conflict on SDIO Command Line. */ + kSDIOReturnCmdLineConflict = 0x604, + + /** @brief SDIO Cmd failed with a CRC error. */ + kSDIOReturnCmdCRCError = 0x605, + + /** @brief SDIO Cmd failed with a End Bit error. */ + kSDIOReturnCmdEndBitError = 0x606, + + /** @brief SDIO Cmd Timed out (no response. */ + kSDIOReturnCmdTimeout = 0x607, + + +// Problems on SDIO Data Line + + /** @brief General SDIO Data Line Error. */ + kSDIOReturnDataError = 0x700, + + /** @brief SDIO Data line is busy. */ + kSDIOReturnDataLineBusy = 0x701, + + /** @brief SDIO Data line's signal level is incorrect. */ + kSDIOReturnDataSignalInvalid = 0x702, + + /** @brief SDIO Data failed with a CRC error. */ + kSDIOReturnDataCRCError = 0x703, + + /** @brief SDIO Data failed with a CRC error. */ + kSDIOReturnDataEndBitError = 0x704, + + /** @brief SDIO Data Timed out (no response. */ + kSDIOReturnDataTimeout = 0x705, +}; + +typedef enum SDIOReturn SDIOReturn_t; + + + +#ifdef __cplusplus +} +#endif + +#endif /* _SDIO_TYPES_H_ */ + diff --git a/drivers/arasan/sdio/sdiodrv_command.c b/drivers/arasan/sdio/sdiodrv_command.c new file mode 100644 index 0000000..2c74a94 --- /dev/null +++ b/drivers/arasan/sdio/sdiodrv_command.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "sdiodrv_command.h" + +#include + +#include +#include + +#include "sdiocommon/sdhc_debug.h" +#include "sdiocommon/sdio_cmdprop.h" +#include "sdiodrv_config.h" + + + +#define CMD_INHIBITED_CHECKS (20) +#define CMD_INHIBITED_WAIT (5) +#define DATA_INHIBITED_CHECKS (20) +#define DATA_INHIBITED_WAIT (5) +#define COMMAND_COMPLETE_CHECKS (1000) + + +static SDIOReturn_t +sdiodrv_prepareCommand(const SDHCRegisters_t *sdhc) +{ + if(sdhc_isCommandInhibitedOnCmd(sdhc)) { + dprintf(DEBUG_CRITICAL, "SDHC @ %p: Command inhibited!\n", sdhc); + + for(unsigned int i=0; sdhc_isCommandInhibitedOnCmd(sdhc) && i < CMD_INHIBITED_CHECKS; i++) { + task_sleep(CMD_INHIBITED_WAIT); + } + + if(sdhc_isCommandInhibitedOnCmd(sdhc)) { + return kSDIOReturnCmdLineBusy; + } + } + + // TODO: Handle busy and abort +/* if(issueWithBusy && !issueAbortCommand) { + if(sdhc_isCommandInhibitedOnData(sdhc)) { + dprintf(DEBUG_CRITICAL, "SDHC @ %p: Data inhibited!\n", sdhc); + + for(unsigned int i=0; sdhc_isCommandInhibitedOnData(sdhc) && i < DATA_INHIBITED_CHECKS; i++) { + task_sleep(DATA_INHIBITED_WAIT); + } + + if(sdhc_isCommandInhibitedOnData(sdhc)) { + return kSDIOReturnDataLineBusy; + } + } + } +*/ + return kSDIOReturnSuccess; +} + + + +static SDIOReturn_t +sdiodrv_completeCommand(SDHCRegisters_t *sdhc, struct SDIOCommandResponse *response) +{ + SDIOReturn_t retval = sdhc_getCommandStatus(sdhc); + + if(kSDIOReturnSuccess != retval) { + dprintf(DEBUG_CRITICAL, "%s: SDIO Cmd Failed (0x%X): cmd = 0x%X, arg = 0x%X, resp0 = 0x%X, normalInt = 0x%X, errorInt = 0x%X, state = 0x%X\n", __func__, + retval, sdhc->command, sdhc->argument, sdhc->response[0], + sdhc->normalInterruptStatus, sdhc->errorInterruptStatus, sdhc->presentState); + + sdiodrv_resetSDHC(sdhc, kSDHCResetCmdLine); + } + + sdhc_clearCommandStatus(sdhc); + + sdhc_copyCommandResponse(sdhc, response); + + return retval; +} + +SDIOReturn_t +sdiodrv_sendSDIOCommand(SDHCRegisters_t *sdhc, + const struct SDIOCommand *command, + struct SDIOCommandResponse *response) +{ + check(command); + + return sdiodrv_sendCommand(sdhc, command->index, command->argument, response); +} + +SDIOReturn_t +sdiodrv_sendCommand(SDHCRegisters_t *sdhc, UInt16 commandIndex, UInt32 commandArg, struct SDIOCommandResponse *response) +{ + check(sdhc); + check(response); + + SDIOReturn_t retval = sdiodrv_prepareCommand(sdhc); + if(kSDIOReturnSuccess != retval) { + return retval; + } + + sdhc->argument = commandArg; + + UInt16 command = sdio_generateCommand(commandIndex); + +// dprintf(DEBUG_INFO, "%s: cmd = 0x%04X, arg = 0x%08X\n", __func__, +// command, sdhc->argument); +// sdhc_dumpRegisterFile(sdhc); + + sdhc->command = command; + + for(unsigned int i=0; !sdhc_isCommandComplete(sdhc); i++) { + if(i >= COMMAND_COMPLETE_CHECKS) { + dprintf(DEBUG_CRITICAL, "%s: No command complete after %u checks: cmd = 0x%X, arg = 0x%X, normalInt = 0x%X, errorInt = 0x%X, state = 0x%X\n", + __func__, COMMAND_COMPLETE_CHECKS, + sdhc->command, sdhc->argument, + sdhc->normalInterruptStatus, sdhc->errorInterruptStatus, sdhc->presentState); + + sdiodrv_resetSDHC(sdhc, kSDHCResetCmdLine); + + return kSDIOReturnNoCmdComplete; + } + + task_yield(); + } + + retval = sdiodrv_completeCommand(sdhc, response); + + return retval; +} + + + diff --git a/drivers/arasan/sdio/sdiodrv_command.h b/drivers/arasan/sdio/sdiodrv_command.h new file mode 100644 index 0000000..40e1b97 --- /dev/null +++ b/drivers/arasan/sdio/sdiodrv_command.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _SDIODRV_COMMAND_H +#define _SDIODRV_COMMAND_H + + +#include +#include + + +struct SDIOCommand; +struct SDIOCommandResponse; + +/** @brief Sends an SDIO Command. + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in] commandIndex + * The number of the command to perform. + * @param[in] commandArg + * The command argument. + * @param[out] response + * The response to the SDIO command. + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnCmdLineBusy - Command line already in use + * kSDIOReturnNoCmdComplete - Command complete status never set in SDHC + * kSDIOReturnCmdLineConflict - Line voltage doesn't match what was driven + * kSDIOReturnCmdTimeout - SDHC timed out waiting for command response + * kSDIOReturnCmdCRCError - SDHC detected a CRC error in command + * kSDIOReturnCmdEndBitError - SDHC detected an end-bit error in command + * kSDIOReturnCmdIndexError - Command index in response doesn't match request + */ +SDIOReturn_t sdiodrv_sendCommand(SDHCRegisters_t *sdhc, + UInt16 commandIndex, + UInt32 commandArg, + struct SDIOCommandResponse *response); + +/** @brief Sends an SDIO Command. + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in] command + * The command parameters. + * @param[out] response + * The response to the SDIO command. + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnCmdLineBusy - Command line already in use + * kSDIOReturnNoCmdComplete - Command complete status never set in SDHC + * kSDIOReturnCmdLineConflict - Line voltage doesn't match what was driven + * kSDIOReturnCmdTimeout - SDHC timed out waiting for command response + * kSDIOReturnCmdCRCError - SDHC detected a CRC error in command + * kSDIOReturnCmdEndBitError - SDHC detected an end-bit error in command + * kSDIOReturnCmdIndexError - Command index in response doesn't match request + */ +SDIOReturn_t sdiodrv_sendSDIOCommand(SDHCRegisters_t *sdhc, + const struct SDIOCommand *command, + struct SDIOCommandResponse *response); + + +#endif /* _SDIODRV_COMMAND_H */ + diff --git a/drivers/arasan/sdio/sdiodrv_config.c b/drivers/arasan/sdio/sdiodrv_config.c new file mode 100644 index 0000000..5a2b0e1 --- /dev/null +++ b/drivers/arasan/sdio/sdiodrv_config.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "sdiodrv_config.h" + +#include + +#include +#include + + +/** Wait this long after a Command / Data reset is triggered before continuing. + * Allows time for the reset to propogate to the SDIO side of the hardware block. + * Value chosen to ensure that at least 4 SD Clock periods pass at the lowest + * expected SD Clock rate. 4 clock periods @ 10 KHz = 400 us + * See: SDIO: Soft Reset not propagated until SD clock running + */ +#define RESET_WAIT_US (400) + + +/** The maximum SD Clock rate clients are allowed to set. + * The maximum SD Clock rate allowed by the standard is 50 MHz. However, + * The Arasan block is rated to support up to a 52 MHz clock. Allow clients + * to set rates up to the higher max: + * Arasan SDIO Driver should allow up to 52 MHz SD Clock + */ +static const IOSDIOClockRate kMaxAllowableSDClockRate = 52000000; + + +static bool +sdiodrv_waitForInternalClk(const SDHCRegisters_t *sdhc) +{ + for (int i = 0; i < 10 && !sdhc_isInternalClockStable(sdhc); i++) { + task_sleep(5); + } + + return sdhc_isInternalClockStable(sdhc); +} + + +static SDIOReturn_t +sdiodrv_enableClocks(SDHCRegisters_t *sdhc) +{ + sdhc_enableInternalClock(sdhc, true); + + if(!sdiodrv_waitForInternalClk(sdhc)) { + return kSDIOReturnInternalClockUnstable; + } + + sdhc_enableSDClock(sdhc, true); + + return kSDIOReturnSuccess; +} + + +static void +sdiodrv_disableClocks(SDHCRegisters_t *sdhc) +{ + sdhc_enableSDClock(sdhc, false); + //sdhc_enableInternalClock(sdhc, false); +} + +IOSDIOClockRate +sdiodrv_setClockRate(SDHCRegisters_t *sdhc, IOSDIOClockRate *targetSDClkRateHz, UInt32 inputClkRateHz) +{ + check(sdhc); + check(targetSDClkRateHz); + check(*targetSDClkRateHz > 0 && *targetSDClkRateHz <= kMaxAllowableSDClockRate); + check(inputClkRateHz); + + if(*targetSDClkRateHz <= 0 || *targetSDClkRateHz > kMaxAllowableSDClockRate || !inputClkRateHz) { + return kSDIOReturnBadArgument; + } + + bool sdClkEnabled = sdhc_isSDClockEnabled(sdhc); + + sdhc_enableSDClock(sdhc, false); + + IOSDIOClockRate newRate = sdhc_setClockDividerRate(sdhc, *targetSDClkRateHz, inputClkRateHz); + + if(sdClkEnabled && !sdiodrv_waitForInternalClk(sdhc)) { + *targetSDClkRateHz = 0; + return kSDIOReturnInternalClockUnstable; + } + + sdhc_setDataTimeoutCounter(sdhc); + + sdhc_enableSDClock(sdhc, sdClkEnabled); + + *targetSDClkRateHz = newRate; + return kSDIOReturnSuccess; +} + +SDIOReturn_t +sdiodrv_resetSDHC(SDHCRegisters_t *sdhc, SDHCResetFlags_t resetOptions) +{ + check(sdhc); + check(resetOptions & (kSDHCResetDataLine | kSDHCResetCmdLine | kSDHCResetAll)); + + if(!(resetOptions & (kSDHCResetDataLine | kSDHCResetCmdLine | kSDHCResetAll))) { + return kSDIOReturnBadArgument; + } + + dprintf(DEBUG_INFO, "%s: Resetting SDHC @ %p, 0x%X\n", __func__, sdhc, resetOptions); + sdhc_reset(sdhc, resetOptions); + + for (int i = 0; i < 100 && sdhc_isResetting(sdhc); i++) { + task_sleep(5); + } + + if(sdhc_isResetting(sdhc)) { + dprintf(DEBUG_CRITICAL, "%s: Failed to complete reset, 0x%X\n", __func__, sdhc->softwareReset); + return kSDIOReturnInReset; + } + + // SDIO: Soft Reset not propagated until SD clock running + if(resetOptions & kSDHCResetAll) { + // If we're doing a full reset, enable the internal clock to ensure + // that the reset is propogated into the SDIO domain + sdhc_enableInternalClock(sdhc, true); + if(!sdiodrv_waitForInternalClk(sdhc)) { + return kSDIOReturnInternalClockUnstable; + } + + } else { + // If we're not doing a full reset, wait for >= 4 SD Clock periods + task_sleep(RESET_WAIT_US); + } + + return kSDIOReturnSuccess; +} + +SDIOReturn_t +sdiodrv_setClockMode(SDHCRegisters_t *sdhc, enum IOSDIOClockMode clockMode) +{ + check(sdhc); + check(kIOSDIO1BitMode == busWidth || kIOSDIO4BitMode == busWidth); + + SDIOReturn_t retval = kSDIOReturnSuccess; + + switch(clockMode) + { + case kIOSDIOClockOff: + sdiodrv_disableClocks(sdhc); + break; + case kIOSDIOClockOn: + retval = sdiodrv_enableClocks(sdhc); + break; + default: + retval = kSDIOReturnBadArgument; + break; + }; + + return retval; +} + +SDIOReturn_t +sdiodrv_setBusWidth(SDHCRegisters_t *sdhc, enum IOSDIOBusWidth busWidth) +{ + check(sdhc); + check(kIOSDIO1BitMode == busWidth || kIOSDIO4BitMode == busWidth); + + SDIOReturn_t retval = kSDIOReturnSuccess; + + switch(busWidth) + { + case kIOSDIO1BitMode: + case kIOSDIO4BitMode: + sdhc_setDataTransferWidth(sdhc, busWidth); + break; + default: + retval = kSDIOReturnBadArgument; + break; + }; + + return retval; +} + + +SDIOReturn_t +sdiodrv_setBusSpeedMode(SDHCRegisters_t *sdhc, enum IOSDIOBusSpeedMode speedMode) +{ + check(sdhc); + check(kIOSDIONormalSpeed == speedMode || kIOSDIOHighSpeed == speedMode); + + SDIOReturn_t retval = kSDIOReturnSuccess; + + switch(speedMode) + { + case kIOSDIONormalSpeed: + sdhc_setHighSpeedMode(sdhc, false); + break; + case kIOSDIOHighSpeed: + check(sdhc_isHighSpeedSupported(sdhc)); + sdhc_setHighSpeedMode(sdhc, true); + break; + default: + retval = kSDIOReturnBadArgument; + break; + }; + + return retval; +} + + + + diff --git a/drivers/arasan/sdio/sdiodrv_config.h b/drivers/arasan/sdio/sdiodrv_config.h new file mode 100644 index 0000000..f10698e --- /dev/null +++ b/drivers/arasan/sdio/sdiodrv_config.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _SDIODRV_CONFIG_H +#define _SDIODRV_CONFIG_H + + +#include +#include +#include + +/** @brief Resets the SDIO Host Controller + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in] resetOptions + * Flags identifying what to reset + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnBadArgument - unsupported flag set + * kSDIOReturnInReset - SDHC didn't come out of reset in a resonable time period + */ +SDIOReturn_t sdiodrv_resetSDHC(SDHCRegisters_t *sdhc, SDHCResetFlags_t resetOptions); + +/** @brief Sets the SD Clock rate. + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in,out] targetSDClkRateHz + * Desired SD Clock rate, in Hz + * On exit set to the actual clock rate set in Hz, 0 on error. + * @param[in] inputClkRateHz + * SDHC Block's input clock rate, in Hz. Used to derive SD Clock. + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnBadArgument - Illegal target or base rate + * kSDIOReturnInternalClockUnstable - Block's internal clock didn't stabilize in a reasonable time period + */ +SDIOReturn_t sdiodrv_setClockRate(SDHCRegisters_t *sdhc, IOSDIOClockRate *targetSDClkRateHz, UInt32 inputClkRateHz); + +/** @brief Enable / disable the SD Clock. + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in] clockMode + * Whether to turn on or turn off the clock. + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnBadArgument - Unsupported clock mode + * kSDIOReturnInternalClockUnstable - Block's internal clock didn't stabilize in a reasonable time period + */ +SDIOReturn_t sdiodrv_setClockMode(SDHCRegisters_t *sdhc, enum IOSDIOClockMode clockMode); + +/** @brief Set the width of the data bus (# of data lines). + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in] busWidth + * Whether to transfer data in 1 or 4 bit mode. + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnBadArgument - Unsupported bus width + */ +SDIOReturn_t sdiodrv_setBusWidth(SDHCRegisters_t *sdhc, enum IOSDIOBusWidth busWidth); + +/** @brief Set the bus speed used by the Host Controller. + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in] speedMode + * Whether to transfer data in low or high speed mode. + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnBadArgument - Unsupported speed mode + */ +SDIOReturn_t sdiodrv_setBusSpeedMode(SDHCRegisters_t *sdhc, enum IOSDIOBusSpeedMode speedMode); + + +#endif /* _SDIODRV_CONFIG_H */ + diff --git a/drivers/arasan/sdio/sdiodrv_transfer.c b/drivers/arasan/sdio/sdiodrv_transfer.c new file mode 100644 index 0000000..0641928 --- /dev/null +++ b/drivers/arasan/sdio/sdiodrv_transfer.c @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "sdiodrv_transfer.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "sdiodrv_config.h" +#include "sdiodrv_command.h" + + +#define TRANSFER_COMPLETE_CHECKS (1000) + +#define DMA_WORD_SIZE (4) +#define DMA_BURST_SIZE (8) + +#define DMA_WORKAROUND_PRESENT (1) + + +static SDIOReturn_t +sdiodrv_prepareTransfer(SDHCRegisters_t *sdhc, const struct SDIOTransfer *transfer) +{ + check(sdhc_getMaxBlockLength(sdhc) < transfer->blockSize); + + sdhc_setBlockSize(sdhc, transfer->blockSize); + + sdhc->blockCount = transfer->blockCount; + + UInt16 transferMode = kSDIOTransferEnableBlockCount | kSDIOTransferEnableDMA; + + if(sdhc->blockCount > 1) { + transferMode |= kSDIOTransferMultipleBlocks; + } + + if(transfer->direction & kSDIODirectionRead) { + transferMode |= kSDIOTransferReadFromCard; + } + + sdhc->transferMode = transferMode; + +// dprintf(DEBUG_INFO, "\n%s: blockSize = %u, blockCount = %u, cmd53ItemCount = %u, cmd53BlkMode = 0x%X, mode = 0x%X\n", __func__, +// transfer->blockSize, transfer->blockCount, +// (0x1FF & transfer->command.argument), ((1 << 27) & transfer->command.argument), transferMode); + + return kSDIOReturnSuccess; +} + +static SDIOReturn_t +sdiodrv_completeTransfer(SDHCRegisters_t *sdhc, const struct SDIOTransfer *transfer) +{ + SDIOReturn_t retval = sdhc_getTransferStatus(sdhc); + + if(kSDIOReturnSuccess != retval) { + dprintf(DEBUG_CRITICAL, "%s: SDIO Transfer Failed (0x%X): cmd = 0x%X, blkSize = %u, blkCount = %u / %u, normalInt = 0x%X, errorInt = 0x%X, state = 0x%X\n", + __func__, retval, + sdhc->command, + transfer->blockSize, sdhc->blockCount, transfer->blockCount, + sdhc->normalInterruptStatus, sdhc->errorInterruptStatus, sdhc->presentState); + + sdiodrv_resetSDHC(sdhc, kSDHCResetDataLine); + } + + sdhc_clearTransferStatus(sdhc); + + return retval; +} + +static void +sdiodrv_logSegments(const struct dma_segment *segment, UInt32 numSegments, UInt32 totalSize) +{ + dprintf(DEBUG_INFO, "%s: numSegments = %u, totalSize = %u\n", __func__, + numSegments, totalSize); + for (unsigned int i = 0; i < numSegments; i++) { + dprintf(DEBUG_INFO, "%s: segment[%u] @ %p: paddr = 0x%X, len = %u\n", __func__, + i, &segment[i], segment[i].paddr, segment[i].length); + } +} + + +/** @brief Adjusts a segment in the list such that the first N segments sum to the block size. + * + * @param[in] segmentList + * The segment list + * @param[in] numSegments + * how many segments are in the segment list. + * @param[in] blockSize + * the target blocksize + * @param[out] origLength + * Original length of the returned segment + * @return + * a pointer to the adjusted segment, NULL if no adjustment occured + */ +static struct dma_segment* +sdiodrv_adjustSegment(struct dma_segment *segmentList, UInt32 numSegments, UInt32 blockSize, UInt32 *origLength) +{ + UInt32 byteCount=0; + + for(UInt32 i = 0; i < numSegments; i++) { + // If the # bytes in the segments sums evenly to blockSize, no adjustment needed + if(byteCount == blockSize) { +// dprintf(DEBUG_INFO, "%s: no adjustment needed: byteCount = %u, blockSize = %u\n", __func__, byteCount, blockSize); + return NULL; + } + + byteCount += segmentList[i].length; + + // Need to adjust this segment + if(byteCount > blockSize) { + *origLength = segmentList[i].length; + UInt32 overage = byteCount - blockSize; + segmentList[i].length -= overage; +// dprintf(DEBUG_INFO, "%s: adjusting: byteCount = %u, blockSize = %u, overage = %u\n", __func__, byteCount, blockSize, overage); + return &segmentList[i]; + } + } + + return NULL; +} + +/** @brief Readjusts a segment back to its original length. */ +static void +sdiodrv_readjustSegment(struct dma_segment *segment, UInt32 origLength) +{ + if(!segment) { + return; + } + +// dprintf(DEBUG_INFO, "%s: readjusting: origLength = %u\n", __func__, origLength); + segment->length = origLength; +} + +/** @brief Advance the segment list to the item byteOffset bytes in. + * + * Note: This function makes no effort to enforce aligmnment of the output segments. + * However, if the input segments are aligned and the byte offset is a multiple of + * the aligment, the output segments will be aligned. + * + * @param[in] segmentList + * The segment list + * @param[in,out] segmentsRemaining + * On input: how many segments are in the segment list. + * On output: how many segments are in the returned list + * @param[in] byteOffset + * How many bytes into the segment list the new head should be + * @return + * the new head of the segment list, NULL if there isn't a segment at the requested byte offset + */ +static struct dma_segment* +sdiodrv_advanceSegList(struct dma_segment *segmentList, UInt32 *segmentsRemaining, UInt32 byteOffset) +{ + const UInt32 numSegments = *segmentsRemaining; + UInt32 byteCount=0; + + for(UInt32 i = 0; i < numSegments; i++) { + // If the current item is the right offset in + if(byteCount == byteOffset) { +// dprintf(DEBUG_INFO, "%s: correct offset: byteCount = %u, byteOffset = %u\n", __func__, byteCount, byteOffset); + return &segmentList[i]; + } + + byteCount += segmentList[i].length; + + // If the offset puts us somewhere inside the current segment + if(byteCount > byteOffset) { + // Adjust the segment to the right offset and return as the new head + UInt32 overage = byteCount - byteOffset; + UInt32 segOffset = segmentList[i].length - overage; +// dprintf(DEBUG_INFO, "%s: updating: byteCount = %u, byteOffset = %u, overage = %u, segOffset = %u\n", __func__, byteCount, byteOffset, overage, segOffset); + + segmentList[i].paddr += segOffset; + segmentList[i].length -= segOffset; + + return &segmentList[i]; + } + (*segmentsRemaining)--; + } + + return NULL; +} + +static inline void +sdiodrv_performCacheOperation(int operation, void *address, u_int32_t length) +{ + // Adjust the address / length so that it is aligned on a cacheline + void *adjustedAddr = (void*)((u_int32_t)address & ~(CPU_CACHELINE_SIZE-1)); + u_int32_t adjustedLength = length + (address - adjustedAddr); + + adjustedLength = (adjustedLength + (CPU_CACHELINE_SIZE-1)) & ~(CPU_CACHELINE_SIZE-1); + +// dprintf(DEBUG_INFO, "%s: op = 0x%X, addr = %p, length = %u\n", __func__, operation, adjustedAddr, adjustedLength); + + platform_cache_operation(operation, adjustedAddr, adjustedLength); +} + + +static void +sdiodrv_handleDMAComplete(void *arg) +{ + struct task_event *dmaCompleteEvent = (struct task_event *)arg; + +// dprintf(DEBUG_INFO, "%s: DMA Complete %p\n", __func__, dmaCompleteEvent); + + event_signal(dmaCompleteEvent); +} + +static SDIOReturn_t +sdiodrv_performDMA(SDHCRegisters_t *sdhc, + const struct SDIOTransfer *transfer, + const struct SDIOMemorySegments *memory, + struct task_event *dmaCompleteEvent) +{ + bool dmaRead = transfer->direction & kSDIODirectionRead; + u_int32_t dmaCommand = (dmaRead ? DMA_CMD_DIR_RX : DMA_CMD_DIR_TX); + int dmaErr; + + +#if DMA_WORKAROUND_PRESENT + +// dprintf(DEBUG_INFO, "%s: starting dma for block %u\n", __func__, 0); + dmaErr = dma_execute_async(dmaCommand, DMA_SDIO, + (struct dma_segment*)memory->segmentList, (void*)&sdhc->bufferDataPort, memory->dataLength, + DMA_WORD_SIZE, DMA_BURST_SIZE, + &sdiodrv_handleDMAComplete, dmaCompleteEvent); + if(dmaErr) { + dprintf(DEBUG_CRITICAL, "%s: DMA %s failure (%d), %u / %u blocks of size %u remain (%u seg @ %p)\n", + __func__, (dmaRead ? "read" : "write"), dmaErr, + sdhc->blockCount, transfer->blockCount, transfer->blockSize, + memory->segmentCount, memory->segmentList); + sdiodrv_logSegments((struct dma_segment *)memory->segmentList, memory->segmentCount, memory->dataLength); + return kSDIOReturnADMAError; + } + +// dprintf(DEBUG_INFO, "%s: waiting on block %u\n", __func__, 0); + bool signaled = event_wait_timeout(dmaCompleteEvent, DMA_SDIO_TIMEOUT_US); + if(!signaled) { + dprintf(DEBUG_INFO, "%s: Timeout on DMA %s, %u / %u blocks of size %u remain (%u seg @ %p)\n", + __func__, (dmaRead ? "read" : "write"), + sdhc->blockCount, transfer->blockCount, transfer->blockSize, + memory->segmentCount, memory->segmentList); + sdiodrv_logSegments((struct dma_segment *)memory->segmentList, memory->segmentCount, memory->dataLength); + + // iBoot IOP SDIO Driver doesn't complete transfer after DMA Timeout + SDIOReturn_t transferStatus = sdiodrv_completeTransfer(sdhc, transfer); + if(kSDIOReturnSuccess == transferStatus) { + transferStatus = kSDIOReturnDMATimeout; + } + + // Save & restore the interrupt config across SDHC reset + // Fix "No SDIO Cmd Complete" errors after "SDIO Data CRC Error" + // 9B139: devices lost ability to use WiFi + UInt16 normalInterruptStatusEnable = sdhc->normalInterruptStatusEnable; + UInt16 normalInterruptSignalEnable = sdhc->normalInterruptSignalEnable; + UInt16 errorInterruptStatusEnable = sdhc->errorInterruptStatusEnable; + UInt16 errorInterruptSignalEnable = sdhc->errorInterruptSignalEnable; + + + // H2A/H3 CDMA - DMA Hang after SDIO CMD53 Rx Data CRC Error + // Hard-reset SDIO block before resetting CDMA + clock_reset_device(CLK_SDIO); + + dma_cancel(DMA_SDIO); + + sdhc->normalInterruptStatusEnable = normalInterruptStatusEnable; + sdhc->normalInterruptSignalEnable = normalInterruptSignalEnable; + sdhc->errorInterruptStatusEnable = errorInterruptStatusEnable; + sdhc->errorInterruptSignalEnable = errorInterruptSignalEnable; + + return transferStatus; + } + +// dprintf(DEBUG_INFO, "%s: END, signaled = %u, err = 0x%X\n", __func__, signaled, sdhc->errorInterruptStatus); + + +#else + + struct dma_segment *blkSegmentList = (struct dma_segment*)memory->segmentList; + UInt32 segmentsRemaining = memory->segmentCount; + struct dma_segment *adjustedSegment = NULL; + UInt32 origLength = 0; + + // We have to setup a new DMA for each SDIO block. Yuck. + for(UInt32 b = 0; b < transfer->blockCount && blkSegmentList; b++) { + + sdiodrv_performCacheOperation(CACHE_CLEAN, blkSegmentList, sizeof(blkSegmentList[0])); + + adjustedSegment = sdiodrv_adjustSegment(blkSegmentList, segmentsRemaining, transfer->blockSize, &origLength); + if(adjustedSegment) { + sdiodrv_performCacheOperation(CACHE_CLEAN, adjustedSegment, sizeof(*adjustedSegment)); + } + +// sdiodrv_logSegments((struct dma_segment *)blkSegmentList, segmentsRemaining, transfer->blockSize); +// dprintf(DEBUG_INFO, "%s: block[%u] @ %p: paddr = 0x%X, len = %u\n", __func__, +// b, &blkSegmentList[0], blkSegmentList[0].paddr, blkSegmentList[0].length); + + dmaErr = dma_execute_async(dmaCommand, DMA_SDIO, + blkSegmentList, (void*)&sdhc->bufferDataPort, transfer->blockSize, + DMA_WORD_SIZE, DMA_BURST_SIZE, + &sdiodrv_handleDMAComplete, dmaCompleteEvent); + + if(dmaErr) { + dprintf(DEBUG_CRITICAL, "%s: DMA %s failure (%d) on block %u of size %u (%u segRem @ %p)\n", __func__, + (dmaRead ? "read" : "write"), dmaErr, b, transfer->blockSize, + segmentsRemaining, blkSegmentList); + sdiodrv_logSegments((struct dma_segment *)blkSegmentList, segmentsRemaining, memory->dataLength); + return kSDIOReturnADMAError; + } + + +// dprintf(DEBUG_INFO, "%s: waiting on block %u\n", __func__, b); + bool signaled = event_wait_timeout(dmaCompleteEvent, DMA_SDIO_TIMEOUT_US); + if(!signaled) { + dprintf(DEBUG_INFO, "%s: Timeout on DMA %s, block %u of size %u (%u segRem @ %p)\n", __func__, + (dmaRead ? "read" : "write"), b, transfer->blockSize, + segmentsRemaining, blkSegmentList); + sdiodrv_logSegments((struct dma_segment *)blkSegmentList, segmentsRemaining, memory->dataLength); + + // iBoot IOP SDIO Driver doesn't complete transfer after DMA Timeout + SDIOReturn_t transferStatus = sdiodrv_completeTransfer(sdhc, transfer); + if(kSDIOReturnSuccess == transferStatus) { + transferStatus = kSDIOReturnDMATimeout; + } + + // Save & restore the interrupt config across SDHC reset + // Fix "No SDIO Cmd Complete" errors after "SDIO Data CRC Error" + // 9B139: devices lost ability to use WiFi + UInt16 normalInterruptStatusEnable = sdhc->normalInterruptStatusEnable; + UInt16 normalInterruptSignalEnable = sdhc->normalInterruptSignalEnable; + UInt16 errorInterruptStatusEnable = sdhc->errorInterruptStatusEnable; + UInt16 errorInterruptSignalEnable = sdhc->errorInterruptSignalEnable; + + + // H2A/H3 CDMA - DMA Hang after SDIO CMD53 Rx Data CRC Error + // Hard-reset SDIO block before resetting CDMA + clock_reset_device(CLK_SDIO); + + dma_cancel(DMA_SDIO); + + sdhc->normalInterruptStatusEnable = normalInterruptStatusEnable; + sdhc->normalInterruptSignalEnable = normalInterruptSignalEnable; + sdhc->errorInterruptStatusEnable = errorInterruptStatusEnable; + sdhc->errorInterruptSignalEnable = errorInterruptSignalEnable; + + return transferStatus; + } + + sdiodrv_readjustSegment(adjustedSegment, origLength); + + blkSegmentList = sdiodrv_advanceSegList(blkSegmentList, &segmentsRemaining, transfer->blockSize); + } + +#endif + + return kSDIOReturnSuccess; +} + + +SDIOReturn_t +sdiodrv_transferData(SDHCRegisters_t *sdhc, + const struct SDIOTransfer *transfer, + const struct SDIOMemorySegments *memory, + struct SDIOCommandResponse *response, + struct task_event *dmaCompleteEvent) +{ + check(sdhc); + check(transfer); + check(memory); + check(response); + check(dmaCompleteEvent); + check(transfer->direction); + check((transfer->direction & (kSDIODirectionRead | kSDIODirectionWrite)) != (kSDIODirectionRead | kSDIODirectionWrite)); + check(transfer->blockCount); + check(transfer->blockSize); + check(memory->dataLength); + check(memory->segmentCount); + check(memory->segmentList); + + + // Prepare the SDHC for the transfer + SDIOReturn_t retval = sdiodrv_prepareTransfer(sdhc, transfer); + if(kSDIOReturnSuccess != retval) { + return retval; + } + + // Send the SDIO Command + retval = sdiodrv_sendSDIOCommand(sdhc, &transfer->command, response); + if(kSDIOReturnSuccess != retval) { + return retval; + } + + // TODO: PIO Mode support? + + // Kick off the DMA + retval = sdiodrv_performDMA(sdhc, transfer, memory, dmaCompleteEvent); + if(kSDIOReturnSuccess != retval) { + return retval; + } + + // Wait until the Host Controller says the transfer is complete + // Should be done by the time the DMA / PIO is done + for(unsigned int i=0; !sdhc_isTransferComplete(sdhc); i++) { + if(i >= TRANSFER_COMPLETE_CHECKS) { + dprintf(DEBUG_CRITICAL, "%s: No (%s) transfer complete after %u checks: cmd = 0x%X, blkSize = %u, blkCount = %u / %u, normalInt = 0x%X, errorInt = 0x%X, state = 0x%X\n", + __func__, ((transfer->direction & kSDIODirectionRead) ? "read" : "write"), TRANSFER_COMPLETE_CHECKS, + sdhc->command, + transfer->blockSize, sdhc->blockCount, transfer->blockCount, + sdhc->normalInterruptStatus, sdhc->errorInterruptStatus, sdhc->presentState); + + sdiodrv_resetSDHC(sdhc, kSDHCResetDataLine); + + if(kSDIOReturnSuccess == retval) { + retval = kSDIOReturnNoTransferComplete; + } + + break; + } + + task_yield(); + } + + // Get the transfer status and cleanup the SDHC + SDIOReturn_t transferStatus = sdiodrv_completeTransfer(sdhc, transfer); + + // Note: on transfer error the SDHC block needs to be reset to workaround: + // H2: Workaround stuck dmacbreq on SW Reset DAT + // We'll let the AP-side of the SDIO driver do this for now, since it has + // the state needed to restore the block to an operational state. + // TODO: Move hardware workarounds into IOP SDIO driver + + return kSDIOReturnSuccess == transferStatus ? retval : transferStatus; +} + + + + diff --git a/drivers/arasan/sdio/sdiodrv_transfer.h b/drivers/arasan/sdio/sdiodrv_transfer.h new file mode 100644 index 0000000..32c558e --- /dev/null +++ b/drivers/arasan/sdio/sdiodrv_transfer.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _SDIODRV_TRANSFER_H +#define _SDIODRV_TRANSFER_H + + +#include +#include + +struct SDIOTransfer; +struct SDIOMemorySegments; +struct SDIOCommandResponse; +struct task_event; + + +/** @brief Transfers Data across the SDIO bus. + * @param[in] sdhc + * Target SDIO Host Controller. + * @param[in] transfer + * Information describing the transfer to perform + * @param[in] memory + * Information describing the memory that will source/sink the transfer. + * (Includes the segment list) + * @param[out] response + * The response to the SDIO command associated with the data transfer + * @param[in] dmaCompleteEvent + * The DMA event used to synchronize the DMA transfer + * @return + * kSDIOReturnSuccess - on success + * kSDIOReturnADMAError - Error executing the DMA + * kSDIOReturnDMATimeout - DMA failed to complete + * kSDIOReturnNoTransferComplete - Transfer complete status never set in SDHC + * kSDIOReturnDataTimeout - SDHC timed out waiting for data + * kSDIOReturnDataCRCError - SDHC detected a CRC error in data + * kSDIOReturnDataEndBitError - SDHC detected an end-bit error in data + */ +SDIOReturn_t sdiodrv_transferData(SDHCRegisters_t *sdhc, + const struct SDIOTransfer *transfer, + const struct SDIOMemorySegments *memory, + struct SDIOCommandResponse *response, + struct task_event *dmaCompleteEvent); + + +#endif /* _SDIODRV_TRANSFER_H */ + diff --git a/drivers/backlight/lm3534/library.mk b/drivers/backlight/lm3534/library.mk new file mode 100644 index 0000000..22c2e26 --- /dev/null +++ b/drivers/backlight/lm3534/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBLM3534_DIR := $(GET_LOCAL_DIR) +LIBLM3534_BUILD := $(call TOLIBDIR,$(LIBLM3534_DIR)/LIBLM3534.a) +COMMONLIBS += LIBLM3534 + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBLM3534_OBJS := $(LIBLM3534_DIR)/lm3534.o + +LIBLM3534_OBJS := $(call TOLIBOBJDIR,$(LIBLM3534_OBJS)) + +ALL_DEPS += $(LIBLM3534_OBJS:%o=%d) + +$(LIBLM3534_BUILD): $(LIBLM3534_OBJS) + +endif diff --git a/drivers/backlight/lm3534/lm3534.c b/drivers/backlight/lm3534/lm3534.c new file mode 100644 index 0000000..16f81a5 --- /dev/null +++ b/drivers/backlight/lm3534/lm3534.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#define LM3534_GPR (0x10) +#define LM3534_DFS (0x11) +#define LM3534_RRR (0x12) +#define LM3534_BRL (0x13) +#define LM3534_BRH (0x14) +#define LM3534_AFT (0x32) + +static bool lm3534_probed; +static uint32_t lm3534_address[2]; +static uint32_t lm3534_bus[2]; +static bool lm3534_present[2]; + +int lm3534_backlight_probe(void) +{ + uint8_t data[1]; + + if (lm3534_probed) + return lm3534_present[0] ? 0 : -1; + lm3534_probed = true; + + lm3534_bus[0] = mib_get_u32(kMIBTargetBacklight0I2CBus); + lm3534_bus[1] = mib_get_u32_opt(kMIBTargetBacklight1I2CBus, (uint32_t)-1); + lm3534_address[0] = mib_get_u32(kMIBTargetBacklight0I2CAddress); + lm3534_address[1] = mib_get_u32_opt(kMIBTargetBacklight1I2CAddress, (uint32_t)-1); + + for (unsigned i = 0; i < 2; i++) { + if (lm3534_bus[i] == (uint32_t)-1) { + break; + } + + dprintf(DEBUG_SPEW, "lm3534: probing backlight controller %u at i2c%u address 0x%x\n", i, lm3534_bus[i], lm3534_address[i]); + + // Probe for the LM3534 by reading a register + data[0] = LM3534_GPR; + if (iic_read(lm3534_bus[i], lm3534_address[i], data, 1, data, 1, IIC_NORMAL) == 0) { + // Mark the LM3534 as present + lm3534_present[i] = true; + } + + if (!lm3534_present[i]) { + if (i == 0) { + // Return an error if the first LM3534 is not present + dprintf(DEBUG_INFO, "lm3534: failed to detect backlight controller, bailing\n"); + return -1; + } else { + // Depending on the display card attached, the second backlight + // controller may or may not exist. Its absense is not fatal. + dprintf(DEBUG_INFO, "lm3534: failed to detect second backlight controller, ignoring\n"); + } + } else { + dprintf(DEBUG_SPEW, "lm3534: successfully probed backlight controller %u with value 0x%x\n", i, data[0]); + } + } + + return 0; +} + +int lm3534_backlight_enable(uint32_t backlight_level) +{ + uint8_t data[2]; + + if (!lm3534_probed) { + lm3534_backlight_probe(); + } + + if (!lm3534_present[0]) + return -1; + + for (unsigned i = 0; i < 2; i++) { + if (!lm3534_present[i]) + break; + + // Configure the backlight for defaults expect no ramp + dprintf(DEBUG_SPEW, "lm3534: setting backlight controller %u to level %u\n", i, backlight_level); + data[0] = LM3534_GPR; + data[1] = target_lm3534_gpr(i); + + // + // Dark boot may hand off to the OS with backlight disabled, but the OS backlight driver depends on iBoot + // to configure the backlight even if it's left disabled. + if (backlight_level == 0) + data[1] &= ~0x1; // bit 0: chip enable + + iic_write(lm3534_bus[i], lm3534_address[i], data, 2); + + uint32_t thresholdValue = 0; + if(mib_exists(kMIBTargetBacklightAutoFreqThresh, &thresholdValue)) { + dprintf(DEBUG_SPEW, "lm3534: Modify Auto-Frequency Threshold (0x%x)\n", thresholdValue); + data[0] = LM3534_AFT; + data[1] = thresholdValue; + iic_write(lm3534_bus[i], lm3534_address[i], data, 2); + } + } + + // Not seeing the battery trap icon + // Delay to ensure that the LM3534 settings are processed before issuing dwi transaction + spin(600); + + extern int dwi_send_backlight_command(uint32_t backlight_command, uint32_t backlight_level); + + dwi_send_backlight_command(0xA, backlight_level); + + return 0; +} diff --git a/drivers/backlight/lm3534/rules.mk b/drivers/backlight/lm3534/rules.mk new file mode 100644 index 0000000..3203bc5 --- /dev/null +++ b/drivers/backlight/lm3534/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2011-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_LM3534=1 + +LIBRARY_MODULES += drivers/backlight/lm3534 diff --git a/drivers/backlight/lp8559/lp8559.c b/drivers/backlight/lp8559/lp8559.c new file mode 100644 index 0000000..5e0ebac --- /dev/null +++ b/drivers/backlight/lp8559/lp8559.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include "lp8559.h" + +static bool lp8559_probed; +static bool lp8559_present; + +int beacon_reg_read(uint8_t reg_offset, uint8_t *value) +{ + int status; + status = iic_read(BACKLIGHT_IIC_BUS, lp8559_IIC_ADDRESS, ®_offset, 1, value, 1, IIC_NORMAL); + return status; +} + +int beacon_reg_write(uint8_t reg_offset, uint8_t value) +{ + int status; + uint8_t data[2] = {reg_offset, value}; + status = iic_write(BACKLIGHT_IIC_BUS, lp8559_IIC_ADDRESS, data, 2); + return status; +} + +int lp8559_backlight_enable(uint32_t backlight_level) +{ + uint8_t cmd, epromid; + + if (!lp8559_probed) { + // Probe for the lp8559 by reading a register + if (beacon_reg_read(lp8559_COMMAND, &cmd) == 0) { + // Mark the lp8559 as present + lp8559_present = true; + } + + // Mark the lp8559 as probed + lp8559_probed = true; + } + + // Return an error if the lp8559 is not present + if (!lp8559_present) { + dprintf(DEBUG_INFO, "failed to detect lp8559, bailing\n"); + return -1; + } + + // Workaround for chips with EPROMID = 0x0 + // J85: Need to update register values in Beacon + beacon_reg_read(lp8559_EPROMID, &epromid); + if (epromid == 0x10) { + // Unlock protected registers + beacon_reg_write(lp8559_LOCK, 0xCF); + + // Set inductor current limit to 2.2A + beacon_reg_write(lp8559_CONFIG, 0x62); + + // Set IMAX to 20mA: + beacon_reg_write(lp8559_CURRENT, 0x02); + + // Set PWM cutover point to 1mA + beacon_reg_write(lp8559_HYBRIDLO, 0x33); + + // Set SLOPE and VERT headroom control + beacon_reg_write(lp8559_VHR1, 0x26); + + // Set PWM global offset + beacon_reg_write(lp8559_TRIM9, 0x08); + + // Lock protected registers + beacon_reg_write(lp8559_LOCK, 0x00); + } + + beacon_reg_read(lp8559_COMMAND, &cmd); + + + // + // Dark boot may hand off to the OS with backlight disabled, but the OS backlight driver depends on iBoot + // to configure the backlight even if it's left disabled. + + // read modify write + // Bit 0 - on, Bit 3 - enable DWI + cmd |= 0x9; + if (backlight_level == 0) { + cmd &= ~(0x9); + } + + // Configure the backlight for defaults expect no ramp + beacon_reg_write(lp8559_COMMAND, cmd); + + // IS this Required ?? + // Not seeing the battery trap icon + // Delay to ensure that the lp8559 settings are processed before issuing dwi transaction + task_sleep(600); + + extern int dwi_send_backlight_command(uint32_t backlight_command, uint32_t backlight_level); + + dwi_send_backlight_command(0xA, backlight_level); + + return 0; +} diff --git a/drivers/backlight/lp8559/lp8559.h b/drivers/backlight/lp8559/lp8559.h new file mode 100644 index 0000000..cfb6e48 --- /dev/null +++ b/drivers/backlight/lp8559/lp8559.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_LP8559_H +#define __DRIVERS_LP8559_H + +#define lp8559_IIC_ADDRESS (0x4C) + +#define lp8559_COMMAND (0x00) +#define lp8559_LOCK (0x0F) +#define lp8559_CONFIG (0x10) +#define lp8559_CURRENT (0x11) +#define lp8559_BCFG1 (0x15) +#define lp8559_BCFG2 (0x16) +#define lp8559_BCFG3 (0x17) +#define lp8559_BCFG5 (0x19) +#define lp8559_HYBRIDLO (0x1A) +#define lp8559_VHR1 (0x1E) +#define lp8559_BCTRL (0x20) +#define lp8559_TRIM2 (0x51) +#define lp8559_TRIM5 (0x54) +#define lp8559_TRIM9 (0x58) +#define lp8559_LEDCFG (0xE6) +#define lp8559_TMLOCK (0xEE) +#define lp8559_EPROMID (0xFC) + +int beacon_reg_read(uint8_t reg_offset, uint8_t *value); +int beacon_reg_write(uint8_t reg_offset, uint8_t value); + +#endif /* __DRIVERS_LP8559_H */ diff --git a/drivers/backlight/lp8559/rules.mk b/drivers/backlight/lp8559/rules.mk new file mode 100644 index 0000000..ff27979 --- /dev/null +++ b/drivers/backlight/lp8559/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_LP8559=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/lp8559.o diff --git a/drivers/dialog/charger/rules.mk b/drivers/dialog/charger/rules.mk new file mode 100644 index 0000000..6068f33 --- /dev/null +++ b/drivers/dialog/charger/rules.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2014 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# only used for "external" chargers (like DIALOG_D2231) + +OPTIONS += \ + WITH_HW_CHARGER_DIALOG=1 \ + WITH_HW_CHARGER=1 + +# the actual code is included by "pmu" driver, but we use this config to switch how that one compiles + +MODULES += \ + drivers/dialog/pmu + diff --git a/drivers/dialog/pmu/NTCTables.h b/drivers/dialog/pmu/NTCTables.h new file mode 100644 index 0000000..e5caa7d --- /dev/null +++ b/drivers/dialog/pmu/NTCTables.h @@ -0,0 +1,92 @@ +/* + * NTCTables.h + * AppleDialogPMU + * + * Created by Heiko Panther on 4/13/09. + * Copyright 2009 Apple Computer, Inc.. All rights reserved. + * + */ + +struct NTCLUT { + uint32_t ohm; + int32_t centiCelsius; +}; + +// ERTJZEG103JA is the thermistor on the N18 MLB. +static const struct NTCLUT ERTJZEG103JA[] = { +{ 205200, -4000 }, +{ 154800, -3500 }, +{ 117900, -3000 }, +{ 90690, -2500 }, +{ 70370, -2000 }, +{ 55070, -1500 }, +{ 43440, -1000 }, +{ 34530, -500 }, +{ 27640, 0 }, +{ 22270, 500 }, +{ 18060, 1000 }, +{ 14740, 1500 }, +{ 12110, 2000 }, +{ 10000, 2500 }, +{ 8309, 3000 }, +{ 6941, 3500 }, +{ 5828, 4000 }, +{ 4916, 4500 }, +{ 4165, 5000 }, +{ 3543, 5500 }, +{ 3027, 6000 }, +{ 2595, 6500 }, +{ 2233, 7000 }, +{ 1929, 7500 }, +{ 1672, 8000 }, +{ 1451, 8500 }, +{ 1261, 9000 }, +{ 1097, 9500 }, +{ 956, 10000 }, +{ 836, 10500 }, +{ 732, 11000 }, +{ 642, 11500 }, +{ 565, 12000 }, +{ 494, 12500 }, +{ 0, 0} }; + +// TDK NTCG103JF103F is the thermistor in the N18 battery pack. +// This table is also used for the Murata NCP03XH103F05RL since its B +// is comparable at B=3380 and B=3435 at 50/85°C +// The Murata part is used on board and battery of N90. +static const struct NTCLUT NTCG103JF103F[] = { +{ 188500, -4000 }, +{ 144290, -3500 }, +{ 111330, -3000 }, +{ 86560, -2500 }, +{ 67790, -2000 }, +{ 53460, -1500 }, +{ 42450, -1000 }, +{ 33930, -500 }, +{ 27280, 0 }, +{ 22070, 500 }, +{ 17960, 1000 }, +{ 14700, 1500 }, +{ 12090, 2000 }, +{ 10000, 2500 }, +{ 8310, 3000 }, +{ 6940, 3500 }, +{ 5830, 4000 }, +{ 4910, 4500 }, +{ 4160, 5000 }, +{ 3540, 5500 }, +{ 3020, 6000 }, +{ 2590, 6500 }, +{ 2230, 7000 }, +{ 1920, 7500 }, +{ 1670, 8000 }, +{ 1450, 8500 }, +{ 1270, 9000 }, +{ 1110, 9500 }, +{ 980, 10000 }, +{ 860, 10500 }, +{ 760, 11000 }, +{ 670, 11500 }, +{ 600, 12000 }, +{ 530, 12500 }, +{ 0, 0 } }; diff --git a/drivers/dialog/pmu/charger.c b/drivers/dialog/pmu/charger.c new file mode 100644 index 0000000..9427ff9 --- /dev/null +++ b/drivers/dialog/pmu/charger.c @@ -0,0 +1,1229 @@ +/* + * Copyright (C) 2008-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if DIALOG_D2255 && !WITH_HW_CHARGER + +bool charger_has_usb(int dock) { return false; } +bool charger_has_external(int dock) { return false; } +bool charger_has_firewire(int dock) { return false; } +bool charger_has_batterypack(int dock) { return false; } +bool charger_charge_done(int dock) { return true; } + +uint32_t charger_get_max_charge_current(int dock) { return 1500; } // bogus, only to prevent infinite loops +int charger_read_battery_level(uint32_t *milliVolts) { return 5000; }; // bogus, only to prevent infinite loops + +void charger_clear_usb_state(void) { } +void charger_clear_alternate_usb_current_limit(void) { } +void charger_set_charging(int dock, uint32_t input_current_limit, uint32_t *charge_current_ma) { } + +#elif !WITH_HW_CHARGER || WITH_HW_CHARGER_DIALOG || DIALOG_D2238 + +#if WITH_HW_CHARGER_DIALOG + +#if DIALOG_D2231 +#include "d2231.h" +#elif DIALOG_D2355 +#include "d2355.h" +#else +#error Unknown Dialog charger selection +#endif + +#else // !WITH_HW_CHARGER_DIALOG + +#if DIALOG_D1755 +#include "d1755.h" +#elif DIALOG_D1815 +#include "d1815.h" +#elif DIALOG_D1881 +#include "d1881.h" +#elif DIALOG_D1946 +#include "d1946.h" +#elif DIALOG_D1972 +#include "d1972.h" +#elif DIALOG_D1974 +#include "d1974.h" +#elif DIALOG_D2018 +#include "d2018.h" +#elif DIALOG_D2045 +#include "d2045.h" +#elif DIALOG_D2089 +#include "d2089.h" +#elif DIALOG_D2186 +#include "d2186.h" +#elif DIALOG_D2207 +#include "d2207.h" +#elif DIALOG_D2238 +#include "d2238.h" +#define charger_print_status pmu_charger_print_status +#define charger_set_charging pmu_charger_set_charging +#define charger_has_external pmu_charger_has_external +#elif DIALOG_D2257 +#include "d2257.h" +#else +#error Unknown Dialog PMU selection +#endif + +#endif // !WITH_HW_CHARGER_DIALOG + +#include "NTCTables.h" +#include + +#if !WITH_HW_CHARGER +#define CHARGER_IIC_BUS PMU_IIC_BUS +#endif + +#ifdef DIALOG_PMU_USE_CHARGE_TABLE +#error powerconfig.h is out of date +#endif + +#if PMU_HAS_ISET_BAT_2BYTES +typedef uint16_t iset_bat_t; +#else +typedef uint8_t iset_bat_t; +#endif + +static iset_bat_t ichg_bat_max; +static uint8_t iset_buck_limit; +#if DIALOG_D1755 +static uint8_t iset_buck_calibration_500; +static uint8_t iset_buck_calibration_1000; +#endif +#if TARGET_USE_CHARGE_TABLE +#if DIALOG_D1815 || DIALOG_D1881 || DIALOG_D1946 +static uint8_t ichg_tbat_max[kDIALOG_ICHG_TBAT_NUM] = TARGET_ICHG_TBAT_MAX; +#endif +#endif + +// This goes after the powerconfig +#ifndef TARGET_MAX_USB_INPUT_CURRENT +#define TARGET_MAX_USB_INPUT_CURRENT (1000) +#endif + +// this is aria With internal charger +#if DIALOG_D2257 && !DIALOG_D2231 && !DIALOG_D2355 +#define DIALOG_CHG_CONTROL kD2257_CHG_CONTROL +#else +#define DIALOG_CHG_CONTROL kDIALOG_SYS_CONTROL +#endif + +static int dialog_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm) +{ + uint8_t confirm; + UInt8 data[kDIALOG_REG_BYTES + 1]; + + if (kDIALOG_REG_BYTES > 1) data[kDIALOG_REG_BYTES - 2] = (reg >> 8) & 0xFF; + data[kDIALOG_REG_BYTES - 1] = (reg & 0xFF); + data[kDIALOG_REG_BYTES] = byte; + + iic_write(dev, kDIALOG_ADDR_W, data, sizeof(data)); + if (do_confirm) { + iic_read(dev, kDIALOG_ADDR_R, data, sizeof(data)-1, &confirm, 1, IIC_NORMAL); + if (byte == confirm) { + dprintf(DEBUG_SPEW, "pmu%d: wrote %x to reg %x\n", dev, byte, reg); + } else { + dprintf(DEBUG_SPEW, "pmu%d: try to write %x to reg %x, but got %x back\n", dev, byte, reg, confirm); + return -1; + } + } + + return 0; +} + +static int dialog_get_data(int dev, uint16_t reg, uint8_t *byte) +{ + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (reg >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (reg & 0xFF); + return iic_read(dev, kDIALOG_ADDR_R, addr, sizeof(addr), byte, 1, IIC_NORMAL); +} + +static void dialog_read_events(eventRegisters data) +{ + bzero(data, sizeof(eventRegisters)); + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (kDIALOG_EVENT_A >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (kDIALOG_EVENT_A & 0xFF); + iic_read(CHARGER_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), data, sizeof(eventRegisters), IIC_NORMAL); +} + +static void dialog_read_status(statusRegisters data) +{ + bzero(data, sizeof(statusRegisters)); + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (kDIALOG_STATUS_A >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (kDIALOG_STATUS_A & 0xFF); + iic_read(CHARGER_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), data, sizeof(statusRegisters), IIC_NORMAL); +} + +#if DIALOG_D2257 && !DIALOG_D2231 && !DIALOG_D2355 +static int +dialog_read_adc(int dev, unsigned input_select, unsigned *level) +{ + int result; + const uint16_t man_ctrl_addr=kDIALOG_ADC_MAN_CTL; + const uint8_t channel_index=input_select & kDIALOG_ADC_CONTROL_MUX_SEL_MASK; + + result=pmu_set_data(dev, man_ctrl_addr, channel_index, 0); + if ( result!=0 ) return -1; + + int done=0; + uint8_t data[2]; // MAN*_RES_LSB, MAN*_RES_MSB + uint8_t addr[2] = { (kDIALOG_ADC_LSB >> 8) & 0xFF, (kDIALOG_ADC_LSB & 0xFF)}; + const utime_t end_time = system_time() + 50*1000 ; + + do { + spin(1000); + + result=iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), &data[0], sizeof(data), IIC_NORMAL); + if ( result!=0 ) break; + + done=( (data[0]&kDIALOG_ADC_LSB_MANADC_ERROR)==0 ); + if ( done ) { + *level = ((unsigned)data[1] << 4) | (data[0] & 0xf); + } else if ( system_time() > end_time ) { + result=-1; + dprintf(DEBUG_CRITICAL, "dialog_read_adc timeout, MUX_SEL=%x\n", input_select); + break; + } + + } while ( !done ); + + // clear EOC + eventRegisters ints_pending; + pmu_read_events(ints_pending); + + return result; +} +#else +static int +dialog_read_adc(int dev, unsigned input_select, unsigned *level) +{ + int result = 0; + uint8_t data[2]; + uint8_t reg; + utime_t start_time; + int timeoutOccurred; +#if ADC_TIMEOUT_STATISTICS + int chg_dis=0; +#endif +#if ADC_TIMEOUT_WORKAROUND + int numTimeouts=0; +#endif + + reg = (input_select & kDIALOG_ADC_CONTROL_MUX_SEL_MASK) | kDIALOG_ADC_CONTROL_DEFAULTS; + +#if !DIALOG_D2231 && !DIALOG_D2238 && !DIALOG_D2255 && !DIALOG_D2355 + if (kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID == input_select) { +#if DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2238 + dialog_set_data(dev, kDIALOG_ADC_CONTROL2, kDIALOG_ADC_CONTROL2_ADC_REF_EN, 0); +#else + dialog_set_data(dev, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_ADC_REF_EN | reg, 0); + reg |= kDIALOG_ADC_CONTROL_ADC_REF_EN; +#endif + spin(80 * 1000); + } +#endif + + dialog_set_data(dev, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_MAN_CONV | reg, 0); + +#if ADC_TIMEOUT_WORKAROUND +continue_conv: +#endif + + start_time = system_time(); + timeoutOccurred = 0; + do { + spin(1000); + + if (system_time() > (start_time + 50*1000)) + { + dprintf(DEBUG_CRITICAL, + "dialog_read_adc timeout, MUX_SEL=%x\n", + input_select); +#if ADC_TIMEOUT_WORKAROUND + timeoutOccurred = 1; + break; +#else + return -1; +#endif + } + + dialog_get_data(dev, kDIALOG_ADC_CONTROL, ®); + } while ((reg & kDIALOG_ADC_CONTROL_MAN_CONV) != 0); + +#if ADC_TIMEOUT_WORKAROUND + enum adc_issues { + kRetriesDidntHelp = 0x01, + kAutoConversionVDD = 0x02, + kAutoConversionTemp = 0x04, + kBatPwrSuspNotAsserted = 0x08, + kChrgDisabled = 0x10 + }; + + if(timeoutOccurred) { + uint8_t issues = 0; +#if ADC_TIMEOUT_STATISTICS + // Write timeout count to scratchpad + if(numTimeouts==0) { + dialog_get_data(dev, kDIALOG_MEMBYTE0+0x09, &data[0]); + if(data[0]<255) data[0]++; + dialog_set_data(dev, kDIALOG_MEMBYTE0+0x09, data[0], 0); + } + // Check that auto conversions are disabled + uint8_t adc_regs[5]; + reg = kDIALOG_ADC_CONTROL; + iic_read(CHARGER_IIC_BUS, kDIALOG_ADDR_R, ®, 1, &adc_regs[0], + sizeof(adc_regs), IIC_NORMAL); + if(adc_regs[0] & kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN) + issues |= kAutoConversionVDD; + if(adc_regs[4] & 0x80) issues |= kAutoConversionTemp; + // Check that we're charging. Not treating this as critical yet, + // but if we're not charging this might be a reason the workaround + // could fail + dialog_get_data(dev, kDIALOG_STATUS_A, &data[0]); + if((data[0]&kD1815_STATUS_A_VBUS_DET)==0) chg_dis |= 1; + // Check that bat_pwr_susp is enabled + dialog_get_data(dev, DIALOG_CHG_CONTROL, &data[0]); + if((data[0]&kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND)==0) + issues |= kBatPwrSuspNotAsserted; +#endif + numTimeouts++; + if(numTimeouts > 10) issues |= kRetriesDidntHelp; + // Trouble? Give up + if(issues) { +#if ADC_TIMEOUT_STATISTICS + // Charging was disabled anytime we tried the workaround + if(chg_dis) issues |= kChrgDisabled; + // Write issues to scratchpad + dialog_set_data(dev, kDIALOG_MEMBYTE0+0x8, issues, 0); + // Write reset count to scratchpad + dialog_get_data(dev, kDIALOG_MEMBYTE0+0x0a, &data[0]); + if(data[0]<255) data[0]++; + dialog_set_data(dev, kDIALOG_MEMBYTE0+0x0a, data[0], 0); +#endif + // PMU register reset + dialog_get_data(dev, 0xE0, &data[0]); + data[0]|=1; // test_enable + dialog_set_data(dev, 0xE0, data[0], 0); + data[0]|=3; // test_enable|SW_RESET + dialog_set_data(dev, 0xE0, data[0], 0); + // NOTREACHED + while(1); + } else { + dialog_get_data(dev, DIALOG_CHG_CONTROL, &data[0]); + // Clear BAT_PWR_SUSP + data[0] &= ~kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND; + dialog_set_data(dev, DIALOG_CHG_CONTROL, data[0], 0); + // Wait + spin(1300); + // Set BAT_PWR_SUSP + data[0] |= kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND; + dialog_set_data(dev, DIALOG_CHG_CONTROL, data[0], 0); + // Try again! + goto continue_conv; + } + } +#endif /* ADC_TIMEOUT_WORKAROUND */ + + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (kDIALOG_ADC_LSB >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (kDIALOG_ADC_LSB & 0xFF); + iic_read(CHARGER_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), &data[0], sizeof(data), IIC_NORMAL); + + dialog_set_data(dev, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS, 0); +#if DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2231 || DIALOG_D2238 + dialog_set_data(dev, kDIALOG_ADC_CONTROL2, kDIALOG_ADC_CONTROL2_DEFAULTS, 0); +#endif + +#if DIALOG_D1755 || DIALOG_D2231 + *level = ((unsigned)data[1] << 2) | (data[0] & 0x3); +#else + *level = ((unsigned)data[1] << 4) | (data[0] & 0xf); +#endif + + return result; +} +#endif + +static int +dialog_read_battery_level(int dev, unsigned *level) +{ + int result; + unsigned adc; + + result = dialog_read_adc(dev, kDIALOG_ADC_CONTROL_MUX_SEL_VBAT, &adc); + +#if DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2231 || DIALOG_D2238 || DIALOG_D2257 || DIALOG_D2355 + *level = ((adc * 2500) >> kDIALOG_ADC_RESOLUTION_BITS) + 2500; +#else + *level = ((adc * 2000) >> kDIALOG_ADC_RESOLUTION_BITS) + 2500; +#endif + + return result; +} + +static int lut_interpolate(const struct NTCLUT * const LUT, const uint32_t R) +{ + int idx=0; + uint32_t upper, lower, R1, R2; + int32_t T1, T2; + do { + upper = LUT[idx].ohm; + lower = LUT[idx+1].ohm; + // Is our lookup value within the range of the two table entries? + // This is also true if the lookup value is outside the table + // range; we just interpolate from the last table entries. + if((R<=lower) && (LUT[idx+2].ohm != 0)) { + idx++; + continue; + } + + // Subtract the lower limit, so lower is the zero offset for interpolation + R1 = upper-lower; + R2 = R - lower; + T1 = LUT[idx].centiCelsius - LUT[idx+1].centiCelsius; + // The interpolation. + // (T1/T2) = (R1/R2) <=> T2 = ( (T1*R2) / R1 ) + T2 = ( (T1*(int32_t)R2) / (int32_t)R1 ); + // Add back the lower limit to our result. + T2 += LUT[idx+1].centiCelsius; + + dprintf(DEBUG_SPEW, "LUTInterpolate: R=%d, R1=%d, R2=%d, T1=%d, T2=%d\n", + R, R1, R2, T1, T2); + break; + } while(1); + + return T2; +} + +static int +dialog_read_battery_temperature(int *level) +{ + int result; + unsigned adc; + + if (level == NULL) return -1; + + result = dialog_read_adc(CHARGER_IIC_BUS, kDIALOG_ADC_CONTROL_MUX_SEL_TBAT, &adc); + + if (result == 0) { + // The NTC is connected to a 50uA current source + // R = U / I; 1/I = 1/50uA = 20000 * 1/A + // U = * / + // adc_fsr comes in mV, take the factor of 1000 out of current constant + const uint32_t Rntc = (adc * (20000/1000) * kDIALOG_ADC_FULL_SCALE_MV) >> kDIALOG_ADC_RESOLUTION_BITS; + dprintf(DEBUG_SPEW, "ADC chan %d: value=%d, Rntc=%d\n", kDIALOG_ADC_CONTROL_MUX_SEL_TBAT, adc, Rntc); + *level=lut_interpolate(NTCG103JF103F, Rntc); + } + + return result; +} + +#if DIALOG_D1815 +bool dialog_workaround_7886796(const statusRegisters status) +{ + // Ashley has a bug where if the voltage drops below VBUS_THR (~4.3V), the charger buck digital control + // resets to 100mA, but the analog side keeps drawing more current. The only way around it + // is to disable the charger. + if (STATUS_FLAG_TEST(status, kDIALOG_STATUS_CHG_ATT_MASK) && !EVENT_FLAG_TEST(status, kDIALOG_STATUS_USB_MASK)) { + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100, true); + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 | kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN, true); + task_sleep(25 * 1000); // wait out 16ms VBUS_PROT_DET debounce plus some margin + return true; + } + + return false; +} +#endif + +bool charger_has_usb(int dock) +{ + statusRegisters status; + + dialog_read_status(status); + +#if DIALOG_D1815 + if (dialog_workaround_7886796(status)) { + dialog_read_status(status); + } +#endif + +#ifdef TARGET_POWER_USB_MASK + return (STATUS_FLAG_TEST(status, TARGET_POWER_USB_MASK)); +#else + return (STATUS_FLAG_TEST(status, kDIALOG_STATUS_USB_MASK)); +#endif +} + +bool charger_has_firewire(int dock) +{ + statusRegisters status; + dialog_read_status(status); + return STATUS_REGISTER_TEST_MASK(status, kDialogStatusFWMask); +} + +bool charger_has_external(int dock) +{ + // external charge not supported + return false; +} + +static void +read_defaults_if_needed(void) +{ + static bool defaults_read = 0; + if (defaults_read) + return; + defaults_read = 1; + +#if PMU_HAS_ISET_BAT_2BYTES + uint8_t otp[2]; + + /* Read and remember max bat charge current */ + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_OTP_ISET_BAT_MSB, &otp[0]); + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_OTP_ISET_BAT_MSB+1, &otp[1]); + ichg_bat_max = (otp[0] << 8) | otp[1]; +#else + uint8_t otp; + + /* Read and remember max bat charge current */ + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_OTP_ISET_BAT, &otp); +#if DIALOG_D2238 + ichg_bat_max = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK & (otp << 1); +#else + ichg_bat_max = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK & + ((otp >> kDIALOG_OTP_ISET_BAT_SHIFT) << kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT); +#endif // DIALOG_D2238 + +#endif + +#if DIALOG_D1755 + // + if (5 == ichg_bat_max) + ichg_bat_max = 0x27; + // + if (1 == ichg_bat_max) + ichg_bat_max = 0x18; + + // read out calibrated USB current limits from OTP. If unset or out of range, use defaults. + // use 450mA rather than 500mA setting by default, because that's what was tested on N88. + dialog_get_data(CHARGER_IIC_BUS, kD1755_OTP_USB_500_LIMIT, &iset_buck_calibration_500); + if ((iset_buck_calibration_500 < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_350) || (iset_buck_calibration_500 > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600)) + iset_buck_calibration_500 = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_450; + dialog_get_data(CHARGER_IIC_BUS, kD1755_OTP_USB_900_LIMIT, &iset_buck_calibration_1000); + if ((iset_buck_calibration_1000 < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600) || (iset_buck_calibration_1000 > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1300)) + iset_buck_calibration_1000 = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900; +#endif +} + +static iset_bat_t +dialog_get_charge_current_setting(unsigned int charge_target_ma) +{ + if (charge_target_ma > kDIALOG_CHARGE_CONTROL_MAX) charge_target_ma = kDIALOG_CHARGE_CONTROL_MAX; + return (charge_target_ma / kDIALOG_CHARGE_CONTROL_STEP); +} + +static uint32_t +dialog_get_charge_current_limit(iset_bat_t setting) +{ + setting = (setting & kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK) >> kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT; + return setting * kDIALOG_CHARGE_CONTROL_STEP; +} + +uint32_t +charger_get_max_charge_current(int dock) +{ + read_defaults_if_needed(); + return dialog_get_charge_current_limit(ichg_bat_max); +} + +int charger_read_battery_temperature(int *centiCelsiusTemperature) +{ + return dialog_read_battery_temperature(centiCelsiusTemperature); +} + +int charger_read_battery_level(uint32_t *milliVolts) +{ + return dialog_read_battery_level(CHARGER_IIC_BUS, milliVolts); +} + +#if !DIALOG_D2238 + +static int +dialog_get_charger_limit(UInt8 setting) +{ +#if DIALOG_D1755 + if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_120) + return 70 + setting*10; + else if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600) + return 350 + (setting-6)*50; + else if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1300) + return 700 + (setting-12)*200; +#elif DIALOG_D1815 + if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200) + return 50 + setting*10; + else if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600) + return 250 + (setting-16)*50; + else if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900) + return 700 + (setting-24)*200; + else if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000) + return 1000 + (setting-26)*200; +#else + if (setting <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN) + return kDIALOG_CHARGE_BUCK_CONTROL_MIN; + else + return kDIALOG_CHARGE_BUCK_CONTROL_MIN + (100*(setting - kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN) + (kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA-1))/kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA; // round up +#endif + + return -1; +} + +static UInt8 +dialog_input_current_limit_step_down(UInt8 iset_buck) +{ +#if DIALOG_D1755 + // steps are big; go down by one + if (iset_buck > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100) { + return (iset_buck - 1); + } else { + return kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + } +#elif DIALOG_D1815 + if (iset_buck <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200) { + return kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + } else if (iset_buck <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600) { + // 50mA steps from 200-600mA + return iset_buck - 2; + } else { + // steps above 600mA are all at least 100mA + return iset_buck - 1; + } +#else + if (iset_buck <= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200) { + return kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + } else { + return iset_buck - kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA; + } +#endif +} + +static void +dialog_log_charger_limit(UInt8 iset_buck) +{ + dprintf(DEBUG_CRITICAL, "limiting USB input current to %d mA\n", dialog_get_charger_limit(iset_buck)); +} + +#endif // !DIALOG_D2238 + +void +charger_set_charging(int dock, uint32_t input_current_limit, uint32_t *charge_current_ma) +{ + dprintf(DEBUG_SPEW, "dialog_set_charging(input_current_limit=%d, charge_current_ma=%d)\n", + input_current_limit, *charge_current_ma); + + iset_bat_t charge_control_bat; + bool pause = (*charge_current_ma == 0); + + read_defaults_if_needed(); + +#if !DIALOG_D2238 + UInt8 syscontrol; + UInt8 charge_buck_control, iset_buck; + + dialog_get_data(CHARGER_IIC_BUS, DIALOG_CHG_CONTROL, &syscontrol); + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, &charge_buck_control); + + syscontrol &= ~kDIALOG_SYS_CONTROL_CHRG_CONTROLS; +#endif + + dprintf(DEBUG_SPEW, "dialog_set_charging(paus=%d, ichg_bat_max=0x%02x)\n", pause, ichg_bat_max); + + if (!pause) { + charge_control_bat = dialog_get_charge_current_setting(*charge_current_ma); + *charge_current_ma -= dialog_get_charge_current_limit(charge_control_bat); + } else { +#if DIALOG_D1815 || DIALOG_D1881 || DIALOG_D1946 + charge_control_bat = kDIALOG_CHARGE_CONTROL_A_CHG_SUSP; +#else + charge_control_bat = 0; +#endif + } + +#if TARGET_USE_CHARGE_TABLE +#if DIALOG_D1815 || DIALOG_D1881 || DIALOG_D1946 + // Ashley takes care of setting the charge limit based on temperature, but the temperature-relative limits + // themselves can change based on voltage (ATV) level. So program the ICHG_BAT registers. + if (!pause) { + for (unsigned int i = 0; i < kDIALOG_ICHG_TBAT_NUM; i++) { + UInt8 tbat_reg = kDIALOG_ICHG_TBAT_0 + 2*i; + UInt8 tbat_data = ichg_tbat_max[i]; + if (charge_control_bat < tbat_data) tbat_data = charge_control_bat; + dialog_set_data(CHARGER_IIC_BUS, tbat_reg, tbat_data, true); + } + } +#endif +#endif + +#if PMU_HAS_ISET_BAT_2BYTES + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_CONTROL_ICHG_BAT_MSB, (charge_control_bat >> 8) & 0xFF, true); + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_CONTROL_ICHG_BAT_MSB+1, charge_control_bat & 0xFF, true); +#else + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_CONTROL_ICHG_BAT, charge_control_bat, true); +#endif + +#if !DIALOG_D2238 + if (input_current_limit < 100) { + syscontrol |= kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND; + } + + dialog_set_data(CHARGER_IIC_BUS, DIALOG_CHG_CONTROL, syscontrol, true); + +#if DIALOG_D1946 + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_SYS_CONTROL2, &syscontrol); + if (input_current_limit < 100) { + syscontrol |= kDIALOG_SYS_CONTROL2_BAT_PWR_SUSPEND; + } else { + syscontrol &= ~kDIALOG_SYS_CONTROL2_BAT_PWR_SUSPEND; + } + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_SYS_CONTROL2, syscontrol, true); +#endif + + if (input_current_limit > TARGET_MAX_USB_INPUT_CURRENT) { + input_current_limit = TARGET_MAX_USB_INPUT_CURRENT; + } + +#if DIALOG_D1881 || DIALOG_D1972 + // use syscfg calibration to limit Angelina (and Agatha) values +#if WITH_SYSCFG + uint32_t iset_buck_cal[3]; + if (syscfgCopyDataForTag('CBAT', (uint8_t *)iset_buck_cal, sizeof(iset_buck_cal)) == sizeof(iset_buck_cal)) { + uint32_t cal100 = iset_buck_cal[0]; // 16.16 fixed-point + uint32_t cal500 = iset_buck_cal[1]; // 16.16 fixed-point + uint32_t cal1000 = iset_buck_cal[2]; // 16.16 fixed-point + + uint32_t calibrated_target = 0; + + if (input_current_limit < 330 && cal100 != 0) { + // round up (keep current below target) + uint32_t calMA = (cal100 + 65535) >> 16; + + if (calMA < 100) { + calibrated_target = input_current_limit + (100 - calMA); + } else if (calMA > 100) { + calibrated_target = input_current_limit - (calMA - 100); + } + } else if (input_current_limit >= 330 && cal500 != 0 && cal1000 != 0) { + SInt32 delta = cal1000 - cal500; // 16.16 fixed-point + SInt32 base = cal500 - delta; // 16.16 fixed-point + SInt32 slope = delta / 500; // 16.16 fixed-point + + SInt32 target = (input_current_limit << 16); // 16.16 fixed-point + // fixed-point divide + calibrated_target = (((SInt64)(target - base) << 16)/ slope) >> 16; + } + + if (calibrated_target != 0) { + // limit to 15% corection + if (calibrated_target > (input_current_limit * 115)/100) { + input_current_limit = (input_current_limit * 115)/100; + } else if (calibrated_target < (input_current_limit * 85)/100) { + input_current_limit = (input_current_limit * 85)/100; + } else { + input_current_limit = calibrated_target; + } + } + } + else +#endif /* WITH_SYSCFG */ + { + // if not available, limit high-charge rate (above 500mA) by 15% to ensure + // charger is below its limit. + if (input_current_limit > 500) { + input_current_limit = (85 * input_current_limit) / 100; + } + } +#endif + +#if DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2018 || DIALOG_2045 || DIALOG_D2089 || DIALOG_D2207 || DIALOG_D2231 || DIALOG_D2355 + if (input_current_limit >= kDIALOG_CHARGE_BUCK_CONTROL_MAX) { + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX; + } else if (input_current_limit >= 100) { + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN + (kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA * (input_current_limit - kDIALOG_CHARGE_BUCK_CONTROL_MIN)) / 100; + } else { + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + } + +#if DIALOG_D1946 + // Alison trim values are too high at high current settings (8922649) + // 1A up to but not including 1.5A should be 25mA lower 1.5A on up should be 50mA lower. + if (iset_buck > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500) { + iset_buck -= (kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA / 2); + } else if (iset_buck > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1450) { + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1450; + } else if (iset_buck > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000) { + iset_buck -= (kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA / 4); + } else if (iset_buck > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_975) { + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_975; + } +#elif DIALOG_D1974 + // J1/J2/J2A : USB 500mA, 1A, 2.1A, 2.4A Adjust input current limit + if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2200) { + // For input current limits of 2.2A on up, should be 62.5mA lower. + iset_buck -= 5; // 5*12.5mA + + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500) { + // For input current limits of 1.5A<=x<2.2A. should be 50mA lower. + iset_buck -= 4; // 4*12.5mA + + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_750) { + // For input current limits of 0.75A<=x<1.5A, should be 37.5mA lower. + iset_buck -= 3; // 3*12.5mA + + } else if ( (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_250) && + (iset_buck < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_750) ) { + // For input current limits of 0.25A<=x<0.75A, should be set 12.5mA lower. + iset_buck -= 1; // 12.5mA + } + + // limit Amelia A0 to 2300mA (9066812) + if (iset_buck > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2300) { + UInt8 chip_id; + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_CHIP_ID, &chip_id); + if ((chip_id & kD1974_CHIP_ID_MRC_MASK) == kD1974_CHIP_ID_MRC_A0) { + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2300; + } + } +#elif DIALOG_D2018 + { + // P101/P102/P103: USB 1A, 2.1A, and 2.4A Input Current Limit Measures Too High + + UInt8 chip_id; + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_CHIP_ID, &chip_id); + + if ((((chip_id & kD2018_CHIP_ID_MRC_MASK) == 0x09) && (chip_id & kD2018_CHIP_ID_TRC_MASK) <=0x30) || + ((chip_id & kD2018_CHIP_ID_MRC_MASK) == 0x08)) { + + if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2200) { + // For input current limits of 2.2A on up, should be 100mA lower. + iset_buck -= kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA; + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500) { + // For input current limits of 1.5A<=x<2.2A. should be 75mA lower. + iset_buck -= (3*kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA)/4; + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000) { + // For input current limits of 1.0A<=x<1.5A, should be set 25mA lower + iset_buck -= kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA/4; + } + } + + // P101/P102/P103:USB 500mA, 2.1A, 2.4A Adjust input current limit for DVT build + // P101/P102/P103: Adjust USB input current limits for DVT build and beyond + if (((chip_id & kD2018_CHIP_ID_MRC_MASK) >= 0x09) && (chip_id & kD2018_CHIP_ID_TRC_MASK) >=0x40) { + if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500) { + // For input current limits of 1.5A on up, should be 37.5mA higher. + iset_buck += 3; // 3*12.5mA + + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_750) { + // For input current limits of 0.75A<=x<1.5A. should be 25mA higher. + iset_buck += 2; // 2*12.5mA + + } else if ( (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_350) && + (iset_buck < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_750) ) { + // For input current limits of 0.35A<=x<0.75A, should be 12.5mA higher. + iset_buck += 1; + + } else if (iset_buck < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_350) { + // For input current limits of x<0.35A, should be set 12.5mA lower. + iset_buck -= 1; + } + } + } +#elif DIALOG_D2089 + if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100) { + // For input current of 2.1A and higher, should be 75mA lower. + iset_buck -= (3*kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA)/4; + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000) { + // For input current nominally @ 1.0A should be set 50mA lower + iset_buck -= kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA/2; + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500) { + // For input current nominally @ 500mA should be set 25mA lower + iset_buck -= kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA/4; + } +#elif DIALOG_D2355 + // J127 : Implement input current limit calibration in iBoot + if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2400) { + iset_buck -= 5; + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1900) { + iset_buck -= 4; + } else if (iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000) { + iset_buck -= 3; + } else if ( iset_buck >= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 ) { + iset_buck -= 1; + } +#endif + +#else + if (input_current_limit >= 1000) { +#if DIALOG_D1755 + iset_buck = iset_buck_calibration_1000; +#else + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000; +#endif + } + else if (input_current_limit >= 500) { +#if DIALOG_D1755 + iset_buck = iset_buck_calibration_500; +#elif DIALOG_D1815 + // should use 450mA instead of 500mA when CNBRICK software behavior bit is set, + // but we can't access it here (syscfg may not yet be configured). + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_450; +#else + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500; +#endif + } + else { + iset_buck = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + } +#endif /* DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2018*/ + + if (iset_buck_limit > 0) iset_buck = iset_buck_limit; + +#ifdef FORCE_ISET_BUCK + dprintf(DEBUG_INFO, "forcing 'iset_buck' from 0x%02X to 0x%02x\n", iset_buck, FORCE_ISET_BUCK); + iset_buck = FORCE_ISET_BUCK; +#endif + + // this is used as a reference for ISET_BUCK, so remove everything else + charge_buck_control &= kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK; + + if (iset_buck < charge_buck_control) { + // Ashley charger needs to be disabled to reduce usb current limit (6692148) + charge_buck_control = iset_buck; + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, charge_buck_control, true); +#if DIALOG_D1755 || DIALOG_D1815 + charge_buck_control |= kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN; + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, charge_buck_control, true); +#endif + } + +#if DIALOG_D1815 + if (input_current_limit >= 100) { + statusRegisters status; + dialog_read_status(status); + if (dialog_workaround_7886796(status)) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + } + } +#endif + +#if DIALOG_D1755 + if (iset_buck > charge_buck_control) { + // clear any pending interrupts from previous attach/detach + eventRegisters events; + charger_read_events(events); + } +#endif + + /* Limit USB current slew rate and back off chargers that can't supply the amount they claim (6662542) */ + while (iset_buck > charge_buck_control) { +#if DIALOG_D1755 + /* Raise the current limit one step at a time, and back off if VBUS drops but the charger remains present + * at 100mA (which the PMU will default to when VBUS snaps off the bus briefly). + */ + + UInt8 data = (++charge_buck_control) | kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN; + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, data, true); + + // check to see if the charger looks removed, which may mean we have overloaded it and VBUS has dropped. + UInt8 event; + bool vbus_rem; + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_EVENT_D, &event); + vbus_rem = event & kD1755_EVENT_D_VBUS_REM; + + if (vbus_rem) { + statusRegisters status; + + // if CHG_ATT is set, this means that charger was not really extracted; otherwise, it might be real extraction and we should trigger a recheck + dialog_read_status(status); + if (STATUS_FLAG_TEST(status, kDIALOG_STATUS_CHG_ATT_MASK)) { + // back off to the last value that worked and try again. + iset_buck = dialog_input_current_limit_step_down(charge_buck_control); + + dialog_log_charger_limit(iset_buck); + + // reduce the current limit to 100mA and ramp up again (to keep the slew rate intact). + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + + // make sure charger is disabled first, so we can reduce the current limit + data = charge_buck_control; + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, data, true); + data = charge_buck_control | kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN; + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, data, true); + + continue; + } + + break; + } +#else + +#if DIALOG_D1815 + /* Raise the current limit 100mA. Keep a dwell time of 10ms between steps, + * except for 700-900mA, which requires 20ms. + */ + if (charge_buck_control == kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700) { + task_sleep(20 * 1000); + } else { + task_sleep(10 * 1000); + } +#else + // 10ms per step (100mA) + task_sleep(10 * 1000); +#endif + +#if DIALOG_D1815 + /* For Ashley only, need to keep VBUS above VBUS_THR (4.3V). So if VBUS falls below 4.4V, + * stop increasing current limit. This is not needed on Angelina/Alison, which are fine + * well below 4.3V (down to VCENTER_DET). + */ + unsigned int vbus; + if (dialog_read_adc(CHARGER_IIC_BUS, kDIALOG_ADC_CONTROL_MUX_SEL_VBUS, &vbus) == 0) { + // VBUS has range of 0-5.5V (2.5V ADC scaled by 0.4545) + vbus = ((vbus * 5500) >> kDIALOG_ADC_RESOLUTION_BITS); + + if (vbus < 4400) { + iset_buck = charge_buck_control; + dialog_log_charger_limit(iset_buck); + continue; + } + } + + if (charge_buck_control < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200; // from 100mA to 200mA + } else if (charge_buck_control < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300; // from 200mA to 300mA + } else if (charge_buck_control < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400; // from 300mA to 400mA + } else if (charge_buck_control < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500; // from 400mA to 500mA + } else if (charge_buck_control < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600; // from 500mA to 600mA + } else if (charge_buck_control < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700; // from 600mA to 700mA + } else if (charge_buck_control < kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900) { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900; // from 700mA to 900mA + } else { + charge_buck_control = kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000; // from 900mA to 1000mA + } +#else + if (charge_buck_control + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA < iset_buck) { + charge_buck_control += kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA; + } else { + charge_buck_control = iset_buck; + } +#endif + +#if DIALOG_D1755 || DIALOG_D1815 + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, + charge_buck_control | kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN, true); +#else + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, charge_buck_control, true); +#endif + +#endif /* !DIALOG_D1755 */ + } + + iset_buck_limit = iset_buck; +#endif // !DIALOG_D2238 +} + +bool charger_charge_done(int dock) +{ + statusRegisters status; + + dialog_read_status(status); + + return !STATUS_FLAG_TEST(status, kDIALOG_STATUS_CHARGING_MASK); +} + +void charger_clear_usb_state(void) +{ + iset_buck_limit = 0; +} + +void charger_clear_alternate_usb_current_limit(void) +{ + +#if DIALOG_D1755 || DIALOG_D2238 + /* no alternate current USB limit */ +#elif DIALOG_D1815 + /* Ashley has an alternate USB current limit on boot; switch to the programmed + * limit, but only after we've programmed it in the case of precharge. + */ + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_ADC_BIST_CONTROL, kD1815_BIST_CONTROL_STD_USB_LIMIT, true); +#else + uint8_t data; + /* Angelina's alternate USB current limit is elsewhere */ + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_CONTROL_EN, &data); + data |= kDIALOG_CHARGE_CONTROL_ALT_USB_DIS; + dialog_set_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_CONTROL_EN, data, true); + +#endif + +} + +bool +charger_has_batterypack(int dock) +{ + // Use NTC to try to detect a disconnected battery, which will + // appear very cold. Since an extremely cold battery pack + // will also fail this check, do not do anything that would + // prevent the system from working correctly if it eventually + // warmed up as a result of this check. + int result; + unsigned adc; + + result = dialog_read_adc(CHARGER_IIC_BUS, kDIALOG_ADC_CONTROL_MUX_SEL_TBAT, &adc); + + // "Cold" is when the upper 9 bits of the ADC reading are all 1. + uint32_t max = (((1 << kDIALOG_ADC_RESOLUTION_BITS)-1) - + ((1 << (kDIALOG_ADC_RESOLUTION_BITS-9))-1)); + + return (result == 0) && (adc < max); +} + +bool +dialog_charger_check_usb_change(const eventRegisters ints_pending, const statusRegisters status) +{ + bool powersupply_change_event = EVENT_REGISTER_TEST_MASK(kDialogEventPwrsupplyMask, ints_pending); + +#if !DIALOG_D2238 + // if VBUS was removed but charger is still attached, try reducing the current limit + bool usb_limited = false; + if (EVENT_REGISTER_TEST_MASK(kDialogEventUSBMask, ints_pending) + && STATUS_FLAG_TEST(status, kDIALOG_STATUS_CHG_ATT_MASK) + && (iset_buck_limit > kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100)) + { + // if input limit has been set back to 100mA when we expected it to be higher, + // but is still attached, there was an extraction (we cannot use VBUS_EXT_REM + // because at low charging voltage, VBUS may not be asserted). + UInt8 iset_buck; + dialog_get_data(CHARGER_IIC_BUS, kDIALOG_CHARGE_BUCK_CONTROL, &iset_buck); + if ((iset_buck & kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK) == kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100) { + usb_limited = true; + } + } + if (usb_limited) + { + iset_buck_limit = dialog_input_current_limit_step_down(iset_buck_limit); + dialog_log_charger_limit(iset_buck_limit); + + if (power_enable_charging(true, true)) { + powersupply_change_event = false; + } + } +#endif + + return powersupply_change_event; +} + +int charger_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm) +{ + return dialog_set_data(dev, reg, byte, do_confirm); +} + +int charger_get_data(int dev, uint16_t reg, uint8_t *byte) +{ + return dialog_get_data(dev, reg, byte); +} + +#if WITH_HW_CHARGER +bool +charger_check_usb_change(int dock, bool expected) +{ + eventRegisters ints_pending; + statusRegisters status; + + /* Read & clear interrupts */ + dialog_read_events(ints_pending); + dialog_read_status(status); + + return dialog_charger_check_usb_change(ints_pending, status); +} + +void +charger_early_init(void) +{ + int rc; + uint8_t data; + + if (!power_is_suspended()) { + // make sure to clear any events + rc=dialog_get_data(CHARGER_IIC_BUS, kDIALOG_EVENT_A + kDIALOG_EVENT_COUNT - 1, &data); + } + +#if DIALOG_D2231 || DIALOG_D2355 +// J99 EVT not recognizing lightning connection + + rc=charger_get_data(CHARGER_IIC_BUS, kDIALOG_OTP_RELOAD_CONF, &data); + if ( rc!=0 ) { + dprintf(DEBUG_CRITICAL, "charger: cannot read reg=%x\n", kDIALOG_OTP_RELOAD_CONF); + } else if ( (data&kDIALOG_OTP_SKIP_RELOAD_TO_ACT)==0 ) { + data|=kDIALOG_OTP_SKIP_RELOAD_TO_ACT; // OVERRIDE OTP_SKIP_RELOAD_TO_ACT + + rc=charger_set_data(CHARGER_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA, false); // enter testmode + if ( rc!=0 ) { + + } else { + rc=charger_set_data(CHARGER_IIC_BUS, kDIALOG_OTP_RELOAD_CONF, data, false); + if ( rc!=0 ) { + + } else { + task_sleep(10 * 1000); // 10ms delay, race on charger insertion + + rc=charger_set_data(CHARGER_IIC_BUS, kDIALOG_OTP_RELOAD_CONF, data, false); + if ( rc!=0 ) dprintf(DEBUG_CRITICAL, "charger: cannot set SKIP_RELOAD_TO_ACT\n"); + } + + rc=charger_set_data(CHARGER_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS, false); // exit testmode + if ( rc!=0 ) panic("charger: cannot exit charger test mode"); + } + } else { + dprintf(DEBUG_INFO, "charger: kDIALOG_OTP_RELOAD_CONF ok\n"); + } +#endif +} + +void +charger_print_status(void) +{ + // no status +} + +#endif // WITH_HW_CHARGER + +#endif /* !WITH_HW_CHARGER || WITH_HW_CHARGER_DIALOG */ diff --git a/drivers/dialog/pmu/d1755.h b/drivers/dialog/pmu/d1755.h new file mode 100644 index 0000000..7987f87 --- /dev/null +++ b/drivers/dialog/pmu/d1755.h @@ -0,0 +1,563 @@ +#define PMU_HAS_SWI 1 +#define PMU_HAS_DWI 0 +#define PMU_HAS_LCM_LDO 0 +#define PMU_HAS_WLED 1 +#define PMU_HAS_REG_BANK 0 + +enum { + kDIALOG_ADDR_R = 0xe8, + kDIALOG_ADDR_W = 0xe9, + kDIALOG_REG_BYTES = 1, +}; + +enum { + kDIALOG_EVENT_COUNT = 4, + kDIALOG_STATUS_COUNT = 4, + kDIALOG_HIBERNATE_COUNT = 1, + kDIALOG_CHIPID_COUNT = 1, + kDIALOG_FAULTLOG_COUNT = 1, + kDIALOG_GPIO_COUNT = 8, + kDIALOG_GPIO_DEB_REG_COUNT = 3 +}; + +#include "dCommon.h" + +enum { + kDIALOG_CHIP_ID = 0x00, + + kDIALOG_EVENT_A = 0x01, + kDIALOG_EVENT_B = 0x02, + kDIALOG_EVENT_C = 0x03, + kDIALOG_EVENT_D = 0x04, + + kDIALOG_STATUS_A = 0x05, + kDIALOG_STATUS_B = 0x06, + kDIALOG_STATUS_C = 0x07, + kDIALOG_STATUS_D = 0x08, + + kDIALOG_IRQ_MASK_A = 0x09, + kDIALOG_IRQ_MASK_B = 0x0a, + kDIALOG_IRQ_MASK_C = 0x0b, + kDIALOG_IRQ_MASK_D = 0x0c, + + kDIALOG_SYS_CONTROL = 0x0d, + + kDIALOG_FAULT_LOG = 0x0e, + + kD1755_ACTIVE1 = 0x10, + kD1755_ACTIVE2 = 0x11, + kD1755_STANDBY1 = 0x12, + kDIALOG_STANDBY = kD1755_STANDBY1, + kD1755_HIBERNATE1 = 0x13, + + kD1755_BUCK1 = 0x14, + kDIALOG_BUCK1 = kD1755_BUCK1, + kD1755_BUCK2 = 0x15, + kD1755_SPECIAL = 0x16, + + kD1755_LDO1 = 0x17, + kD1755_LDO2 = 0x18, + kD1755_LDO3 = 0x19, + kD1755_LDO4 = 0x1a, + kD1755_LDO5 = 0x1b, + kD1755_LDO6 = 0x1c, + kD1755_LDO7 = 0x1d, + kD1755_LDO8 = 0x1e, + kD1755_LDO9 = 0x1f, + kD1755_LDO10 = 0x20, + kD1755_LDO11 = 0x21, + + kDIALOG_LDO_CONTROL = 0x22, + kDIALOG_BUCK_CONTROL = 0x23, + kD1755_BUCK_CONTROL2 = 0x24, + kDIALOG_BUCK_CONTROL2 = kD1755_BUCK_CONTROL2, + + kDIALOG_WLED_ISET = 0x25, + kDIALOG_WLED_CONTROL = 0x26, + kDIALOG_WLED_OPTIONS = kDIALOG_WLED_CONTROL, + + kDIALOG_CHARGE_BUCK_CONTROL = 0x27, + kD1755_CHARGE_CONTROL_A = 0x28, + kD1755_CHARGE_CONTROL_B = 0x29, + kD1755_CHARGE_TIME = 0x2a, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD1755_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_TIME = kD1755_CHARGE_CONTROL_B, + + kD1755_BUCK1_PRE1 = 0x2c, + kDIALOG_BUCK1_PRE1 = kD1755_BUCK1_PRE1, + kD1755_BUCK1_PRE2 = 0x2d, + kD1755_BUCK1_PRE3 = 0x2e, + kD1755_BUCK1_SEL = 0x2f, + kDIALOG_BUCK1_SEL = kD1755_BUCK1_SEL, + + kD1755_SYS_GPIO_1 = 0x50, + kDIALOG_SYS_GPIO_REG_START = kD1755_SYS_GPIO_1, + kD1755_SYS_GPIO_2 = 0x51, + kD1755_SYS_GPIO_3 = 0x52, + kD1755_SYS_GPIO_4 = 0x53, + kD1755_SYS_GPIO_5 = 0x54, + kD1755_SYS_GPIO_6 = 0x55, + kD1755_SYS_GPIO_7 = 0x56, + kD1755_SYS_GPIO_8 = 0x57, + + kD1755_GPIO_DEB1 = 0x59, + kDIALOG_SYS_GPIO_DEB_REG_START = kD1755_GPIO_DEB1, + kD1755_GPIO_DEB2 = 0x5a, + kD1755_GPIO_DEB3 = 0x5b, + + kD1755_BUTTON1 = 0x5c, + kD1755_BUTTON2 = 0x5d, + kD1755_BUTTON3 = 0x5e, + + kDIALOG_SYS_CONFIG = 0x5f, + + kDIALOG_ADC_CONTROL = 0x30, + kDIALOG_ADC_LSB = 0x31, + kDIALOG_ADC_MSB = 0x32, + + kDIALOG_ICHG_AVG = 0x35, + + kDIALOG_RTC_COUNT_A = 0x40, + kDIALOG_RTC_COUNT_B = 0x41, + kDIALOG_RTC_COUNT_C = 0x42, + kDIALOG_RTC_COUNT_D = 0x43, + kDIALOG_RTC_COUNT_E = 0x44, + kDIALOG_RTC_COUNT_F = 0x45, + kDIALOG_RTC_ALARM_A = 0x46, + kDIALOG_RTC_ALARM_B = 0x47, + kDIALOG_RTC_ALARM_C = 0x48, + kDIALOG_RTC_ALARM_D = 0x49, + kDIALOG_RTC_ALARM_E = 0x4a, + kDIALOG_RTC_TIMEZONE = 0x4b, + + kDIALOG_UPCOUNT_A = 0x4c, + kDIALOG_UPCOUNT_B = 0x4d, + kDIALOG_UPCOUNT_C = 0x4e, + kDIALOG_UPCOUNT_D = 0x4f, + + kDIALOG_MEMBYTE0 = 0x60, + kDIALOG_MEMBYTE_LAST = 0x87, + + kD1755_OTP_ISET_USB = 0xa5, + kDIALOG_OTP_ISET_BAT = 0xac, + kD1755_OTP_USB_900_LIMIT = 0xbf, + kD1755_OTP_USB_500_LIMIT = 0xc0, + + kD1755_TEST_MODE = 0xe0, +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0xf << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0xb << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_IN = (0xe << 0), + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 4), + kDIALOG_ADC_CONTROL_ADC_REF_EN = (1 << 5), + kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN = (1 << 6), + kDIALOG_ADC_CONTROL_TBAT_ISRC_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = kDIALOG_ADC_CONTROL_TBAT_ISRC_EN, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 10, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kD1755_ACTIVE1_SPECIAL = (1 << 2), + kD1755_SPECIAL_HIB_CHG = (1 << 2), +}; + +enum { + kD1755_CHIP_ID_MRC_MASK = (15 << 0), + kD1755_CHIP_ID_MRC_AA = (0 << 0), + kD1755_CHIP_ID_MRC_AB = (1 << 0), + kD1755_CHIP_ID_MRC_AC = (2 << 0), + kD1755_CHIP_ID_MRC_AD = (3 << 0), + kD1755_CHIP_ID_MRC_AE = (4 << 0), + kD1755_CHIP_ID_PROG = (1 << 4), + kD1755_CHIP_ID_PID_MASK = (7 << 5), +}; + +enum { + kD1755_EVENT_A_BUTTON1 = (1 << 0), + kD1755_EVENT_A_BUTTON2 = (1 << 1), + kD1755_EVENT_A_BUTTON3 = (1 << 2), + kD1755_EVENT_A_VBUS_DET = (1 << 3), + kD1755_EVENT_A_VHP_DET = (1 << 4), + kD1755_EVENT_A_ACC_DET = (1 << 5), + kD1755_EVENT_A_VBUS_EXT = (1 << 6), + kD1755_EVENT_A_VDD_LOW = (1 << 7), +}; + +// EVENT_B events are assumed volatile (lost over sleep/wake) +enum { + kD1755_EVENT_B_SWI = (1 << 0), + kD1755_EVENT_B_CHG_PRE = (1 << 1), + kD1755_EVENT_B_CHG_FAST = (1 << 2), + kD1755_EVENT_B_CHG_END = (1 << 3), + kD1755_EVENT_B_TBAT = (1 << 4), + kD1755_EVENT_B_EOMC = (1 << 5), + kD1755_EVENT_B_FW_OV = (1 << 6), + kDIALOG_EVENT_B_HIB = (1 << 7), +}; + +enum { + kD1755_EVENT_C_GPIO1 = (1 << 0), + kD1755_EVENT_C_GPIO2 = (1 << 1), + kD1755_EVENT_C_GPIO3 = (1 << 2), + kD1755_EVENT_C_GPIO4 = (1 << 3), + kD1755_EVENT_C_GPIO5 = (1 << 4), + kD1755_EVENT_C_GPIO6 = (1 << 5), + kD1755_EVENT_C_GPIO7 = (1 << 6), + kD1755_EVENT_C_GPIO8 = (1 << 7), +}; + +enum { + kD1755_EVENT_D_ALARM = (1 << 0), + kD1755_EVENT_D_VHP_REM = (1 << 4), + kD1755_EVENT_D_VBUS_REM = (1 << 6), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 3, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_110 = 4, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_120 = 5, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_350 = 6, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 7, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_450 = 8, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 9, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_550 = 10, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 11, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 12, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 13, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1100 = 12, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1300 = 15, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 15, + + kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 20, + kDIALOG_CHARGE_CONTROL_MAX = 1260, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0x78, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kD1755_TEST_MODE_TEST_EN = (1 << 0), + kD1755_TEST_MODE_RESET_PMU = (1 << 1), + kDIALOG_OTP_ISET_BAT_SHIFT = 0, +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_SWI_EN = (1 << 4), + kD1755_SYS_CONTROL_PRO_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE + | kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND | kD1755_SYS_CONTROL_PRO_FET_DIS, +}; + +enum { + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_BOOST = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + kDIALOG_FAULT_LOG_RESET_IN_1 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kD1755_STATUS_A_BUTTON1 = (1 << 0), + kD1755_STATUS_A_BUTTON2 = (1 << 1), + kD1755_STATUS_A_BUTTON3 = (1 << 2), + kD1755_STATUS_A_VBUS_DET = (1 << 3), + kD1755_STATUS_A_VHP_DET = (1 << 4), + kD1755_STATUS_A_ACC_DET = (1 << 5), + kD1755_STATUS_A_VBUS_EXT = (1 << 6), + kD1755_STATUS_A_VDD_LOW = (1 << 7), +}; +enum { + kD1755_STATUS_B_CHG_ATT = (1 << 0), + kD1755_STATUS_B_CHG_PRE = (1 << 1), + kD1755_STATUS_B_CHG_FAST = (1 << 2), + kD1755_STATUS_B_CHG_END = (1 << 3), + kD1755_STATUS_B_TBAT = (1 << 4), + kD1755_STATUS_B_CHG_TO = (1 << 5), + kD1755_STATUS_B_FW_OV = (1 << 6), +}; +enum { + kD1755_STATUS_C_GPIO1 = (1 << 0), + kD1755_STATUS_C_GPIO2 = (1 << 1), + kD1755_STATUS_C_GPIO3 = (1 << 2), + kD1755_STATUS_C_GPIO4 = (1 << 3), + kD1755_STATUS_C_GPIO5 = (1 << 4), + kD1755_STATUS_C_GPIO6 = (1 << 5), + kD1755_STATUS_C_GPIO7 = (1 << 6), + kD1755_STATUS_C_GPIO8 = (1 << 7), +}; + +enum { + kD1755_EVENT_C_GPIO_FW_DETECT = kD1755_EVENT_C_GPIO7 +}; + +enum { + kD1755_EVENT_A_WAKEMASK = kD1755_EVENT_A_BUTTON1 + | kD1755_EVENT_A_BUTTON2 + | kD1755_EVENT_A_BUTTON3 + | kD1755_EVENT_A_VBUS_DET + | kD1755_EVENT_A_VHP_DET + | kD1755_EVENT_A_ACC_DET, + kD1755_EVENT_B_WAKEMASK = 0, + kD1755_EVENT_C_WAKEMASK = kD1755_EVENT_C_GPIO_FW_DETECT, + kD1755_EVENT_D_WAKEMASK = kD1755_EVENT_D_ALARM + | kD1755_EVENT_D_VHP_REM + | kD1755_EVENT_D_VBUS_REM, +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1755_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1755_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(0, kD1755_EVENT_A_BUTTON3), + kDIALOG_EVENT_A_BUTTONS = (kD1755_EVENT_A_BUTTON2 | + kD1755_EVENT_A_BUTTON1 | + kD1755_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(0, kDIALOG_EVENT_A_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(3, kD1755_EVENT_D_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD1755_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD1755_EVENT_A_VBUS_DET), + kDIALOG_EVENT_VHP_DET_MASK = EVENT_FLAG_MAKE(0, kD1755_EVENT_A_VHP_DET), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(1, kD1755_EVENT_B_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_B_HIB), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(1, kD1755_EVENT_B_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(1, kD1755_EVENT_B_TBAT), + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(2, kD1755_EVENT_C_GPIO8), + + kD1755_EVENT_D_VBUS_REM_MASK = EVENT_FLAG_MAKE(3, kD1755_EVENT_D_VBUS_REM), + +/* + kDIALOG_EVENT_WAKE_MASK = ((kD1755_EVENT_A_WAKEMASK << 0) + | (kD1755_EVENT_B_WAKEMASK << 8) + | (kD1755_EVENT_C_WAKEMASK << 16) + | (kD1755_EVENT_D_WAKEMASK << 24)), + + kDIALOG_EVENT_PWRSUPPLY_MASK + = (((kD1755_EVENT_A_VBUS_DET | kD1755_EVENT_A_VHP_DET) << 0) + | (kD1755_EVENT_C_GPIO_FW_DETECT << 16) + | ((kD1755_EVENT_D_VHP_REM | kD1755_EVENT_D_VBUS_REM) << 24)), +*/ + // not on D1755 + kDIALOG_EVENT_ON_MASK = 0, + kDIALOG_EVENT_LDO2_EN_MASK = 0, + kDIALOG_EVENT_GPIO9_MASK = 0, + kDIALOG_EVENT_GPIO10_MASK = 0, + kDIALOG_EVENT_GPIO11_MASK = 0, + kDIALOG_EVENT_GPIO12_MASK = 0, + kDIALOG_EVENT_GPIO13_MASK = 0, + kDIALOG_EVENT_GPIO14_MASK = 0, + kDIALOG_EVENT_GPIO15_MASK = 0, + kDIALOG_EVENT_GPIO16_MASK = 0, + kDIALOG_EVENT_GPIO17_MASK = 0, + kDIALOG_EVENT_GPIO18_MASK = 0, + kDIALOG_EVENT_HOLD_DBL_MASK = 0, + kDIALOG_EVENT_MENU_DBL_MASK = 0, + kDIALOG_EVENT_RINGER_DBL_MASK = 0, +}; + +#define kDIALOG_EVENT_GPIOn_MASK(n) EVENT_FLAG_MAKE(2, (1 << (n))) + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static static const eventRegisters kDialogEventIntMasks = { + ~kD1755_EVENT_A_WAKEMASK, + ~kD1755_EVENT_B_WAKEMASK, + ~kD1755_EVENT_C_WAKEMASK, + ~kD1755_EVENT_D_WAKEMASK +}; + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD1755_EVENT_A_WAKEMASK & ~kDIALOG_EVENT_A_BUTTONS, + kD1755_EVENT_B_WAKEMASK, + kD1755_EVENT_C_WAKEMASK, + kD1755_EVENT_D_WAKEMASK +}; + +// All events that do defer shutdown +static const eventRegisters kDialogEventRestartMask = { + kDIALOG_EVENT_HOLD_BUTTON_MASK | kDIALOG_EVENT_ACC_DET_MASK, + 0, + 0, + kD1755_EVENT_D_ALARM +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD1755_EVENT_A_VBUS_DET | kD1755_EVENT_A_VHP_DET, + 0, + kD1755_EVENT_C_GPIO_FW_DETECT, + kD1755_EVENT_D_VHP_REM | kD1755_EVENT_D_VBUS_REM +}; +static const eventRegisters kDialogEventUSBMask = { + kD1755_EVENT_A_VBUS_DET, + 0, + 0, + kD1755_EVENT_D_VBUS_REM +}; +static const eventRegisters kDialogEventFWMask = { + kD1755_EVENT_A_VHP_DET, + 0, + kD1755_EVENT_C_GPIO_FW_DETECT, + kD1755_EVENT_D_VHP_REM +}; +enum { + kDialogEventPwrsupplyCount = 5, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 3, +}; + +enum { + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = 0, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD1755_STATUS_A_VBUS_DET), + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD1755_STATUS_A_ACC_DET), +// kDIALOG_STATUS_FW_MASK = ((kD1755_STATUS_A_VHP_DET << 0) | (kD1755_EVENT_C_GPIO_FW_DETECT << 16)), +// kDIALOG_STATUS_CHARGING_MASK = ((kD1755_STATUS_B_CHG_PRE | kD1755_STATUS_B_CHG_FAST) << 8), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(1, kD1755_STATUS_B_CHG_TO), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD1755_STATUS_B_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(1, kD1755_STATUS_B_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(1, kD1755_STATUS_B_CHG_ATT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(2, (1 << (gpio))) + + kDIALOG_STATUS_HOLD_BUTTON_MASK = STATUS_FLAG_MAKE(0, kD1755_STATUS_A_BUTTON2), + kDIALOG_STATUS_MENU_BUTTON_MASK = STATUS_FLAG_MAKE(0, kD1755_STATUS_A_BUTTON1), + kDIALOG_STATUS_RINGER_BUTTON_MASK = STATUS_FLAG_MAKE(0, kD1755_STATUS_A_BUTTON3), +}; + +static const statusRegisters kDialogStatusFWMask = {kD1755_STATUS_A_VHP_DET, 0, kD1755_EVENT_C_GPIO_FW_DETECT, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD1755_STATUS_B_CHG_PRE | kD1755_STATUS_B_CHG_FAST, 0, 0}; + +enum { + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (1 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (2 << 5), + + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + kDIALOG_SYS_GPIO_OUTPUT_32KHZ = (1 << 2), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + == kDIALOG_SYS_GPIO_DIRECTION_OUT) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_RAMP_EN = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_SWI_EN = (1 << 3), + kDIALOG_WLED_CONTROL_BOOST_FREQ = (1 << 4), + kDIALOG_WLED_CONTROL_BOOST_ILIMIT_710 = (0 << 5), + kDIALOG_WLED_CONTROL_BOOST_ILIMIT_1000 = (1 << 5), + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL_BOOST_ILIMIT_710, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL_WLED_SWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL_BOOST_FREQ| + kDIALOG_WLED_CONTROL_BOOST_ILIMIT_1000), +}; + +enum { + kDIALOG_RTC_COUNT_A_SEC_MASK = (0x3f), + kDIALOG_RTC_COUNT_A_MONITOR = (1 << 6), +}; + +enum { + kDIALOG_RTC_ALARM_E_YEAR_MASK = (0x3f), + kDIALOG_RTC_ALARM_E_ALARM_ON = (1 << 6) +}; + +enum { + kDIALOG_BUCK_CONTROL_BUCK1_GO = (1 << 6), + kDIALOG_BUCK_CONTROL_BUCK1_SWI_EN = (1 << 7) +}; + +enum { + kDIALOG_BUCK_CONTROL2_HIB_CLK = (1 << 7), +}; + +#define NUM_LDOS 12 +static const struct ldo_params ldo_1755[NUM_LDOS] = { +{ 2500, 50, 0x15, 0x1f, 0x1, kD1755_LDO1, kD1755_ACTIVE1, 0x08 }, // LDO1 +{ 1500, 50, 0x24, 0x3f, 0x0, kD1755_LDO2, kD1755_ACTIVE1, 0x10 }, // LDO2 +{ 2500, 50, 0x10, 0x1f, 0x0, kD1755_LDO3, kD1755_ACTIVE1, 0x20 }, // LDO3 +{ 1800, 50, 0x1e, 0x1f, 0x0, kD1755_LDO4, kD1755_ACTIVE1, 0x40 }, // LDO4 +{ 2500, 50, 0x16, 0x1f, 0x2, kD1755_LDO5, kD1755_ACTIVE1, 0x80 }, // LDO5 +{ 2500, 50, 0x16, 0x1f, 0x4, kD1755_LDO6, kD1755_ACTIVE2, 0x01 }, // LDO6 +{ 1500, 100,0x1f, 0x1f, 0x0, kD1755_LDO7, kD1755_ACTIVE2, 0x02 }, // LDO7 +{ 2000, 50, 0x1f, 0x1f, 0x0, kD1755_LDO8, kD1755_ACTIVE2, 0x04 }, // LDO8 +{ 1200, 25, 0x0c, 0x0f, 0x0, kD1755_LDO9, kD1755_ACTIVE2, 0x80 }, // LDO9 +{ 1700, 50, 0x1a, 0x1f, 0x0, kD1755_LDO10, kD1755_ACTIVE2, 0x10 }, // LDO10 +{ 1700, 50, 0x1a, 0x1f, 0x0, kD1755_LDO11, kD1755_ACTIVE2, 0x20 }, // LDO11 +{ 0, 0, 0, 0, 0x0, 0, kD1755_ACTIVE2, 0x40 }, // 12 - WDIG_EN +}; +#define LDOP ldo_1755 + +#define WLED_ISET_BITS (8) diff --git a/drivers/dialog/pmu/d1815.h b/drivers/dialog/pmu/d1815.h new file mode 100644 index 0000000..a5c4bd0 --- /dev/null +++ b/drivers/dialog/pmu/d1815.h @@ -0,0 +1,677 @@ +#define PMU_HAS_SWI 1 +#define PMU_HAS_DWI 0 +#define PMU_HAS_REG_BANK 0 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_VIB 1 +#define PMU_HAS_WLED 1 + +enum { + kDIALOG_ADDR_R = 0xe8, + kDIALOG_ADDR_W = 0xe9, + kDIALOG_REG_BYTES = 1, +}; + +enum { + kDIALOG_EVENT_COUNT = 6, + kDIALOG_STATUS_COUNT = 5, + kDIALOG_HIBERNATE_COUNT = 3, + kDIALOG_CHIPID_COUNT = 1, + kDIALOG_FAULTLOG_COUNT = 1, + kDIALOG_GPIO_COUNT = 10, +}; + +#include "dCommon.h" + +enum { + kDIALOG_CHIP_ID = 0x00, + + kDIALOG_EVENT_A = 0x01, + kDIALOG_EVENT_B = 0x02, + kDIALOG_EVENT_C = 0x03, + kDIALOG_EVENT_D = 0x04, + kDIALOG_EVENT_E = 0x05, + kDIALOG_EVENT_F = 0x06, + + kDIALOG_STATUS_A = 0x07, + kDIALOG_STATUS_B = 0x08, + kDIALOG_STATUS_C = 0x09, + kDIALOG_STATUS_D = 0x0a, + kDIALOG_STATUS_E = 0x0b, + + kDIALOG_IRQ_MASK_A = 0x0c, + kDIALOG_IRQ_MASK_B = 0x0d, + kDIALOG_IRQ_MASK_C = 0x0e, + kDIALOG_IRQ_MASK_D = 0x0f, + kDIALOG_IRQ_MASK_E = 0x10, + kDIALOG_IRQ_MASK_F = 0x11, + + kDIALOG_SYS_CONTROL = 0x12, + + kDIALOG_FAULT_LOG = 0x13, + + kD1815_ACTIVE1 = 0x14, + kD1815_ACTIVE2 = 0x15, + kD1815_ACTIVE3 = 0x16, + kDIALOG_LCM_ACTIVE = kD1815_ACTIVE3, + kD1815_STANDBY1 = 0x17, + kDIALOG_STANDBY = kD1815_STANDBY1, + kD1815_HIBERNATE1 = 0x18, + kD1815_HIBERNATE2 = 0x19, + kD1815_HIBERNATE3 = 0x1a, + + kD1815_BUCK1 = 0x1b, + kDIALOG_BUCK1 = kD1815_BUCK1, + kD1815_BUCK2 = 0x1c, + + kD1815_LDO1 = 0x1d, + kD1815_LDO2 = 0x1e, + kD1815_LDO3 = 0x1f, + kD1815_LDO4 = 0x20, + kD1815_LDO5 = 0x21, + kD1815_LDO6 = 0x22, + kD1815_LDO7 = 0x23, + kD1815_LDO8 = 0x24, + kD1815_LDO9 = 0x25, + kD1815_LDO10 = 0x26, + kD1815_LDO11 = 0x27, + kD1815_LDO12 = 0x28, + + kDIALOG_BUCK_CONTROL = 0x29, + kDIALOG_BUCK_CONTROL2 = 0x2a, + + kDIALOG_CHARGE_BUCK_CONTROL = 0x2b, + kDIALOG_CHARGE_CONTROL_A = 0x2c, + kDIALOG_CHARGE_CONTROL_B = 0x2d, + kDIALOG_CHARGE_CONTROL_C = 0x2e, + kDIALOG_CHARGE_TIME = 0x2f, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_HIB = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_TIME = kDIALOG_CHARGE_CONTROL_C, + kDIALOG_OTP_ISET_BAT = kDIALOG_CHARGE_CONTROL_A, // not a real OTP register + + kDIALOG_ADC_CONTROL = 0x30, + kDIALOG_ADC_LSB = 0x31, + kDIALOG_ADC_MSB = 0x32, + kDIALOG_ADC_BIST_CONTROL = 0x33, + kD1815_ADC_T_ISET = 0x34, + kDIALOG_ICHG_AVG = 0x35, + + kDIALOG_TBAT_0 = 0x38, + kDIALOG_ICHG_TBAT_0 = 0x39, + kDIALOG_TBAT_1 = 0x3a, + kDIALOG_ICHG_TBAT_1 = 0x3b, + kDIALOG_TBAT_2 = 0x3c, + kDIALOG_ICHG_TBAT_2 = 0x3d, + kDIALOG_TBAT_3 = 0x3e, + kDIALOG_ICHG_TBAT_3 = 0x3f, + kDIALOG_TBAT_4 = 0x40, + kDIALOG_ICHG_TBAT_4 = 0x41, + kDIALOG_TBAT_MAX = 0x42, + kDIALOG_ICHG_TBAT_NUM = 5, + + kDIALOG_T_OFFSET_MSB = 0x43, + kDIALOG_T_OFFSET_LSB = 0x44, + + kDIALOG_RTC_ALARM_A = 0x46, + kDIALOG_RTC_ALARM_B = 0x47, + kDIALOG_RTC_ALARM_C = 0x48, + kDIALOG_RTC_ALARM_D = 0x49, + kDIALOG_RTC_CONTROL = 0x4a, + kDIALOG_RTC_TIMEZONE = 0x4b, + kDIALOG_UPCOUNT_A = 0x4c, + kDIALOG_UPCOUNT_B = 0x4d, + kDIALOG_UPCOUNT_C = 0x4e, + kDIALOG_UPCOUNT_D = 0x4f, + + kD1815_SYS_GPIO_1 = 0x50, + kDIALOG_SYS_GPIO_REG_START = kD1815_SYS_GPIO_1, + kD1815_SYS_GPIO_2 = 0x51, + kD1815_SYS_GPIO_3 = 0x52, + kD1815_SYS_GPIO_4 = 0x53, + kD1815_SYS_GPIO_5 = 0x54, + kD1815_SYS_GPIO_6 = 0x55, + kD1815_SYS_GPIO_7 = 0x56, + kD1815_SYS_GPIO_8 = 0x57, + kD1815_SYS_GPIO_TEMP = 0x58, + kD1815_SYS_GPIO_SPARE = 0x59, + + kD1815_SYS_GPIO_DEB1 = 0x5a, + kDIALOG_SYS_GPIO_DEB_REG_START = kD1815_SYS_GPIO_DEB1, + kD1815_SYS_GPIO_DEB2 = 0x5b, + kD1815_SYS_GPIO_DEB3 = 0x5c, + kD1815_SYS_GPIO_DEB4 = 0x5d, + kD1815_SYS_GPIO_DEB6 = 0x5e, + + kDIALOG_LDO_CONTROL = 0x5f, + + kDIALOG_WLED_ISET = 0x66, + kDIALOG_WLED_ISET2 = 0x67, + kDIALOG_WLED_CONTROL = 0x68, + kDIALOG_WLED_OPTIONS = kDIALOG_WLED_CONTROL, + + kD1815_LCM_CONTROL1 = 0x6a, + kD1815_LCM_CONTROL2 = 0x6b, + kD1815_LCM_CONTROL3 = 0x6c, + kDIALOG_LCM_BOOST = kD1815_LCM_CONTROL3, + + kDIALOG_VIB_CTRL = 0x6e, + kDIALOG_VIB_VSET = 0x6f, + + kD1815_BUTTON1 = 0x78, + kD1815_BUTTON2 = 0x79, + kD1815_BUTTON3 = 0x7a, + kDIALOG_SYS_CONFIG = 0x7b, + + kD1815_BUCK1_PRE1 = 0x7c, + kDIALOG_BUCK1_PRE1 = kD1815_BUCK1_PRE1, + kD1815_BUCK1_PRE2 = 0x7d, + kD1815_BUCK1_PRE3 = 0x7e, + kD1815_BUCK1_SEL = 0x7f, + kDIALOG_BUCK1_SEL = kD1815_BUCK1_SEL, + + kDIALOG_MEMBYTE0 = 0x80, + kDIALOG_MEMBYTE_LAST = 0xa7, + + kDIALOG_BUTTON_DBL = 0xAD, +}; + +enum { + kD1815_CHIP_ID_MRC_MASK = (0xf << 0), + kD1815_CHIP_ID_MRC_A0 = (0 << 0), + kD1815_CHIP_ID_MRC_A1 = (1 << 0), +}; + +enum { + kD1815_EVENT_A_BUTTON1 = (1 << 0), + kD1815_EVENT_A_BUTTON2 = (1 << 1), + kD1815_EVENT_A_BUTTON3 = (1 << 2), + kD1815_EVENT_A_VBUS_DET = (1 << 3), + kD1815_EVENT_A_FW_DET = (1 << 4), + kD1815_EVENT_A_ACC_DET = (1 << 5), + kD1815_EVENT_A_VBUS_EXT = (1 << 6), + kD1815_EVENT_A_VDD_LOW = (1 << 7), +}; + +// EVENT_B events are assumed volatile (lost over sleep/wake) +enum { + kD1815_EVENT_B_SWI = (1 << 0), + kD1815_EVENT_B_CHG_PRE = (1 << 1), + kD1815_EVENT_B_CHG_FAST = (1 << 2), + kD1815_EVENT_B_CHG_END = (1 << 3), + kD1815_EVENT_B_TBAT = (1 << 4), + kD1815_EVENT_B_EOMC = (1 << 5), + kD1815_EVENT_B_FW_OV = (1 << 6), + kDIALOG_EVENT_B_HIB = (1 << 7), +}; + +enum { + kD1815_EVENT_C_GPIO1 = (1 << 0), + kD1815_EVENT_C_GPIO2 = (1 << 1), + kD1815_EVENT_C_GPIO3 = (1 << 2), + kD1815_EVENT_C_GPIO4 = (1 << 3), + kD1815_EVENT_C_GPIO5 = (1 << 4), + kD1815_EVENT_C_GPIO6 = (1 << 5), + kD1815_EVENT_C_GPIO7 = (1 << 6), + kD1815_EVENT_C_GPIO8 = (1 << 7), +}; + +enum { + kD1815_EVENT_E_ALARM = (1 << 0), + kD1815_EVENT_E_FW_REM = (1 << 4), + kD1815_EVENT_E_VBUS_REM = (1 << 6), +}; + +enum { + kD1815_EVENT_F_GPIO9 = (1 << 0), + kD1815_EVENT_F_GPIO10 = (1 << 1), + kD1815_EVENT_F_BTN1_DBL = (1 << 2), + kD1815_EVENT_F_BTN2_DBL = (1 << 3), + kD1815_EVENT_F_BTN3_DBL = (1 << 4), +}; + +enum { + kD1815_STATUS_A_BUTTON1 = (1 << 0), + kD1815_STATUS_A_BUTTON2 = (1 << 1), + kD1815_STATUS_A_BUTTON3 = (1 << 2), + kD1815_STATUS_A_VBUS_DET = (1 << 3), + kD1815_STATUS_A_FW_DET = (1 << 4), + kD1815_STATUS_A_ACC_DET = (1 << 5), + kD1815_STATUS_A_VBUS_EXT = (1 << 6), + kD1815_STATUS_A_VDD_LOW = (1 << 7), +}; +enum { + kD1815_STATUS_B_CHG_ATT = (1 << 0), + kD1815_STATUS_B_CHG_PRE = (1 << 1), + kD1815_STATUS_B_CHG_FAST = (1 << 2), + kD1815_STATUS_B_CHG_END = (1 << 3), + kD1815_STATUS_B_TBAT = (1 << 4), + kD1815_STATUS_B_CHG_TO = (1 << 5), + kD1815_STATUS_B_FW_OV = (1 << 6), +}; +enum { + kD1815_STATUS_C_GPIO1 = (1 << 0), + kD1815_STATUS_C_GPIO2 = (1 << 1), + kD1815_STATUS_C_GPIO3 = (1 << 2), + kD1815_STATUS_C_GPIO4 = (1 << 3), + kD1815_STATUS_C_GPIO5 = (1 << 4), + kD1815_STATUS_C_GPIO6 = (1 << 5), + kD1815_STATUS_C_GPIO7 = (1 << 6), + kD1815_STATUS_C_GPIO8 = (1 << 7), +}; + +enum { + kD1815_STATUS_E_GPIO9 = (1 << 0), + kD1815_STATUS_E_GPIO10 = (1 << 1), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1815_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1815_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(0, kD1815_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS = (kD1815_EVENT_A_BUTTON2 | + kD1815_EVENT_A_BUTTON1 | + kD1815_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(0, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(4, kD1815_EVENT_E_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD1815_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD1815_EVENT_A_VBUS_DET), + kDIALOG_EVENT_VHP_DET_MASK = EVENT_FLAG_MAKE(0, kD1815_STATUS_A_FW_DET), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(1, kD1815_EVENT_B_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_B_HIB), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(1, kD1815_STATUS_B_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(1, kD1815_STATUS_B_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(2, kD1815_EVENT_C_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(5, kD1815_EVENT_F_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(5, kD1815_EVENT_F_GPIO10), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(5, kD1815_EVENT_F_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(5, kD1815_EVENT_F_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(5, kD1815_EVENT_F_BTN3_DBL), + + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO11_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO12_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO13_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO14_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO15_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO16_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO17_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, + + + /* + kDIALOG_EVENT_WAKE_MASK = ((kD1815_EVENT_A_WAKEMASK << 0) + | (kD1815_EVENT_B_WAKEMASK << 8) + | (kD1815_EVENT_C_WAKEMASK << 16) + | (kD1815_EVENT_D_WAKEMASK << 24)), + + kDIALOG_EVENT_BUTTONS_MASK = (kDIALOG_EVENT_HOLD_BUTTON_MASK | + kDIALOG_EVENT_MENU_BUTTON_MASK | + kDIALOG_EVENT_RINGER_BUTTON_MASK), + + kDIALOG_EVENT_PWRSUPPLY_MASK + = (((kD1815_EVENT_A_VBUS_DET | kD1815_STATUS_A_FW_DET) << 0) + | (kD1815_EVENT_C_GPIO_FW_DETECT << 16) + | ((kD1815_EVENT_D_VHP_REM | kD1815_EVENT_D_VBUS_REM) << 24)), + */ + + // not on D1755 + /* + kDIALOG_EVENT_ON_MASK = 0, + kDIALOG_EVENT_LDO2_EN_MASK = 0, + */ +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD1815_STATUS_A_VBUS_DET), + kDIALOG_STATUS_FW_MASK = STATUS_FLAG_MAKE(0, kD1815_STATUS_A_FW_DET), + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD1815_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(1, kD1815_STATUS_B_CHG_PRE | kD1815_STATUS_B_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(1, kD1815_STATUS_B_CHG_TO), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD1815_STATUS_B_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(1, kD1815_STATUS_B_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(1, kD1815_STATUS_B_CHG_ATT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(((gpio) < 8) ? 2 : 5, (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {kD1815_STATUS_A_FW_DET, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD1815_STATUS_B_CHG_PRE | kD1815_STATUS_B_CHG_FAST, 0, 0, 0}; + +enum { + kD1815_EVENT_A_WAKEMASK = kD1815_EVENT_A_BUTTON1 | kD1815_EVENT_A_BUTTON2 | kD1815_EVENT_A_BUTTON3 | kD1815_EVENT_A_VBUS_DET | kD1815_STATUS_A_FW_DET | kD1815_EVENT_A_ACC_DET, + kD1815_EVENT_B_WAKEMASK = kDIALOG_EVENT_B_HIB | kD1815_EVENT_B_TBAT | kD1815_EVENT_B_CHG_END, + kD1815_EVENT_C_WAKEMASK = kD1815_EVENT_C_GPIO1 | kD1815_EVENT_C_GPIO2 | kD1815_EVENT_C_GPIO3 | kD1815_EVENT_C_GPIO4 | kD1815_EVENT_C_GPIO5 | kD1815_EVENT_C_GPIO6 | kD1815_EVENT_C_GPIO7 | kD1815_EVENT_C_GPIO8, + kD1815_EVENT_D_WAKEMASK = 0, + kD1815_EVENT_E_WAKEMASK = kD1815_EVENT_E_ALARM | kD1815_EVENT_E_FW_REM | kD1815_EVENT_E_VBUS_REM, + kD1815_EVENT_F_WAKEMASK = kD1815_EVENT_F_GPIO9 | kD1815_EVENT_F_GPIO10, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + (UInt8)~kD1815_EVENT_A_WAKEMASK, + (UInt8)~kD1815_EVENT_B_WAKEMASK, + (UInt8)~kD1815_EVENT_C_WAKEMASK, + (UInt8)~kD1815_EVENT_D_WAKEMASK, + (UInt8)~kD1815_EVENT_E_WAKEMASK, + (UInt8)~kD1815_EVENT_F_WAKEMASK, +}; + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD1815_EVENT_A_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD1815_EVENT_B_WAKEMASK, + kD1815_EVENT_C_WAKEMASK, + kD1815_EVENT_D_WAKEMASK, + kD1815_EVENT_E_WAKEMASK, + kD1815_EVENT_F_WAKEMASK +}; + +// All events that defer shutdown +static const eventRegisters kDialogEventRestartMask = { + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_HOLD_BUTTON_MASK, 0) | EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ACC_DET_MASK, 0), + 0, + 0, + 0, + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ALARM_MASK, 4), + 0 +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD1815_EVENT_A_VBUS_DET | kD1815_EVENT_A_FW_DET, + 0, + 0, + 0, + kD1815_EVENT_E_FW_REM | kD1815_EVENT_E_VBUS_REM, + 0, +}; +static const eventRegisters kDialogEventUSBMask = { + kD1815_EVENT_A_VBUS_DET, + 0, + 0, + 0, + kD1815_EVENT_E_VBUS_REM, + 0, +}; +static const eventRegisters kDialogEventFWMask = { + kD1815_EVENT_A_FW_DET, + 0, + 0, + 0, + kD1815_EVENT_E_FW_REM, + 0, +}; +enum { + kDialogEventPwrsupplyCount = 4, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 2, +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_SWI_EN = (1 << 4), + kD1815_SYS_CONTROL_PRO_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + kDIALOG_FAULT_LOG_BOOST = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kD1815_ACTIVE3_LCM_BOOST_EN = (1 << 3), + kD1815_ACTIVE3_LCM_LDO1_EN = (1 << 4), + kD1815_ACTIVE3_LCM_LDO2_EN = (1 << 5), + + kDIALOG_LCM_ACTIVE_BOOST_EN = kD1815_ACTIVE3_LCM_BOOST_EN, + kDIALOG_LCM_ACTIVE_MASK = (kD1815_ACTIVE3_LCM_LDO1_EN| + kD1815_ACTIVE3_LCM_LDO2_EN), +}; + +enum { + kDIALOG_BUCK_CONTROL_BUCK1_GO = (1 << 6), + kDIALOG_BUCK_CONTROL_BUCK1_SWI_EN = (1 << 7) +}; + +enum { + kDIALOG_BUCK_CONTROL2_HIB_CLK = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_50 = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x05, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0f, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300 = 0x11, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 0x13, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_450 = 0x14, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x15, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 0x17, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 0x18, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 0x19, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x1a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0x1f, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0x1f, + + kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_A_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_A_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_A_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 30, + kDIALOG_CHARGE_CONTROL_MAX = 1890, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0xf << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_IN = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (0xf << 0), + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 4), + kDIALOG_ADC_CONTROL_ADC_REF_EN = (1 << 5), + kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN = (1 << 6), + kDIALOG_ADC_CONTROL_TBAT_ISRC_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK1 = (0 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (1 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (2 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (3 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (4 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (5 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (6 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (7 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (8 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (9 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IBAT_IN_OFF = (14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IBAT_OUT_OFF = (15 << 0), + kDIALOG_BIST_ADC_CTRL_BIST_EN = (1 << 7), + kD1815_BIST_CONTROL_STD_USB_LIMIT = (1 << 4), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH= (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_RAMP_EN = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_SWI_EN = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_DITHER_EN = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_DITH_RAMP_EN = (1 << 5), + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL_WLED_DITHER_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL_WLED_SWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL_WLED_DITHER_EN| + kDIALOG_WLED_CONTROL_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS (11) + +enum { + kDIALOG_VIB_CTRL_PWM_EN = (1 << 0), + kDIALOG_VIB_CTRL_BRAKE = (1 << 1), + kDIALOG_VIB_CTRL_PWM_CLK_MASK = (3 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_2MHZ = (0 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_1MHZ = (1 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_500KHZ = (2 << 2), + + kDIALOG_VIB_VSET_MASK = (0x3f << 0), +}; + +enum { + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = 0, +}; + +enum { + kDIALOG_SWI_WLED_ISET = (1 << 12), + kDIALOG_SWI_BUCK1_VSEL = (6 << 12), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD1815_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD1815_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD1815_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD1815_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD1815_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD1815_BUTTON_DBL_BTN3_DBL_EN, +}; + +#define NUM_LDOS 19 +static const struct ldo_params ldo_1815[NUM_LDOS] = { +{ 2500, 50, 0x15, 0x1f, 0x1, kD1815_LDO1, kD1815_ACTIVE1, 0x04 }, // LDO1 +{ 1650, 5, 0x1f, 0x1f, 0x0, kD1815_LDO2, kD1815_ACTIVE1, 0x08 }, // LDO2 +{ 2500, 50, 0x10, 0x1f, 0x0, kD1815_LDO3, kD1815_ACTIVE1, 0x10 }, // LDO3 +{ 1800, 50, 0x1e, 0x1f, 0x0, kD1815_LDO4, kD1815_ACTIVE1, 0x20 }, // LDO4 +{ 2500, 50, 0x16, 0x1f, 0x2, kD1815_LDO5, kD1815_ACTIVE1, 0x40 }, // LDO5 +{ 2500, 50, 0x16, 0x1f, 0x4, kD1815_LDO6, kD1815_ACTIVE1, 0x80 }, // LDO6 +{ 1500, 100,0x1f, 0x1f, 0x0, kD1815_LDO7, kD1815_ACTIVE2, 0x01 }, // LDO7 +{ 2000, 50, 0x1f, 0x1f, 0x0, kD1815_LDO8, kD1815_ACTIVE2, 0x02 }, // LDO8 +{ 1200, 25, 0x0c, 0x0f, 0x0, kD1815_LDO9, kD1815_ACTIVE2, 0x04 }, // LDO9 +{ 1700, 50, 0x1a, 0x1f, 0x8, kD1815_LDO10, kD1815_ACTIVE2, 0x08 }, // LDO10 +{ 1700, 50, 0x1a, 0x1f, 0x0, kD1815_LDO11, kD1815_ACTIVE2, 0x10 }, // LDO11 +{ 600, 25, 0x1c, 0x1f, 0x0, kD1815_LDO12, kD1815_ACTIVE2, 0x20 }, // LDO12 +{ 0, 0, 0, 0, 0x0, 0, kD1815_ACTIVE3, 0x02 }, // 13 - WDIG_EN +{ 0, 0, 0, 0, 0x0, 0, kD1815_ACTIVE3, 0x01 }, // 14 - LDO9_DSW +{ 5000, 50, 0x14, 0x1f, 0x0, 0, kD1815_ACTIVE3, 0x10 }, // 15 - LCM_LDO1_EN +{ 5000, 50, 0x14, 0x1f, 0x0, 0, kD1815_ACTIVE3, 0x20 }, // 16 - LCM_LDO2_EN +{ 5000, 50, 0x1f, 0x1f, 0x0, 0, kD1815_ACTIVE3, 0x08 }, // 17 - LCM_BOOST_EN +{ 0, 0, 0, 0, 0x0, 0, kD1815_HIBERNATE1, 0x04 }, // 18 - set LDO1_EN in HIB +{ 0, 0, 0, 0, 0x0, 0, kD1815_HIBERNATE1, 0x80 }, // 19 - set LDO6_EN in HIB +}; +#define LDOP ldo_1815 diff --git a/drivers/dialog/pmu/d1881.h b/drivers/dialog/pmu/d1881.h new file mode 100644 index 0000000..139fc24 --- /dev/null +++ b/drivers/dialog/pmu/d1881.h @@ -0,0 +1,800 @@ +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_REG_BANK 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_VIB 1 +#define PMU_HAS_WLED 1 + +enum { + kDIALOG_ADDR_R = 0xe9, + kDIALOG_ADDR_W = 0xe8, + kDIALOG_REG_BYTES = 1, +}; + +enum { + kDIALOG_EVENT_COUNT = 7, + kDIALOG_STATUS_COUNT = 6, + kDIALOG_HIBERNATE_COUNT = 4, + kDIALOG_CHIPID_COUNT = 1, + kDIALOG_FAULTLOG_COUNT = 1, + kDIALOG_GPIO_COUNT = 11, +}; + +#include "dCommon.h" + +enum { + kDIALOG_BANK_COUNT = 2, + kDIALOG_BANK0_SHARED_COUNT = 0x57, +}; + +enum { + kDIALOG_CHIP_ID = 0x00, + + kDIALOG_EVENT_A = 0x01, + kDIALOG_EVENT_B = 0x02, + kDIALOG_EVENT_C = 0x03, + kDIALOG_EVENT_D = 0x04, + kDIALOG_EVENT_E = 0x05, + kDIALOG_EVENT_F = 0x06, + kDIALOG_EVENT_G = 0x07, + + kDIALOG_STATUS_A = 0x08, + kDIALOG_STATUS_B = 0x09, + kDIALOG_STATUS_C = 0x0a, + kDIALOG_STATUS_D = 0x0b, + kDIALOG_STATUS_E = 0x0c, + kDIALOG_STATUS_F = 0x0d, + + kDIALOG_IRQ_MASK_A = 0x0e, + kDIALOG_IRQ_MASK_B = 0x0f, + kDIALOG_IRQ_MASK_C = 0x10, + kDIALOG_IRQ_MASK_D = 0x11, + kDIALOG_IRQ_MASK_E = 0x12, + kDIALOG_IRQ_MASK_F = 0x13, + kDIALOG_IRQ_MASK_G = 0x14, + + kDIALOG_SYS_CONTROL = 0x15, + kDIALOG_SYS_CONTROL2 = 0x16, + + kDIALOG_FAULT_LOG = 0x17, + kDIALOG_BANKSEL = 0x18, + + kD1881_ACTIVE1 = 0x20, + kD1881_ACTIVE2 = 0x21, + kD1881_ACTIVE3 = 0x22, + kDIALOG_LCM_ACTIVE = kD1881_ACTIVE3, + kD1881_ACTIVE4 = 0x23, + kD1881_STANDBY1 = 0x24, + kDIALOG_STANDBY = kD1881_STANDBY1, + kD1881_HIBERNATE1 = 0x25, + kD1881_HIBERNATE2 = 0x26, + kD1881_HIBERNATE3 = 0x27, + kD1881_HIBERNATE4 = 0x28, + + kD1881_BUCK0 = 0x29, + kDIALOG_BUCK0 = kD1881_BUCK0, + kD1881_BUCK1 = 0x2a, + kD1881_BUCK2 = 0x2b, + kDIALOG_BUCK2 = kD1881_BUCK2, + kD1881_BUCK3 = 0x2c, + kD1881_BUCK4 = 0x2d, + + kD1881_LDO1 = 0x2e, + kD1881_LDO2 = 0x2f, + kD1881_LDO3 = 0x30, + kD1881_LDO4 = 0x31, + kD1881_LDO5 = 0x32, + kD1881_LDO6 = 0x33, + kD1881_LDO7 = 0x34, + kD1881_LDO8 = 0x35, + kD1881_LDO9 = 0x36, + kD1881_LDO10 = 0x37, + kD1881_LDO11 = 0x38, + kD1881_LDO12 = 0x39, + + kDIALOG_BUCK_CONTROL1 = 0x3a, + kDIALOG_BUCK_CONTROL2 = 0x3b, + kDIALOG_BUCK_CONTROL3 = 0x3c, + kDIALOG_BUCK_CONTROL4 = 0x3d, + kDIALOG_BUCK_CONTROL_NUM = 4, + + kDIALOG_CHARGE_BUCK_CONTROL = 0x3e, + kDIALOG_CHARGE_CONTROL_A = 0x3f, + kDIALOG_CHARGE_CONTROL_B = 0x40, + kDIALOG_CHARGE_CONTROL_C = 0x41, + kDIALOG_CHARGE_TIME = 0x42, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_HIB = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_TIME = kDIALOG_CHARGE_CONTROL_C, + kDIALOG_CHARGE_CONTROL_EN = kDIALOG_CHARGE_CONTROL_B, + kDIALOG_OTP_ISET_BAT = kDIALOG_CHARGE_CONTROL_A, // not a real OTP register + + kDIALOG_ADC_CONTROL = 0x43, + kDIALOG_ADC_LSB = 0x44, + kDIALOG_ADC_MSB = 0x45, + + kDIALOG_ICHG_AVG = 0x47, + + kDIALOG_TBAT_0 = 0x4a, + kDIALOG_ICHG_TBAT_0 = 0x4b, + kDIALOG_TBAT_1 = 0x4c, + kDIALOG_ICHG_TBAT_1 = 0x4d, + kDIALOG_TBAT_2 = 0x4e, + kDIALOG_ICHG_TBAT_2 = 0x4f, + kDIALOG_TBAT_3 = 0x50, + kDIALOG_ICHG_TBAT_3 = 0x51, + kDIALOG_TBAT_4 = 0x52, + kDIALOG_ICHG_TBAT_4 = 0x53, + kDIALOG_TBAT_MAX = 0x54, + kDIALOG_ICHG_TBAT_NUM = 5, + + kDIALOG_T_OFFSET_MSB = 0x55, + kDIALOG_T_OFFSET_LSB = 0x56, + + kDIALOG_RTC_ALARM_A = 0x57, + kDIALOG_RTC_ALARM_B = 0x58, + kDIALOG_RTC_ALARM_C = 0x59, + kDIALOG_RTC_ALARM_D = 0x5a, + kDIALOG_RTC_CONTROL = 0x5b, + kDIALOG_RTC_TIMEZONE = 0x5c, + kDIALOG_UPCOUNT_A = 0x5d, + kDIALOG_UPCOUNT_B = 0x5e, + kDIALOG_UPCOUNT_C = 0x5f, + kDIALOG_UPCOUNT_D = 0x60, + + kD1881_SYS_GPIO_1 = 0x61, + kDIALOG_SYS_GPIO_REG_START = kD1881_SYS_GPIO_1, + kD1881_SYS_GPIO_2 = 0x62, + kD1881_SYS_GPIO_3 = 0x63, + kD1881_SYS_GPIO_4 = 0x64, + kD1881_SYS_GPIO_5 = 0x65, + kD1881_SYS_GPIO_6 = 0x66, + kD1881_SYS_GPIO_7 = 0x67, + kD1881_SYS_GPIO_8 = 0x68, + kD1881_SYS_GPIO_9 = 0x69, + kD1881_SYS_GPIO_10 = 0x6a, + kD1881_SYS_GPIO_11 = 0x6b, + + kD1881_SYS_GPIO_DEB1 = 0x6c, + kD1881_SYS_GPIO_DEB2 = 0x6d, + kD1881_SYS_GPIO_DEB3 = 0x6e, + kD1881_SYS_GPIO_DEB4 = 0x6f, + kD1881_SYS_GPIO_DEB5 = 0x70, + kD1881_SYS_GPIO_DEB6 = 0x71, + + kDIALOG_LDO_CONTROL = 0x72, + + kDIALOG_WLED_ISET = 0x78, + kDIALOG_WLED_ISET2 = 0x79, + kDIALOG_WLED_CONTROL = 0x7a, + kDIALOG_WLED_CONTROL2 = 0x7b, + kDIALOG_WLED_DWI_CONTROL = kDIALOG_WLED_CONTROL, + kDIALOG_WLED_OPTIONS = kDIALOG_WLED_CONTROL, + + kD1881_LCM_CONTROL1 = 0x7c, + kD1881_LCM_CONTROL2 = 0x7d, + kD1881_LCM_CONTROL3 = 0x7e, + kD1881_LCM_BST_CONTROL = 0x7f, + kDIALOG_LCM_BOOST = kD1881_LCM_BST_CONTROL, + + kDIALOG_VIB_CTRL = 0x80, + kDIALOG_VIB_VSET = 0x81, + + kDIALOG_TDEV1_RISE = 0x82, + kDIALOG_TDEV1_FALL = 0x83, + kDIALOG_TDEV2_RISE = 0x84, + kDIALOG_TDEV2_FALL = 0x85, + kDIALOG_TDEV3_RISE = 0x86, + kDIALOG_TDEV3_FALL = 0x87, + kDIALOG_TDEV4_RISE = 0x88, + kDIALOG_TDEV4_FALL = 0x89, + kDIALOG_TLDO9_RISE = 0x8a, + kDIALOG_TLDO5_RISE = 0x8b, + kDIALOG_TCBUCK_RISE = 0x8c, + kDIALOG_TCHG_RISE = 0x8d, + kDIALOG_TBUCK0_RISE = 0x8e, + kDIALOG_TBUCK2_RISE = 0x8f, + kDIALOG_TBUCK3_RISE = 0x90, + kDIALOG_TBUCK4_RISE = 0x91, + kDIALOG_TISENSE_HYST = 0x92, + + kD1881_BUTTON1 = 0x93, + kD1881_BUTTON2 = 0x94, + kD1881_BUTTON3 = 0x95, + kDIALOG_SYS_CONFIG = 0x96, + + kD1881_BUCK3_HIB = 0x97, + kD1881_BUCK4_HIB = 0x98, + + kD1881_GPIO_SOFTHIB1 = 0x99, + kD1881_GPIO_SOFTHIB2 = 0x9a, + + kDIALOG_BUTTON_DBL = 0x9b, + + kDIALOG_MEMBYTE0 = 0xa0, + kDIALOG_MEMBYTE_LAST = 0xc7, + + // Bank 1 Test Registers + kD1881_TEST_MODE = 0xe0, + + kDIALOG_APP_TMUX = 0x15c, + kDIALOG_BIST_ADC_CTRL = 0x15d, + kDIALOG_BIST_ADC_LSB = 0x15e, + kDIALOG_BIST_ADC_MSB = 0x15f, +}; + +enum { + kD1881_CHIP_ID_MRC_MASK = (0xf << 0), + kD1881_CHIP_ID_MRC_A0 = (0 << 0), + kD1881_CHIP_ID_MRC_A1 = (1 << 0), + kD1881_CHIP_ID_MRC_B1 = (6 << 0), +}; + +enum { + kD1881_EVENT_A_BUTTON1 = (1 << 0), + kD1881_EVENT_A_BUTTON2 = (1 << 1), + kD1881_EVENT_A_BUTTON3 = (1 << 2), + kD1881_EVENT_A_VCENTER_DET = (1 << 3), + kD1881_EVENT_A_FW_DET = (1 << 4), + kD1881_EVENT_A_ACC_DET = (1 << 5), + kD1881_EVENT_A_VBUS_EXT_DET = (1 << 6), + kD1881_EVENT_A_VDD_LOW = (1 << 7), +}; + +// EVENT_B events are assumed volatile (lost over sleep/wake) +enum { + kD1881_EVENT_B_DWI_TO = (1 << 0), + kD1881_EVENT_B_CHG_PRE = (1 << 1), + kD1881_EVENT_B_CHG_FAST = (1 << 2), + kD1881_EVENT_B_CHG_END = (1 << 3), + kD1881_EVENT_B_TBAT = (1 << 4), + kD1881_EVENT_B_EOMC = (1 << 5), + kD1881_EVENT_B_FW_OV = (1 << 6), + kDIALOG_EVENT_B_HIB = (1 << 7), +}; + +enum { + kD1881_EVENT_C_GPIO1 = (1 << 0), + kD1881_EVENT_C_GPIO2 = (1 << 1), + kD1881_EVENT_C_GPIO3 = (1 << 2), + kD1881_EVENT_C_GPIO4 = (1 << 3), + kD1881_EVENT_C_GPIO5 = (1 << 4), + kD1881_EVENT_C_GPIO6 = (1 << 5), + kD1881_EVENT_C_GPIO7 = (1 << 6), + kD1881_EVENT_C_GPIO8 = (1 << 7), +}; + +enum { + kD1881_EVENT_D_GPIO9 = (1 << 0), + kD1881_EVENT_D_GPIO10 = (1 << 1), + kD1881_EVENT_D_GPIO11 = (1 << 2), + kD1881_EVENT_D_BTN1_DBL = (1 << 3), + kD1881_EVENT_D_BTN2_DBL = (1 << 4), + kD1881_EVENT_D_BTN3_DBL = (1 << 5), + kD1881_EVENT_D_CHG_BUCK_FLG = (1 << 6), + kD1881_EVENT_D_VBUS_OV = (1 << 7), +}; + +enum { + kD1881_EVENT_F_ALARM = (1 << 0), + kD1881_EVENT_F_FW_REM = (1 << 4), + kD1881_EVENT_F_VBUS_REM = (1 << 6), +}; + +enum { + kD1881_STATUS_A_BUTTON1 = (1 << 0), + kD1881_STATUS_A_BUTTON2 = (1 << 1), + kD1881_STATUS_A_BUTTON3 = (1 << 2), + kD1881_STATUS_A_VCENTER_DET = (1 << 3), + kD1881_STATUS_A_FW_DET = (1 << 4), + kD1881_STATUS_A_ACC_DET = (1 << 5), + kD1881_STATUS_A_VBUS_EXT_DET = (1 << 6), + kD1881_STATUS_A_VDD_LOW = (1 << 7), +}; + +enum { + kD1881_STATUS_B_CHG_ATT = (1 << 0), + kD1881_STATUS_B_CHG_PRE = (1 << 1), + kD1881_STATUS_B_CHG_FAST = (1 << 2), + kD1881_STATUS_B_CHG_END = (1 << 3), + kD1881_STATUS_B_TBAT = (1 << 4), + kD1881_STATUS_B_CHG_TO = (1 << 5), + kD1881_STATUS_B_FW_OV = (1 << 6), +}; + +enum { + kD1881_STATUS_C_GPIO1 = (1 << 0), + kD1881_STATUS_C_GPIO2 = (1 << 1), + kD1881_STATUS_C_GPIO3 = (1 << 2), + kD1881_STATUS_C_GPIO4 = (1 << 3), + kD1881_STATUS_C_GPIO5 = (1 << 4), + kD1881_STATUS_C_GPIO6 = (1 << 5), + kD1881_STATUS_C_GPIO7 = (1 << 6), + kD1881_STATUS_C_GPIO8 = (1 << 7), +}; + +enum { + kD1881_STATUS_D_GPIO9 = (1 << 0), + kD1881_STATUS_D_GPIO10 = (1 << 1), + kD1881_STATUS_D_GPIO11 = (1 << 2), + kD1881_STATUS_D_PROT_FET_ON = (1 << 3), + kD1881_STATUS_D_CHG_BUCK_FLG = (1 << 6), + kD1881_STATUS_D_VBUS_OV = (1 << 7), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1881_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1881_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(0, kD1881_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS = (kD1881_EVENT_A_BUTTON2 | + kD1881_EVENT_A_BUTTON1 | + kD1881_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(0, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(5, kD1881_EVENT_F_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD1881_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD1881_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VHP_DET_MASK = EVENT_FLAG_MAKE(0, kD1881_STATUS_A_FW_DET), + kDIALOG_EVENT_VBUS_REM_MASK = EVENT_FLAG_MAKE(5, kD1881_EVENT_F_VBUS_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(1, kD1881_EVENT_B_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_B_HIB), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(1, kD1881_EVENT_B_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(1, kD1881_EVENT_B_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(2, kD1881_EVENT_C_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(3, kD1881_EVENT_D_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(3, kD1881_EVENT_D_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(3, kD1881_EVENT_D_GPIO11), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(3, kD1881_EVENT_D_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(3, kD1881_EVENT_D_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(3, kD1881_EVENT_D_BTN3_DBL), + + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO12_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO13_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO14_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO15_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO16_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO17_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD1881_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD1881_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = STATUS_FLAG_MAKE(0, kD1881_STATUS_A_FW_DET), + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD1881_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(1, kD1881_STATUS_B_CHG_PRE | kD1881_STATUS_B_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(1, kD1881_STATUS_B_CHG_TO), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD1881_STATUS_B_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(1, kD1881_STATUS_B_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(1, kD1881_STATUS_B_CHG_ATT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(2 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {kD1881_STATUS_A_FW_DET, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD1881_STATUS_B_CHG_PRE | kD1881_STATUS_B_CHG_FAST, 0, 0, 0, 0}; + +enum { + kD1881_EVENT_A_WAKEMASK = (kD1881_EVENT_A_BUTTON1 | + kD1881_EVENT_A_BUTTON2 | + kD1881_EVENT_A_BUTTON3 | + kD1881_EVENT_A_VBUS_EXT_DET | + kD1881_STATUS_A_FW_DET | + kD1881_EVENT_A_ACC_DET), + kD1881_EVENT_B_WAKEMASK = 0, + kD1881_EVENT_C_WAKEMASK = 0, + kD1881_EVENT_D_WAKEMASK = 0, + kD1881_EVENT_E_WAKEMASK = 0, + kD1881_EVENT_F_WAKEMASK = (kD1881_EVENT_F_ALARM | + kD1881_EVENT_F_FW_REM | + kD1881_EVENT_F_VBUS_REM), + kD1881_EVENT_G_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD1881_EVENT_A_WAKEMASK, + ~kD1881_EVENT_B_WAKEMASK, + ~kD1881_EVENT_C_WAKEMASK, + ~kD1881_EVENT_D_WAKEMASK, + ~kD1881_EVENT_E_WAKEMASK, + ~kD1881_EVENT_F_WAKEMASK, + ~kD1881_EVENT_G_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD1881_EVENT_A_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD1881_EVENT_B_WAKEMASK, + kD1881_EVENT_C_WAKEMASK, + kD1881_EVENT_D_WAKEMASK, + kD1881_EVENT_E_WAKEMASK, + kD1881_EVENT_F_WAKEMASK, + kD1881_EVENT_G_WAKEMASK, +}; + +// All events that defer shutdown +static const eventRegisters kDialogEventRestartMask = { + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_HOLD_BUTTON_MASK, 0) | EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ACC_DET_MASK, 0), + 0, + 0, + 0, + 0, + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ALARM_MASK, 5), + 0, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD1881_EVENT_A_VBUS_EXT_DET | kD1881_EVENT_A_VCENTER_DET | kD1881_EVENT_A_FW_DET, + 0, + 0, + 0, + 0, + kD1881_EVENT_F_FW_REM | kD1881_EVENT_F_VBUS_REM, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD1881_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + kD1881_EVENT_A_FW_DET, + 0, + 0, + 0, + 0, + kD1881_EVENT_F_FW_REM, + 0, +}; + +enum { + kDialogEventPwrsupplyCount = 5, + kDialogEventUSBCount = 1, + kDialogEventFWCount = 2, +}; + +enum { + kDIALOG_LCM_ACTIVE_BOOST_EN = (1 << 1), + kDIALOG_LCM_ACTIVE_MASK = (1 << 2) | (1 << 3) | (1 << 4), +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_SOFT_HIB = (1 << 3), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PRO_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), +}; + +enum { + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_BOOST = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_BUCK_CONTROL_DWI_EN = (1 << 4), + kD1881_BUCK_CONTROL_CONT_MASK = (3 << 0), + kD1881_BUCK_CONTROL_CONT_SLEEP = (0 << 0), + kD1881_BUCK_CONTROL_CONT_AUTO = (1 << 0), + kD1881_BUCK_CONTROL_CONT_SYNC = (2 << 0), + kD1881_BUCK_CONTROL_CONT_PRE_SYNC = (3 << 0), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x03, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300 = 0x17, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 0x21, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x2b, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 0x3f, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 0x3f, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 0x53, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x5d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0xc1, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 70, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 10, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 2620, +}; + + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_A_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_A_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_A_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 30, + kDIALOG_CHARGE_CONTROL_MAX = 1890, +}; + +enum { + kDIALOG_CHARGE_CONTROL_B_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_B_CHG_BUCK_EN = (1 << 7), + + kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_B_CHG_BUCK_EN, + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = kDIALOG_CHARGE_CONTROL_B_ALT_USB_DIS, + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_B_CHG_BUCK_EN, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_IN = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (0xf << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_IN_OFF = (16 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT_OFF= (17 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO9_TEMP = (18 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_TEMP = (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP = (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_LDO9_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP, + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 5), + kDIALOG_ADC_CONTROL_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (0x00 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (0x01 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (0x02 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (0x03 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (0x04 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (0x05 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (0x06 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (0x07 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (0x08 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (0x09 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (0x0a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (0x0b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (0x0c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (0x0d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (0x0e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (0x0f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (0x10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (0x11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (0x12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10 = (0x13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (0x14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11 = (0x15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (0x16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO12 = (0x17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM1 = (0x18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM1 = (0x19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM2 = (0x1a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM2 = (0x1b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM3 = (0x1c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM3 = (0x1d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (0x1e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (0x1f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUF_ON = (0x20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IBUF_ON = (0x21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0 = (0x22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK1 = (0x24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (0x26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (0x28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (0x2a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_LED = (0x2c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBOOST_LCM = (0x2e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (0x30 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (0x32 << 0), + kDIALOG_BIST_ADC_CTRL_AUTO_RUN = (1 << 6), + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_RAMP_EN = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_DWI_EN = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_DITH_EN = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_DITH_RAMP_EN = (1 << 5), + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL_WLED_DITH_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL_WLED_DWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL_WLED_DITH_EN| + kDIALOG_WLED_CONTROL_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS (11) + +enum { + kDIALOG_VIB_CTRL_PWM_EN = (1 << 0), + kDIALOG_VIB_CTRL_BRAKE = (1 << 1), + kDIALOG_VIB_CTRL_PWM_CLK_MASK = (3 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_2MHZ = (0 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_1MHZ = (1 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_500KHZ = (2 << 2), + + kDIALOG_VIB_VSET_MASK = (0x3f << 0), +}; + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD1815_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD1815_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD1815_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD1815_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD1815_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD1815_BUTTON_DBL_BTN3_DBL_EN, +}; + +#define NUM_LDOS 23 +static const struct ldo_params ldo_1881[NUM_LDOS] = { +{ 2500, 50, 0x15, 0x1f, 0x1, kD1881_LDO1, kD1881_ACTIVE1, 0x20 }, // LDO1 +{ 1650, 5, 0x1f, 0x1f, 0x0, kD1881_LDO2, kD1881_ACTIVE1, 0x40 }, // LDO2 +{ 2500, 50, 0x10, 0x1f, 0x0, kD1881_LDO3, kD1881_ACTIVE1, 0x80 }, // LDO3 +{ 1800, 50, 0x1e, 0x1f, 0x0, kD1881_LDO4, kD1881_ACTIVE2, 0x01 }, // LDO4 +{ 2500, 50, 0x16, 0x1f, 0x0, kD1881_LDO5, kD1881_ACTIVE2, 0x02 }, // LDO5 +{ 2500, 50, 0x16, 0x1f, 0x2, kD1881_LDO6, kD1881_ACTIVE2, 0x04 }, // LDO6 +{ 1500, 100,0x16, 0x1f, 0x0, kD1881_LDO7, kD1881_ACTIVE2, 0x08 }, // LDO7 +{ 2000, 50, 0x1f, 0x1f, 0x0, kD1881_LDO8, kD1881_ACTIVE2, 0x10 }, // LDO8 +{ 1200, 100,0x12, 0x1f, 0x0, kD1881_LDO9, kD1881_ACTIVE2, 0x20 }, // LDO9 +{ 2500, 50, 0x15, 0x1f, 0x4, kD1881_LDO10, kD1881_ACTIVE2, 0x40 }, // LDO10 +{ 1700, 50, 0x1a, 0x1f, 0x0, kD1881_LDO11, kD1881_ACTIVE2, 0x80 }, // LDO11 +{ 600, 25, 0x1c, 0x1f, 0x0, kD1881_LDO12, kD1881_ACTIVE3, 0x01 }, // LDO12 +{ 5000, 50, 0x0a, 0x1f, 0x0, kD1881_LCM_CONTROL1, kD1881_ACTIVE3, 0x04 }, // LCM1_LDO +{ 5000, 50, 0x05, 0x1f, 0x0, kD1881_LCM_CONTROL2, kD1881_ACTIVE3, 0x08 }, // LCM2_LDO +{ 5000, 50, 0x00, 0x1f, 0x0, kD1881_LCM_CONTROL3, kD1881_ACTIVE3, 0x10 }, // LCM3_LDO +{ 5000, 50, 0x1f, 0x1f, 0x0, kD1881_LCM_BST_CONTROL, kD1881_ACTIVE3, 0x02 }, // LCM_BOOST +{ 0, 0, 0, 0, 0x0, 0, kD1881_ACTIVE3, 0x20 }, // 17 - WLED_BST_EN +{ 0, 0, 0, 0, 0x0, 0, kD1881_ACTIVE4, 0x10 }, // 18 - DSP_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1881_ACTIVE4, 0x20 }, // 19 - CPU1V2_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1881_ACTIVE4, 0x40 }, // 20 - WDIG_EN +{ 0, 0, 0, 0, 0x0, 0, kD1881_ACTIVE4, 0x80 }, // 21 - CPU1V8_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1881_HIBERNATE1, 0x20 }, // 22 - set LDO1_EN in HIB +{ 0, 0, 0, 0, 0x0, 0, kD1881_HIBERNATE2, 0x04 }, // 23 - set LDO6_EN in HIB +}; +#define LDOP ldo_1881 + diff --git a/drivers/dialog/pmu/d1946.h b/drivers/dialog/pmu/d1946.h new file mode 100644 index 0000000..62d515f --- /dev/null +++ b/drivers/dialog/pmu/d1946.h @@ -0,0 +1,851 @@ +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_REG_BANK 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_WLED 1 + +enum { + kDIALOG_ADDR_R = 0x79, + kDIALOG_ADDR_W = 0x78, + kDIALOG_REG_BYTES = 1, +}; + +enum { + kDIALOG_EVENT_COUNT = 9, + kDIALOG_STATUS_COUNT = 6, + kDIALOG_HIBERNATE_COUNT = 4, + kDIALOG_CHIPID_COUNT = 1, + kDIALOG_FAULTLOG_COUNT = 1, + kDIALOG_GPIO_COUNT = 18, +}; + +#include "dCommon.h" + +enum { + kDIALOG_BANK_COUNT = 3, + kDIALOG_BANK0_SHARED_COUNT = 0x57, +}; + +enum { + kDIALOG_CHIP_ID = 0x00, + + kDIALOG_EVENT_A = 0x01, + kDIALOG_EVENT_B = 0x02, + kDIALOG_EVENT_C = 0x03, + kDIALOG_EVENT_D = 0x04, + kDIALOG_EVENT_E = 0x05, + kDIALOG_EVENT_F = 0x06, + kDIALOG_EVENT_G = 0x07, + kDIALOG_EVENT_H = 0x08, + kDIALOG_EVENT_K = 0x09, + + kDIALOG_STATUS_A = 0x0a, + kDIALOG_STATUS_B = 0x0b, + kDIALOG_STATUS_C = 0x0c, + kDIALOG_STATUS_D = 0x0d, + kDIALOG_STATUS_E = 0x0e, + kDIALOG_STATUS_F = 0x0f, + kDIALOG_STATUS_G = 0x10, + kDIALOG_STATUS_H = 0x11, + + kDIALOG_IRQ_MASK_A = 0x12, + kDIALOG_IRQ_MASK_B = 0x13, + kDIALOG_IRQ_MASK_C = 0x14, + kDIALOG_IRQ_MASK_D = 0x15, + kDIALOG_IRQ_MASK_E = 0x16, + kDIALOG_IRQ_MASK_F = 0x17, + kDIALOG_IRQ_MASK_G = 0x18, + kDIALOG_IRQ_MASK_H = 0x19, + kDIALOG_IRQ_MASK_K = 0x1a, + + kDIALOG_SYS_CONTROL = 0x1b, + kDIALOG_SYS_CONTROL2 = 0x1c, + + kDIALOG_FAULT_LOG = 0x1d, + kDIALOG_BANKSEL = 0x1e, + + kD1946_ACTIVE1 = 0x20, + kD1946_ACTIVE2 = 0x21, + kD1946_ACTIVE3 = 0x22, + kDIALOG_LCM_ACTIVE = kD1946_ACTIVE3, + kD1946_ACTIVE4 = 0x23, + kD1946_STANDBY1 = 0x24, + kDIALOG_STANDBY = kD1946_STANDBY1, + kD1946_HIBERNATE1 = 0x25, + kD1946_HIBERNATE2 = 0x26, + kD1946_HIBERNATE3 = 0x27, + kD1946_HIBERNATE4 = 0x28, + + kD1946_BUCK0 = 0x29, + kDIALOG_BUCK0 = kD1946_BUCK0, + kD1946_BUCK1 = 0x2a, + kD1946_BUCK2 = 0x2b, + kDIALOG_BUCK2 = kD1946_BUCK2, + kD1946_BUCK3 = 0x2c, + kD1946_BUCK4 = 0x2d, + kD1946_BUCK5 = 0x2e, + + kD1946_LDO1 = 0x2f, + kD1946_LDO2 = 0x30, + kD1946_LDO3 = 0x31, + kD1946_LDO4 = 0x32, + kD1946_LDO5 = 0x33, + kD1946_LDO6 = 0x34, + kD1946_LDO7 = 0x35, + kD1946_LDO8 = 0x36, + kD1946_LDO9 = 0x37, + kD1946_LDO10 = 0x38, + kD1946_LDO11 = 0x39, + kD1946_LDO12 = 0x3a, + + kDIALOG_BUCK_DWI = 0x3b, + + kDIALOG_CHARGE_BUCK_CONTROL = 0x3d, + kDIALOG_CHARGE_BUCK_CONTROL_B = 0x3e, + + kDIALOG_CHARGE_CONTROL_A = 0x3f, + kDIALOG_CHARGE_CONTROL_B = 0x40, + kDIALOG_CHARGE_CONTROL_C = 0x41, + kDIALOG_CHARGE_TIME = 0x42, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_HIB = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_TIME = kDIALOG_CHARGE_CONTROL_C, + kDIALOG_CHARGE_CONTROL_EN = kDIALOG_CHARGE_CONTROL_B, + kDIALOG_OTP_ISET_BAT = kDIALOG_CHARGE_CONTROL_A, // not a real OTP register + + kDIALOG_ADC_CONTROL = 0x43, + kDIALOG_ADC_LSB = 0x44, + kDIALOG_ADC_MSB = 0x45, + + kDIALOG_ICHG_AVG = 0x47, + + kDIALOG_TBAT_0 = 0x4a, + kDIALOG_ICHG_TBAT_0 = 0x4b, + kDIALOG_TBAT_1 = 0x4c, + kDIALOG_ICHG_TBAT_1 = 0x4d, + kDIALOG_TBAT_2 = 0x4e, + kDIALOG_ICHG_TBAT_2 = 0x4f, + kDIALOG_TBAT_3 = 0x50, + kDIALOG_ICHG_TBAT_3 = 0x51, + kDIALOG_TBAT_4 = 0x52, + kDIALOG_ICHG_TBAT_4 = 0x53, + kDIALOG_TBAT_MAX = 0x54, + kDIALOG_ICHG_TBAT_NUM = 5, + + kDIALOG_T_OFFSET_MSB = 0x55, + kDIALOG_T_OFFSET_LSB = 0x56, + + kDIALOG_RTC_ALARM_A = 0x57, + kDIALOG_RTC_ALARM_B = 0x58, + kDIALOG_RTC_ALARM_C = 0x59, + kDIALOG_RTC_ALARM_D = 0x5a, + kDIALOG_RTC_CONTROL = 0x5b, + kDIALOG_RTC_TIMEZONE = 0x5c, + kDIALOG_UPCOUNT_A = 0x5d, + kDIALOG_UPCOUNT_B = 0x5e, + kDIALOG_UPCOUNT_C = 0x5f, + kDIALOG_UPCOUNT_D = 0x60, + + kD1946_SYS_GPIO_1 = 0x61, + kDIALOG_SYS_GPIO_REG_START = kD1946_SYS_GPIO_1, + kD1946_SYS_GPIO_2 = 0x62, + kD1946_SYS_GPIO_3 = 0x63, + kD1946_SYS_GPIO_4 = 0x64, + kD1946_SYS_GPIO_5 = 0x65, + kD1946_SYS_GPIO_6 = 0x66, + kD1946_SYS_GPIO_7 = 0x67, + kD1946_SYS_GPIO_8 = 0x68, + kD1946_SYS_GPIO_9 = 0x69, + kD1946_SYS_GPIO_10 = 0x6a, + kD1946_SYS_GPIO_11 = 0x6b, + kD1946_SYS_GPIO_12 = 0x6c, + kD1946_SYS_GPIO_13 = 0x6d, + kD1946_SYS_GPIO_14 = 0x6e, + kD1946_SYS_GPIO_15 = 0x6f, + kD1946_SYS_GPIO_16 = 0x70, + kD1946_SYS_GPIO_17 = 0x71, + kD1946_SYS_GPIO_18 = 0x72, + + kD1946_SYS_GPIO_DEB1 = 0x73, + kD1946_SYS_GPIO_DEB2 = 0x74, + kD1946_SYS_GPIO_DEB3 = 0x75, + kD1946_SYS_GPIO_DEB4 = 0x76, + kD1946_SYS_GPIO_DEB5 = 0x77, + kD1946_SYS_GPIO_DEB6 = 0x78, + kD1946_SYS_GPIO_DEB7 = 0x79, + kD1946_SYS_GPIO_DEB8 = 0x7a, + kD1946_SYS_GPIO_DEB9 = 0x7b, + + kDIALOG_LDO_CONTROL = 0x7c, + + kD1946_BUTTON1 = 0x7d, + kD1946_BUTTON2 = 0x7e, + kD1946_BUTTON3 = 0x7f, + kDIALOG_SYS_CONFIG = 0x80, + + kD1946_LCM_CONTROL1 = 0x81, + kD1946_LCM_CONTROL2 = 0x82, + kD1946_LCM_CONTROL3 = 0x83, + kD1946_LCM_BST_CONTROL = 0x84, + kDIALOG_LCM_BOOST = kD1946_LCM_BST_CONTROL, + + kD1946_BUCK3_HIB = 0x9a, + kD1946_BUCK4_HIB = 0x9b, + kD1946_GPIO_SOFTHIB1 = 0x9c, + kD1946_GPIO_SOFTHIB2 = 0x9d, + kD1946_GPIO_SOFTHIB3 = 0x9e, + kDIALOG_BUTTON_DBL = 0x9f, + + kDIALOG_MEMBYTE0 = 0xa0, + kDIALOG_MEMBYTE_LAST = 0xc7, + + kDIALOG_WLED_ISET = 0xd0, + kDIALOG_WLED_ISET2 = 0xd1, + kDIALOG_WLED_CONTROL = 0xd2, + kDIALOG_WLED_CONTROL2 = 0xd3, + kDIALOG_WLED_DWI_CONTROL = kDIALOG_WLED_CONTROL2, + kDIALOG_WLED_OPTIONS = kDIALOG_WLED_CONTROL2, + + // Bank 1 Test Registers + kD1946_WLED_CONTROL5 = 0xa5, + kD1946_BUCK_CONTROL1 = 0xab, + kD1946_BUCK_CONTROL3 = 0xad, + + // Bank 2 Test Registers + kD1946_TEST_MODE = 0xd0, + + kDIALOG_APP_TMUX = 0x15c, + kDIALOG_BIST_ADC_CTRL = 0x15d, + kDIALOG_BIST_ADC_LSB = 0x15e, + kDIALOG_BIST_ADC_MSB = 0x15f, +}; + +enum { + kD1946_CHIP_ID_MRC_MASK = (0xf << 0), + kD1946_CHIP_ID_MRC_A0 = (0 << 0), + kD1946_CHIP_ID_MRC_A1 = (1 << 0), +}; + +enum { + kD1946_EVENT_A_BUTTON1 = (1 << 0), + kD1946_EVENT_A_BUTTON2 = (1 << 1), + kD1946_EVENT_A_BUTTON3 = (1 << 2), + kD1946_EVENT_A_VCENTER_DET = (1 << 3), + kD1946_EVENT_A_FW_DET = (1 << 4), + kD1946_EVENT_A_ACC_DET = (1 << 5), + kD1946_EVENT_A_VBUS_EXT_DET = (1 << 6), + kD1946_EVENT_A_VDD_LOW = (1 << 7), +}; + +// EVENT_B events are assumed volatile (lost over sleep/wake) +enum { + kD1946_EVENT_B_DWI_TO = (1 << 0), + kD1946_EVENT_B_CHG_PRE = (1 << 1), + kD1946_EVENT_B_CHG_FAST = (1 << 2), + kD1946_EVENT_B_CHG_END = (1 << 3), + kD1946_EVENT_B_TBAT = (1 << 4), + kD1946_EVENT_B_EOMC = (1 << 5), + kD1946_EVENT_B_FW_OV = (1 << 6), + kDIALOG_EVENT_B_HIB = (1 << 7), +}; + +enum { + kD1946_EVENT_C_GPIO1 = (1 << 0), + kD1946_EVENT_C_GPIO2 = (1 << 1), + kD1946_EVENT_C_GPIO3 = (1 << 2), + kD1946_EVENT_C_GPIO4 = (1 << 3), + kD1946_EVENT_C_GPIO5 = (1 << 4), + kD1946_EVENT_C_GPIO6 = (1 << 5), + kD1946_EVENT_C_GPIO7 = (1 << 6), + kD1946_EVENT_C_GPIO8 = (1 << 7), +}; + +enum { + kD1946_EVENT_D_GPIO9 = (1 << 0), + kD1946_EVENT_D_GPIO10 = (1 << 1), + kD1946_EVENT_D_GPIO11 = (1 << 2), + kD1946_EVENT_D_GPIO12 = (1 << 3), + kD1946_EVENT_D_GPIO13 = (1 << 4), + kD1946_EVENT_D_GPIO14 = (1 << 5), + kD1946_EVENT_D_GPIO15 = (1 << 6), + kD1946_EVENT_D_GPIO16 = (1 << 7), +}; + +enum { + kD1946_EVENT_E_GPIO17 = (1 << 0), + kD1946_EVENT_E_GPIO18 = (1 << 1), + kD1946_EVENT_E_ACC_B_DET = (1 << 2), + kD1946_EVENT_E_BTN1_DBL = (1 << 3), + kD1946_EVENT_E_BTN2_DBL = (1 << 4), + kD1946_EVENT_E_BTN3_DBL = (1 << 5), + kD1946_EVENT_E_CHG_BUCK_FLG = (1 << 6), + kD1946_EVENT_E_VBUS_OV = (1 << 7), +}; + +enum { + kD1946_EVENT_G_ALARM = (1 << 0), + kD1946_EVENT_G_FW_REM = (1 << 4), + kD1946_EVENT_G_VBUS_REM = (1 << 6), +}; + +enum { + kD1946_EVENT_K_VBUS_B_DET = (1 << 3), + kD1946_EVENT_K_CHG_BUCK_B_FLG = (1 << 5), + kD1946_EVENT_K_VBUS_B_EXT = (1 << 6), + kD1946_EVENT_K_VBUS_B_REM = (1 << 7), +}; + +enum { + kD1946_STATUS_A_BUTTON1 = (1 << 0), + kD1946_STATUS_A_BUTTON2 = (1 << 1), + kD1946_STATUS_A_BUTTON3 = (1 << 2), + kD1946_STATUS_A_VCENTER_DET = (1 << 3), + kD1946_STATUS_A_FW_DET = (1 << 4), + kD1946_STATUS_A_ACC_DET = (1 << 5), + kD1946_STATUS_A_VBUS_EXT_DET = (1 << 6), + kD1946_STATUS_A_VDD_LOW = (1 << 7), +}; + +enum { + kD1946_STATUS_B_CHG_ATT = (1 << 0), + kD1946_STATUS_B_CHG_PRE = (1 << 1), + kD1946_STATUS_B_CHG_FAST = (1 << 2), + kD1946_STATUS_B_CHG_END = (1 << 3), + kD1946_STATUS_B_TBAT = (1 << 4), + kD1946_STATUS_B_CHG_TO = (1 << 5), + kD1946_STATUS_B_FW_OV = (1 << 6), +}; + +enum { + kD1946_STATUS_C_GPIO1 = (1 << 0), + kD1946_STATUS_C_GPIO2 = (1 << 1), + kD1946_STATUS_C_GPIO3 = (1 << 2), + kD1946_STATUS_C_GPIO4 = (1 << 3), + kD1946_STATUS_C_GPIO5 = (1 << 4), + kD1946_STATUS_C_GPIO6 = (1 << 5), + kD1946_STATUS_C_GPIO7 = (1 << 6), + kD1946_STATUS_C_GPIO8 = (1 << 7), +}; + +enum { + kD1946_STATUS_D_GPIO9 = (1 << 0), + kD1946_STATUS_D_GPIO10 = (1 << 1), + kD1946_STATUS_D_GPIO11 = (1 << 2), + kD1946_STATUS_D_GPIO12 = (1 << 3), + kD1946_STATUS_D_GPIO13 = (1 << 4), + kD1946_STATUS_D_GPIO14 = (1 << 5), + kD1946_STATUS_D_GPIO15 = (1 << 6), + kD1946_STATUS_D_GPIO16 = (1 << 7), +}; + +enum { + kD1946_STATUS_E_GPIO17 = (1 << 0), + kD1946_STATUS_E_GPIO18 = (1 << 1), + kD1946_STATUS_E_ACC_B_DET = (1 << 2), + kD1946_STATUS_E_PROT_FET_ON = (1 << 3), + kD1946_STATUS_E_PROT_FET_B_ON = (1 << 5), + kD1946_STATUS_E_CHG_BUCK_FLG = (1 << 6), + kD1946_STATUS_E_VBUS_OV = (1 << 7), +}; + +enum { + kD1946_STATUS_H_CHG_B_ATT = (1 << 0), + kD1946_STATUS_H_VBUS_B_OV = (1 << 1), + kD1946_STATUS_H_VCENTER_B_DET = (1 << 3), + kD1946_STATUS_H_CHG_BUCK_B_FLG = (1 << 5), + kD1946_STATUS_H_VBUS_B_EXT_DET = (1 << 6), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1946_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1946_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(0, kD1946_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS = (kD1946_EVENT_A_BUTTON2 | + kD1946_EVENT_A_BUTTON1 | + kD1946_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(0, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(6, kD1946_EVENT_G_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD1946_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD1946_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VHP_DET_MASK = EVENT_FLAG_MAKE(0, kD1946_STATUS_A_FW_DET), + kDIALOG_EVENT_VBUS_REM_MASK = EVENT_FLAG_MAKE(6, kD1946_EVENT_G_VBUS_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(1, kD1946_EVENT_B_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_B_HIB), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(1, kD1946_EVENT_B_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(1, kD1946_EVENT_B_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(2, kD1946_EVENT_C_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(3, kD1946_EVENT_D_GPIO16), + kDIALOG_EVENT_GPIO17_MASK = EVENT_FLAG_MAKE(4, kD1946_EVENT_E_GPIO17), + kDIALOG_EVENT_GPIO18_MASK = EVENT_FLAG_MAKE(4, kD1946_EVENT_E_GPIO18), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(4, kD1946_EVENT_E_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(4, kD1946_EVENT_E_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(4, kD1946_EVENT_E_BTN3_DBL), + + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD1946_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD1946_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = STATUS_FLAG_MAKE(0, kD1946_STATUS_A_FW_DET), + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD1946_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(1, kD1946_STATUS_B_CHG_PRE | kD1946_STATUS_B_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(1, kD1946_STATUS_B_CHG_TO), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD1946_STATUS_B_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(1, kD1946_STATUS_B_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(1, kD1946_STATUS_B_CHG_ATT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(2 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {kD1946_STATUS_A_FW_DET, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD1946_STATUS_B_CHG_PRE | kD1946_STATUS_B_CHG_FAST, 0, 0, 0, 0}; + +enum { + kD1946_EVENT_A_WAKEMASK = (kD1946_EVENT_A_BUTTON1 | + kD1946_EVENT_A_BUTTON2 | + kD1946_EVENT_A_BUTTON3 | + kD1946_EVENT_A_VBUS_EXT_DET | + kD1946_STATUS_A_FW_DET | + kD1946_EVENT_A_ACC_DET), + kD1946_EVENT_B_WAKEMASK = 0, + kD1946_EVENT_C_WAKEMASK = 0, + kD1946_EVENT_D_WAKEMASK = 0, + kD1946_EVENT_E_WAKEMASK = 0, + kD1946_EVENT_F_WAKEMASK = 0, + kD1946_EVENT_G_WAKEMASK = (kD1946_EVENT_G_ALARM | + kD1946_EVENT_G_FW_REM | + kD1946_EVENT_G_VBUS_REM), + kD1946_EVENT_H_WAKEMASK = 0, + kD1946_EVENT_K_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD1946_EVENT_A_WAKEMASK, + ~kD1946_EVENT_B_WAKEMASK, + ~kD1946_EVENT_C_WAKEMASK, + ~kD1946_EVENT_D_WAKEMASK, + ~kD1946_EVENT_E_WAKEMASK, + ~kD1946_EVENT_F_WAKEMASK, + ~kD1946_EVENT_G_WAKEMASK, + ~kD1946_EVENT_H_WAKEMASK, + ~kD1946_EVENT_K_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD1946_EVENT_A_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD1946_EVENT_B_WAKEMASK, + kD1946_EVENT_C_WAKEMASK, + kD1946_EVENT_D_WAKEMASK, + kD1946_EVENT_E_WAKEMASK, + kD1946_EVENT_F_WAKEMASK, + kD1946_EVENT_G_WAKEMASK, + kD1946_EVENT_H_WAKEMASK, + kD1946_EVENT_K_WAKEMASK, +}; + +// All events that defer shutdown +static const eventRegisters kDialogEventRestartMask = { + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_HOLD_BUTTON_MASK, 0) | EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ACC_DET_MASK, 0), + 0, + 0, + 0, + 0, + 0, + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ALARM_MASK, 6), + 0, + 0, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD1946_EVENT_A_VBUS_EXT_DET | kD1946_EVENT_A_FW_DET | kD1946_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + kD1946_EVENT_G_FW_REM | kD1946_EVENT_G_VBUS_REM, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD1946_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + kD1946_EVENT_A_FW_DET, + 0, + 0, + 0, + 0, + 0, + kD1946_EVENT_G_FW_REM, + 0, + 0, +}; + +// XXXKW +enum { + kDialogEventPwrsupplyCount = 5, + kDialogEventUSBCount = 1, + kDialogEventFWCount = 2, +}; + +enum { + kDIALOG_LCM_ACTIVE_BOOST_EN = (1 << 1), + kDIALOG_LCM_ACTIVE_MASK = (1 << 2) | (1 << 3) | (1 << 4), +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_SOFT_HIB = (1 << 3), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PRO_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), + kDIALOG_SYS_CONTROL2_BAT_PWR_SUSPEND = (1 << 7), +}; + +enum { + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_BOOST = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_BUCK_DWI_BUCK0 = (1 << 0), + kDIALOG_BUCK_DWI_BUCK1 = (1 << 1), + kDIALOG_BUCK_DWI_BUCK2 = (1 << 2), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x02, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300 = 0x12, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 0x1a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x22, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 0x2a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 0x32, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 0x42, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_975 = 0x48, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x4a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1450 = 0x6e, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500 = 0x72, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0x9a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100 = 0xa2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 75, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 8, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 3262, +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_A_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_A_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_A_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 40, + kDIALOG_CHARGE_CONTROL_MAX = 2520, +}; + +enum { + kDIALOG_CHARGE_CONTROL_B_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_B_CHG_BUCK_EN = (1 << 7), + + kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_B_CHG_BUCK_EN, + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = kDIALOG_CHARGE_CONTROL_B_ALT_USB_DIS, + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_B_CHG_BUCK_EN, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_IN = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS_A = (15 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = kDIALOG_ADC_CONTROL_MUX_SEL_VBUS_A, + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_IN_OFF = (16 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT_OFF= (17 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK5_TEMP = (18 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO9_TEMP = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_B_TEMP= (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP = (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP= (26 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS_B = (27 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK5_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP, + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 5), + kDIALOG_ADC_CONTROL_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (0x00 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (0x01 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (0x02 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (0x03 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (0x04 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (0x05 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (0x06 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (0x07 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (0x08 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (0x09 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (0x0a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (0x0b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (0x0c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (0x0d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (0x0e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (0x0f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (0x10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (0x11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (0x12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10 = (0x13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (0x14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11 = (0x15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (0x16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO12 = (0x17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM1 = (0x18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM1 = (0x19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM2 = (0x1a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM2 = (0x1b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM3 = (0x1c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM3 = (0x1d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (0x1e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (0x1f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUF_ON = (0x20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IBUF_ON = (0x21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0 = (0x22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK1 = (0x24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (0x26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (0x28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (0x2a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_LED = (0x2c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBOOST_LCM = (0x2e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (0x30 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (0x32 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK5 = (0x34 << 0), + kDIALOG_BIST_ADC_CTRL_AUTO_RUN = (1 << 6), + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_ENABLE3 = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_ENABLE4 = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_ENABLE5 = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_ENABLE6 = (1 << 5), +}; + +enum { + kDIALOG_WLED_CONTROL2_WLED_RAMP_EN = (1 << 2), + kDIALOG_WLED_CONTROL2_WLED_DWI_EN = (1 << 3), + kDIALOG_WLED_CONTROL2_WLED_DITH_EN = (1 << 4), + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN = (1 << 5), + + kDIALOG_WLED_CONTROL_WLED_DWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL2_WLED_DITH_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS (11) + +#define NUM_LDOS 23 +static const struct ldo_params ldo_1946[NUM_LDOS] = { +{ 2500, 50, 0x0a, 0x1f, 0x1, kD1946_LDO1, kD1946_ACTIVE1, 0x20 }, // LDO1 +{ 1650, 5, 0x0a, 0x1f, 0x0, kD1946_LDO2, kD1946_ACTIVE1, 0x40 }, // LDO2 +{ 2500, 50, 0x0a, 0x1f, 0x0, kD1946_LDO3, kD1946_ACTIVE1, 0x80 }, // LDO3 +{ 1800, 50, 0x18, 0x1f, 0x0, kD1946_LDO4, kD1946_ACTIVE2, 0x01 }, // LDO4 +{ 2500, 50, 0x0a, 0x1f, 0x0, kD1946_LDO5, kD1946_ACTIVE2, 0x02 }, // LDO5 +{ 2500, 50, 0x10, 0x1f, 0x2, kD1946_LDO6, kD1946_ACTIVE2, 0x04 }, // LDO6 +{ 1500, 100,0x0a, 0x1f, 0x0, kD1946_LDO7, kD1946_ACTIVE2, 0x08 }, // LDO7 +{ 2000, 50, 0x16, 0x1f, 0x0, kD1946_LDO8, kD1946_ACTIVE2, 0x10 }, // LDO8 +{ 1200, 100,0x00, 0x1f, 0x0, kD1946_LDO9, kD1946_ACTIVE2, 0x20 }, // LDO9 +{ 2500, 50, 0x0a, 0x1f, 0x4, kD1946_LDO10, kD1946_ACTIVE2, 0x40 }, // LDO10 +{ 1700, 50, 0x17, 0x1f, 0x0, kD1946_LDO11, kD1946_ACTIVE2, 0x80 }, // LDO11 +{ 600, 25, 0x14, 0x1f, 0x0, kD1946_LDO12, kD1946_ACTIVE3, 0x01 }, // LDO12 +{ 5000, 50, 0x0c, 0x1f, 0x0, kD1946_LCM_CONTROL1, kD1946_ACTIVE3, 0x04 }, // LCM1_LDO +{ 5000, 50, 0x05, 0x1f, 0x0, kD1946_LCM_CONTROL2, kD1946_ACTIVE3, 0x08 }, // LCM2_LDO +{ 5000, 50, 0x00, 0x1f, 0x0, kD1946_LCM_CONTROL3, kD1946_ACTIVE3, 0x10 }, // LCM3_LDO +{ 5000, 50, 0x1f, 0x1f, 0x0, kD1946_LCM_BST_CONTROL, kD1946_ACTIVE3, 0x02 }, // LCM_BOOST +{ 0, 0, 0, 0, 0x0, 0, kD1946_ACTIVE3, 0x20 }, // 17 - WLED_BST_EN +{ 0, 0, 0, 0, 0x0, 0, kD1946_ACTIVE4, 0x10 }, // 18 - DSP_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1946_ACTIVE4, 0x20 }, // 19 - CPU1V2_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1946_ACTIVE4, 0x40 }, // 20 - WDIG_EN +{ 0, 0, 0, 0, 0x0, 0, kD1946_ACTIVE4, 0x80 }, // 21 - CPU1V8_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1946_HIBERNATE1, 0x20 }, // 22 - set LDO1_EN in HIB +{ 0, 0, 0, 0, 0x0, 0, kD1946_HIBERNATE2, 0x04 }, // 23 - set LDO6_EN in HIB +}; +#define LDOP ldo_1946 + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD1946_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD1946_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD1946_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD1946_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD1946_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD1946_BUTTON_DBL_BTN3_DBL_EN, +}; diff --git a/drivers/dialog/pmu/d1972.h b/drivers/dialog/pmu/d1972.h new file mode 100644 index 0000000..79b7134 --- /dev/null +++ b/drivers/dialog/pmu/d1972.h @@ -0,0 +1,913 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D1972_H +#define __DIALOG_D1972_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_REG_BANK 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_VIB 1 +#define PMU_HAS_WLED 1 + +enum { + kDIALOG_ADDR_R = 0xe9, + kDIALOG_ADDR_W = 0xe8, + kDIALOG_REG_BYTES = 1, +}; + +enum { + kDIALOG_EVENT_COUNT = 9, + kDIALOG_STATUS_COUNT = 8, + kDIALOG_HIBERNATE_COUNT = 4, + kDIALOG_CHIPID_COUNT = 1, + kDIALOG_FAULTLOG_COUNT = 1, + kDIALOG_GPIO_COUNT = 12, +}; + +#include "dCommon.h" + +enum { + kDIALOG_BANK_COUNT = 2, + kDIALOG_BANK0_SHARED_COUNT = 0x5e, +}; + +enum { + // Bank 0 registers + kDIALOG_CHIP_ID = 0x00, + + kDIALOG_EVENT_A = 0x01, + kDIALOG_EVENT_B = 0x02, + kDIALOG_EVENT_C = 0x03, + kDIALOG_EVENT_D = 0x04, + kDIALOG_EVENT_E = 0x05, + kDIALOG_EVENT_F = 0x06, + kDIALOG_EVENT_G = 0x07, + kDIALOG_EVENT_H = 0x08, + kDIALOG_EVENT_I = 0x09, + + kDIALOG_STATUS_A = 0x0a, + kDIALOG_STATUS_B = 0x0b, + kDIALOG_STATUS_C = 0x0c, + kDIALOG_STATUS_D = 0x0d, + kDIALOG_STATUS_E = 0x0e, + kDIALOG_STATUS_F = 0x0f, + kDIALOG_STATUS_G = 0x10, + kDIALOG_STATUS_H = 0x11, + kDIALOG_STATUS_GPIO_1_8 = kDIALOG_STATUS_C, + kDIALOG_STATUS_GPIO_9_16 = kDIALOG_STATUS_D, + kDIALOG_STATUS_GPIO_17_24 = 0, + + kDIALOG_IRQ_MASK_A = 0x12, + kDIALOG_IRQ_MASK_B = 0x13, + kDIALOG_IRQ_MASK_C = 0x14, + kDIALOG_IRQ_MASK_D = 0x15, + kDIALOG_IRQ_MASK_E = 0x16, + kDIALOG_IRQ_MASK_F = 0x17, + kDIALOG_IRQ_MASK_G = 0x18, + kDIALOG_IRQ_MASK_H = 0x19, + kDIALOG_IRQ_MASK_I = 0x1a, + + kDIALOG_SYS_CONTROL = 0x1b, + kDIALOG_SYS_CONTROL2 = 0x1c, + + kDIALOG_FAULT_LOG = 0x1d, + kDIALOG_BANKSEL = 0x1e, + + kD1972_ACTIVE1 = 0x20, + kD1972_ACTIVE2 = 0x21, + kD1972_ACTIVE3 = 0x22, + kDIALOG_LCM_ACTIVE = kD1972_ACTIVE3, + kD1972_ACTIVE4 = 0x23, + kD1972_STANDBY = 0x24, + kDIALOG_STANDBY = kD1972_STANDBY, + kD1972_HIBERNATE1 = 0x25, + kD1972_HIBERNATE2 = 0x26, + kD1972_HIBERNATE3 = 0x27, + kD1972_HIBERNATE4 = 0x28, + + kD1972_BUCK0 = 0x29, + kDIALOG_BUCK0 = kD1972_BUCK0, + kD1972_BUCK2 = 0x2a, + kDIALOG_BUCK2 = kD1972_BUCK2, + kD1972_BUCK3 = 0x2b, + kD1972_BUCK4 = 0x2c, + + kD1972_LDO1 = 0x2d, + kD1972_LDO2 = 0x2e, + kD1972_LDO3 = 0x2f, + kD1972_LDO4 = 0x30, + kD1972_LDO5 = 0x31, + kD1972_LDO6 = 0x32, + kD1972_LDO7 = 0x33, + kD1972_LDO8 = 0x34, + kD1972_LDO9 = 0x35, + kD1972_LDO10 = 0x36, + kD1972_LDO11 = 0x37, + kD1972_LDO12 = 0x38, + kD1972_LDO16 = 0x39, + + kD1972_BUCK_CTRL1 = 0x3a, + kD1972_BUCK_CTRL2 = 0x3b, + kD1972_BUCK_CTRL3 = 0x3c, + kD1972_BUCK_CTRL4 = 0x3d, + kD1972_BUCK_CTRL5 = 0x3e, + + kDIALOG_CHARGE_BUCK_CONTROL = 0x3f, + kDIALOG_CHARGE_BUCK_CONTROL_B = 0x40, + kDIALOG_CHARGE_BUCK_STATUS = 0x41, + kDIALOG_CHARGE_CONTROL_A = 0x42, + kDIALOG_CHARGE_CONTROL_B = 0x43, + kDIALOG_CHARGE_CONTROL_C = 0x44, + kDIALOG_CHARGE_STATUS = 0x45, + kDIALOG_CHARGE_CONTROL_D = 0x46, + kDIALOG_CHARGE_TIME = 0x47, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kDIALOG_CHARGE_CONTROL_B, + kDIALOG_CHARGE_CONTROL_HIB = kDIALOG_CHARGE_CONTROL_B, + kDIALOG_CHARGE_CONTROL_TIME = kDIALOG_CHARGE_CONTROL_D, + kDIALOG_CHARGE_CONTROL_EN = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_OTP_ISET_BAT = kDIALOG_CHARGE_CONTROL_B, + + kDIALOG_ADC_CONTROL = 0x48, + kDIALOG_ADC_LSB = 0x49, + kDIALOG_ADC_MSB = 0x4a, + kDIALOG_ADC_TEMP_CTRL = 0x4b, + + kDIALOG_ICHG_AVG = 0x4c, + kDIALOG_VCC_MAIN_MON = 0x4d, + kDIALOG_ICHG_END = 0x4e, + + kDIALOG_TBAT_0 = 0x4f, + kDIALOG_ICHG_TBAT_0 = 0x50, + kDIALOG_TBAT_1 = 0x51, + kDIALOG_ICHG_TBAT_1 = 0x52, + kDIALOG_TBAT_2 = 0x53, + kDIALOG_ICHG_TBAT_2 = 0x54, + kDIALOG_TBAT_3 = 0x55, + kDIALOG_ICHG_TBAT_3 = 0x56, + kDIALOG_TBAT_4 = 0x57, + kDIALOG_ICHG_TBAT_4 = 0x58, + kDIALOG_TBAT_MAX = 0x59, + kDIALOG_ICHG_TBAT_NUM = 5, + + kDIALOG_T_OFFSET_MSB = 0x5A, + kDIALOG_T_OFFSET_LSB = 0x5B, + kD1972_IBUSCAL1 = 0x5c, + kD1972_IBUSCAL2 = 0x5d, + + kDIALOG_RTC_ALARM_A = 0x5e, + kDIALOG_RTC_ALARM_B = 0x5f, + kDIALOG_RTC_ALARM_C = 0x60, + kDIALOG_RTC_ALARM_D = 0x61, + kDIALOG_RTC_CONTROL = 0x62, + kDIALOG_RTC_TIMEZONE = 0x63, + kDIALOG_UPCOUNT_A = 0x64, + kDIALOG_UPCOUNT_B = 0x65, + kDIALOG_UPCOUNT_C = 0x66, + kDIALOG_UPCOUNT_D = 0x67, + + kD1972_SYS_GPIO_1 = 0x68, + kDIALOG_SYS_GPIO_REG_START = kD1972_SYS_GPIO_1, + kD1972_SYS_GPIO_2 = 0x69, + kD1972_SYS_GPIO_3 = 0x6a, + kD1972_SYS_GPIO_4 = 0x6b, + kD1972_SYS_GPIO_5 = 0x6c, + kD1972_SYS_GPIO_6 = 0x6d, + kD1972_SYS_GPIO_7 = 0x6e, + kD1972_SYS_GPIO_8 = 0x6f, + kD1972_SYS_GPIO_9 = 0x70, + kD1972_SYS_GPIO_10 = 0x71, + kD1972_SYS_GPIO_11 = 0x72, + kD1972_SYS_GPIO_12 = 0x73, + + kD1972_SYS_GPIO_DEB1 = 0x74, + kD1972_SYS_GPIO_DEB2 = 0x75, + kD1972_SYS_GPIO_DEB3 = 0x76, + kD1972_SYS_GPIO_DEB4 = 0x77, + kD1972_SYS_GPIO_DEB5 = 0x78, + kD1972_SYS_GPIO_DEB6 = 0x79, + + kDIALOG_LDO_CONTROL = 0x7a, + + kDIALOG_WLED_ISET = 0x7b, + kDIALOG_WLED_ISET2 = 0x7c, + kDIALOG_WLED_CONTROL = 0x7d, + kDIALOG_WLED_CONTROL2 = 0x7e, + kDIALOG_WLED_DWI_CONTROL = kDIALOG_WLED_CONTROL, + kDIALOG_WLED_OPTIONS = kDIALOG_WLED_CONTROL, + + kD1972_LCM_CONTROL1 = 0x7f, + kD1972_LCM_CONTROL2 = 0x80, + kD1972_LCM_CONTROL3 = 0x81, + kD1972_LCM_BST_CONTROL = 0x82, + kDIALOG_LCM_BOOST = kD1972_LCM_BST_CONTROL, + + kDIALOG_VIB_CTRL = 0x83, + kDIALOG_VIB_VSET = 0x84, + + kD1972_TDEV1_RISE = 0x85, + kD1972_TDEV1_FALL = 0x86, + kD1972_TDEV2_RISE = 0x87, + kD1972_TDEV2_FALL = 0x88, + kD1972_TDEV3_RISE = 0x89, + kD1972_TDEV3_FALL = 0x8a, + kD1972_TDEV4_RISE = 0x8b, + kD1972_TDEV4_FALL = 0x8c, + kD1972_TLDO5_RISE = 0x8d, + kD1972_TLDO16_RISE = 0x8e, + kD1972_TVCENTER_RISE = 0x8f, + kD1972_TLINCHG_RISE = 0x90, + kD1972_TBUCK0_RISE = 0x91, + kD1972_TBUCK2_RISE = 0x92, + kD1972_TBUCK3_RISE = 0x93, + kD1972_TBUCK4_RISE = 0x94, + kD1972_TISENSE_HYSE = 0x95, + + kD1972_BUTTON1 = 0x96, + kD1972_BUTTON2 = 0x97, + kD1972_BUTTON3 = 0x98, + kDIALOG_SYS_CONFIG = 0x99, + + kD1972_BUCK3_ALT = 0x9a, + kD1972_BUCK4_ALT = 0x9b, + kD1972_GPIO_SOFTHIB1 = 0x9c, + kD1972_GPIO_SOFTHIB2 = 0x9d, + kDIALOG_BUTTON_DBL = 0x9e, + + kDIALOG_MEMBYTE0 = 0xa1, + kDIALOG_MEMBYTE_LAST = 0xc8, + + kD1972_TEST_MODE = 0xdc, + + kDIALOG_APP_TMUX = 0x15e, + kDIALOG_BIST_ADC_CTRL = 0x15f, + kDIALOG_BIST_ADC_LSB = 0x160, + kDIALOG_BIST_ADC_MSB = 0x161, +}; + +enum { + kD1972_CHIP_ID_MRC_MASK = (0xf << 0), + kD1972_CHIP_ID_MRC_A0 = (0 << 0), + kD1972_CHIP_ID_MRC_A1 = (1 << 0), +}; + +enum { + kD1972_EVENT_A_BUTTON1 = (1 << 0), + kD1972_EVENT_A_BUTTON2 = (1 << 1), + kD1972_EVENT_A_BUTTON3 = (1 << 2), + kD1972_EVENT_A_VCENTER_DET = (1 << 3), + kD1972_EVENT_A_FW_DET = (1 << 4), + kD1972_EVENT_A_ACC_DET = (1 << 5), + kD1972_EVENT_A_VBUS_EXT_DET = (1 << 6), + kD1972_EVENT_A_VDD_LOW = (1 << 7), +}; + +// EVENT_B events are assumed volatile (lost over sleep/wake) +enum { + kD1972_EVENT_B_DWI_TO = (1 << 0), + kD1972_EVENT_B_CHG_PRE = (1 << 1), + kD1972_EVENT_B_CHG_FAST = (1 << 2), + kD1972_EVENT_B_CHG_END = (1 << 3), + kD1972_EVENT_B_TBAT = (1 << 4), + kD1972_EVENT_B_EOMC = (1 << 5), + kD1972_EVENT_B_FW_OV = (1 << 6), + kDIALOG_EVENT_B_HIB = (1 << 7), +}; + +enum { + kD1972_EVENT_C_GPIO1 = (1 << 0), + kD1972_EVENT_C_GPIO2 = (1 << 1), + kD1972_EVENT_C_GPIO3 = (1 << 2), + kD1972_EVENT_C_GPIO4 = (1 << 3), + kD1972_EVENT_C_GPIO5 = (1 << 4), + kD1972_EVENT_C_GPIO6 = (1 << 5), + kD1972_EVENT_C_GPIO7 = (1 << 6), + kD1972_EVENT_C_GPIO8 = (1 << 7), +}; + +enum { + kD1972_EVENT_D_GPIO9 = (1 << 0), + kD1972_EVENT_D_GPIO10 = (1 << 1), + kD1972_EVENT_D_GPIO11 = (1 << 2), + kD1972_EVENT_D_GPIO12 = (1 << 3), + kD1972_EVENT_D_DPHP = (1 << 4), + kD1972_EVENT_D_CHG_ABCC_ACT = (1 << 5), + kD1972_EVENT_D_CHG_BUCK_FLG = (1 << 6), + kD1972_EVENT_D_VBUS_OV = (1 << 7), +}; + +enum { + kD1972_EVENT_E_TDEV1_FALL = (1 << 0), + kD1972_EVENT_E_TDEV1_RISE = (1 << 1), + kD1972_EVENT_E_TDEV2_FALL = (1 << 2), + kD1972_EVENT_E_TDEV2_RISE = (1 << 3), + kD1972_EVENT_E_TDEV3_FALL = (1 << 4), + kD1972_EVENT_E_TDEV3_RISE = (1 << 5), + kD1972_EVENT_E_TDEV4_FALL = (1 << 6), + kD1972_EVENT_E_TDEV4_RISE = (1 << 7), +}; + +enum { + kD1972_EVENT_F_ALARM = (1 << 0), + kD1972_EVENT_F_LDO1_OC = (1 << 1), + kD1972_EVENT_F_LDO5_OC = (1 << 2), + kD1972_EVENT_F_LDO6_OC = (1 << 3), + kD1972_EVENT_F_FW_DPHP_REM = (1 << 4), + kD1972_EVENT_F_LDO10_OC = (1 << 5), + kD1972_EVENT_F_VBUS_EXT_REM = (1 << 6), + kD1972_EVENT_F_VBUS_OC = (1 << 7), +}; + +enum { + kD1972_EVENT_G_TLDO5 = (1 << 0), + kD1972_EVENT_G_TLDO16 = (1 << 1), + kD1972_EVENT_G_TVCENTER = (1 << 2), + kD1972_EVENT_G_TLINCHG = (1 << 3), + kD1972_EVENT_G_TBUCK0 = (1 << 4), + kD1972_EVENT_G_TBUCK2 = (1 << 5), + kD1972_EVENT_G_TBUCK3 = (1 << 6), + kD1972_EVENT_G_TBUCK4 = (1 << 7), +}; + +enum { + kD1972_EVENT_H_EOMC_BIST = (1 << 0), +}; + +enum { + kD1972_EVENT_I_BTN1_DBL = (1 << 3), + kD1972_EVENT_I_BTN2_DBL = (1 << 4), + kD1972_EVENT_I_BTN3_DBL = (1 << 5), +}; + +enum { + kD1972_STATUS_A_BUTTON1 = (1 << 0), + kD1972_STATUS_A_BUTTON2 = (1 << 1), + kD1972_STATUS_A_BUTTON3 = (1 << 2), + kD1972_STATUS_A_VCENTER_DET = (1 << 3), + kD1972_STATUS_A_FW_DPHP_DET = (1 << 4), + kD1972_STATUS_A_ACC_DET = (1 << 5), + kD1972_STATUS_A_VBUS_EXT_DET = (1 << 6), + kD1972_STATUS_A_VDD_LOW = (1 << 7), +}; + +enum { + kD1972_STATUS_B_CHG_PRE = (1 << 1), + kD1972_STATUS_B_CHG_FAST = (1 << 2), + kD1972_STATUS_B_CHG_END = (1 << 3), + kD1972_STATUS_B_TBAT = (1 << 4), + kD1972_STATUS_B_FW_OV = (1 << 6), +}; + +enum { + kD1972_STATUS_C_GPIO1 = (1 << 0), + kD1972_STATUS_C_GPIO2 = (1 << 1), + kD1972_STATUS_C_GPIO3 = (1 << 2), + kD1972_STATUS_C_GPIO4 = (1 << 3), + kD1972_STATUS_C_GPIO5 = (1 << 4), + kD1972_STATUS_C_GPIO6 = (1 << 5), + kD1972_STATUS_C_GPIO7 = (1 << 6), + kD1972_STATUS_C_GPIO8 = (1 << 7), +}; + +enum { + kD1972_STATUS_D_GPIO9 = (1 << 0), + kD1972_STATUS_D_GPIO10 = (1 << 1), + kD1972_STATUS_D_GPIO11 = (1 << 2), + kD1972_STATUS_D_GPIO12 = (1 << 3), + kD1972_STATUS_D_DPHP = (1 << 4), + kD1972_STATUS_D_CHG_ABCC_ACT = (1 << 5), + kD1972_STATUS_D_CHG_BUCK_FLG = (1 << 6), + kD1972_STATUS_D_VBUS_OV = (1 << 7), +}; + +enum { + kD1972_STATUS_E_TDEV1_FALL = (1 << 0), + kD1972_STATUS_E_TDEV1_RISE = (1 << 1), + kD1972_STATUS_E_TDEV2_FALL = (1 << 2), + kD1972_STATUS_E_TDEV2_RISE = (1 << 3), + kD1972_STATUS_E_TDEV3_FALL = (1 << 4), + kD1972_STATUS_E_TDEV3_RISE = (1 << 5), + kD1972_STATUS_E_TDEV4_FALL = (1 << 6), + kD1972_STATUS_E_TDEV4_RISE = (1 << 7), +}; + +enum { + kD1972_STATUS_F_CHG_ATT = (1 << 0), + kD1972_STATUS_F_CPUA_EN_STAT = (1 << 1), + kD1972_STATUS_F_CPUB_EN_STAT = (1 << 2), + kD1972_STATUS_F_PROT_FET_ON = (1 << 3), + kD1972_STATUS_F_CHG_TO = (1 << 5), + kD1972_STATUS_F_VBUS_OC = (1 << 7), +}; + +enum { + kD1972_STATUS_G_TLDO5 = (1 << 0), + kD1972_STATUS_G_TLDO16 = (1 << 1), + kD1972_STATUS_G_TVCENTER = (1 << 2), + kD1972_STATUS_G_TLINCHG = (1 << 3), + kD1972_STATUS_G_TBUCK0 = (1 << 4), + kD1972_STATUS_G_TBUCK2 = (1 << 5), + kD1972_STATUS_G_TBUCK3 = (1 << 6), + kD1972_STATUS_G_TBUCK4 = (1 << 7), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1972_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1972_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(0, kD1972_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS = (kD1972_EVENT_A_BUTTON2 | + kD1972_EVENT_A_BUTTON1 | + kD1972_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(0, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(5, kD1972_EVENT_F_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD1972_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD1972_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VHP_DET_MASK = EVENT_FLAG_MAKE(0, kD1972_EVENT_A_FW_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(5, kD1972_EVENT_F_VBUS_EXT_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(1, kD1972_EVENT_B_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_B_HIB), + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(3, kD1972_EVENT_D_CHG_ABCC_ACT), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(1, kD1972_EVENT_B_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(1, kD1972_EVENT_B_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(2, kD1972_EVENT_C_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(3, kD1972_EVENT_D_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(3, kD1972_EVENT_D_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(3, kD1972_EVENT_D_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(3, kD1972_EVENT_D_GPIO12), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(8, kD1972_EVENT_I_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(8, kD1972_EVENT_I_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(8, kD1972_EVENT_I_BTN3_DBL), + + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO13_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO14_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO15_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO16_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO17_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD1972_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD1972_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = STATUS_FLAG_MAKE(0, kD1972_STATUS_A_FW_DPHP_DET), + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD1972_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(1, kD1972_STATUS_B_CHG_PRE | kD1972_STATUS_B_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(5, kD1972_STATUS_F_CHG_TO), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD1972_STATUS_B_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(1, kD1972_STATUS_B_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(5, kD1972_STATUS_F_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(3, kD1972_STATUS_D_CHG_ABCC_ACT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(2 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {kD1972_STATUS_A_FW_DPHP_DET, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD1972_STATUS_B_CHG_PRE | kD1972_STATUS_B_CHG_FAST, 0, 0, 0, 0}; + +enum { + kD1972_EVENT_A_WAKEMASK = (kD1972_EVENT_A_BUTTON1 | + kD1972_EVENT_A_BUTTON2 | + kD1972_EVENT_A_BUTTON3 | + kD1972_EVENT_A_VBUS_EXT_DET | + kD1972_STATUS_A_FW_DPHP_DET | + kD1972_EVENT_A_ACC_DET), + kD1972_EVENT_B_WAKEMASK = 0, + kD1972_EVENT_C_WAKEMASK = 0, + kD1972_EVENT_D_WAKEMASK = 0, + kD1972_EVENT_E_WAKEMASK = 0, + kD1972_EVENT_F_WAKEMASK = (kD1972_EVENT_F_ALARM | + kD1972_EVENT_F_FW_DPHP_REM | + kD1972_EVENT_F_VBUS_EXT_REM), + kD1972_EVENT_G_WAKEMASK = 0, + kD1972_EVENT_H_WAKEMASK = 0, + kD1972_EVENT_I_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD1972_EVENT_A_WAKEMASK, + ~kD1972_EVENT_B_WAKEMASK, + ~kD1972_EVENT_C_WAKEMASK, + ~kD1972_EVENT_D_WAKEMASK, + ~kD1972_EVENT_E_WAKEMASK, + ~kD1972_EVENT_F_WAKEMASK, + ~kD1972_EVENT_G_WAKEMASK, + ~kD1972_EVENT_H_WAKEMASK, + ~kD1972_EVENT_I_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD1972_EVENT_A_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD1972_EVENT_B_WAKEMASK, + kD1972_EVENT_C_WAKEMASK, + kD1972_EVENT_D_WAKEMASK, + kD1972_EVENT_E_WAKEMASK, + kD1972_EVENT_F_WAKEMASK, + kD1972_EVENT_G_WAKEMASK, + kD1972_EVENT_H_WAKEMASK, + kD1972_EVENT_I_WAKEMASK, +}; + +// All events that defer shutdown +static const eventRegisters kDialogEventRestartMask = { + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_HOLD_BUTTON_MASK, 0) | EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ACC_DET_MASK, 0), + 0, + 0, + 0, + 0, + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ALARM_MASK, 5), + 0, + 0, + 0, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD1972_EVENT_A_VBUS_EXT_DET | kD1972_EVENT_A_FW_DET | kD1972_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + kD1972_EVENT_F_FW_DPHP_REM | kD1972_EVENT_F_VBUS_EXT_REM, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD1972_EVENT_A_VCENTER_DET, + 0, + 0, + kD1972_EVENT_D_CHG_ABCC_ACT, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + kD1972_EVENT_A_FW_DET, + 0, + 0, + 0, + 0, + kD1972_EVENT_F_FW_DPHP_REM, + 0, + 0, + 0, +}; + +enum { + kDialogEventPwrsupplyCount = 5, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 2, +}; + +enum { + kDIALOG_LCM_ACTIVE_BOOST_EN = (1 << 6), + kDIALOG_LCM_ACTIVE_MASK = (1 << 2) | (1 << 3) | (1 << 4), +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_SOFT_HIB = (1 << 3), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PRO_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), +}; + +enum { + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_BOOST = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_BUCK_CONTROL_DWI_EN = (1 << 4), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x03, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x2b, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x5d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0xc1, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 70, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 10, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 2620, +}; + + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_B_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_B_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 30, + kDIALOG_CHARGE_CONTROL_MAX = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK * kDIALOG_CHARGE_CONTROL_STEP, +}; + +enum { + kDIALOG_CHARGE_CONTROL_C_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN = (1 << 7), + + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = kDIALOG_CHARGE_CONTROL_C_ALT_USB_DIS, + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG, + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (0xf << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG_OFF = (16 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN__LG_OFF = (17 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP = (18 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO16_TEMP = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VCENTER_TEMP = (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP = (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP, + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 5), + kDIALOG_ADC_CONTROL_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (0 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (1 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (2 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (3 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (4 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (5 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (6 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (7 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (8 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (9 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10 = (19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11 = (21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO12 = (23 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM1 = (24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM1 = (25 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM2 = (26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM2 = (27 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM3 = (28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM3 = (29 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO16 = (30 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO16 = (31 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (32 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (33 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUF_ON = (34 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IBUF_ON = (35 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0A = (36 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0B = (38 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0C = (40 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (42 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (44 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (46 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_CPUA_SW_S = (48 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_CPUB_SW_S = (50 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_LED = (52 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBOOST_LCM = (54 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (56 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (58 << 0), + kDIALOG_BIST_ADC_CTRL_AUTO_RUN = (1 << 6), + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_RAMP_EN = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_DWI_EN = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_DITH_EN = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_DITH_RAMP_EN = (1 << 5), + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL_WLED_DITH_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL_WLED_DWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL_WLED_DITH_EN| + kDIALOG_WLED_CONTROL_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS (11) + +#define NUM_LDOS 23 +static const struct ldo_params ldo_1972[NUM_LDOS] = { +{ 2500, 50, 0x15, 0x1f, 0x1, kD1972_LDO1, kD1972_ACTIVE1, 0x40 }, // LDO1 +// LDO2 is funny and has a gap from 1.335V to 1.65V, only supporting the top part +{ 1490, 5, 0x3f, 0x3f, 0x0, kD1972_LDO2, kD1972_ACTIVE1, 0x80 }, // LDO2 +{ 2500, 50, 0x10, 0x1f, 0x0, kD1972_LDO3, kD1972_ACTIVE2, 0x01 }, // LDO3 +{ 1800, 50, 0x1e, 0x1f, 0x0, kD1972_LDO4, kD1972_ACTIVE2, 0x02 }, // LDO4 +{ 2500, 50, 0x16, 0x1f, 0x0, kD1972_LDO5, kD1972_ACTIVE2, 0x04 }, // LDO5 +{ 2500, 50, 0x16, 0x1f, 0x2, kD1972_LDO6, kD1972_ACTIVE2, 0x08 }, // LDO6 +{ 1500, 100,0x16, 0x1f, 0x0, kD1972_LDO7, kD1972_ACTIVE2, 0x10 }, // LDO7 +{ 2000, 50, 0x1f, 0x1f, 0x0, kD1972_LDO8, kD1972_ACTIVE2, 0x20 }, // LDO8 +{ 1200, 100,0x12, 0x1f, 0x0, kD1972_LDO9, kD1972_ACTIVE2, 0x40 }, // LDO9 +{ 2500, 50, 0x15, 0x1f, 0x4, kD1972_LDO10, kD1972_ACTIVE2, 0x80 }, // LDO10 +{ 1700, 50, 0x1a, 0x1f, 0x0, kD1972_LDO11, kD1972_ACTIVE3, 0x01 }, // LDO11 +{ 600, 25, 0x1c, 0x1f, 0x0, kD1972_LDO12, kD1972_ACTIVE3, 0x02 }, // LDO12 +{ 5000, 50, 0x14, 0x1f, 0x0, kD1972_LCM_CONTROL1, kD1972_ACTIVE3, 0x04 }, // LCM1_LDO +{ 5000, 50, 0x14, 0x1f, 0x0, kD1972_LCM_CONTROL2, kD1972_ACTIVE3, 0x08 }, // LCM2_LDO +{ 5000, 50, 0x14, 0x1f, 0x0, kD1972_LCM_CONTROL3, kD1972_ACTIVE3, 0x10 }, // LCM3_LDO +{ 5000, 50, 0x1f, 0x1f, 0x0, kD1972_LCM_BST_CONTROL, kD1972_ACTIVE3, 0x40 }, // LCM_BOOST +{ 0, 0, 0, 0, 0x0, 0, kD1972_ACTIVE3, 0x80 }, // 17 - WLED_BST_EN +{ 0, 0, 0, 0, 0x0, 0, kD1972_ACTIVE4, 0x10 }, // 18 - DSP_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1972_ACTIVE4, 0x20 }, // 19 - CPU1V2_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1972_ACTIVE4, 0x40 }, // 20 - WDIG_EN +{ 0, 0, 0, 0, 0x0, 0, kD1972_ACTIVE4, 0x80 }, // 21 - CPU1V8_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1972_HIBERNATE1, 0x20 }, // 22 - set LDO1_EN in HIB +{ 0, 0, 0, 0, 0x0, 0, kD1972_HIBERNATE2, 0x08 }, // 23 - set LDO6_EN in HIB +}; +#define LDOP ldo_1972 + +enum { + kDIALOG_VIB_CTRL_PWM_EN = (1 << 0), + kDIALOG_VIB_CTRL_BRAKE = (1 << 1), + kDIALOG_VIB_CTRL_PWM_CLK_MASK = (3 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_2MHZ = (0 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_1MHZ = (1 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_500KHZ = (2 << 2), + + kDIALOG_VIB_VSET_MASK = (0x3f << 0), +}; + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD1972_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD1972_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD1972_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD1972_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD1972_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD1972_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif /* __DIALOG_D1972_H */ diff --git a/drivers/dialog/pmu/d1974.h b/drivers/dialog/pmu/d1974.h new file mode 100644 index 0000000..22e44fb --- /dev/null +++ b/drivers/dialog/pmu/d1974.h @@ -0,0 +1,866 @@ +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_REG_BANK 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_WLED 1 + +enum { + kDIALOG_ADDR_R = 0x79, + kDIALOG_ADDR_W = 0x78, + kDIALOG_REG_BYTES = 1, +}; + +enum { + kDIALOG_EVENT_COUNT = 10, + kDIALOG_STATUS_COUNT = 10, + kDIALOG_HIBERNATE_COUNT = 4, + kDIALOG_CHIPID_COUNT = 1, + kDIALOG_FAULTLOG_COUNT = 1, + kDIALOG_GPIO_COUNT = 16, +}; + +#include "dCommon.h" + +enum { + kDIALOG_BANK_COUNT = 3, + kDIALOG_BANK0_SHARED_COUNT = 0x59, +}; + +enum { + // Register Bank 0 + + kDIALOG_CHIP_ID = 0x00, + + kDIALOG_EVENT_A = 0x01, + kDIALOG_EVENT_B = 0x02, + kDIALOG_EVENT_C = 0x03, + kDIALOG_EVENT_D = 0x04, + kDIALOG_EVENT_E = 0x05, + kDIALOG_EVENT_F = 0x06, + kDIALOG_EVENT_G = 0x07, + kDIALOG_EVENT_H = 0x08, + kDIALOG_EVENT_I = 0x09, + kDIALOG_EVENT_J = 0x0a, + + kDIALOG_STATUS_A = 0x0b, + kDIALOG_STATUS_B = 0x0c, + kDIALOG_STATUS_C = 0x0d, + kDIALOG_STATUS_D = 0x0e, + kDIALOG_STATUS_E = 0x0f, + kDIALOG_STATUS_F = 0x10, + kDIALOG_STATUS_G = 0x11, + kDIALOG_STATUS_H = 0x12, + kDIALOG_STATUS_I = 0x13, + kDIALOG_STATUS_J = 0x14, + + kDIALOG_IRQ_MASK_A = 0x15, + kDIALOG_IRQ_MASK_B = 0x16, + kDIALOG_IRQ_MASK_C = 0x17, + kDIALOG_IRQ_MASK_D = 0x18, + kDIALOG_IRQ_MASK_E = 0x19, + kDIALOG_IRQ_MASK_F = 0x1a, + kDIALOG_IRQ_MASK_G = 0x1b, + kDIALOG_IRQ_MASK_H = 0x1c, + kDIALOG_IRQ_MASK_I = 0x1d, + kDIALOG_IRQ_MASK_J = 0x1e, + + kDIALOG_SYS_CONTROL = 0x1f, + kDIALOG_SYS_CONTROL2 = 0x20, + + kDIALOG_FAULT_LOG = 0x21, + kDIALOG_BANKSEL = 0x22, + + kD1974_ACTIVE1 = 0x23, + kD1974_ACTIVE2 = 0x24, + kD1974_ACTIVE3 = 0x25, + kDIALOG_LCM_ACTIVE = kD1974_ACTIVE3, + kD1974_ACTIVE4 = 0x26, + kD1974_STANDBY1 = 0x27, + kDIALOG_STANDBY = kD1974_STANDBY1, + kD1974_HIBERNATE1 = 0x28, + kD1974_HIBERNATE2 = 0x29, + kD1974_HIBERNATE3 = 0x2a, + kD1974_HIBERNATE4 = 0x2b, + + kD1974_BUCK0 = 0x2c, + kDIALOG_BUCK0 = kD1974_BUCK0, + kD1974_BUCK2 = 0x2d, + kDIALOG_BUCK2 = kD1974_BUCK2, + kD1974_BUCK3 = 0x2e, + kD1974_BUCK4 = 0x2f, + kD1974_BUCK5 = 0x30, + + kD1974_LDO1 = 0x31, + kD1974_LDO2 = 0x32, + kD1974_LDO3 = 0x33, + kD1974_LDO4 = 0x34, + kD1974_LDO5 = 0x35, + kD1974_LDO6 = 0x36, + kD1974_LDO7 = 0x37, + kD1974_LDO8 = 0x38, + kD1974_LDO9 = 0x39, + kD1974_LDO10 = 0x3a, + kD1974_LDO11 = 0x3b, + kD1974_LDO12 = 0x3c, + + kDIALOG_BUCK_DWI = 0x3d, + + kDIALOG_CHARGE_BUCK_CONTROL = 0x3e, + + kDIALOG_CHARGE_CONTROL_A = 0x3f, + kDIALOG_CHARGE_CONTROL_B = 0x40, + kDIALOG_CHARGE_CONTROL_C = 0x41, + kDIALOG_CHARGE_CONTROL_D = 0x42, + kDIALOG_CHARGE_TIME = 0x43, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kDIALOG_CHARGE_CONTROL_B, + kDIALOG_CHARGE_CONTROL_HIB = kDIALOG_CHARGE_CONTROL_A, + kDIALOG_CHARGE_CONTROL_TIME = kDIALOG_CHARGE_CONTROL_D, + kDIALOG_CHARGE_CONTROL_EN = kDIALOG_CHARGE_CONTROL_C, + kDIALOG_OTP_ISET_BAT = kDIALOG_CHARGE_CONTROL_A, // not a real OTP register + + kDIALOG_ADC_CONTROL = 0x44, + kDIALOG_ADC_LSB = 0x45, + kDIALOG_ADC_MSB = 0x46, + kDIALOG_ICHG_AVG = 0x47, + + kDIALOG_TBAT_0 = 0x4c, + kDIALOG_ICHG_TBAT_0 = 0x4d, + kDIALOG_TBAT_1 = 0x4e, + kDIALOG_ICHG_TBAT_1 = 0x4f, + kDIALOG_TBAT_2 = 0x50, + kDIALOG_ICHG_TBAT_2 = 0x51, + kDIALOG_TBAT_3 = 0x52, + kDIALOG_ICHG_TBAT_3 = 0x53, + kDIALOG_TBAT_4 = 0x54, + kDIALOG_ICHG_TBAT_4 = 0x55, + kDIALOG_TBAT_MAX = 0x56, + kDIALOG_ICHG_TBAT_NUM = 5, + + kDIALOG_T_OFFSET_MSB = 0x57, + kDIALOG_T_OFFSET_LSB = 0x58, + kD1974_IVBUS_GAIN = 0x59, + + kDIALOG_RTC_ALARM_A = 0x5a, + kDIALOG_RTC_ALARM_B = 0x5b, + kDIALOG_RTC_ALARM_C = 0x5c, + kDIALOG_RTC_ALARM_D = 0x5d, + kDIALOG_RTC_CONTROL = 0x5e, + kDIALOG_RTC_TIMEZONE = 0x5f, + kDIALOG_UPCOUNT_A = 0x60, + kDIALOG_UPCOUNT_B = 0x61, + kDIALOG_UPCOUNT_C = 0x62, + kDIALOG_UPCOUNT_D = 0x63, + + kD1974_SYS_GPIO_1 = 0x64, + kDIALOG_SYS_GPIO_REG_START = kD1974_SYS_GPIO_1, + kD1974_SYS_GPIO_2 = 0x65, + kD1974_SYS_GPIO_3 = 0x66, + kD1974_SYS_GPIO_4 = 0x67, + kD1974_SYS_GPIO_5 = 0x68, + kD1974_SYS_GPIO_6 = 0x69, + kD1974_SYS_GPIO_7 = 0x6a, + kD1974_SYS_GPIO_8 = 0x6b, + kD1974_SYS_GPIO_9 = 0x6c, + kD1974_SYS_GPIO_10 = 0x6d, + kD1974_SYS_GPIO_11 = 0x6e, + kD1974_SYS_GPIO_12 = 0x6f, + kD1974_SYS_GPIO_13 = 0x70, + kD1974_SYS_GPIO_14 = 0x71, + kD1974_SYS_GPIO_15 = 0x72, + kD1974_SYS_GPIO_16 = 0x73, + kD1974_SYS_GPIO_17 = 0x74, + + kD1974_SYS_GPIO_DEB1 = 0x75, + kD1974_SYS_GPIO_DEB2 = 0x76, + kD1974_SYS_GPIO_DEB3 = 0x77, + kD1974_SYS_GPIO_DEB4 = 0x78, + kD1974_SYS_GPIO_DEB5 = 0x79, + kD1974_SYS_GPIO_DEB6 = 0x7a, + kD1974_SYS_GPIO_DEB7 = 0x7b, + kD1974_SYS_GPIO_DEB8 = 0x7c, + kD1974_SYS_GPIO_DEB9 = 0x7d, + + kDIALOG_LDO_CONTROL = 0x7e, + + kD1974_BUTTON1 = 0x7f, + kD1974_BUTTON2 = 0x80, + kD1974_BUTTON3 = 0x81, + kDIALOG_SYS_CONFIG = 0x82, + + kD1974_LCM_CONTROL1 = 0x83, + kD1974_LCM_CONTROL2 = 0x84, + kD1974_LCM_CONTROL3 = 0x85, + kD1974_LCM_BST_CONTROL = 0x86, + kDIALOG_LCM_BOOST = kD1974_LCM_BST_CONTROL, + + kD1974_BUCK3_HIB = 0xa1, + kD1974_BUCK4_HIB = 0xa2, + kD1974_GPIO_SOFTHIB1 = 0xa3, + kD1974_GPIO_SOFTHIB2 = 0xa4, + kD1974_GPIO_SOFTHIB3 = 0xa5, + kDIALOG_BUTTON_DBL = 0xa6, + + kDIALOG_MEMBYTE0 = 0xa7, + kDIALOG_MEMBYTE_LAST = 0xce, + + kDIALOG_WLED_ISET = 0xd3, + kDIALOG_WLED_ISET2 = 0xd4, + kDIALOG_WLED_CONTROL = 0xd5, + kDIALOG_WLED_CONTROL2 = 0xd6, + kDIALOG_WLED_DWI_CONTROL = kDIALOG_WLED_CONTROL2, + kDIALOG_WLED_OPTIONS = kDIALOG_WLED_CONTROL2, + + // Register Bank 1 + + kDIALOG_APP_TMUX = 0x162, + kDIALOG_BIST_ADC_CTRL = 0x163, + kDIALOG_BIST_ADC_LSB = 0x164, + kDIALOG_BIST_ADC_MSB = 0x165, + kDIALOG_BIST_ADC0 = 0x166, + + kDIALOG_BUCK_CTRL1 = 0x1b3, + + kD1974_IVBUS_OFFS = 0x1fc, + + // Bank 2 Test Registers + kD1974_TEST_MODE = 0x2d0, +}; + +enum { + kD1974_CHIP_ID_MRC_MASK = (0xf << 0), + kD1974_CHIP_ID_MRC_A0 = (0 << 0), + kD1974_CHIP_ID_MRC_A1 = (1 << 0), + kD1974_CHIP_ID_TRC_MASK = (0xf << 4), + kD1974_CHIP_ID_TRC_AK = (0xa << 4), +}; + +enum { + kD1974_EVENT_A_BUTTON1 = (1 << 0), + kD1974_EVENT_A_BUTTON2 = (1 << 1), + kD1974_EVENT_A_BUTTON3 = (1 << 2), + kD1974_EVENT_A_VCENTER_DET = (1 << 3), + kD1974_EVENT_A_FW_DET = (1 << 4), + kD1974_EVENT_A_ACC_DET = (1 << 5), + kD1974_EVENT_A_VBUS_EXT_DET = (1 << 6), + kD1974_EVENT_A_VDD_LOW = (1 << 7), +}; + +// EVENT_B events are assumed volatile (lost over sleep/wake) +enum { + kD1974_EVENT_B_CHG_PRE = (1 << 1), + kD1974_EVENT_B_CHG_FAST = (1 << 2), + kD1974_EVENT_B_CHG_END = (1 << 3), + kD1974_EVENT_B_TBAT = (1 << 4), + kD1974_EVENT_B_FW_OV = (1 << 6), + kDIALOG_EVENT_B_HIB = (1 << 7), +}; + +enum { + kD1974_EVENT_C_GPIO1 = (1 << 0), + kD1974_EVENT_C_GPIO2 = (1 << 1), + kD1974_EVENT_C_GPIO3 = (1 << 2), + kD1974_EVENT_C_GPIO4 = (1 << 3), + kD1974_EVENT_C_GPIO5 = (1 << 4), + kD1974_EVENT_C_GPIO6 = (1 << 5), + kD1974_EVENT_C_GPIO7 = (1 << 6), + kD1974_EVENT_C_GPIO8 = (1 << 7), +}; + +enum { + kD1974_EVENT_D_GPIO9 = (1 << 0), + kD1974_EVENT_D_GPIO10 = (1 << 1), + kD1974_EVENT_D_GPIO11 = (1 << 2), + kD1974_EVENT_D_GPIO12 = (1 << 3), + kD1974_EVENT_D_GPIO13 = (1 << 4), + kD1974_EVENT_D_GPIO14 = (1 << 5), + kD1974_EVENT_D_GPIO15 = (1 << 6), + kD1974_EVENT_D_GPIO16 = (1 << 7), +}; + +enum { + kD1974_EVENT_E_GPIO17 = (1 << 0), + kD1974_EVENT_E_BTN1_DBL = (1 << 3), + kD1974_EVENT_E_BTN2_DBL = (1 << 4), + kD1974_EVENT_E_BTN3_DBL = (1 << 5), + kD1974_EVENT_E_CHG_BUCK_FLG = (1 << 6), + kD1974_EVENT_E_VBUS_OV = (1 << 7), +}; + +enum { + kD1974_EVENT_H_ALARM = (1 << 0), + kD1974_EVENT_H_FW_REM = (1 << 4), + kD1974_EVENT_H_VBUS_REM = (1 << 6), + kD1974_EVENT_H_ABCC_FLAG = (1 << 7), +}; + +enum { + kD1974_EVENT_J_DWI_TO = (1 << 1), + kD1974_EVENT_J_EOMC = (1 << 2), + kD1974_EVENT_J_DPHP_DET = (1 << 4), +}; + +enum { + kD1974_STATUS_A_BUTTON1 = (1 << 0), + kD1974_STATUS_A_BUTTON2 = (1 << 1), + kD1974_STATUS_A_BUTTON3 = (1 << 2), + kD1974_STATUS_A_VCENTER_DET = (1 << 3), + kD1974_STATUS_A_FW_DET = (1 << 4), + kD1974_STATUS_A_ACC_DET = (1 << 5), + kD1974_STATUS_A_VBUS_EXT_DET = (1 << 6), + kD1974_STATUS_A_VDD_LOW = (1 << 7), +}; + +enum { + kD1974_STATUS_B_CHG_ATT = (1 << 0), + kD1974_STATUS_B_CHG_PRE = (1 << 1), + kD1974_STATUS_B_CHG_FAST = (1 << 2), + kD1974_STATUS_B_CHG_END = (1 << 3), + kD1974_STATUS_B_TBAT = (1 << 4), + kD1974_STATUS_B_CHG_TO = (1 << 5), + kD1974_STATUS_B_FW_OV = (1 << 6), +}; + +enum { + kD1974_STATUS_C_GPIO1 = (1 << 0), + kD1974_STATUS_C_GPIO2 = (1 << 1), + kD1974_STATUS_C_GPIO3 = (1 << 2), + kD1974_STATUS_C_GPIO4 = (1 << 3), + kD1974_STATUS_C_GPIO5 = (1 << 4), + kD1974_STATUS_C_GPIO6 = (1 << 5), + kD1974_STATUS_C_GPIO7 = (1 << 6), + kD1974_STATUS_C_GPIO8 = (1 << 7), +}; + +enum { + kD1974_STATUS_D_GPIO9 = (1 << 0), + kD1974_STATUS_D_GPIO10 = (1 << 1), + kD1974_STATUS_D_GPIO11 = (1 << 2), + kD1974_STATUS_D_GPIO12 = (1 << 3), + kD1974_STATUS_D_GPIO13 = (1 << 4), + kD1974_STATUS_D_GPIO14 = (1 << 5), + kD1974_STATUS_D_GPIO15 = (1 << 6), + kD1974_STATUS_D_GPIO16 = (1 << 7), +}; + +enum { + kD1974_STATUS_E_GPIO17 = (1 << 0), + kD1974_STATUS_E_CHG_BUCK_FLG = (1 << 6), + kD1974_STATUS_E_VBUS_OV = (1 << 7), +}; + +enum { + kD1974_STATUS_H_ABCC_FLAG = (1 << 7), +}; + +enum { + kD1974_BUCK4_CONT_MASK = (3 << 4), + kD1974_BUCK4_CONT_SLEEP = (0 << 4), + kD1974_BUCK4_CONT_AUTO = (1 << 4), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1974_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD1974_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(0, kD1974_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS = (kD1974_EVENT_A_BUTTON2 | + kD1974_EVENT_A_BUTTON1 | + kD1974_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(0, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(7, kD1974_EVENT_H_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD1974_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD1974_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VHP_DET_MASK = EVENT_FLAG_MAKE(0, kD1974_STATUS_A_FW_DET), + kDIALOG_EVENT_VBUS_REM_MASK = EVENT_FLAG_MAKE(7, kD1974_EVENT_H_VBUS_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(9, kD1974_EVENT_J_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_B_HIB), + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(7, kD1974_EVENT_H_ABCC_FLAG), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(1, kD1974_EVENT_B_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(1, kD1974_EVENT_B_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(2, kD1974_EVENT_C_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(3, kD1974_EVENT_D_GPIO16), + kDIALOG_EVENT_GPIO17_MASK = EVENT_FLAG_MAKE(4, kD1974_EVENT_E_GPIO17), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(4, kD1974_EVENT_E_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(4, kD1974_EVENT_E_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(4, kD1974_EVENT_E_BTN3_DBL), + + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD1974_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD1974_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = STATUS_FLAG_MAKE(0, kD1974_STATUS_A_FW_DET), + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD1974_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(1, kD1974_STATUS_B_CHG_PRE | kD1974_STATUS_B_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(1, kD1974_STATUS_B_CHG_TO), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD1974_STATUS_B_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(1, kD1974_STATUS_B_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(1, kD1974_STATUS_B_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(7, kD1974_STATUS_H_ABCC_FLAG), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(2 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {kD1974_STATUS_A_FW_DET, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD1974_STATUS_B_CHG_PRE | kD1974_STATUS_B_CHG_FAST, 0, 0, 0, 0}; + +enum { + kD1974_EVENT_A_WAKEMASK = (kD1974_EVENT_A_BUTTON1 | + kD1974_EVENT_A_BUTTON2 | + kD1974_EVENT_A_BUTTON3 | + kD1974_EVENT_A_VBUS_EXT_DET | + kD1974_STATUS_A_FW_DET | + kD1974_EVENT_A_ACC_DET), + kD1974_EVENT_B_WAKEMASK = 0, + kD1974_EVENT_C_WAKEMASK = 0, + kD1974_EVENT_D_WAKEMASK = 0, + kD1974_EVENT_E_WAKEMASK = 0, + kD1974_EVENT_F_WAKEMASK = 0, + kD1974_EVENT_G_WAKEMASK = 0, + kD1974_EVENT_H_WAKEMASK = (kD1974_EVENT_H_ALARM | + kD1974_EVENT_H_FW_REM | + kD1974_EVENT_H_VBUS_REM), + kD1974_EVENT_I_WAKEMASK = 0, + kD1974_EVENT_J_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD1974_EVENT_A_WAKEMASK, + ~kD1974_EVENT_B_WAKEMASK, + ~kD1974_EVENT_C_WAKEMASK, + ~kD1974_EVENT_D_WAKEMASK, + ~kD1974_EVENT_E_WAKEMASK, + ~kD1974_EVENT_F_WAKEMASK, + ~kD1974_EVENT_G_WAKEMASK, + ~kD1974_EVENT_H_WAKEMASK, + ~kD1974_EVENT_I_WAKEMASK, + ~kD1974_EVENT_J_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD1974_EVENT_A_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD1974_EVENT_B_WAKEMASK, + kD1974_EVENT_C_WAKEMASK, + kD1974_EVENT_D_WAKEMASK, + kD1974_EVENT_E_WAKEMASK, + kD1974_EVENT_F_WAKEMASK, + kD1974_EVENT_G_WAKEMASK, + kD1974_EVENT_H_WAKEMASK, + kD1974_EVENT_I_WAKEMASK, + kD1974_EVENT_J_WAKEMASK, +}; + +// All events that defer shutdown +static const eventRegisters kDialogEventRestartMask = { + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_HOLD_BUTTON_MASK, 0) | EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ACC_DET_MASK, 0), + 0, + 0, + 0, + 0, + 0, + 0, + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ALARM_MASK, 7), + 0, + 0, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD1974_EVENT_A_VBUS_EXT_DET | kD1974_EVENT_A_FW_DET | kD1974_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + kD1974_EVENT_H_FW_REM | kD1974_EVENT_H_VBUS_REM, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD1974_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + kD1974_EVENT_H_ABCC_FLAG, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + kD1974_EVENT_A_FW_DET, + 0, + 0, + 0, + 0, + 0, + 0, + kD1974_EVENT_H_FW_REM, + 0, + 0, +}; + +// XXXKW +enum { + kDialogEventPwrsupplyCount = 5, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 2, +}; + +enum { + kDIALOG_LCM_ACTIVE_BOOST_EN = (1 << 1), + kDIALOG_LCM_ACTIVE_MASK = (1 << 2) | (1 << 3) | (1 << 4), +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_SOFT_HIB = (1 << 3), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PRO_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), +}; + +enum { + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_BOOST = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_BUCK_DWI_BUCK0 = (1 << 0), + kDIALOG_BUCK_DWI_BUCK1 = (1 << 1), + kDIALOG_BUCK_DWI_BUCK2 = (1 << 2), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x02, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_250 = 0xe, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300 = 0x12, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_350 = 0x16, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 0x1a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x22, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 0x2a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 0x32, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_750 = 0x36, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 0x42, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x4a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500 = 0x72, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1900 = 0x92, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0x9a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100 = 0xa2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2200 = 0xaa, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2300 = 0xb2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 75, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 8, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 3262, +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_A_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_A_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_A_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 50, + kDIALOG_CHARGE_CONTROL_MAX = 3150, +}; + +enum { + kDIALOG_CHARGE_CONTROL_C_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN = (1 << 7), + + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = kDIALOG_CHARGE_CONTROL_C_ALT_USB_DIS, + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 9, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS_OFF = (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT_OFF= (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK5_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO9_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_B_TEMP= (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (26 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP = (27 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP = (28 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP = (29 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP= (30 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK5_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN31 = (31 << 0), + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 5), + kDIALOG_ADC_CONTROL_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (0x00 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (0x01 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (0x02 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (0x03 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (0x04 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (0x05 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (0x06 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (0x07 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (0x08 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (0x09 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (0x0a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (0x0b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (0x0c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (0x0d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (0x0e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (0x0f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (0x10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (0x11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (0x12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10 = (0x13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (0x14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11 = (0x15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (0x16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO12 = (0x17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM1 = (0x18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM1 = (0x19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM2 = (0x1a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM2 = (0x1b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM3 = (0x1c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM3 = (0x1d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (0x1e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (0x1f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUF_ON = (0x20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IBUF_ON = (0x21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0 = (0x22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_WLEDB = (0x24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (0x26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (0x28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (0x2a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_WLEDA = (0x2c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBOOST_LCM = (0x2e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (0x30 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (0x32 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK5 = (0x34 << 0), + kDIALOG_BIST_ADC_CTRL_AUTO_RUN = (1 << 6), + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (15 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ +< kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_ENABLE3 = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_ENABLE4 = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_ENABLE5 = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_ENABLE6 = (1 << 5), +}; + +enum { + kDIALOG_WLED_CONTROL2_WLED_RAMP_EN = (1 << 2), + kDIALOG_WLED_CONTROL2_WLED_DWI_EN = (1 << 3), + kDIALOG_WLED_CONTROL2_WLED_DITH_EN = (1 << 4), + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN = (1 << 5), + + kDIALOG_WLED_CONTROL_WLED_DWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL2_WLED_DITH_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS (11) + +#define NUM_LDOS 23 +static const struct ldo_params ldo_1974[NUM_LDOS] = { +{ 2500, 50, 0x0a, 0x1f, 0x1, kD1974_LDO1, kD1974_ACTIVE1, 0x20 }, // LDO1 +{ 1650, 5, 0x0a, 0x1f, 0x0, kD1974_LDO2, kD1974_ACTIVE1, 0x40 }, // LDO2 +{ 2500, 50, 0x0a, 0x1f, 0x0, kD1974_LDO3, kD1974_ACTIVE1, 0x80 }, // LDO3 +{ 1800, 50, 0x18, 0x1f, 0x0, kD1974_LDO4, kD1974_ACTIVE2, 0x01 }, // LDO4 +{ 2500, 50, 0x0a, 0x1f, 0x0, kD1974_LDO5, kD1974_ACTIVE2, 0x02 }, // LDO5 +{ 2500, 50, 0x10, 0x1f, 0x2, kD1974_LDO6, kD1974_ACTIVE2, 0x04 }, // LDO6 +{ 1500, 100,0x0a, 0x1f, 0x0, kD1974_LDO7, kD1974_ACTIVE2, 0x08 }, // LDO7 +{ 2000, 50, 0x16, 0x1f, 0x0, kD1974_LDO8, kD1974_ACTIVE2, 0x10 }, // LDO8 +{ 1200, 100,0x00, 0x1f, 0x0, kD1974_LDO9, kD1974_ACTIVE2, 0x20 }, // LDO9 +{ 2500, 50, 0x0a, 0x1f, 0x4, kD1974_LDO10, kD1974_ACTIVE2, 0x40 }, // LDO10 +{ 1700, 50, 0x17, 0x1f, 0x0, kD1974_LDO11, kD1974_ACTIVE2, 0x80 }, // LDO11 +{ 600, 25, 0x14, 0x1f, 0x0, kD1974_LDO12, kD1974_ACTIVE3, 0x01 }, // LDO12 +{ 5000, 50, 0x0c, 0x1f, 0x0, kD1974_LCM_CONTROL1, kD1974_ACTIVE3, 0x04 }, // LCM1_LDO +{ 5000, 50, 0x05, 0x1f, 0x0, kD1974_LCM_CONTROL2, kD1974_ACTIVE3, 0x08 }, // LCM2_LDO +{ 5000, 50, 0x00, 0x1f, 0x0, kD1974_LCM_CONTROL3, kD1974_ACTIVE3, 0x10 }, // LCM3_LDO +{ 5000, 50, 0x1f, 0x1f, 0x0, kD1974_LCM_BST_CONTROL, kD1974_ACTIVE3, 0x02 }, // LCM_BOOST +{ 0, 0, 0, 0, 0x0, 0, kD1974_ACTIVE3, 0x20 }, // 17 - WLED_BST_EN +{ 0, 0, 0, 0, 0x0, 0, kD1974_ACTIVE4, 0x10 }, // 18 - DSP_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1974_ACTIVE4, 0x20 }, // 19 - CPU1V2_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1974_ACTIVE4, 0x40 }, // 20 - WDIG_EN +{ 0, 0, 0, 0, 0x0, 0, kD1974_ACTIVE4, 0x80 }, // 21 - CPU1V8_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD1974_HIBERNATE1, 0x20 }, // 22 - set LDO1_EN in HIB +{ 0, 0, 0, 0, 0x0, 0, kD1974_HIBERNATE2, 0x04 }, // 23 - set LDO6_EN in HIB +}; +#define LDOP ldo_1974 + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD1974_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD1974_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD1974_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD1974_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD1974_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD1974_BUTTON_DBL_BTN3_DBL_EN, +}; + diff --git a/drivers/dialog/pmu/d2018.h b/drivers/dialog/pmu/d2018.h new file mode 100644 index 0000000..5d7d0ec --- /dev/null +++ b/drivers/dialog/pmu/d2018.h @@ -0,0 +1,1049 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef __DIALOG_D2018_H +#define __DIALOG_D2018_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_REG_BANK 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_WLED 1 + +enum { + kDIALOG_ADDR_R = 0x79, + kDIALOG_ADDR_W = 0x78, + kDIALOG_REG_BYTES = 1, +}; + +enum { + kDIALOG_EVENT_COUNT = 10, + kDIALOG_STATUS_COUNT = 10, + kDIALOG_HIBERNATE_COUNT = 4, + kDIALOG_CHIPID_COUNT = 1, + kDIALOG_FAULTLOG_COUNT = 2, + kDIALOG_GPIO_COUNT = 17, +}; + +#include "dCommon.h" + +enum { + kDIALOG_BANK_COUNT = 3, + kDIALOG_BANK0_SHARED_COUNT = 0x59, +}; + +enum { + // Register Bank 0 + + kDIALOG_CHIP_ID = 0x00, + + kDIALOG_EVENT_A = 0x01, + kDIALOG_EVENT_B = 0x02, + kDIALOG_EVENT_C = 0x03, + kDIALOG_EVENT_D = 0x04, + kDIALOG_EVENT_E = 0x05, + kDIALOG_EVENT_F = 0x06, + kDIALOG_EVENT_G = 0x07, + kDIALOG_EVENT_H = 0x08, + kDIALOG_EVENT_I = 0x09, + kDIALOG_EVENT_J = 0x0a, + + kDIALOG_STATUS_A = 0x0b, + kDIALOG_STATUS_B = 0x0c, + kDIALOG_STATUS_C = 0x0d, + kDIALOG_STATUS_D = 0x0e, + kDIALOG_STATUS_E = 0x0f, + kDIALOG_STATUS_F = 0x10, + kDIALOG_STATUS_G = 0x11, + kDIALOG_STATUS_H = 0x12, + kDIALOG_STATUS_I = 0x13, + kDIALOG_STATUS_J = 0x14, + kDIALOG_STATUS_GPIO_1_8 = kDIALOG_STATUS_C, + kDIALOG_STATUS_GPIO_9_16 = kDIALOG_STATUS_D, + kDIALOG_STATUS_GPIO_17_24 = kDIALOG_STATUS_E, + + kDIALOG_IRQ_MASK_A = 0x15, + kDIALOG_IRQ_MASK_B = 0x16, + kDIALOG_IRQ_MASK_C = 0x17, + kDIALOG_IRQ_MASK_D = 0x18, + kDIALOG_IRQ_MASK_E = 0x19, + kDIALOG_IRQ_MASK_F = 0x1a, + kDIALOG_IRQ_MASK_G = 0x1b, + kDIALOG_IRQ_MASK_H = 0x1c, + kDIALOG_IRQ_MASK_I = 0x1d, + kDIALOG_IRQ_MASK_J = 0x1e, + + kDIALOG_SYS_CONTROL = 0x1f, + kDIALOG_SYS_CONTROL2 = 0x20, + + kDIALOG_FAULT_LOG = 0x21, + kDIALOG_FAULT_LOG2 = 0x22, // change from Amelia! + kDIALOG_BANKSEL = 0x23, // change from Amelia (was 22) + + kD2018_ACTIVE1 = 0x24, + kD2018_ACTIVE2 = 0x25, + kD2018_ACTIVE3 = 0x26, + kDIALOG_LCM_ACTIVE = kD2018_ACTIVE3, + kD2018_ACTIVE4 = 0x27, + kD2018_ACTIVE5 = 0x28, + kD2018_STANDBY1 = 0x29, + kDIALOG_STANDBY = kD2018_STANDBY1, + kD2018_HIBERNATE1 = 0x2a, + kD2018_HIBERNATE2 = 0x2b, + kD2018_HIBERNATE3 = 0x2c, + kD2018_HIBERNATE4 = 0x2d, + kD2018_HIBERNATE5 = 0x2e, + + kD2018_BUCK0 = 0x2f, + kDIALOG_BUCK0 = kD2018_BUCK0, + kD2018_BUCK2 = 0x30, + kDIALOG_BUCK2 = kD2018_BUCK2, + kD2018_BUCK3 = 0x31, + kD2018_BUCK4 = 0x32, + kD2018_BUCK5 = 0x33, + + kD2018_LDO1 = 0x34, + kD2018_LDO2 = 0x35, + kD2018_LDO3 = 0x36, + kD2018_LDO4 = 0x37, + kD2018_LDO5 = 0x38, + kD2018_LDO6 = 0x39, + kD2018_LDO7 = 0x3a, + kD2018_LDO8 = 0x3b, + kD2018_LDO9 = 0x3c, + kD2018_LDO10 = 0x3d, + kD2018_LDO11 = 0x3e, + kD2018_LDO12 = 0x3f, + kD2018_LDO16 = 0x40, + + kD2018_BUCK_DWI = 0x41, + kDIALOG_BUCK_DWI = kD2018_BUCK_DWI, + + kD2018_CHGBUCK_CTRL = 0x42, + kDIALOG_CHARGE_BUCK_CONTROL = kD2018_CHGBUCK_CTRL, + + kD2018_CHGLIN_CTRL_A = 0x43, + kD2018_CHGLIN_CTRL_B = 0x44, + kD2018_CHGLIN_CTRL_C = 0x45, + kD2018_CHGLIN_CTRL_D = 0x46, + kD2018_CHARGE_TIME = 0x47, + + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD2018_CHGLIN_CTRL_B, + kDIALOG_CHARGE_CONTROL_HIB = kD2018_CHGLIN_CTRL_A, + kDIALOG_CHARGE_CONTROL_TIME = kD2018_CHGLIN_CTRL_D, + kDIALOG_CHARGE_CONTROL_EN = kD2018_CHGLIN_CTRL_C, + kDIALOG_OTP_ISET_BAT = kD2018_CHGLIN_CTRL_A, // not a real OTP register + + + // GPADC Control Registers + kD2018_ADC_CONTROL = 0x48, + kDIALOG_ADC_CONTROL = kD2018_ADC_CONTROL, + kD2018_ADC_LSB = 0x49, + kDIALOG_ADC_LSB = kD2018_ADC_LSB, + kD2018_ADC_MSB = 0x4a, + kD2018_TEMP_CONTROL_1 = 0x4b, + kD2018_TEMP_CONTROL_2 = 0x4c, + kD2018_NTC_SHDN_EN = (1 << 4), + kD2018_AUTO_T_DEV = (1 << 3), + kD2018_ICHG_AVG = 0x4d, + kDIALOG_ICHG_AVG = kD2018_ICHG_AVG, + kD2018_VCC_MAIN_MON = 0x4e, + kD2018_ICHG_END = 0x4f, + kD2018_TBAT_0 = 0x50, + kD2018_ICHG_TBAT_0 = 0x51, + kDIALOG_ICHG_TBAT_0 = kD2018_ICHG_TBAT_0, + kD2018_TBAT_1 = 0x52, + kD2018_ICHG_TBAT_1 = 0x53, + kD2018_TBAT_2 = 0x54, + kD2018_ICHG_TBAT_2 = 0x55, + kD2018_TBAT_3 = 0x56, + kD2018_ICHG_TBAT_3 = 0x57, + kD2018_TBAT_4 = 0x58, + kD2018_ICHG_TBAT_4 = 0x59, + kD2018_TBAT_MAX = 0x5a, + kD2018_ICHG_TBAT_NUM = 5, + kDIALOG_ICHG_TBAT_NUM = kD2018_ICHG_TBAT_NUM, + kD2018_TJ_OFFSET_MSB = 0x5b, + kDIALOG_T_OFFSET_MSB = kD2018_TJ_OFFSET_MSB, + kD2018_TJ_OFFSET_LSB = 0x5c, + kDIALOG_T_OFFSET_LSB = kD2018_TJ_OFFSET_LSB, + kD2018_IVBUS_GAIN = 0x5d, + + // RTC Calendar and Alarm + kD2018_RTC_ALARM_A = 0x5e, + kD2018_RTC_ALARM_B = 0x5f, + kD2018_RTC_ALARM_C = 0x60, + kD2018_RTC_ALARM_D = 0x61, + kD2018_RTC_CONTROL = 0x62, + kD2018_RTC_TIMEZONE = 0x63, + kDIALOG_RTC_ALARM_A = kD2018_RTC_ALARM_A, + kDIALOG_RTC_CONTROL = kD2018_RTC_CONTROL, + + kD2018_SECOND_A = 0x64, + kD2018_SECOND_B = 0x65, + kD2018_SECOND_C = 0x66, + kD2018_SECOND_D = 0x67, + + kDIALOG_UPCOUNT_A = kD2018_SECOND_A, + + // GPIO Control registers + kD2018_SYS_GPIO_1 = 0x68, + kDIALOG_SYS_GPIO_REG_START = kD2018_SYS_GPIO_1, + kD2018_SYS_GPIO_2 = 0x69, + kD2018_SYS_GPIO_3 = 0x6a, + kD2018_SYS_GPIO_4 = 0x6b, + kD2018_SYS_GPIO_5 = 0x6c, + kD2018_SYS_GPIO_6 = 0x6d, + kD2018_SYS_GPIO_7 = 0x6e, + kD2018_SYS_GPIO_8 = 0x6f, + kD2018_SYS_GPIO_9 = 0x70, + kD2018_SYS_GPIO_10 = 0x71, + kD2018_SYS_GPIO_11 = 0x72, + kD2018_SYS_GPIO_12 = 0x73, + kD2018_SYS_GPIO_13 = 0x74, + kD2018_SYS_GPIO_14 = 0x75, + kD2018_SYS_GPIO_15 = 0x76, + kD2018_SYS_GPIO_16 = 0x77, + kD2018_SYS_GPIO_17 = 0x78, + kD2018_SYS_GPIO_DEB1 = 0x79, + kD2018_SYS_GPIO_DEB2 = 0x7a, + kD2018_SYS_GPIO_DEB3 = 0x7b, + kD2018_SYS_GPIO_DEB4 = 0x7c, + kD2018_SYS_GPIO_DEB5 = 0x7d, + kD2018_SYS_GPIO_DEB6 = 0x7e, + kD2018_SYS_GPIO_DEB7 = 0x7f, + kD2018_SYS_GPIO_DEB8 = 0x80, + kD2018_SYS_GPIO_DEB9 = 0x81, + + // Special LDO control Register + kDIALOG_LDO_CONTROL = 0x82, + + // GPI Control registers + kD2018_BUTTON1 = 0x83, + kD2018_BUTTON2 = 0x84, + kD2018_BUTTON3 = 0x85, + kD2018_SYS_CONFIG = 0x86, + kDIALOG_SYS_CONFIG = kD2018_SYS_CONFIG, + + // LCM BOOST Control Registers + kD2018_LCM_CONTROL1 = 0x87, + kD2018_LCM_CONTROL2 = 0x88, + kD2018_LCM_CONTROL3 = 0x89, + kD2018_LCM_BST_CONTROL = 0x8a, + kDIALOG_LCM_BOOST = kD2018_LCM_BST_CONTROL, + + // TEMP Sensors Control registers + kD2018_TDEV1_RISE = 0x8b, + kD2018_TDEV1_FALL = 0x8c, + kD2018_TDEV2_RISE = 0x8d, + kD2018_TDEV2_FALL = 0x8e, + kD2018_TDEV3_RISE = 0x8f, + kD2018_TDEV3_FALL = 0x90, + kD2018_TDEV4_RISE = 0x91, + kD2018_TDEV4_FALL = 0x92, + kD2018_TDEV5_RISE = 0x93, + kD2018_TDEV5_FALL = 0x94, + kD2018_TDEV6_RISE = 0x95, + kD2018_TDEV6_FALL = 0x96, + kD2018_TDEV7_RISE = 0x97, + kD2018_TDEV7_FALL = 0x98, + kD2018_TDEV8_RISE = 0x90, + kD2018_TDEV8_FALL = 0x9a, + kD2018_TBUCK_5_RISE = 0x9b, + kD2018_TLDO9_RISE = 0x9c, + kD2018_OTP_SPARE_BANK0 = 0x9d, + kD2018_TBUCK_A_RISE = 0x9e, + kD2018_TCHG_RISE = 0x9f, + kD2018_TBUCK_0_RISE = 0xa0, + kD2018_TBUCK_2_RISE = 0xa1, + kD2018_TBUCK_3_RISE = 0xa2, + kD2018_TBUCK_4_RISE = 0xa3, + kD2018_TCBUCK_B_RISE = 0xa4, + kD2018_TISENSE_HYST = 0xa5, + + // Special function registers + kD2018_BUCK3_HIB = 0xa6, + kD2018_BUCK4_HIB = 0xa7, + kD2018_GPIO_SOFTHIB1 = 0xa8, + kD2018_GPIO_SOFTHIB2 = 0xa9, + kD2018_GPIO_SOFTHIB3 = 0xaa, + kD2018_BUTTON_DBL = 0xab, + kDIALOG_BUTTON_DBL = kD2018_BUTTON_DBL, + + // Scratch Pads + kD2018_MEMBYTE0 = 0xac, + kDIALOG_MEMBYTE0 = kD2018_MEMBYTE0, + kDIALOG_MEMBYTE_LAST = 0xd3, + // Dialog Reserved Spare (0xd4-0xd7) + + // WLED Dither and Ramping control + kD2018_WLED_ISET = 0xd8, + kD2018_WLED_ISET2 = 0xd9, + kD2018_WLED_PWM_MSB = 0xda, + kD2018_WLED_PWM_LSB = 0xdb, + kD2018_WLED_CONTROL = 0xdc, + kD2018_WLED_CONTROL2 = 0xdd, + kDIALOG_WLED_ISET = kD2018_WLED_ISET, + kDIALOG_WLED_ISET2 = kD2018_WLED_ISET2, + kDIALOG_WLED_CONTROL = kD2018_WLED_CONTROL, + kDIALOG_WLED_CONTROL2 = kD2018_WLED_CONTROL2, + kDIALOG_WLED_DWI_CONTROL= kD2018_WLED_CONTROL2, + kDIALOG_WLED_OPTIONS = kD2018_WLED_CONTROL2, + + // Register Bank 1 (TRIM & CONFIG) + kD2018_TRIM_CONF102 = 0x1f6, + kD2018_IVBUS_OFFS = kD2018_TRIM_CONF102, + + // Bank 1 Test Registers + kD2018_WLED_CONTROL4 = 0x89, + kD2018_BUCK_CONTROL1 = 0xb8, + kD2018_BUCK_CONTROL3 = 0xba, + kD2018_TRIM_CONF68 = 0xd0, + + // Bank 2 Test Registers + kD2018_TEST_MODE = 0xd4, + + // Register Bank 2 (BIST) + + kD2018_APP_TMUX = 0x2bc, + kD2018_BIST_ADC_CTRL = 0x2bd, + kDIALOG_BIST_ADC_CTRL = kD2018_BIST_ADC_CTRL, + kD2018_BADC_MAN1 = 0x2be, + kD2018_BADC_MAN2 = 0x2bf, + kD2018_BIST_ADC0 = 0x2c0, + kDIALOG_BIST_ADC_LSB = kD2018_BADC_MAN1, + kDIALOG_BIST_ADC_MSB = kD2018_BADC_MAN2, +}; + +enum { + kD2018_CHIP_ID_MRC_MASK = (0xf << 0), + kD2018_CHIP_ID_MRC_A0 = 0x08, + + kD2018_CHIP_ID_TRC_MASK = (0x0f << 4), +}; + +enum { + kD2018_EVENT_A_BUTTON1 = (1 << 0), + kD2018_EVENT_A_BUTTON2 = (1 << 1), + kD2018_EVENT_A_BUTTON3 = (1 << 2), + kD2018_EVENT_A_VCENTER_DET = (1 << 3), + kD2018_EVENT_A_FW_DET = (1 << 4), + kD2018_EVENT_A_ACC_DET = (1 << 5), + kD2018_EVENT_A_VBUS_EXT_DET = (1 << 6), + kD2018_EVENT_A_VDD_LOW = (1 << 7), +}; + +// EVENT_B events are assumed volatile (lost over sleep/wake) +enum { + kD2018_EVENT_B_CHG_PRE = (1 << 1), + kD2018_EVENT_B_CHG_FAST = (1 << 2), + kD2018_EVENT_B_CHG_END = (1 << 3), + kD2018_EVENT_B_TBAT = (1 << 4), + kD2018_EVENT_B_FW_OV = (1 << 6), + kDIALOG_EVENT_B_HIB = (1 << 7), +}; + +enum { + kD2018_EVENT_C_GPIO1 = (1 << 0), + kD2018_EVENT_C_GPIO2 = (1 << 1), + kD2018_EVENT_C_GPIO3 = (1 << 2), + kD2018_EVENT_C_GPIO4 = (1 << 3), + kD2018_EVENT_C_GPIO5 = (1 << 4), + kD2018_EVENT_C_GPIO6 = (1 << 5), + kD2018_EVENT_C_GPIO7 = (1 << 6), + kD2018_EVENT_C_GPIO8 = (1 << 7), +}; + +enum { + kD2018_EVENT_D_GPIO9 = (1 << 0), + kD2018_EVENT_D_GPIO10 = (1 << 1), + kD2018_EVENT_D_GPIO11 = (1 << 2), + kD2018_EVENT_D_GPIO12 = (1 << 3), + kD2018_EVENT_D_GPIO13 = (1 << 4), + kD2018_EVENT_D_GPIO14 = (1 << 5), + kD2018_EVENT_D_GPIO15 = (1 << 6), + kD2018_EVENT_D_GPIO16 = (1 << 7), +}; + +enum { + kD2018_EVENT_E_GPIO17 = (1 << 0), + kD2018_EVENT_E_BTN1_DBL = (1 << 3), + kD2018_EVENT_E_BTN2_DBL = (1 << 4), + kD2018_EVENT_E_BTN3_DBL = (1 << 5), + kD2018_EVENT_E_CHG_BUCK_FLG = (1 << 6), + kD2018_EVENT_E_VBUS_OV = (1 << 7), +}; + +enum { + kD2018_EVENT_F_T1_FALL = (1 << 0), + kD2018_EVENT_F_T1_RISE = (1 << 1), + kD2018_EVENT_F_T2_FALL = (1 << 2), + kD2018_EVENT_F_T2_RISE = (1 << 3), + kD2018_EVENT_F_T3_FALL = (1 << 4), + kD2018_EVENT_F_T3_RISE = (1 << 5), + kD2018_EVENT_F_T4_FALL = (1 << 6), + kD2018_EVENT_F_T4_RISE = (1 << 7), +}; + +enum { + kD2018_EVENT_G_T5_FALL = (1 << 0), + kD2018_EVENT_G_T5_RISE = (1 << 1), + kD2018_EVENT_G_T6_FALL = (1 << 2), + kD2018_EVENT_G_T6_RISE = (1 << 3), + kD2018_EVENT_G_T7_FALL = (1 << 4), + kD2018_EVENT_G_T7_RISE = (1 << 5), + kD2018_EVENT_G_T8_FALL = (1 << 6), + kD2018_EVENT_G_T8_RISE = (1 << 7), +}; + +enum { + kD2018_EVENT_H_ALARM = (1 << 0), + kD2018_EVENT_H_FW_REM = (1 << 4), + kD2018_EVENT_H_VBUS_REM = (1 << 6), + kD2018_EVENT_H_ABCC_FLAG = (1 << 7), +}; + +enum { + kD2018_EVENT_I_TBUCK0 = (1 << 0), + kD2018_EVENT_I_TBUCK2 = (1 << 1), + kD2018_EVENT_I_TBUCK3 = (1 << 2), + kD2018_EVENT_I_TBUCK4 = (1 << 3), + kD2018_EVENT_I_TBUCK5 = (1 << 4), + kD2018_EVENT_I_TLDO9 = (1 << 5), + kD2018_EVENT_I_TCHGBUCK_A = (1 << 6), + kD2018_EVENT_I_TCHGBUCK_B = (1 << 7), +}; + +enum { + kD2018_EVENT_J_TCHG_LIN = (1 << 0), + kD2018_EVENT_J_DWI_TO = (1 << 1), + kD2018_EVENT_J_EOMC = (1 << 2), + kD2018_EVENT_J_DPHP_DET = (1 << 4), +}; + +enum { + kD2018_STATUS_A_BUTTON1 = (1 << 0), + kD2018_STATUS_A_BUTTON2 = (1 << 1), + kD2018_STATUS_A_BUTTON3 = (1 << 2), + kD2018_STATUS_A_VCENTER_DET = (1 << 3), + kD2018_STATUS_A_FW_DET = (1 << 4), + kD2018_STATUS_A_ACC_DET = (1 << 5), + kD2018_STATUS_A_VBUS_EXT_DET = (1 << 6), + kD2018_STATUS_A_VDD_LOW = (1 << 7), +}; + +enum { + kD2018_STATUS_B_CHG_ATT = (1 << 0), + kD2018_STATUS_B_CHG_PRE = (1 << 1), + kD2018_STATUS_B_CHG_FAST = (1 << 2), + kD2018_STATUS_B_CHG_END = (1 << 3), + kD2018_STATUS_B_TBAT = (1 << 4), + kD2018_STATUS_B_CHG_TO = (1 << 5), + kD2018_STATUS_B_FW_OV = (1 << 6), +}; + +enum { + kD2018_STATUS_C_GPIO1 = (1 << 0), + kD2018_STATUS_C_GPIO2 = (1 << 1), + kD2018_STATUS_C_GPIO3 = (1 << 2), + kD2018_STATUS_C_GPIO4 = (1 << 3), + kD2018_STATUS_C_GPIO5 = (1 << 4), + kD2018_STATUS_C_GPIO6 = (1 << 5), + kD2018_STATUS_C_GPIO7 = (1 << 6), + kD2018_STATUS_C_GPIO8 = (1 << 7), +}; + +enum { + kD2018_STATUS_D_GPIO9 = (1 << 0), + kD2018_STATUS_D_GPIO10 = (1 << 1), + kD2018_STATUS_D_GPIO11 = (1 << 2), + kD2018_STATUS_D_GPIO12 = (1 << 3), + kD2018_STATUS_D_GPIO13 = (1 << 4), + kD2018_STATUS_D_GPIO14 = (1 << 5), + kD2018_STATUS_D_GPIO15 = (1 << 6), + kD2018_STATUS_D_GPIO16 = (1 << 7), +}; + +enum { + kD2018_STATUS_E_GPIO17 = (1 << 0), + kD2018_STATUS_E_CPUB_EN = (1 << 1), + kD2018_STATUS_E_CPUA_EN = (1 << 2), + kD2018_STATUS_E_CHG_BUCK_FLG = (1 << 6), + kD2018_STATUS_E_VBUS_OV = (1 << 7), +}; + +enum { + kD2018_STATUS_F_T1_FALL = (1 << 0), + kD2018_STATUS_F_T1_RISE = (1 << 1), + kD2018_STATUS_F_T2_FALL = (1 << 2), + kD2018_STATUS_F_T2_RISE = (1 << 3), + kD2018_STATUS_F_T3_FALL = (1 << 4), + kD2018_STATUS_F_T3_RISE = (1 << 5), + kD2018_STATUS_F_T4_FALL = (1 << 6), + kD2018_STATUS_F_T4_RISE = (1 << 7), +}; + +enum { + kD2018_STATUS_G_T5_FALL = (1 << 0), + kD2018_STATUS_G_T5_RISE = (1 << 1), + kD2018_STATUS_G_T6_FALL = (1 << 2), + kD2018_STATUS_G_T6_RISE = (1 << 3), + kD2018_STATUS_G_T7_FALL = (1 << 4), + kD2018_STATUS_G_T7_RISE = (1 << 5), + kD2018_STATUS_G_T8_FALL = (1 << 6), + kD2018_STATUS_G_T8_RISE = (1 << 7), +}; + +enum { + kD2018_STATUS_H_VBUS_OC = (1 << 2), + kD2018_STATUS_H_ABCC_FLAG = (1 << 7), +}; + +enum { + kD2018_STATUS_I_TBUCK0 = (1 << 0), + kD2018_STATUS_I_TBUCK2 = (1 << 1), + kD2018_STATUS_I_TBUCK3 = (1 << 2), + kD2018_STATUS_I_TBUCK4 = (1 << 3), + kD2018_STATUS_I_TBUCK5 = (1 << 4), + kD2018_STATUS_I_TLDO9 = (1 << 5), + kD2018_STATUS_I_TCHGBUCK_A = (1 << 6), + kD2018_STATUS_I_TCHGBUCK_B = (1 << 7), +}; + +enum { + kD2018_STATUS_J_TCHG_LIN = (1 << 0), + kD2018_STATUS_J_PROT_FET_ON = (1 << 3), + kD2018_STATUS_J_DPHP_DET = (1 << 4), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD2018_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(0, kD2018_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(0, kD2018_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS = (kD2018_EVENT_A_BUTTON2 | + kD2018_EVENT_A_BUTTON1 | + kD2018_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(0, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(7, kD2018_EVENT_H_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD2018_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD2018_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VHP_DET_MASK = EVENT_FLAG_MAKE(0, kD2018_STATUS_A_FW_DET), + kDIALOG_EVENT_VBUS_REM_MASK = EVENT_FLAG_MAKE(7, kD2018_EVENT_H_VBUS_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(9, kD2018_EVENT_J_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_B_HIB), + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(7, kD2018_EVENT_H_ABCC_FLAG), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(1, kD2018_EVENT_B_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(1, kD2018_EVENT_B_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(2, kD2018_EVENT_C_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(3, kD2018_EVENT_D_GPIO16), + kDIALOG_EVENT_GPIO17_MASK = EVENT_FLAG_MAKE(4, kD2018_EVENT_E_GPIO17), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(4, kD2018_EVENT_E_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(4, kD2018_EVENT_E_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(4, kD2018_EVENT_E_BTN3_DBL), + + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD2018_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD2018_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = STATUS_FLAG_MAKE(0, kD2018_STATUS_A_FW_DET), + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD2018_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(1, kD2018_STATUS_B_CHG_PRE | kD2018_STATUS_B_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(1, kD2018_STATUS_B_CHG_TO), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD2018_STATUS_B_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(1, kD2018_STATUS_B_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(1, kD2018_STATUS_B_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(7, kD2018_STATUS_H_ABCC_FLAG), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(2 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {kD2018_STATUS_A_FW_DET, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD2018_STATUS_B_CHG_PRE | kD2018_STATUS_B_CHG_FAST, 0, 0, 0, 0}; + +enum { + kD2018_EVENT_A_WAKEMASK = (kD2018_EVENT_A_BUTTON1 | + kD2018_EVENT_A_BUTTON2 | + kD2018_EVENT_A_BUTTON3 | + kD2018_EVENT_A_VBUS_EXT_DET | + kD2018_STATUS_A_FW_DET | + kD2018_EVENT_A_ACC_DET), + kD2018_EVENT_B_WAKEMASK = 0, + kD2018_EVENT_C_WAKEMASK = 0, + kD2018_EVENT_D_WAKEMASK = 0, + kD2018_EVENT_E_WAKEMASK = 0, + kD2018_EVENT_F_WAKEMASK = 0, + kD2018_EVENT_G_WAKEMASK = 0, + kD2018_EVENT_H_WAKEMASK = (kD2018_EVENT_H_ALARM | + kD2018_EVENT_H_FW_REM | + kD2018_EVENT_H_VBUS_REM), + kD2018_EVENT_I_WAKEMASK = 0, + kD2018_EVENT_J_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2018_EVENT_A_WAKEMASK, + ~kD2018_EVENT_B_WAKEMASK, + ~kD2018_EVENT_C_WAKEMASK, + ~kD2018_EVENT_D_WAKEMASK, + ~kD2018_EVENT_E_WAKEMASK, + ~kD2018_EVENT_F_WAKEMASK, + ~kD2018_EVENT_G_WAKEMASK, + ~kD2018_EVENT_H_WAKEMASK, + ~kD2018_EVENT_I_WAKEMASK, + ~kD2018_EVENT_J_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2018_EVENT_A_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD2018_EVENT_B_WAKEMASK, + kD2018_EVENT_C_WAKEMASK, + kD2018_EVENT_D_WAKEMASK, + kD2018_EVENT_E_WAKEMASK, + kD2018_EVENT_F_WAKEMASK, + kD2018_EVENT_G_WAKEMASK, + kD2018_EVENT_H_WAKEMASK, + kD2018_EVENT_I_WAKEMASK, + kD2018_EVENT_J_WAKEMASK, +}; + +// All events that defer shutdown +static const eventRegisters kDialogEventRestartMask = { + EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_HOLD_BUTTON_MASK, 0) | EVENT_FLAG_GET_BIT_FOR_BYTE(kDIALOG_EVENT_ACC_DET_MASK, 0), + 0, + 0, + 0, + 0, + 0, + 0, + kD2018_EVENT_H_ALARM, + 0, + 0, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD2018_EVENT_A_VBUS_EXT_DET | kD2018_EVENT_A_FW_DET | kD2018_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + kD2018_EVENT_H_FW_REM | kD2018_EVENT_H_VBUS_REM, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD2018_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + kD2018_EVENT_H_ABCC_FLAG, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + kD2018_EVENT_A_FW_DET, + 0, + 0, + 0, + 0, + 0, + 0, + kD2018_EVENT_H_FW_REM, + 0, + 0, +}; + +// XXXKW +enum { + kDialogEventPwrsupplyCount = 5, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 2, +}; + +enum { + kDIALOG_LCM_ACTIVE_BOOST_EN = (1 << 1), + kDIALOG_LCM_ACTIVE_MASK = (1 << 2) | (1 << 3) | (1 << 4), +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_SOFT_HIB = (1 << 3), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PRO_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), +}; + +enum { + kDIALOG_FAULT_LOG_NTC_SHDN = FAULTLOG_FLAG_MAKE(0, (1 << 7)), + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_BOOST = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + + kDIALOG_FAULT_LOG_LDO6_BACKPOW = FAULTLOG_FLAG_MAKE(1, (1 << 0)), + + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_BUCK_DWI_BUCK0 = (1 << 0), + kDIALOG_BUCK_DWI_BUCK1 = (1 << 1), + kDIALOG_BUCK_DWI_BUCK2 = (1 << 2), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x02, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_250 = 0xe, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300 = 0x12, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_350 = 0x16, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 0x1a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x22, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 0x2a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 0x32, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_750 = 0x36, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 0x42, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_975 = 0x48, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x4a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1450 = 0x6e, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500 = 0x72, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1900 = 0x92, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0x9a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100 = 0xa2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2200 = 0xaa, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2300 = 0xb2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 75, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 8, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 3262, +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_A_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_A_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_A_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 50, + kDIALOG_CHARGE_CONTROL_MAX = 3150, +}; + +enum { + kDIALOG_CHARGE_CONTROL_C_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN = (1 << 7), + + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = kDIALOG_CHARGE_CONTROL_C_ALT_USB_DIS, + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_VBUS_CHG_BUCK_EN = kDIALOG_CHARGE_CONTROL_C_CHG_BUCK_EN, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 9, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS_OFF = (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBAT_OUT_OFF= (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK5_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO9_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_B_TEMP= (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (26 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP = (27 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP = (28 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP = (29 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP= (30 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK5_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN31 = (31 << 0), + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 6), + kDIALOG_ADC_CONTROL_ADC_REF_EN = (1 << 7), + kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN = 0, // NOT present on Adriana +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (0x00 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (0x01 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (0x02 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (0x03 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (0x04 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (0x05 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (0x06 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (0x07 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (0x08 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (0x09 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (0x0a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (0x0b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (0x0c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (0x0d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (0x0e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (0x0f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (0x10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (0x11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (0x12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10 = (0x13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (0x14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11 = (0x15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (0x16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO12 = (0x17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM1 = (0x18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM1 = (0x19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM2 = (0x1a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM2 = (0x1b << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM3 = (0x1c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM3 = (0x1d << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (0x1e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (0x1f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUF_ON = (0x20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IBUF_ON = (0x21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0 = (0x22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_WLEDB = (0x24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (0x26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (0x28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (0x2a << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_WLEDA = (0x2c << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBOOST_LCM = (0x2e << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (0x30 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (0x32 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK5 = (0x34 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO16 = (0x36 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO16 = (0x37 << 0), + kDIALOG_BIST_ADC_CTRL_AUTO_RUN = (1 << 6), + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (15 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_ENABLE3 = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_ENABLE4 = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_ENABLE5 = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_ENABLE6 = (1 << 5), +}; + +enum { + kDIALOG_WLED_CONTROL2_WLED_RAMP_EN = (1 << 2), + kDIALOG_WLED_CONTROL2_WLED_DWI_EN = (1 << 3), + kDIALOG_WLED_CONTROL2_WLED_DITH_EN = (1 << 4), + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN = (1 << 5), + + kDIALOG_WLED_CONTROL_WLED_DWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL2_WLED_DITH_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS (11) + +#define NUM_LDOS 23 +static const struct ldo_params ldo_2018[NUM_LDOS] = { +{ 2500, 50, 0x15, 0x1f, 0x1, kD2018_LDO1, kD2018_ACTIVE1, 0x80 }, // LDO1 +{ 1650, 5, 0x1f, 0x1f, 0x0, kD2018_LDO2, kD2018_ACTIVE2, 0x01 }, // LDO2 +{ 2500, 50, 0x10, 0x1f, 0x0, kD2018_LDO3, kD2018_ACTIVE2, 0x02 }, // LDO3 +{ 1800, 50, 0x1e, 0x1f, 0x0, kD2018_LDO4, kD2018_ACTIVE2, 0x04 }, // LDO4 +{ 2500, 50, 0x16, 0x1f, 0x0, kD2018_LDO5, kD2018_ACTIVE2, 0x08 }, // LDO5 +{ 2500, 50, 0x16, 0x1f, 0x2, kD2018_LDO6, kD2018_ACTIVE2, 0x10 }, // LDO6 +{ 1500, 100,0x16, 0x1f, 0x0, kD2018_LDO7, kD2018_ACTIVE2, 0x20 }, // LDO7 +{ 2000, 50, 0x1f, 0x1f, 0x0, kD2018_LDO8, kD2018_ACTIVE2, 0x40 }, // LDO8 +{ 1200, 100,0x12, 0x1f, 0x0, kD2018_LDO9, kD2018_ACTIVE2, 0x80 }, // LDO9 +{ 2500, 50, 0x15, 0x1f, 0x4, kD2018_LDO10, kD2018_ACTIVE3, 0x01 }, // LDO10 +{ 1700, 50, 0x1a, 0x1f, 0x0, kD2018_LDO11, kD2018_ACTIVE3, 0x02 }, // LDO11 +{ 600, 25, 0x1c, 0x1f, 0x0, kD2018_LDO12, kD2018_ACTIVE3, 0x04 }, // LDO12 +{ 5000, 50, 0x1f, 0x1f, 0x0, kD2018_LCM_CONTROL1, kD2018_ACTIVE3, 0x08 }, // LDO13 / LCM1_LDO +{ 5000, 50, 0x1f, 0x1f, 0x0, kD2018_LCM_CONTROL2, kD2018_ACTIVE3, 0x10 }, // LDO14 / LCM2_LDO +{ 5000, 50, 0x1f, 0x1f, 0x0, kD2018_LCM_CONTROL3, kD2018_ACTIVE3, 0x20 }, // LDO15 / LCM3_LDO +{ 5000, 50, 0x1f, 0x1f, 0x0, kD2018_LDO16, kD2018_ACTIVE3, 0x40 }, // LDO16 // NEW +{ 5000, 50, 0x1f, 0x1f, 0x0, kD2018_LCM_BST_CONTROL, kD2018_ACTIVE4, 0x02 }, // 17 - LCM_BOOST // MOVED +{ 0, 0, 0, 0, 0x0, 0, kD2018_ACTIVE5, 0x20 }, // 18 - WLED_BST_EN // MOVED +{ 0, 0, 0, 0, 0x0, 0, kD2018_ACTIVE4, 0x20 }, // 19 - CPU1V2_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD2018_ACTIVE4, 0x40 }, // 20 - WDIG_EN +{ 0, 0, 0, 0, 0x0, 0, kD2018_ACTIVE4, 0x80 }, // 21 - CPU1V8_SW_EN +{ 0, 0, 0, 0, 0x0, 0, kD2018_HIBERNATE1, 0x80 }, // 22 - set LDO1_EN in HIB +{ 0, 0, 0, 0, 0x0, 0, kD2018_HIBERNATE2, 0x10 }, // 23 - set LDO6_EN in HIB +}; +#define LDOP ldo_2018 + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_DWI_BUCK0_DWI_EN = (1 << 0), + kDIALOG_DWI_BUCK2_DWI_EN = (1 << 1), + kDIALOG_DWI_LDO16_DWI_EN = (1 << 4), + kDIALOG_DWI_CPUA_EN_CTRL = (1 << 6), + kDIALOG_DWI_CPUB_EN_CTRL = (1 << 7) +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD2018_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD2018_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD2018_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD2018_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD2018_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD2018_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif diff --git a/drivers/dialog/pmu/d2045.h b/drivers/dialog/pmu/d2045.h new file mode 100644 index 0000000..53a824a --- /dev/null +++ b/drivers/dialog/pmu/d2045.h @@ -0,0 +1,1217 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D2045_H +#define __DIALOG_D2045_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_LCM_LDO 0 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_VIB 1 +#define PMU_HAS_RAM 1 +#define PMU_HAS_WLED 0 +#define PMU_HAS_32K_RTC 1 +#define PMU_HAS_ACCUMULATORS 1 + +enum { + kDIALOG_ADDR_R = 0xe9, + kDIALOG_ADDR_W = 0xe8, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_EVENT_COUNT = 12, + kDIALOG_STATUS_COUNT = 13, + kDIALOG_FAULTLOG_COUNT = 2, + kDIALOG_CHIPID_COUNT = 4, + kDIALOG_GPIO_COUNT = 16, +}; + +#include "dCommon.h" + +enum { + kDIALOG_MASK_REV_CODE = 0x0000, + kDIALOG_TRIM_REL_CODE = 0x0001, + kDIALOG_PLATFORM_ID = 0x0002, + kDIALOG_DEVICE_ID1 = 0x0004, + kDIALOG_DEVICE_ID2 = 0x0005, + kDIALOG_DEVICE_ID3 = 0x0006, + kDIALOG_DEVICE_ID4 = 0x0007, + kDIALOG_DEVICE_ID5 = 0x0008, + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, + + kDIALOG_SYS_CONTROL = 0x0010, + kDIALOG_SYS_CONTROL2 = 0x0011, + + kDIALOG_SYS_CONFIG = 0x0020, + kD2045_SYS_CONF_B = 0x0021, + kD2045_SYS_CONF_C = 0x0022, + kD2045_SYS_CONF_D = 0x0023, + kD2045_BG_TRIM = 0x0024, + kD2045_BG_TC_ADC = 0x0025, + kD2045_VREF_RTC_TRIM = 0x0026, + kD2045_VREF_AUX_TRIM = 0x0027, + kD2045_VDD_FAULT = 0x0028, + kD2045_RTC_CTRL0 = 0x0029, + kD2045_RTC_CTRL1 = 0x002a, + kD2045_OSC_CTRL0 = 0x002b, + kD2045_INT_OSC_TRIM = 0x002c, + kD2045_CLK_REQ_FRC = 0x002d, + + kDIALOG_FAULT_LOG = 0x0040, + kDIALOG_FAULT_LOG2 = 0x0041, + + kDIALOG_EVENT_A = 0x0050, + kDIALOG_EVENT_B = 0x0051, + kDIALOG_EVENT_C = 0x0052, + kDIALOG_EVENT_D = 0x0053, + kDIALOG_EVENT_E = 0x0054, + kDIALOG_EVENT_F = 0x0055, + kDIALOG_EVENT_G = 0x0056, + kDIALOG_EVENT_H = 0x0057, + kDIALOG_EVENT_I = 0x0058, + kDIALOG_EVENT_J = 0x0059, + kDIALOG_EVENT_K = 0x005a, + kDIALOG_EVENT_L = 0x005b, + + kDIALOG_STATUS_A = 0x0060, + kDIALOG_STATUS_B = 0x0061, + kDIALOG_STATUS_C = 0x0062, + kDIALOG_STATUS_D = 0x0063, + kDIALOG_STATUS_E = 0x0064, + kDIALOG_STATUS_F = 0x0065, + kDIALOG_STATUS_G = 0x0066, + kDIALOG_STATUS_H = 0x0067, + kDIALOG_STATUS_I = 0x0068, + kDIALOG_STATUS_J = 0x0069, + kDIALOG_STATUS_K = 0x006a, + kDIALOG_STATUS_L = 0x006b, + kDIALOG_STATUS_M = 0x006c, + + kDIALOG_IRQ_MASK_A = 0x0070, + kDIALOG_IRQ_MASK_B = 0x0071, + kDIALOG_IRQ_MASK_C = 0x0072, + kDIALOG_IRQ_MASK_D = 0x0073, + kDIALOG_IRQ_MASK_E = 0x0074, + kDIALOG_IRQ_MASK_F = 0x0075, + kDIALOG_IRQ_MASK_G = 0x0076, + kDIALOG_IRQ_MASK_H = 0x0077, + kDIALOG_IRQ_MASK_I = 0x0078, + kDIALOG_IRQ_MASK_J = 0x0079, + kDIALOG_IRQ_MASK_K = 0x007A, + kDIALOG_IRQ_MASK_L = 0x007B, + + kD2045_ACTIVE1 = 0x0080, + kD2045_ACTIVE2 = 0x0081, + kD2045_ACTIVE3 = 0x0082, + kD2045_ACTIVE4 = 0x0083, + kD2045_ACTIVE5 = 0x0084, + kD2045_ACTIVE6 = 0x0085, + kD2045_ACTIVE7 = 0x0086, + kD2045_STANDBY1 = 0x0088, + kD2045_STANDBY3 = 0x008a, + kD2045_STANDBY4 = 0x008b, + kD2045_STANDBY6 = 0x008d, + kD2045_STANDBY7 = 0x008e, + kD2045_HIBERNATE1 = 0x0090, + kD2045_HIBERNATE3 = 0x0092, + kD2045_HIBERNATE4 = 0x0093, + kD2045_HIBERNATE6 = 0x0095, + kD2045_HIBERNATE7 = 0x0096, + + kD2045_SLOT_TIMINGS = 0x00a0, + kD2045_ACT_TO_HIB_DLY = 0x00a1, + kD2045_BUCK0_SLOT = 0x00b0, + kD2045_BUCK1_SLOT = 0x00b1, + kD2045_BUCK2_SLOT = 0x00b2, + kD2045_BUCK3_SLOT = 0x00b3, + kD2045_BUCK4_SLOT = 0x00b4, + kD2045_BUCK5_SLOT = 0x00b5, + kD2045_LDO1_SLOT = 0x00c1, + kD2045_LDO2_SLOT = 0x00c2, + kD2045_LDO3_SLOT = 0x00c3, + kD2045_LDO4_SLOT = 0x00c4, + kD2045_LDO5_SLOT = 0x00c5, + kD2045_LDO6_SLOT = 0x00c6, + kD2045_LDO7_SLOT = 0x00c7, + kD2045_LDO8_SLOT = 0x00c8, + kD2045_LDO9_SLOT = 0x00c9, + kD2045_LDO10_SLOT = 0x00ca, + kD2045_LDO11_SLOT = 0x00cb, + kD2045_LDO12_SLOT = 0x00cc, + kD2045_LDO13_SLOT = 0x00cd, + kD2045_CHARGE_PUMP_SLOT = 0x00d8, + kD2045_BUCK3_SW1_SLOT = 0x00d9, + kD2045_BUCK3_SW2_SLOT = 0x00da, + kD2045_BUCK3_SW3_SLOT = 0x00db, + kD2045_BUCK4_SW1_SLOT = 0x00dc, + kD2045_BUCK4_SW2_SLOT = 0x00dd, + + kD2045_BUCK_DWI_CTRL0 = 0x00f0, + kD2045_BUCK_DWI_TRIM0 = 0x00f2, + kD2045_BUCK_FSM_TRIM0 = 0x00f4, + kD2045_BUCK_FSM_TRIM1 = 0x00f5, + kD2045_BUCK_CALIB_OFFSET_TRIM = 0x00f6, + + kD2045_BUCK0_VSEL = 0x0100, + kD2045_BUCK0_VSEL_ACTUAL = 0x0102, + kD2045_BUCK0_MINV = 0x0103, + kD2045_BUCK0_MAXV = 0x0104, + kD2045_BUCK0_OFS_V = 0x0105, + kD2045_BUCK0_MODE = 0x0106, + kD2045_BUCK0_START_ILIMIT = 0x0107, + kD2045_BUCK0_SYNC_ILIMIT = 0x0108, + kD2045_BUCK0_SLEEP_ILIMIT = 0x0109, + kD2045_BUCK0_FSM_TRIM0 = 0x010a, + kD2045_BUCK0_FSM_TRIM1 = 0x010b, + kD2045_BUCK0_FSM_TRIM2 = 0x010c, + kD2045_BUCK0_FSM_TRIM3 = 0x010d, + kD2045_BUCK0_CLK_TRIM = 0x010e, + kD2045_BUCK0_CALIB0 = 0x0110, + kD2045_BUCK0_CALIB1 = 0x0111, + kD2045_BUCK0_ANA_TRIM0 = 0x0112, + kD2045_BUCK0_ANA_TRIM1 = 0x0113, + kD2045_BUCK0_ANA_TRIM2 = 0x0114, + kD2045_BUCK0_ANA_TRIM3 = 0x0115, + kD2045_BUCK0_ANA_TRIM4 = 0x0116, + kD2045_BUCK0_ANA_TRIM5 = 0x0117, + kD2045_BUCK0_ANA_TRIM6 = 0x0118, + kD2045_BUCK0_ANA_TRIM7 = 0x0119, + kD2045_BUCK0_ANA_TRIM8 = 0x011a, + kD2045_BUCK0_ANA_TRIM9 = 0x011b, + kD2045_BUCK1_VSEL = 0x0120, + kD2045_BUCK1_VSEL_ACTUAL = 0x0122, + kD2045_BUCK1_MINV = 0x0123, + kD2045_BUCK1_MAXV = 0x0124, + kD2045_BUCK1_OFS_V = 0x0125, + kD2045_BUCK1_MODE = 0x0126, + kD2045_BUCK1_START_ILIMIT = 0x0127, + kD2045_BUCK1_SYNC_ILIMIT = 0x0128, + kD2045_BUCK1_SLEEP_ILIMIT = 0x0129, + kD2045_BUCK1_FSM_TRIM0 = 0x012a, + kD2045_BUCK1_FSM_TRIM1 = 0x012b, + kD2045_BUCK1_FSM_TRIM2 = 0x012c, + kD2045_BUCK1_FSM_TRIM3 = 0x012d, + kD2045_BUCK1_CLK_TRIM = 0x012e, + kD2045_BUCK1_CALIB0 = 0x0130, + kD2045_BUCK1_ANA_TRIM0 = 0x0132, + kD2045_BUCK1_ANA_TRIM1 = 0x0133, + kD2045_BUCK1_ANA_TRIM2 = 0x0134, + kD2045_BUCK1_ANA_TRIM3 = 0x0135, + kD2045_BUCK1_ANA_TRIM4 = 0x0136, + kD2045_BUCK1_ANA_TRIM5 = 0x0137, + kD2045_BUCK1_ANA_TRIM6 = 0x0138, + kD2045_BUCK1_ANA_TRIM7 = 0x0139, + kD2045_BUCK1_ANA_TRIM8 = 0x013a, + kD2045_BUCK1_ANA_TRIM9 = 0x013b, + kD2045_BUCK2_VSEL = 0x0140, + kD2045_BUCK2_VSEL_ACTUAL = 0x0142, + kD2045_BUCK2_MINV = 0x0143, + kD2045_BUCK2_MAXV = 0x0144, + kD2045_BUCK2_OFS_V = 0x0145, + kD2045_BUCK2_MODE = 0x0146, + kD2045_BUCK2_START_ILIMIT = 0x0147, + kD2045_BUCK2_SYNC_ILIMIT = 0x0148, + kD2045_BUCK2_SLEEP_ILIMIT = 0x0149, + kD2045_BUCK2_FSM_TRIM0 = 0x014a, + kD2045_BUCK2_FSM_TRIM1 = 0x014b, + kD2045_BUCK2_FSM_TRIM2 = 0x014c, + kD2045_BUCK2_FSM_TRIM3 = 0x014d, + kD2045_BUCK2_CLK_TRIM = 0x014e, + kD2045_BUCK2_CALIB0 = 0x0150, + kD2045_BUCK2_ANA_TRIM0 = 0x0152, + kD2045_BUCK2_ANA_TRIM1 = 0x0153, + kD2045_BUCK2_ANA_TRIM2 = 0x0154, + kD2045_BUCK2_ANA_TRIM3 = 0x0155, + kD2045_BUCK2_ANA_TRIM4 = 0x0156, + kD2045_BUCK2_ANA_TRIM5 = 0x0157, + kD2045_BUCK2_ANA_TRIM6 = 0x0158, + kD2045_BUCK2_ANA_TRIM7 = 0x0159, + kD2045_BUCK2_ANA_TRIM8 = 0x015a, + kD2045_BUCK2_ANA_TRIM9 = 0x015b, + kD2045_BUCK3_VSEL = 0x0160, + kD2045_BUCK3_VSEL_ALT = 0x0161, + kD2045_BUCK3_VSEL_ACTUAL = 0x0162, + kD2045_BUCK3_MINV = 0x0163, + kD2045_BUCK3_MAXV = 0x0164, + kD2045_BUCK3_OFS_V = 0x0165, + kD2045_BUCK3_MODE = 0x0166, + kD2045_BUCK3_START_ILIMIT = 0x0167, + kD2045_BUCK3_SYNC_ILIMIT = 0x0168, + kD2045_BUCK3_SLEEP_ILIMIT = 0x0169, + kD2045_BUCK3_FSM_TRIM0 = 0x016a, + kD2045_BUCK3_FSM_TRIM2 = 0x016c, + kD2045_BUCK3_FSM_TRIM3 = 0x016d, + kD2045_BUCK3_CLK_TRIM = 0x016e, + kD2045_BUCK3_CALIB0 = 0x0170, + kD2045_BUCK3_ANA_TRIM0 = 0x0172, + kD2045_BUCK3_ANA_TRIM1 = 0x0173, + kD2045_BUCK3_ANA_TRIM2 = 0x0174, + kD2045_BUCK3_ANA_TRIM3 = 0x0175, + kD2045_BUCK3_ANA_TRIM4 = 0x0176, + kD2045_BUCK3_ANA_TRIM5 = 0x0177, + kD2045_BUCK3_ANA_TRIM6 = 0x0178, + kD2045_BUCK3_ANA_TRIM7 = 0x0179, + kD2045_BUCK3_ANA_TRIM8 = 0x017a, + kD2045_BUCK3_ANA_TRIM9 = 0x017b, + kD2045_BUCK4_VSEL = 0x0180, + kD2045_BUCK4_VSEL_ALT = 0x0181, + kD2045_BUCK4_VSEL_ACTUAL = 0x0182, + kD2045_BUCK4_MINV = 0x0183, + kD2045_BUCK4_MAXV = 0x0184, + kD2045_BUCK4_OFS_V = 0x0185, + kD2045_BUCK4_MODE = 0x0186, + kD2045_BUCK4_START_ILIMIT = 0x0187, + kD2045_BUCK4_SYNC_ILIMIT = 0x0188, + kD2045_BUCK4_SLEEP_ILIMIT = 0x0189, + kD2045_BUCK4_FSM_TRIM0 = 0x018a, + kD2045_BUCK4_FSM_TRIM2 = 0x018c, + kD2045_BUCK4_FSM_TRIM3 = 0x018d, + kD2045_BUCK4_CLK_TRIM = 0x018e, + kD2045_BUCK4_CALIB0 = 0x0190, + kD2045_BUCK4_ANA_TRIM0 = 0x0192, + kD2045_BUCK4_ANA_TRIM1 = 0x0193, + kD2045_BUCK4_ANA_TRIM2 = 0x0194, + kD2045_BUCK4_ANA_TRIM3 = 0x0195, + kD2045_BUCK4_ANA_TRIM4 = 0x0196, + kD2045_BUCK4_ANA_TRIM5 = 0x0197, + kD2045_BUCK4_ANA_TRIM6 = 0x0198, + kD2045_BUCK4_ANA_TRIM7 = 0x0199, + kD2045_BUCK4_ANA_TRIM8 = 0x019a, + kD2045_BUCK4_ANA_TRIM9 = 0x019b, + kD2045_BUCK5_VSEL = 0x01a0, + kD2045_BUCK5_VSEL_ACTUAL = 0x01a2, + kD2045_BUCK5_MINV = 0x01a3, + kD2045_BUCK5_MAXV = 0x01a4, + kD2045_BUCK5_OFS_V = 0x01a5, + kD2045_BUCK5_MODE = 0x01a6, + kD2045_BUCK5_START_ILIMIT = 0x01a7, + kD2045_BUCK5_SYNC_ILIMIT = 0x01a8, + kD2045_BUCK5_SLEEP_ILIMIT = 0x01a9, + kD2045_BUCK5_FSM_TRIM0 = 0x01aa, + kD2045_BUCK5_FSM_TRIM2 = 0x01ac, + kD2045_BUCK5_FSM_TRIM3 = 0x01ad, + kD2045_BUCK5_CLK_TRIM = 0x01ae, + kD2045_BUCK5_CALIB_OFFSET_TRIM = 0x01af, + kD2045_BUCK5_CALIB0 = 0x01b0, + kD2045_BUCK5_ANA_TRIM0 = 0x01b2, + kD2045_BUCK5_ANA_TRIM1 = 0x01b3, + kD2045_BUCK5_ANA_TRIM2 = 0x01b4, + kD2045_BUCK5_ANA_TRIM3 = 0x01b5, + kD2045_BUCK5_ANA_TRIM4 = 0x01b6, + kD2045_BUCK5_ANA_TRIM5 = 0x01b7, + kD2045_BUCK5_ANA_TRIM6 = 0x01b8, + kD2045_BUCK5_ANA_TRIM7 = 0x01b9, + kD2045_BUCK5_ANA_TRIM8 = 0x01ba, + kD2045_BUCK5_ANA_TRIM9 = 0x01bb, + + kD2045_LDO1_VSEL = 0x0308, + kD2045_LDO1_VSEL_ACTUAL = 0x0309, + kD2045_LDO1_MINV = 0x030a, + kD2045_LDO1_MAXV = 0x030b, + kD2045_LDO2_VSEL = 0x0310, + kD2045_LDO2_VSEL_ACTUAL = 0x0311, + kD2045_LDO2_MINV = 0x0312, + kD2045_LDO2_MAXV = 0x0313, + kD2045_LDO2_TRIM = 0x0314, + kD2045_LDO3_VSEL = 0x0318, + kD2045_LDO3_VSEL_ACTUAL = 0x0319, + kD2045_LDO3_MINV = 0x031a, + kD2045_LDO3_MAXV = 0x031b, + kD2045_LDO4_VSEL = 0x0320, + kD2045_LDO4_VSEL_ACTUAL = 0x0321, + kD2045_LDO4_MINV = 0x0322, + kD2045_LDO4_MAXV = 0x0323, + kD2045_LDO5_VSEL = 0x0328, + kD2045_LDO5_VSEL_ACTUAL = 0x0329, + kD2045_LDO5_MINV = 0x032a, + kD2045_LDO5_MAXV = 0x032b, + kD2045_LDO5_TRIM = 0x032c, + kD2045_LDO6_VSEL = 0x0330, + kD2045_LDO6_VSEL_ACTUAL = 0x0331, + kD2045_LDO6_MINV = 0x0332, + kD2045_LDO6_MAXV = 0x0333, + kD2045_LDO6_TRIM = 0x0334, + kD2045_LDO7_VSEL = 0x0338, + kD2045_LDO7_VSEL_ACTUAL = 0x0339, + kD2045_LDO7_MINV = 0x033a, + kD2045_LDO7_MAXV = 0x033b, + kD2045_LDO7_TRIM = 0x033c, + kD2045_LDO8_VSEL = 0x0340, + kD2045_LDO8_VSEL_ACTUAL = 0x0341, + kD2045_LDO8_MINV = 0x0342, + kD2045_LDO8_MAXV = 0x0343, + kD2045_LDO8_TRIM = 0x0344, + kD2045_LDO9_VSEL = 0x0348, + kD2045_LDO9_VSEL_ACTUAL = 0x0349, + kD2045_LDO9_MINV = 0x034a, + kD2045_LDO9_MAXV = 0x034b, + kD2045_LDO9_TRIM = 0x034c, + kD2045_LDO10_VSEL = 0x0350, + kD2045_LDO10_VSEL_ACTUAL = 0x0351, + kD2045_LDO10_MINV = 0x0352, + kD2045_LDO10_MAXV = 0x0353, + kD2045_LDO11_VSEL = 0x0358, + kD2045_LDO11_VSEL_ACTUAL = 0x0359, + kD2045_LDO11_MINV = 0x035a, + kD2045_LDO11_MAXV = 0x035b, + kD2045_LDO11_TRIM = 0x035c, + kD2045_LDO12_TRIM = 0x0364, + kD2045_LDO13_VSEL = 0x0368, + kD2045_LDO13_VSEL_ACTUAL = 0x0369, + kD2045_LDO13_MINV = 0x036a, + kD2045_LDO13_MAXV = 0x036b, + kD2045_LDO13_TRIM = 0x036c, + kD2045_LDO_BYP1 = 0x0380, + kDIALOG_LDO_CONTROL = kD2045_LDO_BYP1, + + kD2045_HIB_SW_CTRL = 0x03c0, + + kD2045_GPIO1 = 0x0400, + kDIALOG_SYS_GPIO_REG_START = kD2045_GPIO1, + kD2045_GPIO2 = 0x0401, + kD2045_GPIO3 = 0x0402, + kD2045_GPIO4 = 0x0403, + kD2045_GPIO5 = 0x0404, + kD2045_GPIO6 = 0x0405, + kD2045_GPIO7 = 0x0406, + kD2045_GPIO8 = 0x0407, + kD2045_GPIO9 = 0x0408, + kD2045_GPIO10 = 0x0409, + kD2045_GPIO11 = 0x040a, + kD2045_GPIO12 = 0x040b, + kD2045_GPIO13 = 0x040c, + kD2045_GPIO14 = 0x040d, + kD2045_GPIO15 = 0x040e, + kD2045_GPIO16 = 0x040f, + + kD2045_GPIO_DEB1 = 0x0420, + kD2045_GPIO_DEB2 = 0x0421, + kD2045_GPIO_DEB3 = 0x0422, + kD2045_GPIO_DEB4 = 0x0423, + kD2045_GPIO_DEB5 = 0x0424, + kD2045_GPIO_DEB6 = 0x0425, + kD2045_GPIO_DEB7 = 0x0426, + kD2045_GPIO_DEB8 = 0x0427, + + kD2045_OUT_32K = 0x0430, + + kD2045_BUTTON1_CONF = 0x0440, + kD2045_BUTTON2_CONF = 0x0441, + kD2045_BUTTON3_CONF = 0x0442, + kD2045_BUTTON4_CONF = 0x0443, + kDIALOG_BUTTON_DBL = 0x0444, + kD2045_BUTTON_WAKE = 0x0445, + + kD2045_RESET_IN1_CONF = 0x0448, + kD2045_RESET_IN2_CONF = 0x0449, + kD2045_RESET_IN3_CONF = 0x044a, + + kD2045_TDEV1_RISE = 0x0480, + kD2045_TDEV1_FALL = 0x0481, + kD2045_TDEV2_RISE = 0x0482, + kD2045_TDEV2_FALL = 0x0483, + kD2045_TDEV3_RISE = 0x0484, + kD2045_TDEV3_FALL = 0x0485, + kD2045_TDEV4_RISE = 0x0486, + kD2045_TDEV4_FALL = 0x0487, + kD2045_TLDO5_RISE = 0x04a0, + kD2045_THIBSW_RISE = 0x04a1, + kD2045_TVCENTER_RISE = 0x04a2, + kD2045_TLINCHG_RISE = 0x04a3, + kD2045_TBUCK0_RISE = 0x04a4, + kD2045_TBUCK2_1_RISE = 0x04a5, + kD2045_TBUCK3_5_RISE = 0x04a6, + kD2045_TBUCK1_4_RISE = 0x04a7, + kD2045_TISENSE_HYST = 0x04a8, + kDIALOG_T_OFFSET_MSB = 0x04a9, + kDIALOG_T_OFFSET_LSB = 0x04aa, + + kD2045_ISET_BUCK = 0x04c0, + kD2045_ISET_BUCK_SHADOW = 0x04c1, + kD2045_ISET_BUCK_ABSMAX = 0x04c2, + kD2045_ISET_BUCK_ACTUAL = 0x04c3, + kD2045_ISET_BUCK_ALT = 0x04c4, + kDIALOG_CHARGE_BUCK_CONTROL = kD2045_ISET_BUCK, + kDIALOG_CHARGE_BUCK_STATUS = kD2045_ISET_BUCK_ACTUAL, + kD2045_CHG_CTRL_A = 0x04c5, + kD2045_CHG_CTRL_B = 0x04c6, + kD2045_CHG_CTRL_C = 0x04c7, + kD2045_CHG_CTRL_D = 0x04c8, + kD2045_CHG_CTRL_E = 0x04c9, + kD2045_CHG_CTRL_F = 0x04ca, + kD2045_CHG_TIME = 0x04cb, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD2045_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_HIB = kD2045_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_TIME = kD2045_CHG_CTRL_D, + kDIALOG_CHARGE_CONTROL_EN = kD2045_CHG_CTRL_A, + kDIALOG_OTP_ISET_BAT = kD2045_CHG_CTRL_C, + kDIALOG_CHARGE_STATUS = 0x04cc, + kD2045_CHG_VSET_TRIM = 0x04cd, + kD2045_CHG_VSET_OFS = 0x04ce, + kD2045_IBUS_GAIN_TRIM = 0x04cf, + kD2045_IBUS100_OFS_TRIM = 0x04d0, + kD2045_IBUS500_OFS_TRIM = 0x04d1, + kD2045_CHG_TRIM1 = 0x04d2, + kD2045_CHG_TRIM2 = 0x04d3, + kD2045_CHG_TRIM3 = 0x04d4, + kD2045_CHG_TRIM4 = 0x04d5, + kD2045_ICHG_END = 0x04d6, + + kDIALOG_TBAT_0 = 0x04d7, + kDIALOG_TBAT_1 = 0x04d8, + kDIALOG_TBAT_2 = 0x04d9, + kDIALOG_TBAT_3 = 0x04da, + kDIALOG_TBAT_4 = 0x04db, + kDIALOG_TBAT_MAX = 0x04dc, + kDIALOG_ICHG_TBAT_0 = 0x04dd, + kDIALOG_ICHG_TBAT_1 = 0x04de, + kDIALOG_ICHG_TBAT_2 = 0x04df, + kDIALOG_ICHG_TBAT_3 = 0x04e0, + kDIALOG_ICHG_TBAT_4 = 0x04e1, + + kDIALOG_ICHG_AVG = 0x04e2, + + kDIALOG_ADC_CONTROL = 0x0500, + kDIALOG_ADC_CONTROL2 = 0x0501, + kDIALOG_ADC_LSB = 0x0502, + kDIALOG_ADC_MSB = 0x0503, + kD2045_ADC_TEMP_CTRL0 = 0x0504, + kD2045_ADC_TEMP_CTRL1 = 0x0505, + kD2045_ADC_FSM_TRIM0 = 0x0506, + kD2045_ADC_FSM_TRIM1 = 0x0507, + kD2045_ADC_FSM_TRIM2 = 0x0508, + kD2045_ADC_FSM_TRIM3 = 0x0509, + kD2045_ADC_ANA_TRIM0 = 0x050a, + kD2045_VCC_MAIN_MON = 0x050c, + kDIALOG_IBUS_ACCUM1 = 0x050e, + kDIALOG_IBUS_ACCUM2 = 0x050f, + kDIALOG_IBUS_ACCUM3 = 0x0510, + kDIALOG_VBUS_ACCUM1 = 0x0511, + kDIALOG_VBUS_ACCUM2 = 0x0512, + kDIALOG_VBUS_ACCUM3 = 0x0513, + kDIALOG_TDIE_ACCUM1 = 0x0514, + kDIALOG_TDIE_ACCUM2 = 0x0515, + kDIALOG_TDIE_ACCUM3 = 0x0516, + kDIALOG_IBUS_COUNT1 = 0x0517, + kDIALOG_IBUS_COUNT2 = 0x0518, + kD2045_IBUSCAL_1 = 0x0519, + kD2045_IBUSCAL_2 = 0x051a, + kD2045_IBUSCAL_3 = 0x051b, + kD2045_IBUSCAL_4 = 0x051c, + kD2045_IBUSCAL_5 = 0x051d, + kD2045_IBUSCAL_6 = 0x051e, + kD2045_IBUSCAL_7 = 0x051f, + kD2045_IBUSCAL_8 = 0x0520, + + kDIALOG_APP_TMUX = 0x0540, + kDIALOG_BIST_ADC_CTRL = 0x0541, + kDIALOG_BIST_ADC_LSB = 0x0542, + kDIALOG_BIST_ADC_MSB = 0x0543, + kD2045_BIST_ADC_TRIM1 = 0x0545, + kD2045_BIST_ADC_ANA_TRIM0 = 0x0546, + + kDIALOG_VIB_CTRL = 0x0580, + kDIALOG_VIB_VSET = 0x0581, + kD2045_VIB_TRIM = 0x0582, + kD2045_VIB_ILIMIT_PROG = 0x0583, + + kDIALOG_RTC_ALARM_A = 0x05c0, + kDIALOG_RTC_ALARM_B = 0x05c1, + kDIALOG_RTC_ALARM_C = 0x05c2, + kDIALOG_RTC_ALARM_D = 0x05c3, + kDIALOG_RTC_CONTROL = 0x05c4, + kDIALOG_RTC_TIMEZONE = 0x05c5, + kDIALOG_RTC_SUB_SECOND_A = 0x05c6, + kDIALOG_RTC_SUB_SECOND_B = 0x05c7, + kDIALOG_RTC_SECOND_A = 0x05c8, + kDIALOG_RTC_SECOND_B = 0x05c9, + kDIALOG_RTC_SECOND_C = 0x05ca, + kDIALOG_RTC_SECOND_D = 0x05cb, + + kD2045_SPARE_RW0 = 0x0680, + kD2045_SPARE_RW_LAST = 0x0687, + kD2045_SPARE_RWTOTP0 = 0x06a0, + kD2045_SPARE_RWTOTP_LAST = 0x06a7, + kD2045_SPARE_RWOTP0 = 0x06c0, + kD2045_SPARE_RWOTP1 = 0x0610, + + kDIALOG_MEMBYTE0 = 0x4000, + kDIALOG_MEMBYTE_LAST = 0x4027, + + kDIALOG_RAM0 = 0x8000, + kDIALOG_EXT_MEM_CAL0 = kDIALOG_RAM0, + kDIALOG_EXT_MEM_CAL0_SIZE = 64, + kDIALOG_DIAG_SCRATCH = kDIALOG_EXT_MEM_CAL0+kDIALOG_EXT_MEM_CAL0_SIZE, // + kDIALOG_DIAG_SCRATCH_SIZE = 8, + kDIALOG_EXT_MEM_CAL1= kDIALOG_DIAG_SCRATCH+kDIALOG_DIAG_SCRATCH_SIZE, + kDIALOG_EXT_MEM_CAL1_SIZE= 336, + + kDIALOG_EXT_MEM_CAL_SIZE= kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_EXT_MEM_CAL1_SIZE, + + kDIALOG_RAM_LAST = 0x87ff, +}; + +// Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 2, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, +}; + +enum { + kD2045_EVENT_A_TBAT = (1 << 7), + kD2045_EVENT_A_VBUS_EXT_REM = (1 << 6), + kD2045_EVENT_A_VDD_LOW = (1 << 5), + kD2045_EVENT_A_VBUS_EXT_DET = (1 << 3), + kD2045_EVENT_A_ACC_DET = (1 << 2), + kD2045_EVENT_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2045_EVENT_B_BTN4_DBL = (1 << 7), + kD2045_EVENT_B_BTN3_DBL = (1 << 6), + kD2045_EVENT_B_BTN2_DBL = (1 << 5), + kD2045_EVENT_B_BTN1_DBL = (1 << 4), + kD2045_EVENT_B_BUTTON_4 = (1 << 3), + kD2045_EVENT_B_BUTTON_3 = (1 << 2), + kD2045_EVENT_B_BUTTON_2 = (1 << 1), + kD2045_EVENT_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2045_EVENT_C_CHG_BUCK_FLG = (1 << 6), + kD2045_EVENT_C_CHG_ABCC_ACT = (1 << 5), + kD2045_EVENT_C_CHG_TIMEOUT = (1 << 4), + kD2045_EVENT_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2045_EVENT_C_CHG_END = (1 << 2), + kD2045_EVENT_C_CHG_FAST = (1 << 1), + kD2045_EVENT_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2045_EVENT_D_GPIO8 = (1 << 7), + kD2045_EVENT_D_GPIO7 = (1 << 6), + kD2045_EVENT_D_GPIO6 = (1 << 5), + kD2045_EVENT_D_GPIO5 = (1 << 4), + kD2045_EVENT_D_GPIO4 = (1 << 3), + kD2045_EVENT_D_GPIO3 = (1 << 2), + kD2045_EVENT_D_GPIO2 = (1 << 1), + kD2045_EVENT_D_GPIO1 = (1 << 0), +}; + +enum { + kD2045_EVENT_E_GPIO16 = (1 << 7), + kD2045_EVENT_E_GPIO15 = (1 << 6), + kD2045_EVENT_E_GPIO14 = (1 << 5), + kD2045_EVENT_E_GPIO13 = (1 << 4), + kD2045_EVENT_E_GPIO12 = (1 << 3), + kD2045_EVENT_E_GPIO11 = (1 << 2), + kD2045_EVENT_E_GPIO10 = (1 << 1), + kD2045_EVENT_E_GPIO9 = (1 << 0), +}; + + // EVENT_F has no events + +enum { + kD2045_EVENT_G_T4_RISE = (1 << 7), + kD2045_EVENT_G_T4_FALL = (1 << 6), + kD2045_EVENT_G_T3_RISE = (1 << 5), + kD2045_EVENT_G_T3_FALL = (1 << 4), + kD2045_EVENT_G_T2_RISE = (1 << 3), + kD2045_EVENT_G_T2_FALL = (1 << 2), + kD2045_EVENT_G_T1_RISE = (1 << 1), + kD2045_EVENT_G_T1_FALL = (1 << 0), +}; + + // EVENT_H has no events + +enum { + kD2045_EVENT_I_TBUCK_1_4 = (1 << 7), + kD2045_EVENT_I_TBUCK_3_5 = (1 << 6), + kD2045_EVENT_I_TBUCK_2_1 = (1 << 5), + kD2045_EVENT_I_TBUCK_0 = (1 << 4), + kD2045_EVENT_I_TLINCHG = (1 << 3), + kD2045_EVENT_I_TVCENTER = (1 << 2), + kD2045_EVENT_I_THIBSW = (1 << 1), + kD2045_EVENT_I_TLDO5 = (1 << 0), +}; + +enum { + kD2045_EVENT_J_HIGH_TEMP_WARNING = (1 << 7), +}; + +enum { + kD2045_EVENT_K_VBUS_OV = (1 << 5), + kD2045_EVENT_K_VBUS_OC = (1 << 4), + kD2045_EVENT_K_LDO6_OC = (1 << 3), +}; + +// EVENT_L events are stored by LLB across sleep/wake +enum { + kD2045_EVENT_L_VIB = (1 << 7), + kD2045_EVENT_L_IBUS_OVERFLOW = (1 << 6), + kD2045_EVENT_L_XTAL_ERROR = (1 << 5), + kD2045_EVENT_L_HIB = (1 << 4), + kD2045_EVENT_L_DWI_TO = (1 << 3), + kD2045_EVENT_L_EOMC_BIST = (1 << 2), + kD2045_EVENT_L_EOMC = (1 << 1), + kD2045_EVENT_L_ALARM = (1 << 0), +}; + +enum { + kD2045_STATUS_A_TBAT = (1 << 7), + kD2045_STATUS_A_VDD_LOW = (1 << 5), + kD2045_STATUS_A_VBUS_EXT_DET = (1 << 3), + kD2045_STATUS_A_ACC_DET = (1 << 2), + kD2045_STATUS_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2045_STATUS_B_BUTTON_4 = (1 << 3), + kD2045_STATUS_B_BUTTON_3 = (1 << 2), + kD2045_STATUS_B_BUTTON_2 = (1 << 1), + kD2045_STATUS_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2045_STATUS_C_CHG_BUCK_FLG = (1 << 6), + kD2045_STATUS_C_CHG_ABCC_ACT = (1 << 5), + kD2045_STATUS_C_CHG_TIMEOUT = (1 << 4), + kD2045_STATUS_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2045_STATUS_C_CHG_END = (1 << 2), + kD2045_STATUS_C_CHG_FAST = (1 << 1), + kD2045_STATUS_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2045_STATUS_D_GPIO8 = (1 << 7), + kD2045_STATUS_D_GPIO7 = (1 << 6), + kD2045_STATUS_D_GPIO6 = (1 << 5), + kD2045_STATUS_D_GPIO5 = (1 << 4), + kD2045_STATUS_D_GPIO4 = (1 << 3), + kD2045_STATUS_D_GPIO3 = (1 << 2), + kD2045_STATUS_D_GPIO2 = (1 << 1), + kD2045_STATUS_D_GPIO1 = (1 << 0), +}; + +enum { + kD2045_STATUS_E_GPIO16 = (1 << 7), + kD2045_STATUS_E_GPIO15 = (1 << 6), + kD2045_STATUS_E_GPIO14 = (1 << 5), + kD2045_STATUS_E_GPIO13 = (1 << 4), + kD2045_STATUS_E_GPIO12 = (1 << 3), + kD2045_STATUS_E_GPIO11 = (1 << 2), + kD2045_STATUS_E_GPIO10 = (1 << 1), + kD2045_STATUS_E_GPIO9 = (1 << 0), +}; + + // STATUS_F has no bits + +enum { + kD2045_STATUS_G_T4_RISE = (1 << 7), + kD2045_STATUS_G_T4_FALL = (1 << 6), + kD2045_STATUS_G_T3_RISE = (1 << 5), + kD2045_STATUS_G_T3_FALL = (1 << 4), + kD2045_STATUS_G_T2_RISE = (1 << 3), + kD2045_STATUS_G_T2_FALL = (1 << 2), + kD2045_STATUS_G_T1_RISE = (1 << 1), + kD2045_STATUS_G_T1_FALL = (1 << 0), +}; + + // STATUS_H has no bits + +enum { + kD2045_STATUS_I_TBUCK_1_4 = (1 << 7), + kD2045_STATUS_I_TBUCK_3_5 = (1 << 6), + kD2045_STATUS_I_TBUCK_2_1 = (1 << 5), + kD2045_STATUS_I_TBUCK_0 = (1 << 4), + kD2045_STATUS_I_TLINCHG = (1 << 3), + kD2045_STATUS_I_TVCENTER = (1 << 2), + kD2045_STATUS_I_THIBSW = (1 << 1), + kD2045_STATUS_I_TLDO5 = (1 << 0), +}; + +enum { + kD2045_STATUS_J_HIGH_TEMP_WARNING = (1 << 7), +}; + +enum { + kD2045_STATUS_K_VBUS_OV = (1 << 5), + kD2045_STATUS_K_VBUS_OC = (1 << 4), +}; + +enum { + kD2045_STATUS_L_VIB_ILIM = (1 << 7), + kD2045_STATUS_L_IBUS_OVERFLOW = (1 << 6), + kD2045_STATUS_L_XTAL_ERROR = (1 << 5), +}; + +enum { + kD2045_STATUS_M_PROT_FET_ON = (1 << 1), + kD2045_STATUS_M_CHG_ATT = (1 << 0), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2045_EVENT_B_BUTTON_2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2045_EVENT_B_BUTTON_1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(1, kD2045_EVENT_B_BUTTON_3), + kDIALOG_EVENT_BUTTON4_MASK= EVENT_FLAG_MAKE(1, kD2045_EVENT_B_BUTTON_4), + kDIALOG_EVENT_BUTTONS = (kD2045_EVENT_B_BUTTON_4 | + kD2045_EVENT_B_BUTTON_3 | + kD2045_EVENT_B_BUTTON_2 | + kD2045_EVENT_B_BUTTON_1), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(11, kD2045_EVENT_L_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD2045_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD2045_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(0, kD2045_EVENT_A_VBUS_EXT_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(11, kD2045_EVENT_L_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(11, kD2045_EVENT_L_HIB), + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(2, kD2045_EVENT_C_CHG_ABCC_ACT), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(2, kD2045_EVENT_C_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(0, kD2045_EVENT_A_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(3, kD2045_EVENT_D_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(4, kD2045_EVENT_E_GPIO16), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(1, kD2045_EVENT_B_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(1, kD2045_EVENT_B_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(1, kD2045_EVENT_B_BTN3_DBL), + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO17_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD2045_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD2045_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD2045_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(3, kD2045_STATUS_C_CHG_PRE | kD2045_STATUS_C_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(2, kD2045_STATUS_C_CHG_TIMEOUT), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(2, kD2045_STATUS_C_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(0, kD2045_STATUS_A_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(12, kD2045_STATUS_M_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(2, kD2045_STATUS_C_CHG_ABCC_ACT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(3 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {0, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, 0, kD2045_STATUS_C_CHG_PRE | kD2045_STATUS_C_CHG_FAST }; + +enum { + kD2045_EVENT_A_WAKEMASK = (kD2045_EVENT_A_VBUS_EXT_DET | + kD2045_EVENT_A_VCENTER_DET | + kD2045_EVENT_A_ACC_DET), + kD2045_EVENT_B_WAKEMASK = (kD2045_EVENT_B_BUTTON_1 | + kD2045_EVENT_B_BUTTON_2 | + kD2045_EVENT_B_BUTTON_3 | + kD2045_EVENT_B_BUTTON_4), + kD2045_EVENT_C_WAKEMASK = 0, + kD2045_EVENT_D_WAKEMASK = 0, + kD2045_EVENT_E_WAKEMASK = 0, + kD2045_EVENT_F_WAKEMASK = 0, + kD2045_EVENT_G_WAKEMASK = 0, + kD2045_EVENT_H_WAKEMASK = 0, + kD2045_EVENT_I_WAKEMASK = 0, + kD2045_EVENT_J_WAKEMASK = 0, + kD2045_EVENT_K_WAKEMASK = 0, + kD2045_EVENT_L_WAKEMASK = kD2045_EVENT_L_ALARM, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2045_EVENT_A_WAKEMASK, + ~kD2045_EVENT_B_WAKEMASK, + ~kD2045_EVENT_C_WAKEMASK, + ~kD2045_EVENT_D_WAKEMASK, + ~kD2045_EVENT_E_WAKEMASK, + ~kD2045_EVENT_F_WAKEMASK, + ~kD2045_EVENT_G_WAKEMASK, + ~kD2045_EVENT_H_WAKEMASK, + ~kD2045_EVENT_I_WAKEMASK, + ~kD2045_EVENT_J_WAKEMASK, + ~kD2045_EVENT_K_WAKEMASK, + ~kD2045_EVENT_L_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2045_EVENT_A_WAKEMASK, + kD2045_EVENT_B_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD2045_EVENT_C_WAKEMASK, + kD2045_EVENT_D_WAKEMASK, + kD2045_EVENT_E_WAKEMASK, + kD2045_EVENT_F_WAKEMASK, + kD2045_EVENT_G_WAKEMASK, + kD2045_EVENT_H_WAKEMASK, + kD2045_EVENT_I_WAKEMASK, + kD2045_EVENT_J_WAKEMASK, + kD2045_EVENT_K_WAKEMASK, + kD2045_EVENT_L_WAKEMASK, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD2045_EVENT_A_VBUS_EXT_DET | kD2045_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD2045_EVENT_A_VCENTER_DET, + 0, + kD2045_EVENT_C_CHG_ABCC_ACT, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +enum { + kDialogEventPwrsupplyCount = 2, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 0, +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PROT_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), +}; + +enum { + // FAULT_LOG1 + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 7)), + kDIALOG_FAULT_LOG_RESET_IN_3 = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_2 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + // FAULT_LOG2 + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = FAULTLOG_FLAG_MAKE(1, (1 << 2)), + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = FAULTLOG_FLAG_MAKE(1, (1 << 1)), + kDIALOG_FAULT_LOG_NTC_SHDN = FAULTLOG_FLAG_MAKE(1, (1 << 0)), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x03, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x2b, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x5d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0xc1, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 70, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 10, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 2620, +}; + + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_B_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_B_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 30, + kDIALOG_CHARGE_CONTROL_MAX = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK * kDIALOG_CHARGE_CONTROL_STEP, +}; + +enum { + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 6), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG, + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (0xf << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG_OFF = (16 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG_OFF = (17 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP = (18 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LOADSW_TEMP = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VCENTER_TEMP = (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP = (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP, + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 7), + kDIALOG_ADC_CONTROL2_IBUS_EN = (1 << 0), + kDIALOG_ADC_CONTROL2_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL2_AUTO_VDD_OUT_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, + kDIALOG_ADC_CONTROL2_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (0 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (2 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (4 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (5 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (6 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (7 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (8 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (9 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10 = (23 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11 = (25 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO12 = (27 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO13 = (28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO13 = (29 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (36 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (37 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0 = (40 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK1 = (42 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (44 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (46 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (48 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK5 = (50 << 0), + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +#define NUM_LDOS 19 +// LDO settings for Amber-A1 +static const struct ldo_params ldo_d2045[NUM_LDOS] = { + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO1_VSEL, kD2045_ACTIVE3, 0x02 }, // LDO1 + { 1200, 5, 0xff, 0xff, 0x04, kD2045_LDO2_VSEL, kD2045_ACTIVE3, 0x04 }, // LDO2 + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO3_VSEL, kD2045_ACTIVE3, 0x08 }, // LDO3 + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO4_VSEL, kD2045_ACTIVE3, 0x10 }, // LDO4 + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO5_VSEL, kD2045_ACTIVE3, 0x20 }, // LDO5 + { 1200, 25, 0x7f, 0x7f, 0x40, kD2045_LDO6_VSEL, kD2045_ACTIVE3, 0x40 }, // LDO6 + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO7_VSEL, kD2045_ACTIVE3, 0x80 }, // LDO7 + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO8_VSEL, kD2045_ACTIVE4, 0x01 }, // LDO8 + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO9_VSEL, kD2045_ACTIVE4, 0x02 }, // LDO9 + { 600, 12, 0xff, 0xff, 0x00, kD2045_LDO10_VSEL, kD2045_ACTIVE4, 0x04 }, // LDO10 - actually 12.5mv steps (FIXME) + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO11_VSEL, kD2045_ACTIVE4, 0x08 }, // LDO11 + { 0, 0, 0, 0, 0x00, 0, kD2045_ACTIVE4, 0x00 }, // there is no LDO12 + { 600, 25, 0x7f, 0x7f, 0x00, kD2045_LDO13_VSEL, kD2045_ACTIVE4, 0x20 }, // LDO13 + + { 0, 0, 0, 0, 0x00, 0, kD2045_ACTIVE6, 0x01 }, // 14 - BUCK3_SW1_EN + { 0, 0, 0, 0, 0x00, 0, kD2045_ACTIVE6, 0x02 }, // 15 - BUCK3_SW2_EN + { 0, 0, 0, 0, 0x00, 0, kD2045_ACTIVE6, 0x04 }, // 16 - BUCK3_SW3_EN + { 0, 0, 0, 0, 0x00, 0, kD2045_ACTIVE6, 0x10 }, // 17 - BUCK4_SW1_EN + { 0, 0, 0, 0, 0x00, 0, kD2045_ACTIVE6, 0x20 }, // 18 - BUCK4_SW2_EN + + { 0, 0, 0, 0, 0x00, 0, kD2045_HIBERNATE3, 0x40 }, // 19 - set LDO6_EN in HIB +}; +#define LDOP ldo_d2045 + +enum { + kDIALOG_VIB_CTRL_PWM_EN = (1 << 0), + kDIALOG_VIB_CTRL_BRAKE = (1 << 1), + kDIALOG_VIB_CTRL_PWM_CLK_MASK = (3 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_2MHZ = (0 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_1MHZ = (1 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_500KHZ = (2 << 2), + + kDIALOG_VIB_VSET_MASK = (0x3f << 0), +}; + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD2045_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD2045_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD2045_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kD2045_BUTTON_DBL_BTN4_DBL_EN = (1 << 6), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD2045_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD2045_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD2045_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif /* __DIALOG_D2045_H */ diff --git a/drivers/dialog/pmu/d2089.h b/drivers/dialog/pmu/d2089.h new file mode 100644 index 0000000..df024bf --- /dev/null +++ b/drivers/dialog/pmu/d2089.h @@ -0,0 +1,1496 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D2089_H +#define __DIALOG_D2089_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_VIB 0 +#define PMU_HAS_RAM 1 +#define PMU_HAS_WLED 1 +#define PMU_HAS_32K_RTC 1 +// : +#define PMU_HAS_ACCUMULATORS 0 + +enum { + kDIALOG_ADDR_R = 0x79, + kDIALOG_ADDR_W = 0x78, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_EVENT_COUNT = 14, + kDIALOG_STATUS_COUNT = 13, + kDIALOG_FAULTLOG_COUNT = 2, + kDIALOG_CHIPID_COUNT = 4, + kDIALOG_GPIO_COUNT = 17, +}; + +#include "dCommon.h" + +enum { + kDIALOG_MASK_REV_CODE = 0x0000, + kDIALOG_TRIM_REL_CODE = 0x0001, + kDIALOG_PLATFORM_ID = 0x0002, + kDIALOG_DEVICE_ID1 = 0x0004, + kDIALOG_DEVICE_ID2 = 0x0005, + kDIALOG_DEVICE_ID3 = 0x0006, + kDIALOG_DEVICE_ID4 = 0x0007, + kDIALOG_DEVICE_ID5 = 0x0008, + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, + + kDIALOG_SYS_CONTROL = 0x0010, + kDIALOG_SYS_CONTROL2 = 0x0011, + + kDIALOG_SYS_CONFIG = 0x0020, + kD2089_SYS_CONF_B = 0x0021, + kD2089_SYS_CONF_C = 0x0022, + kD2089_SYS_CONF_D = 0x0023, + kD2089_BG_TRIM = 0x0024, + kD2089_VREF_AUX_TRIM = 0x0025, + kD2089_VRTC_BG_TRIM = 0x0026, + kD2089_VDD_FAULT = 0x0027, + kD2089_RTC_CTRL0 = 0x0028, + kD2089_RTC_CTRL1 = 0x0029, + kD2089_OSC_CTRL0 = 0x002a, + kD2089_INT_OSC_TRIM = 0x002b, + kD2089_CLK_REQ_FRC = 0x002c, + + kDIALOG_FAULT_LOG = 0x0040, + kDIALOG_FAULT_LOG2 = 0x0041, + + kDIALOG_EVENT_A = 0x0050, + kDIALOG_EVENT_B = 0x0051, + kDIALOG_EVENT_C = 0x0052, + kDIALOG_EVENT_D = 0x0053, + kDIALOG_EVENT_E = 0x0054, + kDIALOG_EVENT_F = 0x0055, + kDIALOG_EVENT_G = 0x0056, + kDIALOG_EVENT_H = 0x0057, + kDIALOG_EVENT_I = 0x0058, + kDIALOG_EVENT_J = 0x0059, + kDIALOG_EVENT_K = 0x005a, + kDIALOG_EVENT_L = 0x005b, + + kDIALOG_EVENT_M = 0x005c, + kDIALOG_EVENT_N = 0x005d, + + kDIALOG_STATUS_A = 0x0060, + kDIALOG_STATUS_B = 0x0061, + kDIALOG_STATUS_C = 0x0062, + kDIALOG_STATUS_D = 0x0063, + kDIALOG_STATUS_E = 0x0064, + kDIALOG_STATUS_F = 0x0065, + kDIALOG_STATUS_G = 0x0066, + kDIALOG_STATUS_H = 0x0067, + kDIALOG_STATUS_I = 0x0068, + kDIALOG_STATUS_J = 0x0069, + kDIALOG_STATUS_K = 0x006a, + kDIALOG_STATUS_L = 0x006b, + kDIALOG_STATUS_M = 0x006c, + + kDIALOG_IRQ_MASK_A = 0x0070, + kDIALOG_IRQ_MASK_B = 0x0071, + kDIALOG_IRQ_MASK_C = 0x0072, + kDIALOG_IRQ_MASK_D = 0x0073, + kDIALOG_IRQ_MASK_E = 0x0074, + kDIALOG_IRQ_MASK_F = 0x0075, + kDIALOG_IRQ_MASK_G = 0x0076, + kDIALOG_IRQ_MASK_H = 0x0077, + kDIALOG_IRQ_MASK_I = 0x0078, + kDIALOG_IRQ_MASK_J = 0x0079, + kDIALOG_IRQ_MASK_K = 0x007A, + kDIALOG_IRQ_MASK_L = 0x007B, + kDIALOG_IRQ_MASK_M = 0x007C, + kDIALOG_IRQ_MASK_N = 0x007D, + + kD2089_ACTIVE1 = 0x0080, + kD2089_ACTIVE2 = 0x0081, + kD2089_ACTIVE3 = 0x0082, + kD2089_ACTIVE4 = 0x0083, + kD2089_ACTIVE5 = 0x0084, + kDIALOG_LCM_ACTIVE = kD2089_ACTIVE5, + kD2089_ACTIVE6 = 0x0085, + kD2089_ACTIVE7 = 0x0086, + kD2089_STANDBY1 = 0x0088, + kD2089_STANDBY3 = 0x008a, + kD2089_STANDBY4 = 0x008b, + kD2089_STANDBY6 = 0x008d, + kD2089_STANDBY7 = 0x008e, + kD2089_HIBERNATE1 = 0x0090, + kD2089_HIBERNATE3 = 0x0092, + kD2089_HIBERNATE4 = 0x0093, + kD2089_HIBERNATE6 = 0x0095, + kD2089_HIBERNATE7 = 0x0096, + +//-- + + kD2089_SLOT_TIMINGS = 0x00a0, + kD2089_ACT_TO_HIB_DLY = 0x00a1, + kD2089_BUCK0_SLOT = 0x00b0, + kD2089_BUCK1_SLOT = 0x00b1, + kD2089_BUCK2_SLOT = 0x00b2, + kD2089_BUCK3_SLOT = 0x00b3, + kD2089_BUCK4_SLOT = 0x00b4, + kD2089_BUCK5_SLOT = 0x00b5, + kD2089_BUCK6_SLOT = 0x00b6, + + kD2089_LDO1_SLOT = 0x00c1, + kD2089_LDO2_SLOT = 0x00c2, + kD2089_LDO3_SLOT = 0x00c3, + kD2089_LDO4_SLOT = 0x00c4, + kD2089_LDO5_SLOT = 0x00c5, + kD2089_LDO6_SLOT = 0x00c6, + kD2089_LDO7_SLOT = 0x00c7, + kD2089_LDO8_SLOT = 0x00c8, + kD2089_LDO9_SLOT = 0x00c9, + kD2089_LDO10_SLOT = 0x00ca, + kD2089_LDO11_SLOT = 0x00cb, + kD2089_LDO12_SLOT = 0x00cc, + kD2089_LDO13_SLOT = 0x00cd, + + kD2089_LCM_BOOST_SW_SLOT = 0x00d0, + kD2089_LCM_BOOST_SLOT = 0x00d1, + kD2089_LCM_LDO1_SLOT = 0x00d2, + kD2089_LCM_LDO2_SLOT = 0x00d3, + kD2089_LCM_LDO3_SLOT = 0x00d4, + + kD2089_CHARGE_PUMP_SLOT = 0x00d8, + kD2089_BUCK3_SW1_SLOT = 0x00d9, + kD2089_BUCK3_SW2_SLOT = 0x00da, + kD2089_BUCK3_SW3_SLOT = 0x00db, + kD2089_BUCK4_SW1_SLOT = 0x00dc, + kD2089_BUCK4_SW2_SLOT = 0x00dd, + + kD2089_BUCK_DWI_CTRL0 = 0x00f0, + kD2089_BUCK_DWI_TRIM0 = 0x00f2, + kD2089_BUCK_FSM_TRIM0 = 0x00f4, + kD2089_BUCK_FSM_TRIM1 = 0x00f5, + kD2089_BUCK_FSM_TRIM2 = 0x00f6, + kD2089_BUCK_FSM_TRIM3 = 0x00f7, + + kD2089_BUCK_CALIB_OFFSET_TRIM = 0x00f8, + kD2089_BUCK_DEBUG_OFFSET = 0x00f9, + kD2089_BUCK_OFFSET_SEL = 0x00fa, + kD2089_BUCK_OFFSET_EN = 0x00fb, + + kD2089_BUCK0_VSEL = 0x0100, + kD2089_BUCK0_VSEL_ACTUAL = 0x0102, + kD2089_BUCK0_MINV = 0x0103, + kD2089_BUCK0_MAXV = 0x0104, + kD2089_BUCK0_OFS_V = 0x0105, + kD2089_BUCK0_MODE = 0x0106, + kD2089_BUCK0_START_ILIMIT = 0x0107, + kD2089_BUCK0_SYNC_ILIMIT = 0x0108, + kD2089_BUCK0_SLEEP_ILIMIT = 0x0109, + kD2089_BUCK0_FSM_TRIM0 = 0x010a, + kD2089_BUCK0_FSM_TRIM1 = 0x010b, + kD2089_BUCK0_FSM_TRIM2 = 0x010c, + kD2089_BUCK0_FSM_TRIM3 = 0x010d, + kD2089_BUCK0_CLK_TRIM1 = 0x010e, + kD2089_BUCK0_CLK_TRIM2 = 0x010f, + kD2089_BUCK0_CLK_TRIM3 = 0x0110, + kD2089_BUCK0_CALIB0 = 0x0112, + kD2089_BUCK0_CALIB1 = 0x0113, + kD2089_BUCK0_ANA_TRIM0 = 0x0114, + kD2089_BUCK0_ANA_TRIM1 = 0x0115, + kD2089_BUCK0_ANA_TRIM2 = 0x0116, + kD2089_BUCK0_ANA_TRIM3 = 0x0117, + kD2089_BUCK0_ANA_TRIM4 = 0x0118, + kD2089_BUCK0_ANA_TRIM5 = 0x0119, + kD2089_BUCK0_ANA_TRIM6 = 0x011a, + kD2089_BUCK0_ANA_TRIM7 = 0x011b, + kD2089_BUCK0_ANA_TRIM8 = 0x011c, + kD2089_BUCK0_ANA_TRIM9 = 0x011d, + + kD2089_BUCK1_VSEL = 0x0120, + kD2089_BUCK1_VSEL_ACTUAL = 0x0122, + kD2089_BUCK1_MINV = 0x0123, + kD2089_BUCK1_MAXV = 0x0124, + kD2089_BUCK1_OFS_V = 0x0125, + kD2089_BUCK1_MODE = 0x0126, + kD2089_BUCK1_START_ILIMIT = 0x0127, + kD2089_BUCK1_SYNC_ILIMIT = 0x0128, + kD2089_BUCK1_SLEEP_ILIMIT = 0x0129, + kD2089_BUCK1_FSM_TRIM0 = 0x012a, + kD2089_BUCK1_FSM_TRIM1 = 0x012b, + kD2089_BUCK1_FSM_TRIM2 = 0x012c, + kD2089_BUCK1_FSM_TRIM3 = 0x012d, + kD2089_BUCK1_CLK_TRIM1 = 0x012e, + kD2089_BUCK1_CLK_TRIM2 = 0x012f, + kD2089_BUCK1_CLK_TRIM3 = 0x0130, + kD2089_BUCK1_CALIB0 = 0x0132, + kD2089_BUCK1_CALIB1 = 0x0133, + kD2089_BUCK1_ANA_TRIM0 = 0x0134, + kD2089_BUCK1_ANA_TRIM1 = 0x0135, + kD2089_BUCK1_ANA_TRIM2 = 0x0136, + kD2089_BUCK1_ANA_TRIM3 = 0x0137, + kD2089_BUCK1_ANA_TRIM4 = 0x0138, + kD2089_BUCK1_ANA_TRIM5 = 0x0139, + kD2089_BUCK1_ANA_TRIM6 = 0x013a, + kD2089_BUCK1_ANA_TRIM7 = 0x013b, + kD2089_BUCK1_ANA_TRIM8 = 0x013c, + kD2089_BUCK1_ANA_TRIM9 = 0x013d, + + kD2089_BUCK2_VSEL = 0x0140, + kD2089_BUCK2_VSEL_ACTUAL = 0x0142, + kD2089_BUCK2_MINV = 0x0143, + kD2089_BUCK2_MAXV = 0x0144, + kD2089_BUCK2_OFS_V = 0x0145, + kD2089_BUCK2_MODE = 0x0146, + kD2089_BUCK2_START_ILIMIT = 0x0147, + kD2089_BUCK2_SYNC_ILIMIT = 0x0148, + kD2089_BUCK2_SLEEP_ILIMIT = 0x0149, + kD2089_BUCK2_FSM_TRIM0 = 0x014a, + kD2089_BUCK2_FSM_TRIM1 = 0x014b, + kD2089_BUCK2_FSM_TRIM2 = 0x014c, + kD2089_BUCK2_FSM_TRIM3 = 0x014d, + kD2089_BUCK2_CLK_TRIM = 0x014e, + kD2089_BUCK2_CALIB0 = 0x0150, + kD2089_BUCK2_ANA_TRIM0 = 0x0152, + kD2089_BUCK2_ANA_TRIM1 = 0x0153, + kD2089_BUCK2_ANA_TRIM2 = 0x0154, + kD2089_BUCK2_ANA_TRIM3 = 0x0155, + + kD2089_BUCK3_VSEL = 0x0160, + kD2089_BUCK3_VSEL_ALT = 0x0161, + kD2089_BUCK3_VSEL_ACTUAL = 0x0162, + kD2089_BUCK3_MINV = 0x0163, + kD2089_BUCK3_MAXV = 0x0164, + kD2089_BUCK3_OFS_V = 0x0165, + kD2089_BUCK3_MODE = 0x0166, + kD2089_BUCK3_START_ILIMIT = 0x0167, + kD2089_BUCK3_SYNC_ILIMIT = 0x0168, + kD2089_BUCK3_SLEEP_ILIMIT = 0x0169, + kD2089_BUCK3_FSM_TRIM0 = 0x016a, + kD2089_BUCK3_FSM_TRIM2 = 0x016c, + kD2089_BUCK3_FSM_TRIM3 = 0x016d, + kD2089_BUCK3_CLK_TRIM = 0x016e, + kD2089_BUCK3_CALIB_OFFSET_TRIM = 0x016f, + kD2089_BUCK3_CALIB0 = 0x0170, + kD2089_BUCK3_ANA_TRIM0 = 0x0172, + kD2089_BUCK3_ANA_TRIM1 = 0x0173, + kD2089_BUCK3_ANA_TRIM2 = 0x0174, + kD2089_BUCK3_ANA_TRIM3 = 0x0175, + + kD2089_BUCK4_VSEL = 0x0180, + kD2089_BUCK4_VSEL_ALT = 0x0181, + kD2089_BUCK4_VSEL_ACTUAL = 0x0182, + kD2089_BUCK4_MINV = 0x0183, + kD2089_BUCK4_MAXV = 0x0184, + kD2089_BUCK4_OFS_V = 0x0185, + kD2089_BUCK4_MODE = 0x0186, + kD2089_BUCK4_START_ILIMIT = 0x0187, + kD2089_BUCK4_SYNC_ILIMIT = 0x0188, + kD2089_BUCK4_SLEEP_ILIMIT = 0x0189, + kD2089_BUCK4_FSM_TRIM0 = 0x018a, + kD2089_BUCK4_FSM_TRIM2 = 0x018c, + kD2089_BUCK4_FSM_TRIM3 = 0x018d, + kD2089_BUCK4_CLK_TRIM = 0x018e, + kD2089_BUCK4_CALIB0 = 0x0190, + kD2089_BUCK4_ANA_TRIM0 = 0x0192, + kD2089_BUCK4_ANA_TRIM1 = 0x0193, + kD2089_BUCK4_ANA_TRIM2 = 0x0194, + kD2089_BUCK4_ANA_TRIM3 = 0x0195, + + kD2089_BUCK5_VSEL = 0x01a0, + kD2089_BUCK5_VSEL_ACTUAL = 0x01a2, + kD2089_BUCK5_MINV = 0x01a3, + kD2089_BUCK5_MAXV = 0x01a4, + kD2089_BUCK5_OFS_V = 0x01a5, + kD2089_BUCK5_MODE = 0x01a6, + kD2089_BUCK5_START_ILIMIT = 0x01a7, + kD2089_BUCK5_SYNC_ILIMIT = 0x01a8, + kD2089_BUCK5_SLEEP_ILIMIT = 0x01a9, + kD2089_BUCK5_FSM_TRIM0 = 0x01aa, + kD2089_BUCK5_FSM_TRIM2 = 0x01ac, + kD2089_BUCK5_FSM_TRIM3 = 0x01ad, + kD2089_BUCK5_CLK_TRIM = 0x01ae, + kD2089_BUCK5_CALIB_OFFSET_TRIM = 0x01af, + kD2089_BUCK5_CALIB0 = 0x01b0, + kD2089_BUCK5_ANA_TRIM0 = 0x01b2, + kD2089_BUCK5_ANA_TRIM1 = 0x01b3, + kD2089_BUCK5_ANA_TRIM2 = 0x01b4, + kD2089_BUCK5_ANA_TRIM3 = 0x01b5, + + kD2089_BUCK6_VSEL = 0x01c0, + kD2089_BUCK6_VSEL_ACTUAL = 0x01c2, + kD2089_BUCK6_MINV = 0x01c3, + kD2089_BUCK6_MAXV = 0x01c4, + kD2089_BUCK6_OFS_V = 0x01c5, + kD2089_BUCK6_MODE = 0x01c6, + kD2089_BUCK6_ILIMIT = 0x01c7, + + kD2089_BUCK6_FSM_TRIM0 = 0x01c8, + kD2089_BUCK6_FSM_TRIM1 = 0x01c9, + kD2089_BUCK6_FSM_TRIM2 = 0x01ca, + kD2089_BUCK6_FSM_TRIM3 = 0x01cb, + kD2089_BUCK6_CLK_TRIM = 0x01cc, + kD2089_BUCK6_CALIB_OFFSET_TRIM = 0x01cd, + kD2089_BUCK6_CALIB0 = 0x01ce, + kD2089_BUCK6_ANA_TRIM0 = 0x01d0, + kD2089_BUCK6_ANA_TRIM1 = 0x01d1, + kD2089_BUCK6_ANA_TRIM2 = 0x01d2, + +// LDO Control + + kD2089_LDO_RTC_TRIM = 0x0304, + kD2089_LDO1_VSEL = 0x0308, + kD2089_LDO1_VSEL_ACTUAL = 0x0309, + kD2089_LDO1_MINV = 0x030a, + kD2089_LDO1_MAXV = 0x030b, + kD2089_LDO2_VSEL = 0x0310, + kD2089_LDO2_VSEL_ACTUAL = 0x0311, + kD2089_LDO2_MINV = 0x0312, + kD2089_LDO2_MAXV = 0x0313, + kD2089_LDO3_VSEL = 0x0318, + kD2089_LDO3_VSEL_ACTUAL = 0x0319, + kD2089_LDO3_MINV = 0x031a, + kD2089_LDO3_MAXV = 0x031b, + kD2089_LDO4_VSEL = 0x0320, + kD2089_LDO4_VSEL_ACTUAL = 0x0321, + kD2089_LDO4_MINV = 0x0322, + kD2089_LDO4_MAXV = 0x0323, + kD2089_LDO5_VSEL = 0x0328, + kD2089_LDO5_VSEL_ACTUAL = 0x0329, + kD2089_LDO5_MINV = 0x032a, + kD2089_LDO5_MAXV = 0x032b, + kD2089_LDO5_TRIM = 0x032c, + kD2089_LDO6_VSEL = 0x0330, + kD2089_LDO6_VSEL_ACTUAL = 0x0331, + kD2089_LDO6_MINV = 0x0332, + kD2089_LDO6_MAXV = 0x0333, + kD2089_LDO6_TRIM = 0x0334, + kD2089_LDO7_VSEL = 0x0338, + kD2089_LDO7_VSEL_ACTUAL = 0x0339, + kD2089_LDO7_MINV = 0x033a, + kD2089_LDO7_MAXV = 0x033b, + kD2089_LDO8_VSEL = 0x0340, + kD2089_LDO8_VSEL_ACTUAL = 0x0341, + kD2089_LDO8_MINV = 0x0342, + kD2089_LDO8_MAXV = 0x0343, + kD2089_LDO9_VSEL = 0x0348, + kD2089_LDO9_VSEL_ACTUAL = 0x0349, + kD2089_LDO9_MINV = 0x034a, + kD2089_LDO9_MAXV = 0x034b, + kD2089_LDO10_VSEL = 0x0350, + kD2089_LDO10_VSEL_ACTUAL = 0x0351, + kD2089_LDO10_MINV = 0x0352, + kD2089_LDO10_MAXV = 0x0353, + kD2089_LDO11_VSEL = 0x0358, + kD2089_LDO11_VSEL_ACTUAL = 0x0359, + kD2089_LDO11_MINV = 0x035a, + kD2089_LDO11_MAXV = 0x035b, + kD2089_LDO13_VSEL = 0x0368, + kD2089_LDO13_VSEL_ACTUAL = 0x0369, + kD2089_LDO13_MINV = 0x036a, + kD2089_LDO13_MAXV = 0x036b, + kD2089_LCM_LDO1 = 0x0370, + kD2089_LCM_LDO1_VSEL_ACTUAL = 0x0371, + kD2089_LCM_LDO1_MINV = 0x0372, + kD2089_LCM_LDO1_MAXV = 0x0373, + kD2089_LCM_LDO1_TRIM = 0x0374, + kD2089_LCM_LDO2 = 0x0378, + kD2089_LCM_LDO2_VSEL_ACTUAL = 0x0379, + kD2089_LCM_LDO2_MINV = 0x037a, + kD2089_LCM_LDO2_MAXV = 0x037b, + kD2089_LCM_LDO3 = 0x0380, + kD2089_LCM_LDO3_VSEL_ACTUAL = 0x0381, + kD2089_LCM_LDO3_MINV = 0x0382, + kD2089_LCM_LDO3_MAXV = 0x0383, + kD2089_LDO_BYP1 = 0x0388, + kDIALOG_LDO_CONTROL = kD2089_LDO_BYP1, + +// LCM Boost Control + + kD2089_LCM_BOOST_VSEL = 0x0398, + kD2089_LCM_BOOST_VSEL_ACTUAL = 0x0399, + kD2089_LCM_BOOST_MINV = 0x039a, + kD2089_LCM_BOOST_MAXV = 0x039b, + kD2089_LCM_BOOST_CONF = 0x039c, + kD2089_LCM_BOOST_TRIM = 0x039d, + +// Hibernate Switches + + kD2089_HIB_SW_CTRL = 0x03c0, + kD2089_HIB_SW_CTRL_2 = 0x03c1, + +// GPIO Control + + kD2089_GPIO1 = 0x0400, + kDIALOG_SYS_GPIO_REG_START = kD2089_GPIO1, + kD2089_GPIO2 = 0x0401, + kD2089_GPIO3 = 0x0402, + kD2089_GPIO4 = 0x0403, + kD2089_GPIO5 = 0x0404, + kD2089_GPIO6 = 0x0405, + kD2089_GPIO7 = 0x0406, + kD2089_GPIO8 = 0x0407, + kD2089_GPIO9 = 0x0408, + kD2089_GPIO10 = 0x0409, + kD2089_GPIO11 = 0x040a, + kD2089_GPIO12 = 0x040b, + kD2089_GPIO13 = 0x040c, + kD2089_GPIO14 = 0x040d, + kD2089_GPIO15 = 0x040e, + kD2089_GPIO16 = 0x040f, + kD2089_GPIO17 = 0x0410, + + kD2089_GPIO_DEB1 = 0x0420, + kD2089_GPIO_DEB2 = 0x0421, + kD2089_GPIO_DEB3 = 0x0422, + kD2089_GPIO_DEB4 = 0x0423, + kD2089_GPIO_DEB5 = 0x0424, + kD2089_GPIO_DEB6 = 0x0425, + kD2089_GPIO_DEB7 = 0x0426, + kD2089_GPIO_DEB8 = 0x0427, + kD2089_GPIO_DEB9 = 0x0428, + + kD2089_OUT_32K = 0x0430, + +// GPI Control + + kD2089_BUTTON1_CONF = 0x0440, + kD2089_BUTTON2_CONF = 0x0441, + kD2089_BUTTON3_CONF = 0x0442, + kD2089_BUTTON4_CONF = 0x0443, + kDIALOG_BUTTON_DBL = 0x0444, + kD2089_BUTTON_WAKE = 0x0445, + + kD2089_RESET_IN1_CONF = 0x0448, + kD2089_RESET_IN2_CONF = 0x0449, + kD2089_RESET_IN3_CONF = 0x044a, + kD2089_RIN_POL_RISE = (0<<4), + kD2089_RIN_POL_FALL = (1<<4), + kD2089_RIN_NO_PUPD = (0<<2), + kD2089_RIN_PU = (1<<2), + kD2089_RIN_PD = (2<<2), + kD2089_RIN_T_DEB_10MS = (0<<1), + kD2089_RIN_T_DEB_100MS = (1<<1), + kD2089_RIN_ENABLED = (0<<0), + kD2089_RIN_DISABLED = (1<<0), + +// Temperature Sensor Control + + kD2089_TDEV1_RISE = 0x0480, + kD2089_TDEV1_FALL = 0x0481, + kD2089_TDEV2_RISE = 0x0482, + kD2089_TDEV2_FALL = 0x0483, + kD2089_TDEV3_RISE = 0x0484, + kD2089_TDEV3_FALL = 0x0485, + kD2089_TDEV4_RISE = 0x0486, + kD2089_TDEV4_FALL = 0x0487, + kD2089_TDEV5_RISE = 0x0488, + kD2089_TDEV5_FALL = 0x0489, + kD2089_TDEV6_RISE = 0x048a, + kD2089_TDEV6_FALL = 0x048b, + kD2089_TDEV7_RISE = 0x048c, + kD2089_TDEV7_FALL = 0x048d, + kD2089_TDEV8_RISE = 0x048e, + kD2089_TDEV8_FALL = 0x048f, + kD2089_TLDO5_RISE = 0x04a0, + kD2089_TCBUCK_A_RISE = 0x04a2, + kD2089_TCBUCK_B_RISE = 0x04a3, + kD2089_TLINCHG_RISE = 0x04a4, + kD2089_TBUCK0_RISE = 0x04a5, + kD2089_TBUCK1_RISE = 0x04a6, + kD2089_TBUCK52_RISE = 0x04a7, + kD2089_TBUCK34_RISE = 0x04a8, + kD2089_TBUCK06_RISE = 0x04a9, + kD2089_TISENSE_HYST = 0x04aa, + kDIALOG_T_OFFSET_MSB = 0x04ab, + kDIALOG_T_OFFSET_LSB = 0x04ac, + +// Charging Control + + kD2089_ISET_BUCK = 0x04c0, + kD2089_ISET_BUCK_SHADOW = 0x04c1, + kD2089_ISET_BUCK_ABSMAX = 0x04c2, + kD2089_ISET_BUCK_ACTUAL = 0x04c3, + kD2089_ISET_BUCK_ALT = 0x04c4, + kDIALOG_CHARGE_BUCK_CONTROL = kD2089_ISET_BUCK, + kDIALOG_CHARGE_BUCK_STATUS = kD2089_ISET_BUCK_ACTUAL, + kD2089_CHG_CTRL_A = 0x04c5, + kD2089_CHG_CTRL_B = 0x04c6, + kD2089_CHG_CTRL_C = 0x04c7, + kD2089_CHG_CTRL_D = 0x04c8, + kD2089_CHG_CTRL_E = 0x04c9, + kD2089_CHG_CTRL_F = 0x04ca, + kD2089_CHG_CTRL_G = 0x04cb, + kD2089_CHG_TIME = 0x04cc, + kD2089_CHG_TIME_PRE = 0x04cd, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD2089_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_HIB = kD2089_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_TIME = kD2089_CHG_CTRL_D, + kDIALOG_CHARGE_CONTROL_EN = kD2089_CHG_CTRL_A, + kDIALOG_OTP_ISET_BAT = kD2089_CHG_CTRL_C, + kDIALOG_CHARGE_STATUS = 0x04ce, + kD2089_CHG_VSET_TRIM = 0x04cf, + kD2089_IBUS_GAIN_TRIM = 0x04d1, + kD2089_IBUS100_OFS_TRIM = 0x04d2, + kD2089_IBUS500_OFS_TRIM = 0x04d3, + kD2089_IBUS1500_GAIN_TRIM= 0x04d4, + kD2089_IBUS1500_OFS_TRIM= 0x04d5, + + kD2089_CHG_TRIM1 = 0x04d6, + kD2089_CHG_TRIM2 = 0x04d7, + kD2089_CHG_TRIM3 = 0x04d8, + kD2089_CHG_TRIM4 = 0x04d9, + kD2089_CHG_TRIM5 = 0x04da, + kD2089_ICHG_END = 0x04db, + + kDIALOG_TBAT_0 = 0x04dc, + kDIALOG_TBAT_1 = 0x04dd, + kDIALOG_TBAT_2 = 0x04de, + kDIALOG_TBAT_3 = 0x04df, + kDIALOG_TBAT_4 = 0x04e0, + kDIALOG_TBAT_MAX = 0x04e1, + kDIALOG_ICHG_TBAT_0 = 0x04e2, + kDIALOG_ICHG_TBAT_1 = 0x04e3, + kDIALOG_ICHG_TBAT_2 = 0x04e4, + kDIALOG_ICHG_TBAT_3 = 0x04e5, + kDIALOG_ICHG_TBAT_4 = 0x04e6, + kDIALOG_ICHG_AVG = 0x04e7, + +// GPADC Control and Results + + kDIALOG_ADC_CONTROL = 0x0500, + kDIALOG_ADC_CONTROL2 = 0x0501, + kDIALOG_ADC_LSB = 0x0502, + kDIALOG_ADC_MSB = 0x0503, + kD2089_ADC_TEMP_CTRL0 = 0x0504, + kD2089_ADC_TEMP_CTRL1 = 0x0505, + kD2089_ADC_FSM_TRIM0 = 0x0506, + kD2089_ADC_FSM_TRIM1 = 0x0507, + kD2089_ADC_FSM_TRIM2 = 0x0508, + kD2089_ADC_FSM_TRIM3 = 0x0509, + kD2089_ADC_ANA_TRIM0 = 0x050a, + kD2089_VCC_MAIN_MON = 0x050c, + kDIALOG_IBUS_ACCUM1 = 0x050e, + kDIALOG_IBUS_ACCUM2 = 0x050f, + kDIALOG_IBUS_ACCUM3 = 0x0510, + kDIALOG_VBUS_ACCUM1 = 0x0511, + kDIALOG_VBUS_ACCUM2 = 0x0512, + kDIALOG_VBUS_ACCUM3 = 0x0513, + kDIALOG_TDIE_ACCUM1 = 0x0514, + kDIALOG_TDIE_ACCUM2 = 0x0515, + kDIALOG_TDIE_ACCUM3 = 0x0516, + kDIALOG_IBUS_COUNT1 = 0x0517, + kDIALOG_IBUS_COUNT2 = 0x0518, + kD2089_IBUSCAL_1 = 0x0519, + kD2089_IBUSCAL_2 = 0x051a, + kD2089_IBUSCAL_3 = 0x051b, + kD2089_IBUSCAL_4 = 0x051c, + kD2089_IBUSCAL_5 = 0x051d, + kD2089_IBUSCAL_6 = 0x051e, + kD2089_IBUSCAL_7 = 0x051f, + kD2089_IBUSCAL_8 = 0x0520, + kD2089_IBUCK0_ACCUM1 = 0x0522, + kD2089_IBUCK0_ACCUM2 = 0x0523, + kD2089_IBUCK0_ACCUM3 = 0x0524, + kD2089_IBUCK1_ACCUM1 = 0x0525, + kD2089_IBUCK1_ACCUM2 = 0x0526, + kD2089_IBUCK1_ACCUM3 = 0x0527, + kDIALOG_IBUCK0_COUNT1 = 0x0528, + kDIALOG_IBUCK0_COUNT2 = 0x0529, + kDIALOG_IBUCK1_COUNT1 = 0x052a, + kDIALOG_IBUCK1_COUNT2 = 0x052b, + +// BIST ADC Control and Results + + kDIALOG_APP_TMUX = 0x0540, + kDIALOG_BIST_ADC_CTRL = 0x0541, + kDIALOG_BIST_ADC_LSB = 0x0542, + kDIALOG_BIST_ADC_MSB = 0x0543, + kD2089_BIST_ADC_TRIM1 = 0x0545, + kD2089_BIST_ADC_ANA_TRIM0 = 0x0546, + +// RTC Calendar and Alarm + + kDIALOG_RTC_ALARM_A = 0x05c0, + kDIALOG_RTC_ALARM_B = 0x05c1, + kDIALOG_RTC_ALARM_C = 0x05c2, + kDIALOG_RTC_ALARM_D = 0x05c3, + kDIALOG_RTC_CONTROL = 0x05c4, + kDIALOG_RTC_TIMEZONE = 0x05c5, + kDIALOG_RTC_SUB_SECOND_A = 0x05c6, + kDIALOG_RTC_SUB_SECOND_B = 0x05c7, + kDIALOG_RTC_SECOND_A = 0x05c8, + kDIALOG_RTC_SECOND_B = 0x05c9, + kDIALOG_RTC_SECOND_C = 0x05ca, + kDIALOG_RTC_SECOND_D = 0x05cb, + +// WLED + + kD2089_WLED_ISET_MSB = 0x0600, + kD2089_WLED_ISET_LSB = 0x0601, + kD2089_WLED_PWM_MSB = 0x0602, + kD2089_WLED_PWM_LSB = 0x0603, + kD2089_WLED_CTRL1 = 0x0604, + kD2089_WLED_CTRL2 = 0x0605, + kD2089_WLED_CTRL3 = 0x0606, + kD2089_WLED_CTRL4 = 0x0607, + kD2089_WLED_CTRL5 = 0x0608, + kD2089_WLED_CTRL6 = 0x0609, + kD2089_WLED_CTRL7 = 0x060a, + kD2089_WLED_ERR_STAT_A = 0x060b, + kD2089_WLED_ERR_STAT_B = 0x060c, + kD2089_WLED_CONF1 = 0x060d, + kD2089_WLED_CONF2 = 0x060e, + kD2089_WLED_CONF3 = 0x060f, + kD2089_WLED_TRIM1 = 0x0610, + kD2089_WLED_TRIM2 = 0x0611, + kD2089_WLED_TRIM3 = 0x0612, + kD2089_WLED_TRIM4 = 0x0613, + kD2089_WLED_TRIM5 = 0x0614, + kD2089_WLED_TRIM6 = 0x0615, + kD2089_WLED_TRIM7 = 0x0616, + kD2089_WLED_TRIM8 = 0x0617, + kD2089_WLED_TRIM9 = 0x0618, + kD2089_WLED_TRIM10 = 0x0619, + kD2089_WLED_TRIM11 = 0x061a, + kD2089_WLED_TRIM12 = 0x061b, + kD2089_WLED_TRIM13 = 0x061c, + kD2089_WLED_TRIM14 = 0x061d, + kD2089_WLED_TRIM15 = 0x061e, + kD2089_WLED_TRIM16 = 0x061f, + kD2089_WLED_TRIM17 = 0x0620, + kD2089_WLED_TRIM18 = 0x0621, + kD2089_WLED_TRIM19 = 0x0622, + kD2089_WLED_TRIM20 = 0x0623, + + kDIALOG_WLED_ISET = kD2089_WLED_ISET_MSB, + kDIALOG_WLED_ISET2 = kD2089_WLED_ISET_LSB, + kDIALOG_WLED_CONTROL = kD2089_WLED_CTRL1, + kDIALOG_WLED_DWI_CONTROL= kD2089_WLED_CTRL2, + kDIALOG_WLED_OPTIONS = kD2089_WLED_CTRL2, + +// Reserved Spare Registers + + kD2089_SPARE_RW0 = 0x0680, + kD2089_SPARE_RW_LAST = 0x0687, + kD2089_SPARE_RWTOTP0 = 0x06a0, + kD2089_SPARE_RWTOTP_LAST= 0x06a7, + kD2089_SPARE_RWOTP0 = 0x06c0, + kD2089_SPARE_RWOTP1 = 0x0610, + +// Legacy Scratch Pads + + kDIALOG_MEMBYTE0 = 0x4000, + kDIALOG_MEMBYTE_LAST = 0x4027, + +// Scratch Pad RAM + + kDIALOG_RAM0 = 0x8000, + kDIALOG_EXT_MEM_CAL0 = kDIALOG_RAM0, + kDIALOG_EXT_MEM_CAL0_SIZE = 64, + kDIALOG_DIAG_SCRATCH = kDIALOG_EXT_MEM_CAL0+kDIALOG_EXT_MEM_CAL0_SIZE, // + kDIALOG_DIAG_SCRATCH_SIZE = 8, + kDIALOG_EXT_MEM_CAL1= kDIALOG_DIAG_SCRATCH+kDIALOG_DIAG_SCRATCH_SIZE, + kDIALOG_EXT_MEM_CAL1_SIZE= 336, + kDIALOG_VOLTAGE_KNOBS = kDIALOG_EXT_MEM_CAL1+kDIALOG_EXT_MEM_CAL1_SIZE, + kDIALOG_VOLTAGE_KNOBS_SIZE=32, + + kDIALOG_EXT_MEM_CAL_SIZE= kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_EXT_MEM_CAL1_SIZE, + + kDIALOG_RAM_LAST = 0x87ff, +}; + + +// Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 4, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, + kDIALOG_IBUCK0_ACCUMULATOR = 2, + kDIALOG_IBUCK1_ACCUMULATOR = 3, +}; + +enum { + kD2089_EVENT_A_TBAT = (1 << 7), + kD2089_EVENT_A_VBUS_EXT_REM = (1 << 6), + kD2089_EVENT_A_VDD_LOW = (1 << 5), + kD2089_EVENT_A_CHG_HV_ATT = (1 << 4), + kD2089_EVENT_A_VBUS_EXT_DET = (1 << 3), + kD2089_EVENT_A_ACC_DET = (1 << 2), + kD2089_EVENT_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2089_EVENT_B_BTN4_DBL = (1 << 7), + kD2089_EVENT_B_BTN3_DBL = (1 << 6), + kD2089_EVENT_B_BTN2_DBL = (1 << 5), + kD2089_EVENT_B_BTN1_DBL = (1 << 4), + kD2089_EVENT_B_BUTTON_4 = (1 << 3), + kD2089_EVENT_B_BUTTON_3 = (1 << 2), + kD2089_EVENT_B_BUTTON_2 = (1 << 1), + kD2089_EVENT_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2089_EVENT_C_CHG_BUCK_FLG = (1 << 6), + kD2089_EVENT_C_CHG_ABCC_ACT = (1 << 5), + kD2089_EVENT_C_CHG_TIMEOUT = (1 << 4), + kD2089_EVENT_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2089_EVENT_C_CHG_END = (1 << 2), + kD2089_EVENT_C_CHG_FAST = (1 << 1), + kD2089_EVENT_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2089_EVENT_D_GPIO8 = (1 << 7), + kD2089_EVENT_D_GPIO7 = (1 << 6), + kD2089_EVENT_D_GPIO6 = (1 << 5), + kD2089_EVENT_D_GPIO5 = (1 << 4), + kD2089_EVENT_D_GPIO4 = (1 << 3), + kD2089_EVENT_D_GPIO3 = (1 << 2), + kD2089_EVENT_D_GPIO2 = (1 << 1), + kD2089_EVENT_D_GPIO1 = (1 << 0), +}; + +enum { + kD2089_EVENT_E_GPIO16 = (1 << 7), + kD2089_EVENT_E_GPIO15 = (1 << 6), + kD2089_EVENT_E_GPIO14 = (1 << 5), + kD2089_EVENT_E_GPIO13 = (1 << 4), + kD2089_EVENT_E_GPIO12 = (1 << 3), + kD2089_EVENT_E_GPIO11 = (1 << 2), + kD2089_EVENT_E_GPIO10 = (1 << 1), + kD2089_EVENT_E_GPIO9 = (1 << 0), +}; + +enum { + kD2089_EVENT_F_GPIO17 = (1 << 0), +}; + +enum { + kD2089_EVENT_G_T4_RISE = (1 << 7), + kD2089_EVENT_G_T4_FALL = (1 << 6), + kD2089_EVENT_G_T3_RISE = (1 << 5), + kD2089_EVENT_G_T3_FALL = (1 << 4), + kD2089_EVENT_G_T2_RISE = (1 << 3), + kD2089_EVENT_G_T2_FALL = (1 << 2), + kD2089_EVENT_G_T1_RISE = (1 << 1), + kD2089_EVENT_G_T1_FALL = (1 << 0), +}; + +enum { + kD2089_EVENT_H_T8_RISE = (1 << 7), + kD2089_EVENT_H_T8_FALL = (1 << 6), + kD2089_EVENT_H_T7_RISE = (1 << 5), + kD2089_EVENT_H_T7_FALL = (1 << 4), + kD2089_EVENT_H_T6_RISE = (1 << 3), + kD2089_EVENT_H_T6_FALL = (1 << 2), + kD2089_EVENT_H_T5_RISE = (1 << 1), + kD2089_EVENT_H_T5_FALL = (1 << 0), +}; + +enum { + kD2089_EVENT_I_TLDO5 = (1 << 7), + kD2089_EVENT_I_TBUCK_0_6 = (1 << 4), + kD2089_EVENT_I_TBUCK_3_4 = (1 << 3), + kD2089_EVENT_I_TBUCK_5_2 = (1 << 2), + kD2089_EVENT_I_TBUCK1 = (1 << 1), + kD2089_EVENT_I_TBUCK0 = (1 << 0), +}; + +enum { + kD2089_EVENT_J_HIGH_TEMP_WARNING = (1 << 7), + kD2089_EVENT_J_WLEDB_SHORT = (1 << 6), + kD2089_EVENT_J_WLEDB_OPEN = (1 << 5), + kD2089_EVENT_J_WLEDA_SHORT = (1 << 4), + kD2089_EVENT_J_WLEDA_OPEN = (1 << 3), + kD2089_EVENT_J_TLINCHG = (1 << 2), + kD2089_EVENT_J_TCBUCK_B = (1 << 1), + kD2089_EVENT_J_TCBUCK_A = (1 << 0), +}; + +enum { + kD2089_EVENT_K_XTAL_ERROR = (1 << 6), + kD2089_EVENT_K_VBUS_OV = (1 << 5), + kD2089_EVENT_K_VBUS_OC = (1 << 4), + kD2089_EVENT_K_LDO6_OC = (1 << 0), +}; + +enum { + kD2089_EVENT_L_IBUCK1_OVERFLOW = (1 << 7), + kD2089_EVENT_L_IBUCK0_OVERFLOW = (1 << 6), + kD2089_EVENT_L_IBUS_OVERFLOW = (1 << 5), + kD2089_EVENT_L_HIB = (1 << 4), + kD2089_EVENT_L_DWI_TO = (1 << 3), + kD2089_EVENT_L_EOMC_BIST = (1 << 2), + kD2089_EVENT_L_EOMC = (1 << 1), + kD2089_EVENT_L_ALARM = (1 << 0), +}; + +enum { + kD2089_EVENT_M_BUCK2_POS_ILIM_MON = (1 << 7), + kD2089_EVENT_M_BUCK2_NEG_ILIM_MON = (1 << 6), + kD2089_EVENT_M_BUCK1_POS_ILIM_MON = (1 << 5), + kD2089_EVENT_M_BUCK1_NEG_ILIM_MON = (1 << 4), + kD2089_EVENT_M_BUCK0_POS_ILIM_MON = (1 << 3), + kD2089_EVENT_M_BUCK0_NEG_ILIM_MON = (1 << 2), +}; + +enum { + kD2089_EVENT_N_BUCK6_POS_ILIM_MON = (1 << 7), + kD2089_EVENT_N_BUCK6_NEG_ILIM_MON = (1 << 6), + kD2089_EVENT_N_BUCK5_POS_ILIM_MON = (1 << 5), + kD2089_EVENT_N_BUCK5_NEG_ILIM_MON = (1 << 4), + kD2089_EVENT_N_BUCK4_POS_ILIM_MON = (1 << 3), + kD2089_EVENT_N_BUCK4_NEG_ILIM_MON = (1 << 2), + kD2089_EVENT_N_BUCK3_POS_ILIM_MON = (1 << 1), + kD2089_EVENT_N_BUCK3_NEG_ILIM_MON = (1 << 0), +}; + +enum { + kD2089_STATUS_A_TBAT = (1 << 7), + kD2089_STATUS_A_VDD_LOW = (1 << 5), + kD2089_STATUS_A_CHG_HV_ATT = (1 << 4), + kD2089_STATUS_A_VBUS_EXT_DET= (1 << 3), + kD2089_STATUS_A_ACC_DET = (1 << 2), + kD2089_STATUS_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2089_STATUS_B_BUTTON_4 = (1 << 3), + kD2089_STATUS_B_BUTTON_3 = (1 << 2), + kD2089_STATUS_B_BUTTON_2 = (1 << 1), + kD2089_STATUS_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2089_STATUS_C_CHG_HV_EN = (1 << 7), + kD2089_STATUS_C_CHG_BUCK_FLG= (1 << 6), + kD2089_STATUS_C_CHG_ABCC_ACT= (1 << 5), + kD2089_STATUS_C_CHG_TIMEOUT = (1 << 4), + kD2089_STATUS_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2089_STATUS_C_CHG_END = (1 << 2), + kD2089_STATUS_C_CHG_FAST = (1 << 1), + kD2089_STATUS_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2089_STATUS_D_GPIO8 = (1 << 7), + kD2089_STATUS_D_GPIO7 = (1 << 6), + kD2089_STATUS_D_GPIO6 = (1 << 5), + kD2089_STATUS_D_GPIO5 = (1 << 4), + kD2089_STATUS_D_GPIO4 = (1 << 3), + kD2089_STATUS_D_GPIO3 = (1 << 2), + kD2089_STATUS_D_GPIO2 = (1 << 1), + kD2089_STATUS_D_GPIO1 = (1 << 0), +}; + +enum { + kD2089_STATUS_E_GPIO16 = (1 << 7), + kD2089_STATUS_E_GPIO15 = (1 << 6), + kD2089_STATUS_E_GPIO14 = (1 << 5), + kD2089_STATUS_E_GPIO13 = (1 << 4), + kD2089_STATUS_E_GPIO12 = (1 << 3), + kD2089_STATUS_E_GPIO11 = (1 << 2), + kD2089_STATUS_E_GPIO10 = (1 << 1), + kD2089_STATUS_E_GPIO9 = (1 << 0), +}; + +enum { + kD2089_STATUS_F_GPIO17 = (1 << 0), +}; + +enum { + kD2089_STATUS_G_T4_RISE = (1 << 7), + kD2089_STATUS_G_T4_FALL = (1 << 6), + kD2089_STATUS_G_T3_RISE = (1 << 5), + kD2089_STATUS_G_T3_FALL = (1 << 4), + kD2089_STATUS_G_T2_RISE = (1 << 3), + kD2089_STATUS_G_T2_FALL = (1 << 2), + kD2089_STATUS_G_T1_RISE = (1 << 1), + kD2089_STATUS_G_T1_FALL = (1 << 0), +}; + +enum { + kD2089_STATUS_H_T8_RISE = (1 << 7), + kD2089_STATUS_H_T8_FALL = (1 << 6), + kD2089_STATUS_H_T7_RISE = (1 << 5), + kD2089_STATUS_H_T7_FALL = (1 << 4), + kD2089_STATUS_H_T6_RISE = (1 << 3), + kD2089_STATUS_H_T6_FALL = (1 << 2), + kD2089_STATUS_H_T5_RISE = (1 << 1), + kD2089_STATUS_H_T5_FALL = (1 << 0), +}; + +enum { + kD2089_STATUS_I_TLDO5 = (1 << 7), + kD2089_STATUS_I_TBUCK_0_6 = (1 << 4), + kD2089_STATUS_I_TBUCK_3_4 = (1 << 3), + kD2089_STATUS_I_TBUCK_5_2 = (1 << 2), + kD2089_STATUS_I_TBUCK1 = (1 << 1), + kD2089_STATUS_I_TBUCK0 = (1 << 0), +}; + +enum { + kD2089_STATUS_J_HIGH_TEMP_WARNING = (1 << 7), + kD2089_STATUS_J_TLINCHG = (1 << 2), + kD2089_STATUS_J_TCBUCK_B = (1 << 1), + kD2089_STATUS_J_TCBUCK_A = (1 << 0), +}; + +enum { + kD2089_STATUS_K_XTAL_ERROR = (1 << 6), + kD2089_STATUS_K_VBUS_OV = (1 << 5), + kD2089_STATUS_K_VBUS_OC = (1 << 4), +}; + +enum { + kD2089_STATUS_L_IBUCK1_OVERFLOW = (1 << 7), + kD2089_STATUS_L_IBUCK0_OVERFLOW = (1 << 6), + kD2089_STATUS_L_IBUS_OVERFLOW = (1 << 5), +}; + +enum { + kD2089_STATUS_M_PROT_FET_ON = (1 << 1), + kD2089_STATUS_M_CHG_ATT = (1 << 0), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2089_EVENT_B_BUTTON_2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2089_EVENT_B_BUTTON_1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(1, kD2089_EVENT_B_BUTTON_3), + kDIALOG_EVENT_BUTTON4_MASK= EVENT_FLAG_MAKE(1, kD2089_EVENT_B_BUTTON_4), + kDIALOG_EVENT_BUTTONS = (kD2089_EVENT_B_BUTTON_4 | + kD2089_EVENT_B_BUTTON_3 | + kD2089_EVENT_B_BUTTON_2 | + kD2089_EVENT_B_BUTTON_1), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(11, kD2089_EVENT_L_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD2089_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD2089_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(0, kD2089_EVENT_A_VBUS_EXT_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(11, kD2089_EVENT_L_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(11, kD2089_EVENT_L_HIB), + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(2, kD2089_EVENT_C_CHG_ABCC_ACT), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(2, kD2089_EVENT_C_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(0, kD2089_EVENT_A_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(3, kD2089_EVENT_D_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(4, kD2089_EVENT_E_GPIO16), + kDIALOG_EVENT_GPIO17_MASK = EVENT_FLAG_MAKE(5, kD2089_EVENT_F_GPIO17), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(1, kD2089_EVENT_B_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(1, kD2089_EVENT_B_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(1, kD2089_EVENT_B_BTN3_DBL), + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, +}; + +// FIX ME +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD2089_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD2089_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD2089_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(3, kD2089_STATUS_C_CHG_PRE | kD2089_STATUS_C_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(2, kD2089_STATUS_C_CHG_TIMEOUT), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(2, kD2089_STATUS_C_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(0, kD2089_STATUS_A_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(12, kD2089_STATUS_M_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(2, kD2089_STATUS_C_CHG_ABCC_ACT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(3 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {0, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, 0, kD2089_STATUS_C_CHG_PRE | kD2089_STATUS_C_CHG_FAST }; + +enum { + kD2089_EVENT_A_WAKEMASK = (kD2089_EVENT_A_VBUS_EXT_DET | + kD2089_EVENT_A_VCENTER_DET | + kD2089_EVENT_A_ACC_DET), + kD2089_EVENT_B_WAKEMASK = (kD2089_EVENT_B_BUTTON_1 | + kD2089_EVENT_B_BUTTON_2 | + kD2089_EVENT_B_BUTTON_3 | + kD2089_EVENT_B_BUTTON_4), + kD2089_EVENT_C_WAKEMASK = 0, + kD2089_EVENT_D_WAKEMASK = 0, + kD2089_EVENT_E_WAKEMASK = 0, + kD2089_EVENT_F_WAKEMASK = 0, + kD2089_EVENT_G_WAKEMASK = 0, + kD2089_EVENT_H_WAKEMASK = 0, + kD2089_EVENT_I_WAKEMASK = 0, + kD2089_EVENT_J_WAKEMASK = 0, + kD2089_EVENT_K_WAKEMASK = 0, + kD2089_EVENT_L_WAKEMASK = kD2089_EVENT_L_ALARM, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2089_EVENT_A_WAKEMASK, + ~kD2089_EVENT_B_WAKEMASK, + ~kD2089_EVENT_C_WAKEMASK, + ~kD2089_EVENT_D_WAKEMASK, + ~kD2089_EVENT_E_WAKEMASK, + ~kD2089_EVENT_F_WAKEMASK, + ~kD2089_EVENT_G_WAKEMASK, + ~kD2089_EVENT_H_WAKEMASK, + ~kD2089_EVENT_I_WAKEMASK, + ~kD2089_EVENT_J_WAKEMASK, + ~kD2089_EVENT_K_WAKEMASK, + ~kD2089_EVENT_L_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2089_EVENT_A_WAKEMASK, + kD2089_EVENT_B_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD2089_EVENT_C_WAKEMASK, + kD2089_EVENT_D_WAKEMASK, + kD2089_EVENT_E_WAKEMASK, + kD2089_EVENT_F_WAKEMASK, + kD2089_EVENT_G_WAKEMASK, + kD2089_EVENT_H_WAKEMASK, + kD2089_EVENT_I_WAKEMASK, + kD2089_EVENT_J_WAKEMASK, + kD2089_EVENT_K_WAKEMASK, + kD2089_EVENT_L_WAKEMASK, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD2089_EVENT_A_VBUS_EXT_DET | kD2089_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD2089_EVENT_A_VCENTER_DET, + 0, + kD2089_EVENT_C_CHG_ABCC_ACT, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +enum { + kDialogEventPwrsupplyCount = 2, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 0, +}; + +enum { + kDIALOG_LCM_ACTIVE_BOOST_EN = (1 << 0) | (1 << 1), + kDIALOG_LCM_ACTIVE_MASK = (1 << 2) | (1 << 3) | (1 << 4), +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PROT_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), +}; + +enum { + // FAULT_LOG1 + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 7)), + kDIALOG_FAULT_LOG_RESET_IN_3 = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_2 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + // FAULT_LOG2 + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = FAULTLOG_FLAG_MAKE(1, (1 << 2)), + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = FAULTLOG_FLAG_MAKE(1, (1 << 1)), + kDIALOG_FAULT_LOG_NTC_SHDN = FAULTLOG_FLAG_MAKE(1, (1 << 0)), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x02, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300 = 0x12, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 0x1a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x22, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 0x2a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 0x32, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 0x42, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_975 = 0x48, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x4a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1450 = 0x6e, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500 = 0x72, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1900 = 0x92, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0x9a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100 = 0xa2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2300 = 0xb2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 75, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 8, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 3262, +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_B_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_B_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 50, + kDIALOG_CHARGE_CONTROL_MAX = 3150, +}; + +enum { + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 6), +}; + +enum { + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 7), + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x3f << 0), + + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG = (5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID= (6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG = (9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG, + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (10 << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 9, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG_OFF = (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG_OFF = (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK52_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_B_TEMP= (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (26 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK1_TEMP = (27 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_6_TEMP = (28 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_4_TEMP = (29 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP= (30 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN31 = (31 << 0), + + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK52_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_CBUCK_A_TEMP, + + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK0 = (32 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK1 = (33 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK2 = (34 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK3 = (35 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK4 = (36 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK5 = (37 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK0_OFF = (38 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK1_OFF = (39 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK2_OFF = (40 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK3_OFF = (41 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK4_OFF = (42 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IBUCK5_OFF = (43 << 0), + + kDIALOG_ADC_CONTROL2_AUTO_VDD_OUT_EN = (1 << 7), + kDIALOG_ADC_CONTROL2_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL2_IBUCK1_EN = (1 << 2), + kDIALOG_ADC_CONTROL2_IBUCK0_EN = (1 << 1), + kDIALOG_ADC_CONTROL2_IBUS_EN = (1 << 0), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, + kDIALOG_ADC_CONTROL2_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + + +enum { + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x7f << 0), + +// From Table 65: BIST ADC measurement channel overview + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (0 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (1 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (2 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (3 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (4 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (5 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (6 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (7 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (8 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (9 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO13= (18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO13= (19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11= (20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11= (21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10= (22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10= (23 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM1 = (24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM1 = (25 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM2 = (26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM2 = (27 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLCM3 = (28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILCM3 = (29 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (30 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (31 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUF_ON = (32 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0 = (34 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_WLEDB= (36 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (38 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (40 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (42 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VOUT_WLEDA= (44 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBOOST_LCM= (46 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (48 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (50 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK6 = (52 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK1 = (56 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK5 = (58 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_BUCK3_SW1 = (64 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_BUCK3_SW2 = (66 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_BUCK3_SW3 = (68 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_BUCK4_SW1 = (70 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_BUCK4_SW2 = (72 << 0), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (7 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 5), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (3 << 5), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (4 << 5), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_ENABLE3 = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_ENABLE4 = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_ENABLE5 = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_ENABLE6 = (1 << 5), +}; + +enum { + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN = (1 << 3), + kDIALOG_WLED_CONTROL2_WLED_DITH_EN = (1 << 2), + kDIALOG_WLED_CONTROL2_WLED_DWI_EN = (1 << 1), + kDIALOG_WLED_CONTROL2_WLED_RAMP_EN = (1 << 0), + + kDIALOG_WLED_CONTROL_WLED_DWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL2_WLED_DITH_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS (11) + + + +#define NUM_LDOS 22 +static const struct ldo_params ldo_d2089[NUM_LDOS] = { + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO1_VSEL, kD2089_ACTIVE3, 0x02 }, // LDO1 + { 1200, 5, 0xff, 0xff, 0x04, kD2089_LDO2_VSEL, kD2089_ACTIVE3, 0x04 }, // LDO2 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO3_VSEL, kD2089_ACTIVE3, 0x08 }, // LDO3 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO4_VSEL, kD2089_ACTIVE3, 0x10 }, // LDO4 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO5_VSEL, kD2089_ACTIVE3, 0x20 }, // LDO5 + { 1200, 25, 0x7f, 0x7f, 0x40, kD2089_LDO6_VSEL, kD2089_ACTIVE3, 0x40 }, // LDO6 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO7_VSEL, kD2089_ACTIVE3, 0x80 }, // LDO7 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO8_VSEL, kD2089_ACTIVE4, 0x01 }, // LDO8 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO9_VSEL, kD2089_ACTIVE4, 0x02 }, // LDO9 + { 600, 12, 0xff, 0xff, 0x00, kD2089_LDO10_VSEL, kD2089_ACTIVE4, 0x04 }, // LDO10 - actually 12.5mv steps (FIXME) + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO11_VSEL, kD2089_ACTIVE4, 0x08 }, // LDO11 + { 0, 0, 0, 0, 0x00, 0, kD2089_ACTIVE4, 0x00 }, // there is no LDO12 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2089_LDO13_VSEL, kD2089_ACTIVE4, 0x20 }, // LDO13 + + { 5000, 50, 0x1f, 0x1f, 0x0, kD2089_LCM_BOOST_VSEL,kD2089_ACTIVE5, 0x04 }, // "LDO14" / LCM_LDO1 + { 5000, 50, 0x1f, 0x1f, 0x0, kD2089_LCM_BOOST_VSEL,kD2089_ACTIVE5, 0x08 }, // "LDO15" / LCM_LDO2 + { 5000, 50, 0x1f, 0x1f, 0x0, kD2089_LCM_BOOST_VSEL,kD2089_ACTIVE5, 0x10 }, // "LDO16" / LCM_LDO3 + + { 0, 0, 0, 0, 0x00, 0, kD2089_ACTIVE6, 0x01 }, // "LDO17" - BUCK3_SW1_EN + { 0, 0, 0, 0, 0x00, 0, kD2089_ACTIVE6, 0x02 }, // "LDO18" - BUCK3_SW2_EN + { 0, 0, 0, 0, 0x00, 0, kD2089_ACTIVE6, 0x04 }, // "LDO19" - BUCK3_SW3_EN + { 0, 0, 0, 0, 0x00, 0, kD2089_ACTIVE6, 0x10 }, // "LDO20" - BUCK4_SW1_EN + { 0, 0, 0, 0, 0x00, 0, kD2089_ACTIVE6, 0x20 }, // "LDO21" - BUCK4_SW2_EN + + { 0, 0, 0, 0, 0x00, 0, kD2089_HIBERNATE3, 0x40 }, // "LDO22" - set LDO6_EN in HIB +}; +#define LDOP ldo_d2089 + +enum { + kDIALOG_VIB_CTRL_PWM_EN = (1 << 0), + kDIALOG_VIB_CTRL_BRAKE = (1 << 1), + kDIALOG_VIB_CTRL_PWM_CLK_MASK = (3 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_2MHZ = (0 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_1MHZ = (1 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_500KHZ = (2 << 2), + + kDIALOG_VIB_VSET_MASK = (0x3f << 0), +}; + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD2089_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD2089_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD2089_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kD2089_BUTTON_DBL_BTN4_DBL_EN = (1 << 6), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD2089_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD2089_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD2089_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif /* __DIALOG_D2089_H */ diff --git a/drivers/dialog/pmu/d2186.h b/drivers/dialog/pmu/d2186.h new file mode 100644 index 0000000..a7bcd2e --- /dev/null +++ b/drivers/dialog/pmu/d2186.h @@ -0,0 +1,1430 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D2186_H +#define __DIALOG_D2186_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_LCM_LDO 0 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_VIB 1 +#define PMU_HAS_RAM 1 +#define PMU_HAS_WLED 0 +#define PMU_HAS_32K_RTC 1 +#define PMU_HAS_ACCUMULATORS 1 +#define PMU_HAS_GPIO_CONF 1 + +enum { + kDIALOG_ADDR_R = 0xe9, + kDIALOG_ADDR_W = 0xe8, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_EVENT_COUNT = 13, + kDIALOG_STATUS_COUNT = 14, + kDIALOG_FAULTLOG_COUNT = 2, + kDIALOG_CHIPID_COUNT = 4, + kDIALOG_GPIO_COUNT = 21, +}; + +#include "dCommon.h" + +enum { + kDIALOG_MASK_REV_CODE = 0x0000, + kDIALOG_TRIM_REL_CODE = 0x0001, + kDIALOG_PLATFORM_ID = 0x0002, + kDIALOG_DEVICE_ID1 = 0x0004, + kDIALOG_DEVICE_ID2 = 0x0005, + kDIALOG_DEVICE_ID3 = 0x0006, + kDIALOG_DEVICE_ID4 = 0x0007, + kDIALOG_DEVICE_ID5 = 0x0008, + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, + + kD2186_SYS_CTRL1 = 0x0010, + kD2186_SYS_CTRL2 = 0x0011, + kDIALOG_SYS_CONTROL = kD2186_SYS_CTRL1, + kDIALOG_SYS_CONTROL2 = kD2186_SYS_CTRL2, + + kD2186_SYS_CONF_A = 0x0020, + kDIALOG_SYS_CONFIG = kD2186_SYS_CONF_A, + kD2186_SYS_CONF_B = 0x0021, + kD2186_SYS_CONF_C = 0x0022, + kD2186_SYS_CONF_D = 0x0023, + kD2186_BG_TRIM = 0x0024, + kD2186_BG_TC_ADJ = 0x0025, + kD2186_VREF_RTC_TRIM = 0x0026, + kD2186_VREF_AUX_TRIM = 0x0027, + kD2186_VDD_FAULT = 0x0028, + kD2186_RTC_CTRL0 = 0x0029, + kD2186_RTC_CTRL1 = 0x002a, + kD2186_OSC_CTRL0 = 0x002b, + kD2186_INT_OSC_TRIM = 0x002c, + kD2186_CLK_REQ_FRC = 0x002d, + kD2186_UOV_CONTROL = 0x002e, + kD2186_UOV_BLANK_CONTROL = 0x002f, + + kD2186_FAULT_LOG1 = 0x0040, + kD2186_FAULT_LOG2 = 0x0041, + kDIALOG_FAULT_LOG = kD2186_FAULT_LOG1, + kDIALOG_FAULT_LOG2 = kD2186_FAULT_LOG2, + + kD2186_BUCK_1_0_OUV = 0x0042, + kD2186_BUCK_3_2_OUV = 0x0043, + kD2186_BUCK_5_4_OUV = 0x0044, + kD2186_BUCK_6_OUV = 0x0045, + + kD2186_LDO_1_0_OUV = 0x0046, + kD2186_LDO_3_2_OUV = 0x0047, + kD2186_LDO_5_4_OUV = 0x0048, + kD2186_LDO_7_6_OUV = 0x0049, + kD2186_LDO_9_8_OUV = 0x004a, + kD2186_LDO_11_10_OUV = 0x004b, + kD2186_LDO_13_12_OUV = 0x004c, + + kDIALOG_EVENT_A = 0x0050, + kDIALOG_EVENT_B = 0x0051, + kDIALOG_EVENT_C = 0x0052, + kDIALOG_EVENT_D = 0x0053, + kDIALOG_EVENT_E = 0x0054, + kDIALOG_EVENT_F = 0x0055, + kDIALOG_EVENT_G = 0x0056, + kDIALOG_EVENT_H = 0x0057, + kDIALOG_EVENT_I = 0x0058, + kDIALOG_EVENT_J = 0x0059, + kDIALOG_EVENT_K = 0x005a, + kDIALOG_EVENT_L = 0x005b, + kDIALOG_EVENT_M = 0x005c, + + kDIALOG_STATUS_A = 0x0060, + kDIALOG_STATUS_B = 0x0061, + kDIALOG_STATUS_C = 0x0062, + kDIALOG_STATUS_D = 0x0063, + kDIALOG_STATUS_E = 0x0064, + kDIALOG_STATUS_F = 0x0065, + kDIALOG_STATUS_G = 0x0066, + kDIALOG_STATUS_H = 0x0067, + kDIALOG_STATUS_I = 0x0068, + kDIALOG_STATUS_J = 0x0069, + kDIALOG_STATUS_K = 0x006a, + kDIALOG_STATUS_L = 0x006b, + kDIALOG_STATUS_M = 0x006c, + kDIALOG_STATUS_N = 0x006d, + + kDIALOG_IRQ_MASK_A = 0x0070, + kDIALOG_IRQ_MASK_B = 0x0071, + kDIALOG_IRQ_MASK_C = 0x0072, + kDIALOG_IRQ_MASK_D = 0x0073, + kDIALOG_IRQ_MASK_E = 0x0074, + kDIALOG_IRQ_MASK_F = 0x0075, + kDIALOG_IRQ_MASK_G = 0x0076, + kDIALOG_IRQ_MASK_H = 0x0077, + kDIALOG_IRQ_MASK_I = 0x0078, + kDIALOG_IRQ_MASK_J = 0x0079, + kDIALOG_IRQ_MASK_K = 0x007A, + kDIALOG_IRQ_MASK_L = 0x007B, + kDIALOG_IRQ_MASK_M = 0x007C, + + kD2186_ACTIVE1 = 0x0080, + kD2186_ACTIVE2 = 0x0081, + kD2186_ACTIVE3 = 0x0082, + kD2186_ACTIVE4 = 0x0083, + kD2186_ACTIVE5 = 0x0084, + kD2186_ACTIVE6 = 0x0085, + kD2186_ACTIVE7 = 0x0086, + kD2186_ACTIVE8 = 0x0087, + + kD2186_STANDBY1 = 0x0088, + kD2186_STANDBY3 = 0x008a, + kD2186_STANDBY4 = 0x008b, + kD2186_STANDBY6 = 0x008d, + kD2186_STANDBY7 = 0x008e, + kD2186_STANDBY8 = 0x008f, + + kD2186_HIBERNATE1 = 0x0090, + kD2186_HIBERNATE3 = 0x0092, + kD2186_HIBERNATE4 = 0x0093, + kD2186_HIBERNATE6 = 0x0095, + kD2186_HIBERNATE7 = 0x0096, + kD2186_HIBERNATE8 = 0x0097, + + kD2186_SLOT_TIMINGS = 0x00a0, + kD2186_SLOT_TIMINGS_PWR_UP1 = 0x00a0, + kD2186_SLOT_TIMINGS_PWR_DN1 = 0x00a1, + kD2186_SLOT_TIMINGS_PWR_UP2 = 0x00a2, + kD2186_SLOT_TIMINGS_PWR_DN2 = 0x00a3, + + kD2186_ACT_TO_HIB_DLY = 0x00a4, + + kD2186_BUCK0_SLOT = 0x00b0, + kD2186_BUCK1_SLOT = 0x00b1, + kD2186_BUCK2_SLOT = 0x00b2, + kD2186_BUCK3_SLOT = 0x00b3, + kD2186_BUCK4_SLOT = 0x00b4, + kD2186_BUCK5_SLOT = 0x00b5, + kD2186_BUCK6_SLOT = 0x00b6, + + kD2186_LDO1_SLOT = 0x00c1, + kD2186_LDO2_SLOT = 0x00c2, + kD2186_LDO3_SLOT = 0x00c3, + kD2186_LDO4_SLOT = 0x00c4, + kD2186_LDO5_SLOT = 0x00c5, + kD2186_LDO6_SLOT = 0x00c6, + kD2186_LDO7_SLOT = 0x00c7, + kD2186_LDO8_SLOT = 0x00c8, + kD2186_LDO9_SLOT = 0x00c9, + kD2186_LDO10_SLOT = 0x00ca, + kD2186_LDO11_SLOT = 0x00cb, + // NO LDO12_SLOT + kD2186_LDO13_SLOT = 0x00cd, + + kD2186_CHARGE_PUMP_SLOT = 0x00d8, + + kD2186_BUCK3_SW1_SLOT = 0x00d9, + kD2186_BUCK3_SW2_SLOT = 0x00da, + kD2186_BUCK3_SW3_SLOT = 0x00db, + kD2186_BUCK4_SW1_SLOT = 0x00dc, + kD2186_BUCK4_SW2_SLOT = 0x00dd, + + kD2186_EXT0_SLOT = 0x00e8, + kD2186_EXT1_SLOT = 0x00e9, + kD2186_EXT2_SLOT = 0x00ea, + kD2186_EXT3_SLOT = 0x00eb, + + kD2186_BUCK_DWI_CTRL0 = 0x00f0, + kD2186_BUCK_DWI_TRIM0 = 0x00f2, + kD2186_BUCK_FSM_TRIM0 = 0x00f4, + kD2186_BUCK_FSM_TRIM1 = 0x00f5, + kD2186_BUCK_FSM_TRIM4 = 0x00f8, + kD2186_BUCK_CALIB_OFFSET_TRIM = 0x00f9, + kD2186_BUCK_BYP1 = 0x00fa, + kD2186_BUCK_TRIM0 = 0x00fb, + + kD2186_BUCK0_VSEL = 0x0100, + kD2186_BUCK0_VSEL_ACTUAL = 0x0102, + kD2186_BUCK0_MINV = 0x0103, + kD2186_BUCK0_MAXV = 0x0104, + kD2186_BUCK0_OFS_V = 0x0105, + kD2186_BUCK0_MODE = 0x0106, + kD2186_BUCK0_START_ILIMIT = 0x0107, + kD2186_BUCK0_SYNC_ILIMIT = 0x0108, + kD2186_BUCK0_SLEEP_ILIMIT = 0x0109, + + kD2186_BUCK0_FSM_TRIM0 = 0x010a, + kD2186_BUCK0_FSM_TRIM1 = 0x010b, + kD2186_BUCK0_FSM_TRIM2 = 0x010c, + kD2186_BUCK0_FSM_TRIM3 = 0x010d, + kD2186_BUCK0_CLK_TRIM4 = 0x010e, + kD2186_BUCK0_CLK_TRIM = 0x010f, + + kD2186_BUCK0_CALIB0 = 0x0111, + kD2186_BUCK0_CALIB1 = 0x0112, + + kD2186_BUCK0_ANA_TRIM0 = 0x0113, + kD2186_BUCK0_ANA_TRIM1 = 0x0114, + kD2186_BUCK0_ANA_TRIM2 = 0x0115, + kD2186_BUCK0_ANA_TRIM3 = 0x0116, + kD2186_BUCK0_ANA_TRIM4 = 0x0117, + kD2186_BUCK0_ANA_TRIM5 = 0x0118, + kD2186_BUCK0_ANA_TRIM6 = 0x0119, + kD2186_BUCK0_ANA_TRIM7 = 0x011a, + kD2186_BUCK0_ANA_TRIM8 = 0x011b, + kD2186_BUCK0_ANA_TRIM9 = 0x011c, + + kD2186_BUCK1_VSEL = 0x0120, + kD2186_BUCK1_VSEL_ACTUAL = 0x0122, + kD2186_BUCK1_MINV = 0x0123, + kD2186_BUCK1_MAXV = 0x0124, + kD2186_BUCK1_OFS_V = 0x0125, + kD2186_BUCK1_MODE = 0x0126, + kD2186_BUCK1_START_ILIMIT = 0x0127, + kD2186_BUCK1_SYNC_ILIMIT = 0x0128, + kD2186_BUCK1_SLEEP_ILIMIT = 0x0129, + kD2186_BUCK1_FSM_TRIM0 = 0x012a, + kD2186_BUCK1_FSM_TRIM1 = 0x012b, + kD2186_BUCK1_FSM_TRIM2 = 0x012c, + kD2186_BUCK1_FSM_TRIM3 = 0x012d, + kD2186_BUCK1_CLK_TRIM4 = 0x012e, + kD2186_BUCK1_CLK_TRIM = 0x012f, + + kD2186_BUCK1_CALIB0 = 0x0131, + + kD2186_BUCK1_ANA_TRIM0 = 0x0133, + kD2186_BUCK1_ANA_TRIM1 = 0x0134, + kD2186_BUCK1_ANA_TRIM2 = 0x0135, + kD2186_BUCK1_ANA_TRIM3 = 0x0136, + kD2186_BUCK1_ANA_TRIM4 = 0x0137, + kD2186_BUCK1_ANA_TRIM5 = 0x0138, + kD2186_BUCK1_ANA_TRIM6 = 0x0139, + kD2186_BUCK1_ANA_TRIM7 = 0x013a, + kD2186_BUCK1_ANA_TRIM8 = 0x013b, + kD2186_BUCK1_ANA_TRIM9 = 0x013c, + + kD2186_BUCK2_VSEL = 0x0140, + kD2186_BUCK2_VSEL_ACTUAL = 0x0142, + kD2186_BUCK2_MINV = 0x0143, + kD2186_BUCK2_MAXV = 0x0144, + kD2186_BUCK2_OFS_V = 0x0145, + kD2186_BUCK2_MODE = 0x0146, + kD2186_BUCK2_START_ILIMIT = 0x0147, + kD2186_BUCK2_SYNC_ILIMIT = 0x0148, + kD2186_BUCK2_SLEEP_ILIMIT = 0x0149, + kD2186_BUCK2_FSM_TRIM0 = 0x014a, + kD2186_BUCK2_FSM_TRIM1 = 0x014b, + kD2186_BUCK2_FSM_TRIM2 = 0x014c, + kD2186_BUCK2_FSM_TRIM3 = 0x014d, + kD2186_BUCK2_CLK_TRIM4 = 0x014e, + kD2186_BUCK2_CLK_TRIM = 0x014f, + + kD2186_BUCK2_CALIB0 = 0x0151, + kD2186_BUCK2_ANA_TRIM0 = 0x0153, + kD2186_BUCK2_ANA_TRIM1 = 0x0154, + kD2186_BUCK2_ANA_TRIM2 = 0x0155, + kD2186_BUCK2_ANA_TRIM3 = 0x0156, + kD2186_BUCK2_ANA_TRIM4 = 0x0157, + kD2186_BUCK2_ANA_TRIM5 = 0x0158, + kD2186_BUCK2_ANA_TRIM6 = 0x0159, + kD2186_BUCK2_ANA_TRIM7 = 0x015a, + kD2186_BUCK2_ANA_TRIM8 = 0x015b, + kD2186_BUCK2_ANA_TRIM9 = 0x015c, + + kD2186_BUCK3_VSEL = 0x0160, + kD2186_BUCK3_VSEL_ALT = 0x0161, + kD2186_BUCK3_VSEL_ACTUAL = 0x0162, + kD2186_BUCK3_MINV = 0x0163, + kD2186_BUCK3_MAXV = 0x0164, + kD2186_BUCK3_OFS_V = 0x0165, + kD2186_BUCK3_MODE = 0x0166, + kD2186_BUCK3_START_ILIMIT = 0x0167, + kD2186_BUCK3_SYNC_ILIMIT = 0x0168, + kD2186_BUCK3_SLEEP_ILIMIT = 0x0169, + kD2186_BUCK3_FSM_TRIM0 = 0x016a, + kD2186_BUCK3_FSM_TRIM2 = 0x016c, + kD2186_BUCK3_FSM_TRIM3 = 0x016d, + kD2186_BUCK3_CLK_TRIM = 0x016f, + + kD2186_BUCK3_CALIB_OFFSET_TRIM = 0x0170, + + kD2186_BUCK3_CALIB0 = 0x0171, + kD2186_BUCK3_ANA_TRIM0 = 0x0173, + kD2186_BUCK3_ANA_TRIM1 = 0x0174, + kD2186_BUCK3_ANA_TRIM2 = 0x0175, + kD2186_BUCK3_ANA_TRIM3 = 0x0176, + kD2186_BUCK3_ANA_TRIM4 = 0x0177, + kD2186_BUCK3_ANA_TRIM5 = 0x0178, + kD2186_BUCK3_ANA_TRIM6 = 0x0179, + kD2186_BUCK3_ANA_TRIM7 = 0x017a, + kD2186_BUCK3_ANA_TRIM8 = 0x017b, + kD2186_BUCK3_ANA_TRIM9 = 0x017c, + + kD2186_BUCK4_VSEL = 0x0180, + kD2186_BUCK4_VSEL_ALT = 0x0181, + kD2186_BUCK4_VSEL_ACTUAL = 0x0182, + kD2186_BUCK4_MINV = 0x0183, + kD2186_BUCK4_MAXV = 0x0184, + kD2186_BUCK4_OFS_V = 0x0185, + kD2186_BUCK4_MODE = 0x0186, + kD2186_BUCK4_START_ILIMIT = 0x0187, + kD2186_BUCK4_SYNC_ILIMIT = 0x0188, + kD2186_BUCK4_SLEEP_ILIMIT = 0x0189, + kD2186_BUCK4_FSM_TRIM0 = 0x018a, + kD2186_BUCK4_FSM_TRIM2 = 0x018c, + kD2186_BUCK4_FSM_TRIM3 = 0x018d, + kD2186_BUCK4_CLK_TRIM = 0x018f, + + kD2186_BUCK4_CALIB0 = 0x0191, + kD2186_BUCK4_ANA_TRIM0 = 0x0193, + kD2186_BUCK4_ANA_TRIM1 = 0x0194, + kD2186_BUCK4_ANA_TRIM2 = 0x0195, + kD2186_BUCK4_ANA_TRIM3 = 0x0196, + kD2186_BUCK4_ANA_TRIM4 = 0x0197, + kD2186_BUCK4_ANA_TRIM5 = 0x0198, + kD2186_BUCK4_ANA_TRIM6 = 0x0199, + kD2186_BUCK4_ANA_TRIM7 = 0x019a, + kD2186_BUCK4_ANA_TRIM8 = 0x019b, + kD2186_BUCK4_ANA_TRIM9 = 0x019c, + + kD2186_BUCK5_VSEL = 0x01a0, + kD2186_BUCK5_VSEL_ACTUAL = 0x01a2, + kD2186_BUCK5_MINV = 0x01a3, + kD2186_BUCK5_MAXV = 0x01a4, + kD2186_BUCK5_OFS_V = 0x01a5, + kD2186_BUCK5_MODE = 0x01a6, + kD2186_BUCK5_START_ILIMIT = 0x01a7, + kD2186_BUCK5_SYNC_ILIMIT = 0x01a8, + kD2186_BUCK5_SLEEP_ILIMIT = 0x01a9, + kD2186_BUCK5_FSM_TRIM0 = 0x01aa, + kD2186_BUCK5_FSM_TRIM2 = 0x01ac, + kD2186_BUCK5_FSM_TRIM3 = 0x01ad, + kD2186_BUCK5_CLK_TRIM = 0x01af, + + kD2186_BUCK5_CALIB0 = 0x01b1, + kD2186_BUCK5_ANA_TRIM0 = 0x01b3, + kD2186_BUCK5_ANA_TRIM1 = 0x01b4, + kD2186_BUCK5_ANA_TRIM2 = 0x01b5, + kD2186_BUCK5_ANA_TRIM3 = 0x01b6, + kD2186_BUCK5_ANA_TRIM4 = 0x01b7, + kD2186_BUCK5_ANA_TRIM5 = 0x01b8, + kD2186_BUCK5_ANA_TRIM6 = 0x01b9, + kD2186_BUCK5_ANA_TRIM7 = 0x01ba, + kD2186_BUCK5_ANA_TRIM8 = 0x01bb, + kD2186_BUCK5_ANA_TRIM9 = 0x01bc, + + // XXX: BUCK6 is different?!? + kD2186_BUCK6_VSEL = 0x01c0, + kD2186_BUCK6_VSEL_ACTUAL = 0x01c2, + kD2186_BUCK6_MINV = 0x01c3, + kD2186_BUCK6_MAXV = 0x01c4, + kD2186_BUCK6_OFS_V = 0x01c5, + kD2186_BUCK6_MODE = 0x01c6, + kD2186_BUCK6_START_ILIMIT = 0x01c7, + kD2186_BUCK6_SYNC_ILIMIT = 0x01c8, + kD2186_BUCK6_SLEEP_ILIMIT = 0x01c9, + kD2186_BUCK6_FSM_TRIM0 = 0x01ca, + kD2186_BUCK6_FSM_TRIM1 = 0x01cb, + kD2186_BUCK6_FSM_TRIM2 = 0x01cc, + kD2186_BUCK6_FSM_TRIM3 = 0x01ce, + kD2186_BUCK6_CLK_TRIM = 0x01cf, + kD2186_BUCK6_CALIB_OFFSET_TRIM = 0x01d0, + kD2186_BUCK6_CALIB0 = 0x01d1, + kD2186_BUCK6_ANA_TRIM0 = 0x01d3, + kD2186_BUCK6_ANA_TRIM1 = 0x01d4, + kD2186_BUCK6_ANA_TRIM2 = 0x01d5, + kD2186_BUCK6_ANA_TRIM3 = 0x01d6, + kD2186_BUCK6_ANA_TRIM4 = 0x01d7, + kD2186_BUCK6_ANA_TRIM5 = 0x01d8, + kD2186_BUCK6_ANA_TRIM6 = 0x01d9, + kD2186_BUCK6_ANA_TRIM7 = 0x01da, + kD2186_BUCK6_ANA_TRIM8 = 0x01db, + kD2186_BUCK6_ANA_TRIM9 = 0x01dc, + + kD2186_LDO_RTC_TRIM = 0x0304, + + kD2186_LDO1_VSEL = 0x0308, + kD2186_LDO1_VSEL_ACTUAL = 0x0309, + kD2186_LDO1_MINV = 0x030a, + kD2186_LDO1_MAXV = 0x030b, + kD2186_LDO1_UOV_LIM = 0x030d, + + kD2186_LDO2_VSEL = 0x0310, + kD2186_LDO2_VSEL_ACTUAL = 0x0311, + kD2186_LDO2_MINV = 0x0312, + kD2186_LDO2_MAXV = 0x0313, + kD2186_LDO2_TRIM = 0x0314, + kD2186_LDO2_UOV_LIM = 0x0315, + + kD2186_LDO3_VSEL = 0x0318, + kD2186_LDO3_VSEL_ACTUAL = 0x0319, + kD2186_LDO3_MINV = 0x031a, + kD2186_LDO3_MAXV = 0x031b, + kD2186_LDO3_UOV_LIM = 0x031d, + + kD2186_LDO4_VSEL = 0x0320, + kD2186_LDO4_VSEL_ACTUAL = 0x0321, + kD2186_LDO4_MINV = 0x0322, + kD2186_LDO4_MAXV = 0x0323, + kD2186_LDO4_UOV_LIM = 0x0325, + + kD2186_LDO5_VSEL = 0x0328, + kD2186_LDO5_VSEL_ACTUAL = 0x0329, + kD2186_LDO5_MINV = 0x032a, + kD2186_LDO5_MAXV = 0x032b, + kD2186_LDO5_TRIM = 0x032c, + kD2186_LDO5_UOV_LIM = 0x032d, + + kD2186_LDO6_VSEL = 0x0330, + kD2186_LDO6_VSEL_ACTUAL = 0x0331, + kD2186_LDO6_MINV = 0x0332, + kD2186_LDO6_MAXV = 0x0333, + kD2186_LDO6_TRIM = 0x0334, + kD2186_LDO6_UOV_LIM = 0x0335, + + kD2186_LDO7_VSEL = 0x0338, + kD2186_LDO7_VSEL_ACTUAL = 0x0339, + kD2186_LDO7_MINV = 0x033a, + kD2186_LDO7_MAXV = 0x033b, + kD2186_LDO7_TRIM = 0x033c, + kD2186_LDO7_UOV_LIM = 0x033d, + + kD2186_LDO8_VSEL = 0x0340, + kD2186_LDO8_VSEL_ACTUAL = 0x0341, + kD2186_LDO8_MINV = 0x0342, + kD2186_LDO8_MAXV = 0x0343, + kD2186_LDO8_TRIM = 0x0344, + kD2186_LDO8_UOV_LIM = 0x0345, + + kD2186_LDO9_VSEL = 0x0348, + kD2186_LDO9_VSEL_ACTUAL = 0x0349, + kD2186_LDO9_MINV = 0x034a, + kD2186_LDO9_MAXV = 0x034b, + kD2186_LDO9_TRIM = 0x034c, + kD2186_LDO9_UOV_LIM = 0x033d, + + kD2186_LDO10_VSEL = 0x0350, + kD2186_LDO10_VSEL_ACTUAL = 0x0351, + kD2186_LDO10_MINV = 0x0352, + kD2186_LDO10_MAXV = 0x0353, + kD2186_LDO10_UOV_LIM = 0x0355, + + kD2186_LDO11_VSEL = 0x0358, + kD2186_LDO11_VSEL_ACTUAL = 0x0359, + kD2186_LDO11_MINV = 0x035a, + kD2186_LDO11_MAXV = 0x035b, + kD2186_LDO11_TRIM = 0x035c, + kD2186_LDO11_UOV_LIM = 0x033d, + + kD2186_LDO12_TRIM = 0x0364, + kD2186_LDO12_UOV_LIM = 0x0365, + + kD2186_LDO13_VSEL = 0x0368, + kD2186_LDO13_VSEL_ACTUAL = 0x0369, + kD2186_LDO13_MINV = 0x036a, + kD2186_LDO13_MAXV = 0x036b, + kD2186_LDO13_TRIM = 0x036c, + kD2186_LDO13_UOV_LIM = 0x033d, + + kD2186_LDO_BYP1 = 0x0380, + kDIALOG_LDO_CONTROL = kD2186_LDO_BYP1, + + kD2186_HIB_SW_CTRL = 0x03c0, + + kD2186_GPIO1_CONF1 = 0x0400, + kD2186_GPIO1_CONF2 = 0x0401, + kD2186_GPIO2_CONF1 = 0x0402, + kD2186_GPIO2_CONF2 = 0x0403, + kD2186_GPIO3_CONF1 = 0x0404, + kD2186_GPIO3_CONF2 = 0x0405, + kD2186_GPIO4_CONF1 = 0x0406, + kD2186_GPIO4_CONF2 = 0x0407, + kD2186_GPIO5_CONF1 = 0x0408, + kD2186_GPIO5_CONF2 = 0x0409, + kD2186_GPIO6_CONF1 = 0x040a, + kD2186_GPIO6_CONF2 = 0x040b, + kD2186_GPIO7_CONF1 = 0x040c, + kD2186_GPIO7_CONF2 = 0x040d, + kD2186_GPIO8_CONF1 = 0x040e, + kD2186_GPIO8_CONF2 = 0x040f, + kD2186_GPIO9_CONF1 = 0x0410, + kD2186_GPIO9_CONF2 = 0x0411, + kD2186_GPIO10_CONF1 = 0x0412, + kD2186_GPIO10_CONF2 = 0x0413, + kD2186_GPIO11_CONF1 = 0x0414, + kD2186_GPIO11_CONF2 = 0x0415, + kD2186_GPIO12_CONF1 = 0x0416, + kD2186_GPIO12_CONF2 = 0x0417, + kD2186_GPIO13_CONF1 = 0x0418, + kD2186_GPIO13_CONF2 = 0x0419, + kD2186_GPIO14_CONF1 = 0x041a, + kD2186_GPIO14_CONF2 = 0x041b, + kD2186_GPIO15_CONF1 = 0x041c, + kD2186_GPIO15_CONF2 = 0x041d, + kD2186_GPIO16_CONF1 = 0x041e, + kD2186_GPIO16_CONF2 = 0x041f, + kD2186_GPIO17_CONF1 = 0x0420, + kD2186_GPIO17_CONF2 = 0x0421, + kD2186_GPIO18_CONF1 = 0x0422, + kD2186_GPIO18_CONF2 = 0x0423, + kD2186_GPIO19_CONF1 = 0x0424, + kD2186_GPIO19_CONF2 = 0x0425, + kD2186_GPIO20_CONF1 = 0x0426, + kD2186_GPIO20_CONF2 = 0x0427, + kD2186_GPIO21_CONF1 = 0x0428, + kD2186_GPIO21_CONF2 = 0x0429, + kDIALOG_SYS_GPIO_REG_START = kD2186_GPIO1_CONF1, + + kD2186_OUT_32K = 0x0430, + + kD2186_BUTTON1_CONF = 0x0440, + kD2186_BUTTON2_CONF = 0x0441, + kD2186_BUTTON3_CONF = 0x0442, + kD2186_BUTTON4_CONF = 0x0443, + kDIALOG_BUTTON_DBL = 0x0444, + kD2186_BUTTON_WAKE = 0x0445, + + kD2186_RESET_IN1_CONF = 0x0448, + kD2186_RESET_IN2_CONF = 0x0449, + kD2186_RESET_IN3_CONF = 0x044a, + + kD2186_TDEV1_RISE = 0x0480, + kD2186_TDEV1_FALL = 0x0481, + kD2186_TDEV2_RISE = 0x0482, + kD2186_TDEV2_FALL = 0x0483, + kD2186_TDEV3_RISE = 0x0484, + kD2186_TDEV3_FALL = 0x0485, + kD2186_TDEV4_RISE = 0x0486, + kD2186_TDEV4_FALL = 0x0487, + kD2186_TLDO5_RISE = 0x04a0, + + kD2186_LOADSW_BIUCK6_RISE = 0x04a1, + kD2186_TVCENTER_RISE = 0x04a2, + kD2186_TLINCHG_BUCK4_RISE = 0x04a3, + + kD2186_TBUCK0_RISE = 0x04a4, + kD2186_TBUCK1_RISE = 0x04a5, + kD2186_TBUCK2_3_RISE = 0x04a6, + kD2186_TBUCK5_RISE = 0x04a7, + kD2186_TVIB_RISE = 0x04a8, + kD2186_TISENSE_HYST = 0x04a9, + + kDIALOG_T_OFFSET_MSB = 0x04aa, + kDIALOG_T_OFFSET_LSB = 0x04ab, + + kD2186_ISET_BUCK = 0x04c0, + kD2186_ISET_BUCK_SHADOW = 0x04c1, + kD2186_ISET_BUCK_ABSMAX = 0x04c2, + kD2186_ISET_BUCK_ACTUAL = 0x04c3, + kD2186_ISET_BUCK_ALT = 0x04c4, + kDIALOG_CHARGE_BUCK_CONTROL = kD2186_ISET_BUCK, + kDIALOG_CHARGE_BUCK_STATUS = kD2186_ISET_BUCK_ACTUAL, + + kD2186_CHG_CTRL_A = 0x04c5, + kD2186_CHG_CTRL_B = 0x04c6, + kD2186_CHG_CTRL_C = 0x04c7, + kD2186_CHG_CTRL_D = 0x04c8, + kD2186_CHG_CTRL_E = 0x04c9, + kD2186_CHG_CTRL_F = 0x04ca, + kD2186_CHG_TIME = 0x04cb, + // XXX: verify this + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD2186_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_HIB = kD2186_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_TIME = kD2186_CHG_CTRL_D, + kDIALOG_CHARGE_CONTROL_EN = kD2186_CHG_CTRL_A, + kDIALOG_OTP_ISET_BAT = kD2186_CHG_CTRL_C, + + kD2186_CHG_STAT = 0x04cc, + kDIALOG_CHARGE_STATUS = kD2186_CHG_STAT, + + kD2186_CHG_VSET_TRIM = 0x04cd, + kD2186_CHG_VSET_OFS = 0x04ce, + kD2186_IBUS_GAIN_TRIM = 0x04cf, + kD2186_IBUS100_OFS_TRIM = 0x04d0, + kD2186_IBUS500_OFS_TRIM = 0x04d1, + + kD2186_CHG_TRIM1 = 0x04d2, + kD2186_CHG_TRIM2 = 0x04d3, + kD2186_CHG_TRIM3 = 0x04d4, + kD2186_CHG_TRIM4 = 0x04d5, + kD2186_ICHG_END = 0x04d6, + + kDIALOG_TBAT_0 = 0x04d7, + kDIALOG_TBAT_1 = 0x04d8, + kDIALOG_TBAT_2 = 0x04d9, + kDIALOG_TBAT_3 = 0x04da, + kDIALOG_TBAT_4 = 0x04db, + kDIALOG_TBAT_MAX = 0x04dc, + kDIALOG_ICHG_TBAT_0 = 0x04dd, + kDIALOG_ICHG_TBAT_1 = 0x04de, + kDIALOG_ICHG_TBAT_2 = 0x04df, + kDIALOG_ICHG_TBAT_3 = 0x04e0, + kDIALOG_ICHG_TBAT_4 = 0x04e1, + + kDIALOG_ICHG_AVG = 0x04e2, + + kD2186_ADC_CTRL1 = 0x0500, + kD2186_ADC_CTRL2 = 0x0501, + kDIALOG_ADC_CONTROL = kD2186_ADC_CTRL1, + kDIALOG_ADC_CONTROL2 = kD2186_ADC_CTRL2, + kDIALOG_ADC_LSB = 0x0502, + kDIALOG_ADC_MSB = 0x0503, + kD2186_ADC_TEMP_CTRL0 = 0x0504, + kD2186_ADC_TEMP_CTRL1 = 0x0505, + kD2186_ADC_FSM_TRIM0 = 0x0506, + kD2186_ADC_FSM_TRIM1 = 0x0507, + kD2186_ADC_FSM_TRIM2 = 0x0508, + kD2186_ADC_FSM_TRIM3 = 0x0509, + kD2186_ADC_ANA_TRIM0 = 0x050a, + kD2186_VCC_MAIN_MON = 0x050c, + kDIALOG_IBUS_ACCUM1 = 0x050e, + kDIALOG_IBUS_ACCUM2 = 0x050f, + kDIALOG_IBUS_ACCUM3 = 0x0510, + kDIALOG_VBUS_ACCUM1 = 0x0511, + kDIALOG_VBUS_ACCUM2 = 0x0512, + kDIALOG_VBUS_ACCUM3 = 0x0513, + kDIALOG_TDIE_ACCUM1 = 0x0514, + kDIALOG_TDIE_ACCUM2 = 0x0515, + kDIALOG_TDIE_ACCUM3 = 0x0516, + kDIALOG_IBUS_COUNT1 = 0x0517, + kDIALOG_IBUS_COUNT2 = 0x0518, + kD2186_IBUSCAL_1 = 0x0519, + kD2186_IBUSCAL_2 = 0x051a, + kD2186_IBUSCAL_3 = 0x051b, + kD2186_IBUSCAL_4 = 0x051c, + kD2186_IBUSCAL_5 = 0x051d, + kD2186_IBUSCAL_6 = 0x051e, + kD2186_IBUSCAL_7 = 0x051f, + kD2186_IBUSCAL_8 = 0x0520, + + kD2186_IBUCK0_ACCUM1 = 0x0522, + kD2186_IBUCK0_ACCUM2 = 0x0523, + kD2186_IBUCK0_ACCUM3 = 0x0524, + kD2186_IBUCK0_COUNT1 = 0x0525, + kD2186_IBUCK0_COUNT2 = 0x0526, + kD2186_IBUCK1_ACCUM1 = 0x0527, + kD2186_IBUCK1_ACCUM2 = 0x0528, + kD2186_IBUCK1_ACCUM3 = 0x0529, + kD2186_IBUCK1_COUNT1 = 0x052a, + kD2186_IBUCK1_COUNT2 = 0x052b, + + kDIALOG_APP_TMUX = 0x0540, + kDIALOG_BIST_ADC_CTRL = 0x0541, + kDIALOG_BIST_ADC_LSB = 0x0542, + kDIALOG_BIST_ADC_MSB = 0x0543, + kD2186_BIST_ADC_TRIM1 = 0x0545, + kD2186_BIST_ADC_ANA_TRIM0 = 0x0546, + + kDIALOG_VIB_CTRL = 0x0580, + kDIALOG_VIB_VSET = 0x0581, + kD2186_VIB_TRIM = 0x0582, + kD2186_VIB_ILIMIT_PROG = 0x0583, + + kDIALOG_RTC_ALARM_A = 0x05c0, + kDIALOG_RTC_ALARM_B = 0x05c1, + kDIALOG_RTC_ALARM_C = 0x05c2, + kDIALOG_RTC_ALARM_D = 0x05c3, + kDIALOG_RTC_CONTROL = 0x05c4, + kDIALOG_RTC_TIMEZONE = 0x05c5, + kDIALOG_RTC_SUB_SECOND_A = 0x05c6, + kDIALOG_RTC_SUB_SECOND_B = 0x05c7, + kDIALOG_RTC_SECOND_A = 0x05c8, + kDIALOG_RTC_SECOND_B = 0x05c9, + kDIALOG_RTC_SECOND_C = 0x05ca, + kDIALOG_RTC_SECOND_D = 0x05cb, + + kD2186_SPARE_RW0 = 0x0680, + kD2186_SPARE_RW_LAST = 0x0687, + kD2186_SPARE_RWTOTP0 = 0x06a0, + kD2186_SPARE_RWTOTP_LAST = 0x06a7, + kD2186_SPARE_RWOTP0 = 0x06c0, + kD2186_SPARE_RWOTP1 = 0x06c1, + + kDIALOG_MEMBYTE0 = 0x4000, + kDIALOG_MEMBYTE_LAST = 0x4027, + + kDIALOG_TEST_ACCESS = 0x7000, + kDIALOG_TEST_ACCESS_ENA = 0x1D, + kDIALOG_TEST_ACCESS_DIS = 0x00, + + kDIALOG_RAM0 = 0x8000, + kDIALOG_RAM_LAST = 0x87ff, + + kDIALOG_EXT_MEM_CAL0_SIZE = 64, + kDIALOG_GAP_SCRATCH8_SIZE = 8, // ex diags, free now + kDIALOG_EXT_MEM_CAL1_SIZE = 336, + kDIALOG_VOLTAGE_KNOBS_SIZE = 32, + // ... + kDIALOG_DIAG_SCRATCH_SIZE = 32, + + kDIALOG_EXT_MEM_CAL0 = kDIALOG_RAM0, + kDIALOG_EXT_MEM_CAL1 = kDIALOG_EXT_MEM_CAL0+kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_GAP_SCRATCH8_SIZE, + kDIALOG_VOLTAGE_KNOBS = kDIALOG_EXT_MEM_CAL1+kDIALOG_EXT_MEM_CAL1_SIZE, + // reserved, future + kDIALOG_DIAG_SCRATCH = 0x87e0, + + // handy + kDIALOG_EXT_MEM_CAL_SIZE = kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_EXT_MEM_CAL1_SIZE, +}; + +// Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 2, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, +}; + +enum { + kD2186_EVENT_A_TBAT = (1 << 7), + kD2186_EVENT_A_VBUS_EXT_REM = (1 << 6), + kD2186_EVENT_A_VDD_LOW = (1 << 5), + kD2186_EVENT_A_VBUS_EXT_DET = (1 << 3), + kD2186_EVENT_A_ACC_DET = (1 << 2), + kD2186_EVENT_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2186_EVENT_B_BTN4_DBL = (1 << 7), + kD2186_EVENT_B_BTN3_DBL = (1 << 6), + kD2186_EVENT_B_BTN2_DBL = (1 << 5), + kD2186_EVENT_B_BTN1_DBL = (1 << 4), + kD2186_EVENT_B_BUTTON_4 = (1 << 3), + kD2186_EVENT_B_BUTTON_3 = (1 << 2), + kD2186_EVENT_B_BUTTON_2 = (1 << 1), + kD2186_EVENT_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2186_EVENT_C_CHG_BUCK_FLG = (1 << 6), + kD2186_EVENT_C_CHG_ABCC_ACT = (1 << 5), + kD2186_EVENT_C_CHG_TIMEOUT = (1 << 4), + kD2186_EVENT_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2186_EVENT_C_CHG_END = (1 << 2), + kD2186_EVENT_C_CHG_FAST = (1 << 1), + kD2186_EVENT_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2186_EVENT_D_GPIO8 = (1 << 7), + kD2186_EVENT_D_GPIO7 = (1 << 6), + kD2186_EVENT_D_GPIO6 = (1 << 5), + kD2186_EVENT_D_GPIO5 = (1 << 4), + kD2186_EVENT_D_GPIO4 = (1 << 3), + kD2186_EVENT_D_GPIO3 = (1 << 2), + kD2186_EVENT_D_GPIO2 = (1 << 1), + kD2186_EVENT_D_GPIO1 = (1 << 0), +}; + +enum { + kD2186_EVENT_E_GPIO16 = (1 << 7), + kD2186_EVENT_E_GPIO15 = (1 << 6), + kD2186_EVENT_E_GPIO14 = (1 << 5), + kD2186_EVENT_E_GPIO13 = (1 << 4), + kD2186_EVENT_E_GPIO12 = (1 << 3), + kD2186_EVENT_E_GPIO11 = (1 << 2), + kD2186_EVENT_E_GPIO10 = (1 << 1), + kD2186_EVENT_E_GPIO9 = (1 << 0), +}; + +enum { + kD2186_EVENT_F_GPIO21 = (1 << 4), + kD2186_EVENT_F_GPIO20 = (1 << 3), + kD2186_EVENT_F_GPIO19 = (1 << 2), + kD2186_EVENT_F_GPIO18 = (1 << 1), + kD2186_EVENT_F_GPIO17 = (1 << 0), +}; + +enum { + kD2186_EVENT_G_T4_RISE = (1 << 7), + kD2186_EVENT_G_T4_FALL = (1 << 6), + kD2186_EVENT_G_T3_RISE = (1 << 5), + kD2186_EVENT_G_T3_FALL = (1 << 4), + kD2186_EVENT_G_T2_RISE = (1 << 3), + kD2186_EVENT_G_T2_FALL = (1 << 2), + kD2186_EVENT_G_T1_RISE = (1 << 1), + kD2186_EVENT_G_T1_FALL = (1 << 0), +}; + + // EVENT_H has no events + +enum { + kD2186_EVENT_I_TBUCK_5 = (1 << 7), + kD2186_EVENT_I_TBUCK2_3 = (1 << 6), + kD2186_EVENT_I_TBUCK1 = (1 << 5), + kD2186_EVENT_I_TBUCK0 = (1 << 4), + kD2186_EVENT_I_TLINCHG_BUCK4 = (1 << 3), + kD2186_EVENT_I_TVCENTER = (1 << 2), + kD2186_EVENT_I_LOADSW_BUCK6 = (1 << 1), + kD2186_EVENT_I_TLDO5 = (1 << 0), +}; + +enum { + kD2186_EVENT_J_HIGH_TEMP_WARNING = (1 << 7), + // reserved in the middle + kD2186_EVENT_J_TVIB = (1 << 0), +}; + +enum { + kD2186_EVENT_K_BUCK_LDO_UOV = (1 << 6), + kD2186_EVENT_K_VBUS_OV = (1 << 5), + kD2186_EVENT_K_VBUS_OC = (1 << 4), + kD2186_EVENT_K_BUCK6_OC = (1 << 1), + kD2186_EVENT_K_LDO6_OC = (1 << 0), +}; + +// EVENT_L events are stored by LLB across sleep/wake +enum { + kD2186_EVENT_L_VIB_ILIM = (1 << 7), + kD2186_EVENT_L_IBUS_OVERFLOW = (1 << 6), + kD2186_EVENT_L_XTAL_ERROR = (1 << 5), + kD2186_EVENT_L_HIB = (1 << 4), + kD2186_EVENT_L_DWI_TO = (1 << 3), + kD2186_EVENT_L_EOMC_BIST = (1 << 2), + kD2186_EVENT_L_EOMC = (1 << 1), + kD2186_EVENT_L_ALARM = (1 << 0), +}; + +enum { + kD2186_EVENT_M_IBUCK1_OVERFLOW = (1 << 1), + kD2186_EVENT_M_IBUCK0_OVERFLOW = (1 << 1), +}; + +enum { + kD2186_STATUS_A_TBAT = (1 << 7), + kD2186_STATUS_A_VDD_LOW = (1 << 5), + kD2186_STATUS_A_VBUS_EXT_DET = (1 << 3), + kD2186_STATUS_A_ACC_DET = (1 << 2), + kD2186_STATUS_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2186_STATUS_B_BUTTON_4 = (1 << 3), + kD2186_STATUS_B_BUTTON_3 = (1 << 2), + kD2186_STATUS_B_BUTTON_2 = (1 << 1), + kD2186_STATUS_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2186_STATUS_C_CHG_BUCK_FLG = (1 << 6), + kD2186_STATUS_C_CHG_ABCC_ACT = (1 << 5), + kD2186_STATUS_C_CHG_TIMEOUT = (1 << 4), + kD2186_STATUS_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2186_STATUS_C_CHG_END = (1 << 2), + kD2186_STATUS_C_CHG_FAST = (1 << 1), + kD2186_STATUS_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2186_STATUS_D_GPIO8 = (1 << 7), + kD2186_STATUS_D_GPIO7 = (1 << 6), + kD2186_STATUS_D_GPIO6 = (1 << 5), + kD2186_STATUS_D_GPIO5 = (1 << 4), + kD2186_STATUS_D_GPIO4 = (1 << 3), + kD2186_STATUS_D_GPIO3 = (1 << 2), + kD2186_STATUS_D_GPIO2 = (1 << 1), + kD2186_STATUS_D_GPIO1 = (1 << 0), +}; + +enum { + kD2186_STATUS_E_GPIO16 = (1 << 7), + kD2186_STATUS_E_GPIO15 = (1 << 6), + kD2186_STATUS_E_GPIO14 = (1 << 5), + kD2186_STATUS_E_GPIO13 = (1 << 4), + kD2186_STATUS_E_GPIO12 = (1 << 3), + kD2186_STATUS_E_GPIO11 = (1 << 2), + kD2186_STATUS_E_GPIO10 = (1 << 1), + kD2186_STATUS_E_GPIO9 = (1 << 0), +}; + +enum { + kD2186_STATUS_F_GPIO21 = (1 << 4), + kD2186_STATUS_F_GPIO20 = (1 << 3), + kD2186_STATUS_F_GPIO19 = (1 << 2), + kD2186_STATUS_F_GPIO18 = (1 << 1), + kD2186_STATUS_F_GPIO17 = (1 << 0), +}; + +enum { + kD2186_STATUS_G_T4_RISE = (1 << 7), + kD2186_STATUS_G_T4_FALL = (1 << 6), + kD2186_STATUS_G_T3_RISE = (1 << 5), + kD2186_STATUS_G_T3_FALL = (1 << 4), + kD2186_STATUS_G_T2_RISE = (1 << 3), + kD2186_STATUS_G_T2_FALL = (1 << 2), + kD2186_STATUS_G_T1_RISE = (1 << 1), + kD2186_STATUS_G_T1_FALL = (1 << 0), +}; + + // STATUS_H has no bits + +enum { + kD2186_STATUS_I_TBUCK5 = (1 << 7), + kD2186_STATUS_I_TBUCK2_3 = (1 << 6), + kD2186_STATUS_I_TBUCK1 = (1 << 5), + kD2186_STATUS_I_TBUCK0 = (1 << 4), + kD2186_STATUS_I_TLINCHG_BUCK4 = (1 << 3), + kD2186_STATUS_I_TVCENTER = (1 << 2), + kD2186_STATUS_I_LOADSW_BUCK6 = (1 << 1), + kD2186_STATUS_I_TLDO5 = (1 << 0), +}; + +enum { + kD2186_STATUS_J_HIGH_TEMP_WARNING = (1 << 7), + kD2186_STATUS_J_TVIB = (1 << 0), +}; + +enum { + kD2186_STATUS_K_BUCK_LDO_UOV = (1 << 6), + kD2186_STATUS_K_VBUS_OV = (1 << 5), + kD2186_STATUS_K_VBUS_OC = (1 << 4), +}; + +enum { + kD2186_STATUS_L_VIB_ILIM = (1 << 7), + kD2186_STATUS_L_IBUS_OVERFLOW = (1 << 6), + kD2186_STATUS_L_XTAL_ERROR = (1 << 5), +}; + +enum { + kD2186_STATUS_M_IBUCK1_OVERFLOW = (1 << 1), + kD2186_STATUS_M_IBUCK0_OVERFLOW = (1 << 0), +}; + +enum { + kD2186_STATUS_N_PROT_FET_ON = (1 << 1), + kD2186_STATUS_N_CHG_ATT = (1 << 0), +}; + +//XXX: VERIFY EVERYTHING UNDER THIS ===================================================== + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2186_EVENT_B_BUTTON_2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2186_EVENT_B_BUTTON_1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(1, kD2186_EVENT_B_BUTTON_3), + + kDIALOG_EVENT_BUTTON4_MASK = EVENT_FLAG_MAKE(1, kD2186_EVENT_B_BUTTON_4), + kDIALOG_EVENT_BUTTONS = (kD2186_EVENT_B_BUTTON_4 | + kD2186_EVENT_B_BUTTON_3 | + kD2186_EVENT_B_BUTTON_2 | + kD2186_EVENT_B_BUTTON_1), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(11, kD2186_EVENT_L_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = EVENT_FLAG_MAKE(0, kD2186_EVENT_A_ACC_DET), + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD2186_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(0, kD2186_EVENT_A_VBUS_EXT_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(11, kD2186_EVENT_L_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(11, kD2186_EVENT_L_HIB), + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(2, kD2186_EVENT_C_CHG_ABCC_ACT), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(2, kD2186_EVENT_C_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(0, kD2186_EVENT_A_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(3, kD2186_EVENT_D_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(4, kD2186_EVENT_E_GPIO16), + + kDIALOG_EVENT_GPIO17_MASK = EVENT_FLAG_MAKE(5, kD2186_EVENT_F_GPIO17), + kDIALOG_EVENT_GPIO18_MASK = EVENT_FLAG_MAKE(5, kD2186_EVENT_F_GPIO18), + kDIALOG_EVENT_GPIO19_MASK = EVENT_FLAG_MAKE(5, kD2186_EVENT_F_GPIO19), + kDIALOG_EVENT_GPIO20_MASK = EVENT_FLAG_MAKE(5, kD2186_EVENT_F_GPIO20), + kDIALOG_EVENT_GPIO21_MASK = EVENT_FLAG_MAKE(5, kD2186_EVENT_F_GPIO21), + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(1, kD2186_EVENT_B_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(1, kD2186_EVENT_B_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(1, kD2186_EVENT_B_BTN3_DBL), + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD2186_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD2186_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ACC_DET_MASK = STATUS_FLAG_MAKE(0, kD2186_STATUS_A_ACC_DET), + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(3, kD2186_STATUS_C_CHG_PRE | kD2186_STATUS_C_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(2, kD2186_STATUS_C_CHG_TIMEOUT), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(2, kD2186_STATUS_C_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(0, kD2186_STATUS_A_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(12, kD2186_STATUS_N_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(2, kD2186_STATUS_C_CHG_ABCC_ACT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(3 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {0, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, 0, kD2186_STATUS_C_CHG_PRE | kD2186_STATUS_C_CHG_FAST }; + +enum { + kD2186_EVENT_A_WAKEMASK = (kD2186_EVENT_A_VBUS_EXT_DET | + kD2186_EVENT_A_VCENTER_DET | + kD2186_EVENT_A_ACC_DET), + kD2186_EVENT_B_WAKEMASK = (kD2186_EVENT_B_BUTTON_1 | + kD2186_EVENT_B_BUTTON_2 | + kD2186_EVENT_B_BUTTON_3 | + kD2186_EVENT_B_BUTTON_4), + kD2186_EVENT_C_WAKEMASK = 0, + kD2186_EVENT_D_WAKEMASK = 0, + kD2186_EVENT_E_WAKEMASK = 0, + kD2186_EVENT_F_WAKEMASK = 0, + kD2186_EVENT_G_WAKEMASK = 0, + kD2186_EVENT_H_WAKEMASK = 0, + kD2186_EVENT_I_WAKEMASK = 0, + kD2186_EVENT_J_WAKEMASK = 0, + kD2186_EVENT_K_WAKEMASK = 0, + kD2186_EVENT_L_WAKEMASK = kD2186_EVENT_L_ALARM, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2186_EVENT_A_WAKEMASK, + ~kD2186_EVENT_B_WAKEMASK, + ~kD2186_EVENT_C_WAKEMASK, + ~kD2186_EVENT_D_WAKEMASK, + ~kD2186_EVENT_E_WAKEMASK, + ~kD2186_EVENT_F_WAKEMASK, + ~kD2186_EVENT_G_WAKEMASK, + ~kD2186_EVENT_H_WAKEMASK, + ~kD2186_EVENT_I_WAKEMASK, + ~kD2186_EVENT_J_WAKEMASK, + ~kD2186_EVENT_K_WAKEMASK, + ~kD2186_EVENT_L_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2186_EVENT_A_WAKEMASK, + kD2186_EVENT_B_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD2186_EVENT_C_WAKEMASK, + kD2186_EVENT_D_WAKEMASK, + kD2186_EVENT_E_WAKEMASK, + kD2186_EVENT_F_WAKEMASK, + kD2186_EVENT_G_WAKEMASK, + kD2186_EVENT_H_WAKEMASK, + kD2186_EVENT_I_WAKEMASK, + kD2186_EVENT_J_WAKEMASK, + kD2186_EVENT_K_WAKEMASK, + kD2186_EVENT_L_WAKEMASK, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD2186_EVENT_A_VBUS_EXT_DET | kD2186_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + // only include VCENTER_DET; VBUS can come and go while charger still usable + kD2186_EVENT_A_VCENTER_DET, + 0, + kD2186_EVENT_C_CHG_ABCC_ACT, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +enum { + kDialogEventPwrsupplyCount = 2, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 0, +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PROT_FET_DIS = (1 << 5), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 6), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_DWI_EN = (1 << 0), + kDIALOG_SYS_CONTROL2_DWI_TEST_EN = (1 << 1), + kDIALOG_SYS_CONTROL2_HIB_32K = (1 << 4), +}; + +enum { + // FAULT_LOG1 + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 7)), + kDIALOG_FAULT_LOG_RESET_IN_3 = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_2 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + // FAULT_LOG2 + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = FAULTLOG_FLAG_MAKE(1, (1 << 2)), + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = FAULTLOG_FLAG_MAKE(1, (1 << 1)), + kDIALOG_FAULT_LOG_NTC_SHDN = FAULTLOG_FLAG_MAKE(1, (1 << 0)), +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x03, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x2b, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x5d, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0xc1, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 70, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 10, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 2620, +}; + + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_B_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_B_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 30, + kDIALOG_CHARGE_CONTROL_MAX = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK * kDIALOG_CHARGE_CONTROL_STEP, +}; + +enum { + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 6), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0x0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = (0x1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (0x2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = (0x3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (0x4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG = (0x5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = (0x6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN7 = (0x7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (0x8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG = (0x9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG, + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (0xa << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (0xf << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG_OFF = (16 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG_OFF = (17 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP = (18 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LOADSW_TEMP = (19 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VCENTER_TEMP = (20 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP = (21 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = (22 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP = (23 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP = (24 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP = (25 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_LDO5_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK4_TEMP, + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 7), + kDIALOG_ADC_CONTROL2_IBUS_EN = (1 << 0), + kDIALOG_ADC_CONTROL2_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL2_AUTO_VDD_OUT_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, + kDIALOG_ADC_CONTROL2_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + kDIALOG_BIST_ADC_CTRL_MUX_SEL_MASK = (0x3f << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_A = (0 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_APP_MUX_B = (2 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO1 = (4 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO1 = (5 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO2 = (6 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO2 = (7 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO3 = (8 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO3 = (9 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO4 = (10 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO4 = (11 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO5 = (12 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO5 = (13 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO6 = (14 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO6 = (15 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO7 = (16 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO7 = (17 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO8 = (18 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO8 = (19 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO9 = (20 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO9 = (21 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO10 = (22 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO10 = (23 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO11 = (24 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO11 = (25 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO12 = (26 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO12 = (27 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VLDO13 = (28 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_ILDO13 = (29 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VRTC = (34 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_IRTC = (35 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK0 = (38 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK1 = (40 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK2 = (42 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3 = (44 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4 = (46 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK5 = (48 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK6 = (50 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3_SW1 = (52 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3_SW2 = (54 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK3_SW3 = (56 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4_SW1 = (60 << 0), + kDIALOG_BIST_ADC_CTRL_MUX_SEL_VBUCK4_SW2 = (62 << 0), + kDIALOG_BIST_ADC_CTRL_MAN_CONV = (1 << 7), +}; + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (0x1f << 3), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 3), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 3), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (0x10 << 3), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (0x11 << 3), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +#define NUM_LDOS 20 +static const struct ldo_params ldo_D2186[NUM_LDOS] = { + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO1_VSEL, kD2186_ACTIVE3, 0x02 }, // 00 - LDO1 = PP33_USB + { 1200, 5, 0xff, 0xff, 0x04, kD2186_LDO2_VSEL, kD2186_ACTIVE3, 0x04 }, // 01 - LDO2 = PP1V8_VA + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO3_VSEL, kD2186_ACTIVE3, 0x08 }, // 02 - LDO3 = PP3V0_TRISTAR + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO4_VSEL, kD2186_ACTIVE3, 0x10 }, // 03 - LDO4 = PP_LDO4 + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO5_VSEL, kD2186_ACTIVE3, 0x20 }, // 04 - LDO5 = PP3V0_NAND + { 1200, 25, 0x7f, 0x7f, 0x40, kD2186_LDO6_VSEL, kD2186_ACTIVE3, 0x40 }, // 05 - LDO6 = PP3V0_ACC + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO7_VSEL, kD2186_ACTIVE3, 0x80 }, // 06 - LDO7 = PP3V0_PROX_ALS + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO8_VSEL, kD2186_ACTIVE4, 0x01 }, // 07 - LDO8 = PP2V85_MAMBA + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO9_VSEL, kD2186_ACTIVE4, 0x02 }, // 08 - LDO9 = PP2V85_CAM_AVDD + { 600, 12, 0xff, 0xff, 0x00, kD2186_LDO10_VSEL, kD2186_ACTIVE4, 0x04 }, // 09 - LDO10 - PP1V0 - actually 12.5mv steps (FIXME) + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO11_VSEL, kD2186_ACTIVE4, 0x08 }, // 0a - LDO11 = PP3V0_PROX_IRLED + { 0, 0, 0, 0, 0x00, 0, kD2186_ACTIVE4, 0x00 }, // 0b - there is no LDO12 (PP1V8_ALWAYS) + { 1200, 25, 0x7f, 0x7f, 0x00, kD2186_LDO13_VSEL, kD2186_ACTIVE4, 0x20 }, // 0c - LDO13 = PP3V0_MESA + + { 0, 0, 0, 0, 0x00, 0, kD2186_ACTIVE6, 0x01 }, // 0d - BUCK3_SW1_EN => PP1V8 + { 0, 0, 0, 0, 0x00, 0, kD2186_ACTIVE6, 0x02 }, // 0e - BUCK3_SW2_EN => PP1V8_GRAPE + { 0, 0, 0, 0, 0x00, 0, kD2186_ACTIVE6, 0x04 }, // 0f - BUCK3_SW3_EN => PP1V8_OSCAR + { 0, 0, 0, 0, 0x00, 0, kD2186_ACTIVE6, 0x10 }, // 10 - BUCK4_SW1_EN => PP1V2 + { 0, 0, 0, 0, 0x00, 0, kD2186_ACTIVE6, 0x20 }, // 11 - BUCK4_SW2_EN => PP1V2_OSCAR + + { 0, 0, 0, 0, 0x00, 0, kD2186_HIBERNATE3, 0x40 }, // 12 - LDO19 - set LDO6_EN in HIB + { 0, 0, 0, 0, 0x00, 0, kD2186_ACTIVE1, 0x40 }, // 13 - BUCK6 +}; +#define LDOP ldo_D2186 + +enum { + kDIALOG_VIB_CTRL_PWM_EN = (1 << 0), + kDIALOG_VIB_CTRL_BRAKE = (1 << 1), + kDIALOG_VIB_CTRL_PWM_CLK_MASK = (3 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_2MHZ = (0 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_1MHZ = (1 << 2), + kDIALOG_VIB_CTRL_PWM_CLK_500KHZ = (2 << 2), + + kDIALOG_VIB_VSET_MASK = (0x3f << 0), +}; + +enum { + kDIALOG_SYS_CONFIG_WDOG_EN = (1 << 0), + + kDIALOG_SYS_CONFIG_WDOG_MODE_100MS = (0 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_250MS = (1 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_500MS = (2 << 1), + kDIALOG_SYS_CONFIG_WDOG_MODE_1000MS = (3 << 1), + + kDIALOG_SYS_CONFIG_RESET_TIMER_MASK = (3 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_4S = (0 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_6S = (1 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_8S = (2 << 3), + kDIALOG_SYS_CONFIG_RESET_TIMER_10S = (3 << 3), + + kDIALOG_SYS_CONFIG_WDOG_ACTIVE = (1 << 5), +}; + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD2186_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD2186_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD2186_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kD2186_BUTTON_DBL_BTN4_DBL_EN = (1 << 6), + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD2186_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD2186_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD2186_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif /* __DIALOG_D2186_H */ diff --git a/drivers/dialog/pmu/d2207.h b/drivers/dialog/pmu/d2207.h new file mode 100644 index 0000000..2b15c5f --- /dev/null +++ b/drivers/dialog/pmu/d2207.h @@ -0,0 +1,1608 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D2207_H +#define __DIALOG_D2207_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 1 +#define PMU_HAS_LCM_LDO 1 +#define PMU_HAS_BIST_ADC 1 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_VIB 0 +#define PMU_HAS_RAM 1 +#define PMU_HAS_WLED 1 +#define PMU_HAS_32K_RTC 1 +// : +#define PMU_HAS_ACCUMULATORS 0 +#define PMU_HAS_SYS 1 +#define PMU_HAS_WDT 1 +#define PMU_HAS_CHARGER 1 + +enum { + kDIALOG_ADDR_R = 0x79, + kDIALOG_ADDR_W = 0x78, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_EVENT_COUNT = 14, + kDIALOG_STATUS_COUNT = 13, + kDIALOG_FAULTLOG_COUNT = 2, + kDIALOG_CHIPID_COUNT = 4, + kDIALOG_GPIO_COUNT = 21, +}; + +#include "dCommon.h" + +enum { + kDIALOG_MASK_REV_CODE = 0x0000, + kDIALOG_TRIM_REL_CODE = 0x0001, + kDIALOG_PLATFORM_ID = 0x0002, + kDIALOG_DEVICE_ID1 = 0x0004, + kDIALOG_DEVICE_ID2 = 0x0005, + kDIALOG_DEVICE_ID3 = 0x0006, + kDIALOG_DEVICE_ID4 = 0x0007, + kDIALOG_DEVICE_ID5 = 0x0008, + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, + + kDIALOG_SYS_CONTROL = 0x0010, + kDIALOG_SYS_CONTROL2 = 0x0011, + + kDIALOG_SYS_CONFIG = 0x0020, + kD2207_SYS_CONF_B = 0x0021, + kD2207_SYS_CONF_C = 0x0022, + kD2207_SYS_CONF_D = 0x0023, + kD2207_DWI_CONF = 0x0024, + kD2207_BG_TRIM = 0x0025, + KD2207_BG_TC_TRIM = 0x0026, + kD2207_VREF_AUX_TRIM = 0x0027, + kD2207_VRTC_BG_TRIM = 0x0028, + kD2207_VDD_FAULT = 0x0029, + kD2207_PRE_UVLO_ADJ = 0x002a, + kD2207_PRE_UVLO_ADJ_ACTUAL = 0x002b, + kD2207_PRE_UVLO_CONF = 0x002c, + kD2207_PRE_UVLO_CNT = 0x002d, + kD2207_RTC_CTRL0 = 0x002e, + kD2207_RTC_CTRL1 = 0x002f, + kD2207_OSC_CTRL0 = 0x0030, + kD2207_OSC_TRIM = 0x0031, + kD2207_CLK_REQ_FRC = 0x0032, + kD2207_UOV_CONTROL = 0x0033, + kD2207_UOV_BLANK_CONTROL = 0x0034, + + kDIALOG_FAULT_LOG = 0x0040, + kDIALOG_FAULT_LOG2 = 0x0041, + kD2207_BUCK_0_3_OUV = 0x0042, + kD2207_BUCK_4_6_OUV = 0x0043, + kD2207_LDO_1_4_OUV = 0x0044, + kD2207_LDO_5_8_OUV = 0x0045, + kD2207_LDO_9_12_OUV = 0x0046, + kD2207_LDO_13_14_OUV = 0x0047, + + kDIALOG_EVENT_A = 0x0050, + kDIALOG_EVENT_B = 0x0051, + kDIALOG_EVENT_C = 0x0052, + kDIALOG_EVENT_D = 0x0053, + kDIALOG_EVENT_E = 0x0054, + kDIALOG_EVENT_F = 0x0055, + kDIALOG_EVENT_G = 0x0056, + kDIALOG_EVENT_H = 0x0057, + kDIALOG_EVENT_I = 0x0058, + kDIALOG_EVENT_J = 0x0059, + kDIALOG_EVENT_K = 0x005a, + kDIALOG_EVENT_L = 0x005b, + kDIALOG_EVENT_M = 0x005c, + kDIALOG_EVENT_N = 0x005d, + + kDIALOG_STATUS_A = 0x0060, + kDIALOG_STATUS_B = 0x0061, + kDIALOG_STATUS_C = 0x0062, + kDIALOG_STATUS_D = 0x0063, + kDIALOG_STATUS_E = 0x0064, + kDIALOG_STATUS_F = 0x0065, + kDIALOG_STATUS_G = 0x0066, + kDIALOG_STATUS_H = 0x0067, + kDIALOG_STATUS_I = 0x0068, + kDIALOG_STATUS_J = 0x0069, + kDIALOG_STATUS_K = 0x006a, + kDIALOG_STATUS_L = 0x006b, + kDIALOG_STATUS_M = 0x006c, + + kDIALOG_IRQ_MASK_A = 0x0070, + kDIALOG_IRQ_MASK_B = 0x0071, + kDIALOG_IRQ_MASK_C = 0x0072, + kDIALOG_IRQ_MASK_D = 0x0073, + kDIALOG_IRQ_MASK_E = 0x0074, + kDIALOG_IRQ_MASK_F = 0x0075, + kDIALOG_IRQ_MASK_G = 0x0076, + kDIALOG_IRQ_MASK_H = 0x0077, + kDIALOG_IRQ_MASK_I = 0x0078, + kDIALOG_IRQ_MASK_J = 0x0079, + kDIALOG_IRQ_MASK_K = 0x007A, + kDIALOG_IRQ_MASK_L = 0x007B, + kDIALOG_IRQ_MASK_M = 0x007C, + kDIALOG_IRQ_MASK_N = 0x007D, + + kD2207_ACTIVE1 = 0x0080, + kD2207_ACTIVE2 = 0x0081, + kD2207_ACTIVE3 = 0x0082, + kD2207_ACTIVE4 = 0x0083, + kD2207_ACTIVE5 = 0x0084, + kDIALOG_LCM_ACTIVE = kD2207_ACTIVE5, + kD2207_ACTIVE6 = 0x0085, + kD2207_ACTIVE7 = 0x0086, + kD2207_STANDBY1 = 0x0088, + kD2207_STANDBY3 = 0x008a, + kD2207_STANDBY4 = 0x008b, + kD2207_STANDBY6 = 0x008d, + kD2207_STANDBY7 = 0x008e, + kD2207_HIBERNATE1 = 0x0090, + kD2207_HIBERNATE3 = 0x0092, + kD2207_HIBERNATE4 = 0x0093, + kD2207_HIBERNATE6 = 0x0095, + kD2207_HIBERNATE7 = 0x0096, + +//-- + + kD2207_SLOT_TIMINGS_PWR_UP1 = 0x00a0, + kD2207_SLOT_TIMINGS_PWR_DN1 = 0x00a1, + kD2207_SLOT_TIMINGS_PWR_UP2 = 0x00a2, + kD2207_SLOT_TIMINGS_PWR_DN2 = 0x00a3, + kD2207_ACT_TO_HIB_DLY = 0x00a4, + kD2207_BUCK0_SLOT = 0x00b0, + kD2207_BUCK1_SLOT = 0x00b1, + kD2207_BUCK2_SLOT = 0x00b2, + kD2207_BUCK3_SLOT = 0x00b3, + kD2207_BUCK4_SLOT = 0x00b4, + kD2207_BUCK5_SLOT = 0x00b5, + kD2207_BUCK6_SLOT = 0x00b6, + + kD2207_LDO1_SLOT = 0x00c1, + kD2207_LDO2_SLOT = 0x00c2, + kD2207_LDO3_SLOT = 0x00c3, + kD2207_LDO4_SLOT = 0x00c4, + kD2207_LDO5_SLOT = 0x00c5, + kD2207_LDO6_SLOT = 0x00c6, + kD2207_LDO7_SLOT = 0x00c7, + kD2207_LDO8_SLOT = 0x00c8, + kD2207_LDO9_SLOT = 0x00c9, + kD2207_LDO10_SLOT = 0x00ca, + kD2207_LDO11_SLOT = 0x00cb, + //kD2207_LDO12_SLOT = 0x00cc, Does not exist + kD2207_LDO13_SLOT = 0x00cd, + kD2207_LDO14_SLOT = 0x00ce, + + kD2207_LCM_BOOST_SW_SLOT = 0x00d0, + kD2207_LCM_BOOST_SLOT = 0x00d1, + kD2207_LCM_LDO1_SLOT = 0x00d2, + kD2207_LCM_LDO2_SLOT = 0x00d3, + kD2207_LCM_LDO3_SLOT = 0x00d4, + + kD2207_CHARGE_PUMP_SLOT = 0x00d8, + kD2207_BUCK3_SW1_SLOT = 0x00d9, + kD2207_BUCK3_SW2_SLOT = 0x00da, + kD2207_BUCK3_SW3_SLOT = 0x00db, + kD2207_BUCK4_SW1_SLOT = 0x00dc, + kD2207_BUCK4_SW2_SLOT = 0x00dd, + kD2207_GPIO_18_SLOT = 0x00de, + kD2207_GPIO_19_SLOT = 0x00df, + kD2207_GPIO_20_SLOT = 0x00e0, + kD2207_GPIO_21_SLOT = 0x00e1, + + kD2207_BUCK_DWI_CTRL0 = 0x00f0, + kD2207_BUCK_DWI_TRIM0 = 0x00f2, + kD2207_BUCK_FSM_TRIM0 = 0x00f4, + kD2207_BUCK_FSM_TRIM1 = 0x00f5, + kD2207_BUCK_FSM_TRIM2 = 0x00f6, + kD2207_BUCK_FSM_TRIM3 = 0x00f7, + + kD2207_BUCK_HIGHDVC_CALIB_OFFSET_TRIM = 0x00f8, + kD2207_BUCK_CPI_CLOCK_SEL = 0x00f9, + kD2207_BUCK_OFFSET_SEL = 0x00fa, + kD2207_BUCK_OFFSET_EN = 0x00fb, + + kD2207_BUCK0_VSEL = 0x0100, + kD2207_BUCK0_VSEL_ACTUAL = 0x0102, + kD2207_BUCK0_DEBUG_OFFSET = 0x0103, + kD2207_BUCK0_MINV = 0x0104, + kD2207_BUCK0_MAXV = 0x0105, + kD2207_BUCK0_OFS_V = 0x0106, + kD2207_BUCK0_MODE = 0x0107, + kD2207_BUCK0_START_ILIMIT = 0x0108, + kD2207_BUCK0_SYNC_ILIMIT = 0x0109, + kD2207_BUCK0_SLEEP_ILIMIT = 0x010a, + kD2207_BUCK0_FSM_TRIM0 = 0x010b, + kD2207_BUCK0_FSM_TRIM1 = 0x010c, + kD2207_BUCK0_FSM_TRIM2 = 0x010d, + kD2207_BUCK0_FSM_TRIM3 = 0x010e, + kD2207_BUCK0_FSM_TRIM4 = 0x010f, + kD2207_BUCK0_CLK_TRIM1 = 0x0110, + kD2207_BUCK0_CLK_TRIM2 = 0x0111, + kD2207_BUCK0_CLK_TRIM3 = 0x0112, + kD2207_BUCK0_CALIB0 = 0x0115, + kD2207_BUCK0_CALIB1 = 0x0116, + kD2207_BUCK0_ANA_TRIM0 = 0x0117, + kD2207_BUCK0_ANA_TRIM1 = 0x0118, + kD2207_BUCK0_ANA_TRIM2 = 0x0119, + kD2207_BUCK0_ANA_TRIM3 = 0x011a, + kD2207_BUCK0_ANA_TRIM4 = 0x011b, + kD2207_BUCK0_ANA_TRIM5 = 0x011c, + kD2207_BUCK0_ANA_TRIM6 = 0x011d, + kD2207_BUCK0_ANA_TRIM7 = 0x011e, + kD2207_BUCK0_ANA_TRIM8 = 0x011f, + kD2207_BUCK0_ANA_TRIM9 = 0x0120, + kD2207_BUCK0_ANA_TRIM10 = 0x0121, + + kD2207_BUCK1_VSEL = 0x0128, + kD2207_BUCK1_VSEL_ACTUAL = 0x012a, + kD2207_BUCK1_DEBUG_OFFSET = 0x012b, + kD2207_BUCK1_MINV = 0x012c, + kD2207_BUCK1_MAXV = 0x012d, + kD2207_BUCK1_OFS_V = 0x012e, + kD2207_BUCK1_MODE = 0x012f, + kD2207_BUCK1_START_ILIMIT = 0x0130, + kD2207_BUCK1_SYNC_ILIMIT = 0x0131, + kD2207_BUCK1_SLEEP_ILIMIT = 0x0132, + kD2207_BUCK1_FSM_TRIM0 = 0x0133, + kD2207_BUCK1_FSM_TRIM1 = 0x0134, + kD2207_BUCK1_FSM_TRIM2 = 0x0135, + kD2207_BUCK1_FSM_TRIM3 = 0x0136, + kD2207_BUCK1_FSM_TRIM4 = 0x0137, + kD2207_BUCK1_CLK_TRIM1 = 0x0138, + kD2207_BUCK1_CLK_TRIM2 = 0x0139, + kD2207_BUCK1_CLK_TRIM3 = 0x013a, + kD2207_BUCK1_CALIB0 = 0x013d, + kD2207_BUCK1_CALIB1 = 0x013e, + kD2207_BUCK1_ANA_TRIM0 = 0x013f, + kD2207_BUCK1_ANA_TRIM1 = 0x0140, + kD2207_BUCK1_ANA_TRIM2 = 0x0141, + kD2207_BUCK1_ANA_TRIM3 = 0x0142, + kD2207_BUCK1_ANA_TRIM4 = 0x0143, + kD2207_BUCK1_ANA_TRIM5 = 0x0144, + kD2207_BUCK1_ANA_TRIM6 = 0x0145, + kD2207_BUCK1_ANA_TRIM7 = 0x0146, + kD2207_BUCK1_ANA_TRIM9 = 0x0148, + + kD2207_BUCK2_VSEL = 0x0150, + kD2207_BUCK2_VSEL_ACTUAL = 0x0152, + kD2207_BUCK2_DEBUG_OFFSET = 0x0153, + kD2207_BUCK2_MINV = 0x0154, + kD2207_BUCK2_MAXV = 0x0155, + kD2207_BUCK2_OFS_V = 0x0156, + kD2207_BUCK2_MODE = 0x0157, + kD2207_BUCK2_START_ILIMIT = 0x0158, + kD2207_BUCK2_SYNC_ILIMIT = 0x0159, + kD2207_BUCK2_SLEEP_ILIMIT = 0x015a, + kD2207_BUCK2_FSM_TRIM0 = 0x015b, + kD2207_BUCK2_FSM_TRIM1 = 0x015c, + kD2207_BUCK2_FSM_TRIM2 = 0x015d, + kD2207_BUCK2_FSM_TRIM3 = 0x015e, + kD2207_BUCK2_FSM_TRIM4 = 0x015f, + kD2207_BUCK2_CLK_TRIM = 0x0160, + kD2207_BUCK2_CALIB0 = 0x0163, + kD2207_BUCK2_ANA_TRIM0 = 0x0165, + kD2207_BUCK2_ANA_TRIM1 = 0x0166, + kD2207_BUCK2_ANA_TRIM2 = 0x0167, + kD2207_BUCK2_ANA_TRIM3 = 0x0168, + kD2207_BUCK2_ANA_TRIM4 = 0x0169, + kD2207_BUCK2_ANA_TRIM5 = 0x016a, + kD2207_BUCK2_ANA_TRIM6 = 0x016b, + + kD2207_BUCK3_VSEL = 0x0178, + kD2207_BUCK3_VSEL_ALT = 0x0179, + kD2207_BUCK3_VSEL_ACTUAL = 0x017a, + kD2207_BUCK3_DEBUG_OFFSET = 0x017b, + kD2207_BUCK3_MINV = 0x017c, + kD2207_BUCK3_MAXV = 0x017d, + kD2207_BUCK3_OFS_V = 0x017e, + kD2207_BUCK3_MODE = 0x017f, + kD2207_BUCK3_START_ILIMIT = 0x0180, + kD2207_BUCK3_SYNC_ILIMIT = 0x0181, + kD2207_BUCK3_SLEEP_ILIMIT = 0x0182, + kD2207_BUCK3_FSM_TRIM0 = 0x0183, + kD2207_BUCK3_FSM_TRIM1 = 0x0184, + kD2207_BUCK3_FSM_TRIM3 = 0x0186, + kD2207_BUCK3_FSM_TRIM4 = 0x0187, + kD2207_BUCK3_CLK_TRIM = 0x0188, + kD2207_BUCK3_HIGHDVC_CALIB_OFFSET_TRIM = 0x0189, + kD2207_BUCK3_CALIB0 = 0x018b, + kD2207_BUCK3_ANA_TRIM0 = 0x018d, + kD2207_BUCK3_ANA_TRIM1 = 0x018e, + kD2207_BUCK3_ANA_TRIM2 = 0x018f, + kD2207_BUCK3_ANA_TRIM3 = 0x0190, + kD2207_BUCK3_ANA_TRIM4 = 0x0191, + kD2207_BUCK3_ANA_TRIM6 = 0x0193, + + kD2207_BUCK4_VSEL = 0x01a0, + kD2207_BUCK4_VSEL_ALT = 0x01a1, + kD2207_BUCK4_VSEL_ACTUAL = 0x01a2, + kD2207_BUCK4_DEBUG_OFFSET = 0x01a3, + kD2207_BUCK4_MINV = 0x01a4, + kD2207_BUCK4_MAXV = 0x01a5, + kD2207_BUCK4_OFS_V = 0x01a6, + kD2207_BUCK4_MODE = 0x01a7, + kD2207_BUCK4_START_ILIMIT = 0x01a8, + kD2207_BUCK4_SYNC_ILIMIT = 0x01a9, + kD2207_BUCK4_SLEEP_ILIMIT = 0x01aa, + kD2207_BUCK4_FSM_TRIM0 = 0x01ab, + kD2207_BUCK4_FSM_TRIM1 = 0x01ac, + kD2207_BUCK4_FSM_TRIM3 = 0x01ae, + kD2207_BUCK4_FSM_TRIM4 = 0x01af, + kD2207_BUCK4_CLK_TRIM = 0x01b0, + kD2207_BUCK4_CALIB0 = 0x01b3, + kD2207_BUCK4_ANA_TRIM0 = 0x01b5, + kD2207_BUCK4_ANA_TRIM1 = 0x01b6, + kD2207_BUCK4_ANA_TRIM2 = 0x01b7, + kD2207_BUCK4_ANA_TRIM3 = 0x01b8, + kD2207_BUCK4_ANA_TRIM4 = 0x01b9, + kD2207_BUCK4_ANA_TRIM5 = 0x01ba, + kD2207_BUCK4_ANA_TRIM6 = 0x01bb, + + kD2207_BUCK5_VSEL = 0x01c8, + kD2207_BUCK5_VSEL_ACTUAL = 0x01ca, + kD2207_BUCK5_DEBUG_OFFSET = 0x01cb, + kD2207_BUCK5_MINV = 0x01cc, + kD2207_BUCK5_MAXV = 0x01cd, + kD2207_BUCK5_OFS_V = 0x01ce, + kD2207_BUCK5_MODE = 0x01cf, + kD2207_BUCK5_START_ILIMIT = 0x01d0, + kD2207_BUCK5_SYNC_ILIMIT = 0x01d1, + kD2207_BUCK5_SLEEP_ILIMIT = 0x01d2, + kD2207_BUCK5_FSM_TRIM0 = 0x01d3, + kD2207_BUCK5_FSM_TRIM1 = 0x01d4, + kD2207_BUCK5_FSM_TRIM3 = 0x01d6, + kD2207_BUCK5_FSM_TRIM4 = 0x01d7, + kD2207_BUCK5_CLK_TRIM = 0x01d8, + kD2207_BUCK5_HIGHDVC_CALIB_OFFSET_TRIM = 0x01d9, + kD2207_BUCK5_CALIB0 = 0x01db, + kD2207_BUCK5_ANA_TRIM0 = 0x01dd, + kD2207_BUCK5_ANA_TRIM1 = 0x01de, + kD2207_BUCK5_ANA_TRIM2 = 0x01df, + kD2207_BUCK5_ANA_TRIM3 = 0x01e0, + kD2207_BUCK5_ANA_TRIM4 = 0x01e1, + kD2207_BUCK5_ANA_TRIM5 = 0x01e2, + + kD2207_BUCK6_VSEL = 0x01f0, + kD2207_BUCK6_VSEL_ACTUAL = 0x01f2, + kD2207_BUCK6_DEBUG_OFFSET = 0x01f3, + kD2207_BUCK6_MINV = 0x01f4, + kD2207_BUCK6_MAXV = 0x01f5, + kD2207_BUCK6_OFS_V = 0x01f6, + kD2207_BUCK6_MODE = 0x01f7, + kD2207_BUCK6_ILIMIT = 0x01f8, + kD2207_BUCK6_FSM_TRIM0 = 0x01f9, + kD2207_BUCK6_FSM_TRIM2 = 0x01fb, + kD2207_BUCK6_FSM_TRIM3 = 0x01fc, + kD2207_BUCK6_FSM_TRIM4 = 0x01fd, + kD2207_BUCK6_CLK_TRIM = 0x01fe, + kD2207_BUCK6_HIGHDVC_CALIB_OFFSET_TRIM = 0x01ff, + kD2207_BUCK6_CALIB0 = 0x0201, + kD2207_BUCK6_ANA_TRIM0 = 0x0203, + kD2207_BUCK6_ANA_TRIM1 = 0x0204, + kD2207_BUCK6_ANA_TRIM2 = 0x0205, + +// LDO Control + + kD2207_LDO_RTC_TRIM = 0x0304, + kD2207_LDO1_VSEL = 0x0308, + kD2207_LDO1_VSEL_ACTUAL = 0x0309, + kD2207_LDO1_MINV = 0x030a, + kD2207_LDO1_MAXV = 0x030b, + kD2207_LDO1_UOV_LIM = 0x030d, + kD2207_LDO2_VSEL = 0x0310, + kD2207_LDO2_VSEL_ACTUAL = 0x0311, + kD2207_LDO2_MINV = 0x0312, + kD2207_LDO2_MAXV = 0x0313, + kD2207_LDO2_UOV_LIM = 0x0315, + kD2207_LDO3_VSEL = 0x0318, + kD2207_LDO3_VSEL_ACTUAL = 0x0319, + kD2207_LDO3_MINV = 0x031a, + kD2207_LDO3_MAXV = 0x031b, + kD2207_LDO3_UOV_LIM = 0x031d, + kD2207_LDO4_VSEL = 0x0320, + kD2207_LDO4_VSEL_ACTUAL = 0x0321, + kD2207_LDO4_MINV = 0x0322, + kD2207_LDO4_MAXV = 0x0323, + kD2207_LDO4_UOV_LIM = 0x0325, + kD2207_LDO5_VSEL = 0x0328, + kD2207_LDO5_VSEL_ACTUAL = 0x0329, + kD2207_LDO5_MINV = 0x032a, + kD2207_LDO5_MAXV = 0x032b, + kD2207_LDO5_TRIM = 0x032c, + kD2207_LDO5_UOV_LIM = 0x032d, + kD2207_LDO6_VSEL = 0x0330, + kD2207_LDO6_VSEL_ACTUAL = 0x0331, + kD2207_LDO6_MINV = 0x0332, + kD2207_LDO6_MAXV = 0x0333, + kD2207_LDO6_TRIM = 0x0334, + kD2207_LDO6_UOV_LIM = 0x0335, + kD2207_LDO7_VSEL = 0x0338, + kD2207_LDO7_VSEL_ACTUAL = 0x0339, + kD2207_LDO7_MINV = 0x033a, + kD2207_LDO7_MAXV = 0x033b, + kD2207_LDO7_UOV_LIM = 0x033d, + kD2207_LDO8_VSEL = 0x0340, + kD2207_LDO8_VSEL_ACTUAL = 0x0341, + kD2207_LDO8_MINV = 0x0342, + kD2207_LDO8_MAXV = 0x0343, + kD2207_LDO8_UOV_LIM = 0x0345, + kD2207_LDO9_VSEL = 0x0348, + kD2207_LDO9_VSEL_ACTUAL = 0x0349, + kD2207_LDO9_MINV = 0x034a, + kD2207_LDO9_MAXV = 0x034b, + kD2207_LDO9_UOV_LIM = 0x034d, + kD2207_LDO10_VSEL = 0x0350, + kD2207_LDO10_VSEL_ACTUAL = 0x0351, + kD2207_LDO10_MINV = 0x0352, + kD2207_LDO10_MAXV = 0x0353, + kD2207_LDO10_UOV_LIM = 0x0355, + kD2207_LDO11_VSEL = 0x0358, + kD2207_LDO11_VSEL_ACTUAL = 0x0359, + kD2207_LDO11_MINV = 0x035a, + kD2207_LDO11_MAXV = 0x035b, + kD2207_LDO11_UOV_LIM = 0x035d, + kD2207_LDO12_TRIM = 0x0364, + kD2207_LDO13_VSEL = 0x0368, + kD2207_LDO13_VSEL_ACTUAL = 0x0369, + kD2207_LDO13_MINV = 0x036a, + kD2207_LDO13_MAXV = 0x036b, + kD2207_LDO13_UOV_LIM = 0x036d, + kD2207_LDO14_VSEL = 0x0370, + kD2207_LDO14_VSEL_ACTUAL = 0x0371, + kD2207_LDO14_MINV = 0x0372, + kD2207_LDO14_MAXV = 0x0373, + kD2207_LDO14_UOV_LIM = 0x0375, + + kD2207_LCM_LDO1 = 0x0378, + kD2207_LCM_LDO1_VSEL_ACTUAL = 0x0379, + kD2207_LCM_LDO1_MINV = 0x037a, + kD2207_LCM_LDO1_MAXV = 0x037b, + kD2207_LCM_LDO1_TRIM = 0x037c, + kD2207_LCM_LDO2 = 0x0380, + kD2207_LCM_LDO2_VSEL_ACTUAL = 0x0381, + kD2207_LCM_LDO2_MINV = 0x0382, + kD2207_LCM_LDO2_MAXV = 0x0383, + kD2207_LCM_LDO3 = 0x0388, + kD2207_LCM_LDO3_VSEL_ACTUAL = 0x0389, + kD2207_LCM_LDO3_MINV = 0x038a, + kD2207_LCM_LDO3_MAXV = 0x038b, + kD2207_LDO_BYP1 = 0x0390, + kD2207_LDO_BYP2 = 0x0391, + kDIALOG_LDO_CONTROL = kD2207_LDO_BYP2, + +// LCM Boost Control + + kD2207_LCM_BOOST_VSEL = 0x0398, + kD2207_LCM_BOOST_VSEL_ACTUAL = 0x0399, + kD2207_LCM_BOOST_MINV = 0x039a, + kD2207_LCM_BOOST_MAXV = 0x039b, + kD2207_LCM_BOOST_CONF = 0x039c, + kD2207_LCM_BOOST_TRIM = 0x039d, + +// Hibernate Switches + + kD2207_HIB_SW_CTRL = 0x03c0, + kD2207_HIB_SW_CTRL_2 = 0x03c1, + +// GPIO Control + + kD2207_GPIO1 = 0x0400, + kDIALOG_SYS_GPIO_REG_START = kD2207_GPIO1, + kD2207_GPIO2 = 0x0401, + kD2207_GPIO3 = 0x0402, + kD2207_GPIO4 = 0x0403, + kD2207_GPIO5 = 0x0404, + kD2207_GPIO6 = 0x0405, + kD2207_GPIO7 = 0x0406, + kD2207_GPIO8 = 0x0407, + kD2207_GPIO9 = 0x0408, + kD2207_GPIO10 = 0x0409, + kD2207_GPIO11 = 0x040a, + kD2207_GPIO12 = 0x040b, + kD2207_GPIO13 = 0x040c, + kD2207_GPIO14 = 0x040d, + kD2207_GPIO15 = 0x040e, + kD2207_GPIO16 = 0x040f, + kD2207_GPIO17 = 0x0410, + kD2207_GPIO18_HIB = 0x0411, + kD2207_GPIO18_SBY = 0x0412, + kD2207_GPIO18 = 0x0413, + kD2207_GPIO19_HIB = 0x0414, + kD2207_GPIO19_SBY = 0x0415, + kD2207_GPIO19 = 0x0416, + kD2207_GPIO20_HIB = 0x0417, + kD2207_GPIO20_SBY = 0x0418, + kD2207_GPIO20 = 0x0419, + kD2207_GPIO21_HIB = 0x041a, + kD2207_GPIO21_SBY = 0x041b, + kD2207_GPIO21 = 0x041c, + + kD2207_GPIO_DEB1 = 0x0420, + kD2207_GPIO_DEB2 = 0x0421, + kD2207_GPIO_DEB3 = 0x0422, + kD2207_GPIO_DEB4 = 0x0423, + kD2207_GPIO_DEB5 = 0x0424, + kD2207_GPIO_DEB6 = 0x0425, + kD2207_GPIO_DEB7 = 0x0426, + kD2207_GPIO_DEB8 = 0x0427, + kD2207_GPIO_DEB9 = 0x0428, + kD2207_GPIO_DEB10 = 0x0429, + kD2207_GPIO_DEB11 = 0x042a, + + kD2207_OUT_32K = 0x0430, + +// GPI Control + + kD2207_BUTTON1_CONF = 0x0440, + kD2207_BUTTON2_CONF = 0x0441, + kD2207_BUTTON3_CONF = 0x0442, + kD2207_BUTTON4_CONF = 0x0443, + kDIALOG_BUTTON_DBL = 0x0444, + kD2207_BUTTON_WAKE = 0x0445, + + kD2207_RESET_IN1_CONF = 0x0448, + kD2207_RESET_IN2_CONF = 0x0449, + kD2207_RESET_IN3_CONF = 0x044a, + kD2207_RIN_STD_DIS = (0<<7), + kD2207_RIN_HIB_DIS = (0<<6), + kD2207_RIN_ACT_DIS = (0<<5), + kD2207_RIN_POL_RISE = (0<<4), + kD2207_RIN_POL_FALL = (1<<4), + kD2207_RIN_NO_PUPD = (0<<2), + kD2207_RIN_PU = (1<<2), + kD2207_RIN_PD = (2<<2), + kD2207_RIN_T_DEB_10MS = (0<<1), + kD2207_RIN_T_DEB_100MS = (1<<1), + kD2207_RIN_ENABLED = (0<<0), + kD2207_RIN_DISABLED = (1<<0), + +// Temperature Sensor Control + + kD2207_TDEV1_RISE = 0x0480, + kD2207_TDEV1_FALL = 0x0481, + kD2207_TDEV2_RISE = 0x0482, + kD2207_TDEV2_FALL = 0x0483, + kD2207_TDEV3_RISE = 0x0484, + kD2207_TDEV3_FALL = 0x0485, + kD2207_TDEV4_RISE = 0x0486, + kD2207_TDEV4_FALL = 0x0487, + kD2207_TDEV5_RISE = 0x0488, + kD2207_TDEV5_FALL = 0x0489, + kD2207_TDEV6_RISE = 0x048a, + kD2207_TDEV6_FALL = 0x048b, + kD2207_TDEV7_RISE = 0x048c, + kD2207_TDEV7_FALL = 0x048d, + kD2207_TDEV8_RISE = 0x048e, + kD2207_TDEV8_FALL = 0x048f, + kD2207_TLDO5_RISE = 0x04a0, + kD2207_TCBUCK_A_RISE = 0x04a2, + kD2207_TCBUCK_B_RISE = 0x04a3, + kD2207_TLINCHG_RISE = 0x04a4, + kD2207_TBUCK0_RISE = 0x04a5, + kD2207_TBUCK4_RISE = 0x04a6, + kD2207_TBUCK23_RISE = 0x04a7, + kD2207_TBUCK1_RISE = 0x04a8, + kD2207_TBUCK56_RISE = 0x04a9, + kD2207_TISENSE_HYST = 0x04aa, + kDIALOG_T_OFFSET_MSB = 0x04ab, + kDIALOG_T_OFFSET_LSB = 0x04ac, + +// Charging Control + + kD2207_ISET_BUCK = 0x04c0, + kD2207_ISET_BUCK_SHADOW = 0x04c1, + kD2207_ISET_BUCK_ABSMAX = 0x04c2, + kD2207_ISET_BUCK_ACTUAL = 0x04c3, + kD2207_ISET_BUCK_ALT = 0x04c4, + kDIALOG_CHARGE_BUCK_CONTROL = kD2207_ISET_BUCK, + kDIALOG_CHARGE_BUCK_STATUS = kD2207_ISET_BUCK_ACTUAL, + kD2207_CHG_CTRL_A = 0x04c5, + kD2207_CHG_CTRL_B = 0x04c6, + kD2207_CHG_CTRL_C = 0x04c7, + kD2207_CHG_CTRL_D = 0x04c8, + kD2207_CHG_CTRL_E = 0x04c9, + kD2207_CHG_CTRL_F = 0x04ca, + kD2207_CHG_CTRL_G = 0x04cb, + kD2207_CHG_CTRL_H = 0x04cc, + kD2207_CHG_TIME = 0x04cd, + kD2207_CHG_TIME_PRE = 0x04ce, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD2207_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_HIB = kD2207_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_TIME = kD2207_CHG_CTRL_D, + kDIALOG_CHARGE_CONTROL_EN = kD2207_CHG_CTRL_H, + kDIALOG_OTP_ISET_BAT = kD2207_CHG_CTRL_C, + kDIALOG_CHARGE_STATUS = 0x04cf, + kD2207_CHG_VSET_TRIM = 0x04d0, + kD2207_IBUS_GAIN_TRIM = 0x04d2, + kD2207_IBUS100_OFS_TRIM = 0x04d3, + kD2207_IBUS500_OFS_TRIM = 0x04d4, + kD2207_IBUS1500_GAIN_TRIM= 0x04d5, + kD2207_IBUS1500_OFS_TRIM= 0x04d6, + + kD2207_CHG_TRIM1 = 0x04d7, + kD2207_CHG_TRIM2 = 0x04d8, + kD2207_CHG_TRIM3 = 0x04d9, + kD2207_CHG_TRIM4 = 0x04da, + kD2207_CHG_TRIM5 = 0x04db, + kD2207_ICHG_END = 0x04dc, + + kDIALOG_TBAT_0 = 0x04dd, + kDIALOG_TBAT_1 = 0x04de, + kDIALOG_TBAT_2 = 0x04df, + kDIALOG_TBAT_3 = 0x04e0, + kDIALOG_TBAT_4 = 0x04e1, + kDIALOG_TBAT_MAX = 0x04e2, + kDIALOG_ICHG_TBAT_0 = 0x04e3, + kDIALOG_ICHG_TBAT_1 = 0x04e4, + kDIALOG_ICHG_TBAT_2 = 0x04e5, + kDIALOG_ICHG_TBAT_3 = 0x04e6, + kDIALOG_ICHG_TBAT_4 = 0x04e7, + kDIALOG_ICHG_AVG = 0x04e8, + +// GPADC Control and Results + + kDIALOG_ADC_CONTROL = 0x0500, + kDIALOG_ADC_CONTROL2 = 0x0501, + kDIALOG_ADC_LSB = 0x0502, + kDIALOG_ADC_MSB = 0x0503, + kD2207_ADC_TEMP_CTRL0 = 0x0504, + kD2207_ADC_TEMP_CTRL1 = 0x0505, + kD2207_ADC_FSM_TRIM0 = 0x0506, + kD2207_ADC_FSM_TRIM1 = 0x0507, + kD2207_ADC_FSM_TRIM2 = 0x0508, + kD2207_ADC_FSM_TRIM3 = 0x0509, + kD2207_ADC_ANA_TRIM0 = 0x050a, + kD2207_VCC_MAIN_MON = 0x050c, + kDIALOG_IBUS_ACCUM1 = 0x050e, + kDIALOG_IBUS_ACCUM2 = 0x050f, + kDIALOG_IBUS_ACCUM3 = 0x0510, + kDIALOG_VBUS_ACCUM1 = 0x0511, + kDIALOG_VBUS_ACCUM2 = 0x0512, + kDIALOG_VBUS_ACCUM3 = 0x0513, + kDIALOG_TDIE_ACCUM1 = 0x0514, + kDIALOG_TDIE_ACCUM2 = 0x0515, + kDIALOG_TDIE_ACCUM3 = 0x0516, + kDIALOG_IBUS_COUNT1 = 0x0517, + kDIALOG_IBUS_COUNT2 = 0x0518, + kD2207_IBUSCAL_1 = 0x0519, + kD2207_IBUSCAL_2 = 0x051a, + kD2207_IBUSCAL_3 = 0x051b, + kD2207_IBUSCAL_4 = 0x051c, + kD2207_IBUSCAL_5 = 0x051d, + kD2207_IBUSCAL_6 = 0x051e, + kD2207_IBUSCAL_7 = 0x051f, + kD2207_IBUSCAL_8 = 0x0520, + kD2207_IBUCK0_ACCUM1 = 0x0522, + kD2207_IBUCK0_ACCUM2 = 0x0523, + kD2207_IBUCK0_ACCUM3 = 0x0524, + kD2207_IBUCK1_ACCUM1 = 0x0525, + kD2207_IBUCK1_ACCUM2 = 0x0526, + kD2207_IBUCK1_ACCUM3 = 0x0527, + kDIALOG_IBUCK0_COUNT1 = 0x0528, + kDIALOG_IBUCK0_COUNT2 = 0x0529, + kDIALOG_IBUCK1_COUNT1 = 0x052a, + kDIALOG_IBUCK1_COUNT2 = 0x052b, + +// BIST ADC Control and Results + + kDIALOG_APP_TMUX = 0x0540, + kDIALOG_BIST_ADC_CTRL = 0x0541, + kDIALOG_BIST_ADC_LSB = 0x0542, + kDIALOG_BIST_ADC_MSB = 0x0543, + kD2207_BIST_ADC_TRIM1 = 0x0545, + kD2207_BIST_ADC_ANA_TRIM0 = 0x0546, + +// RTC Calendar and Alarm + + kDIALOG_RTC_ALARM_A = 0x05c0, + kDIALOG_RTC_ALARM_B = 0x05c1, + kDIALOG_RTC_ALARM_C = 0x05c2, + kDIALOG_RTC_ALARM_D = 0x05c3, + kDIALOG_RTC_CONTROL = 0x05c4, + kDIALOG_RTC_TIMEZONE = 0x05c5, + kDIALOG_RTC_SUB_SECOND_A = 0x05c6, + kDIALOG_RTC_SUB_SECOND_B = 0x05c7, + kDIALOG_RTC_SECOND_A = 0x05c8, + kDIALOG_RTC_SECOND_B = 0x05c9, + kDIALOG_RTC_SECOND_C = 0x05ca, + kDIALOG_RTC_SECOND_D = 0x05cb, + +// WLED + + kD2207_WLED_ISET_MSB = 0x0600, + kD2207_WLED_ISET_LSB = 0x0601, + kD2207_WLED_PWM_MSB = 0x0602, + kD2207_WLED_PWM_LSB = 0x0603, + kD2207_WLED_CTRL1 = 0x0604, + kD2207_WLED_CTRL2 = 0x0605, + kD2207_WLED_CTRL3 = 0x0606, + kD2207_WLED_CTRL4 = 0x0607, + kD2207_WLED_CTRL5 = 0x0608, + kD2207_WLED_CTRL6 = 0x0609, + kD2207_WLED_CTRL7 = 0x060a, + kD2207_WLED_ERR_STAT_A = 0x060b, + kD2207_WLED_ERR_STAT_B = 0x060c, + kD2207_WLED_CONF1 = 0x060d, + kD2207_WLED_CONF2 = 0x060e, + kD2207_WLED_CONF3 = 0x060f, + kD2207_WLED_TRIM1 = 0x0610, + kD2207_WLED_TRIM2 = 0x0611, + kD2207_WLED_TRIM3 = 0x0612, + kD2207_WLED_TRIM4 = 0x0613, + kD2207_WLED_TRIM5 = 0x0614, + kD2207_WLED_TRIM6 = 0x0615, + kD2207_WLED_TRIM7 = 0x0616, + kD2207_WLED_TRIM8 = 0x0617, + kD2207_WLED_TRIM9 = 0x0618, + kD2207_WLED_TRIM10 = 0x0619, + kD2207_WLED_TRIM11 = 0x061a, + kD2207_WLED_TRIM12 = 0x061b, + kD2207_WLED_TRIM13 = 0x061c, + kD2207_WLED_TRIM14 = 0x061d, + + kDIALOG_WLED_ISET = kD2207_WLED_ISET_MSB, + kDIALOG_WLED_ISET2 = kD2207_WLED_ISET_LSB, + kDIALOG_WLED_CONTROL = kD2207_WLED_CTRL1, + kDIALOG_WLED_DWI_CONTROL= kD2207_WLED_CTRL2, + kDIALOG_WLED_OPTIONS = kD2207_WLED_CTRL2, + +// Reserved Spare Registers + + kD2207_SPARE_RW0 = 0x0680, + kD2207_SPARE_RW_LAST = 0x0687, + kD2207_SPARE_RWTOTP0 = 0x06a0, + kD2207_SPARE_RWTOTP_LAST= 0x06a7, + kD2207_SPARE_RWOTP0 = 0x06c0, + kD2207_SPARE_RWOTP1 = 0x06c1, + +// Legacy Scratch Pads + + kDIALOG_MEMBYTE0 = 0x4000, + kDIALOG_MEMBYTE_LAST = 0x4027, + +// Scratch Pad RAM + + kDIALOG_TEST_ACCESS = 0x7000, + kDIALOG_TEST_ACCESS_ENA = 0x1D, + kDIALOG_TEST_ACCESS_DIS = 0x00, + + kDIALOG_RAM0 = 0x8000, + kDIALOG_EXT_MEM_CAL0 = kDIALOG_RAM0, + kDIALOG_EXT_MEM_CAL0_SIZE = 64, + kDIALOG_DIAG_SCRATCH = kDIALOG_EXT_MEM_CAL0+kDIALOG_EXT_MEM_CAL0_SIZE, // + kDIALOG_DIAG_SCRATCH_SIZE = 8, + kDIALOG_EXT_MEM_CAL1= kDIALOG_DIAG_SCRATCH+kDIALOG_DIAG_SCRATCH_SIZE, + kDIALOG_EXT_MEM_CAL1_SIZE= 336, + kDIALOG_VOLTAGE_KNOBS = kDIALOG_EXT_MEM_CAL1+kDIALOG_EXT_MEM_CAL1_SIZE, + kDIALOG_VOLTAGE_KNOBS_SIZE=32, + + kDIALOG_EXT_MEM_CAL_SIZE= kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_EXT_MEM_CAL1_SIZE, + + kDIALOG_RAM_LAST = 0x87ff, +}; + + +// Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 4, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, + kDIALOG_IBUCK0_ACCUMULATOR = 2, + kDIALOG_IBUCK1_ACCUMULATOR = 3, +}; + +enum { + kD2207_EVENT_A_TBAT = (1 << 7), + kD2207_EVENT_A_VBUS_EXT_REM = (1 << 6), + kD2207_EVENT_A_VDD_LOW = (1 << 5), + kD2207_EVENT_A_CHG_HV_ATT = (1 << 4), + kD2207_EVENT_A_VBUS_EXT_DET = (1 << 3), + kD2207_EVENT_A_ACC_DET = (1 << 2), + kD2207_EVENT_A_VDD_PRE_UVLO = (1 << 1), + kD2207_EVENT_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2207_EVENT_B_BTN4_DBL = (1 << 7), + kD2207_EVENT_B_BTN3_DBL = (1 << 6), + kD2207_EVENT_B_BTN2_DBL = (1 << 5), + kD2207_EVENT_B_BTN1_DBL = (1 << 4), + kD2207_EVENT_B_BUTTON_4 = (1 << 3), + kD2207_EVENT_B_BUTTON_3 = (1 << 2), + kD2207_EVENT_B_BUTTON_2 = (1 << 1), + kD2207_EVENT_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2207_EVENT_C_CHG_BUCK_FLG = (1 << 6), + kD2207_EVENT_C_CHG_ABCC_ACT = (1 << 5), + kD2207_EVENT_C_CHG_TIMEOUT = (1 << 4), + kD2207_EVENT_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2207_EVENT_C_CHG_END = (1 << 2), + kD2207_EVENT_C_CHG_FAST = (1 << 1), + kD2207_EVENT_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2207_EVENT_D_GPIO8 = (1 << 7), + kD2207_EVENT_D_GPIO7 = (1 << 6), + kD2207_EVENT_D_GPIO6 = (1 << 5), + kD2207_EVENT_D_GPIO5 = (1 << 4), + kD2207_EVENT_D_GPIO4 = (1 << 3), + kD2207_EVENT_D_GPIO3 = (1 << 2), + kD2207_EVENT_D_GPIO2 = (1 << 1), + kD2207_EVENT_D_GPIO1 = (1 << 0), +}; + +enum { + kD2207_EVENT_E_GPIO16 = (1 << 7), + kD2207_EVENT_E_GPIO15 = (1 << 6), + kD2207_EVENT_E_GPIO14 = (1 << 5), + kD2207_EVENT_E_GPIO13 = (1 << 4), + kD2207_EVENT_E_GPIO12 = (1 << 3), + kD2207_EVENT_E_GPIO11 = (1 << 2), + kD2207_EVENT_E_GPIO10 = (1 << 1), + kD2207_EVENT_E_GPIO9 = (1 << 0), +}; + +enum { + kD2207_EVENT_F_GPIO21 = (1 << 4), + kD2207_EVENT_F_GPIO20 = (1 << 3), + kD2207_EVENT_F_GPIO19 = (1 << 2), + kD2207_EVENT_F_GPIO18 = (1 << 1), + kD2207_EVENT_F_GPIO17 = (1 << 0), +}; + +enum { + kD2207_EVENT_G_T4_RISE = (1 << 7), + kD2207_EVENT_G_T4_FALL = (1 << 6), + kD2207_EVENT_G_T3_RISE = (1 << 5), + kD2207_EVENT_G_T3_FALL = (1 << 4), + kD2207_EVENT_G_T2_RISE = (1 << 3), + kD2207_EVENT_G_T2_FALL = (1 << 2), + kD2207_EVENT_G_T1_RISE = (1 << 1), + kD2207_EVENT_G_T1_FALL = (1 << 0), +}; + +enum { + kD2207_EVENT_H_T8_RISE = (1 << 7), + kD2207_EVENT_H_T8_FALL = (1 << 6), + kD2207_EVENT_H_T7_RISE = (1 << 5), + kD2207_EVENT_H_T7_FALL = (1 << 4), + kD2207_EVENT_H_T6_RISE = (1 << 3), + kD2207_EVENT_H_T6_FALL = (1 << 2), + kD2207_EVENT_H_T5_RISE = (1 << 1), + kD2207_EVENT_H_T5_FALL = (1 << 0), +}; + +enum { + kD2207_EVENT_I_TLDO5 = (1 << 7), + kD2207_EVENT_I_TBUCK_5_6 = (1 << 4), + kD2207_EVENT_I_TBUCK_1 = (1 << 3), + kD2207_EVENT_I_TBUCK_2_3 = (1 << 2), + kD2207_EVENT_I_TBUCK4 = (1 << 1), + kD2207_EVENT_I_TBUCK0 = (1 << 0), +}; + +enum { + kD2207_EVENT_J_HIGH_TEMP_WARNING = (1 << 7), + kD2207_EVENT_J_WLEDB_SHORT = (1 << 6), + kD2207_EVENT_J_WLEDB_OPEN = (1 << 5), + kD2207_EVENT_J_WLEDA_SHORT = (1 << 4), + kD2207_EVENT_J_WLEDA_OPEN = (1 << 3), + kD2207_EVENT_J_TLINCHG = (1 << 2), + kD2207_EVENT_J_TCBUCK_B = (1 << 1), + kD2207_EVENT_J_TCBUCK_A = (1 << 0), +}; + +enum { + kD2207_EVENT_K_BUCK_LDO_UOV = (1 << 7), + kD2207_EVENT_K_XTAL_ERROR = (1 << 6), + kD2207_EVENT_K_VBUS_OV = (1 << 5), + kD2207_EVENT_K_VBUS_OC = (1 << 4), + kD2207_EVENT_K_LDO6_OC = (1 << 0), +}; + +enum { + kD2207_EVENT_L_IBUCK1_OVERFLOW = (1 << 7), + kD2207_EVENT_L_IBUCK0_OVERFLOW = (1 << 6), + kD2207_EVENT_L_IBUS_OVERFLOW = (1 << 5), + kD2207_EVENT_L_HIB = (1 << 4), + kD2207_EVENT_L_DWI_TO = (1 << 3), + kD2207_EVENT_L_EOMC_BIST = (1 << 2), + kD2207_EVENT_L_EOMC = (1 << 1), + kD2207_EVENT_L_ALARM = (1 << 0), +}; + +enum { + kD2207_EVENT_M_BUCK2_POS_ILIM_MON = (1 << 7), + kD2207_EVENT_M_BUCK2_NEG_ILIM_MON = (1 << 6), + kD2207_EVENT_M_BUCK1_POS_ILIM_MON = (1 << 5), + kD2207_EVENT_M_BUCK1_NEG_ILIM_MON = (1 << 4), + kD2207_EVENT_M_BUCK0_POS_ILIM_MON = (1 << 3), + kD2207_EVENT_M_BUCK0_NEG_ILIM_MON = (1 << 2), +}; + +enum { + kD2207_EVENT_N_BUCK6_POS_ILIM_MON = (1 << 7), + kD2207_EVENT_N_BUCK6_NEG_ILIM_MON = (1 << 6), + kD2207_EVENT_N_BUCK5_POS_ILIM_MON = (1 << 5), + kD2207_EVENT_N_BUCK5_NEG_ILIM_MON = (1 << 4), + kD2207_EVENT_N_BUCK4_POS_ILIM_MON = (1 << 3), + kD2207_EVENT_N_BUCK4_NEG_ILIM_MON = (1 << 2), + kD2207_EVENT_N_BUCK3_POS_ILIM_MON = (1 << 1), + kD2207_EVENT_N_BUCK3_NEG_ILIM_MON = (1 << 0), +}; + +enum { + kD2207_STATUS_A_TBAT = (1 << 7), + kD2207_STATUS_A_VDD_LOW = (1 << 5), + kD2207_STATUS_A_CHG_HV_ATT = (1 << 4), + kD2207_STATUS_A_VBUS_EXT_DET = (1 << 3), + kD2207_STATUS_A_ACC_DET = (1 << 2), + kD2207_STATUS_A_VDD_PRE_UVLO = (1 << 1), + kD2207_STATUS_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2207_STATUS_B_BUTTON_4 = (1 << 3), + kD2207_STATUS_B_BUTTON_3 = (1 << 2), + kD2207_STATUS_B_BUTTON_2 = (1 << 1), + kD2207_STATUS_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2207_STATUS_C_CHG_HV_EN = (1 << 7), + kD2207_STATUS_C_CHG_BUCK_FLG = (1 << 6), + kD2207_STATUS_C_CHG_ABCC_ACT = (1 << 5), + kD2207_STATUS_C_CHG_TIMEOUT = (1 << 4), + kD2207_STATUS_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2207_STATUS_C_CHG_END = (1 << 2), + kD2207_STATUS_C_CHG_FAST = (1 << 1), + kD2207_STATUS_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2207_STATUS_D_GPIO8 = (1 << 7), + kD2207_STATUS_D_GPIO7 = (1 << 6), + kD2207_STATUS_D_GPIO6 = (1 << 5), + kD2207_STATUS_D_GPIO5 = (1 << 4), + kD2207_STATUS_D_GPIO4 = (1 << 3), + kD2207_STATUS_D_GPIO3 = (1 << 2), + kD2207_STATUS_D_GPIO2 = (1 << 1), + kD2207_STATUS_D_GPIO1 = (1 << 0), +}; + +enum { + kD2207_STATUS_E_GPIO16 = (1 << 7), + kD2207_STATUS_E_GPIO15 = (1 << 6), + kD2207_STATUS_E_GPIO14 = (1 << 5), + kD2207_STATUS_E_GPIO13 = (1 << 4), + kD2207_STATUS_E_GPIO12 = (1 << 3), + kD2207_STATUS_E_GPIO11 = (1 << 2), + kD2207_STATUS_E_GPIO10 = (1 << 1), + kD2207_STATUS_E_GPIO9 = (1 << 0), +}; + +enum { + kD2207_STATUS_F_GPIO21 = (1 << 4), + kD2207_STATUS_F_GPIO20 = (1 << 3), + kD2207_STATUS_F_GPIO19 = (1 << 2), + kD2207_STATUS_F_GPIO18 = (1 << 1), + kD2207_STATUS_F_GPIO17 = (1 << 0), +}; + +enum { + kD2207_STATUS_G_T4_RISE = (1 << 7), + kD2207_STATUS_G_T4_FALL = (1 << 6), + kD2207_STATUS_G_T3_RISE = (1 << 5), + kD2207_STATUS_G_T3_FALL = (1 << 4), + kD2207_STATUS_G_T2_RISE = (1 << 3), + kD2207_STATUS_G_T2_FALL = (1 << 2), + kD2207_STATUS_G_T1_RISE = (1 << 1), + kD2207_STATUS_G_T1_FALL = (1 << 0), +}; + +enum { + kD2207_STATUS_H_T8_RISE = (1 << 7), + kD2207_STATUS_H_T8_FALL = (1 << 6), + kD2207_STATUS_H_T7_RISE = (1 << 5), + kD2207_STATUS_H_T7_FALL = (1 << 4), + kD2207_STATUS_H_T6_RISE = (1 << 3), + kD2207_STATUS_H_T6_FALL = (1 << 2), + kD2207_STATUS_H_T5_RISE = (1 << 1), + kD2207_STATUS_H_T5_FALL = (1 << 0), +}; + +enum { + kD2207_STATUS_I_TLDO5 = (1 << 7), + kD2207_STATUS_I_TBUCK_5_6 = (1 << 4), + kD2207_STATUS_I_TBUCK_1 = (1 << 3), + kD2207_STATUS_I_TBUCK_2_3 = (1 << 2), + kD2207_STATUS_I_TBUCK4 = (1 << 1), + kD2207_STATUS_I_TBUCK0 = (1 << 0), +}; + +enum { + kD2207_STATUS_J_HIGH_TEMP_WARNING = (1 << 7), + kD2207_STATUS_J_TLINCHG = (1 << 2), + kD2207_STATUS_J_TCBUCK_B = (1 << 1), + kD2207_STATUS_J_TCBUCK_A = (1 << 0), +}; + +enum { + kD2207_STATUS_K_BUCK_LDO_UOV = (1 << 7), + kD2207_STATUS_K_XTAL_ERROR = (1 << 6), + kD2207_STATUS_K_VBUS_OV = (1 << 5), + kD2207_STATUS_K_VBUS_OC = (1 << 4), +}; + +enum { + kD2207_STATUS_L_IBUCK1_OVERFLOW = (1 << 7), + kD2207_STATUS_L_IBUCK0_OVERFLOW = (1 << 6), + kD2207_STATUS_L_IBUS_OVERFLOW = (1 << 5), + kD2207_STATUS_L_DWI_TO = (1 << 3), +}; + +enum { + kD2207_STATUS_M_PROT_FET_ON = (1 << 1), + kD2207_STATUS_M_CHG_ATT = (1 << 0), +}; + +enum { + kD2207_BUCK_MODE_FSLEEP = 0, + kD2207_BUCK_MODE_AUTO = 1, + kD2207_BUCK_MODE_FSYNC = 2, + kD2207_BUCK_MODE_MASK = 0x3, +}; + +enum { + kD2207_BUCK_UOV_CMP_EN = ( 1<<2 ), + kD2207_LDO_UOV_CMP_EN = ( 1<<1 ), + kD2207_MAIN_UOV_CMP_EN = ( 1<<0 ), + kD2207_UOV_CMP_MASK = ( kD2207_BUCK_UOV_CMP_EN | kD2207_MAIN_UOV_CMP_EN ), + + kD2207_BUCK_OV_TRIM_SHIFT = 2, + kD2207_BUCK_OV_TRIM_MASK = (0x3< J99 EVT not recognizing lightning connection + kDIALOG_OTP_RELOAD_CONF = kD2231_SYS_CONF_E, + kDIALOG_OTP_SKIP_RELOAD_TO_ACT = (1<<6), +}; + +// ------------------------------------------------------------------- +// +// ------------------------------------------------------------------- + +// Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 2, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, + kDIALOG_IBUCK0_ACCUMULATOR = 0, + kDIALOG_IBUCK1_ACCUMULATOR = 0, +}; + +enum { + kD2231_EVENT_A_TBAT = (1 << 7), + kD2231_EVENT_A_VBUS_EXT_REM = (1 << 6), + kD2231_EVENT_A_VDD_LOW = (1 << 5), + kD2231_EVENT_A_CHG_HV_ATT = (1 << 4), + kD2231_EVENT_A_VBUS_EXT_DET = (1 << 3), + kD2231_EVENT_A_HV_MODE = (1 << 2), + kD2231_EVENT_A_CHG_BUCK_LIMITED = (1 << 1), + kD2231_EVENT_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2231_EVENT_C_CHG_SLOW = (1 << 7), + kD2231_EVENT_C_CHG_BUCK_FLG = (1 << 6), + kD2231_EVENT_C_CHG_ABCC_ACT = (1 << 5), + kD2231_EVENT_C_CHG_TIMEOUT = (1 << 4), + kD2231_EVENT_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2231_EVENT_C_CHG_END = (1 << 2), + kD2231_EVENT_C_CHG_FAST = (1 << 1), + kD2231_EVENT_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2231_EVENT_D_GPIO6 = (1 << 5), + kD2231_EVENT_D_GPIO5 = (1 << 4), + kD2231_EVENT_D_GPIO4 = (1 << 3), + kD2231_EVENT_D_GPIO3 = (1 << 2), + kD2231_EVENT_D_GPIO2 = (1 << 1), + kD2231_EVENT_D_GPIO1 = (1 << 0), +}; + +enum { + kD2231_EVENT_I_VDDREF_CHG_FALL = (1 << 5), + kD2231_EVENT_I_TMID_DIE_FALL = (1 << 4), + kD2231_EVENT_I_TLINCHG_FALL = (1 << 3), + kD2231_EVENT_I_TVCENTER2_FALL = (1 << 2), + kD2231_EVENT_I_TVCENTER1_FALL = (1 << 1), + kD2231_EVENT_I_TBUCK_FALL = (1 << 0), +}; + +enum { + kD2231_EVENT_J_VDDREF_CHG_RISE = (1 << 5), + kD2231_EVENT_J_TMID_DIE_RISE = (1 << 4), + kD2231_EVENT_J_TLINCHG_RISE = (1 << 3), + kD2231_EVENT_J_TVCENTER2_RISE = (1 << 2), + kD2231_EVENT_J_TVCENTER1_RISE = (1 << 1), + kD2231_EVENT_J_TBUCK_RISE = (1 << 0), +}; + +enum { + kD2231_EVENT_L_FAULTY_ADAPTER = (1 << 6), + kD2231_EVENT_L_IBUS_OVERFLOW = (1 << 5), + kD2231_EVENT_L_VBUS_OV = (1 << 4), + kD2231_EVENT_L_CVT_RESTART = (1 << 3), + kD2231_EVENT_L_CVT_INCORRECT_CFG = (1 << 2), + kD2231_EVENT_L_EOMC = (1 << 1), +}; + +enum { + kD2231_STATUS_A_TBAT = (1 << 7), + kD2231_STATUS_A_VDD_LOW = (1 << 5), + kD2231_STATUS_A_CHG_HV_ATT = (1 << 4), + kD2231_STATUS_A_VBUS_EXT_DET = (1 << 3), + kD2231_STATUS_A_HV_MODE = (1 << 2), + kD2231_STATUS_A_CHG_BUCK_ILIMITED = (1 << 1), + kD2231_STATUS_A_VCENTER_DET = (1 << 0), +}; + +enum { + kD2231_STATUS_C_CHG_SLOW = (1 << 7), + kD2231_STATUS_C_CHG_BUCK_FLG = (1 << 6), + kD2231_STATUS_C_CHG_ABCC_ACT = (1 << 5), + kD2231_STATUS_C_CHG_TIMEOUT = (1 << 4), + kD2231_STATUS_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2231_STATUS_C_CHG_END = (1 << 2), + kD2231_STATUS_C_CHG_FAST = (1 << 1), + kD2231_STATUS_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2231_STATUS_D_GPIO6 = (1 << 5), + kD2231_STATUS_D_GPIO5 = (1 << 4), + kD2231_STATUS_D_GPIO4 = (1 << 3), + kD2231_STATUS_D_GPIO3 = (1 << 2), + kD2231_STATUS_D_GPIO2 = (1 << 1), + kD2231_STATUS_D_GPIO1 = (1 << 0), +}; + + +enum { + kD2231_STATUS_I_VDDREF_CHG_FALL = (1 << 5), + kD2231_STATUS_I_TMID_DIE_FALL = (1 << 4), + kD2231_STATUS_I_TLINCHG_FALL = (1 << 3), + kD2231_STATUS_I_TVCENTER2_FALL = (1 << 2), + kD2231_STATUS_I_TVCENTER1_FALL = (1 << 1), + kD2231_STATUS_I_TBUCK_FALL = (1 << 0), +}; + +enum { + kD2231_STATUS_J_VDDREF_CHG_RISE = (1 << 5), + kD2231_STATUS_J_TMID_DIE_RISE = (1 << 4), + kD2231_STATUS_J_TLINCHG_RISE = (1 << 3), + kD2231_STATUS_J_TVCENTER2_RISE = (1 << 2), + kD2231_STATUS_J_TVCENTER1_RISE = (1 << 1), + kD2231_STATUS_J_TBUCK_RISE = (1 << 0), +}; + +enum { + kD2231_STATUS_L_FAULTY_ADAPTER = (1 << 6), + kD2231_STATUS_L_IBUS_OVERFLOW = (1 << 5), + kD2231_STATUS_L_VBUS_OV = (1 << 4), + kD2231_STATUS_L_CVT_INCORRECT_CFG = (1 << 2), +}; + +enum { + kD2231_STATUS_M_CHG_ATT = (1 << 0), +}; + +enum { + kD2231_CHG_CTRL_B_HV_CHG_ALLOW = ( 1<<1 ), + kD2231_CHG_CTRL_B_HV_CHG_ALLOW_MASK = ( 1<<1 ), +}; + + + +enum { + // N.B. as above, event register letters do not directly map to indexes + + kDIALOG_EVENT_HOLD_BUTTON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_MENU_BUTTON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_RINGER_BUTTON_MASK= kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_BUTTON4_MASK= kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_BUTTONS_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_ALARM_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD2231_EVENT_A_VBUS_EXT_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(0, kD2231_EVENT_A_VBUS_EXT_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(5, kD2231_EVENT_L_EOMC), + kDIALOG_EVENT_HIB_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(1, kD2231_EVENT_C_CHG_ABCC_ACT), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(2, kD2231_EVENT_C_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(0, kD2231_EVENT_A_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(2, kD2231_EVENT_D_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(2, kD2231_EVENT_D_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(2, kD2231_EVENT_D_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(2, kD2231_EVENT_D_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(2, kD2231_EVENT_D_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(2, kD2231_EVENT_D_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO8_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO9_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO10_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO11_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO12_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO13_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO14_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO15_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO16_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO17_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO19_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO20_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO21_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_HOLD_DBL_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_MENU_DBL_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_RINGER_DBL_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + // N.B. as above, status register letters do not directly map to indexes + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(0, kD2231_STATUS_A_VBUS_EXT_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD2231_STATUS_A_VCENTER_DET), + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(1, kD2231_STATUS_C_CHG_PRE | kD2231_STATUS_C_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(1, kD2231_STATUS_C_CHG_TIMEOUT), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(1, kD2231_STATUS_C_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(0, kD2231_STATUS_A_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(6, kD2231_STATUS_M_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(1, kD2231_STATUS_C_CHG_ABCC_ACT), +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(2 + (gpio)/8, (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {0, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, kD2231_STATUS_C_CHG_PRE | kD2231_STATUS_C_CHG_FAST, 0, 0, 0, 0}; + +enum { + kD2231_EVENT_A_WAKEMASK = (kD2231_EVENT_A_VBUS_EXT_DET | kD2231_EVENT_A_VBUS_EXT_REM | kD2231_EVENT_A_VCENTER_DET), + kD2231_EVENT_C_WAKEMASK = (kD2231_EVENT_C_CHG_TIMEOUT | kD2231_EVENT_C_CHG_PRECHG_TIMEOUT | kD2231_EVENT_C_CHG_END), + kD2231_EVENT_D_WAKEMASK = (kD2231_EVENT_D_GPIO6 | kD2231_EVENT_D_GPIO5 | kD2231_EVENT_D_GPIO4 | kD2231_EVENT_D_GPIO3 | kD2231_EVENT_D_GPIO2 | kD2231_EVENT_D_GPIO1), + kD2231_EVENT_I_WAKEMASK = 0, + kD2231_EVENT_J_WAKEMASK = 0, + kD2231_EVENT_L_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2231_EVENT_A_WAKEMASK, + ~kD2231_EVENT_C_WAKEMASK, + ~kD2231_EVENT_D_WAKEMASK, + ~kD2231_EVENT_I_WAKEMASK, + ~kD2231_EVENT_J_WAKEMASK, + ~kD2231_EVENT_L_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2231_EVENT_A_WAKEMASK, + kD2231_EVENT_C_WAKEMASK, + kD2231_EVENT_D_WAKEMASK, + kD2231_EVENT_I_WAKEMASK, + kD2231_EVENT_J_WAKEMASK, + kD2231_EVENT_L_WAKEMASK, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD2231_EVENT_A_VBUS_EXT_DET | kD2231_EVENT_A_VCENTER_DET, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { +// in d2231.h only include kD2231_EVENT_A_VBUS_EXT_DET: VCENTER can come and go while charger still usable + kD2231_EVENT_A_VBUS_EXT_DET, + kD2231_EVENT_C_CHG_ABCC_ACT, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + 0, + 0, + 0, + 0, + 0, + 0, +}; + +enum { + kDialogEventPwrsupplyCount = 2, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 0, +}; + +enum { + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 2), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = 0, +}; + +enum { + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + + kDIALOG_FAULT_LOG_WDOG = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_1 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x08, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x0a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x14, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x32, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x64, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0xc8, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100 = 0xd2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2560 = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 80, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 10, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 2550, +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3ff, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 5), + kDIALOG_CHARGE_CONTROL_CHG_HIB = 0, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 10, + kDIALOG_CHARGE_CONTROL_MAX = 6390, +}; + +enum { + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xFF, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x00, // TODO + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 6), +}; + +enum { + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 7), + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH_1A = (1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG = (4 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG, + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN_P = (5 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN_N = (6 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (7 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG = (8 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = (10 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VCENTER_TEMP1 = (13 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LINCHG_TEMP = (14 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_BUCK_TEMP = (15 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VCENTER_TEMP2 = (16 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_MID_DIE_TEMP = (17 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_LV_LDO_TEMP = (18 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_VCENTER_TEMP1, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_LV_LDO_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_ICH_6A = (29 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = kDIALOG_ADC_CONTROL_MUX_SEL_ICH_6A, + + kDIALOG_ADC_CONTROL2_AUTO_VDD_OUT_EN = (1 << 7), + kDIALOG_ADC_CONTROL2_ICH6A_EN = (1 << 1), + kDIALOG_ADC_CONTROL2_IBUS_EN = (1 << 0), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, + kDIALOG_ADC_CONTROL2_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 10, + kDIALOG_ADC_FULL_SCALE_MV = 1500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (1 << 6) | (1 << 1), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (1 << 6), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (0 << 6) | (0 << 1), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (0 << 6) | (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = kDIALOG_SYS_GPIO_DIRECTION_OUT, // not supported +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_OUT) == kDIALOG_SYS_GPIO_DIRECTION_OUT) + +#define NUM_LDOS 0 +static const struct ldo_params ldo_d2231[NUM_LDOS] = { +}; +#define LDOP ldo_d2231 + + +#endif /* __DIALOG_D2231_H */ diff --git a/drivers/dialog/pmu/d2238.h b/drivers/dialog/pmu/d2238.h new file mode 100644 index 0000000..86b32f7 --- /dev/null +++ b/drivers/dialog/pmu/d2238.h @@ -0,0 +1,1190 @@ +/* + * + * Tanzanite: Tanzanite Specification + * + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D2238_H +#define __DIALOG_D2238_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 0 +#define PMU_HAS_LCM_LDO 0 +#define PMU_HAS_BIST_ADC 0 +#define PMU_HAS_CHG_ABCC_FLAG 0 +#define PMU_HAS_VIB 0 +#define PMU_HAS_RAM 1 +#define PMU_HAS_WLED 0 +#define PMU_HAS_32K_RTC 1 +// TODO: #define PMU_HAS_ACCUMULATORS 1 +#define PMU_HAS_GPIO_CONF 1 +#define PMU_HAS_SYS 1 +#define PMU_HAS_WDT 0 +#define PMU_HAS_CHARGER 1 + +enum { + kDIALOG_ADDR_R = 0x79, + kDIALOG_ADDR_W = 0x78, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_EVENT_COUNT = 13, + kDIALOG_STATUS_COUNT = 13, + kDIALOG_FAULTLOG_COUNT = 2, + kDIALOG_CHIPID_COUNT = 10, + kDIALOG_GPIO_COUNT = 15, +}; + +#include "dCommon.h" + +enum { + kDIALOG_MASK_REV_CODE = 0x0000, + kDIALOG_TRIM_REL_CODE = 0x0001, + kDIALOG_PLATFORM_ID = 0x0002, + kDIALOG_DEVICE_ID1 = 0x0004, + kDIALOG_DEVICE_ID2 = 0x0005, + kDIALOG_DEVICE_ID3 = 0x0006, + kDIALOG_DEVICE_ID4 = 0x0007, + kDIALOG_DEVICE_ID5 = 0x0008, + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, + kDIALOG_DEVICE_ID6 = 0x0009, + kDIALOG_DEVICE_ID7 = 0x000A, + + kD2238_SYS_CTRL1 = 0x0010, + kD2238_SYS_CTRL2 = 0x0011, + kDIALOG_SYS_CONTROL = kD2238_SYS_CTRL1, + kDIALOG_SYS_CONTROL2 = kD2238_SYS_CTRL2, + + kD2238_SYS_CONF_A = 0x0020, + kDIALOG_SYS_CONFIG = kD2238_SYS_CONF_A, + kD2238_SYS_CONF_B = 0x0021, + kD2238_SYS_CONF_C = 0x0022, + kD2238_SYS_CONF_D = 0x0023, + kD2238_BG_TRIM = 0x0024, + kD2238_BG_TC_ADJ = 0x0025, + kD2238_VREF_RTC_TRIM = 0x0026, + kD2238_VREF_AUX_TRIM = 0x0027, + kD2238_VDD_FAULT = 0x0028, + kD2238_PRE_UVLO = 0x0029, + kD2238_VDD_MIN_BOOT = 0x002a, + + kD2238_RTC_CTRL0 = 0x002b, + kD2238_RTC_CTRL1 = 0x002c, + kD2238_OSC_CTRL0 = 0x002d, + kD2238_INT_OSC_TRIM = 0x002e, + kD2238_CLK_REQ_FRC = 0x002f, + kD2238_UOV_CONTROL = 0x0030, + kD2238_UOV_BLANK_CONTROL = 0x0031, + + kD2238_FAULT_LOG1 = 0x0040, + kD2238_FAULT_LOG2 = 0x0041, + kDIALOG_FAULT_LOG = kD2238_FAULT_LOG1, + kDIALOG_FAULT_LOG2 = kD2238_FAULT_LOG2, + + kD2238_BUCK_1_0_OUV = 0x0042, + kD2238_BUCK_3_2_OUV = 0x0043, + + kD2238_LDO_1_0_OUV = 0x0046, + kD2238_LDO_3_2_OUV = 0x0047, + kD2238_LDO_5_4_OUV = 0x0048, + kD2238_LDO_7_6_OUV = 0x0049, + kD2238_LDO_9_8_OUV = 0x004a, + + kDIALOG_EVENT_A = 0x0050, + kDIALOG_EVENT_B = 0x0051, + kDIALOG_EVENT_C = 0x0052, + kDIALOG_EVENT_D = 0x0053, + kDIALOG_EVENT_E = 0x0054, + kDIALOG_EVENT_F = 0x0055, + kDIALOG_EVENT_G = 0x0056, + kDIALOG_EVENT_H = 0x0057, + kDIALOG_EVENT_I = 0x0058, + kDIALOG_EVENT_J = 0x0059, + kDIALOG_EVENT_K = 0x005a, + kDIALOG_EVENT_L = 0x005b, + kDIALOG_EVENT_M = 0x005c, + + kDIALOG_STATUS_A = 0x0060, + kDIALOG_STATUS_B = 0x0061, + kDIALOG_STATUS_C = 0x0062, + kDIALOG_STATUS_D = 0x0063, + kDIALOG_STATUS_E = 0x0064, + kDIALOG_STATUS_F = 0x0065, + kDIALOG_STATUS_G = 0x0066, + kDIALOG_STATUS_H = 0x0067, + kDIALOG_STATUS_I = 0x0068, + kDIALOG_STATUS_J = 0x0069, + kDIALOG_STATUS_K = 0x006a, + kDIALOG_STATUS_L = 0x006b, + kDIALOG_STATUS_M = 0x006c, + + kDIALOG_IRQ_MASK_A = 0x0070, + kDIALOG_IRQ_MASK_B = 0x0071, + kDIALOG_IRQ_MASK_C = 0x0072, + kDIALOG_IRQ_MASK_D = 0x0073, + kDIALOG_IRQ_MASK_E = 0x0074, + kDIALOG_IRQ_MASK_F = 0x0075, + kDIALOG_IRQ_MASK_G = 0x0076, + kDIALOG_IRQ_MASK_H = 0x0077, + kDIALOG_IRQ_MASK_I = 0x0078, + kDIALOG_IRQ_MASK_J = 0x0079, + kDIALOG_IRQ_MASK_K = 0x007A, + kDIALOG_IRQ_MASK_L = 0x007B, + kDIALOG_IRQ_MASK_M = 0x007C, + + kD2238_ACTIVE1 = 0x0080, + kD2238_ACTIVE2 = 0x0081, + kD2238_ACTIVE3 = 0x0082, + kD2238_ACTIVE4 = 0x0083, + kD2238_ACTIVE5 = 0x0084, + kD2238_ACTIVE6 = 0x0085, + kD2238_ACTIVE7 = 0x0086, + kD2238_ACTIVE8 = 0x0087, + + kD2238_STANDBY1 = 0x0088, + kD2238_STANDBY3 = 0x008a, + kD2238_STANDBY4 = 0x008b, + kD2238_STANDBY6 = 0x008d, + kD2238_STANDBY7 = 0x008e, + kD2238_STANDBY8 = 0x008f, + + kD2238_HIBERNATE1 = 0x0090, + kD2238_HIBERNATE3 = 0x0092, + kD2238_HIBERNATE4 = 0x0093, + kD2238_HIBERNATE6 = 0x0095, + kD2238_HIBERNATE7 = 0x0096, + kD2238_HIBERNATE8 = 0x0097, + + kD2238_HALT1 = 0x0098, + kD2238_HALT3 = 0x009a, + kD2238_HALT4 = 0x009b, + kD2238_HALT6 = 0x009d, + kD2238_HALT7 = 0x009e, + kD2238_HALT8 = 0x009f, + + kD2238_SLOT_TIMINGS_PWR_UP1 = 0x00a0, + kD2238_SLOT_TIMINGS_PWR_UP2 = 0x00a1, + kD2238_SLOT_TIMINGS_PWR_UP3 = 0x00a2, + kD2238_SLOT_TIMINGS_PWR_UP4 = 0x00a3, + kD2238_SLOT_TIMINGS_PWR_UP5 = 0x00a4, + kD2238_SLOT_TIMINGS_PWR_UP6 = 0x00a5, + kD2238_SLOT_TIMINGS_PWR_UP7 = 0x00a6, + kD2238_SLOT_TIMINGS_PWR_UP8 = 0x00a7, + kD2238_SLOT_TIMINGS_PWR_DN1 = 0x00a8, + kD2238_SLOT_TIMINGS_PWR_DN2 = 0x00a9, + kD2238_SLOT_TIMINGS_PWR_DN3 = 0x00aa, + kD2238_SLOT_TIMINGS_PWR_DN4 = 0x00ab, + kD2238_SLOT_TIMINGS_PWR_DN5 = 0x00ac, + kD2238_SLOT_TIMINGS_PWR_DN6 = 0x00ad, + kD2238_SLOT_TIMINGS_PWR_DN7 = 0x00ae, + kD2238_SLOT_TIMINGS_PWR_DN8 = 0x00af, + kD2238_SLOT_TIMINGS_PWR_DN9 = 0x00b0, + kD2238_SLOT_TIMINGS_PWR_HALT_UP1 = 0x00c0, + kD2238_SLOT_TIMINGS_PWR_HALT_UP2 = 0x00c1, + kD2238_SLOT_TIMINGS_PWR_HALT_UP3 = 0x00c2, + kD2238_SLOT_TIMINGS_PWR_HALT_UP4 = 0x00c3, + kD2238_SLOT_TIMINGS_PWR_HALT_UP5 = 0x00c4, + kD2238_SLOT_TIMINGS_PWR_HALT_UP6 = 0x00c5, + kD2238_SLOT_TIMINGS_PWR_HALT_UP7 = 0x00c6, + kD2238_SLOT_TIMINGS_PWR_HALT_UP8 = 0x00c7, + + kD2238_ACT_TO_HIB_DLY = 0x00c8, + + kD2238_BUCK0_SLOT = 0x00d0, + kD2238_BUCK1_SLOT = 0x00d1, + kD2238_BUCK2_SLOT = 0x00d2, + kD2238_BUCK3_SLOT = 0x00d3, + + kD2238_LDO1_SLOT = 0x00d9, + kD2238_LDO2_SLOT = 0x00da, + kD2238_LDO3_SLOT = 0x00db, + kD2238_LDO4_SLOT = 0x00dc, + kD2238_LDO5_SLOT = 0x00dd, + kD2238_LDO6_SLOT = 0x00de, + kD2238_LDO7_SLOT = 0x00df, + kD2238_LDO8_SLOT = 0x00e0, + + kD2238_CHARGE_PUMP_SLOT = 0x00e8, + + kD2238_SW0_SLOT = 0x00e9, + kD2238_SW1_SLOT = 0x00ea, + kD2238_SW2_SLOT = 0x00eb, + kD2238_SW3A_SLOT = 0x00ec, + kD2238_SW3B_SLOT = 0x00ed, + kD2238_SW3C_SLOT = 0x00ee, + kD2238_SW4_SLOT = 0x00ef, + + kD2238_EXT0_SLOT = 0x00f8, + kD2238_EXT1_SLOT = 0x00f9, + kD2238_EXT2_SLOT = 0x00fa, + kD2238_EXT3_SLOT = 0x00fb, + + kD2238_BUCK0_VSEL = 0x0100, + kD2238_BUCK0_VSEL_ALT = 0x0101, + kD2238_BUCK0_VSEL_ACTUAL = 0x0102, + kD2238_BUCK0_MINV = 0x0103, + kD2238_BUCK0_MAXV = 0x0104, + kD2238_BUCK0_OFS_V = 0x0105, + kD2238_BUCK0_MODE = 0x0106, + kD2238_BUCK0_START_ILIMIT = 0x0107, + kD2238_BUCK0_SYNC_ILIMIT = 0x0108, + kD2238_BUCK0_SLEEP_ILIMIT = 0x0109, + + kD2238_BUCK0_FSM_TRIM0 = 0x010a, + kD2238_BUCK0_FSM_TRIM1 = 0x010b, + kD2238_BUCK0_FSM_TRIM2 = 0x010c, + kD2238_BUCK0_FSM_TRIM3 = 0x010d, + kD2238_BUCK0_CLK_TRIM4 = 0x010e, + kD2238_BUCK0_CLK_TRIM = 0x010f, + + kD2238_BUCK0_CALIB0 = 0x0111, + kD2238_BUCK0_CALIB1 = 0x0112, + + kD2238_BUCK0_ANA_TRIM0 = 0x0113, + kD2238_BUCK0_ANA_TRIM1 = 0x0114, + kD2238_BUCK0_ANA_TRIM2 = 0x0115, + kD2238_BUCK0_ANA_TRIM3 = 0x0116, + kD2238_BUCK0_ANA_TRIM4 = 0x0117, + kD2238_BUCK0_ANA_TRIM5 = 0x0118, + kD2238_BUCK0_ANA_TRIM6 = 0x0119, + kD2238_BUCK0_ANA_TRIM7 = 0x011a, + kD2238_BUCK0_ANA_TRIM8 = 0x011b, + kD2238_BUCK0_ANA_TRIM9 = 0x011c, + + kD2238_BUCK1_VSEL = 0x0120, + kD2238_BUCK1_VSEL_ACTUAL = 0x0122, + kD2238_BUCK1_MINV = 0x0123, + kD2238_BUCK1_MAXV = 0x0124, + kD2238_BUCK1_OFS_V = 0x0125, + kD2238_BUCK1_MODE = 0x0126, + kD2238_BUCK1_START_ILIMIT = 0x0127, + kD2238_BUCK1_SYNC_ILIMIT = 0x0128, + kD2238_BUCK1_SLEEP_ILIMIT = 0x0129, + kD2238_BUCK1_FSM_TRIM0 = 0x012a, + kD2238_BUCK1_FSM_TRIM1 = 0x012b, + kD2238_BUCK1_FSM_TRIM2 = 0x012c, + kD2238_BUCK1_FSM_TRIM3 = 0x012d, + kD2238_BUCK1_CLK_TRIM4 = 0x012e, + kD2238_BUCK1_CLK_TRIM = 0x012f, + + kD2238_BUCK1_CALIB0 = 0x0131, + + kD2238_BUCK1_ANA_TRIM0 = 0x0133, + kD2238_BUCK1_ANA_TRIM1 = 0x0134, + kD2238_BUCK1_ANA_TRIM2 = 0x0135, + kD2238_BUCK1_ANA_TRIM3 = 0x0136, + kD2238_BUCK1_ANA_TRIM4 = 0x0137, + kD2238_BUCK1_ANA_TRIM5 = 0x0138, + kD2238_BUCK1_ANA_TRIM6 = 0x0139, + kD2238_BUCK1_ANA_TRIM7 = 0x013a, + kD2238_BUCK1_ANA_TRIM8 = 0x013b, + kD2238_BUCK1_ANA_TRIM9 = 0x013c, + + kD2238_BUCK2_VSEL = 0x0140, + kD2238_BUCK2_VSEL_HIB = 0x0141, + kD2238_BUCK2_VSEL_HALT = 0x0142, + kD2238_BUCK2_VSEL_ACTUAL = 0x0143, + kD2238_BUCK2_MINV = 0x0144, + kD2238_BUCK2_MAXV = 0x0145, + kD2238_BUCK2_OFS_V = 0x0146, + kD2238_BUCK2_MODE = 0x0147, + kD2238_BUCK2_START_ILIMIT = 0x0148, + kD2238_BUCK2_SYNC_ILIMIT = 0x0149, + kD2238_BUCK2_SLEEP_ILIMIT = 0x014a, + kD2238_BUCK2_FSM_TRIM0 = 0x014b, + kD2238_BUCK2_FSM_TRIM1 = 0x014c, + kD2238_BUCK2_FSM_TRIM2 = 0x014d, + kD2238_BUCK2_FSM_TRIM3 = 0x014e, + kD2238_BUCK2_CLK_TRIM4 = 0x014f, + kD2238_BUCK2_CLK_TRIM = 0x0150, + + kD2238_BUCK2_CALIB_OFFSET_TRIM = 0x0151, + kD2238_BUCK2_CALIB0 = 0x0152, + kD2238_BUCK2_ANA_TRIM0 = 0x0154, + kD2238_BUCK2_ANA_TRIM1 = 0x0155, + kD2238_BUCK2_ANA_TRIM2 = 0x0156, + kD2238_BUCK2_ANA_TRIM3 = 0x0157, + kD2238_BUCK2_ANA_TRIM4 = 0x0158, + kD2238_BUCK2_ANA_TRIM5 = 0x0159, + kD2238_BUCK2_ANA_TRIM6 = 0x015a, + kD2238_BUCK2_ANA_TRIM7 = 0x015b, + kD2238_BUCK2_ANA_TRIM8 = 0x015c, + kD2238_BUCK2_ANA_TRIM9 = 0x015d, + + kD2238_BUCK3_VSEL = 0x0160, + kD2238_BUCK3_VSEL_HIB = 0x0161, + kD2238_BUCK3_VSEL_HALT = 0x0162, + kD2238_BUCK3_VSEL_ACTUAL = 0x0163, + kD2238_BUCK3_MINV = 0x0164, + kD2238_BUCK3_MAXV = 0x0165, + kD2238_BUCK3_OFS_V = 0x0166, + kD2238_BUCK3_MODE = 0x0167, + kD2238_BUCK3_START_ILIMIT = 0x0168, + kD2238_BUCK3_SYNC_ILIMIT = 0x0169, + kD2238_BUCK3_SLEEP_ILIMIT = 0x016a, + kD2238_BUCK3_FSM_TRIM0 = 0x016b, + kD2238_BUCK3_FSM_TRIM1 = 0x016c, + kD2238_BUCK3_FSM_TRIM2 = 0x016d, + kD2238_BUCK3_FSM_TRIM3 = 0x016e, + kD2238_BUCK3_CLK_TRIM = 0x016f, + + kD2238_BUCK3_CALIB_OFFSET_TRIM = 0x0171, + + kD2238_BUCK3_CALIB0 = 0x0172, + kD2238_BUCK3_ANA_TRIM0 = 0x0174, + kD2238_BUCK3_ANA_TRIM1 = 0x0175, + kD2238_BUCK3_ANA_TRIM2 = 0x0176, + kD2238_BUCK3_ANA_TRIM3 = 0x0177, + kD2238_BUCK3_ANA_TRIM4 = 0x0178, + kD2238_BUCK3_ANA_TRIM5 = 0x0179, + kD2238_BUCK3_ANA_TRIM6 = 0x017a, + kD2238_BUCK3_ANA_TRIM7 = 0x017b, + kD2238_BUCK3_ANA_TRIM8 = 0x017c, + kD2238_BUCK3_ANA_TRIM9 = 0x017d, + + kD2238_LDO_RTC_TRIM = 0x0304, + kD2238_LDO_SOFT_START = 0x0307, + + kD2238_LDO1_VSEL = 0x0308, + kD2238_LDO1_VSEL_ACTUAL = 0x0309, + kD2238_LDO1_MINV = 0x030a, + kD2238_LDO1_MAXV = 0x030b, + + kD2238_LDO2_VSEL = 0x0310, + kD2238_LDO2_VSEL_ACTUAL = 0x0311, + kD2238_LDO2_MINV = 0x0312, + kD2238_LDO2_MAXV = 0x0313, + + kD2238_LDO3_VSEL = 0x0318, + kD2238_LDO3_VSEL_ACTUAL = 0x0319, + kD2238_LDO3_MINV = 0x031a, + kD2238_LDO3_MAXV = 0x031b, + + kD2238_LDO4_VSEL = 0x0320, + kD2238_LDO4_VSEL_ACTUAL = 0x0321, + kD2238_LDO4_MINV = 0x0322, + kD2238_LDO4_MAXV = 0x0323, + kD2238_LDO4_UOV_LIM = 0x0324, + kD2238_LDO4_SOFT_START = 0x0325, + + kD2238_LDO5_VSEL = 0x0328, + kD2238_LDO5_VSEL_ACTUAL = 0x0329, + kD2238_LDO5_MINV = 0x032a, + kD2238_LDO5_MAXV = 0x032b, + + kD2238_LDO6_VSEL = 0x0330, + kD2238_LDO6_VSEL_ACTUAL = 0x0331, + kD2238_LDO6_MINV = 0x0332, + kD2238_LDO6_MAXV = 0x0333, + + kD2238_LDO7_VSEL = 0x0338, + kD2238_LDO7_VSEL_ACTUAL = 0x0339, + kD2238_LDO7_MINV = 0x033a, + kD2238_LDO7_MAXV = 0x033b, + + kD2238_LDO8_VSEL = 0x0340, + kD2238_LDO8_VSEL_ACTUAL = 0x0341, + kD2238_LDO8_MINV = 0x0342, + kD2238_LDO8_MAXV = 0x0343, + + kD2238_LDO9_VSEL = 0x0348, + kD2238_LDO9_VSEL_ACTUAL = 0x0349, + kD2238_LDO9_MINV = 0x034a, + kD2238_LDO9_MAXV = 0x034b, + kD2238_LDO9_TRIM = 0x034c, + + kD2238_HIB_SW_CTRL = 0x03c0, + + kD2238_GPIO1_CONF1 = 0x0400, + kD2238_GPIO1_CONF2 = 0x0401, + kD2238_GPIO2_CONF1 = 0x0402, + kD2238_GPIO2_CONF2 = 0x0403, + kD2238_GPIO3_CONF1 = 0x0404, + kD2238_GPIO3_CONF2 = 0x0405, + kD2238_GPIO4_CONF1 = 0x0406, + kD2238_GPIO4_CONF2 = 0x0407, + kD2238_GPIO5_CONF1 = 0x0408, + kD2238_GPIO5_CONF2 = 0x0409, + kD2238_GPIO6_CONF1 = 0x040a, + kD2238_GPIO6_CONF2 = 0x040b, + kD2238_GPIO7_CONF1 = 0x040c, + kD2238_GPIO7_CONF2 = 0x040d, + kD2238_GPIO8_CONF1 = 0x040e, + kD2238_GPIO8_CONF2 = 0x040f, + kD2238_GPIO9_CONF1 = 0x0410, + kD2238_GPIO9_CONF2 = 0x0411, + kD2238_GPIO10_CONF1 = 0x0412, + kD2238_GPIO10_CONF2 = 0x0413, + kD2238_GPIO11_CONF1 = 0x0414, + kD2238_GPIO11_CONF2 = 0x0415, + kD2238_GPIO12_CONF1 = 0x0416, + kD2238_GPIO12_CONF2 = 0x0417, + kD2238_GPIO13_CONF1 = 0x0418, + kD2238_GPIO13_CONF2 = 0x0419, + kD2238_GPIO14_CONF1 = 0x041a, + kD2238_GPIO14_CONF2 = 0x041b, + kD2238_GPIO15_CONF1 = 0x041c, + kD2238_GPIO15_CONF2 = 0x041d, + kDIALOG_SYS_GPIO_REG_START = kD2238_GPIO1_CONF1, + + kD2238_OUT_32K = 0x0430, + + kD2238_BUTTON1_CONF = 0x0440, + kD2238_BUTTON2_CONF = 0x0441, + kD2238_BUTTON3_CONF = 0x0442, + kDIALOG_BUTTON_DBL = 0x0443, + kD2238_BUTTON_WAKE = 0x0444, + + kD2238_RESET_IN1_CONF = 0x0448, + kD2238_RESET_IN2_CONF = 0x0449, + + kD2238_ALL_RAILS_CONF = 0x044a, + kD2238_CORE_HI_CONF = 0x044b, + kD2238_VBUS_DET_CONF = 0x044c, + + kD2238_NRST_CONF = 0x0460, + kD2238_NRST_ADJ = 0x0461, + kD2238_NIRQ_CONF = 0x0462, + kD2238_SYS_ALIVE_CONF = 0x0463, + kD2238_PWR_GOOD_CONF = 0x0464, + kD2238_PWR_GOOD_ADJ = 0x0465, + kD2238_VDD_OK_CONF = 0x0466, + + kD2238_TDEV1_RISE = 0x0480, + kD2238_TDEV1_FALL = 0x0481, + kD2238_TDEV2_RISE = 0x0482, + kD2238_TDEV2_FALL = 0x0483, + kD2238_TDEV3_RISE = 0x0484, + kD2238_TDEV3_FALL = 0x0485, + kD2238_TDEV4_RISE = 0x0486, + kD2238_TDEV4_FALL = 0x0487, + + kD2238_TLDO4_RISE = 0x04a0, + kD2238_TCHARGER_RISE = 0x04a1, + kD2238_TBUCK0_RISE = 0x04a2, + kD2238_TBUCK1_RISE = 0x04a3, + kD2238_TBUCK2_RISE = 0x04a4, + kD2238_TBUCK3_RISE = 0x04a5, + kD2238_TISENSE_HYST = 0x04a6, + + kDIALOG_T_OFFSET_MSB = 0x04a7, + kDIALOG_T_OFFSET_LSB = 0x04a8, + + kD2238_CHG_CTRL_A = 0x04c0, + kD2238_CHG_CTRL_B = 0x04c1, + kD2238_CHG_CTRL_C = 0x04c2, + kD2238_CHG_CTRL_D = 0x04c3, + kD2238_CHG_CTRL_E = 0x04c4, + kD2238_CHG_CTRL_F = 0x04c5, + kD2238_CHG_TIME = 0x04c6, + kD2238_CHG_TIME_PRE = 0x04c7, + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD2238_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_TIME = kD2238_CHG_CTRL_D, + kDIALOG_CHARGE_CONTROL_VSET = kD2238_CHG_CTRL_E, + kDIALOG_OTP_ISET_BAT = kD2238_CHG_CTRL_C, + + kD2238_CHG_STAT = 0x04c8, + kDIALOG_CHARGE_STATUS = kD2238_CHG_STAT, + + kD2238_CHG_VSET_TRIM = 0x04c9, + kD2238_CHG_TRIM1 = 0x04ca, + kD2238_CHG_TRIM2 = 0x04cb, + kD2238_CHG_TRIM3 = 0x04cc, + kD2238_ICHG_END = 0x04cd, + + kDIALOG_TBAT_0 = 0x04ce, + kDIALOG_TBAT_1 = 0x04cf, + kDIALOG_TBAT_2 = 0x04d0, + kDIALOG_TBAT_3 = 0x04d1, + kDIALOG_TBAT_4 = 0x04d2, + kDIALOG_TBAT_MAX = 0x04d3, + kDIALOG_ICHG_TBAT_0 = 0x04d4, + kDIALOG_ICHG_TBAT_1 = 0x04d5, + kDIALOG_ICHG_TBAT_2 = 0x04d6, + kDIALOG_ICHG_TBAT_3 = 0x04d7, + kDIALOG_ICHG_TBAT_4 = 0x04d8, + kD2238_ICHG_TBAT = 0x04d9, + + kDIALOG_ICHG_AVG = 0x04da, + + kD2238_HR_RES = 0x04db, + kD2238_HR_LOW_TH = 0x04dc, + kD2238_HR_LOOPUP_V1 = 0x04dd, + kD2238_HR_LOOPUP_I1 = 0x04de, + kD2238_HR_LOOPUP_V2 = 0x04df, + kD2238_HR_LOOPUP_I2 = 0x04e0, + kD2238_HR_LOOPUP_V3 = 0x04e1, + kD2238_HR_LOOPUP_I3 = 0x04e2, + kD2238_HR_LOOPUP_V4 = 0x04e3, + kD2238_HR_LOOPUP_I4 = 0x04e4, + kD2238_HR_LOOPUP_V5 = 0x04e5, + kD2238_HR_LOOPUP_I5 = 0x04e6, + kD2238_HR_LOOPUP_V6 = 0x04e7, + kD2238_HR_LOOPUP_I6 = 0x04e8, + kD2238_HR_LOOPUP_V7 = 0x04e9, + kD2238_HR_LOOPUP_I7 = 0x04ea, + kD2238_HR_LOOPUP_V8 = 0x04eb, + kD2238_HR_LOOPUP_I8 = 0x04ec, + kD2238_HR_LOOPUP_V9 = 0x04ed, + kD2238_HR_LOOPUP_I9 = 0x04ee, + kD2238_HR_LOOPUP_I10 = 0x04ef, + kD2238_HR_LOOPUP_HR = 0x04f0, + + kD2238_ADC_CTRL1 = 0x0500, + kD2238_ADC_CTRL2 = 0x0501, + kDIALOG_ADC_CONTROL = kD2238_ADC_CTRL1, + kDIALOG_ADC_CONTROL2 = kD2238_ADC_CTRL2, + kDIALOG_ADC_LSB = 0x0502, + kDIALOG_ADC_MSB = 0x0503, + kD2238_ADC_TEMP_CTRL0 = 0x0504, + kD2238_ADC_TEMP_CTRL1 = 0x0505, + kD2238_ADC_HR_CTRL = 0x0506, + kD2238_ADC_FSM_TRIM0 = 0x0507, + kD2238_ADC_FSM_TRIM1 = 0x0508, + kD2238_ADC_FSM_TRIM2 = 0x0509, + kD2238_ADC_ANA_TRIM0 = 0x050a, + kD2238_BIST_ADC_ANA_TRIM0 = 0x050b, + kD2238_VDD_MAIN_MON = 0x050c, + + kD2238_IBUCK0_ACCUM1 = 0x0514, + kD2238_IBUCK0_ACCUM2 = 0x0515, + kD2238_IBUCK0_ACCUM3 = 0x0516, + kD2238_IBUCK0_COUNT1 = 0x0517, + kD2238_IBUCK0_COUNT2 = 0x0518, + kD2238_IBUCK1_ACCUM1 = 0x0519, + kD2238_IBUCK1_ACCUM2 = 0x051a, + kD2238_IBUCK1_ACCUM3 = 0x051b, + kD2238_IBUCK1_COUNT1 = 0x051c, + kD2238_IBUCK1_COUNT2 = 0x051d, + kD2238_IBUCK2_ACCUM1 = 0x051e, + kD2238_IBUCK2_ACCUM2 = 0x052f, + kD2238_IBUCK2_ACCUM3 = 0x0520, + kD2238_IBUCK2_COUNT1 = 0x0521, + kD2238_IBUCK2_COUNT2 = 0x0522, + + kDIALOG_APP_TMUX = 0x0540, + + kDIALOG_RTC_ALARM_A = 0x05c0, + kDIALOG_RTC_ALARM_B = 0x05c1, + kDIALOG_RTC_ALARM_C = 0x05c2, + kDIALOG_RTC_ALARM_D = 0x05c3, + kDIALOG_RTC_CONTROL = 0x05c4, + kDIALOG_RTC_TIMEZONE = 0x05c5, + kDIALOG_RTC_SUB_SECOND_A = 0x05c6, + kDIALOG_RTC_SUB_SECOND_B = 0x05c7, + kDIALOG_RTC_SECOND_A = 0x05c8, + kDIALOG_RTC_SECOND_B = 0x05c9, + kDIALOG_RTC_SECOND_C = 0x05ca, + kDIALOG_RTC_SECOND_D = 0x05cb, + + kD2238_SPARE_RW0 = 0x0680, + kD2238_SPARE_RW_LAST = 0x0687, + kD2238_SPARE_RWTOTP0 = 0x06a0, + kD2238_SPARE_RWTOTP_LAST = 0x06a7, + kD2238_SPARE_RWOTP0 = 0x06c0, + kD2238_SPARE_RWOTP1 = 0x06c1, + + kDIALOG_MEMBYTE0 = 0x4000, + kDIALOG_MEMBYTE_LAST = 0x4027, + + kDIALOG_TEST_ACCESS = 0x7000, + kDIALOG_TEST_ACCESS_ENA = 0x1D, + kDIALOG_TEST_ACCESS_DIS = 0x00, + + kDIALOG_RAM0 = 0x8000, + kDIALOG_DIAG_SCRATCH = kDIALOG_RAM0 + 64, // keep offset the same as Adi + kDIALOG_DIAG_SCRATCH_SIZE = 8, + kDIALOG_VOLTAGE_KNOBS = kDIALOG_DIAG_SCRATCH+kDIALOG_DIAG_SCRATCH_SIZE, + kDIALOG_VOLTAGE_KNOBS_SIZE=32, + + kDIALOG_RAM_LAST = 0x80ff, +}; + +// Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 3, + kDIALOG_IBUCK0_ACCUMULATOR = 0, + kDIALOG_IBUCK1_ACCUMULATOR = 1, + kDIALOG_IBUCK2_ACCUMULATOR = 2, +}; + +enum { + kD2238_EVENT_A_TBAT = (1 << 7), + kD2238_EVENT_A_VBUS_DET_REM = (1 << 6), + kD2238_EVENT_A_VDD_LOW = (1 << 5), + kD2238_EVENT_A_VBUS_DET = (1 << 3), + kD2238_EVENT_A_ACC_DET = (1 << 2), +}; + +enum { + kD2238_EVENT_B_BTN3_DBL = (1 << 6), + kD2238_EVENT_B_BTN2_DBL = (1 << 5), + kD2238_EVENT_B_BTN1_DBL = (1 << 4), + kD2238_EVENT_B_BUTTON_3 = (1 << 2), + kD2238_EVENT_B_BUTTON_2 = (1 << 1), + kD2238_EVENT_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2238_EVENT_C_CHG_HR_OVER = (1 << 7), + kD2238_EVENT_C_CHG_HR_UNDER = (1 << 6), + kD2238_EVENT_C_CHG_TIMEOUT = (1 << 4), + kD2238_EVENT_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2238_EVENT_C_CHG_END = (1 << 2), + kD2238_EVENT_C_CHG_FAST = (1 << 1), + kD2238_EVENT_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2238_EVENT_D_GPIO8 = (1 << 7), + kD2238_EVENT_D_GPIO7 = (1 << 6), + kD2238_EVENT_D_GPIO6 = (1 << 5), + kD2238_EVENT_D_GPIO5 = (1 << 4), + kD2238_EVENT_D_GPIO4 = (1 << 3), + kD2238_EVENT_D_GPIO3 = (1 << 2), + kD2238_EVENT_D_GPIO2 = (1 << 1), + kD2238_EVENT_D_GPIO1 = (1 << 0), +}; + +enum { + kD2238_EVENT_E_GPIO15 = (1 << 6), + kD2238_EVENT_E_GPIO14 = (1 << 5), + kD2238_EVENT_E_GPIO13 = (1 << 4), + kD2238_EVENT_E_GPIO12 = (1 << 3), + kD2238_EVENT_E_GPIO11 = (1 << 2), + kD2238_EVENT_E_GPIO10 = (1 << 1), + kD2238_EVENT_E_GPIO9 = (1 << 0), +}; + + // EVENT_F has no events + +enum { + kD2238_EVENT_G_T4_RISE = (1 << 7), + kD2238_EVENT_G_T4_FALL = (1 << 6), + kD2238_EVENT_G_T3_RISE = (1 << 5), + kD2238_EVENT_G_T3_FALL = (1 << 4), + kD2238_EVENT_G_T2_RISE = (1 << 3), + kD2238_EVENT_G_T2_FALL = (1 << 2), + kD2238_EVENT_G_T1_RISE = (1 << 1), + kD2238_EVENT_G_T1_FALL = (1 << 0), +}; + + // EVENT_H has no events + +enum { + kD2238_EVENT_I_TBUCK3 = (1 << 7), + kD2238_EVENT_I_TBUCK2 = (1 << 6), + kD2238_EVENT_I_TBUCK1 = (1 << 5), + kD2238_EVENT_I_TBUCK0 = (1 << 4), + kD2238_EVENT_I_TCHARGER = (1 << 3), + kD2238_EVENT_I_TLDO4 = (1 << 0), +}; + +enum { + kD2238_EVENT_J_HIGH_TEMP_WARNING = (1 << 7), + kD2238_EVENT_J_BUCK_LDO_UOV = (1 << 6), + kD2238_EVENT_J_IBUCK2_OVERFLOW = (1 << 2), + kD2238_EVENT_J_IBUCK1_OVERFLOW = (1 << 1), + kD2238_EVENT_J_IBUCK0_OVERFLOW = (1 << 0), +}; + + // EVENT_K has no events + +// EVENT_L events are stored by LLB across sleep/wake +enum { + kD2238_EVENT_L_CLK32K_ERROR = (1 << 5), + kD2238_EVENT_L_HIB = (1 << 4), + kD2238_EVENT_L_EOMC = (1 << 1), + kD2238_EVENT_L_ALARM = (1 << 0), +}; + + // EVENT_M has no events + +enum { + kD2238_STATUS_A_TBAT = (1 << 7), + kD2238_STATUS_A_VDD_LOW = (1 << 5), + kD2238_STATUS_A_VBUS_DET = (1 << 3), +}; + +enum { + kD2238_STATUS_B_BUTTON_3 = (1 << 2), + kD2238_STATUS_B_BUTTON_2 = (1 << 1), + kD2238_STATUS_B_BUTTON_1 = (1 << 0), +}; + +enum { + kD2238_STATUS_C_CHG_HR_OVER = (1 << 7), + kD2238_STATUS_C_CHG_HR_UNDER = (1 << 6), + kD2238_STATUS_C_CHG_TIMEOUT = (1 << 4), + kD2238_STATUS_C_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2238_STATUS_C_CHG_END = (1 << 2), + kD2238_STATUS_C_CHG_FAST = (1 << 1), + kD2238_STATUS_C_CHG_PRE = (1 << 0), +}; + +enum { + kD2238_STATUS_D_GPIO8 = (1 << 7), + kD2238_STATUS_D_GPIO7 = (1 << 6), + kD2238_STATUS_D_GPIO6 = (1 << 5), + kD2238_STATUS_D_GPIO5 = (1 << 4), + kD2238_STATUS_D_GPIO4 = (1 << 3), + kD2238_STATUS_D_GPIO3 = (1 << 2), + kD2238_STATUS_D_GPIO2 = (1 << 1), + kD2238_STATUS_D_GPIO1 = (1 << 0), +}; + +enum { + kD2238_STATUS_E_GPIO15 = (1 << 6), + kD2238_STATUS_E_GPIO14 = (1 << 5), + kD2238_STATUS_E_GPIO13 = (1 << 4), + kD2238_STATUS_E_GPIO12 = (1 << 3), + kD2238_STATUS_E_GPIO11 = (1 << 2), + kD2238_STATUS_E_GPIO10 = (1 << 1), + kD2238_STATUS_E_GPIO9 = (1 << 0), +}; + + // STATUS_F has no bits + +enum { + kD2238_STATUS_G_T4_RISE = (1 << 7), + kD2238_STATUS_G_T4_FALL = (1 << 6), + kD2238_STATUS_G_T3_RISE = (1 << 5), + kD2238_STATUS_G_T3_FALL = (1 << 4), + kD2238_STATUS_G_T2_RISE = (1 << 3), + kD2238_STATUS_G_T2_FALL = (1 << 2), + kD2238_STATUS_G_T1_RISE = (1 << 1), + kD2238_STATUS_G_T1_FALL = (1 << 0), +}; + + // STATUS_H has no bits + +enum { + kD2238_STATUS_I_TBUCK3 = (1 << 7), + kD2238_STATUS_I_TBUCK2 = (1 << 6), + kD2238_STATUS_I_TBUCK1 = (1 << 5), + kD2238_STATUS_I_TBUCK0 = (1 << 4), + kD2238_STATUS_I_TCHARGER = (1 << 3), + kD2238_STATUS_I_TLDO4 = (1 << 0), +}; + +enum { + kD2238_STATUS_J_HIGH_TEMP_WARNING = (1 << 7), + kD2238_STATUS_J_BUCK_LDO_UOV = (1 << 6), + kD2238_STATUS_J_IBUCK2_OVERFLOW = (1 << 2), + kD2238_STATUS_J_IBUCK1_OVERFLOW = (1 << 1), + kD2238_STATUS_J_IBUCK0_OVERFLOW = (1 << 0), +}; + + // STATUS_K has no bits + +enum { + kD2238_STATUS_L_CLK32K_ERROR = (1 << 5), +}; + + // STATUS_M has no bits + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2238_EVENT_B_BUTTON_1), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(1, kD2238_EVENT_B_BUTTON_2), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(1, kD2238_EVENT_B_BUTTON_3), + + kDIALOG_EVENT_BUTTON4_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_BUTTONS = (kD2238_EVENT_B_BUTTON_3 | + kD2238_EVENT_B_BUTTON_2 | + kD2238_EVENT_B_BUTTON_1), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(1, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(11, kD2238_EVENT_L_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(0, kD2238_EVENT_A_VBUS_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(0, kD2238_EVENT_A_VBUS_DET_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(11, kD2238_EVENT_L_EOMC), + kDIALOG_EVENT_HIB_MASK = EVENT_FLAG_MAKE(11, kD2238_EVENT_L_HIB), + kDIALOG_EVENT_ABCC_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(2, kD2238_EVENT_C_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(0, kD2238_EVENT_A_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(3, kD2238_EVENT_D_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(4, kD2238_EVENT_E_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(4, kD2238_EVENT_E_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(4, kD2238_EVENT_E_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(4, kD2238_EVENT_E_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(4, kD2238_EVENT_E_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(4, kD2238_EVENT_E_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(4, kD2238_EVENT_E_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO17_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO19_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO20_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO21_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(1, kD2238_EVENT_B_BTN2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(1, kD2238_EVENT_B_BTN1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(1, kD2238_EVENT_B_BTN3_DBL), + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(0, kD2238_STATUS_A_VBUS_DET), + kDIALOG_STATUS_USB_MASK = kDIALOG_STATUS_VBUS_MASK, + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(3, kD2238_STATUS_C_CHG_PRE | kD2238_STATUS_C_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(2, kD2238_STATUS_C_CHG_TIMEOUT), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(2, kD2238_STATUS_C_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(0, kD2238_STATUS_A_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ABCC_MASK = kDIALOG_NOTEXIST_MASK, +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(3 + ((gpio)/8), (1 << ((gpio) % 8))) +}; + +static const statusRegisters kDialogStatusFWMask = {0, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, 0, kD2238_STATUS_C_CHG_PRE | kD2238_STATUS_C_CHG_FAST }; + +enum { + kD2238_EVENT_A_WAKEMASK = kD2238_EVENT_A_VBUS_DET, + kD2238_EVENT_B_WAKEMASK = (kD2238_EVENT_B_BUTTON_1 | + kD2238_EVENT_B_BUTTON_2 | + kD2238_EVENT_B_BUTTON_3), + kD2238_EVENT_C_WAKEMASK = 0, + kD2238_EVENT_D_WAKEMASK = 0, + kD2238_EVENT_E_WAKEMASK = 0, + kD2238_EVENT_F_WAKEMASK = 0, + kD2238_EVENT_G_WAKEMASK = 0, + kD2238_EVENT_H_WAKEMASK = 0, + kD2238_EVENT_I_WAKEMASK = 0, + kD2238_EVENT_J_WAKEMASK = 0, + kD2238_EVENT_K_WAKEMASK = 0, + kD2238_EVENT_L_WAKEMASK = kD2238_EVENT_L_ALARM, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2238_EVENT_A_WAKEMASK, + ~kD2238_EVENT_B_WAKEMASK, + ~kD2238_EVENT_C_WAKEMASK, + ~kD2238_EVENT_D_WAKEMASK, + ~kD2238_EVENT_E_WAKEMASK, + ~kD2238_EVENT_F_WAKEMASK, + ~kD2238_EVENT_G_WAKEMASK, + ~kD2238_EVENT_H_WAKEMASK, + ~kD2238_EVENT_I_WAKEMASK, + ~kD2238_EVENT_J_WAKEMASK, + ~kD2238_EVENT_K_WAKEMASK, + ~kD2238_EVENT_L_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2238_EVENT_A_WAKEMASK, + kD2238_EVENT_B_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD2238_EVENT_C_WAKEMASK, + kD2238_EVENT_D_WAKEMASK, + kD2238_EVENT_E_WAKEMASK, + kD2238_EVENT_F_WAKEMASK, + kD2238_EVENT_G_WAKEMASK, + kD2238_EVENT_H_WAKEMASK, + kD2238_EVENT_I_WAKEMASK, + kD2238_EVENT_J_WAKEMASK, + kD2238_EVENT_K_WAKEMASK, + kD2238_EVENT_L_WAKEMASK, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + kD2238_EVENT_A_VBUS_DET | kD2238_EVENT_A_VBUS_DET_REM, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + kD2238_EVENT_A_VBUS_DET | kD2238_EVENT_A_VBUS_DET_REM, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +enum { + kDIALOG_SYS_CONTROL_STANDBY = (1 << 0), + kDIALOG_SYS_CONTROL_HIBERNATE = (1 << 1), +// kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = 0, + kDIALOG_SYS_CONTROL_HIB_CLK = (1 << 4), + kDIALOG_SYS_CONTROL_PROT_FET_DIS = 0, +// kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = 0, +// kDIALOG_SYS_CONTROL_CHRG_CONTROLS = 0, + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, +}; + +enum { + kDIALOG_SYS_CONTROL2_HIB_32K = 0, +}; + +enum { + // FAULT_LOG1 + kDIALOG_FAULT_LOG_WDOG = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_2 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + // FAULT_LOG2 + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = FAULTLOG_FLAG_MAKE(1, (1 << 2)), + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = FAULTLOG_FLAG_MAKE(1, (1 << 1)), + kDIALOG_FAULT_LOG_NTC_SHDN = FAULTLOG_FLAG_MAKE(1, (1 << 0)), +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x7f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, +// kDIALOG_OTP_ISET_BAT_SHIFT = -1, // OTP is missing the LSB + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = 0, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 3, + kDIALOG_CHARGE_CONTROL_MAX = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK * kDIALOG_CHARGE_CONTROL_STEP, +}; + +enum { + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = 0, + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = 0, +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xFF, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x00, // TODO + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +enum { + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 6), +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x7f << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = (0 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = (1 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = (2 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = (3 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = (4 << 0), + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_LDO4_TEMP = (9 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK0_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK1_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK2_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kDIALOG_ADC_CONTROL_MUX_SEL_LDO4_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kDIALOG_ADC_CONTROL_MUX_SEL_BUCK3_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO1 = (15 << 0), + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO1, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO2, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO2, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO3, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO3, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO4, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO4, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO5, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO5, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO6, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO6, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO7, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO7, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO8, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO8, + kDIALOG_ADC_CONTROL_MUX_SEL_VLDO9, + kDIALOG_ADC_CONTROL_MUX_SEL_ILDO9, + kDIALOG_ADC_CONTROL_MUX_SEL_VRTC, + kDIALOG_ADC_CONTROL_MUX_SEL_IRTC, + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_HR, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUCK0, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUCK1, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUCK2, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUCK3, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK0, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK1, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK2, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK3, + kDIALOG_ADC_CONTROL_MUX_SEL_VSW0, + kDIALOG_ADC_CONTROL_MUX_SEL_VSW1, + kDIALOG_ADC_CONTROL_MUX_SEL_VSW2, + kDIALOG_ADC_CONTROL_MUX_SEL_VSW3A, + kDIALOG_ADC_CONTROL_MUX_SEL_VSW3B, + kDIALOG_ADC_CONTROL_MUX_SEL_VSW3C, + kDIALOG_ADC_CONTROL_MUX_SEL_VSW4, + kDIALOG_ADC_CONTROL_MUX_SEL_APP_MUX, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK0_OFF, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK1_OFF, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK2_OFF, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUCK3_OFF, + kDIALOG_ADC_CONTROL_MUX_SEL_ICH, + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_HR_OFF, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW0, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW1, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW2, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW3A, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW3B, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW3C, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW4, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW_OFF_0, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW_OFF_1, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW_OFF_2, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW_OFF_3A, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW_OFF_3B, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW_OFF_3C, + kDIALOG_ADC_CONTROL_MUX_SEL_ISW_OFF_4, + kDIALOG_ADC_CONTROL_MUX_SEL_APP_MUX_BC, + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 7), + kDIALOG_ADC_CONTROL2_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL2_AUTO_VDD_OUT_EN = (1 << 7), +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, + kDIALOG_ADC_CONTROL2_DEFAULTS = 0, +}; + +enum { + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 2500, +}; + + +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (0x1f << 3), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (0 << 3), + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = (2 << 3), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (0x10 << 3), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (0x11 << 3), +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_MASK) \ + < kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH) + +#define NUM_LDOS 16 +static const struct ldo_params ldo_d2238[NUM_LDOS] = { + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO1_VSEL, kD2238_ACTIVE3, 0x02 }, // 00 - LDO1 + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO2_VSEL, kD2238_ACTIVE3, 0x04 }, // 01 - LDO2 + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO3_VSEL, kD2238_ACTIVE3, 0x08 }, // 02 - LDO3 + { 2400, 25, 0x5c, 0x7f, 0x00, kD2238_LDO4_VSEL, kD2238_ACTIVE3, 0x10 }, // 03 - LDO4 + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO5_VSEL, kD2238_ACTIVE3, 0x20 }, // 04 - LDO5 + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO6_VSEL, kD2238_ACTIVE3, 0x40 }, // 05 - LDO6 + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO7_VSEL, kD2238_ACTIVE3, 0x80 }, // 06 - LDO7 + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO8_VSEL, kD2238_ACTIVE4, 0x01 }, // 07 - LDO8 + { 1200, 25, 0x54, 0x7f, 0x00, kD2238_LDO9_VSEL, 0, 0 }, // 08 - LDO9 (no ACTIVE control) + + { 0, 0, 0, 0, 0x00, 0, kD2238_ACTIVE6, 0x01 }, // 09 - SW0 + { 0, 0, 0, 0, 0x00, 0, kD2238_ACTIVE6, 0x02 }, // 0a - SW1 + { 0, 0, 0, 0, 0x00, 0, kD2238_ACTIVE6, 0x04 }, // 0b - SW2 + { 0, 0, 0, 0, 0x00, 0, kD2238_ACTIVE6, 0x08 }, // 0c - SW3A + { 0, 0, 0, 0, 0x00, 0, kD2238_ACTIVE6, 0x10 }, // 0d - SW3B + { 0, 0, 0, 0, 0x00, 0, kD2238_ACTIVE6, 0x20 }, // 0e - SW3C + { 0, 0, 0, 0, 0x00, 0, kD2238_ACTIVE6, 0x40 }, // 0f - SW4 + +}; +#define LDOP ldo_d2238 + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_150MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_250MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_350MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + kD2238_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD2238_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD2238_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kD2238_BUTTON_DBL_BTN4_DBL_EN = 0, + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD2238_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD2238_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD2238_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif /* __DIALOG_D2238_H */ diff --git a/drivers/dialog/pmu/d2255.h b/drivers/dialog/pmu/d2255.h new file mode 100644 index 0000000..6fb2edc --- /dev/null +++ b/drivers/dialog/pmu/d2255.h @@ -0,0 +1,1363 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D2255_H +#define __DIALOG_D2255_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 0 +#define PMU_HAS_SPI 1 +// TODO: use single register alias (and a value alias) for HAS_SWI,HAS_DWI,HAS_SPI +#define PMU_HAS_LCM_LDO 0 +#define PMU_HAS_BIST_ADC 0 +#define PMU_HAS_CHG_ABCC_FLAG 0 +#define PMU_HAS_VIB 0 +#define PMU_HAS_RAM 1 +#define PMU_HAS_WLED 0 +#define PMU_HAS_32K_RTC 1 +// TODO: enable accumulators +#define PMU_HAS_ACCUMULATORS 0 +#define PMU_HAS_GPIO_CONF 1 +#define PMU_HAS_SYS 1 +#define PMU_HAS_CHARGER 0 +#define PMU_HAS_PERF_STATES 1 +#define PMU_HAS_VSEL_LOCK 1 +#define PMU_DRV_NEW_DRIVER 1 +#define PMU_HAS_SCRATCH 1 + +enum { + kDIALOG_ADDR_R = 0xe9, + kDIALOG_ADDR_W = 0xe8, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_FAULTLOG_COUNT = 15, // kD2255_V_FAULTLOG_COUNT + kDIALOG_EVENT_COUNT = 25, // kD2255_V_EVENT_COUNT + kDIALOG_STATUS_COUNT = 25, // kD2255_V_STATUS_COUNT + kDIALOG_CHIPID_COUNT = 10, // SYSCTL_MASK_REV_CODE:0x0200 -> SYSCTL_DEVICE_ID7:0x020a + kDIALOG_GPIO_COUNT = 21, // IO_GPIO1_CONF1/2:0x0900,0x0901 -> IO_GPIO21_CONF1/2:0x0938,0x0939 +}; + +#include "dCommon.h" + +enum { +// --------------------------------- +// Faultlog (virtual) +// --------------------------------- + kDIALOG_FAULT_LOG_A = 0x0100, + // ... + // kDIALOG_FAULT_LOG_O + +// --------------------------------- +// Event, Status ,IRQ Mask (Virtual) +// --------------------------------- + + kD2255_V_EVENT_A = 0x0140, + kD2255_V_EVENT_B = 0x0141, + kD2255_V_EVENT_C = 0x0142, + kD2255_V_EVENT_D = 0x0143, + kD2255_V_EVENT_E = 0x0144, + kD2255_V_EVENT_F = 0x0145, + kD2255_V_EVENT_G = 0x0146, + kD2255_V_EVENT_H = 0x0147, + kD2255_V_EVENT_I = 0x0148, + kD2255_V_EVENT_J = 0x0149, + kD2255_V_EVENT_K = 0x014a, + kD2255_V_EVENT_L = 0x014b, + kD2255_V_EVENT_M = 0x014c, + kD2255_V_EVENT_N = 0x014d, + kD2255_V_EVENT_O = 0x014e, + kD2255_V_EVENT_P = 0x014f, + kD2255_V_EVENT_Q = 0x0150, + kD2255_V_EVENT_R = 0x0151, + kD2255_V_EVENT_S = 0x0152, + kD2255_V_EVENT_T = 0x0153, + kD2255_V_EVENT_U = 0x0154, + kD2255_V_EVENT_V = 0x0155, + kD2255_V_EVENT_W = 0x0156, + kD2255_V_EVENT_X = 0x0157, + kD2255_V_EVENT_Y = 0x0158, + + kD2255_V_STATUS_A = 0x0180, + // .... V_STATUS_Y + kD2255_V_IRQ_MASK_A = 0x01c0, + // .... V_IRQ_MASK_Y + + kD2255_V_FAULTLOG_COUNT = 15, + kD2255_V_EVENT_COUNT = 25, + kD2255_V_STATUS_COUNT = 25, + + kDIALOG_EVENT_A = kD2255_V_EVENT_A, + kDIALOG_STATUS_A = kD2255_V_STATUS_A, + kDIALOG_IRQ_MASK_A = kD2255_V_IRQ_MASK_A, +}; + +// --------------------------------- +// Chip Identification +// --------------------------------- +enum { + kDIALOG_MASK_REV_CODE = 0x0200, + kDIALOG_TRIM_REL_CODE = 0x0201, + kDIALOG_PLATFORM_ID = 0x0202, + kDIALOG_DEVICE_ID1 = 0x0204, + kDIALOG_DEVICE_ID2 = 0x0205, + kDIALOG_DEVICE_ID3 = 0x0206, + kDIALOG_DEVICE_ID4 = 0x0207, + kDIALOG_DEVICE_ID5 = 0x0208, + kDIALOG_DEVICE_ID6 = 0x0209, + kDIALOG_DEVICE_ID7 = 0x020a, + + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, +}; +// --------------------------------- +// System Control And Status +// --------------------------------- +enum { + kD2255_APP_TMUX = 0x0212, +}; + +// --------------------------------- +// System Configuration +// --------------------------------- + +enum { + kD2255_SYSCTL_PRE_UVLO_CTRL = 0x0268, + kD2255_SYSCTL_PRE_UVLO_SET_MASK = 0xf0, + kD2255_SYSCTL_PRE_UVLO_SET_SHIFT = 4, +}; + +// --------------------------------- +// Faultlog +// --------------------------------- + +enum { + kD2255_FAULT_LOG1 = 0x02c0, + kD2255_FAULT_LOG2 = 0x02c1, + + kDIALOG_FAULT_LOG = kD2255_FAULT_LOG1, + kDIALOG_FAULT_LOG2 = kD2255_FAULT_LOG2, +}; + +// --------------------------------- +// Events. Status and IRQ Control +// --------------------------------- + +enum { + kD2255_SYSCTL_EVENT = 0x02cf, + kD2255_SYSCTL_STATUS = 0x02d0, + kD2255_SYSCTL_IRQ_MASK = 0x02d1, +}; + +// --------------------------------- +// Power Supply Control +// Active,Standby,Hibernate are now encoded here, need TestAccess +// --------------------------------- +enum { + kD2255_PWRONOFF_BUCK0_EN = 0x0300, + kD2255_PWRONOFF_BUCK1_EN = 0x0301, + kD2255_PWRONOFF_BUCK2_EN = 0x0302, + kD2255_PWRONOFF_BUCK3_EN = 0x0303, + kD2255_PWRONOFF_BUCK4_EN = 0x0304, + kD2255_PWRONOFF_BUCK5_EN = 0x0305, + kD2255_PWRONOFF_BUCK6_EN = 0x0306, + kD2255_PWRONOFF_BUCK7_EN = 0x0307, + kD2255_PWRONOFF_BUCK8_EN = 0x0308, + kD2255_PWRONOFF_LDO1_EN = 0x0309, + kD2255_PWRONOFF_LDO2_EN = 0x030a, + kD2255_PWRONOFF_LDO3_EN = 0x030b, + kD2255_PWRONOFF_LDO4_EN = 0x030c, + kD2255_PWRONOFF_LDO5_EN = 0x030d, + kD2255_PWRONOFF_LDO6_EN = 0x030e, + kD2255_PWRONOFF_LDO7_EN = 0x030f, + kD2255_PWRONOFF_LDO8_EN = 0x0310, + kD2255_PWRONOFF_LDO9_EN = 0x0311, + kD2255_PWRONOFF_LDO10_EN = 0x0312, + kD2255_PWRONOFF_LDO11_EN = 0x0313, + kD2255_PWRONOFF_LDO13_EN = 0x0314, + kD2255_PWRONOFF_LDO14_EN = 0x0315, + kD2255_PWRONOFF_LDO15_EN = 0x0316, + kD2255_PWRONOFF_CP_EN = 0x0317, + kD2255_PWRONOFF_BUCK3_SW1_EN = 0x0318, + kD2255_PWRONOFF_BUCK3_SW2_EN = 0x0319, + kD2255_PWRONOFF_BUCK3_SW3_EN = 0x031a, + kD2255_PWRONOFF_BUCK4_SW1_EN = 0x031b, + kD2255_PWRONOFF_GPIO_32K_EN = 0x031c, + kD2255_PWRONOFF_OUT_32K_EN = 0x031d, + kD2255_PWRONOFF_SLEEP_32K_EN = 0x031e, + kD2255_PWRONOFF_NRESET_EN = 0x031f, + kD2255_PWRONOFF_SYS_ALIVE_EN = 0x0320, + kD2255_PWRONOFF_PRE_UVLO_EN = 0x0321, +}; + +// --------------------------------- +// Main FSM, MFSM Events +// --------------------------------- + +enum { + kD2255_MFSM_CTRL = 0x0400, + kD2255_ACT_TO_SLEEP3_DLY = 0x0401, + kD2255_ACT_TO_OFF_DLY = 0x0402, + kD2255_OFF_TIMER_DLY = 0x0403, + kD2255_SLEEP3_TIMER_DLY = 0x0404, + kD2255_MFSM_CONF1 = 0x0460, + + + kD2255_MFSM_CTRL_PERF_FLOOR_OFF = (0<<2), + kD2255_MFSM_CTRL_PERF_FLOOR_SLEEP3 = (1<<2), + kD2255_MFSM_CTRL_PERF_FLOOR_SLEEP2 = (2<<2), + kD2255_MFSM_CTRL_PERF_FLOOR_ACTIVE = (3<<2), + kD2255_MFSM_CTRL_FORCE_SLEEP3 = (1<<1), + kD2255_MFSM_CTRL_FORCE_OFF = (1<<0), + + kDIALOG_SYS_CONTROL_PERF_FLOOR_OFF = kD2255_MFSM_CTRL_PERF_FLOOR_OFF, + kDIALOG_SYS_CONTROL_PERF_FLOOR_SLEEP3 = kD2255_MFSM_CTRL_PERF_FLOOR_SLEEP3, + kDIALOG_SYS_CONTROL_PERF_FLOOR_SLEEP2 = kD2255_MFSM_CTRL_PERF_FLOOR_SLEEP2, + kDIALOG_SYS_CONTROL_PERF_FLOOR_ACTIVE = kD2255_MFSM_CTRL_PERF_FLOOR_ACTIVE, + kDIALOG_SYS_CONTROL_PERF_FLOOR_MASK = (0x3<<2), + + kDIALOG_SYS_CONTROL_HIBERNATE = kD2255_MFSM_CTRL_FORCE_SLEEP3, + kDIALOG_SYS_CONTROL_STANDBY = kD2255_MFSM_CTRL_FORCE_OFF, + // TODO: verify this + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, + + kDIALOG_SYS_CONTROL = kD2255_MFSM_CTRL, +}; + +// --------------------------------- +// RTC Calendar and Clock, Events +// --------------------------------- + +enum { + kDIALOG_RTC_CONTROL = 0x0500, + kDIALOG_RTC_TIMEZONE = 0x0501, + kDIALOG_RTC_SUB_SECOND_A = 0x0502, + kDIALOG_RTC_SUB_SECOND_B = 0x0503, + kDIALOG_RTC_SECOND_A = 0x0504, + kDIALOG_RTC_SECOND_B = 0x0505, + kDIALOG_RTC_SECOND_C = 0x0506, + kDIALOG_RTC_SECOND_D = 0x0507, + kDIALOG_RTC_ALARM_A = 0x0508, + kDIALOG_RTC_ALARM_B = 0x0509, + kDIALOG_RTC_ALARM_C = 0x050a, + kDIALOG_RTC_ALARM_D = 0x050b, + +// Events. Status. Mask in Virtual +// kD2255_RTC_EVENT = 0x05c0, +// kD2255_RTC_STATUS = 0x05c1, +// kD2255_RTC_IRQ_MASK = 0x05c2, +}; + +// --------------------------------- +// SPI Interface +// --------------------------------- + +enum { + kD2255_SPI_CTRL = 0x0600, // global enable + kD2255_EN_CMD0 = 0x0601, // buck#_spi_en + kD2255_EN_CMD1 = 0x0602, // Antigua130: BUCK8 [0] + kD2255_EN_CMD3 = 0x0604, // buck#_spi_dis_master + kD2255_EN_CMD4 = 0x0605, // Antigua130: BUCK8 [0] + kD2255_SPI_CONFIG = 0x0660, + + // set when PMU_HAS_SPI + kDIALOG_SPI_CONTROL = kD2255_SPI_CTRL, + kDIALOG_SPI_CONTROL_SPI_EN = 1, + +// Events. Status. Mask in Virtual +}; + +// --------------------------------- +// Clock Generation +// --------------------------------- + +enum { + kD2255_SYS_CTRL_CONF0 = 0x0700, + kD2255_SYS_CTRL_CONF1 = 0x0760, + kD2255_RTC_CTRL0 = 0x0761, + kD2255_RTC_CTRL1 = 0x0762, + kD2255_RTC_CTRL2 = 0x0763, + kD2255_OSC_CTRL0 = 0x0764, + kD2255_INT_OSC_TRIM = 0x0765, // Antigua130: INT_OSC_TRIM[5:0] + kD2255_CLK_REQ_FRC = 0x0766, + kD2255_BG_CTRL = 0x0767, + + kD2255_CKLGEN_EVENT = 0x07c0, + kD2255_CKLGEN_STATUS = 0x07c1, + kD2255_CKLGEN_IRQ_MASK = 0x07c2, +}; + +// --------------------------------- +// Misc +// --------------------------------- + +enum { + kD2255_HIB_SW_CTRL = 0x0860, // Antigua130: SEL_2V4[2] +}; + +// --------------------------------- +// GPIO configuration +// --------------------------------- + +enum { + kD2255_GPIO1_CONF1 = 0x0900, + kD2255_GPIO1_CONF2 = 0x0901, + kD2255_GPIO2_CONF1, + kD2255_GPIO2_CONF2, + kD2255_GPIO3_CONF1, + kD2255_GPIO3_CONF2, + kD2255_GPIO4_CONF1, + kD2255_GPIO4_CONF2, + kD2255_GPIO5_CONF1, + kD2255_GPIO5_CONF2, + kD2255_GPIO6_CONF1, + kD2255_GPIO6_CONF2, + kD2255_GPIO7_CONF1, + kD2255_GPIO7_CONF2, + kD2255_GPIO8_CONF1, + kD2255_GPIO8_CONF2, + kD2255_GPIO9_CONF1, + kD2255_GPIO9_CONF2, + kD2255_GPIO10_CONF1, + kD2255_GPIO10_CONF2, + kD2255_GPIO11_CONF1, + kD2255_GPIO11_CONF2, + kD2255_GPIO12_CONF1, + kD2255_GPIO12_CONF2, + kD2255_GPIO13_CONF1, + kD2255_GPIO13_CONF2, + kD2255_GPIO14_CONF1, + kD2255_GPIO14_CONF2, + kD2255_GPIO15_CONF1, + kD2255_GPIO15_CONF2, + kD2255_GPIO16_CONF1, + kD2255_GPIO16_CONF2, + kD2255_GPIO17_CONF1, + kD2255_GPIO17_CONF2, + kD2255_GPIO18_CONF1_SLP1 = 0x0922, + kD2255_GPIO18_CONF1_SLP2, + kD2255_GPIO18_CONF1_SLP3, + kD2255_GPIO18_CONF1_OFF, + kD2255_GPIO18_CONF1, + kD2255_GPIO18_CONF2, + kD2255_GPIO19_CONF1_SLP1 = 0x0928, + kD2255_GPIO19_CONF1_SLP2, + kD2255_GPIO19_CONF1_SLP3, + kD2255_GPIO19_CONF1_OFF, + kD2255_GPIO19_CONF1, + kD2255_GPIO19_CONF2, + kD2255_GPIO20_CONF1_SLP1 = 0x092e, + kD2255_GPIO20_CONF1_SLP2, + kD2255_GPIO20_CONF1_SLP3, + kD2255_GPIO20_CONF1_OFF, + kD2255_GPIO20_CONF1, + kD2255_GPIO20_CONF2, + kD2255_GPIO21_CONF1_SLP1 = 0x0934, + kD2255_GPIO21_CONF1_SLP2, + kD2255_GPIO21_CONF1_SLP3, + kD2255_GPIO21_CONF1_OFF, + kD2255_GPIO21_CONF1, + kD2255_GPIO21_CONF2, + kDIALOG_SYS_GPIO_REG_START = kD2255_GPIO1_CONF1, + +// until GPIO21_CONF1, GPIO21_CONF2 ... kDIALOG_GPIO_COUNT gpios + + kD2255_OUT_32K = 0x093a, + kD2255_SLEEP_32K = 0x093b, + kD2255_ACTIVE_RDY = 0x093c, + kD2255_SLEEP1_RDY = 0x093d, + +// GPI Control + kD2255_BUTTON1_CONF = 0x0960, + kD2255_BUTTON2_CONF = 0x0961, + kD2255_BUTTON3_CONF = 0x0962, + kD2255_BUTTON4_CONF = 0x0963, + kD2255_BUTTON_DBL = 0x0964, + kD2255_BUTTON_WAKE = 0x0965, + + kD2255_RESET_IN1_CONF1 = 0x0966, + kD2255_RESET_IN1_CONF2 = 0x0967, + kD2255_RESET_IN2_CONF1 = 0x0968, + kD2255_RESET_IN2_CONF2 = 0x0969, + kD2255_RESET_IN3_CONF1 = 0x096a, + kD2255_RESET_IN3_CONF2 = 0x096b, + + kDIALOG_BUTTON_DBL = kD2255_BUTTON_DBL, +}; + +// --------------------------------- +// Event,Status,IRQ Control +// --------------------------------- +enum { + kD2255_IO_EVENT_A = 0x09c0, + kD2255_IO_EVENT_B = 0x09c1, + kD2255_IO_EVENT_C = 0x09c2, + kD2255_IO_EVENT_D = 0x09c3, + + kD2255_IO_STATUS_A = 0x09c4, + kD2255_IO_STATUS_B = 0x09c5, + kD2255_IO_STATUS_C = 0x09c6, + kD2255_IO_STATUS_D = 0x09c7, + + kD2255_IO_IRQ_MASK_A = 0x09c8, + kD2255_IO_IRQ_MASK_B = 0x09c9, + kD2255_IO_IRQ_MASK_C = 0x09ca, + kD2255_IO_IRQ_MASK_D = 0x09cb, +// Using the Virtual ones +// kDIALOG_EVENT_A = kD2255_IO_EVENT_A, +// kDIALOG_STATUS_A = kD2255_IO_STATUS_A, +// kDIALOG_IRQ_MASK_A = kD2255_IO_IRQ_MASK_A, +}; + +// --------------------------------- +// Buck control +// --------------------------------- + +enum { + kD2255_BUCK0_FAST_VSEL = 0x1000, + kD2255_BUCK0_VSEL = 0x1001, + kD2255_BUCK0_FAST_VSEL_EN, + kD2255_BUCK0_VSEL_ACTUAL, + kD2255_BUCK0_VSEL_LOCK = 0x1004, + kD2255_BUCK0_MINV, + kD2255_BUCK0_MAXV, + kD2255_BUCK0_OFS_V, + kD2255_BUCK0_MODE = 0x1008, + kD2255_BUCK0_DEBUG_OFS_V = 0x1060, + kD2255_BUCK0_FSM_TRIM0 = 0x1061, + kD2255_BUCK0_FSM_TRIM1, + kD2255_BUCK0_FSM_TRIM2, + kD2255_BUCK0_FSM_TRIM3, + kD2255_BUCK0_FSM_TRIM4, + kD2255_BUCK0_FSM_TRIM5, + kD2255_BUCK0_FSM_TRIM6 = 0x1067, + kD2255_BUCK0_FSM_TRIM7 = 0x1068, + kD2255_BUCK0_FSM_TRIM8, + kD2255_BUCK0_FSM_TRIM9, + kD2255_BUCK0_FSM_TRIM10, + kD2255_BUCK0_FSM_TRIM11, + kD2255_BUCK0_FSM_TRIM12, + kD2255_BUCK0_FSM_TRIM13 = 0x106E, + kD2255_BUCK0_CLK_TRIM0 = 0x106F, + kD2255_BUCK0_CLK_TRIM1, + kD2255_BUCK0_CLK_TRIM2, + kD2255_BUCK0_CLK_TRIM3, + kD2255_BUCK0_CALIB0 = 0x1073, + kD2255_BUCK0_CALIB1, + kD2255_BUCK0_CALIB2, + + kD2255_BUCK1_FAST_VSEL = 0x1100, + kD2255_BUCK1_VSEL = 0x1101, + kD2255_BUCK1_VSEL_LOCK = 0x1104, + kD2255_BUCK1_FSM_TRIM6 = 0x1167, + kD2255_BUCK1_FSM_TRIM7 = 0x1168, + kD2255_BUCK1_CLK_TRIM1 = 0x1170, + kD2255_BUCK1_CLK_TRIM2 = 0x1171, + kD2255_BUCK1_CLK_TRIM3 = 0x1172, + kD2255_BUCK1_ANA_TRIM10 = 0x1181, // Antigua130 all diff + + kD2255_BUCK2_FAST_VSEL = 0x1200, + kD2255_BUCK2_VSEL = 0x1201, + kD2255_BUCK2_VSEL_LOCK = 0x1204, + kD2255_BUCK2_MINV = 0x1205, + kD2255_BUCK2_FSM_TRIM6 = 0x1267, + kD2255_BUCK2_FSM_TRIM7 = 0x1268, + + kD2255_BUCK3_FAST_VSEL = 0x1300, + kD2255_BUCK3_VSEL = 0x1301, + kD2255_BUCK3_VSEL_LOCK = 0x1304, + kD2255_BUCK3_FSM_TRIM6 = 0x1367, + kD2255_BUCK3_FSM_TRIM7 = 0x1368, + + kD2255_BUCK4_FAST_VSEL = 0x1400, + kD2255_BUCK4_VSEL = 0x1401, + kD2255_BUCK4_VSEL_LOCK = 0x1404, + kD2255_BUCK4_FSM_TRIM6 = 0x1467, + kD2255_BUCK4_FSM_TRIM7 = 0x1468, + + kD2255_BUCK5_FAST_VSEL = 0x1500, + kD2255_BUCK5_VSEL = 0x1501, + kD2255_BUCK5_VSEL_LOCK = 0x1504, + kD2255_BUCK5_FSM_TRIM6 = 0x1567, + kD2255_BUCK5_FSM_TRIM7 = 0x1568, + kD2255_BUCK5_ANA_TRIM14 = 0x1585, // Antigua130 ANA_TRIM14_SPARE[7:6] + + kD2255_BUCK6_FAST_VSEL = 0x1600, + kD2255_BUCK6_VSEL = 0x1601, + kD2255_BUCK6_VSEL_LOCK = 0x1604, + kD2255_BUCK6_BYP1 = 0x1609, + kD2255_BUCK6_FSM_TRIM6 = 0x1667, + kD2255_BUCK6_FSM_TRIM7 = 0x1668, + + kD2255_BUCK7_FAST_VSEL = 0x1700, + kD2255_BUCK7_VSEL = 0x1701, + kD2255_BUCK7_VSEL_LOCK = 0x1704, + kD2255_BUCK7_FSM_TRIM6 = 0x1767, + kD2255_BUCK7_FSM_TRIM7 = 0x1768, + + kD2255_BUCK8_FAST_VSEL = 0x1800, + kD2255_BUCK8_VSEL = 0x1801, + kD2255_BUCK8_VSEL_LOCK = 0x1804, + kD2255_BUCK8_FSM_TRIM6 = 0x1867, + kD2255_BUCK8_FSM_TRIM7 = 0x1868, + + kDIALOG_BUCK_VSEL_LOCK_EN = 1, + kDIALOG_BUCK_VSEL_LOCK_DIS = 0, + // how much to add to VSEL register base to get VSEL_OFFSET + kDIALOG_BUCK_VSEL_LOCK_OFFSET = (kD2255_BUCK0_VSEL_LOCK-kD2255_BUCK0_VSEL), +}; + +enum { + kD2255_LDO_RTC_TRIM = 0x2062, // Antigua130 VRTC_LDO_TRIM[5:0] + + // LDO control... + kD2255_LDO1_VSEL = 0x2100, + kD2255_LDO1_VSEL_ACTUAL = 0x2101, + kD2255_LDO1_MINV = 0x2160, + kD2255_LDO1_MAXV = 0x2161, + kD2255_LDO1_UOV_LIM_EN_VOUT_PD= 0x2163, // Antigua130 LDO1_UV_LIM[3:2] + + kD2255_LDO2_VSEL = 0x2200, + kD2255_LDO2_VSEL_ACTUAL = 0x2201, + kD2255_LDO2_BYPASS = 0x2202, + kD2255_LDO2_MINV = 0x2260, + kD2255_LDO2_MAXV = 0x2261, + kD2255_LDO2_TRIM = 0x2262, + kD2255_LDO2_UOV_LIM_EN_VOUT_PD= 0x2263, // Antigua130 LDO2_UV_LIM[3:2] + kD2255_LDO2_VSEL_BYPASS_TRIM= 0x2269, + + kD2255_LDO3_VSEL = 0x2300, + kD2255_LDO3_VSEL_ACTUAL = 0x2301, + kD2255_LDO3_MINV = 0x2360, + kD2255_LDO3_MAXV = 0x2361, + kD2255_LDO3_UOV_LIM_EN_VOUT_PD= 0x2363, // Antigua130 LDO3_UV_LIM[3:2] + + kD2255_LDO4_VSEL = 0x2400, + kD2255_LDO4_VSEL_ACTUAL = 0x2401, + kD2255_LDO4_MINV = 0x2460, + kD2255_LDO4_MAXV = 0x2461, + kD2255_LDO4_TRIM = 0x2462, // Antigua130 LDO4_ITEMP[7:5] + kD2255_LDO4_UOV_LIM_EN_VOUT_PD= 0x2463, // Antigua130 LDO4_UV_LIM[3:2] + + kD2255_LDO5_VSEL = 0x2500, + kD2255_LDO5_VSEL_ACTUAL = 0x2501, + kD2255_LDO5_MINV = 0x2560, + kD2255_LDO5_MAXV = 0x2561, + kD2255_LDO5_UOV_LIM_EN_VOUT_PD= 0x2563, // Antigua130 LDO5_UV_LIM[3:2] + kD2255_LDO5_ILIMIT_STATE = 0x2565, // Antigua130 LDO_LDO5_ILIMIT_STATE[2:1] LDO5_ISTART_100MA[3] + // .. + + kD2255_LDO6_VSEL = 0x2600, + kD2255_LDO6_VSEL_ACTUAL = 0x2601, + kD2255_LDO6_BYPASS = 0x2602, + kD2255_LDO6_MINV = 0x2660, + kD2255_LDO6_MAXV = 0x2661, + + kD2255_LDO7_VSEL = 0x2700, + kD2255_LDO7_VSEL_ACTUAL = 0x2701, + kD2255_LDO7_MINV = 0x2760, + kD2255_LDO7_MAXV = 0x2761, + + kD2255_LDO8_VSEL = 0x2800, + kD2255_LDO8_VSEL_ACTUAL = 0x2801, + kD2255_LDO8_MINV = 0x2860, + kD2255_LDO8_MAXV = 0x2861, + + kD2255_LDO9_VSEL = 0x2900, + kD2255_LDO9_VSEL_ACTUAL = 0x2901, + kD2255_LDO9_MINV = 0x2960, + kD2255_LDO9_MAXV = 0x2961, + kD2255_LDO9_TRIM = 0x2962, // Antigua130 LDO9_DROPOUT_TRIM[7:5] + + kD2255_LDO10_VSEL = 0x2A00, + kD2255_LDO10_VSEL_ACTUAL = 0x2A01, + kD2255_LDO10_MINV = 0x2A60, + kD2255_LDO10_MAXV = 0x2A61, + kD2255_LDO10_TRIM = 0x2A62, + + kD2255_LDO11_VSEL = 0x2B00, + kD2255_LDO11_VSEL_ACTUAL = 0x2B01, + kD2255_LDO11_MINV = 0x2B60, + kD2255_LDO11_MAXV = 0x2B61, + kD2255_LDO11_TRIM = 0x2B62, + + kD2255_LDO12_TRIM = 0x2C62, + + kD2255_LDO13_VSEL = 0x2D00, + kD2255_LDO13_VSEL_ACTUAL = 0x2D01, + kD2255_LDO13_MINV = 0x2D60, + kD2255_LDO13_MAXV = 0x2D61, + kD2255_LDO13_TRIM = 0x2D62, + + kD2255_LDO14_VSEL = 0x2E00, + kD2255_LDO14_VSEL_ACTUAL = 0x2E01, + kD2255_LDO14_MINV = 0x2E60, + kD2255_LDO14_MAXV = 0x2E61, + kD2255_LDO14_TRIM = 0x2E62, + + kD2255_LDO15_VSEL = 0x2F00, + kD2255_LDO15_VSEL_ACTUAL = 0x2F01, + kD2255_LDO15_BYPASS = 0x2F02, + kD2255_LDO15_MINV = 0x2F60, + kD2255_LDO15_MAXV = 0x2F61, + kD2255_LDO15_TRIM = 0x2F62, + + kD2255_LDO_EVENT = 0x3FC0, + kD2255_LDO_STATUS = 0x3FC1, + kD2255_LDO_IRQ_MASK = 0x3FC2, + + kDIALOG_BYPASS_EN = 1, + kDIALOG_BYPASS_DIS = 0, +}; + +// --------------------------------- +// POWER ON/OFF +// --------------------------------- + +enum { +// Power Supply Control + kD2255_BUCK0_EN = 0x0300, + kD2255_BUCK1_EN = 0x0301, + kD2255_BUCK2_EN = 0x0302, + kD2255_BUCK3_EN = 0x0303, + kD2255_BUCK4_EN = 0x0304, + kD2255_BUCK5_EN = 0x0305, + kD2255_BUCK6_EN = 0x0306, + kD2255_BUCK7_EN = 0x0307, + kD2255_BUCK8_EN = 0x0308, + kD2255_LDO1_EN = 0x0309, + kD2255_LDO2_EN = 0x030a, + kD2255_LDO3_EN = 0x030b, + kD2255_LDO4_EN = 0x030c, + kD2255_LDO5_EN = 0x030d, + kD2255_LDO6_EN = 0x030e, + kD2255_LDO7_EN = 0x030f, + kD2255_LDO8_EN = 0x0310, + kD2255_LDO9_EN = 0x0311, + kD2255_LDO10_EN = 0x0312, + kD2255_LDO11_EN = 0x0313, + kD2255_LDO13_EN = 0x0314, + kD2255_LDO14_EN = 0x0315, + kD2255_LDO15_EN = 0x0316, + kD2255_CP_EN, + kD2255_BUCK3_SW1_EN = 0x0318, + kD2255_BUCK3_SW2_EN = 0x0319, + kD2255_BUCK3_SW3_EN = 0x031A, + kD2255_BUCK4_SW1_EN = 0x031B, + kD2255_GPIO32K_EN = 0x031C, + kD2255_OUT32K_EN = 0x031D, + kD2255_SLEEP32K_EN = 0x031E, + kD2255_NRESET_EN = 0x031F, + kD2255_SYSALIVE_EN = 0x0320, + kD2255_PRE_UVLO_EN = 0x0321, + + +}; + + +// --------------------------------- +// GPADC control +// --------------------------------- + +enum { + kD2255_GPADC_MAN_CTRL1 = 0x4000, + kD2255_GPADC_MAN_CTRL1_MASK = 0xff, + kD2255_GPADC_MAN1_RES_LSB = 0x4001, + kD2255_GPADC_MAN1_RES_MSB = 0x4002, + + kD2255_GPADC_MAN_CTRL2 = 0x4004, + kD2255_GPADC_MAN_CTRL2_MASK = 0x7F, + kD2255_GPADC_MAN2_RES_LSB = 0x4005, + kD2255_GPADC_MAN2_RES_MSB = 0x4006, + + kD2255_GPADC_TDIE1_RISE = 0x4147, + // .. + kD2255_GPADC_TDIE11_RISE = 0x4151, + + kDIALOG_T_OFFSET_MSB = 0x4153, + kDIALOG_T_OFFSET_LSB = 0x4154, // [0-3] + + kD2265_GPADC_ANA_COMPAT_CONF = 0x4172, // to disable Antigua130's ADC_Compatibility mode + kD2265_GP_ADC_COMPAT_BYPASS = 1, // [0] + + kD2255_GPADC_EVENT0 = 0x418B, + kD2255_GPADC_EVENT1 = 0x418C, + kD2255_GPADC_STATUS0 = 0x4191, + kD2255_GPADC_STATUS1 = 0x4192, +}; + +enum { + kDIALOG_APP_TMUX = kD2255_APP_TMUX, +#if 0 + kDIALOG_BIST_ADC_CTRL = 0x0541, + kDIALOG_BIST_ADC_LSB = 0x0542, + kDIALOG_BIST_ADC_MSB = 0x0543, + kD2186_BIST_ADC_TRIM1 = 0x0545, + kD2186_BIST_ADC_ANA_TRIM0 = 0x0546, + + kD2186_SPARE_RW0 = 0x0680, + kD2186_SPARE_RW_LAST = 0x0687, + kD2186_SPARE_RWTOTP0 = 0x06a0, + kD2186_SPARE_RWTOTP_LAST = 0x06a7, + kD2186_SPARE_RWOTP0 = 0x06c0, + kD2186_SPARE_RWOTP1 = 0x06c1, +#endif +}; + +// --------------------------------- +// RAM/TEST/SCRATCH +// --------------------------------- + +enum { + // Legacy Scratch Pads + kDIALOG_MEMBYTE0 = 0x5000, + kDIALOG_MEMBYTE_LAST = 0x5027, + + kDIALOG_TEST_ACCESS = 0x7000, + kDIALOG_TEST_ACCESS_ENA = 0x1D, // Antigua130 defines 1, ok to use 0x1D + kDIALOG_TEST_ACCESS_DIS = 0x00, + + // Check for Antigua130 (dialog 2265) Implementation + kD2265_IMPLEMENTATION = 0x7081, + kD2265_130NM = 130, + + // Scratch Pad RAM + kDIALOG_RAM0 = 0x8000, + kDIALOG_RAM_LAST = 0x87ff, + + kDIALOG_EXT_MEM_CAL0_SIZE = 64, + kDIALOG_GAP_SCRATCH8_SIZE = 8, // ex diags, free now + kDIALOG_EXT_MEM_CAL1_SIZE = 336, + kDIALOG_VOLTAGE_KNOBS_SIZE = 32, + // ... + kDIALOG_DIAG_SCRATCH_SIZE = 32, + + kDIALOG_EXT_MEM_CAL0 = kDIALOG_RAM0, + kDIALOG_EXT_MEM_CAL1 = kDIALOG_EXT_MEM_CAL0+kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_GAP_SCRATCH8_SIZE, + kDIALOG_VOLTAGE_KNOBS = kDIALOG_EXT_MEM_CAL1+kDIALOG_EXT_MEM_CAL1_SIZE, + // reserved, future + kDIALOG_DIAG_SCRATCH = 0x87e0, + + // handy + kDIALOG_EXT_MEM_CAL_SIZE = kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_EXT_MEM_CAL1_SIZE, +}; + +#if 0 +// TODO: Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 2, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, +}; +#endif + +enum { +// Virtual Event registers + + // SYSCTL_EVENT + kD2255_EVENT_A_UOV = (1 << 1), + kD2255_EVENT_A_HIGH_TEMP_WARNING= (1 << 0), + // MFSM_EVENT + kD2255_EVENT_B_SLEEP3_EXIT = (1 << 2), + kD2255_EVENT_B_SLEEP2_EXIT = (1 << 1), + kD2255_EVENT_B_SLEEP1_EXIT = (1 << 0), + // RTC_EVENT + kD2255_EVENT_C_ALARM = (1 << 0), + // SPI_EVENT + kD2255_EVENT_D_NACK = (1 << 1), + kD2255_EVENT_D_SPI_ERR = (1 << 0), + // CLKGEN_EVENT + kD2255_EVENT_E_XTAL_ERR = (1 << 0), + // IO_EVENT_A + kD2255_EVENT_F_BUTTON4_DBL = (1 << 7), + kD2255_EVENT_F_BUTTON3_DBL = (1 << 6), + kD2255_EVENT_F_BUTTON2_DBL = (1 << 5), + kD2255_EVENT_F_BUTTON1_DBL = (1 << 4), + kD2255_EVENT_F_BUTTON4 = (1 << 3), + kD2255_EVENT_F_BUTTON3 = (1 << 2), + kD2255_EVENT_F_BUTTON2 = (1 << 1), + kD2255_EVENT_F_BUTTON1 = (1 << 0), + // IO_EVENT_B + kD2255_EVENT_G_GPIO8 = (1 << 7), + kD2255_EVENT_G_GPIO7 = (1 << 6), + kD2255_EVENT_G_GPIO6 = (1 << 5), + kD2255_EVENT_G_GPIO5 = (1 << 4), + kD2255_EVENT_G_GPIO4 = (1 << 3), + kD2255_EVENT_G_GPIO3 = (1 << 2), + kD2255_EVENT_G_GPIO2 = (1 << 1), + kD2255_EVENT_G_GPIO1 = (1 << 0), + // IO_EVENT_C + kD2255_EVENT_H_GPIO16 = (1 << 7), + kD2255_EVENT_H_GPIO15 = (1 << 6), + kD2255_EVENT_H_GPIO14 = (1 << 5), + kD2255_EVENT_H_GPIO13 = (1 << 4), + kD2255_EVENT_H_GPIO12 = (1 << 3), + kD2255_EVENT_H_GPIO11 = (1 << 2), + kD2255_EVENT_H_GPIO10 = (1 << 1), + kD2255_EVENT_H_GPIO9 = (1 << 0), + // IO_EVENT_D + kD2255_EVENT_I_GPIO21 = (1 << 4), + kD2255_EVENT_I_GPIO20 = (1 << 3), + kD2255_EVENT_I_GPIO19 = (1 << 2), + kD2255_EVENT_I_GPIO18 = (1 << 1), + kD2255_EVENT_I_GPIO17 = (1 << 0), + // GPADC_EVENT0 + kD2255_EVENT_T_ADC_ERROR = (1 << 7), + kD2255_EVENT_T_EOMC2 = (1 << 1), + kD2255_EVENT_T_EOMC1 = (1 << 0), +}; + + +// EVENT_L events are stored by LLB across sleep/wake +enum { + kD2186_EVENT_L_VIB_ILIM = (1 << 7), + kD2186_EVENT_L_IBUS_OVERFLOW = (1 << 6), + kD2186_EVENT_L_XTAL_ERROR = (1 << 5), + kD2186_EVENT_L_HIB = (1 << 4), + kD2186_EVENT_L_DWI_TO = (1 << 3), + kD2186_EVENT_L_EOMC_BIST = (1 << 2), + kD2186_EVENT_L_EOMC = (1 << 1), + kD2186_EVENT_L_ALARM = (1 << 0), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(5, kD2255_EVENT_F_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(5, kD2255_EVENT_F_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(5, kD2255_EVENT_F_BUTTON3), + kDIALOG_EVENT_BUTTON4_MASK = EVENT_FLAG_MAKE(5, kD2255_EVENT_F_BUTTON4), + + kDIALOG_EVENT_BUTTONS = (kD2255_EVENT_F_BUTTON4 | + kD2255_EVENT_F_BUTTON3 | + kD2255_EVENT_F_BUTTON2 | + kD2255_EVENT_F_BUTTON1), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(5, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(2, kD2255_EVENT_C_ALARM), + kDIALOG_EVENT_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_VBUS_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_VBUS_EXT_REM_MASK = kDIALOG_NOTEXIST_MASK, + + // FIXME: forcing ADC1 + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(19, kD2255_EVENT_T_EOMC1), + kDIALOG_EVENT_HIB_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ABCC_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_CHG_END_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_TBAT_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(6, kD2255_EVENT_G_GPIO8), + + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(7, kD2255_EVENT_H_GPIO16), + + kDIALOG_EVENT_GPIO17_MASK = EVENT_FLAG_MAKE(8, kD2255_EVENT_I_GPIO17), + kDIALOG_EVENT_GPIO18_MASK = EVENT_FLAG_MAKE(8, kD2255_EVENT_I_GPIO18), + kDIALOG_EVENT_GPIO19_MASK = EVENT_FLAG_MAKE(8, kD2255_EVENT_I_GPIO19), + kDIALOG_EVENT_GPIO20_MASK = EVENT_FLAG_MAKE(8, kD2255_EVENT_I_GPIO20), + kDIALOG_EVENT_GPIO21_MASK = EVENT_FLAG_MAKE(8, kD2255_EVENT_I_GPIO21), + + // TODO: check HOLD, MENU, RINGER + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(5, kD2255_EVENT_F_BUTTON2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(5, kD2255_EVENT_F_BUTTON1_DBL), + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(5, kD2255_EVENT_F_BUTTON3_DBL), + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { + kDIALOG_STATUS_USB_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_VBUS_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_CHARGING_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_CHG_TO_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_CHG_END_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_TBAT_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_CHG_ATT_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ABCC_MASK = kDIALOG_NOTEXIST_MASK, +}; + +static const statusRegisters kDialogStatusFWMask = { }; + +enum { + kD2255_EVENT_A_WAKEMASK = 0, + kD2255_EVENT_B_WAKEMASK = 0, + kD2255_EVENT_C_WAKEMASK = kD2255_EVENT_C_ALARM , + kD2255_EVENT_D_WAKEMASK = 0, + kD2255_EVENT_E_WAKEMASK = 0, + kD2255_EVENT_F_WAKEMASK = kD2255_EVENT_F_BUTTON4 | kD2255_EVENT_F_BUTTON3 | + kD2255_EVENT_F_BUTTON2 | kD2255_EVENT_F_BUTTON1 , + kD2255_EVENT_G_WAKEMASK = 0, + kD2255_EVENT_H_WAKEMASK = 0, + kD2255_EVENT_I_WAKEMASK = 0, + kD2255_EVENT_J_WAKEMASK = 0, + kD2255_EVENT_K_WAKEMASK = 0, + kD2255_EVENT_L_WAKEMASK = 0, + kD2255_EVENT_M_WAKEMASK = 0, + kD2255_EVENT_N_WAKEMASK = 0, + kD2255_EVENT_O_WAKEMASK = 0, + kD2255_EVENT_P_WAKEMASK = 0, + kD2255_EVENT_Q_WAKEMASK = 0, + kD2255_EVENT_R_WAKEMASK = 0, + kD2255_EVENT_S_WAKEMASK = 0, + kD2255_EVENT_T_WAKEMASK = 0, + kD2255_EVENT_U_WAKEMASK = 0, + kD2255_EVENT_V_WAKEMASK = 0, + kD2255_EVENT_W_WAKEMASK = 0, + kD2255_EVENT_X_WAKEMASK = 0, + kD2255_EVENT_Y_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2255_EVENT_A_WAKEMASK, + ~kD2255_EVENT_B_WAKEMASK, + ~kD2255_EVENT_C_WAKEMASK, + ~kD2255_EVENT_D_WAKEMASK, + ~kD2255_EVENT_E_WAKEMASK, + ~kD2255_EVENT_F_WAKEMASK, + ~kD2255_EVENT_G_WAKEMASK, + ~kD2255_EVENT_H_WAKEMASK, + ~kD2255_EVENT_I_WAKEMASK, + ~kD2255_EVENT_J_WAKEMASK, + ~kD2255_EVENT_K_WAKEMASK, + ~kD2255_EVENT_L_WAKEMASK, + ~kD2255_EVENT_M_WAKEMASK, + ~kD2255_EVENT_N_WAKEMASK, + ~kD2255_EVENT_O_WAKEMASK, + ~kD2255_EVENT_P_WAKEMASK, + ~kD2255_EVENT_Q_WAKEMASK, + ~kD2255_EVENT_R_WAKEMASK, + ~kD2255_EVENT_S_WAKEMASK, + ~kD2255_EVENT_T_WAKEMASK, + ~kD2255_EVENT_U_WAKEMASK, + ~kD2255_EVENT_V_WAKEMASK, + ~kD2255_EVENT_W_WAKEMASK, + ~kD2255_EVENT_X_WAKEMASK, + ~kD2255_EVENT_Y_WAKEMASK, +}; + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2255_EVENT_A_WAKEMASK, + kD2255_EVENT_B_WAKEMASK, + kD2255_EVENT_C_WAKEMASK, + kD2255_EVENT_D_WAKEMASK, + kD2255_EVENT_E_WAKEMASK, + kD2255_EVENT_F_WAKEMASK & ~kDIALOG_EVENT_BUTTONS, + kD2255_EVENT_G_WAKEMASK, + kD2255_EVENT_H_WAKEMASK, + kD2255_EVENT_I_WAKEMASK, + kD2255_EVENT_J_WAKEMASK, + kD2255_EVENT_K_WAKEMASK, + kD2255_EVENT_L_WAKEMASK, + kD2255_EVENT_M_WAKEMASK, + kD2255_EVENT_N_WAKEMASK, + kD2255_EVENT_O_WAKEMASK, + kD2255_EVENT_P_WAKEMASK, + kD2255_EVENT_Q_WAKEMASK, + kD2255_EVENT_R_WAKEMASK, + kD2255_EVENT_S_WAKEMASK, + kD2255_EVENT_T_WAKEMASK, + kD2255_EVENT_U_WAKEMASK, + kD2255_EVENT_V_WAKEMASK, + kD2255_EVENT_W_WAKEMASK, + kD2255_EVENT_X_WAKEMASK, + kD2255_EVENT_Y_WAKEMASK, +}; + +// All events indicating external power supply +// XXX: D2255 verify this, when I have vbus? GPIO, maybe.. +static const eventRegisters kDialogEventPwrsupplyMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +enum { + kDialogEventPwrsupplyCount = 0, + kDialogEventUSBCount = 0, + kDialogEventFWCount = 0, +}; + +enum { + // FAULT_LOG_A (SYSCTL_FAULT_LOG1) + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 7)), + kDIALOG_FAULT_LOG_RESET_IN_3 = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_2 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + // FAULT_LOG_B (SYSCTL_FAULT_LOG2) + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = FAULTLOG_FLAG_MAKE(1, (1 << 2)), + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = FAULTLOG_FLAG_MAKE(1, (1 << 1)), + kDIALOG_FAULT_LOG_NTC_SHDN = FAULTLOG_FLAG_MAKE(1, (1 << 0)), +}; + +// --------------------------------------------------------------------------- +// GPADC +// --------------------------------------------------------------------------- + + +enum { + kD2255_ADC_CONTROL_MUX_SEL_VDD_MAIN = 0, + kD2255_ADC_CONTROL_MUX_SEL_BRICK_ID = 1, + kD2255_ADC_CONTROL_MUX_SEL_SPARE0 = 2, + kD2255_ADC_CONTROL_MUX_SEL_APP_MUX_A = 3, + kD2255_ADC_CONTROL_MUX_SEL_APP_MUX_B = 4, + // ... + kD2255_ADC_CONTROL_MUX_SEL_VLDO1 = 18, + kD2255_ADC_CONTROL_MUX_SEL_ILDO1 = 19, + kD2255_ADC_CONTROL_MUX_SEL_VLDO2 = 20, + kD2255_ADC_CONTROL_MUX_SEL_ILDO2 = 21, + kD2255_ADC_CONTROL_MUX_SEL_VLDO3 = 22, + kD2255_ADC_CONTROL_MUX_SEL_ILDO3 = 23, + kD2255_ADC_CONTROL_MUX_SEL_VLDO4 = 24, + kD2255_ADC_CONTROL_MUX_SEL_ILDO4 = 25, + kD2255_ADC_CONTROL_MUX_SEL_VLDO5 = 26, + kD2255_ADC_CONTROL_MUX_SEL_ILDO5 = 26, + kD2255_ADC_CONTROL_MUX_SEL_VLDO6 = 28, + kD2255_ADC_CONTROL_MUX_SEL_ILDO6 = 29, + kD2255_ADC_CONTROL_MUX_SEL_VLDO7 = 30, + kD2255_ADC_CONTROL_MUX_SEL_ILDO7 = 31, + kD2255_ADC_CONTROL_MUX_SEL_VLDO8 = 32, + kD2255_ADC_CONTROL_MUX_SEL_ILDO8 = 33, + kD2255_ADC_CONTROL_MUX_SEL_VLDO9 = 34, + kD2255_ADC_CONTROL_MUX_SEL_ILDO9 = 35, + kD2255_ADC_CONTROL_MUX_SEL_VLDO10 = 36, + kD2255_ADC_CONTROL_MUX_SEL_ILDO10 = 37, + kD2255_ADC_CONTROL_MUX_SEL_VLDO11 = 38, + kD2255_ADC_CONTROL_MUX_SEL_ILDO11 = 39, + kD2255_ADC_CONTROL_MUX_SEL_VLDO12 = 40, + kD2255_ADC_CONTROL_MUX_SEL_ILDO12 = 41, + kD2255_ADC_CONTROL_MUX_SEL_VLDO13 = 42, + kD2255_ADC_CONTROL_MUX_SEL_ILDO13 = 43, + kD2255_ADC_CONTROL_MUX_SEL_VLDO14 = 44, + kD2255_ADC_CONTROL_MUX_SEL_ILDO14 = 45, + kD2255_ADC_CONTROL_MUX_SEL_VLDO15 = 46, + kD2255_ADC_CONTROL_MUX_SEL_ILDO15 = 47, + // ReatlimeClock + kD2255_ADC_CONTROL_MUX_SEL_VRTC = 50, + kD2255_ADC_CONTROL_MUX_SEL_IRTC = 51, + // high impedance external input + kD2255_ADC_CONTROL_MUX_SEL_ADC_IN = 82, + // NTCs + kD2255_ADC_CONTROL_MUX_SEL_TJNCT = 88, + kD2255_ADC_CONTROL_MUX_SEL_TCAL = 89, + kD2255_ADC_CONTROL_MUX_SEL_TDEV1 = 90, + kD2255_ADC_CONTROL_MUX_SEL_TDEV2 = 91, + kD2255_ADC_CONTROL_MUX_SEL_TDEV3 = 92, + kD2255_ADC_CONTROL_MUX_SEL_TDEV4 = 93, + // ... + // TINT, measure TDIE (TDIE1,TDIE11) + kD2255_ADC_CONTROL_MUX_SEL_LDO5_TEMP = 112, + kD2255_ADC_CONTROL_MUX_SEL_LDO10_TEMP = 113, + kD2255_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = 114, + kD2255_ADC_CONTROL_MUX_SEL_BUCK1_TEMP, + kD2255_ADC_CONTROL_MUX_SEL_BUCK2_TEMP, + kD2255_ADC_CONTROL_MUX_SEL_BUCK3_TEMP, + kD2255_ADC_CONTROL_MUX_SEL_BUCK4_TEMP, + kD2255_ADC_CONTROL_MUX_SEL_BUCK5_TEMP, + kD2255_ADC_CONTROL_MUX_SEL_BUCK6_TEMP, + kD2255_ADC_CONTROL_MUX_SEL_BUCK7_TEMP, + kD2255_ADC_CONTROL_MUX_SEL_BUCK8_TEMP = 122, + + kD2255_ADC_CONTROL_MUX_SEL_VBUCK0 = 144, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK1, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK2, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK3, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK4, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK5, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK6, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK7, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK8 = 152, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK0 = 176, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK1, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK2, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK3, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK4, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK5, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK6, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK7, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK8 = 184, + + kD2255_ADC_CONTROL_MUX_SEL_IBUCK0_OFF = 208, // offset + kD2255_ADC_CONTROL_MUX_SEL_IBUCK1_OFF, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK2_OFF, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK3_OFF, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK4_OFF, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK5_OFF, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK6_OFF, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK7_OFF, + kD2255_ADC_CONTROL_MUX_SEL_IBUCK8_OFF = 216, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK3_SW1 = 240, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK3_SW2, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK3_SW3, + kD2255_ADC_CONTROL_MUX_SEL_VBUCK4_SW1 = 243, + + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = kD2255_ADC_CONTROL_MUX_SEL_VDD_MAIN, + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = kD2255_ADC_CONTROL_MUX_SEL_BRICK_ID, + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = kD2255_ADC_CONTROL_MUX_SEL_TCAL, + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 5, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kD2255_ADC_CONTROL_MUX_SEL_LDO5_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kD2255_ADC_CONTROL_MUX_SEL_BUCK8_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = kD2255_ADC_CONTROL_MUX_SEL_TJNCT, + + // TODO: verify BRICK_ID_OFFSET + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, + +#if 0 + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 7), + kDIALOG_ADC_CONTROL2_IBUS_EN = (1 << 0), + kDIALOG_ADC_CONTROL2_ADC_REF_EN = (1 << 6), + kDIALOG_ADC_CONTROL2_AUTO_VDD_OUT_EN = (1 << 7), +#endif +}; + +enum { + +// kDIALOG_ADC_CONTROL_DEFAULTS = 0, +// kDIALOG_ADC_CONTROL2_DEFAULTS = 0, +// kDIALOG_ADC_CONTROL_ADC_REF_EN = 0, + + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 7), + kDIALOG_ADC_LSB_ADC_OVL = (1 << 6), + + kDIALOG_ADC_MAN_CTL = kD2255_GPADC_MAN_CTRL1, + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = kD2255_GPADC_MAN_CTRL1_MASK, + kDIALOG_ADC_LSB = kD2255_GPADC_MAN1_RES_LSB, + + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_RESOLUTION_BITS = 12, +}; + +#if 0 +enum { + kDIALOG_APP_TMUX_SEL_MASK = (7 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_0 = (0 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_1 = (1 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_2 = (2 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_3 = (3 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_4 = (4 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_5 = (5 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_6 = (6 << 0), + kDIALOG_APP_TMUX_SEL_AMUX_7 = (7 << 0), + KDIALOG_APP_TMUX_EN = (1 << 7), +}; +#endif + +// ------------------------------------------------ +// +// ------------------------------------------------ + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kD2255_GPIO_IO_CONFIG_IN = (0<<6), + kD2255_GPIO_IO_CONFIG_OUT_OD = (1<<6), + kD2255_GPIO_IO_CONFIG_OUT_PP = (2<<6), +// NOTE: Once a GPIO is set to a safe spare configuration, the safe spare setting must +// be changed before any changes to the associated GPIO_x_IO_TYPE, GPIOx_PUPD and +// GPIOx_WAKE_LVL register fields can be done. + kD2255_GPIO_IO_CONFIG_SAFE_SPARE = (3<<6), + + kD2255_GPIO_IO_TYPE_OUT_LVL = (0<<3), + kD2255_GPIO_IO_TYPE_OUT_32K = (1<<3), + kD2255_GPIO_IO_TYPE_OUT_nRST = (2<<3), + kD2255_GPIO_IO_TYPE_OUT_TEMP = (3<<3), + kD2255_GPIO_IO_TYPE_OUT_LVL2 = (4<<3), + kD2255_GPIO_IO_TYPE_IN_LEVEL_HIGH = (0<<3), + kD2255_GPIO_IO_TYPE_IN_LEVEL_LOW = (1<<3), + kD2255_GPIO_IO_TYPE_IN_EDGE_RISING = (2<<3), + kD2255_GPIO_IO_TYPE_IN_EDGE_FALLING = (3<<3), + kD2255_GPIO_IO_TYPE_IN_EDGE_ANY = (4<<3), + + kDIALOG_SYS_GPIO_CONFIG_MASK = (0x3<<6), + kDIALOG_SYS_GPIO_DIRECTION_MASK = (0x3<<3), + kDIALOG_SYS_GPIO_VALUE_MASK = (1<<0), + + kDIALOG_SYS_GPIO_DIRECTION_OUT = kD2255_GPIO_IO_TYPE_OUT_LVL, + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = kD2255_GPIO_IO_TYPE_OUT_32K, + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = kD2255_GPIO_IO_TYPE_IN_LEVEL_HIGH, + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = kD2255_GPIO_IO_TYPE_IN_LEVEL_LOW, + + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 0), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 0), + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 0), +}; + +// NOTE: it doesn't work with SAFESPARE +#define IS_GPIO_OUTPUT(gpio) \ + (((gpio)&kDIALOG_SYS_GPIO_CONFIG_MASK)!=kD2255_GPIO_IO_CONFIG_IN ) + +#define kDIALOG_STATUS_GPIO_MASK(gpio) \ + STATUS_FLAG_MAKE(6 + ((gpio)/8), (1 << ((gpio) % 8)) ) + +#define NUM_LDOS 29 +// NOTE: here bypass is the OFFSET of the bypass register from VSEL +static const struct ldo_params ldo_D2255[NUM_LDOS] = { + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO1_VSEL, kD2255_LDO1_EN, 1 }, // 00 - LDO1 = + { 1200, 5, 0xff, 0xff, 2, kD2255_LDO2_VSEL, kD2255_LDO2_EN, 1 }, // 01 - LDO2 = (Byp) + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO3_VSEL, kD2255_LDO3_EN, 1 }, // 02 - LDO3 = + { 600, 5, 0xff, 0xff, 0x00, kD2255_LDO4_VSEL, kD2255_LDO4_EN, 1 }, // 03 - LDO4 = + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO5_VSEL, kD2255_LDO5_EN, 1 }, // 04 - LDO5 = + { 1200, 25, 0x7f, 0x7f, 2, kD2255_LDO6_VSEL, kD2255_LDO6_EN, 1 }, // 05 - LDO6 = (Byp) + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO7_VSEL, kD2255_LDO7_EN, 1 }, // 06 - LDO7 = + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO8_VSEL, kD2255_LDO8_EN, 1 }, // 07 - LDO8 = + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO9_VSEL, kD2255_LDO9_EN, 1 }, // 08 - LDO9 = + { 600, 5, 0xff, 0xff, 0x00, kD2255_LDO10_VSEL, kD2255_LDO10_EN, 1 }, // 09 - LDO10 - + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO11_VSEL, kD2255_LDO11_EN, 1 }, // 0a - LDO11 = + { 1800, 0, 0, 0, 0x00, 0, 0, 0 }, // 0b - there is no LDO12 (PP1V8_ALWAYS) + { 2400, 5, 0xff, 0xff, 0x00, kD2255_LDO13_VSEL, kD2255_LDO13_EN, 1 }, // 0c - LDO13 = + { 600, 5, 0xff, 0xff, 0x00, kD2255_LDO14_VSEL, kD2255_LDO14_EN, 1 }, // 0d - LDO14 = + { 1200, 5, 0xff, 0xff, 2, kD2255_LDO15_VSEL, kD2255_LDO15_EN, 1 }, // 0e - LDO15 = (Byp) + + { 500, 5, 0, 0, 0x00, kD2255_BUCK0_VSEL, kD2255_BUCK0_EN, 1 }, // 0f - POWER_RAIL_CPU + { 500, 5, 0, 0, 0x00, kD2255_BUCK1_VSEL, kD2255_BUCK1_EN, 1 }, // 10 - POWER_RAIL_GPU + { 600, 5, 0, 0, 0x00, kD2255_BUCK2_VSEL, kD2255_BUCK2_EN, 1 }, // 11 - POWER_RAIL_SOC + { 1100, 5, 0, 0, 0x00, kD2255_BUCK3_VSEL, kD2255_BUCK3_EN, 1 }, // 12 + { 600, 5, 0, 0, 0x00, kD2255_BUCK4_VSEL, kD2255_BUCK4_EN, 1 }, // 13 + { 600, 5, 0, 0, 0x00, kD2255_BUCK5_VSEL, kD2255_BUCK5_EN, 1 }, // 14 - POWER_RAIL_VDD_FIXED + { 1100, 5, 0, 0, 8, kD2255_BUCK6_VSEL, kD2255_BUCK6_EN, 1 }, // 15 - BUCK6 (Byp) + { 600, 5, 0, 0, 0x00, kD2255_BUCK7_VSEL, kD2255_BUCK7_EN, 1 }, // 16 - POWER_RAIL_CPU_RAM + { 600, 5, 0, 0, 0x00, kD2255_BUCK8_VSEL, kD2255_BUCK8_EN, 1 }, // 17 - POWER_RAIL_GPU_RAM + + { 0, 0, 0, 0, 0x00, 0, kD2255_BUCK3_SW1_EN, 1 }, // 18 + { 0, 0, 0, 0, 0x00, 0, kD2255_BUCK3_SW2_EN, 1 }, // 19 + { 0, 0, 0, 0, 0x00, 0, kD2255_BUCK3_SW3_EN, 1 }, // 1a + { 0, 0, 0, 0, 0x00, 0, kD2255_BUCK4_SW1_EN, 1 }, // 1b + + { 0, 0, 0, 0, 0x00, 0, kD2255_LDO6_EN, 7<<1 }, // 1c +}; +#define LDOP ldo_D2255 + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_10MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_20MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_60MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + + kD2255_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD2255_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD2255_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kD2255_BUTTON_DBL_BTN4_DBL_EN = (1 << 6), + + // TODO: verify this! + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD2255_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD2255_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD2255_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif /* __DIALOG_D2255_H */ diff --git a/drivers/dialog/pmu/d2257.h b/drivers/dialog/pmu/d2257.h new file mode 100644 index 0000000..6acaf68 --- /dev/null +++ b/drivers/dialog/pmu/d2257.h @@ -0,0 +1,1521 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Specs at Aria: Specification and Data-sheet from Vendor (Dialog) +#ifndef __DIALOG_D2257_H +#define __DIALOG_D2257_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 0 +#define PMU_HAS_SPI 1 +// TODO: use single register alias (and a value alias) for HAS_SWI,HAS_DWI,HAS_SPI +#define PMU_HAS_LCM_LDO 0 +// TODO: add BIST ADC +#define PMU_HAS_BIST_ADC 0 +#define PMU_HAS_CHG_ABCC_FLAG 0 +#define PMU_HAS_VIB 0 +#define PMU_HAS_RAM 1 +// TODO: enable wled +#define PMU_HAS_WLED 1 +#define PMU_HAS_32K_RTC 1 +// TODO: enable accumulators +#define PMU_HAS_ACCUMULATORS 0 +#define PMU_HAS_GPIO_CONF 1 +#define PMU_HAS_SYS 1 +#define PMU_HAS_SCRATCH 1 +#define PMU_HAS_CHARGER 1 +#define PMU_HAS_PERF_STATES 1 +#define PMU_DRV_NEW_DRIVER 1 + +enum { + kDIALOG_ADDR_R = 0x79, + kDIALOG_ADDR_W = 0x78, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_FAULTLOG_COUNT = 2, // @0x0100 (read only the first 2) + kDIALOG_EVENT_COUNT = 0x1f, // @0x0140 + kDIALOG_STATUS_COUNT = 0x1f, // @0x0180 + kDIALOG_CHIPID_COUNT = 4, // @0x0000 + kDIALOG_GPIO_COUNT = 22, +}; + +#include "dCommon.h" + +enum { +// --------------------------------- +// Faultlog (virtual) +// --------------------------------- + kDIALOG_FAULT_LOG_A = 0x0100, + // ... + // kDIALOG_FAULT_LOG_R + +// --------------------------------- +// Event, Status ,IRQ Mask (Virtual) +// --------------------------------- + + kD2255_V_EVENT_AA = 0x0140, // 0 + kD2255_V_EVENT_AB = 0x0141, // 1 + kD2255_V_EVENT_AC = 0x0142, // 2 + kD2255_V_EVENT_AD = 0x0143, // 3 + kD2255_V_EVENT_AE = 0x0144, // 4 + kD2255_V_EVENT_AF = 0x0145, // 5 BTNs + kD2255_V_EVENT_AG = 0x0146, // 6 GPIO1-8 + kD2255_V_EVENT_AH = 0x0147, // 7 GPIO9-16 + kD2255_V_EVENT_AI = 0x0148, // 8 GPIO17-22 + kD2255_V_EVENT_AJ = 0x0149, // 9 VBUS/VCENTER + kD2255_V_EVENT_AK = 0x014a, // 10 + kD2255_V_EVENT_AL = 0x014b, // 11 + kD2255_V_EVENT_AM = 0x014c, // 12 + kD2255_V_EVENT_AN = 0x014d, // 13 + kD2255_V_EVENT_AO = 0x014e, // 14 + kD2255_V_EVENT_AP = 0x014f, // 15 + kD2255_V_EVENT_AQ = 0x0150, // 16 + kD2255_V_EVENT_AR = 0x0151, // 17 + kD2255_V_EVENT_AS = 0x0152, // 18 + kD2255_V_EVENT_AT = 0x0153, // 19 + kD2255_V_EVENT_AU = 0x0154, // 20 + kD2255_V_EVENT_AV = 0x0155, // 21 + kD2255_V_EVENT_AW = 0x0156, // 22 + kD2255_V_EVENT_AX = 0x0157, // 23 EOMC + kD2255_V_EVENT_AY = 0x0158, // 24 + kD2255_V_EVENT_AZ, + kD2255_V_EVENT_BA, + kD2255_V_EVENT_BB, + kD2255_V_EVENT_BC, + kD2255_V_EVENT_BD, + kD2255_V_EVENT_BE, + + kD2255_V_STATUS_AA = 0x0180, + // .... V_STATUS_Y + kD2255_V_STATUS_BE = 0x019e, + + + kD2255_V_IRQ_MASK_AA = 0x01c0, + // .... V_IRQ_MASK_Y + kD2255_V_IRQ_MASK_BE = 0x01de, + + kD2255_V_FAULTLOG_COUNT = 0x12, + kD2255_V_EVENT_COUNT = 0x1f, + kD2255_V_STATUS_COUNT = 0x1f, + + kDIALOG_EVENT_A = kD2255_V_EVENT_AA, + kDIALOG_STATUS_A = kD2255_V_STATUS_AA, + kDIALOG_IRQ_MASK_A = kD2255_V_IRQ_MASK_AA, +}; +// --------------------------------- +// Chip Identification +// --------------------------------- +enum { + kDIALOG_MASK_REV_CODE = 0x0200, + kDIALOG_TRIM_REL_CODE = 0x0201, + kDIALOG_PLATFORM_ID = 0x0202, + kDIALOG_DEVICE_ID1 = 0x0204, + kDIALOG_DEVICE_ID2 = 0x0205, + kDIALOG_DEVICE_ID3 = 0x0206, + kDIALOG_DEVICE_ID4 = 0x0207, + kDIALOG_DEVICE_ID5 = 0x0208, + kDIALOG_DEVICE_ID6 = 0x0209, + kDIALOG_DEVICE_ID7 = 0x020a, + + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, +}; + +// --------------------------------- +// System Control And Status +// --------------------------------- + +enum { + kD2257_APP_TMUX = 0x0212, +}; + +// --------------------------------- +// System Configuration +// --------------------------------- + +enum { + kD2257_SYSCTL_PRE_UVLO_CONF = 0x026b, +}; + +// --------------------------------- +// Faultlog +// --------------------------------- + +enum { + kD2257_FAULT_LOG1 = 0x02c0, + kD2257_FAULT_LOG2 = 0x02c1, + + kDIALOG_FAULT_LOG = kD2257_FAULT_LOG1, + kDIALOG_FAULT_LOG2 = kD2257_FAULT_LOG2, +}; + +// --------------------------------- +// Events. Status and IRQ Control +// --------------------------------- + +enum { + kD2257_SYSCTL_EVENT = 0x02d2, + kD2257_SYSCTL_STATUS = 0x02d3, + kD2257_SYSCTL_IRQ_MASK = 0x02d4, +}; + +// --------------------------------- +// Power Supply Control +// Active,Standby,Hibernate are now encoded here, need TestAccess +// --------------------------------- +enum { + kD2257_PWRONOFF_BUCK0_EN = 0x0300, + kD2257_PWRONOFF_BUCK1_EN = 0x0301, + kD2257_PWRONOFF_BUCK2_EN = 0x0302, + kD2257_PWRONOFF_BUCK3_EN = 0x0303, + kD2257_PWRONOFF_BUCK4_EN = 0x0304, + kD2257_PWRONOFF_BUCK5_EN = 0x0305, + kD2257_PWRONOFF_BUCK6_EN = 0x0306, + kD2257_PWRONOFF_BUCK7_EN = 0x0307, + kD2257_PWRONOFF_BUCK8_EN = 0x0308, + + kD2257_PWRONOFF_WLEDA_EN = 0x0309, + kD2257_PWRONOFF_WLEDB_EN = 0x030A, + + kD2257_PWRONOFF_LDO1_EN = 0x030b, + kD2257_PWRONOFF_LDO2_EN = 0x030c, + kD2257_PWRONOFF_LDO3_EN = 0x030d, + kD2257_PWRONOFF_LDO4_EN = 0x030e, + kD2257_PWRONOFF_LDO5_EN = 0x030f, + kD2257_PWRONOFF_LDO6_EN = 0x0310, + kD2257_PWRONOFF_LDO7_EN = 0x0311, + kD2257_PWRONOFF_LDO8_EN = 0x0312, + kD2257_PWRONOFF_LDO9_EN = 0x0313, + kD2257_PWRONOFF_LDO10_EN = 0x0314, + kD2257_PWRONOFF_LDO11_EN = 0x0315, + kD2257_PWRONOFF_LDO13_EN = 0x0316, + kD2257_PWRONOFF_LDO14_EN = 0x0317, + kD2257_PWRONOFF_LDO15_EN = 0x0318, + kD2257_PWRONOFF_LDO16_EN = 0x0319, + + kD2257_PWRONOFF_LCM_BST_SW_EN = 0x031a, + kD2257_PWRONOFF_LCM_BST_EN = 0x031b, + kD2257_PWRONOFF_LCM_LDO1_EN = 0x031c, + kD2257_PWRONOFF_LCM_LDO2_EN = 0x031d, + + kD2257_PWRONOFF_CP_EN = 0x031e, + + kD2257_PWRONOFF_BUCK3_SW1_EN = 0x031f, + kD2257_PWRONOFF_BUCK3_SW2_EN = 0x0320, + kD2257_PWRONOFF_BUCK3_SW3_EN = 0x0321, + kD2257_PWRONOFF_BUCK4_SW1_EN = 0x0322, + kD2257_PWRONOFF_BUCK4_SW2_EN = 0x0323, + + kD2257_PWRONOFF_GPIO_32K_EN = 0x0324, + kD2257_PWRONOFF_OUT_32K_EN = 0x0325, + kD2257_PWRONOFF_SLEEP_32K_EN = 0x0326, + kD2257_PWRONOFF_NRESET_EN = 0x0327, + kD2257_PWRONOFF_SYS_ALIVE_EN = 0x0328, + kD2257_PWRONOFF_PRE_UVLO_EN = 0x0329, + + kDIALOG_PWRONOFF_WLEDA_EN = kD2257_PWRONOFF_WLEDA_EN, + kDIALOG_PWRONOFF_WLEDB_EN = kD2257_PWRONOFF_WLEDB_EN +}; + +// --------------------------------- +// Main FSM, MFSM Events +// --------------------------------- + +enum { + kD2257_MFSM_CTRL = 0x0400, + kD2257_ACT_TO_SLEEP3_DLY = 0x0401, + kD2257_ACT_TO_OFF_DLY = 0x0402, + kD2257_OFF_TIMER_DLY = 0x0403, + kD2257_SLEEP3_TIMER_DLY = 0x0404, + kD2257_MFSM_CONF1 = 0x0460, + + kD2257_MFSM_CTRL_PERF_FLOOR_OFF = (0<<2), + kD2257_MFSM_CTRL_PERF_FLOOR_SLEEP3 = (1<<2), + kD2257_MFSM_CTRL_PERF_FLOOR_SLEEP2 = (2<<2), + kD2257_MFSM_CTRL_PERF_FLOOR_ACTIVE = (3<<2), + kD2257_MFSM_CTRL_FORCE_SLEEP3 = (1<<1), + kD2257_MFSM_CTRL_FORCE_OFF = (1<<0), + + kDIALOG_SYS_CONTROL_PERF_FLOOR_OFF = kD2257_MFSM_CTRL_PERF_FLOOR_OFF, + kDIALOG_SYS_CONTROL_PERF_FLOOR_SLEEP3 = kD2257_MFSM_CTRL_PERF_FLOOR_SLEEP3, + kDIALOG_SYS_CONTROL_PERF_FLOOR_SLEEP2 = kD2257_MFSM_CTRL_PERF_FLOOR_SLEEP2, + kDIALOG_SYS_CONTROL_PERF_FLOOR_ACTIVE = kD2257_MFSM_CTRL_PERF_FLOOR_ACTIVE, + kDIALOG_SYS_CONTROL_PERF_FLOOR_MASK = (0x3<<2), + + kDIALOG_SYS_CONTROL_HIBERNATE = kD2257_MFSM_CTRL_FORCE_SLEEP3, + kDIALOG_SYS_CONTROL_STANDBY = kD2257_MFSM_CTRL_FORCE_OFF, + // TODO: verify this + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = kDIALOG_SYS_CONTROL_HIBERNATE, + + kDIALOG_SYS_CONTROL = kD2257_MFSM_CTRL, +}; + +// --------------------------------- +// RTC Calendar and Clock, Events +// --------------------------------- + +enum { + kDIALOG_RTC_CONTROL = 0x0500, + kDIALOG_RTC_TIMEZONE = 0x0501, + kDIALOG_RTC_SUB_SECOND_A = 0x0502, + kDIALOG_RTC_SUB_SECOND_B = 0x0503, + kDIALOG_RTC_SECOND_A = 0x0504, + kDIALOG_RTC_SECOND_B = 0x0505, + kDIALOG_RTC_SECOND_C = 0x0506, + kDIALOG_RTC_SECOND_D = 0x0507, + kDIALOG_RTC_ALARM_A = 0x0508, + kDIALOG_RTC_ALARM_B = 0x0509, + kDIALOG_RTC_ALARM_C = 0x050a, + kDIALOG_RTC_ALARM_D = 0x050b, + +// Events. Status. Mask in Virtual +// kD2255_RTC_EVENT = 0x05c0, +// kD2255_RTC_STATUS = 0x05c1, +// kD2255_RTC_IRQ_MASK = 0x05c2, +}; + +// --------------------------------- +// SPI Interface +// --------------------------------- + +enum { + kD2257_SPI_CTRL = 0x0600, // global enable + kD2257_EN_CMD0 = 0x0601, // buck#_spi_en + kD2257_EN_CMD1 = 0x0602, + kD2257_EN_CMD2 = 0x0603, // wled spi access enable + kD2257_EN_CMD3 = 0x0604, // buck#_spi_dis_master + kD2257_EN_CMD4 = 0x0605, + kD2257_SPI_CONFIG = 0x0660, + + // set when PMU_HAS_SPI + kDIALOG_SPI_CONTROL = kD2257_SPI_CTRL, + kDIALOG_SPI_CONTROL_SPI_EN = 1, +}; + +// --------------------------------- +// Clock Generation +// --------------------------------- + +enum { + kD2257_SYS_CTRL_CONF0 = 0x0700, + kD2257_SYS_CTRL_CONF1 = 0x0760, + kD2257_RTC_CTRL0 = 0x0761, + kD2257_RTC_CTRL1 = 0x0762, + kD2257_RTC_CTRL2 = 0x0763, + kD2257_OSC_CTRL0 = 0x0764, + kD2257_INT_OSC_TRIM = 0x0765, + kD2257_CLK_REQ_FRC = 0x0766, + kD2257_BG_CTRL = 0x0767, + + kD2257_CKLGEN_EVENT = 0x07c0, + kD2257_CKLGEN_STATUS = 0x07c1, + kD2257_CKLGEN_IRQ_MASK = 0x07c2, +}; + +// --------------------------------- +// WLED +// --------------------------------- + +enum { + kD2257_WLED_ISET_LSB = 0x0b00, + kD2257_WLED_ISET_MSB = 0x0b01, + kD2257_WLED_PWM_LSB = 0x0b02, + kD2257_WLED_PWM_MSB = 0x0b03, + kD2257_WLED_CTRL1 = 0x0b04, + kD2257_WLED_CTRL2 = 0x0b05, + kD2257_WLED_CTRL3 = 0x0b06, + kD2257_WLED_CTRL4 = 0x0b07, + kD2257_WLED_CTRL4A = 0x0b08, + kD2257_WLED_CTRL5 = 0x0b09, + kD2257_WLED_CTRL6 = 0x0b0a, + + kDIALOG_WLED_ISET = kD2257_WLED_ISET_MSB, + kDIALOG_WLED_ISET2 = kD2257_WLED_ISET_LSB, + kDIALOG_WLED_CONTROL = kD2257_WLED_CTRL1, + kDIALOG_WLED_CONTROL1 = kD2257_WLED_CTRL1, + kDIALOG_WLED_CONTROL2 = kD2257_WLED_CTRL2, + kDIALOG_WLED_DWI_CONTROL= kD2257_WLED_CTRL2, + kDIALOG_WLED_OPTIONS = kD2257_WLED_CTRL2, +}; + +enum { + kDIALOG_WLED_CONTROL_WLED_ENABLE1 = (1 << 0), + kDIALOG_WLED_CONTROL_WLED_ENABLE2 = (1 << 1), + kDIALOG_WLED_CONTROL_WLED_ENABLE3 = (1 << 2), + kDIALOG_WLED_CONTROL_WLED_ENABLE4 = (1 << 3), + kDIALOG_WLED_CONTROL_WLED_ENABLE5 = (1 << 4), + kDIALOG_WLED_CONTROL_WLED_ENABLE6 = (1 << 5), +}; + +enum { + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN = (1 << 3), + kDIALOG_WLED_CONTROL2_WLED_DITH_EN = (1 << 2), + kDIALOG_WLED_CONTROL2_WLED_DWI_EN = (1 << 1), + kDIALOG_WLED_CONTROL2_WLED_RAMP_EN = (1 << 0), + + kDIALOG_WLED_CONTROL_WLED_DWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + + kDIALOG_WLED_OPTIONS_DEFAULT = kDIALOG_WLED_CONTROL2_WLED_DITH_EN, + kDIALOG_WLED_OPTIONS_xWI_EN = kDIALOG_WLED_CONTROL2_WLED_DWI_EN, + kDIALOG_WLED_OPTIONS_MASK = (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_EN| + kDIALOG_WLED_CONTROL2_WLED_DITH_RAMP_EN), +}; + +#define WLED_ISET_BITS 11 + +// --------------------------------- +// GPIO configuration +// --------------------------------- + +enum { + kD2257_GPIO1_CONF1 = 0x0900, + kD2257_GPIO1_CONF2 = 0x0901, + kD2257_GPIO2_CONF1, + kD2257_GPIO2_CONF2, + kD2257_GPIO3_CONF1, + kD2257_GPIO3_CONF2, + kD2257_GPIO4_CONF1, + kD2257_GPIO4_CONF2, + kD2257_GPIO5_CONF1, + kD2257_GPIO5_CONF2, + kD2257_GPIO6_CONF1, + kD2257_GPIO6_CONF2, + kD2257_GPIO7_CONF1, + kD2257_GPIO7_CONF2, + kD2257_GPIO8_CONF1, + kD2257_GPIO8_CONF2, + kD2257_GPIO9_CONF1, + kD2257_GPIO9_CONF2, + kD2257_GPIO10_CONF1, + kD2257_GPIO10_CONF2, + kD2257_GPIO11_CONF1, + kD2257_GPIO11_CONF2, + kD2257_GPIO12_CONF1, + kD2257_GPIO12_CONF2, + kD2257_GPIO13_CONF1, + kD2257_GPIO13_CONF2, + kD2257_GPIO14_CONF1, + kD2257_GPIO14_CONF2, + kD2257_GPIO15_CONF1, + kD2257_GPIO15_CONF2, + kD2257_GPIO16_CONF1, + kD2257_GPIO16_CONF2, + kD2257_GPIO17_CONF1, + kD2257_GPIO17_CONF2, + kD2257_GPIO18_CONF1, + kD2257_GPIO18_CONF2, + kD2257_GPIO19_CONF1_SLP1 = 0x0924, + kD2257_GPIO19_CONF1_SLP2, + kD2257_GPIO19_CONF1_SLP3, + kD2257_GPIO19_CONF1_OFF, + kD2257_GPIO19_CONF1, + kD2257_GPIO19_CONF2, + kD2257_GPIO20_CONF1_SLP1 = 0x092A, + kD2257_GPIO20_CONF1_SLP2, + kD2257_GPIO20_CONF1_SLP3, + kD2257_GPIO20_CONF1_OFF, + kD2257_GPIO20_CONF1, + kD2257_GPIO20_CONF2, + kD2257_GPIO21_CONF1_SLP1 = 0x0930, + kD2257_GPIO21_CONF1_SLP2, + kD2257_GPIO21_CONF1_SLP3, + kD2257_GPIO21_CONF1_OFF, + kD2257_GPIO21_CONF1, + kD2257_GPIO21_CONF2, + kD2257_GPIO22_CONF1_SLP1 = 0x0936, + kD2257_GPIO22_CONF1_SLP2, + kD2257_GPIO22_CONF1_SLP3, + kD2257_GPIO22_CONF1_OFF, + kD2257_GPIO22_CONF1, + kD2257_GPIO22_CONF2, + kDIALOG_SYS_GPIO_REG_START = kD2257_GPIO1_CONF1, + +// until GPIO21_CONF1, GPIO21_CONF2 ... kDIALOG_GPIO_COUNT gpios + + kD2257_OUT_32K = 0x093c, + kD2257_SLEEP_32K = 0x093d, + kD2257_ACTIVE_RDY = 0x093e, + kD2257_SLEEP1_RDY = 0x093f, + +// GPI Control + kD2257_BUTTON1_CONF = 0x0960, + kD2257_BUTTON2_CONF = 0x0961, + kD2257_BUTTON3_CONF = 0x0962, + kD2257_BUTTON4_CONF = 0x0963, + kD2257_BUTTON_DBL = 0x0964, + kD2257_BUTTON_WAKE = 0x0965, + + kD2257_RESET_IN1_CONF1 = 0x0966, + kD2257_RESET_IN1_CONF2 = 0x0967, + kD2257_RESET_IN2_CONF1 = 0x0968, + kD2257_RESET_IN2_CONF2 = 0x0969, + kD2257_RESET_IN3_CONF1 = 0x096a, + kD2257_RESET_IN3_CONF2 = 0x096b, + + kDIALOG_BUTTON_DBL = kD2257_BUTTON_DBL, +}; + +// --------------------------------- +// Event,Status,IRQ Control +// --------------------------------- + +enum { + kD2257_IO_EVENT_A = 0x09c0, + kD2257_IO_EVENT_B = 0x09c1, + kD2257_IO_EVENT_C = 0x09c2, + kD2257_IO_EVENT_D = 0x09c3, + + kD2257_IO_STATUS_A = 0x09c4, + kD2257_IO_STATUS_B = 0x09c5, + kD2257_IO_STATUS_C = 0x09c6, + kD2257_IO_STATUS_D = 0x09c7, + + kD2257_IO_IRQ_MASK_A = 0x09c8, + kD2257_IO_IRQ_MASK_B = 0x09c9, + kD2257_IO_IRQ_MASK_C = 0x09ca, + kD2257_IO_IRQ_MASK_D = 0x09cb, +}; + +// --------------------------------- +// Charger / Charging Control +// --------------------------------- + +enum { + kD2257_CHG_CONTROL = 0xa00, + kD2257_SYS_CONF_B = 0xa01, + kD2257_SYS_CONF_D = 0xa02, + + kD2257_ISET_BUCK = 0x0a03, + kD2257_ISET_BUCK_SHADOW = 0x0a04, + kD2257_ISET_BUCK_ABSMAX = 0x0a05, + kD2257_ISET_BUCK_ACTUAL = 0x0a06, + kD2257_ISET_BUCK_ALT = 0x0a07, + kD2257_ICHG_BAT = 0x0a08, + + kD2257_CHG_CTRL_A = 0x0a0a, + kD2257_CHG_CTRL_B = 0x0a0b, + kD2257_CHG_CTRL_C = 0x0a0c, + kD2257_CHG_CTRL_D = 0x0a0d, + kD2257_CHG_CTRL_E = 0x0a0e, + kD2257_CHG_CTRL_F = 0x0a0f, + kD2257_CHG_CTRL_G = 0x0a10, + kD2257_CHG_CTRL_H = 0x0a11, + kD2257_CHG_TIME = 0x0a12, + kD2257_CHG_TIME_PRE = 0x0a13, + kD2257_CHG_STAT = 0x0a14, + +// kD2207_CHG_VSET_TRIM = 0x04d0, +// kD2207_IBUS_GAIN_TRIM = 0x04d2, +// kD2207_IBUS100_OFS_TRIM = 0x04d3, +// kD2207_IBUS500_OFS_TRIM = 0x04d4, +// kD2207_IBUS1500_GAIN_TRIM= 0x04d5, +// kD2207_IBUS1500_OFS_TRIM= 0x04d6, + + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = (1 << 1), + kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND = (1 << 0), + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND + | kDIALOG_SYS_CONTROL_BUS_PWR_SUSPEND, + + kDIALOG_CHARGE_BUCK_CONTROL = kD2257_ISET_BUCK, + kDIALOG_CHARGE_BUCK_STATUS = kD2257_ISET_BUCK_ACTUAL, + kDIALOG_CHARGE_STATUS = kD2257_CHG_STAT, + + kDIALOG_CHARGE_CONTROL_ICHG_BAT = kD2257_ICHG_BAT, + kDIALOG_CHARGE_CONTROL_HIB = kD2257_CHG_CTRL_B, + kDIALOG_CHARGE_CONTROL_TIME = kD2257_CHG_CTRL_D, + kDIALOG_CHARGE_CONTROL_EN = kD2257_CHG_CTRL_G, + kDIALOG_OTP_ISET_BAT = kD2257_CHG_CTRL_C, +}; + +// --------------------------------- +// IPEAK +// --------------------------------- + +enum { + kD2257_IPK_UV_BUCK1_IPEAK_ANA_CONF_2 = 0x0f87, + kD2257_IPK_UV_BUCK1_UV_DIG_CONF_1 = 0x0f8a, + kD2257_IPK_UV_BUCK1_UV_EN_THR = 0x0f8c, + kD2257_IPK_UV_BUCK1_UV_ANA_CONF_1 = 0x0f8d, + kD2257_IPK_UV_BUCK1_UV_OFFSET = 0x0f8e, +}; + +// --------------------------------- +// Buck control +// --------------------------------- + +enum { + kD2257_BUCK0_FAST_VSEL = 0x1000, + kD2257_BUCK0_VSEL = 0x1001, + kD2257_BUCK0_FAST_VSEL_EN = 0x1002, + kD2257_BUCK0_VSEL_ACTUAL = 0x1005, + kD2257_BUCK0_VSEL_LOCK = 0x1006, + kD2257_BUCK0_MINV, + kD2257_BUCK0_MAXV, + kD2257_BUCK0_OFS_V, + kD2257_BUCK0_MODE = 0x100a, + kD2257_BUCK0_FSM_TRIM6 = 0x1067, + kD2257_BUCK0_FSM_TRIM7 = 0x1068, + + kD2257_BUCK1_FAST_VSEL = 0x1100, + kD2257_BUCK1_VSEL = 0x1101, + kD2257_BUCK1_FSM_TRIM6 = 0x1167, + kD2257_BUCK1_FSM_TRIM7 = 0x1168, + + kD2257_BUCK2_FAST_VSEL = 0x1200, + kD2257_BUCK2_VSEL = 0x1201, + kD2257_BUCK2_FSM_TRIM6 = 0x1267, + kD2257_BUCK2_FSM_TRIM7 = 0x1268, + + kD2257_BUCK3_FAST_VSEL = 0x1300, + kD2257_BUCK3_VSEL = 0x1301, + kD2257_BUCK3_FSM_TRIM6 = 0x1367, + kD2257_BUCK3_FSM_TRIM7 = 0x1368, + + kD2257_BUCK4_FAST_VSEL = 0x1400, + kD2257_BUCK4_VSEL = 0x1401, + kD2257_BUCK4_FSM_TRIM6 = 0x1467, + kD2257_BUCK4_FSM_TRIM7 = 0x1468, + + kD2257_BUCK5_FAST_VSEL = 0x1500, + kD2257_BUCK5_VSEL = 0x1501, + kD2257_BUCK5_FSM_TRIM6 = 0x1567, + kD2257_BUCK5_FSM_TRIM7 = 0x1568, + + kD2257_BUCK6_FAST_VSEL = 0x1600, + kD2257_BUCK6_VSEL = 0x1601, + kD2257_BUCK6_FSM_TRIM6 = 0x1667, + kD2257_BUCK6_FSM_TRIM7 = 0x1668, + + kD2257_BUCK7_FAST_VSEL = 0x1700, + kD2257_BUCK7_VSEL = 0x1701, + kD2257_BUCK7_FSM_TRIM6 = 0x1767, + kD2257_BUCK7_FSM_TRIM7 = 0x1768, + + kD2257_BUCK8_FAST_VSEL = 0x1800, + kD2257_BUCK8_VSEL = 0x1801, + kD2257_BUCK8_FSM_TRIM6 = 0x1867, + kD2257_BUCK8_FSM_TRIM7 = 0x1868, + + // LDO control... + kD2257_LDO1_VSEL = 0x2100, + kD2257_LDO1_VSEL_ACTUAL = 0x2101, + kD2257_LDO1_MINV = 0x2160, + kD2257_LDO1_MAXV = 0x2161, + kD2257_LDO1_UOV_LIM_EN_VOUT_PD= 0x2163, + + kD2257_LDO2_VSEL = 0x2200, + kD2257_LDO2_VSEL_ACTUAL = 0x2201, + kD2257_LDO2_BYPASS = 0x2202, + kD2257_LDO2_MINV = 0x2260, + kD2257_LDO2_MAXV = 0x2261, + + kD2257_LDO3_VSEL = 0x2300, + kD2257_LDO3_VSEL_ACTUAL = 0x2301, + kD2257_LDO3_MINV = 0x2360, + kD2257_LDO3_MAXV = 0x2361, + + kD2257_LDO4_VSEL = 0x2400, + kD2257_LDO4_VSEL_ACTUAL = 0x2401, + kD2257_LDO4_MINV = 0x2460, + kD2257_LDO4_MAXV = 0x2461, + + kD2257_LDO5_VSEL = 0x2500, + kD2257_LDO5_VSEL_ACTUAL = 0x2501, + kD2257_LDO5_MINV = 0x2560, + kD2257_LDO5_MAXV = 0x2561, + + kD2257_LDO6_VSEL = 0x2600, + kD2257_LDO6_VSEL_ACTUAL = 0x2601, + kD2257_LDO6_BYPASS = 0x2602, + kD2257_LDO6_MINV = 0x2660, + kD2257_LDO6_MAXV = 0x2661, + + kD2257_LDO7_VSEL = 0x2700, + kD2257_LDO7_VSEL_ACTUAL = 0x2701, + kD2257_LDO7_MINV = 0x2760, + kD2257_LDO7_MAXV = 0x2761, + kD2257_LDO7_SOFT_STARTUP = 0x2764, + + kD2257_LDO8_VSEL = 0x2800, + kD2257_LDO8_VSEL_ACTUAL = 0x2801, + kD2257_LDO8_MINV = 0x2860, + kD2257_LDO8_MAXV = 0x2861, + + kD2257_LDO9_VSEL = 0x2900, + kD2257_LDO9_VSEL_ACTUAL = 0x2901, + kD2257_LDO9_MINV = 0x2960, + kD2257_LDO9_MAXV = 0x2961, + kD2257_LDO9_TRIM = 0x2962, + + kD2257_LDO10_VSEL = 0x2A00, + kD2257_LDO10_VSEL_ACTUAL = 0x2A01, + kD2257_LDO10_MINV = 0x2A60, + kD2257_LDO10_MAXV = 0x2A61, + kD2257_LDO10_TRIM = 0x2A62, + + kD2257_LDO11_VSEL = 0x2B00, + kD2257_LDO11_VSEL_ACTUAL = 0x2B01, + kD2257_LDO11_MINV = 0x2B60, + kD2257_LDO11_MAXV = 0x2B61, + kD2257_LDO11_TRIM = 0x2B62, + + kD2257_LDO12_TRIM = 0x2C62, + + kD2257_LDO13_VSEL = 0x2D00, + kD2257_LDO13_VSEL_ACTUAL = 0x2D01, + kD2257_LDO13_MINV = 0x2D60, + kD2257_LDO13_MAXV = 0x2D61, + kD2257_LDO13_TRIM = 0x2D62, + + kD2257_LDO14_VSEL = 0x2E00, + kD2257_LDO14_VSEL_ACTUAL = 0x2E01, + kD2257_LDO14_MINV = 0x2E60, + kD2257_LDO14_MAXV = 0x2E61, + kD2257_LDO14_TRIM = 0x2E62, + + kD2257_LDO15_VSEL = 0x2F00, + kD2257_LDO15_VSEL_ACTUAL = 0x2F01, + kD2257_LDO15_BYPASS = 0x2F02, + kD2257_LDO15_MINV = 0x2F60, + kD2257_LDO15_MAXV = 0x2F61, + kD2257_LDO15_TRIM = 0x2F62, + + kD2257_LDO16_VSEL = 0x3000, + kD2257_LDO16_VSEL_ACTUAL = 0x3001, + kD2257_LDO16_MINV = 0x3060, + kD2257_LDO16_MAXV = 0x3061, + kD2257_LDO16_TRIM = 0x3062, + + kD2257_LDO_LCM_LDO1_VSEL = 0x3200, + kD2257_LDO_LCM_LDO1_VSEL_ACTUAL = 0x3201, + + kD2257_LDO_LCM_LDO2_VSEL = 0x3300, + kD2257_LDO_LCM_LDO2_VSEL_ACTUAL = 0x3301, + + kD2257_LDO_LCM_BOOST_VSEL = 0x3700, + kD2257_LDO_LCM_BOOST_VSEL_ACTUAL = 0x3701, + kD2257_LDO_LCM_BOOST_VSEL_MINV = 0x3760, + kD2257_LDO_LCM_BOOST_VSEL_MAXV = 0x3761, + kD2257_LDO_LCM_BOOST_CONF = 0x3762, + + kD2257_LDO_EVENT = 0x3FC0, + kD2257_LDO_STATUS = 0x3FC1, + kD2257_LDO_IRQ_MASK = 0x3FC2, + + kDIALOG_BYPASS_EN = 1, + kDIALOG_BYPASS_DIS = 0, +}; + +// --------------------------------- +// GPADC control +// --------------------------------- + +enum { + kD2257_GPADC_MAN_CTRL1 = 0x4000, // Channel 0..253 (0xfd) + kD2257_GPADC_MAN_CTRL1_MASK = 0xff, + kD2257_GPADC_MAN1_RES_LSB = 0x4001, + kD2257_GPADC_MAN1_RES_MSB = 0x4002, + + kD2257_GPADC_MAN_CTRL2 = 0x4004, // Channel 0..127 (0x7f) + kD2257_GPADC_MAN_CTRL2_MASK = 0x7F, + kD2257_GPADC_MAN2_RES_LSB = 0x4005, + kD2257_GPADC_MAN2_RES_MSB = 0x4006, + + kD2257_GPADC_ICHG_AVG = 0x40f8, + // mapped on (kADC_AVG|kD2257_ADC_CONTROL_MUX_SEL_ICH_ADC_CH) known as kDIALOG_ICHG_AVG + + kD2257_GPADC_TDIE1_RISE = 0x413c, + // .. + kD2257_GPADC_TDIE9_RISE = 0x4147, + + kDIALOG_T_OFFSET_MSB = 0x4148, + kDIALOG_T_OFFSET_LSB = 0x4149, // [0-3] + + kD2257_GPADC_EVENT0 = 0x4180, + kD2257_GPADC_EVENT1 = 0x4181, + kD2257_GPADC_STATUS0 = 0x4187, + kD2257_GPADC_STATUS1 = 0x4188, +}; + +enum { + kDIALOG_APP_TMUX = kD2257_APP_TMUX, +#if 0 + kDIALOG_BIST_ADC_CTRL = 0x0541, + kDIALOG_BIST_ADC_LSB = 0x0542, + kDIALOG_BIST_ADC_MSB = 0x0543, + kD2186_BIST_ADC_TRIM1 = 0x0545, + kD2186_BIST_ADC_ANA_TRIM0 = 0x0546, + + kD2186_SPARE_RW0 = 0x0680, + kD2186_SPARE_RW_LAST = 0x0687, + kD2186_SPARE_RWTOTP0 = 0x06a0, + kD2186_SPARE_RWTOTP_LAST = 0x06a7, + kD2186_SPARE_RWOTP0 = 0x06c0, + kD2186_SPARE_RWOTP1 = 0x06c1, +#endif +}; + +// --------------------------------- +// RAM/TEST/SCRATCH +// --------------------------------- + +enum { + // Legacy Scratch Pads + kDIALOG_MEMBYTE0 = 0x5000, + kDIALOG_MEMBYTE_LAST = 0x5027, + + kDIALOG_TEST_ACCESS = 0x7000, + kDIALOG_TEST_ACCESS_ENA = 0x1D, + kDIALOG_TEST_ACCESS_DIS = 0x00, + + // Scratch Pad RAM + kDIALOG_RAM0 = 0x8000, + kDIALOG_RAM_LAST = 0x87ff, + + kDIALOG_EXT_MEM_CAL0_SIZE = 64, + kDIALOG_GAP_SCRATCH8_SIZE = 8, // ex diags, free now + kDIALOG_EXT_MEM_CAL1_SIZE = 336, + kDIALOG_VOLTAGE_KNOBS_SIZE = 32, + kDIALOG_EXT_MEM_CAL2_SIZE = 400, // + // ... + kDIALOG_DIAG_SCRATCH_SIZE = 32, + + kDIALOG_EXT_MEM_CAL0 = kDIALOG_RAM0, + kDIALOG_EXT_MEM_CAL1 = kDIALOG_EXT_MEM_CAL0+kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_GAP_SCRATCH8_SIZE, + kDIALOG_VOLTAGE_KNOBS = kDIALOG_EXT_MEM_CAL1+kDIALOG_EXT_MEM_CAL1_SIZE, + kDIALOG_EXT_MEM_CAL2 = kDIALOG_VOLTAGE_KNOBS+kDIALOG_VOLTAGE_KNOBS_SIZE, + // reserved, future + kDIALOG_DIAG_SCRATCH = 0x87e0, + + // handy + kDIALOG_EXT_MEM_CAL_SIZE = kDIALOG_EXT_MEM_CAL0_SIZE+kDIALOG_EXT_MEM_CAL1_SIZE+kDIALOG_EXT_MEM_CAL2_SIZE, +}; + +#if 0 +// TODO: Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 2, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, +}; +#endif + +enum { +// Event Registers + + // 0: SYSCTL_EVENT + kD2257_EVENT_HIGH_TEMP_WARNING = (1 << 0), + // 1: MFSM_EVENT + // 2: RTC_EVENT + kD2257_EVENT_ALARM = (1 << 0), + // 3: SPI_EVENT + // 4: CLKGEN_EVENT + // 5: IO_EVENT_A + kD2257_EVENT_A_BUTTON4_DBL = (1 << 7), + kD2257_EVENT_A_BUTTON3_DBL = (1 << 6), + kD2257_EVENT_A_BUTTON2_DBL = (1 << 5), + kD2257_EVENT_A_BUTTON1_DBL = (1 << 4), + kD2257_EVENT_A_BUTTON4 = (1 << 3), + kD2257_EVENT_A_BUTTON3 = (1 << 2), + kD2257_EVENT_A_BUTTON2 = (1 << 1), + kD2257_EVENT_A_BUTTON1 = (1 << 0), + // 6: IO_EVENT_B + kD2257_EVENT_B_GPIO8 = (1 << 7), + kD2257_EVENT_B_GPIO7 = (1 << 6), + kD2257_EVENT_B_GPIO6 = (1 << 5), + kD2257_EVENT_B_GPIO5 = (1 << 4), + kD2257_EVENT_B_GPIO4 = (1 << 3), + kD2257_EVENT_B_GPIO3 = (1 << 2), + kD2257_EVENT_B_GPIO2 = (1 << 1), + kD2257_EVENT_B_GPIO1 = (1 << 0), + // 7: IO_EVENT_C + kD2257_EVENT_C_GPIO16 = (1 << 7), + kD2257_EVENT_C_GPIO15 = (1 << 6), + kD2257_EVENT_C_GPIO14 = (1 << 5), + kD2257_EVENT_C_GPIO13 = (1 << 4), + kD2257_EVENT_C_GPIO12 = (1 << 3), + kD2257_EVENT_C_GPIO11 = (1 << 2), + kD2257_EVENT_C_GPIO10 = (1 << 1), + kD2257_EVENT_C_GPIO9 = (1 << 0), + // 8: IO_EVENT_D + kD2257_EVENT_D_GPIO22 = (1 << 5), + kD2257_EVENT_D_GPIO21 = (1 << 4), + kD2257_EVENT_D_GPIO20 = (1 << 3), + kD2257_EVENT_D_GPIO19 = (1 << 2), + kD2257_EVENT_D_GPIO18 = (1 << 1), + kD2257_EVENT_D_GPIO17 = (1 << 0), + // 9: CHG_EVENT_T1 + kD2257_EVENT_CHG1_VBUS_OV = (1 << 6), + kD2257_EVENT_CHG1_VBUS_OC = (1 << 5), + kD2257_EVENT_CHG1_VBUS_EXT_REM = (1 << 4), + kD2257_EVENT_CHG1_CHG_HV_ATT = (1 << 3), + kD2257_EVENT_CHG1_VBUS_EXT_DET = (1 << 1), + kD2257_EVENT_CHG1_VCENTER_DET = (1 << 0), + // 0xa: CHG_EVENT_T2 + kD2257_EVENT_CHG2_BUCK_FLG = (1<<6), + kD2257_EVENT_CHG2_ABCC_ACT = (1<<5), + kD2257_EVENT_CHG2_TIMEOUT = (1<<4), + kD2257_EVENT_CHG2_PRECHG_TIMEOUT= (1<<3), + kD2257_EVENT_CHG2_CHG_END = (1<<2), + kD2257_EVENT_CHG2_CHG_FAST = (1<<1), + kD2257_EVENT_CHG2_CHG_PRE = (1<<0), + // 0x17, GPADC_EVENT0 + kD2257_EVENT_EOMC2 = (1<<1), + kD2257_EVENT_EOMC1 = (1<<0), + // 0x18: GPADC_EVENT1 + kD2257_EVENT_VDDLOW = (1<<7), + kD2257_EVENT_TBAT = (1<<6), +}; + +enum { + kDIALOG_EVENT_HOLD_BUTTON_MASK = EVENT_FLAG_MAKE(5, kD2257_EVENT_A_BUTTON2), + kDIALOG_EVENT_MENU_BUTTON_MASK = EVENT_FLAG_MAKE(5, kD2257_EVENT_A_BUTTON1), + kDIALOG_EVENT_RINGER_BUTTON_MASK= EVENT_FLAG_MAKE(5, kD2257_EVENT_A_BUTTON3), + kDIALOG_EVENT_BUTTON4_MASK = EVENT_FLAG_MAKE(5, kD2257_EVENT_A_BUTTON4), + + kDIALOG_EVENT_BUTTONS = (kD2257_EVENT_A_BUTTON4 | + kD2257_EVENT_A_BUTTON3 | + kD2257_EVENT_A_BUTTON2 | + kD2257_EVENT_A_BUTTON1), + kDIALOG_EVENT_BUTTONS_MASK = EVENT_FLAG_MAKE(5, kDIALOG_EVENT_BUTTONS), + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_EVENT_HOLD_BUTTON_MASK, + + kDIALOG_EVENT_ALARM_MASK = EVENT_FLAG_MAKE(2, kD2257_EVENT_ALARM), + + kDIALOG_EVENT_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, // FIXME + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(9, kD2257_EVENT_CHG1_VBUS_EXT_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(9, kD2257_EVENT_CHG1_VBUS_EXT_REM), + + // FIXME: forcing ADC1 + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(0x17, kD2257_EVENT_EOMC1), + kDIALOG_EVENT_HIB_MASK = kDIALOG_NOTEXIST_MASK, // FIXME + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(0xa, kD2257_EVENT_CHG2_ABCC_ACT), + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(0xa, kD2257_EVENT_CHG2_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(0x18, kD2257_EVENT_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(6, kD2257_EVENT_B_GPIO8), + + kDIALOG_EVENT_GPIO9_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO9), + kDIALOG_EVENT_GPIO10_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO10), + kDIALOG_EVENT_GPIO11_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO11), + kDIALOG_EVENT_GPIO12_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO12), + kDIALOG_EVENT_GPIO13_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO13), + kDIALOG_EVENT_GPIO14_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO14), + kDIALOG_EVENT_GPIO15_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO15), + kDIALOG_EVENT_GPIO16_MASK = EVENT_FLAG_MAKE(7, kD2257_EVENT_C_GPIO16), + + kDIALOG_EVENT_GPIO17_MASK = EVENT_FLAG_MAKE(8, kD2257_EVENT_D_GPIO17), + kDIALOG_EVENT_GPIO18_MASK = EVENT_FLAG_MAKE(8, kD2257_EVENT_D_GPIO18), + kDIALOG_EVENT_GPIO19_MASK = EVENT_FLAG_MAKE(8, kD2257_EVENT_D_GPIO19), + kDIALOG_EVENT_GPIO20_MASK = EVENT_FLAG_MAKE(8, kD2257_EVENT_D_GPIO20), + kDIALOG_EVENT_GPIO21_MASK = EVENT_FLAG_MAKE(8, kD2257_EVENT_D_GPIO21), + kDIALOG_EVENT_GPIO22_MASK = EVENT_FLAG_MAKE(8, kD2257_EVENT_D_GPIO22), + + kDIALOG_EVENT_RINGER_DBL_MASK = EVENT_FLAG_MAKE(5, kD2257_EVENT_A_BUTTON3_DBL), + kDIALOG_EVENT_HOLD_DBL_MASK = EVENT_FLAG_MAKE(5, kD2257_EVENT_A_BUTTON2_DBL), + kDIALOG_EVENT_MENU_DBL_MASK = EVENT_FLAG_MAKE(5, kD2257_EVENT_A_BUTTON1_DBL), + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, // FIXME + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, // FIXME + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, // FIXME +}; + +enum { + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(9, kD2257_EVENT_CHG1_VCENTER_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(9, kD2257_EVENT_CHG1_VBUS_EXT_DET), + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, // FIXME + kDIALOG_STATUS_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, // FIXME + kDIALOG_STATUS_CHARGING_MASK = kDIALOG_NOTEXIST_MASK, // FIXME + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(0xa, kD2257_EVENT_CHG2_TIMEOUT), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(0xa, kD2257_EVENT_CHG2_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(0x18, kD2257_EVENT_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(0xa, kD2257_EVENT_CHG2_ABCC_ACT), +}; + +static const statusRegisters kDialogStatusFWMask = { }; + +enum { + kD2257_EVENT_AA_WAKEMASK = 0, + kD2257_EVENT_AB_WAKEMASK = 0, + kD2257_EVENT_AC_WAKEMASK = kD2257_EVENT_ALARM, + kD2257_EVENT_AD_WAKEMASK = 0, + kD2257_EVENT_AE_WAKEMASK = 0, + kD2257_EVENT_AF_WAKEMASK = kDIALOG_EVENT_BUTTONS, + kD2257_EVENT_AG_WAKEMASK = 0, + kD2257_EVENT_AH_WAKEMASK = 0, + kD2257_EVENT_AI_WAKEMASK = 0, + kD2257_EVENT_AJ_WAKEMASK = kD2257_EVENT_CHG1_VBUS_EXT_DET | kD2257_EVENT_CHG1_VCENTER_DET, // FIXME (kD2186_EVENT_A_ACC_DET) + kD2257_EVENT_AK_WAKEMASK = kD2257_EVENT_CHG2_ABCC_ACT, + kD2257_EVENT_AL_WAKEMASK = 0, + kD2257_EVENT_AM_WAKEMASK = 0, + kD2257_EVENT_AN_WAKEMASK = 0, + kD2257_EVENT_AO_WAKEMASK = 0, + kD2257_EVENT_AP_WAKEMASK = 0, + kD2257_EVENT_AQ_WAKEMASK = 0, + kD2257_EVENT_AR_WAKEMASK = 0, + kD2257_EVENT_AS_WAKEMASK = 0, + kD2257_EVENT_AT_WAKEMASK = 0, + kD2257_EVENT_AU_WAKEMASK = 0, + kD2257_EVENT_AV_WAKEMASK = 0, + kD2257_EVENT_AW_WAKEMASK = 0, + kD2257_EVENT_AX_WAKEMASK = 0, + kD2257_EVENT_AY_WAKEMASK = 0, + kD2257_EVENT_AZ_WAKEMASK = 0, + kD2257_EVENT_BA_WAKEMASK = 0, + kD2257_EVENT_BB_WAKEMASK = 0, + kD2257_EVENT_BC_WAKEMASK = 0, + kD2257_EVENT_BD_WAKEMASK = 0, + kD2257_EVENT_BE_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + ~kD2257_EVENT_AA_WAKEMASK, + ~kD2257_EVENT_AB_WAKEMASK, + ~kD2257_EVENT_AC_WAKEMASK, + ~kD2257_EVENT_AD_WAKEMASK, + ~kD2257_EVENT_AE_WAKEMASK, + ~kD2257_EVENT_AF_WAKEMASK, + ~kD2257_EVENT_AG_WAKEMASK, + ~kD2257_EVENT_AH_WAKEMASK, + ~kD2257_EVENT_AI_WAKEMASK, + ~kD2257_EVENT_AJ_WAKEMASK, + ~kD2257_EVENT_AK_WAKEMASK, + ~kD2257_EVENT_AL_WAKEMASK, + ~kD2257_EVENT_AM_WAKEMASK, + ~kD2257_EVENT_AN_WAKEMASK, + ~kD2257_EVENT_AO_WAKEMASK, + ~kD2257_EVENT_AP_WAKEMASK, + ~kD2257_EVENT_AQ_WAKEMASK, + ~kD2257_EVENT_AR_WAKEMASK, + ~kD2257_EVENT_AS_WAKEMASK, + ~kD2257_EVENT_AT_WAKEMASK, + ~kD2257_EVENT_AU_WAKEMASK, + ~kD2257_EVENT_AV_WAKEMASK, + ~kD2257_EVENT_AW_WAKEMASK, + ~kD2257_EVENT_AX_WAKEMASK, + ~kD2257_EVENT_AY_WAKEMASK, + ~kD2257_EVENT_AZ_WAKEMASK, + ~kD2257_EVENT_BA_WAKEMASK, + ~kD2257_EVENT_BB_WAKEMASK, + ~kD2257_EVENT_BC_WAKEMASK, + ~kD2257_EVENT_BD_WAKEMASK, + ~kD2257_EVENT_BE_WAKEMASK, +}; + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2257_EVENT_AA_WAKEMASK, + kD2257_EVENT_AB_WAKEMASK, + kD2257_EVENT_AC_WAKEMASK, + kD2257_EVENT_AD_WAKEMASK, + kD2257_EVENT_AE_WAKEMASK, + kD2257_EVENT_AF_WAKEMASK & ~kDIALOG_EVENT_BUTTONS , + kD2257_EVENT_AG_WAKEMASK, + kD2257_EVENT_AH_WAKEMASK, + kD2257_EVENT_AI_WAKEMASK, + kD2257_EVENT_AJ_WAKEMASK, + kD2257_EVENT_AK_WAKEMASK, + kD2257_EVENT_AL_WAKEMASK, + kD2257_EVENT_AM_WAKEMASK, + kD2257_EVENT_AN_WAKEMASK, + kD2257_EVENT_AO_WAKEMASK, + kD2257_EVENT_AP_WAKEMASK, + kD2257_EVENT_AQ_WAKEMASK, + kD2257_EVENT_AR_WAKEMASK, + kD2257_EVENT_AS_WAKEMASK, + kD2257_EVENT_AT_WAKEMASK, + kD2257_EVENT_AU_WAKEMASK, + kD2257_EVENT_AV_WAKEMASK, + kD2257_EVENT_AW_WAKEMASK, + kD2257_EVENT_AX_WAKEMASK, + kD2257_EVENT_AY_WAKEMASK, + kD2257_EVENT_AZ_WAKEMASK, + kD2257_EVENT_BA_WAKEMASK, + kD2257_EVENT_BB_WAKEMASK, + kD2257_EVENT_BC_WAKEMASK, + kD2257_EVENT_BD_WAKEMASK, + kD2257_EVENT_BE_WAKEMASK, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + kD2257_EVENT_CHG1_VCENTER_DET | kD2257_EVENT_CHG1_VBUS_EXT_DET, + kD2257_EVENT_CHG2_ABCC_ACT, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +// should I use *_VBUS_DET_REM +static const eventRegisters kDialogEventUSBMask = { + 0, // EVENT_AA + 0, // EVENT_AB + 0, // EVENT_AC + 0, // EVENT_AD + 0, // EVENT_AE + 0, // EVENT_AF + 0, // EVENT_AG + 0, // EVENT_AH + 0, // EVENT_AI + kD2257_EVENT_CHG1_VCENTER_DET | kD2257_EVENT_CHG1_VBUS_EXT_DET, + kD2257_EVENT_CHG2_ABCC_ACT, + 0, // EVENT_AL + 0, // EVENT_AM + 0, // EVENT_AN + 0, // EVENT_AO + 0, // EVENT_AP + 0, // EVENT_AQ + 0, // EVENT_AR + 0, // EVENT_AS + 0, // EVENT_AT + 0, // EVENT_AU + 0, // EVENT_AV + 0, // EVENT_AW + 0, // EVENT_AX + 0, // EVENT_AY + 0, // EVENT_AZ + 0, // EVENT_BA + 0, // EVENT_BB + 0, // EVENT_BC + 0, // EVENT_BD + 0, // EVENT_BE +}; + +static const eventRegisters kDialogEventFWMask = { 0, }; +static const statusRegisters kDialogStatusChargingMask = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + kD2257_EVENT_CHG2_CHG_FAST | kD2257_EVENT_CHG2_CHG_PRE, +}; + + + +enum { + kDialogEventPwrsupplyCount = 2, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 0, +}; + +enum { + // FAULT_LOG_A (SYSCTL_FAULT_LOG1) + kDIALOG_FAULT_LOG_WDOG = FAULTLOG_FLAG_MAKE(0, (1 << 7)), + kDIALOG_FAULT_LOG_RESET_IN_3 = FAULTLOG_FLAG_MAKE(0, (1 << 6)), + kDIALOG_FAULT_LOG_RESET_IN_2 = FAULTLOG_FLAG_MAKE(0, (1 << 5)), + kDIALOG_FAULT_LOG_RESET_IN_1 = FAULTLOG_FLAG_MAKE(0, (1 << 4)), + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + // FAULT_LOG_B (SYSCTL_FAULT_LOG2) + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = FAULTLOG_FLAG_MAKE(1, (1 << 2)), + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = FAULTLOG_FLAG_MAKE(1, (1 << 1)), + kDIALOG_FAULT_LOG_NTC_SHDN = FAULTLOG_FLAG_MAKE(1, (1 << 0)), +}; + +// --------------------------------------------------------------------------- +// GPADC +// --------------------------------------------------------------------------- + +enum { + kD2257_ADC_CONTROL_MUX_SEL_VDD_MAIN = 0, + kD2257_ADC_CONTROL_MUX_SEL_BRICK_ID = 1, + kD2257_ADC_CONTROL_MUX_SEL_SPARE0 = 2, + kD2257_ADC_CONTROL_MUX_SEL_APP_MUX_A = 3, + kD2257_ADC_CONTROL_MUX_SEL_APP_MUX_B = 4, + // ... + kD2257_ADC_CONTROL_MUX_SEL_VLDO1 = 18, + kD2257_ADC_CONTROL_MUX_SEL_ILDO1 = 19, + kD2257_ADC_CONTROL_MUX_SEL_VLDO2, + kD2257_ADC_CONTROL_MUX_SEL_ILDO2, + kD2257_ADC_CONTROL_MUX_SEL_VLDO3, + kD2257_ADC_CONTROL_MUX_SEL_ILDO3, + kD2257_ADC_CONTROL_MUX_SEL_VLDO4, + kD2257_ADC_CONTROL_MUX_SEL_ILDO4, + kD2257_ADC_CONTROL_MUX_SEL_VLDO5, + kD2257_ADC_CONTROL_MUX_SEL_ILDO5, + kD2257_ADC_CONTROL_MUX_SEL_VLDO6, + kD2257_ADC_CONTROL_MUX_SEL_ILDO6, + kD2257_ADC_CONTROL_MUX_SEL_VLDO7, + kD2257_ADC_CONTROL_MUX_SEL_ILDO7, + kD2257_ADC_CONTROL_MUX_SEL_VLDO8, + kD2257_ADC_CONTROL_MUX_SEL_ILDO8, + kD2257_ADC_CONTROL_MUX_SEL_VLDO9, + kD2257_ADC_CONTROL_MUX_SEL_ILDO9, + kD2257_ADC_CONTROL_MUX_SEL_VLDO10, + kD2257_ADC_CONTROL_MUX_SEL_ILDO10, + kD2257_ADC_CONTROL_MUX_SEL_VLDO11, + kD2257_ADC_CONTROL_MUX_SEL_ILDO11, + kD2257_ADC_CONTROL_MUX_SEL_VBUF_ON, + kD2257_ADC_CONTROL_MUX_SEL_ION_BUF, + // no papi, no12 + kD2257_ADC_CONTROL_MUX_SEL_VLDO13 = 42, + kD2257_ADC_CONTROL_MUX_SEL_ILDO13 = 43, + kD2257_ADC_CONTROL_MUX_SEL_VLDO14 = 44, + kD2257_ADC_CONTROL_MUX_SEL_ILDO14 = 45, + kD2257_ADC_CONTROL_MUX_SEL_VLDO15 = 46, + kD2257_ADC_CONTROL_MUX_SEL_ILDO15 = 47, + kD2257_ADC_CONTROL_MUX_SEL_VLDO16 = 48, + kD2257_ADC_CONTROL_MUX_SEL_ILDO16 = 49, + // ReatlimeClock + kD2257_ADC_CONTROL_MUX_SEL_VRTC = 50, + kD2257_ADC_CONTROL_MUX_SEL_IRTC = 51, + + // high impedance external input + kD2257_ADC_CONTROL_MUX_SEL_ADC_IN7 = 82, + // Junction + kD2257_ADC_CONTROL_MUX_SEL_TJNCT = 88, + // NTCs + kD2257_ADC_CONTROL_MUX_SEL_TCAL = 89, // NTC0 + kD2257_ADC_CONTROL_MUX_SEL_TDEV1 = 90, + kD2257_ADC_CONTROL_MUX_SEL_TDEV2 = 91, + kD2257_ADC_CONTROL_MUX_SEL_TDEV3 = 92, + kD2257_ADC_CONTROL_MUX_SEL_TDEV4 = 93, + kD2257_ADC_CONTROL_MUX_SEL_TDEV5, + kD2257_ADC_CONTROL_MUX_SEL_TDEV6, + kD2257_ADC_CONTROL_MUX_SEL_TDEV7, + kD2257_ADC_CONTROL_MUX_SEL_TDEV8, + // .. + + kD2257_ADC_CONTROL_MUX_SEL_TBAT = 108, + + // TINT, measure TDIE (TDIE1,TDIE9) + kD2257_ADC_CONTROL_MUX_SEL_LDO10_TEMP = 112, + kD2257_ADC_CONTROL_MUX_SEL_LDO5CHGBUCKA_TEMP = 113, + kD2257_ADC_CONTROL_MUX_SEL_CHGBUCKB_TEMP = 114, + kD2257_ADC_CONTROL_MUX_SEL_BUCK6_TEMP = 115, + kD2257_ADC_CONTROL_MUX_SEL_BUCK0_TEMP = 116, + kD2257_ADC_CONTROL_MUX_SEL_BUCK28_TEMP, + kD2257_ADC_CONTROL_MUX_SEL_BUCK74_TEMP, + kD2257_ADC_CONTROL_MUX_SEL_BUCK1_TEMP, + kD2257_ADC_CONTROL_MUX_SEL_BUCK35_TEMP, + + kD2257_ADC_CONTROL_MUX_SEL_VBUCK0 = 144, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK1, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK2, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK3, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK4, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK5, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK6, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK7, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK8 = 152, + + kD2257_ADC_CONTROL_MUX_SEL_VBAT = 157, + kD2257_ADC_CONTROL_MUX_SEL_VBUS = 158, + kD2257_ADC_CONTROL_MUX_SEL_ADC_IN31 = 159, + + // Legacy GPADC based iBuck meas + kD2257_ADC_CONTROL_MUX_SEL_IBUCK0 = 176, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK1, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK2, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK3, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK4, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK5 = 181, + // no iBuck6 + kD2257_ADC_CONTROL_MUX_SEL_IBUCK7 = 183, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK8 = 184, + + // SAR based IPBuck meas + // - see BUCKn_ANA_TRIM4 to select power (default) or current measurement + // - see IBUCK_CONFIG_C[IBUCKn_SAR_IMEAS_TYPE] for digital offset cancellation + kD2257_ADC_CONTROL_MUX_SEL_SAR_IBUCK0 = 185, + // SAR Filtered based IPBuck meas + // - see BUCKn_ANA_TRIM4 to select power (default) or current measurement + // - see IBUCK_CONFIG_C[IBUCKn_SAR_IMEAS_TYPE] for digital offset cancellation + // - use IBUCKn_SAR_FILTER_TC to select the filter constant + kD2257_ADC_CONTROL_MUX_SEL_SAR_FILT_IBUCK0 = 186, + kD2257_ADC_CONTROL_MUX_SEL_SAR_IBUCK1, + kD2257_ADC_CONTROL_MUX_SEL_SAR_FILT_IBUCK1, + kD2257_ADC_CONTROL_MUX_SEL_SAR_IBUCK2, + kD2257_ADC_CONTROL_MUX_SEL_SAR_FILT_IBUCK2, + + kD2257_ADC_CONTROL_MUX_SEL_ICH_ADC_CH = 201, + kD2257_ADC_CONTROL_MUX_SEL_IBUS_IN_LG_ADC_CH = 202, + kD2257_ADC_CONTROL_MUX_SEL_IBUS_IN_HG_ADC_CH = 203, + + // cannot use this when IBUCK_CORR_N is set (default) + kD2257_ADC_CONTROL_MUX_SEL_IBUCK0_OFF = 208, // offset + kD2257_ADC_CONTROL_MUX_SEL_IBUCK1_OFF, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK2_OFF, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK3_OFF, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK4_OFF, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK5_OFF, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK6_OFF, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK7_OFF, + kD2257_ADC_CONTROL_MUX_SEL_IBUCK8_OFF = 216, + + kD2257_ADC_CONTROL_MUX_SEL_VBUCK3_SW1 = 240, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK3_SW2, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK3_SW3, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK4_SW1 = 243, + kD2257_ADC_CONTROL_MUX_SEL_VBUCK4_SW2 = 244, + + // ------------------------------------------------ + + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = kD2257_ADC_CONTROL_MUX_SEL_VDD_MAIN, + kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID = kD2257_ADC_CONTROL_MUX_SEL_BRICK_ID, + kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID = kD2257_ADC_CONTROL_MUX_SEL_ADC_IN7, + + kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 = kD2257_ADC_CONTROL_MUX_SEL_TCAL, + kDIALOG_ADC_CONTROL_MUX_NUM_NTC = 8, + + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kD2257_ADC_CONTROL_MUX_SEL_LDO10_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kD2257_ADC_CONTROL_MUX_SEL_BUCK35_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = kD2257_ADC_CONTROL_MUX_SEL_TJNCT, + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = kD2257_ADC_CONTROL_MUX_SEL_TBAT, + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = kD2257_ADC_CONTROL_MUX_SEL_VBAT, + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = kD2257_ADC_CONTROL_MUX_SEL_ICH_ADC_CH, + + // TODO: verify BRICK_ID_OFFSET_MV + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, +}; + +enum { + +// kDIALOG_ADC_CONTROL_DEFAULTS = 0, +// kDIALOG_ADC_CONTROL2_DEFAULTS = 0, +// kDIALOG_ADC_CONTROL_ADC_REF_EN = 0, + + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 7), // MAN1_INVALID + kDIALOG_ADC_LSB_ADC_OVL = (1 << 6), // Overflow + + kDIALOG_ADC_MAN_CTL = kD2257_GPADC_MAN_CTRL1, + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = kD2257_GPADC_MAN_CTRL1_MASK, + kDIALOG_ADC_LSB = kD2257_GPADC_MAN1_RES_LSB, + + kDIALOG_ADC_FULL_SCALE_MV = 2500, + kDIALOG_ADC_RESOLUTION_BITS = 12, +}; + +// ------------------------------------------------ +// GPIO +// ------------------------------------------------ + +enum { + kDIALOG_RTC_CONTROL_MONITOR = (1 << 0), + kDIALOG_RTC_CONTROL_ALARM_EN = (1 << 6), +}; + +enum { + kD2257_GPIO_IO_CONFIG_IN = (0<<6), + kD2257_GPIO_IO_CONFIG_OUT_OD = (1<<6), + kD2257_GPIO_IO_CONFIG_OUT_PP = (2<<6), +// NOTE: Once a GPIO is set to a safe spare configuration, the safe spare setting must +// be changed before any changes to the associated GPIO_x_IO_TYPE, GPIOx_PUPD and +// GPIOx_WAKE_LVL register fields can be done. + kD2257_GPIO_IO_CONFIG_SAFE_SPARE = (3<<6), + + kD2257_GPIO_IO_TYPE_OUT_LVL = (0<<3), + kD2257_GPIO_IO_TYPE_OUT_32K = (1<<3), + kD2257_GPIO_IO_TYPE_OUT_nRST = (2<<3), + kD2257_GPIO_IO_TYPE_OUT_TEMP = (3<<3), + kD2257_GPIO_IO_TYPE_OUT_LVL2 = (4<<3), + kD2257_GPIO_IO_TYPE_IN_LEVEL_HIGH = (0<<3), + kD2257_GPIO_IO_TYPE_IN_LEVEL_LOW = (1<<3), + kD2257_GPIO_IO_TYPE_IN_EDGE_RISING = (2<<3), + kD2257_GPIO_IO_TYPE_IN_EDGE_FALLING = (3<<3), + kD2257_GPIO_IO_TYPE_IN_EDGE_ANY = (4<<3), + + kDIALOG_SYS_GPIO_CONFIG_MASK = (0x3<<6), + kDIALOG_SYS_GPIO_DIRECTION_MASK = (0x3<<3), + kDIALOG_SYS_GPIO_VALUE_MASK = (1<<0), + + kDIALOG_SYS_GPIO_DIRECTION_OUT = kD2257_GPIO_IO_TYPE_OUT_LVL, + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = kD2257_GPIO_IO_TYPE_OUT_32K, + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = kD2257_GPIO_IO_TYPE_IN_LEVEL_HIGH, + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = kD2257_GPIO_IO_TYPE_IN_LEVEL_LOW, + + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 0), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 0), + kDIALOG_SYS_GPIO_INPUT_WAKE = (1 << 0), +}; + +// NOTE: it doesn't work with SAFESPARE +#define IS_GPIO_OUTPUT(gpio) \ + (((gpio)&kDIALOG_SYS_GPIO_CONFIG_MASK)!=kD2257_GPIO_IO_CONFIG_IN ) + +#define kDIALOG_STATUS_GPIO_MASK(gpio) \ + STATUS_FLAG_MAKE(6 + ((gpio)/8), (1 << ((gpio) % 8)) ) + +// ---------------------------------------------------------------------------- +// LDOS +// ---------------------------------------------------------------------------- + +#define NUM_LDOS 0x23 +static const struct ldo_params ldo_D2257[NUM_LDOS] = { + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO1_VSEL, kD2257_PWRONOFF_LDO1_EN, 1 }, // 00 - LDO1 = + { 1200, 5, 0xff, 0xff, 2, kD2257_LDO2_VSEL, kD2257_PWRONOFF_LDO2_EN, 1 }, // 01 - LDO2 = bypass + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO3_VSEL, kD2257_PWRONOFF_LDO3_EN, 1 }, // 02 - LDO3 = + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO4_VSEL, kD2257_PWRONOFF_LDO4_EN, 1 }, // 03 - LDO4 = + { 2400, 5, 0xff, 0xff, 0x00, kD2257_LDO5_VSEL, kD2257_PWRONOFF_LDO5_EN, 1 }, // 04 - LDO5 = + { 2500, 25, 0x7f, 0x7f, 2, kD2257_LDO6_VSEL, kD2257_PWRONOFF_LDO6_EN, 1 }, // 05 - LDO6 = bypass + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO7_VSEL, kD2257_PWRONOFF_LDO7_EN, 1 }, // 06 - LDO7 = + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO8_VSEL, kD2257_PWRONOFF_LDO8_EN, 1 }, // 07 - LDO8 = + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO9_VSEL, kD2257_PWRONOFF_LDO9_EN, 1 }, // 08 - LDO9 = + { 600, 5, 0xff, 0xff, 0x00, kD2257_LDO10_VSEL, kD2257_PWRONOFF_LDO10_EN, 1 }, // 09 - LDO10 - + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO11_VSEL, kD2257_PWRONOFF_LDO11_EN, 1 }, // 0a - LDO11 = + { 1800, 0, 0, 0, 0x00, 0, 0, 0 }, // 0b - there is no LDO12 (PP1V8_ALWAYS) + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO13_VSEL, kD2257_PWRONOFF_LDO13_EN, 1 }, // 0c - LDO13 = + { 600, 5, 0xff, 0xff, 0x00, kD2257_LDO14_VSEL, kD2257_PWRONOFF_LDO14_EN, 1 }, // 0d - LDO14 = + { 600, 5, 0xff, 0xff, 0x00, kD2257_LDO15_VSEL, kD2257_PWRONOFF_LDO15_EN, 1 }, // 0e - LDO15 = + { 1200, 5, 0xff, 0xff, 0x00, kD2257_LDO16_VSEL, kD2257_PWRONOFF_LDO16_EN, 1 }, // 0f - LDO16 = + + { 450, 5, 0, 0, 0x00, kD2257_BUCK0_VSEL, kD2257_PWRONOFF_BUCK0_EN, 1 }, // 10 - POWER_RAIL_CPU + { 450, 5, 0, 0, 0x00, kD2257_BUCK1_VSEL, kD2257_PWRONOFF_BUCK1_EN, 1 }, // 11 - POWER_RAIL_GPU + { 600, 5, 0, 0, 0x00, kD2257_BUCK2_VSEL, kD2257_PWRONOFF_BUCK2_EN, 1 }, // 12 - POWER_RAIL_SOC + { 1100, 5, 0, 0, 0x00, kD2257_BUCK3_VSEL, kD2257_PWRONOFF_BUCK3_EN, 1 }, // 13 + { 600, 5, 0, 0, 0x00, kD2257_BUCK4_VSEL, kD2257_PWRONOFF_BUCK4_EN, 1 }, // 14 + { 600, 5, 0, 0, 0x00, kD2257_BUCK5_VSEL, kD2257_PWRONOFF_BUCK5_EN, 1 }, // 15 - POWER_RAIL_VDD_FIXED + // NOTE: here bypass is the OFFSET of the bypass register from VSEL + { 1800, 5, 0, 0, 0x00, kD2257_BUCK6_VSEL, kD2257_PWRONOFF_BUCK6_EN, 1 }, // 16 - BUCK6 (Byp) + { 600, 5, 0, 0, 0x00, kD2257_BUCK7_VSEL, kD2257_PWRONOFF_BUCK7_EN, 1 }, // 17 - POWER_RAIL_CPU_RAM + { 600, 5, 0, 0, 0x00, kD2257_BUCK8_VSEL, kD2257_PWRONOFF_BUCK8_EN, 1 }, // 18 - POWER_RAIL_GPU_RAM + + { 0, 0, 0, 0, 0x00, 0, kD2257_PWRONOFF_BUCK3_SW1_EN, 1 }, // 19 + { 0, 0, 0, 0, 0x00, 0, kD2257_PWRONOFF_BUCK3_SW2_EN, 1 }, // 1a + { 0, 0, 0, 0, 0x00, 0, kD2257_PWRONOFF_BUCK3_SW3_EN, 1 }, // 1b + { 0, 0, 0, 0, 0x00, 0, kD2257_PWRONOFF_BUCK4_SW1_EN, 1 }, // 1c + { 0, 0, 0, 0, 0x00, 0, kD2257_PWRONOFF_BUCK4_SW2_EN, 1 }, // 1d + + { 0, 0, 0, 0, 0x00, 0, kD2257_PWRONOFF_LCM_BST_SW_EN, 1 }, // 1e + + { 5000, 50, 0x1f, 0x1f, 0x00, kD2257_LDO_LCM_BOOST_VSEL, kD2257_PWRONOFF_LCM_BST_EN, 1 }, // 1f + { 5000, 50, 0x1f, 0x1f, 0x00, kD2257_LDO_LCM_LDO1_VSEL, kD2257_PWRONOFF_LCM_LDO1_EN, 1 }, // 20 + { 5000, 50, 0x1f, 0x1f, 0x00, kD2257_LDO_LCM_LDO2_VSEL, kD2257_PWRONOFF_LCM_LDO2_EN, 1 }, // 21 + { 0, 0, 0, 0, 0x00, 0, kD2257_PWRONOFF_LDO6_EN, 7<<1 }, // 22 LDO36 acc_sleep_pwr + +}; +#define LDOP ldo_D2257 + + +// ---------------------------------------------------------------------------- +// Charge control +// ---------------------------------------------------------------------------- + +// TODO: verify these GUYS +enum { + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x00, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x02, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x0a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_300 = 0x12, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_400 = 0x1a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x22, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_600 = 0x2a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_700 = 0x32, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_900 = 0x42, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_975 = 0x48, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x4a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1450 = 0x6e, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1500 = 0x72, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1900 = 0x92, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0x9a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100 = 0xa2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2300 = 0xb2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 75, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 8, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 3262, +}; + +enum { + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3f, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 6), + kDIALOG_CHARGE_CONTROL_B_CHG_HIB = (1 << 7), + kDIALOG_CHARGE_CONTROL_CHG_HIB = kDIALOG_CHARGE_CONTROL_B_CHG_HIB, +}; + +enum { + kDIALOG_CHARGE_CONTROL_STEP = 50, + kDIALOG_CHARGE_CONTROL_MAX = 3150, +}; + +enum { + // CHG_CTRL_G + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = (1 << 6), + kDIALOG_CHARGE_CONTROL_CHG_BUCK_EN = (1 << 7), +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = 0xF0, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = 0x07, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +// ---------------------------------------------------------------------------- +// Buttons +// ---------------------------------------------------------------------------- + +enum { + kDIALOG_BUTTON_DBL_CLICK_RATE_MASK = (7 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_10MS = (0 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_20MS = (1 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_50MS = (2 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_60MS = (3 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_100MS = (4 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_200MS = (5 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_300MS = (6 << 0), + kDIALOG_BUTTON_DBL_CLICK_RATE_400MS = (7 << 0), + + kD2255_BUTTON_DBL_BTN1_DBL_EN = (1 << 3), + kD2255_BUTTON_DBL_BTN2_DBL_EN = (1 << 4), + kD2255_BUTTON_DBL_BTN3_DBL_EN = (1 << 5), + kD2255_BUTTON_DBL_BTN4_DBL_EN = (1 << 6), + + // TODO: verify this! + kDIALOG_BUTTON_DBL_HOLD_DBL_EN = kD2255_BUTTON_DBL_BTN2_DBL_EN, + kDIALOG_BUTTON_DBL_MENU_DBL_EN = kD2255_BUTTON_DBL_BTN1_DBL_EN, + kDIALOG_BUTTON_DBL_RINGER_DBL_EN = kD2255_BUTTON_DBL_BTN3_DBL_EN, +}; + +#endif /* __DIALOG_D2257_H */ diff --git a/drivers/dialog/pmu/d2355.h b/drivers/dialog/pmu/d2355.h new file mode 100644 index 0000000..d942b3e --- /dev/null +++ b/drivers/dialog/pmu/d2355.h @@ -0,0 +1,844 @@ +/* Euphrates / Arno + * Euphrates: Specification and Data-sheet from Vendor (Dialog) + * + * NOTE: Arno is d2370 + * + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DIALOG_D2355_H +#define __DIALOG_D2355_H + +#define PMU_HAS_SWI 0 +#define PMU_HAS_DWI 0 +#define PMU_HAS_LCM_LDO 0 +#define PMU_HAS_BIST_ADC 0 +#define PMU_HAS_CHG_ABCC_FLAG 1 +#define PMU_HAS_VIB 0 +#define PMU_HAS_RAM 0 +#define PMU_HAS_WLED 0 +#define PMU_HAS_32K_RTC 0 + +// TODO: enable accumulators +#define PMU_HAS_ACCUMULATORS 0 + +#define PMU_HAS_SYS 0 +#define PMU_HAS_WDT 0 +#define PMU_HAS_CHARGER 1 +#define PMU_HAS_ISET_BAT_2BYTES 1 +#define PMU_DRV_NEW_DRIVER 1 + +enum { + kDIALOG_ADDR_R = 0xeb, + kDIALOG_ADDR_W = 0xea, + kDIALOG_REG_BYTES = 2, +}; + +enum { + kDIALOG_EVENT_COUNT = 10, + kDIALOG_STATUS_COUNT = 10, + kDIALOG_FAULTLOG_COUNT = 3, + kDIALOG_CHIPID_COUNT = 9, + kDIALOG_GPIO_COUNT = 8, +}; + +#include "dCommon.h" + +// --------------------------------- +// Chip Identification +// --------------------------------- + +enum { + kDIALOG_MASK_REV_CODE = 0x0000, + kDIALOG_TRIM_REL_CODE = 0x0001, + kDIALOG_PLATFORM_ID = 0x0002, + kDIALOG_PARITY = 0x0003, + kDIALOG_DEVICE_ID1 = 0x0004, + kDIALOG_DEVICE_ID2 = 0x0005, + kDIALOG_DEVICE_ID3 = 0x0006, + kDIALOG_DEVICE_ID4 = 0x0007, + kDIALOG_DEVICE_ID5 = 0x0008, + + kDIALOG_CHIP_ID = kDIALOG_MASK_REV_CODE, +}; + +// --------------------------------- +// System Configuration +// --------------------------------- + +// --------------------------------- +// Faultlog (virtual) +// --------------------------------- + +enum { + kD2355_FAULT_LOG_A = 0x0050, + kD2355_FAULT_LOG_B, + kD2355_FAULT_LOG_C, + + kDIALOG_FAULT_LOG = kD2355_FAULT_LOG_A, +}; + +// --------------------------------- +// Event Register (virtual) +// --------------------------------- + +enum { + kD2355_EVENT_A = 0x0060, + kD2355_EVENT_B, + kD2355_EVENT_C, + kD2355_EVENT_D, + kD2355_EVENT_E, + kD2355_EVENT_F, + kD2355_EVENT_G, + kD2355_EVENT_H, + kD2355_EVENT_I, + kD2355_EVENT_J, + + kDIALOG_EVENT_A = kD2355_EVENT_A, +}; + +// --------------------------------- +// Status Register (virtual) +// --------------------------------- + +enum { + kD2355_STATUS_A = 0x0080, + kD2355_STATUS_B, + kD2355_STATUS_C, + kD2355_STATUS_D, + kD2355_STATUS_E, + kD2355_STATUS_F, + kD2355_STATUS_G, + kD2355_STATUS_H, + kD2355_STATUS_I, + kD2355_STATUS_J, + + kDIALOG_STATUS_A = kD2355_STATUS_A, +}; + +// --------------------------------- +// IRQ Mask Register (virtual) +// --------------------------------- + +enum { + kD2355_IRQ_MASK_A = 0x0a0, + kD2355_IRQ_MASK_B, + kD2355_IRQ_MASK_C, + kD2355_IRQ_MASK_D, + kD2355_IRQ_MASK_E, + kD2355_IRQ_MASK_F, + kD2355_IRQ_MASK_G, + kD2355_IRQ_MASK_H, + kD2355_IRQ_MASK_I, + kD2355_IRQ_MASK_J, + + kDIALOG_IRQ_MASK_A = kD2355_IRQ_MASK_A, +}; +// --------------------------------- +// MAIN FSM & IRQ Control +// --------------------------------- + +enum { + kD2355_MFSM_FAULT_LOG1 = 0x0100, +}; + +enum { + kD2355_MFSM_CONF_A = 0x0140, + kD2355_MFSM_CONF_B, + kD2355_MFSM_CONF_C, +}; + +// --------------------------------- +// GPIO: control +// --------------------------------- + +enum { + kD2355_GPIO_GPIO1 = 0x01c0, + kD2355_GPIO_GPIO2, + kD2355_GPIO_GPIO3, + kD2355_GPIO_GPIO4, + kD2355_GPIO_GPIO5, + kD2355_GPIO_GPIO6, + kD2355_GPIO_GPIO7, + kD2355_GPIO_GPIO8 = 0x01c7, +}; + +// --------------------------------- +// GPIO: Event/Status/IRQ_CTL +// --------------------------------- + +// --------------------------------- +// GPIO: Debouncer Configuration +// --------------------------------- + + +// --------------------------------- +// GPADC +// --------------------------------- + +enum { + kD2355_ADC_EVENT_A = 0x0310, + kD2355_ADC_EVENT_B, + kD2355_ADC_EVENT_C, + + kD2355_ADC_STATUS_A = 0x320, + kD2355_ADC_STATUS_B, + kD2355_ADC_STATUS_C, + + kD2355_ADC_IRQ_MASK_A = 0x0330, + kD2355_ADC_IRQ_MASK_B, + kD2355_ADC_IRQ_MASK_C, +}; + +// --------------------------------- +// Temperature & Sensor Control +// --------------------------------- + +enum { + kD2355_T_OFFSET_MSB = 0x033f, + kD2355_T_OFFSET_LSB = 0x0340, +}; + +// --------------------------------- +// Charging Control +// --------------------------------- + +enum { + kD2355_ADC_CHG_TRIM4 = 0x341, + kD2355_ADC_ICHG_END, + kD2355_ADC_TBAT_0, + kD2355_ADC_TBAT_1, + kD2355_ADC_TBAT_2, + kD2355_ADC_TBAT_3, + kD2355_ADC_TBAT_4, + kD2355_ADC_TBAT_MAX, + // Hysteresis, + // ... + kD2355_ADC_ICHG_AVG = 0x035e, + kD2355_ADC_ICHG6A_AVG = 0x035f, + kD2355_ADC_ACTUAL_TBAT_BAND, +}; + +// --------------------------------- +// GPADC Control and Result +// --------------------------------- + +enum { + kD2355_ADC_CTRL1 = 0x0361, + kD2355_ADC_RES_LSB, + kD2355_ADC_RES_MSB, + kD2355_ADC_CTRL2, + kD2355_ADC_CTRL3, + kD2355_ADC_FSM_TRIM0, + kD2355_ADC_FSM_TRIM1, + kD2355_ADC_FSM_TRIM2, + kD2355_ADC_FSM_SAR, + kD2355_ADC_ANA_TRIM0, + kD2355_ADC_ANA_TRIM1, +}; + +// --------------------------------- +// CHARGER SYSTEM +// --------------------------------- + +// Event, Status & IRQ Control +enum { + kD2355_CHG_EVENT_A = 0x0410, + kD2355_CHG_EVENT_B, + kD2355_CHG_EVENT_C, + kD2355_CHG_EVENT_D, + + kD2355_CHG_STATUS_A = 0x0420, + kD2355_CHG_STATUS_B, + kD2355_CHG_STATUS_C, + kD2355_CHG_STATUS_D, + + kD2355_CHG_IRQ_MASK_A =0x0430, + kD2355_CHG_IRQ_MASK_B, + kD2355_CHG_IRQ_MASK_C, + kD2355_CHG_IRQ_MASK_D, +}; + +enum { + kD2355_CHG_CTRL_A = 0x0440, + kD2355_CHG_CTRL_B = 0x0441, + kD2355_CHG_CTRL_C, + kD2355_CHG_CTRL_D = 0x0443, + kD2355_CHG_CTRL_E, + kD2355_CHG_CTRL_F, + + kD2355_CHG_TIME = 0x0447, + kD2355_CHG_TIME_PRE, + +// USB Current Limit + kD2355_CHG_ISET_BUCK = 0x044e, + kD2355_CHG_ISET_BUCK_SHADOW, + kD2355_CHG_ISET_BUCK_LV_ABSMAX, + kD2355_CHG_ISET_BUCK_HV_ABSMAX, + kD2355_CHG_ISET_BUCK_ACTUAL = 0x0452, + kD2355_CHG_ISET_BUCK_ALT, +// Battery Current Limit + kD2355_CHG_ICHG_PRE_MSB = 0x0454, + kD2355_CHG_ICHG_PRE_LSB, + kD2355_CHG_ICHG_BAT_MSB = 0x0456, + kD2355_CHG_ICHG_BAT_LSB, + kD2355_CHG_ICHG_BAT_MAX_MSB = 0x0458, + kD2355_CHG_ICHG_BAT_MAX_LSB, + // ?? + kD2355_CHG_ICHG_BAT_ACTUAL_MSB = 0x045b, + kD2355_CHG_ICHG_BAT_ACTUAL_LSB, +}; + +// --------------------------------- +// Misc/DEBUG +// --------------------------------- + +enum { + kDIALOG_TEST_ACCESS = 0x0B10, + kDIALOG_TEST_ACCESS_ENA = 0x1D, + kDIALOG_TEST_ACCESS_DIS = 0x00, +}; + +enum { + // J99 EVT not recognizing lightning connection + kDIALOG_OTP_RELOAD_CONF = kD2355_MFSM_CONF_A, + kDIALOG_OTP_SKIP_RELOAD_TO_ACT = (1<<4), +}; + +// --------------------------------- +// Events +// --------------------------------- + +#if 0 +// Synthetic Accumulator Registers +enum { + kDIALOG_ACCUMULATOR_SEL_COUNT = 2, + kDIALOG_IBUS_ACCUMULATOR = 0, + kDIALOG_VBUS_ACCUMULATOR = 1, + kDIALOG_IBUCK0_ACCUMULATOR = 0, + kDIALOG_IBUCK1_ACCUMULATOR = 0, +}; +#endif + +// --------------------------------- +// Events (virtual) +// --------------------------------- + +enum { + // 0: DEB_EVENT_A + kD2355_EVENT_A_GPIO8 = (1 << 7), + kD2355_EVENT_A_GPIO7 = (1 << 6), + kD2355_EVENT_A_GPIO6 = (1 << 5), + kD2355_EVENT_A_GPIO5 = (1 << 4), + kD2355_EVENT_A_GPIO4 = (1 << 3), + kD2355_EVENT_A_GPIO3 = (1 << 2), + kD2355_EVENT_A_GPIO2 = (1 << 1), + kD2355_EVENT_A_GPIO1 = (1 << 0), + // 1: DEB_EVENT_B + kD2355_EVENT_B_CHG_BG_HIGH_TEMP = (1 <<1), + kD2355_EVENT_B_CHG_VBUS_ATT = (1 <<0), + // 2: ADC_EVENT_A + kD2355_EVENT_C_PBUS_CNT_OVERFLOW= (1 << 4), + kD2355_EVENT_C_EOMC = (1 << 3), + kD2355_EVENT_C_IBUS_OVERFLOW = (1 << 2), + kD2355_EVENT_C_TBAT = (1 << 1), + kD2355_EVENT_C_VDD_LOW = (1 << 0), + // 3: ADC_EVENT_B + kD2355_EVENT_D_VDDREF_CHG_FALL = (1 << 5), + kD2355_EVENT_D_TMID_DIE_FALL = (1 << 4), + kD2355_EVENT_D_TLINCHG_FALL = (1 << 3), + kD2355_EVENT_D_TVCENTER2_FALL = (1 << 2), + kD2355_EVENT_D_TVCENTER1_FALL = (1 << 1), + kD2355_EVENT_D_TCBUCK_FALL = (1 << 0), + // 4: ADC_EVENT_C + kD2355_EVENT_E_VDDREF_CHG_RISE = (1 << 5), + kD2355_EVENT_E_TMID_DIE_RISE = (1 << 4), + kD2355_EVENT_E_TLINCHG_RISE = (1 << 3), + kD2355_EVENT_E_TVCENTER2_RISE = (1 << 2), + kD2355_EVENT_E_TVCENTER1_RISE = (1 << 1), + kD2355_EVENT_E_TBUCK_RISE = (1 << 0), + // 5: CHG_EVENT_A + kD2355_EVENT_F_CV_LOOP_AVERAGE_SATURATED = (1 << 7), + kD2355_EVENT_F_FAULTY_ADAPTER = (1 << 6), + kD2355_EVENT_F_VBUS_OV = (1 << 5), + kD2355_EVENT_F_VBUS_EXT_REM = (1 << 4), + kD2355_EVENT_F_CHG_HV_ATT = (1 << 3), + kD2355_EVENT_F_VBUS_EXT_DET = (1 << 2), + kD2355_EVENT_F_HV_MODE = (1 << 1), + kD2355_EVENT_F_VCENTER_DET = (1 << 0), + // 6: CHG_EVENT_B + kD2355_EVENT_G_CHG_SLOW = (1 << 7), + kD2355_EVENT_G_CHG_BUCK_FLG = (1 << 6), + kD2355_EVENT_G_CHG_ABCC_ACT = (1 << 5), + kD2355_EVENT_G_CHG_TIMEOUT = (1 << 4), + kD2355_EVENT_G_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2355_EVENT_G_CHG_END = (1 << 2), + kD2355_EVENT_G_CHG_FAST = (1 << 1), + kD2355_EVENT_G_CHG_PRE = (1 << 0), + // 7: CHG_EVENT_C + // ... kD2355_EVENT_H + // 8: CHG_EVENT_D + // ... kD2355_EVENT_I + // 9: THRCTL_EVENT_A + // ... kD2355_EVENT_J +}; + +enum { + // 0: DEB_STATUS_A + kD2355_STATUS_A_GPIO8 = (1 << 7), + kD2355_STATUS_A_GPIO7 = (1 << 6), + kD2355_STATUS_A_GPIO6 = (1 << 5), + kD2355_STATUS_A_GPIO5 = (1 << 4), + kD2355_STATUS_A_GPIO4 = (1 << 3), + kD2355_STATUS_A_GPIO3 = (1 << 2), + kD2355_STATUS_A_GPIO2 = (1 << 1), + kD2355_STATUS_A_GPIO1 = (1 << 0), + // 1: DEB_STATUS_B + kD2355_STATUS_B_CHG_ATT = (1 <<7), + kD2355_STATUS_B_CHG_BG_HIGH_TEMP = (1 <<1), + kD2355_STATUS_B_CHG_VBUS_ATT = (1 <<0), + // 2: ADC_STATUS_A + kD2355_STATUS_C_PBUS_CNT_OVERFLOW= (1 << 3), + kD2355_STATUS_C_IBUS_OVERFLOW = (1 << 2), + kD2355_STATUS_C_TBAT = (1 << 1), + kD2355_STATUS_C_VDD_LOW = (1 << 0), + // 3: ADC_STATUS_B + kD2355_STATUS_D_VDDREF_CHG_FALL = (1 << 5), + kD2355_STATUS_D_TMID_DIE_FALL = (1 << 4), + kD2355_STATUS_D_TLINCHG_FALL = (1 << 3), + kD2355_STATUS_D_TVCENTER2_FALL = (1 << 2), + kD2355_STATUS_D_TVCENTER1_FALL = (1 << 1), + kD2355_STATUS_D_TCBUCK_FALL = (1 << 0), + // 4: ADC_STATUS_C + kD2355_STATUS_C_VDDREF_CHG_RISE = (1 << 5), + kD2355_STATUS_C_TMID_DIE_RISE = (1 << 4), + kD2355_STATUS_C_TLINCHG_RISE = (1 << 3), + kD2355_STATUS_C_TVCENTER2_RISE = (1 << 2), + kD2355_STATUS_C_TVCENTER1_RISE = (1 << 1), + kD2355_STATUS_C_TBUCK_RISE = (1 << 0), + // 5: CHG_STATUS_A + kD2355_STATUS_F_CV_LOOP_AVERAGE_SATURATED = (1 << 7), + kD2355_STATUS_F_FAULTY_ADAPTER = (1 << 6), + kD2355_STATUS_F_VBUS_OV = (1 << 5), + kD2355_STATUS_F_RES0 = (1 << 4), + kD2355_STATUS_F_CHG_HV_ATT = (1 << 3), + kD2355_STATUS_F_VBUS_EXT_DET = (1 << 2), + kD2355_STATUS_F_HV_MODE = (1 << 1), + kD2355_STATUS_F_VCENTER_DET = (1 << 0), + // 6: CHG_STATUS_B + kD2355_STATUS_G_CHG_SLOW = (1 << 7), + kD2355_STATUS_G_CHG_BUCK_FLG = (1 << 6), + kD2355_STATUS_G_CHG_ABCC_ACT = (1 << 5), + kD2355_STATUS_G_CHG_TIMEOUT = (1 << 4), + kD2355_STATUS_G_CHG_PRECHG_TIMEOUT = (1 << 3), + kD2355_STATUS_G_CHG_END = (1 << 2), + kD2355_STATUS_G_CHG_FAST = (1 << 1), + kD2355_STATUS_G_CHG_PRE = (1 << 0), + // 7: CHG_STATUS_C + // ... kD2355_STATUS_H + // 8: CHG_STATUS_D + // ... kD2355_STATUS_I + // 9: THRCTL_STATUS_A + // ... kD2355_STATUS_J +}; + +enum { + kD2355_CHG_CTRL_A_TCTR_MASK = 0xf0, + kD2355_CHG_CTRL_A_PCTR_MASK = 0x07, + + kD2355_CHG_CTRL_D_FORCE_VSYS_HI_UVLO = ( 1<<7 ), + kD2355_CHG_CTRL_D_SW_BOOST_OFF = ( 1<<6 ), + kD2355_CHG_CTRL_D_BUCK_BUS_PWR_SUSPEND = ( 1<<5 ), + kD2355_CHG_CTRL_D_ALT_USB_DIS1 = ( 1<<4 ), + kD2355_CHG_CTRL_D_SUSPEND = ( 1<<3 ), + kD2355_CHG_CTRL_D_BAT_PWR_SUSP = ( 1<<2 ), + kD2355_CHG_CTRL_D_HV_CHG_ALLOW = ( 1<<1 ), + kD2355_CHG_CTRL_D_OVP_DIS = ( 1<<0 ), + + kD2355_CHG_CTRL_E_BUCK_EN = ( 1<<7 ), +}; + +enum { +// kDIALOG_CHARGE_CONTROL_EN +// used only in iBoot to clear USB_DIS1 and allow control of usb charge limit via ISET_BUCK +// +// kDIALOG_SYS_CONTROL +// Here used only for kD2355_CHG_CTRL_D_BAT_PWR_SUSP +// kDIALOG_CHARGE_CONTROL_ICHG_BAT_MSB +// Battery current limit (in charger_set_charging() ) +// kDIALOG_CHARGE_BUCK_CONTROL +// USB input current limit, used in charger_set_charging() + + kDIALOG_CHARGE_CONTROL_ICHG_BAT_MSB = kD2355_CHG_ICHG_BAT_MSB, + kDIALOG_OTP_ISET_BAT_MSB = kD2355_CHG_ICHG_BAT_MAX_MSB, + kDIALOG_CHARGE_STATUS_MSB = kD2355_CHG_ICHG_BAT_ACTUAL_MSB, + + kDIALOG_CHARGE_BUCK_CONTROL = kD2355_CHG_ISET_BUCK, + kDIALOG_CHARGE_BUCK_STATUS = kD2355_CHG_ISET_BUCK_ACTUAL, + + kDIALOG_SYS_CONTROL = kD2355_CHG_CTRL_D, + kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND = kD2355_CHG_CTRL_D_BAT_PWR_SUSP, + + // masks + kDIALOG_SYS_CONTROL_HIBERNATE_ALWAYS = 0, + kDIALOG_SYS_CONTROL_CHRG_CONTROLS = kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND, + + kDIALOG_CHARGE_CONTROL_EN = kD2355_CHG_CTRL_D, + kDIALOG_CHARGE_CONTROL_ALT_USB_DIS = kD2355_CHG_CTRL_D_ALT_USB_DIS1, + +// for HighVoltage Charging + kDIALOG_HV_CHG_ALLOW = kD2355_CHG_CTRL_D_HV_CHG_ALLOW, + kDIALOG_HV_CHG_ALLOW_MASK = ( 1<<1 ), +}; + +enum { +// for ISET_BUCK (USB current limit) + kDIALOG_CHARGE_BUCK_CONTROL_MIN = 80, + kDIALOG_CHARGE_BUCK_CONTROL_STEP_PER_100MA = 10, + kDIALOG_CHARGE_BUCK_CONTROL_MAX = 2550, + + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MIN = 0x08, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100 = 0x0a, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_200 = 0x14, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_500 = 0x32, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1000 = 0x64, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_1900 = 0xbf, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2000 = 0xc9, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2100 = 0xd2, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2400 = 0xf0, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_2560 = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MAX = 0xff, + kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK = 0xff, +}; + +enum { +// for ICHG_BAT (Battery Current Limit) + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_MASK = 0x3ff, + kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT = 0, + kDIALOG_OTP_ISET_BAT_SHIFT = kDIALOG_CHARGE_CONTROL_A_ISET_BAT_SHIFT, + kDIALOG_CHARGE_CONTROL_B_CHG_SUSP = (1 << 5), + kDIALOG_CHARGE_CONTROL_CHG_HIB = 0, + + // these are ok, the one above not (not in CHARGE_CONTROL_A!!!) + kDIALOG_CHARGE_CONTROL_ISET_BAT_MASK = 0x3ff, + kDIALOG_CHARGE_CONTROL_ISET_BAT_SHIFT = 0, + + kDIALOG_CHARGE_CONTROL_STEP = 10, + kDIALOG_CHARGE_CONTROL_MAX = 6390, + +}; + +enum { + kDIALOG_CHARGE_CONTROL_TIME = kD2355_CHG_CTRL_A, + + kDIALOG_CHARGE_CONTROL_TIME_TCTR_MASK = kD2355_CHG_CTRL_A_TCTR_MASK, + kDIALOG_CHARGE_CONTROL_TIME_TCTR_DISABLED = 0x00, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_MASK = kD2355_CHG_CTRL_A_PCTR_MASK, + kDIALOG_CHARGE_CONTROL_TIME_PCTR_DISABLED = 0x00, +}; + +// --------------------------------- +// GPADC Control and Result +// --------------------------------- + +// channels +enum { + kD2355_ADC_MUX_SEL_VSYS_LO = 0, + kD2355_ADC_MUX_SEL_ICH_1A, + kD2355_ADC_MUX_SEL_TBAT, + kD2355_ADC_MUX_SEL_VBAT, + kD2355_ADC_MUX_SEL_IBUS_IN_LG, + kD2355_ADC_MUX_SEL_ADC_IN_P, + kD2355_ADC_MUX_SEL_ADC_IN_N, + kD2355_ADC_MUX_SEL_TJINT, + kD2355_ADC_MUX_SEL_IBUS_IN_HG, + + kD2355_ADC_MUX_SEL_VBUS = 10, + kD2355_ADC_MUX_SEL_VCENTER, + kD2355_ADC_MUX_SEL_VSYS_HI, + kD2355_ADC_MUX_SEL_VCENTER_TEMP1, + kD2355_ADC_MUX_SEL_LINCHG_TEMP, + kD2355_ADC_MUX_SEL_CHG_BUCK_TEMP, + kD2355_ADC_MUX_SEL_VCENTER_TEMP0, + kD2355_ADC_MUX_SEL_MID_DIE_TEMP, + kD2355_ADC_MUX_SEL_LV_LDO_TEMP = 18, + + kD2355_ADC_MUX_SEL_BOOST_TEMP = 19, + kD2355_ADC_MUX_SEL_ICH_6A = 29, +}; + +enum { + kDIALOG_ADC_CONTROL_MUX_SEL_VDD_OUT = kD2355_ADC_MUX_SEL_VSYS_LO, // TODO: verify + kDIALOG_ADC_CONTROL_MUX_SEL_ICH_1A = kD2355_ADC_MUX_SEL_ICH_1A, + kDIALOG_ADC_CONTROL_MUX_SEL_TBAT = kD2355_ADC_MUX_SEL_TBAT, + kDIALOG_ADC_CONTROL_MUX_SEL_VBAT = kD2355_ADC_MUX_SEL_VBAT, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG = kD2355_ADC_MUX_SEL_IBUS_IN_LG, + kDIALOG_ADC_CONTROL_MUX_SEL_VIBUS = kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_LG, + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN_P = kD2355_ADC_MUX_SEL_ADC_IN_P, + kDIALOG_ADC_CONTROL_MUX_SEL_ADC_IN_N = kD2355_ADC_MUX_SEL_ADC_IN_N, + kDIALOG_ADC_CONTROL_MUX_SEL_TJUNC = kD2355_ADC_MUX_SEL_TJINT, + kDIALOG_ADC_CONTROL_MUX_SEL_IBUS_IN_HG = kD2355_ADC_MUX_SEL_IBUS_IN_HG, + kDIALOG_ADC_CONTROL_MUX_SEL_VBUS = kD2355_ADC_MUX_SEL_VBUS, + kDIALOG_ADC_CONTROL_MUX_SEL_VCENTER_TEMP1 = kD2355_ADC_MUX_SEL_VCENTER_TEMP1, + kDIALOG_ADC_CONTROL_MUX_SEL_LINCHG_TEMP = kD2355_ADC_MUX_SEL_LINCHG_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_CHG_BUCK_TEMP = kD2355_ADC_MUX_SEL_CHG_BUCK_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_MID_DIE_TEMP = kD2355_ADC_MUX_SEL_MID_DIE_TEMP, + kDIALOG_ADC_CONTROL_MUX_SEL_ICH_6A = kD2355_ADC_MUX_SEL_ICH_6A, + kDIALOG_ADC_CONTROL_MUX_SEL_ICH = kD2355_ADC_MUX_SEL_ICH_1A, + + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_START = kD2355_ADC_MUX_SEL_VCENTER_TEMP1, + kDIALOG_ADC_CONTROL_MUX_SEL_TINT_END = kD2355_ADC_MUX_SEL_LV_LDO_TEMP, + + kDIALOG_ADC_CONTROL2_AUTO_VDD_OUT_EN = (1 << 7), + kDIALOG_ADC_CONTROL2_ICH6A_EN = (1 << 1), + kDIALOG_ADC_CONTROL2_IBUS_EN = (1 << 0), + + kDIALOG_ADC_CONTROL_MAN_CONV = (1 << 7), + kDIALOG_ADC_CONTROL_MUX_SEL_MASK = (0x1f << 0), + kDIALOG_ADC_LSB_ADC_OVL = (1 << 7), + kDIALOG_ADC_LSB_MANADC_ERROR = (1 << 6), + + kDIALOG_ICHG_AVG = kD2355_ADC_ICHG_AVG, + + kDIALOG_ADC_RESOLUTION_BITS = 12, + kDIALOG_ADC_FULL_SCALE_MV = 1500, + kDIALOG_ADC_BRICK_ID_OFFSET_MV = 40, // TODO: verify + + kDIALOG_ADC_MAN_CTL = kD2355_ADC_CTRL1, + kDIALOG_ADC_CONTROL = kD2355_ADC_CTRL1, + + kDIALOG_ADC_LSB = kD2355_ADC_RES_LSB, + kDIALOG_ADC_MSB = kD2355_ADC_RES_MSB, + + kDIALOG_T_OFFSET_MSB = kD2355_T_OFFSET_MSB, + kDIALOG_T_OFFSET_LSB = kD2355_T_OFFSET_LSB, +}; + +enum { + kDIALOG_ADC_CONTROL_DEFAULTS = 0, // TODO: verify + kDIALOG_ADC_CONTROL2_DEFAULTS = 0, // TODO: verify +}; + +// ------------------------------------------------------------------------- +// +// ------------------------------------------------------------------------- + +enum { + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW = (0 << 1), + kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH = (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_MASK = (1 << 6) | (1 << 1), + kDIALOG_SYS_GPIO_DIRECTION_OUT = (1 << 6), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH = (0 << 6) | (0 << 1), + kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_LOW = (0 << 6) | (1 << 1), + + kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ = kDIALOG_SYS_GPIO_DIRECTION_OUT, // not supported + + kDIALOG_SYS_GPIO_REG_START = kD2355_GPIO_GPIO1, +}; + +#define IS_GPIO_OUTPUT(gpio) (((gpio)&kDIALOG_SYS_GPIO_DIRECTION_OUT) == kDIALOG_SYS_GPIO_DIRECTION_OUT) + +// ------------------------------------------------------------------------- +// +// ------------------------------------------------------------------------- + +enum { +// N.B. index in Virtual Registers + kDIALOG_FAULT_LOG_RST = FAULTLOG_FLAG_MAKE(0, (1 << 3)), + kDIALOG_FAULT_LOG_POR = FAULTLOG_FLAG_MAKE(0, (1 << 2)), + kDIALOG_FAULT_LOG_OVER_TEMP = FAULTLOG_FLAG_MAKE(0, (1 << 1)), + kDIALOG_FAULT_LOG_VDD_UNDER = FAULTLOG_FLAG_MAKE(0, (1 << 0)), + + kDIALOG_FAULT_LOG_WDOG = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_3 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_2 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_RESET_IN_1 = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_BTN_SHUTDOWN = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_TWO_FINGER_RESET = kDIALOG_NOTEXIST_MASK, + kDIALOG_FAULT_LOG_NTC_SHDN = kDIALOG_NOTEXIST_MASK, +}; + +enum { +// N.B. index in Virtual Registers + kDIALOG_EVENT_HOLD_BUTTON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_MENU_BUTTON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_RINGER_BUTTON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_BUTTON4_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_BUTTONS_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_PWR_BUTTON_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_ALARM_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_VBUS_DET_MASK = EVENT_FLAG_MAKE(5, kD2355_EVENT_F_VBUS_EXT_DET), + kDIALOG_EVENT_VBUS_EXT_REM_MASK = EVENT_FLAG_MAKE(5, kD2355_EVENT_F_VBUS_EXT_REM), + kDIALOG_EVENT_EOMC_MASK = EVENT_FLAG_MAKE(2, kD2355_EVENT_C_EOMC), + kDIALOG_EVENT_HIB_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ABCC_MASK = EVENT_FLAG_MAKE(6, kD2355_EVENT_G_CHG_ABCC_ACT), + + kDIALOG_EVENT_CHG_END_MASK = EVENT_FLAG_MAKE(6, kD2355_EVENT_G_CHG_END), + kDIALOG_EVENT_TBAT_MASK = EVENT_FLAG_MAKE(2, kD2355_EVENT_C_TBAT), + + kDIALOG_EVENT_GPIO1_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO1), + kDIALOG_EVENT_GPIO2_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO2), + kDIALOG_EVENT_GPIO3_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO3), + kDIALOG_EVENT_GPIO4_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO4), + kDIALOG_EVENT_GPIO5_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO5), + kDIALOG_EVENT_GPIO6_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO6), + kDIALOG_EVENT_GPIO7_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO7), + kDIALOG_EVENT_GPIO8_MASK = EVENT_FLAG_MAKE(0, kD2355_EVENT_A_GPIO8), + kDIALOG_EVENT_GPIO9_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO10_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO11_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO12_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO13_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO14_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO15_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO16_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO17_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO18_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO19_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO20_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_GPIO21_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_HOLD_DBL_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_MENU_DBL_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_RINGER_DBL_MASK = kDIALOG_NOTEXIST_MASK, + + kDIALOG_EVENT_VHP_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_ON_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_EVENT_LDO2_EN_MASK = kDIALOG_NOTEXIST_MASK, +}; + +enum { +// N.B. index in Virtual Registers + kDIALOG_STATUS_USB_MASK = STATUS_FLAG_MAKE(5, kD2355_STATUS_F_VBUS_EXT_DET), + kDIALOG_STATUS_VBUS_MASK = STATUS_FLAG_MAKE(5, kD2355_STATUS_F_VCENTER_DET), + kDIALOG_STATUS_FW_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_ACC_DET_MASK = kDIALOG_NOTEXIST_MASK, + kDIALOG_STATUS_CHARGING_MASK = STATUS_FLAG_MAKE(6, kD2355_EVENT_G_CHG_PRE | kD2355_EVENT_G_CHG_FAST), + kDIALOG_STATUS_CHG_TO_MASK = STATUS_FLAG_MAKE(6, kD2355_EVENT_G_CHG_TIMEOUT), + kDIALOG_STATUS_CHG_END_MASK = STATUS_FLAG_MAKE(6, kD2355_EVENT_G_CHG_END), + kDIALOG_STATUS_TBAT_MASK = STATUS_FLAG_MAKE(2, kD2355_STATUS_C_TBAT), + kDIALOG_STATUS_CHG_ATT_MASK = STATUS_FLAG_MAKE(1, kD2355_STATUS_B_CHG_ATT), + kDIALOG_STATUS_ABCC_MASK = STATUS_FLAG_MAKE(6, kD2355_EVENT_G_CHG_ABCC_ACT), + +#define kDIALOG_STATUS_GPIO_MASK(gpio) STATUS_FLAG_MAKE(0, (1 << ((gpio) % 8))) + +}; + +static const statusRegisters kDialogStatusFWMask = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const statusRegisters kDialogStatusChargingMask = {0, 0, 0, 0, 0, 0, kD2355_STATUS_G_CHG_PRE | kD2355_STATUS_G_CHG_FAST, 0 , 0 , 0}; + +enum { + kD2355_EVENT_A_WAKEMASK = ( kD2355_EVENT_A_GPIO1 | kD2355_EVENT_A_GPIO2 | kD2355_EVENT_A_GPIO3 | kD2355_EVENT_A_GPIO4 | + kD2355_EVENT_A_GPIO5 | kD2355_EVENT_A_GPIO6 | kD2355_EVENT_A_GPIO7 | kD2355_EVENT_A_GPIO8 ), + kD2355_EVENT_B_WAKEMASK = 0, + kD2355_EVENT_C_WAKEMASK = 0, + kD2355_EVENT_D_WAKEMASK = 0, + kD2355_EVENT_E_WAKEMASK = 0, + kD2355_EVENT_F_WAKEMASK = kD2355_EVENT_F_VBUS_EXT_DET | kD2355_EVENT_F_VBUS_EXT_REM | kD2355_EVENT_F_VCENTER_DET, + kD2355_EVENT_G_WAKEMASK = kD2355_EVENT_G_CHG_TIMEOUT | kD2355_EVENT_G_CHG_PRECHG_TIMEOUT | kD2355_EVENT_G_CHG_END, + kD2355_EVENT_H_WAKEMASK = 0, + kD2355_EVENT_I_WAKEMASK = 0, + kD2355_EVENT_J_WAKEMASK = 0, +}; + +// All events that are masked during shutdown - inverse of the wake mask, +// events that wake up the system +static const eventRegisters kDialogEventIntMasks = { + (UInt8)~kD2355_EVENT_A_WAKEMASK, // really LLDB? really? + ~kD2355_EVENT_B_WAKEMASK, + ~kD2355_EVENT_C_WAKEMASK, + ~kD2355_EVENT_D_WAKEMASK, + ~kD2355_EVENT_E_WAKEMASK, + ~kD2355_EVENT_F_WAKEMASK, + ~kD2355_EVENT_G_WAKEMASK, + ~kD2355_EVENT_H_WAKEMASK, + ~kD2355_EVENT_I_WAKEMASK, + ~kD2355_EVENT_J_WAKEMASK, +}; + + +// All wake events without the buttons +static const eventRegisters kDialogEventNotButtonMasks = { + kD2355_EVENT_A_WAKEMASK, + kD2355_EVENT_B_WAKEMASK, + kD2355_EVENT_C_WAKEMASK, + kD2355_EVENT_D_WAKEMASK, + kD2355_EVENT_E_WAKEMASK, + kD2355_EVENT_F_WAKEMASK, + kD2355_EVENT_G_WAKEMASK, + kD2355_EVENT_H_WAKEMASK, + kD2355_EVENT_I_WAKEMASK, + kD2355_EVENT_J_WAKEMASK, +}; + +// All events indicating external power supply +static const eventRegisters kDialogEventPwrsupplyMask = { + 0, + 0, + 0, + 0, + 0, + kD2355_EVENT_F_VBUS_EXT_DET | kD2355_EVENT_F_VCENTER_DET, + 0, + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventUSBMask = { +// in d2231.h only include kD2231_EVENT_A_VBUS_EXT_DET: VCENTER can come and go while charger still usable + 0, + 0, + 0, + 0, + 0, + kD2355_EVENT_F_VBUS_EXT_DET | kD2355_EVENT_F_VCENTER_DET, + 0, // kD2355_STATUS_G_CHG_ABCC_ACT ? + 0, + 0, + 0, +}; + +static const eventRegisters kDialogEventFWMask = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +enum { + // TODO: verify this guys + kDialogEventPwrsupplyCount = 2, + kDialogEventUSBCount = 2, + kDialogEventFWCount = 0, +}; + +// ------------------------------------------------------------------------- +// +// ------------------------------------------------------------------------- + + +#define NUM_LDOS 0 +static const struct ldo_params ldo_d2355[NUM_LDOS] = { + +}; +#define LDOP ldo_d2355 + + +#endif diff --git a/drivers/dialog/pmu/dCommon.h b/drivers/dialog/pmu/dCommon.h new file mode 100644 index 0000000..42f2b68 --- /dev/null +++ b/drivers/dialog/pmu/dCommon.h @@ -0,0 +1,57 @@ +#ifndef __DIALOG_DCOMMON_H +#define __DIALOG_DCOMMON_H + +typedef UInt8 eventRegisters[kDIALOG_EVENT_COUNT]; +typedef UInt8 statusRegisters[kDIALOG_STATUS_COUNT]; +typedef UInt8 faultRegisters[kDIALOG_FAULTLOG_COUNT]; + +// Test whether any of the 'mask' bits is set in 'registers' +static inline bool REGISTER_TEST_MASK(const UInt8 *events, const UInt8 *mask, unsigned int count) { + for (unsigned int i = 0 ; i < count; i++) { + if ((events[i] & mask[i]) != 0) return true; + } + return false; +} + +#define EVENT_FLAG_MAKE(byte,bit) ((UInt16)((byte)&0xff)<<8 | ((bit)&0xff)) +#define EVENT_FLAG_GET_BYTE(flag) ((UInt16)flag>>8) +#define EVENT_FLAG_GET_BIT(flag) (flag&0xff) + +/* return a UInt16 if mismatch, which should warn you */ +#define EVENT_FLAG_GET_BIT_FOR_BYTE(flag,byte) \ + (((flag) & 0xff) | (EVENT_FLAG_GET_BYTE(flag)==(byte) ? 0 : 0xffff)) + +#define EVENT_REGISTERS_GET_BYTE(registers,flag) ((registers)[EVENT_FLAG_GET_BYTE(flag)]) +#define EVENT_FLAG_TEST(registers,flag) ((EVENT_REGISTERS_GET_BYTE(registers,flag)&EVENT_FLAG_GET_BIT(flag)) != 0) +#define EVENT_REGISTER_TEST_MASK(registers,mask) REGISTER_TEST_MASK(registers,mask,kDIALOG_EVENT_COUNT) + +#define STATUS_FLAG_MAKE EVENT_FLAG_MAKE +#define STATUS_FLAG_TEST EVENT_FLAG_TEST +#define STATUS_REGISTER_TEST_MASK(registers,mask) REGISTER_TEST_MASK(registers,mask,kDIALOG_STATUS_COUNT) + +#define FAULTLOG_FLAG_MAKE EVENT_FLAG_MAKE +#define FAULTLOG_FLAG_TEST EVENT_FLAG_TEST +#define FAULTLOG_REGISTER_TEST_MASK(registers,mask) REGISTER_TEST_MASK(registers,mask,kDIALOG_FAULTLOG_COUNT) + +enum { + kDIALOG_NOTEXIST_MASK = EVENT_FLAG_MAKE(0, 0) +}; + +struct ldo_params { + UInt16 minv; + UInt8 step; + UInt8 maxs; + UInt8 stepmask; + UInt8 bypass; + UInt16 ldoreg; + UInt16 actreg; + UInt8 actmask; +}; + +int pmu_uvwarn_config(int dev, uint32_t thresholdMV); +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); +int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); +void pmu_check_events(bool *powersupply_change_event, bool *button_event, bool *other_wake_event); +void pmu_read_events(eventRegisters data); + +#endif diff --git a/drivers/dialog/pmu/power.c b/drivers/dialog/pmu/power.c new file mode 100644 index 0000000..7d4fd8f --- /dev/null +++ b/drivers/dialog/pmu/power.c @@ -0,0 +1,1934 @@ +/* + * Copyright (C) 2008-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if DIALOG_D1755 +#include "d1755.h" +#elif DIALOG_D1815 +#include "d1815.h" +#elif DIALOG_D1881 +#include "d1881.h" +#elif DIALOG_D1946 +#include "d1946.h" +#elif DIALOG_D1972 +#include "d1972.h" +#elif DIALOG_D1974 +#include "d1974.h" +#elif DIALOG_D2018 +#include "d2018.h" +#elif DIALOG_D2045 +#include "d2045.h" +#elif DIALOG_D2089 +#include "d2089.h" +#elif DIALOG_D2186 +#include "d2186.h" +#elif DIALOG_D2207 +#include "d2207.h" +#elif DIALOG_D2238 +#include "d2238.h" +#elif DIALOG_D2255 +#include "d2255.h" +#elif DIALOG_D2257 +#include "d2257.h" +#else +#error Unknown Dialog PMU selection +#endif + +#include "NTCTables.h" + +struct pmu_setup_struct +{ + int pmu; + uint16_t reg; + uint16_t value; +}; + +struct core_rails_struct +{ + int pmu; + uint16_t ctrl_reg; + uint16_t data_reg; +}; + +struct power_rail_s { + uint8_t index; + uint16_t min_mv; + uint16_t max_mv; + uint16_t step_uv; // 3125=3.125 mV +}; +typedef struct power_rail_s target_rails_t[POWER_RAIL_COUNT]; + +// must include this after the above declarations +#define POWERCONFIG_PMU_SETUP 1 +#include + +static uint8_t boot_flags; +static eventRegisters cold_boot_ints; +static bool cold_boot_ints_valid; + +// This goes after the powerconfig +#ifndef MAX_BACKLIGHT_LEVEL +#define MAX_BACKLIGHT_LEVEL ((1 << (WLED_ISET_BITS)) - 1) +#endif + +#ifndef TARGET_BRICKID_FULL_SCALE +#define TARGET_BRICKID_FULL_SCALE (5000) +#endif + +// define PMU_DATA_DEBUG_SPEW as DEBUG_CRITICAL to enable logging +#define PMU_DATA_DEBUG_SPEW DEBUG_SPEW + +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm) +{ + uint8_t confirm; + UInt8 data[kDIALOG_REG_BYTES + 1]; + + if (kDIALOG_REG_BYTES > 1) data[kDIALOG_REG_BYTES - 2] = (reg >> 8) & 0xFF; + data[kDIALOG_REG_BYTES - 1] = (reg & 0xFF); + data[kDIALOG_REG_BYTES] = byte; + + int rc=iic_write(dev, kDIALOG_ADDR_W, data, sizeof(data)); + if ( rc!=0 ) { + dprintf(DEBUG_CRITICAL, "pmu%d: wrote %x to reg %x failed (%d)\n", dev, byte, reg, rc); + } else if (do_confirm) { + iic_read(dev, kDIALOG_ADDR_R, data, sizeof(data)-1, &confirm, 1, IIC_NORMAL); + if (byte == confirm) { + dprintf(PMU_DATA_DEBUG_SPEW, "pmu%d: wrote %x to reg %x\n", dev, byte, reg); + } else { + dprintf(PMU_DATA_DEBUG_SPEW, "pmu%d: try to write %x to reg %x, but got %x back\n", dev, byte, reg, confirm); + return -1; + } + } + + return 0; +} + +int pmu_get_data(int dev, uint16_t reg, uint8_t *byte) +{ + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (reg >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (reg & 0xFF); + + const int rc=iic_read(dev, kDIALOG_ADDR_R, addr, sizeof(addr), byte, 1, IIC_NORMAL); + dprintf(PMU_DATA_DEBUG_SPEW, "pmu%d: read %x from reg %x\n", dev, *byte, reg); + return rc; +} + +void pmu_read_events(eventRegisters data) +{ + bzero(data, sizeof(eventRegisters)); + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (kDIALOG_EVENT_A >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (kDIALOG_EVENT_A & 0xFF); + iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), data, sizeof(eventRegisters), IIC_NORMAL); +} + +static void pmu_read_status(statusRegisters data) +{ + bzero(data, sizeof(statusRegisters)); + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (kDIALOG_STATUS_A >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (kDIALOG_STATUS_A & 0xFF); + iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), data, sizeof(statusRegisters), IIC_NORMAL); +} + +static void pmu_write_mask(const eventRegisters data) +{ + uint8_t bytes[sizeof(eventRegisters) + kDIALOG_REG_BYTES]; + + if (kDIALOG_REG_BYTES > 1) bytes[kDIALOG_REG_BYTES - 2] = (kDIALOG_IRQ_MASK_A >> 8) & 0xFF; + bytes[kDIALOG_REG_BYTES - 1] = (kDIALOG_IRQ_MASK_A & 0xFF); + memcpy(bytes+kDIALOG_REG_BYTES, data, sizeof(eventRegisters)); + + iic_write(PMU_IIC_BUS, kDIALOG_ADDR_W, bytes, sizeof(bytes)); +} + +static int pmu_read_nvram(uint16_t addr, void *buffer, uint8_t count) +{ + uint8_t bytes[kDIALOG_REG_BYTES]; + + if (kDIALOG_REG_BYTES > 1) bytes[kDIALOG_REG_BYTES - 2] = (addr>>8) & 0xFF; + bytes[kDIALOG_REG_BYTES - 1] = (addr & 0xFF); + + return iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, bytes, sizeof(bytes), buffer, count, IIC_NORMAL); +} + +static int pmu_write_nvram(uint16_t addr, void *buffer, uint8_t count) +{ + uint8_t bytes[kDIALOG_REG_BYTES+count]; + + if (kDIALOG_REG_BYTES > 1) bytes[kDIALOG_REG_BYTES - 2] = (addr>>8) & 0xFF; + bytes[kDIALOG_REG_BYTES - 1] = (addr & 0xFF); + + memcpy(bytes+kDIALOG_REG_BYTES, buffer, count); + + return iic_write(PMU_IIC_BUS, kDIALOG_ADDR_W, bytes, kDIALOG_REG_BYTES + count); +} + +static int +power_read_memory_calibration_data(uint16_t addr, void *buffer, uint32_t length) +{ + for (uint32_t size=0, count=0; length-count ; count+=size) { + size=length-count; + if ( size>64 ) size=64; + + const bool success=( pmu_read_nvram(addr+count, ((char*)buffer)+count, size) == 0 ); + if ( !success ) return 1; + } + + return 0; +} + +static int +power_write_memory_calibration_data(uint16_t addr, void *buffer, uint32_t length) +{ + for (uint32_t size=0, count=0; length-count ; count+=size) { + size=length-count; + if ( size>64 ) size=64; + + const bool success=( pmu_write_nvram(addr+count, ((char*)buffer)+count, size) == 0 ); + if ( !success ) return 1; + } + + return 0; +} + +// @pre settings is kDIALOG_EXT_MEM_CAL_SIZE byes +bool +power_load_memory_calibration(void *settings, uint32_t length) { + +#if PMU_HAS_RAM && !DIALOG_D2238 + uint32_t count=0, size; + if ((!settings) || (length > kDIALOG_EXT_MEM_CAL_SIZE)) return false; + + bzero(settings, length); + + size=( length>kDIALOG_EXT_MEM_CAL0_SIZE ) ? kDIALOG_EXT_MEM_CAL0_SIZE : length ; + if ( pmu_read_nvram(kDIALOG_EXT_MEM_CAL0, &settings[count], size)!=0 ) return false; + length-=size; count+=size; + + if ( length ) { + size= ( length>kDIALOG_EXT_MEM_CAL1_SIZE ) ? kDIALOG_EXT_MEM_CAL1_SIZE : length ; + if ( power_read_memory_calibration_data(kDIALOG_EXT_MEM_CAL1, &settings[count], size)!=0 ) return false; + length-=size; count+=size; + } + +#if DIALOG_D2257 + if ( length ) { + size= ( length>kDIALOG_EXT_MEM_CAL2_SIZE ) ? kDIALOG_EXT_MEM_CAL2_SIZE : length ; + if ( power_read_memory_calibration_data(kDIALOG_EXT_MEM_CAL2, &settings[count], size)!=0 ) return false; + length-=size; count+=size; + } +#endif + + if ( length ) dprintf(DEBUG_SPEW, "WARN: power_load_memory_calibration remainder=%d\n", length); + + return true; +#endif + + return false; +} + +bool +power_store_memory_calibration(void *settings, uint32_t length) { + +#if PMU_HAS_RAM && !DIALOG_D2238 + uint32_t count=0, size; + + if ((!settings) || (length > kDIALOG_EXT_MEM_CAL_SIZE)) return false; + + size=(length>kDIALOG_EXT_MEM_CAL0_SIZE)?kDIALOG_EXT_MEM_CAL0_SIZE:length; + if ( power_write_memory_calibration_data(kDIALOG_EXT_MEM_CAL0, &settings[count], size)!=0 ) return false; + length-=size; count+=size; + + if ( length ) { + size=(length>kDIALOG_EXT_MEM_CAL1_SIZE)?kDIALOG_EXT_MEM_CAL1_SIZE:length; + if ( power_write_memory_calibration_data(kDIALOG_EXT_MEM_CAL1, &settings[count], size)!=0 ) return false; + length-=size; count+=size; + } + +#if DIALOG_D2257 + if ( length ) { + size=(length>kDIALOG_EXT_MEM_CAL2_SIZE)?kDIALOG_EXT_MEM_CAL2_SIZE:length; + if ( power_write_memory_calibration_data(kDIALOG_EXT_MEM_CAL2, &settings[count], size)!=0 ) return false; + length-=size; count+=size; + } +#endif + + if ( length ) dprintf(DEBUG_SPEW, "WARN: power_store_memory_calibration remainder=%d\n", length); + + return true; +#endif + + return false; +} + + +// @pre settings is kDIALOG_VOLTAGE_KNOBS_SIZE bytes +bool +power_load_voltage_knobs(void *settings, uint32_t length) { + bool success=false; + +#if WITH_VOLTAGE_KNOBS + if ((!settings) || (length != kDIALOG_VOLTAGE_KNOBS_SIZE)) return false; + + bzero(settings, length); + + success=( 0 == pmu_read_nvram(kDIALOG_VOLTAGE_KNOBS, settings, length) ); +#endif + + return success; +} + +bool +power_store_voltage_knobs(void *settings, uint32_t length) { + bool success=false; + +#if WITH_VOLTAGE_KNOBS + if ((!settings) || (length != kDIALOG_VOLTAGE_KNOBS_SIZE)) return false; + + success=(0 == pmu_write_nvram(kDIALOG_VOLTAGE_KNOBS, settings, length)); +#endif + + return success; +} + +#if DIALOG_D2255 || DIALOG_D2257 +static int +dialog_read_adc(int dev, unsigned input_select, unsigned *level) +{ + int result; + const uint16_t man_ctrl_addr=kDIALOG_ADC_MAN_CTL; + const uint8_t channel_index=input_select & kDIALOG_ADC_CONTROL_MUX_SEL_MASK; + + result=pmu_set_data(dev, man_ctrl_addr, channel_index, 0); + if ( result!=0 ) return -1; + + int done=0; + uint8_t data[2]; // MAN*_RES_LSB, MAN*_RES_MSB + uint8_t addr[2] = { (kDIALOG_ADC_LSB >> 8) & 0xFF, (kDIALOG_ADC_LSB & 0xFF)}; + const utime_t end_time = system_time() + 50*1000 ; + + do { + spin(1000); + + result=iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), &data[0], sizeof(data), IIC_NORMAL); + if ( result!=0 ) break; + + done=( (data[0]&kDIALOG_ADC_LSB_MANADC_ERROR)==0 ); + if ( done ) { + *level = ((unsigned)data[1] << 4) | (data[0] & 0xf); + } else if ( system_time() > end_time ) { + result=-1; + dprintf(DEBUG_CRITICAL, "dialog_read_adc timeout, MUX_SEL=%x\n", input_select); + break; + } + + } while ( !done ); + +#if DIALOG_D2255 + // Antigua130 inverts the ADC bits for these channels + if (input_select == kD2255_ADC_CONTROL_MUX_SEL_VDD_MAIN || + input_select == kD2255_ADC_CONTROL_MUX_SEL_BRICK_ID || + input_select == kD2255_ADC_CONTROL_MUX_SEL_APP_MUX_A || + input_select == kD2255_ADC_CONTROL_MUX_SEL_APP_MUX_B) { + + // check for 2265 part (Antigua130) + uint8_t antigua130; + uint8_t addr[2] = { (kD2265_IMPLEMENTATION >> 8) & 0xFF, (kD2265_IMPLEMENTATION & 0xFF)}; + result=iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), &antigua130, 1, IIC_NORMAL); + + if ( (result == 0) && (antigua130 == kD2265_130NM) ) { + *level = ~(*level) & ((1 << kDIALOG_ADC_RESOLUTION_BITS) - 1); + } + } + dprintf (DEBUG_SPEW, "kD2255_ADC_CONTROL_(%d): 2265 bit inverting %#x -> %#x\n", input_select, ((unsigned)data[1] << 4) | (data[0] & 0xf), *level); +#endif + + // clear EOC + eventRegisters ints_pending; + pmu_read_events(ints_pending); + + return result; +} +#else +static int +dialog_read_adc(int dev, unsigned input_select, unsigned *level) +{ + int result = 0; + uint8_t data[2]; + uint8_t reg; + utime_t start_time; + int timeoutOccurred; +#if ADC_TIMEOUT_STATISTICS + int chg_dis=0; +#endif +#if ADC_TIMEOUT_WORKAROUND + int numTimeouts=0; +#endif + + reg = (input_select & kDIALOG_ADC_CONTROL_MUX_SEL_MASK) | kDIALOG_ADC_CONTROL_DEFAULTS; + +#if !DIALOG_D2238 + if (kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID == input_select) { +#if DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2238 + pmu_set_data(dev, kDIALOG_ADC_CONTROL2, kDIALOG_ADC_CONTROL2_ADC_REF_EN, 0); +#else + pmu_set_data(dev, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_ADC_REF_EN | reg, 0); + reg |= kDIALOG_ADC_CONTROL_ADC_REF_EN; +#endif + spin(80 * 1000); + } +#endif + + pmu_set_data(dev, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_MAN_CONV | reg, 0); + +#if ADC_TIMEOUT_WORKAROUND +continue_conv: +#endif + start_time = system_time(); + timeoutOccurred = 0; + do { + spin(1000); + + if (system_time() > (start_time + 50*1000)) + { + dprintf(DEBUG_CRITICAL, + "dialog_read_adc timeout, MUX_SEL=%x\n", + input_select); +#if ADC_TIMEOUT_WORKAROUND + timeoutOccurred = 1; + break; +#else + return -1; +#endif + } + + pmu_get_data(dev, kDIALOG_ADC_CONTROL, ®); + } while ((reg & kDIALOG_ADC_CONTROL_MAN_CONV) != 0); + +#if ADC_TIMEOUT_WORKAROUND + enum adc_issues { + kRetriesDidntHelp = 0x01, + kAutoConversionVDD = 0x02, + kAutoConversionTemp = 0x04, + kBatPwrSuspNotAsserted = 0x08, + kChrgDisabled = 0x10 + }; + + if(timeoutOccurred) { + uint8_t issues = 0; +#if ADC_TIMEOUT_STATISTICS + // Write timeout count to scratchpad + if(numTimeouts==0) { + pmu_get_data(dev, kDIALOG_MEMBYTE0+0x09, &data[0]); + if(data[0]<255) data[0]++; + pmu_set_data(dev, kDIALOG_MEMBYTE0+0x09, data[0], 0); + } + // Check that auto conversions are disabled + uint8_t adc_regs[5]; + reg = kDIALOG_ADC_CONTROL; + iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, ®, 1, &adc_regs[0], + sizeof(adc_regs), IIC_NORMAL); + if(adc_regs[0] & kDIALOG_ADC_CONTROL_AUTO_VDD_OUT_EN) + issues |= kAutoConversionVDD; + if(adc_regs[4] & 0x80) issues |= kAutoConversionTemp; + // Check that we're charging. Not treating this as critical yet, + // but if we're not charging this might be a reason the workaround + // could fail + pmu_get_data(dev, kDIALOG_STATUS_A, &data[0]); + if((data[0]&kD1815_STATUS_A_VBUS_DET)==0) chg_dis |= 1; + // Check that bat_pwr_susp is enabled + pmu_get_data(dev, kDIALOG_SYS_CONTROL, &data[0]); + if((data[0]&kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND)==0) + issues |= kBatPwrSuspNotAsserted; +#endif + numTimeouts++; + if(numTimeouts > 10) issues |= kRetriesDidntHelp; + // Trouble? Give up + if(issues) { +#if ADC_TIMEOUT_STATISTICS + // Charging was disabled anytime we tried the workaround + if(chg_dis) issues |= kChrgDisabled; + // Write issues to scratchpad + pmu_set_data(dev, kDIALOG_MEMBYTE0+0x8, issues, 0); + // Write reset count to scratchpad + pmu_get_data(dev, kDIALOG_MEMBYTE0+0x0a, &data[0]); + if(data[0]<255) data[0]++; + pmu_set_data(dev, kDIALOG_MEMBYTE0+0x0a, data[0], 0); +#endif + // PMU register reset + pmu_get_data(dev, 0xE0, &data[0]); + data[0]|=1; // test_enable + pmu_set_data(dev, 0xE0, data[0], 0); + data[0]|=3; // test_enable|SW_RESET + pmu_set_data(dev, 0xE0, data[0], 0); + // NOTREACHED + while(1); + } else { + pmu_get_data(dev, kDIALOG_SYS_CONTROL, &data[0]); + // Clear BAT_PWR_SUSP + data[0] &= ~kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND; + pmu_set_data(dev, kDIALOG_SYS_CONTROL, data[0], 0); + // Wait + spin(1300); + // Set BAT_PWR_SUSP + data[0] |= kDIALOG_SYS_CONTROL_BAT_PWR_SUSPEND; + pmu_set_data(dev, kDIALOG_SYS_CONTROL, data[0], 0); + // Try again! + goto continue_conv; + } + } +#endif /* ADC_TIMEOUT_WORKAROUND */ + + UInt8 addr[kDIALOG_REG_BYTES]; + if (kDIALOG_REG_BYTES > 1) addr[kDIALOG_REG_BYTES - 2] = (kDIALOG_ADC_LSB >> 8) & 0xFF; + addr[kDIALOG_REG_BYTES - 1] = (kDIALOG_ADC_LSB & 0xFF); + iic_read(PMU_IIC_BUS, kDIALOG_ADDR_R, addr, sizeof(addr), &data[0], sizeof(data), IIC_NORMAL); + + pmu_set_data(dev, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS, 0); +#if DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2238 + pmu_set_data(dev, kDIALOG_ADC_CONTROL2, kDIALOG_ADC_CONTROL2_DEFAULTS, 0); +#endif + +#if DIALOG_D1755 + *level = ((unsigned)data[1] << 2) | (data[0] & 0x3); +#else + *level = ((unsigned)data[1] << 4) | (data[0] & 0xf); +#endif + + return result; +} +#endif + +int +pmu_uvwarn_config(int dev, uint32_t thresholdMV) +{ + int rc=-1; // not supported + +#if DIALOG_D2257 + rc=pmu_set_data(dev, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA, false); + if ( rc<0 ) { + + } else { + uint8_t uv_dig_conf; + + rc=pmu_get_data(dev, kD2257_IPK_UV_BUCK1_UV_DIG_CONF_1, &uv_dig_conf); + if ( rc<0 ) { + dprintf(DEBUG_CRITICAL, "pmu: cannot read UV_CONF (%d)\n", rc); + } else { + if ( thresholdMV!=0 ) { + u_int32_t uv_en_thr; + + rc=power_get_rail_value(POWER_RAIL_GPU, thresholdMV, &uv_en_thr); + if ( rc==0 ) rc=pmu_set_data(dev, kD2257_IPK_UV_BUCK1_UV_EN_THR, uv_en_thr, true); + + uv_dig_conf|=1<<0; // UV_EN + } else { + uv_dig_conf&=0xfe; // clear UV_EN + } + + if ( rc==0 ) rc=pmu_set_data(dev, kD2257_IPK_UV_BUCK1_UV_DIG_CONF_1, uv_dig_conf, true); + } + + int temp=pmu_set_data(dev, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS, false); + if ( temp<0 ) panic("pmu: cannot exit test mode\n"); + } +#endif + + return rc; +} + +static int +dialog_read_battery_level(int dev, unsigned *level) +{ + int result; + +#if DIALOG_D2255 +// PFIXME: D2255 need to use charger_read_battery_level() + result = 0; +#else + unsigned adc = 0; + + result = dialog_read_adc(dev, kDIALOG_ADC_CONTROL_MUX_SEL_VBAT, &adc); + +#if DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2238 || DIALOG_D2231 + *level = ((adc * 2500) >> kDIALOG_ADC_RESOLUTION_BITS) + 2500; +#else + *level = ((adc * 2000) >> kDIALOG_ADC_RESOLUTION_BITS) + 2500; +#endif + +#endif + return result; +} + +static int lut_interpolate(const struct NTCLUT * const LUT, const uint32_t R) +{ + int idx=0; + uint32_t upper, lower, R1, R2; + int32_t T1, T2; + do { + upper = LUT[idx].ohm; + lower = LUT[idx+1].ohm; + // Is our lookup value within the range of the two table entries? + // This is also true if the lookup value is outside the table + // range; we just interpolate from the last table entries. + if((R<=lower) && (LUT[idx+2].ohm != 0)) { + idx++; + continue; + } + + // Subtract the lower limit, so lower is the zero offset for interpolation + R1 = upper-lower; + R2 = R - lower; + T1 = LUT[idx].centiCelsius - LUT[idx+1].centiCelsius; + // The interpolation. + // (T1/T2) = (R1/R2) <=> T2 = ( (T1*R2) / R1 ) + T2 = ( (T1*(int32_t)R2) / (int32_t)R1 ); + // Add back the lower limit to our result. + T2 += LUT[idx+1].centiCelsius; + + dprintf(DEBUG_SPEW, "LUTInterpolate: R=%d, R1=%d, R2=%d, T1=%d, T2=%d\n", + R, R1, R2, T1, T2); + break; + } while(1); + + return T2; +} + +static int +dialog_read_battery_temperature(int *level) +{ + int result; +#if DIALOG_D2255 +// PFIXME: D2255 need to use charger_read_battery_temperature() + result=-1; +#else + unsigned adc = 0; + + if (level == NULL) return -1; + + result = dialog_read_adc(PMU_IIC_BUS, kDIALOG_ADC_CONTROL_MUX_SEL_TBAT, &adc); + + if (result == 0) { + // The NTC is connected to a 50uA current source + // R = U / I; 1/I = 1/50uA = 20000 * 1/A + // U = * / + // adc_fsr comes in mV, take the factor of 1000 out of current constant + const uint32_t Rntc = (adc * (20000/1000) * kDIALOG_ADC_FULL_SCALE_MV) >> kDIALOG_ADC_RESOLUTION_BITS; + dprintf(DEBUG_SPEW, "ADC chan %d: value=%d, Rntc=%d\n", kDIALOG_ADC_CONTROL_MUX_SEL_TBAT, adc, Rntc); + *level=lut_interpolate(NTCG103JF103F, Rntc); + } +#endif + return result; +} + +static int +dialog_use_setup(const struct pmu_setup_struct *setup, uint32_t count) +{ + uint32_t i; + + /* set pmu registers from the list */ + for (i = 0; i < count; i++) { + pmu_set_data(setup[i].pmu, setup[i].reg, setup[i].value, true); + } + + return 0; +} + +// assume that the offset of the lock register from the VSEL register is fixed +static int +dialog_lock_buck_vsel(int dev, uint16_t buck_vsel) +{ +#if PMU_HAS_VSEL_LOCK + const uint16_t buck_vsel_lock=buck_vsel+kDIALOG_BUCK_VSEL_LOCK_OFFSET; + //dprintf(DEBUG_CRITICAL, " pmu: locking vsel_lock_addr=%x\n", buck_vsel_lock); + return pmu_set_data(dev, buck_vsel_lock, kDIALOG_BUCK_VSEL_LOCK_EN, true); +#else + return 0; +#endif +} + +u_int32_t +pmu_read_brick_id_level(void) +{ +#if !DIALOG_D2238 + uint32_t adc = 0; + + if (dialog_read_adc(PMU_IIC_BUS, kDIALOG_ADC_CONTROL_MUX_SEL_BRICK_ID, &adc)) + return 0; + + // Scale to a 1mV resolution - 5000mV is full scale + return (adc * TARGET_BRICKID_FULL_SCALE) >> kDIALOG_ADC_RESOLUTION_BITS; +#else + return 0; +#endif +} + +int pmu_read_system_temperature(int idx, int *centiCelsiusTemperature) +{ + int result; + unsigned adc = 0; + + result = dialog_read_adc(PMU_IIC_BUS, kDIALOG_ADC_CONTROL_MUX_SEL_NTC0 + idx, &adc); + + if (result == 0) { + // The NTC is connected to a 50uA current source + // R = U / I; 1/I = 1/50uA = 20000 * 1/A + // U = * / + // adc_fsr comes in mV, take the factor of 1000 out of current constant + const uint32_t Rntc = (adc * (20000/1000) * kDIALOG_ADC_FULL_SCALE_MV) >> kDIALOG_ADC_RESOLUTION_BITS; + dprintf(DEBUG_SPEW, "ADC chan %d: value=%d, Rntc=%d\n", kDIALOG_ADC_CONTROL_MUX_SEL_NTC0, adc, Rntc); + *centiCelsiusTemperature=lut_interpolate(NTCG103JF103F, Rntc); + } + + return result; + +} + +/* pmu_early_init() is only called in iBSS and LLB - not in iBoot or iBEC. */ +void +pmu_early_init(void) +{ + int rc; + u_int8_t data; + + /* Get and clear the boot flags, ie. kDIALOG_EVENT_B_HIB. */ + /* Events in this register are lost over sleep/wake, so they're stored for the OS later */ + rc=pmu_get_data(PMU_IIC_BUS, kDIALOG_EVENT_A + EVENT_FLAG_GET_BYTE(kDIALOG_EVENT_HIB_MASK), &boot_flags); + if ( rc!=0 ) dprintf(DEBUG_CRITICAL, "pmu%d: cannot read HIB_MASK (%d)\n", PMU_IIC_BUS, rc); + + /* Set all the warm boot defaults */ + dialog_use_setup(pmu_warm_init, sizeof(pmu_warm_init)/sizeof(pmu_warm_init[0])); + + if (!power_is_suspended()) { + dialog_use_setup(pmu_cold_init, sizeof(pmu_cold_init)/sizeof(pmu_cold_init[0])); +#if PMU_COLD_INIT_AP_DEV + if (target_config_dev()) { + dialog_use_setup(pmu_cold_init_dev, sizeof(pmu_cold_init_dev)/sizeof(pmu_cold_init_dev[0])); + } else { + dialog_use_setup(pmu_cold_init_ap, sizeof(pmu_cold_init_ap)/sizeof(pmu_cold_init_ap[0])); + } +#endif + +#if DIALOG_D1946 + /* Force sync mode on P105 proto 1 only */ + pmu_get_data(PMU_IIC_BUS, kDIALOG_CHIP_ID, &data); + if (data == 0x45) { + pmu_set_data(PMU_IIC_BUS, kDIALOG_BANKSEL, 1, true); // Bank 1 + pmu_set_data(PMU_IIC_BUS, kD1946_BUCK_CONTROL1, 0x0e, true); // Buck0 sync mode, 1250mA limit per phase + pmu_set_data(PMU_IIC_BUS, kD1946_BUCK_CONTROL3, 0x0e, true); // Buck2 sync mode, 1250mA limit per phase + pmu_set_data(PMU_IIC_BUS, kDIALOG_BANKSEL, 0, true); + } +#endif +#if DIALOG_D1881 + // Update PMU settings to support PRQs + pmu_get_data(PMU_IIC_BUS, kDIALOG_CHIP_ID, &data); + data &= kD1881_CHIP_ID_MRC_MASK; + + // Angelina prior to Revision B1 requires adjustment to OTP buck parameters + // N94 Force PWM for buck 0/2 in iboot + if (data < kD1881_CHIP_ID_MRC_B1) { + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK_CONTROL1, 0x0a, true); // buck0 sync mode, 1.25A limit per phase + pmu_set_data(PMU_IIC_BUS, kDIALOG_BUCK_CONTROL3, 0x0e, true); // buck2 sync mode, 1.55A limit per phase + } +#endif + /* Make sure we don't hit the interrupt-squashing + * behavior. See */ + pmu_get_data(PMU_IIC_BUS, kDIALOG_EVENT_A + kDIALOG_EVENT_COUNT - 1, &data); +#if DIALOG_D1881 + // + pmu_set_data(PMU_IIC_BUS, kDIALOG_BANKSEL, 1, true); + pmu_get_data(PMU_IIC_BUS, 0xAD, &data); + if (data & 0x60) { + pmu_set_data(PMU_IIC_BUS, kD1881_TEST_MODE, 1, true); // Enable test mode + pmu_set_data(PMU_IIC_BUS, 0xE4, 8, true); + pmu_set_data(PMU_IIC_BUS, 0xAD, data & ~0x60, true); // Clear softstart + pmu_set_data(PMU_IIC_BUS, 0xE4, 0, true); + pmu_set_data(PMU_IIC_BUS, kD1881_TEST_MODE, 0, true); // Disable test mode + } + pmu_set_data(PMU_IIC_BUS, kDIALOG_BANKSEL, 0, true); +#endif +#if DIALOG_D2018 + // P102: WLED boost frequency incorrectly set to 2MHz in the initial A0 samples + pmu_get_data(PMU_IIC_BUS, kDIALOG_CHIP_ID, &data); + if (data == 0x20) { + dialog_use_setup(pmu_cold_init_a0_samples, sizeof(pmu_cold_init_a0_samples)/sizeof(pmu_cold_init_a0_samples[0])); + } +#endif +#if DIALOG_D1972 + // N41 Test iBoot - VDD_SRAM DVC down-ramp + pmu_get_data(PMU_IIC_BUS, kDIALOG_CHIP_ID, &data); + if (data == 0x34) { + pmu_set_data(PMU_IIC_BUS, kD1972_TEST_MODE, 0x1d, true); // Enable test mode + pmu_set_data(PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01, true); // Select bank1 + pmu_set_data(PMU_IIC_BUS, 0xb2, 0xf1, true); // Change LDO16 soak field + pmu_set_data(PMU_IIC_BUS, 0xb3, 0x2f, true); // Change LDO16 pull down strength to 150mA + pmu_set_data(PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00, true); // Select bank0 + pmu_set_data(PMU_IIC_BUS, kD1972_TEST_MODE, 0x00, true); // Disable test mode + } +#endif /* DIALOG_D1972 */ +#if DIALOG_D2257 + + // Re: Aria A0 - Change OTP settings of PMU for better buck response + data=0xff; + pmu_get_data(PMU_IIC_BUS, kDIALOG_CHIP_ID, &data); + if ( data==0x00 ) { + uint8_t plat_id=0xff; + + pmu_get_data(PMU_IIC_BUS, kDIALOG_PLATFORM_ID, &plat_id); + if ( plat_id==0x01 || plat_id==0x02 ) { + data=0xff; + + pmu_get_data(PMU_IIC_BUS, kDIALOG_TRIM_REL_CODE, &data); + if ( data==0x02 ) { + int rc; + + rc=pmu_set_data(PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA, false); + if ( rc!=0 ) { + dprintf(DEBUG_CRITICAL, "D2257: cannot enter PMU test mode\n"); + } else { + rc=pmu_set_data(PMU_IIC_BUS, 0x1161, 0x0a, true); + if ( rc==0 ) rc=pmu_set_data(PMU_IIC_BUS, 0x1861, 0x0a, true); + if ( rc==0 && plat_id==0x2 ) rc=pmu_set_data(PMU_IIC_BUS, 0x3af, 0x44, true); + if ( rc==0 ) rc=pmu_set_data(PMU_IIC_BUS, 0x1792, 0x7B, true); + if ( rc!=0 ) { + dprintf(DEBUG_CRITICAL, "D2257: cannot apply fix for PMU A0 silicon (%d)\n", rc); + } else { + dprintf(DEBUG_CRITICAL, "D2257: PMU A0 fixups ok\n"); + } + + rc=pmu_set_data(PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS, false); + if ( rc!=0 ) panic("D2257: cannot exit PMU test mode"); + } + } + } + } + +#endif + } +} + +/* pmu_setup() is only called in iBSS and LLB - not in iBoot or iBEC. */ +void pmu_setup(void) +{ + /* Set core voltage to the platform's base soc voltage */ + power_set_soc_voltage(platform_get_base_soc_voltage(), false); + +#if !WITH_CPU_APSC + /* Set cpu voltage to the platform's base cpu voltage */ + power_set_cpu_voltage(platform_get_base_cpu_voltage(), false); +#endif + + /* Set ram voltage to the platform's base ram voltage */ + power_set_ram_voltage(platform_get_base_ram_voltage(), false); + +#if DIALOG_D1972 || DIALOG_D2018 || DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 + uint8_t data; + /* Enable DWI from the start — we need to ensure this happens on wakeup */ + pmu_get_data(PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, &data); + data |= kDIALOG_SYS_CONTROL2_DWI_EN; + pmu_set_data(PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, data, true); +#endif + +#if DIALOG_D2018 + /* Enable DWI for BUCK[0,2] & LDO16 */ + pmu_set_data(PMU_IIC_BUS, kD2018_BUCK_DWI, kDIALOG_DWI_BUCK0_DWI_EN | + kDIALOG_DWI_BUCK2_DWI_EN | kDIALOG_DWI_LDO16_DWI_EN | + kDIALOG_DWI_CPUA_EN_CTRL | kDIALOG_DWI_CPUB_EN_CTRL, true); +#endif + + /* Initialize the LDOs to default values */ + dialog_use_setup(pmu_ldo_warm_setup, sizeof(pmu_ldo_warm_setup)/sizeof(pmu_ldo_warm_setup[0])); + if (!power_is_suspended()) { + dialog_use_setup(pmu_ldo_cold_setup, sizeof(pmu_ldo_cold_setup)/sizeof(pmu_ldo_cold_setup[0])); +#if PMU_LDO_COLD_SETUP_AP_DEV + if (target_config_dev()) { + dialog_use_setup(pmu_ldo_cold_setup_dev, sizeof(pmu_ldo_cold_setup_dev)/sizeof(pmu_ldo_cold_setup_dev[0])); + } else { + dialog_use_setup(pmu_ldo_cold_setup_ap, sizeof(pmu_ldo_cold_setup_ap)/sizeof(pmu_ldo_cold_setup_ap[0])); + } +#endif + } + +#if PMU_HAS_VSEL_LOCK && !DEBUG_BUILD + unsigned i; + + for (i= 0; (i != sizeof(ram_rails)/sizeof(ram_rails[0])); i++) { + dialog_lock_buck_vsel(ram_rails[i].pmu, ram_rails[i].data_reg); + } +#endif + +} + +void +pmu_late_init(void) +{ +#if DIALOG_D1755 + u_int8_t otp_iset_usb; + u_int8_t test_mode; + int error = 0; + + pmu_get_data(PMU_IIC_BUS, kD1755_OTP_ISET_USB, &otp_iset_usb); + pmu_get_data(PMU_IIC_BUS, kD1755_TEST_MODE, &test_mode); + + if ((otp_iset_usb & kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK) != kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100) { + // enter test mode + test_mode = kD1755_TEST_MODE_TEST_EN; + pmu_set_data(PMU_IIC_BUS, kD1755_TEST_MODE, test_mode, true); + + // override OTP shadow register: 350mA -> 100mA + otp_iset_usb = (otp_iset_usb & ~kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_MASK) | kDIALOG_CHARGE_BUCK_CONTROL_ISET_BUCK_100; + error = pmu_set_data(PMU_IIC_BUS, kD1755_OTP_ISET_USB, otp_iset_usb, true); + } + + // exit test mode if enabled + if ((error == 0) && (test_mode & kD1755_TEST_MODE_TEST_EN)) { + test_mode = 0; + error = pmu_set_data(PMU_IIC_BUS, kD1755_TEST_MODE, test_mode, true); + } + + // Dialog recommends that if this sequence fails, the PMU should be reset + if (error != 0) { + pmu_set_data(PMU_IIC_BUS, kD1755_TEST_MODE, kD1755_TEST_MODE_TEST_EN | kD1755_TEST_MODE_RESET_PMU, true); + pmu_set_data(PMU_IIC_BUS, kD1755_TEST_MODE, kD1755_TEST_MODE_TEST_EN | kD1755_TEST_MODE_RESET_PMU, true); + } +#endif +} + +extern bool dialog_charger_check_usb_change(const eventRegisters ints_pending, const statusRegisters status); + +void +pmu_check_events(bool *powersupply_change_event, bool *button_event, bool *other_wake_event) +{ + eventRegisters ints_pending; + statusRegisters status; + + /* Read & clear interrupts */ + pmu_read_events(ints_pending); + pmu_read_status(status); + +#if !WITH_HW_CHARGER && !DIALOG_D2238 && !DIALOG_D2255 + *powersupply_change_event = dialog_charger_check_usb_change(ints_pending, status); +#else + *powersupply_change_event = false; +#endif + + // remove power supply events from ints_pending so that they are not picked up by + // the secondary checks; powersupply_changed will always be true if it's an + // event we still care about + for (int i = 0; i < kDIALOG_EVENT_COUNT; i++) { + ints_pending[i] &= ~kDialogEventPwrsupplyMask[i]; + } + + // PMU only wakes on ACC_DET assert, but event fires on either edge. Remove + // accessory detach events. + if (EVENT_FLAG_TEST(ints_pending, kDIALOG_EVENT_ACC_DET_MASK) && !STATUS_FLAG_TEST(status, kDIALOG_STATUS_ACC_DET_MASK)) { + EVENT_REGISTERS_GET_BYTE(ints_pending, kDIALOG_EVENT_ACC_DET_MASK) &= ~EVENT_FLAG_GET_BIT(kDIALOG_EVENT_ACC_DET_MASK); + } + + *button_event = EVENT_FLAG_TEST(ints_pending, kDIALOG_EVENT_BUTTONS_MASK); + *other_wake_event = EVENT_FLAG_TEST(ints_pending, kDIALOG_EVENT_ACC_DET_MASK) || EVENT_FLAG_TEST(ints_pending, kDIALOG_EVENT_ALARM_MASK); +} + +static int +do_pmem_cmd(int argc, struct cmd_arg *args) +{ +#if PMU_HAS_RAM && !DIALOG_D2238 + bool success; + char buffer[kDIALOG_EXT_MEM_CAL_SIZE]; + + if ( argc<2 || strcmp("read", args[1].str)==0 ) { + size_t count=kDIALOG_EXT_MEM_CAL0_SIZE; + size_t offset=0; + + if ( argc>2 ) count=atoi( args[2].str ); + if ( argc>3 ) offset=atoi( args[3].str ); + + success=power_load_memory_calibration(buffer, count); + if ( !success ) { + printf("failed to read %zu bytes\n", count); + } else { + for (size_t i=0; i3 && strcmp("write", args[1].str)==0 ) { + + success=power_load_memory_calibration(buffer, kDIALOG_EXT_MEM_CAL1_SIZE); + if ( !success ) { + printf("failed to read %d bytes\n", kDIALOG_EXT_MEM_CAL1_SIZE); + } else { + size_t offset=atoi( args[2].str ); + int i, overflow=0; + + for (i=3; !overflow && ikDIALOG_EXT_MEM_CAL_SIZE ; + if ( overflow ) { + printf("%#x@%d is out of bounds\n", val, index); + } else { + buffer[index]=val; + } + } + + if ( !overflow ) { + size_t count=kDIALOG_EXT_MEM_CAL0_SIZE; + + if ( offset+i-3>kDIALOG_EXT_MEM_CAL0_SIZE ) count+=kDIALOG_EXT_MEM_CAL1_SIZE; + + success=power_store_memory_calibration(buffer, count); + if ( !success ) printf("failed to write\n"); + } + } + + } else { + printf("usage:\n\t%s \n", args[0].str); + printf("\t\tread [] [] show memory calibration values\n"); + printf("\t\twrite byte byte ... change byte(s) at offset\n"); + return -1; + } + + return 0; +#else + printf("not available on this target\n"); + return -1; +#endif +} + +static inline uint16_t pmu_index2gpio_addr(uint32_t index) +{ +#if DIALOG_D2207 + if (index >= 17) return kD2207_GPIO18 + (index-17)*3; +#endif +#if PMU_HAS_GPIO_CONF + return kDIALOG_SYS_GPIO_REG_START + index*2; +#endif + return kDIALOG_SYS_GPIO_REG_START + index; +} + +static +void dump_gpiocfg_(int gpion) // gpio[1-21] +{ + int result; + uint8_t val[2]; + const uint16_t addr=pmu_index2gpio_addr(gpion-1); + + result=pmu_get_data(PMU_IIC_BUS, addr, val); +#if PMU_HAS_GPIO_CONF + result=pmu_get_data(PMU_IIC_BUS, addr+1, &val[1]); +#endif + if ( result!=0 ) { + printf("gpio%02d: result=%d\n", gpion, result); + } else { + printf("gpio%02d: 0x%04x : cnfga=%02x", gpion, addr, val[0]); +#if PMU_HAS_GPIO_CONF + printf(" cnfgb=%02x", val[1]); +#endif + printf("\n"); + } +} + +static void dump_railcfg_(uint32_t index) +{ + int result; + uint8_t vsel, ena; + char label[32]; + const struct ldo_params *p=&LDOP[index]; + +#if DIALOG_D2257 + const uint8_t last_ldo=16; + const uint8_t last_buck=25; +#else + const uint8_t last_ldo=15; + const uint8_t last_buck=24; +#endif + + if (indexldoreg && p->actreg ) { + result=pmu_get_data(PMU_IIC_BUS, p->ldoreg, &vsel); + if ( result==0 ) result=pmu_get_data(PMU_IIC_BUS, p->actreg, &ena); + if ( result!=0 ) { + printf("rail%02d: result=%d\n", index, result); + } else { + printf("rail%02d: %s : ena[%04x]=%02x vsel[%04x]=%02x", + index, label, p->actreg, ena, p->ldoreg, vsel); + +#if DIALOG_D2255 + uint8_t actual=0xff, fvsel=0xff; + uint16_t areg=0xffff, fvreg=0xffff; + + if ( index<15 ) { + areg=p->ldoreg+1; + } else if ( index>=15 ) { + areg=p->ldoreg+2; + fvreg=p->ldoreg-1; + } + + if ( areg!=0xffff ) { + result=pmu_get_data(PMU_IIC_BUS, areg, &actual); + if ( result!=0 ) actual=0xff; + } + + if ( fvreg!=0xffff ) { + result=pmu_get_data(PMU_IIC_BUS, fvreg, &fvsel); + if ( result!=0 ) actual=0xff; + printf(" fvsel[%04x]=%02x", fvreg, fvsel); + } + + // TODO: convert value to voltage + if ( ena ) printf(" actual[%04x]=%02x", areg, actual); +#endif + printf("\n"); + } + } else { + printf("rail%02d: %s N/A\n", index, label); + } + +} + +static void do_dctl_cmd_help() +{ + printf("\tdctl gpio[] [cfg ][ ]\n"); + printf("\tdctl adc \n"); + printf("\tdctl rail[]\n"); +} + +// dctl gpio +// dctl gpio +// dctl gpio cfg configa +// dctl gpio value direction +// dctl adc +// dctl rail +// dctl rail +// dctl uvwarn thresholdMV +static int +do_dctl_cmd(int argc, struct cmd_arg *args) +{ + + if ( argc==1 ) { + do_dctl_cmd_help(); + } else if ( strncmp("gpio", args[1].str, 4)==0 ) { + + if ( args[1].str[4]==0 ) { + for (int gpion=1; gpion<=kDIALOG_GPIO_COUNT; gpion++) { + dump_gpiocfg_(gpion); + } + } else if ( argc==2 ) { + const int gpion=atoi( &args[1].str[4] ); + if ( gpion>0 && gpion<=kDIALOG_GPIO_COUNT ) dump_gpiocfg_(gpion); + } else if ( argc==4 && args[2].str[0]=='c' ) { + const int gpion=atoi( &args[1].str[4] ); + if ( gpion>0 && gpion<=kDIALOG_GPIO_COUNT ) { + const uint32_t cfga=strtoul( args[3].str,NULL,0 ); + + power_gpio_configure(gpion-1, cfga); + dump_gpiocfg_(gpion); + } + + } else if ( argc==4 ) { + const int gpion=atoi( &args[1].str[4] ); + + if ( gpion>0 && gpion<=kDIALOG_GPIO_COUNT ) { + const uint32_t direction=atoi( args[2].str ); + const uint32_t value=atoi( args[3].str ); + + const int rc=power_set_gpio(gpion-1, direction, value); + if ( rc!=0 ) printf("gpio%02d: direction=%x value=%x (%d)\n", gpion, direction, value, rc); + dump_gpiocfg_(gpion); + } + } + } else if ( strncmp("rail", args[1].str, 4)==0 ) { + + if ( args[1].str[4]==0 ) { + for (int index=0; index=3 ) { + // dctl rail0 ena [vsel] + const int index=atoi( &args[1].str[4] ); + + if ( indexactreg ) { + printf("rail%d: enable register not available", index); + } else { + const uint32_t ena=atoi( args[2].str )&0x1; + + result=pmu_set_data(PMU_IIC_BUS, p->actreg, ena, true); + if ( result!=0 ) { + printf("rail%d: enable error (%d)", index, result); + } else if ( argc==4 ) { + if ( !p->ldoreg ) { + printf("rail%d: vsel register not available", index); + } else { + const uint32_t vsel=atoi( args[3].str )&0xff; + + result=pmu_set_data(PMU_IIC_BUS, p->ldoreg, vsel, true); + if ( result!=0 ) { + printf("rail%d: vsel=%x error (%d)", index, vsel, result); + } + } + } + } + + dump_railcfg_(index); + } + + } + } else if ( strncmp("uvwarn", args[1].str, 5)==0 && argc>1) { + const uint32_t thresholdMV=(uint32_t)atoi( args[2].str ); + + int result=pmu_uvwarn_config(0, thresholdMV); + printf("uvwarn: threshold=%dmV (%d)\n", thresholdMV, result); + + } else if ( strncmp("adc", args[1].str, 4)==0 && argc>1) { + unsigned value = 0; + const int chan=atoi( args[2].str ); + + int result=dialog_read_adc(0, chan, &value); + if ( result<0 ) { + printf("error: chan=%d (%d)\n", chan, result); + } else { + printf("adc: chan=%d value=%u\n", chan, value); + } + + } else { + printf("usage:\n\t%s \n", args[0].str); + do_dctl_cmd_help(); + return -1; + } + + return 0; +} + +#if WITH_RECOVERY_MODE +MENU_COMMAND_DEBUG(pmem, do_pmem_cmd, "Manage memory calibration nvram", NULL); +MENU_COMMAND_DEBUG(dctl, do_dctl_cmd, "Dialog control menu", NULL); +#endif + +static uint8_t nvram_key_map[kPowerNVRAMPropertyCount] = { + 0x0F, // kPowerNVRAMiBootStateKey + 0x00, // kPowerNVRAMiBootDebugKey + 0x01, // kPowerNVRAMiBootStageKey + 0x02, // kPowerNVRAMiBootErrorCountKey + 0x03, // kPowerNVRAMiBootErrorStageKey + 0x10, // kPowerNVRAMiBootMemCalCAOffset0Key + 0x11, // kPowerNVRAMiBootMemCalCAOffset1Key + 0x12, // kPowerNVRAMiBootMemCalCAOffset2Key + 0x13, // kPowerNVRAMiBootMemCalCAOffset3Key + 0x0D, // kPowerNVRAMiBootBootFlags0Key + 0x0E, // kPowerNVRAMiBootBootFlags1Key + 0x14, // kPowerNVRAMiBootEnterDFUKey +}; + +static int dialog_get_nvram(int dev, uint8_t offset, uint8_t *data); +static int dialog_set_nvram(int dev, uint8_t offset, uint8_t data); + +int +power_get_nvram(uint8_t key, uint8_t *data) +{ + uint8_t offset; + + if (key >= kPowerNVRAMPropertyCount) return -1; + offset = nvram_key_map[key]; + + return dialog_get_nvram(PMU_IIC_BUS, offset, data); +} + +int +power_set_nvram(uint8_t key, uint8_t data) +{ + uint8_t offset; + + if (key >= kPowerNVRAMPropertyCount) return -1; + offset = nvram_key_map[key]; + + return dialog_set_nvram(PMU_IIC_BUS, offset, data); +} + +void +power_clr_events(int wake) +{ + /* Read & clear interrupts */ + eventRegisters events; + pmu_read_events(events); + + if (wake) + { + /* Unmask pmu wake interrupts */ + pmu_write_mask(kDialogEventIntMasks); + } +} + +static void +dialog_shutdown(u_int8_t type) +{ +#if !DIALOG_D1755 + if (type == kDIALOG_SYS_CONTROL_STANDBY) + { + int rc; + // turn off all GPIO wake sources so that spurious events will not prevent + // the system from turning off; Ashley will reload OTP once entering standby, + // so OTP wake sources will still turn the system on (this was not true on + // previous PMUs). + for (int i = 0; i < kDIALOG_GPIO_COUNT; i++) { + UInt8 gpioData; + UInt16 addr=pmu_index2gpio_addr(i); + + rc=pmu_get_data(PMU_IIC_BUS, addr, &gpioData); + if ( rc!=0 ) { + dprintf(DEBUG_SPEW, "gpio%d: cannot read (%d)\n", i+1, rc); + } else if (!IS_GPIO_OUTPUT(gpioData) && (gpioData & kDIALOG_SYS_GPIO_INPUT_WAKE) ) { + gpioData &= ~kDIALOG_SYS_GPIO_INPUT_WAKE; + rc=pmu_set_data(PMU_IIC_BUS, addr, gpioData, false); + if ( rc!=0 ) dprintf(DEBUG_SPEW, "gpio%d: cannot read (%d)\n", i+1, rc); + } + } + } +#endif + + pmu_set_data(PMU_IIC_BUS, kDIALOG_SYS_CONTROL, type, false); + enter_critical_section(); + while (true); +} + +void +pmu_shutdown(void) +{ + dialog_shutdown(kDIALOG_SYS_CONTROL_STANDBY); +} + +void +pmu_suspend(void) +{ + dialog_shutdown(kDIALOG_SYS_CONTROL_HIBERNATE); +} + +void +pmu_set_backlight_enable(uint32_t backlight_level) +{ +#if WITH_SWI_BACKLIGHT + extern int swi_backlight_enable(u_int32_t iset_code, u_int32_t backlight_level); + + swi_backlight_enable(kDIALOG_SWI_WLED_ISET, backlight_level); +#elif PMU_HAS_WLED + uint32_t cnt, count = sizeof(pmu_backlight_enable)/sizeof(pmu_backlight_enable[0]); + struct pmu_setup_struct tmp[count]; + const struct pmu_setup_struct *setup; + + if (backlight_level) { + memcpy(tmp, pmu_backlight_enable, count * sizeof(struct pmu_setup_struct)); + setup = tmp; + if ((backlight_level >= 1) && (backlight_level <= MAX_BACKLIGHT_LEVEL)) { + UInt8 backlight_level_1; +#if DIALOG_D1755 + backlight_level_1 = backlight_level; +#elif DIALOG_D2257 + UInt8 backlight_level_2; + backlight_level_1 = (backlight_level >> 8) & 0x7; // msb bits + backlight_level_2 = backlight_level & 0xff; +#else + UInt8 backlight_level_2; + backlight_level_1 = backlight_level >> 3; + backlight_level_2 = backlight_level & 0x7; +#endif + for (cnt = 0; cnt < count; cnt++) { + if (tmp[cnt].reg == kDIALOG_WLED_ISET) { + tmp[cnt].value = backlight_level_1; + } +#if !DIALOG_D1755 + if (tmp[cnt].reg == kDIALOG_WLED_ISET2) { + tmp[cnt].value = backlight_level_2; + } +#endif + } + } + } else { + count = sizeof(pmu_backlight_disable)/sizeof(pmu_backlight_disable[0]); + setup = pmu_backlight_disable; + } + + dialog_use_setup(setup, count); +#endif +} + + +#if DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2045 || DIALOG_D2186 || DIALOG_D2238 +#define POWER_SOC_VMIN (600) +#define POWER_SOC_VMAX (1400) +#define DIALOG_CORE_BUCKOUT(mv) (((mv-600)*1000)+3124)/3125 +#define DIALOG_CORE_BUCKMV(vsel) (600 + ((((vsel) * 3125)) / 1000)) +#elif DIALOG_D2018 +#define POWER_SOC_VMIN (725) +#define POWER_SOC_VMAX (1521) +#define DIALOG_CORE_BUCKOUT(mv) (((mv-725)*1000)+3124)/3125 +#define DIALOG_CORE_BUCKMV(vsel) (725 + ((((vsel) * 3125)) / 1000)) +#elif DIALOG_D2089 || DIALOG_D2207 || DIALOG_D2255 || DIALOG_D2257 +#define POWER_SOC_VMIN (600) +#define POWER_SOC_VMAX (1396) +#define DIALOG_CORE_BUCKOUT(mv) (((mv-600)*1000)+3124)/3125 +#define DIALOG_CORE_BUCKMV(vsel) (600 + ((((vsel) * 3125)) / 1000)) +#else +#define POWER_SOC_VMIN (725) +#define POWER_SOC_VMAX (1500) +#define DIALOG_CORE_BUCKOUT(mv) ((mv-725)+24)/25 +#define DIALOG_CORE_BUCKMV(vsel) (725 + ((vsel) * 25)) +#endif + +#if DIALOG_D2238 +int power_set_soc_voltage(unsigned mv, int override) +{ + return 0; +} +#else +int +power_set_soc_voltage(unsigned mv, int override) +{ + u_int8_t tmp; + + tmp = 0; + + if ((mv < POWER_SOC_VMIN) || (mv > POWER_SOC_VMAX)) return -1; + + unsigned i; + for (i= 0; (i != sizeof(soc_rails)/sizeof(soc_rails[0])); i++) { + pmu_set_data(soc_rails[i].pmu, soc_rails[i].data_reg, DIALOG_CORE_BUCKOUT(mv), true); + +#if DIALOG_D1755 || DIALOG_D1815 + if (soc_rails[i].data_reg == kDIALOG_BUCK1) { + // Be sure to set the BUCK1 selector to 0; this requires/assumes VBUCK1_SWI_EN=0 + pmu_set_data(soc_rails[i].pmu, kDIALOG_BUCK1_SEL, 0, true); + pmu_get_data(soc_rails[i].pmu, soc_rails[i].ctrl_reg, &tmp); + tmp |= kDIALOG_BUCK_CONTROL_BUCK1_GO; + pmu_set_data(soc_rails[i].pmu, soc_rails[i].ctrl_reg, tmp, true); + } +#endif + } + + return 0; +} + +#endif + +#if DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2045 || DIALOG_D2186 || DIALOG_D2238 +#define POWER_CPU_VMIN (600) +#define POWER_CPU_VMAX (1400) +#define DIALOG_CPU_BUCKOUT(mv) (((mv-600)*1000)+3124)/3125 +#define DIALOG_CPU_BUCKMV(vsel) (600 + ((((vsel) * 3125)) / 1000)) +#elif DIALOG_D2018 +#define POWER_CPU_VMIN (725) +#define POWER_CPU_VMAX (1521) +#define DIALOG_CPU_BUCKOUT(mv) (((mv-725)*1000)+3124)/3125 +#define DIALOG_CPU_BUCKMV(vsel) (725 + ((((vsel) * 3125)) / 1000)) +#elif DIALOG_D2089 || DIALOG_D2207 || DIALOG_D2255 +#define POWER_CPU_VMIN (600) +#define POWER_CPU_VMAX (1396) +#define DIALOG_CPU_BUCKOUT(mv) (((mv-600)*1000)+3124)/3125 +#define DIALOG_CPU_BUCKMV(vsel) (600 + ((((vsel) * 3125)) / 1000)) +#elif DIALOG_D2255 +#define POWER_CPU_VMIN (500) +#define POWER_CPU_VMAX (1296) +#define DIALOG_CPU_BUCKOUT(mv) (((mv-500)*1000)+3124)/3125 +#define DIALOG_CPU_BUCKMV(vsel) (500 + ((((vsel) * 3125)) / 1000)) +#elif DIALOG_D2257 +#define POWER_CPU_VMIN (450) +#define POWER_CPU_VMAX (1250) +#define DIALOG_CPU_BUCKOUT(mv) (((mv-450)*1000)+3124)/3125 +#define DIALOG_CPU_BUCKMV(vsel) (450 + ((((vsel) * 3125)) / 1000)) +#endif + +#if DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2018 || DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2255 || DIALOG_D2257 +int +power_set_cpu_voltage(unsigned mv, int override) +{ + u_int8_t tmp; + + tmp = 0; + + if ((mv < POWER_CPU_VMIN) || (mv > POWER_CPU_VMAX)) return -1; + + unsigned i; + for (i= 0; (i != sizeof(cpu_rails)/sizeof(cpu_rails[0])); i++) { + pmu_set_data(cpu_rails[i].pmu, cpu_rails[i].data_reg, DIALOG_CPU_BUCKOUT(mv), true); + } + + return 0; +} + +#else +int +power_set_cpu_voltage(unsigned mv, int override) +{ + return -1; +} +#endif + +#if DIALOG_D1972 || DIALOG_D2018 || DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2255 || DIALOG_D2257 +#define POWER_RAM_VMIN (600) +#define POWER_RAM_VMAX (1400) +#define DIALOG_RAM_BUCKOUT(mv) (((mv-600)*1000)+3124)/3125 + +int +power_set_ram_voltage(unsigned mv, int override) +{ + u_int8_t tmp; + + tmp = 0; + + if ((mv < POWER_RAM_VMIN) || (mv > POWER_RAM_VMAX)) return -1; + + unsigned i; + for (i= 0; (i != sizeof(ram_rails)/sizeof(ram_rails[0])); i++) { + pmu_set_data(ram_rails[i].pmu, ram_rails[i].data_reg, DIALOG_RAM_BUCKOUT(mv), true); + } + + return 0; +} + +#else + +int +power_set_ram_voltage(unsigned mv, int override) +{ + return -1; +} + +#endif + +// TODO: deprecate, use power_get_rail_value() instead +int power_get_buck_value(int buck, unsigned mv, u_int32_t *buffer) +{ + int ret = 0; + + switch (buck) { +#if DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2018 || DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2238 + case 0: + case 1: + *buffer = DIALOG_CPU_BUCKOUT(mv); + break; + case 2: + *buffer = DIALOG_CORE_BUCKOUT(mv); + break; +#endif +// compatibility only +#if DIALOG_D1972 || DIALOG_D2018 + case 16: + *buffer = DIALOG_RAM_BUCKOUT(mv); + break; +#endif + default: ret = -1; break; + } + + return ret; +} + +int +power_get_rail_value(int rail, unsigned mv, u_int32_t *buffer) +{ + int ret = 0; + +#if DIALOG_D2255 || DIALOG_D2257 + switch (rail) { + case POWER_RAIL_CPU: + case POWER_RAIL_SOC: + case POWER_RAIL_VDD_FIXED: + case POWER_RAIL_CPU_RAM: + case POWER_RAIL_GPU: + case POWER_RAIL_GPU_RAM: + if ( mvtarget_rails[rail].max_mv ) { + *buffer=0; // safe? + ret=-1; + } else { + *buffer=(( (mv-target_rails[rail].min_mv)*1000 ) + target_rails[rail].step_uv-1 ) / target_rails[rail].step_uv; + } + break; + default: + ret = -1; + break; + + } +#elif DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2018 || DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2238 || DIALOG_D1972 || DIALOG_D2018 + // compat. rail is a buck + ret=power_get_buck_value(rail, mv, buffer); +#endif + + return ret; +} + +int +power_convert_dwi_to_mv(int rail, u_int32_t dwival) +{ + int ret; + + switch (rail) { +#if DIALOG_D2255 || DIALOG_D2257 + case POWER_RAIL_CPU: + case POWER_RAIL_SOC: + case POWER_RAIL_VDD_FIXED: + case POWER_RAIL_CPU_RAM: + case POWER_RAIL_GPU: + case POWER_RAIL_GPU_RAM: + ret=target_rails[rail].min_mv+(dwival*target_rails[rail].step_uv)/1000 ; + if ( ret>target_rails[rail].max_mv ) ret=-1; + break; +#elif DIALOG_D1881 || DIALOG_D1946 || DIALOG_D1972 || DIALOG_D1974 || DIALOG_D2018 || DIALOG_D2045 || DIALOG_D2089 || DIALOG_D2186 || DIALOG_D2207 || DIALOG_D2238 + case 0: + case 1: + ret = DIALOG_CPU_BUCKMV(dwival); + break; + case 2: + ret = DIALOG_CORE_BUCKMV(dwival); + break; +#endif + default: ret = -1; break; + } + + return ret; +} + +int +power_set_display_voltage_offset(u_int32_t voltage_offset, bool fixed_boost) +{ +#if DIALOG_D1755 || !PMU_HAS_WLED + return -1; +#elif !defined(TARGET_DISPLAY_VOLTAGE_BASE) || !defined(TARGET_DISPLAY_VOLTAGE_SCALE) || !defined(TARGET_DISPLAY_BOOST_LDO) || !defined(TARGET_DISPLAY_BOOST_OFFSET) + return -1; +#else + + u_int32_t display_voltage = TARGET_DISPLAY_VOLTAGE_BASE - (voltage_offset * TARGET_DISPLAY_VOLTAGE_SCALE); + u_int8_t lcm_controlx_data, lcm_boost_data; + + // Convert display_voltage to LCM_CONTROLx value + lcm_controlx_data = (display_voltage - 5000 + 49) / 50; + + // Set LCM_CONTROLx register + pmu_set_data(PMU_IIC_BUS, TARGET_DISPLAY_BOOST_LDO, lcm_controlx_data, true); + + if (false == fixed_boost) { + // Wait for LCMx to settle... 1ms is probably enough, but 10ms for now + task_sleep(10 * 1000); + + // LCM_BOOST should be TARGET_DISPLAY_BOOST_OFFSET higher then LCM_CONTROLx + lcm_boost_data = lcm_controlx_data + TARGET_DISPLAY_BOOST_OFFSET / 50; + + // Set LCM_BOOST register + pmu_set_data(PMU_IIC_BUS, kDIALOG_LCM_BOOST, lcm_boost_data, true); + } + + return 0; +#endif +} + +int +power_get_boot_flag(void) +{ + if ((EVENT_FLAG_GET_BIT(kDIALOG_EVENT_HIB_MASK) & boot_flags) != 0) return kPowerBootFlagWarm; + + if (!cold_boot_ints_valid) { + /* Read & clear interrupts */ + pmu_read_events(cold_boot_ints); + cold_boot_ints_valid = true; + } + + // if a cold boot, distinguish between two types of boot: + // - boot immediately + // - boot only if the power button is pressed and held + // For example, charger attach, alarm wake, or 30-pin accessory insert always powers up. + // A short tap of the power button or E75 accessory insert does not. + + bool button_event = false; + eventRegisters wakeEvents; + memcpy(wakeEvents, cold_boot_ints, sizeof(eventRegisters)); + + const UInt16 cold_button_events[] = { + kDIALOG_EVENT_PWR_BUTTON_MASK, +#if WITH_HW_TRISTAR + kDIALOG_EVENT_ACC_DET_MASK, +#endif + }; + const size_t num_cold_button_events = sizeof(cold_button_events)/sizeof(UInt16); + + for (unsigned i = 0; i < num_cold_button_events; i++) { + UInt16 event = cold_button_events[i]; + if (EVENT_FLAG_TEST(wakeEvents, event)) { + button_event = true; + wakeEvents[EVENT_FLAG_GET_BYTE(event)] &= ~EVENT_FLAG_GET_BIT(event); + } + } + + // if we saw one of the events that would result in a cold-button boot, + // but there are other events pending, or USB is attached (but somehow failed + // to flag an event), continue to boot. + // + // Ignore all buttons from wake mask, not just power, since + // although they (e.g., home button) are "wake" events, they are not "power-on" events. + if (button_event + && !(EVENT_REGISTER_TEST_MASK(kDialogEventNotButtonMasks, wakeEvents)) + && !(power_has_usb())) + return kPowerBootFlagColdButton; + + return kPowerBootFlagCold; +} + +void +pmu_will_resume(void) +{ + // store boot flag for OS use (re-use same NVRAM byte used for voltage between LLB and iBoot) + power_set_nvram(kPowerNVRAMiBootBootFlags0Key, boot_flags); +} + +int +power_read_dock_id(unsigned *id) +{ +#if !DIALOG_D2238 && !DIALOG_D2255 + int result; + unsigned value = 0; + + result = dialog_read_adc(PMU_IIC_BUS, kDIALOG_ADC_CONTROL_MUX_SEL_ACC_ID, &value); + + // Only want the high 4 bits + *id = value >> (kDIALOG_ADC_RESOLUTION_BITS - 4); + + return result; +#else + return -1; +#endif +} + +int +power_set_gpio(uint32_t index, uint32_t direction, uint32_t value) +{ + int result; + uint8_t data; + + if (index >= kDIALOG_GPIO_COUNT) return -1; + + /* Read kDIALOG_SYS_GPIO_X register */ + result = pmu_get_data(PMU_IIC_BUS, pmu_index2gpio_addr(index), &data); + if (result != 0) { + dprintf(DEBUG_SPEW, "gpio%d: cannot read (%d)\n", index+1, result); + return result; + } + + data &= ~(kDIALOG_SYS_GPIO_DIRECTION_MASK | kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH); + switch (direction) { + case 2: + data |= kDIALOG_SYS_GPIO_DIRECTION_OUT_32KHZ; + break; + case 1: + data |= kDIALOG_SYS_GPIO_DIRECTION_OUT; + data |= value ? kDIALOG_SYS_GPIO_OUTPUT_LEVEL_HIGH : kDIALOG_SYS_GPIO_OUTPUT_LEVEL_LOW; + break; + case 0: + default: + data |= kDIALOG_SYS_GPIO_DIRECTION_IN_LEVEL_HIGH; + break; + } + + /* Set kDIALOG_SYS_GPIO_X register */ + result=pmu_set_data(PMU_IIC_BUS, pmu_index2gpio_addr(index), data, true); + if ( result!=0 ) dprintf(DEBUG_SPEW, "gpio%d: cannot set (%d)\n", index+1, result); + + return result; +} + +bool +power_get_gpio(uint32_t index) +{ + u_int8_t reg, mask, data; + + if (index >= kDIALOG_GPIO_COUNT) return false; + + reg = EVENT_FLAG_GET_BYTE(kDIALOG_STATUS_GPIO_MASK(index)); + mask = EVENT_FLAG_GET_BIT(kDIALOG_STATUS_GPIO_MASK(index)); + + int result=pmu_get_data(PMU_IIC_BUS, kDIALOG_STATUS_A + reg, &data); + if ( result!=0 ) dprintf(DEBUG_SPEW, "gpio%d: cannot read (%d)\n", index+1, result); + + return (data & mask) != 0; +} + +void +power_gpio_configure(uint32_t index, u_int32_t config) +{ + if (index >= kDIALOG_GPIO_COUNT) return; + + /* Set kDIALOG_SYS_GPIO_X register */ + int result=pmu_set_data(PMU_IIC_BUS, pmu_index2gpio_addr(index), config, true); + if ( result!=0 ) dprintf(DEBUG_SPEW, "gpio%d: cannot configure (%d)\n", index+1, result); +} + + +int +power_set_ldo(uint32_t ldoSelect, uint32_t voltage) +{ + u_int8_t data; + + // The argument is 1-based, so decrement to be an array index + ldoSelect--; + + // Bounds check and make sure the "LDO" isn't a switch: must have a valid min voltage + if ((ldoSelect >= NUM_LDOS) || (LDOP[ldoSelect].minv == 0)) return -1; + + // Range check the requested voltage + if ((voltage < LDOP[ldoSelect].minv) || (voltage > (uint32_t)(LDOP[ldoSelect].step * + LDOP[ldoSelect].maxs + + LDOP[ldoSelect].minv))) + return -1; + + // Construct the encoding and write the appropriate register + data = ((voltage - LDOP[ldoSelect].minv)/LDOP[ldoSelect].step); + pmu_set_data(PMU_IIC_BUS, LDOP[ldoSelect].ldoreg, data, true); + + return 0; +} + +int +power_enable_ldo(uint32_t ldo, bool enable) +{ + u_int8_t data; + + ldo--; + if (ldo >= NUM_LDOS) return -1; + + pmu_get_data(PMU_IIC_BUS, LDOP[ldo].actreg, &data); + + if (enable) data |= LDOP[ldo].actmask; + else data &= ~LDOP[ldo].actmask; + + pmu_set_data(PMU_IIC_BUS, LDOP[ldo].actreg, data, true); + + return 0; +} + +static uint32_t nvram_valid_mask; +static uint8_t nvram_shadow[kDIALOG_MEMBYTE_LAST - kDIALOG_MEMBYTE0 + 1]; + +static int +dialog_get_nvram(int dev, uint8_t offset, uint8_t *data) +{ + int result; + + if (offset > (kDIALOG_MEMBYTE_LAST - kDIALOG_MEMBYTE0)) return -1; + if (!((1 << offset) & nvram_valid_mask)) { + result = pmu_get_data(dev, kDIALOG_MEMBYTE0 + offset, &nvram_shadow[offset]); + if (result != 0) return result; + nvram_valid_mask |= (1 << offset); + } + + *data = nvram_shadow[offset]; + + return 0; +} + +static int +dialog_set_nvram(int dev, uint8_t offset, uint8_t data) +{ + if (offset > (kDIALOG_MEMBYTE_LAST - kDIALOG_MEMBYTE0)) return -1; + if (((1 << offset) & nvram_valid_mask) && (data == nvram_shadow[offset])) + return 0; + + nvram_shadow[offset] = data; + nvram_valid_mask |= (1 << offset); + + return pmu_set_data(dev, kDIALOG_MEMBYTE0 + offset, data, 0); +} + +utime_t +power_get_calendar_time(void) +{ + uint8_t offset_secs[4], offset_ticks[2]; + static const uint64_t tick_frequency = 32768; + + if (pmu_read_nvram(kDIALOG_MEMBYTE0 + 4, offset_secs, sizeof(offset_secs)) != 0) return 0; + if (pmu_read_nvram(kDIALOG_MEMBYTE0 + 21, offset_ticks, sizeof(offset_ticks)) != 0) return 0; + + uint64_t offset = ((uint64_t)(offset_secs[3]) << (24 + 15)) + + ((uint64_t)(offset_secs[2]) << (16 + 15)) + + ((uint64_t)(offset_secs[1]) << (8 + 15)) + + ((uint64_t)(offset_secs[0]) << (15)) + + ((uint64_t)(offset_ticks[1] & 0x7F) << (8)) + + (uint64_t)(offset_ticks[0]); + + uint64_t ticks; + +#if PMU_HAS_32K_RTC + // registers are latched when reading the first byte; read all six at once + UInt8 data[(kDIALOG_RTC_SECOND_D - kDIALOG_RTC_SUB_SECOND_A) + 1]; + + if (pmu_read_nvram(kDIALOG_RTC_SUB_SECOND_A, data, sizeof(data)) != 0) return 0; + + ticks = ((uint64_t)(data[kDIALOG_RTC_SUB_SECOND_A - kDIALOG_RTC_SUB_SECOND_A])>>1) + | ((uint64_t)(data[kDIALOG_RTC_SUB_SECOND_B - kDIALOG_RTC_SUB_SECOND_A]) << 7) + | ((uint64_t)(data[kDIALOG_RTC_SECOND_A - kDIALOG_RTC_SUB_SECOND_A]) << 15) + | ((uint64_t)(data[kDIALOG_RTC_SECOND_B - kDIALOG_RTC_SUB_SECOND_A]) << 23) + | ((uint64_t)(data[kDIALOG_RTC_SECOND_C - kDIALOG_RTC_SUB_SECOND_A]) << 31) + | ((uint64_t)(data[kDIALOG_RTC_SECOND_D - kDIALOG_RTC_SUB_SECOND_A]) << 39); +#else + uint32_t upcount, upcount2; + + // read twice, to guard against race with the incrementer + do { + if (pmu_read_nvram(kDIALOG_UPCOUNT_A, &upcount, sizeof(upcount)) != 0) return 0; + if (pmu_read_nvram(kDIALOG_UPCOUNT_A, &upcount2, sizeof(upcount2)) != 0) return 0; + } while (upcount != upcount2); + + ticks = upcount * tick_frequency; +#endif + ticks += offset; + + utime_t secs = ticks / tick_frequency; + utime_t usecs = ((ticks % tick_frequency) * 1000000) / tick_frequency; + + return (secs * 1000000) + usecs; +} + +#if !WITH_HW_CHARGER +void charger_print_status(void) +{ + +} +#endif diff --git a/drivers/dialog/pmu/rules.mk b/drivers/dialog/pmu/rules.mk new file mode 100644 index 0000000..e37a5ac --- /dev/null +++ b/drivers/dialog/pmu/rules.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_POWER_DIALOG=1 \ + WITH_HW_POWER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/power.o \ + $(LOCAL_DIR)/charger.o + +MODULES += \ + lib/power + diff --git a/drivers/display/edp/edp.c b/drivers/display/edp/edp.c new file mode 100644 index 0000000..d10e475 --- /dev/null +++ b/drivers/display/edp/edp.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2011,2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "edp.h" + +#define kHPDTimeout (186 * 1000) + +/* + * Panel ID is based on "DP Panel Vendor ID spec, v1.5" + */ + +static u_int32_t edp_panel_id; +static u_int32_t edp_dot_pitch; +static u_int32_t edp_default_color; +static u_int32_t edp_voltage_offset; +static u_int32_t edp_backlight_cal; +static u_int8_t edp_raw_panel_id[kEDPRawPanelIdLength]; +static dp_t edp_display_config; + +int edp_quiesce(void); +static void edp_panel_enable(bool enable); + +int edp_init(struct display_timing *timing, enum colorspace color, u_int32_t *display_id) +{ + int result; + utime_t HPDTime = 0; + + dprintf(DEBUG_CRITICAL, "edp_init()\n"); + + // Save the display's dot pitch + edp_dot_pitch = timing->dot_pitch; + memcpy(&edp_display_config, timing->display_config, sizeof(dp_t)); + + // Kick off eDP controller + if ((result = displayport_init_with_timing_info(timing)) != 0) + goto error; + + // Power-up the display + edp_panel_enable(true); + + //Wait for HPD to allow enough time for TCON to to be ready + if (dp_controller_wait_for_edp_hpd(&HPDTime) == false) { + dprintf(DEBUG_CRITICAL, "timeout waiting for HPD\n"); + goto error; + } + + if (edp_panel_id == 0) { + edp_panel_id = env_get_uint("pinot-panel-id", 0); + } + if (edp_panel_id == 0) { + // read the panel ID + result = displayport_get_raw_panel_id(edp_raw_panel_id); + if (result != 0) { + dprintf(DEBUG_CRITICAL, "edp_init(): read of edp panel id failed\n"); + } else { + edp_panel_id = edp_raw_panel_id[0] << 24; // Build ID + edp_panel_id |= edp_raw_panel_id[1] << 16; // Panel Vendor ID + edp_panel_id |= edp_raw_panel_id[2] << 8; // Program ID + edp_panel_id |= edp_raw_panel_id[3] << 0; // Silicon Vendor/Model ID + + edp_default_color = (edp_raw_panel_id[0] & 1) ? 0x00000000 : 0x00FFFFFF; + edp_voltage_offset = edp_raw_panel_id[4]; + edp_backlight_cal = edp_raw_panel_id[5]; + } + } + + dprintf(DEBUG_CRITICAL, "edp_init(): edp_panel_id: 0x%08x\n", edp_panel_id); + dprintf(DEBUG_CRITICAL, "edp_init(): edp_default_color: 0x%08x\n", edp_default_color); + dprintf(DEBUG_CRITICAL, "edp_init(): edp_backlight_cal: 0x%08x\n", edp_backlight_cal); + + // Ignore the real default color and use black + edp_default_color = 0x00000000; + + if (edp_panel_id == 0) { + dprintf(DEBUG_CRITICAL, "panel_id = 0\n"); + goto error; + } + + // the HPD signal causes the rest of the DP initialization to occur on the dp_controller_task + // we hold the rest of the enable to prevent racing this task and hence violating the panel's timing requirement + utime_t timeout = HPDTime + kHPDTimeout; + dp_device_wait_started(timeout); + + // Enable the CLCD + display_set_enable(true, &edp_default_color); + + *display_id = edp_panel_id; + + // Adjust display voltage offset +#if WITH_HW_POWER_DIALOG + if (edp_voltage_offset != 0) { + bool fixed_boost = env_get_bool("fixed-lcm-boost", false); + power_set_display_voltage_offset(edp_voltage_offset, fixed_boost); + } +#endif + + //Allow enough time before enabling backlight. Per spec at least 134ms (T4 + T5 + T6 + T7) after seeing HPD. + dp_controller_wait_for_HPD_to_BL(HPDTime); + + return 0; + +error: + edp_quiesce(); + return -1; +} + +int edp_quiesce(void) +{ + dprintf(DEBUG_CRITICAL, "edp_quiesce()\n"); + + displayport_quiesce(); + edp_panel_enable(false); + + return 0; +} + +static void edp_panel_enable(bool enable) +{ +#if PMU_LCD_PWR_EN + power_set_gpio(GPIO_PMU_LCD_PWR_EN, 1, enable); +#else + gpio_write(GPIO_LCD_PWR_EN, enable); +#endif +} + +#if WITH_DEVICETREE + +#include + +int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + + if (edp_panel_id == 0) return -1; + + propName = "lcd-panel-id"; + if (FindProperty(edp_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = edp_panel_id; + } + + propName = "raw-panel-id"; + if (FindProperty(edp_node, &propName, &propData, &propSize)) { + if (propSize > sizeof(edp_raw_panel_id)) propSize = sizeof(edp_raw_panel_id); + memcpy(propData, edp_raw_panel_id, propSize); + } + + propName = "pre_configured"; + if (FindProperty(edp_node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(u_int8_t)) + ((u_int32_t *)propData)[0] = displayport_video_configured() ? 1 : 0; + } + + + if (lcd_node != NULL) { + + propName = "alpm-enable"; + if (FindProperty(lcd_node, &propName, &propData, &propSize)) { + if (propSize == sizeof(uint32_t)) { + uint32_t data = dp_device_is_alpm_enabled(); + ((uint32_t*)propData)[0] = data; + } + } + + propName = "lcd-panel-id"; + if (FindProperty(lcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = edp_panel_id; + } + + propName = "raw-panel-id"; + if (FindProperty(lcd_node, &propName, &propData, &propSize)) { + if (propSize > sizeof(edp_raw_panel_id)) propSize = sizeof(edp_raw_panel_id); + memcpy(propData, edp_raw_panel_id, propSize); + } + } + + if (clcd_node != NULL) { + propName = "display-default-color"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = edp_default_color; + } + + propName = "dot-pitch"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = edp_dot_pitch; + } + propName = "vrr-version"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + if (propSize == sizeof(uint32_t)) { + uint32_t data = edp_display_config.vrr_on << 31 | edp_display_config.vrr_enable; + ((uint32_t*)propData)[0] = data; + } + } + } + + if (backlight_node != NULL) { + propName = "display-backlight-calibration"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = edp_backlight_cal; + } + propName = "backlight-id"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + if (((u_int32_t *)propData)[0] == 0xffffffff) { + // We are moving DP panel program-id by 1000 to not collide with + // MIPI panel program ids + ((u_int32_t *)propData)[0] = ((edp_panel_id >> 8) & 0xff) + 1000; + } + } + } + + return 0; +} + +#endif diff --git a/drivers/display/edp/edp.h b/drivers/display/edp/edp.h new file mode 100644 index 0000000..c1f57fa --- /dev/null +++ b/drivers/display/edp/edp.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_EDP_H +#define __DRIVERS_EDP_H + +#endif /* ! __DRIVERS_EDP_H */ diff --git a/drivers/display/edp/rules.mk b/drivers/display/edp/rules.mk new file mode 100644 index 0000000..1cef649 --- /dev/null +++ b/drivers/display/edp/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DISPLAY_EDP=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/edp.o diff --git a/drivers/display/pinot/pinot.c b/drivers/display/pinot/pinot.c new file mode 100644 index 0000000..436442f --- /dev/null +++ b/drivers/display/pinot/pinot.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2008-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinot.h" + +/* Update to Display Sequence spec 080-4502-04 v20, + * hold the specs. The only change is to + * use 7 ms instead of 6ms for the delay after reset. */ + +/* This code is compliant with Display Sequence spec 080-4502-04 v19, + * holds the spec. As repeated below, Type 1 + * does not adhere to the spec and never will. Type 2 comments and + * diagram references are relative to that document. */ + +/* The Pinot driver type (1, 2 or 3) really should come from the panel + * ID. However, we have a timing constraint on Type 2 and 3 drivers that + * needs to be honored before the panel ID can be read. Therefore we + * bind each target to its appropriate driver type and confirm with + * the ID. Type 1 is rare/legacy at this point, so most default to 2. + * Type 3 was introduced to improve on displayON sequence */ +#ifndef PINOT_TYPE +#define PINOT_TYPE (2) +#endif + +static u_int32_t pinot_panel_id; +static u_int32_t pinot_dot_pitch; +static u_int32_t pinot_default_color; +static u_int32_t pinot_voltage_offset; +static u_int32_t pinot_backlight_cal; +static u_int8_t pinot_raw_panel_id[15]; + +static void pinot_enable_reset(bool enable); +static void pinot_enable_power(bool enable); + +static int panel_id_2_class(u_int32_t panel_id) +{ + int driver, panel_class; + + driver = panel_id & 0x3f; + + if (driver > DISP_IC_NUGGET) + panel_class = 3; + else if (driver < DISP_IC_LIBERTY) + panel_class = 1; + else + panel_class = 2; + + return panel_class; +} + +static void pinot_read_panel_id(void) +{ + u_int32_t length; + int result; + int panel_class, driver; + + if (pinot_panel_id == 0) { + pinot_panel_id = env_get_uint("pinot-panel-id", 0); + } + if (pinot_panel_id == 0) { + // read the panel ID + length = sizeof(pinot_raw_panel_id); + pinot_raw_panel_id[0] = DSIM_CMD_DEVICE_ID; + result = mipi_dsim_read_long_command(DSIM_TYPE_GEN_READ_1P, pinot_raw_panel_id, &length); + if ((result != 0) || (length < 3)) { + dprintf(DEBUG_CRITICAL, "pinot_init(): read of pinot panel id failed\n"); + return; + } else { + pinot_panel_id = pinot_raw_panel_id[0] << 24; // Build ID + pinot_panel_id |= pinot_raw_panel_id[1] << 16; // Panel Vendor ID + pinot_panel_id |= (pinot_raw_panel_id[3] & 0xF0) << 8; // Program ID + pinot_panel_id |= (pinot_raw_panel_id[2] & 0xF0) << 4; // + pinot_panel_id |= (pinot_raw_panel_id[3] & 0x07) << 3; // Driver Vendor ID + pinot_panel_id |= (pinot_raw_panel_id[2] & 0x07) << 0; // + pinot_panel_id |= (pinot_raw_panel_id[2] & 0x08) << 4; // Auto Boot Bit + pinot_panel_id |= (pinot_raw_panel_id[3] & 0x08) << 3; // Default Color Bit + + pinot_default_color = ((pinot_raw_panel_id[3] >> 3) & 1) ? 0x00000000 : 0x00FFFFFF; + pinot_voltage_offset = pinot_raw_panel_id[4]; + pinot_backlight_cal = pinot_raw_panel_id[5]; + } + } + + driver = pinot_panel_id & 0x3f; + if (driver == DISP_IC_LIBERTY) + pinot_backlight_cal = target_lookup_backlight_cal((pinot_panel_id >> 24) & 3); + + panel_class = panel_id_2_class(pinot_panel_id); + + //PINOT_TYPE should be removed eventually, but validating old HW has the correct values + if ((PINOT_TYPE != panel_class) && (panel_class > 3)) + panic("Mismatch between PINOT_TYPE and panel ID"); + + dprintf(DEBUG_CRITICAL, "pinot_init(): pinot_panel_id: 0x%08x\n", pinot_panel_id); + dprintf(DEBUG_CRITICAL, "pinot_init(): pinot_default_color: 0x%08x\n", pinot_default_color); + dprintf(DEBUG_CRITICAL, "pinot_init(): pinot_backlight_cal: 0x%08x\n", pinot_backlight_cal); +} + +int pinot_init(struct display_timing *timing, enum colorspace color, u_int32_t *display_id) +{ + utime_t start_time; + int panel_class; + + dprintf(DEBUG_CRITICAL, "pinot_init()\n"); + + // Save the display's dot pitch + pinot_dot_pitch = timing->dot_pitch; + + if (PINOT_TYPE < 2) { + /******************************************************************************* + * The Type 1 sequence is FROZEN as of Durango and shall NEVER BE TOUCHED AGAIN. + * There are known excursions from the display sequencing spec. + ******************************************************************************/ + + // Reset the display and wait + pinot_enable_reset(true); + task_sleep(10 * 1000); + + // Initialize the MIPI-DSI logic + mipi_dsim_init(timing, color); + + // Release the display from reset and wait + pinot_enable_reset(false); + task_sleep(7 * 1000); + + // Send a NOP LP command. Renasas requires a command before HS clock, but we + // can't send the sleep-out until after ID read (for Samsung). + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_NOP, 0x00); + + // Be sure the NOP has been transmitted completely, before going HS. + // We "know" that 10us is enough. + spin(10); + + // Enable the high speed clock and wait + mipi_dsim_enable_high_speed(true); + task_sleep(25 * 1000); + + // Read the panel ID from the display chip. If we don't have a valid panel ID, we + // run the quiesce sequence and bail out. + pinot_read_panel_id(); + if (pinot_panel_id == 0) { + mipi_dsim_quiesce(); + return -1; + } + + // For Renesas Pinot, it is necessary to video- and CLCD-enable before sleep-out. + // The delivery of a VSS packet packet lets the chip fix a latchup condition. + + // For old SOCs the MIPI video data output must be enabled before CLCD + // MIPI will leave the link in LP mode until it receives VSYNC from CLCD. + mipi_dsim_enable_video(true); + + // Ignore the real default color and paint black; program CLCD, start frame timing, take a breath + pinot_default_color = 0x00000000; + display_set_enable(true, &pinot_default_color); + spin(100); + + // Tell the panel to exit sleep, wait 7 frames + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_EXIT_SLEEP, 0x00); + display_delay_frames(7); + + // Turn display on and wait 7 frames before letting the backlight be turned on + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_DISPLAY_ON, 0x00); + display_delay_frames(7); + } else { + // Reset the display, and make sure it has power + pinot_enable_reset(true); + pinot_enable_power(true); + // initialize MIPI-DSI while waiting T1 + // Offset mipi_dsim_init giving the panel 100us to see the reset + // This is important for the iBoot -> iBEC transition + start_time = system_time(); + spin(100); + mipi_dsim_init(timing, color); + while (!time_has_elapsed(start_time, 10 * 1000)) task_yield(); + + // Release the display from reset and wait T2. + pinot_enable_reset(false); + task_sleep(7 * 1000); + + // T4 and T5 are underway, since PWREN is trigger from reset on these drivers. + + // Tell the panel to exit sleep, then wait T3 plus transmission time (~8us) + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_EXIT_SLEEP, 0x00); + spin(12); + + // Enable the high speed clock and wait T6, latch the start time for T7. + // Note that T6 technically ends when the panel ID read reaches the display driver, + // but we're being conservative and measuring until we queue the LP command. + mipi_dsim_enable_high_speed(true); + start_time = system_time(); + task_sleep(25 * 1000); + + // Read the panel ID from the display chip. If we don't have a valid panel ID, we + // run the quiesce sequence and bail out. + pinot_read_panel_id(); + if (pinot_panel_id == 0) { + mipi_dsim_quiesce(); + return -1; + } + + // Paint the panel's native color, enable the CLCD and wait 100us + display_set_enable(true, &pinot_default_color); + + // Finish waiting for T7 then send display-on command + while (!time_has_elapsed(start_time, 100 * 1000)) task_yield(); + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_DISPLAY_ON, 0x00); + + // We can now enable video data after all LP commands are sent. + mipi_dsim_enable_video(true); + + // Now the native color is transmitting to the display. We should guarantee a couple + // frames of native color before we switch to the black background that we want + // the user to see. This delay is part of T9, and we'll do the overlapping T8 + // delay after setting the background to black. + panel_class = panel_id_2_class(pinot_panel_id); + if (panel_class > 2 ) { + display_delay_frames(1); + } else { + display_delay_frames(3); + } + + // Draw black, wait T8 (and the final two frames of T9) before we allow backlight enable. + paint_set_bgcolor(0, 0, 0); + paint_update_image(); + display_delay_frames(2); + } + +#ifdef GPIO_LCD_CHKSUM + // Turn off pull-down on LCD_CHKSUM + gpio_configure_pupdn(GPIO_LCD_CHKSUM, GPIO_NO_PUPDN); +#endif + + *display_id = pinot_panel_id; + +#if WITH_HW_POWER + // Adjust analog display voltage offset (down) if necessary + if (pinot_voltage_offset != 0) { + bool fixed_boost = env_get_bool("fixed-lcm-boost", false); + power_set_display_voltage_offset(pinot_voltage_offset, fixed_boost); + } +#endif + + return 0; +} + +int pinot_quiesce(void) +{ + dprintf(DEBUG_CRITICAL, "pinot_quiesce()\n"); + + /******************************************************************************* + * The Type 1 sequence is FROZEN as of Durango and shall NEVER BE TOUCHED AGAIN. + * There are known excursions from the display sequencing spec. Any changes to + * the common code below must be done in a way that preserves Type 1. + ******************************************************************************/ + + // Wait for T10 (not for Type 1) then send display-off and sleep-in + if (PINOT_TYPE >= 2) + display_delay_frames(1); + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_DISPLAY_OFF, 0x00); + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_ENTER_SLEEP, 0x00); + + // Wait for T12 (which covers T11) then stop clock, reset MIPI and display driver + display_delay_frames(6); + // Because of LP transmission uncertainty of up to 2 frames, we need to pad the + // delay. We only do it for Type 2 displays because Type 1 is frozen. + if (PINOT_TYPE >= 2) + display_delay_frames(2); + + display_set_enable(false, NULL); + + mipi_dsim_enable_high_speed(false); + mipi_dsim_quiesce(); + pinot_enable_reset(true); + pinot_enable_power(false); + + return 0; +} + +static void pinot_enable_reset(bool enable) +{ + gpio_write(GPIO_LCD_RST, enable ^ GPIO_LCD_RST_POLARITY ^ 1); +} + +static void pinot_enable_power(bool enable) +{ +#ifdef GPIO_LCD_PWR_EN + gpio_write(GPIO_LCD_PWR_EN, enable); +#endif +} + +#if WITH_DEVICETREE + +#include + +int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + + if (pinot_panel_id == 0) return -1; + + propName = "lcd-panel-id"; + if (FindProperty(pinot_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = pinot_panel_id; + } + + propName = "raw-panel-id"; + if (FindProperty(pinot_node, &propName, &propData, &propSize)) { + if (propSize > sizeof(pinot_raw_panel_id)) propSize = sizeof(pinot_raw_panel_id); + memcpy(propData, pinot_raw_panel_id, propSize); + } + + if (clcd_node != NULL) { + propName = "display-default-color"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = pinot_default_color; + } + + propName = "dot-pitch"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = pinot_dot_pitch; + } + } + + if (backlight_node != NULL) { + propName = "display-backlight-calibration"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = pinot_backlight_cal; + } + propName = "backlight-id"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + if (((u_int32_t *)propData)[0] == 0xffffffff) { + ((u_int32_t *)propData)[0] = (pinot_panel_id >> 8) & 0xff; + } + } + } + + return 0; +} + +#endif diff --git a/drivers/display/pinot/pinot.h b/drivers/display/pinot/pinot.h new file mode 100644 index 0000000..cf56594 --- /dev/null +++ b/drivers/display/pinot/pinot.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2008-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_PINOT_H +#define __DRIVERS_PINOT_H + +#define DISP_IC_LIBERTY (8) +#define DISP_IC_MLC (9) +#define DISP_IC_NUGGET (13) +#define DISP_IC_NUGGET_B0 (14) + + +#endif /* ! __DRIVERS_PINOT_H */ diff --git a/drivers/display/pinot/rules.mk b/drivers/display/pinot/rules.mk new file mode 100644 index 0000000..b2b383c --- /dev/null +++ b/drivers/display/pinot/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DISPLAY_PINOT=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/pinot.o diff --git a/drivers/display/summit/rules.mk b/drivers/display/summit/rules.mk new file mode 100644 index 0000000..7749f85 --- /dev/null +++ b/drivers/display/summit/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DISPLAY_SUMMIT=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/summit.o diff --git a/drivers/display/summit/summit.c b/drivers/display/summit/summit.c new file mode 100644 index 0000000..f353b02 --- /dev/null +++ b/drivers/display/summit/summit.c @@ -0,0 +1,774 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WITH_HW_DISPLAY_PMU +#include +#endif //WITH_HW_DISPLAY_PMU + +#include "summit.h" + +#define SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA 1 +static u_int32_t summit_panel_id; +static u_int32_t summit_dot_pitch; +static u_int32_t summit_default_color; +static u_int32_t summit_ldo_voltage; +static u_int32_t summit_boost_voltage; +static u_int32_t summit_backlight_cal; +static u_int8_t summit_raw_panel_id[15]; +static uint32_t summit_sram_address[4]; //COL:start and end + //Page:start and end + +static void summit_enable_reset(bool enable); +static void summit_enable_power(bool enable); +static void summit_set_brightness(uint16_t level); +static void summit_enable_brightness_control(bool enable); +static void summit_set_packet_length(uint16_t length); +static void summit_sram_update(struct display_timing *timing); +#ifdef SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA +static void summit_disable_dsi_protocol_error_wa(bool lock_mcs); +#endif +struct display_timing *mipi_timing; + + +static int panel_id_2_class(u_int32_t panel_id) +{ + int driver, panel_class = 1; + + driver = panel_id & 0x3f; + + if (driver > DISP_IC_SUMMIT_A0) + panel_class = 2; + + return panel_class; +} + +static void summit_read_panel_id(void) +{ + u_int32_t length; + int result; + int panel_class, driver; + + if (summit_panel_id == 0) { + summit_panel_id = env_get_uint("summit-panel-id", 0); + } + if (summit_panel_id == 0) { + + // read the panel ID + length = sizeof(summit_raw_panel_id); + summit_raw_panel_id[0] = DSIM_CMD_DEVICE_ID; + result = mipi_dsim_read_long_command(DSIM_TYPE_GEN_READ_1P, summit_raw_panel_id, &length); + if ((result != 0) || (length < 3)) { + dprintf(DEBUG_CRITICAL, "summit_init(): read of summit panel id failed\n"); + return; + } else { + summit_panel_id = summit_raw_panel_id[0] << 24; // Build ID + summit_panel_id |= summit_raw_panel_id[1] << 16; // Panel Vendor ID + summit_panel_id |= (summit_raw_panel_id[3] & 0xF0) << 8; // Program ID + summit_panel_id |= (summit_raw_panel_id[2] & 0xF0) << 4; // + summit_panel_id |= (summit_raw_panel_id[3] & 0x07) << 3; // Driver Vendor ID + summit_panel_id |= (summit_raw_panel_id[2] & 0x07) << 0; // + summit_panel_id |= (summit_raw_panel_id[2] & 0x08) << 4; // Auto Boot Bit + summit_panel_id |= (summit_raw_panel_id[3] & 0x08) << 3; // Default Color Bit + + summit_default_color = ((summit_raw_panel_id[3] >> 3) & 1) ? 0x00000000 : 0x00FFFFFF; + summit_ldo_voltage = summit_raw_panel_id[4]; + summit_boost_voltage = summit_raw_panel_id[5]; + } + } + + driver = summit_panel_id & 0x3f; + panel_class = panel_id_2_class(summit_panel_id); + + dprintf(DEBUG_CRITICAL, "summit_init(): summit_panel_id: 0x%08x\n", summit_panel_id); + dprintf(DEBUG_CRITICAL, "summit_init(): summit_default_color: 0x%08x\n", summit_default_color); + dprintf(DEBUG_CRITICAL, "summit_init(): summit_ldo_voltage: 0x%08x\n", summit_ldo_voltage); + dprintf(DEBUG_CRITICAL, "summit_init(): summit_boost_voltage: 0x%08x\n", summit_boost_voltage); +} + +static void summit_enable_reset(bool enable) +{ +#ifdef GPIO_PMU_LCD_RST + power_gpio_configure(GPIO_PMU_LCD_RST, enable ? 0 : 0x38); +#else + gpio_write(GPIO_LCD_RST, enable ^ GPIO_LCD_RST_POLARITY ^ 1); +#endif +} + +static void summit_enable_power(bool enable) +{ +#ifdef GPIO_PMU_LCD_PWR_EN + power_set_gpio(GPIO_PMU_LCD_PWR_EN, 1, 1); +#endif +#ifdef PMU_LCD_PWR_DVDD +#ifdef PMU_LCD_PWR_VCI + if (enable) { + power_enable_ldo(PMU_LCD_PWR_DVDD, enable); + power_enable_ldo(PMU_LCD_PWR_VCI, enable); + } else { + power_enable_ldo(PMU_LCD_PWR_VCI, enable); + spin(54 * 1000); + power_enable_ldo(PMU_LCD_PWR_DVDD, enable); + } +#endif // PMU_LCD_PWR_VCI +#endif // PMU_LCD_PWR_DVDD +#ifdef GPIO_LCD_PWR_EN + gpio_write(GPIO_LCD_PWR_EN, enable); +#endif +} + +static int summit_init_video_mode(struct display_timing *timing, enum colorspace color, u_int32_t *display_id) +{ + utime_t start_time; + int panel_driver; + UInt8 data[26] = ""; + uint16_t brightness_level = 0xff03; + + // Reset the display, and make sure it has power + summit_enable_reset(true); + summit_enable_power(true); + // initialize MIPI-DSI while waiting T1 + // Offset mipi_dsim_init giving the panel 100us to see the reset + // This is important for the iBoot -> iBEC transition + start_time = system_time(); + spin(100); + mipi_dsim_init(timing, color); + while (!time_has_elapsed(start_time, 10 * 1000)) task_yield(); + + // Release the display from reset and wait T2. + summit_enable_reset(false); + task_sleep(7 * 1000); + + // T4 and T5 are underway, since PWREN is trigger from reset on these drivers. + + // Enable the high speed clock and wait T6, latch the start time for T7. + // Note that T6 technically ends when the panel ID read reaches the display driver, + // but we're being conservative and measuring until we queue the LP command. + mipi_dsim_enable_high_speed(true); + start_time = system_time(); + task_sleep(25 * 1000); + + // set packet length + summit_set_packet_length(0x20); + + spin(1 * 1000); + + // Read the panel ID from the display chip. If we don't have a valid panel ID, we + // run the quiesce sequence and bail out. + summit_read_panel_id(); + if (summit_panel_id == 0) { + mipi_dsim_quiesce(); + return -1; + } + + panel_driver = summit_panel_id & 0x3f; + + if (panel_driver == DISP_IC_SUMMIT_A0) { + summit_set_brightness(brightness_level); + + summit_enable_brightness_control(true); + + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_EXIT_SLEEP, 0x00); + + spin(5 * 1000); + + //Unlock MCS registers + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE_1P, 0xB0, 0xAC); + + spin(1 * 1000); + + //6. Set to internal oscillator + data[0] = 0xC9; + data[1] = 0xF7; + data[2] = 0xF8; + data[3] = 0x02; + data[4] = 0x02; + data[5] = 0x02; + mipi_dsim_send_long_command(DSIM_TYPE_GEN_LONG_WRITE, data, 6); + + spin(5 * 1000); + +#if SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA + summit_disable_dsi_protocol_error_wa(false); +#endif //SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA + + + // Paint the panel's native color, enable the CLCD and wait 100us + display_set_enable(true, &summit_default_color); + spin(32*1000); + + // Finish waiting for T7 then send display-on command + //while (!time_has_elapsed(start_time, 100 * 1000)) task_yield(); + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_DISPLAY_ON, 0x00); + + //8. Set up some more MCS registers that weren't programmed correctly in OTP + data[0] = 0xCE; + data[1] = 0x00; + data[2] = 0x10; + data[3] = 0x10; + data[4] = 0x10; + mipi_dsim_send_long_command(DSIM_TYPE_GEN_LONG_WRITE, data, 5); + + spin(1 * 1000); + + data[0] = 0xCF; + data[1] = 0x15; + mipi_dsim_send_long_command(DSIM_TYPE_GEN_LONG_WRITE, data, 2); + + //lock MCS registers + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE_1P, 0xB0, 0xCA); + + // We can now enable video data after all LP commands are sent. + mipi_dsim_enable_video(true); + + // Now the native color is transmitting to the display. We should guarantee a couple + // frames of native color before we switch to the black background that we want + // the user to see. This delay is part of T9, and we'll do the overlapping T8 + // delay after setting the background to black. + display_delay_frames(3); + + // Draw black, wait T8 (and the final two frames of T9) before we allow backlight enable. + paint_set_bgcolor(0, 0, 0); + paint_update_image(); + display_delay_frames(2); + +#ifdef GPIO_LCD_CHKSUM + // Turn off pull-down on LCD_CHKSUM + gpio_configure_pupdn(GPIO_LCD_CHKSUM, GPIO_NO_PUPDN); +#endif + } else { + +#ifdef WITH_HW_DISPLAY_PMU + display_pmu_init(); +#endif // WITH_HW_DISPLAY_PMU + + // We can now enable video data after all LP commands are sent. + mipi_dsim_enable_video(true); + + // Paint the panel's native color, enable the CLCD and wait 100us + display_set_enable(true, &summit_default_color); + display_delay_frames(1); + + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_EXIT_SLEEP, 0x00); + + spin(5 * 1000); + + summit_set_brightness(brightness_level); + summit_enable_brightness_control(true); + +#if SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA + summit_disable_dsi_protocol_error_wa(true); +#endif //SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA + + // Paint the panel's native color, enable the CLCD and wait 100us + display_set_enable(true, &summit_default_color); + spin(32*1000); + + // Finish waiting for T7 then send display-on command + //while (!time_has_elapsed(start_time, 100 * 1000)) task_yield(); + display_delay_frames(5); + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_DISPLAY_ON, 0x00); + + // Now the native color is transmitting to the display. We should guarantee a couple + // frames of native color before we switch to the black background that we want + // the user to see. This delay is part of T9, and we'll do the overlapping T8 + // delay after setting the background to black. + display_delay_frames(1); + + // Draw black, wait T8 (and the final two frames of T9) before we allow backlight enable. + paint_set_bgcolor(0, 0, 0); + paint_update_image(); + display_delay_frames(2); + +#ifdef GPIO_LCD_CHKSUM + // Turn off pull-down on LCD_CHKSUM + gpio_configure_pupdn(GPIO_LCD_CHKSUM, GPIO_NO_PUPDN); +#endif + } + + *display_id = summit_panel_id; + + return 0; +} + +static int summit_do_panel_calibration() +{ + UInt8 data[] = { 0x51, 0xff, 0x3}; + + return mipi_dsim_send_long_command(DSIM_TYPE_GEN_LUT_WRITE, data, 3); +} + +static int summit_init_cmd_mode(struct display_timing *timing, enum colorspace color, u_int32_t *display_id) +{ + utime_t start_time; + uint32_t brightness_level; + + mipi_timing = timing; + + // Reset the display, and make sure it has power + summit_enable_reset(true); + summit_enable_power(true); + + // initialize MIPI-DSI while waiting T1 + // Offset mipi_dsim_init giving the panel 1.5 ms to see the reset + start_time = system_time(); + mipi_dsim_init(timing, color); + while (!time_has_elapsed(start_time, 15 * 100)) task_yield(); + + // Release the display from reset and wait T2. + summit_enable_reset(false); + task_sleep(5 * 1000); + + // Enable the high speed clock and latch the start time for T4. + // Note that T4 technically ends when the panel ID read reaches the display driver, + // but we're being conservative and measuring until we queue the LP command. + mipi_dsim_enable_high_speed(true); + start_time = system_time(); + + // set packet length + summit_set_packet_length(0x20); + + spin(1 * 1000); + + // Read the panel ID from the display chip. If we don't have a valid panel ID, we + // run the quiesce sequence and bail out. + summit_read_panel_id(); + if (summit_panel_id == 0) { + mipi_dsim_quiesce(); + return -1; + } + +#ifdef WITH_HW_DISPLAY_PMU + display_pmu_init(); +#endif // WITH_HW_DISPLAY_PMU + + //Wait for T4 to complete + while (!time_has_elapsed(start_time, 5 * 1000)) task_yield(); + + summit_sram_update(timing); + + //summit based panels set brightness vs backlight. + //brightness_level = env_get_uint("backlight-level", 0xffff); + brightness_level = 0xff03; + summit_set_brightness(brightness_level); + + summit_enable_brightness_control(true); + + //Sleep out and latch for T5a + start_time = system_time(); + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_EXIT_SLEEP, 0x00); + while (!time_has_elapsed(start_time, 5 * 1000)) task_yield(); + + // Finish waiting for T5 then send display-on command + while (!time_has_elapsed(start_time, 108 * 1000)) task_yield(); + +#if SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA + summit_disable_dsi_protocol_error_wa(true); +#endif //SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA + //Display On + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_DISPLAY_ON, 0x00); + + // We can now enable video data after all LP commands are sent. + mipi_dsim_enable_video(true); + + // Paint the panel's native color, enable adp/adbe + display_set_enable(true, &summit_default_color); + + paint_set_bgcolor(0, 0, 0); + paint_update_image(); + display_delay_frames(1); + + *display_id = summit_panel_id; + + return 0; +} + +static void summit_set_brightness(uint16_t level) +{ + UInt8 data[3] = ""; + + data[0] = 0x51; + data[1] = (level >> 2) & 0xff; + data[2] = (level & 0x3); + mipi_dsim_send_long_command(DSIM_TYPE_GEN_LUT_WRITE, data, 3); + +} + +static void summit_enable_brightness_control(bool enable) +{ + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE_1P, 0x53, enable ? 0x20 : 0); +} + +static void summit_set_packet_length(uint16_t length) +{ + mipi_dsim_send_short_command(0x37, length & 0xff, (length >> 8) & 0xff); +} + +#define SUMMIT_STARTING_COLUMN_ADDRESS 0x0 +#define SUMMIT_STARTING_PAGE_ADDRESS 0x0 + +static void summit_sram_update(struct display_timing *timing) +{ + uint8_t data[5] = ""; + uint16_t sram_start_addr, sram_end_addr; + + sram_end_addr = (timing->h_active - 1); + sram_start_addr = SUMMIT_STARTING_COLUMN_ADDRESS; + summit_sram_address[0] = sram_start_addr; + summit_sram_address[1] = sram_end_addr; + data[0] = 0x2a; + data[1] = ((sram_start_addr >> 8) & 0xff); + data[2] = ((sram_start_addr >> 0) & 0xff); + data[3] = ((sram_end_addr >> 8) & 0xff); + data[4] = ((sram_end_addr >> 0) & 0xff); + mipi_dsim_send_long_command(0x39, data, sizeof(data)); + + sram_end_addr = (timing->v_active - 1); + sram_start_addr = SUMMIT_STARTING_COLUMN_ADDRESS; + summit_sram_address[2] = sram_start_addr; + summit_sram_address[3] = sram_end_addr; + data[0] = 0x2b; + data[1] = ((sram_start_addr >> 8) & 0xff); + data[2] = ((sram_start_addr >> 0) & 0xff); + data[3] = ((sram_end_addr >> 8) & 0xff); + data[4] = ((sram_end_addr >> 0) & 0xff); + mipi_dsim_send_long_command(0x39, data, sizeof(data)); + + data[0] = 0x2c; + data[1] = 0xff; + mipi_dsim_send_long_command(0x39, data, 2); +} + +// +//Global functions +// + +int summit_init(struct display_timing *timing, enum colorspace color, u_int32_t *display_id) +{ + bool is_video_mode = true; + +#ifdef TARGET_DISP_VIDEO_MODE + is_video_mode = TARGET_DISP_VIDEO_MODE; +#endif //TARGET_DISP_VIDEO_MODE + + dprintf(DEBUG_CRITICAL, "summit_init %s mode()\n", is_video_mode ? "video" : "command"); + + // Save the display's dot pitch + summit_dot_pitch = timing->dot_pitch; + + if (is_video_mode) { + return summit_init_video_mode(timing, color, display_id); + } else { + return summit_init_cmd_mode(timing, color, display_id); + } + +} + +int summit_quiesce(void) +{ + // send display-off and wait T7 + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_DISPLAY_OFF, 0x00); + spin(18 * 1000); + + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE, DSIM_CMD_ENTER_SLEEP, 0x00); + + // Wait for T8 then stop clock, reset MIPI and display driver + display_delay_frames(6); + // Because of LP transmission uncertainty of up to 2 frames, we need to pad the + // delay. We only do it for Type 2 displays because Type 1 is frozen. + display_delay_frames(2); + + mipi_dsim_enable_high_speed(false); + mipi_dsim_quiesce(); + summit_enable_reset(true); + summit_enable_power(false); + + return 0; +} + +#ifdef SUMMIT_DISABLE_DSI_PROTOCOL_ERROR_WA +static void summit_disable_dsi_protocol_error_wa(bool lock_mcs) +{ + uint8_t data1[6] = ""; + uint32_t length; + + if (lock_mcs) { + //Unlock MCS registers + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE_1P, 0xB0, 0xAC); + spin(1 * 1000); + } + + data1[0] = 0xd4; + data1[1] = 0x07; + data1[2] = 0xc0; + data1[3] = 0x80; + data1[4] = 0x00; + data1[5] = 0x80; + length = sizeof(data1); + mipi_dsim_send_long_command(DSIM_TYPE_GEN_LONG_WRITE, data1, length); + + if (lock_mcs) { + //lock MCS registers + mipi_dsim_send_short_command(DSIM_TYPE_DSC_WRITE_1P, 0xB0, 0xCA); + } +} +#endif + +int8_t summit_get_raw_panel_id(uint8_t *raw_panel_id, size_t raw_panel_id_length) +{ + RELEASE_ASSERT(raw_panel_id != NULL); + RELEASE_ASSERT(raw_panel_id_length >= sizeof(summit_raw_panel_id)); + + bcopy(summit_raw_panel_id, raw_panel_id, sizeof(summit_raw_panel_id)); + + return 0; +} + +#if WITH_DEVICETREE + +#include + +int summit_update_device_tree(DTNode *summit_node, DTNode *clcd_node, DTNode *backlight_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + char *PropNameFuncDisable = "function-backlight_inval"; + char *PropNameFuncEnable = "function-backlight_enable"; + char *PropNameFuncUpdate = "function-backlight_update"; + char *PropNameFuncNoUpdate = "function-backlight_noupdate"; + + if (summit_panel_id == 0) return -1; + + propName = "lcd-panel-id"; + if (FindProperty(summit_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = summit_panel_id; + } + + propName = "raw-panel-id"; + if (FindProperty(summit_node, &propName, &propData, &propSize)) { + if (propSize > sizeof(summit_raw_panel_id)) propSize = sizeof(summit_raw_panel_id); + memcpy(propData, summit_raw_panel_id, propSize); + } +#ifdef TARGET_DISP_VIDEO_MODE + //tell the os if video or command mode + propName = "video-mode"; + if (FindProperty(summit_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = TARGET_DISP_VIDEO_MODE; + } +#endif //TARGET_DISP_VIDEO_MODE + propName = "sram-addresses"; + if (FindProperty(summit_node, &propName, &propData, &propSize)) { + memcpy(propData, summit_sram_address, sizeof(summit_sram_address)); + } + + if (clcd_node != NULL) { + propName = "display-default-color"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = summit_default_color; + } + + propName = "dot-pitch"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = summit_dot_pitch; + } + +#ifdef TARGET_DISP_VIDEO_MODE + //tell the os if video or command mode + propName = "video-mode"; + if (FindProperty(clcd_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = TARGET_DISP_VIDEO_MODE; + } +#endif //TARGET_DISP_VIDEO_MODE + } + + if (backlight_node != NULL) { + propName = "function-backlight_enable"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + memset(propName, 0, strlen(propName)); + strlcpy(propName, PropNameFuncDisable, strlen(PropNameFuncDisable) + 1); + } + propName = "function-backlight_enable-sum"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + memset(propName, 0, strlen(propName)); + strlcpy(propName, PropNameFuncEnable, strlen(PropNameFuncEnable) + 1); + } + propName = "function-backlight_update"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + memset(propName, 0, strlen(propName)); + strlcpy(propName, PropNameFuncNoUpdate, strlen(PropNameFuncNoUpdate) + 1); + } + + propName = "function-backlight_update-sum"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + memset(propName, 0, strlen(propName)); + strlcpy(propName, PropNameFuncUpdate, strlen(PropNameFuncUpdate) + 1); + } + propName = "display-backlight-calibration"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = summit_backlight_cal; + } + propName = "backlight-id"; + if (FindProperty(backlight_node, &propName, &propData, &propSize)) { + if (((u_int32_t *)propData)[0] == 0xffffffff) { + ((u_int32_t *)propData)[0] = (summit_panel_id >> 8) & 0xff; + } + } + } + return 0; +} + +#endif + +//FOR DEBUG ONLY WHEN NEEDED +#if 0 +static int32_t panelFill(uint32_t width, uint32_t height, uint8_t red, uint8_t green, uint8_t blue ) +{ + int32_t err; + uint32_t x, y; + uint8_t *ptr; + uint8_t *dummyLine; + uint32_t lineBytes; + + printf("width %d height %d red 0x%x green 0x%x blue 0x%x\n", width, height, red, green, blue); + lineBytes = width * 3; + dummyLine = (uint8_t *) malloc(lineBytes + 1); + if (dummyLine == NULL ) return -1; + + ptr = &dummyLine[1]; + printf("%s %d\n", __FUNCTION__, __LINE__); + + for (x = 0; x < width; x++) { + *ptr++ = red; + *ptr++ = green; + *ptr++ = blue; + } + printf("%s %d\n", __FUNCTION__, __LINE__); +#define MIPI_DSI_LONG_DCS_WRITE 0x39 +#define MIPI_DCS_COMMAND_WRITE_MEMORY_START 0x2C +#define MIPI_DCS_COMMAND_WRITE_MEMORY_CONTINUE 0x3C + + for (y = 0; y < height; y++) { + if (y == 0) { + dummyLine[0] = MIPI_DCS_COMMAND_WRITE_MEMORY_START; + err = mipi_dsim_send_long_command( MIPI_DSI_LONG_DCS_WRITE, dummyLine, lineBytes + 1 ); + if (err) + goto PANEL_FILL_ERROR; + } else { + dummyLine[0] = MIPI_DCS_COMMAND_WRITE_MEMORY_CONTINUE; + err = mipi_dsim_send_long_command( MIPI_DSI_LONG_DCS_WRITE, dummyLine, lineBytes + 1 ); + if (err) + goto PANEL_FILL_ERROR; + } + + spin(1000); + } + +PANEL_FILL_ERROR: + free( dummyLine); + + return err; +} + +#include + +static int do_mipi(int argc, struct cmd_arg *args) +{ + if (argc < 3) { + puts("not enough arguments.\n"); +usage: + printf("%s readshort \n", args[0].str); + printf("%s readlong \n", args[0].str); + printf("%s writeshort \n", args[0].str); + printf("%s writelong ...\n", args[0].str); + printf("%s fill \n", args[0].str); + return -1; + } + + int cmd = args[2].u; + + if (!strcmp("readshort", args[1].str)) { + uint8_t data[32]; + int err; + + err = mipi_dsim_read_short_command(cmd, data); + if (err < 0) { + printf("error %d reading from mipi\n", err); + } else { + hexdump(data, sizeof(data)); + } + } else if (!strcmp("readlong", args[1].str)) { + uint8_t data[16]; + int err; + uint32_t len = 32; + + data[0] = args[3].u; + printf("reading from reg 0x%x length %d\n", data[0], len); + err = mipi_dsim_read_long_command(cmd, data, &len); + if (err < 0) { + printf("error %d reading from mipi\n", err); + } else { + hexdump(data, len); + } + } else if (!strcmp("writeshort", args[1].str)) { + u_int8_t data[2]; + int err; + + data[0] = args[3].u; + data[1] = args[4].u; + + printf("writing cmd 0x%x data0 0x%x data1 0x%x\n", cmd, data[0], data[1]); + err = mipi_dsim_send_short_command(cmd, data[0], data[1]); + } else if (!strcmp("writelong", args[1].str)) { + u_int8_t data[64]; + size_t len, i; + int err; + + len = argc - 3; + if (len > sizeof(data)) len = sizeof(data); + + for (i = 0; i < len; i++) { + data[i] = args[i+3].u; + printf("data[%d]=0x%x\n", i, data[i]); + } + + printf("writing %d bytes of data\n", len); + err = mipi_dsim_send_long_command(cmd, data, len); + if (err < 0) + printf("error %d writing to mipi\n", err); + } else if (!strcmp("fill", args[1].str)) { + int err; + + printf("filling width %d height %d r 0x%x g 0%x b 0x%x\n", args[2].u, args[3].u, args[4].u, args[5].u, args[6].u); + err = panelFill(args[2].u, args[3].u, args[4].u, args[5].u, args[6].u); + if (err < 0) { + printf("error %d reading from mipi\n", err); + } + } else if (!strcmp("writeshort", args[1].str)) { + } else { + puts("unrecognized command.\n"); + goto usage; + } + + return 0; +} +#if WITH_RECOVERY_MODE +MENU_COMMAND_DEBUG(mipi, do_mipi, "[read/write] mipi commands", NULL); +#endif +#endif diff --git a/drivers/display/summit/summit.h b/drivers/display/summit/summit.h new file mode 100644 index 0000000..3087e1a --- /dev/null +++ b/drivers/display/summit/summit.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_SUMMIT_H +#define __DRIVERS_SUMMIT_H + +#define DISP_IC_SUMMIT_A0 (0x12) +#define DISP_IC_SUMMIT_B0 (0x13) + + +#endif /* ! __DRIVERS_SUMMIT_H */ diff --git a/drivers/display/tmds/rules.mk b/drivers/display/tmds/rules.mk new file mode 100644 index 0000000..8a89cba --- /dev/null +++ b/drivers/display/tmds/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DISPLAY_TMDS=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/tmds.o diff --git a/drivers/display/tmds/tmds.c b/drivers/display/tmds/tmds.c new file mode 100644 index 0000000..ac9a747 --- /dev/null +++ b/drivers/display/tmds/tmds.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#include "tmds.h" + +int tmds_init(struct display_timing *timing, enum colorspace color, u_int32_t *display_id) +{ + u_int8_t data[2]; + + clock_set_frequency(timing->host_clock_id, 0, 0, 0, 0, timing->pixel_clock); + /* XXX what about CLCD dithering? */ + + gpio_configure(GPIO_LCD_VCLK, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_VSYNC, GPIO_CFG_FUNC1); // XXX GPIO OUT_1 eventually + gpio_configure(GPIO_LCD_HSYNC, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_VDEN, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_VDEN, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D0, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D1, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D2, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D3, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D4, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D5, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D6, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D7, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D8, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D9, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D10, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D11, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D12, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D13, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D14, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D15, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D16, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D17, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D18, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D19, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D20, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D21, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D22, GPIO_CFG_FUNC1); + gpio_configure(GPIO_LCD_D23, GPIO_CFG_FUNC1); + + data[0] = kTFP_DE_CTL; + data[1] = 0; /* Active high DE is assumed */ + if (!timing->neg_hsync) + data[1] |= kTFP_DE_CTL_HS_POL; + if (!timing->neg_vsync) + data[1] |= kTFP_DE_CTL_VS_POL; + iic_write(TMDS_IIC_BUS, kTFP_ADDR_W, data, 2); + + data[0] = kTFP_CTL_1_MODE; + data[1] = kTFP_CTL_1_MODE_nPD | kTFP_CTL_1_MODE_BSEL; + if (timing->neg_vclk) + data[1] |= kTFP_CTL_1_MODE_EDGE; + iic_write(TMDS_IIC_BUS, kTFP_ADDR_W, data, 2); + + return 0; +} + +int tmds_quiesce(void) +{ + dprintf(DEBUG_CRITICAL, "tmds_quiesce()\n"); + return 0; +} + diff --git a/drivers/display/tmds/tmds.h b/drivers/display/tmds/tmds.h new file mode 100644 index 0000000..4ccf8bd --- /dev/null +++ b/drivers/display/tmds/tmds.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TMDS_H +#define __TMDS_H + +/* Definitions for the TI TFP410 */ + +enum { + kTFP_ADDR_R = 0x7f, + kTFP_ADDR_W = 0x7e +}; + +enum { + kTFP_CTL_1_MODE = 0x08, + kTFP_CTL_2_MODE = 0x09, + kTFP_CTL_3_MODE = 0x0a, + + kTFP_DE_DLY = 0x32, + kTFP_DE_CTL = 0x33, + kTFP_DE_TOP = 0x34 +}; + +enum { + kTFP_CTL_1_MODE_nPD = (1 << 0), + kTFP_CTL_1_MODE_EDGE = (1 << 1), + kTFP_CTL_1_MODE_BSEL = (1 << 2), + kTFP_CTL_1_MODE_DSEL = (1 << 3), + kTFP_CTL_1_MODE_HEN = (1 << 4), + kTFP_CTL_1_MODE_VEN = (1 << 5), + kTFP_CTL_1_MODE_TDIS = (1 << 6) +}; + +enum { + kTFP_DE_CTL_DE_DLY8 = (1 << 0), + kTFP_DE_CTL_HS_POL = (1 << 4), + kTFP_DE_CTL_VS_POL = (1 << 5), + kTFP_DE_CTL_DE_GEN = (1 << 6) +}; + +#endif /* __TMDS_H */ diff --git a/drivers/display_pmu/beryllium/beryllium.c b/drivers/display_pmu/beryllium/beryllium.c new file mode 100644 index 0000000..b0f516b --- /dev/null +++ b/drivers/display_pmu/beryllium/beryllium.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#define IIC_ADDRESS (0xEE) + +#define ADDR_0x08 (0x08) +#define ADDR_0x15 (0x15) +#define ADDR_0x16 (0x16) +#define ADDR_0x17 (0x17) + +static bool beryllium_supported; +static uint8_t beryllium_ldo_voltage; // LDO voltage encoding read from Panel +static uint8_t beryllium_boost_voltage; // Boost voltage encoding read from Panel +static bool beryllium_use_updated_voltages; // Set if LDO and Boost voltage override exists + +int display_pmu_init(void) +{ + uint8_t data[2]; + + extern bool ipod6_is_beryllium_supported(); + + if((beryllium_supported = ipod6_is_beryllium_supported()) == false) + goto exit; + +#if WITH_HW_DISPLAY_SUMMIT + extern int8_t summit_get_raw_panel_id(uint8_t *raw_panel_id, size_t raw_panel_id_length); + uint8_t raw_panel_id[15]; + + summit_get_raw_panel_id(raw_panel_id, sizeof(raw_panel_id)); + beryllium_ldo_voltage = raw_panel_id[4]; + beryllium_boost_voltage = raw_panel_id[5]; + beryllium_use_updated_voltages = true; +#endif + + // clear AUTO_RESTART bit + // n27a: Beryllium OTP setting for AUTO_RESTART bit is set wrong + data[0] = ADDR_0x15; + RELEASE_ASSERT(iic_read(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, (const void *)data, 1, (void *)(data + 1), 1, IIC_NORMAL) == 0); + data[1] &= ~(1 << 0); + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); + + // clear SHDN bit, this will cause chip to enter IDLE mode after OTP read + data[0] = ADDR_0x08; + data[1] = 0; + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); + + // wait 2ms + task_sleep(2); + + if (beryllium_use_updated_voltages) { + // set LDO voltage + data[0] = ADDR_0x16; + data[1] = beryllium_ldo_voltage; + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); + + // set Boost voltage + data[0] = ADDR_0x17; + data[1] = beryllium_boost_voltage; + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); + } + +exit: + return 0; +} + +int display_pmu_quiesce(void) +{ + uint8_t data[2]; + + if (beryllium_supported == false) + goto exit; + + // set SHDN bit, this will cause chip to go back into shutdown mode + data[0] = ADDR_0x08; + data[1] = 1; + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); + +exit: + return 0; +} + +#if WITH_DEVICETREE +void display_pmu_update_device_tree(const char *node_string) +{ + uint32_t propSize; + char *propName; + void *propData; + DTNode *node; + + // Find display-pmu node + if (FindNode(0, node_string, &node)) { + if (beryllium_supported && beryllium_use_updated_voltages) { + propName = "ldo-voltage"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (propSize >= sizeof(beryllium_ldo_voltage)) + *(uint32_t *)propData = beryllium_ldo_voltage; + + propName = "boost-voltage"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (propSize >= sizeof(beryllium_boost_voltage)) + *(uint32_t *)propData = beryllium_boost_voltage; + } + else if (!beryllium_supported) { + propName = "not-supported"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (propSize >= sizeof(bool)) + *(bool *)propData = true; + } + } +} +#endif diff --git a/drivers/display_pmu/beryllium/rules.mk b/drivers/display_pmu/beryllium/rules.mk new file mode 100644 index 0000000..9f7913a --- /dev/null +++ b/drivers/display_pmu/beryllium/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DISPLAY_PMU=1 \ + WITH_HW_BERYLLIUM=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/beryllium.o diff --git a/drivers/display_pmu/chestnut/chestnut.c b/drivers/display_pmu/chestnut/chestnut.c new file mode 100644 index 0000000..0e28a62 --- /dev/null +++ b/drivers/display_pmu/chestnut/chestnut.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#define IIC_ADDRESS (0x4E) + +#define DEVICE_ID_0 (0x00) +#define DEVICE_ID_1 (0x01) +#define DEVICE_ID_2 (0x02) +#define REVISION (0x03) +#define STATUS (0x04) +#define ENABLE (0x05) +#define VNEG_CONTROL (0x0F) + +#define TI_DEVICE_ID0 (0x007365) +#define TI_DEVICE_ID1 (0x00F365) +#define INTERSIL_DEVICE_ID (0x0BA46E) + +uint32_t chestnut_device_id; +uint8_t chestnut_device_revision; +bool chestnut_probed; +bool chestnut_present; + +static const char *chestnut_device_string(uint32_t device_id) +{ + switch (device_id) { + case TI_DEVICE_ID0: + case TI_DEVICE_ID1: + return "TI"; + + case INTERSIL_DEVICE_ID: + return "Intersil"; + } + + return "Unknown"; +} + +static void chestnut_probe() +{ + if (!chestnut_probed) { + // Probe by reading a register + uint8_t data[4] = { 0 }; + + data[0] = REVISION; + if (iic_read(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, (const void *)data, 1, (void *)(data + 1), 1, IIC_NORMAL) == 0) { + chestnut_device_revision = data[1]; + + data[0] = DEVICE_ID_0; + if (iic_read(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, (const void *)data, 1, (void *)(data + 1), 3, IIC_NORMAL) == 0) + chestnut_device_id = (data[1] << 16) | (data[2] << 8) | data[3]; + + chestnut_present = true; + } + + chestnut_probed = true; + } + + if (chestnut_present) + dprintf(DEBUG_CRITICAL, "Display PMU found, 0x%08x, %s-%02x\n", chestnut_device_id, chestnut_device_string(chestnut_device_id), chestnut_device_revision); + else + dprintf(DEBUG_INFO, "Display PMU probe failed\n"); +} + +#if TARGET_CHESTNUT_USE_LOW_RIPPLE_MODE && !defined(TARGET_CHESTNUT_VNEG_CONTROL) +#define TARGET_CHESTNUT_VNEG_CONTROL 0x07 +#endif + +int display_pmu_init(void) +{ + chestnut_probe(); + + if (chestnut_present) { + uint8_t data[2]; + +#if defined(TARGET_CHESTNUT_VNEG_CONTROL) + // Set low-ripple mode for VNEG + // N5x | Set low-ripple mode in Chestnut before Chestnut rails are enabled + data[0] = VNEG_CONTROL; + data[1] = TARGET_CHESTNUT_VNEG_CONTROL; + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); +#endif + + // Enable power to the panel + data[0] = ENABLE; + data[1] = 0x3; // Enable Boost (VNEG and VPOS LDOs) + data[1] |= target_get_lcm_ldos(); + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); + + return 0; + } + + return -1; +} + +int display_pmu_quiesce(void) +{ + if (chestnut_present) { + uint8_t data[2]; + + // Disable power to the panel + data[0] = ENABLE; + data[1] = 0; + RELEASE_ASSERT(iic_write(DISPLAY_PMU_IIC_BUS, IIC_ADDRESS, data, 2) == 0); + + return 0; + } + + return -1; +} + +#if WITH_DEVICETREE +void display_pmu_update_device_tree(const char *node_string) +{ + uint32_t propSize; + char *propName; + void *propData; + DTNode *node; + + if (!chestnut_present) + return; + + // Find display-pmu node + if (FindNode(0, node_string, &node)) { + // Fill in the probed device info + + propName = "device-id"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (propSize >= sizeof(chestnut_device_id)) + *(uint32_t *)propData = chestnut_device_id; + + propName = "device-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (propSize >= sizeof(chestnut_device_revision)) + *(uint32_t *)propData = chestnut_device_revision; + + propName = "device-string"; + if (FindProperty(node, &propName, &propData, &propSize)) { + bzero(propData, propSize); + strlcpy(propData, chestnut_device_string(chestnut_device_id), propSize); + } + } +} +#endif diff --git a/drivers/display_pmu/chestnut/rules.mk b/drivers/display_pmu/chestnut/rules.mk new file mode 100644 index 0000000..794cd96 --- /dev/null +++ b/drivers/display_pmu/chestnut/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DISPLAY_PMU=1 \ + WITH_HW_CHESTNUT=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/chestnut.o diff --git a/drivers/displayport/controller.c b/drivers/displayport/controller.c new file mode 100644 index 0000000..074e175 --- /dev/null +++ b/drivers/displayport/controller.c @@ -0,0 +1,691 @@ +/* + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include + +#if WITH_HW_MCU +#include +#endif + +#include "dpcd.h" + +///////////////////////////////////////// +////////// debug support + +#define DP_DEBUG_MASK ( \ + DP_DEBUG_INIT | \ + DP_DEBUG_ERROR | \ + DP_DEBUG_INFO | \ + DP_DEBUG_TRAINING | \ + 0) + +#undef DP_DEBUG_MASK +#define DP_DEBUG_MASK (DP_DEBUG_INIT | DP_DEBUG_ERROR) + +#define DP_DEBUG_INIT (1<<16) // initialisation +#define DP_DEBUG_ERROR (1<<17) // errors +#define DP_DEBUG_INFO (1<<18) // info +#define DP_DEBUG_TRAINING (1<<19) // link training +#define DP_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((DP_DEBUG_ ## _fac) & (DP_DEBUG_MASK | DP_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "DPC: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +///////////////////////////////////////// +////////// consts, macros + +#define kMaxRetry 5 +#define kClockRecoveryDelay 100 +#define kEQDelay 400 +#define kMaxClockRecoveryIterations 100 + + +#define require(assertion, exception_label) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +#define require_action(assertion, exception_label, action) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr(error_code, exception_label) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr_action(error_code, exception_label, action) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + + + +///////////////////////////////////////// +////////// typedefs, enums, structs + +enum { + kLinkTrainingStateIdle, + kLinkTrainingStateStart, + kLinkTrainingStateClockRecovery, + kLinkTrainingStateEQTraining +}; + + +///////////////////////////////////////// +////////// local variables + +static u_int8_t dp_link_clock_recovery_retry[kDPMaxLanes]; +static bool dp_link_voltage_swing_max[kDPMaxLanes]; +static bool dp_link_eq_max[kDPMaxLanes]; +static u_int8_t dp_link_eq_retry; +static u_int32_t dp_link_clock_recovery_iterations; +static u_int8_t dp_link_eq_iterations; +static struct video_link_data dp_video_data; +static int eq_pattern = kDPTrainingPattern2; +static dp_t dp_link_config = { + .mode = kDPControllerMode_Master, + .type = kDPControllerType_DP, + .min_link_rate = 0x6, + .max_link_rate = 0x6, + .lanes = 4, + .ssc = 0, + .alpm = 0, + .vrr_enable = 0, + .vrr_on = 0, +}; + +///////////////////////////////////////// +////////// local functions declaration + +static int run_link_training_state_machine(struct dp_link_train_data *data); +static int process_link_state_start(struct dp_link_train_data *data, u_int32_t *state); +static int process_link_state_clock_recovery(struct dp_link_train_data *data, u_int32_t *state); +static int process_link_state_eq_training(struct dp_link_train_data *data, u_int32_t *state); +static int process_link_state_eq_training_internal(struct dp_link_train_data *data, uint32_t lane, bool *done); +static int process_link_state_clock_recovery_internal(struct dp_link_train_data * data, uint32_t lane, bool *p_done); + + + +///////////////////////////////////////// +////////// DisplayPort global functions + +int displayport_init(dp_t *dp) +{ + // defaults to External display, and Master mode + if ( dp_controller_start(dp) != 0 ) + return -1; + + return 0; +} + +int displayport_init_with_timing_info(struct display_timing *timing_info) +{ + memcpy(&dp_link_config, timing_info->display_config, sizeof(dp_t)); + + displayport_set_timings(timing_info); + + if ( dp_controller_start(&dp_link_config) != 0 ) + return -1; + + return 0; +} + +int displayport_set_timings(struct display_timing *timing_info) +{ + u_int8_t mode; + + memcpy(&dp_link_config, timing_info->display_config, sizeof(dp_t)); + mode = dp_link_config.mode; + + bzero(&dp_video_data, sizeof(struct video_link_data)); + + dp_video_data.mirror_mode = (mode == kDPControllerMode_Slave) ? true : false; + dp_video_data.test_mode = 0; + dp_video_data.color.depth = 8; + dp_video_data.color.space = kDisplayColorSpacesRGB; + dp_video_data.color.range = kDisplayColorDynamicRangeVESA; + dp_video_data.color.coefficient = kDisplayColorCoefficientITU601; + dp_video_data.timing.axis[0].total = timing_info->h_active + timing_info->h_back_porch + + timing_info->h_front_porch + timing_info->h_pulse_width; + dp_video_data.timing.axis[0].active = timing_info->h_active; + dp_video_data.timing.axis[0].sync_width = timing_info->h_pulse_width; + dp_video_data.timing.axis[0].back_porch = timing_info->h_back_porch; + dp_video_data.timing.axis[0].front_porch = timing_info->h_front_porch; + dp_video_data.timing.axis[0].sync_rate = 0; + // Hsync polarity: 0->negative, 1->positive. + dp_video_data.timing.axis[0].sync_polarity = timing_info->neg_hsync ? 0 : 1; + dp_video_data.timing.axis[1].total = timing_info->v_active + timing_info->v_back_porch + + timing_info->v_front_porch + timing_info->v_pulse_width; + dp_video_data.timing.axis[1].active = timing_info->v_active; + dp_video_data.timing.axis[1].sync_width = timing_info->v_pulse_width; + dp_video_data.timing.axis[1].back_porch = timing_info->v_back_porch; + dp_video_data.timing.axis[1].front_porch = timing_info->v_front_porch; + dp_video_data.timing.axis[1].sync_rate = (60 << 16); + // Vsync polarity: 0->negative, 1->positive. + dp_video_data.timing.axis[1].sync_polarity = timing_info->neg_vsync ? 0 : 1; + + debug(INFO, "vTotal:%d hTotal:%d\n", dp_video_data.timing.axis[1].total, dp_video_data.timing.axis[0].total); + +#if WITH_HW_MCU + // Restrict EDID choices to timings matching these, otherwise the + // framebuffer dimensions will mismatch. + restrict_edid(dp_video_data.timing.axis[0].active, + dp_video_data.timing.axis[1].active); +#endif + + return 0; +} + +void displayport_quiesce() +{ + dp_controller_stop(); +} + +int displayport_start_video(void) +{ +#if WITH_HW_MCU && WITH_HW_HOOVER + int downstream_type = get_edid_downstream_type(); + if (downstream_type == kDPDownstreamTypeDVI) { + uint8_t data; + dp_controller_read_bytes_dpcd(DPCD_ADDR_HDMI_DVI_MODE_SELECT, &data, sizeof(data)); + data |= DPCD_ADDR_HDMI_DVI_MODE_SELECT_DVI; + debug(INFO, "Reprogramming Hoover to be in DVI mode: data 0x%x\n", data); + dp_controller_write_bytes_dpcd(DPCD_ADDR_HDMI_DVI_MODE_SELECT, &data, sizeof(data)); + } +#endif + return dp_controller_start_video(&dp_video_data); +} + +int displayport_enable_alpm(bool enable) +{ + return dp_controller_enable_alpm(enable, &dp_video_data); +} + +#if WITH_HW_DISPLAY_EDP +int displayport_get_raw_panel_id(u_int8_t *raw_panel_id) +{ + //caller is responsible for waiting for HPD + return dp_device_get_raw_panel_id(raw_panel_id); +} +#endif // WITH_HW_DISPLAY_EDP + +bool displayport_video_configured() +{ + return dp_controller_video_configured(); +} + +///////////////////////////////////////// +////////// controller global functions + +int dp_controller_train_link(struct dp_link_train_data *data) +{ + int ret; + u_int32_t lc; + u_int32_t lr; + u_int32_t retry = 0; + + ret = -1; + + lc = data->lane_count; + lr = data->link_rate; + + do { + + data->lane_count = __min((dp_controller_get_max_lane_count()), lc); + data->link_rate = __min((dp_controller_get_max_link_rate()), lr); + + do { + // check if the device has sufficient bandwidth + if ( data->lane_count < dp_controller_get_min_lane_count() ) { + ret = -1; + break; + } + + ret = run_link_training_state_machine(data); + + if ( ret != 0 ) { + if ( !data->fast ) { + data->link_rate = __min((dp_controller_get_max_link_rate()), lr); + data->lane_count = data->lane_count/2; + } else { + data->fast = false; + } + } + } while ( ret != 0 ); + + } while ( ret != 0 && ++retry < 5 ); + + return 0; +} + + +///////////////////////////////////////// +////////// controller local functions + +static int run_link_training_state_machine(struct dp_link_train_data *data) +{ + u_int32_t state = kLinkTrainingStateStart; + int ret; + + debug(TRAINING, "Preparing to establish new link\n"); + + // establish link training + do { + switch(state) { + case kLinkTrainingStateStart: + ret = process_link_state_start(data, &state); + break; + case kLinkTrainingStateClockRecovery: + ret = process_link_state_clock_recovery(data, &state); + break; + case kLinkTrainingStateEQTraining: + ret = process_link_state_eq_training(data, &state); + break; + default: + break; + } + + debug(TRAINING, "Performing Link training state=%d result=%d\n", state, ret); + + if ( ret != 0 ) + state = kLinkTrainingStateIdle; + + } while ( state != kLinkTrainingStateIdle ); + + debug(TRAINING, "Link training result=%d\n", ret); + + return ret; +} + +static int process_link_state_start(struct dp_link_train_data *data, u_int32_t *state) +{ + int ret; + u_int32_t index; +#if DISPLAYPORT_VERSION > 2 + eq_pattern = dp_device_get_supports_training_pattern3() ? kDPTrainingPattern3 : kDPTrainingPattern2; +#endif + + ret = -1; + + debug(TRAINING, "Begining START phase of link traing. Initial lanecount=%d linkRate=%u bps\n", + data->lane_count, data->link_rate); + + bzero(dp_link_clock_recovery_retry, sizeof(dp_link_clock_recovery_retry)); + bzero(dp_link_voltage_swing_max, sizeof(dp_link_voltage_swing_max)); + bzero(dp_link_eq_max, sizeof(dp_link_eq_max)); + dp_link_eq_retry = 0; + dp_link_clock_recovery_iterations = 0; + dp_link_eq_iterations = 0; + + // Set link rate and count as you want to establish + // set device + ret = dp_device_set_enhanced_mode(data->enhanced_mode); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device enhanced mode\n")); + + ret = dp_device_set_ASSR(data->assr); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device assr\n")); + + ret = dp_device_set_downspread(data->downspread); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device downspread\n")); + + ret = dp_device_set_link_rate(data->link_rate); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device link rate\n")); + + ret = dp_device_set_lane_count(data->lane_count); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device lane count\n")); + + // set controller + ret = dp_controller_set_link_rate(data->link_rate); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller link rate\n")); + + ret = dp_controller_set_enhanced_mode(data->enhanced_mode); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller enhanced mode\n")); + + ret = dp_controller_set_ASSR(data->assr); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller assr\n")); + + ret = dp_controller_set_downspread(data->downspread); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller downspread\n")); + + ret = dp_controller_set_lane_count(data->lane_count); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller lane count\n")); + + for ( index=0; indexlane_count; index++) { + ret = dp_controller_set_adjustment_levels(index, kDPVoltageLevelMin, kDPEQLevelMin, NULL, NULL); + if ( ret != 0 ) { + debug(ERROR, "Failed to set controller adjustment\n"); + goto exit; + } + + ret = dp_device_set_adjustment_levels(index, kDPVoltageLevelMin, kDPEQLevelMin, false, false); + if ( ret != 0 ) { + debug(ERROR, "Failed to set device adjustment\n"); + goto exit; + } + } + require_noerr_action(ret, exit, debug(ERROR, "Failed to adjustment levels\n")); + + ret = dp_controller_set_training_pattern(kDPTrainingPattern1, false); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller training pattern\n")); + + ret = dp_device_set_training_pattern(kDPTrainingPattern1, false); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device training pattern\n")); + + require(!data->fast, train_fast); + + *state = kLinkTrainingStateClockRecovery; + + return ret; + +train_fast: + debug(TRAINING, "Skipping to fast link training\n"); + + task_sleep(1 * 1000); + + ret = dp_controller_set_training_pattern(eq_pattern, false); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller training pattern\n")); + + ret = dp_device_set_training_pattern(eq_pattern, false); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device training pattern\n")); + + task_sleep(1 * 1000); + + ret = dp_controller_set_training_pattern(kDPTrainingPatternNone, true); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set controller training pattern\n")); + + ret = dp_device_set_training_pattern(kDPTrainingPatternNone, true); + require_noerr_action(ret, exit, debug(ERROR, "Failed to set device training pattern\n")); + +exit: + *state = kLinkTrainingStateIdle; + return ret; +} + +static int process_link_state_clock_recovery(struct dp_link_train_data *data, u_int32_t *state) +{ + uint32_t lane; + uint32_t alignment_status; + bool done = true; + bool succeed = true; + int ret = 0; + + spin(kClockRecoveryDelay); + + ret = dp_device_get_alignment_status_mask(&alignment_status); + require_noerr(ret, exit); + + for ( lane=0; lanelane_count; lane++ ) { + ret = process_link_state_clock_recovery_internal(data, lane, &done); + succeed &= ( ret == 0 ); + } + + if ( !done ) { + ret = dp_device_set_training_pattern(kDPTrainingPattern1, false); + require_noerr(ret, exit); + } + + if ( !succeed ) { + debug(TRAINING, "loop failed: linkRate=%u bps\n", data->link_rate); + // traing pattern : Set to Normal + ret = dp_controller_set_training_pattern(kDPTrainingPatternNone, true); + require_noerr(ret, exit); + ret = dp_device_set_training_pattern(kDPTrainingPatternNone, true); + require_noerr(ret, exit); + + // reduce bit rate + if ( (data->link_rate > dp_controller_get_min_link_rate()) && (data->link_rate == kLinkRate270Gbps) ) { + data->link_rate = kLinkRate162Gbps; + debug(TRAINING, "retry @ linkRate=%d\n", data->link_rate); + *state = kLinkTrainingStateStart; + } + // already in reduced bit-rate + else { + ret = -1; + } + } + else if ( done ) { + // set training pattern 2 for EQ + ret = dp_controller_set_training_pattern(eq_pattern, false); + require_noerr(ret, exit); + + // set the training pattern + ret = dp_device_set_training_pattern(eq_pattern, false); + require_noerr(ret, exit); + + *state = kLinkTrainingStateEQTraining; + } + +exit: + if (++dp_link_clock_recovery_iterations > kMaxClockRecoveryIterations) { + debug(TRAINING, "Max clock recovery iterations exceeded\n"); + ret = -1; + } + + return ret; +} + +static int process_link_state_clock_recovery_internal(struct dp_link_train_data * data, uint32_t lane, + bool *p_done) +{ + int ret = 0; + bool done = false; + uint32_t lane_status = 0; + uint32_t eq = kDPEQLevelMin; + uint32_t voltage_swing = kDPVoltageLevelMin; + uint32_t phy_eq; + uint32_t phy_voltage_swing; + + // might as well read the values for lane + ret = dp_device_get_lane_status_mask(lane, &lane_status); + require_noerr(ret, exit); + + debug(TRAINING, "Reading lane status: lane=%d status=0x%08x\n",lane, lane_status); + + require_action(!(lane_status & kDPLaneStatusFlagClockRecoveryDone), exit, done = true); + + ret = dp_device_get_requested_adjustment_levels(lane, &voltage_swing, &eq); + require_noerr(ret, exit); + ret = dp_controller_get_adjustment_levels(lane, &phy_voltage_swing, &phy_eq); + require_noerr(ret, exit); + + debug(TRAINING, "Reading lane adjust request: Lane%d: voltage=%d eq=%d\n",lane, voltage_swing, eq); + debug(TRAINING, "Current phy lane properties: Lane%d: voltage=%d eq=%d\n",lane, phy_voltage_swing, phy_eq); + + data->lane[lane].voltage = voltage_swing; + data->lane[lane].eq = eq; + + // lane same voltage count + if (phy_voltage_swing == voltage_swing) + dp_link_clock_recovery_retry[lane]++; + else + dp_link_clock_recovery_retry[lane] = 0; + + debug(TRAINING, "_linkClockRecoveryRetry[%d]=%d\n", lane, dp_link_clock_recovery_retry[lane]); + + require_action((dp_link_clock_recovery_retry[lane] < kMaxRetry) && !dp_link_voltage_swing_max[lane], + exit, ret=-1); + + // increase voltage swing as requested,write an updated value + debug(TRAINING, "Setting lane adjust request: Lane%d: voltage=%d eq=%d\n",lane, voltage_swing, eq); + // set voltage drive ONLY on the PHY + ret = dp_controller_set_adjustment_levels(lane, voltage_swing, eq, &dp_link_voltage_swing_max[lane], + &dp_link_eq_max[lane]); + require_noerr(ret, exit); + + // set voltage drive and EQ on the SINK + ret = dp_device_set_adjustment_levels(lane, voltage_swing, eq, dp_link_voltage_swing_max[lane], + dp_link_eq_max[lane]); + +exit: + *p_done &= done; + + return ret; +} + +static int process_link_state_eq_training(struct dp_link_train_data *data, u_int32_t *state) +{ + uint32_t lane; + uint32_t alignment_status; + bool done = true; + bool succeed = true; + bool abort = false; + bool clear = false; + bool reduce = false; + bool restart = false; + int ret = 0; + + debug(TRAINING, "Begining EQ phase of link traing\n"); + + spin(kEQDelay); + + dp_link_eq_retry++; + + ret = dp_device_get_alignment_status_mask(&alignment_status); + require_noerr(ret, exit); + + debug(TRAINING, "alignment_status=0x%08x\n", alignment_status); + + // process the eq state for each lane + for ( lane=0; lanelane_count; lane++ ) { + ret = process_link_state_eq_training_internal(data, lane, &done); + + if ( ret == 0 ) + continue; + + abort = (ret == -1); + succeed = false; + break; + } + + require(!abort, exit); + + done &= (alignment_status & kDPAlignmentStatusFlagsDone) != 0; + + // reapply the training pattern + // this does a bulk write + if ( !done ) { + ret = dp_device_set_training_pattern(eq_pattern, false); + require_noerr(ret, exit); + } + + if ( done ) { + debug(TRAINING, "Link trainking success @ %d lanes and %u Gbps\n", data->lane_count, + data->link_rate); + clear = true; + *state = kLinkTrainingStateIdle; + } else if ( !abort && (!succeed || dp_link_eq_retry > kMaxRetry) ) { + reduce = true; + } + + if ( reduce ) { + debug(TRAINING, "loop failed: laneCount=%d linkRate=%u Gbps\n", data->lane_count, data->link_rate); + clear = true; + // reduce bit rate and restart + if ( (data->link_rate > dp_controller_get_min_link_rate()) && (data->link_rate == kLinkRate270Gbps) ) { + data->link_rate = kLinkRate162Gbps; + debug(TRAINING, "retry @ linkRate=%d\n", data->link_rate); + restart = true; + } + // already in reduced bit-rate + else { + ret = -1; + } + } + + if ( restart ) { + *state = kLinkTrainingStateStart; + } + + if ( clear ) { + // traing pattern : Set to Normal + dp_controller_set_training_pattern(kDPTrainingPatternNone, true); + dp_device_set_training_pattern(kDPTrainingPatternNone, true); + } + +exit: + return ret; +} + +static int process_link_state_eq_training_internal(struct dp_link_train_data *data, uint32_t lane, bool *p_done) +{ + int ret = 0; + bool done = false; + uint32_t lane_status = 0; + uint32_t eq; + uint32_t voltage_swing; + uint32_t phy_eq; + uint32_t phy_voltage_swing; + + // might as well read the values for lane + ret = dp_device_get_lane_status_mask(lane, &lane_status); + require_noerr(ret, exit); + + debug(TRAINING, "Reading lane status: lane=%d lane_status=0x%08x\n",lane, lane_status); + + require_action(lane_status & kDPLaneStatusFlagClockRecoveryDone, exit, ret = -1); + + done = (lane_status & (kDPLaneStatusFlagsEQDone|kDPLaneStatusFlagsSymbolLocked))==(kDPLaneStatusFlagsEQDone|kDPLaneStatusFlagsSymbolLocked); + require(!done, exit); + + ret = dp_device_get_requested_adjustment_levels(lane, &voltage_swing, &eq); + require_noerr(ret, exit); + + ret = dp_controller_get_adjustment_levels(lane, &phy_voltage_swing, &phy_eq); + require_noerr(ret, exit); + + debug(TRAINING, "Reading lane adjust request: Lane%d: voltage=%d eq=%d\n",lane, voltage_swing, eq); + debug(TRAINING, "Current phy lane properties: Lane%d: voltage=%d eq=%d\n",lane, phy_voltage_swing, phy_eq); + + data->lane[lane].voltage = voltage_swing; + data->lane[lane].eq = eq; + + // set voltage drive and EQ on the PHY + ret = dp_controller_set_adjustment_levels(lane, voltage_swing, eq, + &dp_link_voltage_swing_max[lane], &dp_link_eq_max[lane]); + require_noerr(ret, exit); + + // set voltage drive and EQ on the SINK + ret = dp_device_set_adjustment_levels(lane, voltage_swing, eq, + dp_link_voltage_swing_max[lane], dp_link_eq_max[lane]); + +exit: + *p_done &= done; + + return ret; +} diff --git a/drivers/displayport/debug.c b/drivers/displayport/debug.c new file mode 100644 index 0000000..65c7e6b --- /dev/null +++ b/drivers/displayport/debug.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +static struct video_link_data dp_video_data; + +int do_dp(int argc, struct cmd_arg *args) +{ + if (argc < 2) { + puts("not enough arguments.\n"); + goto usage; + } + + if (strcmp("start", args[1].str) == 0) { + static struct display_timing timing_list[] = + { +#if SUB_TARGET_J1 || SUB_TARGET_J2 || SUB_TARGET_J2A + { "ipad3", 0, 252200000, 264, 2048, 5, 150, 5, 1536, 9, 3, 1, 0, 0, 0, 0, 24, DISPLAY_TYPE_EDP, NULL }, +#endif +#if WITH_HW_DISPLAY_DISPLAYPORT + { "720p", 0, 00000000, 243, 1280, 220, 110, 40, 720, 20, 5, 5, 0, 0, 0, 0, 24, DISPLAY_TYPE_DP, NULL }, +#endif + }; +#if SUB_TARGET_J1 || SUB_TARGET_J2 || SUB_TARGET_J2A + dp_t dp = { + .mode = 0x1, + .type = 0x1, + .min_link_rate = 0x6, + .max_link_rate = 0x6, + .lanes = 0x4, + .ssc = 0x0, + .alpm = 0x0, + .vrr_enable = 0x0, + .vrr_on = 0x0, + }; +#elif WITH_HW_DISPLAY_DISPLAYPORT + dp_t dp = { + .mode = 0x1, + .type = 0x1, + .min_link_rate = 0x6, + .max_link_rate = 0x6, + .lanes = 0x2, + .ssc = 0x0, + .alpm = 0x0, + .vrr_enable = 0x0, + }; +#else + dp_t dp; +#endif + timing_list[0].display_config = (void *)&dp; + + displayport_init(&dp); + + bzero(&dp_video_data, sizeof(struct video_link_data)); + + dp_video_data.mirror_mode = false; + dp_video_data.test_mode = 0; + dp_video_data.color.depth = 8; + dp_video_data.color.space = kDisplayColorSpacesRGB; + dp_video_data.color.range = kDisplayColorDynamicRangeVESA; + dp_video_data.color.coefficient = kDisplayColorCoefficientITU601; + dp_video_data.timing.axis[0].total = timing_list[0].h_active + timing_list[0].h_back_porch + timing_list[0].h_front_porch + timing_list[0].h_pulse_width; + dp_video_data.timing.axis[0].active = timing_list[0].h_active; + dp_video_data.timing.axis[0].sync_width = timing_list[0].h_pulse_width; + dp_video_data.timing.axis[0].back_porch = timing_list[0].h_back_porch; + dp_video_data.timing.axis[0].front_porch = timing_list[0].h_front_porch; + dp_video_data.timing.axis[0].sync_rate = 0; + dp_video_data.timing.axis[0].sync_polarity = 0; + dp_video_data.timing.axis[1].total = timing_list[0].v_active + timing_list[0].v_back_porch + timing_list[0].v_front_porch + timing_list[0].v_pulse_width; + dp_video_data.timing.axis[1].active = timing_list[0].v_active; + dp_video_data.timing.axis[1].sync_width = timing_list[0].v_pulse_width; + dp_video_data.timing.axis[1].back_porch = timing_list[0].v_back_porch; + dp_video_data.timing.axis[1].front_porch = timing_list[0].v_front_porch; + dp_video_data.timing.axis[1].sync_rate = 60 << 16; + dp_video_data.timing.axis[1].sync_polarity = 0; + + } else if (strcmp("stop", args[1].str) == 0) { + displayport_quiesce(); + } else if (strcmp("video", args[1].str) == 0) { + if (strcmp("logo", args[2].str) == 0) { + dp_video_data.mirror_mode = false; + dp_video_data.test_mode = 0; + + dp_controller_start_video(&dp_video_data); + } + if (strcmp("bist", args[2].str) == 0) { + + dp_video_data.mirror_mode = false; + dp_video_data.test_mode = 1; + + dp_controller_start_video(&dp_video_data); + } + if (strcmp("mirror", args[2].str) == 0) { + dp_video_data.mirror_mode = true; + dp_video_data.test_mode = 0; + + dp_controller_start_video(&dp_video_data); + } + } else if (strcmp("dpcd", args[1].str) == 0) { + uint8_t data[16]; + int len = args[3].n; + uint32_t intr = 0; + + if (len > 16) + len = 16; + + printf("dpcd read %d bytes from 0x%x\n", len, args[2].n); +#if WITH_HW_DISPLAY_DISPLAYPORT + intr = INT_DPORT0; +#elif WITH_HW_DISPLAY_EDP + intr = INT_EDP0; +#endif + //cuz AppleTV only defines display in iBoot but declares drivers in iBEC + if (intr) mask_int(intr); + dp_controller_read_bytes_dpcd(args[2].n, data, len); + if (intr) unmask_int(intr); + + for (int i=0; i < len; i++) { + printf("0x%02x ", data[i]); + } + printf("\n"); + } else { + puts("unrecognized command.\n"); + goto usage; + } + + return 0; + +usage: + printf("%s start\n", args[0].str); + printf("%s video logo\n", args[0].str); + printf("%s video bist\n", args[0].str); + printf("%s video mirror\n", args[0].str); + printf("%s stop\n", args[0].str); + printf("%s dpcd . Len is max 16 bytes\n", args[0].str); + + return -1; +} + +MENU_COMMAND_DEVELOPMENT(dp, do_dp, "displayport stuff", NULL); + +#endif diff --git a/drivers/displayport/device.c b/drivers/displayport/device.c new file mode 100644 index 0000000..3a19648 --- /dev/null +++ b/drivers/displayport/device.c @@ -0,0 +1,810 @@ +/* + * Copyright (C) 2010-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include + +#include +#include +#include +#include "dpcd.h" + +#if WITH_HW_MCU +#include +#include +#endif + + +///////////////////////////////////////// +////////// debug support + +#define DP_DEBUG_MASK ( \ + DP_DEBUG_INIT | \ + DP_DEBUG_ERROR | \ + DP_DEBUG_INFO | \ + DP_DEBUG_TRAINING | \ + 0) + +#undef DP_DEBUG_MASK +#define DP_DEBUG_MASK (DP_DEBUG_INIT | DP_DEBUG_ERROR) + +#define DP_DEBUG_INIT (1<<16) // initialisation +#define DP_DEBUG_INFO (1<<17) // info +#define DP_DEBUG_TRAINING (1<<18) // link training +#define DP_DEBUG_WAIT (1<<19) // start wait +#define DP_DEBUG_ERROR (1<<20) // error +#define DP_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((DP_DEBUG_ ## _fac) & (DP_DEBUG_MASK | DP_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "DPD: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +///////////////////////////////////////// +////////// consts + +#define kDPDeviceMaxCapabilityBytes 0x0c +#define kDPDeviceMaxDownstreamPorts 16 +#define kEDPRawPanelIdReadTimeout (1 * 1000 * 1000) + +///////////////////////////////////////// +////////// typedefs, enums, structs + +#define require_action(assertion, exception_label, action) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr(error_code, exception_label) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +///////////////////////////////////////// +////////// local variables + +static uint8_t dp_device_downstream_port_capability_bytes[kDPDeviceMaxDownstreamPorts]; +static uint8_t dp_device_capability_bytes[kDPDeviceMaxCapabilityBytes]; +static u_int32_t dp_device_voltage_adjustment_level[kDPMaxLanes]; +static u_int32_t dp_device_eq_adjustment_level[kDPMaxLanes]; +static uint8_t dp_device_adjustment_bytes[5]; +static uint8_t dp_device_lane_status_mask[kDPMaxLanes]; +static bool alpm_enabled; +#if WITH_HW_DISPLAY_EDP +static u_int8_t dp_device_raw_panel_id[kEDPRawPanelIdLength]; +#endif // WITH_HW_DISPLAY_EDP + +///////////////////////////////////////// +////////// local functions declaration + +static int set_power(bool enable); +static int train_link(); +static int enable_alpm(bool enable); +static int cache_capabilities(); +static int update_lane_status_mask(); +static int update_requested_adjustment_levels(); +static int read_raw_panel_id(); + +static struct task_event dp_device_start_event = + EVENT_STATIC_INIT(dp_device_start_event, false, EVENT_FLAG_AUTO_UNSIGNAL); +static bool dp_device_started; +static bool dp_device_start_error; +static utime_t dp_device_started_time; +static struct task_event dp_device_raw_panel_id_ready_event; + +extern utime_t gPowerOnTime; + +///////////////////////////////////////// +////////// dp-device global functions + +int dp_device_start(bool edp_panel) +{ + int ret = -1; + + if ( dp_device_started ) + return 0; + + debug(INIT, "starting\n"); + + event_init(&dp_device_raw_panel_id_ready_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + if ( set_power(true) != 0 ) { + debug(ERROR, "failed to set power\n"); + goto exit; + } + + if ( cache_capabilities() != 0 ) { + debug(ERROR, "failed to cache capabilities\n"); + goto exit; + } + +#if WITH_HW_DISPLAY_EDP + if ( edp_panel ) { + if ( read_raw_panel_id() != 0 ) { + debug(ERROR, "failed to read raw panel id\n"); + goto exit; + } else { + debug(INFO, "successfully read panel id: "); + for ( unsigned i=0; i= timeout) { + debug(WAIT, "Timeout waiting for displayport start\n"); + return -1; + } + event_wait_timeout(&dp_device_start_event, timeout - now); + } + debug(WAIT, "Delayed boot by %lld usecs\n", system_time() - wait_start); + exit: + debug(WAIT, "Started waiting %lld usecs after power on\n", + wait_start - gPowerOnTime); + return dp_device_start_error ? -1 : 0; +} + +void dp_device_stop() +{ + if ( !dp_device_started ) + return; + + set_power(false); + + dp_device_started = false; + alpm_enabled = false; +} + +bool dp_device_is_alpm_enabled() +{ + return alpm_enabled; +} + +#if WITH_HW_DISPLAY_EDP +int dp_device_get_raw_panel_id(u_int8_t *raw_panel_id) +{ + if (event_wait_timeout(&dp_device_raw_panel_id_ready_event, kEDPRawPanelIdReadTimeout) == false) + return -1; + + if (raw_panel_id == NULL) + return -1; + + memset(raw_panel_id, 0, kEDPRawPanelIdLength); + + memcpy(raw_panel_id, dp_device_raw_panel_id, kEDPRawPanelIdLength); + + return 0; +} +#endif // WITH_HW_DISPLAY_EDP + +int dp_device_get_alignment_status_mask(u_int32_t *mask) +{ + int ret; + uint8_t value; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &value, 1); + + update_lane_status_mask(); + update_requested_adjustment_levels(); + + if ( mask ) + *mask = value; + + return ret; +} + +int dp_device_get_lane_status_mask(uint32_t lane, uint32_t *mask) +{ + if ( lane > dp_device_get_max_lane_count() ) + return -1; + + *mask = dp_device_lane_status_mask[lane]; + + return 0; +} + +int dp_device_get_training_pattern(uint32_t *value, bool *scramble) +{ + int ret = 0; + uint8_t val; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_TRAINING_PATTERN_SET, &val, 1); + if ( ret == 0 ) { + if ( value ) + *value = (u_int32_t)(val & DPCD_ADDR_PATTERN_SET_MASK); + if ( scramble ) + *scramble = (val & DPCD_ADDR_TRAINING_PATTERN_SET_SCRMB_DISABLE) == 0; + } + + return ret; +} + +int dp_device_set_training_pattern(uint32_t value, bool scramble) +{ + uint8_t reg_val = value & DPCD_ADDR_PATTERN_SET_MASK; + + if ( !scramble ) + reg_val |= DPCD_ADDR_TRAINING_PATTERN_SET_SCRMB_DISABLE; + + dp_device_adjustment_bytes[0] = reg_val; + + return dp_controller_write_bytes_dpcd(DPCD_ADDR_TRAINING_PATTERN_SET, dp_device_adjustment_bytes, 5); +} + +int dp_device_get_requested_adjustment_levels(uint32_t lane, u_int32_t *voltage, u_int32_t *eq) +{ + if ( lane > dp_device_get_max_lane_count() ) + return -1; + + *voltage = dp_device_voltage_adjustment_level[lane]; + *eq = dp_device_eq_adjustment_level[lane]; + + return 0; +} + +int dp_device_set_adjustment_levels(uint32_t lane, u_int32_t voltage_swing, u_int32_t eq, + bool voltage_max_reached, bool eq_max_reached) +{ + uint8_t value; + + if ( lane > dp_device_get_max_lane_count() ) + return -1; + + value = (eq << DPCD_ADDR_TRAINNIG_SET_PRE_EMPH_SHIFT) | + (voltage_swing << DPCD_ADDR_TRAINNIG_SET_VOL_SWING_SHIFT); + + if (voltage_max_reached) { + value |= DPCD_ADDR_TRAINNIG_SET_VOL_SWING_MAX; + } + + if ( eq_max_reached ) { + value |= DPCD_ADDR_TRAINNIG_SET_PRE_EMPH_MAX; + } + + dp_device_adjustment_bytes[lane+1] = value; + + return 0; +} + +int dp_device_get_enhanced_mode(bool * value) +{ + int ret = 0; + uint8_t val = 0; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_LANE_COUNT_SET, &val, 1); + if ( ret == 0 ) { + *value = val & DPCD_ADDR_LANE_COUNT_SET_ENHANCED; + } + + return ret; +} + +int dp_device_get_sink_count(uint8_t * value) +{ + int ret = 0; + uint8_t val = 0; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_SINK_COUNT, &val, 1); + if ( ret == 0 ) { + *value = val; + } + + return ret; +} + +int dp_device_set_enhanced_mode(bool value) +{ + uint32_t lane_count = 0; + + dp_device_get_lane_count(&lane_count); + lane_count &= DPCD_ADDR_LANE_COUNT_SET_COUNT_MASK; + + if ( value ) + lane_count |= DPCD_ADDR_LANE_COUNT_SET_ENHANCED; + + return dp_controller_write_bytes_dpcd(DPCD_ADDR_LANE_COUNT_SET, (uint8_t *)&lane_count, 1); +} + +int dp_device_get_ASSR(bool * value) +{ + int ret = 0; + uint8_t val = 0; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_RECEIVER_EDP_CONFIG, &val, 1); + if ( ret == 0 ) { + *value = val & DPCD_ADDR_RECEIVER_EDP_CONFIG_ASSR_ENABLE; + } + + return ret; +} + +int dp_device_set_ASSR(bool value) +{ + uint8_t val = 0; + + if ( value ) + val |= DPCD_ADDR_RECEIVER_EDP_CONFIG_ASSR_ENABLE; + + return dp_controller_write_bytes_dpcd(DPCD_ADDR_RECEIVER_EDP_CONFIG, (uint8_t *)&val, 1); +} + +int dp_device_get_downspread(bool * value) +{ + int ret = 0; + uint8_t val = 0; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_DOWNSPREAD_CTRL, &val, 1); + if ( ret == 0 ) { + *value = val & DPCD_ADDR_DOWNSPREAD_ENABLE; + } + + return ret; +} + +int dp_device_set_downspread(bool value) +{ + uint8_t reg_val = 0; + + reg_val = value ? DPCD_ADDR_DOWNSPREAD_ENABLE : 0; + + return dp_controller_write_bytes_dpcd(DPCD_ADDR_DOWNSPREAD_CTRL, (uint8_t *)®_val, 1); +} + +int dp_device_get_lane_count(uint32_t * value) +{ + int ret = 0; + uint8_t val; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_LANE_COUNT_SET, &val, 1); + if ( ret == 0 ) { + *value = val & DPCD_ADDR_LANE_COUNT_SET_COUNT_MASK; + } + + return ret; +} + +int dp_device_set_lane_count(uint32_t value) +{ + bool enhanced_mode = false; + + value &= DPCD_ADDR_LANE_COUNT_SET_COUNT_MASK; + + dp_device_get_enhanced_mode(&enhanced_mode); + if ( enhanced_mode ) + value |= DPCD_ADDR_LANE_COUNT_SET_ENHANCED; + + return dp_controller_write_bytes_dpcd(DPCD_ADDR_LANE_COUNT_SET, (uint8_t *)&value, 1); +} + +int dp_device_get_link_rate(u_int32_t * value) +{ + return dp_controller_read_bytes_dpcd(DPCD_ADDR_LINK_BW_SET, (uint8_t*)value, 1); +} + +int dp_device_set_link_rate(u_int32_t value) +{ + return dp_controller_write_bytes_dpcd(DPCD_ADDR_LINK_BW_SET, (uint8_t *)&value, 1); +} + +int dp_device_hdcp_enable(bool enable) +{ +#if WITH_HW_HOOVER + uint8_t value; + dp_controller_read_bytes_dpcd(DPCD_ADDR_HDMI_DVI_MODE_SELECT, &value, 1); + + if (!enable) value |= DPCD_HDCP_DISABLE; + + return dp_controller_write_bytes_dpcd(DPCD_ADDR_HDMI_DVI_MODE_SELECT, &value, 1); +#else + return 0; +#endif +} + +int dp_device_get_downstream_port_type(int *ret_value) +{ +#if WITH_HW_MCU + // BlueSteel is reporting DP, but we know for sure it's HDMI. + if (ret_value) *ret_value = kDPDownstreamTypeHDMI; + return 0; +#else + int ret = 0; + int value = kDPDownstreamTypeOther; + if (dp_device_get_revision() == 0x11) { + value = dp_device_downstream_port_capability_bytes[0] & 0x07; + } + + if (value == kDPDownstreamTypeDP) { + uint8_t reg_val; + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_DOWNSTREAMPORT_PRESENT, ®_val, 1); + if (ret != 0) goto exit; + + switch (((reg_val >> 1 ) & 3)) { + case 0: + value = kDPDownstreamTypeDP; + break; + case 1: + value = kDPDownstreamTypeVGA; + break; + case 2: + value = kDPDownstreamTypeHDMI; + break; + case 3: + value = kDPDownstreamTypeOther; + break; + } + } + + exit: + if (ret_value) *ret_value = value; + return ret; +#endif +} + +int dp_device_enable_alpm(bool enable) +{ + uint8_t alpm_data = enable; + return dp_controller_write_bytes_dpcd(DPCD_ADDR_ALPM_CTRL, &alpm_data, 1); +} + +///////////////////////////////////////// +////////// dp-device local functions + +static int set_power(bool state) +{ + int ret; + u_int8_t byte; + bool current_state; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_SINK_POWER_STATE, &byte, 1); + debug(INFO, "Read sink power state: ret=%d\n", ret); + require_noerr(ret, exit); + + current_state = (byte == DPCD_ADDR_SINK_POWER_STATE_ON); + + require_action(state != current_state, exit, debug(INFO, "power level already = %d\n", state)); + + debug(INFO, "setting power level = %d\n", state); + + byte = state ? DPCD_ADDR_SINK_POWER_STATE_ON : DPCD_ADDR_SINK_POWER_STATE_OFF; + ret = dp_controller_write_bytes_dpcd(DPCD_ADDR_SINK_POWER_STATE, &byte, 1); + + // see DportV1.1a section 5.2.5 + if ( state ) + task_sleep(20 * 1000); + +exit: + return ret; +} + +static int cache_capabilities() +{ + int ret; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_DPCD_REV, dp_device_capability_bytes, + (uint32_t)sizeof(dp_device_capability_bytes)); + if ( ret != 0 ) { + debug(ERROR, "failed to read capabilities\n"); + return -1; + } + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_DOWNSTREAMPORT_0_CAPS, + dp_device_downstream_port_capability_bytes, + (uint32_t)sizeof(dp_device_downstream_port_capability_bytes)); + if ( ret != 0 ) { + debug(ERROR, "failed to read downstream ports capabilities\n"); + return -1; + } + + return 0; +} + +#if WITH_HW_DISPLAY_EDP +static int read_raw_panel_id() +{ + int ret; + + ret = dp_controller_read_bytes_dpcd(DPCP_ADDR_VENDOR_BYTES, dp_device_raw_panel_id, kEDPRawPanelIdLength); + if (ret != 0) { + debug(ERROR, "failed to read raw panel id\n"); + return -1; + } + + return 0; +} +#endif // WITH_HW_DISPLAY_EDP + +u_int32_t dp_device_get_revision() +{ + return dp_device_capability_bytes[DPCD_ADDR_DPCD_REV]; +} + +u_int32_t dp_device_get_max_lane_count() +{ + return dp_device_capability_bytes[DPCD_ADDR_MAX_LANE_COUNT] & DPCD_ADDR_LANE_COUNT_SET_COUNT_MASK; +} + +u_int32_t dp_device_get_max_link_rate() +{ + return dp_device_capability_bytes[DPCD_ADDR_MAX_LINK_RATE]; +} + +bool dp_device_get_supports_enhanced_mode() +{ + if ( dp_device_get_revision() < 0x11 ) + return false; + + return dp_device_capability_bytes[DPCD_ADDR_MAX_LANE_COUNT] & DPCD_ADDR_LANE_COUNT_SET_ENHANCED; +} + +bool dp_device_get_supports_training_pattern3() +{ + if ( dp_device_get_revision() < 0x12 ) + return false; + + return dp_device_capability_bytes[DPCD_ADDR_MAX_LANE_COUNT] & DPCD_ADDR_LANE_COUNT_TPS3_SUPPORTED; +} + +bool dp_device_get_supports_fast_link_training() +{ + int ret; + uint8_t value = 0; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_MAX_DOWNSPREAD, &value, 1); + require_noerr(ret, exit); + +exit: +#if WITH_HW_HOOVER + return (false); +#else + return (value & (1<<6) ? true : false); +#endif +} + +bool dp_device_get_supports_alpm() +{ + int ret; + uint8_t value = 0; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_ALPM_CAP, &value, 1); + require_noerr(ret, exit); + +exit: + return (value & 1 ? true : false); +} + +bool dp_device_get_supports_assr() +{ + int ret; + uint8_t value = 0; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_ALTERNATE_SCRAMBLE, &value, 1); + require_noerr(ret, exit); + +exit: + return (value & DPCD_ADDR_ALTERNATE_SCRAMBLER_RESET_CAP ? true : false); +} + +bool dp_device_get_supports_downspread() +{ + int ret; + uint8_t value = 0; + + if ( dp_device_get_revision() >= 0x11 ) + return true; + + ret = dp_controller_read_bytes_dpcd(DPCD_ADDR_MAX_DOWNSPREAD, &value, 1); + require_noerr(ret, exit); + +exit: + return (value & (1<<0) ? true : false); +} + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) + +static int train_link() +{ + struct dp_link_train_data data; + int ret; + uint8_t ignore[8]; + + bzero(&data, sizeof(struct dp_link_train_data)); + + // collect data needed for link training + data.lane_count = dp_device_get_max_lane_count(); + data.link_rate = dp_device_get_max_link_rate(); + data.enhanced_mode = dp_device_get_supports_enhanced_mode(); + data.assr = dp_device_get_supports_assr(); + data.fast = dp_device_get_supports_fast_link_training() && dp_controller_get_supports_fast_link_training(); + data.downspread = min(dp_device_get_supports_downspread(),dp_controller_get_supports_downspread()); + + debug(INIT, "lane_count: %d, link_rate: %d, enhanced_mode: %d, assr: %d, fast: %d downspread: %d\n", + data.lane_count, data.link_rate, data.enhanced_mode, data.assr, data.fast, data.downspread); + + if ( !data.lane_count || !data.link_rate ) { + return -1; + } + + ret = dp_controller_train_link(&data); + if ( ret != 0 ) + return -1; + + // clear error bits + dp_controller_read_bytes_dpcd(DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE0_BYTE0, ignore, sizeof(ignore)); + + return 0; +} + +static int enable_alpm(bool enable) +{ + bool supports_alpm; + int ret = 0; + + supports_alpm = dp_device_get_supports_alpm() && dp_controller_get_supports_alpm(); + + printf("supports_alpm %d\n", supports_alpm); + if (supports_alpm) { + ret = dp_device_enable_alpm(enable); + if (ret != 0) { + debug(ERROR, "Failed to %s device alpm\n", enable ? "enable" : "disable"); + return ret; + } + + ret = displayport_enable_alpm(enable); + if (ret != 0) { + debug(ERROR, "Failed to %s controller alpm\n", enable ? "enable" : "disable"); + } + alpm_enabled =true; + } + + + return ret; +} + +static int update_lane_status_mask() +{ + int ret = 0; + uint8_t value, lane; + + for (lane=0; lane>1), &value, 1); + + if ( ret != 0 ) + break; + + if ( lane % 2 ) + dp_device_lane_status_mask[lane] = (value >> DPCD_ADDR_LANEX_Y_STATUS_Y_SHIFT) & + kDPLaneStatusFlagsMask; + else + dp_device_lane_status_mask[lane] = (value >> DPCD_ADDR_LANEX_Y_STATUS_X_SHIFT) & + kDPLaneStatusFlagsMask; + } + + return ret; +} + +static int update_requested_adjustment_levels() +{ + int ret; + uint8_t value, lane; + + ret = 0; + + for (lane=0; lane>1), &value, 1); + + if ( ret != 0 ) + break; + + if ( lane % 2 ) { + dp_device_eq_adjustment_level[lane] = ((value & DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_Y_MASK) >> DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_Y_SHIFT); + dp_device_voltage_adjustment_level[lane] = ((value & DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_Y_MASK) >> DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_Y_SHIFT); + } + else { + dp_device_eq_adjustment_level[lane] = ((value & DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_X_MASK) >> DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_X_SHIFT); + dp_device_voltage_adjustment_level[lane] = ((value & DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_X_MASK) >> DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_X_SHIFT); + } + } + + return ret; +} diff --git a/drivers/displayport/dpcd.h b/drivers/displayport/dpcd.h new file mode 100644 index 0000000..73949e1 --- /dev/null +++ b/drivers/displayport/dpcd.h @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define DPCD_ADDR_DPCD_REV 0x00000 +#define DPCD_ADDR_DPCD_REV_MAJOR_SHIFT 4 +#define DPCD_ADDR_DPCD_REV_MAJOR_MASK (0xf << DPCD_ADDR_DPCD_REV_MAJOR_SHIFT) +#define DPCD_ADDR_DPCD_REV_MINOR_SHIFT 0 +#define DPCD_ADDR_DPCD_REV_MINOR_MASK (0xf << DPCD_ADDR_DPCD_REV_MINOR_SHIFT) + +#define DPCD_ADDR_MAX_LINK_RATE 0x00001 +#define DPCD_ADDR_MAX_LANE_COUNT 0x00002 +#define DPCD_ADDR_MAX_DOWNSPREAD 0x00003 +#define DPCD_ADDR_NORP 0x00004 +#define DPCD_ADDR_DOWNSTREAMPORT_PRESENT 0x00005 + +#define DPCD_ADDR_RECEIVE_PORT0_CAP_0 0x00008 +#define DPCD_ADDR_RECEIVE_PORT0_CAP_0_EDID (1 << 1) + +#define DPCD_ADDR_DOWNSTREAMPORT_COUNT 0x00007 +#define DPCD_ADDR_RECEIVE_PORT0_CAP_1 0x00009 +#define DPCD_ADDR_RECEIVE_PORT0_CAP_2 0x0000a +#define DPCD_ADDR_RECEIVE_PORT0_CAP_3 0x0000b + +#define DPCD_ADDR_ALTERNATE_SCRAMBLE 0x0000d +#define DPCD_ADDR_ALTERNATE_SCRAMBLER_RESET_CAP (1 << 0) +#define DPCD_ADDR_FRAMING_CHANGE_CAP (1 << 1) +#define DPCD_ADDR_INVERTED_TRAINING_BIT_CAP (1 << 2) + +#define DPCD_ADDR_DOWNSTREAMPORT_0_CAPS 0x00080 +#define DPCD_ADDR_ALPM_CAP 0x0002e + + +#define DPCD_ADDR_LINK_BW_SET 0x00100 + +#define DPCD_ADDR_LANE_COUNT_SET 0x00101 +#define DPCD_ADDR_LANE_COUNT_SET_ENHANCED (1 << 7) +#define DPCD_ADDR_LANE_COUNT_SET_COUNT_MASK (0x1f) +#define DPCD_ADDR_LANE_COUNT_TPS3_SUPPORTED (1 << 6) + +#define DPCD_ADDR_TRAINING_PATTERN_SET 0x00102 +#define DPCD_ADDR_PATTERN_SET_MASK 0x3 +#define DPCD_ADDR_QUALITY_PATTERN_SHIFT 2 +#define DPCD_ADDR_TRAINING_PATTERN_SET_SCRMB_DISABLE (1 << 5) + +#define DPCD_ADDR_TRAINNIG_LANE0_SET 0x00103 +#define DPCD_ADDR_TRAINNIG_LANE1_SET 0x00104 +#define DPCD_ADDR_TRAINNIG_LANE2_SET 0x00105 +#define DPCD_ADDR_TRAINNIG_LANE3_SET 0x00106 +#define DPCD_ADDR_TRAINNIG_SET_VOL_SWING_SHIFT 0 +#define DPCD_ADDR_TRAINNIG_SET_VOL_SWING_MASK (0x3 << DPCD_ADDR_TRAINNIG_SET_VOL_SWING_SHIFT) +#define DPCD_ADDR_TRAINNIG_SET_VOL_SWING_MAX (0x1 << 2) +#define DPCD_ADDR_TRAINNIG_SET_PRE_EMPH_SHIFT 3 +#define DPCD_ADDR_TRAINNIG_SET_PRE_EMPH_MASK (0x3 << DPCD_ADDR_TRAINNIG_SET_PRE_EMPH_SHIFT) +#define DPCD_ADDR_TRAINNIG_SET_PRE_EMPH_MAX (0x1 << 5) + +#define DPCD_ADDR_DOWNSPREAD_CTRL 0x00107 +#define DPCD_ADDR_DOWNSPREAD_ENABLE (1 << 4) + +// eDP (DPCD 1.2) +#define DPCD_ADDR_RECEIVER_EDP_CONFIG 0x0010a +#define DPCD_ADDR_RECEIVER_EDP_CONFIG_ASSR_ENABLE (1<<0) + +#define DPCD_ADDR_ALPM_CTRL 0x00116 +#define DPCD_ADDR_ALPM_ENABLE (1 << 0) +#define DPCD_ADDR_ALPM_ALPM_LOCK_ERROR_IRQ_HPD (1 << 1) + +#define DPCD_ADDR_SINK_COUNT 0x00200 + +#define DPCD_ADDR_DEVICE_SERVICE_IRQ_VECTOR 0x00201 +#define DPCD_IRQ_VECTOR_REMOTE_COMMAND (1 << 0) +#define DPCD_IRQ_VECTOR_AUTOMATED_TEST (1 << 1) +#define DPCD_IRQ_VECTOR_CP_IRQ (1 << 2) +#define DPCD_IRQ_VECTOR_SINK_SPECIFIC (1 << 6) + +#define DPCD_ADDR_LANE0_1_STATUS 0x00202 +#define DPCD_ADDR_LANE2_3_STATUS 0x00203 +#define DPCD_ADDR_LANEX_Y_STATUS_X_SHIFT (0) +#define DPCD_ADDR_LANEX_Y_STATUS_Y_SHIFT (4) + +#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x00204 +#define DPCD_ADDR_SINK_STATUS 0x00205 +#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x00206 +#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x00207 + +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_X_SHIFT 0 +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_X_MASK (0x3 << DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_X_SHIFT) + +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_X_SHIFT 2 +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_X_MASK (0x3 << DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_X_SHIFT) + +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_Y_SHIFT 4 +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_Y_MASK (0x3 << DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_VOL_SWG_Y_SHIFT) + +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_Y_SHIFT 6 +#define DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_Y_MASK (0x3 << DPCD_ADDR_ADJUST_REQUEST_LANEX_Y_PRE_EMP_Y_SHIFT) + +#define DPCD_ADDR_TRAINING_SCORE_LANE0 0x00208 +#define DPCD_ADDR_TRAINING_SCORE_LANE1 0x00209 +#define DPCD_ADDR_TRAINING_SCORE_LANE2 0x0020a +#define DPCD_ADDR_TRAINING_SCORE_LANE3 0x0020b + +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE0_BYTE0 0x00210 +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE0_BYTE1 0x00211 +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE1_BYTE0 0x00212 +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE1_BYTE1 0x00213 +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE2_BYTE0 0x00214 +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE2_BYTE1 0x00215 +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE3_BYTE0 0x00216 +#define DPCD_ADDR_SYMBOL_ERROR_COUNT_LANE3_BYTE1 0x00217 + +#define DPCD_ADDR_TEST_REQUEST 0x00218 +#define DPCD_ADDR_TEST_REQUEST_LINK (1 << 0) +#define DPCD_ADDR_TEST_REQUEST_PATTERN (1 << 1) +#define DPCD_ADDR_TEST_REQUEST_EDID (1 << 2) +#define DPCD_ADDR_TEST_REQUEST_PHY (1 << 3) + +#define DPCD_ADDR_TEST_LINK_RATE 0x00219 +#define DPCD_ADDR_TEST_LANE_COUNT 0x00220 +#define DPCD_ADDR_TEST_PATTERN 0x00221 + +#define DPCD_ADDR_TEST_H_TOTAL_H 0x00222 +#define DPCD_ADDR_TEST_H_TOTAL_L 0x00223 +#define DPCD_ADDR_TEST_V_TOTAL_H 0x00224 +#define DPCD_ADDR_TEST_V_TOTAL_L 0x00225 +#define DPCD_ADDR_TEST_H_START_H 0x00226 +#define DPCD_ADDR_TEST_H_START_L 0x00227 +#define DPCD_ADDR_TEST_V_START_H 0x00228 +#define DPCD_ADDR_TEST_V_START_L 0x00229 +#define DPCD_ADDR_TEST_HSYNC_H 0x0022a +#define DPCD_ADDR_TEST_HSYNC_L 0x0022b +#define DPCD_ADDR_TEST_VSYNC_H 0x0022c +#define DPCD_ADDR_TEST_VSYNC_L 0x0022d +#define DPCD_ADDR_TEST_H_WIDTH_H 0x0022e +#define DPCD_ADDR_TEST_H_WIDTH_L 0x0022f +#define DPCD_ADDR_TEST_V_HEGHT_H 0x00230 +#define DPCD_ADDR_TEST_V_HEGHT_L 0x00231 + +#define DPCD_ADDR_TEST_PHY 0x00248 +#define DPCD_ADDR_TEST_PHY_SEL_MASK 3 + + +#define DPCD_ADDR_TEST_RESPONSE 0x00260 +#define DPCD_ADDR_TEST_RESPONSE_ACK (1 << 0) +#define DPCD_ADDR_TEST_RESPONSE_NACK (1 << 1) +#define DPCD_ADDR_TEST_RESPONSE_EDID (1 << 2) + +#define DPCD_ADDR_TEST_EDID_CHECKSUM 0x00261 + + + +#define DPCD_ADDR_SOURCE_IEEE_OUI_7_0 0x00300 +#define DPCD_ADDR_SOURCE_IEEE_OUI_15_8 0x00301 +#define DPCD_ADDR_SOURCE_IEEE_OUI_23_16 0x00302 + +#define DPCD_ADDR_SOURCE_DEVICE_ID_BYTE_0 0x00303 + +#define DPCD_ADDR_SINK_IEEE_OUI_7_0 0x00400 +#define DPCD_ADDR_SINK_IEEE_OUI_15_8 0x00401 +#define DPCD_ADDR_SINK_IEEE_OUI_23_16 0x00402 + +#define DPCD_ADDR_SINK_DEVICE_ID_BYTE_0 0x00403 + +#define DPCP_ADDR_VENDOR_BYTES 0x00430 + +#define DPCD_ADDR_BRANCH_IEEE_OUI_7_0 0x00500 +#define DPCD_ADDR_BRANCH_IEEE_OUI_15_8 0x00501 +#define DPCD_ADDR_BRANCH_IEEE_OUI_23_16 0x00502 + +#define DPCD_ADDR_BRANCH_DEVICE_ID_BYTE_0 0x00503 + +#define DPCD_ADDR_HDMI_DVI_MODE_SELECT 0x00519 +#define DPCD_HDMI_DVI_SELECT_DEFAULT 0x00 +#define DPCD_ADDR_HDMI_DVI_MODE_SELECT_DVI 0x01 +#define DPCD_HDCP_ENABLE 0x00 +#define DPCD_HDCP_DISABLE 0x02 + +#define DPCD_ADDR_SINK_POWER_STATE 0x00600 +#define DPCD_ADDR_SINK_POWER_STATE_ON 0x1 +#define DPCD_ADDR_SINK_POWER_STATE_OFF 0x2 + + +#define DPCD_ADDR_HDCP_BKSV_0 0x68000 +#define DPCD_ADDR_HDCP_BKSV_1 0x68001 +#define DPCD_ADDR_HDCP_BKSV_2 0x68002 +#define DPCD_ADDR_HDCP_BKSV_3 0x68003 +#define DPCD_ADDR_HDCP_BKSV_4 0x68004 +#define DPCD_ADDR_HDCP_R0_0 0x68005 +#define DPCD_ADDR_HDCP_R0_1 0x68006 +#define DPCD_ADDR_HDCP_AKSV_0 0x68007 +#define DPCD_ADDR_HDCP_AKSV_1 0x68008 +#define DPCD_ADDR_HDCP_AKSV_2 0x68009 +#define DPCD_ADDR_HDCP_AKSV_3 0x6800a +#define DPCD_ADDR_HDCP_AKSV_4 0x6800b +#define DPCD_ADDR_HDCP_AN_0 0x6800c +#define DPCD_ADDR_HDCP_AN_1 0x6800d +#define DPCD_ADDR_HDCP_AN_2 0x6800e +#define DPCD_ADDR_HDCP_AN_3 0x6800f +#define DPCD_ADDR_HDCP_AN_4 0x68010 +#define DPCD_ADDR_HDCP_AN_5 0x68011 +#define DPCD_ADDR_HDCP_AN_6 0x68012 +#define DPCD_ADDR_HDCP_AN_7 0x68013 +#define DPCD_ADDR_HDCP_H0_0 0x68014 +#define DPCD_ADDR_HDCP_H0_1 0x68015 +#define DPCD_ADDR_HDCP_H0_2 0x68016 +#define DPCD_ADDR_HDCP_H0_3 0x68017 +#define DPCD_ADDR_HDCP_H1_0 0x68018 +#define DPCD_ADDR_HDCP_H1_1 0x68019 +#define DPCD_ADDR_HDCP_H1_2 0x6801a +#define DPCD_ADDR_HDCP_H1_3 0x6801b +#define DPCD_ADDR_HDCP_H2_0 0x6801c +#define DPCD_ADDR_HDCP_H2_1 0x6801d +#define DPCD_ADDR_HDCP_H2_2 0x6801e +#define DPCD_ADDR_HDCP_H2_3 0x6801f +#define DPCD_ADDR_HDCP_H3_0 0x68020 +#define DPCD_ADDR_HDCP_H3_1 0x68021 +#define DPCD_ADDR_HDCP_H3_2 0x68022 +#define DPCD_ADDR_HDCP_H3_3 0x68023 +#define DPCD_ADDR_HDCP_H4_0 0x68024 +#define DPCD_ADDR_HDCP_H4_1 0x68025 +#define DPCD_ADDR_HDCP_H4_2 0x68026 +#define DPCD_ADDR_HDCP_H4_3 0x68027 + +#define DPCD_ADDR_HDCP_BCAPS 0x68028 +#define DPCD_ADDR_HDCP_BCAPS_HDCP_CAPABLE (1 << 0) +#define DPCD_ADDR_HDCP_BCAPS_IS_REPEATER (1 << 1) + +#define DPCD_ADDR_HDCP_STATUS 0x68029 +#define DPCD_ADDR_HDCP_STATUS_LINK_INTEGRITY_FAILURE (1 << 2) +#define DPCD_ADDR_HDCP_STATUS_R0PRIME_AVAILABLE (1 << 1) +#define DPCD_ADDR_HDCP_STATUS_READY (1 << 0) + +#define DPCD_ADDR_HDCP_BINFO_0 0x6802a + +#define DPCD_ADDR_HDCP_BINFO_1 0x6802b +#define DPCD_ADDR_HDCP_INFO_MAX_CASCADE_EXCEEDED (1 << 11) +#define DPCD_ADDR_HDCP_INFO_MAX_DEVS_EXCEEDED (1 << 7) + +#define DPCD_ADDR_HDCP_KSV_FIFO_0 0x6802c +#define DPCD_ADDR_HDCP_KSV_FIFO_1 0x6802d +#define DPCD_ADDR_HDCP_KSV_FIFO_2 0x6802e +#define DPCD_ADDR_HDCP_KSV_FIFO_3 0x6802f +#define DPCD_ADDR_HDCP_KSV_FIFO_4 0x68030 +#define DPCD_ADDR_HDCP_KSV_FIFO_5 0x68031 +#define DPCD_ADDR_HDCP_KSV_FIFO_6 0x68032 +#define DPCD_ADDR_HDCP_KSV_FIFO_7 0x68033 +#define DPCD_ADDR_HDCP_KSV_FIFO_8 0x68034 +#define DPCD_ADDR_HDCP_KSV_FIFO_9 0x68035 +#define DPCD_ADDR_HDCP_KSV_FIFO_10 0x68036 +#define DPCD_ADDR_HDCP_KSV_FIFO_11 0x68037 +#define DPCD_ADDR_HDCP_KSV_FIFO_12 0x68038 +#define DPCD_ADDR_HDCP_KSV_FIFO_13 0x68039 +#define DPCD_ADDR_HDCP_KSV_FIFO_14 0x6803a +#define DPCD_ADDR_HDCP_RSVD 0x6803b diff --git a/drivers/displayport/edid.h b/drivers/displayport/edid.h new file mode 100644 index 0000000..768b04b --- /dev/null +++ b/drivers/displayport/edid.h @@ -0,0 +1,377 @@ +/* + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2009 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IOKIT_EDID_H +#define _IOKIT_EDID_H + + +#define kEDIDEstablishedTimingsCount 24 +#define kEDIDEstablishedTimingsIIICount 48 + +typedef struct __attribute__((packed)) _EDIDDetailedHeader { + uint8_t header[2]; +}EDIDDetailedHeader; + +//__packed +typedef struct __attribute__((packed)) _EDIDDetailedTiming { + uint8_t pixelClock[2]; + + uint8_t hor_addr_low; + uint8_t hor_blank_low; + uint8_t hor_addr_blank_high; + uint8_t ver_addr_low; + uint8_t ver_blank_low; + uint8_t ver_addr_blank_high; + + uint8_t hor_fporch; // #8 + uint8_t hor_sync; + uint8_t ver_fporch_sync; + + uint8_t hor_ver_porch_sync_high; + uint8_t inmm[3]; // in milimeter + uint8_t hor_border; + uint8_t ver_border; + uint8_t detailed; +} EDIDDetailedTiming; + +typedef struct __attribute__((packed)) _EDIDString{ + uint8_t flag; + char string[13]; +} EDIDString; + +typedef enum { + kEDIDDetailedRangeFlagRateOffsetVerticalMin = (1<<0), + kEDIDDetailedRangeFlagRateOffsetVerticalMax = (1<<1), + kEDIDDetailedRangeFlagRateOffsetHorizontalMin = (1<<2), + kEDIDDetailedRangeFlagRateOffsetHorizontalMax = (1<<3) +} EDIDDetailedRangeFlags; + +enum { + kEDIDDetailedRangeVideoTimingTypeGTF = 0, + kEDIDDetailedRangeVideoTimingTypeRangeLimitsOnly = 1, + kEDIDDetailedRangeVideoTimingTypeSecondaryGTF = 2, + kEDIDDetailedRangeVideoTimingTypeCVT = 4 +}; +typedef uint8_t EDIDDetailedRangeVideoTimingType; + +typedef enum { + kEDIDSupportedAspectFlag15_9 = (1<<3), + kEDIDSupportedAspectFlag5_4 = (1<<4), + kEDIDSupportedAspectFlag16_10 = (1<<5), + kEDIDSupportedAspectFlag16_9 = (1<<6), + kEDIDSupportedAspectFlag4_3 = (1<<7) +} EDIDSupportedAspectFlags; + +typedef enum { + kEDIDPreferredAspectType4_3, + kEDIDPreferredAspectType16_9, + kEDIDPreferredAspectType16_10, + kEDIDPreferredAspectType5_4, + kEDIDPreferredAspectType15_9, + kEDIDPreferredAspectTypeShift = 5, + kEDIDPreferredAspectTypeMask = 0x7, + +} EDIDPreferredAspectType; + +typedef enum { + kEDIDCVTBlankingFlagStandard = (1<<3), + kEDIDCVTBlankingFlagReduced = (1<<4), +} EDIDCVTBlankingFlags; + +typedef enum { + kEDIDDigitalScalingFlagVerticalStretch = (1<<4), + kEDIDDigitalScalingFlagVerticalShrink = (1<<5), + kEDIDDigitalScalingFlagHorizontalStretch = (1<<6), + kEDIDDigitalScalingFlagHorizontalShrink = (1<<7) +} EDIDDigitalScalingFlags; + + +typedef struct __attribute__((packed)) _EDIDDetailedRangeGTF { + uint8_t reserved; + uint8_t breakFrequency; // horizontal freq / 2 (khz) + uint8_t c; // c*2 + uint8_t m[2]; + uint8_t k; + uint8_t j; // j*2 +} EDIDDetailedRangeGTF; + +typedef struct __attribute__((packed)) _EDIDDetailedRangeCVT { + uint8_t version; + // Max. Pix Clk = [(range.maxPixelClockRate) × 10] – [(Byte 12: bits 7-2) × 0.25MHz] + uint8_t precision_activeMaxMSB; // pixel clock precision * 0.25Mhz (bits 7-2) | max active pixels per line MSB (bits 1-0) + uint8_t activeMaxLSB; // max active pixels per line MSB + uint8_t supportedFlags; + uint8_t preferredFlags; + uint8_t scaling; + uint8_t verticalRefreshRate; //hz +} EDIDDetailedRangeCVT; + +typedef struct __attribute__((packed)) _EDIDDetailedRange{ + uint8_t flag; + uint8_t minVerticalRate; + uint8_t maxVerticalRate; + uint8_t minHorizontalRate; + uint8_t maxHorizontalRate; + uint8_t maxPixelClockRate; + + struct { + EDIDDetailedRangeVideoTimingType type; + + union { + EDIDDetailedRangeGTF gtf; + EDIDDetailedRangeCVT cvt; + } data; + }timing; + +} EDIDDetailedRange; + +typedef struct __attribute__((packed)) _EDIDDetailedWhitePoint { + uint8_t index; + uint8_t xyLSB; + uint8_t x; + uint8_t y; + uint8_t gamma; +} EDIDDetailedWhitePoint; + +typedef struct __attribute__((packed)) _EDIDDetailedColorPoint { + EDIDDetailedWhitePoint whitePoint[2]; +} EDIDDetailedColorPoint; + +typedef struct __attribute__((packed)) _EDIDDetailedEstablishedTimingsIII { + uint8_t data[6]; +} EDIDDetailedEstablishedTimingsIII; + +typedef struct __attribute__((packed)) _EDIDDetailedDescriptor { + uint8_t zero[2]; + uint8_t flag; + uint8_t type; + + union { + EDIDString name; + EDIDDetailedRange range; + EDIDDetailedColorPoint color; + uint8_t standard[12]; + uint8_t cvt[12]; + EDIDDetailedEstablishedTimingsIII established; + }data; + +}EDIDDetailedDescriptor; + + +typedef struct __attribute__((packed)) EDIDDetailed { + + union { + EDIDDetailedHeader header; + EDIDDetailedTiming timing; + EDIDDetailedDescriptor descriptor; + } data; + +} EDIDDetailed; + + +typedef struct __attribute__((packed)) _EDIDHeader { + uint8_t header[8]; +} EDIDHeader; + +typedef enum { + kEDIDStandardFeatureFlagGTF = (1<<0), + kEDIDStandardFeatureFlagPreferredNative = (1<<1), + kEDIDStandardFeatureFlagSRGB = (1<<2), + kEDIDStandardFeatureFlagColorDepth = (3<<3), + kEDIDStandardFeatureFlagActiveOff = (1<<5), + kEDIDStandardFeatureFlagSuspend = (1<<6), + kEDIDStandardFeatureFlagStandby = (1<<7) +} EDIDStandardFeatureFlags; + +// STANDARD STUFF +typedef struct __attribute__((packed)) _EDIDStandard { + uint8_t header[8]; + // Vender / Product + uint8_t vendorID[2]; + uint8_t productID[2]; + uint8_t serialNumber[4]; + uint8_t weekOfManu; + uint8_t yearOfManu; + // EDID structure version / rev. + uint8_t version; + uint8_t revision; + // Basic Display Parameters / Features + uint8_t videoInputDef; + uint8_t maxHorzSize; // cm + uint8_t maxVertSize; // cm + uint8_t dispTransferChr; + uint8_t feature; + // Color Characteristics + uint8_t redGreenLowBits; + uint8_t blueWhiteLowBits; + uint8_t redX; + uint8_t redY; + uint8_t greenX; + uint8_t greenY; + uint8_t blueX; + uint8_t blueY; + uint8_t whiteX; + uint8_t whiteY; + // Established Timings + uint8_t established[3]; + // Standard Timing Identification + uint8_t standard[16]; + EDIDDetailed preferred; + EDIDDetailed detailed[3]; + // Extra + uint8_t extensionFlag; + uint8_t checksum; +} EDIDStandard; + + +typedef struct __attribute__((packed)) _EDIDEXTHeader { + uint8_t tag; + uint8_t revision; +} EDIDEXTHeader; + +typedef struct __attribute__((packed)) _EDIDCVT { + uint8_t data[3]; +} EDIDCVT; + +// CEA STUFF + +typedef enum { + kEDIDCEA3DataBlockTypeReserved, + kEDIDCEA3DataBlockTypeAudio, + kEDIDCEA3DataBlockTypeVideo, + kEDIDCEA3DataBlockTypeVenderSpecific, + kEDIDCEA3DataBlockTypeSpeakerAllocation, + kEDIDCEA3DataBlockTypeVESADTC, + kEDIDCEA3DataBlockTypeReserved1, + kEDIDCEA3DataBlockTypeExtended +} EDIDCEA3DataBlockType; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockAudio { + uint8_t descriptor[0]; +} EDIDCEA3DataBlockAudio; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockVideo { + uint8_t descriptor[0]; +} EDIDCEA3DataBlockVideo; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockVendorSpecific { + uint8_t ieeeOui[3]; + uint8_t data[0]; +} EDIDCEA3DataBlockVendorSpecific; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockSpeakerAllocation { + uint8_t data[3]; +} EDIDCEA3DataBlockSpeakerAllocation; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockExtended { + uint8_t tag; + uint8_t data[31]; +} EDIDCEA3DataBlockExtended; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlock { + uint8_t flags; + + union { + EDIDCEA3DataBlockAudio audio; + EDIDCEA3DataBlockVideo video; + EDIDCEA3DataBlockVendorSpecific vendor; + EDIDCEA3DataBlockSpeakerAllocation speaker; + EDIDCEA3DataBlockExtended extended; + } data; + +} EDIDCEA3DataBlock; + +typedef struct __attribute__((packed)) _EDIDCEA_1 { + struct { + uint8_t tag; + uint8_t revision; + uint8_t dataOffset; + uint8_t reserved; + } header; + + uint8_t data[123]; + uint8_t checksum; +} EDIDCEA_1; + +typedef struct __attribute__((packed)) _EDIDCEA_2 { + struct { + uint8_t tag; + uint8_t revision; + uint8_t dataOffset; + uint8_t detailedFlags; + } header; + + uint8_t data[123]; + uint8_t checksum; +} EDIDCEA_2; + +typedef struct __attribute__((packed)) _EDIDCEA_3 { + struct { + uint8_t tag; + uint8_t revision; + uint8_t dataLength; + uint8_t detailedFlags; + } header; + uint8_t data[123]; + uint8_t checksum; +} EDIDCEA_3; + +typedef struct __attribute__((packed)) _EDIDCEA { + union { + EDIDEXTHeader header; + EDIDCEA_1 cea1; + EDIDCEA_2 cea2; + EDIDCEA_3 cea3; + } data; +} EDIDCEA; + +typedef struct __attribute__((packed)) _EDIDVTB{ + EDIDEXTHeader header; + uint8_t dtbCount; + uint8_t cvtCount; + uint8_t stCount; + uint8_t data[122]; + uint8_t checksum; +} EDIDVTB; + +typedef enum { + kEDIDTypeCEA = 0x02, + KEDIDTypeVTB = 0x10, + kEDIDTypeDI = 0x40, +} EDIDType; + +// __packed +typedef struct __attribute__((packed)) _EDID{ + union { + EDIDHeader header; + EDIDStandard standard; + EDIDCEA cea; + EDIDVTB vtb; + } data; + +} EDID; + + + +#endif /* _IOKIT_EDID_H */ diff --git a/drivers/displayport/process_edid.c b/drivers/displayport/process_edid.c new file mode 100644 index 0000000..84211fd --- /dev/null +++ b/drivers/displayport/process_edid.c @@ -0,0 +1,1753 @@ +#if WITH_HW_MCU + +/* + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * This file is based on a manual C++-to-C translation of: + * IODisplayPortFamily/IODPService.cpp + * The scoring system and timing collection is simplified. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "dpcd.h" +#include "edid.h" + +// I2C address for the EDID rom. +#define kI2CEdidDeviceAddr 0x50 + +// H3 DisplayPipe has issues higher than this. +#define kMaxHorizontalActive 1280 + +// Some monitors are slow. Insert microseconds of dumb. +#define kEdidRetryTimeout 5000000 +// Some monitors are suspiciously single-threaded. Don't retry too +// often or they make no forward progress. +#define kEdidRetryDelay 250000 + +///////////////////////////////////////// +////////// debug support + +#define DP_DEBUG_MASK ( \ + DP_DEBUG_EDID | \ + DP_DEBUG_ERROR | \ + DP_DEBUG_INFO | \ + 0) + +#undef DP_DEBUG_MASK +#define DP_DEBUG_MASK DP_DEBUG_ERROR // (DP_DEBUG_EDID | DP_DEBUG_SCORE | DP_DEBUG_DS | DP_DEBUG_ERROR | DP_DEBUG_INFO) + +#define DP_DEBUG_EDID (1<<16) // EDID parsing +#define DP_DEBUG_SCORE (1<<17) // Final validation/scoring +#define DP_DEBUG_DS (1<<18) // Downstream type detection +#define DP_DEBUG_INFO (1<<19) // info +#define DP_DEBUG_ERROR (1<<20) // error +#define DP_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((DP_DEBUG_ ## _fac) & (DP_DEBUG_MASK | DP_DEBUG_ALWAYS)) \ + dprintf(DEBUG_INFO, "EDID: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + +typedef struct { + // Slightly compacted vs IODPDisplayTimingElement.cpp + uint16_t horizontal; + uint16_t vertical; + uint32_t rate; +} __IODPTEEstablished; + +typedef enum { + kSupportFlagNone = (0<<0), + kSupportFlagGTF = (1<<0), + kSupportFlagCVT = (1<<1) +} SupportFlags; + +static int process_edid(EDID *edid); +static int verify_edid(EDID *edid, uint8_t *p_checksum); +static int get_edid(uint32_t offset, EDID *edid); +static int process_edid_vtb(EDIDVTB *vtb); +static int process_edid_cvt_timings(uint8_t *data, uint32_t length); +static int process_edid_cea(EDIDCEA *cea); +static int process_edid_cea1(EDIDCEA_1 *cea1); +static int process_edid_cea2(EDIDCEA_2 *cea2); +static int process_edid_cea3(EDIDCEA_3 *cea3); +static int process_edid_cea3_video(EDIDCEA3DataBlockVideo *video, uint32_t length); +static int process_edid_cea3_vendor_specific(EDIDCEA3DataBlockVendorSpecific *vendor, uint32_t length); +static int process_edid_standard(EDIDStandard *standard); +static int process_edid_standard_feature(EDIDStandard *standard); +static int process_edid_standard_timings(uint8_t *data, uint32_t length); +static int process_edid_standard_established_timings(EDIDStandard *standard); +static int process_edid_detailed(EDIDDetailed *detailed); +static int process_edid_detailed_descriptor(EDIDDetailedDescriptor *descriptor); +static int process_edid_detailed_established_timings_iii(EDIDDetailedEstablishedTimingsIII *established); +static int try_standard_timing_id(uint16_t timing_id); +static int try_established_timing_id(uint8_t index); +static int try_established_timing_iii_id(uint8_t establishedID); +static int try_detailed_timing(EDIDDetailedTiming *detailed); +static int try_cvt_timing_id(EDIDCVT *cvt); +static int try_cea_short_id(uint32_t shortVideoID); +static int get_timing_data_for_cea_short_id(uint32_t shortVideoID, struct video_timing_data *timingData); +static int use_dimensions(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_dmt(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_cvt(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_gtf(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_table(const struct video_timing_data * list, uint32_t count, uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_timings(struct video_timing_data *data); +static uint16_t read_le16(const void *data, uint32_t offset); +static uint32_t read_le32(const void *data, uint32_t offset); + +static bool s_have_timings; +static bool s_abort_edid; +static struct video_timing_data s_best_timings; +static SupportFlags s_timing_support; +static uint32_t s_restrict_h_active; +static uint32_t s_restrict_v_active; +static int s_ds_type = -1; + + +int obtain_edid(void) +{ + int ret = -1; + EDID edid; + uint32_t ext_block_count; + uint32_t index = 0; + + s_have_timings = false; + bzero(&s_best_timings, sizeof(s_best_timings)); + s_timing_support = kSupportFlagNone; + s_ds_type = kDPDownstreamTypeOther; + (void) dp_device_get_downstream_port_type(&s_ds_type); + debug(DS, "Displayport immediate downstream type %d\n", s_ds_type); + + ret = get_edid(0, &edid); + debug(EDID, "Obtaining base EDID result=%d\n", ret); + if (ret) goto exit; + if (s_ds_type == kDPDownstreamTypeHDMI) { + // If we see any EDID activity, start by assuming it's + // actually a DVI monitor with HDMI ports (or adaptor). + // Revert to detecting as HDMI if we receive an appropriate + // flag in one of the EDID packets. + debug(DS, "Assuming HDMI port actually DVI\n"); + s_ds_type = kDPDownstreamTypeDVI; + } + + ret = process_edid(&edid); + debug(EDID, "Processing EDID result=%d\n", ret); + if (ret) goto exit; + + ext_block_count = edid.data.standard.extensionFlag; + debug(EDID, "EDID contains %d extensions\n", ext_block_count); + + for (index = 1; index <= ext_block_count; ++index) { + ret = get_edid(index * sizeof(EDID), &edid); + debug(EDID, "Obtaining EDID extension %d result=%d\n", index, ret); + if (ret) goto exit; + + ret = process_edid(&edid); + debug(EDID, "Processing EDID extension %d result=%d\n", index, ret); + if (ret) goto exit; + } + debug(DS, "Downstream type %d\n", s_ds_type); + + exit: + return ret; +} + +void abort_edid(void) +{ + s_abort_edid = true; +} + +void restrict_edid(uint32_t h_active, uint32_t v_active) +{ + s_restrict_h_active = h_active; + s_restrict_v_active = v_active; +} + +int get_edid_timings(struct video_timing_data *data) +{ + if (!s_have_timings) return -1; + bcopy(&s_best_timings, data, sizeof(s_best_timings)); + debug(ALWAYS, "EDID: %ux%u%c/%u\n", + s_best_timings.axis[kDisplayAxisTypeHorizontal].active, + s_best_timings.axis[kDisplayAxisTypeVertical].active, + s_best_timings.interlaced ? 'i' : 'p', + s_best_timings.axis[kDisplayAxisTypeVertical].sync_rate >> 16); + return 0; +} + +int get_edid_downstream_type(void) +{ + return s_ds_type; +} + +static int process_edid(EDID *edid) +{ + static const uint8_t edid_standard_header[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; + + debug(EDID, "Processing EDID\n"); + + if (!memcmp(edid->data.header.header, edid_standard_header, sizeof(edid_standard_header))) { + process_edid_standard(&edid->data.standard); + } else { + switch (edid->data.header.header[0]) { + case kEDIDTypeCEA: + process_edid_cea(&edid->data.cea); + break; + case KEDIDTypeVTB: + process_edid_vtb(&edid->data.vtb); + break; + default: + debug(EDID, "Unknown EDID type %d\n", edid->data.header.header[0]); + break; + } + } + return 0; +} + +static int process_edid_vtb(EDIDVTB *vtb) +{ + uint32_t index, length; + uint32_t dtbCount, cvtCount, stCount; + + debug(EDID, "Processing EDID VTB\n"); + + if (1 != vtb->header.revision) goto exit; + + if (!(vtb->dtbCount && vtb->cvtCount && vtb->stCount)) goto exit; + + length = sizeof(vtb->data); + index = 0; + dtbCount = vtb->dtbCount; + cvtCount = vtb->cvtCount; + stCount = vtb->stCount; + while ( indexremaining) + break; + + process_edid_detailed((EDIDDetailed*)&vtb->data[index]); + + index += sizeof(EDIDDetailed); + dtbCount--; + } + else if ( cvtCount ) { + uint32_t cvtLength = cvtCount * sizeof(EDIDCVT); + if (cvtLength>remaining) + break; + + process_edid_cvt_timings(&vtb->data[index], cvtLength); + + index += cvtLength; + cvtCount = 0; + } + else if ( stCount ) { + uint32_t stLength = stCount * sizeof(uint16_t); + if (stLength>remaining) + break; + + process_edid_standard_timings(&vtb->data[index], stLength); + + index += stLength; + stCount = 0; + } + else { + break; + } + } + exit: + return 0; +} + +static int process_edid_cvt_timings(uint8_t *data, uint32_t length) +{ + uint32_t index; + debug(EDID, "Processing EDID CVT timings\n"); + for( index = 0; index < length; index+=sizeof(EDIDCVT) ) { + try_cvt_timing_id((EDIDCVT*)&data[index]); + } + return 0; +} + +static int process_edid_cea(EDIDCEA *cea) +{ + debug(EDID, "Processing CEA EDID\n"); + + switch (cea->data.header.revision) { + case 1: + process_edid_cea1(&cea->data.cea1); + break; + case 2: + process_edid_cea2(&cea->data.cea2); + break; + case 3: + process_edid_cea3(&cea->data.cea3); + break; + default: + break; + } + + return 0; +} + +static int process_edid_cea1(EDIDCEA_1 * cea1) +{ + uint32_t relativeDataOffset; + uint32_t index = 0; + + debug(EDID, "Processing CEA v1 EDID\n"); + if (cea1->header.dataOffset<=sizeof(cea1->header)) return -1; + + relativeDataOffset = cea1->header.dataOffset-sizeof(cea1->header); + while ( relativeDataOffset < sizeof(cea1->data) && (sizeof(cea1->data)-relativeDataOffset) >= sizeof(EDIDDetailed)) { + debug(EDID, "Processing Detailed Timing index %d\n", index++); + process_edid_detailed((EDIDDetailed*)(cea1->data + relativeDataOffset)); + relativeDataOffset += sizeof(EDIDDetailed); + } + + return 0; +} + +static int process_edid_cea2(EDIDCEA_2 * cea2) +{ + debug(EDID, "Processing CEA v2 EDID\n"); + // Don't care about audio/color/overscan. Just pass it along. + return process_edid_cea1((EDIDCEA_1*)cea2); +} + +static int process_edid_cea3(EDIDCEA_3 * cea3) +{ + uint32_t startOffset = 0; + uint32_t length = 0; + uint32_t index = 0; + + debug(EDID, "Processing CEA v3 EDID\n"); + + if (cea3->header.dataLength <= sizeof(cea3->header) || cea3->header.dataLength>sizeof(EDIDCEA_3)) return -1; + + length = cea3->header.dataLength-sizeof(cea3->header); + while ( startOffset < length ) { + EDIDCEA3DataBlock * block = (EDIDCEA3DataBlock*)(cea3->data + startOffset); + EDIDCEA3DataBlockType blockType; + uint32_t blockLength; + uint32_t sectionLength; + + debug(EDID, "Processing CEA v3 EDID Data Block index %d\n", index++); + + // Check for padding + if ( !block->flags ) { + debug(EDID, "Encountered zero padding.\n"); + break; + } + + blockType = (EDIDCEA3DataBlockType)((block->flags>>5) & 0x7); + blockLength = (block->flags) & 0x1f; + + sectionLength = blockLength+sizeof(block->flags); + if ( sectionLength>(length-startOffset) ) return -1; + + debug(EDID, "Processing CEA v3 EDID Data Block type %d of length %d\n", + blockType, blockLength); + + switch ( blockType ) { + case kEDIDCEA3DataBlockTypeAudio: + // Don't care. + // process_edid_cea3_audio((EDIDCEA3DataBlockAudio*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeVideo: + process_edid_cea3_video((EDIDCEA3DataBlockVideo*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeSpeakerAllocation: + // Don't care. + // process_edid_cea3_speaker_allocation((EDIDCEA3DataBlockSpeakerAllocation*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeExtended: + // Don't care. + // process_edid_cea3_extended((EDIDCEA3DataBlockExtended*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeVenderSpecific: + process_edid_cea3_vendor_specific((EDIDCEA3DataBlockVendorSpecific*)&block->data, blockLength); + break; + default: + break; + } + startOffset += sectionLength; + } + + return process_edid_cea2((EDIDCEA_2*)cea3); +} + +static int process_edid_cea3_video(EDIDCEA3DataBlockVideo * video, uint32_t length) +{ + uint32_t index; + + debug(EDID, "Processing CEA v3 EDID Video\n"); + + for ( index=0; indexdescriptor[index]; + debug(EDID, "Processing CEA ShortID %d\n", id); + try_cea_short_id(video->descriptor[index]); + } + + return 0; +} + +static int process_edid_cea3_vendor_specific(EDIDCEA3DataBlockVendorSpecific *vendor, uint32_t length) +{ + // Only care that this might be a signal we're HDMI. + static const uint8_t hdmi_out[] = { 0x03, 0x0c, 0x00 }; + if (!memcmp(hdmi_out, vendor->ieeeOui, sizeof(hdmi_out))) { + debug(DS, "EDID says oui, we're HDMI\n"); + s_ds_type = kDPDownstreamTypeHDMI; + } + return 0; +} + +static int process_edid_standard(EDIDStandard *standard) +{ + debug(EDID, "Processing Standard EDID\n"); + + // Don't care about vendor/product IDs, color. + process_edid_standard_feature(standard); + process_edid_standard_established_timings(standard); + process_edid_standard_timings(standard->standard, sizeof(standard->standard)); + process_edid_detailed(&standard->preferred); + process_edid_detailed(&standard->detailed[0]); + process_edid_detailed(&standard->detailed[1]); + process_edid_detailed(&standard->detailed[2]); + + return 0; +} + +static int process_edid_standard_feature(EDIDStandard *standard) +{ + // Don't care about color, just HDMI vs DVI and timings. + if ((s_ds_type != kDPDownstreamTypeVGA) && (standard->videoInputDef & (1<<7)) ) { + if ( standard->version == 1 && standard->revision >= 4 ) { + switch (standard->videoInputDef & 0x0F) { + case 0: + case 1: + debug(DS, "EDID says downstream DVI\n"); + s_ds_type = kDPDownstreamTypeDVI; + break; + case 5: + debug(DS, "EDID says downstream DP\n"); + s_ds_type = kDPDownstreamTypeDP; + break; + default: + debug(DS, "EDID says downstream HDMI\n"); + s_ds_type = kDPDownstreamTypeHDMI; + break; + } + } + } + + if ( standard->feature & kEDIDStandardFeatureFlagGTF ) { + if ( standard->version == 1 && standard->revision >= 4 ) + s_timing_support = kSupportFlagCVT; + else + s_timing_support = kSupportFlagGTF; + } + return 0; +} + +static int process_edid_standard_timings(uint8_t *standard, uint32_t length) +{ + uint32_t index; + for (index = 0; index < length; index += 2) { + uint16_t timing_id = read_le16(standard, index); + try_standard_timing_id(timing_id); + } + return 0; +} + +static int process_edid_standard_established_timings(EDIDStandard *standard) +{ + uint32_t index; + + debug(EDID, "established=0x%02x established1=0x%02x established2=0x%02x\n", + standard->established[0], + standard->established[1], + standard->established[2]); + + for (index = 0; index < kEDIDEstablishedTimingsCount; ++index) { + if (!(standard->established[index>>3] & (1 << (index % 8)))) + continue; + debug(EDID, "index=%d\n", index); + try_established_timing_id(index); + } + return 0; +} + +static int process_edid_detailed(EDIDDetailed *detailed) +{ + if (detailed->data.header.header[0] == 0 && detailed->data.header.header[1] == 0) { + return process_edid_detailed_descriptor(&(detailed->data.descriptor)); + } else { + return try_detailed_timing(&(detailed->data.timing)); + } +} + +static int process_edid_detailed_descriptor(EDIDDetailedDescriptor *descriptor) +{ + if (!descriptor->flag) return 0; + + switch (descriptor->type) { + case 0xff: //Serial number + // Don't care. + break; + case 0xfd: //Range limits + // IODPService.cpp doesn't use this. + // process_edid_detailed_range(&descriptor->data.range); + break; + case 0xfc: //Monitor name + // Don't care. + break; + case 0xfb: // color point data + // Don't care. + // process_edid_detailed_color_point(&descriptor->data.color); + break; + case 0xfa: // standard timing + process_edid_standard_timings(descriptor->data.standard, sizeof(descriptor->data.standard)); + break; + case 0xf8: // CVT + process_edid_cvt_timings(descriptor->data.cvt, sizeof(descriptor->data.cvt)); + break; + case 0xf7: // established timings III + process_edid_detailed_established_timings_iii(&descriptor->data.established); + default: // DCM + break; + } + + return 0; +} + +static int process_edid_detailed_established_timings_iii(EDIDDetailedEstablishedTimingsIII *established) +{ + uint32_t index; + + debug(EDID, "established=%02x established1=%02x established2=%02x established3=%02x established4=%02x established5=%02x\n", established->data[0], established->data[1], established->data[2], established->data[3], established->data[4], established->data[5]); + + for (index = 0; index < kEDIDEstablishedTimingsCount; ++index) { + debug(EDID, "index=%d mask=%08x\n", index, (1 << (index % 8))); + + if ( !(established->data[index>>3] & (1 << (index % 8))) ) + continue; + + try_established_timing_iii_id(index); + } + + return 0; +} + +static int try_standard_timing_id(uint16_t timing_id) +{ + uint32_t horizontal; + uint32_t vertical = 0; + uint32_t rate; + + debug(EDID, "timing_id 0x%04x\n", timing_id); + + if (timing_id == 0x0101) + return -1; + + horizontal = ((timing_id & 0xff) + 31) * 8; + switch ((timing_id >> 14) & 0x3) { + case 0: + vertical = horizontal * 10 / 16; + break; + case 1: + vertical = horizontal * 3 /43; + break; + case 2: + vertical = horizontal * 4 / 5; + break; + case 3: + vertical = horizontal * 9 / 16; + break; + } + + rate = ((timing_id >> 8) & 0x3f) + 60; + + return use_dimensions(horizontal, vertical, rate << 16); +} + +static int try_established_timing_id(uint8_t established_id) +{ + static const __IODPTEEstablished established_info[] = { + {800, 600, 60<<16}, + {800, 600, 56<<16}, + {640, 480, 75<<16}, + {640, 480, 72<<16}, + {640, 480, 67<<16}, + {640, 480, 60<<16}, + {720, 400, 88<<16}, + {720, 400, 70<<16}, + + {1280, 1024, 75<<16}, + {1024, 768, 75<<16}, + {1024, 768, 70<<16}, + {1024, 768, 60<<16}, + {0,0,0}, //interlaced {1024, 768, 87<<16}, + {832, 624, 75<<16}, + {800, 600, 75<<16}, + {800, 600, 72<<16}, + + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {1152, 870, 75<<16} + }; + + if (established_id >= (sizeof(established_info) / sizeof(__IODPTEEstablished))) + return 0; + + return use_dimensions(established_info[established_id].horizontal, + established_info[established_id].vertical, + established_info[established_id].rate); +} + +static int try_established_timing_iii_id(uint8_t establishedID) +{ + static const __IODPTEEstablished sEstablishedInfo[] = { + {1152, 864, 75<<16}, + {1024, 768, 85<<16}, + {800, 600, 85<<16}, + {848, 480, 60<<16}, + {640, 480, 85<<16}, + {720, 400, 85<<16}, + {640, 400, 85<<16}, + {640, 350, 85<<16}, + + {1280, 1024, 85<<16}, + {1280, 1024, 60<<16}, + {1280, 960, 85<<16}, + {1280, 960, 60<<16}, + {1280, 768, 85<<16}, + {1280, 768, 75<<16}, + {1280, 768, 60<<16}, + {0,0,0}, // Reduced Blanking {1280, 768, 60<<16}, + + {1400, 1050, 75<<16}, + {1400, 1050, 60<<16}, + {0,0,0}, // Reduced Blanking {1400, 1050, 60<<16}, + {1440, 900, 85<<16}, + {1440, 900, 75<<16}, + {1440, 900, 60<<16}, + {0,0,0}, // Reduced Blanking {1440, 900, 60<<16}, + {1360, 768, 60<<16}, + + {1600, 1200, 70<<16}, + {1600, 1200, 65<<16}, + {1600, 1200, 60<<16}, + {1680, 1050, 85<<16}, + {1680, 1050, 75<<16}, + {1680, 1050, 60<<16}, + {0,0,0}, // Reduced Blanking {1680, 1050, 60<<16}, + {1400, 1050, 85<<16}, + + {1920, 1200, 60<<16}, + {0,0,0}, // Reduced Blanking {1920, 1200, 60<<16}, + {1856, 1392, 75<<16}, + {1856, 1392, 60<<16}, + {1792, 1344, 75<<16}, + {1792, 1344, 60<<16}, + {1600, 1200, 85<<16}, + {1600, 1200, 75<<16}, + + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {1920, 1440, 75<<16}, + {1920, 1440, 60<<16}, + {1920, 1200, 85<<16}, + {1920, 1200, 75<<16}, + }; + + if (establishedID >= (sizeof(sEstablishedInfo) / sizeof(__IODPTEEstablished))) + return -1; + + return use_dimensions(sEstablishedInfo[establishedID].horizontal, + sEstablishedInfo[establishedID].vertical, + sEstablishedInfo[establishedID].rate); +} + +static int try_detailed_timing(EDIDDetailedTiming *detailed) +{ + struct video_timing_data _data; + uint32_t value; + uint16_t pixelClock; + int64_t rate, area; + + bzero(&_data, sizeof(_data)); + + value = detailed->hor_addr_low; + value |= (detailed->hor_addr_blank_high & 0xF0) << 4; + _data.axis[kDisplayAxisTypeHorizontal].active = value; + + value = detailed->hor_fporch; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<6))<<2; + _data.axis[kDisplayAxisTypeHorizontal].front_porch = value; + + value = detailed->hor_sync; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<4))<<4; + _data.axis[kDisplayAxisTypeHorizontal].sync_width = value; + + value = detailed->hor_blank_low; + value |= (detailed->hor_addr_blank_high & 0xF) << 8; + if ( value < detailed->hor_border ) + return -1; + value -= detailed->hor_border; + + _data.axis[kDisplayAxisTypeHorizontal].total = value + _data.axis[kDisplayAxisTypeHorizontal].active; + + if ( value < (_data.axis[kDisplayAxisTypeHorizontal].front_porch + _data.axis[kDisplayAxisTypeHorizontal].sync_width) ) { + debug(EDID, "Invaid horizontal blanking\n"); + return -1; + } + + _data.axis[kDisplayAxisTypeHorizontal].back_porch = value - _data.axis[kDisplayAxisTypeHorizontal].front_porch - _data.axis[kDisplayAxisTypeHorizontal].sync_width; + + value = detailed->ver_addr_low; + value |= (detailed->ver_addr_blank_high & 0xF0) << 4; + _data.axis[kDisplayAxisTypeVertical].active = value; + + value = (detailed->ver_fporch_sync & 0xF0) >> 4; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<2))<<2; + _data.axis[kDisplayAxisTypeVertical].front_porch = value; + + value = detailed->ver_fporch_sync & 0x0F; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<0))<<4; + _data.axis[kDisplayAxisTypeVertical].sync_width = value; + + value = detailed->ver_blank_low; + value |= (detailed->ver_addr_blank_high & 0xF) << 8; + if ( value < detailed->ver_border ) { + debug(EDID, "Vertical blank < vertical border\n"); + return -1; + } + + value -= detailed->ver_border; + + _data.axis[kDisplayAxisTypeVertical].total = value + _data.axis[kDisplayAxisTypeVertical].active; + if ( value < (_data.axis[kDisplayAxisTypeVertical].front_porch + _data.axis[kDisplayAxisTypeVertical].sync_width) ) + return -1; + _data.axis[kDisplayAxisTypeVertical].back_porch = value - _data.axis[kDisplayAxisTypeVertical].front_porch - _data.axis[kDisplayAxisTypeVertical].sync_width; + + pixelClock = (detailed->pixelClock[1]<<8) | detailed->pixelClock[0]; + area = _data.axis[kDisplayAxisTypeHorizontal].total * _data.axis[kDisplayAxisTypeVertical].total; + + if ( !area ) + return -1; + + rate = ((((uint64_t)pixelClock) * 10000) << 16) / area; + + // round up + rate += 0x8000; + rate &= 0xffff0000; + + _data.axis[kDisplayAxisTypeVertical].sync_rate = rate; + _data.interlaced = ( detailed->detailed & (1<<7) ) != 0; + + // digital + if ( ( detailed->detailed & (1<<4) ) != 0 ) { + + _data.axis[kDisplayAxisTypeHorizontal].sync_polarity = ( detailed->detailed & (1<<1) ) != 0; + + if ( ( detailed->detailed & (1<<3) ) != 0 ) { + _data.axis[kDisplayAxisTypeVertical].sync_polarity = ( detailed->detailed & (1<<2) ) != 0; + } else { + _data.axis[kDisplayAxisTypeVertical].sync_polarity = _data.axis[kDisplayAxisTypeHorizontal].sync_polarity; + + } + + } + + + if ( !_data.axis[kDisplayAxisTypeVertical].active || !_data.axis[kDisplayAxisTypeHorizontal].active || !_data.axis[kDisplayAxisTypeVertical].sync_rate) + return -1; + + return use_timings(&_data); +} + +static int try_cvt_timing_id(EDIDCVT *cvt) +{ + uint32_t horizontal = 0; + uint32_t vertical; + uint32_t rate; + uint32_t index; + + vertical = (((uint32_t)(cvt->data[1]&0xf0))<<4) | cvt->data[0]; + vertical = ( vertical + 1 ) * 2; + switch ((cvt->data[1]>>2) & 0x3) { + case 0: + horizontal = vertical * 4 / 3; + break; + case 1: + horizontal = vertical * 16 / 9; + break; + case 2: + horizontal = vertical * 16 / 10; + break; + default: + return -1; + } + + index = (cvt->data[2]>>5) & 0x3; + if ( cvt->data[2] & (1<<(4-index)) ) { + static const uint32_t sRates[] = { 50, 60, 75, 80 }; + rate = sRates[index]; + } else { + return -1; + } + + return use_dimensions(horizontal, vertical, rate<<16); +} + +static int try_cea_short_id(uint32_t shortVideoID) +{ + struct video_timing_data data; + debug(EDID, "cea_short_id 0x%08x\n", shortVideoID); + + if (get_timing_data_for_cea_short_id(shortVideoID, &data) != 0) + return -1; + + return use_timings(&data); +} + +static int get_timing_data_for_cea_short_id(uint32_t shortVideoID, struct video_timing_data *timingData) +{ + bzero(timingData, sizeof(struct video_timing_data)); + + switch ( shortVideoID ) { + // 1 640x480p @ 60 + case 1: + timingData->axis[kDisplayAxisTypeHorizontal].total = 800; + timingData->axis[kDisplayAxisTypeHorizontal].active = 640; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 96; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 48; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 2; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 33; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 10; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 2,3 720x480p @ 60 + case 2: + case 3: + timingData->axis[kDisplayAxisTypeHorizontal].total = 858; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 62; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 60; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 4 1280x720p @ 60 + case 4: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1650; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 110; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 7, 8 720(1440)x240p @ 60 + case 8: + case 9: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1716; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 124; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 114; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 38; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 262; + timingData->axis[kDisplayAxisTypeVertical].active = 240; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 15; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 12, 13 (2880)x240p @ 60 + case 12: + case 13: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3432; + timingData->axis[kDisplayAxisTypeHorizontal].active = 2880; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 248; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 228; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 76; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 262; + timingData->axis[kDisplayAxisTypeVertical].active = 240; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 15; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 6,7 720(1440)x480i @ 60 + case 6: + case 7: + timingData->interlaced = true; + // 14,15 720(1440)x480p @ 60 + case 14: + case 15: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1716; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 124; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 120; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 32; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 5 1920x1080i @ 60 + case 5: + timingData->interlaced = true; + // 16 1920x1080p @ 60 + case 16: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2200; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 88; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 21, 22 720(1440)x576i @ 50 + case 21: + case 22: + timingData->interlaced = true; + // 17 18 720x576p @ 50 + case 17: + case 18: + timingData->axis[kDisplayAxisTypeHorizontal].total = 864; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 64; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 68; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 12; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 19 1280x720p @ 50 + case 19: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1980; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 23, 24 720(1440)x288p @ 50 + case 23: + case 24: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1728; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 126; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 138; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 24; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 312; + timingData->axis[kDisplayAxisTypeVertical].active = 288; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 19; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 2; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 27, 28 (2880)x288p @ 50 + case 27: + case 28: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3456; + timingData->axis[kDisplayAxisTypeHorizontal].active = 2880; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 252; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 276; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 48; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 312; + timingData->axis[kDisplayAxisTypeVertical].active = 288; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 19; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 2; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 29, 30 1440x576p @ 50 + case 29: + case 30: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1728; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 128; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 136; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 24; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 20 1920x1080i @ 50 + case 20: + timingData->interlaced = true; + // 31 1920x1080p @ 50 + case 31: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2640; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 528; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 32 1920x1080p @ 24 + case 32: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2750; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 638; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 24<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 33 1920x1080p @ 25 + case 33: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2640; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 528; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 25<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 34 1920x1080p @ 30 + case 34: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2200; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 88; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 30<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 10, 11 (2880)x480i @ 60 + case 10: + case 11: + timingData->interlaced = true; + // 35, 36 2880x480p @ 60 + case 35: + case 36: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3432; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 248; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 240; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 64; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 25, 26 (2880)x576i @ 50 + case 25: + case 26: + timingData->interlaced = true; + // 37, 38 2880x576p @ 50 + case 37: + case 38: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3456; + timingData->axis[kDisplayAxisTypeHorizontal].active = 2880; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 256; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 272; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 48; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 39 1920x1080i @ 50 + case 39: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2304; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 168; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 184; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 32; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1250; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 120; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 45; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + + timingData->interlaced = true; + break; + // 40 1920x1080i @ 100 + case 40: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2640; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 528; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1250; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 120; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 45; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + + timingData->interlaced = true; + break; + // 41 1280x720p @ 100 + case 41: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1980; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 100<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 44, 45 720(1440)x576i @ 100 + case 44: + case 45: + timingData->interlaced = true; + // 42, 43 720x576p @ 100 + case 42: + case 43: + timingData->axis[kDisplayAxisTypeHorizontal].total = 864; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 64; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 68; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 12; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 100<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 46 1920x1280i @ 120 + case 46: + return -1; + // 47 1280x720p @ 120 + case 47: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1650; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 110; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 120<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 48, 49 720x480p @ 120 + case 48: + case 49: + timingData->axis[kDisplayAxisTypeHorizontal].total = 858; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 62; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 60; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 120<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 50, 51 720(1440)x480i @ 120 + case 50: + case 51: + return -1; + // 42, 43 720x576p @ 100 + case 52: + case 53: + timingData->axis[kDisplayAxisTypeHorizontal].total = 864; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 64; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 68; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 12; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 200<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 54, 55 720(1440)x576i @ 200 + case 54: + case 55: + return -1; + // 56, 57 720x480p @ 240 + case 56: + case 57: + timingData->axis[kDisplayAxisTypeHorizontal].total = 858; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 62; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 60; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 240<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 58, 59 720(1440)x480i @ 240 + case 58: + case 59: + return -1; + // more to come...too lazy right now + default: + return -1; + break; + } + + return 0; +} + +static int use_dimensions(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + int ret = -1; + debug(EDID, "Use dimensions %ux%u %uHz\n", horizontal, vertical, rate >> 16); + if (s_timing_support & kSupportFlagCVT) { + ret = use_dimensions_cvt(horizontal, vertical, rate); + } else if (s_timing_support & kSupportFlagGTF) { + ret = use_dimensions_gtf(horizontal, vertical, rate); + } + if (ret != 0) { + ret = use_dimensions_dmt(horizontal, vertical, rate); + } + return ret; +} + +static int use_dimensions_dmt(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + static const struct video_timing_data sDMTTimingInfo[] = { + {false, {{832, 640, 64, 96, 32, 0, 1}, {445, 350, 3, 60, 32, 85<<16, 0}} }, + {false, {{832, 640, 64, 96, 32, 0, 0}, {445, 400, 3, 41, 1, 85<<16, 1}} }, + {false, {{936, 720, 72, 108, 36, 0, 0}, {446, 400, 3, 42, 1, 85<<16, 1}} }, + {false, {{800, 640, 96, 48, 16, 0, 0}, {525, 480, 2, 33, 10, 60<<16, 0}} }, + {false, {{832, 640, 40, 128, 24, 0, 0}, {520, 480, 3, 28, 9, 72<<16, 0}} }, + {false, {{840, 640, 64, 120, 16, 0, 0}, {500, 480, 3, 16, 1, 75<<16, 0}} }, + {false, {{832, 640, 56, 80, 56, 0, 0}, {509, 480, 3, 25, 1, 85<<16, 0}} }, + {false, {{1024, 800, 72, 128, 24, 0, 1}, {625, 600, 2, 22, 1, 56<<16, 1}} }, + {false, {{1056, 800, 128, 88, 40, 0, 1}, {628, 600, 4, 23, 1, 60<<16, 1}} }, + {false, {{1040, 800, 120, 64, 56, 0, 1}, {666, 600, 6, 23, 37, 72<<16, 1}} }, + {false, {{1056, 800, 80, 160, 16, 0, 1}, {625, 600, 3, 21, 1, 75<<16, 1}} }, + {false, {{1048, 800, 64, 152, 32, 0, 1}, {631, 600, 3, 27, 1, 85<<16, 1}} }, + {false, {{960, 800, 32, 80, 48, 0, 1}, {636, 600, 4, 29, 3, 120<<16, 0}} }, + {false, {{1088, 848, 112, 112, 16, 0, 1}, {517, 480, 8, 23, 6, 60<<16, 1}} }, + {false, {{1344, 1024, 136, 160, 24, 0, 0}, {806, 768, 6, 29, 3, 60<<16, 0}} }, + {false, {{1328, 1024, 136, 144, 24, 0, 0}, {806, 768, 6, 29, 3, 70<<16, 0}} }, + {false, {{1312, 1024, 96, 176, 16, 0, 1}, {800, 768, 3, 28, 1, 75<<16, 1}} }, + {false, {{1376, 1024, 96, 208, 48, 0, 1}, {808, 768, 3, 36, 1, 85<<16, 1}} }, + {false, {{1600, 1152, 128, 256, 64, 0, 1}, {900, 864, 3, 32, 1, 75<<16, 1}} }, + {false, {{1650, 1280, 40, 220, 110, 0, 1}, {750, 720, 5, 20, 5, 60<<16, 1}} }, + {false, {{1664, 1280, 128, 192, 64, 0, 0}, {798, 768, 7, 20, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {805, 768, 7, 27, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {809, 768, 7, 31, 3, 85<<16, 1}} }, + {false, {{1680, 1280, 128, 200, 72, 0, 0}, {831, 800, 6, 22, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {838, 800, 6, 29, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {843, 800, 6, 34, 3, 85<<16, 1}} }, + {false, {{1800, 1280, 112, 312, 96, 0, 1}, {1000, 960, 3, 36, 1, 60<<16, 1}} }, + {false, {{1728, 1280, 160, 224, 64, 0, 1}, {1011, 960, 3, 47, 1, 85<<16, 1}} }, + {false, {{1688, 1280, 112, 248, 48, 0, 1}, {1066, 1024, 3, 38, 1, 60<<16, 1}} }, + {false, {{1688, 1280, 144, 248, 16, 0, 1}, {1066, 1024, 3, 38, 1, 75<<16, 1}} }, + {false, {{1728, 1280, 160, 224, 64, 0, 1}, {1072, 1024, 3, 44, 1, 85<<16, 1}} }, + {false, {{1792, 1360, 112, 256, 64, 0, 1}, {795, 768, 6, 18, 3, 60<<16, 1}} }, + {false, {{1792, 1366, 143, 213, 70, 0, 1}, {798, 768, 3, 24, 3, 60<<16, 1}} }, + {false, {{1864, 1400, 144, 232, 88, 0, 0}, {1089, 1050, 4, 32, 3, 60<<16, 1}} }, + {false, {{1896, 1400, 144, 248, 104, 0, 0}, {1099, 1050, 4, 42, 3, 75<<16, 1}} }, + {false, {{1912, 1400, 152, 256, 104, 0, 0}, {1105, 1050, 4, 48, 3, 85<<16, 1}} }, + {false, {{1904, 1440, 152, 232, 80, 0, 0}, {934, 900, 6, 25, 3, 60<<16, 1}} }, + {false, {{1936, 1440, 152, 248, 96, 0, 0}, {942, 900, 6, 33, 3, 75<<16, 1}} }, + {false, {{1952, 1440, 152, 256, 104, 0, 0}, {948, 900, 6, 39, 3, 85<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 60<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 65<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 70<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 75<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 85<<16, 1}} }, + {false, {{2240, 1680, 176, 280, 104, 0, 0}, {1089, 1050, 6, 30, 3, 60<<16, 1}} }, + {false, {{2272, 1680, 176, 296, 120, 0, 0}, {1099, 1050, 6, 40, 3, 75<<16, 1}} }, + {false, {{2288, 1680, 176, 304, 128, 0, 0}, {1105, 1050, 6, 46, 3, 85<<16, 1}} }, + {false, {{2448, 1792, 200, 328, 128, 0, 0}, {1394, 1344, 3, 46, 1, 60<<16, 1}} }, + {false, {{2456, 1792, 216, 352, 96, 0, 0}, {1417, 1344, 3, 69, 1, 75<<16, 1}} }, + {false, {{2528, 1856, 224, 352, 96, 0, 0}, {1439, 1392, 3, 43, 1, 60<<16, 1}} }, + {false, {{2560, 1856, 224, 352, 128, 0, 0}, {1500, 1392, 3, 104, 1, 75<<16, 1}} }, + {false, {{2200, 1920, 44, 148, 88, 0, 1}, {1125, 1080, 5, 36, 4, 60<<16, 1}} }, + {false, {{2592, 1920, 200, 336, 136, 0, 0}, {1245, 1200, 6, 36, 3, 60<<16, 1}} }, + {false, {{2608, 1920, 208, 344, 136, 0, 0}, {1255, 1200, 6, 46, 3, 75<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1262, 1200, 6, 53, 3, 85<<16, 1}} }, + {false, {{2600, 1920, 208, 344, 128, 0, 0}, {1500, 1440, 3, 56, 1, 60<<16, 1}} }, + {false, {{2640, 1920, 224, 352, 144, 0, 0}, {1500, 1440, 3, 56, 1, 75<<16, 1}} }, + {false, {{3504, 2560, 280, 472, 192, 0, 0}, {1658, 1600, 6, 49, 3, 60<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1672, 1600, 6, 63, 3, 75<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1682, 1600, 6, 73, 3, 85<<16, 1}} } + }; + + return use_dimensions_table(sDMTTimingInfo, (sizeof(sDMTTimingInfo) / sizeof(struct video_timing_data)), horizontal, vertical, rate); +} + +static int use_dimensions_cvt(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + static const struct video_timing_data sCVTTimingInfo[] = { + {false, {{816, 640, 64, 88, 24, 0, 0}, {423, 400, 6, 14, 3, 85<<16, 1}} }, + {false, {{800, 640, 64, 80, 16, 0, 0}, {500, 480, 4, 13, 3, 60<<16, 1}} }, + {false, {{816, 640, 64, 88, 24, 0, 0}, {504, 480, 4, 17, 3, 75<<16, 1}} }, + {false, {{816, 640, 64, 88, 24, 0, 0}, {507, 480, 4, 20, 3, 85<<16, 1}} }, + {false, {{1024, 800, 80, 112, 32, 0, 0}, {624, 600, 4, 17, 3, 60<<16, 1}} }, + {false, {{1040, 800, 80, 120, 40, 0, 0}, {625, 600, 4, 22, 3, 75<<16, 1}} }, + {false, {{1056, 800, 80, 128, 48, 0, 0}, {633, 600, 4, 26, 3, 85<<16, 1}} }, + {false, {{1328, 1024, 104, 152, 48, 0, 0}, {798, 768, 4, 23, 3, 60<<16, 1}} }, + {false, {{1360, 1024, 104, 168, 64, 0, 0}, {805, 768, 4, 30, 3, 75<<16, 1}} }, + {false, {{1376, 1024, 104, 176, 72, 0, 0}, {809, 768, 4, 34, 3, 85<<16, 1}} }, + {false, {{1536, 1152, 120, 192, 72, 0, 0}, {905, 864, 4, 34, 3, 75<<16, 1}} }, + {false, {{1664, 1280, 128, 192, 64, 0, 0}, {748, 720, 5, 20, 3, 60<<16, 1}} }, + {false, {{1664, 1280, 128, 192, 64, 0, 0}, {798, 768, 7, 20, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {805, 768, 7, 27, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {809, 768, 7, 31, 3, 85<<16, 1}} }, + {false, {{1680, 1280, 128, 200, 72, 0, 0}, {831, 800, 6, 22, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {838, 800, 6, 29, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {843, 800, 6, 34, 3, 85<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {996, 960, 4, 29, 3, 60<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {1011, 960, 4, 44, 3, 85<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {1063, 1024, 7, 29, 3, 60<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {1072, 1024, 7, 38, 3, 75<<16, 1}} }, + {false, {{1744, 1280, 136, 232, 96, 0, 0}, {1078, 1024, 7, 44, 3, 85<<16, 1}} }, + {false, {{1776, 1360, 136, 208, 72, 0, 0}, {798, 768, 5, 22, 3, 60<<16, 1}} }, + {false, {{1864, 1400, 144, 232, 88, 0, 0}, {1089, 1050, 4, 32, 3, 60<<16, 1}} }, + {false, {{1896, 1400, 144, 248, 104, 0, 0}, {1099, 1050, 4, 42, 3, 75<<16, 1}} }, + {false, {{1912, 1400, 152, 256, 104, 0, 0}, {1105, 1050, 4, 48, 3, 85<<16, 1}} }, + {false, {{1904, 1440, 152, 232, 80, 0, 0}, {934, 900, 6, 25, 3, 60<<16, 1}} }, + {false, {{1936, 1440, 152, 248, 96, 0, 0}, {942, 900, 6, 33, 3, 75<<16, 1}} }, + {false, {{1952, 1440, 152, 256, 104, 0, 0}, {948, 900, 6, 39, 3, 85<<16, 1}} }, + {false, {{2160, 1600, 168, 280, 112, 0, 0}, {1245, 1200, 4, 38, 3, 60<<16, 1}} }, + {false, {{2160, 1600, 168, 288, 120, 0, 0}, {1255, 1200, 4, 48, 3, 75<<16, 1}} }, + {false, {{2192, 1600, 168, 296, 128, 0, 0}, {1262, 1200, 4, 55, 3, 85<<16, 1}} }, + {false, {{2240, 1680, 176, 280, 104, 0, 0}, {1089, 1050, 6, 30, 3, 60<<16, 1}} }, + {false, {{2272, 1680, 176, 296, 120, 0, 0}, {1099, 1050, 6, 40, 3, 75<<16, 1}} }, + {false, {{2288, 1680, 176, 304, 128, 0, 0}, {1105, 1050, 6, 46, 3, 85<<16, 1}} }, + {false, {{2432, 1792, 192, 320, 128, 0, 0}, {1393, 1344, 4, 42, 3, 60<<16, 1}} }, + {false, {{2448, 1792, 192, 328, 136, 0, 0}, {1405, 1344, 4, 54, 3, 75<<16, 1}} }, + {false, {{2512, 1856, 200, 328, 128, 0, 0}, {1443, 1392, 4, 44, 3, 60<<16, 1}} }, + {false, {{2544, 1856, 200, 344, 144, 0, 0}, {1456, 1392, 4, 57, 3, 75<<16, 1}} }, + {false, {{2576, 1920, 200, 328, 128, 0, 0}, {1120, 1080, 5, 32, 3, 60<<16, 1}} }, + {false, {{2592, 1920, 200, 336, 136, 0, 0}, {1245, 1200, 6, 36, 3, 60<<16, 1}} }, + {false, {{2608, 1920, 208, 344, 136, 0, 0}, {1255, 1200, 6, 46, 3, 75<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1262, 1200, 6, 53, 3, 85<<16, 1}} }, + {false, {{2608, 1920, 208, 344, 136, 0, 0}, {1493, 1440, 4, 46, 3, 60<<16, 1}} }, + {false, {{2640, 1920, 208, 360, 152, 0, 0}, {1506, 1440, 4, 59, 3, 75<<16, 1}} }, + {false, {{3504, 2560, 280, 472, 192, 0, 0}, {1658, 1600, 6, 49, 3, 60<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1672, 1600, 6, 63, 3, 75<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1682, 1600, 6, 73, 3, 85<<16, 1}} } + }; + + return use_dimensions_table(sCVTTimingInfo, (sizeof(sCVTTimingInfo) / sizeof(struct video_timing_data)), horizontal, vertical, rate); +} + +static int use_dimensions_gtf(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + static const struct video_timing_data sGTFTimingInfo[] = { + {false, {{816, 640, 64, 88, 24, 0, 0}, {421, 400, 3, 17, 1, 85<<16, 1}} }, + {false, {{800, 640, 64, 80, 16, 0, 0}, {497, 480, 3, 13, 1, 60<<16, 1}} }, + {false, {{816, 640, 64, 88, 24, 0, 0}, {502, 480, 3, 18, 1, 75<<16, 1}} }, + {false, {{832, 640, 64, 96, 32, 0, 0}, {505, 480, 3, 21, 1, 85<<16, 1}} }, + {false, {{1024, 800, 80, 112, 32, 0, 0}, {622, 600, 3, 18, 1, 60<<16, 1}} }, + {false, {{1040, 800, 80, 120, 40, 0, 0}, {627, 600, 3, 23, 1, 75<<16, 1}} }, + {false, {{1056, 800, 88, 128, 40, 0, 0}, {630, 600, 3, 26, 1, 85<<16, 1}} }, + {false, {{1344, 1024, 104, 160, 56, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1360, 1024, 112, 168, 56, 0, 0}, {802, 768, 3, 30, 1, 75<<16, 1}} }, + {false, {{1376, 1024, 112, 176, 64, 0, 0}, {807, 768, 3, 35, 1, 85<<16, 1}} }, + {false, {{1552, 1152, 128, 200, 72, 0, 0}, {902, 864, 3, 34, 1, 75<<16, 1}} }, + {false, {{1664, 1280, 136, 192, 56, 0, 0}, {746, 720, 3, 22, 1, 60<<16, 1}} }, + {false, {{1680, 1280, 136, 200, 64, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {802, 768, 3, 30, 1, 75<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {807, 768, 3, 35, 1, 85<<16, 1}} }, + {false, {{1680, 1280, 136, 200, 64, 0, 0}, {828, 800, 3, 24, 1, 60<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {835, 800, 3, 31, 1, 75<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {840, 800, 3, 36, 1, 85<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {994, 960, 3, 30, 1, 60<<16, 1}} }, + {false, {{1744, 1280, 136, 232, 96, 0, 0}, {1008, 960, 3, 44, 1, 85<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {1060, 1024, 3, 32, 1, 60<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {1069, 1024, 3, 44, 1, 75<<16, 1}} }, + {false, {{1744, 1280, 136, 232, 96, 0, 0}, {1075, 1024, 3, 47, 1, 85<<16, 1}} }, + {false, {{1776, 1360, 144, 208, 64, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1800, 1366, 144, 216, 72, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1880, 1400, 152, 240, 88, 0, 0}, {1087, 1050, 3, 33, 1, 60<<16, 1}} }, + {false, {{1896, 1400, 152, 248, 96, 0, 0}, {1096, 1050, 3, 42, 1, 75<<16, 1}} }, + {false, {{1912, 1400, 152, 256, 104, 0, 0}, {1103, 1050, 3, 49, 1, 85<<16, 1}} }, + {false, {{1904, 1440, 152, 232, 80, 0, 0}, {932, 900, 3, 28, 1, 60<<16, 1}} }, + {false, {{1936, 1440, 152, 248, 96, 0, 0}, {940, 900, 3, 36, 1, 75<<16, 1}} }, + {false, {{1952, 1440, 160, 256, 96, 0, 0}, {945, 900, 3, 41, 1, 85<<16, 1}} }, + {false, {{2160, 1600, 176, 280, 104, 0, 0}, {1242, 1200, 3, 38, 1, 60<<16, 1}} }, + {false, {{2192, 1600, 176, 296, 120, 0, 0}, {1253, 1200, 3, 49, 1, 75<<16, 1}} }, + {false, {{2192, 1600, 176, 296, 120, 0, 0}, {1260, 1200, 3, 56, 1, 85<<16, 1}} }, + {false, {{2256, 1680, 184, 288, 104, 0, 0}, {1087, 1050, 3, 33, 1, 60<<16, 1}} }, + {false, {{2288, 1680, 184, 304, 120, 0, 0}, {1096, 1050, 3, 42, 1, 75<<16, 1}} }, + {false, {{2288, 1680, 184, 304, 120, 0, 0}, {1103, 1050, 3, 49, 1, 85<<16, 1}} }, + {false, {{2432, 1792, 192, 320, 128, 0, 0}, {1391, 1344, 3, 43, 1, 60<<16, 1}} }, + {false, {{2464, 1792, 200, 336, 136, 0, 0}, {1403, 1344, 3, 55, 1, 75<<16, 1}} }, + {false, {{2528, 1856, 200, 336, 136, 0, 0}, {1441, 1392, 3, 45, 1, 60<<16, 1}} }, + {false, {{2544, 1856, 200, 344, 144, 0, 0}, {1453, 1392, 3, 57, 1, 75<<16, 1}} }, + {false, {{2576, 1920, 208, 328, 120, 0, 0}, {1118, 1080, 3, 34, 1, 60<<16, 1}} }, + {false, {{2592, 1920, 208, 336, 128, 0, 0}, {1242, 1200, 3, 38, 1, 60<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1253, 1200, 3, 49, 1, 75<<16, 1}} }, + {false, {{2640, 1920, 208, 360, 152, 0, 0}, {1260, 1200, 3, 56, 1, 85<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1490, 1440, 3, 46, 1, 60<<16, 1}} }, + {false, {{2640, 1920, 208, 360, 152, 0, 0}, {1503, 1440, 3, 59, 1, 75<<16, 1}} }, + {false, {{3504, 2560, 280, 472, 192, 0, 0}, {1656, 1600, 3, 52, 1, 60<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1670, 1600, 3, 66, 1, 75<<16, 1}} }, + {false, {{3552, 2560, 288, 496, 208, 0, 0}, {1680, 1600, 3, 76, 1, 85<<16, 1}} } + }; + + return use_dimensions_table(sGTFTimingInfo, (sizeof(sGTFTimingInfo) / sizeof(struct video_timing_data)), horizontal, vertical, rate); +} + +static int use_dimensions_table(const struct video_timing_data * list, uint32_t count, uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + const struct video_timing_data * matching = NULL; + uint32_t roundRate = (rate + 0x8000) & 0xffff0000; + uint32_t index; + struct video_timing_data data; + + if ( !list || !count || !horizontal || !vertical || !rate ) + return -1; + + for (index=0; indexaxis[kDisplayAxisTypeHorizontal].active != horizontal ) + continue; + + if ( timing->axis[kDisplayAxisTypeVertical].active != vertical ) + continue; + + if ( (uint32_t) timing->axis[kDisplayAxisTypeVertical].sync_rate != roundRate ) + continue; + + matching = timing; + break; + } + + if ( !matching ) + return -1; + + bcopy(matching, &data, sizeof(data)); + data.axis[kDisplayAxisTypeVertical].sync_rate = rate; + return use_timings(&data); +} + +static int use_timings(struct video_timing_data *data) +{ + bool winner = false; + uint32_t width, height, rate, size, old_rate; + width = data->axis[kDisplayAxisTypeHorizontal].active; + height = data->axis[kDisplayAxisTypeVertical].active; + rate = data->axis[kDisplayAxisTypeVertical].sync_rate; + size = width * height * 4; // Assume RGBx8888 + + debug(SCORE, "Try timings %ux%u%c/%u\n", + width, height, data->interlaced ? 'i' : 'p', rate >> 16); + + // Reject timings we can't support or don't like. + if (dp_controller_validate_video(data) != 0) { + debug(SCORE, "Rejecting: bad timings\n"); + return -1; + } else if (s_restrict_h_active && s_restrict_v_active && + (width != s_restrict_h_active || height != s_restrict_v_active)) { + // Restricting to specific dimensions. + debug(SCORE, "Rejecting dimensions not matching %ux%u\n", + s_restrict_h_active, s_restrict_v_active); + return -1; + } else if (width > kMaxHorizontalActive) { + debug(SCORE, "Rejecting: horizontal active %u greater than %u\n", + width, kMaxHorizontalActive); + return -1; + } else if (size > DISPLAY_SIZE) { + debug(SCORE, "Rejecting: total size %u too big for buffer %zu bytes\n", + size, (size_t)DISPLAY_SIZE); + return -1; + } + + debug(SCORE, "Accepted\n"); + + // Score these new timings vs the best we have so far. Note than wider/taller + // scoring will only occur if restrict_edid() was not used. + if (s_have_timings) { + old_rate = s_best_timings.axis[kDisplayAxisTypeVertical].sync_rate; + } else { + old_rate = 0; + } + + if (!s_have_timings) { + winner = true; + debug(SCORE, "First candidate\n"); + } else if ((rate >= (59 << 16) && rate <= (61 << 16)) && + (old_rate < (59 << 16) || old_rate > (61 << 16))) { + winner = true; + debug(SCORE, "Preferring 60Hz to non-60Hz\n"); + } else if (width > s_best_timings.axis[kDisplayAxisTypeHorizontal].active) { + winner = true; + debug(SCORE, "Preferring wider\n"); + } else if (height > s_best_timings.axis[kDisplayAxisTypeVertical].active) { + winner = true; + debug(SCORE, "Preferring taller\n"); + } + + if (winner) { + s_have_timings = true; + bcopy(data, &s_best_timings, sizeof(s_best_timings)); + } + + return 0; +} + +static int verify_edid(EDID *edid, uint8_t *p_checksum) +{ + uint32_t index; + uint8_t sum; + + debug(EDID, "Validating EDID\n"); + + for (index = 0, sum = 0; index < sizeof(EDID); ++index) { + sum += ((uint8_t *) edid)[index]; + } + + debug(EDID, "EDID checksum of 0x%02x\n", sum); + + if (p_checksum) + *p_checksum = sum; + + return sum == 0 ? 0 : -1; +} + +static int get_edid(uint32_t offset, EDID *edid) +{ + int ret; + uint32_t tries = 0; + uint64_t timer_start; + + timer_start = system_time(); + + do { + uint8_t checksum; + ++tries; + ret = dp_controller_read_bytes_i2c(kI2CEdidDeviceAddr, offset, + (uint8_t *) edid, sizeof(EDID)); + if (ret) { + debug(EDID, "Failed to read EDID offset=0x%08x ret=0x%08x\n", offset, ret); + if (s_abort_edid) { + // Display is trying to shut down - don't delay it. + debug(ERROR, "EDID retry loop aborted\n"); + break; + } + task_sleep(kEdidRetryDelay); + } else { + ret = verify_edid(edid, &checksum); + debug(EDID, "Verify EDID offset=0x%08x ret=0x%08x checksum=0x%02x\n", offset, ret, checksum); + } + } while (ret != 0 && !time_has_elapsed(timer_start, kEdidRetryTimeout)); + + if (ret == 0) { + debug(EDID, "Got EDID after %d tries, %llu usecs\n", tries, system_time() - timer_start); + } else { + debug(ERROR, "Failed to get EDID after %llu usecs\n", system_time() - timer_start); + } + + return ret; +} + +static uint16_t read_le16(const void *data, uint32_t offset) +{ + const uint8_t *p = (const uint8_t *) data; + uint16_t result = p[offset]; + result |= ((uint16_t) p[offset + 1]) << 8; + return result; +} + +static uint32_t read_le32(const void *data, uint32_t offset) +{ + const uint8_t *p = (const uint8_t *) data; + uint32_t result = p[offset]; + result |= ((uint32_t) p[offset + 1]) << 8; + result |= ((uint32_t) p[offset + 2]) << 16; + result |= ((uint32_t) p[offset + 3]) << 24; + return result; +} + +#endif // WITH_HW_MCU diff --git a/drivers/displayport/rules.mk b/drivers/displayport/rules.mk new file mode 100644 index 0000000..36bf40a --- /dev/null +++ b/drivers/displayport/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2009 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += + +ALL_OBJS += \ + $(LOCAL_DIR)/controller.o \ + $(LOCAL_DIR)/device.o \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/process_edid.o diff --git a/drivers/flash_nand/OAM/EmbeddedIOP/WMRBuf.c b/drivers/flash_nand/OAM/EmbeddedIOP/WMRBuf.c new file mode 100644 index 0000000..fab17ac --- /dev/null +++ b/drivers/flash_nand/OAM/EmbeddedIOP/WMRBuf.c @@ -0,0 +1 @@ +// Empty file diff --git a/drivers/flash_nand/OAM/EmbeddedIOP/WMRFeatures.h b/drivers/flash_nand/OAM/EmbeddedIOP/WMRFeatures.h new file mode 100644 index 0000000..2519748 --- /dev/null +++ b/drivers/flash_nand/OAM/EmbeddedIOP/WMRFeatures.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +///// +// +// Whimory Feature Definitions +// +///// + +#include "WMRTypes.h" + +#ifndef _WMR_FEATURES_H_ +#define _WMR_FEATURES_H_ + +// Define the platform we're on +#define WMR_BUILDING_IBOOT (1) + +// Don't bother collect stats in read-only mode +//#define AND_COLLECT_STATISTICS (1) + +// Defined by platform, but they're all OK with 30 for now +#define FIL_MAX_ECC_CORRECTION (30) + +// ============================================================================= +// configurable preprocessor compilation control +// ============================================================================= + +// Set H2FMI_DEBUG below to 1 if you want to build for debugging (default +// to 0). +#define H2FMI_DEBUG 1 + +// Set H2FMI_TEST_HOOK below to 1 if you want to insert tests at the end +// of FIL_Init in iBoot (default to 0). +#define H2FMI_TEST_HOOK 0 + +// Set H2FMI_WAIT_USING_ISR to true if you want operations to wait for +// dma and bus events by hooking an interrupt service routine to the +// FMI interrupt vector; set to false for waiting using register +// polling with yield (default to true). +#define H2FMI_WAIT_USING_ISR 1 + +#define H2FMI_INSTRUMENT_BUS_1 0 + +// Change the constant below to 1 if you want to see all FMI +// subsystem register writes; note that doing so is likely to change +// timing and therefore behavior, so it should be a rare case that you +// would ever want to do this. In cases where you want to see just +// one or two writes, consider calling the 'h2fmi_dbg_wr' or +// 'h2fmi_dbg_wr8' function directly (default to 0). +#define H2FMI_TRACE_REG_WRITES 0 + +// Change the constant below to 1 if you want to see all FMI +// subsystem register reads; note that doing so is likely to change +// timing and therefore behavior, so it should be a rare case that you +// would ever want to do this. In cases where you want to see just +// one or two reads, consider calling the 'h2fmi_dbg_rd' or +// 'h2fmi_dbg_rd8' function directly (default to 0). +#define H2FMI_TRACE_REG_READS 0 + +// ============================================================================= +// fixed preprocessor compilation control +// ============================================================================= + +#define H2FMI_BOOTROM 0 +#define H2FMI_IOP 1 +#define H2FMI_IBOOT 0 +#define H2FMI_EFI 0 + +#define H2FMI_READONLY 0 +#endif /* _WMR_FEATURES_H_ */ + diff --git a/drivers/flash_nand/OAM/EmbeddedIOP/WMROAM.c b/drivers/flash_nand/OAM/EmbeddedIOP/WMROAM.c new file mode 100644 index 0000000..8ffeaf1 --- /dev/null +++ b/drivers/flash_nand/OAM/EmbeddedIOP/WMROAM.c @@ -0,0 +1,147 @@ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" + +#include +#include +#include +#include +#include +#include +#include + +void * +WMR_MALLOC(UInt32 nSize) +{ + void *p; + + p = memalign(nSize, CPU_CACHELINE_SIZE); + WMR_MEMSET(p, 0, nSize); + return p; +} + +BOOL32 +OAM_Init(void) +{ + return TRUE32; +} + +void OAM_Beep(UInt32 dwMs) +{ +} + +void WMR_FREE(void * ptr, UInt32 size) +{ + free(ptr); +} + +BOOL32 WMR_CHECK_BUFFER(const void * buffer, UInt32 length) +{ + return (((UInt32) buffer % CPU_CACHELINE_SIZE) == 0) ? TRUE32 : FALSE32; +} + +BOOL32 +WMR_FILL_STRUCT(void *pDstBuff, UInt32 *pdwDstBuffSize, const void *pSrcBuff, UInt32 dwSrcBuffSize) +{ + BOOL32 boolRes = TRUE32; + + if (!pDstBuff && pdwDstBuffSize) + { + // Just return the buffer size + *pdwDstBuffSize = dwSrcBuffSize; + } + else if (!pdwDstBuffSize || (*pdwDstBuffSize < dwSrcBuffSize)) + { + // Supplied buffer is too small + UInt32 dwPrintedSize = pdwDstBuffSize ? *pdwDstBuffSize : (UInt32) ~0; + WMR_PRINT(ERROR,"IOCtl on buffer of size %d with %d bytes of src data!\n", + dwPrintedSize, dwSrcBuffSize); + boolRes = FALSE32; + } + else + { + // We have a valid buffer pointer and buffer size + WMR_MEMCPY(pDstBuff, pSrcBuff, dwSrcBuffSize); + *pdwDstBuffSize = dwSrcBuffSize; + } + + return boolRes; +} + +void _WMR_PRINT(const char * format, ...) +{ + va_list args; + + // retrieve the variable arguments + va_start(args, format); + + vprintf(format, args); + + va_end(args); +} + +void +WMR_BEEP(UInt32 milliseconds) +{ + printf("WMR_BEEP\n"); +} + +const char * WMR_GETVERSION(void) +{ + static char version[] = "version string"; + + return version; +} + +BOOL32 +WMR_I_CAN_HAZ_DEBUGGER(void) +{ + return FALSE32; +} + +void WMR_WAIT_US(UInt64 microseconds) +{ + spin(microseconds); +} + +void WMR_SLEEP_US(UInt32 microseconds) +{ + task_sleep(microseconds); +} + +void WMR_YIELD(void) +{ + // Task yield is not available to libraries, so can't build it into Whimory + task_yield(); +} + +void +WMR_DEADLOOP(void) +{ + volatile int i = 1; + while (i) + { + (void) 0; + } +} + +void +WMR_CLOCK_RESET_DEVICE(UInt32 device) +{ + int clock; + + if( device == 0 ) + { + clock = CLK_FMI0; + } + else if( device == 1 ) + { + clock = CLK_FMI1; + } + else + { + panic("invalid WMR_CLOCK_RESET_DEVICE"); + } + + clock_reset_device(clock); +} diff --git a/drivers/flash_nand/OAM/EmbeddedIOP/WMRPlatform.h b/drivers/flash_nand/OAM/EmbeddedIOP/WMRPlatform.h new file mode 100644 index 0000000..a8eb20d --- /dev/null +++ b/drivers/flash_nand/OAM/EmbeddedIOP/WMRPlatform.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "ANDTypes.h" +#include "WMRFeatures.h" + +#include // memcmp +#include // panic +#include // cache +#include // ticks + +#ifndef _WMR_PLATFORM_H_ +#define _WMR_PLATFORM_H_ + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_LOG2 +// +// Returns the floor(log2) of the given number +// +#define WMR_LOG2(x) (31UL - __builtin_clz((UInt32)(x))) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_MEMSET +// WMR_MEMCPY +// WMR_MEMCMP +// +// Standard memory operations (libraries where available) +// + +#define WMR_MEMSET(dest, pattern, length) memset((dest), (pattern), (length)) +#define WMR_MEMCPY(dest, src, length) memcpy((dest), (src), (length)) +#define WMR_MEMCMP(buf1, buf2, length) memcmp((buf1), (buf2), (length)) +#define WMR_STRLEN(str) strlen((str)) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_ASSERT +// +// Print an error and panic if the given condition is not true +// + +# define WMR_ASSERT(_expr) \ + do { \ + if (__builtin_expect(!(_expr), 0)) \ + panic("WMR_ASSERT failed:(%s) %s:%u", \ + #_expr, __FILE__, __LINE__); \ + } while(0); + + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_PANIC +// +// Reset the system +// +# define WMR_PANIC(fmt, ...) \ + panic("WMR_PANIC: " #fmt " %s:%u", \ + ## __VA_ARGS__, __FILE__, __LINE__) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_PREPARE_WRITE_BUFFER +// +// Call before an outgoing I/O operation to ensure cache coherency +// + +#define WRITE_PREP_CACHE_CMD (CACHE_CLEAN) + +#if (defined(WMR_USE_FULL_CACHE_FLUSH) && WMR_USE_FULL_CACHE_FLUSH) +#define WMR_PREPARE_WRITE_BUFFER(buf, length) \ + platform_cache_operation(WRITE_PREP_CACHE_CMD, 0, 0) +#else //WMR_USE_FULL_CACHE_FLUSH +#if WMR_DEBUG +#define WMR_PREPARE_WRITE_BUFFER(buf, length) \ + do{ \ + WMR_ASSERT(0 == ((UInt32)(buf) % CPU_CACHELINE_SIZE)); \ + platform_cache_operation(WRITE_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE));\ + }while(0) +#else +#define WMR_PREPARE_WRITE_BUFFER(buf, length) \ + platform_cache_operation(WRITE_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE)) +#endif// !WMR_DEBUG +#endif // !WMR_USE_FULL_CACHE_FLUSH + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_PREPARE_READ_BUFFER +// +// Call before an incoming I/O operation to ensure cache coherency +// +// Note: On the IOP, we only prepare aligned read buffers from the host, so we +// shouldn't have to actually clean any dirty lines +#define READ_PREP_CACHE_CMD (CACHE_CLEAN | CACHE_INVALIDATE) + +#if (defined(WMR_USE_FULL_CACHE_FLUSH) && WMR_USE_FULL_CACHE_FLUSH) +#define WMR_PREPARE_READ_BUFFER(buf, length) \ + platform_cache_operation(READ_PREP_CACHE_CMD, 0, 0) +#else //WMR_USE_FULL_CACHE_FLUSH +#if WMR_DEBUG +#define WMR_PREPARE_READ_BUFFER(buf, length) \ + do{ \ + WMR_ASSERT(0 == ((UInt32)(buf) % CPU_CACHELINE_SIZE)); \ + platform_cache_operation(READ_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE));\ + }while(0) +#else +#define WMR_PREPARE_READ_BUFFER(buf, length) \ + platform_cache_operation(READ_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE)) +#endif// !WMR_DEBUG +#endif // !WMR_USE_FULL_CACHE_FLUSH + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_COMPLETE_READ_BUFFER +// +// Call after an incoming I/O operation to ensure cache coherency +// +// Note: On the IOP, we only prepare aligned read buffers from the host, so we +// shouldn't have to actually clean any dirty lines +#define WMR_COMPLETE_READ_BUFFER(buf, length) \ + WMR_PREPARE_READ_BUFFER(buf, length) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_GET_TICKS_PER_US +// +// Return the number of native ticks (as returned from WMR_CLOCK_NATIVE) per +// microsecond. +// + +// UInt32 +#define WMR_GET_TICKS_PER_US() (timer_get_tick_rate() / 1000000UL) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CLOCK_NATIVE +// +// Get the current system time in microseconds to be passed to +// WMR_HAS_TIME_ELAPSED_US and WMR_HAS_TIME_ELAPSED_MS, but NOT +// WMR_HAS_TIME_ELAPSED_TICKS +// + +// UInt64 +#define WMR_CLOCK_NATIVE() system_time() + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CLOCK_TICKS +// +// Get the current system time in ticks (suitable for WMR_HAS_TIME_ELAPSED_TICKS) +// + +//UInt64 +#define WMR_CLOCK_TICKS() timer_get_ticks() + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_HAS_TIME_ELAPSED_US +// +// Supply a start timestamp from WMR_CLOCK_NATIVE to determine if the given +// time has elapsed +// + +//UInt64 startTicks, UInt64 elapsedUS +#define WMR_HAS_TIME_ELAPSED_US(startTicks, elapsedUS) \ + (time_has_elapsed((startTicks), (elapsedUS)) ? TRUE32 : FALSE32) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_HAS_TIME_ELAPSED_TICKS +// +// Supply a start timestamp from WMR_CLOCK_NATIVE to determine if the given +// time has elapsed. + +//UInt64 startTicks, UInt64 elapsedTicks +#define WMR_HAS_TIME_ELAPSED_TICKS(startTicks, elapsedTicks) \ + ((timer_get_ticks() - (startTicks)) > (elapsedTicks) ? TRUE32 : FALSE32) + + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_ENTER_CRITICAL_SECTION +// +// Disable pre-emption, reference counted (safe to call in interrupt) + +#define WMR_ENTER_CRITICAL_SECTION() enter_critical_section() + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_EXIT_CRITICAL_SECTION +// +// Enable pre-emption, reference counted (safe to call in interrupt) + +#define WMR_EXIT_CRITICAL_SECTION() exit_critical_section() + +#endif /* _WMR_PLATFORM_H_ */ + diff --git a/drivers/flash_nand/OAM/EmbeddedIOP/WMRTypes.h b/drivers/flash_nand/OAM/EmbeddedIOP/WMRTypes.h new file mode 100644 index 0000000..7be32ef --- /dev/null +++ b/drivers/flash_nand/OAM/EmbeddedIOP/WMRTypes.h @@ -0,0 +1,42 @@ +#ifndef _WMR_TYPES_H_ +#define _WMR_TYPES_H_ + +# include +# include "spTypes.h" + +/*****************************************************************************/ +/* Basic Types */ +/*****************************************************************************/ + +typedef UInt32 BOOL32; + +/*****************************************************************************/ +/* Basic Constants */ +/*****************************************************************************/ + +#define FALSE32 ((BOOL32)0) +#define TRUE32 ((BOOL32)1) + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +# define __align(_x) +/*****************************************************************************/ +/* Basic Compiler Flags */ +/*****************************************************************************/ + +#define INLINE __inline + +#ifdef DEBUG_BUILD +#define WMR_DEBUG (1) +#else +#define WMR_RELEASE (1) +#endif + +#endif /* _WMR_TYPES_H_ */ + diff --git a/drivers/flash_nand/OAM/WMRBuf.h b/drivers/flash_nand/OAM/WMRBuf.h new file mode 100644 index 0000000..93b2b95 --- /dev/null +++ b/drivers/flash_nand/OAM/WMRBuf.h @@ -0,0 +1,35 @@ +#ifndef __WMR_BUF_H__ +#define __WMR_BUF_H__ + +#include "WMRFeatures.h" +#include "WMRTypes.h" +#include "WMRBufTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +// Variables +extern WMR_BufZoneList_t WMR_BufZoneList; + + +// Functions +extern void WMR_Buf_Init(void); // module-level initialization + +extern void *WMR_Buf_Alloc(WMR_BufZone_t *zone, UInt32 size); +extern void *WMR_Buf_Alloc_ForDMA(WMR_BufZone_t *zone, UInt32 size); + +extern void WMR_BufZone_Init(WMR_BufZone_t *zone); +extern BOOL32 WMR_BufZone_FinishedAllocs(WMR_BufZone_t *zone); +extern void WMR_BufZone_Rebase(WMR_BufZone_t *zone, void** buf); +extern void WMR_BufZone_FinishedRebases(WMR_BufZone_t *zone); +extern void WMR_BufZone_Free(WMR_BufZone_t *zone); +extern UInt32 WMR_BufZone_FindDescriptor(UInt8* buf, void **des); // returns offset + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __WMR_BUF_H__ diff --git a/drivers/flash_nand/OAM/WMROAM.h b/drivers/flash_nand/OAM/WMROAM.h new file mode 100644 index 0000000..9c51f54 --- /dev/null +++ b/drivers/flash_nand/OAM/WMROAM.h @@ -0,0 +1,329 @@ +///// +// +// OS Adaptation Module API +// +///// +#include "ANDTypes.h" +#include "WMRFeatures.h" +#include "WMRPlatform.h" + +#ifndef _WMR_OAM_H_ +#define _WMR_OAM_H_ + +#define NUMELEMENTS(x) (sizeof(x) / sizeof((x)[0])) +#define ROUNDDOWNTO(num, gran) ((num) - ((num) % (gran))) +#define ROUNDUPTO(num, gran) ((((num) + (gran) - 1) / (gran)) * (gran)) +#define IS_ALIGNED_TO(addr, align) (((UInt32)(addr)) % (align) == 0) +#define IS_ADDRESS_IN_RANGE(addr, start, end) \ + (((addr) >= (start) && (addr) < (end)) ? TRUE32 : FALSE32) + +#define WMR_MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define WMR_MAX(x, y) (((x) < (y)) ? (y) : (x)) + +#define WMR_CASSERT(x, name) typedef char __WMR_CASSERT_##name[(x) ? 1 : -1] +#define WMR_OFFSETOF(type, field) ((size_t)(&((type *)0)->field)) + +// Print levels +// Use only the last word in a WMR_PRINT call (e.g. ALWAYS for WMR_PRINT_ALWAYS) +#define WMR_PRINT_ALWAYS (1UL << 0) + +#define WMR_PRINT_INIT (1UL << 1) +#define WMR_PRINT_IRQ (1UL << 2) +#define WMR_PRINT_CLOCK (1UL << 3) +#define WMR_PRINT_POWER (1UL << 4) +#define WMR_PRINT_ALIGN (1UL << 5) +#define WMR_PRINT_BUFFER (1UL << 6) +#define WMR_PRINT_FACTORY (1UL << 7) +#define WMR_PRINT_QUAL (1UL << 8) + // WMR_PRINT_QUAL_FATAL allows simulator panics +#define WMR_PRINT_QUAL_FATAL (WMR_PRINT_QUAL | WMR_PRINT_ERROR) + +#define WMR_PRINT_READ (1UL << 10) +#define WMR_PRINT_WRITE (1UL << 11) +#define WMR_PRINT_ERASE (1UL << 12) +#define WMR_PRINT_UECC_PANIC (1UL << 13) + +#define WMR_PRINT_FTL (1UL << 20) +#define WMR_PRINT_VFL (1UL << 21) +#define WMR_PRINT_FIL (1UL << 22) +#define WMR_PRINT_FTLWARN (1UL << 23) +#define WMR_PRINT_VFLWARN (1UL << 24) +#define WMR_PRINT_EXAM (1UL << 25) + +#define WMR_PRINT_CRYPTO (1UL << 27) + +#define WMR_PRINT_INF (1UL << 28) +#define WMR_PRINT_LOG (1UL << 29) +#define WMR_PRINT_MISC (1UL << 30) +#define WMR_PRINT_ERROR (1UL << 31) + +#define WMR_PRINT_LEVEL (WMR_PRINT_ALWAYS | WMR_PRINT_INIT | WMR_PRINT_ERROR | WMR_PRINT_FACTORY | WMR_PRINT_QUAL | WMR_PRINT_VFLWARN) + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +//////////////////////////////////////////////////////////////////////////////// +// +// OAM_Init +// +// Call *once* before any use of WMR or OAM functions +// +BOOL32 OAM_Init(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// gWhimoryInitParameters +// +// Bitmask of initialization parameters to WMR_Init() +// +extern UInt32 gWhimoryInitParameters; + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_SCM_VERSION +// +// Get the SCM changelist of this build +// +UInt32 WMR_SCM_VERSION(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_BUILD_NUMBER +// +// Get the build number of this build +// +UInt32 WMR_BUILD_NUMBER(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_PRINT +// +// Use WMR_PRINT_XXX defines to describe your print type +// +#define TEXT(x) x + +#if (defined (WMR_DEBUG) && WMR_DEBUG) +#define WMR_DBG_PRINT(x) { _WMR_PRINT x; } +#define WMR_RTL_PRINT(x) { _WMR_PRINT x; } +#else +#define WMR_DBG_PRINT(x) +#define WMR_RTL_PRINT(x) { _WMR_PRINT x; } +#endif + +#if (defined(CC_NO_VA_ARGS) && !CC_NO_VA_ARGS) +#define WMR_PRINT(type, format, ...) \ + do { \ + if (WMR_PRINT_ ## type & WMR_PRINT_LEVEL) { \ + _WMR_PRINT("[NAND] %s:%d " format "", __FUNCTION__, __LINE__, __VA_ARGS__); } \ + } while (0) +#else //CC_NO_VA_ARGS +#define WMR_PRINT(type, format, args ...) \ + do { \ + if (WMR_PRINT_ ## type & WMR_PRINT_LEVEL) { \ + _WMR_PRINT("[NAND] %s:%d " format "", __FUNCTION__, __LINE__, ## args); } \ + } while (0) +#endif //CC_NO_VA_ARGS + +void _WMR_PRINT(const char * format, ...); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_MALLOC +// +// Allocate a WMR internal buffer (cache aligned & padded) +// +void *WMR_MALLOC(UInt32 size); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_FREE +// +// Release internal buffer +// +void WMR_FREE(void * ptr, UInt32 size); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_BOOT_MALLOC +// +// Allocate up to one boot-time-only buffer that will be freed with +// WMR_BOOT_FREE() before the NAND driver finishes opening +// +// The size argument is required. The incoming integer value is the minimum +// required size. The outgoing value is the actual size of the buffer. +// +void *WMR_BOOT_MALLOC(UInt32 *size); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_BOOT_FREE +// +// Free the buffer allocated by WMR_BOOT_MALLOC() +// +void WMR_BOOT_FREE(void * ptr); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CHECK_BUFFER +// +// Check if a given buffer is same for I/O DMA +// +BOOL32 WMR_CHECK_BUFFER(const void * buffer, UInt32 length); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_FILL_STRUCT +// +// Safely fill an ioctl buffer. Returns false if dest buffer size is too small +// or unspecified +// + BOOL32 WMR_FILL_STRUCT(void *pDstBuff, UInt32 *pdwDstBuffSize, const void *pSrcBuff, UInt32 dwSrcBuffSize); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_GETVERSION +// +// gets version string (will be used for signature +// +const char * WMR_GETVERSION(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_I_CAN_HAZ_DEBUGGER +// +// indictes whether a unit is capable of being debugged +// +BOOL32 WMR_I_CAN_HAZ_DEBUGGER(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_BEEP +// +// Use a piezo sound (if available) to alert the user to an error +// +void WMR_BEEP(UInt32 milliseconds); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_DEADLOOP +// +// Alert the user that the system has stopped and deadloop +// +// +void WMR_DEADLOOP(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CHKSUM +// +// Calculate a checksum on the given buffer +// +UInt32 WMR_CHKSUM(const void * buf, UInt32 length); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_WAIT_US +// +// Wait the given number of microseconds (may spin or deschedule) +// +void WMR_WAIT_US(UInt64 microseconds); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_SLEEP_US +// +// Sleep the given number of microseconds. On threading/tasking systems, this +// relinquishes cpu control to the scheduler. On simpler systems, this simply +// waits the specified amount of time. +// +void WMR_SLEEP_US(UInt32 microseconds); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_YIELD +// +// Yield cpu control to the scheduler on threading/tasking systems. On simpler +// systems, this simply returns immediately. +// +void WMR_YIELD(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_BUS_FREQ_MHZ +// +// Return the minimum and maximum speeds that the system bus connected to the +// the FMC may operate during NAND accesses +// +void WMR_BUS_FREQ_MHZ(UInt32 * minClockMHz, UInt32 * maxClockMHz); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_BUS_FREQ_HZ +// +// Return a precise version of the fastest operating frequency of the FMC +// +UInt32 WMR_BUS_FREQ_HZ(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_GET_SIGNATURE_MAJOR_VER +// +// Return signature byte indicating the major version +// +UInt8 WMR_GET_SIGNATURE_MAJOR_VER(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_GET_SIGNATURE_LAYOUT +// +// Return signature byte indicating the minor version +// +UInt8 WMR_GET_SIGNATURE_MINOR_VER(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_ACQUIRE_LOCK +// +// Acquire a lock allocated to the NAND driver +// +void WMR_ACQUIRE_LOCK(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_RELEASE_LOCK +// +// Releas a lock acquired through WMR_ACQUIRE_LOCK +// +void WMR_RELEASE_LOCK(void); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CLOCK_GATE +// +// Gates/Ungates the clock for device +// +void WMR_CLOCK_GATE(UInt32 device, BOOL32 enable); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_DLL_CLOCK_GATE +// +// Gates/Ungates the clock for NAND DLL +// +void WMR_DLL_CLOCK_GATE(BOOL32 enable); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CLOCK_RESET_DEVICE +// +// Clock reset device +// +void WMR_CLOCK_RESET_DEVICE(UInt32 device); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _WMR_OAM_H_ */ + diff --git a/drivers/flash_nand/OAM/iBoot/WMRBuf.c b/drivers/flash_nand/OAM/iBoot/WMRBuf.c new file mode 100644 index 0000000..1492d3a --- /dev/null +++ b/drivers/flash_nand/OAM/iBoot/WMRBuf.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include + + +// Variable instantiations + +WMR_BufZoneList_t WMR_BufZoneList; + + +// Functions + +static void ZoneList_Link(WMR_BufZone_t *zone) +{ + // NOP +} + + +static void ZoneList_Unlink(WMR_BufZone_t *zone) +{ + // NOP +} + + +extern void WMR_Buf_Init() +{ + // NOP +} + + +void *WMR_Buf_Alloc(WMR_BufZone_t *zone, UInt32 size) +{ + // Only need cache-line alignment, so pass it through to the other allocator + return WMR_Buf_Alloc_ForDMA(zone, size); +} + + +void *WMR_Buf_Alloc_ForDMA(WMR_BufZone_t *zone, UInt32 size) +{ + void *ret; + UInt32 oldTotal; + + WMR_ASSERT(BZS_ALLOC == zone->state); + + // Align alloc offset + oldTotal = zone->totalAlloc; + zone->totalAlloc = ROUNDUPTO(zone->totalAlloc, CPU_CACHELINE_SIZE); + zone->waste += (zone->totalAlloc - oldTotal); + + // Set up offset pointer + ret = (void*)zone->totalAlloc; + + // Move allocator along + zone->totalAlloc += size; + zone->numAllocs++; + + return ret; +} + + +void WMR_BufZone_Init(WMR_BufZone_t *zone) +{ + zone->baseAddr = NULL; + zone->maxAddr = NULL; + zone->totalAlloc = 0; + zone->numAllocs = 0; + zone->numRebases = 0; + zone->waste = 0; + zone->state = BZS_ALLOC; + + ZoneList_Link(zone); +} + + +BOOL32 WMR_BufZone_FinishedAllocs(WMR_BufZone_t *zone) +{ + UInt8 *buf; + + WMR_ASSERT(BZS_ALLOC == zone->state); + + // Allocate buffer + zone->totalAlloc = ROUNDUPTO(zone->totalAlloc, CPU_CACHELINE_SIZE); + buf = WMR_MALLOC(zone->totalAlloc); + if (NULL == buf) + { + return FALSE32; + } + + // Update zone + zone->baseAddr = buf; + zone->maxAddr = zone->baseAddr + zone->totalAlloc; + zone->state = BZS_FINISHED; + + return TRUE32; +} + + +void WMR_BufZone_Rebase(WMR_BufZone_t *zone, void** buf) +{ + *buf = (void*)(zone->baseAddr + (UInt32)*buf); + zone->numRebases++; +} + + +void WMR_BufZone_FinishedRebases(WMR_BufZone_t *zone) +{ + WMR_ASSERT(zone->numAllocs == zone->numRebases); +} + + +void WMR_BufZone_Free(WMR_BufZone_t *zone) +{ + if (zone->baseAddr) { + WMR_FREE(zone->baseAddr, zone->totalAlloc); + } + + zone->baseAddr = NULL; + zone->maxAddr = NULL; + zone->totalAlloc = 0; + zone->state = BZS_INIT; + + ZoneList_Unlink(zone); +} + +// This function is meaningless on non-Darwin targets +//UInt32 WMR_BufZone_FindDescriptor(UInt8* buf, void **des) // returns offset diff --git a/drivers/flash_nand/OAM/iBoot/WMRBufTypes.h b/drivers/flash_nand/OAM/iBoot/WMRBufTypes.h new file mode 100644 index 0000000..dbd7aec --- /dev/null +++ b/drivers/flash_nand/OAM/iBoot/WMRBufTypes.h @@ -0,0 +1,41 @@ +#ifndef __WMR_BUFTYPES_H__ +#define __WMR_BUFTYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// Types +typedef enum { + BZS_INIT, + BZS_ALLOC, + BZS_FINISHED, + BZS_FREE, +} WMR_BZS_State_e; + +typedef struct { + UInt8* baseAddr; + UInt8* maxAddr; + + UInt32 totalAlloc; + UInt32 numAllocs; + UInt32 numRebases; + UInt32 waste; + + WMR_BZS_State_e state; +} WMR_BufZone_t; + + +typedef struct { +} WMR_BufZoneList_t; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __WMR_BUFTYPES_H__ + + diff --git a/drivers/flash_nand/OAM/iBoot/WMRFeatures.h b/drivers/flash_nand/OAM/iBoot/WMRFeatures.h new file mode 100644 index 0000000..b241933 --- /dev/null +++ b/drivers/flash_nand/OAM/iBoot/WMRFeatures.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +///// +// +// Whimory Feature Definitions +// +///// + + +#include "WMRTypes.h" + +#ifndef _WMR_FEATURES_H_ +#define _WMR_FEATURES_H_ + +// Define the platform we're on +#define WMR_BUILDING_IBOOT (1) +// Allow yaFTL to open +#define AND_SUPPORT_YAFTL (1) +// Allow FTL to open +#define AND_SUPPORT_LEGACY_FTL (0) +#define AND_SUPPORT_LEGACY_VFL (0) +#define PPN_ENABLE_RMA_MODE (1) + +#define AND_MAX_SPECIAL_BLOCKS (120) + +//#define WMR_FIL_TEST_ENABLED (1) + +#if (defined(WMR_DEBUG) && WMR_DEBUG) && \ + (defined(PRODUCT_IBOOT) && PRODUCT_IBOOT) && \ + (defined(WMR_FIL_TEST_ENABLED) && WMR_FIL_TEST_ENABLED) +// Allow writes on H2 and H3 DEBUG-ONLY iBoot builds to enable the FIL interface test +#define AND_COLLECT_STATISTICS (1) +#else +// Disallow write and erase operations to block device as a bootloader +#define AND_READONLY (1) +#endif +#ifndef ENABLE_L2V_TREE +#define ENABLE_L2V_TREE (0) +#endif + +// Don't bother collect stats in read-only mode +//#define AND_COLLECT_STATISTICS (1) +// Use polling (instead of interrupts) +#define BUILDING_SINGLETASKING (1) + +//Should we use line-wise or full-cache operations +#if (defined(PLATFORM_S5L8720X) && PLATFORM_S5L8720X) +// M2 products shipped with full-cache flushing +#define WMR_USE_FULL_CACHE_FLUSH (1) +#endif + +#if (defined(WITH_NAND_BOOT) && WITH_NAND_BOOT) +// Boot-from-nand products use boot block +#define AND_SUPPORT_FIL_BOOT_PAGES (1) +#else +// Don't write a boot block, because this platform won't use it +#define AND_SUPPORT_FIL_BOOT_PAGES (0) +#endif + +// Create feature code for NVRAM support. +#if ((defined(WITH_NAND_NVRAM) && WITH_NAND_NVRAM) || (defined(WITH_EFFACEABLE_NAND) && WITH_EFFACEABLE_NAND)) +#define AND_SUPPORT_NVRAM (1) +#else +#define AND_SUPPORT_NVRAM (0) +#endif + +// Create feature code for firmware area support. +#if (defined(WITH_NAND_FIRMWARE) && WITH_NAND_FIRMWARE) +#define AND_SUPPORT_FW_AREA (1) +#else +#define AND_SUPPORT_FW_AREA (0) +#endif + + +// Allow FIL layer to be built without support for block device. +#if (defined(WITH_NAND_FILESYSTEM) && WITH_NAND_FILESYSTEM) +#define AND_SUPPORT_BLOCK_STORAGE (1) +#else +#define AND_SUPPORT_BLOCK_STORAGE (0) +#endif + +// Build just enough to support boot-from-nand but not full block storage support. +#if (!AND_SUPPORT_BLOCK_STORAGE && WITH_NAND_BOOT) +#define AND_FPART_ONLY (1) +#else +#define AND_FPART_ONLY (0) +#endif + +// Sanity check +#if (defined (AND_SUPPORT_2ND_BOOTLOADER) && AND_SUPPORT_2ND_BOOTLOADER && defined (AND_SIGNATURE_IN_BLOCK_ZERO) && AND_SIGNATURE_IN_BLOCK_ZERO) +#error "AND_SUPPORT_2ND_BOOTLOADER & AND_SIGNATURE_IN_BLOCK_ZERO can't both be defined" +#endif + +// Defined by platform, but they're all OK with 30 for now +#define FIL_MAX_ECC_CORRECTION (30) + +#if (!defined(AND_READONLY) && WMR_BUILDING_IBOOT) +//#error iBoot nand driver does not support writes +#endif + +// ============================================================================= +// configurable preprocessor compilation control +// ============================================================================= + +// Set H2FMI_DEBUG below to 1 if you want to build for debugging (default +// to 0). +#define WMR_IBOOT_WRITE_ENABLE 0 +#define H2FMI_DEBUG 0 + +// Set H2FMI_TEST_HOOK below to 1 if you want to insert tests at the end +// of FIL_Init in iBoot (default to 0). +#define H2FMI_TEST_HOOK 0 + +// Set H2FMI_WAIT_USING_ISR to true if you want operations to wait for +// dma and bus events by hooking an interrupt service routine to the +// FMI interrupt vector; set to false for waiting using register +// polling with yield (default to true). +#if !(defined(AND_READONLY)) || WITH_NAND_NVRAM || WITH_NAND_FIRMWARE || WITH_EFFACEABLE_NAND +// Disable ISR for more efficient deadstripping +#define H2FMI_WAIT_USING_ISR 1 +#endif + +// Change the constant below to 1 if you want to see all FMI +// subsystem register writes; note that doing so is likely to change +// timing and therefore behavior, so it should be a rare case that you +// would ever want to do this. In cases where you want to see just +// one or two writes, consider calling the 'h2fmi_dbg_wr' or +// 'h2fmi_dbg_wr8' function directly (default to 0). +#define H2FMI_TRACE_REG_WRITES 0 + +// Change the constant below to 1 if you want to see all FMI +// subsystem register reads; note that doing so is likely to change +// timing and therefore behavior, so it should be a rare case that you +// would ever want to do this. In cases where you want to see just +// one or two reads, consider calling the 'h2fmi_dbg_rd' or +// 'h2fmi_dbg_rd8' function directly (default to 0). +#define H2FMI_TRACE_REG_READS 0 + +// ============================================================================= +// fixed preprocessor compilation control +// ============================================================================= + +#if (defined (WITH_HW_BOOTROM_NAND) && WITH_HW_BOOTROM_NAND) +#define H2FMI_BOOTROM 1 +#else +#define H2FMI_BOOTROM 0 +#endif + +#define H2FMI_IOP 0 +#define H2FMI_IBOOT 1 +#define H2FMI_EFI 0 + +// Always build SecureROM read-only. +#if (H2FMI_BOOTROM) +#define H2FMI_READONLY 1 +// Otherwise, ignore nand driver read-only configuration in iBoot +// debug builds so that erase/write are available for use in testing +// read operations. +#elif (H2FMI_IBOOT && defined(AND_READONLY) && H2FMI_DEBUG) +#define H2FMI_READONLY 0 +// Otherwise, mirror nand driver configuration in iBoot. +#elif (defined(AND_READONLY)) +#define H2FMI_READONLY 1 +#else +#define H2FMI_READONLY 0 +#endif + +#define DEFAULT_OAM_BOOT_BUFFER_SIZE (0x800000) // 8MB + +#define H2FMI_ALLOW_MULTIS (1) + +#endif /* _WMR_FEATURES_H_ */ + diff --git a/drivers/flash_nand/OAM/iBoot/WMROAM.c b/drivers/flash_nand/OAM/iBoot/WMROAM.c new file mode 100644 index 0000000..b031271 --- /dev/null +++ b/drivers/flash_nand/OAM/iBoot/WMROAM.c @@ -0,0 +1,254 @@ +#include "WMROAM.h" + +#include +#include + +#include +#include +#include +#include +#include + +UInt32 gWhimoryInitParameters = +#if (defined(WITH_BLOCK_ZERO_SIGNATURE) && WITH_BLOCK_ZERO_SIGNATURE) +WMR_INIT_SIGNATURE_IN_BLOCKZERO | +#endif +0; + +static UInt32 boot_buffer_size = DEFAULT_OAM_BOOT_BUFFER_SIZE; +static void * boot_buffer = NULL; + +void * +WMR_MALLOC(UInt32 nSize) +{ + void *p; + + p = memalign(nSize, CPU_CACHELINE_SIZE); + WMR_MEMSET(p, 0, nSize); + return p; +} + +void* +WMR_BOOT_MALLOC(UInt32 *size) +{ + WMR_ASSERT(NULL != size); + WMR_ASSERT(NULL == boot_buffer); // only one allocation allowed + + if (*size <= boot_buffer_size) + { + boot_buffer = malloc(boot_buffer_size); + WMR_MEMSET(boot_buffer, 0, boot_buffer_size); + } + *size = boot_buffer_size; + return boot_buffer; +} + + +void +WMR_BOOT_FREE(void * ptr) +{ + WMR_ASSERT(ptr == boot_buffer); + free(ptr); + boot_buffer = NULL; +} + + +BOOL32 +OAM_Init(void) +{ + return TRUE32; +} + +void OAM_Beep(UInt32 dwMs) +{ +} + +void WMR_FREE(void * ptr, UInt32 size) +{ + free(ptr); +} + +BOOL32 WMR_CHECK_BUFFER(const void * buffer, UInt32 length) +{ +#if (defined(WMR_DEBUG) && WMR_DEBUG) + if (IS_ALIGNED_TO(buffer, CPU_CACHELINE_SIZE) && + IS_ALIGNED_TO(length, CPU_CACHELINE_SIZE)) + { + return TRUE32; + } + else + { + return FALSE32; + } +#else //WMR_DEBUG + return TRUE32; +#endif // !WMR_DEBUG +} + +BOOL32 +WMR_FILL_STRUCT(void *pDstBuff, UInt32 *pdwDstBuffSize, const void *pSrcBuff, UInt32 dwSrcBuffSize) +{ + BOOL32 boolRes = TRUE32; + + if (!pDstBuff && pdwDstBuffSize) + { + // Just return the buffer size + *pdwDstBuffSize = dwSrcBuffSize; + } + else if (!pdwDstBuffSize || (*pdwDstBuffSize < dwSrcBuffSize)) + { + // Supplied buffer is too small + UInt32 dwPrintedSize = pdwDstBuffSize ? *pdwDstBuffSize : (UInt32) ~0; + WMR_PRINT(ERROR,"IOCtl on buffer of size %d with %d bytes of src data!\n", + dwPrintedSize, dwSrcBuffSize); + boolRes = FALSE32; + } + else + { + // We have a valid buffer pointer and buffer size + WMR_MEMCPY(pDstBuff, pSrcBuff, dwSrcBuffSize); + *pdwDstBuffSize = dwSrcBuffSize; + } + + return boolRes; +} + +void _WMR_PRINT(const char * format, ...) +{ + va_list args; + + // retrieve the variable arguments + va_start(args, format); + + vprintf(format, args); + + va_end(args); +} + +void +WMR_BEEP(UInt32 milliseconds) +{ + printf("WMR_BEEP\n"); +} + +const char * WMR_GETVERSION(void) +{ + static char version[] = "version string"; + + return version; +} + +BOOL32 +WMR_I_CAN_HAZ_DEBUGGER(void) +{ + return FALSE32; +} + +void WMR_WAIT_US(UInt64 microseconds) +{ + spin(microseconds); +} + +void WMR_SLEEP_US(UInt32 microseconds) +{ + task_sleep(microseconds); +} + +void WMR_YIELD(void) +{ + // Task yield is not available to libraries, so can't build it into Whimory + task_yield(); +} + +UInt32 WMR_BUS_FREQ_HZ(void) +{ + return clock_get_frequency(CLK_FMI); +} + +void WMR_BUS_FREQ_MHZ(UInt32 * minClockMHz, UInt32 * maxClockMHz) +{ + const UInt32 clkSpeed = WMR_BUS_FREQ_HZ() / 1000000; + + if (minClockMHz) + { + *minClockMHz = clkSpeed; + } + + if (maxClockMHz) + { + *maxClockMHz = clkSpeed; + } +} + +#if FMI_VERSION >= 5 +void WMR_DLL_CLOCK_GATE(BOOL32 enable) +{ + clock_gate(CLK_FMI_DLL, enable); +} +#endif + +void WMR_CLOCK_GATE(UInt32 device, BOOL32 enable) +{ + int clock; + + switch (device) + { + case 0: + clock = CLK_FMI0; + break; + case 1: + clock = CLK_FMI1; + break; + default: + panic("invalid WMR_CLOCK_GATE"); + break; + } + clock_gate(clock, enable); + +#if FMI_VERSION > 1 + switch (device) + { + case 0: + clock = CLK_FMI0BCH; + break; + case 1: + clock = CLK_FMI1BCH; + break; + default: + panic("invalid WMR_CLOCK_GATE"); + break; + } + clock_gate(clock, enable); +#endif //FMI_VERSION > 0 +} + +void +WMR_DEADLOOP(void) +{ + volatile int i = 1; + while (i) + { + (void) 0; + } +} + +void +WMR_CLOCK_RESET_DEVICE(UInt32 device) +{ + int clock; + + if( device == 0 ) + { + clock = CLK_FMI0; + } + else if( device == 1 ) + { + clock = CLK_FMI1; + } + else + { + panic("invalid WMR_CLOCK_RESET_DEVICE"); + } + + clock_reset_device(clock); +} diff --git a/drivers/flash_nand/OAM/iBoot/WMRPlatform.h b/drivers/flash_nand/OAM/iBoot/WMRPlatform.h new file mode 100644 index 0000000..e399546 --- /dev/null +++ b/drivers/flash_nand/OAM/iBoot/WMRPlatform.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "ANDTypes.h" +#include "WMRFeatures.h" + +#include // memcmp +#include // panic +#include // cache +#include // ticks + +#ifndef _WMR_PLATFORM_H_ +#define _WMR_PLATFORM_H_ + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_LOG2 +// +// Returns the floor(log2) of the given number +// +#define WMR_LOG2(x) (31UL - __builtin_clz((UInt32)(x))) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_LSB1 +// +// Returns the least significant set bit's position for the given number +// +#define WMR_LSB1(x) (0 != x ? __builtin_ctz((UInt32)x) : ~0UL) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_MEMSET +// WMR_MEMCPY +// WMR_MEMCMP +// +// Standard memory operations (libraries where available) +// + +#define WMR_MEMSET(dest, pattern, length) memset((dest), (pattern), (length)) +#define WMR_MEMCPY(dest, src, length) memcpy((dest), (src), (length)) +#define WMR_MEMCMP(buf1, buf2, length) memcmp((buf1), (buf2), (length)) +#define WMR_STRLEN(str) strlen((str)) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_ASSERT +// +// Print an error and panic if the given condition is not true +// + +# define WMR_ASSERT(_expr) \ + do { \ + if (__builtin_expect(!(_expr), 0)) \ + panic("WMR_ASSERT failed:(%s) %u", \ + __FILE__, __LINE__); \ + } while(0); + + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_PANIC +// +// Reset the system +// +# define WMR_PANIC(fmt, ...) \ + panic("WMR_PANIC: " #fmt " %s:%u", \ + ## __VA_ARGS__, __FILE__, __LINE__) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_PREPARE_WRITE_BUFFER +// +// Call before an outgoing I/O operation to ensure cache coherency +// + +#define WRITE_PREP_CACHE_CMD (CACHE_CLEAN) + +#if (defined(WMR_USE_FULL_CACHE_FLUSH) && WMR_USE_FULL_CACHE_FLUSH) +#define WMR_PREPARE_WRITE_BUFFER(buf, length) \ + platform_cache_operation(WRITE_PREP_CACHE_CMD, 0, 0) +#else //WMR_USE_FULL_CACHE_FLUSH +#if WMR_DEBUG +#define WMR_PREPARE_WRITE_BUFFER(buf, length) \ + do{ \ + WMR_ASSERT(0 == ((UInt32)(buf) % CPU_CACHELINE_SIZE)); \ + platform_cache_operation(WRITE_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE));\ + }while(0) +#else +#define WMR_PREPARE_WRITE_BUFFER(buf, length) \ + platform_cache_operation(WRITE_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE)) +#endif// !WMR_DEBUG +#endif // !WMR_USE_FULL_CACHE_FLUSH + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_PREPARE_READ_BUFFER +// +// Call before an incoming I/O operation to ensure cache coherency +// +#define READ_PREP_CACHE_CMD (CACHE_CLEAN | CACHE_INVALIDATE) + +#if (defined(WMR_USE_FULL_CACHE_FLUSH) && WMR_USE_FULL_CACHE_FLUSH) +#define WMR_PREPARE_READ_BUFFER(buf, length) \ + platform_cache_operation(READ_PREP_CACHE_CMD, 0, 0) +#else //WMR_USE_FULL_CACHE_FLUSH +#if WMR_DEBUG +#define WMR_PREPARE_READ_BUFFER(buf, length) \ + do{ \ + WMR_ASSERT(0 == ((UInt32)(buf) % CPU_CACHELINE_SIZE)); \ + platform_cache_operation(READ_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE));\ + }while(0) +#else +#define WMR_PREPARE_READ_BUFFER(buf, length) \ + platform_cache_operation(READ_PREP_CACHE_CMD, (buf), ROUNDUPTO((length), CPU_CACHELINE_SIZE)) +#endif// !WMR_DEBUG +#endif // !WMR_USE_FULL_CACHE_FLUSH + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_COMPLETE_READ_BUFFER +// +// Call after an incoming I/O operation to ensure cache coherency +// +// Note: On the IOP, we only prepare aligned read buffers from the host, so we +// shouldn't have to actually clean any dirty lines +#define WMR_COMPLETE_READ_BUFFER(buf, length) \ + WMR_PREPARE_READ_BUFFER(buf, length) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_GET_TICKS_PER_US +// +// Return the number of native ticks (as returned from WMR_CLOCK_NATIVE) per +// microsecond. +// + +// UInt32 +#define WMR_GET_TICKS_PER_US() (timer_get_tick_rate() / 1000000UL) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CLOCK_NATIVE +// +// Get the current system time in microseconds to be passed to +// WMR_HAS_TIME_ELAPSED_US and WMR_HAS_TIME_ELAPSED_MS, but NOT +// WMR_HAS_TIME_ELAPSED_TICKS +// + +// UInt64 +#define WMR_CLOCK_NATIVE() system_time() + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_CLOCK_TICKS +// +// Get the current system time in ticks (suitable for WMR_HAS_TIME_ELAPSED_TICKS) +// + +//UInt64 +#define WMR_CLOCK_TICKS() timer_get_ticks() + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_HAS_TIME_ELAPSED_US +// +// Supply a start timestamp from WMR_CLOCK_NATIVE to determine if the given +// time has elapsed +// + +//UInt64 startTicks, UInt64 elapsedUS +#define WMR_HAS_TIME_ELAPSED_US(startTicks, elapsedUS) \ + (time_has_elapsed((startTicks), (elapsedUS)) ? TRUE32 : FALSE32) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_HAS_TIME_ELAPSED_TICKS +// +// Supply a start timestamp from WMR_CLOCK_NATIVE to determine if the given +// time has elapsed. + +//UInt64 startTicks, UInt64 elapsedTicks +#define WMR_HAS_TIME_ELAPSED_TICKS(startTicks, elapsedTicks) \ + ((timer_get_ticks() - (startTicks)) > (elapsedTicks) ? TRUE32 : FALSE32) + + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_ENTER_CRITICAL_SECTION +// +// Disable pre-emption, reference counted (safe to call in interrupt) + +#define WMR_ENTER_CRITICAL_SECTION() enter_critical_section() + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_EXIT_CRITICAL_SECTION +// +// Enable pre-emption, reference counted (safe to call in interrupt) + +#define WMR_EXIT_CRITICAL_SECTION() exit_critical_section() + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_TRACE_* +// +// Compile-time tracepoints (not supported) +// +#define WMR_TRACE_0(...) +#define WMR_TRACE_1(...) +#define WMR_TRACE_2(...) +#define WMR_TRACE_3(...) +#define WMR_TRACE_4(...) +#define WMR_TRACE_IST_0(...) +#define WMR_TRACE_IST_1(...) +#define WMR_TRACE_IST_2(...) +#define WMR_TRACE_IST_3(...) +#define WMR_TRACE_IST_4(...) + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_RAND +// +// Get the next random number in the stream +// +#define WMR_RAND() rand() + +#endif /* _WMR_PLATFORM_H_ */ + diff --git a/drivers/flash_nand/OAM/iBoot/WMRTypes.h b/drivers/flash_nand/OAM/iBoot/WMRTypes.h new file mode 100644 index 0000000..7be32ef --- /dev/null +++ b/drivers/flash_nand/OAM/iBoot/WMRTypes.h @@ -0,0 +1,42 @@ +#ifndef _WMR_TYPES_H_ +#define _WMR_TYPES_H_ + +# include +# include "spTypes.h" + +/*****************************************************************************/ +/* Basic Types */ +/*****************************************************************************/ + +typedef UInt32 BOOL32; + +/*****************************************************************************/ +/* Basic Constants */ +/*****************************************************************************/ + +#define FALSE32 ((BOOL32)0) +#define TRUE32 ((BOOL32)1) + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +# define __align(_x) +/*****************************************************************************/ +/* Basic Compiler Flags */ +/*****************************************************************************/ + +#define INLINE __inline + +#ifdef DEBUG_BUILD +#define WMR_DEBUG (1) +#else +#define WMR_RELEASE (1) +#endif + +#endif /* _WMR_TYPES_H_ */ + diff --git a/drivers/flash_nand/OAM/rules.mk b/drivers/flash_nand/OAM/rules.mk new file mode 100644 index 0000000..71deae1 --- /dev/null +++ b/drivers/flash_nand/OAM/rules.mk @@ -0,0 +1,22 @@ +# Copyright (c) 2008-2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR) \ + $(LOCAL_DIR)/$(APPLICATION) + +ALL_OBJS += \ + $(LOCAL_DIR)/$(APPLICATION)/WMROAM.o \ + $(LOCAL_DIR)/$(APPLICATION)/WMRBuf.o + +MODULES += \ + lib/heap diff --git a/drivers/flash_nand/OAM/spTypes.h b/drivers/flash_nand/OAM/spTypes.h new file mode 100644 index 0000000..82efc21 --- /dev/null +++ b/drivers/flash_nand/OAM/spTypes.h @@ -0,0 +1,781 @@ +//----------------------------------------------------------------------------- +// +// (C) Copyright 2001 Apple Computer, All rights reserved +// +//----------------------------------------------------------------------------- +// FILE NAME: spTypes.h +// +// DESCRIPTION: +// +// DOCUMENT REF: +// +// NOTES: None +//----------------------------------------------------------------------------- +// +#ifndef __SPTYPES_H__ //-------------------- +#define __SPTYPES_H__ + +//----------------------------------------------------------------------------- +// Standard include files: +//----------------------------------------------------------------------------- +// + +#ifdef __cplusplus +extern "C" +{ +#endif + +//----------------------------------------------------------------------------- +// Types and defines: +//----------------------------------------------------------------------------- +// + +#define False 0 +#define True (!False) + +#ifdef __cplusplus +#define Null 0 +#else +#define Null ((Void *)0) +#endif + +#define MB 0x100000 +#define KB 0x400 + +/* Metrowerks for Windows doesn't support __packed for structures */ +#ifdef __INTEL__ + #define __packed + #pragma options align=packed + +#endif + +//----------------------------------------------------------------------------- +// SP Standard Types Type Pointer +// ------ ------- +typedef signed char xInt8, *pInt8; // 8 bit signed integer +typedef signed short xInt16, *pInt16; // 16 bit signed integer +typedef signed long xInt32, *pInt32; // 32 bit signed integer +typedef signed long long xInt64, *pInt64; // 64 bit signed integer +typedef unsigned char xUInt8, *pUInt8; // 8 bit unsigned integer +typedef const unsigned char cUInt8, *pcUInt8; // 8 bit unsigned integer +typedef unsigned short xUInt16, *pUInt16; // 16 bit unsigned integer +typedef unsigned int xUInt32, *pUInt32; // 32 bit unsigned integer +typedef unsigned long long xUInt64, *pUInt64; // 64 bit unsigned integer +typedef void Void, *pVoid; // Void (typeless) +typedef unsigned int Bool, *pBool; // Boolean (True/False) +typedef char Char, *pChar; // character, character array ptr +typedef char *String, **pString; // Null terminated 8 bit char str, +typedef const char *ConstString,**pConstString; // Null term 8 bit char str ptr + +//----------------------------------------------------------------------------- +// Pointer access macros +//----------------------------------------------------------------------------- + +#define mmioReg8( pv ) *((volatile char *)(pv)) +#define mmioReg8u( pv ) *((volatile unsigned char *)(pv)) +#define mmioReg16( pv ) *((volatile short*)(pv)) +#define mmioReg16u( pv ) *((volatile unsigned short*)(pv)) +#define mmioReg32( pv ) *((volatile long *)(pv)) +#define mmioReg32u( pv ) *((volatile unsigned long *)(pv)) + +// use mmioReg for types that are already defined with volatile and a proper size and type +#define mmioReg( pv ) *(pv) + +// +// For C++ we have to make sure the rValue is invoked +// explicitly from the pointers lvalue when we only want the +// side effects for reading and not the actual result. +// +#define mmioReg8_access( pv ) ((void)(0+mmioReg8( pv ))) +#define mmioReg8u_access( pv ) ((void)(0+mmioReg8u( pv ))) +#define mmioReg16_access( pv ) ((void)(0+mmioReg16( pv ))) +#define mmioReg16u_access( pv ) ((void)(0+mmioReg16u( pv ))) +#define mmioReg32_access( pv ) ((void)(0+mmioReg32( pv ))) +#define mmioReg32u_access( pv ) ((void)(0+mmioReg32u( pv ))) + +// use mmioReg for types that are already defined with volatile and a proper size and type +#define mmioReg_access( pv ) ((void)(0+mmioReg(pv))) + +//----------------------------------------------------------------------------- +// Pointer creation macros +//----------------------------------------------------------------------------- + +#define makePtr( c, b, o ) ((c)(((long)b)+((long)o))) + +#define memberOffset(t,m) ( &(((t)0)->m)) + +#define mmioValueAlterMask( pv, mask, setclear ) \ + pv = (setclear) ? \ + (pv | (mask)) : \ + (pv & ~(mask)) +#define mmioValueAlterBit( pv, bit, setclear ) mmioValueAlterMask(pv, 1 << (bit), setclear) + +//----------------------------------------------------------------------------- +// Error Codes +//----------------------------------------------------------------------------- +// +// +------+------+------------+------+------------------+ +// |31 28|27 24|23 16|15 12|11 0| bit +// +------+------+------------+------+------------------+ +// |Class | Type |ComponentTag|Layer | Error/Progress | +// +------+------+------------+------+------------------+ + +typedef UInt32 spErrorCode_t; +typedef void (*spFn_t)(void); +typedef void (*HandlerFunction)(void); +typedef void (*spFnProgress_t)( UInt32 pct, pVoid pContext); +typedef spErrorCode_t (*spFnUiCmd_t)( pUInt8 argv[],UInt32 argc); + +//----------------------------------------------------------------------------- +// SP_OK is the 32 bit global status value used by all software components +// to indicate successful function/operation status. If a non-zero value is +// returned as status, it should use the component ID formats defined. +// +#define SP_OK 0 // Global success return status + +// +// NOTE: Component ID types are defined as unsigned 32 bit integers (UInt32). +// +#define CID_ERR_BITSHIFT 0 // Component error bit shift +#define CID_TAG_BITSHIFT 16 // Component tag bit shift +#define CID_LAYER_BITSHIFT 12 // Component layer bit shift +#define CID_TYPE_BITSHIFT 24 // Component type bit shift +#define CID_CLASS_BITSHIFT 28 // Component class bit shift + +#define CID_LAYER_BITMASK ( 0x00F << CID_LAYER_BITSHIFT) // Layer AND bitmask +#define CID_TAG_BITMASK ( 0x0FF << CID_TAG_BITSHIFT ) // Comp tag AND bitmask +#define CID_CLASS_BITMASK ( 0x00F << CID_CLASS_BITSHIFT) // Class AND bitmsk +#define CID_ERR_BITMASK ( 0xFFF << CID_ERR_BITSHIFT ) // Component error AND bitmask +#define CID_TYPE_BITMASK ( 0x00F << CID_TYPE_BITSHIFT ) // Type AND bitmask + +#define SP_ERR_GET_ERROR(err) ((err & CID_ERR_BITMASK ) >> CID_ERR_BITSHIFT ) +#define SP_ERR_GET_CLASS(err) ((err & CID_CLASS_BITMASK) >> CID_CLASS_BITSHIFT) +#define SP_ERR_GET_TYPE(err) ((err & CID_TYPE_BITMASK ) >> CID_TYPE_BITSHIFT ) +#define SP_ERR_GET_LAYER(err) ((err & CID_LAYER_BITMASK) >> CID_LAYER_BITSHIFT) + +// Component Class definitions (bits 31:28, 4 bits) +#define CID_CLASS_NONE (0x1 << CID_CLASS_BITSHIFT) // No class information +#define CID_CLASS_INFRASTR (0x2 << CID_CLASS_BITSHIFT) + +// Component Type definitions (bits 27:24, 4 bits) +#define CID_TYPE_NONE (0x0 << CID_TYPE_BITSHIFT) // No data connections + +// Component Tag definitions (bits 23:16, 8 bits) +// NOTE: Component tags are defined in groups, dependent on the class and type. +#define CID_TAG_NONE (0x00 << CID_TAG_BITSHIFT) // No tag information + +#define TAG(num) ((num)<< CID_TAG_BITSHIFT) // Create tag from num + +// Component Layer definitions (bits 15:12, 4 bits) +#define CID_LAYER_NONE (0x0 << CID_LAYER_BITSHIFT) // No layer info +#define CID_LAYER_BOOT (0x1 << CID_LAYER_BITSHIFT) // Boot loader layer +#define CID_LAYER_HWAPI (0x2 << CID_LAYER_BITSHIFT) // Hardware API layer +#define CID_LAYER_IMA (0x3 << CID_LAYER_BITSHIFT) // iMA interface layer + +// STANDARD ERRORS +#define SP_ERR_COMPATIBILITY 0x001 // SW Interface compatibility +#define SP_ERR_MAJOR_VERSION 0x002 // SW Major Version error +#define SP_ERR_COMP_VERSION 0x003 // SW component version error +#define SP_ERR_BAD_MODULE_ID 0x004 // SW - HW module ID error +#define SP_ERR_BAD_UNIT_NUMBER 0x005 // Invalid device unit number +#define SP_ERR_BAD_INSTANCE 0x006 // Bad input instance value +#define SP_ERR_BAD_HANDLE 0x007 // Bad input handle +#define SP_ERR_BAD_INDEX 0x008 // Bad input index +#define SP_ERR_BAD_PARAMETER 0x009 // Invalid input parameter +#define SP_ERR_NO_INSTANCES 0x00A // No instances available +#define SP_ERR_NO_COMPONENT 0x00B // Component is not present +#define SP_ERR_NO_RESOURCES 0x00C // Resource is not available +#define SP_ERR_INSTANCE_IN_USE 0x00D // Instance is already in use +#define SP_ERR_RESOURCE_OWNED 0x00E // Resource is already in use +#define SP_ERR_RESOURCE_NOT_OWNED 0x00F // Caller does not own resource +#define SP_ERR_INCONSISTENT_PARAMS 0x010 // Inconsistent input params +#define SP_ERR_NOT_INITIALIZED 0x011 // Component is not initialized +#define SP_ERR_NOT_ENABLED 0x012 // Component is not enabled +#define SP_ERR_NOT_SUPPORTED 0x013 // Function is not supported +#define SP_ERR_INIT_FAILED 0x014 // Initialization failed +#define SP_ERR_BUSY 0x015 // Component is busy +#define SP_ERR_NOT_BUSY 0x016 // Component is not busy +#define SP_ERR_READ 0x017 // Read error +#define SP_ERR_WRITE 0x018 // Write error +#define SP_ERR_ERASE 0x019 // Erase error +#define SP_ERR_LOCK 0x01A // Lock error +#define SP_ERR_UNLOCK 0x01B // Unlock error +#define SP_ERR_OUT_OF_MEMORY 0x01C // Memory allocation failed +#define SP_ERR_BAD_VIRT_ADDRESS 0x01D // Bad virtual address +#define SP_ERR_BAD_PHYS_ADDRESS 0x01E // Bad physical address +#define SP_ERR_TIMEOUT 0x01F // Timeout error +#define SP_ERR_OVERFLOW 0x020 // Data overflow/overrun error +#define SP_ERR_FULL 0x021 // Queue (etc.) is full +#define SP_ERR_EMPTY 0x022 // Queue (etc.) is empty +#define SP_ERR_NOT_STARTED 0x023 // Component stream not started +#define SP_ERR_ALREADY_STARTED 0x024 // Comp. stream already started +#define SP_ERR_NOT_STOPPED 0x025 // Component stream not stopped +#define SP_ERR_ALREADY_STOPPED 0x026 // Comp. stream already stopped +#define SP_ERR_ALREADY_SETUP 0x027 // Component already setup +#define SP_ERR_NULL_PARAMETER 0x028 // Null input parameter +#define SP_ERR_NULL_DATAINFUNC 0x029 // Null data input function +#define SP_ERR_NULL_DATAOUTFUNC 0x02A // Null data output function +#define SP_ERR_NULL_CONTROLFUNC 0x02B // Null control function +#define SP_ERR_NULL_COMPLETIONFUNC 0x02C // Null completion function +#define SP_ERR_NULL_PROGRESSFUNC 0x02D // Null progress function +#define SP_ERR_NULL_ERRORFUNC 0x02E // Null error handler function +#define SP_ERR_NULL_MEMALLOCFUNC 0x02F // Null memory alloc function +#define SP_ERR_NULL_MEMFREEFUNC 0x030 // Null memory free function +#define SP_ERR_NULL_CONFIGFUNC 0x031 // Null configuration function +#define SP_ERR_NULL_PARENT 0x032 // Null parent data +#define SP_ERR_NULL_IODESC 0x033 // Null in/out descriptor +#define SP_ERR_NULL_CTRLDESC 0x034 // Null control descriptor +#define SP_ERR_UNSUPPORTED_DATACLASS 0x035 // Unsupported data class +#define SP_ERR_UNSUPPORTED_DATATYPE 0x036 // Unsupported data type +#define SP_ERR_UNSUPPORTED_DATASUBTYPE 0x037 // Unsupported data subtype +#define SP_ERR_FORMAT 0x038 // Invalid/unsupported format +#define SP_ERR_INPUT_DESC_FLAGS 0x039 // Bad input descriptor flags +#define SP_ERR_OUTPUT_DESC_FLAGS 0x03A // Bad output descriptor flags +#define SP_ERR_CAP_REQUIRED 0x03B // Capabilities required ??? +#define SP_ERR_BAD_TMALFUNC_TABLE 0x03C // Bad TMAL function table +#define SP_ERR_INVALID_CHANNEL_ID 0x03D // Invalid channel identifier +#define SP_ERR_INVALID_COMMAND 0x03E // Invalid command/request +#define SP_ERR_STREAM_MODE_CONFUSION 0x03F // Stream mode config conflict +#define SP_ERR_UNDERRUN 0x040 // Data underflow/underrun +#define SP_ERR_EMPTY_PACKET_RECVD 0x041 // Empty data packet received +#define SP_ERR_OTHER_DATAINOUT_ERR 0x042 // Other data input/output err +#define SP_ERR_STOP_REQUESTED 0x043 // Stop in progress +#define SP_ERR_PIN_NOT_STARTED 0x044 // Pin not started +#define SP_ERR_PIN_ALREADY_STARTED 0x045 // Pin already started +#define SP_ERR_PIN_NOT_STOPPED 0x046 // Pin not stopped +#define SP_ERR_PIN_ALREADY_STOPPED 0x047 // Pin already stopped +#define SP_ERR_STOP_PIN_REQUESTED 0x048 // Stop of a single pin is in progress +#define SP_ERR_ASSERTION 0x049 // Assertion failure +#define SP_ERR_HIGHWAY_BANDWIDTH 0x04A // Highway bandwidth bus error +#define SP_ERR_HW_RESET_FAILED 0x04B // Hardware reset failed +#define SP_ERR_MEDIA_MISSING 0x04C // Media Missing +#define SP_ERR_DEVICE_ABORT 0x04D // Device Abort +#define SP_ERR_MEDIA_CHANGE 0x04E // Media Change +#define SP_ERR_MEDIA_WRITE_PROTECTED 0x04F // Media Write Protected +#define SP_ERR_HW_ERR_PENDING 0x050 // +#define SP_ERR_HW_ERR 0x051 // Generic Hw Error +#define SP_ERR_NOT_FOUND 0x052 // item not found +#define SP_ERR_DEVICE_NOT_FOUND 0x053 // device not found +#define SP_ERR_ITEMLIST_FULL 0x054 // no room for item in catalog +#define SP_ERR_FNF_ERR 0x055 // file not found +#define SP_ERR_NOPARTITION 0x056 // partition not found +#define SP_ERR_CHECKSUM_FAILED 0x057 // checksum do not match +#define SP_ERR_ATA_SELECT_ERROR 0x058 // IDE error selecting device +#define SP_ERR_ATA_COMMAND_ERROR 0x059 // IDE command failed +#define SP_ERR_ATA_SEQUENCE_ERROR 0x05a // IDE command setup sequence failed +#define SP_ERR_ATA_COMMUNICATIONS_ERROR 0x05b // IDE communications error +#define SP_ERR_IIC_NOACK 0x060 // IIC no ack error + +// Add new standard error/progress status codes here + +#define SP_ERR_COMP_UNIQUE_START 0x800 // 0x800-0xDFF: Component unique + +// SP Standard assert error code start offset +// NOTE: This define should be added to the component's base error value and +// standard error code(s) to define assert error codes. +// +#define SP_ERR_ASSERT_START 0xE00 // 0xE00-0xEFF: Assert failures +#define SP_ERR_ASSERT_LAST 0xEFF // Last assert error range value +#define SP_IS_ASSERT_ERROR(err) \ + ((SP_GET_ERROR(err) >= SP_ERR_ASSERT_START) && \ + (SP_GET_ERROR(err) <= SP_ERR_ASSERT_LAST)) + +// SP Standard fatal error code start offset +// NOTE: This define should be added to the component's base error value and +// standard error code(s) to define fatal error codes. For example: +#define SP_ERR_FATAL_START 0xF00 // 0xF00-0xFFF: Fatal failures +#define SP_ERR_FATAL_LAST 0xFFF // Last fatal error range value +#define SP_IS_FATAL_ERROR(err) \ + ((SP_GET_ERROR(err) >= SP_ERR_FATAL_START) && \ + (SP_GET_ERROR(err) <= SP_ERR_FATAL_LAST)) + +//----------------------------------------------------------------------------- +// SMART Self Test error codes +// + +// return values from ATA disk SMART test +#define SP_SMART_OK 0x00 // no error +#define SP_SMART_ABORTED 0x01 // aborted by host +#define SP_SMART_RESET 0x02 // reset by host +#define SP_SMART_FATAL_ERROR 0x03 // fatal or unknown error +#define SP_SMART_UNKNOWN_ERROR 0x04 // unknown error +#define SP_SMART_ELECTRICAL_ERROR 0x05 // electrical error +#define SP_SMART_SERVO_ERROR 0x06 // servo error +#define SP_SMART_READ_ERROR 0x07 // read error +#define SP_SMART_RESERVED_8 0x08 // reserved +#define SP_SMART_RESERVED_E 0x0E // reserved +// 8 - 14 reserved, assume they indicate error +#define SP_SMART_IN_PROGRESS 0x0F // test in progress +#define SP_SMART_CANCELLED_BY_USER 0x10 // user cancelled test + +// return values from test routine, simplified version of above errors +// if everything is ok, we return SP_SMART_OK +#define SP_SMART_RESCAN 0x01 // incomplete scan, try again +#define SP_SMART_DEADBEEF 0x02 // dead as a doornail + +//----------------------------------------------------------------------------- +// Version Structure +// +typedef UInt32 spVersion_t, *pspVersion_t; + +#define SP_VERSION_MAJOR_NUM_MASK 0xFF000000 +#define SP_VERSION_MAJOR_NUM_SHIFT 24 + +#define SP_VERSION_MINOR_NUM_MASK 0x00FF0000 +#define SP_VERSION_MINOR_NUM_SHIFT 16 + +#define SP_VERSION_COMPATIBILITY_MASK 0x0000FFFF +#define SP_VERSION_COMPATIBILITY_SHIFT 0 + +#define SP_VERSION_GET_MAJOR_NUM(v) (((v) & SP_VERSION_MAJOR_NUM_MASK ) >> \ + SP_VERSION_MAJOR_NUM_SHIFT ) +#define SP_VERSION_GET_MINOR_NUM(v) (((v) & SP_VERSION_MINOR_NUM_MASK ) >> \ + SP_VERSION_MINOR_NUM_SHIFT ) +#define SP_VERSION_GET_COMPATIBILITY(v) (((v) & SP_VERSION_COMPATIBILITY_MASK ) >> \ + SP_VERSION_COMPATIBILITY_SHIFT) + +#define SP_VERSION(mj, mn, c ) ( ( ( (mj ) << SP_VERSION_MAJOR_NUM_SHIFT ) & \ + SP_VERSION_MAJOR_NUM_MASK ) | \ + ( ( (mn ) << SP_VERSION_MINOR_NUM_SHIFT ) & \ + SP_VERSION_MINOR_NUM_MASK ) | \ + ( ( (c ) << SP_VERSION_COMPATIBILITY_SHIFT ) & \ + SP_VERSION_COMPATIBILITY_MASK ) ) + +//----------------------------------------------------------------------------- +// Memory heap +// + +typedef struct tagspboardMemHeap_t +{ + pVoid pvHeapBase; + UInt32 cbHeapSize; + +}spboardMemHeap_t,*pspboardMemHeap_t; + + +//----------------------------------------------------------------------------- +// HW Unit Selection +// +typedef enum tagspUnitSelect_t +{ + spUnitNone = -1, + spUnit0 = 0, + spUnit1 = 1, + spUnit2 = 2, + spUnit3 = 3, + spUnit4 = 4 + +} spUnitSelect_t, *pspUnitSelect_t; + +//----------------------------------------------------------------------------- +// Boot Modes +// +typedef enum +{ + spBootModeRetail = 1, + spBootModeDebug = 2, + spBootModeUiShell = 3, + spBootModeDiag = 4, + spBootModeDisk = 5, + spBootModeScan = 6, + spBootModeSleepTest = 7, + spBootModeReset = 8 +} spBootMode_t, *pspBootMode_t; + +typedef enum +{ + CPU_13_5MHz = 13500, + CPU_24MHz = 24000, + CPU_36MHz = 36000, + CPU_48MHz = 48000, + CPU_64MHz = 64000, + CPU_80MHz = 80000, + CPU_90MHz = 90000 +} spCpuMHz_t, *pspCpuMHz_t; + +//----------------------------------------------------------------------------- +// Instance and handle +// +typedef UInt32 spInstance_t, *pspInstance_t; +typedef UInt32 spHandle_t, *pspHandle_t; + +#define SP_INVALID_HANDLE ((spHandle_t)-1) + +//----------------------------------------------------------------------------- +// Device flags +// +#define SP_HW_DEVICE_RAM 0x00000001 +#define SP_HW_DEVICE_SDRAM 0x00000002 +#define SP_HW_DEVICE_FLASH 0x00000004 +#define SP_HW_DEVICE_IDE 0x00000008 +#define SP_HW_DEVICE_UART1 0x00000010 +#define SP_HW_DEVICE_UART2 0x00000020 +#define SP_HW_DEVICE_LCD 0x00000040 +#define SP_HW_DEVICE_FIREWIRE 0x00000080 +#define SP_HW_DEVICE_GPIO 0x00000100 +#define SP_HW_DEVICE_LEDS 0x00000200 +#define SP_HW_DEVICE_PIEZO 0x00000400 +#define SP_HW_DEVICE_CODEC 0x00000800 +#define SP_HW_DEVICE_A2D 0x00001000 + +#define SP_HW_DEVICE_ALL 0xFFFFFFFF + +//----------------------------------------------------------------------------- +// System config structure location. +// + +#define SP_SYSCONFIG_START_FLASH_ADDRESS_GRPA 0x2000 +#define SP_SYSCONFIG_END_FLASH_ADDRESS_GRPA 0x4000 +#define SP_SYSCONFIG_START_FLASH_ADDRESS_GRPB 0x4000 +#define SP_SYSCONFIG_END_FLASH_ADDRESS_GRPB 0x6000 + +//----------------------------------------------------------------------------- +// System Information Structure +// + +#define SP_FLASH_VERSION_OFFSET 0x4040 +#define SP_FLASH_VERSION_MAGIC 'srev' + +#define SP_SYSINFO_MAGIC 'SysI' + +typedef struct tagspSysInfoAddr_t +{ + UInt32 magic; + UInt32 addr; + +}spSysInfoAddr_t,*pspSysInfoAddr_t; + +#define SP_SYSINFO_BOARDHWNAME_SIZE 16 // SCSI INQ depends on this! +#define SP_SYSINFO_SERIALNUM_SIZE 32 +#define SP_SYSINFO_FIREWIREGUID_SIZE 16 +#define SP_SYSINFO_UNITCHARACTER_SIZE 16 +#define SP_SYSINFO_MODELNUM_SIZE 16 +#define SP_SYSINFO_HWOPTIONS1_SIZE 16 +#define SP_SYSINFO_CONTRAST_SIZE 16 +#define SP_SYSINFO_BACKLIGHT_SIZE 16 +#define SP_SYSINFO_DRMCONFIG_SIZE 16 + +#define SP_SYSINFO_MAX_MEM_RANGES 8 +#define SP_SYSINFO_MAX_BATTERY_CAL 4 + +typedef enum +{ + kSysInfoAddrRangeNone = 0, + kSysInfoAddrRangeFlash = 'Flsh', + kSysInfoAddrRangeSdram = 'Sdrm', + kSysInfoAddrRangeFirewire = 'Frwr', + kSysInfoAddrRangeIram = 'Iram', + kSysInfoAddrRangeHdd0 = 'hdd0', + kSysInfoAddrRangeHdd1 = 'hdd1' + +}spSysInfoAddrRangeType_t; + +typedef struct tagspBattA2DCal_t +{ + UInt32 voltage; // Fix point format 16bit.16bit + UInt32 a2d; + +}spBattA2DCal_t,*pspBattA2DCal_t; + +#define SP_SYSCFG_BATTERY_CAL_VERSION 1 + +typedef struct tagrtcAdjustKeyValueFormat_t +{ + UInt32 version; + UInt32 secPerDay; // Signed fix point format 16bit.16bit + +}rtcAdjustKeyValueFormat_t, *prtcAdjustKeyValueFormat_t; + +#define SP_SYSCFG_RTC_ADJUST_VERSION 1 + +typedef struct tagbatteryA2DCalKeyValueFormat_t +{ + UInt32 version; + UInt32 voltage; // Signed fix point format 16bit.16bit + UInt32 a2d; + +}batteryA2DCalKeyValueFormat_t, *pbatteryA2DCalKeyValueFormat_t; + +// +// Region codes and policy flags +// +#define SP_SYSCFG_REGION_VERSION 1 +#define SP_SYSCFG_REGION_POLICY_BYTES 2 +#define SP_SYSCFG_REGION_VENDOR_MASK 0xC0 + +// NOTE: HP adds the high bit '0x80' to a given region code to avoid adding a string +// to the model number, but still allowing for region differentiation +enum +{ + kSyscfgRegionVendor_Apple = 0x00, + kSyscfgRegionVendor_HP = 0x80 +}; + +// Check Wiki for most up-to-date list (v1.5, 3/10/06) +// http://spgserver.apple.com/Ipodwiki/wiki?Region_Codes +enum // Needs to fit in 16bit! +{ + // Regions (Apple - 0x00) // Regions (HP - 0x80) + kSyscfgRegion_World = 0x00,// Unassigned // Unassigned + + kSyscfgRegion_NorthAmerica = 0x01,// LL = US/Canada // ABA = US/Canada + kSyscfgRegion_Japan = 0x02,// J = Japanese Only + kSyscfgRegion_FrenchGerman = 0x03,// FD = French (F), German (D), Swiss, Austria + kSyscfgRegion_ItalianDutch = 0x04,// TN = Italian (T), Dutch (N), Belgium + kSyscfgRegion_SpanishBrazilian = 0x05,// Y = Spanish (Y), Brazilian Portuguese (BR) + kSyscfgRegion_SwedishNorwegian = 0x06,// S = Swedish (S), Norwegian (H) + kSyscfgRegion_DanishFinnish = 0x07,// DK = Danish (DK), Finnish (K) + kSyscfgRegion_ChineseHongKong = 0x08,// CH = Chinese (CH), Hong Kong + kSyscfgRegion_Korean = 0x09,// KH = Korean (KH) + + kSyscfgRegion_Canada = 0x0A,// C = Canada // ABC = Canada + kSyscfgRegion_LatinAmerica = 0x0B,// E = Latin America // ABM = Latin America + kSyscfgRegion_UnitedKingdom = 0x0C,// B = United Kingdom // ABU = United Kingdom + kSyscfgRegion_Europe = 0x0D,// Z = Rest of Europe + kSyscfgRegion_Australia = 0x0E,// X = Australia, New Zealand + kSyscfgRegion_HongKongSingapore = 0x0F,// FE = HongKong, Singapore + kSyscfgRegion_Taiwan = 0x10,// TA = Taiwan + kSyscfgRegion_ZV = 0x11,// ZV = Europe (British, Swedish, Spanish, Danish) + kSyscfgRegion_ZR = 0x12,// ZR = Europe (French, German, Dutch, Italian) // B19 = Europe (French, German, Dutch, Italian) + kSyscfgRegion_SouthAsia = 0x13,// ZP = Singapore, South Asia +// kSyscfgRegion_Spanish_Q98 = 0x13,// Y = Spanish (Y) [Q98 ONLY] + kSyscfgRegion_HongKong = 0x14,// HK = Hong Kong (HK) +// kSyscfgRegion_KoreaTaiwan_Q98 = 0x14,// PA = Korean, Taiwanise [Q98 ONLY] + kSyscfgRegion_Spanish = 0x15,// Y = Spanish (Y) // ABE = Spanish (Y) + kSyscfgRegion_Chinese = 0x16,// CH = Chinese (CH) + kSyscfgRegion_KoreanTaiwanese = 0x17,// PA = Korean, Taiwanese // AB2 = Korean, Taiwanese + kSyscfgRegion_French = 0x18,// F = French // ABF = French + kSyscfgRegion_German = 0x19,// D = German // ABD = German + kSyscfgRegion_SouthAfrica = 0x1A,// FB = CEMEA, South Africa + kSyscfgRegion_DutchBelgium = 0x1B,// NF = Dutch (N), Belgium + kSyscfgRegion_SpanishItalian = 0x1C,// TY = Spanish, (Y) Italian (T) + kSyscfgRegion_Brazil = 0x1D,// YP = Brazil + kSyscfgRegion_Portugal = 0x1E,// PZ = Portugal + + kSyscfgRegion_LimitValue +}; + +enum // Needs to fit in 16bit! +{ + kSyscfgRegionPolicyFlag_None = 0x0000, + kSyscfgRegionPolicyFlag_EU = 0x0001, // "French" volume problem + kSyscfgRegionPolicyFlag_TVOut = 0x0006 // Two bits, PAL = 00, NTSC = 01 +}; + +enum +{ + kSyscfgRegionPolicyFlag_TVOut_PAL = (0 << 1), + kSyscfgRegionPolicyFlag_TVOut_NTSC = (1 << 1) +}; + +typedef struct tagregionKeyValueFormat_t +{ + UInt16 version; // SP_SYSCFG_REGION_VERSION + UInt8 reserve; + UInt8 PolicySizeBytes; // Currently 2 + + UInt16 regionCode; + UInt16 policyFlags; + +}regionKeyValueFormat_t,*pregionKeyValueFormat_t; + +typedef struct tagunitCharacteristicsFormat_t +{ + // this structure maps on to data provided in flash + UInt8 revision; + UInt8 bytesOfValidData; + + UInt16 oemVendorId; // little endian + UInt32 color; // little endian + UInt8 reserved[8]; + +}unitCharacteristicsFormat_t,*punitCharacteristicsFormat_t; + +// Add stuff at end to maximize compatibility with old bootloaders +typedef struct tagspSysInfo_t +{ + UInt32 magic; + UInt32 size; + + UInt8 pszBoardHwName [ SP_SYSINFO_BOARDHWNAME_SIZE ]; + UInt8 pszSerialNumber[ SP_SYSINFO_SERIALNUM_SIZE ]; + UInt8 pu8FirewireGuid64[ SP_SYSINFO_FIREWIREGUID_SIZE ]; + + // Board Version + spVersion_t boardHwRev; + + // SW Versions + spVersion_t bootLoaderImageRev; + spVersion_t diskModeImageRev; + spVersion_t diagImageRev; + spVersion_t osImageRev; + + // + // Number of Voltage / Analog-to-Digital calibration + // points. + // + UInt32 ccBattA2DCal; + spBattA2DCal_t battA2DCal[SP_SYSINFO_MAX_BATTERY_CAL]; + + // + // Currection to RTC drift due to constant PLL error. + // Seconds per day. + // + Int32 RtcAdjustSecondsPerDay; // Signed fix point + // format 16bit.16bit + + // Board Sw Interface Revision + spVersion_t boardHwSwInterfaceRev; + + // HDD Firmware version string + UInt8 pszHddFirmwareVersion[ 9 ]; + + // Region and Policy flags + UInt16 regionCode; + UInt32 policyFlags; + + UInt8 pszModelNumStr [ SP_SYSINFO_MODELNUM_SIZE ]; + + UInt8 hardwareOptions1[SP_SYSINFO_HWOPTIONS1_SIZE]; + + Int8 contrastAdjBLOff; + Int8 contrastAdjBLOn; + Int8 backlightAdjCenter; + Int8 backlightAdjSwing; + unitCharacteristicsFormat_t unitCharacteristics; + // Drive Low Power Cut Off + UInt16 hddVoltageCutoff; + + UInt8 drmConfig[SP_SYSINFO_DRMCONFIG_SIZE]; + + // Info on memory sizes, properly determined + UInt32 SDRAMSize; + UInt32 SDRAMBase; + UInt32 IRAMSize; + UInt32 IRAMBase; + UInt32 FlashSize; + UInt32 FlashBase; + UInt32 NANDSizeTag; // Tag to help Diagnostics to find NAND size info + UInt32 NANDTotalLBA; + Int32 NANDBlockSize; // negtive number to indicate error + +}spSystemInformation_t,*pspSystemInformation_t; + +#define SYSINFO_BOARDHWREV 1 +#define SYSINFO_BOOTLOADERIMAGEREV 2 +#define SYSINFO_DISKMODEIMAGEREF 3 +#define SYSINFO_DIAGIMAGEREV 4 +#define SYSINFO_OSIMAGEREV 5 + + +#define SP_SYSCFG_KEY_SERIALNUM 'SrNm' +#define SP_SYSCFG_KEY_FIREWIREGUID 'FwId' +#define SP_SYSCFG_KEY_HWID 'HwId' +#define SP_SYSCFG_KEY_HWIFVERSION 'HwVr' +#define SP_SYSCFG_KEY_HWNAME 'HwNm' +#define SP_SYSCFG_KEY_BATTERY_CAL 'Btry' +#define SP_SYSCFG_KEY_RTC_ADJUST 'RtcA' +#define SP_SYSCFG_KEY_REGION 'Regn' +#define SP_SYSCFG_KEY_MODELNUM 'Mod#' +#define SP_SYSCFG_KEY_HWOPTS1 'HwO1' +#define SP_SYSCFG_KEY_CONTRAST 'Cont' +#define SP_SYSCFG_KEY_UNITCHARACTER 'UntC' +#define SP_SYSCFG_KEY_BACKLIGHT 'BkLt' +#define SP_SYSCFG_KEY_DRMCONFIG 'DrmV' + +//----------------------------------------------------------------------------- +// Image Manager types +//----------------------------------------------------------------------------- +// + +#define BT_IMAGE_TYPE_DIAG 'diag' +#define BT_IMAGE_TYPE_OS 'osos' +#define BT_IMAGE_TYPE_DISKMODE 'disk' +#define BT_IMAGE_TYPE_SCANMODE 'scan' +#define BT_IMAGE_TYPE_UPDATE 'aupd' +#define BT_IMAGE_TYPE_BOOTLOGO 'logo' +#define BT_IMAGE_VIDEOCORE_BOOT 'vmcs' +#define BT_IMAGE_TYPE_HIBERNATE 'hibe' +#define BT_IMAGE_TYPE_RESOURCE 'rsrc' +#define BT_IMAGE_TYPE_GRAPE 'grpe' + +//----------------------------------------------------------------------------- +// Image Manager types +//----------------------------------------------------------------------------- +// +#define BT_IMAGE_LOGO_MAGIC 'LoGo' + + +//----------------------------------------------------------------------------- +// Cpu Profile Interval type +//----------------------------------------------------------------------------- +// + +#define SP_PROFILE_EVENT_CPU_0 0 +#define SP_PROFILE_EVENT_COP_0 1 + +typedef struct tagpspProfileContext_t +{ + UInt32 id; + UInt32 maskEnable; + Bool bEnable; + + UInt32 triggerPin; + UInt32 signalPin; + + UInt32 signalPinAddr; + UInt32 signalPinMask; + + UInt32 start; + UInt32 end; + + Bool bHigh; + + UInt32 HiTime; + UInt32 LoTime; + +}spProfileContext_t, *pspProfileContext_t; + + + +//----------------------------------------------------------------------------- +// The target image is passed this 32bit flags word from the Bootloader +// +#define SP_IMAGE_FLAGS_ADDR_PTR_OFFSET 0x10 // - 0x17 + +#define SP_IMAGE_NONE_FLAG 0x00000000 +#define SP_IMAGE_REBOOT_INTO_DISKMODE_FLAG 0x00000001 +#define SP_IMAGE_REBOOT_INTO_RETAILMODE_FLAG 0x00000002 +#define SP_IMAGE_USER_KEY_PRESS_FLAG 0x00000004 +#define SP_IMAGE_HIBERNATE_FLAG 0x00000008 +#define SP_IMAGE_BANGFOLDER 0x00000010 + +//----------------------------------------------------------------------------- +// System info structure pointer has been moved up into the special space now. +// + +#define SP_SYSINFO_ADDR_PTR_OFFSET 0x18 // - 0x1F + +//----------------------------------------------------------------------------- +// Storage area for RTC reference time across boots. +// + +#define SP_RTC_REF_TIME_STRUCT_OFFSET 0x20 // - 0x2B + +//----------------------------------------------------------------------------- +// COP publishes its exception status in this area. +// Reserved for see t_watchdog.h. +// #define SP_COP_EXCEPTION_STATUS_OFFSET 0x2C // - 0x2F + +//----------------------------------------------------------------------------- +// Storage area for Locale information to communicate to DiskMode. +// + +#define SP_LOCALE_TYPE_PTR_OFFSET 0x30 // - 0x33 + +#ifdef __cplusplus +} +#endif + +#endif // __SPTYPES_H__ //------------------ + diff --git a/drivers/flash_nand/benchmark/L2V_Test.c b/drivers/flash_nand/benchmark/L2V_Test.c new file mode 100644 index 0000000..a65791f --- /dev/null +++ b/drivers/flash_nand/benchmark/L2V_Test.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Funcs.h" +#include "L2V_Print.h" +//#include +//#include + +L2V_t L2V; + + +#define LAST_TREE_TEST 16 +#define SIMPLE_SIZE (L2V_TREE_SIZE*LAST_TREE_TEST) + + + +// Prototypes +static void RandomTest(void); +static void SequentialTest(void); +static void Simple_Init(void); +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn); +static void Simple_Lookup(UInt32 lba, UInt32 *vpn); + +static void Seed_Local_Rand(UInt32 seed); +static UInt32 Get_Local_Rand(void); +static UInt32 _current_rand = 0; + + + +void Usage(int argc, char** argv) +{ + printf("Usage: %s s OR %s r (for sequential and random, respectively\n", argv[0], argv[0]); + exit(-1); +} + +int test = 0; + +#if 0 +int main(int argc, char** argv) +{ + L2V_Init(SIMPLE_SIZE, (L2V_VPN_SPECIAL-1) / 8192, 8192); + + if (argc == 2) { + if ('r' == argv[1][0]) { + test = 0; + } else if ('s' == argv[1][0]) { + test = 1; + } else { + Usage(argc, argv); + } + } + if (argc > 2) { + Usage(argc, argv); + } + + if (0 == test) { + RandomTest(); + } else { + SequentialTest(); + } + + return 0; +} +#endif + +#define MAXLEN 512 +void L2VRandomTest() { + UInt32 lba, size, vpn; + UInt32 i; + L2V_SearchCtx_t c; + UInt32 iterations = 1000000; + + L2V_Init(SIMPLE_SIZE, (L2V_VPN_SPECIAL-1) / 8192, 8192); + + L2V_Search_Init(&c); + + Seed_Local_Rand(12345); + + while (iterations--) { + lba = Get_Local_Rand() % ((L2V_TREE_SIZE*LAST_TREE_TEST)-MAXLEN); + size = (Get_Local_Rand() % (MAXLEN-1))+1; + vpn = Get_Local_Rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + + // 1 write + L2V_Update(lba, size, vpn); + + // 5 reads + for (i = 0; i < 5; ++i) + { + c.lba = Get_Local_Rand() % ((L2V_TREE_SIZE*LAST_TREE_TEST)-MAXLEN); + L2V_Search(&c); + } + } +} + +static void SequentialTest() { + UInt32 lba, size, vpn; + UInt32 i, svpn; + L2V_SearchCtx_t c; + + L2V_Search_Init(&c); + + Simple_Init(); + + Seed_Local_Rand(12345); + + lba = 0; + size = 0; + vpn = 1; + + while (1) { + lba += size; + size = (Get_Local_Rand() % (MAXLEN-1))+1; + if ((lba + size) >= L2V_TREE_SIZE) { + lba = 0; + } + if ((Get_Local_Rand() & 3) == 0) { + vpn = Get_Local_Rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + } + while (((vpn + size) & ((1<<(L2V_BITS_VPN-1))-1)) < vpn) { + vpn = Get_Local_Rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + } + + printf("[UPD: lba:%d, size:%d, vpn:%d]\n", lba, size, vpn); + L2V_Update(lba, size, vpn); + Simple_Update(lba, size, vpn); + L2V_PrintUsage(0); + vpn += size; + + + // Validate entire range + unsigned int maxlevel=0; + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_Lookup(i, &svpn); + c.lba = i; + L2V_Search(&c); + if (c.level > maxlevel) maxlevel = c.level; + if (svpn != c.vpn) { + printf("\n\n\n"); + printf("====================\n"); + printf("MISMATCH lba:%d\n", i); + printf("--------------------\n"); + printf("Simple vpn:%d\n", svpn); + printf("Lookup vpn:%d\n", c.vpn); + } + l2v_assert_eq(svpn, c.vpn); + } + printf("maxlevel: %d\n", maxlevel); + l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH); + } +} + + +UInt32 Simple_vpn[SIMPLE_SIZE]; + +static void Simple_Init() +{ + UInt32 i; + + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_vpn[i] = L2V_VPN_MISS; + } +} + + +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn) +{ + while (size) { + Simple_vpn[lba] = vpn; + + // Iterate + lba++; + if (vpn < L2V_VPN_SPECIAL) { + vpn++; + } + size--; + } +} + + +static void Simple_Lookup(UInt32 lba, UInt32 *vpn) +{ + *vpn = Simple_vpn[lba]; +} + + +static void Seed_Local_Rand(UInt32 seed) +{ + _current_rand = seed; +} +static UInt32 Get_Local_Rand(void) +{ + int i; + for (i = 0; i < 17; ++i) + { + _current_rand = (_current_rand >> 1) ^ (UInt32)((0 - (_current_rand & 1u)) & 0xd0000001u); + } + return _current_rand; +} diff --git a/drivers/flash_nand/benchmark/benchmark.c b/drivers/flash_nand/benchmark/benchmark.c new file mode 100644 index 0000000..73674f4 --- /dev/null +++ b/drivers/flash_nand/benchmark/benchmark.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +extern void L2VRandomTest(void); + +static int do_l2v(int argc, struct cmd_arg *args) +{ + UInt64 start = system_time(); + L2VRandomTest(); + printf("test time: %lldus\n", system_time() - start); + return(0); +} +MENU_COMMAND_DEBUG(l2v, do_l2v, "run l2v benchmark", NULL); + +#endif diff --git a/drivers/flash_nand/benchmark/rules.mk b/drivers/flash_nand/benchmark/rules.mk new file mode 100644 index 0000000..9dd59b4 --- /dev/null +++ b/drivers/flash_nand/benchmark/rules.mk @@ -0,0 +1,40 @@ +# Copyright (C) 2010 Apple, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +# +# L2V Test Benchmark +# +LOCAL_DIR := $(GET_LOCAL_DIR) +NAND_DIR := $(dir $(GET_LOCAL_DIR)) +L2V_DIR := $(NAND_DIR)/raw/Whimory/Core/FTL/L2V + +MODULES += drivers/flash_nand/OAM + +GLOBAL_INCLUDES += $(L2V_DIR) + +OPTIONS += ENABLE_L2V_TREE=1 + +ALL_OBJS +=\ + $(LOCAL_DIR)/benchmark.o \ + $(LOCAL_DIR)/L2V_Test.o \ + $(L2V_DIR)/L2V_Forget.o \ + $(L2V_DIR)/L2V_Free.o \ + $(L2V_DIR)/L2V_Funcs.o \ + $(L2V_DIR)/L2V_Init.o \ + $(L2V_DIR)/L2V_Mem.o \ + $(L2V_DIR)/L2V_Print.o \ + $(L2V_DIR)/L2V_Repack.o \ + $(L2V_DIR)/L2V_Search.o \ + $(L2V_DIR)/L2V_Types.o \ + $(L2V_DIR)/L2V_Update.o \ + $(L2V_DIR)/L2V_Valid.o + +IOP_HEAP_REQUIRED := $(call ADD,$(IOP_HEAP_REQUIRED),1048576) + diff --git a/drivers/flash_nand/boot/firmware/nand_firmware.c b/drivers/flash_nand/boot/firmware/nand_firmware.c new file mode 100644 index 0000000..dca5605 --- /dev/null +++ b/drivers/flash_nand/boot/firmware/nand_firmware.c @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_BLOCKDEV + +#include +#include +#include + +#include "nand_part.h" +#include "nand_part_interface.h" +#include "nand_export.h" +#include "nand_firmware.h" + +//#undef DEBUG_LEVEL +//#define DEBUG_LEVEL DEBUG_INFO + +/* ========================================================================== */ + +#define kNandFirmwareBDevName "nand_firmware" +#define kNandLLBBDevName "nand_llb" + +/* ========================================================================== */ + +static NandPartInterface * _npi; +static uint32_t _llb_index; +static uint32_t _firmware_index; +static bool _have_cache; +static uint32_t _cached_part; +static uint32_t _cached_block; +static uint32_t _cached_page; +static uint8_t * _page_cache; + +/* ========================================================================== */ + +static bool nand_firmware_cache_page(uint32_t part, uint32_t block, uint32_t page); +static int nand_firmware_read_block_handler(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count); +#if ALLOW_NAND_FIRMWARE_ERASE +static int nand_firmware_erase_block_handler(struct blockdev *bdev, off_t offset, uint64_t len); +#endif + + +/* ========================================================================== */ + +bool +nand_firmware_init(NandPartInterface *npi, uint32_t partIndex) +{ + const uint32_t page_size = npi_get_bytes_per_page(npi, partIndex); + struct blockdev * _bdev; + bool ok = false; + + _npi = npi; + _have_cache = false; + _cached_part = 0; + _cached_block = 0; + _cached_page = 0; + _page_cache = NULL; + _bdev = NULL; + + _bdev = malloc(sizeof(struct blockdev)); + _page_cache = (uint8_t*)memalign(page_size, CPU_CACHELINE_SIZE); + const uint32_t blockCount = npi_get_block_depth(_npi, partIndex); + const uint32_t pagesPerBlock = npi_get_pages_per_block(_npi, partIndex); + const off_t len = (blockCount * pagesPerBlock * page_size); + const NandPartEntry * entry = npi_get_entry(_npi, partIndex); + + switch (entry->content) { + case kNandPartContentFirmware: + _firmware_index = partIndex; + construct_blockdev(_bdev, kNandFirmwareBDevName, len, kNandPartSectorSize); + break; + case kNandPartContentBootBlock: + _llb_index = partIndex; + construct_blockdev(_bdev, kNandLLBBDevName, len, kNandPartSectorSize); + break; + default: + panic("Should never have been here\n"); + } + + _bdev->read_block_hook = &nand_firmware_read_block_handler; +#if ALLOW_NAND_FIRMWARE_ERASE + _bdev->erase_hook = &nand_firmware_erase_block_handler; +#endif + register_blockdev(_bdev); + + ok = true; + return(ok); +} + +static bool +nand_firmware_cache_page(uint32_t part, uint32_t block, uint32_t page) +{ + bool is_clean; + uint32_t bank; + + if (!_have_cache || (_cached_part != part) || (_cached_block != block) || (_cached_page != page)) { + _have_cache = false; + for (bank = 0; bank < npi_get_bank_width(_npi, part); bank++) { + if (npi_is_block_bad(_npi, part, bank, block)) { + dprintf(DEBUG_SPEW, + "WARNING: bad block (%d:%d:%d)\n", + part, bank, block); + continue; + } + if (npi_read_page(_npi, part, bank, block, page, _page_cache, &is_clean)) { + _have_cache = true; + _cached_part = part; + _cached_block = block; + _cached_page = page; + break; + } else { + dprintf(DEBUG_SPEW, + "WARNING: page read (%d:%d:%d:%d) failed\n", + part, bank, block, page); + } + } + } + + return(_have_cache); +} + +static int +nand_firmware_read_block_handler(struct blockdev *bdev, void *ptr, block_addr sector_addr, uint32_t sector_count) +{ + // this is a bit confusing, since a bdev "block" is not the same as a nand "block"; + // instead, the bdev "block" concept is mapped to a 512-byte virtual "sector" + + const uint32_t sector_base = 0; + uint32_t sector_limit = 0; + + uint32_t block_count; + uint32_t bytes_per_page; + uint32_t pages_per_block; + uint32_t bytes_per_block; + uint32_t sectors_per_block; + uint32_t sectors_per_page; + + uint32_t first_sector = 0; + uint32_t last_sector = 0; + + uint32_t sector_idx; + uint8_t * cursor = (uint8_t *)ptr; + uint32_t sectors_read = 0; + + uint32_t part; + + if (strcmp(bdev->name, kNandFirmwareBDevName) == 0) { + part = _firmware_index; + } else if (strcmp(bdev->name, kNandLLBBDevName) == 0) { + part = _llb_index; + } else { + /* Something wrong */ + dprintf(DEBUG_CRITICAL, + "ERROR: bad bdev: %s\n", + bdev->name); + return(-1); + } + + block_count = npi_get_block_depth(_npi, part); + bytes_per_page = npi_get_bytes_per_page(_npi, part); + pages_per_block = npi_get_pages_per_block(_npi, part); + bytes_per_block = (bytes_per_page * pages_per_block); + sectors_per_block = (bytes_per_block / kNandPartSectorSize); + sectors_per_page = (bytes_per_page / kNandPartSectorSize); + + sector_limit = (block_count * sectors_per_block); + + first_sector = (sector_base + sector_addr); + last_sector = (first_sector + sector_count - 1); + + if (last_sector > sector_limit) { + dprintf(DEBUG_CRITICAL, + "ERROR: 0x%08X-0x%08X not within 0x%08X-0x%08X\n", + first_sector, last_sector, sector_base, sector_limit); + return(-1); + } + + for (sector_idx = first_sector; sector_idx <= last_sector; sector_idx++) { + const uint32_t block = sector_idx / sectors_per_block; + const uint32_t sector_in_block = sector_idx % sectors_per_block; + const uint32_t page = sector_in_block / sectors_per_page; + const uint32_t offset = sector_in_block % sectors_per_page; + if (!nand_firmware_cache_page(part, block, page)) { + dprintf(DEBUG_SPEW, + "WARNING: unable to read firmware page 0x%X\n", + page); + break;; + } + memcpy(cursor, &_page_cache[offset * kNandPartSectorSize], kNandPartSectorSize); + sectors_read++; + cursor += kNandPartSectorSize; + } + + return(sectors_read); +} + +#if ALLOW_NAND_FIRMWARE_ERASE +static int +nand_firmware_erase_block_handler(struct blockdev *bdev, off_t offset, uint64_t len) +{ + uint32_t block_base = 0; + uint32_t block_num = 0; + bool llb_nuke = false; + uint32_t pages_per_block; + uint32_t bytes_per_page; + uint32_t bytes_per_block; + uint32_t part; + + if (strcmp(bdev->name, kNandFirmwareBDevName) == 0) { + part = _firmware_index; + } else if (strcmp(bdev->name, kNandLLBBDevName) == 0) { + part = _llb_index; + llb_nuke = true; + } else { + /* Something wrong */ + dprintf(DEBUG_CRITICAL, + "ERROR: bad bdev: %s\n", + bdev->name); + return(-1); + } + + pages_per_block = npi_get_pages_per_block(_npi, part); + bytes_per_page = npi_get_bytes_per_page(_npi, part); + bytes_per_block = (pages_per_block * bytes_per_page); + + /* Sanity check offset and len before erase, need to be page-size aligned */ + ASSERT(offset >= 0); + if ((uint64_t)offset >= bdev->total_len) + return 0; + if ((offset + len) > bdev->total_len) + len = bdev->total_len - offset; + if ((offset % bytes_per_block) || (len % bytes_per_block)) + return 0; + + block_num = (len / bytes_per_block); + block_base = (offset / bytes_per_block); + + for (UInt16 bank = 0; bank < npi_get_bank_width(_npi, part); bank++) { + /* Read the partition table in the case if LLB erase */ + if (llb_nuke) { + npi_erase_boot_partition(_npi); + } else { + for (UInt16 block = block_base; block < (block_base + block_num); block++) { + if (!npi_erase_block(_npi, part, bank, block)) { + dprintf(DEBUG_SPEW, + "WARNING: Erase(%d:%d:%d) failed\n", part, bank, block); + } + } + } + } + return(block_num * bytes_per_block); +} +#endif + +#endif /* WITH_BLOCKDEV */ + diff --git a/drivers/flash_nand/boot/firmware/nand_firmware.h b/drivers/flash_nand/boot/firmware/nand_firmware.h new file mode 100644 index 0000000..3419fa0 --- /dev/null +++ b/drivers/flash_nand/boot/firmware/nand_firmware.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _NAND_FIRMWARE_H_ +#define _NAND_FIRMWARE_H_ + +// The ability to erase firmware is only allowed for triage/development purposes. +#define ALLOW_NAND_FIRMWARE_ERASE (!RELEASE_BUILD && WITH_MENU && WITH_NAND_FIRMWARE) + +__BEGIN_DECLS + +bool nand_firmware_init(NandPartInterface *npi, uint32_t partIndex); + +__END_DECLS + +#endif // _NAND_FIRMWARE_H_ diff --git a/drivers/flash_nand/boot/firmware/rules.mk b/drivers/flash_nand/boot/firmware/rules.mk new file mode 100644 index 0000000..5ed14e9 --- /dev/null +++ b/drivers/flash_nand/boot/firmware/rules.mk @@ -0,0 +1,17 @@ +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_NAND_FIRMWARE=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/nand_firmware.o diff --git a/drivers/flash_nand/boot/nand_boot.c b/drivers/flash_nand/boot/nand_boot.c new file mode 100644 index 0000000..3736220 --- /dev/null +++ b/drivers/flash_nand/boot/nand_boot.c @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "nand_part.h" +#include "nand_part_interface.h" +#include "nand_export.h" + +#if WITH_NAND_FIRMWARE +# include "firmware/nand_firmware.h" +#endif + +#if WITH_NAND_NVRAM +# include "nvram/nand_nvram_platform.h" +# include "nvram/nand_nvram_impl.h" +#endif + +#if WITH_NAND_SYSCFG +# include +#endif + +#if WITH_EFFACEABLE_NAND +# include +#endif + +/* ========================================================================== */ + +#if WITH_NAND_NVRAM +extern bool flash_nand_nvram_init(NandPartInterface *npi, uint32_t part, bool isNewborn); +#endif + +// ============================================================================= + +static const char * kLogOrigin = "nand_boot"; + +#define _logLine(fac, fmt, args...) _logf_impl(kNandPartLogLevel##fac, "[%s:%s@%4d] " fmt "\n", kLogOrigin, kNandPartLogTag##fac, __LINE__, ##args) + +#define error(args...) _logLine(Error, ##args) +#define info(args...) _logLine(Info, ##args) + +#if NAND_PART_EXTENDED_LOGGING +# define warn(args...) _logLine(Warn, ##args) +#else +# define warn(args...) /* do nothing */ +#endif + +#if NAND_PART_EXTENDED_LOGGING +# define debug(args...) _logLine(Debug, ##args) +#else +# define debug(args...) /* do nothing */ +#endif + +#if NAND_PART_LOCAL_DEBUG_ONLY +# define spew(args...) _logLine(Spew, ##args) +#else +# define spew(args...) /* do nothing */ +#endif + +/* ========================================================================== */ + +#if NAND_PART_LOCAL_DEBUG_ONLY +static void +_conditionally_force_enable_uarts(void) +{ + static bool isEnabled = false; + if (!isEnabled) { + debug_enable_uarts(3); + isEnabled = true; + } +} +#else +# define _conditionally_force_enable_uarts() /* do nothing */ +#endif + +/* ========================================================================== */ + +static nand_boot_context_t _context; + +// ============================================================================= + +#if DEBUG_BUILD +# define USING_STRONG_SEED false +#else +# define USING_STRONG_SEED true +#endif + +// ============================================================================= + +#if DEBUG_BUILD +# define USING_STRONG_SEED false +#else +# define USING_STRONG_SEED true +#endif + +/* ========================================================================== */ + +// XXX - eliminate these references + +#if WITH_NAND_FILESYSTEM +extern uint32_t nand_fsys_block_offset; +#elif WITH_NAND_SYSCFG +uint32_t nand_fsys_block_offset; +#endif + +/* ========================================================================== */ + +static bool _create_partition_device(void * context, NandPartEntry * entry, uint32_t idx); +static bool _publish_partition_device(void * context, uint32_t idx); + +static void * _alloc_mem(void * context, unsigned size, bool align); +static int _compare_mem(void * context, const void * left, const void * right, unsigned int size); +static void * _move_mem(void * context, void * dest, const void * src, unsigned size); +static void * _set_mem(void * context, void * mem, uint8_t val, unsigned size); +static void _free_mem(void * context, void * mem, unsigned size); + +static void _lock_interface(void * context); +static void _unlock_interface(void * context); + +static void _read_random(void * context, void * buf, unsigned size); + +static bool _set_data_property(void * context, const char * key, void * buf, unsigned size); +static bool _set_number_property(void * context, const char * key, uint64_t num, unsigned bits); +static bool _set_string_property(void * context, const char * key, const char * cstring); +static bool _set_boolean_property(void * context, const char * key, bool val); + +static bool _wait_for_fbbt_service(void * context); + +static void _vlogf_message(void * context, NandPartLogLevel lvl, const char * fmt, va_list ap); +static void _vlogf_impl(NandPartLogLevel lvl, const char * fmt, va_list ap); +static void _logf_impl(NandPartLogLevel lvl, const char * fmt, ...); + +static void init_nand_part_callbacks(NandPartProvider *npp); +static void init_nand_part_params(NandPartProvider *npp); +static bool init_nand_boot_context(nand_boot_context_t * cxt); + +/* ========================================================================== */ + +int +nand_boot_init(void) +{ + bool ok = true; + static nand_boot_context_t * cxt = NULL; + + PROFILE_ENTER('NBI'); + + // If we've already been initialized for some reason, short + // circuit and finish. + require(NULL == cxt, finish); + cxt = &_context; + + info("nand_boot_init() starting"); + + ok = init_nand_boot_context(cxt); + require(ok, finally); + + spew("initializing nand_part subsystem"); + ok = nand_part_init(&cxt->npi, &cxt->npp); + require(ok, finally); + + spew("scanning for nand boot partition tables"); + ok = npi_load_ptab(cxt->npi); + require(ok, finally); + +#if WITH_NAND_SYSCFG + // Defer syscfg init until after file system has finished initializing. + // + // XXX - Open FTL before first syscfg request + if (cxt->syscfg_needs_init && cxt->found_fsys_offset) { + if (0 != nand_syscfg_init(cxt->npi)) { + spew("unable to init syscfg"); + ok = false; + } + } +#endif + +finally: + +#if WITH_NAND_NVRAM + // If nvram feature is needed but unable to find valid nand + // nvram partition entry for any reason, create a mock + // ram-based nvram device so that the system won't hang when + // attempting to read the environment settings + // (). + if (!cxt->have_nvram_part) { + if (!flash_nand_nvram_init(cxt->npi, kNandPartEntryMaxCount, true)) { + spew("unable to create temporary nvram device"); + ok = false; + } + } +#endif + + info("nand_boot_init() %s", ok ? "succeeded" : "failed"); + +finish: + PROFILE_EXIT('NBI'); + return(ok ? 0 : -1); +} + +/* ========================================================================== */ + +static bool +_create_partition_device(void * context, NandPartEntry * entry, uint32_t idx) +{ + bool ok = true; + nand_boot_context_t * cxt = withContext(context); + + if (kNandPartEntryMaxCount != idx) { + switch (entry->content) { + case kNandPartContentSyscfg: + cxt->syscfg_needs_init = true; + break; + case kNandPartContentNVRAM: + cxt->have_nvram_part = true; + break; + default: + // nothing to do for most cases + break; + } + } + + return ok; +} + +static bool +_publish_partition_device(void * context, uint32_t idx) +{ + bool ok = true; + nand_boot_context_t * cxt = withContext(context); + const NandPartEntry * entry = NULL; + + if (kNandPartEntryMaxCount == idx) { + debug("nand has not yet been formatted\n"); + return ok; + } + + entry = npi_get_entry(cxt->npi, idx); + switch (entry->content) { + case kNandPartContentBootBlock: +#if ALLOW_NAND_FIRMWARE_ERASE + // The only reason to publish boot block device is to allow + // the erasure of LLB in triage/development use cases. + if (!nand_firmware_init(cxt->npi, idx)) { + spew("unable to create nand LLB device\n"); + ok = false; + } +#endif + break; + case kNandPartContentNVRAM: +#if WITH_NAND_NVRAM + if (!flash_nand_nvram_init(cxt->npi, idx, false)) { + spew("unable to create nand nvram device\n"); + ok = false; + } +#endif + break; + case kNandPartContentFirmware: +#if WITH_NAND_FIRMWARE + if (!nand_firmware_init(cxt->npi, idx)) { + spew("unable to create nand firmware device\n"); + ok = false; + } +#endif + break; + case kNandPartContentFilesystem: + cxt->found_fsys_offset = true; + cxt->fsys_block_offset = entry->slice.offset; +#if WITH_NAND_SYSCFG + nand_fsys_block_offset = entry->slice.offset; +#elif WITH_NAND_FILESYS + // XXX never reachable + nand_fsys_block_offset = entry->slice.offset; +#endif + break; + case kNandPartContentEffaceable: +#if WITH_EFFACEABLE_NAND + effaceable_nand_init(cxt->npi, idx); +#endif + break; + default: + // nothing to do... + ok = true; + } + + return ok; +} + +/* ========================================================================== */ + +static void * +_alloc_mem(void * context, unsigned size, bool align) +{ + void * buf = NULL; + + if (align) { + buf = memalign(size, CPU_CACHELINE_SIZE); + } else { + buf = malloc(size); + } + + return(buf); +} + +static int +_compare_mem(void * context, const void * left, const void * right, unsigned int size) +{ + return(memcmp(left, right, size)); +} + +static void * +_move_mem(void * context, void * dest, const void * src, unsigned size) +{ + return(memmove(dest, src, size)); +} + +static void * +_set_mem(void * context, void * mem, uint8_t val, unsigned size) +{ + return(memset(mem, val, size)); +} + +static void +_free_mem(void * context, void * mem, unsigned size) +{ + free(mem); +} + +static void +_lock_interface(void * context) +{ + // XXX - Given its cooperative multitasking nature, does iBoot + // even need to bother with locking the nand_part_core + // interface? +} + +static void +_unlock_interface(void * context) +{ + // XXX - Given its cooperative multitasking nature, does iBoot + // even need to bother with locking the nand_part_core + // interface? +} + +static void +_read_random(void * context, void * buf, unsigned size) +{ + static bool is_seeded = false; + const unsigned increment = sizeof(int); + uint8_t * cursor = (uint8_t *)buf; + unsigned idx; + + // if we're using a strong seed, draw from the entropy pool to + // re-seed psuedo-random generator the first time function is called + if (!is_seeded && USING_STRONG_SEED) { + unsigned int seed; + random_get_bytes((u_int8_t*)&seed, sizeof(seed)); + srand(seed); + is_seeded = true; + } + + // fill with psuedo-random values by 'int'-sized chunks as long as possible + for (idx = 0; (idx + increment) <= size; idx += increment, cursor += increment) { + *((int*)cursor) = rand(); + } + + // if size doesn't divide evenly by increment, fill fringe bytewise + for (; idx < size; idx++, cursor++) { + *cursor = (uint8_t)rand(); + } +} + +static bool +_set_data_property(void * context, const char * key, void * buf, unsigned size) +{ + spew("%s=[%02x %02x %02x %02x ...]", + key, ((uint8_t*)buf)[0], ((uint8_t*)buf)[1], ((uint8_t*)buf)[2], ((uint8_t*)buf)[3]); + return true; +} + +static bool +_set_number_property(void * context, const char * key, uint64_t num, unsigned bits) +{ + spew("%s=%llu", key, num); + return true; +} + +static bool +_set_string_property(void * context, const char * key, const char * cstring) +{ + spew("%s=%s", key, cstring); + return true; +} + +static bool +_set_boolean_property(void * context, const char * key, bool val) +{ + spew("%s=%s", key, val ? "true" : "false"); + return true; +} + +static bool +_wait_for_fbbt_service(void * context) +{ + // This callback is not relevant in iBoot context. + return true; +} + +static void +_vlogf_message(void * context, NandPartLogLevel lvl, const char * fmt, va_list ap) +{ + _vlogf_impl(lvl, fmt, ap); +} + +static void +_vlogf_impl(NandPartLogLevel lvl, const char * fmt, va_list ap) +{ +#if DEBUG_BUILD + const NandPartLogLevel max_level = kNandPartLogLevelDebug; +#elif DEVELOPMENT_BUILD + const NandPartLogLevel max_level = kNandPartLogLevelInfo; +#else + const NandPartLogLevel max_level = kNandPartLogLevelError; +#endif + + // XXX - Implement circular log buffer to help triage failures + // before debug uart is turned on in development and debug + // builds. + + if (max_level >= lvl) { + if ((kNandPartLogLevelError == lvl) || (kNandPartLogLevelBug == lvl)) { + _conditionally_force_enable_uarts(); + } + vprintf(fmt, ap); + } +} + +static void +_logf_impl(NandPartLogLevel lvl, const char * fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + _vlogf_impl(lvl, fmt, ap); + va_end(ap); +} + +/* ========================================================================== */ + +static void +init_nand_part_callbacks(NandPartProvider *npp) +{ + npp->lock_interface = _lock_interface; + npp->unlock_interface = _unlock_interface; + npp->alloc_mem = _alloc_mem; + npp->compare_mem = _compare_mem; + npp->move_mem = _move_mem; + npp->set_mem = _set_mem; + npp->free_mem = _free_mem; + npp->read_random = _read_random; + npp->set_data_property = _set_data_property; + npp->set_number_property = _set_number_property; + npp->set_string_property = _set_string_property; + npp->set_boolean_property = _set_boolean_property; + npp->wait_for_fbbt_service = _wait_for_fbbt_service; + npp->create_partition_device = _create_partition_device; + npp->publish_partition_device = _publish_partition_device; + npp->vlogf_message = _vlogf_message; + + // The following callbacks are initialized by nand_export_init(): + // + // npp->read_boot_page + // npp->read_full_page + // npp->write_boot_page + // npp->write_full_page + // npp->erase_block + // npp->is_block_factory_bad + // npp->validate_spare_list + // npp->request_spare_blocks +} + +static void +init_nand_part_params(NandPartProvider *npp) +{ + // The only destructive operation allowed on boot block is + // erase of boot partition (i.e. LLB portion but not partition + // table copies), available only in debug builds. +#if ALLOW_NAND_FIRMWARE_ERASE + npp->params.isBootPartErasable = true; +#else + npp->params.isBootPartErasable = false; +#endif + npp->params.isBootPartWritable = false; + npp->params.isFormatEnabled = false; + + // Enable debug-only features only in debug builds of iBoot. +#if DEBUG_BUILD + npp->params.isDebugEnabled = true; +#else + npp->params.isDebugEnabled = false; +#endif + + // In iBoot, only enable tracing for local developer builds. + npp->params.isHostTraceEnabled = false; + npp->params.isClientTraceEnabled = false; +} + +/* ========================================================================== */ + +static bool +init_nand_boot_context(nand_boot_context_t * cxt) +{ + memset(cxt, 0, sizeof(nand_boot_context_t)); + cxt->npp.context = cxt; + + init_nand_part_params(&cxt->npp); + init_nand_part_callbacks(&cxt->npp); + + return nand_export_init(cxt); +} + +/* ========================================================================== */ + +static int do_nand_failval_set(int argc, struct cmd_arg *args) +{ + nand_failval_set(args[1].n, args[2].n); + return 0; +} + +MENU_COMMAND_DEBUG(nand_failval_set, do_nand_failval_set, "Set the number of operations before failure is injected", NULL); + +// ============================================================================= + +static int do_nand_part_dump(int argc, struct cmd_arg *args) +{ + nand_part_dump(_context.npi); + return 0; +} + +MENU_COMMAND_DEBUG(nand_part_dump, do_nand_part_dump, "dump nand partition table info", NULL); + +// ============================================================================= + diff --git a/drivers/flash_nand/boot/nand_export.c b/drivers/flash_nand/boot/nand_export.c new file mode 100644 index 0000000..6de4091 --- /dev/null +++ b/drivers/flash_nand/boot/nand_export.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +#include + +#include "nand_part.h" +#include "nand_part_interface.h" +#include "nand_export.h" + +#include +#include +#include + +#include "ANDTypes.h" +#include "WMRFeatures.h" + +// ============================================================================= + +#define _log(fac, line, fmt, args...) dprintf(DEBUG_CRITICAL, "[nand_export.c : %s @ %4d] " fmt "\n", kNandPartLogTag##fac, line, ##args) + +#define error(args...) _log(Error, __LINE__, ##args) +#define info(args...) _log(Info, __LINE__, ##args) + +#if NAND_PART_EXTENDED_LOGGING +# define warn(args...) _log(Warn, __LINE__, ##args) +# define debug(args...) _log(Debug, __LINE__, ##args) +#else +# define warn(args...) /* do nothing */ +# define debug(args...) /* do nothing */ +#endif + +#if NAND_PART_LOCAL_DEBUG_ONLY +# define spew(args...) _log(Spew, __LINE__, ##args) +#else +# define spew(args...) /* do nothing */ +#endif + +/* ========================================================================== */ + +static bool _read_boot_page(void * context, uint32_t ce, uint32_t addr, void * buf, bool * is_clean); +static bool _read_full_page(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta, bool * is_clean); +static bool _write_boot_page(void * context, uint32_t ce, uint32_t addr, void * buf); +static bool _write_full_page(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta); +static bool _erase_block(void * context, uint32_t ce, uint32_t addr, uint32_t block); + +static bool _is_block_factory_bad(void * context, uint32_t ce, uint32_t block); +static bool _validate_spare_list(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count); +static bool _request_spare_blocks(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count, unsigned * quantity); + +static void _init_nand_export_geometry(NandPartProvider *npp); +static void _init_nand_export_callbacks(NandPartProvider *npp); + +static int failVal[] = {0, 0, 0}; +static int numOps[] = {0, 0, 0}; + +/* ========================================================================== */ + +static bool +_read_boot_page(void * context, uint32_t ce, uint32_t addr, void * buf, bool * is_clean) +{ + Int32 ret; + nand_boot_context_t * cxt = withContext(context); + + require(cxt->is_fil_available, no_fil); + require(0 != FIL_GetFuncTbl()->ReadBLPage, no_op); + ret = FIL_GetFuncTbl()->ReadBLPage(ce, addr, buf); + if (NULL != is_clean) { + *is_clean = (ANDErrorCodeCleanOk == ret); + } + + numOps[READ_OP]++; + if (failVal[READ_OP] > 0 && numOps[READ_OP] >= failVal[READ_OP]) { + debug("*** injecting error ***\n"); + numOps[READ_OP] = 0; + return false; + } + + return((ANDErrorCodeOk == ret) ? true : false); + +no_op: +#if RELEASE_BUILD + error("no FIL ReadBLPage"); +#else + panic("no FIL ReadBLPage"); +#endif + +no_fil: + return false; +} + +static bool +_read_full_page(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta, bool * is_clean) +{ + Int32 ret; + nand_boot_context_t * cxt = withContext(context); + + require(cxt->is_fil_available, no_fil); + require(0 != FIL_GetFuncTbl()->ReadWithECC, no_op); + ret = FIL_GetFuncTbl()->ReadWithECC(ce, addr, buf, meta, NULL, NULL, false); + if (NULL != is_clean) { + *is_clean = (ANDErrorCodeCleanOk == ret); + } + + numOps[READ_OP]++; + if (failVal[READ_OP] > 0 && numOps[READ_OP] >= failVal[READ_OP]) { + debug("*** injecting error ***\n"); + numOps[READ_OP] = 0; + return false; + } + return((ANDErrorCodeOk == ret) ? true : false); + +no_op: +#if RELEASE_BUILD + error("no FIL ReadWithECC"); +#else + panic("no FIL ReadWithECC"); +#endif + +no_fil: + return false; +} + +static bool +_write_boot_page(void * context, uint32_t ce, uint32_t addr, void * buf) +{ + Int32 ret; + nand_boot_context_t * cxt = withContext(context); + + require(cxt->is_fil_available, no_fil); + require(0 != FIL_GetFuncTbl()->WriteBLPage, no_op); + ret = FIL_GetFuncTbl()->WriteBLPage(ce, addr, buf); + + numOps[WRITE_OP]++; + if (failVal[WRITE_OP] > 0 && numOps[WRITE_OP] >= failVal[WRITE_OP]) { + debug("*** injecting error ***\n"); + numOps[WRITE_OP] = 0; + return false; + } + + return((ANDErrorCodeOk == ret) ? true : false); + +no_op: +#if RELEASE_BUILD + error("no FIL WriteBLPage"); +#else + panic("no FIL WriteBLPage"); +#endif + +no_fil: + return false; +} + +static bool +_write_full_page(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta) +{ + Int32 ret; + nand_boot_context_t * cxt = withContext(context); + + require(cxt->is_fil_available, no_fil); + require(0 != FIL_GetFuncTbl()->Write, no_op); + ret = FIL_GetFuncTbl()->Write(ce, addr, buf, meta, false); + + numOps[WRITE_OP]++; + if (failVal[WRITE_OP] > 0 && numOps[WRITE_OP] >= failVal[WRITE_OP]) { + debug("*** injecting error ***\n"); + numOps[WRITE_OP] = 0; + return false; + } + + return((ANDErrorCodeOk == ret) ? true : false); + +no_op: +#if RELEASE_BUILD + error("no FIL Write"); +#else + panic("no FIL Write"); +#endif + +no_fil: + return false; +} + +static bool +_erase_block(void * context, uint32_t ce, uint32_t addr, uint32_t block) +{ + Int32 ret; + nand_boot_context_t * cxt = withContext(context); + + require(cxt->is_fil_available, no_fil); + require(0 != FIL_GetFuncTbl()->Erase, no_op); + + // In iBoot, the FIL erase command expects an block offset; + // however, other environments may expect an address instead. + ret = FIL_GetFuncTbl()->Erase(ce, block); + + numOps[ERASE_OP]++; + if (failVal[ERASE_OP] > 0 && numOps[ERASE_OP] >= failVal[ERASE_OP]) { + debug("*** injecting error ***\n"); + numOps[ERASE_OP] = 0; + return false; + } + + return((ANDErrorCodeOk == ret) ? true : false); + +no_op: +#if RELEASE_BUILD + error("no FIL Erase"); +#else + panic("no FIL Erase"); +#endif + +no_fil: + return false; +} + +/* ========================================================================== */ + +static bool +_is_block_factory_bad(void * context, uint32_t ce, uint32_t block) +{ + // XXX - Access to factory bad block table not yet supported + // in iBoot context. This probably should be fixed from an + // academic perspective; however, by the time we've finished + // formatting during first restore in iOS, the problem of + // factory bad blocks should be moot for nand_part_core. + return false; +} + +static bool +_validate_spare_list(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count) +{ + // XXX - Double-checking spare block list against what VFL + // believes it should be is not yet supported in iBoot; therefore, + // for the moment, simply lie when asked and say that all is well. + return true; +} + +static bool +_request_spare_blocks(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count, unsigned * quantity) +{ + // Requesting spare blocks should only happen as a result of + // initial format (in iOS); therefore, it's a bug if this + // callback is ever in invoked in iBoot. +#if RELEASE_BUILD + error("unexpected callback requesting spare blocks\n"); +#else + panic("unexpected callback requesting spare blocks\n"); +#endif + return false; +} + +/* ========================================================================== */ + +static void +_init_nand_export_geometry(NandPartProvider *npp) +{ + npp->geometry.isPpn = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_PPN_DEVICE); + + npp->geometry.ceCount = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + + /* The value of AND_DEVINFO_BLOCKS_PER_CS should NOT be used for PPN */ + npp->geometry.blocksPerCE = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); + npp->geometry.blockStride = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BLOCK_STRIDE); + + npp->geometry.pagesPerMLCBlock = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_MLC_PAGES_PER_BLOCK); + npp->geometry.pagesPerSLCBlock = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_SLC_PAGES_PER_BLOCK); + + npp->geometry.bytesPerBootPage = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BYTES_PER_BL_PAGE); + npp->geometry.bytesPerFullPage = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + npp->geometry.bytesPerFullPageMeta = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES) * FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + + npp->geometry.bitsPerCauAddr = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BITS_PER_CAU_ADDRESS); + npp->geometry.bitsPerPageAddr = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BITS_PER_PAGE_ADDRESS); + npp->geometry.bitsPerBlockAddr = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BITS_PER_BLOCK_ADDRESS); +} + +static void +_init_nand_export_callbacks(NandPartProvider *npp) +{ + npp->read_boot_page = _read_boot_page; + npp->read_full_page = _read_full_page; + npp->write_boot_page = _write_boot_page; + npp->write_full_page = _write_full_page; + npp->erase_block = _erase_block; + npp->is_block_factory_bad = _is_block_factory_bad; + npp->validate_spare_list = _validate_spare_list; + npp->request_spare_blocks = _request_spare_blocks; +} + +/* ========================================================================== */ + +bool +nand_export_init(nand_boot_context_t * cxt) +{ + bool ok = false; + Int32 ret = 0; + NandPartProvider *npp = &(cxt->npp); + + ret = FIL_Init(); + + // Always export callbacks. Even if FIL failed to init, they + // will be protected internally by 'cxt->is_fil_available'. + _init_nand_export_callbacks(npp); + + if (ANDErrorCodeOk == ret) { + _init_nand_export_geometry(npp); + ok = true; + } else { + dprintf(DEBUG_SPEW, "unable to init nand FIL\n"); + ok = false; + } + + cxt->is_fil_available = ok; + return ok; +} + +/* ========================================================================== */ + + +extern void +nand_failval_set(int op_num, int fail_val) +{ + int i; + failVal[op_num] = fail_val; + + /* print out the failure values set for each operation + * where i = 0 = READ, i = 1 = WRITE, and i = 2 = ERASE + */ + for (i = 0; i < 3; i++) + debug("%d %d\n", i, failVal[i]); +} + + diff --git a/drivers/flash_nand/boot/nand_export.h b/drivers/flash_nand/boot/nand_export.h new file mode 100644 index 0000000..05f68e0 --- /dev/null +++ b/drivers/flash_nand/boot/nand_export.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _NAND_EXPORT_H +#define _NAND_EXPORT_H + +__BEGIN_DECLS + +struct _nand_boot_context +{ + NandPartProvider npp; + NandPartInterface * npi; + + bool is_fil_available; + bool syscfg_needs_init; + bool have_nvram_part; + bool found_fsys_offset; + + uint32_t fsys_block_offset; +}; + +typedef struct _nand_boot_context nand_boot_context_t; + +#define withContext(_ctxt) ((nand_boot_context_t*)(_ctxt)) + +bool nand_export_init(nand_boot_context_t * cxt); +void nand_failval_set(int op_num, int fail_val); + +#define READ_OP 0 +#define WRITE_OP 1 +#define ERASE_OP 2 + +__END_DECLS + +#endif /* ! _NAND_EXPORT_H */ diff --git a/drivers/flash_nand/boot/nand_part.h b/drivers/flash_nand/boot/nand_part.h new file mode 100644 index 0000000..4c2587d --- /dev/null +++ b/drivers/flash_nand/boot/nand_part.h @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +/*! + @header nand_part + + @abstract definition of device-resident persistent partition table + + @copyright Apple Inc. + + @updated 2012-02-21 +*/ + +/* ========================================================================== */ + +#ifndef _NAND_PART_H +#define _NAND_PART_H + +#include + +__BEGIN_DECLS + + +// ============================================================================= +// feature introduction version history + +#define kNandPartFeatureInitialVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeatureFBBTCacheVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeatureEffaceableVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeatureIgnoreFBBTVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeatureTrimDeviceVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeatureFuneralDirgeVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeatureCleanEntryFlagsVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeaturePortableCoreVersionMajor ((uint32_t)0x00000000) +#define kNandPartFeaturePoolPartitionVersionMajor ((uint32_t)0x00000001) + +#define kNandPartFeatureInitialVersionMinor ((uint32_t)0x00000001) +#define kNandPartFeatureFBBTCacheVersionMinor ((uint32_t)0x00000002) +#define kNandPartFeatureEffaceableVersionMinor ((uint32_t)0x00000003) +#define kNandPartFeatureIgnoreFBBTVersionMinor ((uint32_t)0x00000004) +#define kNandPartFeatureTrimDeviceVersionMinor ((uint32_t)0x00000005) +#define kNandPartFeatureFuneralDirgeVersionMinor ((uint32_t)0x00000006) +#define kNandPartFeatureCleanEntryFlagsVersionMinor ((uint32_t)0x00000007) +#define kNandPartFeaturePortableCoreVersionMinor ((uint32_t)0x00000008) +#define kNandPartFeaturePoolPartitionVersionMinor ((uint32_t)0x00000009) + + +// ============================================================================= +// release version history - for historical reference only + +#define kNandPartReleaseNorthstarVersionMajor kNandPartFeatureFBBTCacheVersionMajor +#define kNandPartReleaseNorthstarVersionMinor kNandPartFeatureFBBTCacheVersionMinor + +#define kNandPartReleaseNorthstar2VersionMajor kNandPartFeatureFBBTCacheVersionMajor +#define kNandPartReleaseNorthstar2VersionMinor kNandPartFeatureFBBTCacheVersionMinor + +#define kNandPartReleaseApexVersionMajor kNandPartFeatureIgnoreFBBTVersionMajor +#define kNandPartReleaseApexVersionMinor kNandPartFeatureIgnoreFBBTVersionMinor + +#define kNandPartReleaseBakerVersionMajor kNandPartFeatureFuneralDirgeVersionMajor +#define kNandPartReleaseBakerVersionMinor kNandPartFeatureFuneralDirgeVersionMinor + +#define kNandPartReleaseDurangoVersionMajor kNandPartFeatureFuneralDirgeVersionMajor +#define kNandPartReleaseDurangoVersionMinor kNandPartFeatureFuneralDirgeVersionMinor + +#define kNandPartReleaseTellurideVersionMajor kNandPartFeatureFuneralDirgeVersionMajor +#define kNandPartReleaseTellurideVersionMinor kNandPartFeatureFuneralDirgeVersionMinor + +#define kNandPartReleaseHoodooVersionMajor kNandPartFeatureFuneralDirgeVersionMajor +#define kNandPartReleaseHoodooVersionMinor kNandPartFeatureFuneralDirgeVersionMinor + +#define kNandPartReleaseSundanceVersionMajor kNandPartFeaturePoolPartitionVersionMajor +#define kNandPartReleaseSundanceVersionMinor kNandPartFeaturePoolPartitionVersionMinor + + +// ============================================================================= +// general constants + +#define kNandPartSectorSize 512 +#define kNandPartSectorsPerPage 3 +#define kNandPartPageSize (kNandPartSectorSize * kNandPartSectorsPerPage) +#define kNandPartBankMax 16 + + +// ============================================================================= +// partition header + +typedef struct _NandPartHeader { + + uint32_t magic; + uint32_t should_be_zero; + uint32_t versionMajor; + uint32_t versionMinor; + uint32_t generation; + uint8_t reserved[12]; + +} __attribute__((__packed__)) NandPartHeader; + +#define kNandPartHeaderMagic 'Grdn' + +#define kNandPartHeaderVersionMajor kNandPartReleaseSundanceVersionMajor +#define kNandPartHeaderVersionMinor kNandPartReleaseSundanceVersionMinor + +#define kNandPartHeaderMaxSize (kNandPartSectorSize / 16) + + +// ============================================================================= +// partition factory BBT cache + +typedef struct _NandPartFBBTCacheInfo { + + uint32_t blockDepth; + uint32_t entryCount; + +} __attribute__((__packed__)) NandPartFBBTCacheInfo; + +#define kNandPartFBBTCacheMaxSize (kNandPartSectorSize - kNandPartHeaderMaxSize) +#define kNandPartFBBTCacheEntriesMaxSize (kNandPartFBBTCacheMaxSize - sizeof(NandPartFBBTCacheInfo)) + +typedef struct _NandPartFBBTCacheEntry { + + uint32_t bankNum; + uint32_t blockAddr; + +} __attribute__((__packed__)) NandPartFBBTCacheEntry; + +#define kNandPartFBBTCacheEntryCount (kNandPartFBBTCacheEntriesMaxSize / sizeof(NandPartFBBTCacheEntry)) + +typedef struct _NandPartFBBTCache { + + NandPartFBBTCacheInfo info; + NandPartFBBTCacheEntry entries[kNandPartFBBTCacheEntryCount]; + +} __attribute__((__packed__)) NandPartFBBTCache; + + +// ============================================================================= +// partition device info + +typedef struct _NandPartDevice { + + uint32_t should_be_zero[2]; + uint32_t should_be_one; + + uint32_t numOfCS; + uint32_t blocksPerCS; + uint32_t pagesPerBlock; + uint32_t sectorsPerPage; + uint32_t spareBytesPerPage; + + uint32_t flags; + +} __attribute__((__packed__)) NandPartDevice; + +#define kNandPartDeviceFlagNone ((uint32_t)0x00000000) +#define kNandPartDeviceFlagNeedsCemetery (((uint32_t)0x1) << 0) +#define kNandPartDeviceFlagExplicitEntries (((uint32_t)0x1) << 1) +#define kNandPartDeviceFlagAllowPool (((uint32_t)0x1) << 2) + + +// ============================================================================= +// cemetery +// +// Where bad blocks go to die. + +#define kNandPartCemeteryGate ((uint32_t) 0xDeadCafe) +#define kNandPartCemeteryCapacity 256 +#define nandPartCemeteryPlotsSize(capacity) (((capacity) / 8) + (((capacity) % 8) ? 1 : 0)) +#define kNandPartCemeteryPlotsSize nandPartCemeteryPlotsSize(kNandPartCemeteryCapacity) + +typedef struct _NandPartCemetery { + + uint32_t gate; + uint16_t capacity; + uint8_t flags; + uint8_t reserved[3]; + uint8_t plots[kNandPartCemeteryPlotsSize]; + uint8_t locks[2]; + +} __attribute__((__packed__)) NandPartCemetery; + +#define kNandPartCemeteryFlagIgnoreLocks ((uint8_t)0x01) + + +// ============================================================================= +// spare blocks + +#define kNandPartSpareMaxCount 64 +#define kNandPartSpareMagic 'spAr' + +typedef struct _NandPartSpareLocation { + + uint8_t block[3]; + uint8_t ce; + +} __attribute__((__packed__)) NandPartSpareLocation; + +typedef struct _NandPartSpare { + + uint32_t magic; + uint16_t count; + uint8_t flags; + uint8_t reserved[3]; + NandPartSpareLocation locations[kNandPartSpareMaxCount]; + uint8_t checks[2]; + +} __attribute__((__packed__)) NandPartSpare; + +#define kNandPartSpareFlagIgnoreChecks ((uint8_t)0x01) +#define kNandPartSpareMinExtraCount 4 + + +// ============================================================================= +// block substitutions + +#define kNandPartSubstMaxCount kNandPartSpareMaxCount +#define kNandPartSubstMagic 'subs' + +typedef struct _NandPartSubst { + + uint32_t magic; + uint16_t count; + uint8_t flags; + uint8_t reserved[3]; + uint8_t maps[kNandPartSubstMaxCount]; + uint8_t checks[2]; + +} __attribute__((__packed__)) NandPartSubst; + +#define kNandPartSubstFlagIgnoreChecks ((uint8_t)0x01) +#define kNandPartSubstFlagCorrectedChecks ((uint8_t)0x02) + + +// ============================================================================= +// unused + +#define kNandPartUnusedSize (kNandPartSectorSize \ + - sizeof(NandPartDevice) \ + - sizeof(NandPartCemetery) \ + - sizeof(NandPartSpare) \ + - sizeof(NandPartSubst)) + + +// ============================================================================= +// partition content + +#define kNandPartContentUndefined 0x00000000 +#define kNandPartContentNone 'none' +#define kNandPartContentBootBlock 'boot' +#define kNandPartContentDiagData 'diag' +#define kNandPartContentSyscfg 'scfg' +#define kNandPartContentFirmware 'firm' +#define kNandPartContentNVRAM 'nvrm' +#define kNandPartContentFilesystem 'fsys' +#define kNandPartContentEffaceable 'plog' +#define kNandPartContentBadBlockTable 'fbbt' +#define kNandPartContentErased 0xFFFFFFFF + +#define kNandPartContentNameUnformatted "Unformatted" +#define kNandPartContentNameUnallocated "Unallocated" +#define kNandPartContentNameUnrecognized "Unrecognized" +#define kNandPartContentNameBootBlock "Boot Block" +#define kNandPartContentNameDiagData "Diagnostic Data" +#define kNandPartContentNameSyscfg "System Config" +#define kNandPartContentNameNVRAM "NVRAM" +#define kNandPartContentNameFirmware "Firmware" +#define kNandPartContentNameFilesystem "Filesystem" +#define kNandPartContentNameEffaceable "Effaceable" +#define kNandPartContentNameBadBlockTable "Bad Block Table" + + +// ============================================================================= +// partition entry + +typedef struct _NandPartEntryInfo { + + uint32_t content; + uint32_t reserved_0; + uint32_t reserved_1; + uint32_t flags; + +} __attribute__((__packed__)) NandPartEntryInfo; + +typedef struct _NandPartEntrySlice { + + uint32_t content; + uint32_t offset; + uint32_t depth; + uint32_t flags; + +} __attribute__((__packed__)) NandPartEntrySlice; + +typedef struct _NandPartEntryPool { + + uint32_t content; + uint32_t width; + uint32_t depth; + uint32_t flags; + +} __attribute__((__packed__)) NandPartEntryPool; + +typedef union _NandPartEntry { + + struct { + + uint32_t content; + uint32_t reserved_0; + uint32_t reserved_1; + uint32_t flags; + + } __attribute__((__packed__)); + + NandPartEntryInfo info; + NandPartEntrySlice slice; + NandPartEntryPool pool; + +} NandPartEntry; + +#define kNandPartEntryMaxCount (kNandPartSectorSize / sizeof(NandPartEntry)) + +#define kNandPartEntryFlagsNone 0x00000000 + +#define kNandPartEntryFlagsTypeInfo 0x00000001 +#define kNandPartEntryFlagsTypeSlice 0x00000002 +#define kNandPartEntryFlagsTypePool 0x00000008 +#define kNandPartEntryFlagsUnpartitioned 0x80000000 + +#define kNandPartEntryFlagsTypeMask (kNandPartEntryFlagsTypeInfo | \ + kNandPartEntryFlagsTypeSlice | \ + kNandPartEntryFlagsTypePool | \ + kNandPartEntryFlagsUnpartitioned) + +#define kNandPartEntryFlagsIsBulk 0x00000004 +#define kNandPartEntryFlagsUsingSLCBlocks 0x00000100 +#define kNandPartEntryFlagsUsingFullPages 0x00000200 +#define kNandPartEntryFlagsIgnoreFBBT 0x40000000 + +#define kNandPartEntryFlagsMiscMask (kNandPartEntryFlagsIsBulk | \ + kNandPartEntryFlagsUsingSLCBlocks | \ + kNandPartEntryFlagsUsingFullPages | \ + kNandPartEntryFlagsIgnoreFBBT) + +#define kNandPartEntryFlagsMask (kNandPartEntryFlagsTypeMask | \ + kNandPartEntryFlagsMiscMask) + + +// ============================================================================= +// partition table + +typedef struct _NandPartTable { + + NandPartHeader header; + NandPartFBBTCache fbbtCache; + NandPartDevice device; + NandPartCemetery cemetery; + NandPartSpare spare; + NandPartSubst subst; + uint8_t unused[kNandPartUnusedSize]; + NandPartEntry entries[kNandPartEntryMaxCount]; + +} __attribute__((__packed__)) NandPartTable; + +#define kNandPartTableLayoutIsValid (sizeof(NandPartTable) == kNandPartPageSize) +#define kNandPartTableCopies 2 + + +// ============================================================================= +// partition table incremental differences +// +// incremental difference information about the current partition +// table state that is stored in metadata of other on-nand containers +// (e.g. nvram, effaceable) rather than in partition table itself + +typedef struct _NandPartDiffHeader { + + uint32_t magic; + uint16_t size; + uint16_t sequence; + uint32_t versionMajor; + uint32_t versionMinor; + uint32_t generation; + uint16_t flags; + uint8_t reserved[10]; + +} __attribute__((__packed__)) NandPartDiffHeader; + +typedef struct _NandPartDiff { + + NandPartDiffHeader header; + NandPartCemetery cemetery; + uint8_t checks[2]; + +} __attribute__((__packed__)) NandPartDiff; + +#define kNandPartDiffMagic 'Diff' +#define kNandPartDiffFlagIgnoreChecks ((uint16_t)0x0001) + + +// ============================================================================= +// boot loader + +#define kNandPartLoaderPageCount 128 +#define kNandPartLoaderMaxPages (kNandPartLoaderPageCount - kNandPartTableCopies - 1) +#define kNandPartLoaderMaxSize (kNandPartLoaderMaxPages * kNandPartPageSize) + + +// ============================================================================= +// generally useful macros + +#define isMaskSet(_msk, _val) ((_msk) == ((_msk) & (_val))) + + +__END_DECLS + +#endif /* ! _NAND_PART_H */ diff --git a/drivers/flash_nand/boot/nand_part_core.c b/drivers/flash_nand/boot/nand_part_core.c new file mode 100644 index 0000000..e42bf51 --- /dev/null +++ b/drivers/flash_nand/boot/nand_part_core.c @@ -0,0 +1,3317 @@ +/* + * Copyright (c) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +/*! + @abstract portable core for (mostly boot-related) nand partitioning logic + + @copyright Apple Inc. + + @updated 2012-02-21 +*/ + +/* ========================================================================== */ + +#include +#include + +#include "nand_part.h" +#include "nand_part_interface.h" +#include "nand_part_core.h" + +#define DEBUG_ASSERT_COMPONENT_NAME_STRING "nand_part_core" +#include + + +/* ========================================================================== */ + +#pragma mark - Misc Macros + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define byteN(_x, _idx) ((uint8_t)((_x) >> (8 * _idx))) +#define bool2Char(_b) ((_b) ? 'T' : 'F') + +#define ptabPrecedesFeature(ptab, feature) \ + (ptab->header.versionMinor < kNandPartFeature##feature##VersionMinor) + +#define _hostExec(npc, fn, args...) npc->provider->fn(npc->provider->context, ##args) + +#define funcLocked(_lval, _func, _core, ...) \ + do { \ + NandPartCore * npc = (NandPartCore *)(_core); \ + hostLockInterface(npc); \ + *(_lval) = (_func)(npc, ##__VA_ARGS__); \ + hostUnlockInterface(npc); \ + } while (0) + +#define min(x, y) (((x) < (y)) ? (x) : (y)) + + +/* ========================================================================== */ + +#pragma mark - Logging Infrastructure + +const char * kNandPartLogTagBug = "BUG"; +const char * kNandPartLogTagError = "ERR"; +const char * kNandPartLogTagInfo = "INF"; +const char * kNandPartLogTagWarn = "WRN"; +const char * kNandPartLogTagDebug = "DBG"; +const char * kNandPartLogTagSpew = "SPW"; + +static const char * kLogOrigin = "nand_part_core"; + +#define _logCont(npc, fac, fmt, args...) hostLogMessage(npc, kNandPartLogLevel##fac, fmt, ##args) +#define _logHead(npc, fac, fmt, args...) _logCont(npc, fac, "[%s:%s@%4d] " fmt, kLogOrigin, kNandPartLogTag##fac, __LINE__, ##args) +#define _logLine(npc, fac, fmt, args...) _logHead(npc, fac, fmt "\n", ##args) + +#if NAND_PART_EXTENDED_LOGGING + +# define bug(npc, args...) _logLine(npc, Bug, ##args) +# define error(npc, args...) _logLine(npc, Error, ##args) + +# define info(npc, args...) _logLine(npc, Info, ##args) + +# define warn(npc, args...) _logLine(npc, Warn, ##args) +# define debugCont(npc, args...) _logCont(npc, Debug, ##args) +# define debugHead(npc, args...) _logHead(npc, Debug, ##args) +# define debug(npc, args...) _logLine(npc, Debug, ##args) + +# if NAND_PART_LOCAL_DEBUG_ONLY +# define spew(npc, args...) _logLine(npc, Spew, ##args) +# else +# define spew(npc, args...) /* do nothing */ +# endif + +#else /* NAND_PART_EXTENDED_LOGGING */ + +# define bug(npc, args...) _logLine(npc, Bug, "") +# define error(npc, args...) _logLine(npc, Error, "") + +# define info(npc, args...) /* do nothing */ + +# define warn(npc, args...) _logLine(npc, Warn, "") +# define debugCont(npc, args...) /* do nothing */ +# define debugHead(npc, args...) /* do nothing */ +# define debug(npc, args...) /* do nothing */ + +# define spew(npc, args...) /* do nothing */ + +#endif /* NAND_PART_EXTENDED_LOGGING */ + + +// ============================================================================= + +#pragma mark - Provider Service Wrappers + +#define hostLockInterface(npc) _hostExec(npc, lock_interface) +#define hostUnlockInterface(npc) _hostExec(npc, unlock_interface) + +#define hostAllocMem(npc, size, align) _hostExec(npc, alloc_mem, size, align) +#define hostCompareMem(npc, left, right, size) _hostExec(npc, compare_mem, left, right, size) +#define hostMoveMem(npc, dst, src, size) _hostExec(npc, move_mem, dst, src, size) +#define hostSetMem(npc, mem, val, size) _hostExec(npc, set_mem, mem, val, size) +#define hostFreeMem(npc, mem, size) _hostExec(npc, free_mem, mem, size) + +#define hostReadRandom(npc, buf, size) _hostExec(npc, read_random, buf, size) + +#define hostIsBlockFactoryBad(npc, ce, block) _hostExec(npc, is_block_factory_bad, ce, block) +#define hostValidateSpareList(npc, ces, blocks, count) _hostExec(npc, validate_spare_list, ces, blocks, count) +#define hostRequestSpareBlocks(npc, ces, blocks, count, qty) _hostExec(npc, request_spare_blocks, ces, blocks, count, qty) + +#define hostSetDataProperty(npc, key, buf, size) _hostExec(npc, set_data_property, key, buf, size) +#define hostSetNumberProperty(npc, key, num, bits) _hostExec(npc, set_number_property, key, num, bits) +#define hostSetStringProperty(npc, key, cstring) _hostExec(npc, set_string_property, key, cstring) +#define hostSetBooleanProperty(npc, key, val) _hostExec(npc, set_boolean_property, key, val) + +#define hostWaitForFBBTService(npc) _hostExec(npc, wait_for_fbbt_service) + +static bool +hostCreatePartitionDevice(NandPartCore * npc, NandPartEntry * entry, unsigned idx) +{ + bool ok = _hostExec(npc, create_partition_device, entry, idx); + if (ok) { + info(npc, "created partition %u as '%s'", idx, entryContentName(npc, idx)); + } else { + bug(npc, "failed to create device for partition %u with '%s' content", idx, entryContentName(npc, idx)); + } + return ok; +} + +static bool +hostPublishPartitionDevice(NandPartCore * npc, unsigned idx) +{ + bool ok = _hostExec(npc, publish_partition_device, idx); + if (ok) { + info(npc, "published partition %u", idx); + } else { + bug(npc, "failed to publish partition %u", idx); + } + return ok; +} + +static bool +hostReadBootPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf, bool * is_clean) +{ + bool ok = false; + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostReadBootPage(%u, 0x%08x, %p, %p)", ce, addr, buf, is_clean); + } + ok = _hostExec(npc, read_boot_page, ce, addr, buf, is_clean); + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostReadBootPage => %c (%c)", bool2Char(ok), is_clean ? bool2Char(*is_clean) : '-'); + } + return ok; +} + +static bool +hostReadFullPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf, void * meta, bool * is_clean) +{ + bool ok = false; + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostReadFullPage(%u, 0x%08x, %p, %p, %p)", ce, addr, buf, meta, is_clean); + } + ok = _hostExec(npc, read_full_page, ce, addr, buf, meta, is_clean); + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostReadFullPage => %c (%c)", bool2Char(ok), is_clean ? bool2Char(*is_clean) : '-'); + } + return ok; +} + +static bool +hostWriteBootPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf) +{ + bool ok = false; + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostWriteBootPage(%u, 0x%08x, %p)", ce, addr, buf); + } + ok = _hostExec(npc, write_boot_page, ce, addr, buf); + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostWriteBootPage => %c", bool2Char(ok)); + } + return ok; +} + +static bool +hostWriteFullPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf, void * meta) +{ + bool ok = false; + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostWriteFullPage(%u, 0x%08x, %p, %p)", ce, addr, buf, meta); + } + ok = _hostExec(npc, write_full_page, ce, addr, buf, meta); + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostWriteFullPage => %c", bool2Char(ok)); + } + return ok; +} + +static bool +hostEraseBlock(NandPartCore * npc, uint32_t ce, uint32_t addr, uint32_t block) +{ + bool ok = false; + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostEraseBlock(%u, 0x%08x)", ce, addr); + } + ok = _hostExec(npc, erase_block, ce, addr, block); + if (npc->provider->params.isHostTraceEnabled) { + debug(npc, "hostEraseBlock => %c", bool2Char(ok)); + } + return ok; +} + +static void +hostLogMessage(NandPartCore * npc, NandPartLogLevel lvl, const char * fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + _hostExec(npc, vlogf_message, lvl, fmt, ap); + va_end(ap); +} + + +/* ========================================================================== */ + +#pragma mark - Initialization + +extern bool +nand_part_init(NandPartInterface ** interface, NandPartProvider * provider) +{ + NandPartCore * npc = NULL; + + require((NULL != provider) && (NULL != provider->context), fail_mute); + require((NULL != interface) && (NULL == *interface), fail_params); + + npc = withNandPartCore(provider); + require(NULL != npc, fail_construct); + + debug(npc, "nand_part_init()"); + dumpNandGeometry(npc, &(npc->provider->geometry)); + + // initialize artificial "raw media" entry + npc->rawMedia.content = kNandPartContentUndefined; + npc->rawMedia.reserved_0 = 0; + npc->rawMedia.reserved_1 = 0; + npc->rawMedia.flags = kNandPartEntryFlagsUnpartitioned; + + // allocate and prepare scratch meta buffer + npc->meta = (uint8_t *)hostAllocMem(npc, npc->provider->geometry.bytesPerFullPageMeta, false); + require(NULL != npc->meta, fail_alloc); + resetMetaBuf(npc); + + // allocate and prepare ptab buffer + npc->ptab = (NandPartTable *)hostAllocMem(npc, npc->provider->geometry.bytesPerBootPage, true); + require(NULL != npc->ptab, fail_alloc); + hostSetMem(npc, npc->ptab, 0, npc->provider->geometry.bytesPerBootPage); + + npc->bootIdx = ~0; + npc->isBootPartErased = false; + npc->isPTabValid = false; + + *interface = &npc->interface; + return(true); + +fail_alloc: + bug(npc, "alloc failed"); + if (NULL != npc->meta) { + hostFreeMem(npc, npc->meta, npc->provider->geometry.bytesPerFullPageMeta); + npc->meta = NULL; + } + if (NULL != npc->ptab) { + hostFreeMem(npc, npc->ptab, npc->provider->geometry.bytesPerBootPage); + npc->ptab = NULL; + } + return(false); + +fail_construct: + // XXX - can't use log macros yet + //error(npc, "unable to contruct NandPartCore"); + return(false); + +fail_params: + // XXX - can't use log macros yet + //error(npc, "bad params"); + return(false); + +fail_mute: + // with no provider/context, we're unable to even whine about nature of failure + return(false); +} + +static NandPartCore * +withNandPartCore(NandPartProvider * provider) +{ + // Until the NandPartCore structure is initialized, none of the + // convenience macros for host services can be expected to work. + + NandPartCore * npc = NULL; + npc = (NandPartCore *) provider->alloc_mem(provider->context, sizeof(NandPartCore), false); + if (NULL != npc) { + + provider->set_mem(provider->context, npc, 0, sizeof(NandPartCore)); + + npc->provider = provider; + npc->interface.core = npc; + + npc->interface.get_entry = getEntryExternal; + npc->interface.get_bank_width = getBankWidthExternal; + npc->interface.get_block_depth = getBlockDepthExternal; + npc->interface.get_pages_per_block = getPagesPerBlockExternal; + npc->interface.get_bytes_per_page = getBytesPerPageExternal; + + npc->interface.load_ptab = loadPartitionTableExternal; + npc->interface.erase_boot_partition = eraseBootPartitionExternal; + npc->interface.write_boot_partition = writeBootPartitionExternal; + npc->interface.is_block_bad = isBlockBadExternal; + npc->interface.read_page = readPageExternal; + npc->interface.write_page = writePageExternal; + npc->interface.erase_block = eraseBlockExternal; + npc->interface.request_ptab_diff = requestPTabDiffExternal; + npc->interface.provide_ptab_diff = providePTabDiffExternal; + npc->interface.format_ptab = formatPTabExternal; + npc->interface.get_ptab_bytes = getPTabBytesExternal; + } + + return(npc); +} + +static bool +createUnformattedPartitionDevice(NandPartCore * npc) +{ + return (hostCreatePartitionDevice(npc, &npc->rawMedia, kNandPartEntryMaxCount) && + hostPublishPartitionDevice(npc, kNandPartEntryMaxCount)); +} + +static bool +createPartitionDevices(NandPartCore * npc, bool isNewborn) +{ + bool ok = false; + uint32_t i; + uint32_t created_count = 0; + uint32_t created_mask = 0x0; + uint32_t publish_count = 0; + uint32_t publish_mask = 0x0; + bool isReborn = false; + + spew(npc, "creating partition devices for %s state", isNewborn ? "newborn" : "mature"); + + // Initialize the dead block cemetery. + ok = initCemetery(npc, isNewborn); + require_action(ok, finish_up, bug(npc, "unable to init cemetery")); + + // If debug enabled, dump the portions of the partition table + // expected to have valid content for inspection at this point, + // regardless of whether this is a newborn device. + if (isDebugEnabled(npc)) { + + dumpPTabHeader(npc, &(npc->ptab->header)); + dumpCemetery(npc, &(npc->ptab->cemetery)); + dumpEntries(npc, &(npc->ptab->entries[0])); + } + + // create storage partition objects; however, defer publication of most of + // these in order to properly sequence startup + for (i = 0; i < kNandPartEntryMaxCount; i++) { + + NandPartEntry * entry = &(npc->ptab->entries[i]); + + const uint32_t content = entry->content; + const uint32_t partMask = (0x1 << i); + + cleanEntryFlags(npc, entry, isNewborn); + + if ((content != kNandPartContentUndefined) && + (content != kNandPartContentNone) && + (content != kNandPartContentErased)) { + + hostCreatePartitionDevice(npc, entry, i); + + created_count++; + created_mask |= partMask; + + if ((kNandPartContentFilesystem == content) || + (kNandPartContentBadBlockTable == content)) { + + hostPublishPartitionDevice(npc, i); + + publish_count++; + publish_mask |= partMask; + + } else if (kNandPartContentBootBlock == content) { + + npc->bootIdx = i; + } + + } + } + debug(npc, "created %u partitions", created_count); + + // Fail immediately if there were no valid partitions defined. + ok = (0 < created_count); + require_action(ok, finish_up, error(npc, "no valid partitions created")); + + // Wait for AppleNANDFTL's services to become available as + // implied by AppleNANDFactoryBBT service availability. + debug(npc, "waiting for fbbt service"); + ok = hostWaitForFBBTService(npc); + require_action(ok, finish_up, error(npc, "no fbbt service available")); + debug(npc, "fbbt service now available"); + + // Initialize dynamic meta data. + initDiffSequence(npc); + ok = initReplacements(npc); + require_action(ok, finish_up, bug(npc, "failed to init replacements")); + + // If device appears to be in newborn state and only if format + // is enabled, perform the appropriate preparation for initial + // paritioning; otherwise, when prior partition table exists, + // prepare based upon its content. + if (!isNewborn) { + + ok = prepareMatureState(npc, &isReborn); + require_action(ok, finish_up, error(npc, "couldn't prepare %s state", isReborn ? "reborn" : "mature")); + + } else if (isFormatEnabled(npc)) { + + ok = prepareNewbornState(npc, false); + require_action(ok, finish_up, error(npc, "couldn't prepare newborn state")); + } + + // If debug enabled, dump remaining portions of the partition table. + if (isDebugEnabled(npc)) { + + dumpSpare(npc, &(npc->ptab->spare)); + dumpSubst(npc, &(npc->ptab->subst)); + dumpTranslationTables(npc); + } + + // If format is enabled and device is either newborn or + // reborn, erase all blocks in mapped partitions other than + // boot partition. + if (isFormatEnabled(npc) && (isNewborn || isReborn)) { + + uint32_t part; + uint32_t bank; + uint32_t block; + + for (part = 0; part < kNandPartEntryMaxCount; part++) { + if (isPartitionMapped(npc, part) && (npc->bootIdx != part)) { + for (bank = 0; bank < getBankWidth(npc, part); bank++) { + for (block = 0; block < getBlockDepth(npc, part); block++) { + debug(npc, "erasing %u:%u:%u", part, bank, block); + if (!eraseBlock(npc, part, bank, block, true)) { + warn(npc, "failed erase of %u:%u:%u", part, bank, block); + } + } + } + } + } + } + + // Iterate pubishing partition device for each remaining valid entry not previously published + for (i = 0; i < kNandPartEntryMaxCount; i++) { + + const uint32_t partMask = (0x1 << i); + if (isMaskSet(partMask, created_mask) && !isMaskSet(partMask, publish_mask)) { + + hostPublishPartitionDevice(npc, i); + publish_count++; + publish_mask |= partMask; + } + } + debug(npc, "published %u partitions", publish_count); + + ok = (created_count == publish_count); + require_action(ok, finish_up, + bug(npc, "created_count:%u != publish_count:%u; created_mask:0x%08x; publish_mask:0x%08x", + created_count, publish_count, created_mask, publish_mask)); + + setPartitionTableProperties(npc, isNewborn, isReborn); + +finish_up: + return(ok); +} + + +// ============================================================================= + +#pragma mark - Version-Dependent Fixups + +static void +makeEntryTypesExplicit(NandPartCore * npc) +{ + // Make certain each entry explicitly identifies partition + // type iff the entries haven't already been made explicit and + // the version on partition table precedes the PoolPartition + // feature. + if (!isMaskSet(kNandPartDeviceFlagExplicitEntries, npc->ptab->device.flags) && + ptabPrecedesFeature(npc->ptab, PoolPartition)) { + + uint32_t part; + for (part = 0; part < kNandPartEntryMaxCount; part++) { + + NandPartEntry * entry = &(npc->ptab->entries[part]); + uint32_t content = entry->content; + uint32_t type = (entry->flags & kNandPartEntryFlagsTypeMask); + + if (0 != type) { + + debug(npc, "part %u with content '%c%c%c%c' already has type 0x%08x", + part, + byteN(content, 3), byteN(content, 2), byteN(content, 1), byteN(content, 0), + type); + + } else { + + switch (content) { + + case kNandPartContentBootBlock: // fall through + case kNandPartContentFirmware: // fall through + case kNandPartContentNVRAM: // fall through + case kNandPartContentEffaceable: + + type = kNandPartEntryFlagsTypeSlice; + break; + + case kNandPartContentDiagData: // fall through + case kNandPartContentSyscfg: // fall through + case kNandPartContentBadBlockTable: // fall through + + type = kNandPartEntryFlagsTypeInfo; + break; + + case kNandPartContentFilesystem: + + type = (kNandPartEntryFlagsTypeSlice | + kNandPartEntryFlagsIsBulk); + break; + + default: + + // XXX - This case probably shouldn't be possible and + // might require error reporting/handling. + type = kNandPartEntryFlagsUnpartitioned; + } + + entry->flags |= type; + debug(npc, "marked part %u with content '%c%c%c%c' as type 0x%08x", + part, + byteN(content, 3), byteN(content, 2), byteN(content, 1), byteN(content, 0), + type); + } + } + } +} + +static void +addIgnoreFBBTFlag(NandPartCore * npc) +{ + // Add kNandPartEntryFlagsIgnoreFBBT to appropriate partition entries + // iff version on partition table precedes the IgnoreFBBT feature. + if (ptabPrecedesFeature(npc->ptab, IgnoreFBBT)) { + + uint32_t entryIdx; + NandPartEntry * entry; + + for (entryIdx = 0; entryIdx < kNandPartEntryMaxCount; entryIdx++) { + + entry = &(npc->ptab->entries[entryIdx]); + switch (entry->content) { + + case kNandPartContentEffaceable: /* fall through */ + case kNandPartContentFirmware: /* fall through */ + case kNandPartContentNVRAM: + + // add flag for these partition types + entry->flags = entry->flags | kNandPartEntryFlagsIgnoreFBBT; + debug(npc, "adding kNandPartEntryFlagsIgnoreFBBT to partition %u", entryIdx); + break; + + default: + // don't add flag for any other partition type + break; + } + } + } +} + +static void +cleanEntryFlags(NandPartCore * npc, NandPartEntry * entry, bool isNewborn) +{ + const uint32_t content = entry->content; + + // If newborn or ptab version precedes addition of + // CleanEntryFlags feature, make certain that unused partition + // entries contain only the unpartitioned flag and that all + // other entries are pruned of any unknown flags. + if (isNewborn || ptabPrecedesFeature(npc->ptab, PortableCore)) { + + if ((kNandPartContentUndefined == content) || + (kNandPartContentErased == content) || + (kNandPartContentNone == content)) { + + entry->flags = kNandPartEntryFlagsUnpartitioned; + + } else { + + entry->flags &= kNandPartEntryFlagsMask; + } + } +} + + +/* ========================================================================== */ + +#pragma mark - Mature Device Preparation + +static bool +prepareMatureState(NandPartCore * npc, bool *isReborn) +{ + bool ok = true; + bool isSpareValid = false; + bool isSubstValid = false; + uint32_t * ceList = NULL; + uint32_t * blockList = NULL; + const uint32_t count = npc->ptab->spare.count; + const uint32_t size = sizeof(uint32_t) * count; + uint32_t idx; + + spew(npc, "preparing mature state"); + + // For older devices, it is not an error to fail either subst + // or spare validation; however, in either case, we certainly + // shouldn't proceed with the rest of the preparation below. + isSubstValid = validateSubst(npc, &npc->ptab->subst); + require_action(isSubstValid, clean_up, warn(npc, "no subst info available")); + isSpareValid = validateSpare(npc, &npc->ptab->spare); + require_action(isSpareValid, clean_up, warn(npc, "no spare info available")); + + spew(npc, "spare info in partition table appears to be valid; count:%u, size:%u", count, size); + + ceList = (uint32_t*)hostAllocMem(npc, size, false); + blockList = (uint32_t*)hostAllocMem(npc, size, false); + + ok = ((NULL != ceList) && (NULL != blockList)); + require_action(ok, clean_up, bug(npc, "alloc failed")); + + for (idx = 0; idx < count; idx++) { + NandPartSpareLocation * loc = &npc->ptab->spare.locations[idx]; + ceList[idx] = loc->ce; + blockList[idx] = getSpareLocationBlock(npc, loc); + } + + spew(npc, "notifying Whimory of spare list"); + ok = hostValidateSpareList(npc, ceList, blockList, count); + require_action(ok || (0 < count), clean_up, error(npc, "failed host spare validation")); + + if (ok) { + *isReborn = false; + ok = refreshReplacements(npc); + } else if (0 < count) { + *isReborn = true; + ok = prepareRebornState(npc); + } + +clean_up: + if (NULL != ceList) { + hostFreeMem(npc, ceList, size); + } + if (NULL != blockList) { + hostFreeMem(npc, blockList, size); + } + + return ok; +} + +static void +setPartitionTableProperties(NandPartCore * npc, bool isNewborn, bool isReborn) +{ + hostSetNumberProperty(npc, kNandPartCoreVersionMajorKey, npc->ptab->header.versionMajor, 32); + hostSetNumberProperty(npc, kNandPartCoreVersionMinorKey, npc->ptab->header.versionMajor, 32); + hostSetNumberProperty(npc, kNandPartCoreGenerationKey, npc->ptab->header.generation, 32); + + if (isDebugEnabled(npc)) { + + hostSetBooleanProperty(npc, kNandPartCoreIsNewbornKey, isNewborn); + hostSetBooleanProperty(npc, kNandPartCoreIsRebornKey, isReborn); + + //hostSetDataProperty(npc, "*ptab", npc->ptab, sizeof(*npc->ptab)); + //hostSetDataProperty(npc, "ptab->header", &npc->ptab->header, sizeof(npc->ptab->header)); + //hostSetDataProperty(npc, "ptab->fbbtCache", &npc->ptab->fbbtCache, sizeof(npc->ptab->fbbtCache)); + //hostSetDataProperty(npc, "ptab->device", &npc->ptab->device, sizeof(npc->ptab->device)); + + hostSetDataProperty(npc, "ptab->cemetery", &npc->ptab->cemetery, sizeof(npc->ptab->cemetery)); + hostSetDataProperty(npc, "ptab->spare", &npc->ptab->spare, sizeof(npc->ptab->spare)); + hostSetDataProperty(npc, "ptab->subst", &npc->ptab->subst, sizeof(npc->ptab->subst)); + + //hostSetDataProperty(npc, "ptab->unused", &npc->ptab->unused, sizeof(npc->ptab->unused)); + //hostSetDataProperty(npc, "ptab->entries", &npc->ptab->entries, sizeof(npc->ptab->entries)); + } +} + + +// ============================================================================= + +#pragma mark - Reborn/Newborn Device Preparation + +static bool +prepareRebornState(NandPartCore * npc) +{ + // XXX - don't we need to clean the substitution table here and have another go at it? + + npc->isFBBTCached = false; + + // prepare to be reborn by becoming newborn... + return(prepareNewbornState(npc, true)); +} + +static bool +prepareNewbornState(NandPartCore * npc, bool isReborn) +{ + bool ok = false; + size_t sparesSize = 0; + uint32_t sparesDesired = 0; + uint32_t sparesReceived = kNandPartSpareMaxCount; + uint32_t * ceList = NULL; + uint32_t * blockList = NULL; + uint32_t idx; + uint32_t sparesNeeded = 0; + uint32_t sparesExtra = 0; + + spew(npc, "preparing %s state", isReborn ? "reborn" : "newborn"); + + ok = (NULL != npc->ptab); + require_action(ok, clean_up, bug(npc, "ptab is NULL")); + + sparesNeeded = countSparesNeeded(npc, false); + + ok = (kNandPartCountInvalid != sparesNeeded); + require_action(ok, clean_up, bug(npc, "invalid needed spares count")); + + ok = (kNandPartSpareMaxCount >= sparesNeeded); + require_action(ok, clean_up, bug(npc, "too many spares requested - %u", sparesNeeded)); + + sparesExtra = countSparesExtra(npc); + + sparesDesired = sparesNeeded + sparesExtra; + if (sparesDesired > kNandPartSpareMaxCount) { + debug(npc, "limiting spares from %u to %u", sparesDesired, kNandPartSpareMaxCount); + sparesDesired = kNandPartSpareMaxCount; + } + debug(npc, "spares - desired:%u", sparesDesired); + + sparesSize = sizeof(uint32_t) * sparesReceived; + ceList = (uint32_t*) hostAllocMem(npc, sparesSize, false); + blockList = (uint32_t*) hostAllocMem(npc, sparesSize, false); + + ok = ((NULL != ceList) && (NULL != blockList)); + require_action(ok, clean_up, bug(npc, "alloc failed")); + + // Request spare blocks + debug(npc, "requesting %d spare blocks", sparesDesired); + ok = hostRequestSpareBlocks(npc, ceList, blockList, sparesDesired, &sparesReceived); + require_action(ok, clean_up, error(npc, "spare request failed")); + debug(npc, "spares - received:%u", sparesReceived); + + ok = (kNandPartSpareMaxCount >= sparesReceived); + require_action(ok, clean_up, bug(npc, "too many spares")); + + ok = (sparesNeeded <= sparesReceived); + require_action(ok, clean_up, + error(npc, "insufficient spares - needed:%u received:%u", + sparesNeeded, sparesReceived)); + + if (sparesDesired > sparesReceived) { + warn(npc, "not enough spares"); + } + + spew(npc, "adding blocks from spare list to ptab"); + hostSetMem(npc, &npc->ptab->spare, 0, sizeof(NandPartSpare)); + npc->ptab->spare.count = sparesReceived; + for (idx = 0; idx < npc->ptab->spare.count; idx++) { + const uint32_t ce = ceList[idx]; + const uint32_t block = blockList[idx]; + spew(npc, " %2u - ce:%2u block:0x%08X", idx, ce, block); + npc->ptab->spare.locations[idx].ce = (uint8_t) ce; + setSpareLocationBlock(npc, &npc->ptab->spare.locations[idx], block); + } + npc->ptab->spare.magic = kNandPartSpareMagic; + fletcher16(npc, + &npc->ptab->spare.checks[0], + &npc->ptab->spare.checks[1], + &npc->ptab->spare, + sizeof(npc->ptab->spare) - sizeof(npc->ptab->spare.checks)); + + ok = substituteSparesForBadBlocks(npc); + require_action(ok, clean_up, error(npc, "spare substitution failed")); + + // Now we have valid spares and substitutions + // assigned, we can finally build the real + // replacement table. + refreshReplacements(npc); + + // record good partition table as soon as possible, + // the extra erase cycle is worth minimizing the + // window during which the information just built + // can be lost during fragile device initialization + ok = writePTab(npc); + if (!ok) { + error(npc, "unable to store newborn partition table"); + } + +clean_up: + if (NULL != ceList) + hostFreeMem(npc, ceList, sparesSize); + if (NULL != blockList) + hostFreeMem(npc, blockList, sparesSize); + + return ok; +} + +static uint32_t +countSparesNeeded(NandPartCore * npc, bool useWorstCase) +{ + uint32_t need = kNandPartCountInvalid; + uint32_t scrub = 0; + uint32_t pool = 0; + uint32_t part; + + // determine how many spares are needed to supply blocks + // for pool partitions + for (part = 0; part < kNandPartEntryMaxCount; part++) { + if (isPartitionMapped(npc, part) && areFlagsSet(npc, part, kNandPartEntryFlagsTypePool)) { + pool += (getBankWidth(npc, part) * getBlockDepth(npc, part)); + } + } + + if (useWorstCase) { + uint32_t part; + uint32_t total = 0; + + for (part = 0; part < kNandPartMappingMaxCount; part++) { + if (isPartitionMapped(npc, part) && !areFlagsSet(npc, part, kNandPartEntryFlagsTypePool)) { + const uint32_t count = calcPartitionMapCount(npc, part); + total += count; + } + } + + scrub = total - npc->provider->geometry.ceCount; + } else { + // determine how many spares are needed due to stillborn + // blocks from slice partitions + scrub = scrubMappedPartitionsForStillborn(npc); + } + require_action(kNandPartCountInvalid != scrub, finish_up, bug(npc, "invalid scrub count")); + + // total number of spares needed is the sum of the two + need = scrub + pool; + debug(npc, "counting spares - need:%u = scrub:%u + pool:%u", need, scrub, pool); + +finish_up: + return(need); +} + +static uint32_t +countSparesExtra(NandPartCore * npc) +{ + uint32_t extra = kNandPartCountInvalid; + const uint32_t oldExtra = (kNandPartBankMax - npc->provider->geometry.ceCount) / 2; + const uint32_t newExtra = kNandPartSpareMinExtraCount; + + // A request has been made to reduce the extras count; however, I'd like for + // new builds of launched products to continue to behave the same way. Thus, + // we conditionally decide which quantity to return depending upon whether + // this specific device allows pool partitioning. + extra = (allowPoolPartitions(npc) ? newExtra : oldExtra); + debug(npc, "counting spares - extra:%u = {newExtra:%u,oldExtra:%u}", extra, newExtra, oldExtra); + + return(extra); +} + +static uint32_t +countMaxSpares(NandPartCore * npc) +{ + const uint32_t needed = countSparesNeeded(npc, true); + const uint32_t extra = countSparesExtra(npc); + + return min(needed + extra, kNandPartSpareMaxCount); +} + +static uint32_t +scrubMappedPartitionsForStillborn(NandPartCore * npc) +{ + bool ok = true; + uint32_t part; + uint32_t bank; + uint32_t block; + void * patternBuf = NULL; + uint32_t bytesPerBlock = 0; + uint32_t count = 0; + + spew(npc, "scrubbing mapped partitions"); + + for (part = 0; part < kNandPartEntryMaxCount; part++) { + if (isPartitionMapped(npc, part) && !areFlagsSet(npc, part, kNandPartEntryFlagsTypePool)) { + + // XXX - the filter above allows boot blocks through; should it? + + const uint32_t bytesPerPage = getBytesPerPage(npc, part); + const uint32_t pagesPerBlock = getPagesPerBlock(npc, part); + + if ((NULL == patternBuf) || ((bytesPerPage * pagesPerBlock) != bytesPerBlock)) { + + // Physical geometry for current partition different from prior partition; + // therefore, we need to free previous pattern buffer. + if (NULL != patternBuf) { + hostFreeMem(npc, patternBuf, bytesPerBlock); + patternBuf = NULL; + } + + // Note that this is a large allocation (512 KiB <= bytesPerBlock ~< 4 MiB, for + // relevant historical and near term configurations); however, this allocation + // only happens in Restore OS during first-time init of device, so memory pressure + // shouldn't be a significant issue. + bytesPerBlock = (bytesPerPage * pagesPerBlock); + patternBuf = hostAllocMem(npc, bytesPerBlock, true); + ok = (NULL != patternBuf); + require_action(ok, clean_up, bug(npc, "alloc failed")); + + hostReadRandom(npc, patternBuf, bytesPerBlock); + } + + for (bank = 0; bank < getBankWidth(npc, part); bank++) { + for (block = 0; block < getBlockDepth(npc, part); block++) { + spew(npc, "scrubbing %u:%u:%u", part, bank, block); + if (!scrubBlockForStillborn(npc, part, bank, block, patternBuf)) { + count++; + debug(npc, "block %u:%u:%u is stillborn", part, bank, block); + markBlockDead(npc, part, bank, block, false); + } + } + } + } + } + + debug(npc, "during initial partitioning, %u out of %u blocks found dead in mapped partitions", + count, getTotalMapCount(npc)); + +clean_up: + + if (NULL != patternBuf) { + hostFreeMem(npc, patternBuf, bytesPerBlock); + patternBuf = NULL; + } + + if (!ok) { + return kNandPartCountInvalid; + } + + return(count); +} + +static bool +scrubBlockForStillborn(NandPartCore * npc, uint32_t part, uint32_t bank, uint32_t block, void * patternBuf) +{ + const uint32_t initialScrubCount = 2; + const uint32_t map = calcBlockMap(npc, part, bank, block, false); + const size_t pageSize = getBytesPerPage(npc, part); + const uint32_t pagesPerBlock = getPagesPerBlock(npc, part); + uint8_t * pagePatternBuf = NULL; + uint8_t * readBuf = NULL; + bool isClean; + uint32_t pass; + uint32_t page; + bool ok = true; + + ok = isFormatEnabled(npc); + require_action(ok, clean_up, bug(npc, "attempted to scrub without format enabled")); + + readBuf = (uint8_t *)hostAllocMem(npc, pageSize, true); + ok = (NULL != readBuf); + require_action(ok, clean_up, bug(npc, "alloc failed")); + + for (pass = 0; pass <= initialScrubCount; pass++) { + + ok = eraseBlock(npc, part, bank, block, false); + require_action(ok, clean_up, spew(npc, "failed erase of %u:%u:%u", part, bank, block)); + + // final pass is erase only; not actually a "scrub" per se, + // and solely intended to leave good blocks in an erased state + if (pass != initialScrubCount) { + + // attempt to write to all pages in block + for (page = 0; page < pagesPerBlock; page++) { + + const uint32_t patternPage = ((map + page) % pagesPerBlock); + const size_t patternOffset = patternPage * pageSize; + + pagePatternBuf = (((uint8_t*)patternBuf) + patternOffset); + + ok = writePage(npc, part, bank, block, page, pagePatternBuf, false); + require_action(ok, clean_up, spew(npc, "failed write - %u:%u:%u:%u", part, bank, block, page)); + } + + // after successfully writing to all pages readback and compare + for (page = 0; page < pagesPerBlock; page++) { + + const uint32_t patternPage = ((map + page) % pagesPerBlock); + const size_t patternOffset = patternPage * pageSize; + + pagePatternBuf = (((uint8_t*)patternBuf) + patternOffset); + + ok = readPage(npc, part, bank, block, page, readBuf, &isClean, false); + require_action(ok, clean_up, spew(npc, "failed read - %u:%u:%u:%u (%c)", part, bank, block, page, bool2Char(isClean))); + + ok = (0 == hostCompareMem(npc, pagePatternBuf, readBuf, pageSize)); + require_action(ok, clean_up, spew(npc, "failed compare - %u:%u:%u:%u", part, bank, block, page)); + } + } + } + +clean_up: + if (NULL != readBuf) { + hostFreeMem(npc, readBuf, pageSize); + } + + debug(npc, "block %u:%u:%u %s scrub", part, bank, block, (ok ? "passed" : "failed")); + + return(ok); +} + + +// ============================================================================= + +#pragma mark - Initial Format/Partitioning + +static bool +formatWithSpecs(NandPartCore * npc) +{ + uint32_t index; + bool haveBulk = false; + + initPartitionTable(npc); + + /* add partitions */ + for (index = 0; index < kNandPartEntryMaxCount; index++) { + require_action(addPartition(npc, &(npc->provider->params.partitionSpecs[index]), index, &haveBulk), + fail, error(npc, "unable to add partition %d of %d", index, kNandPartEntryMaxCount)); + } + require_action(haveBulk, fail, error(npc, "no bulk partition defined")); + + /* success - return the array */ + return(true); + +fail: + return(false); +} + +static void +initPartitionTable(NandPartCore * npc) +{ + unsigned idx; + NandPartTable * ptab = npc->ptab; + + /* initialize buffer with random content so that unused areas + * will cause some overall whitening effect + */ + hostReadRandom(npc, ptab, sizeof(NandPartTable)); + + /* immutable magic key */ + ptab->header.magic = kNandPartHeaderMagic; + + /* continue to set the historically unused epoch field to zero */ + ptab->header.should_be_zero = 0; + + /* record current partition major and minor versions */ + ptab->header.versionMajor = majorVersion(npc); + ptab->header.versionMinor = kNandPartHeaderVersionMinor; + + /* generation starts at zero and should get updated every time + * partition tables are rewritten + */ + ptab->header.generation = 1; + + /* copy device information */ + ptab->device.should_be_zero[0] = 0; + ptab->device.should_be_zero[1] = 0; + ptab->device.should_be_one = 1; + ptab->device.numOfCS = npc->provider->geometry.ceCount; + ptab->device.blocksPerCS = npc->provider->geometry.blocksPerCE; + ptab->device.pagesPerBlock = npc->provider->geometry.pagesPerMLCBlock; + ptab->device.sectorsPerPage = npc->provider->geometry.bytesPerFullPage / kNandPartSectorSize; + ptab->device.spareBytesPerPage = npc->provider->geometry.bytesPerFullPageMeta; + + /* in retrospect, this wasn't the most logical place to add a global flags field */ + ptab->device.flags = (isPoolAllowed(npc) ? kNandPartDeviceFlagAllowPool : kNandPartDeviceFlagNone); + ptab->device.flags |= (kNandPartDeviceFlagNeedsCemetery | kNandPartDeviceFlagExplicitEntries); + + /* make certain that all entries have reasonable initial content */ + for (idx = 1; idx < kNandPartEntryMaxCount; idx++) { + ptab->entries[idx].content = kNandPartContentNone; + ptab->entries[idx].reserved_0 = 0; + ptab->entries[idx].reserved_1 = 1; + ptab->entries[idx].flags = kNandPartEntryFlagsUnpartitioned; + } +} + +static uint32_t +majorVersion(NandPartCore * npc) +{ + // Use minimum of current software major version and + // product-specific device tree property. If the property was + // not set in the device tree, the value for it will be set to + // the maximum unsigned integer size, thus defaulting to the + // current software major version. + + return(min(kNandPartHeaderVersionMajor, maxMajorVersion(npc))); +} + +static bool +addPartition(NandPartCore *npc, NandPartSpec *spec, uint32_t index, bool * haveBulk) +{ + bool result = true; + NandPartTable * ptab = npc->ptab; + static uint32_t managedCount = 0; + static uint32_t baseOffset = 0; + + ptab->entries[index].content = spec->content; + ptab->entries[index].flags = spec->type | spec->flags; + + switch (spec->type) { + + case kNandPartEntryFlagsIsBulk: + result = !*haveBulk; + require_action(result, finish_up, error(npc, "bulk spec'ed more than once")); + ptab->entries[index].slice.offset = baseOffset; + ptab->entries[index].slice.depth = (npc->provider->geometry.blocksPerCE - baseOffset); + ptab->entries[index].flags |= kNandPartEntryFlagsTypeSlice; + baseOffset = npc->provider->geometry.blocksPerCE; + *haveBulk = true; + break; + + case kNandPartEntryFlagsTypeSlice: + result = !*haveBulk; + require_action(result, finish_up, error(npc, "slice spec'ed after bulk")); + ptab->entries[index].slice.offset = baseOffset; + ptab->entries[index].slice.depth = spec->depth; + baseOffset += spec->depth; + managedCount += (npc->provider->geometry.ceCount * spec->depth); + break; + + case kNandPartEntryFlagsTypePool: + ptab->entries[index].pool.width = spec->width; + ptab->entries[index].pool.depth = spec->depth; + managedCount += (spec->width * spec->depth); + break; + + case kNandPartEntryFlagsTypeInfo: + break; + + default: + result = false; + require_action(result, finish_up, error(npc, "unrecognized partition type")); + } + + result = (managedCount <= kNandPartCemeteryCapacity); + require_action(result, finish_up, error(npc, "too many blocks allocated")); + + result = (baseOffset <= npc->provider->geometry.blocksPerCE); + require_action(result, finish_up, error(npc, "offset exceeds bank length")); + +finish_up: + return(result); +} + + +// ============================================================================= + +#pragma mark - Runtime Parameters + +static bool +isBootPartErasable(NandPartCore * npc) +{ + return npc->provider->params.isBootPartErasable; +} + +static bool +isBootPartWritable(NandPartCore * npc) +{ + return npc->provider->params.isBootPartWritable; +} + +static bool +isFormatEnabled(NandPartCore * npc) +{ + return npc->provider->params.isFormatEnabled; +} + +static bool +isDebugEnabled(NandPartCore * npc) +{ + return npc->provider->params.isDebugEnabled; +} + +static bool +isPoolAllowed(NandPartCore * npc) +{ + return npc->provider->params.isPoolAllowed; +} + +static uint32_t +maxMajorVersion(NandPartCore * npc) +{ + return npc->provider->params.maxMajorVersion; +} + + +// ============================================================================= + +#pragma mark - Miscellaneous Global Information + +static bool +isPpnDevice(NandPartCore * npc) +{ + return(npc->provider->geometry.isPpn); +} + +static bool +findBootPartIndex(NandPartCore * npc, uint32_t * partIndex) +{ + bool ok = false; + uint32_t idx; + + for (idx = 0; !ok && (idx < kNandPartEntryMaxCount); idx++) { + if (kNandPartContentBootBlock == getEntry(npc, idx)->content) { + *partIndex = idx; + ok = true; + } + } + + return(ok); +}; + +static bool +isEntryIndexValid(NandPartCore * npc, uint32_t partIndex, bool allowRawIndex) +{ + return((kNandPartEntryMaxCount > partIndex) || (allowRawIndex && isRawEntryIndex(npc, partIndex))); +} + +static bool +isRawEntryIndex(NandPartCore * npc, uint32_t partIndex) +{ + return(kNandPartEntryMaxCount == partIndex); +} + +static bool +allowPoolPartitions(NandPartCore * npc) +{ + const bool isPTabCompatible = (kNandPartFeaturePoolPartitionVersionMajor <= npc->ptab->header.versionMajor); + const bool isAllowPoolFlagged = isMaskSet(kNandPartDeviceFlagAllowPool, npc->ptab->device.flags); + return(isPTabCompatible && isAllowPoolFlagged); +} + + +// ============================================================================= + +#pragma mark - Partition Entry Information + +static const char * +entryContentName(NandPartCore * npc, uint32_t partIndex) +{ + const char * name; + + if (isRawEntryIndex(npc, partIndex)) { + name = kNandPartContentNameUnformatted; + } else { + switch (getEntry(npc, partIndex)->content) { + case kNandPartContentBootBlock: + name = kNandPartContentNameBootBlock; + break; + case kNandPartContentDiagData: + name = kNandPartContentNameDiagData; + break; + case kNandPartContentSyscfg: + name = kNandPartContentNameSyscfg; + break; + case kNandPartContentNVRAM: + name = kNandPartContentNameNVRAM; + break; + case kNandPartContentFirmware: + name = kNandPartContentNameFirmware; + break; + case kNandPartContentFilesystem: + name = kNandPartContentNameFilesystem; + break; + case kNandPartContentEffaceable: + name = kNandPartContentNameEffaceable; + break; + case kNandPartContentBadBlockTable: + name = kNandPartContentNameBadBlockTable; + break; + case kNandPartContentNone: + name = kNandPartContentNameUnallocated; + break; + default: + name = kNandPartContentNameUnrecognized; + } + } + + return name; +} + +static bool +areFlagsSet(NandPartCore * npc, uint32_t partIndex, uint32_t flagMask) +{ + return(isMaskSet(flagMask, getEntry(npc, partIndex)->flags)); +} + +static bool +usingSLCBlocks(NandPartCore * npc, uint32_t partIndex) +{ + // pool partitioning block allocations should probably + // redundantly record whether specific block is being treated + // as SLC + + return(areFlagsSet(npc, partIndex, kNandPartEntryFlagsUsingSLCBlocks)); +} + +static bool +usingFullPages(NandPartCore * npc, uint32_t partIndex) +{ + return(areFlagsSet(npc, partIndex, kNandPartEntryFlagsUsingFullPages)); +} + +static uint32_t +getBlockOffset(NandPartCore * npc, uint32_t partIndex) +{ + uint32_t offset = 0; + + require_action(isEntryIndexValid(npc, partIndex, true), finish_up, + bug(npc, "out of bounds - part:%u", partIndex)); + + if (isRawEntryIndex(npc, partIndex)) { + offset = 0; + } else if (areFlagsSet(npc, partIndex, kNandPartEntryFlagsTypeSlice)) { + offset = getEntry(npc, partIndex)->slice.offset; + } else { + warn(npc, "invalid request for block offset of partition 0x%08x", partIndex); + } + +finish_up: + return(offset); +} + + +// ============================================================================= + +#pragma mark - Virtual to Physical Address Calculation + +static uint32_t +mapNandBlock(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + uint32_t block = kNandPartBlockInvalid; + + require_action(getBlockDepth(npc, partIndex) > partBlock, finish_up, + error(npc, "out of bounds - part:%u block:%u", partIndex, partBlock)); + + // this hook will be where the table lookup of nand block for + // pool partitioning will be substituted for the direct + // mapping below + + if (allowSpare && isPartitionMapped(npc, partIndex)) { + uint32_t spareIndex; + if (isBlockReplaced(npc, partIndex, partBank, partBlock, &spareIndex)) { + NandPartSpareLocation * location = getSpareLocation(npc, spareIndex); + require_action(NULL != location, finish_up, bug(npc, "missing location")); + block = getSpareLocationBlock(npc, location); + } else { + block = mapNandBlock(npc, partIndex, partBank, partBlock, false); + } + } else { + block = (partBlock + getBlockOffset(npc, partIndex)); + } + +finish_up: + return(block); +} + +static uint32_t +mapNandCE(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + uint32_t ce = kNandPartCEInvalid; + + require_action(getBankWidth(npc, partIndex) > partBank, finish_up, + error(npc, "out of bounds - part:%u bank:%u", partIndex, partBank)); + + // this hook will be where the table lookup of nand ce for + // pool partitioning will be substituted for the direct + // mapping below + + if (allowSpare && isPartitionMapped(npc, partIndex)) { + uint32_t spareIndex; + if (isBlockReplaced(npc, partIndex, partBank, partBlock, &spareIndex)) { + NandPartSpareLocation * location = getSpareLocation(npc, spareIndex); + require_action(NULL != location, finish_up, bug(npc, "missing location")); + ce = location->ce; + } else { + ce = mapNandCE(npc, partIndex, partBank, partBlock, false); + } + } else { + ce = partBank; + } + +finish_up: + return(ce); +} + +static uint32_t +calcNandAddress(NandPartCore * npc, uint32_t nandBlock, uint32_t pageInBlock, bool useSLC) +{ + uint32_t address; + + if (isPpnDevice(npc)) { + + const uint32_t blockShift = npc->provider->geometry.bitsPerPageAddr; + const uint32_t slcBitShift = (npc->provider->geometry.bitsPerPageAddr + + npc->provider->geometry.bitsPerBlockAddr + + npc->provider->geometry.bitsPerCauAddr); + const uint32_t slcBit = ((useSLC ? 1UL : 0UL) << slcBitShift); + + address = pageInBlock | (nandBlock << blockShift) | slcBit; + + } else { + + address = pageInBlock + (nandBlock * npc->provider->geometry.blockStride); + } + + return (address); +} + +#if NAND_PART_CORE_ORPHAN +static uint32_t +calcNandBlock(NandPartCore * npc, uint32_t nandAddress, bool useSLC) +{ + uint32_t block; + + if (isPpnDevice(npc)) { + + const uint32_t blockShift = npc->provider->geometry.bitsPerPageAddr; + const uint32_t slcBitShift = (npc->provider->geometry.bitsPerPageAddr + + npc->provider->geometry.bitsPerBlockAddr + + npc->provider->geometry.bitsPerCauAddr); + + // XXX - should SLC bit get removed if block previously programmed as SLC? + const uint32_t slcBit = ((useSLC ? 1UL : 0UL) << slcBitShift); + + block = (nandAddress & ~slcBit) >> blockShift; + + } else { + + block = nandAddress / npc->provider->geometry.blockStride; + } + + return (block); +} +#endif + + +// ============================================================================= + +#pragma mark - Meta Buffer Proxy + +static uint8_t * +getMetaBuf(NandPartCore * npc) +{ + return(npc->meta); +} + +static uint8_t * +resetMetaBuf(NandPartCore * npc) +{ + uint8_t * meta = getMetaBuf(npc); + hostSetMem(npc, meta, 0, npc->provider->geometry.bytesPerFullPageMeta); + return(meta); +} + +static uint8_t * +endorseMetaBuf(NandPartCore * npc, uint32_t partIndex) +{ + const uint8_t signature = (partIndex & 0xF) | AND_SPARE_TYPE_REGION_BFN; + uint8_t * meta = resetMetaBuf(npc); + meta[0] = signature; + return(meta); +} + +static void +verifyMetaBuf(NandPartCore * npc, uint32_t partIndex) +{ + const uint8_t signature = (partIndex & 0xF) | AND_SPARE_TYPE_REGION_BFN; + uint8_t * meta = getMetaBuf(npc); + if (signature != meta[0]) { + + // Not an error condition since prior versions haven't been + // rigorous about endorsing meta data; regardless, could be + // quite useful in certain debug scenarios. + // + // Also, it doesn't seem as if all (any?) of the contexts are + // actually faithfully writing this information out. At this + // point, although this has parity with current implementation, + // it may be more dangerous than it's actually worth. + spew(npc, "meta mis-match; signature:0x%02x, meta[0]:0x%02x", signature, meta[0]); + } +} + + +// ============================================================================= + +#pragma mark - Block Replacement + +static bool +initReplacements(NandPartCore * npc) +{ + bool ok = false; + unsigned map; + unsigned count; + NandPartReplacement * replacement; + + spew(npc, "initializing block replacements"); + + // initialize mapping + initMapping(npc); + + // sanity check the mapping count + count = getTotalMapCount(npc); + ok = (kNandPartReplacementMaxCount >= count); + require_action(ok, finish_up, + bug(npc, "total map count, %u, greater than max replacement count, %u", + count, kNandPartReplacementMaxCount)); + + // reset all valid replacement entries + spew(npc, "marking %u replacement entries as valid but not replaced", count); + for (map = 0; map < count; map++) { + + replacement = getMappedReplacement(npc, map); + ok = (NULL != replacement); + require_action(ok, finish_up, bug(npc, "invalid replacement - map:%u", map)); + + replacement->isValid = true; + replacement->isReplaced = false; + replacement->spareIndex = kNandPartReplacementInvalidIndex; + } + + // init all invalid replacement entries + spew(npc, "marking remaining %u replacement entries as invalid and not replaced", + (kNandPartReplacementMaxCount - count)); + for (; map < kNandPartReplacementMaxCount; map++) { + + replacement = getMappedReplacement(npc, map); + ok = (NULL != replacement); + require_action(ok, finish_up, bug(npc, "invalid replacement - map:%u", map)); + + replacement->isValid = false; + replacement->isReplaced = false; + replacement->spareIndex = kNandPartReplacementInvalidIndex; + } + +finish_up: + return ok; +} + +static bool +refreshReplacements(NandPartCore * npc) +{ + bool ok = true; + unsigned spare; + + spew(npc, "refreshing block replacements"); + + if (validateSpare(npc, &npc->ptab->spare) && validateSubst(npc, &npc->ptab->subst)) { + + // walk through substitution table, updating the matching + // replacement for each substitution defined therein + for (spare = 0; spare < npc->ptab->subst.count; spare++) { + + const unsigned map = npc->ptab->subst.maps[spare]; + // walk through only till substitution entries are valid + if (0 == map) + { + break; + } + NandPartReplacement * replacement = getMappedReplacement(npc, map); + + ok = (NULL != replacement); + require_action(ok, finish_up, bug(npc, "invalid replacement - map:%u", map)); + + ok = (replacement->isValid); + require_action(ok, finish_up, bug(npc, "invalid replacement - spare:%u map:%u", spare, map)); + + replacement->isReplaced = true; + replacement->spareIndex = (uint32_t)spare; + } + } + + if (isDebugEnabled(npc)) { + const unsigned size = sizeof(NandPartReplacement) * kNandPartReplacementMaxCount; + hostSetDataProperty(npc, "replacements", &(npc->replacements[0]), size); + } + +finish_up: + return(ok); +} + +static bool +validateSpare(NandPartCore * npc, NandPartSpare * spare) +{ + bool ok = true; + + ok = (kNandPartSpareMagic == spare->magic); + require_action(ok, finish_up, warn(npc, "bad magic - expected:0x%08x found:0x%08x", + kNandPartSpareMagic, spare->magic)); + + ok = (kNandPartSpareMaxCount >= spare->count); + require_action(ok, finish_up, bug(npc, "out of bounds - limit:%u >= count:%u", + kNandPartSpareMaxCount, spare->count)); + + if (!isMaskSet(kNandPartSpareFlagIgnoreChecks, spare->flags)) { + + const size_t len = (sizeof(*spare) - sizeof(spare->checks)); + uint8_t checkA; + uint8_t checkB; + + fletcher16(npc, &checkA, &checkB, spare, len); + ok = ((checkA == spare->checks[0]) && (checkB == spare->checks[1])); + require_action(ok, finish_up, bug(npc, "incorrect checksum")); + } + +finish_up: + return(ok); +} + +static bool +validateSubst(NandPartCore * npc, NandPartSubst * subst) +{ + bool ok = true; + + ok = (kNandPartSubstMagic == subst->magic); + require_action(ok, finish_up, warn(npc, "bad magic - expected:0x%08x found:0x%08x", + kNandPartSubstMagic, subst->magic)); + + ok = (kNandPartSubstMaxCount >= subst->count); + require_action(ok, finish_up, bug(npc, "out of bounds - limit:%u >= count:%u", + kNandPartSubstMaxCount, subst->count)); + + if (!isMaskSet(kNandPartSubstFlagIgnoreChecks, subst->flags) && + isMaskSet(kNandPartSubstFlagCorrectedChecks, subst->flags)) { + + const size_t len = (sizeof(*subst) - sizeof(subst->checks)); + uint8_t checkA; + uint8_t checkB; + + fletcher16(npc, &checkA, &checkB, subst, len); + ok = ((checkA == subst->checks[0]) && (checkB == subst->checks[1])); + require_action(ok, finish_up, bug(npc, "incorrect checksum")); + } + +finish_up: + return(ok); +} + +static bool +isBlockReplaced(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t * spareIndex) +{ + bool isReplaced = false; + uint32_t spare = (uint32_t)-1; + const uint32_t map = calcBlockMap(npc, partIndex, partBank, partBlock, false); + const NandPartReplacement * replacement = getMappedReplacement(npc, map); + + require_action(NULL != replacement, finish_up, bug(npc, "invalid replacement - map:%u", map)); + + isReplaced = replacement->isReplaced; + if (isReplaced && (NULL != spareIndex)) { + *spareIndex = spare = (uint32_t)replacement->spareIndex; + } + + spew(npc, "block is%s replaced - partIndex:%u partBank:%u partBlock:%u map:%u %s:%u", + isReplaced ? "" : " not", partIndex, partBank, partBlock, map, isReplaced ? "spare" : "N/A", spare); + +finish_up: + return(isReplaced); +} + +static NandPartReplacement * +getMappedReplacement(NandPartCore * npc, uint32_t map) +{ + NandPartReplacement * replacement = NULL; + + require_action(kNandPartReplacementMaxCount > map, finish_up, + bug(npc, "out of bounds - map:%u", map)); + replacement = &(npc->replacements[map]); + +finish_up: + return(replacement); +} + +static NandPartSpareLocation * +getSpareLocation(NandPartCore * npc, uint32_t spareIndex) +{ + NandPartSpareLocation * location = NULL; + + require_action(kNandPartSpareMaxCount > spareIndex, finish_up, + bug(npc, "out of bounds - spareIndex:%u", spareIndex)); + location = &npc->ptab->spare.locations[spareIndex]; + +finish_up: + return(location); +} + +static uint32_t +getSpareLocationBlock(NandPartCore * npc, NandPartSpareLocation * location) +{ + return((((uint32_t)location->block[0]) << 0) + + (((uint32_t)location->block[1]) << 8) + + (((uint32_t)location->block[2]) << 16)); +} + +static void +setSpareLocationBlock(NandPartCore * npc, NandPartSpareLocation * location, uint32_t block) +{ + location->block[0] = (uint8_t) (block >> 0); + location->block[1] = (uint8_t) (block >> 8); + location->block[2] = (uint8_t) (block >> 16); +} + +static bool +substituteSparesForBadBlocks(NandPartCore * npc) +{ + NandPartSubst * subst = &(npc->ptab->subst); + bool ok = true; + uint32_t idx = 0; + uint32_t part; + uint32_t bank; + uint32_t block; + + spew(npc, "substituting spares for bad blocks"); + + hostSetMem(npc, subst, 0x00, sizeof(NandPartSubst)); + subst->count = npc->ptab->spare.count; + + for (part = 0; ok && part < kNandPartEntryMaxCount; part++) { + + if (!isPartitionMapped(npc, part)) { + continue; + } + + for (bank = 0; ok && bank < getBankWidth(npc, part); bank++) { + for (block = 0; ok && block < getBlockDepth(npc, part); block++) { + + if (areFlagsSet(npc, part, kNandPartEntryFlagsTypePool) || + isBlockBad(npc, part, bank, block, false)) { + + ok = (subst->count > idx); + require_action(ok, finish_up, bug(npc, "out of spares - idx:%u", idx)); + + debug(npc, "substituting %u:%u:%u with spare idx:%u", part, bank, block, idx); + subst->maps[idx++] = calcBlockMap(npc, part, bank, block, false); + } + } + } + } + + if (ok) { + const size_t len = (sizeof(*subst) - sizeof(subst->checks)); + subst->magic = kNandPartSubstMagic; + subst->flags = kNandPartSubstFlagCorrectedChecks; + fletcher16(npc, &subst->checks[0], &subst->checks[1], subst, len); + } + +finish_up: + return ok; +} + +static void +initMapping(NandPartCore * npc) +{ + unsigned idx; + NandPartMapping * mapping = &(npc->mapping); + uint32_t total = 0; + + spew(npc, "initializing block mappings"); + + for (idx = 0; idx < kNandPartMappingMaxCount; idx++) { + + const uint32_t count = calcPartitionMapCount(npc, idx); + mapping->counts[idx] = count; + mapping->offsets[idx] = total; + total += count; + } + mapping->total = total; + + if (isDebugEnabled(npc)) { + hostSetDataProperty(npc, "mapping", mapping, sizeof(*mapping)); + } +} + +static bool +isPartitionMapped(NandPartCore * npc, uint32_t partIndex) +{ + // XXX: this is ugly and inflexible; introduce better flags + // for recognizing mapped partition types + + const NandPartEntry * entry = getEntry(npc, partIndex); + return((kNandPartContentBootBlock == entry->content) || + (kNandPartContentFirmware == entry->content) || + (kNandPartContentNVRAM == entry->content) || + (kNandPartContentEffaceable == entry->content)); +} + +static uint32_t +calcPartitionMapCount(NandPartCore * npc, uint32_t partIndex) +{ + if ((partIndex >= kNandPartEntryMaxCount) || !isPartitionMapped(npc, partIndex)) { + return 0; + } + return(getBankWidth(npc, partIndex) * getBlockDepth(npc, partIndex)); +} + +static uint32_t +getPartitionMapOffset(NandPartCore * npc, uint32_t partIndex) +{ + return(npc->mapping.offsets[partIndex]); +} + +static uint32_t +getTotalMapCount(NandPartCore * npc) +{ + return(npc->mapping.total); +} + +static uint32_t +calcBlockMap(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + uint32_t map = (uint32_t)-1; + + require_action(isEntryIndexValid(npc, partIndex, false), finish_up, + bug(npc, "out of bounds - partIndex:%u", partIndex)); + require_action(isPartitionMapped(npc, partIndex), finish_up, + bug(npc, "not mapped - partIndex:%u", partIndex)); + + if (allowSpare) { + + uint32_t spareIndex = (uint32_t)-1; + + if (isBlockReplaced(npc, partIndex, partBank, partBlock, &spareIndex)) { + map = getTotalMapCount(npc) + spareIndex; + } else { + map = calcBlockMap(npc, partIndex, partBank, partBlock, false); + } + + } else { + + const uint32_t width = getBankWidth(npc, partIndex); + const uint32_t depth = getBlockDepth(npc, partIndex); + + const uint32_t base = getPartitionMapOffset(npc, partIndex); + const uint32_t row = (width * partBlock); + const uint32_t col = partBank; + + require_action(width > partBank, finish_up, + bug(npc, "out of bounds - width:%u bank:%u", width, partBank)); + require_action(depth > partBlock, finish_up, + bug(npc, "out of bounds - depth:%u block:%u", depth, partBlock)); + + map = (base + row + col); + } + +finish_up: + return(map); +} + +#if NAND_PART_CORE_ORPHAN +// previously only used for now obsolete assetion +static uint32_t +getPartitionMapCount(NandPartCore * npc, uint32_t partIndex) +{ + return(npc->mapping.counts[partIndex]); +} +#endif + + +// ============================================================================= + +#pragma mark - Bad Block Management + +static bool +initCemetery(NandPartCore * npc, bool isNewborn) +{ + bool ok = true; + NandPartCemetery * cemetery = &(npc->ptab->cemetery); + + debug(npc, "initializing cemetery state"); + + if (isNewborn + || ptabPrecedesFeature(npc->ptab, FuneralDirge) + || isMaskSet(kNandPartDeviceFlagNeedsCemetery, npc->ptab->device.flags)) { + + hostSetMem(npc, cemetery, 0x00, sizeof(NandPartCemetery)); + cemetery->gate = kNandPartCemeteryGate; + changeCemeteryLocks(npc, cemetery); + npc->ptab->device.flags &= ~kNandPartDeviceFlagNeedsCemetery; + + } else if (!isCemeterySafe(npc, cemetery)) { + + error(npc, "cemetery is haunted"); + ok = false; + } + + return(ok); +} + +static void +fletcher16(NandPartCore * npc, uint8_t *checkA, uint8_t *checkB, const void *buf, size_t len) +{ + // derived from: http://en.wikipedia.org/wiki/Fletcher%27s_checksum @ 2010-06-26 + + const uint8_t * data = (uint8_t*)buf; + uint16_t sum1 = 0xff, sum2 = 0xff; + + while (len) { + size_t tlen = len > 21 ? 21 : len; + len -= tlen; + do { + sum1 += *data++; + sum2 += sum1; + } while (--tlen); + sum1 = (sum1 & 0xff) + (sum1 >> 8); + sum2 = (sum2 & 0xff) + (sum2 >> 8); + } + + /* Second reduction step to reduce sums to 8 bits */ + sum1 = (sum1 & 0xff) + (sum1 >> 8); + sum2 = (sum2 & 0xff) + (sum2 >> 8); + *checkA = (uint8_t)sum1; + *checkB = (uint8_t)sum2; +} + +static bool +isCemeterySafe(NandPartCore * npc, const NandPartCemetery *cemetery) +{ + bool ok = true; + + // is the cemetery gate present? + ok = (kNandPartCemeteryGate == cemetery->gate); + require_action(ok, finish_up, + bug(npc, "missing gate - expected:0x%08X; found:0x%08X", + kNandPartCemeteryGate, cemetery->gate)); + + // XXX check to make certain none are marked dead beyond total mapped block count + + // check the locks, if they're not being explicitly ignored + if (!isMaskSet(kNandPartCemeteryFlagIgnoreLocks, cemetery->flags)) { + + const size_t len = (sizeof(*cemetery) - sizeof(cemetery->locks)); + uint8_t checkA; + uint8_t checkB; + + fletcher16(npc, &checkA, &checkB, cemetery, len); + ok = ((checkA == cemetery->locks[0]) && (checkB == cemetery->locks[1])); + require_action(ok, finish_up, + bug(npc, "broken locks - expected:{0x%02X, 0x%02X}; found:{0x%02X, 0x%02X}", + checkA, checkB, cemetery->locks[0], cemetery->locks[1])); + } + +finish_up: + return(ok); +} + +static void +changeCemeteryLocks(NandPartCore * npc, NandPartCemetery * cemetery) +{ + const size_t len = (sizeof(*cemetery) - sizeof(cemetery->locks)); + cemetery->locks[0] = cemetery->locks[1] = 0; + fletcher16(npc, &cemetery->locks[0], &cemetery->locks[1], cemetery, len); +} + +static bool +mergePartitionCemetery(NandPartCore * npc, uint32_t partIndex, const NandPartCemetery * partCemetery, NandPartCemetery * mainCemetery) +{ + bool ok = false; + const uint32_t numOfHeadstoneRows = kNandPartCemeteryPlotsSize / sizeof(uint32_t); + uint32_t * oldPlots = (uint32_t *) mainCemetery->plots; + uint32_t * newPlots = (uint32_t *) partCemetery->plots; + uint32_t row; + + debug(npc, "merging cemetery from part:%u", partIndex); + + ok = (kNandPartCemeteryPlotsSize == (sizeof(uint32_t) * numOfHeadstoneRows)); + require_action(ok, finish_up, bug(npc, "expecting plot count evenly divisible by 32")); + + ok = isCemeterySafe(npc, mainCemetery); + require_action(ok, finish_up, bug(npc, "main cemetery unsafe")); + + ok = isCemeterySafe(npc, partCemetery); + require_action(ok, finish_up, bug(npc, "part:%u cemetery unsafe", partIndex)); + + // apply diffs regadless of partition providing the information + for (row = 0; row < numOfHeadstoneRows; row++) { + + // the dead must remain in their graves; if they + // aren't, report the problem, and bury them again + ok = isMaskSet(oldPlots[row], newPlots[row]); + require_action(ok, finish_up, + bug(npc, "dead have risen - oldPlots[%u]:0x%08x, newPlots[%u]:0x%08x", + row, oldPlots[row], row, newPlots[row])); + + oldPlots[row] |= newPlots[row]; + } + + // update checksums + changeCemeteryLocks(npc, mainCemetery); + ok = isCemeterySafe(npc, mainCemetery); + require_action(ok, finish_up, bug(npc, "main cemetery unsafe after merge")); + +finish_up: + return (ok); +} + +static void +markBlockDead(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + const uint32_t map = calcBlockMap(npc, partIndex, partBank, partBlock, allowSpare); + const uint32_t idx = (map / 32); + const uint32_t mask = (((uint32_t)0x1) << (map % 32)); + uint32_t * plots = (uint32_t*) npc->ptab->cemetery.plots; + plots[idx] |= mask; + changeCemeteryLocks(npc, &npc->ptab->cemetery); + debug(npc, "block %u:%u:%u is dead", partIndex, partBank, partBlock); +} + +static bool +isBlockDead(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + const uint32_t map = calcBlockMap(npc, partIndex, partBank, partBlock, allowSpare); + const uint32_t idx = (map / 32); + const uint32_t mask = (((uint32_t)0x1) << (map % 32)); + const uint32_t * plots = (uint32_t*) npc->ptab->cemetery.plots; + const bool isDead = isMaskSet(mask, plots[idx]); + if (isDead) { + debug(npc, "block %u:%u:%u is dead", partIndex, partBank, partBlock); + } + return(isDead); +} + +static NandPartFBBTCache * +getFBBTCache(NandPartCore * npc) +{ + NandPartFBBTCache * cache = NULL; + if (0 != npc->ptab->fbbtCache.info.entryCount) { + cache = &npc->ptab->fbbtCache; + } + return(cache); +} + +static bool +isBlockFactoryBad(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + bool isBad = false; + + if (!isMaskSet(kNandPartEntryFlagsIgnoreFBBT, getEntry(npc, partIndex)->flags) && + !(allowSpare && isBlockReplaced(npc, partIndex, partBank, partBlock, NULL))) { + + uint32_t ce = mapNandCE(npc, partIndex, partBank, partBlock, allowSpare); + uint32_t block = mapNandBlock(npc, partIndex, partBank, partBlock, allowSpare); + NandPartFBBTCache * cache; + + isBad = ((kNandPartCEInvalid == ce) || (kNandPartBlockInvalid == block)); + require_action(!isBad, finish_up, bug(npc, "unable to map - part:%u bank:%u block:%u spare:%c", + partIndex, partBank, partBlock, bool2Char(allowSpare))); + + cacheFactoryBadBlockTable(npc); + cache = getFBBTCache(npc); + if ((NULL != cache) && (block < cache->info.blockDepth)) { + + unsigned idx; + + for (idx = 0; idx < cache->info.entryCount; idx++) { + if ((block == cache->entries[idx].blockAddr) && + (ce == cache->entries[idx].bankNum)) { + isBad = true; + } + } + + } else { + + isBad = hostIsBlockFactoryBad(npc, ce, block); + } + } + +finish_up: + return(isBad); +} + +static void +cacheFactoryBadBlockTable(NandPartCore * npc) +{ + uint32_t entryIdx = 0; + uint32_t blockIdx; + uint32_t ceIdx; + + // XXX - The FBBT cache is quite irrelevant anymore due to the + // grown bad block table (a.k.a. cemetery) and, thus, should + // be deprecated sometime. + + if (!npc->isFBBTCached) { + for (blockIdx = 0; blockIdx < npc->provider->geometry.blocksPerCE; blockIdx++) { + for (ceIdx = 0; ceIdx < npc->provider->geometry.ceCount; ceIdx++) { + if ((kNandPartFBBTCacheEntryCount > entryIdx) && + (hostIsBlockFactoryBad(npc, ceIdx, blockIdx))) { + npc->ptab->fbbtCache.entries[entryIdx].bankNum = ceIdx; + npc->ptab->fbbtCache.entries[entryIdx].blockAddr = blockIdx; + entryIdx++; + } + } + if (kNandPartFBBTCacheEntryCount <= entryIdx) { + break; + } + } + npc->ptab->fbbtCache.info.entryCount = entryIdx; + npc->ptab->fbbtCache.info.blockDepth = blockIdx; + npc->isFBBTCached = true; + } +} + + +/* ========================================================================== */ + +#pragma mark - Partition Table I/O + +static bool +readPTab(NandPartCore * npc) +{ + bool ok = false; + uint32_t ce; + const uint32_t block = 0; + uint32_t page; + bool isClean; + + debug(npc, "reading partition tables from boot blocks"); + for (ce = 0; !ok && (ce < npc->provider->geometry.ceCount); ce++) { + for (page = 0; !ok && (page < kNandPartTableCopies); page++) { + const uint32_t address = calcNandAddress(npc, block, page, false); + spew(npc, "retrieving boot block information from %u:%u", ce, address); + if (!hostReadBootPage(npc, ce, address, npc->ptab, &isClean)) { + debug(npc, "unable to read boot block at %u:%u (%c)", ce, address, bool2Char(isClean)); + } else { + spew(npc, "checking whether %u:%u contains valid partition table", ce, address); + if (validatePTab(npc, npc->ptab)) { + info(npc, "read valid partition table"); + ok = true; + } + } + } + } + + if (!ok) { + info(npc, "no partition table found"); + } + + return(ok); +}; + +static bool +validatePTab(NandPartCore * npc, const NandPartTable * ptab) +{ + bool ok = false; + + // Before anything else, the header magic must match in order + // for partition table validation to succeed. + ok = (kNandPartHeaderMagic == ptab->header.magic); + require_action(ok, finish_up, error(npc, "bad magic - %c%c%c%c", + byteN(ptab->header.magic, 3), + byteN(ptab->header.magic, 2), + byteN(ptab->header.magic, 1), + byteN(ptab->header.magic, 0))); + + // Next, check the major version. Major version changes only happen when + // structural incompatibilities are introduced that cannot be supported + // by older versions of the software; however, newer software is expected + // to maintain compatibility with older versions of the structure. + // Thus, the software's major version must be greater than or equal to + // the structure's major version. + ok = (kNandPartHeaderVersionMajor >= ptab->header.versionMajor); + require_action(ok, finish_up, error(npc, "incompatible major version - 0x%08X", + ptab->header.versionMajor)); + + // Finally, in some cases, it might be valuable to warn about + // minor version differences; however, this should never cause + // structure validation to fail. + if (kNandPartHeaderVersionMinor > ptab->header.versionMinor) { + warn(npc, "minor version on device, 0x%08X, older than driver, 0x%08X", + ptab->header.versionMinor, kNandPartHeaderVersionMinor); + } else if (kNandPartHeaderVersionMinor < ptab->header.versionMinor) { + warn(npc, "minor version on device, 0x%08X, newer than driver, 0x%08X", + ptab->header.versionMinor, kNandPartHeaderVersionMinor); + } + + npc->isPTabValid = true; + +finish_up: + return(ok); +}; + +static bool +writePTab(NandPartCore * npc) +{ + bool ok = false; + uint32_t part; + uint32_t ce; + const uint32_t block = 0; + uint32_t page; + uint32_t goodCopies = 0; + uint32_t len; + bool isClean; + void * buf = NULL; + + ok = findBootPartIndex(npc, &part); + require_action(ok, finish_up, bug(npc, "missing boot partition")); + + // Acquire temp buffer for readback verification. + len = getBytesPerPage(npc, part); + buf = hostAllocMem(npc, len, true); + ok = (NULL != buf); + require_action(ok, finish_up, bug(npc, "alloc failed")); + + // Update minor version information on partition table every write. + npc->ptab->header.versionMinor = kNandPartHeaderVersionMinor; + + // Increment generation information with every write. + npc->ptab->header.generation++; + + // Make certain factory BBT cache is current. + cacheFactoryBadBlockTable(npc); + + for (ce = 0; ce < npc->provider->geometry.ceCount; ce++) { + const uint32_t blockAddr = calcNandAddress(npc, block, 0, false); + if (!hostEraseBlock(npc, ce, blockAddr, block)) { + warn(npc, "failed erase of boot block %u:%u", ce, blockAddr); + } else { + + for (page = 0; page < kNandPartTableCopies; page++) { + const uint32_t pageAddr = calcNandAddress(npc, block, page, false); + if (!hostWriteBootPage(npc, ce, pageAddr, npc->ptab)) { + warn(npc, "failed write to boot page %u:%u", ce, pageAddr); + } + } + + // perform readback and verification + for (page = 0; page < kNandPartTableCopies; page++) { + const uint32_t pageAddr = calcNandAddress(npc, block, page, false); + if (!hostReadBootPage(npc, ce, pageAddr, buf, &isClean)) { + warn(npc, "failed read from boot page %u:%u (%c)", ce, pageAddr, bool2Char(isClean)); + } else if (0 != hostCompareMem(npc, npc->ptab, buf, len)) { + warn(npc, "failed compare for boot page %u:%u", ce, pageAddr); + } else { + goodCopies++; + } + } + } + } + + if (0 < goodCopies) { + ok = true; + info(npc, "first %u pages of boot blocks written with copies of partition table", + kNandPartTableCopies); + } + +finish_up: + if (NULL != buf) { + hostFreeMem(npc, buf, len); + buf = NULL; + } + + return(ok); +}; + + +/* ========================================================================== */ + +#pragma mark - Partition Table Diffs + +static void +initDiffSequence(NandPartCore * npc) +{ + unsigned idx; + for (idx = 0; idx < kNandPartEntryMaxCount; idx++) { + npc->diffSequence[idx] = 0; + } +} + +static bool +validatePTabDiff(NandPartCore * npc, NandPartDiff * diff, unsigned size) +{ + bool ok = true; + + ok = (sizeof(NandPartDiffHeader) <= size); + require_action(ok, finish_up, bug(npc, "diff way too small")); + + ok = (kNandPartDiffMagic == diff->header.magic); + require_action(ok, finish_up, warn(npc, "bad diff magic")); + + ok = (sizeof(NandPartDiff) == diff->header.size); + require_action(ok, finish_up, bug(npc, "bad diff size")); + + ok = (diff->header.size <= size); + require_action(ok, finish_up, bug(npc, "diff still too small")); + + ok = (diff->header.versionMajor == npc->ptab->header.versionMajor); + require_action(ok, finish_up, bug(npc, "diff major version mismatch - diff: %u, ptab: %u", + diff->header.versionMajor, npc->ptab->header.versionMajor)); + + if (diff->header.generation < npc->ptab->header.generation) { + warn(npc, "diff generation earlier than ptab - diff: %u, ptab: %u", + diff->header.generation, npc->ptab->header.generation); + } + + if (0 != diff->header.sequence) { + warn(npc, "diff has sequence of 0"); + } + + if (!isMaskSet(kNandPartDiffFlagIgnoreChecks, diff->header.flags)) { + + const size_t len = (diff->header.size - sizeof(diff->checks)); + uint8_t checkA; + uint8_t checkB; + + fletcher16(npc, &checkA, &checkB, diff, len); + ok = ((checkA == diff->checks[0]) && (checkB == diff->checks[1])); + require_action(ok, finish_up, error(npc, "diff checksum fail")); + } + + debug(npc, "ptab diff is valid"); + +finish_up: + return ok; +} + + +// ============================================================================= + +#pragma mark - Structure Dumping + +static void +dumpNandGeometry(NandPartCore * npc, NandPartGeometry * geometry) +{ + debug(npc, "NandPartGeometry @ %p: {", geometry); + debug(npc, " isPpn: %c", bool2Char(geometry->isPpn)); + debug(npc, " ceCount: %u", geometry->ceCount); + debug(npc, " blocksPerCE: %u", geometry->blocksPerCE); + debug(npc, " blockStride: %u", geometry->blockStride); + debug(npc, " pagesPerMLCBlock: %u", geometry->pagesPerMLCBlock); + debug(npc, " pagesPerSLCBlock: %u", geometry->pagesPerSLCBlock); + debug(npc, " bytesPerBootPage: %u", geometry->bytesPerBootPage); + debug(npc, " bytesPerFullPage: %u", geometry->bytesPerFullPage); + debug(npc, " bytesPerFullPageMeta: %u", geometry->bytesPerFullPageMeta); + debug(npc, " bitsPerCauAddr: %u", geometry->bitsPerCauAddr); + debug(npc, " bitsPerPageAddr: %u", geometry->bitsPerPageAddr); + debug(npc, " bitsPerBlockAddr: %u", geometry->bitsPerBlockAddr); + debug(npc, "}"); +} + +static void +dumpPTabHeader(NandPartCore * npc, NandPartHeader * header) +{ + debug(npc, "NandPartHeader @ %p: {", header); + debug(npc, " magic: '%c%c%c%c'", byteN(header->magic, 3), byteN(header->magic, 2), byteN(header->magic, 1), byteN(header->magic, 0)); + debug(npc, " should_be_zero: 0x%08x", header->should_be_zero); + debug(npc, " versionMajor: 0x%08x", header->versionMajor); + debug(npc, " versionMinor: 0x%08x", header->versionMinor); + debug(npc, " generation: 0x%08x", header->generation); + debug(npc, " reserved[]: {"); + debug(npc, " 0x%02x, 0x%02x, 0x%02x, 0x%02x,", header->reserved[ 0], header->reserved[ 1], header->reserved[ 2], header->reserved[ 3]); + debug(npc, " 0x%02x, 0x%02x, 0x%02x, 0x%02x,", header->reserved[ 4], header->reserved[ 5], header->reserved[ 6], header->reserved[ 7]); + debug(npc, " 0x%02x, 0x%02x, 0x%02x, 0x%02x" , header->reserved[ 8], header->reserved[ 9], header->reserved[10], header->reserved[11]); + debug(npc, " }"); + debug(npc, "}"); +} + +static void +dumpCemetery(NandPartCore * npc, NandPartCemetery * cemetery) +{ + debug(npc, "NandPartCemetery @ %p: {", cemetery); + debug(npc, " gate: 0x%08X", cemetery->gate); + debug(npc, " flags: 0x%02X", cemetery->flags); + debug(npc, " plots: {"); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X,", cemetery->plots[ 0], cemetery->plots[ 1], cemetery->plots[ 2], cemetery->plots[ 3]); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X,", cemetery->plots[ 4], cemetery->plots[ 5], cemetery->plots[ 6], cemetery->plots[ 7]); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X,", cemetery->plots[ 8], cemetery->plots[ 9], cemetery->plots[10], cemetery->plots[11]); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X,", cemetery->plots[12], cemetery->plots[13], cemetery->plots[14], cemetery->plots[15]); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X,", cemetery->plots[16], cemetery->plots[17], cemetery->plots[18], cemetery->plots[19]); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X,", cemetery->plots[20], cemetery->plots[21], cemetery->plots[22], cemetery->plots[23]); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X,", cemetery->plots[24], cemetery->plots[25], cemetery->plots[26], cemetery->plots[27]); + debug(npc, " 0x%02X, 0x%02X, 0x%02X, 0x%02X", cemetery->plots[28], cemetery->plots[29], cemetery->plots[30], cemetery->plots[31]); + debug(npc, " }"); + debug(npc, " locks: { 0x%02X, 0x%02X }", cemetery->locks[0], cemetery->locks[1]); + debug(npc, "}"); +} + +static void +dumpSpare(NandPartCore * npc, NandPartSpare * spare) +{ + unsigned idx; + debug(npc, "NandPartSpare @ %p: {", spare); + debug(npc, " magic: '%c%c%c%c'", byteN(spare->magic, 3), byteN(spare->magic, 2), byteN(spare->magic, 1), byteN(spare->magic, 0)); + debug(npc, " count: %u", spare->count); + debug(npc, " flags: 0x%02x", spare->flags); + debug(npc, " reserved: { 0x%02x, 0x%02x, 0x%02x }", spare->reserved[0], spare->reserved[1], spare->reserved[2]); + debug(npc, " locations[]: {"); + for (idx = 0; idx < kNandPartSpareMaxCount; idx++) { + debug(npc, " [%2d]: { block: 0x%06x, ce: %u }", + idx, getSpareLocationBlock(npc, &(spare->locations[idx])), spare->locations[idx].ce); + } + debug(npc, " }"); + debug(npc, " checks: { 0x%02x, 0x%02x }", spare->checks[0], spare->checks[1]); + debug(npc, "}"); +} + +static void +dumpSubst(NandPartCore * npc, NandPartSubst * subst) +{ + unsigned idx; + debug(npc, "NandPartSubst @ %p: {", subst); + debug(npc, " magic: '%c%c%c%c'", byteN(subst->magic, 3), byteN(subst->magic, 2), byteN(subst->magic, 1), byteN(subst->magic, 0)); + debug(npc, " count: %u", subst->count); + debug(npc, " flags: 0x%02x", subst->flags); + debug(npc, " reserved: { 0x%02x, 0x%02x, 0x%02x }", subst->reserved[0], subst->reserved[1], subst->reserved[2]); + debug(npc, " maps[]: {"); + for (idx = 0; idx < kNandPartSubstMaxCount; idx++) { + debug(npc, " [%2d]: %u", idx, subst->maps[idx]); + } + debug(npc, " }"); + debug(npc, " checks: { 0x%02x, 0x%02x }", subst->checks[0], subst->checks[1]); + debug(npc, "}"); +} + +static void +dumpEntries(NandPartCore * npc, NandPartEntry * entries) +{ + uint32_t part; + + debug(npc, "NandPartEntry[] @ %p: {", entries); + for (part = 0; part < kNandPartEntryMaxCount; part++) { + + debug(npc, " [%u]: {", part); + debug(npc, " content: '%c%c%c%c'", + byteN(entries[part].content, 3), + byteN(entries[part].content, 2), + byteN(entries[part].content, 1), + byteN(entries[part].content, 0)); + + if (areFlagsSet(npc, part, kNandPartEntryFlagsTypeSlice)) { + + debug(npc, " slice.offset: %u", entries[part].slice.offset); + debug(npc, " slice.depth: %u", entries[part].slice.depth); + + } else if (areFlagsSet(npc, part, kNandPartEntryFlagsTypePool)) { + + debug(npc, " pool.width: %u", entries[part].pool.width); + debug(npc, " pool.depth: %u", entries[part].pool.depth); + + } else { + + debug(npc, " reserved_0: %u", entries[part].reserved_0); + debug(npc, " reserved_1: %u", entries[part].reserved_1); + } + + if (isPartitionMapped(npc, part)) { + + debug(npc, " flags: 0x%08x (usingFullPages:%c usingSLCBlocks:%c)", + entries[part].flags, bool2Char(usingFullPages(npc, part)), bool2Char(usingSLCBlocks(npc, part))); + + } else { + + debug(npc, " flags: 0x%08x", entries[part].flags); + } + + debug(npc, " }"); + } + debug(npc, "}"); +} + +static void +dumpPTab(NandPartCore * npc, NandPartTable * ptab) +{ + dumpPTabHeader(npc, &(ptab->header)); + dumpCemetery(npc, &(ptab->cemetery)); + dumpSpare(npc, &(ptab->spare)); + dumpSubst(npc, &(ptab->subst)); + dumpEntries(npc, &(ptab->entries[0])); +} + +static void +dumpMapping(NandPartCore * npc, NandPartMapping * mapping) +{ + unsigned idx; + + debug(npc, "NandPartMapping @ %p: {", mapping); + debug(npc, " total: %u", mapping->total); + debug(npc, " counts[]: {"); + for (idx = 0; idx < kNandPartMappingMaxCount; idx++) { + debug(npc, " [%3u]: %u", idx, mapping->counts[idx]); + } + debug(npc, " }"); + debug(npc, " offsets[]: {"); + for (idx = 0; idx < kNandPartMappingMaxCount; idx++) { + debug(npc, " [%3u]: %u", idx, mapping->offsets[idx]); + } + debug(npc, " }"); + debug(npc, "}"); +} + +static void +dumpReplacements(NandPartCore * npc, NandPartReplacement * replacements) +{ + unsigned idx; + + debug(npc, "NandPartReplacement[] @ %p: {", replacements); + for (idx = 0; idx < kNandPartReplacementMaxCount; idx++) { + const NandPartReplacement *replacement = getMappedReplacement(npc, idx); + require_action(NULL != replacement, finish_up, bug(npc, "unmapped replacement - idx:%u", idx)); + debug(npc, " [%3u]: { isValid: %c; isReplaced: %c; spareIndex: %2u }", + idx, bool2Char(replacement->isValid), bool2Char(replacement->isReplaced), replacement->spareIndex); + } + debug(npc, "}"); + +finish_up: + return; +} + +static void +dumpSeparator(NandPartCore * npc, unsigned char sep, unsigned cnt) +{ + unsigned idx; + for (idx = 0; idx < cnt; idx++) { + debugCont(npc, "%c", sep); + } +} + +static void +dumpTranslationTables(NandPartCore * npc) +{ + uint32_t partIndex; + uint32_t partBank; + uint32_t partBlock; + + dumpMapping(npc, &(npc->mapping)); + dumpReplacements(npc, &(npc->replacements[0])); + + debug(npc, "logical to physical translation tables"); + + for (partIndex = 0; partIndex < kNandPartEntryMaxCount; partIndex++) { + if (isPartitionMapped(npc, partIndex)) { + + // output translation table header + debugHead(npc, " partIndex: %2d", partIndex); + for (partBank = 0; partBank < getBankWidth(npc, partIndex); partBank++) { + debugCont(npc, " | partBank: %2d", partBank); + dumpSeparator(npc, ' ', 35); + } + debugCont(npc, "\n"); + + for (partBlock = 0; partBlock < getBlockDepth(npc, partIndex); partBlock++) { + + // output translation table row seperator + debugHead(npc, " "); + dumpSeparator(npc, '-', 13); + for (partBank = 0; partBank < getBankWidth(npc, partIndex); partBank++) { + debugCont(npc, "-+"); + dumpSeparator(npc, '-', 48); + } + debugCont(npc, "\n"); + + // output translation table row + debugHead(npc, " partBlock: %2d", partBlock); + for (partBank = 0; partBank < getBankWidth(npc, partIndex); partBank++) { + debugCont(npc, " | { ce: %2d, block: 0x%08x, addr: 0x%08x }", + mapNandCE(npc, partIndex, partBank, partBlock, true), + mapNandBlock(npc, partIndex, partBank, partBlock, true), + calcNandAddress(npc, mapNandBlock(npc, partIndex, partBank, partBlock, true), + 0, usingSLCBlocks(npc, partIndex))); + } + debugCont(npc, "\n"); + } + + debugHead(npc, " "); + dumpSeparator(npc, '=', 15); + debugCont(npc, "\n"); + } + } +} + +extern void +nand_part_dump(NandPartInterface * interface) +{ + NandPartCore * npc = (NandPartCore *)interface->core; + dumpNandGeometry(npc, &(npc->provider->geometry)); + dumpPTab(npc, npc->ptab); + dumpTranslationTables(npc); +} + + +/* ========================================================================== */ + +#pragma mark - Interface Implementation + +static const NandPartEntry * +getEntry(NandPartCore * npc, uint32_t partIndex) +{ + NandPartEntry * entry = NULL; + + require_action(isEntryIndexValid(npc, partIndex, true), finish_up, + bug(npc, "out of bounds - part:%u", partIndex)); + + if (isRawEntryIndex(npc, partIndex)) { + debug(npc, "part:%u indicates unformatted nand", partIndex); + entry = &(npc->rawMedia); + } else { + entry = &(npc->ptab->entries[partIndex]); + } + +finish_up: + return entry; +} + +static uint32_t +getBankWidth(NandPartCore * npc, uint32_t partIndex) +{ + uint32_t width = 0; + + require_action(isEntryIndexValid(npc, partIndex, true), finish_up, + bug(npc, "out of bounds - part:%u", partIndex)); + + if ((isRawEntryIndex(npc, partIndex)) || + (areFlagsSet(npc, partIndex, kNandPartEntryFlagsTypeSlice))) { + width = npc->provider->geometry.ceCount; + } else if (areFlagsSet(npc, partIndex, kNandPartEntryFlagsTypePool)) { + width = getEntry(npc, partIndex)->pool.width; + } else { + warn(npc, "invalid request for bank width of partition 0x%08x", partIndex); + } + +finish_up: + return(width); +} + +static uint32_t +getBlockDepth(NandPartCore * npc, uint32_t partIndex) +{ + uint32_t depth = 0; + + require_action(isEntryIndexValid(npc, partIndex, true), finish_up, + bug(npc, "out of bounds - part:%u", partIndex)); + + if (isRawEntryIndex(npc, partIndex)) { + depth = npc->provider->geometry.blocksPerCE; + } else if (areFlagsSet(npc, partIndex, kNandPartEntryFlagsTypeSlice)) { + depth = getEntry(npc, partIndex)->slice.depth; + } else if (areFlagsSet(npc, partIndex, kNandPartEntryFlagsTypePool)) { + depth = getEntry(npc, partIndex)->pool.depth; + } else { + warn(npc, "invalid request for block depth of partition 0x%08x", partIndex); + } + +finish_up: + return(depth); +} + +static uint32_t +getPagesPerBlock(NandPartCore * npc, uint32_t partIndex) +{ + uint32_t count = 0; + + require_action(isEntryIndexValid(npc, partIndex, true), finish_up, + bug(npc, "out of bounds - part:%u", partIndex)); + + if (usingSLCBlocks(npc, partIndex)) { + count = npc->provider->geometry.pagesPerSLCBlock; + } else { + count = npc->provider->geometry.pagesPerMLCBlock; + } + +finish_up: + return(count); +} + +static uint32_t +getBytesPerPage(NandPartCore * npc, uint32_t partIndex) +{ + uint32_t count = 0; + + require_action(isEntryIndexValid(npc, partIndex, true), finish_up, + bug(npc, "out of bounds - part:%u", partIndex)); + + if (usingFullPages(npc, partIndex)) { + count = npc->provider->geometry.bytesPerFullPage; + } else { + count = npc->provider->geometry.bytesPerBootPage; + } + +finish_up: + return(count); +} + +static bool +isBlockBad(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + bool bad = true; + + require_action(isEntryIndexValid(npc, partIndex, true), finish_up, + bug(npc, "out of bounds - part:%u", partIndex)); + + bad = (isBlockDead(npc, partIndex, partBank, partBlock, allowSpare) || + isBlockFactoryBad(npc, partIndex, partBank, partBlock, allowSpare)); + + if (bad) { + spew(npc, "bad block - part:%u bank:%u block:%u spare:%c", + partIndex, partBank, partBlock, bool2Char(allowSpare)); + } + +finish_up: + return bad; +} + +static bool +readPage(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool * isClean, bool allowSpare) +{ + bool ok = false; + uint32_t ce; + uint32_t block; + uint32_t addr; + + ok = isEntryIndexValid(npc, partIndex, false); + require_action(ok, finish_up, bug(npc, "out of bounds - part:%u", partIndex)); + + ce = mapNandCE(npc, partIndex, partBank, partBlock, allowSpare); + block = mapNandBlock(npc, partIndex, partBank, partBlock, allowSpare); + addr = calcNandAddress(npc, block, pageInBlock, usingSLCBlocks(npc, partIndex)); + + ok = ((kNandPartCEInvalid != ce) && (kNandPartBlockInvalid != block)); + require_action(ok, finish_up, bug(npc, "unable to map - part:%u bank:%u block:%u spare:%c", + partIndex, partBank, partBlock, bool2Char(allowSpare))); + + if (npc->provider->params.isClientTraceEnabled) { + debug(npc, "readPage(%u, %u, %u, %u, %p, %p, %c)", + partIndex, partBank, partBlock, pageInBlock, buf, isClean, bool2Char(allowSpare)); + } + + if (usingFullPages(npc, partIndex)) { + + ok = hostReadFullPage(npc, ce, addr, buf, resetMetaBuf(npc), isClean); + require(ok, finish_up); + + // given that driver has not always historically been + // specifying meta buffer content for full page + // operations, it is not considered a failure of the + // read operation if this verification fails; + // therefore, perhaps this should be done only when + // debug is enabled + verifyMetaBuf(npc, partIndex); + + } else { + ok = hostReadBootPage(npc, ce, addr, buf, isClean); + } + +finish_up: + if (npc->provider->params.isClientTraceEnabled) { + debug(npc, "readPage => %c (%c)", bool2Char(ok), isClean ? bool2Char(*isClean) : '-'); + } + return(ok); +} + +static bool +writePage(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool allowSpare) +{ + bool ok = false; + uint32_t ce; + uint32_t block; + uint32_t addr; + + ok = isEntryIndexValid(npc, partIndex, false); + require_action(ok, finish_up, bug(npc, "out of bounds - part:%u", partIndex)); + + ce = mapNandCE(npc, partIndex, partBank, partBlock, allowSpare); + block = mapNandBlock(npc, partIndex, partBank, partBlock, allowSpare); + addr = calcNandAddress(npc, block, pageInBlock, usingSLCBlocks(npc, partIndex)); + + ok = ((kNandPartCEInvalid != ce) && (kNandPartBlockInvalid != block)); + require_action(ok, finish_up, bug(npc, "unable to map - part:%u bank:%u block:%u spare:%c", + partIndex, partBank, partBlock, bool2Char(allowSpare))); + + ok = !isBlockBad(npc, partIndex, partBank, partBlock, allowSpare); + require(ok, finish_up); + + if (npc->provider->params.isClientTraceEnabled) { + debug(npc, "writePage(%u, %u, %u, %u, %p, %c)", + partIndex, partBank, partBlock, pageInBlock, buf, bool2Char(allowSpare)); + } + + if (usingFullPages(npc, partIndex)) { + ok = hostWriteFullPage(npc, ce, addr, buf, endorseMetaBuf(npc, partIndex)); + } else { + ok = hostWriteBootPage(npc, ce, addr, buf); + } + + if (!ok) { + // XXX - double-check with NAND team that this is correct response to a page write failure + markBlockDead(npc, partIndex, partBank, partBlock, allowSpare); + } + +finish_up: + if (npc->provider->params.isClientTraceEnabled) { + debug(npc, "writePage => %c", bool2Char(ok)); + } + return(ok); +} + +static bool +eraseBlock(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare) +{ + bool ok = false; + uint32_t ce; + uint32_t block; + uint32_t addr; + + ok = isEntryIndexValid(npc, partIndex, false); + require_action(ok, finish_up, bug(npc, "out of bounds - part:%u", partIndex)); + + ce = mapNandCE(npc, partIndex, partBank, partBlock, allowSpare); + block = mapNandBlock(npc, partIndex, partBank, partBlock, allowSpare); + addr = calcNandAddress(npc, block, 0, usingSLCBlocks(npc, partIndex)); + + ok = ((kNandPartCEInvalid != ce) && (kNandPartBlockInvalid != block)); + require_action(ok, finish_up, bug(npc, "unable to map - part:%u bank:%u block:%u spare:%c", + partIndex, partBank, partBlock, bool2Char(allowSpare))); + + ok = !isBlockBad(npc, partIndex, partBank, partBlock, allowSpare); + require(ok, finish_up); + + if (npc->provider->params.isClientTraceEnabled) { + debug(npc, "eraseBlock(%u, %u, %u, %c)", + partIndex, partBank, partBlock, bool2Char(allowSpare)); + } + + ok = hostEraseBlock(npc, ce, addr, block); + + if (!ok) { + markBlockDead(npc, partIndex, partBank, partBlock, allowSpare); + } + +finish_up: + if (npc->provider->params.isClientTraceEnabled) { + debug(npc, "eraseBlock => %c", bool2Char(ok)); + } + return(ok); +} + +static bool +requestPTabDiff(NandPartCore * npc, uint32_t partIndex, void * buf, unsigned size) +{ + const unsigned diffSize = sizeof(NandPartDiff); + NandPartDiff * diff = (NandPartDiff*)buf; + bool ok = false; + + ok = isEntryIndexValid(npc, partIndex, false); + require_action(ok, finish_up, bug(npc, "out of bounds - part:%u", partIndex)); + + if (diffSize <= size) { + + // start clean + hostSetMem(npc, diff, 0, diffSize); + + // tag data blob as one of our diffs + diff->header.magic = kNandPartDiffMagic; + diff->header.size = diffSize; + diff->header.sequence = ++(npc->diffSequence[partIndex]); + + // record important info from current partition table + // header to later be able to track whether it is + // applicable to merge the diff + diff->header.versionMajor = npc->ptab->header.versionMajor; + diff->header.versionMinor = npc->ptab->header.versionMinor; + diff->header.generation = npc->ptab->header.generation; + + // record current state of cemetery, so that we don't + // forget about blocks that have died since last restore + hostMoveMem(npc, &diff->cemetery, &npc->ptab->cemetery, sizeof(NandPartCemetery)); + + // apply checksums + fletcher16(npc, &diff->checks[0], &diff->checks[1], diff, diffSize - sizeof(diff->checks)); + + ok = true; + } + +finish_up: + return(ok); +}; + +static bool +providePTabDiff(NandPartCore * npc, uint32_t partIndex, const void * buf, unsigned size) +{ + NandPartDiff * diff = (NandPartDiff*)buf; + bool ok = false; + + ok = isEntryIndexValid(npc, partIndex, false); + require_action(ok, finish_up, bug(npc, "out of bounds - part:%u", partIndex)); + + ok = validatePTabDiff(npc, diff, size); + require_action(ok, finish_up, warn(npc, "ignoring invalid diff - part:%u", partIndex)); + + ok = mergePartitionCemetery(npc, partIndex, &diff->cemetery, &npc->ptab->cemetery); + require_action(ok, finish_up, error(npc, "failed merge - part:%u", partIndex)); + + npc->diffSequence[partIndex] = diff->header.sequence; + debug(npc, "applied ptab diff provided by part:%u", partIndex); + +finish_up: + return(ok); +}; + +static bool +formatPTab(NandPartCore * npc) +{ + bool result = true; + + if (!isFormatEnabled(npc)) { + bug(npc, "partition table format not allowed in this context"); + result = false; + } else if (!validatePTab(npc, npc->ptab)) { + error(npc, "partition table invalid"); + result = false; + } else { + npc->isFBBTCached = false; + if (!createPartitionDevices(npc, true)) { + error(npc, "no partition devices created"); + result = false; + } else { + debug(npc, "copied new partition table and created specified partitions"); + hostSetBooleanProperty(npc, kNandPartCoreIsFormattedKey, true); + } + } + + return(result); +} + +static unsigned +getPTabBytes(NandPartCore * npc, void * buf, unsigned size) +{ + unsigned bytesRead = 0; + if (npc->isPTabValid) { + bytesRead = (size > sizeof(NandPartTable)) ? sizeof(NandPartTable) : size; + hostMoveMem(npc, buf, npc->ptab, bytesRead); + } + return bytesRead; +} + +static bool +loadPartitionTable(NandPartCore * npc) +{ + bool ok = false; + + // We scan all of the available banks looking for partition tables. + if (!readPTab(npc)) { + + npc->isFBBTCached = false; + + // If no partition table is found, create a single "unformatted" partition. + ok = createUnformattedPartitionDevice(npc); + require_action(ok, finish_up, bug(npc, "unable to create unformatted device")); + + debug(npc, "created unformatted device"); + hostSetBooleanProperty(npc, kNandPartCoreIsFormattedKey, false); + + if (isFormatEnabled(npc)) { + ok = formatWithSpecs(npc); + } + + hostSetNumberProperty(npc, kNandPartCoreMaxSparesKey, countMaxSpares(npc), 32); + + } else { + + hostSetNumberProperty(npc, kNandPartCoreMaxSparesKey, countMaxSpares(npc), 32); + + // Force recache of factory BBT information iff version on + // partition table precedes the FBBTCache feature. + if (ptabPrecedesFeature(npc->ptab, FBBTCache)) { + npc->isFBBTCached = true; + } else { + npc->isFBBTCached = false; + } + + // Add kNandPartEntryFlagsIgnoreFBBT flag if necessary. + addIgnoreFBBTFlag(npc); + + // Make certain each entry explicitly identifies partition type + // iff version on partition table precedes the PoolPartition feature. + makeEntryTypesExplicit(npc); + + // Otherwise, publish the partitions defined by the partition table. + ok = createPartitionDevices(npc, false); + require_action(ok, finish_up, bug(npc, "failed to create partition devices")); + + debug(npc, "created devices for partition entries"); + hostSetBooleanProperty(npc, kNandPartCoreIsFormattedKey, true); + } + +finish_up: + return(ok); +} + +static bool +eraseBootPartition(NandPartCore * npc) +{ + bool ok = true; + + ok = isBootPartErasable(npc); + require_action(ok, finish_up, bug(npc, "boot partition erase not allowed in this context")); + + if (!npc->isBootPartErased) { + + // Write partition table to nand, thereby erasing boot + // partition as a side effect. + ok = writePTab(npc); + require_action(ok, finish_up, error(npc, "unable to erase boot partition")); + + npc->isBootPartErased = true; + } + +finish_up: + return(ok); +} + +static bool +writeBootPartition(NandPartCore * npc, uint8_t * llbBuf, unsigned llbSize) +{ + bool ok = false; + uint8_t * tempBuf = NULL; + const bool isPpn = isPpnDevice(npc); + const size_t fullPageSize = npc->provider->geometry.bytesPerFullPage; + const size_t bootPageSize = npc->provider->geometry.bytesPerBootPage; + const uint32_t numAvailPages = getPagesPerBlock(npc, npc->bootIdx); + const uint32_t numPtabPages = kNandPartTableCopies; + const uint32_t numCompletePages = (llbSize / bootPageSize); + const size_t partialPageSize = (llbSize % bootPageSize); + const size_t fillSize = (bootPageSize - partialPageSize); + const uint32_t numPartialPages = ((0 == partialPageSize) ? 0 : 1); + const uint32_t numLlbPages = (numCompletePages + numPartialPages); + const uint32_t numPages = (numPtabPages + numLlbPages); + const uint32_t lastPage = (isPpn ? numAvailPages : numPages) - 1; + const uint32_t block = 0; + size_t remaining = llbSize; + size_t offset = 0; + uint32_t page; + uint32_t ce; + + require_action(npc->bootIdx < kNandPartEntryMaxCount, clean_up, bug(npc, "missing boot partition")); + require_action(isBootPartWritable(npc), clean_up, bug(npc, "boot partition write not allowed in this context")); + require_action(numPages <= numAvailPages, clean_up, error(npc, "LLB is too large; can't write boot partition")); + + ok = eraseBootPartition(npc); + require_action(ok, clean_up, error(npc, "failed erase of boot partition")); + + tempBuf = (uint8_t*)hostAllocMem(npc, fullPageSize, true); + ok = (NULL != tempBuf); + require_action(ok, clean_up, bug(npc, "alloc failed")); + + npc->isBootPartErased = false; + for (page = kNandPartTableCopies; page <= lastPage; page++) { + + const uint32_t addr = calcNandAddress(npc, block, page, false); + const bool isEmpty = (remaining == 0); + const bool isPartial = (!isEmpty && (remaining < bootPageSize)); + const size_t copySize = (isEmpty ? 0 : (isPartial ? partialPageSize : bootPageSize)); + uint32_t goodCopies = 0; + uint8_t * pageBuf = NULL; + + if (isEmpty) { + + ok = ((numPages <= page) && (page < numAvailPages)); + require_action(ok, clean_up, bug(npc, "bad page index %u", page)); + hostReadRandom(npc, tempBuf, fullPageSize); + pageBuf = tempBuf; + + } else if (isPartial) { + + ok = (page == (numPages - 1)); + require_action(ok, clean_up, bug(npc, "bad page index %u", page)); + hostMoveMem(npc, tempBuf, llbBuf + offset, copySize); + hostReadRandom(npc, tempBuf + copySize, fillSize); + pageBuf = tempBuf; + + } else { + + ok = ((numPtabPages <= page) && (page < (numPages - numPartialPages))); + require_action(ok, clean_up, bug(npc, "bad page index %u", page)); + pageBuf = llbBuf + offset; + } + + ok = (NULL != pageBuf); + require_action(ok, clean_up, bug(npc, "pageBuf unassigned")); + + for (ce = 0; ce < npc->provider->geometry.ceCount; ce++) { + + if (isEmpty) { + + // fill empty pages after LLB content by writing as a full page + // iff writing to a PPN device; otherwise, for raw nand devices, + // we leave empty pages unprogrammed, and the bounds defined + // by 'lastPage' above should prevent us from ever executing + // along this conditional path + ok = isPpn; + require_action(ok, clean_up, bug(npc, "empty boot pages should only be written for PPN devices")); + if (!hostWriteFullPage(npc, ce, addr, pageBuf, endorseMetaBuf(npc, npc->bootIdx))) { + warn(npc, "failed empty boot page write at %u:%u", ce, addr); + } + + } else if (!hostWriteBootPage(npc, ce, addr, pageBuf)) { + + // note that a single page write error + // should not abort attempt to write + // boot partition + warn(npc, "failed boot page write at %u:%u", ce, addr); + + } else { + + // XXX - read back to confirm! + goodCopies++; + } + } + + ok = (isEmpty || (0 < goodCopies)); + require_action(ok, clean_up, error(npc, "failed entire page stripe during LLB write")); + + // XXX - Based upon behavior of SecureROM; it only + // matters if at least one CE has entire good copy of + // LLB; therefore, this failure condition is actually + // not sufficient. Extend to correctly identify as + // error the case where no complete copy LLB within + // any CE was written correctly. + + offset += copySize; + remaining -= copySize; + } + + info(npc, "next %u pages of boot blocks written with LLB image of size %u bytes", + numLlbPages, llbSize); + info(npc, "final %u pages of boot blocks %s", + (numAvailPages - numPages), + isPpn ? "written with random data in full page format" : "left unprogrammed"); + +clean_up: + if (NULL != tempBuf) { + hostFreeMem(npc, tempBuf, fullPageSize); + tempBuf = NULL; + } + + return(ok); +} + + +/* ========================================================================== */ + +#pragma mark - Unlocked External Interface Wrappers + +static const NandPartEntry * +getEntryExternal(void * core, uint32_t partIndex) +{ + return getEntry((NandPartCore*)core, partIndex); +} + +static uint32_t +getBankWidthExternal(void * core, uint32_t partIndex) +{ + return getBankWidth((NandPartCore*)core, partIndex); +} + +static uint32_t +getBlockDepthExternal(void * core, uint32_t partIndex) +{ + return getBlockDepth((NandPartCore*)core, partIndex); +} + +static uint32_t +getPagesPerBlockExternal(void * core, uint32_t partIndex) +{ + return getPagesPerBlock((NandPartCore*)core, partIndex); +} + +static uint32_t +getBytesPerPageExternal(void * core, uint32_t partIndex) +{ + return getBytesPerPage((NandPartCore*)core, partIndex); +} + + +/* ========================================================================== */ + +#pragma mark - Locked External Interface Wrappers + +static bool +loadPartitionTableExternal(void * core) +{ + bool ok; + funcLocked(&ok, loadPartitionTable, core); + return(ok); +} + +static bool +eraseBootPartitionExternal(void * core) +{ + bool ok; + funcLocked(&ok, eraseBootPartition, core); + return(ok); +} + +static bool +writeBootPartitionExternal(void * core, void * llbBuf, unsigned llbSize) +{ + bool ok; + funcLocked(&ok, writeBootPartition, core, (uint8_t *)llbBuf, llbSize); + return(ok); +} + +static bool +isBlockBadExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock) +{ + bool ok; + funcLocked(&ok, isBlockBad, core, partIndex, partBank, partBlock, true); + return(ok); +} + +static bool +readPageExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool * isClean) +{ + bool ok; + funcLocked(&ok, readPage, core, partIndex, partBank, partBlock, pageInBlock, buf, isClean, true); + return(ok); +} + +static bool +writePageExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf) +{ + bool ok; + funcLocked(&ok, writePage, core, partIndex, partBank, partBlock, pageInBlock, buf, true); + return(ok); +} + +static bool +eraseBlockExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock) +{ + bool ok; + funcLocked(&ok, eraseBlock, core, partIndex, partBank, partBlock, true); + return(ok); +} + +static bool +requestPTabDiffExternal(void * core, uint32_t partIndex, void * buf, unsigned size) +{ + bool ok; + funcLocked(&ok, requestPTabDiff, core, partIndex, buf, size); + return(ok); +} + +static bool +providePTabDiffExternal(void * core, uint32_t partIndex, const void * buf, unsigned size) +{ + bool ok; + funcLocked(&ok, providePTabDiff, core, partIndex, buf, size); + return(ok); +} + +static bool +formatPTabExternal(void * core) +{ + bool ok; + funcLocked(&ok, formatPTab, core); + return(ok); +} + +static unsigned +getPTabBytesExternal(void * core, void * buf, unsigned size) +{ + unsigned bytesRead; + funcLocked(&bytesRead, getPTabBytes, core, buf, size); + return(bytesRead); +} + + +/* ========================================================================== */ diff --git a/drivers/flash_nand/boot/nand_part_core.h b/drivers/flash_nand/boot/nand_part_core.h new file mode 100644 index 0000000..4b3f7d4 --- /dev/null +++ b/drivers/flash_nand/boot/nand_part_core.h @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +/*! + @header nand_part_core + + @abstract prototypes for internal implementation of nand_part_core.c + + @copyright Apple Inc. + + @updated 2012-02-21 +*/ + +/* ========================================================================== */ + +#ifndef _NAND_PART_CORE_H +#define _NAND_PART_CORE_H + + +// ============================================================================= +// XXX - pass this in from provider rather than hard-code copy + +#define AND_SPARE_TYPE_REGION_BFN (0x40) // allowing BFN to use 4 bits for types + + +// ============================================================================= +// partition mapping +// +// Note that this is a calculated dynamic data structure only. + +#define kNandPartMappingMaxCount kNandPartEntryMaxCount + +typedef struct _NandPartMapping { + + uint32_t total; + uint32_t counts[kNandPartEntryMaxCount]; + uint32_t offsets[kNandPartEntryMaxCount]; + +} NandPartMapping; + + +// ============================================================================= +// mapped block replacement +// +// Note that this is a dynamic data structure only. The array of +// these structs is effectively an expanded version of the persistent +// NandPartSubst information, forming a fully populated table indexing +// from block map number to spare index rather the other way around +// for ease and speed of use when remapping in the runtime context. + +#define kNandPartReplacementMaxCount kNandPartCemeteryCapacity +#define kNandPartReplacementInvalidIndex ((uint32_t)-1) + +typedef struct _NandPartReplacement { + + bool isValid; + bool isReplaced; + uint32_t spareIndex; + +} NandPartReplacement; + + +// ============================================================================= +// state of portable core providing interface for nand partitioning logic + +typedef struct _NandPartCore { + + NandPartInterface interface; + NandPartProvider * provider; + + NandPartEntry rawMedia; + + bool isPTabValid; + bool isBootPartErased; + bool isFBBTCached; + uint32_t bootIdx; + uint16_t diffSequence[kNandPartEntryMaxCount]; + + uint8_t * meta; + NandPartTable * ptab; + + NandPartMapping mapping; + NandPartReplacement replacements[kNandPartReplacementMaxCount]; + +} NandPartCore; + + +/* ========================================================================== */ + +struct partition_spec { + uint32_t type; + uint32_t content; + uint32_t depth; + uint32_t width; /* optional, depending on type */ +}; + + +/* ========================================================================== */ + +#define kNandPartCountInvalid ((uint32_t)-1) +#define kNandPartBlockInvalid ((uint32_t)-1) +#define kNandPartCEInvalid ((uint32_t)-1) + + +/* ========================================================================== */ + +__BEGIN_DECLS + + +/* ========================================================================== */ + +#pragma mark - Provider Service Wrappers + +static bool hostCreatePartitionDevice(NandPartCore * npc, NandPartEntry * entry, unsigned idx); +static bool hostPublishPartitionDevice(NandPartCore * npc, unsigned idx); +static bool hostReadBootPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf, bool * is_clean); +static bool hostReadFullPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf, void * meta, bool * is_clean); +static bool hostWriteBootPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf); +static bool hostWriteFullPage(NandPartCore * npc, uint32_t ce, uint32_t addr, void * buf, void * meta); +static bool hostEraseBlock(NandPartCore * npc, uint32_t ce, uint32_t addr, uint32_t block); +static void hostLogMessage(NandPartCore * npc, NandPartLogLevel lvl, const char * fmt, ...); + + +/* ========================================================================== */ + +#pragma mark - Initialization + +static NandPartCore * withNandPartCore(NandPartProvider * provider); +static bool createUnformattedPartitionDevice(NandPartCore * npc); +static bool createPartitionDevices(NandPartCore * npc, bool isNewborn); + + +/* ========================================================================== */ + +#pragma mark - Version-Dependent Fixups + +static void makeEntryTypesExplicit(NandPartCore * npc); +static void addIgnoreFBBTFlag(NandPartCore * npc); +static void cleanEntryFlags(NandPartCore * npc, NandPartEntry * entry, bool isNewborn); + + +/* ========================================================================== */ + +#pragma mark - Mature Device Preparation + +static bool prepareMatureState(NandPartCore * npc, bool *isReborn); +static void setPartitionTableProperties(NandPartCore * npc, bool isNewborn, bool isReborn); + + +/* ========================================================================== */ + +#pragma mark - Reborn/Newborn Device Preparation + +static bool prepareRebornState(NandPartCore * npc); +static bool prepareNewbornState(NandPartCore * npc, bool isReborn); +static uint32_t countSparesNeeded(NandPartCore * npc, bool useWorstCase); +static uint32_t countSparesExtra(NandPartCore * npc); +static uint32_t scrubMappedPartitionsForStillborn(NandPartCore * npc); +static bool scrubBlockForStillborn(NandPartCore * npc, uint32_t part, uint32_t bank, uint32_t block, void * patternBuf); + + +/* ========================================================================== */ + +#pragma mark - Initial Format/Partitioning + +static bool formatWithSpecs(NandPartCore * npc); +static void initPartitionTable(NandPartCore * npc); +static uint32_t majorVersion(NandPartCore * npc); +static bool addPartition(NandPartCore *npc, NandPartSpec *spec, uint32_t index, bool * haveBulk); + + +/* ========================================================================== */ + +#pragma mark - Runtime Parameters + +static bool isBootPartErasable(NandPartCore * npc); +static bool isBootPartWritable(NandPartCore * npc); +static bool isFormatEnabled(NandPartCore * npc); +static bool isDebugEnabled(NandPartCore * npc); +static bool isPoolAllowed(NandPartCore * npc); +static uint32_t maxMajorVersion(NandPartCore * npc); + + +/* ========================================================================== */ + +#pragma mark - Miscellaneous Global Information + +static bool isPpnDevice(NandPartCore * npc); +static bool findBootPartIndex(NandPartCore * npc, uint32_t * partIndex); +static bool isEntryIndexValid(NandPartCore * npc, uint32_t partIndex, bool allowRawIndex); +static bool isRawEntryIndex(NandPartCore * npc, uint32_t partIndex); +static bool allowPoolPartitions(NandPartCore * npc); + + +/* ========================================================================== */ + +#pragma mark - Partition Entry Information + +static const char * entryContentName(NandPartCore * npc, uint32_t partIndex); +static bool areFlagsSet(NandPartCore * npc, uint32_t partIndex, uint32_t flagMask); +static bool usingSLCBlocks(NandPartCore * npc, uint32_t partIndex); +static bool usingFullPages(NandPartCore * npc, uint32_t partIndex); +static uint32_t getBlockOffset(NandPartCore * npc, uint32_t partIndex); + + +/* ========================================================================== */ + +#pragma mark - Virtual to Physical Address Calculation + +static uint32_t mapNandBlock(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); +static uint32_t mapNandCE(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); +static uint32_t calcNandAddress(NandPartCore * npc, uint32_t nandBlock, uint32_t pageInBlock, bool useSLC); + +#if NAND_PART_CORE_ORPHAN +static uint32_t calcNandBlock(NandPartCore * npc, uint32_t nandAddress, bool useSLC); +#endif + + +/* ========================================================================== */ + +#pragma mark - Meta Buffer Proxy + +static uint8_t * getMetaBuf(NandPartCore * npc); +static uint8_t * resetMetaBuf(NandPartCore * npc); +static uint8_t * endorseMetaBuf(NandPartCore * npc, uint32_t partIndex); +static void verifyMetaBuf(NandPartCore * npc, uint32_t partIndex); + + +/* ========================================================================== */ + +#pragma mark - Block Replacement + +static bool initReplacements(NandPartCore * npc); +static bool refreshReplacements(NandPartCore * npc); +static bool validateSpare(NandPartCore * npc, NandPartSpare * spare); +static bool validateSubst(NandPartCore * npc, NandPartSubst * subst); +static bool isBlockReplaced(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t * spareIndex); +static NandPartReplacement * getMappedReplacement(NandPartCore * npc, uint32_t map); +static NandPartSpareLocation * getSpareLocation(NandPartCore * npc, uint32_t spareIndex); +static uint32_t getSpareLocationBlock(NandPartCore * npc, NandPartSpareLocation * location); +static void setSpareLocationBlock(NandPartCore * npc, NandPartSpareLocation * location, uint32_t block); +static bool substituteSparesForBadBlocks(NandPartCore * npc); +static void initMapping(NandPartCore * npc); +static bool isPartitionMapped(NandPartCore * npc, uint32_t partIndex); +static uint32_t calcPartitionMapCount(NandPartCore * npc, uint32_t partIndex); +static uint32_t getPartitionMapOffset(NandPartCore * npc, uint32_t partIndex); +static uint32_t getTotalMapCount(NandPartCore * npc); +static uint32_t calcBlockMap(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); + +#if NAND_PART_CORE_ORPHAN +static uint32_t getPartitionMapCount(NandPartCore * npc, uint32_t partIndex); +#endif + + +/* ========================================================================== */ + +#pragma mark - Bad Block Management + +static bool initCemetery(NandPartCore * npc, bool isNewborn); +static void fletcher16(NandPartCore * npc, uint8_t *checkA, uint8_t *checkB, const void *buf, size_t len); +static bool isCemeterySafe(NandPartCore * npc, const NandPartCemetery *cemetery); +static void changeCemeteryLocks(NandPartCore * npc, NandPartCemetery * cemetery); +static bool mergePartitionCemetery(NandPartCore * npc, uint32_t partIndex, const NandPartCemetery * partCemetery, NandPartCemetery * mainCemetery); +static void markBlockDead(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); +static bool isBlockDead(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); +static NandPartFBBTCache * getFBBTCache(NandPartCore * npc); +static bool isBlockFactoryBad(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); +static void cacheFactoryBadBlockTable(NandPartCore * npc); + + +/* ========================================================================== */ + +#pragma mark - Partition Table I/O + +static bool readPTab(NandPartCore * npc); +static bool validatePTab(NandPartCore * npc, const NandPartTable * ptab); +static bool writePTab(NandPartCore * npc); + + +/* ========================================================================== */ + +#pragma mark - Partition Table Diffs + +static void initDiffSequence(NandPartCore * npc); +static bool validatePTabDiff(NandPartCore * npc, NandPartDiff * diff, unsigned size); + + +/* ========================================================================== */ + +#pragma mark - Structure Dumping + +static void dumpNandGeometry(NandPartCore * npc, NandPartGeometry * geometry); +static void dumpPTabHeader(NandPartCore * npc, NandPartHeader * header); +static void dumpCemetery(NandPartCore * npc, NandPartCemetery * cemetery); +static void dumpSpare(NandPartCore * npc, NandPartSpare * spare); +static void dumpSubst(NandPartCore * npc, NandPartSubst * subst); +static void dumpEntries(NandPartCore * npc, NandPartEntry * entries); +static void dumpPTab(NandPartCore * npc, NandPartTable * ptab); +static void dumpMapping(NandPartCore * npc, NandPartMapping * mapping); +static void dumpReplacements(NandPartCore * npc, NandPartReplacement * replacements); +static void dumpTranslationTables(NandPartCore * npc); + + +/* ========================================================================== */ + +#pragma mark - Interface Implementation + +static const NandPartEntry * getEntry(NandPartCore * npc, uint32_t partIndex); +static uint32_t getBankWidth(NandPartCore * npc, uint32_t partIndex); +static uint32_t getBlockDepth(NandPartCore * npc, uint32_t partIndex); +static uint32_t getPagesPerBlock(NandPartCore * npc, uint32_t partIndex); +static uint32_t getBytesPerPage(NandPartCore * npc, uint32_t partIndex); +static bool isBlockBad(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); +static bool readPage(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool * isClean, bool allowSpare); +static bool writePage(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool allowSpare); +static bool eraseBlock(NandPartCore * npc, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, bool allowSpare); +static bool requestPTabDiff(NandPartCore * npc, uint32_t partIndex, void * buf, unsigned size); +static bool providePTabDiff(NandPartCore * npc, uint32_t partIndex, const void * buf, unsigned size); +static bool formatPTab(NandPartCore * npc); +static unsigned getPTabBytes(NandPartCore * npc, void * buf, unsigned size); +static bool loadPartitionTable(NandPartCore * npc); +static bool eraseBootPartition(NandPartCore * npc); +static bool writeBootPartition(NandPartCore * npc, uint8_t * llbBuf, unsigned llbSize); + + +/* ========================================================================== */ + +#pragma mark - Unlocked External Interface Wrappers + +static const NandPartEntry * getEntryExternal(void * core, uint32_t partIndex); +static uint32_t getBankWidthExternal(void * core, uint32_t partIndex); +static uint32_t getBlockDepthExternal(void * core, uint32_t partIndex); +static uint32_t getPagesPerBlockExternal(void * core, uint32_t partIndex); +static uint32_t getBytesPerPageExternal(void * core, uint32_t partIndex); + + +/* ========================================================================== */ + +#pragma mark - Locked External Interface Wrappers + +static bool loadPartitionTableExternal(void * core); +static bool eraseBootPartitionExternal(void * core); +static bool writeBootPartitionExternal(void * core, void * llbBuf, unsigned llbSize); +static bool isBlockBadExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock); +static bool readPageExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool * isClean); +static bool writePageExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf); +static bool eraseBlockExternal(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock); +static bool requestPTabDiffExternal(void * core, uint32_t partIndex, void * buf, unsigned size); +static bool providePTabDiffExternal(void * core, uint32_t partIndex, const void * buf, unsigned size); +static bool formatPTabExternal(void * core); +static unsigned getPTabBytesExternal(void * core, void * buf, unsigned size); + + +/* ========================================================================== */ + +__END_DECLS + +#endif /* _NAND_PART_CORE_H */ diff --git a/drivers/flash_nand/boot/nand_part_interface.h b/drivers/flash_nand/boot/nand_part_interface.h new file mode 100644 index 0000000..43ec266 --- /dev/null +++ b/drivers/flash_nand/boot/nand_part_interface.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +/*! + @header nand_part_interface + + @abstract portable core for (mostly boot-related) nand partitioning logic + + @copyright Apple Inc. + + @updated 2012-02-21 +*/ + +/* ========================================================================== */ + +#ifndef _NAND_PART_INTERFACE_H +#define _NAND_PART_INTERFACE_H + +__BEGIN_DECLS + +/* ========================================================================== */ + +// disable significant amounts of the logging for tiny build profile +#if (defined(WITH_NAND_PART_BUILD_TINY) && WITH_NAND_PART_BUILD_TINY) +# define NAND_PART_EXTENDED_LOGGING 0 +#else +# define NAND_PART_EXTENDED_LOGGING 1 +#endif + +// enable for local development only; DO NOT SUBMIT with this enabled to trunk +#define NAND_PART_LOCAL_DEBUG_ONLY 0 + + +/* ========================================================================== */ +/* property keys */ + +#define kNandPartCoreVersionMajorKey "VersionMajor" +#define kNandPartCoreVersionMinorKey "VersionMinor" +#define kNandPartCoreGenerationKey "Generation" + +#define kNandPartCoreIsFormattedKey "isFormatted" +#define kNandPartCoreIsNewbornKey "isNewborn" +#define kNandPartCoreIsRebornKey "isReborn" + +#define kNandPartCoreMaxSparesKey "maxSpares" + + +/* ========================================================================== */ + +enum _NandPartLogLevel { + + kNandPartLogLevelAlways = 0, + + kNandPartLogLevelBug = 1, + kNandPartLogLevelError = 2, + kNandPartLogLevelInfo = 3, + kNandPartLogLevelWarn = 4, + kNandPartLogLevelDebug = 5, + kNandPartLogLevelSpew = 6, + + kNandPartLogLevelNever +}; + +typedef enum _NandPartLogLevel NandPartLogLevel; + +extern const char * kNandPartLogTagBug; +extern const char * kNandPartLogTagError; +extern const char * kNandPartLogTagInfo; +extern const char * kNandPartLogTagWarn; +extern const char * kNandPartLogTagDebug; +extern const char * kNandPartLogTagSpew; + + +/* ========================================================================== */ + +struct _NandPartGeometry { + + bool isPpn; + + uint32_t ceCount; + + uint32_t blocksPerCE; + uint32_t blockStride; + + uint32_t pagesPerMLCBlock; + uint32_t pagesPerSLCBlock; + + uint32_t bytesPerBootPage; + uint32_t bytesPerFullPage; + uint32_t bytesPerFullPageMeta; + + uint32_t bitsPerCauAddr; + uint32_t bitsPerPageAddr; + uint32_t bitsPerBlockAddr; +}; + +typedef struct _NandPartGeometry NandPartGeometry; + + +/* ========================================================================== */ + +struct _NandPartSpec { + uint32_t type; + uint32_t content; + uint32_t depth; + uint32_t width; + uint32_t flags; +}; + +typedef struct _NandPartSpec NandPartSpec; + + +/* ========================================================================== */ + +struct _NandPartParams { + + bool isBootPartErasable; + bool isBootPartWritable; + bool isFormatEnabled; + bool isDebugEnabled; + bool isHostTraceEnabled; + bool isClientTraceEnabled; + bool isPoolAllowed; + uint32_t maxMajorVersion; + NandPartSpec partitionSpecs[kNandPartEntryMaxCount]; +}; + +typedef struct _NandPartParams NandPartParams; + + +/* ========================================================================== */ + +struct _NandPartProvider { + + void * context; + NandPartGeometry geometry; + NandPartParams params; + + void (*lock_interface)(void * context); + void (*unlock_interface)(void * context); + void * (*alloc_mem)(void * context, unsigned size, bool align); + int (*compare_mem)(void * context, const void * left, const void * right, unsigned int size); + void * (*move_mem)(void * context, void * dest, const void * src, unsigned size); + void * (*set_mem)(void * context, void * mem, uint8_t val, unsigned size); + void (*free_mem)(void * context, void * mem, unsigned size); + void (*read_random)(void * context, void * buf, unsigned size); + bool (*read_boot_page)(void * context, uint32_t ce, uint32_t addr, void * buf, bool * is_clean); + bool (*read_full_page)(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta, bool * is_clean); + bool (*write_boot_page)(void * context, uint32_t ce, uint32_t addr, void * buf); + bool (*write_full_page)(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta); + bool (*erase_block)(void * context, uint32_t ce, uint32_t addr, uint32_t block); + bool (*is_block_factory_bad)(void * context, uint32_t ce, uint32_t block); + bool (*validate_spare_list)(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count); + bool (*request_spare_blocks)(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count, unsigned * quantity); + bool (*set_data_property)(void * context, const char * key, void * buf, unsigned size); + bool (*set_number_property)(void * context, const char * key, uint64_t num, unsigned bits); + bool (*set_string_property)(void * context, const char * key, const char * cstring); + bool (*set_boolean_property)(void * context, const char * key, bool val); + bool (*wait_for_fbbt_service)(void * context); + bool (*create_partition_device)(void * context, NandPartEntry * entry, uint32_t idx); + bool (*publish_partition_device)(void * context, uint32_t idx); + void (*vlogf_message)(void * context, NandPartLogLevel lvl, const char * fmt, va_list ap); +}; + +typedef struct _NandPartProvider NandPartProvider; + + +/* ========================================================================== */ + +struct _NandPartInterface { + + void * core; + + bool (*load_ptab)(void * core); + bool (*erase_boot_partition)(void * core); + bool (*write_boot_partition)(void * core, void * llbBuf, unsigned llbSize); + bool (*is_block_bad)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock); + const NandPartEntry * (*get_entry)(void * core, uint32_t partIndex); + uint32_t (*get_bank_width)(void * core, uint32_t partIndex); + uint32_t (*get_block_depth)(void * core, uint32_t partIndex); + uint32_t (*get_pages_per_block)(void * core, uint32_t partIndex); + uint32_t (*get_bytes_per_page)(void * core, uint32_t partIndex); + bool (*read_page)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool * isClean); + bool (*write_page)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf); + bool (*erase_block)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock); + bool (*request_ptab_diff)(void * core, uint32_t partIndex, void * buf, unsigned size); + bool (*provide_ptab_diff)(void * core, uint32_t partIndex, const void * buf, unsigned size); + bool (*format_ptab)(void * core); + unsigned (*get_ptab_bytes)(void * core, void * buf, unsigned size); +}; + +typedef struct _NandPartInterface NandPartInterface; + +#define _npiExec(npi, fn, args...) npi->fn(npi->core, ##args) + +#define npi_load_ptab(npi) _npiExec(npi, load_ptab) +#define npi_erase_boot_partition(npi) _npiExec(npi, erase_boot_partition) +#define npi_write_boot_partition(npi, buf, size) _npiExec(npi, write_boot_partition, buf, size) +#define npi_is_block_bad(npi, part, bank, block) _npiExec(npi, is_block_bad, part, bank, block) +#define npi_get_entry(npi, part) _npiExec(npi, get_entry, part) +#define npi_get_bank_width(npi, part) _npiExec(npi, get_bank_width, part) +#define npi_get_block_depth(npi, part) _npiExec(npi, get_block_depth, part) +#define npi_get_pages_per_block(npi, part) _npiExec(npi, get_pages_per_block, part) +#define npi_get_bytes_per_page(npi, part) _npiExec(npi, get_bytes_per_page, part) +#define npi_read_page(npi, part, bank, block, page, buf, clean) _npiExec(npi, read_page, part, bank, block, page, buf, clean) +#define npi_write_page(npi, part, bank, block, page, buf) _npiExec(npi, write_page, part, bank, block, page, buf) +#define npi_erase_block(npi, part, bank, block) _npiExec(npi, erase_block, part, bank, block) +#define npi_request_ptab_diff(npi, part, buf, size) _npiExec(npi, request_ptab_diff, part, buf, size) +#define npi_provide_ptab_diff(npi, part, buf, size) _npiExec(npi, provide_ptab_diff, part, buf, size) +#define npi_format_ptab(npi) _npiExec(npi, format_ptab) +#define npi_get_ptab_bytes(npi, buf, size) _npiExec(npi, get_ptab_bytes, buf, size) + + +/* ========================================================================== */ + +extern bool nand_part_init(NandPartInterface ** interface, NandPartProvider * provider); +extern void nand_part_dump(NandPartInterface * interface); + +/* ========================================================================== */ + +__END_DECLS + +#endif /* _NAND_PART_INTERFACE_H */ diff --git a/drivers/flash_nand/boot/nvram/nand_nvram.c b/drivers/flash_nand/boot/nvram/nand_nvram.c new file mode 100644 index 0000000..6bbcdce --- /dev/null +++ b/drivers/flash_nand/boot/nvram/nand_nvram.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_NVRAM + +/* ========================================================================== */ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "nand_part.h" +#include "nand_part_interface.h" +#include "nand_export.h" +#include "nand_nvram_impl.h" +#include "nand_nvram_core.h" +#include "nand_nvram_dump.h" + +/* ========================================================================== */ + +#define DEBUG_NONDESTRUCTIVE 0 + +/* ========================================================================== */ + +#define TRACE_ENABLE 0 +#if TRACE_ENABLE + +// FWiW: tracing is relying on single-threaded behavior for correctness + +static utime_t trace_time = 0; +static unsigned int trace_line = 0; + +#define TRACE_BEFORE() \ + do { \ + trace_line = __LINE__; \ + trace_time = system_time(); \ + } while (0) + +#define TRACE_AFTER() \ + do { \ + utime_t elapsed = system_time() - trace_time; \ + dprintf(DEBUG_CRITICAL, \ + "\nTRACE - %s@%u-%u: %u.%03u ms\n", \ + __func__, \ + trace_line, \ + __LINE__, \ + elapsed / 1000, \ + elapsed % 1000); \ + } while (0) + +#else /* !TRACE_ENABLE */ + +#define TRACE_BEFORE() /* do nothing */ +#define TRACE_AFTER() /* do nothing */ + +#endif + +/* ========================================================================== */ + +typedef struct { + + NandPartInterface * npi; + uint32_t part; + bool is_initialized; + nand_nvram_t * nvram; + struct blockdev nvram_bdev; + +} _context_t; + +/* ========================================================================== */ + +static _context_t _context = { .part = ~0 }; + + +/* ========================================================================== */ + +static int flash_nand_nvram_read(struct blockdev *bdev, void *buffer, off_t offset, uint64_t length); +static int flash_nand_nvram_read_block(struct blockdev *bdev, void *buffer, block_addr block, uint32_t count); +static int flash_nand_nvram_write(struct blockdev *bdev, const void *buffer, off_t offset, uint64_t length); +static int flash_nand_nvram_write_block(struct blockdev *bdev, const void *buffer, block_addr block, uint32_t count); + +extern bool +flash_nand_nvram_init(NandPartInterface *npi, uint32_t part, bool isNewborn) +{ + nand_nvram_geometry_t geometry; + uint32_t page_size = 0; + + if (_context.is_initialized) + goto done; + + dprintf(DEBUG_SPEW, "initializing nand nvram...\n"); + + TRACE_BEFORE(); + if (isNewborn || (NULL == npi)) { + + dprintf(DEBUG_SPEW, "nand partition table unavailable; returning failure\n"); + goto done; + + } else { + + _context.npi = npi; + _context.part = part; + + page_size = npi_get_bytes_per_page(npi, part); + + /* specify nand geometry information */ + geometry.bytes_per_meta_buffer = kNAND_NVRAM_META_SIZE; + geometry.bytes_per_meta_actual = kNAND_NVRAM_META_SIZE; + geometry.number_of_banks = npi_get_bank_width(npi, part); + geometry.blocks_per_bank = npi_get_block_depth(npi, part); + geometry.pages_per_block = npi_get_pages_per_block(npi, part); + geometry.data_pages_per_block = geometry.pages_per_block - kNAND_NVRAM_PAGE_RESERVED_IN_BLOCK; + geometry.bytes_per_page = page_size - geometry.bytes_per_meta_buffer; + + if (!nand_nvram_open(&_context.nvram, &_context, &geometry, kNAND_NVRAM_SIZE)) { + dprintf(DEBUG_CRITICAL, "couldn't open nand nvram device\n"); + goto done; + } + + dprintf(DEBUG_SPEW, "nand nvram initialized\n"); + } + + construct_blockdev(&_context.nvram_bdev, "nvram", kNAND_NVRAM_SIZE, 1); + _context.nvram_bdev.read_hook = &flash_nand_nvram_read; + _context.nvram_bdev.read_block_hook = &flash_nand_nvram_read_block; + _context.nvram_bdev.write_hook = &flash_nand_nvram_write; + _context.nvram_bdev.write_block_hook = &flash_nand_nvram_write_block; + register_blockdev(&_context.nvram_bdev); + + _context.is_initialized = true; + +done: + TRACE_AFTER(); + return (_context.is_initialized); +} + +static int +flash_nand_nvram_read(struct blockdev *bdev, void *buffer, off_t offset, uint64_t length) +{ + bool ok = true; + + TRACE_BEFORE(); + if (!_context.is_initialized) { + return 0; + } + + ok = nand_nvram_read(_context.nvram, offset, buffer, length); + TRACE_AFTER(); + + return (ok ? length : 0); +} + +static int +flash_nand_nvram_read_block(struct blockdev *bdev, void *buffer, block_addr block, uint32_t count) +{ + return flash_nand_nvram_read(bdev, buffer, block, count); +} + +static int +flash_nand_nvram_write(struct blockdev *bdev, const void *buffer, off_t offset, uint64_t length) +{ + bool ok = true; + + TRACE_BEFORE(); + if (!_context.is_initialized) { + return 0; + } + + ok = nand_nvram_write(_context.nvram, offset, buffer, length); + if (ok) + ok = nand_nvram_sync(_context.nvram); + TRACE_AFTER(); + + return (ok ? length : 0); +} + +static int +flash_nand_nvram_write_block(struct blockdev *bdev, const void *buffer, block_addr block, uint32_t count) +{ + return flash_nand_nvram_write(bdev, buffer, block, count); +} + +/* ========================================================================== */ + +bool +flash_nand_nvram_is_block_bad(void * context, uint32_t bank, uint32_t block) +{ + const _context_t * ctxt = (_context_t*)context; + bool bad; + + TRACE_BEFORE(); + bad = npi_is_block_bad(ctxt->npi, ctxt->part, bank, block); + TRACE_AFTER(); + + return (bad); +} + +bool +flash_nand_nvram_read_page(void * context, uint32_t bank, uint32_t page, void * data, void * meta, bool * is_clean) +{ + const _context_t * ctxt = (_context_t*)context; + const nand_nvram_geometry_t * geo = nand_nvram_get_geometry(ctxt->nvram); + const uint32_t block = page / geo->pages_per_block; + const uint32_t page_in_block = page % geo->pages_per_block; + const uint32_t nand_page_size = npi_get_bytes_per_page(ctxt->npi, ctxt->part); + UInt8 * buf = NULL; + bool ok = false; + + TRACE_BEFORE(); + buf = (UInt8*)memalign(nand_page_size, CPU_CACHELINE_SIZE); + + if (npi_read_page(ctxt->npi, ctxt->part, bank, block, page_in_block, buf, is_clean)) { + + memcpy(meta, buf, geo->bytes_per_meta_actual); + memcpy(data, buf + geo->bytes_per_meta_buffer, geo->bytes_per_page); + + ok = true; + } + + free(buf); + TRACE_AFTER(); + + return (ok); +} + +bool +flash_nand_nvram_write_page(void * context, uint32_t bank, uint32_t page, void * data, void * meta) +{ + const _context_t * ctxt = (_context_t*)context; + const nand_nvram_geometry_t * geo = nand_nvram_get_geometry(ctxt->nvram); + const uint32_t block = page / geo->pages_per_block; + const uint32_t page_in_block = page % geo->pages_per_block; + const uint32_t nand_page_size = npi_get_bytes_per_page(ctxt->npi, ctxt->part); + UInt8 * buf = NULL; + bool ok = false; + + TRACE_BEFORE(); + buf = (UInt8*)memalign(nand_page_size, CPU_CACHELINE_SIZE); + + memcpy(buf, meta, geo->bytes_per_meta_actual); + memcpy(buf + geo->bytes_per_meta_buffer, data, geo->bytes_per_page); + + ok = npi_write_page(ctxt->npi, ctxt->part, bank, block, page_in_block, buf); + + free(buf); + TRACE_AFTER(); + + return (ok); +} + +bool +flash_nand_nvram_request_ptab_diff(void * context, void * data, uint32_t size) +{ + const _context_t * ctxt = (_context_t*)context; + bool ok; + + TRACE_BEFORE(); + ok = npi_request_ptab_diff(ctxt->npi, ctxt->part, data, size); + TRACE_AFTER(); + + return (ok); +} + +bool +flash_nand_nvram_provide_ptab_diff(void * context, void * data, uint32_t size) +{ + const _context_t * ctxt = (_context_t*)context; + bool ok; + + TRACE_BEFORE(); + ok = npi_provide_ptab_diff(ctxt->npi, ctxt->part, data, size); + TRACE_AFTER(); + + return (ok); +} + +bool +flash_nand_nvram_erase_block(void * context, uint32_t bank, uint32_t block) +{ + const _context_t * ctxt = (_context_t*)context; + bool ok; + + TRACE_BEFORE(); + ok = npi_erase_block(ctxt->npi, ctxt->part, bank, block); + TRACE_AFTER(); + + return (ok); +} + +bool flash_nand_nvram_copy_ptab(void * context, void * buf) +{ + const _context_t * ctxt = (_context_t*)context; + bool ok = false; + + TRACE_BEFORE(); + if (NULL != buf) { + ok = npi_get_ptab_bytes(ctxt->npi, buf, npi_get_bytes_per_page(ctxt->npi, ctxt->part)); + } + TRACE_AFTER(); + + return(ok); +} + +bool flash_nand_nvram_read_ptab(void * context, uint32_t bank, uint32_t page, void * buf) +{ + const _context_t * ctxt = (_context_t*)context; + const nand_nvram_geometry_t * geo = nand_nvram_get_geometry(ctxt->nvram); + const uint32_t block = page / geo->pages_per_block; + const uint32_t page_in_block = page % geo->pages_per_block; + bool is_clean; + bool ok = false; + + TRACE_BEFORE(); + if (NULL != buf) { + ok = npi_read_page(ctxt->npi, ctxt->part, bank, block, page_in_block, buf, &is_clean); + } + TRACE_AFTER(); + + return (ok); +} + +bool flash_nand_nvram_write_ptab(void * context, uint32_t bank, uint32_t page, void * buf) +{ + const _context_t * ctxt = (_context_t*)context; + const nand_nvram_geometry_t * geo = nand_nvram_get_geometry(ctxt->nvram); + const uint32_t block = page / geo->pages_per_block; + const uint32_t page_in_block = page % geo->pages_per_block; + bool ok = false; + + TRACE_BEFORE(); + if (NULL != buf) { + ok = npi_write_page(ctxt->npi, ctxt->part, bank, block, page_in_block, buf); + } + TRACE_AFTER(); + + return (ok); +} + +/* ========================================================================== */ + +static int do_nvram_dump(int argc, struct cmd_arg *args) +{ + return (nand_nvram_dump(_context.nvram) ? 0 : -1); +} + +MENU_COMMAND_DEVELOPMENT(nvramdump, do_nvram_dump, "dump nand-based nvram pages", NULL); + +/* ========================================================================== */ + +#endif // WITH_NVRAM + diff --git a/drivers/flash_nand/boot/nvram/nand_nvram_core.c b/drivers/flash_nand/boot/nvram/nand_nvram_core.c new file mode 100644 index 0000000..5ff026e --- /dev/null +++ b/drivers/flash_nand/boot/nvram/nand_nvram_core.c @@ -0,0 +1,1776 @@ +/* + * Copyright (c) 2008-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "nand_part.h" +#include "nand_nvram_platform.h" +#include "nand_nvram_impl.h" +#include "nand_nvram_core.h" + +/* ========================================================================== */ + +/*! + @group private platform-independent type declarations +*/ + +typedef enum _log_level log_level_t; + +/* ========================================================================== */ + +/*! + @group private platform-independent constant definitions +*/ + +/*! + @const kNAND_NVRAM_MUTE + + @abstract Flag used to eliminate all output. Note that you probably + don't want to use this normally and should instead adjust + kNAND_NVRAM_LOG_LEVEL below. +*/ +#define kNAND_NVRAM_MUTE 0 + +/*! + @const kNAND_NVRAM_LOG_LEVEL + + @abstract Default cutoff level for debug output. +*/ +#define kNAND_NVRAM_LOG_LEVEL LOG_LEVEL_INFO + +/* ========================================================================== */ + +/*! + @group private platform-independent enumerations +*/ + +enum _log_level +{ + LOG_LEVEL_NONE, + LOG_LEVEL_ERROR, + LOG_LEVEL_INFO, + LOG_LEVEL_WARN, + LOG_LEVEL_SPEW, + LOG_LEVEL_ALL +}; + +/* ========================================================================== */ + +/*! + @group private platform-independent macro definitions +*/ + +#if kNAND_NVRAM_MUTE + +#define log_printf(nv, lvl, ...) + +#define dump(nv, lvl, indent, ...) + +#define nand_nvram_fail(nv, val) \ + do { \ + val = false; \ + } while (0) + +#else /* kNAND_NVRAM_MUTE */ + +#define log_printf(nv, lvl, ...) \ + do { \ + if ((lvl) <= kNAND_NVRAM_LOG_LEVEL) \ + nand_nvram_printf(nv->context, __VA_ARGS__); \ + } while (0) + +#define dump(nv, lvl, indent, ...) \ + do { \ + int _idx; \ + for (_idx = 0; _idx < (int)(indent); _idx++) \ + log_printf((nv), (lvl), "%20s", ""); \ + log_printf((nv), (lvl), __VA_ARGS__); \ + } while (0) + +#define nand_nvram_fail(nv, val) \ + do { \ + log_printf((nv), LOG_LEVEL_ERROR, \ + "[NAND_NVRAM] FAIL -> %s@%d\n", \ + __FILE__, __LINE__); \ + val = false; \ + } while (0) + +#endif /* kNAND_NVRAM_MUTE */ + +/* ========================================================================== */ + +/*! + @group static wrappers around system portability hooks +*/ + +static inline void * alloc_mem(nand_nvram_t * nv, uint32_t size); +static inline signed compare_mem(nand_nvram_t * nv, void * left, void * right, uint32_t size); +static inline void copy_mem(nand_nvram_t * nv, void * dest, const void * src, uint32_t size); +static inline void set_mem(nand_nvram_t * nv, void * mem, uint8_t value, uint32_t size); +static inline void free_mem(nand_nvram_t * nv, void * mem, uint32_t size); +static inline bool is_block_bad(nand_nvram_t * nv, uint32_t bank, uint32_t block); +static inline bool read_page(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * data, void * meta, bool * is_clean); +static inline bool write_page(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * data, void * meta); +static inline bool erase_block(nand_nvram_t * nv, uint32_t bank, uint32_t block); +static inline bool request_ptab_diff(nand_nvram_t * nv, void * data, uint32_t size); +static inline bool provide_ptab_diff(nand_nvram_t * nv, void * data, uint32_t size); +static inline bool copy_ptab(nand_nvram_t * nv, void * buf); +static inline bool read_ptab(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * buf); +static inline bool write_ptab(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * buf); + +/* ========================================================================== */ + +/*! + @group implementation functions used to commit of nvram data to nand store +*/ + +/*! + @function commit_shadow + + @abstract Commit new generation of shadowed nvram area from + ram buffers to nand array. + + @result Returns bool indicating whether function succeeded committing at generation to at least one bank. +*/ +static bool commit_shadow(nand_nvram_t * nv); + +/*! + @function commit_to_bank + + @abstract Commit new generation to specified bank. + + @param bank + + @result Returns bool indicating whether function succeeded committing generation to bank. +*/ +static bool commit_to_bank(nand_nvram_t * nv, uint32_t bank, blob_t * scratch); + +/*! + @function prepare_next_commit_block + + @abstract Find and prepare next block in a bank for generation commit. + + @param bank Bank to prepare. + + @param block In/out reference to current commit block and, upon return, to newly prepared block. + + @param attempts In/out reference used by caller to accumulate total block per bank commit attempts. + + @result Returns bool indicating whether function succeeded in preparing a commit block. +*/ +static bool prepare_next_commit_block(nand_nvram_t * nv, uint32_t bank, uint32_t * block, uint32_t * attempts); + +/*! + @function commit_to_block_in_bank + + @abstract Attempt to commit generation to specific bank in block starting at the specified page offset in the block. + + @param bank + + @param block + + @param start_page_in_block + + @result Returns bool indicating whether function succeeded committing to specified block in specified bank. +*/ +static bool commit_to_block_in_bank(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t start_page_in_block, blob_t * scratch); + +static void increment_generation(nand_nvram_t * nv); + +/* ========================================================================== */ + +/*! + @group implementation methods used to restore nvram data from nand store +*/ + +/*! + @function restore_shadow + + @abstract Restore youngest generation of nvram data from nand array. + + @result Returns bool indicating whether function succeeded. +*/ +static bool restore_shadow(nand_nvram_t * nv); + +/*! + @function init_meta +*/ +static void init_meta(nand_nvram_t * nv, meta_t * meta, uint32_t generation, uint32_t page_count, uint32_t page_idx); + +/*! + @function validate_meta + + @abstract Check that individual meta data struct is + internally self-consistent. + + @param page_meta Pointer to page meta struct. + + @result Returns bool indicating whether function succeeded. +*/ +static bool validate_meta(nand_nvram_t * nv, meta_t * page_meta, uint32_t idx); + +/*! + @function calc_page_count_from_size + + @abstract Calculate number of pages required to contain + given size of data. + + @param size Size, in bytes, of data to be stored in nand pages. + + @result Returns number of pages. +*/ +static uint32_t calc_page_count_from_size(nand_nvram_t * nv, uint32_t size); + +static uint32_t calc_extra_offset(nand_nvram_t * nv); +static uint32_t calc_extra_size(nand_nvram_t * nv); + +/*! + @function calc_block_from_page + + @abstract Calculate block offset within bank from page number. + + @param page_num Zero-based page number. + + @result Returns block offset within bank. +*/ +static uint32_t calc_block_from_page(nand_nvram_t * nv, uint32_t page_num); + +/*! + @function calc_page_in_block_from_page + + @abstract Calculate page offset within block from page number. + + @param page_num Zero-based page number. + + @result Returns page offset within block. +*/ +static uint32_t calc_page_in_block_from_page(nand_nvram_t * nv, uint32_t page_num); + +/*! + @function calc_base_page_from_block + + @abstract Calculate page number of base page in block given + block number. + + @param block_num Zero-based block number. + + @result Returns page number. +*/ +static uint32_t calc_base_page_from_block(nand_nvram_t * nv, uint32_t block_num); + +/*! + @function get_blob_page_data + + @abstract Return pointer from within data buffer to indexed + page's data bytes. + + @param page_index Index of page within shadow for which + reference should be returned. + + @result Returns pointer to data bytes within blob page. +*/ +static uint8_t * get_blob_page_data(nand_nvram_t * nv, blob_t * blob, uint32_t page_index); + +/*! + @function get_blob_page_meta + + @abstract Return pointer from within meta buffer to indexed + page's meta struct. + + @param page_index Index of page within shadow for which + reference should be returned. + + @result Return pointer to meta bytes within blob page. +*/ +static meta_t * get_blob_page_meta(nand_nvram_t * nv, blob_t * blob, uint32_t page_index); + +/*! + @function get_blob_generation +*/ +static uint32_t get_blob_generation(nand_nvram_t * nv, blob_t * blob); + +/*! + @function get_blob_page_count +*/ +static uint32_t get_blob_page_count(nand_nvram_t * nv, blob_t * blob); + +/*! + @function alloc_blob +*/ +static bool alloc_blob(nand_nvram_t * nv, blob_t ** blob_ref, uint32_t page_count); + +/*! + @function free_blob +*/ +static void free_blob(nand_nvram_t * nv, blob_t ** blob_ref, uint32_t page_count); + +/*! + @function read_blob +*/ +static bool read_blob(nand_nvram_t * nv, blob_t * blob, uint32_t bank, uint32_t block, uint32_t base, uint32_t offset); + +/*! + @function alloc_page_bufs +*/ +static bool alloc_page_bufs(nand_nvram_t * nv, uint32_t page_count, void ** meta_bufs_ref, void ** data_bufs_ref); + +/*! + @function free_page_bufs +*/ +static void free_page_bufs(nand_nvram_t * nv, uint32_t page_count, void ** meta_bufs_ref, void ** data_bufs_ref); + +static uint32_t calc_watermark_index(nand_nvram_t * nv, uint32_t bank, uint32_t block); +static uint32_t get_watermark(nand_nvram_t * nv, uint32_t bank, uint32_t block); +static void update_watermark(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t new_watermark); +static void clear_watermark(nand_nvram_t * nv, uint32_t bank, uint32_t block); + + +/* ========================================================================== */ + +static bool is_block_closed(nand_nvram_t * nv, uint32_t bank, uint32_t block); +static bool close_block(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t offset); +static bool fill_pages_with_ptab(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t offset, uint32_t count); +static bool beget_newborn(nand_nvram_t * nv); +static void migrate_forward(nand_nvram_t * nv); +static bool find_youngest(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t* ancestor, uint32_t* youngest); + +/* ========================================================================== */ + +#if kNAND_NVRAM_MUTE + +#define dump_geometry(nv, lvl, indent, geo) +#define dump_meta(nv, lvl, indent, meta) +#define dump_data(nv, lvl, indent, data) +#define dump_blob(nv, lvl, indent, blob, page_count) +#define dump_nvram(nv, lvl, indent) + +#else + +static void _dump_geometry(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, nand_nvram_geometry_t * geo); +static void _dump_meta(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, meta_t * meta); +static void _dump_data(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, uint8_t * data); +static void _dump_blob(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, blob_t * blob, uint32_t page_count); +static void _dump_nvram(nand_nvram_t * nv, uint32_t lvl, uint32_t indent); + +#define dump_geometry(nv, lvl, indent, geo) \ + do { \ + if ((lvl) <= kNAND_NVRAM_LOG_LEVEL) \ + _dump_geometry(nv, lvl, indent, geo); \ + } while (0) + +#define dump_meta(nv, lvl, indent, meta) \ + do { \ + if ((lvl) <= kNAND_NVRAM_LOG_LEVEL) \ + _dump_meta(nv, lvl, indent, meta); \ + } while (0) + +#define dump_data(nv, lvl, indent, data) \ + do { \ + if ((lvl) <= kNAND_NVRAM_LOG_LEVEL) \ + _dump_data(nv, lvl, indent, data); \ + } while (0) + +#define dump_blob(nv, lvl, indent, blob, page_count) \ + do { \ + if ((lvl) <= kNAND_NVRAM_LOG_LEVEL) \ + _dump_blob(nv, lvl, indent, blob, page_count); \ + } while (0) + +#define dump_nvram(nv, lvl, indent) \ + do { \ + if ((lvl) <= kNAND_NVRAM_LOG_LEVEL) \ + _dump_nvram(nv, lvl, indent); \ + } while (0) + +#endif + +/* ========================================================================== */ + +bool +nand_nvram_open(nand_nvram_t ** nvram, void * context, nand_nvram_geometry_t * geometry, uint32_t size) +{ + bool ret = true; + bool is_opened = false; + + const uint32_t watermarks_size = geometry->number_of_banks * geometry->blocks_per_bank * sizeof(int32_t); + const uint32_t cursors_size = geometry->number_of_banks * sizeof(uint32_t); + const uint32_t copies_size = geometry->number_of_banks * sizeof(bool); + + nand_nvram_t * nv; + + if (NULL == (nv = (nand_nvram_t *) nand_nvram_alloc_mem(context, sizeof(nand_nvram_t)))) { + + ret = false; + + } else { + + *nvram = nv; + + set_mem(nv, nv, 0, sizeof(nand_nvram_t)); + + nv->context = context; + nv->size = size; + nv->is_dirty = false; + nv->is_born = false; + copy_mem(nv, &nv->geo, geometry, sizeof(nand_nvram_geometry_t)); + + if (sizeof(meta_t) > geometry->bytes_per_meta_actual) { + + nand_nvram_fail(nv, ret); + + } else if (size > (geometry->data_pages_per_block * geometry->bytes_per_page)) { + + nand_nvram_fail(nv, ret); + + } else if (NULL == (nv->watermarks = (uint32_t *) alloc_mem(nv, watermarks_size))) { + + nand_nvram_fail(nv, ret); + + } else if (NULL == (nv->cursors = (uint32_t *) alloc_mem(nv, cursors_size))) { + + nand_nvram_fail(nv, ret); + + } else if (NULL == (nv->copies = (bool *) alloc_mem(nv, copies_size))) { + + nand_nvram_fail(nv, ret); + + } else if (!alloc_blob(nv, &nv->shadow, calc_page_count_from_size(nv, size))) { + + nand_nvram_fail(nv, ret); + + } else { + + uint32_t bank; + uint32_t block; + + for (bank = 0; bank < geometry->number_of_banks; bank++) { + for (block = 0; block < geometry->blocks_per_bank; block++) { + clear_watermark(nv, bank, block); + } + } + + set_mem(nv, nv->cursors, 0, cursors_size); + set_mem(nv, nv->copies, 0, copies_size); + is_opened = true; + } + } + + if (!is_opened) { + + nand_nvram_close(nvram); + + } else { + + dump_nvram(nv, LOG_LEVEL_SPEW, 0); + } + + return (ret); +} + +bool +nand_nvram_read(nand_nvram_t * nv, uint32_t offset, uint8_t * buffer, uint32_t length) +{ + bool ret = true; + const uint32_t extent = offset + length - 1; + + /* + * Bounds check the parameters, and make certain that the blob + * has been correctly restored from nand to shadow memory. + */ + if ((buffer == NULL) || + (length == 0) || + (extent >= nv->size)) { + + log_printf(nv, LOG_LEVEL_SPEW, "buffer: 0x%08X, length: %d, extent: %d\n", + (uint32_t) buffer, length, extent); + nand_nvram_fail(nv, ret); + + } else if (!restore_shadow(nv)) { + + nand_nvram_fail(nv, ret); + + } else { + + /* Then, copy data to buffer from shadow memory. */ + copy_mem(nv, buffer, nv->shadow->data_bufs + offset, length); + } + + dump_nvram(nv, LOG_LEVEL_SPEW, 0); + + return (ret); +} + +bool +nand_nvram_write(nand_nvram_t * nv, uint32_t offset, const uint8_t * buffer, uint32_t length) +{ + bool ret = true; + const uint32_t extent = offset + length - 1; + + /* + * Bounds check the parameters, and make certain that the blob + * has been correctly restored from nand to shadow memory. + */ + if ((buffer == NULL) || + (length == 0) || + (extent >= nv->size)) { + + nand_nvram_fail(nv, ret); + + } else if (!restore_shadow(nv)) { + + nand_nvram_fail(nv, ret); + + } else { + + /* Write data from buffer to shadow memory descriptor. */ + copy_mem(nv, nv->shadow->data_bufs + offset, buffer, length); + + /* Mark blob as dirty. */ + nv->is_dirty = true; + } + + dump_nvram(nv, LOG_LEVEL_SPEW, 0); + + return (ret); +} + +bool +nand_nvram_sync(nand_nvram_t * nv) +{ + bool ret = true; + + /* + * If shadow is dirty, sync current state of blob to nand, thus + * creating a new generation. + */ + if (!restore_shadow(nv)) { + + nand_nvram_fail(nv, ret); + + } else if (nv->is_dirty && !commit_shadow(nv)) { + + nand_nvram_fail(nv, ret); + + } else { + + nv->is_dirty = false; + } + + dump_nvram(nv, LOG_LEVEL_SPEW, 0); + + return (ret); +} + +const nand_nvram_geometry_t * +nand_nvram_get_geometry(nand_nvram_t * nv) +{ + return (&nv->geo); +} + +void +nand_nvram_close(nand_nvram_t ** nvram) +{ + nand_nvram_t * nv = *nvram; + + /* Free allocated memory. */ + if (NULL != nv) { + + free_blob(nv, &nv->shadow, get_blob_page_count(nv, nv->shadow)); + + if (NULL != nv->cursors) + free_mem(nv, nv->cursors, nv->geo.number_of_banks * sizeof(uint32_t)); + + free_mem(nv, nv, sizeof(nand_nvram_t)); + *nvram = NULL; + } +} + +/* ========================================================================== */ + +static bool +restore_shadow(nand_nvram_t * nv) +{ + bool ret = true; + uint32_t copy_count = 0; + uint32_t bank; + uint32_t block; + uint32_t * ancestors = NULL; + uint32_t youngest = kNAND_NVRAM_GENERATION_UNKNOWN; + + if (kNAND_NVRAM_GENERATION_UNKNOWN != get_blob_generation(nv, nv->shadow)) { + log_printf(nv, LOG_LEVEL_SPEW, "shadow already restored from nand\n"); + } else if (NULL == (ancestors = (uint32_t*)alloc_mem(nv, nv->geo.number_of_banks * sizeof(uint32_t)))) { + log_printf(nv, LOG_LEVEL_SPEW, "alloc failed\n"); + ret = false; + } else { + + log_printf(nv, LOG_LEVEL_SPEW, "restoring nvram shadow from nand\n"); + + for (bank = 0; bank < nv->geo.number_of_banks; bank++) { + ancestors[bank] = kNAND_NVRAM_GENERATION_UNKNOWN; + for (block = 0; block < nv->geo.blocks_per_bank; block++) { + if (!is_block_bad(nv, bank, block) && !is_block_closed(nv, bank, block)) { + find_youngest(nv, bank, block, &ancestors[bank], &youngest); + } + } + } + + if (kNAND_NVRAM_GENERATION_UNKNOWN != youngest) { + + const uint8_t version_minor = get_blob_page_meta(nv, nv->shadow, 0)->version_minor; + const uint32_t page_count = get_blob_page_count(nv, nv->shadow); + + nv->is_born = true; + + /* Ensure that a new generation is created if restored generation is + * from an older minor revision of driver. + */ + if (kNAND_NVRAM_VERSION_MINOR > version_minor) { + nv->is_dirty = true; + } else { + nv->is_dirty = false; + } + + if (kNAND_NVRAM_FEATURE_EXTRA_AREA_VERSION_MINOR <= version_minor) { + + const uint32_t extra_offset = calc_extra_offset(nv); + const uint32_t extra_size = calc_extra_size(nv); + const uint32_t last_page_in_blob = page_count - 1; + uint8_t * last_page_data = get_blob_page_data(nv, nv->shadow, last_page_in_blob); + uint8_t * extra_data = last_page_data + extra_offset; + + log_printf(nv, LOG_LEVEL_SPEW, + "providing partition table differences stored in extra area of current generation"); + + if (!provide_ptab_diff(nv, extra_data, extra_size)) { + log_printf(nv, LOG_LEVEL_ERROR, + "failed attempt to provide %d bytes stored in " + "extra area at end of page %d in blob\n", + extra_size, last_page_in_blob); + dump_data(nv, LOG_LEVEL_WARN, 1, last_page_data); + } else { + // change log level to watch this happening during debug + dump_data(nv, LOG_LEVEL_SPEW, 1, last_page_data); + } + } + + for (bank = 0; bank < nv->geo.number_of_banks; bank++) { + + const bool is_youngest = (ancestors[bank] == youngest); + + log_printf(nv, LOG_LEVEL_WARN, + "%s generation %d @ %dp0x%06X\n", + (is_youngest ? "current" : "prior"), + ancestors[bank], + bank, + nv->cursors[bank] - page_count); + + if (ancestors[bank] == youngest) { + nv->copies[bank] = true; + copy_count++; + } + + if (kNAND_NVRAM_GENERATION_UNKNOWN == ancestors[bank]) { + log_printf(nv, LOG_LEVEL_SPEW, + "no valid generation found for bank %d\n", + bank); + } + } + + log_printf(nv, LOG_LEVEL_SPEW, + "restored %d copies of nvram v%d.%d, generation %d, from nand\n", + copy_count, + get_blob_page_meta(nv, nv->shadow, 0)->version_major, + get_blob_page_meta(nv, nv->shadow, 0)->version_minor, + get_blob_generation(nv, nv->shadow)); + dump_nvram(nv, LOG_LEVEL_SPEW, 0); + + } else { + + nv->is_dirty = true; + nv->is_born = false; + log_printf(nv, LOG_LEVEL_SPEW, "nand nvram doesn't yet have any generations\n"); + } + free_mem(nv, ancestors, nv->geo.number_of_banks * sizeof(uint32_t)); + } + + return (ret); +} + +static bool +read_blob(nand_nvram_t * nv, blob_t * blob, uint32_t bank, uint32_t block, uint32_t base, uint32_t offset) +{ + bool is_read = true; + uint32_t idx; + uint8_t * data; + meta_t * meta; + bool is_clean; + + for (idx = 0; idx < get_blob_page_count(nv, blob); idx++) { + + const int32_t page_in_block = offset + idx; + const uint32_t page = base + page_in_block; + + data = get_blob_page_data(nv, blob, idx); + meta = get_blob_page_meta(nv, blob, idx); + + // if any page in blob could not be read or failed + // validation, blob is considered unreadable + if (!read_page(nv, bank, page, data, meta, &is_clean) || + !validate_meta(nv, meta, idx)) { + + is_read = false; + break; + } + } + + return (is_read); +} + +/* ========================================================================== */ + +static bool +commit_shadow(nand_nvram_t * nv) +{ + bool ret = true; + uint32_t commit_count = 0; + blob_t * scratch = NULL; + bool is_newborn = !nv->is_born; + uint32_t bank; + + /* + * Allocate temporary blob for readback verification during + * commit. Note that we only ever need temporary storage for + * one page at a time during commit, so there is no need to + * allocate anything larger. + */ + if (is_newborn && !beget_newborn(nv)) { + + nand_nvram_fail(nv, ret); + + } else if (!alloc_blob(nv, &scratch, 1)) { + + nand_nvram_fail(nv, ret); + + } else { + + /* Migrate forward from previous minor version, if necessary. */ + migrate_forward(nv); + + /* Whether virgin or not, increment nvram generation once for every commit. */ + increment_generation(nv); + + /* + * Commit pages of blob to each bank, recording whether any + * bank was able to commit. + */ + for (bank = 0; bank < nv->geo.number_of_banks; bank++) { + + if (commit_to_bank(nv, bank, scratch)) { + + commit_count++; + } + } + + /* Free temporary blob. */ + free_blob(nv, &scratch, 1); + + /* Fail if we were unable to commit the blob to any bank. */ + if (0 == commit_count) { + + nand_nvram_fail(nv, ret); + + } else { + + log_printf(nv, LOG_LEVEL_SPEW, + "committed %d copies of nvram generation %d\n", + commit_count, get_blob_generation(nv, nv->shadow)); + } + } + + return (ret); +} + +static bool +commit_to_bank(nand_nvram_t * nv, uint32_t bank, blob_t * scratch) +{ + const uint32_t blob_page_count = get_blob_page_count(nv, nv->shadow); + bool is_committed = false; + uint32_t attempts = 0; + const uint32_t start_page = nv->cursors[bank]; + uint32_t block = calc_block_from_page(nv, start_page); + uint32_t page_in_block = calc_page_in_block_from_page(nv, start_page); + uint32_t watermark; + + while (!is_committed && (attempts < nv->geo.blocks_per_bank)) { + + if (is_block_bad(nv, bank, block)) { + + log_printf(nv, LOG_LEVEL_SPEW, + "block %d:%d known to be bad, skipping\n", + bank, block); + page_in_block = nv->geo.pages_per_block; + + } else if ((watermark = get_watermark(nv, bank, block)) != page_in_block) { + + const uint32_t extra = (watermark % blob_page_count); + if ((0 != extra) && (watermark < nv->geo.data_pages_per_block)) { + + // address case where prior commit left partial + // generation (e.g. due to power loss) + const uint32_t missing = (blob_page_count - extra); + log_printf(nv, LOG_LEVEL_INFO, + "prior commit left unaligned watermark at %d:%d:%d\n", + bank, block, watermark); + fill_pages_with_ptab(nv, bank, block, watermark, missing); + watermark = get_watermark(nv, bank, block); + } + + if (page_in_block < watermark) { + + // address case where youngest generation in block has + // written pages after it (e.g. due to corrupted generation + // or after filling partial generation above) + log_printf(nv, LOG_LEVEL_INFO, + "skipping %d pages, %d:%d:%d-%d\n", + watermark - page_in_block, bank, block, page_in_block, watermark - 1); + page_in_block = watermark; + + } else if (page_in_block > watermark) { + + log_printf(nv, LOG_LEVEL_ERROR, + "ERROR: in bank %d, page_in_block > watermark (%d > %d)\n", + bank, page_in_block, watermark); + dump_nvram(nv, LOG_LEVEL_SPEW, 0); + goto out; + } + } + + if ((page_in_block + blob_page_count) > nv->geo.data_pages_per_block) { + if (!prepare_next_commit_block(nv, bank, &block, &attempts)) { + log_printf(nv, LOG_LEVEL_SPEW, + "unable to prepare any block for bank %d\n", bank); + break; + } else { + page_in_block = 0; + } + } + + if (commit_to_block_in_bank(nv, bank, block, page_in_block, scratch)) { + is_committed = true; + } else { + log_printf(nv, LOG_LEVEL_SPEW, + "unable to commit: bank %d, block 0x%08X, page_in_block %d\n", + bank, block, page_in_block); + } + } + +out: + return (is_committed); +} + +static bool +prepare_next_commit_block(nand_nvram_t * nv, uint32_t bank, uint32_t * block, uint32_t *attempts) +{ + bool is_prepared = false; + + /* Start trying at the next block. */ + bool may_close_this; + bool may_close_next = true; + uint32_t this_block = *block; + uint32_t next_block = 0; + uint32_t total_attempts = *attempts; + + while (!is_prepared && (total_attempts < nv->geo.blocks_per_bank)) { + + may_close_this = may_close_next; + next_block = this_block + 1; + + if (next_block >= nv->geo.blocks_per_bank) { + + next_block = 0; + log_printf(nv, LOG_LEVEL_SPEW, + "rolling around to block 0 of bank %d\n", bank); + + } + + if (is_block_bad(nv, bank, next_block)) { + + may_close_next = false; + log_printf(nv, LOG_LEVEL_SPEW, + "block %d of bank %d known to be bad, skipping\n", + next_block, bank); + + } else { + + may_close_next = true; + + if (erase_block(nv, bank, next_block)) { + + is_prepared = true; + log_printf(nv, LOG_LEVEL_SPEW, + "erased block %d of bank %d in preparation for commit\n", + next_block, bank); + + } else { + + log_printf(nv, LOG_LEVEL_SPEW, + "unable to erase block %d of bank %d, skipping\n", + next_block, bank); + } + } + + if (may_close_this) { + close_block(nv, bank, this_block, nv->geo.data_pages_per_block); + } + + this_block = next_block; + total_attempts++; + } + + *block = next_block; + *attempts = total_attempts; + + return (is_prepared); +} + +static bool +commit_to_block_in_bank(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t start_page_in_block, blob_t * scratch) +{ + uint8_t * blob_data = NULL; + meta_t * blob_meta = NULL; + + uint8_t * scratch_data = get_blob_page_data(nv, scratch, 0); + meta_t * scratch_meta = get_blob_page_meta(nv, scratch, 0); + + const uint32_t page_count = get_blob_page_count(nv, nv->shadow); + const uint32_t base_page = calc_base_page_from_block(nv, block); + const uint32_t start_page = start_page_in_block + base_page; + + uint32_t page_in_blob = 0; + uint32_t pages_committed = 0; + + /* + * Write out each page of the blob, read it back, and verify + * the page read is the same as what was just written, + * accumulating a count of how many of the pages were + * successfully committed. + */ + for (page_in_blob = 0; page_in_blob < page_count; page_in_blob++) { + + const uint32_t current_page_in_block = start_page_in_block + page_in_blob; + const uint32_t page = base_page + current_page_in_block; + + blob_data = get_blob_page_data(nv, nv->shadow, page_in_blob); + blob_meta = get_blob_page_meta(nv, nv->shadow, page_in_blob); + + if ((page_count - 1) == page_in_blob) { + + /* We are at the last page of this NVRAM blob, and we will use the extra space + * to store information on behalf of the partition scheme. Currently we have more + * than enough extra space left, but we may run into problem if we change + * the size of NVRAM or page size. + */ + const uint32_t extra_offset = calc_extra_offset(nv); + const uint32_t extra_size = calc_extra_size(nv); + uint8_t * extra_data = blob_data + extra_offset; + + log_printf(nv, LOG_LEVEL_SPEW, + "requesting partition table differences to store in extra area of current generation"); + + if (!request_ptab_diff(nv, extra_data, extra_size)) { + log_printf(nv, LOG_LEVEL_ERROR, + "failed to request %d bytes to store in extra area at end of page %d in blob\n", + extra_size, page_in_blob); + dump_data(nv, LOG_LEVEL_WARN, 1, blob_data); + break; + } else { + // change log level to watch this happening during debug + dump_data(nv, LOG_LEVEL_SPEW, 1, blob_data); + } + } + + /* + * Write page from nv to nand, read back page, and + * verify contents. + */ + if (!write_page(nv, bank, page, blob_data, blob_meta)) { + + log_printf(nv, LOG_LEVEL_SPEW, + "commit failed write of page %d in blob to bank %d page 0x%08X\n", + page_in_blob, bank, page); + break; + + } else if (!read_page(nv, bank, page, scratch_data, scratch_meta, NULL)) { + + log_printf(nv, LOG_LEVEL_SPEW, + "commit failed read of page %d in blob from bank %d page 0x%08X\n", + page_in_blob, bank, page); + break; + + } else if (0 != compare_mem(nv, blob_data, scratch_data, nv->geo.bytes_per_page)) { + + log_printf(nv, LOG_LEVEL_SPEW, + "commit failed data verification of page %d in blob at bank %d page 0x%08X\n", + page_in_blob, bank, page); + log_printf(nv, LOG_LEVEL_SPEW, "blob_data:\n"); + dump_data(nv, LOG_LEVEL_SPEW, 1, blob_data); + log_printf(nv, LOG_LEVEL_SPEW, "scratch_data:\n"); + dump_data(nv, LOG_LEVEL_SPEW, 1, scratch_data); + break; + + } else if (0 != compare_mem(nv, blob_meta, scratch_meta, sizeof(meta_t))) { + + log_printf(nv, LOG_LEVEL_SPEW, + "commit failed meta verification of page %d in blob at bank %d page 0x%08X\n", + page_in_blob, bank, page); + log_printf(nv, LOG_LEVEL_SPEW, "blob_meta:\n"); + dump_meta(nv, LOG_LEVEL_SPEW, 1, blob_meta); + log_printf(nv, LOG_LEVEL_SPEW, "scratch_meta:\n"); + dump_meta(nv, LOG_LEVEL_SPEW, 1, scratch_meta); + break; + + } else { + + /* + * If write, read, and verifications all + * succeeded, increment commit counter. + */ + pages_committed++; + } + } + + /* Update page number of commit cursor for this bank whether or + * not commit actually succeeded. + */ + nv->cursors[bank] = start_page + page_count; + + /* + * If all pages in blob were successfully committed, record + * the page number of the new new commit index for this bank, + * and return true to indicate that the commit succeeded. + */ + if (pages_committed == page_count) { + return (true); + } + return (false); +} + +static void +increment_generation(nand_nvram_t * nv) +{ + if ((NULL != nv->shadow) && (NULL != nv->shadow->meta_bufs)) { + + uint32_t page; + meta_t * meta = get_blob_page_meta(nv, nv->shadow, 0); + uint32_t next_gen = 1 + meta->generation; + + if (kNAND_NVRAM_GENERATION_ERASED == next_gen) { + next_gen = 1; + } + for (page = 0; page < get_blob_page_count(nv, nv->shadow); page++) { + meta = get_blob_page_meta(nv, nv->shadow, page); + meta->generation = next_gen; + meta->version_minor = kNAND_NVRAM_VERSION_MINOR; + } + } +} + +/* ========================================================================== */ + +static void +init_meta(nand_nvram_t * nv, meta_t * meta, uint32_t generation, uint32_t page_count, uint32_t page_idx) +{ + meta->signature = kNAND_NVRAM_SIGNATURE; + meta->version_major = kNAND_NVRAM_VERSION_MAJOR; + meta->version_minor = kNAND_NVRAM_VERSION_MINOR; + meta->generation = generation; + meta->page_max = (uint8_t)(page_count - 1); + meta->page_idx = (uint8_t)page_idx; +} + +static bool +validate_meta(nand_nvram_t * nv, meta_t * meta, uint32_t idx) +{ + return ((meta->signature == kNAND_NVRAM_SIGNATURE) && + (meta->version_major == kNAND_NVRAM_VERSION_MAJOR) && + (meta->generation != kNAND_NVRAM_GENERATION_UNKNOWN) && + (meta->generation != kNAND_NVRAM_GENERATION_ERASED) && + (meta->page_max == (calc_page_count_from_size(nv, nv->size)) - 1) && + (meta->page_idx <= meta->page_max) && + (meta->page_idx == idx)); +} + +/* ========================================================================== */ + +static uint32_t +calc_block_from_page(nand_nvram_t * nv, uint32_t page_num) +{ + /* XXX bounds check page_num */ + return (page_num / nv->geo.pages_per_block); +} + +static uint32_t +calc_page_in_block_from_page(nand_nvram_t * nv, uint32_t page_num) +{ + /* XXX bounds check page_num */ + return (page_num % nv->geo.pages_per_block); +} + +static uint32_t +calc_base_page_from_block(nand_nvram_t * nv, uint32_t block_num) +{ + /* XXX bounds check block_num */ + return (block_num * nv->geo.pages_per_block); +} + +static uint32_t +calc_page_count_from_size(nand_nvram_t * nv, uint32_t size) +{ + uint32_t remainder = ((0 != (size % nv->geo.bytes_per_page)) ? 1 : 0); + return ((size / nv->geo.bytes_per_page) + remainder); +} + +static uint32_t +calc_extra_offset(nand_nvram_t * nv) +{ + return (nv->size % nv->geo.bytes_per_page); +} + +static uint32_t +calc_extra_size(nand_nvram_t * nv) +{ + return (nv->geo.bytes_per_page - calc_extra_offset(nv)); +} + +/* ========================================================================== */ + +static uint32_t +get_blob_generation(nand_nvram_t * nv, blob_t * blob) +{ + if ((NULL != blob) && (NULL != blob->meta_bufs)) { + + return (get_blob_page_meta(nv, blob, 0)->generation); + } + + return kNAND_NVRAM_GENERATION_UNKNOWN; +} + +static uint32_t +get_blob_page_count(nand_nvram_t * nv, blob_t * blob) +{ + return calc_page_count_from_size(nv, nv->size); +} + +static uint8_t * +get_blob_page_data(nand_nvram_t * nv, blob_t * blob, uint32_t page_index) +{ + /* XXX assert bounds check on page_index and buf ptr */ + + uint8_t * bytes = (uint8_t *)blob->data_bufs; + return ((uint8_t*)&bytes[page_index * nv->geo.bytes_per_page]); +} + +static meta_t * +get_blob_page_meta(nand_nvram_t * nv, blob_t * blob, uint32_t page_index) +{ + /* XXX assert bounds check on page_index and buf ptr */ + + uint8_t * bytes = (uint8_t *)blob->meta_bufs; + return ((meta_t *)&bytes[page_index * nv->geo.bytes_per_meta_buffer]); +} + +static bool +alloc_blob(nand_nvram_t * nv, blob_t ** blob_ref, uint32_t page_count) +{ + bool ret = true; + + blob_t * blob = NULL; + void * new_data = NULL; + void * new_meta = NULL; + uint32_t old_page_count = 0; + bool is_realloc; + + /* Allocate shell to hold buffers, if necessary. */ + if (NULL == *blob_ref) { + + if (NULL == (*blob_ref = (blob_t *) alloc_mem(nv, sizeof(blob_t)))) { + + nand_nvram_fail(nv, ret); + return (ret); + } + + set_mem(nv, *blob_ref, 0, sizeof(blob_t)); + + /* + * If this is a zero-length alloc (i.e. nv + * initialization), we're done. + */ + if (page_count == 0) + return (ret); + + } else { + old_page_count = get_blob_page_count(nv, *blob_ref); + } + + blob = *blob_ref; + is_realloc = (old_page_count != 0); + + /* Make certain that this isn't an improper reallocation. */ + if (is_realloc && (old_page_count > page_count)) { + + log_printf(nv, LOG_LEVEL_SPEW, + "attempted invalid realloc from %d pages to %d pages\n", + old_page_count, page_count); + nand_nvram_fail(nv, ret); + + } else if (is_realloc && (old_page_count == page_count)) { + + log_printf(nv, LOG_LEVEL_SPEW, + "unnecessary realloc from %d pages same number of pages\n", + old_page_count); + + } else if (!alloc_page_bufs(nv, page_count, &new_meta, &new_data)) { + + free_blob(nv, blob_ref, page_count); + nand_nvram_fail(nv, ret); + + } else if (0 != page_count) { + + const uint32_t old_data_size = old_page_count * nv->geo.bytes_per_page; + const uint32_t new_data_size = page_count * nv->geo.bytes_per_page; + const uint32_t delta_data_size = new_data_size - old_data_size; + + uint32_t generation = kNAND_NVRAM_GENERATION_UNKNOWN; + uint32_t page; + + if (is_realloc) { + + /* Copy old contents of blob to newly allocated buffers. */ + copy_mem(nv, new_data, blob->data_bufs, old_data_size); + + /* Record old blob generation. */ + generation = get_blob_generation(nv, blob); + + /* Free old data and meta buffers. */ + free_page_bufs(nv, old_page_count, &blob->meta_bufs, &blob->data_bufs); + } + + /* Zero new pages of data buffers. */ + set_mem(nv, ((uint8_t *) new_data) + old_data_size, 0, delta_data_size); + + /* Record pointers to new buffers. */ + blob->data_bufs = new_data; + blob->meta_bufs = new_meta; + + /* Init pages of meta buffers. */ + for (page = 0; page < page_count; page++) { + + meta_t * meta = get_blob_page_meta(nv, blob, page); + init_meta(nv, meta, generation, page_count, page); + } + } + + return (ret); +} + +static void +free_blob(nand_nvram_t * nv, blob_t ** blob_ref, uint32_t page_count) +{ + blob_t * blob = *blob_ref; + + if (NULL != blob) { + + free_page_bufs(nv, page_count, &blob->meta_bufs, &blob->data_bufs); + free_mem(nv, blob, sizeof(blob_t)); + *blob_ref = NULL; + + } else { + + /* XXX warn that we tried to free an unallocated blob */ + } +} + +/* ========================================================================== */ + +static bool +alloc_page_bufs(nand_nvram_t * nv, uint32_t page_count, void ** meta_bufs_ref, void ** data_bufs_ref) +{ + const uint32_t meta_bufs_size = page_count * nv->geo.bytes_per_meta_buffer; + const uint32_t data_bufs_size = page_count * nv->geo.bytes_per_page; + void * new_meta_bufs = NULL; + void * new_data_bufs = NULL; + + /* XXX assert not already allocated */ + + if ((NULL == (new_data_bufs = alloc_mem(nv, data_bufs_size))) || + (NULL == (new_meta_bufs = alloc_mem(nv, meta_bufs_size)))) { + + /* Free buffers if not able to allocate both of them, then fail. */ + free_page_bufs(nv, page_count, &new_meta_bufs, &new_data_bufs); + return (false); + } + + *meta_bufs_ref = new_meta_bufs; + *data_bufs_ref = new_data_bufs; + + return (true); +} + +static void +free_page_bufs(nand_nvram_t * nv, uint32_t page_count, void ** meta_bufs_ref, void ** data_bufs_ref) +{ + if (NULL != *data_bufs_ref) { + + free_mem(nv, *data_bufs_ref, page_count * nv->geo.bytes_per_page); + *data_bufs_ref = NULL; + } + + if (NULL != *meta_bufs_ref) { + + free_mem(nv, *meta_bufs_ref, page_count * nv->geo.bytes_per_meta_buffer); + *meta_bufs_ref = NULL; + } +} + +/* ========================================================================== */ + +static uint32_t +calc_watermark_index(nand_nvram_t * nv, uint32_t bank, uint32_t block) +{ + return ((nv->geo.blocks_per_bank * bank) + block); +} + +static uint32_t +get_watermark(nand_nvram_t * nv, uint32_t bank, uint32_t block) +{ + return(nv->watermarks[calc_watermark_index(nv, bank, block)]); +} + +static void +update_watermark(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t new_watermark) +{ + const uint32_t idx = calc_watermark_index(nv, bank, block); + const uint32_t old_watermark = nv->watermarks[idx]; + if (new_watermark > old_watermark) { + nv->watermarks[idx] = new_watermark; + } +} + +static void +clear_watermark(nand_nvram_t * nv, uint32_t bank, uint32_t block) +{ + nv->watermarks[calc_watermark_index(nv, bank, block)] = 0; +} + +/* ========================================================================== */ + +static inline void * +alloc_mem(nand_nvram_t * nv, uint32_t size) +{ + return ((void *) nand_nvram_alloc_mem(nv->context, size)); +} + +static inline signed +compare_mem(nand_nvram_t * nv, void * left, void * right, uint32_t size) +{ + return (nand_nvram_compare_mem(nv->context, left, right, size)); +} + +static inline void +copy_mem(nand_nvram_t * nv, void * dest, const void * src, uint32_t size) +{ + nand_nvram_copy_mem(nv->context, dest, src, size); +} + +static inline void +set_mem(nand_nvram_t * nv, void * mem, uint8_t value, uint32_t size) +{ + nand_nvram_set_mem(nv->context, mem, value, size); +} + +static inline void +free_mem(nand_nvram_t * nv, void * mem, uint32_t size) +{ + nand_nvram_free_mem(nv->context, mem, size); +} + +static inline bool +is_block_bad(nand_nvram_t * nv, uint32_t bank, uint32_t block) +{ + return (nand_nvram_is_block_bad(nv->context, bank, block)); +} + +static inline bool +read_page(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * data, void * meta, bool * is_clean) +{ + bool ok = nand_nvram_read_page(nv->context, bank, page, data, meta, is_clean); + + // if page read succeeds or is not clean, when clean checking + // is enabled, update block watermark + if (ok || ((NULL != is_clean) && !*is_clean)) { + + const uint32_t block = calc_block_from_page(nv, page); + const uint32_t page_in_block = calc_page_in_block_from_page(nv, page); + + update_watermark(nv, bank, block, page_in_block + 1); + } + + return (ok); +} + +static inline bool +write_page(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * data, void * meta) +{ + const uint32_t block = calc_block_from_page(nv, page); + const uint32_t page_in_block = calc_page_in_block_from_page(nv, page); + + update_watermark(nv, bank, block, page_in_block + 1); + + return (nand_nvram_write_page(nv->context, bank, page, data, meta)); +} + +static inline bool +request_ptab_diff(nand_nvram_t * nv, void * data, uint32_t size) +{ + return (nand_nvram_request_ptab_diff(nv->context, data, size)); +} + +static inline bool +provide_ptab_diff(nand_nvram_t * nv, void * data, uint32_t size) +{ + return (nand_nvram_provide_ptab_diff(nv->context, data, size)); +} + +static inline bool +erase_block(nand_nvram_t * nv, uint32_t bank, uint32_t block) +{ + clear_watermark(nv, bank, block); + return (nand_nvram_erase_block(nv->context, bank, block)); +} + +static inline bool +copy_ptab(nand_nvram_t * nv, void * buf) +{ + return (nand_nvram_copy_ptab(nv->context, buf)); +} + +static inline bool +read_ptab(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * buf) +{ + bool ok = nand_nvram_read_ptab(nv->context, bank, page, buf); + + // if ptab read succeeds, update block watermark + if (ok) { + + const uint32_t block = calc_block_from_page(nv, page); + const uint32_t page_in_block = calc_page_in_block_from_page(nv, page); + + update_watermark(nv, bank, block, page_in_block + 1); + } + + return (ok); +} + +static inline bool +write_ptab(nand_nvram_t * nv, uint32_t bank, uint32_t page, void * buf) +{ + const uint32_t block = calc_block_from_page(nv, page); + const uint32_t page_in_block = calc_page_in_block_from_page(nv, page); + + update_watermark(nv, bank, block, page_in_block + 1); + + return (nand_nvram_write_ptab(nv->context, bank, page, buf)); +} + +/* ========================================================================== */ + +#if !kNAND_NVRAM_MUTE + +static void +_dump_geometry(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, nand_nvram_geometry_t * geo) +{ + dump(nv, lvl, indent, "%-20s%d\n", "number_of_banks:", geo->number_of_banks); + dump(nv, lvl, indent, "%-20s%d\n", "blocks_per_bank:", geo->blocks_per_bank); + dump(nv, lvl, indent, "%-20s%d\n", "pages_per_block:", geo->pages_per_block); + dump(nv, lvl, indent, "%-20s%d\n", "data_pages_per_block:", geo->data_pages_per_block); + dump(nv, lvl, indent, "%-20s%d\n", "bytes_per_page:", geo->bytes_per_page); +} + +static void +_dump_meta(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, meta_t * meta) +{ + dump(nv, lvl, indent, "%-20s0x%04X\n", "signature:", meta->signature); + dump(nv, lvl, indent, "%-20s%d\n", "version_major:", meta->version_major); + dump(nv, lvl, indent, "%-20s%d\n", "version_minor:", meta->version_minor); + dump(nv, lvl, indent, "%-20s%d\n", "generation:", meta->generation); + dump(nv, lvl, indent, "%-20s%d\n", "page_max:", meta->page_max); + dump(nv, lvl, indent, "%-20s%d\n", "page_idx:", meta->page_idx); +} + +#define _isprint(c) (((c) > 32) && ((c) < 127)) + +static void +_dump_data(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, uint8_t * data) +{ + char ascii[17] = {0}; + uint32_t idx; + + for (idx = 0; idx < nv->geo.bytes_per_page; idx++) { + uint32_t col = idx % 16; + if (0 == col) + dump(nv, lvl, indent, "%04X", idx); + dump(nv, lvl, 0, " %02X", data[idx]); + ascii[col] = (_isprint(data[idx]) ? (char) data[idx] : '.'); + if (15 == idx % 16) + dump(nv, lvl, 0, " %s\n", ascii); + } + + if (0 != idx % 16) { + ascii[idx % 16] = 0; + for (; 0 != idx % 16; idx++) + dump(nv, lvl, 0, " "); + dump(nv, lvl, 0, " %s\n", ascii); + } +} + +static void +_dump_blob(nand_nvram_t * nv, uint32_t lvl, uint32_t indent, blob_t * blob, uint32_t page_count) +{ + uint32_t idx; + + dump(nv, lvl, indent, "%-20s0x%08X\n", "meta_bufs:" , (uint32_t) blob->meta_bufs); + + for (idx = 0; idx < page_count; idx++) { + dump(nv, lvl, indent, "meta_bufs[%d]\n", idx); + _dump_meta(nv, lvl, indent + 1, get_blob_page_meta(nv, blob, idx)); + } + + dump(nv, lvl, indent, "%-20s0x%08X\n", "data_bufs:" , (uint32_t) blob->data_bufs); + + for (idx = 0; idx < page_count; idx++) { + dump(nv, lvl, indent, "data_bufs[%d]\n", idx); + _dump_data(nv, lvl, indent + 1, get_blob_page_data(nv, nv->shadow, idx)); + } +} + +static void +_dump_nvram(nand_nvram_t * nv, uint32_t lvl, uint32_t indent) +{ + unsigned idx; + + dump(nv, lvl, indent, "geo:\n"); + _dump_geometry(nv, lvl, indent + 1, &nv->geo); + + dump(nv, lvl, indent, "%-20s0x%08X\n", "context:", (uint32_t)nv->context); + dump(nv, lvl, indent, "%-20s%d\n", "size:", nv->size); + dump(nv, lvl, indent, "%-20s%s\n", "is_born:", nv->is_born ? "true" : "false"); + dump(nv, lvl, indent, "%-20s%s\n", "is_dirty:", nv->is_dirty ? "true" : "false"); + + dump(nv, lvl, indent, "%-20s*0x%08X = {0x%08X", + "watermarks:", (uint32_t)nv->watermarks, nv->watermarks[0]); + for (idx = 1; idx < (nv->geo.number_of_banks * nv->geo.blocks_per_bank); idx++) + dump(nv, lvl, 0, ", 0x%08X", nv->watermarks[idx]); + dump(nv, lvl, 0, "}\n"); + + dump(nv, lvl, indent, "%-20s*0x%08X = {0x%08X", + "cursors:", (uint32_t)nv->cursors, nv->cursors[0]); + for (idx = 1; idx < nv->geo.number_of_banks; idx++) + dump(nv, lvl, 0, ", 0x%08X", nv->cursors[idx]); + dump(nv, lvl, 0, "}\n"); + + dump(nv, lvl, indent, "%-20s*0x%08X = {%s", + "copies:", (uint32_t)nv->copies, nv->copies[0] ? "true" : "false"); + for (idx = 1; idx < nv->geo.number_of_banks; idx++) + dump(nv, lvl, 0, ", %s", nv->copies[idx] ? "true" : "false"); + dump(nv, lvl, 0, "}\n"); + + dump(nv, lvl, indent, "%-20s0x%08X\n", "shadow:", (uint32_t)nv->shadow); + _dump_blob(nv, lvl, indent + 1, nv->shadow, get_blob_page_count(nv, nv->shadow)); +} + +#endif /* !kNAND_NVRAM_MUTE */ + +/* ========================================================================== */ + +static bool +is_block_closed(nand_nvram_t * nv, uint32_t bank, uint32_t block) +{ + bool ok = false; + NandPartTable * ptab = NULL; + uint32_t base = ((block * nv->geo.pages_per_block) + nv->geo.data_pages_per_block); + uint32_t page; + uint32_t idx; + + if (NULL == (ptab = (NandPartTable*)alloc_mem(nv, sizeof(NandPartTable)))) { + panic("alloc failed"); + } else { + for (idx = 0; idx < kNAND_NVRAM_PAGE_RESERVED_IN_BLOCK; idx++) { + page = base + idx; + if (read_ptab(nv, bank, page, ptab) && + (kNandPartHeaderMagic == ptab->header.magic)) { + ok = true; + break; + } + } + free_mem(nv, ptab, sizeof(NandPartTable)); + } + + return (ok); +} + +static bool +close_block(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t offset) +{ + const uint32_t count = (nv->geo.pages_per_block - offset); + log_printf(nv, LOG_LEVEL_SPEW, "closing block %d:%d\n", bank, block); + return(fill_pages_with_ptab(nv, bank, block, offset, count)); +} + +static bool +fill_pages_with_ptab(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t offset, uint32_t count) +{ + bool ok = false; + NandPartTable * ptab = NULL; + const uint32_t base = (block * nv->geo.pages_per_block); + uint32_t idx; + + if (NULL == (ptab = (NandPartTable*)alloc_mem(nv, sizeof(NandPartTable)))) { + panic("alloc failed"); + } else { + if (!copy_ptab(nv, ptab)) { + log_printf(nv, LOG_LEVEL_SPEW, "unable to copy ptab\n"); + } else { + for (idx = 0; idx < count; idx++) { + const uint32_t page_in_block = offset + idx; + const uint32_t page = base + page_in_block; + log_printf(nv, LOG_LEVEL_SPEW, + "filling page %d:%d:%d with ptab\n", + bank, block, page_in_block); + if (write_ptab(nv, bank, page, ptab)) { + ok = true; + } + } + } + free_mem(nv, ptab, sizeof(NandPartTable)); + } + + return (ok); +} + +static bool +beget_newborn(nand_nvram_t * nv) +{ + bool ok = false; + bool is_open; + uint32_t bank; + uint32_t block; + + for (bank = 0; bank < nv->geo.number_of_banks; bank++) { + is_open = false; + for (block = 0; block < nv->geo.blocks_per_bank; block++) { + if (!is_block_bad(nv, bank, block) && erase_block(nv, bank, block)) { + if (!is_open) { + nv->cursors[bank] = calc_base_page_from_block(nv, block); + is_open = true; + ok = true; + } else { + close_block(nv, bank, block, 0); + } + } + } + } + + if (ok) { + nv->is_born = true; + nv->is_dirty = true; + } + + return (ok); +} + +static void +migrate_forward(nand_nvram_t * nv) +{ + const uint8_t version_minor = get_blob_page_meta(nv, nv->shadow, 0)->version_minor; + uint32_t bank; + uint32_t block; + uint32_t open_block; + + if (version_minor < kNAND_NVRAM_VERSION_MINOR) { + for (bank = 0; bank < nv->geo.number_of_banks; bank++) { + open_block = calc_block_from_page(nv, nv->cursors[bank]); + for (block = 0; block < nv->geo.blocks_per_bank; block++) { + if ((block != open_block) && !is_block_closed(nv, bank, block)) { + if (!is_block_bad(nv, bank, block) && (erase_block(nv, bank, block))) { + close_block(nv, bank, block, 0); + } + } + } + } + } +} + +static bool +find_youngest(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t* ancestor, uint32_t* youngest) +{ + /* Strategy: + * + * Do a reverse linear scan in order to find the youngest blob + * available in this block. Because blobs must be committed + * to block in ascending order, the first good block from the + * end that can be read and that validates correctly will + * necessarily be the youngest generation blob in the block. + */ + bool ret = false; + const uint32_t increment = calc_page_count_from_size(nv, nv->size); + const uint32_t available = nv->geo.data_pages_per_block; + const uint32_t slots = (available / increment); + blob_t * scratch = NULL; + uint32_t offset = (slots * increment); + + if (!alloc_blob(nv, &scratch, increment)) { + nand_nvram_fail(nv, ret); + } else { + while (!ret && (offset != 0)) { + const uint32_t base = calc_base_page_from_block(nv, block); + offset -= increment; + if (read_blob(nv, scratch, bank, block, base, offset)) { + const uint32_t generation = get_blob_generation(nv, scratch); + log_printf(nv, LOG_LEVEL_SPEW, + "found generation %d at %dp0x%06X\n", + generation, bank, base + offset); + if (generation >= *ancestor) { + *ancestor = generation; + nv->cursors[bank] = base + offset + increment; + } + if (generation > *youngest) { + *youngest = generation; + free_blob(nv, &nv->shadow, increment); + nv->shadow = scratch; + scratch = NULL; + if (!alloc_blob(nv, &scratch, increment)) { + nand_nvram_fail(nv, ret); + } + } + ret = true; + } else { + log_printf(nv, LOG_LEVEL_SPEW, + "unable to read blob at %dp0x%06X\n", + bank, base + offset); + } + } + } + + free_blob(nv, &scratch, increment); + + return (ret); +} + +/* ========================================================================== */ diff --git a/drivers/flash_nand/boot/nvram/nand_nvram_core.h b/drivers/flash_nand/boot/nvram/nand_nvram_core.h new file mode 100644 index 0000000..8c4c355 --- /dev/null +++ b/drivers/flash_nand/boot/nvram/nand_nvram_core.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2008-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +/*! + @header nand_nvram_core + + @abstract portable core of a nand-based NVRAM device implementation + + @discussion In order to boot from nand, the NVRAM device must have an + implementation with a backing store on the nand flash device since + the traditional nor-based backing store will no longer be available. + This class implements such a device over a slice of the nand array, + using a journalled commit approach with multiple redundant copies. + + @copyright Apple Inc. + + @updated 2011-05-18 +*/ + +/* ========================================================================== */ + +#ifndef _NAND_NVRAM_CORE_H +#define _NAND_NVRAM_CORE_H + +__BEGIN_DECLS + +/* ========================================================================== */ + +/*! + @group public platform-independent interface function declarations +*/ + +/*! + @function nand_nvram_open + + @abstract Open platform-independent ram-shadowed nand nvram device. + + @param _geometry Geometry of nand device array slice for backing store. + + @result Returns bool indicating whether function succeeded. +*/ +bool nand_nvram_open(nand_nvram_t ** _nvram, void * context, nand_nvram_geometry_t * _geometry, uint32_t _size); + +/*! + @function nand_nvram_read + + @abstract Read data from the nvram device shadow. + + @param _offset Byte offset into nvram data blob. + + @param _buffer Pointer to memory buffer to read data from. + + @param _length Amount of data in bytes to read from blob. + + @result Returns bool indicating whether function succeeded. +*/ +bool nand_nvram_read(nand_nvram_t * _nvram, uint32_t _offset, uint8_t * _buffer, uint32_t _length); + +/*! + @function nand_nvram_write + + @abstract Write data to the nvram device shadow. + + @param _offset Byte offset into nvram data blob. + + @param _buffer Pointer to memory buffer to write data into. + + @param _length Amount of data in bytes to write to blob. + + @result Returns bool indicating whether function succeeded. +*/ +bool nand_nvram_write(nand_nvram_t * _nvram, uint32_t _offset, const uint8_t * _buffer, uint32_t _length); + +/*! + @function nand_nvram_sync + + @abstract Synchronize nvram device data to backing store. + + @result Returns bool indicating whether function succeeded. +*/ +bool nand_nvram_sync(nand_nvram_t * _nvram); + +/*! + @function nand_nvram_get_geometry + + @abstract Provide access to nand nvram driver's geometry information. + + @result Returns pointer to struct defining nand nvram geometry. +*/ +const nand_nvram_geometry_t * nand_nvram_get_geometry(nand_nvram_t * _nvram); + +/*! + @function nand_nvram_close + + @abstract Close platform-independent ram-shadowed nand nvram device. +*/ +void nand_nvram_close(nand_nvram_t ** _nvram); + +/* ========================================================================== */ + +__END_DECLS + +#endif /* ! _NAND_NVRAM_CORE_H */ + +/* ========================================================================== */ diff --git a/drivers/flash_nand/boot/nvram/nand_nvram_dump.c b/drivers/flash_nand/boot/nvram/nand_nvram_dump.c new file mode 100644 index 0000000..ffebb52 --- /dev/null +++ b/drivers/flash_nand/boot/nvram/nand_nvram_dump.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +#include "nand_part.h" +#include "nand_nvram_platform.h" +#include "nand_nvram_impl.h" +#include "nand_nvram_dump.h" + +/* ========================================================================== */ + +static void +dumpData(nand_nvram_t * nv, uint8_t * data) +{ + const uint32_t bytes_per_row = 16; + char alpha[bytes_per_row + 1]; + uint32_t col = 0; + uint32_t idx; + + nand_nvram_printf(nv->context, " "); + nand_nvram_set_mem(nv->context, alpha, 0x00, bytes_per_row + 1); + for (idx = 0; idx < nv->geo.bytes_per_page; idx++) { + uint8_t byte = data[idx]; + col = (idx % bytes_per_row); + if (0 == col) { + if (0 != alpha[0]) { + nand_nvram_printf(nv->context, " ", alpha); + nand_nvram_set_mem(nv->context, alpha, 0x00, bytes_per_row + 1); + } + nand_nvram_printf(nv->context, "\n "); + } + alpha[col] = ((0x20 <= byte) && (byte <= 0x7e)) ? (char) byte : '.'; + nand_nvram_printf(nv->context, "%02X ", byte); + } + if (0 != alpha[0]) { + for (idx = 0; idx < (bytes_per_row - (col + 1)); idx++) { + nand_nvram_printf(nv->context, " "); + } + nand_nvram_printf(nv->context, " ", alpha); + nand_nvram_set_mem(nv->context, alpha, 0x00, bytes_per_row + 1); + } + nand_nvram_printf(nv->context, "\n \n"); +} + +static void +dumpMeta(nand_nvram_t * nv, meta_t * meta) +{ + nand_nvram_printf(nv->context, " \n"); + nand_nvram_printf(nv->context, " 0x%08X\n", meta->generation); + nand_nvram_printf(nv->context, " 0x%02X\n", meta->page_max); + nand_nvram_printf(nv->context, " 0x%02X\n", meta->page_idx); + nand_nvram_printf(nv->context, " 0x%02X\n", meta->version_major); + nand_nvram_printf(nv->context, " 0x%02X\n", meta->version_minor); + nand_nvram_printf(nv->context, " 0x%04X\n", meta->signature); + nand_nvram_printf(nv->context, " \n"); +} + +static void +dumpPage(nand_nvram_t * nv, uint32_t bank, uint32_t block, uint32_t page, meta_t * meta, uint8_t * data) +{ + uint32_t abs_page = page + (block * nv->geo.pages_per_block); + + nand_nvram_printf(nv->context, " \n"); + nand_nvram_printf(nv->context, " %d\n", bank); + nand_nvram_printf(nv->context, " %d\n", block); + nand_nvram_printf(nv->context, " %d\n", page); + if (nand_nvram_read_page(nv->context, bank, abs_page, data, meta, NULL)) { + NandPartTable *closing = (NandPartTable*)meta; + if (kNAND_NVRAM_SIGNATURE == meta->signature) { + nand_nvram_printf(nv->context, " content\n"); + dumpMeta(nv, meta); + } else if (kNandPartHeaderMagic == closing->header.magic) { + nand_nvram_printf(nv->context, " closing\n"); + } else { + nand_nvram_printf(nv->context, " unrecognized\n"); + } + dumpData(nv, data); + } else { + nand_nvram_printf(nv->context, " unreadable\n"); + } + nand_nvram_printf(nv->context, " \n"); +} + +static void +dumpBlock(nand_nvram_t * nv, uint32_t bank, uint32_t block, meta_t * meta, uint8_t * data) +{ + uint32_t page; + + nand_nvram_printf(nv->context, " \n"); + nand_nvram_printf(nv->context, " %d\n", bank); + nand_nvram_printf(nv->context, " %d\n", block); + if (nand_nvram_is_block_bad(nv->context, bank, block)) { + nand_nvram_printf(nv->context, " \n"); + } else { + for (page = 0; page < nv->geo.pages_per_block; page++) + { + dumpPage(nv, bank, block, page, meta, data); + } + } + nand_nvram_printf(nv->context, " \n"); +} + +static void +dumpBank(nand_nvram_t * nv, uint32_t bank, meta_t * meta, uint8_t * data) +{ + uint32_t block; + + nand_nvram_printf(nv->context, " \n"); + nand_nvram_printf(nv->context, " %d\n", bank); + for (block = 0; block < nv->geo.blocks_per_bank; block++) + { + dumpBlock(nv, bank, block, meta, data); + } + nand_nvram_printf(nv->context, " \n"); +} + +static void +dumpGeometry(nand_nvram_t * nv) +{ + nand_nvram_printf(nv->context, " \n"); + nand_nvram_printf(nv->context, " %d\n", nv->geo.number_of_banks); + nand_nvram_printf(nv->context, " %d\n", nv->geo.blocks_per_bank); + nand_nvram_printf(nv->context, " %d\n", nv->geo.pages_per_block); + nand_nvram_printf(nv->context, " %d\n", nv->geo.data_pages_per_block); + nand_nvram_printf(nv->context, " %d\n", nv->geo.bytes_per_page); + nand_nvram_printf(nv->context, " %d\n", nv->geo.bytes_per_meta_buffer); + nand_nvram_printf(nv->context, " %d\n", nv->geo.bytes_per_meta_actual); + nand_nvram_printf(nv->context, " \n"); +} + +bool +nand_nvram_dump(nand_nvram_t * nv) +{ + bool ok = false; + uint32_t bank; + meta_t * meta = NULL; + uint8_t * data = NULL; + + if ((NULL != nv) && + (NULL != nv->context) && + (NULL != (meta = nand_nvram_alloc_mem(nv->context, nv->geo.bytes_per_meta_buffer))) && + (NULL != (data = nand_nvram_alloc_mem(nv->context, nv->geo.bytes_per_page)))) { + + nand_nvram_printf(nv->context, "\n"); + dumpGeometry(nv); + for (bank = 0; bank < nv->geo.number_of_banks; bank++) + { + dumpBank(nv, bank, meta, data); + } + nand_nvram_printf(nv->context, "\n"); + ok = true; + } + + if (NULL != meta) { + nand_nvram_free_mem(nv->context, meta, nv->geo.bytes_per_meta_buffer); + } + if (NULL != data) { + nand_nvram_free_mem(nv->context, data, nv->geo.bytes_per_page); + } + + return (ok); +} + +/* ========================================================================== */ diff --git a/drivers/flash_nand/boot/nvram/nand_nvram_dump.h b/drivers/flash_nand/boot/nvram/nand_nvram_dump.h new file mode 100644 index 0000000..b34a8ab --- /dev/null +++ b/drivers/flash_nand/boot/nvram/nand_nvram_dump.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _NAND_NVRAM_DUMP_H_ +#define _NAND_NVRAM_DUMP_H_ + +__BEGIN_DECLS + +bool nand_nvram_dump(nand_nvram_t * nv); + +__END_DECLS + +#endif // _NAND_NVRAM_DUMP_H_ diff --git a/drivers/flash_nand/boot/nvram/nand_nvram_impl.h b/drivers/flash_nand/boot/nvram/nand_nvram_impl.h new file mode 100644 index 0000000..02f6a61 --- /dev/null +++ b/drivers/flash_nand/boot/nvram/nand_nvram_impl.h @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +/*! + @header nand_nvram_impl + + @abstract portable header info for nand nvram implementation use only + + @discussion These declarations have been pulled out into an + independent file so that diagnostic utilities and white box unit + tests might take advantage of knowing implementation-specific + details. Nevertheless, no client of the nand nvram driver nor its + system-specific wrapper should ever need to reference this header. + Any declarations that need that level of visibility are intended to + be placed in "nand_nvram_core.h". + + @copyright Apple Inc. + + @updated 2012-02-21 +*/ + +/* ========================================================================== */ + +#ifndef _NAND_NVRAM_IMPL_H +#define _NAND_NVRAM_IMPL_H + +__BEGIN_DECLS + +/* ========================================================================== */ + +/*! + @group public platform-independent type declarations +*/ + +/*! + @typedef nand_nvram_t + + @abstract Opaque reference to structure needed by nand nvram implementation. +*/ +typedef struct nand_nvram nand_nvram_t; + +/*! + @typedef nand_nvram_geometry_t + + @abstract +*/ +typedef struct nand_nvram_geometry nand_nvram_geometry_t; + +/* ========================================================================== */ + +/*! + @group private platform-independent type declarations +*/ + +typedef struct _meta meta_t; +typedef struct _blob blob_t; + +/* ========================================================================== */ + +/*! + @group public platform-independent constant definitions +*/ + +/*! + @const kNAND_NVRAM_SIZE + + @abstract Standard size of nvram presented by the driver. Note + that, if this ends up changing in the future, this value should + start being defined on a platform/product specific basis. +*/ +#define kNAND_NVRAM_SIZE 8192 + +/*! + @const kNAND_NVRAM_META_SIZE + + @abstract Amount of bytes required by meta data for each nvram + backing store page. +*/ +#define kNAND_NVRAM_META_SIZE 10 + +/*! + @const kNAND_NVRAM_PAGE_RESERVED_IN_BLOCK + + @abstract Number of pages reserved for partition table in each + NAND block. +*/ +#define kNAND_NVRAM_PAGE_RESERVED_IN_BLOCK 2 + +/* ========================================================================== */ + +/*! + @group private platform-independent constant definitions +*/ + +/*! + @const NULL + + @abstract It really sucks that some of our systems don't define NULL. +*/ +#ifndef NULL +#define NULL ((void *)0) +#endif + +/*! + @const kNAND_NVRAM_MAX_SIZE + + @abstract Maximum amount of storage; should fit into a standard 2K page. +*/ +#define kNAND_NVRAM_MAX_SIZE (128 * 2048) + +/*! + @const kNAND_NVRAM_SIGNATURE + + @abstract Constant value used to identify nand nvram meta data. +*/ +#define kNAND_NVRAM_SIGNATURE ((uint16_t) 0xBEAD) + +/*! + @const kNAND_NVRAM_VERSION_MAJOR + + @abstract Major version of the driver that wrote the nvram content. + Major version differences are considered to be incompatible. Even + major version numbers are reserved for development purposes; odd + version numbers should be used for when development is frozen, + stabilized, and therefore only accepting minor revision level changes. +*/ +#define kNAND_NVRAM_FEATURE_EXTRA_AREA_VERSION_MAJOR ((uint8_t) 0x0) +#define kNAND_NVRAM_VERSION_MAJOR kNAND_NVRAM_FEATURE_EXTRA_AREA_VERSION_MAJOR + +/*! + @const kNAND_NVRAM_VERSION_MINOR + + @abstract Minor version of the driver that wrote the nvram content. + Minor versions should be fully compatible within a major version and + are intended to be incremented when the driver has changed between + public releases. +*/ +#define kNAND_NVRAM_FEATURE_EXTRA_AREA_VERSION_MINOR ((uint8_t) 0x3) +#define kNAND_NVRAM_VERSION_MINOR kNAND_NVRAM_FEATURE_EXTRA_AREA_VERSION_MINOR + +/*! + @const kNAND_NVRAM_GENERATION_ERASED + + @abstract A generation number of all ones is reserved since it also + corresponds to the erased state of nand bits. +*/ +#define kNAND_NVRAM_GENERATION_ERASED ((uint32_t) 0xFFFFFFFF) + +/*! + @const kNAND_NVRAM_GENERATION_UNKNOWN + + @abstract A generation number of all zeros is reserved since it + corresponds to the state of an uninitialized meta struct. +*/ +#define kNAND_NVRAM_GENERATION_UNKNOWN ((uint32_t) 0x00000000) + +/* ========================================================================== */ + +/*! + @group public platform-independent structure declarations +*/ + +/*! + @struct nand_nvram_geometry + + @abstract Geometry of nand device array slice. + + @field number_of_banks Number of logical banks. + + @field blocks_per_bank Number of blocks in each bank. + + @field pages_per_block Number of pages per block. + + @field data_pages_per_block Number of pages per block available for data storage. + + @field bytes_per_page Size in bytes of page. + + @field bytes_per_meta_buffer Size in bytes of buffer for in-memory per-page meta info. + + @field bytes_per_meta_actual Size in bytes of in-storage per-page meta info (i.e. actual size). +*/ +struct nand_nvram_geometry { + + uint32_t number_of_banks; + uint32_t blocks_per_bank; + uint32_t pages_per_block; + uint32_t data_pages_per_block; + uint32_t bytes_per_page; + uint32_t bytes_per_meta_buffer; + uint32_t bytes_per_meta_actual; +}; + +/* ========================================================================== */ + +/*! + @group private platform-independent structure declarations +*/ + +/*! + @struct _meta + + @abstract Structure defining per-page meta layout. + + @field generation Monotonically increasing generation of blob; + kNAND_NVRAM_GENERATION_UNKNOWN and kNAND_NVRAM_GENERATION_ERASED are + reserved values that should never appear on a nand device. + + @field page_max Maximum page index for blob (i.e. page count - 1). + + @field page_idx Page index of this meta within blob. + + @field version_major Major version number of nand nvram driver. + + @field version_minor Minor version number of nand nvram driver. + + @field signature Constant value of kNAND_NVRAM_SIGNATURE marks valid + nvram meta. +*/ +struct _meta { + + uint32_t generation; + uint8_t page_max; + uint8_t page_idx; + uint8_t version_major; + uint8_t version_minor; + uint16_t signature; + +} __attribute__((__packed__)); + +/*! + @struct _blob + + @abstract Container for N pages of data and meta information + for convenience of writing to/from nand devices. + + @field pageCount Number of pages currently allocated to + shadow the blob. + + @field metaBufs Buffer containing pages' meta structs. + + @field dataBufs Buffer containing pages' data. +*/ +struct _blob { + + void * meta_bufs; + void * data_bufs; +}; + +/*! + @struct nand_nvram + + @abstract NAND-based nvram driver context information. + + @field geometry Geometry of nand device array slice used for + backing store. + + @field is_dirty Flag indicating whether shadow has been + modified since last restore or sync. + + @field shadow Blob used as container for pages of data and meta + information being shadowed from nand. + + @field cursors Array of page numbers of next page in each + bank available for commit. +*/ +struct nand_nvram { + + nand_nvram_geometry_t geo; + void * context; + uint32_t size; + bool is_born; + bool is_dirty; + uint32_t * watermarks; + uint32_t * cursors; + bool * copies; + blob_t * shadow; +}; + +/* ========================================================================== */ + +__END_DECLS + +#endif /* ! _NAND_NVRAM_IMPL_H */ + +/* ========================================================================== */ diff --git a/drivers/flash_nand/boot/nvram/nand_nvram_platform.h b/drivers/flash_nand/boot/nvram/nand_nvram_platform.h new file mode 100644 index 0000000..c69d555 --- /dev/null +++ b/drivers/flash_nand/boot/nvram/nand_nvram_platform.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* ========================================================================== */ + +/*! + @header nand_nvram_platform + + @abstract iBoot platform-specific macros needed by nand nvram + + @copyright Apple Inc. + + @updated 2011-05-18 +*/ + +/* ========================================================================== */ + +#ifndef _NAND_NVRAM_PLATFORM_H +#define _NAND_NVRAM_PLATFORM_H + +#include + +#include +#include + +__BEGIN_DECLS + +/* ========================================================================== */ + +#define nand_nvram_alloc_mem(context, size) memalign((size), CPU_CACHELINE_SIZE) + +#define nand_nvram_compare_mem(context, left, right, size) memcmp((left), (right), (size)) + +#define nand_nvram_copy_mem(context, dest, src, size) memcpy((dest), (src), (size)) + +#define nand_nvram_set_mem(context, mem, value, size) memset((mem), (value), (size)) + +#define nand_nvram_free_mem(context, mem, size) free((mem)) + +#define nand_nvram_printf(context, ...) dprintf(DEBUG_CRITICAL, __VA_ARGS__) + +#define nand_nvram_is_block_bad(context, bank, block) flash_nand_nvram_is_block_bad((context), (bank), (block)) + +#define nand_nvram_read_page(context, bank, page, data, meta, is_clean) flash_nand_nvram_read_page((context), (bank), (page), (data), (meta), (is_clean)) + +#define nand_nvram_write_page(context, bank, page, data, meta) flash_nand_nvram_write_page((context), (bank), (page), (data), (meta)) + +#define nand_nvram_erase_block(context, bank, block) flash_nand_nvram_erase_block((context), (bank), (block)) + +#define nand_nvram_request_ptab_diff(context, data, size) flash_nand_nvram_request_ptab_diff((context), (data), (size)) + +#define nand_nvram_provide_ptab_diff(context, data, size) flash_nand_nvram_provide_ptab_diff((context), (data), (size)) + +#define nand_nvram_copy_ptab(context, buf) flash_nand_nvram_copy_ptab((context), (buf)) + +#define nand_nvram_read_ptab(context, bank, page, buf) flash_nand_nvram_read_ptab((context), (bank), (page), (buf)) + +#define nand_nvram_write_ptab(context, bank, page, buf) flash_nand_nvram_write_ptab((context), (bank), (page), (buf)) + +/* ========================================================================== */ + +bool flash_nand_nvram_is_block_bad(void * context, uint32_t bank, uint32_t block); +bool flash_nand_nvram_read_page(void * context, uint32_t bank, uint32_t page, void * data, void * meta, bool * is_clean); +bool flash_nand_nvram_write_page(void * context, uint32_t bank, uint32_t page, void * data, void * meta); +bool flash_nand_nvram_erase_block(void * context, uint32_t bank, uint32_t block); +bool flash_nand_nvram_request_ptab_diff(void * context, void * data, uint32_t size); +bool flash_nand_nvram_provide_ptab_diff(void * context, void * data, uint32_t size); +bool flash_nand_nvram_copy_ptab(void * context, void * buf); +bool flash_nand_nvram_read_ptab(void * context, uint32_t bank, uint32_t page, void * buf); +bool flash_nand_nvram_write_ptab(void * context, uint32_t bank, uint32_t page, void * buf); + +/* ========================================================================== */ + +__END_DECLS + +#endif /* _NAND_NVRAM_PLATFORM_H */ + +/* ========================================================================== */ diff --git a/drivers/flash_nand/boot/nvram/rules.mk b/drivers/flash_nand/boot/nvram/rules.mk new file mode 100644 index 0000000..8c737d7 --- /dev/null +++ b/drivers/flash_nand/boot/nvram/rules.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_NAND_NVRAM=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/nand_nvram.o \ + $(LOCAL_DIR)/nand_nvram_core.o \ + $(LOCAL_DIR)/nand_nvram_dump.o diff --git a/drivers/flash_nand/boot/rules.mk b/drivers/flash_nand/boot/rules.mk new file mode 100644 index 0000000..3796751 --- /dev/null +++ b/drivers/flash_nand/boot/rules.mk @@ -0,0 +1,30 @@ +# +# Copyright (c) 2008-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_NAND_BOOT=1 + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR) + +MODULES += \ + lib/effaceable/iboot/nand + +ALL_OBJS += \ + $(LOCAL_DIR)/nand_export.o \ + $(LOCAL_DIR)/nand_part_core.o \ + $(LOCAL_DIR)/nand_boot.o + +ifeq ($(PRODUCT),LLB) +OPTIONS += \ + WITH_NAND_PART_BUILD_TINY=1 +endif \ No newline at end of file diff --git a/drivers/flash_nand/boot/syscfg/nand_syscfg.c b/drivers/flash_nand/boot/syscfg/nand_syscfg.c new file mode 100644 index 0000000..c058f36 --- /dev/null +++ b/drivers/flash_nand/boot/syscfg/nand_syscfg.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_SYSCFG + +// XXX include list is bloated; trim it down + +#include +#include +#include +#include +#include +#include +#include + +#include "WMRFeatures.h" +#include "WMRConfig.h" +#include "ANDTypes.h" +#if WITH_RAW_NAND +#include "WMRExam.h" +#endif // WITH_RAW_NAND +#include "WMROAM.h" +#include "FIL.h" + +#include "nand_part.h" +#include "nand_part_interface.h" +#include "nand_export.h" + +// Ugly, ugly, ugly! +extern uint32_t nand_fsys_block_offset; + +#if WITH_PPN_SYSCFG +extern int ppn_syscfg_init(void); +extern int ppn_read_syscfg_hook(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count); +#endif //WITH_PPN_SYSCFG + +// The syscfg library assumes that syscfg will be 0x4000 bytes into +// the device regardles of whether it's NAND or NOR. nand1 will ONLY +// expose syscfg, so this doesn't make any sense, but we'll say we're +// big enough to read that far in anyway. +#define kSysCfgActualSize ( 0x4000 ) +#define kFakeBdevBlockSize (kSysCfgBdevOffset) +#define kFakeBdevCapacity (kSysCfgBdevOffset + kSysCfgActualSize) + + +#if WITH_RAW_NAND + +static int nand_read_syscfg_hook(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count) +{ + bool ok = true; + BOOL32 result; + + // Only allow reading the "second" block + if ((block != 1) || (count != 1)) { + dprintf(DEBUG_CRITICAL, "attempted to read nand syscfg at non-zero offset\n"); + ok = false; + + } else if (count > 0) { + + result = WMR_GetFPart()->ReadDeviceUniqueInfo(ptr, kFakeBdevBlockSize); + if (!result) { + + dprintf(DEBUG_CRITICAL, "nand_read_block_hook: failure reading syscfg\n"); + ok = false; + } + } + + if (!ok) + return -1; + + return count; +} + +#endif // WITH_RAW_NAND + +int nand_syscfg_init(NandPartInterface * npi) +{ + int err = 0; + struct blockdev *nand_syscfg; + bool is_ppn; + + dprintf(DEBUG_INFO, "nand_syscfg_init()\n"); + + is_ppn = FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_PPN_DEVICE); + + nand_syscfg = malloc(sizeof(struct blockdev)); +#if WITH_PPN_SYSCFG + if (is_ppn) { + if (0 == ppn_syscfg_init()) { + construct_blockdev(nand_syscfg, "nand_syscfg", kFakeBdevCapacity, kFakeBdevBlockSize); + nand_syscfg->read_block_hook = &ppn_read_syscfg_hook; + register_blockdev(nand_syscfg); + syscfgInitWithBdev("nand_syscfg"); + } else { + err = -1; + } + } +#else //WITH_PPN_SYSCFG + check(!is_ppn); +#endif //WITH_PPN_SYSCFG + +#if WITH_RAW_NAND + if (!is_ppn) { + if (WMR_SUCCESS == WMR_PreInit(gWhimoryInitParameters, nand_fsys_block_offset)) { + construct_blockdev(nand_syscfg, "nand_syscfg", kFakeBdevCapacity, kFakeBdevBlockSize); + nand_syscfg->read_block_hook = &nand_read_syscfg_hook; + register_blockdev(nand_syscfg); + syscfgInitWithBdev("nand_syscfg"); + } else { + err = -1; + } + } +#else // WITH_RAW_NAND + check(is_ppn); +#endif // WITH_RAW_NAND + + return err; +} + +#endif /* WITH_SYSCFG */ diff --git a/drivers/flash_nand/boot/syscfg/rules.mk b/drivers/flash_nand/boot/syscfg/rules.mk new file mode 100644 index 0000000..3217b96 --- /dev/null +++ b/drivers/flash_nand/boot/syscfg/rules.mk @@ -0,0 +1,17 @@ +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_NAND_SYSCFG=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/nand_syscfg.o diff --git a/drivers/flash_nand/debug.c b/drivers/flash_nand/debug.c new file mode 100644 index 0000000..fbbac38 --- /dev/null +++ b/drivers/flash_nand/debug.c @@ -0,0 +1,1524 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#include "FIL.h" +#include "ANDTypes.h" +#include "WMRConfig.h" +#include "H2fmi.h" +#include "PPNMiscTypes.h" +#include "WMROAM.h" + +#if !RELEASE_BUILD && WITH_MENU + +#define WITH_NAND_DEBUG (0) +#define MAX_NAND_SIZE_KB (67108864) //(64GB) + +#if WITH_PPN +extern BOOL32 WMR_PPN_CtrlIO(UInt32 dwCtlrIOType, void * pvoidDataBuffer, UInt32 * pdwDataSize); +#endif +#if WITH_RAW_NAND +extern BOOL32 WMR_CtrlIO(UInt32 dwCtlrIOType, void * pvoidDataBuffer, UInt32 * pdwDataSize); +#endif // WITH_RAW_NAND + +static BOOL32 ctrl_io(UInt32 dwCtlrIOType, void * pvoidDataBuffer, UInt32 * pdwDataSize) +{ +#if WITH_PPN + LowFuncTbl *fil = FIL_GetFuncTbl(); + if (fil->GetDeviceInfo(AND_DEVINFO_PPN_DEVICE) > 0) + { + if (!WMR_PPN_CtrlIO(dwCtlrIOType, pvoidDataBuffer, pdwDataSize)) + { + return FALSE32; + } + } + else +#endif + { +#if WITH_RAW_NAND + if (!WMR_CtrlIO(dwCtlrIOType, pvoidDataBuffer, pdwDataSize)) +#endif // WITH_RAW_NAND + { + return FALSE32; + } + } + + return TRUE32; +} + +// raw_read +// +// Read the specifed number of full (main + spare) nand pages to the given +// buffer. They are concatenated with no padding, so a part with an unaligned +// number of spare bytes, multiple pages requests will not have aligned +// main data +// +static int raw_read(UInt32 ce, UInt32 base_page, UInt32 num_pages, void *buffer) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 main_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 spare_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_SPARE); + const UInt32 bytes_per_read = main_size + spare_size; + UInt8 *cursor = buffer; + int err = 0; + UInt32 page_offset; + UInt32 nand_status; + UInt8 *bounce; + + if (!security_allow_memory(buffer, num_pages * bytes_per_read)) + { + printf("Permission Denied\n"); + return -1; + } + + + printf("raw_read ce %d base page %d (0x%08x) #pages %d\n", ce, base_page, base_page, num_pages); + + if (NULL == fil->ReadNoECC) + { + printf("ReadNoECC not available\n"); + return -1; + } + + bounce = malloc(main_size + spare_size); + + for (page_offset = 0; page_offset < num_pages; ++page_offset) + { + UInt32 current_page = base_page + page_offset; + void *spare = bounce + main_size; // put the spare immediately after main + memset(bounce, 0xB6, bytes_per_read); + if (FIL_SUCCESS != (nand_status = fil->ReadNoECC(ce, current_page, bounce, spare))) + { + printf("error 0x%08x reading ce %d page %d\n", nand_status, ce, current_page); + err = -1; + } + memcpy(cursor, bounce, bytes_per_read); + cursor += bytes_per_read; + } + + free(bounce); + printf("%d bytes read to %p\n", cursor - (UInt8*)buffer, buffer); + return err; +} + +#if WITH_PPN +static int cbp2r(UInt16 cau, UInt32 block, UInt32 page_offset) +{ + UInt32 row_addr = 0; + PPN_DeviceInfo* dev = malloc(sizeof(PPN_DeviceInfo)); + LowFuncTbl *fil = FIL_GetFuncTbl(); + + ppnMiscFillDevStruct(dev, fil); + row_addr = ppnMiscConvertToPPNPageAddress(dev, cau, block, page_offset, FALSE32); + printf("cau: %d, block: %d, page_offset: %d corresponds to row addr: 0x%X\n", cau, block, page_offset, row_addr); + free(dev); + return 0; +} + +static int r2cbp(UInt32 row_addr) +{ + UInt16 cau = 0; + UInt16 block = 0; + UInt16 page_offset = 0; + PPN_DeviceInfo* dev = malloc(sizeof(PPN_DeviceInfo)); + LowFuncTbl *fil = FIL_GetFuncTbl(); + + ppnMiscFillDevStruct(dev, fil); + ppnMiscConvertPhysicalAddressToCauBlockPage(dev, row_addr, &cau, &block, &page_offset); + printf("row_addr: 0x%X corresponds to cau: %d, block: %d, page_offset: %d\n",row_addr, cau, block, page_offset); + free(dev); + return 0; +} + +static int read4k(UInt32 ce, UInt32 num_lbas, UInt8 lba_offset, UInt16 cau, UInt16 block, UInt16 base_page, void *buffer) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + PPNCommandStruct* ppn_command; + PPN_DeviceInfo* dev = malloc(sizeof(PPN_DeviceInfo)); + PPNReorderStruct* reorder = malloc(sizeof(PPNReorderStruct)); + const UInt32 main_size = (fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE)) / (fil->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE)); + const UInt32 meta_size = fil->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + const UInt32 bytes_per_read = main_size + meta_size; + PPNStatusType status; + int err = 0; + UInt32 lba_idx; + UInt8 *bounce; + UInt8 *cursor = buffer; + UInt8 current_lba_offset = lba_offset; + UInt16 current_page = base_page; + UInt16 allowed_lbas; + + ppnMiscFillDevStruct(dev, fil); + allowed_lbas = ((dev->pages_per_block_mlc - base_page) * (dev->lbas_per_page)) - lba_offset; + if(num_lbas > allowed_lbas) + { + printf("Reading lbas from only one block is allowed (No more than %d lbas with a page_offset of %d and lba_offset of %d)\n", allowed_lbas, base_page, lba_offset); + printf("pages per blk: %d\n", dev->pages_per_block_mlc); + free(dev); + free(reorder); + return -1; + } + + if (!security_allow_memory(buffer, num_lbas * bytes_per_read)) + { + free(dev); + free(reorder); + printf("Permission Denied\n"); + return -1; + } + + ppn_command = malloc((sizeof(PPNCommandStruct))); + bounce = malloc(bytes_per_read); + + printf("reading %d 4k LBA's starting from CE: %d, cau: %d, Block: %d, Page offset: %d, lba_offset: %d\n", num_lbas, ce, cau, block, base_page, lba_offset); + for(lba_idx = 0; lba_idx < num_lbas; lba_idx++) + { + void *meta = bounce + main_size; + memset(bounce, 0xC7, bytes_per_read); + memset(ppn_command, 0xB6, (sizeof(PPNCommandStruct))); + status = ppnMiscSingleLbaRead(dev, ppn_command, PPN_COMMAND_READ, PPN_NO_OPTIONS, ce, cau, block, current_page, current_lba_offset, FALSE32, bounce, meta); + if(status != PPN_READ_STATUS_VALID) + { + printf("error status: 0x%X reading lba at page offset: %d, lba offset: %d\n", status, current_page, current_lba_offset); + err = -1; + } + memcpy(cursor, bounce, bytes_per_read); + cursor += bytes_per_read; + if((dev->lbas_per_page - current_lba_offset) == 1) + { + current_page ++; + current_lba_offset = 0; + } + else + { + current_lba_offset++; + } + } + + free(bounce); + free(ppn_command); + free(dev); + free(reorder); + return err; +} +#endif // WITH_PPN + +// read_with_ecc +// +// Read the specifed number of main + meta nand pages to the given +// buffer. They are concatenated with no padding, so a part with an unaligned +// number of meta bytes (default today is 12), multiple pages requests will not +// have aligned main data +// +static int read_with_ecc(UInt32 ce, UInt32 base_page, UInt32 num_pages, BOOL32 stats, BOOL32 disable_whitening, void *buffer) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 main_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 meta_size = fil->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE) * fil->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + const UInt32 bytes_per_read = main_size + meta_size; + const UInt32 sectors_per_page = main_size / fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + UInt8 *cursor = buffer; + int err = 0; + UInt32 page_offset; + UInt32 nand_status; + UInt8 *bounce; + UInt8 *buf_stats = NULL; + UInt8 *buf_stats_cursor = NULL; + UInt32 idx; + bool zero_flips = true; + + if (!security_allow_memory(buffer, num_pages * bytes_per_read)) + { + printf("Permission Denied\n"); + return -1; + } + + printf("read ce %d base page %d (0x%08x) #pages %d\n", ce, base_page, base_page, num_pages); + + if (NULL == fil->ReadWithECC) + { + printf("ReadWithECC not available\n"); + return -1; + } + + bounce = malloc(main_size + meta_size); + if(stats) + { + buf_stats = malloc(sectors_per_page); + memset(buf_stats, 0x00, sectors_per_page); + printf("sector stats: \n"); + } + + for (page_offset = 0; page_offset < num_pages; ++page_offset) + { + UInt32 current_page = base_page + page_offset; + void *meta = bounce + main_size; // put the meta immediately after main + memset(bounce, 0xC7, bytes_per_read); + + if (FIL_SUCCESS != (nand_status = fil->ReadWithECC(ce, current_page, bounce, meta, NULL, buf_stats, disable_whitening))) + { + printf("error 0x%08x reading ce %d page %d\n", nand_status, ce, current_page); + err = -1; + } + memcpy(cursor, bounce, bytes_per_read); + cursor += bytes_per_read; + + if(stats) + { + buf_stats_cursor = buf_stats; + zero_flips = true; + for(idx = 0; idx < sectors_per_page; idx++) + { + if(*buf_stats_cursor != 0) + { + zero_flips = false; + break; + } + buf_stats_cursor++; + } + if(!zero_flips) + { + buf_stats_cursor = buf_stats; + printf("ce %d page %d: ", ce, (base_page + page_offset)); + for(idx = 0; idx < sectors_per_page; idx++) + { + printf("%02X ", *buf_stats_cursor); + buf_stats_cursor++; + } + printf("\n"); + } + } + } + + free(bounce); + printf("%d bytes read to %p\n", cursor - (UInt8*)buffer, buffer); + return err; +} + +// read_bl_pages +// +// Read the specifed number of bootloader-style nand pages to the given +// buffer. Multiple pages are concatenated with no padding. +// +static int read_bl_pages(UInt32 ce, UInt32 base_page, UInt32 num_pages, void *buffer) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 bl_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_BL_PAGE); + UInt8 *cursor = buffer; + int err = 0; + UInt32 page_offset; + UInt32 nand_status; + + if (!security_allow_memory(buffer, num_pages * bl_size)) + { + printf("Permission Denied\n"); + return -1; + } + + printf("readboot ce %d base page %d (0x%08x) #pages %d\n", ce, base_page, base_page, num_pages); + + if (NULL == fil->ReadBLPage) + { + printf("ReadBL not available\n"); + return -1; + } + + for (page_offset = 0; page_offset < num_pages; ++page_offset) + { + UInt32 current_page = base_page + page_offset; + memset(cursor, 0xD8, bl_size); + if (FIL_SUCCESS != (nand_status = fil->ReadBLPage(ce, current_page, cursor))) + { + printf("error 0x%08x reading ce %d page %d\n", nand_status, ce, current_page); + err = -1; + } + cursor += bl_size; + } + + printf("%d bytes read to %p\n", cursor - (UInt8*)buffer, buffer); + return err; +} + +static int inspect_single_block(UInt32 ce, UInt32 block) +{ + Int32 nand_status; + int num_clean = 0; + int num_good_boot_pages = 0; + int num_good_full_pages = 0; + int num_uecc = 0; + int num_out_of_order = 0; + + void *page_buffer; + void *meta_buffer; + UInt32 page_offset; + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 slcBits = fil->GetDeviceInfo(AND_DEVINFO_ADDR_BITS_BITS_PER_CELL); + const UInt32 cauBits = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_CAU_ADDRESS); + const UInt32 blockBits = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_BLOCK_ADDRESS); + const UInt32 slc_mask = ~((~0) << slcBits) << (cauBits + blockBits); + const UInt32 pages_per_block = (slc_mask & block)? + fil->GetDeviceInfo(AND_DEVINFO_SLC_PAGES_PER_BLOCK): + fil->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + + if (NULL == fil->ReadWithECC) + { + printf("ReadWithECC is not available\n"); + return -1; + } + + if (NULL == fil->ReadBLPage) + { + printf("ReadBLPage is not available\n"); + return -1; + } + + page_buffer = malloc(fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE) + fil->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES)); + meta_buffer = (UInt8*)page_buffer + fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + + + for (page_offset = 0; page_offset < pages_per_block; ++page_offset) + { + const UInt32 current_page = (block * pages_per_block) + page_offset; + + nand_status = fil->ReadBLPage(ce, current_page, page_buffer); + if (FIL_SUCCESS == nand_status) + { + num_good_boot_pages++;; + if (num_clean > 0) + { + if (0 == num_out_of_order) + { + // only print once + printf("ERROR: Found OK boot-page after clean page on ce %d page %d(0x%08x)\n", + ce, current_page, current_page); + } + num_out_of_order++; + } + } + else if (FIL_SUCCESS_CLEAN == nand_status) + { + num_clean++; + } + else + { + // see if it's a full-page before we call it bad + if (FIL_SUCCESS == (nand_status = fil->ReadWithECC(ce, current_page, page_buffer, meta_buffer, NULL, NULL, FALSE32))) + { + num_good_full_pages++; + if (num_clean > 0) + { + // only print once + if (0 == num_out_of_order) + { + printf("ERROR: Found OK full-page after clean page on ce %d page %d(0x%08x)\n", + ce, current_page, current_page); + } + num_out_of_order++; + } + } + else + { + num_uecc++; + printf("ERROR: Found UECC at ce %d page %d(0x%08x)\n", + ce, current_page, current_page); + } + } + } + + if (num_out_of_order > 0) + { + printf("Error on ce %d block %d - %d pages programmed out of order\n", + ce, block, num_out_of_order); + } + + printf("ce %d block %4d - boot-pages: %4d full-pages: %4d clean: %4d UECC: %4d\n", + ce, block, num_good_boot_pages, num_good_full_pages, num_clean, num_uecc); + + + free(page_buffer); + + return ((num_out_of_order > 0) || (num_uecc > 0)) ? -1 : 0; +} + +// inspect_blocks +// +// Verify that this block has not been programmed incorrectly +// Checks for uecc and clean pages out of order +// +static int inspect_blocks(UInt32 ce, UInt32 start_block, UInt32 num_blocks) +{ + UInt32 block, last_ce; + int overall = 0; + + LowFuncTbl *fil = FIL_GetFuncTbl(); + + last_ce = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS) - 1; + + if (ce > last_ce) + { + printf("ERROR: invalid ce (max is %d)\n", last_ce); + return -1; + } + + for(block = 0; block < num_blocks; ++block) + { + overall |= inspect_single_block(ce, start_block + block); + } + + return overall; +} + +static int nand_info(void) +{ + NandTimingParams timing; + UInt32 data_size; + UInt32 ns_per_clock; + UInt32 clk_mhz; + UInt32 is_toggle; + int err = 0; + + LowFuncTbl *fil = FIL_GetFuncTbl(); + + + printf("PPN: %s\n", fil->GetDeviceInfo(AND_DEVINFO_PPN_DEVICE) ? "Yes" : "No"); + printf("Toggle: %s\n", (is_toggle = fil->GetDeviceInfo(AND_DEVINFO_TOGGLE_DEVICE)) ? "Yes" : "No"); + + printf("Page Size: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE)); + printf("Spare Size: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_SPARE)); + printf("Pages Per Block: %d\n", fil->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK)); + printf("Blocks Per CE: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS)); + printf("Blocks Per CAU: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU)); + printf("CAU's per CE: %d\n", fil->GetDeviceInfo(AND_DEVINFO_CAUS_PER_CE)); + + printf("VS Type: 0x%08x\n", fil->GetDeviceInfo(AND_DEVINFO_VENDOR_SPECIFIC_TYPE)); + printf("Banks Per CE: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BANKS_PER_CS)); + + printf("Refresh: %d\n", fil->GetDeviceInfo(AND_DEVINFO_REFRESH_THRESHOLD)); + printf("Correctable Bits: %d\n", fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_BITS)); + printf("Correctable Sector: %d\n", fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE)); + + printf("Active Channels: %d\n", fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CHANNELS)); + printf("CE Per Channel: %d\n", fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CES_PER_CHANNEL)); + + printf("Bootloader Page: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_BL_PAGE)); + + printf("Bits per page address: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_PAGE_ADDRESS)); + printf("Bits per block address: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_BLOCK_ADDRESS)); + printf("Bits per cau address: %d\n", fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_CAU_ADDRESS)); + printf("Address bits for bits per cell: %d\n", fil->GetDeviceInfo(AND_DEVINFO_ADDR_BITS_BITS_PER_CELL)); + + // Avoid 64-bit math, we're rounding anyway +#ifdef CLK_FMI + clk_mhz = clock_get_frequency(CLK_FMI) / 1000000; +#else + clk_mhz = clock_get_frequency(CLK_HCLK) / 1000000; +#endif + ns_per_clock = 1000 / clk_mhz; + + + memset(&timing, 0xff, sizeof(timing)); + data_size = sizeof(timing); + if (FIL_GetStruct(AND_STRUCT_FIL_GET_TIMINGS, &timing, &data_size)) + { + if (is_toggle) + { + printf("Read/Write Cycle Time: %dns\n", ((timing.ddr_tHALFCYCLE + 1) * 1000 * 2) / clk_mhz); + } + else + { + printf("Read Timing: %dns setup %dns hold %d ns strobe\n", + (timing.sdrTimings.tRP + 1) * ns_per_clock, + (timing.sdrTimings.tREH + 1) * ns_per_clock, + timing.sdrTimings.DCCYCLE * ns_per_clock); + printf("Write Timing: %dns setup %dns hold\n", + (timing.sdrTimings.tWP + 1) * ns_per_clock, + (timing.sdrTimings.tWH + 1) * ns_per_clock); + } + } + else + { + err = -1; + } + + return err; +} + +#define IS_BLOCK_GOOD(bbt, block) ((bbt)[(block) >> 3] & (1 << ((block) & 0x07))) + +// Caller frees the buffer +static UInt8 * allocate_bbt() +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 total_ce = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + const UInt32 blocks_per_ce = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); + const UInt32 bbt_size_per_ce = (blocks_per_ce / 8) + (blocks_per_ce % 8 ? 1 : 0); // bit per block + const UInt32 expected_bbt_size = total_ce * bbt_size_per_ce; + UInt32 data_size = expected_bbt_size; + void * buffer = malloc(data_size); + +#if WITH_PPN + const UInt32 main_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 spare_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_SPARE); + const UInt32 bytes_per_read = main_size + spare_size; + + UInt8 *bounce = NULL; + UInt8 *pData = NULL; + PPNCommandStruct *ppn_command = NULL; + PPN_DeviceInfo *dev = NULL; + PPNStatusType ppn_status; + UInt32 ce; + UInt32 cau; + UInt32 length; + + if (fil->GetDeviceInfo(AND_DEVINFO_PPN_DEVICE) > 0) + { + const UInt32 caus_per_ce = fil->GetDeviceInfo(AND_DEVINFO_CAUS_PER_CE); + const UInt32 blocks_per_cau = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU); + const UInt32 cau_bbt_size = (blocks_per_cau / 8) + (blocks_per_cau % 8 ? 1 : 0); + const UInt32 total_caus = caus_per_ce * total_ce; + const UInt32 required_buffer_size = cau_bbt_size * total_caus; + + data_size = required_buffer_size; + bounce = malloc(bytes_per_read); + ppn_command = malloc((sizeof(PPNCommandStruct))); + dev = malloc(sizeof(PPN_DeviceInfo)); + pData = (UInt8 *) buffer; + ppnMiscFillDevStruct(dev, fil); + + for (ce = 0; ce < total_ce; ce++) + { + for (cau = 0; cau < caus_per_ce; cau++) + { + UInt16 bank = (cau * total_ce) + ce; + memset(bounce, 0xC7, bytes_per_read); + memset(ppn_command, 0xB6, (sizeof(PPNCommandStruct))); + ppn_status = ppnMiscSingleOperation(dev, ppn_command, PPN_COMMAND_CAUBBT, + PPN_NO_OPTIONS, bank, + 0, 0, TRUE32, bounce, NULL); + if(ppn_status != PPN_READ_STATUS_VALID){ + printf("error pulling BBT, status: 0x%x\n", ppn_status); + goto error; + } + WMR_MEMCPY(pData, bounce, cau_bbt_size); + + // Consumers expect opposite bit-order + for (length = cau_bbt_size; length > 0; length--) + { + UInt8 byte = *pData; + *pData = ((byte & 0x01) << 7) | + ((byte & 0x02) << 5) | + ((byte & 0x04) << 3) | + ((byte & 0x08) << 1) | + ((byte & 0x10) >> 1) | + ((byte & 0x20) >> 3) | + ((byte & 0x40) >> 5) | + ((byte & 0x80) >> 7); + pData++; + } + } + } + } + else +#endif + { +#if WITH_RAW_NAND + if (!WMR_CtrlIO(AND_STRUCT_VFL_FACTORY_BBT, buffer, &data_size)) +#endif // WITH_RAW_NAND + { + goto error; + } + } + + if (data_size != expected_bbt_size) + { + printf("error in BBT size. got %d expected %d\n", + expected_bbt_size, data_size); + goto error; + } + + return buffer; +error: + if (NULL != buffer) + { + free(buffer); + buffer = NULL; + } +#if WITH_PPN + if (NULL != bounce) + { + free(bounce); + bounce = NULL; + } + if (NULL != ppn_command) + { + free(ppn_command); + ppn_command = NULL; + } + if (NULL != dev) + { + free(dev); + dev = NULL; + } +#endif + + return buffer; +} + +static int print_raw_bbt() +{ + int err = 0; + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 num_ce = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + const UInt32 blocks_per_ce = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); + const UInt32 bbt_size_per_ce = (blocks_per_ce / 8) + (blocks_per_ce % 8 ? 1 : 0); // bit per block + UInt32 ce, block; + void * buffer = allocate_bbt(); + + if (NULL == buffer) + { + err = -1; + } + else + { + UInt8 *cursor = buffer; + for (ce = 0; ce < num_ce; ++ce) + { + for(block = 0; block < blocks_per_ce; ++block) + { + if (!IS_BLOCK_GOOD(cursor, block)) + { + printf("CE %d Block %d\n", ce, block); + } + } + cursor += bbt_size_per_ce; + } + + } + + free(buffer); + + return err; +} + +#if WITH_PPN +static int print_ppn_bbt() +{ + int err = 0; + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 num_ce = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + const UInt32 caus_per_ce = fil->GetDeviceInfo(AND_DEVINFO_CAUS_PER_CE); + const UInt32 blocks_per_cau = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU); + UInt32 ce; + UInt32 block; + UInt32 cau; + UInt32 cau_block; + UInt8 *buffer = allocate_bbt(); + + if (!buffer) + { + return -1; + } + + block = 0; + for (cau = 0; cau < caus_per_ce; cau++) + { + for (ce = 0; ce < num_ce; ce++) + { + for (cau_block = 0; cau_block < blocks_per_cau; cau_block++, block++) + { + if (!IS_BLOCK_GOOD(buffer, block)) + { + printf("CE %d CAU %d Block 0x%08x bad\n", ce, cau, cau_block); + } + } + } + } + free(buffer); + return err; +} +#endif + +//get_physical_ce +//gets the physical ce given a channel and a ce index within the channel + +#if WITH_PPN +static int get_physical_ce() +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + PPN_DeviceInfo* dev = malloc(sizeof(PPN_DeviceInfo));; + UInt16 channel_idx, cau_idx, ce_idx, bank, phy_ce; + UInt32 idx = 0; + + ppnMiscFillDevStruct(dev, fil); + + for(channel_idx = 0; channel_idx < dev->num_channels; channel_idx++) + { + for(ce_idx = 0; ce_idx < dev->ces_per_channel; ce_idx++) + { + for(cau_idx = 0; cau_idx < dev->caus_per_ce; cau_idx++) + { + bank = ((ce_idx * dev->num_channels * dev->caus_per_ce) + + (cau_idx * dev->num_channels) + channel_idx); + + phy_ce = ppnMiscGetCEFromBank(dev, bank); + + printf("%d: channel: %d, ceIdx: %d, cauIdx: %d corresponds to physical CE: %d\n", idx, channel_idx, ce_idx, cau_idx, phy_ce); + idx++; + } + } + } + return 0; +} +#endif + +// get_stats +// gets the sector stats for the entire device to $loadaddr. can be obtained with usb put + +#if WITH_PPN +static int get_stats(void *buffer) +{ + UInt64 idx; + UInt8 *cursor = (UInt8 *)buffer; + void *meta; + UInt8 *bounce; + LowFuncTbl *fil = FIL_GetFuncTbl(); + PPN_DeviceInfo* dev; + UInt16 channel_idx, ce_idx, bank, cau_idx, page_offset_idx, block_idx, sector_idx; + UInt32 block; + PPNStatusType block_status; + PPNStatusType current_status; + PPNCommandStruct* ppn_command; + BOOL32 is_SLC; + const UInt32 main_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 spare_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_SPARE); + const UInt32 bytes_per_read = main_size + spare_size; + const UInt32 blocks_per_ce = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); + const UInt32 sectors_per_page = main_size / fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + const UInt32 bbt_size_per_ce = (blocks_per_ce / 8) + (blocks_per_ce % sectors_per_page ? 1 : 0); // bit per block + const UInt32 stats_per_page = sectors_per_page + 1; //1 extra byte for SLC/MLC mode + const UInt32 max_stats_size = MAX_NAND_SIZE_KB + (MAX_NAND_SIZE_KB/sectors_per_page); + void * bbt_buffer = allocate_bbt(); + + if (!security_allow_memory(buffer, max_stats_size)) + { + free(bbt_buffer); + printf("Permission Denied\n"); + return -1; + } + memset(buffer, 0x00, max_stats_size); + + dev = malloc(sizeof(PPN_DeviceInfo)); + bounce = malloc(bytes_per_read); + ppn_command = malloc((sizeof(PPNCommandStruct))); + + ppnMiscFillDevStruct(dev, fil); + + idx = 0; + block_status = 0; + is_SLC = FALSE32; //MLC by default + for(channel_idx = 0; channel_idx < dev->num_channels; channel_idx++) + { + for(ce_idx = 0; ce_idx < dev->ces_per_channel; ce_idx++) + { + for(cau_idx = 0; cau_idx < dev->caus_per_ce; cau_idx++) + { + for(block_idx = 0; block_idx < dev->blocks_per_cau; block_idx++) + { + //check for bad blocks + block = block_idx + (cau_idx * dev->blocks_per_cau); + if(!IS_BLOCK_GOOD(((UInt8 *) bbt_buffer + (bbt_size_per_ce * ((channel_idx * dev->ces_per_channel) + ce_idx))), block)) + { + for(page_offset_idx = 0; page_offset_idx < dev->pages_per_block_mlc; page_offset_idx++) + { + idx = stats_per_page * + ((page_offset_idx) + + (block_idx * dev->pages_per_block_mlc) + + (cau_idx * dev->blocks_per_cau * dev->pages_per_block_mlc) + + (ce_idx * dev->caus_per_ce * dev->blocks_per_cau * dev->pages_per_block_mlc) + + (channel_idx * dev->ces_per_channel * dev->caus_per_ce * dev->blocks_per_cau * dev->pages_per_block_mlc)); + cursor[idx] = (UInt8) FALSE32; //MLC default + idx++; + for(sector_idx = 0; sector_idx < sectors_per_page; sector_idx++) + { + cursor[idx] = 0xfc; //bad block marking + idx++; + } + } + continue; + } + + //if previous MLC read was for an SLC programmed page, read it in SLC mode + if((((block_status & PPN_READ_STATUS_WRONG_BITS_PER_CELL))) && (!is_SLC)) + { + is_SLC = TRUE32; + block_idx--; + } + else + { + is_SLC = FALSE32; + } + block_status = 0; + for(page_offset_idx = 0; page_offset_idx < dev->pages_per_block_mlc; page_offset_idx++) + { + bank = ((ce_idx * dev->num_channels * dev->caus_per_ce) + + (cau_idx * dev->num_channels) + channel_idx); + + meta = bounce + main_size; + memset(bounce, 0xC7, bytes_per_read); + memset(ppn_command, 0xB6, (sizeof(PPNCommandStruct))); + current_status = ppnMiscSingleOperation(dev, ppn_command, PPN_COMMAND_READ, + PPN_OPTIONS_REPORT_HEALTH, bank, block_idx, + page_offset_idx, is_SLC, + bounce, meta); + block_status |= current_status; + + idx = stats_per_page * + ((page_offset_idx) + + (block_idx * dev->pages_per_block_mlc) + + (cau_idx * dev->blocks_per_cau * dev->pages_per_block_mlc) + + (ce_idx * dev->caus_per_ce * dev->blocks_per_cau * dev->pages_per_block_mlc) + + (channel_idx * dev->ces_per_channel * dev->caus_per_ce * dev->blocks_per_cau * dev->pages_per_block_mlc)); + cursor[idx] = (UInt8) is_SLC; + idx++; + + for(sector_idx = 0; sector_idx < sectors_per_page; sector_idx++) + { + if((((current_status & PPN_READ_STATUS_INVALID_DATA) &&(!(current_status & PPN_READ_STATUS_CLEAN)))) && (!is_SLC)) + { + cursor[idx] = 0xff; + } + else if(current_status == (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_CLEAN | PPN_READ_STATUS_VALID)) + { + cursor[idx] = 0xfe; + } + else if(current_status == PPN_READ_STATUS_VALID) + { + cursor[idx] = bounce[sector_idx]; + } + else + { + cursor[idx] = 0xfd; + printf("Bad read status: 0x%X - channel: %d, ce: %d, cau: %d, blk: %d, pg_offset: %d, is_SLC: %d\n", current_status, channel_idx, ce_idx, cau_idx, block_idx, page_offset_idx, is_SLC); + } + idx++; + } + } + } + } + } + } + printf("usb put %llu\n", idx); + + printf("Device parameters:\n"); + printf("Number of channels: %d\n", dev->num_channels); + printf("CE's per channel: %d\n", dev->ces_per_channel); + printf("CAU's per CE: %d\n", dev->caus_per_ce); + printf("Blocks per CAU: %d\n", dev->blocks_per_cau); + printf("Pages per Block: %d\n", dev->pages_per_block_mlc); + + free(bbt_buffer); + free(dev); + free(ppn_command); + return 0; +} +#endif //#if WITH_PPN + +#define LOG2(x) (31UL - __builtin_clz((UInt32)(x))) +static int nuke(bool force) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 num_ce = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + const UInt32 blocks_per_ce = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); + const UInt32 bbt_size_per_ce = (blocks_per_ce / 8) + (blocks_per_ce % 8 ? 1 : 0); // bit per block +#if WITH_PPN + const UInt32 die_per_ce = fil->GetDeviceInfo(AND_DEVINFO_CAUS_PER_CE); + const UInt32 blocks_per_die = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU); + const UInt32 die_addr_bits = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_BLOCK_ADDRESS); +#else // WITH_PPN + const UInt32 die_per_ce = fil->GetDeviceInfo(AND_DEVINFO_DIES_PER_CS); + const UInt32 blocks_per_die = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_DIE); + const UInt32 die_addr_bits = LOG2(fil->GetDeviceInfo(AND_DEVINFO_DIE_STRIDE)); +#endif // !WITH_PPN + Int32 nand_status; + UInt8 *bbt; + + UInt32 ce, die, block; + + if (NULL == fil->Erase) + { + printf("erase is not supported\n"); + return -1; + } + + bbt = allocate_bbt(); + if ((NULL == bbt) && !force) + { + printf("bbt not found. force?\n"); + return -1; + } + + for (ce = 0; ce < num_ce; ++ce) + { + const UInt8 *current_bbt = bbt + (bbt_size_per_ce * ce); + for (die = 0; die < die_per_ce; ++die) + { + const UInt32 bbt_die_offset = die * blocks_per_die; + for (block = 0; block < blocks_per_die; ++block) + { + UInt32 physical_block = (die << die_addr_bits) | block; + + if ((NULL == bbt) || IS_BLOCK_GOOD(current_bbt, bbt_die_offset + block)) + { + printf("ce %d block 0x%08x\r", ce, physical_block); + if (FIL_SUCCESS != (nand_status = fil->Erase(ce, physical_block))) + { + printf("erase failed 0x%08x ce %d block 0x%08x\n", + nand_status, ce, physical_block); + } + } + else + { + printf("skipping ce %d block 0x%08x\n", ce, physical_block); + } + } + } + } + + free(bbt); + printf("done with %d blocks\n", (num_ce * die_per_ce * blocks_per_die)); + + return 0; +} + +static int nand_erase(UInt32 ce, UInt32 block, UInt32 num_blocks) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + Int32 nand_status; + int err = 0; + + if (NULL == fil->Erase) + { + printf("erase is not supported\n"); + return -1; + } + + printf("Erase ce %d block %d to block %d\n", ce, block, block + num_blocks - 1); + while(num_blocks > 0) + { + nand_status = fil->Erase(ce, block); + if (FIL_SUCCESS != nand_status) + { + printf("erase failed 0x%08x ce %d block %d\n", nand_status, ce, block); + } + block++; + num_blocks--; + } + + return err; +} + +static int write(UInt32 ce, UInt32 base_page, UInt32 num_pages, void *buffer, UInt32 delay_ms, UInt32 disable_whitening, BOOL32 pattern_present, UInt32 pattern) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + const UInt32 main_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 meta_size = fil->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + const UInt32 bytes_per_write = main_size + meta_size; + UInt8 *cursor = buffer; + UInt8 *meta_cursor = cursor + (main_size * num_pages); + int err = 0; + UInt32 page_offset; + UInt32 nand_status; + UInt32 *data_ptr = NULL; + + if (!security_allow_memory(buffer, num_pages * bytes_per_write)) + { + printf("Permission Denied\n"); + return -1; + } + + if (NULL == fil->Write) + { + printf("Write not available. Set H2FMI_DEBUG and WMR_IBOOT_WRITE_ENABLE to 1.\n"); + return -1; + } + + if ((num_pages > fil->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK)) || ((base_page % fil->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK)) != 0)) + { + printf("Pages only in one block can be programmed at a time starting from the first page\n"); + return -1; + } + + if(NULL == buffer) + { + cursor = malloc(main_size + meta_size); + data_ptr = (UInt32 *) cursor; + //set data pattern + UInt32 idx; + meta_cursor = cursor + main_size; + *((UInt32 *) meta_cursor) = base_page; + + for(idx = 1; idx < (meta_size / sizeof(UInt32)); idx++) + { + *((UInt32 *) meta_cursor + idx) = WMR_RAND(); + } + + if(pattern_present) + { + printf("writing data pattern : 0x%X\n", pattern); + for(idx = 0; idx < (main_size / sizeof(UInt32)); idx++) + { + data_ptr[idx] = pattern; + } + } + else + { + printf("writing random data pattern\n"); + for(idx = 0; idx < (main_size / sizeof(UInt32)); idx++) + { + data_ptr[idx] = WMR_RAND() % 0xffffffff; + } + } + } + + if(delay_ms) + { + nand_erase(ce, base_page/fil->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK), 1); + WMR_SLEEP_US(delay_ms * 1000); + } + + printf("write ce %d base page %d (0x%08x) #pages %d\n", ce, base_page, base_page, num_pages); + + for (page_offset = 0; page_offset < num_pages; ++page_offset) + { + UInt32 current_page = base_page + page_offset; + + if (FIL_SUCCESS != (nand_status = fil->Write(ce, current_page, cursor, meta_cursor, (disable_whitening ? TRUE32 : FALSE32)))) + { + printf("error 0x%08x writing ce %d page %d\n", nand_status, ce, current_page); + err = -1; + } + if (cursor != (UInt8 *)data_ptr) + { + cursor += main_size; + meta_cursor += meta_size; + } + else + { + *((UInt32 *) meta_cursor) = current_page + 1; + } + } + if(NULL != data_ptr) + { + free(data_ptr); + } + return err; +} + +static int write_bl_pages(UInt32 ce, UInt32 base_page, void *buffer, size_t len) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + Int32 nand_status; + int err = 0; + UInt32 page_idx; + const size_t bl_page_size = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_BL_PAGE); + const UInt32 num_pages = len / bl_page_size; + UInt8 *cursor = buffer; + + if (NULL == fil->WriteBLPage) + { + printf("write boot page is not supported\n"); + return -1; + } + + if (((len % bl_page_size) != 0) && (num_pages > 0)) + { + printf("payload must be a multiple of %zu\n", bl_page_size); + return -1; + } + + if (!security_allow_memory(buffer, num_pages * bl_page_size)) + { + printf("Permission Denied\n"); + return -1; + } + + printf("Writing Boot Pages to CE %d from %d to %d\n", ce, base_page, base_page + num_pages - 1); + + for (page_idx = 0; page_idx < num_pages; ++page_idx) + { + const UInt32 current_page = base_page + page_idx; + nand_status = fil->WriteBLPage(ce, current_page, cursor); + if (FIL_SUCCESS != nand_status) + { + printf("Error 0x%x programming ce %d page %d\n", nand_status, ce, current_page); + err = -1; + break; + } + cursor += bl_page_size; + } + + return err; +} + +static void usage(void) +{ + LowFuncTbl *fil = FIL_GetFuncTbl(); + UInt32 lbasPerPage = fil->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + + printf("nand read []\n"); + printf("nand readraw []\n"); + printf("nand readboot []\n"); +#if WITH_NAND_DEBUG + printf("nand writeboot [ ]\n"); + printf("nand erase \n"); + printf("nand write [] [32 bit data pattern]\n"); + printf(" (if delay=0, then no erase before program), random pattern used if no pattern specified. load_addr ignored if pattern specified\n"); + printf(" (Pages only in one block can be programmed at a time starting from the first page)\n"); +#endif // WITH_NAND_DEBUG + printf("nand inspect \n"); + printf("nand bbt\n"); + printf("nand l2p \n"); + if ( 1 == lbasPerPage) //different usage for swiss vs yaFTL + { + printf("nand v2p \n"); + printf("nand sbCycles []\n"); + } + else + { + printf("nand sbCycles []\n"); + printf("nand v2p \n"); + } + printf("nand reset\n"); + printf("nand info\n"); + printf("nand params\n"); + printf("nand getstats\n"); + printf("nand getphyce\n"); + printf("nand r2cbp (converts row address to cau, blk, pg offset)\n"); + printf("nand cbp2r (converts to cau, blk, pg offset to row address)\n"); + printf("nand read4k []\n"); +} + +static int do_nand(int argc, struct cmd_arg *args) +{ + void *buffer; + size_t buffer_len; + int err = 0; + const char *cmd; + + if (argc < 2) + { + usage(); + return 0; + } + + buffer = (void *) env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + buffer_len = (size_t) env_get_uint("filesize", 0); + cmd = args[1].str; + + if (!strcmp(cmd, "info")) + { + (void) buffer; + err = nand_info(); + } + else if (!strcmp(cmd, "params")) + { + err = h2fmiPrintParameters(); + } + else if (!strcmp(cmd, "bbt")) + { + err = print_raw_bbt(); + } +#if WITH_NAND_DEBUG + else if(!strcmp(cmd, "nuke")) + { + bool force = argc > 2 ? true : false; + err = nuke(force); + } + else if(!strcmp(cmd, "erase")) + { + if (argc < 5) + { + return -1; + } + err = nand_erase(args[2].u, args[3].u, args[4].u); + } + else if (!strcmp(cmd, "write")) + { + UInt32 delay_ms = 6 <= argc ? args[5].u : 0; + UInt32 disable_whitening = 7 <= argc ? args[6].u : 0; + BOOL32 pattern_present = 9 <= argc ? TRUE32 : FALSE32; + UInt32 pattern = 9 <= argc ? args[8].u : 0; + buffer = 8 == argc ? (void*)args[7].u : NULL; + + if (argc < 5) + { + usage(); + return -1; + } + + err = write(args[2].u, args[3].u, args[4].u, buffer, delay_ms, disable_whitening, pattern_present, pattern); + } +#endif + else if (!strcmp(cmd, "inspect")) + { + if (argc != 5) + { + usage(); + return -1; + } + err = inspect_blocks(args[2].u, args[3].u, args[4].u); + } + else if (!strcmp(cmd, "readraw")) + { + if (argc < 5) + { + usage(); + return -1; + } + else if (argc > 5) + { + buffer = (void*) args[5].u; + } + err = raw_read(args[2].u, args[3].u, args[4].u, buffer); + } + else if (!strcmp(cmd, "read")) + { + if (argc < 7) + { + usage(); + return -1; + } + else if (argc > 7) + { + buffer = (void*) args[7].u; + } + err = read_with_ecc(args[2].u, args[3].u, args[4].u, args[5].b, args[6].b, buffer); + } +#if WITH_PPN + else if (!strcmp(cmd, "read4k")) + { + if (argc < 8) + { + usage(); + return -1; + } + else if (argc > 8) + { + buffer = (void*) args[8].u; + } + err = read4k(args[2].u, args[3].u, args[4].u, args[5].u, args[6].u, args[7].u, buffer); + } + else if (!strcmp(cmd, "cbp2r")) + { + if (argc < 5) + { + usage(); + return -1; + } + err = cbp2r(args[2].u, args[3].u, args[4].u); + } + else if (!strcmp(cmd, "r2cbp")) + { + if (argc < 3) + { + usage(); + return -1; + } + err = r2cbp(args[2].u); + } +#endif // WITH_PPN + else if (!strcmp(cmd, "readboot")) + { + if (argc < 5) + { + usage(); + return -1; + } + else if (argc > 5) + { + buffer = (void*) args[5].u; + } + err = read_bl_pages(args[2].u, args[3].u, args[4].u, buffer); + } + else if (!strcmp(cmd, "sbCycles")) + { + UInt16 pagesPerSB; + UInt32 vba,vpn; + UInt32 sbIndex; + UInt16 *eraseCntBuf; + UInt16 listLen; + UInt32 size; + bool printSingle = false; + LowFuncTbl *fil = FIL_GetFuncTbl(); + UInt32 lbasPerPage; + + lbasPerPage = fil->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + + size = sizeof(listLen); + if( !ctrl_io(AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS, &listLen, &size) ) + { + return -1; + } + + if (argc > 2) + { + size = sizeof(pagesPerSB); + if (!ctrl_io(AND_STRUCT_VFL_PAGES_PER_SUBLK, &pagesPerSB, &size)) + { + return -1; + } + + vba = args[2].u; + vpn = (lbasPerPage !=0)? vba / lbasPerPage: vba; + sbIndex = vpn / (UInt32)pagesPerSB; + if (sbIndex < listLen) + { + printSingle = true; + } + else + { + printf("sbIndex=%d out of bounds in array length %d (%d pages per SB)\n", + sbIndex,listLen,pagesPerSB); + } + } + + size = sizeof(UInt16)*listLen; + eraseCntBuf = malloc(size); + memset(eraseCntBuf, 0xFF,size); + if ( ctrl_io(AND_STRUCT_FTL_SB_CYCLES, eraseCntBuf, &size) ) + { + if (printSingle) + { + printf("vba: 0x%08x vpn: 0x%08x sb: %d cycles: %d\n", vba, vpn, sbIndex, eraseCntBuf[sbIndex]); + } + else + { + printf("numSBs: %d\n",listLen); + for (sbIndex=0; sbIndex < listLen; sbIndex++) + { + printf("sb: %d cycles: %d\n", sbIndex, (UInt32)(eraseCntBuf[sbIndex])); + } + } + } + else + { + printf("Error: unable to get NAND Cycle Count\n"); + err = -1; + } + + free(eraseCntBuf); + } +#if WITH_PPN + else if (!strcmp(cmd, "getstats")) + { + err = get_stats(buffer); + } + else if(!strcmp(cmd, "getphyce")) + { + err = get_physical_ce(); + } +#endif //WITH_PPN +#if WITH_NAND_DEBUG + else if (!strcmp(cmd, "writeboot")) + { + if ((argc < 3) || (argc == 5)) + { + usage(); + return -1; + } + if (argc > 4) + { + buffer = (void*) args[4].u; + buffer_len = (size_t) args[5].u; + } + err = write_bl_pages(args[2].u, args[3].u, buffer, buffer_len); + } +#endif // WITH_NAND_DEBUG + else if(!strcmp(cmd, "reset")) + { + LowFuncTbl *fil = FIL_GetFuncTbl(); + fil->Reset(); + printf("NAND reset complete\n"); + } + else if (!strcmp(cmd, "l2p")) + { + ANDAddressStruct addr; + UInt32 size = sizeof(addr); + LowFuncTbl *fil = FIL_GetFuncTbl(); + UInt32 lbasPerPage; + + if (argc < 3) + { + usage(); + return -1; + } + + fil = FIL_GetFuncTbl(); + lbasPerPage = fil->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + + memset(&addr, 0, size); + addr.dwLpn = args[2].u; + if (ctrl_io(AND_STRUCT_FTL_GETADDRESS, &addr, &size)) + { + if (1 == lbasPerPage) + printf("vpn: 0x%08x ce: %d ppn: 0x%08x\n", + addr.dwVpn, addr.dwCS, addr.dwPpn); + else + printf("vba: 0x%08x ce: %d ppn: 0x%08x\n", + addr.dwVpn, addr.dwCS, addr.dwPpn); + + } + else + { + err = -1; + } + } + else if (!strcmp(cmd, "v2p")) + { + ANDAddressStruct addr; + UInt32 size = sizeof(addr); + + if (argc < 3) + { + usage(); + return -1; + } + memset(&addr, 0, size); + addr.dwVpn = args[2].u; + if (ctrl_io(AND_STRUCT_VFL_GETADDRESS, &addr, &size)) + { + printf("ce: %d ppn: 0x%08x\n", + addr.dwCS, addr.dwPpn); + } + else + { + err = -1; + } + } + else + { + printf("unsupported operation: %s\n", args[1].str); + usage(); + err = -1; + } + + return err; +} + +MENU_COMMAND_DEVELOPMENT(nand, do_nand, "physical nand commands", NULL); + + +#endif // !RELEASE_BUILD && WITH_MENU diff --git a/drivers/flash_nand/ftl/nand.c b/drivers/flash_nand/ftl/nand.c new file mode 100644 index 0000000..b940240 --- /dev/null +++ b/drivers/flash_nand/ftl/nand.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include + +#include "FIL.h" +#include "ANDTypes.h" +#include "WMRConfig.h" +#include "WMROAM.h" + +extern int ppn_init(void); +extern int raw_nand_init(void); + +uint32_t nand_fsys_block_offset = WMR_BOOT_AREA_DEFAULT_SIZE; + +int flash_nand_init(void) +{ + int ret = -1; + LowFuncTbl *fil; + + dprintf(DEBUG_INFO, "flash_nand_init()\n"); + + /* FIL_Init was already executed when flash_nand_id() was called in platform_late_init() */ + fil = FIL_GetFuncTbl(); + if ((NULL == fil) || (NULL == fil->GetDeviceInfo)) + { + dprintf(DEBUG_INFO, "GetDeviceInfo not populated\n"); + return -1; + } + +#if WITH_PPN + if (fil->GetDeviceInfo(AND_DEVINFO_PPN_DEVICE) > 0) + { + ret = ppn_init(); + } +#if WITH_RAW_NAND + else +#endif // HAS_RAW_NAND +#endif +#if WITH_RAW_NAND + { + ret = raw_nand_init(); + } +#endif + +#if (!WITH_RAW_NAND && !WITH_PPN) +#error nand.c included without a raw or ppn stack +#endif + + return ret; +} + diff --git a/drivers/flash_nand/ftl/rules.mk b/drivers/flash_nand/ftl/rules.mk new file mode 100644 index 0000000..30a3078 --- /dev/null +++ b/drivers/flash_nand/ftl/rules.mk @@ -0,0 +1,22 @@ +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_NAND_FILESYSTEM=1 + +MODULES += \ + drivers/flash_nand + +ALL_OBJS += \ + $(LOCAL_DIR)/nand.o + +WITH_NAND_FTL := true diff --git a/drivers/flash_nand/id/nandid.c b/drivers/flash_nand/id/nandid.c new file mode 100644 index 0000000..b06059c --- /dev/null +++ b/drivers/flash_nand/id/nandid.c @@ -0,0 +1,723 @@ +// Copyright (C) 2008-2009 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// + +#include "WMRFeatures.h" +#if WMR_BUILDING_IBOOT +#include "nandid.h" +#include +#include +#include +#include +#else +#include "NandSpec.h" +#include "NandSpecTables.h" +#endif + +#include "WMROAM.h" +#include "FIL.h" + +// ============================================================================= +// Preprocessor Definitions + +#define WITH_NAND_DT_CONFIG (WITH_NAND_FILESYSTEM && WITH_DEVICETREE) + +// ============================================================================= +// Extern global variables + +// ============================================================================= +// Private Function Declarations + +static BOOL32 isSameChipId(const NandChipId chipId1, const NandChipId chipId2); +static BOOL32 isSameConfigId(const NandConfigId* configId1, const NandConfigId* configId2); + +static const NandGeometry* lookupNandGeometry(const NandChipId chipId); +static const NandTiming* lookupNandTiming(const NandConfigId* configId); +static const NandBoardSupport* lookupBoardSupport(const NandConfigId* configId); +static BOOL32 isValidChipId(const NandChipId chipId); +static BOOL32 getChipIdAndTotalCECountAndCEMap(const NandChipId* chipIds, NandChipId* foundChipId, UInt32* totalCECount, UInt32* ceMap); +static BOOL32 areChipIdsIdentical(const NandChipId* chipIds, NandChipId* chipId); +static UInt32 setBitCount(UInt32 x); +static BOOL32 checkCESymmetryAndGetPackageCnt(NandLandingMap *landingMap, UInt32 ceMap, UInt8* pkgCnt); + +// ============================================================================= +// Private Global Variables +#if WITH_NAND_DT_CONFIG +static NandInfo currentNandInfo; +static UInt32 currentCECount = 0; +static UInt32 currentCEBitmap = 0; +static UInt32 currentActiveDataBus = 0; +#endif //WITH_NAND_DT_CONFIG +static UInt32 currentCorrectableBits = 0; +static UInt32 currentRefreshThreshold = 0; +static BOOL32 ppnDevice = FALSE32; +static BOOL32 toggleDevice = FALSE32; +static BOOL32 _retire_on_invalid_refresh; +static void *_ppn_feature_list = NULL; +static UInt32 _ppn_feature_size = 0; +static void *_dbg_chipids_list = NULL; +static UInt32 _dbg_chipids_size = 0; + +static UInt32 _dqsHalfCycleClocks; +static UInt32 _ceSetupClocks; +static UInt32 _ceHoldClocks; +static UInt32 _ADLClocks; +static UInt32 _WHRClocks; + +static UInt32 _readPreClocks; +static UInt32 _readPostClocks; +static UInt32 _writePreClocks; +static UInt32 _writePostClocks; + +static UInt32 _readSetupClocks; +static UInt32 _readHoldClocks; +static UInt32 _readDccycleClocks; +static UInt32 _writeSetupClocks; +static UInt32 _writeHoldClocks; + +static UInt32 _regDQSTimingCtrl; + +// ============================================================================= +// Local constants + + +// ============================================================================= +// Private Function Definitions + +// compare the contents of a buffer to the given value, repeated +static BOOL32 comparePattern(const UInt8 *buffer, UInt8 value, UInt32 length) +{ + UInt32 idx; + + for (idx = 0; idx < length; ++idx) + { + if (buffer[idx] != value) + { + return FALSE32; + } + + } + + return TRUE32; +} + +static BOOL32 isSameChipId(const NandChipId chipId1, + const NandChipId chipId2) +{ + UInt32 idx; + // Treat 0x00 as dont-care + for (idx = 0; idx < COMPARE_NAND_CHIP_ID_SIZE; ++idx) + { + if (chipId1[idx] && chipId2[idx] && (chipId1[idx] != chipId2[idx])) + { + return FALSE32; + } + } + return TRUE32; +} + +static BOOL32 isSameConfigId(const NandConfigId* configId1, + const NandConfigId* configId2) +{ + if (0 == WMR_MEMCMP(configId1, configId2, sizeof(NandConfigId))) + { + return TRUE32; + } + else + { + return FALSE32; + } +} + +static const NandGeometry* lookupNandGeometry(const NandChipId chipId) +{ + UInt32 count = sizeof(_nandGeometryTable) / sizeof(_nandGeometryTable[0]); + UInt32 idx; + + for (idx = 0; idx < count; idx++) + { + const NandGeometry* geometry = &_nandGeometryTable[idx]; + if (isSameChipId(chipId, geometry->chipId)) + { + return geometry; + } + } + + return NULL; +} + +#if AND_ENABLE_NAND_DESCRIPTION_TEXT +static const NandDescription* lookupNandDescription(const NandPackageId* packageId) +{ + UInt32 idx; + + for (idx = 0; idx < _nandDescriptionTableSize; idx++) + { + const NandDescription* description = &_nandDescriptionTable[idx]; + if (isSamePackageId(packageId, &(description->packageId))) + { + return description; + } + } + + return NULL; +} +#endif + +static const NandTiming* lookupNandTiming(const NandConfigId* configId) +{ + UInt32 count = sizeof(_nandTimingTable) / sizeof(_nandTimingTable[0]); + UInt32 idx; + + for (idx = 0; idx < count; idx++) + { + const NandTiming* timing = &_nandTimingTable[idx]; + if (isSameConfigId(configId, &(timing->configId))) + { + return timing; + } + } + + return NULL; +} + +static const NandBoardSupport* lookupBoardSupport(const NandConfigId* configId) +{ + UInt32 count = sizeof(_nandBoardSupportTable) / sizeof(_nandBoardSupportTable[0]); + UInt32 idx; + + for (idx = 0; idx < count; idx++) + { + const NandBoardSupport* support = &_nandBoardSupportTable[idx]; + if (isSameConfigId(configId, &(support->configId))) + { + return support; + } + } + + return NULL; +} + +static BOOL32 isValidChipId(NandChipId const chipId) +{ + if (comparePattern(&chipId[0], 0x00, NAND_CHIP_ID_SIZE) || + comparePattern(&chipId[0], 0xFF, NAND_CHIP_ID_SIZE)) + { + return FALSE32; + } + else + { + return TRUE32; + } +} + +static BOOL32 getChipIdAndTotalCECountAndCEMap(const NandChipId* chipIds, NandChipId* foundChipId, UInt32* totalCECount, UInt32* ceMap) +{ + BOOL32 found = FALSE32; + UInt32 i; + + *ceMap = 0; + *totalCECount = 0; + + for (i = 0; i < NAND_MAX_CE_COUNT_TOTAL; i++) + { + if (isValidChipId(chipIds[i])) + { + if (!found) + { + WMR_MEMSET(foundChipId, 0, sizeof(NandChipId)); + WMR_MEMCPY(foundChipId, chipIds[i], VALID_NAND_CHIP_ID_SIZE); + found = TRUE32; + } + (*totalCECount)++; + (*ceMap) |= (1 << i); + } + + } + + return found; +} + +static BOOL32 areChipIdsIdentical(const NandChipId* chipIds, NandChipId* chipId) +{ + UInt32 i; + + for (i = 0; i < NAND_MAX_CE_COUNT_TOTAL; i++) + { + if (isValidChipId(chipIds[i]) && (!isSameChipId(*chipId, chipIds[i]))) + { + return FALSE32; + } + } + + return TRUE32; +} + +static UInt32 setBitCount(UInt32 x) +{ + // Count the ones + UInt32 cnt = 0; + + while (x) + { + if (x & 1) + { + cnt++; + } + x = x >> 1; + } + return cnt; +} + +static BOOL32 checkCESymmetryAndGetPackageCnt(NandLandingMap *landingMap, UInt32 ceMap, UInt8* pkgCnt) +{ + UInt32 mask; + UInt32 i = 0; + UInt32 cePerPkg = setBitCount((*landingMap)[0] & ceMap); + + *pkgCnt = 0; + + do + { + mask = (*landingMap)[i]; + + if (mask & ceMap) + { + if (cePerPkg != setBitCount(mask & ceMap)) + { + return FALSE32; + } + (*pkgCnt)++; + } + i++; + } + while (mask != 0); + + return TRUE32; +} + +// ============================================================================= +// Public Function Definitions +BOOL32 findNandInfo(const NandChipId* chipIds, + NandInfo* nandInfo, + const UInt32 numActiveDataBus) +{ + NandConfigId detectedConfigId; + NandChipId chipId; + UInt32 totalCECount; + UInt32 ceMap; + UInt32 i; + + nandInfo->boardInfo = &_nandBoardInfo; + nandInfo->boardSupport = NULL; + nandInfo->configTiming = NULL; + nandInfo->format = &_nandFormatRaw; + + WMR_MEMSET(&detectedConfigId, 0, sizeof(NandConfigId)); + + if (!getChipIdAndTotalCECountAndCEMap(chipIds, &chipId, &totalCECount, &ceMap)) + { + WMR_PRINT(INIT, "No NAND Detected\n"); + return FALSE32; + } + + if (!areChipIdsIdentical(chipIds, &chipId)) + { + WMR_PRINT(INIT, "Chip IDs not identical!\n"); + return FALSE32; + } + + if (!checkCESymmetryAndGetPackageCnt(&_nandBoardInfo.landingMap, ceMap, &(detectedConfigId.packageCnt))) + { + WMR_PRINT(INIT, "Chip IDs not symmetrical!\n"); + return FALSE32; + } + + detectedConfigId.connectedBusCnt = numActiveDataBus; + + nandInfo->geometry = lookupNandGeometry(chipId); + + if (!nandInfo->geometry) + { + WMR_PRINT(INIT, "Unknown Chip ID!\n"); + return FALSE32; + } + + for (i = 0; i < detectedConfigId.packageCnt; i++) + { + WMR_MEMCPY(&(detectedConfigId.packageIds[i].chipId), nandInfo->geometry->chipId, sizeof(NandChipId)); + detectedConfigId.packageIds[i].ceCnt = totalCECount / detectedConfigId.packageCnt; + } + + nandInfo->boardSupport = lookupBoardSupport(&detectedConfigId); + nandInfo->configTiming = lookupNandTiming(&detectedConfigId); + + if (!nandInfo->boardSupport) + { + WMR_PRINT(INIT, "Board support not found!\n"); + return FALSE32; + } + + if (!nandInfo->configTiming) + { + WMR_PRINT(INIT, "Nand timing not found!\n"); + return FALSE32; + } + +#if WITH_NAND_DT_CONFIG + currentNandInfo = *nandInfo; + currentCECount = totalCECount; + currentCEBitmap = ceMap; + currentActiveDataBus = numActiveDataBus; +#endif //WITH_NAND_DT_CONFIG + + return TRUE32; +} + +void setECCLevels(UInt32 numCorrectableBits, UInt32 refreshThresholdBits) +{ + currentCorrectableBits = numCorrectableBits; + currentRefreshThreshold = refreshThresholdBits; +} + +#if WITH_NAND_DT_CONFIG +void addNandProperty(DTNode *node, char *name, uint32_t value) +{ + uint32_t propSize = 0; + void *propData = NULL; + + if (FindProperty(node, &name, &propData, &propSize) && + (propSize == sizeof(value))) + { + *(uint32_t*)propData = value; + } + else + { + WMR_PRINT(ERROR, "Failed to find NAND property: %s\n", name); + } +} + +static void fillPpnFeatures(DTNode *node) +{ + char *propName = "ppn-features"; + void *propData = NULL; + UInt32 propSize = 0; + UInt32 totalSize = sizeof(_ppn_feature_size) + _ppn_feature_size; + UInt8 *cursor; + + if (!FindProperty(node, &propName, &propData, &propSize) || + (totalSize > propSize)) + { + WMR_PANIC("expected device tree property %s of at least %u bytes", propName, (unsigned)totalSize); + } + + cursor = propData; + + WMR_MEMCPY(cursor, &_ppn_feature_size, sizeof(_ppn_feature_size)); + cursor += sizeof(_ppn_feature_size); + + WMR_MEMCPY(cursor, _ppn_feature_list, _ppn_feature_size); + cursor += _ppn_feature_size; +} + +static void fillNandPpnProperties(DTNode *node) +{ + const NandPpn *ppn = currentNandInfo.ppn; + + addNandProperty(node, "ppn-spec-version", ppn->specVersion); + addNandProperty(node, "blocks-cau", ppn->blocksPerCau); + addNandProperty(node, "caus-ce", ppn->causPerCe); + addNandProperty(node, "slc-pages", ppn->slcPagesPerBlock); + addNandProperty(node, "mlc-pages", ppn->mlcPagesPerBlock); + addNandProperty(node, "match-oddeven-caus", ppn->matchOddEvenCaus); + addNandProperty(node, "cau-bits", ppn->bitsPerCau); + addNandProperty(node, "page-bits", ppn->bitsPerPage); + addNandProperty(node, "block-bits", ppn->bitsPerBlock); + addNandProperty(node, "max-transaction-size", ppn->maxTransactionSize); + + fillPpnFeatures(node); +} + +static void fillDbgChipIds(DTNode *node) +{ + char *propName = "dbg-chipids"; + void *propData = NULL; + UInt32 propSize = 0; + UInt32 totalSize = _dbg_chipids_size; + UInt8 *cursor; + + if (NULL == _dbg_chipids_list) + { + goto exit; + } + + if (!FindProperty(node, &propName, &propData, &propSize) || + (totalSize > propSize)) + { + WMR_PRINT(ERROR, "expected device tree property %s of at least %lu bytes", propName, totalSize); + goto exit; + } + + cursor = propData; + + WMR_MEMCPY(cursor, _dbg_chipids_list, _dbg_chipids_size); + cursor += _dbg_chipids_size; + +exit: + + return; +} + +void fillNandConfigProperties(DTNode *node) +{ + uint32_t propSize = 0; + void *propData = NULL; + char *propName = NULL; + + if (0 == currentCECount) { + fillDbgChipIds(node); + return; + } + + // Configuration + addNandProperty(node, "#ce", currentCECount); + addNandProperty(node, "ce-bitmap", currentCEBitmap); + + propName = "device-readid"; + if (FindProperty(node, &propName, &propData, &propSize) && + (propSize == NAND_CHIP_ID_SIZE)) + { + WMR_MEMCPY(propData, currentNandInfo.geometry->chipId, NAND_CHIP_ID_SIZE); + } + + // Geometry + addNandProperty(node, "#databus", currentActiveDataBus); + addNandProperty(node, "#ce-blocks", currentNandInfo.geometry->blocksPerCS); + addNandProperty(node, "#block-pages", currentNandInfo.geometry->pagesPerBlock); + addNandProperty(node, "#page-bytes", currentNandInfo.geometry->dataBytesPerPage); + addNandProperty(node, "#spare-bytes", currentNandInfo.geometry->spareBytesPerPage); + addNandProperty(node, "#die-ce", currentNandInfo.geometry->diesPerCS); + + // Formatting + addNandProperty(node, "bbt-format", currentNandInfo.geometry->initialBBType); + addNandProperty(node, "vendor-type", currentNandInfo.boardSupport->vsType); + addNandProperty(node, "ecc-threshold", currentRefreshThreshold); + addNandProperty(node, "ecc-correctable", currentCorrectableBits); + + // Bus Timing + addNandProperty(node, "read-setup-clks", _readSetupClocks); + addNandProperty(node, "read-hold-clks", _readHoldClocks); + addNandProperty(node, "read-dccycle-clks", _readDccycleClocks); + addNandProperty(node, "write-setup-clks", _writeSetupClocks); + addNandProperty(node, "write-hold-clks", _writeHoldClocks); + + // NAND Format parameters + addNandProperty(node, "meta-per-logical-page", currentNandInfo.format->metaPerLogicalPage); + addNandProperty(node, "valid-meta-per-logical-page", currentNandInfo.format->validMetaPerLogicalPage); + if (currentNandInfo.format->logicalPageSize == 0) + { + // Use native page size + UInt32 pageSize = currentNandInfo.geometry->dataBytesPerPage; + addNandProperty(node, "logical-page-size", pageSize); + } + else + { + addNandProperty(node, "logical-page-size", currentNandInfo.format->logicalPageSize); + } + + if (toggleDevice) + { + addNandProperty(node, "toggle-device", 1); + addNandProperty(node, "enable-diff-dqs", _nandBoardInfo.useDiffDQSMode); + addNandProperty(node, "enable-diff-re", _nandBoardInfo.useDiffREMode); + addNandProperty(node, "enable-vref", _nandBoardInfo.useVref); + + addNandProperty(node, "dqs-half-cycle-clks", _dqsHalfCycleClocks); + + addNandProperty(node, "ce-setup-clks", _ceSetupClocks); + addNandProperty(node, "ce-hold-clks", _ceHoldClocks); + addNandProperty(node, "adl-clks", _ADLClocks); + addNandProperty(node, "whr-clks", _WHRClocks); + + addNandProperty(node, "read-pre-clks", _readPreClocks); + addNandProperty(node, "read-post-clks", _readPostClocks); + addNandProperty(node, "write-pre-clks", _writePreClocks); + addNandProperty(node, "write-post-clks", _writePostClocks); + + addNandProperty(node, "reg-dqs-delay", _regDQSTimingCtrl); + } + else + { + addNandProperty(node, "toggle-device", 0); + } + + if (ppnDevice == TRUE32) + { + addNandProperty(node, "ppn-device", 1); + fillNandPpnProperties(node); + } + else + { + addNandProperty(node, "ppn-device", 0); + } + + addNandProperty(node, "retire-on-invalid-refresh", _retire_on_invalid_refresh); + +} + +#endif //WITH_NAND_CONFIG + +void reportToggleModeFMCTimingValues(UInt32 dqsHalfCycleClocks, + UInt32 ceSetupClocks, + UInt32 ceHoldClocks, + UInt32 adlClocks, + UInt32 whrClocks, + UInt32 readPreClocks, + UInt32 readPostClocks, + UInt32 writePreClocks, + UInt32 writePostClocks, + UInt32 regDQSTimingCtrl) +{ + _dqsHalfCycleClocks = dqsHalfCycleClocks; + _ceSetupClocks = ceSetupClocks; + _ceHoldClocks = ceHoldClocks; + _ADLClocks = adlClocks; + _WHRClocks = whrClocks; + _readPreClocks = readPreClocks; + _readPostClocks = readPostClocks; + _writePreClocks = writePreClocks; + _writePostClocks = writePostClocks; + _regDQSTimingCtrl = regDQSTimingCtrl; +} + +void setToggleMode() +{ + toggleDevice = TRUE32; +} + + +void reportFMCTimingValues(UInt32 readSetupClocks, + UInt32 readHoldClocks, + UInt32 readDccycleClocks, + UInt32 writeSetupClocks, + UInt32 writeHoldClocks) +{ + _readSetupClocks = readSetupClocks; + _readHoldClocks = readHoldClocks; + _readDccycleClocks = readDccycleClocks; + _writeSetupClocks = writeSetupClocks; + _writeHoldClocks = writeHoldClocks; +} + +void setNandIdPpnConfig(const NandChipId* chipIds, + NandInfo* nandInfo, + UInt32 busses, + UInt32 ces) +{ +#if WITH_NAND_DT_CONFIG + currentActiveDataBus = busses; + currentNandInfo = *nandInfo; + + getChipIdAndTotalCECountAndCEMap(chipIds, (NandChipId*)¤tNandInfo.geometry->chipId, ¤tCECount, ¤tCEBitmap); + WMR_ASSERT(ces == currentCECount); +#endif //WITH_NAND_DT_CONFIG + nandInfo->format = &_nandFormatPpn; + ppnDevice = TRUE32; +} + +void setPPNOptions(BOOL32 retire_on_invalid_refresh) +{ + _retire_on_invalid_refresh = retire_on_invalid_refresh; +} + +void reportPpnFeatures(void *list, UInt32 size) +{ + _ppn_feature_list = list; + _ppn_feature_size = size; +} + +void reportDbgChipIds(void *list, UInt32 size) +{ + _dbg_chipids_list = list; + _dbg_chipids_size = size; +} + +// Bitmap of valid CEs (all CEs are identical to CE0) gets cross-checked +// against landing map from nand table +// If a valid CE bit is set on an invalid landing bit, returns error +BOOL32 checkPpnLandingMap(UInt32 validCEMap) +{ + NandLandingMap *landingMap; + UInt32 i = 0; + UInt32 current; + UInt32 intersect, remainder; + + landingMap = &_nandBoardInfo.landingMap; + remainder = validCEMap; + + do { + current = (*landingMap)[i]; + intersect = remainder & current; + remainder &= ~intersect; + i++; + } while ((current != 0) && (remainder != 0)); + + if (remainder != 0) + { + WMR_PRINT(ERROR, "Valid CE bit detected on an invalid landing bit!\n"); + return FALSE32; + } + return TRUE32; +} + +const NandFormat * getPPNFormat(void) +{ + return &_nandFormatPpn; +} + +BOOL32 targetSupportsToggle(void) +{ + return _nandBoardInfo.useToggleMode ? TRUE32 : FALSE32; +} + +BOOL32 targetSupportsDiffDQS(void) +{ + return _nandBoardInfo.useDiffDQSMode ? TRUE32 : FALSE32; +} + +BOOL32 targetSupportsDiffRE(void) +{ + return _nandBoardInfo.useDiffREMode ? TRUE32 : FALSE32; +} + +BOOL32 targetSupportsVREF(void) +{ + return _nandBoardInfo.useVref ? TRUE32 : FALSE32; +} + +BOOL32 targetSupportsSHC(void) +{ + return _nandBoardInfo.useSingleHostChannel; +} + +BOOL32 targetSupportsSingleCE(void) +{ + return _nandBoardInfo.allowSingleChipEnable; +} + +// Run only NAND chip identification +int flash_nand_id(void) +{ + OAM_Init(); + + if (FIL_SUCCESS != FIL_Init()) + return -1; + + return 0; +} diff --git a/drivers/flash_nand/id/nandid.h b/drivers/flash_nand/id/nandid.h new file mode 100644 index 0000000..f9b3ab3 --- /dev/null +++ b/drivers/flash_nand/id/nandid.h @@ -0,0 +1,311 @@ +// Copyright (C) 2008-2009 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// + +#include "ANDTypes.h" +#include "WMRTypes.h" +#include "WMRFeatures.h" +#if WMR_BUILDING_IBOOT +#include +#endif + +#ifndef _NANDID_H_ +#define _NANDID_H_ + +// ============================================================================= +// Preprocessor Constants + +#define NAND_CHIP_ID_SIZE (8) +#define VALID_NAND_CHIP_ID_SIZE (6) +#define COMPARE_NAND_CHIP_ID_SIZE (4) +#define LEGACY_NAND_CHIP_ID_SIZE (4) + +#define NAND_MAX_CE_COUNT_PER_PACKAGE (8) +#define NAND_MAX_PACKAGES_PER_CONFIG (2) +#define NAND_MAX_CE_COUNT_TOTAL (NAND_MAX_PACKAGES_PER_CONFIG * NAND_MAX_CE_COUNT_PER_PACKAGE) + +#define NAND_MAX_APPLE_NAME_SIZE (20) +#define NAND_MAX_VENDOR_NAME_SIZE (20) +#define NAND_MAX_PACKAGE_TYPE_SIZE (20) +#define NAND_MAX_PACKAGE_SIZE_SIZE (20) + +// ============================================================================= +// Drive Strength + +typedef UInt8 NandDriveStrength; + +#define NAND_DRIVE_STRENGTH_DEFAULT ((NandDriveStrength)0) + +#define NAND_DRIVE_STRENGTH_X1 ((NandDriveStrength)1) +#define NAND_DRIVE_STRENGTH_X2 ((NandDriveStrength)2) +#define NAND_DRIVE_STRENGTH_X3 ((NandDriveStrength)3) +#define NAND_DRIVE_STRENGTH_X4 ((NandDriveStrength)4) + +// ============================================================================= +// Nand Chip Id + +typedef UInt8 NandChipId[NAND_CHIP_ID_SIZE]; + +// ============================================================================= +// Nand Package Id + +struct NandPackageIdStruct +{ + // Unique identifier for this struct - start + NandChipId chipId; + UInt8 ceCnt; + // Unique identifier for this struct - end +}; + +typedef struct NandPackageIdStruct NandPackageId; + +// ============================================================================= +// Nand Config Id + +struct NandConfigIdStruct +{ + // Unique identifier for this struct - start + UInt8 connectedBusCnt; + UInt8 packageCnt; + NandPackageId packageIds[NAND_MAX_PACKAGES_PER_CONFIG]; + // Unique identifier for this struct - end +}; + +typedef struct NandConfigIdStruct NandConfigId; + +// ============================================================================= +// Nand Geometry + +struct NandGeometryStruct +{ + // Unique identifier for this struct - start + NandChipId chipId; + // Unique identifier for this struct - end + + UInt16 blocksPerCS; + UInt16 pagesPerBlock; + UInt16 dataBytesPerPage; + UInt16 spareBytesPerPage; + + UInt8 eccPer512Bytes; + CheckInitialBadType initialBBType; + + UInt16 diesPerCS; +}; + +typedef struct NandGeometryStruct NandGeometry; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// Nand Description + +struct NandDescriptionStruct +{ + // Unique identifier for this struct - start + NandPackageId packageId; + // Unique identifier for this struct - end + + char appleName[NAND_MAX_APPLE_NAME_SIZE]; + char vendorPartNumber[NAND_MAX_VENDOR_NAME_SIZE]; + char packageType[NAND_MAX_PACKAGE_TYPE_SIZE]; + char packageSize[NAND_MAX_PACKAGE_SIZE_SIZE]; +}; + +typedef struct NandDescriptionStruct NandDescription; + +// ============================================================================= +// ChipId Description + +struct NandChipIdDescriptionStruct +{ + // Unique identifier for this struct - start + NandChipId chipId; + // Unique identifier for this struct - end + + char die[NAND_MAX_VENDOR_NAME_SIZE]; + char vendor[NAND_MAX_VENDOR_NAME_SIZE]; +}; + +typedef struct NandChipIdDescriptionStruct NandChipIdDescription; +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Timing + +struct NandTimingStruct +{ + // Unique identifier for this struct - start + NandConfigId configId; + // Unique identifier for this struct - end + + // write cycle + UInt8 writeCycleNanosecs; + UInt8 writeSetupNanosecs; + UInt8 writeHoldNanosecs; + + // read cycle + UInt8 readCycleNanosecs; + UInt8 readSetupNanosecs; + UInt8 readHoldNanosecs; + + // read window + UInt8 readDelayNanosecs; + UInt8 readValidNanosecs; +}; + +typedef struct NandTimingStruct NandTiming; + +// ============================================================================= +// Nand Support + +struct NandBoardSupportStruct +{ + // Unique identifier for this struct - start + NandConfigId configId; + // Unique identifier for this struct - end + + VendorSpecificType vsType; +}; + +typedef struct NandBoardSupportStruct NandBoardSupport; + +// ============================================================================= +// Board Package/Landing Map + +typedef UInt32 NandLandingMask; + +typedef NandLandingMask NandLandingMap[NAND_MAX_PACKAGES_PER_CONFIG + 1]; + +// ============================================================================= +// Nand Board Timing + +struct NandBoardInfoStruct +{ + NandDriveStrength controlDstr; + NandDriveStrength dataDstr; + NandDriveStrength chipEnableDstr; + + UInt8 socToNandRiseNanosecs; + UInt8 socToNandFallNanosecs; + UInt8 nandToSocRiseNanosecs; + UInt8 nandToSocFallNanosecs; + + NandLandingMap landingMap; + BOOL32 useToggleMode; + BOOL32 useDiffDQSMode; + BOOL32 useDiffREMode; + BOOL32 useVref; + BOOL32 useSingleHostChannel; + BOOL32 allowSingleChipEnable; +}; + +typedef struct NandBoardInfoStruct NandBoardInfo; + +struct NandPpnStruct +{ + UInt32 specVersion; + UInt32 blocksPerCau; + UInt32 causPerCe; + UInt32 slcPagesPerBlock; + UInt32 mlcPagesPerBlock; + UInt32 matchOddEvenCaus; + UInt32 bitsPerCau; + UInt32 bitsPerPage; + UInt32 bitsPerBlock; + UInt32 maxTransactionSize; +}; + +typedef struct NandPpnStruct NandPpn; + +struct NandFormatStruct +{ + UInt32 metaPerLogicalPage; + UInt32 validMetaPerLogicalPage; + UInt32 logicalPageSize; +}; +typedef struct NandFormatStruct NandFormat; + +// ============================================================================= +// Nand Info + +struct NandInfoStruct +{ + const NandBoardSupport* boardSupport; + const NandBoardInfo* boardInfo; + const NandTiming* configTiming; + const NandGeometry* geometry; + const NandPpn* ppn; + const NandFormat* format; +}; + +typedef struct NandInfoStruct NandInfo; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// ============================================================================= +// Public Function Declarations + +BOOL32 findNandInfo(const NandChipId* chipIds, + NandInfo* nandInfo, + UInt32 numActiveDataBus); + +void setNandIdPpnConfig(const NandChipId* chipIds, + NandInfo* nandInfo, + UInt32 busses, + UInt32 ces); + +void reportFMCTimingValues(UInt32 readSetupClocks, + UInt32 readHoldClocks, + UInt32 readDccycleClocks, + UInt32 writeSetupClocks, + UInt32 writeHoldClocks); + +void reportToggleModeFMCTimingValues(UInt32 dqsHalfCycleClocks, + UInt32 ceSetupClocks, + UInt32 ceHoldClocks, + UInt32 adlClocks, + UInt32 whrClocks, + UInt32 readPreClocks, + UInt32 readPostClocks, + UInt32 writePreClocks, + UInt32 writePostClocks, + UInt32 regDQSTimingCtrl); + +void setToggleMode(); + +void setPPNOptions(BOOL32 retire_on_invalid_refresh); + +void reportPpnFeatures(void *list, UInt32 size); + +void reportDbgChipIds(void *list, UInt32 size); + +void setECCLevels(UInt32 numCorrectableBits, + UInt32 refreshThresholdBits); + +BOOL32 checkPpnLandingMap(UInt32 validCEMap); + +const NandFormat * getPPNFormat(void); + +BOOL32 targetSupportsToggle(void); +BOOL32 targetSupportsDiffDQS(void); +BOOL32 targetSupportsDiffRE(void); +BOOL32 targetSupportsVREF(void); +BOOL32 targetSupportsSHC(void); +BOOL32 targetSupportsSingleCE(void); + +// ============================================================================= +// Public Variables + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // _NANDID_H_ diff --git a/drivers/flash_nand/id/rules.mk b/drivers/flash_nand/id/rules.mk new file mode 100644 index 0000000..3826a54 --- /dev/null +++ b/drivers/flash_nand/id/rules.mk @@ -0,0 +1,21 @@ +# +# Copyright (c) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR) \ + drivers/flash_nand/raw/Whimory/Inc + +MODULES += \ + drivers/flash_nand/OAM + +ALL_OBJS += \ + $(LOCAL_DIR)/nandid.o diff --git a/drivers/flash_nand/ppn-swiss/export.txt b/drivers/flash_nand/ppn-swiss/export.txt new file mode 100644 index 0000000..bc1cf5d --- /dev/null +++ b/drivers/flash_nand/ppn-swiss/export.txt @@ -0,0 +1,12 @@ +_WMR_Open +_WMR_PPN_GetFTL +_WMR_PPN_GetFPart +_WMR_Start +_WMR_PPN_CtrlIO +_ppn_init +_ppnMiscSingleOperation +_ppnMiscFillDevStruct +_ppnMiscGetCEFromBank +_ppnMiscSingleLbaRead +_ppnMiscConvertToPPNPageAddress +_ppnMiscConvertPhysicalAddressToCauBlockPage diff --git a/drivers/flash_nand/ppn-swiss/library.mk b/drivers/flash_nand/ppn-swiss/library.mk new file mode 100644 index 0000000..b0bb06f --- /dev/null +++ b/drivers/flash_nand/ppn-swiss/library.mk @@ -0,0 +1,77 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +SWISSPPN_DIR := $(GET_LOCAL_DIR) +SWISSPPN_BUILD := $(call TOLIBDIR,$(SWISSPPN_DIR)/SWISSPPN.a) +COMMONLIBS += SWISSPPN + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +NAND_DIR := $(patsubst %/,%,$(dir $(GET_LOCAL_DIR))) + +MODULES += \ + drivers/flash_nand/OAM \ + lib/blockdev + +GLOBAL_INCLUDES += \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SVFL \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/Misc \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/FPart \ + $(NAND_DIR)/ppn/WhimoryPPN/Boot \ + $(NAND_DIR)/raw/Whimory/Inc \ + $(NAND_DIR)/OAM \ + $(NAND_DIR)/OAM/iBoot + +# base library files +SWISSPPN_SUBOBJS += \ + $(SWISSPPN_DIR)/ppn.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/FPart/PPNFPart.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/Misc/PPNMisc.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/Misc/VFLBuffer.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SVFL/s_vfl.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_boot.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_btoc.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_cxt.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_external.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_gc.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_geom.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_init.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_internal.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_meta.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_read.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/s_sb.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Free.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Init.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Search.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Update.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Boot/WhimoryBoot.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Boot/RegSwiss.o + +SWISSPPN_SUBOBJS := $(call TOLIBOBJDIR,$(SWISSPPN_SUBOBJS)) +ALL_DEPS += $(SWISSPPN_SUBOBJS:%o=%d) + +SWISSPPN_OBJS := $(call TOLIBOBJDIR,$(SWISSPPN_DIR)/SWISSPPN.o) + + +$(SWISSPPN_OBJS): $(SWISSPPN_SUBOBJS) + @echo LIB_LD $@ + $(_v)$(_LD) $(LIBRARY_LDFLAGS) $(SWISSPPN_SUBOBJS) -o $@ -exported_symbols_list $(SWISSPPN_DIR)/export.txt + +$(SWISSPPN_BUILD): $(SWISSPPN_OBJS) + +endif diff --git a/drivers/flash_nand/ppn-swiss/ppn.c b/drivers/flash_nand/ppn-swiss/ppn.c new file mode 100644 index 0000000..bd0afe6 --- /dev/null +++ b/drivers/flash_nand/ppn-swiss/ppn.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "FIL.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTL.h" +#include "WhimoryBoot.h" +#include "WMROAM.h" + + + +extern uint32_t nand_fsys_block_offset; + +static int nand_filesys_init(uint32_t block_size, uint32_t block_count); +static FTLFunctions *TLFuncPtr=NULL; +static int nand_read_block_hook(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count) +{ + Int32 err; + + if (count > 0) { + err = TLFuncPtr->Read(block, count, ptr); + //err = FTL_Read(block, count, ptr); + + if (err != FIL_SUCCESS) { + printf("nand_read_block_hook: failure %d reading block %u, count %zd\n", err, block, count); + return -1; + } + } + return count; +} + +int ppn_init(void) +{ + uint32_t block_size, block_count; + uint32_t index_cache = 0; + WhimoryBootCode boot_code; + + dprintf(DEBUG_INFO, "swiss_ppn_init()\n"); + + // Find a signature + boot_code = WMR_Start(0, 0, gWhimoryInitParameters); + if (kWhimoryOk == boot_code) { + // Open the FTL + boot_code = WMR_Open(&block_count, &block_size, &index_cache, gWhimoryInitParameters); + if (kWhimoryOk == boot_code) { + // Publish a block device + if (0 != nand_filesys_init(block_size, block_count)) { + return 0; + } + } + } else if (kWhimoryWarningUnformatted == boot_code) { + printf("***NAND driver is not formatted. Run restore process.***\n"); + } + return -1; +} + +static int nand_filesys_init(uint32_t block_size, uint32_t block_count) +{ + struct blockdev *nand; + + TLFuncPtr = WMR_PPN_GetFTL(); + // build a block device around this NAND + nand = malloc(sizeof(struct blockdev)); + + construct_blockdev(nand, "nand0", (off_t)block_count * block_size, block_size); + + nand->read_block_hook = &nand_read_block_hook; + + register_blockdev(nand); + + /* scan ourselves for partitions and publish subdevices */ + partition_scan_and_publish_subdevices("nand0"); + + return 0; +} diff --git a/drivers/flash_nand/ppn-swiss/ppn_syscfg.c b/drivers/flash_nand/ppn-swiss/ppn_syscfg.c new file mode 100644 index 0000000..82636dc --- /dev/null +++ b/drivers/flash_nand/ppn-swiss/ppn_syscfg.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_SYSCFG + +#include +#include +#include + +#include "FPart.h" +#include "VFLBuffer.h" +#include "WMRConfig.h" +#include "WhimoryBoot.h" + +extern uint32_t nand_fsys_block_offset; + +// The syscfg library assumes that syscfg will be 0x4000 bytes into +// the device regardles of whether it's NAND or NOR. nand1 will ONLY +// expose syscfg, so this doesn't make any sense, but we'll say we're +// big enough to read that far in anyway. +#define kSysCfgActualSize ( 0x4000 ) +#define kFakeBdevBlockSize (kSysCfgBdevOffset) +#define kFakeBdevCapacity (kSysCfgBdevOffset + kSysCfgActualSize) + + + +static FPartFunctions *_fpart = NULL; + +int ppn_syscfg_init(void) +{ + WhimoryBootCode boot_code; + + boot_code = WMR_Start(0, 0, 0); + if (kWhimoryOk == boot_code) { + _fpart = WMR_PPN_GetFPart(); + if (NULL != _fpart->ReadSpecialBlock) { + return 0; + } else { + dprintf(DEBUG_CRITICAL, "ppn syscfg is not supported!\n"); + return -1; + } + } + return -1; +} + +int ppn_read_syscfg_hook(struct blockdev *_dev, void *ptr, block_addr block, size_t count) +{ + bool ok = true; + + // Only allow reading the "second" block + if ((block != 1) || (count != 1)) { + dprintf(DEBUG_CRITICAL, "attempted to read ppn syscfg at non-zero offset\n"); + ok = false; + + } else if (count > 0) { + if (!_fpart->ReadSpecialBlock(ptr, kFakeBdevBlockSize, AND_SB_TYPE_UNIQUE_INFO)) { + dprintf(DEBUG_CRITICAL, "ppn_read_syscfg_hook: failure reading syscfg\n"); + ok = false; + } + } + + if (!ok) + return -1; + + return count; +} + +#endif /* WITH_SYSCFG */ diff --git a/drivers/flash_nand/ppn-swiss/rules.mk b/drivers/flash_nand/ppn-swiss/rules.mk new file mode 100644 index 0000000..8d2e8d7 --- /dev/null +++ b/drivers/flash_nand/ppn-swiss/rules.mk @@ -0,0 +1,37 @@ +# Copyright (c) 2007-2009 Apple Inc. All rights reserved. +# Copyright (c) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) +NAND_DIR := $(patsubst %/,%,$(dir $(GET_LOCAL_DIR))) + +OPTIONS += \ + WITH_PPN=1 \ + WITH_PPN_SYSCFG=1 + +GLOBAL_INCLUDES += \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/FPart \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/Misc \ + $(NAND_DIR)/ppn/WhimoryPPN/Boot + +ALL_OBJS += \ + $(LOCAL_DIR)/ppn_syscfg.o + +# +# If a NAND FTL has not been configured, we need some of the raw NAND bits. +# +ifeq ($(WITH_NAND_FTL),) +ALL_OBJS += \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/FPart/PPNFPart.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Core/Misc/PPNMisc.o \ + $(NAND_DIR)/ppn/WhimoryPPN/Boot/WhimoryBoot.o +else +LIBRARY_MODULES += $(LOCAL_DIR) +endif diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.c b/drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.c new file mode 100644 index 0000000..ab81b7e --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "FPart.h" +#include "WMRConfig.h" +#include "WhimoryBoot.h" +#include "ANDStats.h" +#include "FTL.h" +#include "VFL.h" + +static VFLFunctions *stVflFunctions; +static FTLFunctions *stFtlFunctions; + +typedef BOOL32 (*GetStructFunc)(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); + +typedef struct { + UInt32 dwStructLayer; + UInt32 dwStructType; + UInt32 dwStructVersion; +} ExportStructParameters; + + +static ExportStructParameters astrStructsToExport[] = +{ + // header (must be first) + { 0, AND_STRUCT_WMR_EXPORT_ALL, AND_EXPORT_STRUCTURE_VERSION}, + + // WMR Version (FTL & VFL types) + {AND_STRUCT_LAYER_WMR, AND_STRUCT_WMR_VERSION, 0}, + + // VFL_type + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_GET_TYPE, 0}, + + // FTL_type ( FTL/yaFTL) + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_TYPE, 0}, + + // All VFL Meta + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 0, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 1, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 2, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 3, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 4, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 5, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 6, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 7, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 8, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 9, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 10, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 11, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 12, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 13, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 14, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 15, 0}, + + //FTL geometry + {AND_STRUCT_LAYER_FTL,AND_STRUCT_FTL_GET_FTL_DEVICEINFO, 0}, + + // FTL + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_FTLCXT, 0}, + + // FTL counters + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_FTL_EC_BINS, 1}, + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_FTL_RC_BINS, 1}, + + // FTL - Stat + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_STATISTICS, 0}, + + // VFL - Stat + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_STATISTICS, 0}, + + // FIL - Device Info + {AND_STRUCT_LAYER_FIL, AND_STRUCT_FIL_DEVICE_INFO, 0}, + + // FIL - Stat + {AND_STRUCT_LAYER_FIL, AND_STRUCT_FIL_STATISTICS, 0}, + + // footer (must be last) + {0, AND_STRUCT_WMR_EXPORT_ALL_END, AND_EXPORT_STRUCTURE_VERSION}, + +}; + +#define AND_DUMP_DEBUG (0) + +#if AND_DUMP_DEBUG +#define DUMP_VAR(variable) WMR_PRINT(ALWAYS, "%s : %u\n", #variable, (UInt32)(variable)) + + +static void +hexdump(UInt8 *bytes, int count) +{ + int i, j; + + for (i = 0; i < count; i += 16) { + kprintf("%04x:", i); + for (j = 0; (j < 16) && ((i + j) < count); j++) + kprintf(" %02.2x", *bytes++); + kprintf("\n"); + } +} +#else +#define DUMP_VAR(variable) +#endif //AND_DUMP_DEBUG + + + +static GetStructFunc _translateStructLayer (UInt32 dwStructLayer) +{ + switch (dwStructLayer) + { + case AND_STRUCT_LAYER_FTL: + return stFtlFunctions->GetStruct; + case AND_STRUCT_LAYER_VFL: + return stVflFunctions->GetStruct; + case AND_STRUCT_LAYER_FIL: + return FIL_GetStruct; + case AND_STRUCT_LAYER_WMR: + return WMR_PPNGetStruct; + default: + return NULL; + } +} + + +static BOOL32 _appendStructToBuffer(void *pvoidExportBuffer, + UInt32 *pdwBufferSize, + UInt32 dwStructLayer, + UInt32 dwStructType, + UInt32 dwStructVersion) +{ + UInt32 dwDataSize; + BOOL32 boolResult; + GetStructFunc fGetStruct = _translateStructLayer(dwStructLayer); + UInt8 *cursor = (UInt8*) pvoidExportBuffer; + + + DUMP_VAR(pvoidExportBuffer); + if (pdwBufferSize) + { + DUMP_VAR(*pdwBufferSize); + } + DUMP_VAR(dwStructLayer); + DUMP_VAR(dwStructType); + DUMP_VAR(dwStructVersion); + + if (fGetStruct) + { + if (pvoidExportBuffer) + { + // leave room for the struct header + cursor += sizeof(ANDExportStruct); + } + dwDataSize = pdwBufferSize ? (*pdwBufferSize - sizeof(ANDExportStruct)) : 0; + boolResult = fGetStruct(dwStructType, cursor, &dwDataSize); + DUMP_VAR(dwDataSize); + } + else + { + // for header and footer + boolResult = TRUE32; + dwDataSize = 0; + } + + if (boolResult) + { +#if AND_DUMP_DEBUG + if (pvoidExportBuffer) + { + hexdump(pvoidExportBuffer, dwDataSize); + } +#endif + if (pdwBufferSize) + { + *pdwBufferSize = dwDataSize + sizeof(ANDExportStruct); + } + + if (pvoidExportBuffer) + { + ANDExportStruct strExport; + + strExport.dwStructID = dwStructType; + strExport.dwStructureVersion = dwStructVersion; + strExport.dwDataSize = dwDataSize; + strExport.dwIndex = 0; // What is this? + + WMR_MEMCPY(pvoidExportBuffer, &strExport, sizeof(ANDExportStruct)); + } + } + else if (pdwBufferSize) + { + *pdwBufferSize = 0; + } + + DUMP_VAR(boolResult); + return boolResult; +} + + + +#define SUB_MIN_ZERO(minuend, subtrahend) (((minuend) > (subtrahend)) ? ((minuend) - (subtrahend)) : 0) + +BOOL32 ANDExportAllStructs(void * pvoidDataBuffer, UInt32 * pdwDataSize) +{ + UInt32 idx; + ExportStructParameters *nextStruct; + const UInt32 dwNumStructures = sizeof(astrStructsToExport) / sizeof(astrStructsToExport[0]); + const UInt32 dwBufferSize = pdwDataSize ? *pdwDataSize : 0; + UInt8 *cursor = (UInt8*) pvoidDataBuffer; + UInt32 dwBufferRead = 0; + UInt32 dwTmpStructSize; + + if (!pdwDataSize) + { + return FALSE32; + } + + // Update globals + stVflFunctions = WMR_PPN_GetVFL(); + stFtlFunctions = WMR_PPN_GetFTL(); + + nextStruct = &astrStructsToExport[0]; + for (idx = 0; idx < dwNumStructures; ++idx) + { + dwTmpStructSize = SUB_MIN_ZERO(dwBufferSize, dwBufferRead); + _appendStructToBuffer(cursor, + &dwTmpStructSize, + nextStruct->dwStructLayer, + nextStruct->dwStructType, + nextStruct->dwStructVersion); + nextStruct++; + if (cursor) + { + cursor += dwTmpStructSize; + } + dwBufferRead += dwTmpStructSize; + } + + if (pdwDataSize) + { + *pdwDataSize = dwBufferRead; + } + + // pdwDataSize tells the whole story, always pass + return TRUE32; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.h b/drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.h new file mode 100644 index 0000000..1c48377 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRTypes.h" + +#ifndef _ANDSTATS_H_ +#define _ANDSTATS_H_ + +BOOL32 ANDExportAllStructs(void * pvoidDataBuffer, UInt32 * pdwDataSize); + +#endif //_ANDSTATS_H_ + + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegBoth.c b/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegBoth.c new file mode 100644 index 0000000..e367810 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegBoth.c @@ -0,0 +1,28 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. + +#include "WhimoryBoot.h" +#include "WhimoryBootTypes.h" +#include "FTL.h" +#include "VFL.h" + +Boot_FTL_Registry_t g_ftl_registry[] = +{ + { SFTL_PPN_MAJOR_VER, SFTL_PPN_Register }, + { YAFTL_PPN_MAJOR_VER, YAFTL_PPN_Register }, + { 0, NULL }, +}; + +Boot_VFL_Registry_t g_vfl_registry[] = +{ + { PPN_SVFL_MAJOR_VER, PPN_SVFL_GetFunctions }, + { PPN_VFL_MAJOR_VER, PPN_VFL_GetFunctions }, + { 0, NULL }, +}; + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegSwiss.c b/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegSwiss.c new file mode 100644 index 0000000..ed2a68c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegSwiss.c @@ -0,0 +1,26 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. + +#include "WhimoryBoot.h" +#include "WhimoryBootTypes.h" +#include "FTL.h" +#include "VFL.h" + +Boot_FTL_Registry_t g_ftl_registry[] = +{ + { SFTL_PPN_MAJOR_VER, SFTL_PPN_Register }, + { 0, NULL }, +}; + +Boot_VFL_Registry_t g_vfl_registry[] = +{ + { PPN_SVFL_MAJOR_VER, PPN_SVFL_GetFunctions }, + { 0, NULL }, +}; + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegVanilla.c b/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegVanilla.c new file mode 100644 index 0000000..202ec41 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/RegVanilla.c @@ -0,0 +1,26 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. + +#include "WhimoryBoot.h" +#include "WhimoryBootTypes.h" +#include "FTL.h" +#include "VFL.h" + +Boot_FTL_Registry_t g_ftl_registry[] = +{ + { YAFTL_PPN_MAJOR_VER, YAFTL_PPN_Register }, + { 0, NULL }, +}; + +Boot_VFL_Registry_t g_vfl_registry[] = +{ + { PPN_VFL_MAJOR_VER, PPN_VFL_GetFunctions }, + { 0, NULL }, +}; + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.c b/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.c new file mode 100644 index 0000000..a394492 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.c @@ -0,0 +1,1262 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// + +#include "WhimoryBoot.h" +#include "WhimoryBootTypes.h" +#include "WMRConfig.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "FPart.h" +#include "VFL.h" +#include "FTL.h" +#include "FIL.h" +#include "FILTypes.h" +#include "WMRFeatures.h" +#include "ANDStats.h" +#if WMR_UNIT_TEST_ENABLED +#include "WMRTest.h" +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Static variables +//////////////////////////////////////////////////////////////////////////////// + +static struct WhimorySignature _current_signature; +#ifndef AND_READONLY +static struct WhimorySignature _signature_at_boot; // keep around for debug +#endif //AND_READONLY + +static FTLFunctions *_ftl = NULL; +static VFLFunctions *_vfl = NULL; +static FPartFunctions *_fpart = NULL; +static LowFuncTbl *_fil = NULL; + +static struct WhimoryDeviceInfo _device_info; + +extern Boot_FTL_Registry_t g_ftl_registry[]; +extern Boot_VFL_Registry_t g_vfl_registry[]; + +Boot_FPart_Registry_t g_fpart_registry[] = +{ + { PPN_FPart_MAJOR_VER, PPN_FPart_GetFunctions }, + { 0, NULL }, +}; + +//////////////////////////////////////////////////////////////////////////////// +// Static function declarations +//////////////////////////////////////////////////////////////////////////////// + +#if !(AND_FPART_ONLY) +static FTLFunctions * +_LookupFTL + (UInt32 major_ver); + +static VFLFunctions * +_LookupVFL + (UInt32 major_ver); +#endif //!(AND_FPART_ONLY) + +static FPartFunctions * +_LookupFPart + (UInt32 major_ver); + +static void +_GetDeviceInfo + (LowFuncTbl *fil); + +#if (!AND_READONLY) && !(AND_FPART_ONLY) + +static WhimoryBootCode +_AllocateInitialSignature + (void); + +static BOOL32 +_FillNewSignature + (struct WhimorySignature *sig, + UInt32 fpart_major_ver, + UInt32 fpart_options, + UInt32 fpart_format_options, + UInt32 vfl_major_ver, + UInt32 vfl_options, + UInt32 ftl_major_ver, + UInt32 ftl_options, + UInt32 num_keepout_blocks); + +static WhimoryBootCode +_DestructiveFormat + (struct WhimorySignature *sig, + UInt32 megabytes_for_ftl); + +static BOOL32 +_SetFTLPartition + (UInt32 megabytes_for_ftl); + +#endif //(!AND_READONLY) && !(AND_FPART_ONLY) + +static BOOL32 +_SignatureHasCorrectGeometry + (struct WhimorySignature *sig); + +static BOOL32 +_andGetStruct + (UInt32 selector, + void * data, + UInt32 * size); + +static BOOL32 +_andPerformFunction + (UInt32 selector, + void *buffer, + UInt32 *size); + +#if !(AND_FPART_ONLY) +static void +_ClearFILStatistics + (void); +#endif //!(AND_FPART_ONLY) + +//////////////////////////////////////////////////////////////////////////////// +// Public function implementations +//////////////////////////////////////////////////////////////////////////////// + +WhimoryBootCode +WMR_Start + (UInt32 fpart_major_ver, + UInt32 fpart_options, + UInt32 boot_options) // low-power, etc +{ + ANDStatus status; + WhimoryBootCode ret_val = kWhimoryOk; + BOOL32 found_any_signature = FALSE32; + + if (!OAM_Init()) + { + ret_val = kWhimoryErrSetup; + goto start_fail; + } + + WMR_ASSERT(sizeof(struct WhimorySignature) == WHIMORY_SIGNATURE_SIZE); + +#ifndef AND_READONLY + WMR_PRINT(INIT, "Apple PPN NAND Driver, Read/Write\n"); +#else + WMR_PRINT(INIT, "Apple PPN NAND Driver, Read-Only\n"); +#endif //AND_READONLY + + status = FIL_Init(); + if (status != FIL_SUCCESS) + { + ret_val = kWhimoryErrMissingHardware; + goto start_fail; + } + + _fil = FIL_GetFuncTbl(); + + // Populate relevant device info + _GetDeviceInfo(_fil); + + // Verify that there is a device + if (0 == _device_info.num_ce) + { + WMR_PRINT(ERROR, "No NAND device found\n"); + ret_val = kWhimoryErrMissingHardware; + goto start_fail; + } + + WMR_PRINT(INIT, "FIL_Init [OK]\n"); + +#if WMR_UNIT_TEST_ENABLED + // FIL Test Hook + if (!WMR_FIL_Test(_fil)) + { + ret_val = kWhimoryErrUnitTestFailed; + goto start_fail; + } +#endif //WMR_UNIT_TEST_ENABLED + +#if AND_LOW_POWER_MOUNT + // Determine if we need to minimize power + if (boot_options & kWhimoryBootOptionLowPower) + { + UInt32 power_mode = NAND_POWER_MODE_SINGLE_CE; + FIL_SetStruct(AND_STRUCT_FIL_POWER_MODE, + &power_mode, + sizeof(power_mode)); + } +#endif //AND_LOW_POWER_MOUNT + + status = BUF_Init(_device_info.main_bytes_per_page, + _device_info.total_meta_per_page, + WMR_NUM_BUFFERS); + + if (status != BUF_SUCCESS) + { + ret_val = kWhimoryErrOutOfMemory; + goto start_fail; + } + + _fpart = _LookupFPart(fpart_major_ver); + if (NULL == _fpart) + { + ret_val = kWhimoryErrUnsupportedVersion; + goto start_fail; + } + + WMR_ASSERT(NULL != _fpart->Init); + if (!_fpart->Init(_fil, fpart_options)) + { + ret_val = kWhimoryErrSetup; + goto start_fail; + } + +#if WMR_UNIT_TEST_ENABLED + // FPart Test Hook + if (!WMR_FPart_Test(_fpart)) + { + ret_val = kWhimoryErrUnitTestFailed; + goto start_fail; + } +#endif //WMR_UNIT_TEST_ENABLED + + // Read the signature to see if we're allowed to talk to this NAND + WMR_MEMSET(&_current_signature, 0xA5, sizeof(_current_signature)); + found_any_signature = _fpart->ReadSpecialBlock(&_current_signature, + sizeof(_current_signature), + AND_SB_TYPE_DRIVER_SIGNATURE); + + if (!found_any_signature) + { + WMR_PRINT(INIT, "No signature found.\n"); + ret_val = kWhimoryWarningUnformatted; + goto start_fail; + } + + if (WHIMORY_SIGNATURE_MAGIC != _current_signature.magic) + { + WMR_PRINT(ERROR, "Signature has invalid magic: 0x%08x\n", + _current_signature.magic); + ret_val = kWhimoryErrCorruptedFormat; + goto start_fail; + } + + if (fpart_major_ver != _current_signature.fpart_major_ver) + { + WMR_PRINT(ERROR, "FPart major ver in signature is %d\n", + _current_signature.fpart_major_ver); + ret_val = kWhimoryErrCorruptedFormat; + goto start_fail; + } + + if (!_SignatureHasCorrectGeometry(&_current_signature)) + { + WMR_PRINT(ERROR, "Geometry does not match signature\n"); + ret_val = kWhimoryErrCorruptedFormat; + goto start_fail; + } + +#ifndef AND_READONLY + // Copy the found signature to a scratch buffer so we can modify it later + WMR_MEMCPY(&_signature_at_boot, + &_current_signature, + sizeof(_current_signature)); +#endif //AND_READONLY + + if (WHIMORY_SIGNATURE_VER_PPN_CUR < _current_signature.whimory_ver_at_birth) + { + // This device was born from a newer driver and cannot be opened + WMR_PRINT(ERROR, "Device version %d unsupported\n", + _current_signature.whimory_ver_at_birth); + ret_val = kWhimoryBirthVersionTooNew; + goto start_fail; + } + +#if !(AND_FPART_ONLY) + // Make sure that the required FTL and VFL are available + if (NULL == _LookupVFL(_current_signature.vfl_major_ver)) + { + ret_val = kWhimoryMajorVersionNotAvailable; + goto start_fail; + } + + if (NULL == _LookupFTL(_current_signature.ftl_major_ver)) + { + ret_val = kWhimoryMajorVersionNotAvailable; + goto start_fail; + } +#endif //!AND_FPART_ONLY + + return kWhimoryOk; + + start_fail: + + return ret_val; +} + +#if !(AND_FPART_ONLY) +WhimoryBootCode +WMR_Open + (UInt32 *total_sectors, + UInt32 *sector_size, + UInt32 *index_cache, + UInt32 boot_options) +{ + WhimoryBootCode ret_val = kWhimoryOk; + Int32 status; + + WMR_ASSERT(NULL != _fil); + WMR_ASSERT(NULL != _fpart); + WMR_ASSERT(_current_signature.magic == WHIMORY_SIGNATURE_MAGIC); + WMR_ASSERT(WHIMORY_SIGNATURE_VER_PPN_CUR >= _current_signature.whimory_ver_at_birth); + + // Check VFL and FTL software availability first + _vfl = _LookupVFL(_current_signature.vfl_major_ver); + if (NULL == _vfl) + { + ret_val = kWhimoryErrUnsupportedVersion; + goto open_fail; + } + + WMR_ASSERT(NULL != _vfl->GetMinorVersion); + if (_current_signature.vfl_minor_ver != _vfl->GetMinorVersion()) + { + WMR_PRINT(ERROR, "VFL minor version - disk %d sw %d\n", + _current_signature.vfl_minor_ver, _vfl->GetMinorVersion()); + ret_val = kWhimoryMinorVersionMismatch; + goto open_fail; + } + + _ftl = _LookupFTL(_current_signature.ftl_major_ver); + if (NULL == _ftl) + { + ret_val = kWhimoryErrUnsupportedVersion; + goto open_fail; + } + + WMR_ASSERT(NULL != _ftl->GetMinorVersion); + if (_current_signature.ftl_minor_ver != _ftl->GetMinorVersion()) + { + WMR_PRINT(ERROR, "FTL minor version - disk %d sw %d\n", + _current_signature.ftl_minor_ver, _ftl->GetMinorVersion()); + ret_val = kWhimoryMinorVersionMismatch; + goto open_fail; + } + + status = _vfl->Init(_fpart); + if (status != VFL_SUCCESS) + { + WMR_PRINT(ERROR, "VFL_Init [Failed]\n"); + ret_val = kWhimoryErrSetup; + goto open_fail; + } + + status = _vfl->Open(_current_signature.num_keepout_blocks, + _current_signature.vfl_minor_ver, + _current_signature.vfl_options); + + if (status != VFL_SUCCESS) + { + WMR_PRINT(ERROR, "VFL_Open [Failed]\n"); + ret_val = kWhimoryErrCorruptedFormat; + goto open_fail; + } + + WMR_PRINT(INIT, "VFL_Open [OK]\n"); + + _ClearFILStatistics(); + +#if WMR_UNIT_TEST_ENABLED + // VFL Test Hook + if (!WMR_VFL_Test(_vfl)) + { + ret_val = kWhimoryErrUnitTestFailed; + goto open_fail; + } +#endif //WMR_UNIT_TEST_ENABLED + + status = _ftl->Init(_vfl); + if (status != FTL_SUCCESS) + { + WMR_PRINT(ERROR, "FTL_Init [Failed]\n"); + ret_val = kWhimoryErrSetup; + goto open_fail; + } + + if ((boot_options & kWhimoryBootOptionDisableGCInTrim) == kWhimoryBootOptionDisableGCInTrim) + { + _current_signature.ftl_options |= WMR_INIT_DISABLE_GC_IN_TRIM; + } + + if ((boot_options & kWhimorySetIndexCacheSize) == kWhimorySetIndexCacheSize) + { + _current_signature.ftl_options |= WMR_INIT_SET_INDEX_CACHE_SIZE; + _current_signature.ftl_options |= ((*index_cache) << 20); + } +#ifdef AND_SIMULATOR + if(boot_options & (WMR_INIT_IGNORE_ERASE_GAP)) + { + _current_signature.ftl_options |= WMR_INIT_IGNORE_ERASE_GAP; + } +#endif + status = _ftl->Open(total_sectors, + sector_size, + ((boot_options & kWhimoryBootOptionForceFtlRecovery) ? TRUE32 : FALSE32), + ((boot_options & kWhimoryBootOptionFreshOffFTLFormat) ? TRUE32 : FALSE32), + _current_signature.ftl_minor_ver, + _current_signature.ftl_options|((boot_options & kWhimoryBootOptionReadOnly) ? kWhimoryBootOptionReadOnly : 0)); + if (status != FTL_SUCCESS) + { + WMR_PRINT(ERROR, "FTL_Open [Failed]\n"); + ret_val = kWhimoryErrCorruptedFormat; + goto open_fail; + } + WMR_PRINT(INIT, "FTL_Open [OK]\n"); + +#if WMR_UNIT_TEST_ENABLED + // FTL Test Hook + if (!WMR_FTL_Test(_ftl)) + { + ret_val = kWhimoryErrUnitTestFailed; + goto open_fail; + } +#endif //WMR_UNIT_TEST_ENABLED + + return kWhimoryOk; + + open_fail: + WMR_PRINT(ERROR, "FAILED: 0x%08x\n", ret_val); + + return ret_val; +} + +#ifndef AND_READONLY +WhimoryBootCode +WMR_Initial_Format + (UInt32 fpart_major_ver, + UInt32 fpart_options, + UInt32 fpart_format_options, + UInt32 vfl_major_ver, + UInt32 vfl_options, + UInt32 ftl_major_ver, + UInt32 ftl_options, + UInt32 num_keepout_blocks, + UInt32 megabytes_for_ftl) +{ + WhimoryBootCode boot_code = kWhimoryErrSetup; + + // Should have previously attempted to FIL_Init + _fil = FIL_GetFuncTbl(); + WMR_ASSERT(NULL != _fil); + + // Populate relevant device info + _GetDeviceInfo(_fil); + + // Fill-out a signature and get function pointers + if (_FillNewSignature(&_current_signature, + fpart_major_ver, + fpart_options, + fpart_format_options, + vfl_major_ver, + vfl_options, + ftl_major_ver, + ftl_options, + num_keepout_blocks)) + { + // Write that format without maintaining user data + boot_code = _DestructiveFormat(&_current_signature, megabytes_for_ftl); + } + + return boot_code; +} + +WhimoryBootCode +WMR_Update + (const BOOL32 keep_backward_compatibility, + const BOOL32 save_data, + UInt32 vfl_major_ver, + UInt32 vfl_options, + UInt32 ftl_major_ver, + UInt32 ftl_options, + UInt32 num_keepout_blocks) +{ + // This function is like destructive format, but carries forward some + // signature information instead of generating a new signature + + WhimoryBootCode boot_code = kWhimoryOk; + + WMR_ASSERT(WHIMORY_SIGNATURE_MAGIC == _current_signature.magic); + WMR_ASSERT(WHIMORY_SIGNATURE_VER_PPN_CUR >= _current_signature.whimory_ver_at_birth); + + // We don't support these types of graceful transitions yet + WMR_ASSERT(!keep_backward_compatibility); + WMR_ASSERT(!save_data); + + _vfl = _LookupVFL(vfl_major_ver); + if (NULL == _vfl) + { + boot_code = kWhimoryErrUnsupportedVersion; + goto update_error; + } + + _current_signature.vfl_major_ver = vfl_major_ver; + _current_signature.vfl_minor_ver = _vfl->GetMinorVersion(); + _current_signature.vfl_options = vfl_options; + + _ftl = _LookupFTL(ftl_major_ver); + if (NULL == _ftl) + { + boot_code = kWhimoryErrUnsupportedVersion; + goto update_error; + } + + _current_signature.ftl_major_ver = ftl_major_ver; + _current_signature.ftl_minor_ver = _ftl->GetMinorVersion(); + _current_signature.ftl_options = ftl_options; + + if (_current_signature.num_keepout_blocks != num_keepout_blocks) + { + WMR_PRINT(ERROR, "Warning: changing keepout from %d to %d\n", + _current_signature.num_keepout_blocks, num_keepout_blocks); + _current_signature.num_keepout_blocks = num_keepout_blocks; + } + + boot_code = _DestructiveFormat(&_current_signature, 0); + + if (kWhimoryOk != boot_code) + { + // On failure, revert to old setting + WMR_MEMCPY(&_current_signature, &_signature_at_boot, sizeof(_current_signature)); + } + + return boot_code; + + update_error: + + WMR_MEMCPY(&_current_signature, &_signature_at_boot, sizeof(_current_signature)); + return boot_code; +} + +WhimoryBootCode +WMR_Partition + (UInt32 megabytes_for_ftl) +{ + WhimoryBootCode boot_code = kWhimoryOk; + Int32 nand_status; + + WMR_ASSERT(NULL != _fpart); + // Assert that we have a valid signature in memory + WMR_ASSERT(_current_signature.magic == WHIMORY_SIGNATURE_MAGIC); + + _vfl = _LookupVFL(_current_signature.vfl_major_ver); + if (NULL == _vfl) + { + boot_code = kWhimoryErrUnsupportedVersion; + goto partition_fail; + } + + _ftl = _LookupFTL(_current_signature.ftl_major_ver); + if (NULL == _ftl) + { + boot_code = kWhimoryErrUnsupportedVersion; + goto partition_fail; + } + + // Assume VFL is already formatted + if (ANDErrorCodeOk != (nand_status = _vfl->Init(_fpart))) + { + boot_code = kWhimoryErrSetup; + goto partition_fail; + } + + nand_status = _vfl->Open(_current_signature.num_keepout_blocks, + _current_signature.vfl_minor_ver, + _current_signature.vfl_options); + if (ANDErrorCodeOk != nand_status) + { + WMR_PRINT(ERROR, "VFL Open failed\n"); + boot_code = kWhimoryErrCorruptedFormat; + goto partition_fail; + } + + _ClearFILStatistics(); + + if (!_SetFTLPartition(megabytes_for_ftl)) + { + boot_code = kWhimoryErrUnsupportedVersion; + goto partition_fail; + } + + // Format the FTL with the new size, but don't open it + if (ANDErrorCodeOk != (nand_status = _ftl->Init(_vfl))) + { + boot_code = kWhimoryErrSetup; + goto partition_fail; + } + nand_status = _ftl->Format(_current_signature.ftl_options); + if (ANDErrorCodeOk != nand_status) + { + WMR_PRINT(ERROR, "FTL Format failed\n"); + boot_code = kWhimoryErrCorruptedFormat; + goto partition_fail; + } + + if (0 != (WHIMORY_FTL_PARTITION_VALID_BIT & _current_signature.megabytes_for_ftl)) + { + // if there's a pending partition flag in the signature, clear it + _current_signature.megabytes_for_ftl &= ~WHIMORY_FTL_PARTITION_VALID_BIT; + + WMR_PRINT(INIT, "Updating signature\n"); + if (!_fpart->WriteSpecialBlock(&_current_signature, + sizeof(_current_signature), + AND_SB_TYPE_DRIVER_SIGNATURE)) + { + WMR_PRINT(ERROR, "Failed to write signature\n"); + boot_code = kWhimoryErrCorruptedFormat; + goto partition_fail; + } + WMR_MEMCPY(&_signature_at_boot, &_current_signature, sizeof(_current_signature)); + } + + // Tear down so we can call WMR_Open() + _ftl->Close(); + _vfl->Close(); + + return kWhimoryOk; + + partition_fail: + + return boot_code; +} + +#endif // ! AND_READONLY +#endif // ! AND_FPART_ONLY + +void +WMR_Close + (void) +{ + if (NULL != _ftl) + { + _ftl->Close(); + } + _ftl = NULL; + + if (NULL != _vfl) + { + _vfl->Close(); + } + _vfl = NULL; + + if (NULL != _fpart) + { + _fpart->Close(); + } + _fpart = NULL; + + BUF_Close(); + + // Clear static variables + +#ifndef AND_READONLY + WMR_MEMSET(&_signature_at_boot, 0, sizeof(_signature_at_boot)); +#endif //!AND_READONLY + WMR_MEMSET(&_current_signature, 0, sizeof(_current_signature)); + WMR_MEMSET(&_device_info, 0, sizeof(_device_info)); +} + +BOOL32 +_andGetStruct + (UInt32 selector, + void *data, + UInt32 *size) +{ + BOOL32 result = FALSE32; + + if (LOCKDOWN_EXTRACT_ALL == selector) + { + // Mobile Lockdown - Get All Structures +#if AND_COLLECT_STATISTICS + result = ANDExportAllStructs(data, size); +#endif //AND_COLLECT_STATISTICS + } + else if (LOCKDOWN_GET_ALL_SIZE == selector) + { +#if AND_COLLECT_STATISTICS + UInt32 *target_size = (UInt32*)data; + if ((NULL != target_size) && + (NULL != size) && + (*size >= sizeof(*target_size))) + { + result = ANDExportAllStructs(NULL, target_size); + *size = sizeof(*target_size); + } +#endif //AND_COLLECT_STATISTICS + } + else + { + switch (selector & AND_STRUCT_LAYER_MASK) + { + case AND_STRUCT_LAYER_FTL: + { + if ((NULL != _ftl) && (NULL != _ftl->GetStruct)) + { + result = _ftl->GetStruct(selector, data, size); + } + break; + } + + case AND_STRUCT_LAYER_VFL: + { + if ((NULL != _vfl) && (NULL != _vfl->GetStruct)) + { + result = _vfl->GetStruct(selector, data, size); + } + break; + } + + case AND_STRUCT_LAYER_FIL: + { + result = FIL_GetStruct(selector, data, size); + break; + } + + case AND_STRUCT_LAYER_GETALL: + { +#if AND_COLLECT_STATISTICS + if (AND_STRUCT_WMR_EXPORT_ALL == selector) + { + result = ANDExportAllStructs(data, size); + } + else if (AND_STRUCT_WMR_EXPORT_ALL_GET_SIZE == selector) + { + UInt32 *target_size = (UInt32*)data; + if ((NULL != target_size) && + (NULL != size) && + (*size >= sizeof(*target_size))) + { + result = ANDExportAllStructs(NULL, target_size); + *size = sizeof(*target_size); + } + } +#endif //AND_COLLECT_STATISTICS + break; + } + + default: + { + WMR_PRINT(ERROR, "not implemented: 0x%08x\n", selector); + break; + } + } + } + + return result; +} +BOOL32 +_andPerformFunction + (UInt32 selector, + void *buffer, + UInt32 *size) +{ + BOOL32 result = FALSE32; + + switch (selector) + { +#ifndef AND_READONLY + case AND_FUNCTION_INDEX_CACHE_UPDATE: + { + if ((NULL != _ftl) && + (NULL != _ftl->GetStruct) && + (NULL != size)) + { + result = _ftl->GetStruct(selector, NULL, size); + *size = 0; + } + } + break; + + case AND_FUNCTION_SET_BURNIN_CODE: + { + if ((NULL != _vfl) && + (NULL != _vfl->SetStruct) && + (NULL != buffer) && + (NULL != size)) + { + result = _vfl->SetStruct(AND_STRUCT_VFL_BURNIN_CODE, buffer, *size); + } + } + break; + + case AND_FUNCTION_SET_POWER_MODE: + { + if ((NULL != buffer) && + (NULL != size)) + { + result = FIL_SetStruct(AND_STRUCT_FIL_POWER_MODE, buffer, *size); + } + } + break; + + case AND_FUNCTION_NEURALIZE: + { + if (NULL != _fpart) + { + result = _fpart->Neuralize(); + } + } + break; + + case AND_FUNCTION_SET_TIMINGS: + { + if ((NULL != buffer) && + (NULL != size)) + { + result = FIL_SetStruct(AND_STRUCT_FIL_SET_TIMINGS, buffer, *size); + } + } + break; + + case AND_FUNCTION_SAVE_STATS: + { + if(_ftl->WriteStats) + { + result = _ftl->WriteStats(); + } + } + break; + + case _AND_FUNCTION_COMPLETE_EPOCH_UPDATE: + { + WMR_PRINT(ERROR, "Epoch update is deprecated\n"); + result = FALSE32; + + } + break; + +#endif // ! AND_READONLY + default: + { + WMR_PANIC("Unknown selector: 0x%08x\n", selector); + result = FALSE32; + } + } + + if (!result) + { + WMR_PRINT(ERROR, "selector 0x%08x failed\n", selector); + } + + return result; +} + +BOOL32 +WMR_PPN_CtrlIO + (UInt32 selector, + void *data, + UInt32 *size) +{ + if ((selector & AND_STRUCT_LAYER_MASK) == AND_STRUCT_LAYER_FUNCTIONAL) + { + return _andPerformFunction(selector, data, size); + } + else + { + return _andGetStruct(selector, data, size); + } +} + +BOOL32 +WMR_PPNGetStruct + (UInt32 struct_type, + void *data, + UInt32 *size) +{ + BOOL32 result = FALSE32; + + switch (struct_type) + { + case AND_STRUCT_WMR_VERSION: + { + UInt32 dwSignature = WHIMORY_SIGNATURE_MAGIC; + result = WMR_FILL_STRUCT(data, + size, + &dwSignature, + sizeof(dwSignature)); + } + break; + + default: + { + WMR_PRINT(ERROR, "unknown struct id: 0x%08x\n", struct_type); + } + break; + } + return result; +} + +FTLFunctions * +WMR_PPN_GetFTL + (void) +{ + WMR_ASSERT(NULL != _ftl); + + return _ftl; +} + +VFLFunctions * +WMR_PPN_GetVFL + (void) +{ + WMR_ASSERT(NULL != _vfl); + + return _vfl; +} + +FPartFunctions * +WMR_PPN_GetFPart + (void) +{ + WMR_ASSERT(NULL != _fpart); + + return _fpart; +} + +//////////////////////////////////////////////////////////////////////////////// +// Static function implementations +//////////////////////////////////////////////////////////////////////////////// + +#if !defined(AND_READONLY) && !(AND_FPART_ONLY) +BOOL32 +_FillNewSignature + (struct WhimorySignature *sig, + UInt32 fpart_major_ver, + UInt32 fpart_options, + UInt32 fpart_format_options, + UInt32 vfl_major_ver, + UInt32 vfl_options, + UInt32 ftl_major_ver, + UInt32 ftl_options, + UInt32 num_keepout_blocks) +{ + WMR_MEMSET(sig, 0, sizeof(*sig)); + sig->magic = WHIMORY_SIGNATURE_MAGIC; + sig->_deprecated_epoch = 0; + sig->whimory_ver_at_birth = WHIMORY_SIGNATURE_VER_PPN_CUR; + + // Get an FPart + sig->fpart_major_ver = fpart_major_ver; + _fpart = _LookupFPart(fpart_major_ver); + if (NULL == _fpart) + { + return FALSE32; + } + WMR_ASSERT(NULL != _fpart->GetMinorVersion); + sig->fpart_minor_ver = _fpart->GetMinorVersion(); + sig->fpart_options = fpart_options; + sig->fpart_format_options = fpart_format_options; + + // Get a VFL + sig->vfl_major_ver = vfl_major_ver; + _vfl = _LookupVFL(vfl_major_ver); + if (NULL == _vfl) + { + return FALSE32; + } + WMR_ASSERT(NULL != _vfl->GetMinorVersion); + sig->vfl_minor_ver = _vfl->GetMinorVersion(); + sig->vfl_options = vfl_options; + + // Get an FTL + sig->ftl_major_ver = ftl_major_ver; + _ftl = _LookupFTL(ftl_major_ver); + if (NULL == _ftl) + { + return FALSE32; + } + WMR_ASSERT(NULL != _ftl->GetMinorVersion); + sig->ftl_minor_ver = _ftl->GetMinorVersion(); + + // Stash the number of keepout blocks + sig->num_keepout_blocks = num_keepout_blocks; + + // Keep critical geometry information for devices with + // multiple removable packages + sig->num_chip_enables = _device_info.num_ce; + + // For debugging, record what software version formatted this device + WMR_FILL_SW_VERSION(sig->sw_ver_str, sizeof(sig->sw_ver_str)); + + return TRUE32; +} + +WhimoryBootCode +_AllocateInitialSignature + (void) +{ + // if there is no block allocated to signature, allocate one + if (!_fpart->IsSpecialBlockTypeAllocated(AND_SB_TYPE_DRIVER_SIGNATURE)) + { + SpecialBlockAddress signature_block; + if (!_vfl->AllocateSpecialBlock(&signature_block, + AND_SB_TYPE_DRIVER_SIGNATURE)) + { + WMR_PRINT(ERROR, "AllocateSpecialBlock for signature failed\n"); + return kWhimoryErrSetup; + } + if (!_fpart->AllocateSpecialBlockType(&signature_block, + 1, + AND_SB_TYPE_DRIVER_SIGNATURE)) + { + WMR_PRINT(ERROR, "AllocateSpecialBlockType failed\n"); + return kWhimoryErrSetup; + } + } + return kWhimoryOk; +} + +WhimoryBootCode +_DestructiveFormat + (struct WhimorySignature *sig, + UInt32 megabytes_for_ftl) +{ + Int32 nand_status; + + // Init and format FPart + if (!_fpart->Init(_fil, sig->fpart_options)) + { + return kWhimoryErrOutOfMemory; + } + + // Format VFL and open it so FTL can use it + if (ANDErrorCodeOk != (nand_status = _vfl->Init(_fpart))) + { + WMR_PRINT(LOG, "_vfl->Init: 0x%08X\n", nand_status); + return kWhimoryErrOutOfMemory; + } + + WMR_PRINT(INIT, "Starting VFL Format\n"); + if (ANDErrorCodeOk != (nand_status = _vfl->Format(sig->num_keepout_blocks, + sig->vfl_options))) + { + WMR_PRINT(LOG, "_vfl->Format: 0x%08X\n", nand_status); + return kWhimoryErrCorruptedFormat; + } + + if (ANDErrorCodeOk != (nand_status = _vfl->Open(sig->num_keepout_blocks, + sig->vfl_minor_ver, + sig->vfl_options))) + { + WMR_PRINT(LOG, "_vfl->Open: 0x%08X\n", nand_status); + return kWhimoryErrCorruptedFormat; + } + + // Allocate a signature before any persistent FPart blocks + // so that subsequent searches will find it first + WMR_PRINT(INIT, "Allocating signature\n"); + if (ANDErrorCodeOk != _AllocateInitialSignature()) + { + return kWhimoryErrCorruptedFormat; + } + + WMR_PRINT(INIT, "Starting FPart Format\n"); + // Allocate persistent special blocks owned by FPart + if (!_fpart->Format(_vfl, sig->fpart_format_options)) + { + WMR_PRINT(ERROR, "Failed to format FPart\n"); + return kWhimoryErrSetup; + } + + _ClearFILStatistics(); + + // If there is a request for non-zero burnin-size, + // set that before formatting FTL + if ((megabytes_for_ftl > 0) && + !_SetFTLPartition(megabytes_for_ftl)) + { + return kWhimoryErrCorruptedFormat; + } + + // Format the FTL, but don't open it + if (ANDErrorCodeOk != (nand_status = _ftl->Init(_vfl))) + { + WMR_PRINT(LOG, "_ftl->Init: 0x%08X\n", nand_status); + return kWhimoryErrOutOfMemory; + } + WMR_PRINT(INIT, "Starting FTL Format\n"); + if (ANDErrorCodeOk != (nand_status = _ftl->Format((sig->ftl_options) | (WMR_INIT_RUN_PRODUCTION_FORMAT)))) + { + WMR_PRINT(LOG, "_ftl->Format: 0x%08X\n", nand_status); + return kWhimoryErrCorruptedFormat; + } + + // Write signature to tell WMR_Open() about the details + WMR_PRINT(INIT, "Writing final signature\n"); + if (!_fpart->WriteSpecialBlock(sig, + sizeof(*sig), + AND_SB_TYPE_DRIVER_SIGNATURE)) + { + WMR_PRINT(ERROR, "Failed to write signature\n"); + return kWhimoryErrCorruptedFormat; + } + WMR_MEMCPY(&_signature_at_boot, sig, sizeof(*sig)); + + // Close so that init can be called in WMR_Open() + _vfl->Close(); + _ftl->Close(); + return kWhimoryOk; +} + +BOOL32 +_SetFTLPartition + (UInt32 megabytes_for_ftl) +{ + UInt32 num_superblocks = 0; + UInt32 num_superblocks_data_size = sizeof(num_superblocks); + UInt16 superblocks_for_ftl; + BOOL32 result = FALSE32; + + if (!_vfl->GetStruct(AND_STRUCT_VFL_NUM_OF_SUBLKS, + &num_superblocks, + &num_superblocks_data_size)) + { + WMR_PRINT(ERROR, "VFL parameters unavailable\n"); + return FALSE32; + } + + if (megabytes_for_ftl > 0) + { + WMR_ASSERT(num_superblocks > 0); + + WMR_ASSERT(NULL != _ftl); + superblocks_for_ftl = _ftl->ConvertUserMBtoFTLSuperblocks(_vfl, megabytes_for_ftl); + + WMR_PRINT(INIT, "Set to %dMB using %d virtual blocks\n", + megabytes_for_ftl, + superblocks_for_ftl); + WMR_ASSERT(superblocks_for_ftl <= num_superblocks); + } + else + { + WMR_ASSERT(num_superblocks > 0); + // All the superblocks go to FTL + superblocks_for_ftl = num_superblocks; + + WMR_PRINT(INIT, "full size FTL\n"); + } + + result = _vfl->SetStruct(AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS, + &superblocks_for_ftl, + sizeof(superblocks_for_ftl)); + + if (!result) + { + WMR_PRINT(ERROR, "unsupported\n"); + } + + return result; +} + +#endif //!defined(AND_READONLY) && !(AND_FPART_ONLY) + +const struct WhimorySignature * +WMR_PPNGetSignature + (void) +{ + return &_current_signature; +} + +static BOOL32 +_SignatureHasCorrectGeometry + (struct WhimorySignature *sig) +{ + if (sig->num_chip_enables != _device_info.num_ce) + { + return FALSE32; + } + + return TRUE32; +} + +#if !(AND_FPART_ONLY) + +FTLFunctions * +_LookupFTL + (UInt32 major_ver) +{ + UInt32 idx; + + for (idx = 0; NULL != g_ftl_registry[idx].registrar; idx++) + { + if (major_ver == g_ftl_registry[idx].major_ver) + { + return g_ftl_registry[idx].registrar(); + } + } + WMR_PRINT(ERROR, "Unsupported FTL major ver: %d\n", major_ver); + return NULL; +} + +VFLFunctions * +_LookupVFL + (UInt32 major_ver) +{ + UInt32 idx; + + for (idx = 0; NULL != g_vfl_registry[idx].registrar; idx++) + { + if (major_ver == g_vfl_registry[idx].major_ver) + { + return g_vfl_registry[idx].registrar(); + } + } + WMR_PRINT(ERROR, "Unsupported VFL major ver: %d\n", major_ver); + return NULL; +} + +#endif // ! AND_FPART_ONLY + +FPartFunctions * +_LookupFPart + (UInt32 major_ver) +{ + UInt32 idx; + + for (idx = 0; NULL != g_fpart_registry[idx].registrar; idx++) + { + if (major_ver == g_fpart_registry[idx].major_ver) + { + return g_fpart_registry[idx].registrar(); + } + } + WMR_PRINT(ERROR, "Unsupported FPart major ver: %d\n", major_ver); + return NULL; +} + +void +_GetDeviceInfo + (LowFuncTbl *fil) +{ + _device_info.num_ce = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + _device_info.main_bytes_per_page = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + _device_info.total_meta_per_page = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_SPARE); + _device_info.lba_per_page = fil->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); +} + + +#if !(AND_FPART_ONLY) +static void +_ClearFILStatistics(void) +{ + FILStatistics fil_stats; + + WMR_MEMSET(&fil_stats, 0, sizeof(fil_stats)); + FIL_SetStruct(AND_STRUCT_FIL_STATISTICS, &fil_stats, sizeof(fil_stats)); +} +#endif //!(AND_FPART_ONLY) diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.h b/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.h new file mode 100644 index 0000000..1b00839 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBoot.h @@ -0,0 +1,208 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// + +#ifndef _WHIMORY_BOOT_H_ +#define _WHIMORY_BOOT_H_ + +#include "WMRTypes.h" +#include "FTL.h" +#include "VFL.h" +#include "FPart.h" + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus +//////////////////////////////////////////////////////////////////////////////// +// Public structure definitions +//////////////////////////////////////////////////////////////////////////////// + +typedef enum _WhimoryBootCode +{ + kWhimoryOk = 0, + + kWhimoryWarning = (1 << 29), + kWhimoryWarningUnformatted, + kWhimoryEpochMismatch_Deprecated, + kWhimoryMinorVersionMismatch, + kWhimoryMajorVersionNotAvailable, + kWhimoryBirthVersionTooNew, + + kWhimoryError = (1 << 30), + kWhimoryErrMissingHardware, + kWhimoryErrOutOfMemory, + kWhimoryErrUnsupportedVersion, + kWhimoryErrSetup, + kWhimoryErrUnitTestFailed, + kWhimoryErrCorruptedFormat, +} WhimoryBootCode; + +#define kWhimoryBootOptionLowPower (1 << 0) +#define kWhimoryBootOptionForceFtlRecovery (1 << 1) +#define kWhimoryBootOptionFreshOffFTLFormat (1 << 2) +#define kWhimoryBootOptionDisableGCInTrim (1 << 3) +#define kWhimorySetIndexCacheSize (1 << 4) +#define kWhimoryBootOptionReadOnly (1 << 16) // Must align with WMR_INIT_OPEN_READONLY @ bit 16. + +//////////////////////////////////////////////////////////////////////////////// +// Public function declarations +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// WMR_Start +// +// WMR_Start will attempt to locate a signature. It will call OAM_Init() +// and FIL_Init(), so those fuctions should be idempotent. +// Possible non-fatal outcomes: +// kWhimoryWarningUnformatted - Run WMR_Initial_Format() +// +// On kWhimoryOk or warnings, callers can request WMR_PPN_GetFPart() +// +//////////////////////////////////////////////////////////////////////////////// + +WhimoryBootCode +WMR_Start + (UInt32 fpart_major_ver, + UInt32 fpart_options, + UInt32 boot_options); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_Open +// +// WMR_Open will open a block device if the media is properly formatted +// and return appropriate warnings if the device needs to be formatted or +// repaired. +// +//////////////////////////////////////////////////////////////////////////////// + +WhimoryBootCode +WMR_Open + (UInt32 *total_sectors, + UInt32 *sector_size, + UInt32 *index_cache, + UInt32 boot_options); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_Format +// +// Format the media with a given set of preferred versions +// +//////////////////////////////////////////////////////////////////////////////// + +WhimoryBootCode +WMR_Initial_Format + (UInt32 fpart_major_ver, + UInt32 fpart_options, + UInt32 fpart_format_options, + UInt32 vfl_major_ver, + UInt32 vfl_options, + UInt32 ftl_major_ver, + UInt32 ftl_options, + UInt32 num_keepout_blocks, + UInt32 megabytes_for_ftl); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_Partition +// +// Re-size the portion of the VFL that is visible to FTL. +// A value of 0 gives the entire media to FTL. +// +//////////////////////////////////////////////////////////////////////////////// + +WhimoryBootCode +WMR_Partition + (UInt32 megabytes_for_ftl); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_Update +// +// Update the physical format if newer format is supported by this software. +// Optionally require backward compatiblity and saving user data +// +//////////////////////////////////////////////////////////////////////////////// + +WhimoryBootCode +WMR_Update + (const BOOL32 keep_backward_compatibility, + const BOOL32 save_data, + UInt32 vfl_major_ver, + UInt32 vfl_options, + UInt32 ftl_major_ver, + UInt32 ftl_options, + UInt32 num_keepout_blocks); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_Close +// +// Gracefully shut down the block device, deallocate all buffers, and return +// static variables to initial state such that WMR_Open can be called again. +// +//////////////////////////////////////////////////////////////////////////////// + +void +WMR_Close + (void); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_PPN_CtrlIO +// +// Generic IOCtl interface to all layers of whimory. Caller must specifiy data +// buffer size in incoming size pointer. +// +//////////////////////////////////////////////////////////////////////////////// + +BOOL32 +WMR_PPN_CtrlIO + (UInt32 ctrlio_type, + void *data, + UInt32 *size); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_PPNGetStruct +// +// Get a parameter from RAM +// +//////////////////////////////////////////////////////////////////////////////// + +BOOL32 +WMR_PPNGetStruct + (UInt32 ctrlio_type, + void *data, + UInt32 *size); + +//////////////////////////////////////////////////////////////////////////////// +// WMR_PPNGetCurrentSignature +// +// Get the signature representing the current software state +// +//////////////////////////////////////////////////////////////////////////////// + +const struct WhimorySignature * +WMR_PPNGetSignature + (void); + +//////////////////////////////////////////////////////////////////////////////// +// Accessors +// +// Get a parameter from RAM +// +//////////////////////////////////////////////////////////////////////////////// +FTLFunctions *WMR_PPN_GetFTL + (void); +VFLFunctions *WMR_PPN_GetVFL + (void); +FPartFunctions *WMR_PPN_GetFPart + (void); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //_WHIMORY_BOOT_H_ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBootTypes.h b/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBootTypes.h new file mode 100644 index 0000000..334d0f5 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Boot/WhimoryBootTypes.h @@ -0,0 +1,78 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// + +#ifndef _WHIMORY_BOOT_TYPES_H_ +#define _WHIMORY_BOOT_TYPES_H_ + +#define WHIMORY_SIGNATURE_SIZE (3 * 512) +struct WhimorySignature +{ + UInt32 magic; +#define WHIMORY_SIGNATURE_MAGIC (0x776D7278) // 'wmrx' + UInt32 _deprecated_epoch; // 0 for new devices + UInt32 whimory_ver_at_birth; // SW older than birth epoch may not open this drive +#define WHIMORY_SIGNATURE_VER_PPN_CUR (6) + UInt32 ftl_major_ver; + UInt32 ftl_minor_ver; + UInt32 ftl_options; + UInt32 vfl_major_ver; + UInt32 vfl_minor_ver; + UInt32 vfl_options; + UInt32 fpart_major_ver; + UInt32 fpart_minor_ver; + UInt32 fpart_options; // debug-only: need these to find signature + UInt32 num_keepout_blocks; + + UInt32 num_chip_enables; + + // Informational +#define WHIMORY_SW_VER_MAX_LENGTH (128) + UInt8 sw_ver_str[WHIMORY_SW_VER_MAX_LENGTH]; + UInt32 fpart_format_options; // options used for initial format + +#define WHIMORY_FTL_PARTITION_VALID_BIT (1UL << 31) +#define WHIMORY_FTL_PARTITION_SIZE_MASK (0x7fffffffUL) + UInt32 megabytes_for_ftl; + + // Reserve to 1.5KB + UInt8 reserved[WHIMORY_SIGNATURE_SIZE - (16 * sizeof(UInt32)) - 128]; +}; + +struct WhimoryDeviceInfo +{ + UInt32 num_ce; + UInt32 main_bytes_per_page; + UInt32 total_meta_per_page; + UInt32 lba_per_page; +}; + +typedef FTLFunctions * (*FTL_Registrar)(void); +typedef struct +{ + UInt32 major_ver; + FTL_Registrar registrar; +} Boot_FTL_Registry_t; + +typedef VFLFunctions * (*VFL_Registrar)(void); +typedef struct +{ + UInt32 major_ver; + VFL_Registrar registrar; +} Boot_VFL_Registry_t; + +typedef FPartFunctions * (*FPart_Registrar)(void); +typedef struct +{ + UInt32 major_ver; + FPart_Registrar registrar; +} Boot_FPart_Registry_t; + +#endif //_WHIMORY_BOOT_TYPES_H_ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPart.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPart.c new file mode 100644 index 0000000..e7f6d2d --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPart.c @@ -0,0 +1,1647 @@ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "PPNMiscTypes.h" +#include "PPNFPartTypes.h" +#include "FPart.h" +#include "VFL.h" +#include "WMRBuf.h" +#include "WhimoryBoot.h" + +#define kPPNFPartMinorVersion (1) + +#define BYTES_PER_PAGE_META (mcxt->dev.lbas_per_page * mcxt->dev.lba_meta_bytes_buffer) + +static PPNFPart_MainCxt *g_ppnfpartMain = NULL; +extern UInt32 g_num_keepout_blocks; + +static BOOL32 _findSpecialBlock + (PPNFPart_MainCxt *mcxt, + UInt16 *special_block_cache_index, + UInt16 type); + +#if !AND_READONLY + +static void +_setSpareFPartCxt + (PPNFPart_MainCxt *mcxt, + PPNFPart_Spare *spare, + UInt16 vfl_special_type, + UInt8 index) +{ + WMR_MEMSET(spare, 0, sizeof(PPNFPart_Spare)); + spare->spare_type = PPNFPART_SPECIAL_BLOCK_SPARE_TYPE; + spare->vfl_special_type = vfl_special_type; + spare->index = index; +} + +static void +_copySpareFPartCxtToMeta + (PPNFPart_MainCxt *mcxt, + PPNFPart_Spare *spare, + UInt8 *meta) +{ + UInt16 lba_idx; + + for (lba_idx = 0; lba_idx < mcxt->dev.lbas_per_page; lba_idx++) + { + WMR_MEMCPY(meta, spare, sizeof(PPNFPart_Spare)); + meta += mcxt->dev.lba_meta_bytes_buffer; + } +} + +#endif // !AND_READONLY + +static void +_copySpareFPartCxtFromMeta + (PPNFPart_MainCxt *mcxt, + PPNFPart_Spare *spare, + UInt8 *meta) +{ + WMR_MEMCPY(spare, meta, sizeof(PPNFPart_Spare)); +} + +static BOOL32 +_ppnfpartInit + (PPNFPart_MainCxt * mcxt, + LowFuncTbl *pFILFunctions, + UInt32 dwOptions) +{ + if (mcxt->initialized) + { + return TRUE32; + } + + WMR_ASSERT(sizeof(PPNFPart_Spare) == 16); + + mcxt->fil = pFILFunctions; + ppnMiscFillDevStruct(&mcxt->dev, mcxt->fil); + mcxt->done_mapping = FALSE32; + + WMR_BufZone_Init(&mcxt->zone); + mcxt->command = WMR_Buf_Alloc_ForDMA(&mcxt->zone, sizeof(PPNCommandStruct)); + WMR_BufZone_FinishedAllocs(&mcxt->zone); + WMR_BufZone_Rebase(&mcxt->zone, (void **)&mcxt->command); + WMR_BufZone_FinishedRebases(&mcxt->zone); + + mcxt->special_blocks = (SpecialBlockCacheEntryType*)WMR_MALLOC(AND_MAX_SPECIAL_BLOCKS * + sizeof(SpecialBlockCacheEntryType)); + + mcxt->special_blocks_idx = 0; + mcxt->initialized = TRUE32; + + return TRUE32; +} + +static void +_ppnfpartChangeCacheState + (PPNFPart_MainCxt * mcxt, + BOOL32 validate) +{ + if (validate) + { + mcxt->done_mapping = TRUE32; + } + else + { + WMR_MEMSET(mcxt->special_blocks, 0xFF, (AND_MAX_SPECIAL_BLOCKS * sizeof(SpecialBlockCacheEntryType))); + mcxt->special_blocks_idx = 0; + mcxt->done_mapping = FALSE32; + } +} + +static void +_ppnfpartClose + (PPNFPart_MainCxt * mcxt) +{ + _ppnfpartChangeCacheState(mcxt, FALSE32); + WMR_BufZone_Free(&mcxt->zone); + WMR_FREE(mcxt->special_blocks, (AND_MAX_SPECIAL_BLOCKS * sizeof(SpecialBlockCacheEntryType))); + WMR_MEMSET(mcxt, 0, sizeof(PPNFPart_MainCxt)); +} + +static UInt16 +_countBlocksInHeader + (PPNFPart_MainCxt *mcxt, + SpecialBlockHeaderStruct *header) +{ + UInt16 block_address_count; + + for (block_address_count = 0; + block_address_count < PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE; + block_address_count++) + { + if (header->block_addresses[block_address_count].bank == 0xFFFF) + { + break; + } + } + return block_address_count; +} + +static UInt16 +_getMajorVersion + (PPNFPart_MainCxt *mcxt, + UInt32 version) +{ + return (UInt16)(version >> 16); +} + +void +_initSpecialBlockHeader + (SpecialBlockHeaderStruct *header, + SpecialBlockCacheEntryType * blocks, + UInt16 block_count, + UInt32 data_size, + UInt32 copy_number) +{ + UInt16 i; + + WMR_MEMSET(header, 0x00, sizeof(SpecialBlockHeaderStruct)); + WMR_MEMSET(header->block_addresses, 0xFF, + (PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE * sizeof(SpecialBlockAddress))); + for (i = 0; i < block_count; i++) + { + header->block_addresses[i].bank = blocks[i].bank; + header->block_addresses[i].block = blocks[i].block; + } + header->data_size = data_size; + header->version = PPNFPART_STRUCTURE_VERSION; + header->copy_number = copy_number; +} + +static BOOL32 +_findSpecialBlockInCache + (PPNFPart_MainCxt *mcxt, + UInt16 *special_block_cache_index, + UInt16 type) +{ + UInt16 i; + + // try the cache first + for (i = 0; i < mcxt->special_blocks_idx; i++) + { + if (andSBGetCode(mcxt->special_blocks[i].type) == andSBGetCode(type)) + { + if (special_block_cache_index != NULL) + { + *special_block_cache_index = i; + } + return TRUE32; + } + } + return FALSE32; +} + +static UInt16 +_countTypeOfBlocksInCache + (PPNFPart_MainCxt *mcxt, + UInt16 type) +{ + UInt16 i, count = 0; + + for (i = 0; i < mcxt->special_blocks_idx; i++) + { + if (andSBGetCode(mcxt->special_blocks[i].type) == andSBGetCode(type)) + { + count++; + } + } + return count; +} + +static BOOL32 +_isSpecialBlockInCache + (PPNFPart_MainCxt *mcxt, + UInt16 bank, + UInt16 block, + UInt16 type) +{ + UInt16 i; + + for (i = 0; i < mcxt->special_blocks_idx; i++) + { + if ((mcxt->special_blocks[i].bank == bank) && + (mcxt->special_blocks[i].block == block) && + (andSBGetCode(mcxt->special_blocks[i].type) == andSBGetCode(type))) + { + return TRUE32; + } + } + return FALSE32; +} + +static BOOL32 +_addSingleSpecialBlockToCache + (PPNFPart_MainCxt *mcxt, + UInt16 bank, + UInt16 block, + UInt16 type) +{ + UInt16 i; + + // check if the block is in the list (and ignore the add call if it is) + if (_isSpecialBlockInCache(mcxt, bank, block, type)) + { + return TRUE32; + } + + // make sure we have space + if (mcxt->special_blocks_idx >= AND_MAX_SPECIAL_BLOCKS) + { + WMR_PRINT(ERROR, TEXT("[FPART:ERR] no more space in special blcok list index = %d (l:%d)\n"), + mcxt->special_blocks_idx, __LINE__); + return FALSE32; + } + + // add new block to the list + WMR_ASSERT(bank < mcxt->dev.num_of_banks); + WMR_ASSERT(block < mcxt->dev.blocks_per_cau); + + mcxt->special_blocks[mcxt->special_blocks_idx].bank = bank; + mcxt->special_blocks[mcxt->special_blocks_idx].block = block; + mcxt->special_blocks[mcxt->special_blocks_idx].type = type; + mcxt->special_blocks_idx++; + for (i = (mcxt->special_blocks_idx - 1); i > 0; i--) + { + SpecialBlockCacheEntryType temp_sb_entry; + if (mcxt->special_blocks[i].type > mcxt->special_blocks[i - 1].type) + { + WMR_MEMCPY(&temp_sb_entry, &mcxt->special_blocks[i], sizeof(SpecialBlockCacheEntryType)); + WMR_MEMCPY(&mcxt->special_blocks[i], &mcxt->special_blocks[i - 1], sizeof(SpecialBlockCacheEntryType)); + WMR_MEMCPY(&mcxt->special_blocks[i - 1], &temp_sb_entry, sizeof(SpecialBlockCacheEntryType)); + } + else if (mcxt->special_blocks[i].type == mcxt->special_blocks[i - 1].type) + { + if (mcxt->special_blocks[i].bank > mcxt->special_blocks[i - 1].bank) + { + WMR_MEMCPY(&temp_sb_entry, &mcxt->special_blocks[i], sizeof(SpecialBlockCacheEntryType)); + WMR_MEMCPY(&mcxt->special_blocks[i], &mcxt->special_blocks[i - 1], sizeof(SpecialBlockCacheEntryType)); + WMR_MEMCPY(&mcxt->special_blocks[i - 1], &temp_sb_entry, sizeof(SpecialBlockCacheEntryType)); + } + else if (mcxt->special_blocks[i].bank == mcxt->special_blocks[i - 1].bank) + { + if (mcxt->special_blocks[i].block > mcxt->special_blocks[i - 1].block) + { + WMR_MEMCPY(&temp_sb_entry, &mcxt->special_blocks[i], sizeof(SpecialBlockCacheEntryType)); + WMR_MEMCPY(&mcxt->special_blocks[i], &mcxt->special_blocks[i - 1], + sizeof(SpecialBlockCacheEntryType)); + WMR_MEMCPY(&mcxt->special_blocks[i - 1], &temp_sb_entry, sizeof(SpecialBlockCacheEntryType)); + } + } + } + } + return TRUE32; +} + +#if !AND_READONLY + +static void +_removeSingleSpecialBlockFromCache + (PPNFPart_MainCxt *mcxt, + UInt16 bank, + UInt16 block) +{ + UInt16 i; + BOOL32 found_block = FALSE32; + + // mcxt->special_blocks is an ordered list + // removing an item from the list should cause the other items to be pulled in (and keep the order) + + for (i = 0; i < mcxt->special_blocks_idx; i++) + { + if ((bank == mcxt->special_blocks[i].bank) && (block == mcxt->special_blocks[i].block)) + { + mcxt->special_blocks_idx--; + if (i == mcxt->special_blocks_idx) + { + // if we remove the last item in the list then we are done + break; + } + found_block = TRUE32; + } + if (found_block) + { + WMR_MEMCPY(&mcxt->special_blocks[i], &mcxt->special_blocks[i + 1], sizeof(SpecialBlockCacheEntryType)); + } + } +} + +#endif // !AND_READONLY + +static BOOL32 +_addSpecialBlocksToCache + (PPNFPart_MainCxt *mcxt, + SpecialBlockAddress * blocks, + UInt16 block_count, + UInt16 type) +{ + UInt16 i; + + for (i = 0; i < block_count; i++) + { + if (!_addSingleSpecialBlockToCache(mcxt, blocks[i].bank, blocks[i].block, type)) + { + WMR_PRINT(ERROR, TEXT("[FPART:ERR] failed to add special block (bank:0x%X, block:0x%X, type:0x%X)(l:%d)\n"), + blocks[i].bank, blocks[i].block, type, __LINE__); + return FALSE32; + } + } + + return TRUE32; +} + +static BOOL32 +_findSpecialBlock + (PPNFPart_MainCxt *mcxt, + UInt16 *special_block_cache_index, + UInt16 type) +{ + Buffer *buf = NULL; + UInt16 block, bank; + PPNStatusType status; + UInt8 **bbt = NULL; + BOOL32 res = FALSE32; + + // try the cache first + if (_findSpecialBlockInCache(mcxt, special_block_cache_index, type) == TRUE32) + { + return TRUE32; + } + + if (mcxt->done_mapping == TRUE32) + { + return FALSE32; + } + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + + // read the BBTs + bbt = (UInt8**)WMR_MALLOC(sizeof(UInt8*) * mcxt->dev.num_of_banks); + WMR_MEMSET(bbt, 0, (sizeof(UInt8*) * mcxt->dev.num_of_banks)); + + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + bbt[bank] = (UInt8*)WMR_MALLOC(sizeof(UInt8) * ((mcxt->dev.blocks_per_cau >> 3) + 1)); + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, PPN_COMMAND_CAUBBT, + PPN_NO_OPTIONS, bank, 0, 0, FALSE32, buf->pData, NULL); + if (status & PPN_OTHERS_STATUS_OP_FAILED) + { + goto clean_and_return; + } + WMR_MEMCPY(bbt[bank], buf->pData, (sizeof(UInt8) * ((mcxt->dev.blocks_per_cau >> 3) + 1))); + } + + for (block = mcxt->dev.blocks_per_cau - 1; block >= PPN_SPECIAL_BLOCK_LIMIT(&mcxt->dev); block--) + { + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + UInt16 page; + + status = 0; + + if (!ppnMiscIsBlockGood(bbt[bank], block)) + { + continue; + } + + for (page = 0; page < mcxt->dev.pages_per_block_slc && + (!(status & PPN_READ_STATUS_CLEAN)); page++) + { + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, + PPN_COMMAND_READ, PPN_NO_OPTIONS, + bank, block, page, TRUE32, + buf->pData, buf->pSpare); + if (!(status & PPN_READ_STATUS_INVALID_DATA)) + { + SpecialBlockHeaderStruct *temp_header = (SpecialBlockHeaderStruct*)buf->pData; + PPNFPart_Spare *temp_spare = (PPNFPart_Spare *)buf->pSpare; + + // check that this is a special block we identify + if (temp_spare->spare_type != PPNFPART_SPECIAL_BLOCK_SPARE_TYPE) + { + // this is not a special block, skip to the next one + break; + } + // this is a special block, check if this page contains a header + else if (temp_spare->index == 0) + { + UInt16 idx, blocks_in_header = 0; + BOOL32 continue_on_header_error = FALSE32; + SpecialBlockAddress special_block_address[PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE]; + + // verify that what we read makes sense + // check that the header makes sense + if (_getMajorVersion(mcxt, temp_header->version) > + _getMajorVersion(mcxt, PPNFPART_STRUCTURE_VERSION)) + { + WMR_PRINT(ERROR, TEXT("[PPNFPART:ERR] special block header version does not match (0x%08X)\n"), + temp_header->version); + continue_on_header_error = TRUE32; + } + + blocks_in_header = _countBlocksInHeader(mcxt, temp_header); + + for (idx = 0; ((idx < blocks_in_header) && + (!continue_on_header_error)); idx++) + { + if ((temp_header->block_addresses[idx].bank >= mcxt->dev.num_of_banks) || + (temp_header->block_addresses[idx].block >= mcxt->dev.blocks_per_cau)) + { + WMR_PRINT(ERROR, TEXT("[PPNFPART:ERR] SB header address is out of range (0x%04X, 0x)\n"), + temp_header->block_addresses[idx].bank, + temp_header->block_addresses[idx].block); + continue_on_header_error = TRUE32; + } + } + + if (continue_on_header_error) + { + continue; + } + + WMR_MEMSET(special_block_address, 0xFF, + (PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE * sizeof(SpecialBlockAddress))); + + for (idx = 0; idx < blocks_in_header; idx++) + { + special_block_address[idx].bank = temp_header->block_addresses[idx].bank; + special_block_address[idx].block = temp_header->block_addresses[idx].block; + } + + if (andSBGetCode(temp_spare->vfl_special_type) == andSBGetCode(type)) + { + _addSpecialBlocksToCache(mcxt, special_block_address, blocks_in_header, + temp_spare->vfl_special_type); + if (special_block_cache_index != NULL) + { + _findSpecialBlockInCache(mcxt, special_block_cache_index, type); + } + res = TRUE32; + goto clean_and_return; + } + + if (!_findSpecialBlockInCache(mcxt, NULL, temp_spare->vfl_special_type)) + { + _addSpecialBlocksToCache(mcxt, special_block_address, blocks_in_header, + temp_spare->vfl_special_type); + } + + // if we got here, the special block was properly processed + break; + } + } + } + } + } + + mcxt->done_mapping = TRUE32; + + clean_and_return: + + if (buf != NULL) + { + BUF_Release(buf); + } + + for (bank = 0; (bbt != NULL) && (bank < mcxt->dev.num_of_banks); bank++) + { + if (bbt[bank] != NULL) + { + WMR_FREE(bbt[bank], (sizeof(UInt8) * ((mcxt->dev.blocks_per_cau >> 3) + 1))); + } + } + + if (bbt != NULL) + { + WMR_FREE(bbt, (sizeof(UInt8*) * mcxt->dev.num_of_banks)); + } + + return res; +} + +// _readSpecialBlockSingleVersionFromSingleRedundantCopy - reads a single version type special block +// from one of the redundant blocks. + +static BOOL32 +_readSpecialBlockSingleVersionFromSingleRedundantCopy + (PPNFPart_MainCxt *mcxt, + void *data, + UInt32 data_size, + SpecialBlockCacheEntryType *sb_address, + UInt32 *copy_number) // increased by one every time the speical block is written +{ + Buffer *buf; + UInt16 valid_pages; + PPNStatusType status; + UInt8 *data_uint8; + UInt32 pages_per_copy = 1, size_to_copy = 0, number_of_copies = mcxt->dev.pages_per_block_slc; + PPNFPart_Spare spare; + + data_uint8 = (UInt8*)data; + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + + for (valid_pages = 0; valid_pages < pages_per_copy; valid_pages++) + { + BOOL32 data_read = FALSE32; + UInt16 copy_to_read_from; + for (copy_to_read_from = 0; (copy_to_read_from < number_of_copies && + !data_read); copy_to_read_from++) + { + UInt16 page_offset = (copy_to_read_from * pages_per_copy) + valid_pages; + + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, + PPN_COMMAND_READ, PPN_NO_OPTIONS, + sb_address->bank, + sb_address->block, + page_offset, + TRUE32, buf->pData, buf->pSpare); + if (!(status & PPN_READ_STATUS_INVALID_DATA)) + { + UInt32 data_offset, data_to_copy; + _copySpareFPartCxtFromMeta(mcxt, &spare, buf->pSpare); + if (valid_pages == 0) + { + SpecialBlockHeaderStruct *header = (SpecialBlockHeaderStruct *)buf->pData; + + // check that this is really what we are looking for + if (spare.vfl_special_type == sb_address->type && + spare.spare_type == PPNFPART_SPECIAL_BLOCK_SPARE_TYPE && + spare.index == 0) + { + if (copy_number != NULL) + { + *copy_number = header->copy_number; + } + if (data_uint8 != NULL) + { + size_to_copy = WMR_MIN(header->data_size, data_size); + } + else + { + size_to_copy = 0; + } + pages_per_copy = (((size_to_copy + sizeof(SpecialBlockHeaderStruct)) / + mcxt->dev.main_bytes_per_page) + + (((size_to_copy + sizeof(SpecialBlockHeaderStruct)) % + mcxt->dev.main_bytes_per_page) ? 1 : 0)); + number_of_copies = mcxt->dev.pages_per_block_slc / pages_per_copy; + } + else + { + continue; + } + data_to_copy = WMR_MIN((mcxt->dev.main_bytes_per_page - + sizeof(SpecialBlockHeaderStruct)), + size_to_copy); + data_offset = sizeof(SpecialBlockHeaderStruct); + + if (data_to_copy && data_uint8 != NULL) + { + WMR_MEMCPY(&data_uint8[0], &buf->pData[data_offset], data_to_copy); + } + data_read = TRUE32; + break; + } + else + { + if (spare.vfl_special_type == sb_address->type && + spare.spare_type == PPNFPART_SPECIAL_BLOCK_SPARE_TYPE && + spare.index == (UInt8)valid_pages) + { + data_offset = ((valid_pages * mcxt->dev.main_bytes_per_page) - + sizeof(SpecialBlockHeaderStruct)); + data_to_copy = WMR_MIN(mcxt->dev.main_bytes_per_page, + (size_to_copy - data_offset)); + + WMR_MEMCPY(&data_uint8[data_offset], buf->pData, data_to_copy); + data_read = TRUE32; + break; + } + else + { + continue; + } + } + } + } + if (!data_read) + { + goto return_error; + } + } + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +static BOOL32 +_readSpecialBlockSingleVersion + (PPNFPart_MainCxt *mcxt, + void *data, + UInt32 data_size, + UInt16 special_block_cache_index, + UInt32 *copy_number) // increased by one every time the speical block is written +{ + UInt16 sb_count, sb_type, block_idx, known_good_index = 0xFFFF; + UInt32 local_copy_number = 0, curr_copy_number = 0; + SpecialBlockCacheEntryType *sb_addresses; + BOOL32 read_valid_copy = FALSE32; + + sb_type = mcxt->special_blocks[special_block_cache_index].type; + sb_count = _countTypeOfBlocksInCache(mcxt, sb_type); + sb_addresses = &mcxt->special_blocks[special_block_cache_index]; + + // loop through the different redundat copies to find the latest version + for (block_idx = 0; block_idx < sb_count; block_idx++) + { + BOOL32 status_reading_from_this_block = FALSE32; + if (read_valid_copy) + { + status_reading_from_this_block = + _readSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, NULL, 0, + &sb_addresses[block_idx], + &local_copy_number); + } + else + { + status_reading_from_this_block = + _readSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, data, data_size, + &sb_addresses[block_idx], + &local_copy_number); + } + + if (status_reading_from_this_block) + { + if (!read_valid_copy) + { + read_valid_copy = TRUE32; + known_good_index = block_idx; + curr_copy_number = local_copy_number; + } + else + { + if (local_copy_number != curr_copy_number) + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] special block with more than one version (type:0x%04X) (line:%d)!\n"), + sb_type, __LINE__); + } + if (local_copy_number > curr_copy_number) + { + if (_readSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, data, data_size, + &sb_addresses[block_idx], + &local_copy_number)) + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] successfully copied new SB version (new:0x08X, old:0x08X, type:0x%04X) (line:%d)!\n"), + local_copy_number, curr_copy_number, sb_type, __LINE__); + curr_copy_number = local_copy_number; + known_good_index = block_idx; + } + else + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] failed to copy new SB version (new:0x08X, old:0x08X, type:0x%04X) (line:%d)!\n"), + local_copy_number, curr_copy_number, sb_type, __LINE__); + + // read the copy of the SB we read successfully earlier + if (!_readSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, data, data_size, + &sb_addresses[known_good_index], + &local_copy_number)) + { + // if a good copy became bad, fail here + WMR_PRINT(ERROR, TEXT( + "[PPNFPART:ERR] failed to read SB from known good copy (type:0x%04X) (line:%d)!\n"), + sb_type, __LINE__); + return FALSE32; + } + } + } + } + } + else + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] failed to read from assigned SB copy (bank:0x%04X, block:0x%04X, type:0x%04X) (line:%d)!\n"), + sb_addresses[block_idx].bank, sb_addresses[block_idx].block, sb_type, __LINE__); + } + } + if (read_valid_copy && (copy_number != NULL)) + { + *copy_number = local_copy_number; + } + return read_valid_copy; +} + +#ifndef AND_READONLY +static BOOL32 +_writeSpecialBlockSingleVersion + (PPNFPart_MainCxt *mcxt, + void *data, + UInt32 data_size, + UInt16 special_block_cache_index) +{ + const UInt16 pages_per_copy = (((data_size + sizeof(SpecialBlockHeaderStruct)) / + mcxt->dev.main_bytes_per_page) + + (((data_size + sizeof(SpecialBlockHeaderStruct)) % + mcxt->dev.main_bytes_per_page) ? 1 : 0)); + const UInt16 redundancy_per_block = (mcxt->dev.pages_per_block_slc / pages_per_copy); + Buffer *buf; + UInt16 sb_count, page_offset, sb_type, replace_block_index = 0xFFFF; + UInt8 *data_uint8; + SpecialBlockCacheEntryType *sb_addresses; + SpecialBlockHeaderStruct header; + PPNFPart_Spare spare; + UInt32 copy_number = 0; + BOOL32 read_previous_copy_status, replace_bad_block = FALSE32; + BOOL32 done_writing_per_copy[PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE] = { FALSE32 }; + + data_uint8 = (UInt8*)data; + buf = BUF_Get(BUF_MAIN_AND_SPARE); + sb_type = mcxt->special_blocks[special_block_cache_index].type; + sb_count = _countTypeOfBlocksInCache(mcxt, sb_type); + sb_addresses = &mcxt->special_blocks[special_block_cache_index]; + + // try to read the previous version of the sb + read_previous_copy_status = _readSpecialBlockSingleVersion(mcxt, NULL, 0, special_block_cache_index, ©_number); + if (!read_previous_copy_status) + { + copy_number = 0; + } + else + { + copy_number++; + } + WMR_PRINT(ALWAYS, "Writing special block type:0x%04X copy_number:0x%08X\n", sb_type, copy_number); + // prepare the header + _initSpecialBlockHeader(&header, sb_addresses, sb_count, data_size, copy_number); + + do + { + UInt32 sb_start_index = 0, sb_copy = 0; + if (replace_bad_block) + { + SpecialBlockAddress bad_block, new_block; + VFLFunctions *_vfl; + PPNStatusType status; + + bad_block.bank = sb_addresses[replace_block_index].bank; + bad_block.block = sb_addresses[replace_block_index].block; + + // erase the bad block and verify no stale data + ppnMiscSingleOperation(&mcxt->dev, mcxt->command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, bad_block.bank, bad_block.block, + 0, TRUE32, NULL, NULL); + + for (page_offset = 0; page_offset < mcxt->dev.pages_per_block_slc; page_offset++) + { + PPNFPart_Spare *spare = (PPNFPart_Spare*)buf->pSpare; + ((PPNFPart_Spare*)buf->pSpare)->spare_type = PPNFPART_SPECIAL_BLOCK_SPARE_TYPE; + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, PPN_COMMAND_READ, + PPN_NO_OPTIONS, bad_block.bank, bad_block.block, + page_offset, TRUE32, buf->pData, buf->pSpare); + if ((!(status & PPN_READ_STATUS_INVALID_DATA)) && + (spare->spare_type == PPNFPART_SPECIAL_BLOCK_SPARE_TYPE)) + { + WMR_PRINT(ERROR, TEXT( + "[PPNFPART:ERR] after erasing a failed block twice it has stale valid data (bank:0x%X, block:0x%X) (line:%d)!\n"), + bad_block.bank, bad_block.block, __LINE__); + goto return_error; + } + } + + // allocate replacement block, mark this block as grown bad + _vfl = WMR_PPN_GetVFL(); + if (_vfl == NULL) + { + WMR_PRINT(ERROR, TEXT("[PPNFPART:ERR] failed to find vfl (bank:0x%X, block:0x%X) fail (line:%d)!\n"), + bad_block.bank, bad_block.block, __LINE__); + goto return_error; + } + if (!_vfl->MarkBlockAsGrownBad(&bad_block)) + { + WMR_PRINT(ERROR, TEXT( + "[PPNFPART:ERR] failed to mark block as grown bad (bank:0x%X, block:0x%X) fail (line:%d)!\n"), + bad_block.bank, bad_block.block, __LINE__); + goto return_error; + } + _removeSingleSpecialBlockFromCache(mcxt, bad_block.bank, bad_block.block); + if (!_vfl->AllocateSpecialBlock(&new_block, sb_type)) + { + WMR_PRINT(ERROR, TEXT( + "[PPNFPART:ERR] failed to mark block as grown bad (bank:0x%X, block:0x%X) fail (line:%d)!\n"), + bad_block.bank, bad_block.block, __LINE__); + goto return_error; + } + sb_addresses[replace_block_index].bank = new_block.bank; + sb_addresses[replace_block_index].block = new_block.block; + sb_start_index = replace_block_index; + replace_block_index = 0xFFFF; + replace_bad_block = FALSE32; + copy_number++; // change the copy number + _initSpecialBlockHeader(&header, sb_addresses, sb_count, data_size, copy_number); + WMR_MEMSET(done_writing_per_copy, 0, sizeof(BOOL32) * PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE); + } + + for (sb_copy = sb_start_index; (!done_writing_per_copy[sb_copy]) && (!replace_bad_block); + sb_copy = ((sb_copy + 1) % sb_count)) + { + UInt16 i, j; + PPNStatusType status; + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, PPN_COMMAND_ERASE, PPN_NO_OPTIONS, + sb_addresses[sb_copy].bank, sb_addresses[sb_copy].block, + 0, TRUE32, NULL, NULL); + if (status & PPN_ERASE_STATUS_FAIL) + { + WMR_PRINT(ALWAYS, TEXT("[PPNFPART:WRN] erasing special block (bank:0x%X, block:0x%X) fail (line:%d)!\n"), + sb_addresses[sb_copy].bank, sb_addresses[sb_copy].block, __LINE__); + + replace_block_index = sb_copy; + replace_bad_block = TRUE32; + break; + } + + page_offset = 0; + for (i = 0; (i < redundancy_per_block) && (!replace_bad_block); i++) + { + for (j = 0; (j < pages_per_copy) && (!replace_bad_block); j++) + { + UInt16 data_offset = (j == 0 ? 0 : ((j * mcxt->dev.main_bytes_per_page) - + sizeof(SpecialBlockHeaderStruct))); + UInt16 data_to_copy = (j == 0 ? + WMR_MIN((mcxt->dev.main_bytes_per_page - sizeof(SpecialBlockHeaderStruct)), + data_size) : + WMR_MIN(mcxt->dev.main_bytes_per_page, + (data_size - data_offset))); + + WMR_MEMSET(buf->pData, 0x00, mcxt->dev.main_bytes_per_page); + if (j == 0) + { + WMR_MEMCPY(buf->pData, &header, sizeof(SpecialBlockHeaderStruct)); + WMR_MEMCPY(&buf->pData[sizeof(SpecialBlockHeaderStruct)], data, data_to_copy); + } + else + { + WMR_MEMCPY(buf->pData, &data_uint8[data_offset], data_to_copy); + } + + _setSpareFPartCxt(mcxt, &spare, sb_type, (UInt8)j); + _copySpareFPartCxtToMeta(mcxt, &spare, buf->pSpare); + + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, + PPN_COMMAND_PROGRAM, PPN_NO_OPTIONS, + sb_addresses[sb_copy].bank, + sb_addresses[sb_copy].block, + page_offset, TRUE32, + buf->pData, buf->pSpare); + if (status & PPN_PROGRAM_STATUS_FAIL) + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] programming special block (bank:0x%X, block:0x%X) fail (line:%d)!\n"), + sb_addresses[i].bank, sb_addresses[i].block, __LINE__); + replace_block_index = sb_copy; + replace_bad_block = TRUE32; + } + page_offset++; + } + } + + // program unused pages in the block + while ((page_offset < mcxt->dev.pages_per_block_slc) && (!replace_bad_block)) + { + WMR_MEMSET(buf->pData, 0x00, mcxt->dev.main_bytes_per_page); + _setSpareFPartCxt(mcxt, &spare, sb_type, 0xFF); + _copySpareFPartCxtToMeta(mcxt, &spare, buf->pSpare); + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, + PPN_COMMAND_PROGRAM, PPN_NO_OPTIONS, + sb_addresses[sb_copy].bank, + sb_addresses[sb_copy].block, + page_offset, TRUE32, + buf->pData, buf->pSpare); + if (status & PPN_PROGRAM_STATUS_FAIL) + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] programming special block (bank:0x%X, block:0x%X) fail (line:%d)!\n"), + sb_addresses[sb_copy].bank, sb_addresses[sb_copy].block, __LINE__); + replace_block_index = sb_copy; + replace_bad_block = TRUE32; + } + page_offset++; + } + + if (!replace_bad_block) + { + done_writing_per_copy[sb_copy] = TRUE32; + } + } + } + while (replace_bad_block); + + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} +#endif // ! AND_READONLY + +static BOOL32 +_ppnfpartReadSpecialBlock + (PPNFPart_MainCxt *mcxt, + void *data, + UInt32 data_size, + UInt16 type) +{ + UInt16 special_block_cache_index; + BOOL32 res = FALSE32; + + // find the block addresses + if (_findSpecialBlock(mcxt, &special_block_cache_index, type) == FALSE32) + { + WMR_PRINT(ALWAYS, TEXT("[PPNVFL:WRN] Read: failed to locate special blocks (type = 0x%X) (line:%d)!\n"), + type, __LINE__); + return FALSE32; + } + switch (andSBGetHandler(mcxt->special_blocks[special_block_cache_index].type)) + { + case AND_SB_HANDLER_SINGLE_VERSION: + res = _readSpecialBlockSingleVersion(mcxt, data, data_size, special_block_cache_index, NULL); + break; + + default: + WMR_PRINT(ERROR, TEXT("[PPNVFL:ERR] no support for the special block handler (type = 0x%X) (line:%d)!\n"), + type, __LINE__); + break; + } + return res; +} + +#ifndef AND_READONLY +static BOOL32 +_ppnfpartWriteSpecialBlock + (PPNFPart_MainCxt *mcxt, + void *data, + UInt32 data_size, + UInt16 type) +{ + UInt16 special_block_cache_index; + BOOL32 res = FALSE32; + + // find the block addresses + if (!_findSpecialBlock(mcxt, &special_block_cache_index, type)) + { + WMR_PRINT(ERROR, TEXT("[PPNVFL:ERR] Write: failed to locate special blocks (type = 0x%X) (line:%d)!\n"), + type, __LINE__); + return FALSE32; + } + switch (andSBGetHandler(mcxt->special_blocks[special_block_cache_index].type)) + { + case AND_SB_HANDLER_SINGLE_VERSION: + res = _writeSpecialBlockSingleVersion(mcxt, data, data_size, special_block_cache_index); + break; + + default: + WMR_PRINT(ERROR, TEXT("[PPNVFL:ERR] no support for the special block handler (type = 0x%X) (line:%d)!\n"), + type, __LINE__); + break; + } + return res; +} +#endif // !AND_READONLY + +#if !AND_FPART_ONLY +static BOOL32 +_ppnfpartMapSpecialBlocks + (PPNFPart_MainCxt *mcxt, + SpecialBlockAddress *blocks, + UInt16 *types, + UInt16 *count) +{ + UInt16 i; + + // look for none existing type (marking all the types we find on the way) + _findSpecialBlock(mcxt, NULL, 0); + + if (count != NULL && mcxt->special_blocks_idx != 0) + { + *count = mcxt->special_blocks_idx; + } + else + { + return FALSE32; + } + + if (count != NULL && blocks != NULL && types != NULL) + { + for (i = 0; i < mcxt->special_blocks_idx; i++) + { + blocks[i].bank = mcxt->special_blocks[i].bank; + blocks[i].block = mcxt->special_blocks[i].block; + types[i] = mcxt->special_blocks[i].type; + } + } + + return TRUE32; +} +#endif //!AND_FPART_ONLY + +#if (!AND_FPART_ONLY) || (!defined(AND_READONLY)) +static BOOL32 +_ppnfpartAllocateSpecialBlockType + (PPNFPart_MainCxt *mcxt, + SpecialBlockAddress *blocks, + UInt16 blocks_count, + UInt16 type) +{ + return _addSpecialBlocksToCache(mcxt, blocks, blocks_count, type); +} + +static BOOL32 +_ppnfpartIsSpecialBlockTypeAllocated + (PPNFPart_MainCxt *mcxt, + UInt16 type) +{ + return _findSpecialBlock(mcxt, NULL, type); +} +#endif //(!AND_FPART_ONLY) || (!defined(AND_READONLY)) + +#ifndef AND_READONLY + +#define DEFAULT_PERSISTENT_BLOCK_DATA_SIZE (8192) +static BOOL32 +_WriteDefaultPersistentSpecialBlock + (PPNFPart_MainCxt * mcxt, + VFLFunctions *vfl, + UInt16 special_block_type) +{ + BOOL32 retval = TRUE32; + void *buffer = NULL; + + if (!_ppnfpartIsSpecialBlockTypeAllocated(mcxt, special_block_type)) + { + SpecialBlockAddress chosen_blocks[2]; + + // Need to allocate a constant size buffer, + // indpendent of physical page size + buffer = WMR_MALLOC(DEFAULT_PERSISTENT_BLOCK_DATA_SIZE); + WMR_ASSERT(buffer != NULL); + + WMR_PRINT(INIT, "allocating 0x%04x\n", (UInt32)special_block_type); + + if (!vfl->AllocateSpecialBlock(&chosen_blocks[0], special_block_type) || + !vfl->AllocateSpecialBlock(&chosen_blocks[1], special_block_type)) + { + WMR_PRINT(ERROR, "VFL Failed to allocate special block\n"); + retval = FALSE32; + goto done; + } + + if (!_ppnfpartAllocateSpecialBlockType(mcxt, chosen_blocks, 2, special_block_type)) + { + WMR_PRINT(ERROR, "Failed to assign special blocks to FPart\n"); + retval = FALSE32; + goto done; + } + + WMR_MEMSET(buffer, 0xFF, DEFAULT_PERSISTENT_BLOCK_DATA_SIZE); + + if (!_ppnfpartWriteSpecialBlock(mcxt, buffer, DEFAULT_PERSISTENT_BLOCK_DATA_SIZE, special_block_type)) + { + retval = FALSE32; + goto done; + } + } + + done: + if (NULL != buffer) + { + WMR_FREE(buffer, DEFAULT_PERSISTENT_BLOCK_DATA_SIZE); + } + return retval; +} + +static BOOL32 +_ppnfpartFormat + (PPNFPart_MainCxt *mcxt, + VFLFunctions *vfl, + UInt32 format_options) +{ + if ((format_options & FPART_INIT_OPTION_DEV_UNIQUE) && + !_WriteDefaultPersistentSpecialBlock(mcxt, vfl, AND_SB_TYPE_UNIQUE_INFO)) + { + return FALSE32; + } + + if ((format_options & FPART_INIT_OPTION_DIAG_CTRL) && + !_WriteDefaultPersistentSpecialBlock(mcxt, vfl, AND_SB_TYPE_DIAGNOSTICS)) + { + return FALSE32; + } + + return TRUE32; +} + +#if AND_SUPPORT_NEURALIZE +static Int32 +_ppnfpartNeuralize + (PPNFPart_MainCxt *mcxt) +{ + UInt16 i = 0, j = 0; + Buffer *buf; + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + for (i = 0; i < mcxt->dev.num_of_banks; i++) + { + PPNStatusType status; + + // get the original BBT + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, PPN_COMMAND_CAUBBT, + PPN_NO_OPTIONS, i, 0, 0, FALSE32, buf->pData, NULL); + if (status & PPN_OTHERS_STATUS_OP_FAILED) + { + WMR_PRINT(ERROR, "Unable to fetch BBT\n"); + BUF_Release(buf); + return ANDErrorCodeHwErr; + } + + for (j = 0; j < mcxt->dev.blocks_per_cau; j++) + { + if (ppnMiscIsBlockGood(buf->pData, j) == TRUE32) + { + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, i, j, 0, FALSE32, NULL, NULL); + } + } + } + BUF_Release(buf); + return ANDErrorCodeOk; +} +#endif //AND_SUPPORT_NEURALIZE + +#endif //!AND_READONLY + +static BOOL32 +_g_ppnfpartInit + (LowFuncTbl *pFILFunctions, + UInt32 dwOptions) +{ + if (g_ppnfpartMain == NULL) + { + g_ppnfpartMain = (PPNFPart_MainCxt*)WMR_MALLOC(sizeof(PPNFPart_MainCxt)); + if (g_ppnfpartMain == NULL) + { + WMR_PRINT(ERROR, TEXT("[PPNFPART:ERR] failed allocating g_ppnfpartMain (line:%d))\n"), __LINE__); + return FALSE32; + } + WMR_MEMSET(g_ppnfpartMain, 0, sizeof(PPNFPart_MainCxt)); + } + return _ppnfpartInit(g_ppnfpartMain, pFILFunctions, dwOptions); +} + +BOOL32 +_g_ppnfpartReadSpecialBlock + (void *data, + UInt32 data_size, + UInt16 type) +{ + return _ppnfpartReadSpecialBlock(g_ppnfpartMain, data, data_size, type); +} + +static BOOL32 +_g_ppnfpartReadDeviceUniqueInfo + (UInt8 * data, UInt32 data_size) +{ + return _ppnfpartReadSpecialBlock(g_ppnfpartMain, data, data_size, AND_SB_TYPE_UNIQUE_INFO); +} + +static BOOL32 +_g_ppnfpartReadDiagnosticInfo + (UInt8 * data, UInt32 data_size) +{ + return _ppnfpartReadSpecialBlock(g_ppnfpartMain, data, data_size, AND_SB_TYPE_DIAGNOSTICS); +} + +#ifndef AND_READONLY +static BOOL32 +_g_ppnfpartWriteSpecialBlock + (void *data, + UInt32 data_size, + UInt16 type) +{ + return _ppnfpartWriteSpecialBlock(g_ppnfpartMain, data, data_size, type); +} + +static BOOL32 +_g_ppnfpartWriteDeviceUniqueInfo + (UInt8 *data, + UInt32 data_size) +{ + return _ppnfpartWriteSpecialBlock(g_ppnfpartMain, data, data_size, AND_SB_TYPE_UNIQUE_INFO); +} + +static BOOL32 +_g_ppnfpartWriteDiagnosticInfo + (UInt8 *data, + UInt32 data_size) +{ + return _ppnfpartWriteSpecialBlock(g_ppnfpartMain, data, data_size, AND_SB_TYPE_DIAGNOSTICS); +} +#endif // !AND_READONLY + +#if (!defined(AND_READONLY) && AND_SUPPORT_NEURALIZE) +static BOOL32 +_g_ppnfpartNeuralize + (void) +{ + return _ppnfpartNeuralize(g_ppnfpartMain); +} +#endif //!AND_READONLY && AND_SUPPORT_NEURALIZE + +#if !AND_FPART_ONLY +static BOOL32 +_g_ppnfpartMapSpecialBlocks + (SpecialBlockAddress *blocks, + UInt16 *types, + UInt16 *count) +{ + return _ppnfpartMapSpecialBlocks(g_ppnfpartMain, blocks, types, count); +} + +static BOOL32 +_g_ppnfpartAllocateSpecialBlockType + (SpecialBlockAddress *blocks, + UInt16 blocks_count, + UInt16 type) +{ + return _ppnfpartAllocateSpecialBlockType(g_ppnfpartMain, blocks, blocks_count, type); +} + +static BOOL32 +_g_ppnfpartIsSpecialBlockTypeAllocated + (UInt16 type) +{ + return _ppnfpartIsSpecialBlockTypeAllocated(g_ppnfpartMain, type); +} +#endif //!AND_FPART_ONLY + +#ifndef AND_READONLY +static UInt32 +_g_ppnfpartFormat + (VFLFunctions *vfl, + UInt32 format_options) +{ + return _ppnfpartFormat(g_ppnfpartMain, vfl, format_options); +} +#endif //!AND_READONLY + +static UInt32 +_g_ppnfpartGetMinorVersion + (void) +{ + return kPPNFPartMinorVersion; +} + +static void +_g_ppnfpartClose + (void) +{ + if (g_ppnfpartMain != NULL) + { + _ppnfpartClose(g_ppnfpartMain); + WMR_FREE(g_ppnfpartMain, sizeof(PPNFPart_MainCxt)); + g_ppnfpartMain = NULL; + } +} + +#if !AND_FPART_ONLY +static void +_g_ppnfpartChangeCacheState + (BOOL32 validate) +{ + _ppnfpartChangeCacheState(g_ppnfpartMain, validate); +} +#endif //!AND_FPART_ONLY + +void * +_g_ppnfpartGetSingleCommandStruct + (void) +{ + if (g_ppnfpartMain == NULL) + { + return NULL; + } + return g_ppnfpartMain->command; +} + +void +PPNFPart_Register + (FPartFunctions * pFPartFunctions) +{ + WMR_MEMSET(pFPartFunctions, 0, sizeof(FPartFunctions)); + pFPartFunctions->Init = _g_ppnfpartInit; + pFPartFunctions->GetLowFuncTbl = FIL_GetFuncTbl; + pFPartFunctions->ReadSpecialBlock = _g_ppnfpartReadSpecialBlock; + pFPartFunctions->Close = _g_ppnfpartClose; + pFPartFunctions->GetMinorVersion = _g_ppnfpartGetMinorVersion; + pFPartFunctions->ReadDeviceUniqueInfo = _g_ppnfpartReadDeviceUniqueInfo; + pFPartFunctions->ReadDiagnosticInfo = _g_ppnfpartReadDiagnosticInfo; +#if !AND_FPART_ONLY + pFPartFunctions->ChangeCacheState = _g_ppnfpartChangeCacheState; + pFPartFunctions->MapSpecialBlocks = _g_ppnfpartMapSpecialBlocks; + pFPartFunctions->IsSpecialBlockTypeAllocated = _g_ppnfpartIsSpecialBlockTypeAllocated; + pFPartFunctions->AllocateSpecialBlockType = _g_ppnfpartAllocateSpecialBlockType; +#endif //!AND_FPART_ONLY +#ifndef AND_READONLY + pFPartFunctions->Format = _g_ppnfpartFormat; +#if AND_SUPPORT_NEURALIZE + pFPartFunctions->Neuralize = _g_ppnfpartNeuralize; +#endif //AND_SUPPORT_NEURALIZE + pFPartFunctions->WriteSpecialBlock = _g_ppnfpartWriteSpecialBlock; + pFPartFunctions->WriteDeviceUniqueInfo = _g_ppnfpartWriteDeviceUniqueInfo; + pFPartFunctions->WriteDiagnosticInfo = _g_ppnfpartWriteDiagnosticInfo; +#endif // !AND_READONLY + pFPartFunctions->GetSingleCommandStruct = _g_ppnfpartGetSingleCommandStruct; +} + +static FPartFunctions _ppnfpart_functions; + +FPartFunctions * +PPN_FPart_GetFunctions + (void) +{ + PPNFPart_Register(&_ppnfpart_functions); + return &_ppnfpart_functions; +} + +////////////// +// start - hack to switch units from vanilla to swiss +////////////// + +// _readSpecialBlockSingleVersionFromSingleRedundantCopy - reads a single version type special block +// from one of the redundant blocks. + +static BOOL32 +oldReadSpecialBlockSingleVersionFromSingleRedundantCopy + (PPNFPart_MainCxt *mcxt, + void *data, + UInt32 data_size, + SpecialBlockCacheEntryType *sb_address, + UInt32 *copy_number) // increased by one every time the speical block is written +{ + Buffer *org_buf, *buf; + UInt16 valid_pages; + PPNStatusType status; + UInt8 *data_uint8; + UInt32 pages_per_copy = 1, size_to_copy = 0, number_of_copies = mcxt->dev.pages_per_block_slc; + PPNFPart_Spare spare; + + data_uint8 = (UInt8*)data; + + org_buf = BUF_Get(BUF_MAIN_AND_SPARE); + buf = BUF_Get(BUF_MAIN_AND_SPARE); + + for (valid_pages = 0; valid_pages < pages_per_copy; valid_pages++) + { + BOOL32 data_read = FALSE32; + UInt16 copy_to_read_from; + for (copy_to_read_from = 0; (copy_to_read_from < number_of_copies && + !data_read); copy_to_read_from++) + { + UInt16 page_offset = (copy_to_read_from * pages_per_copy) + valid_pages; + + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->command, + PPN_COMMAND_READ, PPN_NO_OPTIONS, + sb_address->bank, + sb_address->block, + page_offset, + TRUE32, org_buf->pData, org_buf->pSpare); + + WMR_MEMCPY(&buf->pData[0], &org_buf->pData[0], (5 * 1024)); + WMR_MEMCPY(&buf->pData[(5 * 1024)], &org_buf->pSpare[16], 16); + WMR_MEMCPY(&buf->pData[(5 * 1024) + 16], &org_buf->pData[(5 * 1024)], ((3 * 1024) - 16)); + WMR_MEMCPY(&buf->pSpare[0], &org_buf->pSpare[0], 16); + WMR_MEMCPY(&buf->pSpare[16], &org_buf->pSpare[0], 16); + if (!(status & PPN_READ_STATUS_INVALID_DATA)) + { + UInt32 data_offset, data_to_copy; + _copySpareFPartCxtFromMeta(mcxt, &spare, buf->pSpare); + if (valid_pages == 0) + { + SpecialBlockHeaderStruct *header = (SpecialBlockHeaderStruct *)buf->pData; + + // check that this is really what we are looking for + if (spare.vfl_special_type == sb_address->type && + spare.spare_type == PPNFPART_SPECIAL_BLOCK_SPARE_TYPE && + spare.index == 0) + { + if (copy_number != NULL) + { + *copy_number = header->copy_number; + } + if (data_uint8 != NULL) + { + size_to_copy = WMR_MIN(header->data_size, data_size); + } + else + { + size_to_copy = 0; + } + pages_per_copy = (((size_to_copy + sizeof(SpecialBlockHeaderStruct)) / + mcxt->dev.main_bytes_per_page) + + (((size_to_copy + sizeof(SpecialBlockHeaderStruct)) % + mcxt->dev.main_bytes_per_page) ? 1 : 0)); + number_of_copies = mcxt->dev.pages_per_block_slc / pages_per_copy; + } + else + { + continue; + } + data_to_copy = WMR_MIN((mcxt->dev.main_bytes_per_page - + sizeof(SpecialBlockHeaderStruct)), + size_to_copy); + data_offset = sizeof(SpecialBlockHeaderStruct); + + if (data_to_copy && data_uint8 != NULL) + { + WMR_MEMCPY(&data_uint8[0], &buf->pData[data_offset], data_to_copy); + } + data_read = TRUE32; + break; + } + else + { + if (spare.vfl_special_type == sb_address->type && + spare.spare_type == PPNFPART_SPECIAL_BLOCK_SPARE_TYPE && + spare.index == (UInt8)valid_pages) + { + data_offset = ((valid_pages * mcxt->dev.main_bytes_per_page) - + sizeof(SpecialBlockHeaderStruct)); + data_to_copy = WMR_MIN(mcxt->dev.main_bytes_per_page, + (size_to_copy - data_offset)); + + WMR_MEMCPY(&data_uint8[data_offset], buf->pData, data_to_copy); + data_read = TRUE32; + break; + } + else + { + continue; + } + } + } + } + if (!data_read) + { + goto return_error; + } + } + BUF_Release(buf); + BUF_Release(org_buf); + return TRUE32; + + return_error: + BUF_Release(buf); + BUF_Release(org_buf); + return FALSE32; +} + +static BOOL32 +oldReadSpecialBlockSingleVersion + (PPNFPart_MainCxt *mcxt, + void *data, + UInt32 data_size, + UInt16 special_block_cache_index, + UInt32 *copy_number) // increased by one every time the speical block is written +{ + UInt16 sb_count, sb_type, block_idx, known_good_index = 0xFFFF; + UInt32 local_copy_number = 0, curr_copy_number = 0; + SpecialBlockCacheEntryType *sb_addresses; + BOOL32 read_valid_copy = FALSE32; + + sb_type = mcxt->special_blocks[special_block_cache_index].type; + sb_count = _countTypeOfBlocksInCache(mcxt, sb_type); + sb_addresses = &mcxt->special_blocks[special_block_cache_index]; + + // loop through the different redundat copies to find the latest version + for (block_idx = 0; block_idx < sb_count; block_idx++) + { + BOOL32 status_reading_from_this_block = FALSE32; + if (read_valid_copy) + { + status_reading_from_this_block = + oldReadSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, NULL, 0, + &sb_addresses[block_idx], + &local_copy_number); + } + else + { + status_reading_from_this_block = + oldReadSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, data, data_size, + &sb_addresses[block_idx], + &local_copy_number); + } + + if (status_reading_from_this_block) + { + if (!read_valid_copy) + { + read_valid_copy = TRUE32; + known_good_index = block_idx; + curr_copy_number = local_copy_number; + } + else + { + if (local_copy_number != curr_copy_number) + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] special block with more than one version (type:0x%04X) (line:%d)!\n"), + sb_type, __LINE__); + } + if (local_copy_number > curr_copy_number) + { + if (oldReadSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, data, data_size, + &sb_addresses[block_idx], + &local_copy_number)) + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] successfully copied new SB version (new:0x08X, old:0x08X, type:0x%04X) (line:%d)!\n"), + local_copy_number, curr_copy_number, sb_type, __LINE__); + curr_copy_number = local_copy_number; + known_good_index = block_idx; + } + else + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] failed to copy new SB version (new:0x08X, old:0x08X, type:0x%04X) (line:%d)!\n"), + local_copy_number, curr_copy_number, sb_type, __LINE__); + + // read the copy of the SB we read successfully earlier + if (!oldReadSpecialBlockSingleVersionFromSingleRedundantCopy(mcxt, data, data_size, + &sb_addresses[known_good_index], + &local_copy_number)) + { + // if a good copy became bad, fail here + WMR_PRINT(ERROR, TEXT( + "[PPNFPART:ERR] failed to read SB from known good copy (type:0x%04X) (line:%d)!\n"), + sb_type, __LINE__); + return FALSE32; + } + } + } + } + } + else + { + WMR_PRINT(ALWAYS, TEXT( + "[PPNFPART:WRN] failed to read from assigned SB copy (bank:0x%04X, block:0x%04X, type:0x%04X) (line:%d)!\n"), + sb_addresses[block_idx].bank, sb_addresses[block_idx].block, sb_type, __LINE__); + } + } + if (read_valid_copy && (copy_number != NULL)) + { + *copy_number = local_copy_number; + } + return read_valid_copy; +} + +BOOL32 +ppnfpartOldReadSpecialBlock + (void *data, + UInt32 data_size, + UInt16 type) +{ + UInt16 special_block_cache_index; + BOOL32 res = FALSE32; + PPNFPart_MainCxt *mcxt = g_ppnfpartMain; + + // find the block addresses + if (_findSpecialBlock(mcxt, &special_block_cache_index, type) == FALSE32) + { + WMR_PRINT(ALWAYS, TEXT("[PPNVFL:WRN] Read: failed to locate special blocks (type = 0x%X) (line:%d)!\n"), + type, __LINE__); + return FALSE32; + } + switch (andSBGetHandler(mcxt->special_blocks[special_block_cache_index].type)) + { + case AND_SB_HANDLER_SINGLE_VERSION: + res = oldReadSpecialBlockSingleVersion(mcxt, data, data_size, special_block_cache_index, NULL); + break; + + default: + WMR_PRINT(ERROR, TEXT("[PPNVFL:ERR] no support for the special block handler (type = 0x%X) (line:%d)!\n"), + type, __LINE__); + break; + } + return res; +} + +////////////// +// end - hack to switch units from vanilla to swiss +////////////// diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPartTypes.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPartTypes.h new file mode 100644 index 0000000..774374d --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNFPartTypes.h @@ -0,0 +1,69 @@ +#ifndef _PPNFPART_TYPES_H_ +#define _PPNFPART_TYPES_H_ + +#include "WMRConfig.h" +#include "PPNMiscTypes.h" +#include "WMRBufTypes.h" + +/* defines */ + +#define PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE (8) +#define PPNFPART_MAX_SPECIAL_BLOCKS_TYPE (20) + +#define PPNFPART_SPECIAL_BLOCK_SPARE_TYPE (AND_SPARE_TYPE_REGION_FPART + 0x00) + +// On NAND structures - Start + +#define PPNFPART_STRUCTURE_VERSION (0x00000001) // use the two MSB as major - not forward compatible + +// SpecialBlockHeaderStruct - used as a header in special blocks that are managed +// by PPNFPart +typedef struct +{ + struct + { + UInt16 bank; + UInt16 block; + } block_addresses[PPNFPART_MAX_SPECIAL_BLOCKS_PER_TYPE]; + UInt32 version; + UInt32 data_size; + UInt32 copy_number; + UInt32 reserved[21]; // reserving bits and rounding the structure size to 128 bytes +} SpecialBlockHeaderStruct; + +// PPNFPart_Spare - used in the metadata of any speical blcok +// managed by PPNFPart +typedef struct +{ + UInt8 spare_type; // spare type + UInt8 index; // for spcial blocks holding information that cross page boundary + UInt16 vfl_special_type; // shared type (between VFL and FPART) identifying this type of special block + UInt8 reserved1[12]; +} PPNFPart_Spare; + +// On NAND structures - End + +typedef struct +{ + UInt16 bank; + UInt16 block; + UInt16 type; +} SpecialBlockCacheEntryType; + +/* PPNFPart internal structures */ +typedef struct +{ + PPN_DeviceInfo dev; + LowFuncTbl *fil; + SpecialBlockCacheEntryType * special_blocks; // malloc to size AND_MAX_SPECIAL_BLOCKS in init + UInt16 special_blocks_idx; // pointer to the next available entry in the special_blocks array + BOOL32 done_mapping; // flag indicating the cache is up to date - no need to search in nand + + // reserve a single command struct for fpart to + // do physical operations + WMR_BufZone_t zone; + PPNCommandStruct * command; + BOOL32 initialized; +} PPNFPart_MainCxt; // hold all other pointers + +#endif /* _PPNFPART_TYPES_H_ */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNTest.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNTest.c new file mode 100644 index 0000000..28f2a21 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FPart/PPNTest.c @@ -0,0 +1,97 @@ +//Test file compiled only for simulator + +static BOOL32 +ppnMiscTestConversionFunctions +(PPN_DeviceInfo * dev); + +static BOOL32 +_verifyAnAddress +(PPN_DeviceInfo * dev, + UInt16 bank, + UInt16 block, + UInt16 page_offset, + BOOL32 slc) +{ + UInt16 chip_enable_idx, channel, cau; + UInt32 page_address = 0, line_failed = 0; + UInt16 temp_bank, temp_block, temp_page_offset; + BOOL32 temp_slc; + + // convert to a physical address + cau = ppnMiscGetCAUFromBank(dev, bank); + if (!(cau < dev->caus_per_ce)) + { + line_failed = __LINE__; + goto return_error; + } + page_address = ppnMiscConvertToPPNPageAddress(dev, cau, block, page_offset, slc); + chip_enable_idx = ppnMiscGetCEIdxFromBank(dev, bank); + if (!(chip_enable_idx < dev->ces_per_channel)) + { + line_failed = __LINE__; + goto return_error; + } + channel = ppnMiscGetChannelFromBank(dev, bank); + if (!(channel < dev->num_channels)) + { + line_failed = __LINE__; + goto return_error; + } + + // convert back + ppnMiscConvertPhysicalAddressToBankBlockPage(dev, channel, chip_enable_idx, page_address, + &temp_bank, &temp_block, &temp_page_offset, &temp_slc); + if (!((temp_bank == bank) && (temp_block == block) && (temp_page_offset == page_offset) && (slc == temp_slc))) + { + line_failed = __LINE__; + goto return_error; + } + + return TRUE32; + +return_error: + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] fail address conversion: (l:%d)\n"), line_failed)); + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] bank:0x%X, block:0x%X, page_offset:0x%X, slc:0x%X\n"), + bank, block, page_offset, slc)); + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] channel:0x%X, chip_enable_idx:0x%X, cau:0x%X\n"), + channel, chip_enable_idx, cau)); + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] temp_bank:0x%X, temp_block:0x%X, temp_page_offset:0x%X, temp_slc:0x%X\n"), + temp_bank, temp_block, temp_page_offset, temp_slc)); + return FALSE32; +} + +static BOOL32 +ppnMiscTestConversionFunctions +(PPN_DeviceInfo * dev) +{ + UInt16 bank, block, page_offset; + UInt32 counter = 0; + + for (bank = 0; bank < dev->num_of_banks; bank++) + { + for (block = 0; block < dev->blocks_per_cau; block++) + { + for (page_offset = 0; page_offset < dev->pages_per_block_mlc; page_offset++) + { + counter++; + if (!(_verifyAnAddress(dev, bank, block, page_offset, TRUE32))) + { + VFL_ERR_PRINT((TEXT("PPNMISC:ERR] fail address conversion test: (l:%d)\n"), __LINE__)); + return FALSE32; + } + } + for (page_offset = 0; page_offset < dev->pages_per_block_slc; page_offset++) + { + if (!(_verifyAnAddress(dev, bank, block, page_offset, TRUE32))) + { + VFL_ERR_PRINT((TEXT("PPNMISC:ERR] fail address conversion test: (l:%d)\n"), __LINE__)); + return FALSE32; + } + } + } + } + + return counter; +} + + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V.h new file mode 100644 index 0000000..ffa28f7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_H__ +#define __L2V_H__ + +#include "L2V_Types.h" + + +extern L2V_t L2V; +extern UInt8 *L2V_root_depth; + + +#endif // __L2V_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Assert.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Assert.h new file mode 100644 index 0000000..e2e7279 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Assert.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_CASSERT_H__ +#define __L2V_CASSERT_H__ + +#define l2v_assert(e) WMR_ASSERT(e) + +#define CASSERT(x, name) typedef char __CASSERT_##name[(x) ? 1 : -1] + +#define l2v_assert_le(x, y) l2v_assert((x) <= (y)) +#define l2v_assert_lt(x, y) l2v_assert((x) < (y)) +#define l2v_assert_ge(x, y) l2v_assert((x) >= (y)) +#define l2v_assert_gt(x, y) l2v_assert((x) > (y)) +#define l2v_assert_eq(x, y) l2v_assert((x) == (y)) +#define l2v_assert_ne(x, y) l2v_assert((x) != (y)) + +#endif // __L2V_CASSERT_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Config.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Config.h new file mode 100644 index 0000000..e54ef7d --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Config.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_CONFIG_H__ +#define __L2V_CONFIG_H__ + +// Defines the minium page size--ONLY used for easier extent (logical range) configuration +#define L2V_MINPAGESIZE_BITS (b_4 + KiB_bits) + +// Defines the node size +#define L2V_CACHELINE 64 +#define L2V_NODE_SIZE L2V_CACHELINE + +// Defines the memory set aside for the node pool +#define L2V_NODEPOOL_MEM (MiB>>2) + +// Defines the size of a logical tree +#define L2V_TREE_BITS 15 + +// Repack periodicity +#define L2V_REPACK_PERIOD 200 + + +#endif // __L2V_CONFIG_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Defines.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Defines.h new file mode 100644 index 0000000..70d4cdd --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Defines.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_DEFINES_H__ +#define __L2V_DEFINES_H__ + +// Shortcuts for the config +#define b_1 0 +#define b_2 1 +#define b_4 2 +#define b_8 3 +#define b_16 4 +#define b_32 5 +#define b_64 6 +#define b_128 7 +#define b_256 8 +#define b_512 9 +#define KiB_bits 10 +#define MiB_bits 20 +#define GiB_bits 30 +#define TiB_bits 40 +#define KiB (1 << KiB_bits) +#define MiB (1 << MiB_bits) +#define GiB (1 << GiB_bits) +#define TiB (1 << TiB_bits) + +#include "L2V_Config.h" + + +// Pointers to NAND +// VPN bits were originally defined seperately as superblock bits, page offset bits; +// combining them results in more flexibility. 10+3 was supposed to represent 8192 max superblocks; +// 12 represented 4096 max pages per superblock. +#define L2V_BITS_VPN (10+3+12) +#define L2V_MAX_SB (1 << L2V_BITS_SB) +#define L2V_BITS_NAND_SPAN (32 - 2 - L2V_BITS_VPN) + + +// Node size +#define L2V_CONTIG_ELEM_SMALL 4 +#define L2V_CONTIG_ELEM_LARGE 6 +#define L2V_MIN_CONTIG_PER_NODE (L2V_NODE_SIZE / L2V_CONTIG_ELEM_LARGE) +#define L2V_MAX_CONTIG_PER_NODE (L2V_NODE_SIZE / L2V_CONTIG_ELEM_SMALL) + + +// Memory usage +#define L2V_NODEPOOL_COUNT (L2V_NODEPOOL_MEM / L2V_NODE_SIZE) +#define L2V_BITS_NODEIDX 16 +#define L2V_BITS_NODE_SPAN (32 - 2 - L2V_BITS_NODEIDX) + + +// Parameters +#define L2V_SUCKUP_CHILDREN_MAX 3 +#define L2V_TRACK_VALID 0 + + +// Tree size +#define L2V_TREE_SIZE (1 << L2V_TREE_BITS) +#define L2V_TREE_MASK (L2V_TREE_SIZE - 1) +#define L2V_MAX_TREE_DEPTH 32 +#define L2V_MAX_TREE_DEPTH_UPD 36 +#define L2V_TREE_DEPTH_REPACK 26 + + +// Magic numbers +#define L2V_CONTIG_FREE_SIG 0xFFFFFFFF +// These represent token values; normally, when we move along a span, we add to vpn and +// subtract from span. If it's a token--such as "missing" or "deallocated"--we should +// subtract from span, but not add to vpn, because it would change the meaning. +#define L2V_VPN_DEALLOC ((1< biggestSize) { + biggest = i; + biggestSize = L2V.TreeNodes[i]; + } + } + + return biggest; +} + +static void Forget(lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node and size + lPtr_t thisPtr; + ContigUnpacked_t cu; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + Forget(L2V_IDX_TO_NODE(cu.u.nodeIdx)); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); +} + +static void ReplaceRoot(UInt32 tree) +{ + ContigUnpacked_t cu; + + // Set up contig + cu.isNodePtr = 0; + cu.hasSpanOF = 0; + cu.u.n.vpn = L2V_VPN_MISS; + cu.span = 0; // Just so it's consistent... value doesn't matter in root + + // Update tree + L2V.Tree[tree] = LPTR_PACK_NAND(cu); + L2V.TreeNodes[tree] = 0; + L2V_root_depth[tree] = 0; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Forget.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Forget.h new file mode 100644 index 0000000..0bb08cf --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Forget.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_FORGET_H__ +#define __L2V_FORGET_H__ + + +#include "L2V_Types.h" + + +extern void L2V_ForgetBiggestTree(void); + + +#endif // __L2V_FORGET_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Free.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Free.c new file mode 100644 index 0000000..05633a6 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Free.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#include "L2V_Extern.h" + +#if ENABLE_L2V_TREE + +void L2V_Free(void) +{ + if (0 == L2V.numRoots) + return; + + // Free arrays: + + if (NULL != L2V.Tree) { + WMR_FREE(L2V.Tree, L2V.numRoots * sizeof(lPtr_t)); + L2V.Tree = NULL; + } + + if (NULL != L2V.TreeNodes) { + WMR_FREE(L2V.TreeNodes, L2V.numRoots * sizeof(UInt32)); + L2V.TreeNodes = NULL; + } + + if (NULL != L2V.UpdatesSinceRepack) { + WMR_FREE(L2V.UpdatesSinceRepack, L2V.numRoots * sizeof(UInt32)); + L2V.UpdatesSinceRepack = NULL; + } + + if (NULL != L2V.Pool.Node) { + WMR_FREE(L2V.Pool.Node, L2V_NODEPOOL_MEM); + L2V.Pool.Node = NULL; + } + + if(L2V_root_depth != NULL) + { + WMR_FREE(L2V_root_depth, L2V.numRoots); + L2V_root_depth = NULL; + } + +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.c new file mode 100644 index 0000000..abbf1f0 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Funcs.h" + +// Empty + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.h new file mode 100644 index 0000000..221fa95 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Funcs.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_FUNCS_H__ +#define __L2V_FUNCS_H__ + + +#include "L2V_Types.h" + + +BOOL32 L2V_Init(UInt32 numLbas, UInt32 numSBs, UInt32 pagesPerSB); +extern void L2V_Search_Init(L2V_SearchCtx_t *c); +extern void L2V_Search(L2V_SearchCtx_t *c); +extern void L2V_Update(UInt32 lba, UInt32 size, UInt32 vpn); +extern void L2V_Repack(UInt32 tree); +extern void L2V_ForgetBiggestTree(void); + + +// Macros + +#define _L2V_NODE_ITERATE_RESUME(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) \ + while ((_nodeByteOfs) <= ((_nodeSize)-sizeof(lPtr_t))) { \ + (_destPtr) = *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]); \ + if (L2V_CONTIG_FREE_SIG == (_destPtr)) { \ + break; \ + } \ + if (LPTR_IS_NODEPTR(_destPtr)) { \ + LPTR_UNPACK_NODE(_destPtr, _cu); \ + } else { \ + LPTR_UNPACK_NAND(_destPtr, _cu); \ + } \ + if ((_cu).hasSpanOF) { \ + (_nodeSize) -= sizeof(UInt16); \ + (_cu).span += *(UInt16*)&(_node)->bytes[_nodeSize] << (LPTR_IS_NODEPTR(_destPtr) ? L2V_BITS_NODE_SPAN : L2V_BITS_NAND_SPAN); \ + l2v_assert_le(_nodeByteOfs, ((_nodeSize)-sizeof(lPtr_t))); \ + } \ + l2v_assert_ne((_cu).span, 0); + +#define _L2V_NODE_ITERATE(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) \ + (_nodeByteOfs) = 0; \ + (_nodeSize) = L2V_NODE_SIZE; \ + _L2V_NODE_ITERATE_RESUME(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) + + +#define _L2V_NODE_ITERATE_NEXT(_nodeByteOfs) \ + (_nodeByteOfs) += sizeof(lPtr_t); + +#define _L2V_NODE_ITERATE_END_NOP } + +#define _L2V_NODE_ITERATE_END(_nodeByteOfs) \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + } + +#define _L2V_NODE_PUSH_CONTIG_NODE(_node, _nodeByteOfs, _nodeSize, _cu) \ + { \ + l2v_assert_ne((_cu).span, 0); \ + (_cu).hasSpanOF = 1; \ + *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]) = LPTR_PACK_NODE(_cu); \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + (_nodeSize) -= sizeof(UInt16); \ + *(UInt16*)&(_node)->bytes[_nodeSize] = (_cu).span >> L2V_BITS_NODE_SPAN; \ + } +#define _L2V_NODE_PUSH_CONTIG_NAND(_node, _nodeByteOfs, _nodeSize, _cu) \ + { \ + l2v_assert_ne((_cu).span, 0); \ + (_cu).hasSpanOF = 0; \ + if ((_cu).span >= (1 << L2V_BITS_NAND_SPAN)) { \ + (_cu).hasSpanOF = 1; \ + (_nodeSize) -= sizeof(UInt16); \ + *(UInt16*)&(_node)->bytes[_nodeSize] = (_cu).span >> L2V_BITS_NAND_SPAN; \ + } \ + *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]) = LPTR_PACK_NAND(_cu); \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + } +#define _L2V_NODE_PUSH_CONTIG(_node, _nodeByteOfs, _nodeSize, _cu) \ + do { \ + if ((_cu).isNodePtr) { \ + _L2V_NODE_PUSH_CONTIG_NODE(_node, _nodeByteOfs, _nodeSize, _cu); \ + } else { \ + _L2V_NODE_PUSH_CONTIG_NAND(_node, _nodeByteOfs, _nodeSize, _cu); \ + } \ + } while (0) +#define _L2V_CONTIG_SIZE(_cu) (sizeof(lPtr_t) + (((_cu).isNodePtr || ((_cu).span >= (1 << L2V_BITS_NAND_SPAN))) ? sizeof(UInt16) : 0)) + +#define _L2V_NODE_FILL(_node, _nodeByteOfs, _nodeSize) \ + do { \ + WMR_MEMSET(&(_node)->bytes[_nodeByteOfs], 0xFF, (_nodeSize) - (_nodeByteOfs)); \ + } while (0) + + +#define min(a, b) ((a) < (b) ? (a) : (b)) + + + + +#endif // __L2V_FUNCS_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Init.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Init.c new file mode 100644 index 0000000..d7c556c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Init.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Mem.h" + + +// Declare our L2V context structure here +L2V_t L2V; +UInt8 *L2V_root_depth; + +// Functions +BOOL32 L2V_Init(UInt32 numLbas, UInt32 numSBs, UInt32 pagesPerSB) +{ + UInt32 i; + Int32 j; + ContigUnpacked_t cu; + + // Set number of superblocks for valid accounting division + L2V.numSBs = numSBs; + L2V.pagesPerSB = pagesPerSB; + if ((numSBs * pagesPerSB) >= L2V_VPN_SPECIAL) { + WMR_PANIC("Tree bitspace not sufficient for geometry %dx%d: please re-adjust", numSBs, pagesPerSB); + } + + // Set tree version + L2V.treeVersion = 0; + + // Calculate roots + L2V.numRoots = (numLbas >> L2V_TREE_BITS) + 1; + + // Allocate arrays + L2V.Tree = WMR_MALLOC(L2V.numRoots * sizeof(lPtr_t)); + l2v_assert_ne(L2V.Tree, NULL); + L2V.TreeNodes = WMR_MALLOC(L2V.numRoots * sizeof(UInt32)); + l2v_assert_ne(L2V.TreeNodes, NULL); + L2V.UpdatesSinceRepack = WMR_MALLOC(L2V.numRoots * sizeof(UInt32)); + l2v_assert_ne(L2V.UpdatesSinceRepack, NULL); + L2V_root_depth = WMR_MALLOC(L2V.numRoots); + l2v_assert_ne(L2V_root_depth , NULL); + for (i = 0; i < L2V.numRoots; i++) { + L2V_root_depth[i] = 0; + } + + // Empty roots; default to miss + cu.hasSpanOF = 0; + cu.u.n.vpn = L2V_VPN_MISS; + cu.span = 0; + for (i = 0; i < L2V.numRoots; i++) { + L2V.Tree[i] = LPTR_PACK_NAND(cu); + } + + // Reset periodic repacker variables + L2V.RepackCounter = 0; + + // Allocate the node pool + L2V.Pool.Node = (lNode_t*)WMR_MALLOC(L2V_NODEPOOL_MEM); + if (NULL == L2V.Pool.Node) { + return FALSE32; + } + + // Finally, put all nodes in the free pool + L2V.Pool.FreePtr = NULL; + L2V.Pool.FreeCount = 0; + for (j = L2V_NODEPOOL_COUNT-1; j >= 0; j--) { + _L2V_FreeNode(&L2V.Pool.Node[j]); + } + + return TRUE32; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.c new file mode 100644 index 0000000..7ebbe11 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" +#include "L2V_Mem.h" +#include "L2V_Assert.h" + + +void _L2V_FreeNode(lNode_t *node) +{ + static int freeCount = 0; + + freeCount++; + + l2v_assert_ge(node, &L2V.Pool.Node[0]); + l2v_assert_le(node, &L2V.Pool.Node[L2V_NODEPOOL_COUNT]); + + node->nextFreePtr = L2V.Pool.FreePtr; + L2V.Pool.FreePtr = node; + L2V.Pool.FreeCount++; +} + + +lNode_t *_L2V_AllocNode() +{ + lNode_t *ret; + static int allocCount = 0; + + allocCount++; + + ret = (lNode_t*)L2V.Pool.FreePtr; + if (NULL != ret) { + L2V.Pool.FreePtr = L2V.Pool.FreePtr->nextFreePtr; + L2V.Pool.FreeCount--; + } + l2v_assert_ne(ret, NULL); + + return ret; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.h new file mode 100644 index 0000000..f744442 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Mem.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_MEM_H__ +#define __L2V_MEM_H__ + + +#include "L2V_Types.h" + + +extern void _L2V_FreeNode(lNode_t *node); +extern lNode_t *_L2V_AllocNode(void); // Warning: may return NULL; up to caller to handle gracefully + + +#endif // __L2V_MEM_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.c new file mode 100644 index 0000000..58e411e --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Print.h" +#include "L2V_Funcs.h" +#include "L2V.h" +#include "L2V_Types.h" + + +#define PRINT_MAXPATH 0 + + +// Prototypes + +static int L2V_GetUsage(lNode_t *node, UInt32 *used, UInt32 *total, UInt32 *nodes, UInt32 totalSpan, BOOL32 isMax); + + +// Functions + +void L2V_PrintPtr(lPtr_t lptr) +{ + ContigUnpacked_t cu; + LPTR_UNPACK(lptr, cu); + L2V_PrintCU(&cu); +} + +void L2V_PrintCU(ContigUnpacked_t *cu) +{ + if (cu->isNodePtr) + printf("[Node]"); + else + printf("[NAND]"); + + if (cu->hasSpanOF) + printf("o"); + else + printf("-"); + + if (cu->isNodePtr) { + printf("[idx:%d][span:%d]", cu->u.nodeIdx, cu->span); + } else { + printf("[vpn:%d][span:%d]", cu->u.n.vpn, cu->span); + } + + printf("\n"); +} + + +void L2V_PrintNode(lNode_t *node) +{ + UInt32 nOfs, nodeSize; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + L2V_PrintCU(&cu); + } _L2V_NODE_ITERATE_END(nOfs); +} + + +void L2V_PrintUsage(UInt32 tree) +{ + UInt32 used, total, nodes, maxdepth; + + ContigUnpacked_t cu; + + used = total = nodes = maxdepth = 0; + printf("Max depth path: "); + printf("digraph G {\n"); + LPTR_UNPACK(L2V.Tree[tree], cu); + if (cu.isNodePtr) { + maxdepth = L2V_GetUsage(L2V_IDX_TO_NODE(cu.u.nodeIdx), &used, &total, &nodes, L2V_TREE_SIZE, 1); + } + printf("}\n"); + printf("\nUsage tree %d: %.2f, nodes: %d, maxdepth: %d\n", tree, (float)used/(float)total, nodes, maxdepth); + printf("Nodes calc: %d tally: %d\n\n", nodes, L2V.TreeNodes[tree]); + if (nodes != L2V.TreeNodes[tree]) while(1);//DP + //l2v_assert_eq(nodes, L2V_NODEPOOL_COUNT - L2V.Pool.FreeCount); // Only valid when using 1 tree +} + +static int L2V_GetUsage(lNode_t *node, UInt32 *used, UInt32 *total, UInt32 *nodes, UInt32 totalSpan, BOOL32 isMax) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + UInt32 sumSpan; + lPtr_t thisPtr, maxNode; + UInt32 depth, maxDepth, maxSpan; + ContigUnpacked_t cu; + + // Walk through + (*nodes)++; + maxDepth = 0; + sumSpan = 0; + + // Iterate through the node, + L2V_PrintNode(node); + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + printf("%d -> %d;\n", (int)L2V_NODE_TO_IDX(node), cu.u.nodeIdx); // DOT output + l2v_assert_ne(cu.u.nodeIdx, 65535); + l2v_assert_ne(L2V_IDX_TO_NODE(cu.u.nodeIdx), node); + l2v_assert_ne(cu.span, 0); + depth = L2V_GetUsage(L2V_IDX_TO_NODE(cu.u.nodeIdx), used, total, nodes, cu.span, 0); + if (depth > maxDepth) { + maxDepth = depth; + maxNode = thisPtr; + maxSpan = cu.span; + } + } + sumSpan += cu.span; + l2v_assert_le(cu.span, 32768); + } _L2V_NODE_ITERATE_END(nOfs); + *used += nOfs; + *total += sizeof(lNode_t); + printf("%d [label=\"us:%.2f\\nsp:%.2f\",shape=box,style=filled,color=\"1.0 %.2f 1.0\"];\n", (int)L2V_NODE_TO_IDX(node), (float)nOfs/sizeof(lNode_t), (float)totalSpan/L2V_TREE_SIZE, (float)nOfs/sizeof(lNode_t)); // DOT output + + if (sumSpan != totalSpan) { + printf("Sum: %d, total: %d\n", sumSpan, totalSpan); + L2V_PrintNode(node); + } + l2v_assert_eq(sumSpan, totalSpan); + l2v_assert_ne(nOfs, 0); + +#if PRINT_MAXPATH + if (maxDepth && isMax) { + printf("<-%d", maxNode.node.nodeIdx); + L2V_GetUsage(L2V_LPTR_TO_NODE(maxNode), &nOfs, &nOfs, &nOfs, maxSpan, 1); + } +#endif + + return maxDepth+1; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.h new file mode 100644 index 0000000..da1e5ce --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Print.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_PRINT_H__ +#define __L2V_PRINT_H__ + + +#include "L2V_Types.h" + + +extern void L2V_PrintPtr(lPtr_t lptr); +extern void L2V_PrintCU(ContigUnpacked_t *cu); +extern void L2V_PrintNode(lNode_t *node); +extern void L2V_PrintUsage(UInt32 tree); + + +#endif // __L2V_PRINT_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.c new file mode 100644 index 0000000..aabc79b --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define AND_TRACE_LAYER FTL + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Repack.h" +#include "L2V.h" +#include "L2V_Types.h" +#include "L2V_Mem.h" +#include "L2V_Funcs.h" + + +#define REPACK_MAX_NODES (L2V_TREE_SIZE/L2V_MIN_CONTIG_PER_NODE) +#define REPACK_TREE_LOG_SIZE 32 + +typedef struct { + lNode_t *bottom[REPACK_MAX_NODES]; + UInt32 bottomSpan[REPACK_MAX_NODES]; + UInt32 bottomIdx; + UInt32 bottom_nOfs; + UInt32 bottom_nodeSize; + UInt32 repackTreeLog[REPACK_TREE_LOG_SIZE]; + UInt32 repackTreeLogIdx; +} RepackCtx_t; + + +// Static definitions +static void CopyAndDestroy(RepackCtx_t *r, lNode_t *node); +static int Rebuild(RepackCtx_t *r); +static void ReplaceRoot(RepackCtx_t *r, UInt32 tree); + + +void L2V_PeriodicRepack() +{ + Int32 best; + UInt32 merit, bestMerit, i; + + // Check if it's appropriate or not + if (L2V.RepackCounter < L2V_REPACK_PERIOD) { + return; + } + L2V.RepackCounter = 0; + + // Find best candidate; merit==updates + bestMerit = 0; + best = -1; + for (i = 0; i < L2V.numRoots; i++) { + merit = L2V.UpdatesSinceRepack[i]; + if (merit >= bestMerit) { + bestMerit = merit; + best = i; + } + } + + l2v_assert_ne(best, -1); + + L2V_Repack(best); +} + + +// WARNING: NOT REENTRANT +static RepackCtx_t r; +void L2V_Repack(UInt32 tree) +{ + lNode_t *root; + ContigUnpacked_t cu; + + LPTR_UNPACK(L2V.Tree[tree], cu); + + // Trying to repack a rootptr? Abort... + if (!cu.isNodePtr) { + return; + } + + WMR_TRACE_1(Repack, START, tree); + + // Up tree version for search-update coherency + L2V.treeVersion++; + + // Create list of new bottom layer + r.bottomIdx = 0; + r.bottom_nOfs = 0; + r.bottom_nodeSize = L2V_NODE_SIZE; + WMR_MEMSET(r.bottom, 0, REPACK_MAX_NODES * sizeof(r.bottom[0])); + WMR_MEMSET(r.bottomSpan, 0, REPACK_MAX_NODES * sizeof(r.bottomSpan[0])); + + // Recurse and destroy + root = L2V_IDX_TO_NODE(cu.u.nodeIdx); + CopyAndDestroy(&r, root); + + l2v_assert_ne(r.bottom_nOfs, 0); + + // Fill rest with "empty" markers + _L2V_NODE_FILL(r.bottom[r.bottomIdx], r.bottom_nOfs, r.bottom_nodeSize); + + // Rebuild hierarchy + L2V.TreeNodes[tree] = Rebuild(&r); + + // Replace root + ReplaceRoot(&r, tree); + + // Clear repack counter + L2V.UpdatesSinceRepack[tree] = 0; + + + // Log which tree we repacked + if (r.repackTreeLogIdx >= REPACK_TREE_LOG_SIZE) { + r.repackTreeLogIdx = 0; + } + r.repackTreeLog[r.repackTreeLogIdx] = tree; + r.repackTreeLogIdx++; + + WMR_TRACE_0(Repack, END); +} + + +static void CopyAndDestroy(RepackCtx_t *r, lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + ContigUnpacked_t cu; + lPtr_t thisPtr; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + CopyAndDestroy(r, L2V_IDX_TO_NODE(cu.u.nodeIdx)); + } else { + // Would be full? Move along... + if ((r->bottom_nOfs + _L2V_CONTIG_SIZE(cu)) > r->bottom_nodeSize) { + // Fill rest with "empty" markers + _L2V_NODE_FILL(r->bottom[r->bottomIdx], r->bottom_nOfs, r->bottom_nodeSize); + + r->bottomIdx++; + l2v_assert_lt(r->bottomIdx, REPACK_MAX_NODES); + } + + // Allocate node if necessary + if (NULL == r->bottom[r->bottomIdx]) { + // Allocate... + r->bottom[r->bottomIdx] = _L2V_AllocNode(); + r->bottom_nOfs = 0; + r->bottom_nodeSize = L2V_NODE_SIZE; + } + + // Copy out + _L2V_NODE_PUSH_CONTIG(r->bottom[r->bottomIdx], r->bottom_nOfs, r->bottom_nodeSize, cu); + r->bottomSpan[r->bottomIdx] += cu.span; + l2v_assert_le(cu.span, L2V_TREE_SIZE); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); +} + + +static int Rebuild(RepackCtx_t *r) +{ + lNode_t *thisBranch; + UInt32 nOfs, nodeSize, thisSpan, i, branchIdx; + ContigUnpacked_t cu; + int nodeCount; + + nodeCount = r->bottomIdx+1; + while (r->bottomIdx > 0) { + thisBranch = _L2V_AllocNode(); + nodeCount++; + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + thisSpan = 0; + branchIdx = 0; + + // Rebuild this layer + for (i = 0; i <= r->bottomIdx; i++) { + cu.isNodePtr = 1; + cu.u.nodeIdx = L2V_NODE_TO_IDX(r->bottom[i]); + cu.span = r->bottomSpan[i]; + + if ((nOfs + _L2V_CONTIG_SIZE(cu)) > nodeSize) { + // Fill rest with "empty" markers + _L2V_NODE_FILL(thisBranch, nOfs, nodeSize); + + // Place it down and get a new one + r->bottom[branchIdx] = thisBranch; + r->bottomSpan[branchIdx] = thisSpan; + branchIdx++; + thisBranch = _L2V_AllocNode(); + nodeCount++; + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + thisSpan = 0; + } + + _L2V_NODE_PUSH_CONTIG(thisBranch, nOfs, nodeSize, cu); + thisSpan += cu.span; + } + + l2v_assert_ne(nOfs, 0); + + r->bottom[branchIdx] = thisBranch; + r->bottomSpan[branchIdx] = thisSpan; + // Fill rest with "empty" markers + _L2V_NODE_FILL(thisBranch, nOfs, nodeSize); + + // Make sure the repack didn't munge the root node's spans + if (0 == branchIdx) { + l2v_assert_eq(thisSpan, L2V_TREE_SIZE); + } + + // Get ready for the next round + r->bottomIdx = branchIdx; + } + + return nodeCount; +} + + +static void ReplaceRoot(RepackCtx_t *r, UInt32 tree) +{ + ContigUnpacked_t cu; + l2v_assert_eq(r->bottomIdx, 0); + cu.u.nodeIdx = L2V_NODE_TO_IDX(r->bottom[0]); + cu.hasSpanOF = 0; + cu.span = 0; + L2V.Tree[tree] = LPTR_PACK_NODE(cu); + if (!LPTR_IS_NODEPTR(L2V.Tree[tree])) { + L2V_root_depth[tree] = 0; + } +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.h new file mode 100644 index 0000000..6086f84 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Repack.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_REPACK_H__ +#define __L2V_REPACK_H__ + + +#include "WMROAM.h" + +// Functions + +extern void L2V_PeriodicRepack(void); +extern void L2V_Repack(UInt32 tree); + + +#endif // __L2V_REPACK_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Search.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Search.c new file mode 100644 index 0000000..af0867c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Search.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" +#include "L2V_Funcs.h" + + +void L2V_Search_Init(L2V_SearchCtx_t *c) +{ + c->next_lba = 0xffffffff; + c->last_node = NULL; + c->span = 0; +} + + +static BOOL32 HitCache(L2V_SearchCtx_t *c) +{ + ContigUnpacked_t cu; + lPtr_t thisPtr; + + + if ((c->treeVersion == L2V.treeVersion) && (c->lba == c->next_lba) && (NULL != c->last_node)) { + // Sequential HIT + _L2V_NODE_ITERATE_RESUME(c->last_node, c->next_nOfs, c->nodeSize, cu, thisPtr) { + if (cu.isNodePtr) + break; + + c->vpn = cu.u.n.vpn; + c->fromStart = 0; + c->span = cu.span; + + _L2V_NODE_ITERATE_NEXT(c->next_nOfs); // This will move nOfs along + c->next_lba = c->lba + c->span; + return TRUE32; + + } _L2V_NODE_ITERATE_END_NOP; + } + + // Clear search history + c->next_lba = 0xffffffff; + c->last_node = NULL; + + return FALSE32; +} + + +void L2V_Search(L2V_SearchCtx_t *c) +{ + UInt32 targTree, targTofs; + UInt32 thisStart, thisMax; + UInt32 nOfs, nodeSize; // Byte offset within the node, and node effective size + ContigUnpacked_t cu, thiscu; + lNode_t *node = NULL; + lPtr_t thisPtr; + + if (HitCache(c)) { + return; + } + + // Determine first root + targTree = c->lba >> L2V_TREE_BITS; + targTofs = c->lba & L2V_TREE_MASK; + l2v_assert_lt(targTree, L2V.numRoots); + + c->level = 0; + thisStart = 0; + c->vpn = L2V_VPN_MISS; + LPTR_UNPACK(L2V.Tree[targTree], cu); + thiscu.span = L2V_TREE_SIZE; + c->next_nOfs = 0; + + // Search from top down + while (c->level < L2V_MAX_TREE_DEPTH) { + // Down and next + // Decode node pointer + if (!cu.isNodePtr) { + // Terminal case--pointer to physical location; calculate relative offset... + c->vpn = cu.u.n.vpn; + c->fromStart = targTofs - thisStart; + if (cu.u.n.vpn < L2V_VPN_SPECIAL) { + c->vpn += c->fromStart; + } + c->span = thiscu.span - c->fromStart; + // Set up return case for sequential searching + c->last_node = node; + c->next_lba = c->lba + c->span; + c->treeVersion = L2V.treeVersion; + // c->next_nOfs is populated from code below, i.e. the previous iteration of this while loop + + // Is it getting really big? Do some preventative maintenence... + if (c->level >= L2V_TREE_DEPTH_REPACK) { + L2V_Repack(targTree); + } + return; + } + + // Walk through + node = L2V_IDX_TO_NODE(cu.u.nodeIdx); + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + // Calculate endpoint + thisMax = thisStart + thiscu.span; + + // Are we in range? + if (targTofs < thisMax) { + // HIT! (Left-hand side implied by order of search.) + cu = thiscu; + _L2V_NODE_ITERATE_NEXT(nOfs); + c->next_nOfs = nOfs; + c->nodeSize = nodeSize; + goto decodePtr; + } + + // Move along in the node + thisStart = thisMax; + } _L2V_NODE_ITERATE_END(nOfs); + + WMR_PANIC("NAND index: bad tree: targTofs %d, level %d\n", targTofs, c->level); + +decodePtr: + // Resume here so we can check the while() condition + c->level++; + } + + l2v_assert(0); // Should never get here; otherwise, the tree is too deep (or recursive or pointing to randomness) +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.c new file mode 100644 index 0000000..c1009cc --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Funcs.h" +#include "L2V_Print.h" +#include +#include + +L2V_t L2V; + + +#define LAST_TREE_TEST 16 +#define SIMPLE_SIZE (L2V_TREE_SIZE*LAST_TREE_TEST) + + +// Prototypes +static void RandomTest(void); +static void SequentialTest(void); +static void Simple_Init(void); +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn); +static void Simple_Lookup(UInt32 lba, UInt32 *vpn); + +void Usage(int argc, char** argv) +{ + printf("Usage: %s s OR %s r (for sequential and random, respectively\n", argv[0], argv[0]); + exit(-1); +} + +int test = 0; + +int main(int argc, char** argv) +{ + L2V_Init(SIMPLE_SIZE, (L2V_VPN_SPECIAL-1) / 8192, 8192); + + if (argc == 2) { + if ('r' == argv[1][0]) { + test = 0; + } else if ('s' == argv[1][0]) { + test = 1; + } else { + Usage(argc, argv); + } + } + if (argc > 2) { + Usage(argc, argv); + } + + if (0 == test) { + RandomTest(); + } else { + SequentialTest(); + } + + return 0; +} + + +#define MAXLEN 512 +static void RandomTest() { + UInt32 lba, size, vpn; + UInt32 i, svpn; + L2V_SearchCtx_t c; + + L2V_Search_Init(&c); + + Simple_Init(); + + sranddev(); + + while (1) { + lba = rand() % ((L2V_TREE_SIZE*LAST_TREE_TEST)-MAXLEN); + size = (rand() % (MAXLEN-1))+1; + vpn = rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + + printf("[UPD: lba:%d, size:%d, vpn:%d]\n", lba, size, vpn); + L2V_Update(lba, size, vpn); + Simple_Update(lba, size, vpn); + //printf("\n"); + //L2V_PrintNode(L2V_LPTR_TO_NODE(L2V.Tree[0])); + L2V_PrintUsage(0); + + + // Validate entire range + int maxlevel=0; + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_Lookup(i, &svpn); + c.lba = i; + L2V_Search(&c); + if (c.level > maxlevel) maxlevel = c.level; + if (svpn != c.vpn) { + printf("\n\n\n"); + printf("====================\n"); + printf("MISMATCH lba:%d\n", i); + printf("--------------------\n"); + printf("Simple vpn:%d\n", svpn); + printf("Lookup vpn:%d\n", c.vpn); + } + l2v_assert_eq(svpn, c.vpn); + } + printf("maxlevel: %d\n", maxlevel); + l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH); + +#if 0 + if (repack++ > 10) { + printf("Repacking tree %d...\n", nextRepack); + L2V_Repack(nextRepack); + L2V_PrintUsage(nextRepack); + repack = 0; + nextRepack = (nextRepack + 1) % LAST_TREE_TEST; + } +#endif + } +} + +static void SequentialTest() { + UInt32 lba, size, vpn; + UInt32 i, svpn; + L2V_SearchCtx_t c; + + L2V_Search_Init(&c); + + Simple_Init(); + + sranddev(); + + lba = 0; + size = 0; + vpn = 1; + + while (1) { + lba += size; + size = (rand() % (MAXLEN-1))+1; + if ((lba + size) >= L2V_TREE_SIZE) { + lba = 0; + } + if ((rand() & 3) == 0) { + vpn = rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + } + while (((vpn + size) & ((1<<(L2V_BITS_VPN-1))-1)) < vpn) { + vpn = rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + } + + printf("[UPD: lba:%d, size:%d, vpn:%d]\n", lba, size, vpn); + L2V_Update(lba, size, vpn); + Simple_Update(lba, size, vpn); + L2V_PrintUsage(0); + vpn += size; + + + // Validate entire range + int maxlevel=0; + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_Lookup(i, &svpn); + c.lba = i; + L2V_Search(&c); + if (c.level > maxlevel) maxlevel = c.level; + if (svpn != c.vpn) { + printf("\n\n\n"); + printf("====================\n"); + printf("MISMATCH lba:%d\n", i); + printf("--------------------\n"); + printf("Simple vpn:%d\n", svpn); + printf("Lookup vpn:%d\n", c.vpn); + } + l2v_assert_eq(svpn, c.vpn); + } + printf("maxlevel: %d\n", maxlevel); + l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH); + } +} + + +UInt32 Simple_vpn[SIMPLE_SIZE]; + +static void Simple_Init() +{ + UInt32 i; + + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_vpn[i] = L2V_VPN_MISS; + } +} + + +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn) +{ + while (size) { + Simple_vpn[lba] = vpn; + + // Iterate + lba++; + if (vpn < L2V_VPN_SPECIAL) { + vpn++; + } + size--; + } +} + + +static void Simple_Lookup(UInt32 lba, UInt32 *vpn) +{ + *vpn = Simple_vpn[lba]; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.mak b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.mak new file mode 100644 index 0000000..5b90ffd --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Test.mak @@ -0,0 +1,28 @@ +OBJS=L2V_Test.o L2V_Funcs.o L2V_Init.o L2V_Mem.o L2V_Search.o L2V_Update.o L2V_Valid.o L2V_Types.o L2V_Print.o L2V_Repack.o L2V_Forget.o L2V_Free.o WMROAM.o +LINK_TARGET=L2V_Test +REBUILDABLES=$(OBJS) $(LINK_TARGET) + +.PHONY: all +all: copythem $(LINK_TARGET) cleanthem + # + +.PHONY: copythem +copythem: + cp WMROAM-test.h WMROAM.h + cp WMROAM-test.c WMROAM.c + cp WMRFeatures-test.h WMRFeatures.h + +.PHONY: cleanthem +cleanthem: + rm WMROAM.c WMROAM.h WMRFeatures.h + +$(LINK_TARGET): $(OBJS) + gcc -g -o $@ $^ -Wall + +.PHONY: clean +clean: + rm -f $(REBUILDABLES) + rm WMROAM.c WMROAM.h WMRFeatures.h + +%.o: %.c + gcc -g -o $@ -c $< -Wall -I. diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.c new file mode 100644 index 0000000..ceab55b --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Defines.h" +#include "L2V_Types.h" + + +BOOL32 _L2V_NodeBig_PushContig(lNodeBig_t *big, ContigUnpacked_t *cu) +{ + Int32 last = ((Int32)big->max)-1; + l2v_assert_ne(cu->span, 0); + + if (!cu->isNodePtr && (last >= 0) && !big->cu[last].isNodePtr && ( + ((cu->u.n.vpn < L2V_VPN_SPECIAL) && ((big->cu[last].u.n.vpn+big->cu[last].span) == cu->u.n.vpn)) + || ((cu->u.n.vpn >= L2V_VPN_SPECIAL) && (big->cu[last].u.n.vpn == cu->u.n.vpn)))) + { + big->cu[last].span += cu->span; + return TRUE32; + } + + big->cu[big->max] = *cu; + big->max++; + + if (cu->isNodePtr) { + l2v_assert_lt(cu->u.nodeIdx, L2V_NODEPOOL_COUNT); + } + + return FALSE32; +} + + +BOOL32 _L2V_NodeBig_PushContig_Node(lNodeBig_t *big, UInt32 nodeIdx, UInt32 span) +{ + big->cu[big->max].isNodePtr = 1; + big->cu[big->max].u.nodeIdx = nodeIdx; + big->cu[big->max].span = span; + big->max++; + + return FALSE32; +} + + +BOOL32 _L2V_NodeBig_PushContig_Nand(lNodeBig_t *big, UInt32 vpn, UInt32 span) +{ + Int32 last = ((Int32)big->max)-1; + l2v_assert_ne(span, 0); + + if ((last >= 0) && !big->cu[last].isNodePtr && ( + ((vpn < L2V_VPN_SPECIAL) && ((big->cu[last].u.n.vpn+big->cu[last].span) == vpn)) + || ((vpn >= L2V_VPN_SPECIAL) && (big->cu[last].u.n.vpn == vpn)))) + { + big->cu[last].span += span; + return TRUE32; + } + + big->cu[big->max].isNodePtr = 0; + big->cu[big->max].u.n.vpn = vpn; + big->cu[big->max].span = span; + big->max++; + + return FALSE32; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.h new file mode 100644 index 0000000..90ce0d7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Types.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_TYPES_H__ +#define __L2V_TYPES_H__ + + +#include "WMROAM.h" +#include "L2V_Defines.h" +#include "L2V_Assert.h" + + +// Pointer type: can point to NAND, or to a subtree +// Bits: 0=isNodePtr, 1=hasSpanOF. +// isNodePtr=0: vpn:L2V_BITS_VPN, span:L2V_BITS_NAND_SPAN +// isNodePtr=1: nodeIdx:L2V_BITS_NODEIDX, span:L2V_BITS_NODE_SPAN +// hasSpanOF: fetch 2 bytes from the right end of the node + +typedef UInt32 lPtr_t; +#define LPTR_IS_NODEPTR(_lptr) ((_lptr) & 1) +#define LPTR_HASSPANOF(_lptr) (((_lptr) & 2) >> 1) +#define LPTR_PACK_NAND(_cu) ( \ + (((_cu).hasSpanOF & 1) << 1) | \ + (((_cu).u.n.vpn & (((1 <> 1) & 1; \ + (_cu).u.n.vpn = ((_lptr) >> 2) & ((1 << L2V_BITS_VPN)-1); \ + (_cu).span = ((_lptr) >> (2+L2V_BITS_VPN)) & ((1 << L2V_BITS_NAND_SPAN)-1); \ + } while (0) +#define LPTR_UNPACK_NODE(_lptr, _cu) do { \ + (_cu).isNodePtr = 1; \ + (_cu).hasSpanOF = ((_lptr) >> 1) & 1; \ + (_cu).u.nodeIdx = ((_lptr) >> 2) & ((1 << L2V_BITS_NODEIDX)-1); \ + (_cu).span = ((_lptr) >> (2+L2V_BITS_NODEIDX)) & ((1 << L2V_BITS_NODE_SPAN)-1); \ + } while (0) +#define LPTR_GET_NODEIDX(_lptr) (((_lptr) >> 2) & ((1 << L2V_BITS_NODEIDX)-1)) +#define LPTR_UNPACK(_lptr, _cu) do { \ + if LPTR_IS_NODEPTR(_lptr) { \ + LPTR_UNPACK_NODE(_lptr, _cu); \ + } else { \ + LPTR_UNPACK_NAND(_lptr, _cu); \ + } \ + } while (0) + +typedef struct { + UInt32 isNodePtr; // Values: 0, 1 (true)... must not be any other value + UInt32 hasSpanOF; // Values: 0, 1 (true)... ditto + union { + struct { + UInt32 vpn; + } n; + UInt32 nodeIdx; + } u; + UInt32 span; +} ContigUnpacked_t; + + +// Node type: union for dynamic and fixed node types (and FreePool linkage) +typedef union _lNode_t { + union _lNode_t *nextFreePtr; + + UInt8 bytes[L2V_NODE_SIZE]; +} lNode_t; +CASSERT(L2V_NODE_SIZE == sizeof(lNode_t), lNode_t_size_matches); + +#define L2V_LNODEBIG_MAX (L2V_MAX_CONTIG_PER_NODE+(L2V_SUCKUP_CHILDREN_MAX*2)+5) +typedef struct { + ContigUnpacked_t cu[L2V_LNODEBIG_MAX]; + UInt32 start; + UInt32 max; +} lNodeBig_t; + + +typedef struct { + lNode_t *Node; // Node pool allocated with malloc() + lNode_t *FreePtr; + UInt32 FreeCount; +} FTLight_NodePool_t; + + +typedef struct { + // Logical space + UInt32 numRoots; + lPtr_t *Tree; + UInt32 *TreeNodes; + UInt32 *UpdatesSinceRepack; + UInt32 RepackCounter; + UInt32 treeVersion; + + // Physical space + UInt32 numSBs; + UInt32 pagesPerSB; +#if L2V_TRACK_VALID!=0 + UInt32 Valid[L2V_MAX_SB]; +#endif + + // Memory + FTLight_NodePool_t Pool; +} L2V_t; + +typedef struct { + // Input: + UInt32 lba; + + // Output: + UInt32 fromStart; // blocks from start of treeSpan + UInt32 vpn; + UInt32 span; + + // Internal state: + lNode_t *last_node; + UInt32 next_lba; + UInt32 next_nOfs; + UInt32 nodeSize; + UInt32 level; + UInt32 treeVersion; +} L2V_SearchCtx_t; + + +// Helper functions + +extern BOOL32 _L2V_NodeBig_PushContig(lNodeBig_t *big, ContigUnpacked_t *cu); // True: compressed with left +extern BOOL32 _L2V_NodeBig_PushContig_Node(lNodeBig_t *big, UInt32 nodeIdx, UInt32 span); // True: compress with left (always false) +extern BOOL32 _L2V_NodeBig_PushContig_Nand(lNodeBig_t *big, UInt32 vpn, UInt32 span); // True: compressed with left +#define _L2V_NodeBig_WillCompress(_big, _vpn, _span) \ + ((_big.max > 0) && (!_big.cu[_big.max-1].isNodePtr) && \ + (((_vpn < L2V_VPN_SPECIAL) && ((_big.cu[_big.max-1].u.n.vpn+_big.cu[_big.max-1].span) == _vpn)) \ + || ((_vpn >= L2V_VPN_SPECIAL) && (_big.cu[_big.max-1].u.n.vpn == _vpn)))) + + +#endif // __L2V_TYPES_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Update.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Update.c new file mode 100644 index 0000000..3e0fce5 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Update.c @@ -0,0 +1,1197 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" +#include "L2V_Funcs.h" +#include "L2V_Mem.h" +#include "L2V_Valid.h" +#include "L2V_Repack.h" +#include "L2V_Types.h" + + +// ##### TYPE DEFINITIONS - LOCAL TO THIS SOURCE FILE ######################### + +typedef struct { + UInt32 incomingTree; + UInt32 incomingOfs, incomingSize; + UInt32 incomingEnd; + UInt32 vpn; + + UInt32 thisStart, thisMax; // Span start/end ofs while in inner loop + + ContigUnpacked_t cu; + lPtr_t nodePtr; + lPtr_t thisPtr; + BOOL32 needsInsert; + lNode_t *node; + UInt32 nOfs; + UInt32 nodeSize; + + BOOL32 changed; // Did we change this node? + lNodeBig_t tmpNode; + + lNode_t *atLevel[L2V_MAX_TREE_DEPTH_UPD+5]; // Add some guard-band + UInt32 level; +} UpdateCtx_t; + + +// ##### PROTOTYPES - LOCAL TO THIS SOURCE FILE ############################### + +static void UpdateGuts(UInt32 lba, UInt32 size, UInt32 vpn); +static void TeardownTree(UInt32 tree); +static int DestroySpanLeft(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 amount); +static int DestroySpanRight(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 keepAmount, UInt32 fullSpan); +static void DestroySpanMiddle(lPtr_t *p, UInt32 left, UInt32 right); +static void TreeToNand(UInt32 tree, UInt32 vpn); + +// Helpers: +static void SuckOneUp(UInt32 tree, lNodeBig_t *big, lPtr_t ptr); +static void Upd_TrivialInsert(); +static BOOL32 Upd_IdentityReplace(); +static BOOL32 Upd_CompleteOverlap(); +static BOOL32 Upd_ChopRight(); +static BOOL32 Upd_ChopLeft(); +static void Upd_ChopMiddleNand(); +static void Upd_FillRemainder(); +static int Upd_GetNodeSize(); +static int Upd_PushNodeOut(lNodeBig_t *b, lNode_t *node, UInt32 minEl, UInt32 maxEl); // Returns sumSpan +static void Upd_SplitAndPush(); +static void RippleUp(lNode_t *oldNode, UInt32 span0, lNode_t *newNode, UInt32 span1); +static void Upd_ShareLeft(); +static void Upd_ShareRight(); +static int Upd_PushLeft(lNode_t *left); +static int Upd_PushRight(lNode_t *right); + + +// ##### FUNCTION DEFINITIONS - EXPORTED FUNCTIONS ############################ + +void L2V_Update(UInt32 lba, UInt32 size, UInt32 vpn) +{ + UInt32 thisSize, treeOfs; + + // Running out of L2V memory? + while (L2V_LowMem) + { + // Make room by forgetting some stuff + L2V_ForgetBiggestTree(); + } + + // Up tree version for search-update coherency + L2V.treeVersion++; + + while (size) { + treeOfs = lba & L2V_TREE_MASK; + thisSize = min(L2V_TREE_SIZE - treeOfs, size); + + UpdateGuts(lba, thisSize, vpn); + + size -= thisSize; + lba += thisSize; + if (vpn < L2V_VPN_SPECIAL) { + vpn += thisSize; + } + } +} + + +// ##### FUNCTION DEFINITIONS - LOCAL TO THIS SOURCE FILE ##################### +UpdateCtx_t u; + +static UInt32 L2V_GetDepth(lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + lPtr_t thisPtr; + UInt32 depth, maxDepth; + ContigUnpacked_t cu; + + // Walk through + maxDepth = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + depth = L2V_GetDepth(L2V_IDX_TO_NODE(cu.u.nodeIdx)); + if (depth > maxDepth) { + maxDepth = depth; + } + } + } _L2V_NODE_ITERATE_END(nOfs); + + return maxDepth+1; +} + +static void UpdateGuts(UInt32 __lba, UInt32 __size, UInt32 __vpn) +{ + UInt32 nodesBefore; + + // Input: guaranteed to not span trees + u.incomingTree = __lba >> L2V_TREE_BITS; + u.incomingOfs = __lba & L2V_TREE_MASK; + u.incomingSize = __size; + u.incomingEnd = u.incomingOfs + u.incomingSize; + u.vpn = __vpn; + if (u.incomingTree >= L2V.numRoots) { + WMR_PANIC("L2V update with out-of-range LBA-- lba:%d, size:%d, vpn:0x%x", __lba, __size, __vpn); + } + nodesBefore = L2V.TreeNodes[u.incomingTree]; + + // Repack periodicity counter update + L2V.UpdatesSinceRepack[u.incomingTree]++; + L2V.RepackCounter++; + L2V_PeriodicRepack(); + + // First check: update to whole tree? + if ((0 == u.incomingOfs) && (L2V_TREE_SIZE == u.incomingSize)) { + TeardownTree(u.incomingTree); + TreeToNand(u.incomingTree, u.vpn); + L2V_root_depth[u.incomingTree] = 0; + return; + } + + // Share left/right, ripple up? + // Tear? + + u.level = 0; + u.thisStart = 0; + u.thisMax = L2V_TREE_SIZE; + u.nodePtr = L2V.Tree[u.incomingTree]; + + _L2V_ValidUp(u.vpn, u.incomingSize); + + + if (!LPTR_IS_NODEPTR(u.nodePtr)) { + Upd_TrivialInsert(); + return; + } + + // Search from top down + while (u.level < L2V_MAX_TREE_DEPTH_UPD) { + // Walk through + LPTR_UNPACK_NODE(u.nodePtr, u.cu); + u.node = L2V_IDX_TO_NODE(u.cu.u.nodeIdx); + u.atLevel[u.level] = u.node; + u.changed = FALSE32; + u.needsInsert = TRUE32; + u.tmpNode.start = 0; + u.tmpNode.max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(u.node, u.nOfs, u.nodeSize, u.cu, u.thisPtr) { + // Calculate endpoint + u.thisMax = u.thisStart + u.cu.span; + if (u.cu.isNodePtr) { + l2v_assert_lt(u.cu.u.nodeIdx, L2V_NODEPOOL_COUNT); + } + + // Identity overlap? + if (Upd_IdentityReplace()) { + // Exit + goto exit; + } + + // Complete overlap? Free this piece... + else if (Upd_CompleteOverlap()) { + // ok + } + + // Chop right off? + else if (Upd_ChopRight()) { + // ok + } + + // Chop left off? + else if (Upd_ChopLeft()) { + // ok + } + + // Chop middle? (+2 total) + else if ((u.incomingOfs > u.thisStart) && (u.incomingEnd < u.thisMax)) { + if (!u.cu.isNodePtr) { + Upd_ChopMiddleNand(); + } else { + u.nodePtr = u.thisPtr; + goto nextLevel; + } + } + + // Too far right or left? Just copy it out... + Upd_FillRemainder(); + + // Move along in the node + u.thisStart = u.thisMax; + } _L2V_NODE_ITERATE_END(u.nOfs); + + // Last guy in the tree, with CompleteOverlaps to the left? (Since that case doesn't insert.) + if (u.needsInsert) { + u.changed = TRUE32; + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } + + if (u.changed) { + // Will it fit? + if ((u.tmpNode.max > L2V_MIN_CONTIG_PER_NODE) && ((u.nOfs = Upd_GetNodeSize()) > L2V_NODE_SIZE)) { + // Try to share left/right + Upd_ShareLeft(); + Upd_ShareRight(); + + // Will it fit now? + if (((u.tmpNode.max-u.tmpNode.start) > L2V_MIN_CONTIG_PER_NODE) && ((u.nOfs = Upd_GetNodeSize()) > L2V_NODE_SIZE)) { + // Darn, split it + Upd_SplitAndPush(); + } else { + Upd_PushNodeOut(&u.tmpNode, u.node, u.tmpNode.start, u.tmpNode.max); + } + goto exit; + } + + if ((1 == (u.tmpNode.max - u.tmpNode.start)) && (0 == u.level)) { + // Single node, single entry? Squash up into root. + _L2V_FreeNode(u.node); + L2V.TreeNodes[u.incomingTree]--; + TreeToNand(u.incomingTree, u.tmpNode.cu[u.tmpNode.start].u.n.vpn); + L2V_root_depth[u.incomingTree] = 0; + goto exit; + } + + Upd_PushNodeOut(&u.tmpNode, u.node, 0, u.tmpNode.max); + goto exit; + } + + l2v_assert(0); + +nextLevel: + u.level++; + } + + // Fell through + + // Should never get here; otherwise, the tree is too deep (or recursive or pointing to randomness) + WMR_PANIC("NAND index update fell through: abort at level %d\n", u.level); + +exit: + // Did it get bigger than we thought it should? + if (u.level > L2V_TREE_DEPTH_REPACK) + { + L2V_Repack(u.incomingTree); + if (LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(L2V.Tree[u.incomingTree]))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + } + return; + } + + if(nodesBefore <= L2V.TreeNodes[u.incomingTree]) + { + L2V_root_depth[u.incomingTree] += (L2V.TreeNodes[u.incomingTree] - nodesBefore); + if(L2V_root_depth[u.incomingTree] < L2V_TREE_DEPTH_REPACK) + { + return; + } + } + + if (LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(L2V.Tree[u.incomingTree]))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + return; + } + + if(L2V_root_depth[u.incomingTree] >= L2V_TREE_DEPTH_REPACK) + { + L2V_Repack(u.incomingTree); + if (LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(L2V.Tree[u.incomingTree]))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + } + } +} + + +static void Teardown(lNode_t *node, UInt32 tree) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node and size + lPtr_t thisPtr; + ContigUnpacked_t cu; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + Teardown(L2V_IDX_TO_NODE(cu.u.nodeIdx), tree); + } else { + // Reduce valid counters + _L2V_ValidDown(cu.vpn, cu.span); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; +} + + +static void TeardownTree(UInt32 tree) +{ + ContigUnpacked_t cu; + + // Unpack the node + LPTR_UNPACK(L2V.Tree[tree], cu); + + if (cu.isNodePtr) { + // Tear down the tree + Teardown(L2V_IDX_TO_NODE(cu.u.nodeIdx), tree); + } else { + // It's a contig (probably just token but in case tree-sb ratios change, this line is necessary) + _L2V_ValidDown(cu.vpn, L2V_TREE_SIZE); + } +} + + +static int DestroySpanLeft(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 amount) +{ + lNode_t *node; + UInt32 nOfs, nodeSize; // Byte offset within the node, and size after subtracting overflows + UInt32 thisAmount; + Int32 children; + lNodeBig_t tmpNode; + BOOL32 changed = FALSE32; + ContigUnpacked_t thiscu; + lPtr_t thisPtr; + + l2v_assert_ne(amount, 0); + l2v_assert_le(amount, L2V_TREE_SIZE); + + if (!cu->isNodePtr) { + _L2V_ValidDown(cu->vpn, amount); + if (cu->u.n.vpn < L2V_VPN_SPECIAL) { + cu->u.n.vpn += amount; + *p = LPTR_PACK_NAND(*cu); + } + return -1; + } else { + node = L2V_IDX_TO_NODE(cu->u.nodeIdx); + tmpNode.max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + thisAmount = min(amount, thiscu.span); + if (thisAmount == thiscu.span) { + changed = TRUE32; + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thisAmount); + } else { + DestroySpanLeft(tree, &thiscu, &thisPtr, thiscu.span); + } + } else if (thisAmount == 0) { + // Copy it out + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } else { + changed = TRUE32; + children = -1; + + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thisAmount); + if (thiscu.u.n.vpn < L2V_VPN_SPECIAL) { + thiscu.u.n.vpn += thisAmount; + } + } else { + children = DestroySpanLeft(tree, &thiscu, &thisPtr, thisAmount); + } + + // Copy it out + if (children == 1) { + SuckOneUp(tree, &tmpNode, thisPtr); + } else { + thiscu.span -= thisAmount; + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } + } + amount -= thisAmount; + } _L2V_NODE_ITERATE_END(nOfs); + + if (changed) { + // Push it back out + Upd_PushNodeOut(&tmpNode, node, 0, tmpNode.max); + } + + if (0 == tmpNode.max) { + // Free this one + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; + *p = L2V_CONTIG_FREE_SIG; + } + + return tmpNode.max; + } +} + + +static int DestroySpanRight(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 keepAmount, UInt32 fullSpan) +{ + lPtr_t thisPtr; + lNode_t *node; + UInt32 nOfs, nodeSize; // Byte offset within the node + UInt32 thisAmount; + Int32 children; + lNodeBig_t tmpNode; + BOOL32 changed = FALSE32; + ContigUnpacked_t thiscu; + + l2v_assert_ne(keepAmount, 0); + l2v_assert_lt(keepAmount, L2V_TREE_SIZE); + l2v_assert_ne(fullSpan, 0); + l2v_assert_le(fullSpan, L2V_TREE_SIZE); + + if (!cu->isNodePtr) { + _L2V_ValidDown(cu->vpn, fullSpan-keepAmount); + return -1; + } else { + node = L2V_IDX_TO_NODE(cu->u.nodeIdx); + tmpNode.max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + thisAmount = min(keepAmount, thiscu.span); + if (thisAmount == thiscu.span) { + // Copy it out + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } else if (thisAmount == 0) { + changed = TRUE32; + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thiscu.span); + } else { + DestroySpanLeft(tree, &thiscu, &thisPtr, thiscu.span); + } + } else if (thisAmount < thiscu.span) { + changed = TRUE32; + children = -1; + + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thiscu.span - thisAmount); + } else { + children = DestroySpanRight(tree, &thiscu, &thisPtr, thisAmount, thiscu.span); + } + + // Copy it out + if (children == 1) { + SuckOneUp(tree, &tmpNode, thisPtr); + } else { + thiscu.span = thisAmount; + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } + } + keepAmount -= thisAmount; + } _L2V_NODE_ITERATE_END(nOfs); + + if (changed) { + // Push it back out + Upd_PushNodeOut(&tmpNode, node, 0, tmpNode.max); + } + + if (0 == tmpNode.max) { + // Free this one + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; + *p = L2V_CONTIG_FREE_SIG; + } + + return tmpNode.max; + } +} + + +static void DestroySpanMiddle(lPtr_t *p, UInt32 left, UInt32 right) +{ + ContigUnpacked_t cu; + + LPTR_UNPACK_NAND(*p, cu); + l2v_assert_eq(cu.isNodePtr, 0); // Must not be a nodePtr, since we recurse in the top-level function + _L2V_ValidDown(cu.vpn, right-left); +} + + +static void TreeToNand(UInt32 tree, UInt32 vpn) +{ + ContigUnpacked_t cu; + + cu.hasSpanOF = 0; + cu.u.n.vpn = vpn; + cu.span = 0; + L2V.Tree[tree] = LPTR_PACK_NAND(cu); + + _L2V_ValidUp(vpn, L2V_TREE_SIZE); +} + + +static void Upd_TrivialInsert() +{ + UInt32 nOfs, nodeSize; + lNode_t *node; + ContigUnpacked_t cu; + + LPTR_UNPACK_NAND(u.nodePtr, u.cu); + + // Break the rootPtr into a node + node = _L2V_AllocNode(); + nodeSize = L2V_NODE_SIZE; + L2V.TreeNodes[u.incomingTree] = 1; + nOfs = 0; + + // ValidDown for old section + if (u.cu.u.n.vpn < L2V_VPN_SPECIAL) { + _L2V_ValidDown(u.cu.u.n.vpn, u.incomingSize); + } + + // Break left? + if (u.incomingOfs) { + cu.u.n.vpn = u.cu.u.n.vpn; + cu.span = u.incomingOfs; + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(u.incomingOfs, L2V_TREE_SIZE); + } + + // Insert node + cu.u.n.vpn = u.vpn; + cu.span = u.incomingSize; + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(u.incomingSize, L2V_TREE_SIZE); + + // Break Right? + cu.span = L2V_TREE_SIZE - u.incomingEnd; + if (cu.span != 0) { + cu.u.n.vpn = u.cu.u.n.vpn; + // Move vpn if not special SB + if (cu.u.n.vpn < L2V_VPN_SPECIAL) { + cu.u.n.vpn += u.incomingEnd; + } + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(cu.span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(node, nOfs, nodeSize); + + // Update Tree ptr + cu.hasSpanOF = 0; + cu.u.nodeIdx = L2V_NODE_TO_IDX(node); + L2V.Tree[u.incomingTree] = LPTR_PACK_NODE(cu); + if (!LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) { + L2V_root_depth[u.incomingTree] = 0; + } +} + + +static BOOL32 Upd_IdentityReplace() +{ + lPtr_t *p; + UInt32 check_nOfs, check_nodeSize; + lPtr_t check_thisPtr; + ContigUnpacked_t check_cu, local_cu; + + if ((u.incomingOfs == u.thisStart) && (u.incomingSize == u.cu.span)) { + // = + + // Make sure we aren't missing a compression opportunity + if (_L2V_NodeBig_WillCompress(u.tmpNode, u.vpn, u.incomingSize)) { + return FALSE32; + } + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + // Destroy old, recursively destroying subtrees if necessary + DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.cu.span); + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + // Overwrite in place--works because nodeptrs are always 6 bytes, and if the span is the same size, updating in place will work + p = (lPtr_t*)(&u.node->bytes[u.nOfs]); + local_cu.isNodePtr = 0; + local_cu.hasSpanOF = 0; + if (LPTR_HASSPANOF(*p)) + local_cu.hasSpanOF = 1; + local_cu.u.n.vpn = u.vpn; + local_cu.span = u.cu.span; + if (local_cu.hasSpanOF) { + *(UInt16*)(&u.node->bytes[u.nodeSize]) = u.cu.span >> L2V_BITS_NAND_SPAN; + } + *p = LPTR_PACK_NAND(local_cu); + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + return TRUE32; + } + + return FALSE32; +} + + +static BOOL32 Upd_CompleteOverlap() +{ + if ((u.incomingOfs <= u.thisStart) && (u.incomingEnd >= u.thisMax)) { + u.changed = TRUE32; + // Destroy old span + DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.cu.span); + + return TRUE32; + } + + return FALSE32; +} + + +static void SuckOneUp(UInt32 tree, lNodeBig_t *big, lPtr_t ptr) +{ + lNode_t *node; + UInt32 nOfs, nodeSize, count; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + l2v_assert_eq(LPTR_IS_NODEPTR(ptr), 1); + node = L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(ptr)); + count = 0; + + // Iterate over children + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + // Push into u->tmpNode + _L2V_NodeBig_PushContig(big, &cu); + count++; + } _L2V_NODE_ITERATE_END(nOfs); + l2v_assert_eq(count, 1); + + // Free old node + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; +} + +static void SuckUp() +{ + lNode_t *node; + UInt32 nOfs, nodeSize; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + l2v_assert_eq(LPTR_IS_NODEPTR(u.thisPtr), 1); + node = L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(u.thisPtr)); + + // Iterate over children + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + // Push into u->tmpNode + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + } _L2V_NODE_ITERATE_END(nOfs); + + // Free old node + _L2V_FreeNode(node); + L2V.TreeNodes[u.incomingTree]--; +} + + +static BOOL32 Upd_ChopRight() +{ + Int32 children; + ContigUnpacked_t cu; + + if ((u.incomingOfs > u.thisStart) && (u.incomingOfs < u.thisMax) && (u.incomingEnd >= u.thisMax)) { + u.changed = TRUE32; + children = DestroySpanRight(u.incomingTree, &u.cu, &u.thisPtr, u.incomingOfs - u.thisStart, u.cu.span); + + // Try to reduce tree depth and maximize usage by sucking children up + if ((children >= 1) && (children <= L2V_SUCKUP_CHILDREN_MAX)) { + SuckUp(); + } else if (0 != children) { + // Still have a child node we need to reference + cu = u.cu; + cu.span = u.incomingOfs - u.thisStart; + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + } + + if (u.needsInsert) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } else { + l2v_assert(0); + } + + return TRUE32; + } + + return FALSE32; +} + + +static BOOL32 Upd_ChopLeft() +{ + Int32 children; + + if ((u.incomingOfs <= u.thisStart) && (u.incomingEnd > u.thisStart) && (u.incomingEnd < u.thisMax)) { + u.changed = TRUE32; + children = DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.incomingEnd - u.thisStart); + + if (u.needsInsert) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } + + // Try to reduce tree depth and maximize usage by sucking children up + if ((children >= 1) && (children <= L2V_SUCKUP_CHILDREN_MAX)) { + SuckUp(); + } else if (0 != children) { + // Still have a child node or nand-ptr we need to reference + u.tmpNode.cu[u.tmpNode.max] = u.cu; + // Ofs moving taken care of by DestroySpanleft + u.tmpNode.cu[u.tmpNode.max].span = u.thisMax - u.incomingEnd; + l2v_assert_ne(u.thisMax - u.incomingEnd, 0); + u.tmpNode.max++; + } + + return TRUE32; + } + + return FALSE32; +} + + +static void Upd_ChopMiddleNand() +{ + u.changed = TRUE32; + DestroySpanMiddle(&u.thisPtr, u.thisStart-u.incomingOfs, u.incomingEnd - u.incomingOfs); + + // Break left + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.cu.u.n.vpn, u.incomingOfs - u.thisStart); + + // Insert in middle + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + + // Break right + // +1 + if (u.cu.u.n.vpn < L2V_VPN_SPECIAL) { + u.cu.u.n.vpn += (u.incomingEnd - u.thisStart); + } + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.cu.u.n.vpn, u.thisMax - u.incomingEnd); +} + + +static void Upd_FillRemainder() +{ + if ((u.thisStart >= u.incomingEnd) || (u.thisMax <= u.incomingOfs)) { + // Did none of the above trims/etc insert the new ptr? + // This is because we had an exact eclipse(s) + if (u.needsInsert && (u.thisStart >= u.incomingEnd)) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } + + // Copy into tmpNode + _L2V_NodeBig_PushContig(&u.tmpNode, &u.cu); + } +} + + +static int Upd_GetNodeSize() +{ + UInt32 i, nOfs; + + nOfs = 0; + + for (i = u.tmpNode.start; i < u.tmpNode.max; i++) { + nOfs += _L2V_CONTIG_SIZE(u.tmpNode.cu[i]); + } + + return nOfs; +} + + +static int Upd_PushNodeOut(lNodeBig_t *b, lNode_t *node, UInt32 minEl, UInt32 maxEl) +{ + UInt32 i, nOfs, nodeSize; + UInt32 sumSpan; + + sumSpan = 0; + + l2v_assert_lt(minEl, L2V_LNODEBIG_MAX); + l2v_assert_le(maxEl, L2V_LNODEBIG_MAX); + + // Copy and squeeze + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + for (i = minEl; i < maxEl; i++) { + _L2V_NODE_PUSH_CONTIG(node, nOfs, nodeSize, b->cu[i]); + + sumSpan += b->cu[i].span; + l2v_assert_le(b->cu[i].span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(node, nOfs, nodeSize); + + return sumSpan; +} + + +static void Upd_SplitAndPush() +{ + lNode_t *newNode, *oldNode; + UInt32 half, span0, span1; + + // Get new node + oldNode = u.node; + newNode = _L2V_AllocNode(); + L2V.TreeNodes[u.incomingTree]++; + + // Divide and push to old/new + half = ((u.tmpNode.max - u.tmpNode.start)>>1) + 1 + u.tmpNode.start; + span0 = Upd_PushNodeOut(&u.tmpNode, oldNode, u.tmpNode.start, half); + l2v_assert_ne(span0, 0); + span1 = Upd_PushNodeOut(&u.tmpNode, newNode, half, u.tmpNode.max); + l2v_assert_ne(span1, 0); + + RippleUp(oldNode, span0, newNode, span1); +} + + +static void RippleUp(lNode_t *oldNode, UInt32 span0, lNode_t *newNode, UInt32 span1) +{ + lNode_t *parent, *parent1; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, span; + UInt32 parentspan0, parentspan1, half; + ContigUnpacked_t cu; + + u.tmpNode.start = u.tmpNode.max = 0; + + if (0 == u.level) { + // Special case: allocate another parent node, link these in + parent = _L2V_AllocNode(); + L2V.TreeNodes[u.incomingTree]++; + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(oldNode), span0); + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(newNode), span1); + span = Upd_PushNodeOut(&u.tmpNode, parent, 0, u.tmpNode.max); + l2v_assert_eq(span, L2V_TREE_SIZE); + + // Replace root + cu.u.nodeIdx = L2V_NODE_TO_IDX(parent); + cu.span = 0; + cu.hasSpanOF = 0; // To get rid of analyzer warning--not used in root ptrs + L2V.Tree[u.incomingTree] = LPTR_PACK_NODE(cu); + } else { + // Get parent + parent = u.atLevel[u.level-1]; + + // Copy into tmpNode + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == oldNode)) { + // Copy old node + _L2V_NodeBig_PushContig_Node(&u.tmpNode, cu.u.nodeIdx, span0); + l2v_assert_ne(span0, 0); + + // Copy new node + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(newNode), span1); + l2v_assert_ne(span1, 0); + + if ((span0+span1) != cu.span) { + WMR_PANIC("NAND index: span0: %d, span1: %d, +: %d, span: %d", span0, span1, span0+span1, cu.span); + } + } else { + // Not involved, copy it out + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + l2v_assert_ne(cu.span, 0); + } + } _L2V_NODE_ITERATE_END(nOfs); + + if (u.tmpNode.max > L2V_MIN_CONTIG_PER_NODE) { + // Split + parent1 = _L2V_AllocNode(); + L2V.TreeNodes[u.incomingTree]++; + half = (u.tmpNode.max>>1) + 1; + parentspan0 = Upd_PushNodeOut(&u.tmpNode, parent, 0, half); + l2v_assert_ne(parentspan0, 0); + parentspan1 = Upd_PushNodeOut(&u.tmpNode, parent1, half, u.tmpNode.max); + l2v_assert_ne(parentspan1, 0); + + // Ripple up + u.level--; + RippleUp(parent, parentspan0, parent1, parentspan1); + } else { + // Push + Upd_PushNodeOut(&u.tmpNode, parent, 0, u.tmpNode.max); + } + } +} + + +static void Upd_ShareLeft() +{ + lNode_t *parent, *left; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, left_nodeIdx, left_nOfs, left_span, spanUp; + BOOL32 left_isNodePtr; + ContigUnpacked_t cu; + + // Initialize so the compiler doesn't complain + cu.hasSpanOF = 0; + cu.span = 0; + left_nOfs = 0; + left_nodeIdx = 0; + left_span = 0; + left_isNodePtr = 0; + + if (0 == u.level) { + // Can't share if we're root... + return; + } + + // Get parent + parent = u.atLevel[u.level-1]; + left = NULL; + + // Find me, then previous sibling + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == u.node)) { + goto foundIt; + } + left = L2V_IDX_TO_NODE(cu.u.nodeIdx); + left_nOfs = nOfs; + left_nodeIdx = cu.u.nodeIdx; + left_span = cu.span; + left_isNodePtr = cu.isNodePtr; + } _L2V_NODE_ITERATE_END(nOfs); + + // Couldn't find ...??? + WMR_PANIC("NAND index update failed node identity search: level: %d, parent: %p\n", u.level, (void*)parent); + +foundIt: + if ((NULL == left) || !left_isNodePtr) { + // We were the first pointed by parent, sorry, no easy left search... + return; + } + + // Great, push some in + spanUp = Upd_PushLeft(left); + + // Down my span in the parent + cu.span -= spanUp; + *(lPtr_t*)(&parent->bytes[nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize] = cu.span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(cu.span, 0); + + // Update left's span in parent + left_span += spanUp; + cu.span = left_span; + cu.u.nodeIdx = left_nodeIdx; + *(lPtr_t*)(&parent->bytes[left_nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize+sizeof(UInt16)] = left_span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(left_span, 0); +} + + +static void Upd_ShareRight() +{ + lNode_t *parent, *right; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, my_nOfs, my_nodeIdx, my_span, spanUp; + BOOL32 isNext; + ContigUnpacked_t cu; + + // Initialize so the compiler doesn't complain + my_span = 0; + my_nodeIdx = 0; + my_nOfs = 0; + + if (0 == u.level) { + // Can't share if we're root... + return; + } + + // Get parent + parent = u.atLevel[u.level-1]; + right = NULL; + + // Find me, then next sibling + isNext = FALSE32; + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (isNext) { + if (cu.isNodePtr) { + right = L2V_IDX_TO_NODE(cu.u.nodeIdx); + } + goto foundIt; + } + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == u.node)) { + isNext = TRUE32; + my_span = cu.span; + my_nOfs = nOfs; + my_nodeIdx = cu.u.nodeIdx; + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Couldn't find right because we were the last one? + l2v_assert_eq(isNext, 1); + return; + +foundIt: + if (NULL == right) { + // No node* right next to us, sorry... + return; + } + + // Great, push some in + spanUp = Upd_PushRight(right); + + // Update right's span in parent + cu.span += spanUp; + *(lPtr_t*)(&parent->bytes[nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize] = cu.span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(cu.span, 0); + + // Down my span in the parent + my_span -= spanUp; + cu.u.nodeIdx = my_nodeIdx; + cu.span = my_span; + *(lPtr_t*)(&parent->bytes[my_nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize+sizeof(UInt16)] = cu.span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(cu.span, 0); +} + + +static int Upd_PushLeft(lNode_t *left) +{ + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, spanUp, myEntrySize; + ContigUnpacked_t cu; + + spanUp = 0; + + // Has room? + _L2V_NODE_ITERATE(left, nOfs, nodeSize, cu, thisPtr) { + } _L2V_NODE_ITERATE_END(nOfs); + + // Calculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.start]); + + // While we have space... + while ((nOfs < (nodeSize-myEntrySize)) && ((u.tmpNode.max - u.tmpNode.start) > 1)) { + // Copy it out + l2v_assert_ne(u.tmpNode.cu[u.tmpNode.start].span, 0); + l2v_assert_le(u.tmpNode.cu[u.tmpNode.start].span, L2V_TREE_SIZE); + _L2V_NODE_PUSH_CONTIG(left, nOfs, nodeSize, u.tmpNode.cu[u.tmpNode.start]); + + // Move along + spanUp += u.tmpNode.cu[u.tmpNode.start].span; + u.tmpNode.start++; + + // Recalculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.start]); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(left, nOfs, nodeSize); + + // And ripple up + return spanUp; +} + + +static int Upd_PushRight(lNode_t *right) +{ + lPtr_t thisPtr; + UInt32 i, numToCopy, spanUp, nOfs, nodeSize, orig_nOfs, orig_nodeSize, myEntrySize; + lNodeBig_t localNode; + BOOL32 didSome = FALSE32; + ContigUnpacked_t cu; + + spanUp = 0; + + // Copy originals out and find out how much free space there is + localNode.start = localNode.max = 0; + _L2V_NODE_ITERATE(right, orig_nOfs, orig_nodeSize, cu, thisPtr) { + localNode.cu[localNode.max] = cu; + l2v_assert_ne(cu.span, 0); + localNode.max++; + } _L2V_NODE_ITERATE_END(orig_nOfs); + + // Calculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.max-1]); + + nOfs = 0; + numToCopy = 0; + + // While we have space... + while (((nOfs+orig_nOfs) < (orig_nodeSize-myEntrySize)) && ((u.tmpNode.max - u.tmpNode.start - numToCopy) > 1)) { + didSome = TRUE32; + + // Mark it as copyable + u.tmpNode.max--; + numToCopy++; + nOfs += myEntrySize; + + // Recalculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.max-1]); + } + + if (!didSome) { + // No room, sorry... + return 0; + } + + + + // Copy new ones + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + i = 0; + while (numToCopy) { + _L2V_NODE_PUSH_CONTIG(right, nOfs, nodeSize, u.tmpNode.cu[u.tmpNode.max+i]); + l2v_assert_le(u.tmpNode.cu[u.tmpNode.max+i].span, L2V_TREE_SIZE); + spanUp += u.tmpNode.cu[u.tmpNode.max+i].span; + i++; + numToCopy--; + } + + // Copy originals + for (localNode.start = 0; localNode.start < localNode.max; localNode.start++) { + _L2V_NODE_PUSH_CONTIG(right, nOfs, nodeSize, localNode.cu[localNode.start]); + l2v_assert_ne(localNode.cu[localNode.start].span, 0); + l2v_assert_le(localNode.cu[localNode.start].span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(right, nOfs, nodeSize); + + // And ripple up + return spanUp; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.c new file mode 100644 index 0000000..a05d71c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" + + +#if L2V_TRACK_VALID!=0 + +void _L2V_ValidUp(UInt32 vpn, UInt32 count) +{ + UInt32 sb = vpn / L2V.pagesPerSB; + L2V.Valid[sb] += count; + //l2v_assert_le(L2V.Valid[sb], sbsize); +} + +void _L2V_ValidDown(UInt32 vpn, UInt32 count) +{ + UInt32 sb = vpn / L2V.pagesPerSB; + //l2v_assert_ge(L2V.Valid[sb], count); + L2V.Valid[sb] -= count; +} + +#endif // track valid + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.h new file mode 100644 index 0000000..875b524 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/L2V_Valid.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_VALID_H__ +#define __L2V_VALID_H__ + + +#include "L2V_Defines.h" + +#if L2V_TRACK_VALID!=0 +extern void _L2V_ValidUp(UInt32 vpn, UInt32 count); +extern void _L2V_ValidDown(UInt32 vpn, UInt32 count); +#else +#define _L2V_ValidUp(vpn, count) +#define _L2V_ValidDown(vpn, count) +#endif + + +#endif // __L2V_VALID_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMRFeatures-test.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMRFeatures-test.h new file mode 100644 index 0000000..74ec296 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMRFeatures-test.h @@ -0,0 +1 @@ +#define ENABLE_L2V_TREE (1) diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.c new file mode 100644 index 0000000..e5c0a7e --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "WMROAM.h" + + +void *WMR_MALLOC(UInt32 size) +{ + void * ptr = malloc(size); + if (ptr) + { + WMR_MEMSET(ptr, 0, size); + } + return ptr; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.h new file mode 100644 index 0000000..788fa92 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/L2V/WMROAM-test.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __WMROAM_H__ +#define __WMROAM_H__ + +#include +#include +#include +#include +#include + +#define UInt32 uint32_t +#define Int32 int32_t +#define UInt16 uint16_t +#define Int16 int16_t +#define UInt8 uint8_t +#define Int8 int8_t +#define BOOL32 bool +#define TRUE32 true +#define FALSE32 false + +#define _WMR_ASSERT(e, file, line) { printf("%s:%u: failed assertion '%s'\nWaiting for debugger...\n", file, line, e); abort(); } +#define WMR_ASSERT(e) if (!(e)) _WMR_ASSERT(#e, __FILE__, __LINE__) +#define WMR_PANIC(format, args...) { printf(format , ##args); abort(); } +#define WMR_MEMSET(a, b, c) memset(a, b, c) +#define WMR_FREE(x, y) free(x) + +extern void *WMR_MALLOC(UInt32 size); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_TRACE_* +// +// Compile-time tracepoints (not supported) +// +#define WMR_TRACE_0(...) +#define WMR_TRACE_1(...) +#define WMR_TRACE_2(...) +#define WMR_TRACE_3(...) +#define WMR_TRACE_4(...) +#define WMR_TRACE_IST_0(...) +#define WMR_TRACE_IST_1(...) +#define WMR_TRACE_IST_2(...) +#define WMR_TRACE_IST_3(...) +#define WMR_TRACE_IST_4(...) + +#endif // __WMROAM_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL.c new file mode 100644 index 0000000..61edfab --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL.c @@ -0,0 +1,6363 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define TIME_TREE 0 +#define AND_TRACE_LAYER FTL + +#include "yaFTL_whoami.h" +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "WMRBuf.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "yaFTLTypes.h" +#include "FTL.h" +#include "yaFTL_Defines.h" +#include "yaFTL_gc.h" +#include "yaFTL_BTOC.h" +#include "L2V/L2V_Extern.h" +#if TIME_TREE +#include +#endif +#include "WMRFeatures.h" +#ifndef ENABLE_L2V_TREE +#error ENABLE_L2V_TREE must be set to 0 or 1 in WMRFeatures.h +#endif + +#define kYaftlMinorVersion (1) + + +#if !NAND_RAW && !NAND_PPN +#error PPN or raw? +#endif + +#ifdef AND_COLLECT_STATISTICS +FTLStatistics stFTLStatistics; +#endif /* AND_COLLECT_STATISTICS */ + +#define CXT_VER "CX01" +FTLWMRDeviceInfo yaFTL_FTLDeviceInfo; +VFLFunctions yaFTL_VFLFunctions; +yaFTL_t yaFTL; +static BOOL32 yaftl_init_done = FALSE32; + +/* static functions declaration section */ +static void YAFTL_FreeMemory(void); +static Int32 YAFTL_Init(VFLFunctions *pVFLFunctions); +static Int32 YAFTL_Open(UInt32 *pTotalScts, + UInt32 * pdwSectorSize, + BOOL32 nandFullRestore, + BOOL32 justFormatted, + UInt32 dwMinorVer, + UInt32 dwOptions); +static Int32 YAFTL_Read(UInt32 nLpn, UInt32 nNumOfScts, + UInt8 *pBuf); +static void YAFTL_Close(void); +static BOOL32 YAFTL_GetStruct(UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 * pdwStructSize); +Int32 _readPage(UInt32 vpn, UInt8 *pageData, + PageMeta_t *pMeta, + BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 scrubOnUECC); +BOOL32 _readMultiPages(UInt32 * padwVpn, + UInt16 wNumPagesToRead, UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 bInternalOp, BOOL32 scrubOnUECC); +#if ENABLE_L2V_TREE +static void PopulateFromIndexCache(UInt32 indexPageNo, UInt32 *indexPageData); +#endif //ENABLE_L2V_TREE + +static void PopulateTreesOnBoot_Fast(void); + +#ifndef AND_READONLY +static Int32 YAFTL_Write(UInt32 nLpn, UInt32 nNumOfScts, + UInt8 *pBuf, BOOL32 isStatic); +static Int32 YAFTL_Format(UInt32 dwOptions); +static Int32 YAFTL_WearLevel(void); +static BOOL32 YAFTL_GarbageCollect(void); +static BOOL32 YAFTL_ShutdownNotify(BOOL32 boolMergeLogs); +Int32 _writePage(UInt32 vpn, UInt8 *pageData, + PageMeta_t *, + BOOL32 bInternalOp); +static ANDStatus writeIndexPage(UInt8 *pageBuffer, PageMeta_t *mdPtr, + UInt8 flag); +UInt32 _allocateBlock(UInt32 blockNo, UInt8 flag, UInt8 type); +BOOL32 _writeMultiPages(UInt16 vbn, UInt16 pageOffset, + UInt16 wNumPagesToWrite, UInt8 *pageData, + PageMeta_t *mdPtr, + BOOL32 bInternalOp); +UInt32* IndexLoadDirty(UInt32 lba, UInt32 *indexOfs); +UInt32* IndexLoadClean(UInt32 lba, UInt32 *indexOfs, UInt32 *d_tocEntry); +void IndexMarkDirty(UInt32 tocEntry); +ANDStatus invalidateCXT(void); +BOOL32 isBlockInEraseNowList(UInt16 blockNo); +BOOL32 removeBlockFromEraseNowList(UInt16 blockNo); +BOOL32 addBlockToEraseNowList(UInt16 blockNo); + +#endif // ! AND_READONLY + +/* + static variables/structures declaration section + */ + +typedef struct blockList +{ + WeaveSeq_t weaveSeq; + UInt16 blockNo; + struct blockList *next; + struct blockList *prev; +} BlockListType; + +typedef struct BlockRange +{ + UInt32 start; + UInt32 end; +} BlockRangeType; + +#if NAND_PPN +typedef struct YAFTLControlInfo +{ + UInt32 versionNo; + UInt32 indexSize; /* index size in blocks */ + UInt32 logicalPartitionSize; /* partititon size in pages exposed to file system */ + UInt32 wrState_data_block; /* current physical block being used for updates */ + UInt32 wrState_data_weaveSeq_Lo; + UInt32 wrState_data_weaveSeq_Hi; + UInt32 wrState_index_block; /* current physical block being used for updates */ + UInt32 wrState_index_weaveSeq_Lo; + UInt32 wrState_index_weaveSeq_Hi; + UInt32 seaState_data_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_index_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_data_allocdBlocks; + UInt32 seaState_index_allocdBlocks; + UInt32 indexCacheSize; + UInt32 FTLRestoreCnt; + UInt32 reserved32[10]; + + UInt16 TOCtableEntriesNo; /* number of entries in index TOC table */ + UInt16 controlPageNo; + UInt16 indexPageRatio; /* TOC of each block contains Lpa for each page written to block */ + UInt16 freeCachePages; + UInt16 nextFreeCachePage; + UInt16 wrState_data_nextPage; /* offset in current block of next free page */ + UInt16 wrState_index_nextPage; /* offset in current block of next free page */ + UInt32 reserved16[10]; + + UInt8 exportedRatio; + UInt8 cxtEraseCounter; + UInt8 reserved8[10]; +} YAFTLControlInfoType; +#elif NAND_RAW +typedef struct YAFTLControlInfo +{ + UInt32 versionNo; + UInt32 indexSize; /* index size in blocks */ + UInt32 logicalPartitionSize; /* partititon size in pages exposed to file system */ + UInt32 wrState_data_block; /* current physical block being used for updates */ + UInt32 wrState_data_weaveSeq; + UInt32 wrState_index_block; /* current physical block being used for updates */ + UInt32 wrState_index_weaveSeq; + UInt32 seaState_data_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_index_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_data_allocdBlocks; + UInt32 seaState_index_allocdBlocks; + UInt32 indexCacheSize; + UInt32 FTLRestoreCnt; + UInt32 reserved32[10]; + + UInt16 TOCtableEntriesNo; /* number of entries in index TOC table */ + UInt16 controlPageNo; + UInt16 indexPageRatio; /* TOC of each block contains Lpa for each page written to block */ + UInt16 freeCachePages; + UInt16 nextFreeCachePage; + UInt16 wrState_data_nextPage; /* offset in current block of next free page */ + UInt16 wrState_index_nextPage; /* offset in current block of next free page */ + UInt32 reserved16[10]; + + UInt8 exportedRatio; + UInt8 cxtEraseCounter; + UInt8 reserved8[10]; +} YAFTLControlInfoType; +#else +#error PPN or raw? +#endif + +static BOOL32 _allocateRestoreIndexBuffers(BlockRangeType **blockRangeBuffer, UInt32 **indexTable, UInt32 *indexTableSize); + +#ifdef AND_COLLECT_STATISTICS +#ifndef AND_READONLY +static BOOL32 _FTLGetStatisticsToCxt(UInt8 * pabData); +#endif //ifndef AND_READONLY +static BOOL32 _FTLSetStatisticsFromCxt(UInt8 * pabData); +#endif +#ifndef AND_READONLY +static BOOL32 YAFTL_WriteStats(void); +#define CXT_ERASE_GAP 50 +#define MOVE_CXT_TRESHOLD 1000 + +#define ERASE_CXT_UPDATE_THRESHOLD (FTL_AREA_SIZE>>4) +#define WRITE_CXT_UPDATE_THRESHOLD (USER_PAGES_TOTAL>>4) +#endif +static UInt32 tempIndexBufferSize = 0; +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ + +void freeBlockList(BlockListType * listHead) +{ + BlockListType * tmpPtr = listHead; + while(tmpPtr != NULL) + { + listHead = tmpPtr; + tmpPtr = tmpPtr->next; + WMR_FREE(listHead, sizeof(BlockListType)); + + } +} + +#if TIME_TREE +mach_timebase_info_data_t sTimebaseInfo; + +static UInt64 ANDPerf_getTime() { + return mach_absolute_time(); +} + +static UInt32 ANDPerf_toUs(UInt64 elapsed) { + if (sTimebaseInfo.denom != sTimebaseInfo.numer) { + if (sTimebaseInfo.denom == 1) { + elapsed *= sTimebaseInfo.numer; + } else { + elapsed = (elapsed * sTimebaseInfo.numer) / (uint64_t)sTimebaseInfo.denom; + } + } + + return elapsed / 1000 /* NS_PER_USEC */; +} +#endif // TIME_TREE + +static void updateReadCounter(UInt16 vba) +{ + if (yaFTL.blockArray[vba].pagesRead > YAFTL_READ_DISTURB_LIMIT) + return; + + yaFTL.blockArray[vba].pagesReadSubCounter++; + if(yaFTL.blockArray[vba].pagesReadSubCounter >= PAGES_READ_SUB_COUNTER_LIMIT) + { + yaFTL.blockArray[vba].pagesReadSubCounter = 0; + yaFTL.blockArray[vba].pagesRead++; + } +} + +static BOOL32 _InitDeviceInfo(void) +{ + yaFTL_FTLDeviceInfo.wPagesPerVb = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + yaFTL_FTLDeviceInfo.wUserVbTotal = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_NUM_OF_USER_SUBLK); + yaFTL_FTLDeviceInfo.wBytesPerPage = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + yaFTL_FTLDeviceInfo.wBytesPerPageMeta = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES) * (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + yaFTL_FTLDeviceInfo.wNumOfBanks = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_NUM_OF_BANKS); + yaFTL_FTLDeviceInfo.dwUserPagesTotal = (UInt32)yaFTL_FTLDeviceInfo.wUserVbTotal * + (UInt32)yaFTL_FTLDeviceInfo.wPagesPerVb; + + debug(INIT, "wPagesPerVb 0x%X", yaFTL_FTLDeviceInfo.wPagesPerVb); + debug(INIT, "wUserVbTotal 0x%X", yaFTL_FTLDeviceInfo.wUserVbTotal); + debug(INIT, "wBytesPerPage 0x%X", yaFTL_FTLDeviceInfo.wBytesPerPage); + debug(INIT, "wNumOfBanks 0x%X", yaFTL_FTLDeviceInfo.wNumOfBanks); + debug(INIT, "dwUserPagesTotal 0x%X", yaFTL_FTLDeviceInfo.dwUserPagesTotal); + + if (sizeof(PageMeta_t) != yaFTL_FTLDeviceInfo.wBytesPerPageMeta) { + WMR_PANIC("yaFTL meta struct size (%d) not equal to bytes per metadata (%d)", sizeof(PageMeta_t), yaFTL_FTLDeviceInfo.wBytesPerPageMeta); + } + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Init */ +/* DESCRIPTION */ +/* This function initializes yaftl global structures */ +/* RETURN VALUES */ +/* FTL_SUCCESS */ +/* YAFTL_Init is completed */ +/* FTL_CRITICAL_ERROR */ +/* YAFTL_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +YAFTL_Init(VFLFunctions *pVFLFunctions) +{ + UInt16 pagesInBlk; + UInt16 pageSize; + UInt32 temp1; + + // Do not allow multiple init() calls because number of user blocks can change + WMR_ASSERT(!yaftl_init_done); + + // Guarantee that yaftl context was packed as expected +#if NAND_PPN + WMR_ASSERT(sizeof(struct YAFTLControlInfo) == 168); +#elif NAND_RAW + WMR_ASSERT(sizeof(struct YAFTLControlInfo) == 160); +#else +#error PPN or raw? +#endif + + // Initialize yaFTL structure + WMR_MEMSET((void*)&yaFTL, 0, sizeof(yaFTL)); + yaFTL.readBufferIndex = 0xffffffff; + yaFTL.currentCxtVpn = 0xffffffff; + yaFTL.indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; + yaFTL.exportedRatio = DEFAULT_EXPO_RATIO; + + WMR_MEMCPY(&yaFTL_VFLFunctions, pVFLFunctions, sizeof(VFLFunctions)); + debug(INIT, "YAFTL_INIT[start]"); + _InitDeviceInfo(); + + pagesInBlk = PAGES_PER_SUBLK; + pageSize = BYTES_PER_PAGE; + /* find out how many pages we need to keep pointer to each data/index page within unit */ + for (yaFTL.controlPageNo = 1; (Int32)(pagesInBlk - yaFTL.controlPageNo) * sizeof(Int32) > ((Int32)pageSize * yaFTL.controlPageNo) - (yaFTL.controlPageNo * sizeof(Int32)); yaFTL.controlPageNo++) + + { + ; + } + debug(INIT, "yaFTL.controlPageNo %d", yaFTL.controlPageNo); + debug(INIT, " PAGES_PER_SUBLK %d", PAGES_PER_SUBLK); + debug(INIT, "BYTES_PER_PAGE %d", BYTES_PER_PAGE); + + yaFTL.indexPageRatio = pageSize / sizeof(UInt32); + + // Buffer allocations + WMR_BufZone_Init(&yaFTL.BufZone); + yaFTL.quickRestore_tBuff = (UInt8 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, BYTES_PER_PAGE); + yaFTL.tmpReadBuffer = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, BYTES_PER_PAGE); + yaFTL.restoreTOC = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.meta_restoreIdx = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_restoreData = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_readCxt = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_quickRestore = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_invalidateCxt = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_writeCxt = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_restoreMountErase = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_restoreMount = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_clearEntryInCache = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_writeBTOC = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_indexLoadDirty = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_getStats = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_GetBlockTOC = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_IsDataPageCurrent = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_WriteZoneData = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.singleMdPtr = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.writeMdPtr = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, NUM_BANKS * YAFTL_WRITE_MAX_STRIPES * sizeof(PageMeta_t)); + yaFTL.readMdPtr = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, (PAGES_PER_SUBLK)*sizeof(PageMeta_t)); + + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BufZone)) { + goto errorPath; + } + + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.quickRestore_tBuff); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.tmpReadBuffer); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.restoreTOC); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreIdx); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreData); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_readCxt); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_quickRestore); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_invalidateCxt); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_writeCxt); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreMountErase); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreMount); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_clearEntryInCache); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_writeBTOC); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_indexLoadDirty); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_getStats); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_GetBlockTOC); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_IsDataPageCurrent); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_WriteZoneData); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.singleMdPtr); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.writeMdPtr); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.readMdPtr); + WMR_BufZone_FinishedRebases(&yaFTL.BufZone); + + debug(INIT, "yaFTL.controlPageNo %d", yaFTL.controlPageNo); + debug(INIT, "BYTES_PER_PAGE %d", BYTES_PER_PAGE); + debug(INIT, "indexPageRatio %d", yaFTL.indexPageRatio); + + /* size of media in pages after we take out CTX ,free blocks and block TOC for each block */ + temp1 = (pagesInBlk - yaFTL.controlPageNo) * (FTL_AREA_SIZE - FTL_CXT_SECTION_SIZE - FREE_BLK_TRH); + + yaFTL.indexSize = (temp1 / (yaFTL.indexPageRatio * (pagesInBlk - yaFTL.controlPageNo))) * INDEX_BLOCKS_RATIO; + if (temp1 % (yaFTL.indexPageRatio * (pagesInBlk - yaFTL.controlPageNo))) + { + yaFTL.indexSize += INDEX_BLOCKS_RATIO; + } + + yaFTL.dataSize = FTL_AREA_SIZE - (yaFTL.indexSize + FTL_CXT_SECTION_SIZE); + yaFTL.logicalPartitionSize = temp1 - yaFTL.indexSize * PAGES_PER_SUBLK; /* logical parititon size in pages . this is the size reported to file system */ + + yaFTL.TOCtableEntriesNo = (FTL_AREA_SIZE * PAGES_PER_SUBLK * 4) / BYTES_PER_PAGE; + yaFTL.tocArray = (TOCEntry *)WMR_MALLOC(yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + if (yaFTL.tocArray == NULL) + { + goto errorPath; + } + yaFTL.blockArray = (BlockEntry *)WMR_MALLOC(FTL_AREA_SIZE * sizeof(BlockEntry)); + + if (yaFTL.blockArray == NULL) + { + goto errorPath; + } + + yaFTL.multiReadvpN = (UInt32 *)WMR_MALLOC(sizeof(UInt32) * PAGES_PER_SUBLK); + if (yaFTL.multiReadvpN == NULL) + { + goto errorPath; + } + + yaFTL.cxtSizeTOC = (yaFTL.TOCtableEntriesNo * sizeof(UInt32)) / BYTES_PER_PAGE; + if ((yaFTL.TOCtableEntriesNo * sizeof(UInt32)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeTOC++; + } + + yaFTL.cxtSizeBlockStatus = FTL_AREA_SIZE / BYTES_PER_PAGE; + if (FTL_AREA_SIZE % BYTES_PER_PAGE) + { + yaFTL.cxtSizeBlockStatus++; + } + + yaFTL.cxtSizeBlockRead = (FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeBlockRead++; + } + + yaFTL.cxtSizeBlockErase = (FTL_AREA_SIZE * sizeof(UInt32)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt32)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeBlockErase++; + } + + yaFTL.cxtSizeValidPagesD = (FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeValidPagesD++; + } + + yaFTL.cxtSizeValidPagesI = (FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeValidPagesI++; + } + + yaFTL.cxtSize = (yaFTL.cxtSizeTOC + yaFTL.cxtSizeBlockStatus + yaFTL.cxtSizeBlockRead + yaFTL.cxtSizeBlockErase + yaFTL.cxtSizeValidPagesI + yaFTL.cxtSizeValidPagesD) + (2 + 2 * yaFTL.controlPageNo) /* yaftl_controlInfo + currentDTOC + currentITOC + yaftl/vfl/fil stats .each one page */; +#ifndef AND_READONLY + yaFTL.cxtAllocation = 0; + yaFTL.cxtEraseCounter = 0; + yaFTL.cxtValid = 0; yaFTL.currentCxtVpn = 0xffffffff; +#endif // ! AND_READONLY + WMR_MEMSET(&yaFTL.seaState, 0, sizeof(yaFTL.seaState)); +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&stFTLStatistics, 0, sizeof(FTLStatistics)); +#endif /* AND_COLLECT_STATISTICS */ + +#if ENABLE_L2V_TREE + L2V_Search_Init(&yaFTL.read_c); +#endif // ENABLE_L2V_TREE + +#ifndef AND_READONLY + if (FTL_SUCCESS != YAFTL_GC_Init()) + { + goto errorPath; + } +#endif + + if (!BTOC_Init()) + { + goto errorPath; + } + + // Get wrState TOCs + yaFTL.wrState.data.TOC = BTOC_Alloc(0xfffffffd, 1); + yaFTL.wrState.index.TOC = BTOC_Alloc(0xfffffffe, 0); + +#if ENABLE_L2V_TREE + if (!L2V_Init(yaFTL.logicalPartitionSize, FTL_AREA_SIZE, PAGES_PER_SUBLK)) { + return FTL_CRITICAL_ERROR; + } +#endif // ENABLE_L2V_TREE + + // Success path + yaftl_init_done = TRUE32; + + if( yaFTL.indexSize == 3) + { + yaFTL.indexSize++; + yaFTL.dataSize--; + } + + yaFTL.erasedBlockCount = 0; + return FTL_SUCCESS; + +errorPath: + YAFTL_FreeMemory(); + return FTL_CRITICAL_ERROR; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* addBlockToList */ +/* DESCRIPTION */ +/* This function builds linked list of valid units ( used in restore ) */ +/* RETURN VALUES */ +/* pointer to a new entry ina list */ +/* */ +/*****************************************************************************/ +static BlockListType *addBlockToList(BlockListType *listHead, UInt16 Vbn, WeaveSeq_t weaveSeq) +{ + BlockListType *nextBlock; + + nextBlock = (BlockListType *)WMR_MALLOC(sizeof(BlockListType)); + if (nextBlock == NULL) + { + debug(ERROR, "cannot allocate %d ", sizeof(BlockListType)); + return NULL; + } + + nextBlock->next = NULL; + nextBlock->prev = NULL; + nextBlock->weaveSeq = weaveSeq; + nextBlock->blockNo = Vbn; + + if (listHead == NULL) + { + nextBlock->next = NULL; + nextBlock->prev = NULL; + listHead = nextBlock; + } + else + { + BlockListType *tmpPtr = listHead; + + while ((tmpPtr->next != NULL) && (tmpPtr->weaveSeq > weaveSeq)) + { + tmpPtr = tmpPtr->next; + } + if (tmpPtr->weaveSeq == weaveSeq) + { + if(sizeof(WeaveSeq_t) <= 4) + WMR_PRINT(QUAL_FATAL, "yaFTL found two blocks (%d, %d) with the same weaveSeq (%d)\n", tmpPtr->blockNo, Vbn, weaveSeq); + else + WMR_PRINT(QUAL_FATAL, "yaFTL found two blocks (%d, %d) with the same weaveSeq (%llu)\n", tmpPtr->blockNo, Vbn, weaveSeq); + } + if (tmpPtr->weaveSeq <= weaveSeq) + { + /* add new node in front of current one */ + + nextBlock->next = tmpPtr; + nextBlock->prev = tmpPtr->prev; + if (tmpPtr->prev != NULL) + { + tmpPtr->prev->next = nextBlock; + } + tmpPtr->prev = nextBlock; + } + else + { + /* add new node as a last node in the list */ + nextBlock->prev = tmpPtr; + nextBlock->next = NULL; + tmpPtr->next = nextBlock; + } + } + if (listHead->prev == NULL) + { + return listHead; + } + else + { + return nextBlock; + } +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* restoreIndexBlock */ +/* DESCRIPTION */ +/* This function is used in restore */ +/* */ +/*****************************************************************************/ +static ANDStatus restoreIndexBlock(UInt16 blockNo, UInt8 isCurrent, WeaveSeq_t listWeaveSequence ) +{ + UInt32 Vpn = blockNo * PAGES_PER_SUBLK, *pageBuffer = yaFTL.tmpReadBuffer, i; + ANDStatus status; + PageMeta_t *mdPtr = yaFTL.meta_restoreIdx; + BOOL32 stillClean = TRUE32; + UInt32 *bTOC = yaFTL.restoreTOC; + UInt32 upperBound; + + if(BTOC_GET_IPN(1) == 1) + { + upperBound = yaFTL.TOCtableEntriesNo; + } + else + { + upperBound = yaFTL.logicalPartitionSize; + } + + status = _readPage(Vpn, ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if (!META_IS_IDX(mdPtr) && (status == FTL_SUCCESS)) { +#ifndef AND_READONLY + WMR_PANIC("yaFTL restoreIndexBlock on a non-index block %d...\n", blockNo); +#else + WMR_PRINT(ERROR, "yaFTL restoreIndexBlock on a non-index block %d... trying anyway...\n", blockNo); +#endif + // Give it a shot anyway in read-only versions... + return FTL_SUCCESS; + } + + status = BTOC_Read(Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo), bTOC, mdPtr, FALSE32, FALSE32, upperBound); + + if ((status != FTL_SUCCESS)) + { + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + if (status != FIL_SUCCESS_CLEAN) + stillClean = FALSE32; + debug(INIT, "cannot read page properly"); + } + if (isCurrent) + { + yaFTL.wrState.index.block = blockNo; + yaFTL.blockArray[blockNo].status = BLOCK_I_CURRENT; + } + else + { + yaFTL.blockArray[blockNo].status = BLOCK_I_ALLOCATED; + } + if (META_IS_BTOC_IDX(mdPtr) && (status == FTL_SUCCESS)) + { + /* block was fully used and it contains valid TOC page */ + for (i = 0; (Int32)i < (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; i++) + { + if ((BTOC_Get(bTOC, (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), upperBound) != 0xffffffff) && (yaFTL.tocArray[BTOC_GET_IPN(BTOC_Get(bTOC, (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), upperBound))].indexPage == 0xffffffff)) + { + yaFTL.tocArray[BTOC_GET_IPN(BTOC_Get(bTOC, (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), upperBound))].indexPage = Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1); + yaFTL.blockArray[blockNo].validPagesINo++; + yaFTL.seaState.index.validPages++; + } + } + if (isCurrent) + { + yaFTL.wrState.index.nextPage = PAGES_PER_SUBLK; /* offset in current block of next free page */ + BTOC_Copy(yaFTL.wrState.index.TOC, bTOC, upperBound); + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } + } + } + else + { + /* probably current block . perform full body scan */ + if (isCurrent) + { + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + yaFTL.wrState.index.nextPage = PAGES_PER_SUBLK - yaFTL.controlPageNo; + } + else + { + yaFTL.wrState.index.nextPage = PAGES_PER_SUBLK; + } + } + for (i = 0; (Int32)i < (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; i++) + { + status = _readPage(Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if (((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) || ((status == FTL_SUCCESS) && ((!META_IS_IDX(mdPtr)) || (META_GET_IPN(mdPtr) >= yaFTL.TOCtableEntriesNo)))) + { + // vadim : just skip the page + debug(INIT, "failure during index scan at 0x%x", Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1)); + stillClean = FALSE32; + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + continue; + } + + if (status == FIL_SUCCESS_CLEAN) + { + if ((isCurrent) && (stillClean)) + { + yaFTL.wrState.index.nextPage = (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1); + } + continue; + } + if(status != FTL_SUCCESS) + { +#ifndef AND_READONLY + WMR_PANIC("no invalid pages beyong this point"); +#else + WMR_PRINT(ERROR,"no invalid pages beyong this point\n"); +#endif + continue; + } + + stillClean = FALSE32; + if (isCurrent) + { + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1], mdPtr); + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } + } + if (yaFTL.tocArray[META_GET_IPN(mdPtr)].indexPage == 0xffffffff) + { + yaFTL.tocArray[META_GET_IPN(mdPtr)].indexPage = Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1); + yaFTL.blockArray[blockNo].validPagesINo++; + yaFTL.seaState.index.validPages++; + } + } + } + if (isCurrent) + { + debug(INIT, "wrState.index.nextPage 0x%x -- %d blockNo 0x%x is current", yaFTL.wrState.index.nextPage, yaFTL.wrState.index.nextPage, blockNo); + } + + return FTL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* restoreBlock */ +/* DESCRIPTION */ +/* This function is used in restore */ +/* */ +/*****************************************************************************/ +static ANDStatus restoreBlock(UInt16 blockNo, UInt32 *indexTable, UInt8 isCurrent, UInt32 rangeOffset, UInt32 rangeSize, BlockRangeType *brPtr, WeaveSeq_t listWeaveSequence) +{ + UInt32 Vpn = blockNo * PAGES_PER_SUBLK, *pageBuffer = yaFTL.tmpReadBuffer, i, lastPageToCheck; + ANDStatus status = FTL_SUCCESS; + PageMeta_t *mdPtr = yaFTL.meta_restoreData; + BOOL32 stillClean = TRUE32; + UInt32 *bTOC = yaFTL.restoreTOC; + + if ((rangeOffset) && (brPtr != NULL)) + { + if ((brPtr[blockNo].end < rangeOffset) || (brPtr[blockNo].start >= (rangeOffset + rangeSize))) + { + return FTL_SUCCESS; + } + } + + if (yaFTL.blockArray[blockNo].validPagesINo == (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + return FTL_SUCCESS; + } + + if ((rangeOffset > 0) && (isCurrent)) + { + WMR_MEMSET(&yaFTL.wrState.data.TOC[yaFTL.wrState.data.nextPage], 0xff, (PAGES_PER_SUBLK - yaFTL.wrState.data.nextPage) * sizeof(UInt32)); + BTOC_Copy(bTOC, yaFTL.wrState.data.TOC, yaFTL.logicalPartitionSize); + META_SET_BTOC_DATA(mdPtr); + } + else + { + status = BTOC_Read(Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo), bTOC, mdPtr, FALSE32, FALSE32, yaFTL.logicalPartitionSize); + if ((status != FTL_SUCCESS)) + { + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + if (status != FIL_SUCCESS_CLEAN) + stillClean = FALSE32; + debug(INIT, "cannot read block TOC during scan"); + //return status; + } + } + if (rangeOffset == 0) + { + if (isCurrent) + { + yaFTL.wrState.data.block = blockNo; + yaFTL.blockArray[blockNo].status = BLOCK_CURRENT; + } + else + { + yaFTL.blockArray[blockNo].status = BLOCK_ALLOCATED; + } + } + + if ((META_IS_BTOC_DATA(mdPtr)) && (status == FTL_SUCCESS)) + { + /* block was fully used and it contains valid TOC page */ + long length; + if ((rangeOffset > 0) && (isCurrent)) + { + length = yaFTL.wrState.data.nextPage; + } + else + { + length = (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; + } + + for (i = 0; (Int32)i < (Int32)length; i++) + { + // check the range before executing restore + if ((!rangeOffset) && (brPtr != NULL)) + { + if ((brPtr[blockNo].end == brPtr[blockNo].start) && (brPtr[blockNo].start == 0xffffffff)) + { + brPtr[blockNo].end = brPtr[blockNo].start = BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize); + } + else + { + if (brPtr[blockNo].end < BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize)) + { + brPtr[blockNo].end = BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize); + } + + if (brPtr[blockNo].start > BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize)) + { + brPtr[blockNo].start = BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize); + } + } + } + + if ((BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) < rangeOffset) || + (BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) >= (rangeOffset + rangeSize))) + { + continue; + } + yaFTL.blockArray[blockNo].validPagesINo++; + if ((BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) != 0xffffffff) && (indexTable[BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) - rangeOffset] == 0xffffffff)) + { + indexTable[BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) - rangeOffset] = Vpn + (length - (i + 1)); + yaFTL.blockArray[blockNo].validPagesDNo++; + yaFTL.seaState.data.validPages++; + } + } + if ((isCurrent) && (!rangeOffset)) + { + yaFTL.wrState.data.nextPage = PAGES_PER_SUBLK; /* offset in current block of next free page */ + BTOC_Copy(yaFTL.wrState.data.TOC, bTOC, yaFTL.logicalPartitionSize); +#ifndef AND_READONLY + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } +#endif + } + } + else + { + /* probably current block . perform full body scan */ + lastPageToCheck = PAGES_PER_SUBLK - yaFTL.controlPageNo; + if (isCurrent) + { + if (status == FTL_SUCCESS) + { + yaFTL.wrState.data.nextPage = PAGES_PER_SUBLK - yaFTL.controlPageNo; + } + else + { + yaFTL.wrState.data.nextPage = PAGES_PER_SUBLK; + } + yaFTL.blockArray[blockNo].validPagesINo = PAGES_PER_SUBLK - yaFTL.controlPageNo; + for (i = 0; (Int32)i < (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; i++) + { + status = _readPage(Vpn + i, ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || (!META_IS_DATA(mdPtr)) || (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)) + { + lastPageToCheck = i; + yaFTL.wrState.data.nextPage = i; + break; + } + else + { + yaFTL.blockArray[blockNo].validPagesINo--; + } + + } + } + + + for (i = 0; (Int32)i < (Int32)lastPageToCheck; i++) + { + status = _readPage(Vpn + (lastPageToCheck - i - 1), ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if (((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) || ((status == FTL_SUCCESS) && ((!META_IS_DATA(mdPtr)) || (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)))) + { + // vadim + // just ignore page and continue ( power failure during update + if (!rangeOffset) + { + yaFTL.blockArray[blockNo].validPagesINo++; + } + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + stillClean = FALSE32; + continue; + //return status; + } + + if ((status == FIL_SUCCESS_CLEAN) && (!rangeOffset)) + { + yaFTL.blockArray[blockNo].validPagesINo++; + } + + if ((isCurrent) && (status == FIL_SUCCESS_CLEAN) && (stillClean)) + { + yaFTL.wrState.data.nextPage = (UInt16)(lastPageToCheck - i - 1); + continue; + } + if (status == FIL_SUCCESS_CLEAN) + continue; + if(status != FTL_SUCCESS) + { +#ifndef AND_READONLY + WMR_PANIC("no invalid pages beyong this point"); +#else + WMR_PRINT(ERROR,"no invalid pages beyong this point\n"); +#endif + continue; + } + + stillClean = FALSE32; + if ((brPtr != NULL) && (!rangeOffset) && (META_GET_LBA(mdPtr) < yaFTL.logicalPartitionSize)) + { + if ((brPtr[blockNo].end == brPtr[blockNo].start) && (brPtr[blockNo].start == 0xffffffff)) + { + brPtr[blockNo].end = brPtr[blockNo].start = META_GET_LBA(mdPtr); + } + else + { + if (brPtr[blockNo].end < META_GET_LBA(mdPtr)) + { + brPtr[blockNo].end = META_GET_LBA(mdPtr); + } + + if (brPtr[blockNo].start > META_GET_LBA(mdPtr)) + { + brPtr[blockNo].start = META_GET_LBA(mdPtr); + } + } + } + + if (isCurrent) + { + yaFTL.wrState.data.TOC[lastPageToCheck - i - 1] = META_GET_LBA(mdPtr); +#ifndef AND_READONLY + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } +#endif // ! AND_READONLY + } + if ((META_GET_LBA(mdPtr) < rangeOffset) || + (META_GET_LBA(mdPtr) >= (rangeOffset + rangeSize))) + { + continue; + } + // this to count all pages we already scanned . Once this number reaches blockszie we can ignore block in all subsequent iterations + yaFTL.blockArray[blockNo].validPagesINo++; + + if (indexTable[META_GET_LBA(mdPtr) - rangeOffset] == 0xffffffff) + { + indexTable[META_GET_LBA(mdPtr) - rangeOffset] = Vpn + (lastPageToCheck - i - 1); + yaFTL.blockArray[blockNo].validPagesDNo++; + yaFTL.seaState.data.validPages++; + } + } + } + + return FTL_SUCCESS; +} + +static ANDStatus readCXTInfo(UInt32 vpn, UInt8 *tBuff, UInt8 qm_valid, BOOL32 *formatSupported) +{ + UInt32 i = 0, size, k, j; + ANDStatus status; + PageMeta_t *md = yaFTL.meta_readCxt; + UInt8 *statPtr = NULL; + UInt16 *validPtr = NULL; + UInt32 *tocPtr = NULL; + struct YAFTLControlInfo *yaftlCI; + UInt32 tmpIndexSize = 0; + + debug(INIT, "readCXTInfo from offset 0x%x", vpn); + + status = _readPage(vpn, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { + return FTL_CRITICAL_ERROR; + } + yaftlCI = (struct YAFTLControlInfo *)tBuff; + if (WMR_MEMCMP(&(yaftlCI->versionNo), CXT_VER, 4) != 0) + + { + if (formatSupported != NULL) + { + *formatSupported = FALSE32; + } + debug(ERROR, "wrong version of CXT %s expected %s", (UInt8 *)(&yaftlCI->versionNo), CXT_VER); + + return FTL_CRITICAL_ERROR; + } +#ifndef AND_READONLY + if(sizeof(WeaveSeq_t) <= 4) + { + if (META_GET_WEAVESEQ(md) != 0xffffffff) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } + else + { + if (META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } +#endif + if( yaFTL.indexSize == 4) + tmpIndexSize = 3; + else + tmpIndexSize = yaFTL.indexSize; + + if (!((yaFTL.logicalPartitionSize == yaftlCI->logicalPartitionSize) && + (tmpIndexSize == yaftlCI->indexSize) && (yaFTL.controlPageNo == yaftlCI->controlPageNo) && + (yaFTL.indexPageRatio == yaftlCI->indexPageRatio) && (yaFTL.TOCtableEntriesNo == yaftlCI->TOCtableEntriesNo) && + (yaFTL.exportedRatio == yaftlCI->exportedRatio))) + { + debug(INIT, "CXT control info mismatch . Getting out"); + return FTL_CRITICAL_ERROR; + } + + if (qm_valid) + { + debug(INIT, "readCXTInfo from offset 0x%x", vpn); + yaFTL.freeCachePages = yaftlCI->freeCachePages; + yaFTL.wrState.data.block = yaftlCI->wrState_data_block; + yaFTL.wrState.data.nextPage = yaftlCI->wrState_data_nextPage; + yaFTL.seaState.data.freeBlocks = yaftlCI->seaState_data_freeBlocks; + yaFTL.wrState.index.block = yaftlCI->wrState_index_block; +#if NAND_PPN + yaFTL.wrState.weaveSeq = (WeaveSeq_t)yaftlCI->wrState_index_weaveSeq_Lo | ((WeaveSeq_t)yaftlCI->wrState_index_weaveSeq_Hi << 32UL); +#elif NAND_RAW + yaFTL.wrState.weaveSeq = yaftlCI->wrState_index_weaveSeq; +#else +#error PPN or raw? +#endif + yaFTL.wrState.index.nextPage = yaftlCI->wrState_index_nextPage; + yaFTL.seaState.index.freeBlocks = yaftlCI->seaState_index_freeBlocks; + yaFTL.seaState.data.allocdBlocks = yaftlCI->seaState_data_allocdBlocks; + yaFTL.seaState.index.allocdBlocks = yaftlCI->seaState_index_allocdBlocks; +#ifndef AND_READONLY + yaFTL.nextFreeCachePage = yaftlCI->nextFreeCachePage; +#if NAND_PPN + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, (WeaveSeq_t)yaftlCI->wrState_data_weaveSeq_Lo | ((WeaveSeq_t)yaftlCI->wrState_data_weaveSeq_Hi << 32UL)); +#elif NAND_RAW + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, yaftlCI->wrState_data_weaveSeq); +#else +#error PPN or raw? +#endif + yaFTL.cxtEraseCounter = yaftlCI->cxtEraseCounter; + yaFTL.FTLRestoreCnt = yaftlCI->FTLRestoreCnt; +#endif + yaFTL.indexCacheSize = yaftlCI->indexCacheSize; + yaFTL.exportedRatio = yaftlCI->exportedRatio; + + debug(INIT, "readCXTInfo logicalPartitionSize %d TOCtableEntriesNo %d \nwrState.data.block %d wrState.data.nextPage %d \n BYTES_PER_PAGE %d \n wrState.index.block %d wrState.index.nextPage %d wrState.weaveSeq %d" + , yaFTL.logicalPartitionSize, yaFTL.TOCtableEntriesNo, yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, BYTES_PER_PAGE, yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, yaFTL.wrState.weaveSeq); + debug(INIT, "readCXTInfo cxtSizeTOC %d cxtSizeBlockStatus %d \ncxtSizeBlockRead %d cxtSizeBlockErase %d\n cxtSizeValidPagesI %d cxtSizeValidPagesD %d ", + yaFTL.cxtSizeTOC, yaFTL.cxtSizeBlockStatus, yaFTL.cxtSizeBlockRead, yaFTL.cxtSizeBlockErase, yaFTL.cxtSizeValidPagesI, yaFTL.cxtSizeValidPagesD); + } + vpn++; + + if (qm_valid) + { + UInt8 i; + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _readPage(vpn + i, ( UInt8 *)((UInt8 *)yaFTL.wrState.data.TOC + (BYTES_PER_PAGE * i)), md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || (!META_IS_CXT(md))) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + } + } + vpn += yaFTL.controlPageNo; + if (qm_valid) + { + UInt8 i; + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _readPage(vpn + i, ( UInt8 *)((UInt8 *)yaFTL.wrState.index.TOC + (BYTES_PER_PAGE * i)), md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + } + } + vpn += yaFTL.controlPageNo; + +#ifdef AND_COLLECT_STATISTICS + /* set statistics */ + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + _FTLSetStatisticsFromCxt(tBuff); +#endif + vpn++; + + if (qm_valid) + { + size = yaFTL.TOCtableEntriesNo; + for (i = 0, j = 0; i < yaFTL.cxtSizeTOC; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + yaFTL.tocArray[j + k].indexPage = tocPtr[k]; + } + } + } + debug(INIT, " readCXTInfo after TOC table i = %d", i); + vpn += yaFTL.cxtSizeTOC; + if (qm_valid) + { + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockStatus; i++, size -= BYTES_PER_PAGE / sizeof(UInt8), j += BYTES_PER_PAGE / sizeof(UInt8)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + statPtr = (UInt8 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt8)) && (k < size); k++) + { + yaFTL.blockArray[j + k].status = statPtr[k]; + } + } + } + debug(INIT, "readCXTInfo after blockstatus i = %d", i); + vpn += yaFTL.cxtSizeBlockStatus; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockRead; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + yaFTL.blockArray[j + k].pagesRead = validPtr[k]; + } + } + debug(INIT, "readCXTInfo after blockread i = %d", i); + vpn += yaFTL.cxtSizeBlockRead; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockErase; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + yaFTL.blockArray[j + k].erasableCount = tocPtr[k]; + } + } + debug(INIT, "readCXTInfo after blockerase i = %d", i); + vpn += yaFTL.cxtSizeBlockErase; + + if (qm_valid) + { + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesI; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + yaFTL.blockArray[j + k].validPagesINo = validPtr[k]; + yaFTL.seaState.index.validPages += yaFTL.blockArray[j + k].validPagesINo; + } + } + } + debug(INIT, "readCXTInfo after validpagesI i = %d", i); + vpn += yaFTL.cxtSizeValidPagesI; + + if (qm_valid) + { + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesD; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + yaFTL.blockArray[j + k].validPagesDNo = validPtr[k]; + yaFTL.seaState.data.validPages += yaFTL.blockArray[j + k].validPagesDNo; + } + } + } + debug(INIT, "readCXTInfo after validPagesD i = %d", i); +#ifdef AND_COLLECT_STATISTICS + if (qm_valid) + { + stFTLStatistics.ddwValidIndexPages = yaFTL.seaState.index.validPages; + stFTLStatistics.ddwValidDataPages = yaFTL.seaState.data.validPages; + } +#endif + + return FTL_SUCCESS; +} + +static ANDStatus quickRestore(UInt16 *cxtT, BOOL32 * formatSupported) +{ + UInt16 i; + ANDStatus status; + PageMeta_t *md = yaFTL.meta_quickRestore; + WeaveSeq_t lastCX = 0; + UInt32 currentCX = 0; + + /* + Read first page out of each Cxt unit to establish which contains a latest valid ( hopefully ) + copy of a quick mount info . Then read last copy and establish its validity . If it's valid read out the whole + thing and return success . If it's not valid use erase/read count info and return failure which would trigger full restore + */ + + if (yaFTL.quickRestore_tBuff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.blockArray[cxtT[i]].status = BLOCK_CTX_CNTR; + } + + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + status = _readPage(cxtT[i] * PAGES_PER_SUBLK, yaFTL.quickRestore_tBuff, md, FALSE32, TRUE32, FALSE32); + if (status != FTL_SUCCESS) + { +#ifndef AND_READONLY + if (status != FIL_SUCCESS_CLEAN) + { + VFL_Erase(cxtT[i], TRUE32); + yaFTL.blockArray[cxtT[i]].erasableCount++; + removeBlockFromEraseNowList(cxtT[i]); + } +#endif + continue; + } + + if(sizeof(WeaveSeq_t) <= 4) + { + if ((META_GET_WEAVESEQ(md) != 0xffffffff) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; +#ifndef AND_READONLY + yaFTL.currentCXTIndex = i; +#endif // ! AND_READONLY + } + } + else + { + if ((META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; +#ifndef AND_READONLY + yaFTL.currentCXTIndex = i; +#endif // ! AND_READONLY + } + } + } + if (lastCX != 0) + { + yaFTL.blockArray[currentCX].status = BLOCK_CTX_CURRENT; + debug(INIT, "currentCX is %d", currentCX); + } + else + { + /* no quick mount info */ + yaFTL.blockArray[cxtT[0]].status = BLOCK_CTX_CURRENT; +#ifndef AND_READONLY + yaFTL.currentCXTIndex = 0; +#endif // ! AND_READONLY + return 5; + } + + /* check validity */ + for (i = 0; (i + (UInt16)yaFTL.cxtSize) < PAGES_PER_SUBLK; i += (UInt16)(yaFTL.cxtSize + 1)) + { +#ifndef AND_READONLY + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); +#endif + status = _readPage((currentCX * PAGES_PER_SUBLK) + i, yaFTL.quickRestore_tBuff, md, FALSE32, TRUE32, FALSE32); // read first page of a potential cxt + if (status != FIL_SUCCESS) + { + // previous copy was the last one . no valid cxt avaiable + // we still read blockerase and blockread counts and then let full restore to kick in + break; + } + + status = _readPage((currentCX * PAGES_PER_SUBLK) + i + yaFTL.cxtSize, yaFTL.quickRestore_tBuff, md, FALSE32, TRUE32, FALSE32); + if (status == FIL_SUCCESS_CLEAN) + { + yaFTL.currentCxtVpn = currentCX * PAGES_PER_SUBLK + i; + + if (readCXTInfo(currentCX * PAGES_PER_SUBLK + i, yaFTL.quickRestore_tBuff, 1, formatSupported) == FTL_SUCCESS) + { + debug(INIT, "quickRestore : seaState.index.validPages = %d seaState.data.validPages = %d", yaFTL.seaState.index.validPages, yaFTL.seaState.data.validPages); +#ifndef AND_READONLY + yaFTL.cxtValid = 1; +#endif // ! AND_READONLY + return FTL_SUCCESS; + } + else + { + debug(INIT, "quickRestore : something is not quite right with it . going for a full one"); +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif // ! AND_READONLY + return 5; // TODO: find a cleaner way to mark a failure + } + } + } + // previous copy was the last one . no valid cxt avaiable + // we still read blockerase and blockread counts and then let full restore to kick in + yaFTL.currentCxtVpn = currentCX * PAGES_PER_SUBLK + i - (yaFTL.cxtSize + 1); // back off to the last invalid copy of cxt +#ifndef AND_READONLY + if(sizeof(WeaveSeq_t) <= 4) + { + if (META_GET_WEAVESEQ(md) != 0xffffffff) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } + else + { + if (META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } + yaFTL.cxtValid = 0; +#endif // ! AND_READONLY + + debug(INIT, "cannot find valid copy of cxt ... reading only relevant info from %d", yaFTL.currentCxtVpn); + readCXTInfo(yaFTL.currentCxtVpn, yaFTL.quickRestore_tBuff, 0, formatSupported); //only need to read out erase and read counters + return 5; +} + +#ifndef AND_READONLY +ANDStatus invalidateCXT(void) +{ + PageMeta_t *mdPtr = yaFTL.meta_invalidateCxt; + ANDStatus status; + Buffer buff; + + buff.pData = (UInt8 *)yaFTL.wrState.index.TOC; + buff.pSpare = (UInt8 *)mdPtr; + + SetupMeta_Cxt(mdPtr, yaFTL.cxtAllocation); + status = VFL_Write(yaFTL.currentCxtVpn + yaFTL.cxtSize, &buff, TRUE32, FALSE32); + if (status != VFL_SUCCESS) + // erase current cxt + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + //return status; + } + + return FTL_SUCCESS; +} +#endif + +#ifndef AND_READONLY +ANDStatus writeCXTInfo(UInt32 vpn, UInt8* tBuff, BOOL32 statsOnly) +{ + UInt32 i, size, k, j; + PageMeta_t *md = yaFTL.meta_writeCxt; + UInt8 *statPtr = NULL; + UInt16 * validPtr = NULL; + UInt32 *tocPtr = NULL; + UInt32 tempVpn = vpn; + ANDStatus status; + struct YAFTLControlInfo *yaftlCI = (struct YAFTLControlInfo *)tBuff; + + if (yaFTL.cxtValid == 1) + { + return FTL_SUCCESS; + } + + yaFTL.cxtAllocation++; + SetupMeta_Cxt(md, yaFTL.cxtAllocation); + + /* Read yaftl control info first also currentDTOC and currentITOC = 3 pages*/ + WMR_MEMCPY(yaftlCI, CXT_VER, 4); // update cxt version info + yaftlCI->controlPageNo = yaFTL.controlPageNo; + yaftlCI->indexPageRatio = yaFTL.indexPageRatio; + if( yaFTL.indexSize == 4) + yaftlCI->indexSize = 3; + else + yaftlCI->indexSize = yaFTL.indexSize; + yaftlCI->logicalPartitionSize = yaFTL.logicalPartitionSize; + yaftlCI->TOCtableEntriesNo = yaFTL.TOCtableEntriesNo; + yaftlCI->freeCachePages = yaFTL.freeCachePages; + yaftlCI->nextFreeCachePage = yaFTL.nextFreeCachePage; + yaftlCI->wrState_data_block = yaFTL.wrState.data.block; +#if NAND_PPN + yaftlCI->wrState_data_weaveSeq_Lo = (UInt32)yaFTL.wrState.weaveSeq & 0xFFFFFFFFUL; + yaftlCI->wrState_data_weaveSeq_Hi = (UInt32)(yaFTL.wrState.weaveSeq >> 32ul) & 0xFFFFFFFFUL; +#elif NAND_RAW + yaftlCI->wrState_data_weaveSeq = (WeaveSeq_t)yaFTL.wrState.weaveSeq; +#else +#error PPN or raw? +#endif + + yaftlCI->wrState_data_nextPage = yaFTL.wrState.data.nextPage; + yaftlCI->seaState_data_freeBlocks = yaFTL.seaState.data.freeBlocks; + yaftlCI->wrState_index_block = yaFTL.wrState.index.block; +#if NAND_PPN + yaftlCI->wrState_index_weaveSeq_Lo = (UInt32)yaFTL.wrState.weaveSeq & 0xFFFFFFFFUL; + yaftlCI->wrState_index_weaveSeq_Hi = (UInt32)(yaFTL.wrState.weaveSeq >> 32UL) & 0xFFFFFFFFUL; +#elif NAND_RAW + yaftlCI->wrState_index_weaveSeq = (WeaveSeq_t)yaFTL.wrState.weaveSeq; +#else +#error PPN or raw? +#endif + yaftlCI->wrState_index_nextPage = yaFTL.wrState.index.nextPage; + yaftlCI->seaState_index_freeBlocks = yaFTL.seaState.index.freeBlocks; + yaftlCI->seaState_data_allocdBlocks = yaFTL.seaState.data.allocdBlocks; + yaftlCI->seaState_index_allocdBlocks = yaFTL.seaState.index.allocdBlocks; + yaftlCI->indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; // use default size for backward compatibility + yaftlCI->exportedRatio = yaFTL.exportedRatio; + yaftlCI->cxtEraseCounter = yaFTL.cxtEraseCounter; + yaftlCI->FTLRestoreCnt = yaFTL.FTLRestoreCnt; + /* yaftl control info */ + + status = _writePage(vpn, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + vpn++; + + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _writePage(vpn + i, (UInt8 *)((UInt8 *)yaFTL.wrState.data.TOC + BYTES_PER_PAGE * i), md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + vpn += yaFTL.controlPageNo; + + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _writePage(vpn + i, (UInt8 *)((UInt8 *)yaFTL.wrState.index.TOC + BYTES_PER_PAGE * i), md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + vpn += yaFTL.controlPageNo; + + /* Write statistics */ +#ifdef AND_COLLECT_STATISTICS + _FTLGetStatisticsToCxt(tBuff); + +#else + WMR_MEMSET(tBuff, 0, BYTES_PER_PAGE); +#endif + status = _writePage(vpn, (UInt8 *)tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + vpn++; + + size = yaFTL.TOCtableEntriesNo; + + if(statsOnly == TRUE32) + WMR_MEMSET(md, 0, sizeof(PageMeta_t)); + + for (i = 0, j = 0; i < yaFTL.cxtSizeTOC; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + tocPtr[k] = yaFTL.tocArray[j + k].indexPage; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeTOC; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockStatus; i++, size -= BYTES_PER_PAGE / sizeof(UInt8), j += BYTES_PER_PAGE / sizeof(UInt8)) + { + statPtr = (UInt8 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt8)) && (k < size); k++) + { + statPtr[k] = yaFTL.blockArray[j + k].status; + + // Fixup state so running GC operations don't break on-media format: + if (BLOCK_GC == statPtr[k]) + { + statPtr[k] = BLOCK_ALLOCATED; + } + else if (BLOCK_I_GC == statPtr[k]) + { + statPtr[k] = BLOCK_I_ALLOCATED; + } + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeBlockStatus; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockRead; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + validPtr[k] = yaFTL.blockArray[j + k].pagesRead; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeBlockRead; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockErase; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + tocPtr[k] = yaFTL.blockArray[j + k].erasableCount; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeBlockErase; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesI; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + validPtr[k] = yaFTL.blockArray[j + k].validPagesINo; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeValidPagesI; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesD; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + validPtr[k] = yaFTL.blockArray[j + k].validPagesDNo; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + yaFTL.currentCxtVpn = tempVpn; + yaFTL.cxtValid = 1; + + return status; +} + +#endif + +#ifndef AND_READONLY +static void moveCXTarea(void) +{ + UInt32 i = 0, j; + UInt16 tempCXT[FTL_CXT_SECTION_SIZE]; + ANDStatus status; + + if (yaFTL.seaState.data.freeBlocks < FTL_CXT_SECTION_SIZE) + { + return; + } + + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + + for (j = 0; j < FTL_CXT_SECTION_SIZE; j++) + { + tempCXT[j] = yaFTL.cxtTable[j]; + } + + for (j = 0; (Int32)j < FTL_AREA_SIZE; j++) + { + if ((yaFTL.blockArray[j].status == BLOCK_FREE) && ( (yaFTL.blockArray[j].erasableCount + CXT_ERASE_GAP) < yaFTL.blockArray[tempCXT[i]].erasableCount)) + { + if( yaFTL.blockArray[j].eraseBeforeUse != 0) + { + status = VFL_Erase(j, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) j, status); + continue; + } + yaFTL.blockArray[j].eraseBeforeUse = 0; + removeBlockFromEraseNowList((UInt16)j); + yaFTL.erasedBlockCount++; + } + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + yaFTL.erasedBlockCount--; + yaFTL.cxtTable[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + + if ( i == 0 ) + return; + + VFL_ChangeFTLCxtVbn(yaFTL.cxtTable); + yaFTL.currentCXTIndex = 0; + yaFTL.currentCxtVpn = 0xffffffff; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + for (j = 0; j < FTL_CXT_SECTION_SIZE; j++) + { + VFL_Erase((UInt16)tempCXT[j], TRUE32); + removeBlockFromEraseNowList((UInt16)tempCXT[j]); + yaFTL.blockArray[tempCXT[j]].status = BLOCK_FREE; + yaFTL.blockArray[tempCXT[j]].erasableCount++; + yaFTL.blockArray[tempCXT[j]].pagesRead = 0; + yaFTL.blockArray[tempCXT[j]].pagesReadSubCounter = 0; + yaFTL.blockArray[tempCXT[j]].validPagesDNo = yaFTL.blockArray[tempCXT[j]].validPagesINo = 0; + yaFTL.blockArray[tempCXT[j]].eraseBeforeUse = 0; + if (j < i) + yaFTL.erasedBlockCount++; + // Update max erase count + if (yaFTL.blockArray[tempCXT[j]].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[tempCXT[j]].erasableCount; + } + } + for(j = i; j < FTL_CXT_SECTION_SIZE; j++) + yaFTL.blockArray[yaFTL.cxtTable[j]].status = BLOCK_CTX_CNTR; +} + +ANDStatus quickMountUpdate(BOOL32 statsOnly) +{ + UInt8 *tBuff = NULL; + Buffer *tmpB = NULL; + ANDStatus status = FTL_SUCCESS; + UInt32 i; + /* + * Read first page out of each Cxt unit to establish which contains a latest valid ( hopefully ) + * copy of a quick mount info . Then read last copy and establish its validity . If it's valid read out the whole + * thing and return success . If it's not valid use erase/read count info and return failure which would trigger full restore + */ + if (yaFTL.cxtValid == 1) // no need to update valid cxt + { + return FTL_SUCCESS; + } + + WMR_TRACE_IST_1(CxtSave, START, statsOnly); + + for (i = 0; ((Int32)i < FTL_AREA_SIZE) && (statsOnly == FALSE32); i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + if(yaFTL.formatWasCalled == 0) + { + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + yaFTL.blockArray[i].erasableCount++; + yaFTL.periodicCxt.erases++; + yaFTL.erasedBlockCount++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + removeBlockFromEraseNowList(i); + } + yaFTL.blockArray[i].eraseBeforeUse = 0; + } + } + + yaFTL.formatWasCalled = 0; + + tmpB = BUF_Get(BUF_MAIN_ONLY); + if (tmpB == NULL) + { + WMR_TRACE_IST_1(CxtSave, END, FTL_CRITICAL_ERROR); + return FTL_CRITICAL_ERROR; + } + + tBuff = (UInt8 *)tmpB->pData; + + if (yaFTL.currentCxtVpn == 0xffffffff) + { + /* First time update */ + status = writeCXTInfo(yaFTL.cxtTable[yaFTL.currentCXTIndex] * PAGES_PER_SUBLK, tBuff, statsOnly); + if (status != VFL_SUCCESS) + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + } + else + { + /* check whether we can add cxt to a current cxt block */ + if (((yaFTL.currentCxtVpn / PAGES_PER_SUBLK) == ((yaFTL.currentCxtVpn + 1 + yaFTL.cxtSize) / PAGES_PER_SUBLK)) && + (((yaFTL.currentCxtVpn + 1 + yaFTL.cxtSize) / PAGES_PER_SUBLK) == ((yaFTL.currentCxtVpn + (1 + yaFTL.cxtSize) * 2) / PAGES_PER_SUBLK))) + { + status = writeCXTInfo(yaFTL.currentCxtVpn + 1 + yaFTL.cxtSize, tBuff, statsOnly); + if (status != VFL_SUCCESS) + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + } + else + { + /* not enough space in current cxt block . erase the oldest and update in it */ + + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + status = writeCXTInfo(yaFTL.cxtTable[yaFTL.currentCXTIndex] * PAGES_PER_SUBLK, tBuff, statsOnly); + if (status != VFL_SUCCESS) + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + } + } + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +#endif // 0 : still working on the above code +/*****************************************************************************/ +/* */ +/* NAME */ +/* restoreMount */ +/* DESCRIPTION */ +/* Perfroms restore mount in case control info is dirty */ +/* */ +/*****************************************************************************/ + +UInt16 findFreeCacheEntry(void); + +static void SetupFreeAndAllocd(void) +{ + UInt32 i; + + yaFTL.seaState.data.freeBlocks = 0; + yaFTL.seaState.data.allocdBlocks = 0; + yaFTL.seaState.index.freeBlocks = 0; + yaFTL.seaState.index.allocdBlocks = 0; + yaFTL.seaState.freeBlocks = 0; + + for (i = 0; i < FTL_AREA_SIZE; i++) { + switch (yaFTL.blockArray[i].status) { + case BLOCK_ALLOCATED: + case BLOCK_CURRENT: + yaFTL.seaState.data.allocdBlocks++; + break; + + case BLOCK_I_ALLOCATED: + case BLOCK_I_CURRENT: + yaFTL.seaState.index.allocdBlocks++; + break; + + case BLOCK_FREE: + yaFTL.seaState.freeBlocks++; + break; + + case BLOCK_CTX_CNTR: + case BLOCK_CTX_CURRENT: + break; + + default: +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Unknown block type: 0x%x\n", yaFTL.blockArray[i].status); +#else + WMR_PRINT(QUAL_FATAL, "Unknown block type: 0x%x\n", yaFTL.blockArray[i].status); +#endif + } + } + + if (yaFTL.seaState.freeBlocks < 2) + { +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("no free blocks %d ", yaFTL.seaState.freeBlocks); +#else + WMR_PRINT(QUAL_FATAL, "no free blocks %d ", yaFTL.seaState.freeBlocks); +#endif + } + + yaFTL.seaState.index.freeBlocks = yaFTL.indexSize - yaFTL.seaState.index.allocdBlocks; + if (yaFTL.seaState.freeBlocks > (UInt32)yaFTL.seaState.index.freeBlocks) + { + yaFTL.seaState.data.freeBlocks = yaFTL.seaState.freeBlocks - yaFTL.seaState.index.freeBlocks; + } + else + { + if (yaFTL.seaState.freeBlocks == 1) + { + yaFTL.seaState.index.freeBlocks = 0; + yaFTL.seaState.data.freeBlocks = 1; + } + else + { + yaFTL.seaState.index.freeBlocks = 1; + yaFTL.seaState.data.freeBlocks = yaFTL.seaState.freeBlocks - yaFTL.seaState.index.freeBlocks; + } + } +} + + +#ifndef AND_READONLY +static ANDStatus restoreMountEraseIndex(UInt16 * ctxT) +{ + UInt32 Vpn; + ANDStatus status = FTL_SUCCESS; + UInt32 *pageBuffer = NULL; + UInt32 i, n; + Buffer * pBuff; + + UInt32 j; + UInt32 *indexTable; + UInt8 ctxNo = 0; + PageMeta_t *mdPtr = yaFTL.meta_restoreMountErase; + BlockListType *listHead = NULL, *tempPtr, *tempHdr; + BlockRangeType *brPtr; + // u_int64_t t1,t2,t3,t4,t22; + BlockListType *listIndexHead = NULL, *tempIndexPtr; + + yaFTL.wrState.index.block = 0xffffffff; + WMR_MEMSET(yaFTL.tocArray, 0xff, yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + WMR_MEMSET(&yaFTL.seaState, 0, sizeof(yaFTL.seaState)); + // t1=mach_absolute_time(); + // Nir - what do you mean we have no cxt? those are kept by the VFL for you... + if (ctxT[0] == 0xffff) + { + /* No ctx units . need to allocate at the end of restore */ + ctxNo = 0; + } + else + { + ctxNo = FTL_CXT_SECTION_SIZE; + } + + Vpn = 0; + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++, Vpn += PAGES_PER_SUBLK) + { + /* + go over all blocks in partititon + todo : setup currentDndex block . Also need to calculate free dataBlocks and perhaps execute GC before we finish restore . + */ + + if (ctxNo) + { + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + } + for (n = 0; n < (UInt32)(PAGES_PER_SUBLK - yaFTL.controlPageNo); n++) + { + status = _readPage(Vpn + n, pBuff->pData, mdPtr, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right with the x%x x%x", Vpn / PAGES_PER_SUBLK, status); + continue; + } + + if (status == FIL_SUCCESS_CLEAN) + { + break; + } + + if (status == FTL_SUCCESS) + { + if((META_IS_IDX(mdPtr)) && (META_GET_IPN(mdPtr) >= yaFTL.TOCtableEntriesNo)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + if((META_IS_DATA(mdPtr)) && (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + break; + } + } + + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right block x%x ... probably need to erase", i); +#ifndef AND_READONLY + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); +#endif + continue; + } + + if ((META_ARE_FLAGS_FF(mdPtr) && (META_GET_LBA(mdPtr) == 0xffffffff)) || (status == FIL_SUCCESS_CLEAN)) /* free block */ + { + yaFTL.blockArray[i].status = BLOCK_FREE; + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + + continue; + } + if (META_IS_IDX(mdPtr)) /* index block : erase */ + { +#ifndef AND_READONLY + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); +#else + /* create a parallel list for Index blocks */ + listIndexHead = addBlockToList(listIndexHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listIndexHead); +#endif + continue; + } + /* Valid data block . Add it to a sorted linked list of data blocks according to weaveSeq */ + if (META_IS_DATA(mdPtr)) + { + yaFTL.blockArray[i].status = BLOCK_ALLOCATED; + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + listHead = addBlockToList(listHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listHead); + continue; + } + debug(ERROR, "block that does not belong to anything 0x%x .. probably need to erase", META_GET_ALL_FLAGS(mdPtr)); +#ifndef AND_READONLY + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); +#endif + } + // t2=mach_absolute_time(); + + BUF_Release(pBuff); + + yaFTL.freeCachePages = (UInt16)yaFTL.indexCacheSize; +#ifndef AND_READONLY + yaFTL.nextFreeCachePage = 0; +#endif + debug(INIT, " restoreMount[after blocklist has been created]"); + if (listIndexHead != NULL) + { + tempIndexPtr = listIndexHead; + while (tempIndexPtr != NULL) + { + if (tempIndexPtr == listIndexHead) + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 1, tempIndexPtr->weaveSeq); + } + else + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 0, tempIndexPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + freeBlockList(tempIndexPtr); + freeBlockList(listHead); + return status; + } + listIndexHead = tempIndexPtr; + tempIndexPtr = tempIndexPtr->next; + WMR_FREE(listIndexHead, sizeof(BlockListType)); + } + } + if (yaFTL.wrState.index.block == 0xffffffff) + { + debug(INIT, "index list is empty "); + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.index.block = i; /* current physical block being used for updates */ + yaFTL.wrState.index.nextPage = 0; /* offset in current block of next free page */ + WMR_MEMSET(yaFTL.wrState.index.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.blockArray[i].status = BLOCK_I_CURRENT; + debug(INIT, "current index block would be %d", i); + break; + } + } + } + + // t22=mach_absolute_time(); + if (listHead == NULL) /* empty partition */ + { + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.data.block = i; + yaFTL.blockArray[yaFTL.wrState.data.block].status = BLOCK_CURRENT; + break; + } + } + yaFTL.wrState.data.nextPage = 0; + WMR_MEMSET(yaFTL.wrState.data.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); +#ifndef AND_READONLY + if (ctxNo == 0) + { + i = 0; + for (j = 0; (Int32)j < FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.cxtTable[i] = ctxT[i]; + } + } +#endif + + // Set up block counters + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + SetupFreeAndAllocd(); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = 0; + stFTLStatistics.ddwValidIndexPages = 0; +#endif + yaFTL.seaState.distCheckable = 1; + CheckBlockDist(); + return FTL_SUCCESS; + } + + tempHdr = listHead; + + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (NULL == pBuff) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + if (!_allocateRestoreIndexBuffers(&brPtr, &indexTable, &tempIndexBufferSize)) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + WMR_MEMSET(brPtr, 0xff, (FTL_AREA_SIZE * sizeof(BlockRangeType))); + + // Set up block counters + SetupFreeAndAllocd(); + + for (j = 0; j < yaFTL.logicalPartitionSize; j += tempIndexBufferSize) + { + WMR_MEMSET(indexTable, 0xff, tempIndexBufferSize * sizeof(UInt32)); + tempPtr = listHead = tempHdr; + while (tempPtr != NULL) + { + if (tempPtr == listHead) + { + status = restoreBlock(tempPtr->blockNo, indexTable, 1, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + else + { + status = restoreBlock(tempPtr->blockNo, indexTable, 0, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + freeBlockList(tempHdr); + BUF_Release(pBuff); + return status; + } + listHead = tempPtr; + tempPtr = tempPtr->next; + if ((j + tempIndexBufferSize) >= yaFTL.logicalPartitionSize) + { + tempHdr = tempPtr; + WMR_FREE(listHead, sizeof(BlockListType)); + } + } + + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + + for (i = 0, pageBuffer = indexTable; (i < (tempIndexBufferSize * 4) / BYTES_PER_PAGE) && ((i * yaFTL.indexPageRatio + j) < yaFTL.logicalPartitionSize); i++, pageBuffer += (BYTES_PER_PAGE / 4)) + { + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + if (WMR_MEMCMP(pageBuffer, pBuff->pData, BYTES_PER_PAGE) != 0) + { + UInt16 cE; + + /* Need to copy valid page in index cache */ + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) + { + yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; + } + + cE = findFreeCacheEntry(); + if (cE == 0xffff) + { +#ifdef AND_READONLY + debug(ERROR, "can still be enough to mount OS partition"); + BUF_Release(pBuff); + return FTL_SUCCESS; +#else + WMR_MEMCPY(yaFTL.tmpReadBuffer, pageBuffer, BYTES_PER_PAGE); + SetupMeta_Index(mdPtr, i + ((j * 4) / BYTES_PER_PAGE)); + status = writeIndexPage((UInt8*)yaFTL.tmpReadBuffer, mdPtr, 0); + if (status != FTL_SUCCESS) + { + BUF_Release(pBuff); + return FTL_CRITICAL_ERROR; + } + + continue; +#endif + } + WMR_MEMCPY(yaFTL.indexCache[cE].indexPage, pageBuffer, BYTES_PER_PAGE); + yaFTL.indexCache[cE].status = IC_DIRTY_PAGE; + yaFTL.indexCache[cE].tocEntry = (UInt16)(i + ((j * 4) / BYTES_PER_PAGE)); + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = cE; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + } + else + { + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = 0xffff; + } + } + } + // t3=mach_absolute_time(); + +#ifndef AND_READONLY + /* Vadim - check presence of CXT blocks . If there are none allocate them */ + + if (ctxNo == 0) + { + i = 0; + for (j = 0; j < (UInt32)FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + } +#endif + + BUF_Release(pBuff); + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + + // t4=mach_absolute_time(); + // debug(MISC, "time spent in restore is %llu %llu %llu %llu %llu ",t2-t1,t22-t2,t3-t22,t4-t3,t4-t1); + debug(INIT, "current i block %d current i page %d", yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage); + + debug(INIT, "restoreMount : logicalPartitionSize %d TOCtableEntriesNo %d \nwrState.data.block %d wrState.data.nextPage %d \n BYTES_PER_PAGE %d \n wrState.index.block %d wrState.index.nextPage %d wrState.weaveSeq %d" + , yaFTL.logicalPartitionSize, yaFTL.TOCtableEntriesNo, yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, BYTES_PER_PAGE, yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, yaFTL.wrState.weaveSeq); + debug(INIT, "restoreMount seaState.data.allocdBlocks %d dataSize %d FTL_SIZE %d pagesinblock %d", yaFTL.seaState.data.allocdBlocks, yaFTL.dataSize, FTL_AREA_SIZE, PAGES_PER_SUBLK); + + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } +#ifndef AND_READONLY + for (i = 0; ((Int32)i < FTL_AREA_SIZE); i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) && (yaFTL.blockArray[i].validPagesDNo == 0 )) + { + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + continue; + } + if ((yaFTL.blockArray[i].status == BLOCK_I_ALLOCATED) && (yaFTL.blockArray[i].validPagesINo == 0 )) + { + YAFTL_GC_Index(i, FALSE32); + } + } + // Move the current blocks out : + i = yaFTL.wrState.index.block; + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE)&& (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + i = yaFTL.wrState.data.block; + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + while ((yaFTL.indexSize - FREE_I_BLOCK_TRS) < yaFTL.seaState.index.allocdBlocks) + { + debug(MISC, "free index %d %d", yaFTL.indexSize, yaFTL.seaState.index.allocdBlocks); + YAFTL_GC_Index(0xffffffff, FALSE32); + } +#endif + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + yaFTL.blockArray[i].validPagesINo = 0; + } +#ifndef AND_READONLY + if ((yaFTL.blockArray[i].status != BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_MOVED)) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + else + { + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + } +#endif + } + debug(INIT, "restoreMount : seaState.index.validPages = %d seaState.data.validPages = %d", yaFTL.seaState.index.validPages, yaFTL.seaState.data.validPages); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = yaFTL.seaState.data.validPages; + stFTLStatistics.ddwValidIndexPages = yaFTL.seaState.index.validPages; +#endif + + yaFTL.seaState.distCheckable = 1; + CheckBlockDist(); + return FTL_SUCCESS; +} + +#endif + + +static ANDStatus restoreMount(UInt16 * ctxT, const UInt32 readOnly) +{ + UInt32 Vpn; + ANDStatus status = FTL_SUCCESS; + UInt32 *pageBuffer = NULL; + UInt32 i, n; + Buffer * pBuff; + + UInt32 j; + UInt32 *indexTable; + UInt8 ctxNo = 0; + PageMeta_t *mdPtr = yaFTL.meta_restoreMount; + BlockListType *listHead = NULL, *tempPtr, *tempHdr; + BlockRangeType *brPtr; + // u_int64_t t1,t2,t3,t4,t22; + BlockListType *listIndexHead = NULL, *tempIndexPtr; + + yaFTL.wrState.index.block = 0xffffffff; + WMR_MEMSET(yaFTL.tocArray, 0xff, yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + WMR_MEMSET(&yaFTL.seaState, 0, sizeof(yaFTL.seaState)); + + // t1=mach_absolute_time(); + // Nir - what do you mean we have no cxt? those are kept by the VFL for you... + if (ctxT[0] == 0xffff) + { + /* No ctx units . need to allocate at the end of restore */ + ctxNo = 0; + } + else + { + ctxNo = FTL_CXT_SECTION_SIZE; + } + + Vpn = 0; + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++, Vpn += PAGES_PER_SUBLK) + { + /* + go over all blocks in partititon + todo : setup currentDndex block . Also need to calculate free dataBlocks and perhaps execute GC before we finish restore . + */ + + if (ctxNo) + { + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + } + for (n = 0; n < (UInt32)(PAGES_PER_SUBLK - yaFTL.controlPageNo); n++) + { + status = _readPage(Vpn + n, pBuff->pData, mdPtr, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right with the x%x x%x", Vpn / PAGES_PER_SUBLK, status); + continue; + } + + if (status == FIL_SUCCESS_CLEAN) + { + break; + } + + if (status == FTL_SUCCESS) + { + if((META_IS_IDX(mdPtr)) && (META_GET_IPN(mdPtr) >= yaFTL.TOCtableEntriesNo)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + if((META_IS_DATA(mdPtr)) && (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + break; + } + } + + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right block x%x ... probably need to erase", i); +#ifndef AND_READONLY + if ( !readOnly ) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); + } +#endif + continue; + } + + if ((META_ARE_FLAGS_FF(mdPtr) && (META_GET_LBA(mdPtr) == 0xffffffff)) || (status == FIL_SUCCESS_CLEAN)) /* free block */ + { + yaFTL.blockArray[i].status = BLOCK_FREE; + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + + continue; + } + if (META_IS_IDX(mdPtr)) /* index block : erase */ + { + /* create a parallel list for Index blocks */ + listIndexHead = addBlockToList(listIndexHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listIndexHead); + continue; + } + /* Valid data block . Add it to a sorted linked list of data blocks according to weaveSeq */ + if (META_IS_DATA(mdPtr)) + { + listHead = addBlockToList(listHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listHead); + continue; + } + debug(ERROR, "block that does not belong to anything 0x%x .. probably need to erase", META_GET_ALL_FLAGS(mdPtr)); +#ifndef AND_READONLY + if ( !readOnly ) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); + } +#endif + } + // t2=mach_absolute_time(); + + BUF_Release(pBuff); + + yaFTL.freeCachePages = (UInt16)yaFTL.indexCacheSize; +#ifndef AND_READONLY + if ( !readOnly ) + { + yaFTL.nextFreeCachePage = 0; + } +#endif + debug(INIT, " restoreMount[after blocklist has been created]"); + if (listIndexHead != NULL) + { + tempIndexPtr = listIndexHead; + while (tempIndexPtr != NULL) + { + if (tempIndexPtr == listIndexHead) + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 1, tempIndexPtr->weaveSeq); + } + else + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 0, tempIndexPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + freeBlockList(listIndexHead); + freeBlockList(listHead); + return status; + } + listIndexHead = tempIndexPtr; + tempIndexPtr = tempIndexPtr->next; + WMR_FREE(listIndexHead, sizeof(BlockListType)); + } + } + if (yaFTL.wrState.index.block == 0xffffffff) + { + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.index.block = i; /* current physical block being used for updates */ + yaFTL.wrState.index.nextPage = 0; /* offset in current block of next free page */ + WMR_MEMSET(yaFTL.wrState.index.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.blockArray[i].status = BLOCK_I_CURRENT; + debug(INIT, "current index block would be %d", i); + break; + } + } + } + + // t22=mach_absolute_time(); + if (listHead == NULL) /* empty partition */ + { + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.data.block = i; + yaFTL.blockArray[yaFTL.wrState.data.block].status = BLOCK_CURRENT; + break; + } + } + yaFTL.wrState.data.nextPage = 0; + WMR_MEMSET(yaFTL.wrState.data.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); +#ifndef AND_READONLY + if ( !readOnly ) + { + if (ctxNo == 0) + { + i = 0; + for (j = 0; (Int32)j < FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.cxtTable[i] = ctxT[i]; + } + } + } +#endif + + // Set up block counters + SetupFreeAndAllocd(); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = 0; + stFTLStatistics.ddwValidIndexPages = 0; +#endif + + yaFTL.seaState.distCheckable = 1; + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + CheckBlockDist(); + return FTL_SUCCESS; + } + + tempHdr = listHead; + + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (NULL == pBuff) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + if (!_allocateRestoreIndexBuffers(&brPtr, &indexTable, &tempIndexBufferSize)) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + WMR_MEMSET(brPtr, 0xff, (FTL_AREA_SIZE * sizeof(BlockRangeType))); + + for (j = 0; j < yaFTL.logicalPartitionSize; j += tempIndexBufferSize) + { + WMR_MEMSET(indexTable, 0xff, tempIndexBufferSize * sizeof(UInt32)); + tempPtr = listHead = tempHdr; + while (tempPtr != NULL) + { + if (tempPtr == listHead) + { + status = restoreBlock(tempPtr->blockNo, indexTable, 1, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + else + { + status = restoreBlock(tempPtr->blockNo, indexTable, 0, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + freeBlockList(tempHdr); + BUF_Release(pBuff); + return status; + } + listHead = tempPtr; + tempPtr = tempPtr->next; + if ((j + tempIndexBufferSize) >= yaFTL.logicalPartitionSize) + { + tempHdr = tempPtr; + WMR_FREE(listHead, sizeof(BlockListType)); + } + } + + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + + for (i = 0, pageBuffer = indexTable; (i < (tempIndexBufferSize * 4) / BYTES_PER_PAGE) && ((i * yaFTL.indexPageRatio + j) < yaFTL.logicalPartitionSize); i++, pageBuffer += (BYTES_PER_PAGE / 4)) + { + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + + if (WMR_MEMCMP(pageBuffer, pBuff->pData, BYTES_PER_PAGE) == 0) + { + if ((yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) && (yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo > 0)) + { + yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + } + + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex != 0xffff) + { + yaFTL.indexCache[yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex].status = FREE_CACHE_PAGE; + yaFTL.indexCache[yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex].counter = 0; + } + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = 0xffff; + continue; /* index page does not contain any valid pages */ + } + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) + { + status = _readPage(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage, (UInt8 *)pBuff->pData, NULL, FALSE32, TRUE32, FALSE32); + if (status != FTL_SUCCESS) + { + debug(ERROR, "index page is unreadable at 0x%x", yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage); + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + } + } + + if (WMR_MEMCMP(pageBuffer, pBuff->pData, BYTES_PER_PAGE) != 0) + { + UInt16 cE; + + /* Need to copy valid page in index cache */ + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) + { + yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; + } + + cE = findFreeCacheEntry(); + if (cE == 0xffff) + { + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + BUF_Release(pBuff); +#ifdef AND_READONLY + if ( !readOnly ) + { + debug(ERROR, "ran out of available cache pages on toc entry %d", (i + ((j * 4) / BYTES_PER_PAGE))); + debug(ERROR, "can still be enough to mount OS partition"); + freeBlockList(tempHdr); + return FTL_SUCCESS; + } + else +#endif + { + debug(ERROR,"ran out of available cache pages on toc entry %d", (i + ((j * 4) / BYTES_PER_PAGE))); + freeBlockList(tempHdr); + return FTL_CRITICAL_ERROR; + } + } + WMR_MEMCPY(yaFTL.indexCache[cE].indexPage, pageBuffer, BYTES_PER_PAGE); + yaFTL.indexCache[cE].status = IC_DIRTY_PAGE; + yaFTL.indexCache[cE].tocEntry = (UInt16)(i + ((j * 4) / BYTES_PER_PAGE)); + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = cE; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + } + } + } + // t3=mach_absolute_time(); + +#ifndef AND_READONLY + if ( !readOnly ) + { + /* Vadim - check presence of CXT blocks . If there are none allocate them */ + + if (ctxNo == 0) + { + i = 0; + for (j = 0; j < (UInt32)FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + } + } +#endif + + BUF_Release(pBuff); + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + + // Set up block counters + SetupFreeAndAllocd(); + + // t4=mach_absolute_time(); + // debug(MISC, "time spent in restore is %llu %llu %llu %llu %llu ",t2-t1,t22-t2,t3-t22,t4-t3,t4-t1); + debug(INIT, "current i block %d current i page %d", yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage); + + debug(INIT, "restoreMount : logicalPartitionSize %d TOCtableEntriesNo %d \nwrState.data.block %d wrState.data.nextPage %d \n BYTES_PER_PAGE %d \n wrState.index.block %d wrState.index.nextPage %d wrState.weaveSeq %d" + , yaFTL.logicalPartitionSize, yaFTL.TOCtableEntriesNo, yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, BYTES_PER_PAGE, yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, yaFTL.wrState.weaveSeq); + debug(INIT, "restoreMount seaState.data.allocdBlocks %d dataSize %d FTL_SIZE %d pagesinblock %d", yaFTL.seaState.data.allocdBlocks, yaFTL.dataSize, FTL_AREA_SIZE, PAGES_PER_SUBLK); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = yaFTL.seaState.data.validPages; + stFTLStatistics.ddwValidIndexPages = yaFTL.seaState.index.validPages; +#endif + + yaFTL.seaState.distCheckable = 1; + CheckBlockDist(); + + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } +#ifndef AND_READONLY + if ( !readOnly ) + { + for (i = 0; ((Int32)i < FTL_AREA_SIZE); i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) && (yaFTL.blockArray[i].validPagesDNo == 0 )) + { + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + continue; + } + if ((yaFTL.blockArray[i].status == BLOCK_I_ALLOCATED) && (yaFTL.blockArray[i].validPagesINo == 0 )) + { + YAFTL_GC_Index(i, FALSE32); + } + } + // Move the current blocks out : + i = yaFTL.wrState.index.block; + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + i = yaFTL.wrState.data.block; + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + while ((yaFTL.indexSize - FREE_I_BLOCK_TRS) < yaFTL.seaState.index.allocdBlocks) + { + debug(MISC, "free index %d %d", yaFTL.indexSize, yaFTL.seaState.index.allocdBlocks); + YAFTL_GC_Index(0xffffffff, FALSE32); + } + } +#endif + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + yaFTL.blockArray[i].validPagesINo = 0; + } +#ifndef AND_READONLY + if ( !readOnly ) + { + if ((yaFTL.blockArray[i].status != BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_MOVED)) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + else + { + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + } + } +#endif + } + debug(INIT, "restoreMount : seaState.index.validPages = %d seaState.data.validPages = %d", yaFTL.seaState.index.validPages, yaFTL.seaState.data.validPages); + + CheckBlockDist(); + + return FTL_SUCCESS; +} + +static BOOL32 +_allocateRestoreIndexBuffers(BlockRangeType **blockRangeBuffer, UInt32 **indexTable, UInt32 *indexTableSize) +{ + const UInt32 kBlockRangeSize = FTL_AREA_SIZE * sizeof(BlockRangeType); + void *blockRange = NULL; + void *table = NULL; + UInt32 bootBufferSize; + + if ((NULL == blockRangeBuffer) || (NULL == indexTable)) + { + return FALSE32; + } + + blockRange = WMR_MALLOC(kBlockRangeSize); + + bootBufferSize = MIN_RESTORE_BUFFER; + table = (UInt8 *)WMR_BOOT_MALLOC(&bootBufferSize); + + if ((NULL == table) || (NULL == blockRange)) + { + if (NULL != blockRange) + { + WMR_FREE(blockRange, kBlockRangeSize); + } + debug(ERROR, "could not allocate enough memory for the restore"); + return FALSE32; + } + + if(bootBufferSize > (MAX_RESTORE_BUFFER * sizeof(UInt32))) + { + bootBufferSize = (MAX_RESTORE_BUFFER) * sizeof(UInt32); + } + else + { + bootBufferSize = ROUNDDOWNTO(bootBufferSize, MIN_RESTORE_BUFFER); + } + + *indexTable = (UInt32*) table; + *blockRangeBuffer = (BlockRangeType*) blockRange; + *indexTableSize = bootBufferSize / sizeof(UInt32); + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Open */ +/* DESCRIPTION */ +/* This function mounts the device using control info or restore */ +/* if control info is dirty */ +/* RETURN VALUES */ +/* FTL_SUCCESS */ +/* YAFTL_Init is completed */ +/* FTL_CRITICAL_ERROR */ +/* YAFTL_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +YAFTL_Open(UInt32 *pTotalPages, UInt32 * pdwPageSize, BOOL32 nandFullRestore, BOOL32 justFormatted, UInt32 dwMinorVer, UInt32 dwOptions) +{ + UInt16 i; +#ifndef AND_READONLY + UInt32 tempIndexCacheSize = yaFTL.indexCacheSize; +#endif + Int32 status = FTL_CRITICAL_ERROR; + UInt16 cxtT[FTL_CXT_SECTION_SIZE]; + BOOL32 formatSupported = TRUE32; + + const UInt32 readOnly = ( WMR_INIT_OPEN_READONLY == (WMR_INIT_OPEN_READONLY & dwOptions) ? 1 : 0 ); + + /* read out VFL_meta data . If it is not present execute full format . If it is present go and fetch "quick mount" info from CX area if it's valid .If not execute restore + For now we need to start from fresh media which means there is no quick mount info and all blocks are free . */ +#ifndef AND_READONLY + if(justFormatted == TRUE32) + yaFTL.formatWasCalled = justFormatted; + WMR_MEMSET(yaFTL.eraseNowList, 0xff, sizeof(UInt16) * ERASE_NOW_LIST_SIZE); +#endif + WMR_MEMSET(yaFTL.tocArray, 0xff, sizeof(TOCEntry) * yaFTL.TOCtableEntriesNo); + WMR_MEMSET(yaFTL.blockArray, 0xff, sizeof(BlockEntry) * FTL_AREA_SIZE); + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.blockArray[i].validPagesDNo = 0; + yaFTL.blockArray[i].validPagesINo = 0; + yaFTL.blockArray[i].erasableCount = 0; + yaFTL.blockArray[i].pagesRead = 0; + yaFTL.blockArray[i].pagesReadSubCounter = 0; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.blockArray[i].status = 0; + } + + yaFTL.wrState.lastBlock = 0xffffffff; + /* Get CXT blocks from the VFL */ + WMR_MEMCPY(cxtT, VFL_GetFTLCxtVbn(), FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + + /* + Vadim : here we make a decision about quick mount . + If quick mount units do not exist - go to restore + If quick mount units exist - go with quick mount if there is a valid copy . + Otherwise, go with restore . + */ + if (cxtT[0] != 0xffff) + { + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.cxtTable[i] = cxtT[i]; + yaFTL.blockArray[yaFTL.cxtTable[i]].status = BLOCK_CTX_CNTR; + debug(OPEN, "YAFTL_Open cxt [ %d ] = 0x%x %d 0x%x %d", i, cxtT[i], cxtT[i], FTL_AREA_SIZE, FTL_AREA_SIZE); + } + + status = (UInt16)quickRestore(cxtT, &formatSupported); + if (formatSupported != TRUE32) + { + debug(ERROR, "YAFTL_OPEN unsupported low-level format version cannot continue ."); + return FTL_CRITICAL_ERROR; + } +#ifdef AND_COLLECT_STATISTICS + if(stFTLStatistics.ddwRefreshCnt == 0xffffffff) + { + debug(ERROR, "YAFTL_OPEN clearing refresh stats"); + stFTLStatistics.ddwRefreshCnt = 0; + } +#endif +#ifndef AND_READONLY + if ((dwOptions & WMR_INIT_SET_INDEX_CACHE_SIZE) == WMR_INIT_SET_INDEX_CACHE_SIZE) + { + yaFTL.indexCacheSize = (dwOptions >> 20); + tempIndexCacheSize = yaFTL.indexCacheSize; + debug(INIT, "YAFTL_OPEN index cache will be set to 0x%x -- 0x%x", yaFTL.indexCacheSize, tempIndexCacheSize); + } + if ((yaFTL.cxtAllocation != 0) && (yaFTL.cxtAllocation != 0xffffffff)) + for(i = 0; i < FTL_CXT_SECTION_SIZE; i++) + if( yaFTL.blockArray[yaFTL.cxtTable[i]].erasableCount == 0) + yaFTL.blockArray[yaFTL.cxtTable[i]].erasableCount = (UInt32 + )(yaFTL.cxtAllocation / (PAGES_PER_SUBLK / yaFTL.cxtSize)); +#endif + if ((status != FTL_SUCCESS) || (nandFullRestore == TRUE32)) + { + debug(INIT, "YAFTL_OPEN forcing full mount 0x%x %d ", status, nandFullRestore); + status = FTL_CRITICAL_ERROR; + } + /* Allocate index cache based on a size saved in cxt area */ + if ((status != FTL_SUCCESS) && (WMR_MIN( NAND_MOUNT_INDEX_SIZE, ((yaFTL.logicalPartitionSize / yaFTL.indexPageRatio) + 1)) > yaFTL.indexCacheSize)) + { +#ifndef AND_READONLY + tempIndexCacheSize = yaFTL.indexCacheSize; +#endif + yaFTL.indexCacheSize = WMR_MIN( NAND_MOUNT_INDEX_SIZE, ((yaFTL.logicalPartitionSize / yaFTL.indexPageRatio) + 1));//NAND_MOUNT_INDEX_SIZE; + } + yaFTL.indexCache = (CacheIndexEntry *)WMR_MALLOC(yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + if (yaFTL.indexCache == NULL) + { + return FTL_CRITICAL_ERROR; + } + + // Allocate index cache buffers + WMR_BufZone_Init(&yaFTL.BufZone_IndexCache); + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + // Pre-reserve + yaFTL.indexCache[i].indexPage = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone_IndexCache, BYTES_PER_PAGE); + } + + // Finish allocations + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BufZone_IndexCache)) + { + return FTL_CRITICAL_ERROR; + } + + // Rebase and initialize + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + WMR_BufZone_Rebase(&yaFTL.BufZone_IndexCache, (void**)&yaFTL.indexCache[i].indexPage); + yaFTL.indexCache[i].status = FREE_CACHE_PAGE; + yaFTL.indexCache[i].tocEntry = 0xffff; + yaFTL.indexCache[i].counter = 0; + WMR_MEMSET(yaFTL.indexCache[i].indexPage, 0xff, BYTES_PER_PAGE); + } + + // Finish rebase + WMR_BufZone_FinishedRebases(&yaFTL.BufZone_IndexCache); + + if (status == FTL_SUCCESS) + { + debug(OPEN, "YAFTL_OPEN quick mount is present and valid . open is done "); + *pTotalPages = ((yaFTL.logicalPartitionSize - 1) / 100) * yaFTL.exportedRatio /*EXPO_RATIO*/; + *pdwPageSize = BYTES_PER_PAGE; + yaFTL.maxEraseCount = 0; yaFTL.minEraseCount = 0xffffffff; yaFTL.erasedBlockCount = 0; + for (i = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + if ((yaFTL.blockArray[i].status != BLOCK_CTX_CNTR) && (yaFTL.blockArray[i].status != BLOCK_CTX_CURRENT)) + { + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + if (yaFTL.blockArray[i].erasableCount < yaFTL.minEraseCount) + { + yaFTL.minEraseCount = yaFTL.blockArray[i].erasableCount; + } + } + } + + // Set up block counters + SetupFreeAndAllocd(); + BTOC_BootFixup(); + + PopulateTreesOnBoot_Fast(); + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + return status; + } + } + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.blockArray[i].validPagesDNo = 0; + yaFTL.blockArray[i].validPagesINo = 0; + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + else + yaFTL.blockArray[i].status = 0; + } + debug(ERROR, "CXT is not valid . Performing full NAND R/O restore ... "); +#ifdef AND_USE_NOTIFY + { + LowFuncTbl *pLowFuncTbl; + + pLowFuncTbl = FIL_GetFuncTbl(); + pLowFuncTbl->Notify(AND_NOTIFY_RECOVER); + } +#endif /* AND_USE_NOTIFY */ + + status = (UInt16)restoreMount(cxtT, readOnly); + if (status != FTL_SUCCESS) + { +#ifndef AND_READONLY + debug(ERROR, "Read only full restore failed. Performing full NAND R/W restore ... "); + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + yaFTL.indexCache[i].status = FREE_CACHE_PAGE; + yaFTL.indexCache[i].tocEntry = 0xffff; + yaFTL.indexCache[i].counter = 0; + WMR_MEMSET(yaFTL.indexCache[i].indexPage, 0xff, BYTES_PER_PAGE); + } + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.blockArray[i].validPagesDNo = 0; + yaFTL.blockArray[i].validPagesINo = 0; + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + else + yaFTL.blockArray[i].status = 0; + } + + status = restoreMountEraseIndex(cxtT); + if (status != FTL_SUCCESS) +#endif + return status; + } + + BTOC_BootFixup(); + + // force next cxt update out of the current cxt block ( unclean shutdown ) + if(yaFTL.currentCxtVpn != 0xffffffff) + yaFTL.currentCxtVpn = ((yaFTL.currentCxtVpn / PAGES_PER_SUBLK) * PAGES_PER_SUBLK) + (PAGES_PER_SUBLK - 1); + + // Detect min/max erase counts + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.maxEraseCount = 0; yaFTL.minEraseCount = 0xffffffff; + if ((yaFTL.blockArray[i].status != BLOCK_CTX_CNTR) && (yaFTL.blockArray[i].status != BLOCK_CTX_CURRENT)) + { + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + if (yaFTL.blockArray[i].erasableCount < yaFTL.minEraseCount) + { + yaFTL.minEraseCount = yaFTL.blockArray[i].erasableCount; + } + } + } + + *pTotalPages = ((yaFTL.logicalPartitionSize - 1) / 100) * yaFTL.exportedRatio /*EXPO_RATIO*/; + *pdwPageSize = BYTES_PER_PAGE; +#ifndef AND_READONLY + if ( !readOnly ) + { + if (yaFTL.indexCacheSize != tempIndexCacheSize) + { + UInt32 tmpVar = (UInt32)tempIndexCacheSize; + YAFTL_GetStruct(AND_FUNCTION_INDEX_CACHE_UPDATE, NULL, (UInt32 *)&tmpVar); + } + } +#endif + + PopulateTreesOnBoot_Fast(); + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + return FTL_SUCCESS; +} + + +#if ENABLE_L2V_TREE +static void PopulateFromIndexCache(UInt32 indexPageNo, UInt32 *indexPageData) +{ + UInt32 lpn; + UInt32 i, lastLpn, lastPhy, lastLen; + UInt32 *phyPtr; + + lpn = indexPageNo * yaFTL.indexPageRatio; + lastLpn = 0xffffffff; + lastPhy = 0xffffffff; + lastLen = 0; + phyPtr = indexPageData; + + for (i = 0; (i < yaFTL.indexPageRatio) && !L2V_LowMem; i++, phyPtr++) + { + if (0 == lastLen) + { + lastLpn = lpn + i; + lastPhy = *phyPtr; + lastLen = 1; + continue; + } + + if (((0xffffffff != lastPhy) && ((lastPhy + lastLen) == *phyPtr)) || ((0xffffffff == lastPhy) && (lastPhy == *phyPtr))) + { + lastLen++; + } + else + { + if (0xffffffff == lastPhy) { + L2V_Update(lastLpn, lastLen, L2V_VPN_DEALLOC); + } else { + L2V_Update(lastLpn, lastLen, lastPhy); + } + + lastLpn = lpn + i; + lastPhy = *phyPtr; + lastLen = 1; + } + } + + if (lastLen && !L2V_LowMem) + { + if (0xffffffff == lastPhy) { + L2V_Update(lastLpn, lastLen, L2V_VPN_DEALLOC); + } else { + L2V_Update(lastLpn, lastLen, lastPhy); + } + } +} +#endif // ENABLE_L2V_TREE + + +#if ENABLE_L2V_TREE +#ifdef AND_READONLY +#error Tree not supported in read-only AND driver. This would require GC to allocate index buffer in AND_READONLY mode, since we share that to populate trees. +#endif +static void PopulateTreesOnBoot_Fast() +{ + UInt32 zoneSize, indexPageNo, successCount, failCount, i; +#if TIME_TREE + UInt64 startTime; +#endif + BOOL32 BoolStatus; + Int32 status; + + indexPageNo = 0; + successCount = 0; + failCount = 0; + +#if TIME_TREE + (void) clock_timebase_info(&sTimebaseInfo); + startTime = ANDPerf_getTime(); +#endif + + while ((indexPageNo < yaFTL.TOCtableEntriesNo) && !L2V_LowMem) { + // Fill out VPNs + zoneSize = 0; + while (((indexPageNo + zoneSize) < yaFTL.TOCtableEntriesNo) && (zoneSize < yaFTL.gc.zoneSize)) + { + if (0xffffffff != yaFTL.tocArray[indexPageNo+zoneSize].indexPage) { + yaFTL.gc.index.vpns[zoneSize] = yaFTL.tocArray[indexPageNo+zoneSize].indexPage; + zoneSize++; + } else { + // Creates gaps. Ok so long as we're careful about inferring starts/ends, and use meta read from page, not calculated + indexPageNo++; + } + } + + // Read index pages + BoolStatus = _readMultiPages(yaFTL.gc.index.vpns, zoneSize, &yaFTL.gc.index.zone[0], (UInt8*)&yaFTL.gc.index.meta[0], 0, 0); + if (BoolStatus != TRUE32) + { + for (i = 0; i < zoneSize; i++) + { + status = _readPage(yaFTL.gc.index.vpns[i], &yaFTL.gc.index.zone[BYTES_PER_PAGE * i], &yaFTL.gc.index.meta[i], 0, TRUE32, 0); + if (status != FTL_SUCCESS) + { + META_SET_LBA(&yaFTL.gc.index.meta[i], 0xffffffff); + } + } + } + + // Now scan the results--if it's the current one, update using it + for (i = 0; (i < zoneSize) && !L2V_LowMem; i++) + { + if ((META_IS_IDX(&yaFTL.gc.index.meta[i])) && (yaFTL.TOCtableEntriesNo > META_GET_IPN(&yaFTL.gc.index.meta[i]))) + { + PopulateFromIndexCache(META_GET_IPN(&yaFTL.gc.index.meta[i]), (UInt32*)&yaFTL.gc.index.zone[BYTES_PER_PAGE * i]); + successCount++; + } + else + { + failCount++; + } + } + + indexPageNo += zoneSize; + } + +#if TIME_TREE + WMR_PRINT("NAND cache population time: %dus\n", ANDPerf_toUs(ANDPerf_getTime() - startTime)); +#endif +} +#else // if not ENABLE_L2V_TREE: +static void PopulateTreesOnBoot_Fast() +{ + // Do nothing +} +#endif // !ENABLE_L2V_TREE + + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* allocateBlock */ +/* DESCRIPTION */ +/* Allocates free block for either index or data update operartions */ +/* */ +/*****************************************************************************/ +UInt32 allocateBlock(UInt32 blockNo, UInt8 flag, UInt8 type) +{ + UInt32 i; + UInt32 minCount = 0xffffffff, minCountIndex = 0xffffffff; + UInt16 blockToEraseForReal = 0; + + // Wear leveling periodicity counter + yaFTL.wearLevel.blocksSince++; + + if(yaFTL.erasedBlockCount < (FREE_BLK_TRH + FREE_I_BLOCK_TRS)) + { + blockToEraseForReal = (FREE_BLK_TRH + FREE_I_BLOCK_TRS) - yaFTL.erasedBlockCount; + } + else + blockToEraseForReal = 0; + + // Set up minWeaveSeq, clear out data gc adjust + if (1 == type) + { + yaFTL.wrState.data.minWeaveSeq = yaFTL.wrState.weaveSeq; + yaFTL.gc.data.gcDataAdjust = 0; + } + else + { + yaFTL.wrState.index.minWeaveSeq = yaFTL.wrState.weaveSeq; + } + + // look for a block with smallest erasable unit count + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++) + { + if((type == 1) && (yaFTL.blockArray[i].status == BLOCK_FREE) && ((yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED_ALIGNED_DATA) || (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED)) ) + { + if((isBlockInEraseNowList(i)) || (blockToEraseForReal > 0)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + if(blockToEraseForReal > 0) + { + blockToEraseForReal--; + } + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.blockArray[i].erasableCount++; + yaFTL.periodicCxt.erases++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + removeBlockFromEraseNowList((UInt16)i); + } + else + { + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + } + } + else + { + if((type != 1) && (yaFTL.blockArray[i].status == BLOCK_FREE) && ((yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED_ALIGNED_INDEX) || (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED))) + { + if((isBlockInEraseNowList(i)) || (blockToEraseForReal > 0)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + if(blockToEraseForReal > 0) + { + blockToEraseForReal--; + } + removeBlockFromEraseNowList((UInt16)i); + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.blockArray[i].erasableCount++; + yaFTL.periodicCxt.erases++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + } + else + { + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + } + } + } + + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != BLOCK_TO_BE_ERASED_ALIGNED_DATA) && (yaFTL.blockArray[i].eraseBeforeUse != BLOCK_TO_BE_ERASED_ALIGNED_INDEX) && (minCount > yaFTL.blockArray[i].erasableCount)) + { + minCount = yaFTL.blockArray[i].erasableCount; + minCountIndex = i; + WMR_ASSERT(0 == yaFTL.blockArray[i].validPagesINo); + WMR_ASSERT(0 == yaFTL.blockArray[i].validPagesDNo); + } + } + if (minCountIndex == 0xffffffff) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("no free yaFTL blocks: type %d\n", type); + return minCountIndex; + } + if (type == 1) /* dataBlock */ + { + BTOC_Dealloc(yaFTL.wrState.data.TOC); +#ifndef AND_READONLY + if (yaFTL.blockArray[minCountIndex].eraseBeforeUse == BLOCK_TO_BE_ERASED) + { + UInt8 status; + WMR_ASSERT(BLOCK_FREE == yaFTL.blockArray[minCountIndex].status); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + status = VFL_Erase((UInt16)minCountIndex, TRUE32); + if (status != FTL_SUCCESS) + { + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + removeBlockFromEraseNowList((UInt16)minCountIndex); + yaFTL.blockArray[minCountIndex].erasableCount++; + yaFTL.periodicCxt.erases++; + yaFTL.blockArray[minCountIndex].eraseBeforeUse = 0; + } +#endif + yaFTL.blockArray[yaFTL.wrState.data.block].status = BLOCK_ALLOCATED; + yaFTL.wrState.data.block = minCountIndex; + yaFTL.blockArray[minCountIndex].status = BLOCK_CURRENT; + yaFTL.wrState.data.nextPage = 0; + yaFTL.wrState.data.TOC = BTOC_Alloc(yaFTL.wrState.data.block, 1); + WMR_MEMSET(yaFTL.wrState.data.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.seaState.data.freeBlocks--; + yaFTL.seaState.freeBlocks--; + if(yaFTL.erasedBlockCount) + yaFTL.erasedBlockCount--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks--; +#endif + yaFTL.seaState.data.allocdBlocks++; + //wrState.data.weaveSeq++; + return yaFTL.wrState.data.block; + } + else + { + BTOC_Dealloc(yaFTL.wrState.index.TOC); +#ifndef AND_READONLY + if (yaFTL.blockArray[minCountIndex].eraseBeforeUse == BLOCK_TO_BE_ERASED) + { + UInt8 status; + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + status = VFL_Erase((UInt16)minCountIndex, TRUE32); + if (status != FTL_SUCCESS) + { + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + removeBlockFromEraseNowList((UInt16)minCountIndex); + yaFTL.blockArray[minCountIndex].erasableCount++; + yaFTL.periodicCxt.erases++; + yaFTL.blockArray[minCountIndex].eraseBeforeUse = 0; + } +#endif + yaFTL.blockArray[yaFTL.wrState.index.block].status = BLOCK_I_ALLOCATED; + yaFTL.wrState.index.block = minCountIndex; + yaFTL.blockArray[minCountIndex].status = BLOCK_I_CURRENT; + yaFTL.wrState.index.nextPage = 0; + yaFTL.wrState.index.TOC = BTOC_Alloc(yaFTL.wrState.index.block, 0); + WMR_MEMSET(yaFTL.wrState.index.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.seaState.index.freeBlocks--; + yaFTL.seaState.freeBlocks--; + if(yaFTL.erasedBlockCount) + yaFTL.erasedBlockCount--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks--; +#endif + yaFTL.seaState.index.allocdBlocks++; + + return yaFTL.wrState.index.block; + } +} +#endif //ifndef AND_READONLY + +/*****************************************************************************/ +/* */ +/* NAME */ +/* findFreeCacheEntry */ +/* DESCRIPTION */ +/* Finds free entry in index cache table */ +/* */ +/*****************************************************************************/ +UInt16 findFreeCacheEntry(void) +{ + UInt16 i; + + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + if (yaFTL.indexCache[i].status == FREE_CACHE_PAGE) + { + return i; + } + } + return 0xffff; +} + +#ifndef AND_READONLY +UInt16 clearEntryInCache(UInt8 flag, UInt16 candidate, UInt8 keepInCache) +{ + UInt16 i; + UInt16 bestCandidateCounterBusy = 0xffff, bestCandidateBusy = 0xffff, bestCandidateCounterDirty = 0xffff, bestCandidateDirty = 0xffff; + UInt8 status; + + if (candidate == 0xffff) + { + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + if (yaFTL.indexCache[i].status == FREE_CACHE_PAGE) + { + return i; + } + if ((yaFTL.indexCache[i].status == IC_BUSY_PAGE) && (yaFTL.indexCache[i].counter <= bestCandidateCounterBusy)) + { + bestCandidateBusy = i; + bestCandidateCounterBusy = yaFTL.indexCache[i].counter; + } + if ((yaFTL.indexCache[i].status == IC_DIRTY_PAGE) && (yaFTL.indexCache[i].counter <= bestCandidateCounterDirty)) + { + bestCandidateDirty = i; + bestCandidateCounterDirty = yaFTL.indexCache[i].counter; + } + } + } + else + { + // Note: bestCandidateCounterBusy and bestCandidateCounterDirty are not updated by this path, since they are not needed. + if (yaFTL.indexCache[candidate].status == FREE_CACHE_PAGE) + { + return candidate; + } + if (yaFTL.indexCache[candidate].status == IC_BUSY_PAGE) + { + bestCandidateBusy = candidate; + } + if (yaFTL.indexCache[candidate].status == IC_DIRTY_PAGE) + { + bestCandidateDirty = candidate; + } + } + + if (bestCandidateBusy != 0xffff) + { + if(keepInCache == 0) + { + yaFTL.tocArray[yaFTL.indexCache[bestCandidateBusy].tocEntry].cacheIndex = 0xffff; + WMR_MEMSET(yaFTL.indexCache[bestCandidateBusy].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.indexCache[bestCandidateBusy].status = FREE_CACHE_PAGE; + yaFTL.indexCache[bestCandidateBusy].counter = 0; + yaFTL.freeCachePages++; + } + return bestCandidateBusy; + } + + if (bestCandidateDirty != 0xffff) + { + PageMeta_t *mdPtr = yaFTL.meta_clearEntryInCache; + UInt32 tocEntry = yaFTL.indexCache[bestCandidateDirty].tocEntry; + + SetupMeta_Index(mdPtr, tocEntry); + + if (yaFTL.tocArray[tocEntry].indexPage != 0xffffffff) + { + WMR_ASSERT(0 != yaFTL.blockArray[yaFTL.tocArray[tocEntry].indexPage / PAGES_PER_SUBLK].validPagesINo); + yaFTL.blockArray[(yaFTL.tocArray[tocEntry].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + } + status = (UInt8)writeIndexPage((UInt8 *)yaFTL.indexCache[bestCandidateDirty].indexPage, mdPtr, flag); + if (FTL_SUCCESS != status) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't write index page %d in clearEntryInCache", yaFTL.indexCache[bestCandidateDirty].indexPage); + } + + // collectBlockStats(); + if(keepInCache == 0) + { + yaFTL.tocArray[tocEntry].cacheIndex = 0xffff; + yaFTL.indexCache[bestCandidateDirty].status = FREE_CACHE_PAGE; + yaFTL.indexCache[bestCandidateDirty].counter = 0; + WMR_MEMSET(yaFTL.indexCache[bestCandidateDirty].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.freeCachePages++; + } + else + { + yaFTL.indexCache[bestCandidateDirty].status = IC_BUSY_PAGE; + } + return bestCandidateDirty; + } + + return 0xffff; +} +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* writeCurrentBlockTOC */ +/* DESCRIPTION */ +/* writes block TOC info once block is full */ +/* */ +/*****************************************************************************/ +ANDStatus writeCurrentBlockTOC(UInt8 type) +{ + UInt8 i; + Int32 status; + UInt32 Vpn; + PageMeta_t *md = yaFTL.meta_writeBTOC; + + if (type == 1) + { + SetupMeta_Data_BTOC(md); + + Vpn = yaFTL.wrState.data.nextPage + (yaFTL.wrState.data.block * PAGES_PER_SUBLK); + if (yaFTL.wrState.data.nextPage == (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + for (i = 0; i < yaFTL.controlPageNo; i++, Vpn++) + { + status = _writePage(Vpn, ((UInt8*)yaFTL.wrState.data.TOC) + (i * BYTES_PER_PAGE), md, FALSE32); + if (status != FTL_SUCCESS) + { + return FTL_CRITICAL_ERROR; + } + yaFTL.wrState.data.nextPage++; + } + } + } + else + { + SetupMeta_Index_BTOC(md); + + Vpn = yaFTL.wrState.index.nextPage + (yaFTL.wrState.index.block * PAGES_PER_SUBLK); + if (yaFTL.wrState.index.nextPage == (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + for (i = 0; i < yaFTL.controlPageNo; i++, Vpn++) + { + status = _writePage(Vpn, ((UInt8*)yaFTL.wrState.index.TOC) + (i * BYTES_PER_PAGE), md, FALSE32); + if (status != FTL_SUCCESS) + { + return FTL_CRITICAL_ERROR; + } + yaFTL.wrState.index.nextPage++; + } + } + } + return FTL_SUCCESS; +} + +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* flushIndexCache */ +/* DESCRIPTION */ +/* commits index cached pages to flash */ +/* */ +/*****************************************************************************/ +static ANDStatus flushIndexCache(UInt8 keepInCache) +{ + UInt16 i; + + while ((yaFTL.indexSize - FREE_I_BLOCK_TRS) < yaFTL.seaState.index.allocdBlocks) + { + YAFTL_GC_Index(0xffffffff, TRUE32); + } + + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + clearEntryInCache(0, i, keepInCache); + } + + return FTL_SUCCESS; +} + +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* writeIndexPage */ +/* DESCRIPTION */ +/* writes index page to flash */ +/* */ +/*****************************************************************************/ +static ANDStatus writeIndexPage(UInt8 *pageBuffer, PageMeta_t *mdPtr, UInt8 flag) +{ + UInt32 Vpn; + ANDStatus status; + + ONEMORETIME: + if (yaFTL.wrState.index.nextPage < (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + /* we have space in current index block */ + Vpn = yaFTL.wrState.index.nextPage + (yaFTL.wrState.index.block * PAGES_PER_SUBLK); /* should use << if possible */ + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[yaFTL.wrState.index.nextPage], mdPtr); + META_SET_WEAVESEQ(mdPtr); + status = _writePage(Vpn, pageBuffer, mdPtr, FALSE32); + if (status != FTL_SUCCESS) + { + debug(WRITE, "cannot write index page "); + YAFTL_GC_Index_Enq(yaFTL.wrState.index.block); + allocateBlock(yaFTL.wrState.index.block, 0, 0); + + goto ONEMORETIME; + } + yaFTL.wrState.index.nextPage++; + yaFTL.blockArray[yaFTL.wrState.index.block].validPagesINo++; + yaFTL.seaState.index.validPages++; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages++; +#endif + } + else + { + /* current block is full . need to allocate new block */ + writeCurrentBlockTOC(0); + allocateBlock(yaFTL.wrState.index.block, flag, 0); + + Vpn = yaFTL.wrState.index.nextPage + (yaFTL.wrState.index.block * PAGES_PER_SUBLK); // should use << if possible + WMR_ASSERT(0 == yaFTL.wrState.index.nextPage); + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[yaFTL.wrState.index.nextPage], mdPtr); + META_SET_WEAVESEQ(mdPtr); + status = _writePage(Vpn, pageBuffer, mdPtr, FALSE32); + if (status != FTL_SUCCESS) + { + debug(WRITE, "cannot write index page "); + YAFTL_GC_Index_Enq(yaFTL.wrState.index.block); + allocateBlock(yaFTL.wrState.index.block, 0, 0); + + goto ONEMORETIME; + } + yaFTL.blockArray[yaFTL.wrState.index.block].validPagesINo++; + yaFTL.seaState.index.validPages++; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages++; +#endif + yaFTL.wrState.index.nextPage++; + } + + yaFTL.tocArray[META_GET_IPN(mdPtr)].indexPage = Vpn; + return FTL_SUCCESS; +} +#endif + +#ifndef AND_READONLY + + +static ANDStatus makeErasable(UInt32 block) +{ + if((block < FTL_AREA_SIZE) && (yaFTL.blockArray[block].status == BLOCK_ALLOCATED) && (yaFTL.blockArray[block].validPagesDNo == 0)) + { + YAFTL_GC_Data_Deq_sb(block); + yaFTL.blockArray[block].eraseBeforeUse = BLOCK_TO_BE_ERASED_ALIGNED_DATA; + yaFTL.blockArray[block].pagesRead = 0; + yaFTL.blockArray[block].pagesReadSubCounter = 0; + yaFTL.blockArray[block].validPagesDNo = yaFTL.blockArray[block].validPagesINo = 0; + yaFTL.seaState.freeBlocks++; + yaFTL.blockArray[block].status = BLOCK_FREE; + yaFTL.seaState.data.freeBlocks++; + yaFTL.seaState.data.allocdBlocks--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks++; +#endif + } + return FTL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_DeleteSectors */ +/* DESCRIPTION */ +/* marks range of logical pages that are deleted or about to be deleted */ +/* as not valid */ +/* */ +/*****************************************************************************/ +static void YAFTL_DeleteSectors(UInt32 lba, UInt32 count) +{ + UInt32 i, indexOfs; + UInt32 *indexPage = NULL; + UInt32 oldVpn, oldBlock, oldBlockValid; + UInt32 newZeroValid = 0, entry; + + if (yaFTL.cxtValid) { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + // Index: decrement valid in sb, and global validPages, update vpn, erase? + for (i = 0; i < count; i++) { + // Load index page if it's not valid +#if ENABLE_L2V_TREE + if(indexPage == NULL) + { + yaFTL.read_c.span = 0; + yaFTL.read_c.lba = lba + i; + L2V_Search(&yaFTL.read_c); + WMR_ASSERT(0 != yaFTL.read_c.span); + if (L2V_VPN_DEALLOC == yaFTL.read_c.vpn) + { + i += (yaFTL.read_c.span -1); + continue; + } + } +#endif // ENABLE_L2V_TREE + if (indexPage == NULL) + { + indexPage = IndexLoadClean(lba + i, &indexOfs, &entry); + } + + if(indexPage == NULL) + { + i += (yaFTL.indexPageRatio - (((lba + i) % yaFTL.indexPageRatio) + 1)); + continue; + } + + // Take care of the old + oldVpn = indexPage[indexOfs]; + oldBlockValid = 0xffffffff; + oldBlock = oldVpn / PAGES_PER_SUBLK; + if (0xffffffff != oldVpn) + { + yaFTL.seaState.data.validPages--; + WMR_ASSERT(0 != yaFTL.blockArray[oldBlock].validPagesDNo); + oldBlockValid = --yaFTL.blockArray[oldBlock].validPagesDNo; + indexPage[indexOfs] = 0xffffffff; + IndexMarkDirty(entry); +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages--; +#endif + } + indexOfs++; + + // Ready to erase? + if ((0 == oldBlockValid) + && (BLOCK_ALLOCATED == yaFTL.blockArray[oldBlock].status)) + { + makeErasable(oldBlock); + newZeroValid++; + } + + // Invalidate current index page if we've passed the end + if (indexOfs >= yaFTL.indexPageRatio) + { + indexPage = NULL; + } + } + +#if ENABLE_L2V_TREE + L2V_Update(lba, count, L2V_VPN_DEALLOC); +#endif // ENABLE_L2V_TREE +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Unmap */ +/* DESCRIPTION */ +/* spans trim */ +/* */ +/*****************************************************************************/ +static ANDStatus YAFTL_Unmap(FTLExtent_t *extents, UInt32 numExtents) +{ + while (numExtents--) + { + YAFTL_DeleteSectors((UInt32)extents->lba, (UInt32)extents->span); + extents++; + } + + return FTL_SUCCESS; +} + +#endif + +BOOL32 _verifyMetaData(UInt32 lpn, PageMeta_t * pmdPtr, UInt32 numOfPages) +{ + UInt32 i; + + for (i = 0; i < numOfPages; i++) + { + if (META_GET_LBA(&pmdPtr[i]) != (lpn + i)) + { +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Yaftl_read error .mismatch between lpn and metadata at lpn 0x%08x meta 0x%08x", lpn + i, META_GET_LBA(&pmdPtr[i])); +#else + WMR_PRINT(QUAL_FATAL, "Yaftl_read error .mismatch between lpn and metadata at lpn 0x%08x meta 0x%08x", lpn + i, META_GET_LBA(&pmdPtr[i])); +#endif + return FALSE32; + } + // Check for uECC mark + if (META_IS_UECC(&pmdPtr[i])) { + return FALSE32; + } + } + return TRUE32; +} + + + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Read */ +/* DESCRIPTION */ +/* reads out a range of consecutive logical pages */ +/* */ +/*****************************************************************************/ +//#include + +static Int32 +YAFTL_Read(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pBuf) +{ + UInt32 i, vpnOffset = 0; + UInt8 *currBatch = NULL; + UInt32 vPN /*,*tPtr=NULL*/; + UInt16 cacheIndexPtr; + UInt8 *currPage = pBuf; + Int32 status; + ANDStatus statusRet = FTL_SUCCESS; + UInt32 * vpnT = NULL; + UInt32 indexPageNo, indexPageSub, indexPage; + + if((pBuf == NULL) && (dwNumOfPages != 1)) + return FTL_CRITICAL_ERROR; +#ifdef AND_COLLECT_STATISTICS + if(pBuf != NULL) + stFTLStatistics.ddwFTLReadCnt++; + if((dwNumOfPages > 0) && (dwNumOfPages <= 8)) + { + stFTLStatistics.ddwRead[dwNumOfPages-1]++; + } + else + { + if(dwNumOfPages > 8) + stFTLStatistics.ddwReadOver8++; + } +#endif + /* take care of a simple case of reading single sector and then take it from there */ + if ((dwLpn + dwNumOfPages) >= yaFTL.logicalPartitionSize) + { + return FTL_CRITICAL_ERROR; + } + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(dwLpn, dwNumOfPages, pBuf); + } + + yaFTL.readBufferIndex = 0xffffffff; + + yaFTL.read_c.span = 0; + vpnT = yaFTL.multiReadvpN; + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + vpnT[0] = 0xffffffff; + } + for (i = 0; i < dwNumOfPages; i++, currPage += BYTES_PER_PAGE) + { +#if ENABLE_L2V_TREE + if (0 == yaFTL.read_c.span) { + yaFTL.read_c.lba = dwLpn + i; + L2V_Search(&yaFTL.read_c); + + } + WMR_ASSERT(0 != yaFTL.read_c.span); + + if (L2V_VPN_MISS != yaFTL.read_c.vpn) { + // Not missing from IC tree + if (L2V_VPN_DEALLOC != yaFTL.read_c.vpn) { + // Not deallocated + vPN = yaFTL.read_c.vpn; + if (yaFTL.read_c.vpn < L2V_VPN_SPECIAL) { + yaFTL.read_c.vpn++; + } + } else { + // Deallocated + vPN = 0xffffffff; + } + yaFTL.read_c.span--; + } else { + yaFTL.read_c.span--; + if (yaFTL.read_c.vpn < L2V_VPN_SPECIAL) { + yaFTL.read_c.vpn++; + } +#else // if not ENABLE_L2V_TREE: + if (1) { +#endif // !ENABLE_L2V_TREE + + // Missed first search... :( + indexPageNo = (dwLpn + i) / yaFTL.indexPageRatio; + indexPageSub = (dwLpn + i) % yaFTL.indexPageRatio; + indexPage = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexPtr = yaFTL.tocArray[indexPageNo].cacheIndex; + + if ((indexPage != 0xffffffff) || (cacheIndexPtr != 0xffff)) + { + /* Index page exists */ + if (cacheIndexPtr != 0xffff) + { + /* Index page is in index cache */ + vPN = yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub]; + if (yaFTL.indexCache[cacheIndexPtr].counter < YAFTL_INDEX_CACHE_COUNTER_LIMIT) + yaFTL.indexCache[cacheIndexPtr].counter++; + } + else + { + /* Index page exists , but it is not in index cache . Read it from flash to cache first */ + cacheIndexPtr = findFreeCacheEntry(); + + if (cacheIndexPtr != 0xffff) + { + status = (UInt8)_readPage(indexPage, (UInt8 *)(yaFTL.indexCache[cacheIndexPtr].indexPage), NULL, FALSE32, TRUE32, TRUE32); + if (status != FTL_SUCCESS) + { + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } +#ifndef AND_READONLY + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Failed Index read Page 0x%08x Status 0x%08x", indexPage, status); +#endif + return status; + } +#if ENABLE_L2V_TREE + PopulateFromIndexCache(indexPageNo, (UInt32*)yaFTL.indexCache[cacheIndexPtr].indexPage); +#endif // ENABLE_L2V_TREE + yaFTL.freeCachePages--; + yaFTL.indexCache[cacheIndexPtr].status = IC_BUSY_PAGE; + yaFTL.indexCache[cacheIndexPtr].counter = 1; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexPtr; + yaFTL.indexCache[cacheIndexPtr].tocEntry = indexPageNo; + vPN = yaFTL.indexCache[yaFTL.tocArray[indexPageNo].cacheIndex].indexPage[indexPageSub]; + } + else + { + if (yaFTL.readBufferIndex != indexPageNo) + { + status = (UInt8)_readPage(indexPage, (UInt8 *)yaFTL.tmpReadBuffer, NULL, FALSE32, TRUE32, TRUE32); + if (status != FTL_SUCCESS) + { + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } +#ifndef AND_READONLY + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Failed Index read Page 0x%08x Status 0x%08x", indexPage, status); +#endif + return status; + } + yaFTL.readBufferIndex = indexPageNo; + } + vPN = yaFTL.tmpReadBuffer[indexPageSub]; + } + } + } + else + { + /* Index page does not exist => page was never updated */ + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + vpnOffset = 0; + continue; + } + } + + // Translation valid--perform the read: + if (vPN != 0xffffffff) + { + vpnT[vpnOffset] = vPN; + vpnOffset++; + if (currBatch == NULL) + { + currBatch = currPage; + } + if (PAGES_PER_SUBLK == vpnOffset) + { + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + debug(READ, "Yaftl_read before readmulti1 how many 0x%x where 0x%x", vpnOffset, currBatch); + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + vpnOffset = 0; + currBatch = NULL; + } + } + else + { + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + debug(READ, "Yaftl_read before readmulti2 how many 0x%x where 0x%x", vpnOffset, currBatch); + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + vpnOffset = 0; + currBatch = NULL; + continue; + } + } + + if (vpnOffset != 0) + { + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + debug(READ, "Yaftl_read before readmulti how many 0x%x where 0x%x", vpnOffset, currBatch); + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + } + + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_USERDATA_ERROR; + } +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwPagesReadCnt += dwNumOfPages; +#endif +#ifndef AND_READONLY + if (yaFTL.readLimit == TRUE32) + { + if (yaFTL.blockArray[yaFTL.wrState.index.block].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + if ((yaFTL.blockArray[yaFTL.wrState.index.block].status == BLOCK_I_ALLOCATED) + || (yaFTL.blockArray[yaFTL.wrState.index.block].status == BLOCK_I_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[yaFTL.wrState.index.block].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + { + UInt16 sb = yaFTL.wrState.index.block; + + BTOC_Lock(sb); + YAFTL_GC_Index(yaFTL.wrState.index.block, TRUE32); + BTOC_Unlock(sb); + } + WMR_TRACE_IST_0(ReadDist, END); + + } + } + if (yaFTL.blockArray[yaFTL.wrState.data.block].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + if ((yaFTL.blockArray[yaFTL.wrState.data.block].status == BLOCK_ALLOCATED) + || (yaFTL.blockArray[yaFTL.wrState.data.block].status == BLOCK_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[yaFTL.wrState.data.block].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + { + UInt16 sb = yaFTL.wrState.data.block; + + BTOC_Lock(sb); + YAFTL_GC_Data(yaFTL.wrState.data.block, TRUE32); + BTOC_Unlock(sb); + } + WMR_TRACE_IST_0(ReadDist, END); + } + } + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + if ((yaFTL.blockArray[i].status == BLOCK_I_ALLOCATED) + || (yaFTL.blockArray[i].status == BLOCK_I_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[i].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + YAFTL_GC_Index(i, TRUE32); + WMR_TRACE_IST_0(ReadDist, END); + continue; + } + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) + || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[i].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + YAFTL_GC_Data(i, TRUE32); + WMR_TRACE_IST_0(ReadDist, END); + continue; + } + } + } + yaFTL.readLimit = FALSE32; + } + + // Periodic cxt save for ANDStats preservation + if ((yaFTL.periodicCxt.pagesWritten >= WRITE_CXT_UPDATE_THRESHOLD) || (yaFTL.periodicCxt.erases >= ERASE_CXT_UPDATE_THRESHOLD)) + { + YAFTL_WriteStats(); + } +#endif + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } + + return statusRet; +} + +#ifndef AND_READONLY +void IndexMarkDirty(UInt32 tocEntry) +{ + UInt32 cacheIndexOfs; + UInt32 indexPagePhy; + + if(tocEntry >= yaFTL.TOCtableEntriesNo) + return; + + cacheIndexOfs = yaFTL.tocArray[tocEntry].cacheIndex; + indexPagePhy = yaFTL.tocArray[tocEntry].indexPage; + + if(cacheIndexOfs >= yaFTL.indexCacheSize) + return; + + if (IC_DIRTY_PAGE == yaFTL.indexCache[cacheIndexOfs].status) + return; + + // Mark as dirty + yaFTL.indexCache[cacheIndexOfs].status = IC_DIRTY_PAGE; + + // Early out; nothing to account for + if (0xffffffff == indexPagePhy) + { + return; + } + + // Mark previous index page as invalid + yaFTL.blockArray[indexPagePhy / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[tocEntry].indexPage = 0xffffffff; +} + +UInt32* IndexLoadClean(UInt32 lba, UInt32 *indexOfs, UInt32 *d_tocEntry) +{ + UInt32 indexPageNo, indexPageSub; + UInt32 indexPagePhy; + UInt32 cacheIndexOfs, oldCacheIndexOfs; + UInt32 status; + PageMeta_t *md = yaFTL.meta_indexLoadDirty; + + *d_tocEntry = 0xffffffff; + + // Calculate which index page and offset within for this update + indexPageNo = lba / yaFTL.indexPageRatio; + indexPageSub = lba % yaFTL.indexPageRatio; + indexPagePhy = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexOfs = yaFTL.tocArray[indexPageNo].cacheIndex; + oldCacheIndexOfs = cacheIndexOfs; + // Set up return parameter + *indexOfs = indexPageSub; + + // Don't load unmapped regions + if ((0xffffffff == indexPagePhy) && (0xffff == cacheIndexOfs)) + { + // All sectors addressed are in deleted state + return NULL; + } + + // Find or create cache entry + if (0xffff == cacheIndexOfs) { + cacheIndexOfs = findFreeCacheEntry(); + if (cacheIndexOfs == 0xffff) { + cacheIndexOfs = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexOfs == 0xffff) { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("failed to evict index page from cache"); + } + } + WMR_MEMSET(yaFTL.indexCache[cacheIndexOfs].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.freeCachePages--; + status = _readPage(indexPagePhy, (UInt8 *)yaFTL.indexCache[cacheIndexOfs].indexPage, md, FALSE32, TRUE32, TRUE32); + //TODO: reconstruct index page by default, but be careful of coherency issues with prior tree update + if (status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("uECC index page in ILD: vpn 0x%x, indexPageNo %d", indexPagePhy, indexPageNo); // TODO: reconstruct + } + // Reset counter since we just pulled this in to the cache + yaFTL.indexCache[cacheIndexOfs].counter = 0; + yaFTL.indexCache[cacheIndexOfs].status = IC_BUSY_PAGE; + yaFTL.indexCache[cacheIndexOfs].tocEntry = indexPageNo; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexOfs; + } + + // Give back the pointer to the cached index page + *d_tocEntry = indexPageNo; + + return yaFTL.indexCache[cacheIndexOfs].indexPage; +} + +UInt32* IndexLoadDirty(UInt32 lba, UInt32 *indexOfs) +{ + UInt32 indexPageNo, indexPageSub; + UInt32 indexPagePhy; + UInt32 cacheIndexOfs, oldCacheIndexOfs; + UInt32 *indexPage; + UInt32 status; + PageMeta_t *md = yaFTL.meta_indexLoadDirty; + + // Calculate which index page and offset within for this update + indexPageNo = lba / yaFTL.indexPageRatio; + indexPageSub = lba % yaFTL.indexPageRatio; + indexPagePhy = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexOfs = yaFTL.tocArray[indexPageNo].cacheIndex; + oldCacheIndexOfs = cacheIndexOfs; + // Set up return parameter + *indexOfs = indexPageSub; + + // Find or create cache entry + if (0xffff == cacheIndexOfs) { + cacheIndexOfs = findFreeCacheEntry(); + if (cacheIndexOfs == 0xffff) { + cacheIndexOfs = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexOfs == 0xffff) { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("failed to evict index page from cache"); + } + } + WMR_MEMSET(yaFTL.indexCache[cacheIndexOfs].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.freeCachePages--; + // Reset counter since we just pulled this in to the cache + yaFTL.indexCache[cacheIndexOfs].counter = 0; + } + yaFTL.indexCache[cacheIndexOfs].tocEntry = indexPageNo; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexOfs; + + yaFTL.indexCache[cacheIndexOfs].status = IC_DIRTY_PAGE; + if (yaFTL.indexCache[cacheIndexOfs].counter < YAFTL_INDEX_CACHE_COUNTER_LIMIT) + yaFTL.indexCache[cacheIndexOfs].counter++; + indexPage = yaFTL.indexCache[cacheIndexOfs].indexPage; + + // Don't load unmapped regions + if (0xffffffff == indexPagePhy) { + // All sectors addressed are in deleted state + return indexPage; + } + + // Load index page + if (0xffff == oldCacheIndexOfs) { + status = _readPage(indexPagePhy, (UInt8 *)indexPage, md, FALSE32, TRUE32, TRUE32); + //TODO: reconstruct index page by default, but be careful of coherency issues with prior tree update + if (status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("uECC index page in ILD: vpn 0x%x, indexPageNo %d", indexPagePhy, indexPageNo); // TODO: reconstruct + } + } + + // Mark previous index page as invalid + yaFTL.blockArray[indexPagePhy / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[indexPageNo].indexPage = 0xffffffff; + + // Give back the pointer to the cached index page + return indexPage; +} +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Write */ +/* DESCRIPTION */ +/* writes a range of consecutive logical pages to flash */ +/* */ +/*****************************************************************************/ +static Int32 +YAFTL_Write(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pabDataBuf, BOOL32 isStatic) +{ + UInt8 *curPage; + PageMeta_t *mdPtr; + UInt32 lba, count; + UInt32 toMegaStripeEnd, toBlockEnd, thisCount, ofs, i; + UInt32 vpn, indexOfs, oldBlock; + UInt32 *indexPage; + // For recovering from program failure--restart the write at the beginning of + // the write, or the most recently crossed superblock boundary. + UInt32 blockStartLba, blockStartCnt; + UInt8 *blockStartBuf; + + // Invalidate context + if (yaFTL.cxtValid) { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + debug(WRITE, " YAFTL_Write[start] 0x%x 0x%x isStatic: %s", dwLpn, dwNumOfPages, (isStatic)?"YES":"NO"); +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLWriteCnt++; + if((dwNumOfPages > 0) && (dwNumOfPages <= 8)) + { + stFTLStatistics.ddwWrite[dwNumOfPages-1]++; + } + else + { + if(dwNumOfPages > 8) + stFTLStatistics.ddwWriteOver8++; + } +#endif + if ((dwLpn + dwNumOfPages) >= yaFTL.logicalPartitionSize) + { + return FTL_CRITICAL_ERROR; + } + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(dwLpn, dwNumOfPages, pabDataBuf); + } + + // Delete the sectors prior to write + YAFTL_DeleteSectors(dwLpn, dwNumOfPages); + + blockStartLba = dwLpn; + blockStartCnt = dwNumOfPages; + blockStartBuf = pabDataBuf; +recoverPfail: + // Restore counters + curPage = blockStartBuf; + lba = blockStartLba; + count = blockStartCnt; + + // Do garbage collection prior to the write + YAFTL_GC_PreWrite(count); + + mdPtr = yaFTL.writeMdPtr; + // Writes and tree/index update: + ofs = 0; + while (count) { + // Advance block? + if (yaFTL.wrState.data.nextPage >= (PAGES_PER_SUBLK - yaFTL.controlPageNo)) { + writeCurrentBlockTOC(1); + allocateBlock(yaFTL.wrState.data.block, 0, 1); + blockStartLba = lba; + blockStartCnt = count; + blockStartBuf = curPage; + } + + // How many this round? Do up to a megastripe, subtracting to align to stripe end. + toMegaStripeEnd = ((NUM_BANKS * YAFTL_WRITE_MAX_STRIPES) - (yaFTL.wrState.data.nextPage % NUM_BANKS)); + toBlockEnd = (PAGES_PER_SUBLK - yaFTL.controlPageNo - yaFTL.wrState.data.nextPage); + thisCount = WMR_MIN(count, WMR_MIN(toMegaStripeEnd, toBlockEnd)); + + // Generate metadata + SetupMeta_Data(mdPtr, lba, thisCount); + + // Write the data + vpn = (yaFTL.wrState.data.block * (UInt32)PAGES_PER_SUBLK) + yaFTL.wrState.data.nextPage; + if (!VFL_WriteMultiplePagesInVb(vpn, thisCount, curPage, (UInt8 *)mdPtr, TRUE32, FALSE32)) { + oldBlock = yaFTL.wrState.data.block; + if(addBlockToEraseNowList(oldBlock) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", oldBlock); + } + BTOC_Lock(oldBlock); + allocateBlock(oldBlock, 0, 1); + YAFTL_DeleteSectors(blockStartLba, blockStartCnt); + if (BLOCK_FREE != yaFTL.blockArray[oldBlock].status) { + // Only GC it if it wasn't taken care of by DeleteSectors + YAFTL_GC_Data(oldBlock, TRUE32); + } + BTOC_Unlock(oldBlock); + goto recoverPfail; + } + + // Update TOC: + for (i = 0; i < thisCount; i++) { + yaFTL.wrState.data.TOC[yaFTL.wrState.data.nextPage + i] = lba + i; + } + + // Tree: update +#if ENABLE_L2V_TREE + L2V_Update(lba, thisCount, vpn); +#endif // ENABLE_L2V_TREE + + // Index: decrement valid in sb, and global validPages, update vpn + indexPage = IndexLoadDirty(lba, &indexOfs); + for (i = 0; i < thisCount; i++) { + // Update vpn + indexPage[indexOfs] = vpn + i; + + // Next + indexOfs++; + if (indexOfs >= yaFTL.indexPageRatio) { + indexPage = IndexLoadDirty(lba + i + 1, &indexOfs); + } + } + + // Update counters + yaFTL.wrState.data.nextPage += thisCount; + yaFTL.seaState.data.validPages += thisCount; + yaFTL.blockArray[yaFTL.wrState.data.block].validPagesDNo += thisCount; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages += thisCount; +#endif + + // Next + lba += thisCount; + ofs += thisCount; + count -= thisCount; + curPage += (thisCount * BYTES_PER_PAGE); + } + + // Periodic cxt save for ANDStats preservation + stFTLStatistics.ddwPagesWrittenCnt += dwNumOfPages; + yaFTL.periodicCxt.pagesWritten += dwNumOfPages; + if ((yaFTL.periodicCxt.pagesWritten >= WRITE_CXT_UPDATE_THRESHOLD) || (yaFTL.periodicCxt.erases >= ERASE_CXT_UPDATE_THRESHOLD)) + { + YAFTL_WriteStats(); + } + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } + + return FTL_SUCCESS; +} + +#endif + + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Format */ +/* DESCRIPTION */ +/* performs low-level clean up of a flash */ +/* */ +/*****************************************************************************/ +#ifdef AND_COLLECT_STATISTICS +static ANDStatus getStats(UInt16 *cxtT) +{ + UInt16 currentCX = 0; + UInt16 i; + ANDStatus status = FTL_CRITICAL_ERROR; + WeaveSeq_t lastCX = 0; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + UInt8 *tBuff; + PageMeta_t *md = yaFTL.meta_getStats; + + debug(FORMAT, "[FTL:MSG] getStats[start] 0x%x", PAGES_PER_SUBLK); + + /* read out VFL_meta data . If it is not present execute full format . If it is present go and fetch "quick mount" info from CX area if it's valid .If not execute restore + For now we need to start from fresh media which means there is no quick mount info and all blocks are free . */ + /* Get CXT blocks from the VFL */ + if (buf == NULL) + { + return FTL_CRITICAL_ERROR; + } + + tBuff = buf->pData; + + if (cxtT[0] == 0xffff) + { + BUF_Release(buf); + return FTL_CRITICAL_ERROR; + } + + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + status = VFL_Read(cxtT[i] * PAGES_PER_SUBLK, buf, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (status != VFL_SUCCESS) + { + continue; + } + WMR_MEMCPY(md, buf->pSpare, sizeof(PageMeta_t)); + if(sizeof(WeaveSeq_t) <= 4) + { + if ((META_GET_WEAVESEQ(md) != 0xffffffff) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = (UInt32)META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; + } + } + else + { + if ((META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = (UInt32)META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; + } + } + } + + if (lastCX != 0) + { + debug(FORMAT, "getStats : currentCX is %d", currentCX); + } + else + { + debug(FORMAT, "[FTL:MSG] getStats could not find CXT at all "); + BUF_Release(buf); + return FTL_CRITICAL_ERROR; + } + + for (i = PAGES_PER_SUBLK; i > 0; i--) + { + status = VFL_Read((currentCX * PAGES_PER_SUBLK) + (i - 1), buf, TRUE32, FALSE32, NULL, NULL, FALSE32); + + if (status == VFL_SUCCESS) + { + if (WMR_MEMCMP(tBuff, CXT_VER, 4) == 0) + { + debug(FORMAT, "latest cxt is at offset 0x%x",(currentCX * PAGES_PER_SUBLK) + (i - 1)); + status = VFL_Read((currentCX * PAGES_PER_SUBLK) + (i - 1) + 1 + 2*yaFTL.controlPageNo, buf, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (status == VFL_SUCCESS) + { + debug(FORMAT, "getting stats at offset 0x%x", (currentCX * PAGES_PER_SUBLK) + (i - 1) + 1 + 2*yaFTL.controlPageNo); + _FTLSetStatisticsFromCxt(tBuff); + BUF_Release(buf); + return FTL_SUCCESS; + } + } + } + } + debug(FORMAT, "[FTL:MSG] getStats could not find CXT at all "); + BUF_Release(buf); + + return FTL_CRITICAL_ERROR; +} +#endif + +static ANDStatus YAFTL_Format(UInt32 dwOptions) +{ + UInt32 i, ftlType; + ANDStatus status, statStatus; + UInt16 cxtT[FTL_CXT_SECTION_SIZE]; + BOOL32 moveCxt = FALSE32; + + status = FTL_CRITICAL_ERROR; + debug(FORMAT, "[FTL:MSG] YAFTL_Format[start]"); +#ifdef AND_COLLECT_STATISTICS + WMR_MEMCPY(cxtT, VFL_GetFTLCxtVbn(), FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + + statStatus = getStats(cxtT); +#endif + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + status = VFL_Erase((UInt16)i, TRUE32); + } + + if(cxtT[0] != 0xffff) + { + for (i = 0; i < (UInt32)FTL_CXT_SECTION_SIZE; i++) + { + if(cxtT[i] >= FTL_AREA_SIZE) + { + debug(FORMAT, "[FTL:MSG] YAFTL_Format cxt 0x%x is out of range 0x%x",cxtT[i], FTL_AREA_SIZE); + VFL_Erase((UInt16)cxtT[i], TRUE32); + moveCxt = TRUE32; + } + } + if(moveCxt == TRUE32) + { + for (i = 0; i < (UInt32)FTL_CXT_SECTION_SIZE; i++) + { + cxtT[i] = i; + } + VFL_ChangeFTLCxtVbn(cxtT); + } + } + +#ifdef AND_COLLECT_STATISTICS + if (statStatus == FTL_SUCCESS) + { + yaFTL.currentCxtVpn = 0xffffffff; + yaFTL.currentCXTIndex = 0; + yaFTL.cxtValid = 0; + yaFTL.formatWasCalled = 1; + quickMountUpdate(FALSE32); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + } +#endif + if (status != FTL_SUCCESS) + { + return status; + } + debug(FORMAT, "[FTL:MSG] YAFTL_Format[end]"); + ftlType = FTL_TYPE_YAFTL; + VFL_SetStruct(AND_STRUCT_VFL_FTLTYPE, &ftlType, sizeof(UInt32)); + yaFTL.formatWasCalled = 1; + return FTL_SUCCESS; +} +#endif +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_WearLevel */ +/* DESCRIPTION */ +/* moves read-only blocks around */ +/* */ +/*****************************************************************************/ +static Int32 YAFTL_WearLevel(void) +{ + UInt16 i,bestCandidate = 0xffff; + UInt16 bestCount = 0xffff; + UInt8 erasedCount = 0; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwWearLevelCnt++; +#endif + + // Gap too big, or not our time yet? Exit. + if (yaFTL.wearLevel.pointOfNoReturn || (yaFTL.wearLevel.blocksSince < YAFTL_WEARLEVEL_PERIOD)) + { + for (i = 0; (i < FTL_AREA_SIZE) && (erasedCount < ERASE_IDLE_LIMIT); i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + return status; + } + + yaFTL.erasedBlockCount++; + erasedCount++; + yaFTL.blockArray[i].erasableCount++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + yaFTL.blockArray[i].eraseBeforeUse = 0; + } + } + return FTL_OUT_OF_RANGE_ERROR; + } + + WMR_TRACE_IST_0(WearLevel, START); + + // Find best candidate (least cycled block) + for (i = 0; i < FTL_AREA_SIZE; i++) + { + if (BLOCK_ALLOCATED != yaFTL.blockArray[i].status) + { + // Don't consider non-data blocks; erased blocks are ok, and index will take care of itself + continue; + } + + // Detect gap-too-big condition (aka pointOfNoReturn); + if ((yaFTL.blockArray[i].erasableCount + ERASE_COUNT_GAP_UPPER_LIMIT) < yaFTL.maxEraseCount) + { + debug(MISC, "\nYAFTL_WearLevel gap is too big . 0x%x maxerase 0x%x\n", yaFTL.blockArray[i].erasableCount, yaFTL.maxEraseCount); + yaFTL.wearLevel.pointOfNoReturn = TRUE32; + break; + } + + // Block at least GAP_LIMIT less than the maxErase? + if ((yaFTL.blockArray[i].erasableCount + ERASE_COUNT_GAP_LIMIT) < yaFTL.maxEraseCount) + { + if (yaFTL.blockArray[i].erasableCount < bestCount) + { + bestCandidate = i; + bestCount = yaFTL.blockArray[i].erasableCount; + } + } + } + + // Didn't find a candidate + if (0xffff == bestCandidate) + { + WMR_TRACE_IST_1(WearLevel, END, FTL_OUT_OF_RANGE_ERROR); + return FTL_OUT_OF_RANGE_ERROR; + } + + // Perform wear leveling + debug(MISC, "\nYAFTL_WearLevel @@@ block 0x%x blockerase 0x%x maxerase 0x%x\n", bestCandidate, yaFTL.blockArray[bestCandidate].erasableCount, yaFTL.maxEraseCount); + YAFTL_GC_Data(bestCandidate, TRUE32); + yaFTL.wearLevel.blocksSince -= YAFTL_WEARLEVEL_PERIOD; + + WMR_TRACE_IST_1(WearLevel, END, FTL_SUCCESS); + return FTL_SUCCESS; +} +#endif +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_GarbageCollect */ +/* DESCRIPTION */ +/* perfroms defragementation of a disk while system in idle time */ +/* */ +/*****************************************************************************/ +static BOOL32 YAFTL_GarbageCollect(void) +{ + return 1; +} +#endif +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_ShutdownNotify */ +/* DESCRIPTION */ +/* commits cached index pages as well as control information to flash */ +/* */ +/*****************************************************************************/ + +UInt16 how_many_updates = 0; + +static BOOL32 YAFTL_ShutdownNotify(BOOL32 boolMergeLogs) +{ + + flushIndexCache(1); + if(how_many_updates++ > MOVE_CXT_TRESHOLD ) + { + moveCXTarea(); + how_many_updates = 0; + } + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFlushCnt++; +#endif + + while (quickMountUpdate(FALSE32) != FTL_SUCCESS) + { + debug(ERROR, "YAFTL_flushquickmountupdate failed"); + } + + // Clear periodic context drop counters + yaFTL.periodicCxt.pagesWritten = 0; + yaFTL.periodicCxt.erases = 0; + + return 1; +} + +static BOOL32 YAFTL_WriteStats(void) +{ + BOOL32 result = TRUE32; + + if(how_many_updates++ > MOVE_CXT_TRESHOLD ) + { + moveCXTarea(); + how_many_updates = 0; + } + + if (yaFTL.cxtValid != 1) + { + if(quickMountUpdate(TRUE32) != FTL_SUCCESS) + { + debug(ERROR, "YAFTL_flushquickmountupdate failed"); + result = FALSE32; + } + else + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + } + + // Clear periodic context drop counters + yaFTL.periodicCxt.pagesWritten = 0; + yaFTL.periodicCxt.erases = 0; + + return result; +} +#endif + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_FreeMemory */ +/* DESCRIPTION */ +/* frees all allocated memory; called on error path in _Open, and _Close */ +/* */ +/*****************************************************************************/ +static void YAFTL_FreeMemory(void) +{ + // Free the zone + WMR_BufZone_Free(&yaFTL.BufZone); + WMR_BufZone_Free(&yaFTL.BufZone_IndexCache); + + // [TOC_SIZE] Table of content that contains location of index pages + // in flash and index cache + if (NULL != yaFTL.tocArray) { + WMR_FREE(yaFTL.tocArray, yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + } + // [INDEX_CACHE_SIZE] cached index pages + if (NULL != yaFTL.indexCache) { + WMR_FREE(yaFTL.indexCache, yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + } + // [YAFTL_NO_OF_BLOCKS] block information + if (NULL != yaFTL.blockArray) { + WMR_FREE(yaFTL.blockArray, FTL_AREA_SIZE * sizeof(BlockEntry)); + } + if (NULL != yaFTL.multiReadvpN) { + WMR_FREE(yaFTL.multiReadvpN, sizeof(UInt32) * PAGES_PER_SUBLK); + } + +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&stFTLStatistics, 0, sizeof(FTLStatistics)); +#endif // AND_COLLECT_STATISTICS + +#ifndef AND_READONLY + YAFTL_GC_Close(); +#endif + +#if ENABLE_L2V_TREE + L2V_Free(); +#endif // ENABLE_L2V_TREE + + BTOC_Close(); + + // Null out pointers + yaFTL.quickRestore_tBuff = NULL; + yaFTL.wrState.data.TOC = NULL; + yaFTL.wrState.index.TOC = NULL; + yaFTL.tmpReadBuffer = NULL; + yaFTL.restoreTOC = NULL; + yaFTL.meta_restoreIdx = NULL; + yaFTL.meta_restoreData = NULL; + yaFTL.meta_readCxt = NULL; + yaFTL.meta_quickRestore = NULL; + yaFTL.meta_invalidateCxt = NULL; + yaFTL.meta_writeCxt = NULL; + yaFTL.meta_restoreMountErase = NULL; + yaFTL.meta_restoreMount = NULL; + yaFTL.meta_clearEntryInCache = NULL; + yaFTL.meta_writeBTOC = NULL; + yaFTL.meta_indexLoadDirty = NULL; + yaFTL.meta_getStats = NULL; + yaFTL.meta_GetBlockTOC = NULL; + yaFTL.meta_IsDataPageCurrent = NULL; + yaFTL.meta_WriteZoneData = NULL; + yaFTL.tocArray = NULL; + yaFTL.indexCache = NULL; + yaFTL.blockArray = NULL; + yaFTL.writeMdPtr = NULL; + yaFTL.multiReadvpN = NULL; + yaFTL.readMdPtr = NULL; + yaFTL.singleMdPtr = NULL; +} +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Close */ +/* DESCRIPTION */ +/* frees up all the memory allocated by YAFTL tables */ +/* */ +/*****************************************************************************/ +static void YAFTL_Close(void) +{ + YAFTL_FreeMemory(); + WMR_MEMSET(&yaFTL_FTLDeviceInfo, 0, sizeof(FTLWMRDeviceInfo)); + WMR_MEMSET(&yaFTL_VFLFunctions, 0, sizeof(VFLFunctions)); + WMR_MEMSET(&yaFTL, 0, sizeof(yaFTL_t)); + yaftl_init_done = FALSE32; + +} + +#ifndef AND_READONLY + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _writeMultiPages */ +/* DESCRIPTION */ +/* writes a set of virtual pages */ +/* */ +/*****************************************************************************/ +BOOL32 _writeMultiPages(UInt16 vbn, UInt16 pageOffset, UInt16 wNumPagesToWrite, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp) +{ + BOOL32 status; + UInt32 vpn; + const BOOL32 bMovingUserData = bInternalOp && META_IS_DATA(mdPtr); + + debug(WRITE, "[FTL:MSG] writeMultiPages[start] 0x%x ", wNumPagesToWrite); + + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + vpn = (((UInt32)vbn * (UInt32)PAGES_PER_SUBLK) + (UInt32)pageOffset); + status = VFL_WriteMultiplePagesInVb(vpn, wNumPagesToWrite, pageData, (UInt8 *)mdPtr, TRUE32, bMovingUserData); + if (status) + { + return TRUE32; + } + else + { + WMR_PRINT(QUAL, "we got multiwrite failure at vbn %d\n", (UInt32) vbn); + return FALSE32; + } +} + +#endif + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _readMultiPages */ +/* DESCRIPTION */ +/* reads a set of virtual pages from flash */ +/* */ +/*****************************************************************************/ +BOOL32 _readMultiPages(UInt32 * padwVpn, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 bInternalOp, BOOL32 scrubOnUECC) +{ + BOOL32 status; + Int32 stat; + PageMeta_t *tempP = NULL; + UInt32 currentOffset, currentLen, i; + BOOL32 needsRefresh = FALSE32; + + debug(READ, " _readMultiPages[start] 0x%x ", wNumPagesToRead); + if (pbaSpare == NULL) + { + tempP = yaFTL.readMdPtr; + } + else + { + tempP = (PageMeta_t *)pbaSpare; + } + currentOffset = 0; + currentLen = wNumPagesToRead; + + while (currentLen > PAGES_PER_SUBLK) + { + for(i = 0; i < PAGES_PER_SUBLK; i++) + { + updateReadCounter((UInt16) padwVpn[currentOffset+i] / PAGES_PER_SUBLK); + } + + status = VFL_ReadScatteredPagesInVb(&(padwVpn[currentOffset]), PAGES_PER_SUBLK, &(pbaData[currentOffset * BYTES_PER_PAGE]), (UInt8 *)tempP, &needsRefresh, NULL, bInternalOp, &stat); + if (!status) + { + debug(ERROR, "we got read failure "); + status = TRUE32; + WMR_TRACE_IST_1(SingleReadFallback, START, stat); + for (i = 0; i < PAGES_PER_SUBLK; i++) + { + UInt32 current_vpn = padwVpn[currentOffset + i]; + stat = _readPage(current_vpn, &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + WMR_PRINT(QUAL, "read failure on vpn %d\n", current_vpn); + status = FALSE32; + } + } + WMR_TRACE_IST_1(SingleReadFallback, END, stat); + if (!status) + { + return FALSE32; + } + else + { + WMR_PRINT(QUAL_FATAL, "were able to overcome read failure\n"); + } + } + else + { + if(stat != FTL_SUCCESS) + return FALSE32; +#ifndef AND_READONLY + if( needsRefresh ) + { + WMR_PRINT(QUAL, "refresh is triggered\n"); + status = TRUE32; + for (i = 0; i < PAGES_PER_SUBLK; i++) + { + stat = _readPage(padwVpn[currentOffset + i], &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + status = FALSE32; + } + } + if (!status) + { + return FALSE32; + } + } +#endif + } + currentOffset += PAGES_PER_SUBLK; + currentLen -= PAGES_PER_SUBLK; + #ifndef AND_READONLY + /* Vadim - should not invalidate cxt while reading */ + /* cxtValid = 0; */ + if (yaFTL.blockArray[padwVpn[currentOffset] / PAGES_PER_SUBLK].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + yaFTL.readLimit = TRUE32; + WMR_TRACE_IST_1(ReadCountEnq, NONE, padwVpn[currentOffset] / PAGES_PER_SUBLK); + } + #endif // ! AND_READONLY + } + + if (currentLen > 0) + { + for(i = 0; i < currentLen; i++) + { + updateReadCounter((UInt16) padwVpn[currentOffset+i] / PAGES_PER_SUBLK); + } + +#ifndef AND_READONLY + if (yaFTL.blockArray[padwVpn[currentOffset] / PAGES_PER_SUBLK].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + yaFTL.readLimit = TRUE32; + WMR_TRACE_IST_1(ReadCountEnq, NONE, padwVpn[currentOffset] / PAGES_PER_SUBLK); + } +#endif // ! AND_READONLY + needsRefresh = FALSE32; + status = VFL_ReadScatteredPagesInVb(&(padwVpn[currentOffset]), (UInt16)currentLen, &(pbaData[currentOffset * BYTES_PER_PAGE]), (UInt8 *)tempP, &needsRefresh, NULL, bInternalOp, &stat); + if (status == FALSE32) + { + debug(ERROR, "we got read failure "); + status = TRUE32; + for (i = 0; i < currentLen; i++) + { + UInt32 current_vpn = padwVpn[currentOffset + i]; + stat = _readPage(current_vpn, &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + WMR_PRINT(QUAL, "read failure on vpn %d\n", current_vpn); + status = FALSE32; + } + } + + if (!status) + { + return FALSE32; + } + + WMR_PRINT(QUAL_FATAL, "were able to overcome read failure "); + } + else + { + if(stat != FTL_SUCCESS) + return FALSE32; +#ifndef AND_READONLY + if( needsRefresh ) + { + debug(ERROR, "refresh is triggered"); + status = TRUE32; + for (i = 0; i < currentLen; i++) + { + stat = _readPage(padwVpn[currentOffset + i], &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + status = FALSE32; + } + } + if (!status) + { + return FALSE32; + } + } +#endif + } + } + + return TRUE32; +} + +#ifndef AND_READONLY + +BOOL32 isBlockInEraseNowList(UInt16 blockNo) +{ + UInt8 i; + BOOL32 res = FALSE32; + + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + if(yaFTL.eraseNowList[i] == blockNo) + { + res = TRUE32; + break; + } + } + + return res; +} + +BOOL32 removeBlockFromEraseNowList(UInt16 blockNo) +{ + UInt8 i; + BOOL32 res = FALSE32; + + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + if(yaFTL.eraseNowList[i] == blockNo) + { + res = TRUE32; + yaFTL.eraseNowList[i] = 0xffff; + break; + } + } + + return res; +} + +BOOL32 addBlockToEraseNowList(UInt16 blockNo) +{ + UInt8 i; + BOOL32 res = FALSE32; + + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + if(yaFTL.eraseNowList[i] == blockNo) + { + res = TRUE32; + break; + } + if(yaFTL.eraseNowList[i] == 0xffff) + { + yaFTL.eraseNowList[i] = blockNo; + res = TRUE32; + break; + } + } + if(res == FALSE32) + { + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + UInt16 blockToCheck = yaFTL.eraseNowList[i]; + ANDStatus status; + + if(yaFTL.blockArray[blockToCheck].status == BLOCK_FREE) + { + if(yaFTL.blockArray[blockToCheck].eraseBeforeUse != 0) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(blockToCheck, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) blockToCheck, status); + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + yaFTL.blockArray[blockToCheck].eraseBeforeUse = 0; + yaFTL.blockArray[blockToCheck].erasableCount++; + yaFTL.periodicCxt.erases++; + if (yaFTL.blockArray[blockToCheck].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[blockToCheck].erasableCount; + } + } + yaFTL.eraseNowList[i] = blockNo; + res = TRUE32; + break; + } + } + } + return res; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _writePage */ +/* DESCRIPTION */ +/* writes sigle virtual page to flash */ +/* */ +/*****************************************************************************/ +Int32 _writePage(UInt32 vpn, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp) +{ + Buffer *buff; + Int32 status; + BOOL32 bMovingUserData; + + buff = BUF_Get(BUF_MAIN_AND_SPARE); + if (buff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + buff->pData = pageData; + if (mdPtr != NULL) + { + WMR_MEMCPY(buff->pSpare, mdPtr, sizeof(PageMeta_t)); + bMovingUserData = bInternalOp && META_IS_DATA(mdPtr); + } + else + { + bMovingUserData = FALSE32; + } + + status = VFL_Write(vpn, buff, TRUE32, bMovingUserData); + if (status != VFL_SUCCESS) + { + WMR_PRINT(QUAL, "we got write failure at vpn %d ", vpn); + if(addBlockToEraseNowList(vpn / PAGES_PER_SUBLK) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", vpn / PAGES_PER_SUBLK); + } + } + BUF_Release(buff); + return status; +} +#endif + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _readPage */ +/* DESCRIPTION */ +/* reads sigle virtual page from flash */ +/* */ +/*****************************************************************************/ +Int32 _readPage(UInt32 vpn, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 bMarkECCForScrub) +{ + Buffer buff; + long status; + BOOL32 needsRefresh = FALSE32; + + buff.pData = pageData; + if (mdPtr) + { + buff.pSpare = (UInt8 *)mdPtr; + } + else + { + buff.pSpare = (UInt8 *)yaFTL.singleMdPtr; + } + + status = VFL_Read(vpn, &buff, boolCleanCheck, bMarkECCForScrub, &needsRefresh, NULL, bInternalOp); + if ((status == VFL_CRITICAL_ERROR) || (status == VFL_U_ECC_ERROR)) + { + if (bMarkECCForScrub) + { + // This is more serious if we were expecting it to be good + WMR_PRINT(QUAL, "we got read failure at x%x block 0x%x block status x%x scrub %d\n", + vpn, vpn / PAGES_PER_SUBLK, yaFTL.blockArray[vpn / PAGES_PER_SUBLK].status, bMarkECCForScrub); +#ifndef AND_READONLY + if(addBlockToEraseNowList(vpn / PAGES_PER_SUBLK) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", vpn / PAGES_PER_SUBLK); + } +#endif + } + else + { + debug(ERROR, "we got read failure at x%x block 0x%x block status x%x scrub %d", + vpn, vpn / PAGES_PER_SUBLK, yaFTL.blockArray[vpn / PAGES_PER_SUBLK].status, bMarkECCForScrub); + } + status = FTL_CRITICAL_ERROR; + } + + updateReadCounter((UInt16) vpn / PAGES_PER_SUBLK); + + if (needsRefresh && bMarkECCForScrub) + { + WMR_PRINT(QUAL, "vfl suggests read refresh on vpn %d\n", vpn); + } +#ifndef AND_READONLY + if ((yaFTL.blockArray[vpn / PAGES_PER_SUBLK].pagesRead > YAFTL_READ_DISTURB_LIMIT) || (needsRefresh == TRUE32)) + { + yaFTL.readLimit = TRUE32; + if( needsRefresh ) + { + debug(ERROR, "refresh is triggered at vpn 0x%x\n",vpn); + yaFTL.blockArray[vpn / PAGES_PER_SUBLK].pagesRead = 0xffff; // !!! this is a prep for readDistrub handling + WMR_TRACE_IST_1(ReadRefreshEnq, NONE, vpn / PAGES_PER_SUBLK); + } + else + { + WMR_TRACE_IST_1(ReadCountEnq, NONE, vpn / PAGES_PER_SUBLK); + } + } +#endif // ! AND_READONLY + + return status; +} + +static BOOL32 YAFTL_ECBins(void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + UInt16 blockIdx; + FTLBinsStruct hdr; + const UInt32 kdwStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_EC_BINS; + + if (!yaFTL.blockArray) + { + return FALSE32; + } + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= kdwStructSize)) + { + const UInt32 max_bin_val = FTL_MAX_EC_BIN_VAL; + const UInt32 bin_size = FTL_EC_BIN_SIZE; + UInt32 size = *pdwStructSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_EC_BINS; + WMR_MEMSET(pvoidStructBuffer, 0, kdwStructSize); + WMR_FILL_STRUCT(pvoidStructBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < FTL_AREA_SIZE; ++blockIdx) + { + UInt32 index; + UInt16 usage; + void *cursor; + + if (yaFTL.blockArray[blockIdx].erasableCount >= max_bin_val) + { + index = FTL_NUM_EC_BINS - 1; + } + else + { + index = yaFTL.blockArray[blockIdx].erasableCount / bin_size; + } + + cursor = ((char *)pvoidStructBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (pdwStructSize) + { + *pdwStructSize = kdwStructSize; + boolRes = TRUE32; + } + + return boolRes; +} + +static BOOL32 YAFTL_RCBins(void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + UInt16 blockIdx; + FTLBinsStruct hdr; + const UInt32 kdwStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_RC_BINS; + + if (!yaFTL.blockArray) + { + return FALSE32; + } + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= kdwStructSize)) + { + const UInt32 max_bin_val = YAFTL_READ_DISTURB_LIMIT; + const UInt32 bin_size = FTL_RC_BIN_SIZE(max_bin_val); + UInt32 size = *pdwStructSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_RC_BINS; + WMR_MEMSET(pvoidStructBuffer, 0, kdwStructSize); + WMR_FILL_STRUCT(pvoidStructBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < FTL_AREA_SIZE; ++blockIdx) + { + UInt32 index; + UInt16 usage; + void *cursor; + + if (yaFTL.blockArray[blockIdx].pagesRead >= max_bin_val) + { + index = FTL_NUM_RC_BINS - 1; + } + else + { + index = yaFTL.blockArray[blockIdx].pagesRead / bin_size; + } + + cursor = ((char *)pvoidStructBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (pdwStructSize) + { + *pdwStructSize = kdwStructSize; + boolRes = TRUE32; + } + + return boolRes; +} + +static void fillUpTLBlockStructure(UInt32 blockNo, ANDFTLBlockStruct * tlBlockStruct) +{ + tlBlockStruct->blockSizeInLbas = PAGES_PER_SUBLK; + tlBlockStruct->validLbas = 0; + tlBlockStruct->blockType = 0; + switch (yaFTL.blockArray[blockNo].status) + { + case BLOCK_ALLOCATED: + case BLOCK_CURRENT: + case BLOCK_GC: + { + tlBlockStruct->blockType |= TL_BLOCK_DATA; + tlBlockStruct->validLbas = yaFTL.blockArray[blockNo].validPagesDNo; + break; + } + + case BLOCK_I_ALLOCATED: + case BLOCK_I_CURRENT: + case BLOCK_I_GC: + { + tlBlockStruct->blockType |= TL_BLOCK_INDEX; + tlBlockStruct->validLbas = yaFTL.blockArray[blockNo].validPagesINo; + break; + } + + case BLOCK_FREE: + { + tlBlockStruct->blockType |= TL_BLOCK_FREE; + break; + } + case BLOCK_CTX_CNTR: + case BLOCK_CTX_CURRENT: + tlBlockStruct->blockType |= TL_BLOCK_CXT; + break; + + default: + tlBlockStruct->blockType |= TL_BLOCK_UNKNOWN; + } +} + +static BOOL32 YAFTL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType) + { + case AND_STRUCT_FTL_GET_TYPE: + { + UInt8 bFTLType = FTL_TYPE_YAFTL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &bFTLType, sizeof(bFTLType)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_FTL_GET_FTL_STATS_SIZE: + { + UInt32 dwStatsSize = sizeof(FTLStatistics); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwStatsSize, sizeof(dwStatsSize)); + break; + } + + case AND_STRUCT_FTL_STATISTICS: + { +#if ENABLE_L2V_TREE + stFTLStatistics.ddwNodesFree = L2V.Pool.FreeCount; + stFTLStatistics.ddwNodesTotal = L2V_NODEPOOL_COUNT; +#endif //ENABLE_L2V_TREE + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stFTLStatistics, sizeof(stFTLStatistics)); + break; + } +#endif + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO_SIZE: + { + UInt32 dwFTLDevInfoSize = sizeof(FTLWMRDeviceInfo); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwFTLDevInfoSize, sizeof(dwFTLDevInfoSize)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &yaFTL_FTLDeviceInfo, sizeof(yaFTL_FTLDeviceInfo)); + + break; + } + + case AND_STRUCT_FTL_GETADDRESS: + { + ANDAddressStruct stAddr; + UInt32 dwAddrSize = sizeof(stAddr); + BOOL32 boolFillRes; + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= sizeof(stAddr))) + { + WMR_MEMCPY(&stAddr, pvoidStructBuffer, sizeof(stAddr)); + + if((YAFTL_Read(stAddr.dwLpn, 1, NULL) == FTL_SUCCESS) && (yaFTL.multiReadvpN[0] != 0xffffffff)) + { + stAddr.dwVpn = yaFTL.multiReadvpN[0]; + boolRes = VFL_GetStruct(AND_STRUCT_VFL_GETADDRESS, &stAddr, &dwAddrSize); + } + else + { + boolRes = FALSE32; + } + } + + boolFillRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stAddr, sizeof(stAddr)); + + if (boolRes) + { + boolRes = boolFillRes; + } + + break; + } + + case AND_STRUCT_FTL_SB_CYCLES: + { + UInt32 sbIndex; + UInt32 numBufEntries = (*pdwStructSize) / sizeof(UInt16); + UInt16 *sbEraseCnts = (UInt16 *) pvoidStructBuffer; + UInt32 numSBlks = (UInt32)FTL_AREA_SIZE; + + if((numSBlks != numBufEntries) || (sbEraseCnts == NULL)){ + boolRes = FALSE32; + break; + } + + for (sbIndex=0; sbIndex < numSBlks; sbIndex++){ + sbEraseCnts[sbIndex] = (UInt16) (yaFTL.blockArray[sbIndex].erasableCount); + } + + boolRes = TRUE32; + break; + } + +#ifndef AND_READONLY + case AND_FUNCTION_INDEX_CACHE_UPDATE: + { + UInt32 i; + + if (!pdwStructSize) + { + boolRes = FALSE32; + break; + } + + boolRes = TRUE32; // So we can fail if the backup reallocate fails + flushIndexCache(0); + //todo : make sure we update TOC to reflect that current cache is gone + WMR_BufZone_Free(&yaFTL.BufZone_IndexCache); + WMR_FREE(yaFTL.indexCache, yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); /* [INDEX_CACHE_SIZE] cached index pages */ + yaFTL.indexCacheSize = *pdwStructSize; + + ALLOCATE_DEFAULT_CACHE: + yaFTL.indexCache = (CacheIndexEntry *)WMR_MALLOC(yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + if (yaFTL.indexCache == NULL) + { + boolRes = FALSE32; + yaFTL.indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; + goto ALLOCATE_DEFAULT_CACHE; + } + + // Allocate index cache buffers + WMR_BufZone_Init(&yaFTL.BufZone_IndexCache); + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + // Pre-reserve + yaFTL.indexCache[i].indexPage = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone_IndexCache, BYTES_PER_PAGE); + } + + // Finish allocations + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BufZone_IndexCache)) + { + WMR_FREE(yaFTL.indexCache, yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + WMR_ASSERT(FALSE32 != boolRes); // Panics if the re-allocate fails + boolRes = FALSE32; + yaFTL.indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; + goto ALLOCATE_DEFAULT_CACHE; + } + + // Rebase and initialize + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + WMR_BufZone_Rebase(&yaFTL.BufZone_IndexCache, (void**)&yaFTL.indexCache[i].indexPage); + yaFTL.indexCache[i].status = FREE_CACHE_PAGE; + yaFTL.indexCache[i].tocEntry = 0xffff; + yaFTL.indexCache[i].counter = 0; + WMR_MEMSET(yaFTL.indexCache[i].indexPage, 0xff, BYTES_PER_PAGE); + } + + // Finish rebases + WMR_BufZone_FinishedRebases(&yaFTL.BufZone_IndexCache); + + while (quickMountUpdate(FALSE32) != FTL_SUCCESS) + { + debug(ERROR, "YAFTL_flushquickmountupdate failed"); + } +// debug(ERROR, "YAFTL_GetStruct : update cache size to %d done ",indexCacheSize); + yaFTL.freeCachePages = yaFTL.indexCacheSize; + + boolRes = TRUE32; + break; + } +#endif // ! AND_READONLY + + case AND_STRUCT_FTL_GET_FTL_EC_BINS: + { + boolRes = YAFTL_ECBins(pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_FTL_GET_FTL_RC_BINS: + { + boolRes = YAFTL_RCBins(pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_FTL_RECOMMEND_CONTENT_DELETION: + { + UInt32 data = 0; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &data, sizeof(data)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_BLOCK_COUNT: + { + UInt32 tlBlockCount = FTL_AREA_SIZE; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &tlBlockCount, sizeof(tlBlockCount)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_BLOCK_STAT: + { + UInt32 i, tmpBuffSize = *pdwStructSize, tmpChunkSize; + ANDFTLBlockStruct tempStruct; + UInt8 * tmpPtr = (UInt8 *)pvoidStructBuffer; + + if(tmpBuffSize >= (FTL_AREA_SIZE * sizeof(tempStruct))) + { + for(i = 0; (i < FTL_AREA_SIZE) && (tmpBuffSize >= sizeof(tempStruct)); i++, tmpBuffSize -= sizeof(tempStruct)) + { + fillUpTLBlockStructure(i, &tempStruct); + tmpChunkSize = tmpBuffSize; + boolRes = WMR_FILL_STRUCT(tmpPtr + (i * sizeof(ANDFTLBlockStruct)), &tmpChunkSize, &tempStruct, sizeof(tempStruct)); + } + } + break; + } + + default: + boolRes = FALSE32; + } + + return boolRes; +} +#ifdef AND_COLLECT_STATISTICS + +void _UpdateStatisticsCounters(UInt8 *pabSrc, void *pvoidStat, UInt32 dwSize) +{ + UInt32 dwIdx; + UInt64 * paddwStat = (UInt64 *)pvoidStat; + + for (dwIdx = 0; dwIdx < (dwSize / sizeof(UInt64)); dwIdx++) + { + UInt64 ddwTemp; + WMR_MEMCPY(&ddwTemp, &pabSrc[dwIdx * sizeof(UInt64)], sizeof(UInt64)); + paddwStat[dwIdx] = ddwTemp; //intentionally overwrite, not increment + } +} + +#ifndef AND_READONLY +static BOOL32 _FTLGetStatisticsToCxt(UInt8 * pabData) +{ + UInt32 dwStatBuffSize; + UInt32 dwStatVersion = AND_EXPORT_STRUCTURE_VERSION; + + UInt8 *pabCursor = pabData; + UInt8 *pabVersion = &pabData[BYTES_PER_PAGE - sizeof(UInt32)]; + + WMR_MEMSET(pabCursor, 0, BYTES_PER_PAGE); + + WMR_MEMCPY(pabCursor, &stFTLStatistics, sizeof(stFTLStatistics)); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_STATISTICS, pabCursor, &dwStatBuffSize); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_FILSTATISTICS, pabCursor, &dwStatBuffSize); + + // mark the statistics version + WMR_MEMCPY(pabVersion, &dwStatVersion, sizeof(UInt32)); + return TRUE32; +} +#endif //ifndef AND_READONLY + +static BOOL32 _FTLSetStatisticsFromCxt(UInt8 * pabData) +{ + UInt32 dwStatBuffSize; + Buffer *pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + UInt8 *pabCursor; + + if (!pBuff) + { + debug(ERROR, "BUF_Get failed in _FTLSetStatisticsFromCxt!\n"); + return FALSE32; + } + + pabCursor = pabData; + + _UpdateStatisticsCounters(pabCursor, &stFTLStatistics, sizeof(FTLStatistics)); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_STATISTICS, pBuff->pData, &dwStatBuffSize); + _UpdateStatisticsCounters(pabCursor, pBuff->pData, dwStatBuffSize); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + VFL_SetStruct(AND_STRUCT_VFL_STATISTICS, pBuff->pData, dwStatBuffSize); + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_FILSTATISTICS, pBuff->pData, &dwStatBuffSize); + _UpdateStatisticsCounters(pabCursor, pBuff->pData, dwStatBuffSize); + VFL_SetStruct(AND_STRUCT_VFL_FILSTATISTICS, pBuff->pData, dwStatBuffSize); + + BUF_Release(pBuff); + return TRUE32; +} + +#endif + +static UInt32 _getMinorVersion(void) +{ + return kYaftlMinorVersion; +} + +#ifndef AND_READONLY +// This function is stateless. Don't use stFTLDeviceInfo +static UInt32 yaftl_ConvertUserMBtoFTLSuperblocks(VFLFunctions *vfl, UInt32 user_mb) +{ + UInt32 ftl_virtual_blocks; + const UInt32 page_size = vfl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 pages_per_vb = vfl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + const UInt32 requested_pages = (user_mb * 1024) / (page_size / 1024); + + ftl_virtual_blocks = ((((requested_pages * 100) / DEFAULT_EXPO_RATIO)) / pages_per_vb) + FTL_CXT_SECTION_SIZE + DEFAULT_INDEX_CACHE_SIZE + 1; + + return ftl_virtual_blocks; +} +#endif //!AND_READONLY + +#if NAND_PPN +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_PPN_Register */ +/* DESCRIPTION */ +/* register YAFTL access functions */ +/* */ +/*****************************************************************************/ +static FTLFunctions _yaftl_functions = +{ + .Init = YAFTL_Init, + .Open = YAFTL_Open, + + .Read = YAFTL_Read, + .Close = YAFTL_Close, + .GetStruct = YAFTL_GetStruct, + .GetMinorVersion = _getMinorVersion, + +#ifndef AND_READONLY + .ConvertUserMBtoFTLSuperblocks = yaftl_ConvertUserMBtoFTLSuperblocks, + .Write = YAFTL_Write, + .Unmap = YAFTL_Unmap, + .Format = YAFTL_Format, + .WearLevel = YAFTL_WearLevel, + .GarbageCollect = YAFTL_GarbageCollect, + .ShutdownNotify = YAFTL_ShutdownNotify, + .WriteStats = YAFTL_WriteStats, +#endif +}; + +FTLFunctions *YAFTL_PPN_Register(void) +{ + return &_yaftl_functions; +} + +#elif NAND_RAW + +/*****************************************************************************/ +/* */ +/* NAME */ +/* registerYAFTL */ +/* DESCRIPTION */ +/* register YAFTL access functions */ +/* */ +/*****************************************************************************/ + +void YAFTL_Register(FTLFunctions * pFTLFunctions) +{ + pFTLFunctions->Init = YAFTL_Init; + pFTLFunctions->Open = YAFTL_Open; + + pFTLFunctions->Read = YAFTL_Read; + pFTLFunctions->Close = YAFTL_Close; + pFTLFunctions->GetStruct = YAFTL_GetStruct; + pFTLFunctions->GetMinorVersion = _getMinorVersion; + +#ifndef AND_READONLY + pFTLFunctions->ConvertUserMBtoFTLSuperblocks = yaftl_ConvertUserMBtoFTLSuperblocks; + pFTLFunctions->Write = YAFTL_Write; + pFTLFunctions->Unmap = YAFTL_Unmap; + pFTLFunctions->Format = YAFTL_Format; + pFTLFunctions->WearLevel = YAFTL_WearLevel; + pFTLFunctions->GarbageCollect = YAFTL_GarbageCollect; + pFTLFunctions->ShutdownNotify = YAFTL_ShutdownNotify; + pFTLFunctions->WriteStats = YAFTL_WriteStats; +#endif +} +#else +#error PPN or raw? +#endif + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTLTypes.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTLTypes.h new file mode 100644 index 0000000..da0e119 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTLTypes.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _YAFTLTYPES_H_ +#define _YAFTLTYPES_H_ + +#include "yaFTL_whoami.h" +#include "VFLBuffer.h" +#include "yaFTL_Defines.h" +#include "L2V/L2V_Extern.h" +#include "WMRBuf.h" +#include "yaFTL_meta.h" + +typedef struct +{ + // Info generated by CalcGlobal + UInt16 wPagesPerVb; /* the count of pages per virtual block */ + UInt16 wUserVbTotal; /* the total number of data virtual block */ + UInt32 dwUserPagesTotal; /* the total number of data sector */ + UInt16 wBytesPerPage; /* bytes per page (main) */ + UInt16 wNumOfBanks; /* the number of banks */ + UInt16 wBytesPerPageMeta; /* bytes per page (meta) */ +} FTLWMRDeviceInfo; + +#define PAGES_PER_SUBLK (yaFTL_FTLDeviceInfo.wPagesPerVb) +#define NUM_BANKS (yaFTL_FTLDeviceInfo.wNumOfBanks) +#define FTL_AREA_SIZE (yaFTL_FTLDeviceInfo.wUserVbTotal) +#define USER_PAGES_TOTAL (yaFTL_FTLDeviceInfo.dwUserPagesTotal) +#define BYTES_PER_PAGE (yaFTL_FTLDeviceInfo.wBytesPerPage) +#define BYTES_PER_PAGE_META (yaFTL_FTLDeviceInfo.wBytesPerPageMeta) +#define NUM_BANKS (yaFTL_FTLDeviceInfo.wNumOfBanks) + +typedef struct +{ +// UInt32 serialCounter; // serial allocation counter that would be used for restore +// UInt16 validPagesNo; // Number of valid pages in block + UInt32 erasableCount; + UInt16 validPagesDNo; + UInt16 validPagesINo; + UInt16 pagesRead; + UInt8 status; + UInt8 eraseBeforeUse; + UInt8 pagesReadSubCounter; +} BlockEntry; + +// TOCEntry: pointer to cache index if the given index page is in the cache, or pointer to NAND if not. +// P.S.: not related to BlockTOCs. +typedef struct +{ + UInt32 indexPage; // location on the flash + UInt16 cacheIndex; // 0xff means not cached +} TOCEntry; + +typedef struct +{ + UInt32 *indexPage; // pointer to the page address array + UInt32 tocEntry; // index of the TOCEntry + UInt16 counter; // number of hits on this cache + UInt16 status; // free/occupied/dirty +} CacheIndexEntry; + +typedef struct +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwFTLWriteCnt; + UInt64 ddwFTLReadCnt; + UInt64 ddwDataGCCnt; + UInt64 ddwIndexGCCnt; + UInt64 ddwEmptyGCDataCnt; /* case there is data to copy */ + UInt64 ddwEmptyGCIndexCnt; /* case there is data to copy */ + UInt64 ddwValidDataPages; + UInt64 ddwValidIndexPages; + UInt64 ddwFreeBlks; + UInt64 ddwFTLRestoreCnt; + UInt64 ddwReadDisturbHandleCall; + UInt64 ddwWearLevelCnt; + UInt64 ddwFlushCnt; + UInt64 ddwRefreshCnt; + UInt64 ddwRead[8]; + UInt64 ddwReadOver8; + UInt64 ddwWrite[8]; + UInt64 ddwWriteOver8; + UInt64 ddwNodesFree; + UInt64 ddwNodesTotal; +} FTLStatistics; + +#define FTL_STATISTICS_DESCREPTION { \ + "ddwPagesWrittenCnt", \ + "ddwPagesReadCnt", \ + "ddwFTLWriteCnt", \ + "ddwFTLReadCnt", \ + "ddwDataGCCnt", \ + "ddwIndexGCCnt", \ + "ddwEmptyGCDataCnt", \ + "ddwEmptyGCIndexCnt", \ + "ddwValidDataPages", \ + "ddwValidIndexPages", \ + "ddwFreeBlks", \ + "ddwFTLRestoreCnt", \ + "ddwReadDisturbHandleCall", \ + "ddwWearLevelCnt", \ + "ddwFlushCnt", \ + "ddwRefreshCnt", \ + "ddwRead1", \ + "ddwRead2", \ + "ddwRead3", \ + "ddwRead4", \ + "ddwRead5", \ + "ddwRead6", \ + "ddwRead7", \ + "ddwRead8", \ + "ddwReadOver8", \ + "ddwWrite1", \ + "ddwWrite2", \ + "ddwWrite3", \ + "ddwWrite4", \ + "ddwWrite5", \ + "ddwWrite6", \ + "ddwWrite7", \ + "ddwWrite8", \ + "ddwWriteOver8", \ + "ddwNodesFree", \ + "ddwNodesTotal", \ +} + +#define GCFIFO_DEPTH 16 +typedef struct +{ + UInt32 block[GCFIFO_DEPTH + 1]; + UInt32 head, tail; // head==tail means it is empty +} GC_Fifo_t; + +typedef enum + { + GCD_IDLE, + GCD_EVICT, + GCD_ERASE, + GCD_FIXINDEX_RETRY, + GCD_FIXDATA_RETRY, + } GCDState; + + +typedef struct +{ + // In: + UInt32 in_block; + + // Work FIFO for error handling + GC_Fifo_t workFifo; + + // Choose out: + UInt32 chosenBlock; + UInt32 chosenValid; + UInt32 chosenErases; + + // Buffers: + UInt32 outstandingAllocs; + Buffer *tmpB1, *tmpB2, *tmpB3; + UInt32 *TOCbuff; + UInt8 *pageBuffer; + + // GC zone: + UInt32 *vpns; + UInt8 *zone; + PageMeta_t *meta; + UInt32 curZoneSize; + UInt32 ueccCounter; + + // State: + GCDState state; + UInt32 curPage; + UInt32 pagesRange; + UInt32 pagesCopied; + Int32 gcDataAdjust; // only meaningful for data GC + + L2V_SearchCtx_t read_c; // Search context for GC translation +} GC_Ctx_t; + +#define ERASE_NOW_LIST_SIZE 5 + +typedef struct +{ + WMR_BufZone_t BufZone; // Buffer zone allocators + WMR_BufZone_t BufZone_IndexCache; // ... + UInt16 controlPageNo, indexPageRatio; /* TOC of each block contains Lpa for each page written to block */ + UInt32 indexSize; /* index size in blocks */ + UInt32 dataSize; + UInt32 logicalPartitionSize; /* partititon size in pages exposed to file system */ + UInt16 TOCtableEntriesNo; /* number of entries in index TOC table */ + + UInt16 freeCachePages; + UInt16 erasedBlockCount; + #ifndef AND_READONLY + UInt16 nextFreeCachePage; + UInt64 cxtAllocation; + UInt32 currentCXTIndex, FTLRestoreCnt; + UInt8 cxtEraseCounter; + UInt32 currentDBlockAllocationNo; + UInt8 cxtValid; + UInt8 formatWasCalled; + BOOL32 readLimit; + UInt16 eraseNowList[ERASE_NOW_LIST_SIZE]; + #endif + + struct + { + struct + { + UInt32 block; + UInt32 *TOC; + UInt16 nextPage; + WeaveSeq_t minWeaveSeq; + } data; + struct + { + UInt32 block; + UInt32 *TOC; + UInt16 nextPage; + WeaveSeq_t minWeaveSeq; + } index; + + WeaveSeq_t weaveSeq; + UInt32 lastBlock; + } wrState; + + struct + { + UInt32 size; + UInt32 curAge; + UInt32 free; + UInt32 isData; + UInt32 **BTOC; + UInt32 *sb; + Int32 *age; + WMR_BufZone_t BufZone; // Buffer zone allocator + + // For srcVpn: + UInt32 srcSize; + UInt32 curSrc; + UInt32 *srcSb; + UInt32 **srcVpn; + UInt32 isLocked; + } BTOCcache; + + struct + { + struct + { + UInt32 allocdBlocks; + Int32 freeBlocks; + UInt32 validPages; + } data; + struct + { + UInt32 allocdBlocks; + Int32 freeBlocks; + UInt32 validPages; + } index; + UInt32 freeBlocks; + BOOL32 distCheckable; + } seaState; + + struct + { + UInt32 blocksSince; + BOOL32 pointOfNoReturn; + } wearLevel; + + struct + { + UInt32 pagesWritten; + UInt32 erases; + } periodicCxt; + + TOCEntry *tocArray; /* [TOC_SIZE] Table of content that contains location of index pages in flash and index cache */ + CacheIndexEntry *indexCache; /* [INDEX_CACHE_SIZE] cached index pages */ + BlockEntry *blockArray; /* [YAFTL_NO_OF_BLOCKS] block information */ + UInt32 *restoreTOC; // blockTOC for restore + + PageMeta_t *meta_restoreIdx; + PageMeta_t *meta_restoreData; + PageMeta_t *meta_readCxt; + PageMeta_t *meta_quickRestore; + PageMeta_t *meta_invalidateCxt; + PageMeta_t *meta_writeCxt; + PageMeta_t *meta_restoreMountErase; + PageMeta_t *meta_restoreMount; + PageMeta_t *meta_clearEntryInCache; + PageMeta_t *meta_writeBTOC; + PageMeta_t *meta_indexLoadDirty; + PageMeta_t *meta_getStats; + PageMeta_t *meta_GetBlockTOC; + PageMeta_t *meta_IsDataPageCurrent; + PageMeta_t *meta_WriteZoneData; + + UInt8 *quickRestore_tBuff; + UInt32 *tmpReadBuffer; // = NULL; + UInt32 readBufferIndex; // = 0xffffffff; + PageMeta_t *writeMdPtr; // = NULL; + UInt32 *multiReadvpN; // = NULL; + PageMeta_t *readMdPtr; // = NULL; + PageMeta_t *singleMdPtr; + UInt32 cxtSize, cxtSizeTOC, cxtSizeBlockStatus, cxtSizeBlockRead, + cxtSizeBlockErase, cxtSizeValidPagesD, cxtSizeValidPagesI; + UInt32 currentCxtVpn; // = 0xffffffff; + UInt16 cxtTable[FTL_CXT_SECTION_SIZE]; + UInt32 maxEraseCount, minEraseCount; // = 0 + + UInt32 indexCacheSize; // = DEFAULT_INDEX_CACHE_SIZE; + UInt8 exportedRatio; // = DEFAULT_EXPO_RATIO; + + // Garbage collection structures + struct + { + UInt32 zoneSize; + GC_Ctx_t data; + GC_Ctx_t index; + WMR_BufZone_t BufZone; // Buffer zone allocator + PageMeta_t *meta_buf; + } gc; + + // Read search context + L2V_SearchCtx_t read_c; +} yaFTL_t; + +#endif /* _YAFTLTYPES_H_ */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.c new file mode 100644 index 0000000..4283472 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "yaFTL_whoami.h" +#include "WMRConfig.h" +#include "yaFTL_BTOC.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTL.h" +#include "yaFTLTypes.h" +#include "yaFTL_Defines.h" + +// Extern context struct +extern yaFTL_t yaFTL; +extern FTLWMRDeviceInfo yaFTL_FTLDeviceInfo; +extern Int32 _readPage(UInt32 vpn, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 scrubOnUECC); +extern ANDStatus invalidateCXT(void); + +BOOL32 BTOC_Init() +{ + UInt32 i; + + yaFTL.BTOCcache.size = YAFTL_BTOCCACHE_SIZE_PER * 2; + WMR_ASSERT(yaFTL.BTOCcache.size <= 32); + yaFTL.BTOCcache.srcSize = YAFTL_BTOCCACHE_SRCSIZE; + yaFTL.BTOCcache.curSrc = yaFTL.BTOCcache.srcSize-1; + + yaFTL.BTOCcache.curAge = 0; + yaFTL.BTOCcache.age = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.age) * yaFTL.BTOCcache.size); + yaFTL.BTOCcache.sb = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.sb) * yaFTL.BTOCcache.size); + yaFTL.BTOCcache.BTOC = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.BTOC) * yaFTL.BTOCcache.size); + yaFTL.BTOCcache.srcVpn = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.srcVpn) * yaFTL.BTOCcache.srcSize); + yaFTL.BTOCcache.srcSb = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.srcSb) * yaFTL.BTOCcache.srcSize); + yaFTL.BTOCcache.isLocked = 0; + + // Check for allocation failure + if ((NULL == yaFTL.BTOCcache.age) || (NULL == yaFTL.BTOCcache.sb) || (NULL == yaFTL.BTOCcache.BTOC) + || (NULL == yaFTL.BTOCcache.srcVpn) || (NULL == yaFTL.BTOCcache.srcSb)) + { + return FALSE32; + } + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + yaFTL.BTOCcache.sb[i] = 0xffffffff; + } + + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + yaFTL.BTOCcache.srcSb[i] = 0xffffffff; + yaFTL.BTOCcache.srcVpn[i] = WMR_MALLOC(sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + WMR_MEMSET(yaFTL.BTOCcache.srcVpn[i], 0xff, sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + } + + yaFTL.BTOCcache.free = (1 << yaFTL.BTOCcache.size) - 1; + yaFTL.BTOCcache.isData = (1 << YAFTL_BTOCCACHE_SIZE_PER) - 1; + + // Allocate buffers + WMR_BufZone_Init(&yaFTL.BTOCcache.BufZone); + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + yaFTL.BTOCcache.BTOC[i] = (UInt32*)WMR_Buf_Alloc_ForDMA(&yaFTL.BTOCcache.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + } + + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BTOCcache.BufZone)) { + return FALSE32; + } + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + WMR_BufZone_Rebase(&yaFTL.BTOCcache.BufZone, (void**)&yaFTL.BTOCcache.BTOC[i]); + } + + WMR_BufZone_FinishedRebases(&yaFTL.BTOCcache.BufZone); + + return TRUE32; +} + +void BTOC_Close() +{ + UInt32 i; + + WMR_BufZone_Free(&yaFTL.BTOCcache.BufZone); + + if (NULL != yaFTL.BTOCcache.age) + { + WMR_FREE(yaFTL.BTOCcache.age, sizeof(*yaFTL.BTOCcache.age) * yaFTL.BTOCcache.size); + } + if (NULL != yaFTL.BTOCcache.sb) + { + WMR_FREE(yaFTL.BTOCcache.sb, sizeof(*yaFTL.BTOCcache.sb) * yaFTL.BTOCcache.size); + } + if (NULL != yaFTL.BTOCcache.BTOC) + { + WMR_FREE(yaFTL.BTOCcache.BTOC, sizeof(*yaFTL.BTOCcache.BTOC) * yaFTL.BTOCcache.size); + } + // Free srcVpn memory + if (NULL != yaFTL.BTOCcache.srcSb) + { + WMR_FREE(yaFTL.BTOCcache.srcSb, sizeof(*yaFTL.BTOCcache.srcSb) * yaFTL.BTOCcache.srcSize); + } + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + WMR_FREE(yaFTL.BTOCcache.srcVpn[i], sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + } + if (NULL != yaFTL.BTOCcache.srcVpn) + { + WMR_FREE(yaFTL.BTOCcache.srcVpn, sizeof(*yaFTL.BTOCcache.srcVpn) * yaFTL.BTOCcache.srcSize); + } + + yaFTL.BTOCcache.age = NULL; + yaFTL.BTOCcache.sb = NULL; + yaFTL.BTOCcache.BTOC = NULL; + yaFTL.BTOCcache.srcSb = NULL; + yaFTL.BTOCcache.srcVpn = NULL; + + yaFTL.BTOCcache.size = 0; + + yaFTL.BTOCcache.srcSize = 0; +} + +void BTOC_BootFixup() +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if (0xfffffffd == yaFTL.BTOCcache.sb[i]) + { + yaFTL.BTOCcache.sb[i] = yaFTL.wrState.data.block; + } + if (0xfffffffe == yaFTL.BTOCcache.sb[i]) + { + yaFTL.BTOCcache.sb[i] = yaFTL.wrState.index.block; + } + } +} + +UInt32 *BTOC_Alloc(UInt32 sb, BOOL32 isData) +{ + UInt32 i, minIdx, isData32 = (isData ? 1 : 0); + Int32 minAge; + + // Get a srcVpn + yaFTL.BTOCcache.curSrc = (yaFTL.BTOCcache.curSrc + 1) % yaFTL.BTOCcache.srcSize; + yaFTL.BTOCcache.srcSb[yaFTL.BTOCcache.curSrc] = sb; + WMR_MEMSET(yaFTL.BTOCcache.srcVpn[yaFTL.BTOCcache.curSrc], 0xff, sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + + // Get a BTOC + yaFTL.BTOCcache.curAge++; + + minAge = 0x7fffffff; + minIdx = 0xffffffff; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if (((yaFTL.BTOCcache.isData & (1 << i)) == (isData32 << i)) + && (yaFTL.BTOCcache.free & (1 << i)) + && (yaFTL.BTOCcache.age[i] < minAge) + && ((yaFTL.BTOCcache.isLocked & (1 << i)) == 0)) + { + minAge = yaFTL.BTOCcache.age[i]; + minIdx = i; + } + } + + if (0xffffffff != minIdx) { + yaFTL.BTOCcache.free &= ~(1 << minIdx); + yaFTL.BTOCcache.sb[minIdx] = sb; + yaFTL.BTOCcache.age[minIdx] = yaFTL.BTOCcache.curAge; + return yaFTL.BTOCcache.BTOC[minIdx]; + } +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't allocate a BTOC"); +#endif + return NULL; +} + +UInt32 BTOC_GetSrc(UInt32 destVpn) +{ + UInt32 i, sb, idx; + + sb = destVpn / PAGES_PER_SUBLK; + idx = destVpn % PAGES_PER_SUBLK; + + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + if (sb == yaFTL.BTOCcache.srcSb[i]) { + return yaFTL.BTOCcache.srcVpn[i][idx]; + } + } + + return 0xffffffff; +} + +void BTOC_SetSrc(UInt32 destVpn, UInt32 srcVpn) +{ + UInt32 i, sb, idx; + + sb = destVpn / PAGES_PER_SUBLK; + idx = destVpn % PAGES_PER_SUBLK; + + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + if (sb == yaFTL.BTOCcache.srcSb[i]) { + yaFTL.BTOCcache.srcVpn[i][idx] = srcVpn; + } + } +} + +void BTOC_Dealloc(UInt32 *BTOC) +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if (BTOC == yaFTL.BTOCcache.BTOC[i]) + { + yaFTL.BTOCcache.free |= (1 << i); + return; + } + } +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't deallocate BTOC: 0x%x", BTOC); +#endif +} + +UInt32 *BTOC_Search(UInt32 sb, BOOL32 isData) +{ + UInt32 i, isData32 = (isData ? 1 : 0); + Int32 maxAge = -1; + UInt32 *best = NULL; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if ((yaFTL.BTOCcache.sb[i] == sb) && (yaFTL.BTOCcache.age[i] > maxAge) && ((yaFTL.BTOCcache.isData & (1 << i)) == (isData32 << i))) + { + maxAge = yaFTL.BTOCcache.age[i]; + best = yaFTL.BTOCcache.BTOC[i]; + } + } + + return best; +} + +void BTOC_Lock(UInt32 sb) +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if ((yaFTL.BTOCcache.sb[i] == sb) && ((yaFTL.BTOCcache.free & (1 << i)) == 0)) + { + yaFTL.BTOCcache.isLocked |= (1 << i); + break; + } + } + +} + +void BTOC_Unlock(UInt32 sb) +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if ((yaFTL.BTOCcache.sb[i] == sb) && (yaFTL.BTOCcache.isLocked & (1 << i))) + { + yaFTL.BTOCcache.isLocked &= ~(1 << i); + break; + } + } + +} + +ANDStatus BTOC_Read(UInt32 vpn, UInt32 *bTOC, PageMeta_t *mdPtr, BOOL32 val, BOOL32 scrubOnUECC, UInt32 upperBound) +{ + UInt16 i; + ANDStatus status = FTL_CRITICAL_ERROR; + + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _readPage(vpn + i, ((UInt8 *)bTOC) + (i * BYTES_PER_PAGE), mdPtr, val, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + break; + } + } + if (status == FTL_SUCCESS) + { + UInt32 * tmpPtr = (UInt32 *)bTOC; + for(i = 0; i < ((yaFTL.controlPageNo * BYTES_PER_PAGE) >> 2);i++) + if(tmpPtr[i] >= upperBound) + { + tmpPtr[i] = 0xffffffff; + } + } + return status; +} + + +void BTOC_SetAll(UInt32 *bTOC, UInt8 value) +{ + WMR_MEMSET(bTOC, value, yaFTL.controlPageNo * BYTES_PER_PAGE); +} + + +void BTOC_Copy(UInt32 *left, UInt32 *right, UInt32 upperBound) +{ + UInt16 i; + for(i = 0; i < ((yaFTL.controlPageNo * BYTES_PER_PAGE) >> 2);i++) + if(right[i] >= upperBound) + { + left[i] = 0xffffffff; + } + else + { + left[i] = right[i]; + } +} + + +UInt32 BTOC_Get(UInt32 *bTOC, UInt32 offset, UInt32 upperBound) +{ + if(bTOC[offset] >= upperBound) + { + return 0xffffffff; + } + else + { + return bTOC[offset]; + } +} + + +UInt32 BTOC_Set(UInt32 *bTOC, UInt32 offset, UInt32 val, UInt32 upperBound) +{ + if(val >= upperBound) + { + bTOC[offset] = 0xffffffff; + } + else + { + bTOC[offset] = val; + } + return val; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.h new file mode 100644 index 0000000..41a2653 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_BTOC.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_BTOC_H__ +#define __YAFTL_BTOC_H__ + +// Includes +#include "yaFTL_whoami.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "yaFTLTypes.h" +#include "yaFTL_meta.h" + +// Defines and types declared elsewhere + +// Prototypes: + +// BTOC init/alloc/dealloc +extern BOOL32 BTOC_Init(void); +extern void BTOC_BootFixup(void); +extern void BTOC_Close(void); +extern UInt32 *BTOC_Alloc(UInt32 sb, BOOL32 isData); +extern void BTOC_Dealloc(UInt32 *BTOC); +extern UInt32 *BTOC_Search(UInt32 sb, BOOL32 isData); +extern void BTOC_Lock(UInt32 sb); +extern void BTOC_Unlock(UInt32 sb); + +// Read +extern ANDStatus BTOC_Read(UInt32 vpn, UInt32 *bTOC, PageMeta_t *mdPtr, BOOL32 val, BOOL32 scrubOnUECC, UInt32 upperBound); + +// Src for GC +extern void BTOC_SetSrc(UInt32 destVpn, UInt32 srcVpn); +extern UInt32 BTOC_GetSrc(UInt32 destVpn); + +// Getters/setters +extern void BTOC_SetAll(UInt32 *bTOC, UInt8 value); +extern UInt32 BTOC_Get(UInt32 *bTOC, UInt32 offset, UInt32 upperBound); +extern UInt32 BTOC_Set(UInt32 *bTOC, UInt32 offset, UInt32 val, UInt32 upperBound); + +// Copy +extern void BTOC_Copy(UInt32 *left, UInt32 *right, UInt32 upperBound); + +#endif // ----- #ifndef __YAFTL_BTOC_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_Defines.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_Defines.h new file mode 100644 index 0000000..91b91c5 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_Defines.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_DEFINES_H__ +#define __YAFTL_DEFINES_H__ + + +#define YAFTLDBG_INIT (1 << 0) +#define YAFTLDBG_FORMAT (1 << 1) +#define YAFTLDBG_READ (1 << 2) +#define YAFTLDBG_WRITE (1 << 3) +#define YAFTLDBG_ERASE (1 << 4) +#define YAFTLDBG_MISC (1 << 5) +#define YAFTLDBG_ERROR (1 << 6) +#define YAFTLDBG_OPEN (1 << 7) +#define YAFTLDBG_INFO (1 << 8) + +//#define YAFTL_DEBUG (YAFTLDBG_INIT | YAFTLDBG_ERROR | YAFTLDBG_INFO) +#define YAFTL_DEBUG (YAFTLDBG_ERROR) +#ifdef YAFTL_DEBUG +#define YAFTL_ENABLE_DEBUG_PRINT (0xff) + +# define debug(fac, fmt, args ...) \ + do { \ + if (YAFTLDBG_ ## fac & YAFTL_DEBUG & YAFTL_ENABLE_DEBUG_PRINT) { \ + _WMR_PRINT("yaFTL::%s(l:%d): " fmt "\n", __FUNCTION__, __LINE__, ## args); \ + } \ + } while (0) +#else +# define debug(fac, fmt, args ...) do { } while (0) +#endif + +#define FREE_BLK_TRH (5) /* number of units we require to be avaiable at any time */ +#define INDEX_AREA (1) /* block belongs to Index area */ +#define DATA_AREA (2) /* block belongs to data area */ +#define FREE_I_BLOCK_TRS (2) /* minimum free blocks within index area */ +#define DEFAULT_INDEX_CACHE_SIZE (10) /* index cached pages */ +#define INDEX_BLOCKS_RATIO (3) /* ratio of index area in flash to required index area by flash size */ +#define DEFAULT_EXPO_RATIO (99) /* percentage of data area exposed to file system */ +#define CXT_ERASE_LIMIT (30) + + +#define IC_DIRTY_PAGE 1 +#define IC_BUSY_PAGE 2 +#define FREE_CACHE_PAGE 0xffff + +#define BLOCK_FREE (0xFF) /* block marked as free */ +#define BLOCK_ALLOCATED (1) /* block marked as allocated for data area */ +#define BLOCK_CURRENT (4) /* block marked as current in data area */ + +#define BLOCK_GC (8) /* block in data area goes through GC process */ + +#define BLOCK_I_FREE (0xFF) /* block marked as free */ +#define BLOCK_I_CURRENT (32) /* block marked as current index block */ +#define BLOCK_I_ALLOCATED (64) /* block marked as idex block */ +#define BLOCK_I_GC (128) /* block in index area goes through GC process */ +#define BLOCK_TO_BE_ERASED (0x1) /* erase block before use . make sure the block is not erased before current block is closed */ +#define BLOCK_TO_BE_ERASED_ALIGNED_DATA (0x2) /* erase block before use . make sure the block is not erased before current block is closed */ +#define BLOCK_TO_BE_ERASED_ALIGNED_INDEX (0x4) /* erase block before use . make sure the block is not erased before current block is closed */ +#define BLOCK_READ_SCATTER (0x8) /* mark a block as being used in multi-read operation */ +#define BLOCK_TO_BE_MOVED (0x80) /* use it as an idication that block is to be refreshed after full mount is complete due to UECCs */ + +#define ERASE_IDLE_LIMIT (5) /* number of free blocks to be erased in idle time */ + +#define BLOCK_CTX_CNTR (2) /* block marked as CXT */ +#define BLOCK_CTX_CURRENT (16) /* block marked as current CXT */ +#define INDEX_PAGE_MARK (0x80000000) /* to be defined */ + +#define YAFTL_READ_DISTURB_LIMIT YAFTL_RC_THRESHOLD /* read disturb limit */ + +#define MIN_RESTORE_BUFFER (0x10000) +#define MAX_RESTORE_BUFFER (0x200000) +#define YAFTL_WEARLEVEL_PERIOD 30 +#define ERASE_COUNT_GAP_LIMIT 100 +#define ERASE_COUNT_GAP_UPPER_LIMIT 500 +#define STATIC_WEARLEVEL_TRIGGER 1000 +#define NAND_MOUNT_INDEX_SIZE 1000 +#define YAFTL_WRITE_MAX_STRIPES 32 +#define YAFTL_INDEX_CACHE_COUNTER_LIMIT 0xFFFF +#define PAGES_READ_SUB_COUNTER_LIMIT YAFTL_RC_MULTIPLIER + +// GCZONE_DOUBLEUPTO defines the point up to which we will multiply banks to. +// It is similar to setting a minimum of 16, but works with non-pow-2 configs. +#define GCZONE_DOUBLEUPTO 16 +#define YAFTL_GC_RATIO_SCALAR 4 + +// Maximum number of TOC pages/block to support +#define MAX_TOC_PAGES 4 +#define YAFTL_BTOCCACHE_SIZE_PER 2 +#define YAFTL_BTOCCACHE_SRCSIZE 2 + +// make the function pointers in vfl struct look like the old vfl functions +#ifndef AND_READONLY +#define VFL_Format (yaFTL_VFLFunctions.Format) +#define VFL_Write (yaFTL_VFLFunctions.WriteSinglePage) +#define VFL_Erase (yaFTL_VFLFunctions.Erase) +#define VFL_ChangeFTLCxtVbn (yaFTL_VFLFunctions.ChangeFTLCxtVbn) +#define VFL_WriteMultiplePagesInVb (yaFTL_VFLFunctions.WriteMultiplePagesInVb) +#endif // ! AND_READONLY +#define VFL_Init (yaFTL_VFLFunctions.Init) +#define VFL_Open (yaFTL_VFLFunctions.Open) +#define VFL_Close (yaFTL_VFLFunctions.Close) +#define VFL_ReadMultiplePagesInVb (yaFTL_VFLFunctions.ReadMultiplePagesInVb) +#define VFL_ReadScatteredPagesInVb (yaFTL_VFLFunctions.ReadScatteredPagesInVb) +#define VFL_Read (yaFTL_VFLFunctions.ReadSinglePage) +#define VFL_GetFTLCxtVbn (yaFTL_VFLFunctions.GetFTLCxtVbn) +//#define VFL_GetAddress (yaFTL_VFLFunctions.GetAddress) +#define VFL_GetDeviceInfo (yaFTL_VFLFunctions.GetDeviceInfo) +#define VFL_GetStruct (yaFTL_VFLFunctions.GetStruct) +#define VFL_SetStruct (yaFTL_VFLFunctions.SetStruct) + +#endif // ----- #ifndef _YAFTL_DEFINES_H__INC ----- + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.c new file mode 100644 index 0000000..1d4b52e --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.c @@ -0,0 +1,1716 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define AND_TRACE_LAYER FTL + +#include "yaFTL_whoami.h" +#include "yaFTL_gc.h" +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTL.h" +#include "yaFTLTypes.h" +#include "yaFTL_Defines.h" +#include "yaFTL_BTOC.h" +#include "L2V/L2V_Extern.h" +#include "WMRFeatures.h" +#ifndef ENABLE_L2V_TREE +#error ENABLE_L2V_TREE must be set to 0 or 1 in WMRFeatures.h +#endif + +#ifndef AND_READONLY + +// Prototypes +ANDStatus YAFTL_GC_Index(UInt32 block, BOOL32 scrubOnUECC); +ANDStatus YAFTL_GC_Data(UInt32 block, BOOL32 scrubOnUECC); + +static ANDStatus GCMachine_Data(Int32 writeSize, BOOL32 scrubOnUECC); +static void ChooseIndexSB(void); +static void ChooseDataSB(void); +static ANDStatus EraseIndex(UInt32 block); +static ANDStatus EraseData(UInt32 block); +static ANDStatus GetBlockTOC(GC_Ctx_t *c, BOOL32 srcubOnUECC, UInt32 upperBound, UInt32 *ueccCounter); +static void SanityCheckValid(GC_Ctx_t *c); +static ANDStatus EvictIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC); +static ANDStatus EvictData(UInt32 minAmount, BOOL32 scrubOnUECC); +static ANDStatus ReadZone(GC_Ctx_t *c, BOOL32 index, BOOL32 scrubOnUECC); +static ANDStatus WriteZoneData(GC_Ctx_t *c, BOOL32 scrubOnUECC); +static ANDStatus WriteZoneIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC); + +// Externs, from yAFTL.c: to be cleaned up into a common header/source +#ifdef AND_COLLECT_STATISTICS +extern FTLStatistics stFTLStatistics; +#endif +extern yaFTL_t yaFTL; +extern VFLFunctions yaFTL_VFLFunctions; +extern FTLWMRDeviceInfo yaFTL_FTLDeviceInfo; +extern UInt16 findFreeCacheEntry(void); +extern UInt16 clearEntryInCache(UInt8 flag, UInt16 candidate, UInt8 flush); +extern UInt32 allocateBlock(UInt32 blockNo, UInt8 flag, UInt8 type); +extern Int32 _readPage(UInt32 vpn, UInt8 *pageData, + PageMeta_t * pMeta, + BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 bMarkECCForScrub); +extern BOOL32 _readMultiPages(UInt32 * padwVpn, + UInt16 wNumPagesToRead, UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 bInternalOp, BOOL32 scrubOnUECC); +extern BOOL32 _writeMultiPages(UInt16 vbn, UInt16 pageOffset, + UInt16 wNumPagesToWrite, UInt8 *pageData, + PageMeta_t *mdPtr, + BOOL32 bInternalOp); +extern ANDStatus writeCurrentBlockTOC(UInt8 type); +extern UInt16 createTOClookUP(UInt32 *TOCarray, UInt16 *lookUParray, UInt16 arrayLn); +extern ANDStatus invalidateCXT(void); +extern BOOL32 isBlockInEraseNowList(UInt16 blockNo); +extern BOOL32 removeBlockFromEraseNowList(UInt16 blockNo); +extern BOOL32 addBlockToEraseNowList(UInt16 blockNo); + +// Defines +#define FREE_BLK_TRH_UPDATED 4 //FREE_BLK_TRH +#define FREE_BLK_GAP 2 +#define lowData(adjust) (((yaFTL.seaState.data.freeBlocks*PAGES_PER_SUBLK)+yaFTL.gc.data.gcDataAdjust) < (Int32)(((FREE_BLK_TRH_UPDATED + FREE_BLK_GAP) * PAGES_PER_SUBLK) + (adjust))) +#define dangerousData(adjust) ((((yaFTL.seaState.data.freeBlocks*PAGES_PER_SUBLK)+yaFTL.gc.data.gcDataAdjust) < (Int32)((FREE_BLK_TRH_UPDATED * PAGES_PER_SUBLK) + (adjust))) || ((yaFTL.seaState.data.allocdBlocks + FREE_BLK_TRH) > yaFTL.dataSize)) +#define dangerousIndex ((yaFTL.seaState.index.freeBlocks < (Int32)FREE_I_BLOCK_TRS) || ((yaFTL.seaState.index.allocdBlocks + FREE_I_BLOCK_TRS) > yaFTL.indexSize)) + +// Debug self-consistency checks +#define SELFCONSISTENCY_CHECKS 0 +#if SELFCONSISTENCY_CHECKS + +//SELFCONSISTENCY_CHECKS==1 +void CheckDataCounts(void) +{ + UInt32 i, sum = 0; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + sum += yaFTL.blockArray[i].validPagesDNo; + } + WMR_ASSERT(sum == yaFTL.seaState.data.validPages); +} + +//SELFCONSISTENCY_CHECKS==1 +static UInt32 ValidSnapshot[8192]; + +//SELFCONSISTENCY_CHECKS==1 +void SaveValids() +{ + UInt32 i; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + ValidSnapshot[i] = yaFTL.blockArray[i].validPagesDNo; + } +} + +//SELFCONSISTENCY_CHECKS==1 +void CheckValids() +{ + UInt32 i; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + WMR_ASSERT(ValidSnapshot[i] == yaFTL.blockArray[i].validPagesDNo); + } +} + +//SELFCONSISTENCY_CHECKS==1 +void CheckBlockDist() +{ + UInt32 i, D, I, free; + BOOL32 err = FALSE32; + + // Don't check during GC of power-on restore + if (!yaFTL.seaState.distCheckable) + return; + + D = I = free = 0; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + switch (yaFTL.blockArray[i].status) + { + case BLOCK_ALLOCATED: + case BLOCK_CURRENT: + case BLOCK_GC: + D++; + break; + + case BLOCK_I_ALLOCATED: + case BLOCK_I_CURRENT: + I++; + break; + + case BLOCK_FREE: + free++; + break; + + case BLOCK_I_GC: + // Should never get here, since I_GC is monolithic and we should only call this routine before or after + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("BLOCK_I_GC in CheckBlockDist()"); + break; + } + } + + if (!((D == yaFTL.seaState.data.allocdBlocks) || (D == (yaFTL.seaState.data.allocdBlocks + 1)))) + { + WMR_PRINT(ERROR, "D err\n"); + err = TRUE32; + } + if (!((I == yaFTL.seaState.index.allocdBlocks) || (I == (yaFTL.seaState.index.allocdBlocks + 1)))) + { + WMR_PRINT(ERROR, "I err\n"); + err = TRUE32; + } + if ((free != (UInt32)(yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks)) || (free != yaFTL.seaState.freeBlocks)) + { + WMR_PRINT(ERROR, "Free err\n"); + err = TRUE32; + } + if (yaFTL.seaState.data.freeBlocks & 0x80000000) + { + WMR_PRINT(ERROR, "D underflow error\n"); + err = TRUE32; + } + if (yaFTL.seaState.index.freeBlocks & 0x80000000) + { + WMR_PRINT(ERROR, "I underflow error\n"); + err = TRUE32; + } + WMR_ASSERT(FALSE32 == err); +} + +#else +//SELFCONSISTENCY_CHECKS==0 +void CheckDataCounts(void) +{ +} +void SaveValids(void) +{ +} +void CheckValids(void) +{ +} +void CheckBlockDist(void) +{ +} +#endif + +BOOL32 WorkFifo_isEmpty(GC_Fifo_t *f) +{ + return f->tail == f->head; +} + +void WorkFifo_Enq(GC_Fifo_t *f, UInt32 block) +{ + UInt32 p; + p = f->head; + while (p != f->tail) + { + if (f->block[p] == block) + { + return; + } + + p++; + if (p > GCFIFO_DEPTH) + { + p = 0; + } + } + + f->block[f->tail] = block; + f->tail++; + if (f->tail > GCFIFO_DEPTH) + { + f->tail = 0; + } + WMR_ASSERT(f->tail != f->head); +} + +UInt32 WorkFifo_Deq(GC_Fifo_t *f) +{ + UInt32 ret; + + WMR_ASSERT(f->tail != f->head); + + ret = f->block[f->head]; + + f->head++; + if (f->head > GCFIFO_DEPTH) + { + f->head = 0; + } + + return ret; +} + +UInt32 YAFTL_GC_Data_Deq_sb(UInt32 block) +{ + UInt32 p; + UInt32 nRet = -1; + GC_Fifo_t *f = &yaFTL.gc.data.workFifo; + + p = f->head; + + while (p != f->tail) + { + if (f->block[p] == block) + { + nRet = f->block[p]; + break; + } + + p++; + if (p > GCFIFO_DEPTH) + { + p = 0; + } + } + + if(p == f->tail) + return nRet; + + while (p != f->tail) + { + if(p == GCFIFO_DEPTH) + { + f->block[p]=f->block[0]; + p=0; + } + else + { + f->block[p]=f->block[p+1]; + p++; + } + } + + if(f->tail == 0) + f->tail = GCFIFO_DEPTH; + else + f->tail--; + + return nRet; +} + +// Functions + +ANDStatus YAFTL_GC_Init() +{ +#if ENABLE_L2V_TREE + L2V_Search_Init(&yaFTL.gc.data.read_c); +#endif // ENABLE_L2V_TREE + + // GC Zone size should be a multiple of banks, up to 16 (or whatever banks is naturally). + // This logic guarantees low-bank configs will have higher performance, while making sure + // high-bank configs don't occupy too much memory. + // It is similar to setting a minimum of 16, but works with non-pow-2 configs. + yaFTL.gc.zoneSize = NUM_BANKS; + while (yaFTL.gc.zoneSize < GCZONE_DOUBLEUPTO) { + yaFTL.gc.zoneSize <<= 1; + } + + yaFTL.gc.data.state = GCD_IDLE; + yaFTL.gc.data.in_block = 0xffffffff; + yaFTL.gc.index.in_block = 0xffffffff; + + WMR_BufZone_Init(&yaFTL.gc.BufZone); + yaFTL.gc.data.TOCbuff = (UInt32*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.gc.data.pageBuffer = (UInt8 *)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE); + yaFTL.gc.index.TOCbuff = (UInt32*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.gc.index.pageBuffer = (UInt8 *)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE); + yaFTL.gc.meta_buf = (PageMeta_t*)WMR_Buf_Alloc(&yaFTL.gc.BufZone, sizeof(PageMeta_t)); + yaFTL.gc.data.zone = (UInt8*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE * yaFTL.gc.zoneSize); + yaFTL.gc.index.zone = (UInt8*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE * yaFTL.gc.zoneSize); + yaFTL.gc.data.meta = (PageMeta_t*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.gc.zoneSize * sizeof(PageMeta_t)); + yaFTL.gc.index.meta = (PageMeta_t*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.gc.zoneSize * sizeof(PageMeta_t)); + + if (!WMR_BufZone_FinishedAllocs(&yaFTL.gc.BufZone)) { + return FTL_CRITICAL_ERROR; + } + + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.TOCbuff); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.pageBuffer); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.TOCbuff); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.pageBuffer); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.meta_buf); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.zone); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.zone); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.meta); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.meta); + WMR_BufZone_FinishedRebases(&yaFTL.gc.BufZone); + + yaFTL.gc.data.vpns = (UInt32*) WMR_MALLOC(yaFTL.gc.zoneSize * sizeof(UInt32)); + yaFTL.gc.index.vpns = (UInt32*) WMR_MALLOC(yaFTL.gc.zoneSize * sizeof(UInt32)); + + if ((NULL == yaFTL.gc.data.TOCbuff) || (NULL == yaFTL.gc.data.pageBuffer) + || (NULL == yaFTL.gc.index.TOCbuff) || (NULL == yaFTL.gc.index.pageBuffer) + || (NULL == yaFTL.gc.meta_buf) + || (NULL == yaFTL.gc.data.zone) || (NULL == yaFTL.gc.index.zone) + || (NULL == yaFTL.gc.data.vpns) || (NULL == yaFTL.gc.data.meta) + || (NULL == yaFTL.gc.index.vpns) || (NULL == yaFTL.gc.index.meta) + ) + { + return FTL_CRITICAL_ERROR; + } + + return FTL_SUCCESS; +} + +void YAFTL_GC_Close() +{ + WMR_BufZone_Free(&yaFTL.gc.BufZone); + + yaFTL.gc.data.TOCbuff = NULL; + yaFTL.gc.data.pageBuffer = NULL; + yaFTL.gc.index.TOCbuff = NULL; + yaFTL.gc.index.pageBuffer = NULL; + yaFTL.gc.meta_buf = NULL; + yaFTL.gc.data.zone = NULL; + yaFTL.gc.index.zone = NULL; + yaFTL.gc.data.meta = NULL; + yaFTL.gc.index.meta = NULL; + + if (NULL != yaFTL.gc.data.vpns) { + WMR_FREE(yaFTL.gc.data.vpns, yaFTL.gc.zoneSize * sizeof(UInt32)); + } + if (NULL != yaFTL.gc.index.vpns) { + WMR_FREE(yaFTL.gc.index.vpns, yaFTL.gc.zoneSize * sizeof(UInt32)); + } + + yaFTL.gc.data.vpns = NULL; + yaFTL.gc.index.vpns = NULL; +} + +void YAFTL_GC_PreWrite(UInt32 writeSize) +{ + CheckDataCounts(); + CheckBlockDist(); + yaFTL.gc.data.in_block = 0xffffffff; + + // Below low low low mark? + while (dangerousIndex || dangerousData(writeSize)) + { + if (dangerousIndex) + { + YAFTL_GC_Index(0xffffffff, TRUE32); + } + if (dangerousData(writeSize)) + { + YAFTL_GC_Data(0xffffffff, TRUE32); + } + } + + CheckBlockDist(); + + // If we're low on space, or the garbage collector is not idle, (-> this is important to not cause hangs) + if (lowData(writeSize) || (GCD_IDLE != yaFTL.gc.data.state)) + { + GCMachine_Data(writeSize, TRUE32); + } + + CheckBlockDist(); +} + +static void MoveOnIfCurrentI(UInt32 inBlock) +{ + // Is this the current index block? + if (BLOCK_I_CURRENT == yaFTL.blockArray[inBlock].status) + { + // Have to allocate a new one so we don't pull the rug out from underneath ourselves... + allocateBlock(yaFTL.wrState.index.block, 0, 0); + } +} + +ANDStatus YAFTL_GC_Index(UInt32 block, BOOL32 scrubOnUECC) +{ + GC_Ctx_t *c = &yaFTL.gc.index; + ANDStatus status = FTL_SUCCESS; + + WMR_TRACE_IST_2(GCIndex, START, block, scrubOnUECC); + + c->in_block = block; + + stFTLStatistics.ddwIndexGCCnt++; + + CheckBlockDist(); + + again: + ChooseIndexSB(); + + if (0 == c->chosenValid) + { + // No valid pages--just erase it and be done with it all + stFTLStatistics.ddwEmptyGCIndexCnt++; + goto eraseExit; + } + + // Get block TOC, either from memory or by reading it off the NAND + if(BTOC_GET_IPN(1) == 1) + { + GetBlockTOC(c, scrubOnUECC, yaFTL.TOCtableEntriesNo, NULL); + } + else + { + GetBlockTOC(c, scrubOnUECC, yaFTL.logicalPartitionSize, NULL); + } + + status = EvictIndex(c, scrubOnUECC); + if (FTL_SUCCESS != status) + { + goto again; + } + + eraseExit: + SanityCheckValid(c); + + // Zap it! + status = EraseIndex(c->chosenBlock); + if (FTL_SUCCESS != status) + { + WMR_TRACE_IST_1(GCIndex, END, status); + return status; + } + + if (!WorkFifo_isEmpty(&c->workFifo)) + { + goto again; + } + + CheckBlockDist(); + + WMR_TRACE_IST_1(GCIndex, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +static void MoveOnIfCurrentD(UInt32 inBlock) +{ + // Is it the current data block? + if (BLOCK_CURRENT == yaFTL.blockArray[inBlock].status) + { + allocateBlock(yaFTL.wrState.data.block, 0, 1); + } +} + + +// Data state machine: +// 1) choose block +// 2) read TOC or reconstruct +// 3) [loop] find valid spans, move preferentially in chunks of sequentiality +// 4) sanity check +// 5) erase block + + +static ANDStatus GCMachine_Data(Int32 writeSize, BOOL32 scrubOnUECC) +{ + ANDStatus status; + UInt32 cost; + Int32 ratio; + + again: + WMR_TRACE_IST_3(GCMachine, START, writeSize, scrubOnUECC, yaFTL.gc.data.state); + switch (yaFTL.gc.data.state) + { + case GCD_IDLE: + while (dangerousIndex) + { + // Important for wearleveling calls, for instance + // Safe because YAFTL_GC_Index only calls GCMachine_Data if state != GCD_IDLE + YAFTL_GC_Index(0xffffffff, scrubOnUECC); + } + + stFTLStatistics.ddwDataGCCnt++; + ChooseDataSB(); + if (0 == yaFTL.gc.data.chosenValid) + { + stFTLStatistics.ddwEmptyGCDataCnt++; + yaFTL.gc.data.state = GCD_ERASE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + yaFTL.gc.data.curPage = 0; + yaFTL.gc.data.pagesCopied = 0; + yaFTL.gc.data.ueccCounter = 0; + GetBlockTOC(&yaFTL.gc.data, scrubOnUECC, yaFTL.logicalPartitionSize, &yaFTL.gc.data.ueccCounter); + yaFTL.blockArray[yaFTL.gc.data.chosenBlock].status = BLOCK_GC; + yaFTL.gc.data.state = GCD_EVICT; + break; + + case GCD_EVICT: + // Check if it's been invalidated by host writes since we entered the state machine + WMR_ASSERT(0 == yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesINo); + if (0 == yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesDNo) + { + // And short-circuit to the ERASE state + yaFTL.gc.data.state = GCD_ERASE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + cost = yaFTL.gc.zoneSize; + if (writeSize > 0) + { + ratio = (FREE_BLK_TRH_UPDATED * 2 * PAGES_PER_SUBLK) - ((yaFTL.seaState.data.freeBlocks*PAGES_PER_SUBLK)+yaFTL.gc.data.gcDataAdjust); + if (ratio <= 0) ratio = 1; + ratio = (ratio * YAFTL_GC_RATIO_SCALAR) / FREE_BLK_GAP; + // Writes should evict an amount relative to the current ratio of low-end validity + cost = PAGES_PER_SUBLK - yaFTL.controlPageNo - yaFTL.gc.data.chosenValid; // Divisor + if (!cost) + { + cost = 1; // Avoid div0 when we move a full block for wear-leveling purposes etc. + } + cost = (writeSize * PAGES_PER_SUBLK) / cost; + cost = (cost * ratio) / PAGES_PER_SUBLK; + // Round up to a zone boundary (makes no sense to do less!) + cost += yaFTL.gc.zoneSize - 1; + cost -= cost % yaFTL.gc.zoneSize; + } + + status = EvictData(cost, scrubOnUECC); + if (FTL_SUCCESS != status) + { + if (GCD_EVICT == yaFTL.gc.data.state) + { + yaFTL.gc.data.state = GCD_IDLE; + } + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + if (yaFTL.gc.data.curPage >= yaFTL.gc.data.pagesRange) + { + SanityCheckValid(&yaFTL.gc.data); + } + break; + + case GCD_ERASE: + SanityCheckValid(&yaFTL.gc.data); + status = EraseData(yaFTL.gc.data.chosenBlock); + yaFTL.gc.data.state = GCD_IDLE; + if (FTL_SUCCESS != status) + { + WMR_TRACE_IST_1(GCMachine, END, status); + return status; + } + if (!WorkFifo_isEmpty(&yaFTL.gc.data.workFifo)) + { + // If we had an error causing us to do extra data GCs, + // don't stop in the idle state. + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + break; + + case GCD_FIXINDEX_RETRY: + while (!WorkFifo_isEmpty(&yaFTL.gc.index.workFifo)) + { + YAFTL_GC_Index(0xffffffff, scrubOnUECC); + } + yaFTL.gc.data.state = GCD_IDLE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + + case GCD_FIXDATA_RETRY: + yaFTL.gc.data.state = GCD_IDLE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + WMR_TRACE_IST_1(GCMachine, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +void YAFTL_GC_Data_Enq(UInt32 block) +{ + WMR_TRACE_IST_1(GCDataEnq, NONE, block); + WorkFifo_Enq(&yaFTL.gc.data.workFifo, block); +} + +void YAFTL_GC_Index_Enq(UInt32 block) +{ + WMR_TRACE_IST_1(GCIndexEnq, NONE, block); + WorkFifo_Enq(&yaFTL.gc.index.workFifo, block); +} + +ANDStatus YAFTL_GC_Data(UInt32 block, BOOL32 scrubOnUECC) +{ + ANDStatus status; + + WMR_TRACE_IST_2(GCData, START, block, scrubOnUECC); + + CheckBlockDist(); + + // Kill any previous GC operations + // This makes GC recovery from write fail more safe + if (GCD_IDLE != yaFTL.gc.data.state) { + // Un-mark pending GC operations + if ((0xffffffff != yaFTL.gc.data.chosenBlock) && (BLOCK_GC == yaFTL.blockArray[yaFTL.gc.data.chosenBlock].status)) { + yaFTL.blockArray[yaFTL.gc.data.chosenBlock].status = BLOCK_ALLOCATED; + } + } + yaFTL.gc.data.state = GCD_IDLE; + +again: + // Set up the new one + yaFTL.gc.data.in_block = block; + + // And start it + do + { + status = GCMachine_Data(0, scrubOnUECC); + if (FTL_SUCCESS != status) + { + WMR_TRACE_IST_1(GCData, END, status); + return status; + } + } + while (GCD_IDLE != yaFTL.gc.data.state); + + if (!WorkFifo_isEmpty(&yaFTL.gc.data.workFifo)) + { + block = WorkFifo_Deq(&yaFTL.gc.data.workFifo); + goto again; + } + + CheckBlockDist(); + + WMR_TRACE_IST_1(GCData, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +static void ChooseSB(GC_Ctx_t *c, UInt32 filter) +{ + UInt32 i, status; + UInt32 thisValid, thisErases; + UInt32 best, bestValid, bestErases; + + best = bestValid = bestErases = 0xFFFFFFFF; + + if (0xffffffff != c->in_block) { + MoveOnIfCurrentI(c->in_block); + MoveOnIfCurrentD(c->in_block); + } + + if (!WorkFifo_isEmpty(&c->workFifo)) + { + if (0xffffffff != c->in_block) + { + WorkFifo_Enq(&c->workFifo, c->in_block); + } + c->in_block = WorkFifo_Deq(&c->workFifo); + } + + if (0xffffffff != c->in_block) + { + c->chosenBlock = c->in_block; + c->chosenValid = yaFTL.blockArray[c->in_block].validPagesDNo + yaFTL.blockArray[c->in_block].validPagesINo; + c->chosenErases = yaFTL.blockArray[c->in_block].erasableCount; + status = yaFTL.blockArray[c->in_block].status; + if (status != filter) + { + // Note: these rules use implication, that works in conjunction with the wrapper if statement so + // BLOCK_I_ALLOCATED filter means BLOCK_I_CURRENT/GC will work, and the same for BLOCK_ALLOCATED and BLOCK_CURRENT/GC. + WMR_ASSERT((filter != BLOCK_ALLOCATED) || ((status == BLOCK_CURRENT) || (status == BLOCK_GC))); + WMR_ASSERT((filter != BLOCK_I_ALLOCATED) || ((status == BLOCK_I_CURRENT) || (status == BLOCK_I_GC))); + } + c->in_block = 0xffffffff; + return; + } + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + // Not allocated to the filter type? Don't consider... + if (yaFTL.blockArray[i].status != filter) + { + continue; + } + + // Grab local copies + thisValid = yaFTL.blockArray[i].validPagesDNo + yaFTL.blockArray[i].validPagesINo; + thisErases = yaFTL.blockArray[i].erasableCount; + + // Minimize valid + if ((thisValid < bestValid) || ((thisValid == bestValid) && (thisErases < bestErases))) + { + best = i; + bestValid = thisValid; + bestErases = thisErases; + } + } + + WMR_ASSERT(best != 0xFFFFFFFF); + WMR_ASSERT(bestValid != 0xFFFFFFFF); + WMR_ASSERT(bestErases != 0xFFFFFFFF); + + // Output + c->chosenBlock = best; + c->chosenValid = bestValid; + c->chosenErases = bestErases; +} + +static void ChooseIndexSB() +{ + ChooseSB(&yaFTL.gc.index, BLOCK_I_ALLOCATED); +} + +static void ChooseDataSB() +{ + ChooseSB(&yaFTL.gc.data, BLOCK_ALLOCATED); +} + +static ANDStatus EraseIndex(UInt32 block) +{ + yaFTL.blockArray[block].eraseBeforeUse = BLOCK_TO_BE_ERASED_ALIGNED_INDEX; + yaFTL.blockArray[block].pagesRead = 0; + yaFTL.blockArray[block].pagesReadSubCounter = 0; + yaFTL.blockArray[block].validPagesDNo = yaFTL.blockArray[block].validPagesINo = 0; + yaFTL.seaState.freeBlocks++; + yaFTL.blockArray[block].status = BLOCK_I_FREE; + yaFTL.seaState.index.freeBlocks++; + yaFTL.seaState.index.allocdBlocks--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks++; +#endif + return FTL_SUCCESS; +} + +static ANDStatus EraseData(UInt32 block) +{ + yaFTL.blockArray[block].eraseBeforeUse = BLOCK_TO_BE_ERASED_ALIGNED_DATA; + yaFTL.blockArray[block].pagesRead = 0; + yaFTL.blockArray[block].pagesReadSubCounter = 0; + yaFTL.blockArray[block].validPagesDNo = yaFTL.blockArray[block].validPagesINo = 0; + yaFTL.seaState.freeBlocks++; + yaFTL.blockArray[block].status = BLOCK_FREE; + yaFTL.seaState.data.freeBlocks++; + yaFTL.seaState.data.allocdBlocks--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks++; +#endif + return FTL_SUCCESS; +} + +static ANDStatus GetBlockTOC(GC_Ctx_t *c, BOOL32 scrubOnUECC, UInt32 upperBound, UInt32 *ueccCounter) +{ + UInt32 i; + UInt32 *ramBTOC; + PageMeta_t *meta = yaFTL.gc.meta_buf; + + ANDStatus status; + + c->pagesRange = PAGES_PER_SUBLK - yaFTL.controlPageNo; + + // Is it in memory? + ramBTOC = BTOC_Search(c->chosenBlock, c == &yaFTL.gc.data); + if (NULL != ramBTOC) { + BTOC_Copy(c->TOCbuff, ramBTOC, upperBound); + return FTL_SUCCESS; + } + + // Have to read it off the NAND... + status = BTOC_Read((c->chosenBlock * PAGES_PER_SUBLK) + (PAGES_PER_SUBLK - yaFTL.controlPageNo), c->TOCbuff, meta, FALSE32, scrubOnUECC, upperBound); + if ((status != FTL_SUCCESS) || ((status == FTL_SUCCESS) && !META_IS_BTOC(meta))) + { + BOOL32 uncleanFound = FALSE32; + + debug(MISC, "cannot read blockTOC - restoring blockTOC manually"); + BTOC_SetAll(c->TOCbuff, 0xff); + i = (UInt32)(PAGES_PER_SUBLK - yaFTL.controlPageNo); + while (i-- > 0) + { + status = _readPage((c->chosenBlock * PAGES_PER_SUBLK) + i, c->pageBuffer, meta, FALSE32, TRUE32, scrubOnUECC); + if (VFL_SUCCESS_CLEAN != status) + { + uncleanFound = TRUE32; + } + if ((status == FTL_SUCCESS) && (META_GET_IPNRAW(meta) < upperBound)) + { + c->TOCbuff[i] = META_GET_IPNRAW(meta); + } + else + { + if ((FTL_CRITICAL_ERROR == status) || ((VFL_SUCCESS_CLEAN == status) && uncleanFound)) + { + if (NULL != ueccCounter) + { + debug(MISC, "got error at block %d page %d, assuming uecc\n", c->chosenBlock, i); + (*ueccCounter)++; + } + } + } + } + } + + return FTL_SUCCESS; +} + +static void SanityCheckValid(GC_Ctx_t *c) +{ + // Sanity check: should now be empty... + if ((yaFTL.blockArray[c->chosenBlock].validPagesINo + yaFTL.blockArray[c->chosenBlock].validPagesDNo) != 0) + { + CheckDataCounts(); + debug(ERROR, "something could be wrong with GC; index:%d data:%d ", yaFTL.blockArray[c->chosenBlock].validPagesINo, yaFTL.blockArray[c->chosenBlock].validPagesDNo); + if (c->ueccCounter >= (yaFTL.blockArray[c->chosenBlock].validPagesINo + yaFTL.blockArray[c->chosenBlock].validPagesDNo)) + { + // If we had uncorrectables, we may be missing data... best way to mark it is to do a P->L translation, but that + // would be a very slow, exhaustive searchof the index tables--though we should consider implementing it at some point. + debug(ERROR, "fixing up validity counters since we had %d uECC(s) ", c->ueccCounter); + yaFTL.blockArray[c->chosenBlock].validPagesINo = 0; + yaFTL.blockArray[c->chosenBlock].validPagesDNo = 0; + } + else + { + // It must be a real bug since we had no uncorrectables to blame + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Non-zero validity counter Block %d Index: %d Data: %d UECC: %d", + c->chosenBlock, + (UInt32) yaFTL.blockArray[c->chosenBlock].validPagesINo, + (UInt32) yaFTL.blockArray[c->chosenBlock].validPagesDNo, + c->ueccCounter); + } + } +} + +typedef enum +{ + IPS_DEAD, + IPS_DIRTYCACHE, + IPS_BUSYCACHE, + IPS_ALIVE, + IPS_ERROR, +} IPageState_t; + +static IPageState_t GetIndexPageState(UInt32 page, UInt32 *r_presentIdxPage, UInt32 *r_indexPagePhy, UInt32 *r_cacheIndexPtr) +{ + GC_Ctx_t *c = &yaFTL.gc.index; + UInt32 presentIdxPage, indexPagePhy, cacheIndexPtr; + + // Extract which IdxPage lives at this location + presentIdxPage = BTOC_GET_IPN(c->TOCbuff[page]); + *r_presentIdxPage = presentIdxPage; + + if (0xffffffff == c->TOCbuff[page]) + { + // Nothing to move + return IPS_DEAD; + } + + // Calculate which index page, its location (if any) in the cache + indexPagePhy = yaFTL.tocArray[presentIdxPage].indexPage; + cacheIndexPtr = yaFTL.tocArray[presentIdxPage].cacheIndex; + *r_indexPagePhy = indexPagePhy; + *r_cacheIndexPtr = cacheIndexPtr; + + if ((0xffffffff == indexPagePhy) && (0xffff == cacheIndexPtr)) + { + // Not on medium or in cache... (span deallocated) + return IPS_DEAD; + } + + if ((0xffffffff != indexPagePhy) && (indexPagePhy != ((c->chosenBlock * PAGES_PER_SUBLK) + page))) + { + // Early out for wrong location... + return IPS_DEAD; + } + + if ((cacheIndexPtr != 0xffff) && (yaFTL.indexCache[cacheIndexPtr].status == IC_DIRTY_PAGE)) + { + // In cache, and dirty, so it will make it down eventually... + return IPS_DIRTYCACHE; + } + + if ((cacheIndexPtr != 0xffff) && (yaFTL.indexCache[cacheIndexPtr].status == IC_BUSY_PAGE)) + { + // It's in the cache as busy; special logic needed by caller... + return IPS_BUSYCACHE; + } + + if (indexPagePhy != 0xffffffff) + { + if (((c->chosenBlock * PAGES_PER_SUBLK) + page) == indexPagePhy) + { + // We've found a live one! + return IPS_ALIVE; + } + else + { + // On medium, but not in that location, so don't move it + // Should be unreachable + WMR_ASSERT(0); + return IPS_DEAD; + } + } + + // Should never get here, as the above logic should cover all cases. + WMR_ASSERT(0); + return IPS_ERROR; +} + +static ANDStatus EvictIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC) +{ + UInt32 page, alignZoneSize; + UInt32 presentIdxPage, indexPagePhy, cacheIndexPtr; + UInt16 newCacheEntry; + ANDStatus status; + + status = FTL_SUCCESS; + c->pagesCopied = 0; + c->curZoneSize = 0; + c->ueccCounter = 0; + + yaFTL.blockArray[c->chosenBlock].status = BLOCK_I_GC; + + // Iterate over the range of potentially valid virtual pages + for (page = 0; (page < c->pagesRange) && (c->pagesCopied < c->chosenValid); page++) + { + switch (GetIndexPageState(page, &presentIdxPage, &indexPagePhy, &cacheIndexPtr)) + { + case IPS_DEAD: + case IPS_DIRTYCACHE: + // Nothing to move. + break; + + case IPS_BUSYCACHE: + yaFTL.indexCache[cacheIndexPtr].status = IC_DIRTY_PAGE; // So it gets written to the flash later. + if (((c->chosenBlock * PAGES_PER_SUBLK) + page) == indexPagePhy) + { + // Pre-check validity + WMR_ASSERT(0 != yaFTL.blockArray[c->chosenBlock].validPagesINo); + + // Manage validity and page copy count + yaFTL.blockArray[c->chosenBlock].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[presentIdxPage].indexPage = 0xffffffff; + + c->pagesCopied++; + } + break; + + case IPS_ALIVE: + newCacheEntry = findFreeCacheEntry(); + if (newCacheEntry != 0xffff) + { + // Read it in to the cache if we can + status = _readPage((c->chosenBlock * PAGES_PER_SUBLK) + page, (UInt8 *)(yaFTL.indexCache[newCacheEntry].indexPage), yaFTL.singleMdPtr, FALSE32, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + yaFTL.indexCache[newCacheEntry].status = IC_DIRTY_PAGE; + yaFTL.indexCache[newCacheEntry].tocEntry = presentIdxPage; + yaFTL.tocArray[presentIdxPage].cacheIndex = newCacheEntry; + yaFTL.tocArray[presentIdxPage].indexPage = 0xffffffff; + + // Pre-check validity + WMR_ASSERT(0 != yaFTL.blockArray[c->chosenBlock].validPagesINo); + + // Manage validity and page copy count + yaFTL.blockArray[c->chosenBlock].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + c->pagesCopied++; + } + else + { + // No free cache pages... copy it over + + // Pre-check validity + WMR_ASSERT(yaFTL.blockArray[c->chosenBlock].validPagesINo >= c->curZoneSize); + + // Zone overflow? + alignZoneSize = yaFTL.gc.zoneSize - (yaFTL.wrState.index.nextPage % NUM_BANKS); + if (c->curZoneSize >= alignZoneSize) + { + status = ReadZone(c, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneIndex(c, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + + c->curZoneSize = 0; + } + + // Place in zone + yaFTL.gc.index.vpns[c->curZoneSize] = (c->chosenBlock * PAGES_PER_SUBLK) + page; + c->curZoneSize++; + } + break; + + default: + WMR_ASSERT(0); + break; + } + } + + // Do remainder + if (c->curZoneSize > 0) + { + status = ReadZone(c, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneIndex(c, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + } + + return status; +} + +static BOOL32 IsDataPageCurrent(UInt32 page, UInt32 *vPN, ANDStatus *status, BOOL32 scrubOnUECC) +{ + GC_Ctx_t *c = &yaFTL.gc.data; + UInt32 presentVpn, indexPageNo, indexPageSub, indexPagePhy, cacheIndexPtr; + PageMeta_t *tMD = yaFTL.gc.meta_buf; + + // Extract which VPN lives at this location + presentVpn = c->TOCbuff[page]; + + if (0xffffffff == presentVpn) + { + // Nothing to move... + return FALSE32; + } + +#if ENABLE_L2V_TREE + // Out of search span, or switched to a different region? + if ((0 == yaFTL.gc.data.read_c.span) || (yaFTL.gc.data.read_c.lba != presentVpn)) { + yaFTL.gc.data.read_c.lba = presentVpn; + L2V_Search(&yaFTL.gc.data.read_c); + } + WMR_ASSERT(0 != yaFTL.gc.data.read_c.span); + + // Move search iterator along--NOTE: can't use these values below; if we need to, move these to exit paths + yaFTL.gc.data.read_c.lba++; + yaFTL.gc.data.read_c.span--; + + if (L2V_VPN_DEALLOC == yaFTL.gc.data.read_c.vpn) { + // Deallocated + return FALSE32; + } + + if (yaFTL.gc.data.read_c.vpn < L2V_VPN_SPECIAL) { + *vPN = yaFTL.gc.data.read_c.vpn; + yaFTL.gc.data.read_c.vpn++; // Only because not in special range + return *vPN == ((c->chosenBlock * PAGES_PER_SUBLK) + page); + } + + // Missed first search... :( + WMR_ASSERT(L2V_VPN_MISS == yaFTL.gc.data.read_c.vpn); + + if (yaFTL.gc.data.read_c.vpn < L2V_VPN_SPECIAL) { + yaFTL.gc.data.read_c.vpn++; + } +#endif // ENABLE_L2V_TREE + + // Calculate which index page, how far in, where the index page lives, and its location in the cache + indexPageNo = presentVpn / yaFTL.indexPageRatio; + WMR_ASSERT(indexPageNo < yaFTL.TOCtableEntriesNo); + indexPageSub = presentVpn % yaFTL.indexPageRatio; + indexPagePhy = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexPtr = yaFTL.tocArray[indexPageNo].cacheIndex; + + if ((0xffffffff == indexPagePhy) && (0xffff == cacheIndexPtr)) + { + // Not on medium or in cache... + return FALSE32; + } + + if (0xffff == cacheIndexPtr) + { + // Need to read index page in to cache first + cacheIndexPtr = findFreeCacheEntry(); + if (cacheIndexPtr == 0xffff) + { + /* Cache is full and we need to clear space for new index page */ + cacheIndexPtr = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexPtr == 0xffff) + { + *status = FTL_CRITICAL_ERROR; + yaFTL.gc.data.state = GCD_FIXINDEX_RETRY; + + return FALSE32; + } + } + + *status = _readPage(indexPagePhy, (UInt8 *)(yaFTL.indexCache[cacheIndexPtr].indexPage), tMD, FALSE32, TRUE32, scrubOnUECC); + if (*status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Index UECC Page 0x%08x Status 0x%08x", indexPagePhy, *status); + return FALSE32; + } + + if (!META_IS_IDX(tMD)) + { + debug(ERROR, "meta data expected to be from an index page"); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Invalid Index metadata 0x%02x", (UInt32) META_GET_ALL_FLAGS(tMD)); + *status = FTL_CRITICAL_ERROR; + return FALSE32; + } + yaFTL.freeCachePages--; + yaFTL.indexCache[cacheIndexPtr].status = IC_BUSY_PAGE; + yaFTL.indexCache[cacheIndexPtr].counter = 1; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexPtr; + yaFTL.indexCache[cacheIndexPtr].tocEntry = indexPageNo; + } + + *vPN = yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub]; + return *vPN == ((c->chosenBlock * PAGES_PER_SUBLK) + page); +} + +static ANDStatus EvictData(UInt32 minAmount, BOOL32 scrubOnUECC) +{ + UInt32 vPN, alignZoneSize; + ANDStatus status; + UInt32 moved = 0; + + status = FTL_SUCCESS; + + yaFTL.gc.data.curZoneSize = 0; + + // Clear search state every time we enter EvictData, for coherency +#if ENABLE_L2V_TREE + L2V_Search_Init(&yaFTL.gc.data.read_c); +#endif // ENABLE_L2V_TREE + + for (; (moved < minAmount) && (yaFTL.gc.data.curPage < yaFTL.gc.data.pagesRange) && (yaFTL.gc.data.pagesCopied < yaFTL.gc.data.chosenValid); yaFTL.gc.data.curPage++) + { + if (IsDataPageCurrent(yaFTL.gc.data.curPage, &vPN, &status, scrubOnUECC)) + { + yaFTL.gc.data.vpns[yaFTL.gc.data.curZoneSize] = vPN; + yaFTL.gc.data.curZoneSize++; + moved++; + yaFTL.gc.data.pagesCopied++; + } + if (FTL_SUCCESS != status) + { + return status; + } + + alignZoneSize = yaFTL.gc.zoneSize - (yaFTL.wrState.data.nextPage % NUM_BANKS); + if (yaFTL.gc.data.curZoneSize >= alignZoneSize) + { + WMR_ASSERT(yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesDNo >= yaFTL.gc.data.curZoneSize); + + status = ReadZone(&yaFTL.gc.data, FALSE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneData(&yaFTL.gc.data, scrubOnUECC); + if (status != FTL_SUCCESS) + { + yaFTL.gc.data.state = GCD_FIXDATA_RETRY; + return status; + } + yaFTL.gc.data.curZoneSize = 0; + } + } + + if (yaFTL.gc.data.curZoneSize > 0) + { + WMR_ASSERT(yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesDNo >= yaFTL.gc.data.curZoneSize); + + status = ReadZone(&yaFTL.gc.data, FALSE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneData(&yaFTL.gc.data, scrubOnUECC); + if (status != FTL_SUCCESS) + { + yaFTL.gc.data.state = GCD_FIXDATA_RETRY; + return status; + } + } + + return status; +} + +static BOOL32 ReconstructIndex(UInt32 indexEntry, UInt32 *indexPage) +{ +#if ENABLE_L2V_TREE + UInt32 lpnOfs, lpn, vpn, add, amount; + + lpn = indexEntry * yaFTL.indexPageRatio; + yaFTL.gc.index.read_c.span = 0; + + lpnOfs = 0; + while (lpnOfs < yaFTL.indexPageRatio) { + if (0 == yaFTL.gc.index.read_c.span) { + yaFTL.gc.index.read_c.lba = lpn + lpnOfs; + L2V_Search(&yaFTL.gc.index.read_c); + } + WMR_ASSERT(0 != yaFTL.gc.index.read_c.span); + + // Missing? Bail out + if (L2V_VPN_MISS == yaFTL.gc.index.read_c.vpn) { + return FALSE32; + } + + // Not missing from IC tree + if (L2V_VPN_DEALLOC != yaFTL.gc.index.read_c.vpn) { + // Not deallocated + vpn = yaFTL.gc.index.read_c.vpn; + WMR_ASSERT(yaFTL.gc.index.read_c.vpn < L2V_VPN_SPECIAL); + + // Complete the span + amount = WMR_MIN(yaFTL.indexPageRatio-lpnOfs, yaFTL.gc.index.read_c.span); + add = amount; + while (amount--) { + indexPage[lpnOfs++] = vpn++; + + } + + yaFTL.gc.index.read_c.vpn += add; + yaFTL.gc.index.read_c.span -= add; + } else { + // Deallocated + vpn = 0xffffffff; + + // Complete the span + amount = WMR_MIN(yaFTL.indexPageRatio-lpnOfs, yaFTL.gc.index.read_c.span); + add = amount; + while (amount--) { + indexPage[lpnOfs++] = vpn; + } + + yaFTL.gc.index.read_c.span -= add; + } + + } + + return TRUE32; +#else + return FALSE32; +#endif +} + +static void ScrubZone(GC_Ctx_t *c, BOOL32 index) +{ + UInt32 i, ipn, lba; + + if (index) { + for (i = 0; i < c->curZoneSize; i++) + { + ipn = META_GET_IPN(&c->meta[i]); + if (ipn >= yaFTL.TOCtableEntriesNo) + { + META_SET_IPN_FROM_BTOC(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + SetupMeta_Data_UECC(&c->meta[i]); + } + } + } else { + for (i = 0; i < c->curZoneSize; i++) + { + lba = META_GET_LBA(&c->meta[i]); + if (lba >= yaFTL.logicalPartitionSize) + { + META_SET_LBA(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + SetupMeta_Data_UECC(&c->meta[i]); + } + } + } +} + +static ANDStatus ReadZone(GC_Ctx_t *c, BOOL32 index, BOOL32 scrubOnUECC) +{ + BOOL32 BoolStatus, dontRead; + UInt8 i; + // Handling uECCs, trying older data: + BOOL32 failed, rereadOrig; + UInt32 srcVpn; + + dontRead = FALSE32; + if (index) { + dontRead = TRUE32; + for (i = 0; dontRead && (i < c->curZoneSize); i++) + { + META_SET_IPN_FROM_BTOC(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + WMR_ASSERT(META_GET_LBA(&c->meta[i]) != 0xffffffff); + dontRead = dontRead && ReconstructIndex(META_GET_IPN(&c->meta[i]), (UInt32*)&c->zone[BYTES_PER_PAGE * i]); + } + BoolStatus = TRUE32; + } + if (!dontRead) { + BoolStatus = _readMultiPages(c->vpns, c->curZoneSize, c->zone, (UInt8*)c->meta, !index, scrubOnUECC); + } + + if (BoolStatus == TRUE32) + { + ScrubZone(c, index); + return FTL_SUCCESS; + } + else + { + for (i = 0; i < c->curZoneSize; i++) + { + if (_readPage(c->vpns[i], &c->zone[BYTES_PER_PAGE * i], &c->meta[i], !index, TRUE32, scrubOnUECC) != FTL_SUCCESS) + { + failed = TRUE32; + if (!index) + { + srcVpn = BTOC_GetSrc(c->vpns[i]); + if (0xffffffff != srcVpn) + { + rereadOrig = FALSE32; + if (_readPage(srcVpn, &c->zone[BYTES_PER_PAGE * i], &c->meta[i], !index, TRUE32, scrubOnUECC) == FTL_SUCCESS) + { + failed = FALSE32; + } + else + { + rereadOrig = TRUE32; + } + + if (rereadOrig || (!rereadOrig && (c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK] != META_GET_LBA(&c->meta[i])))) + { + _readPage(c->vpns[i], &c->zone[BYTES_PER_PAGE * i], &c->meta[i], !index, TRUE32, scrubOnUECC); + } + } + } + + if (failed) { + if (index) { + META_SET_IPN_FROM_BTOC(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + } else { + META_SET_LBA(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + } + WMR_ASSERT(META_GET_LBA(&c->meta[i]) != 0xffffffff); + if (index) { + if (!ReconstructIndex(META_GET_IPN(&c->meta[i]), (UInt32*)&c->zone[BYTES_PER_PAGE * i])) { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't reconstruct yaFTL index after a uECC: vpn 0x%x", c->vpns[i]); + } + } else { + SetupMeta_Data_UECC(&c->meta[i]); + } + c->ueccCounter++; + } + } + } + } + + ScrubZone(c, index); + return FTL_SUCCESS; +} + +static ANDStatus WriteZoneData(GC_Ctx_t *c, BOOL32 scrubOnUECC) +{ + BOOL32 status; + UInt8 i; + UInt32 prevVpn; + UInt16 cacheIndexPtr; + UInt32 count, thisOfs, thisCount; + PageMeta_t *mdPtr = &yaFTL.gc.data.meta[0]; + PageMeta_t *md_index = yaFTL.gc.meta_buf; + UInt32 indexPageNo, indexPageSub; + UInt32 newVpn; + + thisOfs = 0; + count = c->curZoneSize; + c->gcDataAdjust += c->curZoneSize; + + // While we still have data we want to move, + while (count) + { + // If we have space left in this block, + if (yaFTL.wrState.data.nextPage < (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + // Move as much as we can + thisCount = WMR_MIN((UInt32)((PAGES_PER_SUBLK - yaFTL.controlPageNo) - yaFTL.wrState.data.nextPage), (UInt32)count); + + // Fill in metadata + SetupMeta_DataGC(&mdPtr[thisOfs], thisCount); + + // Write the data + status = _writeMultiPages(yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, thisCount, &yaFTL.gc.data.zone[thisOfs * BYTES_PER_PAGE], &mdPtr[thisOfs], TRUE32); + if (status == TRUE32) + { + newVpn = (yaFTL.wrState.data.block * PAGES_PER_SUBLK) + yaFTL.wrState.data.nextPage; + for (i = 0; i < thisCount; i++, newVpn++) + { + // Update block TOC + yaFTL.wrState.data.TOC[yaFTL.wrState.data.nextPage + i] = META_GET_LBA(&mdPtr[thisOfs + i]); + // and src vpn + BTOC_SetSrc(newVpn, yaFTL.gc.data.vpns[thisOfs + i]); + // And temporary housing for updates to tree + yaFTL.gc.data.vpns[thisOfs + i] = newVpn; + } + yaFTL.wrState.data.nextPage += thisCount; + thisOfs += thisCount; + } + else + { + if(addBlockToEraseNowList(yaFTL.wrState.data.block) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", yaFTL.wrState.data.block); + } + WorkFifo_Enq(&c->workFifo, c->chosenBlock); + WorkFifo_Enq(&c->workFifo, yaFTL.wrState.data.block); + allocateBlock(yaFTL.wrState.data.block, 0, 1); + + return FTL_CRITICAL_ERROR; + } + + // Move along + count -= thisCount; + } + + // Want to write more data but out of space? + if (count && (yaFTL.wrState.data.nextPage >= (PAGES_PER_SUBLK - yaFTL.controlPageNo))) + { + // Write the block TOC + writeCurrentBlockTOC(1); + + // Move to the next block + allocateBlock(yaFTL.wrState.data.block, 0, 1); + } + } + + // Now we need to update index to reflect change in Lpn location + for (i = 0; i < c->curZoneSize; i++) + { +#if ENABLE_L2V_TREE + L2V_Update(META_GET_LBA(&mdPtr[i]), 1, yaFTL.gc.data.vpns[i]); +#endif // ENABLE_L2V_TREE + + // Calculate which index page and offset within for this update + indexPageNo = META_GET_LBA(&mdPtr[i]) / yaFTL.indexPageRatio; + indexPageSub = META_GET_LBA(&mdPtr[i]) % yaFTL.indexPageRatio; + + WMR_ASSERT((yaFTL.tocArray[indexPageNo].indexPage != 0xffffffff) || (yaFTL.tocArray[indexPageNo].cacheIndex != 0xffff)); + + // This is a page that belongs to valid index batch + // Need to get index page to cache and update its content + cacheIndexPtr = yaFTL.tocArray[indexPageNo].cacheIndex; + if (0xffff == cacheIndexPtr) + { + cacheIndexPtr = findFreeCacheEntry(); + if (cacheIndexPtr == 0xffff) + { + /* Cache is full and we need to clear space for new index page */ + cacheIndexPtr = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexPtr == 0xffff) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("failed to evict index page from cache"); + } + } + status = _readPage(yaFTL.tocArray[indexPageNo].indexPage, (UInt8 *)(yaFTL.indexCache[cacheIndexPtr].indexPage), md_index, FALSE32, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Index UECC Page 0x%08x Status 0x%08x", yaFTL.tocArray[indexPageNo].indexPage, status); + return status; + } + yaFTL.freeCachePages--; + // Reset counter since we just pulled this in to the cache + yaFTL.indexCache[cacheIndexPtr].counter = 0; + } + + // Find previous physical location + prevVpn = yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub]; + if (prevVpn != 0xffffffff) + { + // Deprecate validity + if (yaFTL.blockArray[prevVpn / PAGES_PER_SUBLK].validPagesDNo == 0) + { + debug(ERROR, "miscalculated valid pages "); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Incorrect valid pages VPN 0x%08x Valid %d", + prevVpn, yaFTL.blockArray[prevVpn / PAGES_PER_SUBLK].validPagesDNo); + return FTL_CRITICAL_ERROR; + } + yaFTL.blockArray[prevVpn / PAGES_PER_SUBLK].validPagesDNo--; + yaFTL.seaState.data.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages--; +#endif + } + + // Update with new page location + yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub] = yaFTL.gc.data.vpns[i]; + // Update validity + yaFTL.blockArray[yaFTL.gc.data.vpns[i] / PAGES_PER_SUBLK].validPagesDNo++; + yaFTL.seaState.data.validPages++; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages++; +#endif + + // Cross-link cache entry with index page info (redunant if it was already touched but it's ok) + yaFTL.indexCache[cacheIndexPtr].tocEntry = indexPageNo; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexPtr; + + // Mark previous index page as invalid if we just sucked it into cache + if (yaFTL.tocArray[indexPageNo].indexPage != 0xffffffff) + { + yaFTL.blockArray[(yaFTL.tocArray[indexPageNo].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[indexPageNo].indexPage = 0xffffffff; + } + + // Mark cache entry as being dirty and touch the counter + yaFTL.indexCache[cacheIndexPtr].status = IC_DIRTY_PAGE; + if (yaFTL.indexCache[cacheIndexPtr].counter < YAFTL_INDEX_CACHE_COUNTER_LIMIT) + yaFTL.indexCache[cacheIndexPtr].counter++; + } + + return FTL_SUCCESS; +} + +static ANDStatus WriteZoneIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC) +{ + BOOL32 BoolStatus; + UInt8 i; + UInt32 count, thisCount, thisOfs; + PageMeta_t *mdPtr = &yaFTL.gc.index.meta[0]; + + thisOfs = 0; + count = c->curZoneSize; + + // While we still have data we want to move, + while (count) + { + // And if we have space left in this block, + if (yaFTL.wrState.index.nextPage < (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + thisCount = WMR_MIN((UInt32)((PAGES_PER_SUBLK - yaFTL.controlPageNo) - yaFTL.wrState.index.nextPage), (UInt32)count); + + // Fill in metadata + SetupMeta_IndexGC(&mdPtr[thisOfs], thisCount); + + // Write the data + BoolStatus = _writeMultiPages(yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, thisCount, &yaFTL.gc.index.zone[thisOfs * BYTES_PER_PAGE], &mdPtr[thisOfs], FALSE32); + if (BoolStatus == TRUE32) + { + for (i = 0; i < thisCount; i++) + { + // Update block TOC + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[yaFTL.wrState.index.nextPage + i], &mdPtr[thisOfs + i]); + yaFTL.tocArray[META_GET_IPN(&mdPtr[thisOfs + i])].indexPage = yaFTL.wrState.index.block * PAGES_PER_SUBLK + yaFTL.wrState.index.nextPage + i; + } + + // Update valid counts + yaFTL.blockArray[yaFTL.wrState.index.block].validPagesINo += thisCount; + yaFTL.blockArray[c->chosenBlock].validPagesINo -= thisCount; + c->pagesCopied += thisCount; + + yaFTL.wrState.index.nextPage += thisCount; + thisOfs += thisCount; + } + else + { + if(addBlockToEraseNowList(yaFTL.wrState.index.block) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", yaFTL.wrState.index.block); + } + WorkFifo_Enq(&c->workFifo, c->chosenBlock); + WorkFifo_Enq(&c->workFifo, yaFTL.wrState.index.block); + allocateBlock(yaFTL.wrState.index.block, 0, 0); + return FTL_CRITICAL_ERROR; + } + + // Move along + count -= thisCount; + } + + // Want to write more data but out of space? + if (count && (yaFTL.wrState.index.nextPage >= (PAGES_PER_SUBLK - yaFTL.controlPageNo))) + { + // Write the block TOC + writeCurrentBlockTOC(0); + + // Move to the next block + allocateBlock(yaFTL.wrState.index.block, 0, 0); + WMR_ASSERT(0 == yaFTL.wrState.index.nextPage); + } + } + + // And get outta here + return FTL_SUCCESS; +} + +#endif // AND_READONLY + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.h new file mode 100644 index 0000000..dd17c8a --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_gc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_GC_H__ +#define __YAFTL_GC_H__ + +#include "yaFTL_whoami.h" +#include "ANDTypes.h" + +// General setup/close +extern ANDStatus YAFTL_GC_Init(void); +extern void YAFTL_GC_Close(void); + +// Called by Write +extern void YAFTL_GC_PreWrite(UInt32 writeSize); + +// For error recovery +extern void YAFTL_GC_Data_Enq(UInt32 block); +extern UInt32 YAFTL_GC_Data_Deq_sb(UInt32 block); +extern void YAFTL_GC_Index_Enq(UInt32 block); + +// Direct access to the machines +extern ANDStatus YAFTL_GC_Index(UInt32 block, BOOL32 scrubOnUECC); +extern ANDStatus YAFTL_GC_Data(UInt32 block, BOOL32 scrubOnUECC); + +#ifdef AND_READONLY +#define CheckBlockDist(x) +#else +extern void CheckBlockDist(void); +#endif + +#endif // ----- #ifndef __YAFTL_GC_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta.h new file mode 100644 index 0000000..d462e82 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef __YAFTL_META_H__ +#define __YAFTL_META_H__ + +#include "yaFTL_whoami.h" +#include "WMROAM.h" + +#if NAND_PPN +#include "yaFTL_meta_ppn.h" +#else +// Default to raw to avoid compilation errors--meta isn't needed by some of the parsers that include yaFTLTypes.h +#include "yaFTL_meta_raw.h" +#endif + +#endif // __YAFTL_META_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.c new file mode 100644 index 0000000..67cb451 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "yaFTL_whoami.h" +#include "yaFTL_meta_ppn.h" +#include "WMRConfig.h" +#include "yaFTLTypes.h" + +extern yaFTL_t yaFTL; + + +void SetupMeta_Data(PageMeta_t *__meta, UInt32 lba, UInt32 count) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_DATA; + m->c.FTLFlags = 0; + m->lba = lba; + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + m->userSeq = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + + // Next + lba++; + m++; + } +} + +void SetupMeta_Data_UECC(PageMeta_t *__meta) +{ + __meta->c.FTLFlags |= PFLAG_UECC; +} + +void SetupMeta_Index(PageMeta_t *__meta, UInt32 ipn) +{ + PageMeta_Idx_t *m = (PageMeta_Idx_t*)__meta; + + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_IDX; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + m->baseLba = ipn * yaFTL.indexPageRatio; +} + +void SetupMeta_Data_BTOC(PageMeta_t *__meta) +{ + PageMeta_BTOC_t *m = (PageMeta_BTOC_t*)__meta; + + m->c.PageType = PAGETYPE_FTL_BTOC_DATA; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.data.minWeaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.data.minWeaveSeq >> 16); + m->maxWeaveSeqAdd = (UInt32)(yaFTL.wrState.weaveSeq - yaFTL.wrState.data.minWeaveSeq); + m->__rfu__ = 0xffffffff; +} + +void SetupMeta_Index_BTOC(PageMeta_t *__meta) +{ + PageMeta_BTOC_t *m = (PageMeta_BTOC_t*)__meta; + + m->c.PageType = PAGETYPE_FTL_BTOC_IDX; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.index.minWeaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.index.minWeaveSeq >> 16); + m->maxWeaveSeqAdd = (UInt32)(yaFTL.wrState.weaveSeq - yaFTL.wrState.index.minWeaveSeq); + m->__rfu__ = 0xffffffff; +} + +void SetupMeta_IndexGC(PageMeta_t *__meta, UInt32 count) +{ + PageMeta_Idx_t *m = (PageMeta_Idx_t*)__meta; + + while (count--) { + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_IDX; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + + // Next + m++; + } +} + +void SetupMeta_DataGC(PageMeta_t *__meta, UInt32 count) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_DATA; + // Don't touch FTLFlags--might have uECC flag + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + // Don't touch LBA or userSeq + + // Next + m++; + } +} + +void SetupMeta_Cxt(PageMeta_t *__meta, UInt64 weaveSeq) +{ + PageMeta_Cxt_t *m = (PageMeta_Cxt_t*)__meta; + + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_CXT; + m->c.FTLFlags = 0; + m->c.weaveLo = weaveSeq; + m->c.weaveHi = (UInt32)(weaveSeq >> 16); + m->__rfu1__ = 0; + m->__rfu2__ = 0; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.h new file mode 100644 index 0000000..b946567 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_ppn.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_META_PPN_H__ +#define __YAFTL_META_PPN_H__ + +#include "yaFTL_whoami.h" +#include "WMROAM.h" + + + +// PageType defines-- +#define PAGETYPE_FTL_DATA (AND_SPARE_TYPE_REGION_FTL + 0x00) +#define PAGETYPE_FTL_BTOC_DATA (AND_SPARE_TYPE_REGION_FTL + 0x1C) +#define PAGETYPE_FTL_BTOC_IDX (AND_SPARE_TYPE_REGION_FTL + 0x1D) +#define PAGETYPE_FTL_IDX (AND_SPARE_TYPE_REGION_FTL + 0x1E) +#define PAGETYPE_FTL_CXT (AND_SPARE_TYPE_REGION_FTL + 0x1F) + + +// FTLFlags defines-- +#define PFLAG_UECC 0x01 // uECC state for data pages (moved by GC and thus re-encoded) + + +// Must be 16 bytes on PPN + +typedef struct { + UInt8 PageType; + UInt8 FTLFlags; + UInt16 weaveLo; + UInt32 weaveHi; +} PageMeta_Common_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 __f1; + UInt32 __f2; +} PageMeta_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 userSeq; + UInt32 lba; +} PageMeta_Data_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 maxWeaveSeqAdd; + UInt32 __rfu__; +} PageMeta_BTOC_t; + +typedef struct { + PageMeta_Common_t c; + UInt16 __rfu__; + UInt16 lbaAdd; + UInt32 baseLba; +} PageMeta_Idx_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 __rfu1__; + UInt32 __rfu2__; +} PageMeta_Cxt_t; + + +typedef UInt64 WeaveSeq_t; + + +// Setup +extern void SetupMeta_Data(PageMeta_t *__meta, UInt32 lba, UInt32 count); +extern void SetupMeta_Data_UECC(PageMeta_t *__meta); + +extern void SetupMeta_Index(PageMeta_t *__meta, UInt32 ipn); + +extern void SetupMeta_Data_BTOC(PageMeta_t *__meta); +extern void SetupMeta_Index_BTOC(PageMeta_t *__meta); + +extern void SetupMeta_IndexGC(PageMeta_t *__meta, UInt32 count); +extern void SetupMeta_DataGC(PageMeta_t *__meta, UInt32 count); + +extern void SetupMeta_Cxt(PageMeta_t *__meta, UInt64 weaveSeq); + +#define META_SET_LBA(meta, foo) do { ((PageMeta_Data_t*)(meta))->lba = (foo); } while (0) +#define META_SET_WEAVESEQ(meta) do { (meta)->c.weaveLo = (UInt16)yaFTL.wrState.weaveSeq; (meta)->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); } while (0) +#define META_SET_BTOC_DATA(meta) do { (meta)->c.PageType = PAGETYPE_FTL_BTOC_DATA; } while (0) +#define META_SET_IPN_FROM_BTOC(meta, bte) do { ((PageMeta_Idx_t*)(meta))->baseLba = (bte); } while (0) +#define BTOC_SET_FROM_IPN(bte, meta) do { (bte) = ((PageMeta_Idx_t*)(meta))->baseLba; } while (0) + + +// Query +#define BTOC_GET_IPN(bte) ((bte) / yaFTL.indexPageRatio) +#define META_ARE_FLAGS_FF(meta) ((0xff == (meta)->c.PageType) && (0xff == (meta)->c.FTLFlags)) +#define META_IS_IDX(meta) (PAGETYPE_FTL_IDX == (meta)->c.PageType) +#define META_IS_DATA(meta) (PAGETYPE_FTL_DATA == (meta)->c.PageType) +#define META_IS_CXT(meta) (PAGETYPE_FTL_CXT == (meta)->c.PageType) +#define META_IS_BTOC_IDX(meta) (PAGETYPE_FTL_BTOC_IDX == (meta)->c.PageType) +#define META_IS_BTOC_DATA(meta) (PAGETYPE_FTL_BTOC_DATA == (meta)->c.PageType) +#define META_IS_BTOC(meta) ((PAGETYPE_FTL_BTOC_IDX == (meta)->c.PageType) || (PAGETYPE_FTL_BTOC_DATA == ((meta)->c.PageType))) +#define META_IS_UECC(meta) ((meta)->c.FTLFlags & PFLAG_UECC) +#define META_GET_WEAVESEQ(meta) ((UInt64)(meta)->c.weaveLo | ((UInt64)(meta)->c.weaveHi << 16)) +#define META_GET_LBA(meta) (((PageMeta_Data_t*)(meta))->lba) +#define META_GET_IPN(meta) (((PageMeta_Idx_t*)(meta))->baseLba / yaFTL.indexPageRatio) +#define META_GET_IPNRAW(meta) (((PageMeta_Idx_t*)(meta))->baseLba) +#define META_GET_ALL_FLAGS(meta) (((UInt32)((meta)->c.FTLFlags) << 8) | (UInt32)((meta)->c.PageType)) + + + +#endif // __YAFTL_META_PPN_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.c new file mode 100644 index 0000000..d2a70ba --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "yaFTL_whoami.h" +#include "yaFTL_meta_raw.h" +#include "WMRConfig.h" +#include "yaFTLTypes.h" + +extern yaFTL_t yaFTL; + + +void SetupMeta_Data(PageMeta_t *meta, UInt32 lba, UInt32 count) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.data.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.data.block; + } + + while (count--) + { + meta->FTLFlags = PAGETYPE_FTL_DATA; + meta->lba = lba; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; + + // Next + lba++; + meta++; + } +} + +void SetupMeta_Data_UECC(PageMeta_t *meta) +{ + meta->FTLFlags |= PFLAG_UECC; +} + +void SetupMeta_Index(PageMeta_t *meta, UInt32 ipn) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.index.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.index.block; + } + + meta->FTLFlags = PAGETYPE_FTL_IDX; + meta->lba = ipn; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; +} + +void SetupMeta_Data_BTOC(PageMeta_t *meta) +{ + meta->FTLFlags = PFLAG_BTOC; + meta->weaveSeq = (UInt32)yaFTL.wrState.data.minWeaveSeq; +} + +void SetupMeta_Index_BTOC(PageMeta_t *meta) +{ + meta->FTLFlags = PAGETYPE_FTL_IDX | PFLAG_BTOC; + meta->weaveSeq = (UInt32)yaFTL.wrState.index.minWeaveSeq; +} + +void SetupMeta_IndexGC(PageMeta_t *meta, UInt32 count) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.index.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.index.block; + } + + while (count--) + { + meta->FTLFlags = PAGETYPE_FTL_IDX; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; + + // Next + meta++; + } +} + +void SetupMeta_DataGC(PageMeta_t *meta, UInt32 count) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.data.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.data.block; + } + + while (count--) + { + // Or in the page type and clear all but uECC flag + meta->FTLFlags = (meta->FTLFlags & PFLAG_UECC) | PAGETYPE_FTL_DATA; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; + + // Next + meta++; + } +} + +void SetupMeta_Cxt(PageMeta_t *meta, UInt64 weaveSeq) +{ + yaFTL.wrState.weaveSeq++; + + meta->FTLFlags = PAGETYPE_FTL_CXT; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.h new file mode 100644 index 0000000..1fb17e6 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_meta_raw.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_META_RAW_H__ +#define __YAFTL_META_RAW_H__ + +#include "yaFTL_whoami.h" +#include "WMROAM.h" + +// Page FTLFlags +#define PAGETYPE_FTL_IDX 0x04 +#define PAGETYPE_FTL_DATA 0x10 +#define PAGETYPE_FTL_CXT 0x20 +#define PFLAG_BTOC 0x08 +#define PFLAG_UECC 0x40 // uECC state (moved by GC and thus re-encoded) + +// Must be 12 bytes on raw +typedef struct +{ + UInt32 lba; // formerly known as logicalPageNo + UInt32 weaveSeq; // formerly known as allocationNo + UInt8 __DEPRECATED_seqNo; + UInt8 FTLFlags; + UInt16 __pad; +} PageMeta_t; + +typedef UInt32 WeaveSeq_t; + + +extern void SetupMeta_Data(PageMeta_t *meta, UInt32 lba, UInt32 count); +extern void SetupMeta_Data_UECC(PageMeta_t *meta); + +extern void SetupMeta_Index(PageMeta_t *meta, UInt32 ipn); + +extern void SetupMeta_Data_BTOC(PageMeta_t *meta); +extern void SetupMeta_Index_BTOC(PageMeta_t *meta); + +extern void SetupMeta_IndexGC(PageMeta_t *meta, UInt32 count); +extern void SetupMeta_DataGC(PageMeta_t *meta, UInt32 count); + +extern void SetupMeta_Cxt(PageMeta_t *meta, UInt64 weaveSeq); + +#define META_SET_LBA(meta, foo) do { (meta)->lba = (foo); } while (0) +#define META_SET_WEAVESEQ(meta) do { \ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.index.block) \ + { \ + yaFTL.wrState.weaveSeq++; \ + yaFTL.wrState.lastBlock = yaFTL.wrState.index.block; \ + } \ + (meta)->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; \ +} while(0) +#define META_SET_BTOC_DATA(meta) do { (meta)->FTLFlags = PFLAG_BTOC; } while (0) +#define META_SET_IPN_FROM_BTOC(meta, bte) do { (meta)->lba = (bte); } while (0) +#define BTOC_SET_FROM_IPN(bte, meta) do { (bte) = (meta)->lba; } while (0) + + +// Query +#define BTOC_GET_IPN(bte) (bte) +#define META_ARE_FLAGS_FF(meta) (0xff == (meta)->FTLFlags) +#define META_IS_IDX(meta) ((meta)->FTLFlags & PAGETYPE_FTL_IDX) +#define META_IS_DATA(meta) ((meta)->FTLFlags & PAGETYPE_FTL_DATA) +#define META_IS_CXT(meta) ((meta)->FTLFlags & PAGETYPE_FTL_CXT) +#define META_IS_BTOC_IDX(meta) (((meta)->FTLFlags & PAGETYPE_FTL_IDX) && ((meta)->FTLFlags & PFLAG_BTOC)) +#define META_IS_BTOC_DATA(meta) (!((meta)->FTLFlags & PAGETYPE_FTL_IDX) && ((meta)->FTLFlags & PFLAG_BTOC)) +#define META_IS_BTOC(meta) ((meta)->FTLFlags & PFLAG_BTOC) +#define META_IS_UECC(meta) ((meta)->FTLFlags & PFLAG_UECC) +#define META_GET_WEAVESEQ(meta) ((meta)->weaveSeq) +#define META_GET_LBA(meta) ((meta)->lba) +#define META_GET_IPN(meta) ((meta)->lba) +#define META_GET_IPNRAW(meta) ((meta)->lba) +#define META_GET_ALL_FLAGS(meta) ((UInt32)((meta)->FTLFlags)) + + + +#endif // __YAFTL_META_RAW_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_whoami.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_whoami.h new file mode 100644 index 0000000..67abbf1 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/FTL/yaFTL_whoami.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_WHOAMI_H__ +#define __YAFTL_WHOAMI_H__ + +#define NAND_PPN 1 + +#endif + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMisc.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMisc.c new file mode 100644 index 0000000..719c39c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMisc.c @@ -0,0 +1,842 @@ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "PPNMiscTypes.h" +#include "PPN_FIL.h" +#include "FIL.h" + +/* print functions - for now i am keeping it old school */ +#if (defined (AND_SIMULATOR) && AND_SIMULATOR) +#define VFL_ERR_PRINT(x) WMR_PANIC x +#else +#define VFL_ERR_PRINT(x) WMR_RTL_PRINT(x) +#endif +#define VFL_WRN_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (VFL_LOG_MSG_ON) +#define VFL_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else +#define VFL_LOG_PRINT(x) +#endif +#define VFL_INF_MSG_ON (0) +#if (defined (VFL_INF_MSG_ON) && VFL_INF_MSG_ON) +#define VFL_INF_PRINT(x, y) { if (x) { WMR_RTL_PRINT(y); } } +#else +#define VFL_INF_PRINT(x, y) +#endif + +#define BYTES_PER_PAGE_META (dev->lbas_per_page * dev->lba_meta_bytes_buffer) + +#define PPNMISC_VERIFY_CONVERSION (0) + +#if PPNMISC_VERIFY_CONVERSION +static BOOL32 +ppnMiscTestConversionFunctions + (PPN_DeviceInfo * dev); +#endif // PPNMISC_VERIFY_CONVERSION + +/* + * Name: ppnMiscGetCAUFromBank + * Input: bank + * Return value: CAU inside a chip enable + */ +UInt16 +ppnMiscGetCAUFromBank + (PPN_DeviceInfo * dev, + UInt16 bank) +{ + return (UInt16)((bank / dev->num_channels) % dev->caus_per_ce); +} + +/* + * Name: ppnMiscGetChannelFromBank + * Input: bank + * Return value: channel this bank belongs to + */ +UInt16 +ppnMiscGetChannelFromBank + (PPN_DeviceInfo * dev, + UInt16 bank) +{ + return (UInt16)(bank % dev->num_channels); +} + +/* + * ppnMiscGetCEIdxFromBank + * Input: bank + * Return value: chip enable index (location) within a channel + */ +UInt16 +ppnMiscGetCEIdxFromBank + (PPN_DeviceInfo * dev, + UInt16 bank) +{ + return (UInt16)((bank / (dev->caus_per_ce * dev->num_channels)) % dev->ces_per_channel); +} + +/* + * Name: ppnMiscGetCEFromBank + * Input: bank + * Return value: physical chip enable value used by the FIL layer + */ +UInt16 +ppnMiscGetCEFromBank + (PPN_DeviceInfo * dev, + UInt16 bank) +{ + UInt16 chip_enable_idx, channel; + + chip_enable_idx = ppnMiscGetCEIdxFromBank(dev, bank); + channel = ppnMiscGetChannelFromBank(dev, bank); + return dev->chip_enable_table[channel][chip_enable_idx]; +} + +/* + * Name: ppnMiscGetCEIdxFromChipEnable + * Input: channel, physical chip enable + * Return value: chip enable index inside the specified channel + */ +UInt16 +ppnMiscGetCEIdxFromChipEnable + (PPN_DeviceInfo * dev, + UInt16 channel, + UInt16 chip_enable) +{ + UInt16 chip_enable_idx; + + WMR_ASSERT(channel < dev->num_channels); + for (chip_enable_idx = 0; chip_enable_idx < dev->ces_per_channel; chip_enable_idx++) + { + if (dev->chip_enable_table[channel][chip_enable_idx] == chip_enable) + { + break; + } + } + WMR_ASSERT(chip_enable_idx < dev->ces_per_channel); + return chip_enable_idx; +} + +/* + * Name: ppnMiscConvertToPPNPageAddress + * Input: cau, block, page offset, slc mode + * Return value: physical ppn page address + */ +UInt32 +ppnMiscConvertToPPNPageAddress + (PPN_DeviceInfo * dev, + UInt16 cau, + UInt16 block, + UInt16 page, + BOOL32 slcAddress) +{ + UInt32 ppnPageAddr; + + ppnPageAddr = (UInt32)page; + ppnPageAddr |= (UInt32)((UInt32)block << dev->bits_per_page_addr); + ppnPageAddr |= (UInt32)((UInt32)cau << (dev->bits_per_page_addr + dev->bits_per_block_addr)); + ppnPageAddr |= (UInt32)((UInt32)(slcAddress ? 1 : 0) << + (dev->bits_per_page_addr + dev->bits_per_block_addr + dev->bits_per_cau_addr)); + + return ppnPageAddr; +} + +/* + * Name: ppnMiscConvertPhysicalAddressToCauBlockPage + * Input: physcial page address (row address) + * Output: cau, block, page offset + * Return value: none + */ +void +ppnMiscConvertPhysicalAddressToCauBlockPage + (PPN_DeviceInfo * dev, + UInt32 page, + UInt16 *cau, + UInt16 *block, + UInt16 *page_offset) +{ + UInt32 mask; + + // get page offset + mask = (1UL << dev->bits_per_page_addr) - 1; + *page_offset = (UInt16)(page & mask); + + // get block + mask = (1UL << dev->bits_per_block_addr) - 1; + page >>= dev->bits_per_page_addr; + *block = (UInt16)(page & mask); + + // get cau + mask = (1UL << dev->bits_per_cau_addr) - 1; + page >>= dev->bits_per_block_addr; + *cau = (UInt16)(page & mask); +} + +/* + * Name: ppnMiscConvertPhysicalAddressToBankBlockPage + * Input: channel, physical chip enable, physcial page address + * Output: bank, block, page offset, slc mode + * Return value: none + */ +void +ppnMiscConvertPhysicalAddressToBankBlockPage + (PPN_DeviceInfo * dev, + UInt16 channel, + UInt16 chip_enable_idx, + UInt32 page, + UInt16 *bank, + UInt16 *block, + UInt16 *page_offset, + BOOL32 *slc) +{ + UInt16 cau; + UInt32 mask; + + // get page offset + mask = (1UL << dev->bits_per_page_addr) - 1; + *page_offset = (UInt16)(page & mask); + + // get block + mask = (1UL << dev->bits_per_block_addr) - 1; + page >>= dev->bits_per_page_addr; + *block = (UInt16)(page & mask); + + // get cau + mask = (1UL << dev->bits_per_cau_addr) - 1; + page >>= dev->bits_per_block_addr; + cau = (UInt16)(page & mask); + + // get SLC bit + page >>= dev->bits_per_cau_addr; + *slc = (page & 1) ? TRUE32 : FALSE32; + + *bank = ((chip_enable_idx * dev->num_channels * dev->caus_per_ce) + + (cau * dev->num_channels) + channel); +} + +/* + * Name: ppnMiscSingleOperation + * Description: this function prepares a command for a low level operation. + * Input: command type, bank, block, page offset, slc mode, data pointer, + * meta pointer + * data pointer, meta pointer + * Return value: operation status + */ +PPNStatusType +ppnMiscSingleOperation + (PPN_DeviceInfo * dev, + PPNCommandStruct * command, + PPNCommand command_type, + PPNOptions options, + UInt16 bank, + UInt16 block, + UInt16 page_offset, + BOOL32 slc, + void *data, + void *meta) +{ + UInt16 cau = 0, channel = 0, i = 0, chip_enable_idx = 0; + UInt8 status; + UInt32 row_addr; + + channel = ppnMiscGetChannelFromBank(dev, bank); + cau = ppnMiscGetCAUFromBank(dev, bank); + chip_enable_idx = ppnMiscGetCEIdxFromBank(dev, bank); + + WMR_MEMSET(command, 0, sizeof(PPNCommandStruct)); + + command->num_pages = 1; + command->lbas = dev->lbas_per_page; + command->command = command_type; + command->options = options; + command->mem_buffers[0].data = data; + command->mem_buffers[0].meta = meta; + command->mem_buffers[0].num_of_lbas = dev->lbas_per_page; // change if this is a small read + row_addr = ppnMiscConvertToPPNPageAddress(dev, cau, block, page_offset, slc); + + switch (command_type) + { + case PPN_COMMAND_READ: + { + command->entry[0].addr.row = row_addr; + command->entry[0].addr.column = 0; + command->entry[0].addr.length = + (dev->lba_meta_bytes_buffer + dev->main_bytes_per_lba) * dev->lbas_per_page; + command->mem_index[0].offset = 0; + command->mem_index[0].idx = 0; // change for sub page reads + command->entry[0].lbas = dev->lbas_per_page; // change for sub page reads + break; + } + +#ifndef AND_READONLY + case PPN_COMMAND_PROGRAM: + case PPN_COMMAND_ERASE: + { + command->entry[0].addr.row = row_addr; + command->mem_index[0].offset = 0; + command->mem_index[0].idx = 0; + command->entry[0].lbas = dev->lbas_per_page; + break; + } +#endif // AND_READONLY + + default: + { + command->entry[0].addr.row = row_addr; + command->mem_index[0].offset = 0; + command->mem_index[0].idx = 0; + command->entry[0].lbas = dev->lbas_per_page; + break; + } + } + + command->entry[0].ceIdx = chip_enable_idx; + for (i = 0; i < dev->ces_per_channel; i++) + { + command->ceInfo[i].ce = dev->chip_enable_table[channel][i]; + command->ceInfo[i].pages = 0; + } + command->ceInfo[chip_enable_idx].pages = 1; + + command->context.device_info = NULL; + command->context.handle = NULL; + command->context.bus_num = channel; + + dev->fil->PerformCommandList(&command, 1); + status = command->page_status_summary; + + return status; +} + +/* + * Name: ppnMiscSingleLbaRead + * Description: this function prepares a command for a low level single LBA read. + * Input: command type, ce, cau, block, page offset, slc mode, data pointer, + * meta pointer + * Return value: operation status + */ +PPNStatusType +ppnMiscSingleLbaRead + (PPN_DeviceInfo * dev, + PPNCommandStruct * command, + PPNCommand command_type, + PPNOptions options, + UInt16 ce, + UInt16 cau, + UInt16 block, + UInt16 page_offset, + UInt8 lba_offset, + BOOL32 slc, + void *data, + void *meta) +{ + UInt16 channel = 0, i = 0, chip_enable_idx = 0; + UInt8 status; + UInt32 row_addr; + + chip_enable_idx = ce % dev->ces_per_channel; + channel = ce / dev->ces_per_channel; + + WMR_MEMSET(command, 0, sizeof(PPNCommandStruct)); + + command->num_pages = 1; + command->lbas = 1; + command->command = command_type; + command->options = options; + command->mem_buffers[0].data = data; + command->mem_buffers[0].meta = meta; + command->mem_buffers[0].num_of_lbas = 1; + row_addr = ppnMiscConvertToPPNPageAddress(dev, cau, block, page_offset, slc); + + switch (command_type) + { + case PPN_COMMAND_READ: + { + command->entry[0].addr.row = row_addr; + command->entry[0].addr.column = lba_offset * (dev->main_bytes_per_lba + dev->lba_meta_bytes_buffer); + command->entry[0].addr.length = + (dev->lba_meta_bytes_buffer + dev->main_bytes_per_lba); + command->mem_index[0].offset = 0; + command->mem_index[0].idx = command->mem_buffers_count; + command->entry[0].lbas = 1; + break; + } + default: + { + VFL_ERR_PRINT((TEXT("PPNMISC:ERR] currently only read supported: (l:%d)\n"), __LINE__)); + return 0; + } + } + + command->entry[0].ceIdx = chip_enable_idx; + for (i = 0; i < dev->ces_per_channel; i++) + { + command->ceInfo[i].ce = dev->chip_enable_table[channel][i]; + command->ceInfo[i].pages = 0; + } + command->ceInfo[chip_enable_idx].pages = 1; + + command->context.device_info = NULL; + command->context.handle = NULL; + command->context.bus_num = channel; + + dev->fil->PerformCommandList(&command, 1); + status = command->page_status_summary; + + return status; +} + +/* + * Name: ppnMiscFillDevStruct + * Description: this function fills the device information struct for vfl and fpart. + * Input: fil function struct + * Return value: none + */ +void +ppnMiscFillDevStruct + (PPN_DeviceInfo * dev, + LowFuncTbl *fil) +{ + UInt16 channel, chip_enable_idx; + + dev->fil = fil; + dev->num_channels = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CHANNELS); + dev->ces_per_channel = fil->GetDeviceInfo(AND_DEVINFO_NUM_OF_CES_PER_CHANNEL); + dev->caus_per_ce = fil->GetDeviceInfo(AND_DEVINFO_CAUS_PER_CE); + dev->blocks_per_cau = fil->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU); + dev->pages_per_block_slc = fil->GetDeviceInfo(AND_DEVINFO_SLC_PAGES_PER_BLOCK); + dev->pages_per_block_mlc = fil->GetDeviceInfo(AND_DEVINFO_MLC_PAGES_PER_BLOCK); + dev->f_match_oddeven_blocks = (BOOL32)fil->GetDeviceInfo(AND_DEVINFO_MATCH_ODDEVEN_CAUS); + dev->bits_per_cau_addr = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_CAU_ADDRESS); + dev->bits_per_page_addr = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_PAGE_ADDRESS); + dev->bits_per_block_addr = fil->GetDeviceInfo(AND_DEVINFO_BITS_PER_BLOCK_ADDRESS); + dev->main_bytes_per_page = fil->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + dev->num_of_banks = dev->num_channels * dev->ces_per_channel * dev->caus_per_ce; + dev->lbas_per_page = fil->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + dev->main_bytes_per_lba = dev->main_bytes_per_page / dev->lbas_per_page; + dev->lba_meta_bytes_buffer = fil->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + dev->lba_meta_bytes_valid = fil->GetDeviceInfo(AND_DEVINFO_FIL_META_VALID_BYTES); + dev->max_pages_in_prep_per_ce = fil->GetDeviceInfo(AND_DEVINFO_FIL_PREP_BUFFER_ENTRIES); + // dev->f_match_oddeven_blocks = (fil->GetDeviceInfo(AND_DEVINFO_FIL_MATCH_ODD_EVEN_BLKS) ? + // TRUE32 : FALSE32); + +// WMR_PRINT(ALWAYS, "num_of_banks = %d (num_channels = %d, ces_per_channel = %d, caus_per_ce = %d\n", +// dev->num_of_banks, dev->num_channels, dev->ces_per_channel, dev->caus_per_ce); + + dev->pages_per_sublk = dev->num_of_banks * dev->pages_per_block_mlc; + for (channel = 0; channel < dev->num_channels; channel++) + { + for (chip_enable_idx = 0; chip_enable_idx < dev->ces_per_channel; chip_enable_idx++) + { + PPNChipEnableStruct chip_enable_struct; + UInt32 size; + chip_enable_struct.channel = channel; + chip_enable_struct.chip_enable_idx = chip_enable_idx; + FIL_GetStruct(AND_STRUCT_FIL_GET_CE_INFO, &chip_enable_struct, &size); + dev->chip_enable_table[channel][chip_enable_idx] = chip_enable_struct.physical_chip_enable; + } + } + +#if PPNMISC_VERIFY_CONVERSION + // debug code - verify that the conversion code works correctly + ppnMiscTestConversionFunctions(dev); +#endif // PPNMISC_VERIFY_CONVERSION +} + +/* + * Name: ppnMiscIsBlockGood + * Description: this function takes the bad block table bitmap and checks if a + * block is initally marked bad or not. + * Input: bad block table bitmap (as read from the PPN device), block + * Return value: none + */ +BOOL32 +ppnMiscIsBlockGood + (UInt8 *bbt, + UInt16 block) +{ + UInt16 byte; + UInt8 bit; + + byte = block >> 3; + bit = 0x80 >> (block & 0x0007); + return bbt[byte] & bit ? TRUE32 : FALSE32; +} + +#ifndef AND_READONLY + +BOOL32 +ppnMiscTestSpecialBlock + (PPN_DeviceInfo * dev, + PPNCommandStruct * command, + UInt16 bank, + UInt16 block, + UInt8 spareType) +{ + // try the block (erase, program, read) twice + UInt16 page_offset, i; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + BOOL32 slc = TRUE32; + BOOL32 pages; + + for (i = 0; i < 2; i++) + { + PPNStatusType status; + + // alternate between slc and mlc + slc = (slc ? FALSE32 : TRUE32); + pages = (slc ? dev->pages_per_block_slc : dev->pages_per_block_mlc); + + // erase + status = ppnMiscSingleOperation(dev, command, PPN_COMMAND_ERASE, PPN_OPTIONS_IGNORE_BAD_BLOCK, + bank, block, 0, slc, NULL, NULL); + if (status & (PPN_ERASE_STATUS_RETIRE | PPN_ERASE_STATUS_FAIL)) + { + VFL_WRN_PRINT((TEXT("PPNMISC:WRN] testing special block - failed erasing (0x%X, 0x%X) (l:%d)\n"), bank, + block, __LINE__)); + goto return_error; + } + + // program + for (page_offset = 0; page_offset < pages; page_offset++) + { + WMR_MEMSET(buf->pData, (UInt8)page_offset, dev->main_bytes_per_page); + WMR_MEMSET(buf->pSpare, spareType, BYTES_PER_PAGE_META); + status = ppnMiscSingleOperation(dev, command, PPN_COMMAND_PROGRAM, PPN_NO_OPTIONS, + bank, block, page_offset, slc, buf->pData, buf->pSpare); + if (status & (PPN_PROGRAM_STATUS_FAIL)) + { + VFL_WRN_PRINT((TEXT( + "PPNMISC:WRN] testing special block - failed programming (0x%X, 0x%X, 0x%X) (l:%d)\n"), + bank, block, + page_offset, __LINE__)); + goto return_error; + } + } + // verify + for (page_offset = 0; page_offset < pages; page_offset++) + { + WMR_MEMSET(buf->pData, 0, dev->main_bytes_per_page); + WMR_MEMSET(buf->pSpare, 0, BYTES_PER_PAGE_META); + status = ppnMiscSingleOperation(dev, command, PPN_COMMAND_READ, PPN_NO_OPTIONS, bank, block, page_offset, + slc, buf->pData, buf->pSpare); + if (status & (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_RETIRE)) + { + VFL_WRN_PRINT((TEXT("PPNMISC:WRN] testing special block - failed reading (0x%X, 0x%X, 0x%X) (l:%d)\n"), + bank, block, page_offset, __LINE__)); + goto return_error; + } + if (buf->pData[0] != (UInt8)page_offset || buf->pSpare[0] != spareType) + { + VFL_WRN_PRINT((TEXT("PPNMISC:WRN] testing special block - failed verifying (0x%X, 0x%X, 0x%X) (l:%d)\n"), + bank, block, page_offset, __LINE__)); + goto return_error; + } + } + } + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +#endif // AND_READONLY + +BOOL32 +ppnMiscAddPhysicalAddressToCommandStructure + (PPN_DeviceInfo * dev, + PPNCommandStruct **commands, + UInt16 channel, + UInt16 chip_enable_idx, + UInt16 cau, + UInt16 block, + UInt16 page_offset, + BOOL32 slc, + UInt8 pba_offset, + UInt8 pba_count, + UInt8 mem_index, + UInt16 mem_offset) +{ + UInt16 idx = 0; + UInt32 page_address = 0; + PPNCommandStruct *command; + + page_address = ppnMiscConvertToPPNPageAddress(dev, cau, block, page_offset, FALSE32); + command = commands[channel]; + // check for buffer overflow + if ((command->num_pages >= PPN_MAX_PAGES) || + (command->ceInfo[chip_enable_idx].pages >= PPN_MAX_PAGES_PER_CE) || + (command->ceInfo[chip_enable_idx].pages >= dev->max_pages_in_prep_per_ce)) + { + return FALSE32; + } + + // use idx as a temp variable for index in this specific channel + idx = commands[channel]->num_pages; + command->entry[idx].ceIdx = chip_enable_idx; + switch (command->command) + { + case PPN_COMMAND_READ: + { + command->entry[idx].addr.row = page_address; + command->entry[idx].addr.column = pba_offset * (dev->main_bytes_per_lba + dev->lba_meta_bytes_buffer); + command->entry[idx].addr.length = pba_count * (dev->main_bytes_per_lba + dev->lba_meta_bytes_buffer); + command->mem_index[idx].offset = mem_offset; + command->mem_index[idx].idx = mem_index; + command->entry[idx].lbas = pba_count; + break; + } + +#ifndef AND_READONLY + case PPN_COMMAND_PROGRAM: + case PPN_COMMAND_ERASE: + { + command->entry[idx].addr.row = page_address; + command->mem_index[idx].offset = mem_offset; + command->mem_index[idx].idx = mem_index; + command->entry[idx].lbas = dev->lbas_per_page; + break; + } +#endif // AND_READONLY + + default: + { + command->entry[idx].addr.row = page_address; + command->mem_index[idx].offset = mem_offset; + command->mem_index[idx].idx = mem_index; + command->entry[idx].lbas = dev->lbas_per_page; + break; + } + } + commands[channel]->lbas += command->entry[idx].lbas; + command->num_pages++; + + // use idx as a temp variable for index in prep buffer + command->ceInfo[chip_enable_idx].pages++; + + return TRUE32; +} + +/* + * Name: ppnMiscAddMemoryToCommandStructure + * Output: pointer to commands structure + * Input: command type, data pointer, meta pointer. + * Return value: TRUE32 for success otherwise FALSE32 + */ +BOOL32 +ppnMiscAddMemoryToCommandStructure + (PPN_DeviceInfo *dev, + PPNCommandStruct **commands, + UInt16 num_of_command_structs, + void *data, + void *meta, + UInt8 num_of_lbas) +{ + UInt16 struct_idx; + + for (struct_idx = 0; struct_idx < num_of_command_structs; struct_idx++) + { + PPNCommandStruct *command = commands[struct_idx]; + PPNMemoryEntry *mem = &command->mem_buffers[command->mem_buffers_count]; + + if (command->mem_buffers_count >= PPN_MAX_MEM_BUFFERS) + { + return FALSE32; + } + + mem->data = data; + mem->meta = meta; + mem->num_of_lbas = num_of_lbas; + command->mem_buffers_count++; + } + return TRUE32; +} + +/* + * Name: ppnMiscInitCommandStructure + * Output: pointer to commands structure + * Input: command type, data pointer, meta pointer. + * Return value: none + */ +void +ppnMiscInitCommandStructure + (PPN_DeviceInfo * dev, + PPNCommandStruct **commands, + UInt16 num_of_command_structs, + PPNCommand command, + PPNOptions options) +{ + UInt16 i, j; + + for (i = 0; i < num_of_command_structs; i++) + { + WMR_MEMSET(commands[i], 0, sizeof(PPNCommandStruct)); + // initilaze the command structure fields + commands[i]->options = options; + commands[i]->num_pages = 0; + commands[i]->lbas = 0; + commands[i]->command = command; + commands[i]->mem_buffers[0].data = NULL; + commands[i]->mem_buffers[0].meta = NULL; + commands[i]->mem_buffers_count = 0; + for (j = 0; j < dev->ces_per_channel; j++) + { + commands[i]->ceInfo[j].ce = dev->chip_enable_table[i][j]; + commands[i]->ceInfo[j].pages = 0; + } + commands[i]->context.device_info = NULL; + commands[i]->context.handle = NULL; + commands[i]->context.bus_num = i; + } +} + +#if PPNMISC_VERIFY_CONVERSION + +static BOOL32 +_verifyAnAddress + (PPN_DeviceInfo * dev, + UInt16 bank, + UInt16 block, + UInt16 page_offset, + BOOL32 slc) +{ + UInt16 chip_enable_idx, channel, cau; + UInt32 page_address = 0, line_failed = 0; + UInt16 temp_bank, temp_block, temp_page_offset; + BOOL32 temp_slc; + + // convert to a physical address + cau = ppnMiscGetCAUFromBank(dev, bank); + if (!(cau < dev->caus_per_ce)) + { + line_failed = __LINE__; + goto return_error; + } + page_address = ppnMiscConvertToPPNPageAddress(dev, cau, block, page_offset, slc); + chip_enable_idx = ppnMiscGetCEIdxFromBank(dev, bank); + if (!(chip_enable_idx < dev->ces_per_channel)) + { + line_failed = __LINE__; + goto return_error; + } + channel = ppnMiscGetChannelFromBank(dev, bank); + if (!(channel < dev->num_channels)) + { + line_failed = __LINE__; + goto return_error; + } + + // convert back + ppnMiscConvertPhysicalAddressToBankBlockPage(dev, channel, chip_enable_idx, page_address, + &temp_bank, &temp_block, &temp_page_offset, &temp_slc); + if (!((temp_bank == bank) && (temp_block == block) && (temp_page_offset == page_offset) && (slc == temp_slc))) + { + line_failed = __LINE__; + goto return_error; + } + + return TRUE32; + + return_error: + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] fail address conversion: (l:%d)\n"), line_failed)); + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] bank:0x%X, block:0x%X, page_offset:0x%X, slc:0x%X\n"), + bank, block, page_offset, slc)); + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] channel:0x%X, chip_enable_idx:0x%X, cau:0x%X\n"), + channel, chip_enable_idx, cau)); + VFL_WRN_PRINT((TEXT("PPNMISC:ERR] temp_bank:0x%X, temp_block:0x%X, temp_page_offset:0x%X, temp_slc:0x%X\n"), + temp_bank, temp_block, temp_page_offset, temp_slc)); + return FALSE32; +} + +static BOOL32 +ppnMiscTestConversionFunctions + (PPN_DeviceInfo * dev) +{ + UInt16 bank, block, page_offset; + UInt32 counter = 0; + + for (bank = 0; bank < dev->num_of_banks; bank++) + { + for (block = 0; block < dev->blocks_per_cau; block++) + { + for (page_offset = 0; page_offset < dev->pages_per_block_mlc; page_offset++) + { + counter++; + if (!(_verifyAnAddress(dev, bank, block, page_offset, TRUE32))) + { + VFL_ERR_PRINT((TEXT("PPNMISC:ERR] fail address conversion test: (l:%d)\n"), __LINE__)); + return FALSE32; + } + } + for (page_offset = 0; page_offset < dev->pages_per_block_slc; page_offset++) + { + if (!(_verifyAnAddress(dev, bank, block, page_offset, TRUE32))) + { + VFL_ERR_PRINT((TEXT("PPNMISC:ERR] fail address conversion test: (l:%d)\n"), __LINE__)); + return FALSE32; + } + } + } + } + + return counter; +} + +#endif // PPNMISC_VERIFY_CONVERSION + +void +ppnMiscReorderCommandStruct + (PPN_DeviceInfo * dev, + PPNCommandStruct **commands, + UInt16 num_of_command_structs, + PPNReorderStruct *reorder) +{ + UInt16 channel; + + // if there is only one ce per channel no need to reorder + if (dev->ces_per_channel == 1) + { + return; + } + +#if !AND_READONLY + if (PPN_COMMAND_PROGRAM == (*commands)->command) + { + return; + } +#endif // !AND_READONLY + + for (channel = 0; channel < num_of_command_structs; channel++) + { + PPNCommandStruct *command = commands[channel]; + UInt16 ce, page_idx; + UInt16 ce_page_count[PPN_MAX_CES_PER_BUS] = {0}; + + if (1 >= command->num_pages) + { + continue; + } + + for (page_idx = 0; page_idx < command->num_pages; page_idx++) + { + const PPNCommandEntry *entry = &command->entry[page_idx]; + const PPNMemoryIndex *memIndex = &command->mem_index[page_idx]; + reorder->entry[entry->ceIdx][ce_page_count[entry->ceIdx]] = *entry; + reorder->mem_index[entry->ceIdx][ce_page_count[entry->ceIdx]] = *memIndex; + ce_page_count[entry->ceIdx]++; + } + + page_idx = 0; + for (ce = 0; ce < dev->ces_per_channel; ce++) + { + const PPNCommandEntry *entry = reorder->entry[ce]; + const PPNMemoryIndex *memIndex = reorder->mem_index[ce]; + WMR_MEMCPY(&command->entry[page_idx], entry, ce_page_count[ce] * sizeof(*entry)); + WMR_MEMCPY(&command->mem_index[page_idx], memIndex, ce_page_count[ce] * sizeof(*memIndex)); + command->ceInfo[ce].offset = page_idx; + page_idx += ce_page_count[ce]; + } + } +} diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMiscTypes.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMiscTypes.h new file mode 100644 index 0000000..4358a79 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/PPNMiscTypes.h @@ -0,0 +1,158 @@ +#ifndef _PPN_MISC_TYPES_H_ +#define _PPN_MISC_TYPES_H_ + +#include "WMRConfig.h" +#include "PPN_FIL.h" +#include "FIL.h" + +#define PPN_SPECIAL_BLOCK_LIMIT(dev) ((dev)->blocks_per_cau - (((dev)->blocks_per_cau * 5) / 100)) + +/* PPNVFL internal structures */ + +typedef struct +{ + UInt32 num_channels; + UInt32 ces_per_channel; + UInt32 caus_per_ce; + UInt32 num_of_banks; + UInt32 blocks_per_cau; + UInt32 pages_per_block_slc; + UInt32 pages_per_block_mlc; + UInt32 bits_per_cau_addr; + UInt32 bits_per_page_addr; + UInt32 bits_per_block_addr; + UInt32 main_bytes_per_page; + UInt32 main_bytes_per_lba; + UInt32 pages_per_sublk; + UInt32 lbas_per_page; + UInt32 lba_meta_bytes_valid; + UInt32 lba_meta_bytes_buffer; + UInt32 max_pages_in_prep_per_ce; + BOOL32 f_match_oddeven_blocks; + UInt16 chip_enable_table[4][4]; // up to 4 channels and up to 4 chip enables per channel + LowFuncTbl *fil; +} PPN_DeviceInfo; + +typedef struct +{ + PPNCommandEntry entry[PPN_MAX_CES_PER_BUS][PPN_MAX_PAGES_PER_CE]; + PPNMemoryIndex mem_index[PPN_MAX_CES_PER_BUS][PPN_MAX_PAGES_PER_CE]; +} PPNReorderStruct; + +UInt16 ppnMiscGetCAUFromBank + (PPN_DeviceInfo * dev, + UInt16 bank); +UInt16 ppnMiscGetChannelFromBank + (PPN_DeviceInfo * dev, + UInt16 bank); +UInt16 ppnMiscGetCEIdxFromBank + (PPN_DeviceInfo * dev, + UInt16 bank); +UInt16 ppnMiscGetCEFromBank + (PPN_DeviceInfo * dev, + UInt16 bank); +UInt16 ppnMiscGetCEIdxFromChipEnable + (PPN_DeviceInfo * dev, + UInt16 channel, + UInt16 chip_enable); +UInt32 ppnMiscConvertToPPNPageAddress + (PPN_DeviceInfo * dev, + UInt16 cau, + UInt16 block, + UInt16 page, + BOOL32 slcAddress); +void ppnMiscConvertPhysicalAddressToBankBlockPage + (PPN_DeviceInfo * dev, + UInt16 channel, + UInt16 chip_enable_idx, + UInt32 page, + UInt16 *bank, + UInt16 *block, + UInt16 *page_offset, + BOOL32 *slc); +void ppnMiscConvertPhysicalAddressToCauBlockPage + (PPN_DeviceInfo * dev, + UInt32 page, + UInt16 *cau, + UInt16 *block, + UInt16 *page_offset); +PPNStatusType ppnMiscSingleOperation + (PPN_DeviceInfo * dev, + PPNCommandStruct * command, + PPNCommand command_type, + PPNOptions options, + UInt16 bank, + UInt16 block, + UInt16 page_offset, + BOOL32 slc, + void *data, + void *meta); +void ppnMiscFillDevStruct + (PPN_DeviceInfo * dev, + LowFuncTbl *fil); +BOOL32 ppnMiscIsBlockGood + (UInt8 *bbt, + UInt16 block); +BOOL32 +ppnMiscAddPhysicalAddressToCommandStructure + (PPN_DeviceInfo * dev, + PPNCommandStruct **commands, + UInt16 channel, + UInt16 chip_enable_idx, + UInt16 cau, + UInt16 block, + UInt16 page_offset, + BOOL32 slc, + UInt8 pba_offset, + UInt8 pba_count, + UInt8 mem_index, + UInt16 mem_offset); +void +ppnMiscInitCommandStructure + (PPN_DeviceInfo * dev, + PPNCommandStruct **commands, + UInt16 num_of_command_structs, + PPNCommand command, + PPNOptions options); +BOOL32 +ppnMiscAddMemoryToCommandStructure + (PPN_DeviceInfo *dev, + PPNCommandStruct **commands, + UInt16 num_of_command_structs, + void *data, + void *meta, + UInt8 num_of_lbas); + +#ifndef AND_READONLY +BOOL32 +ppnMiscTestSpecialBlock + (PPN_DeviceInfo * dev, + PPNCommandStruct * command, + UInt16 bank, + UInt16 block, + UInt8 spareType); +#endif // AND_READONLY + +void +ppnMiscReorderCommandStruct + (PPN_DeviceInfo * dev, + PPNCommandStruct **commands, + UInt16 num_of_command_structs, + PPNReorderStruct *reorder); + +PPNStatusType +ppnMiscSingleLbaRead + (PPN_DeviceInfo * dev, + PPNCommandStruct * command, + PPNCommand command_type, + PPNOptions options, + UInt16 ce, + UInt16 cau, + UInt16 block, + UInt16 page_offset, + UInt8 lba_offset, + BOOL32 slc, + void *data, + void *meta); + +#endif /* _PPN_MISC_TYPES_H_ */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.c new file mode 100644 index 0000000..8f8d36c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.c @@ -0,0 +1,399 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL Buffer Management */ +/* FILE : VFLBuffer.c */ +/* PURPOSE : This file contains routines for managing buffers which */ +/* whimory uses. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 13-JUL-2005 [Jaesung Jung] : separate from vfl.c & reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : fix from code inspection */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Header file inclusions */ +/*****************************************************************************/ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" + +/*****************************************************************************/ +/* Debug Print #defines */ +/*****************************************************************************/ +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) +#define BUF_ERR_PRINT(x) { WMR_RTL_PRINT(x); WMR_PANIC(); } +#else +#define BUF_ERR_PRINT(x) WMR_RTL_PRINT(x) +#endif +#define BUF_RTL_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (BUF_LOG_MSG_ON) +#define BUF_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else +#define BUF_LOG_PRINT(x) +#endif + +#if defined (BUF_INF_MSG_ON) +#define BUF_INF_PRINT(x) WMR_DBG_PRINT(x) +#else +#define BUF_INF_PRINT(x) +#endif + +/*****************************************************************************/ +/* Static variables definitions */ +/*****************************************************************************/ +BUFCxt *pstBufferCxt = NULL; + +typedef struct +{ + UInt16 wBytesPerPage; /* bytes per page (main) */ + UInt16 wBytesPerPageMeta; +} VFLBufferDeviceInfo; +static VFLBufferDeviceInfo stVFLBufferDeviceInfo; + +#define BYTES_PER_PAGE (stVFLBufferDeviceInfo.wBytesPerPage) +#define BYTES_PER_PAGE_META (stVFLBufferDeviceInfo.wBytesPerPageMeta) + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Init */ +/* DESCRIPTION */ +/* This function initializes the buffer manager & the buffer pool. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* BUF_SUCCESS */ +/* BUF_Init is completed. */ +/* BUF_CRITICAL_ERROR */ +/* BUF_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +Int32 +BUF_Init(UInt16 wDataBytesPerPage, UInt16 wMetaBytesPerPage, UInt16 wNumberOfBuffers) +{ + UInt32 nBufIdx; + Buffer *pBufIdx; + + if (pstBufferCxt != NULL) + { + return BUF_SUCCESS; + } + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Init(void)\n"))); + + stVFLBufferDeviceInfo.wBytesPerPage = wDataBytesPerPage; + stVFLBufferDeviceInfo.wBytesPerPageMeta = wMetaBytesPerPage; + + /* Initialize buffer context */ + pstBufferCxt = (BUFCxt *)WMR_MALLOC(sizeof(BUFCxt)); + pstBufferCxt->dwNumOfBuffers = wNumberOfBuffers; + if (pstBufferCxt == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Init(void) BUFCxt Init Failure\n"))); + BUF_Close(); + return BUF_CRITICAL_ERROR; + } + + /* Initialize buffer list */ + pstBufferCxt->pBufferList = (Buffer *)WMR_MALLOC(sizeof(Buffer) * pstBufferCxt->dwNumOfBuffers); + + if (pstBufferCxt->pBufferList == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Init(void) BUFCxt->pBufferList Init Failure\n"))); + BUF_Close(); + return BUF_CRITICAL_ERROR; + } + + pBufIdx = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++) + { +#ifdef WMR_USE_FAKE_POINTERS + /* + * In order to make it possible to DMA to the contents of the buffer pool, + * OAM_Init has already allocated an IOBufferMemoryDescriptor of the appropriate + * size. Thus, we just have to index into it... + */ + extern UInt8 *_OAM_PageBufferPoolBase; + extern UInt8 *_OAM_SpareBufferPoolBase; + pBufIdx->pData = _OAM_PageBufferPoolBase + (nBufIdx * BYTES_PER_PAGE); + pBufIdx->pSpare = _OAM_SpareBufferPoolBase + (nBufIdx * BYTES_PER_PAGE_META); +#else /* !WMR_USE_FAKE_POINTERS */ + pBufIdx->pData = (UInt8 *)WMR_MALLOC(BYTES_PER_PAGE + BYTES_PER_PAGE_META); + pBufIdx->pSpare = pBufIdx->pData + BYTES_PER_PAGE; +#endif + + if (pBufIdx->pData == NULL || pBufIdx->pSpare == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Init(void) pBufIdx->pData, pBufIdx->pSpare Init Failure\n"))); + BUF_Close(); + return BUF_CRITICAL_ERROR; + } + + pBufIdx->pDataBak = pBufIdx->pData; +#ifdef WMR_USE_FAKE_POINTERS /* need to save the spare pointer as it is not contiguous */ + pBufIdx->pSpareBak = pBufIdx->pSpare; +#endif + pBufIdx->eStatus = BUF_FREE; + + pBufIdx++; + } + + pstBufferCxt->nFreeBuffers = pstBufferCxt->dwNumOfBuffers; + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Init(void) nRe=0x%x\n"), BUF_SUCCESS)); + return BUF_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Get */ +/* DESCRIPTION */ +/* This function returns a new free buffer. */ +/* if there is not a free buffer, this function calls the sync function */ +/* and generates a new free buffer. */ +/* PARAMETERS */ +/* eType [IN] */ +/* buffer type */ +/* RETURN VALUES */ +/* Buffer */ +/* BUF_Get is completed. */ +/* NULL */ +/* BUF_Get is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +Buffer * +BUF_Get(BUFType eType) +{ + UInt32 nBufIdx; + Buffer *pBufRet; + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Get(eType = %d)\n"), eType)); + + /* Check buffer context was initialized */ + if (pstBufferCxt == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) Buffer manager is not initialized\n"), eType)); + return NULL; + } + + /* NirW - from the checked in M1 code - Check buffer context was not written over */ + if (pstBufferCxt->pBufferList == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) Buffer pointer was overwritten!\n"), eType)); + return NULL; + } + + if (pstBufferCxt->nFreeBuffers == 0) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) No free buffer\n"), eType)); + return NULL; + } + + /* Find a free buffer from the buffer pool. */ + pBufRet = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++, pBufRet++) + { + if (pBufRet->eStatus == BUF_FREE) + { + break; + } + } + + if (nBufIdx >= pstBufferCxt->dwNumOfBuffers) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) Can't find a free buffer\n"), eType)); + return NULL; + } + + /* Check the buffer type */ + if (eType == BUF_SPARE_ONLY) + { + pBufRet->pData = NULL; + } + else if (eType == BUF_MAIN_ONLY) + { + pBufRet->pSpare = NULL; + } + + /* Initialize the spare buffer */ + if (eType != BUF_MAIN_ONLY) + { + WMR_MEMSET(pBufRet->pSpare, 0xFF, BYTES_PER_PAGE_META); + } + + /* Change the buffer status & bitmap */ + pBufRet->eStatus = BUF_ALLOCATED; +/* pBufRet->nBitmap = 0; */ + + /* Decrease the number of free buffers */ + pstBufferCxt->nFreeBuffers--; + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Get(eType = %d)\n"), eType)); + + return pBufRet; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Release */ +/* DESCRIPTION */ +/* This function releases the buffer to the buffer pool. */ +/* PARAMETERS */ +/* pBuf [IN] */ +/* buffer pointer */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +void +BUF_Release(Buffer *pBuf) +{ + UInt16 wIdx; + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Release(pBuf = %x)\n"), pBuf)); + + if (pBuf == NULL) + { + return; + } + + //WMR_ASSERT((pBuf - pstBufferCxt->pBufferList) >= 0 && +// (pBuf - pstBufferCxt->pBufferList) < pstBufferCxt->dwNumOfBuffers); + for (wIdx = 0; wIdx < pstBufferCxt->dwNumOfBuffers; wIdx++) + { + if (pBuf == &pstBufferCxt->pBufferList[wIdx]) + { + break; + } + } + WMR_ASSERT(wIdx < pstBufferCxt->dwNumOfBuffers); + /* NirW */ + if (pBuf->eStatus == BUF_FREE) + { + return; + } + + WMR_ASSERT(pBuf->eStatus == BUF_ALLOCATED); + + /* Reinitialize the buffer */ + pBuf->pData = pBuf->pDataBak; +#ifdef WMR_USE_FAKE_POINTERS /* need to restore non-adjacent spare pointer */ + pBuf->pSpare = pBuf->pSpareBak; +#else + pBuf->pSpare = pBuf->pDataBak + BYTES_PER_PAGE; +#endif + + pBuf->eStatus = BUF_FREE; + + pstBufferCxt->nFreeBuffers++; + + WMR_ASSERT(pstBufferCxt->nFreeBuffers <= pstBufferCxt->dwNumOfBuffers); + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Release(pBuf = %x)\n"), pBuf)); + + return; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Close */ +/* DESCRIPTION */ +/* This function releases buffer manager context. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +void +BUF_Close(void) +{ + UInt32 nBufIdx; + Buffer *pBufIdx; + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Close(void)\n"))); + + if (pstBufferCxt != NULL) + { + if (pstBufferCxt->pBufferList != NULL) + { + pBufIdx = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++) + { +#ifndef WMR_USE_FAKE_POINTERS + WMR_FREE(pBufIdx->pDataBak, (BYTES_PER_PAGE + BYTES_PER_PAGE_META)); +#endif + pBufIdx->pData = NULL; + pBufIdx->pSpare = NULL; + + pBufIdx++; + } + + WMR_FREE(pstBufferCxt->pBufferList, (sizeof(Buffer) * pstBufferCxt->dwNumOfBuffers)); + + pstBufferCxt->pBufferList = NULL; + } + + WMR_FREE(pstBufferCxt, sizeof(BUFCxt)); + + pstBufferCxt = NULL; + } + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Close(void)\n"))); + + return; +} + +void +BUF_ReleaseAllBuffers(void) +{ + UInt32 nBufIdx; + Buffer *pBufIdx; + + pBufIdx = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++) + { + BUF_Release(pBufIdx); + pBufIdx++; + } +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.h new file mode 100644 index 0000000..b13e6e7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/Misc/VFLBuffer.h @@ -0,0 +1,104 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL Buffer Management */ +/* FILE : VFLBuffer.h */ +/* PURPOSE : This file contains routines for managing buffers which */ +/* whimory uses. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 13-JUL-2005 [Jaesung Jung] : separate from vfl.c & reorganize code */ +/* */ +/*****************************************************************************/ + +#ifndef _VFL_BUFFER_H_ +#define _VFL_BUFFER_H_ + +/*****************************************************************************/ +/* Return value of BUF_XXX() */ +/*****************************************************************************/ +#define BUF_SUCCESS ANDErrorCodeOk +#define BUF_CRITICAL_ERROR ANDErrorCodeAllocFailErr + +/*****************************************************************************/ +/* Buffer state enum definition */ +/*****************************************************************************/ +typedef enum +{ + BUF_FREE = 0x10000000, /* the buffer is free */ + BUF_ALLOCATED = 0x10000001, /* the buffer is allocated to some layer */ +} BUFStat; + +/*****************************************************************************/ +/* Buffer type enum & macro definition */ +/*****************************************************************************/ +typedef enum +{ + BUF_MAIN_AND_SPARE = 0x10000000, /* to get a buffer which has main & spare*/ + BUF_MAIN_ONLY = 0x10000001, /* to get a buffer which has main only */ + BUF_SPARE_ONLY = 0x10000002 /* to get a buffer which has spare only */ +} BUFType; + +#define BITMAP_FULL_PAGE ((1 << SECTORS_PER_PAGE) - 1) + +/*****************************************************************************/ +/* Buffer structure definition */ +/*****************************************************************************/ +typedef struct Buf +{ + UInt8 *pData; /* buffer area for main area */ + UInt8 *pSpare; /* buffer area for spare area */ +// UInt32 nBitmap; /* valid sector bitmap for pData */ + BUFStat eStatus; /* the status of buffer */ + UInt8 *pDataBak; /* the original pointer of data buffer */ +#ifdef WMR_USE_FAKE_POINTERS /* data and spare buffers are not adjacent */ + UInt8 *pSpareBak; /* the original pointer of spare buffer */ +#endif +} Buffer; + +typedef struct +{ + Buffer *pBufferList; /* the list of all the buffers */ + UInt32 nFreeBuffers; /* the count of free buffers */ + UInt32 dwNumOfBuffers; +} BUFCxt; + +/*****************************************************************************/ +/* exported function prototype of VFL buffer manager */ +/*****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +Int32 BUF_Init(UInt16 wDataBytesPerPage, UInt16 wMetaBytesPerPage, UInt16 wNumberOfBuffers); +Buffer *BUF_Get(BUFType eType); +void BUF_Release(Buffer *pBuf); +void BUF_Close(void); +void BUF_ReleaseAllBuffers(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _VFL_BUFFER_H_ */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V.h new file mode 100644 index 0000000..52759ee --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_H__ +#define __L2V_H__ + +#include "L2V_Types.h" + + +extern L2V_t L2V; +extern UInt32 L2V_nodepool_mem; +extern UInt8 *L2V_root_depth; +extern tempNodePool_t tempNodes; + +#endif // __L2V_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Assert.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Assert.h new file mode 100644 index 0000000..334b194 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Assert.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_CASSERT_H__ +#define __L2V_CASSERT_H__ + +#define l2v_assert(e) WMR_ASSERT(e) + +#define l2v_assert_le(x, y) l2v_assert((x) <= (y)) +#define l2v_assert_lt(x, y) l2v_assert((x) < (y)) +#define l2v_assert_ge(x, y) l2v_assert((x) >= (y)) +#define l2v_assert_gt(x, y) l2v_assert((x) > (y)) +#define l2v_assert_eq(x, y) l2v_assert((x) == (y)) +#define l2v_assert_ne(x, y) l2v_assert((x) != (y)) + +#endif // __L2V_CASSERT_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Config.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Config.h new file mode 100644 index 0000000..0fefc79 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Config.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_CONFIG_H__ +#define __L2V_CONFIG_H__ + +// Defines the node size +#define L2V_NODE_SIZE 64 + +// Defines the memory set aside for the node pool +#define L2V_NODEPOOL_MEM (L2V_nodepool_mem + 0) +// Defines the size of a logical tree +#define L2V_TREE_BITS 15 + +// Repack periodicity +#define L2V_REPACK_PERIOD 200 + + +#endif // __L2V_CONFIG_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Defines.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Defines.h new file mode 100644 index 0000000..55dd0bc --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Defines.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_DEFINES_H__ +#define __L2V_DEFINES_H__ + +// Shortcuts for the config +#define b_1 0 +#define b_2 1 +#define b_4 2 +#define b_8 3 +#define b_16 4 +#define b_32 5 +#define b_64 6 +#define b_128 7 +#define b_256 8 +#define b_512 9 +#define KiB_bits 10 +#define MiB_bits 20 +#define GiB_bits 30 +#define TiB_bits 40 +#define KiB (1 << KiB_bits) +#define MiB (1 << MiB_bits) +#define GiB (1 << GiB_bits) +#define TiB (1 << TiB_bits) + +#include "L2V_Config.h" + + +// Node size +#define L2V_CONTIG_ELEM_SMALL 4 +#define L2V_CONTIG_ELEM_LARGE 6 +#define L2V_MIN_CONTIG_PER_NODE (L2V_NODE_SIZE / L2V_CONTIG_ELEM_LARGE) +#define L2V_MAX_CONTIG_PER_NODE (L2V_NODE_SIZE / L2V_CONTIG_ELEM_SMALL) + + +// Memory usage +#define L2V_NODEPOOL_COUNT (L2V_NODEPOOL_MEM / L2V_NODE_SIZE) + + +// Parameters +#define L2V_SUCKUP_CHILDREN_MAX 3 +#define L2V_TRACK_VALID 1 + + +// Tree size +#define L2V_TREE_SIZE (1 << L2V_TREE_BITS) +#define L2V_TREE_MASK (L2V_TREE_SIZE - 1) +#define L2V_MAX_TREE_DEPTH 32 +#define L2V_MAX_TREE_DEPTH_UPD 36 +#define L2V_TREE_DEPTH_REPACK 26 + + +// Magic numbers +#define L2V_CONTIG_FREE_SIG 0xFFFFFFFF +// VBA macros, to make quick read-only accessors +#define L2V_VBA_SPECIAL (L2V.vba.special+0) +#define L2V_VBA_DEALLOC (L2V.vba.dealloc+0) + + +// Transforms +#define L2V_IDX_TO_NODE(idx) (&L2V.Pool.Node[idx]) +#define L2V_NODE_TO_IDX(ptr) ((lNode_t*)(ptr) - &L2V.Pool.Node[0]) + +// Memory state +#define L2V_LowishMem (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH*16)) +#define L2V_LowMem (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH*8)) +#define L2V_CriticalMem (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH+1)) +#define L2V_TimeToRepack (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH << 1)) + +// Frag search +#define L2V_FIND_FRAGS_MAX 32 +#define L2V_LIST_FRAGS_MAX 64 + + +#endif // __L2V_DEFINES_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump.m b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump.m new file mode 100644 index 0000000..7cac194 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump.m @@ -0,0 +1,281 @@ +// +// L2V_Dump.m +// L2V_Dump +// +// Created by John Vink on 7/29/11. +// Copyright (c) 2011 Apple, Inc. All rights reserved. +// + + +#import "L2V_Print.h" +#import "L2V_Types.h" + +#import + +#define L2V_SIZE_32_BIT (0x3c) +#define L2V_SIZE_64_BIT (0x50) +#define L2V_OFFSET_POOL_64_BIT (0x38) +#define SIZE_OF_LONG_64_BIT 8 + +L2V_t L2V; + +// ------------------------------------------------------------- +// * usage +// ------------------------------------------------------------- +static void usage() +{ + printf("L2V_Dump: \n"); +} + + +// ------------------------------------------------------------- +// * main +// ------------------------------------------------------------- +int main (int argc, const char * argv[]) +{ + NSAutoreleasePool* pool = [NSAutoreleasePool new]; + + // try to make sure the L2V struct hasn't changed (much) since I wrote the code to convert it from 32 bit to 64 bit + if (sizeof(long) == SIZE_OF_LONG_64_BIT) + { + L2V_t* dummyL2V = (L2V_t*) 0; + if (sizeof(L2V_t) != L2V_SIZE_64_BIT || (long)&dummyL2V->Pool != L2V_OFFSET_POOL_64_BIT) + { + printf("L2V struct has changed.\n"); + return 1; + } + } + +#if 0 + fprintf(stderr, "architecture: %d bit\n", sizeof(long) * 8); + + L2V_t* dummyL2V = (L2V_t*) 0; + printf("numRoots %2x %d\n", &dummyL2V->numRoots, sizeof(dummyL2V->numRoots)); + printf("Root %2x %d\n", &dummyL2V->Root, sizeof(dummyL2V->Root)); + printf("RepackCounter %2x %d\n", &dummyL2V->RepackCounter, sizeof(dummyL2V->RepackCounter)); + printf("treeVersion %2x %d\n", &dummyL2V->treeVersion, sizeof(dummyL2V->treeVersion)); + printf("max_sb %2x %d\n", &dummyL2V->max_sb, sizeof(dummyL2V->max_sb)); + printf("vbas_per_sb %2x %d\n", &dummyL2V->vbas_per_sb, sizeof(dummyL2V->vbas_per_sb)); + printf("bits %2x %d\n", &dummyL2V->bits, sizeof(dummyL2V->bits)); + printf("bits.node_span %2x %d\n", &dummyL2V->bits.node_span, sizeof(dummyL2V->bits.node_span)); + printf("bits.nodeIdx %2x %d\n", &dummyL2V->bits.nodeIdx, sizeof(dummyL2V->bits.nodeIdx)); + printf("bits.nand_span %2x %d\n", &dummyL2V->bits.nand_span, sizeof(dummyL2V->bits.nand_span)); + printf("bits.vba %2x %d\n", &dummyL2V->bits.vba, sizeof(dummyL2V->bits.vba)); + printf("vba %2x %d\n", &dummyL2V->vba, sizeof(dummyL2V->vba)); + printf("vba.special %2x %d\n", &dummyL2V->vba.special, sizeof(dummyL2V->vba.special)); + printf("vba.dealloc %2x %d\n", &dummyL2V->vba.dealloc, sizeof(dummyL2V->vba.dealloc)); + printf("Pool %2x %d\n", &dummyL2V->Pool, sizeof(dummyL2V->Pool)); + printf("Total Size %2x\n", sizeof(L2V_t)); +#endif + + if (argc != 2) + { + usage(); + return 1; + } + + const char* filename = argv[1]; + int fd = open(filename, O_RDONLY); + if (-1 == fd) + { + fprintf(stderr, "Cannot open %s\n", filename); + return 1; + } + + // see how big the XML is + UInt32 xmlSize = 0; + ssize_t result = read(fd, &xmlSize, sizeof(xmlSize)); + if (sizeof(xmlSize) != result) + { + fprintf(stderr, "Unable to read size of XML\n"); + return 1; + } + + // read the XML + char* xmlBuffer = (char*) malloc(xmlSize); + if (NULL == xmlBuffer) + { + fprintf(stderr, "Cannot allocate XML buffer of %d\n", xmlSize); + return 1; + } + + result = read(fd, xmlBuffer, xmlSize); + if ((ssize_t)xmlSize != result) + { + fprintf(stderr, "Unable to read XML\n"); + return 1; + } + + NSData* xmlData = [NSData dataWithBytes:xmlBuffer length:xmlSize]; + if (NULL == xmlData) + { + fprintf(stderr, "Cannot create NSData from XML buffer\n"); + return 1; + } + + NSPropertyListReadOptions format = NSPropertyListXMLFormat_v1_0; + NSError* error = NULL; + NSDictionary* dict = [NSPropertyListSerialization propertyListWithData:xmlData options:0 format:&format error:&error]; + if (NULL == dict) + { + fprintf(stderr, "Cannot convert XML data to NSDictionary\n"); + return 1; + } + + NSDictionary* infoDict = [dict objectForKey:@"Info"]; + if (NULL == infoDict || ![infoDict isKindOfClass:[NSDictionary class]]) + { + fprintf(stderr, "Cannot get Info dict\n"); + return 1; + } + + NSNumber* ftlTypeNumber = [infoDict objectForKey:@"FTL Type"]; + if (NULL == ftlTypeNumber || ![ftlTypeNumber isKindOfClass:[NSNumber class]]) + { + fprintf(stderr, "Cannot get FTL Type from Info dict\n"); + return 1; + } + + if ([ftlTypeNumber intValue] != FTL_TYPE_SFTL) + { + fprintf(stderr, "FTL type is not AppleSwiss\n"); + return 1; + } + + NSArray* blobs = [dict objectForKey:@"Blobs"]; + if (NULL == blobs || ![blobs isKindOfClass:[NSArray class]]) + { + fprintf(stderr, "Cannot get Blobs array\n"); + return 1; + } + + NSDictionary* structDict; + L2V_t l2vStruct; + for (structDict in blobs) + { + if (![structDict isKindOfClass:[NSDictionary class]]) + { + fprintf(stderr, "Blobs element is not a dictionary\n"); + return 1; + } + + NSString* structType = [structDict objectForKey:@"Label"]; + NSNumber* structSize = [structDict objectForKey:@"Size"]; + + if (NULL == structType || ![structType isKindOfClass:[NSString class]]) + { + fprintf(stderr, "Cannot get Blob label\n"); + return 1; + } + + if (NULL == structSize || ![structSize isKindOfClass:[NSNumber class]]) + { + fprintf(stderr, "Cannot get Blob size\n"); + return 1; + } + + if ([structType isEqualToString:@"AND_STRUCT_FTL_L2V_STRUCT"]) + { + BOOL read32Bit = NO; + if ([structSize intValue] != sizeof(L2V_t)) + { + if ([structSize intValue] == L2V_SIZE_32_BIT) + { + read32Bit = YES; + } + else + { + fprintf(stderr, "Expected size of %d for L2V, but got %d\n", sizeof(L2V_t), [structSize intValue]); + return 1; + } + } + if (read32Bit) + { + uint8_t* l2v32bitBuffer = malloc(L2V_SIZE_32_BIT); + result = read(fd, l2v32bitBuffer, L2V_SIZE_32_BIT); + if (result != L2V_SIZE_32_BIT) + { + fprintf(stderr, "Could not read L2V struct\n"); + free(l2v32bitBuffer); + return 1; + } + l2vStruct.numRoots = *(UInt32*)l2v32bitBuffer; + l2vStruct.RepackCounter = *(UInt32*)&l2v32bitBuffer[8]; + l2vStruct.treeVersion = *(UInt32*)&l2v32bitBuffer[0xc]; + l2vStruct.max_sb = *(UInt32*)&l2v32bitBuffer[0x10]; + l2vStruct.vbas_per_sb = *(UInt32*)&l2v32bitBuffer[0x14]; + l2vStruct.bits.node_span = *(UInt32*)&l2v32bitBuffer[0x18]; + l2vStruct.bits.nodeIdx = *(UInt32*)&l2v32bitBuffer[0x1c]; + l2vStruct.bits.nand_span = *(UInt32*)&l2v32bitBuffer[0x20]; + l2vStruct.bits.vba = *(UInt32*)&l2v32bitBuffer[0x24]; + l2vStruct.vba.special = *(UInt32*)&l2v32bitBuffer[0x28]; + l2vStruct.vba.dealloc = *(UInt32*)&l2v32bitBuffer[0x2c]; + free(l2v32bitBuffer); + } + else + { + result = read(fd, &l2vStruct, sizeof(L2V_t)); + if (result != sizeof(L2V_t)) + { + fprintf(stderr, "Could not read L2V struct\n"); + return 1; + } + } + } + else if ([structType isEqualToString:@"AND_STRUCT_FTL_L2V_ROOTS"]) + { + UInt32 rootSize = [structSize intValue]; + l2vStruct.Root = malloc(rootSize); + if (NULL == l2vStruct.Root) + { + fprintf(stderr, "Could not allocate %d bytes for roots\n", rootSize); + return 1; + } + result = read(fd, l2vStruct.Root, rootSize); + if (result != (ssize_t)rootSize) + { + fprintf(stderr, "Could not read L2V roots\n"); + return 1; + } + } + else if ([structType isEqualToString:@"AND_STRUCT_FTL_L2V_POOL"]) + { + UInt32 poolSize = [structSize intValue]; + l2vStruct.Pool.Node = malloc(poolSize); + if (NULL == l2vStruct.Pool.Node) + { + fprintf(stderr, "Could not allocate %d bytes for pool\n", poolSize); + return 1; + } + result = read(fd, l2vStruct.Pool.Node, poolSize); + if (result != (ssize_t)poolSize) + { + fprintf(stderr, "Could not read L2V pool\n"); + return 1; + } + } + else + { + fprintf(stderr, "Unknown label %s\n", [structType cStringUsingEncoding:NSASCIIStringEncoding]); + return 1; + } + } + + l2vStruct.Pool.FreePtr = NULL; + l2vStruct.Pool.FreeCount = 0; + + L2V = l2vStruct; + + printf("Number of roots:%d\n", l2vStruct.numRoots); + UInt32 rootNumber; + for (rootNumber = 0; rootNumber < l2vStruct.numRoots; rootNumber++) + { + printf("---- Root %d:\n", rootNumber); + L2V_PrintUsage(rootNumber); + } + + [pool release]; + + return 0; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump_Prefix.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump_Prefix.h new file mode 100644 index 0000000..0b95acc --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Dump_Prefix.h @@ -0,0 +1,19 @@ +// +// L2V_Dump_Prefix.h +// IOFlashStorage +// +// Created by John Vink on 7/29/11. +// Copyright (c) 2011 Apple, Inc. All rights reserved. +// + +#ifdef __OBJC__ + #import +#endif + +// include these files so that L2V_Print.c will build +#include +#include + +#define _WMR_ASSERT(e, file, line) { printf("%s:%u: failed assertion '%s'\nWaiting for debugger...\n", file, line, e); abort(); } +#define WMR_ASSERT(e) if (!(e)) _WMR_ASSERT(#e, __FILE__, __LINE__) +#define WMR_PANIC(fmt, ...) { printf(fmt, ## __VA_ARGS__); abort(); } diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Extern.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Extern.h new file mode 100644 index 0000000..aa60172 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Extern.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_EXTERN_H__ +#define __L2V_EXTERN_H__ + + +#include "L2V_Types.h" + +// Define the context structure for faster macro access +extern L2V_t L2V; +extern UInt32 L2V_nodepool_mem; +extern UInt8 *L2V_root_depth; +extern tempNodePool_t tempNodes; + +extern BOOL32 L2V_Init(UInt32 numLbas, UInt32 max_sb, UInt32 vbas_per_sb); +extern void L2V_Nuke(void); +extern void L2V_Free(void); +extern void L2V_Search_Init(L2V_SearchCtx_t *c); +extern void L2V_Search(L2V_SearchCtx_t *c); +extern void L2V_Update(UInt32 lba, UInt32 size, UInt32 vba); +extern void L2V_Repack(UInt32 tree); +extern UInt32 L2V_ForceRepack(void); +extern void L2V_FindFrag(UInt32 *d_lba, UInt32 *d_span); + +#define L2V_IdleRepackThr (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH*32)) +#define L2V_LowishMem (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH*16)) +#define L2V_LowMem (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH*8)) +#define L2V_CriticalMem (L2V.Pool.FreeCount <= (L2V_MAX_TREE_DEPTH+1)) + + +#endif // __L2V_EXTERN_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_FindFrag.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_FindFrag.c new file mode 100644 index 0000000..b04d626 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_FindFrag.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Funcs.h" + +typedef struct { + UInt32 lba; + UInt32 span; +} fragItem_t; + +static struct { + UInt32 curLba; + fragItem_t item[L2V_FIND_FRAGS_MAX]; + UInt32 nextIdx; + UInt32 idx; + UInt32 cnt; + UInt32 sum; + UInt32 minSum; + UInt32 minSumLba; + + fragItem_t listItem[L2V_LIST_FRAGS_MAX+1]; + UInt32 listSize; + + Int32 curTree; +} frag; + +static void TreeFrag(lNode_t *node); + +void L2V_FindFrag(UInt32 *d_lba, UInt32 *d_span) +{ + lNode_t *root; + UInt32 tree; + UInt32 lba, span; + UInt32 curIdx; + RootContig_t rc; + + if (frag.listSize < (L2V_LIST_FRAGS_MAX>>2)) { + // Initialize structures + frag.idx = 0; + frag.cnt = 0; + frag.sum = 0; + frag.minSum = 0xffffffff; + frag.minSumLba = 0xffffffff; + + // Iterate over roots + for (tree = 0; tree < L2V.numRoots; tree++, frag.curTree--) { + if (frag.curTree < 0) { + frag.curTree = L2V.numRoots-1; + } + frag.curLba = frag.curTree << L2V_TREE_BITS; + + rc = L2V.Root[frag.curTree].rootContig; + + // No fragments if there's no tree! + if (ROOT_CONTIG_DEALLOC == rc) { + frag.curLba += L2V_TREE_SIZE; + continue; + } + + // Recurse and destroy + root = L2V_IDX_TO_NODE(ROOT_CONTIG_GET_NODEIDX(rc)); + TreeFrag(root); + + if (frag.listSize && (L2V_FIND_FRAGS_MAX == frag.listItem[0].span)) { + // Early out: it can't get any smaller! + break; + } + } + } + + // Extract from queue + lba = frag.listItem[0].lba; + span = frag.listItem[0].span; + for (curIdx = 1; curIdx < frag.listSize; curIdx++) { + frag.listItem[curIdx-1] = frag.listItem[curIdx]; + } + frag.listSize--; + + // Limit + span = WMR_MIN(span, L2V.vbas_per_sb<<1); + + // Report it + *d_lba = lba; + *d_span = span; +} + +static void TreeFrag(lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + ContigUnpacked_t cu; + lPtr_t thisPtr; + UInt32 curIdx; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + TreeFrag(L2V_IDX_TO_NODE(cu.u.nodeIdx)); + } else { + // Prepare next index + frag.nextIdx = frag.idx + 1; + if (frag.nextIdx >= L2V_FIND_FRAGS_MAX) + frag.nextIdx = 0; + + // Subtract prior span if the search is full + if (L2V_FIND_FRAGS_MAX == frag.cnt) { + frag.sum -= frag.item[frag.idx].span; + } + + // Add to rolling average + frag.item[frag.idx].span = cu.span; + frag.item[frag.idx].lba = frag.curLba; + frag.sum += cu.span; + frag.cnt = WMR_MIN(frag.cnt+1, L2V_FIND_FRAGS_MAX); + + // Minify + if (L2V_FIND_FRAGS_MAX == frag.cnt) { + if (frag.listSize < L2V_LIST_FRAGS_MAX) { + frag.listItem[frag.listSize].lba = (UInt32)-1; + frag.listItem[frag.listSize].span = (UInt32)-1; + frag.listSize++; + } + + // Insert, slipping from end + curIdx = frag.listSize; + while ((curIdx > 0) && (frag.sum < frag.listItem[curIdx-1].span)) { + curIdx--; + frag.listItem[curIdx+1].lba = frag.listItem[curIdx].lba; + frag.listItem[curIdx+1].span = frag.listItem[curIdx].span; + } + + if (curIdx < frag.listSize) { + frag.listItem[curIdx].lba = frag.item[frag.nextIdx].lba; + frag.listItem[curIdx].span = frag.sum; + // Empty pending, to guarantee no overlaps + frag.idx = 0; + frag.sum = 0; + frag.cnt = 0; + } + } + + // Next + frag.curLba += cu.span; + frag.idx = frag.nextIdx; + } + } _L2V_NODE_ITERATE_END(nOfs); +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Free.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Free.c new file mode 100644 index 0000000..1aed2fd --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Free.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V_Extern.h" + +void L2V_Free(void) +{ + if (0 == L2V.numRoots) + return; + + // Free arrays: + + if (NULL != L2V.Root) { + WMR_FREE(L2V.Root, L2V.numRoots * sizeof(Root_t)); + L2V.Root = NULL; + } + + if (NULL != L2V.Pool.Node) { + WMR_FREE(L2V.Pool.Node, L2V_NODEPOOL_MEM); + L2V.Pool.Node = NULL; + } + + if(L2V_root_depth != NULL) + { + WMR_FREE(L2V_root_depth, L2V.numRoots); + L2V_root_depth = NULL; + } + + if(tempNodes.isEntryAvailable) + { + WMR_FREE(tempNodes.isEntryAvailable, tempNodes.poolSize); + } + if(tempNodes.tempNodeEntries) + { + WMR_FREE(tempNodes.tempNodeEntries, sizeof(lNodeBig_t) * tempNodes.poolSize); + } + tempNodes.poolSize = 0; + +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.c new file mode 100644 index 0000000..e2a705d --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V_Funcs.h" + +// Empty + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.h new file mode 100644 index 0000000..ffd7556 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Funcs.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_FUNCS_H__ +#define __L2V_FUNCS_H__ + + +#include "L2V_Types.h" + + +extern BOOL32 L2V_Init(UInt32 numLbas, UInt32 max_sb, UInt32 vbas_per_sb); +extern void L2V_Nuke(void); +extern void L2V_Search_Init(L2V_SearchCtx_t *c); +extern void L2V_Search(L2V_SearchCtx_t *c); +extern void L2V_Update(UInt32 lba, UInt32 size, UInt32 vba); +extern void L2V_Repack(UInt32 tree); + + +// Macros + +#define _L2V_NODE_ITERATE_RESUME(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) \ + while ((_nodeByteOfs) <= ((_nodeSize)-sizeof(lPtr_t))) { \ + (_destPtr) = *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]); \ + if (L2V_CONTIG_FREE_SIG == (_destPtr)) { \ + break; \ + } \ + if (LPTR_IS_NODEPTR(_destPtr)) { \ + LPTR_UNPACK_NODE(_destPtr, _cu); \ + } else { \ + LPTR_UNPACK_NAND(_destPtr, _cu); \ + } \ + if ((_cu).hasSpanOF) { \ + (_nodeSize) -= sizeof(UInt16); \ + (_cu).span += *(UInt16*)&(_node)->bytes[_nodeSize] << (LPTR_IS_NODEPTR(_destPtr) ? L2V.bits.node_span : L2V.bits.nand_span); \ + l2v_assert_le(_nodeByteOfs, ((_nodeSize)-sizeof(lPtr_t))); \ + } \ + (_cu).span += 1; \ + l2v_assert_ne((_cu).span, 0); + +#define _L2V_NODE_ITERATE(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) \ + (_nodeByteOfs) = 0; \ + (_nodeSize) = L2V_NODE_SIZE; \ + _L2V_NODE_ITERATE_RESUME(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) + + +#define _L2V_NODE_ITERATE_NEXT(_nodeByteOfs) \ + (_nodeByteOfs) += sizeof(lPtr_t); + +#define _L2V_NODE_ITERATE_END_NOP } + +#define _L2V_NODE_ITERATE_END(_nodeByteOfs) \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + } + +#define _L2V_NODE_PUSH_CONTIG_NODE(_node, _nodeByteOfs, _nodeSize, _cu) \ + { \ + l2v_assert_ne((_cu).span, 0); \ + (_cu).hasSpanOF = 1; \ + *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]) = LPTR_PACK_NODE(_cu); \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + (_nodeSize) -= sizeof(UInt16); \ + *(UInt16*)&(_node)->bytes[_nodeSize] = ((_cu).span-1) >> L2V.bits.node_span; \ + } +#define _L2V_NODE_PUSH_CONTIG_NAND(_node, _nodeByteOfs, _nodeSize, _cu) \ + { \ + l2v_assert_ne((_cu).span, 0); \ + (_cu).hasSpanOF = 0; \ + if ((_cu).span > (1UL << L2V.bits.nand_span)) { \ + (_cu).hasSpanOF = 1; \ + (_nodeSize) -= sizeof(UInt16); \ + *(UInt16*)&(_node)->bytes[_nodeSize] = ((_cu).span-1) >> L2V.bits.nand_span; \ + } \ + *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]) = LPTR_PACK_NAND(_cu); \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + } +#define _L2V_NODE_PUSH_CONTIG(_node, _nodeByteOfs, _nodeSize, _cu) \ + do { \ + if ((_cu).isNodePtr) { \ + _L2V_NODE_PUSH_CONTIG_NODE(_node, _nodeByteOfs, _nodeSize, _cu); \ + } else { \ + _L2V_NODE_PUSH_CONTIG_NAND(_node, _nodeByteOfs, _nodeSize, _cu); \ + } \ + } while (0) +#define _L2V_CONTIG_SIZE(_cu) (sizeof(lPtr_t) + (((_cu).isNodePtr || ((_cu).span > (1UL << L2V.bits.nand_span))) ? sizeof(UInt16) : 0)) + +#define _L2V_NODE_FILL(_node, _nodeByteOfs, _nodeSize) \ + do { \ + WMR_MEMSET(&(_node)->bytes[_nodeByteOfs], 0xFF, (_nodeSize) - (_nodeByteOfs)); \ + } while (0) + + +#define min(a, b) ((a) < (b) ? (a) : (b)) + + + + +#endif // __L2V_FUNCS_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Init.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Init.c new file mode 100644 index 0000000..809956f --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Init.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V_Mem.h" + +// Declare our L2V context structure here +L2V_t L2V; +UInt32 L2V_nodepool_mem = 0xffffffff; +UInt8 *L2V_root_depth; +tempNodePool_t tempNodes; + +void L2V_Nuke(void) +{ + UInt32 i; + Int32 j; + + // Set tree version + L2V.treeVersion = 0; + + // Empty roots; default to miss + for (i = 0; i < L2V.numRoots; i++) { + L2V.Root[i].rootContig = ROOT_CONTIG_DEALLOC; + L2V_root_depth[i] = 0; + } + + // Reset periodic repacker variables + L2V.RepackCounter = 0; + + // Finally, put all nodes in the free pool + L2V.Pool.FreePtr = NULL; + L2V.Pool.FreeCount = 0; + for (j = L2V_NODEPOOL_COUNT-1; j >= 0; j--) { + _L2V_FreeNode(&L2V.Pool.Node[j]); + } +} + +// Functions +BOOL32 L2V_Init(UInt32 numLbas, UInt32 max_sb, UInt32 vbas_per_sb) +{ + // Set up bits + // ... nand lptrs + L2V.bits.vba = WMR_LOG2((2 * max_sb * vbas_per_sb) - 1); + WMR_ASSERT(L2V.bits.vba <= 30); + L2V.bits.nand_span = 32 - 2 - L2V.bits.vba; + + // ... node lptrs + L2V.bits.nodeIdx = WMR_LOG2((2 * L2V_NODEPOOL_COUNT) - 1); + WMR_ASSERT(L2V.bits.nodeIdx <= 30); + L2V.bits.node_span = 32 - 2 - L2V.bits.nodeIdx; + + // Set up special vbas + L2V.vba.dealloc = (1 << L2V.bits.vba) - 1; + L2V.vba.special = L2V.vba.dealloc; + + // Set number of superblocks for valid accounting division + L2V.max_sb = max_sb; + L2V.vbas_per_sb = vbas_per_sb; + if ((max_sb * vbas_per_sb) > (L2V.vba.special+1)) { + WMR_PANIC("Tree bitspace not sufficient for geometry %dx%d: please re-adjust", max_sb, vbas_per_sb); + } + + // Calculate roots + L2V.numRoots = (numLbas >> L2V_TREE_BITS) + 1; + + // Allocate arrays + L2V.Root = WMR_MALLOC(L2V.numRoots * sizeof(Root_t)); + l2v_assert_ne(L2V.Root , NULL); + L2V_root_depth = WMR_MALLOC(L2V.numRoots); + l2v_assert_ne(L2V_root_depth , NULL); + + tempNodes.tempNodeEntries = NULL; + tempNodes.isEntryAvailable = NULL; + tempNodes.tempNodeEntries = WMR_MALLOC(sizeof(lNodeBig_t) * L2V_MAX_TREE_DEPTH); + l2v_assert_ne(tempNodes.tempNodeEntries, NULL); + tempNodes.isEntryAvailable = WMR_MALLOC(L2V_MAX_TREE_DEPTH); + l2v_assert_ne(tempNodes.isEntryAvailable, NULL); + tempNodes.poolSize = L2V_MAX_TREE_DEPTH; + WMR_MEMSET(tempNodes.isEntryAvailable, 0xff, tempNodes.poolSize); + + if(L2V_nodepool_mem != 0xffffffff) + { + L2V.Pool.Node = (lNode_t*)WMR_MALLOC(L2V_nodepool_mem); + if (NULL == L2V.Pool.Node) { + return FALSE32; + } + } + else + { + return FALSE32; + } + + L2V_Nuke(); + + return TRUE32; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.c new file mode 100644 index 0000000..b7fef17 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Mem.h" +#include "L2V_Funcs.h" +#include "L2V_Assert.h" + + +void _L2V_FreeNode(lNode_t *node) +{ + static int freeCount = 0; + + freeCount++; + + l2v_assert_ge(node, &L2V.Pool.Node[0]); + l2v_assert_le(node, &L2V.Pool.Node[L2V_NODEPOOL_COUNT]); + + node->nextFreePtr = L2V.Pool.FreePtr; + L2V.Pool.FreePtr = node; + L2V.Pool.FreeCount++; +} + + +lNode_t *_L2V_AllocNode() +{ + lNode_t *ret; + static int allocCount = 0; + + allocCount++; + + ret = (lNode_t*)L2V.Pool.FreePtr; + if (NULL != ret) { + L2V.Pool.FreePtr = L2V.Pool.FreePtr->nextFreePtr; + L2V.Pool.FreeCount--; + _L2V_NODE_FILL(ret, 0, L2V_NODE_SIZE); + } + l2v_assert_ne(ret, NULL); + + return ret; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.h new file mode 100644 index 0000000..f744442 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Mem.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_MEM_H__ +#define __L2V_MEM_H__ + + +#include "L2V_Types.h" + + +extern void _L2V_FreeNode(lNode_t *node); +extern lNode_t *_L2V_AllocNode(void); // Warning: may return NULL; up to caller to handle gracefully + + +#endif // __L2V_MEM_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.c new file mode 100644 index 0000000..1ae8313 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V_Print.h" +#include "L2V_Funcs.h" +#include "L2V.h" +#include "L2V_Types.h" + + +#define PRINT_MAXPATH 0 + + +// Prototypes + +static int L2V_GetUsage(lNode_t *node, UInt32 *used, UInt32 *total, UInt32 *nodes, UInt32 totalSpan, BOOL32 isMax); + + +// Functions + +void L2V_PrintPtr(lPtr_t lptr) +{ + ContigUnpacked_t cu; + LPTR_UNPACK(lptr, cu); + L2V_PrintCU(&cu); +} + +void L2V_PrintCU(ContigUnpacked_t *cu) +{ + if (cu->isNodePtr) + printf("[Node]"); + else + printf("[NAND]"); + + if (cu->hasSpanOF) + printf("o"); + else + printf("-"); + + if (cu->isNodePtr) { + printf("[idx:%d][span:%d]", cu->u.nodeIdx, cu->span); + } else { + if (L2V_VBA_DEALLOC == cu->u.vba) { + printf("[vba:DEALLOC][span:%d]", cu->span); + } else { + printf("[vba:%d][span:%d]", cu->u.vba, cu->span); + } + } + + printf("\n"); +} + + +void L2V_PrintNode(lNode_t *node) +{ + UInt32 nOfs, nodeSize; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + L2V_PrintCU(&cu); + } _L2V_NODE_ITERATE_END(nOfs); +} + + +void L2V_PrintUsage(UInt32 tree) +{ + UInt32 used, total, nodes, maxdepth; + RootContig_t rc = L2V.Root[tree].rootContig; + + used = total = nodes = maxdepth = 0; + printf("digraph G {\n"); + if (ROOT_CONTIG_DEALLOC != rc) + { + maxdepth = L2V_GetUsage(L2V_IDX_TO_NODE(ROOT_CONTIG_GET_NODEIDX(rc)), &used, &total, &nodes, L2V_TREE_SIZE, 1); + } + else + { + printf("[NAND]r[vba:DEALLOC][span:32768]\n"); + } + printf("}\n"); + printf("\nUsage tree %d: %.2f, nodes: %d, maxdepth: %d\n", tree, total ? (float)used/(float)total : 0, nodes, maxdepth); + printf("Nodes calc: %d tally: %d\n\n", nodes, L2V.Root[tree].numNodes); + if (nodes != L2V.Root[tree].numNodes) + { + WMR_PANIC("nodes (%d) != L2V.Root[tree].numNodes (%d)\n", nodes, L2V.Root[tree].numNodes); + } +} + +static int L2V_GetUsage(lNode_t *node, UInt32 *used, UInt32 *total, UInt32 *nodes, UInt32 totalSpan, BOOL32 isMax) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + UInt32 sumSpan; + lPtr_t thisPtr, maxNode; + UInt32 depth, maxDepth, maxSpan; + ContigUnpacked_t cu; + UInt32 thisUsed = 0; + + // Walk through + (*nodes)++; + maxDepth = 0; + sumSpan = 0; + + // Iterate through the node, + L2V_PrintNode(node); + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + thisUsed += sizeof(lPtr_t); + if (cu.hasSpanOF) thisUsed += sizeof(UInt16); + if (cu.isNodePtr) { + printf("%d -> %d;\n", (int)L2V_NODE_TO_IDX(node), cu.u.nodeIdx); // DOT output + l2v_assert_ne(cu.u.nodeIdx, 65535); + l2v_assert_ne(L2V_IDX_TO_NODE(cu.u.nodeIdx), node); + l2v_assert_ne(cu.span, 0); + depth = L2V_GetUsage(L2V_IDX_TO_NODE(cu.u.nodeIdx), used, total, nodes, cu.span, 0); + if (depth > maxDepth) { + maxDepth = depth; + maxNode = thisPtr; + maxSpan = cu.span; + } + } + sumSpan += cu.span; + l2v_assert_le(cu.span, 32768); + } _L2V_NODE_ITERATE_END(nOfs); + *used += thisUsed; + *total += sizeof(lNode_t); + printf("%d [label=\"us:%.2f\\nsp:%.2f\",shape=box,style=filled,color=\"1.0 %.2f 1.0\"];\n", (int)L2V_NODE_TO_IDX(node), (float)thisUsed/sizeof(lNode_t), (float)totalSpan/L2V_TREE_SIZE, (float)thisUsed/sizeof(lNode_t)); // DOT output + + if (sumSpan != totalSpan) { + printf("Sum: %d, total: %d\n", sumSpan, totalSpan); + L2V_PrintNode(node); + } + l2v_assert_eq(sumSpan, totalSpan); + l2v_assert_ne(nOfs, 0); + +#if PRINT_MAXPATH + if (maxDepth && isMax) { + printf("<-%d", maxNode.node.nodeIdx); + L2V_GetUsage(L2V_LPTR_TO_NODE(maxNode), &nOfs, &nOfs, &nOfs, maxSpan, 1); + } +#endif + + return maxDepth+1; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.h new file mode 100644 index 0000000..da1e5ce --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Print.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_PRINT_H__ +#define __L2V_PRINT_H__ + + +#include "L2V_Types.h" + + +extern void L2V_PrintPtr(lPtr_t lptr); +extern void L2V_PrintCU(ContigUnpacked_t *cu); +extern void L2V_PrintNode(lNode_t *node); +extern void L2V_PrintUsage(UInt32 tree); + + +#endif // __L2V_PRINT_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.c new file mode 100644 index 0000000..ec60c96 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define AND_TRACE_LAYER FTL + +#include "L2V_Repack.h" +#include "L2V.h" +#include "L2V_Types.h" +#include "L2V_Mem.h" +#include "L2V_Funcs.h" + + +#define REPACK_MAX_NODES (L2V_TREE_SIZE/L2V_MIN_CONTIG_PER_NODE) +#define REPACK_TREE_LOG_SIZE 32 + +typedef struct { + lNode_t *bottom[REPACK_MAX_NODES]; + UInt32 bottomSpan[REPACK_MAX_NODES]; + UInt32 bottomIdx; + UInt32 bottom_nOfs; + UInt32 bottom_nodeSize; +#if REPACK_DATA_GATHERING + UInt32 repackedTree[REPACK_TREE_LOG_SIZE]; + UInt32 updSinceRepack[REPACK_TREE_LOG_SIZE]; + UInt32 numNodesBef[REPACK_TREE_LOG_SIZE]; + UInt32 numNodesAft[REPACK_TREE_LOG_SIZE]; + UInt32 numNodeContBef[REPACK_TREE_LOG_SIZE]; + UInt32 numNodeContAft[REPACK_TREE_LOG_SIZE]; + UInt32 numNandCont[REPACK_TREE_LOG_SIZE]; + UInt32 timeREP[REPACK_TREE_LOG_SIZE]; + UInt32 timeCD[REPACK_TREE_LOG_SIZE]; + UInt32 timeREB[REPACK_TREE_LOG_SIZE]; + UInt32 repackTreeLogIdx; +#endif +} RepackCtx_t; + + +// Static definitions +static void CopyAndDestroy(RepackCtx_t *r, lNode_t *node); +static int Rebuild(RepackCtx_t *r); +static void ReplaceRoot(RepackCtx_t *r, UInt32 tree); +static int CopyAndDestroyOneNode(RepackCtx_t *r, lNode_t *node, int nodeCount); + + +UInt32 L2V_ForceRepack(void) +{ + UInt32 best; + UInt32 merit, bestMerit, i; + + // Find best candidate; merit==updates + bestMerit = 0; + best = 0xffffffff; + for (i = 0; i < L2V.numRoots; i++) { + if((L2V.Root[i].rootContig != ROOT_CONTIG_DEALLOC) && (L2V.Root[i].numNodes > 0) && (L2V.Root[i].updatesSinceRepack > 0)) + { + merit = L2V.Root[i].updatesSinceRepack; + if (merit >= bestMerit) { + bestMerit = merit; + best = i; + } + } + } + + if(L2V_CriticalMem) + { + l2v_assert_ne(best, 0xffffffff); + l2v_assert_ne(bestMerit, 0); + } + + if(best != 0xffffffff) + { + L2V_Repack(best); + } + return best; +} + +void L2V_PeriodicRepack() +{ + // Check if it's appropriate or not + if (L2V.RepackCounter < L2V_REPACK_PERIOD) { + return; + } + L2V.RepackCounter = 0; + + L2V_ForceRepack(); +} + + +// WARNING: NOT REENTRANT +static RepackCtx_t r; +void L2V_Repack(UInt32 tree) +{ + lNode_t *root; + RootContig_t rc; +#if REPACK_DATA_GATHERING + UInt64 ticks, ticks_CD, ticks_REB; + + ticks = WMR_CLOCK_TICKS(); + + // Log which tree we repacked + if (r.repackTreeLogIdx >= REPACK_TREE_LOG_SIZE) { + r.repackTreeLogIdx = 0; + } + r.repackedTree[r.repackTreeLogIdx] = tree; + r.updSinceRepack[r.repackTreeLogIdx] = L2V.Root[tree].updatesSinceRepack; + r.numNodesBef[r.repackTreeLogIdx] = L2V.Root[tree].numNodes; + r.numNodeContBef[r.repackTreeLogIdx] = 0; + r.numNodeContAft[r.repackTreeLogIdx] = 0; + r.numNandCont[r.repackTreeLogIdx] = 0; + +#endif + + rc = L2V.Root[tree].rootContig; + + // Trying to repack a rootptr? Abort... + if (ROOT_CONTIG_DEALLOC == rc) { + return; + } + + WMR_TRACE_1(Repack, START, tree); + + // Up tree version for search-update coherency + L2V.treeVersion++; + + // Create list of new bottom layer + r.bottomIdx = 0; + r.bottom_nOfs = 0; + r.bottom_nodeSize = L2V_NODE_SIZE; + WMR_MEMSET(r.bottom, 0, REPACK_MAX_NODES * sizeof(r.bottom[0])); + WMR_MEMSET(r.bottomSpan, 0, REPACK_MAX_NODES * sizeof(r.bottomSpan[0])); + + // Recurse and destroy + root = L2V_IDX_TO_NODE(ROOT_CONTIG_GET_NODEIDX(rc)); +#if REPACK_DATA_GATHERING + ticks_CD = WMR_CLOCK_TICKS(); +#endif + CopyAndDestroy(&r, root); +#if REPACK_DATA_GATHERING + ticks_CD = WMR_CLOCK_TICKS() - ticks_CD; +#endif + + l2v_assert_ne(r.bottom_nOfs, 0); + +#if REPACK_DATA_GATHERING + ticks_REB = WMR_CLOCK_TICKS(); +#endif + // Rebuild hierarchy + L2V.Root[tree].numNodes = Rebuild(&r); +#if REPACK_DATA_GATHERING + ticks_REB = WMR_CLOCK_TICKS() - ticks_REB; +#endif + + // Replace root + ReplaceRoot(&r, tree); + + // Clear repack counter + L2V.Root[tree].updatesSinceRepack = 0; + +#if REPACK_DATA_GATHERING + ticks = WMR_CLOCK_TICKS() - ticks; + + r.numNodesAft[r.repackTreeLogIdx] = L2V.Root[tree].numNodes; + r.timeREP[r.repackTreeLogIdx] = (UInt32)(ticks / WMR_GET_TICKS_PER_US()); + r.timeCD[r.repackTreeLogIdx] = (UInt32)(ticks_CD / WMR_GET_TICKS_PER_US()); + r.timeREB[r.repackTreeLogIdx] = (UInt32)(ticks_REB / WMR_GET_TICKS_PER_US()); + + r.repackTreeLogIdx++; + +#endif + + WMR_TRACE_0(Repack, END); +} + + +static int CopyAndDestroyOneNode(RepackCtx_t *r, lNode_t *node, int nodeCount) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + ContigUnpacked_t cu; + lPtr_t thisPtr; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + // Would be full? Move along... + if ((r->bottom_nOfs + _L2V_CONTIG_SIZE(cu)) > r->bottom_nodeSize) { + r->bottomIdx++; + l2v_assert_lt(r->bottomIdx, REPACK_MAX_NODES); + } + + // Allocate node if necessary + if (NULL == r->bottom[r->bottomIdx]) { + // Allocate... + r->bottom[r->bottomIdx] = _L2V_AllocNode(); + nodeCount++; + r->bottom_nOfs = 0; + r->bottom_nodeSize = L2V_NODE_SIZE; + } + + // Copy out + _L2V_NODE_PUSH_CONTIG(r->bottom[r->bottomIdx], r->bottom_nOfs, r->bottom_nodeSize, cu); + r->bottomSpan[r->bottomIdx] += cu.span; + l2v_assert_le(cu.span, L2V_TREE_SIZE); + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); + nodeCount--; + return nodeCount; +} + + +static void CopyAndDestroy(RepackCtx_t *r, lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + ContigUnpacked_t cu; + lPtr_t thisPtr; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse +#if REPACK_DATA_GATHERING + r->numNodeContBef[r->repackTreeLogIdx]++; +#endif + CopyAndDestroy(r, L2V_IDX_TO_NODE(cu.u.nodeIdx)); + } else { +#if REPACK_DATA_GATHERING + r->numNandCont[r->repackTreeLogIdx]++; +#endif + // Would be full? Move along... + if ((r->bottom_nOfs + _L2V_CONTIG_SIZE(cu)) > r->bottom_nodeSize) { + r->bottomIdx++; + l2v_assert_lt(r->bottomIdx, REPACK_MAX_NODES); + } + + // Allocate node if necessary + if (NULL == r->bottom[r->bottomIdx]) { + // Allocate... + r->bottom[r->bottomIdx] = _L2V_AllocNode(); + r->bottom_nOfs = 0; + r->bottom_nodeSize = L2V_NODE_SIZE; + } + + // Copy out + _L2V_NODE_PUSH_CONTIG(r->bottom[r->bottomIdx], r->bottom_nOfs, r->bottom_nodeSize, cu); + r->bottomSpan[r->bottomIdx] += cu.span; + l2v_assert_le(cu.span, L2V_TREE_SIZE); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); +} + + +static int Rebuild(RepackCtx_t *r) +{ + lNode_t *thisBranch; + UInt32 nOfs, nodeSize, thisSpan, i, branchIdx; + ContigUnpacked_t cu; + int nodeCount; + lNode_t *tempBottomNode; + + nodeCount = r->bottomIdx + 1; + + while (r->bottomIdx > 0) { + thisBranch = _L2V_AllocNode(); + nodeCount++; + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + thisSpan = 0; + branchIdx = 0; + + // Rebuild this layer + for (i = 0; i < r->bottomIdx; i++) { + cu.isNodePtr = 1; + cu.u.nodeIdx = L2V_NODE_TO_IDX(r->bottom[i]); + cu.span = r->bottomSpan[i]; + + if ((nOfs + _L2V_CONTIG_SIZE(cu)) > nodeSize) { + // Place it down and get a new one + r->bottom[branchIdx] = thisBranch; + r->bottomSpan[branchIdx] = thisSpan; + branchIdx++; + thisBranch = _L2V_AllocNode(); + nodeCount++; + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + thisSpan = 0; + } + + _L2V_NODE_PUSH_CONTIG(thisBranch, nOfs, nodeSize, cu); + thisSpan += cu.span; +#if REPACK_DATA_GATHERING + r->numNodeContAft[r->repackTreeLogIdx]++; +#endif + } + + l2v_assert_ne(nOfs, 0); + + r->bottom[branchIdx] = thisBranch; + r->bottomSpan[branchIdx] = thisSpan; + tempBottomNode = r->bottom[r->bottomIdx]; + // Get ready for the next round + r->bottomIdx = branchIdx; + r->bottom_nOfs = nOfs; + r->bottom_nodeSize = nodeSize; + WMR_MEMSET(&(r->bottom[branchIdx + 1]), 0, (REPACK_MAX_NODES - (branchIdx + 1)) * sizeof(r->bottom[0])); + WMR_MEMSET(&(r->bottomSpan[branchIdx + 1]), 0, (REPACK_MAX_NODES - (branchIdx + 1)) * sizeof(r->bottomSpan[0])); + + // repack the remainder to ensure we do not waste extra node + nodeCount = CopyAndDestroyOneNode(r, tempBottomNode, nodeCount); + + // Make sure the repack didn't munge the root node's spans + if (0 == r->bottomIdx) { + l2v_assert_eq(r->bottomSpan[r->bottomIdx], L2V_TREE_SIZE); + } + } + + return nodeCount; +} + + +static void ReplaceRoot(RepackCtx_t *r, UInt32 tree) +{ + ContigUnpacked_t cu; + l2v_assert_eq(r->bottomIdx, 0); + cu.u.nodeIdx = L2V_NODE_TO_IDX(r->bottom[0]); + cu.isNodePtr = 1; + L2V.Root[tree].rootContig = ROOT_CONTIG_PACK(cu); + if(ROOT_CONTIG_DEALLOC == L2V.Root[tree].rootContig) + { + L2V_root_depth[tree] = 0; + } +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.h new file mode 100644 index 0000000..6d5354c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Repack.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_REPACK_H__ +#define __L2V_REPACK_H__ + + +#include "WMROAM.h" + +// Functions + +extern void L2V_PeriodicRepack(void); +extern void L2V_Repack(UInt32 tree); +extern UInt32 L2V_ForceRepack(void); + +#endif // __L2V_REPACK_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Search.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Search.c new file mode 100644 index 0000000..cda9a5b --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Search.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Funcs.h" + + +void L2V_Search_Init(L2V_SearchCtx_t *c) +{ + c->next_lba = 0xffffffff; + c->last_node = NULL; + c->span = 0; +} + + +static BOOL32 HitCache(L2V_SearchCtx_t *c) +{ + ContigUnpacked_t cu; + lPtr_t thisPtr; + + + if ((c->treeVersion == L2V.treeVersion) && (c->lba == c->next_lba) && (NULL != c->last_node)) { + // Sequential HIT + _L2V_NODE_ITERATE_RESUME(c->last_node, c->next_nOfs, c->nodeSize, cu, thisPtr) { + if (cu.isNodePtr) + break; + + c->vba = cu.u.vba; + c->fromStart = 0; + c->span = cu.span; + + _L2V_NODE_ITERATE_NEXT(c->next_nOfs); // This will move nOfs along + c->next_lba = c->lba + c->span; + return TRUE32; + + } _L2V_NODE_ITERATE_END_NOP; + } + + // Clear search history + c->next_lba = 0xffffffff; + c->last_node = NULL; + + return FALSE32; +} + + +void L2V_Search(L2V_SearchCtx_t *c) +{ + UInt32 targTree, targTofs; + UInt32 thisStart, thisMax; + UInt32 nOfs, nodeSize; // Byte offset within the node, and node effective size + ContigUnpacked_t cu, thiscu; + lNode_t *node = NULL; + lPtr_t thisPtr; + + if (HitCache(c)) { + return; + } + + // Determine first root + targTree = c->lba >> L2V_TREE_BITS; + targTofs = c->lba & L2V_TREE_MASK; + l2v_assert_lt(targTree, L2V.numRoots); + + c->level = 0; + thisStart = 0; + c->vba = L2V_VBA_DEALLOC; + ROOT_CONTIG_UNPACK(L2V.Root[targTree].rootContig, cu); + thiscu.span = L2V_TREE_SIZE; + c->next_nOfs = 0; + + // Search from top down + while (c->level < L2V_MAX_TREE_DEPTH) { + // Down and next + // Decode node pointer + if (!cu.isNodePtr) { + // Terminal case--pointer to physical location; calculate relative offset... + c->vba = cu.u.vba; + c->fromStart = targTofs - thisStart; + if (cu.u.vba < L2V_VBA_SPECIAL) { + c->vba += c->fromStart; + } + c->span = thiscu.span - c->fromStart; + // Set up return case for sequential searching + c->last_node = node; + c->next_lba = c->lba + c->span; + c->treeVersion = L2V.treeVersion; + // c->next_nOfs is populated from code below, i.e. the previous iteration of this while loop + + // Is it getting really big? Do some preventative maintenence... + if (c->level >= L2V_TREE_DEPTH_REPACK) { + L2V_Repack(targTree); + } + return; + } + + // Walk through + node = L2V_IDX_TO_NODE(cu.u.nodeIdx); + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + // Calculate endpoint + thisMax = thisStart + thiscu.span; + + // Are we in range? + if (targTofs < thisMax) { + // HIT! (Left-hand side implied by order of search.) + cu = thiscu; + _L2V_NODE_ITERATE_NEXT(nOfs); + c->next_nOfs = nOfs; + c->nodeSize = nodeSize; + goto decodePtr; + } + + // Move along in the node + thisStart = thisMax; + } _L2V_NODE_ITERATE_END(nOfs); + + WMR_PANIC("NAND index: bad tree: targTofs %d, level %d\n", targTofs, c->level); + +decodePtr: + // Resume here so we can check the while() condition + c->level++; + } + + l2v_assert(0); // Should never get here; otherwise, the tree is too deep (or recursive or pointing to randomness) +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.c new file mode 100644 index 0000000..b602a4b --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Funcs.h" +#include "L2V_Print.h" +#include +#include + +L2V_t L2V; + + +#define LAST_TREE_TEST 16 +#define SIMPLE_SIZE (L2V_TREE_SIZE*LAST_TREE_TEST) + + +// Prototypes +static void RandomTest(void); +static void SequentialTest(void); +static void Simple_Init(void); +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vba); +static void Simple_Lookup(UInt32 lba, UInt32 *vba); + +void Usage(int argc, char** argv) +{ + printf("Usage: %s s OR %s r (for sequential and random, respectively\n", argv[0], argv[0]); + exit(-1); +} + +int test = 0; + +int main(int argc, char** argv) +{ + // we should add an option to change a pool size via command line + L2V_nodepool_mem = DEFAULT_L2V_NODEPOOL_MEM; + + //L2V_Init(SIMPLE_SIZE, 32768, 32768); + //L2V_Init(SIMPLE_SIZE, 16384, 32768); + //L2V_Init(SIMPLE_SIZE, 16384, 16384); + //L2V_Init(SIMPLE_SIZE, 8192, 8192); + L2V_Init(SIMPLE_SIZE, 8200, 8192); + + if (argc == 2) { + if ('r' == argv[1][0]) { + test = 0; + } else if ('s' == argv[1][0]) { + test = 1; + } else { + Usage(argc, argv); + } + } + if (argc > 2) { + Usage(argc, argv); + } + + if (0 == test) { + RandomTest(); + } else { + SequentialTest(); + } + + return 0; +} + + +#define MAXLEN 512 +static void RandomTest() { + UInt32 lba, size, vba; + UInt32 i, svba; + L2V_SearchCtx_t c; + + L2V_Search_Init(&c); + + Simple_Init(); + + sranddev(); + + while (1) { + lba = rand() % ((L2V_TREE_SIZE*LAST_TREE_TEST)-MAXLEN); + size = (rand() % (MAXLEN-1))+1; + vba = rand() % ((1UL<<(L2V.bits.vba-1))-size-1); + + printf("[UPD: lba:%d, size:%d, vba:%d]\n", lba, size, vba); + L2V_Update(lba, size, vba, 0); + Simple_Update(lba, size, vba); + //printf("\n"); + //L2V_PrintNode(L2V_LPTR_TO_NODE(L2V.Tree[0])); + L2V_PrintUsage(lba/L2V_TREE_SIZE); + + + // Validate entire range + int maxlevel=0; + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_Lookup(i, &svba); + c.lba = i; + L2V_Search(&c); + if (c.level > maxlevel) maxlevel = c.level; + if (svba != c.vba) { + printf("\n\n\n"); + printf("====================\n"); + printf("MISMATCH lba:%d\n", i); + printf("--------------------\n"); + printf("Simple vba:%d\n", svba); + printf("Lookup vba:%d\n", c.vba); + } + l2v_assert_eq(svba, c.vba); + } + printf("maxlevel: %d\n", maxlevel); + l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH); + +#if 0 + if (repack++ > 10) { + printf("Repacking tree %d...\n", nextRepack); + L2V_Repack(nextRepack); + L2V_PrintUsage(nextRepack); + repack = 0; + nextRepack = (nextRepack + 1) % LAST_TREE_TEST; + } +#endif + } +} + +static void SequentialTest() { + UInt32 lba, size, vba; + UInt32 i, svba; + L2V_SearchCtx_t c; + + L2V_Search_Init(&c); + + Simple_Init(); + + sranddev(); + + lba = 0; + size = 0; + vba = 1; + + while (1) { + lba += size; + size = (rand() % (MAXLEN-1))+1; + if ((lba + size) >= L2V_TREE_SIZE) { + lba = 0; + } + if ((rand() & 3) == 0) { + vba = rand() % ((1UL<<(L2V.bits.vba-1))-size-1); + } + while (((vba + size) & ((1<<(L2V.bits.vba-1))-1)) < vba) { + vba = rand() % ((1UL<<(L2V.bits.vba-1))-size-1); + } + + printf("[UPD: lba:%d, size:%d, vba:%d]\n", lba, size, vba); + L2V_Update(lba, size, vba, 0); + Simple_Update(lba, size, vba); + L2V_PrintUsage(lba/L2V_TREE_SIZE); + vba += size; + + + // Validate entire range + int maxlevel=0; + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_Lookup(i, &svba); + c.lba = i; + L2V_Search(&c); + if (c.level > maxlevel) maxlevel = c.level; + if (svba != c.vba) { + printf("\n\n\n"); + printf("====================\n"); + printf("MISMATCH lba:%d\n", i); + printf("--------------------\n"); + printf("Simple vba:%d\n", svba); + printf("Lookup vba:%d\n", c.vba); + } + l2v_assert_eq(svba, c.vba); + } + printf("maxlevel: %d\n", maxlevel); + l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH); + } +} + + +UInt32 Simple_vba[SIMPLE_SIZE]; + +static void Simple_Init() +{ + UInt32 i; + + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_vba[i] = L2V_VBA_DEALLOC; + } +} + + +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vba) +{ + while (size) { + Simple_vba[lba] = vba; + + // Iterate + lba++; + if (vba < L2V_VBA_SPECIAL) { + vba++; + } + size--; + } +} + + +static void Simple_Lookup(UInt32 lba, UInt32 *vba) +{ + *vba = Simple_vba[lba]; +} + +void Outside_L2V_ValidUp(UInt32 vba, UInt32 count) +{ +} +void Outside_L2V_ValidDown(UInt32 vba, UInt32 count) +{ +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.mak b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.mak new file mode 100644 index 0000000..e05a87d --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Test.mak @@ -0,0 +1,28 @@ +OBJS=L2V_Test.o L2V_Funcs.o L2V_Init.o L2V_Mem.o L2V_Search.o L2V_Update.o L2V_Types.o L2V_Print.o L2V_Repack.o L2V_Free.o L2V_FindFrag.o WMROAM.o +LINK_TARGET=L2V_Test +REBUILDABLES=$(OBJS) $(LINK_TARGET) + +.PHONY: all +all: copythem $(LINK_TARGET) cleanthem + # + +.PHONY: copythem +copythem: + cp WMROAM-test.h WMROAM.h + cp WMROAM-test.c WMROAM.c + cp WMRFeatures-test.h WMRFeatures.h + +.PHONY: cleanthem +cleanthem: + rm WMROAM.c WMROAM.h WMRFeatures.h + +$(LINK_TARGET): $(OBJS) + gcc -g -o $@ $^ -Wall + +.PHONY: clean +clean: + rm -f $(REBUILDABLES) + rm WMROAM.c WMROAM.h WMRFeatures.h + +%.o: %.c + gcc -g -o $@ -c $< -Wall -I. diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.c new file mode 100644 index 0000000..f302375 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V_Defines.h" +#include "L2V_Types.h" +#include "L2V.h" + + +BOOL32 _L2V_NodeBig_PushContig(lNodeBig_t *big, ContigUnpacked_t *cu) +{ + Int32 last = ((Int32)big->max)-1; + l2v_assert_ne(cu->span, 0); + + if (!cu->isNodePtr && (last >= 0) && !big->cu[last].isNodePtr && ( + ((cu->u.vba < L2V_VBA_SPECIAL) && ((big->cu[last].u.vba+big->cu[last].span) == cu->u.vba)) + || ((cu->u.vba >= L2V_VBA_SPECIAL) && (big->cu[last].u.vba == cu->u.vba)))) + { + big->cu[last].span += cu->span; + return TRUE32; + } + + big->cu[big->max] = *cu; + big->max++; + + if (cu->isNodePtr) { + l2v_assert_lt(cu->u.nodeIdx, L2V_NODEPOOL_COUNT); + } + + return FALSE32; +} + + +BOOL32 _L2V_NodeBig_PushContig_Node(lNodeBig_t *big, UInt32 nodeIdx, UInt32 span) +{ + big->cu[big->max].isNodePtr = 1; + big->cu[big->max].u.nodeIdx = nodeIdx; + big->cu[big->max].span = span; + big->max++; + + return FALSE32; +} + + +BOOL32 _L2V_NodeBig_PushContig_Nand(lNodeBig_t *big, UInt32 vba, UInt32 span) +{ + Int32 last = ((Int32)big->max)-1; + l2v_assert_ne(span, 0); + + if ((last >= 0) && !big->cu[last].isNodePtr && ( + ((vba < L2V_VBA_SPECIAL) && ((big->cu[last].u.vba+big->cu[last].span) == vba)) + || ((vba >= L2V_VBA_SPECIAL) && (big->cu[last].u.vba == vba)))) + { + big->cu[last].span += span; + return TRUE32; + } + + big->cu[big->max].isNodePtr = 0; + big->cu[big->max].u.vba = vba; + big->cu[big->max].span = span; + big->max++; + + return FALSE32; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.h new file mode 100644 index 0000000..4380e26 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Types.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_TYPES_H__ +#define __L2V_TYPES_H__ + + +#include "WMROAM.h" +#include "L2V_Defines.h" +#include "L2V_Assert.h" + + +// Pointer type: can point to NAND, or to a subtree +// Bits: 0=isNodePtr, 1=hasSpanOF. +// isNodePtr=0: vba:L2V.bits.vba, span:L2V.bits.nand_span +// isNodePtr=1: nodeIdx:L2V.bits.nodeIdx, span:L2V.bits.node_span +// hasSpanOF: fetch 2 bytes from the right end of the node + +typedef UInt32 lPtr_t; +#define LPTR_IS_NODEPTR(_lptr) ((_lptr) & 1) +#define LPTR_HASSPANOF(_lptr) (((_lptr) & 2) >> 1) +#define LPTR_PACK_NAND(_cu) ( \ + (((_cu).hasSpanOF & 1) << 1) | \ + (((_cu).u.vba & (((1UL<> 1) & 1; \ + (_cu).u.vba = ((_lptr) >> 2) & ((1UL<> (2+L2V.bits.vba)) & ((1UL<> 1) & 1; \ + (_cu).u.nodeIdx = ((_lptr) >> 2) & ((1UL<> (2+L2V.bits.nodeIdx)) & ((1UL<> 2) & ((1UL<> L2V.bits.nand_span) +#define LPTR_PACK_NODE_SPANOF(_span) ((_span-1) >> L2V.bits.node_span) + +typedef UInt16 RootContig_t; +#define ROOT_CONTIG_DEALLOC (0xFFFF) +#define ROOT_CONTIG_GET_NODEIDX(rc) (rc) +#define ROOT_CONTIG_PACK(_cu) ((_cu).isNodePtr ? (_cu).u.nodeIdx : ROOT_CONTIG_DEALLOC) // might have to type cast to UInt16 +#define ROOT_CONTIG_UNPACK(_rc, _cu) do { \ + (_cu).hasSpanOF = 0; /* dont care */ \ + if (ROOT_CONTIG_DEALLOC == (_rc)) \ + { \ + (_cu).u.vba = L2V_VBA_DEALLOC; \ + (_cu).isNodePtr = 0; \ + } \ + else \ + { \ + (_cu).u.nodeIdx = (_rc); \ + (_cu).isNodePtr = 1; \ + } \ + (_cu).span = L2V_TREE_SIZE; \ + }while(0); + +typedef struct { + UInt32 isNodePtr; // Values: 0, 1 (true)... must not be any other value + UInt32 hasSpanOF; // Values: 0, 1 (true)... ditto + union { + UInt32 vba; + UInt32 nodeIdx; + } u; + UInt32 span; +} ContigUnpacked_t; + + +// Node type: union for dynamic and fixed node types (and FreePool linkage) +typedef union _lNode_t { + union _lNode_t *nextFreePtr; + + UInt8 bytes[L2V_NODE_SIZE]; +} lNode_t; +WMR_CASSERT(L2V_NODE_SIZE == sizeof(lNode_t), lNode_t_size_matches); + +#define L2V_LNODEBIG_MAX (L2V_MAX_CONTIG_PER_NODE+(L2V_SUCKUP_CHILDREN_MAX*2)+5) +typedef struct { + ContigUnpacked_t cu[L2V_LNODEBIG_MAX]; + UInt32 start; + UInt32 max; +} lNodeBig_t; + + +typedef struct { + lNode_t *Node; // Node pool allocated with malloc() + lNode_t *FreePtr; + UInt32 FreeCount; +} FTLight_NodePool_t; + +typedef struct{ + lNodeBig_t *tempNodeEntries; + UInt8 *isEntryAvailable; + UInt32 poolSize; +} tempNodePool_t; + +typedef struct { + RootContig_t rootContig; + UInt16 numNodes; + UInt16 updatesSinceRepack; // 2 bytes because upper bounded by L2V_REPACK_PERIOD(which is 200) +} Root_t; + +typedef struct { + UInt32 node_span; + UInt32 nodeIdx; + UInt32 nand_span; + UInt32 vba; +} L2V_Bits_t; + +typedef struct { + // Special vbas + UInt32 special; + UInt32 dealloc; +} L2V_vba_t; + + +typedef struct { + // Logical space + UInt32 numRoots; + Root_t *Root; + UInt32 RepackCounter; + UInt32 treeVersion; + + // Physical space + UInt32 max_sb; + UInt32 vbas_per_sb; + + // Bit arrangements + L2V_Bits_t bits; + // Special VBAs + L2V_vba_t vba; + + // Memory + FTLight_NodePool_t Pool; +} L2V_t; + +typedef struct { + // Input: + UInt32 lba; + + // Output: + UInt32 fromStart; // blocks from start of treeSpan + UInt32 vba; + UInt32 span; + + // Internal state: + lNode_t *last_node; + UInt32 next_lba; + UInt32 next_nOfs; + UInt32 nodeSize; + UInt32 level; + UInt32 treeVersion; +} L2V_SearchCtx_t; + + +// Helper functions + +extern BOOL32 _L2V_NodeBig_PushContig(lNodeBig_t *big, ContigUnpacked_t *cu); // True: compressed with left +extern BOOL32 _L2V_NodeBig_PushContig_Node(lNodeBig_t *big, UInt32 nodeIdx, UInt32 span); // True: compress with left (always false) +extern BOOL32 _L2V_NodeBig_PushContig_Nand(lNodeBig_t *big, UInt32 vba, UInt32 span); // True: compressed with left +#define _L2V_NodeBig_WillCompress(_big, _vba, _span) \ + ((_big.max > 0) && (!_big.cu[_big.max-1].isNodePtr) && \ + (((_vba < L2V_VBA_SPECIAL) && ((_big.cu[_big.max-1].u.vba+_big.cu[_big.max-1].span) == _vba)) \ + || ((_vba >= L2V_VBA_SPECIAL) && (_big.cu[_big.max-1].u.vba == _vba)))) + + +#endif // __L2V_TYPES_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Update.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Update.c new file mode 100644 index 0000000..afc726c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Update.c @@ -0,0 +1,1213 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Funcs.h" +#include "L2V_Mem.h" +#include "L2V_Valid.h" +#include "L2V_Repack.h" +#include "L2V_Types.h" + + +// ##### TYPE DEFINITIONS - LOCAL TO THIS SOURCE FILE ######################### + +typedef struct { + UInt32 incomingTree; + UInt32 incomingOfs, incomingSize; + UInt32 incomingEnd; + UInt32 vba; + + UInt32 thisStart, thisMax; // Span start/end ofs while in inner loop + + ContigUnpacked_t cu; + lPtr_t nodePtr; + lPtr_t thisPtr; + BOOL32 needsInsert; + lNode_t *node; + UInt32 nOfs; + UInt32 nodeSize; + + BOOL32 changed; // Did we change this node? + lNodeBig_t tmpNode; + + lNode_t *atLevel[L2V_MAX_TREE_DEPTH_UPD+5]; // Add some guard-band + UInt32 level; +} UpdateCtx_t; + + +// ##### PROTOTYPES - LOCAL TO THIS SOURCE FILE ############################### + +static void UpdateGuts(UInt32 lba, UInt32 size, UInt32 vba); +static void TeardownTree(UInt32 tree); +static int DestroySpanLeft(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 amount); +static int DestroySpanRight(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 keepAmount, UInt32 fullSpan); +static void DestroySpanMiddle(lPtr_t *p, UInt32 down); + +// Helpers: +static void SuckOneUp(UInt32 tree, lNodeBig_t *big, lPtr_t ptr); +static void Upd_TrivialInsert(void); +static BOOL32 Upd_IdentityReplace(void); +static BOOL32 Upd_CompleteOverlap(void); +static BOOL32 Upd_ChopRight(void); +static BOOL32 Upd_ChopLeft(void); +static void Upd_ChopMiddleNand(void); +static void Upd_FillRemainder(void); +static int Upd_GetNodeSize(void); +static int Upd_PushNodeOut(lNodeBig_t *b, lNode_t *node, UInt32 minEl, UInt32 maxEl); // Returns sumSpan +static void Upd_SplitAndPush(void); +static void RippleUp(lNode_t *oldNode, UInt32 span0, lNode_t *newNode, UInt32 span1); +static void Upd_ShareLeft(void); +static void Upd_ShareRight(void); +static int Upd_PushLeft(lNode_t *left); +static int Upd_PushRight(lNode_t *right); + + +// ##### FUNCTION DEFINITIONS - EXPORTED FUNCTIONS ############################ + +void L2V_Update(UInt32 lba, UInt32 size, UInt32 vba) +{ + UInt32 thisSize, treeOfs; + + // Running out of L2V memory? + while (L2V_CriticalMem) { + L2V_ForceRepack(); + } + + // Up tree version for search-update coherency + L2V.treeVersion++; + + while (size) { + treeOfs = lba & L2V_TREE_MASK; + thisSize = min(L2V_TREE_SIZE - treeOfs, size); + + UpdateGuts(lba, thisSize, vba); + + size -= thisSize; + lba += thisSize; + if (vba < L2V_VBA_SPECIAL) { + vba += thisSize; + } + } +} + + +// ##### FUNCTION DEFINITIONS - LOCAL TO THIS SOURCE FILE ##################### +UpdateCtx_t u; + +static lNodeBig_t * allocateTempNode(tempNodePool_t *tempNodes) +{ + UInt32 i; + for(i = 0; i < tempNodes->poolSize; i++) + { + if(tempNodes->isEntryAvailable[i]) + { + tempNodes->isEntryAvailable[i] = 0; + return &(tempNodes->tempNodeEntries[i]); + } + } + return NULL; +} + +static void freeTempNode(tempNodePool_t *tempNodes, lNodeBig_t * tempNode) +{ + UInt32 index = (UInt32)(tempNode - tempNodes->tempNodeEntries); + if(index < tempNodes->poolSize) + { + tempNodes->isEntryAvailable[index] = 0xff; + } +} + +static UInt32 L2V_GetDepth(lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + lPtr_t thisPtr; + UInt32 depth, maxDepth; + ContigUnpacked_t cu; + + // Walk through + maxDepth = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + depth = L2V_GetDepth(L2V_IDX_TO_NODE(cu.u.nodeIdx)); + if (depth > maxDepth) { + maxDepth = depth; + } + } + } _L2V_NODE_ITERATE_END(nOfs); + + return maxDepth+1; +} + + +static void UpdateGuts(UInt32 __lba, UInt32 __size, UInt32 __vba) +{ + ContigUnpacked_t tmpCu; + UInt32 nodesBefore = 0; + RootContig_t rc; + + // Input: guaranteed to not span trees + u.incomingTree = __lba >> L2V_TREE_BITS; + u.incomingOfs = __lba & L2V_TREE_MASK; + u.incomingSize = __size; + u.incomingEnd = u.incomingOfs + u.incomingSize; + u.vba = __vba; + nodesBefore = L2V.Root[u.incomingTree].numNodes; + if (u.incomingTree >= L2V.numRoots) { + WMR_PANIC("L2V update with out-of-range LBA-- lba:%d, size:%d, vba:0x%x", __lba, __size, __vba); + } + + // Repack periodicity counter update + if(L2V.Root[u.incomingTree].updatesSinceRepack < 0xffff) + { + L2V.Root[u.incomingTree].updatesSinceRepack++; + } + L2V.RepackCounter++; + L2V_PeriodicRepack(); + + // First check: update the whole tree to dealloc state? + if ((0 == u.incomingOfs) && (L2V_TREE_SIZE == u.incomingSize) && (L2V_VBA_DEALLOC == u.vba)) { + TeardownTree(u.incomingTree); + L2V.Root[u.incomingTree].rootContig = ROOT_CONTIG_DEALLOC; + L2V_root_depth[u.incomingTree] = 0; + Outside_L2V_ValidUp(u.vba, L2V_TREE_SIZE); + return; + } + + // Share left/right, ripple up? + // Tear? + + u.level = 0; + u.thisStart = 0; + u.thisMax = L2V_TREE_SIZE; + ROOT_CONTIG_UNPACK(L2V.Root[u.incomingTree].rootContig, tmpCu); + + Outside_L2V_ValidUp(u.vba, u.incomingSize); + + if (!tmpCu.isNodePtr) { + u.nodePtr = LPTR_PACK_NAND(tmpCu); + Upd_TrivialInsert(); + return; + } + + u.nodePtr = LPTR_PACK_NODE(tmpCu); + + // Search from top down + while (u.level < L2V_MAX_TREE_DEPTH_UPD) { + // Walk through + LPTR_UNPACK_NODE(u.nodePtr, u.cu); + u.node = L2V_IDX_TO_NODE(u.cu.u.nodeIdx); + u.atLevel[u.level] = u.node; + u.changed = FALSE32; + u.needsInsert = TRUE32; + u.tmpNode.start = 0; + u.tmpNode.max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(u.node, u.nOfs, u.nodeSize, u.cu, u.thisPtr) { + // Calculate endpoint + u.thisMax = u.thisStart + u.cu.span; + if (u.cu.isNodePtr) { + l2v_assert_lt(u.cu.u.nodeIdx, L2V_NODEPOOL_COUNT); + } + + // Identity overlap? + if (Upd_IdentityReplace()) { + // Exit + goto exit; + } + + // Complete overlap? Free this piece... + else if (Upd_CompleteOverlap()) { + // ok + } + + // Chop right off? + else if (Upd_ChopRight()) { + // ok + } + + // Chop left off? + else if (Upd_ChopLeft()) { + // ok + } + + // Chop middle? (+2 total) + else if ((u.incomingOfs > u.thisStart) && (u.incomingEnd < u.thisMax)) { + if (!u.cu.isNodePtr) { + Upd_ChopMiddleNand(); + } else { + u.nodePtr = u.thisPtr; + goto nextLevel; + } + } + + // Too far right or left? Just copy it out... + Upd_FillRemainder(); + + // Move along in the node + u.thisStart = u.thisMax; + } _L2V_NODE_ITERATE_END(u.nOfs); + + // Last guy in the tree, with CompleteOverlaps to the left? (Since that case doesn't insert.) + if (u.needsInsert) { + u.changed = TRUE32; + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vba, u.incomingSize); + u.needsInsert = FALSE32; + } + + if (u.changed) { + // Will it fit? + if ((u.tmpNode.max > L2V_MIN_CONTIG_PER_NODE) && ((u.nOfs = Upd_GetNodeSize()) > L2V_NODE_SIZE)) { + // Try to share left/right + Upd_ShareLeft(); + Upd_ShareRight(); + + // Will it fit now? + if (((u.tmpNode.max-u.tmpNode.start) > L2V_MIN_CONTIG_PER_NODE) && ((u.nOfs = Upd_GetNodeSize()) > L2V_NODE_SIZE)) { + // Darn, split it + Upd_SplitAndPush(); + } else { + Upd_PushNodeOut(&u.tmpNode, u.node, u.tmpNode.start, u.tmpNode.max); + } + goto exit; + } + + if ((1 == (u.tmpNode.max - u.tmpNode.start)) + && (0 == u.level) + && (L2V_VBA_DEALLOC == u.tmpNode.cu[u.tmpNode.start].u.vba)) + { + // Single node, single entry, dealloc? Squash up into root. + _L2V_FreeNode(u.node); + L2V.Root[u.incomingTree].numNodes--; + L2V.Root[u.incomingTree].rootContig = ROOT_CONTIG_DEALLOC; + L2V_root_depth[u.incomingTree] = 0; + goto exit; + } + + Upd_PushNodeOut(&u.tmpNode, u.node, 0, u.tmpNode.max); + goto exit; + } + + l2v_assert(0); + +nextLevel: + u.level++; + } + + // Fell through + + // Should never get here; otherwise, the tree is too deep (or recursive or pointing to randomness) + WMR_PANIC("NAND index update fell through: abort at level %d\n", u.level); + +exit: + // Did it get bigger than we thought it should? + if (u.level > L2V_TREE_DEPTH_REPACK) + { + L2V_Repack(u.incomingTree); + rc = L2V.Root[u.incomingTree].rootContig; + if(L2V.Root[u.incomingTree].rootContig != ROOT_CONTIG_DEALLOC) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(ROOT_CONTIG_GET_NODEIDX(rc))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + } + return; + } + + if(nodesBefore <= L2V.Root[u.incomingTree].numNodes) + { + L2V_root_depth[u.incomingTree] += (L2V.Root[u.incomingTree].numNodes - nodesBefore); + if(L2V_root_depth[u.incomingTree] < L2V_TREE_DEPTH_REPACK) + { + return; + } + } + + rc = L2V.Root[u.incomingTree].rootContig; + if(L2V.Root[u.incomingTree].rootContig != ROOT_CONTIG_DEALLOC) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(ROOT_CONTIG_GET_NODEIDX(rc))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + return; + } + + if(L2V_root_depth[u.incomingTree] >= L2V_TREE_DEPTH_REPACK) + { + L2V_Repack(u.incomingTree); + if(L2V.Root[u.incomingTree].rootContig != ROOT_CONTIG_DEALLOC) + { + rc = L2V.Root[u.incomingTree].rootContig; + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(ROOT_CONTIG_GET_NODEIDX(rc))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + } + } + +} + + +static void Teardown(lNode_t *node, UInt32 tree) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node and size + lPtr_t thisPtr; + ContigUnpacked_t cu; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + Teardown(L2V_IDX_TO_NODE(cu.u.nodeIdx), tree); + } else { + // Reduce valid counters + Outside_L2V_ValidDown(cu.u.vba, cu.span); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); + L2V.Root[tree].numNodes--; +} + + +static void TeardownTree(UInt32 tree) +{ + RootContig_t rc = L2V.Root[tree].rootContig; + + if (ROOT_CONTIG_DEALLOC != rc) { + // Tear down the tree + Teardown(L2V_IDX_TO_NODE(ROOT_CONTIG_GET_NODEIDX(rc)), tree); + } +} + + +static int DestroySpanLeft(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 amount) +{ + lNode_t *node; + UInt32 nOfs, nodeSize; // Byte offset within the node, and size after subtracting overflows + UInt32 thisAmount; + Int32 children; + lNodeBig_t *tmpNode; + ContigUnpacked_t thiscu; + lPtr_t thisPtr; + + l2v_assert_ne(amount, 0); + l2v_assert_le(amount, L2V_TREE_SIZE); + + if (!cu->isNodePtr) { + Outside_L2V_ValidDown(cu->u.vba, amount); + if (cu->u.vba < L2V_VBA_SPECIAL) { + cu->u.vba += amount; + *p = LPTR_PACK_NAND(*cu); + } + return -1; + } else { + node = L2V_IDX_TO_NODE(cu->u.nodeIdx); + tmpNode = allocateTempNode(&tempNodes); + l2v_assert_ne(tmpNode, NULL); + tmpNode->max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + thisAmount = min(amount, thiscu.span); + if (thisAmount == thiscu.span) { + if (!thiscu.isNodePtr) { + Outside_L2V_ValidDown(thiscu.u.vba, thisAmount); + } else { + DestroySpanLeft(tree, &thiscu, &thisPtr, thisAmount); + } + } else if (thisAmount == 0) { + // Copy it out + _L2V_NodeBig_PushContig(tmpNode, &thiscu); + } else { + children = -1; + + if (!thiscu.isNodePtr) { + Outside_L2V_ValidDown(thiscu.u.vba, thisAmount); + if (thiscu.u.vba < L2V_VBA_SPECIAL) { + thiscu.u.vba += thisAmount; + } + } else { + children = DestroySpanLeft(tree, &thiscu, &thisPtr, thisAmount); + } + + // Copy it out + if (children == 1) { + SuckOneUp(tree, tmpNode, thisPtr); + } else { + thiscu.span -= thisAmount; + _L2V_NodeBig_PushContig(tmpNode, &thiscu); + } + } + amount -= thisAmount; + } _L2V_NODE_ITERATE_END(nOfs); + + if (0 == tmpNode->max) { // Destroyed the whole sub-tree + // Free this one + _L2V_FreeNode(node); + L2V.Root[tree].numNodes--; + *p = L2V_CONTIG_FREE_SIG; + } else { // Destroyed some full contigs and/or a partial contig of the sub-tree + // Push it back out + Upd_PushNodeOut(tmpNode, node, 0, tmpNode->max); + } + freeTempNode(&tempNodes, tmpNode); + return tmpNode->max; + } +} + + +static int DestroySpanRight(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 keepAmount, UInt32 fullSpan) +{ + lPtr_t thisPtr; + lNode_t *node; + UInt32 nOfs, nodeSize; // Byte offset within the node + UInt32 thisAmount; + Int32 children; + lNodeBig_t *tmpNode; + BOOL32 changed = FALSE32; + ContigUnpacked_t thiscu; + + l2v_assert_ne(keepAmount, 0); + l2v_assert_lt(keepAmount, L2V_TREE_SIZE); + l2v_assert_ne(fullSpan, 0); + l2v_assert_le(fullSpan, L2V_TREE_SIZE); + + if (!cu->isNodePtr) { + Outside_L2V_ValidDown(cu->u.vba, fullSpan-keepAmount); + return -1; + } else { + node = L2V_IDX_TO_NODE(cu->u.nodeIdx); + tmpNode = allocateTempNode(&tempNodes); + l2v_assert_ne(tmpNode, NULL); + tmpNode->max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + thisAmount = min(keepAmount, thiscu.span); + if (thisAmount == thiscu.span) { + // Copy it out + _L2V_NodeBig_PushContig(tmpNode, &thiscu); + } else if (thisAmount == 0) { + changed = TRUE32; + if (!thiscu.isNodePtr) { + Outside_L2V_ValidDown(thiscu.u.vba, thiscu.span); + } else { + DestroySpanLeft(tree, &thiscu, &thisPtr, thiscu.span); + } + } else if (thisAmount < thiscu.span) { + changed = TRUE32; + children = -1; + + if (!thiscu.isNodePtr) { + Outside_L2V_ValidDown(thiscu.u.vba, thiscu.span - thisAmount); + } else { + children = DestroySpanRight(tree, &thiscu, &thisPtr, thisAmount, thiscu.span); + } + + // Copy it out + if (children == 1) { + SuckOneUp(tree, tmpNode, thisPtr); + } else { + thiscu.span = thisAmount; + _L2V_NodeBig_PushContig(tmpNode, &thiscu); + } + } + keepAmount -= thisAmount; + } _L2V_NODE_ITERATE_END(nOfs); + + if (changed) { + // Push it back out + Upd_PushNodeOut(tmpNode, node, 0, tmpNode->max); + } + + if (0 == tmpNode->max) { + // Free this one + _L2V_FreeNode(node); + L2V.Root[tree].numNodes--; + *p = L2V_CONTIG_FREE_SIG; + } + freeTempNode(&tempNodes, tmpNode); + return tmpNode->max; + } +} + + +static void DestroySpanMiddle(lPtr_t *p, UInt32 down) +{ + ContigUnpacked_t cu; + + LPTR_UNPACK_NAND(*p, cu); + l2v_assert_eq(cu.isNodePtr, 0); // Must not be a nodePtr, since we recurse in the top-level function + Outside_L2V_ValidDown(cu.u.vba, down); +} + + +static void Upd_TrivialInsert() +{ + UInt32 nOfs, nodeSize; + lNode_t *node; + ContigUnpacked_t cu; + + LPTR_UNPACK_NAND(u.nodePtr, u.cu); + + // Break the rootPtr into a node + node = _L2V_AllocNode(); + nodeSize = L2V_NODE_SIZE; + L2V.Root[u.incomingTree].numNodes = 1; + nOfs = 0; + + // ValidDown for old section + if (u.cu.u.vba < L2V_VBA_SPECIAL) { + Outside_L2V_ValidDown(u.cu.u.vba, u.incomingSize); + } + + // Break left? + if (u.incomingOfs) { + cu.u.vba = u.cu.u.vba; + cu.span = u.incomingOfs; + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(u.incomingOfs, L2V_TREE_SIZE); + } + + // Insert node + cu.u.vba = u.vba; + cu.span = u.incomingSize; + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(u.incomingSize, L2V_TREE_SIZE); + + // Break Right? + cu.span = L2V_TREE_SIZE - u.incomingEnd; + if (cu.span != 0) { + cu.u.vba = u.cu.u.vba; + // Move vba if not special SB + if (cu.u.vba < L2V_VBA_SPECIAL) { + cu.u.vba += u.incomingEnd; + } + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(cu.span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(node, nOfs, nodeSize); + + // Update Tree ptr + cu.u.nodeIdx = L2V_NODE_TO_IDX(node); + cu.isNodePtr = 1; + L2V.Root[u.incomingTree].rootContig = ROOT_CONTIG_PACK(cu); + if(ROOT_CONTIG_DEALLOC == L2V.Root[u.incomingTree].rootContig) + { + L2V_root_depth[u.incomingTree] = 0; + } +} + + +static BOOL32 Upd_IdentityReplace() +{ + lPtr_t *p; + UInt32 check_nOfs, check_nodeSize; + lPtr_t check_thisPtr; + ContigUnpacked_t check_cu, local_cu; + + if ((u.incomingOfs == u.thisStart) && (u.incomingSize == u.cu.span)) { + // = + + // Make sure we aren't missing a compression opportunity + if (_L2V_NodeBig_WillCompress(u.tmpNode, u.vba, u.incomingSize)) { + return FALSE32; + } + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + // Destroy old, recursively destroying subtrees if necessary + DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.cu.span); + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + // Overwrite in place--works because nodeptrs are always 6 bytes, and if the span is the same size, updating in place will work + p = (lPtr_t*)(&u.node->bytes[u.nOfs]); + local_cu.isNodePtr = 0; + local_cu.hasSpanOF = 0; + if (LPTR_HASSPANOF(*p)) + local_cu.hasSpanOF = 1; + local_cu.u.vba = u.vba; + local_cu.span = u.cu.span; + if (local_cu.hasSpanOF) { + *(UInt16*)(&u.node->bytes[u.nodeSize]) = LPTR_PACK_NAND_SPANOF(u.cu.span); + } + *p = LPTR_PACK_NAND(local_cu); + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + return TRUE32; + } + + return FALSE32; +} + + +static BOOL32 Upd_CompleteOverlap() +{ + if ((u.incomingOfs <= u.thisStart) && (u.incomingEnd >= u.thisMax)) { + u.changed = TRUE32; + // Destroy old span + DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.cu.span); + + return TRUE32; + } + + return FALSE32; +} + + +static void SuckOneUp(UInt32 tree, lNodeBig_t *big, lPtr_t ptr) +{ + lNode_t *node; + UInt32 nOfs, nodeSize, count; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + l2v_assert_eq(LPTR_IS_NODEPTR(ptr), 1); + node = L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(ptr)); + count = 0; + + // Iterate over children + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + // Push into u->tmpNode + _L2V_NodeBig_PushContig(big, &cu); + count++; + } _L2V_NODE_ITERATE_END(nOfs); + l2v_assert_eq(count, 1); + + // Free old node + _L2V_FreeNode(node); + L2V.Root[tree].numNodes--; +} + +static void SuckUp() +{ + lNode_t *node; + UInt32 nOfs, nodeSize; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + l2v_assert_eq(LPTR_IS_NODEPTR(u.thisPtr), 1); + node = L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(u.thisPtr)); + + // Iterate over children + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + // Push into u->tmpNode + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + } _L2V_NODE_ITERATE_END(nOfs); + + // Free old node + _L2V_FreeNode(node); + L2V.Root[u.incomingTree].numNodes--; +} + + +static BOOL32 Upd_ChopRight() +{ + Int32 children; + ContigUnpacked_t cu; + + if ((u.incomingOfs > u.thisStart) && (u.incomingOfs < u.thisMax) && (u.incomingEnd >= u.thisMax)) { + u.changed = TRUE32; + children = DestroySpanRight(u.incomingTree, &u.cu, &u.thisPtr, u.incomingOfs - u.thisStart, u.cu.span); + + // Try to reduce tree depth and maximize usage by sucking children up + if ((children >= 1) && (children <= L2V_SUCKUP_CHILDREN_MAX)) { + SuckUp(); + } else if (0 != children) { + // Still have a child node we need to reference + cu = u.cu; + cu.span = u.incomingOfs - u.thisStart; + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + } + + if (u.needsInsert) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vba, u.incomingSize); + u.needsInsert = FALSE32; + } else { + l2v_assert(0); + } + + return TRUE32; + } + + return FALSE32; +} + + +static BOOL32 Upd_ChopLeft() +{ + Int32 children; + + if ((u.incomingOfs <= u.thisStart) && (u.incomingEnd > u.thisStart) && (u.incomingEnd < u.thisMax)) { + u.changed = TRUE32; + children = DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.incomingEnd - u.thisStart); + + if (u.needsInsert) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vba, u.incomingSize); + u.needsInsert = FALSE32; + } + + // Try to reduce tree depth and maximize usage by sucking children up + if ((children >= 1) && (children <= L2V_SUCKUP_CHILDREN_MAX)) { + SuckUp(); + } else if (0 != children) { + // Still have a child node or nand-ptr we need to reference + u.tmpNode.cu[u.tmpNode.max] = u.cu; + // Ofs moving taken care of by DestroySpanleft + u.tmpNode.cu[u.tmpNode.max].span = u.thisMax - u.incomingEnd; + l2v_assert_ne(u.thisMax - u.incomingEnd, 0); + u.tmpNode.max++; + } + + return TRUE32; + } + + return FALSE32; +} + + +static void Upd_ChopMiddleNand() +{ + u.changed = TRUE32; + DestroySpanMiddle(&u.thisPtr, u.incomingSize); + + // Break left + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.cu.u.vba, u.incomingOfs - u.thisStart); + + // Insert in middle + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vba, u.incomingSize); + u.needsInsert = FALSE32; + + // Break right + // +1 + if (u.cu.u.vba < L2V_VBA_SPECIAL) { + u.cu.u.vba += (u.incomingEnd - u.thisStart); + } + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.cu.u.vba, u.thisMax - u.incomingEnd); +} + + +static void Upd_FillRemainder() +{ + if ((u.thisStart >= u.incomingEnd) || (u.thisMax <= u.incomingOfs)) { + // Did none of the above trims/etc insert the new ptr? + // This is because we had an exact eclipse(s) + if (u.needsInsert && (u.thisStart >= u.incomingEnd)) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vba, u.incomingSize); + u.needsInsert = FALSE32; + } + + // Copy into tmpNode + _L2V_NodeBig_PushContig(&u.tmpNode, &u.cu); + } +} + + +static int Upd_GetNodeSize() +{ + UInt32 i, nOfs; + + nOfs = 0; + + for (i = u.tmpNode.start; i < u.tmpNode.max; i++) { + nOfs += _L2V_CONTIG_SIZE(u.tmpNode.cu[i]); + } + + return nOfs; +} + + +static int Upd_PushNodeOut(lNodeBig_t *b, lNode_t *node, UInt32 minEl, UInt32 maxEl) +{ + UInt32 i, nOfs, nodeSize; + UInt32 sumSpan; + + sumSpan = 0; + + l2v_assert_lt(minEl, L2V_LNODEBIG_MAX); + l2v_assert_le(maxEl, L2V_LNODEBIG_MAX); + + // Copy and squeeze + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + for (i = minEl; i < maxEl; i++) { + _L2V_NODE_PUSH_CONTIG(node, nOfs, nodeSize, b->cu[i]); + + sumSpan += b->cu[i].span; + l2v_assert_le(b->cu[i].span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(node, nOfs, nodeSize); + + return sumSpan; +} + + +static void Upd_SplitAndPush() +{ + lNode_t *newNode, *oldNode; + UInt32 half, span0, span1; + + // Get new node + oldNode = u.node; + newNode = _L2V_AllocNode(); + L2V.Root[u.incomingTree].numNodes++; + + // Divide and push to old/new + half = ((u.tmpNode.max - u.tmpNode.start)>>1) + 1 + u.tmpNode.start; + span0 = Upd_PushNodeOut(&u.tmpNode, oldNode, u.tmpNode.start, half); + l2v_assert_ne(span0, 0); + span1 = Upd_PushNodeOut(&u.tmpNode, newNode, half, u.tmpNode.max); + l2v_assert_ne(span1, 0); + + RippleUp(oldNode, span0, newNode, span1); +} + + +static void RippleUp(lNode_t *oldNode, UInt32 span0, lNode_t *newNode, UInt32 span1) +{ + lNode_t *parent, *parent1; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, span; + UInt32 parentspan0, parentspan1, half; + ContigUnpacked_t cu; + + u.tmpNode.start = u.tmpNode.max = 0; + + if (0 == u.level) { + // Special case: allocate another parent node, link these in + parent = _L2V_AllocNode(); + L2V.Root[u.incomingTree].numNodes++; + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(oldNode), span0); + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(newNode), span1); + span = Upd_PushNodeOut(&u.tmpNode, parent, 0, u.tmpNode.max); + l2v_assert_eq(span, L2V_TREE_SIZE); + + // Replace root + cu.u.nodeIdx = L2V_NODE_TO_IDX(parent); + cu.isNodePtr = 1; + L2V.Root[u.incomingTree].rootContig = ROOT_CONTIG_PACK(cu); + if(ROOT_CONTIG_DEALLOC == L2V.Root[u.incomingTree].rootContig) + { + L2V_root_depth[u.incomingTree] = 0; + } + } else { + // Get parent + parent = u.atLevel[u.level-1]; + + // Copy into tmpNode + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == oldNode)) { + // Copy old node + _L2V_NodeBig_PushContig_Node(&u.tmpNode, cu.u.nodeIdx, span0); + l2v_assert_ne(span0, 0); + + // Copy new node + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(newNode), span1); + l2v_assert_ne(span1, 0); + + if ((span0+span1) != cu.span) { + WMR_PANIC("NAND index: span0: %d, span1: %d, +: %d, span: %d", span0, span1, span0+span1, cu.span); + } + } else { + // Not involved, copy it out + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + l2v_assert_ne(cu.span, 0); + } + } _L2V_NODE_ITERATE_END(nOfs); + + if (u.tmpNode.max > L2V_MIN_CONTIG_PER_NODE) { + // Split + parent1 = _L2V_AllocNode(); + L2V.Root[u.incomingTree].numNodes++; + half = (u.tmpNode.max>>1) + 1; + parentspan0 = Upd_PushNodeOut(&u.tmpNode, parent, 0, half); + l2v_assert_ne(parentspan0, 0); + parentspan1 = Upd_PushNodeOut(&u.tmpNode, parent1, half, u.tmpNode.max); + l2v_assert_ne(parentspan1, 0); + + // Ripple up + u.level--; + RippleUp(parent, parentspan0, parent1, parentspan1); + } else { + // Push + Upd_PushNodeOut(&u.tmpNode, parent, 0, u.tmpNode.max); + } + } +} + + +static void Upd_ShareLeft() +{ + lNode_t *parent, *left; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, left_nodeIdx, left_nOfs, left_span, spanUp; + BOOL32 left_isNodePtr; + ContigUnpacked_t cu; + + // Initialize so the compiler doesn't complain + cu.hasSpanOF = 0; + cu.span = 0; + left_nOfs = 0; + left_nodeIdx = 0; + left_span = 0; + left_isNodePtr = 0; + + if (0 == u.level) { + // Can't share if we're root... + return; + } + + // Get parent + parent = u.atLevel[u.level-1]; + left = NULL; + + // Find me, then previous sibling + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == u.node)) { + goto foundIt; + } + left = L2V_IDX_TO_NODE(cu.u.nodeIdx); + left_nOfs = nOfs; + left_nodeIdx = cu.u.nodeIdx; + left_span = cu.span; + left_isNodePtr = cu.isNodePtr; + } _L2V_NODE_ITERATE_END(nOfs); + + // Couldn't find ...??? + WMR_PANIC("NAND index update failed node identity search: level: %d, parent: %p\n", u.level, (void*)parent); + +foundIt: + if ((NULL == left) || !left_isNodePtr) { + // We were the first pointed by parent, sorry, no easy left search... + return; + } + + // Great, push some in + spanUp = Upd_PushLeft(left); + + // Down my span in the parent + cu.span -= spanUp; + *(lPtr_t*)(&parent->bytes[nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize] = LPTR_PACK_NODE_SPANOF(cu.span); + l2v_assert_ne(cu.span, 0); + + // Update left's span in parent + left_span += spanUp; + cu.span = left_span; + cu.u.nodeIdx = left_nodeIdx; + *(lPtr_t*)(&parent->bytes[left_nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize+sizeof(UInt16)] = LPTR_PACK_NODE_SPANOF(left_span); + l2v_assert_ne(left_span, 0); +} + + +static void Upd_ShareRight() +{ + lNode_t *parent, *right; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, my_nOfs, my_nodeIdx, my_span, spanUp; + BOOL32 isNext; + ContigUnpacked_t cu; + + // Initialize so the compiler doesn't complain + my_span = 0; + my_nodeIdx = 0; + my_nOfs = 0; + + if (0 == u.level) { + // Can't share if we're root... + return; + } + + // Get parent + parent = u.atLevel[u.level-1]; + right = NULL; + + // Find me, then next sibling + isNext = FALSE32; + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (isNext) { + if (cu.isNodePtr) { + right = L2V_IDX_TO_NODE(cu.u.nodeIdx); + } + goto foundIt; + } + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == u.node)) { + isNext = TRUE32; + my_span = cu.span; + my_nOfs = nOfs; + my_nodeIdx = cu.u.nodeIdx; + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Couldn't find right because we were the last one? + l2v_assert_eq(isNext, 1); + return; + +foundIt: + if (NULL == right) { + // No node* right next to us, sorry... + return; + } + + // Great, push some in + spanUp = Upd_PushRight(right); + + // Update right's span in parent + cu.span += spanUp; + *(lPtr_t*)(&parent->bytes[nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize] = LPTR_PACK_NODE_SPANOF(cu.span); + l2v_assert_ne(cu.span, 0); + + // Down my span in the parent + my_span -= spanUp; + cu.u.nodeIdx = my_nodeIdx; + cu.span = my_span; + *(lPtr_t*)(&parent->bytes[my_nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize+sizeof(UInt16)] = LPTR_PACK_NODE_SPANOF(cu.span); + l2v_assert_ne(cu.span, 0); +} + + +static int Upd_PushLeft(lNode_t *left) +{ + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, spanUp, myEntrySize; + ContigUnpacked_t cu; + + spanUp = 0; + + // Has room? + _L2V_NODE_ITERATE(left, nOfs, nodeSize, cu, thisPtr) { + } _L2V_NODE_ITERATE_END(nOfs); + + // Calculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.start]); + + // While we have space... + while ((nOfs < (nodeSize-myEntrySize)) && ((u.tmpNode.max - u.tmpNode.start) > 1)) { + // Copy it out + l2v_assert_ne(u.tmpNode.cu[u.tmpNode.start].span, 0); + l2v_assert_le(u.tmpNode.cu[u.tmpNode.start].span, L2V_TREE_SIZE); + _L2V_NODE_PUSH_CONTIG(left, nOfs, nodeSize, u.tmpNode.cu[u.tmpNode.start]); + + // Move along + spanUp += u.tmpNode.cu[u.tmpNode.start].span; + u.tmpNode.start++; + + // Recalculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.start]); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(left, nOfs, nodeSize); + + // And ripple up + return spanUp; +} + + +static int Upd_PushRight(lNode_t *right) +{ + lPtr_t thisPtr; + UInt32 i, numToCopy, spanUp, nOfs, nodeSize, orig_nOfs, orig_nodeSize, myEntrySize; + lNodeBig_t localNode; + BOOL32 didSome = FALSE32; + ContigUnpacked_t cu; + + spanUp = 0; + + // Copy originals out and find out how much free space there is + localNode.start = localNode.max = 0; + _L2V_NODE_ITERATE(right, orig_nOfs, orig_nodeSize, cu, thisPtr) { + localNode.cu[localNode.max] = cu; + l2v_assert_ne(cu.span, 0); + localNode.max++; + } _L2V_NODE_ITERATE_END(orig_nOfs); + + // Calculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.max-1]); + + nOfs = 0; + numToCopy = 0; + + // While we have space... + while (((nOfs+orig_nOfs) < (orig_nodeSize-myEntrySize)) && ((u.tmpNode.max - u.tmpNode.start - numToCopy) > 1)) { + didSome = TRUE32; + + // Mark it as copyable + u.tmpNode.max--; + numToCopy++; + nOfs += myEntrySize; + + // Recalculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.max-1]); + } + + if (!didSome) { + // No room, sorry... + return 0; + } + + + + // Copy new ones + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + i = 0; + while (numToCopy) { + _L2V_NODE_PUSH_CONTIG(right, nOfs, nodeSize, u.tmpNode.cu[u.tmpNode.max+i]); + l2v_assert_le(u.tmpNode.cu[u.tmpNode.max+i].span, L2V_TREE_SIZE); + spanUp += u.tmpNode.cu[u.tmpNode.max+i].span; + i++; + numToCopy--; + } + + // Copy originals + for (localNode.start = 0; localNode.start < localNode.max; localNode.start++) { + _L2V_NODE_PUSH_CONTIG(right, nOfs, nodeSize, localNode.cu[localNode.start]); + l2v_assert_ne(localNode.cu[localNode.start].span, 0); + l2v_assert_le(localNode.cu[localNode.start].span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(right, nOfs, nodeSize); + + // And ripple up + return spanUp; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Valid.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Valid.h new file mode 100644 index 0000000..4e15c41 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/L2V_Valid.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_VALID_H__ +#define __L2V_VALID_H__ + + +#include "L2V_Defines.h" + +#if L2V_TRACK_VALID!=0 +// Implemented in the user of L2V +extern void Outside_L2V_ValidUp(UInt32 vba, UInt32 count); +extern void Outside_L2V_ValidDown(UInt32 vba, UInt32 count); +#else +#error L2V valid tracking must be on +#endif + + +#endif // __L2V_VALID_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMRFeatures-test.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMRFeatures-test.h new file mode 100644 index 0000000..74ec296 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMRFeatures-test.h @@ -0,0 +1 @@ +#define ENABLE_L2V_TREE (1) diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.c new file mode 100644 index 0000000..e5c0a7e --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "WMROAM.h" + + +void *WMR_MALLOC(UInt32 size) +{ + void * ptr = malloc(size); + if (ptr) + { + WMR_MEMSET(ptr, 0, size); + } + return ptr; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.h new file mode 100644 index 0000000..2638041 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/L2V/WMROAM-test.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __WMROAM_H__ +#define __WMROAM_H__ + +#include +#include +#include +#include +#include + +#define UInt32 uint32_t +#define Int32 int32_t +#define UInt16 uint16_t +#define Int16 int16_t +#define UInt8 uint8_t +#define Int8 int8_t +#define BOOL32 bool +#define TRUE32 true +#define FALSE32 false + +#define _WMR_ASSERT(e, file, line) { printf("%s:%u: failed assertion '%s'\nWaiting for debugger...\n", file, line, e); abort(); } +#define WMR_ASSERT(e) if (!(e)) _WMR_ASSERT(#e, __FILE__, __LINE__) +#define WMR_PANIC(format, args...) { printf(format , ##args); abort(); } +#define WMR_MEMSET(a, b, c) memset(a, b, c) +#define WMR_FREE(x, y) free(x) + +#define WMR_CASSERT(x, name) typedef char __WMR_CASSERT_##name[(x) ? 1 : -1] +#define WMR_OFFSETOF(type, field) ((size_t)(&((type *)0)->field)) + +#define WMR_LOG2(x) (31UL - __builtin_clz((UInt32)(x))) +#define WMR_MIN(x, y) (((x) < (y)) ? (x) : (y)) + +extern void *WMR_MALLOC(UInt32 size); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_TRACE_* +// +// Compile-time tracepoints (not supported) +// +#define WMR_TRACE_0(...) +#define WMR_TRACE_1(...) +#define WMR_TRACE_2(...) +#define WMR_TRACE_3(...) +#define WMR_TRACE_4(...) +#define WMR_TRACE_IST_0(...) +#define WMR_TRACE_IST_1(...) +#define WMR_TRACE_IST_2(...) +#define WMR_TRACE_IST_3(...) +#define WMR_TRACE_IST_4(...) + +#endif // __WMROAM_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/compare-valid.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/compare-valid.gdb new file mode 100644 index 0000000..9241e9a --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/compare-valid.gdb @@ -0,0 +1,15 @@ +set $idx = 0 +set $max = sftl.__geom.max_sb + +while ($idx < $max) + set $t = sftl.sb[$idx].type + if (3 == $t) + set $a = sftl.sb[$idx].validLbas + set $b = sftl.dbg.validSums[$idx] + if ($a != $b) + printf "%d: %d <-> %d; %2.5f\n", $idx, $a, $b, ((float)$a)/(float)$b + end + end + set $idx = $idx + 1 +end + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-bb.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-bb.gdb new file mode 100644 index 0000000..84065d7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-bb.gdb @@ -0,0 +1,29 @@ +set $sb = 0 +set $bank = 0 +set $sb_max = mcxt.dev.blocks_per_cau +set $bank_max = mcxt.dev.num_of_banks +set $good = 0 +set $bad = 0 + +while ($sb < $sb_max) + set $bank = 0 + set $base = mcxt.r_gen.bytes_per_vbn_bitmap * $sb + + while ($bank < $bank_max) + if (mcxt.v2p_bitmap[$base + ($bank >> 3)] & (1 << ($bank % 8))) + set $good = $good + 1 + else + set $bad = $bad + 1 + end + + set $bank = $bank + 1 + end + + set $sb = $sb + 1 +end + +printf "Good blocks: %d\n", $good +printf "Bad blocks: %d\n", $bad +printf "Total blocks: %d\n", ($good + $bad) +printf "Total FTL blocks: %d\n", (sftl.__geom.max_sb * sftl.__geom.num_banks) +printf "Bad block FTL percentage: %.3f\n", ((float)$bad * 100.0 / (sftl.__geom.max_sb * sftl.__geom.num_banks)) diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-sbs.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-sbs.gdb new file mode 100644 index 0000000..cd70e01 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/count-sbs.gdb @@ -0,0 +1,67 @@ +set $unknown = 0 +set $erased = 0 +set $pending = 0 +set $ebu = 0 +set $data = 0 +set $data_cur = 0 +set $data_gc = 0 +set $data_pending_gc = 0 +set $cxt = 0 +set $dead = 0 + +set $idx = 0 +set $max = sftl.__geom.max_sb +while ($idx < $max) + set $t = sftl.sb[$idx].type + if (1 == $t) + set $erased = $erased + 1 + else + if (2 == $t) + set $pending = $pending + 1 + else + if (3 == $t) + set $data = $data + 1 + else + if (4 == $t) + set $data_cur = $data_cur + 1 + else + if (5 == $t) + set $data_gc = $data_gc + 1 + else + if (6 == $t) + set $data_pending_gc = $data_pending_gc + 1 + else + if (7 == $t) + set $cxt = $cxt + 1 + else + if (8 == $t) + set $dead = $dead + 1 + else + if (9 == $t) + set $ebu = $ebu + 1 + else + printf "Unknown block type: sftl.sb[%d].type = %d\n", $idx, $t + set $unknown = $unknown + 1 + end + end + end + end + end + end + end + end + end + + set $idx = $idx + 1 +end + +printf "unknown: %d\n", $unknown +printf "erased: %d\n", $erased +printf "erase-before-use: %d\n", $ebu +printf "pending: %d\n", $pending +printf "data: %d\n", $data +printf "data_cur: %d\n", $data_cur +printf "data_gc: %d\n", $data_gc +printf "data_pending_gc: %d\n", $data_pending_gc +printf "cxt: %d\n", $cxt +printf "dead: %d\n", $dead diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/erases-histo.sh b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/erases-histo.sh new file mode 100644 index 0000000..b241253 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/erases-histo.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +sed 's/.*://g' | awk '{ print int($1/10)*10 }' | sort -n | uniq -c diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-0valid.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-0valid.gdb new file mode 100644 index 0000000..01cb939 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-0valid.gdb @@ -0,0 +1,12 @@ +set $idx = 0 +set $max = sftl.__geom.max_sb + +while ($idx < $max) + set $t = sftl.sb[$idx].type + set $v = sftl.sb[$idx].validLbas + if ((0 == $v) && (1 != $t)) + printf "[%d]: %d\n", $idx, $t + end + set $idx = $idx + 1 +end + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-high-reads.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-high-reads.gdb new file mode 100644 index 0000000..96546a8 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/find-high-reads.gdb @@ -0,0 +1,12 @@ +set $idx = 0 +set $max = sftl.__geom.max_sb +set $limit = 1000 + +while ($idx < $max) + set $r = sftl.sb[$idx].reads + if ($r >= $limit) + printf "[%d]: %d\n", $idx, $r + end + set $idx = $idx + 1 +end + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/free-space.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/free-space.gdb new file mode 100644 index 0000000..300e15c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/free-space.gdb @@ -0,0 +1 @@ +printf "Free space: %2.3f%s\n", (((float)sftl.max_lba - sftl.seaState.validLbas) * 100.0) / (float)sftl.max_lba, "%" diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/gc-zone-lbas.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/gc-zone-lbas.gdb new file mode 100644 index 0000000..79e5926 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/gc-zone-lbas.gdb @@ -0,0 +1,7 @@ +set $idx = 0 +set $max = sftl.gc.data.curZoneSize + +while ($idx < $max) + printf "%d: %d\n", $idx, sftl.gc.data.meta[$idx].__f1 + set $idx = $idx + 1 +end diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-erases.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-erases.gdb new file mode 100644 index 0000000..eeee44c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-erases.gdb @@ -0,0 +1,17 @@ +set logging redirect on +set logging overwrite on +set logging file ~/erases.txt +set logging on + +set $idx = 0 +set $max = sftl.__geom.max_sb + +while ($idx < $max) + set $t = sftl.sb[$idx].type + set $v = sftl.sb[$idx].erases + printf "%d:%d\n", $idx, $v + set $idx = $idx + 1 +end + +set logging off +printf "Saved to ~/erases.txt; please analyze\n" diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-userseq.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-userseq.gdb new file mode 100644 index 0000000..9706f8f --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-userseq.gdb @@ -0,0 +1,21 @@ +set logging redirect on +set logging overwrite on +set logging file ~/userSeq.txt +set logging on + +set $idx = 0 +set $max = sftl.__geom.max_sb + +while ($idx < $max) + set $t = sftl.sb[$idx].type + set $v = 0 + if (3 == $t) + set $v = sftl.sb[$idx].validLbas + printf "sb:%5d erases:%5d static:%d userSeq min:%9d max:%9d avg:%9d length:%5d\n", $idx, sftl.sb[$idx].erases, (sftl.sb[$idx].num_btoc_vbas_AND_staticFlag & 1), sftl.sb_userSeq[$idx].min, sftl.sb_userSeq[$idx].max, sftl.sb_userSeq[$idx].avg, sftl.sb_userSeq[$idx].count + + end + set $idx = $idx + 1 +end + +set logging off +printf "Saved to ~/userSeq.txt; please analyze\n" diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-valid.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-valid.gdb new file mode 100644 index 0000000..900667f --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/log-valid.gdb @@ -0,0 +1,38 @@ +set logging redirect on +set logging overwrite on +set logging file ~/valids.txt +set logging on + +set $idx = 0 +set $max = sftl.__geom.max_sb +set $vbas_per_sb = sftl.__geom.vbas_per_sb + +set $bank_max = mcxt.dev.num_of_banks + +while ($idx < $max) + set $bank = 0 + set $base = mcxt.r_gen.bytes_per_vbn_bitmap * $idx + + set $good = 0 + set $bad = 0 + while ($bank < $bank_max) + if (mcxt.v2p_bitmap[$base + ($bank >> 3)] & (1 << ($bank % 8))) + set $good = $good + 1 + else + set $bad = $bad + 1 + end + + set $bank = $bank + 1 + end + + set $t = sftl.sb[$idx].type + set $v = 0 + if (3 == $t) + set $v = sftl.sb[$idx].validLbas + end + printf "%d:%d/%d,%.2f\n", $idx, $v, ($vbas_per_sb * $good) / $bank_max, (100 * ((float)$v * $bank_max) / $good / $vbas_per_sb) + set $idx = $idx + 1 +end + +set logging off +printf "Saved to ~/valids.txt; please sort and graph\n" diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/min-valid.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/min-valid.gdb new file mode 100644 index 0000000..dfae804 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/min-valid.gdb @@ -0,0 +1,16 @@ +set $idx = 0 +set $max = sftl.__geom.max_sb +set $minv = 65535 + +while ($idx < $max) + set $t = sftl.sb[$idx].type + set $v = sftl.sb[$idx].validLbas + if (3 == $t) + if ($v < $minv) + set $minv = $v + end + end + set $idx = $idx + 1 +end + +printf "Min valid: %d/%d\n", $minv, sftl.__geom.vbas_per_sb diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/print-bb.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/print-bb.gdb new file mode 100644 index 0000000..1590bd9 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/print-bb.gdb @@ -0,0 +1,28 @@ +set $sb = 0 +set $bank = 0 +set $sb_max = mcxt.dev.blocks_per_cau +set $bank_max = mcxt.dev.num_of_banks + +while ($sb < $sb_max) + set $bank = 0 + set $base = mcxt.r_gen.bytes_per_vbn_bitmap * $sb + + printf "sb:0x%04x |", $sb + while ($bank < $bank_max) + if (mcxt.v2p_bitmap[$base + ($bank >> 3)] & (1 << ($bank % 8))) + if (mcxt.v2p_scrub_bitmap[$base + ($bank >> 3)] & (1 << ($bank % 8))) + printf "s" + else + printf " " + end + else + printf "x" + end + + set $bank = $bank + 1 + end + printf "|\n" + + set $sb = $sb + 1 +end + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/wamp.gdb b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/wamp.gdb new file mode 100644 index 0000000..44d4aa0 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/gdb/wamp.gdb @@ -0,0 +1,3 @@ +printf "wAmp: %.2f\n", ((float)mcxt.stat.ddwPagesWrittenCnt * sftl.__geom.vbas_per_page) / (float)sftl.stats.lbas_written +printf "flatten wAmp: %.2f\n", ((float)sftl.stats.lbas_written + sftl.stats.lbas_flatten) / (float)sftl.stats.lbas_written +printf "GC wAmp: %.2f\n", ((float)sftl.stats.lbas_written + sftl.stats.lbas_gc) / (float)sftl.stats.lbas_written diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.c new file mode 100644 index 0000000..98c8010 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define AND_TRACE_LAYER FTL + +#include "s_bg.h" +#include "s_gc.h" + +#ifndef AND_READONLY + +void s_bg_write(UInt32 writeSize) +{ + s_gc_bg(writeSize); +} + +void s_bg_read(UInt32 readSize) +{ + s_gc_bg(readSize); +} + +void s_bg_enq(UInt32 sb, BOOL32 scrubOnUECC) +{ + s_gc_data_enq(sb, S_GC_CTX_BG); +} + +#endif + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.h new file mode 100644 index 0000000..ad7ded7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_bg.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __S_BG_H__ +#define __S_BG_H__ + +#include "s_internal.h" + +#ifndef AND_READONLY + +// Called by Write +extern void s_bg_write(UInt32 writeSize); +extern void s_bg_read(UInt32 readSize); + +extern void s_bg_enq(UInt32 sb, BOOL32 scrubOnUECC); + +#endif // AND_READONLY + +#endif // #ifndef __S_BG_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.c new file mode 100644 index 0000000..3b87788 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_boot.h" +#include "s_cxt.h" +#include "s_sb.h" +#include "s_write.h" +#include "s_geom.h" +#include "s_gc.h" +#include "s_flatten.h" +#include "s_dbg.h" +#include "WhimoryBoot.h" + +Int32 sftl_boot(UInt32 *reported_lba, UInt32 *lba_size, BOOL32 fullRestore, BOOL32 justFmt, UInt32 minorVer, UInt32 opts) +{ +#ifndef AND_READONLY + UInt32 i, sb, t; +#endif // AND_READONLY + + const UInt32 readOnly = ( kWhimoryBootOptionReadOnly == ( kWhimoryBootOptionReadOnly & opts ) ? 1 : 0 ); + +#ifdef AND_SIMULATOR + if(opts & WMR_INIT_IGNORE_ERASE_GAP) + { + sftl.ignoreEraseGap = TRUE32; + } +#endif + + // Populate return fields + *reported_lba = sftl.reported_lba; + *lba_size = s_g_mul_bytes_per_lba(1); + + // Load cxt, scan, etc + if (!s_cxt_boot(readOnly)) { + return ANDErrorCodeHwErr; + } + + s_dbg_check_sb_dist(); + s_dbg_check_data_counts(); + + sftl.stats.boot_count++; + +#ifndef AND_READONLY + if (readOnly) { + // -- skip remaining block if r/w driver opened in RO mode. + return ANDErrorCodeOk; + } + + sftl.readDist.readsSince = S_READDIST_PERIOD; + sftl.wearLev.blocksSince = S_WEARLEV_PERIOD; + // Clear out stream state + for (i = 0; i < S_SBSTREAM_MAX; i++) { + sftl.write.stream[i].sb = 0xffffffff; + } + // Switch to dynamic stream + s_write_switch(S_SBSTREAM_DYN); + + s_dbg_check_sb_dist(); + s_dbg_check_data_counts(); + + // GC some PENDING_GC sb's, and erase all PENDING_ERASEs + for (sb = 0; sb < s_g_max_sb; sb++) { + t = s_sb_get_type(sb); + if (S_SB_DATA_PENDING_GC == t) { + // Flatten out some memory if necessary + while (!s_flatten()) { + // Program failure? + s_write_reseq(); + s_write_handle_pfail(); + } + t = s_sb_get_type(sb); + if (S_SB_DATA_PENDING_GC == t) { + // Double-check the sb type; could have changed via flatten + s_gc_data(sb, FALSE32); + s_dbg_check_data_counts(); + } + t = s_sb_get_type(sb); + } + // Erase PENDING_ERASES, whether from GC or scan (uECC/invalid PageType) + if (S_SB_PENDING_ERASE == t) { + s_sb_boot_free_erase(sb); + s_dbg_check_data_counts(); + } + + s_dbg_check_sb_dist(); + s_dbg_check_data_counts(); + } + sftl.readDist.readsSince = S_READDIST_PERIOD; + sftl.wearLev.blocksSince = S_WEARLEV_PERIOD; +#endif // AND_READONLY + + return ANDErrorCodeOk; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.h new file mode 100644 index 0000000..795c8ae --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_boot.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_BOOT_H__ +#define __S_BOOT_H__ + +#include "s_internal.h" + +extern Int32 sftl_boot(UInt32 *reported_lba, UInt32 *lba_size, BOOL32 fullRestore, BOOL32 justFmt, UInt32 minorVer, UInt32 opts); + +#endif // __S_BOOT_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.c new file mode 100644 index 0000000..0afc468 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.c @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_internal.h" +#include "s_btoc.h" +#include "s_sb.h" +#include "s_gc.h" +#include "s_geom.h" + +void btoc_calc_userSeq(s_btoc_entry_t *bte, UInt32 len, UInt32 sb) +{ + UInt32 curUser, userMin = 0xffffffff, userMax = 0; + UInt64 userSum = 0, lenAdjust = 0; + UInt32 i; + + // Calculate userSeq min/max/avg given a BTOC + for (i = 0; i < len; i++) { + curUser = bte[i].userWeaveSeq; + if (0xffffffff == curUser) { + lenAdjust++; + continue; + } + + if (curUser < userMin) { + userMin = curUser; + } + if (curUser > userMax) { + userMax = curUser; + } + userSum += curUser; + } + + len = (UInt32)(len - lenAdjust); + if (0 == len) { + len = 1; + } + if (0xffffffff == userMin) { + userMin = userMax; + } + + sftl.sb_userSeq[sb].min = userMin; + sftl.sb_userSeq[sb].max = userMax; + sftl.sb_userSeq[sb].avg = (UInt32)(userSum / len); + sftl.sb_userSeq[sb].count = len; +} + +BOOL32 s_btoc_init(void) +{ + UInt32 i, bpl, btb; + + // Calculate maximal BTOC size + bpl = sizeof(s_btoc_entry_t); + btb = ((s_g_vbas_per_sb * bpl) + s_g_bytes_per_page - 1); + sftl.__geom.max_pages_per_btoc = (btb / s_g_bytes_per_page) + 1; // One for leftovers + + sftl.BTOCcache.size = S_BTOCCACHE_SIZE; + WMR_ASSERT(sftl.BTOCcache.size <= 32); + sftl.BTOCcache.srcSize = S_BTOCCACHE_SRCSIZE; + sftl.BTOCcache.curSrc = sftl.BTOCcache.srcSize-1; + + sftl.BTOCcache.curAge = 0; + sftl.BTOCcache.age = WMR_MALLOC(sizeof(*sftl.BTOCcache.age) * sftl.BTOCcache.size); + sftl.BTOCcache.sb = WMR_MALLOC(sizeof(*sftl.BTOCcache.sb) * sftl.BTOCcache.size); + sftl.BTOCcache.BTOC = WMR_MALLOC(sizeof(*sftl.BTOCcache.BTOC) * sftl.BTOCcache.size); + sftl.BTOCcache.srcVpn = WMR_MALLOC(sizeof(*sftl.BTOCcache.srcVpn) * sftl.BTOCcache.srcSize); + sftl.BTOCcache.srcSb = WMR_MALLOC(sizeof(*sftl.BTOCcache.srcSb) * sftl.BTOCcache.srcSize); + + // Check for allocation failure + if ((NULL == sftl.BTOCcache.age) || (NULL == sftl.BTOCcache.sb) || (NULL == sftl.BTOCcache.BTOC) + || (NULL == sftl.BTOCcache.srcVpn) || (NULL == sftl.BTOCcache.srcSb)) + { + return FALSE32; + } + + for (i = 0; i < sftl.BTOCcache.size; i++) + { + sftl.BTOCcache.sb[i] = 0xffffffff; + } + + for (i = 0; i < sftl.BTOCcache.srcSize; i++) + { + sftl.BTOCcache.srcSb[i] = 0xffffffff; + sftl.BTOCcache.srcVpn[i] = WMR_MALLOC(sizeof(**sftl.BTOCcache.srcVpn) * s_g_vbas_per_sb); + WMR_MEMSET(sftl.BTOCcache.srcVpn[i], 0xff, sizeof(**sftl.BTOCcache.srcVpn) * s_g_vbas_per_sb); + } + + sftl.BTOCcache.free = (1 << sftl.BTOCcache.size) - 1; + + // Allocate buffers + WMR_BufZone_Init(&sftl.BTOCcache.BufZone); + + for (i = 0; i < sftl.BTOCcache.size; i++) + { + sftl.BTOCcache.BTOC[i] = (s_btoc_entry_t*)WMR_Buf_Alloc_ForDMA(&sftl.BTOCcache.BufZone, s_g_max_pages_per_btoc * s_g_bytes_per_page); + } + sftl.BTOCcache.meta = WMR_Buf_Alloc_ForDMA(&sftl.BTOCcache.BufZone, WMR_MAX(S_BTOC_META_SIZE, s_g_max_pages_per_btoc * s_g_vbas_per_page) * s_g_bytes_per_lba_meta); + + if (!WMR_BufZone_FinishedAllocs(&sftl.BTOCcache.BufZone)) { + return FALSE32; + } + + for (i = 0; i < sftl.BTOCcache.size; i++) + { + WMR_BufZone_Rebase(&sftl.BTOCcache.BufZone, (void**)&sftl.BTOCcache.BTOC[i]); + } + WMR_BufZone_Rebase(&sftl.BTOCcache.BufZone, (void**)&sftl.BTOCcache.meta); + + WMR_BufZone_FinishedRebases(&sftl.BTOCcache.BufZone); + + return TRUE32; +} + +void s_btoc_close() +{ + UInt32 i; + + WMR_BufZone_Free(&sftl.BTOCcache.BufZone); + + if (NULL != sftl.BTOCcache.age) + { + WMR_FREE(sftl.BTOCcache.age, sizeof(*sftl.BTOCcache.age) * sftl.BTOCcache.size); + } + if (NULL != sftl.BTOCcache.sb) + { + WMR_FREE(sftl.BTOCcache.sb, sizeof(*sftl.BTOCcache.sb) * sftl.BTOCcache.size); + } + if (NULL != sftl.BTOCcache.BTOC) + { + WMR_FREE(sftl.BTOCcache.BTOC, sizeof(*sftl.BTOCcache.BTOC) * sftl.BTOCcache.size); + } + + // Free srcVpn memory + if (NULL != sftl.BTOCcache.srcSb) + { + WMR_FREE(sftl.BTOCcache.srcSb, sizeof(*sftl.BTOCcache.srcSb) * sftl.BTOCcache.srcSize); + } + for (i = 0; i < sftl.BTOCcache.srcSize; i++) + { + WMR_FREE(sftl.BTOCcache.srcVpn[i], sizeof(**sftl.BTOCcache.srcVpn) * s_g_vbas_per_sb); + } + WMR_FREE(sftl.BTOCcache.srcVpn, sizeof(*sftl.BTOCcache.srcVpn) * sftl.BTOCcache.srcSize); + + sftl.BTOCcache.age = NULL; + sftl.BTOCcache.sb = NULL; + sftl.BTOCcache.BTOC = NULL; + sftl.BTOCcache.srcSb = NULL; + sftl.BTOCcache.srcVpn = NULL; + + sftl.BTOCcache.size = 0; + + sftl.BTOCcache.srcSize = 0; +} + +#ifndef AND_READONLY + +BOOL32 s_btoc_isFull(void) +{ + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + + WMR_ASSERT((wr->nextVbaOfs + wr->BTOC_vba) <= wr->maxVbaOfs); + return ((wr->nextVbaOfs + wr->BTOC_vba) == wr->maxVbaOfs); +} + +UInt32 s_btoc_update_size(Int32 remaining) +{ + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + UInt32 maxSize, vba; + + maxSize = wr->maxVbaOfs - wr->nextVbaOfs; + + // Recalculate number of BTOC VBAs + do { + vba = (((wr->BTOCidx+1+remaining) * sizeof(s_btoc_entry_t)) + s_g_bytes_per_page - 1); + vba = s_g_div_bytes_per_page(vba); + vba = s_g_mul_vbas_per_page(vba); + remaining--; + WMR_ASSERT(remaining >= -1); + } while (vba > maxSize); + + wr->BTOC_vba = vba; + + return remaining+1; +} + +void s_btoc_add_data(UInt32 vba, UInt32 lba, UInt32 count, WeaveSeq_t weaveSeq, UInt32 userWeaveSeq) +{ + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + s_btoc_entry_t *last_bte, *bte; + UInt32 lastCount; + + if (0 == wr->BTOCidx) { + // First entry? Set up minWeaveSeq + wr->minWeaveSeq = weaveSeq; + } + + // RLE-compress + if (wr->BTOCidx > 0) { + last_bte = &wr->BTOC[wr->BTOCidx-1]; + lastCount = last_bte->count; + if ((lba < S_TOKEN_LBA_BASE) + && (lba == (last_bte->lba + lastCount)) + && (wr->minWeaveSeq + last_bte->weaveSeqAdd + lastCount) == weaveSeq) + { + // Perfectly sequential; not token lba; no gaps in lba, vba (implied), or weaveSeq? + last_bte->count += count; + goto commonExit; + } + } + + WMR_ASSERT(wr->BTOCidx <= s_g_vbas_per_sb); + bte = &wr->BTOC[wr->BTOCidx]; + bte->lba = lba; + bte->count = count; + bte->weaveSeqAdd = (UInt32)(weaveSeq - wr->minWeaveSeq); + WMR_ASSERT(bte->weaveSeqAdd < S_WEAVE_SEQ_ADD_TRS); + bte->userWeaveSeq = userWeaveSeq; + wr->BTOCidx++; + +commonExit: + WMR_ASSERT(vba == s_g_addr_to_vba(wr->sb, wr->nextVbaOfs)); + wr->nextVbaOfs += count; +} + +BOOL32 s_btoc_cross_data(void) +{ + ANDStatus status; + UInt32 num_vba, vba; + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + + // Terminate btoc + WMR_ASSERT(0 != wr->BTOCidx); + wr->BTOC[wr->BTOCidx].count = 0; + num_vba = wr->maxVbaOfs - wr->nextVbaOfs; // write all of the pages + + // Calculate userSeq values + btoc_calc_userSeq(wr->BTOC, wr->BTOCidx, wr->sb); + + // Write BTOC + vba = s_g_addr_to_vba(wr->sb, sftl.vfl->GetVbasPerVb(wr->sb) - num_vba); + s_SetupMeta_Data_BTOC(sftl.BTOCcache.meta, wr->minWeaveSeq, num_vba, wr->pageFlags); + status = sftl.vfl->ProgramMultipleVbas(vba, num_vba, (UInt8*)wr->BTOC, (UInt8*)sftl.BTOCcache.meta, TRUE32, FALSE32); + if (!status) { + s_sb_clr_num_btoc_vbas(wr->sb); + WMR_PRINT(QUAL, "sftl: program failure writing BTOC sb:%d vba:0x%x\n", wr->sb, vba); + // Handled by caller + return FALSE32; + } + s_sb_set_num_btoc_vbas(wr->sb, num_vba); + + // Get next sb--find best, reallocate btoc + s_sb_next_cur(); + + return TRUE32; +} + +#endif // AND_READONLY + +void s_btoc_copy(s_btoc_entry_t *dest, s_btoc_entry_t *src, UInt32 *len) +{ + *len = (UInt32)(-1); + do { + *dest = *src; + if ((dest->lba > sftl.max_lba) && (dest->lba < S_TOKEN_LBA_BASE)) { + if (WMR_I_CAN_HAZ_DEBUGGER()) { + WMR_PANIC("BTOC stomping lba:%d to S_TOK_UECC\n", dest->lba); + } else { + WMR_PRINT(ALWAYS, "BTOC stomping lba:%d to S_TOK_UECC\n", dest->lba); + } + dest->lba = S_TOK_UECC; + } + (*len)++; + dest++; + src++; + WMR_ASSERT((s_g_max_pages_per_btoc * s_g_bytes_per_page / sizeof(s_btoc_entry_t)) > *len); + } while (0 != (src-1)->count); +} + +void s_btoc_read_cb(UInt32 vba, VFLReadStatusType status, UInt8 *__meta) +{ + PageMeta_Data_t *meta = (PageMeta_Data_t*)__meta; + + if (status & VFL_READ_STATUS_UNIDENTIFIED) { + WMR_PRINT(QUAL_FATAL, "BTOC read got unidentified read status (0x%x) on vba:0x%x; did we get a timeout? Pretending it was uECC.\n", status, vba); + status = (status & ~VFL_READ_STATUS_UNIDENTIFIED) | VFL_READ_STATUS_UECC; + } + + if (status & VFL_READ_STATUS_CLEAN) { + META_SET_LBA(meta, S_TOK_ERASED); + } else if (status & VFL_READ_STATUS_UECC) { + WMR_PRINT(ALWAYS, "S_TOK_UECC vba:0x%x status:0x%x\n", vba, status); + META_SET_LBA(meta, S_TOK_UECC); + } +} + +BOOL32 s_btoc_read(UInt32 sb, s_btoc_entry_t *btoc, UInt32 *len, BOOL32 stopEarly, BOOL32 scrubOnUECC) +{ + // Return value: FALSE32 == had to reconstruct + UInt32 vba, num_vba; + VFLReadStatusType status; + UInt32 count, thisCount, curLba, curCnt, lba, i; + UInt32 innerCnt, innerOfs, innerThis, thisErased; + WeaveSeq_t baseWeave = 0, curWeave = 0; + BOOL32 baseWeaveSet, isData; + s_btoc_entry_t *bte; +#ifndef AND_READONLY + s_btoc_entry_t *ramBTOC; +#endif // AND_READONLY + VFL_ReadSpans_t *const rs = &sftl.BTOCcache.rs; + BOOL32 ret = TRUE32; + + *len = 0; + +#ifndef AND_READONLY + // Is it in memory? + ramBTOC = s_btoc_search(sb); + if (NULL != ramBTOC) { + s_btoc_copy(btoc, ramBTOC, len); + goto readExit; + } +#endif // AND_READONLY + + num_vba = s_sb_get_num_btoc_vbas(sb); + if (0 != num_vba) { + vba = s_g_addr_to_vba(sb, sftl.vfl->GetVbasPerVb(sb) - num_vba); + sftl.vfl->ReadSpansInit(rs, NULL, 0, FALSE32, scrubOnUECC); + sftl.vfl->ReadSpansAdd(rs, vba, num_vba, (UInt8*)btoc, (UInt8*)sftl.BTOCcache.meta); + status = sftl.vfl->ReadSpans(rs); + if (!(status & (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN))) { + if (!META_IS_BTOC_DATA(sftl.BTOCcache.meta)) { + WMR_PRINT(ALWAYS, "Error: BTOC not valid"); + goto scanIt; + } + + WMR_ASSERT(0 == btoc->weaveSeqAdd); + bte = btoc; + while (0 != bte->count) { + (*len)++; + bte++; + } + + goto readExit; + } + } + +scanIt: + // If we had to scan, either because we had none or it was uECC, + // clear out the number of VBAs so it gets erased at shutdown. + s_sb_set_num_btoc_vbas_0ok(sb, 0); + + // Scan + count = sftl.vfl->GetVbasPerVb(sb); + vba = s_g_addr_to_vba(sb, 0); + curLba = (UInt32)(-1); + curCnt = 0; + baseWeaveSet = FALSE32; + bte = btoc; + + while (count) { + thisCount = WMR_MIN(count, S_SCAN_META_SIZE); + sftl.vfl->ReadSpansInit(rs, s_btoc_read_cb, (VFL_READ_STATUS_UECC|VFL_READ_STATUS_CLEAN), FALSE32, scrubOnUECC); + + // Set up reads + innerCnt = thisCount; + innerOfs = 0; + while (innerCnt) { + innerThis = WMR_MIN(innerCnt, sftl.gc.zoneSize); + sftl.vfl->ReadSpansAdd(rs, vba+innerOfs, innerThis, sftl.gc.zone, (UInt8*)&sftl.scan_meta[innerOfs]); + innerOfs += innerThis; + innerCnt -= innerThis; + }; + sftl.vfl->ReadSpans(rs); + if (!baseWeaveSet) { + baseWeave = META_GET_WEAVESEQ(&sftl.scan_meta[0]); + baseWeaveSet = TRUE32; + } + + thisErased = 0; + for (i = 0; i < thisCount; i++) { + lba = META_GET_LBA(&sftl.scan_meta[i]); + isData = META_IS_DATA(&sftl.scan_meta[i]); + // Ignore LBAs past drive capacity that aren't token values + if (((lba >= sftl.max_lba) && (lba < S_TOKEN_LBA_BASE)) || (!isData && (S_TOK_ERASED != lba))) { + lba = S_TOK_UECC; + } + // Count erased content + if (S_TOK_ERASED == lba) { + thisErased++; + } + + // Throw into BTOC if end, beginning, or not sequential, or weaveSeq gap + if (((count - i) == 1) + || !curCnt + || ((curLba < S_TOKEN_LBA_BASE) && ((curLba + curCnt) != lba)) + || ((curLba >= S_TOKEN_LBA_BASE) && (curLba != lba)) + || (((curWeave + curCnt) != META_GET_WEAVESEQ(&sftl.scan_meta[i])) && + (curLba != S_TOK_ERASED)) + || (S_TOK_UECC == curLba)) + { + if (curCnt) { + bte->lba = curLba; + bte->count = curCnt; + if ((S_TOK_ERASED == curLba) || (S_TOK_UECC == curLba)) { + bte->weaveSeqAdd = 0; + } else { + bte->weaveSeqAdd = (UInt32)(curWeave - baseWeave); + } + bte->userWeaveSeq = META_GET_USERSEQ(&sftl.scan_meta[i]); + bte++; + (*len)++; + } + curLba = lba; + curCnt = 1; + curWeave = META_GET_WEAVESEQ(&sftl.scan_meta[i]); + } else { + // RLE-compress + curCnt++; + } + } + + if (stopEarly && (S_BTOC_META_SIZE == thisErased)) { + // Stop early, we've seen enough erased content + break; + } + + // Next + vba += thisCount; + count -= thisCount; + } + + // Null-terminate + bte->count = 0; + ret = FALSE32; + +readExit: + // Calculate user seq stats + btoc_calc_userSeq(btoc, *len, sb); + + return ret; +} + +s_btoc_entry_t *s_btoc_alloc(UInt32 sb) +{ + UInt32 i, minIdx; + Int32 minAge; + + // Get a srcVpn + sftl.BTOCcache.curSrc = (sftl.BTOCcache.curSrc + 1) % sftl.BTOCcache.srcSize; + sftl.BTOCcache.srcSb[sftl.BTOCcache.curSrc] = sb; + WMR_MEMSET(sftl.BTOCcache.srcVpn[sftl.BTOCcache.curSrc], 0xff, sizeof(**sftl.BTOCcache.srcVpn) * s_g_vbas_per_sb); + + // Get a BTOC + sftl.BTOCcache.curAge++; + + minAge = 0x7fffffff; + minIdx = 0xffffffff; + + for (i = 0; i < sftl.BTOCcache.size; i++) + { + if ((sftl.BTOCcache.free & (1 << i)) + && (sftl.BTOCcache.age[i] < minAge)) + { + minAge = sftl.BTOCcache.age[i]; + minIdx = i; + } + } + + if (0xffffffff != minIdx) { + sftl.BTOCcache.free &= ~(1 << minIdx); + sftl.BTOCcache.sb[minIdx] = sb; + sftl.BTOCcache.age[minIdx] = sftl.BTOCcache.curAge; + WMR_MEMSET(sftl.BTOCcache.BTOC[minIdx], 0, s_g_max_pages_per_btoc * s_g_bytes_per_page); + return sftl.BTOCcache.BTOC[minIdx]; + } + + WMR_PANIC("Couldn't allocate a BTOC"); + return NULL; +} + +#ifndef AND_READONLY +UInt32 s_btoc_getSrc(UInt32 dest_vba) +{ + UInt32 i, sb, vbaOfs; + + sb = s_g_vba_to_sb(dest_vba); + vbaOfs = s_g_vba_to_vbaOfs(dest_vba); + + for (i = 0; i < sftl.BTOCcache.srcSize; i++) + { + if (sb == sftl.BTOCcache.srcSb[i]) { + return sftl.BTOCcache.srcVpn[i][vbaOfs]; + } + } + + return 0xffffffff; +} +#endif // AND_READONLY + +#ifndef AND_READONLY +void s_btoc_setSrc(UInt32 dest_vba, UInt32 src_vba) +{ + UInt32 i, sb, vbaOfs; + + sb = s_g_vba_to_sb(dest_vba); + vbaOfs = s_g_vba_to_vbaOfs(dest_vba); + + for (i = 0; i < sftl.BTOCcache.srcSize; i++) + { + if (sb == sftl.BTOCcache.srcSb[i]) { + sftl.BTOCcache.srcVpn[i][vbaOfs] = src_vba; + } + } +} +#endif // AND_READONLY + +void s_btoc_dealloc(s_btoc_entry_t *BTOC) +{ + UInt32 i; + + for (i = 0; i < sftl.BTOCcache.size; i++) + { + if (BTOC == sftl.BTOCcache.BTOC[i]) + { + sftl.BTOCcache.free |= (1 << i); + return; + } + } + + WMR_PANIC("Couldn't deallocate BTOC: %p", BTOC); +} + +#ifndef AND_READONLY +s_btoc_entry_t *s_btoc_search(UInt32 sb) +{ + UInt32 i; + Int32 maxAge = -1; + s_btoc_entry_t *best = NULL; + + for (i = 0; i < sftl.BTOCcache.size; i++) + { + if ((sftl.BTOCcache.sb[i] == sb) && (sftl.BTOCcache.age[i] > maxAge)) + { + maxAge = sftl.BTOCcache.age[i]; + best = sftl.BTOCcache.BTOC[i]; + } + } + + return best; +} +#endif // AND_READONLY + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.h new file mode 100644 index 0000000..f7877e6 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_btoc.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_BTOC_H__ +#define __S_BTOC_H__ + +#include "s_internal.h" + + +extern BOOL32 s_btoc_init(void); +extern void s_btoc_close(void); + +#ifndef AND_READONLY +// Write flow: +extern BOOL32 s_btoc_isFull(void); +extern UInt32 s_btoc_update_size(Int32 remaining); +extern void s_btoc_add_data(UInt32 vba, UInt32 lba, UInt32 count, WeaveSeq_t weaveSeq, UInt32 userWeaveSeq); +extern BOOL32 s_btoc_cross_data(void); +#endif // AND_READONLY + +// Read flow: +extern BOOL32 s_btoc_read(UInt32 sb, s_btoc_entry_t *btoc, UInt32 *len, BOOL32 stopEarly, BOOL32 scrubOnUECC); // return: BTOC good=true + +// BTOC cache: +extern s_btoc_entry_t *s_btoc_alloc(UInt32 sb); +extern void s_btoc_dealloc(s_btoc_entry_t *BTOC); + +#ifndef AND_READONLY +extern UInt32 s_btoc_getSrc(UInt32 destVpn); +extern void s_btoc_setSrc(UInt32 destVpn, UInt32 srcVpn); +extern s_btoc_entry_t *s_btoc_search(UInt32 sb); +#else // AND_READONLY +#define s_btoc_getSrc(x) +#define s_btoc_setSrc(x) +#define s_btoc_search(x) +#endif // AND_READONLY + +#endif // __S_BTOC_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.c new file mode 100644 index 0000000..433d3ea --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_cxt.h" +#include "s_cxt_diff.h" +#include "s_cxt_load.h" +#include "s_cxt_save.h" +#include "s_dbg.h" +#include "s_stats.h" +#include "s_geom.h" +#include "s_sb.h" +#include "s_write.h" + +// external function: + +void s_cxt_init(void) +{ + UInt32 sbarrSize, treeSize, bytesPerSb; + + // Calculate cxt size + sbarrSize = sizeof(sftl.sb[0]) * s_g_max_sb; + treeSize = L2V_NODEPOOL_MEM * 2; + bytesPerSb = s_g_mul_bytes_per_lba(s_g_vbas_per_sb); + sftl.cxt.cxt_vbas = (((sbarrSize + treeSize + bytesPerSb - 1) / s_g_bytes_per_page) * s_g_vbas_per_page); + sftl.cxt.cxt_sbs = (sftl.cxt.cxt_vbas + s_g_vbas_per_sb - 1) / s_g_vbas_per_sb; +} + +BOOL32 s_cxt_boot(const UInt32 readOnly) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt64 Tstart, Tfin; + BOOL32 enumerate; + s_sb_fmt_t *shadowSB = NULL; + BOOL32 uncleanShutDownRecovery; + + // Set up cxt variables + cxt->load.baseWeaveSeq = 0; + cxt->load.bases = 0; + + // Init weave order, allocate memory + if (!s_wo_init()) { + return FALSE32; + } + + // Scan all superblocks, make in-order age range list + WMR_PRINT(FTL, "scanning for weaves and types...\n"); + Tstart = WMR_CLOCK_TICKS(); + s_scan_all_sb(); + Tfin = WMR_CLOCK_TICKS(); + WMR_PRINT(FTL, "[%dms]\n", (Tfin-Tstart) / WMR_GET_TICKS_PER_US() / 1000); + + // Load cxt + WMR_PRINT(FTL, "loading cxt...\n"); + Tstart = WMR_CLOCK_TICKS(); + shadowSB = WMR_MALLOC(sizeof(s_sb_fmt_t) * s_g_max_sb); + enumerate = s_cxt_load(FALSE32, shadowSB); + Tfin = WMR_CLOCK_TICKS(); + WMR_PRINT(FTL, "[%dms]\n", (Tfin-Tstart) / WMR_GET_TICKS_PER_US() / 1000); + if (!enumerate) { + goto skipDiffStats; + } + + // And scan data written since the cxt + WMR_PRINT(FTL, "adopting diffs...\n"); + Tstart = WMR_CLOCK_TICKS(); + s_cxt_scan_diff(); + Tfin = WMR_CLOCK_TICKS(); + WMR_PRINT(FTL, "[%dms]\n", (Tfin-Tstart) / WMR_GET_TICKS_PER_US() / 1000); + + // New data must be newer than cxt + WMR_ASSERT(sftl.write.weaveSeq >= cxt->load.baseWeaveSeq); + + // Load AND statistics + s_cxt_stats_load(); + if (cxt->diff.updates) { + sftl.stats.unclean_boot_count++; + uncleanShutDownRecovery = TRUE32; + WMR_PRINT(ALWAYS, "sftl: error, unclean shutdown; adopted %d spans\n", cxt->diff.updates); + } + else + { + uncleanShutDownRecovery = FALSE32; + } + + if((uncleanShutDownRecovery == FALSE32) && (shadowSB != NULL)) + { + UInt16 sb; + for (sb = 0; sb < s_g_max_sb; sb++) + { + if((shadowSB[sb].type == S_SB_ERASED) && (s_sb_get_type(sb) == S_SB_ERASE_BEFORE_USE)) + { + s_sb_set_type(sb, S_SB_ERASED); + sftl.seaState.erased_sb++; + } + } + } + +skipDiffStats: + // Free temporary memory + if(shadowSB != NULL) + { + WMR_FREE(shadowSB, sizeof(s_sb_fmt_t) * s_g_max_sb); + } + s_wo_close(); + +#ifndef AND_READONLY + // Mark all 0-valid data SBs as pending erase + s_sb_sweep0(); +#endif + + sftl.booted = 1; + s_dbg_check_sb_dist(); + s_dbg_check_validSums(); + s_dbg_check_data_counts(); + + return TRUE32; +} + +#ifndef AND_READONLY +void s_cxt_periodic(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + + if (cxt->periodic.sbsSince >= S_CXT_PERIOD_SBS) { + s_cxt_save(); + cxt->periodic.sbsSince = 0; + cxt->periodic.sbsSinceStats = 0; + } else if (cxt->periodic.sbsSinceStats >= S_STATS_PERIOD_SBS) { + s_stats_insert(); + s_write_push_full_buf(TRUE32); + cxt->periodic.sbsSinceStats = 0; + } +} +#endif // AND_READONLY + +void s_cxt_addSb(UInt32 sb, WeaveSeq_t weaveSeq) +{ + s_cxt_t *const cxt = &sftl.cxt; + Int32 pos; + + WMR_ASSERT(cxt->load.bases < S_CXT_MAX_SB); + + // Insert in decerasing order to sftl.load.baseSb, baseWeaves, bases: + + // Find position and slip + pos = cxt->load.bases; + while ((pos > 0) && (weaveSeq > cxt->load.baseWeaves[pos-1])) { + cxt->load.baseSb[pos] = cxt->load.baseSb[pos-1]; + cxt->load.baseWeaves[pos] = cxt->load.baseWeaves[pos-1]; + pos--; + } + + // Insert + cxt->load.baseSb[pos] = sb; + cxt->load.baseWeaves[pos] = weaveSeq; + cxt->load.bases++; +} diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.h new file mode 100644 index 0000000..9a6d778 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_CXT_H__ +#define __S_CXT_H__ + +#include "s_internal.h" + +// Cxt contains: +// - L2V tree +// - block state and valid counts +// - tl stats + +#define s_cxt_is_firstSb(_m, _sb, _vbaOfs) ((PAGETYPE_FTL_CXT == (_m)->c.PageType) && (0 == (_vbaOfs)) && (S_CXTTAG_BASE == META_GET_CXT_TAG(_m))) + +extern void s_cxt_addSb(UInt32 sb, WeaveSeq_t weaveSeq); + +extern void s_cxt_init(void); +extern BOOL32 s_cxt_boot(const UInt32 readOnly); + +#ifndef AND_READONLY +extern void s_cxt_periodic(void); +extern void s_cxt_save(void); +#else // -> !AND_READONLY +#define s_cxt_periodic() +#define s_cxt_save() +#endif // !AND_READONLY + +#endif // __S_CXT_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.c new file mode 100644 index 0000000..45e36d7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_cxt.h" +#include "s_btoc.h" +#include "s_geom.h" +#include "s_sb.h" +#include "s_dbg.h" + +// functions: +static void data_weaveseq_add(UInt32 sb, PageMeta_BTOC_t *meta); +static void wo_append(UInt32 sb, WeaveSeq_t minWeaveSeq, WeaveSeq_t maxWeaveSeq); +static void wo_sort(void); +static void clean_add(UInt32 sb, BOOL32 force); + +void s_diff_sbFilter_add(UInt32 sb) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + UInt32 idx, bit; + + WMR_ASSERT(NULL != diff->sbFilter); + WMR_ASSERT(sb < s_g_max_sb); + + idx = sb / 32; + bit = sb & 31; + + diff->sbFilter[idx] |= (1 << bit); +} + +BOOL32 s_diff_sbFilter_has(UInt32 sb) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + UInt32 idx, bit; + + WMR_ASSERT(NULL != diff->sbFilter); + WMR_ASSERT(sb < s_g_max_sb); + + idx = sb / 32; + bit = sb & 31; + + return (diff->sbFilter[idx] >> bit) & 1; +} + +void s_diff_filterPost(WeaveSeq_t weave) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + UInt32 idx; + + for (idx = 0; idx < diff->size; idx++) { + if (diff->item[idx].minWeaveSeq > weave) { + s_diff_sbFilter_add(diff->item[idx].sb); + } + } +} + +static void wo_seed(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + s_cxt_diff_t *const diff = &sftl.cxt.diff; + UInt32 seed_max, num; + BOOL32 no_gc; + + diff->idx = 0; + seed_max = WMR_MIN(S_SBSTREAM_PHY_MAX, WMR_MIN(sftl.BTOCcache.size, diff->size - diff->idx)); + + for (num = 0; (num < seed_max) && (diff->idx < diff->size); diff->idx++) { + // Skip sbs wholly older than cxt + if ((diff->item[diff->idx].maxWeaveSeq < cxt->load.baseWeaveSeq) && (diff->idx < diff->size)) { + continue; + } + + diff->itemIdx[num] = diff->idx; + diff->btoc[num] = s_btoc_alloc(0xffffffff); + no_gc = s_btoc_read(diff->item[diff->idx].sb, diff->btoc[num], &diff->btoc_len[num], TRUE32, FALSE32); + if (!no_gc) { + s_sb_set_type(diff->item[diff->idx].sb, S_SB_DATA_PENDING_GC); + } + diff->vba[num] = s_g_addr_to_vba(diff->item[diff->idx].sb, 0); + diff->bte[num] = diff->btoc[num]; + diff->weave[num] = diff->item[diff->idx].minWeaveSeq; + num++; + } +} + +static void wo_unseed(void) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + UInt32 i; + + for (i = 0; i < S_SBSTREAM_PHY_MAX; i++) { + if (NULL != diff->btoc[i]) { + s_btoc_dealloc(diff->btoc[i]); + } + } +} + +static UInt32 find_min(void) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + UInt32 i, which; + WeaveSeq_t weave, minWeave; + + minWeave = (WeaveSeq_t)(~0L); + which = ~0; + + for (i = 0; i < S_SBSTREAM_PHY_MAX; i++) { + if (0 == diff->btoc_len[i]) + continue; + + weave = diff->weave[i] + diff->bte[i]->weaveSeqAdd; + if (weave < minWeave) { + minWeave = weave; + which = i; + } + } + + return which; +} + +static void load_trims(UInt32 vba) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt8 *buf = sftl.tmpBuf; + PageMeta_Data_t *meta = (PageMeta_Data_t*)sftl.boot.meta; + UInt32 *trims = (UInt32*)sftl.tmpBuf; + UInt32 num, lba, count; + + sftl.vfl->ReadSpansInit(&cxt->load.rs, NULL, 0, TRUE32, FALSE32); + + sftl.vfl->ReadSpansAdd(&cxt->load.rs, vba, 1, buf, (UInt8*)meta); + if ((sftl.vfl->ReadSpans(&cxt->load.rs)) & (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN)) { + return; + } + + num = *trims++; + while (num--) { + lba = *trims++; + count = *trims++; + L2V_Update(lba, count, L2V_VBA_DEALLOC); + } +} + +void s_cxt_scan_diff(void) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + s_cxt_t *const cxt = &sftl.cxt; + BOOL32 no_gc, skipping; + UInt32 i, which, lba, vba, count; +#ifndef AND_READONLY + UInt32 lastCount = 0; +#endif // AND_READONLY + WeaveSeq_t weaveSeq, lastWeave = 0; + + // Seed it + wo_seed(); + diff->updates = 0; + count = 0; + + skipping = FALSE32; + while (1) { + // Find next piece to weave + which = find_min(); + if ((UInt32)~0 == which) { + for (i = 0; i < S_SBSTREAM_PHY_MAX; i++) { + WMR_ASSERT(0 == diff->btoc_len[i]); + } + break; + } + + // Iterate along mappings + lba = diff->bte[which]->lba; + count = diff->bte[which]->count; + weaveSeq = diff->weave[which] + diff->bte[which]->weaveSeqAdd; + vba = diff->vba[which]; +#ifndef AND_READONLY + if ((lba < S_TOKEN_LBA_BASE) && (weaveSeq < lastWeave)) { + if (WMR_I_CAN_HAZ_DEBUGGER()) { + // Panic on debuggable units + WMR_PANIC("weaveSeq non-monotonic! lba:%d count:%d vba:0x%x weaveSeq:0x%llx lastWeave:0x%llx lastCount:%d which:%d", lba, count, vba, weaveSeq, lastWeave, lastCount, which); + } else { + if (0 == s_sb_get_num_btoc_vbas(s_g_vba_to_sb(vba))) { + // Misordering in sb's without BTOCs are more likely to be the result of NAND errors + WMR_PRINT(ERROR, "weaveSeq non-monotonic, treating as media error! lba:%d count:%d vba:0x%x weaveSeq:0x%llx lastWeave:0x%llx lastCount:%d which:%d\n", lba, count, vba, weaveSeq, lastWeave, lastCount, which); + lba = S_TOK_UECC; + } else { + // Whereas in sb's with BTOCs, a software bug is more likely + WMR_PRINT(ERROR, "weaveSeq non-monotonic, ignoring the fact... lba:%d count:%d vba:0x%x weaveSeq:0x%llx lastWeave:0x%llx lastCount:%d which:%d\n", lba, count, vba, weaveSeq, lastWeave, lastCount, which); + } + } + } + if (weaveSeq >= diff->item[diff->itemIdx[which]].maxWeaveSeq) { + WMR_PANIC("weaveSeq exceeds block maximum! lba:%d count:%d vba:0x%x weaveSeq:0x%llx maxWeaveSeq:0x%llx which:%d\n", lba, count, vba, weaveSeq, diff->item[diff->itemIdx[which]].maxWeaveSeq, which); + } +#endif // AND_READONLY + + if (weaveSeq > cxt->load.baseWeaveSeq) { + if (lba < S_TOKEN_LBA_BASE) { + if (!skipping) { + L2V_Update(lba, count, vba); + diff->updates++; + if (S_LBA_STATS == lba) { + cxt->load.sawStats_lba = 1; + } + } + } else if (S_TOK_PAD == lba) { + // Ignore + } else if (S_TOK_DELETE == lba) { + if (!skipping) { + load_trims(vba); + } + } else if (S_TOK_ERASED == lba) { + // Ignore erased spans [comes from BTOC read-scan] + s_sb_set_type(s_g_vba_to_sb(vba), S_SB_DATA_PENDING_GC); + } else if (S_TOK_UECC == lba) { + s_sb_set_type(s_g_vba_to_sb(vba), S_SB_DATA_PENDING_GC); + if (!skipping && (diff->idx >= diff->size)) { + // Skip anything newer + WMR_PRINT(ALWAYS, "uECC in stream at vba:0x%x; exiting early to be coherent!\n", vba); + skipping = TRUE32; + } + } else { + WMR_PRINT(ALWAYS, "unknown token: 0x%x\n", lba); + } + } else { + // Check ordering + if ((S_TOK_ERASED != lba) && (S_TOK_UECC != lba)) { + WMR_ASSERT(0 == diff->updates); + } + } + + // Next + diff->vba[which] += count; + diff->bte[which]++; + WMR_ASSERT(0 != diff->btoc_len[which]); + diff->btoc_len[which]--; + if (lba < S_TOKEN_LBA_BASE) { + lastWeave = WMR_MAX(lastWeave, weaveSeq + count); +#ifndef AND_READONLY + lastCount = count; +#endif // AND_READONLY + } + + if ((!diff->bte[which]->count) && (diff->idx < diff->size)) { + WMR_ASSERT(0 == diff->btoc_len[which]); + + // Load next + // Skip sbs wholly older than cxt + while ((diff->item[diff->idx].maxWeaveSeq < cxt->load.baseWeaveSeq) && (diff->idx < diff->size)) { + diff->idx++; + } + if (diff->idx != diff->size) { + diff->itemIdx[which] = diff->idx; + no_gc = s_btoc_read(diff->item[diff->idx].sb, diff->btoc[which], &diff->btoc_len[which], TRUE32, FALSE32); + if (!no_gc) { + s_sb_set_type(diff->item[diff->idx].sb, S_SB_DATA_PENDING_GC); + } + diff->vba[which] = s_g_addr_to_vba(diff->item[diff->idx].sb, 0); + diff->bte[which] = diff->btoc[which]; + diff->weave[which] = diff->item[diff->idx].minWeaveSeq; + + diff->idx++; + } + } + } + + // Set up weave sequence for incoming writes + sftl.write.weaveSeq = WMR_MAX(sftl.write.weaveSeq, lastWeave); + + // Free BTOCs + wo_unseed(); + + s_dbg_check_validSums(); +} + +static void scan_all_sb_cb(UInt32 vba, VFLReadStatusType status, UInt8 *__meta) +{ + if (status & VFL_READ_STATUS_UNIDENTIFIED) { + WMR_PRINT(QUAL_FATAL, "scan_all got unidentified read status (0x%x) on vba:0x%x; did we get a timeout? Pretending it was uECC.\n", status, vba); + status = (status & ~VFL_READ_STATUS_UNIDENTIFIED) | VFL_READ_STATUS_UECC; + } + + if (status & VFL_READ_STATUS_UECC) { + META_SET_LBA_UECC(__meta); + } else if (status & VFL_READ_STATUS_CLEAN) { + META_SET_LBA_CLEAN(__meta); + } +} + +void s_scan_all_sb(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 vba, sb, size, i, lookSb; + PageMeta_t *meta, *metaBTOC; + UInt8 *buf; + UInt32 vbas_in_sb; + + // Find pagetypes, weaveSeqMin, weaveSeqAdd + for (sb = 0; sb < s_g_max_sb; ) { + size = 0; + + // Clear read-spattered + sftl.vfl->ReadSpansInit(&cxt->load.rs, scan_all_sb_cb, VFL_READ_STATUS_ALL, TRUE32, FALSE32); + buf = sftl.gc.zone; + meta = sftl.scan_meta; + + // Quick first pass; scan the first and last vbas + lookSb = sb; + while ((size < S_SCAN_META_SIZE) && (sb < s_g_max_sb)) { + vbas_in_sb = sftl.vfl->GetVbasPerVb(sb); + if (vbas_in_sb) { + // Schedule read of first page + vba = s_g_addr_to_vba(sb, 0); + sftl.vfl->ReadSpansAdd(&cxt->load.rs, vba, 1, buf, (UInt8*)meta); + meta++; + + // And last, which should be a subset of the BTOC + vba = s_g_addr_to_vba(sb, (vbas_in_sb - 1)); + sftl.vfl->ReadSpansAdd(&cxt->load.rs, vba, 1, buf, (UInt8*)meta); + meta++; + + // Since we took space + size += 2; + } else { + s_sb_set_type(sb, S_SB_DEAD); + sftl.seaState.dead_sb++; + } + + // Next + sb++; + } + + WMR_ASSERT(size <= S_SCAN_META_SIZE); + // Perform read + sftl.vfl->ReadSpans(&cxt->load.rs); + + // Examine metadata + meta = sftl.scan_meta; + for (i = 0; i < size; i += 2) { + // Skip over zero-sized superblocks, again + while (0 == (vbas_in_sb = sftl.vfl->GetVbasPerVb(lookSb))) { + lookSb++; + } + + metaBTOC = meta+1; + if (!META_IS_LBA_UECC(metaBTOC) + && !META_IS_LBA_CLEAN(metaBTOC) + && (PAGETYPE_FTL_BTOC_DATA == META_GET_PAGETYPE(metaBTOC))) + { + data_weaveseq_add(lookSb, (PageMeta_BTOC_t*)metaBTOC); + } else { + if (META_IS_LBA_UECC(meta)) { + clean_add(lookSb, TRUE32); + } else if (META_IS_LBA_CLEAN(meta)) { + clean_add(lookSb, FALSE32); + } else { + if ((PAGETYPE_FTL_DATA == meta->c.PageType) + || (PAGETYPE_FTL_INTDATA == meta->c.PageType)) { + META_BTOC_SET_NUM_VBAS(meta, 0); // Override btoc vba counter + data_weaveseq_add(lookSb, (PageMeta_BTOC_t*)meta); + } else if (PAGETYPE_FTL_CXT == meta->c.PageType) { + s_sb_set_type(lookSb, S_SB_CXT); + sftl.seaState.cxt_sb++; + if (s_cxt_is_firstSb(meta, lookSb, 0)) { + s_cxt_addSb(lookSb, META_GET_WEAVESEQ(meta)); + } + } else { + WMR_PRINT(ALWAYS, "Unknown PageType:0x%02x in sb:%d (r/w: erase, r/o: ignore)\n", META_GET_PAGETYPE(meta), lookSb); + clean_add(lookSb, TRUE32); + } + } + } + + // Next + meta += 2; + lookSb++; + } + } + + wo_sort(); +} + +BOOL32 s_wo_init(void) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + WMR_MEMSET(diff, 0, sizeof(*diff)); + + diff->item = WMR_MALLOC(sizeof(s_wo_item_t) * s_g_max_sb); + WMR_ASSERT(0 != s_g_max_sb); + diff->sbFilter = WMR_MALLOC(sizeof(*diff->sbFilter) * ((s_g_max_sb + 31) / 32)); + diff->size = 0; + + return (NULL != diff->item) && (NULL != diff->sbFilter); +} + +void s_wo_close(void) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + + if (NULL != diff->item) { + WMR_FREE(diff->item, sizeof(s_wo_item_t) * s_g_max_sb); + } + diff->item = NULL; + + if (NULL != diff->sbFilter) { + WMR_FREE(diff->sbFilter, sizeof(*diff->sbFilter) * ((s_g_max_sb + 31) / 32)); + } + diff->sbFilter = NULL; +} + +static void data_weaveseq_add(UInt32 sb, PageMeta_BTOC_t *meta) +{ + WeaveSeq_t maxWeave; + + if (META_IS_BTOC_DATA(meta)) { + s_sb_set_num_btoc_vbas_0ok(sb, META_BTOC_GET_NUM_VBAS(meta)); + maxWeave = META_GET_WEAVESEQ_MAX(meta); + } else { + s_sb_set_num_btoc_vbas_0ok(sb, 0); + maxWeave = ~0LL; + WMR_ASSERT(0xffffffffffffffffLL == maxWeave); + } + + s_sb_set_static(sb, META_IS_STATIC(meta)); + s_sb_set_type(sb, S_SB_DATA); + sftl.seaState.data_sb++; + s_sb_log_next(); + + wo_append(sb, META_GET_WEAVESEQ_MIN(meta), maxWeave); +} + +static void wo_append(UInt32 sb, WeaveSeq_t minWeaveSeq, WeaveSeq_t maxWeaveSeq) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + UInt32 idx; + +#if AND_SIMULATOR + Int32 i; + + // Debug code to make sure it's not already on the list + for (i = (Int32)diff->size-1; i >= 0; i--) { + if (diff->item[i].sb == sb) { + WMR_PANIC("duplicate item on weave list"); + } + } +#endif + + // Put it on the list + idx = diff->size; + diff->size++; + WMR_ASSERT(diff->size < s_g_max_sb); + + diff->item[idx].sb = sb; + diff->item[idx].minWeaveSeq = minWeaveSeq; + diff->item[idx].maxWeaveSeq = maxWeaveSeq; +} + +static void wo_sort(void) +{ + s_cxt_diff_t *const diff = &sftl.cxt.diff; + WeaveSeq_t min; + UInt32 minIdx, i, j; + s_wo_item_t tmp; + + if (0 == diff->size) { + return; + } + + for (i = 0; i < diff->size-1; i++) { + min = diff->item[i].minWeaveSeq; + minIdx = i; + + // Find min + for (j = i+1; j < diff->size; j++) { + if (diff->item[j].minWeaveSeq < min) { + min = diff->item[j].minWeaveSeq; + minIdx = j; + } + } + + // Found the smallest element? + if (minIdx != i) { + // Swap + tmp = diff->item[i]; + diff->item[i] = diff->item[minIdx]; + diff->item[minIdx] = tmp; + } + } +} + +static void clean_add(UInt32 sb, BOOL32 force) +{ + s_sb_set_type(sb, force ? S_SB_PENDING_ERASE : S_SB_ERASE_BEFORE_USE); + sftl.seaState.free_sb++; + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sb); + s_diff_sbFilter_add(sb); +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.h new file mode 100644 index 0000000..e37fdd7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_diff.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_CXT_DIFF_H__ +#define __S_CXT_DIFF_H__ + +#include "s_internal.h" + +// Lifecycle: +extern BOOL32 s_wo_init(void); +extern void s_wo_close(void); + +// sb filter: +extern void s_diff_sbFilter_add(UInt32 sb); +extern BOOL32 s_diff_sbFilter_has(UInt32 sb); +extern void s_diff_filterPost(WeaveSeq_t weave); + +// Scan: +extern void s_scan_all_sb(void); +extern void s_cxt_scan_diff(void); + +#endif // __S_CXT_DIFF_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.c new file mode 100644 index 0000000..65b7d94 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.c @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_cxt_load.h" +#include "s_cxt_diff.h" +#include "s_geom.h" +#include "s_stats.h" +#include "s_sb.h" +#include "s_dbg.h" +#include "s_read.h" + +static BOOL32 cxtLoadBase(BOOL32 *enumerate, BOOL32 statsOnly) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 *base = (UInt32*)sftl.gc.zone; + PageMeta_t *baseMeta = sftl.gc.meta; + UInt32 *buf; + UInt32 sb, vba, num, bufMaxIdx; + VFLReadStatusType vfl_status; + const VFLReadStatusType vfl_status_mask = (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN | + VFL_READ_STATUS_VALID_DATA | VFL_READ_STATUS_UNIDENTIFIED); + const VFLReadStatusType vfl_status_expected = VFL_READ_STATUS_VALID_DATA; + + *enumerate = TRUE32; + + sb = cxt->load.baseSb[cxt->load.baseCur]; + vba = s_g_addr_to_vba(sb, 0); + + vfl_status = sftl.vfl->ReadMultipleVbas(vba, s_g_vbas_per_page, (UInt8*)base, (UInt8*)baseMeta, FALSE32, FALSE32); + if ((vfl_status & vfl_status_mask) != vfl_status_expected) { + return FALSE32; + } + + // Suck out sb's + buf = base; + num = *buf++; + cxt->save.num_sb = 0; + while (num--) { + WMR_ASSERT(cxt->save.num_sb < S_CXT_MAX_SB); + cxt->save.sb[cxt->save.num_sb] = *buf++; + cxt->save.num_sb++; + } + WMR_ASSERT(0 != cxt->save.num_sb); + WMR_ASSERT(cxt->save.sb[0] == sb); + + // Check FTL superblocks + buf = base; + bufMaxIdx = (s_g_bytes_per_page / sizeof(*buf)) - 1; + if (!statsOnly && (0 != buf[bufMaxIdx]) && (buf[bufMaxIdx] != s_g_max_sb)) { + WMR_PRINT(ALWAYS, "context-stored FTL superblocks doesn't match current--enmuerating as blank...\n"); + *enumerate = FALSE32; + return FALSE32; + } + + cxt->save.num_sb_used = 0; + cxt->load.baseWeaveSeq = META_GET_WEAVESEQ(&sftl.gc.meta[0]); + + return TRUE32; +} + +static BOOL32 toTree(UInt8* data8) +{ + s_cxt_t *const cxt = &sftl.cxt; + s_cxt_contig_t *contig = (s_cxt_contig_t*)data8; + UInt32 count = s_g_bytes_per_lba / sizeof(s_cxt_contig_t); + UInt32 lba, baseLba, sb; + + if (0xffffffff == contig->span) { + // Unused + return TRUE32; + } + WMR_ASSERT(0xfffffff0 == contig->span); + baseLba = contig->vba; + contig++; + count--; + + if (baseLba != cxt->load.curLba) { + WMR_PRINT(ALWAYS, "sftl: error, cxt lba not consecutive: %d, %d\n", baseLba, cxt->load.curLba); + return FALSE32; + } + + lba = baseLba; + while (count--) { + if (0xffffffff == contig->vba) { + break; + } + WMR_ASSERT(0 != contig->span); + sb = s_g_vba_to_sb(contig->vba); + if ((L2V_VBA_SPECIAL <= contig->vba) || !s_diff_sbFilter_has(sb)) { + L2V_Update(lba, contig->span, contig->vba); + } + lba += contig->span; + contig++; + } + + cxt->load.curLba = lba; + return TRUE32; +} + +static BOOL32 interpret(PageMeta_t *meta, UInt8* data, UInt32 vba, BOOL32 statsOnly, s_sb_fmt_t *shadowSB) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 tag, ofs, thisCount, i; + UInt32 *readPtr; + s_sb_fmt_t *sbarr; + s_sb_userSeq_t *userSeqPtr; + + tag = META_GET_CXT_TAG(meta); + + if (!META_IS_CXT(meta)) + return (S_CXTTAG_CLEAN == tag); + + if (statsOnly) { + // For the format path, we may want to load only stats + if (S_CXTTAG_STATS == tag) { + if (!cxt->load.sawStats_cxt) { + s_stats_from_buf(data, s_g_bytes_per_lba); + cxt->load.sawStats_cxt = 1; + } + } + return TRUE32; + } + + if (cxt->load.total_clean && (S_CXTTAG_CLEAN != tag)) { + WMR_PRINT(ALWAYS, "sftl: error, unexpected clean content in the middle of context\n"); + return FALSE32; + } + + switch (tag) { + case S_CXTTAG_CLEAN: + // Clean: ignore + cxt->load.total_clean++; + break; + + case S_CXTTAG_BASE: + // Ignore + break; + + case S_CXTTAG_STATS: + // Remember this vba for later: + if (!cxt->load.sawStats_cxt) { + cxt->load.sawStats_cxt = 1; + cxt->load.stats_cxt_vba = vba; + } + break; + + case S_CXTTAG_SB: + ofs = META_GET_CXT_OFS(meta); + thisCount = META_GET_CXT_LEN(meta); + if (0 == thisCount) { + // Ignore 0-count vbas past the end of the array; it may occur becase of padding + break; + } + WMR_ASSERT((ofs + thisCount) >= ofs); + WMR_ASSERT((ofs+thisCount) <= s_g_max_sb); + sbarr = (s_sb_fmt_t*)data; + if(shadowSB != NULL) + { + WMR_MEMCPY(&(shadowSB[ofs]), sbarr, (thisCount * sizeof(s_sb_fmt_t))); + } + for (i = 0; i < thisCount; i++) { + sftl.sb[ofs+i].erases = sbarr[i].erases; + } + break; + + case S_CXTTAG_TREE: + if (!toTree(data)) { + return FALSE32; + } + break; + + case S_CXTTAG_USERSEQ: + ofs = META_GET_CXT_OFS(meta); + thisCount = META_GET_CXT_LEN(meta); + if (0 == thisCount) { + // Ignore 0-count vbas past the end of the array; it may occur because of padding + break; + } + WMR_ASSERT((ofs + thisCount) >= ofs); + WMR_ASSERT((ofs+thisCount) <= s_g_max_sb); + userSeqPtr = (s_sb_userSeq_t*)data; + for (i = 0; i < thisCount; i++) { + sftl.sb_userSeq[ofs+i] = userSeqPtr[i]; + } + break; + + case S_CXTTAG_READS: + ofs = META_GET_CXT_OFS(meta); + thisCount = META_GET_CXT_LEN(meta); + if (0 == thisCount) { + // Ignore 0-count vbas past the end of the array; it may occur becase of padding + break; + } + WMR_ASSERT((ofs + thisCount) >= ofs); + WMR_ASSERT((ofs+thisCount) <= s_g_max_sb); + readPtr = (UInt32*)data; + for (i = 0; i < thisCount; i++) { + sftl.sb[ofs+i].reads = readPtr[i]; + } + break; + + default: + WMR_PRINT(ALWAYS, "cxt load: unknown tag type %d\n", tag); + break; + } + + return TRUE32; +} + +static void cxtReadInterpret_cb(UInt32 vba, VFLReadStatusType status, UInt8 *__meta) +{ + s_cxt_t *const cxt = &sftl.cxt; + + if (status & VFL_READ_STATUS_UNIDENTIFIED) { + WMR_PRINT(QUAL_FATAL, "cxt load got unidentified read status (0x%x) on vba:0x%x; did we get a timeout? Pretending it was uECC.\n", status, vba); + status = (status & ~VFL_READ_STATUS_UNIDENTIFIED) | VFL_READ_STATUS_UECC; + } + + if (status & VFL_READ_STATUS_UECC) { + cxt->load.scan_uecc++; + } else if (status & VFL_READ_STATUS_CLEAN) { + META_SET_CXT_TAG(__meta, S_CXTTAG_CLEAN); + cxt->load.scan_clean++; + } else if (status & VFL_READ_STATUS_VALID_DATA) { + cxt->load.scan_ok++; + } +} + +static BOOL32 cxtReadInterpret(BOOL32 statsOnly, s_sb_fmt_t *shadowSB) +{ + // Read all sb's, interpreting and loading vbas + // Non-cxt superblocks -> remove from sb list (are clean or data) + + s_cxt_t *const cxt = &sftl.cxt; + UInt32 vba, vbaOfs, thisCount; + UInt32 sb, curSb, vbaMax, i; + UInt32 wasCxt; + + cxt->load.total_clean = 0; + + for (curSb = 0; curSb < cxt->save.num_sb; curSb++) { + sb = cxt->save.sb[curSb]; + vbaOfs = 0; + vbaMax = sftl.vfl->GetVbasPerVb(sb); + wasCxt = 0; + + while (vbaOfs < vbaMax) { + thisCount = WMR_MIN(vbaMax - vbaOfs, sftl.gc.zoneSize); + + cxt->load.scan_clean = 0; + cxt->load.scan_uecc = 0; + cxt->load.scan_ok = 0; + + sftl.vfl->ReadSpansInit(&cxt->load.rs, cxtReadInterpret_cb, VFL_READ_STATUS_ALL, TRUE32, FALSE32); + + vba = s_g_addr_to_vba(sb, vbaOfs); + sftl.vfl->ReadSpansAdd(&cxt->load.rs, vba, thisCount, (UInt8*)sftl.gc.zone, (UInt8*)sftl.gc.meta); + sftl.vfl->ReadSpans(&cxt->load.rs); + + if (cxt->load.scan_uecc) + return FALSE32; + if ((cxt->load.scan_ok) && META_IS_CXT(&sftl.gc.meta[0]) && (0 == vbaOfs)) + wasCxt = 1; + + // Iterate over vbas we just read, and interpret + for (i = 0; i < thisCount; i++) { + if (!interpret(&sftl.gc.meta[i], &sftl.gc.zone[s_g_mul_bytes_per_lba(i)], vba+i, statsOnly, shadowSB)) + { + return FALSE32; + } + } + + if ((cxt->load.scan_clean == thisCount) && (thisCount == sftl.gc.zoneSize)) { + // Early exit when we see a lot of clean; this is normal + cxt->save.num_sb_used += wasCxt; + goto exit; + } + + vbaOfs += thisCount; + } + + cxt->save.num_sb_used += wasCxt; + } + +exit: + cxt->save.num_sb = cxt->save.num_sb_used; + return TRUE32; +} + +void cxtRamNuke(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 i; + + cxt->load.baseCur++; + L2V_Nuke(); + WMR_MEMSET(&sftl.stats, 0, sizeof(sftl.stats)); + + cxt->load.sawStats_cxt = 0; + cxt->load.sawStats_lba = 0; + cxt->save.num_sb = 0; + + for (i = 0; i < s_g_max_sb; i++) { + sftl.sb[i].erases = 0; + sftl.sb[i].reads = 0; + sftl.sb[i].validLbas = 0; + } + sftl.seaState.validLbas = 0; +} + +void s_cxt_load_finish(void) +{ +#ifndef AND_READONLY + // Erase all old cxts + s_cxt_t *const cxt = &sftl.cxt; + UInt32 sb, i; + BOOL32 skip; + + for (sb = 0; sb < s_g_max_sb; sb++) { + if (S_SB_CXT == s_sb_get_type(sb)) { + skip = FALSE32; + for (i = 0; i < cxt->save.num_sb; i++) { + if (sb == cxt->save.sb[i]) + skip = TRUE32; + } + if (!skip) { + s_sb_cxt_free_erase(sb); + } + } + } +#endif +} + +BOOL32 s_cxt_load(BOOL32 statsOnly, s_sb_fmt_t *shadowSB) +{ + s_cxt_t *const cxt = &sftl.cxt; + BOOL32 status, enumerate; + BOOL32 retStatus = TRUE32; + + // Try to load contexts, from newest to oldest + cxt->load.baseCur = 0; + s_dbg_check_validSums(); + +again: + cxt->load.baseWeaveSeq = 0; + // No good cxts + if (cxt->load.baseCur >= cxt->load.bases) { + goto exit; + } + + // Load base + if (!cxtLoadBase(&enumerate, statsOnly)) { + WMR_PRINT(ALWAYS, "couldn't load cxt %d; issue with base...\n", cxt->load.baseCur); + cxtRamNuke(); + + if (!enumerate) { + retStatus = FALSE32; + goto exit; + } + // Force a context save post-boot + cxt->periodic.sbsSince = S_CXT_PERIOD_SBS; + goto again; + } + + if (!statsOnly) { + s_diff_filterPost(cxt->load.baseWeaveSeq); + } + + // Read and interpret + cxt->load.curLba = 0; + status = cxtReadInterpret(statsOnly, shadowSB); + if (!status) { + WMR_PRINT(ALWAYS, "couldn't load cxt %d; uECC or missing pages...\n", cxt->load.baseCur); + cxtRamNuke(); + // Force a context save post-boot + cxt->periodic.sbsSince = S_CXT_PERIOD_SBS; + goto again; + } + + if (!statsOnly) { + // Tree not fully populated? + // Try older one... + if (cxt->load.curLba < sftl.max_lba) { + WMR_PRINT(ALWAYS, "couldn't load cxt %d; tree not fully loaded...\n", cxt->load.baseCur); + cxtRamNuke(); + // Force a context save post-boot + cxt->periodic.sbsSince = S_CXT_PERIOD_SBS; + goto again; + } + } + + // Set up weaveSeq to be newer than cxt + sftl.write.weaveSeq = sftl.cxt.load.baseWeaveSeq + (sftl.cxt.save.num_sb * s_g_vbas_per_sb) + 1; + + s_dbg_check_validSums(); + +exit: + if (!statsOnly) { + // Erase any cxts not currently used + s_cxt_load_finish(); + } + + return retStatus; +} + +#ifndef AND_READONLY +void s_cxt_stats_load(void) +{ + VFLReadStatusType status; + + s_cxt_t *const cxt = &sftl.cxt; + + WMR_ASSERT(!cxt->load.loadedStats); + cxt->load.loadedStats = TRUE32; + + if (cxt->load.sawStats_lba) { + if (ANDErrorCodeOk == s_read_int(S_LBA_STATS, 1, sftl.tmpBuf)) { + s_stats_from_buf(sftl.tmpBuf, s_g_bytes_per_lba); + } else { + WMR_PRINT(ERROR, "could not load sftl stats"); + } + } else if (cxt->load.sawStats_cxt) { + sftl.vfl->ReadSpansInit(&cxt->load.rs, NULL, VFL_READ_STATUS_ALL, TRUE32, FALSE32); + sftl.vfl->ReadSpansAdd(&cxt->load.rs, cxt->load.stats_cxt_vba, 1, sftl.tmpBuf, (UInt8*)sftl.boot.meta); + status = sftl.vfl->ReadSpans(&cxt->load.rs); + if (!(status & (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN))) { + s_stats_from_buf(sftl.tmpBuf, s_g_bytes_per_lba); + } else { + WMR_PRINT(ERROR, "could not load sftl stats. status = 0x%x", status); + } + } +} +#endif // !AND_READONLY + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.h new file mode 100644 index 0000000..7cc9ecc --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_load.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_CXT_LOAD_H__ +#define __S_CXT_LOAD_H__ + +#include "s_internal.h" + +extern BOOL32 s_cxt_load(BOOL32 statsOnly, s_sb_fmt_t *shadowSB); + +#ifndef AND_READONLY +extern void s_cxt_stats_load(void); +#else // ->!AND_READONLY +#define s_cxt_stats_load() +#endif // !AND_READONLY + +#endif // __S_CXT_LOAD_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.c new file mode 100644 index 0000000..4a25d6a --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.c @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#define AND_TRACE_LAYER FTL + +#include "s_cxt.h" +#include "s_geom.h" +#include "s_sb.h" +#include "s_dbg.h" +#include "s_stats.h" +#include "s_write.h" +#include "s_trim.h" + +#ifndef AND_READONLY + +static void cxtContigAdd(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + L2V_SearchCtx_t *const c = &cxt->save.c; + + cxt->save.curContig->span = c->span; + cxt->save.curContig->vba = c->vba; + cxt->save.curContig++; + cxt->save.curIdx++; +} + +static void cxtNextPage(UInt32 baseLba, BOOL32 done) +{ + s_cxt_t *const cxt = &sftl.cxt; + L2V_SearchCtx_t *const c = &cxt->save.c; + + if ((cxt->save.curIdx < cxt->save.idxPerVba) && !done) + return; + + while (cxt->save.curIdx < cxt->save.idxPerVba) { + c->vba = c->span = 0xffffffff; + cxtContigAdd(); + } + + cxt->save.curVba++; + if(cxt->save.curVba >= sftl.gc.zoneSize) + { + return; + } + cxt->save.curContig = (s_cxt_contig_t*)&sftl.gc.zone[s_g_mul_bytes_per_lba(cxt->save.curVba)]; + cxt->save.curIdx = 0; + + // Base lba: + cxt->save.curContig->span = 0xfffffff0; + cxt->save.curContig->vba = baseLba; + WMR_ASSERT((0xffffffff != baseLba) || done); + cxt->save.curContig++; + cxt->save.curIdx++; +} + +static void cxtNextSB(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 thisVbas; + + cxt->save.vba = s_g_addr_to_vba(cxt->save.sb[cxt->save.num_sb_used], 0); + thisVbas = sftl.vfl->GetVbasPerVb(cxt->save.sb[cxt->save.num_sb_used]); + WMR_ASSERT(0 != thisVbas); + cxt->save.maxVba = cxt->save.vba + thisVbas; + cxt->save.num_sb_used++; +} + +static void cxtBatchSetup(UInt32 baseLba) +{ + s_cxt_t *const cxt = &sftl.cxt; + + cxt->save.idxPerVba = s_g_bytes_per_lba / sizeof(s_cxt_contig_t); + cxt->save.curVba = (UInt32)(-1); + cxt->save.curIdx = (UInt32)(-1); + cxtNextPage(baseLba, FALSE32); +} + +static BOOL32 cxtNextBatch(UInt32 baseLba, BOOL32 done) +{ + s_cxt_t *const cxt = &sftl.cxt; + BOOL32 status; + s_cxt_contig_t *contig; + + if (((cxt->save.curVba < sftl.gc.zoneSize) && !done) || (0 == cxt->save.curVba)) + return TRUE32; + + // Fill out zone with pad + while (cxt->save.curVba < sftl.gc.zoneSize) { + contig = (s_cxt_contig_t*)&sftl.gc.zone[s_g_mul_bytes_per_lba(cxt->save.curVba)]; + contig->span = 0xffffffff; + contig->vba = 0xffffffff; + cxt->save.curVba++; + } + + if ((cxt->save.vba+cxt->save.curVba) >= cxt->save.maxVba) { + cxtNextSB(); + } + + s_SetupMeta_Cxt(sftl.gc.meta, cxt->save.curVba, S_CXTTAG_TREE, 0, 0, 0); + status = sftl.vfl->ProgramMultipleVbas(cxt->save.vba, cxt->save.curVba, (UInt8*)sftl.gc.zone, (UInt8*)sftl.gc.meta, TRUE32, FALSE32); + if (!status) { + WMR_PRINT(QUAL, "sftl: program failure writing cxt batch vba:0x%x\n", cxt->save.vba); + } + cxt->save.vba += cxt->save.curVba; + + cxtBatchSetup(baseLba); + + return status; +} + +static BOOL32 cxtSaveBase(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 *base = (UInt32*)sftl.gc.zone; + PageMeta_t *baseMeta = sftl.gc.meta; + UInt32 *buf; + UInt32 i, bufMaxIdx; + BOOL32 status; + + s_SetupMeta_Cxt(baseMeta, s_g_vbas_per_page, S_CXTTAG_BASE, 0, 0, 0); + + // Fill out base data + buf = base; + WMR_MEMSET(buf, 0, s_g_bytes_per_page); + buf[0] = cxt->save.num_sb; + WMR_ASSERT(0 != buf[0]); + for (i = 0; i < cxt->save.num_sb; i++) { + buf[i+1] = cxt->save.sb[i]; + } + + // Stuff FTL superblocks in + bufMaxIdx = (s_g_bytes_per_page / sizeof(*buf)) - 1; + buf[bufMaxIdx] = s_g_max_sb; + + status = sftl.vfl->ProgramMultipleVbas(cxt->save.vba, s_g_vbas_per_page, (UInt8*)base, (UInt8*)baseMeta, TRUE32, FALSE32); + if (!status) { + WMR_PRINT(QUAL, "sftl: program failure writing cxt base vba:0x%x\n", cxt->save.vba); + return FALSE32; + } + + cxt->save.vba += s_g_vbas_per_page; + WMR_ASSERT(cxt->save.vba < cxt->save.maxVba); + + return TRUE32; +} + +static BOOL32 cxtSaveStats(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 *buf = (UInt32*)sftl.gc.zone; + BOOL32 status; + + s_stats_to_buf(buf); + s_SetupMeta_Cxt(sftl.gc.meta, s_g_vbas_per_page, S_CXTTAG_STATS, 0, 0, 0); + + status = sftl.vfl->ProgramMultipleVbas(cxt->save.vba, s_g_vbas_per_page, (UInt8*)sftl.gc.zone, (UInt8*)sftl.gc.meta, TRUE32, FALSE32); + if (!status) { + WMR_PRINT(QUAL, "sftl: program failure writing cxt stats vba:0x%x\n", cxt->save.vba); + return FALSE32; + } + + cxt->save.vba += s_g_vbas_per_page; + WMR_ASSERT(cxt->save.vba < cxt->save.maxVba); + + return TRUE32; +} + +static BOOL32 cxtSaveSB(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 count, thisCount, curCount, thisCountLbas, idx = 0; + BOOL32 status; + s_sb_t *src; + s_sb_fmt_t *dest; + + count = sizeof(s_sb_fmt_t) * s_g_max_sb; + src = &sftl.sb[0]; + + while (count) { + thisCount = WMR_MIN(s_g_mul_bytes_per_lba(sftl.gc.zoneSize), count); + thisCountLbas = ((thisCount + s_g_bytes_per_page - 1) / s_g_bytes_per_page) * s_g_vbas_per_page; + + dest = (s_sb_fmt_t*)&sftl.gc.zone[0]; + curCount = thisCount; + while (curCount >= sizeof(s_sb_fmt_t)) { + dest->type = src->type; + dest->num_btoc_vbas_AND_staticFlag = src->num_btoc_vbas_AND_staticFlag; + dest->validLbas = src->validLbas; + dest->__was_reads = 0; + dest->erases = src->erases; + + src++, dest++; + curCount -= sizeof(s_sb_fmt_t); + } + + s_SetupMeta_Cxt(sftl.gc.meta, thisCountLbas, S_CXTTAG_SB, idx, s_g_bytes_per_lba/sizeof(s_sb_fmt_t), thisCount / sizeof(s_sb_fmt_t)); + status = sftl.vfl->ProgramMultipleVbas(cxt->save.vba, thisCountLbas, (UInt8*)sftl.gc.zone, (UInt8*)sftl.gc.meta, TRUE32, FALSE32); + if (!status) { + WMR_PRINT(QUAL, "sftl: program failure writing cxt SB array vba:0x%x\n", cxt->save.vba); + return FALSE32; + } + + // Next + idx += thisCountLbas * s_g_bytes_per_lba / sizeof(s_sb_fmt_t); + count -= thisCount; + cxt->save.vba += thisCountLbas; + WMR_ASSERT(cxt->save.vba < cxt->save.maxVba); + } + + return TRUE32; +} + +static BOOL32 cxtSaveUserSeq(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 count, thisCount, curCount, thisCountLbas, idx = 0; + BOOL32 status; + s_sb_userSeq_t *src; + s_sb_userSeq_t *dest; + + count = sizeof(*src) * s_g_max_sb; + src = &sftl.sb_userSeq[0]; + WMR_ASSERT((s_g_bytes_per_lba % sizeof(*src)) == 0); + + while (count) { + thisCount = WMR_MIN(s_g_mul_bytes_per_lba(sftl.gc.zoneSize), count); + thisCountLbas = ((thisCount + s_g_bytes_per_page - 1) / s_g_bytes_per_page) * s_g_vbas_per_page; + + dest = (s_sb_userSeq_t*)&sftl.gc.zone[0]; + curCount = thisCount; + while (curCount >= sizeof(*src)) { + *dest = *src; + + src++, dest++; + curCount -= sizeof(*src); + } + + s_SetupMeta_Cxt(sftl.gc.meta, thisCountLbas, S_CXTTAG_USERSEQ, idx, s_g_bytes_per_lba/sizeof(*dest), thisCount / sizeof(*dest)); + status = sftl.vfl->ProgramMultipleVbas(cxt->save.vba, thisCountLbas, (UInt8*)sftl.gc.zone, (UInt8*)sftl.gc.meta, TRUE32, FALSE32); + if (!status) { + WMR_PRINT(QUAL, "sftl: program failure writing cxt userSeq vba:0x%x\n", cxt->save.vba); + return FALSE32; + } + + // Next + idx += thisCountLbas * (s_g_bytes_per_lba / sizeof(*src)); + count -= thisCount; + cxt->save.vba += thisCountLbas; + WMR_ASSERT(cxt->save.vba < cxt->save.maxVba); + } + + return TRUE32; +} + +static BOOL32 cxtSaveReads(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 count, thisCount, curCount, thisCountLbas, idx = 0; + BOOL32 status; + s_sb_t *src; + UInt32 *dest; + + count = sizeof(UInt32) * s_g_max_sb; + src = &sftl.sb[0]; + + while (count) { + thisCount = WMR_MIN(s_g_mul_bytes_per_lba(sftl.gc.zoneSize), count); + thisCountLbas = ((thisCount + s_g_bytes_per_page - 1) / s_g_bytes_per_page) * s_g_vbas_per_page; + + dest = (UInt32*)&sftl.gc.zone[0]; + curCount = thisCount; + while (curCount >= sizeof(UInt32)) { + *dest = src->reads; + + src++, dest++; + curCount -= sizeof(UInt32); + } + + s_SetupMeta_Cxt(sftl.gc.meta, thisCountLbas, S_CXTTAG_READS, idx, s_g_bytes_per_lba/sizeof(UInt32), thisCount / sizeof(UInt32)); + status = sftl.vfl->ProgramMultipleVbas(cxt->save.vba, thisCountLbas, (UInt8*)sftl.gc.zone, (UInt8*)sftl.gc.meta, TRUE32, FALSE32); + if (!status) { + WMR_PRINT(QUAL, "sftl: program failure writing cxt reads vba:0x%x\n", cxt->save.vba); + return FALSE32; + } + + // Next + idx += thisCountLbas * s_g_bytes_per_lba / sizeof(UInt32); + count -= thisCount; + cxt->save.vba += thisCountLbas; + WMR_ASSERT(cxt->save.vba < cxt->save.maxVba); + } + + return TRUE32; +} + +static BOOL32 cxtSaveTree(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + L2V_SearchCtx_t *const c = &cxt->save.c; + UInt32 lba; + + L2V_Search_Init(c); + + // Initialize structures + lba = 0; + + cxtBatchSetup(lba); + + while (lba < sftl.max_lba) { + // Obtain next span + c->lba = lba; + L2V_Search(c); + WMR_ASSERT(0 != c->span); + + // Save + cxtContigAdd(); + + // Next + lba += c->span; + + // Page full? + cxtNextPage(lba, FALSE32); + // Batch full? + if (!cxtNextBatch(lba, FALSE32)) + return FALSE32; + } + + cxtNextPage(0xffffffff, TRUE32); + return cxtNextBatch(lba, TRUE32); +} + +static void cxtRememberOld(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 i; + + // Remember old cxt sb's + for (i = 0; i < cxt->save.num_sb; i++) { + cxt->save.old_sb[i] = cxt->save.sb[i]; + } + cxt->save.old_num_sb = cxt->save.num_sb; +} + +static void cxtMakeSpace(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 sumVbas, thisVbas; + + cxt->save.num_sb = 0; + sumVbas = 0; + while (sumVbas < sftl.cxt.cxt_vbas) { + WMR_ASSERT(cxt->save.num_sb < S_CXT_MAX_SB); + cxt->save.sb[cxt->save.num_sb] = s_sb_cxt_alloc(); + thisVbas = sftl.vfl->GetVbasPerVb(cxt->save.sb[cxt->save.num_sb]); + WMR_ASSERT(0 != thisVbas); + sumVbas += thisVbas; + cxt->save.num_sb++; + } + s_dbg_check_sb_dist(); + + cxt->save.num_sb_used = 0; + cxtNextSB(); +} + +static void cxtEraseCur(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 i; + + // Erase the ones we've used + for (i = 0; i < cxt->save.num_sb_used; i++) { + sftl.vfl->Erase(cxt->save.sb[i], TRUE32); + } + + // Free them + for (i = 0; i < cxt->save.num_sb; i++) { + s_sb_cxt_free_clean(cxt->save.sb[i]); + } + + // Reallocate + cxtMakeSpace(); +} + +static void cxtEraseOld(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 i; + + for (i = 0; i < cxt->save.old_num_sb; i++) { + s_sb_cxt_free_erase(cxt->save.old_sb[i]); + } + + s_dbg_check_sb_dist(); +} + +static void cxtFreeUnused(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 i; + + for (i = cxt->save.num_sb_used; i < cxt->save.num_sb; i++) { + s_sb_cxt_free_clean(cxt->save.sb[i]); + } + + cxt->save.num_sb = cxt->save.num_sb_used; + + s_dbg_check_sb_dist(); +} + +void s_cxt_save(void) +{ + WMR_TRACE_IST_0(CxtSave, START); + + // Must drain pending buffers, since they already have weaveSeq's attached + s_drain_stream_all(TRUE32); + + // Apply pending trims, without token + s_trim_apply(FALSE32); + + // Allocate space + cxtRememberOld(); + cxtMakeSpace(); + +retry: + + // Base page; contains pointers to other sb's, etc + if (!cxtSaveBase()) { + cxtEraseCur(); + goto retry; + } + + // Save AND stats + if (!cxtSaveStats()) { + cxtEraseCur(); + goto retry; + } + + // Save superblock array + if (!cxtSaveSB()) { + cxtEraseCur(); + goto retry; + } + + // Save userSeq + if (!cxtSaveUserSeq()) { + cxtEraseCur(); + goto retry; + } + + // Save reads + if (!cxtSaveReads()) { + cxtEraseCur(); + goto retry; + } + + // Save tree + s_dbg_check_validSums(); + if (!cxtSaveTree()) { + cxtEraseCur(); + goto retry; + } + + // Erase old cxt + cxtEraseOld(); + + // Free unused superblocks, since we over-allocated + cxtFreeUnused(); + + // Clear vulnerability flags + s_trim_clearVulnerables(); + + WMR_TRACE_IST_0(CxtSave, END); +} + +#endif // AND_READONLY + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.h new file mode 100644 index 0000000..ef7ac8f --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_cxt_save.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_CXT_LOAD_H__ +#define __S_CXT_LOAD_H__ + +#include "s_internal.h" + +extern void s_cxt_save(void); + +#endif // __S_CXT_LOAD_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.c new file mode 100644 index 0000000..2cdc055 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_dbg.h" +#include "s_sb.h" +#include "s_geom.h" + +// Debug self-consistency checks +#if S_DBG_CONSISTENCY && !defined(AND_READONLY) + +//S_DBG_CONSISTENCY==1 +BOOL32 s_dbg_init(void) +{ + sftl.dbg.validSums = WMR_MALLOC(s_g_max_sb * sizeof(*sftl.dbg.validSums)); + + return (NULL != sftl.dbg.validSums); +} + +//S_DBG_CONSISTENCY==1 +void s_dbg_close(void) +{ + if (NULL != sftl.dbg.validSums) { + WMR_FREE(sftl.dbg.validSums, s_g_max_sb * sizeof(*sftl.dbg.validSums)); + } + + sftl.dbg.validSums = NULL; +} + +//S_DBG_CONSISTENCY==1 +void s_dbg_check_validSums(void) +{ + UInt32 lba, sb; + UInt32 i; + + WMR_MEMSET(&sftl.dbg.validSums[0], 0, s_g_max_sb * sizeof(*sftl.dbg.validSums)); + + // Make a complete pass through the tree, accumulating valid spans into a shadow + // superblock valid counter array. + lba = 0; + L2V_Search_Init(&sftl.dbg.c); + while (lba < sftl.max_lba) { + sftl.dbg.c.lba = lba; + L2V_Search(&sftl.dbg.c); + if (sftl.dbg.c.vba < L2V_VBA_SPECIAL) { + sb = s_g_vba_to_sb(sftl.dbg.c.vba); + WMR_ASSERT(sb < s_g_max_sb); + sftl.dbg.validSums[sb] += sftl.dbg.c.span; + } + + // Next + lba += sftl.dbg.c.span; + } + + // Compare computed valids with maintained valids--should be exactly the same. + for (i = 0; i < s_g_max_sb; i++) { + WMR_ASSERT(sftl.dbg.validSums[i] == sftl.sb[i].validLbas); + } +} + +//S_DBG_CONSISTENCY==1 +void s_dbg_check_data_counts(void) +{ + UInt32 i, sum = 0; + UInt32 free_sum = 0; + UInt32 type; + + for (i = 0; i < s_g_max_sb; i++) + { + sum += s_sb_get_validLbas(i); + type = s_sb_get_type(i); + if ((S_SB_ERASED == type) + || (S_SB_PENDING_ERASE == type) + || (S_SB_ERASE_BEFORE_USE == type)) + { + free_sum += sftl.vfl->GetVbasPerVb(i); + } + } + WMR_ASSERT(sum == sftl.seaState.validLbas); + WMR_ASSERT(free_sum == sftl.seaState.vbas_in_free_sb); +} + +//S_DBG_CONSISTENCY==1 +#if AND_SIMULATOR + +#define MAX_ERASE_GAP 100 +#define MAX_ERASE_LIMIT 3000 + +typedef struct +{ + UInt32 eraseMin; + UInt32 minCounter; + UInt32 eraseMax; + UInt32 maxCounter; + UInt32 eraseAve; + BOOL32 populated; + s_stats_t statSnapShot; +} erase_stat; + +erase_stat eraseStatArray[MAX_ERASE_LIMIT / MAX_ERASE_GAP] = {0}; + +BOOL32 checkWL(UInt32 index) +{ + BOOL32 retStatus = TRUE32; + + if((index > 1) && (index <= (MAX_ERASE_LIMIT / MAX_ERASE_GAP))) + { + if((eraseStatArray[index - 2].eraseMin >= eraseStatArray[index - 1].eraseMin) || + (eraseStatArray[index - 2].eraseAve >= eraseStatArray[index - 1].eraseAve)) + { + UInt32 i; + + for (i = 0; i < s_g_max_sb; i++) + { + if((s_sb_get_type(i) != S_SB_DEAD) && (s_sb_get_erases(i) == eraseStatArray[index - 1].eraseMin)) + { + WMR_PRINT(ALWAYS,"block %d has type 0x%x validlbas 0x%x no of erases %d\n", + i, s_sb_get_type(i), s_sb_get_validLbas(i), s_sb_get_erases(i)); + } + } + + retStatus = FALSE32; + + if(sftl.ignoreEraseGap) + { + WMR_PRINT(ALWAYS, "Does not look like wearleveling works Min : %d c %d - %d c %d, Ave : %d - %d, Max %d c %d - %d c %d\n", + eraseStatArray[index - 2].eraseMin, eraseStatArray[index - 2].minCounter, + eraseStatArray[index - 1].eraseMin, eraseStatArray[index - 1].minCounter, + eraseStatArray[index - 2].eraseAve, eraseStatArray[index - 1].eraseAve, + eraseStatArray[index - 2].eraseMax, eraseStatArray[index - 2].maxCounter, + eraseStatArray[index - 1].eraseMax, eraseStatArray[index - 1].minCounter); + } + else + { + WMR_PANIC("Does not look like wearleveling works Min : %d c %d - %d c %d, Ave : %d - %d, Max %d c %d - %d c %d\n", + eraseStatArray[index - 2].eraseMin, eraseStatArray[index - 2].minCounter, + eraseStatArray[index - 1].eraseMin, eraseStatArray[index - 1].minCounter, + eraseStatArray[index - 2].eraseAve, eraseStatArray[index - 1].eraseAve, + eraseStatArray[index - 2].eraseMax, eraseStatArray[index - 2].maxCounter, + eraseStatArray[index - 1].eraseMax, eraseStatArray[index - 1].minCounter); + } + } + } + + return retStatus; +} + +#endif + +void s_dbg_check_sb_dist(void) +{ + UInt32 i; + Int32 sb_data, sb_erased, sb_free, sb_cxt, sb_dead; + BOOL32 err = FALSE32; +#if AND_SIMULATOR + UInt32 maxErase = 0, minErase = 0xffffffff, accumErases = 0, accumCounter = 0, arrayEntry, maxCounter = 0, minCounter = 0; +#endif + + // Don't check during GC of power-on restore + if (!sftl.booted) + return; + + sb_data = sb_erased = sb_free = sb_cxt = sb_dead = 0; + + for (i = 0; i < s_g_max_sb; i++) { +#if AND_SIMULATOR + if(s_sb_get_type(i) != S_SB_DEAD) + { + accumErases += s_sb_get_erases(i); + accumCounter++; + if(s_sb_get_erases(i) > maxErase) + { + maxErase = s_sb_get_erases(i); + maxCounter = 1; + } + else + { + if(maxErase == s_sb_get_erases(i)) + { + maxCounter++; + } + } + if(s_sb_get_erases(i) < minErase) + { + minErase = s_sb_get_erases(i); + minCounter = 1; + } + else + { + if(minErase == s_sb_get_erases(i)) + { + minCounter++; + } + } + } + +#endif + + switch (s_sb_get_type(i)) { + case S_SB_DEAD: + sb_dead++; + break; + + case S_SB_DATA: + case S_SB_DATA_CUR: + case S_SB_DATA_GC: + case S_SB_DATA_PENDING_GC: + sb_data++; + break; + + case S_SB_ERASED: + sb_erased++; + sb_free++; + break; + + case S_SB_PENDING_ERASE: + case S_SB_ERASE_BEFORE_USE: + sb_free++; + break; + + case S_SB_CXT: + sb_cxt++; + break; + + default: + WMR_PANIC("unknown block type: %d", s_sb_get_type(i)); + break; + } + } + +#if AND_SIMULATOR + arrayEntry = maxErase / MAX_ERASE_GAP; + if((arrayEntry) && (arrayEntry <= (MAX_ERASE_LIMIT / MAX_ERASE_GAP)) && ( eraseStatArray[arrayEntry - 1].populated == FALSE32)) + { + eraseStatArray[arrayEntry - 1].eraseMin = minErase; + eraseStatArray[arrayEntry - 1].minCounter = minCounter; + eraseStatArray[arrayEntry - 1].eraseMax = maxErase; + eraseStatArray[arrayEntry - 1].maxCounter = maxCounter; + eraseStatArray[arrayEntry - 1].eraseAve = accumErases / accumCounter; + eraseStatArray[arrayEntry - 1].populated = TRUE32; + WMR_MEMCPY(&(eraseStatArray[arrayEntry - 1].statSnapShot), &(sftl.stats), sizeof(s_stats_t)); + checkWL(arrayEntry); + } +#endif + + if (sb_data != sftl.seaState.data_sb) + { + WMR_PRINT(ERROR, "Data sb counts don't match; %d != %d\n", sb_data, sftl.seaState.data_sb); + err = TRUE32; + } + if (sb_cxt != sftl.seaState.cxt_sb) + { + WMR_PRINT(ERROR, "Cxt sb counts don't match; %d != %d\n", sb_cxt, sftl.seaState.cxt_sb); + err = TRUE32; + } + if (sb_erased != sftl.seaState.erased_sb) + { + WMR_PRINT(ERROR, "Erased sb counts don't match; %d != %d\n", sb_erased, sftl.seaState.erased_sb); + err = TRUE32; + } + if (sb_free != sftl.seaState.free_sb) + { + WMR_PRINT(ERROR, "Free sb counts don't match; %d != %d\n", sb_free, sftl.seaState.free_sb); + err = TRUE32; + } + if (sb_dead != sftl.seaState.dead_sb) + { + WMR_PRINT(ERROR, "Dead sb counts don't match; %d != %d\n", sb_dead, sftl.seaState.dead_sb); + err = TRUE32; + } + if (sftl.seaState.free_sb < 0) + { + WMR_PRINT(ERROR, "Free sb underflow error\n"); + err = TRUE32; + } + if (sftl.seaState.data_sb < 0) + { + WMR_PRINT(ERROR, "Data sb underflow error\n"); + err = TRUE32; + } + if (sftl.seaState.dead_sb < 0) + { + WMR_PRINT(ERROR, "Dead sb underflow error\n"); + err = TRUE32; + } + if ((sb_data+sb_free+sb_cxt+sb_dead) != (Int32)s_g_max_sb) { + WMR_PRINT(ERROR, "sum not right: %d != %d\n", sb_data+sb_free+sb_cxt+sb_dead, s_g_max_sb); + err = TRUE32; + } + WMR_ASSERT(FALSE32 == err); +} + +#endif + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.h new file mode 100644 index 0000000..590b036 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_dbg.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_DBG_H__ +#define __S_DBG_H__ + +#include "s_internal.h" + +#define S_DBG_INIT (1 << 0) +#define S_DBG_FORMAT (1 << 1) +#define S_DBG_READ (1 << 2) +#define S_DBG_WRITE (1 << 3) +#define S_DBG_ERASE (1 << 4) +#define S_DBG_MISC (1 << 5) +#define S_DBG_ERROR (1 << 6) +#define S_DBG_OPEN (1 << 7) +#define S_DBG_INFO (1 << 8) + +#define SFTL_DEBUG (S_DBG_ERROR) + +#ifdef SFTL_DEBUG +#define SFTL_ENABLE_DEBUG_PRINT (0xff) +# define s_debug(fac, fmt, args ...) \ + do { \ + if (S_DBG_ ## fac & SFTL_DEBUG & SFTL_ENABLE_DEBUG_PRINT) { \ + _WMR_PRINT("sftl::%s(l:%d): " fmt "\n", __FUNCTION__, __LINE__, ## args); \ + } \ + } while (0) +#else +# define s_debug(fac, fmt, args ...) do { } while (0) +#endif + + +// Self-consistency checks +#if S_DBG_CONSISTENCY && !defined(AND_READONLY) +extern BOOL32 s_dbg_init(void); +extern void s_dbg_close(void); +extern void s_dbg_check_validSums(void); +extern void s_dbg_check_data_counts(void); +extern void s_dbg_check_sb_dist(void); +#else +#define s_dbg_init() TRUE32 +#define s_dbg_close() +#define s_dbg_check_validSums() +#define s_dbg_check_data_counts() +#define s_dbg_check_sb_dist() +#endif + +#endif // __S_DBG_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_defines.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_defines.h new file mode 100644 index 0000000..30bd84a --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_defines.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_DEFINES_H__ +#define __S_DEFINES_H__ + +#define S_RESERVE_QUANTIZE 8 +#define S_RESERVE_PERMIL_APPROX 68 + +#if AND_SIMULATOR +#define S_DBG_CONSISTENCY 1 +#endif + +#define S_LBAS_INTERNAL 16 // LBAs reserved for TL-internal data (such as stats) +#define S_LBA_STATS (sftl.max_lba - 1) + +#define S_CXT_PERIOD_SBS 100 +#define S_STATS_PERIOD_SBS 10 +#define S_CXT_MAX_SB 32 + +#define S_BTOCCACHE_SRCSIZE 2 +#define S_SCAN_META_SIZE 256 +#define S_BTOC_META_SIZE 64 +#define S_GCZONE_DOUBLEUPTO 16 +#define S_GCFIFO_DEPTH 32 +#define S_GCFIFO_FULL 4 +#define S_GC_NUM_CTX 2 +#define S_GC_CTX_FG 0 +#define S_GC_CTX_BG 1 +#define S_GC_VALIDHIST_SIZE 16 + +#define S_READDIST_LIMIT_PER_SB S_RC_THRESHOLD +#define S_READDIST_LIMIT_PER_OPEN_SB (10000) +#define S_READDIST_PERIOD 100 // Only consider counter-relocations every x reads + +#define S_WEARLEV_PERIOD 20 +#define S_WEARLEV_MIN_GAP 50 +#define S_WEARLEV_DYN_GAP 10 + +#define S_BOOT_MAX_GC 20 + +#define S_WEAVE_SEQ_ADD_TRS 0x8000000 + +#define S_TOKEN_LBA_BASE 0xffff0000 + +#define S_LOWMEM_REPACK_MAX 10 +#define S_TRIM_CUTOFF_LOWMEM 256 +#define S_TRIM_SUMSPAN_TRIGGER 1024 +#define S_TRIM_BLOOMFILTER_SPAN 1024 + +#define USERSEQ_OLD_THRESH (sftl.reported_lba >> 16) // one cycle through the drive +#define S_USERSEQ_IS_OLD(x) ((x + USERSEQ_OLD_THRESH) < (UInt32)(sftl.write.weaveSeq >> 16)) + +// Superblock types: +typedef enum { + S_SB_UNKNOWN = 0, + S_SB_ERASED = 1, + S_SB_PENDING_ERASE = 2, + S_SB_DATA = 3, + S_SB_DATA_CUR = 4, + S_SB_DATA_GC = 5, + S_SB_DATA_PENDING_GC = 6, + S_SB_CXT = 7, + S_SB_DEAD = 8, + S_SB_ERASE_BEFORE_USE = 9, +} s_sb_type_e; + +typedef enum { + S_SBSTREAM_DYN = 0, + S_SBSTREAM_STATIC = 1, + S_SBSTREAM_WEARLEV = 2, + S_SBSTREAM_MAX +} s_sbstream_type_e; +#define S_SBSTREAM_PHY_MAX 4 + +#define MIN_NOT_ZERO(a, b) (0 == (b) ? (a) : (0 == (a) ? (b) : WMR_MIN(a, b))) +#define S_SBSTREAM_PAGES(_max) MIN_NOT_ZERO(s_g_num_banks, (_max) / s_g_bytes_per_page) +#define S_SBSTREAM_BUFSIZE(_st, _max) (((_st) == 0) ? (s_g_vbas_per_page * S_SBSTREAM_PAGES(_max)) : (s_g_vbas_per_page)) + +#define S_ROUNDUP_POW2(v, g) (((v) + (g) - 1) & ~((g) - 1)) +#define S_WRITE_LBAS_THRESHOLD(s) WMR_MAX(S_ROUNDUP_POW2((s)->bufSize >> 2, s_g_vbas_per_page), /* 25% for large configs */ \ + WMR_MIN((s)->bufSize, s_g_vbas_per_page << 1)) /* 2 pages for small configs */ + +// Dependent on maximum SB streams: +#define S_BTOCCACHE_SIZE (2*S_SBSTREAM_MAX) +#define S_GC_FREE_THRESHOLD (2 + S_SBSTREAM_PHY_MAX) +#define S_GC_LOW_GAP 5 +#define S_GC_IDLELOW_GAP (S_GC_LOW_GAP+5) + +#define S_TOK_PAD (S_TOKEN_LBA_BASE+0) +#define S_TOK_DELETE (S_TOKEN_LBA_BASE+1) +#define S_TOK_ERASED 0xffffffff +#define S_TOK_UECC 0xffffff00 + +typedef enum { + S_CXTTAG_BASE = 1, + S_CXTTAG_STATS = 2, + S_CXTTAG_SB = 3, + S_CXTTAG_TREE = 4, + S_CXTTAG_USERSEQ = 5, + S_CXTTAG_READS = 6, +} s_cxttag_e; +#define S_CXTTAG_CLEAN 0xff + +#endif // __S_DEFINES_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_external.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_external.c new file mode 100644 index 0000000..3ab83f6 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_external.c @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "WMRConfig.h" +#include "s_internal.h" +#include "s_init.h" +#include "s_boot.h" +#include "s_read.h" +#include "s_write.h" +#include "s_trim.h" +#include "s_fmt.h" +#include "s_gc.h" +#include "s_wearlev.h" +#include "s_geom.h" +#include "s_sb.h" +#include "s_stats.h" +#include "FTL.h" +#include "VFL.h" + +#define kSftlMinorVersion 1 + +static UInt32 _getMinorVersion(void) +{ + return kSftlMinorVersion; +} + +#ifndef AND_READONLY +static Int32 sftl_wearlevel(void) +{ + return ANDErrorCodeOutOfRangeErr; +} + + +static void L2V_IdleRepack(void) +{ + if(L2V_IdleRepackThr) + { + L2V_ForceRepack(); + } +} + +static Int32 sftl_IdleGCStripe(void) +{ + static UInt32 ctx = S_GC_CTX_BG; + Int32 ret = FTL_SUCCESS; + + if(s_gc_slice(ctx) == FALSE32) + { + /* Switch a stream */ + if(ctx == S_GC_CTX_BG) + ctx = S_GC_CTX_FG; + else + ctx = S_GC_CTX_BG; + if(s_gc_slice(ctx) == FALSE32) + { + /* Nothing to wearlevel? check the LV2 tree state */ + L2V_IdleRepack(); + /* Nothing more to do . Switch a stream and get out */ + if(ctx == S_GC_CTX_BG) + ctx = S_GC_CTX_FG; + else + ctx = S_GC_CTX_BG; + /* nothing more to do . get out */ + ret = FTL_OUT_OF_RANGE_ERROR; + } + } + + return ret; +} + + +static BOOL32 sftl_garbagecollect(void) +{ + return TRUE32; +} + +static BOOL32 sftl_drain(void) +{ + s_drain_stream_all(TRUE32); + return TRUE32; +} + +// This function is stateless. Don't use stFTLDeviceInfo +static UInt32 sftl_ConvertUserMBtoFTLSuperblocks(VFLFunctions *vfl, UInt32 user_mb) +{ + UInt32 ftl_virtual_blocks; + const UInt32 page_size = vfl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 pages_per_vb = vfl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + const UInt32 vfl_vbs = vfl->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU); + const UInt32 requested_pages = (user_mb * 1024) / (page_size / 1024); + + ftl_virtual_blocks = (requested_pages / pages_per_vb) + 1; + ftl_virtual_blocks += ((vfl_vbs * S_RESERVE_PERMIL_APPROX) + 999) / 1000; + + return ftl_virtual_blocks; +} +#endif //!AND_READONLY + +static BOOL32 sftl_ec_bins(void *structBuffer, UInt32 *structSize) +{ + BOOL32 boolRes = FALSE32; + UInt32 blockIdx, erases; + FTLBinsStruct hdr; + const UInt32 neededStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_EC_BINS; + + if (!sftl.sb) { + return FALSE32; + } + + if (structBuffer && structSize && (*structSize >= neededStructSize)) { + const UInt32 max_bin_val = FTL_MAX_EC_BIN_VAL; + const UInt32 bin_size = FTL_EC_BIN_SIZE; + UInt32 size = *structSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_EC_BINS; + WMR_MEMSET(structBuffer, 0, neededStructSize); + WMR_FILL_STRUCT(structBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < s_g_max_sb; ++blockIdx) { + UInt32 index; + UInt16 usage; + void *cursor; + + erases = s_sb_get_erases(blockIdx); + + if (erases >= max_bin_val) { + index = FTL_NUM_EC_BINS-1; + } else { + index = erases/bin_size; + } + + cursor = ((char *)structBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (structSize) { + *structSize = neededStructSize; + boolRes = TRUE32; + } + + return boolRes; +} + +static BOOL32 sftl_rc_bins(void *structBuffer, UInt32 *structSize) +{ + BOOL32 boolRes = FALSE32; + UInt32 blockIdx, reads; + FTLBinsStruct hdr; + const UInt32 neededStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_RC_BINS; + + if (!sftl.sb) { + return FALSE32; + } + + if (structBuffer && structSize && (*structSize >= neededStructSize)) { + const UInt32 max_bin_val = S_READDIST_LIMIT_PER_SB; + const UInt32 bin_size = FTL_RC_BIN_SIZE(max_bin_val); + UInt32 size = *structSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_RC_BINS; + WMR_MEMSET(structBuffer, 0, neededStructSize); + WMR_FILL_STRUCT(structBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < s_g_max_sb; ++blockIdx) { + UInt32 index; + UInt16 usage; + void *cursor; + + reads = s_sb_get_reads(blockIdx); + + if (reads >= max_bin_val) { + index = FTL_NUM_RC_BINS-1; + } else { + index = reads/bin_size; + } + + cursor = ((char *)structBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (structSize) { + *structSize = neededStructSize; + boolRes = TRUE32; + } + + return boolRes; +} + + +static void fillUpTLBlockStructure(UInt32 blockNo, ANDFTLBlockStruct * tlBlockStruct) +{ + tlBlockStruct->blockSizeInLbas = sftl.vfl->GetVbasPerVb(blockNo); + tlBlockStruct->validLbas = 0; + tlBlockStruct->blockType = 0; + switch (s_sb_get_type(blockNo)) + { + case S_SB_DATA: + case S_SB_DATA_CUR: + case S_SB_DATA_GC: + case S_SB_DATA_PENDING_GC: + { + tlBlockStruct->blockType |= TL_BLOCK_DATA; + if(s_sb_get_static(blockNo)) + tlBlockStruct->blockType |= TL_BLOCK_DATA_STATIC; + tlBlockStruct->validLbas = s_sb_get_validLbas(blockNo); + break; + } + + case S_SB_DEAD: + { + tlBlockStruct->blockType |= TL_BLOCK_DEAD; + break; + } + + case S_SB_ERASED: + case S_SB_PENDING_ERASE: + case S_SB_ERASE_BEFORE_USE: + { + tlBlockStruct->blockType |= TL_BLOCK_FREE; + break; + } + + case S_SB_CXT: + tlBlockStruct->blockType |= TL_BLOCK_CXT; + break; + + default: + tlBlockStruct->blockType |= TL_BLOCK_UNKNOWN; + } +} + +static BOOL32 sftl_getStruct(UInt32 dwStructType, void *structBuffer, UInt32 *structSize) +{ + ANDAddressStruct addr; + UInt32 addrSize = sizeof(addr); + BOOL32 boolRes = FALSE32, boolFillRes; + UInt8 FTLType; + UInt32 FTLDevInfoSize; + UInt32 value; +#ifdef AND_COLLECT_STATISTICS + UInt32 statSize; +#endif + sftl_devinfo_t *devI = (sftl_devinfo_t*)sftl.tmpBuf; + + switch (dwStructType) { + case AND_STRUCT_FTL_GET_TYPE: + FTLType = FTL_TYPE_SFTL; + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, &FTLType, sizeof(FTLType)); + break; + + #ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_FTL_GET_FTL_STATS_SIZE: + statSize = s_stats_to_buf((UInt32*)sftl.tmpBuf); + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, &statSize, sizeof(statSize)); + break; + + case AND_STRUCT_FTL_STATISTICS: + statSize = s_stats_to_buf((UInt32*)sftl.tmpBuf); + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, sftl.tmpBuf, statSize); + break; + #endif + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO_SIZE: + FTLDevInfoSize = sizeof(sftl_devinfo_t); + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, &FTLDevInfoSize, sizeof(FTLDevInfoSize)); + break; + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO: + devI->wPagesPerVb = s_g_vbas_per_sb; + devI->wUserVbTotal = s_g_max_sb; + devI->dwUserPagesTotal = s_g_vbas_per_sb * s_g_max_sb; + devI->wBytesPerPage = s_g_bytes_per_lba; + devI->wNumOfBanks = s_g_num_banks; + devI->wBytesPerPageMeta = s_g_bytes_per_lba_meta; + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, devI, sizeof(sftl_devinfo_t)); + break; + + case AND_STRUCT_FTL_GETADDRESS: + + if (structBuffer && structSize && (*structSize >= sizeof(addr))) + { + WMR_MEMCPY(&addr, structBuffer, sizeof(addr)); + + addr.dwVpn = s_read_xlate(addr.dwLpn); + if (AND_GET_ADDRESS_SPECIAL > addr.dwVpn) { + boolRes = sftl.vfl->GetStruct(AND_STRUCT_VFL_GETADDRESS, &addr, &addrSize); + } else { + boolRes = FALSE32; + } + } + + boolFillRes = WMR_FILL_STRUCT(structBuffer, structSize, &addr, sizeof(addr)); + + if (boolRes) { + boolRes = boolFillRes; + } + break; + + case AND_STRUCT_FTL_SB_CYCLES: + { + UInt32 sbIndex; + UInt32 numBufEntries = (*structSize) / sizeof(UInt16); + UInt16 *sbEraseCnts = (UInt16 *) structBuffer; + UInt32 numSBlks = s_g_max_sb; + + if((numSBlks != numBufEntries) || (sbEraseCnts == NULL)){ + boolRes = FALSE32; + break; + } + + for (sbIndex=0; sbIndex < numSBlks; sbIndex++){ + sbEraseCnts[sbIndex] = sftl.sb[sbIndex].erases; + } + + boolRes = TRUE32; + break; + } + + case AND_STRUCT_FTL_SB_READ_CYCLES: + { + UInt32 sbIndex; + UInt32 numBufEntries = (*structSize) / sizeof(UInt32); + UInt32 *sbReadCnts = (UInt32 *) structBuffer; + UInt32 numSBlks = sftl.vfl->GetDeviceInfo(AND_DEVINFO_NUM_OF_USER_SUBLK); + + if((numSBlks != numBufEntries) || (sbReadCnts == NULL)){ + boolRes = FALSE32; + break; + } + + for (sbIndex=0; sbIndex < numSBlks; sbIndex++){ + sbReadCnts[sbIndex] = sftl.sb[sbIndex].reads; + } + + boolRes = TRUE32; + break; + } + + case AND_STRUCT_FTL_GET_FTL_EC_BINS: + boolRes = sftl_ec_bins(structBuffer, structSize); + break; + + case AND_STRUCT_FTL_GET_FTL_RC_BINS: + boolRes = sftl_rc_bins(structBuffer, structSize); + break; + + case AND_STRUCT_FTL_RECOMMEND_CONTENT_DELETION: + value = 0; + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, &value, sizeof(value)); + break; + + case AND_STRUCT_FTL_IDEAL_SIZE_1K: + value = s_calc_lbas(TRUE32) * (s_g_bytes_per_lba / 1024); + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, &value, sizeof(value)); + break; + + case AND_STRUCT_FTL_GET_FTL_BLOCK_COUNT: + { + UInt32 tlBlockCount = s_g_max_sb; + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, &tlBlockCount, sizeof(tlBlockCount)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_BLOCK_STAT: + { + UInt32 i, tmpBuffSize = *structSize, tmpChunkSize; + ANDFTLBlockStruct tempStruct; + UInt8 * tmpPtr = (UInt8 *)structBuffer; + + if(tmpBuffSize >= (s_g_max_sb * sizeof(tempStruct))) + { + for(i = 0; (i < s_g_max_sb) && (tmpBuffSize >= sizeof(tempStruct)); i++, tmpBuffSize -= sizeof(tempStruct)) + { + fillUpTLBlockStructure(i, &tempStruct); + tmpChunkSize = tmpBuffSize; + boolRes = WMR_FILL_STRUCT(tmpPtr + (i * sizeof(ANDFTLBlockStruct)), &tmpChunkSize, &tempStruct, sizeof(tempStruct)); + } + } + break; + } + + case AND_STRUCT_FTL_L2V_STRUCT: + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, &L2V, sizeof(L2V)); + break; + + case AND_STRUCT_FTL_L2V_ROOTS: + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, L2V.Root, L2V.numRoots*sizeof(*L2V.Root)); + break; + + case AND_STRUCT_FTL_L2V_POOL: + boolRes = WMR_FILL_STRUCT(structBuffer, structSize, L2V.Pool.Node, L2V_nodepool_mem); + break; + + default: + boolRes = FALSE32; + break; + } + + return boolRes; +} + +static FTLFunctions _sftl_functions = +{ + .Init = sftl_init, + .Open = sftl_boot, + + .Read = sftl_read, + .ReadSpans = sftl_read_spans, + .Close = sftl_close, + .GetStruct = sftl_getStruct, + .GetMinorVersion = _getMinorVersion, + +#ifndef AND_READONLY + .ConvertUserMBtoFTLSuperblocks = sftl_ConvertUserMBtoFTLSuperblocks, + .Write = sftl_write, + .Unmap = sftl_unmap, + .Format = sftl_format, + .WearLevel = sftl_wearlevel, + .IdleGC = sftl_IdleGCStripe, + .GarbageCollect = sftl_garbagecollect, + .ShutdownNotify = sftl_shutdown_notify, + .Drain = sftl_drain, +#endif +}; + +FTLFunctions *SFTL_PPN_Register(void) +{ + return &_sftl_functions; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.c new file mode 100644 index 0000000..03de644 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#define AND_TRACE_LAYER FTL + +#include "s_flatten.h" +#include "s_gc.h" +#include "s_write.h" +#include "L2V/L2V_Extern.h" + +#ifndef AND_READONLY + +BOOL32 s_flatten(void) +{ + UInt32 lba, span; + + if (!L2V_LowishMem) { + return TRUE32; + } + + WMR_TRACE_IST_0(Flatten, START); + + do { + + do { + // Repack while critically low + L2V_ForceRepack(); + } while (L2V_CriticalMem); + // No need to continue if we're above threshold + if(!L2V_LowMem) + { + continue; + } + // Steam-roller! + // find lba region + do { + L2V_FindFrag(&lba, &span); + if((lba + span) > sftl.max_lba) { + if(lba >= sftl.max_lba) { + span = 0; + } else { + span = sftl.max_lba - lba; + } + } + } while(span == 0); + + // Do any GC upfront + s_gc_for_flatten(span); + + // Write it + s_drain_stream_all(TRUE32); + sftl.stats.lbas_flatten += span; + if (!s_gc_inject(lba, span)) { + WMR_TRACE_IST_1(Flatten, END, FALSE32); + return FALSE32; + } + s_drain_stream_all(TRUE32); + L2V_Repack(lba >> L2V_TREE_BITS); + } while (L2V_LowMem); + + WMR_TRACE_IST_1(Flatten, END, TRUE32); + return TRUE32; +} + +#endif // AND_READONLY diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.h new file mode 100644 index 0000000..aba0f1b --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_flatten.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_FLATTEN_H__ +#define __S_FLATTEN_H__ + +#include "s_internal.h" + +extern BOOL32 s_flatten(void); + +#endif // __S_FLATTEN_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.c new file mode 100644 index 0000000..7fb7c0f --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_fmt.h" +#include "s_geom.h" +#include "s_cxt.h" +#include "s_cxt_load.h" +#include "s_sb.h" + +#ifndef AND_READONLY + +static void stats_scan_all_cb(UInt32 vba, VFLReadStatusType status, UInt8 *__meta) +{ + PageMeta_BTOC_t *meta = (PageMeta_BTOC_t*)__meta; + UInt32 sb, vbaOfs; + + sb = s_g_vba_to_sb(vba); + vbaOfs = s_g_vba_to_vbaOfs(vba); + + if (status & VFL_READ_STATUS_UNIDENTIFIED) { + WMR_PRINT(QUAL_FATAL, "stats scan got unidentified read status (0x%x) on vba:0x%x; did we get a timeout? Pretending it was uECC.\n", status, vba); + status = (status & ~VFL_READ_STATUS_UNIDENTIFIED) | VFL_READ_STATUS_UECC; + } + + // Need a valid first-cxt page + if (status & VFL_READ_STATUS_VALID_DATA) { + if (PAGETYPE_FTL_CXT == meta->c.PageType) { + if (s_cxt_is_firstSb(meta, sb, vbaOfs)) { + s_cxt_addSb(sb, META_GET_WEAVESEQ(meta)); + } + } + } +} + +void stats_scan_all(void) +{ + s_cxt_t *const cxt = &sftl.cxt; + UInt32 vba, sb, size; + PageMeta_t *meta; + UInt8 *buf; + UInt32 vbas_in_sb; + + // Set up cxt variables + cxt->load.baseWeaveSeq = 0; + cxt->load.bases = 0; + + // Find pagetypes, weaveSeqMin, weaveSeqAdd + for (sb = 0; sb < s_g_vfl_max_sb; ) { + size = 0; + + // Clear read-spattered + sftl.vfl->ReadSpansInit(&cxt->load.rs, stats_scan_all_cb, VFL_READ_STATUS_ALL, TRUE32, FALSE32); + buf = sftl.gc.zone; + meta = sftl.scan_meta; + + // Read the first vba per sb to find cxt + while ((size < S_SCAN_META_SIZE) && (sb < s_g_vfl_max_sb)) { + vbas_in_sb = sftl.vfl->GetVbasPerVb(sb); + if (vbas_in_sb) { + // Schedule read of first page + vba = s_g_addr_to_vba(sb, 0); + sftl.vfl->ReadSpansAdd(&cxt->load.rs, vba, 1, buf, (UInt8*)meta); + meta++; + } + + // Next + size++; + sb++; + } + + WMR_ASSERT(size <= S_SCAN_META_SIZE); + // Perform read + sftl.vfl->ReadSpans(&cxt->load.rs); + } +} + +void loadStats(void) +{ + stats_scan_all(); + s_cxt_load(TRUE32, NULL); +} + +Int32 sftl_format(UInt32 opts) +{ + UInt32 i; + + if(!(WMR_INIT_RUN_PRODUCTION_FORMAT & opts)) + { + loadStats(); + } + + for (i = 0; i < s_g_max_sb; i++) { + s_sb_fmt_erase(i); + } + + sftl.cxt.save.num_sb = 0; + s_cxt_save(); + + return ANDErrorCodeOk; +} + +#endif // AND_READONLY + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.h new file mode 100644 index 0000000..a927991 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_fmt.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_FMT_H__ +#define __S_FMT_H__ + +#include "s_internal.h" + +extern Int32 sftl_format(UInt32 opts); + +#endif // __S_FMT_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.c new file mode 100644 index 0000000..90122fe --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.c @@ -0,0 +1,1111 @@ +/* + * Copyright (c) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define AND_TRACE_LAYER FTL + +#include "s_gc.h" +#include "s_sb.h" +#include "s_dbg.h" +#include "s_btoc.h" +#include "s_write.h" +#include "s_geom.h" +#include "s_stats.h" + +#ifndef AND_READONLY + +// Statics +static void GCMachine_Data(Int32 writeSize, BOOL32 scrubOnUECC, UInt32 ctx); +static void EraseData(UInt32 sb); +static void ChooseSB(UInt32 ctx); +static void SanityCheckValid(UInt32 ctx); +static ANDStatus EvictData(UInt32 minAmount, BOOL32 scrubOnUECC, UInt32 ctx); +static void ZoneSetup(BOOL32 scrubOnUECC); +static void ZoneAdd(UInt32 lba, UInt32 vba, UInt32 count); +static BOOL32 MoveZone(BOOL32 dynStream, BOOL32 forFlatten, BOOL32 scrubOnUECC, UInt32 ctx); +static void ReadZone_cb(UInt32 vba, VFLReadStatusType status, UInt8 *meta); +static void ReadZone(BOOL32 scrubOnUECC, UInt32 ctx); +static UInt32 AnalyzeZone(void); + + +BOOL32 s_WorkFifo_isEmpty(GC_Fifo_t *f) +{ + return f->tail == f->head; +} + +BOOL32 s_WorkFifo_isFullish(GC_Fifo_t *f) +{ + Int32 space; + + if (s_WorkFifo_isEmpty(f)) { + return FALSE32; + } + + if (f->tail > f->head) { + space = f->tail - f->head; + } else { + space = f->tail + (S_GCFIFO_DEPTH+1 - f->head); + } + + WMR_ASSERT(space > 0); + + return (space < S_GCFIFO_FULL); +} + +void s_WorkFifo_Enq(GC_Fifo_t *f, UInt32 sb) +{ + UInt32 p; + UInt32 newTail; + + newTail = f->tail + 1; + if (newTail > S_GCFIFO_DEPTH) + { + newTail = 0; + } + if (newTail == f->head) { + // FIFO is full, get out + return; + } + + p = f->head; + while (p != f->tail) + { + if (f->sb[p] == sb) + { + return; + } + + p++; + if (p > S_GCFIFO_DEPTH) + { + p = 0; + } + } + + f->sb[f->tail] = sb; + f->tail = newTail; + WMR_ASSERT(f->tail != f->head); +} + +UInt32 s_WorkFifo_Deq(GC_Fifo_t *f) +{ + UInt32 ret; + + WMR_ASSERT(f->tail != f->head); + + ret = f->sb[f->head]; + + f->head++; + if (f->head > S_GCFIFO_DEPTH) + { + f->head = 0; + } + + return ret; +} + +UInt32 s_WorkFifo_Deq_sb(GC_Fifo_t *f, UInt32 sb) +{ + UInt32 p; + UInt32 nRet = (UInt32)-1; + p = f->head; + + while (p != f->tail) + { + if (f->sb[p] == sb) + { + nRet = f->sb[p]; + break; + } + + p++; + if (p > S_GCFIFO_DEPTH) + { + p = 0; + } + } + + if(p == f->tail) + return nRet; + + while (p != f->tail) + { + if(p == S_GCFIFO_DEPTH) + { + f->sb[p]=f->sb[0]; + p=0; + } + else + { + f->sb[p]=f->sb[p+1]; + p++; + } + } + + if(f->tail == 0) + f->tail = S_GCFIFO_DEPTH; + else + f->tail--; + + return nRet; +} + +// Functions + +#endif // AND_READONLY + +BOOL32 s_gc_init(void) +{ + UInt32 ctx; + + // GC Zone size should be a multiple of banks, up to 16 (or whatever banks is naturally). + // This logic guarantees low-bank configs will have higher performance, while making sure + // high-bank configs don't occupy too much memory. + // It is similar to setting a minimum of 16, but works with non-pow-2 configs. + sftl.gc.zoneSize = s_g_num_banks * s_g_vbas_per_page; + while (sftl.gc.zoneSize < S_GCZONE_DOUBLEUPTO) { + sftl.gc.zoneSize <<= 1; + } + WMR_ASSERT(0 == (sftl.gc.zoneSize % s_g_vbas_per_page)); + + L2V_Search_Init(&sftl.gc.read_c); + for (ctx = 0; ctx < S_GC_NUM_CTX; ctx++) { + sftl.gc.ctx[ctx].state = GCD_IDLE; + sftl.gc.ctx[ctx].in_sb = 0xffffffff; + } + + + WMR_BufZone_Init(&sftl.gc.BufZone); + WMR_ASSERT(0 != s_g_max_pages_per_btoc); + for (ctx = 0; ctx < S_GC_NUM_CTX; ctx++) { + sftl.gc.ctx[ctx].BTOC = (s_btoc_entry_t*)WMR_Buf_Alloc_ForDMA(&sftl.gc.BufZone, s_g_max_pages_per_btoc * s_g_bytes_per_page); + } + sftl.gc.meta_buf = (PageMeta_t*)WMR_Buf_Alloc_ForDMA(&sftl.gc.BufZone, sizeof(PageMeta_t)); + sftl.gc.zone = (UInt8*)WMR_Buf_Alloc_ForDMA(&sftl.gc.BufZone, s_g_bytes_per_lba * sftl.gc.zoneSize); + sftl.gc.meta = (PageMeta_t*)WMR_Buf_Alloc_ForDMA(&sftl.gc.BufZone, sftl.gc.zoneSize * sizeof(PageMeta_t)); + + if (!WMR_BufZone_FinishedAllocs(&sftl.gc.BufZone)) { + return FALSE32; + } + + for (ctx = 0; ctx < S_GC_NUM_CTX; ctx++) { + WMR_BufZone_Rebase(&sftl.gc.BufZone, (void**)&sftl.gc.ctx[ctx].BTOC); + } + WMR_BufZone_Rebase(&sftl.gc.BufZone, (void**)&sftl.gc.meta_buf); + WMR_BufZone_Rebase(&sftl.gc.BufZone, (void**)&sftl.gc.zone); + WMR_BufZone_Rebase(&sftl.gc.BufZone, (void**)&sftl.gc.meta); + WMR_BufZone_FinishedRebases(&sftl.gc.BufZone); + + sftl.gc.vbas = (UInt32*)WMR_MALLOC(sftl.gc.zoneSize * sizeof(UInt32)); + sftl.gc.lbas = (UInt32*)WMR_MALLOC(sftl.gc.zoneSize * sizeof(UInt32)); + sftl.gc.uecc = (UInt32*)WMR_MALLOC(((sftl.gc.zoneSize+31)/32) * sizeof(UInt32)); + + // Init write-multi + sftl.gc.wm.lba = (UInt32*) WMR_MALLOC(sftl.gc.zoneSize * sizeof(UInt32)); + sftl.gc.wm.subCount = (UInt32*)WMR_MALLOC(sftl.gc.zoneSize * sizeof(UInt32)); + + for (ctx = 0; ctx < S_GC_NUM_CTX; ctx++) { + if (NULL == sftl.gc.ctx[ctx].BTOC) { + return FALSE32; + } + } + if ((NULL == sftl.gc.meta_buf) + || (NULL == sftl.gc.zone) || (NULL == sftl.gc.meta) + || (NULL == sftl.gc.lbas) || (NULL == sftl.gc.vbas) + || (NULL == sftl.gc.uecc) + || (NULL == sftl.gc.wm.lba) || (NULL == sftl.gc.wm.subCount) + ) + { + return FALSE32; + } + + return TRUE32; +} + +void s_gc_close() +{ + WMR_BufZone_Free(&sftl.gc.BufZone); + + if (NULL != sftl.gc.lbas) { + WMR_FREE(sftl.gc.lbas, sftl.gc.zoneSize * sizeof(UInt32)); + } + if (NULL != sftl.gc.vbas) { + WMR_FREE(sftl.gc.vbas, sftl.gc.zoneSize * sizeof(UInt32)); + } + if (NULL != sftl.gc.uecc) { + WMR_FREE(sftl.gc.uecc, ((sftl.gc.zoneSize+31)/32) * sizeof(UInt32)); + } + if (NULL != sftl.gc.wm.lba) { + WMR_FREE(sftl.gc.wm.lba, sftl.gc.zoneSize * sizeof(UInt32)); + } + if (NULL != sftl.gc.wm.subCount) { + WMR_FREE(sftl.gc.wm.subCount, sftl.gc.zoneSize * sizeof(UInt32)); + } + + WMR_MEMSET(&sftl.gc, 0, sizeof(sftl.gc)); +} + +#ifndef AND_READONLY + +void s_gc_for_flatten(UInt32 writeSize) +{ + while (dangerousData(writeSize)) + { + GCMachine_Data(writeSize, TRUE32, S_GC_CTX_FG); + } +} + + +BOOL32 s_gc_slice(UInt32 ctx) +{ + UInt32 writeSize = sftl.gc.zoneSize; + BOOL32 status = FALSE32; + + s_dbg_check_data_counts(); + s_dbg_check_sb_dist(); + sftl.gc.ctx[ctx].in_sb = 0xffffffff; + + // Below low low low mark? + if ((ctx == S_GC_CTX_FG) && dangerousData(writeSize)) + { + GCMachine_Data(writeSize, TRUE32, ctx); + status = TRUE32; + } + + s_dbg_check_sb_dist(); + + // If we're low on space, or the garbage collector is not idle, (-> this is important to not cause hangs) + if ((status == FALSE32) && (((ctx == S_GC_CTX_FG) && idleLowData(writeSize)) || (GCD_IDLE != sftl.gc.ctx[ctx].state) || !s_WorkFifo_isEmpty(&sftl.gc.ctx[ctx].workFifo))) + { + GCMachine_Data(writeSize, TRUE32, ctx); + status = TRUE32; + } + + s_dbg_check_sb_dist(); + return status; +} + +void s_gc_prewrite(UInt32 writeSize) +{ + s_dbg_check_data_counts(); + s_dbg_check_sb_dist(); + sftl.gc.ctx[S_GC_CTX_FG].in_sb = 0xffffffff; + + // Below low low low mark? + while (dangerousData(writeSize)) + { + GCMachine_Data(writeSize, TRUE32, S_GC_CTX_FG); + } + + s_dbg_check_sb_dist(); + + // If we're low on space, or the garbage collector is not idle, (-> this is important to not cause hangs) + if (lowData(writeSize) || (GCD_IDLE != sftl.gc.ctx[S_GC_CTX_FG].state) || !s_WorkFifo_isEmpty(&sftl.gc.ctx[S_GC_CTX_FG].workFifo)) + { + GCMachine_Data(writeSize, TRUE32, S_GC_CTX_FG); + } + + s_dbg_check_sb_dist(); +} + +void s_gc_bg(UInt32 writeSize) +{ + s_dbg_check_data_counts(); + s_dbg_check_sb_dist(); + sftl.gc.ctx[S_GC_CTX_BG].in_sb = 0xffffffff; + + // Below low low low mark? + if (dangerousData(writeSize)) + { + // Get out + return; + } + + s_dbg_check_sb_dist(); + + // If the garbage collector is not idle, (-> this is important to not cause hangs) + if ((GCD_IDLE != sftl.gc.ctx[S_GC_CTX_BG].state) || !s_WorkFifo_isEmpty(&sftl.gc.ctx[S_GC_CTX_BG].workFifo)) + { + GCMachine_Data(writeSize, TRUE32, S_GC_CTX_BG); + } + + s_dbg_check_sb_dist(); +} + +void s_gc_bg_shutdown(void) +{ + s_dbg_check_data_counts(); + s_dbg_check_sb_dist(); + sftl.gc.ctx[S_GC_CTX_BG].in_sb = 0xffffffff; + + // If we're low on space, or the garbage collector is not idle, (-> this is important to not cause hangs) + while ((GCD_IDLE != sftl.gc.ctx[S_GC_CTX_BG].state) || !s_WorkFifo_isEmpty(&sftl.gc.ctx[S_GC_CTX_BG].workFifo)) + { + // Below low low low mark? + if (dangerousData(0)) + { + // Get out + return; + } + + s_dbg_check_sb_dist(); + + GCMachine_Data(0, TRUE32, S_GC_CTX_BG); + } + + s_dbg_check_sb_dist(); +} + +static void MoveOnIfCurrentD(UInt32 inBlock) +{ + // Is it the current data block? + if (S_SB_DATA_CUR == sftl.sb[inBlock].type) + { + s_sb_next_from_sb(inBlock); + } +} + + +// Data state machine: +// 1) choose block +// 2) read TOC or reconstruct +// 3) [loop] find valid spans, move preferentially in chunks of sequentiality +// 4) sanity check +// 5) erase block + + +static void GCMachine_Data(Int32 writeSize, BOOL32 scrubOnUECC, UInt32 ctx) +{ + GC_Ctx_t *const c = &sftl.gc.ctx[ctx]; + ANDStatus status; + UInt32 cost; + + sftl.gc.inProgress = TRUE32; + again: + WMR_TRACE_IST_3(GCMachine, START, writeSize, scrubOnUECC, c->state); + switch (c->state) + { + case GCD_IDLE: + if (!idleLowData(writeSize) && s_WorkFifo_isEmpty(&c->workFifo) && (0xffffffff == c->in_sb)) { + // Nothing to do... get out + break; + } + if ((S_GC_CTX_BG == ctx) && s_WorkFifo_isEmpty(&c->workFifo)) { + // BG writes shouldn't search for invalid + break; + } + + sftl.stats.data_gc++; + ChooseSB(ctx); + if (0 == c->chosenValid) + { + sftl.stats.zero_valid_cross++; + c->state = GCD_ERASE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + c->vba = s_g_addr_to_vba(c->sb, 0); + c->done = FALSE32; + s_btoc_read(c->sb, c->BTOC, &c->BTOC_len, FALSE32, scrubOnUECC); + c->curBteIdx = 0; + s_sb_set_type(c->sb, S_SB_DATA_GC); + c->state = GCD_EVICT; + c->ueccCounter = 0; + // Drain so GC batches prefer to be aligned + s_drain_stream_all(FALSE32); + + // Fall through to GCD_EVICT + + case GCD_EVICT: + // Check if it's been invalidated by host writes since we entered the state machine + if (0 == s_sb_get_validLbas(c->sb)) + { + // And short-circuit to the ERASE state + c->state = GCD_ERASE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + cost = sftl.gc.zoneSize; + if (S_GC_CTX_BG == ctx) { + // BG writes should be 10% of the bandwidth, rounded up + cost = (writeSize / 10) + sftl.gc.zoneSize - 1; + cost -= cost % sftl.gc.zoneSize; + } else if (writeSize > 0) { + if (c->invalidHistSize) { + cost = (c->invalidHistSum / c->invalidHistSize); // Divisor + } else { + cost = 1; + } + if (!cost) + { + cost = (writeSize * c->chosenSize); // Avoid div0 when we move a full block + } + cost = (writeSize * c->chosenSize) / cost; + // Round up to a zone boundary (makes no sense to do less!) + cost += sftl.gc.zoneSize - 1; + cost -= cost % sftl.gc.zoneSize; + } + + s_drain_stream_all(FALSE32); // for coherency + status = EvictData(cost, scrubOnUECC, ctx); + if (ANDErrorCodeOk != status) + { + if (GCD_EVICT == c->state) { + c->state = GCD_IDLE; + } + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + if ((0 == s_sb_get_validLbas(c->sb)) || c->done) + { + if (0 != s_sb_get_validLbas(c->sb)) { + // Drain, to make sure all LBAs get written and thus L2V updated + s_drain_stream_all(FALSE32); + } + SanityCheckValid(ctx); + + // Short-circuit to the ERASE state + c->state = GCD_ERASE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + break; + + case GCD_ERASE: + SanityCheckValid(ctx); + EraseData(c->sb); + c->state = GCD_IDLE; + break; + + default: + WMR_PANIC("unknown gc state %d", c->state); + } + WMR_TRACE_IST_0(GCMachine, END); +} + +void s_gc_data_enq(UInt32 sb, UInt32 ctx) +{ + WMR_TRACE_IST_1(GCDataEnq, NONE, sb); + s_WorkFifo_Enq(&sftl.gc.ctx[ctx].workFifo, sb); +} + +ANDStatus s_gc_data(UInt32 sb, BOOL32 scrubOnUECC) +{ + UInt32 ctx = S_GC_CTX_FG; + + WMR_TRACE_IST_2(GCData, START, sb, scrubOnUECC); + + s_dbg_check_sb_dist(); + + // Kill any previous GC operations + // This makes GC recovery from write fail more safe + if (GCD_IDLE != sftl.gc.ctx[S_GC_CTX_FG].state) { + // Un-mark pending GC operations + if ((0xffffffff != sftl.gc.ctx[S_GC_CTX_FG].sb) && (S_SB_DATA_GC == sftl.sb[sftl.gc.ctx[S_GC_CTX_FG].sb].type)) { + sftl.sb[sftl.gc.ctx[S_GC_CTX_FG].sb].type = S_SB_DATA; + } + } + sftl.gc.ctx[ctx].state = GCD_IDLE; + +again: + // Set up the new one + sftl.gc.ctx[ctx].in_sb = sb; + + // And start it + do + { + GCMachine_Data(0, scrubOnUECC, ctx); + } + while (GCD_IDLE != sftl.gc.ctx[ctx].state); + + if (!s_WorkFifo_isEmpty(&sftl.gc.ctx[ctx].workFifo)) + { + sb = s_WorkFifo_Deq(&sftl.gc.ctx[ctx].workFifo); + goto again; + } + + s_dbg_check_sb_dist(); + + WMR_TRACE_IST_1(GCData, END, ANDErrorCodeOk); + sftl.gc.inProgress = FALSE32; + return ANDErrorCodeOk; +} + +BOOL32 s_gc_move_advisable(void) +{ + return !dangerousData(s_g_vbas_per_sb); +} + +static void ChooseSB(UInt32 ctx) +{ + UInt32 i, type; + UInt32 thisValid, thisMerit, thisErases; + UInt32 best, bestMerit, bestValid, bestErases; + GC_Ctx_t *c = &sftl.gc.ctx[ctx]; + + best = bestMerit = bestValid = bestErases = 0xFFFFFFFF; + + if (0xffffffff != c->in_sb) { + MoveOnIfCurrentD(c->in_sb); + } + + if (!s_WorkFifo_isEmpty(&c->workFifo)) + { + if (0xffffffff != c->in_sb) + { + s_WorkFifo_Enq(&c->workFifo, c->in_sb); + } + c->in_sb = s_WorkFifo_Deq(&c->workFifo); + } else { + // BG shouldn't have any choice + WMR_ASSERT(S_GC_CTX_BG != ctx); + } + + if (0xffffffff != c->in_sb) + { + c->sb = c->in_sb; + c->chosenValid = s_sb_get_validLbas(c->in_sb); + c->chosenErases = s_sb_get_erases(c->in_sb); + type = s_sb_get_type(c->in_sb); + WMR_ASSERT((type == S_SB_DATA) || (type == S_SB_DATA_CUR) || (type == S_SB_DATA_GC) || (type == S_SB_DATA_PENDING_GC)); + c->in_sb = 0xffffffff; + MoveOnIfCurrentD(c->sb); + return; + } + + for (i = 0; i < s_g_max_sb; i++) + { + // Not a data sb? Don't consider... + if ((S_SB_DATA != s_sb_get_type(i)) + && (S_SB_DATA_PENDING_GC != s_sb_get_type(i))) + { + continue; + } + + // Grab local copies + thisValid = s_sb_get_validLbas(i); + thisMerit = (thisValid * s_g_vbas_per_sb) / sftl.vfl->GetVbasPerVb(i); + thisErases = s_sb_get_erases(i); + + // Minimize merit (sounds backwards, I know) + if ((thisMerit < bestMerit) || ((thisMerit == bestMerit) && (thisErases < bestErases))) + { + best = i; + bestMerit = thisMerit; + bestValid = thisValid; + bestErases = thisErases; + } + } + + WMR_ASSERT(best != 0xFFFFFFFF); + WMR_ASSERT(bestMerit != 0xFFFFFFFF); + WMR_ASSERT(bestErases != 0xFFFFFFFF); + + // Output + c->sb = best; + c->chosenMerit = bestMerit; + c->chosenValid = bestValid; + c->chosenErases = bestErases; + c->chosenSize = sftl.vfl->GetVbasPerVb(best); + + // Invalid history + c->invalidHistSum -= c->invalidHist[c->invalidHistIdx]; + c->invalidHist[c->invalidHistIdx] = c->chosenSize - c->chosenValid; + c->invalidHistSum += c->chosenSize - c->chosenValid; + c->invalidHistIdx++; + if (c->invalidHistIdx >= S_GC_VALIDHIST_SIZE) { + c->invalidHistIdx = 0; + } + if (c->invalidHistSize < S_GC_VALIDHIST_SIZE) { + c->invalidHistSize++; + } +} + +static void EraseData(UInt32 sb) +{ + UInt32 num_btoc_vbas; + + WMR_ASSERT(0 == s_sb_get_validLbas(sb)); + + if((S_SB_ERASED == s_sb_get_type(sb)) || (S_SB_PENDING_ERASE == s_sb_get_type(sb)) || (S_SB_ERASE_BEFORE_USE == s_sb_get_type(sb))) + return; + + // Set erase as pending + s_sb_set_reads(sb, 0); + s_sb_set_validLbas(sb, 0); + num_btoc_vbas = s_sb_get_num_btoc_vbas(sb); + s_sb_set_type(sb, num_btoc_vbas ? S_SB_ERASE_BEFORE_USE : S_SB_PENDING_ERASE); + + // Manage free/allocated counters + sftl.seaState.free_sb++; + sftl.seaState.data_sb--; + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sb); +} + +UInt32 findLba(UInt32 vba, UInt32 ctx) +{ + GC_Ctx_t *const c = &sftl.gc.ctx[ctx]; + L2V_SearchCtx_t *const read_c = &c->uecc_c; + UInt32 read_vbaEnd, lba = 0; + + while (lba < sftl.max_lba) { + read_c->lba = lba; + L2V_Search(read_c); + read_vbaEnd = read_c->vba + read_c->span; + + // Hit? + if ((read_c->vba <= vba) && (vba < read_vbaEnd)) { + return lba + (vba - read_c->vba); + } + + // Next + lba += read_c->span; + } + + return S_TOK_UECC; +} + +void findVbas(UInt32 vbaBase, UInt32 count, BOOL32 trimIfFound) +{ + L2V_SearchCtx_t *const read_c = &sftl.gc.read_c; + UInt32 read_vbaEnd, lba = 0; + UInt32 vbaEnd = vbaBase + count; + + while (lba < sftl.max_lba) { + read_c->lba = lba; + L2V_Search(read_c); + read_vbaEnd = read_c->vba + read_c->span; + + if ((vbaBase < read_vbaEnd) && (read_c->vba < vbaEnd)) + { + WMR_PRINT(ALWAYS, "Range hit: lba %d, search 0x%x-0x%x, found 0x%x-0x%x\n", lba, vbaBase, vbaEnd, read_c->vba, read_vbaEnd); + + if(trimIfFound) + { + UInt32 adjustedLba = read_c->lba; + UInt32 adjustedCount = read_c->span; + + if(read_c->vba < vbaBase) + { + adjustedLba += (vbaBase - read_c->vba); + adjustedCount -= (vbaBase - read_c->vba); + } + if(read_vbaEnd > vbaEnd) + { + adjustedCount -= (read_vbaEnd - vbaEnd); + } + L2V_Update(adjustedLba, adjustedCount, L2V_VBA_DEALLOC); + } + } + // Next + lba += read_c->span; + } +} + +static void SanityCheckValid(UInt32 ctx) +{ + GC_Ctx_t *const c = &sftl.gc.ctx[ctx]; + + // Sanity check: should now be empty... + if (c->ueccCounter < sftl.sb[c->sb].validLbas) + { + s_debug(ERROR, "GC didn't fully evict (valid:%d); finding missing data and cross-checking counters...\n", sftl.sb[c->sb].validLbas); + + findVbas(s_g_addr_to_vba(c->sb, 0), s_g_vbas_per_sb, FALSE32); + + s_dbg_check_validSums(); + s_dbg_check_data_counts(); + + WMR_PANIC("Non-zero validity counter Block %d: %d UECC: %d", + c->sb, + (UInt32) sftl.sb[c->sb].validLbas, + c->ueccCounter); + } + else + { + if(sftl.sb[c->sb].validLbas) + { + // Some data gone missing due to UECCs. Adjust validLba counter + findVbas(s_g_addr_to_vba(c->sb, 0), s_g_vbas_per_sb, TRUE32); + sftl.seaState.validLbas -= sftl.sb[c->sb].validLbas; + sftl.sb[c->sb].validLbas = 0; + } + } +} + +BOOL32 s_gc_inject(UInt32 lba, UInt32 count) +{ + L2V_SearchCtx_t *const read_c = &sftl.gc.read_c; + UInt32 origCount = count, thisCount, curCount; + + while (count) { + thisCount = WMR_MIN(count, sftl.gc.zoneSize - sftl.gc.curZoneSize); + + // Set up zone + ZoneSetup(TRUE32); + while (sftl.gc.curZoneSize < thisCount) { + read_c->lba = lba; + L2V_Search(read_c); + curCount = WMR_MIN(thisCount - sftl.gc.curZoneSize, read_c->span); + ZoneAdd(lba, read_c->vba, curCount); + + // Next + lba += curCount; + count -= curCount; + } + + // Move it + if (!MoveZone(TRUE32, TRUE32, TRUE32, S_GC_CTX_FG)) { + return FALSE32; + } + } + + // Compensate + sftl.stats.lbas_gc -= origCount; + + return TRUE32; +} + +static ANDStatus EvictData(UInt32 minAmount, BOOL32 scrubOnUECC, UInt32 ctx) +{ + GC_Ctx_t *const c = &sftl.gc.ctx[ctx]; + L2V_SearchCtx_t *const read_c = &sftl.gc.read_c; + UInt32 evictedLbas = 0; + UInt32 thisCount; + s_btoc_entry_t *bte; + UInt32 status; + + // Clear out search cxt since things have happened since the last call + ZoneSetup(scrubOnUECC); + + do { + // Consider the current bte + bte = &c->BTOC[c->curBteIdx]; + if ((c->curBteIdx >= c->BTOC_len) || (0 == s_sb_get_validLbas(c->sb))) { + // Reached the end of the BTOC, or moved all of the valid data? + c->done = TRUE32; + goto evictExit; + } + + // uECC? + if (S_TOK_UECC == bte->lba) { + // Find which LBA lives here: + bte->lba = findLba(c->vba, ctx); + } + + // Search tree + if (S_TOKEN_LBA_BASE <= bte->lba) { + read_c->vba = 0xffffffff; + read_c->span = bte->count; + } else if ((0 == read_c->span) || (read_c->lba != bte->lba)) { + read_c->lba = bte->lba; + L2V_Search(read_c); + } + WMR_ASSERT(0 != read_c->span); + + thisCount = WMR_MIN((UInt32)bte->count, (UInt32)read_c->span); + if (read_c->vba == c->vba) { + // Hit! + // How much can we read into the zone? + thisCount = WMR_MIN(thisCount, sftl.gc.zoneSize - sftl.gc.curZoneSize); + + // Throw spans into zone + WMR_ASSERT(0 != thisCount); + ZoneAdd(bte->lba, c->vba, thisCount); + evictedLbas += thisCount; + } + + // Next + bte->count -= thisCount; + if (S_TOKEN_LBA_BASE > bte->lba) { + bte->lba += thisCount; + } + c->vba += thisCount; + read_c->span -= thisCount; + + // Move bte along? + if (0 == bte->count) { + c->curBteIdx++; + } + +evictExit: + // Zone full, or done? + if (c->done || (sftl.gc.curZoneSize == sftl.gc.zoneSize) || (evictedLbas >= minAmount)) { + status = MoveZone(FALSE32, FALSE32, scrubOnUECC, ctx); + if (!status) { + s_write_reseq(); + s_WorkFifo_Enq(&c->workFifo, c->sb); + s_WorkFifo_Enq(&c->workFifo, sftl.write.stream[sftl.write.curStream].sb); + s_sb_next_cur(); + return ANDErrorCodeHwErr; + } + ZoneSetup(scrubOnUECC); + } + } while ((evictedLbas < minAmount) && !c->done); + + return ANDErrorCodeOk; +} + +static void ZoneSetup(BOOL32 scrubOnUECC) +{ + s_write_multi_t *const wm = &sftl.gc.wm; + L2V_SearchCtx_t *const read_c = &sftl.gc.read_c; + UInt32 i; + + wm->len = 0; + sftl.gc.curZoneSize = 0; + for (i = 0; i < sftl.gc.zoneSize; i += 32) { + sftl.gc.uecc[i>>5] = 0; + } + read_c->span = 0; + sftl.vfl->ReadSpansInit(&sftl.gc.rs, ReadZone_cb, (VFL_READ_STATUS_UECC|VFL_READ_STATUS_CLEAN), TRUE32, scrubOnUECC); +} + +static void ZoneAdd(UInt32 lba, UInt32 vba, UInt32 count) +{ + s_write_multi_t *const wm = &sftl.gc.wm; + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + VFL_ReadSpans_t *const rs = &sftl.gc.rs; + UInt32 i; + + WMR_ASSERT(0 != count); + + if (L2V_VBA_SPECIAL > vba) { + // Real data; read spattered + sftl.vfl->ReadSpansAdd(rs, vba, count, &sftl.gc.zone[s_g_mul_bytes_per_lba(sftl.gc.curZoneSize)], (UInt8*)&sftl.gc.meta[sftl.gc.curZoneSize]); + for (i = 0; i < count; i++) { + sftl.gc.lbas[sftl.gc.curZoneSize+i] = lba + i; + sftl.gc.vbas[sftl.gc.curZoneSize+i] = vba + i; + } + } else { + // Trimmed content? Setup metadata + WMR_ASSERT(L2V_VBA_DEALLOC == vba); + s_SetupMeta_Trim(&sftl.gc.meta[sftl.gc.curZoneSize], lba, count, wr->pageFlags); + WMR_WRITE_TRIM(&sftl.gc.zone[s_g_mul_bytes_per_lba(sftl.gc.curZoneSize)], s_g_bytes_per_lba, count); + for (i = 0; i < count; i++) { + sftl.gc.lbas[sftl.gc.curZoneSize+i] = lba + i; + sftl.gc.vbas[sftl.gc.curZoneSize+i] = 0xffffffff; + } + } + + // Add to write multi + wm->lba[wm->len] = lba; + wm->subCount[wm->len] = count; + wm->len++; + + // Accumulate to zone size + sftl.gc.curZoneSize += count; +} + +static BOOL32 MoveZone(BOOL32 dynStream, BOOL32 forFlatten, BOOL32 scrubOnUECC, UInt32 ctx) +{ + s_write_multi_t *const wm = &sftl.gc.wm; + UInt32 staticness; + + if (0 == sftl.gc.curZoneSize) { + // Simplify caller logic--no work->success + return TRUE32; + } + + // Read the GC zone + ReadZone(scrubOnUECC, ctx); + + // Analyze zone for staticness, and lba mismatches; switch stream at 50% point + staticness = AnalyzeZone(); + if (dynStream) { + staticness = 0; + } + if (S_GC_CTX_FG == ctx) { + s_write_gc_switch(((staticness << 1) >= sftl.gc.curZoneSize) ? S_SBSTREAM_STATIC : S_SBSTREAM_DYN); + } else { + s_write_gc_switch(S_SBSTREAM_WEARLEV); + } + + // Set up the write multi + wm->gc = TRUE32; + wm->flatten = forFlatten; + wm->buf = sftl.gc.zone; + wm->meta = sftl.gc.meta; + wm->count = sftl.gc.curZoneSize; + wm->cur = 0; + wm->padding = FALSE32; + + sftl.stats.lbas_gc += sftl.gc.curZoneSize; + sftl.gc.curZoneSize = 0; + + return s_write_multi_internal(wm); +} + +static void ScrubZone(void) +{ + UInt32 i, lba; + + for (i = 0; i < sftl.gc.curZoneSize; i++) { + lba = META_GET_LBA(&sftl.gc.meta[i]); + // LBA in page out of range? + if (lba >= sftl.max_lba) { + // Stomp it + if (WMR_I_CAN_HAZ_DEBUGGER()) { + if (!(((sftl.gc.uecc[i>>5]) >> (i&31)) & 1)) { + WMR_PANIC("lba:%d out of range in GC; stomping to lba:%d", lba, sftl.gc.lbas[i]); + } + } else { + WMR_PRINT(ALWAYS, "lba:%d out of range in GC; stomping to lba:%d", lba, sftl.gc.lbas[i]); + } + s_SetupMeta_Data_UECC(&sftl.gc.meta[i], sftl.gc.lbas[i]); + } + } +} + +static void ReadZone_cb(UInt32 vba, VFLReadStatusType status, UInt8 *meta) +{ + UInt32 idx; + + if (status & VFL_READ_STATUS_UNIDENTIFIED) { + WMR_PRINT(QUAL_FATAL, "gc read got unidentified read status (0x%x) on vba:0x%x; did we get a timeout? Pretending it was uECC.\n", status, vba); + status = (status & ~VFL_READ_STATUS_UNIDENTIFIED) | VFL_READ_STATUS_UECC; + } + + if ((status & VFL_READ_STATUS_UECC) || (status & VFL_READ_STATUS_CLEAN)) { + idx = ((PageMeta_t*)meta) - sftl.gc.meta; + sftl.gc.uecc[idx>>5] |= (1 << (idx&31)); + } +} + +static void ReadZone(BOOL32 scrubOnUECC, UInt32 ctx) +{ + BOOL32 status; + UInt32 i; + UInt32 j; + UInt32 sb; + // Handling uECCs, trying older data: + BOOL32 failed, rereadOrig; + UInt32 srcVba; + + if (0 == sftl.gc.rs.len) { + // Empty rs state--writing all trimmed data + return; + } + + status = sftl.vfl->ReadSpans(&sftl.gc.rs); + + if (status & (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN)) { + + // iterate along failures find uECCs; + for (i = 0; i < sftl.gc.curZoneSize; i++) { + if (sftl.gc.uecc[i>>5] & (1 << (i&31))) { + // any of them map to the current block? If so, get out + sb = s_g_vba_to_sb(sftl.gc.vbas[i]); + for (j = 0; j < S_SBSTREAM_MAX; j++) { + if (sftl.write.stream[j].sb == sb) { + sftl.write.stream[j].abandon = TRUE32; + } + } + + failed = TRUE32; + srcVba = s_btoc_getSrc(sftl.gc.vbas[i]); + // try to reread from prior location; + if (0xffffffff != srcVba) { + const VFLReadStatusType vfl_status_mask = (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN | + VFL_READ_STATUS_VALID_DATA | VFL_READ_STATUS_UNIDENTIFIED); + const VFLReadStatusType vfl_status_expected = VFL_READ_STATUS_VALID_DATA; + VFLReadStatusType vfl_status; + + vfl_status = sftl.vfl->ReadMultipleVbas(srcVba, 1, &sftl.gc.zone[s_g_bytes_per_lba * i], (UInt8*)&sftl.gc.meta[i], TRUE32, scrubOnUECC); + rereadOrig = FALSE32; + + if ((vfl_status & vfl_status_mask) != vfl_status_expected) { + rereadOrig = TRUE32; + } + // if fail or LBA doesn't match, reread from original uECC spot, and mark meta as UECC + if (rereadOrig || (!rereadOrig && (sftl.gc.lbas[i] != META_GET_LBA(&sftl.gc.meta[i])))) { + vfl_status = sftl.vfl->ReadMultipleVbas(sftl.gc.vbas[i], 1, &sftl.gc.zone[s_g_bytes_per_lba * i], (UInt8*)&sftl.gc.meta[i], TRUE32, scrubOnUECC); + + if((vfl_status & vfl_status_mask) != vfl_status_expected) { + failed = FALSE32; + } + } else { + failed = FALSE32; + } + } + + if (failed) { + s_SetupMeta_Data_UECC(&sftl.gc.meta[i], sftl.gc.lbas[i]); + sftl.gc.ctx[ctx].ueccCounter++; + } + } + } + } + + ScrubZone(); + for (j = 0; j < S_SBSTREAM_MAX; j++) + { + if(sftl.write.stream[j].abandon == TRUE32) + { + s_sb_next(j); + sftl.write.stream[j].abandon = FALSE32; + } + } +} + +static UInt32 AnalyzeZone(void) +{ + s_write_multi_t *const wm = &sftl.gc.wm; + UInt32 i, j, cur, lba, staticness = 0; + + cur = j = 0; + for (i = 0; i < sftl.gc.curZoneSize; i++) { + if (META_IS_STATIC(&sftl.gc.meta[i]) || S_USERSEQ_IS_OLD(META_GET_USERSEQ(&sftl.gc.meta[i]))) { + staticness++; + } + lba = META_GET_LBA(&sftl.gc.meta[i]); + if (lba != (wm->lba[cur]+j)) { + WMR_PANIC("LBA mismatch in GC; lba: %d, meta %d", wm->lba[cur]+j, lba); + } + if (S_LBA_STATS == lba) { + // Override stats LBA data + s_stats_to_buf((UInt32*)&sftl.gc.zone[s_g_mul_bytes_per_lba(i)]); + } + + // Next lba + j++; + if (j >= wm->subCount[cur]) { + j = 0; + cur++; + } + } + + return staticness; +} + +extern void s_gc_zeroValidCross(void) +{ + GC_Ctx_t *c = &sftl.gc.ctx[S_GC_CTX_FG]; + + if (sftl.gc.inProgress) { + return; + } + + // Invalid history + c->invalidHistSum -= c->invalidHist[c->invalidHistIdx]; + c->invalidHist[c->invalidHistIdx] = s_g_vbas_per_sb; + c->invalidHistSum += s_g_vbas_per_sb; + c->invalidHistIdx++; + if (c->invalidHistIdx >= S_GC_VALIDHIST_SIZE) { + c->invalidHistIdx = 0; + } + if (c->invalidHistSize < S_GC_VALIDHIST_SIZE) { + c->invalidHistSize++; + } +} + +#endif // AND_READONLY diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.h new file mode 100644 index 0000000..cd7d578 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_gc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __S_GC_H__ +#define __S_GC_H__ + +#include "s_internal.h" + +// Defines +#define lowData(adjust) ((sftl.seaState.vbas_in_free_sb+sftl.write.sum_gcDataAdjust) < ((s_g_vbas_per_sb * (S_GC_FREE_THRESHOLD + S_GC_LOW_GAP + sftl.cxt.cxt_sbs)) + (adjust))) +#define idleLowData(adjust) ((sftl.seaState.vbas_in_free_sb+sftl.write.sum_gcDataAdjust) < ((s_g_vbas_per_sb * (S_GC_FREE_THRESHOLD + S_GC_IDLELOW_GAP + sftl.cxt.cxt_sbs)) + (adjust))) +#define dangerousData(adjust) ((sftl.seaState.vbas_in_free_sb+sftl.write.sum_gcDataAdjust) < ((s_g_vbas_per_sb * (S_GC_FREE_THRESHOLD + sftl.cxt.cxt_sbs)) + (adjust))) + +// General setup/close +extern BOOL32 s_gc_init(void); +extern void s_gc_close(void); + +// Called by Write +extern void s_gc_prewrite(UInt32 writeSize); +extern void s_gc_bg(UInt32 writeSize); +extern void s_gc_for_flatten(UInt32 writeSize); +extern void s_gc_bg_shutdown(void); + +// For error recovery +extern void s_gc_data_enq(UInt32 sb, UInt32 ctx); + +// Direct access to the machines +extern ANDStatus s_gc_data(UInt32 sb, BOOL32 scrubOnUECC); +extern BOOL32 s_gc_move_advisable(void); + +extern BOOL32 s_gc_inject(UInt32 lba, UInt32 count); +extern void s_gc_zeroValidCross(void); +extern BOOL32 s_gc_slice(UInt32 ctx); +extern BOOL32 s_WorkFifo_isEmpty(GC_Fifo_t *f); +extern BOOL32 s_WorkFifo_isFullish(GC_Fifo_t *f); + +#endif // #ifndef __S_GC_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.c new file mode 100644 index 0000000..99041a6 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_geom.h" + +#ifndef AND_READONLY +UInt32 (*s_g_mul_bytes_per_lba)(UInt32 num); +UInt32 (*s_g_mul_bytes_per_lba_meta)(UInt32 num); +UInt32 (*s_g_addr_to_vba)(UInt32 sb, UInt32 vbaOfs); +UInt32 (*s_g_vba_to_sb)(UInt32 vba); +UInt32 (*s_g_vba_to_vbaOfs)(UInt32 vba); +UInt32 (*s_g_div_bytes_per_page)(UInt32 num); +UInt32 (*s_g_mul_vbas_per_page)(UInt32 num); +UInt32 (*s_g_div_vbas_per_stripe)(UInt32 num); +UInt32 (*s_g_mod_vbas_per_stripe)(UInt32 num); + +UInt32 s_g_mul_bytes_per_lba_shift(UInt32 num) +{ + return num << sftl.__geom.bytes_per_lba_shift; +} + +UInt32 s_g_mul_bytes_per_lba_meta_shift(UInt32 num) +{ + return num << sftl.__geom.bytes_per_lba_meta_shift; +} + +UInt32 s_g_addr_to_vba_shift(UInt32 sb, UInt32 vbaOfs) +{ + return (sb << sftl.__geom.vbas_per_sb_shift) + vbaOfs; +} + +UInt32 s_g_vba_to_sb_shift(UInt32 vba) +{ + return vba >> sftl.__geom.vbas_per_sb_shift; +} + +UInt32 s_g_vba_to_vbaOfs_shift(UInt32 vba) +{ + return vba & ((1 << sftl.__geom.vbas_per_sb_shift) - 1); +} + +UInt32 s_g_div_bytes_per_page_shift(UInt32 num) +{ + return num >> sftl.__geom.bytes_per_page_shift; +} + +UInt32 s_g_mul_vbas_per_page_shift(UInt32 num) +{ + return num << sftl.__geom.vbas_per_page_shift; +} + +UInt32 s_g_div_vbas_per_stripe_shift(UInt32 num) +{ + return num >> sftl.__geom.vbas_per_stripe_shift; +} + +UInt32 s_g_mod_vbas_per_stripe_and(UInt32 num) +{ + return num & (sftl.__geom.vbas_per_stripe-1); +} + +UInt32 s_g_mul_bytes_per_lba_mul(UInt32 num) +{ + return num * sftl.__geom.bytes_per_lba; +} + +UInt32 s_g_mul_bytes_per_lba_meta_mul(UInt32 num) +{ + return num * sftl.__geom.bytes_per_lba_meta; +} + +UInt32 s_g_addr_to_vba_mul(UInt32 sb, UInt32 vbaOfs) +{ + return (sb * sftl.__geom.vbas_per_sb) + vbaOfs; +} + +UInt32 s_g_vba_to_sb_div(UInt32 vba) +{ + return vba / sftl.__geom.vbas_per_sb; +} + +UInt32 s_g_vba_to_vbaOfs_div(UInt32 vba) +{ + return vba % sftl.__geom.vbas_per_sb; +} + +UInt32 s_g_div_bytes_per_page_div(UInt32 num) +{ + return num / sftl.__geom.bytes_per_page; +} + +UInt32 s_g_mul_vbas_per_page_mul(UInt32 num) +{ + return num * sftl.__geom.vbas_per_page; +} + +UInt32 s_g_div_vbas_per_stripe_div(UInt32 num) +{ + return num / sftl.__geom.vbas_per_stripe; +} + +UInt32 s_g_mod_vbas_per_stripe_mod(UInt32 num) +{ + return num % sftl.__geom.vbas_per_stripe; +} + +BOOL32 s_can_ffs(UInt32 num) +{ + return 0 == (num & (num - 1)); +} + +UInt32 s_ffs(UInt32 num) +{ + UInt32 shift = 0; + WMR_ASSERT(0 == (num & (num - 1))); + + while (num > 1) { + shift++; + num >>= 1; + } + + return shift; +} +#endif // AND_READONLY + +void s_geom_init(void) +{ + sftl.__geom.pages_per_sb = sftl.vfl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + sftl.__geom.max_sb = sftl.vfl->GetDeviceInfo(AND_DEVINFO_NUM_OF_USER_SUBLK); + sftl.__geom.vfl_max_sb = sftl.vfl->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CAU); + sftl.__geom.bytes_per_page = sftl.vfl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + sftl.__geom.vbas_per_page = sftl.vfl->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + sftl.__geom.vbas_per_sb = sftl.__geom.pages_per_sb * sftl.__geom.vbas_per_page; + sftl.__geom.bytes_per_lba = sftl.__geom.bytes_per_page / sftl.__geom.vbas_per_page; + sftl.__geom.bytes_per_lba_meta = sftl.vfl->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + sftl.__geom.num_banks = sftl.vfl->GetDeviceInfo(AND_DEVINFO_NUM_OF_BANKS); + sftl.__geom.vbas_per_stripe = s_g_num_banks * s_g_vbas_per_page; + +#ifndef AND_READONLY + // Bytes per lba: + if (s_can_ffs(sftl.__geom.bytes_per_lba)) { + sftl.__geom.bytes_per_lba_shift = s_ffs(sftl.__geom.bytes_per_lba); + s_g_mul_bytes_per_lba = &s_g_mul_bytes_per_lba_shift; + } else { + s_g_mul_bytes_per_lba = &s_g_mul_bytes_per_lba_mul; + } + + // Bytes per page: + if (s_can_ffs(sftl.__geom.bytes_per_page)) { + sftl.__geom.bytes_per_page_shift = s_ffs(sftl.__geom.bytes_per_page); + s_g_div_bytes_per_page = &s_g_div_bytes_per_page_shift; + } else { + s_g_div_bytes_per_page = &s_g_div_bytes_per_page_div; + } + + // Bytes per lba META: + if (s_can_ffs(sftl.__geom.bytes_per_lba_meta)) { + sftl.__geom.bytes_per_lba_meta_shift = s_ffs(sftl.__geom.bytes_per_lba_meta); + s_g_mul_bytes_per_lba_meta = &s_g_mul_bytes_per_lba_meta_shift; + } else { + s_g_mul_bytes_per_lba_meta = &s_g_mul_bytes_per_lba_meta_mul; + } + + // VBAs per sb: + if (s_can_ffs(sftl.__geom.vbas_per_sb)) { + sftl.__geom.vbas_per_sb_shift = s_ffs(sftl.__geom.vbas_per_sb); + s_g_addr_to_vba = &s_g_addr_to_vba_shift; + s_g_vba_to_sb = &s_g_vba_to_sb_shift; + s_g_vba_to_vbaOfs = &s_g_vba_to_vbaOfs_shift; + } else { + s_g_addr_to_vba = &s_g_addr_to_vba_mul; + s_g_vba_to_sb = &s_g_vba_to_sb_div; + s_g_vba_to_vbaOfs = &s_g_vba_to_vbaOfs_div; + } + + // VBAs per page: + if (s_can_ffs(sftl.__geom.vbas_per_page)) { + sftl.__geom.vbas_per_page_shift = s_ffs(sftl.__geom.vbas_per_page); + s_g_mul_vbas_per_page = &s_g_mul_vbas_per_page_shift; + } else { + s_g_mul_vbas_per_page = &s_g_mul_vbas_per_page_mul; + } + + // VBAS per stripe: + if (s_can_ffs(sftl.__geom.vbas_per_stripe)) { + sftl.__geom.vbas_per_stripe_shift = s_ffs(sftl.__geom.vbas_per_stripe); + s_g_div_vbas_per_stripe = &s_g_div_vbas_per_stripe_shift; + s_g_mod_vbas_per_stripe = &s_g_mod_vbas_per_stripe_and; + } else { + s_g_div_vbas_per_stripe = &s_g_div_vbas_per_stripe_div; + s_g_mod_vbas_per_stripe = &s_g_mod_vbas_per_stripe_mod; + } +#endif // AND_READONLY + + // Sanity-check meta size: + if (sizeof(PageMeta_t) != sftl.__geom.bytes_per_lba_meta) { + WMR_PANIC("sftl meta struct size (%d) not equal to bytes per metadata (%d)", sizeof(PageMeta_t), sftl.__geom.bytes_per_lba_meta); + } +} + + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.h new file mode 100644 index 0000000..f2fe3a3 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_geom.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __SFTL_GEOM_H__ +#define __SFTL_GEOM_H__ + +#include "s_internal.h" + +#define s_g_bytes_per_page (sftl.__geom.bytes_per_page+0) +#define s_g_bytes_per_lba (sftl.__geom.bytes_per_lba+0) +#define s_g_bytes_per_lba_meta (sftl.__geom.bytes_per_lba_meta+0) +#define s_g_vbas_per_sb (sftl.__geom.vbas_per_sb+0) +#define s_g_vbas_per_page (sftl.__geom.vbas_per_page+0) +#define s_g_max_pages_per_btoc (sftl.__geom.max_pages_per_btoc+0) +#define s_g_max_sb (sftl.__geom.max_sb+0) +#define s_g_vfl_max_sb (sftl.__geom.vfl_max_sb+0) +#define s_g_num_banks (sftl.__geom.num_banks+0) +#define s_g_vbas_per_stripe (sftl.__geom.vbas_per_stripe+0) + +extern void s_geom_init(void); + +#ifndef AND_READONLY + +extern UInt32 (*s_g_mul_bytes_per_lba)(UInt32 num); +extern UInt32 (*s_g_mul_bytes_per_lba_meta)(UInt32 num); +extern UInt32 (*s_g_addr_to_vba)(UInt32 sb, UInt32 vbaOfs); +extern UInt32 (*s_g_vba_to_sb)(UInt32 vba); +extern UInt32 (*s_g_vba_to_vbaOfs)(UInt32 vba); +extern UInt32 (*s_g_div_bytes_per_page)(UInt32 num); +extern UInt32 (*s_g_mul_vbas_per_page)(UInt32 num); +extern UInt32 (*s_g_div_vbas_per_stripe)(UInt32 num); +extern UInt32 (*s_g_mod_vbas_per_stripe)(UInt32 num); + +#else // AND_READONLY + +#define s_g_mul_bytes_per_lba(x) ((x) * sftl.__geom.bytes_per_lba) +#define s_g_mul_bytes_per_lba_meta(x) ((x) * sftl.__geom.bytes_per_lba_meta) +#define s_g_addr_to_vba(x, y) (((x) * sftl.__geom.vbas_per_sb) + (y)) +#define s_g_vba_to_sb(x) ((x) / sftl.__geom.vbas_per_sb) +#define s_g_vba_to_vbaOfs(x) ((x) % sftl.__geom.vbas_per_sb) +#define s_g_div_bytes_per_page(x) ((x) / sftl.__geom.bytes_per_page) +#define s_g_mul_vbas_per_page(x) ((x) * sftl.__geom.vbas_per_page) +#define s_g_div_vbas_per_stripe(x) ((x) / sftl.__geom.vbas_per_stripe) +#define s_g_mod_vbas_per_stripe(x) ((x) % sftl.__geom.vbas_per_stripe) + +#endif // AND_READONLY + +#endif // __SFTL_GEOM_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.c new file mode 100644 index 0000000..2478e51 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_internal.h" +#include "s_read.h" +#include "s_write.h" +#include "s_trim.h" +#include "s_sb.h" +#include "s_btoc.h" +#include "s_gc.h" +#include "s_dbg.h" +#include "s_geom.h" +#include "VFL.h" +#include "s_readdist.h" +#include "s_cxt.h" + + +static UInt32 do_quantize(UInt32 target) +{ + UInt32 out; + UInt32 quant; + + // Multiply by superblock size + out = target * s_g_vbas_per_sb; + + // Quantize + quant = (1 << WMR_LOG2(out)) / S_RESERVE_QUANTIZE; + + // Adjust by a quarter to move quantization window + out += (quant / 4); + + // Quantize + out /= quant; + out *= quant; + + // Scale back + out /= s_g_vbas_per_sb; + + return out; +} + +UInt32 s_calc_lbas(BOOL32 ideal) +{ + UInt32 quantize_sb; + UInt32 target_sb; + UInt32 quantize_vfl; + UInt32 num_4gb; + UInt64 reported_bytes; + UInt32 numLba; + + if (ideal) { + // Ideal capacity is based on VFL superblocks + target_sb = s_g_vfl_max_sb; + } else { + // Otherwise, consider burnin partition size + target_sb = s_g_max_sb; + } + + quantize_sb = do_quantize(target_sb); + quantize_vfl = do_quantize(s_g_vfl_max_sb); + + // Significantly smaller than full-sized (i.e. burnin partitioned)? + if (!ideal && ((s_g_vfl_max_sb - s_g_max_sb) >= ((quantize_vfl * S_RESERVE_PERMIL_APPROX) / 1000))) { + // Then ignore quantization + numLba = (UInt32)(s_g_vbas_per_sb * target_sb); + numLba -= (UInt32)((quantize_vfl * s_g_vbas_per_sb * S_RESERVE_PERMIL_APPROX) / 1000); + } else { + // Calculate LBAs, based on power-of-ten ratio + num_4gb = (quantize_sb * s_g_vbas_per_sb * (s_g_bytes_per_lba / 1024)) / (4 * 1024 * 1024); + reported_bytes = 4000000000ULL * num_4gb; + numLba = (UInt32)((reported_bytes + s_g_bytes_per_lba - 1) / s_g_bytes_per_lba); + } + + return numLba; +} + +void s_freeMemory(void) +{ + WMR_BufZone_Free(&sftl.BufZone); + s_dbg_close(); + s_gc_close(); +#ifndef AND_READONLY + s_trim_close(); + s_write_close(); + s_readDist_close(); +#endif // AND_READONLY + s_sb_close(); + s_btoc_close(); + L2V_Free(); + WMR_MEMSET((void*)&sftl, 0, sizeof(sftl)); +} + +Int32 sftl_init(VFLFunctions *vflfuncs) +{ + UInt32 thisSize; +#ifndef AND_READONLY + UInt32 i, bufMax; +#endif // AND_READONLY + + // Do not allow multiple init() calls because number of user blocks can change + WMR_ASSERT(!sftl_init_done); + + // Format checks: + // s_btoc_entry_t + WMR_ASSERT(WMR_OFFSETOF(s_btoc_entry_t, weaveSeqAdd) == 0); + WMR_ASSERT(WMR_OFFSETOF(s_btoc_entry_t, userWeaveSeq) == 4); + WMR_ASSERT(WMR_OFFSETOF(s_btoc_entry_t, lba) == 8); + WMR_ASSERT(WMR_OFFSETOF(s_btoc_entry_t, count) == 12); + // s_sb_fmt_t + WMR_ASSERT(WMR_OFFSETOF(s_sb_fmt_t, type) == 0); + WMR_ASSERT(WMR_OFFSETOF(s_sb_fmt_t, num_btoc_vbas_AND_staticFlag) == 1); + WMR_ASSERT(WMR_OFFSETOF(s_sb_fmt_t, validLbas) == 2); + WMR_ASSERT(WMR_OFFSETOF(s_sb_fmt_t, __was_reads) == 4); + WMR_ASSERT(WMR_OFFSETOF(s_sb_fmt_t, erases) == 6); + // s_cxt_contig_t + WMR_ASSERT(WMR_OFFSETOF(s_cxt_contig_t, vba) == 0); + WMR_ASSERT(WMR_OFFSETOF(s_cxt_contig_t, span) == 4); + + // Pre-clear sftl + WMR_MEMSET((void*)&sftl, 0, sizeof(sftl)); + + sftl.vfl = vflfuncs; + + s_debug(INIT, "S_INIT[start]"); + + s_geom_init(); +#ifndef AND_READONLY + if (!s_trim_init()) { + goto errorPath; + } + s_cxt_init(); + s_readDist_init(); +#endif + + // Buffer allocations--all DMA-able buffers must be allocated here + WMR_BufZone_Init(&sftl.BufZone); +#ifndef AND_READONLY + bufMax = sftl.vfl->GetDeviceInfo(AND_DEVINFO_STREAM_BUFFER_MAX); + for (i = 0; i < S_SBSTREAM_MAX; i++) { + sftl.write.stream[i].bufSize = S_SBSTREAM_BUFSIZE(i, bufMax); + sftl.write.stream[i].bufPage = (UInt8 *)WMR_Buf_Alloc_ForDMA(&sftl.BufZone, s_g_bytes_per_lba * sftl.write.stream[i].bufSize); + sftl.write.stream[i].bufMeta = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&sftl.BufZone, sizeof(PageMeta_t) * sftl.write.stream[i].bufSize); + sftl.write.stream[i].bufThreshold = S_WRITE_LBAS_THRESHOLD(&sftl.write.stream[i]); + } + thisSize = sizeof(sftl.write.meta_size); + sftl.vfl->GetStruct(AND_STRUCT_VFL_MAX_TRANS_IN_PAGES, &sftl.write.meta_size, &thisSize); + // make sure it's a multiplication of a pefrect stripes that does not exceed AND_STRUCT_VFL_MAX_TRANS_IN_PAGES + sftl.write.meta_size = ROUNDDOWNTO(sftl.write.meta_size, s_g_num_banks); + if(sftl.write.meta_size == 0) + { + sftl.write.meta_size = s_g_num_banks; + } + sftl.write.meta_size *= (s_g_vbas_per_page); + sftl.write.meta = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&sftl.BufZone, sftl.write.meta_size * sizeof(PageMeta_t)); +#endif // AND_READONLY + sftl.read.meta = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&sftl.BufZone, s_g_vbas_per_sb * sizeof(PageMeta_t)); + sftl.boot.meta = (PageMeta_BTOC_t *)WMR_Buf_Alloc_ForDMA(&sftl.BufZone, sizeof(PageMeta_t)); + sftl.scan_meta = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&sftl.BufZone, S_SCAN_META_SIZE * sizeof(PageMeta_t)); + sftl.tmpBuf = (UInt8 *)WMR_Buf_Alloc_ForDMA(&sftl.BufZone, s_g_bytes_per_page); + + if (!WMR_BufZone_FinishedAllocs(&sftl.BufZone)) { + goto errorPath; + } + +#ifndef AND_READONLY + for (i = 0; i < S_SBSTREAM_MAX; i++) { + WMR_BufZone_Rebase(&sftl.BufZone, (void**)&sftl.write.stream[i].bufPage); + WMR_BufZone_Rebase(&sftl.BufZone, (void**)&sftl.write.stream[i].bufMeta); + } + WMR_BufZone_Rebase(&sftl.BufZone, (void**)&sftl.write.meta); +#endif // AND_READONLY + WMR_BufZone_Rebase(&sftl.BufZone, (void**)&sftl.read.meta); + WMR_BufZone_Rebase(&sftl.BufZone, (void**)&sftl.boot.meta); + WMR_BufZone_Rebase(&sftl.BufZone, (void**)&sftl.scan_meta); + WMR_BufZone_Rebase(&sftl.BufZone, (void**)&sftl.tmpBuf); + WMR_BufZone_FinishedRebases(&sftl.BufZone); + + thisSize = sizeof(sftl.reported_lba); + sftl.vfl->GetStruct(AND_STRUCT_VFL_EXPORTED_LBA_NO, &sftl.reported_lba, &thisSize); + if (sftl.reported_lba == 0xffffffff) + { + sftl.reported_lba = s_calc_lbas(FALSE32); + sftl.vfl->SetStruct(AND_STRUCT_VFL_EXPORTED_LBA_NO, &sftl.reported_lba, thisSize); + } + + sftl.max_lba = sftl.reported_lba + S_LBAS_INTERNAL; // Reserve some LBAs for internal use + + L2V_Search_Init(&sftl.read.c); + + if (!s_btoc_init()) + { + goto errorPath; + } + + if (!s_gc_init()) + { + goto errorPath; + } + + if (!s_sb_init()) + { + goto errorPath; + } + +#ifndef AND_READONLY + if (!s_write_init()) + { + goto errorPath; + } +#endif // AND_READONLY + + if (!s_dbg_init()) + { + goto errorPath; + } + + // Allocate the node pool + thisSize = sizeof(L2V_nodepool_mem); + sftl.vfl->GetStruct(AND_STRUCT_VFL_EXPORTED_L2V_POOL, &L2V_nodepool_mem, &thisSize); + if (!L2V_Init(sftl.max_lba, s_g_max_sb, s_g_vbas_per_sb)) { + return ANDErrorCodeHwErr; + } + + // Success path + sftl_init_done = TRUE32; + + return ANDErrorCodeOk; + +errorPath: + s_freeMemory(); + return ANDErrorCodeHwErr; +} + +void sftl_close(void) +{ + s_freeMemory(); + sftl_init_done = FALSE32; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.h new file mode 100644 index 0000000..926a4d9 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_init.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_INIT_H__ +#define __S_INIT_H__ + +#include "s_internal.h" +#include "VFL.h" + +extern UInt32 s_calc_lbas(BOOL32 ideal); +extern Int32 sftl_init(VFLFunctions *pVFLFunctions); +extern void sftl_close(void); + +#endif // __S_INIT_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.c new file mode 100644 index 0000000..e7f329f --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_internal.h" + +sftl_t sftl; +BOOL32 sftl_init_done = FALSE32; + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.h new file mode 100644 index 0000000..51c1755 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_internal.h @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_INTERNAL_H__ +#define __S_INTERNAL_H__ + +#include "WMROAM.h" +#include "WMRBufTypes.h" +#include "WMRBuf.h" +#include "s_meta.h" +#include "L2V/L2V_Extern.h" +#include "s_defines.h" +#include "VFL.h" +#include "FTL.h" + +typedef struct +{ + UInt32 vbas_per_sb, vbas_per_sb_shift; + UInt32 pages_per_sb, pages_per_sb_shift; + UInt32 max_sb, vfl_max_sb; + UInt32 vbas_per_page, vbas_per_page_shift; + UInt32 bytes_per_page, bytes_per_page_shift; + UInt32 bytes_per_lba, bytes_per_lba_shift; + UInt32 bytes_per_lba_meta, bytes_per_lba_meta_shift; + UInt32 num_banks, num_banks_shift; + UInt32 vbas_per_stripe, vbas_per_stripe_shift; + UInt32 max_pages_per_btoc; +} sftl_geom_t; + +typedef struct { + UInt16 wPagesPerVb; + UInt16 wUserVbTotal; + UInt32 dwUserPagesTotal; + UInt16 wBytesPerPage; + UInt16 wNumOfBanks; + UInt16 wBytesPerPageMeta; +} sftl_devinfo_t; + +typedef struct +{ + UInt32 sb[S_GCFIFO_DEPTH + 1]; + UInt32 head, tail; // head==tail means it is empty +} GC_Fifo_t; + +typedef enum + { + GCD_IDLE, + GCD_EVICT, + GCD_ERASE, + GCD_FIXINDEX_RETRY, + GCD_FIXDATA_RETRY, + } GCDState; + +typedef struct +{ + UInt32 weaveSeqAdd; + UInt32 userWeaveSeq; + UInt32 lba; + UInt32 count; +} s_btoc_entry_t; +// Compile-time assertion to protect on-NAND format +WMR_CASSERT(sizeof(s_btoc_entry_t) == 16, s_btoc_entry_size_is_16); + +typedef struct +{ + UInt32 blockStartLba; + UInt32 blockStartCnt; + UInt8 *blockStartBuf; + BOOL32 gc, flatten, padding; + UInt32 *lba; + UInt32 *subCount; + UInt8 *buf; + PageMeta_t *meta; + UInt32 count; + UInt32 len; + UInt32 cur; +} s_write_multi_t; + +typedef struct +{ + // In: + UInt32 in_sb; + + // Work FIFO for error handling + GC_Fifo_t workFifo; + + // Invalid history + UInt32 invalidHist[S_GC_VALIDHIST_SIZE]; + UInt32 invalidHistSize; + UInt32 invalidHistIdx; + UInt32 invalidHistSum; + + // Choose out: + UInt32 sb; + UInt32 chosenMerit; + UInt32 chosenValid; + UInt32 chosenErases; + UInt32 chosenSize; + + // BTOC: + s_btoc_entry_t *BTOC; + UInt32 BTOC_len; + UInt32 curBteIdx; + + UInt32 ueccCounter; + + // State: + BOOL32 done; + GCDState state; + UInt32 vba; + + L2V_SearchCtx_t uecc_c; // For uECC lba search +} GC_Ctx_t; + +typedef struct +{ + UInt8 type; + UInt8 num_btoc_vbas_AND_staticFlag; + UInt16 validLbas; + UInt16 __was_reads; + UInt16 erases; +} s_sb_fmt_t; +// Compile-time assertions to protect on-NAND format +WMR_CASSERT(sizeof(s_sb_fmt_t) == 8, s_sb_fmt_size_is_8); + +typedef struct { + UInt8 type; + UInt16 num_btoc_vbas_AND_staticFlag; + UInt16 validLbas; + UInt16 erases; + UInt32 reads; +} s_sb_t; +WMR_CASSERT(sizeof(s_sb_t) == 12, s_sb_size_is_12); + +typedef struct +{ + UInt32 min; + UInt32 max; + UInt32 avg; + UInt32 count; +} s_sb_userSeq_t; + +typedef struct +{ + // Per-stream state: + WeaveSeq_t minWeaveSeq; + s_btoc_entry_t *BTOC; + UInt32 BTOCidx; + UInt32 BTOC_vba; + UInt32 sb; + UInt32 nextVbaOfs; + UInt32 maxVbaOfs; + UInt32 pageFlags; + UInt32 gcDataAdjust; + BOOL32 abandon; + +#ifndef AND_READONLY + // Buffered-up LBAs: + PageMeta_t *bufMeta; + UInt8 *bufPage; + UInt32 bufLbas; + UInt32 bufSize; + UInt32 bufThreshold; +#endif // AND_READONLY +} s_wrstream_t; + +typedef struct +{ +#ifndef AND_READONLY + // Allocated memory: + PageMeta_t *meta; + UInt8 *writePad; + UInt32 meta_size; +#endif // AND_READONLY + + // Write state: + WeaveSeq_t weaveSeq; + + s_wrstream_t stream[S_SBSTREAM_MAX]; + UInt32 curStream; + s_write_multi_t drain_wm; + s_write_multi_t pad_wm; + UInt32 sum_gcDataAdjust; + + // Host state: + s_write_multi_t host_wm; +} s_wrstate_t; + +typedef struct +{ + UInt32 size; + UInt32 curAge; + UInt32 free; + s_btoc_entry_t **BTOC; + PageMeta_t *meta; + UInt32 *sb; + Int32 *age; + WMR_BufZone_t BufZone; // Buffer zone allocator + VFL_ReadSpans_t rs; + + // For srcVpn: + UInt32 srcSize; + UInt32 curSrc; + UInt32 *srcSb; + UInt32 **srcVpn; +} s_btoccache_t; + +typedef struct { + UInt32 vba; + UInt32 span; +} s_cxt_contig_t; +// Compile-time assertion to protect on-NAND format +WMR_CASSERT(sizeof(s_cxt_contig_t) == 8, s_cxt_contig_size_is_8); + +typedef struct { + UInt32 sb; + WeaveSeq_t minWeaveSeq; + WeaveSeq_t maxWeaveSeq; +} s_wo_item_t; + +typedef struct +{ + s_wo_item_t *item; + UInt32 *sbFilter; + UInt32 size; + UInt32 idx; + UInt32 updates; + + // Weave-ordering: + s_btoc_entry_t *btoc[S_SBSTREAM_PHY_MAX]; + s_btoc_entry_t *bte[S_SBSTREAM_PHY_MAX]; + WeaveSeq_t weave[S_SBSTREAM_PHY_MAX]; + UInt32 itemIdx[S_SBSTREAM_PHY_MAX]; + UInt32 vba[S_SBSTREAM_PHY_MAX]; + UInt32 btoc_len[S_SBSTREAM_PHY_MAX]; +} s_cxt_diff_t; + +typedef struct { + // Save + struct { + L2V_SearchCtx_t c; + UInt32 sb[S_CXT_MAX_SB]; + UInt32 num_sb, num_sb_used; + UInt32 idxPerVba; + + // Current batch + s_cxt_contig_t *curContig; + UInt32 curIdx, curVba; + + // Physical location + UInt32 vba, maxVba; + + // Old cxt: + UInt32 old_sb[S_CXT_MAX_SB]; + UInt32 old_num_sb; + } save; + + // Load: + struct { + WeaveSeq_t baseWeaveSeq; + VFL_ReadSpans_t rs; + + UInt32 baseSb[S_CXT_MAX_SB]; + WeaveSeq_t baseWeaves[S_CXT_MAX_SB]; + UInt32 bases; + UInt32 baseCur; + + UInt32 total_clean; + UInt32 scan_clean; + UInt32 scan_uecc; + UInt32 scan_ok; + + UInt32 curLba; + + BOOL32 sawStats_cxt; + BOOL32 sawStats_lba; + UInt32 stats_cxt_vba; + BOOL32 loadedStats; + } load; + + // Periodicity: + struct + { + UInt32 pagesWritten; + UInt32 sbsSince; + UInt32 sbsSinceStats; + } periodic; + + // Diff: + s_cxt_diff_t diff; + + UInt32 cxt_vbas; + UInt32 cxt_sbs; +} s_cxt_t; + +typedef struct +{ + UInt64 lbas_read; + UInt64 lbas_written; + UInt64 lbas_gc; + UInt64 lbas_flatten; + + UInt64 xacts_write; + UInt64 xacts_read; + + UInt64 data_gc; + UInt64 zero_valid_cross; + + UInt64 valid_lbas; + UInt64 free_sb; + UInt64 data_sb; + UInt64 cxt_sb; + UInt64 dead_sb; + + UInt64 boot_count; + UInt64 unclean_boot_count; + UInt64 refresh_gcs; + UInt64 readCount_gcs; + UInt64 wearLev_gcs; + UInt64 shutdowns; + + UInt64 lbas_read_1; + UInt64 lbas_read_2; + UInt64 lbas_read_3; + UInt64 lbas_read_4; + UInt64 lbas_read_5; + UInt64 lbas_read_6; + UInt64 lbas_read_7; + UInt64 lbas_read_8; + UInt64 lbas_read_over_8; + + UInt64 lbas_write_1; + UInt64 lbas_write_2; + UInt64 lbas_write_3; + UInt64 lbas_write_4; + UInt64 lbas_write_5; + UInt64 lbas_write_6; + UInt64 lbas_write_7; + UInt64 lbas_write_8; + UInt64 lbas_write_over_8; + + UInt64 L2V_pool_free; + UInt64 L2V_pool_count; + + UInt64 lbas_written_static; + UInt64 lbas_written_dynamic; + + UInt64 span_xacts_read; + UInt64 span_freebies_read; +} s_stats_t; + +typedef struct +{ + PageMeta_BTOC_t *meta; +} s_boot_t; + +typedef struct +{ + BOOL32 readsSince; + UInt32 readCount_sb; + UInt32 refresh_sb; +} s_readDist_t; + +typedef struct +{ + L2V_SearchCtx_t c; + UInt16 *validSums; +} s_dbg_t; + + +typedef struct { + UInt32 lba; + UInt32 lbaEnd; +} s_trim_item_t; + + typedef struct + { + Int32 max; + Int32 count; + UInt32 sumSpan; + s_trim_item_t *item; + UInt32 vulnerableWords; + UInt32 *vulnerable; + UInt32 bloomFilterWords; + UInt32 *bloomFilter; +} s_trim_t; + +typedef struct +{ + WMR_BufZone_t BufZone; // Buffer zone allocators + UInt32 reported_lba; // exposed logical space + UInt32 max_lba; // managed logical space + BOOL32 booted; +#ifdef AND_SIMULATOR + BOOL32 ignoreEraseGap; +#endif + + s_stats_t stats; + s_boot_t boot; + s_cxt_t cxt; + s_wrstate_t write; + s_btoccache_t BTOCcache; + sftl_geom_t __geom; + s_sb_t *sb; + UInt16 *minEraseLocations; + s_sb_userSeq_t *sb_userSeq; + s_readDist_t readDist; + s_dbg_t dbg; + s_trim_t trim; + + // Single-page read buffer for convenience + UInt8 *tmpBuf; + // Scan meta buffer + PageMeta_t *scan_meta; + + struct + { + Int32 data_sb; + Int32 free_sb; + Int32 erased_sb; + Int32 dead_sb; + Int32 cxt_sb; + UInt32 validLbas; + UInt32 vbas_in_free_sb; + } seaState; + + struct + { + UInt32 blocksSince; + BOOL32 pointOfNoReturn; + UInt32 maxErases; + } wearLev; + + // Garbage collection structures + struct + { + // Shared state: + BOOL32 inProgress; + UInt32 zoneSize; + L2V_SearchCtx_t read_c; // Search context for GC translation + UInt32 *vbas; + UInt32 *lbas; + UInt32 *uecc; + UInt8 *zone; + PageMeta_t *meta; + UInt32 curZoneSize; + s_write_multi_t wm; + VFL_ReadSpans_t rs; + + GC_Ctx_t ctx[S_GC_NUM_CTX]; + + WMR_BufZone_t BufZone; // Buffer zone allocator + PageMeta_t *meta_buf; + } gc; + + struct { + struct { + FTLExtent_t *extents; + UInt32 offset; + } batch; + PageMeta_t *meta; + // Read search context + L2V_SearchCtx_t c; + VFL_ReadSpans_t rs; + } read; + VFLFunctions *vfl; +} sftl_t; + +extern sftl_t sftl; +extern BOOL32 sftl_init_done; + +#endif // __S_INTERNAL_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.c new file mode 100644 index 0000000..05a7bd5 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "s_internal.h" + + +void s_SetupMeta_TrimRead(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + m->c.PageType = PAGETYPE_FTL_DATA; + m->c.FTLFlags = flags; + m->lba = lba; + m->c.weaveLo = sftl.write.weaveSeq; + m->c.weaveHi = (UInt32)(sftl.write.weaveSeq >> 16); + m->userSeq = (UInt32)(sftl.write.weaveSeq >> 16); + + // Next + lba++; + m++; + } +} + +void s_SetupMeta_Data_Padding(PageMeta_t *meta, UInt32 count, UInt32 flags) +{ + UInt32 i; + + for(i = 0; i < count ; i++) + { + s_SetupMeta_Data(&meta[i], S_TOK_PAD, 1, flags); + } + +} + +void s_SetupMeta_Trim(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags) +{ + s_SetupMeta_Data(__meta, lba, count, flags); +} + +void s_SetupMeta_Data(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + m->c.PageType = PAGETYPE_FTL_DATA; + m->c.FTLFlags = flags; + m->lba = lba; + m->c.weaveLo = sftl.write.weaveSeq; + m->c.weaveHi = (UInt32)(sftl.write.weaveSeq >> 16); + m->userSeq = (UInt32)(sftl.write.weaveSeq >> 16); + + // Next + lba++; + m++; + sftl.write.weaveSeq++; + } +} + +void s_SetupMeta_IntData(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + m->c.PageType = PAGETYPE_FTL_INTDATA; + m->c.FTLFlags = flags; + m->lba = lba; + m->c.weaveLo = sftl.write.weaveSeq; + m->c.weaveHi = (UInt32)(sftl.write.weaveSeq >> 16); + m->userSeq = (UInt32)(sftl.write.weaveSeq >> 16); + + // Next + lba++; + m++; + sftl.write.weaveSeq++; + } +} + +void s_SetupMeta_Data_UECC(PageMeta_t *__meta, UInt32 lba) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + m->c.FTLFlags |= PFLAG_UECC; + m->lba = lba; +} + +void s_SetupMeta_Data_BTOC(PageMeta_t *__meta, WeaveSeq_t minWeaveSeq, UInt32 num_btoc_vbas, UInt32 pageFlags) +{ + UInt32 count; + + PageMeta_BTOC_t *m = (PageMeta_BTOC_t*)__meta; + + count = num_btoc_vbas; + + while (count--) { + m->c.PageType = PAGETYPE_FTL_BTOC_DATA; + m->c.FTLFlags = (num_btoc_vbas << 1) | (pageFlags & 1); + m->c.weaveLo = minWeaveSeq; + m->c.weaveHi = (UInt32)(minWeaveSeq >> 16); + m->maxWeaveSeqAdd = (UInt32)(sftl.write.weaveSeq - minWeaveSeq); + m->btoc_vbas = num_btoc_vbas; + m->__rfu__ = 0xffff; + + // Next + m++; + } +} + +void s_SetupMeta_DataGC(PageMeta_t *__meta, UInt32 count) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + m->c.PageType = PAGETYPE_FTL_DATA; + if (S_LBA_STATS == m->lba) { + m->c.PageType = PAGETYPE_FTL_INTDATA; + } + // Don't touch FTLFlags--might have uECC flag + m->c.weaveLo = sftl.write.weaveSeq; + m->c.weaveHi = (UInt32)(sftl.write.weaveSeq >> 16); + // Don't touch LBA or userSeq + + // Next + m++; + sftl.write.weaveSeq++; + } +} + +void s_SetupMeta_Cxt(PageMeta_t *__meta, UInt32 count, UInt32 tag, UInt32 ofs, UInt32 per, UInt32 len) +{ + PageMeta_Cxt_t *m = (PageMeta_Cxt_t*)__meta; + UInt32 thisCount; + + while (count--) { + thisCount = WMR_MIN(per, len); + + m->c.PageType = PAGETYPE_FTL_CXT; + m->c.FTLFlags = tag; + m->c.weaveLo = sftl.write.weaveSeq; + m->c.weaveHi = (UInt32)(sftl.write.weaveSeq >> 16); + m->ofs = ofs; + m->len = thisCount; + m->__rfu__ = 0xffffffff; + + // Next + m++; + sftl.write.weaveSeq++; + ofs += per; + len -= thisCount; + } +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.h new file mode 100644 index 0000000..ef4ec53 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_meta.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __S_META_H__ +#define __S_META_H__ + +#include "WMROAM.h" + +// PageType defines-- +#define PAGETYPE_FTL_DATA (AND_SPARE_TYPE_REGION_FTL + 0x01) +#define PAGETYPE_FTL_INTDATA (AND_SPARE_TYPE_REGION_FTL + 0x02) +#define PAGETYPE_FTL_BTOC_DATA (AND_SPARE_TYPE_REGION_FTL + 0x1C) +#define PAGETYPE___rfu1___ (AND_SPARE_TYPE_REGION_FTL + 0x1D) +#define PAGETYPE___rfu2___ (AND_SPARE_TYPE_REGION_FTL + 0x1E) +#define PAGETYPE_FTL_CXT (AND_SPARE_TYPE_REGION_FTL + 0x1F) + + +// FTLFlags defines-- +#define PFLAG_STATIC 0x01 // Preserve static/dynamic inferences and hints +#define PFLAG_UECC 0x02 // uECC state for data pages (moved by GC and thus re-encoded) + + +// Must be 16 bytes on PPN + +typedef struct { + UInt8 PageType; + UInt8 FTLFlags; + UInt16 weaveLo; + UInt32 weaveHi; +} PageMeta_Common_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 __f1; + UInt32 __f2; +} PageMeta_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 lba; + UInt32 userSeq; +} PageMeta_Data_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 maxWeaveSeqAdd; + UInt16 btoc_vbas; + UInt16 __rfu__; +} PageMeta_BTOC_t; + +typedef struct { + PageMeta_Common_t c; + UInt16 ofs; + UInt16 len; + UInt32 __rfu__; +} PageMeta_Cxt_t; + + +typedef UInt64 WeaveSeq_t; + + +// Setup +extern void s_SetupMeta_TrimRead(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags); +extern void s_SetupMeta_Trim(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags); +extern void s_SetupMeta_Data(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags); +extern void s_SetupMeta_IntData(PageMeta_t *__meta, UInt32 lba, UInt32 count, UInt32 flags); +extern void s_SetupMeta_Data_UECC(PageMeta_t *__meta, UInt32 lba); +extern void s_SetupMeta_Data_Padding(PageMeta_t *meta, UInt32 count, UInt32 flags); + +extern void s_SetupMeta_Index(PageMeta_t *__meta, UInt32 ipn); + +extern void s_SetupMeta_Data_BTOC(PageMeta_t *__meta, WeaveSeq_t minWeaveSeq, UInt32 num_btoc_pages, UInt32 pageFlags); +extern void s_SetupMeta_DataGC(PageMeta_t *__meta, UInt32 count); + +extern void s_SetupMeta_Cxt(PageMeta_t *__meta, UInt32 count, UInt32 tag, UInt32 ofs, UInt32 per, UInt32 len); + +#define META_SET_LBA(meta, foo) do { ((PageMeta_Data_t*)(meta))->lba = (foo); } while (0) +#define META_SET_CXT_TAG(meta, foo) do { ((PageMeta_Cxt_t*)(meta))->c.FTLFlags = (foo); } while (0) +#define META_SET_WEAVESEQ(meta) do { (meta)->c.weaveLo = (UInt16)sftl.write.weaveSeq; (meta)->c.weaveHi = (UInt32)(sftl.write.weaveSeq >> 16); sftl.write.weaveSeq++; } while (0) +#define META_SET_LBA_UECC(meta) do { ((PageMeta_Data_t*)(meta))->lba = 0xfffffffe; } while (0) +#define META_SET_LBA_CLEAN(meta) do { ((PageMeta_Data_t*)(meta))->lba = 0xffffffff; } while (0) + +// Query +#define META_IS_STATIC(meta) (((PageMeta_t*)(meta))->c.FTLFlags & PFLAG_STATIC) +#define META_IS_DATA(meta) ((PAGETYPE_FTL_DATA == (meta)->c.PageType) || (PAGETYPE_FTL_INTDATA == (meta)->c.PageType)) +#define META_IS_CXT(meta) (PAGETYPE_FTL_CXT == (meta)->c.PageType) +#define META_IS_BTOC_DATA(meta) (PAGETYPE_FTL_BTOC_DATA == (meta)->c.PageType) +#define META_IS_UECC(meta) ((meta)->c.FTLFlags & PFLAG_UECC) +#define META_GET_PAGETYPE(meta) ((UInt32)((meta)->c.PageType)) +#define META_GET_WEAVESEQ(meta) ((UInt64)(meta)->c.weaveLo | ((UInt64)(meta)->c.weaveHi << 16)) +#define META_GET_USERSEQ(meta) (((PageMeta_Data_t*)(meta))->userSeq) +#define META_GET_LBA(meta) (((PageMeta_Data_t*)(meta))->lba) +#define META_GET_CXT_TAG(meta) (((PageMeta_Cxt_t*)(meta))->c.FTLFlags) +#define META_GET_CXT_OFS(meta) ((UInt32)(((PageMeta_Cxt_t*)(meta))->ofs)) +#define META_GET_CXT_LEN(meta) ((UInt32)(((PageMeta_Cxt_t*)(meta))->len)) +#define META_IS_LBA_UECC(meta) (0xfffffffe == ((PageMeta_Data_t*)(meta))->lba) +#define META_IS_LBA_CLEAN(meta) (0xffffffff == ((PageMeta_Data_t*)(meta))->lba) + +// BTOC: +#define META_GET_WEAVESEQ_MIN(meta) ((UInt64)(meta)->c.weaveLo | ((UInt64)(meta)->c.weaveHi << 16)) +#define META_GET_WEAVESEQ_MAX(meta) (((UInt64)(meta)->c.weaveLo | ((UInt64)(meta)->c.weaveHi << 16)) + (UInt64)(meta)->maxWeaveSeqAdd) +#define META_BTOC_GET_NUM_VBAS(meta) ((((PageMeta_BTOC_t*)meta)->btoc_vbas == 0xffff) ? ((meta)->c.FTLFlags>>1) : (((PageMeta_BTOC_t*)meta)->btoc_vbas)) +#define META_BTOC_SET_NUM_VBAS(meta, foo) do { (meta)->c.FTLFlags = (foo) << 1; ((PageMeta_BTOC_t*)meta)->btoc_vbas = foo; } while (0) + +#endif // __S_META_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.c new file mode 100644 index 0000000..033da09 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.c @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRConfig.h" +#include "s_read.h" +#include "s_readdist.h" +#include "s_geom.h" +#include "s_sb.h" +#include "s_stats.h" +#ifndef AND_READONLY +#include "s_write.h" +#include "s_gc.h" +#endif + +BOOL32 s_verify_meta(UInt32 len, PageMeta_t *m) +{ + UInt32 i; + PageMeta_t *meta = m; + FTLExtent_t *extent = sftl.read.batch.extents; + UInt32 offset = sftl.read.batch.offset; + + for (i = 0; i < len; i++, meta++, offset++) { + if (offset >= extent->span) + { + offset = 0; + extent++; + } + + if (META_GET_LBA(meta) != (extent->lba+offset)) { +#ifndef AND_READONLY + WMR_PANIC("sftl: lba mismatch; lba:0x%llx, meta:0x%x\n", (UInt64)extent->lba+offset, META_GET_LBA(meta)); +#else + WMR_PRINT(QUAL_FATAL, "sftl: lba mismatch; lba:0x%llx, meta:0x%x\n", (UInt64)extent->lba+offset, META_GET_LBA(meta)); +#endif + } + if (META_IS_UECC(meta)) { + WMR_PRINT(QUAL, "sftl: uECC flag in meta; lba:0x%llx, meta:0x%x\n", (UInt64)extent->lba+offset, META_GET_LBA(meta)); + return FALSE32; + } + } + + return TRUE32; +} + +UInt32 s_read_xlate(UInt32 lba) +{ +#ifndef AND_READONLY + UInt32 i, j; + UInt32 bufLba; +#endif // AND_READONLY + + if (lba >= sftl.max_lba) { + return AND_GET_ADDRESS_OUT_OF_RANGE; + } + +#ifndef AND_READONLY + // Return token value of AND_GET_ADDRESS_CACHED_WRITE if it's currently buffered + for (i = 0; i < S_SBSTREAM_MAX; i++) { + for (j = 0; j < sftl.write.stream[i].bufLbas; j++) { + bufLba = META_GET_LBA(&sftl.write.stream[i].bufMeta[j]); + if (bufLba == lba) { + return AND_GET_ADDRESS_CACHED_WRITE; + } + } + } +#endif // AND_READONLY + + sftl.read.c.lba = lba; + L2V_Search(&sftl.read.c); + + if (L2V_VBA_DEALLOC == sftl.read.c.vba) { + return AND_GET_ADDRESS_TRIMMED; + } + + return sftl.read.c.vba; +} + +void sftl_read_cb(UInt32 vba, VFLReadStatusType status, UInt8 *meta) +{ + PageMeta_t *pMeta = (PageMeta_t *)meta; + FTLExtent_t *extent = sftl.read.batch.extents; + UInt32 offset = sftl.read.batch.offset; +#ifndef AND_READONLY + UInt32 i; +#endif // AND_READONLY + + offset += pMeta - sftl.read.meta; + while (offset >= extent->span) + { + offset -= (UInt32)extent->span; + extent++; + } + + if (status & VFL_READ_STATUS_UNIDENTIFIED) { + WMR_PRINT(QUAL_FATAL, "read got unidentified read status (0x%x) on vba:0x%x; did we get a timeout? Pretending it was uECC.\n", status, vba); + status = (status & ~VFL_READ_STATUS_UNIDENTIFIED) | VFL_READ_STATUS_UECC; + } + + if (status & VFL_READ_STATUS_REFRESH) { + WMR_PRINT(QUAL, "sftl: requested refresh lba:%lld vba:0x%x status:0x%x\n", (UInt64)extent->lba+offset, vba, status); +#ifndef AND_READONLY + s_readRefresh_enq(vba); +#endif // AND_READONLY + } + if (status & VFL_READ_STATUS_RETIRE) { + WMR_PRINT(QUAL, "sftl: requested retire lba:%lld vba:0x%x status:0x%x\n", (UInt64)extent->lba+offset, vba, status); +#ifndef AND_READONLY + s_readRefresh_enq(vba); +#endif // AND_READONLY + } + if (status & VFL_READ_STATUS_UECC) { + WMR_PRINT(QUAL, "sftl: error uECC lba:%lld vba:0x%x status:0x%x\n", (UInt64)extent->lba+offset, vba, status); + } + if (status & VFL_READ_STATUS_CLEAN) { + WMR_PRINT(QUAL, "sftl: error clean lba:%lld vba:0x%x status:0x%x\n", (UInt64)extent->lba+offset, vba, status); + } + +#ifndef AND_READONLY + if ((status & VFL_READ_STATUS_REFRESH) || (status & VFL_READ_STATUS_RETIRE) || (status & VFL_READ_STATUS_UECC)) { + for (i = 0; i < S_SBSTREAM_MAX; i++) { + if (sftl.write.stream[i].sb == s_g_vba_to_sb(vba)) { + sftl.write.stream[i].abandon = TRUE32; + } + } + } +#endif // AND_READONLY +} + +Int32 s_read_real(FTLExtent_t *origExtent, UInt32 origCount, UInt8 *origBuf) +{ + UInt32 curLba, curCount; + FTLExtent_t *curExtent; + UInt32 thisCount, batchCount; + UInt8 *curBuf = origBuf; + PageMeta_t *batchMeta; + Int32 status; + ANDStatus statusRet = ANDErrorCodeOk; + UInt32 nandSpans; + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; // for trim inject +#ifndef AND_READONLY + UInt32 i; +#endif // AND_READONLY + + curExtent = origExtent; + curLba = (UInt32)curExtent->lba; + curCount = (UInt32)curExtent->span; + batchCount = 0; + nandSpans = 0; + sftl.read.c.span = 0; + batchMeta = sftl.read.meta; + + sftl.read.batch.extents = curExtent; + sftl.read.batch.offset = 0; + + sftl.vfl->ReadSpansInit(&sftl.read.rs, sftl_read_cb, VFL_READ_STATUS_ALL, FALSE32, TRUE32); + + while (curCount) + { + // Translate + if (0 == sftl.read.c.span) { + sftl.read.c.lba = curLba; + L2V_Search(&sftl.read.c); + } + WMR_ASSERT(0 != sftl.read.c.span); + + // How much? + thisCount = WMR_MIN(WMR_MIN(sftl.read.c.span, curCount), s_g_vbas_per_sb - batchCount); + + // Real data, or trimmed token? + if (L2V_VBA_SPECIAL > sftl.read.c.vba) { + sftl.vfl->ReadSpansAdd(&sftl.read.rs, sftl.read.c.vba, thisCount, curBuf, (UInt8*)batchMeta); +#ifndef AND_READONLY + s_readDist_add(sftl.read.c.vba, thisCount); +#endif // AND_READONLY + sftl.read.c.vba += thisCount; + nandSpans++; + } else { + s_SetupMeta_TrimRead(batchMeta, curLba, thisCount, wr->pageFlags); + } + sftl.read.c.span -= thisCount; + + // Next + curBuf += s_g_mul_bytes_per_lba(thisCount); + batchMeta += thisCount; + + curCount -= thisCount; + curLba += thisCount; + batchCount += thisCount; + + if (0 >= curCount) + { + curExtent++; + if ((UInt32)(curExtent - origExtent) < origCount) + { + curLba = (UInt32)curExtent->lba; + curCount = (UInt32)curExtent->span; + sftl.read.c.span = 0; + } + } + + // End of line, or saturated batch? + if (!curCount || (batchCount == s_g_vbas_per_sb)) { + if (nandSpans) { + status = sftl.vfl->ReadSpans(&sftl.read.rs); + if (!(status & (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN))) { + if(!s_verify_meta(batchCount, sftl.read.meta)) { + statusRet = ANDErrorCodeUserDataErr; + } + } else { + statusRet = ANDErrorCodeUserDataErr; + } + } + if (curCount) { + // Next round's on me... + sftl.vfl->ReadSpansInit(&sftl.read.rs, sftl_read_cb, (VFL_READ_STATUS_REFRESH | VFL_READ_STATUS_RETIRE), TRUE32, FALSE32); + batchCount = 0; + nandSpans = 0; + batchMeta = sftl.read.meta; + sftl.read.batch.extents = curExtent; + sftl.read.batch.offset = curLba - (UInt32)curExtent->lba; + } + } + } + +#ifndef AND_READONLY + for (i = 0; i < S_SBSTREAM_MAX; i++) { + if (sftl.write.stream[i].abandon) { + s_sb_next(i); + sftl.write.stream[i].abandon = FALSE32; + } + } + + s_readDist_end_of_read_handle(); +#endif // AND_READONLY + + return statusRet; +} + +Int32 s_read_int(UInt32 origLba, UInt32 origCount, UInt8 *origBuf) +{ + Int32 status; + FTLExtent_t extent; + + if (((origLba + origCount) > sftl.max_lba) || (origLba < sftl.reported_lba)) + { + return ANDErrorCodeHwErr; + } + + extent.lba = origLba; + extent.span = origCount; + status = s_read_real(&extent, 1, origBuf); + + return status; +} + +#ifndef AND_READONLY +void s_read_coherency(UInt32 lba, UInt32 count) { + UInt32 i, j; + UInt32 bufLba; + + for (i = 0; i < S_SBSTREAM_MAX; i++) { + for (j = 0; j < sftl.write.stream[i].bufLbas; j++) { + bufLba = META_GET_LBA(&sftl.write.stream[i].bufMeta[j]); + if ((bufLba >= lba) && (bufLba < (lba + count))) { + // Hit -- drain this stream + s_drain_stream(i, TRUE32); + } + } + } +} + +static void pad_current_block(void) +{ + UInt8 i; + UInt32 currentSb; + for (i = 0; i < S_SBSTREAM_MAX; i++) { + currentSb = sftl.write.stream[i].sb; + if ((currentSb < s_g_max_sb) && (sftl.sb[currentSb].reads > S_READDIST_LIMIT_PER_OPEN_SB)) { + if(s_pad_block(currentSb) == FALSE32) { + s_gc_data_enq(currentSb, S_GC_CTX_FG); + } + break; + } + } +} +#endif // AND_READONLY + +Int32 sftl_read(UInt32 origLba, UInt32 origCount, UInt8 *origBuf) +{ + Int32 status; + FTLExtent_t extent; + + sftl.stats.xacts_read++; + switch (origCount) + { + case 0 : break; + case 1 : sftl.stats.lbas_read_1++; + break; + case 2 : sftl.stats.lbas_read_2++; + break; + case 3 : sftl.stats.lbas_read_3++; + break; + case 4 : sftl.stats.lbas_read_4++; + break; + case 5 : sftl.stats.lbas_read_5++; + break; + case 6 : sftl.stats.lbas_read_6++; + break; + case 7 : sftl.stats.lbas_read_7++; + break; + case 8 : sftl.stats.lbas_read_8++; + break; + default : sftl.stats.lbas_read_over_8++; + } + + if ((origLba + origCount) > sftl.reported_lba) + { + return ANDErrorCodeHwErr; + } + +#ifndef AND_READONLY + s_read_coherency(origLba, origCount); +#endif // AND_READONLY + + extent.lba = origLba; + extent.span = origCount; + status = s_read_real(&extent, 1, origBuf); + + sftl.stats.lbas_read += origCount; + + s_stats_update(); + +#ifndef AND_READONLY + pad_current_block(); +#endif + + return status; +} + +Int32 sftl_read_spans(FTLExtent_t *extents, UInt32 count, UInt8 *buf) +{ + Int32 status; + UInt32 i; + + sftl.stats.xacts_read += count; + sftl.stats.span_xacts_read++; + sftl.stats.span_freebies_read += count - 1; + + for (i = 0 ; i < count ; i++) + { + UInt32 lba = (UInt32)extents[i].lba; + UInt32 span = (UInt32)extents[i].span; + + switch (span) + { + case 0 : break; + case 1 : sftl.stats.lbas_read_1++; + break; + case 2 : sftl.stats.lbas_read_2++; + break; + case 3 : sftl.stats.lbas_read_3++; + break; + case 4 : sftl.stats.lbas_read_4++; + break; + case 5 : sftl.stats.lbas_read_5++; + break; + case 6 : sftl.stats.lbas_read_6++; + break; + case 7 : sftl.stats.lbas_read_7++; + break; + case 8 : sftl.stats.lbas_read_8++; + break; + default : sftl.stats.lbas_read_over_8++; + } + + sftl.stats.lbas_read += span; + + if ((lba + span) > sftl.reported_lba) + { + return ANDErrorCodeHwErr; + } + +#ifndef AND_READONLY + s_read_coherency(lba, span); +#endif // AND_READONLY + } + + status = s_read_real(extents, count, buf); + + s_stats_update(); + return status; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.h new file mode 100644 index 0000000..a9ef867 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_read.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_READ_H__ +#define __S_READ_H__ + +#include "s_internal.h" + +extern UInt32 s_read_xlate(UInt32 lba); +extern Int32 s_read_int(UInt32 lba, UInt32 count, UInt8 *buf); +extern Int32 sftl_read(UInt32 lba, UInt32 count, UInt8 *buf); +extern Int32 sftl_read_spans(FTLExtent_t *extents, UInt32 count, UInt8 *buf); + +#endif // __S_READ_H__ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.c new file mode 100644 index 0000000..154cd41 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#define AND_TRACE_LAYER FTL + +#include "WMRConfig.h" +#include "s_readdist.h" +#include "s_sb.h" +#include "s_bg.h" +#include "s_geom.h" + +void s_readDist_init(void) +{ + sftl.readDist.readsSince = 0; + sftl.readDist.refresh_sb = 0xffffffff; + sftl.readDist.readCount_sb = 0xffffffff; +} + +void s_readDist_close(void) +{ + // Nothing now +} + +void s_readCount_enq(UInt32 vba) +{ + UInt32 sb; + + WMR_TRACE_IST_1(ReadCountEnq, NONE, vba); + + sb = s_g_vba_to_sb(vba); + + if (0xffffffff == sftl.readDist.readCount_sb) { + sftl.readDist.readCount_sb = sb; + } +} + +void s_readRefresh_enq(UInt32 vba) +{ + UInt32 sb; + + WMR_TRACE_IST_1(ReadRefreshEnq, NONE, vba); + + sb = s_g_vba_to_sb(vba); + + if (0xffffffff == sftl.readDist.refresh_sb) { + sftl.readDist.refresh_sb = sb; + } + else + { + sftl.sb[sb].reads = S_READDIST_LIMIT_PER_SB; + } +} + +void s_readDist_end_of_read_handle(void) +{ +#ifndef AND_READONLY + UInt32 sb, type; + + if (!sftl.booted) { + return; + } + + sftl.readDist.readsSince++; + + // Find offending sb + sb = sftl.readDist.refresh_sb; + if (0xffffffff != sb) { + sftl.readDist.refresh_sb = 0xffffffff; + sftl.stats.refresh_gcs++; + } else { + sb = sftl.readDist.readCount_sb; + + // Not been long enough? Get out + if (sftl.readDist.readsSince < S_READDIST_PERIOD) { + return; + } + + // Service BG slice for read + s_bg_read(1); + + // Don't go further if we have nothing to do + if (0xffffffff == sb) { + return; + } + sftl.readDist.readCount_sb = 0xffffffff; + sftl.readDist.readsSince = 0; + sftl.stats.readCount_gcs++; + } + + WMR_TRACE_IST_0(ReadDist, START); + + // Give it to bg + type = s_sb_get_type(sb); + if ((S_SB_DATA == type) || (S_SB_DATA_CUR == type) || (S_SB_DATA_GC == type) || (S_SB_DATA_PENDING_GC == type)) { + s_bg_enq(sb, TRUE32); + } + + WMR_TRACE_IST_0(ReadDist, END); +#endif +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.h new file mode 100644 index 0000000..8ff165c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_readdist.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_READDIST_H__ +#define __S_READDIST_H__ + +#include "s_internal.h" + +#define s_readDist_add(vba, amount) \ +do { \ + UInt32 ____temp1; \ + ____temp1 = s_g_vba_to_sb(vba); \ + sftl.sb[____temp1].reads += s_g_div_vbas_per_stripe((amount) + s_g_vbas_per_stripe - 1); \ + if (sftl.sb[____temp1].reads >= S_READDIST_LIMIT_PER_SB) { \ + s_readCount_enq(vba); \ + } \ +} while(0) + +extern void s_readDist_init(void); +extern void s_readDist_close(void); +extern void s_readRefresh_enq(UInt32 vba); +extern void s_readCount_enq(UInt32 vba); +extern void s_readDist_end_of_read_handle(void); + +#endif // __S_READDIST_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.c new file mode 100644 index 0000000..90bd2a4 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.c @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_internal.h" +#include "s_defines.h" +#include "s_sb.h" +#include "s_btoc.h" +#include "s_wearlev.h" +#include "s_geom.h" +#include "s_dbg.h" +#include "s_trim.h" +#ifndef AND_READONLY +#include "s_gc.h" +#include "s_bg.h" +#endif + +BOOL32 s_sb_init(void) +{ + UInt32 i; + + sftl.minEraseLocations = WMR_MALLOC(sizeof(UInt16) * S_GC_FREE_THRESHOLD); + if(NULL == sftl.minEraseLocations) + { + return FALSE32; + } + WMR_MEMSET(sftl.minEraseLocations, 0xff, sizeof(UInt16) * S_GC_FREE_THRESHOLD); + + sftl.sb = (s_sb_t*)WMR_MALLOC(sizeof(*sftl.sb) * s_g_max_sb); + if (NULL == sftl.sb) { + return FALSE32; + } + sftl.sb_userSeq = (s_sb_userSeq_t*)WMR_MALLOC(sizeof(*sftl.sb_userSeq) * s_g_max_sb); + if (NULL == sftl.sb_userSeq) { + return FALSE32; + } + WMR_MEMSET(sftl.sb_userSeq, 0, sizeof(*sftl.sb_userSeq) * s_g_max_sb); + + for (i = 0; i < s_g_max_sb; i++) { + s_sb_set_type(i, S_SB_UNKNOWN); + s_sb_set_num_btoc_vbas_0ok(i, 0); + s_sb_set_validLbas(i, 0); + s_sb_set_reads(i, 0); + } + + return TRUE32; +} + +void s_sb_close(void) +{ + if(NULL != sftl.minEraseLocations) { + WMR_FREE(sftl.minEraseLocations, sizeof(UInt16) * S_GC_FREE_THRESHOLD); + } + if (NULL != sftl.sb) { + WMR_FREE(sftl.sb, sizeof(*sftl.sb) * s_g_max_sb); + } + if (NULL != sftl.sb_userSeq) { + WMR_FREE(sftl.sb_userSeq, sizeof(*sftl.sb_userSeq) * s_g_max_sb); + } + + sftl.minEraseLocations = NULL; + sftl.sb = NULL; + sftl.sb_userSeq = NULL; +} + +#ifndef AND_READONLY +void s_sb_next_cur(void) +{ + s_sb_next(sftl.write.curStream); +} + +static BOOL32 checkForEOL(void) +{ + UInt32 vbas, sb; + + // Sum available VBAs + vbas = 0; + for (sb = 0; sb < s_g_max_sb; sb++) { + switch (s_sb_get_type(sb)) { + case S_SB_ERASED: + case S_SB_PENDING_ERASE: + case S_SB_ERASE_BEFORE_USE: + case S_SB_DATA: + vbas += sftl.vfl->GetVbasPerVb(sb); + break; + } + } + + WMR_PRINT(ALWAYS, "Checking for NAND EOL; VBAs:%d LBA-max:%d LBAs-in-use:%d\n", vbas, sftl.reported_lba, sftl.seaState.validLbas); + + // Check if it's a legitimate EOL, or GC bug + if ((sftl.seaState.validLbas + (2 * S_GC_FREE_THRESHOLD * s_g_vbas_per_sb)) >= vbas) { +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) + WMR_SIM_EXIT("NAND end-of-life!"); +#else // defined(AND_SIMULATOR) && AND_SIMULATOR + WMR_PANIC("NAND end-of-life!"); +#endif // defined(AND_SIMULATOR) && AND_SIMULATOR + } + + return FALSE32; +} +#define ENTRY_UNPOPULATED 0xffff +static UInt16 getMaxErase(UInt16 *eraseableArray, UInt8 count, UInt8 *location) +{ + UInt8 i; + UInt16 maxValue = 0; + + if((eraseableArray == NULL) || (location == NULL)) + { + return 0; + } + + for(i = 0; i < count; i++) + { + if(eraseableArray[i] == ENTRY_UNPOPULATED) + { + maxValue = ENTRY_UNPOPULATED; + *location = i; + break; + } + if(sftl.sb[eraseableArray[i]].erases > maxValue) + { + maxValue = sftl.sb[eraseableArray[i]].erases; + *location = i; + } + } + return maxValue; +} + +static UInt16 replaceMaxErase(UInt16 *eraseableArray, UInt8 location, UInt16 newEntry) +{ + if((eraseableArray == NULL) || ((eraseableArray[location] != ENTRY_UNPOPULATED) && (sftl.sb[eraseableArray[location]].erases < sftl.sb[newEntry].erases))) + { + return ENTRY_UNPOPULATED; + } + + eraseableArray[location] = newEntry; + + return location; +} + +UInt32 s_sb_alloc(BOOL32 chooseMinErases) +{ + UInt32 i, chosen, vbas, type; + UInt32 minErases, minIdx; + UInt32 maxErases, maxIdx; + UInt8 maxEraseEntryLocation; + UInt32 minErased, minErasedIdx; + +again: + minErases = 0xffffffff; + minIdx = 0xffffffff; + minErased = 0xffffffff; + minErasedIdx = 0xffffffff; + maxErases = 0; + maxIdx = 0xffffffff; + + WMR_MEMSET(sftl.minEraseLocations, 0xff, sizeof(UInt16) * S_GC_FREE_THRESHOLD); + // Find min-erase block + for (i = 0; i < s_g_max_sb; i++) { + type = s_sb_get_type(i); + if(((sftl.seaState.erased_sb ) < S_GC_FREE_THRESHOLD) + && ((S_SB_ERASE_BEFORE_USE == type) || (S_SB_PENDING_ERASE == type))) + { + if(getMaxErase(sftl.minEraseLocations, S_GC_FREE_THRESHOLD, &maxEraseEntryLocation) > sftl.sb[i].erases) + { + replaceMaxErase(sftl.minEraseLocations, maxEraseEntryLocation, (UInt16)i); + } + } + + if ((S_SB_ERASED == type) + || (S_SB_PENDING_ERASE == type) + || (S_SB_ERASE_BEFORE_USE == type)) + { + WMR_ASSERT(0 == s_sb_get_validLbas(i)); + if (s_sb_get_erases(i) < minErases) { + minErases = s_sb_get_erases(i); + minIdx = i; + } + if (s_sb_get_erases(i) >= maxErases) { + maxErases = s_sb_get_erases(i); + maxIdx = i; + } + if(S_SB_ERASED == type) + { + if (s_sb_get_erases(i) < minErased) { + minErased = s_sb_get_erases(i); + minErasedIdx = i; + } + } + } + } + + // Check for allocation failure + if ((0xffffffff == minIdx) || (0xffffffff == maxIdx)) { + if (!checkForEOL()) { + WMR_PANIC("GC bug? Ran out of blocks, but probably not EOL."); + } + } + + for(i = 0; (i < S_GC_FREE_THRESHOLD) && (sftl.seaState.erased_sb < S_GC_FREE_THRESHOLD); i++) + { + if((sftl.minEraseLocations[i] != ENTRY_UNPOPULATED) && ((S_SB_ERASE_BEFORE_USE == s_sb_get_type(sftl.minEraseLocations[i])) || (S_SB_PENDING_ERASE == s_sb_get_type(sftl.minEraseLocations[i])))) + { + sftl.seaState.vbas_in_free_sb -= sftl.vfl->GetVbasPerVb(sftl.minEraseLocations[i]); + sftl.vfl->Erase(sftl.minEraseLocations[i], TRUE32); + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sftl.minEraseLocations[i]); + s_sb_set_type(sftl.minEraseLocations[i], S_SB_ERASED); + s_sb_log_erase(sftl.minEraseLocations[i]); + sftl.seaState.erased_sb++; + s_dbg_check_sb_dist(); + s_trim_checkVulnerable(sftl.minEraseLocations[i]); + + } + + } + + if (chooseMinErases) { + if((minErasedIdx != minIdx) && ((minErases + 1) >= minErased)) + chosen = minErasedIdx; + else + chosen = minIdx; + } else { + if((minErasedIdx != minIdx) && ((minErases + 1) >= minErased)) + chosen = minErasedIdx; + else + chosen = minIdx; + //TODO:evaluate median instead of maxIdx ( too extreme ) for static stream. + } + + // Decrement free space by pre-erase size + sftl.seaState.vbas_in_free_sb -= sftl.vfl->GetVbasPerVb(chosen); + + if (S_SB_ERASED != s_sb_get_type(chosen)) { + // Erase it + sftl.vfl->Erase(chosen, TRUE32); + s_sb_log_erase(chosen); + s_trim_checkVulnerable(chosen); + // Don't set the type, since it's set by caller + } else { + sftl.seaState.erased_sb--; + } + + // Filter out dead superblocks + vbas = sftl.vfl->GetVbasPerVb(chosen); + if (0 == vbas) { + s_sb_set_type(chosen, S_SB_DEAD); + sftl.seaState.dead_sb++; + sftl.seaState.free_sb--; + goto again; + } + + // Counters + sftl.seaState.free_sb--; + s_sb_set_reads(chosen, 0); + + return chosen; +} + +UInt32 s_sb_cxt_alloc(void) +{ + UInt32 chosen; + + chosen = s_sb_alloc(TRUE32); + s_sb_set_type(chosen, S_SB_CXT); + sftl.seaState.cxt_sb++; + + return chosen; +} + +void s_sb_cxt_free_clean(UInt32 sb) +{ + UInt32 type; + + type = s_sb_get_type(sb); + if ((S_SB_ERASED != type) + && (S_SB_PENDING_ERASE != type) + && (S_SB_ERASE_BEFORE_USE != type)) + { + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sb); + WMR_ASSERT(S_SB_CXT == s_sb_get_type(sb)); + sftl.seaState.free_sb++; + sftl.seaState.cxt_sb--; + } + + if (S_SB_ERASED != type) { + sftl.seaState.erased_sb++; + } + + s_sb_set_type(sb, S_SB_ERASED); + s_sb_log_erase(sb); +} + +void s_sb_cxt_free_erase(UInt32 sb) +{ + WMR_ASSERT(S_SB_CXT == s_sb_get_type(sb)); + sftl.vfl->Erase(sb, TRUE32); + s_sb_cxt_free_clean(sb); +} + +void s_sb_boot_free_erase(UInt32 sb) +{ + sftl.seaState.vbas_in_free_sb -= sftl.vfl->GetVbasPerVb(sb); + sftl.vfl->Erase(sb, TRUE32); + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sb); + s_sb_set_type(sb, S_SB_ERASED); + sftl.seaState.erased_sb++; + s_sb_log_erase(sb); +} + +void s_sb_fmt_erase(UInt32 sb) +{ + sftl.vfl->Erase(sb, TRUE32); + s_sb_set_type(sb, S_SB_ERASED); + sftl.seaState.erased_sb++; + sftl.seaState.free_sb++; + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sb); +} + +void s_sb_next(UInt32 stream) +{ + UInt32 chosen; + s_wrstream_t *wr = &sftl.write.stream[stream]; + + // Wear leveling periodicity counter + s_wearlev_cross_block(); + + s_sb_log_next(); + + chosen = s_sb_alloc(S_SBSTREAM_DYN == stream); + sftl.seaState.data_sb++; + sftl.write.sum_gcDataAdjust -= wr->gcDataAdjust; + wr->gcDataAdjust = 0; + + if (NULL != wr->BTOC) { + s_btoc_dealloc(wr->BTOC); + } + + if (0xffffffff != wr->sb) { + s_sb_set_type(wr->sb, S_SB_DATA); + if(s_sb_get_num_btoc_vbas(wr->sb) == 0) + { + s_bg_enq(wr->sb, TRUE32); + } + } + + wr->sb = chosen; + s_sb_set_type(chosen, S_SB_DATA_CUR); + if (S_SBSTREAM_STATIC == stream) { + s_sb_set_static(chosen, 1); + } else { + s_sb_set_static(chosen, 0); + } + wr->nextVbaOfs = 0; + wr->maxVbaOfs = sftl.vfl->GetVbasPerVb(chosen); + wr->BTOC = s_btoc_alloc(chosen); + wr->BTOCidx = 0; + wr->BTOC_vba = s_g_vbas_per_page; + + // Set it to have 0 BTOC vbas for existence detection on program fail gc + s_sb_clr_num_btoc_vbas(chosen); +} + +void s_sb_next_from_sb(UInt32 sb) +{ + UInt32 i; + + for (i = 0; i < S_SBSTREAM_MAX; i++) { + if (sb == sftl.write.stream[i].sb) { + s_sb_next(i); + return; + } + } + + WMR_PANIC("sb %d not a current write block", sb); +} + + +void s_sb_sweep0(void) +{ + UInt32 sb, t; + + for (sb = 0; sb < s_g_max_sb; sb++) { + t = s_sb_get_type(sb); + if ((0 == s_sb_get_validLbas(sb)) && ((S_SB_DATA == t) || (S_SB_DATA_PENDING_GC == t))) { + s_sb_set_type(sb, S_SB_ERASE_BEFORE_USE); + sftl.seaState.free_sb++; + sftl.seaState.data_sb--; + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sb); + } + } +} + +#endif // !AND_READONLY + +// Implement L2V functions for reducing validity: +void Outside_L2V_ValidUp(UInt32 vba, UInt32 count) +{ + UInt32 sbN; + + if (L2V_VBA_SPECIAL <= vba) + return; + WMR_ASSERT(count < s_g_vbas_per_sb); + + sbN = s_g_vba_to_sb(vba); + sftl.sb[sbN].validLbas += count; + sftl.seaState.validLbas += count; +} + +void Outside_L2V_ValidDown(UInt32 vba, UInt32 count) +{ + UInt32 sbN; + UInt32 num_btoc_vbas; + + if (L2V_VBA_SPECIAL <= vba) + return; + WMR_ASSERT(count < s_g_vbas_per_sb); + + sbN = s_g_vba_to_sb(vba); + WMR_ASSERT(sftl.sb[sbN].validLbas >= count); + WMR_ASSERT(sftl.seaState.validLbas >= count); + sftl.sb[sbN].validLbas -= count; + sftl.seaState.validLbas -= count; + + // Zero-valid and not the current block? ... and we're booted? + if ((0 == sftl.sb[sbN].validLbas) && (S_SB_DATA == sftl.sb[sbN].type) && sftl.booted) { + // Immediately transition to erasable + num_btoc_vbas = s_sb_get_num_btoc_vbas(sbN); + s_sb_set_type(sbN, num_btoc_vbas ? S_SB_ERASE_BEFORE_USE : S_SB_PENDING_ERASE); + s_sb_set_reads(sbN, 0); + sftl.seaState.free_sb++; + sftl.seaState.data_sb--; + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(sbN); + // Update stats + sftl.stats.zero_valid_cross++; +#ifndef AND_READONLY + s_gc_zeroValidCross(); +#endif + } +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.h new file mode 100644 index 0000000..da9cd9f --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_sb.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_SB_H__ +#define __S_SB_H__ + +#include "s_internal.h" + +// Getters +#define s_sb_get_type(sbno) (sftl.sb[sbno].type+0) +#define s_sb_get_validLbas(sbno) (sftl.sb[sbno].validLbas+0) +#define s_sb_get_reads(sbno) (sftl.sb[sbno].reads+0) +#define s_sb_get_num_btoc_vbas(sbno) (sftl.sb[sbno].num_btoc_vbas_AND_staticFlag>>1) +#define s_sb_get_erases(sbno) (sftl.sb[sbno].erases+0) +#define s_sb_get_static(sbno) (sftl.sb[sbno].num_btoc_vbas_AND_staticFlag & 1) + +// Setters +#ifndef AND_READONLY +extern UInt32 s_WorkFifo_Deq_sb(GC_Fifo_t *f, UInt32 sb); + +WMR_CASSERT(S_GC_NUM_CTX == 2, num_ctx_matches_sb_set_type); +#define s_sb_set_type(sbno, x) \ +do {\ + if(((x) != S_SB_DATA_PENDING_GC) && ((x) != S_SB_DATA)) { \ + s_WorkFifo_Deq_sb(&sftl.gc.ctx[0].workFifo, (sbno)); \ + s_WorkFifo_Deq_sb(&sftl.gc.ctx[1].workFifo, (sbno)); \ + } \ + sftl.sb[sbno].type = (x); \ +} while (0) +#else +#define s_sb_set_type(sbno, x) \ +do {\ + sftl.sb[sbno].type = (x); \ + } while (0) +#endif +#define s_sb_set_validLbas(sbno, x) do { sftl.sb[sbno].validLbas = (x); } while (0) +#define s_sb_set_reads(sbno, x) do { sftl.sb[sbno].reads = (x); } while (0) +#define s_sb_set_num_btoc_vbas(sbno, x) do { WMR_ASSERT(0 != (x)); sftl.sb[sbno].num_btoc_vbas_AND_staticFlag = (sftl.sb[sbno].num_btoc_vbas_AND_staticFlag & 1) | ((x) << 1); } while(0) +#define s_sb_set_num_btoc_vbas_0ok(sbno, x) do { sftl.sb[sbno].num_btoc_vbas_AND_staticFlag = (x) << 1; } while(0) +#define s_sb_clr_num_btoc_vbas(sbno) do { sftl.sb[sbno].num_btoc_vbas_AND_staticFlag &= 1; } while(0) +#define s_sb_set_static(sbno, sFlag) do { sftl.sb[sbno].num_btoc_vbas_AND_staticFlag = (sftl.sb[sbno].num_btoc_vbas_AND_staticFlag & ~1) | ((sFlag) & 1); } while (0) +#define s_sb_log_erase(sbN) \ +do { \ + sftl.sb[sbN].erases++; \ +} while (0) +#define s_sb_log_next() \ +do { \ + sftl.cxt.periodic.sbsSince++; \ + sftl.cxt.periodic.sbsSinceStats++; \ +} while (0) + + +extern BOOL32 s_sb_init(void); +extern void s_sb_close(void); +extern void s_sb_next_cur(void); +extern void s_sb_next(UInt32 stream); +extern void s_sb_next_from_sb(UInt32 sb); +extern UInt32 s_sb_cxt_alloc(void); +extern void s_sb_boot_free_erase(UInt32 sb); +extern void s_sb_cxt_free_erase(UInt32 sb); +extern void s_sb_cxt_free_clean(UInt32 sb); +extern void s_sb_fmt_erase(UInt32 sb); +extern void s_sb_sweep0(void); + +#endif // __S_SB_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.c new file mode 100644 index 0000000..4b7b14a --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_stats.h" +#include "s_geom.h" +#include "s_token.h" +#include "FTL.h" + +#ifndef AND_READONLY + +void voidFunc(UInt32 dwStructType, void *pvoidStructBuffer, UInt32 dwStructSize) { +} + +#undef X_FTL_doStat +#define X_FTL_doStat(_part, _val) do { if (key == S_STATKEY_ ## _part) { WMR_PRINT(ALWAYS, #_part " = %lld\n", val64); continue; } } while(0); +FTL_makeStatParser(print_stats, voidFunc, voidFunc) + +UInt32 s_stats_to_buf(UInt32 *buf) +{ + UInt32 *baseBuf; + UInt32 thisSize, dwords; + + baseBuf = buf; + + // Number of elements + *buf++ = (sizeof(s_stats_t)/sizeof(UInt64)) + 2; + + // sftl stats: +#undef X_FTL_doStat +#define X_FTL_doStat(_part, _val) do { buf[0] = (S_STATKEY_ ## _part); buf[1] = 2; *(UInt64*)&buf[2] = sftl.stats._part; buf += 4; } while(0); + FTL_doAllStats + WMR_ASSERT((buf - baseBuf) == (((sizeof(s_stats_t) * 2) / sizeof(UInt32)) + 1)); + + // VFL + thisSize = AND_STATISTICS_SIZE_PER_LAYER; + sftl.vfl->GetStruct(AND_STRUCT_VFL_STATISTICS, ((UInt8*)buf)+sizeof(UInt64), &thisSize); + buf[0] = S_STATKEY_VFL; + dwords = (thisSize + sizeof(UInt32) - 1) / sizeof(UInt32); + buf[1] = dwords; + buf += 2; + buf += dwords; + + // FIL + thisSize = AND_STATISTICS_SIZE_PER_LAYER; + sftl.vfl->GetStruct(AND_STRUCT_VFL_FILSTATISTICS, ((UInt8*)buf)+sizeof(UInt64), &thisSize); + buf[0] = S_STATKEY_FIL; + dwords = (thisSize + sizeof(UInt32) - 1) / sizeof(UInt32); + buf[1] = dwords; + buf += 2; + buf += dwords; + + WMR_ASSERT((UInt32)((UInt8*)buf - (UInt8*)baseBuf) <= s_g_bytes_per_lba); + return (UInt32)((UInt8*)buf - (UInt8*)baseBuf); +} + +static void _UpdateStatisticsCounters(UInt8 * src, void *stat_buff, UInt32 size) +{ + UInt32 idx; + const UInt32 num_of_items = (size / sizeof(UInt64)); + UInt64 * stat_buff_u64 = (UInt64 *)stat_buff; + + for (idx = 0; idx < num_of_items; idx++) { + UInt64 *temp_ptr_u64 = (UInt64*)&src[idx * sizeof(UInt64)]; + stat_buff_u64[idx] += *temp_ptr_u64; + } +} + +BOOL32 _updateLowerStats(UInt32 struct_type, void * struct_buffer, UInt32 struct_size) +{ + UInt32 this_size; + UInt64 curr_stat_buf[AND_STATISTICS_SIZE_PER_LAYER/sizeof(UInt64)]; + + this_size = AND_STATISTICS_SIZE_PER_LAYER; + sftl.vfl->GetStruct(struct_type, curr_stat_buf, &this_size); + _UpdateStatisticsCounters((UInt8*)struct_buffer, curr_stat_buf, this_size); + sftl.vfl->SetStruct(struct_type, curr_stat_buf, this_size); + + return TRUE32; +} + +#undef X_FTL_doStat +#define X_FTL_doStat(_part, _val) do { if (key == S_STATKEY_ ## _part) { sftl.stats._part += val64; continue; } } while(0); +FTL_makeStatParser(s_stats_from_buf_jump, _updateLowerStats, _updateLowerStats) +void s_stats_from_buf(UInt8 *buf, UInt32 size) +{ + WMR_MEMSET(&sftl.stats, 0, sizeof(sftl.stats)); + s_stats_from_buf_jump(buf, size); +} + +void s_stats_insert(void) +{ + UInt32 *buf; + + // Put stats in buffer + buf = (UInt32*)sftl.tmpBuf; + s_stats_to_buf(buf); + + // Insert the token + s_token_insert(S_LBA_STATS, buf); +} + +void s_stats_update(void) +{ + // Update stats from various places + sftl.stats.valid_lbas = sftl.seaState.validLbas; + sftl.stats.free_sb = sftl.seaState.free_sb; + sftl.stats.data_sb = sftl.seaState.data_sb; + sftl.stats.cxt_sb = sftl.seaState.cxt_sb; + sftl.stats.dead_sb = sftl.seaState.dead_sb; + sftl.stats.L2V_pool_free = L2V.Pool.FreeCount; + sftl.stats.L2V_pool_count = L2V_nodepool_mem / sizeof(lNode_t); +} + +#endif // !AND_READONLY diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.h new file mode 100644 index 0000000..5b25c76 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_stats.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_STATS_H__ +#define __S_STATS_H__ + +#include "s_internal.h" + +#ifndef AND_READONLY + +extern void s_stats_from_buf(UInt8 *buf, UInt32 size); +extern UInt32 s_stats_to_buf(UInt32 *buf); + +extern void s_stats_insert(void); + +extern void s_stats_update(void); + +#else // ->!AND_READONLY + +#define s_stats_from_buf(x, y) +#define s_stats_to_buf(x) 0 +#define s_stats_insert() +#define s_stats_update() + +#endif // !AND_READONLY + +#endif // __S_STATS_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.c new file mode 100644 index 0000000..25a0b7a --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "s_token.h" +#include "s_geom.h" + +void s_token_insert(UInt32 tokenLba, UInt32 *srcBuf) +{ + UInt32 *dstBuf; + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + + WMR_ASSERT(wr->bufLbas < wr->bufSize); + + // Put in buffer + dstBuf = (UInt32*)&wr->bufPage[s_g_mul_bytes_per_lba(wr->bufLbas)]; + WMR_MEMCPY(dstBuf, srcBuf, s_g_bytes_per_lba); + + // Meta + s_SetupMeta_IntData(&wr->bufMeta[wr->bufLbas], tokenLba, 1, wr->pageFlags);; + + // Next + wr->bufLbas++; +} + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.h new file mode 100644 index 0000000..742acc4 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_token.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_TOKEN_H__ +#define __S_TOKEN_H__ + +#include "s_internal.h" + +extern void s_token_insert(UInt32 tokenLba, UInt32 *srcBuf); + +#endif // __S_TOKEN_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.c new file mode 100644 index 0000000..c73a643 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "s_internal.h" +#include "s_trim.h" +#include "s_token.h" +#include "s_write.h" +#include "s_flatten.h" +#include "s_sb.h" +#include "s_gc.h" +#include "s_geom.h" +#include "s_stats.h" +#include "s_dbg.h" + +#ifndef AND_READONLY + +#define BLOOM_BITS (sizeof(*sftl.trim.bloomFilter)*8) +#define VULNERABLE_BITS (sizeof(*sftl.trim.vulnerable)*8) + +BOOL32 s_trim_init(void) +{ + sftl.trim.count = 0; + sftl.trim.sumSpan = 0; + sftl.trim.max = ((s_g_bytes_per_lba - sizeof(UInt32)) / sizeof(s_trim_item_t)); + sftl.trim.vulnerableWords = (s_g_vfl_max_sb+VULNERABLE_BITS-1)/VULNERABLE_BITS; + sftl.trim.bloomFilterWords = ((((s_g_vfl_max_sb * s_g_vbas_per_sb) + S_TRIM_BLOOMFILTER_SPAN - 1) / S_TRIM_BLOOMFILTER_SPAN) + BLOOM_BITS-1) / BLOOM_BITS; + + sftl.trim.item = WMR_MALLOC(s_g_bytes_per_lba); + sftl.trim.vulnerable = WMR_MALLOC(sftl.trim.vulnerableWords * sizeof(*sftl.trim.vulnerable)); + sftl.trim.bloomFilter = WMR_MALLOC(sftl.trim.bloomFilterWords * sizeof(*sftl.trim.bloomFilter)); + return (NULL != sftl.trim.item) && (NULL != sftl.trim.vulnerable) && (NULL != sftl.trim.bloomFilter); +} + +void s_trim_close(void) +{ + sftl.trim.count = 0; + sftl.trim.sumSpan = 0; + if (NULL != sftl.trim.item) { + WMR_FREE(sftl.trim.item, s_g_bytes_per_lba); + sftl.trim.item = NULL; + } + if (NULL != sftl.trim.vulnerable) { + WMR_FREE(sftl.trim.vulnerable, sftl.trim.vulnerableWords * sizeof(*sftl.trim.vulnerable)); + sftl.trim.vulnerable = NULL; + } + if (NULL != sftl.trim.bloomFilter) { + WMR_FREE(sftl.trim.bloomFilter, sftl.trim.bloomFilterWords * sizeof(*sftl.trim.bloomFilter)); + sftl.trim.bloomFilter = NULL; + } +} + +void s_trim_apply(BOOL32 token) +{ + s_trim_t *const trim = &sftl.trim; + UInt32 *base; + UInt32 *buf; + Int32 i; + + base = (UInt32*)sftl.tmpBuf; + buf = base; + *buf++ = trim->count; + for (i = 0; i < trim->count; i++) { + if (L2V_LowMem && ((trim->item[i].lbaEnd-trim->item[i].lba) < S_TRIM_CUTOFF_LOWMEM)) { + (*base)--; + continue; + } + *buf++ = trim->item[i].lba; + *buf++ = trim->item[i].lbaEnd - trim->item[i].lba; + L2V_Update(trim->item[i].lba, trim->item[i].lbaEnd - trim->item[i].lba, L2V_VBA_DEALLOC); + } + trim->count = 0; + trim->sumSpan = 0; + + if (token) { + s_token_insert(S_TOK_DELETE, (UInt32*)sftl.tmpBuf); + s_write_push_full_buf(TRUE32); + } + + // Clear bloom filter + WMR_MEMSET(sftl.trim.bloomFilter, 0, sftl.trim.bloomFilterWords * sizeof(*sftl.trim.bloomFilter)); +} + +Int32 sftl_unmap(FTLExtent_t *extents, UInt32 numExtents) +{ + s_trim_t *const trim = &sftl.trim; + UInt32 sb, lba, span, t, lbaEnd; + UInt32 bloomBucket, bloomBucketMax; + + while (numExtents--) { + lba = (UInt32)extents->lba; + span = (UInt32)extents->span; + lbaEnd = lba + span; + WMR_ASSERT((lba + span) <= sftl.reported_lba); + + bloomBucketMax = lbaEnd / S_TRIM_BLOOMFILTER_SPAN; + for (bloomBucket = lba / S_TRIM_BLOOMFILTER_SPAN; bloomBucket <= bloomBucketMax; bloomBucket++) { + trim->bloomFilter[bloomBucket / BLOOM_BITS] |= 1 << (bloomBucket & (BLOOM_BITS-1)); + } + + // Insert into pending list, or compress + if (trim->count && (trim->item[trim->count-1].lbaEnd == lba)) { + trim->item[trim->count-1].lbaEnd = lbaEnd; + } else { + trim->item[trim->count].lba = lba; + trim->item[trim->count].lbaEnd = lbaEnd; + trim->count++; + } + trim->sumSpan += span; + + // Push trim vba? + if (trim->count >= trim->max) { + s_trim_apply(TRUE32); + } + + s_dbg_check_data_counts(); + if ((0 == lba) && (sftl.reported_lba == span)) { + s_trim_apply(TRUE32); + // Erase all pending + for (sb = 0; sb < s_g_max_sb; sb++) { + t = s_sb_get_type(sb); + if ((S_SB_PENDING_ERASE == t) || (S_SB_ERASE_BEFORE_USE == t)) { + s_sb_boot_free_erase(sb); + } + } + } + s_dbg_check_data_counts(); + + // Move along + extents++; + } + + // Enough to justify an early push of the token? + if ((trim->sumSpan >= S_TRIM_SUMSPAN_TRIGGER) && (L2V_LowMem || lowData(s_g_vbas_per_sb))) { + s_trim_apply(TRUE32); + s_drain_stream_cur(TRUE32); + } + + s_stats_update(); + return ANDErrorCodeOk; +} + +void s_trim_writeCollide(UInt32 lba, UInt32 span) +{ + s_trim_t *const trim = &sftl.trim; + Int32 i, j; + UInt32 tLbaMin, tLbaMax; + UInt32 lbaEnd; + BOOL32 bloomHit; + UInt32 bloomBucket, bloomBucketMax; + + lbaEnd = lba + span; + + // Check bloom filter + bloomHit = FALSE32; + bloomBucketMax = lbaEnd / S_TRIM_BLOOMFILTER_SPAN; + for (bloomBucket = lba / S_TRIM_BLOOMFILTER_SPAN; bloomBucket <= bloomBucketMax; bloomBucket++) { + if (trim->bloomFilter[bloomBucket / BLOOM_BITS] & (1 << (bloomBucket & (BLOOM_BITS-1)))) { + bloomHit = TRUE32; + break; + } + } + if (!bloomHit) { + return; + } + + // Find and manage collisions + for (i = 0; i < trim->count; i++) { + tLbaMin = trim->item[i].lba; + tLbaMax = trim->item[i].lbaEnd; + + if (!((tLbaMax <= lba) || (lbaEnd <= tLbaMin))) { + // Identity hit or eclipse? + if ((lba <= tLbaMin) && (lbaEnd >= tLbaMax)) { + // Slip back + trim->sumSpan -= (tLbaMax - tLbaMin); + for (j = i; j < (trim->count-1); j++) { + trim->item[j] = trim->item[j+1]; + } + trim->count--; + i--; + } + // Left-chop? + else if ((lbaEnd < tLbaMax) && (lba <= tLbaMin)) { + trim->sumSpan -= (lbaEnd - tLbaMin); + trim->item[i].lba = lbaEnd; + } + // Right-chop? + else if ((lba > tLbaMin) && (lbaEnd >= tLbaMax)) { + trim->sumSpan -= (tLbaMax - lba); + trim->item[i].lbaEnd = lba; + } + // Middle chop + else { + WMR_ASSERT(lba > tLbaMin); + WMR_ASSERT(lbaEnd < tLbaMax); + + // No room to slip forward? Drop it and move on + if ((trim->count+1) >= trim->max) { + s_trim_apply(TRUE32); + return; + } + // Slip forward + for (j = trim->count; j > i; j--) { + trim->item[j] = trim->item[j-1]; + } + trim->count++; + + // Make right chop + trim->item[i+1].lba = lbaEnd; + + // Chop to left + trim->item[i].lbaEnd = lba; + + trim->sumSpan -= span; + } + } + } +} + +void s_trim_markVulnerable(UInt32 vba) +{ + s_trim_t *const trim = &sftl.trim; + UInt32 sb; + + sb = s_g_vba_to_sb(vba); + + WMR_ASSERT((sb / VULNERABLE_BITS) < trim->vulnerableWords); + trim->vulnerable[sb / VULNERABLE_BITS] |= (1 << (sb & (VULNERABLE_BITS-1))); +} + +void s_trim_clearVulnerables(void) +{ + s_trim_t *const trim = &sftl.trim; + + WMR_MEMSET(trim->vulnerable, 0, trim->vulnerableWords * sizeof(*trim->vulnerable)); +} + +void s_trim_checkVulnerable(UInt32 sb) +{ + s_trim_t *const trim = &sftl.trim; + + if (trim->vulnerable[sb / VULNERABLE_BITS] & (1 << (sb & (VULNERABLE_BITS-1)))) { + // Force a cxt save on the next write + sftl.cxt.periodic.sbsSince = S_CXT_PERIOD_SBS; + } +} + +#endif + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.h new file mode 100644 index 0000000..739522e --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_trim.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_TRIM_H__ +#define __S_TRIM_H__ + +#include "FTL.h" +#include "s_internal.h" + +// Lifecycle +extern BOOL32 s_trim_init(void); +extern void s_trim_close(void); + +// Trimmers +extern Int32 sftl_unmap(FTLExtent_t *extents, UInt32 numExtents); + +// Write collision +extern void s_trim_apply(BOOL32 token); +extern void s_trim_writeCollide(UInt32 lba, UInt32 span); + +// Vulnerability management +extern void s_trim_markVulnerable(UInt32 vba); +extern void s_trim_clearVulnerables(void); +extern void s_trim_checkVulnerable(UInt32 sb); + +#endif // __S_TRIM_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.c new file mode 100644 index 0000000..c0a8dcc --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#define AND_TRACE_LAYER FTL + +#include "WMRConfig.h" +#include "s_readdist.h" +#include "s_wearlev.h" +#include "s_geom.h" +#include "s_gc.h" +#include "s_sb.h" +#include "s_bg.h" + +#ifndef AND_READONLY + +void s_wearlev_search(void) +{ + UInt32 i, erases, type; + UInt32 curErases, sb, refreshSB; + UInt32 maxErases; + UInt32 maxDynErases; + + // Early out: not our time yet + if (sftl.wearLev.blocksSince < S_WEARLEV_PERIOD) { + return; + } + sftl.wearLev.blocksSince -= S_WEARLEV_PERIOD; + + WMR_TRACE_IST_0(WearLevel, START); + + // Find lowest-cycled static data superblock + maxErases = 0; + maxDynErases = 0; + curErases = ~0; + sb = ~0; + refreshSB = ~0; + for (i = 0; i < s_g_max_sb; i++) { + // Filter for data SB + type = s_sb_get_type(i); + if (S_SB_DATA != type) { + continue; + } + + erases = s_sb_get_erases(i); + + // Is it lowest-cycled and static (old data)? + if ((erases < curErases) && S_USERSEQ_IS_OLD(sftl.sb_userSeq[i].avg)) { + // Minify + curErases = erases; + sb = i; + } + + if (erases > maxErases) { + // Maxify + maxErases = erases; + } + + if (!S_USERSEQ_IS_OLD(sftl.sb_userSeq[i].avg) && (erases > maxDynErases)) { + // Maxify dynamic-sb erases + maxDynErases = erases; + } + + if ((~((UInt32)0) == refreshSB) && (sftl.sb[i].reads >= S_READDIST_LIMIT_PER_SB) && (sb != i)) + { + refreshSB = i; + } + } + + // Don't wear-level unless the lowest-cycled static block makes the gap big + if ((curErases + S_WEARLEV_MIN_GAP) >= maxErases) { + sb = ~0; + } + + // Don't wear-level unless the highest-cycled dynamic superblock is approaching the gap + if ((maxDynErases + S_WEARLEV_DYN_GAP) < maxErases) { + sb = ~0; + } + + // Put into high-cycled superblock; GC will use the static flags to partition + if (~((UInt32)0) != refreshSB) + { + sftl.stats.readCount_gcs++; + s_bg_enq(refreshSB, TRUE32); + } + else + { + if (~((UInt32)0) != sb) + { + sftl.stats.wearLev_gcs++; + s_bg_enq(sb, TRUE32); + } + } + + WMR_TRACE_IST_0(WearLevel, END); +} + +#endif // AND_READONLY diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.h new file mode 100644 index 0000000..afef846 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_wearlev.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_WEARLEV_H__ +#define __S_WEARLEV_H__ + +#include "s_internal.h" + +#define s_wearlev_cross_block() do { sftl.wearLev.blocksSince++; } while(0) +extern void s_wearlev_search(void); + +#endif // __S_WEARLEV_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.c new file mode 100644 index 0000000..540dcb7 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.c @@ -0,0 +1,710 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#define AND_TRACE_LAYER FTL + +#include "s_internal.h" +#include "s_write.h" +#include "s_btoc.h" +#include "s_meta.h" +#include "s_sb.h" +#include "s_gc.h" +#include "s_bg.h" +#include "s_dbg.h" +#include "s_cxt.h" +#include "s_token.h" +#include "s_flatten.h" +#include "s_geom.h" +#include "s_stats.h" +#include "s_trim.h" +#include "s_wearlev.h" + +#ifndef AND_READONLY + +// Prototypes: +BOOL32 s_write_multi_internal(s_write_multi_t *wm); +BOOL32 handleRagged(BOOL32 front, s_write_multi_t *wm, BOOL32 forceWrite, BOOL32 *wrotePage); + +BOOL32 s_write_init(void) +{ + UInt32 i; + + // Initialize to a known state + for (i = 0; i < S_SBSTREAM_MAX; i++) { + sftl.write.stream[i].sb = 0xffffffff; + sftl.write.stream[i].abandon = FALSE32; + sftl.write.stream[i].pageFlags = 0; + } + + // Set up the static stream to contain the static flag + sftl.write.stream[S_SBSTREAM_STATIC].pageFlags = PFLAG_STATIC; + + // Init write-multis + sftl.write.drain_wm.lba = (UInt32*)WMR_MALLOC(sizeof(UInt32)); + sftl.write.drain_wm.subCount = (UInt32*)WMR_MALLOC(sizeof(UInt32)); + sftl.write.host_wm.lba = (UInt32*)WMR_MALLOC(sizeof(UInt32)); + sftl.write.host_wm.subCount = (UInt32*)WMR_MALLOC(sizeof(UInt32)); + sftl.write.pad_wm.lba = (UInt32*)WMR_MALLOC(sizeof(UInt32)); + sftl.write.pad_wm.subCount = (UInt32*)WMR_MALLOC(sizeof(UInt32)); + + if ( (NULL == sftl.write.drain_wm.lba) || (NULL == sftl.write.drain_wm.subCount) + || (NULL == sftl.write.host_wm.lba) || (NULL == sftl.write.host_wm.subCount) + || (NULL == sftl.write.pad_wm.lba) || (NULL == sftl.write.pad_wm.subCount) + ) + { + return FALSE32; + } + + return TRUE32; +} + +void s_write_close(void) +{ + // Free the memory + if (NULL != sftl.write.drain_wm.lba) { + WMR_FREE(sftl.write.drain_wm.lba, sizeof(UInt32)); + } + if (NULL != sftl.write.drain_wm.subCount) { + WMR_FREE(sftl.write.drain_wm.subCount, sizeof(UInt32)); + } + if (NULL != sftl.write.host_wm.lba) { + WMR_FREE(sftl.write.host_wm.lba, sizeof(UInt32)); + } + if (NULL != sftl.write.host_wm.subCount) { + WMR_FREE(sftl.write.host_wm.subCount, sizeof(UInt32)); + } + if (NULL != sftl.write.pad_wm.lba) { + WMR_FREE(sftl.write.pad_wm.lba, sizeof(UInt32)); + } + if (NULL != sftl.write.pad_wm.subCount) { + WMR_FREE(sftl.write.pad_wm.subCount, sizeof(UInt32)); + } + // Null out the pointers + sftl.write.drain_wm.lba = NULL; + sftl.write.drain_wm.subCount = NULL; + sftl.write.host_wm.lba = NULL; + sftl.write.host_wm.subCount = NULL; + sftl.write.pad_wm.lba = NULL; + sftl.write.pad_wm.subCount = NULL; +} + +void s_write_switch(UInt32 stream) +{ + WMR_ASSERT(stream < S_SBSTREAM_MAX); + sftl.write.curStream = stream; +} + +void s_write_host_switch(UInt32 stream) +{ + if (stream != sftl.write.curStream) { + s_drain_stream_cur(TRUE32); + s_write_switch(stream); + } +} + +void s_write_gc_switch(UInt32 stream) +{ + if (stream != sftl.write.curStream) { + s_drain_stream(sftl.write.curStream, FALSE32); + s_write_switch(stream); + } +} + +void s_write_push_full_buf(BOOL32 doGC) +{ + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + + if (wr->bufLbas >= wr->bufSize) { + s_drain_stream_cur(doGC); + } +} + +void s_drain_stream_cur(BOOL32 doGC) +{ + s_drain_stream(sftl.write.curStream, doGC); +} + +BOOL32 s_drain_stream(UInt32 stream, BOOL32 doGC) +{ + BOOL32 wrotePage = FALSE32; + s_wrstream_t *wr; + s_write_multi_t *const wm = &sftl.write.drain_wm; + + wr = &sftl.write.stream[stream]; + + // MUST BE REENTRANT: called by sftl_shutdown_notify, get a pfail call gc, calls this again + + if (0 == wr->bufLbas) { + return FALSE32; + } + + // Switch streams + s_write_switch(stream); + + WMR_ASSERT(wr->bufLbas <= wr->bufSize); + +again: + // Check if we're already drained (because GC did it for us) + if (0 == wr->bufLbas) { + return FALSE32; + } + + // Allocate a superblock if we don't have one + if (0xffffffff == wr->sb) { + s_sb_next(sftl.write.curStream); + } + + // Pad to page boundary + while (wr->bufLbas & (s_g_vbas_per_page-1)) { + s_stats_insert(); + } + + // Set up the wm + wm->buf = wr->bufPage; + wm->meta = wr->bufMeta; + wm->gc = FALSE32; + wm->flatten = FALSE32; + wm->count = 0; + + // Push the page + if (!handleRagged(TRUE32, wm, TRUE32, &wrotePage)) { + s_write_reseq(); + WMR_ASSERT(wrotePage); + if (doGC) { + s_write_handle_pfail(); + goto again; + } else { + s_gc_data_enq(sftl.write.stream[sftl.write.curStream].sb, S_GC_CTX_FG); + s_sb_next_cur(); + goto again; + } + } + WMR_ASSERT(wrotePage); + + return TRUE32; +} + +void s_drain_stream_all(BOOL32 doGC) +{ + UInt32 i; + BOOL32 drained; + + // Drain all streams until they are all clean, so GC doesn't leave any hanging + do { + drained = FALSE32; + for (i = 0; i < S_SBSTREAM_MAX; i++) { + drained |= s_drain_stream(i, doGC); + } + } while (drained); +} + +BOOL32 sftl_shutdown_notify(BOOL32 ignoredOption) +{ + UInt16 i; + + s_dbg_check_data_counts(); + s_drain_stream_all(TRUE32); + s_dbg_check_data_counts(); + + // BG shutdown + s_gc_bg_shutdown(); + + // Erase all pending-erase without BTOC + for (i = 0; i < s_g_max_sb; i++) { + if (S_SB_PENDING_ERASE == s_sb_get_type(i)) { + sftl.seaState.vbas_in_free_sb -= sftl.vfl->GetVbasPerVb(i); + sftl.vfl->Erase(i, TRUE32); + sftl.seaState.vbas_in_free_sb += sftl.vfl->GetVbasPerVb(i); + s_sb_set_type(i, S_SB_ERASED); + s_sb_log_erase(i); + sftl.seaState.erased_sb++; + } + } + s_dbg_check_data_counts(); + + sftl.stats.shutdowns++; + + // Save context + s_cxt_save(); + s_dbg_check_data_counts(); + + return TRUE32; +} + +void btoc_terminate(void) +{ + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + wr->BTOC[wr->BTOCidx].count = 0; +} + +void s_write_handle_pfail(void) +{ + UInt32 old_sb; + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + + old_sb = wr->sb; + btoc_terminate(); + s_sb_next_cur(); + + if (S_SB_DATA == s_sb_get_type(old_sb)) { + // Only GC it if it wasn't taken care of by DeleteSectors + s_gc_data(old_sb, TRUE32); + } +} + +void s_write_reseq(void) +{ + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + UInt32 i; + + // Resequence metadata for buffered content + for (i = 0; i < wr->bufLbas; i++) { + META_SET_WEAVESEQ(&wr->bufMeta[i]); + } +} + +Int32 sftl_write(UInt32 lba, UInt32 span, UInt8 *buf, BOOL32 isStatic) +{ + s_write_multi_t *const wm = &sftl.write.host_wm; + UInt32 origSpan = span; + + WMR_TRACE_4(Write, START, lba, span, buf, isStatic); + + s_dbg_check_data_counts(); + + s_debug(WRITE, " sftl_write[start] 0x%x 0x%x isStatic: %s", lba, span, (isStatic)?"YES":"NO"); + + sftl.stats.xacts_write++; + switch (span) + { + case 0 : break; + case 1 : sftl.stats.lbas_write_1++; + break; + case 2 : sftl.stats.lbas_write_2++; + break; + case 3 : sftl.stats.lbas_write_3++; + break; + case 4 : sftl.stats.lbas_write_4++; + break; + case 5 : sftl.stats.lbas_write_5++; + break; + case 6 : sftl.stats.lbas_write_6++; + break; + case 7 : sftl.stats.lbas_write_7++; + break; + case 8 : sftl.stats.lbas_write_8++; + break; + default : sftl.stats.lbas_write_over_8++; + } + + if ((lba + span) >= sftl.max_lba) + { + WMR_TRACE_1(Write, END, ANDErrorCodeHwErr); + return ANDErrorCodeHwErr; + } + + s_trim_writeCollide(lba, span); + + wm->blockStartLba = lba; + wm->blockStartCnt = span; + wm->blockStartBuf = buf; +recoverPfail: + // Restore counters + lba = wm->blockStartLba; + span = wm->blockStartCnt; + + // Flatten and GC until we're happy about both + do { + while (!s_flatten()) { + // Program failure? + s_write_reseq(); + s_write_handle_pfail(); + } + + // Do garbage collection prior to the write + s_gc_prewrite(span); + } while (L2V_LowMem); + + // Switch to the appropriate stream + if (isStatic) { + s_write_host_switch(S_SBSTREAM_STATIC); + sftl.stats.lbas_written_static += span; + } else { + s_write_host_switch(S_SBSTREAM_DYN); + sftl.stats.lbas_written_dynamic += span; + } + + // Set up write_multi struct for a single write + wm->gc = FALSE32; + wm->flatten = FALSE32; + wm->lba[0] = wm->blockStartLba; + wm->subCount[0] = wm->blockStartCnt; + wm->buf = wm->blockStartBuf; + wm->meta = sftl.write.meta; + wm->count = wm->blockStartCnt; + wm->len = 1; + wm->cur = 0; + + if (!s_write_multi_internal(wm)) { + s_write_reseq(); + L2V_Update(wm->blockStartLba, wm->blockStartCnt, L2V_VBA_DEALLOC); + s_write_handle_pfail(); + goto recoverPfail; + } + + sftl.stats.lbas_written += origSpan; + + s_wearlev_search(); // find a target if appropriate + s_bg_write(origSpan); + +#if AND_SWISS_DRAIN_AFTER_WRITE + // Only for EFI/diags... + s_drain_stream_all(TRUE32); +#endif + + // Periodic cxt save for ANDStats preservation + s_cxt_periodic(); + + s_stats_update(); + + s_dbg_check_data_counts(); + + WMR_TRACE_1(Write, END, ANDErrorCodeOk); + + return ANDErrorCodeOk; +} + +static BOOL32 advance_sb(s_write_multi_t *wm) +{ + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + + if (s_btoc_isFull()) { + WMR_ASSERT((wr->nextVbaOfs + wr->BTOC_vba) == wr->maxVbaOfs); + if (!s_btoc_cross_data()) { + return FALSE32; + } + if(wm->padding) { + wm->blockStartLba = 0xffffffff; + } else { + if (wm->cur < wm->len) { + wm->blockStartLba = wm->lba[wm->cur]; + wm->blockStartCnt = wm->count; + wm->blockStartBuf = wm->buf; + } + } + } + + return TRUE32; +} + +BOOL32 handleRagged(BOOL32 front, s_write_multi_t *wm, BOOL32 forceWrite, BOOL32 *wrotePage) +{ + s_wrstream_t *wr = &sftl.write.stream[sftl.write.curStream]; + UInt32 i, lba, vba, bufIdx, bufMax, thisCount = 0; + + *wrotePage = FALSE32; + + if (front && (0 == wr->bufLbas)) { + // Don't buffer anything up + return TRUE32; + } + + if (((sftl.write.weaveSeq + wm->count) - wr->minWeaveSeq) >= S_WEAVE_SEQ_ADD_TRS) { + s_sb_next(sftl.write.curStream); + wr = &sftl.write.stream[sftl.write.curStream]; + } + + bufMax = wr->bufSize; + if (bufMax >= s_g_vbas_per_stripe) { + if (wr->bufLbas <= (bufMax - s_g_mod_vbas_per_stripe(wr->nextVbaOfs))) { + bufMax -= s_g_mod_vbas_per_stripe(wr->nextVbaOfs); + } + } + + // Don't buffer too much if we're going to program later anyway + if (front && (wm->count >= (bufMax - wr->bufLbas) + wr->bufThreshold)) { + bufMax = S_ROUNDUP_POW2(wr->bufLbas, s_g_vbas_per_page); + } + WMR_ASSERT(bufMax <= wr->bufSize); + + while ((wr->bufLbas < bufMax) && wm->count) { + thisCount = WMR_MIN(wm->subCount[wm->cur], bufMax - wr->bufLbas); + + // Put in buffer + WMR_PERFORM_AES(&wr->bufPage[s_g_mul_bytes_per_lba(wr->bufLbas)], wm->buf, thisCount, s_g_bytes_per_lba); + if (!wm->gc) { + s_SetupMeta_Data(&wr->bufMeta[wr->bufLbas], wm->lba[wm->cur], thisCount, wr->pageFlags); + } else { + // Copy over flags, userWeaveSeq, lba + WMR_MEMCPY(&wr->bufMeta[wr->bufLbas], wm->meta, s_g_mul_bytes_per_lba_meta(thisCount)); + s_SetupMeta_DataGC(&wr->bufMeta[wr->bufLbas], thisCount); + } + + // Next + wr->bufLbas += thisCount; + wm->count -= thisCount; + wm->lba[wm->cur] += thisCount; + wm->subCount[wm->cur] -= thisCount; + if (0 == wm->subCount[wm->cur]) { + wm->cur++; + } + wm->buf += s_g_mul_bytes_per_lba(thisCount); + if (wm->gc) { + wm->meta += thisCount; + } + } + + // Write a buffer? + WMR_ASSERT(wr->bufLbas <= bufMax); + if ((wr->bufLbas == bufMax) || forceWrite) { + bufIdx = 0; + WMR_ASSERT(0 == (wr->bufLbas & (s_g_vbas_per_page-1))); + while (bufIdx < wr->bufLbas) { + // May be necessary to move forward now + if (!advance_sb(wm)) { + return FALSE32; + } + + thisCount = WMR_MIN(wr->bufLbas - bufIdx, (wr->maxVbaOfs - wr->nextVbaOfs - wr->BTOC_vba)); + thisCount = s_btoc_update_size(thisCount); + thisCount = WMR_MIN(thisCount, (wr->maxVbaOfs - wr->nextVbaOfs - wr->BTOC_vba)); + + if (0 == thisCount) { + // Necessary if BTOC and user write just met + continue; + } + + vba = s_g_addr_to_vba(wr->sb, wr->nextVbaOfs); + *wrotePage = TRUE32; + if (!sftl.vfl->ProgramMultipleVbas(vba, thisCount, &wr->bufPage[s_g_mul_bytes_per_lba(bufIdx)], (UInt8*)&wr->bufMeta[bufIdx], TRUE32, TRUE32)) { + WMR_PRINT(QUAL, "sftl: program failure sb:%d vba:0x%x\n", wr->sb, vba); + return FALSE32; + } + for (i = 0; i < thisCount; i++) { + // Update TOC: + lba = META_GET_LBA(&wr->bufMeta[bufIdx+i]); + s_btoc_add_data(vba+i, lba, 1, META_GET_WEAVESEQ(&wr->bufMeta[bufIdx+i]), META_GET_USERSEQ(&wr->bufMeta[bufIdx+i])); + // Tree: update + if (L2V_VBA_SPECIAL > lba) { + L2V_Update(lba, 1, vba + i); + } else if (S_TOK_DELETE == lba) { + s_trim_markVulnerable(vba); + } + } + + // Next + WMR_ASSERT(wr->nextVbaOfs <= wr->maxVbaOfs); + bufIdx += thisCount; + } + + // Buffer is now empty + wr->bufLbas = 0; + } + + // Advance superblock if we went far enough + if (!advance_sb(wm)) { + return FALSE32; + } + + return TRUE32; +} + +BOOL32 s_write_multi_internal(s_write_multi_t *wm) +{ + UInt32 vba, updCount, updatedNoOfBanks, updatedVbasInSb, updatedMegaStripeSize; + UInt32 toMegaStripeEnd, toBlockEnd, thisCount, chunk, wmThis, i; + BOOL32 wrotePage; + WeaveSeq_t weaveSeq; + s_wrstream_t *const wr = &sftl.write.stream[sftl.write.curStream]; + + // Allocate a superblock if we don't have one + if ((0xffffffff == wr->sb) || ((wr->sb < s_g_max_sb) && ((sftl.write.weaveSeq - wr->minWeaveSeq) >= S_WEAVE_SEQ_ADD_TRS))) { + s_sb_next(sftl.write.curStream); + } + + // Finish prior ragged edge: + if (!handleRagged(TRUE32, wm, FALSE32, &wrotePage)) { + return FALSE32; + } else { + if((wm->padding) && (wm->blockStartLba != S_TOK_PAD)) { + return TRUE32; + } + } + + // Program enough so the buffer won't be too full in post-write handleRagged + while (wr->bufThreshold <= wm->count) { + // Advance superblock? + if (!advance_sb(wm)) { + return FALSE32; + } else { + if((wm->padding) && (wm->blockStartLba != S_TOK_PAD)) { + return TRUE32; + } + } + + // How much room do we have? + wmThis = s_btoc_update_size(wm->len - wm->cur); + thisCount = 0; + for (i = 0; i < wmThis; i++) { + thisCount += wm->subCount[wm->cur+i]; + } + + if((updatedVbasInSb = sftl.vfl->GetVbasPerVb(wr->sb)) != (s_g_vbas_per_sb)) + { + updatedNoOfBanks = updatedVbasInSb / ((s_g_vbas_per_sb) / (s_g_num_banks)); + updatedMegaStripeSize = ROUNDDOWNTO(sftl.write.meta_size, (updatedNoOfBanks * s_g_vbas_per_page)); + WMR_ASSERT(0 != updatedMegaStripeSize); + } + else + { + updatedNoOfBanks = (s_g_num_banks); + updatedMegaStripeSize = sftl.write.meta_size; + } + // How many this round? Do up to a megastripe (aligned) + toMegaStripeEnd = updatedMegaStripeSize - (wr->nextVbaOfs % (updatedNoOfBanks * (s_g_vbas_per_page))); + toBlockEnd = (wr->maxVbaOfs - wr->nextVbaOfs - wr->BTOC_vba); + thisCount = WMR_MIN(WMR_MIN(thisCount, wm->count & ~(s_g_vbas_per_page-1)), WMR_MIN(toMegaStripeEnd, toBlockEnd)); + + if (0 == thisCount) { + // Necessary if BTOC and user write just met + continue; + } + + // Generate metadata + weaveSeq = sftl.write.weaveSeq; + if (!wm->gc) { + if(wm->padding) { + s_SetupMeta_Data_Padding(wm->meta, thisCount, wr->pageFlags); + } + else { + s_SetupMeta_Data(wm->meta, wm->lba[wm->cur], thisCount, wr->pageFlags); + } + } else { + s_SetupMeta_DataGC(wm->meta, thisCount); + if (!wm->flatten) { + wr->gcDataAdjust += thisCount; + sftl.write.sum_gcDataAdjust += thisCount; + } + } + + // Write the data + vba = s_g_addr_to_vba(wr->sb, wr->nextVbaOfs); + if (!sftl.vfl->ProgramMultipleVbas(vba, thisCount, wm->buf, (UInt8*)wm->meta, TRUE32, wm->gc)) { + WMR_PRINT(QUAL, "sftl: program failure sb:%d vba:0x%x\n", wr->sb, vba); + return FALSE32; + } + + updCount = thisCount; + while (updCount) { + chunk = WMR_MIN(updCount, wm->subCount[wm->cur]); + + // Update TOC: + WMR_ASSERT(0 != chunk); + s_btoc_add_data(vba, wm->lba[wm->cur], chunk, weaveSeq, META_GET_USERSEQ(wm->meta)); + + // Tree: update + if(!wm->padding) { + L2V_Update(wm->lba[wm->cur], chunk, vba); + } + + // Next + weaveSeq += chunk; + vba += chunk; + updCount -= chunk; + wm->lba[wm->cur] += chunk; + wm->subCount[wm->cur] -= chunk; + if (0 == wm->subCount[wm->cur]) { + wm->cur++; + } + } + + // Next + wm->count -= thisCount; + wm->buf += s_g_mul_bytes_per_lba(thisCount); + if (wm->gc) { + wm->meta += thisCount; + } + } + + // Advance sb, if the last write took us to the end + if (!advance_sb(wm)) { + return FALSE32; + } else { + if((wm->padding) && (wm->blockStartLba != S_TOK_PAD)) { + return TRUE32; + } + } + + // Buffer up ending ragged edge + if (wm->count) { + WMR_ASSERT(0 == wr->bufLbas); + } + wrotePage = FALSE32; + while (wm->count) { + if (!handleRagged(FALSE32, wm, FALSE32, &wrotePage)) { + return FALSE32; + } + } + + return TRUE32; +} + +BOOL32 s_pad_block(UInt32 block) +{ + s_write_multi_t *const wm = &sftl.write.pad_wm; + UInt8 i; + + if ((s_sb_get_num_btoc_vbas(block) > 0) || (S_SB_DATA_CUR != s_sb_get_type(block))) { + // Simplify caller logic--no work->success + return TRUE32; + } + + for (i = 0; i < S_SBSTREAM_MAX; i++) { + if(block == sftl.write.stream[i].sb) { + break; + } + } + + + if(i < S_SBSTREAM_MAX) { + s_write_switch(i); + } + else { + return FALSE32; + } + + + s_drain_stream(i, TRUE32); + + if(block != sftl.write.stream[i].sb) { + return TRUE32; + } + + // Set up the write multi + wm->blockStartLba = S_TOK_PAD; + wm->blockStartCnt = WMR_MIN(sftl.gc.zoneSize, s_g_num_banks * s_g_vbas_per_page); + wm->gc = FALSE32; + wm->flatten = FALSE32; + wm->padding = TRUE32; + wm->buf = sftl.gc.zone; + wm->meta = sftl.write.meta; + wm->count = WMR_MIN(sftl.gc.zoneSize, s_g_num_banks * s_g_vbas_per_page); + wm->subCount[0] = wm->count; + wm->len = 1; + wm->cur = 0; + wm->lba[0] = S_TOK_PAD; + + return s_write_multi_internal(wm); +} + +#endif // AND_READONLY diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.h new file mode 100644 index 0000000..ecf77c2 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SFTL/s_write.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#ifndef __S_WRITE_H__ +#define __S_WRITE_H__ + +#include "s_internal.h" + +// Init/close +extern BOOL32 s_write_init(void); +extern void s_write_close(void); + +// Multi-stream +extern void s_write_switch(UInt32 stream); +extern void s_write_host_switch(UInt32 stream); +extern void s_write_gc_switch(UInt32 stream); + +// Draining +extern void s_write_push_full_buf(BOOL32 doGC); +extern BOOL32 sftl_shutdown_notify(BOOL32 ignoredOption); +extern void s_drain_stream_cur(BOOL32 doGC); +extern void s_drain_stream_all(BOOL32 doGC); +extern BOOL32 s_drain_stream(UInt32 stream, BOOL32 doGC); + +// External write +extern Int32 sftl_write(UInt32 lba, UInt32 count, UInt8 *buf, BOOL32 isStatic); + +// Internal write +extern BOOL32 s_write_multi_internal(s_write_multi_t *wm); // false=pfail + +extern BOOL32 s_pad_block(UInt32 block); + +// Pfail handling +extern void s_write_reseq(void); +extern void s_write_handle_pfail(void); + +#endif // __S_WRITE_H__ + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl.c new file mode 100644 index 0000000..83d2cba --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl.c @@ -0,0 +1,4477 @@ + +#define AND_TRACE_LAYER VFL + +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "PPNMiscTypes.h" +#include "s_vfl_types.h" +#include "VFL.h" + +#define kPPNVFLMinorVersion_ver1 (1) // first version +#define kPPNVFLMinorVersion_ver2 (2) // fixed rdar://9098529 + +#define kPPNVFLMinorVersion kPPNVFLMinorVersion_ver2 + +// _readPageOfASet - defines +#define RPS_STATUS_SPARE_TYPE_MISSMATCH (1 << 1) +#define RPS_STATUS_BANK_MISSMATCH (1 << 2) +#define RPS_STATUS_IDX_MISSMATCH (1 << 3) + +/* ----------- I/F commands - start ------------- */ + +static Int32 _ppnvflOpen + (UInt32 dwKeepout, + UInt32 minor_ver, + UInt32 dwOptions); + +/* ----------- I/F commands - end ------------- */ + +PPNVFL_MainCxt mcxt; +static VFLFailureDetails gstLastFailure; + +#if WMR_EFI +ANDNandLayoutStruct p_layout; +UInt32 p_layout_size = sizeof(ANDNandLayoutStruct); +UInt32 stats_copy_from_meta = 0; +UInt32 stats_copy_from_data = 0; +UInt32 stats_offset_from_meta = 0; +UInt32 stats_offset_from_data = 0; +#endif + +// helper functions - local +#if !AND_READONLY +static BOOL32 _programCxtLastPage + (Buffer * buf, + BOOL32 retry); +static BOOL32 _copyVFLCxtToOtherPair + (void); +#endif // !AND_READONLY +static BOOL32 _readVFLCxtPage + (Buffer *buf, + UInt16 bank, + UInt16 vfl_idx); +static void +_copyFromOnNandCxtToRam + (UInt8 *data); +#if !AND_READONLY +static void +_copyFromRamToOnNandCxt + (UInt8 *data); +static BOOL32 +_checkForBankMapPages + (UInt16 vfl_set); +#endif // !AND_READONLY + +typedef enum +{ + VFLCxtProgramFail = 0, + VFLCxtProgramDone = 2, + VFLCxtProgramRetry = 3, +} ProgramVFLCxtPageWrapStatus; + +#if !AND_READONLY +static ProgramVFLCxtPageWrapStatus _programVFLCxtPageWrap + (Buffer *buf, + UInt16 bank, + UInt16 vfl_idx); +static BOOL32 _programVFLCxtPage + (Buffer *buf, + UInt16 bank, + UInt16 vfl_idx); +#endif // !AND_READONLY +static void +_convertVFLPageIdxToPhysicalPageBlockOffsets + (UInt16 set, + UInt16 vfl_page_idx, + UInt16 *vfl_block_offset, + UInt16 *vfl_page_offset); +#ifndef AND_READONLY +static BOOL32 +_markBlockForRetirement + (UInt16 bank, + UInt16 block); +#endif // !AND_READONLY + +#if !AND_READONLY + +static void +_setVFLCxtSpare + (UInt8 *meta, + UInt8 bank, + UInt8 vfl_idx) +{ + PPNVFL_CxtSpare spare; + UInt16 lba_idx; + + WMR_MEMSET(&spare, 0x00, sizeof(PPNVFL_CxtSpare)); + spare.cxt_age = mcxt.r_gen.cxt_age; + spare.bank = bank; + spare.spareType = PPNVFL_SPARE_TYPE_CXT; + spare.idx = vfl_idx; + for (lba_idx = 0; lba_idx < mcxt.dev.lbas_per_page; lba_idx++) + { + WMR_MEMCPY(meta, &spare, sizeof(PPNVFL_CxtSpare)); + } +} + +/* + * Name: _ReportFailure + * Input: mode, FailingCE, PhysicalPageAddress + * Output: none + * Return value: none + */ +static void +_ReportFailure + (VFLFailureMode mode, + UInt16 wFailingCE, + UInt32 dwPhysicalPage) +{ + gstLastFailure.mode = mode; + gstLastFailure.wCE[0] = wFailingCE; + gstLastFailure.dwPhysicalPage = dwPhysicalPage; +} + +#endif // !AND_READONLY + +/* address translating functions - start */ + +static UInt8 +_countVbnPhysicalBlocks + (UInt16 vbn) +{ + UInt16 byte_idx, count; + UInt32 bitmap_start_offset; + + if (vbn == mcxt.r_gen.cached_vbn) + { + return mcxt.r_gen.cached_vbn_good_blocks; + } + + bitmap_start_offset = mcxt.r_gen.bytes_per_vbn_bitmap * vbn; + + for (byte_idx = 0, count = 0; byte_idx < mcxt.r_gen.bytes_per_vbn_bitmap; byte_idx++) + { + UInt8 bit_idx; + for (bit_idx = 0; bit_idx < 8; bit_idx++) + { + if (mcxt.v2p_bitmap[bitmap_start_offset + byte_idx] & (1 << bit_idx)) + { + mcxt.r_gen.cached_banks_v2p[count] = (byte_idx << 3) + bit_idx; + count++; + } + } + } + + mcxt.r_gen.cached_vbn = vbn; + mcxt.r_gen.cached_vbn_good_blocks = count; + return count; +} + +static UInt8 +_getVbnPhysicalBank + (UInt16 vbn, + UInt16 good_bank_offset) +{ + _countVbnPhysicalBlocks(vbn); + WMR_ASSERT(vbn == mcxt.r_gen.cached_vbn); + return mcxt.r_gen.cached_banks_v2p[good_bank_offset]; +} + +static UInt8 +_getVbnGoodBankOffset + (UInt16 vbn, + UInt16 physical_bank) +{ + UInt16 byte_idx, good_bank_offset = 0; + const UInt32 bitmap_start_offset = mcxt.r_gen.bytes_per_vbn_bitmap * vbn; + BOOL32 done = FALSE32; + + for (byte_idx = 0; + (byte_idx < mcxt.r_gen.bytes_per_vbn_bitmap) && (!done); byte_idx++) + { + UInt8 bit_idx; + for (bit_idx = 0; (bit_idx < 8) && (!done); bit_idx++) + { + if (mcxt.v2p_bitmap[bitmap_start_offset + byte_idx] & (1 << bit_idx)) + { + if (physical_bank == ((byte_idx << 3) + bit_idx)) + { + done = TRUE32; + break; + } + else + { + good_bank_offset++; + } + } + } + } + return good_bank_offset; +} + +static void +_convertReadAddressToVba + (UInt16 channel, + UInt16 chip_enable_idx, + const RowColLenAddressType *read_addr, + UInt32 *vba, + UInt16 *bank, + UInt16 *block, + UInt16 *page_offset, + BOOL32 *slc) +{ + UInt8 good_bank_offset; + + ppnMiscConvertPhysicalAddressToBankBlockPage(&mcxt.dev, channel, chip_enable_idx, + read_addr->row, bank, block, page_offset, slc); + good_bank_offset = _getVbnGoodBankOffset(*block, *bank); + *vba = ((*block * mcxt.dev.pages_per_sublk) + + (*page_offset * _countVbnPhysicalBlocks(*block)) + good_bank_offset); + *vba *= mcxt.dev.lbas_per_page; + *vba += (read_addr->column / (mcxt.dev.main_bytes_per_lba + mcxt.dev.lba_meta_bytes_buffer)); +} + +static void +_convertBankBlockToByteAndBitIdx + (UInt16 bank, + UInt16 pbn, + UInt32 *byte_idx, + UInt16 *bit_idx) +{ + *byte_idx = ((mcxt.r_gen.bytes_per_vbn_bitmap * pbn) + + ((bank >> 3) % mcxt.r_gen.bytes_per_vbn_bitmap)); + *bit_idx = bank % 8; +} + +static void +_setBlockAsVbnInBitmap + (UInt16 bank, + UInt16 pbn) +{ + UInt32 byte_idx; + UInt16 bit_idx; + + _convertBankBlockToByteAndBitIdx(bank, pbn, &byte_idx, &bit_idx); + mcxt.v2p_bitmap[byte_idx] |= (1 << bit_idx); +} + +static void +_markBlockToScrubInBitmap + (UInt16 bank, + UInt16 pbn) +{ + UInt32 byte_idx; + UInt16 bit_idx; + + _convertBankBlockToByteAndBitIdx(bank, pbn, &byte_idx, &bit_idx); + if (!(mcxt.v2p_scrub_bitmap[byte_idx] & (1 << bit_idx))) + { + mcxt.blocks_to_scrub_count++; + mcxt.v2p_scrub_bitmap[byte_idx] |= (1 << bit_idx); + } +} + +#if !AND_READONLY + +static void +_setBlockAsBadInBitmap + (UInt16 bank, + UInt16 pbn) +{ + UInt32 byte_idx; + UInt16 bit_idx; + + _convertBankBlockToByteAndBitIdx(bank, pbn, &byte_idx, &bit_idx); + mcxt.v2p_bitmap[byte_idx] &= (~(1 << bit_idx)); +} + +static void +_unmarkBlockToScrubInBitmap + (UInt16 bank, + UInt16 pbn) +{ + UInt32 byte_idx; + UInt16 bit_idx; + + _convertBankBlockToByteAndBitIdx(bank, pbn, &byte_idx, &bit_idx); + if (mcxt.v2p_scrub_bitmap[byte_idx] & (1 << bit_idx)) + { + mcxt.blocks_to_scrub_count--; + mcxt.v2p_scrub_bitmap[byte_idx] &= (~(1 << bit_idx)); + } +} + +static BOOL32 +_isBlockToScrubInBitmap + (UInt16 bank, + UInt16 pbn) +{ + UInt32 byte_idx; + UInt16 bit_idx; + + _convertBankBlockToByteAndBitIdx(bank, pbn, &byte_idx, &bit_idx); + + return (mcxt.v2p_scrub_bitmap[byte_idx] & (1 << bit_idx)) ? TRUE32 : FALSE32; +} + +#endif // !AND_READONLY + +/* + * Name: _convertVpnToBankBlockPage + * Input: vpn + * Output: bank, block, page offset + * Return value: none + */ +static void +_convertVpnToBankBlockPage + (UInt32 vpn, + UInt16 *bank, + UInt16 *block, + UInt16 *page_offset) +{ + const UInt16 vbn = vpn / mcxt.dev.pages_per_sublk; + const UInt16 physical_blocks_in_vbn = _countVbnPhysicalBlocks(vbn); + const UInt16 page_offset_gen = vpn % mcxt.dev.pages_per_sublk; + const UInt16 good_block_offset = page_offset_gen % physical_blocks_in_vbn; + const UInt16 physical_bank_offset = _getVbnPhysicalBank(vbn, good_block_offset); + const UInt16 page_offset_var = page_offset_gen / physical_blocks_in_vbn; + + WMR_ASSERT(physical_blocks_in_vbn <= mcxt.dev.num_of_banks); + WMR_ASSERT(physical_bank_offset < mcxt.dev.num_of_banks); + WMR_ASSERT(vbn < mcxt.dev.blocks_per_cau); + WMR_ASSERT(page_offset_var < mcxt.dev.pages_per_block_mlc); + + if (bank != NULL) + { + *bank = physical_bank_offset; + } + if (block != NULL) + { + *block = vbn; + } + if (page_offset != NULL) + { + *page_offset = page_offset_var; + } +} +/* address translating functions - end */ + +/* + * Name: _printV2PMapping + * Description: if WMR_PRINT_VFL_V2PMAPPING is enabled and VFL_INF_PRINT + * is working this function print the virtual to phsical map. + * Return value: none + */ + +// to enable this print you should replace 0 with a print type that is +// enabled in WMR_PRINT_LEVEL +#define WMR_PRINT_VFLINF_CXT_BLOCK_MAPPING (0) + +static void +_printVFLBlockMapping + (UInt32 line) +{ +#if (WMR_PRINT_VFLINF_CXT_BLOCK_MAPPING) + UInt16 i, bank; + + WMR_PRINT(VFLINF_CXT_BLOCK_MAPPING, + "printing vfl block list cxt_age:0x%X (caller line:%d)\n", mcxt.r_gen.cxt_age, line); + for (i = 0; i < mcxt.r_gen.num_of_vfl_blocks; i++) + { + WMR_PRINT(VFLINF_CXT_BLOCK_MAPPING, + "(0x%02X, 0x%04X, 0x%02X)\n", mcxt.gen.vfl_blocks[i].bank, mcxt.gen.vfl_blocks[i].block, mcxt.gen.vfl_blocks[i].features); + } + WMR_PRINT(VFLINF_CXT_BLOCK_MAPPING, + "printing mapping pages (caller line:%d)\n", line); + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + for (i = 0; i < mcxt.r_gen.pages_per_block_mapping; i++) + { + WMR_PRINT(VFLINF_CXT_BLOCK_MAPPING, "bank 0x%02X: 0x%04X \n", bank, mcxt.vfl_map_pages[bank][i]); + } + } +#endif // WMR_PRINT_VFLINF_CXT_BLOCK_MAPPING +} + +/* + * Name: _calcNumOfVFLSuBlk + * Return value: number of VFL virtual blocks for this media + */ +static UInt32 +_calcNumOfVFLSuBlk + (void) +{ + return mcxt.dev.blocks_per_cau; +} + +/* ppn commands functions - start */ +/* + * Name: _addAddressToCommandStructure + * Output: pointer to commands structure + * Input: vfl address to add, index in the global operation (coming from the FTL). + * Return value: TRUE32 is successful, otehrwise - FALSE32 + */ +static BOOL32 +_addAddressToCommandStructure + (PPNCommandStruct **commands, + UInt32 vfl_address, + UInt8 vba_offset, + UInt8 vba_count, + UInt8 mem_index, + UInt16 mem_offset) +{ + UInt16 bank = 0, block = 0, cau = 0, chip_enable_idx = 0, channel = 0, + page_offset = 0; + + // convert address from vfl to physical + _convertVpnToBankBlockPage(vfl_address, &bank, &block, &page_offset); + channel = ppnMiscGetChannelFromBank(&mcxt.dev, bank); + chip_enable_idx = ppnMiscGetCEIdxFromBank(&mcxt.dev, bank); + cau = ppnMiscGetCAUFromBank(&mcxt.dev, bank); + return ppnMiscAddPhysicalAddressToCommandStructure(&mcxt.dev, mcxt.commands, channel, chip_enable_idx, + cau, block, page_offset, FALSE32, vba_offset, vba_count, + mem_index, mem_offset); +} + +typedef enum +{ + InitOnly = 1UL << 0, + FillOnly = 1UL << 1, + PackOnly = 1UL << 2, + InitAndFill = (InitOnly | FillOnly), + InitFillPack = (InitOnly | FillOnly | PackOnly), +} FillSequentialAddressesInitType; + +/* + * Name: _fillSequentialAddressesToCommandStructure + * Description: this function takes a start address and number of pages and + * generates commands structure to send to the FIL. + * Output: pointer to commands structure + * Input: start vfl address, number of addresses, command type, + * data pointer, meta pointer + * Return value: TRUE32 is successful, otehrwise - FALSE32 + */ +static BOOL32 +_fillSequentialAddressesToCommandStructure + (PPNCommandStruct **commands, + UInt32 vba, + UInt16 *num_vbas, + PPNCommand command, + void *data, + void *meta, + PPNOptions options, + FillSequentialAddressesInitType init) +{ + UInt16 vba_idx; + + if (init & InitOnly) + { + ppnMiscInitCommandStructure(&mcxt.dev, mcxt.commands, mcxt.dev.num_channels, command, options); + } + + if (init & FillOnly) + { + for (vba_idx = 0; (vba_idx < *num_vbas) && (init & FillOnly); ) + { + const UInt32 curr_vba = vba + vba_idx; + const UInt32 vpn = curr_vba / mcxt.dev.lbas_per_page; + const UInt16 vba_offset = curr_vba % mcxt.dev.lbas_per_page; + const UInt16 vba_count = + WMR_MIN((UInt32)(*num_vbas - vba_idx), (UInt32)(mcxt.dev.lbas_per_page - vba_offset)); + + if (_addAddressToCommandStructure(mcxt.commands, vpn, vba_offset, vba_count, + mcxt.commands[0]->mem_buffers_count, vba_idx) == FALSE32) + { + *num_vbas = vba_idx; + break; + } + + vba_idx += vba_count; + } + ppnMiscAddMemoryToCommandStructure(&mcxt.dev, mcxt.commands, mcxt.dev.num_channels, data, meta, vba_idx); + } + + if (init & PackOnly) + { + ppnMiscReorderCommandStruct(&mcxt.dev, mcxt.commands, mcxt.dev.num_channels, mcxt.reorder); + } + + return TRUE32; +} + +/* ppn commands functions - end */ + +/* block replacement functions - start */ + +#ifndef AND_READONLY + +static BOOL32 +_setBlockUsageInVFLCxt + (UInt16 bank, + UInt16 block, + P2UsageType new_usage) +{ + P2UsageType *p2_block_usage_map; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + const UInt16 vflcxt_in_page_offset = block % mcxt.r_gen.pbns_per_cxt_mapping_page; + const UInt16 vflcxt_page_index = block / mcxt.r_gen.pbns_per_cxt_mapping_page; + BOOL32 retry_program_cxt = FALSE32; + + p2_block_usage_map = (P2UsageType*)buf->pData; + + do + { + ProgramVFLCxtPageWrapStatus program_status; + P2UsageType *on_vflcxt_block_usage = &p2_block_usage_map[vflcxt_in_page_offset]; + retry_program_cxt = FALSE32; + // mark the block we are replacing as bad + if (_readVFLCxtPage(buf, bank, vflcxt_page_index) == FALSE32) + { + WMR_PRINT(ERROR, "error reading vfl cxt (bank:0x%X, index:0x%X, block:0x%X)\n", + bank, vflcxt_page_index, block); + goto return_error; + } + + *on_vflcxt_block_usage = new_usage; + + program_status = _programVFLCxtPageWrap(buf, bank, vflcxt_page_index); + if (program_status == VFLCxtProgramFail) + { + WMR_PRINT(ERROR, "error programming vfl cxt (bank:0x%X, index:0x%X)\n", + bank, vflcxt_page_index); + goto return_error; + } + else if (program_status == VFLCxtProgramRetry) + { + retry_program_cxt = TRUE32; + } + else + { + retry_program_cxt = FALSE32; + } + } + while (retry_program_cxt); + + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +static BOOL32 +_ppnvflAllocateSpecialBlock + (SpecialBlockAddress *chosen_block, + UInt16 type) +{ + UInt16 bank, i; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + P2UsageType *p2_block_usage_map = (P2UsageType*)buf->pData; + BOOL32 retry_allocating = FALSE32; + UInt8 failed_banks_marks[PPNVFL_MAX_SUPPORTED_BANKS]; + + WMR_MEMSET(failed_banks_marks, 0, sizeof(failed_banks_marks)); + + do + { + UInt16 vfl_idx, min_special_blocks = 0xFFFF;; + UInt16 total_special_blocks = 0; + chosen_block->bank = PPNVFL_INVALID_BANK_BLOCK; + chosen_block->block = PPNVFL_INVALID_BANK_BLOCK; + retry_allocating = FALSE32; + + // choose a bank + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + const UInt16 specials_in_bank = mcxt.r_banks[bank].num_special_blocks; + + total_special_blocks += specials_in_bank; + + if ((specials_in_bank < min_special_blocks) && + (mcxt.r_banks[bank].num_available != 0) && + (!(failed_banks_marks[bank]))) + { + chosen_block->bank = bank; + min_special_blocks = specials_in_bank; + } + } + + if (chosen_block->bank == PPNVFL_INVALID_BANK_BLOCK) + { +#if AND_SIMULATOR + WMR_SIM_EXIT("Out of available blocks"); +#endif // AND_SIMULATOR + WMR_PRINT(ERROR, "failed finding a bank to allocate special block\n"); + goto return_error; + } + else if (AND_MAX_SPECIAL_BLOCKS < total_special_blocks) + { + WMR_PRINT(ERROR, "total special blocks has exceeded the max allowed\n"); + goto return_error; + } + + bank = chosen_block->bank; + + // chose a block + for (vfl_idx = mcxt.r_gen.pages_per_block_mapping; + (vfl_idx > 0) && (!retry_allocating) && (chosen_block->block == PPNVFL_INVALID_BANK_BLOCK); ) + { + UInt16 cxt_blocks_offset; + UInt16 blocks_in_cxt_page; + vfl_idx--; + cxt_blocks_offset = vfl_idx * mcxt.r_gen.pbns_per_cxt_mapping_page; + blocks_in_cxt_page = WMR_MIN(mcxt.r_gen.pbns_per_cxt_mapping_page, + (mcxt.dev.blocks_per_cau - cxt_blocks_offset)); + if (_readVFLCxtPage(buf, bank, + vfl_idx) == FALSE32) + { + WMR_PRINT(ERROR, "failed _readVFLCxtPage!\n"); + goto return_error; + } + for (i = blocks_in_cxt_page; ((i > 0) && (i + cxt_blocks_offset > PPN_SPECIAL_BLOCK_LIMIT(&mcxt.dev)) && + (!retry_allocating) && (chosen_block->block == PPNVFL_INVALID_BANK_BLOCK)); ) + { + i--; + if (p2_block_usage_map[i] == PPNVFL_TYPE_AVAILABLE_MARK) + { + ProgramVFLCxtPageWrapStatus program_status; + UInt16 potential_block = i + cxt_blocks_offset; + if (!ppnMiscTestSpecialBlock(&mcxt.dev, mcxt.commands[0], bank, potential_block, PPNVFL_SPARE_TYPE_TST)) + { + WMR_PRINT(VFLWARN, "failed testing block (bank:0x%X, block:0x%X) for sb allocation\n", + bank, potential_block); + + p2_block_usage_map[i] = PPNVFL_TYPE_GROWN_BB; + } + else + { + chosen_block->block = potential_block; + p2_block_usage_map[i] = type; + } + // program the update back to the NAND + program_status = _programVFLCxtPageWrap(buf, bank, vfl_idx); + if (program_status == VFLCxtProgramFail) + { + WMR_PRINT(ERROR, "error programming vfl cxt (bank:0x%X, i:0x%X)\n", bank, i); + goto return_error; + } + else if (program_status == VFLCxtProgramRetry) + { + retry_allocating = TRUE32; + } + else + { + // mark the change in the VFL RAM structures + mcxt.r_banks[bank].num_available--; + if (p2_block_usage_map[i] == PPNVFL_TYPE_GROWN_BB) + { + mcxt.r_banks[bank].num_grown_bad++; + retry_allocating = TRUE32; + } + else + { + mcxt.r_banks[bank].num_special_blocks++; + } + } + } + } + } + if ((!retry_allocating) && (chosen_block->block == PPNVFL_INVALID_BANK_BLOCK)) + { + failed_banks_marks[bank] = 1; + retry_allocating = TRUE32; + } + } + while (retry_allocating); + + if (chosen_block->block == PPNVFL_INVALID_BANK_BLOCK) + { + WMR_PRINT(ERROR, "failed to find a new special block (bank:0x%X)\n", bank); + goto return_error; + } + + if (_programCxtLastPage(buf, TRUE32) == FALSE32) + { + WMR_PRINT(ERROR, "error programming last vfl cxt (bank:0x%X)\n", bank); + goto return_error; + } + + if (!mcxt.fpart->AllocateSpecialBlockType(chosen_block, 1, type)) + { + WMR_PRINT(ERROR, "fpart failed to allocate special block with type %p\n", type); + goto return_error; + } + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +static BOOL32 +_removeBadBlock + (UInt16 bank, + UInt16 block) +{ + Buffer *buf = NULL; + + if (!_setBlockUsageInVFLCxt(bank, block, PPNVFL_TYPE_GROWN_BB)) + { + WMR_PRINT(ERROR, "failed to mark block as bad (bank:0x%X, block:0x%X)!\n", bank, block); + goto return_error; + } + buf = BUF_Get(BUF_MAIN_AND_SPARE); + + // remove the block from the scrub bitmap if it is marked + _unmarkBlockToScrubInBitmap(bank, block); + + if (_programCxtLastPage(buf, TRUE32) == FALSE32) + { + WMR_PRINT(ERROR, "error programming last vfl cxt (bank:0x%X, index:0x%X)\n", bank, block); + goto return_error; + } + + WMR_PRINT(VFLWARN, "done removing (bank:0x%X, block:0x%X)!\n", bank, block); + + BUF_Release(buf); + _setBlockAsBadInBitmap(bank, block); + mcxt.r_banks[bank].num_grown_bad++; + mcxt.r_banks[bank].num_p2v--; + return TRUE32; + + return_error: + if (buf != NULL) + { + BUF_Release(buf); + } + WMR_PANIC("_replaceBadBlock() fail bank:0x%04X block:0x%04X\n", bank, block); + return FALSE32; +} + +static BOOL32 +_chooseReplacementBank + (UInt16 *new_bank) +{ + UInt16 bank, max_available, min_cxt_blocks; + + *new_bank = PPNVFL_INVALID_BANK_BLOCK; + + // chose a bank to work with + // pick the bank with maximum available blocks and minimum cxt blocks + max_available = 0; + min_cxt_blocks = 0xFFFF; + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + if (mcxt.r_banks[bank].num_available) + { + if (*new_bank == PPNVFL_INVALID_BANK_BLOCK) + { + *new_bank = bank; + min_cxt_blocks = mcxt.r_banks[bank].num_cxt; + max_available = mcxt.r_banks[bank].num_available; + } + else if (mcxt.r_banks[bank].num_cxt < min_cxt_blocks) + { + min_cxt_blocks = mcxt.r_banks[bank].num_cxt; + max_available = mcxt.r_banks[bank].num_available; + *new_bank = bank; + } + else if (mcxt.r_banks[bank].num_cxt == min_cxt_blocks) + { + if (mcxt.r_banks[bank].num_available > max_available) + { + min_cxt_blocks = mcxt.r_banks[bank].num_cxt; + max_available = mcxt.r_banks[bank].num_available; + *new_bank = bank; + } + } + } + } + if (*new_bank == PPNVFL_INVALID_BANK_BLOCK) + { + return FALSE32; + } + return TRUE32; +} + +static BOOL32 +_chooseReplacementBlock + (UInt16 new_bank, + UInt16 *new_block, + UInt16 *new_block_index, + UInt16 *new_block_cxt_page, + Buffer *buf) +{ + UInt16 i, j, num_failed_blocks = 0; + const UInt16 blocks_in_cxt_page = mcxt.r_gen.pbns_per_cxt_mapping_page; + P2UsageType *p2_block_usage_map = (P2UsageType*)buf->pData;; + + + // pick a replacement block + i = mcxt.r_gen.pages_per_block_mapping; + *new_block = PPNVFL_INVALID_BANK_BLOCK; + do + { + i--; + if (_readVFLCxtPage(buf, new_bank, i) == FALSE32) + { + WMR_PRINT(ERROR, "failed _readVFLCxtPage!\n"); + break; + } + j = blocks_in_cxt_page; + do + { + UInt16 potential_new_block; + + j--; + potential_new_block = j + (i * blocks_in_cxt_page); + + if (p2_block_usage_map[j] == PPNVFL_TYPE_AVAILABLE_MARK) + { + // test the block - do not mark blocks as bad if they fail, just continue + if (ppnMiscTestSpecialBlock(&mcxt.dev, mcxt.commands[0], new_bank, potential_new_block, PPNVFL_SPARE_TYPE_TST)) + { + *new_block = potential_new_block; + *new_block_index = j; + *new_block_cxt_page = i; + break; + } + else + { + WMR_PRINT(VFLWARN, "failed testing replacement block (bank:0x%X, block:0x%X)!\n", + new_bank, potential_new_block); + num_failed_blocks++; + } + } + } + while (j != 0); + } + while ((i != 0) && (*new_block == PPNVFL_INVALID_BANK_BLOCK)); + + // verify a block was found + if (*new_block == PPNVFL_INVALID_BANK_BLOCK) + { + WMR_ASSERT(num_failed_blocks == mcxt.r_banks[new_bank].num_available); + mcxt.r_banks[new_bank].num_available = 0; + WMR_PRINT(VFLWARN, "failed searching for replacement block\n"); + return FALSE32; + } + return TRUE32; +} + +static BOOL32 +_replaceErasedCxtBlock + (UInt16 vfl_index) +{ + UInt16 new_bank = PPNVFL_INVALID_BANK_BLOCK, new_block_index = 0xFFFF, new_block_cxt_page = 0xFFFF; + UInt16 bank, i, new_block = PPNVFL_INVALID_BANK_BLOCK; + P2UsageType *p2_block_usage_map = NULL; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + const UInt16 blocks_in_cxt_page = mcxt.r_gen.pbns_per_cxt_mapping_page; + const UInt16 replaced_block = mcxt.gen.vfl_blocks[vfl_index].block; + const UInt16 replaced_bank = mcxt.gen.vfl_blocks[vfl_index].bank; + const UInt16 replaced_index = replaced_block % blocks_in_cxt_page; + const UInt16 replaced_cxt_page = replaced_block / blocks_in_cxt_page; + const UInt16 blocks_per_vfl_set = (mcxt.r_gen.num_of_vfl_blocks >> 1); + const UInt16 set_mapping_offset = mcxt.r_gen.next_cxt_block_offset * blocks_per_vfl_set; + + p2_block_usage_map = (P2UsageType*)buf->pData; + + _printVFLBlockMapping(__LINE__); + WMR_ASSERT(!_checkForBankMapPages(mcxt.r_gen.next_cxt_block_offset)); + + while (_chooseReplacementBank(&new_bank)) + { + + if (_chooseReplacementBlock(new_bank, &new_block, &new_block_index, &new_block_cxt_page, buf)) + { + break; + } + } + + if (new_bank == PPNVFL_INVALID_BANK_BLOCK) + { +#if AND_SIMULATOR + WMR_SIM_EXIT("Out of replacement blocks"); +#endif // AND_SIMULATOR + WMR_PRINT(ERROR, "failed finding a bank to provide vfl cxt blocks!\n"); + goto return_error; + } + + mcxt.gen.vfl_blocks[vfl_index].block = new_block; + mcxt.gen.vfl_blocks[vfl_index].bank = new_bank; + _unsetVFLCxtScrubMark(mcxt.gen.vfl_blocks[vfl_index]); + + _printVFLBlockMapping(__LINE__); + // erase original - ignore status + ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_ERASE, + PPN_OPTIONS_IGNORE_BAD_BLOCK, replaced_bank, replaced_block, 0, + TRUE32, NULL, NULL); + + // erase current vfl set - fail replacement operation if we get an erase error + for (i = 0; i < blocks_per_vfl_set; i++) + { + PPNStatusType status; + + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt.gen.vfl_blocks[set_mapping_offset + i].bank, + mcxt.gen.vfl_blocks[set_mapping_offset + i].block, + 0, TRUE32, NULL, NULL); + if (status & (PPN_ERASE_STATUS_RETIRE | PPN_ERASE_STATUS_FAIL | PPN_PROGRAM_STATUS_GEB)) + { + WMR_PRINT(QUAL_FATAL, "failed erase new vfl block (bank:0x%04X, block: 0x%04X) with status 0x%02X\n", + mcxt.gen.vfl_blocks[set_mapping_offset + i].bank, + mcxt.gen.vfl_blocks[set_mapping_offset + i].block, status); + goto return_error; + } + } + // program last cxt page + mcxt.r_gen.next_cxt_page_offset = 0; + _copyFromRamToOnNandCxt(buf->pData); + mcxt.r_gen.cxt_age--; + mcxt.r_gen.need_rewrite = FALSE32; + + if (!_programVFLCxtPage(buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX)) + { + WMR_PRINT(ERROR, "_programVFLCxtPage failed while allocating new vfl block (bank:0x%04X, block: 0x%04X)\n", + new_bank, new_block); + goto return_error; + } + + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + for (i = 0; i < mcxt.r_gen.pages_per_block_mapping; i++) + { + if (_readVFLCxtPage(buf, bank, i) == FALSE32) + { + WMR_PRINT(ERROR, "failed _readVFLCxtPage !\n"); + goto return_error; + } + + if (new_block_cxt_page == i && new_bank == bank) + { + p2_block_usage_map[new_block_index] = PPNVFL_TYPE_VFL_INFO; + mcxt.r_banks[bank].num_available--; + mcxt.r_banks[bank].num_cxt++; + } + + if (replaced_cxt_page == i && replaced_bank == bank) + { + p2_block_usage_map[replaced_index] = PPNVFL_TYPE_GROWN_BB; + mcxt.r_banks[bank].num_cxt--; + mcxt.r_banks[bank].num_grown_bad++; + } + if (!_programVFLCxtPage(buf, bank, i)) + { + WMR_PRINT(ERROR, "_programVFLCxtPage failed with the new vfl block (bank:0x%04X, block: 0x%04X)\n", + new_bank, new_block); + goto return_error; + } + } + } + + // program last cxt page + _copyFromRamToOnNandCxt(buf->pData); + + if (!_programVFLCxtPage(buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX)) + { + WMR_PRINT(ERROR, "_programVFLCxtPage failed with the new vfl block (bank:0x%04X, block: 0x%04X)\n", + new_bank, new_block); + goto return_error; + } + + WMR_PRINT(VFLWARN, "replacing cxt_idx 0x%X, org (bank:0x%X, block:0x%X), new (bank:0x%X, block:0x%X)!\n", + vfl_index, replaced_bank, replaced_block, new_bank, new_block); + + // erase the old vfl cxt set + for (i = 0; i < blocks_per_vfl_set; i++) + { + const UInt16 old_set_location = (mcxt.r_gen.next_cxt_block_offset == 1 ? 0 : 1); + const UInt16 old_set_mapping_offset = old_set_location * blocks_per_vfl_set; + + if (_isVFLCxtBlockMarkedScrub(mcxt.gen.vfl_blocks[old_set_mapping_offset + i])) + { + // erase bad block and ignore status + ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_ERASE, + PPN_OPTIONS_IGNORE_BAD_BLOCK, + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].block, + 0, + TRUE32, NULL, NULL); + } + else + { + PPNStatusType status; + + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].block, + 0, + TRUE32, NULL, NULL); + + if (status & PPN_ERASE_STATUS_RETIRE) + { + WMR_PRINT(QUAL, "failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with retire status\n", + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].block); + _setVFLCxtScrubMark(mcxt.gen.vfl_blocks[old_set_mapping_offset + i]); + if (!_programVFLCxtPage(buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX)) + { + WMR_PRINT(ERROR, "_programVFLCxtPage failed while allocating new vfl block (bank:0x%04X, block: 0x%04X)\n", + new_bank, new_block); + goto return_error; + } + } + else if (status & PPN_ERASE_STATUS_FAIL) + { + WMR_PRINT(QUAL_FATAL, "failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with no retire status\n", + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt.gen.vfl_blocks[old_set_mapping_offset + i].block); + goto return_error; + } + } + } + + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +#endif // AND_READONLY + +#ifndef AND_READONLY + +static BOOL32 +_markBlockForRetirement + (UInt16 bank, + UInt16 block) +{ + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + BOOL32 ret_val; + + _markBlockToScrubInBitmap(bank, block); + ret_val = _setBlockUsageInVFLCxt(bank, block, PPNVFL_P2V_SCRUB_BIT); + + if (ret_val) + { + ret_val = _programCxtLastPage(buf, TRUE32); + } + + BUF_Release(buf); + + return ret_val; +} + +#endif // AND_READONLY + +/* block replacement functions - end */ + +/* + * Name: _analyzeSpansReadStatuses + * Description: this function analyzes the read operation statuses (used for multipage read) + * Input: number of pages read, mark for scrub + * Output: need refresh flag, operation result flag, clean flag + * Return value: none + */ +static void +_analyzeSpansReadStatuses + (UInt16 vba_index_start, + UInt16 vba_index_count, + VFLReadStatusType *result_flags, + BOOL32 boolMarkForScrub, + VFL_ReadSpans_t *s) +{ + UInt16 channel; + + // look at the status + for (channel = 0; channel < mcxt.dev.num_channels; channel++) + { + UInt16 i; + PPNCommandStruct *command = mcxt.commands[channel]; + + // locate the block that need to be replaced + for (i = 0; i < command->num_pages; i++) + { + PPNStatusType current_status = mcxt.commands[channel]->entry[i].status; + VFLReadStatusType current_result = 0; + BOOL32 call_ftl_callback = FALSE32, retire_block = FALSE32; + + switch (current_status) + { + case (PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_VALID | PPN_READ_STATUS_REFRESH): + case (PPN_READ_STATUS_VALID | PPN_READ_STATUS_RETIRE): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_RETIRE | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_CLEAN | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_GEB | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_WRONG_BITS_PER_CELL | PPN_READ_STATUS_VALID): + break; + + default: + current_result |= VFL_READ_STATUS_UNIDENTIFIED; + + if (WMR_I_CAN_HAZ_DEBUGGER()) + { + // avoid the callback in case we have unrecognized status + // and connected to debugger + s->cbOpt = 0; + s->cb = NULL; + } + + break; + } + if (!(current_result & VFL_READ_STATUS_UNIDENTIFIED)) + { + if (current_status & PPN_READ_STATUS_INVALID_DATA && + (!(current_status & PPN_READ_STATUS_CLEAN))) + { + current_result |= VFL_READ_STATUS_UECC; + } + if (current_status & PPN_READ_STATUS_WRONG_BITS_PER_CELL) + { + current_result |= VFL_READ_STATUS_UECC; + } + if (current_status & PPN_READ_STATUS_CLEAN) + { + current_result |= VFL_READ_STATUS_CLEAN; + } + if (current_status & PPN_READ_STATUS_REFRESH) + { + current_result |= VFL_READ_STATUS_REFRESH; + } + if (current_status & PPN_READ_STATUS_RETIRE) + { + current_result |= VFL_READ_STATUS_RETIRE; + } + if (!(current_status & PPN_READ_STATUS_INVALID_DATA)) + { + current_result |= VFL_READ_STATUS_VALID_DATA; + } + } + *result_flags |= current_result; + retire_block = ((boolMarkForScrub && + (current_status & (PPN_READ_STATUS_RETIRE | PPN_READ_STATUS_WRONG_BITS_PER_CELL))) + ? TRUE32 : FALSE32); + call_ftl_callback = ((s != NULL) && (current_result & s->cbOpt) && (s->cb != NULL)) ? TRUE32 : FALSE32; + + if (retire_block || call_ftl_callback) + { + UInt16 vba_idx, bank, block, page_offset; + BOOL32 slc; + UInt32 vba; + UInt8 *meta, *page_meta; + const PPNCommandEntry *entry = &command->entry[i]; + const PPNMemoryIndex *memoryIndex = &command->mem_index[i]; + const PageAddressType page = mcxt.commands[channel]->entry[i].addr.row; + const UInt16 chip_enable_idx = mcxt.commands[channel]->entry[i].ceIdx; + const UInt16 column_addr = mcxt.commands[channel]->entry[i].addr.column; + + _convertReadAddressToVba(channel, entry->ceIdx, &entry->addr, + &vba, &bank, &block, &page_offset, &slc); + + if (retire_block) + { +#ifndef AND_READONLY + _markBlockForRetirement(bank, block); +#endif // ! AND_READONLY + + WMR_PRINT(VFLWARN, "reporting a read error status = 0x%X vba:0x%X result:0x%X\n", + current_status, vba, current_result); + WMR_PRINT(VFLWARN, "bank:0x%X, block:0x%X, page_offset:0x%X, slc:0x%X\n", + bank, block, page_offset, slc); + WMR_PRINT(VFLWARN, "channel:0x%X, chip_enable_idx:0x%X, page_address:0x%X, column: 0x%X\n", + channel, chip_enable_idx, page, column_addr); + } + + meta = (UInt8*)command->mem_buffers[memoryIndex->idx].meta; + page_meta = &meta[memoryIndex->offset * mcxt.dev.lba_meta_bytes_buffer]; + for (vba_idx = 0; vba_idx < entry->lbas; vba_idx++) + { + UInt8 *curr_meta = &page_meta[vba_idx * mcxt.dev.lba_meta_bytes_buffer]; + UInt32 curr_vba = vba + vba_idx; + + if (retire_block) + { + WMR_PRINT(VFLWARN, "retiring vba:0x%08X status:0x%02X result:0x%08X " + "meta: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n", + curr_vba, current_status, current_result, + curr_meta[0], curr_meta[1], curr_meta[2], curr_meta[3], + curr_meta[4], curr_meta[5], curr_meta[6], curr_meta[7], + curr_meta[8], curr_meta[9], curr_meta[10], curr_meta[11], + curr_meta[12], curr_meta[13], curr_meta[14], curr_meta[15]); + } + + if (call_ftl_callback) + { + s->cb(curr_vba, current_result, curr_meta); + } + } + } + } + } + + if ((*result_flags & + (VFL_READ_STATUS_REFRESH | VFL_READ_STATUS_RETIRE | + VFL_READ_STATUS_UECC | VFL_READ_STATUS_UNIDENTIFIED)) && + WMR_I_CAN_HAZ_DEBUGGER()) + { + WMR_PRINT(VFLWARN, "Unexpected PPN read results flags:0x%X\n", *result_flags); + WMR_PRINT(VFLWARN, "st vba ba blk ofs s ch ce len col row meta \n"); + for (channel = 0; channel < mcxt.dev.num_channels; channel++) + { + UInt16 i; + + // locate the block that need to be replaced + for (i = 0; i < mcxt.commands[channel]->num_pages; i++) + { + const PPNCommandStruct *command = mcxt.commands[channel]; + const PPNCommandEntry *entry = &command->entry[i]; + const PPNMemoryIndex *memoryIndex = &command->mem_index[i]; + const PPNStatusType current_status = entry->status; + const UInt16 chip_enable_idx = entry->ceIdx; + const UInt8 *meta = (UInt8*)command->mem_buffers[memoryIndex->idx].meta; + const UInt8 *page_meta = &meta[memoryIndex->offset * mcxt.dev.lba_meta_bytes_buffer]; + UInt16 bank, block, page_offset, vba_idx; + BOOL32 slc; + UInt32 vba; + + _convertReadAddressToVba(channel, chip_enable_idx, &entry->addr, + &vba, &bank, &block, &page_offset, &slc); + + for (vba_idx = 0; vba_idx < entry->lbas; vba_idx++) + { + const UInt8 *curr_meta = &page_meta[vba_idx * mcxt.dev.lba_meta_bytes_buffer]; + UInt32 curr_vba = vba + vba_idx; + WMR_PRINT(VFLWARN, "%02X %08X %02X %04X %03X %01X %02X %02X" + " %04X %04X %08X" + " %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n", + current_status, curr_vba, bank, block, page_offset, slc, channel, chip_enable_idx, + entry->addr.length, entry->addr.column, entry->addr.row, + curr_meta[0], curr_meta[1], curr_meta[2], curr_meta[3], + curr_meta[4], curr_meta[5], curr_meta[6], curr_meta[7], + curr_meta[8], curr_meta[9], curr_meta[10], curr_meta[11], + curr_meta[12], curr_meta[13], curr_meta[14], curr_meta[15]); + } + } + } + } + + if (!(*result_flags)) + { + WMR_PANIC("result flags: 0x%02x\n", (UInt32) * result_flags); + } + + if(*result_flags & (VFL_READ_STATUS_UNIDENTIFIED | VFL_READ_STATUS_REFRESH | + VFL_READ_STATUS_RETIRE | VFL_READ_STATUS_UECC)) + { + if (WMR_I_CAN_HAZ_DEBUGGER() && (*result_flags & VFL_READ_STATUS_UNIDENTIFIED)) + { + WMR_PANIC("Read operation contained an unidentified status\n", (UInt32) * result_flags); + } + + if(boolMarkForScrub) + { + WMR_PRINT(QUAL, "Errors in PPN read results flags:0x%X\n", *result_flags); + } + WMR_PRINT(UECC_PANIC, "Errors in PPN read: results flags:0x%X, boolMarkForScrub: %d\n", *result_flags, boolMarkForScrub); + } +} + +static void +_copyMapPagesFromOnNandCxtToRam + (UInt8 *data) +{ + UInt16 bank; + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)data; + + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + WMR_MEMCPY(mcxt.vfl_map_pages[bank], on_nand->banks[bank].vfl_map_pages, + mcxt.r_gen.pages_per_block_mapping * sizeof(UInt16)); + } +} + +static void +_copyFromOnNandCxtToRam + (UInt8 *data) +{ + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)data; + + // copy gen + WMR_MEMCPY(&mcxt.gen, &on_nand->gen, sizeof(PPNVFL_GeneralCxt)); + // copy vfl map locations + _copyMapPagesFromOnNandCxtToRam(data); +} + +#if !AND_READONLY + +static void +_copyFromRamToOnNandCxt + (UInt8 *data) +{ + UInt16 bank; + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)data; + + WMR_MEMSET(data, 0, mcxt.dev.main_bytes_per_page); + // copy gen + WMR_MEMCPY(&on_nand->gen, &mcxt.gen, sizeof(PPNVFL_GeneralCxt)); + + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + WMR_MEMCPY(on_nand->banks[bank].vfl_map_pages, mcxt.vfl_map_pages[bank], + mcxt.r_gen.pages_per_block_mapping * sizeof(UInt16)); + } +} + +#endif // !AND_READONLY + +static UInt16 +_div2RoundUp + (UInt16 in) +{ + return (((in) & 0x1) == 1) ? (((in) >> 1) + 1) : ((in) >> 1); +} + +static Int32 +_readPageOfASet + (UInt16 set, + UInt16 cxt_page_offset, + Buffer *buf, + UInt8 expected_bank, + UInt8 expected_idx) +{ + UInt16 redundant_copy; + PPNStatusType status; + UInt16 vfl_block_offset = 0; + UInt16 vfl_page_offset = 0; + BOOL32 clean = TRUE32; + const BOOL32 original_need_rewrite = mcxt.r_gen.need_rewrite; + + _convertVFLPageIdxToPhysicalPageBlockOffsets(set, cxt_page_offset, + &vfl_block_offset, &vfl_page_offset); + + for (redundant_copy = 0; redundant_copy < mcxt.r_gen.vfl_blocks_redundancy; redundant_copy++) + { + const UInt16 bank = mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].bank; + const UInt16 block = mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].block; + PPNVFL_CxtSpare *cxt_spare = (PPNVFL_CxtSpare*) buf->pSpare; + + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_READ, PPN_NO_OPTIONS, + bank, block, vfl_page_offset, TRUE32, buf->pData, buf->pSpare); + + // check if this is not the first copy or if the copy is marked to be moved + if (((redundant_copy != 0) || + (status & (PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_RETIRE))) && + (set == mcxt.r_gen.next_cxt_block_offset)) + { + // avoid the prints when searching through clean pages... + // print only if we ran into none clean pages + if (!clean) + { + WMR_PRINT(VFLWARN, "read a copy of the vfl cxt with status 0x%02X" + " set:%01d, copy:%01d, page_offset:0x%03X type:0x%02X\n", + status, set, redundant_copy, cxt_page_offset, cxt_spare->spareType); + } + + mcxt.r_gen.need_rewrite = TRUE32; + } + + // if this is not initial search for cxt we should take the indication + // for replacement from the device + if ((status & PPN_READ_STATUS_RETIRE) && (!mcxt.r_gen.search_for_cxt)) + { + _setVFLCxtScrubMark(mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy]); + } + + if (!(status & PPN_READ_STATUS_INVALID_DATA)) + { + UInt8 rps_status = 0; + + if (cxt_spare->spareType != PPNVFL_SPARE_TYPE_CXT) + { + rps_status |= RPS_STATUS_SPARE_TYPE_MISSMATCH; + } + + if ((expected_bank != cxt_spare->bank) && (expected_bank != PPNVFL_CXT_IGNORE_BANKIDX)) + { + rps_status |= RPS_STATUS_BANK_MISSMATCH; + } + + if ((expected_idx != cxt_spare->idx) && (expected_idx != PPNVFL_CXT_IGNORE_BANKIDX)) + { + rps_status |= RPS_STATUS_IDX_MISSMATCH; + } + + if (mcxt.r_gen.need_rewrite && (!original_need_rewrite)) + { + WMR_PRINT(VFLWARN, "failed reading the first copy of the vfl cxt " + "(succeeded reading another copy)\n"); + } + + if (rps_status == 0) + { + return ANDErrorCodeOk; + } + else + { + WMR_PRINT(ERROR, "problem reading a vfl cxt copy" + " rps_status:0x%02X, set:%01d, copy:%01d, page_offset:0x%03X" + " type:0x%02X bank:0x%02X idx:0x%02X\n", + rps_status, set, redundant_copy, cxt_page_offset, + cxt_spare->spareType, cxt_spare->bank, cxt_spare->idx); + mcxt.r_gen.need_rewrite = TRUE32; + } + } + + if (!(status & PPN_READ_STATUS_CLEAN)) + { + clean = FALSE32; + } + } + + if (clean) + { + mcxt.r_gen.need_rewrite = original_need_rewrite; + return ANDErrorCodeCleanOk; + } + + WMR_PRINT(VFLWARN, "failed to read a single vfl cxt copy (UECC)\n"); + mcxt.r_gen.need_rewrite = TRUE32; + return ANDErrorCodeUserDataErr; +} + +static Int32 +_readSingleRedundancyPageOfASet + (UInt16 set, + UInt16 cxt_page_offset, + UInt16 redundant_copy, + Buffer *buf) +{ + PPNStatusType status; + UInt16 vfl_block_offset = 0, vfl_page_offset = 0, bank = PPNVFL_INVALID_BANK_BLOCK, block = PPNVFL_INVALID_BANK_BLOCK; + + _convertVFLPageIdxToPhysicalPageBlockOffsets(set, cxt_page_offset, + &vfl_block_offset, &vfl_page_offset); + + bank = mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].bank; + block = mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].block; + + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_READ, PPN_NO_OPTIONS, + bank, block, vfl_page_offset, TRUE32, buf->pData, buf->pSpare); + + // check if this is not the first copy or if the copy is marked to be moved + if ((status & (PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_RETIRE)) && + (set == mcxt.r_gen.next_cxt_block_offset)) + { + WMR_PRINT(VFLWARN, "_readSingleRedundancyPageOfASet got status:0x%02X from " + "redundant_copy:0x%04X set:0x%04X cxt_page_offset:0x%04X\n", + status, redundant_copy, set, cxt_page_offset); + mcxt.r_gen.need_rewrite = TRUE32; + } + + // if this is not initial search for cxt we should take the indication + // for replacement from the device + if ((status & PPN_READ_STATUS_RETIRE) && (!mcxt.r_gen.search_for_cxt)) + { + _setVFLCxtScrubMark(mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy]); + } + + if (!(status & PPN_READ_STATUS_INVALID_DATA)) + { + return ANDErrorCodeOk; + } + + if (status & PPN_READ_STATUS_CLEAN) + { + return ANDErrorCodeCleanOk; + } + + return ANDErrorCodeUserDataErr; +} + +/* vfl cxt management functions - start */ +/* + * Name: _findOnNANDCxt + * Description: this function find the current cxt per bank and update the information + * in ram. + * Input: bank + * Return value: TRUE32 is successful, FALSE32 otherwise. + */ + +static BOOL32 +_findOnNANDCxt + (void) +{ + Buffer *buf, *buf2; + UInt16 bank = ~0, page, start_page, mid_page, end_page, block_idx, vfl_cxt_idx, cxt_blocks_idx; + PPNStatusType status; + PPNVFL_CxtSpare spare0, spare1; + BOOL32 found_valid_cxt; + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + buf2 = BUF_Get(BUF_MAIN_AND_SPARE); + + // find the first written VFLCxt + found_valid_cxt = FALSE32; + for (block_idx = (mcxt.dev.blocks_per_cau - 1); ((!found_valid_cxt) && (block_idx != 0)); block_idx--) + { + for (bank = 0; ((!found_valid_cxt) && (bank < mcxt.dev.num_of_banks)); bank++) + { + PPNVFL_CxtSpare *cxt_spare = (PPNVFL_CxtSpare*)buf->pSpare; + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_READ, + PPN_NO_OPTIONS, bank, block_idx, 0, TRUE32, + buf->pData, buf->pSpare); + if ((!(status & PPN_READ_STATUS_INVALID_DATA)) && + cxt_spare->spareType == PPNVFL_SPARE_TYPE_CXT && + cxt_spare->idx == PPNVFL_CXT_LAST_BANKIDX) + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf->pData; + WMR_MEMCPY(mcxt.gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(VFLCxtBlockAddress) * mcxt.r_gen.num_of_vfl_blocks)); + mcxt.r_gen.cxt_age = cxt_spare->cxt_age; + found_valid_cxt = TRUE32; + break; + } + } + } + if (!found_valid_cxt) + { + WMR_PRINT(ERROR, "could not find a single copy of VFLCxt\n"); + goto error_return; + } + + // agree on the location of the VFLCxt blocks - find the latest blocks and see that they all point to the same VFL + // blocks + found_valid_cxt = FALSE32; + do + { + for (vfl_cxt_idx = 0; vfl_cxt_idx < mcxt.r_gen.num_of_vfl_blocks; vfl_cxt_idx++) + { + PPNVFL_CxtSpare *cxt_spare = (PPNVFL_CxtSpare*)buf->pSpare; + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_READ, + PPN_NO_OPTIONS, + mcxt.gen.vfl_blocks[vfl_cxt_idx].bank, + mcxt.gen.vfl_blocks[vfl_cxt_idx].block, + 0, TRUE32, buf->pData, buf->pSpare); + if ((!(status & PPN_READ_STATUS_INVALID_DATA)) && + cxt_spare->spareType == PPNVFL_SPARE_TYPE_CXT && + cxt_spare->idx == PPNVFL_CXT_LAST_BANKIDX && + mcxt.r_gen.cxt_age > cxt_spare->cxt_age) + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf->pData; + WMR_MEMCPY(mcxt.gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(VFLCxtBlockAddress) * mcxt.r_gen.num_of_vfl_blocks)); + mcxt.r_gen.cxt_age = cxt_spare->cxt_age; + break; + } + } + if (vfl_cxt_idx == mcxt.r_gen.num_of_vfl_blocks) + { + found_valid_cxt = TRUE32; + } + } + while (!found_valid_cxt); + + // use spare0 for the 1st pair and spare1 for the 2nd + WMR_MEMSET(&spare0, 0, sizeof(PPNVFL_CxtSpare)); + WMR_MEMSET(&spare1, 0, sizeof(PPNVFL_CxtSpare)); + + // read the 1st set + if (_readPageOfASet(0, 0, buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX) == ANDErrorCodeOk) + { + WMR_MEMCPY(&spare0, buf->pSpare, sizeof(PPNVFL_CxtSpare)); + } + + // read the 2nd set + if (_readPageOfASet(1, 0, buf2, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX) == ANDErrorCodeOk) + { + WMR_MEMCPY(&spare1, buf2->pSpare, sizeof(PPNVFL_CxtSpare)); + } + + // make a decision which pair of VFLCxt blcoks is current one and use it + if (spare0.spareType == PPNVFL_SPARE_TYPE_CXT && spare1.spareType == PPNVFL_SPARE_TYPE_CXT) + { + WMR_ASSERT(spare0.cxt_age != spare1.cxt_age); + + // assume that if we have two valid copies the older one is good + // as soon as we have a good good set in a new block we should erase the + // old block + if ((UInt32)spare0.cxt_age < (UInt32)spare1.cxt_age) + { + mcxt.r_gen.next_cxt_block_offset = 0; + WMR_PRINT(INF, "_findOnNANDCxt() bank:0x%04X AGE0 0x%X, age1 0x%X, type0 0x%X, type1 0x%X\n", + bank, spare0.cxt_age, spare1.cxt_age, spare0.spareType, spare1.spareType); + } + else + { + mcxt.r_gen.next_cxt_block_offset = 1; + WMR_PRINT(INF, "_findOnNANDCxt() bank:0x%04X age0 0x%X, AGE1 0x%X, type0 0x%X, type1 0x%X\n", + bank, spare0.cxt_age, spare1.cxt_age, spare0.spareType, spare1.spareType); + } + } + else if (spare0.spareType == PPNVFL_SPARE_TYPE_CXT) + { + mcxt.r_gen.next_cxt_block_offset = 0; + } + else if (spare1.spareType == PPNVFL_SPARE_TYPE_CXT) + { + mcxt.r_gen.next_cxt_block_offset = 1; + } + else + { + WMR_PRINT(INF, "could not find a single copy of VFLCxt (bank:0x%X)\n",bank); + goto error_return; + } + + // make sure the block list is up to date + if (mcxt.r_gen.next_cxt_block_offset) + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf2->pData; + WMR_MEMCPY(mcxt.gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(VFLCxtBlockAddress) * mcxt.r_gen.num_of_vfl_blocks)); + } + else + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf->pData; + WMR_MEMCPY(mcxt.gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(VFLCxtBlockAddress) * mcxt.r_gen.num_of_vfl_blocks)); + } + + // search for the latest version of the VFLCxt inside the current VFLCxt block pair + start_page = 1; // a set with a single page is not a valid set + end_page = mcxt.r_gen.vfl_pages_per_set - 1; + found_valid_cxt = FALSE32; + + while (end_page >= start_page) + { + PPNVFL_CxtSpare *spare = (PPNVFL_CxtSpare*)buf->pSpare; + mid_page = _div2RoundUp(end_page + start_page); + Int32 read_status = _readPageOfASet(mcxt.r_gen.next_cxt_block_offset, mid_page, + buf, PPNVFL_CXT_IGNORE_BANKIDX, PPNVFL_CXT_IGNORE_BANKIDX); + + if (read_status == ANDErrorCodeOk) + { + if (start_page == end_page) + { + if (spare->idx == PPNVFL_CXT_LAST_BANKIDX) + { + mcxt.r_gen.cxt_age = spare->cxt_age; + mcxt.r_gen.next_cxt_page_offset = start_page + 1; + + _copyFromOnNandCxtToRam(buf->pData); + + // verify the last page we wrote is valid + if (_readSingleRedundancyPageOfASet(mcxt.r_gen.next_cxt_block_offset, start_page, + (mcxt.r_gen.vfl_blocks_redundancy - 1), buf) != ANDErrorCodeOk) + { + mcxt.r_gen.need_rewrite = TRUE32; + WMR_PRINT(VFLWARN, "could not find vfl cxt in the last redundancy copy\n"); + } + + found_valid_cxt = TRUE32; + break; + } + else + { + mcxt.r_gen.need_rewrite = TRUE32; + WMR_PRINT(VFLWARN, "could not find cxt in bubble search\n"); + break; + } + } + else + { + start_page = mid_page; + continue; + } + } + + if (read_status == ANDErrorCodeCleanOk) + { + end_page = mid_page - 1; + continue; + } + + WMR_PRINT(VFLWARN, "deteteced vfl cxt pages with user data errors\n"); + end_page = mid_page; + mcxt.r_gen.need_rewrite = TRUE32; + break; + } + + for (cxt_blocks_idx = 0; (cxt_blocks_idx < 2) && (!found_valid_cxt); cxt_blocks_idx++) + { + for (page = (mcxt.r_gen.vfl_pages_per_set - 1); !found_valid_cxt; page--) + { + PPNVFL_CxtSpare *spare = (PPNVFL_CxtSpare*)buf->pSpare; + + Int32 read_status = _readPageOfASet(mcxt.r_gen.next_cxt_block_offset, page, buf, + PPNVFL_CXT_IGNORE_BANKIDX, PPNVFL_CXT_IGNORE_BANKIDX); + + if (read_status == ANDErrorCodeCleanOk) + { + continue; + } + + WMR_PRINT(VFLWARN, "Reading cxt next_cxt_block_offset:0x%04X, page:0x%04X read_status:0x%08X\n", + mcxt.r_gen.next_cxt_block_offset, page, read_status); + WMR_PRINT(VFLWARN, "spareType:0x%02X, bank:0x%02X, idx:0x%02X cxt_age:0x%08X\n", + spare->spareType, spare->bank, spare->idx, spare->cxt_age); + + if ((read_status == ANDErrorCodeOk) && (spare->spareType == PPNVFL_SPARE_TYPE_CXT) && + (spare->idx == PPNVFL_CXT_LAST_BANKIDX)) + { + mcxt.r_gen.cxt_age = spare->cxt_age; + _copyFromOnNandCxtToRam(buf->pData); + found_valid_cxt = TRUE32; + + if (0 == page) + { + // if the latest summary page we found is in page 0 the current block does not + // contain a full set we should copy to it from the other block + mcxt.r_gen.next_cxt_block_offset = (mcxt.r_gen.next_cxt_block_offset == 1 ? 0 : 1); + } + + break; + } + + if (page == 0) + { + break; + } + } + + if (!found_valid_cxt) + { + // switch to the other cxt set + mcxt.r_gen.next_cxt_block_offset = (mcxt.r_gen.next_cxt_block_offset == 1 ? 0 : 1); + } + } + + if (!found_valid_cxt) + { + WMR_PRINT(ERROR, "unable to find vfl cxt copy on the device\n"); + goto error_return; + } + + if (mcxt.gen.num_of_ftl_sublk > mcxt.gen.num_of_vfl_sublk) + { + WMR_PRINT(ERROR, "FTLSuBlks(=%d) > VFLSuBlks(=%d)\n", + mcxt.gen.num_of_ftl_sublk, mcxt.gen.num_of_vfl_sublk); + goto error_return; + } + + WMR_PRINT(INF, "_findOnNANDCxt(0x%04X) block 0x%X, page 0x%X, age 0x%X\n", + bank, mcxt.r_gen.next_cxt_block_offset, mcxt.r_gen.next_cxt_page_offset, + mcxt.r_gen.cxt_age); + + // initialize cached mapping + mcxt.r_gen.cached_vbn = 0xFFFF; + mcxt.r_gen.cached_vbn_good_blocks = 0; + WMR_MEMSET(mcxt.r_gen.cached_banks_v2p, 0xFF, sizeof(mcxt.r_gen.cached_banks_v2p)); + + BUF_Release(buf); + BUF_Release(buf2); + return TRUE32; + + error_return: + BUF_Release(buf); + BUF_Release(buf2); + return FALSE32; +} + +/* + * Name: _readVFLCxtPage + * Description: reads a single VFL Cxt page (either mapping or VFLCxt struct) + * Input: buffer, bank, index (what page to read). + * Return value: TRUE32 is successful, FALSE32 otherwise. + */ + +static BOOL32 +_readVFLCxtPage + (Buffer *buf, + UInt16 bank, + UInt16 vfl_idx) +{ + PPNVFL_CxtSpare *spare = (PPNVFL_CxtSpare*)buf->pSpare; + Int32 read_status; + const UInt16 set = ((mcxt.vfl_map_pages[bank][vfl_idx] & 0x8000) >> 15); + const UInt16 cxt_page_offset = (mcxt.vfl_map_pages[bank][vfl_idx] & 0x7FFF); + + WMR_PRINT(INF, "readVFLCxtPage(0x%04X, 0x%04X)\n", bank, vfl_idx); + read_status = _readPageOfASet(set, cxt_page_offset, buf, bank, vfl_idx); + + if ((read_status != ANDErrorCodeOk) || + ((spare->spareType != PPNVFL_SPARE_TYPE_CXT) || + (spare->idx != (UInt8)vfl_idx))) + { + WMR_PRINT(ERROR, "Error reading both cxt copies status 0x%X spareType 0x%02X index 0x%02X requested index 0x%02X\n", + read_status, spare->spareType, spare->idx, (UInt8)vfl_idx); + return FALSE32; + } + return TRUE32; +} + +static void +_convertVFLPageIdxToPhysicalPageBlockOffsets + (UInt16 set, + UInt16 vfl_page_idx, + UInt16 *vfl_block_offset, + UInt16 *vfl_page_offset) +{ + const UInt16 vfl_block_depth = (vfl_page_idx / mcxt.dev.pages_per_block_slc); + + *vfl_block_offset = ((set * mcxt.r_gen.vfl_blocks_redundancy * mcxt.r_gen.vfl_blocks_depth) + + (vfl_block_depth * mcxt.r_gen.vfl_blocks_redundancy)); + *vfl_page_offset = vfl_page_idx % mcxt.dev.pages_per_block_slc; +} +/* + * Name: _programVFLCxtPage + * Description: programs a single VFL Cxt page (either mapping or VFLCxt struct) + * Input: buffer, bank, index (what page to read). + * Return value: TRUE32 is successful, FALSE32 otherwise. + */ + +#ifndef AND_READONLY + +static BOOL32 +_programVFLCxtPage + (Buffer *buf, + UInt16 bank, + UInt16 vfl_idx) +{ + PPNStatusType status; + UInt16 redundant_copy, set = mcxt.r_gen.next_cxt_block_offset; + UInt16 vfl_block_offset, vfl_page_offset; + + WMR_PRINT(INF, "programVFLCxtPage(0x%04X, 0x%04X) page offset - 0x%X, set - 0x%X\n", + bank, vfl_idx, mcxt.r_gen.next_cxt_page_offset, set); + + WMR_ASSERT(mcxt.r_gen.next_cxt_page_offset != 0 || ((PPNVFL_CXT_LAST_BANKIDX == bank) && (PPNVFL_CXT_LAST_BANKIDX == vfl_idx))); + + _setVFLCxtSpare(buf->pSpare, bank, vfl_idx); + + _convertVFLPageIdxToPhysicalPageBlockOffsets(set, mcxt.r_gen.next_cxt_page_offset, + &vfl_block_offset, &vfl_page_offset); + + for (redundant_copy = 0; ((redundant_copy < mcxt.r_gen.vfl_blocks_redundancy) && + (!mcxt.r_gen.need_rewrite)); redundant_copy++) + { + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_PROGRAM, + PPN_NO_OPTIONS, + mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].bank, + mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].block, + vfl_page_offset, TRUE32, buf->pData, buf->pSpare); + if (status & (PPN_PROGRAM_STATUS_FAIL | PPN_PROGRAM_STATUS_GEB)) + { + PPNVFL_CxtSpare * spare = (PPNVFL_CxtSpare*) buf->pSpare; + mcxt.r_gen.need_rewrite = TRUE32; + + // leaving this print as warning so EFI does not stop till the next one + WMR_PRINT(VFLWARN, "status 0x%X marking vflcxt block for scrubbing(bank:0x%X, block:0x%X)\n", + status, + mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].bank, + mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy].block); + WMR_PRINT(QUAL, "spare->bank 0x%X, spare->idx 0x%X, spare->cxt_age 0x%X\n", + spare->bank, spare->idx, spare->cxt_age); + _setVFLCxtScrubMark(mcxt.gen.vfl_blocks[vfl_block_offset + redundant_copy]); + } + } + if (mcxt.r_gen.need_rewrite) + { + WMR_PRINT(VFLWARN, "failed _programVFLCxtPage mcxt.r_gen.need_rewrite is true\n"); + return FALSE32; + } + if (vfl_idx != PPNVFL_CXT_LAST_BANKIDX) + { + mcxt.vfl_map_pages[bank][vfl_idx] = (mcxt.r_gen.next_cxt_page_offset | + ((mcxt.r_gen.next_cxt_block_offset & 0x0001) << 15)); + } + + mcxt.r_gen.next_cxt_page_offset++; + mcxt.r_gen.cxt_age--; + + return TRUE32; +} + +static ProgramVFLCxtPageWrapStatus +_programVFLCxtPageWrap + (Buffer *buf, + UInt16 bank, + UInt16 vfl_idx) +{ + WMR_PRINT(INF, "programVFLCxtPageWrap(0x%04X, 0x%04X)\n", bank, vfl_idx); + if (mcxt.r_gen.next_cxt_page_offset == mcxt.r_gen.vfl_pages_per_set || + mcxt.r_gen.need_rewrite) + { + WMR_PRINT(VFLWARN, "Changing PPNVFL Cxt blocks pair ()\n"); + if (_copyVFLCxtToOtherPair() == FALSE32) + { + return VFLCxtProgramFail; + } + // if this is the last page, assume the copy function wrote it + if (vfl_idx == PPNVFL_CXT_LAST_BANKIDX) + { + return VFLCxtProgramDone; + } + return VFLCxtProgramRetry; + } + + return _programVFLCxtPage(buf, bank, vfl_idx) ? VFLCxtProgramDone : VFLCxtProgramRetry; +} + +static BOOL32 +_checkForVFLBlocksInScrubList + (UInt16 new_set_location, + BOOL32 *replace_blocks_array, + BOOL32 *replace_in_new_set) +{ + const UInt16 blocks_per_vfl_set = (mcxt.r_gen.num_of_vfl_blocks >> 1); + const UInt16 new_set_mapping_offset = new_set_location * blocks_per_vfl_set; + UInt16 idx; + + for (idx = 0; idx < blocks_per_vfl_set; idx++) + { + if (_isVFLCxtBlockMarkedScrub(mcxt.gen.vfl_blocks[new_set_mapping_offset + idx])) + { + WMR_PRINT(VFLWARN, "vfl cxt block replacement - found a vfl cxt block in the scrub list (bank: 0x%X, block: 0x%X, idx: 0x%X)\n", + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].block, idx); + if (*replace_in_new_set) + { + WMR_PRINT(ERROR, "more than one block to replace in the vfl cxt\n"); + return FALSE32; + } + replace_blocks_array[idx] = TRUE32; + *replace_in_new_set = TRUE32; + } + } + + return TRUE32; +} + +static BOOL32 +_checkForBankMapPages + (UInt16 vfl_set) +{ + UInt16 bank, i; + BOOL32 found_page_maps_from_set = FALSE32; + + for (bank = 0; (bank < mcxt.dev.num_of_banks) && (!found_page_maps_from_set); bank++) + { + for (i = 0; (i < mcxt.r_gen.pages_per_block_mapping) && (!found_page_maps_from_set); i++) + { + const UInt16 this_page_set = ((mcxt.vfl_map_pages[bank][i] & 0x8000) >> 15); + if (this_page_set == vfl_set) + { + found_page_maps_from_set = TRUE32; + } + } + } + return found_page_maps_from_set; +} + + +// _copyVFLCxtToOtherPair - Use this function to copy the current vfl cxt from the pair it +// resides in to the other pair (either due to program failure or due to lack of space) +static BOOL32 +_copyVFLCxtToOtherPair + (void) +{ + UInt16 idx, bank; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + Buffer *buf_mcxt_copy = BUF_Get(BUF_MAIN_AND_SPARE); + PPNStatusType status; + BOOL32 replace_blocks[PPNVFL_MAX_INFO_BLOCK_COUNT >> 1] = { FALSE32 }; + BOOL32 replace_in_new_set = FALSE32; + const UInt16 blocks_per_vfl_set = (mcxt.r_gen.num_of_vfl_blocks >> 1); + const UInt16 new_set_location = (mcxt.r_gen.next_cxt_block_offset == 1 ? 0 : 1); + const UInt16 new_set_mapping_offset = new_set_location * blocks_per_vfl_set; + + WMR_PRINT(VFLWARN, "_copyVFLCxtToOtherPair - original cxt set 0x%x, age 0x%X\n", + mcxt.r_gen.next_cxt_block_offset, mcxt.r_gen.cxt_age); + + if (buf == NULL || buf_mcxt_copy == NULL) + { + WMR_PRINT(ERROR, "failed allocating buf\n"); + goto return_error; + } + + // make a copy of the vfl map pages (case things go bad) + _copyFromRamToOnNandCxt(buf_mcxt_copy->pData); + + // check if there are replacement in the new pair + if (!_checkForVFLBlocksInScrubList(new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + + // check if there are any maps pointing to the set we are about to erase + if (_checkForBankMapPages(new_set_location)) + { + goto return_error; + } + + + mcxt.r_gen.need_rewrite = FALSE32; + // erase the set of blocks we want to use + if (!replace_in_new_set) + { + for (idx = 0; idx < blocks_per_vfl_set; idx++) + { + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].block, + 0, + TRUE32, NULL, NULL); + + if (status & PPN_ERASE_STATUS_RETIRE) + { + WMR_PRINT(QUAL, "failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with retire status\n", + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].block); + replace_blocks[idx] = TRUE32; + replace_in_new_set = TRUE32; + } + else if (status & PPN_ERASE_STATUS_FAIL) + { + WMR_PRINT(QUAL_FATAL, "failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with no retire status\n", + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt.gen.vfl_blocks[new_set_mapping_offset + idx].block); + goto return_error; + } + } + } + mcxt.r_gen.next_cxt_block_offset = new_set_location; + mcxt.r_gen.next_cxt_page_offset = 0; + + if ((!replace_in_new_set) && (!_programCxtLastPage(buf, FALSE32))) + { + WMR_PRINT(VFLWARN, "failed _programCxtLastPage inside _copyVFLCxtToOtherPair()\n"); + if (!_checkForVFLBlocksInScrubList(new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + if (!replace_in_new_set) + { + WMR_PRINT(ERROR, "failed _programVFLCxtPage but no blocks in scrub list\n"); + goto return_error; + } + } + + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + for (idx = 0; ((!replace_in_new_set) && + (idx < mcxt.r_gen.pages_per_block_mapping)); idx++) + { + if (!_readVFLCxtPage(buf, bank, idx)) + { + WMR_PRINT(ERROR, "failed _readVFLCxtPage inside _copyVFLCxtToOtherPair ()\n"); + goto return_error; + } + if (!_programVFLCxtPage(buf, bank, idx)) + { + WMR_PRINT(VFLWARN, "failed _programVFLCxtPage inside _copyVFLCxtToOtherPair ()\n"); + if (!_checkForVFLBlocksInScrubList(new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + if (!replace_in_new_set) + { + WMR_PRINT(ERROR, "failed _programVFLCxtPage but no blocks in scrub list\n"); + goto return_error; + } + } + } + } + if ((!replace_in_new_set) && (!_programCxtLastPage(buf, FALSE32))) + { + WMR_PRINT(VFLWARN, "failed _programCxtLastPage inside _copyVFLCxtToOtherPair()\n"); + if (!_checkForVFLBlocksInScrubList(new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + if (!replace_in_new_set) + { + WMR_PRINT(ERROR, "failed _programVFLCxtPage but no blocks in scrub list\n"); + goto return_error; + } + } + + if (replace_in_new_set) + { + UInt16 replacement_count = 0; + + for (idx = 0; idx < blocks_per_vfl_set; idx++) + { + if (replace_blocks[idx]) + { + replacement_count++; + } + WMR_ASSERT(replacement_count <= 1); // allow only one block replacement + } + for (idx = 0; idx < blocks_per_vfl_set; idx++) + { + if (replace_blocks[idx]) + { + // revert the map (case the error happen while programming the new set and mapping is off) + _copyMapPagesFromOnNandCxtToRam(buf_mcxt_copy->pData); + + BUF_Release(buf); + buf = NULL; + BUF_Release(buf_mcxt_copy); + buf_mcxt_copy = NULL; + // handle errors in working with the new pair + if (!_replaceErasedCxtBlock((new_set_mapping_offset + idx))) + { + WMR_PRINT(ERROR, "need to replace flag is set but nothing is marked for replacement (idx:0x%X)\n", idx); + goto return_error; + } + break; + } + } + if (idx == blocks_per_vfl_set) + { + WMR_PRINT(ERROR, "need to replace flag is set but nothing is marked for replacement (idx:0x%X)\n", idx); + goto return_error; + } + } + + // check if we need to replace a block from the previous set, if so, replace it here + + if (buf != NULL) + { + BUF_Release(buf); + } + if (buf_mcxt_copy != NULL) + { + BUF_Release(buf_mcxt_copy); + } + return TRUE32; + + return_error: + if (buf != NULL) + { + BUF_Release(buf); + } + if (buf_mcxt_copy != NULL) + { + BUF_Release(buf_mcxt_copy); + } + return FALSE32; +} + +static BOOL32 +_programCxtLastPage + (Buffer * buf, + BOOL32 retry) +{ + ProgramVFLCxtPageWrapStatus program_status; + + do + { + _copyFromRamToOnNandCxt(buf->pData); + program_status = _programVFLCxtPageWrap(buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX); + } + while ((program_status == VFLCxtProgramRetry) && retry); + + return (program_status != VFLCxtProgramDone) ? FALSE32 : TRUE32; +} + +static BOOL32 +_setNumOfFTLSuBlks + (UInt16 num_of_ftl_sublk) +{ + BOOL32 res; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + + WMR_PRINT(INF, "_setNumOfFTLSuBlks (0x%04X)\n", num_of_ftl_sublk); + if (num_of_ftl_sublk > mcxt.gen.num_of_vfl_sublk) + { + WMR_PANIC("[PPNVFL:WRN] failed setting the number of ftl blocks " + "num_of_vfl_sublk:0x%04X < num_of_ftl_sublk:0x%04X\n", + num_of_ftl_sublk, mcxt.gen.num_of_vfl_sublk); + } + mcxt.gen.num_of_ftl_sublk = num_of_ftl_sublk; + mcxt.gen.exported_lba_no = 0xffffffff; + res = _programCxtLastPage(buf, TRUE32); + BUF_Release(buf); + + return res; +} + +static BOOL32 +_setNumOfExportedLbas + (UInt32 num_of_exported_lbas) +{ + BOOL32 res; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + + mcxt.gen.exported_lba_no = num_of_exported_lbas; + + res = _programCxtLastPage(buf, TRUE32); + BUF_Release(buf); + + return res; +} + +static BOOL32 +_setL2vPoolSize + (UInt32 exported_l2v_pool_size) +{ + BOOL32 res; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + + mcxt.gen.exported_l2v_pool_size = exported_l2v_pool_size; + + res = _programCxtLastPage(buf, TRUE32); + BUF_Release(buf); + + return res; +} + +/* vfl cxt management functions - end */ + +#endif // AND_READONLY + +/* vfl I/F implementation - start */ +/* + * Name: _ppnvflInit + * Description: this function initialize the memory and structures for ppnvfl + * Input: fpart function table + * Return value: ANDErrorCodeOk if successfull + */ +static Int32 +_ppnvflInit + (FPartFunctions * pFPartFunctions) +{ + UInt32 i; + UInt16 pages_per_vfl_cxt_copy; // including the cxt and mapping + + if (mcxt.initialized) + { + return ANDErrorCodeOk; + } + + // Format checks: + WMR_ASSERT(sizeof(PPNVFL_CxtSpare) == 16); + WMR_ASSERT(WMR_OFFSETOF(PPNVFL_GeneralCxt, vfl_blocks) == 256); + + mcxt.fpart = pFPartFunctions; + mcxt.fil = mcxt.fpart->GetLowFuncTbl(); + + ppnMiscFillDevStruct(&mcxt.dev, mcxt.fil); + mcxt.single_command = (PPNCommandStruct*)mcxt.fpart->GetSingleCommandStruct(); + + // allocating the memory for the CAUs structures + // this code may later on move to open + if (mcxt.dev.num_channels == 0 || mcxt.dev.ces_per_channel == 0 || mcxt.dev.caus_per_ce == 0) + { + WMR_PRINT(ERROR, "_ppnvflInit num_channels 0x%X ces_per_channel 0x%X caus_per_ce 0x%X\n", + mcxt.dev.num_channels, mcxt.dev.ces_per_channel, mcxt.dev.caus_per_ce); + } + + mcxt.r_gen.pages_per_block_mapping = 1; + i = mcxt.dev.blocks_per_cau * sizeof(P2UsageType); + while (i > mcxt.dev.main_bytes_per_page) + { + i -= mcxt.dev.main_bytes_per_page; + mcxt.r_gen.pages_per_block_mapping++; + } + mcxt.r_gen.pbns_per_cxt_mapping_page = mcxt.dev.main_bytes_per_page / sizeof(P2UsageType); + + // calculate vfl cxt on nand - depth, redundancy and pages per set + mcxt.r_gen.vfl_blocks_redundancy = 4; + // make sure that we have at least twice as many entries as needed for a single copy of vflcxt and + // all the mapping + pages_per_vfl_cxt_copy = 1 + (mcxt.r_gen.pages_per_block_mapping * mcxt.dev.num_of_banks); + mcxt.r_gen.vfl_blocks_depth = 1; + while ((UInt16)(mcxt.r_gen.vfl_blocks_depth * (UInt16)mcxt.dev.pages_per_block_slc) < + (UInt32)(pages_per_vfl_cxt_copy * PPNVFL_NUM_OF_VFL_CXT_BLOCK_SETS)) + { + mcxt.r_gen.vfl_blocks_depth++; + } + mcxt.r_gen.vfl_pages_per_set = (mcxt.r_gen.vfl_blocks_depth * mcxt.dev.pages_per_block_slc); + mcxt.r_gen.num_of_vfl_blocks = (mcxt.r_gen.vfl_blocks_depth * mcxt.r_gen.vfl_blocks_redundancy * + PPNVFL_NUM_OF_VFL_CXT_BLOCK_SETS); + + mcxt.gen.num_of_vfl_sublk = _calcNumOfVFLSuBlk(); + mcxt.gen.num_of_ftl_sublk = mcxt.gen.num_of_vfl_sublk; + mcxt.gen.exported_lba_no = 0xffffffff; + mcxt.gen.exported_l2v_pool_size = 0xffffffff; + mcxt.r_gen.cxt_age = 0xFFFFFFFF; + mcxt.r_gen.bytes_per_vbn_bitmap = (mcxt.dev.num_of_banks >> 3) + (mcxt.dev.num_of_banks % 8 ? 1 : 0); + mcxt.v2p_bitmap_size = mcxt.r_gen.bytes_per_vbn_bitmap * mcxt.gen.num_of_vfl_sublk; + mcxt.vfl_map_pages = (UInt16**)WMR_MALLOC(sizeof(UInt16*) * mcxt.dev.num_of_banks); + mcxt.vfl_map_pages[0] = (UInt16*)WMR_MALLOC(sizeof(UInt16) * mcxt.dev.num_of_banks * + mcxt.r_gen.pages_per_block_mapping); + for (i = 1; i < mcxt.dev.num_of_banks; i++) + { + mcxt.vfl_map_pages[i] = &mcxt.vfl_map_pages[0][mcxt.r_gen.pages_per_block_mapping * i]; + } + mcxt.r_banks = (PPNVFL_BankRAMCxt*)WMR_MALLOC(sizeof(PPNVFL_BankRAMCxt) * mcxt.dev.num_of_banks); + + mcxt.v2p_bitmap = (UInt8*)WMR_MALLOC(mcxt.v2p_bitmap_size); // bit per block + WMR_MEMSET(mcxt.v2p_bitmap, 0, mcxt.v2p_bitmap_size); // mark all blocks as bad + mcxt.v2p_scrub_bitmap = (UInt8*)WMR_MALLOC(mcxt.v2p_bitmap_size); // bit per block + WMR_MEMSET(mcxt.v2p_scrub_bitmap, 0, mcxt.v2p_bitmap_size); // mark all blocks as bad + + if (mcxt.dev.ces_per_channel > 1) + { + mcxt.reorder = (PPNReorderStruct*)WMR_MALLOC(sizeof(PPNReorderStruct)); + } + else + { + mcxt.reorder = NULL; + } + + // allocate memory for the commands + WMR_ASSERT(mcxt.dev.num_of_banks <= PPNVFL_MAX_SUPPORTED_BANKS); + WMR_BufZone_Init(&mcxt.bufzone); + for (i = 0; i < mcxt.dev.num_channels; i++) + { + mcxt.commands[i] = (PPNCommandStruct *)WMR_Buf_Alloc_ForDMA(&mcxt.bufzone, sizeof(PPNCommandStruct)); + } + WMR_BufZone_FinishedAllocs(&mcxt.bufzone); + + for (i = 0; i < mcxt.dev.num_channels; i++) + { + WMR_BufZone_Rebase(&mcxt.bufzone, (void **)&mcxt.commands[i]); + WMR_ASSERT(mcxt.commands[i] != NULL); + } + WMR_BufZone_FinishedRebases(&mcxt.bufzone); + +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&mcxt.stat, 0, sizeof(SVFLStatistics)); +#endif + + mcxt.initialized = TRUE32; + return ANDErrorCodeOk; +} + +static BOOL32 +_isVFLCxtBlock + (UInt16 bank, + UInt16 block) +{ + UInt16 vfl_info_idx; + const UInt8 bank_uint8 = (UInt8) bank; + + for (vfl_info_idx = 0; vfl_info_idx < mcxt.r_gen.num_of_vfl_blocks; vfl_info_idx++) + { + if ((mcxt.gen.vfl_blocks[vfl_info_idx].bank == bank_uint8) && + (mcxt.gen.vfl_blocks[vfl_info_idx].block == block)) + { + return TRUE32; + } + } + return FALSE32; +} + +/* + * Name: _ppnvflOpen + * Description: reads the vfl structures from nand and build the ram version + * Input: + * Return value: ANDErrorCodeOk if successful. + */ + +static Int32 +_ppnvflOpen + (UInt32 dwKeepout, + UInt32 minor_ver, + UInt32 dwOptions) +{ + Buffer * buf = NULL; + UInt16 bank, j; + SpecialBlockAddress *special_blocks = NULL; + UInt16 *special_blocks_types = NULL; + UInt16 total_special_blocks = 0, total_cxt_blocks = 0, total_nand_boot_blocks = 0; + Int32 ret_val = ANDErrorCodeHwErr; +#if WMR_EFI + const UInt8 num_sectors = (mcxt.dev.main_bytes_per_page) / 1024; +#endif + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + // populate the General and CAU structures + + special_blocks = (SpecialBlockAddress *)WMR_MALLOC(AND_MAX_SPECIAL_BLOCKS * + sizeof(SpecialBlockAddress)); + special_blocks_types = (UInt16*)WMR_MALLOC(AND_MAX_SPECIAL_BLOCKS * sizeof(UInt16)); + + WMR_MEMSET(mcxt.v2p_bitmap, 0, mcxt.v2p_bitmap_size); // mark all blocks as bad + mcxt.blocks_to_scrub_count = 0; + WMR_MEMSET(mcxt.v2p_scrub_bitmap, 0, mcxt.v2p_bitmap_size); // mark all blocks as bad + + mcxt.r_gen.cxt_age = 0xFFFFFFFF; + mcxt.r_gen.keepout = dwKeepout; + mcxt.r_gen.options = dwOptions; + + WMR_MEMSET(mcxt.vfl_map_pages[0], 0, (mcxt.dev.num_of_banks * + mcxt.r_gen.pages_per_block_mapping * sizeof(UInt16))); + WMR_MEMSET(mcxt.r_banks, 0, (sizeof(PPNVFL_BankRAMCxt) * mcxt.dev.num_of_banks)); + + mcxt.r_gen.search_for_cxt = TRUE32; + + if (_findOnNANDCxt() == FALSE32) + { + WMR_PRINT(ERROR, "Error _findOnNANDCxt()\n"); + BUF_Release(buf); + return ANDErrorCodeHwErr; + } + + if (!mcxt.r_gen.need_rewrite) + { + mcxt.r_gen.search_for_cxt = FALSE32; + } + + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + // read the mapping and fill the v2p maps + for (j = 0; j < mcxt.r_gen.pages_per_block_mapping; j++) + { + UInt16 block, startOffset, count; + P2UsageType *p2_block_usage_map = (P2UsageType*)buf->pData; + if (_readVFLCxtPage(buf, bank, j) == FALSE32) + { + WMR_PRINT(ERROR, "Error _readVFLCxtPage(bank=%d, %d)\n", bank, j); + BUF_Release(buf); + return ANDErrorCodeHwErr; + } + startOffset = j * (mcxt.r_gen.pbns_per_cxt_mapping_page); + count = WMR_MIN((mcxt.dev.blocks_per_cau - startOffset), + mcxt.r_gen.pbns_per_cxt_mapping_page); + for (block = 0; block < count; block++) + { + UInt16 pbn = block + startOffset; + if (!(p2_block_usage_map[block] & AND_SB_BIT_SPEICAL_FLAG)) + { + mcxt.r_banks[bank].num_p2v++; + _setBlockAsVbnInBitmap(bank, pbn); + if (p2_block_usage_map[block] & PPNVFL_P2V_SCRUB_BIT) + { + _markBlockToScrubInBitmap(bank, pbn); + } + } + // count bad blocks (initial and grown and special blocks) + else + { + switch (p2_block_usage_map[block]) + { + case PPNVFL_TYPE_AVAILABLE_MARK: + mcxt.r_banks[bank].num_available++; + break; + + case PPNVFL_TYPE_GROWN_BB: + mcxt.r_banks[bank].num_grown_bad++; + break; + + case PPNVFL_TYPE_INITIAL_BB: + mcxt.r_banks[bank].num_initial_bad++; + break; + + case PPNVFL_TYPE_VFL_INFO: + mcxt.r_banks[bank].num_cxt++; + WMR_ASSERT(_isVFLCxtBlock(bank, pbn)); + total_cxt_blocks++; + break; + + default: + { + if (andSBGetHandler(p2_block_usage_map[block]) != AND_SB_HANDLER_VFL_CXT) + { + if (AND_MAX_SPECIAL_BLOCKS <= total_special_blocks) + { + WMR_PRINT(ERROR, "total special blocks has exceeded the max allowed\n"); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + mcxt.r_banks[bank].num_special_blocks++; + special_blocks[total_special_blocks].bank = bank; + special_blocks[total_special_blocks].block = pbn; + special_blocks_types[total_special_blocks] = p2_block_usage_map[block]; + if(special_blocks_types[total_special_blocks] == AND_SB_TYPE_NAND_BOOT) + { + total_nand_boot_blocks++; + } + total_special_blocks++; + break; + } + else + { + WMR_PRINT(ERROR, "unknown block marking: 0x%08x\n", p2_block_usage_map[block]); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + } + } + } + } + } + } + + WMR_ASSERT(total_cxt_blocks == mcxt.r_gen.num_of_vfl_blocks); + mcxt.r_gen.cxt_age--; + if((BOOT_BLOCK_ALLOCATION_COUNT(&mcxt)) && (total_nand_boot_blocks > BOOT_BLOCK_ALLOCATION_COUNT(&mcxt))) + { + WMR_PRINT(ALWAYS, "!!!!!! total nand boot blocks exceeded max allowed %d > %d !!!!!! \n", total_nand_boot_blocks, BOOT_BLOCK_ALLOCATION_COUNT(&mcxt)); + } + + if (total_special_blocks != 0) + { + UInt16 sb_idx; + + mcxt.fpart->ChangeCacheState(FALSE32); + // send the list to FPart + for (sb_idx = 0; sb_idx < total_special_blocks; sb_idx++) + { + if (!mcxt.fpart->AllocateSpecialBlockType(&special_blocks[sb_idx], 1, special_blocks_types[sb_idx])) + { + WMR_PRINT(ERROR, "fpart failed to allocate special block with type %p\n", + special_blocks_types[sb_idx]); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + } + mcxt.fpart->ChangeCacheState(TRUE32); + } + + ret_val = ANDErrorCodeOk; + + _printVFLBlockMapping(__LINE__); +#ifndef AND_READONLY + if (mcxt.r_gen.need_rewrite) + { + if (!_copyVFLCxtToOtherPair()) + { + // we failed to copy the vfl cxt we have not functional cxt + WMR_PRINT(ERROR, "failed _copyVFLCxtToOtherPair after need_rewrite = TRUE\n"); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + mcxt.r_gen.search_for_cxt = FALSE32; + _printVFLBlockMapping(__LINE__); + } +#endif + +#if WMR_EFI + //Bitflip info is always in the first few bytes on the bus - So need to check if those were data or meta + + if(!FIL_GetStruct(AND_STRUCT_FIL_NAND_LAYOUT, &p_layout, &p_layout_size)) + { + WMR_PRINT(ERROR, "Could not get NAND layout for sector stats manipulation\n"); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + if(p_layout.dwMetaSegmentIndex == 0) //meta first, then data + { + //bitflips overflow from meta into data + if(num_sectors > p_layout.pastrSegments[0].dwLength) + { + stats_copy_from_meta = p_layout.pastrSegments[0].dwLength; + stats_copy_from_data = num_sectors - stats_copy_from_meta; + stats_offset_from_meta = 0; + stats_offset_from_data = stats_copy_from_meta; + } + else + { + stats_copy_from_meta = num_sectors; + } + } + else //data first, then meta. Assume that there are no more than 'sector size' number of sectors + { + stats_copy_from_data = num_sectors; + } +#endif // WMR_EFI + + exit: + if (NULL != buf) + { + BUF_Release(buf); + } + if (NULL != special_blocks) + { + WMR_FREE(special_blocks, (AND_MAX_SPECIAL_BLOCKS * sizeof(SpecialBlockAddress))); + } + if (NULL != special_blocks_types) + { + WMR_FREE(special_blocks_types, (AND_MAX_SPECIAL_BLOCKS * sizeof(UInt16))); + } + + mcxt.r_gen.active = FALSE32; + + return ret_val; +} + +#ifndef AND_READONLY + +/* this function fills the vfl cxt block list */ +static BOOL32 +_fillVFLCxtBlockList + (P2UsageType **on_nand_block_map) +{ + UInt16 vfl_info_idx, pbn, bank; + + pbn = mcxt.dev.blocks_per_cau - 1; + + for (vfl_info_idx = 0; ((vfl_info_idx < mcxt.r_gen.num_of_vfl_blocks) && + (pbn != 0)); pbn--) + { + for (bank = 0; ((bank < mcxt.dev.num_of_banks) && + (vfl_info_idx < mcxt.r_gen.num_of_vfl_blocks)); bank++) + { + if (on_nand_block_map[bank][pbn] == PPNVFL_TYPE_AVAILABLE_MARK) + { + if (ppnMiscTestSpecialBlock(&mcxt.dev, mcxt.commands[0], bank, pbn, PPNVFL_SPARE_TYPE_TST)) + { + on_nand_block_map[bank][pbn] = PPNVFL_TYPE_VFL_INFO; + mcxt.gen.vfl_blocks[vfl_info_idx].bank = bank; + mcxt.gen.vfl_blocks[vfl_info_idx].block = pbn; + mcxt.gen.vfl_blocks[vfl_info_idx].features = 0; + vfl_info_idx++; + } + else + { + on_nand_block_map[bank][pbn] = PPNVFL_TYPE_GROWN_BB; + } + } + } + } + + if ((vfl_info_idx < mcxt.r_gen.num_of_vfl_blocks) || (pbn == 0)) + { + WMR_PRINT(ERROR, "failed allocating vfl info blocks \n"); + goto return_error; + } + + return TRUE32; + + return_error: + return FALSE32; +} + +/* + * Name: _calcFormatNumOfVFLUserBlks + * Return value: number of VFL virtual blocks for this media + */ +static UInt32 +_calcFormatNumOfVFLUserBlks +(void) +{ + UInt32 shift, result, above, under, closest_power_of_two; + + shift = WMR_LOG2(mcxt.dev.blocks_per_cau); + + above = mcxt.dev.blocks_per_cau - (1 << shift); + under = (1 << (shift + 1)) - mcxt.dev.blocks_per_cau; + + if (under < above) + { + shift = shift + 1; + } + closest_power_of_two = (1 << shift); + result = mcxt.dev.num_of_banks * PPNVFL_USER_BLKS_PER_256B * (closest_power_of_two >> 8); + return result; +} + +static BOOL32 +_programFormatVFLCxt + (P2UsageType **on_nand_block_map, + Buffer *buf) +{ + UInt16 bank, i, vfl_info_idx; + PPNStatusType status; + + for (vfl_info_idx = 0; vfl_info_idx < mcxt.r_gen.num_of_vfl_blocks; vfl_info_idx++) + { + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt.gen.vfl_blocks[vfl_info_idx].bank, + mcxt.gen.vfl_blocks[vfl_info_idx].block, + 0, TRUE32, NULL, NULL); + if (status & PPN_ERASE_STATUS_FAIL) + { + // we should not get here - vfl blocks were tested + _setVFLCxtScrubMark(mcxt.gen.vfl_blocks[vfl_info_idx]); + WMR_PRINT(QUAL_FATAL, "format fail erasing info block fail!\n"); + goto return_error; + } + } + + mcxt.r_gen.next_cxt_block_offset = 0; + mcxt.r_gen.next_cxt_page_offset = 0; + mcxt.r_gen.need_rewrite = FALSE32; + + if (!_programCxtLastPage(buf, TRUE32)) + { + WMR_PRINT(VFLWARN, "_ppnvflFormat - failed _programCxtLastPage()\n"); + goto return_error; + } + + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + for (i = 0; i < mcxt.r_gen.pages_per_block_mapping; i++) + { + UInt16 start_offset = i * mcxt.r_gen.pbns_per_cxt_mapping_page; + UInt16 size_to_copy = WMR_MIN(mcxt.dev.main_bytes_per_page, + ((mcxt.dev.blocks_per_cau - start_offset) * sizeof(P2UsageType))); + WMR_MEMSET(buf->pData, 0xFF, mcxt.dev.main_bytes_per_page); + WMR_MEMCPY(buf->pData, &on_nand_block_map[bank][start_offset], size_to_copy); + if (!_programVFLCxtPage(buf, bank, i)) + { + WMR_PRINT(VFLWARN, "_ppnvflFormat - failed _programCxtLastPage()\n"); + goto return_error; + } + } + } + + if (!_programCxtLastPage(buf, TRUE32)) + { + WMR_PRINT(VFLWARN, "_ppnvflFormat - failed _programCxtLastPage()\n"); + goto return_error; + } + + return TRUE32; + + return_error: + + // mark the good vfl blocks as available + // mark the grown bad as grown bad + for (vfl_info_idx = 0; vfl_info_idx < mcxt.r_gen.num_of_vfl_blocks; vfl_info_idx++) + { + const UInt8 curr_bank = mcxt.gen.vfl_blocks[vfl_info_idx].bank; + const UInt16 curr_block = mcxt.gen.vfl_blocks[vfl_info_idx].block; + + if (_isVFLCxtBlockMarkedScrub(mcxt.gen.vfl_blocks[vfl_info_idx])) + { + on_nand_block_map[curr_bank][curr_block] = PPNVFL_TYPE_GROWN_BB; + _unsetVFLCxtScrubMark(mcxt.gen.vfl_blocks[vfl_info_idx]); + ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_ERASE, + PPN_OPTIONS_IGNORE_BAD_BLOCK, curr_bank, curr_block, + 0, TRUE32, NULL, NULL); + } + else + { + on_nand_block_map[curr_bank][curr_block] = PPNVFL_TYPE_AVAILABLE_MARK; + } + } + + return FALSE32; +} + +/* + * Name: _ppnvflFormat + * Description: implements format function for the vfl I/F + * Input: + * Return value: ANDErrorCodeOk if successful. + */ +static Int32 +_ppnvflFormat + (UInt32 dwKeepout, + UInt32 dwOptions) +{ + UInt16 bank, pbn, i, pre_mapped_special_blocks; + Buffer *buf = NULL; + P2UsageType **on_nand_block_map = NULL; + PPNStatusType status; + UInt16 sb_allocation_count = 0; + UInt16 *special_blocks_types = NULL; + SpecialBlockAddress *special_blocks = NULL; + UInt32 sizeof_special_blocks_types = 0, sizeof_special_blocks = 0, vbn_allocation_count = 0; + const UInt32 min_num_of_user_blocks = _calcFormatNumOfVFLUserBlks(); // minimum number of physical blocks that + // needs to be available for ftls + UInt32 sb_pre_alloc; + + + // Init the general structure + mcxt.r_gen.cxt_age = 0xFFFFFFFF; + mcxt.r_gen.keepout = dwKeepout; + mcxt.r_gen.options = dwOptions; + mcxt.gen.ftl_type = 0xFFFFFFFF; + mcxt.gen.exported_lba_no = 0xFFFFFFFF; + mcxt.gen.exported_l2v_pool_size = 0xffffffff; + + WMR_PRINT(ALWAYS, "dwKeepout:%d, dwOptions:0x%X\n", dwKeepout, dwOptions); + + // before we start - make sure the PPN configuration here make sense to this vfl + if (mcxt.dev.ces_per_channel > PPN_MAX_CES_PER_BUS) + { + WMR_PRINT(ERROR, "PPNVFL does not support configurations with more than %d CEs/Channel (found %d)!\n", + PPN_MAX_CES_PER_BUS, mcxt.dev.ces_per_channel); + goto return_error; + } + if (mcxt.dev.main_bytes_per_page < PPNVFL_MIN_PAGE_SIZE) + { + WMR_PRINT(ERROR, "PPNVFL does not support configurations with less than %d bytes per page (found %d)!\n", + PPNVFL_MIN_PAGE_SIZE, mcxt.dev.main_bytes_per_page); + goto return_error; + } + if (mcxt.dev.num_of_banks > PPNVFL_MAX_SUPPORTED_BANKS) + { + WMR_PRINT(ERROR, "PPNVFL does not support configurations with more than %d banks (found %d)!\n", + PPNVFL_MAX_SUPPORTED_BANKS, mcxt.dev.num_of_banks); + goto return_error; + } + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + if (buf == NULL) + { + WMR_PRINT(ERROR, "BUF_Get fail!\n"); + return ANDErrorCodeHwErr; + } + + // start - 1. allocate memory to hold phisycal to virtual mapping + on_nand_block_map = (P2UsageType**)WMR_MALLOC(sizeof(P2UsageType*) * mcxt.dev.num_of_banks); + if (on_nand_block_map == NULL) + { + WMR_PRINT(ERROR, "allocation fail!\n"); + goto return_error; + } + on_nand_block_map[0] = (P2UsageType*)WMR_MALLOC(mcxt.dev.blocks_per_cau * mcxt.dev.num_of_banks * + sizeof(P2UsageType)); + if (on_nand_block_map[0] == NULL) + { + WMR_PRINT(ERROR, "allocation fail!\n"); + goto return_error; + } + // assign the rest of the pointers + for (bank = 1; bank < mcxt.dev.num_of_banks; bank++) + { + on_nand_block_map[bank] = &(on_nand_block_map[0][(bank * mcxt.dev.blocks_per_cau)]); + } + // end - 1. allocate memory to hold phisycal to virtual mapping - end + + // start - 2. read the bbts + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + status = ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_CAUBBT, + PPN_NO_OPTIONS, bank, 0, 0, TRUE32, buf->pData, NULL); + if (status & PPN_OTHERS_STATUS_OP_FAILED) + { + WMR_PRINT(ERROR, "ReadCAUBBT fail!\n"); + goto return_error; + } + + for (pbn = 0; pbn < mcxt.dev.blocks_per_cau; pbn++) + { + if (ppnMiscIsBlockGood(buf->pData, pbn) == FALSE32) + { + on_nand_block_map[bank][pbn] = PPNVFL_TYPE_INITIAL_BB; + WMR_PRINT(ALWAYS, "Initial Bad Block bank: 0x%04x block 0x%04x\n", bank, pbn); + } + else + { + on_nand_block_map[bank][pbn] = PPNVFL_TYPE_AVAILABLE_MARK; + } + } + } + // end - 2. read the bbts + + // start - 3. mark special blocks + // start - 3.1 mark pre allocated special blocks + if (mcxt.fpart->MapSpecialBlocks(NULL, NULL, &pre_mapped_special_blocks) == TRUE32) + { + sizeof_special_blocks_types = pre_mapped_special_blocks * sizeof(UInt16); + sizeof_special_blocks = pre_mapped_special_blocks * sizeof(SpecialBlockAddress); + + special_blocks_types = (UInt16*)WMR_MALLOC(sizeof_special_blocks_types); + special_blocks = (SpecialBlockAddress*)WMR_MALLOC(sizeof_special_blocks); + + if (mcxt.fpart->MapSpecialBlocks(special_blocks, special_blocks_types, + &pre_mapped_special_blocks) == FALSE32) + { + WMR_PRINT(ERROR, "MapSpecialBlocks fail after success??? \n"); + goto return_error; + } + for (i = 0; i < pre_mapped_special_blocks; i++) + { + bank = special_blocks[i].bank; + pbn = special_blocks[i].block; + on_nand_block_map[bank][pbn] = special_blocks_types[i]; + } + } + // end - 3.1 mark pre allocated special blocks + + // start - 3.2 mark block zero + // start - 3.3 mark nand boot blocks + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + if (ppnMiscGetCAUFromBank(&mcxt.dev, bank) == 0) + { + on_nand_block_map[bank][0] = AND_SB_TYPE_BLOCK_ZERO; + // support for legacy nand-boot area + if (0 == (WMR_INIT_USE_KEEPOUT_AS_BORROW & mcxt.r_gen.options)) + { + for (pbn = 0; pbn < mcxt.r_gen.keepout; pbn++) + { + if (on_nand_block_map[bank][pbn] == PPNVFL_TYPE_AVAILABLE_MARK) + { + on_nand_block_map[bank][pbn] = AND_SB_TYPE_KEEPOUT_BOOT; + } + } + } + } + } + + // end - 3.2 mark block zero + // end - 3.3 mark nand boot blocks + + // start - 3.4 mark vfl context blocks + WMR_MEMSET(mcxt.gen.vfl_blocks, 0xFF, (sizeof(mcxt.gen.vfl_blocks[0]) * mcxt.r_gen.num_of_vfl_blocks)); + if (!_fillVFLCxtBlockList(on_nand_block_map)) + { + goto return_error; + } + // end - 3.4 mark vfl context blocks + + // start - 3.5 generate a bar for the perfect striping (make sure we put special blocks on top) + + sb_allocation_count = 0; + sb_pre_alloc = SPECIAL_BLOCK_PRE_ALLOCATION_COUNT(&mcxt); + for (pbn = mcxt.dev.blocks_per_cau - 1; + ((pbn >= PPN_SPECIAL_BLOCK_LIMIT(&mcxt.dev)) && (sb_allocation_count < sb_pre_alloc)); + pbn--) + { + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + if (on_nand_block_map[bank][pbn] == PPNVFL_TYPE_AVAILABLE_MARK) + { + if (sb_pre_alloc > sb_allocation_count) + { + sb_allocation_count++; + } + else + { + // we have enough sb, allocate rest of stripe for vbn + on_nand_block_map[bank][pbn] = PPNVFL_TYPE_VBN; + vbn_allocation_count++; + } + } + } + } + + if (pbn < PPN_SPECIAL_BLOCK_LIMIT(&mcxt.dev)) + { + WMR_PRINT(ERROR, "_ppnvflFormat - unable to reserve special block stripe - 0x%X\n", pbn); + goto return_error; + } + + mcxt.gen.num_of_vfl_sublk = pbn + 1; + mcxt.gen.num_of_ftl_sublk = pbn + 1; + // end - 3.5 generate a bar for the perfect striping (make sure we put special blocks on top) + + // end - 3. mark special blocks + + // start - 4. allocate virtual blocks - start + // start - 4.1. pick the best aligned blocks first + + for (pbn = 1; pbn < mcxt.gen.num_of_vfl_sublk; pbn++) + { + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + if (on_nand_block_map[bank][pbn] == PPNVFL_TYPE_AVAILABLE_MARK) + { + on_nand_block_map[bank][pbn] = PPNVFL_TYPE_VBN; + vbn_allocation_count++; + } + } + } + + if (PPNVFL_TYPE_VBN == on_nand_block_map[mcxt.dev.num_of_banks - 1][pbn]) + { + mcxt.gen.num_of_vfl_sublk = pbn + 1; + mcxt.gen.num_of_ftl_sublk = pbn + 1; + } + + if (vbn_allocation_count < min_num_of_user_blocks) + { + WMR_PRINT(ERROR, "_ppnvflFormat - unable to reserve enough blocks " + "for ftl - actual 0x%X, expected 0x%X\n", + vbn_allocation_count, min_num_of_user_blocks); + goto return_error; + } + + // end - 4.1. pick the best aligned blocks first + // end - 4. allocate virtual blocks - end + + // start - 5. program the context blocks + // start - 5.1. erase all the vfl context blocks + // start - 5.2. program the cxt blocks + while (!_programFormatVFLCxt(on_nand_block_map, buf)) + { + WMR_PRINT(VFLWARN, "_programFormatVFLCxt failed, reallocating vflcxt blocks\n"); + + if (!_fillVFLCxtBlockList(on_nand_block_map)) + { + goto return_error; + } + } + // end - 5.1. erase all the vfl context blocks + // end - 5.2. program the cxt blocks + // end - 5. program the context blocks + + // start - 6. clean up the mess + // free temp allocations done in this function + WMR_FREE(on_nand_block_map[0], mcxt.dev.blocks_per_cau * mcxt.dev.num_of_banks * sizeof(P2UsageType)); + WMR_FREE(on_nand_block_map, (sizeof(P2UsageType*) * mcxt.dev.num_of_banks)); + + if (special_blocks_types != NULL) + { + WMR_FREE(special_blocks_types, sizeof_special_blocks_types); + } + + if (special_blocks != NULL) + { + WMR_FREE(special_blocks, sizeof_special_blocks); + } + + BUF_Release(buf); + // end - 6. clean up the mess + + return ANDErrorCodeOk; + + return_error: + + // start - 6. clean up the mess + // free temp allocations done in this function + if (on_nand_block_map != NULL && on_nand_block_map[0] != NULL) + { + WMR_FREE(on_nand_block_map[0], mcxt.dev.blocks_per_cau * mcxt.dev.num_of_banks * sizeof(P2UsageType)); + } + + if (on_nand_block_map != NULL) + { + WMR_FREE(on_nand_block_map, (sizeof(P2UsageType*) * mcxt.dev.num_of_banks)); + } + + if (special_blocks_types != NULL) + { + WMR_FREE(special_blocks_types, sizeof_special_blocks_types); + } + + if (special_blocks != NULL) + { + WMR_FREE(special_blocks, sizeof_special_blocks); + } + + BUF_Release(buf); + // end - 6. clean up the mess + + return ANDErrorCodeHwErr; +} + +#endif // !AND_READONLY + +/* + * Name: _bitSwapBuffer + * Description: swaps the order of the bits on every byte in the given buffer + * Input: buffer and length, no alignment requirement + * Output: bit-swapped buffer + */ +static void +_bitSwapBuffer + (void *buffer, + UInt32 length) +{ + UInt8 *cursor = (UInt8*)buffer; + + while (length--) + { + UInt8 byte = *cursor; + *cursor = ((byte & 0x01) << 7) | + ((byte & 0x02) << 5) | + ((byte & 0x04) << 3) | + ((byte & 0x08) << 1) | + ((byte & 0x10) >> 1) | + ((byte & 0x20) >> 3) | + ((byte & 0x40) >> 5) | + ((byte & 0x80) >> 7); + cursor++; + } +} + +/* + * Name: _ppnvflGetStruct + * Description: implements GetStruct function for the vfl I/F + * Input: struct type + * Output: buffer, buffer size + * Return value: TRUE32 if successful, otherwise - FALSE32 + */ +static BOOL32 +_ppnvflGetStruct + (UInt32 dwStructType, + void *pvoidStructBuffer, + UInt32 *pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { + case AND_STRUCT_VFL_GET_TYPE: + { + UInt8 bVFLType = VFL_TYPE_SWISSPPNVFL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &bVFLType, + sizeof(bVFLType)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_STATISTICS_SIZE: + { + UInt32 dwStatSize = sizeof(SVFLStatistics); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwStatSize, + sizeof(dwStatSize)); + break; + } + + case AND_STRUCT_VFL_STATISTICS: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &mcxt.stat, + sizeof(mcxt.stat)); + break; + } +#endif // AND_COLLECT_STATISTICS + + case AND_STRUCT_VFL_FILSTATISTICS: + { + boolRes = FIL_GetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, + pdwStructSize); + break; + } + + case AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS: + { + UInt16 dwNumFTLSuBlks = mcxt.gen.num_of_ftl_sublk; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumFTLSuBlks, + sizeof(dwNumFTLSuBlks)); + break; + } + + case AND_STRUCT_VFL_EXPORTED_LBA_NO: + { + UInt32 dwNumOfExportedLbas = mcxt.gen.exported_lba_no; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumOfExportedLbas, + sizeof(dwNumOfExportedLbas)); + break; + } + + case AND_STRUCT_VFL_EXPORTED_L2V_POOL: + { + UInt32 dwL2vPoolSize = mcxt.gen.exported_l2v_pool_size; +#ifndef AND_READONLY + UInt32 vfl_capacity_in_kb = mcxt.gen.num_of_vfl_sublk * mcxt.dev.pages_per_sublk * (mcxt.dev.main_bytes_per_page/1024); + + if ((AND_L2V_POOL_SIZE_UNSPECIFIED == dwL2vPoolSize) || ((LARGE_DISK_THRESHOLD_KB < vfl_capacity_in_kb) && (LARGE_DISK_L2V_NODEPOOL_MEM > dwL2vPoolSize ))) + { + if(AND_L2V_POOL_SIZE_UNSPECIFIED == dwL2vPoolSize) + { + dwL2vPoolSize = mcxt.fil->GetDeviceInfo(AND_DEVINFO_L2V_POOL_SIZE); + } + if (LARGE_DISK_THRESHOLD_KB < vfl_capacity_in_kb) + { + dwL2vPoolSize = WMR_MAX(dwL2vPoolSize, LARGE_DISK_L2V_NODEPOOL_MEM); + } + if (AND_L2V_POOL_SIZE_UNSPECIFIED != dwL2vPoolSize) + { + _setL2vPoolSize(dwL2vPoolSize); + } + } +#endif // AND_READONLY + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwL2vPoolSize, + sizeof(dwL2vPoolSize)); + break; + } + + case AND_STRUCT_VFL_NUM_OF_SUBLKS: + { + UInt16 dwNumVFLSuBlks = mcxt.gen.num_of_vfl_sublk; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumVFLSuBlks, + sizeof(dwNumVFLSuBlks)); + break; + } + + case AND_STRUCT_VFL_BYTES_PER_PAGE: + { + UInt16 wPageSize = mcxt.dev.main_bytes_per_page; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPageSize, + sizeof(wPageSize)); + break; + } + + case AND_STRUCT_VFL_PAGES_PER_SUBLK: + { + UInt16 wPagesPerSuBlk = mcxt.dev.pages_per_sublk; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPagesPerSuBlk, + sizeof(wPagesPerSuBlk)); + break; + } + + case AND_STRUCT_VFL_NUM_CHANNELS: + { + UInt32 dwNumChannels = mcxt.dev.num_channels; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumChannels, + sizeof(dwNumChannels)); + break; + } + + case AND_STRUCT_VFL_CES_PER_CHANNEL: + { + UInt32 dwCesPerChannel = mcxt.dev.ces_per_channel; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwCesPerChannel, + sizeof(dwCesPerChannel)); + break; + } + + case AND_STRUCT_VFL_CAUS_PER_CE: + { + UInt32 dwCausPerCe = mcxt.dev.caus_per_ce; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwCausPerCe, + sizeof(dwCausPerCe)); + break; + } + + case AND_STRUCT_VFL_MAX_TRANS_IN_PAGES: + { + UInt32 maxTransactionSizeinPages = (mcxt.dev.ces_per_channel) * (mcxt.dev.num_channels) * (PPN_MAX_PAGES_PER_CE); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &maxTransactionSizeinPages, + sizeof(maxTransactionSizeinPages)); + break; + } + + case AND_STRUCT_VFL_NAND_TYPE: + { + UInt32 nand_type = NAND_TYPE_PPN; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &nand_type, + sizeof(nand_type)); + break; + } + + case AND_STRUCT_VFL_BYTES_PER_META: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &mcxt.dev.lba_meta_bytes_buffer, + sizeof(mcxt.dev.lba_meta_bytes_buffer)); + break; + } + + case AND_STRUCT_VFL_VALID_BYTES_PER_META: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &mcxt.dev.lba_meta_bytes_valid, + sizeof(mcxt.dev.lba_meta_bytes_valid)); + break; + } + + case AND_STRUCT_VFL_PUBLIC_FBBT: + // Fall Through + case AND_STRUCT_VFL_FACTORY_BBT: + { + UInt8 cau; + UInt8 ce; + UInt8 *pData; + Buffer *buf; + const UInt32 cau_bbt_size = (mcxt.dev.blocks_per_cau / 8) + (mcxt.dev.blocks_per_cau % 8 ? 1 : 0); + const UInt32 total_ces = mcxt.dev.ces_per_channel * mcxt.dev.num_channels; + const UInt32 total_caus = mcxt.dev.caus_per_ce * total_ces; + const UInt32 required_buffer_size = cau_bbt_size * total_caus; + + if (NULL == pdwStructSize) + { + // Can't do anything without a size + boolRes = FALSE32; + } + else if (NULL == pvoidStructBuffer) + { + // Just report the size + *pdwStructSize = required_buffer_size; + boolRes = TRUE32; + } + else if (*pdwStructSize < required_buffer_size) + { + // Caller is asking for actual data with + // too small of a buffer + boolRes = FALSE32; + } + else if (AND_STRUCT_VFL_PUBLIC_FBBT == (dwStructType & AND_STRUCT_INDEX_MASK)) + { + *pdwStructSize = required_buffer_size; + + // Mark all blocks bad + WMR_MEMSET(pvoidStructBuffer, 0, *pdwStructSize); + + for (ce = 0; ce < total_ces; ce++) + { + const UInt32 ce_bbt_size = cau_bbt_size * mcxt.dev.caus_per_ce; + const UInt32 ce_bbt_idx = ce * ce_bbt_size; + UInt8 *ce_bbt_ptr = ((UInt8 *)pvoidStructBuffer) + ce_bbt_idx; + + // Mark block 0 good + ce_bbt_ptr[0] = 0x01; + } + + boolRes = TRUE32; + } + else + { + *pdwStructSize = required_buffer_size; + boolRes = TRUE32; + pData = (UInt8 *)pvoidStructBuffer; + buf = BUF_Get(BUF_MAIN_AND_SPARE); + WMR_ASSERT(buf != NULL); + + for (ce = 0; ce < total_ces; ce++) + { + for (cau = 0; cau < mcxt.dev.caus_per_ce; cau++) + { + ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_CAUBBT, + PPN_NO_OPTIONS, + ((cau * total_ces) + ce), + 0, 0, TRUE32, buf->pData, NULL); + WMR_MEMCPY(pData, buf->pData, cau_bbt_size); + // Consumers expect opposite bit-order + _bitSwapBuffer(pData, cau_bbt_size); + pData += cau_bbt_size; + } + } + BUF_Release(buf); + } + + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_BITS: + { + UInt16 correctableBits = (UInt16)mcxt.fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &correctableBits, sizeof(correctableBits)); + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_SIZE: + { + UInt16 correctableSize = (UInt16)mcxt.fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &correctableSize, sizeof(correctableSize)); + break; + } + + case AND_STRUCT_VFL_PAGES_PER_BLOCK: + { + UInt16 pagesPerBlock = (UInt16)mcxt.fil->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &pagesPerBlock, sizeof(pagesPerBlock)); + break; + } + + case AND_STRUCT_VFL_DEVICEINFO_SIZE: + { + UInt32 deviceInfoSize = sizeof(mcxt.dev); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &deviceInfoSize, sizeof(deviceInfoSize)); + break; + } + + case AND_STRUCT_VFL_DEVICEINFO: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &mcxt.dev, sizeof(mcxt.dev)); + break; + } + + case AND_STRUCT_VFL_GETADDRESS: + { + UInt16 bank, block, page_offset, cau; + UInt32 vba, vpn; + ANDAddressStruct *addrStruct = (ANDAddressStruct*)pvoidStructBuffer; + *pdwStructSize = sizeof(ANDAddressStruct); + vba = addrStruct->dwVpn; + vpn = vba / mcxt.dev.lbas_per_page; + _convertVpnToBankBlockPage(vpn, &bank, &block, &page_offset); + cau = ppnMiscGetCAUFromBank(&mcxt.dev, bank); + addrStruct->dwPpn = ppnMiscConvertToPPNPageAddress(&mcxt.dev, cau, block, page_offset, FALSE32); + addrStruct->dwCS = (UInt32)ppnMiscGetCEFromBank(&mcxt.dev, bank); + addrStruct->dwColumn = vba % mcxt.dev.lbas_per_page; + addrStruct->dwCau = cau; + boolRes = TRUE32; + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_BURNIN_CODE: + { + UInt32 code = (UInt32)mcxt.stat.ddwBurnInCode; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &code, sizeof(code)); + break; + } +#endif //AND_COLLECT_STATISTICS + + case AND_STRUCT_VFL_LAST_ERROR: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &gstLastFailure, sizeof(gstLastFailure)); + break; + } + + case AND_STRUCT_VFL_VFLMETA: + { + const UInt32 chip_enable_idx = dwStructType & AND_STRUCT_CS_MASK; + + if ((NULL == pvoidStructBuffer) && + (NULL != pdwStructSize)) + { + *pdwStructSize = sizeof(PPNVFLMetaDataExport); + boolRes = TRUE32; + } + else if ((NULL != pvoidStructBuffer) && + (NULL != pdwStructSize) && + (*pdwStructSize >= sizeof(PPNVFLMetaDataExport)) && + (chip_enable_idx < (mcxt.dev.num_channels * mcxt.dev.ces_per_channel))) + { + PPNVFLMetaDataExport *exported_meta = (PPNVFLMetaDataExport*)pvoidStructBuffer; + UInt16 bank; + WMR_MEMSET(pvoidStructBuffer, 0xFF, sizeof(PPNVFLMetaDataExport)); + exported_meta->version = PPNVFL_EXPORT_META_VERSION; + exported_meta->dev_info.num_of_channels = mcxt.dev.num_channels; + exported_meta->dev_info.ces_per_channel = mcxt.dev.ces_per_channel; + exported_meta->dev_info.caus_per_ce = mcxt.dev.caus_per_ce; + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + exported_meta->per_bank_data[bank].geometry.chip_enable = ppnMiscGetCEFromBank(&mcxt.dev, bank); + exported_meta->per_bank_data[bank].geometry.chip_enable_idx = ppnMiscGetCEIdxFromBank(&mcxt.dev, + bank); + exported_meta->per_bank_data[bank].geometry.channel = ppnMiscGetChannelFromBank(&mcxt.dev, bank); + exported_meta->per_bank_data[bank].geometry.cau = ppnMiscGetCAUFromBank(&mcxt.dev, bank); + exported_meta->per_bank_data[bank].num_special_blocks = mcxt.r_banks[bank].num_special_blocks; + exported_meta->per_bank_data[bank].num_grown_bad = mcxt.r_banks[bank].num_grown_bad; + exported_meta->per_bank_data[bank].num_initial_bad = mcxt.r_banks[bank].num_initial_bad; + exported_meta->per_bank_data[bank].num_available = mcxt.r_banks[bank].num_available; + exported_meta->per_bank_data[bank].num_cxt = mcxt.r_banks[bank].num_cxt; + exported_meta->per_bank_data[bank].num_p2v = mcxt.r_banks[bank].num_p2v; + } + *pdwStructSize = sizeof(PPNVFLMetaDataExport); + boolRes = TRUE32; + } + break; + } + +#if AND_SUPPORT_BLOCK_BORROWING + case AND_STRUCT_VFL_FIND_BORROWED_BLOCKS: + { + if (NULL != pdwStructSize) + { + BorrowBlockAddress *pastrBlocks = (BorrowBlockAddress*)pvoidStructBuffer; + SpecialBlockAddress special_blocks[AND_MAX_SPECIAL_BLOCKS]; + UInt16 i, count, max_count, types[AND_MAX_SPECIAL_BLOCKS]; + + + mcxt.fpart->MapSpecialBlocks(special_blocks, types, &count); + max_count = WMR_MIN(count, (*pdwStructSize / sizeof(pastrBlocks[0]))); + WMR_PRINT(ALWAYS, "Checking borrowed blocks - count: %d max_count: %d\n", count, max_count); + for (i = 0; i < max_count; i++) + { + UInt16 channel; + UInt16 ceIdx; + UInt16 cau; + UInt32 ppn_page; + channel = ppnMiscGetChannelFromBank(&mcxt.dev, special_blocks[i].bank); + ceIdx = ppnMiscGetCEIdxFromBank(&mcxt.dev, special_blocks[i].bank); + pastrBlocks[i].dwPhysicalCE = channel + ceIdx * mcxt.dev.num_channels; + cau = ppnMiscGetCAUFromBank(&mcxt.dev, special_blocks[i].bank); + ppn_page = ppnMiscConvertToPPNPageAddress(&mcxt.dev, cau, special_blocks[i].block, 0, FALSE32); + pastrBlocks[i].dwPhysicalBlock = (ppn_page >> mcxt.dev.bits_per_page_addr); + pastrBlocks[i].wType = types[i]; + } + *pdwStructSize = max_count * sizeof(pastrBlocks[0]); + boolRes = TRUE32; + } + break; + } +#endif + + default: + WMR_PANIC("_ppnvflGetStruct not handling dwStructType 0x%08x", dwStructType); + WMR_PRINT(VFLWARN, "_ppnvflGetStruct 0x%X is not identified as VFL data struct identifier!\n", dwStructType); + boolRes = FALSE32; + } + return boolRes; +} + +/* + * Name: _ppnvflGetDeviceInfo + * Description: implements GetDeviceInfo function for the vfl I/F + * Input: type + * Return value: info per the requested information type + */ +static UInt32 +_ppnvflGetDeviceInfo + (UInt32 dwParamType) +{ + UInt32 dwRetVal = 0xFFFFFFFF; + + switch (dwParamType) + { + case AND_DEVINFO_PAGES_PER_SUBLK: + { + dwRetVal = (UInt32)mcxt.dev.pages_per_sublk; + break; + } + + case AND_DEVINFO_BYTES_PER_PAGE: + { + dwRetVal = (UInt32)mcxt.dev.main_bytes_per_page; + break; + } + + case AND_DEVINFO_NUM_OF_BANKS: + { + dwRetVal = (UInt32)mcxt.dev.num_of_banks; + break; + } + + case AND_DEVINFO_NUM_OF_USER_SUBLK: + { + dwRetVal = (UInt32)mcxt.gen.num_of_ftl_sublk; + break; + } + + case AND_DEVINFO_FTL_TYPE: + { + dwRetVal = (UInt32)mcxt.gen.ftl_type; + break; + } + + case AND_DEVINFO_FIL_LBAS_PER_PAGE: + { + dwRetVal = (UInt32)mcxt.dev.lbas_per_page; + break; + } + + case AND_DEVINFO_FIL_META_VALID_BYTES: + { + dwRetVal = (UInt32)mcxt.dev.lba_meta_bytes_valid; + break; + } + + case AND_DEVINFO_FIL_META_BUFFER_BYTES: + { + dwRetVal = (UInt32)mcxt.dev.lba_meta_bytes_buffer; + break; + } + + case AND_DEVINFO_VFL_AVAILABLE_VBAS: + { + UInt32 num_of_vbas = 0; + UInt8 bank; + for (bank = 0; bank < mcxt.dev.num_of_banks; bank++) + { + num_of_vbas += (mcxt.r_banks[bank].num_p2v * mcxt.dev.lbas_per_page * + mcxt.dev.pages_per_block_mlc); + } + dwRetVal = num_of_vbas; + break; + } + + case AND_DEVINFO_BLOCKS_PER_CAU: + { + dwRetVal = (UInt32)mcxt.dev.blocks_per_cau; + break; + } + + // pass-through to FIL + case AND_DEVINFO_STREAM_BUFFER_MAX: + { + dwRetVal = mcxt.fil->GetDeviceInfo(dwParamType); + break; + } + + default: + { + WMR_PANIC("dwParamType not supported (0x%08x)\n", dwParamType); + break; + } + } + return dwRetVal; +} + +static VFLReadStatusType +_ppnvflReadMultipleVbas + (UInt32 vba, + UInt16 count, + UInt8 *data, + UInt8 *meta, + BOOL32 bDisableWhitening, + BOOL32 bMarkECCForScrub) +{ + UInt16 vba_idx; + VFLReadStatusType op_status = 0; + + WMR_PRINT(LOG, "ReadMultipleVbas(0x%08X, 0x%04X)\n", vba, count); + +#ifdef AND_COLLECT_STATISTICS + mcxt.stat.ddwVbasReadCnt += count; + mcxt.stat.ddwSequentialReadCallCnt++; +#endif + + for (vba_idx = 0; vba_idx < count; ) + { + UInt16 vbas_added = count - vba_idx; + UInt8 *curr_data = &data[vba_idx * mcxt.dev.main_bytes_per_lba]; + UInt8 *curr_meta = &meta[vba_idx * mcxt.dev.lba_meta_bytes_buffer]; + UInt32 curr_vba = vba + vba_idx; + + _fillSequentialAddressesToCommandStructure(mcxt.commands, curr_vba, &vbas_added, + PPN_COMMAND_READ, curr_data, curr_meta, + (bMarkECCForScrub ? 0 : PPN_OPTIONS_IGNORE_BAD_BLOCK), + InitFillPack); + + mcxt.fil->PerformCommandList(mcxt.commands, mcxt.dev.num_channels); + + _analyzeSpansReadStatuses(0, vbas_added, &op_status, bMarkECCForScrub, NULL); + vba_idx += vbas_added; + } + + return op_status; +} + +#ifndef AND_READONLY + +/* + * Name: _ppnvflProgramMultipleVbas + * Description: implements multi page program for the vfl I/F + * Input: start virtual page address, number of page to program, + * data buffer, meta buffer + * ignored: replace block on fail, whitening + * Return value: TRUE32 if successful, otherwise FALSE32 + */ +static BOOL32 +_ppnvflProgramMultipleVbas + (UInt32 vba, + UInt16 count, + UInt8 * data, + UInt8 * meta, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening) +{ + UInt16 channel, i; + BOOL32 res = TRUE32, last_failure_updated = FALSE32; + UInt16 vba_idx; + UInt16 phyCE; + + WMR_TRACE_4(ProgramMultipleVbas, START, vba, count, boolReplaceBlockOnFail, bDisableWhitening); + + WMR_ASSERT(!(vba % mcxt.dev.lbas_per_page)); + WMR_ASSERT(!(count % mcxt.dev.lbas_per_page)); + WMR_ASSERT(!mcxt.r_gen.active); + mcxt.r_gen.active = TRUE32; + + WMR_PRINT(LOG, "ProgramMultipleVbas(0x%08X, 0x%04X)\n", vba, count); +#ifdef AND_COLLECT_STATISTICS + mcxt.stat.ddwVbasProgrammedCnt += count; + mcxt.stat.ddwSequentialProgramCallCnt++; +#endif + + for (vba_idx = 0; vba_idx < count && res; ) + { + UInt16 vbas_added = count - vba_idx; + UInt8 *curr_meta = &meta[vba_idx * mcxt.dev.lba_meta_bytes_buffer]; + + _fillSequentialAddressesToCommandStructure(mcxt.commands, (vba + vba_idx), + &vbas_added, PPN_COMMAND_PROGRAM, + &data[vba_idx * mcxt.dev.main_bytes_per_lba], + curr_meta, + PPN_NO_OPTIONS, InitFillPack); + mcxt.fil->PerformCommandList(mcxt.commands, mcxt.dev.num_channels); + + // handle program errors + for (channel = 0; channel < mcxt.dev.num_channels; channel++) + { + PPNCommandStruct *command = mcxt.commands[channel]; + + for (i = 0; ((command->page_status_summary & PPN_PROGRAM_STATUS_FAIL) && + (i < command->num_pages)); i++) + { + if (command->entry[i].status & PPN_PROGRAM_STATUS_FAIL) + { + UInt16 bank, block, page_offset; + BOOL32 slc; + + ppnMiscConvertPhysicalAddressToBankBlockPage(&mcxt.dev, channel, + command->entry[i].ceIdx, + command->entry[i].addr.row, &bank, &block, + &page_offset, &slc); + + phyCE = ppnMiscGetCEFromBank(&mcxt.dev,bank); + if (last_failure_updated == FALSE32) + { + _ReportFailure(VFLFailWrite, phyCE, command->entry[i].addr.row); + last_failure_updated = TRUE32; + } + + if (boolReplaceBlockOnFail == TRUE32) + { + WMR_PRINT(QUAL, "program fail -> retire " + "vba:0x%X bank:0x%X, block:0x%X page_offset:0x%X " + "phy CE: %d, row addr: 0x%X\n", + vba, bank, block, page_offset, phyCE, command->entry[i].addr.row); + _markBlockForRetirement(bank, block); + } + else + { + WMR_PRINT(QUAL, "program fail -> do NOT retire " + "vba:0x%X bank:0x%X, block:0x%X page_offset:0x%X\n" + "phy CE: %d, row addr: 0x%X\n", + vba, bank, block, page_offset, phyCE, command->entry[i].addr.row); + } + res = FALSE32; + } + } + } + vba_idx += vbas_added; + } + + WMR_TRACE_1(ProgramMultipleVbas, END, res); + + mcxt.r_gen.active = FALSE32; + return res; +} + +/* + * Name: _ppnvflErase + * Description: implements erase single virtual block for the vfl I/F + * Input: virtual block address, replace block on fail + * Return value: ANDErrorCodeOk if successful, otherwise ANDErrorWriteFailureErr + */ +static Int32 +_ppnvflErase + (UInt16 wVbn, + BOOL32 bReplaceOnFail) +{ + UInt32 vba; + UInt16 bank, channel, vbas_to_erase; + BOOL32 last_failure_updated = FALSE32; + UInt16 phyCE; + ANDStatus status = ANDErrorCodeOk; + + WMR_PRINT(LOG, "Erase (0x%04X)\n", wVbn); + + WMR_ASSERT(!mcxt.r_gen.active); + mcxt.r_gen.active = TRUE32; + +#ifdef AND_COLLECT_STATISTICS + mcxt.stat.ddwVBlocksErasedCnt++; + mcxt.stat.ddwEraseCallCnt++; +#endif + + for (bank = 0; (bank < mcxt.dev.num_of_banks) && (mcxt.blocks_to_scrub_count != 0); bank++) + { + if (_isBlockToScrubInBitmap(bank, wVbn)) + { + if (!_removeBadBlock(bank, wVbn)) + { + status = ANDErrorWriteFailureErr; + goto exit; + } + // invalidate the vbn cache + mcxt.r_gen.cached_vbn = 0xFFFF; + } + } + + vbas_to_erase = _countVbnPhysicalBlocks(wVbn) * mcxt.dev.lbas_per_page; + vba = wVbn * mcxt.dev.pages_per_sublk * mcxt.dev.lbas_per_page; + _fillSequentialAddressesToCommandStructure(mcxt.commands, vba, &vbas_to_erase, + PPN_COMMAND_ERASE, NULL, NULL, PPN_NO_OPTIONS, InitFillPack); + mcxt.fil->PerformCommandList(mcxt.commands, mcxt.dev.num_channels); + + for (channel = 0; channel < mcxt.dev.num_channels; channel++) + { + PPNCommandStruct *command = mcxt.commands[channel]; + UInt16 page_idx; + + for (page_idx = 0; ((command->page_status_summary & PPN_ERASE_STATUS_RETIRE) && + (page_idx < command->num_pages)); page_idx++) + { + // invalidate the vbn cache + mcxt.r_gen.cached_vbn = PPNVFL_INVALID_BANK_BLOCK; + + if (command->entry[page_idx].status & PPN_ERASE_STATUS_RETIRE) + { + UInt16 block, page_offset; + BOOL32 slc; + + ppnMiscConvertPhysicalAddressToBankBlockPage(&mcxt.dev, channel, + command->entry[page_idx].ceIdx, + command->entry[page_idx].addr.row, &bank, &block, + &page_offset, + &slc); + + WMR_PRINT(QUAL, "failed to erase a block - channel: 0x%02X, ceIdx:0x%02X, " + "page_addr: 0x%08X, bank: 0x%02X, block: 0x%04X, slc:%01d\n", + channel, command->entry[page_idx].ceIdx, command->entry[page_idx].addr.row, + bank, block, slc); + + if (last_failure_updated == FALSE32) + { + phyCE = ppnMiscGetCEFromBank(&mcxt.dev,bank); + _ReportFailure(VFLFailErase, phyCE, + command->entry[page_idx].addr.row); + last_failure_updated = TRUE32; + } + + // replace a bad block if the caller asked us to do so + if (bReplaceOnFail == TRUE32) + { + if (!_removeBadBlock(bank, block)) + { + WMR_PRINT(ERROR, "error removing a block\n"); + status = ANDErrorWriteFailureErr; + goto exit; + } + } + else + { + status = ANDErrorWriteFailureErr; + goto exit; + } + } + } + } + +exit: + mcxt.r_gen.active = FALSE32; + return status; +} + +#endif // AND_READONLY + +/* + * Name: _ppnvflSetStruct + * Description: implements SetStruct for the vfl I/F + * Input: type, buffer, buffer size + * Return value: TRUE32 if successful, otherwise FALSE32 + */ +static BOOL32 +_ppnvflSetStruct + (UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 dwStructSize) +{ + BOOL32 result = FALSE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { +#ifndef AND_READONLY + case AND_STRUCT_VFL_FTLTYPE: + { + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + mcxt.gen.ftl_type = (*((UInt32*)pvoidStructBuffer)); + + result = _programCxtLastPage(buf, TRUE32); + BUF_Release(buf); + } + break; + + case AND_STRUCT_VFL_EXPORTED_LBA_NO: + { + result = _setNumOfExportedLbas(*((UInt32*)pvoidStructBuffer)); + } + break; + + case AND_STRUCT_VFL_EXPORTED_L2V_POOL: + { + result = _setL2vPoolSize(*((UInt32*)pvoidStructBuffer)); + } + break; + + case AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS: + { + result = _setNumOfFTLSuBlks(*((UInt16*)pvoidStructBuffer)); + } + break; +#endif // AND_READONLY + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_BURNIN_CODE: + { + if (NULL != pvoidStructBuffer) + { + mcxt.stat.ddwBurnInCode = *((UInt32*)pvoidStructBuffer); + result = TRUE32; + } + } + break; + + case AND_STRUCT_VFL_STATISTICS: + { + if ((NULL != pvoidStructBuffer)) + { + WMR_MEMCPY(&mcxt.stat, pvoidStructBuffer, WMR_MIN(sizeof(SVFLStatistics), dwStructSize)); + result = TRUE32; + } + } + break; + + case AND_STRUCT_VFL_FILSTATISTICS: + { + result = FIL_SetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, dwStructSize); + } + break; +#endif //AND_COLLECT_STATISTICS + + default: + { + WMR_PRINT(ERROR, "_ppnvflSetStruct 0x%X is not identified is VFL data struct identifier!\n", dwStructType); + } + } + return result; +} + +/* + * Name: _ppnvflClose + * Description: implements close for the vfl I/F + * Input: + * Return value: none + */ +static void +_ppnvflClose + (void) +{ + if (mcxt.v2p_bitmap) + { + WMR_FREE(mcxt.v2p_bitmap, mcxt.v2p_bitmap_size); + mcxt.v2p_bitmap = NULL; + } + + if (mcxt.v2p_scrub_bitmap) + { + WMR_FREE(mcxt.v2p_scrub_bitmap, mcxt.v2p_bitmap_size); + mcxt.v2p_scrub_bitmap = NULL; + } + + if (mcxt.vfl_map_pages[0]) + { + WMR_FREE(mcxt.vfl_map_pages[0], (sizeof(UInt16) * mcxt.dev.num_of_banks * mcxt.r_gen.pages_per_block_mapping)); + mcxt.vfl_map_pages[0] = NULL; + } + + if (mcxt.vfl_map_pages) + { + WMR_FREE(mcxt.vfl_map_pages, (sizeof(UInt16*) * mcxt.dev.num_of_banks)); + mcxt.vfl_map_pages = NULL; + } + + if (mcxt.r_banks) + { + WMR_FREE(mcxt.r_banks, (sizeof(PPNVFL_BankRAMCxt) * mcxt.dev.num_of_banks)); + mcxt.r_banks = NULL; + } + + if (mcxt.reorder) + { + WMR_FREE(mcxt.reorder, sizeof(PPNReorderStruct)); + mcxt.reorder = NULL; + } + + if (mcxt.initialized) + { + WMR_BufZone_Free(&mcxt.bufzone); + } + WMR_MEMSET(&mcxt, 0, sizeof(PPNVFL_MainCxt)); +} + +#ifndef AND_READONLY +#if (defined(AND_SUPPORT_BLOCK_BORROWING) && AND_SUPPORT_BLOCK_BORROWING) +static BOOL32 +_ppnvflBorrowSpareBlock + (UInt32 *pdwPhysicalCE, + UInt32 *pdwPhysicalBlock, + UInt16 wType) +{ + BOOL32 res; + SpecialBlockAddress special_block; + + res = _ppnvflAllocateSpecialBlock(&special_block, wType); + if (res) + { + UInt16 channel; + UInt16 ceIdx; + UInt16 cau; + UInt32 ppn_page; + channel = ppnMiscGetChannelFromBank(&mcxt.dev, special_block.bank); + ceIdx = ppnMiscGetCEIdxFromBank(&mcxt.dev, special_block.bank); + *pdwPhysicalCE = channel + ceIdx * mcxt.dev.num_channels; + cau = ppnMiscGetCAUFromBank(&mcxt.dev, special_block.bank); + ppn_page = ppnMiscConvertToPPNPageAddress(&mcxt.dev, cau, special_block.block, 0, FALSE32); + *pdwPhysicalBlock = (ppn_page >> mcxt.dev.bits_per_page_addr); + } + return res; +} +#endif // AND_SUPPORT_BLOCK_BORROWING + +static BOOL32 +_ppnvflMarkBlockAsGrownBad + (SpecialBlockAddress *block) +{ + P2UsageType block_usage; + BOOL32 result; + + block_usage = PPNVFL_TYPE_GROWN_BB; + mcxt.r_banks[block->bank].num_special_blocks--; + mcxt.r_banks[block->bank].num_grown_bad++; + result = _setBlockUsageInVFLCxt(block->bank, block->block, block_usage); + + if (result) + { + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + + result = _programCxtLastPage(buf, TRUE32); + BUF_Release(buf); + } + + return result; +} +#endif // AND_READONLY + +static UInt16 +_ppnvflGetVbasPerVb + (UInt16 wVbn) +{ + return _countVbnPhysicalBlocks(wVbn) * mcxt.dev.pages_per_block_mlc * mcxt.dev.lbas_per_page; +} + +static void +_ppnvflReadSpansInit + (VFL_ReadSpans_t *s, + VFL_ReadSpansCB_t cb, + UInt32 cbOpt, + BOOL32 bDisableWhitening, + BOOL32 bMarkECCForScrub) +{ +#ifdef AND_COLLECT_STATISTICS + mcxt.stat.ddwSpansReadInitCallCnt++; +#endif + + WMR_ASSERT(!mcxt.r_gen.active); + + s->bDisableWhitening = bDisableWhitening; + s->bMarkECCForScrub = bMarkECCForScrub; + s->len = 0; + s->cb = cb; + s->cbOpt = cbOpt; + s->op_status = 0; +} + +static VFLReadStatusType +_ppnvflReadSpans + (VFL_ReadSpans_t *s) +{ + UInt16 sp_idx; + UInt16 vba_index_start = 0, vba_index_count = 0; + + WMR_ASSERT(!mcxt.r_gen.active); + mcxt.r_gen.active = TRUE32; + +#ifdef AND_COLLECT_STATISTICS + mcxt.stat.ddwSpansReadExecCallCnt++; +#endif + + for (sp_idx = 0; sp_idx < s->len; sp_idx++) + { + UInt16 vba_idx; + const UInt32 vba = s->vba[sp_idx]; + const UInt16 count = s->count[sp_idx]; + UInt8* data = s->data[sp_idx]; + UInt8* meta = s->meta[sp_idx]; +#ifdef AND_COLLECT_STATISTICS + mcxt.stat.ddwVbasReadCnt += count; +#endif + + WMR_ASSERT((data != NULL) && (meta != NULL)); + WMR_PRINT(LOG, "ReadSpans[%02d](0x%08X, 0x%04X)\n", sp_idx, vba, count); + + for (vba_idx = 0; vba_idx < s->count[sp_idx]; ) + { + UInt16 vbas_added = count - vba_idx; + UInt8 *curr_data = &data[vba_idx * mcxt.dev.main_bytes_per_lba]; + UInt8 *curr_meta = &meta[vba_idx * mcxt.dev.lba_meta_bytes_buffer]; + UInt32 curr_vba = vba + vba_idx; + + if (vba_index_count == 0) + { + _fillSequentialAddressesToCommandStructure(mcxt.commands, curr_vba, &vbas_added, + PPN_COMMAND_READ, curr_data, curr_meta, + (s->bMarkECCForScrub ? 0 : PPN_OPTIONS_IGNORE_BAD_BLOCK), + InitAndFill); + } + else + { + _fillSequentialAddressesToCommandStructure(mcxt.commands, curr_vba, &vbas_added, + PPN_COMMAND_READ, curr_data, curr_meta, + (s->bMarkECCForScrub ? 0 : PPN_OPTIONS_IGNORE_BAD_BLOCK), + FillOnly); + } + + vba_idx += vbas_added; + if (0 != vbas_added) + { + vba_index_count += vbas_added; + } + else + { + _fillSequentialAddressesToCommandStructure(mcxt.commands, 0, NULL, + PPN_COMMAND_NONE, NULL, NULL, + (s->bMarkECCForScrub ? 0 : PPN_OPTIONS_IGNORE_BAD_BLOCK), + PackOnly); + mcxt.fil->PerformCommandList(mcxt.commands, mcxt.dev.num_channels); + _analyzeSpansReadStatuses(vba_index_start, vba_index_count, &s->op_status, + s->bMarkECCForScrub, s); + vba_index_start += vba_index_count; + vba_index_count = 0; + } + } + } + + if (vba_index_count != 0) + { + _fillSequentialAddressesToCommandStructure(mcxt.commands, 0, NULL, + PPN_COMMAND_NONE, NULL, NULL, + (s->bMarkECCForScrub ? 0 : PPN_OPTIONS_IGNORE_BAD_BLOCK), + PackOnly); + mcxt.fil->PerformCommandList(mcxt.commands, mcxt.dev.num_channels); + _analyzeSpansReadStatuses(vba_index_start, vba_index_count, &s->op_status, s->bMarkECCForScrub, s); + } + + mcxt.r_gen.active = FALSE32; + return s->op_status; +} + +static void +_ppnvflReadSpansAdd + (VFL_ReadSpans_t *s, + UInt32 vba, + UInt32 count, + UInt8 *data, + UInt8 *meta) +{ + WMR_PRINT(LOG, "ReadSpansAdd (0x%08X, 0x%04X)\n", vba, count); + WMR_ASSERT(vba < (mcxt.dev.pages_per_sublk * mcxt.dev.blocks_per_cau * mcxt.dev.lbas_per_page)); + WMR_ASSERT(!mcxt.r_gen.active); + +#ifdef AND_COLLECT_STATISTICS + mcxt.stat.ddwSpansReadAddCallCnt++; +#endif + + if (s->len >= VFL_SPANS_MAX) + { + _ppnvflReadSpans(s); + s->len = 0; + } + + WMR_ASSERT((data != NULL) && (meta != NULL)); + + s->vba[s->len] = vba; + s->count[s->len] = count; + s->data[s->len] = data; + s->meta[s->len] = meta; + s->len++; +} + +/* vfl I/F implementation - end */ + +static UInt32 +_ppnvflGetMinorVersion + (void) +{ + return kPPNVFLMinorVersion; +} + +#if WMR_EFI +// Page APIs, implemented for EFI/Bonfire +static BOOL32 +_ppnvflWriteMultiplePagesInVb + (UInt32 dwVpn, + UInt16 wNumPagesToWrite, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening) +{ + UInt32 vba = dwVpn * mcxt.dev.lbas_per_page; + UInt32 vbaCount = wNumPagesToWrite * mcxt.dev.lbas_per_page; + + return _ppnvflProgramMultipleVbas(vba, vbaCount, pbaData, pbaSpare, boolReplaceBlockOnFail, + bDisableWhitening); +} +#endif // WMR_EFI + +#if WMR_EFI +/* + * Name: _analyzeMultiScatteredReadStatuses + * Description: this function analyzes the read operation statuses (used for multipage read) + * Input: number of pages read, mark for scrub + * Output: need refresh flag, operation result flag, clean flag + * Return value: none + */ +static UInt32 +_analyzeMultiScatteredReadStatuses + (UInt32 *result_flags, + UInt16 bank) +{ + BOOL32 last_failure_updated = FALSE32; + UInt32 current_result = 0; + UInt32 read_status = VFL_READ_STATUS_UNIDENTIFIED; + + PPNStatusType current_status = mcxt.single_command->entry[0].status; + UInt16 phyCE; + + switch (current_status) + { + case (PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_VALID | PPN_READ_STATUS_REFRESH): + case (PPN_READ_STATUS_VALID | PPN_READ_STATUS_RETIRE): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_RETIRE | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_CLEAN | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_GEB | PPN_READ_STATUS_VALID): + break; + + default: + current_result |= VFL_READ_STATUS_UNIDENTIFIED; + break; + } + if (!(current_result & VFL_READ_STATUS_UNIDENTIFIED)) + { + if (current_status & PPN_READ_STATUS_INVALID_DATA && + (!(current_status & PPN_READ_STATUS_CLEAN))) + { + current_result |= VFL_READ_STATUS_UECC; + } + if (current_status & PPN_READ_STATUS_CLEAN) + { + current_result |= VFL_READ_STATUS_CLEAN; + read_status = VFL_READ_STATUS_CLEAN; + } + if (current_status & PPN_READ_STATUS_REFRESH) + { + current_result |= VFL_READ_STATUS_REFRESH; + } + if (current_status & PPN_READ_STATUS_RETIRE) + { + current_result |= VFL_READ_STATUS_RETIRE; + } + if (!(current_status & PPN_READ_STATUS_INVALID_DATA)) + { + current_result |= VFL_READ_STATUS_VALID_DATA; + read_status = VFL_READ_STATUS_VALID_DATA; + } + } + *result_flags |= current_result; + if ((!last_failure_updated) && (current_result & VFL_READ_STATUS_UECC)) + { + last_failure_updated = TRUE32; + phyCE = ppnMiscGetCEFromBank(&mcxt.dev,bank); + _ReportFailure(VFLFailUECC, phyCE, mcxt.single_command->entry[0].addr.row); + read_status = VFL_READ_STATUS_UECC; + } + else if (current_result & VFL_READ_STATUS_REFRESH) + { + phyCE = ppnMiscGetCEFromBank(&mcxt.dev,bank); + _ReportFailure(VFLFailRefresh, phyCE, mcxt.single_command->entry[0].addr.row); + } + return read_status; +} +#endif // WMR_EFI + +#if WMR_EFI +// Page APIs, implemented for EFI/Bonfire +static BOOL32 +_ppnvflReadScatteredPagesInVb + (UInt32 * padwVpn, + UInt16 wNumPagesToRead, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening, + Int32 *actualStatus) +{ + UInt16 vpn_idx; + BOOL32 res = FALSE32; + const UInt8 num_sectors = (mcxt.dev.main_bytes_per_page) / 1024; //Number of kilobyte sectors + UInt32 op_status = 0; + UInt32 read_status; + + WMR_PRINT(LOG, "ReadScatteredPagesInVb(0x%04X)\n", wNumPagesToRead); + + // mark all the sectors as not valid + if (pabSectorStats != NULL) + { + WMR_MEMSET(pabSectorStats, 0xFD, (num_sectors * wNumPagesToRead)); + } + + for (vpn_idx = 0; vpn_idx < wNumPagesToRead; vpn_idx++) + { + UInt32 vpn = padwVpn[vpn_idx]; + UInt16 bank, block, page_offset; + UInt8 *data = &pbaData[vpn_idx * mcxt.dev.main_bytes_per_page]; + UInt8 *meta = &pbaSpare[vpn_idx * mcxt.dev.lba_meta_bytes_valid * mcxt.dev.lbas_per_page]; + UInt8 *stats; + UInt8 *stats_meta = NULL; + UInt8 *stats_data = NULL; + + // convert to physical address + _convertVpnToBankBlockPage(vpn, &bank, &block, &page_offset); + + if (pabSectorStats != NULL) + { + ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_READ, + PPN_OPTIONS_REPORT_HEALTH, + bank, block, page_offset, FALSE32, data, meta); + // use the right offset in the stats buffer (leave swiss holes where relevant) + stats = &pabSectorStats[vpn_idx * num_sectors]; + read_status = _analyzeMultiScatteredReadStatuses(&op_status, bank); + + if(stats_copy_from_data) + { + stats_data = stats + stats_offset_from_data; + } + if(stats_copy_from_meta) + { + stats_meta = stats + stats_offset_from_meta; + } + + if (read_status & VFL_READ_STATUS_VALID_DATA) + { + if(stats_data) + { + WMR_MEMCPY(stats_data, data, stats_copy_from_data); + } + if(stats_meta) + { + WMR_MEMCPY(stats_meta, meta, stats_copy_from_meta); + } + } + else if (read_status & VFL_READ_STATUS_CLEAN) + { + if(stats_data) + { + WMR_MEMSET(stats_data, 0xFE, stats_copy_from_data); + } + if(stats_meta) + { + WMR_MEMSET(stats_meta, 0xFE, stats_copy_from_meta); + } + } + else if (read_status & VFL_READ_STATUS_UECC) + { + if(stats_data) + { + WMR_MEMSET(stats_data, 0xFF, stats_copy_from_data); + } + if(stats_meta) + { + WMR_MEMSET(stats_meta, 0xFF, stats_copy_from_meta); + } + } + } + else + { + ppnMiscSingleOperation(&mcxt.dev, mcxt.single_command, PPN_COMMAND_READ, + PPN_NO_OPTIONS, + bank, block, page_offset, FALSE32, data, meta); + read_status = _analyzeMultiScatteredReadStatuses(&op_status, bank); + } + } + + if (actualStatus != NULL) + { + if (op_status & VFL_READ_STATUS_UNIDENTIFIED) + { + WMR_PRINT(ERROR, "op_status 0x%02x\n", op_status); + *actualStatus = ANDErrorCodeHwErr; + } + else if((op_status & VFL_READ_STATUS_CLEAN) && (!(op_status & VFL_READ_STATUS_VALID_DATA))&& (!(op_status & VFL_READ_STATUS_UECC))) + { + *actualStatus = ANDErrorCodeCleanOk; + res = TRUE32; + } + else if ((op_status & VFL_READ_STATUS_UECC) || + ((op_status & VFL_READ_STATUS_CLEAN) && (!(op_status & VFL_READ_STATUS_VALID_DATA)))) + { + *actualStatus = ANDErrorCodeUserDataErr; + } + else if (op_status & VFL_READ_STATUS_VALID_DATA) + { + *actualStatus = ANDErrorCodeOk; + res = TRUE32; + } + else + { + // don't panic, per rdar://8234566 + WMR_PRINT(ERROR, "op_status 0x%02x\n", op_status); + *actualStatus = ANDErrorCodeHwErr; + } + } + if (pboolNeedRefresh != NULL) + { + if (op_status & (VFL_READ_STATUS_REFRESH | VFL_READ_STATUS_RETIRE | VFL_READ_STATUS_UECC)) + { + *pboolNeedRefresh = TRUE32; + } + else + { + *pboolNeedRefresh = FALSE32; + } + } + + return res; +} +#endif // WMR_EFI + +void +SwissVFL_Register + (VFLFunctions * pVFL_Functions) +{ + WMR_MEMSET(pVFL_Functions, 0, sizeof(VFLFunctions)); +#ifndef AND_READONLY + pVFL_Functions->Format = _ppnvflFormat; + pVFL_Functions->Erase = _ppnvflErase; +#if (defined(AND_SUPPORT_BLOCK_BORROWING) && AND_SUPPORT_BLOCK_BORROWING) + pVFL_Functions->BorrowSpareBlock = _ppnvflBorrowSpareBlock; +#endif // AND_SUPPORT_BLOCK_BORROWING + pVFL_Functions->ProgramMultipleVbas = _ppnvflProgramMultipleVbas; +#endif // ! AND_READONLY + pVFL_Functions->Init = _ppnvflInit; + pVFL_Functions->Open = _ppnvflOpen; + pVFL_Functions->Close = _ppnvflClose; + pVFL_Functions->ReadMultipleVbas = _ppnvflReadMultipleVbas; + // pVFL_Functions->GetAddress = VFL_GetAddress; + pVFL_Functions->GetStruct = _ppnvflGetStruct; + pVFL_Functions->SetStruct = _ppnvflSetStruct; + pVFL_Functions->GetDeviceInfo = _ppnvflGetDeviceInfo; +#ifndef AND_READONLY + pVFL_Functions->AllocateSpecialBlock = _ppnvflAllocateSpecialBlock; + pVFL_Functions->MarkBlockAsGrownBad = _ppnvflMarkBlockAsGrownBad; +#endif + pVFL_Functions->GetMinorVersion = _ppnvflGetMinorVersion; + pVFL_Functions->GetVbasPerVb = _ppnvflGetVbasPerVb; + pVFL_Functions->ReadSpansInit = _ppnvflReadSpansInit; + pVFL_Functions->ReadSpansAdd = _ppnvflReadSpansAdd; + pVFL_Functions->ReadSpans = _ppnvflReadSpans; + +#if WMR_EFI + // Page APIs, for EFI/Bonfire ONLY + pVFL_Functions->WriteMultiplePagesInVb = _ppnvflWriteMultiplePagesInVb; + pVFL_Functions->ReadScatteredPagesInVb = _ppnvflReadScatteredPagesInVb; +#endif +} + +static VFLFunctions _ppnvfl_functions; + +VFLFunctions * +PPN_SVFL_GetFunctions + (void) +{ + SwissVFL_Register(&_ppnvfl_functions); + return &_ppnvfl_functions; +} +/* global calls for the ppnvfl (using the declared global main vfl cxt struct - end */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl_types.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl_types.h new file mode 100644 index 0000000..e66f5cf --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/SVFL/s_vfl_types.h @@ -0,0 +1,292 @@ +#ifndef _PPNVFL_TYPES_H_ +#define _PPNVFL_TYPES_H_ + +#include "WMRConfig.h" +#include "FPart.h" +#include "VFL.h" +#include "FIL.h" +#include "PPN_FIL.h" +#include "WMRBuf.h" +#include "PPNMiscTypes.h" +#include "WMROAM.h" + +/* defines */ +#define PPNVFL_ROOM_FOR_BOOT_BLOCKS (20) +#define PPNVFL_NUM_OF_VFL_CXT_BLOCK_SETS (2) +#define PPNVFL_MAX_INFO_BLOCK_COUNT (64) +#define PPNVFL_MAX_SUPPORTED_CHANNELS (2) + +// #define AND_SB_TYPE_DRIVER_SIGNATURE (AND_SB_BIT_SPEICAL_FLAG | AND_SB_BIT_PERSISTENT_FLAG | +// andSBSetHandler(AND_SB_HANDLER_SINGLE_VERSION) | andSBSetCode(AND_SB_CODE_DRIVER_SIGNATURE)) + +#define PPNVFL_CODE_VFL_AVAILABLE (0xF0) +#define PPNVFL_CODE_VFL_INFO (0xF1) +#define PPNVFL_CODE_GROWN_BB (0xFD) +#define PPNVFL_CODE_INITIAL_BB (0xFE) + +#define PPNVFL_TYPE_AVAILABLE_MARK (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_VFL_AVAILABLE)) + +#define PPNVFL_TYPE_VFL_INFO (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_VFL_INFO)) +#define PPNVFL_TYPE_GROWN_BB (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_GROWN_BB)) +#define PPNVFL_TYPE_INITIAL_BB (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_INITIAL_BB)) + +#define PPNVFL_TYPE_VBN (0) + +#define PPNVFL_SPARE_TYPE_CXT (AND_SPARE_TYPE_REGION_VFL | 0x00) +#define PPNVFL_SPARE_TYPE_TST (AND_SPARE_TYPE_REGION_VFL | 0x01) + +#define PPNVFL_MIN_PAGE_SIZE (8192) // minimum page size in bytes + +#define PPN_V2P_MIXED_MARK (0x8000) // use bit 15 to mark a virtual block is made + // of different blocks at different CAUs (not all the same offset) + +#define PPNVFL_P2V_SCRUB_BIT (1 << 0) // use bit 0 in the p2v mapping to indicate a block should be retired + +#define BOOT_BLOCK_ALLOCATION_COUNT(m) (0 != (WMR_INIT_USE_KEEPOUT_AS_BORROW & (m)->r_gen.options) ? \ + (m)->r_gen.keepout : 0) + +#define SPECIAL_BLOCK_PRE_ALLOCATION_COUNT(m) (BOOT_BLOCK_ALLOCATION_COUNT(m) + 11) + // number of pre allocated special blocks + // 64 BFN (worst case), 1 Signature, + // 2 Unique Info, 2 Diags, 6 Spare + +#define P2SB_RESERVED_VALUE (0xFFFF) +#define P2V_RESERVED_VALUE (0x00) + +#define PPNVFL_CXT_LAST_BANKIDX (0xFF) // use this define for the index and bank of the last/summary index page +#define PPNVFL_CXT_IGNORE_BANKIDX (0xF0) // use this value to tell the read function to ignore the bank and index values +#define PPNVFL_INVALID_BANK_BLOCK (0xFFFF) // use to mark unasinged value or invliad assignment + +/* PPNVFL internal structures */ + +typedef struct +{ + UInt16 block; + UInt8 bank; + UInt8 features; // bit fields... +} VFLCxtBlockAddress; + +#define S_VFL_CXT_BLOCK_SCRUB_BIT (1 << 7) + +#define _isVFLCxtBlockMarkedScrub(_blk_addr) (_blk_addr.features & S_VFL_CXT_BLOCK_SCRUB_BIT) +#define _setVFLCxtScrubMark(_blk_addr) { _blk_addr.features |= S_VFL_CXT_BLOCK_SCRUB_BIT; } +#define _unsetVFLCxtScrubMark(_blk_addr) { _blk_addr.features &= (~S_VFL_CXT_BLOCK_SCRUB_BIT); } + +WMR_CASSERT((sizeof(VFLCxtBlockAddress) == 4), sizeof_VFLCxtBlockAddress); + +typedef UInt16 P2UsageType; + +// On NAND structures - Start + +// IMPORTANT: the following defines are used in on nand structures - be careful changing it +#define PPNVFL_MAX_SUPPORTED_BANKS (128) +#define PPNVFL_SCRUB_BLOCK_COUNT (20) + +// PPNVFL_GeneralCxt - general vfl context +typedef struct +{ + UInt32 ftl_type; // FTL identifier + UInt32 exported_lba_no; // Number of LBAs exported by a TL + UInt32 exported_l2v_pool_size; // l2v tree allocated size in bytes + UInt16 num_of_ftl_sublk; // the number of super blocks allocated for the FTL - + // default id to give all to FTL + UInt16 num_of_vfl_sublk; // the total number of available super blocks + UInt8 reserved[0xF0]; + + // start the vfl_bloock array in offset 256 + VFLCxtBlockAddress vfl_blocks[64]; // vfl blocks physical addresses +} PPNVFL_GeneralCxt; + +WMR_CASSERT((sizeof(PPNVFL_GeneralCxt) == 512), sizeof_PPNVFL_GeneralCxt); + +// vfl blocks geometry example +// in this example redundancy of 4 and depth of 2 is used. +// the vfl is always made of two sets +// numbers are [s,r,d] where s - set (out of two), r - redundancy, d - depth + +/* + + set 0: + [0,0,0][0,0,1] + [0,1,0][0,1,1] + [0,1,0][0,1,1] + [0,3,0][0,3,1] + + set 1: + [1,0,0][1,0,1] + [1,1,0][1,1,1] + [1,1,0][1,1,1] + [1,3,0][1,3,1] + + [s,r,d] is located in: + (s * vfl_blocks_redundancy * vfl_blocks_depth) + + (d * vfl_blocks_redundancy) + r + + */ + +// PPNVFL_BankCxt - per bank vfl context +typedef struct +{ + UInt16 vfl_map_pages[16]; +} PPNVFL_BankCxt; + +WMR_CASSERT((sizeof(PPNVFL_BankCxt) == 32), sizeof_PPNVFL_BankCxt); + +// PPNVFL_OnNANDCxt - a container structure (allowing space for expension) +// for general vfl and bank specific vfl data +typedef struct +{ + // generic info + PPNVFL_GeneralCxt gen; + // bank specific info + PPNVFL_BankCxt banks[PPNVFL_MAX_SUPPORTED_BANKS]; +} PPNVFL_OnNANDCxt; + +typedef struct +{ + UInt8 spareType; // spare type + UInt8 bank; // bank number of the p2v mapping + UInt8 idx; // page number of the p2v mapping + UInt8 reserved1[1]; // reserved + UInt32 cxt_age; // context age 0xFFFFFFFF --> 0x0 + UInt8 reserved2[8]; // reserved +} PPNVFL_CxtSpare; +// On NAND structures - End + +typedef struct +{ + UInt32 cxt_age; // context age 0xFFFFFFFF --> 0x0 + UInt16 pages_per_block_mapping; // how many pages are needed for all block mapping + UInt16 pbns_per_cxt_mapping_page; // how many block mappings fit in a page + UInt16 keepout; + UInt32 options; + UInt16 vfl_blocks_redundancy; // how many copies are used in parallel per one part of the vfl blocks pair + UInt16 vfl_blocks_depth; // how many blocks are used per copy + UInt16 vfl_pages_per_set; // how many pages we can write in a set (if depth is bigger than 1 this + // number is depth * slc_page_per_block) + UInt16 num_of_vfl_blocks; // number of vfl blocks + UInt16 next_cxt_block_offset; // can be 0 or 1 two copies are written in two parallel blocks + UInt16 next_cxt_page_offset; + BOOL32 need_rewrite; + UInt8 bytes_per_vbn_bitmap; + BOOL32 search_for_cxt; + + // cached mapping + UInt16 cached_vbn; + UInt16 cached_vbn_good_blocks; + UInt8 cached_banks_v2p[PPNVFL_MAX_SUPPORTED_BANKS]; + + BOOL32 active; +} PPNVFL_GeneralRAMCxt; + +typedef struct +{ + UInt16 num_special_blocks; + UInt16 num_grown_bad; + UInt16 num_initial_bad; + UInt16 num_available; + UInt16 num_cxt; + UInt16 num_p2v; +} PPNVFL_BankRAMCxt; + +#ifdef AND_COLLECT_STATISTICS +typedef struct +{ + UInt64 ddwVbasProgrammedCnt; + UInt64 ddwVbasReadCnt; + UInt64 ddwVBlocksErasedCnt; + UInt64 ddwSequentialReadCallCnt; + UInt64 ddwScatteredReadCallCnt; + UInt64 ddwSpansReadInitCallCnt; + UInt64 ddwSpansReadAddCallCnt; + UInt64 ddwSpansReadExecCallCnt; + UInt64 ddwSequentialProgramCallCnt; + UInt64 ddwEraseCallCnt; + UInt64 ddwBurnInCode; +} SVFLStatistics; + +#define SVFL_STATISTICS_DESCRIPTION { \ + "ddwVbasProgrammedCnt", \ + "ddwVbasReadCnt", \ + "ddwVBlocksErasedCnt", \ + "ddwSequentialReadCallCnt", \ + "ddwScatteredReadCallCnt", \ + "ddwSpansReadInitCallCnt", \ + "ddwSpansReadAddCallCnt", \ + "ddwSpansReadExecCallCnt", \ + "ddwSequentialProgramCallCnt", \ + "ddwEraseCallCnt", \ + "ddwBurnInCode" \ +} +#endif /* AND_COLLECT_STATISTICS */ + +typedef struct +{ + PPNVFL_GeneralRAMCxt r_gen; + PPN_DeviceInfo dev; + PPNVFL_GeneralCxt gen; + UInt16 **vfl_map_pages; + PPNVFL_BankRAMCxt *r_banks; + FPartFunctions *fpart; + LowFuncTbl *fil; +#ifdef AND_COLLECT_STATISTICS + SVFLStatistics stat; +#endif + + UInt8 *v2p_bitmap; + UInt8 *v2p_scrub_bitmap; + UInt16 blocks_to_scrub_count; + UInt32 v2p_bitmap_size; + + PPNCommandStruct *commands[PPNVFL_MAX_SUPPORTED_CHANNELS]; + PPNCommandStruct *single_command; + WMR_BufZone_t bufzone; + + UInt16 **chip_enable_table; // chip_enable_table[x][y] is the physical chip enable of + // chip enable number y in channel x + + PPNReorderStruct *reorder; + + BOOL32 initialized; +} PPNVFL_MainCxt; // hold all other pointers + +#define PPNVFL_EXPORT_META_VERSION 0x00000004 +#define PPNVFL_MAX_SUPPORTED_BANKS_EXPORT (128) // intentionally seperating the export + // define from other defines that are used + // for on-NAND structures +#if (PPNVFL_MAX_SUPPORTED_BANKS_EXPORT < PPNVFL_MAX_SUPPORTED_BANKS) +#error PPNVFL_MAX_SUPPORTED_BANKS_EXPORT is less than PPNVFL_MAX_SUPPORTED_BANKS +#endif // PPNVFL_MAX_SUPPORTED_BANKS_EXPORT < PPNVFL_MAX_SUPPORTED_BANKS + +typedef struct +{ + UInt32 version; // make sure this value chanegs if new fields are added or the structure changes + struct + { + UInt32 num_of_channels; + UInt32 ces_per_channel; + UInt32 caus_per_ce; + } dev_info; + struct + { + struct + { + UInt32 chip_enable; + UInt16 chip_enable_idx; + UInt16 channel; + UInt16 cau; + } geometry; + UInt16 num_special_blocks; + UInt16 num_grown_bad; + UInt16 num_initial_bad; + UInt16 num_available; + UInt16 num_cxt; + UInt16 num_p2v; + } per_bank_data[PPNVFL_MAX_SUPPORTED_BANKS_EXPORT]; +} PPNVFLMetaDataExport; + +#endif /* _PPNVFL_TYPES_H_ */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLInterface.c b/drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLInterface.c new file mode 100644 index 0000000..8be2757 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLInterface.c @@ -0,0 +1,4711 @@ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "PPNMiscTypes.h" +#include "PPNVFLTypes.h" + +#define kPPNVFLMinorVersion (1) + +/* print functions - for now i am keeping it old school */ +#if (defined (AND_SIMULATOR) && AND_SIMULATOR) +#define VFL_ERR_PRINT(x) WMR_PANIC x +#else +#define VFL_ERR_PRINT(x) WMR_RTL_PRINT(x) +#endif +#define VFL_WRN_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (VFL_LOG_MSG_ON) +#define VFL_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else +#define VFL_LOG_PRINT(x) +#endif +#define VFL_INF_MSG_ON (0) +#if (defined (VFL_INF_MSG_ON) && VFL_INF_MSG_ON) +#define VFL_INF_PRINT(x, y) { if (x) { WMR_RTL_PRINT(y); } } +#else +#define VFL_INF_PRINT(x, y) +#endif + +// read result flags - 32 Bit +#define PPNVFL_READ_RES_REFRESH (1 << 0) +#define PPNVFL_READ_RES_RETIRE (1 << 1) +#define PPNVFL_READ_RES_UECC (1 << 2) // UECC = invalid data TRUE and clean FALSE +#define PPNVFL_READ_RES_CLEAN (1 << 3) // UECC = invalid data TRUE and clean TRUE +#define PPNVFL_READ_RES_VALID_DATA (1 << 4) // at least one of the pages had valid data +#define PPNVFL_READ_RES_UNIDENTIFIED (1 << 5) // at least one status was something we do not expect + +#define PPNVFL_CONTEXT_BLOCK_LIMIT(dev) (((dev)->blocks_per_cau * 5) / 100) + +#define SECTOR_SIZE 1024 + +// _readPageOfASet - defines +#define RPS_STATUS_SPARE_TYPE_MISSMATCH (1 << 1) +#define RPS_STATUS_BANK_MISSMATCH (1 << 2) +#define RPS_STATUS_IDX_MISSMATCH (1 << 3) + +/* ----------- I/F commands - start ------------- */ + +#ifndef AND_READONLY +static Int32 _g_ppnvflFormat + (UInt32 dwKeepout, + UInt32 dwOptions); +static Int32 _g_ppnvflWriteSinglePage + (UInt32 nVpn, + Buffer *pBuf, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening); +static Int32 _g_ppnvflErase + (UInt16 wVbn, + BOOL32 bReplaceOnFail); +static Int32 _g_ppnvflChangeFTLCxtVbn + (UInt16 *aFTLCxtVbn); +static BOOL32 _g_ppnvflWriteMultiplePagesInVb + (UInt32 dwVpn, + UInt16 wNumPagesToWrite, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening); +#endif // ! AND_READONLY +static Int32 _g_ppnvflInit + (FPartFunctions * pFPartFunctions); +static Int32 _g_ppnvflOpen + (UInt32 dwKeepout, + UInt32 minor_ver, + UInt32 dwOptions); +static void _g_ppnvflClose + (void); +static BOOL32 _g_ppnvflReadScatteredPagesInVb + (UInt32 * padwVpn, + UInt16 wNumPagesToRead, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening, + Int32 *actualStatus); +static Int32 _g_ppnvflReadSinglePage + (UInt32 nVpn, + Buffer *pBuf, + BOOL32 bCleanCheck, + BOOL32 bMarkECCForScrub, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening); +static UInt16* _g_ppnvflGetFTLCxtVbn + (void); +static BOOL32 _g_ppnvflGetStruct + (UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 * pdwStructSize); +static BOOL32 _g_ppnvflSetStruct + (UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 dwStructSize); +static UInt32 _g_ppnvflGetDeviceInfo + (UInt32 dwParamType); +static Int32 _ppnvflOpen + (PPNVFL_MainCxt * mcxt, + UInt32 dwKeepout, + UInt32 minor_ver, + UInt32 dwOptions); + +/* ----------- I/F commands - end ------------- */ + +static PPNVFL_MainCxt *g_ppnvflMain = NULL; +static VFLFailureDetails gstLastFailure; + +// helper functions - local +#if !AND_READONLY +static BOOL32 _programCxtLastPage + (PPNVFL_MainCxt * mcxt, + Buffer * buf, + BOOL32 retry); +static BOOL32 _copyVFLCxtToOtherPair + (PPNVFL_MainCxt * mcxt); +#endif // !AND_READONLY +static BOOL32 _readVFLCxtPage + (PPNVFL_MainCxt * mcxt, + Buffer *buf, + UInt16 bank, + UInt16 vfl_idx); +static void +_copyFromOnNandCxtToRam + (PPNVFL_MainCxt * mcxt, + UInt8 *data); +#if !AND_READONLY +static void +_copyFromRamToOnNandCxt + (PPNVFL_MainCxt * mcxt, + UInt8 *data); +#endif // !AND_READONLY + +typedef enum +{ + VFLCxtProgramFail = 0, + VFLCxtProgramDone = 2, + VFLCxtProgramRetry = 3, +} ProgramVFLCxtPageWrapStatus; + +#if !AND_READONLY +static ProgramVFLCxtPageWrapStatus _programVFLCxtPageWrap + (PPNVFL_MainCxt * mcxt, + Buffer *buf, + UInt16 bank, + UInt16 vfl_idx); +static BOOL32 _programVFLCxtPage + (PPNVFL_MainCxt * mcxt, + Buffer *buf, + UInt16 bank, + UInt16 vfl_idx); +#endif // !AND_READONLY +static void +_convertVFLPageIdxToPhysicalPageBlockOffsets + (PPNVFL_MainCxt * mcxt, + UInt16 set, + UInt16 vfl_page_idx, + UInt16 *vfl_block_offset, + UInt16 *vfl_page_offset); + +#ifndef AND_READONLY +static BOOL32 +_markBlockForReplacement + (PPNVFL_MainCxt * mcxt, + UInt16 bank, + UInt16 block); +#endif // ! AND_READONLY + +#if !AND_READONLY + +static void +_setVFLCxtSpare + (PPNVFL_MainCxt * mcxt, + UInt8 *meta, + UInt8 bank, + UInt8 vfl_idx) +{ + PPNVFL_CxtSpare *spare = (PPNVFL_CxtSpare*)meta; + + WMR_MEMSET(spare, 0x00, sizeof(PPNVFL_CxtSpare)); + spare->cxt_age = mcxt->r_gen.cxt_age; + spare->bank = bank; + spare->spareType = PPNVFL_SPARE_TYPE_CXT; + spare->idx = vfl_idx; +} + +#endif // !AND_READONLY + +/* + * Name: _ReportFailure + * Input: mode, FailingCE, PhysicalPageAddress + * Output: none + * Return value: none + */ +static void +_ReportFailure + (VFLFailureMode mode, + UInt16 wFailingCE, + UInt32 dwPhysicalPage) +{ + gstLastFailure.mode = mode; + gstLastFailure.wCE[0] = wFailingCE; + gstLastFailure.dwPhysicalPage = dwPhysicalPage; +} + +/* address translating functions - start */ + +static UInt32 +_getMixedArrayEntryOffset + (PPNVFL_MainCxt * mcxt, + UInt16 vbn, + UInt16 mixed_array_offset) +{ + const UInt32 v2p_mixed_entry_uint32 = mcxt->v2p_main[vbn] & (~PPN_V2P_MIXED_MARK); + const UInt32 num_of_banks_uint32 = mcxt->dev.num_of_banks; + const UInt32 mixed_array_offset_uint32 = mixed_array_offset; + + return (v2p_mixed_entry_uint32 * num_of_banks_uint32) + mixed_array_offset_uint32; +} + +/* + * Name: _convertVpnToBankBlockPage + * Input: vpn + * Output: bank, block, page offset + * Return value: none + */ +static void +_convertVpnToBankBlockPage + (PPNVFL_MainCxt * mcxt, + UInt32 vpn, + UInt16 *bank, + UInt16 *block, + UInt16 *page_offset) +{ + UInt16 vbn = vpn / mcxt->dev.pages_per_sublk; + UInt16 mixed_array_offset = vpn % mcxt->dev.num_of_banks; + + if (mcxt->v2p_main[vbn] & PPN_V2P_MIXED_MARK) + { + UInt32 mixed_index = _getMixedArrayEntryOffset(mcxt, vbn, mixed_array_offset); + *block = mcxt->v2p_mixed[mixed_index].pbn; + *bank = mcxt->v2p_mixed[mixed_index].bank; + } + else + { + *block = mcxt->v2p_main[vbn]; + *bank = mixed_array_offset; + } + *page_offset = (vpn % mcxt->dev.pages_per_sublk) / mcxt->dev.num_of_banks; +} +/* address translating functions - end */ + +/* + * Name: _printV2PMapping + * Description: if PPNVFL_PRINT_V2PMAPPING is enabled and VFL_INF_PRINT + * is working this function print the virtual to phsical map. + * Return value: none + */ + +#define PPNVFL_PRINT_V2PMAPPING (1) + +static void +_printV2PMapping + (PPNVFL_MainCxt * mcxt) +{ +#if (defined(PPNVFL_PRINT_V2PMAPPING) && PPNVFL_PRINT_V2PMAPPING) + UInt16 vbn; + UInt32 vpn; + + VFL_INF_PRINT(1, (TEXT("_printV2PMapping()\n"))); + for (vbn = 0; vbn < mcxt->gen.num_of_vfl_sublk; vbn++) + { + UInt16 bank_idx; + vpn = (UInt32)vbn * (UInt32)mcxt->dev.pages_per_sublk; + VFL_INF_PRINT(1, (TEXT("%04X : "), vbn)); + for (bank_idx = 0; bank_idx < mcxt->dev.num_of_banks; bank_idx++) + { + UInt16 bank, block, page_offset; + _convertVpnToBankBlockPage(mcxt, (vpn + bank_idx), &bank, &block, &page_offset); + VFL_INF_PRINT(1, (TEXT("[%02X, %04X] "), bank, block)); + } + VFL_INF_PRINT(1, (TEXT("\n"))); + } +#endif +} + +#define PPNVFL_PRINT_CXT_BLOCK_MAPPING (1) + +static void +_printVFLBlockMapping + (PPNVFL_MainCxt * mcxt, + UInt32 line) +{ + UInt16 i, bank; + + VFL_INF_PRINT(PPNVFL_PRINT_CXT_BLOCK_MAPPING, + (TEXT("[PPNVFL:INF] printing vfl block list (caller line:%d)\n"), line)); + for (i = 0; i < mcxt->r_gen.num_of_vfl_blocks; i++) + { + VFL_INF_PRINT(PPNVFL_PRINT_CXT_BLOCK_MAPPING, + (TEXT("(0x%04X, 0x%04X)"), mcxt->gen.vfl_blocks[i].bank, mcxt->gen.vfl_blocks[i].block)); + } + VFL_INF_PRINT(PPNVFL_PRINT_CXT_BLOCK_MAPPING, (TEXT("\n"))); + VFL_INF_PRINT(PPNVFL_PRINT_CXT_BLOCK_MAPPING, + (TEXT("[PPNVFL:INF] printing mapping pages (caller line:%d)\n"), line)); + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + VFL_INF_PRINT(PPNVFL_PRINT_CXT_BLOCK_MAPPING, + (TEXT("bank 0x%02X: "), bank)); + for (i = 0; i < mcxt->r_gen.pages_per_block_mapping; i++) + { + VFL_INF_PRINT(PPNVFL_PRINT_CXT_BLOCK_MAPPING, + (TEXT("0x%04X "), mcxt->vfl_map_pages[bank][i])); + } + VFL_INF_PRINT(PPNVFL_PRINT_CXT_BLOCK_MAPPING, (TEXT("\n"))); + } +} +/* + * Name: callPrintV2PMapping + * Description: this function is a none static version of _printV2PMapping + * Return value: none + */ +void +callPrintV2PMapping + (void) +{ + _printV2PMapping(g_ppnvflMain); +} + +/* + * Name: _calcNumOfVFLSuBlk + * Return value: number of VFL virtual blocks for this media + */ +static UInt32 +_calcNumOfVFLSuBlk + (PPNVFL_MainCxt * mcxt) +{ + UInt32 temp, shift; + + temp = mcxt->dev.blocks_per_cau + 100; // making sure we have the right bit set + shift = 0; + while (temp >>= 1) + { + shift++; + } + return PPNVFL_USER_BLKS_PER_256B * (1 << (shift - 8)); +} + +/* ppn commands functions - start */ +/* + * Name: _addAddressToCommandStructure + * Output: pointer to commands structure + * Input: vfl address to add, index in the global operation (coming from the FTL). + * Return value: TRUE32 is successful, otehrwise - FALSE32 + */ +#define PPNVFL_PRINT_ADD_ADDRESS (1) +static BOOL32 +_addAddressToCommandStructure + (PPNVFL_MainCxt * mcxt, + PPNCommandStruct **commands, + UInt32 vfl_address, + UInt8 vba_offset, + UInt8 vba_count, + UInt8 mem_index, + UInt16 mem_offset) +{ + UInt16 bank = 0, block = 0, cau = 0, chip_enable_idx = 0, channel = 0, + page_offset = 0; + + // convert address from vfl to physical + _convertVpnToBankBlockPage(mcxt, vfl_address, &bank, &block, &page_offset); + channel = ppnMiscGetChannelFromBank(&mcxt->dev, bank); + chip_enable_idx = ppnMiscGetCEIdxFromBank(&mcxt->dev, bank); + cau = ppnMiscGetCAUFromBank(&mcxt->dev, bank); + return ppnMiscAddPhysicalAddressToCommandStructure(&mcxt->dev, mcxt->commands, channel, chip_enable_idx, + cau, block, page_offset, FALSE32, vba_offset, vba_count, + mem_index, mem_offset); +} + +/* + * Name: _fillScatteredAddressesToCommandStructure + * Description: this function takes an array of scattered addresses and + * generates commands structure to send to the FIL. + * Output: pointer to commands structure + * Input: array of vfl addresses, number of addresses, command type, + * data pointer, meta pointer + * Return value: TRUE32 is successful, otehrwise - FALSE32 + */ +static BOOL32 +_fillScatteredAddressesToCommandStructure + (PPNVFL_MainCxt * mcxt, + PPNCommandStruct **commands, + UInt32 *vfl_addresses, + UInt16 *num_addresses, + PPNCommand command, + void *data, + void *meta, + PPNOptions options) +{ + UInt16 addr_idx; + + ppnMiscInitCommandStructure(&mcxt->dev, mcxt->commands, mcxt->dev.num_channels, command, options); + for (addr_idx = 0; addr_idx < *num_addresses; addr_idx++) + { + if (_addAddressToCommandStructure(mcxt, mcxt->commands, vfl_addresses[addr_idx], 0, 1, + mcxt->commands[0]->mem_buffers_count, addr_idx) == FALSE32) + { + *num_addresses = addr_idx; + break; + } + } + ppnMiscAddMemoryToCommandStructure(&mcxt->dev, mcxt->commands, mcxt->dev.num_channels, data, meta, addr_idx); + ppnMiscReorderCommandStruct(&mcxt->dev, mcxt->commands, mcxt->dev.num_channels, mcxt->reorder); + + return TRUE32; +} + +#if !AND_READONLY + +/* + * Name: _fillSequentialAddressesToCommandStructure + * Description: this function takes a start address and number of pages and + * generates commands structure to send to the FIL. + * Output: pointer to commands structure + * Input: start vfl address, number of addresses, command type, + * data pointer, meta pointer + * Return value: TRUE32 is successful, otehrwise - FALSE32 + */ +static BOOL32 +_fillSequentialAddressesToCommandStructure + (PPNVFL_MainCxt * mcxt, + PPNCommandStruct **commands, + UInt32 vfl_address, + UInt16 *num_addresses, + PPNCommand command, + void *data, + void *meta, + PPNOptions options) +{ + UInt16 addr_idx; + + ppnMiscInitCommandStructure(&mcxt->dev, mcxt->commands, mcxt->dev.num_channels, command, options); + for (addr_idx = 0; addr_idx < *num_addresses; addr_idx++) + { + if (_addAddressToCommandStructure(mcxt, mcxt->commands, (vfl_address + addr_idx), 0, 1, + mcxt->commands[0]->mem_buffers_count, addr_idx) == FALSE32) + { + *num_addresses = addr_idx; + break; + } + } + ppnMiscAddMemoryToCommandStructure(&mcxt->dev, mcxt->commands, mcxt->dev.num_channels, data, meta, addr_idx); + ppnMiscReorderCommandStruct(&mcxt->dev, mcxt->commands, mcxt->dev.num_channels, mcxt->reorder); + + return TRUE32; +} + +#endif // !AND_READONLY + +/* ppn commands functions - end */ + +/* vfl mixed list functions - start */ +static UInt32 +_getV2PMixedArraySize + (PPNVFL_MainCxt * mcxt) +{ + return sizeof(MixedEntryType) * (mcxt->dev.blocks_per_cau - mcxt->gen.num_of_vfl_sublk) * + mcxt->dev.num_of_banks * mcxt->dev.num_of_banks; +} + +/* + * Name: _isMixedBlock + * Description: this function checks if a virtual block has blocks from + * different offsets in different banks or not. + * Input: virtual block address + * Return value: TRUE32 if the block is mixed, otherwise FALSE32 + */ +BOOL32 +_isMixedBlock + (PPNVFL_MainCxt * mcxt, + UInt16 vbn) +{ + WMR_ASSERT(mcxt->v2p_main[vbn] != 0xFFFF); + + if (mcxt->v2p_main[vbn] & PPN_V2P_MIXED_MARK) + { + return TRUE32; + } + return FALSE32; +} + +/* + * Name: _setMixedBlockEntry + * Description: this function adds/changes a block in an existing + * mixed entry. + * Input: vbn, bank, block in the bank + * Return value: TRUE32 if successful, otherwise FALSE32 + */ +static BOOL32 +_setMixedBlockEntry + (PPNVFL_MainCxt * mcxt, + UInt16 vbn, + UInt16 mixed_array_offset, + UInt16 bank, + UInt16 pbn) +{ + const UInt32 entry_offset = _getMixedArrayEntryOffset(mcxt, vbn, mixed_array_offset); + + if (_isMixedBlock(mcxt, vbn) == FALSE32) + { + return FALSE32; + } + + mcxt->v2p_mixed[entry_offset].pbn = pbn; + mcxt->v2p_mixed[entry_offset].bank = bank; + return TRUE32; +} + +/* + * Name: _addNewMixedBlockEntry + * Description: this function generates a new mixed block entry. + * Input: vbn, bank, block in the bank + * Return value: TRUE32 if successful, otherwise FALSE32 + */ +static BOOL32 +_addNewMixedBlockEntry + (PPNVFL_MainCxt * mcxt, + UInt16 vbn, + UInt16 mixed_array_offset, + UInt16 bank, + UInt16 pbn) +{ + const UInt16 main_pbn = mcxt->v2p_main[vbn]; + const UInt16 mixed_entry = mcxt->mixed_entries; + UInt32 entry_offset; + UInt16 i; + + if (_isMixedBlock(mcxt, vbn) == TRUE32) + { + return FALSE32; + } + + mcxt->v2p_main[vbn] = mixed_entry | PPN_V2P_MIXED_MARK; + mcxt->mixed_entries++; + entry_offset = _getMixedArrayEntryOffset(mcxt, vbn, 0); + for (i = 0; i < mcxt->dev.num_of_banks; i++) + { + mcxt->v2p_mixed[entry_offset + i].pbn = main_pbn; + mcxt->v2p_mixed[entry_offset + i].bank = i; + } + return _setMixedBlockEntry(mcxt, vbn, mixed_array_offset, bank, pbn); +} + +/* vfl mixed list functions - end */ + +/* block replacement functions - start */ + +#ifndef AND_READONLY + +#define PPNVFL_CHECK_REPLACEMENT_BLOCK_WITH_REOPEN (0) +/* debug code - compare vfl cxt before and after opening vfl */ +BOOL32 +_testVFLCxtAfterOpenCycle + (PPNVFL_MainCxt * mcxt) +{ + UInt16 temp_bank; + PPNVFL_MainCxt main_cxt_copy; + PPNVFL_BankRAMCxt *r_banks_copy; + UInt16 *v2p_main_copy; + MixedEntryType *v2p_mixed_copy; + BOOL32 res = TRUE32; + UInt16 i; + + r_banks_copy = (PPNVFL_BankRAMCxt*)WMR_MALLOC(mcxt->dev.num_of_banks * + sizeof(PPNVFL_BankRAMCxt)); + v2p_main_copy = (UInt16*)WMR_MALLOC(sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk); + v2p_mixed_copy = (MixedEntryType*)WMR_MALLOC(_getV2PMixedArraySize(mcxt)); + WMR_MEMCPY(&main_cxt_copy, mcxt, sizeof(PPNVFL_MainCxt)); + WMR_MEMCPY(r_banks_copy, mcxt->r_banks, (sizeof(PPNVFL_BankRAMCxt) * mcxt->dev.num_of_banks)); + WMR_MEMCPY(v2p_main_copy, mcxt->v2p_main, (sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk)); + WMR_MEMCPY(v2p_mixed_copy, mcxt->v2p_mixed, _getV2PMixedArraySize(mcxt)); + + ppnMiscFillDevStruct(&mcxt->dev, mcxt->fil); + _ppnvflOpen(mcxt, mcxt->r_gen.keepout, 0, 0); + // compare banks and main info before and after + if (WMR_MEMCMP(&main_cxt_copy, mcxt, sizeof(PPNVFL_MainCxt)) != 0) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] problem comparing main (line:%d)\n"), __LINE__)); + res = FALSE32; + } + + for (temp_bank = 0; temp_bank < mcxt->dev.num_of_banks; temp_bank++) + { + if (WMR_MEMCMP(&r_banks_copy[temp_bank], &mcxt->r_banks[temp_bank], sizeof(PPNVFL_BankRAMCxt)) != 0) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] problem comparing bank 0x%X RAM(line:%d)\n"), temp_bank, __LINE__)); + res = FALSE32; + } + } + + for (i = 0; i < mcxt->gen.num_of_vfl_sublk; i++) + { + if ((mcxt->v2p_main[i] & PPN_V2P_MIXED_MARK) != (v2p_main_copy[i] & PPN_V2P_MIXED_MARK)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] problem comparing v2p_main[0x%04X] org = 0x%04X reopen = 0x%04X (line:%d)\n"), + i, mcxt->v2p_main[i] != v2p_main_copy[i], __LINE__)); + res = FALSE32; + } + else if (mcxt->v2p_main[i] & PPN_V2P_MIXED_MARK) + { + UInt16 j; + const UInt16 idx_new = mcxt->v2p_main[i] & (~PPN_V2P_MIXED_MARK); + const UInt16 idx_org = v2p_main_copy[i] & (~PPN_V2P_MIXED_MARK); + for (j = 0; j < mcxt->dev.num_of_banks; j++) + { + const UInt32 entry_offset_new = ((UInt32)idx_new * (UInt32)mcxt->dev.num_of_banks) + (UInt32)j; + const UInt32 entry_offset_org = ((UInt32)idx_org * (UInt32)mcxt->dev.num_of_banks) + (UInt32)j; + if (WMR_MEMCMP(&mcxt->v2p_mixed[entry_offset_new], + &v2p_mixed_copy[entry_offset_org], + sizeof(MixedEntryType))) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] problem comparing v2p_mixed[0x%X][0x%X] org = 0x%04X reopen = 0x%04X (line:%d)\n"), + i, j, mcxt->v2p_mixed[entry_offset_new], v2p_mixed_copy[entry_offset_org], __LINE__)); + res = FALSE32; + } + } + } + else if (mcxt->v2p_main[i] != v2p_main_copy[i]) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] problem comparing v2p_main[0x%04X] org = 0x%04X reopen = 0x%04X (line:%d)\n"), + i, mcxt->v2p_main[i] != v2p_main_copy[i], __LINE__)); + res = FALSE32; + } + } + + WMR_FREE(r_banks_copy, (mcxt->dev.num_of_banks * + sizeof(PPNVFL_BankRAMCxt))); + WMR_FREE(v2p_main_copy, (sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk)); + WMR_FREE(v2p_mixed_copy, (_getV2PMixedArraySize(mcxt))); + return res; +} + +static BOOL32 +_setBlockUsageInVFLCxt + (PPNVFL_MainCxt *mcxt, + UInt16 bank, + UInt16 block, + P2BlockUsageType *new_usage, + P2BlockUsageType *old_usage) +{ + P2BlockUsageType *p2_block_usage_map; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + const UInt16 vflcxt_in_page_offset = block % mcxt->r_gen.pbns_per_cxt_mapping_page; + const UInt16 vflcxt_page_index = block / mcxt->r_gen.pbns_per_cxt_mapping_page; + BOOL32 retry_program_cxt = FALSE32; + + p2_block_usage_map = (P2BlockUsageType*)buf->pData; + + do + { + ProgramVFLCxtPageWrapStatus program_status; + P2BlockUsageType *on_vflcxt_block_usage = &p2_block_usage_map[vflcxt_in_page_offset]; + retry_program_cxt = FALSE32; + // mark the block we are replacing as bad + if (_readVFLCxtPage(mcxt, buf, bank, vflcxt_page_index) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] error reading vfl cxt (bank:0x%X, index:0x%X, block:0x%X) (line:%d)"), + bank, vflcxt_page_index, block, __LINE__)); + goto return_error; + } + + if ((old_usage != NULL) && WMR_MEMCMP(old_usage, on_vflcxt_block_usage, sizeof(P2BlockUsageType))) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] old_usage is different than written (bank:0x%X, block:0x%X, old usage:0x%08X, written type: 0x%X) (line:%d)"), + bank, block, *((UInt32*)old_usage), *((UInt32*)on_vflcxt_block_usage), __LINE__)); + goto return_error; + } + on_vflcxt_block_usage->p2sb.type = PPNVFL_TYPE_GROWN_BB; + on_vflcxt_block_usage->p2sb.reserved = P2SB_RESERVED_VALUE; + + program_status = _programVFLCxtPageWrap(mcxt, buf, bank, vflcxt_page_index); + if (program_status == VFLCxtProgramFail) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] error programming vfl cxt (bank:0x%X, index:0x%X) (line:%d)"), + bank, vflcxt_page_index, __LINE__)); + goto return_error; + } + else if (program_status == VFLCxtProgramRetry) + { + retry_program_cxt = TRUE32; + } + else + { + retry_program_cxt = FALSE32; + } + } + while (retry_program_cxt); + + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +#define PPNVFL_PRINT_SPEICAL_BLOCK_ALLOC_SUMMARY +static BOOL32 +_ppnvflAllocateSpecialBlock + (PPNVFL_MainCxt * mcxt, + SpecialBlockAddress *chosen_block, + UInt16 type) +{ + UInt16 bank, i; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + P2BlockUsageType *p2_block_usage_map = (P2BlockUsageType*)buf->pData; + BOOL32 retry_allocating = FALSE32; + UInt32 failed_banks_mask = 0; + +#if (defined(PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_BEFORE) && PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_BEFORE) + _printV2PMapping(mcxt); +#endif + + do + { + UInt16 vfl_idx, min_special_blocks = 0xFFFF;; + UInt16 total_special_blocks = 0; + chosen_block->bank = 0xFFFF; + chosen_block->block = 0xFFFF; + retry_allocating = FALSE32; + // choose a bank + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + const UInt16 specials_in_bank = mcxt->r_banks[bank].num_special_blocks; + total_special_blocks += specials_in_bank; + if (specials_in_bank < min_special_blocks && + mcxt->r_banks[bank].num_available != 0 && + !(failed_banks_mask & (1UL << bank))) + { + chosen_block->bank = bank; + min_special_blocks = specials_in_bank; + } + } + if (chosen_block->bank == 0xFFFF) + { +#if AND_SIMULATOR + WMR_SIM_EXIT("Out of available blocks"); +#endif // AND_SIMULATOR + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] failed finding a bank to allocate special block (line:%d)\n"), __LINE__)); + goto return_error; + } + else if (AND_MAX_SPECIAL_BLOCKS < total_special_blocks) + { + VFL_ERR_PRINT((TEXT("total special blocks has exceeded the max allowed\n"))); + goto return_error; + } + bank = chosen_block->bank; + + // chose a block + for (vfl_idx = mcxt->r_gen.pages_per_block_mapping; + (vfl_idx > 0) && (!retry_allocating) && (chosen_block->block == 0xFFFF); ) + { + UInt16 cxt_blocks_offset; + UInt16 blocks_in_cxt_page; + vfl_idx--; + cxt_blocks_offset = vfl_idx * mcxt->r_gen.pbns_per_cxt_mapping_page; + blocks_in_cxt_page = WMR_MIN(mcxt->r_gen.pbns_per_cxt_mapping_page, + (mcxt->dev.blocks_per_cau - cxt_blocks_offset)); + if (_readVFLCxtPage(mcxt, buf, bank, + vfl_idx) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed _readVFLCxtPage (line:%d)!\n"), __LINE__)); + goto return_error; + } + for (i = blocks_in_cxt_page; (i > 0) && (i + cxt_blocks_offset > PPN_SPECIAL_BLOCK_LIMIT(&mcxt->dev)) && (!retry_allocating) && (chosen_block->block == 0xFFFF); ) + { + i--; + if (p2_block_usage_map[i].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + ProgramVFLCxtPageWrapStatus program_status; + UInt16 potential_block = i + cxt_blocks_offset; + if (!ppnMiscTestSpecialBlock(&mcxt->dev, mcxt->commands[0], bank, potential_block, PPNVFL_SPARE_TYPE_TST)) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed testing block (bank:0x%X, block:0x%X) for sb allocation (line:%d)"), + bank, potential_block, __LINE__)); + + p2_block_usage_map[i].p2sb.type = PPNVFL_TYPE_GROWN_BB; + p2_block_usage_map[i].p2sb.reserved = P2SB_RESERVED_VALUE; + } + else + { + chosen_block->block = potential_block; + p2_block_usage_map[i].p2sb.type = type; + p2_block_usage_map[i].p2sb.reserved = P2SB_RESERVED_VALUE; + } + // program the update back to the NAND + program_status = _programVFLCxtPageWrap(mcxt, buf, bank, vfl_idx); + if (program_status == VFLCxtProgramFail) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] error programming vfl cxt (bank:0x%X, i:0x%X) (line:%d)"), + bank, i, __LINE__)); + goto return_error; + } + else if (program_status == VFLCxtProgramRetry) + { + retry_allocating = TRUE32; + } + else + { + // mark the change in the VFL RAM structures + mcxt->r_banks[bank].num_available--; + if (p2_block_usage_map[i].p2sb.type == PPNVFL_TYPE_GROWN_BB) + { + mcxt->r_banks[bank].num_grown_bad++; + retry_allocating = TRUE32; + } + else + { + mcxt->r_banks[bank].num_special_blocks++; + } + } + } + } + } + if ((!retry_allocating) && (chosen_block->block == 0xFFFF)) + { + failed_banks_mask |= 1UL << bank; + retry_allocating = TRUE32; + } + } + while (retry_allocating); + + if (chosen_block->block == 0xFFFF) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed to find a new special block (bank:0x%X)(line:%d)!\n"), + bank, __LINE__)); + goto return_error; + } + + if (_programCxtLastPage(mcxt, buf, TRUE32) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] error programming last vfl cxt (bank:0x%X) (line:%d)"), + bank, __LINE__)); + goto return_error; + } + +#if (defined(PPNVFL_CHECK_REPLACEMENT_BLOCK_WITH_REOPEN) && PPNVFL_CHECK_REPLACEMENT_BLOCK_WITH_REOPEN) +#if (defined(PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER) && PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER) + _printV2PMapping(mcxt); +#endif // PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER + _testVFLCxtAfterOpenCycle(mcxt); +#endif // PPNVFL_CHECK_REPLACEMENT_BLOCK_WITH_REOPEN + if (!mcxt->fpart->AllocateSpecialBlockType(chosen_block, 1, type)) + { + VFL_ERR_PRINT((TEXT("fpart failed to allocate special block with type %p\n"), type)); + goto return_error; + } + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +#define PPNVFL_PRINT_BLOCK_REPLACEMENT (1) +#if (defined(PPNVFL_PRINT_BLOCK_REPLACEMENT) && PPNVFL_PRINT_BLOCK_REPLACEMENT) +#define PPNVFL_PRINT_BLOCK_REPLACEMENT_SUMMARY (1) +#define PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_BEFORE (0) +#define PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER (0) +#else +#define PPNVFL_PRINT_BLOCK_REPLACEMENT_SUMMARY (0) +#define PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_BEFORE (0) +#define PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER (0) +#endif + +static BOOL32 +_replaceBadBlock + (PPNVFL_MainCxt * mcxt, + UInt16 replaced_bank, + UInt16 replaced_block, + UInt16 vbn, + UInt16 mixed_array_offset) +{ + UInt16 i, j, new_block = 0xFFFF, new_bank = replaced_bank; + P2BlockUsageType *p2_block_usage_map; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + const UInt16 blocks_in_cxt_page = mcxt->r_gen.pbns_per_cxt_mapping_page; + BOOL32 retry_program_cxt = FALSE32; + P2BlockUsageType old_usage, new_usage; + + p2_block_usage_map = (P2BlockUsageType*)buf->pData; + +#if (defined(PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_BEFORE) && PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_BEFORE) + _printV2PMapping(mcxt); +#endif + + do + { + ProgramVFLCxtPageWrapStatus program_status; + // search for an available block + // read the cxt pages search for replacement blocks + + retry_program_cxt = FALSE32; + if (mcxt->r_banks[new_bank].num_available == 0) + { + UInt16 max_avail_bank = 0xFFFF, max_avail_count = 0, bank; + + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] can't find available blocks in the original bank - look elsewhere (bank:0x%X, block:0x%X)(line:%d)!\n"), + replaced_bank, replaced_block, __LINE__)); + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + if (max_avail_count < mcxt->r_banks[bank].num_available) + { + max_avail_count = mcxt->r_banks[bank].num_available; + max_avail_bank = bank; + } + } + if (max_avail_bank == 0xFFFF) + { +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) + WMR_SIM_EXIT("Out of replacement blocks"); +#else // defined(AND_SIMULATOR) && AND_SIMULATOR + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed - no replacement blocks in any of the banks (bank:0x%X, block:0x%X)(line:%d)!\n"), + replaced_bank, replaced_block, __LINE__)); +#endif // defined(AND_SIMULATOR) && AND_SIMULATOR + goto return_error; + } + new_bank = max_avail_bank; + } + for (i = 0; ((!retry_program_cxt) && (i < mcxt->r_gen.pages_per_block_mapping) && + (new_block == 0xFFFF)); i++) + { + if (_readVFLCxtPage(mcxt, buf, new_bank, i) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed _readVFLCxtPage (line:%d)!\n"), __LINE__)); + goto return_error; + } + for (j = 0; j < blocks_in_cxt_page; j++) + { + if (p2_block_usage_map[j].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + UInt16 potential_new_block = j + (i * blocks_in_cxt_page); + p2_block_usage_map[j].p2v.vbn = vbn; + p2_block_usage_map[j].p2v.offset = (UInt8)mixed_array_offset; + p2_block_usage_map[j].p2v.reserved = P2V_RESERVED_VALUE; + + // program the update back to the NAND + program_status = _programVFLCxtPageWrap(mcxt, buf, new_bank, i); + if (program_status == VFLCxtProgramFail) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] error programming vfl cxt (bank:0x%X, i:0x%X, j:0x%X) (line:%d)"), + new_bank, i, j, __LINE__)); + goto return_error; + } + else if (program_status == VFLCxtProgramRetry) + { + retry_program_cxt = TRUE32; + break; + } + new_block = potential_new_block; + // mark the change in the VFL RAM structures + if (_isMixedBlock(mcxt, vbn) == TRUE32) + { + _setMixedBlockEntry(mcxt, vbn, mixed_array_offset, new_bank, new_block); + } + else + { + _addNewMixedBlockEntry(mcxt, vbn, mixed_array_offset, new_bank, new_block); + } + mcxt->r_banks[new_bank].num_available--; + mcxt->r_banks[new_bank].num_p2v++; + mcxt->r_banks[replaced_bank].num_p2v--; + mcxt->r_banks[replaced_bank].num_grown_bad++; + VFL_INF_PRINT(PPNVFL_PRINT_BLOCK_REPLACEMENT_SUMMARY, + (TEXT( + "[PPNVFL:INF] block replacement (vbn:0x%X, array_offset:0x%X, new_bank:0x%X, new_block:0x%X) (l:%d)\n"), + vbn, mixed_array_offset, new_bank, new_block, __LINE__)); + break; + } + } + } + + if ((!retry_program_cxt) && (new_block == 0xFFFF)) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed to find replacement block (bank:0x%X, block:0x%X)(line:%d)!\n"), + replaced_bank, replaced_block, __LINE__)); + goto return_error; + } + } + while (retry_program_cxt); + + BUF_Release(buf); + buf = NULL; + old_usage.p2v.vbn = vbn; + old_usage.p2v.offset = (UInt8)mixed_array_offset; + old_usage.p2v.reserved = P2V_RESERVED_VALUE; + new_usage.p2sb.type = PPNVFL_TYPE_GROWN_BB; + new_usage.p2sb.reserved = P2SB_RESERVED_VALUE; + if (!_setBlockUsageInVFLCxt(mcxt, replaced_bank, replaced_block, &new_usage, &old_usage)) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed to mark block as bad (bank:0x%X, block:0x%X)(line:%d)!\n"), + replaced_bank, replaced_block, __LINE__)); + goto return_error; + } + buf = BUF_Get(BUF_MAIN_AND_SPARE); + + // find the block we replaced in the scrub list and remove it + for (i = 0; i < mcxt->gen.scrub_idx; i++) + { + if (replaced_block == mcxt->gen.scrub_list[i].block && + replaced_bank == mcxt->gen.scrub_list[i].bank) + { + if (i != mcxt->gen.scrub_idx - 1) + { + // move the block in the last scrub index to the place of the one + // we are replacing so we can substruct scrub_idx + mcxt->gen.scrub_list[i].block = mcxt->gen.scrub_list[mcxt->gen.scrub_idx - 1].block; + mcxt->gen.scrub_list[i].bank = mcxt->gen.scrub_list[mcxt->gen.scrub_idx - 1].bank; + } + mcxt->gen.scrub_idx--; + break; + } + } + + if (_programCxtLastPage(mcxt, buf, TRUE32) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] error programming last vfl cxt (bank:0x%X, index:0x%X) (line:%d)"), + replaced_bank, replaced_block, __LINE__)); + goto return_error; + } + + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] replacing vbn 0x%X, org (bank:0x%X, block:0x%X), new (bank:0x%X, block:0x%X) (line:%d)!\n"), + vbn, replaced_bank, replaced_block, new_bank, new_block, __LINE__)); +#if (defined(PPNVFL_CHECK_REPLACEMENT_BLOCK_WITH_REOPEN) && PPNVFL_CHECK_REPLACEMENT_BLOCK_WITH_REOPEN) + _testVFLCxtAfterOpenCycle(mcxt); +#if (defined(PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER) && PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER) + _printV2PMapping(mcxt); +#endif // PPNVFL_PRINT_BLOCK_REPLACEMENT_MAPPING_AFTER +#endif // PPNVFL_CHECK_REPLACEMENT_BLOCK_WITH_REOPEN + BUF_Release(buf); + return TRUE32; + + return_error: + if (buf != NULL) + { + BUF_Release(buf); + } + WMR_PANIC("_replaceBadBlock() fail bank 0x%x block 0x%x vbn 0x%x offset 0x%x\n", replaced_bank, replaced_block, vbn, + mixed_array_offset); + return FALSE32; +} + +static BOOL32 +_replaceErasedCxtBlock + (PPNVFL_MainCxt * mcxt, + UInt16 vfl_index) +{ + UInt16 i, j, new_block = 0xFFFF, new_bank = 0xFFFF, new_block_index = 0xFFFF, new_block_cxt_page = 0xFFFF; + UInt16 bank, max_available, min_cxt_blocks; + P2BlockUsageType *p2_block_usage_map = NULL; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + const UInt16 blocks_in_cxt_page = mcxt->r_gen.pbns_per_cxt_mapping_page; + const UInt16 replaced_block = mcxt->gen.vfl_blocks[vfl_index].block; + const UInt16 replaced_bank = mcxt->gen.vfl_blocks[vfl_index].bank; + const UInt16 replaced_index = replaced_block % blocks_in_cxt_page; + const UInt16 replaced_cxt_page = replaced_block / blocks_in_cxt_page; + const UInt16 blocks_per_vfl_set = (mcxt->r_gen.num_of_vfl_blocks >> 1); + const UInt16 set_mapping_offset = mcxt->r_gen.next_cxt_block_offset * blocks_per_vfl_set; + + PPNStatusType status; + + p2_block_usage_map = (P2BlockUsageType*)buf->pData; + + _printVFLBlockMapping(mcxt, __LINE__); + + // chose a bank to work with + // pick the bank with maximum available blocks and minimum cxt blocks + max_available = 0; + min_cxt_blocks = 0xFFFF; + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + if (mcxt->r_banks[bank].num_available) + { + if (new_bank == 0xFFFF) + { + new_bank = bank; + min_cxt_blocks = mcxt->r_banks[bank].num_cxt; + max_available = mcxt->r_banks[bank].num_available; + } + else if (mcxt->r_banks[bank].num_cxt < min_cxt_blocks) + { + min_cxt_blocks = mcxt->r_banks[bank].num_cxt; + max_available = mcxt->r_banks[bank].num_available; + new_bank = bank; + } + else if (mcxt->r_banks[bank].num_cxt == min_cxt_blocks) + { + if (mcxt->r_banks[bank].num_available > max_available) + { + min_cxt_blocks = mcxt->r_banks[bank].num_cxt; + max_available = mcxt->r_banks[bank].num_available; + new_bank = bank; + } + } + } + } + + // verify a bank was chosen + if (new_bank == 0xFFFF) + { +#if AND_SIMULATOR + WMR_SIM_EXIT("Out of replacement blocks"); +#endif // AND_SIMULATOR + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed finding a bank to provide vfl cxt blocks (line:%d)!\n"), + __LINE__)); + goto return_error; + } + + // pick a replacement block + for (i = 0; (i < mcxt->r_gen.pages_per_block_mapping) && (new_block == 0xFFFF); i++) + { + if (_readVFLCxtPage(mcxt, buf, new_bank, i) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed _readVFLCxtPage (line:%d)!\n"), __LINE__)); + goto return_error; + } + for (j = 0; j < blocks_in_cxt_page; j++) + { + UInt16 potential_new_block = j + (i * blocks_in_cxt_page); + if (p2_block_usage_map[j].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + // test the block - do not mark blocks as bad if they fail, just continue + if (ppnMiscTestSpecialBlock(&mcxt->dev, mcxt->commands[0], new_bank, potential_new_block, PPNVFL_SPARE_TYPE_TST)) + { + new_block = potential_new_block; + new_block_index = j; + new_block_cxt_page = i; + mcxt->gen.vfl_blocks[vfl_index].block = new_block; + mcxt->gen.vfl_blocks[vfl_index].bank = new_bank; + break; + } + else + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed testing replacement block (bank:0x%X, block:0x%X)(line:%d)!\n"), + new_bank, potential_new_block, __LINE__)); + } + } + } + } + + // verify a block was found + if (new_block == 0xFFFF) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed searching for replacement block (bank:0x%X, block:0x%X)(line:%d)!\n"), + replaced_bank, replaced_block, __LINE__)); + goto return_error; + } + + _printVFLBlockMapping(mcxt, __LINE__); + // erase original - ignore status + ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_ERASE, + PPN_OPTIONS_IGNORE_BAD_BLOCK, replaced_bank, replaced_block, 0, + TRUE32, NULL, NULL); + + // erase current vfl set - fail replacement operation if we get an erase error + for (i = 0; i < blocks_per_vfl_set; i++) + { + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt->gen.vfl_blocks[set_mapping_offset + i].bank, + mcxt->gen.vfl_blocks[set_mapping_offset + i].block, + 0, TRUE32, NULL, NULL); + if (status & (PPN_ERASE_STATUS_RETIRE | PPN_ERASE_STATUS_FAIL | PPN_PROGRAM_STATUS_GEB)) + { + WMR_PRINT(QUAL_FATAL, + "failed erase new vfl block (bank:0x%04X, block: 0x%04X) with status 0x%02X\n", + mcxt->gen.vfl_blocks[set_mapping_offset + i].bank, + mcxt->gen.vfl_blocks[set_mapping_offset + i].block, status); + goto return_error; + } + } + // program last cxt page + mcxt->r_gen.next_cxt_page_offset = 0; + _copyFromRamToOnNandCxt(mcxt, buf->pData); + mcxt->r_gen.cxt_age--; + mcxt->r_gen.need_rewrite = FALSE32; + + if (!_programVFLCxtPage(mcxt, buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] _programVFLCxtPage failed while allocating new vfl block (bank:0x%04X, block: 0x%04X) (line:%d)\n"), + new_bank, new_block, __LINE__)); + goto return_error; + } + + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + for (i = 0; i < mcxt->r_gen.pages_per_block_mapping; i++) + { + if (_readVFLCxtPage(mcxt, buf, bank, i) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed _readVFLCxtPage (line:%d)!\n"), __LINE__)); + goto return_error; + } + + if (new_block_cxt_page == i && new_bank == bank) + { + p2_block_usage_map[new_block_index].p2sb.type = PPNVFL_TYPE_VFL_INFO; + p2_block_usage_map[new_block_index].p2sb.reserved = P2SB_RESERVED_VALUE; + mcxt->r_banks[bank].num_available--; + mcxt->r_banks[bank].num_cxt++; + } + + if (replaced_cxt_page == i && replaced_bank == bank) + { + p2_block_usage_map[replaced_index].p2sb.type = PPNVFL_TYPE_GROWN_BB; + p2_block_usage_map[replaced_index].p2sb.reserved = P2SB_RESERVED_VALUE; + mcxt->r_banks[bank].num_cxt--; + mcxt->r_banks[bank].num_grown_bad++; + } + if (!_programVFLCxtPage(mcxt, buf, bank, i)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] _programVFLCxtPage failed with the new vfl block (bank:0x%04X, block: 0x%04X) (line:%d)\n"), + new_bank, new_block, __LINE__)); + goto return_error; + } + } + } + + // check if the original block is in the scrub list, if so remove it + for (i = 0; i < mcxt->gen.scrub_idx; i++) + { + if (replaced_block == mcxt->gen.scrub_list[i].block && replaced_bank == mcxt->gen.scrub_list[i].bank) + { + if (i != mcxt->gen.scrub_idx - 1) + { + // move the block in the last scrub index to the place of the one + // we are replacing so we can substruct scrub_idx + mcxt->gen.scrub_list[i].bank = mcxt->gen.scrub_list[mcxt->gen.scrub_idx - 1].bank; + mcxt->gen.scrub_list[i].block = mcxt->gen.scrub_list[mcxt->gen.scrub_idx - 1].block; + } + mcxt->gen.scrub_idx--; + break; + } + } + + // program last cxt page + _copyFromRamToOnNandCxt(mcxt, buf->pData); + + if (!_programVFLCxtPage(mcxt, buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] _programVFLCxtPage failed with the new vfl block (bank:0x%04X, block: 0x%04X) (line:%d)\n"), + new_bank, new_block, __LINE__)); + goto return_error; + } + + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] replacing cxt_idx 0x%X, org (bank:0x%X, block:0x%X), new (bank:0x%X, block:0x%X) (line:%d)!\n"), + vfl_index, replaced_bank, replaced_block, new_bank, new_block, __LINE__)); + + // erase the set of blocks we want to use + for (i = 0; i < blocks_per_vfl_set; i++) + { + const UInt16 old_set_location = (mcxt->r_gen.next_cxt_block_offset == 1 ? 0 : 1); + const UInt16 old_set_mapping_offset = old_set_location * blocks_per_vfl_set; + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].block, + 0, + TRUE32, NULL, NULL); + + if (status & PPN_ERASE_STATUS_RETIRE) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with retire status (line:%d)\n"), + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].block, __LINE__)); + if (!_markBlockForReplacement(mcxt, mcxt->gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].block)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed marking vflcxt block (bank:0x%04X, block: 0x%04X) for scrub (line:%d)\n"), + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].block, __LINE__)); + } + } + else if (status & PPN_ERASE_STATUS_FAIL) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with no retire status (line:%d)\n"), + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].bank, + mcxt->gen.vfl_blocks[old_set_mapping_offset + i].block, __LINE__)); + goto return_error; + } + } + + BUF_Release(buf); + return TRUE32; + + return_error: + BUF_Release(buf); + return FALSE32; +} + +#endif // ! AND_READONLY + +static BOOL32 +_markBlockForReplacementNoProgram + (PPNVFL_MainCxt * mcxt, + UInt16 bank, + UInt16 block) +{ + UInt16 i; + + // check if the block is allready in the scrub list + for (i = 0; i < mcxt->gen.scrub_idx; i++) + { + if (mcxt->gen.scrub_list[i].block == block && mcxt->gen.scrub_list[i].bank == bank) + { + return TRUE32; + } + } + + if (mcxt->gen.scrub_idx >= PPNVFL_SCRUB_BLOCK_COUNT) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] scrub list is full bank 0x%X (line:%d)!\n"), + bank, __LINE__)); + return FALSE32; + } + + mcxt->gen.scrub_list[mcxt->gen.scrub_idx].block = block; + mcxt->gen.scrub_list[mcxt->gen.scrub_idx].bank = bank; + mcxt->gen.scrub_idx++; + + return TRUE32; +} + +#ifndef AND_READONLY + +static BOOL32 +_markBlockForReplacement + (PPNVFL_MainCxt * mcxt, + UInt16 bank, + UInt16 block) +{ + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + BOOL32 ret_val; + + if (_markBlockForReplacementNoProgram(mcxt, bank, block) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] fail _markBlockForReplacementNoProgram (bank:0x%X) (line:%d)!\n"), + bank, __LINE__)); + BUF_Release(buf); + return FALSE32; + } + + ret_val = _programCxtLastPage(mcxt, buf, TRUE32); + BUF_Release(buf); + + return ret_val; +} +#endif // AND_READONLY +/* block replacement functions - end */ + +/* + * Name: _analyzeMultiReadStatuses + * Description: this function analyzes the read operation statuses (used for multipage read) + * Input: number of pages read, mark for scrub + * Output: need refresh flag, operation result flag, clean flag + * Return value: none + */ +void +_analyzeMultiReadStatuses + (PPNVFL_MainCxt * mcxt, + UInt32 *vpn_array, + UInt8 *spare, + UInt32 *result_flags, + BOOL32 boolMarkForScrub, + UInt8 *pabSectorStats) +{ + UInt16 channel; + UInt16 phyCE; + BOOL32 last_failure_updated = FALSE32; + UInt32 stats_offset; + const UInt8 num_sectors = (mcxt->dev.main_bytes_per_page) / SECTOR_SIZE; //Number of kilobyte sector + + // look at the status + for (channel = 0; channel < mcxt->dev.num_channels; channel++) + { + UInt16 i; + + // locate the block that need to be replaced + for (i = 0; i < mcxt->commands[channel]->num_pages; i++) + { + PPNStatusType current_status = mcxt->commands[channel]->entry[i].status; + UInt32 current_result = 0, actions = 0; + switch (current_status) + { + case (PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_VALID | PPN_READ_STATUS_REFRESH): + case (PPN_READ_STATUS_VALID | PPN_READ_STATUS_RETIRE): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_RETIRE | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_CLEAN | PPN_READ_STATUS_VALID): + case (PPN_READ_STATUS_INVALID_DATA | PPN_READ_STATUS_GEB | PPN_READ_STATUS_VALID): + break; + + default: + current_result |= PPNVFL_READ_RES_UNIDENTIFIED; + break; + } + if (!(current_result & PPNVFL_READ_RES_UNIDENTIFIED)) + { + if (current_status & PPN_READ_STATUS_INVALID_DATA && + (!(current_status & PPN_READ_STATUS_CLEAN))) + { + current_result |= PPNVFL_READ_RES_UECC; + if(pabSectorStats) + { + stats_offset = (mcxt->commands[channel]->mem_index[i].offset) * num_sectors; + WMR_MEMSET(pabSectorStats + stats_offset, 0xFF, num_sectors); + } + } + if (current_status & PPN_READ_STATUS_CLEAN) + { + current_result |= PPNVFL_READ_RES_CLEAN; + if(pabSectorStats) + { + stats_offset = (mcxt->commands[channel]->mem_index[i].offset) * num_sectors; + WMR_MEMSET(pabSectorStats + stats_offset, 0xFE, num_sectors); + } + } + if (current_status & PPN_READ_STATUS_REFRESH) + { + current_result |= PPNVFL_READ_RES_REFRESH; + } + if (current_status & PPN_READ_STATUS_RETIRE) + { + current_result |= PPNVFL_READ_RES_RETIRE; + } + if (!(current_status & PPN_READ_STATUS_INVALID_DATA)) + { + current_result |= PPNVFL_READ_RES_VALID_DATA; + } + } + *result_flags |= current_result; + if (current_result & + (PPNVFL_READ_RES_REFRESH | PPNVFL_READ_RES_RETIRE | + PPNVFL_READ_RES_UECC | PPNVFL_READ_RES_UNIDENTIFIED)) + { + const UInt16 chip_enable_idx = mcxt->commands[channel]->entry[i].ceIdx; + const PageAddressType page = mcxt->commands[channel]->entry[i].addr.row; + UInt16 bank, block, page_offset; + BOOL32 slc; + UInt16 transaction_index = mcxt->commands[channel]->mem_index[i].offset; + UInt32 vpn = (vpn_array == NULL ? 0xFFFFFFFF : vpn_array[transaction_index]); + UInt8 *curr_spare = &spare[transaction_index * mcxt->dev.lba_meta_bytes_buffer]; + + // reverse the address to bank, block, page offset, slc type address + ppnMiscConvertPhysicalAddressToBankBlockPage(&mcxt->dev, channel, + chip_enable_idx, page, &bank, &block, + &page_offset, &slc); + + if ((!last_failure_updated) && (current_result & PPNVFL_READ_RES_UECC)) + { + actions |= 1; + last_failure_updated = TRUE32; + phyCE = ppnMiscGetCEFromBank(&mcxt->dev,bank); + _ReportFailure(VFLFailUECC, phyCE, page); + } + else if (current_result & VFL_READ_STATUS_REFRESH) + { + phyCE = ppnMiscGetCEFromBank(&mcxt->dev,bank); + _ReportFailure(VFLFailRefresh, phyCE, page); + } + +#ifndef AND_READONLY + if (boolMarkForScrub && (current_status & PPN_READ_STATUS_RETIRE)) + { + _markBlockForReplacement(mcxt, bank, block); + actions |= 2; + } +#endif // ! AND_READONLY + + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] reporting a read error status = 0x%X actions:0x%X vpn:0x%X result:0x%X (l:%d)\n"), + current_status, actions, vpn, current_result, __LINE__)); + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] bank:0x%X, block:0x%X, page_offset:0x%X, slc:0x%X\n"), + bank, block, page_offset, slc)); + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] channel:0x%X, chip_enable_idx:0x%X, page_address:0x%X\n"), + channel, chip_enable_idx, page)); + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] meta: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n"), + curr_spare[0], curr_spare[1], curr_spare[2], curr_spare[3], + curr_spare[4], curr_spare[5], curr_spare[6], curr_spare[7], + curr_spare[8], curr_spare[9], curr_spare[10], curr_spare[11], + curr_spare[12], curr_spare[13], curr_spare[14], curr_spare[15])); + } + } + } + + if ((*result_flags & + (PPNVFL_READ_RES_REFRESH | PPNVFL_READ_RES_RETIRE | + PPNVFL_READ_RES_UECC | PPNVFL_READ_RES_UNIDENTIFIED)) || + ((*result_flags & PPNVFL_READ_RES_CLEAN) && + (*result_flags & PPNVFL_READ_RES_VALID_DATA))) + { + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] *result_flags:0x%X (line:%d)\n"), *result_flags, __LINE__)); + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] st vpn ba blk ofs s ch ce len col row meta (line:%d)\n"), + __LINE__)); + for (channel = 0; channel < mcxt->dev.num_channels; channel++) + { + UInt16 i; + + // locate the block that need to be replaced + for (i = 0; i < mcxt->commands[channel]->num_pages; i++) + { + const PPNCommandEntry *entry = &mcxt->commands[channel]->entry[i]; + const PPNStatusType current_status = entry->status; + const UInt16 chip_enable_idx = entry->ceIdx; + const PageAddressType page = entry->addr.row; + const UInt16 transaction_index = mcxt->commands[channel]->mem_index[i].offset; + const UInt8 *curr_spare = &spare[transaction_index * mcxt->dev.lba_meta_bytes_buffer]; + const UInt32 vpn = (vpn_array == NULL ? 0xFFFFFFFF : vpn_array[transaction_index]); + UInt16 bank, block, page_offset; + BOOL32 slc; + + // reverse the address to bank, block, page offset, slc type address + ppnMiscConvertPhysicalAddressToBankBlockPage(&mcxt->dev, channel, + chip_enable_idx, page, &bank, &block, + &page_offset, &slc); + + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] %02X %08X %02X %04X %03X %01X %02X %02X" + " %04X %04X %08X" + " %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\n"), + current_status, vpn, bank, block, page_offset, slc, channel, chip_enable_idx, + entry->addr.length, entry->addr.column, entry->addr.row, + curr_spare[0], curr_spare[1], curr_spare[2], curr_spare[3], + curr_spare[4], curr_spare[5], curr_spare[6], curr_spare[7], + curr_spare[8], curr_spare[9], curr_spare[10], curr_spare[11], + curr_spare[12], curr_spare[13], curr_spare[14], curr_spare[15])); + } + } + } + if (!(*result_flags)) + { + WMR_PANIC("result flags: 0x%02x\n", *result_flags); + } +} + +static void +_copyMapPagesFromOnNandCxtToRam + (PPNVFL_MainCxt * mcxt, + UInt8 *data) +{ + UInt16 bank; + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)data; + + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + WMR_MEMCPY(mcxt->vfl_map_pages[bank], on_nand->banks[bank].vfl_map_pages, + mcxt->r_gen.pages_per_block_mapping * sizeof(UInt16)); + } +} + +static void +_copyFromOnNandCxtToRam + (PPNVFL_MainCxt * mcxt, + UInt8 *data) +{ + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)data; + + // copy gen + WMR_MEMCPY(&mcxt->gen, &on_nand->gen, sizeof(PPNVFL_GeneralCxt)); + // copy vfl map locations + _copyMapPagesFromOnNandCxtToRam(mcxt, data); +} + +#if !AND_READONLY + +static void +_copyFromRamToOnNandCxt + (PPNVFL_MainCxt * mcxt, + UInt8 *data) +{ + UInt16 bank; + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)data; + + WMR_MEMSET(data, 0, mcxt->dev.main_bytes_per_page); + // copy gen + WMR_MEMCPY(&on_nand->gen, &mcxt->gen, sizeof(PPNVFL_GeneralCxt)); + + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + WMR_MEMCPY(on_nand->banks[bank].vfl_map_pages, mcxt->vfl_map_pages[bank], + mcxt->r_gen.pages_per_block_mapping * sizeof(UInt16)); + } +} + +#endif // !AND_READONLY + +static UInt16 +_div2RoundUp + (UInt16 in) +{ + return (((in) & 0x1) == 1) ? (((in) >> 1) + 1) : ((in) >> 1); +} + +static Int32 +_readPageOfASet + (PPNVFL_MainCxt * mcxt, + UInt16 set, + UInt16 cxt_page_offset, + Buffer *buf, + UInt8 expected_bank, + UInt8 expected_idx) +{ + UInt16 redundant_copy; + PPNStatusType status; + UInt16 vfl_block_offset = 0; + UInt16 vfl_page_offset = 0; + BOOL32 clean = TRUE32; + const BOOL32 original_need_rewrite = mcxt->r_gen.need_rewrite; + + _convertVFLPageIdxToPhysicalPageBlockOffsets(mcxt, set, cxt_page_offset, + &vfl_block_offset, &vfl_page_offset); + + for (redundant_copy = 0; redundant_copy < mcxt->r_gen.vfl_blocks_redundancy; redundant_copy++) + { + const UInt16 bank = mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].bank; + const UInt16 block = mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].block; + PPNVFL_CxtSpare *cxt_spare = (PPNVFL_CxtSpare*) buf->pSpare; + + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_READ, PPN_NO_OPTIONS, + bank, block, vfl_page_offset, TRUE32, buf->pData, buf->pSpare); + + // check if this is not the first copy or if the copy is marked to be moved + if (((redundant_copy != 0) || + (status & (PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_RETIRE))) && + (set == mcxt->r_gen.next_cxt_block_offset)) + { + // avoid the prints when searching through clean pages... + // print only if we ran into none clean pages + if (!clean) + { + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] read a copy of the vfl cxt with status 0x%02X" + " set:%01d, copy:%01d, page_offset:0x%03X type:0x%02X (line:%d)\n"), + status, set, redundant_copy, cxt_page_offset, cxt_spare->spareType, __LINE__)); + } + + mcxt->r_gen.need_rewrite = TRUE32; + } + + // if this is not initial search for cxt we should take the indication + // for replacement from the device +#ifndef AND_READONLY + if ((status & PPN_READ_STATUS_RETIRE) && (!mcxt->r_gen.search_for_cxt)) + { + _markBlockForReplacementNoProgram(mcxt, bank, block); + } +#endif // ! AND_READONLY + + if (!(status & PPN_READ_STATUS_INVALID_DATA)) + { + UInt8 rps_status = 0; + + if (cxt_spare->spareType != PPNVFL_SPARE_TYPE_CXT) + { + rps_status |= RPS_STATUS_SPARE_TYPE_MISSMATCH; + } + + if ((expected_bank != cxt_spare->bank) && (expected_bank != PPNVFL_CXT_IGNORE_BANKIDX)) + { + rps_status |= RPS_STATUS_BANK_MISSMATCH; + } + + if ((expected_idx != cxt_spare->idx) && (expected_idx != PPNVFL_CXT_IGNORE_BANKIDX)) + { + rps_status |= RPS_STATUS_IDX_MISSMATCH; + } + + if (mcxt->r_gen.need_rewrite && (!original_need_rewrite)) + { + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] failed reading the first copy of the vfl cxt " + "(succeeded reading another copy) (line:%d)\n"), __LINE__)); + } + + if (rps_status == 0) + { + return ANDErrorCodeOk; + } + else + { + WMR_PRINT(VFLWARN, "problem reading a vfl cxt copy" + " rps_status:0x%02X, set:%01d, copy:%01d, page_offset:0x%03X" + " type:0x%02X bank:0x%02X idx:0x%02X\n", + rps_status, set, redundant_copy, cxt_page_offset, + cxt_spare->spareType, cxt_spare->bank, cxt_spare->idx); + mcxt->r_gen.need_rewrite = TRUE32; + } + } + + if (!(status & PPN_READ_STATUS_CLEAN)) + { + clean = FALSE32; + } + } + + if (clean) + { + mcxt->r_gen.need_rewrite = original_need_rewrite; + return ANDErrorCodeCleanOk; + } + + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] failed to read a single vfl cxt copy (UECC) (line:%d)\n"), __LINE__)); + mcxt->r_gen.need_rewrite = TRUE32; + return ANDErrorCodeUserDataErr; +} + +static Int32 +_readSingleRedundancyPageOfASet + (PPNVFL_MainCxt *mcxt, + UInt16 set, + UInt16 cxt_page_offset, + UInt16 redundant_copy, + Buffer *buf) +{ + PPNStatusType status; + UInt16 vfl_block_offset = 0, vfl_page_offset = 0, bank = 0xFFFF, block = 0xFFFF; + + _convertVFLPageIdxToPhysicalPageBlockOffsets(mcxt, set, cxt_page_offset, + &vfl_block_offset, &vfl_page_offset); + + bank = mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].bank; + block = mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].block; + + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_READ, + PPN_NO_OPTIONS, bank, block, vfl_page_offset, TRUE32, buf->pData, buf->pSpare); + + // check if this is not the first copy or if the copy is marked to be moved + if ((status & (PPN_READ_STATUS_REFRESH | PPN_READ_STATUS_RETIRE)) && + (set == mcxt->r_gen.next_cxt_block_offset)) + { + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] _readSingleRedundancyPageOfASet got status:0x%02X from " + "redundant_copy:0x%04X set:0x%04X cxt_page_offset:0x%04X (line:%d)\n"), + status, redundant_copy, set, cxt_page_offset, __LINE__)); + mcxt->r_gen.need_rewrite = TRUE32; + } + + // if this is not initial search for cxt we should take the indication + // for replacement from the device + if ((status & PPN_READ_STATUS_RETIRE) && (!mcxt->r_gen.search_for_cxt)) + { + _markBlockForReplacementNoProgram(mcxt, bank, block); + } + + if (!(status & PPN_READ_STATUS_INVALID_DATA)) + { + PPNVFL_CxtSpare *cxt_spare = (PPNVFL_CxtSpare*) buf->pSpare; + if (cxt_spare->spareType == PPNVFL_SPARE_TYPE_CXT) + { + return ANDErrorCodeOk; + } + else + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] _readSingleRedundancyPageOfASet got ok status " + "but wrong sparetype 0x%02X (line:%d)\n"), + cxt_spare->spareType, __LINE__)); + return ANDErrorCodeUserDataErr; + } + } + + if (status & PPN_READ_STATUS_CLEAN) + { + return ANDErrorCodeCleanOk; + } + + return ANDErrorCodeUserDataErr; +} + +/* vfl cxt management functions - start */ +/* + * Name: _findOnNANDCxt + * Description: this function find the current cxt per bank and update the information + * in ram. + * Input: bank + * Return value: TRUE32 is successful, FALSE32 otherwise. + */ +#define PPNVFL_PRINT_FINDVFLCXT_SUMMARY (1) +#define PPNVFL_PRINT_FINDVFLCXT_MORE_INFO (1) + +static BOOL32 +_findOnNANDCxt + (PPNVFL_MainCxt * mcxt) +{ + Buffer *buf, *buf2; + UInt16 bank, page, start_page, mid_page, end_page, block_idx, vfl_cxt_idx, cxt_blocks_idx; + PPNStatusType status; + PPNVFL_CxtSpare spare0, spare1; + BOOL32 found_valid_cxt; + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + buf2 = BUF_Get(BUF_MAIN_AND_SPARE); + + // find the first written VFLCxt + found_valid_cxt = FALSE32; + for (block_idx = 0; ((!found_valid_cxt) && (block_idx < mcxt->dev.blocks_per_cau)); block_idx++) + { + if (PPNVFL_CONTEXT_BLOCK_LIMIT(&mcxt->dev) == block_idx) + { + // we don't want to panic, we just want to complain loudly for debug purposes + WMR_PRINT(ERROR, "VFL context not found yet... %lu of %lu sublks checked...\n", + block_idx, mcxt->dev.blocks_per_cau); + } + for (bank = 0; ((!found_valid_cxt) && (bank < mcxt->dev.num_of_banks)); bank++) + { + UInt16 keepout = (ppnMiscGetCAUFromBank(&mcxt->dev, bank) ? 0 : + WMR_MAX(mcxt->r_gen.keepout, 1)); + PPNVFL_CxtSpare *cxt_spare = (PPNVFL_CxtSpare*)buf->pSpare; + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_READ, PPN_NO_OPTIONS, + bank, (block_idx + keepout), 0, TRUE32, buf->pData, buf->pSpare); + if ((!(status & PPN_READ_STATUS_INVALID_DATA)) && + cxt_spare->spareType == PPNVFL_SPARE_TYPE_CXT && + cxt_spare->idx == PPNVFL_CXT_LAST_BANKIDX) + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf->pData; + WMR_MEMCPY(mcxt->gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(BlockAddress) * mcxt->r_gen.num_of_vfl_blocks)); + mcxt->r_gen.cxt_age = cxt_spare->cxt_age; + found_valid_cxt = TRUE32; + break; + } + } + } + if (!found_valid_cxt) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] could not find a single copy of VFLCxt (l:%d)\n"), __LINE__)); + goto error_return; + } + + // agree on the location of the VFLCxt blocks - find the latest blocks and see that they all point to the same VFL + // blocks + found_valid_cxt = FALSE32; + do + { + for (vfl_cxt_idx = 0; vfl_cxt_idx < mcxt->r_gen.num_of_vfl_blocks; vfl_cxt_idx++) + { + PPNVFL_CxtSpare *cxt_spare = (PPNVFL_CxtSpare*)buf->pSpare; + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_READ, + PPN_NO_OPTIONS, + mcxt->gen.vfl_blocks[vfl_cxt_idx].bank, + mcxt->gen.vfl_blocks[vfl_cxt_idx].block, + 0, TRUE32, buf->pData, buf->pSpare); + if ((!(status & PPN_READ_STATUS_INVALID_DATA)) && + cxt_spare->spareType == PPNVFL_SPARE_TYPE_CXT && + cxt_spare->idx == 0xFF && + mcxt->r_gen.cxt_age > cxt_spare->cxt_age) + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf->pData; + WMR_MEMCPY(mcxt->gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(BlockAddress) * mcxt->r_gen.num_of_vfl_blocks)); + mcxt->r_gen.cxt_age = cxt_spare->cxt_age; + break; + } + } + if (vfl_cxt_idx == mcxt->r_gen.num_of_vfl_blocks) + { + found_valid_cxt = TRUE32; + } + } + while (!found_valid_cxt); + + // use spare0 for the 1st pair and spare1 for the 2nd + WMR_MEMSET(&spare0, 0, sizeof(PPNVFL_CxtSpare)); + WMR_MEMSET(&spare1, 0, sizeof(PPNVFL_CxtSpare)); + + // read the 1st set + if (_readPageOfASet(mcxt, 0, 0, buf, PPNVFL_CXT_IGNORE_BANKIDX, PPNVFL_CXT_LAST_BANKIDX) == ANDErrorCodeOk) + { + WMR_MEMCPY(&spare0, buf->pSpare, sizeof(PPNVFL_CxtSpare)); + } + + // read the 2nd set + if (_readPageOfASet(mcxt, 1, 0, buf2, PPNVFL_CXT_IGNORE_BANKIDX, PPNVFL_CXT_LAST_BANKIDX) == ANDErrorCodeOk) + { + WMR_MEMCPY(&spare1, buf2->pSpare, sizeof(PPNVFL_CxtSpare)); + } + + // make a decision which pair of VFLCxt blcoks is current one and use it + if (spare0.spareType == PPNVFL_SPARE_TYPE_CXT && spare1.spareType == PPNVFL_SPARE_TYPE_CXT) + { + // assume that if we have two valid copies the older one is good + // as soon as we have a good good set in a new block we should erase the + // old block + if ((UInt32)spare0.cxt_age < (UInt32)spare1.cxt_age) + { + mcxt->r_gen.next_cxt_block_offset = 0; + VFL_INF_PRINT(PPNVFL_PRINT_FINDVFLCXT_MORE_INFO, + (TEXT( + "[PPNVFL:INF] _findOnNANDCxt(0x%04X) AGE0 0x%X, age1 0x%X, type0 0x%X, type1 0x%X (line:%d)\n"), + bank, spare0.cxt_age, spare1.cxt_age, spare0.spareType, spare1.spareType, __LINE__)); + } + else + { + mcxt->r_gen.next_cxt_block_offset = 1; + VFL_INF_PRINT(PPNVFL_PRINT_FINDVFLCXT_MORE_INFO, + (TEXT( + "[PPNVFL:INF] _findOnNANDCxt(0x%04X) age0 0x%X, AGE1 0x%X, type0 0x%X, type1 0x%X (line:%d)\n"), + bank, spare0.cxt_age, spare1.cxt_age, spare0.spareType, spare1.spareType, __LINE__)); + } + } + else if (spare0.spareType == PPNVFL_SPARE_TYPE_CXT) + { + mcxt->r_gen.next_cxt_block_offset = 0; + } + else if (spare1.spareType == PPNVFL_SPARE_TYPE_CXT) + { + mcxt->r_gen.next_cxt_block_offset = 1; + } + else + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] could not find a single copy of VFLCxt (bank:0x%X) (l:%d)\n"), + bank, __LINE__)); + goto error_return; + } + + // make sure the block list is up to date + if (mcxt->r_gen.next_cxt_block_offset) + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf2->pData; + WMR_MEMCPY(mcxt->gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(BlockAddress) * mcxt->r_gen.num_of_vfl_blocks)); + } + else + { + PPNVFL_OnNANDCxt * on_nand = (PPNVFL_OnNANDCxt*)buf->pData; + WMR_MEMCPY(mcxt->gen.vfl_blocks, on_nand->gen.vfl_blocks, + (sizeof(BlockAddress) * mcxt->r_gen.num_of_vfl_blocks)); + } + + // search for the latest version of the VFLCxt inside the current VFLCxt block pair + start_page = 0; + end_page = mcxt->r_gen.vfl_pages_per_set - 1; + found_valid_cxt = FALSE32; + + while (end_page >= start_page) + { + PPNVFL_CxtSpare *spare = (PPNVFL_CxtSpare*)buf->pSpare; + mid_page = _div2RoundUp(end_page + start_page); + Int32 read_status = _readPageOfASet(mcxt, mcxt->r_gen.next_cxt_block_offset, mid_page, + buf, PPNVFL_CXT_IGNORE_BANKIDX, PPNVFL_CXT_IGNORE_BANKIDX); + + if (read_status == ANDErrorCodeOk) + { + if (start_page == end_page) + { + if (spare->idx == PPNVFL_CXT_LAST_BANKIDX) + { + mcxt->r_gen.cxt_age = spare->cxt_age; + mcxt->r_gen.next_cxt_page_offset = start_page + 1; + + _copyFromOnNandCxtToRam(mcxt, buf->pData); + + // verify the last page we wrote is valid + if (_readSingleRedundancyPageOfASet(mcxt, mcxt->r_gen.next_cxt_block_offset, start_page, + (mcxt->r_gen.vfl_blocks_redundancy - 1), buf) != ANDErrorCodeOk) + { + mcxt->r_gen.need_rewrite = TRUE32; + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] could not find vfl cxt in the last redundancy copy (line:%d)\n"), + __LINE__)); + } + + found_valid_cxt = TRUE32; + break; + } + else + { + mcxt->r_gen.need_rewrite = TRUE32; + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] could not find cxt in bubble search (line:%d)\n"), __LINE__)); + break; + } + } + else + { + start_page = mid_page; + continue; + } + } + + if (read_status == ANDErrorCodeCleanOk) + { + end_page = mid_page - 1; + continue; + } + + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] deteteced vfl cxt pages with user data errors (l:%d)\n"), __LINE__)); + end_page = mid_page; + mcxt->r_gen.need_rewrite = TRUE32; + break; + } + + for (cxt_blocks_idx = 0; (cxt_blocks_idx < 2) && (!found_valid_cxt); cxt_blocks_idx++) + { + for (page = (mcxt->r_gen.vfl_pages_per_set - 1); (page != 0) && (!found_valid_cxt); page--) + { + PPNVFL_CxtSpare *spare = (PPNVFL_CxtSpare*)buf->pSpare; + + Int32 read_status = _readPageOfASet(mcxt, mcxt->r_gen.next_cxt_block_offset, page, buf, + PPNVFL_CXT_IGNORE_BANKIDX, PPNVFL_CXT_LAST_BANKIDX); + + if (read_status == ANDErrorCodeCleanOk) + { + continue; + } + + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] Reading cxt next_cxt_block_offset:0x%04X, page:0x%04X read_status:0x%08X (line:%d)\n"), + mcxt->r_gen.next_cxt_block_offset, page, read_status, __LINE__)); + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] spareType:0x%02X, bank:0x%02X, idx:0x%02X cxt_age:0x%08X (line:%d)\n"), + spare->spareType, spare->bank, spare->idx, spare->cxt_age, __LINE__)); + + if (read_status == ANDErrorCodeOk) + { + mcxt->r_gen.cxt_age = spare->cxt_age; + _copyFromOnNandCxtToRam(mcxt, buf->pData); + found_valid_cxt = TRUE32; + break; + } + } + if (!found_valid_cxt) + { + // switch to the other cxt set + mcxt->r_gen.next_cxt_block_offset = (mcxt->r_gen.next_cxt_block_offset == 1 ? 0 : 1); + } + } + + if (!found_valid_cxt) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] unable to find vfl cxt copy on the device (line:%d)\n"), __LINE__)); + goto error_return; + } + + if (mcxt->gen.num_of_ftl_sublk > mcxt->gen.num_of_vfl_sublk) + { + VFL_ERR_PRINT((TEXT("FTLSuBlks(=%d) > VFLSuBlks(=%d)\n"), mcxt->gen.num_of_ftl_sublk, mcxt->gen.num_of_vfl_sublk)); + goto error_return; + } + + VFL_INF_PRINT(PPNVFL_PRINT_FINDVFLCXT_SUMMARY, + (TEXT("[PPNVFL:INF] _findOnNANDCxt(0x%04X) block 0x%X, page 0x%X, age 0x%X(line:%d)\n"), + bank, mcxt->r_gen.next_cxt_block_offset, mcxt->r_gen.next_cxt_page_offset, + mcxt->r_gen.cxt_age, __LINE__)); + BUF_Release(buf); + BUF_Release(buf2); + return TRUE32; + + error_return: + BUF_Release(buf); + BUF_Release(buf2); + return FALSE32; +} + +/* + * Name: _readVFLCxtPage + * Description: reads a single VFL Cxt page (either mapping or VFLCxt struct) + * Input: buffer, bank, index (what page to read). + * Return value: TRUE32 is successful, FALSE32 otherwise. + */ +#define PPNVFL_PRINT_READVFLCXT_SUMMARY (0) + +static BOOL32 +_readVFLCxtPage + (PPNVFL_MainCxt * mcxt, + Buffer *buf, + UInt16 bank, + UInt16 vfl_idx) +{ + PPNVFL_CxtSpare *spare = (PPNVFL_CxtSpare*)buf->pSpare; + Int32 read_status; + const UInt16 set = ((mcxt->vfl_map_pages[bank][vfl_idx] & 0x8000) >> 15); + const UInt16 cxt_page_offset = (mcxt->vfl_map_pages[bank][vfl_idx] & 0x7FFF); + + VFL_INF_PRINT(PPNVFL_PRINT_READVFLCXT_SUMMARY, + (TEXT("[PPNVFL:INF] readVFLCxtPage(0x%04X, 0x%04X) (line:%d)\n"), bank, vfl_idx, __LINE__)); + + read_status = _readPageOfASet(mcxt, set, cxt_page_offset, buf, PPNVFL_CXT_IGNORE_BANKIDX, vfl_idx); + + if (read_status != ANDErrorCodeOk) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] Error reading cxt copies status 0x%X spareType 0x%02X index 0x%02X" + " requested index 0x%02X bank 0x%02X requested bank 0x%02X age 0x%08X (line:%d)\n"), + read_status, spare->spareType, spare->idx, (UInt8)vfl_idx, spare->bank, (UInt8)bank, + spare->cxt_age, __LINE__)); + return FALSE32; + } + return TRUE32; +} + +static void +_convertVFLPageIdxToPhysicalPageBlockOffsets + (PPNVFL_MainCxt * mcxt, + UInt16 set, + UInt16 vfl_page_idx, + UInt16 *vfl_block_offset, + UInt16 *vfl_page_offset) +{ + const UInt16 vfl_block_depth = (vfl_page_idx / mcxt->dev.pages_per_block_slc); + + *vfl_block_offset = ((set * mcxt->r_gen.vfl_blocks_redundancy * mcxt->r_gen.vfl_blocks_depth) + + (vfl_block_depth * mcxt->r_gen.vfl_blocks_redundancy)); + *vfl_page_offset = vfl_page_idx % mcxt->dev.pages_per_block_slc; +} + +#ifndef AND_READONLY + +/* + * Name: _programVFLCxtPage + * Description: programs a single VFL Cxt page (either mapping or VFLCxt struct) + * Input: buffer, bank, index (what page to read). + * Return value: TRUE32 is successful, FALSE32 otherwise. + */ +#define PPNVFL_PRINT_PROGRAMVFLCXT_SUMMARY (1) +#define PPNVFL_PRINT_PROGRAMVFLCXT_ADDRESSES (1) + +static BOOL32 +_programVFLCxtPage + (PPNVFL_MainCxt * mcxt, + Buffer *buf, + UInt16 bank, + UInt16 vfl_idx) +{ + PPNStatusType status; + UInt16 redundant_copy, set = mcxt->r_gen.next_cxt_block_offset; + UInt16 vfl_block_offset, vfl_page_offset; + + VFL_INF_PRINT(PPNVFL_PRINT_PROGRAMVFLCXT_SUMMARY, + (TEXT("[PPNVFL:INF] programVFLCxtPage(0x%04X, 0x%04X) page_offset:0x%X set:0x%X age:0x%08X (l:%d)\n"), + bank, vfl_idx, mcxt->r_gen.next_cxt_page_offset, set, mcxt->r_gen.cxt_age, __LINE__)); + + _setVFLCxtSpare(mcxt, buf->pSpare, bank, vfl_idx); + + _convertVFLPageIdxToPhysicalPageBlockOffsets(mcxt, set, mcxt->r_gen.next_cxt_page_offset, + &vfl_block_offset, &vfl_page_offset); + + for (redundant_copy = 0; ((redundant_copy < mcxt->r_gen.vfl_blocks_redundancy) && + (!mcxt->r_gen.need_rewrite)); redundant_copy++) + { + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_PROGRAM, + PPN_NO_OPTIONS, + mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].bank, + mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].block, + vfl_page_offset, TRUE32, buf->pData, buf->pSpare); + if (status & (PPN_PROGRAM_STATUS_FAIL | PPN_PROGRAM_STATUS_GEB)) + { + mcxt->r_gen.need_rewrite = TRUE32; + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] status 0x%X marking vflcxt block for scrubbing(bank:0x%X, block:0x%X) (line:%d)\n"), + status, + mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].bank, + mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].block, + __LINE__)); + _markBlockForReplacementNoProgram(mcxt, + mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].bank, + mcxt->gen.vfl_blocks[vfl_block_offset + redundant_copy].block); + } + } + if (mcxt->r_gen.need_rewrite) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed _programVFLCxtPage mcxt->r_gen.need_rewrite is true (line:%d)\n"), + __LINE__)); + return FALSE32; + } + if (vfl_idx != PPNVFL_CXT_LAST_BANKIDX) + { + mcxt->vfl_map_pages[bank][vfl_idx] = (mcxt->r_gen.next_cxt_page_offset | + ((mcxt->r_gen.next_cxt_block_offset & 0x0001) << 15)); + } + + mcxt->r_gen.next_cxt_page_offset++; + mcxt->r_gen.cxt_age--; + + return TRUE32; +} + +static ProgramVFLCxtPageWrapStatus +_programVFLCxtPageWrap + (PPNVFL_MainCxt * mcxt, + Buffer *buf, + UInt16 bank, + UInt16 vfl_idx) +{ + VFL_INF_PRINT(PPNVFL_PRINT_PROGRAMVFLCXT_SUMMARY, + (TEXT("[PPNVFL:INF] programVFLCxtPageWrap(0x%04X, 0x%04X) (line:%d)\n"), bank, vfl_idx, __LINE__)); + if (mcxt->r_gen.next_cxt_page_offset == mcxt->r_gen.vfl_pages_per_set || + mcxt->r_gen.need_rewrite) + { + VFL_WRN_PRINT((TEXT("[PPNVFL:WRN] Changing PPNVFL Cxt blocks pair ()\n"))); + if (_copyVFLCxtToOtherPair(mcxt) == FALSE32) + { + return VFLCxtProgramFail; + } + // if this is the last page, assume the copy function wrote it + if (vfl_idx == PPNVFL_CXT_LAST_BANKIDX) + { + return VFLCxtProgramDone; + } + return VFLCxtProgramRetry; + } + + return _programVFLCxtPage(mcxt, buf, bank, vfl_idx) ? VFLCxtProgramDone : VFLCxtProgramRetry; +} + +#define PPNVFL_PRINT_COPYVFLCXT_SUMMARY (1) + +static BOOL32 +_checkForVFLBlocksInScrubList + (PPNVFL_MainCxt * mcxt, + UInt16 new_set_location, + BOOL32 *replace_blocks_array, + BOOL32 *replace_in_new_set) +{ + const UInt16 blocks_per_vfl_set = (mcxt->r_gen.num_of_vfl_blocks >> 1); + const UInt16 new_set_mapping_offset = new_set_location * blocks_per_vfl_set; + + if (mcxt->gen.scrub_idx) + { + UInt16 scrub_idx, idx; + for (scrub_idx = 0; scrub_idx < mcxt->gen.scrub_idx; scrub_idx++) + { + for (idx = 0; idx < blocks_per_vfl_set; idx++) + { + if ((mcxt->gen.scrub_list[scrub_idx].block == + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].block) && + (mcxt->gen.scrub_list[scrub_idx].bank == mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].bank)) + { + if (*replace_in_new_set) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] more than one block to replace in the vfl cxt (0x%04X) (line:%d)\n"), + __LINE__)); + return FALSE32; + } + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] vfl cxt block replacement - found a vfl cxt block in the scrub list (bank: 0x%X, block: 0x%X, idx: 0x%X) (line:%d)\n"), + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].block, idx, __LINE__)); + replace_blocks_array[idx] = TRUE32; + *replace_in_new_set = TRUE32; + } + } + } + } + return TRUE32; +} + +// _copyVFLCxtToOtherPair - Use this function to copy the current vfl cxt from the pair it +// resides in to the other pair (either due to program failure or due to lack of space) +static BOOL32 +_copyVFLCxtToOtherPair + (PPNVFL_MainCxt * mcxt) +{ + UInt16 idx, bank; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + Buffer *buf_mcxt_copy = BUF_Get(BUF_MAIN_AND_SPARE); + PPNStatusType status; + BOOL32 replace_blocks[PPNVFL_MAX_INFO_BLOCK_COUNT >> 1] = { FALSE32 }; + BOOL32 replace_in_new_set = FALSE32; + const UInt16 blocks_per_vfl_set = (mcxt->r_gen.num_of_vfl_blocks >> 1); + const UInt16 new_set_location = (mcxt->r_gen.next_cxt_block_offset == 1 ? 0 : 1); + const UInt16 new_set_mapping_offset = new_set_location * blocks_per_vfl_set; + + VFL_INF_PRINT(PPNVFL_PRINT_COPYVFLCXT_SUMMARY, + (TEXT("[PPNVFL:INF] _copyVFLCxtToOtherPair - original cxt set 0x%x, age 0x%X (line:%d)\n"), + mcxt->r_gen.next_cxt_block_offset, mcxt->r_gen.cxt_age, __LINE__)); + + if (buf == NULL || buf_mcxt_copy == NULL) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed allocating buf (line:%d)\n"), __LINE__)); + goto return_error; + } + + // make a copy of the vfl map pages (case things go bad) + _copyFromRamToOnNandCxt(mcxt, buf_mcxt_copy->pData); + + // check if there are replacement in the new pair + if (!_checkForVFLBlocksInScrubList(mcxt, new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + + mcxt->r_gen.need_rewrite = FALSE32; + // erase the set of blocks we want to use + if (!replace_in_new_set) + { + for (idx = 0; idx < blocks_per_vfl_set; idx++) + { + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].block, + 0, + TRUE32, NULL, NULL); + + if (status & PPN_ERASE_STATUS_RETIRE) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with retire status (line:%d)\n"), + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].block, __LINE__)); + replace_blocks[idx] = TRUE32; + replace_in_new_set = TRUE32; + } + else if (status & PPN_ERASE_STATUS_FAIL) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed erase vflcxt block (bank:0x%04X, block: 0x%04X) with no retire status (line:%d)\n"), + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].bank, + mcxt->gen.vfl_blocks[new_set_mapping_offset + idx].block, __LINE__)); + goto return_error; + } + } + } + mcxt->r_gen.next_cxt_block_offset = new_set_location; + mcxt->r_gen.next_cxt_page_offset = 0; + + if ((!replace_in_new_set) && (!_programCxtLastPage(mcxt, buf, FALSE32))) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed _programCxtLastPage inside _copyVFLCxtToOtherPair() (line:%d)\n"), + __LINE__)); + if (!_checkForVFLBlocksInScrubList(mcxt, new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + if (!replace_in_new_set) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed _programVFLCxtPage but no blocks in scrub list (line:%d)\n"), + __LINE__)); + goto return_error; + } + } + + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + for (idx = 0; ((!replace_in_new_set) && + (idx < mcxt->r_gen.pages_per_block_mapping)); idx++) + { + if (!_readVFLCxtPage(mcxt, buf, bank, idx)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed _readVFLCxtPage inside _copyVFLCxtToOtherPair () (line:%d)\n"), + __LINE__)); + goto return_error; + } + if (!_programVFLCxtPage(mcxt, buf, bank, idx)) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed _programVFLCxtPage inside _copyVFLCxtToOtherPair () (line:%d)\n"), + __LINE__)); + if (!_checkForVFLBlocksInScrubList(mcxt, new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + if (!replace_in_new_set) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed _programVFLCxtPage but no blocks in scrub list (line:%d)\n"), + __LINE__)); + goto return_error; + } + } + } + } + if ((!replace_in_new_set) && (!_programCxtLastPage(mcxt, buf, FALSE32))) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed _programCxtLastPage inside _copyVFLCxtToOtherPair() (line:%d)\n"), + __LINE__)); + if (!_checkForVFLBlocksInScrubList(mcxt, new_set_location, replace_blocks, &replace_in_new_set)) + { + goto return_error; + } + if (!replace_in_new_set) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] failed _programVFLCxtPage but no blocks in scrub list (line:%d)\n"), + __LINE__)); + goto return_error; + } + } + + if (replace_in_new_set) + { + for (idx = 0; idx < blocks_per_vfl_set; idx++) + { + if (replace_blocks[idx]) + { + // revert the map (case the error happen while programming the new set and mapping is off) + _copyMapPagesFromOnNandCxtToRam(mcxt, buf_mcxt_copy->pData); + + BUF_Release(buf); + buf = NULL; + BUF_Release(buf_mcxt_copy); + buf_mcxt_copy = NULL; + // handle errors in working with the new pair + if (!_replaceErasedCxtBlock(mcxt, (new_set_mapping_offset + idx))) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] need to replace flag is set but nothing is marked for replacement (idx:0x%X) (line:%d)\n"), + idx, __LINE__)); + goto return_error; + } + break; + } + } + if (idx == blocks_per_vfl_set) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] need to replace flag is set but nothing is marked for replacement (idx:0x%X) (line:%d)\n"), + idx, __LINE__)); + goto return_error; + } + } + + if (buf != NULL) + { + BUF_Release(buf); + } + if (buf_mcxt_copy != NULL) + { + BUF_Release(buf_mcxt_copy); + } + return TRUE32; + + return_error: + if (buf != NULL) + { + BUF_Release(buf); + } + if (buf_mcxt_copy != NULL) + { + BUF_Release(buf_mcxt_copy); + } + return FALSE32; +} + +static BOOL32 +_programCxtLastPage + (PPNVFL_MainCxt * mcxt, + Buffer * buf, + BOOL32 retry) +{ + ProgramVFLCxtPageWrapStatus program_status; + + do + { + _copyFromRamToOnNandCxt(mcxt, buf->pData); + program_status = _programVFLCxtPageWrap(mcxt, buf, PPNVFL_CXT_LAST_BANKIDX, PPNVFL_CXT_LAST_BANKIDX); + } + while ((program_status == VFLCxtProgramRetry) && retry); + + return (program_status != VFLCxtProgramDone) ? FALSE32 : TRUE32; +} + +/* + * Name: _ppnvflChangeFTLCxtVbn + * Description: implements ChangeFTLCxt for the vfl I/F + * Input: new ftl cxt array + * Return value: ANDErrorCodeOk if successful + */ +#define PPNVFL_PRINT_SET_NUM_OF_FTL_SUBLKS_SUMMARY (1) +static BOOL32 +_setNumOfFTLSuBlks + (PPNVFL_MainCxt * mcxt, + UInt16 num_of_ftl_sublk) +{ + BOOL32 res; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (num_of_ftl_sublk > mcxt->gen.num_of_vfl_sublk) + { + WMR_PANIC("invalid burnin-size settings: %d FTL, %d VFL sublks", num_of_ftl_sublk, mcxt->gen.num_of_vfl_sublk); + } + + VFL_INF_PRINT(PPNVFL_PRINT_SET_NUM_OF_FTL_SUBLKS_SUMMARY, + (TEXT("[PPNVFL:INF] _setNumOfFTLSuBlks (0x%04X)\n"), num_of_ftl_sublk)); + mcxt->gen.num_of_ftl_sublk = num_of_ftl_sublk; + + res = _programCxtLastPage(mcxt, buf, TRUE32); + BUF_Release(buf); + + return res; +} + +/* vfl cxt management functions - end */ + +#endif // ! AND_READONLY + +/* vfl I/F implementation - start */ +/* + * Name: _ppnvflInit + * Description: this function initialize the memory and structures for ppnvfl + * Input: fpart function table + * Return value: ANDErrorCodeOk if successfull + */ +static Int32 +_ppnvflInit + (PPNVFL_MainCxt * mcxt, + FPartFunctions * pFPartFunctions) +{ + UInt32 i; + UInt16 pages_per_vfl_cxt_copy; // including the cxt and mapping + + if (mcxt->initialized) + { + return TRUE32; + } + + WMR_ASSERT(sizeof(PPNVFL_CxtSpare) == 16); + + mcxt->fpart = pFPartFunctions; + mcxt->fil = mcxt->fpart->GetLowFuncTbl(); + + ppnMiscFillDevStruct(&mcxt->dev, mcxt->fil); + WMR_ASSERT(mcxt->dev.lbas_per_page == 1); + mcxt->single_command = (PPNCommandStruct*)mcxt->fpart->GetSingleCommandStruct(); + + // allocating the memory for the CAUs structures + // this code may later on move to open + if (mcxt->dev.num_channels == 0 || mcxt->dev.ces_per_channel == 0 || mcxt->dev.caus_per_ce == 0) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] _ppnvflInit num_channels 0x%X ces_per_channel 0x%X caus_per_ce 0x%X\n"), + mcxt->dev.num_channels, mcxt->dev.ces_per_channel, mcxt->dev.caus_per_ce)); + } + + mcxt->r_gen.pages_per_block_mapping = 1; + i = mcxt->dev.blocks_per_cau * sizeof(P2BlockUsageType); + while (i > mcxt->dev.main_bytes_per_page) + { + i -= mcxt->dev.main_bytes_per_page; + mcxt->r_gen.pages_per_block_mapping++; + } + mcxt->r_gen.pbns_per_cxt_mapping_page = mcxt->dev.main_bytes_per_page / sizeof(P2BlockUsageType); + + // calculate vfl cxt on nand - depth, redundancy and pages per set + mcxt->r_gen.vfl_blocks_redundancy = 4; + // make sure that we have at least twice as many entries as needed for a single copy of vflcxt and + // all the mapping + pages_per_vfl_cxt_copy = 1 + (mcxt->r_gen.pages_per_block_mapping * mcxt->dev.num_of_banks); + mcxt->r_gen.vfl_blocks_depth = 1; + while ((UInt16)(mcxt->r_gen.vfl_blocks_depth * (UInt16)mcxt->dev.pages_per_block_slc) < + (UInt32)(pages_per_vfl_cxt_copy * PPNVFL_NUM_OF_VFL_CXT_BLOCK_SETS)) + { + mcxt->r_gen.vfl_blocks_depth++; + } + mcxt->r_gen.vfl_pages_per_set = (mcxt->r_gen.vfl_blocks_depth * mcxt->dev.pages_per_block_slc); + mcxt->r_gen.num_of_vfl_blocks = (mcxt->r_gen.vfl_blocks_depth * mcxt->r_gen.vfl_blocks_redundancy * + PPNVFL_NUM_OF_VFL_CXT_BLOCK_SETS); + + mcxt->gen.num_of_vfl_sublk = _calcNumOfVFLSuBlk(mcxt); + mcxt->gen.num_of_ftl_sublk = mcxt->gen.num_of_vfl_sublk; + mcxt->r_gen.cxt_age = 0xFFFFFFFF; + mcxt->vfl_map_pages = (UInt16**)WMR_MALLOC(sizeof(UInt16*) * mcxt->dev.num_of_banks); + mcxt->vfl_map_pages[0] = (UInt16*)WMR_MALLOC(sizeof(UInt16) * mcxt->dev.num_of_banks * + mcxt->r_gen.pages_per_block_mapping); + for (i = 1; i < mcxt->dev.num_of_banks; i++) + { + mcxt->vfl_map_pages[i] = &mcxt->vfl_map_pages[0][mcxt->r_gen.pages_per_block_mapping * i]; + } + mcxt->r_banks = (PPNVFL_BankRAMCxt*)WMR_MALLOC(sizeof(PPNVFL_BankRAMCxt) * mcxt->dev.num_of_banks); + mcxt->v2p_main = (UInt16*)WMR_MALLOC(sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk); + mcxt->mixed_entries = 0; + mcxt->v2p_mixed = (MixedEntryType*)WMR_MALLOC(_getV2PMixedArraySize(mcxt)); + + WMR_MEMSET(mcxt->v2p_main, 0xFF, (sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk)); + WMR_MEMSET(mcxt->v2p_mixed, 0xFF, _getV2PMixedArraySize(mcxt)); + + // allocate memory for the commands + WMR_ASSERT(mcxt->dev.num_of_banks <= PPNVFL_MAX_SUPPORTED_BANKS); + WMR_BufZone_Init(&mcxt->bufzone); + for (i = 0; i < mcxt->dev.num_channels; i++) + { + mcxt->commands[i] = (PPNCommandStruct *)WMR_Buf_Alloc_ForDMA(&mcxt->bufzone, sizeof(PPNCommandStruct)); + } + WMR_BufZone_FinishedAllocs(&mcxt->bufzone); + + for (i = 0; i < mcxt->dev.num_channels; i++) + { + WMR_BufZone_Rebase(&mcxt->bufzone, (void **)&mcxt->commands[i]); + WMR_ASSERT(mcxt->commands[i] != NULL); + } + WMR_BufZone_FinishedRebases(&mcxt->bufzone); + + if (mcxt->dev.ces_per_channel > 1) + { + mcxt->reorder = (PPNReorderStruct*)WMR_MALLOC(sizeof(PPNReorderStruct)); + } + else + { + mcxt->reorder = NULL; + } + +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&mcxt->stat, 0, sizeof(PPNVFLStatistics)); +#endif + + mcxt->initialized = TRUE32; + return ANDErrorCodeOk; +} + +/* + * Name: _ppnvflOpen + * Description: reads the vfl structures from nand and build the ram version + * Input: + * Return value: ANDErrorCodeOk if successful. + */ +#define PPNVFL_PRINT_RAM_MAPPING_BUILDUP (0) +#define PPNVFL_PRINT_OPEN_V2PMAPPING (0) + +static Int32 +_ppnvflOpen + (PPNVFL_MainCxt * mcxt, + UInt32 dwKeepout, + UInt32 minor_ver, + UInt32 dwOptions) +{ + Buffer * buf = NULL; + UInt16 bank, j; + UInt8 *validate_mapping = NULL; + SpecialBlockAddress *special_blocks = NULL; + UInt16 *special_blocks_types = NULL; + UInt16 total_special_blocks = 0; + Int32 ret_val; + + mcxt->format_options = dwOptions; + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + // populate the General and CAU structures + + special_blocks = (SpecialBlockAddress *)WMR_MALLOC(AND_MAX_SPECIAL_BLOCKS * + sizeof(SpecialBlockAddress)); + special_blocks_types = (UInt16*)WMR_MALLOC(AND_MAX_SPECIAL_BLOCKS * sizeof(UInt16)); + + // clear the buffer + WMR_MEMSET(mcxt->v2p_main, 0xFF, (sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk)); + WMR_MEMSET(mcxt->v2p_mixed, 0xFF, _getV2PMixedArraySize(mcxt)); + + mcxt->r_gen.cxt_age = 0xFFFFFFFF; + mcxt->r_gen.keepout = dwKeepout; + mcxt->mixed_entries = 0; + + WMR_MEMSET(mcxt->vfl_map_pages[0], 0, (mcxt->dev.num_of_banks * + mcxt->r_gen.pages_per_block_mapping * sizeof(UInt16))); + WMR_MEMSET(mcxt->r_banks, 0, (sizeof(PPNVFL_BankRAMCxt) * mcxt->dev.num_of_banks)); + + validate_mapping = (UInt8*)WMR_MALLOC(mcxt->dev.blocks_per_cau * sizeof(UInt8)); + + mcxt->r_gen.search_for_cxt = TRUE32; + if (_findOnNANDCxt(mcxt) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:WRN] Error _findOnNANDCxt() (line:%d)\n"), __LINE__)); + BUF_Release(buf); + return ANDErrorCodeHwErr; + } + mcxt->r_gen.search_for_cxt = FALSE32; + + WMR_MEMSET(validate_mapping, 0, (mcxt->dev.blocks_per_cau * sizeof(UInt8))); + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + // read the mapping and fill the v2p maps + for (j = 0; j < mcxt->r_gen.pages_per_block_mapping; j++) + { + UInt16 block, startOffset, count; + P2BlockUsageType *p2_block_usage_map = (P2BlockUsageType*)buf->pData; + if (_readVFLCxtPage(mcxt, buf, bank, j) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:WRN] Error _readVFLCxtPage(bank=%d, %d) (line:%d)\n"), bank, j, __LINE__)); + BUF_Release(buf); + return ANDErrorCodeHwErr; + } + startOffset = j * (mcxt->r_gen.pbns_per_cxt_mapping_page); + count = WMR_MIN((mcxt->dev.blocks_per_cau - startOffset), + mcxt->r_gen.pbns_per_cxt_mapping_page); + for (block = 0; block < count; block++) + { + UInt16 pbn = block + startOffset; + + if (!(p2_block_usage_map[block].p2sb.type & AND_SB_BIT_SPEICAL_FLAG)) + { + UInt16 vbn = p2_block_usage_map[block].p2v.vbn; + UInt8 offset = p2_block_usage_map[block].p2v.offset; + mcxt->r_banks[bank].num_p2v++; + if (vbn >= mcxt->gen.num_of_vfl_sublk) + { + WMR_PRINT(ERROR, "vbn %d of %d\n", vbn, mcxt->gen.num_of_vfl_sublk); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + validate_mapping[vbn]++; + + if (mcxt->v2p_main[vbn] == 0xFFFF) + { + if ((offset == bank) && (bank == 0)) + { + VFL_INF_PRINT(PPNVFL_PRINT_RAM_MAPPING_BUILDUP, + (TEXT("[PPNVFL:INF] main: bank 0x%X vbn 0x%X pbn 0x%X (line:%d)\n"), + bank, vbn, pbn, __LINE__)); + mcxt->v2p_main[vbn] = pbn; + } + else + { + mcxt->v2p_main[vbn] = PPN_V2P_UNMAPPED; + _addNewMixedBlockEntry(mcxt, vbn, offset, bank, pbn); + } + } + else if ((mcxt->v2p_main[vbn] != pbn) || (offset != bank)) + { + // this is a mixed entry + if (_isMixedBlock(mcxt, vbn) == TRUE32) + { + VFL_INF_PRINT(PPNVFL_PRINT_RAM_MAPPING_BUILDUP, + (TEXT("[PPNVFL:INF] set: vbn 0x%X offset 0x%X bank 0x%X pbn 0x%X (line:%d)\n"), + vbn, offset, bank, pbn, __LINE__)); + // this is an existing mixed entry use the allocated slot + _setMixedBlockEntry(mcxt, vbn, offset, bank, pbn); + } + else + { + VFL_INF_PRINT(PPNVFL_PRINT_RAM_MAPPING_BUILDUP, + (TEXT( + "[PPNVFL:INF] add[0x%04X]: vbn 0x%04X offset 0x%02X bank 0x%02X pbn 0x%04X (line:%d)\n"), + mcxt->mixed_entries, vbn, offset, bank, pbn, __LINE__)); + // this is a new entry + _addNewMixedBlockEntry(mcxt, vbn, offset, bank, pbn); + } + } + } + // count bad blocks (initial and grown and special blocks) + else + { + switch (p2_block_usage_map[block].p2sb.type) + { + case PPNVFL_TYPE_AVAILABLE_MARK: + mcxt->r_banks[bank].num_available++; + break; + + case PPNVFL_TYPE_GROWN_BB: + mcxt->r_banks[bank].num_grown_bad++; + break; + + case PPNVFL_TYPE_INITIAL_BB: + mcxt->r_banks[bank].num_initial_bad++; + break; + + case PPNVFL_TYPE_VFL_INFO: + mcxt->r_banks[bank].num_cxt++; + break; + + default: + { + if (andSBGetHandler(p2_block_usage_map[block].p2sb.type) != AND_SB_HANDLER_VFL_CXT) + { + if (AND_MAX_SPECIAL_BLOCKS <= total_special_blocks) + { + VFL_ERR_PRINT((TEXT("total special blocks has exceeded the max allowed\n"))); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + mcxt->r_banks[bank].num_special_blocks++; + special_blocks[total_special_blocks].bank = bank; + special_blocks[total_special_blocks].block = pbn; + special_blocks_types[total_special_blocks] = p2_block_usage_map[block].p2sb.type; + total_special_blocks++; + break; + } + else + { + VFL_ERR_PRINT((TEXT("unknown block marking: 0x%08x\n"), + p2_block_usage_map[block].p2sb.type)); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + } + } + } + } + } + } + + for (j = 0; j < mcxt->gen.num_of_vfl_sublk; j++) + { + if (validate_mapping[j] != mcxt->dev.num_of_banks) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] validate_mapping[%d] = %d (l:%d)\n"), j, validate_mapping[j], + __LINE__)); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + } + + mcxt->r_gen.cxt_age--; + + if (total_special_blocks != 0) + { + UInt16 sb_idx; + + mcxt->fpart->ChangeCacheState(FALSE32); + // send the list to FPart + for (sb_idx = 0; sb_idx < total_special_blocks; sb_idx++) + { + if (!mcxt->fpart->AllocateSpecialBlockType(&special_blocks[sb_idx], 1, special_blocks_types[sb_idx])) + { + VFL_ERR_PRINT((TEXT("fpart failed to allocate special block with type %p\n"), + special_blocks_types[sb_idx])); + ret_val = ANDErrorCodeHwErr; + goto exit; + } + } + mcxt->fpart->ChangeCacheState(TRUE32); + } + + ret_val = ANDErrorCodeOk; + + _printVFLBlockMapping(mcxt, __LINE__); +#ifndef AND_READONLY + if (mcxt->r_gen.need_rewrite) + { + if (!_copyVFLCxtToOtherPair(mcxt)) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed _copyVFLCxtToOtherPair after need_rewrite = TRUE (line:%d)\n"), + __LINE__)); + } + _printVFLBlockMapping(mcxt, __LINE__); + } +#endif + exit: + if (NULL != buf) + { + BUF_Release(buf); + } + if (NULL != validate_mapping) + { + WMR_FREE(validate_mapping, (mcxt->dev.blocks_per_cau * sizeof(UInt8))); + } + if (NULL != special_blocks) + { + WMR_FREE(special_blocks, (AND_MAX_SPECIAL_BLOCKS * sizeof(SpecialBlockAddress))); + } + if (NULL != special_blocks_types) + { + WMR_FREE(special_blocks_types, (AND_MAX_SPECIAL_BLOCKS * sizeof(UInt16))); + } + +#if (defined(PPNVFL_PRINT_OPEN_V2PMAPPING) && PPNVFL_PRINT_OPEN_V2PMAPPING) + _printV2PMapping(mcxt); +#endif + + return ret_val; +} + +#ifndef AND_READONLY +/* + * Name: _ppnvflFormat + * Description: implements format function for the vfl I/F + * Input: + * Return value: ANDErrorCodeOk if successful. + */ +static Int32 +_ppnvflFormat + (PPNVFL_MainCxt * mcxt, + UInt32 dwKeepout, + UInt32 dwOptions) +{ + UInt16 bank, pbn, vbn, i, pre_mapped_special_blocks, vfl_info_idx; + Buffer *buf = NULL; + P2BlockUsageType **on_nand_block_map = NULL; + PPNStatusType status; + UInt16 perfect_match_bar; + BOOL32 assign_vbns_out_of_banks = FALSE32; + + mcxt->format_options = dwOptions; + + // Init the general structure + mcxt->r_gen.cxt_age = 0xFFFFFFFF; + mcxt->r_gen.keepout = dwKeepout; + mcxt->gen.ftl_type = 0xFFFFFFFF; + + // before we start - make sure the PPN configuration here make sense to this vfl + if (mcxt->dev.ces_per_channel > PPN_MAX_CES_PER_BUS) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] PPNVFL does not support configurations with more than %d CEs/Channel (found %d) (line:%d)!\n"), + PPN_MAX_CES_PER_BUS, mcxt->dev.ces_per_channel, __LINE__)); + goto return_error; + } + if (mcxt->dev.main_bytes_per_page < PPNVFL_MIN_PAGE_SIZE) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] PPNVFL does not support configurations with less than %d bytes per page (found %d) (line:%d)!\n"), + PPNVFL_MIN_PAGE_SIZE, mcxt->dev.main_bytes_per_page, __LINE__)); + goto return_error; + } + if (mcxt->dev.num_of_banks > PPNVFL_MAX_SUPPORTED_BANKS) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] PPNVFL does not support configurations with more than %d banks (found %d) (line:%d)!\n"), + PPNVFL_MAX_SUPPORTED_BANKS, mcxt->dev.num_of_banks, __LINE__)); + goto return_error; + } + + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + mcxt->gen.ftl_cxt_vbn[i] = i; + } + + buf = BUF_Get(BUF_MAIN_AND_SPARE); + if (buf == NULL) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] BUF_Get fail (line:%d)!\n"), __LINE__)); + return ANDErrorCodeHwErr; + } + + // start - 1. allocate memory to hold phisycal to virtual mapping + on_nand_block_map = (P2BlockUsageType**)WMR_MALLOC(sizeof(P2BlockUsageType*) * mcxt->dev.num_of_banks); + if (on_nand_block_map == NULL) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] allocation fail (line:%d)!\n"), __LINE__)); + goto return_error; + } + on_nand_block_map[0] = (P2BlockUsageType*)WMR_MALLOC(mcxt->dev.blocks_per_cau * mcxt->dev.num_of_banks * + sizeof(P2BlockUsageType)); + if (on_nand_block_map[0] == NULL) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] allocation fail (line:%d)!\n"), __LINE__)); + goto return_error; + } + // assign the rest of the pointers + for (bank = 1; bank < mcxt->dev.num_of_banks; bank++) + { + on_nand_block_map[bank] = &(on_nand_block_map[0][(bank * mcxt->dev.blocks_per_cau)]); + } + // end - 1. allocate memory to hold phisycal to virtual mapping - end + + // start - 2. read the bbts + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_CAUBBT, + PPN_NO_OPTIONS, bank, 0, 0, TRUE32, buf->pData, NULL); + if (status & PPN_OTHERS_STATUS_OP_FAILED) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] ReadCAUBBT fail (line:%d)!\n"), __LINE__)); + goto return_error; + } + + for (pbn = 0; pbn < mcxt->dev.blocks_per_cau; pbn++) + { + if (ppnMiscIsBlockGood(buf->pData, pbn) == FALSE32) + { + on_nand_block_map[bank][pbn].p2sb.type = PPNVFL_TYPE_INITIAL_BB; + on_nand_block_map[bank][pbn].p2sb.reserved = P2SB_RESERVED_VALUE; + } + else + { + on_nand_block_map[bank][pbn].p2sb.type = PPNVFL_TYPE_AVAILABLE_MARK; + on_nand_block_map[bank][pbn].p2sb.reserved = P2SB_RESERVED_VALUE; + } + } + } + // end - 2. read the bbts + + // start - 3. mark special blocks + // start - 3.1 mark pre allocated special blocks + if (mcxt->fpart->MapSpecialBlocks(NULL, NULL, &pre_mapped_special_blocks) == TRUE32) + { + UInt16 *special_blocks_types; + SpecialBlockAddress *special_blocks; + + special_blocks_types = (UInt16*)WMR_MALLOC(pre_mapped_special_blocks * sizeof(UInt16)); + special_blocks = (SpecialBlockAddress*)WMR_MALLOC(pre_mapped_special_blocks * + sizeof(SpecialBlockAddress)); + + if (mcxt->fpart->MapSpecialBlocks(special_blocks, special_blocks_types, + &pre_mapped_special_blocks) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] MapSpecialBlocks fail after success??? (line:%d)\n"), + __LINE__)); + goto return_error; + } + for (i = 0; i < pre_mapped_special_blocks; i++) + { + bank = special_blocks[i].bank; + pbn = special_blocks[i].block; + on_nand_block_map[bank][pbn].p2sb.type = special_blocks_types[i]; + on_nand_block_map[bank][pbn].p2sb.reserved = P2SB_RESERVED_VALUE; + } + } + // end - 3.1 mark pre allocated special blocks + + // start - 3.2 mark block zero + // start - 3.3 mark nand boot blocks + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + if (ppnMiscGetCAUFromBank(&mcxt->dev, bank) == 0) + { + on_nand_block_map[bank][0].p2sb.type = AND_SB_TYPE_BLOCK_ZERO; + // support legacy nand-boot area + for (pbn = 0; pbn < mcxt->r_gen.keepout; pbn++) + { + if (on_nand_block_map[bank][pbn].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + on_nand_block_map[bank][pbn].p2sb.type = AND_SB_TYPE_KEEPOUT_BOOT; + } + } + } + } + + // end - 3.2 mark block zero + // end - 3.3 mark nand boot blocks + + // start - 3.4 mark vfl context blocks + pbn = 0; + for (vfl_info_idx = 0; ((vfl_info_idx < mcxt->r_gen.num_of_vfl_blocks) && + (pbn < mcxt->dev.blocks_per_cau)); pbn++) + { + if (PPNVFL_CONTEXT_BLOCK_LIMIT(&mcxt->dev) == pbn) + { + // we don't want to panic, we just want to complain loudly for debug purposes + WMR_PRINT(ERROR, "VFL context allocation not complete yet..." + "%lu of %lu sublks checked..." + "%lu of %lu vflblks allocated...\n", + pbn, mcxt->dev.blocks_per_cau, vfl_info_idx, mcxt->r_gen.num_of_vfl_blocks); + } + + for (bank = 0; ((bank < mcxt->dev.num_of_banks) && + (vfl_info_idx < mcxt->r_gen.num_of_vfl_blocks)); bank++) + { + if (on_nand_block_map[bank][pbn].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + if (ppnMiscTestSpecialBlock(&mcxt->dev, mcxt->commands[0], bank, pbn, PPNVFL_SPARE_TYPE_TST)) + { + on_nand_block_map[bank][pbn].p2sb.type = PPNVFL_TYPE_VFL_INFO; + mcxt->gen.vfl_blocks[vfl_info_idx].bank = bank; + mcxt->gen.vfl_blocks[vfl_info_idx].block = pbn; + vfl_info_idx++; + } + else + { + on_nand_block_map[bank][pbn].p2sb.type = PPNVFL_TYPE_GROWN_BB; + } + } + } + } + + if (vfl_info_idx < mcxt->r_gen.num_of_vfl_blocks) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed allocating vfl info blocks (line:%d)\n"), + __LINE__)); + goto return_error; + } + + // end - 3.4 mark vfl context blocks + // start - 3.5 generate a bar for the perfect striping (make sure we put special blocks on top) + perfect_match_bar = mcxt->dev.blocks_per_cau - 1; + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + UInt16 sb_allocation_count; + pbn = mcxt->dev.blocks_per_cau; + for (sb_allocation_count = 0; + (sb_allocation_count < SPECIAL_BLOCK_PRE_ALLOCATION_STRIPE) && (pbn >= PPN_SPECIAL_BLOCK_LIMIT(&mcxt->dev)); + sb_allocation_count++) + { + for (pbn--; pbn >= PPN_SPECIAL_BLOCK_LIMIT(&mcxt->dev); pbn--) + { + if (on_nand_block_map[bank][pbn].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + break; + } + } + } + if (pbn < PPN_SPECIAL_BLOCK_LIMIT(&mcxt->dev)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:WRN] _ppnvflFormat - unable to reserve special block stripe - 0x%X (line:%d)\n"), + bank, __LINE__)); + goto return_error; + } + if (pbn < perfect_match_bar) + { + perfect_match_bar = pbn; + } + } + // end - 3.5 generate a bar for the perfect striping (make sure we put special blocks on top) + + // end - 3. mark special blocks + + // start - 4. allocate virtual blocks - start + // start - 4.1. pick the best aligned blocks first + WMR_MEMSET(mcxt->v2p_main, 0xFF, (sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk)); + WMR_MEMSET(mcxt->v2p_mixed, 0xFF, _getV2PMixedArraySize(mcxt)); + mcxt->mixed_entries = 0; + pbn = 0; + for (vbn = 0; (vbn < mcxt->gen.num_of_vfl_sublk) && (pbn < perfect_match_bar); ) + { + for (; pbn < perfect_match_bar; pbn++) + { + BOOL32 all_are_available = TRUE32; + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + if (on_nand_block_map[bank][pbn].p2sb.type != PPNVFL_TYPE_AVAILABLE_MARK) + { + all_are_available = FALSE32; + break; + } + } + if (all_are_available == TRUE32) + { + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + on_nand_block_map[bank][pbn].p2v.vbn = vbn; + on_nand_block_map[bank][pbn].p2v.offset = bank; + on_nand_block_map[bank][pbn].p2v.reserved = P2V_RESERVED_VALUE; + } + mcxt->v2p_main[vbn] = pbn; + vbn++; + break; + } + } + } + // end - 4.1. pick the best aligned blocks first + + // start - 4.2 pick any allowable combination for the rest of the virtual blocks + + // choose replacements from the same bank (until we run out) + assign_vbns_out_of_banks = FALSE32; + if (vbn < mcxt->gen.num_of_vfl_sublk) + { + UInt16 vbn_idx = vbn; + for (vbn_idx = vbn; vbn_idx < mcxt->gen.num_of_vfl_sublk; vbn_idx++) + { + mcxt->v2p_main[vbn_idx] = PPN_V2P_UNMAPPED; + if (!_addNewMixedBlockEntry(mcxt, vbn_idx, 0, 0, PPN_V2P_UNMAPPED)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:WRN] _ppnvflFormat - _addNewMixedBlockEntry fail (line:%d)\n"), + __LINE__)); + goto return_error; + } + } + + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + for (vbn_idx = vbn, pbn = 0; (pbn < mcxt->dev.blocks_per_cau) && (vbn_idx < mcxt->gen.num_of_vfl_sublk); + pbn++) + { + if (on_nand_block_map[bank][pbn].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + on_nand_block_map[bank][pbn].p2v.vbn = vbn_idx; + on_nand_block_map[bank][pbn].p2v.offset = bank; + on_nand_block_map[bank][pbn].p2v.reserved = P2V_RESERVED_VALUE; + if (!_setMixedBlockEntry(mcxt, vbn_idx, bank, bank, pbn)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] _ppnvflFormat - _setMixedBlockEntry fail (line:%d)\n"), + __LINE__)); + goto return_error; + } + vbn_idx++; + } + } + if (vbn_idx < mcxt->gen.num_of_vfl_sublk) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] _ppnvflFormat - out of good blocks for vbns in bank - 0x%X (line:%d)\n"), + bank, __LINE__)); + assign_vbns_out_of_banks = TRUE32; + } + } + } + + // if we need to replace out of bank do it... + if (assign_vbns_out_of_banks) + { + UInt16 vbn_idx, mixed_array_offset; + pbn = 0; + bank = 0; + for (vbn_idx = vbn; ((vbn_idx < mcxt->gen.num_of_vfl_sublk) && + (pbn < mcxt->dev.blocks_per_cau)); vbn_idx++) + { + for (mixed_array_offset = 0; ((mixed_array_offset < mcxt->dev.num_of_banks) && + (pbn < mcxt->dev.blocks_per_cau)); mixed_array_offset++) + { + const UInt32 entry_offset = _getMixedArrayEntryOffset(mcxt, vbn_idx, mixed_array_offset); + if (mcxt->v2p_mixed[entry_offset].pbn == PPN_V2P_UNMAPPED) + { + BOOL32 replacement_found = FALSE32; + // choose the lowest physical available - from whichever bank that has free blocks + for (; ((pbn < mcxt->dev.blocks_per_cau) && (!replacement_found)); pbn++) + { + for (bank = (bank == mcxt->dev.num_of_banks ? 0 : bank); + ((bank < mcxt->dev.num_of_banks) && (!replacement_found)); bank++) + { + if (on_nand_block_map[bank][pbn].p2sb.type == PPNVFL_TYPE_AVAILABLE_MARK) + { + on_nand_block_map[bank][pbn].p2v.vbn = vbn_idx; + on_nand_block_map[bank][pbn].p2v.offset = mixed_array_offset; + on_nand_block_map[bank][pbn].p2v.reserved = P2V_RESERVED_VALUE; + if (!_setMixedBlockEntry(mcxt, vbn_idx, mixed_array_offset, bank, pbn)) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] _ppnvflFormat - _setMixedBlockEntry fail (line:%d)\n"), + __LINE__)); + goto return_error; + } + replacement_found = TRUE32; + } + } + } + if (!replacement_found) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] _ppnvflFormat - could not find blocks for all the vbns (line:%d)\n"), + __LINE__)); + goto return_error; + } + } + } + } + } + + // end - 4.2 pick any allowable combination for the rest of the virtual blocks + // end - 4. allocate virtual blocks - end + + // start - 5. program the context blocks + // start - 5.1. erase all the vfl context blocks + for (vfl_info_idx = 0; vfl_info_idx < mcxt->r_gen.num_of_vfl_blocks; vfl_info_idx++) + { + status = ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, + mcxt->gen.vfl_blocks[vfl_info_idx].bank, + mcxt->gen.vfl_blocks[vfl_info_idx].block, + 0, TRUE32, NULL, NULL); + if (status & PPN_ERASE_STATUS_FAIL) + { + // we should not get here - vfl blocks were tested + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] format fail erasing info block fail (line:%d)!\n"), __LINE__)); + goto return_error; + } + } + // end - 5.1. erase all the vfl context blocks + + // start - 5.2. program the cxt blocks + if (!_programCxtLastPage(mcxt, buf, TRUE32)) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:WRN] _ppnvflFormat - failed _programCxtLastPage() (line:%d)\n"), + __LINE__)); + goto return_error; + } + + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + for (i = 0; i < mcxt->r_gen.pages_per_block_mapping; i++) + { + UInt16 start_offset = i * mcxt->r_gen.pbns_per_cxt_mapping_page; + UInt16 size_to_copy = WMR_MIN(mcxt->dev.main_bytes_per_page, + ((mcxt->dev.blocks_per_cau - start_offset) * sizeof(P2BlockUsageType))); + WMR_MEMSET(buf->pData, 0xFF, mcxt->dev.main_bytes_per_page); + WMR_MEMCPY(buf->pData, &on_nand_block_map[bank][start_offset], size_to_copy); + if (!_programVFLCxtPage(mcxt, buf, bank, i)) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:WRN] _ppnvflFormat - failed _programCxtLastPage() (line:%d)\n"), + __LINE__)); + goto return_error; + } + } + } + + if (!_programCxtLastPage(mcxt, buf, TRUE32)) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:WRN] _ppnvflFormat - failed _programCxtLastPage() (line:%d)\n"), + __LINE__)); + goto return_error; + } + // end - 5.2. program the cxt blocks + // end - 5. program the context blocks + + // start - 6. clean up the mess + // free temp allocations done in this function + WMR_FREE(on_nand_block_map[0], mcxt->dev.blocks_per_cau * mcxt->dev.num_of_banks * sizeof(P2BlockUsageType)); + WMR_FREE(on_nand_block_map, (sizeof(P2BlockUsageType*) * mcxt->dev.num_of_banks)); + + BUF_Release(buf); + // end - 6. clean up the mess + + return ANDErrorCodeOk; + + return_error: + + // start - 6. clean up the mess + // free temp allocations done in this function + if (on_nand_block_map != NULL && on_nand_block_map[0] != NULL) + { + WMR_FREE(on_nand_block_map[0], mcxt->dev.blocks_per_cau * mcxt->dev.num_of_banks * sizeof(P2BlockUsageType)); + } + if (on_nand_block_map != NULL) + { + WMR_FREE(on_nand_block_map, (sizeof(P2BlockUsageType*) * mcxt->dev.num_of_banks)); + } + + BUF_Release(buf); + // end - 6. clean up the mess + + return ANDErrorCodeHwErr; +} + +#endif // !AND_READONLY + +/* + * Name: _bitSwapBuffer + * Description: swaps the order of the bits on every byte in the given buffer + * Input: buffer and length, no alignment requirement + * Output: bit-swapped buffer + */ +static void +_bitSwapBuffer + (void *buffer, + UInt32 length) +{ + UInt8 *cursor = (UInt8*)buffer; + + while (length--) + { + UInt8 byte = *cursor; + *cursor = ((byte & 0x01) << 7) | + ((byte & 0x02) << 5) | + ((byte & 0x04) << 3) | + ((byte & 0x08) << 1) | + ((byte & 0x10) >> 1) | + ((byte & 0x20) >> 3) | + ((byte & 0x40) >> 5) | + ((byte & 0x80) >> 7); + cursor++; + } +} + +/* + * Name: _ppnvflGetStruct + * Description: implements GetStruct function for the vfl I/F + * Input: struct type + * Output: buffer, buffer size + * Return value: TRUE32 if successful, otherwise - FALSE32 + */ +static BOOL32 +_ppnvflGetStruct + (PPNVFL_MainCxt * mcxt, + UInt32 dwStructType, + void *pvoidStructBuffer, + UInt32 *pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { + case AND_STRUCT_VFL_GET_TYPE: + { + UInt8 bVFLType = VFL_TYPE_PPNVFL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &bVFLType, + sizeof(bVFLType)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_STATISTICS_SIZE: + { + UInt32 dwStatSize = sizeof(PPNVFLStatistics); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwStatSize, + sizeof(dwStatSize)); + break; + } + + case AND_STRUCT_VFL_STATISTICS: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &mcxt->stat, + sizeof(mcxt->stat)); + break; + } +#endif // AND_COLLECT_STATISTICS + + case AND_STRUCT_VFL_FILSTATISTICS: + { + boolRes = FIL_GetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, + pdwStructSize); + break; + } + + case AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS: + { + UInt16 dwNumFTLSuBlks = mcxt->gen.num_of_ftl_sublk; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumFTLSuBlks, + sizeof(dwNumFTLSuBlks)); + break; + } + + case AND_STRUCT_VFL_NUM_OF_SUBLKS: + { + UInt16 dwNumVFLSuBlks = mcxt->gen.num_of_vfl_sublk; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumVFLSuBlks, + sizeof(dwNumVFLSuBlks)); + break; + } + + case AND_STRUCT_VFL_BYTES_PER_PAGE: + { + UInt16 wPageSize = mcxt->dev.main_bytes_per_page; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPageSize, + sizeof(wPageSize)); + break; + } + + case AND_STRUCT_VFL_PAGES_PER_SUBLK: + { + UInt16 wPagesPerSuBlk = mcxt->dev.pages_per_sublk; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPagesPerSuBlk, + sizeof(wPagesPerSuBlk)); + break; + } + + case AND_STRUCT_VFL_NUM_CHANNELS: + { + UInt32 dwNumChannels = mcxt->dev.num_channels; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumChannels, + sizeof(dwNumChannels)); + break; + } + + case AND_STRUCT_VFL_CES_PER_CHANNEL: + { + UInt32 dwCesPerChannel = mcxt->dev.ces_per_channel; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwCesPerChannel, + sizeof(dwCesPerChannel)); + break; + } + + case AND_STRUCT_VFL_CAUS_PER_CE: + { + UInt32 dwCausPerCe = mcxt->dev.caus_per_ce; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwCausPerCe, + sizeof(dwCausPerCe)); + break; + } + + case AND_STRUCT_VFL_NAND_TYPE: + { + UInt32 nand_type = NAND_TYPE_PPN; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &nand_type, + sizeof(nand_type)); + break; + } + + case AND_STRUCT_VFL_BYTES_PER_META: + { + UInt16 wBytesPerMetaData = (UInt16)mcxt->fil->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wBytesPerMetaData, + sizeof(wBytesPerMetaData)); + break; + } + + case AND_STRUCT_VFL_VALID_BYTES_PER_META: + { + UInt16 wBytesPerMetaData = (UInt16)mcxt->fil->GetDeviceInfo(AND_DEVINFO_FIL_META_VALID_BYTES); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wBytesPerMetaData, + sizeof(wBytesPerMetaData)); + break; + } + + case AND_STRUCT_VFL_PUBLIC_FBBT: + // Fall Through + case AND_STRUCT_VFL_FACTORY_BBT: + { + UInt8 cau; + UInt8 ce; + UInt8 *pData; + Buffer *buf; + const UInt32 cau_bbt_size = (mcxt->dev.blocks_per_cau / 8) + (mcxt->dev.blocks_per_cau % 8 ? 1 : 0); + const UInt32 total_ces = mcxt->dev.ces_per_channel * mcxt->dev.num_channels; + const UInt32 total_caus = mcxt->dev.caus_per_ce * total_ces; + const UInt32 required_buffer_size = cau_bbt_size * total_caus; + + if (NULL == pdwStructSize) + { + // Can't do anything without a size + boolRes = FALSE32; + } + else if (NULL == pvoidStructBuffer) + { + // Just report the size + *pdwStructSize = required_buffer_size; + boolRes = TRUE32; + } + else if (*pdwStructSize < required_buffer_size) + { + // Caller is asking for actual data with + // too small of a buffer + boolRes = FALSE32; + } + else + { + *pdwStructSize = required_buffer_size; + boolRes = TRUE32; + pData = (UInt8 *)pvoidStructBuffer; + buf = BUF_Get(BUF_MAIN_AND_SPARE); + WMR_ASSERT(buf != NULL); + + for (ce = 0; ce < total_ces; ce++) + { + for (cau = 0; cau < mcxt->dev.caus_per_ce; cau++) + { + ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_CAUBBT, + PPN_NO_OPTIONS, ((cau * total_ces) + ce), + 0, 0, TRUE32, buf->pData, NULL); + WMR_MEMCPY(pData, buf->pData, cau_bbt_size); + // Consumers expect opposite bit-order + _bitSwapBuffer(pData, cau_bbt_size); + pData += cau_bbt_size; + } + } + BUF_Release(buf); + } + + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_BITS: + { + UInt16 correctableBits = (UInt16)mcxt->fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &correctableBits, sizeof(correctableBits)); + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_SIZE: + { + UInt16 correctableSize = (UInt16)mcxt->fil->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &correctableSize, sizeof(correctableSize)); + break; + } + + case AND_STRUCT_VFL_PAGES_PER_BLOCK: + { + UInt16 pagesPerBlock = (UInt16)mcxt->fil->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &pagesPerBlock, sizeof(pagesPerBlock)); + break; + } + + case AND_STRUCT_VFL_DEVICEINFO_SIZE: + { + UInt32 deviceInfoSize = sizeof(mcxt->dev); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &deviceInfoSize, sizeof(deviceInfoSize)); + break; + } + + case AND_STRUCT_VFL_DEVICEINFO: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &mcxt->dev, sizeof(mcxt->dev)); + break; + } + + case AND_STRUCT_VFL_GETADDRESS: + { + UInt16 bank, block, page_offset, cau; + ANDAddressStruct *addrStruct = (ANDAddressStruct*)pvoidStructBuffer; + *pdwStructSize = sizeof(ANDAddressStruct); + _convertVpnToBankBlockPage(mcxt, addrStruct->dwVpn, &bank, &block, &page_offset); + cau = ppnMiscGetCAUFromBank(&mcxt->dev, bank); + addrStruct->dwPpn = ppnMiscConvertToPPNPageAddress(&mcxt->dev, cau, block, page_offset, FALSE32); + addrStruct->dwCS = (UInt32)ppnMiscGetCEFromBank(&mcxt->dev, bank); + addrStruct->dwCau = cau; + boolRes = TRUE32; + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_BURNIN_CODE: + { + UInt32 code = (UInt32)mcxt->stat.ddwBurnInCode; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &code, sizeof(code)); + break; + } +#endif //AND_COLLECT_STATISTICS + + case AND_STRUCT_VFL_LAST_ERROR: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &gstLastFailure, sizeof(gstLastFailure)); + break; + } + + case AND_STRUCT_VFL_VFLMETA: + { + const UInt32 chip_enable_idx = dwStructType & AND_STRUCT_CS_MASK; + + if ((NULL == pvoidStructBuffer) && + (NULL != pdwStructSize)) + { + *pdwStructSize = sizeof(PPNVFLMetaDataExport); + boolRes = TRUE32; + } + else if ((NULL != pvoidStructBuffer) && + (NULL != pdwStructSize) && + (*pdwStructSize >= sizeof(PPNVFLMetaDataExport)) && + (chip_enable_idx < (mcxt->dev.num_channels * mcxt->dev.ces_per_channel))) + { + PPNVFLMetaDataExport *exported_meta = (PPNVFLMetaDataExport*)pvoidStructBuffer; + UInt16 bank; + WMR_MEMSET(pvoidStructBuffer, 0xFF, sizeof(PPNVFLMetaDataExport)); + exported_meta->version = PPNVFL_EXPORT_META_VERSION; + exported_meta->dev_info.num_of_channels = mcxt->dev.num_channels; + exported_meta->dev_info.ces_per_channel = mcxt->dev.ces_per_channel; + exported_meta->dev_info.caus_per_ce = mcxt->dev.caus_per_ce; + for (bank = 0; bank < mcxt->dev.num_of_banks; bank++) + { + exported_meta->per_bank_data[bank].geometry.chip_enable = ppnMiscGetCEFromBank(&mcxt->dev, bank); + exported_meta->per_bank_data[bank].geometry.chip_enable_idx = ppnMiscGetCEIdxFromBank(&mcxt->dev, + bank); + exported_meta->per_bank_data[bank].geometry.channel = ppnMiscGetChannelFromBank(&mcxt->dev, bank); + exported_meta->per_bank_data[bank].geometry.cau = ppnMiscGetCAUFromBank(&mcxt->dev, bank); + exported_meta->per_bank_data[bank].num_special_blocks = mcxt->r_banks[bank].num_special_blocks; + exported_meta->per_bank_data[bank].num_grown_bad = mcxt->r_banks[bank].num_grown_bad; + exported_meta->per_bank_data[bank].num_initial_bad = mcxt->r_banks[bank].num_initial_bad; + exported_meta->per_bank_data[bank].num_available = mcxt->r_banks[bank].num_available; + exported_meta->per_bank_data[bank].num_cxt = mcxt->r_banks[bank].num_cxt; + exported_meta->per_bank_data[bank].num_p2v = mcxt->r_banks[bank].num_p2v; + } + *pdwStructSize = sizeof(PPNVFLMetaDataExport); + boolRes = TRUE32; + } + break; + } + +#if AND_SUPPORT_BLOCK_BORROWING + case AND_STRUCT_VFL_FIND_BORROWED_BLOCKS: + { + if (NULL != pdwStructSize) + { + BorrowBlockAddress *pastrBlocks = (BorrowBlockAddress*)pvoidStructBuffer; + SpecialBlockAddress special_blocks[AND_MAX_SPECIAL_BLOCKS]; + UInt16 i, count, max_count, types[AND_MAX_SPECIAL_BLOCKS]; + + mcxt->fpart->MapSpecialBlocks(special_blocks, types, &count); + max_count = WMR_MIN(count, (*pdwStructSize / sizeof(pastrBlocks[0]))); + for (i = 0; i < max_count; i++) + { + UInt16 channel; + UInt16 ceIdx; + UInt16 cau; + UInt32 ppn_page; + channel = ppnMiscGetChannelFromBank(&mcxt->dev, special_blocks[i].bank); + ceIdx = ppnMiscGetCEIdxFromBank(&mcxt->dev, special_blocks[i].bank); + if (mcxt->format_options & WMR_INIT__USE_NEW_DUAL_CHANNEL_ADDRESS) + { + pastrBlocks[i].dwPhysicalCE = channel + (ceIdx * mcxt->dev.num_channels); + } + else + { + pastrBlocks[i].dwPhysicalCE = (channel * mcxt->dev.ces_per_channel) + ceIdx; + } + cau = ppnMiscGetCAUFromBank(&mcxt->dev, special_blocks[i].bank); + ppn_page = ppnMiscConvertToPPNPageAddress(&mcxt->dev, cau, special_blocks[i].block, 0, FALSE32); + pastrBlocks[i].dwPhysicalBlock = (ppn_page >> mcxt->dev.bits_per_page_addr); + pastrBlocks[i].wType = types[i]; + } + *pdwStructSize = max_count * sizeof(pastrBlocks[0]); + boolRes = TRUE32; + } + break; + } +#endif + + default: + WMR_PANIC("_ppnvflGetStruct not handling dwStructType 0x%08x", dwStructType); + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] _ppnvflGetStruct 0x%X is not identified as VFL data struct identifier!\n"), + dwStructType)); + boolRes = FALSE32; + } + return boolRes; +} + +/* + * Name: _ppnvflGetDeviceInfo + * Description: implements GetDeviceInfo function for the vfl I/F + * Input: type + * Return value: info per the requested information type + */ +static UInt32 +_ppnvflGetDeviceInfo + (PPNVFL_MainCxt * mcxt, + UInt32 dwParamType) +{ + UInt32 dwRetVal = 0xFFFFFFFF; + + switch (dwParamType) + { + case AND_DEVINFO_PAGES_PER_SUBLK: + { + dwRetVal = (UInt32)mcxt->dev.pages_per_sublk; + break; + } + + case AND_DEVINFO_BYTES_PER_PAGE: + { + dwRetVal = (UInt32)mcxt->dev.main_bytes_per_page; + break; + } + + case AND_DEVINFO_NUM_OF_BANKS: + { + dwRetVal = (UInt32)mcxt->dev.num_of_banks; + break; + } + + case AND_DEVINFO_NUM_OF_USER_SUBLK: + { + dwRetVal = (UInt32)mcxt->gen.num_of_ftl_sublk; + break; + } + + case AND_DEVINFO_FTL_TYPE: + { + dwRetVal = (UInt32)mcxt->gen.ftl_type; + break; + } + + case AND_DEVINFO_FIL_LBAS_PER_PAGE: + { + dwRetVal = (UInt32)mcxt->dev.lbas_per_page; + break; + } + + case AND_DEVINFO_FIL_META_VALID_BYTES: + { + dwRetVal = (UInt32)mcxt->dev.lba_meta_bytes_valid; + break; + } + + case AND_DEVINFO_FIL_META_BUFFER_BYTES: + { + dwRetVal = (UInt32)mcxt->dev.lba_meta_bytes_buffer; + break; + } + + default: + { + WMR_PANIC("dwParamType not supported (0x%08x)\n", dwParamType); + break; + } + } + return dwRetVal; +} + +#define PPNVFL_PRINT_READSCATTERED_SUMMARY (1) + +/* + * Name: _ppnvflReadScatteredPagesInVb + * Description: implements scattered page read function for the vfl I/F + * Input: addaress array of pages to read, number of pages to read, + * data buffer, meta buffer + * Output: need to refresh flag, pabSectorStatus (for bonfire), actual status + * Ignored: whitening flag + * Return value: TRUE32 if successful, otherwise FALSE32 + */ +static BOOL32 +_ppnvflReadScatteredPagesInVb + (PPNVFL_MainCxt * mcxt, + UInt32 * padwVpn, + UInt16 wNumPagesToRead, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening, + Int32 *actualStatus) +{ + UInt16 page_idx; + UInt16 page_count; + UInt32 op_status = 0; + const UInt8 num_sectors = (mcxt->dev.main_bytes_per_page) / 1024; //Number of kilobyte sectors + BOOL32 op_result = FALSE32; + Int32 temp_actual_status; + + VFL_INF_PRINT(PPNVFL_PRINT_READSCATTERED_SUMMARY, + (TEXT("[PPNVFL:INF] ReadScattered (0x%08X, 0x%04X)\n"), padwVpn, wNumPagesToRead)); + +#ifdef AND_COLLECT_STATISTICS + mcxt->stat.ddwPagesReadCnt += wNumPagesToRead; + mcxt->stat.ddwScatteredReadCallCnt++; +#endif + + for (page_idx = 0; page_idx < wNumPagesToRead; ) + { + UInt16 pages_added = wNumPagesToRead - page_idx; + UInt8 *data = &pbaData[page_idx * mcxt->dev.main_bytes_per_page]; + UInt8 *spare = &pbaSpare[page_idx * mcxt->dev.lba_meta_bytes_buffer]; + UInt32 *vpn_ptr = &padwVpn[page_idx]; + + if (pabSectorStats != NULL) + { + _fillScatteredAddressesToCommandStructure(mcxt, mcxt->commands, vpn_ptr, &pages_added, + PPN_COMMAND_READ, data, spare, PPN_OPTIONS_REPORT_HEALTH); + } + else + { + _fillScatteredAddressesToCommandStructure(mcxt, mcxt->commands, vpn_ptr, &pages_added, + PPN_COMMAND_READ, data, spare, PPN_NO_OPTIONS); + } + + mcxt->fil->PerformCommandList(mcxt->commands, mcxt->dev.num_channels); + + if (pabSectorStats != NULL) + { + for (page_count = page_idx; page_count < (page_idx + pages_added); page_count++) + { + //TO DO. refer Data & Metadata ordering for PPN Health monitoring + WMR_MEMCPY((pabSectorStats + (page_count * num_sectors)), + (pbaData + (page_count * (mcxt->dev.main_bytes_per_page))), num_sectors); + } + } + _analyzeMultiReadStatuses(mcxt, vpn_ptr, spare, &op_status, + (pabSectorStats == NULL ? TRUE32 : FALSE32), pabSectorStats); + + page_idx += pages_added; + } + + if (op_status & PPNVFL_READ_RES_UNIDENTIFIED) + { + // don't panic, per rdar://8234566 + WMR_PRINT(ERROR, "op_status 0x%02x\n", op_status); + mcxt->fpart->GetLowFuncTbl()->Reset(); + temp_actual_status = ANDErrorCodeHwErr; + } + else if (op_status & PPNVFL_READ_RES_UECC) + { + temp_actual_status = ANDErrorCodeUserDataErr; + } + else if(op_status & PPNVFL_READ_RES_CLEAN) + { + temp_actual_status = ANDErrorCodeCleanOk; + op_result = TRUE32; + } + else if (op_status & PPNVFL_READ_RES_VALID_DATA) + { + op_result = TRUE32; + temp_actual_status = ANDErrorCodeOk; + } + else + { + // don't panic, per rdar://8234566 + WMR_PRINT(ERROR, "op_status 0x%02x\n", op_status); + mcxt->fpart->GetLowFuncTbl()->Reset(); + temp_actual_status = ANDErrorCodeHwErr; + } + + if (actualStatus != NULL) + { + *actualStatus = temp_actual_status; + } + + if (pboolNeedRefresh != NULL) + { + if (op_status & (PPNVFL_READ_RES_REFRESH | PPNVFL_READ_RES_RETIRE | PPNVFL_READ_RES_UECC)) + { + *pboolNeedRefresh = TRUE32; + } + else + { + *pboolNeedRefresh = FALSE32; + } + } + return op_result; +} + +/* + * Name: _ppnvflReadSinglePage + * Description: implements single page read function for the vfl I/F + * Input: virtual page address, data buffer, meta buffer, mark for scrub + * Output: need to refresh flag + * Ignored: pabSectorStatus and whitening flag and actual status + * Return value: TRUE32 if successful, otherwise FALSE32 + */ +static Int32 +_ppnvflReadSinglePage + (PPNVFL_MainCxt * mcxt, + UInt32 nVpn, + Buffer *pBuf, + BOOL32 bCleanCheck, + BOOL32 bMarkECCForScrub, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening) +{ + UInt32 op_status = 0; + UInt16 num_pages = 1; + +#ifdef AND_COLLECT_STATISTICS + mcxt->stat.ddwPagesReadCnt++; + mcxt->stat.ddwSingleReadCallCnt++; +#endif + + if (pabSectorStats != NULL) + { + _fillScatteredAddressesToCommandStructure(mcxt, mcxt->commands, &nVpn, &num_pages, PPN_COMMAND_READ, + pBuf->pData, pBuf->pSpare, + ((bMarkECCForScrub ? 0 : PPN_OPTIONS_IGNORE_BAD_BLOCK) | + PPN_OPTIONS_REPORT_HEALTH)); + } + else + { + _fillScatteredAddressesToCommandStructure(mcxt, mcxt->commands, &nVpn, &num_pages, PPN_COMMAND_READ, + pBuf->pData, pBuf->pSpare, + (bMarkECCForScrub ? 0 : PPN_OPTIONS_IGNORE_BAD_BLOCK)); + } + + mcxt->fil->PerformCommandList(mcxt->commands, mcxt->dev.num_channels); + + if (pabSectorStats != NULL) + { + //TO DO. refer Data & Metadata ordering for PPN Health monitoring + WMR_MEMCPY(pabSectorStats, pBuf->pData, ((mcxt->dev.main_bytes_per_page) / 1024)); //Copy corresponding to + // number of kilobyte + // sectors + } + _analyzeMultiReadStatuses(mcxt, &nVpn, pBuf->pSpare, &op_status, bMarkECCForScrub, pabSectorStats); + + if (pboolNeedRefresh != NULL) + { + if (op_status & (PPNVFL_READ_RES_REFRESH | PPNVFL_READ_RES_RETIRE | PPNVFL_READ_RES_UECC)) + { + *pboolNeedRefresh = TRUE32; + } + else + { + *pboolNeedRefresh = FALSE32; + } + } + + if ((op_status & PPNVFL_READ_RES_UECC) || + ((op_status & PPNVFL_READ_RES_CLEAN) && (!bCleanCheck))) + { + return ANDErrorCodeUserDataErr; + } + else if (op_status & PPNVFL_READ_RES_CLEAN) + { + return ANDErrorCodeCleanOk; + } + else if (op_status & PPNVFL_READ_RES_VALID_DATA) + { + return ANDErrorCodeOk; + } + VFL_ERR_PRINT((TEXT("PPNVFL:ERR] _ppnvflReadSinglePage fail with op_status 0x%X (l:%d)\n"), op_status, __LINE__)); + return ANDErrorCodeHwErr; +} + +/* + * Name: _ppnvflGetFTLCxtVbn + * Description: implements GetFTLCxt for the vfl I/F + * Input: + * Return value: ftl cxt addresses array + */ +static UInt16* +_ppnvflGetFTLCxtVbn + (PPNVFL_MainCxt * mcxt) +{ + return mcxt->gen.ftl_cxt_vbn; +} + +#ifndef AND_READONLY +/* + * Name: _ppnvflWriteMultiplePagesInVb + * Description: implements multi page program for the vfl I/F + * Input: start virtual page address, number of page to program, + * data buffer, meta buffer + * ignored: replace block on fail, whitening + * Return value: TRUE32 if successful, otherwise FALSE32 + */ + +#define PPNVFL_PRINT_WRITEMULTI_SUMMARY (0) + +static BOOL32 +_ppnvflWriteMultiplePagesInVb + (PPNVFL_MainCxt * mcxt, + UInt32 dwVpn, + UInt16 wNumPagesToWrite, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening) +{ + UInt16 channel, i; + BOOL32 res = TRUE32, last_failure_updated = FALSE32; + UInt16 page_idx; + UInt16 phyCE; + + VFL_INF_PRINT(PPNVFL_PRINT_WRITEMULTI_SUMMARY, (TEXT("[PPNVFL:INF] WriteMulti(0x%08X, 0x%04X) (line:%d)!\n"), + dwVpn, wNumPagesToWrite, __LINE__)); +#ifdef AND_COLLECT_STATISTICS + mcxt->stat.ddwPagesWrittenCnt += wNumPagesToWrite; + mcxt->stat.ddwMultipleWriteCallCnt++; +#endif + + for (page_idx = 0; page_idx < wNumPagesToWrite && res; ) + { + UInt16 pages_added = wNumPagesToWrite - page_idx; + + _fillSequentialAddressesToCommandStructure(mcxt, mcxt->commands, (dwVpn + page_idx), + &pages_added, PPN_COMMAND_PROGRAM, + &pbaData[page_idx * mcxt->dev.main_bytes_per_page], + &pbaSpare[page_idx * mcxt->dev.lba_meta_bytes_buffer], + PPN_NO_OPTIONS); + mcxt->fil->PerformCommandList(mcxt->commands, mcxt->dev.num_channels); + + // handle program errors + for (channel = 0; channel < mcxt->dev.num_channels; channel++) + { + PPNCommandStruct *command = mcxt->commands[channel]; + + for (i = 0; ((command->page_status_summary & PPN_PROGRAM_STATUS_FAIL) && + (i < command->num_pages)); i++) + { + if (command->entry[i].status & PPN_PROGRAM_STATUS_FAIL) + { + UInt16 bank, block, page_offset; + BOOL32 slc; + + ppnMiscConvertPhysicalAddressToBankBlockPage(&mcxt->dev, channel, + command->entry[i].ceIdx, + command->entry[i].addr.row, &bank, &block, + &page_offset, + &slc); + + if (last_failure_updated == FALSE32) + { + phyCE = ppnMiscGetCEFromBank(&mcxt->dev,bank); + _ReportFailure(VFLFailWrite, phyCE, + command->entry[i].addr.row); + last_failure_updated = TRUE32; + } + + if (boolReplaceBlockOnFail == TRUE32) + { + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] marking (vpn: 0x%X, bank: 0x%X, block: 0x%X) for scrub (program failed) (l:%d)\n"), + dwVpn, bank, block, __LINE__)); + _markBlockForReplacement(mcxt, bank, block); + } + VFL_WRN_PRINT((TEXT( + "[PPNVFL:WRN] failed programming (bank: 0x%X, block: 0x%X, page offset: 0x%X) (line:%d)\n"), + bank, block, page_offset, __LINE__)); + res = FALSE32; + } + } + } + page_idx += pages_added; + } + return res; +} + +/* + * Name: _ppnvflWriteMultiplePagesInVb + * Description: implements multi page program for the vfl I/F + * Input: virtual page address, buffer (main + spare) + * ignored: replace block on fail, whitening + * Return value: ANDErrorCodeOk if successful, otherwise ANDErrorWriteFailureErr + */ +static Int32 +_ppnvflWriteSinglePage + (PPNVFL_MainCxt * mcxt, + UInt32 nVpn, + Buffer *pBuf, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening) +{ + BOOL32 bWriteReturn; + + bWriteReturn = _ppnvflWriteMultiplePagesInVb(mcxt, nVpn, 1, pBuf->pData, pBuf->pSpare, + boolReplaceBlockOnFail, bDisableWhitening); +#ifdef AND_COLLECT_STATISTICS + mcxt->stat.ddwSingleWriteCallCnt++; + mcxt->stat.ddwMultipleWriteCallCnt--; +#endif + if (bWriteReturn == TRUE32) + { + return ANDErrorCodeOk; + } + return ANDErrorWriteFailureErr; +} + +/* + * Name: _ppnvflErase + * Description: implements erase single virtual block for the vfl I/F + * Input: virtual block address, replace block on fail + * Return value: ANDErrorCodeOk if successful, otherwise ANDErrorWriteFailureErr + */ +#define PPNVFL_PRINT_VFLERASE_SUMMARY (0) +static Int32 +_ppnvflErase + (PPNVFL_MainCxt * mcxt, + UInt16 wVbn, + BOOL32 bReplaceOnFail) +{ + UInt32 vpn; + UInt16 i, channel, mixed_array_offset; + UInt16 blocks_to_erase = mcxt->dev.num_of_banks; + BOOL32 last_failure_updated = FALSE32; + UInt16 phyCE; + + VFL_INF_PRINT(PPNVFL_PRINT_VFLERASE_SUMMARY, (TEXT("[PPNVFL:INF] Erase (0x%04X)\n"), wVbn)); + +#ifdef AND_COLLECT_STATISTICS + mcxt->stat.ddwBlocksErasedCnt++; + mcxt->stat.ddwEraseCallCnt++; +#endif + + vpn = wVbn * mcxt->dev.pages_per_sublk; + // check if there are any blocks to replace + for (mixed_array_offset = 0; ((mcxt->gen.scrub_idx != 0) && + (mixed_array_offset < mcxt->dev.num_of_banks) && + bReplaceOnFail); mixed_array_offset++) + { + UInt16 temp_block, temp_bank, temp_page_offset; + _convertVpnToBankBlockPage(mcxt, (vpn + mixed_array_offset), &temp_bank, &temp_block, &temp_page_offset); + for (i = 0; i < mcxt->gen.scrub_idx; i++) + { + // check if this is the block we need to replace + if (mcxt->gen.scrub_list[i].bank == temp_bank && mcxt->gen.scrub_list[i].block == temp_block) + { + if (bReplaceOnFail == TRUE32) + { + if (_replaceBadBlock(mcxt, temp_bank, temp_block, wVbn, mixed_array_offset) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failed replacing a bad block (bank:0x%04X) (line:%)\n"), temp_bank, + __LINE__)); + return ANDErrorWriteFailureErr; + } + } + } + } + } + + _fillSequentialAddressesToCommandStructure(mcxt, mcxt->commands, vpn, &blocks_to_erase, PPN_COMMAND_ERASE, NULL, + NULL, PPN_NO_OPTIONS); + mcxt->fil->PerformCommandList(mcxt->commands, mcxt->dev.num_channels); + + // handle erase errors + for (channel = 0; channel < mcxt->dev.num_channels; channel++) + { + PPNCommandStruct *command = mcxt->commands[channel]; + + for (i = 0; ((command->page_status_summary & PPN_ERASE_STATUS_RETIRE) && + (i < command->num_pages)); i++) + { + if (command->entry[i].status & PPN_ERASE_STATUS_RETIRE) + { + UInt16 bank, block, page_offset; + BOOL32 slc; + PPNStatusType status; + UInt8 trials = 0; + + ppnMiscConvertPhysicalAddressToBankBlockPage(&mcxt->dev, channel, + command->entry[i].ceIdx, + command->entry[i].addr.row, &bank, &block, + &page_offset, + &slc); + if (last_failure_updated == FALSE32) + { + phyCE = ppnMiscGetCEFromBank(&mcxt->dev,bank); + _ReportFailure(VFLFailErase, phyCE, + command->entry[i].addr.row); + last_failure_updated = TRUE32; + } + + WMR_PRINT(QUAL, "Erase status failure on bank %d block %d\n", (UInt32)bank, (UInt32)block); + // replace a bad block if the caller asked us to do so + if (bReplaceOnFail == TRUE32) + { + for (trials = 0; trials < 3; trials++) + { + for (mixed_array_offset = 0; mixed_array_offset < mcxt->dev.num_of_banks; mixed_array_offset++) + { + UInt16 temp_bank = 0, temp_block = 0, temp_page_offset = 0; + _convertVpnToBankBlockPage(mcxt, (vpn + mixed_array_offset), &temp_bank, &temp_block, + &temp_page_offset); + if (bank == temp_bank && block == temp_block) + { + break; + } + } + + if (mixed_array_offset == mcxt->dev.num_of_banks) + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] error matching the failing block to vbn (bank: 0x%X, block:0x%X, vbn: 0x%X) (l:%d)\n"), + bank, block, wVbn, __LINE__)); + return ANDErrorWriteFailureErr; + } + + if (_replaceBadBlock(mcxt, bank, block, wVbn, mixed_array_offset) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] error replacing a block\n"))); + return ANDErrorWriteFailureErr; + } + + // erase the replacement block + _convertVpnToBankBlockPage(mcxt, (vpn + mixed_array_offset), &bank, &block, &page_offset); + status = + ppnMiscSingleOperation(&mcxt->dev, mcxt->single_command, PPN_COMMAND_ERASE, + PPN_NO_OPTIONS, bank, block, page_offset, slc, NULL, NULL); + if (!(status & PPN_ERASE_STATUS_RETIRE || status & PPN_ERASE_STATUS_FAIL)) + { + break; + } + else + { + WMR_PRINT(QUAL, "Erase status failure on bank %d block %d\n", (UInt32)bank, (UInt32)block); + } + } + } + else + { + return ANDErrorWriteFailureErr; + } + } + } + } + + return ANDErrorCodeOk; +} + +/* + * Name: _ppnvflChangeFTLCxtVbn + * Description: implements ChangeFTLCxt for the vfl I/F + * Input: new ftl cxt array + * Return value: ANDErrorCodeOk if successful + */ +#define PPNVFL_PRINT_CHANGEFTLCXT_SUMMARY (1) +static Int32 +_ppnvflChangeFTLCxtVbn + (PPNVFL_MainCxt * mcxt, + UInt16 *aFTLCxtVbn) +{ + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + + VFL_INF_PRINT(PPNVFL_PRINT_CHANGEFTLCXT_SUMMARY, (TEXT("[PPNVFL:INF] ChangeFTLCxtVbn (0x%04X, 0x%04X, 0x%04X)\n"), + aFTLCxtVbn[0], aFTLCxtVbn[1], aFTLCxtVbn[2])); + WMR_MEMCPY(mcxt->gen.ftl_cxt_vbn, aFTLCxtVbn, (FTL_CXT_SECTION_SIZE * sizeof(UInt16))); + + _programCxtLastPage(mcxt, buf, TRUE32); + BUF_Release(buf); + + return ANDErrorCodeOk; +} +#endif // ! AND_READONLY + +/* + * Name: _ppnvflSetStruct + * Description: implements SetStruct for the vfl I/F + * Input: type, buffer, buffer size + * Return value: TRUE32 if successful, otherwise FALSE32 + */ +static BOOL32 +_ppnvflSetStruct + (PPNVFL_MainCxt * mcxt, + UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 dwStructSize) +{ + BOOL32 result = FALSE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { +#ifndef AND_READONLY + case AND_STRUCT_VFL_FTLTYPE: + { + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + mcxt->gen.ftl_type = (*((UInt32*)pvoidStructBuffer)); + + result = _programCxtLastPage(mcxt, buf, TRUE32); + BUF_Release(buf); + } + break; + + case AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS: + { + result = _setNumOfFTLSuBlks(mcxt, *((UInt16*)pvoidStructBuffer)); + } + break; +#endif // AND_READONLY + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_BURNIN_CODE: + { + if (NULL != pvoidStructBuffer) + { + mcxt->stat.ddwBurnInCode = *((UInt32*)pvoidStructBuffer); + result = TRUE32; + } + } + break; + + case AND_STRUCT_VFL_STATISTICS: + { + if ((NULL != pvoidStructBuffer)) + { + WMR_MEMCPY(&mcxt->stat, pvoidStructBuffer, WMR_MIN(sizeof(PPNVFLStatistics), dwStructSize)); + result = TRUE32; + } + } + break; + + case AND_STRUCT_VFL_FILSTATISTICS: + { + result = FIL_SetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, dwStructSize); + } + break; +#endif //AND_COLLECT_STATISTICS + + default: + { + VFL_ERR_PRINT((TEXT( + "[PPNVFL:ERR] _ppnvflSetStruct 0x%X is not identified is VFL data struct identifier!\n"), + dwStructType)); + } + } + return result; +} + +/* + * Name: _ppnvflClose + * Description: implements close for the vfl I/F + * Input: + * Return value: none + */ +static void +_ppnvflClose + (PPNVFL_MainCxt * mcxt) +{ + if (mcxt->v2p_main != NULL) + { + WMR_FREE(mcxt->v2p_main, (sizeof(UInt16) * mcxt->gen.num_of_vfl_sublk)); + mcxt->v2p_main = NULL; + } + if (mcxt->v2p_mixed) + { + WMR_FREE(mcxt->v2p_mixed, _getV2PMixedArraySize(mcxt)); + mcxt->v2p_mixed = NULL; + } + if (mcxt->vfl_map_pages) + { + if (mcxt->vfl_map_pages[0]) + { + WMR_FREE(mcxt->vfl_map_pages[0], (sizeof(UInt16) * mcxt->dev.num_of_banks * mcxt->r_gen.pages_per_block_mapping)); + } + WMR_FREE(mcxt->vfl_map_pages, (sizeof(UInt16*) * mcxt->dev.num_of_banks)); + mcxt->vfl_map_pages = NULL; + } + if (mcxt->r_banks) + { + WMR_FREE(mcxt->r_banks, (sizeof(PPNVFL_BankRAMCxt) * mcxt->dev.num_of_banks)); + mcxt->r_banks = NULL; + } + + if (mcxt->reorder) + { + WMR_FREE(mcxt->reorder, sizeof(PPNReorderStruct)); + mcxt->reorder = NULL; + } + + if (mcxt->initialized) + { + WMR_BufZone_Free(&mcxt->bufzone); + } + WMR_MEMSET(mcxt, 0, sizeof(PPNVFL_MainCxt)); +} + +#ifndef AND_READONLY +#if (defined(AND_SUPPORT_BLOCK_BORROWING) && AND_SUPPORT_BLOCK_BORROWING) +static BOOL32 +_ppnvflBorrowSpareBlock + (PPNVFL_MainCxt * mcxt, + UInt32 *pdwPhysicalCE, + UInt32 *pdwPhysicalBlock, + UInt16 wType) +{ + BOOL32 res; + SpecialBlockAddress special_block; + + res = _ppnvflAllocateSpecialBlock(mcxt, &special_block, wType); + if (res) + { + UInt16 channel; + UInt16 ceIdx; + UInt16 cau; + UInt32 ppn_page; + channel = ppnMiscGetChannelFromBank(&mcxt->dev, special_block.bank); + ceIdx = ppnMiscGetCEIdxFromBank(&mcxt->dev, special_block.bank); + if (mcxt->format_options & WMR_INIT__USE_NEW_DUAL_CHANNEL_ADDRESS) + { + *pdwPhysicalCE = channel + (ceIdx * mcxt->dev.num_channels); + } + else + { + *pdwPhysicalCE = (channel * mcxt->dev.ces_per_channel) + ceIdx; + } + cau = ppnMiscGetCAUFromBank(&mcxt->dev, special_block.bank); + ppn_page = ppnMiscConvertToPPNPageAddress(&mcxt->dev, cau, special_block.block, 0, FALSE32); + *pdwPhysicalBlock = (ppn_page >> mcxt->dev.bits_per_page_addr); + } + return res; +} +#endif // AND_SUPPORT_BLOCK_BORROWING + +static BOOL32 +_ppnvflMarkBlockAsGrownBad + (PPNVFL_MainCxt * mcxt, + SpecialBlockAddress *block) +{ + P2BlockUsageType block_usage; + BOOL32 result; + + block_usage.p2sb.type = PPNVFL_TYPE_GROWN_BB; + block_usage.p2sb.reserved = P2SB_RESERVED_VALUE; + mcxt->r_banks[block->bank].num_special_blocks--; + mcxt->r_banks[block->bank].num_grown_bad++; + result = _setBlockUsageInVFLCxt(mcxt, block->bank, block->block, &block_usage, NULL); + + if (result) + { + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + + result = _programCxtLastPage(mcxt, buf, TRUE32); + BUF_Release(buf); + } + + return result; +} +#endif // ! AND_READONLY + +/* vfl I/F implementation - end */ + +/* global calls for the ppnvfl (using the declared global main vfl cxt struct - start */ +static Int32 +_g_ppnvflInit + (FPartFunctions * pFPartFunctions) +{ + // Init a global main structure and call the real init + if (g_ppnvflMain == NULL) + { + g_ppnvflMain = (PPNVFL_MainCxt*)WMR_MALLOC(sizeof(PPNVFL_MainCxt)); + if (g_ppnvflMain == NULL) + { + VFL_ERR_PRINT((TEXT("[PPNVFL:ERR] failure to allocate g_ppnvflMain (line:%d)"), __LINE__)); + return ANDErrorCodeHwErr; + } + WMR_MEMSET(g_ppnvflMain, 0, sizeof(PPNVFL_MainCxt)); + } + return _ppnvflInit(g_ppnvflMain, pFPartFunctions); +} + +static Int32 +_g_ppnvflOpen + (UInt32 dwKeepout, + UInt32 minor_ver, + UInt32 dwOptions) +{ + return _ppnvflOpen(g_ppnvflMain, dwKeepout, minor_ver, dwOptions); +} +#ifndef AND_READONLY +static Int32 +_g_ppnvflFormat + (UInt32 dwKeepout, + UInt32 dwOptions) +{ + return _ppnvflFormat(g_ppnvflMain, dwKeepout, dwOptions); +} +#endif //!AND_READONLY + +static BOOL32 +_g_ppnvflGetStruct + (UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 * pdwStructSize) +{ + return _ppnvflGetStruct(g_ppnvflMain, dwStructType, pvoidStructBuffer, pdwStructSize); +} + +static UInt32 +_g_ppnvflGetDeviceInfo + (UInt32 dwParamType) +{ + return _ppnvflGetDeviceInfo(g_ppnvflMain, dwParamType); +} + +static BOOL32 +_g_ppnvflReadScatteredPagesInVb + (UInt32 * padwVpn, + UInt16 wNumPagesToRead, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening, + Int32 *actualStatus) +{ + return _ppnvflReadScatteredPagesInVb(g_ppnvflMain, padwVpn, wNumPagesToRead, pbaData, + pbaSpare, pboolNeedRefresh, pabSectorStats, + bDisableWhitening, actualStatus); +} + +static Int32 +_g_ppnvflReadSinglePage + (UInt32 nVpn, + Buffer *pBuf, + BOOL32 bCleanCheck, + BOOL32 bMarkECCForScrub, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening) +{ + return _ppnvflReadSinglePage(g_ppnvflMain, nVpn, pBuf, bCleanCheck, bMarkECCForScrub, + pboolNeedRefresh, pabSectorStats, bDisableWhitening); +} +static UInt16* +_g_ppnvflGetFTLCxtVbn + (void) +{ + return _ppnvflGetFTLCxtVbn(g_ppnvflMain); +} + +#ifndef AND_READONLY + +static Int32 +_g_ppnvflWriteSinglePage + (UInt32 nVpn, + Buffer *pBuf, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening) +{ + return _ppnvflWriteSinglePage(g_ppnvflMain, nVpn, pBuf, boolReplaceBlockOnFail, bDisableWhitening); +} + +static Int32 +_g_ppnvflErase + (UInt16 wVbn, + BOOL32 bReplaceOnFail) +{ + return _ppnvflErase(g_ppnvflMain, wVbn, bReplaceOnFail); +} + +static Int32 +_g_ppnvflChangeFTLCxtVbn + (UInt16 *aFTLCxtVbn) +{ + return _ppnvflChangeFTLCxtVbn(g_ppnvflMain, aFTLCxtVbn); +} + +static BOOL32 +_g_ppnvflWriteMultiplePagesInVb + (UInt32 dwVpn, + UInt16 wNumPagesToWrite, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 boolReplaceBlockOnFail, + BOOL32 bDisableWhitening) +{ + return _ppnvflWriteMultiplePagesInVb(g_ppnvflMain, dwVpn, wNumPagesToWrite, pbaData, pbaSpare, + boolReplaceBlockOnFail, bDisableWhitening); +} + +static BOOL32 +_g_ppnvflAllocateSpecialBlock + (SpecialBlockAddress *block, + UInt16 type) +{ + return _ppnvflAllocateSpecialBlock(g_ppnvflMain, block, type); +} + +#if (defined(AND_SUPPORT_BLOCK_BORROWING) && AND_SUPPORT_BLOCK_BORROWING) +static BOOL32 +_g_ppnvflBorrowSpareBlock + (UInt32 *pdwPhysicalCE, + UInt32 *pdwPhysicalBlock, + UInt16 wType) +{ + return _ppnvflBorrowSpareBlock(g_ppnvflMain, pdwPhysicalCE, pdwPhysicalBlock, wType); +} +#endif // AND_SUPPORT_BLOCK_BORROWING + +static BOOL32 +_g_ppnvflMarkBlockAsGrownBad + (SpecialBlockAddress *block) +{ + return _ppnvflMarkBlockAsGrownBad(g_ppnvflMain, block); +} + +#endif // ! AND_READONLY + +static UInt32 +_g_ppnvflGetMinorVersion + (void) +{ + return kPPNVFLMinorVersion; +} + +static UInt16 +_g_ppnvflGetVbasPerVb + (UInt16 wVbn) +{ + return g_ppnvflMain->dev.pages_per_sublk; +} + +static BOOL32 +_g_ppnvflSetStruct + (UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 dwStructSize) +{ + return _ppnvflSetStruct(g_ppnvflMain, dwStructType, pvoidStructBuffer, dwStructSize); +} + +static void +_g_ppnvflClose + (void) +{ + if (g_ppnvflMain != NULL) + { + _ppnvflClose(g_ppnvflMain); + WMR_FREE(g_ppnvflMain, sizeof(PPNVFL_MainCxt)); + g_ppnvflMain = NULL; + } +} + +void +PPNVFL_Register + (VFLFunctions * pVFL_Functions) +{ + WMR_MEMSET(pVFL_Functions, 0, sizeof(VFLFunctions)); +#ifndef AND_READONLY + pVFL_Functions->Format = _g_ppnvflFormat; + pVFL_Functions->WriteSinglePage = _g_ppnvflWriteSinglePage; + pVFL_Functions->Erase = _g_ppnvflErase; + pVFL_Functions->ChangeFTLCxtVbn = _g_ppnvflChangeFTLCxtVbn; + pVFL_Functions->WriteMultiplePagesInVb = _g_ppnvflWriteMultiplePagesInVb; +#if (defined(AND_SUPPORT_BLOCK_BORROWING) && AND_SUPPORT_BLOCK_BORROWING) + pVFL_Functions->BorrowSpareBlock = _g_ppnvflBorrowSpareBlock; +#endif // AND_SUPPORT_BLOCK_BORROWING +#endif // ! AND_READONLY + pVFL_Functions->Init = _g_ppnvflInit; + pVFL_Functions->Open = _g_ppnvflOpen; + pVFL_Functions->Close = _g_ppnvflClose; + pVFL_Functions->ReadScatteredPagesInVb = _g_ppnvflReadScatteredPagesInVb; + pVFL_Functions->ReadSinglePage = _g_ppnvflReadSinglePage; + pVFL_Functions->GetFTLCxtVbn = _g_ppnvflGetFTLCxtVbn; + // pVFL_Functions->GetAddress = VFL_GetAddress; + pVFL_Functions->GetStruct = _g_ppnvflGetStruct; + pVFL_Functions->SetStruct = _g_ppnvflSetStruct; + pVFL_Functions->GetDeviceInfo = _g_ppnvflGetDeviceInfo; +#ifndef AND_READONLY + pVFL_Functions->AllocateSpecialBlock = _g_ppnvflAllocateSpecialBlock; + pVFL_Functions->MarkBlockAsGrownBad = _g_ppnvflMarkBlockAsGrownBad; +#endif + pVFL_Functions->GetMinorVersion = _g_ppnvflGetMinorVersion; + pVFL_Functions->GetVbasPerVb = _g_ppnvflGetVbasPerVb; +} + +static VFLFunctions _ppnvfl_functions; + +VFLFunctions * +PPN_VFL_GetFunctions + (void) +{ + PPNVFL_Register(&_ppnvfl_functions); + return &_ppnvfl_functions; +} + +/* global calls for the ppnvfl (using the declared global main vfl cxt struct - end */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLTypes.h b/drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLTypes.h new file mode 100644 index 0000000..0ddca2c --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Core/VFL/PPNVFLTypes.h @@ -0,0 +1,283 @@ +#ifndef _PPNVFL_TYPES_H_ +#define _PPNVFL_TYPES_H_ + +#include "WMRConfig.h" +#include "FPart.h" +#include "VFL.h" +#include "FIL.h" +#include "PPN_FIL.h" +#include "WMRBuf.h" +#include "PPNMiscTypes.h" + +/* defines */ +#define PPNVFL_SCRUB_BLOCK_COUNT (20) +#define PPNVFL_ROOM_FOR_BOOT_BLOCKS (20) +#define PPNVFL_MAX_SUPPORTED_BANKS (128) +#define PPNVFL_NUM_OF_VFL_CXT_BLOCK_SETS (2) +#define PPNVFL_MAX_INFO_BLOCK_COUNT (64) +#define PPNVFL_MAX_SUPPORTED_CHANNELS (2) + +// #define AND_SB_TYPE_DRIVER_SIGNATURE (AND_SB_BIT_SPEICAL_FLAG | AND_SB_BIT_PERSISTENT_FLAG | +// andSBSetHandler(AND_SB_HANDLER_SINGLE_VERSION) | andSBSetCode(AND_SB_CODE_DRIVER_SIGNATURE)) + +#define PPNVFL_CODE_VFL_AVAILABLE (0xF0) +#define PPNVFL_CODE_VFL_INFO (0xF1) +#define PPNVFL_CODE_GROWN_BB (0xFD) +#define PPNVFL_CODE_INITIAL_BB (0xFE) + +#define PPNVFL_TYPE_AVAILABLE_MARK (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_VFL_AVAILABLE)) + +#define PPNVFL_TYPE_VFL_INFO (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_VFL_INFO)) +#define PPNVFL_TYPE_GROWN_BB (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_GROWN_BB)) +#define PPNVFL_TYPE_INITIAL_BB (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_VFL_CXT) | \ + andSBSetCode(PPNVFL_CODE_INITIAL_BB)) + +#define PPNVFL_SPARE_TYPE_CXT (AND_SPARE_TYPE_REGION_VFL | 0x00) +#define PPNVFL_SPARE_TYPE_TST (AND_SPARE_TYPE_REGION_VFL | 0x01) + +#define PPNVFL_MIN_PAGE_SIZE (8192) // minimum page size in bytes + +#define PPN_V2P_MIXED_MARK (0x8000) // use the 16 bit to mark a virtual block is made + // of different blocks at different CAUs (not all the same offset) +#define PPN_V2P_UNMAPPED (0x7FFF) // indicator that this block entry is unmapped + +#define SPECIAL_BLOCK_PRE_ALLOCATION_STRIPE (8) + +#define P2SB_RESERVED_VALUE (0xFFFF) +#define P2V_RESERVED_VALUE (0x00) + +#define PPNVFL_CXT_LAST_BANKIDX (0xFF) // use this define for the index and bank of the last/summary index page +#define PPNVFL_CXT_IGNORE_BANKIDX (0xF0) // use this value to tell the read function to ignore the bank and index values + +/* PPNVFL internal structures */ + +typedef struct +{ + UInt16 block; + UInt16 bank; +} BlockAddress; + +typedef struct +{ + UInt16 vbn; // what vbn this blcok belongs to + UInt8 offset; // what offset in the vbn this block is used for if all the banks have blocks available + // this number should equal to the bank number this physical blcok is coming from + UInt8 reserved; // should be set to 0x00 at this point +} P2VType; + +typedef struct +{ + UInt16 type; // special block type + UInt16 reserved; // should be set to 0xFFFF at this point +} P2SpecialBlockType; + +typedef union +{ + P2VType p2v; + P2SpecialBlockType p2sb; +} P2BlockUsageType; + +typedef struct +{ + UInt16 pbn; + UInt8 bank; +} MixedEntryType; + +// On NAND structures - Start + +// PPNVFL_GeneralCxt - general vfl context +typedef struct +{ + UInt32 ftl_type; // FTL identifier + BlockAddress scrub_list[PPNVFL_SCRUB_BLOCK_COUNT]; + UInt16 ftl_cxt_vbn[FTL_CXT_SECTION_SIZE]; // page address (FTL virtual addressing space) of FTL Cxt + UInt16 num_of_ftl_sublk; // the number of super blocks allocated for the FTL - + // default id to give all to FTL + UInt16 num_of_vfl_sublk; // the total number of available super blocks + UInt16 scrub_idx; + UInt8 reserved[160]; + + // start the vfl_blocks array at offset 256 + BlockAddress vfl_blocks[64]; // vfl blocks physical addresses +} PPNVFL_GeneralCxt; + +// vfl blocks geometry example +// in this example redundancy of 4 and depth of 2 is used. +// the vfl is always made of two sets +// numbers are [s,r,d] where s - set (out of two), r - redundancy, d - depth + +/* + + set 0: + [0,0,0][0,0,1] + [0,1,0][0,1,1] + [0,1,0][0,1,1] + [0,3,0][0,3,1] + + set 1: + [1,0,0][1,0,1] + [1,1,0][1,1,1] + [1,1,0][1,1,1] + [1,3,0][1,3,1] + + [s,r,d] is located in: + (s * vfl_blocks_redundancy * vfl_blocks_depth) + + (d * vfl_blocks_redundancy) + r + + */ + +// PPNVFL_BankCxt - per bank vfl context +typedef struct +{ + UInt16 vfl_map_pages[16]; +} PPNVFL_BankCxt; + +// PPNVFL_OnNANDCxt - a container structure (allowing space for expension) +// for general vfl and bank specific vfl data +typedef struct +{ + // generic info + PPNVFL_GeneralCxt gen; + // bank specific info + PPNVFL_BankCxt banks[PPNVFL_MAX_SUPPORTED_BANKS]; +} PPNVFL_OnNANDCxt; + +typedef struct +{ + UInt8 spareType; // spare type + UInt8 bank; // bank number of the p2v mapping + UInt8 idx; // page number of the p2v mapping + UInt8 reserved1[1]; // reserved + UInt32 cxt_age; // context age 0xFFFFFFFF --> 0x0 + UInt8 reserved2[8]; // reserved +} PPNVFL_CxtSpare; +// On NAND structures - End + +typedef struct +{ + UInt32 cxt_age; // context age 0xFFFFFFFF --> 0x0 + UInt16 pages_per_block_mapping; // how many pages are needed for all block mapping + UInt16 pbns_per_cxt_mapping_page; // how many block mappings fit in a page + UInt16 keepout; + UInt16 vfl_blocks_redundancy; // how many copies are used in parallel per one part of the vfl blocks pair + UInt16 vfl_blocks_depth; // how many blocks are used per copy + UInt16 vfl_pages_per_set; // how many pages we can write in a set (if depth is bigger than 1 this + // number is depth * slc_page_per_block) + UInt16 num_of_vfl_blocks; // number of vfl blocks + UInt16 next_cxt_block_offset; // can be 0 or 1 two copies are written in two parallel blocks + UInt16 next_cxt_page_offset; + BOOL32 need_rewrite; + BOOL32 search_for_cxt; +} PPNVFL_GeneralRAMCxt; + +typedef struct +{ + UInt16 num_special_blocks; + UInt16 num_grown_bad; + UInt16 num_initial_bad; + UInt16 num_available; + UInt16 num_cxt; + UInt16 num_p2v; +} PPNVFL_BankRAMCxt; + +#ifdef AND_COLLECT_STATISTICS +typedef struct +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwBlocksErasedCnt; + UInt64 ddwSingleWriteCallCnt; + UInt64 ddwSingleReadCallCnt; + UInt64 ddwSequentialReadCallCnt; + UInt64 ddwScatteredReadCallCnt; + UInt64 ddwMultipleWriteCallCnt; + UInt64 ddwEraseCallCnt; + UInt64 ddwEraseTimeoutFailCnt; + UInt64 ddwBurnInCode; +} PPNVFLStatistics; + +#define VFL_STATISTICS_DESCREPTION { \ + "ddwPagesWrittenCnt", \ + "ddwPagesReadCnt", \ + "ddwBlocksErasedCnt", \ + "ddwSingleWriteCallCnt", \ + "ddwSingleReadCallCnt", \ + "ddwSequetialReadCallCnt", \ + "ddwScatteredReadCallCnt", \ + "ddwMultipleWriteCallCnt", \ + "ddwEraseCallCnt", \ + "ddwEraseTimeoutFailCnt", \ + "ddwBurnInCode", \ +} +#endif /* AND_COLLECT_STATISTICS */ + +typedef struct +{ + PPNVFL_GeneralRAMCxt r_gen; + PPN_DeviceInfo dev; + PPNVFL_GeneralCxt gen; + UInt16 **vfl_map_pages; + PPNVFL_BankRAMCxt *r_banks; + FPartFunctions *fpart; + LowFuncTbl *fil; +#ifdef AND_COLLECT_STATISTICS + PPNVFLStatistics stat; +#endif + UInt16 *v2p_main; // main virtual to physical table + // use one entry to vbn assuming no replacement block or mark + // an entry in the v2p_mixed + MixedEntryType *v2p_mixed; + UInt16 mixed_entries; + + PPNCommandStruct *commands[PPNVFL_MAX_SUPPORTED_CHANNELS]; + PPNCommandStruct *single_command; + WMR_BufZone_t bufzone; + + PPNReorderStruct *reorder; + + UInt16 **chip_enable_table; // chip_enable_table[x][y] is the physical chip enable of + // chip enable number y in channel x + + BOOL32 initialized; + UInt32 format_options; +} PPNVFL_MainCxt; // hold all other pointers + +#define PPNVFL_EXPORT_META_VERSION 0x00000001 +#define PPNVFL_MAX_SUPPORTED_BANKS_EXPORT (128) // intentionally seperating the export + // define from other defines that are used + // for on-NAND structures +#if (PPNVFL_MAX_SUPPORTED_BANKS_EXPORT < PPNVFL_MAX_SUPPORTED_BANKS) +#error PPNVFL_MAX_SUPPORTED_BANKS_EXPORT is less than PPNVFL_MAX_SUPPORTED_BANKS +#endif // PPNVFL_MAX_SUPPORTED_BANKS_EXPORT < PPNVFL_MAX_SUPPORTED_BANKS + +typedef struct +{ + UInt32 version; // make sure this value chanegs if new fields are added or the structure changes + struct + { + UInt32 num_of_channels; + UInt32 ces_per_channel; + UInt32 caus_per_ce; + } dev_info; + struct + { + struct + { + UInt32 chip_enable; + UInt16 chip_enable_idx; + UInt16 channel; + UInt16 cau; + } geometry; + UInt16 num_special_blocks; + UInt16 num_grown_bad; + UInt16 num_initial_bad; + UInt16 num_available; + UInt16 num_cxt; + UInt16 num_p2v; + } per_bank_data[PPNVFL_MAX_SUPPORTED_BANKS_EXPORT]; +} PPNVFLMetaDataExport; + +#endif /* _PPNVFL_TYPES_H_ */ diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Test/FILTest.c b/drivers/flash_nand/ppn/WhimoryPPN/Test/FILTest.c new file mode 100644 index 0000000..5e02b7e --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Test/FILTest.c @@ -0,0 +1,433 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// +// +// + +#include "WMROAM.h" +#include "WMRBuf.h" +#include "ANDTypes.h" +#include "WMRTest.h" +#include "FTL.h" +#include "PPN_FIL.h" +#include "PPNMiscTypes.h" +#include "WMRConfig.h" + +//////////////////////////////////////////////////////////////////////////////// +// Local types +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// Defines +//////////////////////////////////////////////////////////////////////////////// +#define AND_MAX_BANKS (AND_MAX_BANKS_PER_CS * 4) +#define AND_MAX_CHANNELS (2) +#define TEST_DATA_WATERMARK (0xB6) +#define TEST_META_WATERMARK (0xC7) +#define TEST_STATS_WATERMARK (0xD8) + +#define TEST_MAX_PAGES_PER_OP (2) +#define TEST_DUMP_ON_MISCOMPARE (0) + +#define PPN_COMMAND_PROGRAM (2UL) +#define PPN_COMMAND_ERASE (3UL) + + +//////////////////////////////////////////////////////////////////////////////// +// Static function declarations +//////////////////////////////////////////////////////////////////////////////// + +static BOOL32 FILInterfaceTest(UInt16 *blockList); +static BOOL32 InitTestInfo(void); +static void FillBufferWithCountingPattern(UInt8 *buffer, UInt32 startValue, UInt32 bytes); +#if TEST_DUMP_ON_MISCOMPARE +static void FILTestHexdump(void *data, UInt32 length); +#endif // TEST_DUMP_ON_MISCOMPARE + +//////////////////////////////////////////////////////////////////////////////// +// Static variables +typedef struct +{ + UInt32 pagesPerBlock; + UInt32 numCE; + UInt32 bootPageBytes; + UInt32 correctableSectorsPerPage; +} FILTestInfo; + +static FILTestInfo testInfo; +static PPN_DeviceInfo devInfo; +static LowFuncTbl *pFIL = NULL; +static WMR_BufZone_t bufZone; + + +//////////////////////////////////////////////////////////////////////////////// +// Public functions +//////////////////////////////////////////////////////////////////////////////// + +// Entry point +BOOL32 +WMR_FIL_Test + (LowFuncTbl *fil) +{ + pFIL = fil; + //return TRUE32; + return FIL_Test(); +} + + +BOOL32 FIL_Test() +{ + UInt16 blockList[AND_MAX_BANKS]; + WMR_MEMSET(blockList, 0, sizeof(UInt16) * AND_MAX_BANKS); + WMR_BufZone_Init(&bufZone); + InitTestInfo(); + ppnMiscFillDevStruct(&devInfo, pFIL); + return FILInterfaceTest(blockList); +} + +// Local functions + +BOOL32 InitTestInfo(void) +{ + testInfo.pagesPerBlock = pFIL->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + WMR_ASSERT(testInfo.pagesPerBlock > 0); + testInfo.numCE = pFIL->GetDeviceInfo(AND_DEVINFO_NUM_OF_CES_PER_CHANNEL) * pFIL->GetDeviceInfo(AND_DEVINFO_NUM_OF_CHANNELS); + WMR_ASSERT(testInfo.numCE > 0); + + testInfo.bootPageBytes = pFIL->GetDeviceInfo(AND_DEVINFO_BYTES_PER_BL_PAGE); + WMR_ASSERT(testInfo.bootPageBytes > 0); + + return TRUE32; +} + + + + +// Block list is assumed to be numBanks long and non-overlapping banks +BOOL32 isClean(UInt8 *buf, UInt32 size) +{ + UInt32 i; + for (i=0; ipage_status_summary != 0x40) + { + WMR_PRINT(ALWAYS, "Erase failed with summary status = 0x%x\n", ppnCmd[0]->page_status_summary); + goto exit; + } + + // Clean check single page + WMR_PRINT(ALWAYS, "Clean checking CAU %d Block %d Page %d\n", bank, blockList[0], page); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, dataPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, metaPerPage); + ppnMiscInitCommandStructure(&devInfo, ppnCmd, devInfo.num_channels, PPN_COMMAND_READ, PPN_NO_OPTIONS); + for (lba = 0 ; lba < devInfo.lbas_per_page ; lba++) + { + ppnMiscAddPhysicalAddressToCommandStructure(&devInfo, ppnCmd, + ppnMiscGetChannelFromBank(&devInfo, bank), + ppnMiscGetCEIdxFromBank(&devInfo, bank), + ppnMiscGetCAUFromBank(&devInfo, bank), + blockList[0], 0, FALSE32, devInfo.lbas_per_page - 1 - lba, 1, lba, 0); + ppnMiscAddMemoryToCommandStructure(&devInfo, ppnCmd, devInfo.num_channels, + &verifyDataBuffer[lba * devInfo.main_bytes_per_lba], + &verifyMetaBuffer[lba * devInfo.lba_meta_bytes_buffer], + 1); + } + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, dataBufferSize); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, metaBufferSize); + ppnMiscReorderCommandStruct(&devInfo, ppnCmd, devInfo.num_channels, ppnReorder); + pFIL->PerformCommandList(ppnCmd, 1); + for (lba = 0 ; lba < devInfo.lbas_per_page ; lba++) + { + WMR_PRINT(ALWAYS, "ppnCmd[0]->entry[%d].status = 0x%08x\n", lba, ppnCmd[0]->entry[lba].status); + } + if (ppnCmd[0]->page_status_summary != 0x49) + { + WMR_PRINT(ALWAYS, "Clean check single page failed with summary status = 0x%x\n", ppnCmd[0]->page_status_summary); + goto exit; + } + if (isClean(verifyDataBuffer, dataPerPage) == FALSE32) + { + WMR_PRINT(ALWAYS, "Clean Detect failed: Main!\n"); + //goto exit; + } + if (isClean(verifyMetaBuffer, metaPerPage) == FALSE32) + { + WMR_PRINT(ALWAYS, "Clean Detect failed: Meta!\n"); + //goto exit; + } + + // Program single page + WMR_PRINT(ALWAYS, "Writing single page CAU %d Block %d Page %d\n", bank, blockList[0], page); + FillBufferWithCountingPattern(writeDataBuffer, testSeed++, dataPerPage); + FillBufferWithCountingPattern(writeMetaBuffer, testSeed++, metaPerPage); + ppnMiscSingleOperation(&devInfo, ppnCmd[0], PPN_COMMAND_PROGRAM, PPN_NO_OPTIONS, bank, blockList[0], page, FALSE32, writeDataBuffer, writeMetaBuffer); + if (ppnCmd[0]->page_status_summary != 0x62) + { + WMR_PRINT(ALWAYS, "Program single page failed with summary status = 0x%x\n", ppnCmd[0]->page_status_summary); + goto exit; + } + + // Read back and verify + WMR_PRINT(ALWAYS, "Reading back single page CAU %d Block %d Page %d\n", bank, blockList[0], page); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, dataPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, metaPerPage); + ppnMiscSingleOperation(&devInfo, ppnCmd[0], PPN_COMMAND_READ, PPN_NO_OPTIONS, bank, blockList[0], page, FALSE32, verifyDataBuffer, verifyMetaBuffer); + if (ppnCmd[0]->page_status_summary != 0x40) + { + WMR_PRINT(ALWAYS, "Read back single page failed with summary status = 0x%x\n", ppnCmd[0]->page_status_summary); + goto exit; + } + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, metaPerPage)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in meta section\n"); +#if TEST_DUMP_ON_MISCOMPARE + WMR_PRINT(ALWAYS, "Expected:\n"); + FILTestHexdump(writeMetaBuffer, metaPerPage); + WMR_PRINT(ALWAYS, "Actual:\n"); + FILTestHexdump(verifyMetaBuffer, metaPerPage); +#endif // TEST_DUMP_ON_MISCOMPARE + goto exit; + } + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, dataPerPage)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in data section\n"); +#if TEST_DUMP_ON_MISCOMPARE + WMR_PRINT(ALWAYS, "Expected:\n"); + FILTestHexdump(writeDataBuffer, dataPerPage); + WMR_PRINT(ALWAYS, "Actual:\n"); + FILTestHexdump(verifyDataBuffer, dataPerPage); +#endif // TEST_DUMP_ON_MISCOMPARE + goto exit; + } + + // MultiBlockErase (Block from all bank) + WMR_PRINT(ALWAYS, "Erasing Block %d from all banks\n", blockList[0]); + ppnMiscInitCommandStructure(&devInfo, ppnCmd, devInfo.num_channels, PPN_COMMAND_ERASE, PPN_NO_OPTIONS); + for (bank=0; bankPerformCommandList(ppnCmd, devInfo.num_channels); + for (channel = 0 ; channel < devInfo.num_channels ; channel++) + { + if (ppnCmd[channel]->page_status_summary != 0x40) + { + WMR_PRINT(ALWAYS, "MultiBlockErase failed with summary status = 0x%x\n", ppnCmd[channel]->page_status_summary); + goto exit; + } + } + + // MultiPageProgram (Program 2 pages on each bank) + WMR_PRINT(ALWAYS, "Multipage Programming %d pages of Block %d of each bank\n", TEST_MAX_PAGES_PER_OP, blockList[0]); + ppnMiscInitCommandStructure(&devInfo, ppnCmd, devInfo.num_channels, PPN_COMMAND_PROGRAM, PPN_NO_OPTIONS); + for (bank=0; bank page ; page++) + { + ppnMiscAddPhysicalAddressToCommandStructure(&devInfo, ppnCmd, + ppnMiscGetChannelFromBank(&devInfo, bank), + ppnMiscGetCEIdxFromBank(&devInfo, bank), + ppnMiscGetCAUFromBank(&devInfo, bank), + blockList[0], page, FALSE32, 0, devInfo.lbas_per_page, bank*2+page, 0); + ppnMiscAddMemoryToCommandStructure(&devInfo, ppnCmd, devInfo.num_channels, + &writeDataBuffer[(bank*2+page) * dataPerPage], + &writeMetaBuffer[(bank*2+page) * metaPerPage], + devInfo.lbas_per_page); + } + } + FillBufferWithCountingPattern(writeDataBuffer, testSeed++, dataBufferSize); + FillBufferWithCountingPattern(writeMetaBuffer, testSeed++, metaBufferSize); + ppnMiscReorderCommandStruct(&devInfo, ppnCmd, devInfo.num_channels, ppnReorder); + pFIL->PerformCommandList(ppnCmd, devInfo.num_channels); + for (channel = 0 ; channel < devInfo.num_channels ; channel++) + { + if (ppnCmd[channel]->page_status_summary != 0x62) + { + WMR_PRINT(ALWAYS, "Multipage Program failed with summary status = 0x%x\n", ppnCmd[channel]->page_status_summary); + goto exit; + } + } + + // MultiPageRead (Read 2 pages on each bank) + WMR_PRINT(ALWAYS, "Multipage Read of %d pages of Block %d of each bank\n", TEST_MAX_PAGES_PER_OP, blockList[0]); + ppnMiscInitCommandStructure(&devInfo, ppnCmd, devInfo.num_channels, PPN_COMMAND_READ, PPN_NO_OPTIONS); + for (bank=0; bank page ; page++) + { + ppnMiscAddPhysicalAddressToCommandStructure(&devInfo, ppnCmd, + ppnMiscGetChannelFromBank(&devInfo, bank), + ppnMiscGetCEIdxFromBank(&devInfo, bank), + ppnMiscGetCAUFromBank(&devInfo, bank), + blockList[0], page, FALSE32, 0, devInfo.lbas_per_page, bank*2+page, 0); + ppnMiscAddMemoryToCommandStructure(&devInfo, ppnCmd, devInfo.num_channels, + &verifyDataBuffer[(bank*2+page) * dataPerPage], + &verifyMetaBuffer[(bank*2+page) * metaPerPage], + devInfo.lbas_per_page); + } + } + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, dataBufferSize); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, metaBufferSize); + ppnMiscReorderCommandStruct(&devInfo, ppnCmd, devInfo.num_channels, ppnReorder); + pFIL->PerformCommandList(ppnCmd, devInfo.num_channels); + for (channel = 0 ; channel < devInfo.num_channels ; channel++) + { + if (ppnCmd[channel]->page_status_summary != 0x40) + { + WMR_PRINT(ALWAYS, "Multipage Read failed with summary status = 0x%x\n", ppnCmd[channel]->page_status_summary); + goto exit; + } + } + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, metaBufferSize)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in meta section\n"); +#if TEST_DUMP_ON_MISCOMPARE + WMR_PRINT(ALWAYS, "Expected:\n"); + FILTestHexdump(writeMetaBuffer, metaBufferSize); + WMR_PRINT(ALWAYS, "Actual:\n"); + FILTestHexdump(verifyMetaBuffer, metaBufferSize); +#endif // TEST_DUMP_ON_MISCOMPARE + goto exit; + } + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, dataBufferSize)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in data section\n"); +#if TEST_DUMP_ON_MISCOMPARE + WMR_PRINT(ALWAYS, "Expected:\n"); + FILTestHexdump(writeDataBuffer, dataBufferSize); + WMR_PRINT(ALWAYS, "Actual:\n"); + FILTestHexdump(verifyDataBuffer, dataBufferSize); +#endif // TEST_DUMP_ON_MISCOMPARE + goto exit; + } + + ret = TRUE32; + +exit: + WMR_PRINT(ALWAYS, "Interface Test %s\n", ret ? "Passed" : "Failed"); + + if (ppnReorder) + { + WMR_FREE(ppnReorder, sizeof(PPNReorderStruct)); + } + + WMR_BufZone_Free(&bufZone); + + return ret; +} + +static void FillBufferWithCountingPattern(UInt8 *buffer, UInt32 value, UInt32 bytes) +{ + UInt32 *word; + + if (0 != bytes % sizeof(*word)) + { + const UInt32 extra = bytes % sizeof(*word); + + bytes -= extra; + WMR_MEMCPY(&buffer[bytes], &value, extra); + value++; + } + + while (0 < bytes) + { + bytes -= sizeof(*word); + word = (UInt32 *)&buffer[bytes]; + *word = value++; + } +} + + +#if TEST_DUMP_ON_MISCOMPARE +#define HEXDUMP_WIDTH (16) +static void FILTestHexdump(void *data, UInt32 length) +{ + UInt32 i, j; + UInt8 *bytes = (UInt8*) data; + for (i = 0; i < length; i += HEXDUMP_WIDTH) + { + for (j = 0; (j < HEXDUMP_WIDTH) && ((i + j) < length); j++) + { + _WMR_PRINT(" %02x", (UInt32) *bytes++); + } + _WMR_PRINT("\n"); + } +} +#endif // TEST_DUMP_ON_MISCOMPARE + diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Test/FPartTest.c b/drivers/flash_nand/ppn/WhimoryPPN/Test/FPartTest.c new file mode 100644 index 0000000..f5a8a39 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Test/FPartTest.c @@ -0,0 +1,45 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// +// +// Just call WMR_FPart_Test() with an init'ed FPart +// + +#include "WMROAM.h" +#include "WMRBuf.h" +#include "ANDTypes.h" +#include "WMRTest.h" +#include "FPart.h" + +//////////////////////////////////////////////////////////////////////////////// +// Local types +//////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////// +// Static variables + + +//////////////////////////////////////////////////////////////////////////////// +// Static function declarations +//////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////// +// Public functions +//////////////////////////////////////////////////////////////////////////////// + +// Entry point +BOOL32 +WMR_FPart_Test + (FPartFunctions *fpart) +{ + return TRUE32; +} diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Test/FTLTest.c b/drivers/flash_nand/ppn/WhimoryPPN/Test/FTLTest.c new file mode 100644 index 0000000..9400dbd --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Test/FTLTest.c @@ -0,0 +1,45 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// +// +// Just call WMR_FTL_Test() with an opened FTL +// + +#include "WMROAM.h" +#include "WMRBuf.h" +#include "ANDTypes.h" +#include "WMRTest.h" +#include "FTL.h" + +//////////////////////////////////////////////////////////////////////////////// +// Local types +//////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////// +// Static variables + + +//////////////////////////////////////////////////////////////////////////////// +// Static function declarations +//////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////// +// Public functions +//////////////////////////////////////////////////////////////////////////////// + +// Entry point +BOOL32 +WMR_FTL_Test + (FTLFunctions *ftl) +{ + return TRUE32; +} diff --git a/drivers/flash_nand/ppn/WhimoryPPN/Test/VFLTest.c b/drivers/flash_nand/ppn/WhimoryPPN/Test/VFLTest.c new file mode 100644 index 0000000..f48ea63 --- /dev/null +++ b/drivers/flash_nand/ppn/WhimoryPPN/Test/VFLTest.c @@ -0,0 +1,426 @@ +// Copyright (C) 2010 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// +// +// Just call WMR_VFL_Test() with an opened VFL. Test will run on burnin +// area, leaving FTL untouched +// + +#include "WMROAM.h" +#include "WMRBuf.h" +#include "ANDTypes.h" +#include "VFL.h" + +#define SVFL 0 +//////////////////////////////////////////////////////////////////////////////// +// Local types +//////////////////////////////////////////////////////////////////////////////// +typedef struct +{ + UInt16 num_ftl_vb; + UInt16 num_total_vb; + UInt16 pages_per_vb; + UInt16 bytes_per_page; + UInt32 lba_per_page; + UInt32 bytes_per_meta; +}VFLTestInfo; + +typedef struct +{ + void * write_main; + void * write_meta; + void * verify_main; + void * verify_meta; + UInt32 * virtual_page_list; +}VFLTestBuffers; + +//////////////////////////////////////////////////////////////////////////////// +// Static variables +//////////////////////////////////////////////////////////////////////////////// + +static VFLFunctions *_vfl = NULL; +static VFLTestInfo _test_info; +static VFLTestBuffers _buf; + +VFLTestBuffers *my_vfl_test_buffers = &_buf; // convenience pointer + +#if(SVFL) +static VFL_ReadSpans_t s; +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Static function declarations +//////////////////////////////////////////////////////////////////////////////// + +static BOOL32 +_GetVFLUInt16 + (UInt32 struct_name, + UInt16 *value); + +static BOOL32 +_GetVFLUInt32 + (UInt32 struct_name, + UInt32 *value); + +static BOOL32 +_GetTestInfo + (void); + +static void +_FillBuffer + (UInt8 *buffer, + UInt32 size, + UInt8 seed); + +static void +_FillSwissMetaBuffer + (UInt8 *buffer, + UInt32 size, + UInt8 seed); + +static BOOL32 +_RunSequentialTest + (void); + +//////////////////////////////////////////////////////////////////////////////// +// Public functions +//////////////////////////////////////////////////////////////////////////////// + +// Entry point +BOOL32 +WMR_VFL_Test + (VFLFunctions *vfl) +{ + WMR_BufZone_t zone; + BOOL32 result = TRUE32; + + WMR_MEMSET(&_test_info, 0, sizeof(_test_info)); + WMR_MEMSET(&_buf, 0, sizeof(_buf)); + + _vfl = vfl; + if (!_GetTestInfo()) + { + return FALSE32; + } + + WMR_BufZone_Init(&zone); + + _buf.write_main = WMR_Buf_Alloc_ForDMA(&zone, + _test_info.pages_per_vb * _test_info.bytes_per_page); + _buf.write_meta = WMR_Buf_Alloc_ForDMA(&zone, + _test_info.pages_per_vb * _test_info.lba_per_page * _test_info.bytes_per_meta ); + _buf.verify_main = WMR_Buf_Alloc_ForDMA(&zone, + _test_info.pages_per_vb * _test_info.bytes_per_page); + _buf.verify_meta = WMR_Buf_Alloc_ForDMA(&zone, + _test_info.pages_per_vb * _test_info.lba_per_page * _test_info.bytes_per_meta); + + result = WMR_BufZone_FinishedAllocs(&zone); + WMR_ASSERT(result); + + WMR_BufZone_Rebase(&zone, &_buf.write_main); + WMR_BufZone_Rebase(&zone, &_buf.write_meta); + WMR_BufZone_Rebase(&zone, &_buf.verify_main); + WMR_BufZone_Rebase(&zone, &_buf.verify_meta); + + WMR_BufZone_FinishedRebases(&zone); + + _buf.virtual_page_list = WMR_MALLOC(sizeof(UInt32) * _test_info.pages_per_vb); + WMR_ASSERT(NULL != _buf.virtual_page_list); + + result = _RunSequentialTest(); + + WMR_BufZone_Free(&zone); + WMR_FREE(_buf.virtual_page_list, sizeof(UInt32) * _test_info.pages_per_vb); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// Static function implementations +//////////////////////////////////////////////////////////////////////////////// +#if SVFL +static void vfl_read_cb(UInt32 vba, VFLReadStatusType status, UInt8 *meta) +{ + if (status & VFL_READ_STATUS_REFRESH) { + WMR_PANIC( "sftl: requested refresh vba:0x%x status:0x%x\n", vba, status); + } + if (status & VFL_READ_STATUS_RETIRE) { + WMR_PANIC("sftl: requested retire vba:0x%x status:0x%x\n", vba, status); + } + if (status & VFL_READ_STATUS_UECC) { + WMR_PANIC("sftl: error uECC vba:0x%x status:0x%x\n", vba, status); + } + if (status & VFL_READ_STATUS_CLEAN) { + WMR_PANIC("sftl: error clean vba:0x%x status:0x%x\n", vba, status); + } +} +#endif // SVFL + +BOOL32 +_RunSequentialTest + (void) +{ + BOOL32 nand_result; + UInt16 block; + + const UInt32 TEST_CHUNK_PAGES = _test_info.pages_per_vb; + + const UInt32 bytes_per_stripe_main = + TEST_CHUNK_PAGES * _test_info.bytes_per_page; + const UInt32 bytes_per_stripe_meta = + TEST_CHUNK_PAGES * _test_info.lba_per_page * _test_info.bytes_per_meta; + + _FillBuffer(_buf.write_main, bytes_per_stripe_main, 0x34); + _FillSwissMetaBuffer(_buf.write_meta, bytes_per_stripe_meta, 0); + + WMR_MEMCPY(_buf.verify_main, _buf.write_main, bytes_per_stripe_main); + WMR_MEMCPY(_buf.verify_meta, _buf.write_meta, bytes_per_stripe_meta); + +#if(!SVFL) //Vanilla PPNVFL + { +#ifndef AND_READONLY + UInt32 page; + BOOL32 needs_refresh = FALSE32; + + WMR_PRINT(ALWAYS,"***************************************Vanilla PPNVFL test starting******************************\n"); + for (block = _test_info.num_ftl_vb; block < _test_info.num_total_vb; ++block) + { + Int32 status = FIL_SUCCESS; + const UInt32 first_page_in_vb = block * _test_info.pages_per_vb; + WMR_PRINT(ALWAYS, "Erase block %d(0x%08x)\n", block, block); + status = _vfl->Erase(block, FALSE32); + WMR_ASSERT(VFL_SUCCESS == status); + WMR_PRINT(ALWAYS, "Write pages %d(0x%08x):%d\n", + first_page_in_vb, first_page_in_vb, _test_info.pages_per_vb); + nand_result = _vfl->WriteMultiplePagesInVb(first_page_in_vb, + TEST_CHUNK_PAGES, + _buf.write_main, + _buf.write_meta, + FALSE32, + FALSE32); + + WMR_ASSERT(nand_result); + + for (page = 0; page < TEST_CHUNK_PAGES; ++page) + { + _buf.virtual_page_list[page] = first_page_in_vb + page; + } + WMR_PRINT(ALWAYS, "Readback pages %d(0x%08x):%d\n", + first_page_in_vb, first_page_in_vb, _test_info.pages_per_vb); + status = _vfl->ReadScatteredPagesInVb(_buf.virtual_page_list, + TEST_CHUNK_PAGES, + _buf.verify_main, + _buf.verify_meta, + &needs_refresh, + NULL, + FALSE32, + NULL); + + //WMR_ASSERT(VFL_SUCCESS == status); + WMR_ASSERT(!WMR_MEMCMP(_buf.verify_main, _buf.write_main, bytes_per_stripe_main)); + WMR_ASSERT(!WMR_MEMCMP(_buf.verify_meta, _buf.write_meta, bytes_per_stripe_meta)); + WMR_ASSERT(!needs_refresh); + } +#endif // !AND_READONLY + // Make another read pass after all programming is complete + for (block = _test_info.num_ftl_vb; block < _test_info.num_total_vb; ++block) + { + const UInt32 first_page_in_vb = block * _test_info.pages_per_vb; + for (page = 0; page < TEST_CHUNK_PAGES; ++page) + { + _buf.virtual_page_list[page] = first_page_in_vb + page; + } + WMR_PRINT(ALWAYS, "Read pages %d(0x%08x):%d\n", + first_page_in_vb, first_page_in_vb, _test_info.pages_per_vb); + nand_result = _vfl->ReadScatteredPagesInVb(_buf.virtual_page_list, + TEST_CHUNK_PAGES, + _buf.verify_main, + _buf.verify_meta, + &needs_refresh, + NULL, + FALSE32, + NULL); + + WMR_ASSERT(nand_result); + WMR_ASSERT(!WMR_MEMCMP(_buf.verify_main, _buf.write_main, bytes_per_stripe_main)); + WMR_ASSERT(!WMR_MEMCMP(_buf.verify_meta, _buf.write_meta, bytes_per_stripe_meta)); + WMR_ASSERT(!needs_refresh); + } + + } +#else //SwissVFL + { + UInt32 vba; + WMR_PRINT(ALWAYS,"***************************************SVFL test starting******************************\n"); + WMR_PRINT(ALWAYS,"pages_per_vb = %d, lbas_per_page = %d\n",_test_info.pages_per_vb, _test_info.lba_per_page); + WMR_PRINT(ALWAYS,"start blk = %d, end_blk = %d\n",_test_info.num_ftl_vb, _test_info.num_total_vb); + WMR_PRINT(ALWAYS,"bytes_per_meta = %d, buf_write_data: 0x%X, buf_write_meta: 0x%X, buf_read_data: 0x%X, buf_read_meta: 0x%X\n", + _test_info.bytes_per_meta, _buf.write_main, _buf.write_meta, _buf.verify_main, _buf.verify_meta); + + //Erase + Program + for (block = _test_info.num_ftl_vb; block < _test_info.num_total_vb; ++block) + { + if(!(_vfl->GetVbasPerVb(block))) + { + continue; + } + Int32 status = FIL_SUCCESS; + const UInt32 first_page_in_vb = block * _test_info.pages_per_vb; + const UInt32 VbasInBlock = _vfl->GetVbasPerVb(block); + + WMR_PRINT(ALWAYS, "Erase block %d(0x%08x)\n", block, block); + status = _vfl->Erase(block, FALSE32); + WMR_ASSERT(VFL_SUCCESS == status); + nand_result = _vfl->ProgramMultipleVbas((first_page_in_vb * _test_info.lba_per_page), + VbasInBlock, + _buf.write_main, + _buf.write_meta, + FALSE32, + TRUE32); + WMR_ASSERT(nand_result); + } + + //Readback + for (block = _test_info.num_ftl_vb; block < _test_info.num_total_vb; ++block) + { + if(!(_vfl->GetVbasPerVb(block))) + { + continue; + } + const UInt32 start_vba = block * _test_info.pages_per_vb * _test_info.lba_per_page; + const UInt32 end_vba = start_vba + _vfl->GetVbasPerVb(block); + for(vba = start_vba; vba < end_vba; vba++) + { + _vfl->ReadSpansInit(&s, vfl_read_cb, VFL_READ_STATUS_ALL, TRUE32, FALSE32); + _vfl->ReadSpansAdd(&s, vba, 1, _buf.verify_main, _buf.verify_meta); + if(_vfl->ReadSpans(&s) & (VFL_READ_STATUS_UECC | VFL_READ_STATUS_CLEAN)) + { + ANDAddressStruct stAddr; + UInt32 dwAddrSize = sizeof(stAddr); + stAddr.dwVpn = vba; + _vfl->GetStruct(AND_STRUCT_VFL_GETADDRESS, &stAddr, &dwAddrSize); + WMR_PANIC("error reading: vba: = 0x%x cs = 0x%x ppn = 0x%x\n", vba, stAddr.dwCS, stAddr.dwPpn); + } + WMR_ASSERT(!WMR_MEMCMP(_buf.verify_main, _buf.write_main, (_test_info.bytes_per_page/_test_info.lba_per_page))); + WMR_ASSERT(!WMR_MEMCMP(_buf.verify_meta, _buf.write_meta, _test_info.bytes_per_meta)); + } + } + } +#endif + + WMR_PRINT(ALWAYS, "*************************************Test Passed***********************************************\n"); + return TRUE32; +} + +static void +_FillBuffer + (UInt8 *buffer, + UInt32 size, + UInt8 seed) +{ + // Use a counting pattern for now + while (size--) + { + *buffer++ = seed++; + } +} + +static void +_FillSwissMetaBuffer + (UInt8 *buffer, + UInt32 size, + UInt8 seed) +{ + UInt8 original_seed = seed; + // Use a counting pattern for now + while (size--) + { + *buffer++ = seed++; + if((seed % (_test_info.bytes_per_meta)) == 0 ) + { + seed = original_seed; + } + } +} + +BOOL32 +_GetVFLUInt16 + (UInt32 struct_name, + UInt16 *value) +{ + UInt32 size = sizeof(*value); + + WMR_ASSERT(NULL != value); + *value = 0; + if (!_vfl->GetStruct(struct_name, value, &size) || + (size != sizeof(*value))) + { + WMR_PRINT(ERROR, "Failed 0x%08x\n", struct_name); + return FALSE32; + } + return TRUE32; +} + +BOOL32 +_GetVFLUInt32 + (UInt32 struct_name, + UInt32 *value) +{ + UInt32 size = sizeof(*value); + + WMR_ASSERT(NULL != value); + *value = 0; + if (!_vfl->GetStruct(struct_name, value, &size) || + (size > sizeof(*value))) + { + WMR_PRINT(ERROR, "Failed 0x%08x\n", struct_name); + return FALSE32; + } + return TRUE32; +} + +BOOL32 +_GetTestInfo + (void) +{ + if (!_GetVFLUInt16(AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS, + &_test_info.num_ftl_vb)) + { + return FALSE32; + } + + if (!_GetVFLUInt16(AND_STRUCT_VFL_NUM_OF_SUBLKS, + &_test_info.num_total_vb)) + { + return FALSE32; + } + + if (!_GetVFLUInt16(AND_STRUCT_VFL_PAGES_PER_SUBLK, + &_test_info.pages_per_vb)) + { + return FALSE32; + } + + if (!_GetVFLUInt16(AND_STRUCT_VFL_BYTES_PER_PAGE, + &_test_info.bytes_per_page)) + { + return FALSE32; + } + + _test_info.lba_per_page = _vfl->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + + if (!_GetVFLUInt32(AND_STRUCT_VFL_BYTES_PER_META, + &_test_info.bytes_per_meta)) + { + return FALSE32; + } + + return TRUE32; +} + diff --git a/drivers/flash_nand/ppn/export.txt b/drivers/flash_nand/ppn/export.txt new file mode 100644 index 0000000..bc1cf5d --- /dev/null +++ b/drivers/flash_nand/ppn/export.txt @@ -0,0 +1,12 @@ +_WMR_Open +_WMR_PPN_GetFTL +_WMR_PPN_GetFPart +_WMR_Start +_WMR_PPN_CtrlIO +_ppn_init +_ppnMiscSingleOperation +_ppnMiscFillDevStruct +_ppnMiscGetCEFromBank +_ppnMiscSingleLbaRead +_ppnMiscConvertToPPNPageAddress +_ppnMiscConvertPhysicalAddressToCauBlockPage diff --git a/drivers/flash_nand/ppn/library.mk b/drivers/flash_nand/ppn/library.mk new file mode 100644 index 0000000..8660159 --- /dev/null +++ b/drivers/flash_nand/ppn/library.mk @@ -0,0 +1,61 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +WHIMORYPPN_DIR := $(GET_LOCAL_DIR) +WHIMORYPPN_BUILD := $(call TOLIBDIR,$(WHIMORYPPN_DIR)/WHIMORYPPN.a) +COMMONLIBS += WHIMORYPPN + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +NAND_DIR := $(patsubst %/,%,$(dir $(GET_LOCAL_DIR))) + +MODULES += \ + drivers/flash_nand/OAM \ + lib/blockdev + +GLOBAL_INCLUDES += \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/VFL \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/FTL \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/FPart \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/Misc \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Boot \ + $(NAND_DIR)/raw/Whimory/Inc \ + $(NAND_DIR)/OAM \ + $(NAND_DIR)/OAM/iBoot + +$(info WHIMORYPPN_DIR is $(WHIMORYPPN_DIR)) + +# base library files +WHIMORYPPN_SUBOBJS += \ + $(WHIMORYPPN_DIR)/ppn.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/FPart/PPNFPart.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/Misc/PPNMisc.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/Misc/VFLBuffer.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/FTL/yaFTL.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/FTL/yaFTL_BTOC.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Core/VFL/PPNVFLInterface.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Boot/WhimoryBoot.o \ + $(WHIMORYPPN_DIR)/WhimoryPPN/Boot/RegVanilla.o + +WHIMORYPPN_SUBOBJS := $(call TOLIBOBJDIR,$(WHIMORYPPN_SUBOBJS)) +ALL_DEPS += $(WHIMORYPPN_SUBOBJS:%o=%d) + +WHIMORYPPN_OBJS := $(call TOLIBOBJDIR,$(WHIMORYPPN_DIR)/WHIMORYPPN.o) + + +$(WHIMORYPPN_OBJS): $(WHIMORYPPN_SUBOBJS) + @echo LIB_LD $@ + $(_v)$(_LD) $(LIBRARY_LDFLAGS) $(WHIMORYPPN_SUBOBJS) -o $@ -exported_symbols_list $(WHIMORYPPN_DIR)/export.txt + +$(WHIMORYPPN_BUILD): $(WHIMORYPPN_OBJS) + +endif diff --git a/drivers/flash_nand/ppn/ppn.c b/drivers/flash_nand/ppn/ppn.c new file mode 100644 index 0000000..83262a9 --- /dev/null +++ b/drivers/flash_nand/ppn/ppn.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "FIL.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTL.h" +#include "WhimoryBoot.h" +#include "WMROAM.h" + + + +extern uint32_t nand_fsys_block_offset; + +static int nand_filesys_init(uint32_t block_size, uint32_t block_count); +static FTLFunctions *TLFuncPtr=NULL; +static int nand_read_block_hook(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count) +{ + Int32 err; + + if (count > 0) { + err = TLFuncPtr->Read(block, count, ptr); + //err = FTL_Read(block, count, ptr); + + if (err != FIL_SUCCESS) { + printf("nand_read_block_hook: failure %d reading block %u, count %zd\n", err, block, count); + return -1; + } + } + return count; +} + +int ppn_init(void) +{ + uint32_t block_size, block_count; + uint32_t index_cache = 0; + WhimoryBootCode boot_code; + + dprintf(DEBUG_INFO, "ppn_init()\n"); + + // Find a signature + boot_code = WMR_Start(0, 0, gWhimoryInitParameters); + if (kWhimoryOk == boot_code) { + // Open the FTL + boot_code = WMR_Open(&block_count, &block_size, &index_cache, gWhimoryInitParameters); + if (kWhimoryOk == boot_code) { + // Publish a block device + if (0 != nand_filesys_init(block_size, block_count)) { + return 0; + } + } + } else if (kWhimoryWarningUnformatted == boot_code) { + printf("***NAND driver is not formatted. Run restore process.***\n"); + } + return -1; +} + +static int nand_filesys_init(uint32_t block_size, uint32_t block_count) +{ + struct blockdev *nand; + + TLFuncPtr = WMR_PPN_GetFTL(); + // build a block device around this NAND + nand = malloc(sizeof(struct blockdev)); + + construct_blockdev(nand, "nand0", (uint64_t)block_count * block_size, block_size); + + nand->read_block_hook = &nand_read_block_hook; + + register_blockdev(nand); + + /* scan ourselves for partitions and publish subdevices */ + partition_scan_and_publish_subdevices("nand0"); + + return 0; +} diff --git a/drivers/flash_nand/ppn/ppn_syscfg.c b/drivers/flash_nand/ppn/ppn_syscfg.c new file mode 100644 index 0000000..82636dc --- /dev/null +++ b/drivers/flash_nand/ppn/ppn_syscfg.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_SYSCFG + +#include +#include +#include + +#include "FPart.h" +#include "VFLBuffer.h" +#include "WMRConfig.h" +#include "WhimoryBoot.h" + +extern uint32_t nand_fsys_block_offset; + +// The syscfg library assumes that syscfg will be 0x4000 bytes into +// the device regardles of whether it's NAND or NOR. nand1 will ONLY +// expose syscfg, so this doesn't make any sense, but we'll say we're +// big enough to read that far in anyway. +#define kSysCfgActualSize ( 0x4000 ) +#define kFakeBdevBlockSize (kSysCfgBdevOffset) +#define kFakeBdevCapacity (kSysCfgBdevOffset + kSysCfgActualSize) + + + +static FPartFunctions *_fpart = NULL; + +int ppn_syscfg_init(void) +{ + WhimoryBootCode boot_code; + + boot_code = WMR_Start(0, 0, 0); + if (kWhimoryOk == boot_code) { + _fpart = WMR_PPN_GetFPart(); + if (NULL != _fpart->ReadSpecialBlock) { + return 0; + } else { + dprintf(DEBUG_CRITICAL, "ppn syscfg is not supported!\n"); + return -1; + } + } + return -1; +} + +int ppn_read_syscfg_hook(struct blockdev *_dev, void *ptr, block_addr block, size_t count) +{ + bool ok = true; + + // Only allow reading the "second" block + if ((block != 1) || (count != 1)) { + dprintf(DEBUG_CRITICAL, "attempted to read ppn syscfg at non-zero offset\n"); + ok = false; + + } else if (count > 0) { + if (!_fpart->ReadSpecialBlock(ptr, kFakeBdevBlockSize, AND_SB_TYPE_UNIQUE_INFO)) { + dprintf(DEBUG_CRITICAL, "ppn_read_syscfg_hook: failure reading syscfg\n"); + ok = false; + } + } + + if (!ok) + return -1; + + return count; +} + +#endif /* WITH_SYSCFG */ diff --git a/drivers/flash_nand/ppn/rules.mk b/drivers/flash_nand/ppn/rules.mk new file mode 100644 index 0000000..a9a01da --- /dev/null +++ b/drivers/flash_nand/ppn/rules.mk @@ -0,0 +1,36 @@ +# Copyright (c) 2007-2009 Apple Inc. All rights reserved. +# Copyright (c) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PPN=1 \ + WITH_PPN_SYSCFG=1 + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/WhimoryPPN/Core/FPart \ + $(LOCAL_DIR)/WhimoryPPN/Core/Misc \ + $(LOCAL_DIR)/WhimoryPPN/Boot + +ALL_OBJS += \ + $(LOCAL_DIR)/ppn_syscfg.o + +# +# If a NAND FTL has not been configured, we need some of the raw NAND bits. +# +ifeq ($(WITH_NAND_FTL),) +ALL_OBJS += \ + $(LOCAL_DIR)/WhimoryPPN/Core/FPart/PPNFPart.o \ + $(LOCAL_DIR)/WhimoryPPN/Core/Misc/PPNMisc.o \ + $(LOCAL_DIR)/WhimoryPPN/Boot/WhimoryBoot.o +else +LIBRARY_MODULES += $(LOCAL_DIR) +endif diff --git a/drivers/flash_nand/raw/Whimory/Core/FPart/FPart.c b/drivers/flash_nand/raw/Whimory/Core/FPart/FPart.c new file mode 100644 index 0000000..fef3395 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FPart/FPart.c @@ -0,0 +1,1925 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL interface */ +/* FILE : VFLinterface.c */ +/* PURPOSE : This file contains the exported routine for interfacing with*/ +/* the upper layer of VFL. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 16-SEP-2003 [SJ Myoung] : multi-block read speed up */ +/* flash_read(,,,UInt8 sector_offset) add argument */ +/* 22-SEP-2003 [JH Kim] : buf_get() bug-fix (if no free buffer) */ +/* 29-SEP-2003 [HM Jung] : code size reduction */ +/* check init bad from PAGE_CLEAN */ +/* 03-NOV-2003 [JH Kim] : replace_bad_block() - add loop when erase */ +/* if erase fail */ +/* 12-JAN-2004 [JH Kim] : fix by sequential order */ +/* 26-JAN-2004 [JH Kim] : add buffer usage trace code */ +/* 13-MAR-2005 [Jaesung Jung] : duet port */ +/* 21-MAR-2005 [Jaesung Jung] : move ASSERT DEFINE to copy_data.h */ +/* 21-MAR-2005 [Jaesung Jung] : remove pattern_test code */ +/* 28-MAR-2005 [Jaesung Jung] : add logical to physical API */ +/* 07-APR-2005 [Jaesung Jung] : MLC support (2way) */ +/* 08-APR-2005 [Jaesung Jung] : add context checksum check */ +/* 11-APR-2005 [Jaesung Jung] : optimize PAGE_CLEAN check */ +/* 18-JUL-2005 [Jaesung Jung] : reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : bug-fix from code inspection */ +/* 22-NOV-2005 [Yangsup Lee ] : remove checksum code */ +/* 24-JAN-2006 [Yangsup Lee ] : change sector offset to sector bitmap */ +/* 24-JAN-2006 [Yangsup Lee ] : support un-pair bad block management */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Header file inclusions */ +/*****************************************************************************/ +// avoid using the generic device info and move the info to the layers + +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "FIL.h" +#include "FPartTypes.h" +#include "FPart.h" + +#define GET_Ppn(Pbn, POffset) ((Pbn) * BLOCK_STRIDE + (POffset)) /* translate block + pages offset to page address*/ +#define BLOCKS_PER_CS (stUnderVFLDeviceInfo.wBlocksPerCS) +#define CS_TOTAL (stUnderVFLDeviceInfo.wNumOfCEs) +#define PAGES_PER_BLOCK (stUnderVFLDeviceInfo.wPagesPerBlock) +#define BYTES_PER_PAGE (stUnderVFLDeviceInfo.wBytesPerPage) +#define BYTES_PER_SPARE (stUnderVFLDeviceInfo.wBytesPerSpare) +#define INITIAL_BBT_TYPE (stUnderVFLDeviceInfo.checkInitialBadType) +#define BYTES_PER_BL_PAGE (stUnderVFLDeviceInfo.wBytesPerBLPage) +#define DIES_PER_CS (stUnderVFLDeviceInfo.wDiesPerCS) +#define BLOCKS_PER_DIE (stUnderVFLDeviceInfo.wBlocksPerDie) +#define DIE_STRIDE (stUnderVFLDeviceInfo.wDieStride) +#define BLOCK_STRIDE (stUnderVFLDeviceInfo.wBlockStride) +#define LAST_ADDRESSABLE_BLOCK (stUnderVFLDeviceInfo.wLastBlock) +#define GET_Pbn(wDieIdx, wBlkIdx) ((wDieIdx) * DIE_STRIDE + (wBlkIdx)) +#define _Cbn2Pbn(Cbn) (((Cbn) / BLOCKS_PER_DIE) * DIE_STRIDE + ((Cbn) % BLOCKS_PER_DIE)) //contiguous physical block to non-contiguous + +// 4% bad blocks are calculated from the nearest power of two +#define WORST_CASE_LAST_GOOD_BLOCK (((1UL << WMR_LOG2(BLOCKS_PER_CS)) * 96) / 100) + +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ +#define WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS (3) +#define MAX_ATTEMTS_BBT (3) + +/*****************************************************************************/ +/* Static variables definitions */ +/*****************************************************************************/ +specialBlockCache (*blockCacheArray)[MAX_NUM_SPECIAL_BLOCKS_PER_CS] = NULL; +/*****************************************************************************/ +/* UnderVFL local function prototypes */ +/*****************************************************************************/ + +// Part 1 static declarations +static BOOL32 _ReadSpecialInfoBlock(UInt16 wCS, SpecialBlockHeaderStruct * pSpecialBlockHeaderStruct, UInt8 * pabData, + UInt32 dwDataBufferSize, UInt8 * pbaSignature, UInt32 dwSignatureSize, BOOL32 boolCheckBlockZero,UInt16 *signatureLocation); + +#ifndef AND_READONLY +static BOOL32 _CheckInitialBad(UInt16 wCS, UInt16 wPbn, + Buffer *pBuf, Buffer *pSpareBuf, UInt32 *pInitBad); +static BOOL32 _CreateBBT(UInt16 wCS, UInt8 * pBBT); +static BOOL32 _WriteSpecialBlock(UInt16 wCS, UInt16 wPBlk, SpecialBlockHeaderStruct * pSpecialBlockHeaderStruct, UInt8 * pabData, UInt32 dwDataBufferSize); +static BOOL32 VFL_WriteDeviceUniqueInfo(UInt8 * pabData, UInt32 dwDataBufferSize); +static BOOL32 VFL_WriteDiagControlInfo(UInt8 * pabData, UInt32 dwDataBufferSize); +#endif // ! AND_READONLY + +static LowFuncTbl *pFuncTbl = NULL; +static UnderVFLDeviceInfo stUnderVFLDeviceInfo; +static FPartSignatureStyle stFPartSignatureStyle; +#ifndef AND_READONLY +static BOOL32 bSupportDevUniqueInfo = FALSE32; +static BOOL32 bSupportDiagCtrlInfo = FALSE32; +#endif // ! AND_READONLY + +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + +static BOOL32 specialBlockCachePopulated = FALSE32; + + +/* special block cache */ +static void specialBlockCache_Init(void) +{ + UInt8 i,j,k; + + if( blockCacheArray == NULL ) + { + blockCacheArray = (specialBlockCache (*)[MAX_NUM_SPECIAL_BLOCKS_PER_CS])WMR_MALLOC(CS_TOTAL * MAX_NUM_SPECIAL_BLOCKS_PER_CS * sizeof(specialBlockCache)); + if(blockCacheArray == NULL) + { + WMR_PRINT(ERROR, TEXT("specialBlockCache_Init : unable to allocate special block cache of size 0x%x\n"),CS_TOTAL * MAX_NUM_SPECIAL_BLOCKS_PER_CS * sizeof(specialBlockCache)); + return; + } + } + + for(i=0;i= CS_TOTAL)) + return FALSE32; + + WMR_MEMSET(defaultSignature,0xff,SPECIAL_BLOCK_SIGNATURE_SIZE); + for(i=0;i= CS_TOTAL)) + return FALSE32; + + for(i=0;iabSignature,blockCacheArray[csNo][i].abSignature,SPECIAL_BLOCK_SIGNATURE_SIZE) == 0) + break; + } + if(i < MAX_NUM_OF_SPECIALS) + { + WMR_MEMCPY(sbCacheEntry,&(blockCacheArray[csNo][i]),sizeof(specialBlockCache)); + return TRUE32; + } + return FALSE32; +} + +static BOOL32 specialBlockCache_invalidate(UInt8 csNo, const UInt8 * blockSignature, UInt8 arrayElement) +{ + UInt8 i; + + if((blockCacheArray == NULL) || (blockSignature == NULL) || (csNo >= CS_TOTAL)) + return FALSE32; + + for(i=0;i> 3; + bBit = (1 << (((UInt8)wIdx) & 0x07)); + if (pbaBBT[dByteLocation] & bBit) + { + return TRUE32; + } + return FALSE32; +} +#endif // ! AND_READONLY + +BOOL32 VFL_ReadBBT(UInt16 wCS, UInt8* pBBT) +{ + BBTInfoHeaderStruct bbtInfoHeaderStruct; + BOOL32 result; + + if (pBBT) + { + WMR_MEMSET(pBBT, 0, BBT_SIZE_PER_CS); + } + + result = _ReadSpecialInfoBlock(wCS, (SpecialBlockHeaderStruct*) &bbtInfoHeaderStruct, pBBT, BBT_SIZE_PER_CS, (UInt8 *)BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE, FALSE32, NULL); + + return result; +} + +BOOL32 VFL_ReadBBTWithoutSpecial(UInt16 wCS, UInt8* pBBT) +{ + BOOL32 result; + UInt32 idx; + BBTInfoHeaderStruct tmpHeader; + + result = _ReadSpecialInfoBlock(wCS, (SpecialBlockHeaderStruct*)&tmpHeader, pBBT, BBT_SIZE_PER_CS, (UInt8 *)BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE, FALSE32, NULL); + + // Block 0 is guaranteed to be good + _MarkBlockAsGoodInBBT(pBBT, 0); + + // Find the FPart special blocks that have been marked as bad + for (idx = 0; + (idx < MAX_NUM_SPECIAL_BLOCKS_PER_CS) && ((tmpHeader.adwSpecialBlocks[idx] & VFL_BLOCK_INDEX_MASK) != VFL_INVALID_INFO_INDEX); + ++idx) + { + _MarkBlockAsGoodInBBT(pBBT, tmpHeader.adwSpecialBlocks[idx]); + } + + return result; +} + +static BOOL32 VFL_VerifyProductionFormat(void) +{ + BOOL32 res = TRUE32; + UInt16 wCS; + BBTInfoHeaderStruct bbtInfoHeaderStruct; + + // Since we're in recovery mode, check if we're whitening or not + + if (FIL_GetFuncTbl()->SetWhiteningState) + { + FIL_GetFuncTbl()->SetWhiteningState(TRUE32); + } + + for (wCS = 0; wCS < CS_TOTAL && res == TRUE32; wCS++) + { + res = VFL_ReadBBT(wCS, NULL); + if (!res && (wCS == 0) && FIL_GetFuncTbl()->SetWhiteningState) + { + // If we couldn't find a BBT with whitening, + // try it without and leave it turned off if bbt located + FIL_GetFuncTbl()->SetWhiteningState(FALSE32); + res = VFL_ReadBBT(0, NULL); + if (!res && (wCS == 0)) + { + /* virgin device . go with whitening if avaiable */ + FIL_GetFuncTbl()->SetWhiteningState(TRUE32); + } + if( res && (wCS == 0)) + WMR_PRINT(ALWAYS, TEXT("[FIL] Disable data whitening\n")); + } + } + + if ( res && _ReadSpecialInfoBlock(0, (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, NULL, 0, (UInt8*)BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE, TRUE32, NULL) ) + { + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] BBT found in CS 0 Block 0... Forcing a failure of %s().\n"), __FUNCTION__); + res = FALSE32; + } + + return res; +} + +#define CLEAN_PAGE_THRESHOLD 3 +#define HW_ERROR_THRESHOLD 2 + +static BOOL32 readOneSpecialBlock(UInt16 wCS, UInt16 wBlkIdx, SpecialBlockHeaderStruct * pSpecialBlockHeaderStruct, UInt8 * pabData, + UInt32 dwDataBufferSize, UInt8 * pbaSignature, UInt32 dwSignatureSize, UInt16 *signatureLocation, BOOL32 updateSBCache) +{ + UInt16 wPageIdx, wCleanPages = 0, wHWErrors = 0; + Buffer *pBuf; + + if (pFuncTbl == NULL) + { + pFuncTbl = FIL_GetFuncTbl(); + } + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuf == NULL) + { + return FALSE32; + } + + if(pbaSignature == NULL) + return FALSE32; + + for (wPageIdx = 0; (wPageIdx < PAGES_PER_BLOCK) && (wCleanPages < CLEAN_PAGE_THRESHOLD) && (wHWErrors < HW_ERROR_THRESHOLD); wPageIdx++) + { + Int32 nRet; + nRet = pFuncTbl->ReadMaxECC(wCS, GET_Ppn(_Cbn2Pbn(wBlkIdx), wPageIdx), pBuf->pData); + if (nRet == FIL_SUCCESS) + { + if (WMR_MEMCMP(pBuf->pData, pbaSignature, dwSignatureSize) == 0) + { + /* we found the relevant page */ + UInt32 dwDataSizeOnFlash; + UInt32 dwBytesRead = 0, dwBytesToRead; + + if(signatureLocation != NULL) + *signatureLocation = wBlkIdx; + // header information back to the caller + if (pSpecialBlockHeaderStruct != NULL) + { + WMR_MEMCPY(pSpecialBlockHeaderStruct, pBuf->pData, sizeof(SpecialBlockHeaderStruct)); + } + + // retrieve the data size + dwDataSizeOnFlash = ((SpecialBlockHeaderStruct *)pBuf->pData)->dwDataSize; + if (pabData == NULL) + { + BUF_Release(pBuf); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(updateSBCache == TRUE32) + specialBlockCache_set(wCS, pbaSignature, wBlkIdx); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + return TRUE32; + } + dwBytesToRead = WMR_MIN(dwDataSizeOnFlash, dwDataBufferSize); + // retrieve the data if it is all in one page + if (dwBytesToRead <= (BYTES_PER_PAGE - sizeof(SpecialBlockHeaderStruct))) + { + WMR_MEMCPY(pabData, &pBuf->pData[sizeof(SpecialBlockHeaderStruct)], WMR_MIN(dwDataSizeOnFlash, dwDataBufferSize)); + BUF_Release(pBuf); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(updateSBCache == TRUE32) + specialBlockCache_set(wCS, pbaSignature, wBlkIdx); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + return TRUE32; + } + WMR_MEMCPY(pabData, &pBuf->pData[sizeof(SpecialBlockHeaderStruct)], (BYTES_PER_PAGE - sizeof(SpecialBlockHeaderStruct))); + dwBytesRead += (BYTES_PER_PAGE - sizeof(SpecialBlockHeaderStruct)); + wPageIdx++; + while (dwBytesRead < dwBytesToRead && wPageIdx < PAGES_PER_BLOCK) + { + nRet = pFuncTbl->ReadMaxECC(wCS, GET_Ppn(_Cbn2Pbn(wBlkIdx), wPageIdx), pBuf->pData); + if (nRet == FIL_SUCCESS) + { + UInt32 dwBytesToCopyThisTime = WMR_MIN(BYTES_PER_PAGE, (dwBytesToRead - dwBytesRead)); + WMR_MEMCPY(&pabData[dwBytesRead], pBuf->pData, dwBytesToCopyThisTime); + dwBytesRead += dwBytesToCopyThisTime; + wPageIdx++; + } + else + { + break; + } + } + if (dwBytesToRead == dwBytesRead) + { + BUF_Release(pBuf); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(updateSBCache == TRUE32) + specialBlockCache_set(wCS, pbaSignature, wBlkIdx); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + return TRUE32; + } + } + } + if (nRet == FIL_SUCCESS_CLEAN) + { + wCleanPages++; + } + if (nRet == FIL_CRITICAL_ERROR) + { + wHWErrors++; + } + } + BUF_Release(pBuf); + return FALSE32; +} + +static BOOL32 _ReadSpecialInfoBlock(UInt16 wCS, SpecialBlockHeaderStruct * pSpecialBlockHeaderStruct, UInt8 * pabData, + UInt32 dwDataBufferSize, UInt8 * pbaSignature, UInt32 dwSignatureSize, BOOL32 boolCheckBlockZero,UInt16 *signatureLocation) +{ + UInt16 wBlkIdx, wBlkEnd; + specialBlockCache sbCacheEntry; + + WMR_MEMSET(&sbCacheEntry,0,sizeof(specialBlockCache)); + if(pbaSignature != NULL) + WMR_MEMCPY(sbCacheEntry.abSignature,pbaSignature,SPECIAL_BLOCK_SIGNATURE_SIZE); + else + return FALSE32; + +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if((boolCheckBlockZero == FALSE32) && (specialBlockCache_get(wCS, &sbCacheEntry))) + { // !!!! Vadim : makes ure thet maxSpecial is according to the signature + UInt8 i; + UInt8 maxSpecialNo = 2; + if(WMR_MEMCMP(sbCacheEntry.abSignature,NAND_DRIVER_SIGN_BLOCK_SIGNATURE,SPECIAL_BLOCK_SIGNATURE_SIZE) == 0) + maxSpecialNo = 1; + for(i = 0;i < maxSpecialNo;i++) + { + if(sbCacheEntry.sbLocation[i].locationValid == TRUE32) + wBlkIdx = sbCacheEntry.sbLocation[i].location; + else + continue; + if( readOneSpecialBlock(wCS, wBlkIdx, pSpecialBlockHeaderStruct, pabData, + dwDataBufferSize, pbaSignature, dwSignatureSize, signatureLocation,FALSE32) ) + return TRUE32; + else + specialBlockCache_invalidate(wCS, pbaSignature, i); + + + } + + } +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + { + if (boolCheckBlockZero) + { + wBlkIdx = 1; + wBlkEnd = 1; + } + else + { + /* search for a valid index structure - starting from the last block */ + wBlkIdx = BLOCKS_PER_CS; + wBlkEnd = WORST_CASE_LAST_GOOD_BLOCK; + } + + while (wBlkIdx-- >= wBlkEnd) + { + if( readOneSpecialBlock(wCS, wBlkIdx, pSpecialBlockHeaderStruct, pabData, + dwDataBufferSize, pbaSignature, dwSignatureSize, signatureLocation,TRUE32) ) + { +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(WMR_MEMCMP(sbCacheEntry.abSignature,BBT_BLOCK_SIGNATURE,SPECIAL_BLOCK_SIGNATURE_SIZE) == 0) + { + if(wCS == 0) + { + specialBlockCache_set(wCS, (UInt8 *)BBT_BLOCK_SIGNATURE, pSpecialBlockHeaderStruct->adwReserved[FPART_SPECIAL_BLK_BBT_BACKUP_IDX]); + specialBlockCache_set(wCS, (UInt8 *)UNIQUE_INFO_BLOCK_SIGNATURE, pSpecialBlockHeaderStruct->adwReserved[FPART_SPECIAL_BLK_DEV_UNIQUE_PRIMARY_IDX]); + specialBlockCache_set(wCS, (UInt8 *)UNIQUE_INFO_BLOCK_SIGNATURE, pSpecialBlockHeaderStruct->adwReserved[FPART_SPECIAL_BLK_DEV_UNIQUE_BACKUP_IDX]); + specialBlockCache_set(wCS, (UInt8 *)NAND_DRIVER_SIGN_BLOCK_SIGNATURE, pSpecialBlockHeaderStruct->adwReserved[FPART_SPECIAL_BLK_DEV_SIGNATURE_IDX]); + specialBlockCache_set(wCS, (UInt8 *)DIAG_INFO_BLOCK_SIGNATURE, pSpecialBlockHeaderStruct->adwReserved[FPART_SPECIAL_BLK_DIAG_CTRL_PRIMARY_IDX]); + specialBlockCache_set(wCS, (UInt8 *)DIAG_INFO_BLOCK_SIGNATURE, pSpecialBlockHeaderStruct->adwReserved[FPART_SPECIAL_BLK_DIAG_CTRL_BACKUP_IDX]); + specialBlockCachePopulated = TRUE32; + } + else + { + specialBlockCache_set(wCS, (UInt8 *)BBT_BLOCK_SIGNATURE, pSpecialBlockHeaderStruct->adwReserved[FPART_SPECIAL_BLK_BBT_BACKUP_IDX]); + } + } +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + return TRUE32; + } + } + } + return FALSE32; +} + +#ifndef AND_READONLY + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_FactoryReformat */ +/* DESCRIPTION */ +/* This function reformats a unit safely */ +/* PARAMETERS */ +/* BOOL32 Force - wipe all blocks without care */ +/* RETURN VALUES */ +/* ANDErrorCodeOk */ +/* Format is completed. */ +/* ANDErrorCodeHwErr */ +/* Format is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_FactoryReformat(BOOL32 boolForce, BOOL32 boolEraseBlockZero, UInt32 dwKeepoutArea) +{ + UInt16 wCSIdx, wDieIdx, wBlkIdx, wBBTIdx; + UInt8 *pabBBTBuffer = NULL; + + WMR_PRINT(LOG, TEXT("[VFL: IN] ++VFL_FactoryReformat()\n")); + + /* allocate buffer for the BBT */ + pabBBTBuffer = (UInt8*)WMR_MALLOC(BBT_SIZE_PER_CS); + if (pabBBTBuffer == NULL) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] failed to allocate BBT buffer!\n")); + return ANDErrorCodeHwErr; + } + + // check if there is any hope at all of getting a valid BBT + if ((boolForce == TRUE32) || (VFL_VerifyProductionFormat() == TRUE32)) + { + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + if ((boolForce == TRUE32) || (VFL_ReadBBT(wCSIdx, pabBBTBuffer) == TRUE32)) + { + WMR_PRINT(ALWAYS, TEXT("[VFL:INF] BBT found for CS %d\n"), wCSIdx); + wBBTIdx = dwKeepoutArea; + for (wDieIdx = 0; wDieIdx < DIES_PER_CS; wDieIdx++) + { + if( wDieIdx == 0 ) + wBlkIdx = dwKeepoutArea; + else + wBlkIdx = 0; + for (; wBlkIdx < BLOCKS_PER_DIE; wBlkIdx++) + { + // only erase good blocks + if ((boolForce == TRUE32) || _isBlockGood(pabBBTBuffer, wBBTIdx)) + { + /* check that the block is erasable */ + UInt16 wEraseCnt; + for (wEraseCnt = 0; wEraseCnt < WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS; wEraseCnt++) + { + Int32 nFILRet; + nFILRet = pFuncTbl->Erase(wCSIdx, GET_Pbn(wDieIdx, wBlkIdx)); + if (nFILRet == FIL_SUCCESS) + { + break; + } + } + if (wEraseCnt == WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Failed erasing CS %d block 0x%X\n"), wCSIdx, wBBTIdx); + _MarkBlockAsBadInBBT(pabBBTBuffer, wBBTIdx); + } + } + wBBTIdx++; + } + } + if (boolEraseBlockZero == TRUE32) + { + Int32 nFILRet; + nFILRet = pFuncTbl->Erase(wCSIdx, 0); + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Faild erasing block 0\n")); + } + } + } + else + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] No BBT found for CS %d\n"), wCSIdx); + WMR_FREE(pabBBTBuffer, BBT_SIZE_PER_CS); + return ANDErrorCodeHwErr; + } + } + } + else + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] No factory bad block tables found!\n")); + WMR_FREE(pabBBTBuffer, BBT_SIZE_PER_CS); + return ANDErrorCodeHwErr; + } + + WMR_FREE(pabBBTBuffer, BBT_SIZE_PER_CS); + WMR_PRINT(LOG, TEXT("[VFL:OUT] --VFL_FactoryReformat()\n")); + return ANDErrorCodeOk; +} + +static BOOL32 _testSpecialBlockCandidate(UInt16 wBank, UInt16 wPBlk) +{ + Buffer *pBuf = NULL; + UInt16 i; + Int32 nFILRet; + BOOL32 res = TRUE32; + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuf == NULL) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] VFL_WriteInitialBBT failed allocating buffer for spare\n")); + return FALSE32; + } + + WMR_MEMSET(pBuf->pData , 0, BYTES_PER_PAGE); + WMR_MEMSET(pBuf->pSpare , 0, BYTES_PER_METADATA_RAW); + nFILRet = pFuncTbl->Erase(wBank, _Cbn2Pbn(wPBlk)); + if(nFILRet != FIL_SUCCESS ) + { + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] testSpecialBlockCandidate failed erasing bank %d, 0x%04X \n"), wBank, wPBlk); + res = FALSE32; + } + for(i=0;(i < PAGES_PER_BLOCK) && (nFILRet == FIL_SUCCESS);i++) + { + nFILRet = pFuncTbl->Write(wBank, GET_Ppn(_Cbn2Pbn(wPBlk), i), pBuf->pData, pBuf->pSpare, TRUE32); + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] testSpecialBlockCandidate failed writing to bank %d, 0x%04X \n"), wBank, wPBlk); + res = FALSE32; + break; + } + nFILRet = pFuncTbl->ReadWithECC(wBank, GET_Ppn(_Cbn2Pbn(wPBlk), i), pBuf->pData, pBuf->pSpare, NULL, NULL, TRUE32); + if (nFILRet != FIL_SUCCESS) + { + res = FALSE32; + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] testSpecialBlockCandidate failed reading bank %d, 0x%04X \n"), wBank, wPBlk); + break; + } + } + +#if (defined(WMR_ENABLE_ERASE_PROG_BAD_BLOCK)) + if (!res) + { + WMR_ENABLE_ERASE_PROG_BAD_BLOCK(wBank, _Cbn2Pbn(wPBlk)); + } +#endif // WMR_ENABLE_ERASE_PROG_BAD_BLOCK + + nFILRet = pFuncTbl->Erase(wBank, _Cbn2Pbn(wPBlk)); + +#if (defined(WMR_DISABLE_ERASE_PROG_BAD_BLOCK)) + if (!res) + { + WMR_DISABLE_ERASE_PROG_BAD_BLOCK(wBank, _Cbn2Pbn(wPBlk)); + } +#endif // WMR_DISABLE_ERASE_PROG_BAD_BLOCK + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] testSpecialBlockCandidate failed erasing bank %d, 0x%04X \n"), wBank, wPBlk); + res = FALSE32; + } + BUF_Release(pBuf); + return res; +} + +static BOOL32 +VFL_WriteInitialBBT(void) +{ + BOOL32 res = TRUE32, bbtDone = FALSE32; + UInt16 wCSIdx; + BBTInfoHeaderStruct bbtInfoHeaderStruct; + UInt8 *pabBBTBuffer = NULL,*pabBBTBufferRAMOnly = NULL; + UInt8 tryNo, BBTRAMCS = 0xff; + Buffer *pBuf = NULL; + + // Special-block ordering currently requires that we have syscfg + // FPart Special Block Assignment Bug + WMR_ASSERT(bSupportDevUniqueInfo); + + /* allocate buffer for the BBT */ + pabBBTBuffer = (UInt8*)WMR_MALLOC(BBT_SIZE_PER_CS); + pabBBTBufferRAMOnly = (UInt8*)WMR_MALLOC(BBT_SIZE_PER_CS); + for(tryNo = 0, wCSIdx = 0 ; ( tryNo < MAX_ATTEMTS_BBT ) && ( bbtDone == FALSE32 ) ; tryNo++) + { + res = TRUE32; + while(wCSIdx < CS_TOTAL) + { + UInt16 wBBIdx, wBBEnd; + UInt16 wMarkIdx; + BOOL32 boolBlk0HasBBT = FALSE32; + UInt32 dwCurrentCENumSpecialBlocks; + + WMR_MEMCPY(bbtInfoHeaderStruct.abSignature, BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE); + WMR_MEMSET(bbtInfoHeaderStruct.adwSpecialBlocks, 0xFF, sizeof(bbtInfoHeaderStruct.adwSpecialBlocks)); + bbtInfoHeaderStruct.dwBBTSize = BBT_SIZE_PER_CS; + bbtInfoHeaderStruct.dwVersion = VFL_BBT_STRUCT_VERSION; + WMR_PRINT(ALWAYS, TEXT("[VFL:inf] VFL_WriteInitialBBT about to scan CS %d \n"), wCSIdx); + /* check if block 0 has the BBT in it */ + WMR_MEMSET(pabBBTBuffer, 0, BBT_SIZE_PER_CS); + boolBlk0HasBBT = _ReadSpecialInfoBlock(wCSIdx, (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, pabBBTBuffer, BBT_SIZE_PER_CS, (UInt8*)BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE, TRUE32, NULL); + + /* get bbt */ + if (boolBlk0HasBBT == FALSE32) + { + WMR_PRINT(ALWAYS, TEXT("[VFL:inf] VFL_WriteInitialBBT no BBT in block 0 scanning CS %d \n"), wCSIdx); + WMR_MEMSET(pabBBTBuffer, 0, BBT_SIZE_PER_CS); + res = _CreateBBT(wCSIdx, pabBBTBuffer); + if (res == FALSE32) + { + WMR_PRINT(FACTORY, "[VFL:inf] VFL_WriteInitialBBT _CreateBBT failed CS 0x%x\n", wCSIdx); + break; + } + /* Mark block 0 as bad - we use this block to store the bootloader / signature */ + _MarkBlockAsBadInBBT(pabBBTBuffer, 0); + /* write the BBT to the BBT blocks as well as block 0 */ + res = _WriteSpecialBlock(wCSIdx, 0, (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, pabBBTBuffer, BBT_SIZE_PER_CS); + if (res == FALSE32) + { + WMR_PRINT(FACTORY, "[VFL:inf] VFL_WriteInitialBBT updating block 0 at CS 0x%x failed \n", wCSIdx); + pFuncTbl->Erase(wCSIdx, 0); + break; + } + } + else + { + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] VFL_WriteIntialBBT found BBT in Block0, but not SpecialBlocks\n")); + } + if (BBTRAMCS != wCSIdx) + { + WMR_MEMCPY(pabBBTBufferRAMOnly, pabBBTBuffer, BBT_SIZE_PER_CS); + BBTRAMCS = wCSIdx; + } + if (wCSIdx == 0) + { + dwCurrentCENumSpecialBlocks = DEFAULT_NUMBER_OF_SPECIAL_BLOCKS_CS0; + if (bSupportDevUniqueInfo) + { + dwCurrentCENumSpecialBlocks += FPART_COPIES_OF_SPECIAL_INFO; + } + if (bSupportDiagCtrlInfo) + { + dwCurrentCENumSpecialBlocks += FPART_COPIES_OF_SPECIAL_INFO; + } + } + else + { + dwCurrentCENumSpecialBlocks = NUMBER_OF_SPECIAL_BLOCKS_NOTCS0; + } + + wBBIdx = (UInt16)(BLOCKS_PER_CS); + wBBEnd = WORST_CASE_LAST_GOOD_BLOCK; + for (wMarkIdx = 0; wMarkIdx < dwCurrentCENumSpecialBlocks; ) + { + while (wBBIdx-- >= wBBEnd) + { + if (_isBlockGood(pabBBTBufferRAMOnly, wBBIdx)) + { + break; + } + } + if (wBBIdx < wBBEnd - 1) + { + WMR_PRINT(FACTORY, "[VFL:ERR] VFL_WriteInitialBBT ran out of Special Block candidates: CS %d, passed %d, needed %d, tested %d\n", + wCSIdx, wMarkIdx, dwCurrentCENumSpecialBlocks, BLOCKS_PER_CS - WORST_CASE_LAST_GOOD_BLOCK + 1); + res = FALSE32; + break; + } + if( _testSpecialBlockCandidate( wCSIdx, wBBIdx) == FALSE32 ) + { + WMR_PRINT(ERROR, TEXT("[VFL:inf] VFL_WriteInitialBBT testSpecialBlockCandidate failed at 0x%x 0x%x \n"),wCSIdx, wBBIdx); + _MarkBlockAsBadInBBT(pabBBTBufferRAMOnly, wBBIdx); + continue; + } + _MarkBlockAsBadInBBT(pabBBTBuffer, wBBIdx); + bbtInfoHeaderStruct.adwSpecialBlocks[wMarkIdx] = wBBIdx; + wMarkIdx++; + } + if(res == FALSE32) + { + break; + } + res = _WriteSpecialBlock(wCSIdx, (UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_PRIMARY_IDX], (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, pabBBTBuffer, BBT_SIZE_PER_CS); + if (res == FALSE32) + { + WMR_PRINT(FACTORY, "[VFL:inf] VFL_WriteInitialBBT failed udating CS 0x%x block 0x%x \n", wCSIdx, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_PRIMARY_IDX]); + _MarkBlockAsBadInBBT(pabBBTBufferRAMOnly, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_PRIMARY_IDX]); + pFuncTbl->Erase(wCSIdx, _Cbn2Pbn((UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_PRIMARY_IDX])); + break; + } + res = _WriteSpecialBlock(wCSIdx, (UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_BACKUP_IDX], (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, pabBBTBuffer, BBT_SIZE_PER_CS); + if (res == FALSE32) + { + WMR_PRINT(FACTORY, "[VFL:inf] VFL_WriteInitialBBT failed udating CS 0x%x block 0x%x \n", wCSIdx, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_BACKUP_IDX]); + _MarkBlockAsBadInBBT(pabBBTBufferRAMOnly, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_BACKUP_IDX]); + pFuncTbl->Erase(wCSIdx, _Cbn2Pbn((UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_PRIMARY_IDX])); + pFuncTbl->Erase(wCSIdx, _Cbn2Pbn((UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_BACKUP_IDX])); + break; + } + if(res == TRUE32) + { +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCache_set(wCSIdx, bbtInfoHeaderStruct.abSignature, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_PRIMARY_IDX]); + specialBlockCache_set(wCSIdx, bbtInfoHeaderStruct.abSignature, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_BBT_BACKUP_IDX]); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + wCSIdx++; + } + } + if(res == TRUE32) + bbtDone = TRUE32; + } + +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCachePopulated = TRUE32; +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + + // Write a default unique info buffer so it's quick to find + if (res) + { + pBuf = BUF_Get(BUF_MAIN_ONLY); + WMR_ASSERT(NULL != pBuf); + WMR_MEMSET(pBuf->pData, 0xFF, BYTES_PER_PAGE); + } + if (res && bSupportDevUniqueInfo) + { + res = VFL_WriteDeviceUniqueInfo(pBuf->pData, BYTES_PER_PAGE); + } + if (res && bSupportDiagCtrlInfo) + { + res = VFL_WriteDiagControlInfo(pBuf->pData, BYTES_PER_PAGE); + } + if (NULL != pBuf) + { + BUF_Release(pBuf); + } + + for (wCSIdx = 0; (wCSIdx < CS_TOTAL) && (res == TRUE32); wCSIdx++) + { + pFuncTbl->Erase(wCSIdx, 0); + } + + WMR_FREE(pabBBTBuffer, BBT_SIZE_PER_CS); + WMR_FREE(pabBBTBufferRAMOnly, BBT_SIZE_PER_CS); + return res; +} + +static BOOL32 +_HasSandiskDefectMark(UInt8 *pabData) +{ + UInt32 dwByteIdx; + + // Block is defective if the first 6 bytes of this page are 0x0 + + for (dwByteIdx = 0; dwByteIdx < 6; ++dwByteIdx) + { + if (0x00 != pabData[dwByteIdx]) + { + return FALSE32; + } + } + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _CheckInitialBad */ +/* DESCRIPTION */ +/* This function checks spare to find initial bad block. */ +/* PARAMETERS */ +/* wBank [IN] physical bank number */ +/* wPbn [IN] physical block number */ +/* pabSBuf [IN] the pointer of spare buffer */ +/* pInitBad [OUT] initial bad or not */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _CheckInitialBad is completed */ +/* FALSE32 */ +/* _CheckInitialBad is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_CheckInitialBad(UInt16 wCS, UInt16 wPbn, Buffer *pBuf, Buffer * pBufSpare, UInt32 *pInitBad) +{ + Int32 nFILRet; + UInt32 dwPpn; + + WMR_PRINT(LOG, TEXT("[VFL: IN] ++_CheckInitialBad(wCS:%d, wPbn:%d)\n"), wCS, wPbn); + + WMR_ASSERT(wCS < CS_TOTAL && wPbn < LAST_ADDRESSABLE_BLOCK); + + *pInitBad = 0xFFFFFFFF; + + switch (INITIAL_BBT_TYPE) + { + case INIT_BBT_SANDISK_MLC: + { + UInt32 dwPageOffset; + + for (dwPageOffset = 0; dwPageOffset < 2; ++dwPageOffset) + { + dwPpn = GET_Ppn(wPbn, dwPageOffset); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (_HasSandiskDefectMark(pBuf->pData)) + { + *pInitBad = 0x0; + break; // break for-loop + } + } + } + break; + + case INIT_BBT_TOSHIBA_MLC: + { + dwPpn = GET_Ppn(wPbn, 0); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if ((pBuf->pData[0] != 0xFF) || (pBufSpare->pData[0] != 0xFF)) + { + *pInitBad = 0x0; + break; + } + + dwPpn = GET_Ppn(wPbn, (PAGES_PER_BLOCK - 1)); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if ((pBuf->pData[0] != 0xFF) || (pBufSpare->pData[0] != 0xFF)) + { + *pInitBad = 0x0; + } + } + break; + + case INIT_BBT_SAMSUNG_MLC: + { + dwPpn = GET_Ppn(wPbn, (PAGES_PER_BLOCK - 1)); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] != 0xFF) + { + *pInitBad = 0x0; + } + } + break; + + case INIT_BBT_SAMSUNG_MLC_8K: + { + dwPpn = GET_Ppn(wPbn, 0); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] != 0xFF) + { + *pInitBad = 0x0; + break; + } + + dwPpn = GET_Ppn(wPbn, (PAGES_PER_BLOCK - 1)); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] != 0xFF) + { + *pInitBad = 0x0; + } + } + break; + + case INIT_BBT_HYNIX_MLC: + { + dwPpn = GET_Ppn(wPbn, (PAGES_PER_BLOCK - 3)); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] != 0xFF) + { + *pInitBad = 0x0; + break; + } + + dwPpn = GET_Ppn(wPbn, (PAGES_PER_BLOCK - 1)); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] != 0xFF) + { + *pInitBad = 0x0; + } + } + break; + + case INIT_BBT_SAMSUNG_SLC: + { + dwPpn = GET_Ppn(wPbn, 0); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] != 0xFF) + { + *pInitBad = 0x0; + break; + } + + dwPpn = GET_Ppn(wPbn, 1); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] != 0xFF) + { + *pInitBad = 0x0; + } + } + break; + + case INIT_BBT_INTEL_ONFI: + { + // From page 82 of June 2007 version of "Intel MD516 NAND Flash Memory" datasheet: + // + // "NAND Flash devices are shipped from the factory erased. The factory identifies invalid + // blocks before shipping by programming 00h into the first spare location (column + // address 4,096) of the first page of each bad block. + // + // "System software should check columns 4096 to 4313 on the first page of each block + // prior to performing any program or erase operations on the NAND Flash device. A bad + // block table can then be created, allowing system software to map around these areas. + // Factory testing is performed under worst-case conditions. Because blocks marked + // 'bad' may be marginal, it may not be possible to recover this information if the block is + // erased." + + UInt16 wIdx; + + dwPpn = GET_Ppn(wPbn, 0); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + for (wIdx = 0; wIdx < BYTES_PER_SPARE; wIdx++) + { + if (pBufSpare->pData[wIdx] == 0x00) + { + *pInitBad = 0; + break; + } + } + } + break; + + case INIT_BBT_MICRON_ONFI: + { + // From Micron's L63 datasheet, July 2008 version, pg 87, Error management section: + // NAND Flash devices are shipped from the factory erased. The factory identifies invalid + // blocks before shipping by attempting to program the bad-block mark into every location + // in the first page of each invalid block. It may not be possible to program every location in + // an invalid block with the bad-block mark. However, the first spare area location in each + // bad block is guaranteed to contain the bad-block mark. This method is compliant with + // ONFI Factory Defect Mapping requirements. + + dwPpn = GET_Ppn(wPbn, 0); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + if (pBufSpare->pData[0] == 0x00) + { + *pInitBad = 0; + } + } + break; + + case INIT_BBT_ONFI: + { + // From section 3.2.1 on page 23 in revision 1.0 of the ONFI specification: + // + // "If a block is defective and 8-bit data access is used, the manufacturer shall mark the block as + // defective by setting at least one byte in the defect area...of the first or last + // page of the defective block to a value of 00h. If a block is defective and 16-bit data access is + // used, the manufacturer shall mark the block as defective by setting at least one word in the defect + // area of the first or last page of the defective block to a value of 0000h." + + UInt16 wIdx; + + dwPpn = GET_Ppn(wPbn, 0); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + for (wIdx = 0; wIdx < BYTES_PER_SPARE; wIdx++) + { + if (pBufSpare->pData[wIdx] == 0x00) + { + *pInitBad = 0; + break; + } + } + + if (0 != *pInitBad) + { + dwPpn = GET_Ppn(wPbn, (PAGES_PER_BLOCK - 1)); + + nFILRet = pFuncTbl->ReadNoECC(wCS, dwPpn, pBuf->pData, pBufSpare->pData); + + if (nFILRet != FIL_SUCCESS) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Read(wCS:%d) fail!\n"), wCS); + return FALSE32; + } + + for (wIdx = 0; wIdx < BYTES_PER_SPARE; wIdx++) + { + if (pBufSpare->pData[wIdx] == 0x00) + { + *pInitBad = 0; + break; + } + } + } + } + break; + + default: + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Unknown initial bad block algorithm type (0x%x).\n"), + INITIAL_BBT_TYPE); + return FALSE32; + } + + WMR_PRINT(LOG, TEXT("[VFL:OUT] --_CheckInitialBad(wCS:%d, wPbn:%d)\n"), wCS, wPbn); + + return TRUE32; +} + +static BOOL32 +_CreateBBT(UInt16 wCS, UInt8 * pabBBT) +{ + UInt16 wBBTIdx, wDieIdx, wBlkIdx; + UInt32 nBad; + UInt32 dwBBCnt = 0; + Buffer *pBufSpare = NULL, *pBufMain = NULL; + + WMR_ASSERT(wCS < CS_TOTAL); + pBufMain = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBufMain == NULL) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] _CreateBBT failed allocating buffer for spare\n")); + return FALSE32; + } + + pBufSpare = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBufSpare == NULL) + { + BUF_Release(pBufMain); + WMR_PRINT(ERROR, TEXT("[VFL:ERR] _CreateBBT failed allocating buffer for spare\n")); + return FALSE32; + } + /* mark all blocks as good */ + WMR_MEMSET(pabBBT, 0xFF, BBT_SIZE_PER_CS); + wBBTIdx = 0; + for (wDieIdx = 0; wDieIdx < DIES_PER_CS; wDieIdx++) + { + for (wBlkIdx = 0; wBlkIdx < BLOCKS_PER_DIE; wBlkIdx++) + { + if (_CheckInitialBad(wCS, GET_Pbn(wDieIdx, wBlkIdx), pBufMain, pBufSpare, &nBad) == FALSE32) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] _CreateBBT failed calling _CheckInitialBad\n")); + BUF_Release(pBufSpare); + return FALSE32; + } + if (nBad == 0) /* block is bad */ + { + _MarkBlockAsBadInBBT(pabBBT, wBBTIdx); + dwBBCnt++; + } + else + { + _MarkBlockAsGoodInBBT(pabBBT, wBBTIdx); + } + wBBTIdx++; + } + } + WMR_PRINT(ALWAYS, TEXT("[VFL:INF] _CreateBBT found %d bad blocks in wCS 0x%x\n"), dwBBCnt, wCS); + + BUF_Release(pBufMain); + BUF_Release(pBufSpare); + return TRUE32; +} + +static BOOL32 _WriteSpecialBlock(UInt16 wBank, UInt16 wPBlk, SpecialBlockHeaderStruct * pSpecialBlockHeaderStruct, UInt8 * pabData, UInt32 dwDataBufferSize) +{ + BOOL32 res = TRUE32; + UInt16 wTrialCnt = 0, wWriteIdx; + Int32 nFILRet; + Buffer *pBuffSrc, *pBuffVerify; + + // check the arguments + if (pSpecialBlockHeaderStruct == NULL || pabData == NULL || dwDataBufferSize == 0) + { + return FALSE32; + } + pBuffSrc = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuffSrc == NULL) + { + return FALSE32; + } + pBuffVerify = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuffVerify == NULL) + { + BUF_Release(pBuffSrc); + return FALSE32; + } + + for (wTrialCnt = 0; wTrialCnt < WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS; wTrialCnt++) + { + res = TRUE32; +#if (defined(WMR_ENABLE_ERASE_PROG_BAD_BLOCK)) + WMR_ENABLE_ERASE_PROG_BAD_BLOCK(wBank, _Cbn2Pbn(wPBlk)); +#endif + + nFILRet = pFuncTbl->Erase(wBank, _Cbn2Pbn(wPBlk)); + +#if (defined(WMR_DISABLE_ERASE_PROG_BAD_BLOCK)) + WMR_DISABLE_ERASE_PROG_BAD_BLOCK(wBank, _Cbn2Pbn(wPBlk)); +#endif + + if (nFILRet != FIL_SUCCESS) + { +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) + WMR_SIM_EXIT_NO_VALIDATION("Failed to erase a special block - code does not support reallocation\n"); +#endif // AND_SIMULATOR + res = FALSE32; + continue; + } + + /* write the data to whole pages in the block */ + for (wWriteIdx = 0; wWriteIdx < PAGES_PER_BLOCK && res == TRUE32;) + { + UInt32 dwBytesWritten = 0; + // internal loop for x pages per single copy + while (dwBytesWritten < dwDataBufferSize && wWriteIdx < PAGES_PER_BLOCK) + { + WMR_MEMSET(pBuffSrc->pData, 0x00, BYTES_PER_PAGE); + WMR_MEMSET(pBuffSrc->pSpare, 0x00, BYTES_PER_METADATA_RAW); + // put the data together + if (dwBytesWritten == 0) + { + dwBytesWritten = WMR_MIN((BYTES_PER_PAGE - sizeof(SpecialBlockHeaderStruct)), dwDataBufferSize); + WMR_MEMCPY(pBuffSrc->pData, pSpecialBlockHeaderStruct, sizeof(SpecialBlockHeaderStruct)); + WMR_MEMCPY(&pBuffSrc->pData[sizeof(SpecialBlockHeaderStruct)], pabData, dwBytesWritten); + } + else + { + UInt32 dwBytesWrittenThisTime = WMR_MIN(BYTES_PER_PAGE, (dwDataBufferSize - dwBytesWritten)); + WMR_MEMCPY(pBuffSrc->pData, &pabData[dwBytesWritten], dwBytesWrittenThisTime); + dwBytesWritten += dwBytesWrittenThisTime; + } + // now write and imidiately read and verify + nFILRet = pFuncTbl->WriteMaxECC(wBank, GET_Ppn(_Cbn2Pbn(wPBlk), wWriteIdx), pBuffSrc->pData); + if (nFILRet != FIL_SUCCESS) + { + res = FALSE32; + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] _WriteSpecialBlock failed writing to bank %d, 0x%04X, 0x%04X, line %d \n"), wBank, wPBlk, wWriteIdx, __LINE__); + break; + } + + nFILRet = pFuncTbl->ReadMaxECC(wBank, GET_Ppn(_Cbn2Pbn(wPBlk), wWriteIdx), pBuffVerify->pData); + if (nFILRet != FIL_SUCCESS) + { + res = FALSE32; + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] _WriteSpecialBlock failed reading from bank %d, 0x%04X, 0x%04X, line %d \n"), wBank, wPBlk, wWriteIdx, __LINE__); + break; + } + if (WMR_MEMCMP(pBuffVerify->pData, pBuffSrc->pData, BYTES_PER_PAGE) != 0) + { + res = FALSE32; + WMR_PRINT(ALWAYS, TEXT("[VFL:WRN] _WriteSpecialBlock failed verifying bank %d, 0x%04X, 0x%04X, line %d \n"), wBank, wPBlk, wWriteIdx, __LINE__); + break; + } + wWriteIdx++; + } + } + if (res == TRUE32) + { + break; + } + } + BUF_Release(pBuffSrc); + BUF_Release(pBuffVerify); + if (wTrialCnt == WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS) + { + return FALSE32; + } + return res; +} + +#endif + + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Neuralize */ +/* DESCRIPTION */ +/* This function erases all blocks but the factory-marked bad blocks, */ +/* thus making the NAND look like they came fresh from the factory. */ +/* PARAMETERS */ +/* (none) */ +/* RETURN VALUES */ +/* TRUE32 */ +/* Passed */ +/* FALSE32 */ +/* Failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +#ifndef AND_READONLY +BOOL32 +VFL_Neuralize() +{ +#if !(defined(AND_SUPPORT_NEURALIZE) && AND_SUPPORT_NEURALIZE) + return FALSE32; +#else + UInt16 wCSIdx, wDieIdx, wBlkIdx, wBBTIdx; + UInt8 *pabBBTBuffer = NULL; + + WMR_PRINT(LOG, TEXT("[VFL: IN] ++VFL_Neuralize()\n")); + + /* allocate buffer for the BBT */ + pabBBTBuffer = (UInt8*)WMR_MALLOC(BBT_SIZE_PER_CS); + if (pabBBTBuffer == NULL) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] failed to allocate BBT buffer!\n")); + return FALSE32; + } + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + if (VFL_ReadBBTWithoutSpecial(wCSIdx, pabBBTBuffer) == TRUE32) + { + WMR_PRINT(ALWAYS, TEXT("[VFL:INF] BBT found for CS %d\n"), wCSIdx); + wBBTIdx = 0; + for (wDieIdx = 0; wDieIdx < DIES_PER_CS; wDieIdx++) + { + for (wBlkIdx = 0; wBlkIdx < BLOCKS_PER_DIE; wBlkIdx++) + { + // only erase good blocks + if (_isBlockGood(pabBBTBuffer, wBBTIdx)) + { + /* check that the block is erasable */ + UInt16 wEraseCnt; + for (wEraseCnt = 0; wEraseCnt < WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS; wEraseCnt++) + { + Int32 nFILRet; + nFILRet = pFuncTbl->Erase(wCSIdx, GET_Pbn(wDieIdx, wBlkIdx)); + if (nFILRet == FIL_SUCCESS) + { + break; + } + WMR_PRINT(ERROR, TEXT("[VFL:ERR] Failed erasing CS %d block 0x%X\n"), wCSIdx, (wDieIdx * BLOCK_STRIDE + wBlkIdx)); + } + } + wBBTIdx++; + } + } + } + else + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] No BBT found for CS %d\n"), wCSIdx); + } + } + + WMR_FREE(pabBBTBuffer, BBT_SIZE_PER_CS); + WMR_PRINT(LOG, TEXT("[VFL:OUT] --VFL_Neuralize()\n")); + return TRUE32; +#endif +} +#endif //AND_READONLY + +static BOOL32 VFL_ReadDeviceUniqueInfo(UInt8 * pabData, UInt32 dwDataBufferSize) +{ + BOOL32 boolRet = FALSE32; +#if !(defined (DISABLE_NAND_SYSCFG) && DISABLE_NAND_SYSCFG) +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if (specialBlockCache_hasEntry(0, UNIQUE_INFO_BLOCK_SIGNATURE) || !specialBlockCachePopulated) +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + { + boolRet = _ReadSpecialInfoBlock(0, NULL, pabData, dwDataBufferSize, (UInt8*)UNIQUE_INFO_BLOCK_SIGNATURE, UNIQUE_INFO_BLOCK_SIGNATURE_SIZE, FALSE32, NULL); + } +#endif + + return boolRet; +} + +#ifndef AND_READONLY +static BOOL32 VFL_WriteDeviceUniqueInfo(UInt8 * pabData, UInt32 dwDataBufferSize) +{ +#if (defined (DISABLE_NAND_SYSCFG) && DISABLE_NAND_SYSCFG) + return FALSE32; +#else + BBTInfoHeaderStruct bbtInfoHeaderStruct; + SpecialBlockHeaderStruct specialBlockHeaderStruct; + BOOL32 boolRes; + specialBlockCache sbCacheEntry; + + WMR_MEMSET(&sbCacheEntry,0,sizeof(specialBlockCache)); + WMR_MEMCPY(sbCacheEntry.abSignature, UNIQUE_INFO_BLOCK_SIGNATURE, UNIQUE_INFO_BLOCK_SIGNATURE_SIZE); + WMR_MEMSET(&bbtInfoHeaderStruct, 0, sizeof(bbtInfoHeaderStruct)); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(specialBlockCache_get(0, &sbCacheEntry)) + { + if( sbCacheEntry.sbLocation[0].locationValid) + bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_PRIMARY_IDX] = sbCacheEntry.sbLocation[0].location; + if( sbCacheEntry.sbLocation[1].locationValid) + bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_BACKUP_IDX] = sbCacheEntry.sbLocation[1].location; + } +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if((sbCacheEntry.sbLocation[0].locationValid == FALSE32) || (sbCacheEntry.sbLocation[1].locationValid == FALSE32 )) + { + if (_ReadSpecialInfoBlock(0, (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, NULL, 0, (UInt8*)BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE, FALSE32, NULL) == FALSE32) + { + return FALSE32; + } + } + if ((bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_PRIMARY_IDX] >= BLOCKS_PER_CS) || + (bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_BACKUP_IDX] >= BLOCKS_PER_CS)) + { + // Diag Control Info has not been allocated + return FALSE32; + } + WMR_MEMSET(&specialBlockHeaderStruct, 0, sizeof(SpecialBlockHeaderStruct)); + WMR_MEMCPY(specialBlockHeaderStruct.abSignature, UNIQUE_INFO_BLOCK_SIGNATURE, UNIQUE_INFO_BLOCK_SIGNATURE_SIZE); + specialBlockHeaderStruct.dwDataSize = dwDataBufferSize; +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCache_invalidate(0, UNIQUE_INFO_BLOCK_SIGNATURE, 0); + specialBlockCache_invalidate(0, UNIQUE_INFO_BLOCK_SIGNATURE, 1); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + boolRes = _WriteSpecialBlock(0, (UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_PRIMARY_IDX], &specialBlockHeaderStruct, pabData, dwDataBufferSize); + if (boolRes == TRUE32) + { + boolRes = _WriteSpecialBlock(0, (UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_BACKUP_IDX], &specialBlockHeaderStruct, pabData, dwDataBufferSize); + } +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if (boolRes == TRUE32) + { + specialBlockCache_set(0, specialBlockHeaderStruct.abSignature, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_PRIMARY_IDX]); + specialBlockCache_set(0, specialBlockHeaderStruct.abSignature, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_UNIQUE_BACKUP_IDX]); + } +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + return boolRes; +#endif // DISABLE_NAND_SYSCFG +} +#endif /* ! AND_READONLY */ + +static BOOL32 VFL_ReadDiagControlInfo(UInt8 * pabData, UInt32 dwDataBufferSize) +{ + BOOL32 boolRet = FALSE32; +#if !(defined (DISABLE_NAND_SYSCFG) && DISABLE_NAND_SYSCFG) +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if (specialBlockCache_hasEntry(0, DIAG_INFO_BLOCK_SIGNATURE) || !specialBlockCachePopulated) +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + { + boolRet = _ReadSpecialInfoBlock(0, NULL, pabData, dwDataBufferSize, (UInt8*)DIAG_INFO_BLOCK_SIGNATURE, DIAG_INFO_BLOCK_SIGNATURE_SIZE, FALSE32, NULL); + } +#endif + + return boolRet; +} + +#ifndef AND_READONLY +static BOOL32 VFL_WriteDiagControlInfo(UInt8 * pabData, UInt32 dwDataBufferSize) +{ +#if (defined (DISABLE_NAND_SYSCFG) && DISABLE_NAND_SYSCFG) + return FALSE32; +#else + BBTInfoHeaderStruct bbtInfoHeaderStruct; + SpecialBlockHeaderStruct specialBlockHeaderStruct; + BOOL32 boolRes, boolRes2; + specialBlockCache sbCacheEntry; + + WMR_MEMSET(&sbCacheEntry,0,sizeof(specialBlockCache)); + WMR_MEMCPY(sbCacheEntry.abSignature, DIAG_INFO_BLOCK_SIGNATURE, DIAG_INFO_BLOCK_SIGNATURE_SIZE); + WMR_MEMSET(&bbtInfoHeaderStruct, 0, sizeof(bbtInfoHeaderStruct)); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(specialBlockCache_get(0, &sbCacheEntry)) + { + if( sbCacheEntry.sbLocation[0].locationValid) + bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_PRIMARY_IDX] = sbCacheEntry.sbLocation[0].location; + if( sbCacheEntry.sbLocation[1].locationValid) + bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_BACKUP_IDX] = sbCacheEntry.sbLocation[1].location; + } +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if((sbCacheEntry.sbLocation[0].locationValid == FALSE32) || (sbCacheEntry.sbLocation[1].locationValid == FALSE32 )) + { + if (_ReadSpecialInfoBlock(0, (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, NULL, 0, (UInt8*)BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE, FALSE32, NULL) == FALSE32) + { + return FALSE32; + } + } + if ((bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_PRIMARY_IDX] >= BLOCKS_PER_CS) || + (bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_BACKUP_IDX] >= BLOCKS_PER_CS)) + { + // Diag Control Info has not been allocated + return FALSE32; + } + WMR_MEMSET(&specialBlockHeaderStruct, 0, sizeof(SpecialBlockHeaderStruct)); + WMR_MEMCPY(specialBlockHeaderStruct.abSignature, DIAG_INFO_BLOCK_SIGNATURE, DIAG_INFO_BLOCK_SIGNATURE_SIZE); + specialBlockHeaderStruct.dwDataSize = dwDataBufferSize; +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCache_invalidate(0, DIAG_INFO_BLOCK_SIGNATURE, 0); + specialBlockCache_invalidate(0, DIAG_INFO_BLOCK_SIGNATURE, 1); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + boolRes = _WriteSpecialBlock(0, (UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_PRIMARY_IDX], &specialBlockHeaderStruct, pabData, dwDataBufferSize); + if (boolRes == TRUE32) + { +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCache_set(0, specialBlockHeaderStruct.abSignature, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_PRIMARY_IDX]); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + } + else + { + pFuncTbl->Erase(0, _Cbn2Pbn((UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_PRIMARY_IDX])); + } + boolRes2 = _WriteSpecialBlock(0, (UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_BACKUP_IDX], &specialBlockHeaderStruct, pabData, dwDataBufferSize); + if (boolRes2 == TRUE32) + { +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCache_set(0, specialBlockHeaderStruct.abSignature, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_BACKUP_IDX]); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + } + else + { + pFuncTbl->Erase(0, _Cbn2Pbn((UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DIAG_CTRL_BACKUP_IDX])); + } + if (boolRes == FALSE32 && boolRes2 == FALSE32) + { + WMR_PRINT(ERROR, TEXT("[VFL:ERR] VFL_WriteDiagControlInfo failed writing to special blocks (line:%d)\n"), __LINE__); + return FALSE32; + } + else + return TRUE32; + +#endif // DISABLE_NAND_SYSCFG +} + +#endif /* ! AND_READONLY */ + +#ifndef AND_READONLY +static BOOL32 VFL_WriteSignature(void * pvoidSignature, UInt32 dwSignatureSize) +{ + BBTInfoHeaderStruct bbtInfoHeaderStruct; + SpecialBlockHeaderStruct specialBlockHeaderStruct; + BOOL32 boolRes; + specialBlockCache sbCacheEntry; + + WMR_MEMSET(&sbCacheEntry,0,sizeof(specialBlockCache)); + WMR_MEMCPY(sbCacheEntry.abSignature, NAND_DRIVER_SIGN_BLOCK_SIGNATURE, NAND_DRIVER_SIGN_BLOCK_SIGNATURE_SIZE); + WMR_MEMSET(&bbtInfoHeaderStruct, 0, sizeof(bbtInfoHeaderStruct)); + WMR_MEMSET(&specialBlockHeaderStruct, 0, sizeof(specialBlockHeaderStruct)); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(specialBlockCache_get(0, &sbCacheEntry)) + { + if( sbCacheEntry.sbLocation[0].locationValid) + bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_SIGNATURE_IDX] = sbCacheEntry.sbLocation[0].location; + } +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(sbCacheEntry.sbLocation[0].locationValid == FALSE32) + { + if (_ReadSpecialInfoBlock(0, (SpecialBlockHeaderStruct *)&bbtInfoHeaderStruct, NULL, 0, (UInt8*)BBT_BLOCK_SIGNATURE, BBT_BLOCK_SIGNATURE_SIZE, FALSE32, NULL) == FALSE32) + { + return FALSE32; + } + } + WMR_MEMSET(&specialBlockHeaderStruct, 0, sizeof(SpecialBlockHeaderStruct)); + WMR_MEMCPY(specialBlockHeaderStruct.abSignature, NAND_DRIVER_SIGN_BLOCK_SIGNATURE, NAND_DRIVER_SIGN_BLOCK_SIGNATURE_SIZE); + specialBlockHeaderStruct.dwDataSize = dwSignatureSize; + if (pvoidSignature == NULL) + { + UInt16 signatureBlock=0xffff; + Buffer *signV ; + + signV = BUF_Get(BUF_MAIN_AND_SPARE); + if (!signV) + { + WMR_PRINT(ERROR, TEXT("BUF_Get failed in VFL_ReadBlockZeroSignatureNoHeader!\n")); + return FALSE32; + } + + while (_ReadSpecialInfoBlock(0, NULL, signV->pData, dwSignatureSize, (UInt8*)NAND_DRIVER_SIGN_BLOCK_SIGNATURE, NAND_DRIVER_SIGN_BLOCK_SIGNATURE_SIZE, FALSE32,&signatureBlock) == TRUE32) + { + if(signatureBlock != 0xffff) + { + pFuncTbl->Erase(0, _Cbn2Pbn(signatureBlock)); + } + signatureBlock = 0xffff; + } + BUF_Release(signV); + return TRUE32; + } +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCache_invalidate(0, NAND_DRIVER_SIGN_BLOCK_SIGNATURE, 0); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + boolRes = _WriteSpecialBlock(0, (UInt16)bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_SIGNATURE_IDX], &specialBlockHeaderStruct, (UInt8*)pvoidSignature, dwSignatureSize); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if(boolRes == TRUE32 ) + specialBlockCache_set(0, specialBlockHeaderStruct.abSignature, bbtInfoHeaderStruct.adwSpecialBlocks[FPART_SPECIAL_BLK_DEV_SIGNATURE_IDX]); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + return boolRes; +} +#endif /* ! AND_READONLY */ + +static BOOL32 VFL_ReadSignature(void * pvoidSignature, UInt32 dwSignatureSize) +{ + BOOL32 ret; + if (FIL_GetFuncTbl()->SetWhiteningState) + { + FIL_GetFuncTbl()->SetWhiteningState(TRUE32); + } + ret = _ReadSpecialInfoBlock(0, NULL, (UInt8*)pvoidSignature, dwSignatureSize, (UInt8*)NAND_DRIVER_SIGN_BLOCK_SIGNATURE, NAND_DRIVER_SIGN_BLOCK_SIGNATURE_SIZE, FALSE32, NULL); + if (!ret && FIL_GetFuncTbl()->SetWhiteningState) + { + // disable whitening and try again + FIL_GetFuncTbl()->SetWhiteningState(FALSE32); + ret = _ReadSpecialInfoBlock(0, NULL, (UInt8*)pvoidSignature, dwSignatureSize, (UInt8*)NAND_DRIVER_SIGN_BLOCK_SIGNATURE, NAND_DRIVER_SIGN_BLOCK_SIGNATURE_SIZE, FALSE32, NULL); + if( !ret ) + { + FIL_GetFuncTbl()->SetWhiteningState(TRUE32); + } + else + WMR_PRINT(ALWAYS, TEXT("[FIL] Disable data whitening\n")); + } + return ret; +} + +static BOOL32 UnderVFL_Init(LowFuncTbl *pFILFunctions, UInt32 dwOptions) +{ +#ifndef AND_READONLY + bSupportDevUniqueInfo = (dwOptions & FPART_INIT_OPTION_DEV_UNIQUE) ? TRUE32 : FALSE32; + bSupportDiagCtrlInfo = (dwOptions & FPART_INIT_OPTION_DIAG_CTRL) ? TRUE32 : FALSE32; +#endif // ! AND_READONLY + + stFPartSignatureStyle = SIGNATURE_STYLE_NOTSET; + pFuncTbl = pFILFunctions; + stUnderVFLDeviceInfo.checkInitialBadType = (CheckInitialBadType)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BBT_TYPE); + stUnderVFLDeviceInfo.wBlocksPerCS = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); + stUnderVFLDeviceInfo.wDiesPerCS = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_DIES_PER_CS); + stUnderVFLDeviceInfo.wBlocksPerDie = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_DIE); + stUnderVFLDeviceInfo.wDieStride = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_DIE_STRIDE); + stUnderVFLDeviceInfo.wBlockStride = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BLOCK_STRIDE); + stUnderVFLDeviceInfo.wLastBlock = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_LAST_BLOCK); + stUnderVFLDeviceInfo.wUserBlocksPerCS = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_USER_BLOCKS_PER_CS); + stUnderVFLDeviceInfo.wBytesPerPage = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + stUnderVFLDeviceInfo.wNumOfCEs = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + stUnderVFLDeviceInfo.wPagesPerBlock = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + stUnderVFLDeviceInfo.wBytesPerSpare = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_SPARE); + stUnderVFLDeviceInfo.wBytesPerBLPage = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_BL_PAGE); +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + specialBlockCache_Init(); +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + return TRUE32; +} + +static void UnderVFL_Close(void) +{ +#if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) + if( blockCacheArray != NULL ) + { + WMR_FREE(blockCacheArray, CS_TOTAL * MAX_NUM_SPECIAL_BLOCKS_PER_CS * sizeof(specialBlockCache)); + blockCacheArray = NULL; + } +#endif // #if !(defined(AND_DISABLE_SPECIAL_BLOCK_CACHE) && AND_DISABLE_SPECIAL_BLOCK_CACHE) +} + +// Add: +// 1. read signature function that search for signature in block zero with no header (M68 style). +// 2. undervfl/pflash register. +// 3. add path through functions to fil. +// 4. need to change the factory reformat to format single fpartition (specified). + +static BOOL32 +VFL_ReadBlockZeroSignatureNoHeader(void * pvoidData, UInt32 dwSignatureSize) +{ + Buffer *pBuf; + Int32 nRet; + UInt16 wPageIdx; + BOOL32 boolFoundValidData; + UInt8 *pabData = (UInt8*)pvoidData; + + /* + * Search block zero, bank zero for the driver signature. + * + * Sets boolSignatureFound to TRUE32 and sets nSig if a signature is found. + * Sets boolBlk0IsClean appropriately. + */ + boolFoundValidData = FALSE32; + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (!pBuf) + { + WMR_PRINT(ERROR, TEXT("BUF_Get failed in VFL_ReadBlockZeroSignatureNoHeader!\n")); + return FALSE32; + } + for (wPageIdx = 0; wPageIdx < PAGES_PER_BLOCK; wPageIdx++) + { + nRet = pFuncTbl->ReadMaxECC(0, wPageIdx, pBuf->pData); + if (nRet == FIL_U_ECC_ERROR) + { + nRet = pFuncTbl->ReadWithECC(0, wPageIdx, pBuf->pData, pBuf->pSpare, NULL, NULL, FALSE32); + } + /* + * If we successfully read a page that contains a compatible signature, + * save the signature block and consider ourselves done. + */ + if (nRet == FIL_SUCCESS) + { + WMR_MEMCPY(pabData, pBuf->pData, dwSignatureSize); + boolFoundValidData = TRUE32; + break; + } + } + BUF_Release(pBuf); + return boolFoundValidData; +} + +#ifndef AND_READONLY +static BOOL32 +VFL_WriteBlockZeroSignatureNoHeader(void * pvoidData, UInt32 dwSignatureSize) +{ + Int32 nRetTemp; + Buffer * pBuf; + UInt16 wPageIdx; + LowFuncTbl *pLowFuncTbl; + UInt8 *pabData = (UInt8*)pvoidData; + + pLowFuncTbl = FIL_GetFuncTbl(); + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pBuf == NULL) + { + return FALSE32; + } + + WMR_MEMSET(pBuf->pData, 0, BYTES_PER_PAGE); + WMR_MEMSET(pBuf->pSpare, 0, BYTES_PER_METADATA_RAW); + WMR_MEMCPY(pBuf->pData, pabData, dwSignatureSize); + + /* erase the first block */ + nRetTemp = pLowFuncTbl->Erase(0, 0); + + if (nRetTemp != FIL_SUCCESS) + { + return FALSE32; + } + if (pvoidData != NULL && dwSignatureSize != 0) + { + for (wPageIdx = 0; wPageIdx < PAGES_PER_BLOCK; wPageIdx++) + { + nRetTemp = pLowFuncTbl->WriteMaxECC(0, wPageIdx, pBuf->pData); + + if (nRetTemp != FIL_SUCCESS) + { + return FALSE32; + } + } + } + BUF_Release(pBuf); + return TRUE32; +} +#endif // ! AND_READONLY +void FPART_SetSignatureStyle(void * pvoidFPartFunctions, FPartSignatureStyle fpartSignatureStyle) +{ + FPartFunctions * pFPartFunctions = (FPartFunctions *)pvoidFPartFunctions; + + stFPartSignatureStyle = fpartSignatureStyle; + switch (stFPartSignatureStyle) + { + case SIGNATURE_STYLE_BLOCKZERO_NOHEADER: + pFPartFunctions->ReadSignature = VFL_ReadBlockZeroSignatureNoHeader; +#ifndef AND_READONLY + pFPartFunctions->WriteSignature = VFL_WriteBlockZeroSignatureNoHeader; +#endif + break; + + case SIGNATURE_STYLE_RESERVEDBLOCK_HEADER: + pFPartFunctions->ReadSignature = VFL_ReadSignature; +#ifndef AND_READONLY + pFPartFunctions->WriteSignature = VFL_WriteSignature; +#endif + break; + + default: + pFPartFunctions->ReadSignature = NULL; +#ifndef AND_READONLY + pFPartFunctions->WriteSignature = NULL; +#endif + } +} + +void FPart_Register(FPartFunctions * pFPartFunctions) +{ +#ifndef AND_READONLY + pFPartFunctions->WriteInitialBBT = VFL_WriteInitialBBT; + pFPartFunctions->FactoryReformat = VFL_FactoryReformat; + pFPartFunctions->Neuralize = VFL_Neuralize; + pFPartFunctions->WriteDeviceUniqueInfo = VFL_WriteDeviceUniqueInfo; + pFPartFunctions->WriteDiagnosticInfo = VFL_WriteDiagControlInfo; + pFPartFunctions->WriteSignature = NULL; +#endif // ! AND_READONLY + pFPartFunctions->ReadDeviceUniqueInfo = VFL_ReadDeviceUniqueInfo; + pFPartFunctions->ReadDiagnosticInfo = VFL_ReadDiagControlInfo; + pFPartFunctions->VerifyProductionFormat = VFL_VerifyProductionFormat; + pFPartFunctions->ReadSignature = NULL; + pFPartFunctions->Init = UnderVFL_Init; + pFPartFunctions->Close = UnderVFL_Close; + pFPartFunctions->GetLowFuncTbl = FIL_GetFuncTbl; + pFPartFunctions->SetSignatureStyle = FPART_SetSignatureStyle; +} + diff --git a/drivers/flash_nand/raw/Whimory/Core/FPart/FPartTypes.h b/drivers/flash_nand/raw/Whimory/Core/FPart/FPartTypes.h new file mode 100644 index 0000000..e593073 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FPart/FPartTypes.h @@ -0,0 +1,125 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL types definition header */ +/* FILE : VFLTypes.h */ +/* PURPOSE : This header defines Data types which are shared */ +/* by all VFL submodules */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 04-AUG-2003 [HM Jung] : first writing */ +/* 14-JUL-2005 [Jaesung Jung] : reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : fix from code inspection */ +/* 24-JAN-2006 [Yangsup Lee ] : support un-pair bad block management */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ +#ifndef _UNDER_VFL_TYPES_H_ +#define _UNDER_VFL_TYPES_H_ + +/* Device Information Structures and defines */ + +#define VFL_META_STRUCT_VERSION 0x00000004 /* changed Oct 6th 2006 */ +#define VFL_BBT_STRUCT_VERSION 0x00000004 /* changed Oct 6th 2006 */ + +#define BBT_BLOCK_SIGNATURE (UInt8*)"DEVICEINFOBBT\0\0\0" +#define BBT_BLOCK_SIGNATURE_SIZE 16 + +#define UNIQUE_INFO_BLOCK_SIGNATURE (UInt8*)"DEVICEUNIQUEINFO" +#define UNIQUE_INFO_BLOCK_SIGNATURE_SIZE 16 + +#define NAND_DRIVER_SIGN_BLOCK_SIGNATURE (UInt8*)"NANDDRIVERSIGN\0\0" +#define NAND_DRIVER_SIGN_BLOCK_SIGNATURE_SIZE 16 + +#define DIAG_INFO_BLOCK_SIGNATURE (UInt8*)"DIAGCONTROLINFO\0" +#define DIAG_INFO_BLOCK_SIGNATURE_SIZE 16 + +#define BBT_SIZE_PER_CS ((BLOCKS_PER_CS / 8) + (BLOCKS_PER_CS % 8 ? 1 : 0)) + +#define WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS (4) + +#define VFL_BLOCK_INDEX_MASK (0xFFFF) +#define VFL_INVALID_INFO_INDEX (0xFFFF) + +#define FPART_SPECIAL_BLK_BBT_PRIMARY_IDX (0) // Primary copy of bad block table +#define FPART_SPECIAL_BLK_BBT_BACKUP_IDX (1) // Backup copy of bad block table +#define FPART_SPECIAL_BLK_DEV_UNIQUE_PRIMARY_IDX (2) // Primary copy of device-unique information +#define FPART_SPECIAL_BLK_DEV_UNIQUE_BACKUP_IDX (3) // Backup copy of device-unique information +#define FPART_SPECIAL_BLK_DEV_SIGNATURE_IDX (4) // Driver signature +#define FPART_SPECIAL_BLK_DIAG_CTRL_PRIMARY_IDX (5) // Primary copy of diag control bits +#define FPART_SPECIAL_BLK_DIAG_CTRL_BACKUP_IDX (6) // Backup copy of diag control bits + +#define FPART_COPIES_OF_SPECIAL_INFO (2) // Copies of syscfg and diag bits + +#define MAX_NUM_SPECIAL_BLOCKS_PER_CS (8) /* This should always be 8 as BBTInfoHeaderStruct and SpecialBlockHeaderStruct should be of the same size*/ +#define MAX_NUM_OF_SPECIALS (5) /* no of special blocks ( backups not included )*/ +#define MAX_SPECIAL_BLOCK_COPIES (2) +#define SPECIAL_BLOCK_SIGNATURE_SIZE BBT_BLOCK_SIGNATURE_SIZE + +typedef struct +{ + UInt8 abSignature[16]; + UInt32 dwVersion; + UInt32 adwSpecialBlocks[MAX_NUM_SPECIAL_BLOCKS_PER_CS]; + UInt32 dwBBTSize; +} BBTInfoHeaderStruct; + +typedef struct +{ + UInt32 location; + BOOL32 locationValid; +} specialBlockLocation; +typedef struct +{ + UInt8 abSignature[SPECIAL_BLOCK_SIGNATURE_SIZE]; + specialBlockLocation sbLocation[MAX_SPECIAL_BLOCK_COPIES]; +} specialBlockCache; + +typedef struct +{ + UInt8 abSignature[16]; + UInt32 dwVersion; + UInt32 adwReserved[MAX_NUM_SPECIAL_BLOCKS_PER_CS]; + UInt32 dwDataSize; +} SpecialBlockHeaderStruct; + +typedef struct +{ + UInt16 wPagesPerBlock; /* the count of pages per block */ + UInt16 wNumOfCEs; + CheckInitialBadType checkInitialBadType; + UInt16 wDiesPerCS; + UInt16 wBlocksPerCS; /* the count of blocks per CS */ + + UInt16 wBlocksPerDie; + UInt16 wDieStride; + UInt16 wBlockStride; + UInt16 wLastBlock; + UInt16 wUserBlocksPerCS; + UInt16 wBytesPerPage; /* bytes per page (main) */ + UInt16 wBytesPerSpare; + UInt16 wBytesPerBLPage; +} UnderVFLDeviceInfo; + +#endif /* _UNDER_VFL_TYPES_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/FTLInterface.c b/drivers/flash_nand/raw/Whimory/Core/FTL/FTLInterface.c new file mode 100644 index 0000000..f17c0c0 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/FTLInterface.c @@ -0,0 +1,4665 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : FTL */ +/* NAME : FTL interface */ +/* FILE : FTLinterface.c */ +/* PURPOSE : This file contains the exported routine for interfacing with*/ +/* the upper layer of FTL. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 22-JUL-2005 [Jaesung Jung] : first writing */ +/* 03-NOV-2005 [Yangsup Lee ] : Add wear-leveling algorithm */ +/* 13-NOV-2005 [Yangsup Lee ] : Remove checksum for MLC */ +/* 22-NOV-2005 [Yangsup Lee ] : Modify wear-leveling algorithm */ +/* 16-FEB-2006 [Yangsup Lee ] : Remove write bitmap for Internal */ +/* Interleaving */ +/* 08-MAR-2006 [Yangsup Lee ] : Don't merge FAT area */ +/* 14-MAR-2006 [Yangsup Lee ] : Don't use bad mark area */ +/* 29-MAR-2006 [Yangsup Lee ] : Modify wear-leveling algorithm(No grouping)*/ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "WMRBuf.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTLTypes.h" +#include "FTL.h" +#if AND_SUPPORT_LEGACY_FTL + +#define GET_FTL_SPARE_TYPE(pSBuf) ((UInt8 *)(pSBuf))[FTL_SPARE_TYPE_LOCATION] +#define SET_FTL_SPARE_TYPE(pSBuf, type) ((UInt8 *)(pSBuf))[FTL_SPARE_TYPE_LOCATION] = (type) + +#define FTL_ECC_MARK (0x55) +#define GET_FTL_ECC_MARK(pSBuf) (((UInt32 *)(pSBuf))[FTL_ECC_MARK_WORD] & FTL_ECC_MARK_MASK) +#define CHECK_FTL_ECC_MARK(pSBuf) (GET_FTL_ECC_MARK((pSBuf)) == FTL_ECC_MARK_MASK ? TRUE32 : FALSE32) /* TRUE32 if there is no error FALSE32 if there is an error */ +#define SET_FTL_ECC_MARK(pSBuf) do { ((UInt8 *)(pSBuf))[FTL_ECC_MARK_BYTE] = FTL_ECC_MARK; ((UInt8 *)(pSBuf))[FTL_ECC_MARK_BYTE_LEGACY] = FTL_ECC_MARK; } while (0) + +#define FTL_NUM_PAGES_PER_EC_TABLE (((FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE) + (((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) ? 1 : 0)) +#define FTL_NUM_PAGES_PER_RC_TABLE (((FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE) + (((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) ? 1 : 0)) +#define FTL_NUM_PAGES_PER_MAP_TABLE (((USER_SUBLKS_TOTAL * sizeof(UInt16)) / BYTES_PER_PAGE) + (((USER_SUBLKS_TOTAL * sizeof(UInt16)) % BYTES_PER_PAGE) ? 1 : 0)) +#define FTL_NUM_PAGES_PER_LOGCXT_MAP_TABLE (((LOG_SECTION_SIZE * PAGES_PER_SUBLK * sizeof(UInt16)) / BYTES_PER_PAGE) + (((LOG_SECTION_SIZE * PAGES_PER_SUBLK * sizeof(UInt16)) % BYTES_PER_PAGE) ? 1 : 0)) + +#define FTL_NUM_PAGES_TO_WRITE_IN_STORECXT (FTL_NUM_PAGES_PER_EC_TABLE + FTL_NUM_PAGES_PER_RC_TABLE + FTL_NUM_PAGES_PER_MAP_TABLE + FTL_NUM_PAGES_PER_LOGCXT_MAP_TABLE + 1 /* index */ + 1 /* statistics */) + +#define FTL_NUM_PAGES_PER_CXT_WITHOUT_EC (FTL_NUM_PAGES_PER_MAP_TABLE + 1) + +#define CONVERT_L2V(l) (pstFTLCxt->pawMapTable[(l)]) +#define MODIFY_LB_MAP(lb, vb) (pstFTLCxt->pawMapTable[(lb)] = (vb)) +#define GET_EC_PER_VB(vb) (pstFTLCxt->pawECCacheTable[(vb)]) +#define GET_EC_PER_LB(lb) (GET_EC_PER_VB(CONVERT_L2V(lb))) + +#define MARK_LOG_AS_EMPTY(pLog) ((pLog)->wVbn = LOG_EMPTY_SLOT) +#define ASSIGN_VBN_TO_LOG(pLog, wVbnParam) ((pLog)->wVbn = (wVbnParam)) + +#define IS_LBN_IN_RANGE(wLbnParam) (((wLbnParam) == 0) || ((((wLbnParam) > 0)) && ((wLbnParam) < USER_SUBLKS_TOTAL))) +#define FTL_SET_LOG_LBN(pLogParam, wLbnParam) \ + { \ + ((pLogParam)->wLbn = (wLbnParam)); \ + WMR_ASSERT(IS_LBN_IN_RANGE(wLbnParam)); \ + } + +#define FTL_CHANGE_FTLCXT_TO_NEXT_BLOCK() \ + { pstFTLCxt->dwCurrMapCxtPage = GET_Vpn(GET_Vbn(pstFTLCxt->dwCurrMapCxtPage), (PAGES_PER_SUBLK - 1)); } + +#define DIV2_ROUNDUP(a) ((((a) & 0x1) == 1) ? (((a)>>1)+1) : ((a)>>1)) + +/*****************************************************************************/ +/* Debug Print #defines */ +/*****************************************************************************/ +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) +#define FTL_ERR_PRINT(x) { WMR_RTL_PRINT(x); WMR_PANIC(); } +#else +#define FTL_ERR_PRINT(x) WMR_RTL_PRINT(x) +#endif +#define FTL_WRN_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (FTL_LOG_MSG_ON) + #define FTL_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else + #define FTL_LOG_PRINT(x) +#endif + +#if defined (FTL_INF_MSG_ON) + #define FTL_INF_PRINT(x) WMR_DBG_PRINT(x) +#else + #define FTL_INF_PRINT(x) +#endif + +/*****************************************************************************/ +/* Static variables definitions */ +/*****************************************************************************/ +static FTLCxt2 *pstFTLCxt = NULL; +static FTLMeta *pstFTLMeta = NULL; + +WMR_BufZone_t FTL_BufZone; +static UInt8 * pstbaMultiplePagesWriteSpare = NULL; +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) || \ + !(defined(AND_READONLY) && AND_READONLY) +static UInt8 * pstSimpleMergeDataBuffer = NULL; +#endif +static UInt32 * pstadwScatteredReadVpn = NULL; +static VFLFunctions stVFLFunctions; +static FTLWMRDeviceInfo stFTLDeviceInfo; + +#ifdef AND_COLLECT_STATISTICS +static FTLStatistics stFTLStatistics; +#endif /* AND_COLLECT_STATISTICS */ + +// make the function pointers in vfl struct look like the old vfl functions +#ifndef AND_READONLY +#define VFL_Format (stVFLFunctions.Format) +#define VFL_Write (stVFLFunctions.WriteSinglePage) +#define VFL_Erase (stVFLFunctions.Erase) +#define VFL_ChangeFTLCxtVbn (stVFLFunctions.ChangeFTLCxtVbn) +#define VFL_WriteMultiplePagesInVb (stVFLFunctions.WriteMultiplePagesInVb) +#endif // ! AND_READONLY +#define VFL_Init (stVFLFunctions.Init) +#define VFL_Open (stVFLFunctions.Open) +#define VFL_Close (stVFLFunctions.Close) +#define VFL_ReadMultiplePagesInVb (stVFLFunctions.ReadMultiplePagesInVb) +#define VFL_ReadScatteredPagesInVb (stVFLFunctions.ReadScatteredPagesInVb) +#define VFL_Read (stVFLFunctions.ReadSinglePage) +#define VFL_GetFTLCxtVbn (stVFLFunctions.GetFTLCxtVbn) +//#define VFL_GetAddress (stVFLFunctions.GetAddress) +#define VFL_GetDeviceInfo (stVFLFunctions.GetDeviceInfo) +#define VFL_GetStruct (stVFLFunctions.GetStruct) +#define VFL_SetStruct (stVFLFunctions.SetStruct) + +/* maximum block erase count of each map */ + +/*****************************************************************************/ +/* Definitions */ +/*****************************************************************************/ +#define GET_LOGCxt(v) (&(pstFTLCxt->aLOGCxtTable[v])) +#define GET_FTLCxt() (&(pstFTLMeta->stFTLCxt)) +#define GET_Vpn(Vbn, POffset) ((UInt32)(Vbn) * (UInt32)PAGES_PER_SUBLK + (UInt32)(POffset)) +#define GET_PageOffset(page) ((page) % PAGES_PER_SUBLK) +#define GET_Vbn(page) ((page) / PAGES_PER_SUBLK) + +/*****************************************************************************/ +/* Static function prototypes */ +/*****************************************************************************/ +static void _GetFTLCxtSpare(UInt32 *pAge, UInt8 *pStatus, + UInt16 * pwLogicalNumber, UInt8 *pSBuf); +static void _GetLOGCxtSpare(UInt8 *pSBuf, UInt32 * pdwLPn, UInt32 * pdwWriteAge); + +static BOOL32 _LoadFTLCxt(void); +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) +static BOOL32 _MakeLogMap(void); +#endif +static LOGCxt *_ScanLogSection(UInt32 nLbn); +static void _InitLogCxt(LOGCxt *pLog); + +static Int32 _FTLRead(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pBuf); + +#ifdef AND_COLLECT_STATISTICS +static BOOL32 _FTLSetStatisticsFromCxt(UInt8 * pabData); +#endif // AND_COLLECT_STATISTICS + +#ifndef AND_READONLY +static BOOL32 _AutoWearLevel(void); +static BOOL32 _AddLbnToRefreshList(UInt16 wLbn, UInt16 wVbn); +static BOOL32 _IsBlockInRefreshList(UInt16 wLbn, UInt16 wVbn, UInt32 * pdwIdx); +static BOOL32 _FTLMarkCxtNotValid(void); +#ifdef AND_COLLECT_STATISTICS +static BOOL32 _FTLGetStatisticsToCxt(UInt8 * pabData); +#endif // AND_COLLECT_STATISTICS +static BOOL32 _DoMoveMerge(LOGCxt *pLogVictim); +static BOOL32 _DoCopyMerge(LOGCxt *pLogVictim); +static BOOL32 _DoSimpleMerge(LOGCxt *pLogVictim); +static BOOL32 _Merge(LOGCxt *pLogVictim); +static void _DisableCopyMerge(LOGCxt *pLog, UInt32 nLPOffset); +static BOOL32 _StoreFTLCxt(void); +static void _SetFTLCxtSpare(UInt32 *pdwAge, UInt8 *pStatus, + UInt16 * pwLogicalNumber, UInt8 *pabSBuf); +static void _SetLOGCxtSpare(UInt32 dwLPn, UInt32 dwWriteAge, UInt8 *pSBuf); +static BOOL32 _GetFreeVb(UInt16 *pwVbn); +static BOOL32 _SetFreeVb(UInt16 wVbn); +static BOOL32 _HandleRefreshBlock(void); +#endif + +// declaration for the functions FTL_Register publish + +static Int32 FTL_Init(VFLFunctions *pVFLFunctions); +static Int32 FTL_Open(UInt32 *pTotalScts, UInt32 * pdwSectorSize, BOOL32 nandFullRestore, BOOL32 justFormatted, UInt32 dwMinorVer, UInt32 dwOptions); +static Int32 FTL_Read(UInt32 nLpn, UInt32 nNumOfScts, UInt8 *pBuf); +static void FTL_Close(void); +static BOOL32 FTL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); + +#ifndef AND_READONLY +static Int32 FTL_Write(UInt32 nLpn, UInt32 nNumOfScts, UInt8 *pBuf, BOOL32 isStatic); +static Int32 FTL_Format(UInt32 dwOptions); +static Int32 FTL_WearLevel(void); +static BOOL32 FTL_GarbageCollect(void); +static BOOL32 FTL_ShutdownNotify(BOOL32 boolMergeLogs); +#endif + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ + +/* + + NAME + _EraseAndMarkEC + DESCRIPTION + This function updates the erase counters and call the VFL_Erase function + PARAMETERS + wVbn [IN] block number + RETURN VALUES + VFL_Erase result + NOTES + + */ + +#ifndef AND_READONLY +static Int32 +_EraseAndMarkEC(UInt16 wVbn) +{ + pstFTLCxt->pawECCacheTable[wVbn]++; + pstFTLCxt->pawRCCacheTable[wVbn] = 0; + return VFL_Erase(wVbn, TRUE32); +} + +/* + + NAME + _SetFTLCxtSpare + DESCRIPTION + This function set context age & status mark to FTL context spare. + PARAMETERS + pAge [IN] the pointer of context age + pStatus [IN] the pointer of status mark + *pSBuf [IN/OUT] the pointer of spare area buffer + RETURN VALUES + none + NOTES + + */ +static void +_SetFTLCxtSpare(UInt32 *pdwAge, UInt8 *pStatus, UInt16 * pwLogicalNumber, UInt8 *pabSBuf) +{ + FTLCxtSpare *pSpare = (FTLCxtSpare *)pabSBuf; + + WMR_MEMSET(pabSBuf, 0xFF, BYTES_PER_METADATA_RAW); + if (pdwAge != NULL) + { + pSpare->dwCxtAge = *pdwAge; + } + if (pStatus != NULL) + { + pSpare->bStatusMark = *pStatus; + } + if (pwLogicalNumber != NULL) + { + pSpare->wLogicalNumber = *pwLogicalNumber; + } +} +#endif // AND_READONLY + +/* + + NAME + _GetFTLCxtSpare + DESCRIPTION + This function returns context age & status mark + from FTL context spare. + PARAMETERS + pAge [OUT] the pointer of context age + pStatus [OUT] the pointer of status mark + *pSBuf [IN] the pointer of spare area buffer + RETURN VALUES + none + NOTES + + */ +static void +_GetFTLCxtSpare(UInt32 *pdwAge, UInt8 *pStatus, UInt16 * pwLogicalNumber, UInt8 *pSBuf) +{ + FTLCxtSpare *pSpare = (FTLCxtSpare *)pSBuf; + + if (pdwAge != NULL) + { + *pdwAge = pSpare->dwCxtAge; + } + if (pwLogicalNumber != NULL) + { + *pwLogicalNumber = pSpare->wLogicalNumber; + } + if (pStatus != NULL) + { + *pStatus = pSpare->bStatusMark; + } +} + +/* + + NAME + _GetLOGCxtSpare + DESCRIPTION + This function returns logical page offset from log spare + PARAMETERS + *pSBuf [IN] the pointer of spare area buffer + RETURN VALUES + NOTES + + */ +static void +_GetLOGCxtSpare(UInt8 *pabSBuf, UInt32 * pdwLpn, UInt32 * pdwWriteAge) +{ + LOGSpare *pSpare; + + pSpare = (LOGSpare *)pabSBuf; + if (pdwLpn != NULL) + { + *pdwLpn = pSpare->dwLPOffset; + } + if (pdwWriteAge != NULL) + { + *pdwWriteAge = pSpare->dwWriteAge; + } +} + +/* + NAME + _SetLOGCxtSpare + DESCRIPTION + This function set logical page offset on spare area. + PARAMETERS + pdwLpn [IN] logical page number + dwWriteAge [IN] counter (allow identifing the latest version of a logical page + case we have a reset / power failure) - see (FTLCxt type). + *pSBuf [IN/OUT] the pointer of spare area buffer + RETURN VALUES + none + NOTES + + */ +#ifndef AND_READONLY +static void +_SetLOGCxtSpare(UInt32 pdwLpn, UInt32 dwWriteAge, UInt8 *pabSBuf) +{ + LOGSpare *pSpare; + + WMR_MEMSET(pabSBuf, 0xFF, BYTES_PER_METADATA_RAW); + pSpare = (LOGSpare *)pabSBuf; + pSpare->dwLPOffset = pdwLpn; + pSpare->dwWriteAge = dwWriteAge; + pSpare->bSpareType = FTL_SPARE_TYPE_LOG; +} +/* + NAME + _PrepareNextMapCxtPage + DESCRIPTION + This function updates the pstFTLCxt->dwCurrMapCxtPagevalue to enable the next write of Cxt information to the flash. + PARAMETERS + RETURN VALUES + FLASE32 - for failure. + TRUE32 - for success. + NOTES + */ +static BOOL32 +_PrepareNextMapCxtPage(void) +{ + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_PrepareNextMapCxtPage()\n"))); + + /* check if context block is full */ + if ((pstFTLCxt->dwCurrMapCxtPage + 1) % PAGES_PER_SUBLK == 0) + { + /* allocate idle context block */ + UInt16 wCurrCxtIdx, wReplacedCxtVbn; + UInt16 wFreeVb; + + /* check what is the current Cxt index */ + for (wCurrCxtIdx = 0; wCurrCxtIdx < (UInt16)FTL_CXT_SECTION_SIZE; wCurrCxtIdx++) + { + if (pstFTLCxt->dwCurrMapCxtPage > GET_Vpn(pstFTLCxt->awMapCxtVbn[wCurrCxtIdx], 0) && + pstFTLCxt->dwCurrMapCxtPage < GET_Vpn((pstFTLCxt->awMapCxtVbn[wCurrCxtIdx] + 1), 0)) + { + break; + } + } + /* we want to throw out the oldest block the one opposite to the index (i.e. 0 -> 1, 1 -> 2, 2 -> 0) and replace it with the idle one */ + wCurrCxtIdx = ((wCurrCxtIdx + 1) % FTL_CXT_SECTION_SIZE); + if (pstFTLCxt->dwMetaWearLevelCounter % (FTL_CXT_SECTION_SIZE * FTL_METAWEARLEVEL_RATIO) < FTL_CXT_SECTION_SIZE) + { + pstFTLCxt->dwMetaWearLevelCounter++; + wReplacedCxtVbn = pstFTLCxt->awMapCxtVbn[wCurrCxtIdx]; + if (_GetFreeVb(&wFreeVb) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _PrepareNextMapCxtPage failed _GetFreeVb(0x%X) (line:%d)\n"), wFreeVb, __LINE__)); + return FALSE32; + } + pstFTLCxt->awMapCxtVbn[wCurrCxtIdx] = wFreeVb; + pstFTLCxt->dwCurrMapCxtPage = GET_Vpn(wFreeVb, 0); + if (_SetFreeVb(wReplacedCxtVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _PrepareNextMapCxtPage failed _SetFreeVb(0x%X) (line:%d)\n"), wReplacedCxtVbn, __LINE__)); + return FALSE32; + } + if (VFL_ChangeFTLCxtVbn(pstFTLCxt->awMapCxtVbn) != VFL_SUCCESS) + { + return FALSE32; + } + } + else + { + pstFTLCxt->dwMetaWearLevelCounter++; + if (_EraseAndMarkEC(pstFTLCxt->awMapCxtVbn[wCurrCxtIdx]) != VFL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _PrepareNextMapCxtPage failed _EraseAndMarkEC(0x%X) (line:%d)\n"), pstFTLCxt->awMapCxtVbn[wCurrCxtIdx], __LINE__)); + return FALSE32; + } + pstFTLCxt->dwCurrMapCxtPage = GET_Vpn(pstFTLCxt->awMapCxtVbn[wCurrCxtIdx], 0); + } + } + else + { + pstFTLCxt->dwCurrMapCxtPage++; + } + + pstFTLCxt->dwAge--; + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_PrepareNextMapCxtPage()\n"))); + + return TRUE32; +} + +/* + NAME + _StoreFTLCxt + DESCRIPTION + This function writes the context & the map data on FTL info area. + PARAMETERS + RETURN VALUES + TRUE32 + _StoreFTLCxt is completed + FALSE32 + _StoreFTLCxt is failed + NOTES + + */ +static BOOL32 +_StoreFTLCxt(void) +{ + BOOL32 bRet = TRUE32; + const UInt8 baStoreCxt[] = + { + FTL_SPARE_TYPE_CXT_EC_TABLE, + FTL_SPARE_TYPE_CXT_RC_TABLE, + FTL_SPARE_TYPE_CXT_MAP_TABLE, + FTL_SPARE_TYPE_CXT_LOGCXT_MAP, + FTL_SPARE_TYPE_CXT_STAT, + FTL_SPARE_TYPE_CXT_INDEX, + }; + UInt32 dwCxtIdx = 0; + UInt16 dwPageIdx = 0; + UInt32 dwSize = 0; + UInt8 *pbaSrc = NULL; + UInt32 *padwPtrs = NULL; + UInt32 dwBufIdx = 0; + UInt32 dwWriteIdx = 0; + UInt8 *pbaData = pstSimpleMergeDataBuffer; + UInt8 *pbaSpare = pstbaMultiplePagesWriteSpare; + + /* Initialize FTL Meta */ + pstFTLMeta->dwVersion = FTL_VERSION; + pstFTLMeta->dwVersionNot = FTL_VERSION_NOT; + + /* If entire FTL Context won't fit in the current block, get the next one */ + if (GET_Vbn(pstFTLCxt->dwCurrMapCxtPage + 1) != + GET_Vbn(pstFTLCxt->dwCurrMapCxtPage + FTL_NUM_PAGES_TO_WRITE_IN_STORECXT + 1)) + { + FTL_CHANGE_FTLCXT_TO_NEXT_BLOCK(); + } + + dwWriteIdx = GET_PageOffset(pstFTLCxt->dwCurrMapCxtPage + 1); + + /* Loop while we have context to write or a failure occurs */ + while ( (bRet) && (NUMELEMENTS(baStoreCxt) > dwCxtIdx) ) + { + /* If we don't have content to write, get more */ + if ( (0 == dwSize) || (NULL == pbaSrc) ) + { + switch ( baStoreCxt[dwCxtIdx] ) + { + case FTL_SPARE_TYPE_CXT_EC_TABLE: + dwSize = FTL_AREA_SIZE * sizeof(UInt16); + pbaSrc = (UInt8 *)pstFTLCxt->pawECCacheTable; + padwPtrs = pstFTLCxt->adwECTablePtrs; + break; + + case FTL_SPARE_TYPE_CXT_RC_TABLE: + dwSize = FTL_AREA_SIZE * sizeof(UInt16); + pbaSrc = (UInt8 *)pstFTLCxt->pawRCCacheTable; + padwPtrs = pstFTLCxt->adwRCTablePtrs; + break; + + case FTL_SPARE_TYPE_CXT_MAP_TABLE: + dwSize = USER_SUBLKS_TOTAL * sizeof(UInt16); + pbaSrc = (UInt8 *)pstFTLCxt->pawMapTable; + padwPtrs = pstFTLCxt->adwMapTablePtrs; + break; + + case FTL_SPARE_TYPE_CXT_LOGCXT_MAP: + dwSize = (LOG_SECTION_SIZE + 1) * PAGES_PER_SUBLK * sizeof(UInt16); + pbaSrc = (UInt8 *)pstFTLCxt->pawLOGCxtMapTable; + padwPtrs = pstFTLCxt->adwLOGCxtMapPtrs; + break; + + case FTL_SPARE_TYPE_CXT_STAT: + pstFTLCxt->adwStatPtrs[0] = FTL_TABLE_PTR_INVALID_VALUE; + pstFTLCxt->adwStatPtrs[1] = FTL_TABLE_PTR_INVALID_VALUE; + if (0 == dwSize) + { + dwSize = BYTES_PER_PAGE; + } +#ifdef AND_COLLECT_STATISTICS + _FTLGetStatisticsToCxt(&pbaData[dwBufIdx * BYTES_PER_PAGE]); +#else //AND_COLLECT_STATISTICS + WMR_MEMSET(&pbaData[dwBufIdx * BYTES_PER_PAGE], 0x00, BYTES_PER_PAGE); +#endif //AND_COLLECT_STATISTICS + padwPtrs = pstFTLCxt->adwStatPtrs; + break; + + case FTL_SPARE_TYPE_CXT_INDEX: + pstFTLCxt->boolFlashCxtIsValid = TRUE32; + dwSize = sizeof(FTLMeta); + pbaSrc = (UInt8 *)pstFTLMeta; + break; + + default: + WMR_PANIC("%s(): Unknown FTL Spare Context 0x%02X!\n", __FUNCTION__, baStoreCxt[dwCxtIdx]); + bRet = FALSE32; + break; + } + } + + /* Break if an error occurred */ + if ( !bRet ) + { + break; + } + + /* Prepare page for current content */ + if (!_PrepareNextMapCxtPage()) + { + bRet = FALSE32; + break; + } + + /* + * If a source pointer was provided, copy one byte at a time. + * Otherwise, assume the data was copied over for us. + */ + if (NULL != pbaSrc) + { + WMR_MEMCPY + ( + &pbaData[dwBufIdx * BYTES_PER_PAGE], + &pbaSrc[dwPageIdx * BYTES_PER_PAGE], + WMR_MIN(dwSize, BYTES_PER_PAGE) + ); + } + + /* Prepare spare data */ + _SetFTLCxtSpare(&pstFTLCxt->dwAge, NULL, &dwPageIdx, &pbaSpare[dwBufIdx * BYTES_PER_METADATA_RAW]); + SET_FTL_SPARE_TYPE(&pbaSpare[dwBufIdx * BYTES_PER_METADATA_RAW], baStoreCxt[dwCxtIdx]); + + /* Update pointers with content's VPN if necessary */ + if (NULL != padwPtrs) + { + padwPtrs[dwPageIdx] = pstFTLCxt->dwCurrMapCxtPage; + } + + dwBufIdx++; + + /* If content size is greater than a page, update size and index for another loop. */ + if ( dwSize > BYTES_PER_PAGE ) + { + dwSize -= BYTES_PER_PAGE; + dwPageIdx++; + } + /* Otherwise, prepare for next set of data */ + else + { + dwCxtIdx++; + dwSize = 0; + pbaSrc = NULL; + padwPtrs = NULL; + dwPageIdx = 0; + } + + /* Make sure no one caused a buffer overflow */ + WMR_ASSERT ( ((UInt32)PAGES_PER_SIMPLE_MERGE_BUFFER >= dwBufIdx ) || + (NUMELEMENTS(baStoreCxt) >= dwCxtIdx)); + + /* + * If the buffer is full or we've exhausted our FTL Context, perform a write */ + if (((UInt32)PAGES_PER_SIMPLE_MERGE_BUFFER == dwBufIdx ) || + (NUMELEMENTS(baStoreCxt) == dwCxtIdx)) + { + BOOL32 bWriteStatus = TRUE32; + + bWriteStatus = VFL_WriteMultiplePagesInVb( + GET_Vpn(GET_Vbn(pstFTLCxt->dwCurrMapCxtPage), dwWriteIdx), + dwBufIdx, + pbaData, + pbaSpare, + TRUE32, + FALSE32); + + if ( !bWriteStatus ) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] %s(): VFL_WriteMultiplePagesInVb() failed!\n"), __FUNCTION__)); + bRet = FALSE32; + break; + } + else + { + /* Update our write index and mark the buffer empty */ + dwWriteIdx += dwBufIdx; + dwBufIdx = 0; + } + } + } + + return bRet; +} +#endif + +/* + + NAME + _LoadFTLCxt + DESCRIPTION + This function loads the minimum aged ftl context. + PARAMETERS + none + RETURN VALUES + TRUE32 + _LoadFTLCxt is completed + FALSE32 + _LoadFTLCxt is failed + NOTES + + */ +static BOOL32 +_LoadFTLCxt(void) +{ + UInt16 wCxtPage, wLoadIdx; + UInt16 wCxtVbn, wVbnIdx; + UInt32 dwMinAge = 0xFFFFFFFF; + Buffer *pBuf = NULL; + Int32 nVFLRet; + BOOL32 boolFoundValidIndex; + UInt16 * pawMapTable = pstFTLCxt->pawMapTable; +#ifndef AND_READONLY + UInt16 * pawECCacheTable = pstFTLCxt->pawECCacheTable; + UInt16 * pawRCCacheTable = pstFTLCxt->pawRCCacheTable; +#endif /* #ifndef AND_READONLY */ + UInt16 * pawLOGCxtMapTable = pstFTLCxt->pawLOGCxtMapTable; + UInt16 * pawCxtMap; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_LoadFTLCxt()\n"))); + + wCxtVbn = 0xFFFF; + + pawCxtMap = VFL_GetFTLCxtVbn(); + if (pawCxtMap == NULL) + { + return FALSE32; /* that does not suppose to happen */ + } + else + { + WMR_MEMCPY(pstFTLCxt->awMapCxtVbn, pawCxtMap, (FTL_CXT_SECTION_SIZE * sizeof(UInt16))); + } + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuf == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] BUF_Get error (line:%d)!\n"), __LINE__)); + return FALSE32; + } + + /* search the minimum aged context virtual block & page offset */ + for (wVbnIdx = 0; wVbnIdx < FTL_CXT_SECTION_SIZE; wVbnIdx++) + { + UInt32 dwAge; + + nVFLRet = VFL_Read(GET_Vpn(pstFTLCxt->awMapCxtVbn[wVbnIdx], 0), pBuf, TRUE32, FALSE32, NULL, NULL, FALSE32); + + /* ignore uncorrectable ECC error */ + if (nVFLRet == VFL_CRITICAL_ERROR) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on VFL_Read(line:%d)!\n"), __LINE__)); + BUF_Release(pBuf); + return FALSE32; + } + + _GetFTLCxtSpare(&dwAge, NULL, NULL, pBuf->pSpare); + if (FTL_SPARE_IS_CXT_MARK(GET_FTL_SPARE_TYPE(pBuf->pSpare)) && nVFLRet == VFL_SUCCESS) + { + if (wCxtVbn == 0xFFFF || dwAge < dwMinAge) + { + dwMinAge = dwAge; + wCxtVbn = pstFTLCxt->awMapCxtVbn[wVbnIdx]; + } + } + } + + BUF_Release(pBuf); + + /* if can not find context */ + if (wCxtVbn == 0xFFFF) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] Can not find context!\n"))); + return FALSE32; + } + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuf == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] BUF_Get error (line:%d)!\n"), __LINE__)); + return FALSE32; + } + /* find if there is a relavant index cxt page */ + boolFoundValidIndex = FALSE32; + +#if FTL_FIND_IDX_PG_BY_BIN_SRCH + { + Int16 startPage = 0, endPage = PAGES_PER_SUBLK-1, midPage; + Int32 nVFLRet; + + while (endPage >= startPage) + { + midPage = DIV2_ROUNDUP(endPage + startPage); + wCxtPage = midPage; + nVFLRet = VFL_Read(GET_Vpn(wCxtVbn, wCxtPage), pBuf, TRUE32, FALSE32, NULL, NULL, FALSE32); + + + if (nVFLRet == VFL_SUCCESS_CLEAN) + { + endPage = midPage - 1; + } + else if (nVFLRet == VFL_SUCCESS) + { + if (startPage == endPage) + { + /* check that this is an index */ + if (GET_FTL_SPARE_TYPE(pBuf->pSpare) == FTL_SPARE_TYPE_CXT_INDEX) + { + boolFoundValidIndex = TRUE32; + WMR_MEMCPY(pstFTLMeta, pBuf->pData, sizeof(FTLMeta)); + } + break; + } + else + { + startPage = midPage; + } + } + else + { + /* the page is written but not probably assume we have no valid index (i.e. power failure)*/ + break; + } + } + } +#else + for (wCxtPage = (UInt16)PAGES_PER_SUBLK; wCxtPage != 0;) + { + wCxtPage--; + nVFLRet = VFL_Read(GET_Vpn(wCxtVbn, wCxtPage), pBuf, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (nVFLRet == VFL_SUCCESS) + { + /* check that this is an index */ + if (GET_FTL_SPARE_TYPE(pBuf->pSpare) == FTL_SPARE_TYPE_CXT_INDEX) + { + boolFoundValidIndex = TRUE32; + WMR_MEMCPY(pstFTLMeta, pBuf->pData, sizeof(FTLMeta)); + } + break; + } + else if (nVFLRet != VFL_SUCCESS_CLEAN) + { + /* the page is written but not probably assume we have no valid index (i.e. power failure)*/ + break; + } + } +#endif + + /* change the pointers to what they were */ + pstFTLCxt->pawMapTable = pawMapTable; +#ifndef AND_READONLY + pstFTLCxt->pawECCacheTable = pawECCacheTable; + pstFTLCxt->pawRCCacheTable = pawRCCacheTable; +#endif /* #ifndef AND_READONLY */ + pstFTLCxt->pawLOGCxtMapTable = pawLOGCxtMapTable; + for (wLoadIdx = 0; wLoadIdx < (LOG_SECTION_SIZE + 1); wLoadIdx++) + { + pstFTLCxt->aLOGCxtTable[wLoadIdx].paPOffsetL2P = &pstFTLCxt->pawLOGCxtMapTable[PAGES_PER_SUBLK * wLoadIdx]; + } + + /* load the data using the pointers in the index */ + /* load maps */ + for (wLoadIdx = 0; (boolFoundValidIndex == TRUE32) && + (wLoadIdx < FTL_NUM_PAGES_PER_MAP_TABLE); + wLoadIdx++) + { + nVFLRet = VFL_Read(pstFTLCxt->adwMapTablePtrs[wLoadIdx], pBuf, TRUE32, TRUE32, NULL, NULL, FALSE32); + if (nVFLRet != VFL_SUCCESS) + { + boolFoundValidIndex = FALSE32; + break; + } + WMR_MEMCPY(&(((UInt8 *)pstFTLCxt->pawMapTable)[wLoadIdx * BYTES_PER_PAGE]), pBuf->pData, WMR_MIN(((USER_SUBLKS_TOTAL * sizeof(UInt16)) - (wLoadIdx * BYTES_PER_PAGE)), BYTES_PER_PAGE)); + } + + /* load logcxt maps here */ + for (wLoadIdx = 0; (boolFoundValidIndex == TRUE32) && + (wLoadIdx < FTL_NUM_PAGES_PER_LOGCXT_MAP_TABLE); + wLoadIdx++) + { + nVFLRet = VFL_Read(pstFTLCxt->adwLOGCxtMapPtrs[wLoadIdx], pBuf, TRUE32, TRUE32, NULL, NULL, FALSE32); + if (nVFLRet != VFL_SUCCESS) + { + boolFoundValidIndex = FALSE32; + break; + } + WMR_MEMCPY(&(((UInt8 *)pstFTLCxt->pawLOGCxtMapTable)[wLoadIdx * BYTES_PER_PAGE]), pBuf->pData, WMR_MIN(((LOG_SECTION_SIZE * PAGES_PER_SUBLK * sizeof(UInt16)) - (wLoadIdx * BYTES_PER_PAGE)), BYTES_PER_PAGE)); + } + +#ifndef AND_READONLY + /* load EC Table */ + for (wLoadIdx = 0; (boolFoundValidIndex == TRUE32) && + (wLoadIdx < FTL_NUM_PAGES_PER_EC_TABLE); + wLoadIdx++) + { + nVFLRet = VFL_Read(pstFTLCxt->adwECTablePtrs[wLoadIdx], pBuf, TRUE32, TRUE32, NULL, NULL, FALSE32); + if (nVFLRet != VFL_SUCCESS) + { + boolFoundValidIndex = FALSE32; + break; + } + WMR_MEMCPY(&(((UInt8 *)pstFTLCxt->pawECCacheTable)[wLoadIdx * BYTES_PER_PAGE]), pBuf->pData, WMR_MIN(((FTL_AREA_SIZE * sizeof(UInt16)) - (wLoadIdx * BYTES_PER_PAGE)), BYTES_PER_PAGE)); + } +#endif /* #ifndef AND_READONLY */ + +#ifndef AND_READONLY + /* load RC Table */ + for (wLoadIdx = 0; (boolFoundValidIndex == TRUE32) && + (wLoadIdx < FTL_NUM_PAGES_PER_RC_TABLE); + wLoadIdx++) + { + nVFLRet = VFL_Read(pstFTLCxt->adwRCTablePtrs[wLoadIdx], pBuf, TRUE32, TRUE32, NULL, NULL, FALSE32); + if (nVFLRet != VFL_SUCCESS) + { + boolFoundValidIndex = FALSE32; + break; + } + WMR_MEMCPY(&(((UInt8 *)pstFTLCxt->pawRCCacheTable)[wLoadIdx * BYTES_PER_PAGE]), pBuf->pData, WMR_MIN(((FTL_AREA_SIZE * sizeof(UInt16)) - (wLoadIdx * BYTES_PER_PAGE)), BYTES_PER_PAGE)); + } +#endif /* #ifndef AND_READONLY */ + +#ifdef AND_COLLECT_STATISTICS + if (boolFoundValidIndex == TRUE32) + { + // read the stats + if ((pstFTLCxt->adwStatPtrs[1] == FTL_TABLE_PTR_INVALID_VALUE) && + (pstFTLCxt->adwStatPtrs[0] / PAGES_PER_SUBLK < VFL_GetDeviceInfo(AND_DEVINFO_NUM_OF_USER_SUBLK))) + { + nVFLRet = VFL_Read(pstFTLCxt->adwStatPtrs[0], pBuf, TRUE32, TRUE32, NULL, NULL, FALSE32); + if (nVFLRet != VFL_SUCCESS) + { + boolFoundValidIndex = FALSE32; + } + else + { + _FTLSetStatisticsFromCxt(pBuf->pData); + } + } + } +#endif // AND_COLLECT_STATISTICS + + BUF_Release(pBuf); + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_LoadFTLCxt()\n"))); + return boolFoundValidIndex; +} + +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) +/* + + NAME + _RecoverLOGCxtInfo + DESCRIPTION + This function recovers the log mapping based on the info found in the block. + This function should only be used as part as _FTLRestore. + PARAMETERS + none + RETURN VALUES + TRUE32 + success + FALSE32 + failure (should only occour if allocating a buffer failed). + NOTES + + */ + +BOOL32 _RecoverLOGCxtInfo(LOGCxt * pLog) +{ + UInt16 wVpnIdx; + Buffer *pBuf = NULL; + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pBuf == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] BUF_Get error (line:%d)!\n"), __LINE__)); + return FALSE32; + } + + for (wVpnIdx = 0; wVpnIdx < PAGES_PER_SUBLK; wVpnIdx++) + { + UInt32 dwVpn; + Int32 nVFLRet; + + dwVpn = GET_Vpn(pLog->wVbn, wVpnIdx); + + nVFLRet = VFL_Read(dwVpn, pBuf, TRUE32, FALSE32, NULL, NULL, FALSE32); + + if (nVFLRet == VFL_SUCCESS) + { + UInt32 dwLpn; + _GetLOGCxtSpare(pBuf->pSpare, &dwLpn, NULL); + if (pLog->paPOffsetL2P[(dwLpn % PAGES_PER_SUBLK)] == 0xFFFF) + { + pLog->wNumOfValidLP++; + } + pLog->paPOffsetL2P[(dwLpn % PAGES_PER_SUBLK)] = wVpnIdx; + } + } + BUF_Release(pBuf); + return TRUE32; +} +#endif // ! WMR_DISABLE_FTL_RECOVERY + +/* + + NAME + _MakeLogMap + DESCRIPTION + This function makes log virtual block context from scanning log blocks. + PARAMETERS + none + RETURN VALUES + TRUE32 + _MakeLogMap is completed + FALSE32 + _MakeLogMap is failed + NOTES + + */ +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) +static BOOL32 +_MakeLogMap(void) +{ + LOGCxt *pLog; + UInt16 wIdx; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_MakeLogMap()\n"))); + + for (wIdx = 0; wIdx < LOG_SECTION_SIZE; wIdx++) + { + pLog = GET_LOGCxt(wIdx); + + _InitLogCxt(pLog); + + if (pLog->wVbn == LOG_EMPTY_SLOT) + { + continue; + } + + if (_RecoverLOGCxtInfo(pLog) == FALSE32) + { + return FALSE32; + } + + /* avoid suprises - since we are not sure what got us to restore we can not assume the rest of the log is usable */ + pLog->boolCopyMerge = FALSE32; + pLog->wFreePOffset = PAGES_PER_SUBLK; + } + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_MakeLogMap()\n"))); + return TRUE32; +} +#endif //#if (defined(WMR_ENABLE_FTL_RECOVERY) && WMR_ENABLE_FTL_RECOVERY) + +#ifndef AND_READONLY +/* + + NAME + _DisableCopyMerge + DESCRIPTION + This function chooses whether the log can be copymerged or not. + PARAMETERS + pLog [IN] the pointer of log block context + nLPOffset [IN] logical page offset + RETURN VALUES + none + NOTES + + */ +static void +_DisableCopyMerge(LOGCxt *pLog, UInt32 nLPOffset) +{ + UInt32 nPPOffset; + + nPPOffset = pLog->paPOffsetL2P[nLPOffset]; + + if (pLog->wFreePOffset != pLog->wNumOfValidLP || + nPPOffset != nLPOffset) + { + /* miss align case */ + pLog->boolCopyMerge = FALSE32; + } +} +#endif // ! AND_READONLY + +/* + + NAME + _ScanLogSection + DESCRIPTION + This function returns log block context from the logical block number. + (super block address) + PARAMETERS + nLbn [IN] logical block number (super block address) + RETURN VALUES + LOGCxt* + the pointer of log block context + NULL + there is no log to match the lbn. + NOTES + + */ +static LOGCxt * +_ScanLogSection(UInt32 nLbn) +{ + UInt32 nIdx; + + for (nIdx = 0; nIdx < LOG_SECTION_SIZE; nIdx++) + { + if (pstFTLCxt->aLOGCxtTable[nIdx].wVbn != LOG_EMPTY_SLOT && pstFTLCxt->aLOGCxtTable[nIdx].wLbn == nLbn) + { + return &(pstFTLCxt->aLOGCxtTable[nIdx]); + } + } + + return NULL; +} +#ifndef AND_READONLY +/* + + NAME + _GetFreeVb + DESCRIPTION + This function returns virtual block number of free block. + PARAMETERS + pVbn [OUT] the pointer of virtual block number + pEC [OUT] the erase count of free block + RETURN VALUES + TRUE32 + _GetFreeVb is completed + FALSE32 + _GetFreeVb is failed + NOTES + + */ +static BOOL32 +_GetFreeVb(UInt16 *pwVbn) +{ + UInt16 wIdx; + + UInt16 wFreeVbListTail = pstFTLCxt->wFreeVbListTail; + UInt16 wRetVbn; + UInt32 wMinEC = 0xFFFF; + UInt16 wFreeIdx = FREE_SECTION_SIZE; + UInt16 wTemp; + static UInt16 wLastAllocatedFreeVb = 0xFFFF; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_GetFreeVb()\n"))); + + /* choose minimum erased free block */ + for (wIdx = 0; wIdx < pstFTLCxt->wNumOfFreeVb; wIdx++) + { + UInt16 wIdxTemp = wIdx + wFreeVbListTail; + + if (wIdxTemp >= FREE_SECTION_SIZE) + { + wIdxTemp -= FREE_SECTION_SIZE; + } + + /* avoid giving the last allocated vb two times in a row */ + if (wLastAllocatedFreeVb != pstFTLCxt->awFreeVbList[wIdxTemp]) + { + if (wMinEC > pstFTLCxt->pawECCacheTable[pstFTLCxt->awFreeVbList[wIdxTemp]]) + { + wMinEC = pstFTLCxt->pawECCacheTable[pstFTLCxt->awFreeVbList[wIdxTemp]]; + wFreeIdx = wIdxTemp; + } + } + } + // WMR_ASSERT(wFreeIdx < FREE_SECTION_SIZE); + if (wFreeIdx >= FREE_SECTION_SIZE) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _GetFreeVb failed wFreeIdx = 0x%X (line:%d)!\n"), wFreeIdx, __LINE__)); + return FALSE32; + } + /* if the chosen block (nFreeIdx) is not the one in the wFreeVbListTail location of the aFreeVbList + swap the pointers and erase counters (EC) between the chosen and the wFreeVbListTail */ + if (wFreeIdx != wFreeVbListTail) + { + wTemp = pstFTLCxt->awFreeVbList[wFreeVbListTail]; + pstFTLCxt->awFreeVbList[wFreeVbListTail] = pstFTLCxt->awFreeVbList[wFreeIdx]; + pstFTLCxt->awFreeVbList[wFreeIdx] = wTemp; + } + + wRetVbn = pstFTLCxt->awFreeVbList[wFreeVbListTail]; + wLastAllocatedFreeVb = wRetVbn; + + // WMR_ASSERT(wRetVbn < FTL_AREA_SIZE); + if (wRetVbn >= FTL_AREA_SIZE) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _GetFreeVb failed wRetVbn = 0x%X (line:%d)!\n"), wRetVbn, __LINE__)); + return FALSE32; + } + + /* move free vb list's pointer */ + if ((wFreeVbListTail + 1) == FREE_SECTION_SIZE) + { + pstFTLCxt->wFreeVbListTail = 0; + } + else + { + pstFTLCxt->wFreeVbListTail = wFreeVbListTail + 1; + } + + pstFTLCxt->wNumOfFreeVb--; + + //WMR_ASSERT(wFreeVbListTail < FREE_SECTION_SIZE); + //WMR_ASSERT(pstFTLCxt->wNumOfFreeVb < FREE_SECTION_SIZE); + if ((wFreeVbListTail >= FREE_SECTION_SIZE) || (pstFTLCxt->wNumOfFreeVb >= FREE_SECTION_SIZE)) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _GetFreeVb failed wFreeVbListTail = 0x%X, pstFTLCxt->wNumOfFreeVb = 0x%X (line:%d)!\n"), wFreeVbListTail, pstFTLCxt->wNumOfFreeVb, __LINE__)); + return FALSE32; + } + + *pwVbn = wRetVbn; + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_GetFreeVb()\n"))); + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _SetFreeVb */ +/* DESCRIPTION */ +/* This function adds virtual block to the free vb list. */ +/* PARAMETERS */ +/* wVbn [IN] virtual block number */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_SetFreeVb(UInt16 wVbn) +{ + UInt32 nFreeVbListHead; + + WMR_ASSERT(wVbn < FTL_AREA_SIZE); + + nFreeVbListHead = pstFTLCxt->wFreeVbListTail + pstFTLCxt->wNumOfFreeVb++; + + if (_EraseAndMarkEC(wVbn) != VFL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _SetFreeVb failed _EraseAndMarkEC(0x%X) (line:%d)\n"), wVbn, __LINE__)); + return FALSE32; + } + + if (nFreeVbListHead >= FREE_SECTION_SIZE) + { + nFreeVbListHead -= FREE_SECTION_SIZE; + } + + WMR_ASSERT(nFreeVbListHead < FREE_SECTION_SIZE); + WMR_ASSERT(pstFTLCxt->wNumOfFreeVb <= FREE_SECTION_SIZE); + + pstFTLCxt->awFreeVbList[nFreeVbListHead] = wVbn; + + WMR_ASSERT(pstFTLCxt->wNumOfFreeVb <= FREE_SECTION_SIZE); + + return TRUE32; +} +#endif /* AND_READONLY */ + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _InitLogCxt */ +/* DESCRIPTION */ +/* This function initializes log context. */ +/* PARAMETERS */ +/* pLog [IN] the pointer of log context */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static void +_InitLogCxt(LOGCxt *pLog) +{ + WMR_MEMSET(pLog->paPOffsetL2P, 0xFF, (PAGES_PER_SUBLK * sizeof(UInt16))); + + pLog->boolCopyMerge = TRUE32; + pLog->wFreePOffset = 0; + pLog->wNumOfValidLP = 0; +} + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* _MoveD2F */ +/* DESCRIPTION */ +/* This function copies from data block to free block */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _MoveD2F is completed */ +/* FALSE32 */ +/* _MoveD2F is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_MoveD2F(UInt16 wDataLbn, UInt16 wFreeVbn) +{ + Int32 nRet; + UInt16 wIdx, wLPOffsetIdx; + BOOL32 boolCopyRes = FALSE32; + // use a different area of the spare buffer than the one used by _FTLRead that reads PAGES_PER_SIMPLE_MERGE_BUFFER pages + UInt8 *pabMultiSpareBuffer = &pstbaMultiplePagesWriteSpare[PAGES_PER_SIMPLE_MERGE_BUFFER * BYTES_PER_METADATA_RAW]; + + FTL_LOG_PRINT((TEXT("[FTL:OUT] ++_MoveD2F()\n"))); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwMoveD2FCnt++; +#endif + /* copy from data block to free block */ + + pstFTLCxt->dwWriteAge++; + for (wIdx = 0; wIdx < PAGES_PER_SUBLK; wIdx += PAGES_PER_SIMPLE_MERGE_BUFFER) + { + if (_FTLRead(((((UInt32)wDataLbn) * PAGES_PER_SUBLK) + (UInt32)wIdx), PAGES_PER_SIMPLE_MERGE_BUFFER, pstSimpleMergeDataBuffer) == FTL_SUCCESS) + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < PAGES_PER_SIMPLE_MERGE_BUFFER; wLPOffsetIdx++) + { + UInt8 * pbaTempSpare = &(pabMultiSpareBuffer[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(GET_Vpn(wDataLbn, (wIdx + wLPOffsetIdx)), pstFTLCxt->dwWriteAge, pbaTempSpare); + } + } + else + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed calling _FTLRead(0x%X, 0x%X, 0x%X) (line:%d)\n"), + ((((UInt32)wDataLbn) * PAGES_PER_SUBLK) + (UInt32)wIdx), PAGES_PER_SIMPLE_MERGE_BUFFER, pstSimpleMergeDataBuffer, __LINE__)); + for (wLPOffsetIdx = 0; wLPOffsetIdx < PAGES_PER_SIMPLE_MERGE_BUFFER; wLPOffsetIdx++) + { + UInt8 * pbaTempSpare = &(pabMultiSpareBuffer[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(GET_Vpn(wDataLbn, (wIdx + wLPOffsetIdx)), pstFTLCxt->dwWriteAge, pbaTempSpare); + if (_FTLRead(((((UInt32)wDataLbn) * PAGES_PER_SUBLK) + (UInt32)(wIdx + wLPOffsetIdx)), 1, &pstSimpleMergeDataBuffer[BYTES_PER_PAGE * wLPOffsetIdx]) != FTL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed calling _FTLRead(0x%X, 0x%X, 0x%X) (line:%d)\n"), + ((((UInt32)wDataLbn) * PAGES_PER_SUBLK) + (UInt32)(wIdx + wLPOffsetIdx)), 1, &pstSimpleMergeDataBuffer[BYTES_PER_PAGE * wLPOffsetIdx], __LINE__)); + SET_FTL_ECC_MARK(pbaTempSpare); + } + } + } + + if ((wLPOffsetIdx + wIdx) == PAGES_PER_SUBLK) + { + SET_FTL_SPARE_TYPE(&(pabMultiSpareBuffer[(wLPOffsetIdx - 1) * BYTES_PER_METADATA_RAW]), FTL_SPARE_TYPE_DATA); + } + boolCopyRes = VFL_WriteMultiplePagesInVb(GET_Vpn(wFreeVbn, wIdx), PAGES_PER_SIMPLE_MERGE_BUFFER, pstSimpleMergeDataBuffer, pabMultiSpareBuffer, TRUE32, FALSE32); + if (boolCopyRes == FALSE32) + { + break; + } + } + if (boolCopyRes == FALSE32) + { + /* Erase the failed free block to avoid failure in restore */ + nRet = _EraseAndMarkEC(wFreeVbn); + if (nRet != VFL_SUCCESS) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _MoveD2F error running VFL_Erase(0x%X) (line:%d)!\n"), wFreeVbn, __LINE__)); + } + FTL_WRN_PRINT((TEXT("[FTL:WRN] _MoveD2F failed moving the data block to a new block!\n"))); + return FALSE32; + } + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_MoveD2F()\n"))); + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _AutoWearLevel */ +/* DESCRIPTION */ +/* This function operates wear level. */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _AutoWearLevel is completed */ +/* FALSE32 */ +/* _AutoWearLevel is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_AutoWearLevel(void) +{ + UInt16 wIdx; + + UInt16 wMinEC = 0xFFFF; /* minimum erase count */ + UInt16 wMaxEC = 0x0; /* maximum erase count */ + + UInt16 wMinVbn = 0; + UInt16 wMinLbn = 0; + + UInt16 wFreeIdx = FREE_SECTION_SIZE; /* need to be given a starting value */ + UInt16 wFreeVbn; + static UInt16 wLastFreeVbn = 0xFFFF; + Int32 nVFLRet; + + FTL_LOG_PRINT((TEXT("[FTL:OUT] ++_AutoWearLevel()\n"))); + + if (_FTLMarkCxtNotValid() == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _AutoWearLevel failed calling _FTLMarkCxtNotValid\n"))); + return FALSE32; + } + /* choose maximum erased free block */ + for (wIdx = 0; wIdx < pstFTLCxt->wNumOfFreeVb; wIdx++) + { + UInt16 wIdxTemp = wIdx + pstFTLCxt->wFreeVbListTail; + + if (wIdxTemp >= FREE_SECTION_SIZE) + { + wIdxTemp -= FREE_SECTION_SIZE; /* making the aFreeVbEC list cyclic */ + } + + /* verify that we are not getting the same free vb time after time */ + if (wLastFreeVbn != pstFTLCxt->awFreeVbList[wIdxTemp]) + { + if ((wMaxEC < pstFTLCxt->pawECCacheTable[pstFTLCxt->awFreeVbList[wIdxTemp]]) || (wFreeIdx == FREE_SECTION_SIZE)) + { + wMaxEC = pstFTLCxt->pawECCacheTable[pstFTLCxt->awFreeVbList[wIdxTemp]]; + wFreeIdx = wIdxTemp; + } + } + } + + WMR_ASSERT(wFreeIdx < FREE_SECTION_SIZE); + + wFreeVbn = pstFTLCxt->awFreeVbList[wFreeIdx]; + wLastFreeVbn = wFreeVbn; + /* calculate data blocks erase count */ + for (wIdx = 0; wIdx < USER_SUBLKS_TOTAL; wIdx++) + { + UInt16 wECTemp; + + /* using vb from the map table we make sure to swap only data blocks */ + wECTemp = pstFTLCxt->pawECCacheTable[CONVERT_L2V(wIdx)]; + + if (wMinEC >= wECTemp && _ScanLogSection(wIdx) == NULL) + { + wMinEC = wECTemp; + wMinVbn = CONVERT_L2V(wIdx); + wMinLbn = wIdx; + } + + if (wMaxEC <= wECTemp) + { + wMaxEC = wECTemp; + } + } + + if (wMaxEC == 0 || WMR_WEAR_LEVEL_MAX_DIFF > (wMaxEC - wMinEC) || wMinVbn == wFreeVbn) + { + return TRUE32; + } + + /* erase free block */ + nVFLRet = _EraseAndMarkEC(wFreeVbn); + if (nVFLRet != VFL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on VFL_Erase(0x%X) (line:%d)!\n"), wFreeVbn, __LINE__)); + return FALSE32; + } + + if (_MoveD2F(wMinLbn, wFreeVbn) == FALSE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _MoveD2F Failed (line:%d)!\n"), __LINE__)); + return FALSE32; + } + else + { + if (_EraseAndMarkEC(CONVERT_L2V(wMinLbn)) != VFL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _AutoWearLevel failed _EraseAndMarkEC(0x%X) (line:%d)\n"), wMinLbn, __LINE__)); + } + pstFTLCxt->awFreeVbList[wFreeIdx] = CONVERT_L2V(wMinLbn); + MODIFY_LB_MAP(wMinLbn, wFreeVbn); + } + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_AutoWearLevel()\n"))); + + return TRUE32; +} + +/* + + NAME + FTL_WearLevel + DESCRIPTION + This function operates wearlevels a single VB. + RETURN VALUES + FTL_SUCCESS + success + FTL_CRITICAL_ERROR + failure + FTL_OUT_OF_RANGE + counter is under WMR_WEAR_LEVEL_FREQUENCY (we are done wearleveling). + */ +static Int32 +FTL_WearLevel(void) +{ + if (_IsBlockInRefreshList(0xFFFF, 0xFFFF, NULL) == TRUE32) + { + UInt8 bTrialIdx; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwWearLevelCnt++; +#endif + /* only wear level after a write operation to avoid unvalidating the FTLCxt before wearlelveling */ + for (bTrialIdx = 0; bTrialIdx < 4; bTrialIdx++) + { + if (_HandleRefreshBlock() == TRUE32) + { + return FTL_SUCCESS; + } + } + if (bTrialIdx == 4) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] FTL_WearLevel failed _HandleRefreshBlock() (line:%d)\n"), __LINE__)); + return FTL_CRITICAL_ERROR; + } + } + else if (pstFTLCxt->wNumOfFreeVb < (FREE_LIST_SIZE + 3)) + { +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwWearLevelCnt++; +#endif + if (_Merge(NULL) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] FTL_WearLevel failed _Merge(NULL) (line:%d)\n"), __LINE__)); + return FTL_CRITICAL_ERROR; + } + return FTL_SUCCESS; + } + else if (pstFTLCxt->boolFlashCxtIsValid == FALSE32 && pstFTLCxt->wWearLevelCounter >= WMR_WEAR_LEVEL_FREQUENCY) + { + /* only wear level after a write operation to avoid unvalidating the FTLCxt before wearlelveling */ + UInt8 bTrialIdx; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwWearLevelCnt++; +#endif + for (bTrialIdx = 0; bTrialIdx < 4; bTrialIdx++) + { + if (_AutoWearLevel() == TRUE32) + { + pstFTLCxt->wWearLevelCounter -= WMR_WEAR_LEVEL_FREQUENCY; + return FTL_SUCCESS; + } + } + if (bTrialIdx == 4) + { + return FTL_CRITICAL_ERROR; + } + } + return FTL_OUT_OF_RANGE_ERROR; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _PrepareLog */ +/* DESCRIPTION */ +/* This function prepares log block context. */ +/* PARAMETERS */ +/* nLbn [IN] logical block number */ +/* pLOGCxt [OUT] the pointer of log block context */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _PrepareLog is completed */ +/* FALSE32 */ +/* _PrepareLog is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static LOGCxt * +_PrepareLog(UInt16 wLbn) +{ + LOGCxt *pLog; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_PrepareLog(nLbn:%d)\n"), wLbn)); + + pLog = _ScanLogSection(wLbn); + + if (pLog == NULL) + { + /* if log is not allocated */ + BOOL32 boolCleanLogFound = FALSE32; + + for (pLog = pstFTLCxt->aLOGCxtTable; + pLog != pstFTLCxt->aLOGCxtTable + LOG_SECTION_SIZE; + pLog++) + { + if (pLog->wVbn != LOG_EMPTY_SLOT && + pLog->wFreePOffset == 0) + { + boolCleanLogFound = TRUE32; + break; + } + } + + if (boolCleanLogFound == TRUE32) + { + /* find free log context */ + FTL_SET_LOG_LBN(pLog, wLbn); + } + else + { + if (pstFTLCxt->wNumOfFreeVb == FREE_LIST_SIZE) + { + /* make a new free block */ + if (_Merge(NULL) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _Merge!\n"))); + return NULL; + } + } + + pLog = pstFTLCxt->aLOGCxtTable; + + while (pLog->wVbn != LOG_EMPTY_SLOT) + { + pLog++; + } + + FTL_SET_LOG_LBN(pLog, wLbn); + { + UInt16 wVbnForLog; + if (_GetFreeVb(&wVbnForLog) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _GetFreeVb (line:%d)!\n"), __LINE__)); + return NULL; + } + ASSIGN_VBN_TO_LOG(pLog, wVbnForLog); + } + } + + /* initialize the newly generated log context */ + _InitLogCxt(pLog); + } + + pLog->dwLogAge = pstFTLCxt->dwWriteAge - 1; + + if (pLog->dwLogAge == 0) /* NirW - check to see if this if is needed */ + { + UInt32 nIdx; + LOGCxt *pTempLog; + + for (nIdx = 0; nIdx < LOG_SECTION_SIZE; nIdx++) + { + pTempLog = GET_LOGCxt(nIdx); + pTempLog->dwLogAge = 0; + } + } + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_PrepareLog(nLbn:%d)\n"), wLbn)); + + return pLog; +} +#endif + +#if !defined(AND_READONLY) || \ + !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) + +#define FTL_EXTRA_LOG_CXT (&(pstFTLCxt->aLOGCxtTable[LOG_SECTION_SIZE])) +void _CopyLOGCxt(LOGCxt * pLOGDst, LOGCxt * pLOGSrc) +{ + pLOGDst->boolCopyMerge = pLOGSrc->boolCopyMerge; + pLOGDst->dwLogAge = pLOGSrc->dwLogAge; + pLOGDst->wFreePOffset = pLOGSrc->wFreePOffset; + FTL_SET_LOG_LBN(pLOGDst, pLOGSrc->wLbn); + pLOGDst->wNumOfValidLP = pLOGSrc->wNumOfValidLP; + pLOGDst->wVbn = pLOGSrc->wVbn; + WMR_MEMCPY(pLOGDst->paPOffsetL2P, pLOGSrc->paPOffsetL2P, (PAGES_PER_SUBLK * sizeof(UInt16))); +} +#endif /* !defined(AND_READONLY) || \ + !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) */ + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* _DoMoveMerge */ +/* DESCRIPTION */ +/* This function operates move merge. (log --> free) */ +/* PARAMETERS */ +/* pLogVictim [IN] the pointer of log block context (victim) */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _DoMoveMerge is completed */ +/* FALSE32 */ +/* _DoMoveMerge is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_DoMoveMerge(LOGCxt *pLogVictim) +{ + UInt32 nIdx; + UInt16 wF2LVbn; + UInt16 wL2FVbn; + UInt32 nSrcPOffset; + UInt8 bTrialIdx; + BOOL32 boolRes = FALSE32; + Buffer *pBuff; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_DoMoveMerge(nLbn:%d)\n"), pLogVictim->wLbn)); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwDoMoveMergeCnt++; +#endif + /* check for the rare case that the log failed completely and contains no valid blocks */ + if (pLogVictim->wNumOfValidLP == 0) + { + if (_SetFreeVb(pLogVictim->wVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed _SetFreeVb(0x%X) (line:%d)!\n"), pLogVictim->wVbn, __LINE__)); + return FALSE32; + } + MARK_LOG_AS_EMPTY(pLogVictim); + return TRUE32; + } + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuff == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed BUF_Get (line:%d)!\n"), __LINE__)); + return FALSE32; + } + wL2FVbn = pLogVictim->wVbn; + _CopyLOGCxt(FTL_EXTRA_LOG_CXT, pLogVictim); + + for (bTrialIdx = 0; bTrialIdx < 4; bTrialIdx++) + { + UInt16 wPagesToCopy; + UInt16 wWriteOffset; + /* get free block from free block list */ + if (_GetFreeVb(&wF2LVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _GetFreeVb (line:%d)!\n"), __LINE__)); + BUF_Release(pBuff); + return FALSE32; + } + pLogVictim->wFreePOffset = 0; + pLogVictim->boolCopyMerge = TRUE32; + + /* recalculate number of valid page for disable copy merge operation */ + pLogVictim->wNumOfValidLP = 0; + wPagesToCopy = 0; + wWriteOffset = 0; + pstFTLCxt->dwWriteAge++; + for (nIdx = 0; nIdx < PAGES_PER_SUBLK; nIdx++) + { + nSrcPOffset = pLogVictim->paPOffsetL2P[nIdx]; + + if (nSrcPOffset != 0xFFFF) + { + pstadwScatteredReadVpn[wPagesToCopy] = GET_Vpn(wL2FVbn, nSrcPOffset); + pstadwScatteredReadVpn[PAGES_PER_SIMPLE_MERGE_BUFFER + wPagesToCopy] = GET_Vpn(pLogVictim->wLbn, nIdx); // this is the Lpn + pLogVictim->paPOffsetL2P[nIdx] = pLogVictim->wFreePOffset; + + pLogVictim->wFreePOffset++; + + pLogVictim->wNumOfValidLP++; + + if (pLogVictim->boolCopyMerge == TRUE32) + { + _DisableCopyMerge(pLogVictim, nIdx); + } + wPagesToCopy++; + } + if (wPagesToCopy == PAGES_PER_SIMPLE_MERGE_BUFFER || ((wPagesToCopy != 0) && (nIdx == (UInt32)(PAGES_PER_SUBLK - 1)))) + { + UInt16 wLPOffsetIdx; + if (VFL_ReadScatteredPagesInVb(pstadwScatteredReadVpn, wPagesToCopy, pstSimpleMergeDataBuffer, pstbaMultiplePagesWriteSpare, NULL, NULL, FALSE32, NULL) == TRUE32) + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < wPagesToCopy; wLPOffsetIdx++) + { + UInt8 * pbaTempSpare = &(pstbaMultiplePagesWriteSpare[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(pstadwScatteredReadVpn[PAGES_PER_SIMPLE_MERGE_BUFFER + wLPOffsetIdx], pstFTLCxt->dwWriteAge, pbaTempSpare); + } + } + else + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < wPagesToCopy; wLPOffsetIdx++) + { + Int32 nRet; + UInt8 * pbaTempSpare = &(pstbaMultiplePagesWriteSpare[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(pstadwScatteredReadVpn[PAGES_PER_SIMPLE_MERGE_BUFFER + wLPOffsetIdx], pstFTLCxt->dwWriteAge, pbaTempSpare); + pBuff->pData = &pstSimpleMergeDataBuffer[BYTES_PER_PAGE * wLPOffsetIdx]; + nRet = VFL_Read(pstadwScatteredReadVpn[wLPOffsetIdx], pBuff, TRUE32, TRUE32, NULL, NULL, FALSE32); + if (nRet != VFL_SUCCESS && nRet != VFL_SUCCESS_CLEAN) + { + SET_FTL_ECC_MARK(pbaTempSpare); + } + } + } + // write + if (VFL_WriteMultiplePagesInVb(GET_Vpn(wF2LVbn, wWriteOffset), wPagesToCopy, pstSimpleMergeDataBuffer, pstbaMultiplePagesWriteSpare, TRUE32, FALSE32) == FALSE32) + { + break; + } + + wWriteOffset += wPagesToCopy; + wPagesToCopy = 0; + } + } + if (nIdx == PAGES_PER_SUBLK) + { + /* release the log block to free block */ + if (_SetFreeVb(wL2FVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed _SetFreeVb(0x%X) (line:%d)!\n"), pLogVictim->wVbn, __LINE__)); + boolRes = FALSE32; + break; + } + + ASSIGN_VBN_TO_LOG(pLogVictim, wF2LVbn); + boolRes = TRUE32; + break; + } + else + { + /* restore the values in the log */ + _CopyLOGCxt(pLogVictim, FTL_EXTRA_LOG_CXT); + if (_SetFreeVb(wF2LVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed _SetFreeVb(0x%X) (line:%d)!\n"), wF2LVbn, __LINE__)); + boolRes = FALSE32; + break; + } + } + } + BUF_Release(pBuff); + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_DoMoveMerge(nLbn:%d)\n"), pLogVictim->wLbn)); + if (boolRes == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _DoMoveMerge failed!\n"))); + } + return boolRes; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _DoCopyMerge */ +/* DESCRIPTION */ +/* This function operates copy merge. (data --> log) */ +/* PARAMETERS */ +/* pLogVictim [IN] the pointer of log block context (victim) */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _DoCopyMerge is completed */ +/* FALSE32 */ +/* _DoCopyMerge is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_DoCopyMerge(LOGCxt *pLogVictim) +{ + UInt16 wD2FVbn, wL2DVbn; + BOOL32 boolRes = FALSE32; + UInt16 wPagesToCopy; + Buffer * pBuff; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_DoCopyMerge(nLbn:%d)\n"), pLogVictim->wLbn)); + + //WMR_ASSERT(pLogVictim->boolCopyMerge == TRUE32); + //WMR_ASSERT(pLogVictim->wFreePOffset == pLogVictim->wNumOfValidLP); + if ((pLogVictim->boolCopyMerge == FALSE32) || (pLogVictim->wFreePOffset != pLogVictim->wNumOfValidLP)) + { + return FALSE32; + } + + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuff == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed BUF_Get (line:%d)!\n"), __LINE__)); + return FALSE32; + } + + wD2FVbn = CONVERT_L2V(pLogVictim->wLbn); + + wL2DVbn = pLogVictim->wVbn; +#ifdef AND_COLLECT_STATISTICS + if (pLogVictim->wFreePOffset < PAGES_PER_SUBLK) + { + stFTLStatistics.ddwDoCopyMergeCnt2++; + } + else + { + stFTLStatistics.ddwDoCopyMergeCnt1++; + } +#endif + + /* copy rest pages from data to log */ + for (; pLogVictim->wFreePOffset < PAGES_PER_SUBLK; pLogVictim->wFreePOffset += wPagesToCopy) + { + BOOL32 boolReadRes; + UInt16 wLPOffsetIdx; + wPagesToCopy = WMR_MIN((PAGES_PER_SUBLK - pLogVictim->wFreePOffset), PAGES_PER_SIMPLE_MERGE_BUFFER); + // No need to count reads here, as this is the last read from the block before it is recycled + if (NULL != VFL_ReadMultiplePagesInVb) + { + boolReadRes = VFL_ReadMultiplePagesInVb(wD2FVbn, pLogVictim->wFreePOffset, wPagesToCopy, pstSimpleMergeDataBuffer, pstbaMultiplePagesWriteSpare, NULL, NULL, FALSE32); + } + else + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < wPagesToCopy; wLPOffsetIdx++) + { + pstadwScatteredReadVpn[wLPOffsetIdx] = GET_Vpn(wD2FVbn, pLogVictim->wFreePOffset + wLPOffsetIdx); + } + boolReadRes = VFL_ReadScatteredPagesInVb(pstadwScatteredReadVpn, wPagesToCopy, pstSimpleMergeDataBuffer, pstbaMultiplePagesWriteSpare, NULL, NULL, FALSE32, NULL); + } + if (TRUE32 == boolReadRes) + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < wPagesToCopy; wLPOffsetIdx++) + { + UInt8 * pbaTempSpare = &(pstbaMultiplePagesWriteSpare[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(GET_Vpn(pLogVictim->wLbn, (pLogVictim->wFreePOffset + wLPOffsetIdx)), pstFTLCxt->dwWriteAge, pbaTempSpare); + } + } + else + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < wPagesToCopy; wLPOffsetIdx++) + { + Int32 nRet; + UInt8 * pbaTempSpare = &(pstbaMultiplePagesWriteSpare[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(GET_Vpn(pLogVictim->wLbn, (pLogVictim->wFreePOffset + wLPOffsetIdx)), pstFTLCxt->dwWriteAge, pbaTempSpare); + pBuff->pData = &pstSimpleMergeDataBuffer[BYTES_PER_PAGE * wLPOffsetIdx]; + nRet = VFL_Read(GET_Vpn(wD2FVbn, (pLogVictim->wFreePOffset + wLPOffsetIdx)), pBuff, TRUE32, TRUE32, NULL, NULL, FALSE32); + if (nRet != VFL_SUCCESS && nRet != VFL_SUCCESS_CLEAN) + { + SET_FTL_ECC_MARK(pbaTempSpare); + } + } + } + /* check if this write contains the last page, if it does, mark as data */ + if ((pLogVictim->wFreePOffset + wLPOffsetIdx) == PAGES_PER_SUBLK) + { + SET_FTL_SPARE_TYPE(&(pstbaMultiplePagesWriteSpare[(wLPOffsetIdx - 1) * BYTES_PER_METADATA_RAW]), FTL_SPARE_TYPE_DATA); + } + if (VFL_WriteMultiplePagesInVb(GET_Vpn(wL2DVbn, pLogVictim->wFreePOffset), wPagesToCopy, pstSimpleMergeDataBuffer, pstbaMultiplePagesWriteSpare, TRUE32, FALSE32) == FALSE32) + { + break; + } + } + + if (pLogVictim->wFreePOffset < PAGES_PER_SUBLK) + { + pLogVictim->boolCopyMerge = FALSE32; + boolRes = _DoSimpleMerge(pLogVictim); + } + else + { + /* release data block to free block */ + if (_SetFreeVb(wD2FVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed _SetFreeVb(0x%X) (line:%d)!\n"), wD2FVbn, __LINE__)); + } + + /* modify map table */ + MODIFY_LB_MAP(pLogVictim->wLbn, wL2DVbn); + + MARK_LOG_AS_EMPTY(pLogVictim); + boolRes = TRUE32; + } + BUF_Release(pBuff); + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_DoCopyMerge(nLbn:%d)\n"), pLogVictim->wLbn)); + + return boolRes; +} + +/* + NAME + _DoSimpleMerge + DESCRIPTION + This function operates simple merge. (log & data --> free) + PARAMETERS + pLogVictim [IN] the pointer of log block context (victim) + RETURN VALUES + TRUE32 + _DoSimpleMerge is completed + FALSE32 + _DoSimpleMerge is failed + NOTES + */ + +static BOOL32 +_DoSimpleMerge(LOGCxt *pLogVictim) +{ + UInt16 wIdx, wLPOffsetIdx; + UInt16 wF2DVbn; + UInt8 bTrialIdx; + BOOL32 boolRes = FALSE32, boolCopyRes = FALSE32; + // use a different area of the spare buffer than the one used by _FTLRead that reads PAGES_PER_SIMPLE_MERGE_BUFFER pages + UInt8 *pabMultiSpareBuffer = &pstbaMultiplePagesWriteSpare[PAGES_PER_SIMPLE_MERGE_BUFFER * BYTES_PER_METADATA_RAW]; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_DoSimpleMerge(nLbn:%d)\n"), pLogVictim->wLbn)); + + // WMR_ASSERT(pLogVictim != NULL); + if (pLogVictim == NULL) + { + return FALSE32; + } + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwDoSimpleMergeCnt++; +#endif + + for (bTrialIdx = 0; bTrialIdx < 4; bTrialIdx++) + { + if (_GetFreeVb(&wF2DVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _GetFreeVb (line:%d)!\n"), __LINE__)); + return FALSE32; + } + pstFTLCxt->dwWriteAge++; + for (wIdx = 0; wIdx < PAGES_PER_SUBLK; wIdx += PAGES_PER_SIMPLE_MERGE_BUFFER) + { + if (_FTLRead(((((UInt32)pLogVictim->wLbn) * PAGES_PER_SUBLK) + (UInt32)wIdx), PAGES_PER_SIMPLE_MERGE_BUFFER, pstSimpleMergeDataBuffer) == FTL_SUCCESS) + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < PAGES_PER_SIMPLE_MERGE_BUFFER; wLPOffsetIdx++) + { + UInt8 * pbaTempSpare = &(pabMultiSpareBuffer[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(GET_Vpn(pLogVictim->wLbn, (wIdx + wLPOffsetIdx)), pstFTLCxt->dwWriteAge, pbaTempSpare); + } + } + else + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed calling _FTLRead(0x%X, 0x%X, 0x%X)(line:%d)\n"), + ((((UInt32)pLogVictim->wLbn) * PAGES_PER_SUBLK) + (UInt32)wIdx), PAGES_PER_SIMPLE_MERGE_BUFFER, pstSimpleMergeDataBuffer, __LINE__)); + for (wLPOffsetIdx = 0; wLPOffsetIdx < PAGES_PER_SIMPLE_MERGE_BUFFER; wLPOffsetIdx++) + { + UInt8 * pbaTempSpare = &(pabMultiSpareBuffer[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(GET_Vpn(pLogVictim->wLbn, (wIdx + wLPOffsetIdx)), pstFTLCxt->dwWriteAge, pbaTempSpare); + if (_FTLRead(((((UInt32)pLogVictim->wLbn) * PAGES_PER_SUBLK) + (UInt32)(wIdx + wLPOffsetIdx)), 1, &pstSimpleMergeDataBuffer[BYTES_PER_PAGE * wLPOffsetIdx]) != FTL_SUCCESS) + { + SET_FTL_ECC_MARK(pbaTempSpare); + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed calling _FTLRead(0x%X, 0x%X, 0x%X) (line:%d)\n"), + ((((UInt32)pLogVictim->wLbn) * PAGES_PER_SUBLK) + (UInt32)(wIdx + wLPOffsetIdx)), 1, &pstSimpleMergeDataBuffer[BYTES_PER_PAGE * wLPOffsetIdx], __LINE__)); + } + } + } + if ((wLPOffsetIdx + wIdx) == PAGES_PER_SUBLK) + { + SET_FTL_SPARE_TYPE(&(pabMultiSpareBuffer[(wLPOffsetIdx - 1) * BYTES_PER_METADATA_RAW]), FTL_SPARE_TYPE_DATA); + } + boolCopyRes = VFL_WriteMultiplePagesInVb(GET_Vpn(wF2DVbn, wIdx), PAGES_PER_SIMPLE_MERGE_BUFFER, pstSimpleMergeDataBuffer, pabMultiSpareBuffer, TRUE32, FALSE32); + if (boolCopyRes == FALSE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _DoSimpleMerge error writing to free page\n"))); + break; + } + } + if (boolCopyRes == TRUE32) + { + boolRes = TRUE32; + break; + } + else + { + if (_SetFreeVb(wF2DVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _DoSimpleMerge failed _SetFreeVb(0x%X) (line:%d)\n"), wF2DVbn, __LINE__)); + } + } + } + if (boolRes == TRUE32) + { + /* release log and data blocks */ + if (_SetFreeVb(pLogVictim->wVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _DoSimpleMerge failed _SetFreeVb(0x%X) (line:%d)\n"), pLogVictim->wVbn, __LINE__)); + } + MARK_LOG_AS_EMPTY(pLogVictim); + if (_SetFreeVb(CONVERT_L2V(pLogVictim->wLbn)) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _DoSimpleMerge failed _SetFreeVb(0x%X) (line:%d)\n"), CONVERT_L2V(pLogVictim->wLbn), __LINE__)); + } + /* modify map table */ + MODIFY_LB_MAP(pLogVictim->wLbn, wF2DVbn); + } + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_DoSimpleMerge(nLbn:%d)\n"), pLogVictim->wLbn)); + if (boolRes == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _DoSimpleMerge failed!\n"))); + } + return boolRes; +} +/* + NAME + _Merge + DESCRIPTION + This function select merge operation. + PARAMETERS + pLogVictim [IN] the pointer of log block context (victim) + RETURN VALUES + TRUE32 + _Merge is completed + FALSE32 + _Merge is failed + NOTES + */ +static BOOL32 +_Merge(LOGCxt *pLogVictim) +{ + UInt32 eMergeMethod = 0; + + enum + { + MERGE_SIMPLE, MERGE_COPY_SWAP, MERGE_MOVE + }; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_Merge()\n"))); + + if (_FTLMarkCxtNotValid() == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _Merge failed calling _FTLMarkCxtNotValid\n"))); + return FALSE32; + } + /* search victim log block if there is no victim */ + /* copy > simple (victim == NULL) */ + /* move > copy > simple (vicim != NULL) */ + if (pLogVictim == NULL) + { + UInt32 nMinMergeCost = 0xFFFFFFFF; + UInt32 nIdx; + + for (nIdx = 0; nIdx < LOG_SECTION_SIZE; nIdx++) + { + UInt32 nMergeCost, eMergeMethodTemp; + LOGCxt *pLog = GET_LOGCxt(nIdx); + + if (pLog->wVbn == LOG_EMPTY_SLOT) + { + continue; + } + + //WMR_ASSERT(pLog->wFreePOffset != 0); + //WMR_ASSERT(pLog->wNumOfValidLP != 0); + if ((pLog->wFreePOffset == 0) || (pLog->wNumOfValidLP == 0)) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _Merge error(line:%d)!\n"), __LINE__)); + return FALSE32; + } + + if (pLog->boolCopyMerge == TRUE32) + { + eMergeMethodTemp = MERGE_COPY_SWAP; + nMergeCost = pLog->dwLogAge; + } + else + { + eMergeMethodTemp = MERGE_SIMPLE; + nMergeCost = pLog->dwLogAge; + } + + if (nMergeCost < nMinMergeCost) + { + nMinMergeCost = nMergeCost; + eMergeMethod = eMergeMethodTemp; + pLogVictim = pLog; + } + else if (pLogVictim != NULL && + nMergeCost == nMinMergeCost && + pLog->wNumOfValidLP > pLogVictim->wNumOfValidLP) + { + nMinMergeCost = nMergeCost; + eMergeMethod = eMergeMethodTemp; + pLogVictim = pLog; + } + } + } + else + { + if (pLogVictim->wNumOfValidLP <= PAGES_PER_SUBLK / 2) + { + // note that the _DoMoveMerge function does not turn log to data even if the number of valid blocks is PAGES_PER_SUBLK + eMergeMethod = MERGE_MOVE; + } + else if (pLogVictim->boolCopyMerge == TRUE32) + { + eMergeMethod = MERGE_COPY_SWAP; + } + else + { + eMergeMethod = MERGE_SIMPLE; + } + } + + if (pLogVictim == NULL) + { + return FALSE32; + } + if (eMergeMethod == MERGE_MOVE) + { + if (_DoMoveMerge(pLogVictim) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _DoMoveMerge!\n"))); + return FALSE32; + } + } + else + { + if (eMergeMethod == MERGE_COPY_SWAP) + { + if (_DoCopyMerge(pLogVictim) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _DoCopyMerge!\n"))); + return FALSE32; + } + } + else + { + if (_DoSimpleMerge(pLogVictim) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _DoSimpleMerge!\n"))); + return FALSE32; + } + } + } + + pstFTLCxt->wWearLevelCounter++; + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --_Merge()\n"))); + + return TRUE32; +} +#endif // AND_READONLY + +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) +BOOL32 _ScanForFreeBlk(UInt16 wVBlk) +{ + UInt16 wIdx; + + for (wIdx = 0; wIdx < pstFTLCxt->wNumOfFreeVb; wIdx++) + { + UInt16 wIdxTemp = wIdx + pstFTLCxt->wFreeVbListTail; + + if (wIdxTemp >= FREE_SECTION_SIZE) + { + wIdxTemp -= FREE_SECTION_SIZE; + } + if (pstFTLCxt->awFreeVbList[wIdxTemp] == wVBlk) + { + return TRUE32; + } + } + return FALSE32; +} +// return values: +// FLASE32 - log block +// TRUE32 - potential data block +BOOL32 _CheckLogBlock(UInt16 wVbn) +{ + Int32 nVFLRet; + UInt16 wPageIdx; + Buffer * pBuff; + + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pBuff == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed BUF_Get (line:%d)!\n"), __LINE__)); + return FALSE32; + } + + for (wPageIdx = 0; wPageIdx < PAGES_PER_SUBLK; wPageIdx++) + { + UInt32 dwWrittenLpn; + nVFLRet = VFL_Read(GET_Vpn(wVbn, wPageIdx), pBuff, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (nVFLRet == VFL_SUCCESS) + { + _GetLOGCxtSpare(pBuff->pSpare, &dwWrittenLpn, NULL); + if ((dwWrittenLpn % PAGES_PER_SUBLK) != wPageIdx) + { + BUF_Release(pBuff); + return FALSE32; + } + } + } + BUF_Release(pBuff); + return TRUE32; +} +#endif //#if (defined(WMR_ENABLE_FTL_RECOVERY) && WMR_ENABLE_FTL_RECOVERY) + +/* this function sould be called if there are no valid context structures */ + +#define FTL_RESTORE_BLOCK_FULL 0 +#define FTL_RESTORE_BLOCK_0_IS_WRITTEN 1 +#define FTL_RESTORE_BLOCK_0_IS_EMPTY 2 +#define FTL_RESTORE_BLOCK_0_IS_INVALID 3 + +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) +BOOL32 +_FTLRestore(void) +{ + Buffer * pBuff; + BOOL32 boolRes = TRUE32; + FTLRestoreStruct * pFTLRestoreStruct = NULL; /* per virtual block (vb) mark logical block it contains */ + UInt16 wVBlkIdx, wLBlkIdx; + UInt16 wDataBlkCnt, wLogBlkCnt, wFreeBlkCnt; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; +#endif /* AND_COLLECT_STATISTICS */ + FTL_WRN_PRINT((TEXT("[FTL:WRN] Recovering NAND Data Structures - this will take some time!\n"))); + /* allocate a buffer to read pages from the nand */ + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuff == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] BUF_Get error (line:%d)!\n"), __LINE__)); + return FALSE32; + } + + /* instead of allocating, we now share with pstSimpleMergeDataBuffer (32KB) */ + pFTLRestoreStruct = (FTLRestoreStruct *) pstSimpleMergeDataBuffer; + + /* this function expects pFTLRestoreStruct to be initialized with 0xFF */ + WMR_MEMSET(pFTLRestoreStruct, 0xFF, FTL_AREA_SIZE * sizeof(FTLRestoreStruct)); + + /* init mapping in FTLCxt */ + WMR_MEMSET(pstFTLCxt->pawMapTable, 0xFF, (sizeof(UInt16) * USER_SUBLKS_TOTAL)); /* clear the map table */ + + // init the refresh block information + WMR_MEMSET(pstFTLCxt->aFTLReadRefreshList, 0xFF, + (sizeof(FTLReadRefreshStruct) * FTL_READ_REFRESH_LIST_SIZE)); + pstFTLCxt->dwRefreshListIdx = 0; + + /* init the log structures */ + for (wLBlkIdx = 0; wLBlkIdx < (LOG_SECTION_SIZE + 1); wLBlkIdx++) + { + _InitLogCxt(&pstFTLCxt->aLOGCxtTable[wLBlkIdx]); + pstFTLCxt->aLOGCxtTable[wLBlkIdx].wLbn = pstFTLCxt->aLOGCxtTable[wLBlkIdx].wVbn = LOG_EMPTY_SLOT; + } + +#ifndef AND_READONLY + /* init the ec cache */ + WMR_MEMSET(pstFTLCxt->pawECCacheTable, 0, (FTL_AREA_SIZE * sizeof(UInt16))); /* clear the ec cache table */ + + /* init the rc cache */ + WMR_MEMSET(pstFTLCxt->pawRCCacheTable, 0, (FTL_AREA_SIZE * sizeof(UInt16))); /* clear the ec cache table */ + + /* init the ec and rc pointers */ + for (wLBlkIdx = 0; wLBlkIdx < MAX_NUM_OF_EC_TABLES; wLBlkIdx++) + { + pstFTLCxt->adwECTablePtrs[wLBlkIdx] = FTL_TABLE_PTR_INVALID_VALUE; /* 0 might be a valid value */ + pstFTLCxt->adwRCTablePtrs[wLBlkIdx] = FTL_TABLE_PTR_INVALID_VALUE; /* 0 might be a valid value */ + } +#endif /* #ifndef AND_READONLY */ + + // init the stat pointers + pstFTLCxt->adwStatPtrs[0] = FTL_TABLE_PTR_INVALID_VALUE; + pstFTLCxt->adwStatPtrs[1] = FTL_TABLE_PTR_INVALID_VALUE; + + pstFTLCxt->dwWriteAge = 0; + pstFTLCxt->dwAge = 0xFFFFFFFF; + + /* mark the cxt blocks */ + WMR_MEMCPY(pstFTLCxt->awMapCxtVbn, VFL_GetFTLCxtVbn(), (sizeof(UInt16) * FTL_CXT_SECTION_SIZE)); + for (wLBlkIdx = 0; wLBlkIdx < FTL_CXT_SECTION_SIZE; wLBlkIdx++) + { + Int32 nVFLRet; + nVFLRet = VFL_Read(GET_Vpn(pstFTLCxt->awMapCxtVbn[wLBlkIdx], 0), pBuff, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (nVFLRet == VFL_SUCCESS && FTL_SPARE_IS_CXT_MARK(GET_FTL_SPARE_TYPE(pBuff->pSpare))) + { + _GetFTLCxtSpare(&(pFTLRestoreStruct[pstFTLCxt->awMapCxtVbn[wLBlkIdx]].dwWriteAge), NULL, NULL, pBuff->pSpare); + pstFTLCxt->dwAge = WMR_MIN(pFTLRestoreStruct[pstFTLCxt->awMapCxtVbn[wLBlkIdx]].dwWriteAge, pstFTLCxt->dwAge); + } + pFTLRestoreStruct[pstFTLCxt->awMapCxtVbn[wLBlkIdx]].bSpareType = FTL_SPARE_TYPE_CXT; + if (pstFTLCxt->dwAge == pFTLRestoreStruct[pstFTLCxt->awMapCxtVbn[wLBlkIdx]].dwWriteAge) + { + pstFTLCxt->dwCurrMapCxtPage = GET_Vpn(pstFTLCxt->awMapCxtVbn[wLBlkIdx], (PAGES_PER_SUBLK - 1)); + } + } + + /* search blocks that belong to the FTL layer look for data and log block types */ + for (wVBlkIdx = 0; wVBlkIdx < FTL_AREA_SIZE; wVBlkIdx++) + { + Int32 nVFLRet; + + if (pFTLRestoreStruct[wVBlkIdx].bSpareType == FTL_SPARE_TYPE_CXT) + { + continue; + } + /* read the last page of the VB (look for full logs and data blocks) */ + WMR_MEMSET(pBuff->pSpare, 0xFF, BYTES_PER_METADATA_RAW); + nVFLRet = VFL_Read(GET_Vpn(wVBlkIdx, (PAGES_PER_SUBLK - 1)), pBuff, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (nVFLRet == VFL_SUCCESS) + { + /* sort the VBs by the type byte */ + switch (GET_FTL_SPARE_TYPE(pBuff->pSpare)) + { + /* full logs and data blocks */ + case FTL_SPARE_TYPE_LOG: + case FTL_SPARE_TYPE_DATA: + { + UInt32 dwLbn, dwLpn; + _GetLOGCxtSpare(pBuff->pSpare, &dwLpn, &(pFTLRestoreStruct[wVBlkIdx].dwWriteAge)); + dwLbn = (dwLpn / PAGES_PER_SUBLK); + if (IS_LBN_IN_RANGE((UInt16)dwLbn)) + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = GET_FTL_SPARE_TYPE(pBuff->pSpare); + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_FULL; + pFTLRestoreStruct[wVBlkIdx].wLbn = (UInt16)dwLbn; + /* if this is a data block map it */ + if (pFTLRestoreStruct[wVBlkIdx].bSpareType == FTL_SPARE_TYPE_DATA) + { + UInt16 wLbn; + wLbn = pFTLRestoreStruct[wVBlkIdx].wLbn; + + if (pstFTLCxt->pawMapTable[wLbn] == 0xFFFF) + { + /* this is the first data block copy for this logical block - map it */ + MODIFY_LB_MAP(wLbn, wVBlkIdx); + } + else + { + UInt16 wOldVbn; + wOldVbn = pstFTLCxt->pawMapTable[wLbn]; + /* this is not the only data block copy for this logical block - map it only if it is newer than the previous version */ + if (pFTLRestoreStruct[wVBlkIdx].dwWriteAge > pFTLRestoreStruct[wOldVbn].dwWriteAge) + { + MODIFY_LB_MAP(wLbn, wVBlkIdx); + } + else + { + wOldVbn = wVBlkIdx; + } + pFTLRestoreStruct[wOldVbn].bSpareType = FTL_SPARE_TYPE_FREE; /* mark the older block as free */ + } + } + if (pstFTLCxt->dwWriteAge < pFTLRestoreStruct[wVBlkIdx].dwWriteAge) + { + pstFTLCxt->dwWriteAge = pFTLRestoreStruct[wVBlkIdx].dwWriteAge; + } + } + else + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore found block (#%d) with wLbn %d!\n"), wVBlkIdx, dwLbn)); + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_WRITTEN; + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + } + break; + } + + /* FTLCxt types */ + case FTL_SPARE_TYPE_CXT_INDEX: + case FTL_SPARE_TYPE_CXT_MAP_TABLE: + case FTL_SPARE_TYPE_CXT_EC_TABLE: + case FTL_SPARE_TYPE_CXT_RC_TABLE: + case FTL_SPARE_TYPE_CXT_LOGCXT_MAP: + case FTL_SPARE_TYPE_CXT_INVALID: + case FTL_SPARE_TYPE_CXT_STAT: + { + /* mark the type of the block as free - real FTL_SPARE_TYPE_CXT will be marked later */ + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_FULL; + _GetFTLCxtSpare(&(pFTLRestoreStruct[wVBlkIdx].dwWriteAge), NULL, NULL, pBuff->pSpare); + break; + } + + default: + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore found block (#%d) with unidentified spare(page is 0x%X) spare is 0x%X !\n"), + wVBlkIdx, (PAGES_PER_SUBLK - 1), GET_FTL_SPARE_TYPE(pBuff->pSpare))); + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_WRITTEN; + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + } + } + else + { + /* if the last page is not written */ + WMR_MEMSET(pBuff->pSpare, 0xFF, BYTES_PER_METADATA_RAW); + nVFLRet = VFL_Read(GET_Vpn(wVBlkIdx, 0), pBuff, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (nVFLRet == VFL_SUCCESS) + { + /* this is not a full page - it should be either CXT or LOG */ + switch (GET_FTL_SPARE_TYPE(pBuff->pSpare)) + { + case FTL_SPARE_TYPE_LOG: + { + UInt32 dwLbn, dwLpn; + _GetLOGCxtSpare(pBuff->pSpare, &dwLpn, &(pFTLRestoreStruct[wVBlkIdx].dwWriteAge)); + dwLbn = (dwLpn / PAGES_PER_SUBLK); + if (IS_LBN_IN_RANGE((UInt16)dwLbn)) + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = GET_FTL_SPARE_TYPE(pBuff->pSpare); + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_WRITTEN; + pFTLRestoreStruct[wVBlkIdx].wLbn = (UInt16)dwLbn; + if (pstFTLCxt->dwWriteAge < pFTLRestoreStruct[wVBlkIdx].dwWriteAge) + { + pstFTLCxt->dwWriteAge = pFTLRestoreStruct[wVBlkIdx].dwWriteAge; + } + } + else + { + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_WRITTEN; + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + } + break; + } + + case FTL_SPARE_TYPE_CXT_INDEX: + case FTL_SPARE_TYPE_CXT_MAP_TABLE: + case FTL_SPARE_TYPE_CXT_EC_TABLE: + case FTL_SPARE_TYPE_CXT_RC_TABLE: + case FTL_SPARE_TYPE_CXT_LOGCXT_MAP: + case FTL_SPARE_TYPE_CXT_INVALID: + case FTL_SPARE_TYPE_CXT_STAT: + { + /* mark the type of the block as free - real FTL_SPARE_TYPE_CXT will be marked later */ + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_WRITTEN; + _GetFTLCxtSpare(&(pFTLRestoreStruct[wVBlkIdx].dwWriteAge), NULL, NULL, pBuff->pSpare); + break; + } + + default: + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore found block (#%d) with unidentified spare(page is 0) 0x%X!\n"), + wVBlkIdx, GET_FTL_SPARE_TYPE(pBuff->pSpare))); + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_WRITTEN; + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + break; + } + } + } + else if (nVFLRet == VFL_SUCCESS_CLEAN) + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_EMPTY; // the virtual block is blank + } + } + // this is a simple solution - though we might loose a lot of info this way - + if (nVFLRet != VFL_SUCCESS_CLEAN && nVFLRet != VFL_SUCCESS) + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + pFTLRestoreStruct[wVBlkIdx].bIsBlkFull = FTL_RESTORE_BLOCK_0_IS_WRITTEN; + } + } + + /* + at this point - any data block that has been written and taken off the log list should be in the map. + for the rest we can assign free blocks. + */ + + /* mark any log that is older than the matching data block as free and put relevant logs in the FTLMeta structure */ + for (wVBlkIdx = 0; wVBlkIdx < FTL_AREA_SIZE; wVBlkIdx++) + { + if (pFTLRestoreStruct[wVBlkIdx].bSpareType == FTL_SPARE_TYPE_LOG) + { + /* check if the matching data block dwWriteAge is bigger than this log */ + UInt32 dwWriteAge = 0; + wLBlkIdx = pFTLRestoreStruct[wVBlkIdx].wLbn; + if (pstFTLCxt->pawMapTable[wLBlkIdx] != 0xFFFF) + { + dwWriteAge = pFTLRestoreStruct[pstFTLCxt->pawMapTable[wLBlkIdx]].dwWriteAge; + } + else + { + // take a look at the log blocks - if it is organized as data block mark it as one... + if (_CheckLogBlock(wVBlkIdx) == TRUE32) + { + // this can be marked as a data block + MODIFY_LB_MAP(wLBlkIdx, wVBlkIdx); + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_DATA; + continue; + } + } + if (pFTLRestoreStruct[wVBlkIdx].dwWriteAge < dwWriteAge) + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + } + else + { + UInt32 dwLogIdx; + /* this is possibly real log - check for log with matching lbn */ + for (dwLogIdx = 0; dwLogIdx < (LOG_SECTION_SIZE + 1); dwLogIdx++) + { + BOOL32 boolUpdateLog = FALSE32; + /* if we got to a log with lbn set to 0xFFFF than there is no log with this lbn */ + if (pstFTLCxt->aLOGCxtTable[dwLogIdx].wLbn == 0xFFFF) + { + boolUpdateLog = TRUE32; + } + else if (pstFTLCxt->aLOGCxtTable[dwLogIdx].wLbn == pFTLRestoreStruct[wVBlkIdx].wLbn) + { + UInt16 wOldVbn = pstFTLCxt->aLOGCxtTable[dwLogIdx].wVbn; + + if (pFTLRestoreStruct[wVBlkIdx].dwWriteAge == pstFTLCxt->dwWriteAge || pstFTLCxt->aLOGCxtTable[dwLogIdx].dwLogAge == pstFTLCxt->dwWriteAge) + { + LOGCxt * pLOGCxtOld; + LOGCxt * pLOGCxtNew; + UInt16 wPageIdx; + /* this is possibly a power failure issue */ + FTL_EXTRA_LOG_CXT->dwLogAge = pFTLRestoreStruct[wVBlkIdx].dwWriteAge; + FTL_EXTRA_LOG_CXT->wLbn = pFTLRestoreStruct[wVBlkIdx].wLbn; + FTL_EXTRA_LOG_CXT->wVbn = (UInt16)wVBlkIdx; + _RecoverLOGCxtInfo(FTL_EXTRA_LOG_CXT); + _RecoverLOGCxtInfo(&(pstFTLCxt->aLOGCxtTable[dwLogIdx])); + /* now we should have the # of valid pages set for both log versions */ + if (pFTLRestoreStruct[wVBlkIdx].dwWriteAge == pstFTLCxt->dwWriteAge) + { + pLOGCxtNew = FTL_EXTRA_LOG_CXT; + pLOGCxtOld = &(pstFTLCxt->aLOGCxtTable[dwLogIdx]); + } + else + { + pLOGCxtOld = FTL_EXTRA_LOG_CXT; + pLOGCxtNew = &(pstFTLCxt->aLOGCxtTable[dwLogIdx]); + } + /* verify that the newer version contains at least all the pages that were in the old version */ + for (wPageIdx = 0; wPageIdx < PAGES_PER_SUBLK; wPageIdx++) + { + if (pLOGCxtOld->paPOffsetL2P[wPageIdx] != 0xFFFF && pLOGCxtNew->paPOffsetL2P[wPageIdx] == 0xFFFF) + { + break; + } + } + /* check if the newer version is valid */ + if (wPageIdx == PAGES_PER_SUBLK) + { + /* the newer log is valid get rid of the old one */ + if (pLOGCxtOld->dwLogAge == pFTLRestoreStruct[wVBlkIdx].dwWriteAge) + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + } + else + { + boolUpdateLog = TRUE32; + pFTLRestoreStruct[wOldVbn].bSpareType = FTL_SPARE_TYPE_FREE; + } + } + else + { + /* the newer log is invalid get rid of it */ + if (pLOGCxtNew->dwLogAge == pFTLRestoreStruct[wVBlkIdx].dwWriteAge) + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + } + else + { + boolUpdateLog = TRUE32; + pFTLRestoreStruct[wOldVbn].bSpareType = FTL_SPARE_TYPE_FREE; + } + } + /* clean FTL_EXTRA_LOG_CXT */ + FTL_EXTRA_LOG_CXT->wVbn = 0xFFFF; + FTL_EXTRA_LOG_CXT->wLbn = 0xFFFF; + _InitLogCxt(FTL_EXTRA_LOG_CXT); + _InitLogCxt(&(pstFTLCxt->aLOGCxtTable[dwLogIdx])); + } + else if (pFTLRestoreStruct[wOldVbn].dwWriteAge < pFTLRestoreStruct[wVBlkIdx].dwWriteAge) + { + boolUpdateLog = TRUE32; + pFTLRestoreStruct[wOldVbn].bSpareType = FTL_SPARE_TYPE_FREE; + } + else + { + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_FREE; + } + if (boolUpdateLog == FALSE32) + { + break; + } + } + + if (boolUpdateLog == TRUE32) + { + pstFTLCxt->aLOGCxtTable[dwLogIdx].dwLogAge = pFTLRestoreStruct[wVBlkIdx].dwWriteAge; + pstFTLCxt->aLOGCxtTable[dwLogIdx].wLbn = pFTLRestoreStruct[wVBlkIdx].wLbn; + pstFTLCxt->aLOGCxtTable[dwLogIdx].wVbn = (UInt16)wVBlkIdx; + break; + } + } + } + } + } + + if (pstFTLCxt->aLOGCxtTable[LOG_SECTION_SIZE].wVbn != 0xFFFF) + { + UInt16 wLogIdx; + // case we have all the logs full + one in the middle of a move... + // + // look for a log with age matching the age in FTLCxt - mark it as free and copy the spare log to to it + + for (wLogIdx = 0; wLogIdx < (LOG_SECTION_SIZE + 1); wLogIdx++) + { + if (pstFTLCxt->aLOGCxtTable[wLogIdx].dwLogAge == pstFTLCxt->dwWriteAge) + { + break; + } + } + + // if we did not find the right LOG fail _FTLRestore + if (wLogIdx == (LOG_SECTION_SIZE + 1)) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - # of LOG blocks > LOG_SECTION_SIZE failing _FTLRestore (line:%d)\n"), __LINE__)); + return FALSE32; + } + + pFTLRestoreStruct[pstFTLCxt->aLOGCxtTable[wLogIdx].wVbn].bSpareType = FTL_SPARE_TYPE_FREE; + _CopyLOGCxt(&pstFTLCxt->aLOGCxtTable[wLogIdx], FTL_EXTRA_LOG_CXT); + } + /* now we have the the data blocks in the map and log indexes - next recover map locations that point to empty blocks */ + wVBlkIdx = 0; /* check if we need to start elsewhere to leave space for the FTLCxt info */ + for (wLBlkIdx = 0; (wLBlkIdx < USER_SUBLKS_TOTAL) && (wVBlkIdx < FTL_AREA_SIZE); wLBlkIdx++) + { + /* check if the map location is free */ + if (pstFTLCxt->pawMapTable[wLBlkIdx] == 0xFFFF) + { + do + { + if (pFTLRestoreStruct[wVBlkIdx].bSpareType == FTL_SPARE_TYPE_FREE) + { + MODIFY_LB_MAP(wLBlkIdx, wVBlkIdx); + pFTLRestoreStruct[wVBlkIdx].wLbn = wLBlkIdx; + pFTLRestoreStruct[wVBlkIdx].bSpareType = FTL_SPARE_TYPE_DATA; + /* erase blocks that suppose to be empty - case we use blocks that were partially erased or had bad info */ +#ifndef AND_READONLY + if (FTL_SUCCESS != _EraseAndMarkEC(wVBlkIdx)) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - failed EraseAndMarkEC in spare pool (line:%d)\n"), __LINE__)); + return FALSE32; + } +#endif + wVBlkIdx++; + break; + } + wVBlkIdx++; + } + while (wVBlkIdx < FTL_AREA_SIZE); + } + } + + /* last - recover the free vb */ + { + UInt16 wLogIdx, wFreeIdx; + UInt16 wFreeVbCounter; + for (wLogIdx = 0; wLogIdx < LOG_SECTION_SIZE; wLogIdx++) + { + if (pstFTLCxt->aLOGCxtTable[wLogIdx].wLbn == 0xFFFF) + { + break; + } + } + + wFreeVbCounter = 0; + wVBlkIdx = 0; + wFreeIdx = wLogIdx; + /* NirW - write the below code again to make it clearer */ + for (; (wFreeIdx < FREE_SECTION_SIZE) && (wVBlkIdx < FTL_AREA_SIZE); wFreeIdx++) + { + do + { + if (pFTLRestoreStruct[wVBlkIdx].bSpareType == FTL_SPARE_TYPE_FREE) + { + pstFTLCxt->awFreeVbList[wFreeIdx] = wVBlkIdx; + wFreeVbCounter++; + wVBlkIdx++; + break; + } + wVBlkIdx++; + } + while (wVBlkIdx < FTL_AREA_SIZE); + } + if ((wFreeVbCounter + wLogIdx) != FREE_SECTION_SIZE) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - not all free vb were located - disk is heading toward corruptions!!!\n"))); + return FALSE32; + } + /* mark the rest */ + for (wLogIdx = 0; wLogIdx < (FREE_SECTION_SIZE - wFreeVbCounter); wLogIdx++) + { + pstFTLCxt->awFreeVbList[wLogIdx] = 0xFFFF; + } + pstFTLCxt->wNumOfFreeVb = wFreeVbCounter; + pstFTLCxt->wFreeVbListTail = FREE_SECTION_SIZE - wFreeVbCounter; + } + + /* count!!! - go over the map table and make sure we have everything covered */ + for (wLBlkIdx = 0; wLBlkIdx < USER_SUBLKS_TOTAL; wLBlkIdx++) + { + if (pstFTLCxt->pawMapTable[wLBlkIdx] >= FTL_AREA_SIZE) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - pstFTLCxt->pawMapTable[0x%X] = 0x%X - restore is about to fail (line:%d)!!!\n"), wLBlkIdx, pstFTLCxt->pawMapTable[wLBlkIdx], __LINE__)); + boolRes = FALSE32; + } + else if (pFTLRestoreStruct[pstFTLCxt->pawMapTable[wLBlkIdx]].wLbn != wLBlkIdx) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - pFTLRestoreStruct[pstFTLCxt->pawMapTable[0x%X]].wLbn = 0x%X\n"), + wLBlkIdx, pFTLRestoreStruct[pstFTLCxt->pawMapTable[wLBlkIdx]].wLbn)); + FTL_ERR_PRINT((TEXT("[FTL:ERR] pstFTLCxt->pawMapTable[0x%X] = 0x%X - restore is about to fail (line:%d)!!!\n"), + wLBlkIdx, pstFTLCxt->pawMapTable[wLBlkIdx], __LINE__)); + boolRes = FALSE32; + } + } + + /* count!!! - go over the VBs and make sure we have everything covered */ + wDataBlkCnt = 0, wLogBlkCnt = 0, wFreeBlkCnt = 0; + for (wVBlkIdx = 0; (boolRes == TRUE32) && (wVBlkIdx < FTL_AREA_SIZE); wVBlkIdx++) + { + switch (pFTLRestoreStruct[wVBlkIdx].bSpareType) + { + case FTL_SPARE_TYPE_FREE: + wFreeBlkCnt++; + if (_ScanForFreeBlk(wVBlkIdx) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - _ScanForFreeBlk(0x%X) failed - restore is about to fail (line:%d)!!!\n"), wVBlkIdx, __LINE__)); + boolRes = FALSE32; + } + break; + + case FTL_SPARE_TYPE_LOG: + { + LOGCxt * pLOGCxt; + wLogBlkCnt++; + pLOGCxt = _ScanLogSection(pFTLRestoreStruct[wVBlkIdx].wLbn); + if (pLOGCxt == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - _ScanLogSection(0x%X) failed - restore is about to fail (line:%d)!!!\n"), wVBlkIdx, __LINE__)); + boolRes = FALSE32; + } + else if (pLOGCxt->wVbn != wVBlkIdx) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - _ScanLogSection(0x%X) failed - restore is about to fail (line:%d)!!!\n"), wVBlkIdx, __LINE__)); + boolRes = FALSE32; + } + break; + } + + case FTL_SPARE_TYPE_DATA: + { + wDataBlkCnt++; + if (!IS_LBN_IN_RANGE(pFTLRestoreStruct[wVBlkIdx].wLbn)) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - IS_LBN_IN_RANGE failed - pFTLRestoreStruct[0x%X].wLbn = 0x%X restore is about to fail (line:%d)!!!\n"), wVBlkIdx, pFTLRestoreStruct[wVBlkIdx].wLbn, __LINE__)); + boolRes = FALSE32; + } + else if (pstFTLCxt->pawMapTable[pFTLRestoreStruct[wVBlkIdx].wLbn] != wVBlkIdx) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - IS_LBN_IN_RANGE failed - pstFTLCxt->pawMapTable[pFTLRestoreStruct[0x%X].wLbn] = 0x%X .Lbn is 0x%X restore is about to fail (line:%d)!!!\n"), + wVBlkIdx, pstFTLCxt->pawMapTable[pFTLRestoreStruct[wVBlkIdx].wLbn], pFTLRestoreStruct[wVBlkIdx].wLbn, __LINE__)); + boolRes = FALSE32; + } + break; + } + + case FTL_SPARE_TYPE_CXT: + break; + + default: + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - pFTLRestoreStruct[0x%X].bSpareType = 0x%X (unknown) - restore is about to fail (line:%d)!!!\n"), wVBlkIdx, pFTLRestoreStruct[wVBlkIdx].bSpareType, __LINE__)); + boolRes = FALSE32; + break; + } + } + if (wDataBlkCnt != USER_SUBLKS_TOTAL || wFreeBlkCnt != pstFTLCxt->wNumOfFreeVb || + wLogBlkCnt != (FREE_SECTION_SIZE - pstFTLCxt->wNumOfFreeVb)) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - wDataBlkCnt = 0x%X, wFreeBlkCnt = 0x%X\n"), wDataBlkCnt, wFreeBlkCnt)); + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore - pstFTLCxt->wNumOfFreeVb = 0x%X, wLogBlkCnt = 0x%X - restore is about to fail (line:%d)!!!\n"), pstFTLCxt->wNumOfFreeVb, wLogBlkCnt, __LINE__)); + boolRes = FALSE32; + } + + /* look for the latest FTLCxt structure to retrieve EC information */ + { + UInt16 awSortedCxtVBlk[FTL_CXT_SECTION_SIZE]; /* to be sorted by age */ + UInt16 wTempVBlkIdx1, wTempVBlkIdx2 = 0, wECFoundCounter, wRCFoundCounter, wStatFoundCounter; + + for (wTempVBlkIdx1 = 0; wTempVBlkIdx1 < FTL_CXT_SECTION_SIZE; wTempVBlkIdx1++) + { + if (pstFTLCxt->dwCurrMapCxtPage == GET_Vpn(pstFTLCxt->awMapCxtVbn[wTempVBlkIdx1], (PAGES_PER_SUBLK - 1))) + { + wTempVBlkIdx2 = wTempVBlkIdx1; + break; + } + } + wTempVBlkIdx2 += FTL_CXT_SECTION_SIZE; + for (wTempVBlkIdx1 = 0; wTempVBlkIdx1 < FTL_CXT_SECTION_SIZE; wTempVBlkIdx1++) + { + awSortedCxtVBlk[wTempVBlkIdx1] = pstFTLCxt->awMapCxtVbn[((wTempVBlkIdx2 - wTempVBlkIdx1) % FTL_CXT_SECTION_SIZE)]; + } + + /* 0 is the latest cxt info */ + wECFoundCounter = 0; + wRCFoundCounter = 0; + wStatFoundCounter = 0; + for (wTempVBlkIdx1 = 0; (wTempVBlkIdx1 < FTL_CXT_SECTION_SIZE) && ((wECFoundCounter < FTL_NUM_PAGES_PER_EC_TABLE) || (wRCFoundCounter < FTL_NUM_PAGES_PER_RC_TABLE) || (wStatFoundCounter < 1)); wTempVBlkIdx1++) + { + for (wTempVBlkIdx2 = PAGES_PER_SUBLK; (wTempVBlkIdx2 != 0) && ((wECFoundCounter < FTL_NUM_PAGES_PER_EC_TABLE) || (wRCFoundCounter < FTL_NUM_PAGES_PER_RC_TABLE) || (wStatFoundCounter < 1));) + { + Int32 nVFLRet; + + wTempVBlkIdx2--; + + nVFLRet = VFL_Read(GET_Vpn(awSortedCxtVBlk[wTempVBlkIdx1], wTempVBlkIdx2), pBuff, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (nVFLRet == VFL_SUCCESS) + { + if (FTL_SPARE_IS_CXT_MARK(GET_FTL_SPARE_TYPE(pBuff->pSpare))) + { + UInt16 wSpareIndex; + UInt32 dwECSpareAge; + _GetFTLCxtSpare(&dwECSpareAge, NULL, &wSpareIndex, pBuff->pSpare); + if (pstFTLCxt->dwAge > dwECSpareAge) + { + pstFTLCxt->dwAge = dwECSpareAge; + /* we assume this is the last page written - to be on the safe side we will write the next page in a different block */ + } + if (GET_FTL_SPARE_TYPE(pBuff->pSpare) == FTL_SPARE_TYPE_CXT_EC_TABLE && pstFTLCxt->adwECTablePtrs[wSpareIndex] == FTL_TABLE_PTR_INVALID_VALUE) + { +#ifndef AND_READONLY + UInt16 wBytesToCopy; + wECFoundCounter++; + pstFTLCxt->adwECTablePtrs[wSpareIndex] = GET_Vpn(awSortedCxtVBlk[wTempVBlkIdx1], wTempVBlkIdx2); + wBytesToCopy = WMR_MIN(((sizeof(UInt16) * FTL_AREA_SIZE) - (wSpareIndex * BYTES_PER_PAGE)), BYTES_PER_PAGE); + WMR_MEMCPY(&(pstFTLCxt->pawECCacheTable[(wSpareIndex * BYTES_PER_PAGE) / sizeof(UInt16)]), pBuff->pData, wBytesToCopy); +#endif /* #ifndef AND_READONLY */ + } + else if (GET_FTL_SPARE_TYPE(pBuff->pSpare) == FTL_SPARE_TYPE_CXT_RC_TABLE && pstFTLCxt->adwRCTablePtrs[wSpareIndex] == FTL_TABLE_PTR_INVALID_VALUE) + { +#ifndef AND_READONLY + UInt16 wBytesToCopy; + wRCFoundCounter++; + pstFTLCxt->adwRCTablePtrs[wSpareIndex] = GET_Vpn(awSortedCxtVBlk[wTempVBlkIdx1], wTempVBlkIdx2); + wBytesToCopy = WMR_MIN(((sizeof(UInt16) * FTL_AREA_SIZE) - (wSpareIndex * BYTES_PER_PAGE)), BYTES_PER_PAGE); + WMR_MEMCPY(&(pstFTLCxt->pawRCCacheTable[(wSpareIndex * BYTES_PER_PAGE) / sizeof(UInt16)]), pBuff->pData, wBytesToCopy); +#endif /* #ifndef AND_READONLY */ + } + else if (GET_FTL_SPARE_TYPE(pBuff->pSpare) == FTL_SPARE_TYPE_CXT_STAT && pstFTLCxt->adwStatPtrs[0] == FTL_TABLE_PTR_INVALID_VALUE && wSpareIndex == 0) + { +#ifdef AND_COLLECT_STATISTICS + _FTLSetStatisticsFromCxt(pBuff->pData); +#endif // AND_COLLECT_STATISTICS + wStatFoundCounter++; + pstFTLCxt->adwStatPtrs[0] = FTL_TABLE_PTR_INVALID_VALUE; + } + } + } + } + } +#ifndef AND_READONLY + /* check that we found all the EC pointers */ + if (wECFoundCounter != FTL_NUM_PAGES_PER_EC_TABLE) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _FTLRestore - lost part of the EC Table\n"))); + } + if (wRCFoundCounter != FTL_NUM_PAGES_PER_RC_TABLE) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _FTLRestore - lost part of the RC Table\n"))); + } + if (wStatFoundCounter != 1) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _FTLRestore - lost part of the Stat information\n"))); + } +#endif // AND_READONLY + } + +#ifndef AND_READONLY + { + UInt16 wIdx; + for (wIdx = 0; wIdx < pstFTLCxt->wNumOfFreeVb; wIdx++) + { + UInt16 wIdxTemp = wIdx + pstFTLCxt->wFreeVbListTail; + + if (wIdxTemp >= FREE_SECTION_SIZE) + { + wIdxTemp -= FREE_SECTION_SIZE; + } + + if (_EraseAndMarkEC(pstFTLCxt->awFreeVbList[wIdxTemp]) != VFL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRestore failed _EraseAndMarkEC(0x%X) (line:%d)\n"), pstFTLCxt->awFreeVbList[wIdxTemp], __LINE__)); + } + } + } +#endif + pstFTLCxt->wWearLevelCounter = 0; + pstFTLCxt->dwReadsSinceLastRefreshMark = 0; + + if (boolRes == TRUE32) + { + boolRes = _MakeLogMap(); + } + + // zero-init as if this buffer came from WMR_MALLOC + WMR_MEMSET(pFTLRestoreStruct, 0, FTL_AREA_SIZE * sizeof(FTLRestoreStruct)); + BUF_Release(pBuff); + if (boolRes == TRUE32) + { + pstFTLCxt->boolFlashCxtIsValid = FALSE32; +#ifndef AND_READONLY + if (FTL_ShutdownNotify(FALSE32) == FALSE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] Failure running FTL_ShutdownNotify after _FTLRestore!\n"))); + } +#endif + } + FTL_WRN_PRINT((TEXT("[FTL:WRN] _FTLRestore OK!\n"))); + return boolRes; +} +#endif // #if (defined(WMR_ENABLE_FTL_RECOVERY) && WMR_ENABLE_FTL_RECOVERY) + +/* + + NAME + FTL_Open + DESCRIPTION + This function loads ftl context & initialize log context. + PARAMETERS + pTotalPages [OUT] the count of pages which user can use. + pdwPageSize [OUT] page size in bytes. + RETURN VALUES + FTL_SUCCESS + FTL_Open is completed + FTL_CRITICAL_ERROR + FTL_Open is failed + NOTES + Exports native page size as file system's sector size (LBA). + H file with the function name uses sectors rather than pages in + paramter names. + + */ +static Int32 +FTL_Open(UInt32 *pTotalPages, UInt32 * pdwPageSize, BOOL32 nandFullRestore, BOOL32 justFormatted, UInt32 dwMinorVer, UInt32 dwOptions) +{ + FTL_LOG_PRINT((TEXT("[FTL: IN] ++FTL_Open()\n"))); + + if (_LoadFTLCxt() == FALSE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] Failure running _LoadFTLCxt!\n"))); +#ifdef AND_USE_NOTIFY + { + LowFuncTbl *pLowFuncTbl; + + pLowFuncTbl = FIL_GetFuncTbl(); + pLowFuncTbl->Notify(AND_NOTIFY_RECOVER); + } +#endif /* AND_USE_NOTIFY */ +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) + if (_FTLRestore() == FALSE32) + { + /* Always release all buffers before returning to the extrnal caller */ + BUF_ReleaseAllBuffers(); + return FTL_CRITICAL_ERROR; + } +#else + FTL_ERR_PRINT((TEXT("[FTL:ERR] Application does not contain FTL_Restore code. Run debug bootloader.\n"))); + return FTL_CRITICAL_ERROR; +#endif // #if (defined(WMR_ENABLE_FTL_RECOVERY) && WMR_ENABLE_FTL_RECOVERY) + } + + *pTotalPages = USER_PAGES_TOTAL; + *pdwPageSize = BYTES_PER_PAGE; + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --FTL_Open()\n"))); + /* Always release all buffers before returning to the extrnal caller */ + BUF_ReleaseAllBuffers(); + return FTL_SUCCESS; +} + +/* + NAME + FTL_Read + DESCRIPTION + This function reads pages within user predefined area. + PARAMETERS + nLpn [IN] logical page number. + nNumOfPages [IN] the number of pages to read. + pBuf [IN/OUT] buffer for read. + RETURN VALUES + FTL_SUCCESS + FTL_Read is completed + FTL_CRITICAL_ERROR + FTL_Read is failed + FTL_USERDATA_ERROR + there is an uncorrectable read error on user data + FTL_OUT_OF_RANGE + input parameters are invalid + NOTES + */ +static Int32 +FTL_Read(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pBuf) +{ + Int32 nRetValue; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwPagesReadCnt += dwNumOfPages; + stFTLStatistics.ddwFTLReadCnt++; +#endif + nRetValue = _FTLRead(dwLpn, dwNumOfPages, pBuf); + if (nRetValue != FTL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] failed calling _FTLRead(0x%08X, 0x%08X, 0x%08X)(line:%d)\n"), + dwLpn, dwNumOfPages, (UInt32)pBuf, __LINE__)); + } + + // NirW - for now fix right here, we should come with better strategy later +#ifndef AND_READONLY + if ((pstFTLCxt->dwRefreshListIdx > (FTL_READ_REFRESH_LIST_SIZE >> 1)) || + (_IsBlockInRefreshList(0xFFFF, 0xFFFF, NULL) && + pstFTLCxt->dwReadsSinceLastRefreshMark > FTL_READS_SINCE_LAST_REFRESH_MARK_TRASHOLD)) + { + _HandleRefreshBlock(); + } +#endif // ! AND_READONLY + /* release all buffers as a security measure */ + BUF_ReleaseAllBuffers(); + + return nRetValue; +} + +static UInt32 +_Lbn2Vpn(LOGCxt * pLog, UInt32 dwLbn, UInt16 wLPOffset) +{ + UInt32 dwVpn; + + dwVpn = 0xFFFFFFFF; + if (pLog != NULL) + { + if (pLog->paPOffsetL2P[wLPOffset] != 0xFFFF) + { + UInt32 nVPOffset; + + nVPOffset = pLog->paPOffsetL2P[wLPOffset]; + dwVpn = GET_Vpn(pLog->wVbn, nVPOffset); + } + } + if (dwVpn == 0xFFFFFFFF) + { + dwVpn = wLPOffset + ((UInt32)CONVERT_L2V(dwLbn) * PAGES_PER_SUBLK); + } + return dwVpn; +} + +/* + NAME + _FTLRead + DESCRIPTION + This function reads pages within user predefined area. + PARAMETERS + nLpn [IN] logical page number. + nNumOfPages [IN] the number of pages to read. + pBuf [IN/OUT] buffer for read. + RETURN VALUES + FTL_SUCCESS + _FTLRead is completed + FTL_CRITICAL_ERROR + _FTLRead is failed + FTL_USERDATA_ERROR + there is an uncorrectable read error on user data + FTL_OUT_OF_RANGE + input parameters are invalid + NOTES + */ + +static Int32 +_FTLRead(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pBuf) +{ + Buffer *pInBuf = NULL; + LOGCxt *pLog; + UInt32 dwLbn, dwReadPages = 0, dwVpn; + UInt16 wLPOffset; + BOOL32 bLast = FALSE32, bReadErr = FALSE32, boolReadMultiplePagesFailure = FALSE32; + Int32 nVFLRet; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++_FTLRead(dwLpn:%d, dwNumOfPages:%d)\n"), dwLpn, dwNumOfPages)); + + pstFTLCxt->dwReadsSinceLastRefreshMark++; + /* input parameter check */ + // check the data buffer is not a NULL pointer + if (pBuf == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] pBuf == NULL!\n"))); + return FTL_CRITICAL_ERROR; + } + // check that the paramters are not zero pages to read or out of range + if (dwNumOfPages == 0 || (dwLpn + dwNumOfPages) > USER_PAGES_TOTAL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] input parameters are invalid!\n"))); + return FTL_OUT_OF_RANGE_ERROR; + } + + /* calculate logical block number & page offset */ + dwLbn = dwLpn / PAGES_PER_SUBLK; + wLPOffset = (UInt16)(dwLpn - dwLbn * PAGES_PER_SUBLK); + + /* initialize interal buffer */ + pInBuf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pInBuf == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] BUF_Get error (line:%d)!\n"), __LINE__)); + return FTL_CRITICAL_ERROR; + } + + /* find log block if there is */ + pLog = _ScanLogSection(dwLbn); + + for (;;) + { + if (boolReadMultiplePagesFailure == FALSE32) + { + BOOL32 boolReadRes; + UInt16 wPagesReadThisTime = WMR_MIN((UInt16)(dwNumOfPages - dwReadPages), (UInt16)(PAGES_PER_SUBLK - wLPOffset)); + + // check if either the log or the data block went beyond exceptable read counter +#ifndef AND_READONLY + if (pstFTLCxt->pawRCCacheTable[CONVERT_L2V(dwLbn)] >= FTL_RC_TRESHOLD) + { + _AddLbnToRefreshList((UInt16)dwLbn, CONVERT_L2V(dwLbn)); + } + if (pLog != NULL) + { + if (pstFTLCxt->pawRCCacheTable[pLog->wVbn] >= FTL_RC_TRESHOLD) + { + _AddLbnToRefreshList((UInt16)dwLbn, pLog->wVbn); + } + } +#endif // AND_READONLY + if (pLog == NULL) + { + BOOL32 boolAddVbToRefreshList; + // count reads per bank +#ifndef AND_READONLY + pstFTLCxt->pawRCCacheTable[CONVERT_L2V(dwLbn)] += ((wPagesReadThisTime / BANKS_TOTAL) + ((wPagesReadThisTime % BANKS_TOTAL) ? 1 : 0)); +#endif /* #ifndef AND_READONLY */ + if (NULL != VFL_ReadMultiplePagesInVb) + { + boolReadRes = VFL_ReadMultiplePagesInVb(CONVERT_L2V(dwLbn), wLPOffset, wPagesReadThisTime, + &pBuf[dwReadPages * BYTES_PER_PAGE], pstbaMultiplePagesWriteSpare, &boolAddVbToRefreshList, NULL, FALSE32); + } + else + { + UInt16 wPageIdx; + for (wPageIdx = 0; wPageIdx < wPagesReadThisTime; wPageIdx++) + { + pstadwScatteredReadVpn[wPageIdx] = GET_Vpn(CONVERT_L2V(dwLbn), wLPOffset + wPageIdx); + } + boolReadRes = VFL_ReadScatteredPagesInVb(pstadwScatteredReadVpn, wPagesReadThisTime, + &pBuf[dwReadPages * BYTES_PER_PAGE], pstbaMultiplePagesWriteSpare, &boolAddVbToRefreshList, NULL, FALSE32, NULL); + } + if (boolAddVbToRefreshList == TRUE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _AddLbnToRefreshList (0x%X, 0x%X) (line:%d)!\n"), dwLbn, CONVERT_L2V(dwLbn), __LINE__)); +#ifndef AND_READONLY + _AddLbnToRefreshList((UInt16)dwLbn, CONVERT_L2V(dwLbn)); +#endif // ! AND_READONLY + } + } + else + { + BOOL32 boolAddVbToRefreshList; + UInt16 wPageIdx; + for (wPageIdx = 0; wPageIdx < wPagesReadThisTime; wPageIdx++) + { + pstadwScatteredReadVpn[wPageIdx] = _Lbn2Vpn(pLog, dwLbn, (wLPOffset + wPageIdx)); +#ifndef AND_READONLY + if (GET_Vbn(pstadwScatteredReadVpn[wPageIdx]) == pLog->wVbn) + { + pstFTLCxt->pawRCCacheTable[pLog->wVbn]++; + } + else + { + pstFTLCxt->pawRCCacheTable[pstFTLCxt->pawMapTable[dwLbn]]++; + } +#endif /* #ifndef AND_READONLY */ + } + + boolReadRes = VFL_ReadScatteredPagesInVb(pstadwScatteredReadVpn, + wPagesReadThisTime, + &pBuf[dwReadPages * BYTES_PER_PAGE], pstbaMultiplePagesWriteSpare, &boolAddVbToRefreshList, NULL, FALSE32, NULL); + + if (boolAddVbToRefreshList == TRUE32) + { + // this should not be main stream case - no big deal if we mark both blocks + // to be refreshed + FTL_WRN_PRINT((TEXT("[FTL:WRN] _AddLbnToRefreshList (0x%X, 0x%X, 0x%X) (line:%d)!\n"), dwLbn, CONVERT_L2V(dwLbn), pLog->wVbn, __LINE__)); +#ifndef AND_READONLY + _AddLbnToRefreshList((UInt16)dwLbn, CONVERT_L2V(dwLbn)); + _AddLbnToRefreshList((UInt16)dwLbn, pLog->wVbn); +#endif // ! AND_READONLY + } + } + + if (boolReadRes == TRUE32) + { + UInt16 wPageIdx; + + for (wPageIdx = 0; wPageIdx < wPagesReadThisTime; wPageIdx++) + { + if (CHECK_FTL_ECC_MARK(&pstbaMultiplePagesWriteSpare[(wPageIdx * BYTES_PER_METADATA_RAW)]) == FALSE32) + { + ANDAddressStruct andAddressStruct; + UInt32 dwSize = sizeof(andAddressStruct); + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRead ECC Mark lbn 0x%X, offset 0x%X, pIdx 0x%X mark 0x%08X (line:%d)!\n"), dwLbn, wLPOffset, wPageIdx, + GET_FTL_ECC_MARK(&pstbaMultiplePagesWriteSpare[(wPageIdx * BYTES_PER_METADATA_RAW)]), __LINE__)); + andAddressStruct.dwLpn = GET_Vpn(dwLbn, (wLPOffset + wPageIdx)); + FTL_GetStruct(AND_STRUCT_FTL_GETADDRESS, &andAddressStruct, &dwSize); + FTL_ERR_PRINT((TEXT("[FTL:ERR] address l:0x%08X v:0x%08X cs:0x%02X p:0x%08X (line:%d)!\n"), + andAddressStruct.dwLpn, andAddressStruct.dwVpn, andAddressStruct.dwCS, andAddressStruct.dwPpn, __LINE__)); + bReadErr = TRUE32; /* identify pages that were copied from pages with bad ecc */ + } + } + dwReadPages += wPagesReadThisTime; + dwLpn += wPagesReadThisTime; + wLPOffset += wPagesReadThisTime; + if (dwReadPages == dwNumOfPages) + { + bLast = TRUE32; + } + else + { + bLast = FALSE32; + } + } + else + { + if (pLog != NULL) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] VFL_ReadScatteredPagesInVb failed (0x%X, 0x%X, 0x%X); will retry with multiple VFL_Read calls (line:%d)!\n"), + dwLbn, CONVERT_L2V(dwLbn), pLog->wVbn, __LINE__)); + } + else + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] VFL_ReadMultiplePagesInVb failed (0x%X, 0x%X); will retry with multiple VFL_Read calls (line:%d)!\n"), + dwLbn, CONVERT_L2V(dwLbn), __LINE__)); + } + boolReadMultiplePagesFailure = TRUE32; + } + } + if (!((dwReadPages == dwNumOfPages) || (wLPOffset == PAGES_PER_SUBLK))) + { + UInt8 * pabOrgData; + BOOL32 boolAddVbToRefreshList; + + /* if log block is allocated */ + dwVpn = _Lbn2Vpn(pLog, dwLbn, wLPOffset); + + /* check last read case */ + if (dwReadPages + 1 == dwNumOfPages) + { + bLast = TRUE32; + } + else + { + bLast = FALSE32; + } + + pabOrgData = pInBuf->pData; + pInBuf->pData = (pBuf + dwReadPages * BYTES_PER_PAGE); + + nVFLRet = VFL_Read(dwVpn, pInBuf, TRUE32, TRUE32, &boolAddVbToRefreshList, NULL, FALSE32); + pInBuf->pData = pabOrgData; +#ifndef AND_READONLY + if (boolAddVbToRefreshList == TRUE32) + { + UInt16 wVbn = (UInt16)GET_Vbn(dwVpn); + FTL_WRN_PRINT((TEXT("[FTL:WRN] _AddLbnToRefreshList (0x%X, 0x%X) (line:%d)!\n"), (UInt16)dwLbn, wVbn, __LINE__)); + _AddLbnToRefreshList((UInt16)dwLbn, wVbn); + } +#endif // ! AND_READONLY + + if (nVFLRet == VFL_CRITICAL_ERROR) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on VFL_Read(line:%d)!\n"), __LINE__)); + BUF_Release(pInBuf); + return FTL_CRITICAL_ERROR; + } + + if (nVFLRet == VFL_U_ECC_ERROR || (CHECK_FTL_ECC_MARK(pInBuf->pSpare) == FALSE32)) + { + ANDAddressStruct andAddressStruct; + UInt32 dwSize = sizeof(andAddressStruct); + FTL_ERR_PRINT((TEXT("[FTL:ERR] Real ECC ERROR VFL_Read(line:%d) ECC mark is 0x%02X!\n"), __LINE__, GET_FTL_ECC_MARK(pInBuf->pSpare))); + andAddressStruct.dwLpn = GET_Vpn(dwLbn, wLPOffset); + FTL_GetStruct(AND_STRUCT_FTL_GETADDRESS, &andAddressStruct, &dwSize); + FTL_ERR_PRINT((TEXT("[FTL:ERR] address l:0x%08X v:0x%08X cs:0x%02X p:0x%08X (line:%d)!\n"), + andAddressStruct.dwLpn, andAddressStruct.dwVpn, andAddressStruct.dwCS, andAddressStruct.dwPpn, __LINE__)); + + if (pLog != NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] lbn 0x%X pLog->wVbn 0x%X dataVbn 0x%X offset 0x%X vpn 0x%X!\n"), + dwLbn, pLog->wVbn, CONVERT_L2V(dwLbn), wLPOffset, _Lbn2Vpn(pLog, dwLbn, wLPOffset))); + } + else + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] lbn 0x%X dataVbn 0x%X offset 0x%X vpn 0x%X!\n"), + dwLbn, CONVERT_L2V(dwLbn), wLPOffset, _Lbn2Vpn(pLog, dwLbn, wLPOffset))); + } + bReadErr = TRUE32; /* identify pages that were copied from pages with bad ecc */ + } + + if (nVFLRet == VFL_SUCCESS) + { + UInt32 dwWrittenLpn; + _GetLOGCxtSpare(pInBuf->pSpare, &dwWrittenLpn, NULL); + if (dwWrittenLpn != dwLpn) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] VFL_Read (dwWrittenLpn(0x%X) != dwLpn(0x%X))!\n"), dwWrittenLpn, dwLpn)); + } + } + + dwLpn++; + dwReadPages++; + wLPOffset++; + if (dwReadPages == dwNumOfPages) + { + bLast = TRUE32; + } + } + + if (bLast) + { + break; + } + + if (wLPOffset == PAGES_PER_SUBLK) + { + dwLbn++; + if ((UInt16)dwLbn >= USER_SUBLKS_TOTAL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on VFL_Read(line:%d)!\n"), __LINE__)); + BUF_Release(pInBuf); + return FTL_CRITICAL_ERROR; + } + wLPOffset = 0; + pLog = _ScanLogSection(dwLbn); + boolReadMultiplePagesFailure = FALSE32; + } + } + + BUF_Release(pInBuf); + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --FTL_Read(dwLpn:%d, dwNumOfPages:%d)\n"), dwLpn, dwNumOfPages)); + + if (bReadErr) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _FTLRead returns FTL_USERDATA_ERROR (line:%d)!\n"), __LINE__)); + return FTL_USERDATA_ERROR; + } + else + { + return FTL_SUCCESS; + } +} +#ifndef AND_READONLY +static BOOL32 _FTLMarkCxtNotValid(void) +{ + if (pstFTLCxt->boolFlashCxtIsValid == TRUE32) + { + Int32 nRetVal; + UInt8 bTryIdx = 4; + while (--bTryIdx) + { + /* invalidate the cache */ + Buffer * pBuf; + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuf == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] BUF_Get error (line:%d)!\n"), __LINE__)); + return FALSE32; + } + if (_PrepareNextMapCxtPage() == FALSE32) + { + BUF_Release(pBuf); + return FALSE32; + } + /* set the data area */ + WMR_MEMSET(pBuf->pData, 0xFF, BYTES_PER_PAGE); + /* set the spare */ + _SetFTLCxtSpare(&pstFTLCxt->dwAge, NULL, NULL, pBuf->pSpare); + SET_FTL_SPARE_TYPE(pBuf->pSpare, FTL_SPARE_TYPE_CXT_INVALID); + nRetVal = VFL_Write(pstFTLCxt->dwCurrMapCxtPage, pBuf, TRUE32, FALSE32); + BUF_Release(pBuf); + if (nRetVal == VFL_SUCCESS) + { + pstFTLCxt->boolFlashCxtIsValid = FALSE32; + break; + } + // write fail therefore we have to change context blocks + FTL_CHANGE_FTLCXT_TO_NEXT_BLOCK(); + } + if (bTryIdx == 0) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] Error invalidating the Index (line:%d)!\n"), __LINE__)); + return FALSE32; + } + } + return TRUE32; +} + +/* + + NAME + FTL_Write + DESCRIPTION + This function writes pages within user predefined area. + PARAMETERS + nLpn [IN] logical page number. + nNumOfPages [IN] the number of pages to read. + pBuf [IN] buffer for write. + RETURN VALUES + FTL_SUCCESS + FTL_Write is completed + FTL_CRITICAL_ERROR + FTL_Write is failed + FTL_OUT_OF_RANGE + input parameters are invalid + NOTES + + */ +static Int32 +FTL_Write(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pabDataBuf, BOOL32 isStatic) +{ + LOGCxt *pLog = NULL; + UInt16 wLbn; + UInt16 wLPOffset; + UInt32 dwWritePages = 0; + UInt32 dwRemainPages; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++FTL_Write(dwLpn:%d, dwNumOfPages:%d)\n"), dwLpn, dwNumOfPages)); + // isStatic is not supported + WMR_ASSERT(!isStatic); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwPagesWrittenCnt += dwNumOfPages; + stFTLStatistics.ddwFTLWriteCnt++; +#endif + if (pabDataBuf == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] pabDataBuf == NULL!\n"))); + return FTL_CRITICAL_ERROR; + } + + /* Sanity check for arguments */ + if (dwNumOfPages == 0 || (dwLpn + dwNumOfPages) > USER_PAGES_TOTAL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] input parameters are invalid!\n"))); + return FTL_OUT_OF_RANGE_ERROR; + } + + // Step A: Check if pstFTLCxt is flash valid (i.e. first write operation since flush) + // If this is the first write, mark the pstFTLCxt in the flash as invalid. + if (_FTLMarkCxtNotValid() == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] FTL_Write failed calling _FTLMarkCxtNotValid\n"))); + return FTL_CRITICAL_ERROR; + } + // Step B: Prepare variables before getting into the write loop + wLbn = (UInt16)(dwLpn / PAGES_PER_SUBLK); + wLPOffset = (UInt16)(dwLpn - wLbn * PAGES_PER_SUBLK); + + dwRemainPages = dwNumOfPages; + + if ((pLog = _PrepareLog(wLbn)) == NULL) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _PrepareLog!\n"))); + BUF_ReleaseAllBuffers(); + return FTL_CRITICAL_ERROR; + } + + // Step C: run the write loop until all pages are written to the flash + for (;;) + { + BOOL32 boolFullLBWrite = FALSE32; + + // if the log block is full merge it - if it is released create another log block... + // the code should be changed so: + // 1. we first check for the case of full vb write operation. + // 2. we check for the case of not enough space in the log here - + // case there is not enough space we should merge the relevant info to a new log block + // then copy the new info. + if (pLog->wFreePOffset == PAGES_PER_SUBLK) + { + /* if log block is full */ + if (_Merge(pLog) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _Merge!\n"))); + BUF_ReleaseAllBuffers(); + return FTL_CRITICAL_ERROR; + } + + /* check if the log has a free block attached to it */ + if (pLog->wVbn == LOG_EMPTY_SLOT) + { + UInt16 wVbnForLog; + /* set a new free block to log after merge operation*/ + if (_GetFreeVb(&wVbnForLog) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _GetFreeVb (line:%d)!\n"), __LINE__)); + BUF_ReleaseAllBuffers(); + return FTL_CRITICAL_ERROR; + } + ASSIGN_VBN_TO_LOG(pLog, wVbnForLog); + + _InitLogCxt(pLog); + } + } + + /* check if we can do multiple pages write operation - do we have more that BANKS_TOTAL to write in the current logical block */ + /* + we want to use this function in one of two cases: + 1. we have a write operation for a whole vb. + 2. we have a write operation for a log that have enough free space. + */ + if ((dwRemainPages >= PAGES_PER_SUBLK) && (wLPOffset == 0)) + { + boolFullLBWrite = TRUE32; + } + + { + UInt16 wLPOffsetIdx; + UInt16 wDesVbn; + UInt16 wVPOffset; + UInt16 wNumOfPagesToWrite = (UInt16)WMR_MIN(((UInt32)(PAGES_PER_SUBLK - wLPOffset)), dwRemainPages); + if (boolFullLBWrite == FALSE32) + { + wNumOfPagesToWrite = WMR_MIN((PAGES_PER_SUBLK - pLog->wFreePOffset), wNumOfPagesToWrite); + } + + /* fill up the spare data */ + wDesVbn = pLog->wVbn; + wVPOffset = pLog->wFreePOffset; + if (boolFullLBWrite == TRUE32 && pLog->wFreePOffset != 0) + { + if (_GetFreeVb(&wDesVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _GetFreeVb (line:%d)!\n"), __LINE__)); + BUF_ReleaseAllBuffers(); + return FTL_CRITICAL_ERROR; + } + wVPOffset = 0; + } + if (wVPOffset == 0) + { + pstFTLCxt->dwWriteAge++; + } + for (wLPOffsetIdx = 0; wLPOffsetIdx < wNumOfPagesToWrite; wLPOffsetIdx++) + { + UInt8 * pbaTempSpare = &(pstbaMultiplePagesWriteSpare[wLPOffsetIdx * BYTES_PER_METADATA_RAW]); + _SetLOGCxtSpare(GET_Vpn(pLog->wLbn, (wLPOffset + wLPOffsetIdx)), pstFTLCxt->dwWriteAge, pbaTempSpare); + } + + /* change the spare type from log to data if relevant */ + if ((wLPOffset + wLPOffsetIdx) == PAGES_PER_SUBLK) + { + UInt8 * pbaTempSpare = &(pstbaMultiplePagesWriteSpare[(--wLPOffsetIdx) * BYTES_PER_METADATA_RAW]); + if (boolFullLBWrite == TRUE32) + { + SET_FTL_SPARE_TYPE(pbaTempSpare, FTL_SPARE_TYPE_DATA); + } + else if (pLog->boolCopyMerge == TRUE32 && pLog->wFreePOffset == wLPOffset && pLog->wFreePOffset == pLog->wNumOfValidLP) + { + SET_FTL_SPARE_TYPE(pbaTempSpare, FTL_SPARE_TYPE_DATA); + } + } + + if (VFL_WriteMultiplePagesInVb(GET_Vpn(wDesVbn, wVPOffset), wNumOfPagesToWrite, (pabDataBuf + (dwWritePages * BYTES_PER_PAGE)), pstbaMultiplePagesWriteSpare, TRUE32, FALSE32) == FALSE32) + { + if (wDesVbn == pLog->wVbn) + { + pLog->wFreePOffset = PAGES_PER_SUBLK; + pLog->boolCopyMerge = FALSE32; + } + else + { + if (_SetFreeVb(wDesVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] FTL_Write failed _SetFreeVb(0x%X) (line:%d)\n"), wDesVbn, __LINE__)); + } + } + continue; + } + else + { + if (wDesVbn != pLog->wVbn) + { + /* this is a full block write to free block - release the log */ + if (_SetFreeVb(pLog->wVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] FTL_Write failed _SetFreeVb(0x%X) (line:%d)\n"), pLog->wVbn, __LINE__)); + } + if (_SetFreeVb(CONVERT_L2V(pLog->wLbn)) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] FTL_Write failed _SetFreeVb(0x%X) (line:%d)\n"), CONVERT_L2V(pLog->wLbn), __LINE__)); + } + MODIFY_LB_MAP(pLog->wLbn, wDesVbn); + MARK_LOG_AS_EMPTY(pLog); + wLPOffset = PAGES_PER_SUBLK; + } + else + { + for (wLPOffsetIdx = 0; wLPOffsetIdx < wNumOfPagesToWrite; wLPOffsetIdx++, wLPOffset++) + { + if (pLog->paPOffsetL2P[wLPOffset] == 0xFFFF) + { + pLog->wNumOfValidLP++; + } + else + { + pLog->boolCopyMerge = FALSE32; + } + pLog->paPOffsetL2P[wLPOffset] = pLog->wFreePOffset++; + } + if (pLog->wFreePOffset != pLog->wNumOfValidLP || pLog->wNumOfValidLP != wLPOffset) + { + pLog->boolCopyMerge = FALSE32; + } + } + dwWritePages += wNumOfPagesToWrite; + dwRemainPages -= wNumOfPagesToWrite; + wLPOffset--; + } + } + /* NirW - check if boolCopyMerge == TRUE32 - if it does take the log out for the log list and mark the original unit as free */ + if (pLog->wFreePOffset == PAGES_PER_SUBLK && pLog->boolCopyMerge == TRUE32) + { + _Merge(pLog); + } + + if (dwRemainPages == 0) + { + break; + } + + if (++wLPOffset == PAGES_PER_SUBLK) + { + if (++wLbn == USER_SUBLKS_TOTAL) + { + break; + } + + if ((pLog = _PrepareLog(wLbn)) == NULL) /* crossing to the next block */ + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] there is error on _PrepareLog!\n"))); + BUF_ReleaseAllBuffers(); + return FTL_CRITICAL_ERROR; + } + + wLPOffset = 0; + } + } + + if (pstFTLCxt->dwRefreshListIdx > (FTL_READ_REFRESH_LIST_SIZE >> 1)) + { + _HandleRefreshBlock(); + } + else if (pstFTLCxt->wWearLevelCounter >= WMR_WEAR_LEVEL_FREQUENCY_DELAY) + { + UInt8 bTrialIdx; + pstFTLCxt->wWearLevelCounter -= WMR_WEAR_LEVEL_FREQUENCY; + for (bTrialIdx = 0; bTrialIdx < 4; bTrialIdx++) + { + if (_AutoWearLevel() == TRUE32) + { + break; + } + } + } + + FTL_LOG_PRINT((TEXT("[FTL:OUT] --FTL_Write(dwLpn:%d, dwNumOfPages:%d)\n"), dwLpn, dwNumOfPages)); + + /* Always release all buffers before returning to the extrnal caller */ + BUF_ReleaseAllBuffers(); + return FTL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* FTL_Format */ +/* DESCRIPTION */ +/* This function formats ftl. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* FTL_SUCCESS */ +/* FTL_Format is completed */ +/* FTL_CRITICAL_ERROR */ +/* FTL_Format is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +FTL_Format(UInt32 dwOptions) +{ + UInt16 wIdx; + Int32 nFTLRet = FTL_SUCCESS; + UInt32 dwFTLType; + + FTL_LOG_PRINT((TEXT("[FTL: IN] ++FTL_Format()\n"))); + + for (wIdx = 0; wIdx < FTL_AREA_SIZE; wIdx++) + { + VFL_Erase(wIdx, TRUE32); + } + + /* init EC table */ + WMR_MEMSET(pstFTLCxt->pawECCacheTable, 0, (FTL_AREA_SIZE * sizeof(UInt16))); + /* init RC table */ + WMR_MEMSET(pstFTLCxt->pawRCCacheTable, 0, (FTL_AREA_SIZE * sizeof(UInt16))); + + /* initialize ftl context (free virtual block list) */ + for (wIdx = 0; wIdx < FREE_SECTION_SIZE; wIdx++) + { + pstFTLCxt->awFreeVbList[wIdx] = wIdx + FREE_SECTION_START; + if (_EraseAndMarkEC(wIdx + FREE_SECTION_START) != VFL_SUCCESS) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] FTL_Format failed _EraseAndMarkEC(0x%X) (line:%d)\n"), (wIdx + FREE_SECTION_START), __LINE__)); + } + } + + pstFTLCxt->wNumOfFreeVb = FREE_SECTION_SIZE; + pstFTLCxt->wFreeVbListTail = 0; + + /* init logs table */ + for (wIdx = 0; wIdx < LOG_SECTION_SIZE; wIdx++) + { + pstFTLCxt->aLOGCxtTable[wIdx].wVbn = LOG_EMPTY_SLOT; + } + + /* init map table */ + for (wIdx = 0; wIdx < USER_SUBLKS_TOTAL; wIdx++) + { + pstFTLCxt->pawMapTable[wIdx] = (UInt16)(DATA_SECTION_START + wIdx); + } + + /* init read reclaim info - NirW - to be added */ + + /* init the Cxt pointers */ + for (wIdx = 0; wIdx < FTL_CXT_SECTION_SIZE; wIdx++) + { + pstFTLCxt->awMapCxtVbn[wIdx] = wIdx; + } + pstFTLCxt->dwCurrMapCxtPage = GET_Vpn(pstFTLCxt->awMapCxtVbn[0], (PAGES_PER_SUBLK - 1)); + + pstFTLCxt->dwAge = 0xFFFFFFFF; + pstFTLCxt->dwWriteAge = 0; /* NirW */ + + pstFTLCxt->wWearLevelCounter = 0; + pstFTLCxt->dwMetaWearLevelCounter = 0; + + // init the refresh block information + WMR_MEMSET(pstFTLCxt->aFTLReadRefreshList, 0xFF, + (sizeof(FTLReadRefreshStruct) * FTL_READ_REFRESH_LIST_SIZE)); + pstFTLCxt->dwRefreshListIdx = 0; + pstFTLCxt->dwReadsSinceLastRefreshMark = 0; + + if (VFL_ChangeFTLCxtVbn(pstFTLCxt->awMapCxtVbn) != VFL_SUCCESS) + { + return FTL_CRITICAL_ERROR; + } + { + UInt8 bTryStoreFTLCxt = 3; + while (_StoreFTLCxt() == FALSE32 && --bTryStoreFTLCxt) + { + /* make sure that the next time we try it is in a different block */ + FTL_CHANGE_FTLCXT_TO_NEXT_BLOCK(); + } + if (bTryStoreFTLCxt == 0) + { + nFTLRet = FTL_CRITICAL_ERROR; + } + } + + dwFTLType = FTL_TYPE_FTL; + VFL_SetStruct(AND_STRUCT_VFL_FTLTYPE, &dwFTLType, sizeof(UInt32)); + + FTL_LOG_PRINT((TEXT("[FTL: IN] --FTL_Format()\n"))); + + return nFTLRet; +} +#endif // AND_READONLY +static BOOL32 _InitDeviceInfo(void) +{ + stFTLDeviceInfo.wPagesPerVb = (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + stFTLDeviceInfo.wUserVbTotal = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_NUM_OF_USER_SUBLK) - + (FTL_CXT_SECTION_SIZE + FREE_SECTION_SIZE); + stFTLDeviceInfo.wBytesPerPage = (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + stFTLDeviceInfo.wNumOfBanks = (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_NUM_OF_BANKS); + stFTLDeviceInfo.dwUserPagesTotal = + (UInt32)stFTLDeviceInfo.wUserVbTotal * (UInt32)stFTLDeviceInfo.wPagesPerVb; + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* FTL_Init */ +/* DESCRIPTION */ +/* This function initializes ftl context. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* FTL_SUCCESS */ +/* FTL_Init is completed */ +/* FTL_CRITICAL_ERROR */ +/* FTL_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +FTL_Init(VFLFunctions *pVFLFunctions) +{ + UInt16 wLogIdx; + + WMR_MEMCPY(&stVFLFunctions, pVFLFunctions, sizeof(VFLFunctions)); + FTL_LOG_PRINT((TEXT("[FTL: IN] ++FTL_Init()\n"))); + + _InitDeviceInfo(); + // needed to verify that the index information will not cross two super blocks + WMR_ASSERT(FTL_NUM_PAGES_TO_WRITE_IN_STORECXT < PAGES_PER_SUBLK); + WMR_ASSERT((PAGES_PER_SIMPLE_MERGE_BUFFER << 1) < PAGES_PER_SUBLK); // using pstadwScatteredReadVpn for both read and write in _DoMoveMerge +#ifdef AND_COLLECT_STATISTICS + WMR_ASSERT(sizeof(FTLStatistics) < AND_STATISTICS_SIZE_PER_LAYER); + WMR_MEMSET(&stFTLStatistics, 0, sizeof(FTLStatistics)); +#endif // AND_COLLECT_STATISTICS + /* init pstFTLCxt */ + if (pstFTLCxt == NULL) + { + pstFTLMeta = (FTLMeta *)WMR_MALLOC(sizeof(FTLMeta)); + if (pstFTLMeta == NULL) + { + return FTL_CRITICAL_ERROR; + } + pstFTLCxt = &pstFTLMeta->stFTLCxt; + WMR_MEMSET(pstFTLMeta->abReserved, 0, ((BYTES_PER_SECTOR - 2) * sizeof(UInt32)) - sizeof(FTLCxt2)); + pstFTLCxt->boolFlashCxtIsValid = FALSE32; /* make sure the cache is marked as invalid until loading */ + + pstFTLCxt->pawMapTable = (UInt16 *)WMR_MALLOC(sizeof(UInt16) * USER_SUBLKS_TOTAL); /* covers lb area (user available logical blocks) */ + /* added 1 LOGCxt for _DoMoveMerge */ + pstFTLCxt->pawLOGCxtMapTable = (UInt16 *)WMR_MALLOC((LOG_SECTION_SIZE + 1) * PAGES_PER_SUBLK * sizeof(UInt16)); /* covers log tables area (+ offsets array) */ +#ifndef AND_READONLY + pstFTLCxt->pawECCacheTable = (UInt16 *)WMR_MALLOC(FTL_AREA_SIZE * sizeof(UInt16)); /* covers vb area available to FTL - data and tables (log and FTLCtx) */ + pstFTLCxt->pawRCCacheTable = (UInt16 *)WMR_MALLOC(FTL_AREA_SIZE * sizeof(UInt16)); /* covers vb area available to FTL - data and tables (log and FTLCtx) */ +#endif +#if (defined(AND_READONLY) && AND_READONLY) && defined(WMR_MAX_READONLY_PAGES) + pstbaMultiplePagesWriteSpare = (UInt8 *)WMR_MALLOC(WMR_MAX_READONLY_PAGES * BYTES_PER_METADATA_RAW); + pstadwScatteredReadVpn = (UInt32 *)WMR_MALLOC(WMR_MAX_READONLY_PAGES * sizeof(UInt32)); +#else + pstbaMultiplePagesWriteSpare = (UInt8 *)WMR_MALLOC(PAGES_PER_SUBLK * BYTES_PER_METADATA_RAW); + pstadwScatteredReadVpn = (UInt32 *)WMR_MALLOC(PAGES_PER_SUBLK * sizeof(UInt32)); +#endif + + // Buffer allocation +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) || \ + !(defined(AND_READONLY) && AND_READONLY) + WMR_BufZone_Init(&FTL_BufZone); + pstSimpleMergeDataBuffer = (UInt8*)WMR_Buf_Alloc_ForDMA(&FTL_BufZone, PAGES_PER_SIMPLE_MERGE_BUFFER * BYTES_PER_PAGE); + WMR_BufZone_FinishedAllocs(&FTL_BufZone); + WMR_BufZone_Rebase(&FTL_BufZone, (void**)&pstSimpleMergeDataBuffer); + WMR_BufZone_FinishedRebases(&FTL_BufZone); +#endif + + if (pstFTLCxt->pawMapTable == NULL || pstFTLCxt->pawLOGCxtMapTable == NULL || + pstbaMultiplePagesWriteSpare == NULL +#ifndef AND_READONLY + || pstFTLCxt->pawRCCacheTable == NULL || pstFTLCxt->pawECCacheTable == NULL +#endif +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) || \ + !(defined(AND_READONLY) && AND_READONLY) + || pstSimpleMergeDataBuffer == NULL +#endif + ) + { + if (pstFTLCxt->pawMapTable != NULL) + { + WMR_FREE(pstFTLCxt->pawMapTable, (sizeof(UInt16) * USER_SUBLKS_TOTAL)); + } + if (pstFTLCxt->pawLOGCxtMapTable != NULL) + { + WMR_FREE(pstFTLCxt->pawLOGCxtMapTable, ((LOG_SECTION_SIZE + 1) * PAGES_PER_SUBLK * sizeof(UInt16))); + } + if (pstFTLCxt->pawECCacheTable != NULL) + { + WMR_FREE(pstFTLCxt->pawECCacheTable, (FTL_AREA_SIZE * sizeof(UInt16))); + } + if (pstFTLCxt->pawRCCacheTable != NULL) + { + WMR_FREE(pstFTLCxt->pawECCacheTable, (FTL_AREA_SIZE * sizeof(UInt16))); + } + if (pstFTLCxt != NULL) + { + WMR_FREE(pstFTLCxt, (sizeof(FTLCxt2))); + } + if (pstbaMultiplePagesWriteSpare != NULL) + { + WMR_FREE(pstbaMultiplePagesWriteSpare, (PAGES_PER_SUBLK * BYTES_PER_METADATA_RAW)); + } +#ifndef AND_READONLY + WMR_BufZone_Free(&FTL_BufZone); +#endif + return FTL_CRITICAL_ERROR; + } + /* init the pointers to the log arrays */ + for (wLogIdx = 0; wLogIdx < (LOG_SECTION_SIZE + 1); wLogIdx++) + { + pstFTLCxt->aLOGCxtTable[wLogIdx].paPOffsetL2P = &pstFTLCxt->pawLOGCxtMapTable[PAGES_PER_SUBLK * wLogIdx]; + _InitLogCxt(&pstFTLCxt->aLOGCxtTable[wLogIdx]); + } + } + FTL_LOG_PRINT((TEXT("[FTL:OUT] --FTL_Init()\n"))); + + return FTL_SUCCESS; +} +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* FTL_GarbageCollect */ +/* DESCRIPTION */ +/* This function call _Merge(NULL) function. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* TRUE32 */ +/* FTL_GarbageCollect is success. */ +/* FALSE32 */ +/* FTL_GarbageCollect is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +FTL_GarbageCollect(void) +{ + UInt32 nIdx; + LOGCxt *pLog; + BOOL32 bLogExist = FALSE32; + + for (nIdx = 0; nIdx < LOG_SECTION_SIZE; nIdx++) + { + pLog = GET_LOGCxt(nIdx); + + if (pLog->wVbn != LOG_EMPTY_SLOT) + { + bLogExist = TRUE32; + break; + } + } + + if (bLogExist == TRUE32) + { + return _Merge(NULL); + } + + return TRUE32; +} + +static BOOL32 FTL_ShutdownNotify(BOOL32 boolMergeLogs) +{ + BOOL32 boolStat = TRUE32, boolRetTemp; + UInt16 wIdx; + + if (pstFTLCxt->boolFlashCxtIsValid == TRUE32) + { + return TRUE32; + } + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFlushCnt++; +#endif + if (boolMergeLogs == TRUE32) + { + for (wIdx = 0; wIdx < LOG_SECTION_SIZE; wIdx++) + { + LOGCxt * pLog = GET_LOGCxt(wIdx); + + if (pLog->wVbn != LOG_EMPTY_SLOT) + { + pstFTLCxt->wWearLevelCounter++; + if (pLog->boolCopyMerge == TRUE32) + { + boolRetTemp = _DoCopyMerge(pLog); + } + else + { + boolRetTemp = _DoSimpleMerge(pLog); + } + if (boolRetTemp == FALSE32) + { + boolStat = boolRetTemp; + } + } + } + } + if (boolStat == TRUE32) + { + UInt8 bTryStoreFTLCxt = 5; + while (_StoreFTLCxt() == FALSE32 && --bTryStoreFTLCxt) + { + /* make sure that the next time we try it is in a different block */ + FTL_CHANGE_FTLCXT_TO_NEXT_BLOCK(); + } + if (bTryStoreFTLCxt == 0) + { + boolStat = FALSE32; + } + } + /* Always release all buffers before returning to the extrnal caller */ + BUF_ReleaseAllBuffers(); + return boolStat; +} +#endif // AND_READONLY + +#ifdef AND_COLLECT_STATISTICS +static BOOL32 FTL_ECBins(void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + UInt16 blockIdx; + FTLBinsStruct hdr; + const UInt32 kdwStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_EC_BINS; + + if (!pstFTLCxt || !pstFTLCxt->pawECCacheTable) + { + return FALSE32; + } + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= kdwStructSize)) + { + const UInt32 max_bin_val = FTL_MAX_EC_BIN_VAL; + const UInt32 bin_size = FTL_EC_BIN_SIZE; + UInt32 size = *pdwStructSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_EC_BINS; + WMR_MEMSET(pvoidStructBuffer, 0, kdwStructSize); + WMR_FILL_STRUCT(pvoidStructBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < FTL_AREA_SIZE; ++blockIdx) + { + UInt32 index; + UInt16 usage; + void *cursor; + + if (pstFTLCxt->pawECCacheTable[blockIdx] >= max_bin_val) + { + index = FTL_NUM_EC_BINS - 1; + } + else + { + index = pstFTLCxt->pawECCacheTable[blockIdx] / bin_size; + } + + cursor = ((char *)pvoidStructBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (pdwStructSize) + { + *pdwStructSize = kdwStructSize; + boolRes = TRUE32; + } + + return boolRes; +} + +static BOOL32 FTL_RCBins(void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + UInt16 blockIdx; + FTLBinsStruct hdr; + const UInt32 kdwStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_RC_BINS; + + if (!pstFTLCxt || !pstFTLCxt->pawRCCacheTable) + { + return FALSE32; + } + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= kdwStructSize)) + { + const UInt32 max_bin_val = FTL_RC_TRESHOLD; + const UInt32 bin_size = FTL_RC_BIN_SIZE(max_bin_val); + UInt32 size = *pdwStructSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_RC_BINS; + WMR_MEMSET(pvoidStructBuffer, 0, kdwStructSize); + WMR_FILL_STRUCT(pvoidStructBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < FTL_AREA_SIZE; ++blockIdx) + { + UInt32 index; + UInt16 usage; + void *cursor; + + if (pstFTLCxt->pawRCCacheTable[blockIdx] >= max_bin_val) + { + index = FTL_NUM_RC_BINS - 1; + } + else + { + index = pstFTLCxt->pawRCCacheTable[blockIdx] / bin_size; + } + + cursor = ((char *)pvoidStructBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (pdwStructSize) + { + *pdwStructSize = kdwStructSize; + boolRes = TRUE32; + } + + return boolRes; +} +#endif //AND_COLLECT_STATISTICS +static BOOL32 FTL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType) + { + case AND_STRUCT_FTL_GET_TYPE: + { + UInt8 bFTLType = FTL_TYPE_FTL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &bFTLType, sizeof(bFTLType)); + break; + } + + case AND_STRUCT_FTL_GETADDRESS: + { + ANDAddressStruct stAddr; + UInt16 wLbn, wPOffset; + UInt32 dwAddrSize = sizeof(stAddr); + LOGCxt * pLog; + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= sizeof(stAddr))) + { + WMR_MEMCPY(&stAddr, pvoidStructBuffer, sizeof(stAddr)); + + wLbn = (UInt16)GET_Vbn(stAddr.dwLpn); + pLog = _ScanLogSection(wLbn); + wPOffset = (UInt16)GET_PageOffset(stAddr.dwLpn); + stAddr.dwVpn = _Lbn2Vpn(pLog, wLbn, wPOffset); + boolRes = VFL_GetStruct(AND_STRUCT_VFL_GETADDRESS, &stAddr, &dwAddrSize); + + if (boolRes) + { + WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stAddr, sizeof(stAddr)); + } + } + else if (pdwStructSize) + { + *pdwStructSize = sizeof(ANDAddressStruct); + } + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_FTL_GET_FTL_STATS_SIZE: + { + UInt32 dwStatsSize = sizeof(FTLStatistics); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwStatsSize, sizeof(dwStatsSize)); + break; + } + + case AND_STRUCT_FTL_STATISTICS: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stFTLStatistics, sizeof(stFTLStatistics)); + break; + } +#endif // AND_COLLECT_STATISTICS + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO_SIZE: + { + UInt32 dwDeviceInfoSize = sizeof(FTLWMRDeviceInfo); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwDeviceInfoSize, sizeof(dwDeviceInfoSize)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stFTLDeviceInfo, sizeof(stFTLDeviceInfo)); + break; + } + + case AND_STRUCT_FTL_FTLCXT: + { + if (pstFTLCxt) + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, pstFTLCxt, sizeof(*pstFTLCxt)); + } + break; + } + + case AND_STRUCT_FTL_MAPTABLE: + { + if (pstFTLCxt && pstFTLCxt->pawMapTable) + { + const UInt32 dwMapTableSize = sizeof(UInt16) * USER_SUBLKS_TOTAL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, pstFTLCxt->pawMapTable, dwMapTableSize); + } + break; + } + + case AND_STRUCT_FTL_LOGCXTTABLE: + { + if (pstFTLCxt && pstFTLCxt->pawLOGCxtMapTable) + { + const UInt32 dwLogMapSize = (LOG_SECTION_SIZE + 1) * PAGES_PER_SUBLK * sizeof(UInt16); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, pstFTLCxt->pawLOGCxtMapTable, dwLogMapSize); + } + break; + } + + case AND_STRUCT_FTL_ECTABLE: + { + if (pstFTLCxt && pstFTLCxt->pawECCacheTable) + { + const UInt32 dwECTableSize = FTL_AREA_SIZE * sizeof(UInt16); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, pstFTLCxt->pawECCacheTable, dwECTableSize); + } + break; + } + + case AND_STRUCT_FTL_RCTABLE: + { + if (pstFTLCxt && pstFTLCxt->pawRCCacheTable) + { + const UInt32 dwRCTableSize = FTL_AREA_SIZE * sizeof(UInt16); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, pstFTLCxt->pawRCCacheTable, dwRCTableSize); + } + break; + } +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_FTL_GET_FTL_EC_BINS: + { + boolRes = FTL_ECBins(pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_FTL_GET_FTL_RC_BINS: + { + boolRes = FTL_RCBins(pvoidStructBuffer, pdwStructSize); + break; + } +#endif + default: + FTL_WRN_PRINT((TEXT("[FTL:WRN] FTL_GetStruct 0x%X is not identified as FTL data struct identifier!\n"), dwStructType)); + boolRes = FALSE32; + } + return boolRes; +} + +// Added close to enable better testing on the simulator (no need to stop the application to reload AND). +// this code does not touch the NAND itself (just release memory, and clean pointers and statics). +static void FTL_Close(void) +{ + if (pstFTLCxt != NULL) + { + WMR_FREE(pstFTLCxt->pawMapTable, (sizeof(UInt16) * USER_SUBLKS_TOTAL)); + WMR_FREE(pstFTLCxt->pawLOGCxtMapTable, ((LOG_SECTION_SIZE + 1) * PAGES_PER_SUBLK * sizeof(UInt16))); +#ifndef AND_READONLY + WMR_FREE(pstFTLCxt->pawECCacheTable, (FTL_AREA_SIZE * sizeof(UInt16))); + WMR_FREE(pstFTLCxt->pawRCCacheTable, (FTL_AREA_SIZE * sizeof(UInt16))); +#endif /* #ifndef AND_READONLY */ + WMR_FREE(pstFTLCxt, sizeof(FTLMeta)); + WMR_FREE(pstbaMultiplePagesWriteSpare, (PAGES_PER_SUBLK * BYTES_PER_METADATA_RAW)); + WMR_FREE(pstadwScatteredReadVpn, (PAGES_PER_SUBLK * sizeof(UInt32))); + +#ifndef AND_READONLY + WMR_BufZone_Free(&FTL_BufZone); +#endif + + pstFTLCxt = NULL; + pstbaMultiplePagesWriteSpare = NULL; +#if !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) || \ + !(defined(AND_READONLY) && AND_READONLY) + pstSimpleMergeDataBuffer = NULL; +#endif + pstadwScatteredReadVpn = NULL; +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&stFTLStatistics, 0, sizeof(FTLStatistics)); +#endif + } +} + +#ifndef AND_READONLY +static BOOL32 _IsBlockInRefreshList(UInt16 wLbn, UInt16 wVbn, UInt32 * pdwIdx) +{ + BOOL32 boolRes = FALSE32; + UInt32 dwIdx; + + if (pstFTLCxt->dwRefreshListIdx == 0) + { + return FALSE32; + } + else if (wLbn == 0xFFFF && wVbn == 0xFFFF) + { + return TRUE32; + } + + for (dwIdx = 0; dwIdx < pstFTLCxt->dwRefreshListIdx && boolRes == FALSE32; dwIdx++) + { + // if the wVbn == 0xFFFF, find any matching wLbn + if (wVbn == 0xFFFF) + { + if (pstFTLCxt->aFTLReadRefreshList[dwIdx].wLbn == wLbn) + { + boolRes = TRUE32; + } + } + else if (wLbn == 0xFFFF) + { + if (pstFTLCxt->aFTLReadRefreshList[dwIdx].wVbn == wVbn) + { + boolRes = TRUE32; + } + } + else if (pstFTLCxt->aFTLReadRefreshList[dwIdx].wLbn == wLbn && + pstFTLCxt->aFTLReadRefreshList[dwIdx].wVbn == wVbn) + { + boolRes = TRUE32; + } + } + if (pdwIdx != NULL) + { + *pdwIdx = dwIdx; + } + return boolRes; +} +static void _RemoveBlockFromRefreshList(UInt16 wLbn, UInt16 wVbn) +{ + UInt32 dwIdx = 0; + + if ((0xFFFF == wLbn) && (0xFFFF == wVbn)) + { + return; + } + if (_IsBlockInRefreshList(wLbn, wVbn, &dwIdx) == FALSE32) + { + return; + } + + do + { + if (dwIdx == pstFTLCxt->dwRefreshListIdx - 1) + { + pstFTLCxt->dwRefreshListIdx--; + pstFTLCxt->aFTLReadRefreshList[dwIdx].wLbn = 0xFFFF; + pstFTLCxt->aFTLReadRefreshList[dwIdx].wVbn = 0xFFFF; + } + else + { + pstFTLCxt->dwRefreshListIdx--; + pstFTLCxt->aFTLReadRefreshList[dwIdx].wLbn = + pstFTLCxt->aFTLReadRefreshList[pstFTLCxt->dwRefreshListIdx].wLbn; + pstFTLCxt->aFTLReadRefreshList[dwIdx].wVbn = + pstFTLCxt->aFTLReadRefreshList[pstFTLCxt->dwRefreshListIdx].wVbn; + pstFTLCxt->aFTLReadRefreshList[pstFTLCxt->dwRefreshListIdx].wLbn = 0xFFFF; + pstFTLCxt->aFTLReadRefreshList[pstFTLCxt->dwRefreshListIdx].wVbn = 0xFFFF; + } + } + while (_IsBlockInRefreshList(wLbn, wVbn, &dwIdx) == TRUE32); +} + +static BOOL32 _HandleRefreshBlock(void) +{ + UInt16 wFreeVbn, wTempWord, wLbn, wVbn; + LOGCxt * pLOGCxt; + BOOL32 boolFoundMatch = FALSE32; + + // sanity check + if (pstFTLCxt->dwRefreshListIdx == 0) + { + return TRUE32; + } + + if (_FTLMarkCxtNotValid() == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] __HandleRefreshBlock failed calling _FTLMarkCxtNotValid\n"))); + return FALSE32; + } + + wLbn = pstFTLCxt->aFTLReadRefreshList[0].wLbn; + wVbn = pstFTLCxt->aFTLReadRefreshList[0].wVbn; + + // check if the information in the list is still relevant + pLOGCxt = _ScanLogSection(wLbn); + wTempWord = pstFTLCxt->pawMapTable[wLbn]; + if (wTempWord == wVbn) + { + boolFoundMatch = TRUE32; + } + else if (pLOGCxt != NULL) + { + if (pLOGCxt->wVbn == wVbn) + { + boolFoundMatch = TRUE32; + } + } + + if (boolFoundMatch == FALSE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] info in the refresh list seems to be out of date - removing from list (0x%X, 0x%X) (line:%d)\n"), + wLbn, wVbn, __LINE__)); + _RemoveBlockFromRefreshList(wLbn, wVbn); + return TRUE32; + } + + if (pstFTLCxt->boolFlashCxtIsValid == TRUE32) + { + pstFTLCxt->boolFlashCxtIsValid = FALSE32; + } + if (pLOGCxt != NULL) + { + BOOL32 boolRes; + // this block has an active log - do simple merge here + boolRes = _DoSimpleMerge(pLOGCxt); + if (boolRes == TRUE32) + { + _RemoveBlockFromRefreshList(wLbn, 0xFFFF); + return TRUE32; + } + FTL_WRN_PRINT((TEXT("[FTL:WRN] _HandleRefreshBlock failed _DoSimpleMerge (line:%d)\n"), __LINE__)); + return FALSE32; + } + + // this block does not have log - use move + if (_GetFreeVb(&wFreeVbn) == FALSE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _HandleRefreshBlock failed _GetFreeVb (line:%d)\n"), __LINE__)); + return FALSE32; + } + + if (wFreeVbn != 0xFFFF) + { + BOOL32 boolRes; + boolRes = _MoveD2F(wLbn, wFreeVbn); + + if (boolRes == FALSE32) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _HandleRefreshBlock failed _MoveD2F (line:%d)\n"), __LINE__)); + if (_SetFreeVb(wFreeVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _HandleRefreshBlock failed _SetFreeVb(0x%X) (line:%d)\n"), wFreeVbn, __LINE__)); + } + return FALSE32; + } + else + { + _RemoveBlockFromRefreshList(wLbn, 0xFFFF); + if (_SetFreeVb(wVbn) == FALSE32) + { + FTL_ERR_PRINT((TEXT("[FTL:ERR] _HandleRefreshBlock failed _SetFreeVb(0x%X) (line:%d)\n"), wVbn, __LINE__)); + } + MODIFY_LB_MAP(wLbn, wFreeVbn); + return TRUE32; + } + } + return FALSE32; +} + +static BOOL32 _AddLbnToRefreshList(UInt16 wLbn, UInt16 wVbn) +{ + UInt32 dwIdx; + + if (_IsBlockInRefreshList(wLbn, wVbn, &dwIdx) == TRUE32) + { + return TRUE32; + } + + pstFTLCxt->dwReadsSinceLastRefreshMark = 0; + if (pstFTLCxt->dwRefreshListIdx == FTL_READ_REFRESH_LIST_SIZE) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _AddLbnToRefreshList(0x%X, 0x%X) failed adding new block to list - list is full!!! (line:%d)!\n"), + wLbn, wVbn, __LINE__)); + return FALSE32; + } + + if (pstFTLCxt->dwRefreshListIdx == FTL_READ_REFRESH_LIST_SIZE) + { + FTL_WRN_PRINT((TEXT("[FTL:WRN] _AddLbnToRefreshList(0x%X, 0x%X) failed calling (line:%d)!\n"), + wLbn, wVbn, __LINE__)); + return FALSE32; + } + pstFTLCxt->aFTLReadRefreshList[pstFTLCxt->dwRefreshListIdx].wLbn = wLbn; + pstFTLCxt->aFTLReadRefreshList[pstFTLCxt->dwRefreshListIdx].wVbn = wVbn; + pstFTLCxt->dwRefreshListIdx++; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwReadDisturbHandleCall++; +#endif /* AND_COLLECT_STATISTICS */ + return TRUE32; +} +#endif // AND_READONLY + +#ifdef AND_COLLECT_STATISTICS +static void _UpdateStatisticsCounters(UInt8 *pabSrc, void *pvoidStat, UInt32 dwSize) +{ + UInt32 dwIdx; + UInt64 * paddwStat = (UInt64 *)pvoidStat; + + for (dwIdx = 0; dwIdx < (dwSize / sizeof(UInt64)); dwIdx++) + { + UInt64 ddwTemp; + WMR_MEMCPY(&ddwTemp, &pabSrc[dwIdx * sizeof(UInt64)], sizeof(UInt64)); + paddwStat[dwIdx] += ddwTemp; + } +} + +#ifndef AND_READONLY +static BOOL32 _FTLGetStatisticsToCxt(UInt8 * pabData) +{ + UInt32 dwStatBuffSize; + UInt32 dwStatVersion = AND_EXPORT_STRUCTURE_VERSION; + UInt8 *pabCursor = pabData; + UInt8 *pabVersion = &pabData[BYTES_PER_PAGE - sizeof(UInt32)]; + + + WMR_MEMSET(pabCursor, 0, BYTES_PER_PAGE); + + WMR_MEMCPY(pabCursor, &stFTLStatistics, sizeof(stFTLStatistics)); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_STATISTICS, pabCursor, &dwStatBuffSize); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_FILSTATISTICS, pabCursor, &dwStatBuffSize); + + // mark the statistics version + WMR_MEMCPY(pabVersion, &dwStatVersion, sizeof(UInt32)); + return TRUE32; +} +#endif // ! AND_READONLY +static BOOL32 _FTLSetStatisticsFromCxt(UInt8 * pabData) +{ + UInt32 dwStatBuffSize; + Buffer *pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + UInt8 *pabCursor; + if (!pBuff) + { + FTL_ERR_PRINT((TEXT("BUF_Get failed in _FTLSetStatisticsFromCxt!\n"))); + return FALSE32; + } + + pabCursor = pabData; + + _UpdateStatisticsCounters(pabCursor, &stFTLStatistics, sizeof(FTLStatistics)); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_STATISTICS, pBuff->pData, &dwStatBuffSize); + _UpdateStatisticsCounters(pabCursor, pBuff->pData, dwStatBuffSize); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + VFL_SetStruct(AND_STRUCT_VFL_STATISTICS, pBuff->pData, dwStatBuffSize); + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_FILSTATISTICS, pBuff->pData, &dwStatBuffSize); + _UpdateStatisticsCounters(pabCursor, pBuff->pData, dwStatBuffSize); + VFL_SetStruct(AND_STRUCT_VFL_FILSTATISTICS, pBuff->pData, dwStatBuffSize); + + BUF_Release(pBuff); + return TRUE32; +} +#endif // AND_COLLECT_STATISTICS +void FTL_Register(FTLFunctions * pFTLFunctions) +{ + pFTLFunctions->Init = FTL_Init; + pFTLFunctions->Open = FTL_Open; + pFTLFunctions->Read = FTL_Read; + pFTLFunctions->Close = FTL_Close; + pFTLFunctions->GetStruct = FTL_GetStruct; + +#ifndef AND_READONLY + pFTLFunctions->Write = FTL_Write; + pFTLFunctions->Unmap = NULL; + pFTLFunctions->Format = FTL_Format; + pFTLFunctions->WearLevel = FTL_WearLevel; + pFTLFunctions->GarbageCollect = FTL_GarbageCollect; + pFTLFunctions->ShutdownNotify = FTL_ShutdownNotify; + pFTLFunctions->WriteStats = NULL; +#endif +} + +#endif //AND_SUPPORT_LEGACY_FTL diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/FTLTypes.h b/drivers/flash_nand/raw/Whimory/Core/FTL/FTLTypes.h new file mode 100644 index 0000000..603c481 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/FTLTypes.h @@ -0,0 +1,305 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : FTL */ +/* NAME : FTL types definition header */ +/* FILE : FTLTypes.h */ +/* PURPOSE : This header defines Data types which are shared */ +/* by all FTL submodules */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 22-JUL-2005 [Jaesung Jung] : first writing */ +/* 03-NOV-2005 [Yangsup Lee ] : Add wear-leveling algorithm */ +/* 14-MAR-2006 [Yangsup Lee ] : Don't use bad mark area */ +/* 29-MAR-2006 [Yangsup Lee ] : modify wear-leveling structure */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ +#ifndef _FTL_TYPES_H_ +#define _FTL_TYPES_H_ + +#include "WMRConfig.h" + +typedef struct +{ + // Info generated by CalcGlobal + UInt16 wPagesPerVb; /* the count of pages per virtual block */ + UInt16 wUserVbTotal; /* the total number of data virtual block */ + UInt32 dwUserPagesTotal; /* the total number of data sector */ + UInt16 wBytesPerPage; /* bytes per page (main) */ + + UInt16 wNumOfBanks; /* the number of banks */ +} FTLWMRDeviceInfo; + +#define PAGES_PER_SUBLK (stFTLDeviceInfo.wPagesPerVb) +#define USER_SUBLKS_TOTAL (stFTLDeviceInfo.wUserVbTotal) +#define USER_PAGES_TOTAL (stFTLDeviceInfo.dwUserPagesTotal) +#define BYTES_PER_PAGE (stFTLDeviceInfo.wBytesPerPage) + +#define BANKS_TOTAL (stFTLDeviceInfo.wNumOfBanks) +#define WMR_NUM_OF_BANKS (8) /* the maximum number of bank */ +#define BYTES_PER_SECTOR (512) + +#define FTL_INFO_SECTION_SIZE FTL_CXT_SECTION_SIZE +#define FREE_SECTION_START FTL_CXT_SECTION_SIZE +#define DATA_SECTION_START (FTL_CXT_SECTION_SIZE + FREE_SECTION_SIZE) + +#define LOG_SECTION_SIZE (FREE_SECTION_SIZE - FREE_LIST_SIZE) + +#define FREE_SECTION_SIZE (20) +#define FREE_LIST_SIZE (3) + +#define FTL_AREA_SIZE (FTL_CXT_SECTION_SIZE + FREE_SECTION_SIZE + USER_SUBLKS_TOTAL) + +#define MAX_NUM_OF_MAP_TABLES (WMR_MAX_VB / (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) + (WMR_MAX_VB % (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) ? 1 : 0)) * (sizeof(UInt16)) +#define MAX_NUM_OF_EC_TABLES (WMR_MAX_VB / (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) + (WMR_MAX_VB % (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) ? 1 : 0)) * (sizeof(UInt32)) +#define MAX_NUM_OF_LOGCXT_MAPS (((LOG_SECTION_SIZE * WMR_MAX_PAGES_PER_BLOCK * WMR_NUM_OF_BANKS * sizeof(UInt16)) / (WMR_SECTOR_SIZE * WMR_SECTORS_PER_PAGE_MIN)) + (((LOG_SECTION_SIZE * WMR_MAX_PAGES_PER_BLOCK * WMR_NUM_OF_BANKS * sizeof(UInt16)) % (WMR_SECTOR_SIZE * WMR_SECTORS_PER_PAGE_MIN)) ? 1 : 0)) + +#define BBT_SIZE_PER_CS ((BLOCKS_PER_CS / 8) + (BLOCKS_PER_CS % 8 ? 1 : 0)) + +#if defined(FTL_SMALL_MERGE_BUFFER) && FTL_SMALL_MERGE_BUFFER +#define FTL_SIMPLEMERGE_MIN_PAGES (4) +#else +#define FTL_SIMPLEMERGE_MIN_PAGES (PAGES_PER_SUBLK >> 3) /* creates a 64K to 128K buffer in current units */ +#endif +#define FTL_RESTORE_MIN_PAGES (((FTL_AREA_SIZE * sizeof(FTLRestoreStruct)) - 1) / BYTES_PER_PAGE + 1) + +/* + * pstSimpleMergeDataBuffer is used in the following functions and must adhere to the following rules: + * 1. _DoSimpleMerge() - Must be aligned to BANKS_TOTAL pages and a power of 2. + * 2. _StoreFTLCxt() - Must be of size BANKS_TOTAL page at least. + * 3. _FTLRestore() - Must be of size FTL_RESTORE_MIN_PAGES at least. + */ +#define PAGES_PER_SIMPLE_MERGE_BUFFER (1 << (WMR_LOG2(WMR_MAX(FTL_SIMPLEMERGE_MIN_PAGES, FTL_RESTORE_MIN_PAGES) - 1) + 1)) + +/*****************************************************************************/ +/* Data structure for storing the FTL log block context definition */ +/*****************************************************************************/ +#ifdef AND_COLLECT_STATISTICS + +typedef struct +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwFTLWriteCnt; + UInt64 ddwFTLReadCnt; + UInt64 ddwDoMoveMergeCnt; + UInt64 ddwDoCopyMergeCnt1; /* case there is NO data to copy */ + UInt64 ddwDoCopyMergeCnt2; /* case there is data to copy */ + UInt64 ddwDoSimpleMergeCnt; + UInt64 ddwMoveD2FCnt; + UInt64 ddwFTLRestoreCnt; + UInt64 ddwReadDisturbHandleCall; + UInt64 ddwWearLevelCnt; + UInt64 ddwFlushCnt; +} FTLStatistics; + +#define FTL_STATISTICS_DESCREPTION { \ + "ddwPagesWrittenCnt", \ + "ddwPagesReadCnt", \ + "ddwFTLWriteCnt", \ + "ddwFTLReadCnt", \ + "ddwDoMoveMergeCnt", \ + "ddwDoCopyMergeCnt1", \ + "ddwDoCopyMergeCnt2", \ + "ddwDoSimpleMergeCnt", \ + "ddwMoveD2FCnt", \ + "ddwFTLRestoreCnt", \ + "ddwReadDisturbHandleCall", \ + "ddwWearLevelCnt", \ + "ddwFlushCnt", \ +} + +#endif /* AND_COLLECT_STATISTICS */ + +#define FTL_VERSION (0x46560001) +#define FTL_VERSION_NOT (~(FTL_VERSION)) + +/*****************************************************************************/ +/* Data structure for log block spare area */ +/*****************************************************************************/ +typedef struct +{ + UInt32 dwLogAge; /* log age - uses a global counter starting from 0 */ + UInt16 wVbn; /* the virtual block number of log block */ + UInt16 wLbn; /* the logical block number of log block */ + UInt16 *paPOffsetL2P; /* L2P page offset mapping table *//* size - PAGES_PER_SUBLK * sizeof(UInt16) functionality - maps pages of a logical block inside the block */ + UInt16 wFreePOffset; /* free page offset in log block *//* the next physical page to write to */ + UInt16 wNumOfValidLP; /* the number of valid page *//* the number of valid pages in the log - stay the same when rewriting a page */ + BOOL32 boolCopyMerge; /* can be copymerged or not *//* ??? */ + /* name sure this structure is aligned 16-bit */ +} LOGCxt; + +typedef struct +{ + UInt16 wLbn; + UInt16 wVbn; +} FTLReadRefreshStruct; + +/*****************************************************************************/ +/* Data structure for storing the FTL context definition */ +/*****************************************************************************/ +/* NOTICE !!! */ +/* this structure is used directly to load FTL context by WMR_MEMCPY*/ +/* so the byte pad of this structure must be 0 */ +typedef struct +{ + UInt32 dwAge; /* Cxt Write Age - Counter starting From 0xFFFFFFFF going down */ + + UInt32 dwWriteAge; /* counter starting from 0 - unique age of the first ftl write operation to the block */ + + UInt16 wNumOfFreeVb; /* number of free VB */ + UInt16 wFreeVbListTail; /* marks the first available VB in a cyclic list */ + UInt16 wWearLevelCounter; /* this counter is by the FTL to decide whether an Autowearlevel operation is needed after FTL_Write is done */ + + UInt16 awFreeVbList[FREE_SECTION_SIZE]; /* cyclic list of the free VBs */ + + UInt32 adwMapTablePtrs[MAX_NUM_OF_MAP_TABLES]; /* page address (Vpn) of the Map table pages in the Cxt block - only valid when boolFlashCxtIsValid is TRUE32 */ + UInt32 adwECTablePtrs[MAX_NUM_OF_EC_TABLES]; /* page address of the Erase Counter table */ + UInt32 adwLOGCxtMapPtrs[MAX_NUM_OF_LOGCXT_MAPS]; /* page address of the LOGCxt map table */ + + UInt16 * pawMapTable; /* cached map table logical blocks to virtual blocks - value will be recalculated in FTL_Init */ + UInt16 * pawECCacheTable; /* cached Erase counter table - value will be recalculated in FTL_Init - data is recovered from the last valid Erase Map in case of power failure */ + UInt16 * pawLOGCxtMapTable; /* pointer to the map of the logs - this is a pointer and will be calculated in the Init - data can be restored if the info is flushed */ + LOGCxt aLOGCxtTable[LOG_SECTION_SIZE + 1]; /* LOGCxt array */ + + UInt32 dwMetaWearLevelCounter; /* used to decide whether the index info super blocks need to be replaced or not (slows down VFL Cxt blocks wear) */ + UInt16 wOverErasedBlock; /* should not be used - mark the last erased vb before setting boolFlushECTable */ + + UInt16 awMapCxtVbn[FTL_CXT_SECTION_SIZE]; /* vb address of the FTL Cxt information */ + UInt32 dwCurrMapCxtPage; /* pointer to the last written Cxt info page */ + + BOOL32 boolFlashCxtIsValid; /* mark whether the FTLCxt on the flash is up to date or not */ + + // this code was added Apr 4th 2007 + UInt32 adwRCTablePtrs[MAX_NUM_OF_EC_TABLES]; /* page address of the Read Counter table */ + UInt16 * pawRCCacheTable; /* cached Erase counter table - value will be recalculated in FTL_Init - data is recovered from the last valid Erase Map in case of power failure */ + FTLReadRefreshStruct aFTLReadRefreshList[FTL_READ_REFRESH_LIST_SIZE]; + UInt32 dwRefreshListIdx; + UInt32 dwReadsSinceLastRefreshMark; + // this code was added Apr 20th 2007 + UInt32 adwStatPtrs[2]; // allocate 2 pages for stats +} FTLCxt2; + +typedef struct +{ + FTLCxt2 stFTLCxt; + UInt8 abReserved[((BYTES_PER_SECTOR - 2) * sizeof(UInt32)) - sizeof(FTLCxt2)]; + UInt32 dwVersion; + UInt32 dwVersionNot; +} FTLMeta; + +/*****************************************************************************/ +/* Data structure of the FTL context & virtual block mapping table definition*/ +/*****************************************************************************/ +/* NOTICE !!! */ +/* this structure is used directly to load FTL context by WMR_MEMCPY*/ +/* so the byte pad of this structure must be 0 */ + +/*****************************************************************************/ +/* Data structure for FTL context spare area */ +/*****************************************************************************/ + +/* + Spare area of the flash: + The implementation used here assumes a page has 12 free bytes in the redundant area to store data (index, age, etc). + Bytes 0-7 are used for data + Byte 8 - is currently reserved. + Byte 9 is used for data type - bits 6-7 of the byte is 00 for VFL spare types and 01 for FTL spare types. + Byte 10 is used to mark ECC error in LOGCxt reserved for Cxt + Byte 11 is currently reserved + */ + +/* NirW - possibly need to define the next two structures as compact (i.e. no alignment should be done by the compiler). */ + +/* spare layout for SLC & MLC */ +typedef struct +{ + UInt32 dwCxtAge; /* context age 0xFFFFFFFF --> 0x0 */ + UInt16 wLogicalNumber; /* status (confirm) mark */ + UInt8 bStatusMark; /* status (confirm) mark */ + UInt8 baReserved[1]; + UInt8 bECCMark; + UInt8 bSpareType; +} FTLCxtSpare; + +/* spare layout for SLC */ +typedef struct +{ + UInt32 dwLPOffset; + UInt32 dwWriteAge; + UInt8 bReserved; + UInt8 bSpareType; +} LOGSpare; + +typedef struct +{ + UInt16 wLbn; /* this struct can only handle 32K super blocks */ + UInt8 bSpareType; + UInt8 bIsBlkFull; /* 0 - block is full; 1 - page 0 is written; 2 - page 0 is empty; 3 - page 0 is invalid */ + UInt32 dwWriteAge; +} FTLRestoreStruct; + +FTLCxt2 * FTL_GetFTLCxt2Ptr(void); + +// defines +/* + FTL_SPARE_TYPE_LOG - log block (either not full or not fill consecutively + we should look for this mark in page 0 and in the last page of the block for recovery + */ +#define FTL_SPARE_TYPE_LOG 0x40 +/* + FTL_SPARE_TYPE_DATA - either originally data block or a log block filled from page 0 to the end (consecutively) - + look for this mark at the last page of the block + */ +#define FTL_SPARE_TYPE_DATA 0x41 + +#define FTL_SPARE_TYPE_CXT 0x42 /* used only in restore operation */ +#define FTL_SPARE_TYPE_CXT_INDEX 0x43 +#define FTL_SPARE_TYPE_CXT_MAP_TABLE 0x44 +#define FTL_SPARE_TYPE_CXT_LOGCXT_MAP 0x45 +#define FTL_SPARE_TYPE_CXT_EC_TABLE 0x46 +#define FTL_SPARE_TYPE_CXT_STAT 0x47 + +#define FTL_SPARE_IS_CXT_MARK(x) ((x) >= FTL_SPARE_TYPE_CXT_INDEX && (x) <= FTL_SPARE_TYPE_CXT_INVALID) + +#define FTL_SPARE_TYPE_FREE 0x48 /* this is not to be written on the flash but to use as a mark that a block can be erased */ +#define FTL_SPARE_TYPE_CXT_RC_TABLE 0x49 +#define FTL_SPARE_TYPE_CXT_INVALID 0x4F /* mark that the CXT saved is no longer relevant - write this mark before + executing any ftl writes */ + +/* + The ECC mark was originally in byte 10, but we have since shrunk to 10 total bytes of meta data. + The FMSS guarantees bytes 10 and 11 to be 0xFFFF. + To check ECC mark, check for any value besides 0xFF in either byte 8 or 10. + */ +#define FTL_SPARE_TYPE_LOCATION 9 /* the byte location of the spare type in the spare area */ +#define FTL_ECC_MARK_BYTE 8 /* the location of the byte in the spare that contains the mark */ +#define FTL_ECC_MARK_BYTE_LEGACY 10 /* the old location of the byte in the spare that contains the mark */ +#define FTL_ECC_MARK_WORD 2 /* the location of the word in the spare that contains the marks */ +#define FTL_ECC_MARK_MASK 0x00FF00FF /* use this mask on the 2nd word to check for ECC mark */ +#define FTL_TABLE_PTR_INVALID_VALUE 0xFFFFFFFF + +#define LOG_EMPTY_SLOT (0xFFFF) + +#endif /* _FTL_TYPES_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V.h new file mode 100644 index 0000000..ffa28f7 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_H__ +#define __L2V_H__ + +#include "L2V_Types.h" + + +extern L2V_t L2V; +extern UInt8 *L2V_root_depth; + + +#endif // __L2V_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Assert.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Assert.h new file mode 100644 index 0000000..e2e7279 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Assert.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_CASSERT_H__ +#define __L2V_CASSERT_H__ + +#define l2v_assert(e) WMR_ASSERT(e) + +#define CASSERT(x, name) typedef char __CASSERT_##name[(x) ? 1 : -1] + +#define l2v_assert_le(x, y) l2v_assert((x) <= (y)) +#define l2v_assert_lt(x, y) l2v_assert((x) < (y)) +#define l2v_assert_ge(x, y) l2v_assert((x) >= (y)) +#define l2v_assert_gt(x, y) l2v_assert((x) > (y)) +#define l2v_assert_eq(x, y) l2v_assert((x) == (y)) +#define l2v_assert_ne(x, y) l2v_assert((x) != (y)) + +#endif // __L2V_CASSERT_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Config.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Config.h new file mode 100644 index 0000000..e54ef7d --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Config.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_CONFIG_H__ +#define __L2V_CONFIG_H__ + +// Defines the minium page size--ONLY used for easier extent (logical range) configuration +#define L2V_MINPAGESIZE_BITS (b_4 + KiB_bits) + +// Defines the node size +#define L2V_CACHELINE 64 +#define L2V_NODE_SIZE L2V_CACHELINE + +// Defines the memory set aside for the node pool +#define L2V_NODEPOOL_MEM (MiB>>2) + +// Defines the size of a logical tree +#define L2V_TREE_BITS 15 + +// Repack periodicity +#define L2V_REPACK_PERIOD 200 + + +#endif // __L2V_CONFIG_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Defines.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Defines.h new file mode 100644 index 0000000..70d4cdd --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Defines.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_DEFINES_H__ +#define __L2V_DEFINES_H__ + +// Shortcuts for the config +#define b_1 0 +#define b_2 1 +#define b_4 2 +#define b_8 3 +#define b_16 4 +#define b_32 5 +#define b_64 6 +#define b_128 7 +#define b_256 8 +#define b_512 9 +#define KiB_bits 10 +#define MiB_bits 20 +#define GiB_bits 30 +#define TiB_bits 40 +#define KiB (1 << KiB_bits) +#define MiB (1 << MiB_bits) +#define GiB (1 << GiB_bits) +#define TiB (1 << TiB_bits) + +#include "L2V_Config.h" + + +// Pointers to NAND +// VPN bits were originally defined seperately as superblock bits, page offset bits; +// combining them results in more flexibility. 10+3 was supposed to represent 8192 max superblocks; +// 12 represented 4096 max pages per superblock. +#define L2V_BITS_VPN (10+3+12) +#define L2V_MAX_SB (1 << L2V_BITS_SB) +#define L2V_BITS_NAND_SPAN (32 - 2 - L2V_BITS_VPN) + + +// Node size +#define L2V_CONTIG_ELEM_SMALL 4 +#define L2V_CONTIG_ELEM_LARGE 6 +#define L2V_MIN_CONTIG_PER_NODE (L2V_NODE_SIZE / L2V_CONTIG_ELEM_LARGE) +#define L2V_MAX_CONTIG_PER_NODE (L2V_NODE_SIZE / L2V_CONTIG_ELEM_SMALL) + + +// Memory usage +#define L2V_NODEPOOL_COUNT (L2V_NODEPOOL_MEM / L2V_NODE_SIZE) +#define L2V_BITS_NODEIDX 16 +#define L2V_BITS_NODE_SPAN (32 - 2 - L2V_BITS_NODEIDX) + + +// Parameters +#define L2V_SUCKUP_CHILDREN_MAX 3 +#define L2V_TRACK_VALID 0 + + +// Tree size +#define L2V_TREE_SIZE (1 << L2V_TREE_BITS) +#define L2V_TREE_MASK (L2V_TREE_SIZE - 1) +#define L2V_MAX_TREE_DEPTH 32 +#define L2V_MAX_TREE_DEPTH_UPD 36 +#define L2V_TREE_DEPTH_REPACK 26 + + +// Magic numbers +#define L2V_CONTIG_FREE_SIG 0xFFFFFFFF +// These represent token values; normally, when we move along a span, we add to vpn and +// subtract from span. If it's a token--such as "missing" or "deallocated"--we should +// subtract from span, but not add to vpn, because it would change the meaning. +#define L2V_VPN_DEALLOC ((1< biggestSize) { + biggest = i; + biggestSize = L2V.TreeNodes[i]; + } + } + + return biggest; +} + +static void Forget(lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node and size + lPtr_t thisPtr; + ContigUnpacked_t cu; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + Forget(L2V_IDX_TO_NODE(cu.u.nodeIdx)); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); +} + +static void ReplaceRoot(UInt32 tree) +{ + ContigUnpacked_t cu; + + // Set up contig + cu.isNodePtr = 0; + cu.hasSpanOF = 0; + cu.u.n.vpn = L2V_VPN_MISS; + cu.span = 0; // Just so it's consistent... value doesn't matter in root + + // Update tree + L2V.Tree[tree] = LPTR_PACK_NAND(cu); + L2V.TreeNodes[tree] = 0; + L2V_root_depth[tree] = 0; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Forget.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Forget.h new file mode 100644 index 0000000..0bb08cf --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Forget.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_FORGET_H__ +#define __L2V_FORGET_H__ + + +#include "L2V_Types.h" + + +extern void L2V_ForgetBiggestTree(void); + + +#endif // __L2V_FORGET_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Free.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Free.c new file mode 100644 index 0000000..05633a6 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Free.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#include "L2V_Extern.h" + +#if ENABLE_L2V_TREE + +void L2V_Free(void) +{ + if (0 == L2V.numRoots) + return; + + // Free arrays: + + if (NULL != L2V.Tree) { + WMR_FREE(L2V.Tree, L2V.numRoots * sizeof(lPtr_t)); + L2V.Tree = NULL; + } + + if (NULL != L2V.TreeNodes) { + WMR_FREE(L2V.TreeNodes, L2V.numRoots * sizeof(UInt32)); + L2V.TreeNodes = NULL; + } + + if (NULL != L2V.UpdatesSinceRepack) { + WMR_FREE(L2V.UpdatesSinceRepack, L2V.numRoots * sizeof(UInt32)); + L2V.UpdatesSinceRepack = NULL; + } + + if (NULL != L2V.Pool.Node) { + WMR_FREE(L2V.Pool.Node, L2V_NODEPOOL_MEM); + L2V.Pool.Node = NULL; + } + + if(L2V_root_depth != NULL) + { + WMR_FREE(L2V_root_depth, L2V.numRoots); + L2V_root_depth = NULL; + } + +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.c new file mode 100644 index 0000000..abbf1f0 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Funcs.h" + +// Empty + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.h new file mode 100644 index 0000000..221fa95 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Funcs.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_FUNCS_H__ +#define __L2V_FUNCS_H__ + + +#include "L2V_Types.h" + + +BOOL32 L2V_Init(UInt32 numLbas, UInt32 numSBs, UInt32 pagesPerSB); +extern void L2V_Search_Init(L2V_SearchCtx_t *c); +extern void L2V_Search(L2V_SearchCtx_t *c); +extern void L2V_Update(UInt32 lba, UInt32 size, UInt32 vpn); +extern void L2V_Repack(UInt32 tree); +extern void L2V_ForgetBiggestTree(void); + + +// Macros + +#define _L2V_NODE_ITERATE_RESUME(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) \ + while ((_nodeByteOfs) <= ((_nodeSize)-sizeof(lPtr_t))) { \ + (_destPtr) = *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]); \ + if (L2V_CONTIG_FREE_SIG == (_destPtr)) { \ + break; \ + } \ + if (LPTR_IS_NODEPTR(_destPtr)) { \ + LPTR_UNPACK_NODE(_destPtr, _cu); \ + } else { \ + LPTR_UNPACK_NAND(_destPtr, _cu); \ + } \ + if ((_cu).hasSpanOF) { \ + (_nodeSize) -= sizeof(UInt16); \ + (_cu).span += *(UInt16*)&(_node)->bytes[_nodeSize] << (LPTR_IS_NODEPTR(_destPtr) ? L2V_BITS_NODE_SPAN : L2V_BITS_NAND_SPAN); \ + l2v_assert_le(_nodeByteOfs, ((_nodeSize)-sizeof(lPtr_t))); \ + } \ + l2v_assert_ne((_cu).span, 0); + +#define _L2V_NODE_ITERATE(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) \ + (_nodeByteOfs) = 0; \ + (_nodeSize) = L2V_NODE_SIZE; \ + _L2V_NODE_ITERATE_RESUME(_node, _nodeByteOfs, _nodeSize, _cu, _destPtr) + + +#define _L2V_NODE_ITERATE_NEXT(_nodeByteOfs) \ + (_nodeByteOfs) += sizeof(lPtr_t); + +#define _L2V_NODE_ITERATE_END_NOP } + +#define _L2V_NODE_ITERATE_END(_nodeByteOfs) \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + } + +#define _L2V_NODE_PUSH_CONTIG_NODE(_node, _nodeByteOfs, _nodeSize, _cu) \ + { \ + l2v_assert_ne((_cu).span, 0); \ + (_cu).hasSpanOF = 1; \ + *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]) = LPTR_PACK_NODE(_cu); \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + (_nodeSize) -= sizeof(UInt16); \ + *(UInt16*)&(_node)->bytes[_nodeSize] = (_cu).span >> L2V_BITS_NODE_SPAN; \ + } +#define _L2V_NODE_PUSH_CONTIG_NAND(_node, _nodeByteOfs, _nodeSize, _cu) \ + { \ + l2v_assert_ne((_cu).span, 0); \ + (_cu).hasSpanOF = 0; \ + if ((_cu).span >= (1 << L2V_BITS_NAND_SPAN)) { \ + (_cu).hasSpanOF = 1; \ + (_nodeSize) -= sizeof(UInt16); \ + *(UInt16*)&(_node)->bytes[_nodeSize] = (_cu).span >> L2V_BITS_NAND_SPAN; \ + } \ + *(lPtr_t*)(&(_node)->bytes[_nodeByteOfs]) = LPTR_PACK_NAND(_cu); \ + (_nodeByteOfs) += sizeof(lPtr_t); \ + } +#define _L2V_NODE_PUSH_CONTIG(_node, _nodeByteOfs, _nodeSize, _cu) \ + do { \ + if ((_cu).isNodePtr) { \ + _L2V_NODE_PUSH_CONTIG_NODE(_node, _nodeByteOfs, _nodeSize, _cu); \ + } else { \ + _L2V_NODE_PUSH_CONTIG_NAND(_node, _nodeByteOfs, _nodeSize, _cu); \ + } \ + } while (0) +#define _L2V_CONTIG_SIZE(_cu) (sizeof(lPtr_t) + (((_cu).isNodePtr || ((_cu).span >= (1 << L2V_BITS_NAND_SPAN))) ? sizeof(UInt16) : 0)) + +#define _L2V_NODE_FILL(_node, _nodeByteOfs, _nodeSize) \ + do { \ + WMR_MEMSET(&(_node)->bytes[_nodeByteOfs], 0xFF, (_nodeSize) - (_nodeByteOfs)); \ + } while (0) + + +#define min(a, b) ((a) < (b) ? (a) : (b)) + + + + +#endif // __L2V_FUNCS_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Init.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Init.c new file mode 100644 index 0000000..d7c556c --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Init.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Mem.h" + + +// Declare our L2V context structure here +L2V_t L2V; +UInt8 *L2V_root_depth; + +// Functions +BOOL32 L2V_Init(UInt32 numLbas, UInt32 numSBs, UInt32 pagesPerSB) +{ + UInt32 i; + Int32 j; + ContigUnpacked_t cu; + + // Set number of superblocks for valid accounting division + L2V.numSBs = numSBs; + L2V.pagesPerSB = pagesPerSB; + if ((numSBs * pagesPerSB) >= L2V_VPN_SPECIAL) { + WMR_PANIC("Tree bitspace not sufficient for geometry %dx%d: please re-adjust", numSBs, pagesPerSB); + } + + // Set tree version + L2V.treeVersion = 0; + + // Calculate roots + L2V.numRoots = (numLbas >> L2V_TREE_BITS) + 1; + + // Allocate arrays + L2V.Tree = WMR_MALLOC(L2V.numRoots * sizeof(lPtr_t)); + l2v_assert_ne(L2V.Tree, NULL); + L2V.TreeNodes = WMR_MALLOC(L2V.numRoots * sizeof(UInt32)); + l2v_assert_ne(L2V.TreeNodes, NULL); + L2V.UpdatesSinceRepack = WMR_MALLOC(L2V.numRoots * sizeof(UInt32)); + l2v_assert_ne(L2V.UpdatesSinceRepack, NULL); + L2V_root_depth = WMR_MALLOC(L2V.numRoots); + l2v_assert_ne(L2V_root_depth , NULL); + for (i = 0; i < L2V.numRoots; i++) { + L2V_root_depth[i] = 0; + } + + // Empty roots; default to miss + cu.hasSpanOF = 0; + cu.u.n.vpn = L2V_VPN_MISS; + cu.span = 0; + for (i = 0; i < L2V.numRoots; i++) { + L2V.Tree[i] = LPTR_PACK_NAND(cu); + } + + // Reset periodic repacker variables + L2V.RepackCounter = 0; + + // Allocate the node pool + L2V.Pool.Node = (lNode_t*)WMR_MALLOC(L2V_NODEPOOL_MEM); + if (NULL == L2V.Pool.Node) { + return FALSE32; + } + + // Finally, put all nodes in the free pool + L2V.Pool.FreePtr = NULL; + L2V.Pool.FreeCount = 0; + for (j = L2V_NODEPOOL_COUNT-1; j >= 0; j--) { + _L2V_FreeNode(&L2V.Pool.Node[j]); + } + + return TRUE32; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.c new file mode 100644 index 0000000..7ebbe11 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" +#include "L2V_Mem.h" +#include "L2V_Assert.h" + + +void _L2V_FreeNode(lNode_t *node) +{ + static int freeCount = 0; + + freeCount++; + + l2v_assert_ge(node, &L2V.Pool.Node[0]); + l2v_assert_le(node, &L2V.Pool.Node[L2V_NODEPOOL_COUNT]); + + node->nextFreePtr = L2V.Pool.FreePtr; + L2V.Pool.FreePtr = node; + L2V.Pool.FreeCount++; +} + + +lNode_t *_L2V_AllocNode() +{ + lNode_t *ret; + static int allocCount = 0; + + allocCount++; + + ret = (lNode_t*)L2V.Pool.FreePtr; + if (NULL != ret) { + L2V.Pool.FreePtr = L2V.Pool.FreePtr->nextFreePtr; + L2V.Pool.FreeCount--; + } + l2v_assert_ne(ret, NULL); + + return ret; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.h new file mode 100644 index 0000000..f744442 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Mem.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_MEM_H__ +#define __L2V_MEM_H__ + + +#include "L2V_Types.h" + + +extern void _L2V_FreeNode(lNode_t *node); +extern lNode_t *_L2V_AllocNode(void); // Warning: may return NULL; up to caller to handle gracefully + + +#endif // __L2V_MEM_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.c new file mode 100644 index 0000000..58e411e --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Print.h" +#include "L2V_Funcs.h" +#include "L2V.h" +#include "L2V_Types.h" + + +#define PRINT_MAXPATH 0 + + +// Prototypes + +static int L2V_GetUsage(lNode_t *node, UInt32 *used, UInt32 *total, UInt32 *nodes, UInt32 totalSpan, BOOL32 isMax); + + +// Functions + +void L2V_PrintPtr(lPtr_t lptr) +{ + ContigUnpacked_t cu; + LPTR_UNPACK(lptr, cu); + L2V_PrintCU(&cu); +} + +void L2V_PrintCU(ContigUnpacked_t *cu) +{ + if (cu->isNodePtr) + printf("[Node]"); + else + printf("[NAND]"); + + if (cu->hasSpanOF) + printf("o"); + else + printf("-"); + + if (cu->isNodePtr) { + printf("[idx:%d][span:%d]", cu->u.nodeIdx, cu->span); + } else { + printf("[vpn:%d][span:%d]", cu->u.n.vpn, cu->span); + } + + printf("\n"); +} + + +void L2V_PrintNode(lNode_t *node) +{ + UInt32 nOfs, nodeSize; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + L2V_PrintCU(&cu); + } _L2V_NODE_ITERATE_END(nOfs); +} + + +void L2V_PrintUsage(UInt32 tree) +{ + UInt32 used, total, nodes, maxdepth; + + ContigUnpacked_t cu; + + used = total = nodes = maxdepth = 0; + printf("Max depth path: "); + printf("digraph G {\n"); + LPTR_UNPACK(L2V.Tree[tree], cu); + if (cu.isNodePtr) { + maxdepth = L2V_GetUsage(L2V_IDX_TO_NODE(cu.u.nodeIdx), &used, &total, &nodes, L2V_TREE_SIZE, 1); + } + printf("}\n"); + printf("\nUsage tree %d: %.2f, nodes: %d, maxdepth: %d\n", tree, (float)used/(float)total, nodes, maxdepth); + printf("Nodes calc: %d tally: %d\n\n", nodes, L2V.TreeNodes[tree]); + if (nodes != L2V.TreeNodes[tree]) while(1);//DP + //l2v_assert_eq(nodes, L2V_NODEPOOL_COUNT - L2V.Pool.FreeCount); // Only valid when using 1 tree +} + +static int L2V_GetUsage(lNode_t *node, UInt32 *used, UInt32 *total, UInt32 *nodes, UInt32 totalSpan, BOOL32 isMax) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + UInt32 sumSpan; + lPtr_t thisPtr, maxNode; + UInt32 depth, maxDepth, maxSpan; + ContigUnpacked_t cu; + + // Walk through + (*nodes)++; + maxDepth = 0; + sumSpan = 0; + + // Iterate through the node, + L2V_PrintNode(node); + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + printf("%d -> %d;\n", (int)L2V_NODE_TO_IDX(node), cu.u.nodeIdx); // DOT output + l2v_assert_ne(cu.u.nodeIdx, 65535); + l2v_assert_ne(L2V_IDX_TO_NODE(cu.u.nodeIdx), node); + l2v_assert_ne(cu.span, 0); + depth = L2V_GetUsage(L2V_IDX_TO_NODE(cu.u.nodeIdx), used, total, nodes, cu.span, 0); + if (depth > maxDepth) { + maxDepth = depth; + maxNode = thisPtr; + maxSpan = cu.span; + } + } + sumSpan += cu.span; + l2v_assert_le(cu.span, 32768); + } _L2V_NODE_ITERATE_END(nOfs); + *used += nOfs; + *total += sizeof(lNode_t); + printf("%d [label=\"us:%.2f\\nsp:%.2f\",shape=box,style=filled,color=\"1.0 %.2f 1.0\"];\n", (int)L2V_NODE_TO_IDX(node), (float)nOfs/sizeof(lNode_t), (float)totalSpan/L2V_TREE_SIZE, (float)nOfs/sizeof(lNode_t)); // DOT output + + if (sumSpan != totalSpan) { + printf("Sum: %d, total: %d\n", sumSpan, totalSpan); + L2V_PrintNode(node); + } + l2v_assert_eq(sumSpan, totalSpan); + l2v_assert_ne(nOfs, 0); + +#if PRINT_MAXPATH + if (maxDepth && isMax) { + printf("<-%d", maxNode.node.nodeIdx); + L2V_GetUsage(L2V_LPTR_TO_NODE(maxNode), &nOfs, &nOfs, &nOfs, maxSpan, 1); + } +#endif + + return maxDepth+1; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.h new file mode 100644 index 0000000..da1e5ce --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Print.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_PRINT_H__ +#define __L2V_PRINT_H__ + + +#include "L2V_Types.h" + + +extern void L2V_PrintPtr(lPtr_t lptr); +extern void L2V_PrintCU(ContigUnpacked_t *cu); +extern void L2V_PrintNode(lNode_t *node); +extern void L2V_PrintUsage(UInt32 tree); + + +#endif // __L2V_PRINT_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.c new file mode 100644 index 0000000..aabc79b --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define AND_TRACE_LAYER FTL + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Repack.h" +#include "L2V.h" +#include "L2V_Types.h" +#include "L2V_Mem.h" +#include "L2V_Funcs.h" + + +#define REPACK_MAX_NODES (L2V_TREE_SIZE/L2V_MIN_CONTIG_PER_NODE) +#define REPACK_TREE_LOG_SIZE 32 + +typedef struct { + lNode_t *bottom[REPACK_MAX_NODES]; + UInt32 bottomSpan[REPACK_MAX_NODES]; + UInt32 bottomIdx; + UInt32 bottom_nOfs; + UInt32 bottom_nodeSize; + UInt32 repackTreeLog[REPACK_TREE_LOG_SIZE]; + UInt32 repackTreeLogIdx; +} RepackCtx_t; + + +// Static definitions +static void CopyAndDestroy(RepackCtx_t *r, lNode_t *node); +static int Rebuild(RepackCtx_t *r); +static void ReplaceRoot(RepackCtx_t *r, UInt32 tree); + + +void L2V_PeriodicRepack() +{ + Int32 best; + UInt32 merit, bestMerit, i; + + // Check if it's appropriate or not + if (L2V.RepackCounter < L2V_REPACK_PERIOD) { + return; + } + L2V.RepackCounter = 0; + + // Find best candidate; merit==updates + bestMerit = 0; + best = -1; + for (i = 0; i < L2V.numRoots; i++) { + merit = L2V.UpdatesSinceRepack[i]; + if (merit >= bestMerit) { + bestMerit = merit; + best = i; + } + } + + l2v_assert_ne(best, -1); + + L2V_Repack(best); +} + + +// WARNING: NOT REENTRANT +static RepackCtx_t r; +void L2V_Repack(UInt32 tree) +{ + lNode_t *root; + ContigUnpacked_t cu; + + LPTR_UNPACK(L2V.Tree[tree], cu); + + // Trying to repack a rootptr? Abort... + if (!cu.isNodePtr) { + return; + } + + WMR_TRACE_1(Repack, START, tree); + + // Up tree version for search-update coherency + L2V.treeVersion++; + + // Create list of new bottom layer + r.bottomIdx = 0; + r.bottom_nOfs = 0; + r.bottom_nodeSize = L2V_NODE_SIZE; + WMR_MEMSET(r.bottom, 0, REPACK_MAX_NODES * sizeof(r.bottom[0])); + WMR_MEMSET(r.bottomSpan, 0, REPACK_MAX_NODES * sizeof(r.bottomSpan[0])); + + // Recurse and destroy + root = L2V_IDX_TO_NODE(cu.u.nodeIdx); + CopyAndDestroy(&r, root); + + l2v_assert_ne(r.bottom_nOfs, 0); + + // Fill rest with "empty" markers + _L2V_NODE_FILL(r.bottom[r.bottomIdx], r.bottom_nOfs, r.bottom_nodeSize); + + // Rebuild hierarchy + L2V.TreeNodes[tree] = Rebuild(&r); + + // Replace root + ReplaceRoot(&r, tree); + + // Clear repack counter + L2V.UpdatesSinceRepack[tree] = 0; + + + // Log which tree we repacked + if (r.repackTreeLogIdx >= REPACK_TREE_LOG_SIZE) { + r.repackTreeLogIdx = 0; + } + r.repackTreeLog[r.repackTreeLogIdx] = tree; + r.repackTreeLogIdx++; + + WMR_TRACE_0(Repack, END); +} + + +static void CopyAndDestroy(RepackCtx_t *r, lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + ContigUnpacked_t cu; + lPtr_t thisPtr; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + CopyAndDestroy(r, L2V_IDX_TO_NODE(cu.u.nodeIdx)); + } else { + // Would be full? Move along... + if ((r->bottom_nOfs + _L2V_CONTIG_SIZE(cu)) > r->bottom_nodeSize) { + // Fill rest with "empty" markers + _L2V_NODE_FILL(r->bottom[r->bottomIdx], r->bottom_nOfs, r->bottom_nodeSize); + + r->bottomIdx++; + l2v_assert_lt(r->bottomIdx, REPACK_MAX_NODES); + } + + // Allocate node if necessary + if (NULL == r->bottom[r->bottomIdx]) { + // Allocate... + r->bottom[r->bottomIdx] = _L2V_AllocNode(); + r->bottom_nOfs = 0; + r->bottom_nodeSize = L2V_NODE_SIZE; + } + + // Copy out + _L2V_NODE_PUSH_CONTIG(r->bottom[r->bottomIdx], r->bottom_nOfs, r->bottom_nodeSize, cu); + r->bottomSpan[r->bottomIdx] += cu.span; + l2v_assert_le(cu.span, L2V_TREE_SIZE); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); +} + + +static int Rebuild(RepackCtx_t *r) +{ + lNode_t *thisBranch; + UInt32 nOfs, nodeSize, thisSpan, i, branchIdx; + ContigUnpacked_t cu; + int nodeCount; + + nodeCount = r->bottomIdx+1; + while (r->bottomIdx > 0) { + thisBranch = _L2V_AllocNode(); + nodeCount++; + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + thisSpan = 0; + branchIdx = 0; + + // Rebuild this layer + for (i = 0; i <= r->bottomIdx; i++) { + cu.isNodePtr = 1; + cu.u.nodeIdx = L2V_NODE_TO_IDX(r->bottom[i]); + cu.span = r->bottomSpan[i]; + + if ((nOfs + _L2V_CONTIG_SIZE(cu)) > nodeSize) { + // Fill rest with "empty" markers + _L2V_NODE_FILL(thisBranch, nOfs, nodeSize); + + // Place it down and get a new one + r->bottom[branchIdx] = thisBranch; + r->bottomSpan[branchIdx] = thisSpan; + branchIdx++; + thisBranch = _L2V_AllocNode(); + nodeCount++; + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + thisSpan = 0; + } + + _L2V_NODE_PUSH_CONTIG(thisBranch, nOfs, nodeSize, cu); + thisSpan += cu.span; + } + + l2v_assert_ne(nOfs, 0); + + r->bottom[branchIdx] = thisBranch; + r->bottomSpan[branchIdx] = thisSpan; + // Fill rest with "empty" markers + _L2V_NODE_FILL(thisBranch, nOfs, nodeSize); + + // Make sure the repack didn't munge the root node's spans + if (0 == branchIdx) { + l2v_assert_eq(thisSpan, L2V_TREE_SIZE); + } + + // Get ready for the next round + r->bottomIdx = branchIdx; + } + + return nodeCount; +} + + +static void ReplaceRoot(RepackCtx_t *r, UInt32 tree) +{ + ContigUnpacked_t cu; + l2v_assert_eq(r->bottomIdx, 0); + cu.u.nodeIdx = L2V_NODE_TO_IDX(r->bottom[0]); + cu.hasSpanOF = 0; + cu.span = 0; + L2V.Tree[tree] = LPTR_PACK_NODE(cu); + if (!LPTR_IS_NODEPTR(L2V.Tree[tree])) { + L2V_root_depth[tree] = 0; + } +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.h new file mode 100644 index 0000000..6086f84 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Repack.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_REPACK_H__ +#define __L2V_REPACK_H__ + + +#include "WMROAM.h" + +// Functions + +extern void L2V_PeriodicRepack(void); +extern void L2V_Repack(UInt32 tree); + + +#endif // __L2V_REPACK_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Search.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Search.c new file mode 100644 index 0000000..af0867c --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Search.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" +#include "L2V_Funcs.h" + + +void L2V_Search_Init(L2V_SearchCtx_t *c) +{ + c->next_lba = 0xffffffff; + c->last_node = NULL; + c->span = 0; +} + + +static BOOL32 HitCache(L2V_SearchCtx_t *c) +{ + ContigUnpacked_t cu; + lPtr_t thisPtr; + + + if ((c->treeVersion == L2V.treeVersion) && (c->lba == c->next_lba) && (NULL != c->last_node)) { + // Sequential HIT + _L2V_NODE_ITERATE_RESUME(c->last_node, c->next_nOfs, c->nodeSize, cu, thisPtr) { + if (cu.isNodePtr) + break; + + c->vpn = cu.u.n.vpn; + c->fromStart = 0; + c->span = cu.span; + + _L2V_NODE_ITERATE_NEXT(c->next_nOfs); // This will move nOfs along + c->next_lba = c->lba + c->span; + return TRUE32; + + } _L2V_NODE_ITERATE_END_NOP; + } + + // Clear search history + c->next_lba = 0xffffffff; + c->last_node = NULL; + + return FALSE32; +} + + +void L2V_Search(L2V_SearchCtx_t *c) +{ + UInt32 targTree, targTofs; + UInt32 thisStart, thisMax; + UInt32 nOfs, nodeSize; // Byte offset within the node, and node effective size + ContigUnpacked_t cu, thiscu; + lNode_t *node = NULL; + lPtr_t thisPtr; + + if (HitCache(c)) { + return; + } + + // Determine first root + targTree = c->lba >> L2V_TREE_BITS; + targTofs = c->lba & L2V_TREE_MASK; + l2v_assert_lt(targTree, L2V.numRoots); + + c->level = 0; + thisStart = 0; + c->vpn = L2V_VPN_MISS; + LPTR_UNPACK(L2V.Tree[targTree], cu); + thiscu.span = L2V_TREE_SIZE; + c->next_nOfs = 0; + + // Search from top down + while (c->level < L2V_MAX_TREE_DEPTH) { + // Down and next + // Decode node pointer + if (!cu.isNodePtr) { + // Terminal case--pointer to physical location; calculate relative offset... + c->vpn = cu.u.n.vpn; + c->fromStart = targTofs - thisStart; + if (cu.u.n.vpn < L2V_VPN_SPECIAL) { + c->vpn += c->fromStart; + } + c->span = thiscu.span - c->fromStart; + // Set up return case for sequential searching + c->last_node = node; + c->next_lba = c->lba + c->span; + c->treeVersion = L2V.treeVersion; + // c->next_nOfs is populated from code below, i.e. the previous iteration of this while loop + + // Is it getting really big? Do some preventative maintenence... + if (c->level >= L2V_TREE_DEPTH_REPACK) { + L2V_Repack(targTree); + } + return; + } + + // Walk through + node = L2V_IDX_TO_NODE(cu.u.nodeIdx); + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + // Calculate endpoint + thisMax = thisStart + thiscu.span; + + // Are we in range? + if (targTofs < thisMax) { + // HIT! (Left-hand side implied by order of search.) + cu = thiscu; + _L2V_NODE_ITERATE_NEXT(nOfs); + c->next_nOfs = nOfs; + c->nodeSize = nodeSize; + goto decodePtr; + } + + // Move along in the node + thisStart = thisMax; + } _L2V_NODE_ITERATE_END(nOfs); + + WMR_PANIC("NAND index: bad tree: targTofs %d, level %d\n", targTofs, c->level); + +decodePtr: + // Resume here so we can check the while() condition + c->level++; + } + + l2v_assert(0); // Should never get here; otherwise, the tree is too deep (or recursive or pointing to randomness) +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.c new file mode 100644 index 0000000..c1009cc --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "L2V.h" +#include "L2V_Funcs.h" +#include "L2V_Print.h" +#include +#include + +L2V_t L2V; + + +#define LAST_TREE_TEST 16 +#define SIMPLE_SIZE (L2V_TREE_SIZE*LAST_TREE_TEST) + + +// Prototypes +static void RandomTest(void); +static void SequentialTest(void); +static void Simple_Init(void); +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn); +static void Simple_Lookup(UInt32 lba, UInt32 *vpn); + +void Usage(int argc, char** argv) +{ + printf("Usage: %s s OR %s r (for sequential and random, respectively\n", argv[0], argv[0]); + exit(-1); +} + +int test = 0; + +int main(int argc, char** argv) +{ + L2V_Init(SIMPLE_SIZE, (L2V_VPN_SPECIAL-1) / 8192, 8192); + + if (argc == 2) { + if ('r' == argv[1][0]) { + test = 0; + } else if ('s' == argv[1][0]) { + test = 1; + } else { + Usage(argc, argv); + } + } + if (argc > 2) { + Usage(argc, argv); + } + + if (0 == test) { + RandomTest(); + } else { + SequentialTest(); + } + + return 0; +} + + +#define MAXLEN 512 +static void RandomTest() { + UInt32 lba, size, vpn; + UInt32 i, svpn; + L2V_SearchCtx_t c; + + L2V_Search_Init(&c); + + Simple_Init(); + + sranddev(); + + while (1) { + lba = rand() % ((L2V_TREE_SIZE*LAST_TREE_TEST)-MAXLEN); + size = (rand() % (MAXLEN-1))+1; + vpn = rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + + printf("[UPD: lba:%d, size:%d, vpn:%d]\n", lba, size, vpn); + L2V_Update(lba, size, vpn); + Simple_Update(lba, size, vpn); + //printf("\n"); + //L2V_PrintNode(L2V_LPTR_TO_NODE(L2V.Tree[0])); + L2V_PrintUsage(0); + + + // Validate entire range + int maxlevel=0; + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_Lookup(i, &svpn); + c.lba = i; + L2V_Search(&c); + if (c.level > maxlevel) maxlevel = c.level; + if (svpn != c.vpn) { + printf("\n\n\n"); + printf("====================\n"); + printf("MISMATCH lba:%d\n", i); + printf("--------------------\n"); + printf("Simple vpn:%d\n", svpn); + printf("Lookup vpn:%d\n", c.vpn); + } + l2v_assert_eq(svpn, c.vpn); + } + printf("maxlevel: %d\n", maxlevel); + l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH); + +#if 0 + if (repack++ > 10) { + printf("Repacking tree %d...\n", nextRepack); + L2V_Repack(nextRepack); + L2V_PrintUsage(nextRepack); + repack = 0; + nextRepack = (nextRepack + 1) % LAST_TREE_TEST; + } +#endif + } +} + +static void SequentialTest() { + UInt32 lba, size, vpn; + UInt32 i, svpn; + L2V_SearchCtx_t c; + + L2V_Search_Init(&c); + + Simple_Init(); + + sranddev(); + + lba = 0; + size = 0; + vpn = 1; + + while (1) { + lba += size; + size = (rand() % (MAXLEN-1))+1; + if ((lba + size) >= L2V_TREE_SIZE) { + lba = 0; + } + if ((rand() & 3) == 0) { + vpn = rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + } + while (((vpn + size) & ((1<<(L2V_BITS_VPN-1))-1)) < vpn) { + vpn = rand() % ((1<<(L2V_BITS_VPN-1))-size-1); + } + + printf("[UPD: lba:%d, size:%d, vpn:%d]\n", lba, size, vpn); + L2V_Update(lba, size, vpn); + Simple_Update(lba, size, vpn); + L2V_PrintUsage(0); + vpn += size; + + + // Validate entire range + int maxlevel=0; + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_Lookup(i, &svpn); + c.lba = i; + L2V_Search(&c); + if (c.level > maxlevel) maxlevel = c.level; + if (svpn != c.vpn) { + printf("\n\n\n"); + printf("====================\n"); + printf("MISMATCH lba:%d\n", i); + printf("--------------------\n"); + printf("Simple vpn:%d\n", svpn); + printf("Lookup vpn:%d\n", c.vpn); + } + l2v_assert_eq(svpn, c.vpn); + } + printf("maxlevel: %d\n", maxlevel); + l2v_assert_lt(maxlevel, L2V_MAX_TREE_DEPTH); + } +} + + +UInt32 Simple_vpn[SIMPLE_SIZE]; + +static void Simple_Init() +{ + UInt32 i; + + for (i = 0; i < SIMPLE_SIZE; i++) { + Simple_vpn[i] = L2V_VPN_MISS; + } +} + + +static void Simple_Update(UInt32 lba, UInt32 size, UInt32 vpn) +{ + while (size) { + Simple_vpn[lba] = vpn; + + // Iterate + lba++; + if (vpn < L2V_VPN_SPECIAL) { + vpn++; + } + size--; + } +} + + +static void Simple_Lookup(UInt32 lba, UInt32 *vpn) +{ + *vpn = Simple_vpn[lba]; +} + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.mak b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.mak new file mode 100644 index 0000000..5b90ffd --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Test.mak @@ -0,0 +1,28 @@ +OBJS=L2V_Test.o L2V_Funcs.o L2V_Init.o L2V_Mem.o L2V_Search.o L2V_Update.o L2V_Valid.o L2V_Types.o L2V_Print.o L2V_Repack.o L2V_Forget.o L2V_Free.o WMROAM.o +LINK_TARGET=L2V_Test +REBUILDABLES=$(OBJS) $(LINK_TARGET) + +.PHONY: all +all: copythem $(LINK_TARGET) cleanthem + # + +.PHONY: copythem +copythem: + cp WMROAM-test.h WMROAM.h + cp WMROAM-test.c WMROAM.c + cp WMRFeatures-test.h WMRFeatures.h + +.PHONY: cleanthem +cleanthem: + rm WMROAM.c WMROAM.h WMRFeatures.h + +$(LINK_TARGET): $(OBJS) + gcc -g -o $@ $^ -Wall + +.PHONY: clean +clean: + rm -f $(REBUILDABLES) + rm WMROAM.c WMROAM.h WMRFeatures.h + +%.o: %.c + gcc -g -o $@ -c $< -Wall -I. diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.c new file mode 100644 index 0000000..ceab55b --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V_Defines.h" +#include "L2V_Types.h" + + +BOOL32 _L2V_NodeBig_PushContig(lNodeBig_t *big, ContigUnpacked_t *cu) +{ + Int32 last = ((Int32)big->max)-1; + l2v_assert_ne(cu->span, 0); + + if (!cu->isNodePtr && (last >= 0) && !big->cu[last].isNodePtr && ( + ((cu->u.n.vpn < L2V_VPN_SPECIAL) && ((big->cu[last].u.n.vpn+big->cu[last].span) == cu->u.n.vpn)) + || ((cu->u.n.vpn >= L2V_VPN_SPECIAL) && (big->cu[last].u.n.vpn == cu->u.n.vpn)))) + { + big->cu[last].span += cu->span; + return TRUE32; + } + + big->cu[big->max] = *cu; + big->max++; + + if (cu->isNodePtr) { + l2v_assert_lt(cu->u.nodeIdx, L2V_NODEPOOL_COUNT); + } + + return FALSE32; +} + + +BOOL32 _L2V_NodeBig_PushContig_Node(lNodeBig_t *big, UInt32 nodeIdx, UInt32 span) +{ + big->cu[big->max].isNodePtr = 1; + big->cu[big->max].u.nodeIdx = nodeIdx; + big->cu[big->max].span = span; + big->max++; + + return FALSE32; +} + + +BOOL32 _L2V_NodeBig_PushContig_Nand(lNodeBig_t *big, UInt32 vpn, UInt32 span) +{ + Int32 last = ((Int32)big->max)-1; + l2v_assert_ne(span, 0); + + if ((last >= 0) && !big->cu[last].isNodePtr && ( + ((vpn < L2V_VPN_SPECIAL) && ((big->cu[last].u.n.vpn+big->cu[last].span) == vpn)) + || ((vpn >= L2V_VPN_SPECIAL) && (big->cu[last].u.n.vpn == vpn)))) + { + big->cu[last].span += span; + return TRUE32; + } + + big->cu[big->max].isNodePtr = 0; + big->cu[big->max].u.n.vpn = vpn; + big->cu[big->max].span = span; + big->max++; + + return FALSE32; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.h new file mode 100644 index 0000000..90ce0d7 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Types.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_TYPES_H__ +#define __L2V_TYPES_H__ + + +#include "WMROAM.h" +#include "L2V_Defines.h" +#include "L2V_Assert.h" + + +// Pointer type: can point to NAND, or to a subtree +// Bits: 0=isNodePtr, 1=hasSpanOF. +// isNodePtr=0: vpn:L2V_BITS_VPN, span:L2V_BITS_NAND_SPAN +// isNodePtr=1: nodeIdx:L2V_BITS_NODEIDX, span:L2V_BITS_NODE_SPAN +// hasSpanOF: fetch 2 bytes from the right end of the node + +typedef UInt32 lPtr_t; +#define LPTR_IS_NODEPTR(_lptr) ((_lptr) & 1) +#define LPTR_HASSPANOF(_lptr) (((_lptr) & 2) >> 1) +#define LPTR_PACK_NAND(_cu) ( \ + (((_cu).hasSpanOF & 1) << 1) | \ + (((_cu).u.n.vpn & (((1 <> 1) & 1; \ + (_cu).u.n.vpn = ((_lptr) >> 2) & ((1 << L2V_BITS_VPN)-1); \ + (_cu).span = ((_lptr) >> (2+L2V_BITS_VPN)) & ((1 << L2V_BITS_NAND_SPAN)-1); \ + } while (0) +#define LPTR_UNPACK_NODE(_lptr, _cu) do { \ + (_cu).isNodePtr = 1; \ + (_cu).hasSpanOF = ((_lptr) >> 1) & 1; \ + (_cu).u.nodeIdx = ((_lptr) >> 2) & ((1 << L2V_BITS_NODEIDX)-1); \ + (_cu).span = ((_lptr) >> (2+L2V_BITS_NODEIDX)) & ((1 << L2V_BITS_NODE_SPAN)-1); \ + } while (0) +#define LPTR_GET_NODEIDX(_lptr) (((_lptr) >> 2) & ((1 << L2V_BITS_NODEIDX)-1)) +#define LPTR_UNPACK(_lptr, _cu) do { \ + if LPTR_IS_NODEPTR(_lptr) { \ + LPTR_UNPACK_NODE(_lptr, _cu); \ + } else { \ + LPTR_UNPACK_NAND(_lptr, _cu); \ + } \ + } while (0) + +typedef struct { + UInt32 isNodePtr; // Values: 0, 1 (true)... must not be any other value + UInt32 hasSpanOF; // Values: 0, 1 (true)... ditto + union { + struct { + UInt32 vpn; + } n; + UInt32 nodeIdx; + } u; + UInt32 span; +} ContigUnpacked_t; + + +// Node type: union for dynamic and fixed node types (and FreePool linkage) +typedef union _lNode_t { + union _lNode_t *nextFreePtr; + + UInt8 bytes[L2V_NODE_SIZE]; +} lNode_t; +CASSERT(L2V_NODE_SIZE == sizeof(lNode_t), lNode_t_size_matches); + +#define L2V_LNODEBIG_MAX (L2V_MAX_CONTIG_PER_NODE+(L2V_SUCKUP_CHILDREN_MAX*2)+5) +typedef struct { + ContigUnpacked_t cu[L2V_LNODEBIG_MAX]; + UInt32 start; + UInt32 max; +} lNodeBig_t; + + +typedef struct { + lNode_t *Node; // Node pool allocated with malloc() + lNode_t *FreePtr; + UInt32 FreeCount; +} FTLight_NodePool_t; + + +typedef struct { + // Logical space + UInt32 numRoots; + lPtr_t *Tree; + UInt32 *TreeNodes; + UInt32 *UpdatesSinceRepack; + UInt32 RepackCounter; + UInt32 treeVersion; + + // Physical space + UInt32 numSBs; + UInt32 pagesPerSB; +#if L2V_TRACK_VALID!=0 + UInt32 Valid[L2V_MAX_SB]; +#endif + + // Memory + FTLight_NodePool_t Pool; +} L2V_t; + +typedef struct { + // Input: + UInt32 lba; + + // Output: + UInt32 fromStart; // blocks from start of treeSpan + UInt32 vpn; + UInt32 span; + + // Internal state: + lNode_t *last_node; + UInt32 next_lba; + UInt32 next_nOfs; + UInt32 nodeSize; + UInt32 level; + UInt32 treeVersion; +} L2V_SearchCtx_t; + + +// Helper functions + +extern BOOL32 _L2V_NodeBig_PushContig(lNodeBig_t *big, ContigUnpacked_t *cu); // True: compressed with left +extern BOOL32 _L2V_NodeBig_PushContig_Node(lNodeBig_t *big, UInt32 nodeIdx, UInt32 span); // True: compress with left (always false) +extern BOOL32 _L2V_NodeBig_PushContig_Nand(lNodeBig_t *big, UInt32 vpn, UInt32 span); // True: compressed with left +#define _L2V_NodeBig_WillCompress(_big, _vpn, _span) \ + ((_big.max > 0) && (!_big.cu[_big.max-1].isNodePtr) && \ + (((_vpn < L2V_VPN_SPECIAL) && ((_big.cu[_big.max-1].u.n.vpn+_big.cu[_big.max-1].span) == _vpn)) \ + || ((_vpn >= L2V_VPN_SPECIAL) && (_big.cu[_big.max-1].u.n.vpn == _vpn)))) + + +#endif // __L2V_TYPES_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Update.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Update.c new file mode 100644 index 0000000..3e0fce5 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Update.c @@ -0,0 +1,1197 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" +#include "L2V_Funcs.h" +#include "L2V_Mem.h" +#include "L2V_Valid.h" +#include "L2V_Repack.h" +#include "L2V_Types.h" + + +// ##### TYPE DEFINITIONS - LOCAL TO THIS SOURCE FILE ######################### + +typedef struct { + UInt32 incomingTree; + UInt32 incomingOfs, incomingSize; + UInt32 incomingEnd; + UInt32 vpn; + + UInt32 thisStart, thisMax; // Span start/end ofs while in inner loop + + ContigUnpacked_t cu; + lPtr_t nodePtr; + lPtr_t thisPtr; + BOOL32 needsInsert; + lNode_t *node; + UInt32 nOfs; + UInt32 nodeSize; + + BOOL32 changed; // Did we change this node? + lNodeBig_t tmpNode; + + lNode_t *atLevel[L2V_MAX_TREE_DEPTH_UPD+5]; // Add some guard-band + UInt32 level; +} UpdateCtx_t; + + +// ##### PROTOTYPES - LOCAL TO THIS SOURCE FILE ############################### + +static void UpdateGuts(UInt32 lba, UInt32 size, UInt32 vpn); +static void TeardownTree(UInt32 tree); +static int DestroySpanLeft(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 amount); +static int DestroySpanRight(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 keepAmount, UInt32 fullSpan); +static void DestroySpanMiddle(lPtr_t *p, UInt32 left, UInt32 right); +static void TreeToNand(UInt32 tree, UInt32 vpn); + +// Helpers: +static void SuckOneUp(UInt32 tree, lNodeBig_t *big, lPtr_t ptr); +static void Upd_TrivialInsert(); +static BOOL32 Upd_IdentityReplace(); +static BOOL32 Upd_CompleteOverlap(); +static BOOL32 Upd_ChopRight(); +static BOOL32 Upd_ChopLeft(); +static void Upd_ChopMiddleNand(); +static void Upd_FillRemainder(); +static int Upd_GetNodeSize(); +static int Upd_PushNodeOut(lNodeBig_t *b, lNode_t *node, UInt32 minEl, UInt32 maxEl); // Returns sumSpan +static void Upd_SplitAndPush(); +static void RippleUp(lNode_t *oldNode, UInt32 span0, lNode_t *newNode, UInt32 span1); +static void Upd_ShareLeft(); +static void Upd_ShareRight(); +static int Upd_PushLeft(lNode_t *left); +static int Upd_PushRight(lNode_t *right); + + +// ##### FUNCTION DEFINITIONS - EXPORTED FUNCTIONS ############################ + +void L2V_Update(UInt32 lba, UInt32 size, UInt32 vpn) +{ + UInt32 thisSize, treeOfs; + + // Running out of L2V memory? + while (L2V_LowMem) + { + // Make room by forgetting some stuff + L2V_ForgetBiggestTree(); + } + + // Up tree version for search-update coherency + L2V.treeVersion++; + + while (size) { + treeOfs = lba & L2V_TREE_MASK; + thisSize = min(L2V_TREE_SIZE - treeOfs, size); + + UpdateGuts(lba, thisSize, vpn); + + size -= thisSize; + lba += thisSize; + if (vpn < L2V_VPN_SPECIAL) { + vpn += thisSize; + } + } +} + + +// ##### FUNCTION DEFINITIONS - LOCAL TO THIS SOURCE FILE ##################### +UpdateCtx_t u; + +static UInt32 L2V_GetDepth(lNode_t *node) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node + lPtr_t thisPtr; + UInt32 depth, maxDepth; + ContigUnpacked_t cu; + + // Walk through + maxDepth = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + depth = L2V_GetDepth(L2V_IDX_TO_NODE(cu.u.nodeIdx)); + if (depth > maxDepth) { + maxDepth = depth; + } + } + } _L2V_NODE_ITERATE_END(nOfs); + + return maxDepth+1; +} + +static void UpdateGuts(UInt32 __lba, UInt32 __size, UInt32 __vpn) +{ + UInt32 nodesBefore; + + // Input: guaranteed to not span trees + u.incomingTree = __lba >> L2V_TREE_BITS; + u.incomingOfs = __lba & L2V_TREE_MASK; + u.incomingSize = __size; + u.incomingEnd = u.incomingOfs + u.incomingSize; + u.vpn = __vpn; + if (u.incomingTree >= L2V.numRoots) { + WMR_PANIC("L2V update with out-of-range LBA-- lba:%d, size:%d, vpn:0x%x", __lba, __size, __vpn); + } + nodesBefore = L2V.TreeNodes[u.incomingTree]; + + // Repack periodicity counter update + L2V.UpdatesSinceRepack[u.incomingTree]++; + L2V.RepackCounter++; + L2V_PeriodicRepack(); + + // First check: update to whole tree? + if ((0 == u.incomingOfs) && (L2V_TREE_SIZE == u.incomingSize)) { + TeardownTree(u.incomingTree); + TreeToNand(u.incomingTree, u.vpn); + L2V_root_depth[u.incomingTree] = 0; + return; + } + + // Share left/right, ripple up? + // Tear? + + u.level = 0; + u.thisStart = 0; + u.thisMax = L2V_TREE_SIZE; + u.nodePtr = L2V.Tree[u.incomingTree]; + + _L2V_ValidUp(u.vpn, u.incomingSize); + + + if (!LPTR_IS_NODEPTR(u.nodePtr)) { + Upd_TrivialInsert(); + return; + } + + // Search from top down + while (u.level < L2V_MAX_TREE_DEPTH_UPD) { + // Walk through + LPTR_UNPACK_NODE(u.nodePtr, u.cu); + u.node = L2V_IDX_TO_NODE(u.cu.u.nodeIdx); + u.atLevel[u.level] = u.node; + u.changed = FALSE32; + u.needsInsert = TRUE32; + u.tmpNode.start = 0; + u.tmpNode.max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(u.node, u.nOfs, u.nodeSize, u.cu, u.thisPtr) { + // Calculate endpoint + u.thisMax = u.thisStart + u.cu.span; + if (u.cu.isNodePtr) { + l2v_assert_lt(u.cu.u.nodeIdx, L2V_NODEPOOL_COUNT); + } + + // Identity overlap? + if (Upd_IdentityReplace()) { + // Exit + goto exit; + } + + // Complete overlap? Free this piece... + else if (Upd_CompleteOverlap()) { + // ok + } + + // Chop right off? + else if (Upd_ChopRight()) { + // ok + } + + // Chop left off? + else if (Upd_ChopLeft()) { + // ok + } + + // Chop middle? (+2 total) + else if ((u.incomingOfs > u.thisStart) && (u.incomingEnd < u.thisMax)) { + if (!u.cu.isNodePtr) { + Upd_ChopMiddleNand(); + } else { + u.nodePtr = u.thisPtr; + goto nextLevel; + } + } + + // Too far right or left? Just copy it out... + Upd_FillRemainder(); + + // Move along in the node + u.thisStart = u.thisMax; + } _L2V_NODE_ITERATE_END(u.nOfs); + + // Last guy in the tree, with CompleteOverlaps to the left? (Since that case doesn't insert.) + if (u.needsInsert) { + u.changed = TRUE32; + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } + + if (u.changed) { + // Will it fit? + if ((u.tmpNode.max > L2V_MIN_CONTIG_PER_NODE) && ((u.nOfs = Upd_GetNodeSize()) > L2V_NODE_SIZE)) { + // Try to share left/right + Upd_ShareLeft(); + Upd_ShareRight(); + + // Will it fit now? + if (((u.tmpNode.max-u.tmpNode.start) > L2V_MIN_CONTIG_PER_NODE) && ((u.nOfs = Upd_GetNodeSize()) > L2V_NODE_SIZE)) { + // Darn, split it + Upd_SplitAndPush(); + } else { + Upd_PushNodeOut(&u.tmpNode, u.node, u.tmpNode.start, u.tmpNode.max); + } + goto exit; + } + + if ((1 == (u.tmpNode.max - u.tmpNode.start)) && (0 == u.level)) { + // Single node, single entry? Squash up into root. + _L2V_FreeNode(u.node); + L2V.TreeNodes[u.incomingTree]--; + TreeToNand(u.incomingTree, u.tmpNode.cu[u.tmpNode.start].u.n.vpn); + L2V_root_depth[u.incomingTree] = 0; + goto exit; + } + + Upd_PushNodeOut(&u.tmpNode, u.node, 0, u.tmpNode.max); + goto exit; + } + + l2v_assert(0); + +nextLevel: + u.level++; + } + + // Fell through + + // Should never get here; otherwise, the tree is too deep (or recursive or pointing to randomness) + WMR_PANIC("NAND index update fell through: abort at level %d\n", u.level); + +exit: + // Did it get bigger than we thought it should? + if (u.level > L2V_TREE_DEPTH_REPACK) + { + L2V_Repack(u.incomingTree); + if (LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(L2V.Tree[u.incomingTree]))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + } + return; + } + + if(nodesBefore <= L2V.TreeNodes[u.incomingTree]) + { + L2V_root_depth[u.incomingTree] += (L2V.TreeNodes[u.incomingTree] - nodesBefore); + if(L2V_root_depth[u.incomingTree] < L2V_TREE_DEPTH_REPACK) + { + return; + } + } + + if (LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(L2V.Tree[u.incomingTree]))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + return; + } + + if(L2V_root_depth[u.incomingTree] >= L2V_TREE_DEPTH_REPACK) + { + L2V_Repack(u.incomingTree); + if (LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) + { + L2V_root_depth[u.incomingTree] = L2V_GetDepth(L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(L2V.Tree[u.incomingTree]))); + } + else + { + L2V_root_depth[u.incomingTree] = 0; + } + } +} + + +static void Teardown(lNode_t *node, UInt32 tree) +{ + UInt32 nOfs, nodeSize; // Byte offset within the node and size + lPtr_t thisPtr; + ContigUnpacked_t cu; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr) { + // Recurse + Teardown(L2V_IDX_TO_NODE(cu.u.nodeIdx), tree); + } else { + // Reduce valid counters + _L2V_ValidDown(cu.vpn, cu.span); + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Free the node + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; +} + + +static void TeardownTree(UInt32 tree) +{ + ContigUnpacked_t cu; + + // Unpack the node + LPTR_UNPACK(L2V.Tree[tree], cu); + + if (cu.isNodePtr) { + // Tear down the tree + Teardown(L2V_IDX_TO_NODE(cu.u.nodeIdx), tree); + } else { + // It's a contig (probably just token but in case tree-sb ratios change, this line is necessary) + _L2V_ValidDown(cu.vpn, L2V_TREE_SIZE); + } +} + + +static int DestroySpanLeft(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 amount) +{ + lNode_t *node; + UInt32 nOfs, nodeSize; // Byte offset within the node, and size after subtracting overflows + UInt32 thisAmount; + Int32 children; + lNodeBig_t tmpNode; + BOOL32 changed = FALSE32; + ContigUnpacked_t thiscu; + lPtr_t thisPtr; + + l2v_assert_ne(amount, 0); + l2v_assert_le(amount, L2V_TREE_SIZE); + + if (!cu->isNodePtr) { + _L2V_ValidDown(cu->vpn, amount); + if (cu->u.n.vpn < L2V_VPN_SPECIAL) { + cu->u.n.vpn += amount; + *p = LPTR_PACK_NAND(*cu); + } + return -1; + } else { + node = L2V_IDX_TO_NODE(cu->u.nodeIdx); + tmpNode.max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + thisAmount = min(amount, thiscu.span); + if (thisAmount == thiscu.span) { + changed = TRUE32; + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thisAmount); + } else { + DestroySpanLeft(tree, &thiscu, &thisPtr, thiscu.span); + } + } else if (thisAmount == 0) { + // Copy it out + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } else { + changed = TRUE32; + children = -1; + + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thisAmount); + if (thiscu.u.n.vpn < L2V_VPN_SPECIAL) { + thiscu.u.n.vpn += thisAmount; + } + } else { + children = DestroySpanLeft(tree, &thiscu, &thisPtr, thisAmount); + } + + // Copy it out + if (children == 1) { + SuckOneUp(tree, &tmpNode, thisPtr); + } else { + thiscu.span -= thisAmount; + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } + } + amount -= thisAmount; + } _L2V_NODE_ITERATE_END(nOfs); + + if (changed) { + // Push it back out + Upd_PushNodeOut(&tmpNode, node, 0, tmpNode.max); + } + + if (0 == tmpNode.max) { + // Free this one + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; + *p = L2V_CONTIG_FREE_SIG; + } + + return tmpNode.max; + } +} + + +static int DestroySpanRight(UInt32 tree, ContigUnpacked_t *cu, lPtr_t *p, UInt32 keepAmount, UInt32 fullSpan) +{ + lPtr_t thisPtr; + lNode_t *node; + UInt32 nOfs, nodeSize; // Byte offset within the node + UInt32 thisAmount; + Int32 children; + lNodeBig_t tmpNode; + BOOL32 changed = FALSE32; + ContigUnpacked_t thiscu; + + l2v_assert_ne(keepAmount, 0); + l2v_assert_lt(keepAmount, L2V_TREE_SIZE); + l2v_assert_ne(fullSpan, 0); + l2v_assert_le(fullSpan, L2V_TREE_SIZE); + + if (!cu->isNodePtr) { + _L2V_ValidDown(cu->vpn, fullSpan-keepAmount); + return -1; + } else { + node = L2V_IDX_TO_NODE(cu->u.nodeIdx); + tmpNode.max = 0; + + // Iterate through the node, + _L2V_NODE_ITERATE(node, nOfs, nodeSize, thiscu, thisPtr) { + thisAmount = min(keepAmount, thiscu.span); + if (thisAmount == thiscu.span) { + // Copy it out + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } else if (thisAmount == 0) { + changed = TRUE32; + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thiscu.span); + } else { + DestroySpanLeft(tree, &thiscu, &thisPtr, thiscu.span); + } + } else if (thisAmount < thiscu.span) { + changed = TRUE32; + children = -1; + + if (!thiscu.isNodePtr) { + _L2V_ValidDown(thiscu.vpn, thiscu.span - thisAmount); + } else { + children = DestroySpanRight(tree, &thiscu, &thisPtr, thisAmount, thiscu.span); + } + + // Copy it out + if (children == 1) { + SuckOneUp(tree, &tmpNode, thisPtr); + } else { + thiscu.span = thisAmount; + _L2V_NodeBig_PushContig(&tmpNode, &thiscu); + } + } + keepAmount -= thisAmount; + } _L2V_NODE_ITERATE_END(nOfs); + + if (changed) { + // Push it back out + Upd_PushNodeOut(&tmpNode, node, 0, tmpNode.max); + } + + if (0 == tmpNode.max) { + // Free this one + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; + *p = L2V_CONTIG_FREE_SIG; + } + + return tmpNode.max; + } +} + + +static void DestroySpanMiddle(lPtr_t *p, UInt32 left, UInt32 right) +{ + ContigUnpacked_t cu; + + LPTR_UNPACK_NAND(*p, cu); + l2v_assert_eq(cu.isNodePtr, 0); // Must not be a nodePtr, since we recurse in the top-level function + _L2V_ValidDown(cu.vpn, right-left); +} + + +static void TreeToNand(UInt32 tree, UInt32 vpn) +{ + ContigUnpacked_t cu; + + cu.hasSpanOF = 0; + cu.u.n.vpn = vpn; + cu.span = 0; + L2V.Tree[tree] = LPTR_PACK_NAND(cu); + + _L2V_ValidUp(vpn, L2V_TREE_SIZE); +} + + +static void Upd_TrivialInsert() +{ + UInt32 nOfs, nodeSize; + lNode_t *node; + ContigUnpacked_t cu; + + LPTR_UNPACK_NAND(u.nodePtr, u.cu); + + // Break the rootPtr into a node + node = _L2V_AllocNode(); + nodeSize = L2V_NODE_SIZE; + L2V.TreeNodes[u.incomingTree] = 1; + nOfs = 0; + + // ValidDown for old section + if (u.cu.u.n.vpn < L2V_VPN_SPECIAL) { + _L2V_ValidDown(u.cu.u.n.vpn, u.incomingSize); + } + + // Break left? + if (u.incomingOfs) { + cu.u.n.vpn = u.cu.u.n.vpn; + cu.span = u.incomingOfs; + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(u.incomingOfs, L2V_TREE_SIZE); + } + + // Insert node + cu.u.n.vpn = u.vpn; + cu.span = u.incomingSize; + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(u.incomingSize, L2V_TREE_SIZE); + + // Break Right? + cu.span = L2V_TREE_SIZE - u.incomingEnd; + if (cu.span != 0) { + cu.u.n.vpn = u.cu.u.n.vpn; + // Move vpn if not special SB + if (cu.u.n.vpn < L2V_VPN_SPECIAL) { + cu.u.n.vpn += u.incomingEnd; + } + _L2V_NODE_PUSH_CONTIG_NAND(node, nOfs, nodeSize, cu); + l2v_assert_le(cu.span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(node, nOfs, nodeSize); + + // Update Tree ptr + cu.hasSpanOF = 0; + cu.u.nodeIdx = L2V_NODE_TO_IDX(node); + L2V.Tree[u.incomingTree] = LPTR_PACK_NODE(cu); + if (!LPTR_IS_NODEPTR(L2V.Tree[u.incomingTree])) { + L2V_root_depth[u.incomingTree] = 0; + } +} + + +static BOOL32 Upd_IdentityReplace() +{ + lPtr_t *p; + UInt32 check_nOfs, check_nodeSize; + lPtr_t check_thisPtr; + ContigUnpacked_t check_cu, local_cu; + + if ((u.incomingOfs == u.thisStart) && (u.incomingSize == u.cu.span)) { + // = + + // Make sure we aren't missing a compression opportunity + if (_L2V_NodeBig_WillCompress(u.tmpNode, u.vpn, u.incomingSize)) { + return FALSE32; + } + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + // Destroy old, recursively destroying subtrees if necessary + DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.cu.span); + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + // Overwrite in place--works because nodeptrs are always 6 bytes, and if the span is the same size, updating in place will work + p = (lPtr_t*)(&u.node->bytes[u.nOfs]); + local_cu.isNodePtr = 0; + local_cu.hasSpanOF = 0; + if (LPTR_HASSPANOF(*p)) + local_cu.hasSpanOF = 1; + local_cu.u.n.vpn = u.vpn; + local_cu.span = u.cu.span; + if (local_cu.hasSpanOF) { + *(UInt16*)(&u.node->bytes[u.nodeSize]) = u.cu.span >> L2V_BITS_NAND_SPAN; + } + *p = LPTR_PACK_NAND(local_cu); + + // Check spans + _L2V_NODE_ITERATE(u.node, check_nOfs, check_nodeSize, check_cu, check_thisPtr) { + } _L2V_NODE_ITERATE_END(check_nOfs); + + return TRUE32; + } + + return FALSE32; +} + + +static BOOL32 Upd_CompleteOverlap() +{ + if ((u.incomingOfs <= u.thisStart) && (u.incomingEnd >= u.thisMax)) { + u.changed = TRUE32; + // Destroy old span + DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.cu.span); + + return TRUE32; + } + + return FALSE32; +} + + +static void SuckOneUp(UInt32 tree, lNodeBig_t *big, lPtr_t ptr) +{ + lNode_t *node; + UInt32 nOfs, nodeSize, count; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + l2v_assert_eq(LPTR_IS_NODEPTR(ptr), 1); + node = L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(ptr)); + count = 0; + + // Iterate over children + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + // Push into u->tmpNode + _L2V_NodeBig_PushContig(big, &cu); + count++; + } _L2V_NODE_ITERATE_END(nOfs); + l2v_assert_eq(count, 1); + + // Free old node + _L2V_FreeNode(node); + L2V.TreeNodes[tree]--; +} + +static void SuckUp() +{ + lNode_t *node; + UInt32 nOfs, nodeSize; + lPtr_t thisPtr; + ContigUnpacked_t cu; + + l2v_assert_eq(LPTR_IS_NODEPTR(u.thisPtr), 1); + node = L2V_IDX_TO_NODE(LPTR_GET_NODEIDX(u.thisPtr)); + + // Iterate over children + _L2V_NODE_ITERATE(node, nOfs, nodeSize, cu, thisPtr) { + // Push into u->tmpNode + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + } _L2V_NODE_ITERATE_END(nOfs); + + // Free old node + _L2V_FreeNode(node); + L2V.TreeNodes[u.incomingTree]--; +} + + +static BOOL32 Upd_ChopRight() +{ + Int32 children; + ContigUnpacked_t cu; + + if ((u.incomingOfs > u.thisStart) && (u.incomingOfs < u.thisMax) && (u.incomingEnd >= u.thisMax)) { + u.changed = TRUE32; + children = DestroySpanRight(u.incomingTree, &u.cu, &u.thisPtr, u.incomingOfs - u.thisStart, u.cu.span); + + // Try to reduce tree depth and maximize usage by sucking children up + if ((children >= 1) && (children <= L2V_SUCKUP_CHILDREN_MAX)) { + SuckUp(); + } else if (0 != children) { + // Still have a child node we need to reference + cu = u.cu; + cu.span = u.incomingOfs - u.thisStart; + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + } + + if (u.needsInsert) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } else { + l2v_assert(0); + } + + return TRUE32; + } + + return FALSE32; +} + + +static BOOL32 Upd_ChopLeft() +{ + Int32 children; + + if ((u.incomingOfs <= u.thisStart) && (u.incomingEnd > u.thisStart) && (u.incomingEnd < u.thisMax)) { + u.changed = TRUE32; + children = DestroySpanLeft(u.incomingTree, &u.cu, &u.thisPtr, u.incomingEnd - u.thisStart); + + if (u.needsInsert) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } + + // Try to reduce tree depth and maximize usage by sucking children up + if ((children >= 1) && (children <= L2V_SUCKUP_CHILDREN_MAX)) { + SuckUp(); + } else if (0 != children) { + // Still have a child node or nand-ptr we need to reference + u.tmpNode.cu[u.tmpNode.max] = u.cu; + // Ofs moving taken care of by DestroySpanleft + u.tmpNode.cu[u.tmpNode.max].span = u.thisMax - u.incomingEnd; + l2v_assert_ne(u.thisMax - u.incomingEnd, 0); + u.tmpNode.max++; + } + + return TRUE32; + } + + return FALSE32; +} + + +static void Upd_ChopMiddleNand() +{ + u.changed = TRUE32; + DestroySpanMiddle(&u.thisPtr, u.thisStart-u.incomingOfs, u.incomingEnd - u.incomingOfs); + + // Break left + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.cu.u.n.vpn, u.incomingOfs - u.thisStart); + + // Insert in middle + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + + // Break right + // +1 + if (u.cu.u.n.vpn < L2V_VPN_SPECIAL) { + u.cu.u.n.vpn += (u.incomingEnd - u.thisStart); + } + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.cu.u.n.vpn, u.thisMax - u.incomingEnd); +} + + +static void Upd_FillRemainder() +{ + if ((u.thisStart >= u.incomingEnd) || (u.thisMax <= u.incomingOfs)) { + // Did none of the above trims/etc insert the new ptr? + // This is because we had an exact eclipse(s) + if (u.needsInsert && (u.thisStart >= u.incomingEnd)) { + // +1 + _L2V_NodeBig_PushContig_Nand(&u.tmpNode, u.vpn, u.incomingSize); + u.needsInsert = FALSE32; + } + + // Copy into tmpNode + _L2V_NodeBig_PushContig(&u.tmpNode, &u.cu); + } +} + + +static int Upd_GetNodeSize() +{ + UInt32 i, nOfs; + + nOfs = 0; + + for (i = u.tmpNode.start; i < u.tmpNode.max; i++) { + nOfs += _L2V_CONTIG_SIZE(u.tmpNode.cu[i]); + } + + return nOfs; +} + + +static int Upd_PushNodeOut(lNodeBig_t *b, lNode_t *node, UInt32 minEl, UInt32 maxEl) +{ + UInt32 i, nOfs, nodeSize; + UInt32 sumSpan; + + sumSpan = 0; + + l2v_assert_lt(minEl, L2V_LNODEBIG_MAX); + l2v_assert_le(maxEl, L2V_LNODEBIG_MAX); + + // Copy and squeeze + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + for (i = minEl; i < maxEl; i++) { + _L2V_NODE_PUSH_CONTIG(node, nOfs, nodeSize, b->cu[i]); + + sumSpan += b->cu[i].span; + l2v_assert_le(b->cu[i].span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(node, nOfs, nodeSize); + + return sumSpan; +} + + +static void Upd_SplitAndPush() +{ + lNode_t *newNode, *oldNode; + UInt32 half, span0, span1; + + // Get new node + oldNode = u.node; + newNode = _L2V_AllocNode(); + L2V.TreeNodes[u.incomingTree]++; + + // Divide and push to old/new + half = ((u.tmpNode.max - u.tmpNode.start)>>1) + 1 + u.tmpNode.start; + span0 = Upd_PushNodeOut(&u.tmpNode, oldNode, u.tmpNode.start, half); + l2v_assert_ne(span0, 0); + span1 = Upd_PushNodeOut(&u.tmpNode, newNode, half, u.tmpNode.max); + l2v_assert_ne(span1, 0); + + RippleUp(oldNode, span0, newNode, span1); +} + + +static void RippleUp(lNode_t *oldNode, UInt32 span0, lNode_t *newNode, UInt32 span1) +{ + lNode_t *parent, *parent1; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, span; + UInt32 parentspan0, parentspan1, half; + ContigUnpacked_t cu; + + u.tmpNode.start = u.tmpNode.max = 0; + + if (0 == u.level) { + // Special case: allocate another parent node, link these in + parent = _L2V_AllocNode(); + L2V.TreeNodes[u.incomingTree]++; + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(oldNode), span0); + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(newNode), span1); + span = Upd_PushNodeOut(&u.tmpNode, parent, 0, u.tmpNode.max); + l2v_assert_eq(span, L2V_TREE_SIZE); + + // Replace root + cu.u.nodeIdx = L2V_NODE_TO_IDX(parent); + cu.span = 0; + cu.hasSpanOF = 0; // To get rid of analyzer warning--not used in root ptrs + L2V.Tree[u.incomingTree] = LPTR_PACK_NODE(cu); + } else { + // Get parent + parent = u.atLevel[u.level-1]; + + // Copy into tmpNode + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == oldNode)) { + // Copy old node + _L2V_NodeBig_PushContig_Node(&u.tmpNode, cu.u.nodeIdx, span0); + l2v_assert_ne(span0, 0); + + // Copy new node + _L2V_NodeBig_PushContig_Node(&u.tmpNode, L2V_NODE_TO_IDX(newNode), span1); + l2v_assert_ne(span1, 0); + + if ((span0+span1) != cu.span) { + WMR_PANIC("NAND index: span0: %d, span1: %d, +: %d, span: %d", span0, span1, span0+span1, cu.span); + } + } else { + // Not involved, copy it out + _L2V_NodeBig_PushContig(&u.tmpNode, &cu); + l2v_assert_ne(cu.span, 0); + } + } _L2V_NODE_ITERATE_END(nOfs); + + if (u.tmpNode.max > L2V_MIN_CONTIG_PER_NODE) { + // Split + parent1 = _L2V_AllocNode(); + L2V.TreeNodes[u.incomingTree]++; + half = (u.tmpNode.max>>1) + 1; + parentspan0 = Upd_PushNodeOut(&u.tmpNode, parent, 0, half); + l2v_assert_ne(parentspan0, 0); + parentspan1 = Upd_PushNodeOut(&u.tmpNode, parent1, half, u.tmpNode.max); + l2v_assert_ne(parentspan1, 0); + + // Ripple up + u.level--; + RippleUp(parent, parentspan0, parent1, parentspan1); + } else { + // Push + Upd_PushNodeOut(&u.tmpNode, parent, 0, u.tmpNode.max); + } + } +} + + +static void Upd_ShareLeft() +{ + lNode_t *parent, *left; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, left_nodeIdx, left_nOfs, left_span, spanUp; + BOOL32 left_isNodePtr; + ContigUnpacked_t cu; + + // Initialize so the compiler doesn't complain + cu.hasSpanOF = 0; + cu.span = 0; + left_nOfs = 0; + left_nodeIdx = 0; + left_span = 0; + left_isNodePtr = 0; + + if (0 == u.level) { + // Can't share if we're root... + return; + } + + // Get parent + parent = u.atLevel[u.level-1]; + left = NULL; + + // Find me, then previous sibling + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == u.node)) { + goto foundIt; + } + left = L2V_IDX_TO_NODE(cu.u.nodeIdx); + left_nOfs = nOfs; + left_nodeIdx = cu.u.nodeIdx; + left_span = cu.span; + left_isNodePtr = cu.isNodePtr; + } _L2V_NODE_ITERATE_END(nOfs); + + // Couldn't find ...??? + WMR_PANIC("NAND index update failed node identity search: level: %d, parent: %p\n", u.level, (void*)parent); + +foundIt: + if ((NULL == left) || !left_isNodePtr) { + // We were the first pointed by parent, sorry, no easy left search... + return; + } + + // Great, push some in + spanUp = Upd_PushLeft(left); + + // Down my span in the parent + cu.span -= spanUp; + *(lPtr_t*)(&parent->bytes[nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize] = cu.span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(cu.span, 0); + + // Update left's span in parent + left_span += spanUp; + cu.span = left_span; + cu.u.nodeIdx = left_nodeIdx; + *(lPtr_t*)(&parent->bytes[left_nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize+sizeof(UInt16)] = left_span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(left_span, 0); +} + + +static void Upd_ShareRight() +{ + lNode_t *parent, *right; + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, my_nOfs, my_nodeIdx, my_span, spanUp; + BOOL32 isNext; + ContigUnpacked_t cu; + + // Initialize so the compiler doesn't complain + my_span = 0; + my_nodeIdx = 0; + my_nOfs = 0; + + if (0 == u.level) { + // Can't share if we're root... + return; + } + + // Get parent + parent = u.atLevel[u.level-1]; + right = NULL; + + // Find me, then next sibling + isNext = FALSE32; + _L2V_NODE_ITERATE(parent, nOfs, nodeSize, cu, thisPtr) { + if (isNext) { + if (cu.isNodePtr) { + right = L2V_IDX_TO_NODE(cu.u.nodeIdx); + } + goto foundIt; + } + if (cu.isNodePtr && (L2V_IDX_TO_NODE(cu.u.nodeIdx) == u.node)) { + isNext = TRUE32; + my_span = cu.span; + my_nOfs = nOfs; + my_nodeIdx = cu.u.nodeIdx; + } + } _L2V_NODE_ITERATE_END(nOfs); + + // Couldn't find right because we were the last one? + l2v_assert_eq(isNext, 1); + return; + +foundIt: + if (NULL == right) { + // No node* right next to us, sorry... + return; + } + + // Great, push some in + spanUp = Upd_PushRight(right); + + // Update right's span in parent + cu.span += spanUp; + *(lPtr_t*)(&parent->bytes[nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize] = cu.span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(cu.span, 0); + + // Down my span in the parent + my_span -= spanUp; + cu.u.nodeIdx = my_nodeIdx; + cu.span = my_span; + *(lPtr_t*)(&parent->bytes[my_nOfs]) = LPTR_PACK_NODE(cu); + *(UInt16*)&parent->bytes[nodeSize+sizeof(UInt16)] = cu.span >> L2V_BITS_NODE_SPAN; + l2v_assert_ne(cu.span, 0); +} + + +static int Upd_PushLeft(lNode_t *left) +{ + lPtr_t thisPtr; + UInt32 nOfs, nodeSize, spanUp, myEntrySize; + ContigUnpacked_t cu; + + spanUp = 0; + + // Has room? + _L2V_NODE_ITERATE(left, nOfs, nodeSize, cu, thisPtr) { + } _L2V_NODE_ITERATE_END(nOfs); + + // Calculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.start]); + + // While we have space... + while ((nOfs < (nodeSize-myEntrySize)) && ((u.tmpNode.max - u.tmpNode.start) > 1)) { + // Copy it out + l2v_assert_ne(u.tmpNode.cu[u.tmpNode.start].span, 0); + l2v_assert_le(u.tmpNode.cu[u.tmpNode.start].span, L2V_TREE_SIZE); + _L2V_NODE_PUSH_CONTIG(left, nOfs, nodeSize, u.tmpNode.cu[u.tmpNode.start]); + + // Move along + spanUp += u.tmpNode.cu[u.tmpNode.start].span; + u.tmpNode.start++; + + // Recalculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.start]); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(left, nOfs, nodeSize); + + // And ripple up + return spanUp; +} + + +static int Upd_PushRight(lNode_t *right) +{ + lPtr_t thisPtr; + UInt32 i, numToCopy, spanUp, nOfs, nodeSize, orig_nOfs, orig_nodeSize, myEntrySize; + lNodeBig_t localNode; + BOOL32 didSome = FALSE32; + ContigUnpacked_t cu; + + spanUp = 0; + + // Copy originals out and find out how much free space there is + localNode.start = localNode.max = 0; + _L2V_NODE_ITERATE(right, orig_nOfs, orig_nodeSize, cu, thisPtr) { + localNode.cu[localNode.max] = cu; + l2v_assert_ne(cu.span, 0); + localNode.max++; + } _L2V_NODE_ITERATE_END(orig_nOfs); + + // Calculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.max-1]); + + nOfs = 0; + numToCopy = 0; + + // While we have space... + while (((nOfs+orig_nOfs) < (orig_nodeSize-myEntrySize)) && ((u.tmpNode.max - u.tmpNode.start - numToCopy) > 1)) { + didSome = TRUE32; + + // Mark it as copyable + u.tmpNode.max--; + numToCopy++; + nOfs += myEntrySize; + + // Recalculate size + myEntrySize = _L2V_CONTIG_SIZE(u.tmpNode.cu[u.tmpNode.max-1]); + } + + if (!didSome) { + // No room, sorry... + return 0; + } + + + + // Copy new ones + nOfs = 0; + nodeSize = L2V_NODE_SIZE; + i = 0; + while (numToCopy) { + _L2V_NODE_PUSH_CONTIG(right, nOfs, nodeSize, u.tmpNode.cu[u.tmpNode.max+i]); + l2v_assert_le(u.tmpNode.cu[u.tmpNode.max+i].span, L2V_TREE_SIZE); + spanUp += u.tmpNode.cu[u.tmpNode.max+i].span; + i++; + numToCopy--; + } + + // Copy originals + for (localNode.start = 0; localNode.start < localNode.max; localNode.start++) { + _L2V_NODE_PUSH_CONTIG(right, nOfs, nodeSize, localNode.cu[localNode.start]); + l2v_assert_ne(localNode.cu[localNode.start].span, 0); + l2v_assert_le(localNode.cu[localNode.start].span, L2V_TREE_SIZE); + } + + // Fill rest of node with "empty" signature + _L2V_NODE_FILL(right, nOfs, nodeSize); + + // And ripple up + return spanUp; +} + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.c new file mode 100644 index 0000000..a05d71c --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRFeatures.h" +#if ENABLE_L2V_TREE +#include "L2V.h" + + +#if L2V_TRACK_VALID!=0 + +void _L2V_ValidUp(UInt32 vpn, UInt32 count) +{ + UInt32 sb = vpn / L2V.pagesPerSB; + L2V.Valid[sb] += count; + //l2v_assert_le(L2V.Valid[sb], sbsize); +} + +void _L2V_ValidDown(UInt32 vpn, UInt32 count) +{ + UInt32 sb = vpn / L2V.pagesPerSB; + //l2v_assert_ge(L2V.Valid[sb], count); + L2V.Valid[sb] -= count; +} + +#endif // track valid + +#endif // ENABLE_L2V_TREE + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.h new file mode 100644 index 0000000..875b524 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/L2V_Valid.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __L2V_VALID_H__ +#define __L2V_VALID_H__ + + +#include "L2V_Defines.h" + +#if L2V_TRACK_VALID!=0 +extern void _L2V_ValidUp(UInt32 vpn, UInt32 count); +extern void _L2V_ValidDown(UInt32 vpn, UInt32 count); +#else +#define _L2V_ValidUp(vpn, count) +#define _L2V_ValidDown(vpn, count) +#endif + + +#endif // __L2V_VALID_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMRFeatures-test.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMRFeatures-test.h new file mode 100644 index 0000000..74ec296 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMRFeatures-test.h @@ -0,0 +1 @@ +#define ENABLE_L2V_TREE (1) diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.c b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.c new file mode 100644 index 0000000..e5c0a7e --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Author: Daniel J. Post (djp), dpost@apple.com + +#include "WMROAM.h" + + +void *WMR_MALLOC(UInt32 size) +{ + void * ptr = malloc(size); + if (ptr) + { + WMR_MEMSET(ptr, 0, size); + } + return ptr; +} + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.h b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.h new file mode 100644 index 0000000..788fa92 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/L2V/WMROAM-test.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __WMROAM_H__ +#define __WMROAM_H__ + +#include +#include +#include +#include +#include + +#define UInt32 uint32_t +#define Int32 int32_t +#define UInt16 uint16_t +#define Int16 int16_t +#define UInt8 uint8_t +#define Int8 int8_t +#define BOOL32 bool +#define TRUE32 true +#define FALSE32 false + +#define _WMR_ASSERT(e, file, line) { printf("%s:%u: failed assertion '%s'\nWaiting for debugger...\n", file, line, e); abort(); } +#define WMR_ASSERT(e) if (!(e)) _WMR_ASSERT(#e, __FILE__, __LINE__) +#define WMR_PANIC(format, args...) { printf(format , ##args); abort(); } +#define WMR_MEMSET(a, b, c) memset(a, b, c) +#define WMR_FREE(x, y) free(x) + +extern void *WMR_MALLOC(UInt32 size); + +//////////////////////////////////////////////////////////////////////////////// +// +// WMR_TRACE_* +// +// Compile-time tracepoints (not supported) +// +#define WMR_TRACE_0(...) +#define WMR_TRACE_1(...) +#define WMR_TRACE_2(...) +#define WMR_TRACE_3(...) +#define WMR_TRACE_4(...) +#define WMR_TRACE_IST_0(...) +#define WMR_TRACE_IST_1(...) +#define WMR_TRACE_IST_2(...) +#define WMR_TRACE_IST_3(...) +#define WMR_TRACE_IST_4(...) + +#endif // __WMROAM_H__ diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL.c b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL.c new file mode 100644 index 0000000..a78a488 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL.c @@ -0,0 +1,6343 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define TIME_TREE 0 +#define AND_TRACE_LAYER FTL + +#include "yaFTL_whoami.h" +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "WMRBuf.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "yaFTLTypes.h" +#include "FTL.h" +#include "yaFTL_Defines.h" +#include "yaFTL_gc.h" +#include "yaFTL_BTOC.h" +#include "L2V/L2V_Extern.h" +#if TIME_TREE +#include +#endif +#include "WMRFeatures.h" +#ifndef ENABLE_L2V_TREE +#error ENABLE_L2V_TREE must be set to 0 or 1 in WMRFeatures.h +#endif + +#define kYaftlMinorVersion (1) + + +#if !NAND_RAW && !NAND_PPN +#error PPN or raw? +#endif + +#ifdef AND_COLLECT_STATISTICS +FTLStatistics stFTLStatistics; +#endif /* AND_COLLECT_STATISTICS */ + +#define CXT_VER "CX01" +FTLWMRDeviceInfo yaFTL_FTLDeviceInfo; +VFLFunctions yaFTL_VFLFunctions; +yaFTL_t yaFTL; +static BOOL32 yaftl_init_done = FALSE32; + +/* static functions declaration section */ +static void YAFTL_FreeMemory(void); +static Int32 YAFTL_Init(VFLFunctions *pVFLFunctions); +static Int32 YAFTL_Open(UInt32 *pTotalScts, + UInt32 * pdwSectorSize, + BOOL32 nandFullRestore, + BOOL32 justFormatted, + UInt32 dwMinorVer, + UInt32 dwOptions); +static Int32 YAFTL_Read(UInt32 nLpn, UInt32 nNumOfScts, + UInt8 *pBuf); +static void YAFTL_Close(void); +static BOOL32 YAFTL_GetStruct(UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 * pdwStructSize); +Int32 _readPage(UInt32 vpn, UInt8 *pageData, + PageMeta_t *pMeta, + BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 scrubOnUECC); +BOOL32 _readMultiPages(UInt32 * padwVpn, + UInt16 wNumPagesToRead, UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 bInternalOp, BOOL32 scrubOnUECC); +#if ENABLE_L2V_TREE +static void PopulateFromIndexCache(UInt32 indexPageNo, UInt32 *indexPageData); +#endif //ENABLE_L2V_TREE + +static void PopulateTreesOnBoot_Fast(void); + +#ifndef AND_READONLY +static Int32 YAFTL_Write(UInt32 nLpn, UInt32 nNumOfScts, + UInt8 *pBuf, BOOL32 isStatic); +static Int32 YAFTL_Format(UInt32 dwOptions); +static Int32 YAFTL_WearLevel(void); +static BOOL32 YAFTL_GarbageCollect(void); +static BOOL32 YAFTL_ShutdownNotify(BOOL32 boolMergeLogs); +Int32 _writePage(UInt32 vpn, UInt8 *pageData, + PageMeta_t *, + BOOL32 bInternalOp); +static ANDStatus writeIndexPage(UInt8 *pageBuffer, PageMeta_t *mdPtr, + UInt8 flag); +UInt32 _allocateBlock(UInt32 blockNo, UInt8 flag, UInt8 type); +BOOL32 _writeMultiPages(UInt16 vbn, UInt16 pageOffset, + UInt16 wNumPagesToWrite, UInt8 *pageData, + PageMeta_t *mdPtr, + BOOL32 bInternalOp); +UInt32* IndexLoadDirty(UInt32 lba, UInt32 *indexOfs); +UInt32* IndexLoadClean(UInt32 lba, UInt32 *indexOfs, UInt32 *d_tocEntry); +void IndexMarkDirty(UInt32 tocEntry); +ANDStatus invalidateCXT(void); +BOOL32 isBlockInEraseNowList(UInt16 blockNo); +BOOL32 removeBlockFromEraseNowList(UInt16 blockNo); +BOOL32 addBlockToEraseNowList(UInt16 blockNo); + +#endif // ! AND_READONLY + +/* + static variables/structures declaration section + */ + +typedef struct blockList +{ + WeaveSeq_t weaveSeq; + UInt16 blockNo; + struct blockList *next; + struct blockList *prev; +} BlockListType; + +typedef struct BlockRange +{ + UInt32 start; + UInt32 end; +} BlockRangeType; + +#if NAND_PPN +typedef struct YAFTLControlInfo +{ + UInt32 versionNo; + UInt32 indexSize; /* index size in blocks */ + UInt32 logicalPartitionSize; /* partititon size in pages exposed to file system */ + UInt32 wrState_data_block; /* current physical block being used for updates */ + UInt32 wrState_data_weaveSeq_Lo; + UInt32 wrState_data_weaveSeq_Hi; + UInt32 wrState_index_block; /* current physical block being used for updates */ + UInt32 wrState_index_weaveSeq_Lo; + UInt32 wrState_index_weaveSeq_Hi; + UInt32 seaState_data_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_index_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_data_allocdBlocks; + UInt32 seaState_index_allocdBlocks; + UInt32 indexCacheSize; + UInt32 FTLRestoreCnt; + UInt32 reserved32[10]; + + UInt16 TOCtableEntriesNo; /* number of entries in index TOC table */ + UInt16 controlPageNo; + UInt16 indexPageRatio; /* TOC of each block contains Lpa for each page written to block */ + UInt16 freeCachePages; + UInt16 nextFreeCachePage; + UInt16 wrState_data_nextPage; /* offset in current block of next free page */ + UInt16 wrState_index_nextPage; /* offset in current block of next free page */ + UInt32 reserved16[10]; + + UInt8 exportedRatio; + UInt8 cxtEraseCounter; + UInt8 reserved8[10]; +} YAFTLControlInfoType; +#elif NAND_RAW +typedef struct YAFTLControlInfo +{ + UInt32 versionNo; + UInt32 indexSize; /* index size in blocks */ + UInt32 logicalPartitionSize; /* partititon size in pages exposed to file system */ + UInt32 wrState_data_block; /* current physical block being used for updates */ + UInt32 wrState_data_weaveSeq; + UInt32 wrState_index_block; /* current physical block being used for updates */ + UInt32 wrState_index_weaveSeq; + UInt32 seaState_data_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_index_freeBlocks; /* number of free ( erased ) blocks */ + UInt32 seaState_data_allocdBlocks; + UInt32 seaState_index_allocdBlocks; + UInt32 indexCacheSize; + UInt32 FTLRestoreCnt; + UInt32 reserved32[10]; + + UInt16 TOCtableEntriesNo; /* number of entries in index TOC table */ + UInt16 controlPageNo; + UInt16 indexPageRatio; /* TOC of each block contains Lpa for each page written to block */ + UInt16 freeCachePages; + UInt16 nextFreeCachePage; + UInt16 wrState_data_nextPage; /* offset in current block of next free page */ + UInt16 wrState_index_nextPage; /* offset in current block of next free page */ + UInt32 reserved16[10]; + + UInt8 exportedRatio; + UInt8 cxtEraseCounter; + UInt8 reserved8[10]; +} YAFTLControlInfoType; +#else +#error PPN or raw? +#endif + +static BOOL32 _allocateRestoreIndexBuffers(BlockRangeType **blockRangeBuffer, UInt32 **indexTable, UInt32 *indexTableSize); + +#ifdef AND_COLLECT_STATISTICS +#ifndef AND_READONLY +static BOOL32 _FTLGetStatisticsToCxt(UInt8 * pabData); +#endif //ifndef AND_READONLY +static BOOL32 _FTLSetStatisticsFromCxt(UInt8 * pabData); +#endif +#ifndef AND_READONLY +static BOOL32 YAFTL_WriteStats(void); +#define CXT_ERASE_GAP 50 +#define MOVE_CXT_TRESHOLD 1000 + +#define ERASE_CXT_UPDATE_THRESHOLD (FTL_AREA_SIZE>>4) +#define WRITE_CXT_UPDATE_THRESHOLD (USER_PAGES_TOTAL>>4) +#endif +static UInt32 tempIndexBufferSize = 0; +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ + +void freeBlockList(BlockListType * listHead) +{ + BlockListType * tmpPtr = listHead; + while(tmpPtr != NULL) + { + listHead = tmpPtr; + tmpPtr = tmpPtr->next; + WMR_FREE(listHead, sizeof(BlockListType)); + + } +} + +#if TIME_TREE +mach_timebase_info_data_t sTimebaseInfo; + +static UInt64 ANDPerf_getTime() { + return mach_absolute_time(); +} + +static UInt32 ANDPerf_toUs(UInt64 elapsed) { + if (sTimebaseInfo.denom != sTimebaseInfo.numer) { + if (sTimebaseInfo.denom == 1) { + elapsed *= sTimebaseInfo.numer; + } else { + elapsed = (elapsed * sTimebaseInfo.numer) / (uint64_t)sTimebaseInfo.denom; + } + } + + return elapsed / 1000 /* NS_PER_USEC */; +} +#endif // TIME_TREE + +static void updateReadCounter(UInt16 vba) +{ + if (yaFTL.blockArray[vba].pagesRead > YAFTL_READ_DISTURB_LIMIT) + return; + + yaFTL.blockArray[vba].pagesReadSubCounter++; + if(yaFTL.blockArray[vba].pagesReadSubCounter >= PAGES_READ_SUB_COUNTER_LIMIT) + { + yaFTL.blockArray[vba].pagesReadSubCounter = 0; + yaFTL.blockArray[vba].pagesRead++; + } +} + +static BOOL32 _InitDeviceInfo(void) +{ + yaFTL_FTLDeviceInfo.wPagesPerVb = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + yaFTL_FTLDeviceInfo.wUserVbTotal = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_NUM_OF_USER_SUBLK); + yaFTL_FTLDeviceInfo.wBytesPerPage = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + yaFTL_FTLDeviceInfo.wBytesPerPageMeta = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES) * (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + yaFTL_FTLDeviceInfo.wNumOfBanks = + (UInt16)VFL_GetDeviceInfo(AND_DEVINFO_NUM_OF_BANKS); + yaFTL_FTLDeviceInfo.dwUserPagesTotal = (UInt32)yaFTL_FTLDeviceInfo.wUserVbTotal * + (UInt32)yaFTL_FTLDeviceInfo.wPagesPerVb; + + debug(INIT, "wPagesPerVb 0x%X", yaFTL_FTLDeviceInfo.wPagesPerVb); + debug(INIT, "wUserVbTotal 0x%X", yaFTL_FTLDeviceInfo.wUserVbTotal); + debug(INIT, "wBytesPerPage 0x%X", yaFTL_FTLDeviceInfo.wBytesPerPage); + debug(INIT, "wNumOfBanks 0x%X", yaFTL_FTLDeviceInfo.wNumOfBanks); + debug(INIT, "dwUserPagesTotal 0x%X", yaFTL_FTLDeviceInfo.dwUserPagesTotal); + + if (sizeof(PageMeta_t) != yaFTL_FTLDeviceInfo.wBytesPerPageMeta) { + WMR_PANIC("yaFTL meta struct size (%d) not equal to bytes per metadata (%d)", sizeof(PageMeta_t), yaFTL_FTLDeviceInfo.wBytesPerPageMeta); + } + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Init */ +/* DESCRIPTION */ +/* This function initializes yaftl global structures */ +/* RETURN VALUES */ +/* FTL_SUCCESS */ +/* YAFTL_Init is completed */ +/* FTL_CRITICAL_ERROR */ +/* YAFTL_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +YAFTL_Init(VFLFunctions *pVFLFunctions) +{ + UInt16 pagesInBlk; + UInt16 pageSize; + UInt32 temp1; + + // Do not allow multiple init() calls because number of user blocks can change + WMR_ASSERT(!yaftl_init_done); + + // Guarantee that yaftl context was packed as expected +#if NAND_PPN + WMR_ASSERT(sizeof(struct YAFTLControlInfo) == 168); +#elif NAND_RAW + WMR_ASSERT(sizeof(struct YAFTLControlInfo) == 160); +#else +#error PPN or raw? +#endif + + // Initialize yaFTL structure + WMR_MEMSET((void*)&yaFTL, 0, sizeof(yaFTL)); + yaFTL.readBufferIndex = 0xffffffff; + yaFTL.currentCxtVpn = 0xffffffff; + yaFTL.indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; + yaFTL.exportedRatio = DEFAULT_EXPO_RATIO; + + WMR_MEMCPY(&yaFTL_VFLFunctions, pVFLFunctions, sizeof(VFLFunctions)); + debug(INIT, "YAFTL_INIT[start]"); + _InitDeviceInfo(); + + pagesInBlk = PAGES_PER_SUBLK; + pageSize = BYTES_PER_PAGE; + /* find out how many pages we need to keep pointer to each data/index page within unit */ + for (yaFTL.controlPageNo = 1; (Int32)(pagesInBlk - yaFTL.controlPageNo) * sizeof(Int32) > ((Int32)pageSize * yaFTL.controlPageNo) - (yaFTL.controlPageNo * sizeof(Int32)); yaFTL.controlPageNo++) + + { + ; + } + debug(INIT, "yaFTL.controlPageNo %d", yaFTL.controlPageNo); + debug(INIT, " PAGES_PER_SUBLK %d", PAGES_PER_SUBLK); + debug(INIT, "BYTES_PER_PAGE %d", BYTES_PER_PAGE); + + yaFTL.indexPageRatio = pageSize / sizeof(UInt32); + + // Buffer allocations + WMR_BufZone_Init(&yaFTL.BufZone); + yaFTL.quickRestore_tBuff = (UInt8 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, BYTES_PER_PAGE); + yaFTL.tmpReadBuffer = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, BYTES_PER_PAGE); + yaFTL.restoreTOC = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.meta_restoreIdx = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_restoreData = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_readCxt = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_quickRestore = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_invalidateCxt = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_writeCxt = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_restoreMountErase = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_restoreMount = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_clearEntryInCache = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_writeBTOC = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_indexLoadDirty = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_getStats = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_GetBlockTOC = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_IsDataPageCurrent = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.meta_WriteZoneData = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.singleMdPtr = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, sizeof(PageMeta_t)); + yaFTL.writeMdPtr = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, NUM_BANKS * YAFTL_WRITE_MAX_STRIPES * sizeof(PageMeta_t)); + yaFTL.readMdPtr = (PageMeta_t *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone, (PAGES_PER_SUBLK)*sizeof(PageMeta_t)); + + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BufZone)) { + goto errorPath; + } + + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.quickRestore_tBuff); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.tmpReadBuffer); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.restoreTOC); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreIdx); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreData); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_readCxt); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_quickRestore); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_invalidateCxt); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_writeCxt); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreMountErase); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_restoreMount); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_clearEntryInCache); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_writeBTOC); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_indexLoadDirty); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_getStats); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_GetBlockTOC); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_IsDataPageCurrent); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.meta_WriteZoneData); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.singleMdPtr); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.writeMdPtr); + WMR_BufZone_Rebase(&yaFTL.BufZone, (void**)&yaFTL.readMdPtr); + WMR_BufZone_FinishedRebases(&yaFTL.BufZone); + + debug(INIT, "yaFTL.controlPageNo %d", yaFTL.controlPageNo); + debug(INIT, "BYTES_PER_PAGE %d", BYTES_PER_PAGE); + debug(INIT, "indexPageRatio %d", yaFTL.indexPageRatio); + + /* size of media in pages after we take out CTX ,free blocks and block TOC for each block */ + temp1 = (pagesInBlk - yaFTL.controlPageNo) * (FTL_AREA_SIZE - FTL_CXT_SECTION_SIZE - FREE_BLK_TRH); + + yaFTL.indexSize = (temp1 / (yaFTL.indexPageRatio * (pagesInBlk - yaFTL.controlPageNo))) * INDEX_BLOCKS_RATIO; + if (temp1 % (yaFTL.indexPageRatio * (pagesInBlk - yaFTL.controlPageNo))) + { + yaFTL.indexSize += INDEX_BLOCKS_RATIO; + } + + yaFTL.dataSize = FTL_AREA_SIZE - (yaFTL.indexSize + FTL_CXT_SECTION_SIZE); + yaFTL.logicalPartitionSize = temp1 - yaFTL.indexSize * PAGES_PER_SUBLK; /* logical parititon size in pages . this is the size reported to file system */ + + yaFTL.TOCtableEntriesNo = (FTL_AREA_SIZE * PAGES_PER_SUBLK * 4) / BYTES_PER_PAGE; + yaFTL.tocArray = (TOCEntry *)WMR_MALLOC(yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + if (yaFTL.tocArray == NULL) + { + goto errorPath; + } + yaFTL.blockArray = (BlockEntry *)WMR_MALLOC(FTL_AREA_SIZE * sizeof(BlockEntry)); + + if (yaFTL.blockArray == NULL) + { + goto errorPath; + } + + yaFTL.multiReadvpN = (UInt32 *)WMR_MALLOC(sizeof(UInt32) * PAGES_PER_SUBLK); + if (yaFTL.multiReadvpN == NULL) + { + goto errorPath; + } + + yaFTL.cxtSizeTOC = (yaFTL.TOCtableEntriesNo * sizeof(UInt32)) / BYTES_PER_PAGE; + if ((yaFTL.TOCtableEntriesNo * sizeof(UInt32)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeTOC++; + } + + yaFTL.cxtSizeBlockStatus = FTL_AREA_SIZE / BYTES_PER_PAGE; + if (FTL_AREA_SIZE % BYTES_PER_PAGE) + { + yaFTL.cxtSizeBlockStatus++; + } + + yaFTL.cxtSizeBlockRead = (FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeBlockRead++; + } + + yaFTL.cxtSizeBlockErase = (FTL_AREA_SIZE * sizeof(UInt32)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt32)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeBlockErase++; + } + + yaFTL.cxtSizeValidPagesD = (FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeValidPagesD++; + } + + yaFTL.cxtSizeValidPagesI = (FTL_AREA_SIZE * sizeof(UInt16)) / BYTES_PER_PAGE; + if ((FTL_AREA_SIZE * sizeof(UInt16)) % BYTES_PER_PAGE) + { + yaFTL.cxtSizeValidPagesI++; + } + + yaFTL.cxtSize = (yaFTL.cxtSizeTOC + yaFTL.cxtSizeBlockStatus + yaFTL.cxtSizeBlockRead + yaFTL.cxtSizeBlockErase + yaFTL.cxtSizeValidPagesI + yaFTL.cxtSizeValidPagesD) + (2 + 2 * yaFTL.controlPageNo) /* yaftl_controlInfo + currentDTOC + currentITOC + yaftl/vfl/fil stats .each one page */; +#ifndef AND_READONLY + yaFTL.cxtAllocation = 0; + yaFTL.cxtEraseCounter = 0; + yaFTL.cxtValid = 0; yaFTL.currentCxtVpn = 0xffffffff; +#endif // ! AND_READONLY + WMR_MEMSET(&yaFTL.seaState, 0, sizeof(yaFTL.seaState)); +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&stFTLStatistics, 0, sizeof(FTLStatistics)); +#endif /* AND_COLLECT_STATISTICS */ + +#if ENABLE_L2V_TREE + L2V_Search_Init(&yaFTL.read_c); +#endif // ENABLE_L2V_TREE + +#ifndef AND_READONLY + if (FTL_SUCCESS != YAFTL_GC_Init()) + { + goto errorPath; + } +#endif + + if (!BTOC_Init()) + { + goto errorPath; + } + + // Get wrState TOCs + yaFTL.wrState.data.TOC = BTOC_Alloc(0xfffffffd, 1); + yaFTL.wrState.index.TOC = BTOC_Alloc(0xfffffffe, 0); + +#if ENABLE_L2V_TREE + if (!L2V_Init(yaFTL.logicalPartitionSize, FTL_AREA_SIZE, PAGES_PER_SUBLK)) { + return FTL_CRITICAL_ERROR; + } +#endif // ENABLE_L2V_TREE + + // Success path + yaftl_init_done = TRUE32; + + if( yaFTL.indexSize == 3) + { + yaFTL.indexSize++; + yaFTL.dataSize--; + } + + yaFTL.erasedBlockCount = 0; + return FTL_SUCCESS; + +errorPath: + YAFTL_FreeMemory(); + return FTL_CRITICAL_ERROR; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* addBlockToList */ +/* DESCRIPTION */ +/* This function builds linked list of valid units ( used in restore ) */ +/* RETURN VALUES */ +/* pointer to a new entry ina list */ +/* */ +/*****************************************************************************/ +static BlockListType *addBlockToList(BlockListType *listHead, UInt16 Vbn, WeaveSeq_t weaveSeq) +{ + BlockListType *nextBlock; + + nextBlock = (BlockListType *)WMR_MALLOC(sizeof(BlockListType)); + if (nextBlock == NULL) + { + debug(ERROR, "cannot allocate %d ", sizeof(BlockListType)); + return NULL; + } + + nextBlock->next = NULL; + nextBlock->prev = NULL; + nextBlock->weaveSeq = weaveSeq; + nextBlock->blockNo = Vbn; + + if (listHead == NULL) + { + nextBlock->next = NULL; + nextBlock->prev = NULL; + listHead = nextBlock; + } + else + { + BlockListType *tmpPtr = listHead; + + while ((tmpPtr->next != NULL) && (tmpPtr->weaveSeq > weaveSeq)) + { + tmpPtr = tmpPtr->next; + } + if (tmpPtr->weaveSeq == weaveSeq) + { + if(sizeof(WeaveSeq_t) <= 4) + WMR_PRINT(QUAL_FATAL, "yaFTL found two blocks (%d, %d) with the same weaveSeq (%d)\n", tmpPtr->blockNo, Vbn, weaveSeq); + else + WMR_PRINT(QUAL_FATAL, "yaFTL found two blocks (%d, %d) with the same weaveSeq (%llu)\n", tmpPtr->blockNo, Vbn, weaveSeq); + } + if (tmpPtr->weaveSeq <= weaveSeq) + { + /* add new node in front of current one */ + + nextBlock->next = tmpPtr; + nextBlock->prev = tmpPtr->prev; + if (tmpPtr->prev != NULL) + { + tmpPtr->prev->next = nextBlock; + } + tmpPtr->prev = nextBlock; + } + else + { + /* add new node as a last node in the list */ + nextBlock->prev = tmpPtr; + nextBlock->next = NULL; + tmpPtr->next = nextBlock; + } + } + if (listHead->prev == NULL) + { + return listHead; + } + else + { + return nextBlock; + } +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* restoreIndexBlock */ +/* DESCRIPTION */ +/* This function is used in restore */ +/* */ +/*****************************************************************************/ +static ANDStatus restoreIndexBlock(UInt16 blockNo, UInt8 isCurrent, WeaveSeq_t listWeaveSequence ) +{ + UInt32 Vpn = blockNo * PAGES_PER_SUBLK, *pageBuffer = yaFTL.tmpReadBuffer, i; + ANDStatus status; + PageMeta_t *mdPtr = yaFTL.meta_restoreIdx; + BOOL32 stillClean = TRUE32; + UInt32 *bTOC = yaFTL.restoreTOC; + UInt32 upperBound; + + if(BTOC_GET_IPN(1) == 1) + { + upperBound = yaFTL.TOCtableEntriesNo; + } + else + { + upperBound = yaFTL.logicalPartitionSize; + } + + status = _readPage(Vpn, ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if (!META_IS_IDX(mdPtr) && (status == FTL_SUCCESS)) { +#ifndef AND_READONLY + WMR_PANIC("yaFTL restoreIndexBlock on a non-index block %d...\n", blockNo); +#else + WMR_PRINT(ERROR, "yaFTL restoreIndexBlock on a non-index block %d... trying anyway...\n", blockNo); +#endif + // Give it a shot anyway in read-only versions... + return FTL_SUCCESS; + } + + status = BTOC_Read(Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo), bTOC, mdPtr, FALSE32, FALSE32, upperBound); + + if ((status != FTL_SUCCESS)) + { + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + if (status != FIL_SUCCESS_CLEAN) + stillClean = FALSE32; + debug(INIT, "cannot read page properly"); + } + if (isCurrent) + { + yaFTL.wrState.index.block = blockNo; + yaFTL.blockArray[blockNo].status = BLOCK_I_CURRENT; + } + else + { + yaFTL.blockArray[blockNo].status = BLOCK_I_ALLOCATED; + } + if (META_IS_BTOC_IDX(mdPtr) && (status == FTL_SUCCESS)) + { + /* block was fully used and it contains valid TOC page */ + for (i = 0; (Int32)i < (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; i++) + { + if ((BTOC_Get(bTOC, (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), upperBound) != 0xffffffff) && (yaFTL.tocArray[BTOC_GET_IPN(BTOC_Get(bTOC, (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), upperBound))].indexPage == 0xffffffff)) + { + yaFTL.tocArray[BTOC_GET_IPN(BTOC_Get(bTOC, (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), upperBound))].indexPage = Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1); + yaFTL.blockArray[blockNo].validPagesINo++; + yaFTL.seaState.index.validPages++; + } + } + if (isCurrent) + { + yaFTL.wrState.index.nextPage = PAGES_PER_SUBLK; /* offset in current block of next free page */ + BTOC_Copy(yaFTL.wrState.index.TOC, bTOC, upperBound); + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } + } + } + else + { + /* probably current block . perform full body scan */ + if (isCurrent) + { + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + yaFTL.wrState.index.nextPage = PAGES_PER_SUBLK - yaFTL.controlPageNo; + } + else + { + yaFTL.wrState.index.nextPage = PAGES_PER_SUBLK; + } + } + for (i = 0; (Int32)i < (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; i++) + { + status = _readPage(Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1), ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if (((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) || ((status == FTL_SUCCESS) && ((!META_IS_IDX(mdPtr)) || (META_GET_IPN(mdPtr) >= yaFTL.TOCtableEntriesNo)))) + { + // vadim : just skip the page + debug(INIT, "failure during index scan at 0x%x", Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1)); + stillClean = FALSE32; + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + continue; + } + + if (status == FIL_SUCCESS_CLEAN) + { + if ((isCurrent) && (stillClean)) + { + yaFTL.wrState.index.nextPage = (UInt16)(PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1); + } + continue; + } + if(status != FTL_SUCCESS) + { +#ifndef AND_READONLY + WMR_PANIC("no invalid pages beyong this point"); +#else + WMR_PRINT(ERROR,"no invalid pages beyong this point\n"); +#endif + continue; + } + + stillClean = FALSE32; + if (isCurrent) + { + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1], mdPtr); + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreIndexBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } + } + if (yaFTL.tocArray[META_GET_IPN(mdPtr)].indexPage == 0xffffffff) + { + yaFTL.tocArray[META_GET_IPN(mdPtr)].indexPage = Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo - i - 1); + yaFTL.blockArray[blockNo].validPagesINo++; + yaFTL.seaState.index.validPages++; + } + } + } + if (isCurrent) + { + debug(INIT, "wrState.index.nextPage 0x%x -- %d blockNo 0x%x is current", yaFTL.wrState.index.nextPage, yaFTL.wrState.index.nextPage, blockNo); + } + + return FTL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* restoreBlock */ +/* DESCRIPTION */ +/* This function is used in restore */ +/* */ +/*****************************************************************************/ +static ANDStatus restoreBlock(UInt16 blockNo, UInt32 *indexTable, UInt8 isCurrent, UInt32 rangeOffset, UInt32 rangeSize, BlockRangeType *brPtr, WeaveSeq_t listWeaveSequence) +{ + UInt32 Vpn = blockNo * PAGES_PER_SUBLK, *pageBuffer = yaFTL.tmpReadBuffer, i, lastPageToCheck; + ANDStatus status = FTL_SUCCESS; + PageMeta_t *mdPtr = yaFTL.meta_restoreData; + BOOL32 stillClean = TRUE32; + UInt32 *bTOC = yaFTL.restoreTOC; + + if ((rangeOffset) && (brPtr != NULL)) + { + if ((brPtr[blockNo].end < rangeOffset) || (brPtr[blockNo].start >= (rangeOffset + rangeSize))) + { + return FTL_SUCCESS; + } + } + + if (yaFTL.blockArray[blockNo].validPagesINo == (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + return FTL_SUCCESS; + } + + if ((rangeOffset > 0) && (isCurrent)) + { + WMR_MEMSET(&yaFTL.wrState.data.TOC[yaFTL.wrState.data.nextPage], 0xff, (PAGES_PER_SUBLK - yaFTL.wrState.data.nextPage) * sizeof(UInt32)); + BTOC_Copy(bTOC, yaFTL.wrState.data.TOC, yaFTL.logicalPartitionSize); + META_SET_BTOC_DATA(mdPtr); + } + else + { + status = BTOC_Read(Vpn + (PAGES_PER_SUBLK - yaFTL.controlPageNo), bTOC, mdPtr, FALSE32, FALSE32, yaFTL.logicalPartitionSize); + if ((status != FTL_SUCCESS)) + { + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + if (status != FIL_SUCCESS_CLEAN) + stillClean = FALSE32; + debug(INIT, "cannot read block TOC during scan"); + //return status; + } + } + if (rangeOffset == 0) + { + if (isCurrent) + { + yaFTL.wrState.data.block = blockNo; + yaFTL.blockArray[blockNo].status = BLOCK_CURRENT; + } + else + { + yaFTL.blockArray[blockNo].status = BLOCK_ALLOCATED; + } + } + + if ((META_IS_BTOC_DATA(mdPtr)) && (status == FTL_SUCCESS)) + { + /* block was fully used and it contains valid TOC page */ + long length; + if ((rangeOffset > 0) && (isCurrent)) + { + length = yaFTL.wrState.data.nextPage; + } + else + { + length = (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; + } + + for (i = 0; (Int32)i < (Int32)length; i++) + { + // check the range before executing restore + if ((!rangeOffset) && (brPtr != NULL)) + { + if ((brPtr[blockNo].end == brPtr[blockNo].start) && (brPtr[blockNo].start == 0xffffffff)) + { + brPtr[blockNo].end = brPtr[blockNo].start = BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize); + } + else + { + if (brPtr[blockNo].end < BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize)) + { + brPtr[blockNo].end = BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize); + } + + if (brPtr[blockNo].start > BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize)) + { + brPtr[blockNo].start = BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize); + } + } + } + + if ((BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) < rangeOffset) || + (BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) >= (rangeOffset + rangeSize))) + { + continue; + } + yaFTL.blockArray[blockNo].validPagesINo++; + if ((BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) != 0xffffffff) && (indexTable[BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) - rangeOffset] == 0xffffffff)) + { + indexTable[BTOC_Get(bTOC, (UInt16)(length - (i + 1)), yaFTL.logicalPartitionSize) - rangeOffset] = Vpn + (length - (i + 1)); + yaFTL.blockArray[blockNo].validPagesDNo++; + yaFTL.seaState.data.validPages++; + } + } + if ((isCurrent) && (!rangeOffset)) + { + yaFTL.wrState.data.nextPage = PAGES_PER_SUBLK; /* offset in current block of next free page */ + BTOC_Copy(yaFTL.wrState.data.TOC, bTOC, yaFTL.logicalPartitionSize); +#ifndef AND_READONLY + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } +#endif + } + } + else + { + /* probably current block . perform full body scan */ + lastPageToCheck = PAGES_PER_SUBLK - yaFTL.controlPageNo; + if (isCurrent) + { + if (status == FTL_SUCCESS) + { + yaFTL.wrState.data.nextPage = PAGES_PER_SUBLK - yaFTL.controlPageNo; + } + else + { + yaFTL.wrState.data.nextPage = PAGES_PER_SUBLK; + } + yaFTL.blockArray[blockNo].validPagesINo = PAGES_PER_SUBLK - yaFTL.controlPageNo; + for (i = 0; (Int32)i < (Int32)PAGES_PER_SUBLK - yaFTL.controlPageNo; i++) + { + status = _readPage(Vpn + i, ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || (!META_IS_DATA(mdPtr)) || (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)) + { + lastPageToCheck = i; + yaFTL.wrState.data.nextPage = i; + break; + } + else + { + yaFTL.blockArray[blockNo].validPagesINo--; + } + + } + } + + + for (i = 0; (Int32)i < (Int32)lastPageToCheck; i++) + { + status = _readPage(Vpn + (lastPageToCheck - i - 1), ( UInt8 *)pageBuffer, mdPtr, FALSE32, TRUE32, FALSE32); + if (((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) || ((status == FTL_SUCCESS) && ((!META_IS_DATA(mdPtr)) || (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)))) + { + // vadim + // just ignore page and continue ( power failure during update + if (!rangeOffset) + { + yaFTL.blockArray[blockNo].validPagesINo++; + } + yaFTL.blockArray[blockNo].eraseBeforeUse = BLOCK_TO_BE_MOVED; + stillClean = FALSE32; + continue; + //return status; + } + + if ((status == FIL_SUCCESS_CLEAN) && (!rangeOffset)) + { + yaFTL.blockArray[blockNo].validPagesINo++; + } + + if ((isCurrent) && (status == FIL_SUCCESS_CLEAN) && (stillClean)) + { + yaFTL.wrState.data.nextPage = (UInt16)(lastPageToCheck - i - 1); + continue; + } + if (status == FIL_SUCCESS_CLEAN) + continue; + if(status != FTL_SUCCESS) + { +#ifndef AND_READONLY + WMR_PANIC("no invalid pages beyong this point"); +#else + WMR_PRINT(ERROR,"no invalid pages beyong this point\n"); +#endif + continue; + } + + stillClean = FALSE32; + if ((brPtr != NULL) && (!rangeOffset) && (META_GET_LBA(mdPtr) < yaFTL.logicalPartitionSize)) + { + if ((brPtr[blockNo].end == brPtr[blockNo].start) && (brPtr[blockNo].start == 0xffffffff)) + { + brPtr[blockNo].end = brPtr[blockNo].start = META_GET_LBA(mdPtr); + } + else + { + if (brPtr[blockNo].end < META_GET_LBA(mdPtr)) + { + brPtr[blockNo].end = META_GET_LBA(mdPtr); + } + + if (brPtr[blockNo].start > META_GET_LBA(mdPtr)) + { + brPtr[blockNo].start = META_GET_LBA(mdPtr); + } + } + } + + if (isCurrent) + { + yaFTL.wrState.data.TOC[lastPageToCheck - i - 1] = META_GET_LBA(mdPtr); +#ifndef AND_READONLY + if( listWeaveSequence <= META_GET_WEAVESEQ(mdPtr)) + { + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + } + else + { + if(sizeof(WeaveSeq_t) <= 4) + debug(ERROR, "restoreBlock weaveSequence is lower than expected 0x%x < 0x%x", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + else + debug(ERROR, "restoreBlock weaveSequence is lower than expected %llu < %llu", META_GET_WEAVESEQ(mdPtr) ,listWeaveSequence); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, listWeaveSequence); + } +#endif // ! AND_READONLY + } + if ((META_GET_LBA(mdPtr) < rangeOffset) || + (META_GET_LBA(mdPtr) >= (rangeOffset + rangeSize))) + { + continue; + } + // this to count all pages we already scanned . Once this number reaches blockszie we can ignore block in all subsequent iterations + yaFTL.blockArray[blockNo].validPagesINo++; + + if (indexTable[META_GET_LBA(mdPtr) - rangeOffset] == 0xffffffff) + { + indexTable[META_GET_LBA(mdPtr) - rangeOffset] = Vpn + (lastPageToCheck - i - 1); + yaFTL.blockArray[blockNo].validPagesDNo++; + yaFTL.seaState.data.validPages++; + } + } + } + + return FTL_SUCCESS; +} + +static ANDStatus readCXTInfo(UInt32 vpn, UInt8 *tBuff, UInt8 qm_valid, BOOL32 *formatSupported) +{ + UInt32 i = 0, size, k, j; + ANDStatus status; + PageMeta_t *md = yaFTL.meta_readCxt; + UInt8 *statPtr = NULL; + UInt16 *validPtr = NULL; + UInt32 *tocPtr = NULL; + struct YAFTLControlInfo *yaftlCI; + UInt32 tmpIndexSize = 0; + + debug(INIT, "readCXTInfo from offset 0x%x", vpn); + + status = _readPage(vpn, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { + return FTL_CRITICAL_ERROR; + } + yaftlCI = (struct YAFTLControlInfo *)tBuff; + if (WMR_MEMCMP(&(yaftlCI->versionNo), CXT_VER, 4) != 0) + + { + if (formatSupported != NULL) + { + *formatSupported = FALSE32; + } + debug(ERROR, "wrong version of CXT %s expected %s", (UInt8 *)(&yaftlCI->versionNo), CXT_VER); + + return FTL_CRITICAL_ERROR; + } +#ifndef AND_READONLY + if(sizeof(WeaveSeq_t) <= 4) + { + if (META_GET_WEAVESEQ(md) != 0xffffffff) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } + else + { + if (META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } +#endif + if( yaFTL.indexSize == 4) + tmpIndexSize = 3; + else + tmpIndexSize = yaFTL.indexSize; + + if (!((yaFTL.logicalPartitionSize == yaftlCI->logicalPartitionSize) && + (tmpIndexSize == yaftlCI->indexSize) && (yaFTL.controlPageNo == yaftlCI->controlPageNo) && + (yaFTL.indexPageRatio == yaftlCI->indexPageRatio) && (yaFTL.TOCtableEntriesNo == yaftlCI->TOCtableEntriesNo) && + (yaFTL.exportedRatio == yaftlCI->exportedRatio))) + { + debug(INIT, "CXT control info mismatch . Getting out"); + return FTL_CRITICAL_ERROR; + } + + if (qm_valid) + { + debug(INIT, "readCXTInfo from offset 0x%x", vpn); + yaFTL.freeCachePages = yaftlCI->freeCachePages; + yaFTL.wrState.data.block = yaftlCI->wrState_data_block; + yaFTL.wrState.data.nextPage = yaftlCI->wrState_data_nextPage; + yaFTL.seaState.data.freeBlocks = yaftlCI->seaState_data_freeBlocks; + yaFTL.wrState.index.block = yaftlCI->wrState_index_block; +#if NAND_PPN + yaFTL.wrState.weaveSeq = (WeaveSeq_t)yaftlCI->wrState_index_weaveSeq_Lo | ((WeaveSeq_t)yaftlCI->wrState_index_weaveSeq_Hi << 32UL); +#elif NAND_RAW + yaFTL.wrState.weaveSeq = yaftlCI->wrState_index_weaveSeq; +#else +#error PPN or raw? +#endif + yaFTL.wrState.index.nextPage = yaftlCI->wrState_index_nextPage; + yaFTL.seaState.index.freeBlocks = yaftlCI->seaState_index_freeBlocks; + yaFTL.seaState.data.allocdBlocks = yaftlCI->seaState_data_allocdBlocks; + yaFTL.seaState.index.allocdBlocks = yaftlCI->seaState_index_allocdBlocks; +#ifndef AND_READONLY + yaFTL.nextFreeCachePage = yaftlCI->nextFreeCachePage; +#if NAND_PPN + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, (WeaveSeq_t)yaftlCI->wrState_data_weaveSeq_Lo | ((WeaveSeq_t)yaftlCI->wrState_data_weaveSeq_Hi << 32UL)); +#elif NAND_RAW + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, yaftlCI->wrState_data_weaveSeq); +#else +#error PPN or raw? +#endif + yaFTL.cxtEraseCounter = yaftlCI->cxtEraseCounter; + yaFTL.FTLRestoreCnt = yaftlCI->FTLRestoreCnt; +#endif + yaFTL.indexCacheSize = yaftlCI->indexCacheSize; + yaFTL.exportedRatio = yaftlCI->exportedRatio; + + debug(INIT, "readCXTInfo logicalPartitionSize %d TOCtableEntriesNo %d \nwrState.data.block %d wrState.data.nextPage %d \n BYTES_PER_PAGE %d \n wrState.index.block %d wrState.index.nextPage %d wrState.weaveSeq %d" + , yaFTL.logicalPartitionSize, yaFTL.TOCtableEntriesNo, yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, BYTES_PER_PAGE, yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, yaFTL.wrState.weaveSeq); + debug(INIT, "readCXTInfo cxtSizeTOC %d cxtSizeBlockStatus %d \ncxtSizeBlockRead %d cxtSizeBlockErase %d\n cxtSizeValidPagesI %d cxtSizeValidPagesD %d ", + yaFTL.cxtSizeTOC, yaFTL.cxtSizeBlockStatus, yaFTL.cxtSizeBlockRead, yaFTL.cxtSizeBlockErase, yaFTL.cxtSizeValidPagesI, yaFTL.cxtSizeValidPagesD); + } + vpn++; + + if (qm_valid) + { + UInt8 i; + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _readPage(vpn + i, ( UInt8 *)((UInt8 *)yaFTL.wrState.data.TOC + (BYTES_PER_PAGE * i)), md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || (!META_IS_CXT(md))) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + } + } + vpn += yaFTL.controlPageNo; + if (qm_valid) + { + UInt8 i; + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _readPage(vpn + i, ( UInt8 *)((UInt8 *)yaFTL.wrState.index.TOC + (BYTES_PER_PAGE * i)), md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + } + } + vpn += yaFTL.controlPageNo; + +#ifdef AND_COLLECT_STATISTICS + /* set statistics */ + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + _FTLSetStatisticsFromCxt(tBuff); +#endif + vpn++; + + if (qm_valid) + { + size = yaFTL.TOCtableEntriesNo; + for (i = 0, j = 0; i < yaFTL.cxtSizeTOC; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + yaFTL.tocArray[j + k].indexPage = tocPtr[k]; + } + } + } + debug(INIT, " readCXTInfo after TOC table i = %d", i); + vpn += yaFTL.cxtSizeTOC; + if (qm_valid) + { + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockStatus; i++, size -= BYTES_PER_PAGE / sizeof(UInt8), j += BYTES_PER_PAGE / sizeof(UInt8)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + statPtr = (UInt8 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt8)) && (k < size); k++) + { + yaFTL.blockArray[j + k].status = statPtr[k]; + } + } + } + debug(INIT, "readCXTInfo after blockstatus i = %d", i); + vpn += yaFTL.cxtSizeBlockStatus; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockRead; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + yaFTL.blockArray[j + k].pagesRead = validPtr[k]; + } + } + debug(INIT, "readCXTInfo after blockread i = %d", i); + vpn += yaFTL.cxtSizeBlockRead; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockErase; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + yaFTL.blockArray[j + k].erasableCount = tocPtr[k]; + } + } + debug(INIT, "readCXTInfo after blockerase i = %d", i); + vpn += yaFTL.cxtSizeBlockErase; + + if (qm_valid) + { + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesI; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + yaFTL.blockArray[j + k].validPagesINo = validPtr[k]; + yaFTL.seaState.index.validPages += yaFTL.blockArray[j + k].validPagesINo; + } + } + } + debug(INIT, "readCXTInfo after validpagesI i = %d", i); + vpn += yaFTL.cxtSizeValidPagesI; + + if (qm_valid) + { + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesD; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + status = _readPage(vpn + i, tBuff, md, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) || !META_IS_CXT(md)) + { +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif + + return FTL_CRITICAL_ERROR; + } + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + yaFTL.blockArray[j + k].validPagesDNo = validPtr[k]; + yaFTL.seaState.data.validPages += yaFTL.blockArray[j + k].validPagesDNo; + } + } + } + debug(INIT, "readCXTInfo after validPagesD i = %d", i); +#ifdef AND_COLLECT_STATISTICS + if (qm_valid) + { + stFTLStatistics.ddwValidIndexPages = yaFTL.seaState.index.validPages; + stFTLStatistics.ddwValidDataPages = yaFTL.seaState.data.validPages; + } +#endif + + return FTL_SUCCESS; +} + +static ANDStatus quickRestore(UInt16 *cxtT, BOOL32 * formatSupported) +{ + UInt16 i; + ANDStatus status; + PageMeta_t *md = yaFTL.meta_quickRestore; + WeaveSeq_t lastCX = 0; + UInt32 currentCX = 0; + + /* + Read first page out of each Cxt unit to establish which contains a latest valid ( hopefully ) + copy of a quick mount info . Then read last copy and establish its validity . If it's valid read out the whole + thing and return success . If it's not valid use erase/read count info and return failure which would trigger full restore + */ + + if (yaFTL.quickRestore_tBuff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.blockArray[cxtT[i]].status = BLOCK_CTX_CNTR; + } + + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + status = _readPage(cxtT[i] * PAGES_PER_SUBLK, yaFTL.quickRestore_tBuff, md, FALSE32, TRUE32, FALSE32); + if (status != FTL_SUCCESS) + { +#ifndef AND_READONLY + if (status != FIL_SUCCESS_CLEAN) + { + VFL_Erase(cxtT[i], TRUE32); + yaFTL.blockArray[cxtT[i]].erasableCount++; + removeBlockFromEraseNowList(cxtT[i]); + } +#endif + continue; + } + + if(sizeof(WeaveSeq_t) <= 4) + { + if ((META_GET_WEAVESEQ(md) != 0xffffffff) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; +#ifndef AND_READONLY + yaFTL.currentCXTIndex = i; +#endif // ! AND_READONLY + } + } + else + { + if ((META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; +#ifndef AND_READONLY + yaFTL.currentCXTIndex = i; +#endif // ! AND_READONLY + } + } + } + if (lastCX != 0) + { + yaFTL.blockArray[currentCX].status = BLOCK_CTX_CURRENT; + debug(INIT, "currentCX is %d", currentCX); + } + else + { + /* no quick mount info */ + yaFTL.blockArray[cxtT[0]].status = BLOCK_CTX_CURRENT; +#ifndef AND_READONLY + yaFTL.currentCXTIndex = 0; +#endif // ! AND_READONLY + return 5; + } + + /* check validity */ + for (i = 0; (i + (UInt16)yaFTL.cxtSize) < PAGES_PER_SUBLK; i += (UInt16)(yaFTL.cxtSize + 1)) + { +#ifndef AND_READONLY + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); +#endif + status = _readPage((currentCX * PAGES_PER_SUBLK) + i, yaFTL.quickRestore_tBuff, md, FALSE32, TRUE32, FALSE32); // read first page of a potential cxt + if (status != FIL_SUCCESS) + { + // previous copy was the last one . no valid cxt avaiable + // we still read blockerase and blockread counts and then let full restore to kick in + break; + } + + status = _readPage((currentCX * PAGES_PER_SUBLK) + i + yaFTL.cxtSize, yaFTL.quickRestore_tBuff, md, FALSE32, TRUE32, FALSE32); + if (status == FIL_SUCCESS_CLEAN) + { + yaFTL.currentCxtVpn = currentCX * PAGES_PER_SUBLK + i; + + if (readCXTInfo(currentCX * PAGES_PER_SUBLK + i, yaFTL.quickRestore_tBuff, 1, formatSupported) == FTL_SUCCESS) + { + debug(INIT, "quickRestore : seaState.index.validPages = %d seaState.data.validPages = %d", yaFTL.seaState.index.validPages, yaFTL.seaState.data.validPages); +#ifndef AND_READONLY + yaFTL.cxtValid = 1; +#endif // ! AND_READONLY + return FTL_SUCCESS; + } + else + { + debug(INIT, "quickRestore : something is not quite right with it . going for a full one"); +#ifndef AND_READONLY + yaFTL.cxtValid = 0; +#endif // ! AND_READONLY + return 5; // TODO: find a cleaner way to mark a failure + } + } + } + // previous copy was the last one . no valid cxt avaiable + // we still read blockerase and blockread counts and then let full restore to kick in + yaFTL.currentCxtVpn = currentCX * PAGES_PER_SUBLK + i - (yaFTL.cxtSize + 1); // back off to the last invalid copy of cxt +#ifndef AND_READONLY + if(sizeof(WeaveSeq_t) <= 4) + { + if (META_GET_WEAVESEQ(md) != 0xffffffff) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } + else + { + if (META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) + { + yaFTL.cxtAllocation = META_GET_WEAVESEQ(md); + } + } + yaFTL.cxtValid = 0; +#endif // ! AND_READONLY + + debug(INIT, "cannot find valid copy of cxt ... reading only relevant info from %d", yaFTL.currentCxtVpn); + readCXTInfo(yaFTL.currentCxtVpn, yaFTL.quickRestore_tBuff, 0, formatSupported); //only need to read out erase and read counters + return 5; +} + +#ifndef AND_READONLY +ANDStatus invalidateCXT(void) +{ + PageMeta_t *mdPtr = yaFTL.meta_invalidateCxt; + ANDStatus status; + Buffer buff; + + buff.pData = (UInt8 *)yaFTL.wrState.index.TOC; + buff.pSpare = (UInt8 *)mdPtr; + + SetupMeta_Cxt(mdPtr, yaFTL.cxtAllocation); + status = VFL_Write(yaFTL.currentCxtVpn + yaFTL.cxtSize, &buff, TRUE32, FALSE32); + if (status != VFL_SUCCESS) + // erase current cxt + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + //return status; + } + + return FTL_SUCCESS; +} +#endif + +#ifndef AND_READONLY +ANDStatus writeCXTInfo(UInt32 vpn, UInt8* tBuff, BOOL32 statsOnly) +{ + UInt32 i, size, k, j; + PageMeta_t *md = yaFTL.meta_writeCxt; + UInt8 *statPtr = NULL; + UInt16 * validPtr = NULL; + UInt32 *tocPtr = NULL; + UInt32 tempVpn = vpn; + ANDStatus status; + struct YAFTLControlInfo *yaftlCI = (struct YAFTLControlInfo *)tBuff; + + if (yaFTL.cxtValid == 1) + { + return FTL_SUCCESS; + } + + yaFTL.cxtAllocation++; + SetupMeta_Cxt(md, yaFTL.cxtAllocation); + + /* Read yaftl control info first also currentDTOC and currentITOC = 3 pages*/ + WMR_MEMCPY(yaftlCI, CXT_VER, 4); // update cxt version info + yaftlCI->controlPageNo = yaFTL.controlPageNo; + yaftlCI->indexPageRatio = yaFTL.indexPageRatio; + if( yaFTL.indexSize == 4) + yaftlCI->indexSize = 3; + else + yaftlCI->indexSize = yaFTL.indexSize; + yaftlCI->logicalPartitionSize = yaFTL.logicalPartitionSize; + yaftlCI->TOCtableEntriesNo = yaFTL.TOCtableEntriesNo; + yaftlCI->freeCachePages = yaFTL.freeCachePages; + yaftlCI->nextFreeCachePage = yaFTL.nextFreeCachePage; + yaftlCI->wrState_data_block = yaFTL.wrState.data.block; +#if NAND_PPN + yaftlCI->wrState_data_weaveSeq_Lo = (UInt32)yaFTL.wrState.weaveSeq & 0xFFFFFFFFUL; + yaftlCI->wrState_data_weaveSeq_Hi = (UInt32)(yaFTL.wrState.weaveSeq >> 32ul) & 0xFFFFFFFFUL; +#elif NAND_RAW + yaftlCI->wrState_data_weaveSeq = (WeaveSeq_t)yaFTL.wrState.weaveSeq; +#else +#error PPN or raw? +#endif + + yaftlCI->wrState_data_nextPage = yaFTL.wrState.data.nextPage; + yaftlCI->seaState_data_freeBlocks = yaFTL.seaState.data.freeBlocks; + yaftlCI->wrState_index_block = yaFTL.wrState.index.block; +#if NAND_PPN + yaftlCI->wrState_index_weaveSeq_Lo = (UInt32)yaFTL.wrState.weaveSeq & 0xFFFFFFFFUL; + yaftlCI->wrState_index_weaveSeq_Hi = (UInt32)(yaFTL.wrState.weaveSeq >> 32UL) & 0xFFFFFFFFUL; +#elif NAND_RAW + yaftlCI->wrState_index_weaveSeq = (WeaveSeq_t)yaFTL.wrState.weaveSeq; +#else +#error PPN or raw? +#endif + yaftlCI->wrState_index_nextPage = yaFTL.wrState.index.nextPage; + yaftlCI->seaState_index_freeBlocks = yaFTL.seaState.index.freeBlocks; + yaftlCI->seaState_data_allocdBlocks = yaFTL.seaState.data.allocdBlocks; + yaftlCI->seaState_index_allocdBlocks = yaFTL.seaState.index.allocdBlocks; + yaftlCI->indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; // use default size for backward compatibility + yaftlCI->exportedRatio = yaFTL.exportedRatio; + yaftlCI->cxtEraseCounter = yaFTL.cxtEraseCounter; + yaftlCI->FTLRestoreCnt = yaFTL.FTLRestoreCnt; + /* yaftl control info */ + + status = _writePage(vpn, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + vpn++; + + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _writePage(vpn + i, (UInt8 *)((UInt8 *)yaFTL.wrState.data.TOC + BYTES_PER_PAGE * i), md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + vpn += yaFTL.controlPageNo; + + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _writePage(vpn + i, (UInt8 *)((UInt8 *)yaFTL.wrState.index.TOC + BYTES_PER_PAGE * i), md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + vpn += yaFTL.controlPageNo; + + /* Write statistics */ +#ifdef AND_COLLECT_STATISTICS + _FTLGetStatisticsToCxt(tBuff); + +#else + WMR_MEMSET(tBuff, 0, BYTES_PER_PAGE); +#endif + status = _writePage(vpn, (UInt8 *)tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + vpn++; + + size = yaFTL.TOCtableEntriesNo; + + if(statsOnly == TRUE32) + WMR_MEMSET(md, 0, sizeof(PageMeta_t)); + + for (i = 0, j = 0; i < yaFTL.cxtSizeTOC; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + tocPtr[k] = yaFTL.tocArray[j + k].indexPage; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeTOC; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockStatus; i++, size -= BYTES_PER_PAGE / sizeof(UInt8), j += BYTES_PER_PAGE / sizeof(UInt8)) + { + statPtr = (UInt8 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt8)) && (k < size); k++) + { + statPtr[k] = yaFTL.blockArray[j + k].status; + + // Fixup state so running GC operations don't break on-media format: + if (BLOCK_GC == statPtr[k]) + { + statPtr[k] = BLOCK_ALLOCATED; + } + else if (BLOCK_I_GC == statPtr[k]) + { + statPtr[k] = BLOCK_I_ALLOCATED; + } + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeBlockStatus; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockRead; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + validPtr[k] = yaFTL.blockArray[j + k].pagesRead; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeBlockRead; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeBlockErase; i++, size -= BYTES_PER_PAGE / sizeof(UInt32), j += BYTES_PER_PAGE / sizeof(UInt32)) + { + tocPtr = (UInt32 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt32)) && (k < size); k++) + { + tocPtr[k] = yaFTL.blockArray[j + k].erasableCount; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeBlockErase; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesI; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + validPtr[k] = yaFTL.blockArray[j + k].validPagesINo; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + vpn += yaFTL.cxtSizeValidPagesI; + + size = FTL_AREA_SIZE; + for (i = 0, j = 0; i < yaFTL.cxtSizeValidPagesD; i++, size -= BYTES_PER_PAGE / sizeof(UInt16), j += BYTES_PER_PAGE / sizeof(UInt16)) + { + validPtr = (UInt16 *)tBuff; + for (k = 0; (k < BYTES_PER_PAGE / sizeof(UInt16)) && (k < size); k++) + { + validPtr[k] = yaFTL.blockArray[j + k].validPagesDNo; + } + status = _writePage(vpn + i, tBuff, md, FALSE32); + if (status != VFL_SUCCESS) + { + return status; + } + } + + yaFTL.currentCxtVpn = tempVpn; + yaFTL.cxtValid = 1; + + return status; +} + +#endif + +#ifndef AND_READONLY +static void moveCXTarea(void) +{ + UInt32 i = 0, j; + UInt16 tempCXT[FTL_CXT_SECTION_SIZE]; + ANDStatus status; + + if (yaFTL.seaState.data.freeBlocks < FTL_CXT_SECTION_SIZE) + { + return; + } + + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + + for (j = 0; j < FTL_CXT_SECTION_SIZE; j++) + { + tempCXT[j] = yaFTL.cxtTable[j]; + } + + for (j = 0; (Int32)j < FTL_AREA_SIZE; j++) + { + if ((yaFTL.blockArray[j].status == BLOCK_FREE) && ( (yaFTL.blockArray[j].erasableCount + CXT_ERASE_GAP) < yaFTL.blockArray[tempCXT[i]].erasableCount)) + { + if( yaFTL.blockArray[j].eraseBeforeUse != 0) + { + status = VFL_Erase(j, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) j, status); + continue; + } + yaFTL.blockArray[j].eraseBeforeUse = 0; + removeBlockFromEraseNowList((UInt16)j); + yaFTL.erasedBlockCount++; + } + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + yaFTL.erasedBlockCount--; + yaFTL.cxtTable[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + + if ( i == 0 ) + return; + + VFL_ChangeFTLCxtVbn(yaFTL.cxtTable); + yaFTL.currentCXTIndex = 0; + yaFTL.currentCxtVpn = 0xffffffff; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + for (j = 0; j < FTL_CXT_SECTION_SIZE; j++) + { + VFL_Erase((UInt16)tempCXT[j], TRUE32); + removeBlockFromEraseNowList((UInt16)tempCXT[j]); + yaFTL.blockArray[tempCXT[j]].status = BLOCK_FREE; + yaFTL.blockArray[tempCXT[j]].erasableCount++; + yaFTL.blockArray[tempCXT[j]].pagesRead = 0; + yaFTL.blockArray[tempCXT[j]].pagesReadSubCounter = 0; + yaFTL.blockArray[tempCXT[j]].validPagesDNo = yaFTL.blockArray[tempCXT[j]].validPagesINo = 0; + yaFTL.blockArray[tempCXT[j]].eraseBeforeUse = 0; + if (j < i) + yaFTL.erasedBlockCount++; + // Update max erase count + if (yaFTL.blockArray[tempCXT[j]].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[tempCXT[j]].erasableCount; + } + } + for(j = i; j < FTL_CXT_SECTION_SIZE; j++) + yaFTL.blockArray[yaFTL.cxtTable[j]].status = BLOCK_CTX_CNTR; +} + +ANDStatus quickMountUpdate(BOOL32 statsOnly) +{ + UInt8 *tBuff = NULL; + Buffer *tmpB = NULL; + ANDStatus status = FTL_SUCCESS; + UInt32 i; + /* + * Read first page out of each Cxt unit to establish which contains a latest valid ( hopefully ) + * copy of a quick mount info . Then read last copy and establish its validity . If it's valid read out the whole + * thing and return success . If it's not valid use erase/read count info and return failure which would trigger full restore + */ + if (yaFTL.cxtValid == 1) // no need to update valid cxt + { + return FTL_SUCCESS; + } + + WMR_TRACE_IST_1(CxtSave, START, statsOnly); + + for (i = 0; ((Int32)i < FTL_AREA_SIZE) && (statsOnly == FALSE32); i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + if(yaFTL.formatWasCalled == 0) + { + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + yaFTL.blockArray[i].erasableCount++; + yaFTL.periodicCxt.erases++; + yaFTL.erasedBlockCount++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + removeBlockFromEraseNowList(i); + } + yaFTL.blockArray[i].eraseBeforeUse = 0; + } + } + + yaFTL.formatWasCalled = 0; + + tmpB = BUF_Get(BUF_MAIN_ONLY); + if (tmpB == NULL) + { + WMR_TRACE_IST_1(CxtSave, END, FTL_CRITICAL_ERROR); + return FTL_CRITICAL_ERROR; + } + + tBuff = (UInt8 *)tmpB->pData; + + if (yaFTL.currentCxtVpn == 0xffffffff) + { + /* First time update */ + status = writeCXTInfo(yaFTL.cxtTable[yaFTL.currentCXTIndex] * PAGES_PER_SUBLK, tBuff, statsOnly); + if (status != VFL_SUCCESS) + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + } + else + { + /* check whether we can add cxt to a current cxt block */ + if (((yaFTL.currentCxtVpn / PAGES_PER_SUBLK) == ((yaFTL.currentCxtVpn + 1 + yaFTL.cxtSize) / PAGES_PER_SUBLK)) && + (((yaFTL.currentCxtVpn + 1 + yaFTL.cxtSize) / PAGES_PER_SUBLK) == ((yaFTL.currentCxtVpn + (1 + yaFTL.cxtSize) * 2) / PAGES_PER_SUBLK))) + { + status = writeCXTInfo(yaFTL.currentCxtVpn + 1 + yaFTL.cxtSize, tBuff, statsOnly); + if (status != VFL_SUCCESS) + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + } + else + { + /* not enough space in current cxt block . erase the oldest and update in it */ + + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + status = writeCXTInfo(yaFTL.cxtTable[yaFTL.currentCXTIndex] * PAGES_PER_SUBLK, tBuff, statsOnly); + if (status != VFL_SUCCESS) + { + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CNTR; + yaFTL.currentCXTIndex++; + if (yaFTL.currentCXTIndex >= FTL_CXT_SECTION_SIZE) + { + yaFTL.currentCXTIndex = 0; + } + yaFTL.blockArray[yaFTL.cxtTable[yaFTL.currentCXTIndex]].status = BLOCK_CTX_CURRENT; + /* todo : add erase in case this is not the first time + todo : check if we need to erase ( no need if this is the first time we use this unit ) */ + VFL_Erase((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex], TRUE32); + removeBlockFromEraseNowList((UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]); + yaFTL.blockArray[(UInt16)yaFTL.cxtTable[yaFTL.currentCXTIndex]].erasableCount++; + yaFTL.cxtEraseCounter++; + yaFTL.currentCxtVpn = 0xffffffff; + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, status); + return status; + } + } + } + BUF_Release(tmpB); + WMR_TRACE_IST_1(CxtSave, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +#endif // 0 : still working on the above code +/*****************************************************************************/ +/* */ +/* NAME */ +/* restoreMount */ +/* DESCRIPTION */ +/* Perfroms restore mount in case control info is dirty */ +/* */ +/*****************************************************************************/ + +UInt16 findFreeCacheEntry(void); + +static void SetupFreeAndAllocd(void) +{ + UInt32 i; + + yaFTL.seaState.data.freeBlocks = 0; + yaFTL.seaState.data.allocdBlocks = 0; + yaFTL.seaState.index.freeBlocks = 0; + yaFTL.seaState.index.allocdBlocks = 0; + yaFTL.seaState.freeBlocks = 0; + + for (i = 0; i < FTL_AREA_SIZE; i++) { + switch (yaFTL.blockArray[i].status) { + case BLOCK_ALLOCATED: + case BLOCK_CURRENT: + yaFTL.seaState.data.allocdBlocks++; + break; + + case BLOCK_I_ALLOCATED: + case BLOCK_I_CURRENT: + yaFTL.seaState.index.allocdBlocks++; + break; + + case BLOCK_FREE: + yaFTL.seaState.freeBlocks++; + break; + + case BLOCK_CTX_CNTR: + case BLOCK_CTX_CURRENT: + break; + + default: +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Unknown block type: 0x%x\n", yaFTL.blockArray[i].status); +#else + WMR_PRINT(QUAL_FATAL, "Unknown block type: 0x%x\n", yaFTL.blockArray[i].status); +#endif + } + } + + if (yaFTL.seaState.freeBlocks < 2) + { +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("no free blocks %d ", yaFTL.seaState.freeBlocks); +#else + WMR_PRINT(QUAL_FATAL, "no free blocks %d ", yaFTL.seaState.freeBlocks); +#endif + } + + yaFTL.seaState.index.freeBlocks = yaFTL.indexSize - yaFTL.seaState.index.allocdBlocks; + if (yaFTL.seaState.freeBlocks > (UInt32)yaFTL.seaState.index.freeBlocks) + { + yaFTL.seaState.data.freeBlocks = yaFTL.seaState.freeBlocks - yaFTL.seaState.index.freeBlocks; + } + else + { + if (yaFTL.seaState.freeBlocks == 1) + { + yaFTL.seaState.index.freeBlocks = 0; + yaFTL.seaState.data.freeBlocks = 1; + } + else + { + yaFTL.seaState.index.freeBlocks = 1; + yaFTL.seaState.data.freeBlocks = yaFTL.seaState.freeBlocks - yaFTL.seaState.index.freeBlocks; + } + } +} + + +#ifndef AND_READONLY +static ANDStatus restoreMountEraseIndex(UInt16 * ctxT) +{ + UInt32 Vpn; + ANDStatus status = FTL_SUCCESS; + UInt32 *pageBuffer = NULL; + UInt32 i, n; + Buffer * pBuff; + + UInt32 j; + UInt32 *indexTable; + UInt8 ctxNo = 0; + PageMeta_t *mdPtr = yaFTL.meta_restoreMountErase; + BlockListType *listHead = NULL, *tempPtr, *tempHdr; + BlockRangeType *brPtr; + // u_int64_t t1,t2,t3,t4,t22; + BlockListType *listIndexHead = NULL, *tempIndexPtr; + + yaFTL.wrState.index.block = 0xffffffff; + WMR_MEMSET(yaFTL.tocArray, 0xff, yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + WMR_MEMSET(&yaFTL.seaState, 0, sizeof(yaFTL.seaState)); + // t1=mach_absolute_time(); + // Nir - what do you mean we have no cxt? those are kept by the VFL for you... + if (ctxT[0] == 0xffff) + { + /* No ctx units . need to allocate at the end of restore */ + ctxNo = 0; + } + else + { + ctxNo = FTL_CXT_SECTION_SIZE; + } + + Vpn = 0; + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++, Vpn += PAGES_PER_SUBLK) + { + /* + go over all blocks in partititon + todo : setup currentDndex block . Also need to calculate free dataBlocks and perhaps execute GC before we finish restore . + */ + + if (ctxNo) + { + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + } + for (n = 0; n < (UInt32)(PAGES_PER_SUBLK - yaFTL.controlPageNo); n++) + { + status = _readPage(Vpn + n, pBuff->pData, mdPtr, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right with the x%x x%x", Vpn / PAGES_PER_SUBLK, status); + continue; + } + + if (status == FIL_SUCCESS_CLEAN) + { + break; + } + + if (status == FTL_SUCCESS) + { + if((META_IS_IDX(mdPtr)) && (META_GET_IPN(mdPtr) >= yaFTL.TOCtableEntriesNo)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + if((META_IS_DATA(mdPtr)) && (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + break; + } + } + + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right block x%x ... probably need to erase", i); +#ifndef AND_READONLY + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); +#endif + continue; + } + + if ((META_ARE_FLAGS_FF(mdPtr) && (META_GET_LBA(mdPtr) == 0xffffffff)) || (status == FIL_SUCCESS_CLEAN)) /* free block */ + { + yaFTL.blockArray[i].status = BLOCK_FREE; + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + + continue; + } + if (META_IS_IDX(mdPtr)) /* index block : erase */ + { +#ifndef AND_READONLY + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); +#else + /* create a parallel list for Index blocks */ + listIndexHead = addBlockToList(listIndexHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listIndexHead); +#endif + continue; + } + /* Valid data block . Add it to a sorted linked list of data blocks according to weaveSeq */ + if (META_IS_DATA(mdPtr)) + { + yaFTL.blockArray[i].status = BLOCK_ALLOCATED; + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + listHead = addBlockToList(listHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listHead); + continue; + } + debug(ERROR, "block that does not belong to anything 0x%x .. probably need to erase", META_GET_ALL_FLAGS(mdPtr)); +#ifndef AND_READONLY + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); +#endif + } + // t2=mach_absolute_time(); + + BUF_Release(pBuff); + + yaFTL.freeCachePages = (UInt16)yaFTL.indexCacheSize; +#ifndef AND_READONLY + yaFTL.nextFreeCachePage = 0; +#endif + debug(INIT, " restoreMount[after blocklist has been created]"); + if (listIndexHead != NULL) + { + tempIndexPtr = listIndexHead; + while (tempIndexPtr != NULL) + { + if (tempIndexPtr == listIndexHead) + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 1, tempIndexPtr->weaveSeq); + } + else + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 0, tempIndexPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + freeBlockList(tempIndexPtr); + freeBlockList(listHead); + return status; + } + listIndexHead = tempIndexPtr; + tempIndexPtr = tempIndexPtr->next; + WMR_FREE(listIndexHead, sizeof(BlockListType)); + } + } + if (yaFTL.wrState.index.block == 0xffffffff) + { + debug(INIT, "index list is empty "); + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.index.block = i; /* current physical block being used for updates */ + yaFTL.wrState.index.nextPage = 0; /* offset in current block of next free page */ + WMR_MEMSET(yaFTL.wrState.index.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.blockArray[i].status = BLOCK_I_CURRENT; + debug(INIT, "current index block would be %d", i); + break; + } + } + } + + // t22=mach_absolute_time(); + if (listHead == NULL) /* empty partition */ + { + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.data.block = i; + yaFTL.blockArray[yaFTL.wrState.data.block].status = BLOCK_CURRENT; + break; + } + } + yaFTL.wrState.data.nextPage = 0; + WMR_MEMSET(yaFTL.wrState.data.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); +#ifndef AND_READONLY + if (ctxNo == 0) + { + i = 0; + for (j = 0; (Int32)j < FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.cxtTable[i] = ctxT[i]; + } + } +#endif + + // Set up block counters + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + SetupFreeAndAllocd(); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = 0; + stFTLStatistics.ddwValidIndexPages = 0; +#endif + yaFTL.seaState.distCheckable = 1; + CheckBlockDist(); + return FTL_SUCCESS; + } + + tempHdr = listHead; + + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (NULL == pBuff) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + if (!_allocateRestoreIndexBuffers(&brPtr, &indexTable, &tempIndexBufferSize)) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + WMR_MEMSET(brPtr, 0xff, (FTL_AREA_SIZE * sizeof(BlockRangeType))); + + // Set up block counters + SetupFreeAndAllocd(); + + for (j = 0; j < yaFTL.logicalPartitionSize; j += tempIndexBufferSize) + { + WMR_MEMSET(indexTable, 0xff, tempIndexBufferSize * sizeof(UInt32)); + tempPtr = listHead = tempHdr; + while (tempPtr != NULL) + { + if (tempPtr == listHead) + { + status = restoreBlock(tempPtr->blockNo, indexTable, 1, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + else + { + status = restoreBlock(tempPtr->blockNo, indexTable, 0, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + freeBlockList(tempHdr); + BUF_Release(pBuff); + return status; + } + listHead = tempPtr; + tempPtr = tempPtr->next; + if ((j + tempIndexBufferSize) >= yaFTL.logicalPartitionSize) + { + tempHdr = tempPtr; + WMR_FREE(listHead, sizeof(BlockListType)); + } + } + + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + + for (i = 0, pageBuffer = indexTable; (i < (tempIndexBufferSize * 4) / BYTES_PER_PAGE) && ((i * yaFTL.indexPageRatio + j) < yaFTL.logicalPartitionSize); i++, pageBuffer += (BYTES_PER_PAGE / 4)) + { + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + if (WMR_MEMCMP(pageBuffer, pBuff->pData, BYTES_PER_PAGE) != 0) + { + UInt16 cE; + + /* Need to copy valid page in index cache */ + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) + { + yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; + } + + cE = findFreeCacheEntry(); + if (cE == 0xffff) + { +#ifdef AND_READONLY + debug(ERROR, "can still be enough to mount OS partition"); + BUF_Release(pBuff); + return FTL_SUCCESS; +#else + WMR_MEMCPY(yaFTL.tmpReadBuffer, pageBuffer, BYTES_PER_PAGE); + SetupMeta_Index(mdPtr, i + ((j * 4) / BYTES_PER_PAGE)); + status = writeIndexPage((UInt8*)yaFTL.tmpReadBuffer, mdPtr, 0); + if (status != FTL_SUCCESS) + { + BUF_Release(pBuff); + return FTL_CRITICAL_ERROR; + } + + continue; +#endif + } + WMR_MEMCPY(yaFTL.indexCache[cE].indexPage, pageBuffer, BYTES_PER_PAGE); + yaFTL.indexCache[cE].status = IC_DIRTY_PAGE; + yaFTL.indexCache[cE].tocEntry = (UInt16)(i + ((j * 4) / BYTES_PER_PAGE)); + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = cE; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + } + else + { + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = 0xffff; + } + } + } + // t3=mach_absolute_time(); + +#ifndef AND_READONLY + /* Vadim - check presence of CXT blocks . If there are none allocate them */ + + if (ctxNo == 0) + { + i = 0; + for (j = 0; j < (UInt32)FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + } +#endif + + BUF_Release(pBuff); + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + + // t4=mach_absolute_time(); + // debug(MISC, "time spent in restore is %llu %llu %llu %llu %llu ",t2-t1,t22-t2,t3-t22,t4-t3,t4-t1); + debug(INIT, "current i block %d current i page %d", yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage); + + debug(INIT, "restoreMount : logicalPartitionSize %d TOCtableEntriesNo %d \nwrState.data.block %d wrState.data.nextPage %d \n BYTES_PER_PAGE %d \n wrState.index.block %d wrState.index.nextPage %d wrState.weaveSeq %d" + , yaFTL.logicalPartitionSize, yaFTL.TOCtableEntriesNo, yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, BYTES_PER_PAGE, yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, yaFTL.wrState.weaveSeq); + debug(INIT, "restoreMount seaState.data.allocdBlocks %d dataSize %d FTL_SIZE %d pagesinblock %d", yaFTL.seaState.data.allocdBlocks, yaFTL.dataSize, FTL_AREA_SIZE, PAGES_PER_SUBLK); + + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } +#ifndef AND_READONLY + for (i = 0; ((Int32)i < FTL_AREA_SIZE); i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) && (yaFTL.blockArray[i].validPagesDNo == 0 )) + { + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + continue; + } + if ((yaFTL.blockArray[i].status == BLOCK_I_ALLOCATED) && (yaFTL.blockArray[i].validPagesINo == 0 )) + { + YAFTL_GC_Index(i, FALSE32); + } + } + // Move the current blocks out : + i = yaFTL.wrState.index.block; + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE)&& (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + i = yaFTL.wrState.data.block; + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + while ((yaFTL.indexSize - FREE_I_BLOCK_TRS) < yaFTL.seaState.index.allocdBlocks) + { + debug(MISC, "free index %d %d", yaFTL.indexSize, yaFTL.seaState.index.allocdBlocks); + YAFTL_GC_Index(0xffffffff, FALSE32); + } +#endif + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + yaFTL.blockArray[i].validPagesINo = 0; + } +#ifndef AND_READONLY + if ((yaFTL.blockArray[i].status != BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_MOVED)) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + else + { + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + } +#endif + } + debug(INIT, "restoreMount : seaState.index.validPages = %d seaState.data.validPages = %d", yaFTL.seaState.index.validPages, yaFTL.seaState.data.validPages); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = yaFTL.seaState.data.validPages; + stFTLStatistics.ddwValidIndexPages = yaFTL.seaState.index.validPages; +#endif + + yaFTL.seaState.distCheckable = 1; + CheckBlockDist(); + return FTL_SUCCESS; +} + +#endif + + +static ANDStatus restoreMount(UInt16 * ctxT, const UInt32 readOnly) +{ + UInt32 Vpn; + ANDStatus status = FTL_SUCCESS; + UInt32 *pageBuffer = NULL; + UInt32 i, n; + Buffer * pBuff; + + UInt32 j; + UInt32 *indexTable; + UInt8 ctxNo = 0; + PageMeta_t *mdPtr = yaFTL.meta_restoreMount; + BlockListType *listHead = NULL, *tempPtr, *tempHdr; + BlockRangeType *brPtr; + // u_int64_t t1,t2,t3,t4,t22; + BlockListType *listIndexHead = NULL, *tempIndexPtr; + + yaFTL.wrState.index.block = 0xffffffff; + WMR_MEMSET(yaFTL.tocArray, 0xff, yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + WMR_MEMSET(&yaFTL.seaState, 0, sizeof(yaFTL.seaState)); + + // t1=mach_absolute_time(); + // Nir - what do you mean we have no cxt? those are kept by the VFL for you... + if (ctxT[0] == 0xffff) + { + /* No ctx units . need to allocate at the end of restore */ + ctxNo = 0; + } + else + { + ctxNo = FTL_CXT_SECTION_SIZE; + } + + Vpn = 0; + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++, Vpn += PAGES_PER_SUBLK) + { + /* + go over all blocks in partititon + todo : setup currentDndex block . Also need to calculate free dataBlocks and perhaps execute GC before we finish restore . + */ + + if (ctxNo) + { + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + } + for (n = 0; n < (UInt32)(PAGES_PER_SUBLK - yaFTL.controlPageNo); n++) + { + status = _readPage(Vpn + n, pBuff->pData, mdPtr, FALSE32, TRUE32, FALSE32); + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right with the x%x x%x", Vpn / PAGES_PER_SUBLK, status); + continue; + } + + if (status == FIL_SUCCESS_CLEAN) + { + break; + } + + if (status == FTL_SUCCESS) + { + if((META_IS_IDX(mdPtr)) && (META_GET_IPN(mdPtr) >= yaFTL.TOCtableEntriesNo)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + if((META_IS_DATA(mdPtr)) && (META_GET_LBA(mdPtr) >= yaFTL.logicalPartitionSize)) + { + status = FTL_CRITICAL_ERROR; + continue; + } + break; + } + } + + if ((status != FTL_SUCCESS) && (status != FIL_SUCCESS_CLEAN)) + { + debug(INIT, "something is not right block x%x ... probably need to erase", i); +#ifndef AND_READONLY + if ( !readOnly ) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); + } +#endif + continue; + } + + if ((META_ARE_FLAGS_FF(mdPtr) && (META_GET_LBA(mdPtr) == 0xffffffff)) || (status == FIL_SUCCESS_CLEAN)) /* free block */ + { + yaFTL.blockArray[i].status = BLOCK_FREE; + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + + continue; + } + if (META_IS_IDX(mdPtr)) /* index block : erase */ + { + /* create a parallel list for Index blocks */ + listIndexHead = addBlockToList(listIndexHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listIndexHead); + continue; + } + /* Valid data block . Add it to a sorted linked list of data blocks according to weaveSeq */ + if (META_IS_DATA(mdPtr)) + { + listHead = addBlockToList(listHead, (UInt16)i, META_GET_WEAVESEQ(mdPtr)); + yaFTL.wrState.weaveSeq = WMR_MAX(yaFTL.wrState.weaveSeq, META_GET_WEAVESEQ(mdPtr)); + WMR_ASSERT(NULL != listHead); + continue; + } + debug(ERROR, "block that does not belong to anything 0x%x .. probably need to erase", META_GET_ALL_FLAGS(mdPtr)); +#ifndef AND_READONLY + if ( !readOnly ) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].status = BLOCK_FREE; + } + yaFTL.blockArray[i].erasableCount++; + removeBlockFromEraseNowList((UInt16)i); + } +#endif + } + // t2=mach_absolute_time(); + + BUF_Release(pBuff); + + yaFTL.freeCachePages = (UInt16)yaFTL.indexCacheSize; +#ifndef AND_READONLY + if ( !readOnly ) + { + yaFTL.nextFreeCachePage = 0; + } +#endif + debug(INIT, " restoreMount[after blocklist has been created]"); + if (listIndexHead != NULL) + { + tempIndexPtr = listIndexHead; + while (tempIndexPtr != NULL) + { + if (tempIndexPtr == listIndexHead) + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 1, tempIndexPtr->weaveSeq); + } + else + { + status = restoreIndexBlock(tempIndexPtr->blockNo, 0, tempIndexPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + freeBlockList(listIndexHead); + freeBlockList(listHead); + return status; + } + listIndexHead = tempIndexPtr; + tempIndexPtr = tempIndexPtr->next; + WMR_FREE(listIndexHead, sizeof(BlockListType)); + } + } + if (yaFTL.wrState.index.block == 0xffffffff) + { + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.index.block = i; /* current physical block being used for updates */ + yaFTL.wrState.index.nextPage = 0; /* offset in current block of next free page */ + WMR_MEMSET(yaFTL.wrState.index.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.blockArray[i].status = BLOCK_I_CURRENT; + debug(INIT, "current index block would be %d", i); + break; + } + } + } + + // t22=mach_absolute_time(); + if (listHead == NULL) /* empty partition */ + { + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].status == BLOCK_FREE) + { + yaFTL.wrState.data.block = i; + yaFTL.blockArray[yaFTL.wrState.data.block].status = BLOCK_CURRENT; + break; + } + } + yaFTL.wrState.data.nextPage = 0; + WMR_MEMSET(yaFTL.wrState.data.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); +#ifndef AND_READONLY + if ( !readOnly ) + { + if (ctxNo == 0) + { + i = 0; + for (j = 0; (Int32)j < FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.cxtTable[i] = ctxT[i]; + } + } + } +#endif + + // Set up block counters + SetupFreeAndAllocd(); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = 0; + stFTLStatistics.ddwValidIndexPages = 0; +#endif + + yaFTL.seaState.distCheckable = 1; + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + CheckBlockDist(); + return FTL_SUCCESS; + } + + tempHdr = listHead; + + pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + if (NULL == pBuff) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + if (!_allocateRestoreIndexBuffers(&brPtr, &indexTable, &tempIndexBufferSize)) + { + freeBlockList(listHead); + return FTL_CRITICAL_ERROR; + } + + WMR_MEMSET(brPtr, 0xff, (FTL_AREA_SIZE * sizeof(BlockRangeType))); + + for (j = 0; j < yaFTL.logicalPartitionSize; j += tempIndexBufferSize) + { + WMR_MEMSET(indexTable, 0xff, tempIndexBufferSize * sizeof(UInt32)); + tempPtr = listHead = tempHdr; + while (tempPtr != NULL) + { + if (tempPtr == listHead) + { + status = restoreBlock(tempPtr->blockNo, indexTable, 1, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + else + { + status = restoreBlock(tempPtr->blockNo, indexTable, 0, j, tempIndexBufferSize, brPtr, tempPtr->weaveSeq); + } + if (status != FTL_SUCCESS) + { + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + freeBlockList(tempHdr); + BUF_Release(pBuff); + return status; + } + listHead = tempPtr; + tempPtr = tempPtr->next; + if ((j + tempIndexBufferSize) >= yaFTL.logicalPartitionSize) + { + tempHdr = tempPtr; + WMR_FREE(listHead, sizeof(BlockListType)); + } + } + + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + + for (i = 0, pageBuffer = indexTable; (i < (tempIndexBufferSize * 4) / BYTES_PER_PAGE) && ((i * yaFTL.indexPageRatio + j) < yaFTL.logicalPartitionSize); i++, pageBuffer += (BYTES_PER_PAGE / 4)) + { + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + + if (WMR_MEMCMP(pageBuffer, pBuff->pData, BYTES_PER_PAGE) == 0) + { + if ((yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) && (yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo > 0)) + { + yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + } + + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex != 0xffff) + { + yaFTL.indexCache[yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex].status = FREE_CACHE_PAGE; + yaFTL.indexCache[yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex].counter = 0; + } + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = 0xffff; + continue; /* index page does not contain any valid pages */ + } + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) + { + status = _readPage(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage, (UInt8 *)pBuff->pData, NULL, FALSE32, TRUE32, FALSE32); + if (status != FTL_SUCCESS) + { + debug(ERROR, "index page is unreadable at 0x%x", yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage); + WMR_MEMSET(pBuff->pData, 0xff, BYTES_PER_PAGE); + } + } + + if (WMR_MEMCMP(pageBuffer, pBuff->pData, BYTES_PER_PAGE) != 0) + { + UInt16 cE; + + /* Need to copy valid page in index cache */ + if (yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage != 0xffffffff) + { + yaFTL.blockArray[(yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; + } + + cE = findFreeCacheEntry(); + if (cE == 0xffff) + { + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + BUF_Release(pBuff); +#ifdef AND_READONLY + if ( !readOnly ) + { + debug(ERROR, "ran out of available cache pages on toc entry %d", (i + ((j * 4) / BYTES_PER_PAGE))); + debug(ERROR, "can still be enough to mount OS partition"); + freeBlockList(tempHdr); + return FTL_SUCCESS; + } + else +#endif + { + debug(ERROR,"ran out of available cache pages on toc entry %d", (i + ((j * 4) / BYTES_PER_PAGE))); + freeBlockList(tempHdr); + return FTL_CRITICAL_ERROR; + } + } + WMR_MEMCPY(yaFTL.indexCache[cE].indexPage, pageBuffer, BYTES_PER_PAGE); + yaFTL.indexCache[cE].status = IC_DIRTY_PAGE; + yaFTL.indexCache[cE].tocEntry = (UInt16)(i + ((j * 4) / BYTES_PER_PAGE)); + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].cacheIndex = cE; + yaFTL.tocArray[i + ((j * 4) / BYTES_PER_PAGE)].indexPage = 0xffffffff; + } + } + } + // t3=mach_absolute_time(); + +#ifndef AND_READONLY + if ( !readOnly ) + { + /* Vadim - check presence of CXT blocks . If there are none allocate them */ + + if (ctxNo == 0) + { + i = 0; + for (j = 0; j < (UInt32)FTL_AREA_SIZE; j++) + { + if (yaFTL.blockArray[j].status == BLOCK_FREE) + { + yaFTL.blockArray[j].status = BLOCK_CTX_CNTR; + ctxT[i] = (UInt16)j; + i++; + if (i >= FTL_CXT_SECTION_SIZE) + { + break; + } + } + } + VFL_ChangeFTLCxtVbn(ctxT); + } + } +#endif + + BUF_Release(pBuff); + WMR_BOOT_FREE(indexTable); + WMR_FREE(brPtr, FTL_AREA_SIZE * sizeof(BlockRangeType)); + + // Set up block counters + SetupFreeAndAllocd(); + + // t4=mach_absolute_time(); + // debug(MISC, "time spent in restore is %llu %llu %llu %llu %llu ",t2-t1,t22-t2,t3-t22,t4-t3,t4-t1); + debug(INIT, "current i block %d current i page %d", yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage); + + debug(INIT, "restoreMount : logicalPartitionSize %d TOCtableEntriesNo %d \nwrState.data.block %d wrState.data.nextPage %d \n BYTES_PER_PAGE %d \n wrState.index.block %d wrState.index.nextPage %d wrState.weaveSeq %d" + , yaFTL.logicalPartitionSize, yaFTL.TOCtableEntriesNo, yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, BYTES_PER_PAGE, yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, yaFTL.wrState.weaveSeq); + debug(INIT, "restoreMount seaState.data.allocdBlocks %d dataSize %d FTL_SIZE %d pagesinblock %d", yaFTL.seaState.data.allocdBlocks, yaFTL.dataSize, FTL_AREA_SIZE, PAGES_PER_SUBLK); + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLRestoreCnt++; + stFTLStatistics.ddwFreeBlks = yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks; + stFTLStatistics.ddwValidDataPages = yaFTL.seaState.data.validPages; + stFTLStatistics.ddwValidIndexPages = yaFTL.seaState.index.validPages; +#endif + + yaFTL.seaState.distCheckable = 1; + CheckBlockDist(); + + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } +#ifndef AND_READONLY + if ( !readOnly ) + { + for (i = 0; ((Int32)i < FTL_AREA_SIZE); i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) && (yaFTL.blockArray[i].validPagesDNo == 0 )) + { + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + continue; + } + if ((yaFTL.blockArray[i].status == BLOCK_I_ALLOCATED) && (yaFTL.blockArray[i].validPagesINo == 0 )) + { + YAFTL_GC_Index(i, FALSE32); + } + } + // Move the current blocks out : + i = yaFTL.wrState.index.block; + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + i = yaFTL.wrState.data.block; + yaFTL.blockArray[i].validPagesINo = 0; + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + + while ((yaFTL.indexSize - FREE_I_BLOCK_TRS) < yaFTL.seaState.index.allocdBlocks) + { + debug(MISC, "free index %d %d", yaFTL.indexSize, yaFTL.seaState.index.allocdBlocks); + YAFTL_GC_Index(0xffffffff, FALSE32); + } + } +#endif + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + yaFTL.blockArray[i].validPagesINo = 0; + } +#ifndef AND_READONLY + if ( !readOnly ) + { + if ((yaFTL.blockArray[i].status != BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_MOVED)) + { + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + YAFTL_GC_Data(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + else + { + YAFTL_GC_Index(i, FALSE32); + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != 0)) + { + status = VFL_Erase((UInt16)i, TRUE32); + if (status == FTL_SUCCESS) + { + yaFTL.blockArray[i].erasableCount++; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.erasedBlockCount++; + } + } + } + } + } +#endif + } + debug(INIT, "restoreMount : seaState.index.validPages = %d seaState.data.validPages = %d", yaFTL.seaState.index.validPages, yaFTL.seaState.data.validPages); + + CheckBlockDist(); + + return FTL_SUCCESS; +} + +static BOOL32 +_allocateRestoreIndexBuffers(BlockRangeType **blockRangeBuffer, UInt32 **indexTable, UInt32 *indexTableSize) +{ + const UInt32 kBlockRangeSize = FTL_AREA_SIZE * sizeof(BlockRangeType); + void *blockRange = NULL; + void *table = NULL; + UInt32 bootBufferSize; + + if ((NULL == blockRangeBuffer) || (NULL == indexTable)) + { + return FALSE32; + } + + blockRange = WMR_MALLOC(kBlockRangeSize); + + bootBufferSize = MIN_RESTORE_BUFFER; + table = (UInt8 *)WMR_BOOT_MALLOC(&bootBufferSize); + + if ((NULL == table) || (NULL == blockRange)) + { + if (NULL != blockRange) + { + WMR_FREE(blockRange, kBlockRangeSize); + } + debug(ERROR, "could not allocate enough memory for the restore"); + return FALSE32; + } + + if(bootBufferSize > (MAX_RESTORE_BUFFER * sizeof(UInt32))) + { + bootBufferSize = (MAX_RESTORE_BUFFER) * sizeof(UInt32); + } + else + { + bootBufferSize = ROUNDDOWNTO(bootBufferSize, MIN_RESTORE_BUFFER); + } + + *indexTable = (UInt32*) table; + *blockRangeBuffer = (BlockRangeType*) blockRange; + *indexTableSize = bootBufferSize / sizeof(UInt32); + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Open */ +/* DESCRIPTION */ +/* This function mounts the device using control info or restore */ +/* if control info is dirty */ +/* RETURN VALUES */ +/* FTL_SUCCESS */ +/* YAFTL_Init is completed */ +/* FTL_CRITICAL_ERROR */ +/* YAFTL_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +YAFTL_Open(UInt32 *pTotalPages, UInt32 * pdwPageSize, BOOL32 nandFullRestore, BOOL32 justFormatted, UInt32 dwMinorVer, UInt32 dwOptions) +{ + UInt16 i; +#ifndef AND_READONLY + UInt32 tempIndexCacheSize = yaFTL.indexCacheSize; +#endif + Int32 status = FTL_CRITICAL_ERROR; + UInt16 cxtT[FTL_CXT_SECTION_SIZE]; + BOOL32 formatSupported = TRUE32; + + const UInt32 readOnly = ( WMR_INIT_OPEN_READONLY == (WMR_INIT_OPEN_READONLY & dwOptions) ? 1 : 0 ); + + /* read out VFL_meta data . If it is not present execute full format . If it is present go and fetch "quick mount" info from CX area if it's valid .If not execute restore + For now we need to start from fresh media which means there is no quick mount info and all blocks are free . */ +#ifndef AND_READONLY + if(justFormatted == TRUE32) + yaFTL.formatWasCalled = justFormatted; + WMR_MEMSET(yaFTL.eraseNowList, 0xff, sizeof(UInt16) * ERASE_NOW_LIST_SIZE); +#endif + WMR_MEMSET(yaFTL.tocArray, 0xff, sizeof(TOCEntry) * yaFTL.TOCtableEntriesNo); + WMR_MEMSET(yaFTL.blockArray, 0xff, sizeof(BlockEntry) * FTL_AREA_SIZE); + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.blockArray[i].validPagesDNo = 0; + yaFTL.blockArray[i].validPagesINo = 0; + yaFTL.blockArray[i].erasableCount = 0; + yaFTL.blockArray[i].pagesRead = 0; + yaFTL.blockArray[i].pagesReadSubCounter = 0; + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.blockArray[i].status = 0; + } + + yaFTL.wrState.lastBlock = 0xffffffff; + /* Get CXT blocks from the VFL */ + WMR_MEMCPY(cxtT, VFL_GetFTLCxtVbn(), FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + + /* + Vadim : here we make a decision about quick mount . + If quick mount units do not exist - go to restore + If quick mount units exist - go with quick mount if there is a valid copy . + Otherwise, go with restore . + */ + if (cxtT[0] != 0xffff) + { + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + yaFTL.cxtTable[i] = cxtT[i]; + yaFTL.blockArray[yaFTL.cxtTable[i]].status = BLOCK_CTX_CNTR; + debug(OPEN, "YAFTL_Open cxt [ %d ] = 0x%x %d 0x%x %d", i, cxtT[i], cxtT[i], FTL_AREA_SIZE, FTL_AREA_SIZE); + } + + status = (UInt16)quickRestore(cxtT, &formatSupported); + if (formatSupported != TRUE32) + { + debug(ERROR, "YAFTL_OPEN unsupported low-level format version cannot continue ."); + return FTL_CRITICAL_ERROR; + } +#ifdef AND_COLLECT_STATISTICS + if(stFTLStatistics.ddwRefreshCnt == 0xffffffff) + { + debug(ERROR, "YAFTL_OPEN clearing refresh stats"); + stFTLStatistics.ddwRefreshCnt = 0; + } +#endif +#ifndef AND_READONLY + if ((dwOptions & WMR_INIT_SET_INDEX_CACHE_SIZE) == WMR_INIT_SET_INDEX_CACHE_SIZE) + { + yaFTL.indexCacheSize = (dwOptions >> 20); + tempIndexCacheSize = yaFTL.indexCacheSize; + debug(INIT, "YAFTL_OPEN index cache will be set to 0x%x -- 0x%x", yaFTL.indexCacheSize, tempIndexCacheSize); + } + if ((yaFTL.cxtAllocation != 0) && (yaFTL.cxtAllocation != 0xffffffff)) + for(i = 0; i < FTL_CXT_SECTION_SIZE; i++) + if( yaFTL.blockArray[yaFTL.cxtTable[i]].erasableCount == 0) + yaFTL.blockArray[yaFTL.cxtTable[i]].erasableCount = (UInt32 + )(yaFTL.cxtAllocation / (PAGES_PER_SUBLK / yaFTL.cxtSize)); +#endif + if ((status != FTL_SUCCESS) || (nandFullRestore == TRUE32)) + { + debug(INIT, "YAFTL_OPEN forcing full mount 0x%x %d ", status, nandFullRestore); + status = FTL_CRITICAL_ERROR; + } + /* Allocate index cache based on a size saved in cxt area */ + if ((status != FTL_SUCCESS) && (WMR_MIN( NAND_MOUNT_INDEX_SIZE, ((yaFTL.logicalPartitionSize / yaFTL.indexPageRatio) + 1)) > yaFTL.indexCacheSize)) + { +#ifndef AND_READONLY + tempIndexCacheSize = yaFTL.indexCacheSize; +#endif + yaFTL.indexCacheSize = WMR_MIN( NAND_MOUNT_INDEX_SIZE, ((yaFTL.logicalPartitionSize / yaFTL.indexPageRatio) + 1));//NAND_MOUNT_INDEX_SIZE; + } + yaFTL.indexCache = (CacheIndexEntry *)WMR_MALLOC(yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + if (yaFTL.indexCache == NULL) + { + return FTL_CRITICAL_ERROR; + } + + // Allocate index cache buffers + WMR_BufZone_Init(&yaFTL.BufZone_IndexCache); + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + // Pre-reserve + yaFTL.indexCache[i].indexPage = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone_IndexCache, BYTES_PER_PAGE); + } + + // Finish allocations + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BufZone_IndexCache)) + { + return FTL_CRITICAL_ERROR; + } + + // Rebase and initialize + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + WMR_BufZone_Rebase(&yaFTL.BufZone_IndexCache, (void**)&yaFTL.indexCache[i].indexPage); + yaFTL.indexCache[i].status = FREE_CACHE_PAGE; + yaFTL.indexCache[i].tocEntry = 0xffff; + yaFTL.indexCache[i].counter = 0; + WMR_MEMSET(yaFTL.indexCache[i].indexPage, 0xff, BYTES_PER_PAGE); + } + + // Finish rebase + WMR_BufZone_FinishedRebases(&yaFTL.BufZone_IndexCache); + + if (status == FTL_SUCCESS) + { + debug(OPEN, "YAFTL_OPEN quick mount is present and valid . open is done "); + *pTotalPages = ((yaFTL.logicalPartitionSize - 1) / 100) * yaFTL.exportedRatio /*EXPO_RATIO*/; + *pdwPageSize = BYTES_PER_PAGE; + yaFTL.maxEraseCount = 0; yaFTL.minEraseCount = 0xffffffff; yaFTL.erasedBlockCount = 0; + for (i = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + if ((yaFTL.blockArray[i].status != BLOCK_CTX_CNTR) && (yaFTL.blockArray[i].status != BLOCK_CTX_CURRENT)) + { + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + if (yaFTL.blockArray[i].erasableCount < yaFTL.minEraseCount) + { + yaFTL.minEraseCount = yaFTL.blockArray[i].erasableCount; + } + } + } + + // Set up block counters + SetupFreeAndAllocd(); + BTOC_BootFixup(); + + PopulateTreesOnBoot_Fast(); + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + return status; + } + } + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.blockArray[i].validPagesDNo = 0; + yaFTL.blockArray[i].validPagesINo = 0; + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + else + yaFTL.blockArray[i].status = 0; + } + debug(ERROR, "CXT is not valid . Performing full NAND R/O restore ... "); +#ifdef AND_USE_NOTIFY + { + LowFuncTbl *pLowFuncTbl; + + pLowFuncTbl = FIL_GetFuncTbl(); + pLowFuncTbl->Notify(AND_NOTIFY_RECOVER); + } +#endif /* AND_USE_NOTIFY */ + + status = (UInt16)restoreMount(cxtT, readOnly); + if (status != FTL_SUCCESS) + { +#ifndef AND_READONLY + debug(ERROR, "Read only full restore failed. Performing full NAND R/W restore ... "); + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + yaFTL.indexCache[i].status = FREE_CACHE_PAGE; + yaFTL.indexCache[i].tocEntry = 0xffff; + yaFTL.indexCache[i].counter = 0; + WMR_MEMSET(yaFTL.indexCache[i].indexPage, 0xff, BYTES_PER_PAGE); + } + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.blockArray[i].validPagesDNo = 0; + yaFTL.blockArray[i].validPagesINo = 0; + if ((yaFTL.blockArray[i].status == BLOCK_CTX_CNTR) || (yaFTL.blockArray[i].status == BLOCK_CTX_CURRENT)) + { + continue; + } + else + yaFTL.blockArray[i].status = 0; + } + + status = restoreMountEraseIndex(cxtT); + if (status != FTL_SUCCESS) +#endif + return status; + } + + BTOC_BootFixup(); + + // force next cxt update out of the current cxt block ( unclean shutdown ) + if(yaFTL.currentCxtVpn != 0xffffffff) + yaFTL.currentCxtVpn = ((yaFTL.currentCxtVpn / PAGES_PER_SUBLK) * PAGES_PER_SUBLK) + (PAGES_PER_SUBLK - 1); + + // Detect min/max erase counts + for (i = 0; i < FTL_AREA_SIZE; i++) + { + yaFTL.maxEraseCount = 0; yaFTL.minEraseCount = 0xffffffff; + if ((yaFTL.blockArray[i].status != BLOCK_CTX_CNTR) && (yaFTL.blockArray[i].status != BLOCK_CTX_CURRENT)) + { + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + if (yaFTL.blockArray[i].erasableCount < yaFTL.minEraseCount) + { + yaFTL.minEraseCount = yaFTL.blockArray[i].erasableCount; + } + } + } + + *pTotalPages = ((yaFTL.logicalPartitionSize - 1) / 100) * yaFTL.exportedRatio /*EXPO_RATIO*/; + *pdwPageSize = BYTES_PER_PAGE; +#ifndef AND_READONLY + if ( !readOnly ) + { + if (yaFTL.indexCacheSize != tempIndexCacheSize) + { + UInt32 tmpVar = (UInt32)tempIndexCacheSize; + YAFTL_GetStruct(AND_FUNCTION_INDEX_CACHE_UPDATE, NULL, (UInt32 *)&tmpVar); + } + } +#endif + + PopulateTreesOnBoot_Fast(); + for (i = 0, yaFTL.erasedBlockCount = 0; i < FTL_AREA_SIZE; i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == 0)) + yaFTL.erasedBlockCount++; + } + return FTL_SUCCESS; +} + + +#if ENABLE_L2V_TREE +static void PopulateFromIndexCache(UInt32 indexPageNo, UInt32 *indexPageData) +{ + UInt32 lpn; + UInt32 i, lastLpn, lastPhy, lastLen; + UInt32 *phyPtr; + + lpn = indexPageNo * yaFTL.indexPageRatio; + lastLpn = 0xffffffff; + lastPhy = 0xffffffff; + lastLen = 0; + phyPtr = indexPageData; + + for (i = 0; (i < yaFTL.indexPageRatio) && !L2V_LowMem; i++, phyPtr++) + { + if (0 == lastLen) + { + lastLpn = lpn + i; + lastPhy = *phyPtr; + lastLen = 1; + continue; + } + + if (((0xffffffff != lastPhy) && ((lastPhy + lastLen) == *phyPtr)) || ((0xffffffff == lastPhy) && (lastPhy == *phyPtr))) + { + lastLen++; + } + else + { + if (0xffffffff == lastPhy) { + L2V_Update(lastLpn, lastLen, L2V_VPN_DEALLOC); + } else { + L2V_Update(lastLpn, lastLen, lastPhy); + } + + lastLpn = lpn + i; + lastPhy = *phyPtr; + lastLen = 1; + } + } + + if (lastLen && !L2V_LowMem) + { + if (0xffffffff == lastPhy) { + L2V_Update(lastLpn, lastLen, L2V_VPN_DEALLOC); + } else { + L2V_Update(lastLpn, lastLen, lastPhy); + } + } +} +#endif // ENABLE_L2V_TREE + + +#if ENABLE_L2V_TREE +#ifdef AND_READONLY +#error Tree not supported in read-only AND driver. This would require GC to allocate index buffer in AND_READONLY mode, since we share that to populate trees. +#endif +static void PopulateTreesOnBoot_Fast() +{ + UInt32 zoneSize, indexPageNo, successCount, failCount, i; +#if TIME_TREE + UInt64 startTime; +#endif + BOOL32 BoolStatus; + Int32 status; + + indexPageNo = 0; + successCount = 0; + failCount = 0; + +#if TIME_TREE + (void) clock_timebase_info(&sTimebaseInfo); + startTime = ANDPerf_getTime(); +#endif + + while ((indexPageNo < yaFTL.TOCtableEntriesNo) && !L2V_LowMem) { + // Fill out VPNs + zoneSize = 0; + while (((indexPageNo + zoneSize) < yaFTL.TOCtableEntriesNo) && (zoneSize < yaFTL.gc.zoneSize)) + { + if (0xffffffff != yaFTL.tocArray[indexPageNo+zoneSize].indexPage) { + yaFTL.gc.index.vpns[zoneSize] = yaFTL.tocArray[indexPageNo+zoneSize].indexPage; + zoneSize++; + } else { + // Creates gaps. Ok so long as we're careful about inferring starts/ends, and use meta read from page, not calculated + indexPageNo++; + } + } + + // Read index pages + BoolStatus = _readMultiPages(yaFTL.gc.index.vpns, zoneSize, &yaFTL.gc.index.zone[0], (UInt8*)&yaFTL.gc.index.meta[0], 0, 0); + if (BoolStatus != TRUE32) + { + for (i = 0; i < zoneSize; i++) + { + status = _readPage(yaFTL.gc.index.vpns[i], &yaFTL.gc.index.zone[BYTES_PER_PAGE * i], &yaFTL.gc.index.meta[i], 0, TRUE32, 0); + if (status != FTL_SUCCESS) + { + META_SET_LBA(&yaFTL.gc.index.meta[i], 0xffffffff); + } + } + } + + // Now scan the results--if it's the current one, update using it + for (i = 0; (i < zoneSize) && !L2V_LowMem; i++) + { + if ((META_IS_IDX(&yaFTL.gc.index.meta[i])) && (yaFTL.TOCtableEntriesNo > META_GET_IPN(&yaFTL.gc.index.meta[i]))) + { + PopulateFromIndexCache(META_GET_IPN(&yaFTL.gc.index.meta[i]), (UInt32*)&yaFTL.gc.index.zone[BYTES_PER_PAGE * i]); + successCount++; + } + else + { + failCount++; + } + } + + indexPageNo += zoneSize; + } + +#if TIME_TREE + WMR_PRINT("NAND cache population time: %dus\n", ANDPerf_toUs(ANDPerf_getTime() - startTime)); +#endif +} +#else // if not ENABLE_L2V_TREE: +static void PopulateTreesOnBoot_Fast() +{ + // Do nothing +} +#endif // !ENABLE_L2V_TREE + + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* allocateBlock */ +/* DESCRIPTION */ +/* Allocates free block for either index or data update operartions */ +/* */ +/*****************************************************************************/ +UInt32 allocateBlock(UInt32 blockNo, UInt8 flag, UInt8 type) +{ + UInt32 i; + UInt32 minCount = 0xffffffff, minCountIndex = 0xffffffff; + UInt16 blockToEraseForReal = 0; + + // Wear leveling periodicity counter + yaFTL.wearLevel.blocksSince++; + + if(yaFTL.erasedBlockCount < (FREE_BLK_TRH + FREE_I_BLOCK_TRS)) + { + blockToEraseForReal = (FREE_BLK_TRH + FREE_I_BLOCK_TRS) - yaFTL.erasedBlockCount; + } + else + blockToEraseForReal = 0; + + // Set up minWeaveSeq, clear out data gc adjust + if (1 == type) + { + yaFTL.wrState.data.minWeaveSeq = yaFTL.wrState.weaveSeq; + yaFTL.gc.data.gcDataAdjust = 0; + } + else + { + yaFTL.wrState.index.minWeaveSeq = yaFTL.wrState.weaveSeq; + } + + // look for a block with smallest erasable unit count + for (i = 0; (Int32)i < FTL_AREA_SIZE; i++) + { + if((type == 1) && (yaFTL.blockArray[i].status == BLOCK_FREE) && ((yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED_ALIGNED_DATA) || (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED)) ) + { + if((isBlockInEraseNowList(i)) || (blockToEraseForReal > 0)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + if(blockToEraseForReal > 0) + { + blockToEraseForReal--; + } + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.blockArray[i].erasableCount++; + yaFTL.periodicCxt.erases++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + removeBlockFromEraseNowList((UInt16)i); + } + else + { + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + } + } + else + { + if((type != 1) && (yaFTL.blockArray[i].status == BLOCK_FREE) && ((yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED_ALIGNED_INDEX) || (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED))) + { + if((isBlockInEraseNowList(i)) || (blockToEraseForReal > 0)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + if(blockToEraseForReal > 0) + { + blockToEraseForReal--; + } + removeBlockFromEraseNowList((UInt16)i); + yaFTL.blockArray[i].eraseBeforeUse = 0; + yaFTL.blockArray[i].erasableCount++; + yaFTL.periodicCxt.erases++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + } + else + { + yaFTL.blockArray[i].eraseBeforeUse = BLOCK_TO_BE_ERASED; + } + } + } + + if ((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse != BLOCK_TO_BE_ERASED_ALIGNED_DATA) && (yaFTL.blockArray[i].eraseBeforeUse != BLOCK_TO_BE_ERASED_ALIGNED_INDEX) && (minCount > yaFTL.blockArray[i].erasableCount)) + { + minCount = yaFTL.blockArray[i].erasableCount; + minCountIndex = i; + WMR_ASSERT(0 == yaFTL.blockArray[i].validPagesINo); + WMR_ASSERT(0 == yaFTL.blockArray[i].validPagesDNo); + } + } + if (minCountIndex == 0xffffffff) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("no free yaFTL blocks: type %d\n", type); + return minCountIndex; + } + if (type == 1) /* dataBlock */ + { + BTOC_Dealloc(yaFTL.wrState.data.TOC); +#ifndef AND_READONLY + if (yaFTL.blockArray[minCountIndex].eraseBeforeUse == BLOCK_TO_BE_ERASED) + { + UInt8 status; + WMR_ASSERT(BLOCK_FREE == yaFTL.blockArray[minCountIndex].status); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + status = VFL_Erase((UInt16)minCountIndex, TRUE32); + if (status != FTL_SUCCESS) + { + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + removeBlockFromEraseNowList((UInt16)minCountIndex); + yaFTL.blockArray[minCountIndex].erasableCount++; + yaFTL.periodicCxt.erases++; + yaFTL.blockArray[minCountIndex].eraseBeforeUse = 0; + } +#endif + yaFTL.blockArray[yaFTL.wrState.data.block].status = BLOCK_ALLOCATED; + yaFTL.wrState.data.block = minCountIndex; + yaFTL.blockArray[minCountIndex].status = BLOCK_CURRENT; + yaFTL.wrState.data.nextPage = 0; + yaFTL.wrState.data.TOC = BTOC_Alloc(yaFTL.wrState.data.block, 1); + WMR_MEMSET(yaFTL.wrState.data.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.seaState.data.freeBlocks--; + yaFTL.seaState.freeBlocks--; + if(yaFTL.erasedBlockCount) + yaFTL.erasedBlockCount--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks--; +#endif + yaFTL.seaState.data.allocdBlocks++; + //wrState.data.weaveSeq++; + return yaFTL.wrState.data.block; + } + else + { + BTOC_Dealloc(yaFTL.wrState.index.TOC); +#ifndef AND_READONLY + if (yaFTL.blockArray[minCountIndex].eraseBeforeUse == BLOCK_TO_BE_ERASED) + { + UInt8 status; + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + status = VFL_Erase((UInt16)minCountIndex, TRUE32); + if (status != FTL_SUCCESS) + { + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + removeBlockFromEraseNowList((UInt16)minCountIndex); + yaFTL.blockArray[minCountIndex].erasableCount++; + yaFTL.periodicCxt.erases++; + yaFTL.blockArray[minCountIndex].eraseBeforeUse = 0; + } +#endif + yaFTL.blockArray[yaFTL.wrState.index.block].status = BLOCK_I_ALLOCATED; + yaFTL.wrState.index.block = minCountIndex; + yaFTL.blockArray[minCountIndex].status = BLOCK_I_CURRENT; + yaFTL.wrState.index.nextPage = 0; + yaFTL.wrState.index.TOC = BTOC_Alloc(yaFTL.wrState.index.block, 0); + WMR_MEMSET(yaFTL.wrState.index.TOC, 0xff, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.seaState.index.freeBlocks--; + yaFTL.seaState.freeBlocks--; + if(yaFTL.erasedBlockCount) + yaFTL.erasedBlockCount--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks--; +#endif + yaFTL.seaState.index.allocdBlocks++; + + return yaFTL.wrState.index.block; + } +} +#endif //ifndef AND_READONLY + +/*****************************************************************************/ +/* */ +/* NAME */ +/* findFreeCacheEntry */ +/* DESCRIPTION */ +/* Finds free entry in index cache table */ +/* */ +/*****************************************************************************/ +UInt16 findFreeCacheEntry(void) +{ + UInt16 i; + + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + if (yaFTL.indexCache[i].status == FREE_CACHE_PAGE) + { + return i; + } + } + return 0xffff; +} + +#ifndef AND_READONLY +UInt16 clearEntryInCache(UInt8 flag, UInt16 candidate, UInt8 keepInCache) +{ + UInt16 i; + UInt16 bestCandidateCounterBusy = 0xffff, bestCandidateBusy = 0xffff, bestCandidateCounterDirty = 0xffff, bestCandidateDirty = 0xffff; + UInt8 status; + + if (candidate == 0xffff) + { + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + if (yaFTL.indexCache[i].status == FREE_CACHE_PAGE) + { + return i; + } + if ((yaFTL.indexCache[i].status == IC_BUSY_PAGE) && (yaFTL.indexCache[i].counter <= bestCandidateCounterBusy)) + { + bestCandidateBusy = i; + bestCandidateCounterBusy = yaFTL.indexCache[i].counter; + } + if ((yaFTL.indexCache[i].status == IC_DIRTY_PAGE) && (yaFTL.indexCache[i].counter <= bestCandidateCounterDirty)) + { + bestCandidateDirty = i; + bestCandidateCounterDirty = yaFTL.indexCache[i].counter; + } + } + } + else + { + // Note: bestCandidateCounterBusy and bestCandidateCounterDirty are not updated by this path, since they are not needed. + if (yaFTL.indexCache[candidate].status == FREE_CACHE_PAGE) + { + return candidate; + } + if (yaFTL.indexCache[candidate].status == IC_BUSY_PAGE) + { + bestCandidateBusy = candidate; + } + if (yaFTL.indexCache[candidate].status == IC_DIRTY_PAGE) + { + bestCandidateDirty = candidate; + } + } + + if (bestCandidateBusy != 0xffff) + { + if(keepInCache == 0) + { + yaFTL.tocArray[yaFTL.indexCache[bestCandidateBusy].tocEntry].cacheIndex = 0xffff; + WMR_MEMSET(yaFTL.indexCache[bestCandidateBusy].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.indexCache[bestCandidateBusy].status = FREE_CACHE_PAGE; + yaFTL.indexCache[bestCandidateBusy].counter = 0; + yaFTL.freeCachePages++; + } + return bestCandidateBusy; + } + + if (bestCandidateDirty != 0xffff) + { + PageMeta_t *mdPtr = yaFTL.meta_clearEntryInCache; + UInt32 tocEntry = yaFTL.indexCache[bestCandidateDirty].tocEntry; + + SetupMeta_Index(mdPtr, tocEntry); + + if (yaFTL.tocArray[tocEntry].indexPage != 0xffffffff) + { + WMR_ASSERT(0 != yaFTL.blockArray[yaFTL.tocArray[tocEntry].indexPage / PAGES_PER_SUBLK].validPagesINo); + yaFTL.blockArray[(yaFTL.tocArray[tocEntry].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + } + status = (UInt8)writeIndexPage((UInt8 *)yaFTL.indexCache[bestCandidateDirty].indexPage, mdPtr, flag); + if (FTL_SUCCESS != status) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't write index page %d in clearEntryInCache", yaFTL.indexCache[bestCandidateDirty].indexPage); + } + + // collectBlockStats(); + if(keepInCache == 0) + { + yaFTL.tocArray[tocEntry].cacheIndex = 0xffff; + yaFTL.indexCache[bestCandidateDirty].status = FREE_CACHE_PAGE; + yaFTL.indexCache[bestCandidateDirty].counter = 0; + WMR_MEMSET(yaFTL.indexCache[bestCandidateDirty].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.freeCachePages++; + } + else + { + yaFTL.indexCache[bestCandidateDirty].status = IC_BUSY_PAGE; + } + return bestCandidateDirty; + } + + return 0xffff; +} +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* writeCurrentBlockTOC */ +/* DESCRIPTION */ +/* writes block TOC info once block is full */ +/* */ +/*****************************************************************************/ +ANDStatus writeCurrentBlockTOC(UInt8 type) +{ + UInt8 i; + Int32 status; + UInt32 Vpn; + PageMeta_t *md = yaFTL.meta_writeBTOC; + + if (type == 1) + { + SetupMeta_Data_BTOC(md); + + Vpn = yaFTL.wrState.data.nextPage + (yaFTL.wrState.data.block * PAGES_PER_SUBLK); + if (yaFTL.wrState.data.nextPage == (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + for (i = 0; i < yaFTL.controlPageNo; i++, Vpn++) + { + status = _writePage(Vpn, ((UInt8*)yaFTL.wrState.data.TOC) + (i * BYTES_PER_PAGE), md, FALSE32); + if (status != FTL_SUCCESS) + { + return FTL_CRITICAL_ERROR; + } + yaFTL.wrState.data.nextPage++; + } + } + } + else + { + SetupMeta_Index_BTOC(md); + + Vpn = yaFTL.wrState.index.nextPage + (yaFTL.wrState.index.block * PAGES_PER_SUBLK); + if (yaFTL.wrState.index.nextPage == (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + for (i = 0; i < yaFTL.controlPageNo; i++, Vpn++) + { + status = _writePage(Vpn, ((UInt8*)yaFTL.wrState.index.TOC) + (i * BYTES_PER_PAGE), md, FALSE32); + if (status != FTL_SUCCESS) + { + return FTL_CRITICAL_ERROR; + } + yaFTL.wrState.index.nextPage++; + } + } + } + return FTL_SUCCESS; +} + +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* flushIndexCache */ +/* DESCRIPTION */ +/* commits index cached pages to flash */ +/* */ +/*****************************************************************************/ +static ANDStatus flushIndexCache(UInt8 keepInCache) +{ + UInt16 i; + + while ((yaFTL.indexSize - FREE_I_BLOCK_TRS) < yaFTL.seaState.index.allocdBlocks) + { + YAFTL_GC_Index(0xffffffff, TRUE32); + } + + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + clearEntryInCache(0, i, keepInCache); + } + + return FTL_SUCCESS; +} + +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* writeIndexPage */ +/* DESCRIPTION */ +/* writes index page to flash */ +/* */ +/*****************************************************************************/ +static ANDStatus writeIndexPage(UInt8 *pageBuffer, PageMeta_t *mdPtr, UInt8 flag) +{ + UInt32 Vpn; + ANDStatus status; + + ONEMORETIME: + if (yaFTL.wrState.index.nextPage < (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + /* we have space in current index block */ + Vpn = yaFTL.wrState.index.nextPage + (yaFTL.wrState.index.block * PAGES_PER_SUBLK); /* should use << if possible */ + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[yaFTL.wrState.index.nextPage], mdPtr); + META_SET_WEAVESEQ(mdPtr); + status = _writePage(Vpn, pageBuffer, mdPtr, FALSE32); + if (status != FTL_SUCCESS) + { + debug(WRITE, "cannot write index page "); + YAFTL_GC_Index_Enq(yaFTL.wrState.index.block); + allocateBlock(yaFTL.wrState.index.block, 0, 0); + + goto ONEMORETIME; + } + yaFTL.wrState.index.nextPage++; + yaFTL.blockArray[yaFTL.wrState.index.block].validPagesINo++; + yaFTL.seaState.index.validPages++; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages++; +#endif + } + else + { + /* current block is full . need to allocate new block */ + writeCurrentBlockTOC(0); + allocateBlock(yaFTL.wrState.index.block, flag, 0); + + Vpn = yaFTL.wrState.index.nextPage + (yaFTL.wrState.index.block * PAGES_PER_SUBLK); // should use << if possible + WMR_ASSERT(0 == yaFTL.wrState.index.nextPage); + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[yaFTL.wrState.index.nextPage], mdPtr); + META_SET_WEAVESEQ(mdPtr); + status = _writePage(Vpn, pageBuffer, mdPtr, FALSE32); + if (status != FTL_SUCCESS) + { + debug(WRITE, "cannot write index page "); + YAFTL_GC_Index_Enq(yaFTL.wrState.index.block); + allocateBlock(yaFTL.wrState.index.block, 0, 0); + + goto ONEMORETIME; + } + yaFTL.blockArray[yaFTL.wrState.index.block].validPagesINo++; + yaFTL.seaState.index.validPages++; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages++; +#endif + yaFTL.wrState.index.nextPage++; + } + + yaFTL.tocArray[META_GET_IPN(mdPtr)].indexPage = Vpn; + return FTL_SUCCESS; +} +#endif + +#ifndef AND_READONLY + + +static ANDStatus makeErasable(UInt32 block) +{ + if((block < FTL_AREA_SIZE) && (yaFTL.blockArray[block].status == BLOCK_ALLOCATED) && (yaFTL.blockArray[block].validPagesDNo == 0)) + { + YAFTL_GC_Data_Deq_sb(block); + yaFTL.blockArray[block].eraseBeforeUse = BLOCK_TO_BE_ERASED_ALIGNED_DATA; + yaFTL.blockArray[block].pagesRead = 0; + yaFTL.blockArray[block].pagesReadSubCounter = 0; + yaFTL.blockArray[block].validPagesDNo = yaFTL.blockArray[block].validPagesINo = 0; + yaFTL.seaState.freeBlocks++; + yaFTL.blockArray[block].status = BLOCK_FREE; + yaFTL.seaState.data.freeBlocks++; + yaFTL.seaState.data.allocdBlocks--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks++; +#endif + } + return FTL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_DeleteSectors */ +/* DESCRIPTION */ +/* marks range of logical pages that are deleted or about to be deleted */ +/* as not valid */ +/* */ +/*****************************************************************************/ +static void YAFTL_DeleteSectors(UInt32 lba, UInt32 count) +{ + UInt32 i, indexOfs; + UInt32 *indexPage = NULL; + UInt32 oldVpn, oldBlock, oldBlockValid; + UInt32 newZeroValid = 0, entry; + + if (yaFTL.cxtValid) { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + // Index: decrement valid in sb, and global validPages, update vpn, erase? + for (i = 0; i < count; i++) { + // Load index page if it's not valid +#if ENABLE_L2V_TREE + if(indexPage == NULL) + { + yaFTL.read_c.span = 0; + yaFTL.read_c.lba = lba + i; + L2V_Search(&yaFTL.read_c); + WMR_ASSERT(0 != yaFTL.read_c.span); + if (L2V_VPN_DEALLOC == yaFTL.read_c.vpn) + { + i += (yaFTL.read_c.span -1); + continue; + } + } +#endif // ENABLE_L2V_TREE + if (indexPage == NULL) + { + indexPage = IndexLoadClean(lba + i, &indexOfs, &entry); + } + + if(indexPage == NULL) + { + i += (yaFTL.indexPageRatio - (((lba + i) % yaFTL.indexPageRatio) + 1)); + continue; + } + + // Take care of the old + oldVpn = indexPage[indexOfs]; + oldBlockValid = 0xffffffff; + oldBlock = oldVpn / PAGES_PER_SUBLK; + if (0xffffffff != oldVpn) + { + yaFTL.seaState.data.validPages--; + WMR_ASSERT(0 != yaFTL.blockArray[oldBlock].validPagesDNo); + oldBlockValid = --yaFTL.blockArray[oldBlock].validPagesDNo; + indexPage[indexOfs] = 0xffffffff; + IndexMarkDirty(entry); +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages--; +#endif + } + indexOfs++; + + // Ready to erase? + if ((0 == oldBlockValid) + && (BLOCK_ALLOCATED == yaFTL.blockArray[oldBlock].status)) + { + makeErasable(oldBlock); + newZeroValid++; + } + + // Invalidate current index page if we've passed the end + if (indexOfs >= yaFTL.indexPageRatio) + { + indexPage = NULL; + } + } + +#if ENABLE_L2V_TREE + L2V_Update(lba, count, L2V_VPN_DEALLOC); +#endif // ENABLE_L2V_TREE +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Unmap */ +/* DESCRIPTION */ +/* spans trim */ +/* */ +/*****************************************************************************/ +static ANDStatus YAFTL_Unmap(FTLExtent_t *extents, UInt32 numExtents) +{ + while (numExtents--) + { + YAFTL_DeleteSectors((UInt32)extents->lba, (UInt32)extents->span); + extents++; + } + + return FTL_SUCCESS; +} + +#endif + +BOOL32 _verifyMetaData(UInt32 lpn, PageMeta_t * pmdPtr, UInt32 numOfPages) +{ + UInt32 i; + + for (i = 0; i < numOfPages; i++) + { + if (META_GET_LBA(&pmdPtr[i]) != (lpn + i)) + { +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Yaftl_read error .mismatch between lpn and metadata at lpn 0x%08x meta 0x%08x", lpn + i, META_GET_LBA(&pmdPtr[i])); +#else + WMR_PRINT(QUAL_FATAL, "Yaftl_read error .mismatch between lpn and metadata at lpn 0x%08x meta 0x%08x", lpn + i, META_GET_LBA(&pmdPtr[i])); +#endif + return FALSE32; + } + // Check for uECC mark + if (META_IS_UECC(&pmdPtr[i])) { + return FALSE32; + } + } + return TRUE32; +} + + + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Read */ +/* DESCRIPTION */ +/* reads out a range of consecutive logical pages */ +/* */ +/*****************************************************************************/ +//#include + +static Int32 +YAFTL_Read(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pBuf) +{ + UInt32 i, vpnOffset = 0; + UInt8 *currBatch = NULL; + UInt32 vPN /*,*tPtr=NULL*/; + UInt16 cacheIndexPtr; + UInt8 *currPage = pBuf; + Int32 status; + ANDStatus statusRet = FTL_SUCCESS; + UInt32 * vpnT = NULL; + UInt32 indexPageNo, indexPageSub, indexPage; + + if((pBuf == NULL) && (dwNumOfPages != 1)) + return FTL_CRITICAL_ERROR; +#ifdef AND_COLLECT_STATISTICS + if(pBuf != NULL) + stFTLStatistics.ddwFTLReadCnt++; + if((dwNumOfPages > 0) && (dwNumOfPages <= 8)) + { + stFTLStatistics.ddwRead[dwNumOfPages-1]++; + } + else + { + if(dwNumOfPages > 8) + stFTLStatistics.ddwReadOver8++; + } +#endif + /* take care of a simple case of reading single sector and then take it from there */ + if ((dwLpn + dwNumOfPages) >= yaFTL.logicalPartitionSize) + { + return FTL_CRITICAL_ERROR; + } + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(dwLpn, dwNumOfPages, pBuf); + } + + yaFTL.readBufferIndex = 0xffffffff; + + yaFTL.read_c.span = 0; + vpnT = yaFTL.multiReadvpN; + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + vpnT[0] = 0xffffffff; + } + for (i = 0; i < dwNumOfPages; i++, currPage += BYTES_PER_PAGE) + { +#if ENABLE_L2V_TREE + if (0 == yaFTL.read_c.span) { + yaFTL.read_c.lba = dwLpn + i; + L2V_Search(&yaFTL.read_c); + + } + WMR_ASSERT(0 != yaFTL.read_c.span); + + if (L2V_VPN_MISS != yaFTL.read_c.vpn) { + // Not missing from IC tree + if (L2V_VPN_DEALLOC != yaFTL.read_c.vpn) { + // Not deallocated + vPN = yaFTL.read_c.vpn; + if (yaFTL.read_c.vpn < L2V_VPN_SPECIAL) { + yaFTL.read_c.vpn++; + } + } else { + // Deallocated + vPN = 0xffffffff; + } + yaFTL.read_c.span--; + } else { + yaFTL.read_c.span--; + if (yaFTL.read_c.vpn < L2V_VPN_SPECIAL) { + yaFTL.read_c.vpn++; + } +#else // if not ENABLE_L2V_TREE: + if (1) { +#endif // !ENABLE_L2V_TREE + + // Missed first search... :( + indexPageNo = (dwLpn + i) / yaFTL.indexPageRatio; + indexPageSub = (dwLpn + i) % yaFTL.indexPageRatio; + indexPage = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexPtr = yaFTL.tocArray[indexPageNo].cacheIndex; + + if ((indexPage != 0xffffffff) || (cacheIndexPtr != 0xffff)) + { + /* Index page exists */ + if (cacheIndexPtr != 0xffff) + { + /* Index page is in index cache */ + vPN = yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub]; + if (yaFTL.indexCache[cacheIndexPtr].counter < YAFTL_INDEX_CACHE_COUNTER_LIMIT) + yaFTL.indexCache[cacheIndexPtr].counter++; + } + else + { + /* Index page exists , but it is not in index cache . Read it from flash to cache first */ + cacheIndexPtr = findFreeCacheEntry(); + + if (cacheIndexPtr != 0xffff) + { + status = (UInt8)_readPage(indexPage, (UInt8 *)(yaFTL.indexCache[cacheIndexPtr].indexPage), NULL, FALSE32, TRUE32, TRUE32); + if (status != FTL_SUCCESS) + { + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } +#ifndef AND_READONLY + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Failed Index read Page 0x%08x Status 0x%08x", indexPage, status); +#endif + return status; + } +#if ENABLE_L2V_TREE + PopulateFromIndexCache(indexPageNo, (UInt32*)yaFTL.indexCache[cacheIndexPtr].indexPage); +#endif // ENABLE_L2V_TREE + yaFTL.freeCachePages--; + yaFTL.indexCache[cacheIndexPtr].status = IC_BUSY_PAGE; + yaFTL.indexCache[cacheIndexPtr].counter = 1; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexPtr; + yaFTL.indexCache[cacheIndexPtr].tocEntry = indexPageNo; + vPN = yaFTL.indexCache[yaFTL.tocArray[indexPageNo].cacheIndex].indexPage[indexPageSub]; + } + else + { + if (yaFTL.readBufferIndex != indexPageNo) + { + status = (UInt8)_readPage(indexPage, (UInt8 *)yaFTL.tmpReadBuffer, NULL, FALSE32, TRUE32, TRUE32); + if (status != FTL_SUCCESS) + { + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } +#ifndef AND_READONLY + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Failed Index read Page 0x%08x Status 0x%08x", indexPage, status); +#endif + return status; + } + yaFTL.readBufferIndex = indexPageNo; + } + vPN = yaFTL.tmpReadBuffer[indexPageSub]; + } + } + } + else + { + /* Index page does not exist => page was never updated */ + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + vpnOffset = 0; + continue; + } + } + + // Translation valid--perform the read: + if (vPN != 0xffffffff) + { + vpnT[vpnOffset] = vPN; + vpnOffset++; + if (currBatch == NULL) + { + currBatch = currPage; + } + if (PAGES_PER_SUBLK == vpnOffset) + { + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + debug(READ, "Yaftl_read before readmulti1 how many 0x%x where 0x%x", vpnOffset, currBatch); + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + vpnOffset = 0; + currBatch = NULL; + } + } + else + { + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + debug(READ, "Yaftl_read before readmulti2 how many 0x%x where 0x%x", vpnOffset, currBatch); + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + vpnOffset = 0; + currBatch = NULL; + continue; + } + } + + if (vpnOffset != 0) + { + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_SUCCESS; + } + debug(READ, "Yaftl_read before readmulti how many 0x%x where 0x%x", vpnOffset, currBatch); + if (_readMultiPages((UInt32 *)vpnT, (UInt16)vpnOffset, currBatch, NULL, FALSE32, TRUE32)) + { + if(_verifyMetaData((dwLpn + ((currBatch - pBuf) / BYTES_PER_PAGE)), yaFTL.readMdPtr, vpnOffset) == FALSE32) + statusRet = FTL_USERDATA_ERROR; + } + else + statusRet = FTL_USERDATA_ERROR; + } + + if((pBuf == NULL) && (dwNumOfPages == 1)) + { + return FTL_USERDATA_ERROR; + } +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwPagesReadCnt += dwNumOfPages; +#endif +#ifndef AND_READONLY + if (yaFTL.readLimit == TRUE32) + { + if (yaFTL.blockArray[yaFTL.wrState.index.block].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + if ((yaFTL.blockArray[yaFTL.wrState.index.block].status == BLOCK_I_ALLOCATED) + || (yaFTL.blockArray[yaFTL.wrState.index.block].status == BLOCK_I_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[yaFTL.wrState.index.block].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + { + UInt16 sb = yaFTL.wrState.index.block; + + BTOC_Lock(sb); + YAFTL_GC_Index(yaFTL.wrState.index.block, TRUE32); + BTOC_Unlock(sb); + } + WMR_TRACE_IST_0(ReadDist, END); + + } + } + if (yaFTL.blockArray[yaFTL.wrState.data.block].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + if ((yaFTL.blockArray[yaFTL.wrState.data.block].status == BLOCK_ALLOCATED) + || (yaFTL.blockArray[yaFTL.wrState.data.block].status == BLOCK_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[yaFTL.wrState.data.block].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + { + UInt16 sb = yaFTL.wrState.data.block; + + BTOC_Lock(sb); + YAFTL_GC_Data(yaFTL.wrState.data.block, TRUE32); + BTOC_Unlock(sb); + } + WMR_TRACE_IST_0(ReadDist, END); + } + } + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + if (yaFTL.blockArray[i].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + if ((yaFTL.blockArray[i].status == BLOCK_I_ALLOCATED) + || (yaFTL.blockArray[i].status == BLOCK_I_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[i].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + YAFTL_GC_Index(i, TRUE32); + WMR_TRACE_IST_0(ReadDist, END); + continue; + } + if ((yaFTL.blockArray[i].status == BLOCK_ALLOCATED) + || (yaFTL.blockArray[i].status == BLOCK_CURRENT)) + { + WMR_TRACE_IST_0(ReadDist, START); +#ifdef AND_COLLECT_STATISTICS + if(yaFTL.blockArray[i].pagesRead == 0xffff) + { + stFTLStatistics.ddwReadDisturbHandleCall++; + } + else + { + stFTLStatistics.ddwRefreshCnt++; + } +#endif + YAFTL_GC_Data(i, TRUE32); + WMR_TRACE_IST_0(ReadDist, END); + continue; + } + } + } + yaFTL.readLimit = FALSE32; + } + + // Periodic cxt save for ANDStats preservation + if ((yaFTL.periodicCxt.pagesWritten >= WRITE_CXT_UPDATE_THRESHOLD) || (yaFTL.periodicCxt.erases >= ERASE_CXT_UPDATE_THRESHOLD)) + { + YAFTL_WriteStats(); + } +#endif + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } + + return statusRet; +} + +#ifndef AND_READONLY +void IndexMarkDirty(UInt32 tocEntry) +{ + UInt32 cacheIndexOfs; + UInt32 indexPagePhy; + + if(tocEntry >= yaFTL.TOCtableEntriesNo) + return; + + cacheIndexOfs = yaFTL.tocArray[tocEntry].cacheIndex; + indexPagePhy = yaFTL.tocArray[tocEntry].indexPage; + + if(cacheIndexOfs >= yaFTL.indexCacheSize) + return; + + if (IC_DIRTY_PAGE == yaFTL.indexCache[cacheIndexOfs].status) + return; + + // Mark as dirty + yaFTL.indexCache[cacheIndexOfs].status = IC_DIRTY_PAGE; + + // Early out; nothing to account for + if (0xffffffff == indexPagePhy) + { + return; + } + + // Mark previous index page as invalid + yaFTL.blockArray[indexPagePhy / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[tocEntry].indexPage = 0xffffffff; +} + +UInt32* IndexLoadClean(UInt32 lba, UInt32 *indexOfs, UInt32 *d_tocEntry) +{ + UInt32 indexPageNo, indexPageSub; + UInt32 indexPagePhy; + UInt32 cacheIndexOfs, oldCacheIndexOfs; + UInt32 status; + PageMeta_t *md = yaFTL.meta_indexLoadDirty; + + *d_tocEntry = 0xffffffff; + + // Calculate which index page and offset within for this update + indexPageNo = lba / yaFTL.indexPageRatio; + indexPageSub = lba % yaFTL.indexPageRatio; + indexPagePhy = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexOfs = yaFTL.tocArray[indexPageNo].cacheIndex; + oldCacheIndexOfs = cacheIndexOfs; + // Set up return parameter + *indexOfs = indexPageSub; + + // Don't load unmapped regions + if ((0xffffffff == indexPagePhy) && (0xffff == cacheIndexOfs)) + { + // All sectors addressed are in deleted state + return NULL; + } + + // Find or create cache entry + if (0xffff == cacheIndexOfs) { + cacheIndexOfs = findFreeCacheEntry(); + if (cacheIndexOfs == 0xffff) { + cacheIndexOfs = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexOfs == 0xffff) { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("failed to evict index page from cache"); + } + } + WMR_MEMSET(yaFTL.indexCache[cacheIndexOfs].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.freeCachePages--; + status = _readPage(indexPagePhy, (UInt8 *)yaFTL.indexCache[cacheIndexOfs].indexPage, md, FALSE32, TRUE32, TRUE32); + //TODO: reconstruct index page by default, but be careful of coherency issues with prior tree update + if (status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("uECC index page in ILD: vpn 0x%x, indexPageNo %d", indexPagePhy, indexPageNo); // TODO: reconstruct + } + // Reset counter since we just pulled this in to the cache + yaFTL.indexCache[cacheIndexOfs].counter = 0; + yaFTL.indexCache[cacheIndexOfs].status = IC_BUSY_PAGE; + yaFTL.indexCache[cacheIndexOfs].tocEntry = indexPageNo; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexOfs; + } + + // Give back the pointer to the cached index page + *d_tocEntry = indexPageNo; + + return yaFTL.indexCache[cacheIndexOfs].indexPage; +} + +UInt32* IndexLoadDirty(UInt32 lba, UInt32 *indexOfs) +{ + UInt32 indexPageNo, indexPageSub; + UInt32 indexPagePhy; + UInt32 cacheIndexOfs, oldCacheIndexOfs; + UInt32 *indexPage; + UInt32 status; + PageMeta_t *md = yaFTL.meta_indexLoadDirty; + + // Calculate which index page and offset within for this update + indexPageNo = lba / yaFTL.indexPageRatio; + indexPageSub = lba % yaFTL.indexPageRatio; + indexPagePhy = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexOfs = yaFTL.tocArray[indexPageNo].cacheIndex; + oldCacheIndexOfs = cacheIndexOfs; + // Set up return parameter + *indexOfs = indexPageSub; + + // Find or create cache entry + if (0xffff == cacheIndexOfs) { + cacheIndexOfs = findFreeCacheEntry(); + if (cacheIndexOfs == 0xffff) { + cacheIndexOfs = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexOfs == 0xffff) { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("failed to evict index page from cache"); + } + } + WMR_MEMSET(yaFTL.indexCache[cacheIndexOfs].indexPage, 0xff, BYTES_PER_PAGE); + yaFTL.freeCachePages--; + // Reset counter since we just pulled this in to the cache + yaFTL.indexCache[cacheIndexOfs].counter = 0; + } + yaFTL.indexCache[cacheIndexOfs].tocEntry = indexPageNo; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexOfs; + + yaFTL.indexCache[cacheIndexOfs].status = IC_DIRTY_PAGE; + if (yaFTL.indexCache[cacheIndexOfs].counter < YAFTL_INDEX_CACHE_COUNTER_LIMIT) + yaFTL.indexCache[cacheIndexOfs].counter++; + indexPage = yaFTL.indexCache[cacheIndexOfs].indexPage; + + // Don't load unmapped regions + if (0xffffffff == indexPagePhy) { + // All sectors addressed are in deleted state + return indexPage; + } + + // Load index page + if (0xffff == oldCacheIndexOfs) { + status = _readPage(indexPagePhy, (UInt8 *)indexPage, md, FALSE32, TRUE32, TRUE32); + //TODO: reconstruct index page by default, but be careful of coherency issues with prior tree update + if (status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("uECC index page in ILD: vpn 0x%x, indexPageNo %d", indexPagePhy, indexPageNo); // TODO: reconstruct + } + } + + // Mark previous index page as invalid + yaFTL.blockArray[indexPagePhy / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[indexPageNo].indexPage = 0xffffffff; + + // Give back the pointer to the cached index page + return indexPage; +} +#endif + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Write */ +/* DESCRIPTION */ +/* writes a range of consecutive logical pages to flash */ +/* */ +/*****************************************************************************/ +static Int32 +YAFTL_Write(UInt32 dwLpn, UInt32 dwNumOfPages, UInt8 *pabDataBuf, BOOL32 isStatic) +{ + UInt8 *curPage; + PageMeta_t *mdPtr; + UInt32 lba, count; + UInt32 toMegaStripeEnd, toBlockEnd, thisCount, ofs, i; + UInt32 vpn, indexOfs, oldBlock; + UInt32 *indexPage; + // For recovering from program failure--restart the write at the beginning of + // the write, or the most recently crossed superblock boundary. + UInt32 blockStartLba, blockStartCnt; + UInt8 *blockStartBuf; + + // Invalidate context + if (yaFTL.cxtValid) { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + debug(WRITE, " YAFTL_Write[start] 0x%x 0x%x isStatic: %s", dwLpn, dwNumOfPages, (isStatic)?"YES":"NO"); +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFTLWriteCnt++; + if((dwNumOfPages > 0) && (dwNumOfPages <= 8)) + { + stFTLStatistics.ddwWrite[dwNumOfPages-1]++; + } + else + { + if(dwNumOfPages > 8) + stFTLStatistics.ddwWriteOver8++; + } +#endif + if ((dwLpn + dwNumOfPages) >= yaFTL.logicalPartitionSize) + { + return FTL_CRITICAL_ERROR; + } + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(dwLpn, dwNumOfPages, pabDataBuf); + } + + // Delete the sectors prior to write + YAFTL_DeleteSectors(dwLpn, dwNumOfPages); + + blockStartLba = dwLpn; + blockStartCnt = dwNumOfPages; + blockStartBuf = pabDataBuf; +recoverPfail: + // Restore counters + curPage = blockStartBuf; + lba = blockStartLba; + count = blockStartCnt; + + // Do garbage collection prior to the write + YAFTL_GC_PreWrite(count); + + mdPtr = yaFTL.writeMdPtr; + // Writes and tree/index update: + ofs = 0; + while (count) { + // Advance block? + if (yaFTL.wrState.data.nextPage >= (PAGES_PER_SUBLK - yaFTL.controlPageNo)) { + writeCurrentBlockTOC(1); + allocateBlock(yaFTL.wrState.data.block, 0, 1); + blockStartLba = lba; + blockStartCnt = count; + blockStartBuf = curPage; + } + + // How many this round? Do up to a megastripe, subtracting to align to stripe end. + toMegaStripeEnd = ((NUM_BANKS * YAFTL_WRITE_MAX_STRIPES) - (yaFTL.wrState.data.nextPage % NUM_BANKS)); + toBlockEnd = (PAGES_PER_SUBLK - yaFTL.controlPageNo - yaFTL.wrState.data.nextPage); + thisCount = WMR_MIN(count, WMR_MIN(toMegaStripeEnd, toBlockEnd)); + + // Generate metadata + SetupMeta_Data(mdPtr, lba, thisCount); + + // Write the data + vpn = (yaFTL.wrState.data.block * (UInt32)PAGES_PER_SUBLK) + yaFTL.wrState.data.nextPage; + if (!VFL_WriteMultiplePagesInVb(vpn, thisCount, curPage, (UInt8 *)mdPtr, TRUE32, FALSE32)) { + oldBlock = yaFTL.wrState.data.block; + if(addBlockToEraseNowList(oldBlock) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", oldBlock); + } + BTOC_Lock(oldBlock); + allocateBlock(oldBlock, 0, 1); + YAFTL_DeleteSectors(blockStartLba, blockStartCnt); + if (BLOCK_FREE != yaFTL.blockArray[oldBlock].status) { + // Only GC it if it wasn't taken care of by DeleteSectors + YAFTL_GC_Data(oldBlock, TRUE32); + } + BTOC_Unlock(oldBlock); + goto recoverPfail; + } + + // Update TOC: + for (i = 0; i < thisCount; i++) { + yaFTL.wrState.data.TOC[yaFTL.wrState.data.nextPage + i] = lba + i; + } + + // Tree: update +#if ENABLE_L2V_TREE + L2V_Update(lba, thisCount, vpn); +#endif // ENABLE_L2V_TREE + + // Index: decrement valid in sb, and global validPages, update vpn + indexPage = IndexLoadDirty(lba, &indexOfs); + for (i = 0; i < thisCount; i++) { + // Update vpn + indexPage[indexOfs] = vpn + i; + + // Next + indexOfs++; + if (indexOfs >= yaFTL.indexPageRatio) { + indexPage = IndexLoadDirty(lba + i + 1, &indexOfs); + } + } + + // Update counters + yaFTL.wrState.data.nextPage += thisCount; + yaFTL.seaState.data.validPages += thisCount; + yaFTL.blockArray[yaFTL.wrState.data.block].validPagesDNo += thisCount; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages += thisCount; +#endif + + // Next + lba += thisCount; + ofs += thisCount; + count -= thisCount; + curPage += (thisCount * BYTES_PER_PAGE); + } + + // Periodic cxt save for ANDStats preservation + stFTLStatistics.ddwPagesWrittenCnt += dwNumOfPages; + yaFTL.periodicCxt.pagesWritten += dwNumOfPages; + if ((yaFTL.periodicCxt.pagesWritten >= WRITE_CXT_UPDATE_THRESHOLD) || (yaFTL.periodicCxt.erases >= ERASE_CXT_UPDATE_THRESHOLD)) + { + YAFTL_WriteStats(); + } + + if (FIL_GetFuncTbl()->RegisterCurrentTransaction) + { + FIL_GetFuncTbl()->RegisterCurrentTransaction(0, 0, NULL); + } + + return FTL_SUCCESS; +} + +#endif + + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Format */ +/* DESCRIPTION */ +/* performs low-level clean up of a flash */ +/* */ +/*****************************************************************************/ +#ifdef AND_COLLECT_STATISTICS +static ANDStatus getStats(UInt16 *cxtT) +{ + UInt16 currentCX = 0; + UInt16 i; + ANDStatus status = FTL_CRITICAL_ERROR; + WeaveSeq_t lastCX = 0; + Buffer *buf = BUF_Get(BUF_MAIN_AND_SPARE); + UInt8 *tBuff; + PageMeta_t *md = yaFTL.meta_getStats; + + debug(FORMAT, "[FTL:MSG] getStats[start] 0x%x", PAGES_PER_SUBLK); + + /* read out VFL_meta data . If it is not present execute full format . If it is present go and fetch "quick mount" info from CX area if it's valid .If not execute restore + For now we need to start from fresh media which means there is no quick mount info and all blocks are free . */ + /* Get CXT blocks from the VFL */ + if (buf == NULL) + { + return FTL_CRITICAL_ERROR; + } + + tBuff = buf->pData; + + if (cxtT[0] == 0xffff) + { + BUF_Release(buf); + return FTL_CRITICAL_ERROR; + } + + for (i = 0; i < FTL_CXT_SECTION_SIZE; i++) + { + status = VFL_Read(cxtT[i] * PAGES_PER_SUBLK, buf, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (status != VFL_SUCCESS) + { + continue; + } + WMR_MEMCPY(md, buf->pSpare, sizeof(PageMeta_t)); + if(sizeof(WeaveSeq_t) <= 4) + { + if ((META_GET_WEAVESEQ(md) != 0xffffffff) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = (UInt32)META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; + } + } + else + { + if ((META_GET_WEAVESEQ(md) != (WeaveSeq_t)0xffffffffffffULL) && (lastCX < META_GET_WEAVESEQ(md))) + { + lastCX = (UInt32)META_GET_WEAVESEQ(md); + currentCX = cxtT[i]; + } + } + } + + if (lastCX != 0) + { + debug(FORMAT, "getStats : currentCX is %d", currentCX); + } + else + { + debug(FORMAT, "[FTL:MSG] getStats could not find CXT at all "); + BUF_Release(buf); + return FTL_CRITICAL_ERROR; + } + + for (i = PAGES_PER_SUBLK; i > 0; i--) + { + status = VFL_Read((currentCX * PAGES_PER_SUBLK) + (i - 1), buf, TRUE32, FALSE32, NULL, NULL, FALSE32); + + if (status == VFL_SUCCESS) + { + if (WMR_MEMCMP(tBuff, CXT_VER, 4) == 0) + { + debug(FORMAT, "latest cxt is at offset 0x%x",(currentCX * PAGES_PER_SUBLK) + (i - 1)); + status = VFL_Read((currentCX * PAGES_PER_SUBLK) + (i - 1) + 1 + 2*yaFTL.controlPageNo, buf, TRUE32, FALSE32, NULL, NULL, FALSE32); + if (status == VFL_SUCCESS) + { + debug(FORMAT, "getting stats at offset 0x%x", (currentCX * PAGES_PER_SUBLK) + (i - 1) + 1 + 2*yaFTL.controlPageNo); + _FTLSetStatisticsFromCxt(tBuff); + BUF_Release(buf); + return FTL_SUCCESS; + } + } + } + } + debug(FORMAT, "[FTL:MSG] getStats could not find CXT at all "); + BUF_Release(buf); + + return FTL_CRITICAL_ERROR; +} +#endif + +static ANDStatus YAFTL_Format(UInt32 dwOptions) +{ + UInt32 i, ftlType; + ANDStatus status, statStatus; + UInt16 cxtT[FTL_CXT_SECTION_SIZE]; + BOOL32 moveCxt = FALSE32; + + status = FTL_CRITICAL_ERROR; + debug(FORMAT, "[FTL:MSG] YAFTL_Format[start]"); +#ifdef AND_COLLECT_STATISTICS + WMR_MEMCPY(cxtT, VFL_GetFTLCxtVbn(), FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + + statStatus = getStats(cxtT); +#endif + for (i = 0; i < (UInt32)FTL_AREA_SIZE; i++) + { + status = VFL_Erase((UInt16)i, TRUE32); + } + + if(cxtT[0] != 0xffff) + { + for (i = 0; i < (UInt32)FTL_CXT_SECTION_SIZE; i++) + { + if(cxtT[i] >= FTL_AREA_SIZE) + { + debug(FORMAT, "[FTL:MSG] YAFTL_Format cxt 0x%x is out of range 0x%x",cxtT[i], FTL_AREA_SIZE); + VFL_Erase((UInt16)cxtT[i], TRUE32); + moveCxt = TRUE32; + } + } + if(moveCxt == TRUE32) + { + for (i = 0; i < (UInt32)FTL_CXT_SECTION_SIZE; i++) + { + cxtT[i] = i; + } + VFL_ChangeFTLCxtVbn(cxtT); + } + } + +#ifdef AND_COLLECT_STATISTICS + if (statStatus == FTL_SUCCESS) + { + yaFTL.currentCxtVpn = 0xffffffff; + yaFTL.currentCXTIndex = 0; + yaFTL.cxtValid = 0; + yaFTL.formatWasCalled = 1; + quickMountUpdate(FALSE32); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + } +#endif + if (status != FTL_SUCCESS) + { + return status; + } + debug(FORMAT, "[FTL:MSG] YAFTL_Format[end]"); + ftlType = FTL_TYPE_YAFTL; + VFL_SetStruct(AND_STRUCT_VFL_FTLTYPE, &ftlType, sizeof(UInt32)); + yaFTL.formatWasCalled = 1; + return FTL_SUCCESS; +} +#endif +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_WearLevel */ +/* DESCRIPTION */ +/* moves read-only blocks around */ +/* */ +/*****************************************************************************/ +static Int32 YAFTL_WearLevel(void) +{ + UInt16 i,bestCandidate = 0xffff; + UInt16 bestCount = 0xffff; + UInt8 erasedCount = 0; + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwWearLevelCnt++; +#endif + + // Gap too big, or not our time yet? Exit. + if (yaFTL.wearLevel.pointOfNoReturn || (yaFTL.wearLevel.blocksSince < YAFTL_WEARLEVEL_PERIOD)) + { + for (i = 0; (i < FTL_AREA_SIZE) && (erasedCount < ERASE_IDLE_LIMIT); i++) + { + if((yaFTL.blockArray[i].status == BLOCK_FREE) && (yaFTL.blockArray[i].eraseBeforeUse == BLOCK_TO_BE_ERASED)) + { + ANDStatus status; + + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(i, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) i, status); + return status; + } + + yaFTL.erasedBlockCount++; + erasedCount++; + yaFTL.blockArray[i].erasableCount++; + if (yaFTL.blockArray[i].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[i].erasableCount; + } + yaFTL.blockArray[i].eraseBeforeUse = 0; + } + } + return FTL_OUT_OF_RANGE_ERROR; + } + + WMR_TRACE_IST_0(WearLevel, START); + + // Find best candidate (least cycled block) + for (i = 0; i < FTL_AREA_SIZE; i++) + { + if (BLOCK_ALLOCATED != yaFTL.blockArray[i].status) + { + // Don't consider non-data blocks; erased blocks are ok, and index will take care of itself + continue; + } + + // Detect gap-too-big condition (aka pointOfNoReturn); + if ((yaFTL.blockArray[i].erasableCount + ERASE_COUNT_GAP_UPPER_LIMIT) < yaFTL.maxEraseCount) + { + debug(MISC, "\nYAFTL_WearLevel gap is too big . 0x%x maxerase 0x%x\n", yaFTL.blockArray[i].erasableCount, yaFTL.maxEraseCount); + yaFTL.wearLevel.pointOfNoReturn = TRUE32; + break; + } + + // Block at least GAP_LIMIT less than the maxErase? + if ((yaFTL.blockArray[i].erasableCount + ERASE_COUNT_GAP_LIMIT) < yaFTL.maxEraseCount) + { + if (yaFTL.blockArray[i].erasableCount < bestCount) + { + bestCandidate = i; + bestCount = yaFTL.blockArray[i].erasableCount; + } + } + } + + // Didn't find a candidate + if (0xffff == bestCandidate) + { + WMR_TRACE_IST_1(WearLevel, END, FTL_OUT_OF_RANGE_ERROR); + return FTL_OUT_OF_RANGE_ERROR; + } + + // Perform wear leveling + debug(MISC, "\nYAFTL_WearLevel @@@ block 0x%x blockerase 0x%x maxerase 0x%x\n", bestCandidate, yaFTL.blockArray[bestCandidate].erasableCount, yaFTL.maxEraseCount); + YAFTL_GC_Data(bestCandidate, TRUE32); + yaFTL.wearLevel.blocksSince -= YAFTL_WEARLEVEL_PERIOD; + + WMR_TRACE_IST_1(WearLevel, END, FTL_SUCCESS); + return FTL_SUCCESS; +} +#endif +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_GarbageCollect */ +/* DESCRIPTION */ +/* perfroms defragementation of a disk while system in idle time */ +/* */ +/*****************************************************************************/ +static BOOL32 YAFTL_GarbageCollect(void) +{ + return 1; +} +#endif +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_ShutdownNotify */ +/* DESCRIPTION */ +/* commits cached index pages as well as control information to flash */ +/* */ +/*****************************************************************************/ + +UInt16 how_many_updates = 0; + +static BOOL32 YAFTL_ShutdownNotify(BOOL32 boolMergeLogs) +{ + + flushIndexCache(1); + if(how_many_updates++ > MOVE_CXT_TRESHOLD ) + { + moveCXTarea(); + how_many_updates = 0; + } + +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFlushCnt++; +#endif + + while (quickMountUpdate(FALSE32) != FTL_SUCCESS) + { + debug(ERROR, "YAFTL_flushquickmountupdate failed"); + } + + // Clear periodic context drop counters + yaFTL.periodicCxt.pagesWritten = 0; + yaFTL.periodicCxt.erases = 0; + + return 1; +} + +static BOOL32 YAFTL_WriteStats(void) +{ + BOOL32 result = TRUE32; + + if(how_many_updates++ > MOVE_CXT_TRESHOLD ) + { + moveCXTarea(); + how_many_updates = 0; + } + + if (yaFTL.cxtValid != 1) + { + if(quickMountUpdate(TRUE32) != FTL_SUCCESS) + { + debug(ERROR, "YAFTL_flushquickmountupdate failed"); + result = FALSE32; + } + else + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + } + + // Clear periodic context drop counters + yaFTL.periodicCxt.pagesWritten = 0; + yaFTL.periodicCxt.erases = 0; + + return result; +} +#endif + +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_FreeMemory */ +/* DESCRIPTION */ +/* frees all allocated memory; called on error path in _Open, and _Close */ +/* */ +/*****************************************************************************/ +static void YAFTL_FreeMemory(void) +{ + // Free the zone + WMR_BufZone_Free(&yaFTL.BufZone); + WMR_BufZone_Free(&yaFTL.BufZone_IndexCache); + + // [TOC_SIZE] Table of content that contains location of index pages + // in flash and index cache + if (NULL != yaFTL.tocArray) { + WMR_FREE(yaFTL.tocArray, yaFTL.TOCtableEntriesNo * sizeof(TOCEntry)); + } + // [INDEX_CACHE_SIZE] cached index pages + if (NULL != yaFTL.indexCache) { + WMR_FREE(yaFTL.indexCache, yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + } + // [YAFTL_NO_OF_BLOCKS] block information + if (NULL != yaFTL.blockArray) { + WMR_FREE(yaFTL.blockArray, FTL_AREA_SIZE * sizeof(BlockEntry)); + } + if (NULL != yaFTL.multiReadvpN) { + WMR_FREE(yaFTL.multiReadvpN, sizeof(UInt32) * PAGES_PER_SUBLK); + } + +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&stFTLStatistics, 0, sizeof(FTLStatistics)); +#endif // AND_COLLECT_STATISTICS + +#ifndef AND_READONLY + YAFTL_GC_Close(); +#endif + +#if ENABLE_L2V_TREE + L2V_Free(); +#endif // ENABLE_L2V_TREE + + BTOC_Close(); + + // Null out pointers + yaFTL.quickRestore_tBuff = NULL; + yaFTL.wrState.data.TOC = NULL; + yaFTL.wrState.index.TOC = NULL; + yaFTL.tmpReadBuffer = NULL; + yaFTL.restoreTOC = NULL; + yaFTL.meta_restoreIdx = NULL; + yaFTL.meta_restoreData = NULL; + yaFTL.meta_readCxt = NULL; + yaFTL.meta_quickRestore = NULL; + yaFTL.meta_invalidateCxt = NULL; + yaFTL.meta_writeCxt = NULL; + yaFTL.meta_restoreMountErase = NULL; + yaFTL.meta_restoreMount = NULL; + yaFTL.meta_clearEntryInCache = NULL; + yaFTL.meta_writeBTOC = NULL; + yaFTL.meta_indexLoadDirty = NULL; + yaFTL.meta_getStats = NULL; + yaFTL.meta_GetBlockTOC = NULL; + yaFTL.meta_IsDataPageCurrent = NULL; + yaFTL.meta_WriteZoneData = NULL; + yaFTL.tocArray = NULL; + yaFTL.indexCache = NULL; + yaFTL.blockArray = NULL; + yaFTL.writeMdPtr = NULL; + yaFTL.multiReadvpN = NULL; + yaFTL.readMdPtr = NULL; + yaFTL.singleMdPtr = NULL; +} +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_Close */ +/* DESCRIPTION */ +/* frees up all the memory allocated by YAFTL tables */ +/* */ +/*****************************************************************************/ +static void YAFTL_Close(void) +{ + YAFTL_FreeMemory(); + WMR_MEMSET(&yaFTL_FTLDeviceInfo, 0, sizeof(FTLWMRDeviceInfo)); + WMR_MEMSET(&yaFTL_VFLFunctions, 0, sizeof(VFLFunctions)); + WMR_MEMSET(&yaFTL, 0, sizeof(yaFTL_t)); + yaftl_init_done = FALSE32; + +} + +#ifndef AND_READONLY + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _writeMultiPages */ +/* DESCRIPTION */ +/* writes a set of virtual pages */ +/* */ +/*****************************************************************************/ +BOOL32 _writeMultiPages(UInt16 vbn, UInt16 pageOffset, UInt16 wNumPagesToWrite, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp) +{ + BOOL32 status; + UInt32 vpn; + const BOOL32 bMovingUserData = bInternalOp && META_IS_DATA(mdPtr); + + debug(WRITE, "[FTL:MSG] writeMultiPages[start] 0x%x ", wNumPagesToWrite); + + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + vpn = (((UInt32)vbn * (UInt32)PAGES_PER_SUBLK) + (UInt32)pageOffset); + status = VFL_WriteMultiplePagesInVb(vpn, wNumPagesToWrite, pageData, (UInt8 *)mdPtr, TRUE32, bMovingUserData); + if (status) + { + return TRUE32; + } + else + { + WMR_PRINT(QUAL, "we got multiwrite failure at vbn %d\n", (UInt32) vbn); + return FALSE32; + } +} + +#endif + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _readMultiPages */ +/* DESCRIPTION */ +/* reads a set of virtual pages from flash */ +/* */ +/*****************************************************************************/ +BOOL32 _readMultiPages(UInt32 * padwVpn, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 bInternalOp, BOOL32 scrubOnUECC) +{ + BOOL32 status; + Int32 stat; + PageMeta_t *tempP = NULL; + UInt32 currentOffset, currentLen, i; + BOOL32 needsRefresh = FALSE32; + + debug(READ, " _readMultiPages[start] 0x%x ", wNumPagesToRead); + if (pbaSpare == NULL) + { + tempP = yaFTL.readMdPtr; + } + else + { + tempP = (PageMeta_t *)pbaSpare; + } + currentOffset = 0; + currentLen = wNumPagesToRead; + + while (currentLen > PAGES_PER_SUBLK) + { + for(i = 0; i < PAGES_PER_SUBLK; i++) + { + updateReadCounter((UInt16) padwVpn[currentOffset+i] / PAGES_PER_SUBLK); + } + + status = VFL_ReadScatteredPagesInVb(&(padwVpn[currentOffset]), PAGES_PER_SUBLK, &(pbaData[currentOffset * BYTES_PER_PAGE]), (UInt8 *)tempP, &needsRefresh, NULL, bInternalOp, &stat); + if (!status) + { + debug(ERROR, "we got read failure "); + status = TRUE32; + WMR_TRACE_IST_1(SingleReadFallback, START, stat); + for (i = 0; i < PAGES_PER_SUBLK; i++) + { + UInt32 current_vpn = padwVpn[currentOffset + i]; + stat = _readPage(current_vpn, &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + WMR_PRINT(QUAL, "read failure on vpn %d\n", current_vpn); + status = FALSE32; + } + } + WMR_TRACE_IST_1(SingleReadFallback, END, stat); + if (!status) + { + return FALSE32; + } + else + { + WMR_PRINT(QUAL_FATAL, "were able to overcome read failure\n"); + } + } + else + { + if(stat != FTL_SUCCESS) + return FALSE32; +#ifndef AND_READONLY + if( needsRefresh ) + { + WMR_PRINT(QUAL, "refresh is triggered\n"); + status = TRUE32; + for (i = 0; i < PAGES_PER_SUBLK; i++) + { + stat = _readPage(padwVpn[currentOffset + i], &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + status = FALSE32; + } + } + if (!status) + { + return FALSE32; + } + } +#endif + } + currentOffset += PAGES_PER_SUBLK; + currentLen -= PAGES_PER_SUBLK; + #ifndef AND_READONLY + /* Vadim - should not invalidate cxt while reading */ + /* cxtValid = 0; */ + if (yaFTL.blockArray[padwVpn[currentOffset] / PAGES_PER_SUBLK].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + yaFTL.readLimit = TRUE32; + WMR_TRACE_IST_1(ReadCountEnq, NONE, padwVpn[currentOffset] / PAGES_PER_SUBLK); + } + #endif // ! AND_READONLY + } + + if (currentLen > 0) + { + for(i = 0; i < currentLen; i++) + { + updateReadCounter((UInt16) padwVpn[currentOffset+i] / PAGES_PER_SUBLK); + } + +#ifndef AND_READONLY + if (yaFTL.blockArray[padwVpn[currentOffset] / PAGES_PER_SUBLK].pagesRead > YAFTL_READ_DISTURB_LIMIT) + { + yaFTL.readLimit = TRUE32; + WMR_TRACE_IST_1(ReadCountEnq, NONE, padwVpn[currentOffset] / PAGES_PER_SUBLK); + } +#endif // ! AND_READONLY + needsRefresh = FALSE32; + status = VFL_ReadScatteredPagesInVb(&(padwVpn[currentOffset]), (UInt16)currentLen, &(pbaData[currentOffset * BYTES_PER_PAGE]), (UInt8 *)tempP, &needsRefresh, NULL, bInternalOp, &stat); + if (status == FALSE32) + { + debug(ERROR, "we got read failure "); + status = TRUE32; + for (i = 0; i < currentLen; i++) + { + UInt32 current_vpn = padwVpn[currentOffset + i]; + stat = _readPage(current_vpn, &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + WMR_PRINT(QUAL, "read failure on vpn %d\n", current_vpn); + status = FALSE32; + } + } + + if (!status) + { + return FALSE32; + } + + WMR_PRINT(QUAL_FATAL, "were able to overcome read failure "); + } + else + { + if(stat != FTL_SUCCESS) + return FALSE32; +#ifndef AND_READONLY + if( needsRefresh ) + { + debug(ERROR, "refresh is triggered"); + status = TRUE32; + for (i = 0; i < currentLen; i++) + { + stat = _readPage(padwVpn[currentOffset + i], &(pbaData[(currentOffset + i) * BYTES_PER_PAGE]), &tempP[currentOffset + i], bInternalOp, TRUE32, scrubOnUECC); + if (stat != FTL_SUCCESS) + { + status = FALSE32; + } + } + if (!status) + { + return FALSE32; + } + } +#endif + } + } + + return TRUE32; +} + +#ifndef AND_READONLY + +BOOL32 isBlockInEraseNowList(UInt16 blockNo) +{ + UInt8 i; + BOOL32 res = FALSE32; + + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + if(yaFTL.eraseNowList[i] == blockNo) + { + res = TRUE32; + break; + } + } + + return res; +} + +BOOL32 removeBlockFromEraseNowList(UInt16 blockNo) +{ + UInt8 i; + BOOL32 res = FALSE32; + + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + if(yaFTL.eraseNowList[i] == blockNo) + { + res = TRUE32; + yaFTL.eraseNowList[i] = 0xffff; + break; + } + } + + return res; +} + +BOOL32 addBlockToEraseNowList(UInt16 blockNo) +{ + UInt8 i; + BOOL32 res = FALSE32; + + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + if(yaFTL.eraseNowList[i] == blockNo) + { + res = TRUE32; + break; + } + if(yaFTL.eraseNowList[i] == 0xffff) + { + yaFTL.eraseNowList[i] = blockNo; + res = TRUE32; + break; + } + } + if(res == FALSE32) + { + for(i = 0; i < ERASE_NOW_LIST_SIZE; i++) + { + UInt16 blockToCheck = yaFTL.eraseNowList[i]; + ANDStatus status; + + if(yaFTL.blockArray[blockToCheck].status == BLOCK_FREE) + { + if(yaFTL.blockArray[blockToCheck].eraseBeforeUse != 0) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + // Erase it + status = VFL_Erase(blockToCheck, TRUE32); + if (status != FTL_SUCCESS) + { + WMR_PANIC("VFL_Erase(%d) failed with 0x%08x", (UInt32) blockToCheck, status); + return 0xffffffff; + } + yaFTL.erasedBlockCount++; + yaFTL.blockArray[blockToCheck].eraseBeforeUse = 0; + yaFTL.blockArray[blockToCheck].erasableCount++; + yaFTL.periodicCxt.erases++; + if (yaFTL.blockArray[blockToCheck].erasableCount > yaFTL.maxEraseCount) + { + yaFTL.maxEraseCount = yaFTL.blockArray[blockToCheck].erasableCount; + } + } + yaFTL.eraseNowList[i] = blockNo; + res = TRUE32; + break; + } + } + } + return res; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _writePage */ +/* DESCRIPTION */ +/* writes sigle virtual page to flash */ +/* */ +/*****************************************************************************/ +Int32 _writePage(UInt32 vpn, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp) +{ + Buffer *buff; + Int32 status; + BOOL32 bMovingUserData; + + buff = BUF_Get(BUF_MAIN_AND_SPARE); + if (buff == NULL) + { + return FTL_CRITICAL_ERROR; + } + + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + buff->pData = pageData; + if (mdPtr != NULL) + { + WMR_MEMCPY(buff->pSpare, mdPtr, sizeof(PageMeta_t)); + bMovingUserData = bInternalOp && META_IS_DATA(mdPtr); + } + else + { + bMovingUserData = FALSE32; + } + + status = VFL_Write(vpn, buff, TRUE32, bMovingUserData); + if (status != VFL_SUCCESS) + { + WMR_PRINT(QUAL, "we got write failure at vpn %d ", vpn); + if(addBlockToEraseNowList(vpn / PAGES_PER_SUBLK) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", vpn / PAGES_PER_SUBLK); + } + } + BUF_Release(buff); + return status; +} +#endif + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _readPage */ +/* DESCRIPTION */ +/* reads sigle virtual page from flash */ +/* */ +/*****************************************************************************/ +Int32 _readPage(UInt32 vpn, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 bMarkECCForScrub) +{ + Buffer buff; + long status; + BOOL32 needsRefresh = FALSE32; + + buff.pData = pageData; + if (mdPtr) + { + buff.pSpare = (UInt8 *)mdPtr; + } + else + { + buff.pSpare = (UInt8 *)yaFTL.singleMdPtr; + } + + status = VFL_Read(vpn, &buff, boolCleanCheck, bMarkECCForScrub, &needsRefresh, NULL, bInternalOp); + if ((status == VFL_CRITICAL_ERROR) || (status == VFL_U_ECC_ERROR)) + { + if (bMarkECCForScrub) + { + // This is more serious if we were expecting it to be good + WMR_PRINT(QUAL, "we got read failure at x%x block 0x%x block status x%x scrub %d\n", + vpn, vpn / PAGES_PER_SUBLK, yaFTL.blockArray[vpn / PAGES_PER_SUBLK].status, bMarkECCForScrub); +#ifndef AND_READONLY + if(addBlockToEraseNowList(vpn / PAGES_PER_SUBLK) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", vpn / PAGES_PER_SUBLK); + } +#endif + } + else + { + debug(ERROR, "we got read failure at x%x block 0x%x block status x%x scrub %d", + vpn, vpn / PAGES_PER_SUBLK, yaFTL.blockArray[vpn / PAGES_PER_SUBLK].status, bMarkECCForScrub); + } + status = FTL_CRITICAL_ERROR; + } + + updateReadCounter((UInt16) vpn / PAGES_PER_SUBLK); + + if (needsRefresh && bMarkECCForScrub) + { + WMR_PRINT(QUAL, "vfl suggests read refresh on vpn %d\n", vpn); + } +#ifndef AND_READONLY + if ((yaFTL.blockArray[vpn / PAGES_PER_SUBLK].pagesRead > YAFTL_READ_DISTURB_LIMIT) || (needsRefresh == TRUE32)) + { + yaFTL.readLimit = TRUE32; + if( needsRefresh ) + { + debug(ERROR, "refresh is triggered at vpn 0x%x\n",vpn); + yaFTL.blockArray[vpn / PAGES_PER_SUBLK].pagesRead = 0xffff; // !!! this is a prep for readDistrub handling + WMR_TRACE_IST_1(ReadRefreshEnq, NONE, vpn / PAGES_PER_SUBLK); + } + else + { + WMR_TRACE_IST_1(ReadCountEnq, NONE, vpn / PAGES_PER_SUBLK); + } + } +#endif // ! AND_READONLY + + return status; +} + +static BOOL32 YAFTL_ECBins(void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + UInt16 blockIdx; + FTLBinsStruct hdr; + const UInt32 kdwStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_EC_BINS; + + if (!yaFTL.blockArray) + { + return FALSE32; + } + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= kdwStructSize)) + { + const UInt32 max_bin_val = FTL_MAX_EC_BIN_VAL; + const UInt32 bin_size = FTL_EC_BIN_SIZE; + UInt32 size = *pdwStructSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_EC_BINS; + WMR_MEMSET(pvoidStructBuffer, 0, kdwStructSize); + WMR_FILL_STRUCT(pvoidStructBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < FTL_AREA_SIZE; ++blockIdx) + { + UInt32 index; + UInt16 usage; + void *cursor; + + if (yaFTL.blockArray[blockIdx].erasableCount >= max_bin_val) + { + index = FTL_NUM_EC_BINS - 1; + } + else + { + index = yaFTL.blockArray[blockIdx].erasableCount / bin_size; + } + + cursor = ((char *)pvoidStructBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (pdwStructSize) + { + *pdwStructSize = kdwStructSize; + boolRes = TRUE32; + } + + return boolRes; +} + +static BOOL32 YAFTL_RCBins(void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + UInt16 blockIdx; + FTLBinsStruct hdr; + const UInt32 kdwStructSize = sizeof(hdr) + sizeof(*hdr.usage) * FTL_NUM_RC_BINS; + + if (!yaFTL.blockArray) + { + return FALSE32; + } + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= kdwStructSize)) + { + const UInt32 max_bin_val = YAFTL_READ_DISTURB_LIMIT; + const UInt32 bin_size = FTL_RC_BIN_SIZE(max_bin_val); + UInt32 size = *pdwStructSize; // only used for WMR_FILL_STRUCT + + hdr.maxValue = max_bin_val; + hdr.binCount = FTL_NUM_RC_BINS; + WMR_MEMSET(pvoidStructBuffer, 0, kdwStructSize); + WMR_FILL_STRUCT(pvoidStructBuffer, &size, &hdr, sizeof(hdr)); + + for (blockIdx = 0; blockIdx < FTL_AREA_SIZE; ++blockIdx) + { + UInt32 index; + UInt16 usage; + void *cursor; + + if (yaFTL.blockArray[blockIdx].pagesRead >= max_bin_val) + { + index = FTL_NUM_RC_BINS - 1; + } + else + { + index = yaFTL.blockArray[blockIdx].pagesRead / bin_size; + } + + cursor = ((char *)pvoidStructBuffer) + WMR_OFFSETOF(FTLBinsStruct, usage[index]); + WMR_MEMCPY(&usage, cursor, sizeof(usage)); + usage++; + WMR_MEMCPY(cursor, &usage, sizeof(usage)); + } + boolRes = TRUE32; + } + + if (pdwStructSize) + { + *pdwStructSize = kdwStructSize; + boolRes = TRUE32; + } + + return boolRes; +} + +static void fillUpTLBlockStructure(UInt32 blockNo, ANDFTLBlockStruct * tlBlockStruct) +{ + tlBlockStruct->blockSizeInLbas = PAGES_PER_SUBLK; + tlBlockStruct->validLbas = 0; + tlBlockStruct->blockType = 0; + switch (yaFTL.blockArray[blockNo].status) + { + case BLOCK_ALLOCATED: + case BLOCK_CURRENT: + case BLOCK_GC: + { + tlBlockStruct->blockType |= TL_BLOCK_DATA; + tlBlockStruct->validLbas = yaFTL.blockArray[blockNo].validPagesDNo; + break; + } + + case BLOCK_I_ALLOCATED: + case BLOCK_I_CURRENT: + case BLOCK_I_GC: + { + tlBlockStruct->blockType |= TL_BLOCK_INDEX; + tlBlockStruct->validLbas = yaFTL.blockArray[blockNo].validPagesINo; + break; + } + + case BLOCK_FREE: + { + tlBlockStruct->blockType |= TL_BLOCK_FREE; + break; + } + case BLOCK_CTX_CNTR: + case BLOCK_CTX_CURRENT: + tlBlockStruct->blockType |= TL_BLOCK_CXT; + break; + + default: + tlBlockStruct->blockType |= TL_BLOCK_UNKNOWN; + } +} + +static BOOL32 YAFTL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType) + { + case AND_STRUCT_FTL_GET_TYPE: + { + UInt8 bFTLType = FTL_TYPE_YAFTL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &bFTLType, sizeof(bFTLType)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_FTL_GET_FTL_STATS_SIZE: + { + UInt32 dwStatsSize = sizeof(FTLStatistics); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwStatsSize, sizeof(dwStatsSize)); + break; + } + + case AND_STRUCT_FTL_STATISTICS: + { +#if ENABLE_L2V_TREE + stFTLStatistics.ddwNodesFree = L2V.Pool.FreeCount; + stFTLStatistics.ddwNodesTotal = L2V_NODEPOOL_COUNT; +#endif //ENABLE_L2V_TREE + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stFTLStatistics, sizeof(stFTLStatistics)); + break; + } +#endif + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO_SIZE: + { + UInt32 dwFTLDevInfoSize = sizeof(FTLWMRDeviceInfo); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwFTLDevInfoSize, sizeof(dwFTLDevInfoSize)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_DEVICEINFO: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &yaFTL_FTLDeviceInfo, sizeof(yaFTL_FTLDeviceInfo)); + + break; + } + + case AND_STRUCT_FTL_GETADDRESS: + { + ANDAddressStruct stAddr; + UInt32 dwAddrSize = sizeof(stAddr); + BOOL32 boolFillRes; + + if (pvoidStructBuffer && pdwStructSize && (*pdwStructSize >= sizeof(stAddr))) + { + WMR_MEMCPY(&stAddr, pvoidStructBuffer, sizeof(stAddr)); + + if((YAFTL_Read(stAddr.dwLpn, 1, NULL) == FTL_SUCCESS) && (yaFTL.multiReadvpN[0] != 0xffffffff)) + { + stAddr.dwVpn = yaFTL.multiReadvpN[0]; + boolRes = VFL_GetStruct(AND_STRUCT_VFL_GETADDRESS, &stAddr, &dwAddrSize); + } + else + { + boolRes = FALSE32; + } + } + + boolFillRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stAddr, sizeof(stAddr)); + + if (boolRes) + { + boolRes = boolFillRes; + } + + break; + } + +#ifndef AND_READONLY + case AND_FUNCTION_INDEX_CACHE_UPDATE: + { + UInt32 i; + + if (!pdwStructSize) + { + boolRes = FALSE32; + break; + } + + boolRes = TRUE32; // So we can fail if the backup reallocate fails + flushIndexCache(0); + //todo : make sure we update TOC to reflect that current cache is gone + WMR_BufZone_Free(&yaFTL.BufZone_IndexCache); + WMR_FREE(yaFTL.indexCache, yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); /* [INDEX_CACHE_SIZE] cached index pages */ + yaFTL.indexCacheSize = *pdwStructSize; + + ALLOCATE_DEFAULT_CACHE: + yaFTL.indexCache = (CacheIndexEntry *)WMR_MALLOC(yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + if (yaFTL.indexCache == NULL) + { + boolRes = FALSE32; + yaFTL.indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; + goto ALLOCATE_DEFAULT_CACHE; + } + + // Allocate index cache buffers + WMR_BufZone_Init(&yaFTL.BufZone_IndexCache); + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + // Pre-reserve + yaFTL.indexCache[i].indexPage = (UInt32 *)WMR_Buf_Alloc_ForDMA(&yaFTL.BufZone_IndexCache, BYTES_PER_PAGE); + } + + // Finish allocations + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BufZone_IndexCache)) + { + WMR_FREE(yaFTL.indexCache, yaFTL.indexCacheSize * sizeof(CacheIndexEntry)); + WMR_ASSERT(FALSE32 != boolRes); // Panics if the re-allocate fails + boolRes = FALSE32; + yaFTL.indexCacheSize = DEFAULT_INDEX_CACHE_SIZE; + goto ALLOCATE_DEFAULT_CACHE; + } + + // Rebase and initialize + for (i = 0; i < yaFTL.indexCacheSize; i++) + { + WMR_BufZone_Rebase(&yaFTL.BufZone_IndexCache, (void**)&yaFTL.indexCache[i].indexPage); + yaFTL.indexCache[i].status = FREE_CACHE_PAGE; + yaFTL.indexCache[i].tocEntry = 0xffff; + yaFTL.indexCache[i].counter = 0; + WMR_MEMSET(yaFTL.indexCache[i].indexPage, 0xff, BYTES_PER_PAGE); + } + + // Finish rebases + WMR_BufZone_FinishedRebases(&yaFTL.BufZone_IndexCache); + + while (quickMountUpdate(FALSE32) != FTL_SUCCESS) + { + debug(ERROR, "YAFTL_flushquickmountupdate failed"); + } +// debug(ERROR, "YAFTL_GetStruct : update cache size to %d done ",indexCacheSize); + yaFTL.freeCachePages = yaFTL.indexCacheSize; + + boolRes = TRUE32; + break; + } +#endif // ! AND_READONLY + + case AND_STRUCT_FTL_GET_FTL_EC_BINS: + { + boolRes = YAFTL_ECBins(pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_FTL_GET_FTL_RC_BINS: + { + boolRes = YAFTL_RCBins(pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_FTL_RECOMMEND_CONTENT_DELETION: + { + UInt32 data = 0; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &data, sizeof(data)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_BLOCK_COUNT: + { + UInt32 tlBlockCount = FTL_AREA_SIZE; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &tlBlockCount, sizeof(tlBlockCount)); + break; + } + + case AND_STRUCT_FTL_GET_FTL_BLOCK_STAT: + { + UInt32 i, tmpBuffSize = *pdwStructSize, tmpChunkSize; + ANDFTLBlockStruct tempStruct; + UInt8 * tmpPtr = (UInt8 *)pvoidStructBuffer; + + if(tmpBuffSize >= (FTL_AREA_SIZE * sizeof(tempStruct))) + { + for(i = 0; (i < FTL_AREA_SIZE) && (tmpBuffSize >= sizeof(tempStruct)); i++, tmpBuffSize -= sizeof(tempStruct)) + { + fillUpTLBlockStructure(i, &tempStruct); + tmpChunkSize = tmpBuffSize; + boolRes = WMR_FILL_STRUCT(tmpPtr + (i * sizeof(ANDFTLBlockStruct)), &tmpChunkSize, &tempStruct, sizeof(tempStruct)); + } + } + break; + } + + default: + boolRes = FALSE32; + } + + return boolRes; +} +#ifdef AND_COLLECT_STATISTICS + +void _UpdateStatisticsCounters(UInt8 *pabSrc, void *pvoidStat, UInt32 dwSize) +{ + UInt32 dwIdx; + UInt64 * paddwStat = (UInt64 *)pvoidStat; + + for (dwIdx = 0; dwIdx < (dwSize / sizeof(UInt64)); dwIdx++) + { + UInt64 ddwTemp; + WMR_MEMCPY(&ddwTemp, &pabSrc[dwIdx * sizeof(UInt64)], sizeof(UInt64)); + paddwStat[dwIdx] = ddwTemp; //intentionally overwrite, not increment + } +} + +#ifndef AND_READONLY +static BOOL32 _FTLGetStatisticsToCxt(UInt8 * pabData) +{ + UInt32 dwStatBuffSize; + UInt32 dwStatVersion = AND_EXPORT_STRUCTURE_VERSION; + + UInt8 *pabCursor = pabData; + UInt8 *pabVersion = &pabData[BYTES_PER_PAGE - sizeof(UInt32)]; + + WMR_MEMSET(pabCursor, 0, BYTES_PER_PAGE); + + WMR_MEMCPY(pabCursor, &stFTLStatistics, sizeof(stFTLStatistics)); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_STATISTICS, pabCursor, &dwStatBuffSize); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_FILSTATISTICS, pabCursor, &dwStatBuffSize); + + // mark the statistics version + WMR_MEMCPY(pabVersion, &dwStatVersion, sizeof(UInt32)); + return TRUE32; +} +#endif //ifndef AND_READONLY + +static BOOL32 _FTLSetStatisticsFromCxt(UInt8 * pabData) +{ + UInt32 dwStatBuffSize; + Buffer *pBuff = BUF_Get(BUF_MAIN_AND_SPARE); + UInt8 *pabCursor; + + if (!pBuff) + { + debug(ERROR, "BUF_Get failed in _FTLSetStatisticsFromCxt!\n"); + return FALSE32; + } + + pabCursor = pabData; + + _UpdateStatisticsCounters(pabCursor, &stFTLStatistics, sizeof(FTLStatistics)); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_STATISTICS, pBuff->pData, &dwStatBuffSize); + _UpdateStatisticsCounters(pabCursor, pBuff->pData, dwStatBuffSize); + pabCursor += AND_STATISTICS_SIZE_PER_LAYER; + VFL_SetStruct(AND_STRUCT_VFL_STATISTICS, pBuff->pData, dwStatBuffSize); + + dwStatBuffSize = AND_STATISTICS_SIZE_PER_LAYER; + VFL_GetStruct(AND_STRUCT_VFL_FILSTATISTICS, pBuff->pData, &dwStatBuffSize); + _UpdateStatisticsCounters(pabCursor, pBuff->pData, dwStatBuffSize); + VFL_SetStruct(AND_STRUCT_VFL_FILSTATISTICS, pBuff->pData, dwStatBuffSize); + + BUF_Release(pBuff); + return TRUE32; +} + +#endif + +static UInt32 _getMinorVersion(void) +{ + return kYaftlMinorVersion; +} + +#ifndef AND_READONLY +// This function is stateless. Don't use stFTLDeviceInfo +static UInt32 yaftl_ConvertUserMBtoFTLSuperblocks(VFLFunctions *vfl, UInt32 user_mb) +{ + UInt32 ftl_virtual_blocks; + const UInt32 page_size = vfl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + const UInt32 pages_per_vb = vfl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + const UInt32 requested_pages = (user_mb * 1024) / (page_size / 1024); + + ftl_virtual_blocks = ((((requested_pages * 100) / DEFAULT_EXPO_RATIO)) / pages_per_vb) + FTL_CXT_SECTION_SIZE + DEFAULT_INDEX_CACHE_SIZE + 1; + + return ftl_virtual_blocks; +} +#endif //!AND_READONLY + +#if NAND_PPN +/*****************************************************************************/ +/* */ +/* NAME */ +/* YAFTL_PPN_Register */ +/* DESCRIPTION */ +/* register YAFTL access functions */ +/* */ +/*****************************************************************************/ +static FTLFunctions _yaftl_functions = +{ + .Init = YAFTL_Init, + .Open = YAFTL_Open, + + .Read = YAFTL_Read, + .Close = YAFTL_Close, + .GetStruct = YAFTL_GetStruct, + .GetMinorVersion = _getMinorVersion, + +#ifndef AND_READONLY + .ConvertUserMBtoFTLSuperblocks = yaftl_ConvertUserMBtoFTLSuperblocks, + .Write = YAFTL_Write, + .Unmap = YAFTL_Unmap, + .Format = YAFTL_Format, + .WearLevel = YAFTL_WearLevel, + .GarbageCollect = YAFTL_GarbageCollect, + .ShutdownNotify = YAFTL_ShutdownNotify, + .WriteStats = YAFTL_WriteStats, +#endif +}; + +FTLFunctions *YAFTL_PPN_Register(void) +{ + return &_yaftl_functions; +} + +#elif NAND_RAW + +/*****************************************************************************/ +/* */ +/* NAME */ +/* registerYAFTL */ +/* DESCRIPTION */ +/* register YAFTL access functions */ +/* */ +/*****************************************************************************/ + +void YAFTL_Register(FTLFunctions * pFTLFunctions) +{ + pFTLFunctions->Init = YAFTL_Init; + pFTLFunctions->Open = YAFTL_Open; + + pFTLFunctions->Read = YAFTL_Read; + pFTLFunctions->Close = YAFTL_Close; + pFTLFunctions->GetStruct = YAFTL_GetStruct; + pFTLFunctions->GetMinorVersion = _getMinorVersion; + +#ifndef AND_READONLY + pFTLFunctions->ConvertUserMBtoFTLSuperblocks = yaftl_ConvertUserMBtoFTLSuperblocks; + pFTLFunctions->Write = YAFTL_Write; + pFTLFunctions->Unmap = YAFTL_Unmap; + pFTLFunctions->Format = YAFTL_Format; + pFTLFunctions->WearLevel = YAFTL_WearLevel; + pFTLFunctions->GarbageCollect = YAFTL_GarbageCollect; + pFTLFunctions->ShutdownNotify = YAFTL_ShutdownNotify; + pFTLFunctions->WriteStats = YAFTL_WriteStats; +#endif +} +#else +#error PPN or raw? +#endif + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTLTypes.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTLTypes.h new file mode 100644 index 0000000..da0e119 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTLTypes.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _YAFTLTYPES_H_ +#define _YAFTLTYPES_H_ + +#include "yaFTL_whoami.h" +#include "VFLBuffer.h" +#include "yaFTL_Defines.h" +#include "L2V/L2V_Extern.h" +#include "WMRBuf.h" +#include "yaFTL_meta.h" + +typedef struct +{ + // Info generated by CalcGlobal + UInt16 wPagesPerVb; /* the count of pages per virtual block */ + UInt16 wUserVbTotal; /* the total number of data virtual block */ + UInt32 dwUserPagesTotal; /* the total number of data sector */ + UInt16 wBytesPerPage; /* bytes per page (main) */ + UInt16 wNumOfBanks; /* the number of banks */ + UInt16 wBytesPerPageMeta; /* bytes per page (meta) */ +} FTLWMRDeviceInfo; + +#define PAGES_PER_SUBLK (yaFTL_FTLDeviceInfo.wPagesPerVb) +#define NUM_BANKS (yaFTL_FTLDeviceInfo.wNumOfBanks) +#define FTL_AREA_SIZE (yaFTL_FTLDeviceInfo.wUserVbTotal) +#define USER_PAGES_TOTAL (yaFTL_FTLDeviceInfo.dwUserPagesTotal) +#define BYTES_PER_PAGE (yaFTL_FTLDeviceInfo.wBytesPerPage) +#define BYTES_PER_PAGE_META (yaFTL_FTLDeviceInfo.wBytesPerPageMeta) +#define NUM_BANKS (yaFTL_FTLDeviceInfo.wNumOfBanks) + +typedef struct +{ +// UInt32 serialCounter; // serial allocation counter that would be used for restore +// UInt16 validPagesNo; // Number of valid pages in block + UInt32 erasableCount; + UInt16 validPagesDNo; + UInt16 validPagesINo; + UInt16 pagesRead; + UInt8 status; + UInt8 eraseBeforeUse; + UInt8 pagesReadSubCounter; +} BlockEntry; + +// TOCEntry: pointer to cache index if the given index page is in the cache, or pointer to NAND if not. +// P.S.: not related to BlockTOCs. +typedef struct +{ + UInt32 indexPage; // location on the flash + UInt16 cacheIndex; // 0xff means not cached +} TOCEntry; + +typedef struct +{ + UInt32 *indexPage; // pointer to the page address array + UInt32 tocEntry; // index of the TOCEntry + UInt16 counter; // number of hits on this cache + UInt16 status; // free/occupied/dirty +} CacheIndexEntry; + +typedef struct +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwFTLWriteCnt; + UInt64 ddwFTLReadCnt; + UInt64 ddwDataGCCnt; + UInt64 ddwIndexGCCnt; + UInt64 ddwEmptyGCDataCnt; /* case there is data to copy */ + UInt64 ddwEmptyGCIndexCnt; /* case there is data to copy */ + UInt64 ddwValidDataPages; + UInt64 ddwValidIndexPages; + UInt64 ddwFreeBlks; + UInt64 ddwFTLRestoreCnt; + UInt64 ddwReadDisturbHandleCall; + UInt64 ddwWearLevelCnt; + UInt64 ddwFlushCnt; + UInt64 ddwRefreshCnt; + UInt64 ddwRead[8]; + UInt64 ddwReadOver8; + UInt64 ddwWrite[8]; + UInt64 ddwWriteOver8; + UInt64 ddwNodesFree; + UInt64 ddwNodesTotal; +} FTLStatistics; + +#define FTL_STATISTICS_DESCREPTION { \ + "ddwPagesWrittenCnt", \ + "ddwPagesReadCnt", \ + "ddwFTLWriteCnt", \ + "ddwFTLReadCnt", \ + "ddwDataGCCnt", \ + "ddwIndexGCCnt", \ + "ddwEmptyGCDataCnt", \ + "ddwEmptyGCIndexCnt", \ + "ddwValidDataPages", \ + "ddwValidIndexPages", \ + "ddwFreeBlks", \ + "ddwFTLRestoreCnt", \ + "ddwReadDisturbHandleCall", \ + "ddwWearLevelCnt", \ + "ddwFlushCnt", \ + "ddwRefreshCnt", \ + "ddwRead1", \ + "ddwRead2", \ + "ddwRead3", \ + "ddwRead4", \ + "ddwRead5", \ + "ddwRead6", \ + "ddwRead7", \ + "ddwRead8", \ + "ddwReadOver8", \ + "ddwWrite1", \ + "ddwWrite2", \ + "ddwWrite3", \ + "ddwWrite4", \ + "ddwWrite5", \ + "ddwWrite6", \ + "ddwWrite7", \ + "ddwWrite8", \ + "ddwWriteOver8", \ + "ddwNodesFree", \ + "ddwNodesTotal", \ +} + +#define GCFIFO_DEPTH 16 +typedef struct +{ + UInt32 block[GCFIFO_DEPTH + 1]; + UInt32 head, tail; // head==tail means it is empty +} GC_Fifo_t; + +typedef enum + { + GCD_IDLE, + GCD_EVICT, + GCD_ERASE, + GCD_FIXINDEX_RETRY, + GCD_FIXDATA_RETRY, + } GCDState; + + +typedef struct +{ + // In: + UInt32 in_block; + + // Work FIFO for error handling + GC_Fifo_t workFifo; + + // Choose out: + UInt32 chosenBlock; + UInt32 chosenValid; + UInt32 chosenErases; + + // Buffers: + UInt32 outstandingAllocs; + Buffer *tmpB1, *tmpB2, *tmpB3; + UInt32 *TOCbuff; + UInt8 *pageBuffer; + + // GC zone: + UInt32 *vpns; + UInt8 *zone; + PageMeta_t *meta; + UInt32 curZoneSize; + UInt32 ueccCounter; + + // State: + GCDState state; + UInt32 curPage; + UInt32 pagesRange; + UInt32 pagesCopied; + Int32 gcDataAdjust; // only meaningful for data GC + + L2V_SearchCtx_t read_c; // Search context for GC translation +} GC_Ctx_t; + +#define ERASE_NOW_LIST_SIZE 5 + +typedef struct +{ + WMR_BufZone_t BufZone; // Buffer zone allocators + WMR_BufZone_t BufZone_IndexCache; // ... + UInt16 controlPageNo, indexPageRatio; /* TOC of each block contains Lpa for each page written to block */ + UInt32 indexSize; /* index size in blocks */ + UInt32 dataSize; + UInt32 logicalPartitionSize; /* partititon size in pages exposed to file system */ + UInt16 TOCtableEntriesNo; /* number of entries in index TOC table */ + + UInt16 freeCachePages; + UInt16 erasedBlockCount; + #ifndef AND_READONLY + UInt16 nextFreeCachePage; + UInt64 cxtAllocation; + UInt32 currentCXTIndex, FTLRestoreCnt; + UInt8 cxtEraseCounter; + UInt32 currentDBlockAllocationNo; + UInt8 cxtValid; + UInt8 formatWasCalled; + BOOL32 readLimit; + UInt16 eraseNowList[ERASE_NOW_LIST_SIZE]; + #endif + + struct + { + struct + { + UInt32 block; + UInt32 *TOC; + UInt16 nextPage; + WeaveSeq_t minWeaveSeq; + } data; + struct + { + UInt32 block; + UInt32 *TOC; + UInt16 nextPage; + WeaveSeq_t minWeaveSeq; + } index; + + WeaveSeq_t weaveSeq; + UInt32 lastBlock; + } wrState; + + struct + { + UInt32 size; + UInt32 curAge; + UInt32 free; + UInt32 isData; + UInt32 **BTOC; + UInt32 *sb; + Int32 *age; + WMR_BufZone_t BufZone; // Buffer zone allocator + + // For srcVpn: + UInt32 srcSize; + UInt32 curSrc; + UInt32 *srcSb; + UInt32 **srcVpn; + UInt32 isLocked; + } BTOCcache; + + struct + { + struct + { + UInt32 allocdBlocks; + Int32 freeBlocks; + UInt32 validPages; + } data; + struct + { + UInt32 allocdBlocks; + Int32 freeBlocks; + UInt32 validPages; + } index; + UInt32 freeBlocks; + BOOL32 distCheckable; + } seaState; + + struct + { + UInt32 blocksSince; + BOOL32 pointOfNoReturn; + } wearLevel; + + struct + { + UInt32 pagesWritten; + UInt32 erases; + } periodicCxt; + + TOCEntry *tocArray; /* [TOC_SIZE] Table of content that contains location of index pages in flash and index cache */ + CacheIndexEntry *indexCache; /* [INDEX_CACHE_SIZE] cached index pages */ + BlockEntry *blockArray; /* [YAFTL_NO_OF_BLOCKS] block information */ + UInt32 *restoreTOC; // blockTOC for restore + + PageMeta_t *meta_restoreIdx; + PageMeta_t *meta_restoreData; + PageMeta_t *meta_readCxt; + PageMeta_t *meta_quickRestore; + PageMeta_t *meta_invalidateCxt; + PageMeta_t *meta_writeCxt; + PageMeta_t *meta_restoreMountErase; + PageMeta_t *meta_restoreMount; + PageMeta_t *meta_clearEntryInCache; + PageMeta_t *meta_writeBTOC; + PageMeta_t *meta_indexLoadDirty; + PageMeta_t *meta_getStats; + PageMeta_t *meta_GetBlockTOC; + PageMeta_t *meta_IsDataPageCurrent; + PageMeta_t *meta_WriteZoneData; + + UInt8 *quickRestore_tBuff; + UInt32 *tmpReadBuffer; // = NULL; + UInt32 readBufferIndex; // = 0xffffffff; + PageMeta_t *writeMdPtr; // = NULL; + UInt32 *multiReadvpN; // = NULL; + PageMeta_t *readMdPtr; // = NULL; + PageMeta_t *singleMdPtr; + UInt32 cxtSize, cxtSizeTOC, cxtSizeBlockStatus, cxtSizeBlockRead, + cxtSizeBlockErase, cxtSizeValidPagesD, cxtSizeValidPagesI; + UInt32 currentCxtVpn; // = 0xffffffff; + UInt16 cxtTable[FTL_CXT_SECTION_SIZE]; + UInt32 maxEraseCount, minEraseCount; // = 0 + + UInt32 indexCacheSize; // = DEFAULT_INDEX_CACHE_SIZE; + UInt8 exportedRatio; // = DEFAULT_EXPO_RATIO; + + // Garbage collection structures + struct + { + UInt32 zoneSize; + GC_Ctx_t data; + GC_Ctx_t index; + WMR_BufZone_t BufZone; // Buffer zone allocator + PageMeta_t *meta_buf; + } gc; + + // Read search context + L2V_SearchCtx_t read_c; +} yaFTL_t; + +#endif /* _YAFTLTYPES_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.c b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.c new file mode 100644 index 0000000..4283472 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "yaFTL_whoami.h" +#include "WMRConfig.h" +#include "yaFTL_BTOC.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTL.h" +#include "yaFTLTypes.h" +#include "yaFTL_Defines.h" + +// Extern context struct +extern yaFTL_t yaFTL; +extern FTLWMRDeviceInfo yaFTL_FTLDeviceInfo; +extern Int32 _readPage(UInt32 vpn, UInt8 *pageData, PageMeta_t *mdPtr, BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 scrubOnUECC); +extern ANDStatus invalidateCXT(void); + +BOOL32 BTOC_Init() +{ + UInt32 i; + + yaFTL.BTOCcache.size = YAFTL_BTOCCACHE_SIZE_PER * 2; + WMR_ASSERT(yaFTL.BTOCcache.size <= 32); + yaFTL.BTOCcache.srcSize = YAFTL_BTOCCACHE_SRCSIZE; + yaFTL.BTOCcache.curSrc = yaFTL.BTOCcache.srcSize-1; + + yaFTL.BTOCcache.curAge = 0; + yaFTL.BTOCcache.age = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.age) * yaFTL.BTOCcache.size); + yaFTL.BTOCcache.sb = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.sb) * yaFTL.BTOCcache.size); + yaFTL.BTOCcache.BTOC = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.BTOC) * yaFTL.BTOCcache.size); + yaFTL.BTOCcache.srcVpn = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.srcVpn) * yaFTL.BTOCcache.srcSize); + yaFTL.BTOCcache.srcSb = WMR_MALLOC(sizeof(*yaFTL.BTOCcache.srcSb) * yaFTL.BTOCcache.srcSize); + yaFTL.BTOCcache.isLocked = 0; + + // Check for allocation failure + if ((NULL == yaFTL.BTOCcache.age) || (NULL == yaFTL.BTOCcache.sb) || (NULL == yaFTL.BTOCcache.BTOC) + || (NULL == yaFTL.BTOCcache.srcVpn) || (NULL == yaFTL.BTOCcache.srcSb)) + { + return FALSE32; + } + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + yaFTL.BTOCcache.sb[i] = 0xffffffff; + } + + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + yaFTL.BTOCcache.srcSb[i] = 0xffffffff; + yaFTL.BTOCcache.srcVpn[i] = WMR_MALLOC(sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + WMR_MEMSET(yaFTL.BTOCcache.srcVpn[i], 0xff, sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + } + + yaFTL.BTOCcache.free = (1 << yaFTL.BTOCcache.size) - 1; + yaFTL.BTOCcache.isData = (1 << YAFTL_BTOCCACHE_SIZE_PER) - 1; + + // Allocate buffers + WMR_BufZone_Init(&yaFTL.BTOCcache.BufZone); + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + yaFTL.BTOCcache.BTOC[i] = (UInt32*)WMR_Buf_Alloc_ForDMA(&yaFTL.BTOCcache.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + } + + if (!WMR_BufZone_FinishedAllocs(&yaFTL.BTOCcache.BufZone)) { + return FALSE32; + } + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + WMR_BufZone_Rebase(&yaFTL.BTOCcache.BufZone, (void**)&yaFTL.BTOCcache.BTOC[i]); + } + + WMR_BufZone_FinishedRebases(&yaFTL.BTOCcache.BufZone); + + return TRUE32; +} + +void BTOC_Close() +{ + UInt32 i; + + WMR_BufZone_Free(&yaFTL.BTOCcache.BufZone); + + if (NULL != yaFTL.BTOCcache.age) + { + WMR_FREE(yaFTL.BTOCcache.age, sizeof(*yaFTL.BTOCcache.age) * yaFTL.BTOCcache.size); + } + if (NULL != yaFTL.BTOCcache.sb) + { + WMR_FREE(yaFTL.BTOCcache.sb, sizeof(*yaFTL.BTOCcache.sb) * yaFTL.BTOCcache.size); + } + if (NULL != yaFTL.BTOCcache.BTOC) + { + WMR_FREE(yaFTL.BTOCcache.BTOC, sizeof(*yaFTL.BTOCcache.BTOC) * yaFTL.BTOCcache.size); + } + // Free srcVpn memory + if (NULL != yaFTL.BTOCcache.srcSb) + { + WMR_FREE(yaFTL.BTOCcache.srcSb, sizeof(*yaFTL.BTOCcache.srcSb) * yaFTL.BTOCcache.srcSize); + } + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + WMR_FREE(yaFTL.BTOCcache.srcVpn[i], sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + } + if (NULL != yaFTL.BTOCcache.srcVpn) + { + WMR_FREE(yaFTL.BTOCcache.srcVpn, sizeof(*yaFTL.BTOCcache.srcVpn) * yaFTL.BTOCcache.srcSize); + } + + yaFTL.BTOCcache.age = NULL; + yaFTL.BTOCcache.sb = NULL; + yaFTL.BTOCcache.BTOC = NULL; + yaFTL.BTOCcache.srcSb = NULL; + yaFTL.BTOCcache.srcVpn = NULL; + + yaFTL.BTOCcache.size = 0; + + yaFTL.BTOCcache.srcSize = 0; +} + +void BTOC_BootFixup() +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if (0xfffffffd == yaFTL.BTOCcache.sb[i]) + { + yaFTL.BTOCcache.sb[i] = yaFTL.wrState.data.block; + } + if (0xfffffffe == yaFTL.BTOCcache.sb[i]) + { + yaFTL.BTOCcache.sb[i] = yaFTL.wrState.index.block; + } + } +} + +UInt32 *BTOC_Alloc(UInt32 sb, BOOL32 isData) +{ + UInt32 i, minIdx, isData32 = (isData ? 1 : 0); + Int32 minAge; + + // Get a srcVpn + yaFTL.BTOCcache.curSrc = (yaFTL.BTOCcache.curSrc + 1) % yaFTL.BTOCcache.srcSize; + yaFTL.BTOCcache.srcSb[yaFTL.BTOCcache.curSrc] = sb; + WMR_MEMSET(yaFTL.BTOCcache.srcVpn[yaFTL.BTOCcache.curSrc], 0xff, sizeof(**yaFTL.BTOCcache.srcVpn) * PAGES_PER_SUBLK); + + // Get a BTOC + yaFTL.BTOCcache.curAge++; + + minAge = 0x7fffffff; + minIdx = 0xffffffff; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if (((yaFTL.BTOCcache.isData & (1 << i)) == (isData32 << i)) + && (yaFTL.BTOCcache.free & (1 << i)) + && (yaFTL.BTOCcache.age[i] < minAge) + && ((yaFTL.BTOCcache.isLocked & (1 << i)) == 0)) + { + minAge = yaFTL.BTOCcache.age[i]; + minIdx = i; + } + } + + if (0xffffffff != minIdx) { + yaFTL.BTOCcache.free &= ~(1 << minIdx); + yaFTL.BTOCcache.sb[minIdx] = sb; + yaFTL.BTOCcache.age[minIdx] = yaFTL.BTOCcache.curAge; + return yaFTL.BTOCcache.BTOC[minIdx]; + } +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't allocate a BTOC"); +#endif + return NULL; +} + +UInt32 BTOC_GetSrc(UInt32 destVpn) +{ + UInt32 i, sb, idx; + + sb = destVpn / PAGES_PER_SUBLK; + idx = destVpn % PAGES_PER_SUBLK; + + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + if (sb == yaFTL.BTOCcache.srcSb[i]) { + return yaFTL.BTOCcache.srcVpn[i][idx]; + } + } + + return 0xffffffff; +} + +void BTOC_SetSrc(UInt32 destVpn, UInt32 srcVpn) +{ + UInt32 i, sb, idx; + + sb = destVpn / PAGES_PER_SUBLK; + idx = destVpn % PAGES_PER_SUBLK; + + for (i = 0; i < yaFTL.BTOCcache.srcSize; i++) + { + if (sb == yaFTL.BTOCcache.srcSb[i]) { + yaFTL.BTOCcache.srcVpn[i][idx] = srcVpn; + } + } +} + +void BTOC_Dealloc(UInt32 *BTOC) +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if (BTOC == yaFTL.BTOCcache.BTOC[i]) + { + yaFTL.BTOCcache.free |= (1 << i); + return; + } + } +#ifndef AND_READONLY + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't deallocate BTOC: 0x%x", BTOC); +#endif +} + +UInt32 *BTOC_Search(UInt32 sb, BOOL32 isData) +{ + UInt32 i, isData32 = (isData ? 1 : 0); + Int32 maxAge = -1; + UInt32 *best = NULL; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if ((yaFTL.BTOCcache.sb[i] == sb) && (yaFTL.BTOCcache.age[i] > maxAge) && ((yaFTL.BTOCcache.isData & (1 << i)) == (isData32 << i))) + { + maxAge = yaFTL.BTOCcache.age[i]; + best = yaFTL.BTOCcache.BTOC[i]; + } + } + + return best; +} + +void BTOC_Lock(UInt32 sb) +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if ((yaFTL.BTOCcache.sb[i] == sb) && ((yaFTL.BTOCcache.free & (1 << i)) == 0)) + { + yaFTL.BTOCcache.isLocked |= (1 << i); + break; + } + } + +} + +void BTOC_Unlock(UInt32 sb) +{ + UInt32 i; + + for (i = 0; i < yaFTL.BTOCcache.size; i++) + { + if ((yaFTL.BTOCcache.sb[i] == sb) && (yaFTL.BTOCcache.isLocked & (1 << i))) + { + yaFTL.BTOCcache.isLocked &= ~(1 << i); + break; + } + } + +} + +ANDStatus BTOC_Read(UInt32 vpn, UInt32 *bTOC, PageMeta_t *mdPtr, BOOL32 val, BOOL32 scrubOnUECC, UInt32 upperBound) +{ + UInt16 i; + ANDStatus status = FTL_CRITICAL_ERROR; + + for (i = 0; i < yaFTL.controlPageNo; i++) + { + status = _readPage(vpn + i, ((UInt8 *)bTOC) + (i * BYTES_PER_PAGE), mdPtr, val, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + break; + } + } + if (status == FTL_SUCCESS) + { + UInt32 * tmpPtr = (UInt32 *)bTOC; + for(i = 0; i < ((yaFTL.controlPageNo * BYTES_PER_PAGE) >> 2);i++) + if(tmpPtr[i] >= upperBound) + { + tmpPtr[i] = 0xffffffff; + } + } + return status; +} + + +void BTOC_SetAll(UInt32 *bTOC, UInt8 value) +{ + WMR_MEMSET(bTOC, value, yaFTL.controlPageNo * BYTES_PER_PAGE); +} + + +void BTOC_Copy(UInt32 *left, UInt32 *right, UInt32 upperBound) +{ + UInt16 i; + for(i = 0; i < ((yaFTL.controlPageNo * BYTES_PER_PAGE) >> 2);i++) + if(right[i] >= upperBound) + { + left[i] = 0xffffffff; + } + else + { + left[i] = right[i]; + } +} + + +UInt32 BTOC_Get(UInt32 *bTOC, UInt32 offset, UInt32 upperBound) +{ + if(bTOC[offset] >= upperBound) + { + return 0xffffffff; + } + else + { + return bTOC[offset]; + } +} + + +UInt32 BTOC_Set(UInt32 *bTOC, UInt32 offset, UInt32 val, UInt32 upperBound) +{ + if(val >= upperBound) + { + bTOC[offset] = 0xffffffff; + } + else + { + bTOC[offset] = val; + } + return val; +} + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.h new file mode 100644 index 0000000..41a2653 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_BTOC.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_BTOC_H__ +#define __YAFTL_BTOC_H__ + +// Includes +#include "yaFTL_whoami.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "yaFTLTypes.h" +#include "yaFTL_meta.h" + +// Defines and types declared elsewhere + +// Prototypes: + +// BTOC init/alloc/dealloc +extern BOOL32 BTOC_Init(void); +extern void BTOC_BootFixup(void); +extern void BTOC_Close(void); +extern UInt32 *BTOC_Alloc(UInt32 sb, BOOL32 isData); +extern void BTOC_Dealloc(UInt32 *BTOC); +extern UInt32 *BTOC_Search(UInt32 sb, BOOL32 isData); +extern void BTOC_Lock(UInt32 sb); +extern void BTOC_Unlock(UInt32 sb); + +// Read +extern ANDStatus BTOC_Read(UInt32 vpn, UInt32 *bTOC, PageMeta_t *mdPtr, BOOL32 val, BOOL32 scrubOnUECC, UInt32 upperBound); + +// Src for GC +extern void BTOC_SetSrc(UInt32 destVpn, UInt32 srcVpn); +extern UInt32 BTOC_GetSrc(UInt32 destVpn); + +// Getters/setters +extern void BTOC_SetAll(UInt32 *bTOC, UInt8 value); +extern UInt32 BTOC_Get(UInt32 *bTOC, UInt32 offset, UInt32 upperBound); +extern UInt32 BTOC_Set(UInt32 *bTOC, UInt32 offset, UInt32 val, UInt32 upperBound); + +// Copy +extern void BTOC_Copy(UInt32 *left, UInt32 *right, UInt32 upperBound); + +#endif // ----- #ifndef __YAFTL_BTOC_H__ diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_Defines.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_Defines.h new file mode 100644 index 0000000..91b91c5 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_Defines.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_DEFINES_H__ +#define __YAFTL_DEFINES_H__ + + +#define YAFTLDBG_INIT (1 << 0) +#define YAFTLDBG_FORMAT (1 << 1) +#define YAFTLDBG_READ (1 << 2) +#define YAFTLDBG_WRITE (1 << 3) +#define YAFTLDBG_ERASE (1 << 4) +#define YAFTLDBG_MISC (1 << 5) +#define YAFTLDBG_ERROR (1 << 6) +#define YAFTLDBG_OPEN (1 << 7) +#define YAFTLDBG_INFO (1 << 8) + +//#define YAFTL_DEBUG (YAFTLDBG_INIT | YAFTLDBG_ERROR | YAFTLDBG_INFO) +#define YAFTL_DEBUG (YAFTLDBG_ERROR) +#ifdef YAFTL_DEBUG +#define YAFTL_ENABLE_DEBUG_PRINT (0xff) + +# define debug(fac, fmt, args ...) \ + do { \ + if (YAFTLDBG_ ## fac & YAFTL_DEBUG & YAFTL_ENABLE_DEBUG_PRINT) { \ + _WMR_PRINT("yaFTL::%s(l:%d): " fmt "\n", __FUNCTION__, __LINE__, ## args); \ + } \ + } while (0) +#else +# define debug(fac, fmt, args ...) do { } while (0) +#endif + +#define FREE_BLK_TRH (5) /* number of units we require to be avaiable at any time */ +#define INDEX_AREA (1) /* block belongs to Index area */ +#define DATA_AREA (2) /* block belongs to data area */ +#define FREE_I_BLOCK_TRS (2) /* minimum free blocks within index area */ +#define DEFAULT_INDEX_CACHE_SIZE (10) /* index cached pages */ +#define INDEX_BLOCKS_RATIO (3) /* ratio of index area in flash to required index area by flash size */ +#define DEFAULT_EXPO_RATIO (99) /* percentage of data area exposed to file system */ +#define CXT_ERASE_LIMIT (30) + + +#define IC_DIRTY_PAGE 1 +#define IC_BUSY_PAGE 2 +#define FREE_CACHE_PAGE 0xffff + +#define BLOCK_FREE (0xFF) /* block marked as free */ +#define BLOCK_ALLOCATED (1) /* block marked as allocated for data area */ +#define BLOCK_CURRENT (4) /* block marked as current in data area */ + +#define BLOCK_GC (8) /* block in data area goes through GC process */ + +#define BLOCK_I_FREE (0xFF) /* block marked as free */ +#define BLOCK_I_CURRENT (32) /* block marked as current index block */ +#define BLOCK_I_ALLOCATED (64) /* block marked as idex block */ +#define BLOCK_I_GC (128) /* block in index area goes through GC process */ +#define BLOCK_TO_BE_ERASED (0x1) /* erase block before use . make sure the block is not erased before current block is closed */ +#define BLOCK_TO_BE_ERASED_ALIGNED_DATA (0x2) /* erase block before use . make sure the block is not erased before current block is closed */ +#define BLOCK_TO_BE_ERASED_ALIGNED_INDEX (0x4) /* erase block before use . make sure the block is not erased before current block is closed */ +#define BLOCK_READ_SCATTER (0x8) /* mark a block as being used in multi-read operation */ +#define BLOCK_TO_BE_MOVED (0x80) /* use it as an idication that block is to be refreshed after full mount is complete due to UECCs */ + +#define ERASE_IDLE_LIMIT (5) /* number of free blocks to be erased in idle time */ + +#define BLOCK_CTX_CNTR (2) /* block marked as CXT */ +#define BLOCK_CTX_CURRENT (16) /* block marked as current CXT */ +#define INDEX_PAGE_MARK (0x80000000) /* to be defined */ + +#define YAFTL_READ_DISTURB_LIMIT YAFTL_RC_THRESHOLD /* read disturb limit */ + +#define MIN_RESTORE_BUFFER (0x10000) +#define MAX_RESTORE_BUFFER (0x200000) +#define YAFTL_WEARLEVEL_PERIOD 30 +#define ERASE_COUNT_GAP_LIMIT 100 +#define ERASE_COUNT_GAP_UPPER_LIMIT 500 +#define STATIC_WEARLEVEL_TRIGGER 1000 +#define NAND_MOUNT_INDEX_SIZE 1000 +#define YAFTL_WRITE_MAX_STRIPES 32 +#define YAFTL_INDEX_CACHE_COUNTER_LIMIT 0xFFFF +#define PAGES_READ_SUB_COUNTER_LIMIT YAFTL_RC_MULTIPLIER + +// GCZONE_DOUBLEUPTO defines the point up to which we will multiply banks to. +// It is similar to setting a minimum of 16, but works with non-pow-2 configs. +#define GCZONE_DOUBLEUPTO 16 +#define YAFTL_GC_RATIO_SCALAR 4 + +// Maximum number of TOC pages/block to support +#define MAX_TOC_PAGES 4 +#define YAFTL_BTOCCACHE_SIZE_PER 2 +#define YAFTL_BTOCCACHE_SRCSIZE 2 + +// make the function pointers in vfl struct look like the old vfl functions +#ifndef AND_READONLY +#define VFL_Format (yaFTL_VFLFunctions.Format) +#define VFL_Write (yaFTL_VFLFunctions.WriteSinglePage) +#define VFL_Erase (yaFTL_VFLFunctions.Erase) +#define VFL_ChangeFTLCxtVbn (yaFTL_VFLFunctions.ChangeFTLCxtVbn) +#define VFL_WriteMultiplePagesInVb (yaFTL_VFLFunctions.WriteMultiplePagesInVb) +#endif // ! AND_READONLY +#define VFL_Init (yaFTL_VFLFunctions.Init) +#define VFL_Open (yaFTL_VFLFunctions.Open) +#define VFL_Close (yaFTL_VFLFunctions.Close) +#define VFL_ReadMultiplePagesInVb (yaFTL_VFLFunctions.ReadMultiplePagesInVb) +#define VFL_ReadScatteredPagesInVb (yaFTL_VFLFunctions.ReadScatteredPagesInVb) +#define VFL_Read (yaFTL_VFLFunctions.ReadSinglePage) +#define VFL_GetFTLCxtVbn (yaFTL_VFLFunctions.GetFTLCxtVbn) +//#define VFL_GetAddress (yaFTL_VFLFunctions.GetAddress) +#define VFL_GetDeviceInfo (yaFTL_VFLFunctions.GetDeviceInfo) +#define VFL_GetStruct (yaFTL_VFLFunctions.GetStruct) +#define VFL_SetStruct (yaFTL_VFLFunctions.SetStruct) + +#endif // ----- #ifndef _YAFTL_DEFINES_H__INC ----- + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.c b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.c new file mode 100644 index 0000000..1d4b52e --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.c @@ -0,0 +1,1716 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define AND_TRACE_LAYER FTL + +#include "yaFTL_whoami.h" +#include "yaFTL_gc.h" +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTL.h" +#include "yaFTLTypes.h" +#include "yaFTL_Defines.h" +#include "yaFTL_BTOC.h" +#include "L2V/L2V_Extern.h" +#include "WMRFeatures.h" +#ifndef ENABLE_L2V_TREE +#error ENABLE_L2V_TREE must be set to 0 or 1 in WMRFeatures.h +#endif + +#ifndef AND_READONLY + +// Prototypes +ANDStatus YAFTL_GC_Index(UInt32 block, BOOL32 scrubOnUECC); +ANDStatus YAFTL_GC_Data(UInt32 block, BOOL32 scrubOnUECC); + +static ANDStatus GCMachine_Data(Int32 writeSize, BOOL32 scrubOnUECC); +static void ChooseIndexSB(void); +static void ChooseDataSB(void); +static ANDStatus EraseIndex(UInt32 block); +static ANDStatus EraseData(UInt32 block); +static ANDStatus GetBlockTOC(GC_Ctx_t *c, BOOL32 srcubOnUECC, UInt32 upperBound, UInt32 *ueccCounter); +static void SanityCheckValid(GC_Ctx_t *c); +static ANDStatus EvictIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC); +static ANDStatus EvictData(UInt32 minAmount, BOOL32 scrubOnUECC); +static ANDStatus ReadZone(GC_Ctx_t *c, BOOL32 index, BOOL32 scrubOnUECC); +static ANDStatus WriteZoneData(GC_Ctx_t *c, BOOL32 scrubOnUECC); +static ANDStatus WriteZoneIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC); + +// Externs, from yAFTL.c: to be cleaned up into a common header/source +#ifdef AND_COLLECT_STATISTICS +extern FTLStatistics stFTLStatistics; +#endif +extern yaFTL_t yaFTL; +extern VFLFunctions yaFTL_VFLFunctions; +extern FTLWMRDeviceInfo yaFTL_FTLDeviceInfo; +extern UInt16 findFreeCacheEntry(void); +extern UInt16 clearEntryInCache(UInt8 flag, UInt16 candidate, UInt8 flush); +extern UInt32 allocateBlock(UInt32 blockNo, UInt8 flag, UInt8 type); +extern Int32 _readPage(UInt32 vpn, UInt8 *pageData, + PageMeta_t * pMeta, + BOOL32 bInternalOp, BOOL32 boolCleanCheck, BOOL32 bMarkECCForScrub); +extern BOOL32 _readMultiPages(UInt32 * padwVpn, + UInt16 wNumPagesToRead, UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 bInternalOp, BOOL32 scrubOnUECC); +extern BOOL32 _writeMultiPages(UInt16 vbn, UInt16 pageOffset, + UInt16 wNumPagesToWrite, UInt8 *pageData, + PageMeta_t *mdPtr, + BOOL32 bInternalOp); +extern ANDStatus writeCurrentBlockTOC(UInt8 type); +extern UInt16 createTOClookUP(UInt32 *TOCarray, UInt16 *lookUParray, UInt16 arrayLn); +extern ANDStatus invalidateCXT(void); +extern BOOL32 isBlockInEraseNowList(UInt16 blockNo); +extern BOOL32 removeBlockFromEraseNowList(UInt16 blockNo); +extern BOOL32 addBlockToEraseNowList(UInt16 blockNo); + +// Defines +#define FREE_BLK_TRH_UPDATED 4 //FREE_BLK_TRH +#define FREE_BLK_GAP 2 +#define lowData(adjust) (((yaFTL.seaState.data.freeBlocks*PAGES_PER_SUBLK)+yaFTL.gc.data.gcDataAdjust) < (Int32)(((FREE_BLK_TRH_UPDATED + FREE_BLK_GAP) * PAGES_PER_SUBLK) + (adjust))) +#define dangerousData(adjust) ((((yaFTL.seaState.data.freeBlocks*PAGES_PER_SUBLK)+yaFTL.gc.data.gcDataAdjust) < (Int32)((FREE_BLK_TRH_UPDATED * PAGES_PER_SUBLK) + (adjust))) || ((yaFTL.seaState.data.allocdBlocks + FREE_BLK_TRH) > yaFTL.dataSize)) +#define dangerousIndex ((yaFTL.seaState.index.freeBlocks < (Int32)FREE_I_BLOCK_TRS) || ((yaFTL.seaState.index.allocdBlocks + FREE_I_BLOCK_TRS) > yaFTL.indexSize)) + +// Debug self-consistency checks +#define SELFCONSISTENCY_CHECKS 0 +#if SELFCONSISTENCY_CHECKS + +//SELFCONSISTENCY_CHECKS==1 +void CheckDataCounts(void) +{ + UInt32 i, sum = 0; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + sum += yaFTL.blockArray[i].validPagesDNo; + } + WMR_ASSERT(sum == yaFTL.seaState.data.validPages); +} + +//SELFCONSISTENCY_CHECKS==1 +static UInt32 ValidSnapshot[8192]; + +//SELFCONSISTENCY_CHECKS==1 +void SaveValids() +{ + UInt32 i; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + ValidSnapshot[i] = yaFTL.blockArray[i].validPagesDNo; + } +} + +//SELFCONSISTENCY_CHECKS==1 +void CheckValids() +{ + UInt32 i; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + WMR_ASSERT(ValidSnapshot[i] == yaFTL.blockArray[i].validPagesDNo); + } +} + +//SELFCONSISTENCY_CHECKS==1 +void CheckBlockDist() +{ + UInt32 i, D, I, free; + BOOL32 err = FALSE32; + + // Don't check during GC of power-on restore + if (!yaFTL.seaState.distCheckable) + return; + + D = I = free = 0; + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + switch (yaFTL.blockArray[i].status) + { + case BLOCK_ALLOCATED: + case BLOCK_CURRENT: + case BLOCK_GC: + D++; + break; + + case BLOCK_I_ALLOCATED: + case BLOCK_I_CURRENT: + I++; + break; + + case BLOCK_FREE: + free++; + break; + + case BLOCK_I_GC: + // Should never get here, since I_GC is monolithic and we should only call this routine before or after + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("BLOCK_I_GC in CheckBlockDist()"); + break; + } + } + + if (!((D == yaFTL.seaState.data.allocdBlocks) || (D == (yaFTL.seaState.data.allocdBlocks + 1)))) + { + WMR_PRINT(ERROR, "D err\n"); + err = TRUE32; + } + if (!((I == yaFTL.seaState.index.allocdBlocks) || (I == (yaFTL.seaState.index.allocdBlocks + 1)))) + { + WMR_PRINT(ERROR, "I err\n"); + err = TRUE32; + } + if ((free != (UInt32)(yaFTL.seaState.data.freeBlocks + yaFTL.seaState.index.freeBlocks)) || (free != yaFTL.seaState.freeBlocks)) + { + WMR_PRINT(ERROR, "Free err\n"); + err = TRUE32; + } + if (yaFTL.seaState.data.freeBlocks & 0x80000000) + { + WMR_PRINT(ERROR, "D underflow error\n"); + err = TRUE32; + } + if (yaFTL.seaState.index.freeBlocks & 0x80000000) + { + WMR_PRINT(ERROR, "I underflow error\n"); + err = TRUE32; + } + WMR_ASSERT(FALSE32 == err); +} + +#else +//SELFCONSISTENCY_CHECKS==0 +void CheckDataCounts(void) +{ +} +void SaveValids(void) +{ +} +void CheckValids(void) +{ +} +void CheckBlockDist(void) +{ +} +#endif + +BOOL32 WorkFifo_isEmpty(GC_Fifo_t *f) +{ + return f->tail == f->head; +} + +void WorkFifo_Enq(GC_Fifo_t *f, UInt32 block) +{ + UInt32 p; + p = f->head; + while (p != f->tail) + { + if (f->block[p] == block) + { + return; + } + + p++; + if (p > GCFIFO_DEPTH) + { + p = 0; + } + } + + f->block[f->tail] = block; + f->tail++; + if (f->tail > GCFIFO_DEPTH) + { + f->tail = 0; + } + WMR_ASSERT(f->tail != f->head); +} + +UInt32 WorkFifo_Deq(GC_Fifo_t *f) +{ + UInt32 ret; + + WMR_ASSERT(f->tail != f->head); + + ret = f->block[f->head]; + + f->head++; + if (f->head > GCFIFO_DEPTH) + { + f->head = 0; + } + + return ret; +} + +UInt32 YAFTL_GC_Data_Deq_sb(UInt32 block) +{ + UInt32 p; + UInt32 nRet = -1; + GC_Fifo_t *f = &yaFTL.gc.data.workFifo; + + p = f->head; + + while (p != f->tail) + { + if (f->block[p] == block) + { + nRet = f->block[p]; + break; + } + + p++; + if (p > GCFIFO_DEPTH) + { + p = 0; + } + } + + if(p == f->tail) + return nRet; + + while (p != f->tail) + { + if(p == GCFIFO_DEPTH) + { + f->block[p]=f->block[0]; + p=0; + } + else + { + f->block[p]=f->block[p+1]; + p++; + } + } + + if(f->tail == 0) + f->tail = GCFIFO_DEPTH; + else + f->tail--; + + return nRet; +} + +// Functions + +ANDStatus YAFTL_GC_Init() +{ +#if ENABLE_L2V_TREE + L2V_Search_Init(&yaFTL.gc.data.read_c); +#endif // ENABLE_L2V_TREE + + // GC Zone size should be a multiple of banks, up to 16 (or whatever banks is naturally). + // This logic guarantees low-bank configs will have higher performance, while making sure + // high-bank configs don't occupy too much memory. + // It is similar to setting a minimum of 16, but works with non-pow-2 configs. + yaFTL.gc.zoneSize = NUM_BANKS; + while (yaFTL.gc.zoneSize < GCZONE_DOUBLEUPTO) { + yaFTL.gc.zoneSize <<= 1; + } + + yaFTL.gc.data.state = GCD_IDLE; + yaFTL.gc.data.in_block = 0xffffffff; + yaFTL.gc.index.in_block = 0xffffffff; + + WMR_BufZone_Init(&yaFTL.gc.BufZone); + yaFTL.gc.data.TOCbuff = (UInt32*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.gc.data.pageBuffer = (UInt8 *)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE); + yaFTL.gc.index.TOCbuff = (UInt32*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.controlPageNo * BYTES_PER_PAGE); + yaFTL.gc.index.pageBuffer = (UInt8 *)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE); + yaFTL.gc.meta_buf = (PageMeta_t*)WMR_Buf_Alloc(&yaFTL.gc.BufZone, sizeof(PageMeta_t)); + yaFTL.gc.data.zone = (UInt8*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE * yaFTL.gc.zoneSize); + yaFTL.gc.index.zone = (UInt8*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, BYTES_PER_PAGE * yaFTL.gc.zoneSize); + yaFTL.gc.data.meta = (PageMeta_t*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.gc.zoneSize * sizeof(PageMeta_t)); + yaFTL.gc.index.meta = (PageMeta_t*)WMR_Buf_Alloc_ForDMA(&yaFTL.gc.BufZone, yaFTL.gc.zoneSize * sizeof(PageMeta_t)); + + if (!WMR_BufZone_FinishedAllocs(&yaFTL.gc.BufZone)) { + return FTL_CRITICAL_ERROR; + } + + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.TOCbuff); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.pageBuffer); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.TOCbuff); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.pageBuffer); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.meta_buf); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.zone); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.zone); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.data.meta); + WMR_BufZone_Rebase(&yaFTL.gc.BufZone, (void**)&yaFTL.gc.index.meta); + WMR_BufZone_FinishedRebases(&yaFTL.gc.BufZone); + + yaFTL.gc.data.vpns = (UInt32*) WMR_MALLOC(yaFTL.gc.zoneSize * sizeof(UInt32)); + yaFTL.gc.index.vpns = (UInt32*) WMR_MALLOC(yaFTL.gc.zoneSize * sizeof(UInt32)); + + if ((NULL == yaFTL.gc.data.TOCbuff) || (NULL == yaFTL.gc.data.pageBuffer) + || (NULL == yaFTL.gc.index.TOCbuff) || (NULL == yaFTL.gc.index.pageBuffer) + || (NULL == yaFTL.gc.meta_buf) + || (NULL == yaFTL.gc.data.zone) || (NULL == yaFTL.gc.index.zone) + || (NULL == yaFTL.gc.data.vpns) || (NULL == yaFTL.gc.data.meta) + || (NULL == yaFTL.gc.index.vpns) || (NULL == yaFTL.gc.index.meta) + ) + { + return FTL_CRITICAL_ERROR; + } + + return FTL_SUCCESS; +} + +void YAFTL_GC_Close() +{ + WMR_BufZone_Free(&yaFTL.gc.BufZone); + + yaFTL.gc.data.TOCbuff = NULL; + yaFTL.gc.data.pageBuffer = NULL; + yaFTL.gc.index.TOCbuff = NULL; + yaFTL.gc.index.pageBuffer = NULL; + yaFTL.gc.meta_buf = NULL; + yaFTL.gc.data.zone = NULL; + yaFTL.gc.index.zone = NULL; + yaFTL.gc.data.meta = NULL; + yaFTL.gc.index.meta = NULL; + + if (NULL != yaFTL.gc.data.vpns) { + WMR_FREE(yaFTL.gc.data.vpns, yaFTL.gc.zoneSize * sizeof(UInt32)); + } + if (NULL != yaFTL.gc.index.vpns) { + WMR_FREE(yaFTL.gc.index.vpns, yaFTL.gc.zoneSize * sizeof(UInt32)); + } + + yaFTL.gc.data.vpns = NULL; + yaFTL.gc.index.vpns = NULL; +} + +void YAFTL_GC_PreWrite(UInt32 writeSize) +{ + CheckDataCounts(); + CheckBlockDist(); + yaFTL.gc.data.in_block = 0xffffffff; + + // Below low low low mark? + while (dangerousIndex || dangerousData(writeSize)) + { + if (dangerousIndex) + { + YAFTL_GC_Index(0xffffffff, TRUE32); + } + if (dangerousData(writeSize)) + { + YAFTL_GC_Data(0xffffffff, TRUE32); + } + } + + CheckBlockDist(); + + // If we're low on space, or the garbage collector is not idle, (-> this is important to not cause hangs) + if (lowData(writeSize) || (GCD_IDLE != yaFTL.gc.data.state)) + { + GCMachine_Data(writeSize, TRUE32); + } + + CheckBlockDist(); +} + +static void MoveOnIfCurrentI(UInt32 inBlock) +{ + // Is this the current index block? + if (BLOCK_I_CURRENT == yaFTL.blockArray[inBlock].status) + { + // Have to allocate a new one so we don't pull the rug out from underneath ourselves... + allocateBlock(yaFTL.wrState.index.block, 0, 0); + } +} + +ANDStatus YAFTL_GC_Index(UInt32 block, BOOL32 scrubOnUECC) +{ + GC_Ctx_t *c = &yaFTL.gc.index; + ANDStatus status = FTL_SUCCESS; + + WMR_TRACE_IST_2(GCIndex, START, block, scrubOnUECC); + + c->in_block = block; + + stFTLStatistics.ddwIndexGCCnt++; + + CheckBlockDist(); + + again: + ChooseIndexSB(); + + if (0 == c->chosenValid) + { + // No valid pages--just erase it and be done with it all + stFTLStatistics.ddwEmptyGCIndexCnt++; + goto eraseExit; + } + + // Get block TOC, either from memory or by reading it off the NAND + if(BTOC_GET_IPN(1) == 1) + { + GetBlockTOC(c, scrubOnUECC, yaFTL.TOCtableEntriesNo, NULL); + } + else + { + GetBlockTOC(c, scrubOnUECC, yaFTL.logicalPartitionSize, NULL); + } + + status = EvictIndex(c, scrubOnUECC); + if (FTL_SUCCESS != status) + { + goto again; + } + + eraseExit: + SanityCheckValid(c); + + // Zap it! + status = EraseIndex(c->chosenBlock); + if (FTL_SUCCESS != status) + { + WMR_TRACE_IST_1(GCIndex, END, status); + return status; + } + + if (!WorkFifo_isEmpty(&c->workFifo)) + { + goto again; + } + + CheckBlockDist(); + + WMR_TRACE_IST_1(GCIndex, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +static void MoveOnIfCurrentD(UInt32 inBlock) +{ + // Is it the current data block? + if (BLOCK_CURRENT == yaFTL.blockArray[inBlock].status) + { + allocateBlock(yaFTL.wrState.data.block, 0, 1); + } +} + + +// Data state machine: +// 1) choose block +// 2) read TOC or reconstruct +// 3) [loop] find valid spans, move preferentially in chunks of sequentiality +// 4) sanity check +// 5) erase block + + +static ANDStatus GCMachine_Data(Int32 writeSize, BOOL32 scrubOnUECC) +{ + ANDStatus status; + UInt32 cost; + Int32 ratio; + + again: + WMR_TRACE_IST_3(GCMachine, START, writeSize, scrubOnUECC, yaFTL.gc.data.state); + switch (yaFTL.gc.data.state) + { + case GCD_IDLE: + while (dangerousIndex) + { + // Important for wearleveling calls, for instance + // Safe because YAFTL_GC_Index only calls GCMachine_Data if state != GCD_IDLE + YAFTL_GC_Index(0xffffffff, scrubOnUECC); + } + + stFTLStatistics.ddwDataGCCnt++; + ChooseDataSB(); + if (0 == yaFTL.gc.data.chosenValid) + { + stFTLStatistics.ddwEmptyGCDataCnt++; + yaFTL.gc.data.state = GCD_ERASE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + yaFTL.gc.data.curPage = 0; + yaFTL.gc.data.pagesCopied = 0; + yaFTL.gc.data.ueccCounter = 0; + GetBlockTOC(&yaFTL.gc.data, scrubOnUECC, yaFTL.logicalPartitionSize, &yaFTL.gc.data.ueccCounter); + yaFTL.blockArray[yaFTL.gc.data.chosenBlock].status = BLOCK_GC; + yaFTL.gc.data.state = GCD_EVICT; + break; + + case GCD_EVICT: + // Check if it's been invalidated by host writes since we entered the state machine + WMR_ASSERT(0 == yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesINo); + if (0 == yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesDNo) + { + // And short-circuit to the ERASE state + yaFTL.gc.data.state = GCD_ERASE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + cost = yaFTL.gc.zoneSize; + if (writeSize > 0) + { + ratio = (FREE_BLK_TRH_UPDATED * 2 * PAGES_PER_SUBLK) - ((yaFTL.seaState.data.freeBlocks*PAGES_PER_SUBLK)+yaFTL.gc.data.gcDataAdjust); + if (ratio <= 0) ratio = 1; + ratio = (ratio * YAFTL_GC_RATIO_SCALAR) / FREE_BLK_GAP; + // Writes should evict an amount relative to the current ratio of low-end validity + cost = PAGES_PER_SUBLK - yaFTL.controlPageNo - yaFTL.gc.data.chosenValid; // Divisor + if (!cost) + { + cost = 1; // Avoid div0 when we move a full block for wear-leveling purposes etc. + } + cost = (writeSize * PAGES_PER_SUBLK) / cost; + cost = (cost * ratio) / PAGES_PER_SUBLK; + // Round up to a zone boundary (makes no sense to do less!) + cost += yaFTL.gc.zoneSize - 1; + cost -= cost % yaFTL.gc.zoneSize; + } + + status = EvictData(cost, scrubOnUECC); + if (FTL_SUCCESS != status) + { + if (GCD_EVICT == yaFTL.gc.data.state) + { + yaFTL.gc.data.state = GCD_IDLE; + } + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + if (yaFTL.gc.data.curPage >= yaFTL.gc.data.pagesRange) + { + SanityCheckValid(&yaFTL.gc.data); + } + break; + + case GCD_ERASE: + SanityCheckValid(&yaFTL.gc.data); + status = EraseData(yaFTL.gc.data.chosenBlock); + yaFTL.gc.data.state = GCD_IDLE; + if (FTL_SUCCESS != status) + { + WMR_TRACE_IST_1(GCMachine, END, status); + return status; + } + if (!WorkFifo_isEmpty(&yaFTL.gc.data.workFifo)) + { + // If we had an error causing us to do extra data GCs, + // don't stop in the idle state. + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + break; + + case GCD_FIXINDEX_RETRY: + while (!WorkFifo_isEmpty(&yaFTL.gc.index.workFifo)) + { + YAFTL_GC_Index(0xffffffff, scrubOnUECC); + } + yaFTL.gc.data.state = GCD_IDLE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + + case GCD_FIXDATA_RETRY: + yaFTL.gc.data.state = GCD_IDLE; + WMR_TRACE_IST_0(GCMachine, END); + goto again; + } + + WMR_TRACE_IST_1(GCMachine, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +void YAFTL_GC_Data_Enq(UInt32 block) +{ + WMR_TRACE_IST_1(GCDataEnq, NONE, block); + WorkFifo_Enq(&yaFTL.gc.data.workFifo, block); +} + +void YAFTL_GC_Index_Enq(UInt32 block) +{ + WMR_TRACE_IST_1(GCIndexEnq, NONE, block); + WorkFifo_Enq(&yaFTL.gc.index.workFifo, block); +} + +ANDStatus YAFTL_GC_Data(UInt32 block, BOOL32 scrubOnUECC) +{ + ANDStatus status; + + WMR_TRACE_IST_2(GCData, START, block, scrubOnUECC); + + CheckBlockDist(); + + // Kill any previous GC operations + // This makes GC recovery from write fail more safe + if (GCD_IDLE != yaFTL.gc.data.state) { + // Un-mark pending GC operations + if ((0xffffffff != yaFTL.gc.data.chosenBlock) && (BLOCK_GC == yaFTL.blockArray[yaFTL.gc.data.chosenBlock].status)) { + yaFTL.blockArray[yaFTL.gc.data.chosenBlock].status = BLOCK_ALLOCATED; + } + } + yaFTL.gc.data.state = GCD_IDLE; + +again: + // Set up the new one + yaFTL.gc.data.in_block = block; + + // And start it + do + { + status = GCMachine_Data(0, scrubOnUECC); + if (FTL_SUCCESS != status) + { + WMR_TRACE_IST_1(GCData, END, status); + return status; + } + } + while (GCD_IDLE != yaFTL.gc.data.state); + + if (!WorkFifo_isEmpty(&yaFTL.gc.data.workFifo)) + { + block = WorkFifo_Deq(&yaFTL.gc.data.workFifo); + goto again; + } + + CheckBlockDist(); + + WMR_TRACE_IST_1(GCData, END, FTL_SUCCESS); + return FTL_SUCCESS; +} + +static void ChooseSB(GC_Ctx_t *c, UInt32 filter) +{ + UInt32 i, status; + UInt32 thisValid, thisErases; + UInt32 best, bestValid, bestErases; + + best = bestValid = bestErases = 0xFFFFFFFF; + + if (0xffffffff != c->in_block) { + MoveOnIfCurrentI(c->in_block); + MoveOnIfCurrentD(c->in_block); + } + + if (!WorkFifo_isEmpty(&c->workFifo)) + { + if (0xffffffff != c->in_block) + { + WorkFifo_Enq(&c->workFifo, c->in_block); + } + c->in_block = WorkFifo_Deq(&c->workFifo); + } + + if (0xffffffff != c->in_block) + { + c->chosenBlock = c->in_block; + c->chosenValid = yaFTL.blockArray[c->in_block].validPagesDNo + yaFTL.blockArray[c->in_block].validPagesINo; + c->chosenErases = yaFTL.blockArray[c->in_block].erasableCount; + status = yaFTL.blockArray[c->in_block].status; + if (status != filter) + { + // Note: these rules use implication, that works in conjunction with the wrapper if statement so + // BLOCK_I_ALLOCATED filter means BLOCK_I_CURRENT/GC will work, and the same for BLOCK_ALLOCATED and BLOCK_CURRENT/GC. + WMR_ASSERT((filter != BLOCK_ALLOCATED) || ((status == BLOCK_CURRENT) || (status == BLOCK_GC))); + WMR_ASSERT((filter != BLOCK_I_ALLOCATED) || ((status == BLOCK_I_CURRENT) || (status == BLOCK_I_GC))); + } + c->in_block = 0xffffffff; + return; + } + + for (i = 0; i < FTL_AREA_SIZE; i++) + { + // Not allocated to the filter type? Don't consider... + if (yaFTL.blockArray[i].status != filter) + { + continue; + } + + // Grab local copies + thisValid = yaFTL.blockArray[i].validPagesDNo + yaFTL.blockArray[i].validPagesINo; + thisErases = yaFTL.blockArray[i].erasableCount; + + // Minimize valid + if ((thisValid < bestValid) || ((thisValid == bestValid) && (thisErases < bestErases))) + { + best = i; + bestValid = thisValid; + bestErases = thisErases; + } + } + + WMR_ASSERT(best != 0xFFFFFFFF); + WMR_ASSERT(bestValid != 0xFFFFFFFF); + WMR_ASSERT(bestErases != 0xFFFFFFFF); + + // Output + c->chosenBlock = best; + c->chosenValid = bestValid; + c->chosenErases = bestErases; +} + +static void ChooseIndexSB() +{ + ChooseSB(&yaFTL.gc.index, BLOCK_I_ALLOCATED); +} + +static void ChooseDataSB() +{ + ChooseSB(&yaFTL.gc.data, BLOCK_ALLOCATED); +} + +static ANDStatus EraseIndex(UInt32 block) +{ + yaFTL.blockArray[block].eraseBeforeUse = BLOCK_TO_BE_ERASED_ALIGNED_INDEX; + yaFTL.blockArray[block].pagesRead = 0; + yaFTL.blockArray[block].pagesReadSubCounter = 0; + yaFTL.blockArray[block].validPagesDNo = yaFTL.blockArray[block].validPagesINo = 0; + yaFTL.seaState.freeBlocks++; + yaFTL.blockArray[block].status = BLOCK_I_FREE; + yaFTL.seaState.index.freeBlocks++; + yaFTL.seaState.index.allocdBlocks--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks++; +#endif + return FTL_SUCCESS; +} + +static ANDStatus EraseData(UInt32 block) +{ + yaFTL.blockArray[block].eraseBeforeUse = BLOCK_TO_BE_ERASED_ALIGNED_DATA; + yaFTL.blockArray[block].pagesRead = 0; + yaFTL.blockArray[block].pagesReadSubCounter = 0; + yaFTL.blockArray[block].validPagesDNo = yaFTL.blockArray[block].validPagesINo = 0; + yaFTL.seaState.freeBlocks++; + yaFTL.blockArray[block].status = BLOCK_FREE; + yaFTL.seaState.data.freeBlocks++; + yaFTL.seaState.data.allocdBlocks--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwFreeBlks++; +#endif + return FTL_SUCCESS; +} + +static ANDStatus GetBlockTOC(GC_Ctx_t *c, BOOL32 scrubOnUECC, UInt32 upperBound, UInt32 *ueccCounter) +{ + UInt32 i; + UInt32 *ramBTOC; + PageMeta_t *meta = yaFTL.gc.meta_buf; + + ANDStatus status; + + c->pagesRange = PAGES_PER_SUBLK - yaFTL.controlPageNo; + + // Is it in memory? + ramBTOC = BTOC_Search(c->chosenBlock, c == &yaFTL.gc.data); + if (NULL != ramBTOC) { + BTOC_Copy(c->TOCbuff, ramBTOC, upperBound); + return FTL_SUCCESS; + } + + // Have to read it off the NAND... + status = BTOC_Read((c->chosenBlock * PAGES_PER_SUBLK) + (PAGES_PER_SUBLK - yaFTL.controlPageNo), c->TOCbuff, meta, FALSE32, scrubOnUECC, upperBound); + if ((status != FTL_SUCCESS) || ((status == FTL_SUCCESS) && !META_IS_BTOC(meta))) + { + BOOL32 uncleanFound = FALSE32; + + debug(MISC, "cannot read blockTOC - restoring blockTOC manually"); + BTOC_SetAll(c->TOCbuff, 0xff); + i = (UInt32)(PAGES_PER_SUBLK - yaFTL.controlPageNo); + while (i-- > 0) + { + status = _readPage((c->chosenBlock * PAGES_PER_SUBLK) + i, c->pageBuffer, meta, FALSE32, TRUE32, scrubOnUECC); + if (VFL_SUCCESS_CLEAN != status) + { + uncleanFound = TRUE32; + } + if ((status == FTL_SUCCESS) && (META_GET_IPNRAW(meta) < upperBound)) + { + c->TOCbuff[i] = META_GET_IPNRAW(meta); + } + else + { + if ((FTL_CRITICAL_ERROR == status) || ((VFL_SUCCESS_CLEAN == status) && uncleanFound)) + { + if (NULL != ueccCounter) + { + debug(MISC, "got error at block %d page %d, assuming uecc\n", c->chosenBlock, i); + (*ueccCounter)++; + } + } + } + } + } + + return FTL_SUCCESS; +} + +static void SanityCheckValid(GC_Ctx_t *c) +{ + // Sanity check: should now be empty... + if ((yaFTL.blockArray[c->chosenBlock].validPagesINo + yaFTL.blockArray[c->chosenBlock].validPagesDNo) != 0) + { + CheckDataCounts(); + debug(ERROR, "something could be wrong with GC; index:%d data:%d ", yaFTL.blockArray[c->chosenBlock].validPagesINo, yaFTL.blockArray[c->chosenBlock].validPagesDNo); + if (c->ueccCounter >= (yaFTL.blockArray[c->chosenBlock].validPagesINo + yaFTL.blockArray[c->chosenBlock].validPagesDNo)) + { + // If we had uncorrectables, we may be missing data... best way to mark it is to do a P->L translation, but that + // would be a very slow, exhaustive searchof the index tables--though we should consider implementing it at some point. + debug(ERROR, "fixing up validity counters since we had %d uECC(s) ", c->ueccCounter); + yaFTL.blockArray[c->chosenBlock].validPagesINo = 0; + yaFTL.blockArray[c->chosenBlock].validPagesDNo = 0; + } + else + { + // It must be a real bug since we had no uncorrectables to blame + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Non-zero validity counter Block %d Index: %d Data: %d UECC: %d", + c->chosenBlock, + (UInt32) yaFTL.blockArray[c->chosenBlock].validPagesINo, + (UInt32) yaFTL.blockArray[c->chosenBlock].validPagesDNo, + c->ueccCounter); + } + } +} + +typedef enum +{ + IPS_DEAD, + IPS_DIRTYCACHE, + IPS_BUSYCACHE, + IPS_ALIVE, + IPS_ERROR, +} IPageState_t; + +static IPageState_t GetIndexPageState(UInt32 page, UInt32 *r_presentIdxPage, UInt32 *r_indexPagePhy, UInt32 *r_cacheIndexPtr) +{ + GC_Ctx_t *c = &yaFTL.gc.index; + UInt32 presentIdxPage, indexPagePhy, cacheIndexPtr; + + // Extract which IdxPage lives at this location + presentIdxPage = BTOC_GET_IPN(c->TOCbuff[page]); + *r_presentIdxPage = presentIdxPage; + + if (0xffffffff == c->TOCbuff[page]) + { + // Nothing to move + return IPS_DEAD; + } + + // Calculate which index page, its location (if any) in the cache + indexPagePhy = yaFTL.tocArray[presentIdxPage].indexPage; + cacheIndexPtr = yaFTL.tocArray[presentIdxPage].cacheIndex; + *r_indexPagePhy = indexPagePhy; + *r_cacheIndexPtr = cacheIndexPtr; + + if ((0xffffffff == indexPagePhy) && (0xffff == cacheIndexPtr)) + { + // Not on medium or in cache... (span deallocated) + return IPS_DEAD; + } + + if ((0xffffffff != indexPagePhy) && (indexPagePhy != ((c->chosenBlock * PAGES_PER_SUBLK) + page))) + { + // Early out for wrong location... + return IPS_DEAD; + } + + if ((cacheIndexPtr != 0xffff) && (yaFTL.indexCache[cacheIndexPtr].status == IC_DIRTY_PAGE)) + { + // In cache, and dirty, so it will make it down eventually... + return IPS_DIRTYCACHE; + } + + if ((cacheIndexPtr != 0xffff) && (yaFTL.indexCache[cacheIndexPtr].status == IC_BUSY_PAGE)) + { + // It's in the cache as busy; special logic needed by caller... + return IPS_BUSYCACHE; + } + + if (indexPagePhy != 0xffffffff) + { + if (((c->chosenBlock * PAGES_PER_SUBLK) + page) == indexPagePhy) + { + // We've found a live one! + return IPS_ALIVE; + } + else + { + // On medium, but not in that location, so don't move it + // Should be unreachable + WMR_ASSERT(0); + return IPS_DEAD; + } + } + + // Should never get here, as the above logic should cover all cases. + WMR_ASSERT(0); + return IPS_ERROR; +} + +static ANDStatus EvictIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC) +{ + UInt32 page, alignZoneSize; + UInt32 presentIdxPage, indexPagePhy, cacheIndexPtr; + UInt16 newCacheEntry; + ANDStatus status; + + status = FTL_SUCCESS; + c->pagesCopied = 0; + c->curZoneSize = 0; + c->ueccCounter = 0; + + yaFTL.blockArray[c->chosenBlock].status = BLOCK_I_GC; + + // Iterate over the range of potentially valid virtual pages + for (page = 0; (page < c->pagesRange) && (c->pagesCopied < c->chosenValid); page++) + { + switch (GetIndexPageState(page, &presentIdxPage, &indexPagePhy, &cacheIndexPtr)) + { + case IPS_DEAD: + case IPS_DIRTYCACHE: + // Nothing to move. + break; + + case IPS_BUSYCACHE: + yaFTL.indexCache[cacheIndexPtr].status = IC_DIRTY_PAGE; // So it gets written to the flash later. + if (((c->chosenBlock * PAGES_PER_SUBLK) + page) == indexPagePhy) + { + // Pre-check validity + WMR_ASSERT(0 != yaFTL.blockArray[c->chosenBlock].validPagesINo); + + // Manage validity and page copy count + yaFTL.blockArray[c->chosenBlock].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[presentIdxPage].indexPage = 0xffffffff; + + c->pagesCopied++; + } + break; + + case IPS_ALIVE: + newCacheEntry = findFreeCacheEntry(); + if (newCacheEntry != 0xffff) + { + // Read it in to the cache if we can + status = _readPage((c->chosenBlock * PAGES_PER_SUBLK) + page, (UInt8 *)(yaFTL.indexCache[newCacheEntry].indexPage), yaFTL.singleMdPtr, FALSE32, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + yaFTL.indexCache[newCacheEntry].status = IC_DIRTY_PAGE; + yaFTL.indexCache[newCacheEntry].tocEntry = presentIdxPage; + yaFTL.tocArray[presentIdxPage].cacheIndex = newCacheEntry; + yaFTL.tocArray[presentIdxPage].indexPage = 0xffffffff; + + // Pre-check validity + WMR_ASSERT(0 != yaFTL.blockArray[c->chosenBlock].validPagesINo); + + // Manage validity and page copy count + yaFTL.blockArray[c->chosenBlock].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + c->pagesCopied++; + } + else + { + // No free cache pages... copy it over + + // Pre-check validity + WMR_ASSERT(yaFTL.blockArray[c->chosenBlock].validPagesINo >= c->curZoneSize); + + // Zone overflow? + alignZoneSize = yaFTL.gc.zoneSize - (yaFTL.wrState.index.nextPage % NUM_BANKS); + if (c->curZoneSize >= alignZoneSize) + { + status = ReadZone(c, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneIndex(c, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + + c->curZoneSize = 0; + } + + // Place in zone + yaFTL.gc.index.vpns[c->curZoneSize] = (c->chosenBlock * PAGES_PER_SUBLK) + page; + c->curZoneSize++; + } + break; + + default: + WMR_ASSERT(0); + break; + } + } + + // Do remainder + if (c->curZoneSize > 0) + { + status = ReadZone(c, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneIndex(c, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + } + + return status; +} + +static BOOL32 IsDataPageCurrent(UInt32 page, UInt32 *vPN, ANDStatus *status, BOOL32 scrubOnUECC) +{ + GC_Ctx_t *c = &yaFTL.gc.data; + UInt32 presentVpn, indexPageNo, indexPageSub, indexPagePhy, cacheIndexPtr; + PageMeta_t *tMD = yaFTL.gc.meta_buf; + + // Extract which VPN lives at this location + presentVpn = c->TOCbuff[page]; + + if (0xffffffff == presentVpn) + { + // Nothing to move... + return FALSE32; + } + +#if ENABLE_L2V_TREE + // Out of search span, or switched to a different region? + if ((0 == yaFTL.gc.data.read_c.span) || (yaFTL.gc.data.read_c.lba != presentVpn)) { + yaFTL.gc.data.read_c.lba = presentVpn; + L2V_Search(&yaFTL.gc.data.read_c); + } + WMR_ASSERT(0 != yaFTL.gc.data.read_c.span); + + // Move search iterator along--NOTE: can't use these values below; if we need to, move these to exit paths + yaFTL.gc.data.read_c.lba++; + yaFTL.gc.data.read_c.span--; + + if (L2V_VPN_DEALLOC == yaFTL.gc.data.read_c.vpn) { + // Deallocated + return FALSE32; + } + + if (yaFTL.gc.data.read_c.vpn < L2V_VPN_SPECIAL) { + *vPN = yaFTL.gc.data.read_c.vpn; + yaFTL.gc.data.read_c.vpn++; // Only because not in special range + return *vPN == ((c->chosenBlock * PAGES_PER_SUBLK) + page); + } + + // Missed first search... :( + WMR_ASSERT(L2V_VPN_MISS == yaFTL.gc.data.read_c.vpn); + + if (yaFTL.gc.data.read_c.vpn < L2V_VPN_SPECIAL) { + yaFTL.gc.data.read_c.vpn++; + } +#endif // ENABLE_L2V_TREE + + // Calculate which index page, how far in, where the index page lives, and its location in the cache + indexPageNo = presentVpn / yaFTL.indexPageRatio; + WMR_ASSERT(indexPageNo < yaFTL.TOCtableEntriesNo); + indexPageSub = presentVpn % yaFTL.indexPageRatio; + indexPagePhy = yaFTL.tocArray[indexPageNo].indexPage; + cacheIndexPtr = yaFTL.tocArray[indexPageNo].cacheIndex; + + if ((0xffffffff == indexPagePhy) && (0xffff == cacheIndexPtr)) + { + // Not on medium or in cache... + return FALSE32; + } + + if (0xffff == cacheIndexPtr) + { + // Need to read index page in to cache first + cacheIndexPtr = findFreeCacheEntry(); + if (cacheIndexPtr == 0xffff) + { + /* Cache is full and we need to clear space for new index page */ + cacheIndexPtr = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexPtr == 0xffff) + { + *status = FTL_CRITICAL_ERROR; + yaFTL.gc.data.state = GCD_FIXINDEX_RETRY; + + return FALSE32; + } + } + + *status = _readPage(indexPagePhy, (UInt8 *)(yaFTL.indexCache[cacheIndexPtr].indexPage), tMD, FALSE32, TRUE32, scrubOnUECC); + if (*status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Index UECC Page 0x%08x Status 0x%08x", indexPagePhy, *status); + return FALSE32; + } + + if (!META_IS_IDX(tMD)) + { + debug(ERROR, "meta data expected to be from an index page"); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Invalid Index metadata 0x%02x", (UInt32) META_GET_ALL_FLAGS(tMD)); + *status = FTL_CRITICAL_ERROR; + return FALSE32; + } + yaFTL.freeCachePages--; + yaFTL.indexCache[cacheIndexPtr].status = IC_BUSY_PAGE; + yaFTL.indexCache[cacheIndexPtr].counter = 1; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexPtr; + yaFTL.indexCache[cacheIndexPtr].tocEntry = indexPageNo; + } + + *vPN = yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub]; + return *vPN == ((c->chosenBlock * PAGES_PER_SUBLK) + page); +} + +static ANDStatus EvictData(UInt32 minAmount, BOOL32 scrubOnUECC) +{ + UInt32 vPN, alignZoneSize; + ANDStatus status; + UInt32 moved = 0; + + status = FTL_SUCCESS; + + yaFTL.gc.data.curZoneSize = 0; + + // Clear search state every time we enter EvictData, for coherency +#if ENABLE_L2V_TREE + L2V_Search_Init(&yaFTL.gc.data.read_c); +#endif // ENABLE_L2V_TREE + + for (; (moved < minAmount) && (yaFTL.gc.data.curPage < yaFTL.gc.data.pagesRange) && (yaFTL.gc.data.pagesCopied < yaFTL.gc.data.chosenValid); yaFTL.gc.data.curPage++) + { + if (IsDataPageCurrent(yaFTL.gc.data.curPage, &vPN, &status, scrubOnUECC)) + { + yaFTL.gc.data.vpns[yaFTL.gc.data.curZoneSize] = vPN; + yaFTL.gc.data.curZoneSize++; + moved++; + yaFTL.gc.data.pagesCopied++; + } + if (FTL_SUCCESS != status) + { + return status; + } + + alignZoneSize = yaFTL.gc.zoneSize - (yaFTL.wrState.data.nextPage % NUM_BANKS); + if (yaFTL.gc.data.curZoneSize >= alignZoneSize) + { + WMR_ASSERT(yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesDNo >= yaFTL.gc.data.curZoneSize); + + status = ReadZone(&yaFTL.gc.data, FALSE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneData(&yaFTL.gc.data, scrubOnUECC); + if (status != FTL_SUCCESS) + { + yaFTL.gc.data.state = GCD_FIXDATA_RETRY; + return status; + } + yaFTL.gc.data.curZoneSize = 0; + } + } + + if (yaFTL.gc.data.curZoneSize > 0) + { + WMR_ASSERT(yaFTL.blockArray[yaFTL.gc.data.chosenBlock].validPagesDNo >= yaFTL.gc.data.curZoneSize); + + status = ReadZone(&yaFTL.gc.data, FALSE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + return status; + } + status = WriteZoneData(&yaFTL.gc.data, scrubOnUECC); + if (status != FTL_SUCCESS) + { + yaFTL.gc.data.state = GCD_FIXDATA_RETRY; + return status; + } + } + + return status; +} + +static BOOL32 ReconstructIndex(UInt32 indexEntry, UInt32 *indexPage) +{ +#if ENABLE_L2V_TREE + UInt32 lpnOfs, lpn, vpn, add, amount; + + lpn = indexEntry * yaFTL.indexPageRatio; + yaFTL.gc.index.read_c.span = 0; + + lpnOfs = 0; + while (lpnOfs < yaFTL.indexPageRatio) { + if (0 == yaFTL.gc.index.read_c.span) { + yaFTL.gc.index.read_c.lba = lpn + lpnOfs; + L2V_Search(&yaFTL.gc.index.read_c); + } + WMR_ASSERT(0 != yaFTL.gc.index.read_c.span); + + // Missing? Bail out + if (L2V_VPN_MISS == yaFTL.gc.index.read_c.vpn) { + return FALSE32; + } + + // Not missing from IC tree + if (L2V_VPN_DEALLOC != yaFTL.gc.index.read_c.vpn) { + // Not deallocated + vpn = yaFTL.gc.index.read_c.vpn; + WMR_ASSERT(yaFTL.gc.index.read_c.vpn < L2V_VPN_SPECIAL); + + // Complete the span + amount = WMR_MIN(yaFTL.indexPageRatio-lpnOfs, yaFTL.gc.index.read_c.span); + add = amount; + while (amount--) { + indexPage[lpnOfs++] = vpn++; + + } + + yaFTL.gc.index.read_c.vpn += add; + yaFTL.gc.index.read_c.span -= add; + } else { + // Deallocated + vpn = 0xffffffff; + + // Complete the span + amount = WMR_MIN(yaFTL.indexPageRatio-lpnOfs, yaFTL.gc.index.read_c.span); + add = amount; + while (amount--) { + indexPage[lpnOfs++] = vpn; + } + + yaFTL.gc.index.read_c.span -= add; + } + + } + + return TRUE32; +#else + return FALSE32; +#endif +} + +static void ScrubZone(GC_Ctx_t *c, BOOL32 index) +{ + UInt32 i, ipn, lba; + + if (index) { + for (i = 0; i < c->curZoneSize; i++) + { + ipn = META_GET_IPN(&c->meta[i]); + if (ipn >= yaFTL.TOCtableEntriesNo) + { + META_SET_IPN_FROM_BTOC(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + SetupMeta_Data_UECC(&c->meta[i]); + } + } + } else { + for (i = 0; i < c->curZoneSize; i++) + { + lba = META_GET_LBA(&c->meta[i]); + if (lba >= yaFTL.logicalPartitionSize) + { + META_SET_LBA(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + SetupMeta_Data_UECC(&c->meta[i]); + } + } + } +} + +static ANDStatus ReadZone(GC_Ctx_t *c, BOOL32 index, BOOL32 scrubOnUECC) +{ + BOOL32 BoolStatus, dontRead; + UInt8 i; + // Handling uECCs, trying older data: + BOOL32 failed, rereadOrig; + UInt32 srcVpn; + + dontRead = FALSE32; + if (index) { + dontRead = TRUE32; + for (i = 0; dontRead && (i < c->curZoneSize); i++) + { + META_SET_IPN_FROM_BTOC(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + WMR_ASSERT(META_GET_LBA(&c->meta[i]) != 0xffffffff); + dontRead = dontRead && ReconstructIndex(META_GET_IPN(&c->meta[i]), (UInt32*)&c->zone[BYTES_PER_PAGE * i]); + } + BoolStatus = TRUE32; + } + if (!dontRead) { + BoolStatus = _readMultiPages(c->vpns, c->curZoneSize, c->zone, (UInt8*)c->meta, !index, scrubOnUECC); + } + + if (BoolStatus == TRUE32) + { + ScrubZone(c, index); + return FTL_SUCCESS; + } + else + { + for (i = 0; i < c->curZoneSize; i++) + { + if (_readPage(c->vpns[i], &c->zone[BYTES_PER_PAGE * i], &c->meta[i], !index, TRUE32, scrubOnUECC) != FTL_SUCCESS) + { + failed = TRUE32; + if (!index) + { + srcVpn = BTOC_GetSrc(c->vpns[i]); + if (0xffffffff != srcVpn) + { + rereadOrig = FALSE32; + if (_readPage(srcVpn, &c->zone[BYTES_PER_PAGE * i], &c->meta[i], !index, TRUE32, scrubOnUECC) == FTL_SUCCESS) + { + failed = FALSE32; + } + else + { + rereadOrig = TRUE32; + } + + if (rereadOrig || (!rereadOrig && (c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK] != META_GET_LBA(&c->meta[i])))) + { + _readPage(c->vpns[i], &c->zone[BYTES_PER_PAGE * i], &c->meta[i], !index, TRUE32, scrubOnUECC); + } + } + } + + if (failed) { + if (index) { + META_SET_IPN_FROM_BTOC(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + } else { + META_SET_LBA(&c->meta[i], c->TOCbuff[c->vpns[i] % PAGES_PER_SUBLK]); + } + WMR_ASSERT(META_GET_LBA(&c->meta[i]) != 0xffffffff); + if (index) { + if (!ReconstructIndex(META_GET_IPN(&c->meta[i]), (UInt32*)&c->zone[BYTES_PER_PAGE * i])) { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("Couldn't reconstruct yaFTL index after a uECC: vpn 0x%x", c->vpns[i]); + } + } else { + SetupMeta_Data_UECC(&c->meta[i]); + } + c->ueccCounter++; + } + } + } + } + + ScrubZone(c, index); + return FTL_SUCCESS; +} + +static ANDStatus WriteZoneData(GC_Ctx_t *c, BOOL32 scrubOnUECC) +{ + BOOL32 status; + UInt8 i; + UInt32 prevVpn; + UInt16 cacheIndexPtr; + UInt32 count, thisOfs, thisCount; + PageMeta_t *mdPtr = &yaFTL.gc.data.meta[0]; + PageMeta_t *md_index = yaFTL.gc.meta_buf; + UInt32 indexPageNo, indexPageSub; + UInt32 newVpn; + + thisOfs = 0; + count = c->curZoneSize; + c->gcDataAdjust += c->curZoneSize; + + // While we still have data we want to move, + while (count) + { + // If we have space left in this block, + if (yaFTL.wrState.data.nextPage < (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + // Move as much as we can + thisCount = WMR_MIN((UInt32)((PAGES_PER_SUBLK - yaFTL.controlPageNo) - yaFTL.wrState.data.nextPage), (UInt32)count); + + // Fill in metadata + SetupMeta_DataGC(&mdPtr[thisOfs], thisCount); + + // Write the data + status = _writeMultiPages(yaFTL.wrState.data.block, yaFTL.wrState.data.nextPage, thisCount, &yaFTL.gc.data.zone[thisOfs * BYTES_PER_PAGE], &mdPtr[thisOfs], TRUE32); + if (status == TRUE32) + { + newVpn = (yaFTL.wrState.data.block * PAGES_PER_SUBLK) + yaFTL.wrState.data.nextPage; + for (i = 0; i < thisCount; i++, newVpn++) + { + // Update block TOC + yaFTL.wrState.data.TOC[yaFTL.wrState.data.nextPage + i] = META_GET_LBA(&mdPtr[thisOfs + i]); + // and src vpn + BTOC_SetSrc(newVpn, yaFTL.gc.data.vpns[thisOfs + i]); + // And temporary housing for updates to tree + yaFTL.gc.data.vpns[thisOfs + i] = newVpn; + } + yaFTL.wrState.data.nextPage += thisCount; + thisOfs += thisCount; + } + else + { + if(addBlockToEraseNowList(yaFTL.wrState.data.block) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", yaFTL.wrState.data.block); + } + WorkFifo_Enq(&c->workFifo, c->chosenBlock); + WorkFifo_Enq(&c->workFifo, yaFTL.wrState.data.block); + allocateBlock(yaFTL.wrState.data.block, 0, 1); + + return FTL_CRITICAL_ERROR; + } + + // Move along + count -= thisCount; + } + + // Want to write more data but out of space? + if (count && (yaFTL.wrState.data.nextPage >= (PAGES_PER_SUBLK - yaFTL.controlPageNo))) + { + // Write the block TOC + writeCurrentBlockTOC(1); + + // Move to the next block + allocateBlock(yaFTL.wrState.data.block, 0, 1); + } + } + + // Now we need to update index to reflect change in Lpn location + for (i = 0; i < c->curZoneSize; i++) + { +#if ENABLE_L2V_TREE + L2V_Update(META_GET_LBA(&mdPtr[i]), 1, yaFTL.gc.data.vpns[i]); +#endif // ENABLE_L2V_TREE + + // Calculate which index page and offset within for this update + indexPageNo = META_GET_LBA(&mdPtr[i]) / yaFTL.indexPageRatio; + indexPageSub = META_GET_LBA(&mdPtr[i]) % yaFTL.indexPageRatio; + + WMR_ASSERT((yaFTL.tocArray[indexPageNo].indexPage != 0xffffffff) || (yaFTL.tocArray[indexPageNo].cacheIndex != 0xffff)); + + // This is a page that belongs to valid index batch + // Need to get index page to cache and update its content + cacheIndexPtr = yaFTL.tocArray[indexPageNo].cacheIndex; + if (0xffff == cacheIndexPtr) + { + cacheIndexPtr = findFreeCacheEntry(); + if (cacheIndexPtr == 0xffff) + { + /* Cache is full and we need to clear space for new index page */ + cacheIndexPtr = clearEntryInCache(0, 0xffff, 0); + if (cacheIndexPtr == 0xffff) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("failed to evict index page from cache"); + } + } + status = _readPage(yaFTL.tocArray[indexPageNo].indexPage, (UInt8 *)(yaFTL.indexCache[cacheIndexPtr].indexPage), md_index, FALSE32, TRUE32, scrubOnUECC); + if (status != FTL_SUCCESS) + { + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Index UECC Page 0x%08x Status 0x%08x", yaFTL.tocArray[indexPageNo].indexPage, status); + return status; + } + yaFTL.freeCachePages--; + // Reset counter since we just pulled this in to the cache + yaFTL.indexCache[cacheIndexPtr].counter = 0; + } + + // Find previous physical location + prevVpn = yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub]; + if (prevVpn != 0xffffffff) + { + // Deprecate validity + if (yaFTL.blockArray[prevVpn / PAGES_PER_SUBLK].validPagesDNo == 0) + { + debug(ERROR, "miscalculated valid pages "); + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + + WMR_PANIC("Incorrect valid pages VPN 0x%08x Valid %d", + prevVpn, yaFTL.blockArray[prevVpn / PAGES_PER_SUBLK].validPagesDNo); + return FTL_CRITICAL_ERROR; + } + yaFTL.blockArray[prevVpn / PAGES_PER_SUBLK].validPagesDNo--; + yaFTL.seaState.data.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages--; +#endif + } + + // Update with new page location + yaFTL.indexCache[cacheIndexPtr].indexPage[indexPageSub] = yaFTL.gc.data.vpns[i]; + // Update validity + yaFTL.blockArray[yaFTL.gc.data.vpns[i] / PAGES_PER_SUBLK].validPagesDNo++; + yaFTL.seaState.data.validPages++; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidDataPages++; +#endif + + // Cross-link cache entry with index page info (redunant if it was already touched but it's ok) + yaFTL.indexCache[cacheIndexPtr].tocEntry = indexPageNo; + yaFTL.tocArray[indexPageNo].cacheIndex = cacheIndexPtr; + + // Mark previous index page as invalid if we just sucked it into cache + if (yaFTL.tocArray[indexPageNo].indexPage != 0xffffffff) + { + yaFTL.blockArray[(yaFTL.tocArray[indexPageNo].indexPage) / PAGES_PER_SUBLK].validPagesINo--; + yaFTL.seaState.index.validPages--; +#ifdef AND_COLLECT_STATISTICS + stFTLStatistics.ddwValidIndexPages--; +#endif + yaFTL.tocArray[indexPageNo].indexPage = 0xffffffff; + } + + // Mark cache entry as being dirty and touch the counter + yaFTL.indexCache[cacheIndexPtr].status = IC_DIRTY_PAGE; + if (yaFTL.indexCache[cacheIndexPtr].counter < YAFTL_INDEX_CACHE_COUNTER_LIMIT) + yaFTL.indexCache[cacheIndexPtr].counter++; + } + + return FTL_SUCCESS; +} + +static ANDStatus WriteZoneIndex(GC_Ctx_t *c, BOOL32 scrubOnUECC) +{ + BOOL32 BoolStatus; + UInt8 i; + UInt32 count, thisCount, thisOfs; + PageMeta_t *mdPtr = &yaFTL.gc.index.meta[0]; + + thisOfs = 0; + count = c->curZoneSize; + + // While we still have data we want to move, + while (count) + { + // And if we have space left in this block, + if (yaFTL.wrState.index.nextPage < (PAGES_PER_SUBLK - yaFTL.controlPageNo)) + { + thisCount = WMR_MIN((UInt32)((PAGES_PER_SUBLK - yaFTL.controlPageNo) - yaFTL.wrState.index.nextPage), (UInt32)count); + + // Fill in metadata + SetupMeta_IndexGC(&mdPtr[thisOfs], thisCount); + + // Write the data + BoolStatus = _writeMultiPages(yaFTL.wrState.index.block, yaFTL.wrState.index.nextPage, thisCount, &yaFTL.gc.index.zone[thisOfs * BYTES_PER_PAGE], &mdPtr[thisOfs], FALSE32); + if (BoolStatus == TRUE32) + { + for (i = 0; i < thisCount; i++) + { + // Update block TOC + BTOC_SET_FROM_IPN(yaFTL.wrState.index.TOC[yaFTL.wrState.index.nextPage + i], &mdPtr[thisOfs + i]); + yaFTL.tocArray[META_GET_IPN(&mdPtr[thisOfs + i])].indexPage = yaFTL.wrState.index.block * PAGES_PER_SUBLK + yaFTL.wrState.index.nextPage + i; + } + + // Update valid counts + yaFTL.blockArray[yaFTL.wrState.index.block].validPagesINo += thisCount; + yaFTL.blockArray[c->chosenBlock].validPagesINo -= thisCount; + c->pagesCopied += thisCount; + + yaFTL.wrState.index.nextPage += thisCount; + thisOfs += thisCount; + } + else + { + if(addBlockToEraseNowList(yaFTL.wrState.index.block) == FALSE32) + { + // Invalidate context + if (yaFTL.cxtValid == 1) + { + invalidateCXT(); + yaFTL.cxtValid = 0; + } + WMR_PANIC("cannot add block %d to a scrub list", yaFTL.wrState.index.block); + } + WorkFifo_Enq(&c->workFifo, c->chosenBlock); + WorkFifo_Enq(&c->workFifo, yaFTL.wrState.index.block); + allocateBlock(yaFTL.wrState.index.block, 0, 0); + return FTL_CRITICAL_ERROR; + } + + // Move along + count -= thisCount; + } + + // Want to write more data but out of space? + if (count && (yaFTL.wrState.index.nextPage >= (PAGES_PER_SUBLK - yaFTL.controlPageNo))) + { + // Write the block TOC + writeCurrentBlockTOC(0); + + // Move to the next block + allocateBlock(yaFTL.wrState.index.block, 0, 0); + WMR_ASSERT(0 == yaFTL.wrState.index.nextPage); + } + } + + // And get outta here + return FTL_SUCCESS; +} + +#endif // AND_READONLY + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.h new file mode 100644 index 0000000..dd17c8a --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_gc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_GC_H__ +#define __YAFTL_GC_H__ + +#include "yaFTL_whoami.h" +#include "ANDTypes.h" + +// General setup/close +extern ANDStatus YAFTL_GC_Init(void); +extern void YAFTL_GC_Close(void); + +// Called by Write +extern void YAFTL_GC_PreWrite(UInt32 writeSize); + +// For error recovery +extern void YAFTL_GC_Data_Enq(UInt32 block); +extern UInt32 YAFTL_GC_Data_Deq_sb(UInt32 block); +extern void YAFTL_GC_Index_Enq(UInt32 block); + +// Direct access to the machines +extern ANDStatus YAFTL_GC_Index(UInt32 block, BOOL32 scrubOnUECC); +extern ANDStatus YAFTL_GC_Data(UInt32 block, BOOL32 scrubOnUECC); + +#ifdef AND_READONLY +#define CheckBlockDist(x) +#else +extern void CheckBlockDist(void); +#endif + +#endif // ----- #ifndef __YAFTL_GC_H__ diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta.h new file mode 100644 index 0000000..d462e82 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#ifndef __YAFTL_META_H__ +#define __YAFTL_META_H__ + +#include "yaFTL_whoami.h" +#include "WMROAM.h" + +#if NAND_PPN +#include "yaFTL_meta_ppn.h" +#else +// Default to raw to avoid compilation errors--meta isn't needed by some of the parsers that include yaFTLTypes.h +#include "yaFTL_meta_raw.h" +#endif + +#endif // __YAFTL_META_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.c b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.c new file mode 100644 index 0000000..67cb451 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "yaFTL_whoami.h" +#include "yaFTL_meta_ppn.h" +#include "WMRConfig.h" +#include "yaFTLTypes.h" + +extern yaFTL_t yaFTL; + + +void SetupMeta_Data(PageMeta_t *__meta, UInt32 lba, UInt32 count) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_DATA; + m->c.FTLFlags = 0; + m->lba = lba; + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + m->userSeq = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + + // Next + lba++; + m++; + } +} + +void SetupMeta_Data_UECC(PageMeta_t *__meta) +{ + __meta->c.FTLFlags |= PFLAG_UECC; +} + +void SetupMeta_Index(PageMeta_t *__meta, UInt32 ipn) +{ + PageMeta_Idx_t *m = (PageMeta_Idx_t*)__meta; + + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_IDX; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + m->baseLba = ipn * yaFTL.indexPageRatio; +} + +void SetupMeta_Data_BTOC(PageMeta_t *__meta) +{ + PageMeta_BTOC_t *m = (PageMeta_BTOC_t*)__meta; + + m->c.PageType = PAGETYPE_FTL_BTOC_DATA; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.data.minWeaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.data.minWeaveSeq >> 16); + m->maxWeaveSeqAdd = (UInt32)(yaFTL.wrState.weaveSeq - yaFTL.wrState.data.minWeaveSeq); + m->__rfu__ = 0xffffffff; +} + +void SetupMeta_Index_BTOC(PageMeta_t *__meta) +{ + PageMeta_BTOC_t *m = (PageMeta_BTOC_t*)__meta; + + m->c.PageType = PAGETYPE_FTL_BTOC_IDX; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.index.minWeaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.index.minWeaveSeq >> 16); + m->maxWeaveSeqAdd = (UInt32)(yaFTL.wrState.weaveSeq - yaFTL.wrState.index.minWeaveSeq); + m->__rfu__ = 0xffffffff; +} + +void SetupMeta_IndexGC(PageMeta_t *__meta, UInt32 count) +{ + PageMeta_Idx_t *m = (PageMeta_Idx_t*)__meta; + + while (count--) { + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_IDX; + m->c.FTLFlags = 0; + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + + // Next + m++; + } +} + +void SetupMeta_DataGC(PageMeta_t *__meta, UInt32 count) +{ + PageMeta_Data_t *m = (PageMeta_Data_t*)__meta; + + while (count--) { + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_DATA; + // Don't touch FTLFlags--might have uECC flag + m->c.weaveLo = yaFTL.wrState.weaveSeq; + m->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); + // Don't touch LBA or userSeq + + // Next + m++; + } +} + +void SetupMeta_Cxt(PageMeta_t *__meta, UInt64 weaveSeq) +{ + PageMeta_Cxt_t *m = (PageMeta_Cxt_t*)__meta; + + yaFTL.wrState.weaveSeq++; + + m->c.PageType = PAGETYPE_FTL_CXT; + m->c.FTLFlags = 0; + m->c.weaveLo = weaveSeq; + m->c.weaveHi = (UInt32)(weaveSeq >> 16); + m->__rfu1__ = 0; + m->__rfu2__ = 0; +} + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.h new file mode 100644 index 0000000..b946567 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_ppn.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_META_PPN_H__ +#define __YAFTL_META_PPN_H__ + +#include "yaFTL_whoami.h" +#include "WMROAM.h" + + + +// PageType defines-- +#define PAGETYPE_FTL_DATA (AND_SPARE_TYPE_REGION_FTL + 0x00) +#define PAGETYPE_FTL_BTOC_DATA (AND_SPARE_TYPE_REGION_FTL + 0x1C) +#define PAGETYPE_FTL_BTOC_IDX (AND_SPARE_TYPE_REGION_FTL + 0x1D) +#define PAGETYPE_FTL_IDX (AND_SPARE_TYPE_REGION_FTL + 0x1E) +#define PAGETYPE_FTL_CXT (AND_SPARE_TYPE_REGION_FTL + 0x1F) + + +// FTLFlags defines-- +#define PFLAG_UECC 0x01 // uECC state for data pages (moved by GC and thus re-encoded) + + +// Must be 16 bytes on PPN + +typedef struct { + UInt8 PageType; + UInt8 FTLFlags; + UInt16 weaveLo; + UInt32 weaveHi; +} PageMeta_Common_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 __f1; + UInt32 __f2; +} PageMeta_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 userSeq; + UInt32 lba; +} PageMeta_Data_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 maxWeaveSeqAdd; + UInt32 __rfu__; +} PageMeta_BTOC_t; + +typedef struct { + PageMeta_Common_t c; + UInt16 __rfu__; + UInt16 lbaAdd; + UInt32 baseLba; +} PageMeta_Idx_t; + +typedef struct { + PageMeta_Common_t c; + UInt32 __rfu1__; + UInt32 __rfu2__; +} PageMeta_Cxt_t; + + +typedef UInt64 WeaveSeq_t; + + +// Setup +extern void SetupMeta_Data(PageMeta_t *__meta, UInt32 lba, UInt32 count); +extern void SetupMeta_Data_UECC(PageMeta_t *__meta); + +extern void SetupMeta_Index(PageMeta_t *__meta, UInt32 ipn); + +extern void SetupMeta_Data_BTOC(PageMeta_t *__meta); +extern void SetupMeta_Index_BTOC(PageMeta_t *__meta); + +extern void SetupMeta_IndexGC(PageMeta_t *__meta, UInt32 count); +extern void SetupMeta_DataGC(PageMeta_t *__meta, UInt32 count); + +extern void SetupMeta_Cxt(PageMeta_t *__meta, UInt64 weaveSeq); + +#define META_SET_LBA(meta, foo) do { ((PageMeta_Data_t*)(meta))->lba = (foo); } while (0) +#define META_SET_WEAVESEQ(meta) do { (meta)->c.weaveLo = (UInt16)yaFTL.wrState.weaveSeq; (meta)->c.weaveHi = (UInt32)(yaFTL.wrState.weaveSeq >> 16); } while (0) +#define META_SET_BTOC_DATA(meta) do { (meta)->c.PageType = PAGETYPE_FTL_BTOC_DATA; } while (0) +#define META_SET_IPN_FROM_BTOC(meta, bte) do { ((PageMeta_Idx_t*)(meta))->baseLba = (bte); } while (0) +#define BTOC_SET_FROM_IPN(bte, meta) do { (bte) = ((PageMeta_Idx_t*)(meta))->baseLba; } while (0) + + +// Query +#define BTOC_GET_IPN(bte) ((bte) / yaFTL.indexPageRatio) +#define META_ARE_FLAGS_FF(meta) ((0xff == (meta)->c.PageType) && (0xff == (meta)->c.FTLFlags)) +#define META_IS_IDX(meta) (PAGETYPE_FTL_IDX == (meta)->c.PageType) +#define META_IS_DATA(meta) (PAGETYPE_FTL_DATA == (meta)->c.PageType) +#define META_IS_CXT(meta) (PAGETYPE_FTL_CXT == (meta)->c.PageType) +#define META_IS_BTOC_IDX(meta) (PAGETYPE_FTL_BTOC_IDX == (meta)->c.PageType) +#define META_IS_BTOC_DATA(meta) (PAGETYPE_FTL_BTOC_DATA == (meta)->c.PageType) +#define META_IS_BTOC(meta) ((PAGETYPE_FTL_BTOC_IDX == (meta)->c.PageType) || (PAGETYPE_FTL_BTOC_DATA == ((meta)->c.PageType))) +#define META_IS_UECC(meta) ((meta)->c.FTLFlags & PFLAG_UECC) +#define META_GET_WEAVESEQ(meta) ((UInt64)(meta)->c.weaveLo | ((UInt64)(meta)->c.weaveHi << 16)) +#define META_GET_LBA(meta) (((PageMeta_Data_t*)(meta))->lba) +#define META_GET_IPN(meta) (((PageMeta_Idx_t*)(meta))->baseLba / yaFTL.indexPageRatio) +#define META_GET_IPNRAW(meta) (((PageMeta_Idx_t*)(meta))->baseLba) +#define META_GET_ALL_FLAGS(meta) (((UInt32)((meta)->c.FTLFlags) << 8) | (UInt32)((meta)->c.PageType)) + + + +#endif // __YAFTL_META_PPN_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.c b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.c new file mode 100644 index 0000000..d2a70ba --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include "yaFTL_whoami.h" +#include "yaFTL_meta_raw.h" +#include "WMRConfig.h" +#include "yaFTLTypes.h" + +extern yaFTL_t yaFTL; + + +void SetupMeta_Data(PageMeta_t *meta, UInt32 lba, UInt32 count) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.data.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.data.block; + } + + while (count--) + { + meta->FTLFlags = PAGETYPE_FTL_DATA; + meta->lba = lba; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; + + // Next + lba++; + meta++; + } +} + +void SetupMeta_Data_UECC(PageMeta_t *meta) +{ + meta->FTLFlags |= PFLAG_UECC; +} + +void SetupMeta_Index(PageMeta_t *meta, UInt32 ipn) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.index.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.index.block; + } + + meta->FTLFlags = PAGETYPE_FTL_IDX; + meta->lba = ipn; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; +} + +void SetupMeta_Data_BTOC(PageMeta_t *meta) +{ + meta->FTLFlags = PFLAG_BTOC; + meta->weaveSeq = (UInt32)yaFTL.wrState.data.minWeaveSeq; +} + +void SetupMeta_Index_BTOC(PageMeta_t *meta) +{ + meta->FTLFlags = PAGETYPE_FTL_IDX | PFLAG_BTOC; + meta->weaveSeq = (UInt32)yaFTL.wrState.index.minWeaveSeq; +} + +void SetupMeta_IndexGC(PageMeta_t *meta, UInt32 count) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.index.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.index.block; + } + + while (count--) + { + meta->FTLFlags = PAGETYPE_FTL_IDX; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; + + // Next + meta++; + } +} + +void SetupMeta_DataGC(PageMeta_t *meta, UInt32 count) +{ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.data.block) + { + yaFTL.wrState.weaveSeq++; + yaFTL.wrState.lastBlock = yaFTL.wrState.data.block; + } + + while (count--) + { + // Or in the page type and clear all but uECC flag + meta->FTLFlags = (meta->FTLFlags & PFLAG_UECC) | PAGETYPE_FTL_DATA; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; + + // Next + meta++; + } +} + +void SetupMeta_Cxt(PageMeta_t *meta, UInt64 weaveSeq) +{ + yaFTL.wrState.weaveSeq++; + + meta->FTLFlags = PAGETYPE_FTL_CXT; + meta->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; +} + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.h new file mode 100644 index 0000000..1fb17e6 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_meta_raw.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_META_RAW_H__ +#define __YAFTL_META_RAW_H__ + +#include "yaFTL_whoami.h" +#include "WMROAM.h" + +// Page FTLFlags +#define PAGETYPE_FTL_IDX 0x04 +#define PAGETYPE_FTL_DATA 0x10 +#define PAGETYPE_FTL_CXT 0x20 +#define PFLAG_BTOC 0x08 +#define PFLAG_UECC 0x40 // uECC state (moved by GC and thus re-encoded) + +// Must be 12 bytes on raw +typedef struct +{ + UInt32 lba; // formerly known as logicalPageNo + UInt32 weaveSeq; // formerly known as allocationNo + UInt8 __DEPRECATED_seqNo; + UInt8 FTLFlags; + UInt16 __pad; +} PageMeta_t; + +typedef UInt32 WeaveSeq_t; + + +extern void SetupMeta_Data(PageMeta_t *meta, UInt32 lba, UInt32 count); +extern void SetupMeta_Data_UECC(PageMeta_t *meta); + +extern void SetupMeta_Index(PageMeta_t *meta, UInt32 ipn); + +extern void SetupMeta_Data_BTOC(PageMeta_t *meta); +extern void SetupMeta_Index_BTOC(PageMeta_t *meta); + +extern void SetupMeta_IndexGC(PageMeta_t *meta, UInt32 count); +extern void SetupMeta_DataGC(PageMeta_t *meta, UInt32 count); + +extern void SetupMeta_Cxt(PageMeta_t *meta, UInt64 weaveSeq); + +#define META_SET_LBA(meta, foo) do { (meta)->lba = (foo); } while (0) +#define META_SET_WEAVESEQ(meta) do { \ + if (yaFTL.wrState.lastBlock != yaFTL.wrState.index.block) \ + { \ + yaFTL.wrState.weaveSeq++; \ + yaFTL.wrState.lastBlock = yaFTL.wrState.index.block; \ + } \ + (meta)->weaveSeq = (UInt32)yaFTL.wrState.weaveSeq; \ +} while(0) +#define META_SET_BTOC_DATA(meta) do { (meta)->FTLFlags = PFLAG_BTOC; } while (0) +#define META_SET_IPN_FROM_BTOC(meta, bte) do { (meta)->lba = (bte); } while (0) +#define BTOC_SET_FROM_IPN(bte, meta) do { (bte) = (meta)->lba; } while (0) + + +// Query +#define BTOC_GET_IPN(bte) (bte) +#define META_ARE_FLAGS_FF(meta) (0xff == (meta)->FTLFlags) +#define META_IS_IDX(meta) ((meta)->FTLFlags & PAGETYPE_FTL_IDX) +#define META_IS_DATA(meta) ((meta)->FTLFlags & PAGETYPE_FTL_DATA) +#define META_IS_CXT(meta) ((meta)->FTLFlags & PAGETYPE_FTL_CXT) +#define META_IS_BTOC_IDX(meta) (((meta)->FTLFlags & PAGETYPE_FTL_IDX) && ((meta)->FTLFlags & PFLAG_BTOC)) +#define META_IS_BTOC_DATA(meta) (!((meta)->FTLFlags & PAGETYPE_FTL_IDX) && ((meta)->FTLFlags & PFLAG_BTOC)) +#define META_IS_BTOC(meta) ((meta)->FTLFlags & PFLAG_BTOC) +#define META_IS_UECC(meta) ((meta)->FTLFlags & PFLAG_UECC) +#define META_GET_WEAVESEQ(meta) ((meta)->weaveSeq) +#define META_GET_LBA(meta) ((meta)->lba) +#define META_GET_IPN(meta) ((meta)->lba) +#define META_GET_IPNRAW(meta) ((meta)->lba) +#define META_GET_ALL_FLAGS(meta) ((UInt32)((meta)->FTLFlags)) + + + +#endif // __YAFTL_META_RAW_H__ + diff --git a/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_whoami.h b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_whoami.h new file mode 100644 index 0000000..79fa2b3 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/FTL/yaFTL_whoami.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __YAFTL_WHOAMI_H__ +#define __YAFTL_WHOAMI_H__ + +#define NAND_RAW 1 + +#endif + diff --git a/drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.c b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.c new file mode 100644 index 0000000..2d1b3dc --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.c @@ -0,0 +1,399 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL Buffer Management */ +/* FILE : VFLBuffer.c */ +/* PURPOSE : This file contains routines for managing buffers which */ +/* whimory uses. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 13-JUL-2005 [Jaesung Jung] : separate from vfl.c & reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : fix from code inspection */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Header file inclusions */ +/*****************************************************************************/ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" + +/*****************************************************************************/ +/* Debug Print #defines */ +/*****************************************************************************/ +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) +#define BUF_ERR_PRINT(x) { WMR_RTL_PRINT(x); WMR_PANIC(); } +#else +#define BUF_ERR_PRINT(x) WMR_RTL_PRINT(x) +#endif +#define BUF_RTL_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (BUF_LOG_MSG_ON) +#define BUF_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else +#define BUF_LOG_PRINT(x) +#endif + +#if defined (BUF_INF_MSG_ON) +#define BUF_INF_PRINT(x) WMR_DBG_PRINT(x) +#else +#define BUF_INF_PRINT(x) +#endif + +/*****************************************************************************/ +/* Static variables definitions */ +/*****************************************************************************/ +BUFCxt *pstBufferCxt = NULL; + +typedef struct +{ + UInt16 wBytesPerPage; /* bytes per page (main) */ + UInt16 wBytesPerPageMeta; +} VFLBufferDeviceInfo; +static VFLBufferDeviceInfo stVFLBufferDeviceInfo; + +#define BYTES_PER_PAGE (stVFLBufferDeviceInfo.wBytesPerPage) +#define BYTES_PER_PAGE_META (stVFLBufferDeviceInfo.wBytesPerPageMeta) + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Init */ +/* DESCRIPTION */ +/* This function initializes the buffer manager & the buffer pool. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* BUF_SUCCESS */ +/* BUF_Init is completed. */ +/* BUF_CRITICAL_ERROR */ +/* BUF_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +Int32 +BUF_Init(UInt16 wDataBytesPerPage, UInt16 wMetaBytesPerPage, UInt16 wNumberOfBuffers) +{ + UInt32 nBufIdx; + Buffer *pBufIdx; + + if (pstBufferCxt != NULL) + { + return BUF_SUCCESS; + } + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Init(void)\n"))); + + stVFLBufferDeviceInfo.wBytesPerPage = wDataBytesPerPage; + stVFLBufferDeviceInfo.wBytesPerPageMeta = wMetaBytesPerPage; + + /* Initialize buffer context */ + pstBufferCxt = (BUFCxt *)WMR_MALLOC(sizeof(BUFCxt)); + pstBufferCxt->dwNumOfBuffers = wNumberOfBuffers; + if (pstBufferCxt == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Init(void) BUFCxt Init Failure\n"))); + BUF_Close(); + return BUF_CRITICAL_ERROR; + } + + /* Initialize buffer list */ + pstBufferCxt->pBufferList = (Buffer *)WMR_MALLOC(sizeof(Buffer) * pstBufferCxt->dwNumOfBuffers); + + if (pstBufferCxt->pBufferList == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Init(void) BUFCxt->pBufferList Init Failure\n"))); + BUF_Close(); + return BUF_CRITICAL_ERROR; + } + + pBufIdx = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++) + { +#ifdef WMR_USE_FAKE_POINTERS + /* + * In order to make it possible to DMA to the contents of the buffer pool, + * OAM_Init has already allocated an IOBufferMemoryDescriptor of the appropriate + * size. Thus, we just have to index into it... + */ + extern UInt8 *_OAM_PageBufferPoolBase; + extern UInt8 *_OAM_SpareBufferPoolBase; + pBufIdx->pData = _OAM_PageBufferPoolBase + (nBufIdx * BYTES_PER_PAGE); + pBufIdx->pSpare = _OAM_SpareBufferPoolBase + (nBufIdx * BYTES_PER_PAGE_META); +#else /* !WMR_USE_FAKE_POINTERS */ + pBufIdx->pData = (UInt8 *)WMR_MALLOC(BYTES_PER_PAGE + BYTES_PER_PAGE_META); + pBufIdx->pSpare = pBufIdx->pData + BYTES_PER_PAGE; +#endif + + if (pBufIdx->pData == NULL || pBufIdx->pSpare == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Init(void) pBufIdx->pData, pBufIdx->pSpare Init Failure\n"))); + BUF_Close(); + return BUF_CRITICAL_ERROR; + } + + pBufIdx->pDataBak = pBufIdx->pData; +#ifdef WMR_USE_FAKE_POINTERS /* need to save the spare pointer as it is not contiguous */ + pBufIdx->pSpareBak = pBufIdx->pSpare; +#endif + pBufIdx->eStatus = BUF_FREE; + + pBufIdx++; + } + + pstBufferCxt->nFreeBuffers = pstBufferCxt->dwNumOfBuffers; + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Init(void) nRe=0x%x\n"), BUF_SUCCESS)); + return BUF_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Get */ +/* DESCRIPTION */ +/* This function returns a new free buffer. */ +/* if there is not a free buffer, this function calls the sync function */ +/* and generates a new free buffer. */ +/* PARAMETERS */ +/* eType [IN] */ +/* buffer type */ +/* RETURN VALUES */ +/* Buffer */ +/* BUF_Get is completed. */ +/* NULL */ +/* BUF_Get is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +Buffer * +BUF_Get(BUFType eType) +{ + UInt32 nBufIdx; + Buffer *pBufRet; + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Get(eType = %d)\n"), eType)); + + /* Check buffer context was initialized */ + if (pstBufferCxt == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) Buffer manager is not initialized\n"), eType)); + return NULL; + } + + /* NirW - from the checked in M1 code - Check buffer context was not written over */ + if (pstBufferCxt->pBufferList == NULL) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) Buffer pointer was overwritten!\n"), eType)); + return NULL; + } + + if (pstBufferCxt->nFreeBuffers == 0) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) No free buffer\n"), eType)); + return NULL; + } + + /* Find a free buffer from the buffer pool. */ + pBufRet = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++, pBufRet++) + { + if (pBufRet->eStatus == BUF_FREE) + { + break; + } + } + + if (nBufIdx >= pstBufferCxt->dwNumOfBuffers) + { + BUF_ERR_PRINT((TEXT("[BUF:ERR] BUF_Get(eType = %d) Can't find a free buffer\n"), eType)); + return NULL; + } + + /* Check the buffer type */ + if (eType == BUF_SPARE_ONLY) + { + pBufRet->pData = NULL; + } + else if (eType == BUF_MAIN_ONLY) + { + pBufRet->pSpare = NULL; + } + + /* Initialize the spare buffer */ + if (eType != BUF_MAIN_ONLY) + { + WMR_MEMSET(pBufRet->pSpare, 0xFF, BYTES_PER_PAGE_META); + } + + /* Change the buffer status & bitmap */ + pBufRet->eStatus = BUF_ALLOCATED; +/* pBufRet->nBitmap = 0; */ + + /* Decrease the number of free buffers */ + pstBufferCxt->nFreeBuffers--; + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Get(eType = %d)\n"), eType)); + + return pBufRet; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Release */ +/* DESCRIPTION */ +/* This function releases the buffer to the buffer pool. */ +/* PARAMETERS */ +/* pBuf [IN] */ +/* buffer pointer */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +void +BUF_Release(Buffer *pBuf) +{ + UInt16 wIdx; + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Release(pBuf = %x)\n"), pBuf)); + + if (pBuf == NULL) + { + return; + } + + //WMR_ASSERT((pBuf - pstBufferCxt->pBufferList) >= 0 && +// (pBuf - pstBufferCxt->pBufferList) < pstBufferCxt->dwNumOfBuffers); + for (wIdx = 0; wIdx < pstBufferCxt->dwNumOfBuffers; wIdx++) + { + if (pBuf == &pstBufferCxt->pBufferList[wIdx]) + { + break; + } + } + WMR_ASSERT(wIdx < pstBufferCxt->dwNumOfBuffers); + /* NirW */ + if (pBuf->eStatus == BUF_FREE) + { + return; + } + + WMR_ASSERT(pBuf->eStatus == BUF_ALLOCATED); + + /* Reinitialize the buffer */ + pBuf->pData = pBuf->pDataBak; +#ifdef WMR_USE_FAKE_POINTERS /* need to restore non-adjacent spare pointer */ + pBuf->pSpare = pBuf->pSpareBak; +#else + pBuf->pSpare = pBuf->pDataBak + BYTES_PER_PAGE; +#endif + + pBuf->eStatus = BUF_FREE; + + pstBufferCxt->nFreeBuffers++; + + WMR_ASSERT(pstBufferCxt->nFreeBuffers <= pstBufferCxt->dwNumOfBuffers); + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Release(pBuf = %x)\n"), pBuf)); + + return; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* BUF_Close */ +/* DESCRIPTION */ +/* This function releases buffer manager context. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +void +BUF_Close(void) +{ + UInt32 nBufIdx; + Buffer *pBufIdx; + + BUF_LOG_PRINT((TEXT("[BUF: IN] ++BUF_Close(void)\n"))); + + if (pstBufferCxt != NULL) + { + if (pstBufferCxt->pBufferList != NULL) + { + pBufIdx = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++) + { +#ifndef WMR_USE_FAKE_POINTERS + WMR_FREE(pBufIdx->pDataBak, (BYTES_PER_PAGE + BYTES_PER_PAGE_META)); +#endif + pBufIdx->pData = NULL; + pBufIdx->pSpare = NULL; + + pBufIdx++; + } + + WMR_FREE(pstBufferCxt->pBufferList, (sizeof(Buffer) * pstBufferCxt->dwNumOfBuffers)); + + pstBufferCxt->pBufferList = NULL; + } + + WMR_FREE(pstBufferCxt, sizeof(BUFCxt)); + + pstBufferCxt = NULL; + } + + BUF_LOG_PRINT((TEXT("[BUF:OUT] --BUF_Close(void)\n"))); + + return; +} + +void +BUF_ReleaseAllBuffers(void) +{ + UInt32 nBufIdx; + Buffer *pBufIdx; + + pBufIdx = pstBufferCxt->pBufferList; + + for (nBufIdx = 0; nBufIdx < pstBufferCxt->dwNumOfBuffers; nBufIdx++) + { + BUF_Release(pBufIdx); + pBufIdx++; + } +} + diff --git a/drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.h b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.h new file mode 100644 index 0000000..b13e6e7 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLBuffer.h @@ -0,0 +1,104 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL Buffer Management */ +/* FILE : VFLBuffer.h */ +/* PURPOSE : This file contains routines for managing buffers which */ +/* whimory uses. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 13-JUL-2005 [Jaesung Jung] : separate from vfl.c & reorganize code */ +/* */ +/*****************************************************************************/ + +#ifndef _VFL_BUFFER_H_ +#define _VFL_BUFFER_H_ + +/*****************************************************************************/ +/* Return value of BUF_XXX() */ +/*****************************************************************************/ +#define BUF_SUCCESS ANDErrorCodeOk +#define BUF_CRITICAL_ERROR ANDErrorCodeAllocFailErr + +/*****************************************************************************/ +/* Buffer state enum definition */ +/*****************************************************************************/ +typedef enum +{ + BUF_FREE = 0x10000000, /* the buffer is free */ + BUF_ALLOCATED = 0x10000001, /* the buffer is allocated to some layer */ +} BUFStat; + +/*****************************************************************************/ +/* Buffer type enum & macro definition */ +/*****************************************************************************/ +typedef enum +{ + BUF_MAIN_AND_SPARE = 0x10000000, /* to get a buffer which has main & spare*/ + BUF_MAIN_ONLY = 0x10000001, /* to get a buffer which has main only */ + BUF_SPARE_ONLY = 0x10000002 /* to get a buffer which has spare only */ +} BUFType; + +#define BITMAP_FULL_PAGE ((1 << SECTORS_PER_PAGE) - 1) + +/*****************************************************************************/ +/* Buffer structure definition */ +/*****************************************************************************/ +typedef struct Buf +{ + UInt8 *pData; /* buffer area for main area */ + UInt8 *pSpare; /* buffer area for spare area */ +// UInt32 nBitmap; /* valid sector bitmap for pData */ + BUFStat eStatus; /* the status of buffer */ + UInt8 *pDataBak; /* the original pointer of data buffer */ +#ifdef WMR_USE_FAKE_POINTERS /* data and spare buffers are not adjacent */ + UInt8 *pSpareBak; /* the original pointer of spare buffer */ +#endif +} Buffer; + +typedef struct +{ + Buffer *pBufferList; /* the list of all the buffers */ + UInt32 nFreeBuffers; /* the count of free buffers */ + UInt32 dwNumOfBuffers; +} BUFCxt; + +/*****************************************************************************/ +/* exported function prototype of VFL buffer manager */ +/*****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +Int32 BUF_Init(UInt16 wDataBytesPerPage, UInt16 wMetaBytesPerPage, UInt16 wNumberOfBuffers); +Buffer *BUF_Get(BUFType eType); +void BUF_Release(Buffer *pBuf); +void BUF_Close(void); +void BUF_ReleaseAllBuffers(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _VFL_BUFFER_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Core/VFL/VFLInterface.c b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLInterface.c new file mode 100644 index 0000000..490ea88 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLInterface.c @@ -0,0 +1,2374 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL interface */ +/* FILE : VFLinterface.c */ +/* PURPOSE : This file contains the exported routine for interfacing with*/ +/* the upper layer of VFL. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 16-SEP-2003 [SJ Myoung] : multi-block read speed up */ +/* flash_read(,,,UInt8 sector_offset) add argument */ +/* 22-SEP-2003 [JH Kim] : buf_get() bug-fix (if no free buffer) */ +/* 29-SEP-2003 [HM Jung] : code size reduction */ +/* check init bad from PAGE_CLEAN */ +/* 03-NOV-2003 [JH Kim] : replace_bad_block() - add loop when erase */ +/* if erase fail */ +/* 12-JAN-2004 [JH Kim] : fix by sequential order */ +/* 26-JAN-2004 [JH Kim] : add buffer usage trace code */ +/* 13-MAR-2005 [Jaesung Jung] : duet port */ +/* 21-MAR-2005 [Jaesung Jung] : move ASSERT DEFINE to copy_data.h */ +/* 21-MAR-2005 [Jaesung Jung] : remove pattern_test code */ +/* 28-MAR-2005 [Jaesung Jung] : add logical to physical API */ +/* 07-APR-2005 [Jaesung Jung] : MLC support (2way) */ +/* 08-APR-2005 [Jaesung Jung] : add context checksum check */ +/* 11-APR-2005 [Jaesung Jung] : optimize PAGE_CLEAN check */ +/* 18-JUL-2005 [Jaesung Jung] : reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : bug-fix from code inspection */ +/* 22-NOV-2005 [Yangsup Lee ] : remove checksum code */ +/* 24-JAN-2006 [Yangsup Lee ] : change sector offset to sector bitmap */ +/* 24-JAN-2006 [Yangsup Lee ] : support un-pair bad block management */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Header file inclusions */ +/*****************************************************************************/ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "VFLTypes.h" +#include "FPart.h" +#include "VFL.h" +#include "FIL.h" +#if AND_SUPPORT_LEGACY_VFL +/*****************************************************************************/ +/* Debug Print #defines */ +/*****************************************************************************/ + +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) +#define VFL_ERR_PRINT(x) { WMR_RTL_PRINT(x); WMR_PANIC(); } +#else +#define VFL_ERR_PRINT(x) WMR_RTL_PRINT(x) +#endif +#define VFL_WRN_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (VFL_LOG_MSG_ON) +#define VFL_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else +#define VFL_LOG_PRINT(x) +#endif + +#if defined (VFL_INF_MSG_ON) +#define VFL_INF_PRINT(x) WMR_DBG_PRINT(x) +#else +#define VFL_INF_PRINT(x) +#endif + +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Static variables definitions */ +/*****************************************************************************/ +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) +VFLMeta *pstVFLMeta = NULL; +#else +static VFLMeta *pstVFLMeta = NULL; +#endif +static UInt32 * pstadwScatteredReadPpn = NULL; +static UInt16 * pstawScatteredReadBank = NULL; + +static LowFuncTbl *pFuncTbl = NULL; +static UInt8 *pstBBTArea = NULL; +static VFLWMRDeviceInfo stVFLDeviceInfo; +static FPartFunctions stFPartFunctions; + +static UInt32 gdwMaxGlobalAge; +#ifdef AND_COLLECT_STATISTICS +static VFLStatistics stVFLStatistics; +#endif +/*****************************************************************************/ +/* Definitions */ +/*****************************************************************************/ +#define GET_VFLCxt(v) (&(pstVFLMeta + (v))->stVFLCxt) +#define GET_AsyncOp(v) (pstAsyncOp + (v)) +#define GET_Ppn(Pbn, POffset) ((Pbn) * PAGES_PER_BLOCK + (POffset)) /* transalte block + pages offset to page address*/ +#define GET_Pbn(Ppn) ((UInt16)((UInt32)(Ppn) / PAGES_PER_BLOCK)) +/*****************************************************************************/ +/* VFL local function prototypes */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Static function prototypes */ +/*****************************************************************************/ +static void _GetVFLSpare(UInt32 *pAge, UInt8 *pStatus, + UInt8 *pbType, UInt8 *pSBuf); +#ifndef AND_READONLY +static void _SetVFLSpare(UInt32 *pAge, UInt8 *pSBuf); +static BOOL32 _StoreVFLCxt(UInt16 wBank); + +static BOOL32 _GetReservedBlk(UInt16 wBank, UInt16 wPbn, + UInt16 *pwIdx); +static BOOL32 _ReplaceBadBlk(UInt16 wBank, UInt16 wSrcPbn, + UInt16 *pwDesPbn); +#endif +static BOOL32 _LoadVFLCxt(UInt16 wBank, UInt8 *pabBBT); +static void _RemapBadBlk(UInt16 wBank, UInt16 wSrcPbn, + UInt16 *pwDesPbn); +static void _GetPhysicalAddr(UInt32 dwVpn, UInt16 *pwBank, + UInt16 *pwPbn, UInt16 *pwPOffset); + +#ifndef AND_READONLY +static BOOL32 _AddBlockToScrubList(UInt16 wBank, UInt16 wVbnToScrub); +static BOOL32 _RemoveBlockFromScrubList(UInt16 wBank, UInt16 wVbnToScrub); +static BOOL32 _IsBlockInScrubList(UInt16 wBank, UInt16 wVbnToScrub); +#endif + +#ifndef AND_READONLY +static Int32 VFL_Format(UInt32 dwBootAreaSize, UInt32 dwOptions); +static Int32 VFL_Write(UInt32 nVpn, Buffer *pBuf, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening); +static Int32 VFL_Erase(UInt16 wVbn, BOOL32 bReplaceOnFail); +static Int32 VFL_ChangeFTLCxtVbn(UInt16 *aFTLCxtVbn); +static BOOL32 VFL_WriteMultiplePagesInVb(UInt32 dwVpn, UInt16 wNumPagesToWrite, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening); +#endif // ! AND_READONLY +static Int32 VFL_Init(FPartFunctions * pFPartFunctions); +static Int32 VFL_Open(UInt32 dwBootAreaSize, UInt32 minor_ver, UInt32 dwOptions); +static void VFL_Close(void); +static BOOL32 VFL_ReadMultiplePagesInVb(UInt16 wVbn, UInt16 wStartPOffset, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pabSectorStat, BOOL32 bDisableWhitening); +static BOOL32 VFL_ReadScatteredPagesInVb(UInt32 * padwVpn, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pabSectorStat, BOOL32 bDisableWhitening, Int32 *actualStatus); +static Int32 VFL_Read(UInt32 nVpn, Buffer *pBuf, BOOL32 bCleanCheck, BOOL32 bMarkECCForScrub, BOOL32 * pboolNeedRefresh, UInt8 * pabSectorStat, BOOL32 bDisableWhitening); +static UInt16* VFL_GetFTLCxtVbn(void); +//static BOOL32 VFL_GetAddress (ANDAddressStruct * pANDAddressStruct); +static BOOL32 VFL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); +static BOOL32 VFL_SetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 dwStructSize); +static UInt32 VFL_GetDeviceInfo(UInt32 dwParamType); + +#define BLOCK_IS_BAD 0 +#define BLOCK_IS_GOOD 1 + +#define WMR_NUM_COPIES_OF_DEVICE_INFO_INDEX (8) +#define WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS (4) +#define WMR_MAX_ERRORS_WRITING_INDEX_BLOCKS (4) + +#define WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS (3) + +#define VFL_NUM_OF_VFL_CXT_COPIES (8) +#define VFL_MAX_NUM_OF_VFL_CXT_ERRORS (3) + +#define VFL_INVALID_INFO_INDEX (0xFFFF) + +/* + + NAME + MARK_BLOCK_AS_BAD + DESCRIPTION + This define marks block as bad in the bbt. + PARAMETERS + pBBT [IN] bbt buffer + idx [IN] block index + RETURN VALUES + none + NOTES + + */ + +#define MARK_BLOCK_AS_BAD(pBBT, idx) \ + { \ + UInt16 dByteLocation; \ + UInt8 bBit; \ + dByteLocation = ((UInt16)(idx)) >> 3; \ + bBit = (UInt8)(~(1 << (((UInt8)(idx)) & 0x07))); \ + ((UInt8 *)(pBBT))[dByteLocation] &= bBit; \ + } + +/* + + NAME + MARK_BLOCK_AS_GOOD + DESCRIPTION + This define marks block as good in the bbt. + PARAMETERS + pBBT [IN] bbt buffer + idx [IN] block index + RETURN VALUES + none + NOTES + + */ +#define MARK_BLOCK_AS_GOOD(pBBT, idx) \ + { \ + UInt16 dByteLocation; \ + UInt8 bBit; \ + dByteLocation = ((UInt16)(idx)) >> 3; \ + bBit = (1 << (((UInt8)(idx)) & 0x07)); \ + ((UInt8 *)(pBBT))[dByteLocation] |= bBit; \ + } + +static void _NANDCheckSum(UInt32 * pbaData, UInt32 dwDataSize, UInt32 * pdwCheckSum1, UInt32 * pdwCheckSum2) +{ + UInt32 dwIdx; + UInt32 dwXorsum; + UInt32 dwChecksum; + + dwChecksum = 0; + dwXorsum = 0; + for (dwIdx = 0; dwIdx < (dwDataSize / 4); dwIdx++) + { + dwChecksum += pbaData[dwIdx]; + dwXorsum ^= pbaData[dwIdx]; + } + /* avoid passing when vflcxt is zeroed */ + *pdwCheckSum1 = dwChecksum + 0xAABBCCDD; + *pdwCheckSum2 = dwXorsum ^ 0xAABBCCDD; +} + +static BOOL32 _CheckVFLCxtDataIsUntouched(UInt16 wBank) +{ + UInt32 dwTempCheckSum; + UInt32 dwTempXor; + static UInt32 dwCount = 0; + + dwCount++; + _NANDCheckSum((UInt32*)&pstVFLMeta[wBank], (sizeof(VFLMeta) - (2 * sizeof(UInt32))), &dwTempCheckSum, &dwTempXor); + if (!(dwTempCheckSum == pstVFLMeta[wBank].dwCheckSum) && (dwTempXor == pstVFLMeta[wBank].dwXorSum)) + { + return FALSE32; + } + return TRUE32; +} +static void _UpdateVFLCxtChecksum(UInt16 wBank) +{ + _NANDCheckSum((UInt32*)&pstVFLMeta[wBank], (sizeof(VFLMeta) - (2 * sizeof(UInt32))), &pstVFLMeta[wBank].dwCheckSum, &pstVFLMeta[wBank].dwXorSum); +} + +typedef struct +{ + void (*UpdateChecksum)(UInt16 wBank); + BOOL32 (*VerifyChecksum)(UInt16 wBank); +} ChecksumFuncStruct; + +static ChecksumFuncStruct vflChecksumFunc; + +#define RECALC_VFL_CXT_CHECK_SUM(bank) vflChecksumFunc.UpdateChecksum(bank) + +#define CHECK_VFL_CXT_CHECK_SUM(bank) \ + { \ + if (vflChecksumFunc.VerifyChecksum(bank) == FALSE32) { \ + WMR_ASSERT(0); } \ + } + +#define CHECK_VFL_CXT_CHECK_SUM_NO_ASSERT(bank) vflChecksumFunc.VerifyChecksum(bank) + +#ifndef AND_READONLY +static BOOL32 +_AddBlockToScrubList(UInt16 wBank, UInt16 wVbnToScrub) +{ + UInt16 wScrubIdx = WMR_MAX_RESERVED_SIZE; + VFLCxt * pVFLCxt = GET_VFLCxt(wBank); + + if (_IsBlockInScrubList(wBank, wVbnToScrub) == TRUE32) + { + return TRUE32; + } + + /* check if the list is not empty */ + if (pVFLCxt->wBadMapTableScrubIdx != WMR_MAX_RESERVED_SIZE) + { + /* check that the block in not allready in the list */ + while (--wScrubIdx && (pVFLCxt->wBadMapTableScrubIdx <= wScrubIdx)) + { + if (pVFLCxt->aBadMapTable[wScrubIdx] == wVbnToScrub) + { + return TRUE32; + } + } + } + /* make sure we do not get close to the wBadMapTableMaxIdx */ + if (pVFLCxt->wBadMapTableScrubIdx == (pVFLCxt->wBadMapTableMaxIdx + 10)) + { + return FALSE32; + } + CHECK_VFL_CXT_CHECK_SUM(wBank); + pVFLCxt->wBadMapTableScrubIdx--; + pVFLCxt->aBadMapTable[pVFLCxt->wBadMapTableScrubIdx] = wVbnToScrub; + RECALC_VFL_CXT_CHECK_SUM(wBank); + return _StoreVFLCxt(wBank); +} + +static BOOL32 +_RemoveBlockFromScrubList(UInt16 wBank, UInt16 wVbnToScrub) +{ + UInt16 wScrubIdx = WMR_MAX_RESERVED_SIZE; + VFLCxt * pVFLCxt = GET_VFLCxt(wBank); + + /* check if the list is not empty */ + if (pVFLCxt->wBadMapTableScrubIdx != WMR_MAX_RESERVED_SIZE) + { + /* check that the block in not allready in the list */ + while (--wScrubIdx && (pVFLCxt->wBadMapTableScrubIdx <= wScrubIdx)) + { + if (pVFLCxt->aBadMapTable[wScrubIdx] == wVbnToScrub) + { + CHECK_VFL_CXT_CHECK_SUM(wBank); + pVFLCxt->aBadMapTable[wScrubIdx] = 0; + /* we found the block - if it is in the middle of the list replace it with the bottom one */ + if ((wScrubIdx != pVFLCxt->wBadMapTableScrubIdx) && (pVFLCxt->wBadMapTableScrubIdx != (WMR_MAX_RESERVED_SIZE - 1))) + { + pVFLCxt->aBadMapTable[wScrubIdx] = pVFLCxt->aBadMapTable[pVFLCxt->wBadMapTableScrubIdx]; + } + pVFLCxt->wBadMapTableScrubIdx++; + RECALC_VFL_CXT_CHECK_SUM(wBank); + return _StoreVFLCxt(wBank); + } + } + } + return FALSE32; +} + +static BOOL32 +_IsBlockInScrubList(UInt16 wBank, UInt16 wVbnToScrub) +{ + UInt16 wScrubIdx = WMR_MAX_RESERVED_SIZE; + VFLCxt * pVFLCxt = GET_VFLCxt(wBank); + + /* check if the list is not empty */ + if (pVFLCxt->wBadMapTableScrubIdx != WMR_MAX_RESERVED_SIZE) + { + /* check that the block in not allready in the list */ + while (--wScrubIdx && (pVFLCxt->wBadMapTableScrubIdx <= wScrubIdx)) + { + if (pVFLCxt->aBadMapTable[wScrubIdx] == wVbnToScrub) + { + return TRUE32; + } + } + } + return FALSE32; +} +#endif // AND_READONLY + +static BOOL32 _isBlockGood(UInt8 * pbaBBT, UInt16 wIdx) +{ + UInt16 dByteLocation; + UInt8 bBit; + + dByteLocation = ((UInt16)wIdx) >> 3; + bBit = (1 << (((UInt8)wIdx) & 0x07)); + if (pbaBBT[dByteLocation] & bBit) + { + return TRUE32; + } + return FALSE32; +} + +BOOL32 _isBadMarkTableMarkGood(UInt8 * pbaBadMark, UInt16 wPbn) +{ + UInt32 dwByteOffset, dwBitOffset; + UInt8 bValue; + + dwByteOffset = wPbn / BAD_MARK_COMPRESS_SIZE / 8; + dwBitOffset = 7 - (wPbn / BAD_MARK_COMPRESS_SIZE) % 8; + bValue = pbaBadMark[dwByteOffset]; + + if (!((bValue >> dwBitOffset) & 0x1)) + { + return FALSE32; + } + return TRUE32; +} + +void _SetBadMarkTable(UInt8 * pbaBadMark, UInt16 wPbn, BOOL32 boolGood) +{ + UInt32 dwByteOffset, dwBitOffset; + + dwByteOffset = wPbn / BAD_MARK_COMPRESS_SIZE / 8; + dwBitOffset = 7 - (wPbn / BAD_MARK_COMPRESS_SIZE) % 8; + + if (boolGood) + { + pbaBadMark[dwByteOffset] |= (1 << dwBitOffset); + } + else + { + pbaBadMark[dwByteOffset] &= ~(1 << dwBitOffset); + } +} + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ +/*****************************************************************************/ +/* */ +/* NAME */ +/* _GetVFLSpare */ +/* DESCRIPTION */ +/* This function returns VFL context info from spare area. */ +/* PARAMETERS */ +/* *pdwAge [OUT] the pointer of context age */ +/* *pStatus [OUT] the pointer of status mark */ +/* *pSBu [IN] the pointer of spare buffer */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static void +_GetVFLSpare(UInt32 *pdwAge, UInt8 *pStatus, UInt8 *pbType, UInt8 *pSBuf) +{ + VFLSpare *pSpare = (VFLSpare *)pSBuf; + + if (pdwAge != NULL) + { + *pdwAge = pSpare->dwCxtAge; + } + if (pbType != NULL) + { + *pbType = pSpare->bSpareType; + } + if (pStatus != NULL) + { + *pStatus = pSpare->cStatusMark; + } +} + +/* + + NAME + _SetVFLSpare + DESCRIPTION + This function stores VFL context info on spare area. + PARAMETERS + *pdwAge [OUT] the pointer of context age + *pSBuf [IN] the pointer of spare buffer + RETURN VALUES + none + NOTES + + */ +#ifndef AND_READONLY +static void +_SetVFLSpare(UInt32 *pdwAge, UInt8 *pSBuf) +{ + VFLSpare *pSpare = (VFLSpare *)pSBuf; + + if (pdwAge != NULL) + { + pSpare->dwCxtAge = *pdwAge; + } + /* the status mark of MLC is always valid */ + pSpare->cStatusMark = PAGE_VALID; + pSpare->bSpareType = VFL_SPARE_TYPE_CXT; +} + +/* writes the VFLCxt 8 times to and verifies it was written properly at least 5 times */ +static BOOL32 _WriteVFLCxtToFlash(UInt16 wBank) +{ + UInt16 wPageIdx, wNumOfErrors; + UInt32 dwCxtAge; + Buffer *pBuf = NULL; + VFLCxt *pVFLCxt; + BOOL32 boolWriteVFLCxtSuccess = FALSE32; + UInt16 wCurrCxtPOffset; + + VFL_LOG_PRINT((TEXT("[VFL:INF] ++_WriteVFLCxtToFlash(wBank:%d)\n"), wBank)); + + /* check current state */ + if (wBank >= BANKS_TOTAL) + { + return FALSE32; + } + + pVFLCxt = GET_VFLCxt(wBank); + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuf == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] error BUF_Get(line:%d)\n"), __LINE__)); + return FALSE32; + } + CHECK_VFL_CXT_CHECK_SUM(wBank); + dwCxtAge = --(pVFLCxt->dwCxtAge); + pVFLCxt->dwGlobalCxtAge = ++gdwMaxGlobalAge; + wCurrCxtPOffset = pVFLCxt->wNextCxtPOffset; + pVFLCxt->wNextCxtPOffset += VFL_NUM_OF_VFL_CXT_COPIES; + RECALC_VFL_CXT_CHECK_SUM(wBank); + WMR_MEMCPY(pBuf->pData, &pstVFLMeta[wBank], sizeof(VFLMeta)); + + /* writing the information */ + for (wPageIdx = 0; wPageIdx < VFL_NUM_OF_VFL_CXT_COPIES; wPageIdx++) + { + WMR_MEMSET(pBuf->pSpare, 0xFF, BYTES_PER_METADATA_RAW); + _SetVFLSpare(&dwCxtAge, pBuf->pSpare); + + /* we are not checking the result of the operation here - we will check the content below using read */ + if (pFuncTbl->Write(wBank, GET_Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], + (wCurrCxtPOffset + wPageIdx)), pBuf->pData, pBuf->pSpare, FALSE32) != FIL_SUCCESS) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] _WriteVFLCxtToFlash failed write (0x%X, 0x%X) (line:%d)\n"), + wBank, GET_Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], (wCurrCxtPOffset + wPageIdx)), __LINE__)); + BUF_Release(pBuf); + return FALSE32; + } + } + + wNumOfErrors = 0; + + for (wPageIdx = 0; wPageIdx < VFL_NUM_OF_VFL_CXT_COPIES; wPageIdx++) + { + Int32 nFILRet; + nFILRet = pFuncTbl->ReadWithECC(wBank, GET_Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], + (wCurrCxtPOffset + wPageIdx)), pBuf->pData, pBuf->pSpare, NULL, NULL, FALSE32); + if (nFILRet == FIL_SUCCESS) + { + UInt8 bStatusMark, bSpareType; + _GetVFLSpare(&dwCxtAge, &bStatusMark, &bSpareType, pBuf->pSpare); + if ((WMR_MEMCMP(pBuf->pData, pVFLCxt, sizeof(VFLCxt)) != 0) || (dwCxtAge != pVFLCxt->dwCxtAge) || (bStatusMark != PAGE_VALID) || (bSpareType != VFL_SPARE_TYPE_CXT)) + { + wNumOfErrors++; + } + } + else + { + wNumOfErrors++; + } + } + + if (wNumOfErrors <= VFL_MAX_NUM_OF_VFL_CXT_ERRORS) + { + boolWriteVFLCxtSuccess = TRUE32; + } + else + { + VFL_ERR_PRINT((TEXT("[VFL:WRN] Fail writing VFLCxt(line:%d) bank %d block %d page %d\n"), __LINE__, wBank, pVFLCxt->wCxtLocation, wCurrCxtPOffset)); + } + + BUF_Release(pBuf); + VFL_LOG_PRINT((TEXT("[VFL: IN] --_WriteVFLCxtToFlash(wBank:%d)\n"), wBank)); + return boolWriteVFLCxtSuccess; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _StoreVFLCxt */ +/* DESCRIPTION */ +/* This function stores VFL context on VFL area. */ +/* PARAMETERS */ +/* wBank bank number */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _StoreVFLCxt is completed */ +/* FALSE32 */ +/* _StoreVFLCxt is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ + +/* + Changes in _StoreVFLCxt: + - store several copies of the same context information (8 copies of the same data). + - after each write, sync and verify the content - fail the current block if 4 out of the 8 do not match or do not pass ECC. + - + */ +static BOOL32 +_StoreVFLCxt(UInt16 wBank) +{ + VFLCxt *pVFLCxt; + BOOL32 boolWriteVFLCxtSuccess = FALSE32; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_StoreVFLCxt(wBank:%d)\n"), wBank)); + + /* check current state */ + if (wBank >= BANKS_TOTAL) + { + return FALSE32; + } + + pVFLCxt = GET_VFLCxt(wBank); + + /* check if we still have space in the current block */ + if ((pVFLCxt->wNextCxtPOffset + VFL_NUM_OF_VFL_CXT_COPIES) <= PAGES_PER_BLOCK) + { + // -> we have space in the current block + + /* write copies in the current block */ + boolWriteVFLCxtSuccess = _WriteVFLCxtToFlash(wBank); + } + + if (boolWriteVFLCxtSuccess == FALSE32) + { + // -> we do NOT have space in the current block or write operation in the current block failed + UInt16 wVFLCxtBlkIdx, wOriginalCxtLocation; + /* search for a valid erase unit we can write to */ + wOriginalCxtLocation = pVFLCxt->wCxtLocation; + wVFLCxtBlkIdx = (pVFLCxt->wCxtLocation + 1) % VFL_INFO_SECTION_SIZE; + while (wVFLCxtBlkIdx != wOriginalCxtLocation) + { + UInt16 wEraseCnt; + + /* check if this index point to a valid block */ + if (pVFLCxt->awInfoBlk[wVFLCxtBlkIdx] == VFL_INVALID_INFO_INDEX) + { + wVFLCxtBlkIdx = (wVFLCxtBlkIdx + 1) % VFL_INFO_SECTION_SIZE; + continue; + } + + /* block is valid try to erase it - up to x times */ + for (wEraseCnt = 0; wEraseCnt < WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS; wEraseCnt++) + { + Int32 nFILRet; + nFILRet = pFuncTbl->Erase(wBank, pVFLCxt->awInfoBlk[wVFLCxtBlkIdx]); + if (nFILRet == FIL_SUCCESS) + { + break; + } + } + + if (wEraseCnt == WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS) + { + // pVFLCxt->awInfoBlk[wVFLCxtBlkIdx] = VFL_INVALID_INFO_INDEX; + VFL_ERR_PRINT((TEXT("[VFL:ERR] Fail erasing VFLBlock bank %d block 0x%X (line:%d)\n"), wBank, pVFLCxt->awInfoBlk[wVFLCxtBlkIdx], __LINE__)); + wVFLCxtBlkIdx = (wVFLCxtBlkIdx + 1) % VFL_INFO_SECTION_SIZE; + continue; + } + + CHECK_VFL_CXT_CHECK_SUM(wBank); + pVFLCxt->wCxtLocation = wVFLCxtBlkIdx; + pVFLCxt->wNextCxtPOffset = 0; + RECALC_VFL_CXT_CHECK_SUM(wBank); + + boolWriteVFLCxtSuccess = _WriteVFLCxtToFlash(wBank); + if (boolWriteVFLCxtSuccess == FALSE32) + { + wVFLCxtBlkIdx = (wVFLCxtBlkIdx + 1) % VFL_INFO_SECTION_SIZE; + continue; + } + else + { + break; + } + } + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_StoreVFLCxt(wBank:%d)\n"), wBank)); + if (boolWriteVFLCxtSuccess == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _StoreVFLCxt(line:%d) fail bank %d!\n"), __LINE__, wBank)); + } + + return boolWriteVFLCxtSuccess; +} +#endif + +static BOOL32 _ReadVFLCxtFromFlash(UInt16 wBank, UInt16 wBlk, UInt16 wStartPOffset, Buffer * pBuf) +{ + Int32 nFILRet; + UInt16 wPageIdx; + + for (wPageIdx = 0; wPageIdx < VFL_NUM_OF_VFL_CXT_COPIES; wPageIdx++) + { + nFILRet = pFuncTbl->ReadWithECC(wBank, GET_Ppn(wBlk, (wStartPOffset + wPageIdx)), pBuf->pData, pBuf->pSpare, NULL, NULL, FALSE32); + if (nFILRet == FIL_SUCCESS) + { + UInt8 bStatus, bSpareType; + /* verify the status byte */ + _GetVFLSpare(NULL, &bStatus, &bSpareType, pBuf->pSpare); + if (bStatus == PAGE_VALID && bSpareType == VFL_SPARE_TYPE_CXT) + { + return TRUE32; + } + } + } + return FALSE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _LoadVFLCxt */ +/* DESCRIPTION */ +/* This function loads VFL context from VFL area. */ +/* PARAMETERS */ +/* wBank bank number */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _LoadVFLCxt is completed */ +/* FALSE32 */ +/* _LoadVFLCxt is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_LoadVFLCxt(UInt16 wBank, UInt8 * pabBBT) +{ + VFLCxt *pVFLCxt; + UInt16 wBlkIdx, wPOffsetIdx; + Buffer *pBuf = NULL; + UInt32 dwMinAge; + UInt16 wNewCxt, wNewPOffset; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_LoadVFLCxt(wBank:%d)\n"), wBank)); + + /* check current state */ + if (wBank >= BANKS_TOTAL) + { + return FALSE32; + } + + pVFLCxt = GET_VFLCxt(wBank); + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pBuf == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(wBank:%d) failed BUF_Get(line:%d)\n"), wBank, __LINE__)); + return FALSE32; + } + + /* first thing - find the first block with VFLCxt information and extract the awInfoBlk from it */ + for (wBlkIdx = VFL_AREA_START; wBlkIdx < VFL_AREA_SIZE; wBlkIdx++) + { + if (_isBlockGood(pabBBT, wBlkIdx) == TRUE32) + { + if (_ReadVFLCxtFromFlash(wBank, wBlkIdx, 0, pBuf) == TRUE32) + { + VFLCxt *pVFLCxtTemp; + pVFLCxtTemp = (VFLCxt *)pBuf->pData; + WMR_MEMCPY(pVFLCxt->awInfoBlk, pVFLCxtTemp->awInfoBlk, (sizeof(UInt16) * VFL_INFO_SECTION_SIZE)); + break; + } + } + } + if (wBlkIdx == VFL_AREA_SIZE) + { + BUF_Release(pBuf); + /* we should never get here - getting here means we fail to find a valid VFLCxt in the VFL_AREA */ + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(line:%d) fail bank %d!\n"), __LINE__, wBank)); + return FALSE32; + } + + /* look for the youngest VFLCxt block */ + dwMinAge = 0xFFFFFFFF; + wNewCxt = VFL_INFO_SECTION_SIZE; + for (wBlkIdx = 0; wBlkIdx < VFL_INFO_SECTION_SIZE; wBlkIdx++) + { + UInt32 dwAge; + + if (pVFLCxt->awInfoBlk[wBlkIdx] != VFL_INVALID_INFO_INDEX) + { + if (_ReadVFLCxtFromFlash(wBank, pVFLCxt->awInfoBlk[wBlkIdx], 0, pBuf) == FALSE32) + { + continue; + } + } + else + { + continue; + } + _GetVFLSpare(&dwAge, NULL, NULL, pBuf->pSpare); + if (dwMinAge >= dwAge && dwAge != 0) + { + wNewCxt = wBlkIdx; + dwMinAge = dwAge; + } + else + { + continue; + } + } + if (wNewCxt == VFL_INFO_SECTION_SIZE) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(line:%d) bank %d!\n"), __LINE__, wBank)); + BUF_Release(pBuf); + return FALSE32; + } + + /* look for the youngest valid VFLCxt version in the youngest block (i.e. search the youngest block pages) */ + wNewPOffset = 0; + for (wPOffsetIdx = VFL_NUM_OF_VFL_CXT_COPIES; wPOffsetIdx < PAGES_PER_BLOCK; wPOffsetIdx += VFL_NUM_OF_VFL_CXT_COPIES) + { + if (_ReadVFLCxtFromFlash(wBank, pVFLCxt->awInfoBlk[wNewCxt], wPOffsetIdx, pBuf) == FALSE32) + { + break; + } + + wNewPOffset = wPOffsetIdx; + } + if (_ReadVFLCxtFromFlash(wBank, pVFLCxt->awInfoBlk[wNewCxt], wNewPOffset, pBuf) == FALSE32) + { + /* this shouldn't happen since are using valid pointers */ + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(line:%d) bank %d!\n"), __LINE__, wBank)); + BUF_Release(pBuf); + return FALSE32; + } + + WMR_MEMCPY(&pstVFLMeta[wBank], pBuf->pData, sizeof(VFLMeta)); + + if (pVFLCxt->dwGlobalCxtAge > gdwMaxGlobalAge) + { + gdwMaxGlobalAge = pVFLCxt->dwGlobalCxtAge; + } + + BUF_Release(pBuf); + if (CHECK_VFL_CXT_CHECK_SUM_NO_ASSERT(wBank) == FALSE32) + { + return FALSE32; + } + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_LoadVFLCxt(wBank:%d)\n"), wBank)); + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _GetReservedBlk */ +/* DESCRIPTION */ +/* This function returns the reserved block index. */ +/* PARAMETERS */ +/* wBank [IN] bank number */ +/* nPbn [IN] the physical bad block address. */ +/* *pIdx[OUT] the pointer of the replaced good block index. */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _GetReservedBlk is completed */ +/* FALSE32 */ +/* _GetReservedBlk is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +#ifndef AND_READONLY +static BOOL32 +_GetReservedBlk(UInt16 wBank, UInt16 wPbn, UInt16 *pwIdx) +{ + VFLCxt *pVFLCxt; + UInt16 wIdx; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_GetReservedBlk(wBank:%d, wPbn:%d)\n"), wBank, wPbn)); + + if ((wBank > BANKS_TOTAL) || (wPbn >= BLOCKS_PER_BANK) || (pwIdx == NULL)) + { + return FALSE32; + } + + pVFLCxt = GET_VFLCxt(wBank); + + for (wIdx = 0; wIdx < pVFLCxt->wReservedSecSize; wIdx++) + { + /* find good block index of reserved blocks */ + { + if (pVFLCxt->aBadMapTable[wIdx] == 0) + { + *pwIdx = wIdx; + break; + } + } + } + + /* there is no reserved block */ + if (wIdx == pVFLCxt->wReservedSecSize) + { + if (pwIdx != NULL) + { + *pwIdx = 0xFFFF; + } + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_GetReservedBlk(wBank:%d, wPbn:%d)\n"), wBank, wPbn)); + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _ReplaceBadBlk */ +/* DESCRIPTION */ +/* This function replaces the bad block with the reserved block. */ +/* PARAMETERS */ +/* wBank [IN] bank number */ +/* nSrcPbn [IN] the physical source bad block address */ +/* *pDesLPbn[OUT] the pointer of the replaced good block address */ +/* *pDesRPbn[OUT] the pointer of the replaced good block address */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _ReplaceBadBlk is completed */ +/* FALSE32 */ +/* _ReplaceBadBlk is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static BOOL32 +_ReplaceBadBlk(UInt16 wBank, UInt16 wSrcPbn, UInt16 *pwDesPbn) +{ + VFLCxt *pVFLCxt; + Int32 nFILRet = VFL_CRITICAL_ERROR; + UInt16 wIdx = 0, wReplacementIdx = 0; + UInt8 bTrialIdx1, bTrialIdx2; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_ReplaceBadBlk(wBank:%d, wSrcPbn:%d)\n"), wBank, wSrcPbn)); + + /* check current state */ + if ((wBank >= BANKS_TOTAL) || (wSrcPbn >= BLOCKS_PER_BANK) || + (pwDesPbn == NULL)) + { + return FALSE32; + } + + pVFLCxt = GET_VFLCxt(wBank); + + /* get reserved block index of good block */ + for (bTrialIdx1 = 0; bTrialIdx1 < 3; bTrialIdx1++) + { + if (_GetReservedBlk(wBank, wSrcPbn, pwDesPbn) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _GetReservedBlk(wBank:%d, wSrcPbn:%d) fail!\n"), wBank, wSrcPbn)); + return FALSE32; + } + + WMR_ASSERT(pwDesPbn != NULL); + + if (*pwDesPbn == 0xFFFF) + { +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) + WMR_SIM_EXIT("Out of replacement blocks"); +#else // defined(AND_SIMULATOR) && AND_SIMULATOR + VFL_ERR_PRINT((TEXT("[VFL:ERR] there is no reserved block!!!\n"))); +#endif // defined(AND_SIMULATOR) && AND_SIMULATOR + *pwDesPbn = wSrcPbn; + + return FALSE32; + } + + wReplacementIdx = *pwDesPbn; + + for (bTrialIdx2 = 0; bTrialIdx2 < 3; bTrialIdx2++) + { /* erase the reserved block */ + nFILRet = pFuncTbl->Erase(wBank, (wReplacementIdx + pVFLCxt->wReservedSecStart)); + if (nFILRet == VFL_SUCCESS) + { + break; + } + } + if (nFILRet != FIL_SUCCESS) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] erase fail occured while replacing a bad block!!!\n"))); + } + else + { + break; + } + } + if (nFILRet != FIL_SUCCESS) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] erase fail occurs when replaces bad block(line:%d)!!!\n"), __LINE__)); + } + /* update bad block management table */ + CHECK_VFL_CXT_CHECK_SUM(wBank); + for (wIdx = 0; wIdx < wReplacementIdx; wIdx++) + { + if (pVFLCxt->aBadMapTable[wIdx] == wSrcPbn) + { + pVFLCxt->aBadMapTable[wIdx] = 0xFFFF; + } + } + pVFLCxt->aBadMapTable[wReplacementIdx] = (UInt16)wSrcPbn; + + *pwDesPbn = wReplacementIdx + pVFLCxt->wReservedSecStart; + + if (pVFLCxt->wBadMapTableMaxIdx <= wReplacementIdx) + { + pVFLCxt->wBadMapTableMaxIdx = (UInt16)(wReplacementIdx + 1); + } + + /* update bad mark table */ + if (_isBadMarkTableMarkGood(pVFLCxt->aBadMark, wSrcPbn)) + { + _SetBadMarkTable(pVFLCxt->aBadMark, wSrcPbn, FALSE32); + } + RECALC_VFL_CXT_CHECK_SUM(wBank); + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_ReplaceBadBlk(wBank:%d, wSrcPbn:%d)\n"), wBank, wSrcPbn)); + return TRUE32; +} +#endif +/*****************************************************************************/ +/* */ +/* NAME */ +/* _RemapBadBlk */ +/* DESCRIPTION */ +/* This function remaps the block address if it is bad block. */ +/* PARAMETERS */ +/* wBank [IN] bank number */ +/* nSrcPbn [IN] the physical source block address */ +/* pwDesPbn [OUT] the pointer of the remapped good block address */ +/* RETURN VALUES */ +/* TRUE32 */ +/* _RemapBadBlk is completed */ +/* FALSE32 */ +/* _RemapBadBlk is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static void +_RemapBadBlk(UInt16 wBank, UInt16 wSrcPbn, UInt16 *pwDesPbn) +{ + VFLCxt *pVFLCxt; + UInt16 wIdx; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_RemapBadBlk(wBank:%d, wSrcPbn:%d)\n"), wBank, wSrcPbn)); + + pVFLCxt = GET_VFLCxt(wBank); + + /* check wSrcPbn block is bad block or not */ + { + BOOL32 bRemap = FALSE32; + + if (!_isBadMarkTableMarkGood(pVFLCxt->aBadMark, wSrcPbn)) + { + for (wIdx = 0; wIdx < pVFLCxt->wBadMapTableMaxIdx; wIdx++) + { + if (pVFLCxt->aBadMapTable[wIdx] == (UInt16)wSrcPbn) + { + *pwDesPbn = pVFLCxt->wReservedSecStart + wIdx; + bRemap = TRUE32; + + WMR_ASSERT(*pwDesPbn < BLOCKS_PER_BANK); + break; + } + } + } + + if (bRemap == FALSE32) + { + *pwDesPbn = wSrcPbn; + } + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_RemapBadBlk(wBank:%d, wSrcPbn:%d)\n"), wBank, wSrcPbn)); +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* _GetPhysicalAddr */ +/* DESCRIPTION */ +/* This function returns the physical bank, block & page address of */ +/* the virtual page address */ +/* PARAMETERS */ +/* nVpn [IN] virtual page number */ +/* pBank [OUT] physical bank number */ +/* pPbn [OUT] physical block number */ +/* pPOffset [OUT] physical page offset */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static void +_GetPhysicalAddr(UInt32 dwVpn, UInt16 *pwBank, UInt16 *pwPbn, UInt16 *pwPOffset) +{ + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_GetPhysicalAddr(nVpn:%d)\n"), dwVpn)); + + WMR_ASSERT(dwVpn < PAGES_TOTAL); + WMR_ASSERT(dwVpn >= PAGES_PER_SUBLK); + + *pwBank = (UInt16)(dwVpn % BANKS_TOTAL); + *pwPbn = (UInt16)(dwVpn / PAGES_PER_SUBLK); + *pwPOffset = (UInt16)((dwVpn / BANKS_TOTAL) % PAGES_PER_BLOCK); + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_GetPhysicalAddr(nVpn:%d)\n"), dwVpn)); + return; +} + +static UInt16 +_CalcNumOfVFLSuBlk(void) +{ + // Any blocks above the binary size will be used as spares + UInt32 wRoundedBlocksPerBank = 1UL << WMR_LOG2(BLOCKS_PER_BANK); + + return VFL_USER_BLKS_PER_1K * (wRoundedBlocksPerBank / 1024); +} +static BOOL32 _InitDeviceInfo(void) +{ + pFuncTbl = stFPartFunctions.GetLowFuncTbl(); + stVFLDeviceInfo.wBlocksPerBank = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); // this vfl does not use VS -> banks = cs + stVFLDeviceInfo.wBytesPerPage = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + stVFLDeviceInfo.wNumOfBank = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + stVFLDeviceInfo.wPagesPerBlock = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + stVFLDeviceInfo.bRefreshThreshold = (UInt8)pFuncTbl->GetDeviceInfo(AND_DEVINFO_REFRESH_THRESHOLD); + stVFLDeviceInfo.wUserSuBlkTotal = _CalcNumOfVFLSuBlk(); + stVFLDeviceInfo.dwPagesTotal = (UInt32)stVFLDeviceInfo.wBlocksPerBank * + (UInt32)stVFLDeviceInfo.wPagesPerBlock * (UInt32)stVFLDeviceInfo.wNumOfBank; + stVFLDeviceInfo.wPagesPerSuBlk = stVFLDeviceInfo.wPagesPerBlock * stVFLDeviceInfo.wNumOfBank; + stVFLDeviceInfo.dwUserPagesTotal = (UInt32)stVFLDeviceInfo.wUserSuBlkTotal * (UInt32)stVFLDeviceInfo.wPagesPerSuBlk; + + stVFLDeviceInfo.dwValidMetaPerLogicalPage = pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_META_VALID_BYTES); + stVFLDeviceInfo.dwTotalMetaPerLogicalPage = pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + stVFLDeviceInfo.dwLogicalPageSize = pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + + + if (stVFLDeviceInfo.wNumOfBank != 1) + { + RESERVED_SECTION_SIZE = stVFLDeviceInfo.wBlocksPerBank - (stVFLDeviceInfo.dwVFLAreaStart + FTL_AREA_SIZE + VFL_INFO_SECTION_SIZE); + } + else + { + UInt32 dwRemainSupBlk; + + dwRemainSupBlk = stVFLDeviceInfo.wBlocksPerBank - FTL_AREA_SIZE - stVFLDeviceInfo.wNumOfBank * (stVFLDeviceInfo.dwVFLAreaStart + VFL_INFO_SECTION_SIZE); + + RESERVED_SECTION_SIZE = (UInt16)(dwRemainSupBlk / stVFLDeviceInfo.wNumOfBank); + } + + VFL_AREA_SIZE = VFL_INFO_SECTION_SIZE + RESERVED_SECTION_SIZE; + + FTL_CXT_SECTION_START = FTL_AREA_START; + pFuncTbl->SetDeviceInfo(AND_DEVINFO_BANKS_PER_CS, 1); + pFuncTbl->SetDeviceInfo(AND_DEVINFO_VENDOR_SPECIFIC_TYPE, FIL_VS_SIMPLE); + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Init */ +/* DESCRIPTION */ +/* This function initializes VFL layer. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Init is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Init(FPartFunctions * pFPartFunctions) +{ + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Init()\n"))); + + WMR_MEMCPY(&stFPartFunctions, pFPartFunctions, sizeof(FPartFunctions)); + _InitDeviceInfo(); + + /* the size of FTLMeta must be 2048 bytes */ + WMR_ASSERT(sizeof(VFLMeta) == 2048); +#ifdef AND_COLLECT_STATISTICS + WMR_ASSERT(sizeof(VFLStatistics) < AND_STATISTICS_SIZE_PER_LAYER); + WMR_MEMSET(&stVFLStatistics, 0, sizeof(VFLStatistics)); +#endif // AND_COLLECT_STATISTICS + /* init VFL meta */ + if (pstVFLMeta == NULL) + { + pstVFLMeta = (VFLMeta *)WMR_MALLOC(sizeof(VFLMeta) * BANKS_TOTAL); + if (pstVFLMeta == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] there is no memory to initialize pstVFLCxt!\n"))); + return VFL_CRITICAL_ERROR; + } + } + + /* init BBT area - allocate a byte per 8 blocks to store the BBT */ + if (pstBBTArea == NULL) + { + pstBBTArea = (UInt8 *)WMR_MALLOC(BBT_SIZE_PER_BANK); + + if (pstBBTArea == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] there is no memory to initialize pstBBTArea!\n"))); + return VFL_CRITICAL_ERROR; + } + } + + /* Allocate buffers for scattered read operation */ + if (pstadwScatteredReadPpn == NULL && pstawScatteredReadBank == NULL) + { + pstadwScatteredReadPpn = (UInt32 *)WMR_MALLOC(PAGES_PER_SUBLK * sizeof(UInt32)); + pstawScatteredReadBank = (UInt16 *)WMR_MALLOC(PAGES_PER_SUBLK * sizeof(UInt16)); + + if (pstadwScatteredReadPpn == NULL || pstawScatteredReadBank == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] there is no memory to initialize pstBBTArea!\n"))); + return VFL_CRITICAL_ERROR; + } + } + + /* get low level function table */ + pFuncTbl = stFPartFunctions.GetLowFuncTbl(); + + if (pFuncTbl == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] stFPartFunctions.GetLowFuncTbl() fail!\n"))); + return VFL_CRITICAL_ERROR; + } + gdwMaxGlobalAge = 0; + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Init()\n"))); + + /* set the poitners to the checksum functions */ + vflChecksumFunc.UpdateChecksum = _UpdateVFLCxtChecksum; + vflChecksumFunc.VerifyChecksum = _CheckVFLCxtDataIsUntouched; + + return VFL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Open */ +/* DESCRIPTION */ +/* This function opens VFL layer. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Open is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Open is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Open(UInt32 dwBootAreaSize, UInt32 minor_ver, UInt32 dwOptions) +{ + UInt16 wBankIdx; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Open()\n"))); + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + BOOL32 bRet; + + bRet = VFL_ReadBBT(wBankIdx, pstBBTArea); + if (bRet == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_ReadBBT(wBank:%d)(line %d) fail!\n"), wBankIdx, __LINE__)); + return VFL_CRITICAL_ERROR; + } + bRet = _LoadVFLCxt(wBankIdx, pstBBTArea); + + if (bRet == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(wBank:%d)(line %d) fail!\n"), wBankIdx, __LINE__)); + return VFL_CRITICAL_ERROR; + } + } + + /* make sure that FTLCxt is updated everywhere */ + { + UInt16 awFTLCxtVbnTemp[FTL_CXT_SECTION_SIZE]; + WMR_MEMCPY(awFTLCxtVbnTemp, VFL_GetFTLCxtVbn(), (FTL_CXT_SECTION_SIZE * sizeof(UInt16))); + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + /* make sure all are up to date so later storing of VFL Cxt would be correct */ + WMR_MEMCPY(pstVFLMeta[wBankIdx].stVFLCxt.aFTLCxtVbn, awFTLCxtVbnTemp, FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + RECALC_VFL_CXT_CHECK_SUM(wBankIdx); + } + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Open()\n"))); + + return VFL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Read */ +/* DESCRIPTION */ +/* This function reads virtual page. */ +/* PARAMETERS */ +/* nVpn [IN] virtual page number */ +/* pBuf [IN] Buffer pointer */ +/* bCleanCheck [IN] clean check or not */ +/* bMarkECCForScrub [IN] in case of ECC error - add to scrub */ +/* list or not */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Read is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Read is failed. */ +/* VFL_U_ECC_ERROR */ +/* ECC uncorrectable error occurs from FIL read function. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Read(UInt32 dwVpn, Buffer *pBuf, BOOL32 boolCleanCheck, BOOL32 bMarkECCForScrub, BOOL32 * pboolNeedRefresh, UInt8 * pabSectorStat, BOOL32 bDisableWhitening) +{ + UInt16 wBank; + UInt16 wPbn; + UInt16 wPOffset; + UInt16 wPbnRemapped; + UInt32 dwPpnRemapped; + UInt32 dwVpnCorrected; + Int32 nFILRet; + UInt8 bECCCorrectedBits; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Read(dwVpn:%d,boolCleanCheck:%d)\n"), dwVpn, boolCleanCheck)); + + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = FALSE32; + } + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesReadCnt++; + stVFLStatistics.ddwSingleReadCallCnt++; +#endif + dwVpnCorrected = dwVpn + (FTL_CXT_SECTION_START * PAGES_PER_SUBLK); + /* check virtual page address */ + if (dwVpnCorrected >= PAGES_TOTAL || dwVpnCorrected < PAGES_PER_SUBLK) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Read(dwVpn:%d) dwVpn Overflow!\n"), dwVpnCorrected)); + return VFL_CRITICAL_ERROR; + } + + /* calculate physical address */ + _GetPhysicalAddr(dwVpnCorrected, &wBank, &wPbn, &wPOffset); + + /* get remapped block address from VFL context */ + _RemapBadBlk(wBank, wPbn, &wPbnRemapped); + + /* get remapped page address */ + dwPpnRemapped = GET_Ppn(wPbnRemapped, wPOffset); + + nFILRet = pFuncTbl->ReadWithECC(wBank, dwPpnRemapped, pBuf->pData, + pBuf->pSpare, &bECCCorrectedBits, NULL, bDisableWhitening); + + // in case we are no ready to process clean pages mark the page as ecc error if it is clean + if (boolCleanCheck == FALSE32 && nFILRet == FIL_SUCCESS_CLEAN) + { + nFILRet = FIL_U_ECC_ERROR; + } + + // check if the page need to be refreshed + if (pboolNeedRefresh != NULL) + { + if ((bECCCorrectedBits >= FIL_ECC_REFRESH_TRESHOLD && nFILRet == FIL_SUCCESS) || + (nFILRet == FIL_U_ECC_ERROR)) + { + // Mark the block for refresh + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = TRUE32; + } + } + } + + if (nFILRet == FIL_CRITICAL_ERROR || nFILRet == FIL_U_ECC_ERROR) + { + // reset the bank in the hopes of making it behave + pFuncTbl->Reset(); + nFILRet = pFuncTbl->ReadWithECC(wBank, dwPpnRemapped, pBuf->pData, + pBuf->pSpare, NULL, NULL, bDisableWhitening); + // in case we are no ready to process clean pages mark the page as ecc error if it is clean + if (boolCleanCheck == FALSE32 && nFILRet == FIL_SUCCESS_CLEAN) + { + nFILRet = FIL_U_ECC_ERROR; + } + if (nFILRet == FIL_CRITICAL_ERROR || nFILRet == FIL_U_ECC_ERROR) + { +#ifndef AND_READONLY + UInt32 dwIdx, dwFFMetaCnt = 0; + // reset the bank in the hopes of making it behave for the next user + pFuncTbl->Reset(); + // + // IMPORTANT!!! caution when porting this code - we might need to allocate another buffer here + // + // use read with no ecc - this will get us the closest data to the original + pFuncTbl->ReadNoECC(wBank, dwPpnRemapped, pBuf->pData, pBuf->pSpare); + VFL_WRN_PRINT((TEXT("[VFL:WRN] Read(0x%X) returns 0x%X fail!\n"), dwVpn, nFILRet)); + for (dwIdx = 0; dwIdx < BYTES_PER_METADATA_RAW; dwIdx++) + { + if (pBuf->pSpare[dwIdx] == 0xFF) + { + dwFFMetaCnt++; + } + } + VFL_WRN_PRINT((TEXT("[VFL:WRN] Meta: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X Meta FF Count %d (line:%d)\n"), + pBuf->pSpare[0], pBuf->pSpare[1], pBuf->pSpare[2], pBuf->pSpare[3], + pBuf->pSpare[4], pBuf->pSpare[5], pBuf->pSpare[6], pBuf->pSpare[7], + pBuf->pSpare[8], pBuf->pSpare[9], pBuf->pSpare[10], pBuf->pSpare[11], + dwFFMetaCnt, __LINE__)); + + /* if the error is ECC mark the block for scrubing */ + if ((nFILRet == FIL_U_ECC_ERROR) && (bMarkECCForScrub == TRUE32)) + { + _AddBlockToScrubList(wBank, wPbn); + } +#endif + return nFILRet; + } + } + + if (nFILRet == FIL_SUCCESS_CLEAN) + { + WMR_MEMSET(pBuf->pSpare, 0xFF, BYTES_PER_METADATA_RAW); + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Read(dwVpn:%d,boolCleanCheck:%d)\n"), dwVpn, boolCleanCheck)); + return nFILRet; +} +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Write */ +/* DESCRIPTION */ +/* This function writes virtual page. */ +/* PARAMETERS */ +/* nVpn [IN] virtual page number */ +/* pBuf [IN] Buffer pointer */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Write is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Write is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Write(UInt32 dwVpn, Buffer *pBuf, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening) +{ + UInt16 wBank; + UInt16 wPbn; + UInt16 wPOffset; + UInt16 wPbnRemapped; + UInt32 dwPpnRemapped; + UInt32 dwVpnCorrected; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Write(dwVpn:%d)\n"), dwVpn)); + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesWrittenCnt++; + stVFLStatistics.ddwSingleWriteCallCnt++; +#endif + + dwVpnCorrected = dwVpn + (FTL_CXT_SECTION_START * PAGES_PER_SUBLK); // FTL can access only vb FTL_CXT_SECTION_START and up. + + /* check virtual page address */ + if (dwVpnCorrected >= PAGES_TOTAL || dwVpnCorrected < PAGES_PER_SUBLK) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Write(dwVpn:%d) dwVpn Overflow!\n"), dwVpn)); + return VFL_CRITICAL_ERROR; + } + + /* calculate physical address */ + _GetPhysicalAddr(dwVpnCorrected, &wBank, &wPbn, &wPOffset); + + /* get remapped block address from VFL context */ + _RemapBadBlk(wBank, wPbn, &wPbnRemapped); + + /* get remapped page address */ + dwPpnRemapped = GET_Ppn(wPbnRemapped, wPOffset); + + /* write page data */ + if (pFuncTbl->Write(wBank, dwPpnRemapped, pBuf->pData, pBuf->pSpare, bDisableWhitening) != FIL_SUCCESS) + { + CHECK_VFL_CXT_CHECK_SUM(wBank); + pstVFLMeta[wBank].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wBank); + _AddBlockToScrubList(wBank, wPbn); + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Write(dwVpn:%d) failed!\n"), dwVpn)); + return VFL_CRITICAL_ERROR; + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Write(dwVpn:%d)\n"), dwVpn)); + + return VFL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Erase */ +/* DESCRIPTION */ +/* This function erases virtual block(super block). */ +/* PARAMETERS */ +/* wVbn [IN] virtual block number */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Erase is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Erase is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Erase(UInt16 wVbn, BOOL32 bReplaceOnFail) +{ + UInt16 wPbnRemapped; + UInt16 wVbnCorrected; + Int32 nRetVal = VFL_CRITICAL_ERROR; + UInt16 wBankIdx; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Erase(wVbn:%d)\n"), wVbn)); + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwBlocksErasedCnt++; + stVFLStatistics.ddwEraseCallCnt++; +#endif + + wVbnCorrected = wVbn + FTL_CXT_SECTION_START; + if (wVbnCorrected >= BLOCKS_PER_BANK || wVbnCorrected == 0 || (wVbnCorrected >= VFL_AREA_START && wVbnCorrected < VFL_AREA_START + VFL_AREA_SIZE)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase(wVbn:%d) input overflow!\n"), wVbn)); + return VFL_CRITICAL_ERROR; + } + // NirW - code need to change to work with new erase in parallel. + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + UInt8 bTrialIdx; + if (_IsBlockInScrubList(wBankIdx, wVbnCorrected)) + { + UInt16 wReplacementPbn; + _ReplaceBadBlk(wBankIdx, wVbnCorrected, &wReplacementPbn); + _RemoveBlockFromScrubList(wBankIdx, wVbnCorrected); + } + + /* erase blocks */ + for (bTrialIdx = 0; bTrialIdx < WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS; bTrialIdx++) + { + /* calculate replaced physical block address */ + _RemapBadBlk(wBankIdx, wVbnCorrected, &wPbnRemapped); + + nRetVal = pFuncTbl->Erase(wBankIdx, wPbnRemapped); + if (nRetVal != FIL_SUCCESS) + { + // try one more time... + nRetVal = pFuncTbl->Erase(wBankIdx, wPbnRemapped); + } + + if (nRetVal == FIL_SUCCESS) + { + break; + } + else if (!bReplaceOnFail) + { + return nRetVal; + } + else if (nRetVal == FIL_WRITE_FAIL_ERROR) + { + UInt16 wReplacementPbn; + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Erase failed erasing pbn 0x%X bank %d!\n"), wPbnRemapped, wBankIdx)); + CHECK_VFL_CXT_CHECK_SUM(wBankIdx); + pstVFLMeta[wBankIdx].stVFLCxt.wNumOfEraseFail++; + RECALC_VFL_CXT_CHECK_SUM(wBankIdx); + if (_ReplaceBadBlk(wBankIdx, wVbnCorrected, &wReplacementPbn) != TRUE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed _ReplaceBadBlk\n"))); + return VFL_CRITICAL_ERROR; + } + if (_StoreVFLCxt(wBankIdx) != TRUE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed _StoreVFLCxt\n"))); + return VFL_CRITICAL_ERROR; + } + } + } + if (bTrialIdx == WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed erasing / replacing vbn 0x%X bank %d!\n"), wVbnCorrected, wBankIdx)); + break; + } + } + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Erase(wVbn:%d)\n"), wVbn)); + + return nRetVal; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Format */ +/* DESCRIPTION */ +/* This function formats VFL. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Format is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Format is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Format(UInt32 dwBootAreaSize, UInt32 dwOptions) +{ + UInt16 wBankIdx; + VFLCxt *pVFLCxt; + UInt8 * pbaBBT; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Format()\n"))); + + WMR_MEMSET(pstVFLMeta, 0, sizeof(VFLMeta) * BANKS_TOTAL); + pstVFLMeta->dwVersion = VFL_META_VERSION; + pbaBBT = pstBBTArea; + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + Buffer *pBuf = NULL; + UInt16 wIdx, wPbn; + + if (VFL_ReadBBT(wBankIdx, pbaBBT) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_ReadBBT(%d) fail!\n"), wBankIdx)); + return VFL_CRITICAL_ERROR; + } + pVFLCxt = GET_VFLCxt(wBankIdx); + + pVFLCxt->dwGlobalCxtAge = wBankIdx; + for (wIdx = 0; wIdx < FTL_INFO_SECTION_SIZE; wIdx++) + { + pVFLCxt->aFTLCxtVbn[wIdx] = (UInt16)(wIdx); + } + + pVFLCxt->wNumOfInitBadBlk = 0; + pVFLCxt->wNumOfEraseFail = 0; + pVFLCxt->wNumOfWriteFail = 0; + pVFLCxt->wCxtLocation = 0; + pVFLCxt->wNextCxtPOffset = 0; + pVFLCxt->dwCxtAge = 0; + pVFLCxt->wBadMapTableMaxIdx = 0; + pVFLCxt->wBadMapTableScrubIdx = WMR_MAX_RESERVED_SIZE; + + WMR_MEMSET(pVFLCxt->aBadMark, 0xFF, VFL_BAD_MARK_INFO_TABLE_SIZE); + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pBuf == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] BUF_Get fail (line:%d)!\n"), __LINE__)); + return VFL_CRITICAL_ERROR; + } + + /* initial bad check of VFL_INFO_SECTION */ + for (wIdx = 0, wPbn = VFL_AREA_START; wIdx < VFL_INFO_SECTION_SIZE && wPbn < VFL_AREA_SIZE; wPbn++) + { + if (_isBlockGood(pbaBBT, wPbn)) + { + /* check that the block is erasable */ + UInt16 wEraseCnt; + for (wEraseCnt = 0; wEraseCnt < WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS; wEraseCnt++) + { + Int32 nFILRet; + nFILRet = pFuncTbl->Erase(wBankIdx, wPbn); + if (nFILRet == FIL_SUCCESS) + { + break; + } + } + if (wEraseCnt == WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS) + { + pVFLCxt->wNumOfInitBadBlk++; + } + else + { + pVFLCxt->awInfoBlk[wIdx++] = wPbn; + } + } + else + { + pVFLCxt->wNumOfInitBadBlk++; + } + } + + pVFLCxt->wReservedSecStart = wPbn; + pVFLCxt->wReservedSecSize = RESERVED_SECTION_SIZE - pVFLCxt->wNumOfInitBadBlk; + if (pVFLCxt->wReservedSecSize >= WMR_MAX_RESERVED_SIZE) + { + /* we should never get to this line - WMR_MAX_RESERVED_SIZE should cover all the flahses we work with */ + pVFLCxt->wReservedSecSize = WMR_MAX_RESERVED_SIZE; + } + + /* initial bad check of reserved area */ + for (wIdx = 0; wIdx < pVFLCxt->wReservedSecSize; wIdx++) + { + if (_isBlockGood(pbaBBT, (wIdx + pVFLCxt->wReservedSecStart))) + { + pVFLCxt->aBadMapTable[wIdx] = 0; + } + else + { + pVFLCxt->aBadMapTable[wIdx] = 0xFFFF; + pVFLCxt->wNumOfInitBadBlk++; + } + } + + for (wIdx = (VFL_AREA_START + VFL_AREA_SIZE); wIdx < BLOCKS_PER_BANK; wIdx++) + { + if (!_isBlockGood(pbaBBT, wIdx)) + { + UInt16 wTemp; + + pVFLCxt->wNumOfInitBadBlk++; + RECALC_VFL_CXT_CHECK_SUM(wBankIdx); + if (_ReplaceBadBlk(wBankIdx, wIdx, &wTemp) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _ReplaceBadBlk fail!\n"))); + return VFL_CRITICAL_ERROR; + } + } + } + + BUF_Release(pBuf); + RECALC_VFL_CXT_CHECK_SUM(wBankIdx); + if (_StoreVFLCxt(wBankIdx) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _StoreVFLCxt fail!\n"))); + return VFL_CRITICAL_ERROR; + } + } + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Format()\n"))); + return VFL_SUCCESS; +} +#endif // ! AND_READONLY + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Close */ +/* DESCRIPTION */ +/* This function releases VFL layer. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static void +VFL_Close(void) +{ + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Close()\n"))); + + /* release buffer manager */ + BUF_Close(); + + /* release VFL meta */ + if (pstVFLMeta != NULL) + { + WMR_FREE(pstVFLMeta, sizeof(VFLMeta) * BANKS_TOTAL); + pstVFLMeta = NULL; + } + + if (pstBBTArea != NULL) + { + WMR_FREE(pstBBTArea, BBT_SIZE_PER_BANK); + pstBBTArea = NULL; + } + + if (pstadwScatteredReadPpn != NULL) + { + WMR_FREE(pstadwScatteredReadPpn, (PAGES_PER_SUBLK * sizeof(UInt32))); + pstadwScatteredReadPpn = NULL; + } + + if (pstawScatteredReadBank != NULL) + { + WMR_FREE(pstawScatteredReadBank, (PAGES_PER_SUBLK * sizeof(UInt16))); + pstawScatteredReadBank = NULL; + } + +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&stVFLStatistics, 0, sizeof(VFLStatistics)); +#endif + pFuncTbl = NULL; + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Close()\n"))); + + return; +} + +static UInt16* +VFL_GetFTLCxtVbn(void) +{ + UInt32 nBankIdx; + UInt16 *pFTLCxtVbn = NULL; + VFLCxt *pVFLCxt = NULL; + UInt32 aMaxGlobalAge = 0; + + for (nBankIdx = 0; nBankIdx < BANKS_TOTAL; nBankIdx++) + { + pVFLCxt = GET_VFLCxt(nBankIdx); + + if (pVFLCxt->dwGlobalCxtAge >= aMaxGlobalAge) + { + aMaxGlobalAge = pVFLCxt->dwGlobalCxtAge; + pFTLCxtVbn = pVFLCxt->aFTLCxtVbn; + } + } + return pFTLCxtVbn; +} + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_ChangeFTLCxtVbn */ +/* DESCRIPTION */ +/* This function change the virtual block number of FTL context block */ +/* PARAMETERS */ +/* aFTLCxtVbn [IN] FTL context block list */ +/* that replace old FTL context positon */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Format is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Format is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_ChangeFTLCxtVbn(UInt16 *pwaFTLCxtVbn) +{ + UInt16 wWritePosition; + UInt16 wBankIdx; + + wWritePosition = (UInt16)(gdwMaxGlobalAge % BANKS_TOTAL); + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + CHECK_VFL_CXT_CHECK_SUM(wBankIdx); + /* make sure all are up to date so later storing of VFL Cxt would be correct */ + WMR_MEMCPY(pstVFLMeta[wBankIdx].stVFLCxt.aFTLCxtVbn, pwaFTLCxtVbn, FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + RECALC_VFL_CXT_CHECK_SUM(wBankIdx); + } + + if (!_StoreVFLCxt(wWritePosition)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL context write fail !\n"))); + return VFL_CRITICAL_ERROR; + } + + return VFL_SUCCESS; +} + +/* this function suppose to make the writing of several pages in the same block more efficient */ +/* + NAME + VFL_WriteMultiplePagesInVb + DESCRIPTION + This function suppose to make the writing of several pages in the same block + more efficient. + Data and spare info (only meta data) for pages the write is given by the FTL + as an array. + + PARAMETERS + wVbn - the Vbn we are writing to. + wStartPOffset - start offset from the beginning of the Vbn. + wNumPagesToWrite - number of pages to write. + pbaData - data buffer. + pbaSpare - meta data buffer. + RETURN VALUES + TRUE32 + Operation completed successfully. + FALSE32 + Operation failed. + NOTES + This function should not be used for writes of less than TOTAL_BANKS Vbs!!! + */ + +static BOOL32 VFL_WriteMultiplePagesInVb(UInt32 dwVpn, UInt16 wNumPagesToWrite, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening) +{ + UInt16 awPbnRemapped[WMR_MAX_DEVICE]; + UInt32 adwPpnRemapped[WMR_MAX_DEVICE]; + UInt16 wVbnCorrected; + UInt16 wPOffsetIdx; + UInt16 wBankIdx; + UInt16 wVbn, wStartPOffset; + + UInt16 wFailingCE = CE_STATUS_UNINITIALIZED; + UInt32 wFailingPage = PAGE_STATUS_UNINITIALIZED; + + wStartPOffset = (UInt16)(dwVpn % PAGES_PER_SUBLK); + wVbn = (UInt16)(dwVpn / PAGES_PER_SUBLK); + if ((wStartPOffset + wNumPagesToWrite) > PAGES_PER_SUBLK) + { + return FALSE32; + } + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesWrittenCnt += wNumPagesToWrite; + stVFLStatistics.ddwMultipleWriteCallCnt++; +#endif + + wVbnCorrected = (wVbn + FTL_CXT_SECTION_START); // FTL can access only vb FTL_CXT_SECTION_START and up. + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + _RemapBadBlk(wBankIdx, wVbnCorrected, &(awPbnRemapped[wBankIdx])); + } + + /* write the first few sectors until we are BANKS_TOTAL aligned */ + for (wPOffsetIdx = wStartPOffset; wPOffsetIdx < (wStartPOffset + wNumPagesToWrite) && (wPOffsetIdx % BANKS_TOTAL); wPOffsetIdx++, pbaData += BYTES_PER_PAGE, pbaSpare += BYTES_PER_METADATA_RAW) + { + wBankIdx = (wPOffsetIdx % BANKS_TOTAL); + + if (pFuncTbl->Write(wBankIdx, GET_Ppn(awPbnRemapped[wBankIdx], (wPOffsetIdx / BANKS_TOTAL)), pbaData, pbaSpare, bDisableWhitening) != FIL_SUCCESS) + { + /* Add the block to the Write Failures list */ + CHECK_VFL_CXT_CHECK_SUM(wBankIdx); + pstVFLMeta[wBankIdx].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wBankIdx); + _AddBlockToScrubList(wBankIdx, wVbnCorrected); + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_WriteMultiplePagesInVb(wVbn:0x%0X) fail!\n"), wVbn)); + return FALSE32; + } + } + + if (((wStartPOffset + wNumPagesToWrite) - wPOffsetIdx) > BANKS_TOTAL) + { + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + adwPpnRemapped[wBankIdx] = GET_Ppn(awPbnRemapped[wBankIdx], (wPOffsetIdx / BANKS_TOTAL)); + } + + if (pFuncTbl->WriteMultiplePages(adwPpnRemapped, pbaData, pbaSpare, (UInt16)((((wStartPOffset + wNumPagesToWrite) - wPOffsetIdx) / BANKS_TOTAL) * BANKS_TOTAL), FALSE32, FALSE32, &wFailingCE, bDisableWhitening, &wFailingPage) != FIL_SUCCESS) + { + return FALSE32; + } + pbaData += ((((wStartPOffset + wNumPagesToWrite) - wPOffsetIdx) / BANKS_TOTAL) * BANKS_TOTAL) * BYTES_PER_PAGE; + pbaSpare += ((((wStartPOffset + wNumPagesToWrite) - wPOffsetIdx) / BANKS_TOTAL) * BANKS_TOTAL) * BYTES_PER_METADATA_RAW; + wPOffsetIdx += ((((wStartPOffset + wNumPagesToWrite) - wPOffsetIdx) / BANKS_TOTAL) * BANKS_TOTAL); + } + + for (; wPOffsetIdx < (wStartPOffset + wNumPagesToWrite); wPOffsetIdx++, pbaData += BYTES_PER_PAGE, pbaSpare += BYTES_PER_METADATA_RAW) + { + wBankIdx = (wPOffsetIdx % BANKS_TOTAL); + + if (pFuncTbl->Write(wBankIdx, GET_Ppn(awPbnRemapped[wBankIdx], (wPOffsetIdx / BANKS_TOTAL)), pbaData, pbaSpare, bDisableWhitening) != FIL_SUCCESS) + { + /* Add the block to the Write Failures list */ + CHECK_VFL_CXT_CHECK_SUM(wBankIdx); + pstVFLMeta[wBankIdx].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wBankIdx); + _AddBlockToScrubList(wBankIdx, wVbnCorrected); + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_WriteMultiplePagesInVb(wVbn:0x%0X) fail!\n"), wVbn)); + return FALSE32; + } + } + + return TRUE32; +} +#endif + +VFLMeta * FTL_GetVFLMetaPtr(void) +{ + return pstVFLMeta; +} + +static BOOL32 +VFL_ReadMultiplePagesInVb(UInt16 wVbn, UInt16 wStartPOffset, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pabSectorStat, BOOL32 bDisableWhitening) +{ + UInt16 wBankIdx; + UInt16 wVbnCorrected; + UInt16 awPbnRemapped[WMR_MAX_DEVICE]; + UInt32 adwPpnRemapped[WMR_MAX_DEVICE]; + Int32 nRet; + Buffer buffer; + UInt16 wPagesRead = 0; + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesReadCnt += wNumPagesToRead; + stVFLStatistics.ddwSequetialReadCallCnt++; +#endif + + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = FALSE32; + } + wVbnCorrected = (wVbn + FTL_CXT_SECTION_START); // FTL can access only vb FTL_CXT_SECTION_START and up. + + // possibly change the code here to use scatter if the call is not aligned + // also consider changing the code so we have a single call for the start leftover and end leftover... + while (wStartPOffset % BANKS_TOTAL && wPagesRead < wNumPagesToRead) + { + buffer.pData = &pbaData[wPagesRead * BYTES_PER_PAGE]; + buffer.pSpare = &pbaSpare[wPagesRead * BYTES_PER_METADATA_RAW]; + nRet = VFL_Read((((UInt32)wVbn * PAGES_PER_SUBLK) + wStartPOffset++), &buffer, TRUE32, FALSE32, pboolNeedRefresh, NULL, bDisableWhitening); +#ifdef AND_COLLECT_STATISTICS + // correct the numbers changed by VFL_Read... + stVFLStatistics.ddwPagesReadCnt--; + stVFLStatistics.ddwSingleReadCallCnt--; +#endif + if (nRet != FIL_SUCCESS && nRet != FIL_SUCCESS_CLEAN) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_ReadMultiplePagesInVb 0x%X (line:%d)!\n"), nRet, __LINE__)); + return FALSE32; + } + wPagesRead++; + } + if (wPagesRead == wNumPagesToRead) + { + return TRUE32; + } + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + _RemapBadBlk(wBankIdx, wVbnCorrected, &(awPbnRemapped[wBankIdx])); + adwPpnRemapped[wBankIdx] = GET_Ppn(awPbnRemapped[wBankIdx], (wStartPOffset / BANKS_TOTAL)); + } + + if ((wNumPagesToRead - wPagesRead) > BANKS_TOTAL) + { + UInt8 bECCCorrectedBits; + nRet = pFuncTbl->ReadMultiplePages(adwPpnRemapped, &pbaData[wPagesRead * BYTES_PER_PAGE], + &pbaSpare[wPagesRead * BYTES_PER_METADATA_RAW], + (((wNumPagesToRead - wPagesRead) / BANKS_TOTAL) * BANKS_TOTAL), + &bECCCorrectedBits, NULL, bDisableWhitening); + if (nRet != FIL_SUCCESS && nRet != FIL_SUCCESS_CLEAN) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_ReadMultiplePagesInVb 0x%X (line:%d)!\n"), nRet, __LINE__)); + return FALSE32; + } + if (bECCCorrectedBits >= FIL_ECC_REFRESH_TRESHOLD && pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = TRUE32; + } + wStartPOffset += ((wNumPagesToRead - wPagesRead) / BANKS_TOTAL) * BANKS_TOTAL; + wPagesRead += ((wNumPagesToRead - wPagesRead) / BANKS_TOTAL) * BANKS_TOTAL; + } + + while (wPagesRead < wNumPagesToRead) + { + buffer.pData = &pbaData[wPagesRead * BYTES_PER_PAGE]; + buffer.pSpare = &pbaSpare[wPagesRead * BYTES_PER_METADATA_RAW]; + nRet = VFL_Read((((UInt32)wVbn * PAGES_PER_SUBLK) + wStartPOffset++), &buffer, + TRUE32, FALSE32, + (pboolNeedRefresh != NULL && *pboolNeedRefresh != TRUE32 ? pboolNeedRefresh : NULL), + NULL, + bDisableWhitening); +#ifdef AND_COLLECT_STATISTICS + // correct the numbers changed by VFL_Read... + stVFLStatistics.ddwPagesReadCnt--; + stVFLStatistics.ddwSingleReadCallCnt--; +#endif + if (nRet != FIL_SUCCESS && nRet != FIL_SUCCESS_CLEAN) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_ReadMultiplePagesInVb 0x%X (line:%d)!\n"), nRet, __LINE__)); + return FALSE32; + } + wPagesRead++; + } + return TRUE32; +} + +static BOOL32 +VFL_ReadScatteredPagesInVb(UInt32 * padwVpn, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pabSectorStat, BOOL32 bDisableWhitening, Int32 * actualStatus) +{ + UInt16 wPageIdx; + Int32 nRet; + UInt8 bCorrectableECC; + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesReadCnt += wNumPagesToRead; + stVFLStatistics.ddwScatteredReadCallCnt++; +#endif + + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = FALSE32; + } + + for (wPageIdx = 0; wPageIdx < wNumPagesToRead; wPageIdx++) + { + UInt32 dwVpnCorrected; + UInt16 wPbn, wPbnRemapped, wPOffset; + + dwVpnCorrected = padwVpn[wPageIdx] + (FTL_CXT_SECTION_START * PAGES_PER_SUBLK); + + /* calculate physical address */ + _GetPhysicalAddr(dwVpnCorrected, &pstawScatteredReadBank[wPageIdx], &wPbn, &wPOffset); + + /* get remapped block address from VFL context */ + _RemapBadBlk(pstawScatteredReadBank[wPageIdx], wPbn, &wPbnRemapped); + + /* get remapped page address */ + pstadwScatteredReadPpn[wPageIdx] = GET_Ppn(wPbnRemapped, wPOffset); + } + + nRet = pFuncTbl->ReadScatteredPages(pstawScatteredReadBank, pstadwScatteredReadPpn, pbaData, pbaSpare, wNumPagesToRead, &bCorrectableECC, NULL, bDisableWhitening); + if (bCorrectableECC >= FIL_ECC_REFRESH_TRESHOLD && pboolNeedRefresh != NULL) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_ReadScatteredPagesInVb mark page for refresh (line:%d)!\n"), __LINE__)); + *pboolNeedRefresh = TRUE32; + } + + return (nRet == FIL_SUCCESS || nRet == FIL_SUCCESS_CLEAN) ? TRUE32 : FALSE32; +} + +static BOOL32 +VFL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { + case AND_STRUCT_VFL_VFLMETA: + { + const UInt32 wCS = dwStructType & AND_STRUCT_CS_MASK; + if (pstVFLMeta && (wCS < BANKS_TOTAL)) + { + VFLMeta *pSrcMeta = &pstVFLMeta[wCS]; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, pSrcMeta, sizeof(*pSrcMeta)); + } + break; + } + + case AND_STRUCT_VFL_GET_TYPE: + { + UInt8 bVFLType = VFL_TYPE_VFL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &bVFLType, sizeof(bVFLType)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_STATISTICS_SIZE: + { + UInt32 dwStatSize = sizeof(VFLStatistics); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwStatSize, sizeof(dwStatSize)); + break; + } + + case AND_STRUCT_VFL_STATISTICS: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stVFLStatistics, sizeof(stVFLStatistics)); + break; + } +#endif // AND_COLLECT_STATISTICS + + case AND_STRUCT_VFL_DEVICEINFO_SIZE: + { + UInt32 dwDevInfoSize = sizeof(VFLWMRDeviceInfo); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwDevInfoSize, sizeof(dwDevInfoSize)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_DEVICEINFO: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stVFLDeviceInfo, sizeof(stVFLDeviceInfo)); + break; + } + + case AND_STRUCT_VFL_FILSTATISTICS: + { + boolRes = FIL_GetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, pdwStructSize); + break; + } +#endif + + case AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS: + // fall through + case AND_STRUCT_VFL_NUM_OF_SUBLKS: + { + UInt16 wNumSuBlks = FTL_AREA_SIZE; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wNumSuBlks, sizeof(wNumSuBlks)); + break; + } + + case AND_STRUCT_VFL_BYTES_PER_PAGE: + { + UInt16 wPageSize = BYTES_PER_PAGE; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPageSize, sizeof(wPageSize)); + break; + } + + case AND_STRUCT_VFL_PAGES_PER_SUBLK: + { + UInt16 wPagesPerSuBlk = PAGES_PER_SUBLK; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPagesPerSuBlk, sizeof(wPagesPerSuBlk)); + break; + } + + case AND_STRUCT_VFL_BYTES_PER_META: + { + UInt16 wBytesPerMetaData = BYTES_PER_METADATA_RAW; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wBytesPerMetaData, sizeof(wBytesPerMetaData)); + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_BITS: + { + UInt16 wCorrectableBits = (UInt16) pFuncTbl->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_BITS); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wCorrectableBits, sizeof(wCorrectableBits)); + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_SIZE: + { + UInt16 wCorrectableSize = (UInt16) pFuncTbl->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wCorrectableSize, sizeof(wCorrectableSize)); + break; + } + + default: + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_GetStruct 0x%X is not identified is VFL data struct identifier!\n"), dwStructType)); + boolRes = FALSE32; + } + return boolRes; +} + +static BOOL32 +VFL_SetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 dwStructSize) +{ + BOOL32 boolRes = TRUE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { + case AND_STRUCT_VFL_STATISTICS: + { +#ifdef AND_COLLECT_STATISTICS + WMR_MEMCPY(&stVFLStatistics, pvoidStructBuffer, WMR_MIN(sizeof(VFLStatistics), dwStructSize)); +#else + boolRes = FALSE32; +#endif + break; + } + + case AND_STRUCT_VFL_FILSTATISTICS: + { +#ifdef AND_COLLECT_STATISTICS + FIL_SetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, dwStructSize); +#else + boolRes = FALSE32; +#endif + break; + } + + case AND_STRUCT_VFL_FTLTYPE: + case AND_STRUCT_VFL_NEW_FTLTYPE: + case AND_STRUCT_VFL_NEW_NUM_OF_FTL_SUBLKS: + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_SetStruct 0x%X is not supported!\n"), dwStructType)); + break; + } + + default: + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_SetStruct 0x%X is not a VFL data struct identifier!\n"), dwStructType)); + boolRes = FALSE32; + } + return boolRes; +} + +static UInt16 VFL_GetVbasPerVb(UInt16 wVbn) +{ + return PAGES_PER_SUBLK; +} + +void VFL_Register(VFLFunctions * pVFL_Functions) +{ +#ifndef AND_READONLY + pVFL_Functions->Format = VFL_Format; + pVFL_Functions->WriteSinglePage = VFL_Write; + pVFL_Functions->Erase = VFL_Erase; + pVFL_Functions->ChangeFTLCxtVbn = VFL_ChangeFTLCxtVbn; + pVFL_Functions->WriteMultiplePagesInVb = VFL_WriteMultiplePagesInVb; +#endif // ! AND_READONLY + pVFL_Functions->Init = VFL_Init; + pVFL_Functions->Open = VFL_Open; + pVFL_Functions->Close = VFL_Close; + pVFL_Functions->ReadMultiplePagesInVb = VFL_ReadMultiplePagesInVb; + pVFL_Functions->ReadScatteredPagesInVb = VFL_ReadScatteredPagesInVb; + pVFL_Functions->ReadSinglePage = VFL_Read; + pVFL_Functions->GetFTLCxtVbn = VFL_GetFTLCxtVbn; +// pVFL_Functions->GetAddress = VFL_GetAddress; + pVFL_Functions->GetStruct = VFL_GetStruct; + pVFL_Functions->SetStruct = VFL_SetStruct; + pVFL_Functions->GetDeviceInfo = VFL_GetDeviceInfo; + pVFL_Functions->GetVbasPerVb = VFL_GetVbasPerVb; +} + +static UInt32 VFL_GetDeviceInfo(UInt32 dwParamType) +{ + UInt32 dwRetVal = 0xFFFFFFFF; + + switch (dwParamType) + { + case AND_DEVINFO_PAGES_PER_SUBLK: + { + dwRetVal = (UInt32)PAGES_PER_SUBLK; + break; + } + + case AND_DEVINFO_BYTES_PER_PAGE: + { + dwRetVal = (UInt32)BYTES_PER_PAGE; + break; + } + + case AND_DEVINFO_NUM_OF_BANKS: + { + dwRetVal = (UInt32)BANKS_TOTAL; + break; + } + + case AND_DEVINFO_NUM_OF_USER_SUBLK: + { + dwRetVal = (UInt32)FTL_AREA_SIZE; + break; + } + + case AND_DEVINFO_FTL_TYPE: + { + dwRetVal = (UInt32)FTL_TYPE_FTL; + break; + } + + case AND_DEVINFO_FTL_NEED_FORMAT: + { + dwRetVal = (UInt32)0; + break; + } + case AND_DEVINFO_FIL_LBAS_PER_PAGE: + { + dwRetVal = stVFLDeviceInfo.dwLogicalPageSize; + break; + } + case AND_DEVINFO_FIL_META_BUFFER_BYTES: + { + dwRetVal = stVFLDeviceInfo.dwTotalMetaPerLogicalPage; + break; + } + case AND_DEVINFO_FIL_META_VALID_BYTES: + { + dwRetVal = stVFLDeviceInfo.dwValidMetaPerLogicalPage; + break; + } + + default: + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_GetDeviceInfo dwParamType not supported (0x%X) (line:%d)!\n"), dwParamType, __LINE__)); + break; + } + return dwRetVal; +} + +#endif //#if AND_SUPPORT_LEGACY_VFL diff --git a/drivers/flash_nand/raw/Whimory/Core/VFL/VFLTypes.h b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLTypes.h new file mode 100644 index 0000000..04b1269 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/VFL/VFLTypes.h @@ -0,0 +1,233 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL types definition header */ +/* FILE : VFLTypes.h */ +/* PURPOSE : This header defines Data types which are shared */ +/* by all VFL submodules */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 04-AUG-2003 [HM Jung] : first writing */ +/* 14-JUL-2005 [Jaesung Jung] : reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : fix from code inspection */ +/* 24-JAN-2006 [Yangsup Lee ] : support un-pair bad block management */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ +#ifndef _VFL_TYPES_H_ +#define _VFL_TYPES_H_ + +typedef struct +{ + UInt16 wPagesPerBlock; /* the count of pages per block */ + UInt16 wPagesPerSuBlk; /* the count of pages per virtual block */ + UInt32 dwPagesTotal; /* the total number of pages */ + UInt16 wUserSuBlkTotal; /* the total number of data virtual block */ + UInt32 dwUserPagesTotal; /* the total number of data sector */ + + UInt16 wBlocksPerBank; /* the count of blocks per bank */ + + UInt16 wBytesPerPage; /* bytes per page (main) */ + + UInt32 dwValidMetaPerLogicalPage; + UInt32 dwTotalMetaPerLogicalPage; + UInt32 dwLogicalPageSize; + + UInt16 wNumOfBank; /* the number of banks */ + UInt8 bRefreshThreshold; // number of bit flips beyond which we want to rewrite the page + + // taken from WMRLayout + UInt16 dwVFLAreaStart; /* the block number where VFL area starts */ + UInt16 wVFLAreaSize; /* the block number of VFL area size */ + UInt16 wReservedSecSize; /* the size of reserved section */ + + UInt16 wFTLCxtStart; /* FTL cxt section start */ + UInt16 wFreeSecStart; /* free section start */ +} VFLWMRDeviceInfo; + +#define PAGES_PER_BLOCK (stVFLDeviceInfo.wPagesPerBlock) +#define PAGES_PER_SUBLK (stVFLDeviceInfo.wPagesPerSuBlk) +#define PAGES_TOTAL (stVFLDeviceInfo.dwPagesTotal) +#define USER_SUBLKS_TOTAL (stVFLDeviceInfo.wUserSuBlkTotal) +#define USER_PAGES_TOTAL (stVFLDeviceInfo.dwUserPagesTotal) +#define BLOCKS_PER_BANK (stVFLDeviceInfo.wBlocksPerBank) +#define BYTES_PER_PAGE (stVFLDeviceInfo.wBytesPerPage) +#define BANKS_TOTAL (stVFLDeviceInfo.wNumOfBank) + +#define VFL_AREA_START (stVFLDeviceInfo.dwVFLAreaStart) +#define VFL_AREA_SIZE (stVFLDeviceInfo.wVFLAreaSize) + +#define VFL_INFO_SECTION_START (VFL_AREA_START) +#define VFL_INFO_SECTION_SIZE (4) +#define RESERVED_SECTION_SIZE (stVFLDeviceInfo.wReservedSecSize) + +#define FTL_CXT_SECTION_START (stVFLDeviceInfo.wFTLCxtStart) +#define FTL_INFO_SECTION_SIZE FTL_CXT_SECTION_SIZE +#define LOG_SECTION_SIZE (FREE_SECTION_SIZE - FREE_LIST_SIZE) +#define FREE_SECTION_SIZE (20) +#define FREE_LIST_SIZE (3) + +#define FTL_AREA_START (VFL_AREA_START + VFL_AREA_SIZE) +#define FTL_AREA_SIZE (FTL_INFO_SECTION_SIZE + FREE_SECTION_SIZE + USER_SUBLKS_TOTAL) +#define FIL_ECC_REFRESH_TRESHOLD (stVFLDeviceInfo.bRefreshThreshold) + +#define BBT_SIZE_PER_BANK ((BLOCKS_PER_BANK / 8) + (BLOCKS_PER_BANK % 8 ? 1 : 0)) +#define BYTES_PER_SECTOR (512) +#define WMR_MAX_DEVICE (8) /* the maximum number of banks */ + +/*****************************************************************************/ +/* VFL constant definitions */ +/*****************************************************************************/ +#define INIT_BAD_MARK (0) /* bad mark position in spare */ +#define INIT_BAD_MARK_SECOND (64) /* bad mark position in spare */ + /* (2 plane programming) */ + +#define BAD_MARK_COMPRESS_SIZE (8) + +/*****************************************************************************/ +/* VFL context status(confirm) mark definition */ +/*****************************************************************************/ +#define PAGE_INCOMPLETE (0xFF) +#define PAGE_VALID (0x00) + +#define VFL_BAD_MARK_INFO_TABLE_SIZE (WMR_MAX_VB / 8 / BAD_MARK_COMPRESS_SIZE) +/*****************************************************************************/ +/* Data structure for storing the VFL context definition */ +/*****************************************************************************/ +/* NOTICE !!! */ +/* this structure is used directly to load VFL context by WMR_MEMCPY*/ +/* so the byte pad of this structure must be 0 */ +typedef struct +{ + UInt32 dwGlobalCxtAge; /* age for FTL meta information search */ + UInt16 aFTLCxtVbn[FTL_CXT_SECTION_SIZE]; /* page address (FTL virtual addressing space) of FTL Cxt */ + UInt16 wPadding; /* padding (align to UInt32) */ + + UInt32 dwCxtAge; /* context age 0xFFFFFFFF --> 0x0 - NirW - check if the variable is used anywhere - what is the difference between dwGlobalCxtAge and dwCxtAge */ + UInt16 wCxtLocation; /* current context block location (Physical) */ + UInt16 wNextCxtPOffset; /* current context page offset information */ + + /* this data is used for summary */ + UInt16 wNumOfInitBadBlk; /* the number of initial bad blocks - used for VFL format */ + UInt16 wNumOfWriteFail; /* the number of write fail - currently not used */ + UInt16 wNumOfEraseFail; /* the number of erase fail - updated (++) every time there is an erase failure that causes remapping of a block */ + + /* bad blocks management table & good block pointer */ + UInt16 wBadMapTableMaxIdx; /* index to the last bad block updated in the aBadMapTable */ + UInt16 wReservedSecStart; /* index of the first physical block that will be used as reserved in the bank (the first block after VFL Cxt Info) */ + UInt16 wReservedSecSize; /* number of physical blocks that are available as reserved (some might be bad blocks) */ + UInt16 aBadMapTable[WMR_MAX_RESERVED_SIZE]; /* remapping table of bad blocks - the UInt 16 value set here is the virtual block (vfl address space) that is being replaced */ + UInt8 aBadMark[VFL_BAD_MARK_INFO_TABLE_SIZE]; /* compact bitmap presentation of bad block (initial and accumulated) */ + + /* bad blocks management table within VFL info area */ + UInt16 awInfoBlk[VFL_INFO_SECTION_SIZE]; /* physical block addresses where Cxt information is stored */ + UInt16 wBadMapTableScrubIdx; /* Index for the scrub list (start from the top of aBadMapTable */ +} VFLCxt; + +/* VFLMeta size is 2048 bytes(4 sector) */ +#define VFL_META_VERSION 0x00000001 +typedef struct +{ + VFLCxt stVFLCxt; + UInt8 abReserved[((BYTES_PER_SECTOR - 3) * sizeof(UInt32)) - sizeof(VFLCxt)]; + UInt32 dwVersion; + UInt32 dwCheckSum; + UInt32 dwXorSum; +} VFLMeta; + +/*****************************************************************************/ +/* Data structure for VFL context spare area */ +/*****************************************************************************/ +/* spare layout for SLC & MLC */ +typedef struct +{ + UInt32 dwCxtAge; /* context age 0xFFFFFFFF --> 0x0 */ + UInt32 dwReserved; /* reserved */ + UInt8 cStatusMark; /* status (confirm) mark - currently not used for anything */ + UInt8 bSpareType; /* spare type */ + /* reserved for main ECC */ +} VFLSpare; + +#define VFL_SPARE_TYPE_CXT 0x80 + +/*****************************************************************************/ +/* Asynchronous operation management structure & enum definition */ +/*****************************************************************************/ + +/* Device Information Structures and defines */ + +#define VFL_META_STRUCT_VERSION 0x00000004 /* changed Oct 6th 2006 */ +#define VFL_BBT_STRUCT_VERSION 0x00000004 /* changed Oct 6th 2006 */ + +#define BBT_BLOCK_SIGNATURE (UInt8*)"DEVICEINFOBBT\0\0\0" +#define BBT_BLOCK_SIGNATURE_SIZE 16 + +#define UNIQUE_INFO_BLOCK_SIGNATURE (UInt8*)"DEVICEUNIQUEINFO" +#define UNIQUE_INFO_BLOCK_SIGNATURE_SIZE 16 + +#define NAND_DRIVER_SIGN_BLOCK_SIGNATURE (UInt8*)"NANDDRIVERSIGN\0\0" +#define NAND_DRIVER_SIGN_BLOCK_SIGNATURE_SIZE 16 + +#define NUMBER_OF_SPECIAL_BLOCKS (5) /* discuss what is the right value here with Mike Smith */ + +#define BBT_SIZE_PER_BANK ((BLOCKS_PER_BANK / 8) + (BLOCKS_PER_BANK % 8 ? 1 : 0)) + +#define WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS (4) + +typedef struct +{ + UInt8 abSignature[16]; + UInt32 dwVersion; + UInt32 adwSpecialBlocks[8]; + UInt32 dwBBTSize; +} BBTInfoHeaderStruct; + +#ifdef AND_COLLECT_STATISTICS +typedef struct +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwBlocksErasedCnt; + UInt64 ddwSingleWriteCallCnt; + UInt64 ddwSingleReadCallCnt; + UInt64 ddwSequetialReadCallCnt; + UInt64 ddwScatteredReadCallCnt; + UInt64 ddwMultipleWriteCallCnt; + UInt64 ddwEraseCallCnt; +} VFLStatistics; + +#define VFL_STATISTICS_DESCREPTION { \ + "ddwPagesWrittenCnt", \ + "ddwPagesReadCnt", \ + "ddwBlocksErasedCnt", \ + "ddwSingleWriteCallCnt", \ + "ddwSingleReadCallCnt", \ + "ddwSequetialReadCallCnt", \ + "ddwScatteredReadCallCnt", \ + "ddwMultipleWriteCallCnt", \ + "ddwEraseCallCnt", \ +} +#endif /* AND_COLLECT_STATISTICS */ + +#endif /* _VFL_TYPES_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLInterface.c b/drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLInterface.c new file mode 100644 index 0000000..493b465 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLInterface.c @@ -0,0 +1,4255 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL interface */ +/* FILE : VFLinterface.c */ +/* PURPOSE : This file contains the exported routine for interfacing with*/ +/* the upper layer of VFL. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 16-SEP-2003 [SJ Myoung] : multi-block read speed up */ +/* flash_read(,,,UInt8 sector_offset) add argument */ +/* 22-SEP-2003 [JH Kim] : buf_get() bug-fix (if no free buffer) */ +/* 29-SEP-2003 [HM Jung] : code size reduction */ +/* check init bad from PAGE_CLEAN */ +/* 03-NOV-2003 [JH Kim] : replace_bad_block() - add loop when erase */ +/* if erase fail */ +/* 12-JAN-2004 [JH Kim] : fix by sequential order */ +/* 26-JAN-2004 [JH Kim] : add buffer usage trace code */ +/* 13-MAR-2005 [Jaesung Jung] : duet port */ +/* 21-MAR-2005 [Jaesung Jung] : move ASSERT DEFINE to copy_data.h */ +/* 21-MAR-2005 [Jaesung Jung] : remove pattern_test code */ +/* 28-MAR-2005 [Jaesung Jung] : add logical to physical API */ +/* 07-APR-2005 [Jaesung Jung] : MLC support (2way) */ +/* 08-APR-2005 [Jaesung Jung] : add context checksum check */ +/* 11-APR-2005 [Jaesung Jung] : optimize PAGE_CLEAN check */ +/* 18-JUL-2005 [Jaesung Jung] : reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : bug-fix from code inspection */ +/* 22-NOV-2005 [Yangsup Lee ] : remove checksum code */ +/* 24-JAN-2006 [Yangsup Lee ] : change sector offset to sector bitmap */ +/* 24-JAN-2006 [Yangsup Lee ] : support un-pair bad block management */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Header file inclusions */ +/*****************************************************************************/ +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "VSVFLTypes.h" +#include "FPart.h" +#include "VFL.h" +#include "FIL.h" + +/*****************************************************************************/ +/* Debug Print #defines */ +/*****************************************************************************/ +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) +#define VFL_ERR_PRINT(x) { WMR_RTL_PRINT(x); WMR_PANIC(); } +#else +#define VFL_ERR_PRINT(x) WMR_RTL_PRINT(x) +#endif +#define VFL_WRN_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (VFL_LOG_MSG_ON) +#define VFL_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else +#define VFL_LOG_PRINT(x) //WMR_RTL_PRINT(x) +#endif + +#if defined (VFL_INF_MSG_ON) +#define VFL_INF_PRINT(x) WMR_DBG_PRINT(x) +#else +#define VFL_INF_PRINT(x) +#endif + +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Static variables definitions */ +/*****************************************************************************/ +#ifndef AND_READONLY +static UInt16 *pawPbnOriginal = NULL; +static UInt16 *pawPbn = NULL; +static UInt16 *pawPbnUnmapped = NULL; +#endif +static UInt16 *pawPbnRemapped = NULL; +static UInt32 *padwPpnRemapped = NULL; +static VFLMeta *pstVFLMeta = NULL; +static UInt32 *pstadwScatteredReadWritePpn = NULL; +static UInt16 *pstawScatteredReadWriteCS = NULL; + +static LowFuncTbl *pFuncTbl = NULL; +static UInt8 *pstabCSBBTArea[16]; +static VSVFLWMRDeviceInfo stVSVFLWMRDeviceInfo; +static FPartFunctions stFPartFunctions; + +// vendor specific conversion functions (bank, Tpn to CS, Ppn) +static void (*_pfnConvertP2C)(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) = NULL; +static void (*_pfnConvertC2P)(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn) = NULL; +static BOOL32 _SetBankToCSConvertFunctions(VendorSpecificType vendorSpecificType); +static UInt16 _GetBanksPerCS(VendorSpecificType vendorSpecificType); +static BOOL32 _SetV2PFunctions(VendorSpecificType vendorSpecificType); +static void (*_ConvertP2T)(UInt16 wPbn, UInt16* pwBank, UInt16* pwTbn); +static void (*_ConvertT2P)(UInt16 wBank, UInt16 wTbn, UInt16* pwPbn); + +#ifndef AND_READONLY +static Int32 VFL_Format(UInt32 dwBootAreaSize, UInt32 dwOptions); +static Int32 VFL_Write(UInt32 nVpn, Buffer *pBuf, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening); +static Int32 VFL_Erase(UInt16 wVbn, BOOL32 bReplaceOnFail); +static Int32 VFL_ChangeFTLCxtVbn(UInt16 *aFTLCxtVbn); +static BOOL32 VFL_WriteMultiplePagesInVb(UInt32 dwVpn, UInt16 wNumPagesToWrite, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening); +#endif // ! AND_READONLY +static Int32 VFL_Init(FPartFunctions * pFPartFunctions); +static Int32 VFL_Open(UInt32 dwBootAreaSize, UInt32 minor_ver, UInt32 dwOptions); +static void VFL_Close(void); +#if (!AND_DISABLE_READ_MULTIPLE) +static BOOL32 VFL_ReadMultiplePagesInVb(UInt16 wVbn, UInt16 wStartPOffset, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening); +#endif /* if (!AND_DISABLE_READ_MULTIPLE) */ +static BOOL32 VFL_ReadScatteredPagesInVb(UInt32 * padwVpn, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening, Int32* actualStatus); +static Int32 VFL_Read(UInt32 nVpn, Buffer *pBuf, BOOL32 bCleanCheck, BOOL32 bMarkECCForScrub, BOOL32 * pboolNeedRefresh, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening); +static UInt16* VFL_GetFTLCxtVbn(void); +//static BOOL32 VFL_GetAddress (ANDAddressStruct * pANDAddressStruct); +static BOOL32 VFL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); +static UInt32 VFL_GetDeviceInfo(UInt32 dwParamType); + +static UInt32 gdwMaxGlobalAge; +static VFLFailureDetails gstLastFailure; +#ifdef AND_COLLECT_STATISTICS +static VFLStatistics stVFLStatistics; +#endif +#ifndef AND_READONLY +#define RETIRE_ON_REFRESH_TRESHOLD 2 +static UInt8 * vflBlockRefreshTrigger = NULL; +#endif +/*****************************************************************************/ +/* Definitions */ +/*****************************************************************************/ +#define _GetNumOfSuBlks() (pstVFLMeta[0].stVFLCxt.wNumOfVFLSuBlk) +#define _GetNumOfFTLSuBlks() (pstVFLMeta[0].stVFLCxt.wNumOfFTLSuBlk) +#define _GetFTLType() (pstVFLMeta[0].stVFLCxt.dwFTLType) +#define GET_VFLCxt(v) (&(pstVFLMeta + (v))->stVFLCxt) +#define _Cbn2Ppn(Cbn, POffset) (_Cbn2Pbn(Cbn) * BLOCK_STRIDE + (POffset)) /* translate block + pages offset to page address*/ +#define _Vpn2Vbn(dwVpn) ((UInt16)((UInt32)(dwVpn) / PAGES_PER_SUBLK)) +#define _Vbn2Tbn(wVbn) (wVbn) +#define _ReserveIdx2Bank(wIdx) ((wIdx) / VFL_RESERVED_SECTION_SIZE_BANK) +#define _ReserveIdx2Tbn(wIdx) (((wIdx) % VFL_RESERVED_SECTION_SIZE_BANK) + _GetNumOfSuBlks()) +#define _Bank2CS(wBank) ((wBank) % CS_TOTAL) +#define _Vpn2Bank(dwVpn) ((UInt16)((dwVpn) % BANKS_TOTAL)) +#define _CSBank2Bank(wCS, wBank) (((wBank) * CS_TOTAL) + (wCS)) +#define _Bank2CSBank(wBank) ((wBank) / CS_TOTAL) +#define _Cbn2Pbn(Cbn) (((Cbn) / BLOCKS_PER_DIE ) * DIE_STRIDE + ((Cbn) % BLOCKS_PER_DIE)) //contiguous physical block to non-contiguous + +/*****************************************************************************/ +/* Global variables redefinitions (WMRDeviceInfo) */ +/*****************************************************************************/ +#define PAGES_PER_BLOCK (stVSVFLWMRDeviceInfo.wPagesPerBlock) +#define PAGES_PER_SUBLK (stVSVFLWMRDeviceInfo.wPagesPerSuBlk) + +#define USER_BLOCKS_PER_BANK (USER_BLOCKS_TOTAL / BANKS_PER_CS) +#define USER_BLOCKS_TOTAL (stVSVFLWMRDeviceInfo.wUserBlocksPerCS) +#define USER_SUBLKS_TOTAL (stVSVFLWMRDeviceInfo.wNumOfFTLSuBlks) +#define USER_PAGES_TOTAL (stVSVFLWMRDeviceInfo.dwUserPagesTotal) + +#define BYTES_PER_SECTOR (WMR_SECTOR_SIZE) +#define BYTES_PER_PAGE (stVSVFLWMRDeviceInfo.wBytesPerPage) +#define PAGES_PER_CS (BLOCKS_PER_CS * BLOCK_STRIDE) + +/*****************************************************************************/ +/* Global variables redefinitions (WMRConfig) */ +/*****************************************************************************/ +#define BANKS_TOTAL (stVSVFLWMRDeviceInfo.wNumOfBank) +#define CS_TOTAL (stVSVFLWMRDeviceInfo.wNumOfCEs) +#define BLOCKS_PER_CS (stVSVFLWMRDeviceInfo.wBlocksPerCS) +#define BANKS_PER_CS (stVSVFLWMRDeviceInfo.wNumOfBanksPerCS) +#define BLOCKS_PER_BANK (stVSVFLWMRDeviceInfo.wBlocksPerBank) +#define BLOCKS_PER_DIE (stVSVFLWMRDeviceInfo.wBlocksPerDie) +#define DIE_STRIDE (stVSVFLWMRDeviceInfo.wDieStride) +#define BLOCK_STRIDE (stVSVFLWMRDeviceInfo.wBlockStride) + +/*****************************************************************************/ +/* VFL local function prototypes */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Static function prototypes */ +/*****************************************************************************/ +static void _GetVFLSpare(UInt32 *pAge, UInt8 *pStatus, + UInt8 *pbType, UInt8 *pSBuf); +static BOOL32 _LoadVFLCxt(UInt16 wCS, UInt8 *pabBBT); +static UInt16 _RemapBlock(UInt16 wCS, UInt16 wPbn, BOOL32 *pboolAligned, BOOL32 *pboolCorrectBank); +static VFLCxt * _GetNewestVFLCxt(void); +static BOOL32 _GetFactoryBBTBuffer(void* pvoidStructBuffer, UInt32* pdwStructSize); +static void _ReportECCFailureMultiple(UInt16 wVbn); +static void _ReportECCFailureSingle(UInt16 wFailingCE, UInt16 dwPPN); +#ifndef AND_READONLY +static UInt16 _CalcNumOfVFLSuBlk(void); +static BOOL32 _SetFTLType(UInt32 dwFTLType); +static BOOL32 _SetNumOfFTLSuBlks(UInt16 wNumOfFTLSuBlks); +static BOOL32 _StoreVFLCxt(UInt16 wCS); +static void _SetVFLSpare(UInt32 *pAge, UInt8 *pSBuf); +static BOOL32 _ReplaceBadBlock(UInt16 wCSIdx, UInt16 wIdx); +static BOOL32 _SetNewFTLParams(void); +static BOOL32 _SetFTLType(UInt32 dwFTLType); +static BOOL32 _SetNewFTLType(UInt32 dwFTLType); +static BOOL32 _SetNewNumOfFTLSuBlks(UInt16 wNumOfFTLSuBlks); +static BOOL32 _SetNumOfFTLSuBlks(UInt16 wNumOfFTLSuBlks); +static BOOL32 _IsBlockInScrubList(UInt16 wCS, UInt16 wPbn); +static BOOL32 _AddBlockToScrubList(UInt16 wCS, UInt16 wPbn); +static BOOL32 _RemoveBlockFromScrubList(UInt16 wCS, UInt16 wPbn); +static BOOL32 _WriteVFLCxtToFlash(UInt16 wCS); +static void _MarkWriteFailBlockForDeleteWithVpn(UInt16 wFailingCE, UInt32 dwVpn); +static void _MarkWriteFailBlockForDeleteWithPbn(UInt16 wFailingCE, UInt16 wPbn); +static void _MarkWriteScatteredFailBlockForDelete(UInt16 wFailingCE, UInt32 dwVpn, + UInt32 wFailingPage, UInt16 ceList[], UInt32 physPageList[], UInt16 wPbnUnmapped[], UInt16 wPagesToWriteNow); +static void _MarkWriteMultipleFailBlockForDelete(UInt16 wFailingCE, UInt32 dwVpn, + UInt32 wFailingPage, UInt16 awPbnUnmapped[], UInt16 awPbnRemapped[], UInt32 adwPpnRemapped[], UInt16 wPagesToWriteNow); +static void _ReportWriteFailureMultiple(UInt16 wFailingCE, UInt32 dwVbn, Int32 nFILRet); +static void _ReportWriteFailureSingle(UInt16 wFailingCE, UInt32 dwPPN, Int32 nFILRet); +static void _ReportWriteScatteredFailBlock(UInt16 wFailingCE, UInt32 wVbn, + UInt32 wFailingPage, UInt16 ceList[], UInt32 physPageList[], UInt16 wPagesToWriteNow, Int32 nFILRet); +static void _ReportWriteMultipleFailBlock(UInt16 wFailingCE, UInt32 wVbn, + UInt32 wFailingPage, UInt32 adwPpnRemapped[], UInt16 wPagesToWriteNow, Int32 nFILRet); +static void _ReportEraseFailureMultiple(UInt16 wFailingCE, UInt16 dwVbn, Int32 nFILRet); +static void _ReportEraseFailureSingle(UInt16 wFailingCE, UInt16 dwBlock, Int32 nFILRet); +#endif + +#define WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS (3) + +#define VFL_NUM_OF_VFL_CXT_COPIES (8) +#define VFL_MAX_NUM_OF_VFL_CXT_ERRORS (3) + +void _Vpn2Cbn(UInt32 dwVpn, UInt16 *pwCS, UInt16 *pdwCbn) +{ + UInt16 wVbn, wBank, wTbn, wPbn; + + wVbn = _Vpn2Vbn(dwVpn); + wBank = _Vpn2Bank(dwVpn); + wTbn = _Vbn2Tbn(wVbn); + _ConvertT2P(wBank, wTbn, &wPbn); + *pwCS = _Bank2CS(wBank); + *pdwCbn = _RemapBlock(*pwCS, wPbn, NULL, NULL); +} + +void _Vpn2Ppn(UInt32 dwVpn, UInt16 *pwCS, UInt32 *pdwPpn) +{ + UInt16 wVbn, wBank, wTbn, wPbn, wPOffset; + + wVbn = _Vpn2Vbn(dwVpn); + wBank = _Vpn2Bank(dwVpn); + wTbn = _Vbn2Tbn(wVbn); + _ConvertT2P(wBank, wTbn, &wPbn); + *pwCS = _Bank2CS(wBank); + wPbn = _RemapBlock(*pwCS, wPbn, NULL, NULL); + wPOffset = (UInt16)((dwVpn % PAGES_PER_SUBLK) / BANKS_TOTAL); + *pdwPpn = _Cbn2Ppn(wPbn, wPOffset); +} + +static void _NANDCheckSum(UInt32 * pbaData, UInt32 dwDataSize, UInt32 * pdwCheckSum1, UInt32 * pdwCheckSum2) +{ + UInt32 dwIdx; + UInt32 dwXorsum; + UInt32 dwChecksum; + + dwChecksum = 0; + dwXorsum = 0; + for (dwIdx = 0; dwIdx < (dwDataSize / 4); dwIdx++) + { + dwChecksum += pbaData[dwIdx]; + dwXorsum ^= pbaData[dwIdx]; + } + /* avoid passing when vflcxt is zeroed */ + *pdwCheckSum1 = dwChecksum + 0xAABBCCDD; + *pdwCheckSum2 = dwXorsum ^ 0xAABBCCDD; +} + +static BOOL32 _CheckVFLCxtDataIsUntouched(UInt16 wCS) +{ + UInt32 dwTempCheckSum; + UInt32 dwTempXor; + static UInt32 dwCount = 0; + + WMR_ASSERT(wCS < CS_TOTAL); + + dwCount++; + _NANDCheckSum((UInt32*)&pstVFLMeta[wCS], (sizeof(VFLMeta) - (2 * sizeof(UInt32))), &dwTempCheckSum, &dwTempXor); + if (!((dwTempCheckSum == pstVFLMeta[wCS].dwCheckSum) && (dwTempXor == pstVFLMeta[wCS].dwXorSum)) ) + { + return FALSE32; + } + return TRUE32; +} +static void _UpdateVFLCxtChecksum(UInt16 wCS) +{ + _NANDCheckSum((UInt32*)&pstVFLMeta[wCS], (sizeof(VFLMeta) - (2 * sizeof(UInt32))), &pstVFLMeta[wCS].dwCheckSum, &pstVFLMeta[wCS].dwXorSum); +} + +typedef struct +{ + void (*UpdateChecksum)(UInt16 wCS); + BOOL32 (*VerifyChecksum)(UInt16 wCS); +} ChecksumFuncStruct; + +static ChecksumFuncStruct vflChecksumFunc; + +#define RECALC_VFL_CXT_CHECK_SUM(cs) vflChecksumFunc.UpdateChecksum(cs) + +#define CHECK_VFL_CXT_CHECK_SUM(cs) \ + { \ + if (vflChecksumFunc.VerifyChecksum(cs) == FALSE32) { \ + WMR_ASSERT(0); } \ + } + +#define CHECK_VFL_CXT_CHECK_SUM_NO_ASSERT(cs) vflChecksumFunc.VerifyChecksum(cs) + +static BOOL32 _isBlockGood(UInt8 * pbaBBT, UInt16 wIdx) +{ + UInt16 dByteLocation; + UInt8 bBit; + + dByteLocation = ((UInt16)wIdx) >> 3; + bBit = (1 << (((UInt8)wIdx) & 0x07)); + if (pbaBBT[dByteLocation] & bBit) + { + return TRUE32; + } + return FALSE32; +} + + +static void _ReportECCFailureMultiple(UInt16 wVbn) +{ + UInt16 wBankIdx; + + WMR_MEMSET(&gstLastFailure, VFL_VALUE_UNKNOWN, sizeof(VFLFailureDetails)); + gstLastFailure.mode = VFLFailUECC; + + // Restrict the number reported, since this is really broad + // Hopefully someone will read-single through this and find the real error + for (wBankIdx = 0; + (wBankIdx < BANKS_TOTAL) && (wBankIdx < VFL_MAX_FAILURE_REGIONS); + ++wBankIdx ) + { + gstLastFailure.wCE[wBankIdx] = _Bank2CS(wBankIdx); + _ConvertT2P(wBankIdx, _Vbn2Tbn(wVbn), &gstLastFailure.wPhysicalBlock[wBankIdx]); + } +} + +static void _ReportECCFailureSingle(UInt16 wFailingCE, UInt16 dwPPN) +{ + WMR_MEMSET(&gstLastFailure, VFL_VALUE_UNKNOWN, sizeof(VFLFailureDetails)); + gstLastFailure.mode = VFLFailUECC; + gstLastFailure.wCE[0] = wFailingCE; + gstLastFailure.wPhysicalBlock[0] = dwPPN / PAGES_PER_BLOCK; + gstLastFailure.dwPhysicalPage = dwPPN; +} + + +#ifndef AND_READONLY +static void _MarkWriteFailBlockForDeleteWithVpn(UInt16 wFailingCE, UInt32 dwVpn) +{ + UInt16 wPbn; + UInt16 wBankIdx; + + UInt16 wVbn = _Vpn2Vbn(dwVpn); + + if (wFailingCE < CS_TOTAL) + { + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + //scrub all blocks in failed CE + if (_Bank2CS(wBankIdx) == wFailingCE) + { + _ConvertT2P(wBankIdx, _Vbn2Tbn(wVbn), &wPbn); + _AddBlockToScrubList(wFailingCE, wPbn); + VFL_WRN_PRINT((TEXT("[VFL:WRN] Marked write fail block for delete, CE %d, block 0x%X (line:%d)\n"), wFailingCE, wPbn, __LINE__)); + } + } + } + else + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] invalid CE 0x%X, no marking done (line:%d).\n"), wFailingCE, __LINE__)); + } +} + +static void _MarkWriteFailBlockForDeleteWithPbn(UInt16 wFailingCE, UInt16 wPbn) +{ + _AddBlockToScrubList(wFailingCE, wPbn); + VFL_WRN_PRINT((TEXT("[VFL:WRN] Marked write fail block for delete, CE %d, block 0x%X (line:%d)\n"), wFailingCE, wPbn, __LINE__)); +} + + +static void _MarkWriteScatteredFailBlockForDelete(UInt16 wFailingCE, UInt32 dwVpn, UInt32 wFailingPage, + UInt16 ceList[], UInt32 physPageList[], UInt16 wPbnUnmapped[], UInt16 wPagesToWriteNow) +{ + BOOL32 foundFailingPageInfo = FALSE32; + UInt16 wIndex; + for ( wIndex = 0; wIndex < wPagesToWriteNow; wIndex++ ) + { + if ( (ceList[wIndex] == wFailingCE) && (physPageList[wIndex] == wFailingPage) ) + { + _MarkWriteFailBlockForDeleteWithPbn(wFailingCE, wPbnUnmapped[wIndex]); + foundFailingPageInfo = TRUE32; + break; + } + } + if ( !foundFailingPageInfo ) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] Failed to find failing page (pg: 0x%x, CE: %d, CS[] @ %p, pg[] @ %p, n=%d)\n"), + wFailingPage,wFailingCE,ceList,physPageList,wPagesToWriteNow)); + _MarkWriteFailBlockForDeleteWithVpn(wFailingCE, dwVpn); + } +} + +static void _MarkWriteMultipleFailBlockForDelete(UInt16 wFailingCE, UInt32 dwVpn, UInt32 wFailingPage, + UInt16 awPbnUnmapped[], UInt16 awPbnRemapped[], UInt32 adwPpnRemapped[], UInt16 wPagesToWriteNow) +{ + BOOL32 foundFailingPageInfo = FALSE32; + int iSlice = -1; + UInt32 wIndex; + VFL_WRN_PRINT((TEXT("[VFL:WRN] Scanning for page 0x%x\n"),wFailingPage)); + for ( wIndex = 0; wIndex < wPagesToWriteNow; wIndex++ ) + { + if ( 0 == (wIndex % BANKS_TOTAL) ) + { + iSlice++; + } + if ( (_Bank2CS(wIndex % BANKS_TOTAL) == wFailingCE) && ((adwPpnRemapped[wIndex % BANKS_TOTAL] + iSlice) == wFailingPage) ) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] Found page on slice %d (of %d), pg: 0x%x, blk: 0x%x\n"), + iSlice,wPagesToWriteNow,(adwPpnRemapped[wIndex % BANKS_TOTAL] + iSlice),awPbnRemapped[wIndex % BANKS_TOTAL])); + _MarkWriteFailBlockForDeleteWithPbn(wFailingCE, awPbnUnmapped[wIndex % BANKS_TOTAL]); + foundFailingPageInfo = TRUE32; + break; + } + } + if ( !foundFailingPageInfo ) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] Failed to find failing page! Falling back to CE/Vpn\n"))); + _MarkWriteFailBlockForDeleteWithVpn(wFailingCE, dwVpn); + } +} + +static void _ReportWriteFailureMultiple(UInt16 wFailingCE, UInt32 dwVbn, Int32 nFILRet) +{ + UInt16 wBankIdx; + UInt16 wFailIdx; + + WMR_MEMSET(&gstLastFailure, VFL_VALUE_UNKNOWN, sizeof(VFLFailureDetails)); + if(nFILRet == FIL_CRITICAL_ERROR) + { + gstLastFailure.mode = VFLFailWriteTimeOut; + return; + } + gstLastFailure.mode = VFLFailWrite; + + wFailIdx = 0; + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; ++wBankIdx) + { + if (_Bank2CS(wBankIdx) == wFailingCE) + { + gstLastFailure.wCE[wFailIdx] = wFailingCE; + _ConvertT2P(wBankIdx, _Vbn2Tbn(dwVbn), &gstLastFailure.wPhysicalBlock[wFailIdx]); + wFailIdx += 1; + } + } +} + +static void _ReportWriteFailureSingle(UInt16 wFailingCE, UInt32 dwPPN, Int32 nFILRet) +{ + WMR_MEMSET(&gstLastFailure, VFL_VALUE_UNKNOWN, sizeof(VFLFailureDetails)); + + if(nFILRet == FIL_CRITICAL_ERROR) + { + gstLastFailure.mode = VFLFailWriteTimeOut; + return; + } + + gstLastFailure.mode = VFLFailWrite; + + gstLastFailure.wCE[0] = wFailingCE; + gstLastFailure.wPhysicalBlock[0] = dwPPN / PAGES_PER_BLOCK; + gstLastFailure.dwPhysicalPage = dwPPN; +} + +static void _ReportWriteScatteredFailBlock(UInt16 wFailingCE, UInt32 wVbn, UInt32 wFailingPage, + UInt16 ceList[], UInt32 physPageList[], UInt16 wPagesToWriteNow, Int32 nFILRet) +{ + BOOL32 foundFailingPageInfo = FALSE32; + UInt16 wIndex; + for ( wIndex = 0; wIndex < wPagesToWriteNow; wIndex++ ) + { + if ( (ceList[wIndex] == wFailingCE) && (physPageList[wIndex] == wFailingPage) ) + { + _ReportWriteFailureSingle(wFailingCE,wFailingPage, nFILRet); + foundFailingPageInfo = TRUE32; + break; + } + } + if ( !foundFailingPageInfo ) + { + VFL_ERR_PRINT((TEXT("Failed to find failing page (pg: 0x%x, CE: %d, CS[] @ %p, pg[] @ %p, n=%d)\n"), + wFailingPage,wFailingCE,ceList,physPageList,wPagesToWriteNow)); + _ReportWriteFailureMultiple(wFailingCE, wVbn, nFILRet); + } +} + +static void _ReportWriteMultipleFailBlock(UInt16 wFailingCE, UInt32 wVbn, UInt32 wFailingPage, + UInt32 adwPpnRemapped[], UInt16 wPagesToWriteNow, Int32 nFILRet) +{ + BOOL32 foundFailingPageInfo = FALSE32; + int iSlice = -1; + UInt32 wIndex; + for ( wIndex = 0; wIndex < wPagesToWriteNow; wIndex++ ) + { + if ( 0 == (wIndex % BANKS_TOTAL) ) + { + iSlice++; + } + if ( (_Bank2CS(wIndex % BANKS_TOTAL) == wFailingCE) && ((adwPpnRemapped[wIndex % BANKS_TOTAL] + iSlice) == wFailingPage) ) + { + _ReportWriteFailureSingle(wFailingCE, wFailingPage, nFILRet); + foundFailingPageInfo = TRUE32; + break; + } + } + if ( !foundFailingPageInfo ) + { + _ReportWriteFailureMultiple(wFailingCE, wVbn, nFILRet); + } +} + +static void _ReportEraseFailureMultiple(UInt16 wFailingCE, UInt16 dwVbn, Int32 nFILRet) +{ + UInt16 wBankIdx; + UInt16 wFailIdx; + + WMR_MEMSET(&gstLastFailure, VFL_VALUE_UNKNOWN, sizeof(VFLFailureDetails)); + if(nFILRet == FIL_CRITICAL_ERROR) + { + gstLastFailure.mode = VFLFailEraseTimeOut; + return; + } + gstLastFailure.mode = VFLFailErase; + + wFailIdx = 0; + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; ++wBankIdx) + { + if (_Bank2CS(wBankIdx) == wFailingCE) + { + gstLastFailure.wCE[wFailIdx] = wFailingCE; + _ConvertT2P(wBankIdx, _Vbn2Tbn(dwVbn), &gstLastFailure.wPhysicalBlock[wFailIdx]); + wFailIdx += 1; + } + } +} + +static void _ReportEraseFailureSingle(UInt16 wFailingCE, UInt16 dwBlock, Int32 nFILRet) +{ + WMR_MEMSET(&gstLastFailure, VFL_VALUE_UNKNOWN, sizeof(VFLFailureDetails)); + if(nFILRet == FIL_CRITICAL_ERROR) + { + gstLastFailure.mode = VFLFailEraseTimeOut; + return; + } + gstLastFailure.mode = VFLFailErase; + + gstLastFailure.wCE[0] = wFailingCE; + gstLastFailure.wPhysicalBlock[0] = dwBlock; +} + +static BOOL32 _AddBlockToScrubList(UInt16 wCS, UInt16 wPbn) +{ + VFLCxt * pVFLCxt = GET_VFLCxt(wCS); + + if (_IsBlockInScrubList(wCS, wPbn) == TRUE32) + { + return TRUE32; + } + + /* make sure we do not get close to the wBadMapTableMaxIdx */ + if (pVFLCxt->wScrubIdx >= VFL_SCRUB_LIST_SIZE) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _AddBlockToScrubList pVFLCxt->wScrubIdx = %d wCS = %d (line:%d)\n"), pVFLCxt->wScrubIdx, wCS, __LINE__)); + return FALSE32; + } + CHECK_VFL_CXT_CHECK_SUM(wCS); + pVFLCxt->awScrubList[pVFLCxt->wScrubIdx] = wPbn; + pVFLCxt->wScrubIdx++; + RECALC_VFL_CXT_CHECK_SUM(wCS); + return _StoreVFLCxt(wCS); +} + +static BOOL32 _IsBlockInScrubList(UInt16 wCS, UInt16 wPbn) +{ + VFLCxt * pVFLCxt = GET_VFLCxt(wCS); + UInt16 wScrubIdx = 0; + + for (wScrubIdx = 0; wScrubIdx < pVFLCxt->wScrubIdx; wScrubIdx++) + { + if (pVFLCxt->awScrubList[wScrubIdx] == wPbn) + { + return TRUE32; + } + } + return FALSE32; +} + +static BOOL32 _RemoveBlockFromScrubList(UInt16 wCS, UInt16 wPbn) +{ + VFLCxt * pVFLCxt = GET_VFLCxt(wCS); + UInt16 wScrubIdx = 0; + + if (_IsBlockInScrubList(wCS, wPbn) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _RemoveBlockFromScrubList(%d, 0x%X) failed calling _IsBlockInScrubList (line:%d)\n"), wCS, wPbn, __LINE__)); + return FALSE32; + } + for (wScrubIdx = 0; wScrubIdx < pVFLCxt->wScrubIdx; wScrubIdx++) + { + if (pVFLCxt->awScrubList[wScrubIdx] == wPbn) + { + CHECK_VFL_CXT_CHECK_SUM(wCS); + pVFLCxt->awScrubList[wScrubIdx] = 0; + /* we found the block - if it is in the middle of the list replace it with the bottom one */ + if ((wScrubIdx != pVFLCxt->wScrubIdx) && (pVFLCxt->wScrubIdx != 1)) + { + pVFLCxt->awScrubList[wScrubIdx] = pVFLCxt->awScrubList[pVFLCxt->wScrubIdx - 1]; + } + pVFLCxt->wScrubIdx--; + RECALC_VFL_CXT_CHECK_SUM(wCS); + return _StoreVFLCxt(wCS); + } + } + return FALSE32; +} + +#if AND_SUPPORT_BLOCK_BORROWING + +static void _MarkReservedBlock(const UInt16 wCS, const UInt16 wPbn, const UInt32 dwReplacementIdx, const UInt16 wMark) +{ + VFLCxt *pVFLCxt = &pstVFLMeta[wCS].stVFLCxt; + UInt8 *pabBBT = pstabCSBBTArea[wCS]; + + // Make sure we aren't being asked to lend a bad block + WMR_ASSERT(_isBlockGood(pabBBT, wPbn)); + + _MarkBlockAsBadInBBT(pabBBT, wPbn); + + // Find the replacement index of the block we've been asked to lend + WMR_ASSERT(dwReplacementIdx < (UInt32)VFL_RESERVED_SECTION_SIZE_CS); + WMR_ASSERT(VFL_BAD_MAP_TABLE_AVAILABLE_MARK == pVFLCxt->awBadMapTable[dwReplacementIdx]); + + // Mark that block as used (but don't change replacement index + pVFLCxt->awBadMapTable[dwReplacementIdx] = wMark; +} + +static void _findBestBlockToBorrow(UInt16 *pdwCE, UInt16 *pdwCbn, UInt32 *pdwReplacementIdx) +{ + // Find a CE/Block pair that is eligible to borrow + UInt16 wBank; + UInt16 wCS; + UInt16 wSearchIdx; + UInt16 wStartIdx; + UInt16 wEndIdx; + + UInt32 dwMostAvailableBlocks = 0; + UInt32 dwBestBank = ~0; + UInt32 dwBestCS = ~0; + + VFLCxt *pVFLCxt = NULL; + + // Select the bank with the most replacement blocks available + for (wCS = 0; wCS < CS_TOTAL; ++wCS) + { + UInt16 *pawReplacements = pstVFLMeta[wCS].stVFLCxt.awReplacementIdx; + pVFLCxt = &pstVFLMeta[wCS].stVFLCxt; + for (wBank = 0; wBank < BANKS_PER_CS; ++wBank) + { + UInt32 dwAvailableBlocks = 0; + for(wSearchIdx = pawReplacements[wBank]; + wSearchIdx < ((wBank + 1) * VFL_RESERVED_SECTION_SIZE_BANK); + ++wSearchIdx) + { + if (VFL_BAD_MAP_TABLE_AVAILABLE_MARK == pVFLCxt->awBadMapTable[wSearchIdx]) + { + dwAvailableBlocks++; + } + } + if (dwAvailableBlocks > dwMostAvailableBlocks) + { + dwMostAvailableBlocks = dwAvailableBlocks; + dwBestCS = wCS; + dwBestBank = wBank; + } + } + } + // Make sure we found a candidate + if (!((dwBestCS < CS_TOTAL) && (dwBestBank < BANKS_PER_CS))) + { +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) + WMR_SIM_EXIT("Out of blocks for borrowing\n"); +#endif // AND_SIMULATOR + WMR_PANIC("Out of blocks for borrowing\n"); + } + + // Find the last replacement block on that Bank/CS + pVFLCxt = &pstVFLMeta[dwBestCS].stVFLCxt; + // Calculate the last reserved area index for the selected bank + wStartIdx = ((dwBestBank + 1) * VFL_RESERVED_SECTION_SIZE_BANK) - 1; + wEndIdx = pVFLCxt->awReplacementIdx[dwBestBank]; + for (wSearchIdx = wStartIdx; wSearchIdx >= wEndIdx; --wSearchIdx) + { + if (VFL_BAD_MAP_TABLE_AVAILABLE_MARK == pVFLCxt->awBadMapTable[wSearchIdx]) + { + UInt16 wPbn; + *pdwCE = dwBestCS; + _ConvertT2P(_CSBank2Bank(dwBestCS, _ReserveIdx2Bank(wSearchIdx)), _ReserveIdx2Tbn(wSearchIdx), &wPbn); + *pdwCbn = wPbn; + *pdwReplacementIdx = wSearchIdx; + return; + } + } + WMR_PANIC("No available blocks found CE %d Bank %d\n", (UInt32) dwBestCS, (UInt32) dwBestBank); +} + +static BOOL32 _stressBlock(UInt16 wCS, UInt16 wCbn) +{ + // Initial block screening intended to weed out beginning-of-bathtub failures +#define TEST_ITERATIONS (3) + const UInt8 bTestPattern[TEST_ITERATIONS] = {0x00, 0xA5, 0x5A}; + UInt32 dwIteration; + Int32 andStatus; + UInt32 dwPageOffset; + BOOL32 result = FALSE32; + Buffer *pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + Buffer *pBufVerify = BUF_Get(BUF_MAIN_AND_SPARE); + + WMR_ASSERT(NULL != pBuf); + WMR_ASSERT(NULL != pBufVerify); + + for (dwIteration = 0; dwIteration < TEST_ITERATIONS; ++dwIteration) + { + andStatus = pFuncTbl->Erase(wCS, _Cbn2Pbn(wCbn)); + if (ANDErrorCodeOk != andStatus) + { + WMR_PRINT(ERROR, "Iteration %d write CE %d Block %d failed 0x%08x\n", + dwIteration, (UInt32) wCS, _Cbn2Pbn(wCbn), andStatus); + result = FALSE32; + goto exit; + } + + WMR_MEMSET(pBuf->pSpare, 0, stVSVFLWMRDeviceInfo.dwValidMetaPerLogicalPage); + + for(dwPageOffset = 0; dwPageOffset < PAGES_PER_BLOCK; ++dwPageOffset) + { + const UInt32 dwPageAddress = _Cbn2Ppn(wCbn, dwPageOffset); + WMR_MEMSET(pBuf->pData, bTestPattern[dwIteration] + dwPageOffset, BYTES_PER_PAGE); + WMR_MEMCPY(pBuf->pSpare, &dwPageAddress, sizeof(dwPageAddress)); + andStatus = pFuncTbl->Write(wCS, dwPageAddress, pBuf->pData, pBuf->pSpare, TRUE32); + if (ANDErrorCodeOk != andStatus) + { + WMR_PRINT(VFLWARN, "Iteration %d write CE %d Page %d failed 0x%08x\n", + dwIteration, (UInt32) wCS, dwPageAddress, andStatus); + result = FALSE32; + goto exit; + } + } + + for(dwPageOffset = 0; dwPageOffset < PAGES_PER_BLOCK; ++dwPageOffset) + { + const UInt32 dwPageAddress = _Cbn2Ppn(wCbn, dwPageOffset); + UInt8 bCorrectedBits = 0; + + // Set up expected data + WMR_MEMSET(pBuf->pData, bTestPattern[dwIteration] + dwPageOffset, BYTES_PER_PAGE); + WMR_MEMCPY(pBuf->pSpare, &dwPageAddress, sizeof(dwPageAddress)); + + // Watermark + WMR_MEMSET(pBufVerify->pSpare, 0xB6, stVSVFLWMRDeviceInfo.dwValidMetaPerLogicalPage); + WMR_MEMSET(pBufVerify->pData, 0xC7, BYTES_PER_PAGE); + andStatus = pFuncTbl->ReadWithECC(wCS, dwPageAddress, pBufVerify->pData, pBufVerify->pSpare, &bCorrectedBits, NULL, TRUE32); + if (ANDErrorCodeOk != andStatus) + { + WMR_PRINT(ERROR, "Iteration %d read CE %d Page %d failed 0x%08x\n", + dwIteration, (UInt32) wCS, dwPageAddress, andStatus); + result = FALSE32; + goto exit; + } + + if (WMR_MEMCMP(pBufVerify->pData, pBuf->pData, BYTES_PER_PAGE)) + { + WMR_PRINT(ERROR, "Iteration %d main data miscompare CE %d Page %d\n", + dwIteration, (UInt32) wCS, dwPageAddress); + result = FALSE32; + goto exit; + } + + if (WMR_MEMCMP(pBufVerify->pSpare, pBuf->pSpare, stVSVFLWMRDeviceInfo.dwValidMetaPerLogicalPage)) + { + WMR_PRINT(ERROR, "Iteration %d metadata miscompare CE %d Page %d\n", + dwIteration, (UInt32) wCS, dwPageAddress); + result = FALSE32; + goto exit; + } + + if (bCorrectedBits >= stVSVFLWMRDeviceInfo.bRefreshThreshold) + { + WMR_PRINT(ERROR, "Iteration %d exceeded refresh CE %d Page %d\n", + dwIteration, (UInt32) wCS, dwPageAddress); + result = FALSE32; + goto exit; + } + } + } + + result = TRUE32; + + andStatus = pFuncTbl->Erase(wCS, _Cbn2Pbn(wCbn)); + if (ANDErrorCodeOk != andStatus) + { + WMR_PRINT(ERROR, "Cleanup erase failed 0x%08x\n", andStatus); + result = FALSE32; + } + +exit: + + BUF_Release(pBuf); + BUF_Release(pBufVerify); + + WMR_PRINT(ALWAYS, "CE %d Block %d %s\n", + (UInt32) wCS, (UInt32) _Cbn2Pbn(wCbn), (result ? "PASSED" : "FAILED")); + + return result; +} + +static BOOL32 _BorrowSpareBlock(UInt16 *pdwCE, UInt16 *pdwBlock) +{ + UInt16 wBlock = ~0; + UInt16 wCS = ~0; + UInt32 dwReplacementIdx = ~0; + BOOL32 found = FALSE32; + + if ((NULL == pdwCE) || (NULL == pdwBlock)) + { + return FALSE32; + } + + // Find blocks until one passes initial screening + while (!found) + { + _findBestBlockToBorrow(&wCS, &wBlock, &dwReplacementIdx); + if (_stressBlock(wCS, wBlock)) + { + found = TRUE32; + } + else + { + CHECK_VFL_CXT_CHECK_SUM(wCS); + _MarkReservedBlock(wCS, wBlock, dwReplacementIdx, VFL_BAD_MAP_TABLE_STRESS_FAIL_MARK); + RECALC_VFL_CXT_CHECK_SUM(wCS); + if (!_StoreVFLCxt(wCS)) + { + WMR_PANIC("_StoreVFLCxt(%d) failed\n", (UInt32) wCS); + } + } + } + + // Take the block from the reserved area + CHECK_VFL_CXT_CHECK_SUM(wCS); + _MarkReservedBlock(wCS, wBlock, dwReplacementIdx, VFL_BAD_MAP_TABLE_BORROW_MARK); + RECALC_VFL_CXT_CHECK_SUM(wCS); + + if (!_StoreVFLCxt(wCS)) + { + WMR_PANIC("_StoreVFLCxt(%d) failed\n", (UInt32) wCS); + } + + // Report physical address to the caller (to be passed directly to FIL) + *pdwCE = wCS; + *pdwBlock = _Cbn2Pbn(wBlock); + + return TRUE32; +} + +static BOOL32 _VSVFL_BorrowBlock(UInt32 *pdwCE, UInt32 *pdwPhysicalBlock, UInt16 wType) +{ + UInt16 ce; + UInt16 block; + BOOL32 ret; + + if (AND_SB_TYPE_NAND_BOOT != wType) + { + // only support nand-boot blocks for now + ret = FALSE32; + } + else if ((NULL == pdwCE) || (NULL == pdwPhysicalBlock)) + { + ret = FALSE32; + } + else + { + ret = _BorrowSpareBlock(&ce, &block); + *pdwCE = ce; + *pdwPhysicalBlock = block; + } + + return ret; +} + +#endif // AND_SUPPORT_BLOCK_BORROWING +#endif // ! AND_READONLY + +#if AND_SUPPORT_BLOCK_BORROWING +static BOOL32 _VSVFL_FindBorrowedBlocks(BorrowBlockAddress *pastrBlocks, UInt32 *pdwnumBlocks) +{ + UInt16 wCE, wReserveIdx, wBlockIdx; + + if (NULL == pdwnumBlocks) + { + return FALSE32; + } + + wBlockIdx = 0; + for (wCE = 0; + wCE < CS_TOTAL; + ++wCE) + { + UInt16 *pawMap = pstVFLMeta[wCE].stVFLCxt.awBadMapTable; + + for (wReserveIdx = 0; + wReserveIdx < VFL_RESERVED_SECTION_SIZE_CS; + ++wReserveIdx) + { + if ( VFL_BAD_MAP_TABLE_BORROW_MARK == pawMap[wReserveIdx]) + { + if ((NULL != pastrBlocks)) + { + UInt16 wCbn; + pastrBlocks[wBlockIdx].dwPhysicalCE = wCE; + _ConvertT2P(_CSBank2Bank(wCE, _ReserveIdx2Bank(wReserveIdx)), _ReserveIdx2Tbn(wReserveIdx), &wCbn); + pastrBlocks[wBlockIdx].dwPhysicalBlock = _Cbn2Pbn(wCbn); + pastrBlocks[wBlockIdx].wType = AND_SB_TYPE_NAND_BOOT; + } + ++wBlockIdx; + if (wBlockIdx >= *pdwnumBlocks) + { + *pdwnumBlocks = wBlockIdx; + return TRUE32; + } + } + } + + } + *pdwnumBlocks = wBlockIdx; + + return TRUE32; +} +#endif // AND_SUPPORT_BLOCK_BORROWING + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ +/*****************************************************************************/ +/* */ +/* NAME */ +/* _GetVFLSpare */ +/* DESCRIPTION */ +/* This function returns VFL context info from spare area. */ +/* PARAMETERS */ +/* *pdwAge [OUT] the pointer of context age */ +/* *pStatus [OUT] the pointer of status mark */ +/* *pSBu [IN] the pointer of spare buffer */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static void +_GetVFLSpare(UInt32 *pdwAge, UInt8 *pStatus, UInt8 *pbType, UInt8 *pSBuf) +{ + VFLSpare *pSpare = (VFLSpare *)pSBuf; + + if (pdwAge != NULL) + { + *pdwAge = pSpare->dwCxtAge; + } + if (pbType != NULL) + { + *pbType = pSpare->bSpareType; + } + if (pStatus != NULL) + { + *pStatus = pSpare->cStatusMark; + } +} + +#ifndef AND_READONLY +/* + + NAME + _SetVFLSpare + DESCRIPTION + This function stores VFL context info on spare area. + PARAMETERS + *pdwAge [OUT] the pointer of context age + *pSBuf [IN] the pointer of spare buffer + RETURN VALUES + none + NOTES + + */ +static void +_SetVFLSpare(UInt32 *pdwAge, UInt8 *pSBuf) +{ + VFLSpare *pSpare = (VFLSpare *)pSBuf; + + if (pdwAge != NULL) + { + pSpare->dwCxtAge = *pdwAge; + } + /* the status mark of MLC is always valid */ + pSpare->cStatusMark = PAGE_VALID; + pSpare->bSpareType = VFL_SPARE_TYPE_CXT; +} + +// helper function list sorting +static void _SortList(UInt16 *pawIndex, UInt16 * pawValues, UInt16 wSize) +{ + UInt16 wIdx1, wIdx2; + + if (wSize == 1) + { + return; + } + for (wIdx1 = 0; wIdx1 < (wSize - 1); wIdx1++) + { + for (wIdx2 = wIdx1 + 1; wIdx2 < wSize; wIdx2++) + { + if (pawValues[pawIndex[wIdx2]] < pawValues[pawIndex[wIdx1]]) + { + UInt16 wTemp = pawIndex[wIdx2]; + pawIndex[wIdx2] = pawIndex[wIdx1]; + pawIndex[wIdx1] = wTemp; + } + } + } +} + +/** + * Replaces bad block, updating CXT but does NOT update the + * checksum -- the caller must do that. + * + * @return BOOL32 + */ +static BOOL32 _ReplaceBadBlock(UInt16 wCS, UInt16 wPbn) +{ + VFLCxt *pVFLCxt = &pstVFLMeta[wCS].stVFLCxt; + UInt16 wTbn, wBank, wIdx; + UInt16 awBanksSorted[AND_MAX_BANKS_PER_CS]; + UInt8 *pabBBT = pstabCSBBTArea[wCS]; + + _MarkBlockAsBadInBBT(pabBBT, wPbn); + _ConvertP2T(wPbn, &wBank, &wTbn); + + // first thing make sure the block was not replaced by another block + // if it did mark that block as bad and cancel the previous replacement + for (wIdx = 0; wIdx < VFL_RESERVED_SECTION_SIZE_CS; wIdx++) + { + if (pVFLCxt->awBadMapTable[wIdx] == wPbn) + { + UInt16 wTempPbn; + pVFLCxt->awBadMapTable[wIdx] = VFL_BAD_MAP_TABLE_BAD_MARK; + // mark the replacement block as bad + _ConvertT2P(_CSBank2Bank(wCS, _ReserveIdx2Bank(wIdx)), _ReserveIdx2Tbn(wIdx), &wTempPbn); + _MarkBlockAsBadInBBT(pabBBT, wTempPbn); + } + } + + // check if we can replace the block from its own bank + if (pVFLCxt->awReplacementIdx[wBank] < VFL_RESERVED_SECTION_SIZE_BANK) + { + while (pVFLCxt->awReplacementIdx[wBank] < VFL_RESERVED_SECTION_SIZE_BANK) + { + UInt16 wNextReplacementBlkIdx = pVFLCxt->awReplacementIdx[wBank] + (wBank * VFL_RESERVED_SECTION_SIZE_BANK); + if (pVFLCxt->awBadMapTable[wNextReplacementBlkIdx] == VFL_BAD_MAP_TABLE_AVAILABLE_MARK) + { + pVFLCxt->awBadMapTable[wNextReplacementBlkIdx] = wPbn; + pVFLCxt->awReplacementIdx[wBank]++; + return TRUE32; + } + pVFLCxt->awReplacementIdx[wBank]++; + } + } + + // check which other block as the most available blocks + for (wIdx = 0; wIdx < BANKS_PER_CS; wIdx++) + { + awBanksSorted[wIdx] = wIdx; + } + + _SortList(awBanksSorted, pVFLCxt->awReplacementIdx, BANKS_PER_CS); + for (wIdx = 0; wIdx < BANKS_PER_CS; wIdx++) + { + if (pVFLCxt->awReplacementIdx[awBanksSorted[wIdx]] < VFL_RESERVED_SECTION_SIZE_BANK) + { + while (pVFLCxt->awReplacementIdx[awBanksSorted[wIdx]] < VFL_RESERVED_SECTION_SIZE_BANK) + { + UInt16 wNextReplacementBlkIdx = pVFLCxt->awReplacementIdx[awBanksSorted[wIdx]] + (awBanksSorted[wIdx] * VFL_RESERVED_SECTION_SIZE_BANK); + if (pVFLCxt->awBadMapTable[wNextReplacementBlkIdx] == VFL_BAD_MAP_TABLE_AVAILABLE_MARK) + { + pVFLCxt->awBadMapTable[wNextReplacementBlkIdx] = wPbn; + pVFLCxt->awReplacementIdx[awBanksSorted[wIdx]]++; + return TRUE32; + } + pVFLCxt->awReplacementIdx[awBanksSorted[wIdx]]++; + } + } + } + // no reason to continue once NAND runs out of replacement blocks +#if (defined(AND_SIMULATOR) && AND_SIMULATOR) + WMR_SIM_EXIT("Out of replacement blocks"); +#else // defined(AND_SIMULATOR) && AND_SIMULATOR + WMR_PANIC("Failed _ReplaceBadBlock CE %d PBN %d", (UInt32) wCS, (UInt32) wPbn); +#endif // defined(AND_SIMULATOR) && AND_SIMULATOR + return FALSE32; +} +#endif // ! AND_READONLY + +static UInt16 _RemapBlock(UInt16 wCS, UInt16 wPbn, BOOL32 *pboolAligned, BOOL32 *pboolCorrectBank) +{ + UInt16 wIdx; + UInt8 * pabBBT = pstabCSBBTArea[wCS]; + VFLCxt * pVFLCxt = GET_VFLCxt(wCS); + + // check if the original block is bad + if (_isBlockGood(pabBBT, wPbn) == TRUE32) + { + return wPbn; + } + + if (pboolAligned != NULL) + { + *pboolAligned = FALSE32; + } + for (wIdx = 0; wIdx < VFL_RESERVED_SECTION_SIZE_CS; wIdx++) + { + if (pVFLCxt->awBadMapTable[wIdx] == wPbn) + { + UInt16 wRemappedPbn, wTbn, wBank; + wBank = _CSBank2Bank(wCS, _ReserveIdx2Bank(wIdx)); + wTbn = _ReserveIdx2Tbn(wIdx); + _ConvertT2P(wBank, wTbn, &wRemappedPbn); + if (pboolCorrectBank != NULL) + { + UInt16 wOrgBank, wOrgTbn; + _ConvertP2T(wPbn, &wOrgBank, &wOrgTbn); + if (_Bank2CSBank(wBank) != wOrgBank) + { + *pboolCorrectBank = FALSE32; + } + } + return wRemappedPbn; + } + } + WMR_PANIC("Failed to map CE %d Block 0x%04x\n", (UInt32) wCS, (UInt32) wPbn); + return VFL_BAD_MAP_TABLE_BAD_MARK; +} + +#ifndef AND_READONLY +/* writes the VFLCxt 8 times to and verifies it was written properly at least 5 times */ +static BOOL32 _WriteVFLCxtToFlash(UInt16 wCS) +{ + UInt16 wPageIdx, wNumOfErrors; + UInt32 dwCxtAge; + Buffer *pBuf = NULL; + VFLCxt *pVFLCxt; + BOOL32 boolWriteVFLCxtSuccess = FALSE32; + UInt16 wCurrCxtPOffset; + Int32 nFILRet; + + VFL_LOG_PRINT((TEXT("[VFL:INF] ++_WriteVFLCxtToFlash(wCS:%d)\n"), wCS)); + + /* check current state */ + if (wCS >= CS_TOTAL) + { + return FALSE32; + } + + pVFLCxt = GET_VFLCxt(wCS); + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + if (pBuf == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] error BUF_Get(line:%d)\n"), __LINE__)); + return FALSE32; + } + CHECK_VFL_CXT_CHECK_SUM(wCS); + dwCxtAge = --(pVFLCxt->dwCxtAge); + pVFLCxt->dwGlobalCxtAge = ++gdwMaxGlobalAge; + wCurrCxtPOffset = pVFLCxt->wNextCxtPOffset; + pVFLCxt->wNextCxtPOffset += VFL_NUM_OF_VFL_CXT_COPIES; + RECALC_VFL_CXT_CHECK_SUM(wCS); + WMR_MEMCPY(pBuf->pData, &pstVFLMeta[wCS], sizeof(VFLMeta)); + + /* writing the information */ + for (wPageIdx = 0; wPageIdx < VFL_NUM_OF_VFL_CXT_COPIES; wPageIdx++) + { + WMR_MEMSET(pBuf->pSpare, 0xFF, BYTES_PER_METADATA_RAW); + _SetVFLSpare(&dwCxtAge, pBuf->pSpare); + + /* we are not checking the result of the operation here - we will check the content below using read */ + nFILRet = pFuncTbl->Write(wCS, _Cbn2Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], + (wCurrCxtPOffset + wPageIdx)), pBuf->pData, pBuf->pSpare, FALSE32); + if ( nFILRet != FIL_SUCCESS) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] _WriteVFLCxtToFlash failed write (0x%X, 0x%X) (line:%d)\n"), + wCS, _Cbn2Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], (wCurrCxtPOffset + wPageIdx)), __LINE__)); + BUF_Release(pBuf); + _ReportWriteFailureSingle(wCS, _Cbn2Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], + (wCurrCxtPOffset + wPageIdx)), nFILRet); + return FALSE32; + } + } + + wNumOfErrors = 0; + + for (wPageIdx = 0; wPageIdx < VFL_NUM_OF_VFL_CXT_COPIES; wPageIdx++) + { + Int32 nFILRet; + nFILRet = pFuncTbl->ReadWithECC(wCS, _Cbn2Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], + (wCurrCxtPOffset + wPageIdx)), pBuf->pData, pBuf->pSpare, NULL, NULL, FALSE32); + if (nFILRet == FIL_SUCCESS) + { + UInt8 bStatusMark, bSpareType; + _GetVFLSpare(&dwCxtAge, &bStatusMark, &bSpareType, pBuf->pSpare); + if ((WMR_MEMCMP(pBuf->pData, pVFLCxt, sizeof(VFLCxt)) != 0) || (dwCxtAge != pVFLCxt->dwCxtAge) || (bStatusMark != PAGE_VALID) || (bSpareType != VFL_SPARE_TYPE_CXT)) + { + wNumOfErrors++; + } + } + else + { + _ReportECCFailureSingle(wCS, _Cbn2Ppn(pVFLCxt->awInfoBlk[pVFLCxt->wCxtLocation], + (wCurrCxtPOffset + wPageIdx))); + wNumOfErrors++; + } + } + + if (wNumOfErrors <= VFL_MAX_NUM_OF_VFL_CXT_ERRORS) + { + boolWriteVFLCxtSuccess = TRUE32; + } + else + { + VFL_ERR_PRINT((TEXT("[VFL:WRN] Fail writing VFLCxt(line:%d) CS %d block %d page %d\n"), __LINE__, wCS, pVFLCxt->wCxtLocation, wCurrCxtPOffset)); + } + + BUF_Release(pBuf); + VFL_LOG_PRINT((TEXT("[VFL: IN] --_WriteVFLCxtToFlash(wCS:%d)\n"), wCS)); + return boolWriteVFLCxtSuccess; +} + +/* + NAME + _StoreVFLCxt + DESCRIPTION + This function stores VFL context on VFL area. + PARAMETERS + wCS CS number + RETURN VALUES + TRUE32 + _StoreVFLCxt is completed + FALSE32 + _StoreVFLCxt is failed + NOTES + */ +static BOOL32 +_StoreVFLCxt(UInt16 wCS) +{ + VFLCxt *pVFLCxt; + BOOL32 boolWriteVFLCxtSuccess = FALSE32; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_StoreVFLCxt(wCS:%d)\n"), wCS)); + + /* check current state */ + WMR_ASSERT(wCS < CS_TOTAL); + + pVFLCxt = GET_VFLCxt(wCS); + + /* check if we still have space in the current block */ + if ((pVFLCxt->wNextCxtPOffset + VFL_NUM_OF_VFL_CXT_COPIES) <= PAGES_PER_BLOCK) + { + // we have space in the current block + boolWriteVFLCxtSuccess = _WriteVFLCxtToFlash(wCS); + } + + if (boolWriteVFLCxtSuccess == FALSE32) + { + // we do NOT have space in the current block or write operation in the current block failed + UInt16 wVFLCxtBlkIdx, wOriginalCxtLocation; + /* search for a valid erase unit we can write to */ + wOriginalCxtLocation = pVFLCxt->wCxtLocation; + wVFLCxtBlkIdx = (pVFLCxt->wCxtLocation + 1) % VFL_INFO_SECTION_SIZE; + while (wVFLCxtBlkIdx != wOriginalCxtLocation) + { + UInt16 wEraseCnt; + + /* check if this index point to a valid block */ + if (pVFLCxt->awInfoBlk[wVFLCxtBlkIdx] == VFL_INVALID_INFO_INDEX) + { + wVFLCxtBlkIdx = (wVFLCxtBlkIdx + 1) % VFL_INFO_SECTION_SIZE; + continue; + } + + /* block is valid try to erase it - up to x times */ + for (wEraseCnt = 0; wEraseCnt < WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS; wEraseCnt++) + { + Int32 nFILRet; + +#if (defined(WMR_ENABLE_ERASE_PROG_BAD_BLOCK)) + WMR_ENABLE_ERASE_PROG_BAD_BLOCK(wCS, _Cbn2Pbn(pVFLCxt->awInfoBlk[wVFLCxtBlkIdx])); +#endif // WMR_ENABLE_ERASE_PROG_BAD_BLOCK + + nFILRet = pFuncTbl->Erase(wCS, _Cbn2Pbn(pVFLCxt->awInfoBlk[wVFLCxtBlkIdx])); + +#if (defined(WMR_DISABLE_ERASE_PROG_BAD_BLOCK)) + WMR_DISABLE_ERASE_PROG_BAD_BLOCK(wCS, _Cbn2Pbn(pVFLCxt->awInfoBlk[wVFLCxtBlkIdx])); +#endif // WMR_DISABLE_ERASE_PROG_BAD_BLOCK + + if (nFILRet == FIL_SUCCESS) + { + break; + } + else + { + _ReportEraseFailureSingle(wCS, pVFLCxt->awInfoBlk[wVFLCxtBlkIdx], nFILRet); + } + } + + if (wEraseCnt == WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS) + { + // pVFLCxt->awInfoBlk[wVFLCxtBlkIdx] = VFL_INVALID_INFO_INDEX; + VFL_ERR_PRINT((TEXT("[VFL:ERR] Fail erasing VFLBlock CS %d block 0x%X (line:%d)\n"), wCS, pVFLCxt->awInfoBlk[wVFLCxtBlkIdx], __LINE__)); + wVFLCxtBlkIdx = (wVFLCxtBlkIdx + 1) % VFL_INFO_SECTION_SIZE; + continue; + } + + CHECK_VFL_CXT_CHECK_SUM(wCS); + pVFLCxt->wCxtLocation = wVFLCxtBlkIdx; + pVFLCxt->wNextCxtPOffset = 0; + RECALC_VFL_CXT_CHECK_SUM(wCS); + + boolWriteVFLCxtSuccess = _WriteVFLCxtToFlash(wCS); + if (boolWriteVFLCxtSuccess == FALSE32) + { + wVFLCxtBlkIdx = (wVFLCxtBlkIdx + 1) % VFL_INFO_SECTION_SIZE; + continue; + } + else + { + break; + } + } + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_StoreVFLCxt(wCS:%d)\n"), wCS)); + if (boolWriteVFLCxtSuccess == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _StoreVFLCxt(line:%d) fail CS %d!\n"), __LINE__, wCS)); + } + + return boolWriteVFLCxtSuccess; +} +#endif // ! AND_READONLY + +static BOOL32 _ReadVFLCxtFromFlash(UInt16 wCS, UInt16 wBlk, UInt16 wStartPOffset, Buffer * pBuf) +{ + Int32 nFILRet; + UInt16 wPageIdx; + + for (wPageIdx = 0; wPageIdx < VFL_NUM_OF_VFL_CXT_COPIES; wPageIdx++) + { + nFILRet = pFuncTbl->ReadWithECC(wCS, _Cbn2Ppn(wBlk, (wStartPOffset + wPageIdx)), pBuf->pData, pBuf->pSpare, NULL, NULL, FALSE32); + if (nFILRet == FIL_SUCCESS) + { + // NirW - we can check here the number of valid VFLCxt copies and refresh if needed + UInt8 bStatus, bSpareType; + /* verify the status byte */ + _GetVFLSpare(NULL, &bStatus, &bSpareType, pBuf->pSpare); + if (bStatus == PAGE_VALID && bSpareType == VFL_SPARE_TYPE_CXT) + { + VFLMeta *tmpPtr= (VFLMeta *)(pBuf->pData); + if(tmpPtr->dwVersion > VFL_META_VERSION) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _ReadVFLCxtFromFlash VFLCXT version mismatch CS 0x%x : 0x%x 0x%x \n"), wCS,tmpPtr->dwVersion,VFL_META_VERSION)); + return FALSE32; + } + return TRUE32; + } + } + else + { + _ReportECCFailureSingle(wCS, _Cbn2Ppn(wBlk, (wStartPOffset + wPageIdx))); + } + } + return FALSE32; +} + +/* + NAME + _LoadVFLCxt + DESCRIPTION + This function loads VFL context from VFL area. + PARAMETERS + wCS CS number + RETURN VALUES + TRUE32 + _LoadVFLCxt is completed + FALSE32 + _LoadVFLCxt is failed + NOTES + */ +static BOOL32 +_LoadVFLCxt(UInt16 wCS, UInt8 * pabBBT) +{ + VFLCxt *pVFLCxt; + UInt16 wBlkIdx, wPOffsetIdx; + Buffer *pBuf = NULL; + UInt32 dwMinAge; + UInt16 wNewCxt, wNewPOffset; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++_LoadVFLCxt(wCS:%d)\n"), wCS)); + + /* check current state */ + if (wCS >= CS_TOTAL) + { + return FALSE32; + } + + pVFLCxt = GET_VFLCxt(wCS); + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pBuf == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(wCS:%d) failed BUF_Get(line:%d)\n"), wCS, __LINE__)); + return FALSE32; + } + + /* first thing - find the first block with VFLCxt information and extract the awInfoBlk from it */ + for (wBlkIdx = VFL_FIRST_BLK_TO_SEARCH_CXT; wBlkIdx < VFL_LAST_BLK_TO_SEARCH_CXT; wBlkIdx++) + { + if (_ReadVFLCxtFromFlash(wCS, wBlkIdx, 0, pBuf) == TRUE32) + { + VFLCxt *pVFLCxtTemp; + pVFLCxtTemp = (VFLCxt *)pBuf->pData; + WMR_MEMCPY(pVFLCxt->awInfoBlk, pVFLCxtTemp->awInfoBlk, (sizeof(UInt16) * VFL_INFO_SECTION_SIZE)); + break; + } + } + if (wBlkIdx == VFL_LAST_BLK_TO_SEARCH_CXT) + { + BUF_Release(pBuf); + /* we should never get here - getting here means we fail to find a valid VFLCxt in the VFL_AREA */ + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(line:%d) fail CS %d!\n"), __LINE__, wCS)); + return FALSE32; + } + + /* look for the youngest VFLCxt block */ + dwMinAge = 0xFFFFFFFF; + wNewCxt = VFL_INFO_SECTION_SIZE; + for (wBlkIdx = 0; wBlkIdx < VFL_INFO_SECTION_SIZE; wBlkIdx++) + { + UInt32 dwAge; + + if (pVFLCxt->awInfoBlk[wBlkIdx] != VFL_INVALID_INFO_INDEX) + { + if (_ReadVFLCxtFromFlash(wCS, pVFLCxt->awInfoBlk[wBlkIdx], 0, pBuf) == FALSE32) + { + continue; + } + } + else + { + continue; + } + _GetVFLSpare(&dwAge, NULL, NULL, pBuf->pSpare); + if (dwMinAge >= dwAge && dwAge != 0) + { + wNewCxt = wBlkIdx; + dwMinAge = dwAge; + } + else + { + continue; + } + } + if (wNewCxt == VFL_INFO_SECTION_SIZE) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(line:%d) CW %d!\n"), __LINE__, wCS)); + BUF_Release(pBuf); + return FALSE32; + } + + /* look for the youngest valid VFLCxt version in the youngest block (i.e. search the youngest block pages) */ + wNewPOffset = 0; + for (wPOffsetIdx = VFL_NUM_OF_VFL_CXT_COPIES; wPOffsetIdx < PAGES_PER_BLOCK; wPOffsetIdx += VFL_NUM_OF_VFL_CXT_COPIES) + { + if (_ReadVFLCxtFromFlash(wCS, pVFLCxt->awInfoBlk[wNewCxt], wPOffsetIdx, pBuf) == FALSE32) + { + break; + } + + wNewPOffset = wPOffsetIdx; + } + if (_ReadVFLCxtFromFlash(wCS, pVFLCxt->awInfoBlk[wNewCxt], wNewPOffset, pBuf) == FALSE32) + { + /* this shouldn't happen since are using valid pointers */ + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(line:%d) CS %d!\n"), __LINE__, wCS)); + BUF_Release(pBuf); + return FALSE32; + } + + WMR_MEMCPY(&pstVFLMeta[wCS], pBuf->pData, sizeof(VFLMeta)); + + if (pVFLCxt->dwGlobalCxtAge > gdwMaxGlobalAge) + { + gdwMaxGlobalAge = pVFLCxt->dwGlobalCxtAge; + } + + BUF_Release(pBuf); + if (CHECK_VFL_CXT_CHECK_SUM_NO_ASSERT(wCS) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] CHECK_VFL_CXT_CHECK_SUM_NO_ASSERT(%d) failed (line:%d)!\n"), wCS, __LINE__)); + return FALSE32; + } + VFL_LOG_PRINT((TEXT("[VFL:OUT] --_LoadVFLCxt(wCS:%d)\n"), wCS)); + + return TRUE32; +} + +static BOOL32 _SetUpVendorSpecificRelatedParams(VendorSpecificType vendorSpecificType) +{ + // set the relevant FIL parameters + stVSVFLWMRDeviceInfo.wNumOfBanksPerCS = _GetBanksPerCS(vendorSpecificType); + + stVSVFLWMRDeviceInfo.wPagesPerSuBlk = stVSVFLWMRDeviceInfo.wPagesPerBlock * stVSVFLWMRDeviceInfo.wNumOfBanksPerCS * stVSVFLWMRDeviceInfo.wNumOfCEs; + stVSVFLWMRDeviceInfo.wNumOfBank = stVSVFLWMRDeviceInfo.wNumOfBanksPerCS * stVSVFLWMRDeviceInfo.wNumOfCEs; + stVSVFLWMRDeviceInfo.wBlocksPerBank = (UInt16)(stVSVFLWMRDeviceInfo.wBlocksPerCS / stVSVFLWMRDeviceInfo.wNumOfBanksPerCS); + + _SetV2PFunctions(vendorSpecificType); + _SetBankToCSConvertFunctions(vendorSpecificType); + + pFuncTbl->SetDeviceInfo(AND_DEVINFO_BANKS_PER_CS, stVSVFLWMRDeviceInfo.wNumOfBanksPerCS); + pFuncTbl->SetDeviceInfo(AND_DEVINFO_VENDOR_SPECIFIC_TYPE, vendorSpecificType); + return TRUE32; +} + +static BOOL32 _InitDeviceInfo(void) +{ + pFuncTbl = stFPartFunctions.GetLowFuncTbl(); + stVSVFLWMRDeviceInfo.wBlocksPerCS = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_CS); + stVSVFLWMRDeviceInfo.wBytesPerPage = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + stVSVFLWMRDeviceInfo.wNumOfCEs = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + stVSVFLWMRDeviceInfo.wPagesPerBlock = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + stVSVFLWMRDeviceInfo.bRefreshThreshold = (UInt8)pFuncTbl->GetDeviceInfo(AND_DEVINFO_REFRESH_THRESHOLD); + + stVSVFLWMRDeviceInfo.wNumOfBanksPerCS = 1; + stVSVFLWMRDeviceInfo.wBlocksPerDie = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BLOCKS_PER_DIE); + stVSVFLWMRDeviceInfo.wDieStride = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_DIE_STRIDE); + stVSVFLWMRDeviceInfo.wBlockStride = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_BLOCK_STRIDE); + stVSVFLWMRDeviceInfo.wUserBlocksPerCS = (UInt16)pFuncTbl->GetDeviceInfo(AND_DEVINFO_USER_BLOCKS_PER_CS); + + stVSVFLWMRDeviceInfo.dwValidMetaPerLogicalPage = pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_META_VALID_BYTES); + stVSVFLWMRDeviceInfo.dwTotalMetaPerLogicalPage = pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + stVSVFLWMRDeviceInfo.dwLogicalPageSize = pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_LBAS_PER_PAGE); + + VFL_LOG_PRINT((TEXT("[VFL:LOG] _ConvertP2T = 0X%X\n"), _ConvertP2T)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] _ConvertT2P = 0X%X\n"), _ConvertT2P)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] wPagesPerBlock = 0X%X\n"), stVSVFLWMRDeviceInfo.wPagesPerBlock)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] bRefreshThreshold = 0X%X\n"), stVSVFLWMRDeviceInfo.bRefreshThreshold)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] wNumOfCEs = 0X%X\n"), stVSVFLWMRDeviceInfo.wNumOfCEs)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] wBlocksPerCS = 0X%X\n"), stVSVFLWMRDeviceInfo.wBlocksPerCS)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] wBytesPerPage = 0X%X\n"), stVSVFLWMRDeviceInfo.wBytesPerPage)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] dwValidMetaPerLogicalPage = 0X%X\n"), stVSVFLWMRDeviceInfo.dwValidMetaPerLogicalPage)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] dwTotalMetaPerLogicalPage = 0X%X\n"), stVSVFLWMRDeviceInfo.dwTotalMetaPerLogicalPage)); + VFL_LOG_PRINT((TEXT("[VFL:LOG] dwLogicalPageSize = 0X%X\n"), stVSVFLWMRDeviceInfo.dwLogicalPageSize)); + + return TRUE32; +} + + +static BOOL32 _initWriteMultipleTables(void) +{ + WMR_ASSERT(BANKS_TOTAL > 0); + +#ifndef AND_READONLY + // init pawPbnOriginal + if (pawPbnOriginal == NULL) + { + pawPbnOriginal = (UInt16 *)WMR_MALLOC(sizeof(*pawPbnOriginal) * BANKS_TOTAL); + if ( pawPbnOriginal == NULL ) + { + return FALSE32; + } + } + + // init pawPbn + if (pawPbn == NULL) + { + pawPbn = (UInt16 *)WMR_MALLOC(sizeof(*pawPbn) * BANKS_TOTAL); + if ( pawPbn == NULL ) + { + return FALSE32; + } + } + + // init pawPbnUnmapped + if (pawPbnUnmapped == NULL) + { + pawPbnUnmapped = (UInt16 *)WMR_MALLOC(sizeof(*pawPbnUnmapped) * BANKS_TOTAL); + if ( pawPbnUnmapped == NULL ) + { + return FALSE32; + } + } +#endif + + // init pawPbnRemapped + if (pawPbnRemapped == NULL) + { + pawPbnRemapped = (UInt16 *)WMR_MALLOC(sizeof(*pawPbnRemapped) * BANKS_TOTAL); + if ( pawPbnRemapped == NULL ) + { + return FALSE32; + } + } + + // init padwPpnRemapped + if (padwPpnRemapped == NULL) + { + padwPpnRemapped = (UInt32 *)WMR_MALLOC(sizeof(*padwPpnRemapped) * BANKS_TOTAL); + if ( padwPpnRemapped == NULL ) + { + return FALSE32; + } + } + + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Init */ +/* DESCRIPTION */ +/* This function initializes VFL layer. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Init is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Init is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Init(FPartFunctions * pFPartFunctions) +{ + UInt16 wCSIdx; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Init()\n"))); + + WMR_ASSERT(FTL_FORMAT_STRUCT_SIZE == sizeof(FTLFormatType)); + WMR_MEMCPY(&stFPartFunctions, pFPartFunctions, sizeof(FPartFunctions)); + _InitDeviceInfo(); + /* the size of FTLMeta must be 2048 bytes */ + WMR_ASSERT(sizeof(VFLMeta) == 2048); +#ifdef AND_COLLECT_STATISTICS + WMR_ASSERT(sizeof(VFLStatistics) < AND_STATISTICS_SIZE_PER_LAYER); + + WMR_MEMSET(&stVFLStatistics, 0, sizeof(VFLStatistics)); +#endif // AND_COLLECT_STATISTICS + /* init VFL meta */ + if (pstVFLMeta == NULL) + { + pstVFLMeta = (VFLMeta *)WMR_MALLOC(sizeof(VFLMeta) * CS_TOTAL); + if ( pstVFLMeta == NULL ) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] there is no memory to initialize pstVFLCxt!\n"))); + return VFL_CRITICAL_ERROR; + } + } + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + pstabCSBBTArea[wCSIdx] = (UInt8*)WMR_MALLOC(BBT_SIZE_PER_CS); + } + + /* get low level function table */ + pFuncTbl = stFPartFunctions.GetLowFuncTbl(); + + if (pFuncTbl == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] FIL_GetFuncTbl() fail!\n"))); + return VFL_CRITICAL_ERROR; + } + gdwMaxGlobalAge = 0; + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Init()\n"))); + + /* set the poitners to the checksum functions */ + vflChecksumFunc.UpdateChecksum = _UpdateVFLCxtChecksum; + vflChecksumFunc.VerifyChecksum = _CheckVFLCxtDataIsUntouched; + + return VFL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Open */ +/* DESCRIPTION */ +/* This function opens VFL layer. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Open is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Open is failed */ +/* NOTES */ +/* */ +/*****************************************************************************/ +Int32 +VFL_Open(UInt32 dwBootAreaSize, UInt32 minor_ver, UInt32 dwOptions) +{ + UInt16 wCSIdx, wIdx; + VFLCxt *pVFLCxt; + +#ifndef AND_READONLY + FTLFormatType * pFTLFormatType; +#endif + VendorSpecificType vendorSpecificType; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Open()\n"))); + + stVSVFLWMRDeviceInfo.dwVFLAreaStart = dwBootAreaSize; + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + BOOL32 bRet; + UInt8 * pabBBT = pstabCSBBTArea[wCSIdx]; + + bRet = VFL_ReadBBT(wCSIdx, pabBBT); + if (bRet == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_ReadBBT(wCS:%d)(line %d) fail!\n"), wCSIdx, __LINE__)); + return VFL_CRITICAL_ERROR; + } + bRet = _LoadVFLCxt(wCSIdx, pabBBT); + + if (bRet == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _LoadVFLCxt(wCSIdx:%d)(line %d) fail!\n"), wCSIdx, __LINE__)); + return VFL_CRITICAL_ERROR; + } + } + + pVFLCxt = _GetNewestVFLCxt(); + if (pVFLCxt->wNumOfFTLSuBlk > pVFLCxt->wNumOfVFLSuBlk) + { + VFL_ERR_PRINT((TEXT("FTLSuBlks(=%d) > VFLSuBlks(=%d)\n"), pVFLCxt->wNumOfFTLSuBlk, pVFLCxt->wNumOfVFLSuBlk)); + return VFL_CRITICAL_ERROR; + } + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + /* make sure all are up to date so later storing of VFL Cxt would be correct */ + WMR_MEMCPY(pstVFLMeta[wCSIdx].stVFLCxt.awFTLCxtVbn, pVFLCxt->awFTLCxtVbn, FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + pstVFLMeta[wCSIdx].stVFLCxt.wNumOfVFLSuBlk = pVFLCxt->wNumOfVFLSuBlk; + pstVFLMeta[wCSIdx].stVFLCxt.wNumOfFTLSuBlk = pVFLCxt->wNumOfFTLSuBlk; + pstVFLMeta[wCSIdx].stVFLCxt.dwFTLType = pVFLCxt->dwFTLType; + WMR_MEMCPY(pstVFLMeta[wCSIdx].stVFLCxt.abFTLFormat, pVFLCxt->abFTLFormat, FTL_FORMAT_STRUCT_SIZE); + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + } + + // since we use s vs value from the VFLCxt we need to move the allocation from Init here + WMR_MEMCPY(&vendorSpecificType, pstVFLMeta[0].stVFLCxt.abVSFormtType, 4); +#if (defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) + if (vendorSpecificType != FIL_VS_SIMPLE) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Open context vs-type is not simple (line %d)\n"), __LINE__)); + return VFL_CRITICAL_ERROR; + } +#endif + if (vendorSpecificType == FIL_VS_UNKNOWN) + { + vendorSpecificType = (VendorSpecificType)pFuncTbl->GetDeviceInfo(AND_DEVINFO_VENDOR_SPECIFIC_TYPE); + } + + _SetUpVendorSpecificRelatedParams(vendorSpecificType); + + /* Allocate buffers for scattered read/write operation */ + if (pstadwScatteredReadWritePpn == NULL && pstawScatteredReadWriteCS == NULL) + { +#if (defined(AND_READONLY) && AND_READONLY) && defined(WMR_MAX_READONLY_PAGES) + pstadwScatteredReadWritePpn = (UInt32 *)WMR_MALLOC(WMR_MAX_READONLY_PAGES * sizeof(UInt32)); + pstawScatteredReadWriteCS = (UInt16 *)WMR_MALLOC(WMR_MAX_READONLY_PAGES * sizeof(UInt16)); +#else + pstadwScatteredReadWritePpn = (UInt32 *)WMR_MALLOC(PAGES_PER_SUBLK * sizeof(UInt32)); + pstawScatteredReadWriteCS = (UInt16 *)WMR_MALLOC(PAGES_PER_SUBLK * sizeof(UInt16)); +#endif + + if (pstadwScatteredReadWritePpn == NULL || pstawScatteredReadWriteCS == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] there is no memory to initialize pstadwScatteredReadPpn or pstawScatteredReadCS!\n"))); + return VFL_CRITICAL_ERROR; + } + } + + if (!_initWriteMultipleTables()) + { + return VFL_CRITICAL_ERROR; + } + + // Per CS, build the bitmap BBT + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + UInt8 *pabBBT = pstabCSBBTArea[wCSIdx]; + VFLCxt *pVFLCxt = &pstVFLMeta[wCSIdx].stVFLCxt; + UInt16 wBankIdx; + WMR_MEMSET(pabBBT, 0xFF, BBT_SIZE_PER_CS); + for (wBankIdx = 0; wBankIdx < BANKS_PER_CS; wBankIdx++) + { + for (wIdx = 0; wIdx < VFL_RESERVED_SECTION_SIZE_BANK; wIdx++) + { + UInt16 wCurrIdxToCheck = wIdx + (VFL_RESERVED_SECTION_SIZE_BANK * wBankIdx); + if (pVFLCxt->awBadMapTable[wCurrIdxToCheck] > VFL_BAD_MAP_TABLE_AVAILABLE_MARK) + { + UInt16 wPbn, wTbn = wIdx + _GetNumOfSuBlks(); + _ConvertT2P(_CSBank2Bank(wCSIdx, wBankIdx), wTbn, &wPbn); + _MarkBlockAsBadInBBT(pabBBT, wPbn); + } + else if (pVFLCxt->awBadMapTable[wCurrIdxToCheck] < BLOCKS_PER_CS) + { + _MarkBlockAsBadInBBT(pabBBT, pVFLCxt->awBadMapTable[wCurrIdxToCheck]); + } + else if (pVFLCxt->awBadMapTable[wCurrIdxToCheck] != VFL_BAD_MAP_TABLE_AVAILABLE_MARK) + { + WMR_PANIC("[VFL:ERR] CS %d Bad Map Table entry %d contains invalid value 0x%08x\n", + (UInt32) wCSIdx, (UInt32) wCurrIdxToCheck, (UInt32) pVFLCxt->awBadMapTable[wCurrIdxToCheck]); + } + } + } + } +#ifndef AND_READONLY + pFTLFormatType = (FTLFormatType *)pstVFLMeta[0].stVFLCxt.abFTLFormat; + if (pFTLFormatType->bFormatFTL) + { + _SetNewFTLParams(); + } + vflBlockRefreshTrigger=(UInt8 *)WMR_MALLOC(pVFLCxt->wNumOfVFLSuBlk); + if(vflBlockRefreshTrigger == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] cannot alocate refreshtrigger array. continue to operate in legacy mode \n"))); + } + else + WMR_MEMSET(vflBlockRefreshTrigger,0,pVFLCxt->wNumOfVFLSuBlk); +#endif + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Open()\n"))); + + return VFL_SUCCESS; +} + +BOOL32 _BlankCheckSpare(UInt32 * padwBuff, UInt16 wSize) +{ + UInt16 i, j, zeroes; + UInt32 dwVal; + + zeroes = 0; + for (i = 0; i < wSize; i += sizeof(UInt32), padwBuff++) + { + dwVal = *padwBuff; + if (dwVal != 0xFFFFFFFF) + { + for (j = 0; j < 32; j++) + { + if (!(dwVal & 1) && (++zeroes > 2)) + { + return FALSE32; + } + dwVal >>= 1; + } + } + } + return TRUE32; +} +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Read */ +/* DESCRIPTION */ +/* This function reads virtual page. */ +/* PARAMETERS */ +/* nVpn [IN] virtual page number */ +/* pBuf [IN] Buffer pointer */ +/* bCleanCheck [IN] clean check or not */ +/* bMarkECCForScrub [IN] in case of ECC error - add to scrub */ +/* list or not */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Read is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Read is failed. */ +/* VFL_U_ECC_ERROR */ +/* ECC uncorrectable error occurs from FIL read function. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Read(UInt32 dwVpn, Buffer *pBuf, BOOL32 boolCleanCheck, BOOL32 bMarkECCForScrub, BOOL32 * pboolNeedRefresh, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening) +{ + UInt16 wCS; + UInt32 dwPpn; + Int32 nFILRet; + UInt8 bECCCorrectedBits; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Read(dwVpn:%d,boolCleanCheck:%d)\n"), dwVpn, boolCleanCheck)); + + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = FALSE32; + } + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesReadCnt++; + stVFLStatistics.ddwSingleReadCallCnt++; +#endif + + /* calculate physical address */ + _Vpn2Ppn(dwVpn, &wCS, &dwPpn); + + nFILRet = pFuncTbl->ReadWithECC(wCS, dwPpn, pBuf->pData, + pBuf->pSpare, &bECCCorrectedBits, pdwaSectorStats, bDisableWhitening); + + // in case we are no ready to process clean pages mark the page as ecc error if it is clean + if (boolCleanCheck == FALSE32 && nFILRet == FIL_SUCCESS_CLEAN) + { + nFILRet = FIL_U_ECC_ERROR; + _ReportECCFailureSingle(wCS, dwPpn); + } + + // check if the page need to be refreshed + if (pboolNeedRefresh != NULL) + { + if ((bECCCorrectedBits >= FIL_ECC_REFRESH_TRESHOLD && nFILRet == FIL_SUCCESS) || + (nFILRet == FIL_U_ECC_ERROR)) + { +#ifndef AND_READONLY + if(bMarkECCForScrub == TRUE32 && bECCCorrectedBits >= FIL_ECC_REFRESH_TRESHOLD && nFILRet == FIL_SUCCESS && vflBlockRefreshTrigger != NULL) + vflBlockRefreshTrigger[dwVpn/PAGES_PER_SUBLK]++; +#endif + // Mark the block for refresh + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = TRUE32; + } + } + } + + if (nFILRet == FIL_CRITICAL_ERROR || nFILRet == FIL_U_ECC_ERROR) + { + // reset the bank in the hopes of making it behave + pFuncTbl->Reset(); + nFILRet = pFuncTbl->ReadWithECC(wCS, dwPpn, pBuf->pData, + pBuf->pSpare, NULL, NULL, bDisableWhitening); + // in case we are no ready to process clean pages mark the page as ecc error if it is clean + if (boolCleanCheck == FALSE32 && nFILRet == FIL_SUCCESS_CLEAN) + { + nFILRet = FIL_U_ECC_ERROR; + + _ReportECCFailureSingle(wCS, dwPpn); + } + } +#ifndef AND_READONLY + if (((nFILRet == FIL_U_ECC_ERROR) && (bMarkECCForScrub == TRUE32)) || (bMarkECCForScrub == TRUE32 && vflBlockRefreshTrigger != NULL && vflBlockRefreshTrigger[dwVpn/PAGES_PER_SUBLK] >= RETIRE_ON_REFRESH_TRESHOLD)) + { + UInt16 tCS; + UInt16 tcbN; + _Vpn2Cbn(dwVpn, &tCS, &tcbN); + _AddBlockToScrubList(tCS, tcbN); + if(vflBlockRefreshTrigger != NULL) + vflBlockRefreshTrigger[dwVpn/PAGES_PER_SUBLK] = 0; + } +#endif + + if (nFILRet == FIL_SUCCESS_CLEAN) + { + WMR_MEMSET(pBuf->pSpare, 0xFF, BYTES_PER_METADATA_RAW); + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Read(dwVpn:%d,boolCleanCheck:%d)\n"), dwVpn, boolCleanCheck)); + return nFILRet; +} +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Write */ +/* DESCRIPTION */ +/* This function writes virtual page. */ +/* PARAMETERS */ +/* nVpn [IN] virtual page number */ +/* pBuf [IN] Buffer pointer */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Write is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Write is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Write(UInt32 dwVpn, Buffer *pBuf, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening) +{ + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Write(dwVpn:%d)\n"), dwVpn)); + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwSingleWriteCallCnt++; +#endif + + /* write page data */ + if (VFL_WriteMultiplePagesInVb(dwVpn, ((UInt16)1), pBuf->pData, pBuf->pSpare, boolReplaceBlockOnFail, bDisableWhitening) != TRUE32) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Write(dwVpn:%d) failed!\n"), dwVpn)); + return VFL_CRITICAL_ERROR; + } + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Write(dwVpn:%d)\n"), dwVpn)); + + return VFL_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Erase */ +/* DESCRIPTION */ +/* This function erases virtual block(super block). */ +/* PARAMETERS */ +/* wVbn [IN] virtual block number */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Erase is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Erase is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Erase(UInt16 wVbn, BOOL32 bReplaceOnFail) +{ + UInt16 wPbn; + Int32 nRetVal = VFL_CRITICAL_ERROR; + UInt16 wBankIdx; + BOOL32 boolAligned = TRUE32, boolCorrectBank = TRUE32; + UInt16 wFailingCE = CE_STATUS_UNINITIALIZED; + UInt32 dwFailingBlock = BLOCK_STATUS_UNINITIALIZED; + UInt32 numReplacements; + BOOL32 foundBlock; + BOOL32 bReplaceBadBlockResult; + Int32 nFILRet = FIL_CRITICAL_ERROR; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VSVFL_Erase(wVbn:%d)\n"), wVbn)); + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwBlocksErasedCnt++; + stVFLStatistics.ddwEraseCallCnt++; +#endif + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + UInt16 wCS; + + _ConvertT2P(wBankIdx, _Vbn2Tbn(wVbn), &wPbn); + wCS = _Bank2CS(wBankIdx); + + pawPbnRemapped[wBankIdx] = wPbn; + + if (_IsBlockInScrubList(wCS, pawPbnRemapped[wBankIdx]) == TRUE32) + { + _ReplaceBadBlock(wCS, wPbn); + RECALC_VFL_CXT_CHECK_SUM(wCS); + _RemoveBlockFromScrubList(wCS, pawPbnRemapped[wBankIdx]); + pawPbnRemapped[wBankIdx] = _RemapBlock(wCS, wPbn, &boolAligned, &boolCorrectBank); + } + pawPbnRemapped[wBankIdx] = _RemapBlock(wCS, wPbn, NULL, NULL); + pawPbnRemapped[wBankIdx] = _Cbn2Pbn(pawPbnRemapped[wBankIdx]); + } + if (pFuncTbl->EraseMultiple != NULL) + { + numReplacements = 0; + do + { + dwFailingBlock = BLOCK_STATUS_UNINITIALIZED; + wFailingCE = CE_STATUS_UNINITIALIZED; + nFILRet = pFuncTbl->EraseMultiple(pawPbnRemapped, boolAligned, boolCorrectBank, &wFailingCE, &dwFailingBlock); + if ( nFILRet == FIL_SUCCESS) { + return VFL_SUCCESS; + } + + _ReportEraseFailureMultiple(wFailingCE, wVbn, nFILRet); + + if (!bReplaceOnFail) + { + return VFL_CRITICAL_ERROR; + } + + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Erase failed erasing in parallel Vbn 0x%X Pbn 0x%X on CE %d! (line:%d)\n"), wVbn, dwFailingBlock, wFailingCE, __LINE__)); + + if (CE_STATUS_UNINITIALIZED == wFailingCE) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Erase failing CE not provided; Vbn 0x%X on all banks will be replaced!\n"), wVbn)); + } + else if (BLOCK_STATUS_UNINITIALIZED == dwFailingBlock) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Erase failing block not provided; Vbn 0x%X on all banks of CE %d will be replaced!\n"), wVbn, wFailingCE)); + } + + // now we have to mark failing block bad and to replace + foundBlock = FALSE32; + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + if ((CE_STATUS_UNINITIALIZED == wFailingCE) || + ((_Bank2CS(wBankIdx) == wFailingCE) && + ((BLOCK_STATUS_UNINITIALIZED == dwFailingBlock) || + (pawPbnRemapped[wBankIdx] == dwFailingBlock)))) + { + _ConvertT2P(wBankIdx, _Vbn2Tbn(wVbn), &wPbn); + + CHECK_VFL_CXT_CHECK_SUM(_Bank2CS(wBankIdx)); + pstVFLMeta[_Bank2CS(wBankIdx)].stVFLCxt.wNumOfEraseFail++; + bReplaceBadBlockResult = _ReplaceBadBlock(_Bank2CS(wBankIdx), wPbn); + RECALC_VFL_CXT_CHECK_SUM(_Bank2CS(wBankIdx)); + if ( bReplaceBadBlockResult != TRUE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed _ReplaceBadBlk\n"))); + return VFL_CRITICAL_ERROR; + } + if (_StoreVFLCxt(_Bank2CS(wBankIdx)) != TRUE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed _StoreVFLCxt\n"))); + return VFL_CRITICAL_ERROR; + } + if (nRetVal != VFL_CRITICAL_ERROR) + { +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwEraseTimeoutFailCnt++; +#endif + } + + foundBlock = TRUE32; + numReplacements++; + pawPbnRemapped[wBankIdx] = _Cbn2Pbn(_RemapBlock(_Bank2CS(wBankIdx), wPbn, NULL, NULL)); + } + } + if ( !foundBlock ) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed, but no blocks were replaced!\n"))); + return VFL_CRITICAL_ERROR; + } + } + while (numReplacements <= (UInt32)(2 * BANKS_TOTAL)); + + if (numReplacements > (UInt32)(2 * BANKS_TOTAL)) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Erase failed after attemting block replacements %d times\n"), numReplacements)); + return VFL_CRITICAL_ERROR; + } + } + + // if EraseMultiple not found then sequentially erase blocks + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + UInt8 bTrialIdx; + UInt16 wCS, wPbnRemapped; + + _ConvertT2P(wBankIdx, _Vbn2Tbn(wVbn), &wPbn); + wCS = _Bank2CS(wBankIdx); + + /* erase blocks */ + for (bTrialIdx = 0; bTrialIdx < WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS; bTrialIdx++) + { + /* calculate replaced physical block address */ + wPbnRemapped = _RemapBlock(wCS, wPbn, NULL, NULL); + nRetVal = pFuncTbl->Erase(wCS, _Cbn2Pbn(wPbnRemapped)); + + if (nRetVal == FIL_SUCCESS) + { + break; + } + else + { + _ReportEraseFailureSingle(wCS, wPbn, nRetVal); + + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_Erase failed erasing pbn 0x%X bank %d status = 0x%X (line:%d)!\n"), wPbnRemapped, wBankIdx, nRetVal, __LINE__)); + if (!bReplaceOnFail) + { + return VFL_CRITICAL_ERROR; + } + CHECK_VFL_CXT_CHECK_SUM(wCS); + pstVFLMeta[wCS].stVFLCxt.wNumOfEraseFail++; + bReplaceBadBlockResult = _ReplaceBadBlock(wCS, wPbn); + RECALC_VFL_CXT_CHECK_SUM(wCS); + if ( bReplaceBadBlockResult != TRUE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed _ReplaceBadBlk\n"))); + return VFL_CRITICAL_ERROR; + } + if (_StoreVFLCxt(_Bank2CS(wBankIdx)) != TRUE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed _StoreVFLCxt\n"))); + return VFL_CRITICAL_ERROR; + } + if (nRetVal != FIL_WRITE_FAIL_ERROR) + { +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwEraseTimeoutFailCnt++; +#endif + } + } + } + if (bTrialIdx == WMR_NUM_OF_ERASE_TRIALS_FOR_DATA_BLOCKS) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Erase failed erasing / replacing vbn 0x%X bank %d!\n"), wVbn, wBankIdx)); + break; + } + } + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VSVFL_Erase(wVbn:%d)\n"), wVbn)); + + WMR_ASSERT(nRetVal == FIL_SUCCESS); + return nRetVal; +} + +static UInt16 +_CalcNumOfVFLSuBlk(void) +{ + // Any blocks above the binary size will be used as spares + UInt32 wRoundedBlocksPerBank = 1UL << WMR_LOG2(BLOCKS_PER_BANK); + + return VSVFL_USER_BLKS_PER_1K * (wRoundedBlocksPerBank / 1024); +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Format */ +/* DESCRIPTION */ +/* This function formats VFL. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Format is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Format is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_Format(UInt32 dwBootAreaSize, UInt32 dwOptions) +{ + BOOL32 bReplaceBadBlockResult; + UInt16 wCSIdx; + VFLCxt *pVFLCxt; + UInt16 wNumOfVFLSuBlk; + VendorSpecificType vendorSpecificType = (VendorSpecificType)pFuncTbl->GetDeviceInfo(AND_DEVINFO_VENDOR_SPECIFIC_TYPE); + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Format()\n"))); + + WMR_MEMSET(pstVFLMeta, 0, sizeof(VFLMeta) * CS_TOTAL); + + stVSVFLWMRDeviceInfo.dwVFLAreaStart = dwBootAreaSize; + +#if (defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) + if (vendorSpecificType != FIL_VS_SIMPLE) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_Format context vs-type is not simple (line %d)\n"), __LINE__)); + return VFL_CRITICAL_ERROR; + } +#endif + + _SetUpVendorSpecificRelatedParams(vendorSpecificType); + // moved out of the init since we need VFL to open or format to know + // what the size of the super block is + if (pstadwScatteredReadWritePpn == NULL && pstawScatteredReadWriteCS == NULL) + { + pstadwScatteredReadWritePpn = (UInt32 *)WMR_MALLOC(PAGES_PER_SUBLK * sizeof(UInt32)); + pstawScatteredReadWriteCS = (UInt16 *)WMR_MALLOC(PAGES_PER_SUBLK * sizeof(UInt16)); + + if (pstadwScatteredReadWritePpn == NULL || pstawScatteredReadWriteCS == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] there is no memory to initialize pstadwScatteredReadPpn or pstawScatteredReadCS!\n"))); + return VFL_CRITICAL_ERROR; + } + } + + if (!_initWriteMultipleTables()) + { + return VFL_CRITICAL_ERROR; + } + + wNumOfVFLSuBlk = _CalcNumOfVFLSuBlk(); + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + UInt8 *pabBBT = pstabCSBBTArea[wCSIdx]; + Buffer *pBuf = NULL; + UInt16 wIdx, wPbn, wBankIdx; + + if (VFL_ReadBBT(wCSIdx, pabBBT) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_ReadBBT(%d) fail!\n"), wCSIdx)); + return VFL_CRITICAL_ERROR; + } + pstVFLMeta[wCSIdx].dwVersion = VFL_META_VERSION; + pVFLCxt = GET_VFLCxt(wCSIdx); + + // set the number super blocks + pVFLCxt->wNumOfVFLSuBlk = wNumOfVFLSuBlk; + pVFLCxt->wNumOfFTLSuBlk = wNumOfVFLSuBlk; + WMR_MEMCPY(pVFLCxt->abVSFormtType, &vendorSpecificType, 4); + + pVFLCxt->dwGlobalCxtAge = wCSIdx; + for (wIdx = 0; wIdx < FTL_CXT_SECTION_SIZE; wIdx++) + { + pVFLCxt->awFTLCxtVbn[wIdx] = (UInt16)(wIdx); + } + + pBuf = BUF_Get(BUF_MAIN_AND_SPARE); + + if (pBuf == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] BUF_Get fail (line:%d)!\n"), __LINE__)); + return VFL_CRITICAL_ERROR; + } + + pVFLCxt->wNumOfInitBadBlk = 0; + + //count initial bad block number and save in VFLCxt + for (wIdx = 0; wIdx < BLOCKS_PER_CS; wIdx++) + { + if (_isBlockGood(pabBBT, wIdx) != TRUE32) + { + pVFLCxt->wNumOfInitBadBlk++; + } + } + + /* initial bad check of VFL_INFO_SECTION */ + for (wIdx = 0, wPbn = VFL_FIRST_BLK_TO_SEARCH_CXT; wIdx < VFL_INFO_SECTION_SIZE && wPbn < VFL_LAST_BLK_TO_SEARCH_CXT; wPbn++) + { + if (_isBlockGood(pabBBT, wPbn)) + { + /* check that the block is erasable */ + UInt16 wEraseCnt; + for (wEraseCnt = 0; wEraseCnt < WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS; wEraseCnt++) + { + Int32 nFILRet; + nFILRet = pFuncTbl->Erase(wCSIdx, _Cbn2Pbn(wPbn)); + if (nFILRet == FIL_SUCCESS) + { + break; + } + _ReportEraseFailureSingle(wCSIdx, wPbn, nFILRet); + } + if (wEraseCnt == WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS) + { + VFL_WRN_PRINT((TEXT("[VFL:ERR] VFL info section: exceeded erase limit at wCSIdx %x wPbn %x (line:%d)!\n"), wCSIdx, wPbn, __LINE__)); + } + else + { + pVFLCxt->awInfoBlk[wIdx++] = wPbn; + } + } + else + { + //VFL_WRN_PRINT((TEXT("[VFL:ERR] VFL info section: bad block at wCSIdx %x wPbn %x (line:%d)!\n"), wCSIdx, wPbn, __LINE__)); + } + } + if (wPbn == VFL_LAST_BLK_TO_SEARCH_CXT) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] wPbn == VFL_LAST_BLK_TO_SEARCH_CXT (line:%d)!\n"), __LINE__)); + return VFL_CRITICAL_ERROR; + } + + /* initial bad check of reserved area */ + for (wBankIdx = 0; wBankIdx < BANKS_PER_CS; wBankIdx++) + { + for (wIdx = 0; wIdx < VFL_RESERVED_SECTION_SIZE_BANK; wIdx++) + { + UInt16 wPbn; + UInt16 wTbn = wIdx + _GetNumOfSuBlks(); + + _ConvertT2P(_CSBank2Bank(wCSIdx, wBankIdx), wTbn, &wPbn); + if (_isBlockGood(pabBBT, wPbn)) + { + pVFLCxt->awBadMapTable[(VFL_RESERVED_SECTION_SIZE_BANK * wBankIdx) + wIdx] = VFL_BAD_MAP_TABLE_AVAILABLE_MARK; + } + else + { + pVFLCxt->awBadMapTable[(VFL_RESERVED_SECTION_SIZE_BANK * wBankIdx) + wIdx] = VFL_BAD_MAP_TABLE_BAD_MARK; + } + } + } + // replace blocks we assigned to VFL_INFO_SECTION_SIZE + for (wIdx = 0; wIdx <= pVFLCxt->awInfoBlk[VFL_INFO_SECTION_SIZE - 1]; wIdx++) + { + bReplaceBadBlockResult = _ReplaceBadBlock(wCSIdx, wIdx); + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + + if ( bReplaceBadBlockResult == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _ReplaceBadBlock failed (line:%d)!\n"), __LINE__)); + return VFL_CRITICAL_ERROR; + } + } + for (wBankIdx = 0; wBankIdx < BANKS_PER_CS; wBankIdx++) + { + for (wIdx = 0; wIdx < _GetNumOfSuBlks(); wIdx++) + { + UInt16 wPbn; + _ConvertT2P(_CSBank2Bank(wCSIdx, wBankIdx), wIdx, &wPbn); + if ((wPbn > pVFLCxt->awInfoBlk[VFL_INFO_SECTION_SIZE - 1]) && _isBlockGood(pabBBT, wPbn) == FALSE32) + { + bReplaceBadBlockResult = _ReplaceBadBlock(wCSIdx, wPbn); + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + if ( bReplaceBadBlockResult == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _ReplaceBadBlock failed (line:%d)!\n"), __LINE__)); + return VFL_CRITICAL_ERROR; + } + } + } + } + + BUF_Release(pBuf); + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + if (_StoreVFLCxt(wCSIdx) == FALSE32) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _StoreVFLCxt fail!\n"))); + return VFL_CRITICAL_ERROR; + } + } + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Format()\n"))); + return VFL_SUCCESS; +} +#endif // ! AND_READONLY + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_Close */ +/* DESCRIPTION */ +/* This function releases VFL layer. */ +/* PARAMETERS */ +/* none */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +void +VFL_Close(void) +{ + UInt16 wCSIdx; + + VFL_LOG_PRINT((TEXT("[VFL: IN] ++VFL_Close()\n"))); + + /* release buffer manager */ + BUF_Close(); + +#ifndef AND_READONLY + if (NULL != vflBlockRefreshTrigger) + { + WMR_FREE(vflBlockRefreshTrigger, _GetNewestVFLCxt()->wNumOfVFLSuBlk); + vflBlockRefreshTrigger = NULL; + } +#endif + + /* release VFL meta */ + if (pstVFLMeta != NULL) + { + WMR_FREE(pstVFLMeta, sizeof(VFLMeta) * CS_TOTAL); + pstVFLMeta = NULL; + } + +#ifndef AND_READONLY + /* release pawPbnOriginal */ + if (pawPbnOriginal != NULL) + { + WMR_FREE(pawPbnOriginal, sizeof(*pawPbnOriginal) * BANKS_TOTAL); + pawPbnOriginal = NULL; + } + + /* release pawPbn */ + if (pawPbn != NULL) + { + WMR_FREE(pawPbn, sizeof(*pawPbn) * BANKS_TOTAL); + pawPbn = NULL; + } + + /* release pawPbnUnmapped */ + if (pawPbnUnmapped != NULL) + { + WMR_FREE(pawPbnUnmapped, sizeof(*pawPbnUnmapped) * BANKS_TOTAL); + pawPbnUnmapped = NULL; + } +#endif + + /* release pawPbnRemapped */ + if (pawPbnRemapped != NULL) + { + WMR_FREE(pawPbnRemapped, sizeof(*pawPbnRemapped) * BANKS_TOTAL); + pawPbnRemapped = NULL; + } + + /* release padwPpnRemapped */ + if (padwPpnRemapped != NULL) + { + WMR_FREE(padwPpnRemapped, sizeof(*padwPpnRemapped) * BANKS_TOTAL); + padwPpnRemapped = NULL; + } + + if (pstadwScatteredReadWritePpn != NULL) + { + WMR_FREE(pstadwScatteredReadWritePpn, (PAGES_PER_SUBLK * sizeof(UInt32))); + pstadwScatteredReadWritePpn = NULL; + } + + if (pstawScatteredReadWriteCS != NULL) + { + WMR_FREE(pstawScatteredReadWriteCS, (PAGES_PER_SUBLK * sizeof(UInt16))); + pstawScatteredReadWriteCS = NULL; + } + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + WMR_FREE(pstabCSBBTArea[wCSIdx], BBT_SIZE_PER_CS); + pstabCSBBTArea[wCSIdx] = NULL; + } + +#ifdef AND_COLLECT_STATISTICS + WMR_MEMSET(&stVFLStatistics, 0, sizeof(VFLStatistics)); +#endif + pFuncTbl = NULL; + + VFL_LOG_PRINT((TEXT("[VFL:OUT] --VFL_Close()\n"))); + + return; +} + +static VFLCxt * _GetNewestVFLCxt(void) +{ + UInt32 wCSIdx; + VFLCxt *pNewestVFLCxt = NULL; + VFLCxt *pVFLCxt = NULL; + UInt32 aMaxGlobalAge = 0; + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + pVFLCxt = GET_VFLCxt(wCSIdx); + + if (pVFLCxt->dwGlobalCxtAge >= aMaxGlobalAge) + { + aMaxGlobalAge = pVFLCxt->dwGlobalCxtAge; + pNewestVFLCxt = pVFLCxt; + } + } + return pNewestVFLCxt; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_GetFTLCxtVbn */ +/* DESCRIPTION */ +/* This function is returning the recent FTL context block position */ +/* PARAMETERS */ +/* aFTLCxtVbn [OUT] Recent FTL context block list */ +/* RETURN VALUES */ +/* none */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static UInt16* +VFL_GetFTLCxtVbn(void) +{ + return _GetNewestVFLCxt()->awFTLCxtVbn; +} + +#ifndef AND_READONLY +/*****************************************************************************/ +/* */ +/* NAME */ +/* VFL_ChangeFTLCxtVbn */ +/* DESCRIPTION */ +/* This function change the virtual block number of FTL context block */ +/* PARAMETERS */ +/* awFTLCxtVbn [IN] FTL context block list */ +/* that replace old FTL context positon */ +/* RETURN VALUES */ +/* VFL_SUCCESS */ +/* VFL_Format is completed. */ +/* VFL_CRITICAL_ERROR */ +/* VFL_Format is failed. */ +/* NOTES */ +/* */ +/*****************************************************************************/ +static Int32 +VFL_ChangeFTLCxtVbn(UInt16 *pwaFTLCxtVbn) +{ + UInt16 wWritePosition; + UInt16 wCSIdx; + + wWritePosition = (UInt16)(gdwMaxGlobalAge % CS_TOTAL); + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + CHECK_VFL_CXT_CHECK_SUM(wCSIdx); + /* make sure all are up to date so later storing of VFL Cxt would be correct */ + WMR_MEMCPY(pstVFLMeta[wCSIdx].stVFLCxt.awFTLCxtVbn, pwaFTLCxtVbn, FTL_CXT_SECTION_SIZE * sizeof(UInt16)); + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + } + + if (!_StoreVFLCxt(wWritePosition)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL context write fail !\n"))); + return VFL_CRITICAL_ERROR; + } + + return VFL_SUCCESS; +} + +static BOOL32 +_SetFTLType(UInt32 dwFTLType) +{ + UInt16 wWritePosition; + UInt16 wCSIdx; + VFLCxt *pVFLCxt = NULL; + + wWritePosition = (UInt16)(gdwMaxGlobalAge % CS_TOTAL); + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + pVFLCxt = &pstVFLMeta[wCSIdx].stVFLCxt; + CHECK_VFL_CXT_CHECK_SUM(wCSIdx); + /* make sure all are up to date so later storing of VFL Cxt would be correct */ + pVFLCxt->dwFTLType = dwFTLType; + // setting the FTL should come from the FTL format function + // clear any new VFL settings we had... + WMR_MEMSET(pVFLCxt->abFTLFormat, 0, FTL_FORMAT_STRUCT_SIZE); + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + } + + if (!_StoreVFLCxt(wWritePosition)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _SetFTLType fail !\n"))); + return FALSE32; + } + + return TRUE32; +} + +static BOOL32 +_SetNewFTLType(UInt32 dwFTLType) +{ + UInt16 wWritePosition; + UInt16 wCSIdx; + VFLCxt *pVFLCxt = NULL; + FTLFormatType * pFTLFormatType; + + wWritePosition = (UInt16)(gdwMaxGlobalAge % CS_TOTAL); + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + pVFLCxt = &pstVFLMeta[wCSIdx].stVFLCxt; + pFTLFormatType = (FTLFormatType *)pVFLCxt->abFTLFormat; + + CHECK_VFL_CXT_CHECK_SUM(wCSIdx); + WMR_MEMCPY(pFTLFormatType->abNewNumOfFTLSuBlk, &pVFLCxt->wNumOfFTLSuBlk, sizeof(UInt16)); + WMR_MEMCPY(pFTLFormatType->abNewFTLType, &dwFTLType, sizeof(UInt32)); + pFTLFormatType->bFormatFTL = 1; // mark for format + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + } + + if (!_StoreVFLCxt(wWritePosition)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _SetNewFTLType fail !\n"))); + return FALSE32; + } + + return TRUE32; +} + +static BOOL32 +_SetNewNumOfFTLSuBlks(UInt16 wNumOfFTLSuBlks) +{ + UInt16 wWritePosition; + UInt16 wCSIdx; + VFLCxt *pVFLCxt = NULL; + FTLFormatType * pFTLFormatType; + + wWritePosition = (UInt16)(gdwMaxGlobalAge % CS_TOTAL); + + if (wNumOfFTLSuBlks > _GetNumOfSuBlks()) { + WMR_PANIC("invalid burnin-size settings: %d FTL, %d VFL sublks", wNumOfFTLSuBlks, _GetNumOfSuBlks()); + } + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + pVFLCxt = &pstVFLMeta[wCSIdx].stVFLCxt; + pFTLFormatType = (FTLFormatType *)pVFLCxt->abFTLFormat; + + CHECK_VFL_CXT_CHECK_SUM(wCSIdx); + // make sure we keep the current FTL type + WMR_MEMCPY(pFTLFormatType->abNewFTLType, &pVFLCxt->dwFTLType, sizeof(UInt32)); + WMR_MEMCPY(pFTLFormatType->abNewNumOfFTLSuBlk, &wNumOfFTLSuBlks, sizeof(UInt16)); + pFTLFormatType->bFormatFTL = 1; // mark for format + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + } + + if (!_StoreVFLCxt(wWritePosition)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _SetNewNumOfFTLSuBlks fail !\n"))); + return FALSE32; + } + + return TRUE32; +} + +static BOOL32 +_SetNumOfFTLSuBlks(UInt16 wNumOfFTLSuBlks) +{ + UInt16 wWritePosition; + UInt16 wCSIdx; + + wWritePosition = (UInt16)(gdwMaxGlobalAge % CS_TOTAL); + + if (wNumOfFTLSuBlks > _GetNumOfSuBlks()) { + WMR_PANIC("invalid burnin-size settings: %d FTL, %d VFL sublks", wNumOfFTLSuBlks, _GetNumOfSuBlks()); + } + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + CHECK_VFL_CXT_CHECK_SUM(wCSIdx); + /* make sure all are up to date so later storing of VFL Cxt would be correct */ + if (wNumOfFTLSuBlks == 0) + { + pstVFLMeta[wCSIdx].stVFLCxt.wNumOfFTLSuBlk = pstVFLMeta[wCSIdx].stVFLCxt.wNumOfVFLSuBlk; + } + else + { + pstVFLMeta[wCSIdx].stVFLCxt.wNumOfFTLSuBlk = wNumOfFTLSuBlks; + } + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + } + + if (!_StoreVFLCxt(wWritePosition)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _SetNewNumOfFTLSuBlks fail !\n"))); + return FALSE32; + } + + return TRUE32; +} + +static BOOL32 +_SetNewFTLParams(void) +{ + UInt16 wWritePosition; + UInt16 wCSIdx; + VFLCxt *pVFLCxt = NULL; + FTLFormatType * pFTLFormatType; + + wWritePosition = (UInt16)(gdwMaxGlobalAge % CS_TOTAL); + + for (wCSIdx = 0; wCSIdx < CS_TOTAL; wCSIdx++) + { + pVFLCxt = &pstVFLMeta[wCSIdx].stVFLCxt; + pFTLFormatType = (FTLFormatType *)pVFLCxt->abFTLFormat; + + CHECK_VFL_CXT_CHECK_SUM(wCSIdx); + // make sure we keep the current FTL type + WMR_MEMCPY(&pVFLCxt->dwFTLType, pFTLFormatType->abNewFTLType, sizeof(UInt32)); + WMR_MEMCPY(&pVFLCxt->wNumOfFTLSuBlk, pFTLFormatType->abNewNumOfFTLSuBlk, sizeof(UInt16)); + if (pVFLCxt->wNumOfFTLSuBlk == 0) + { + pVFLCxt->wNumOfFTLSuBlk = pVFLCxt->wNumOfVFLSuBlk; + } + RECALC_VFL_CXT_CHECK_SUM(wCSIdx); + } + + if (!_StoreVFLCxt(wWritePosition)) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL context write fail !\n"))); + return FALSE32; + } + + return TRUE32; +} + +/* + NAME + VFL_WriteMultiplePagesInVb + DESCRIPTION + This function suppose to make the writing of several pages in the same block + more efficient. + Data and spare info (only meta data) for pages the write is given by the FTL + as an array. + + PARAMETERS + wVbn - the Vbn we are writing to. + wStartPOffset - start offset from the beginning of the Vbn. + wNumPagesToWrite - number of pages to write. + pbaData - data buffer. + pbaSpare - meta data buffer. + RETURN VALUES + TRUE32 + Operation completed successfully. + FALSE32 + Operation failed. + NOTES + This function should not be used for writes of less than TOTAL_BANKS Vbs!!! + */ + + +BOOL32 VFL_WriteMultiplePagesInVb(UInt32 dwVpn, UInt16 wNumPagesToWrite, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening) +{ + UInt16 wPOffsetIdx, wCurrPOffset; + UInt16 wBankIdx; + UInt16 wPagesToWriteNow; + BOOL32 boolAligned = TRUE32, boolCorrectBank = TRUE32; + UInt16 wVbn, wStartPOffset; + + UInt16 wFailingCE = CE_STATUS_UNINITIALIZED; + UInt32 wFailingPage = PAGE_STATUS_UNINITIALIZED; + Int32 nFILRet = FIL_CRITICAL_ERROR; + + wStartPOffset = (UInt16)(dwVpn % PAGES_PER_SUBLK); + wVbn = _Vpn2Vbn(dwVpn); + + // WMR_ASSERT((wStartPOffset + wNumPagesToWrite) < (PAGES_PER_SUBLK + 1)); + if ((wStartPOffset + wNumPagesToWrite) > PAGES_PER_SUBLK) + { + return FALSE32; + } + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesWrittenCnt += wNumPagesToWrite; + stVFLStatistics.ddwMultipleWriteCallCnt++; +#endif + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + UInt16 wPbn; + _ConvertT2P(wBankIdx, _Vbn2Tbn(wVbn), &wPbn); + pawPbnUnmapped[wBankIdx] = wPbn; + pawPbnRemapped[wBankIdx] = _RemapBlock(_Bank2CS(wBankIdx), wPbn, &boolAligned, &boolCorrectBank); + } + /* write the first few sectors until we are BANKS_TOTAL aligned - start */ + wCurrPOffset = wStartPOffset; + wPagesToWriteNow = WMR_MIN(wNumPagesToWrite, (BANKS_TOTAL - (wCurrPOffset % BANKS_TOTAL))); + if (wPagesToWriteNow != 0 && wPagesToWriteNow != BANKS_TOTAL) + { + for (wPOffsetIdx = 0; wPOffsetIdx < wPagesToWriteNow; wPOffsetIdx++) + { + UInt16 wBank = _Vpn2Bank((wPOffsetIdx + wCurrPOffset)); + // prepare the data for write scattered + pstawScatteredReadWriteCS[wPOffsetIdx] = _Bank2CS(wBank); + pawPbn[wPOffsetIdx] = pawPbnRemapped[wBank]; + pawPbnOriginal[wPOffsetIdx] = pawPbnUnmapped[wBank]; + pstadwScatteredReadWritePpn[wPOffsetIdx] = _Cbn2Ppn(pawPbn[wPOffsetIdx], ((wPOffsetIdx + wCurrPOffset) / BANKS_TOTAL)); + } + if (pFuncTbl->WriteScatteredPages != NULL) + { + nFILRet = pFuncTbl->WriteScatteredPages(pstawScatteredReadWriteCS, pstadwScatteredReadWritePpn, pbaData, pbaSpare, wPagesToWriteNow, &wFailingCE, bDisableWhitening, &wFailingPage); + if (nFILRet != FIL_SUCCESS) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_WriteMultiplePagesInVb(wVbn:0x%0X) (line:%d) fail!\n"), wVbn, __LINE__)); + + if (wFailingCE < CS_TOTAL) + { + CHECK_VFL_CXT_CHECK_SUM(wFailingCE); + pstVFLMeta[wFailingCE].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wFailingCE); + } + _ReportWriteScatteredFailBlock(wFailingCE,wVbn,wFailingPage,pstawScatteredReadWriteCS,pstadwScatteredReadWritePpn,wPagesToWriteNow, nFILRet); + + if (boolReplaceBlockOnFail == TRUE32) + { + _MarkWriteScatteredFailBlockForDelete(wFailingCE, dwVpn, wFailingPage, pstawScatteredReadWriteCS, pstadwScatteredReadWritePpn, pawPbnOriginal, wPagesToWriteNow); + } + + return FALSE32; + } + pbaData += (wPagesToWriteNow * BYTES_PER_PAGE); + pbaSpare += (wPagesToWriteNow * BYTES_PER_METADATA_RAW); + } + else + { + for (wPOffsetIdx = 0; wPOffsetIdx < wPagesToWriteNow; wPOffsetIdx++) + { + nFILRet = pFuncTbl->Write(pstawScatteredReadWriteCS[wPOffsetIdx], pstadwScatteredReadWritePpn[wPOffsetIdx], pbaData, pbaSpare, bDisableWhitening); + if (nFILRet != FIL_SUCCESS) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_WriteMultiplePagesInVb(wVbn:0x%0X) (line:%d) fail!\n"), wVbn, __LINE__)); + + wFailingCE = pstawScatteredReadWriteCS[wPOffsetIdx]; // We know the failingCE since we only tried a single. + CHECK_VFL_CXT_CHECK_SUM(wFailingCE); + pstVFLMeta[wFailingCE].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wFailingCE); + _ReportWriteFailureSingle(wFailingCE, pstadwScatteredReadWritePpn[wPOffsetIdx], nFILRet); + + if (boolReplaceBlockOnFail == TRUE32) + { + _MarkWriteFailBlockForDeleteWithPbn(wFailingCE, pawPbnOriginal[wPOffsetIdx]); + } + + return FALSE32; + } + pbaData += BYTES_PER_PAGE; + pbaSpare += BYTES_PER_METADATA_RAW; + } + } + // recalc the offsets + wCurrPOffset += wPagesToWriteNow; + } + /* write the first few sectors until we are BANKS_TOTAL aligned - end */ + + /* write full super pages using write multiple - start */ + if (((wStartPOffset + wNumPagesToWrite) - wCurrPOffset) > BANKS_TOTAL) + { + wPagesToWriteNow = ((((wStartPOffset + wNumPagesToWrite) - wCurrPOffset) / BANKS_TOTAL) * BANKS_TOTAL); + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + padwPpnRemapped[wBankIdx] = _Cbn2Ppn(pawPbnRemapped[wBankIdx], (wCurrPOffset / BANKS_TOTAL)); + // for now - we check here - later this check should be done when generating pawPbnRemapped + } + + nFILRet = pFuncTbl->WriteMultiplePages(padwPpnRemapped, pbaData, pbaSpare, wPagesToWriteNow, boolAligned, boolCorrectBank, &wFailingCE, bDisableWhitening, &wFailingPage); + if ( nFILRet != FIL_SUCCESS) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_WriteMultiplePagesInVb(wVbn:0x%0X) (line:%d) fail!\n"), wVbn, __LINE__)); + + if (wFailingCE < CS_TOTAL) + { + CHECK_VFL_CXT_CHECK_SUM(wFailingCE); + pstVFLMeta[wFailingCE].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wFailingCE); + } + _ReportWriteMultipleFailBlock(wFailingCE,wVbn,wFailingPage,padwPpnRemapped,wPagesToWriteNow, nFILRet); + + if (boolReplaceBlockOnFail == TRUE32) + { + _MarkWriteMultipleFailBlockForDelete(wFailingCE, dwVpn, wFailingPage, pawPbnUnmapped, pawPbnRemapped, padwPpnRemapped, wPagesToWriteNow); + } + + return FALSE32; + } + pbaData += wPagesToWriteNow * BYTES_PER_PAGE; + pbaSpare += wPagesToWriteNow * BYTES_PER_METADATA_RAW; + wCurrPOffset += wPagesToWriteNow; + } + /* write full super pages using write multiple - end */ + + /* write the last not banks aligned pages - start */ + wPagesToWriteNow = (wStartPOffset + wNumPagesToWrite) - wCurrPOffset; + if (wPagesToWriteNow != 0) + { + for (wPOffsetIdx = 0; wPOffsetIdx < wPagesToWriteNow; wPOffsetIdx++) + { + UInt16 wBank = _Vpn2Bank((wPOffsetIdx + wCurrPOffset)); + // prepare the data for write scattered + pstawScatteredReadWriteCS[wPOffsetIdx] = _Bank2CS(wBank); + pawPbn[wPOffsetIdx] = pawPbnRemapped[wBank]; + pawPbnOriginal[wPOffsetIdx] = pawPbnUnmapped[wBank]; + pstadwScatteredReadWritePpn[wPOffsetIdx] = _Cbn2Ppn(pawPbn[wPOffsetIdx], ((wPOffsetIdx + wCurrPOffset) / BANKS_TOTAL)); + } + + if (pFuncTbl->WriteScatteredPages != NULL) + { + nFILRet = pFuncTbl->WriteScatteredPages(pstawScatteredReadWriteCS, pstadwScatteredReadWritePpn, pbaData, pbaSpare, wPagesToWriteNow, &wFailingCE, bDisableWhitening, &wFailingPage); + if (nFILRet != FIL_SUCCESS) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_WriteMultiplePagesInVb(wVbn:0x%0X) (line:%d) fail!\n"), wVbn, __LINE__)); + + if (wFailingCE < CS_TOTAL) + { + CHECK_VFL_CXT_CHECK_SUM(wFailingCE); + pstVFLMeta[wFailingCE].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wFailingCE); + } + _ReportWriteScatteredFailBlock(wFailingCE,wVbn,wFailingPage,pstawScatteredReadWriteCS,pstadwScatteredReadWritePpn,wPagesToWriteNow, nFILRet); + + if (boolReplaceBlockOnFail == TRUE32) + { + _MarkWriteScatteredFailBlockForDelete(wFailingCE, dwVpn, wFailingPage, pstawScatteredReadWriteCS, pstadwScatteredReadWritePpn, pawPbnOriginal, wPagesToWriteNow); + } + + return FALSE32; + } + } + else + { + for (wPOffsetIdx = 0; wPOffsetIdx < wPagesToWriteNow; wPOffsetIdx++) + { + nFILRet = pFuncTbl->Write(pstawScatteredReadWriteCS[wPOffsetIdx], pstadwScatteredReadWritePpn[wPOffsetIdx], pbaData, pbaSpare, bDisableWhitening); + if (nFILRet != FIL_SUCCESS) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_WriteMultiplePagesInVb(wVbn:0x%0X) (line:%d) fail!\n"), wVbn, __LINE__)); + + wFailingCE = pstawScatteredReadWriteCS[wPOffsetIdx]; // We know the failingCE since we only tried a single. + CHECK_VFL_CXT_CHECK_SUM(wFailingCE); + pstVFLMeta[wFailingCE].stVFLCxt.wNumOfWriteFail++; + RECALC_VFL_CXT_CHECK_SUM(wFailingCE); + _ReportWriteFailureSingle(wFailingCE, pstadwScatteredReadWritePpn[wPOffsetIdx], nFILRet); + + if (boolReplaceBlockOnFail == TRUE32) + { + _MarkWriteFailBlockForDeleteWithPbn(wFailingCE, pawPbnOriginal[wPOffsetIdx]); + } + + return FALSE32; + } + pbaData += BYTES_PER_PAGE; + pbaSpare += BYTES_PER_METADATA_RAW; + } + } + } + // no need to recalc offsets here... + /* write the last not banks aligned pages - end */ + return TRUE32; +} +#endif + +#if (!AND_DISABLE_READ_MULTIPLE) + +BOOL32 VFL_ReadMultiplePagesInVb(UInt16 wVbn, UInt16 wStartPOffset, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening) +{ + UInt16 wBankIdx, wPagesToReadNow; + UInt16 wPOffsetIdx, wCurrPOffset; + UInt8 bECCCorrectedBits; + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesReadCnt += wNumPagesToRead; + stVFLStatistics.ddwSequetialReadCallCnt++; +#endif + + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + UInt16 wPbn; + _ConvertT2P(wBankIdx, _Vbn2Tbn(wVbn), &wPbn); + pawPbnRemapped[wBankIdx] = _RemapBlock(_Bank2CS(wBankIdx), wPbn, NULL, NULL); + } + + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = FALSE32; + } + /* read the first few sectors until we are BANKS_TOTAL aligned - start */ + wCurrPOffset = wStartPOffset; + + wPagesToReadNow = WMR_MIN(wNumPagesToRead, (BANKS_TOTAL - (wCurrPOffset % BANKS_TOTAL))); + if (wPagesToReadNow != 0 && wPagesToReadNow != BANKS_TOTAL) + { + Int32 nRet; + for (wPOffsetIdx = 0; wPOffsetIdx < wPagesToReadNow; wPOffsetIdx++) + { + UInt16 wBank = _Vpn2Bank((wPOffsetIdx + wCurrPOffset)); + // prepare the data for write scattered + pstawScatteredReadWriteCS[wPOffsetIdx] = _Bank2CS(wBank); + pstadwScatteredReadWritePpn[wPOffsetIdx] = _Cbn2Ppn(pawPbnRemapped[wBank], ((wPOffsetIdx + wCurrPOffset) / BANKS_TOTAL)); + } + + nRet = pFuncTbl->ReadScatteredPages(pstawScatteredReadWriteCS, pstadwScatteredReadWritePpn, pbaData, pbaSpare, wPagesToReadNow, &bECCCorrectedBits, pdwaSectorStats, bDisableWhitening); + if ((nRet != FIL_SUCCESS) && (nRet != FIL_SUCCESS_CLEAN)) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_ReadMultiplePagesInVb(wVbn:0x%0X) (line:%d) fail!\n"), wVbn, __LINE__)); + + _ReportECCFailureMultiple(wVbn); + return FALSE32; + } + if (bECCCorrectedBits >= FIL_ECC_REFRESH_TRESHOLD && pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = TRUE32; + } + // recalc the offsets + wCurrPOffset += wPagesToReadNow; + pbaData += (wPagesToReadNow * BYTES_PER_PAGE); + pbaSpare += (wPagesToReadNow * BYTES_PER_METADATA_RAW); + } + /* read the first few sectors until we are BANKS_TOTAL aligned - end */ + + /* read full super pages using write multiple - start */ + if (((wStartPOffset + wNumPagesToRead) - wCurrPOffset) > BANKS_TOTAL) + { + Int32 nFILRet; + wPagesToReadNow = ((((wStartPOffset + wNumPagesToRead) - wCurrPOffset) / BANKS_TOTAL) * BANKS_TOTAL); + for (wBankIdx = 0; wBankIdx < BANKS_TOTAL; wBankIdx++) + { + padwPpnRemapped[wBankIdx] = _Cbn2Ppn(pawPbnRemapped[wBankIdx], (wCurrPOffset / BANKS_TOTAL)); + } + + nFILRet = pFuncTbl->ReadMultiplePages(padwPpnRemapped, pbaData, pbaSpare, wPagesToReadNow, &bECCCorrectedBits, pdwaSectorStats, bDisableWhitening); + if (nFILRet != FIL_SUCCESS && nFILRet != FIL_SUCCESS_CLEAN) + { + _ReportECCFailureMultiple(wVbn); + return FALSE32; + } + if (bECCCorrectedBits >= FIL_ECC_REFRESH_TRESHOLD && pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = TRUE32; + } + pbaData += wPagesToReadNow * BYTES_PER_PAGE; + pbaSpare += wPagesToReadNow * BYTES_PER_METADATA_RAW; + wCurrPOffset += wPagesToReadNow; + } + /* read full super pages using write multiple - end */ + + /* read the last not banks aligned pages - start */ + wPagesToReadNow = (wStartPOffset + wNumPagesToRead) - wCurrPOffset; + if (wPagesToReadNow != 0) + { + Int32 nFILRet; + for (wPOffsetIdx = 0; wPOffsetIdx < wPagesToReadNow; wPOffsetIdx++) + { + UInt16 wBank = _Vpn2Bank((wPOffsetIdx + wCurrPOffset)); + // prepare the data for write scattered + pstawScatteredReadWriteCS[wPOffsetIdx] = _Bank2CS(wBank); + pstadwScatteredReadWritePpn[wPOffsetIdx] = _Cbn2Ppn(pawPbnRemapped[wBank], ((wPOffsetIdx + wCurrPOffset) / BANKS_TOTAL)); + } + nFILRet = pFuncTbl->ReadScatteredPages(pstawScatteredReadWriteCS, pstadwScatteredReadWritePpn, pbaData, pbaSpare, wPagesToReadNow, &bECCCorrectedBits, pdwaSectorStats, bDisableWhitening); + if (nFILRet != FIL_SUCCESS && nFILRet != FIL_SUCCESS_CLEAN) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_ReadMultiplePagesInVb(wVbn:0x%0X) (line:%d) fail!\n"), wVbn, __LINE__)); + + _ReportECCFailureMultiple(wVbn); + + return FALSE32; + } + if (bECCCorrectedBits >= FIL_ECC_REFRESH_TRESHOLD && pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = TRUE32; + } + } + /* read the last not banks aligned pages - end */ + return TRUE32; +} + +#endif /* if (!AND_DISABLE_READ_MULTIPLE) */ + +BOOL32 VFL_ReadScatteredPagesInVb(UInt32 * padwVpn, UInt16 wNumPagesToRead, UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 * pboolNeedRefresh, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening, Int32 *actualStatus) +{ + UInt16 wPageIdx; + Int32 nRet; + UInt8 bCorrectableECC = 0; + +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwPagesReadCnt += wNumPagesToRead; + stVFLStatistics.ddwScatteredReadCallCnt++; +#endif + + if (pboolNeedRefresh != NULL) + { + *pboolNeedRefresh = FALSE32; + } + + for (wPageIdx = 0; wPageIdx < wNumPagesToRead; wPageIdx++) + { + // translate Vpn address to CS and dwPpn + _Vpn2Ppn(padwVpn[wPageIdx], &pstawScatteredReadWriteCS[wPageIdx], &pstadwScatteredReadWritePpn[wPageIdx]); + } + + nRet = pFuncTbl->ReadScatteredPages(pstawScatteredReadWriteCS, pstadwScatteredReadWritePpn, pbaData, pbaSpare, wNumPagesToRead, &bCorrectableECC, pdwaSectorStats, bDisableWhitening); + if (bCorrectableECC >= FIL_ECC_REFRESH_TRESHOLD && pboolNeedRefresh != NULL) + { + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_ReadScatteredPagesInVb mark page for refresh (line:%d)!\n"), __LINE__)); + *pboolNeedRefresh = TRUE32; + } + if(actualStatus != NULL) + *actualStatus = nRet; + if ((nRet != FIL_SUCCESS) && (nRet != FIL_SUCCESS_CLEAN)) + { + _ReportECCFailureMultiple(_Vpn2Vbn(padwVpn[0])); // Make the best guess + return FALSE32; + } + else + { + return TRUE32; + } +} + +static BOOL32 +VFL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { + case AND_STRUCT_VFL_VFLMETA: + { + const UInt32 wCS = dwStructType & AND_STRUCT_CS_MASK; + if (pstVFLMeta && (wCS < CS_TOTAL)) + { + VFLMeta *pSrcMeta = &pstVFLMeta[wCS]; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, pSrcMeta, sizeof(*pSrcMeta)); + } + break; + } + + case AND_STRUCT_VFL_GET_TYPE: + { + UInt8 bVFLType = VFL_TYPE_VSVFL; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &bVFLType, sizeof(bVFLType)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_STATISTICS_SIZE: + { + UInt32 dwStatSize = sizeof(VFLStatistics); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwStatSize, sizeof(dwStatSize)); + break; + } + + case AND_STRUCT_VFL_STATISTICS: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stVFLStatistics, sizeof(stVFLStatistics)); + break; + } +#endif // AND_COLLECT_STATISTICS + + case AND_STRUCT_VFL_DEVICEINFO_SIZE: + { + UInt32 dwDevInfoSize = sizeof(stVSVFLWMRDeviceInfo); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwDevInfoSize, sizeof(dwDevInfoSize)); + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_DEVICEINFO: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stVSVFLWMRDeviceInfo, sizeof(stVSVFLWMRDeviceInfo)); + break; + } +#endif + + case AND_STRUCT_VFL_FILSTATISTICS: + { + boolRes = FIL_GetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS: + { + UInt16 dwNumFTLSuBlks = _GetNumOfFTLSuBlks(); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumFTLSuBlks, sizeof(dwNumFTLSuBlks)); + break; + } + + case AND_STRUCT_VFL_NUM_OF_SUBLKS: + { + UInt16 dwNumVFLSuBlks = _GetNumOfSuBlks(); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwNumVFLSuBlks, sizeof(dwNumVFLSuBlks)); + break; + } + + case AND_STRUCT_VFL_GETADDRESS: + { + ANDAddressStruct stAddress; + + if (pvoidStructBuffer) + { + UInt16 wCS = 0; + + WMR_MEMCPY(&stAddress, pvoidStructBuffer, sizeof(stAddress)); + _Vpn2Ppn(stAddress.dwVpn, &wCS, &stAddress.dwPpn); + stAddress.dwCS = wCS; + + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &stAddress, sizeof(stAddress)); + } + else if (pdwStructSize) + { + *pdwStructSize = sizeof(stAddress); + boolRes = TRUE32; + } + + break; + } + +#ifdef AND_COLLECT_STATISTICS + case AND_STRUCT_VFL_BURNIN_CODE: + { + UInt32 dwBurnInCodeTrunc = (UInt32) stVFLStatistics.ddwBurnInCode; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwBurnInCodeTrunc, sizeof(dwBurnInCodeTrunc)); + break; + } +#endif //AND_COLLECT_STATISTICS + + case AND_STRUCT_VFL_BYTES_PER_PAGE: + { + UInt16 wPageSize = BYTES_PER_PAGE; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPageSize, sizeof(wPageSize)); + break; + } + + case AND_STRUCT_VFL_PAGES_PER_SUBLK: + { + UInt16 wPagesPerSuBlk = PAGES_PER_SUBLK; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPagesPerSuBlk, sizeof(wPagesPerSuBlk)); + break; + } + + case AND_STRUCT_VFL_BYTES_PER_META: + { + UInt16 wBytesPerMetaData = (UInt16) pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_META_BUFFER_BYTES); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wBytesPerMetaData, sizeof(wBytesPerMetaData)); + break; + } + + case AND_STRUCT_VFL_VALID_BYTES_PER_META: + { + UInt16 wBytesPerMetaData = (UInt16) pFuncTbl->GetDeviceInfo(AND_DEVINFO_FIL_META_VALID_BYTES); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wBytesPerMetaData, sizeof(wBytesPerMetaData)); + break; + } + + case AND_STRUCT_VFL_NAND_TYPE: + { + UInt32 nandType = NAND_TYPE_RAW; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &nandType, + sizeof(nandType)); + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_BITS: + { + UInt16 wCorrectableBits = (UInt16) pFuncTbl->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_BITS); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wCorrectableBits, sizeof(wCorrectableBits)); + break; + } + + case AND_STRUCT_VFL_CORRECTABLE_SIZE: + { + UInt16 wCorrectableSize = (UInt16) pFuncTbl->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wCorrectableSize, sizeof(wCorrectableSize)); + break; + } + + case AND_STRUCT_VFL_PUBLIC_FBBT: + // Fall Through + case AND_STRUCT_VFL_FACTORY_BBT: + { + boolRes = _GetFactoryBBTBuffer(pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_VFL_PAGES_PER_BLOCK: + { + UInt16 wPagesPerBlock = (UInt16) pFuncTbl->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &wPagesPerBlock, sizeof(wPagesPerBlock)); + break; + } + + case AND_STRUCT_VFL_LAST_ERROR: + { + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &gstLastFailure, sizeof(gstLastFailure)); + break; + } + +#if AND_SUPPORT_BLOCK_BORROWING + case AND_STRUCT_VFL_FIND_BORROWED_BLOCKS: + { + UInt32 maxBlocks; + if (NULL != pdwStructSize) + { + BorrowBlockAddress *pastrBlocks = (BorrowBlockAddress*)pvoidStructBuffer; + maxBlocks = *pdwStructSize / sizeof(pastrBlocks[0]); + boolRes = _VSVFL_FindBorrowedBlocks(pastrBlocks, &maxBlocks); + *pdwStructSize = maxBlocks * sizeof(pastrBlocks[0]); + } + break; + } +#endif + + default: + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_GetStruct 0x%X is not identified is VFL data struct identifier!\n"), dwStructType)); + boolRes = FALSE32; + } + return boolRes; +} + +static BOOL32 +VFL_SetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 dwStructSize) +{ + BOOL32 boolRes = TRUE32; + + switch (dwStructType & AND_STRUCT_INDEX_MASK) + { +#ifndef AND_READONLY + case AND_STRUCT_VFL_FTLTYPE: + { + _SetFTLType(*((UInt32*)pvoidStructBuffer)); + break; + } + + case AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS: + { + _SetNumOfFTLSuBlks(*((UInt16*)pvoidStructBuffer)); + break; + } + + case AND_STRUCT_VFL_NEW_FTLTYPE: + { + _SetNewFTLType(*((UInt32*)pvoidStructBuffer)); + break; + } + + case AND_STRUCT_VFL_NEW_NUM_OF_FTL_SUBLKS: + { + _SetNewNumOfFTLSuBlks(*((UInt16*)pvoidStructBuffer)); + break; + } +#endif + + case AND_STRUCT_VFL_BURNIN_CODE: + { +#ifdef AND_COLLECT_STATISTICS + stVFLStatistics.ddwBurnInCode = *((UInt32*)pvoidStructBuffer); +#else + boolRes = FALSE32; +#endif + break; + } + + case AND_STRUCT_VFL_STATISTICS: + { +#ifdef AND_COLLECT_STATISTICS + WMR_MEMCPY(&stVFLStatistics, pvoidStructBuffer, WMR_MIN(sizeof(VFLStatistics), dwStructSize)); +#else + boolRes = FALSE32; +#endif + break; + } + +#ifndef AND_READONLY + case AND_STRUCT_VFL_FILSTATISTICS: + { +#ifdef AND_COLLECT_STATISTICS + FIL_SetStruct(AND_STRUCT_FIL_STATISTICS, pvoidStructBuffer, dwStructSize); +#else + boolRes = FALSE32; +#endif + break; + } +#endif // ! AND_READONLY + + default: + VFL_WRN_PRINT((TEXT("[VFL:WRN] VFL_SetStruct 0x%X is not identified is VFL data struct identifier!\n"), dwStructType)); + boolRes = FALSE32; + } + return boolRes; +} + +static UInt16 VFL_GetVbasPerVb(UInt16 wVbn) +{ + return PAGES_PER_SUBLK; +} + +void VSVFL_Register(VFLFunctions * pVFL_Functions) +{ +#ifndef AND_READONLY + pVFL_Functions->Format = VFL_Format; + pVFL_Functions->WriteSinglePage = VFL_Write; + pVFL_Functions->Erase = VFL_Erase; + pVFL_Functions->ChangeFTLCxtVbn = VFL_ChangeFTLCxtVbn; + pVFL_Functions->WriteMultiplePagesInVb = VFL_WriteMultiplePagesInVb; +#if AND_SUPPORT_BLOCK_BORROWING + pVFL_Functions->BorrowSpareBlock = _VSVFL_BorrowBlock; +#endif //AND_SUPPORT_BLOCK_BORROWING +#endif // ! AND_READONLY + pVFL_Functions->Init = VFL_Init; + pVFL_Functions->Open = VFL_Open; + pVFL_Functions->Close = VFL_Close; +#if (!AND_DISABLE_READ_MULTIPLE) + pVFL_Functions->ReadMultiplePagesInVb = VFL_ReadMultiplePagesInVb; +#else /* if (!AND_DISABLE_READ_MULTIPLE) */ + pVFL_Functions->ReadMultiplePagesInVb = NULL; +#endif /* if (!AND_DISABLE_READ_MULTIPLE) */ + pVFL_Functions->ReadScatteredPagesInVb = VFL_ReadScatteredPagesInVb; + pVFL_Functions->ReadSinglePage = VFL_Read; + pVFL_Functions->GetFTLCxtVbn = VFL_GetFTLCxtVbn; +// pVFL_Functions->GetAddress = VFL_GetAddress; + pVFL_Functions->GetStruct = VFL_GetStruct; + pVFL_Functions->SetStruct = VFL_SetStruct; + pVFL_Functions->GetDeviceInfo = VFL_GetDeviceInfo; + pVFL_Functions->GetVbasPerVb = VFL_GetVbasPerVb; +} + +static UInt32 VFL_GetDeviceInfo(UInt32 dwParamType) +{ + UInt32 dwRetVal = 0xFFFFFFFF; + + switch (dwParamType) + { + case AND_DEVINFO_PAGES_PER_SUBLK: + { + dwRetVal = (UInt32)PAGES_PER_SUBLK; + break; + } + + case AND_DEVINFO_BYTES_PER_PAGE: + { + dwRetVal = (UInt32)BYTES_PER_PAGE; + break; + } + + case AND_DEVINFO_NUM_OF_BANKS: + { + dwRetVal = (UInt32)BANKS_TOTAL; + break; + } + + case AND_DEVINFO_NUM_OF_USER_SUBLK: + { + dwRetVal = (UInt32)_GetNumOfFTLSuBlks(); + break; + } + + case AND_DEVINFO_FTL_TYPE: + { + dwRetVal = (UInt32)_GetFTLType(); + break; + } + + case AND_DEVINFO_FTL_NEED_FORMAT: + { + FTLFormatType * pFTLFormatType = (FTLFormatType *)pstVFLMeta[0].stVFLCxt.abFTLFormat; + dwRetVal = (UInt32)(pFTLFormatType->bFormatFTL); + break; + } + case AND_DEVINFO_FIL_LBAS_PER_PAGE: + { + dwRetVal = stVSVFLWMRDeviceInfo.dwLogicalPageSize; + break; + } + case AND_DEVINFO_FIL_META_BUFFER_BYTES: + { + dwRetVal = stVSVFLWMRDeviceInfo.dwTotalMetaPerLogicalPage; + break; + } + case AND_DEVINFO_FIL_META_VALID_BYTES: + { + dwRetVal = stVSVFLWMRDeviceInfo.dwValidMetaPerLogicalPage; + break; + } + + default: + VFL_ERR_PRINT((TEXT("[VFL:ERR] VFL_GetDeviceInfo dwParamType not supported (0x%X) (line:%d)!\n"), dwParamType, __LINE__)); + break; + } + return dwRetVal; +} + +// ============================================================================= +// Private Addressing and Timing Functions +// ============================================================================= + +// direct block and page mapping address "conversions" (i.e. noop) +void _pfnConvert_Direct(UInt32 dwBankOrCE, UInt32 dwPpnOrCpn, UInt32* pdwCEOrBank, UInt32* pdwCpnOrPpn) +{ + *pdwCEOrBank = dwBankOrCE; + *pdwCpnOrPpn = dwPpnOrCpn; +} +#if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) +// generic address conversion functions +void _Helper_ConvertP2C_OneBitReorder(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn, UInt32 dwReorderMask) +{ + const UInt32 dwBelowReorderMask = dwReorderMask - 1; // Assumption: dwReorderMask is a power of 2! + const UInt32 dwAboveReorderMask = ~dwBelowReorderMask; + + // insert reorder bit back in correct position of "chip" page number by extracting from MSB of "physical" bank number + *pdwCpn = ((dwPpn & dwBelowReorderMask) | + (((dwBank / CS_TOTAL) & 0x1) ? dwReorderMask : 0) | + ((dwPpn & dwAboveReorderMask) << 1)); + + // strip reorder bit from MSB of "physical" bank number to produce "chip" CE + *pdwCE = dwBank % CS_TOTAL; +} + +void _Helper_ConvertC2P_OneBitReorder(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn, UInt32 dwReorderMask) +{ + const UInt32 dwBelowReorderMask = dwReorderMask - 1; // Assumption: dwReorderMask is a power of 2! + const UInt32 dwAboveReorderMask = ~dwBelowReorderMask << 1; + + // remove reorder bit from "chip" page number to produce "physical" page number + *pdwPpn = ((dwCpn & dwBelowReorderMask) | + ((dwCpn & dwAboveReorderMask) >> 1)); + + // prepend psuedo-bank bit to "chip" CE as MSB of "physical" bank number + *pdwBank = dwCE + ((dwCpn & dwReorderMask) ? CS_TOTAL : 0); +} +void _Helper_ConvertP2C_TwoBitReorder(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn, UInt32 dw1stReorderMask, UInt32 dw2ndReorderMask) +{ + const BOOL32 bool1stIsUpper = (dw1stReorderMask > dw2ndReorderMask); + + const UInt32 dwUpperReorderMask = bool1stIsUpper ? dw1stReorderMask : dw2ndReorderMask; + const UInt32 dwLowerReorderMask = bool1stIsUpper ? dw2ndReorderMask : dw1stReorderMask; + + const UInt32 dwBelowReorderMask = dwLowerReorderMask - 1; + const UInt32 dwAboveReorderMask = ~(dwUpperReorderMask - 1); + const UInt32 dwBetweenReorderMask = ~(dwBelowReorderMask | dwAboveReorderMask); + + // insert reorder bits back in correct positions of "chip" page number + // by extracting from two most significant bits of "physical" bank number + *pdwCpn = ((dwPpn & dwBelowReorderMask) | + ((dwPpn & dwBetweenReorderMask) << 1) | + ((dwPpn & dwAboveReorderMask) << 2) | + (((dwBank / CS_TOTAL) & 0x1) ? dw1stReorderMask : 0) | + (((dwBank / CS_TOTAL) & 0x2) ? dw2ndReorderMask : 0)); + + // strip reorder bits from two most significant bits of "physical" bank number + // to produce "chip" CE + *pdwCE = dwBank % CS_TOTAL; +} +void _Helper_ConvertC2P_TwoBitReorder(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn, UInt32 dw1stReorderMask, UInt32 dw2ndReorderMask) +{ + const BOOL32 bool1stIsUpper = (dw1stReorderMask > dw2ndReorderMask); + + const UInt32 dwUpperReorderMask = bool1stIsUpper ? dw1stReorderMask : dw2ndReorderMask; + const UInt32 dwLowerReorderMask = bool1stIsUpper ? dw2ndReorderMask : dw1stReorderMask; + + const UInt32 dwBelowReorderMask = dwLowerReorderMask - 1; + const UInt32 dwAboveReorderMask = ~(dwUpperReorderMask - 1) << 1; + const UInt32 dwBetweenReorderMask = ~(dwBelowReorderMask | dwLowerReorderMask | dwUpperReorderMask | dwAboveReorderMask); + + // remove reorder bits from "chip" page number to produce "physical" page number + *pdwPpn = ((dwCpn & dwBelowReorderMask) | + ((dwCpn & dwBetweenReorderMask) >> 1) | + ((dwCpn & dwAboveReorderMask) >> 2)); + + // prepend psuedo-bank bits to "chip" CE as most significant bits of "physical" bank number + *pdwBank = (((dwCpn & dw2ndReorderMask) ? (2 * CS_TOTAL) : 0) + + ((dwCpn & dw1stReorderMask) ? CS_TOTAL : 0) + + dwCE); +} + +// address conversions for alternating two planes, addressed on least significant block address +void _pfnConvertP2C_TwoPlaneLSB(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) +{ + _Helper_ConvertP2C_OneBitReorder(dwBank, dwPpn, pdwCE, pdwCpn, PAGES_PER_BLOCK); +} +void _pfnConvertC2P_TwoPlaneLSB(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn) +{ + _Helper_ConvertC2P_OneBitReorder(dwCE, dwCpn, pdwBank, pdwPpn, PAGES_PER_BLOCK); +} + +// address conversions for alternating two dies, addressed on most significant block address +void _pfnConvertP2C_TwoDieMSB(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) +{ + _Helper_ConvertP2C_OneBitReorder(dwBank, dwPpn, pdwCE, pdwCpn, PAGES_PER_CS >> 1); +} +void _pfnConvertC2P_TwoDieMSB(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn) +{ + _Helper_ConvertC2P_OneBitReorder(dwCE, dwCpn, pdwBank, pdwPpn, PAGES_PER_CS >> 1); +} + +// address conversions for alternating two planes, addressed on least significant block address, +// then two dies, addressed on most significant block address (i.e. D0:P0, D0:P1, D1:P0, D1:P1) +void _pfnConvertP2C_TwoPlaneLSBTwoDieMSB(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) +{ + _Helper_ConvertP2C_TwoBitReorder(dwBank, dwPpn, pdwCE, pdwCpn, PAGES_PER_BLOCK, PAGES_PER_CS >> 1); +} +void _pfnConvertC2P_TwoPlaneLSBTwoDieMSB(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn) +{ + _Helper_ConvertC2P_TwoBitReorder(dwCE, dwCpn, pdwBank, pdwPpn, PAGES_PER_BLOCK, PAGES_PER_CS >> 1); +} + +// address conversions for alternating between Toshiba-style districts +void _pfnConvertP2C_ToshibaTwoDistrict(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) +{ + const UInt32 dwDistrictMask = PAGES_PER_BLOCK; // Assumes this is a power of 2. + + _Helper_ConvertP2C_OneBitReorder(dwBank, dwPpn, pdwCE, pdwCpn, dwDistrictMask); +} +void _pfnConvertC2P_ToshibaTwoDistrict(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn) +{ + const UInt32 dwDistrictMask = PAGES_PER_BLOCK; // Assumes this is a power of 2. + + _Helper_ConvertC2P_OneBitReorder(dwCE, dwCpn, pdwBank, pdwPpn, dwDistrictMask); +} + +// Converts to CE / Cpn without power of 2 assumptions on # of +// blocks per chip select. +// +// Assumed vendor ordering is as follows (for a 2-CE part): +// +// bank CE Die Plane|District +// +// 0 0 0 0 +// 1 1 0 0 +// ------------------------ nCE +// 2 0 0 1 +// 3 1 0 1 +// ------------------------ 2 * nCE ( 2 = nPlanes ) +// +// Which is to say that we alternate with the CS first, and then the Plane/District. +// +// This algorithm assumes that planes / districts are based +// upon even/odd block #'s (even = plane0) and that there are +// 128 pages per block (meaning we need to preserve the seven +// least significant bits of the Ppn). +void _pfnConvertP2C_SingleDie_7bitPlaneNoPower2(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) +{ + const UInt32 wPlane_x_Banks = 2 * CS_TOTAL; // Assumes 2 planes... + const UInt32 fDistrictZero = ( (dwBank % wPlane_x_Banks)> 1) | (dwCpn & 0x7f); // Assumes 128 pages per block +} + +// Converts to CE / Cpn without power of 2 assumptions on # of +// blocks per chip select. +// +// Assumed vendor ordering is as follows (for a 2-CE part): +// +// bank CE Die Plane|District +// +// 0 0 0 0 +// 1 1 0 0 +// ------------------------ nCE +// 2 0 0 1 +// 3 1 0 1 +// ------------------------ 2 * nCE ( 2 = nPlanes ) +// 4 0 1 0 +// 5 1 1 0 +// 6 0 1 1 +// 7 1 1 1 +// ------------------------ 2 * nCE * nDie ( 2 = nPlanes ) +// +// Which is to say that we alternate with the CS first, +// Plane/District second and finally the Die. +// +// This algorithm assumes that planes / districts are based +// upon even/odd block #'s (even = plane0) and that there are +// 128 pages per block (meaning we need to preserve the seven +// least significant bits of the Ppn). +void _pfnConvertP2C_TwoDie2_7bitPlaneNoPower2(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) +{ + const UInt32 wPlane_x_Banks = 2 * CS_TOTAL; // Assumes 2 planes... + const UInt32 fDistrictZero = ( (dwBank % wPlane_x_Banks)= wPagesPerDie ) + { + dwCpn -= wPagesPerDie; + *pdwBank += wPlane_x_Banks; + } + + wBlkNum = dwCpn / PAGES_PER_BLOCK; + fDistrictZero = ( 0 == (wBlkNum & 1) ? 1 : 0 ); + + if ( !fDistrictZero ) + { + // district 1 + wBlkNum--; + *pdwBank += (wPlane_x_Banks / 2); + } + *pdwPpn = PAGES_PER_BLOCK * (wBlkNum >> 1) | (dwCpn & 0x7f); // Assumes 128 pages per block +} + +// address conversions for alternating between Toshiba-style districts with extended areas +// +void _pfnConvertP2C_ToshibaTwoDistrictExt(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) +{ + const UInt32 dwExtBlocks = 128; + const UInt32 dwExtPages = dwExtBlocks * PAGES_PER_BLOCK; + const UInt32 dwExtDistrictMask = dwExtPages >> 2; + + const UInt32 dwMainBlocks = BLOCKS_PER_CS - dwExtBlocks; + const UInt32 dwMainPages = dwMainBlocks * PAGES_PER_BLOCK; + const UInt32 dwMainDistrictMask = dwMainPages >> 2; + + // note that the Main/Ext page boundary gets shifted down by one bit + // to reflect that Ppn already has reorder bit removed from Cpn + const UInt32 dwDistrictMask = ((dwMainPages >> 1) > dwPpn) ? dwMainDistrictMask : dwExtDistrictMask; + + _Helper_ConvertP2C_OneBitReorder(dwBank, dwPpn, pdwCE, pdwCpn, dwDistrictMask); +} +void _pfnConvertC2P_ToshibaTwoDistrictExt(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn) +{ + const UInt32 dwExtBlocks = 128; + const UInt32 dwExtPages = dwExtBlocks * PAGES_PER_BLOCK; + const UInt32 dwExtDistrictMask = dwExtPages >> 2; + + const UInt32 dwMainBlocks = BLOCKS_PER_CS - dwExtBlocks; + const UInt32 dwMainPages = dwMainBlocks * PAGES_PER_BLOCK; + const UInt32 dwMainDistrictMask = dwMainPages >> 2; + + const UInt32 dwDistrictMask = (dwMainPages > dwCpn) ? dwMainDistrictMask : dwExtDistrictMask; + + _Helper_ConvertC2P_OneBitReorder(dwCE, dwCpn, pdwBank, pdwPpn, dwDistrictMask); +} +#endif // #if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) +void _ConvertT2P_Default(UInt16 wBank, UInt16 wTbn, UInt16 *pwPbn) +{ + UInt32 dwCpn, dwCS; + // note that the naming conventions are messed up here + if (_pfnConvertP2C == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _pfnConvertP2C is not set (line:%d)!\n"), __LINE__)); + return; + } + _pfnConvertP2C((UInt32)wBank, (UInt32)(wTbn * PAGES_PER_BLOCK), &dwCS, &dwCpn); + *pwPbn = (UInt16)(dwCpn / PAGES_PER_BLOCK); +} + +// Note - this function return the bank offset with the CS (ast if the system as a single CS) +void _ConvertP2T_Default(UInt16 wPbn, UInt16 *pwBank, UInt16 *pwTbn) +{ + // note that the naming conventions are messed up here + UInt32 dwPpn, dwBank; + + // note that the naming conventions are messed up here + if (_pfnConvertC2P == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _pfnConvertC2P is not set (line:%d)!\n"), __LINE__)); + return; + } + _pfnConvertC2P((UInt32)0, (UInt32)(wPbn * PAGES_PER_BLOCK), &dwBank, &dwPpn); + *pwTbn = (UInt16)(dwPpn / PAGES_PER_BLOCK); + *pwBank = _Bank2CSBank((UInt16)dwBank); +} +#if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) +// Note - this function return the bank offset with the CS (ast if the system as a single CS) +void _ConvertP2T_ToshibaTwoDie(UInt16 wPbn, UInt16 *pwBank, UInt16 *pwTbn) +{ + // note that the naming conventions are messed up here + UInt32 dwPpn, dwBank; + + // note that the naming conventions are messed up here + if (_pfnConvertC2P == NULL) + { + VFL_ERR_PRINT((TEXT("[VFL:ERR] _pfnConvertC2P is not set (line:%d)!\n"), __LINE__)); + return; + } + _pfnConvertC2P((UInt32)0, (UInt32)(wPbn * BLOCK_STRIDE), &dwBank, &dwPpn); + *pwTbn = (UInt16)(dwPpn / BLOCK_STRIDE); + *pwBank = _Bank2CSBank((UInt16)dwBank); +} +#endif // #if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) +static BOOL32 _SetV2PFunctions(VendorSpecificType vendorSpecificType) +{ + switch (VS_GET_FMT(vendorSpecificType)) + { + default: + { + _ConvertP2T = _ConvertP2T_Default; + _ConvertT2P = _ConvertT2P_Default; + } + } + return TRUE32; +} + +#if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) +static BOOL32 _SetBankToCSConvertFunctionsOld(VendorSpecificType vendorSpecificType) +{ + switch (vendorSpecificType) + { + case FIL_VS_SIMPLE: + _pfnConvertP2C = _pfnConvert_Direct; + _pfnConvertC2P = _pfnConvert_Direct; + break; + + case FIL_VS_HYNIX_2P: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSB; + break; + + case FIL_VS_ONFI_2D: + _pfnConvertP2C = _pfnConvertP2C_TwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoDieMSB; + break; + + case FIL_VS_ONFI_2P: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSB; + break; + + case FIL_VS_ONFI_2P_2D: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSBTwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSBTwoDieMSB; + break; + + case FIL_VS_ONFI_2D_CACHE: + _pfnConvertP2C = _pfnConvertP2C_TwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoDieMSB; + break; + + case FIL_VS_ONFI_2P_CACHE: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSB; + break; + + case FIL_VS_ONFI_2P_2D_CACHE: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSBTwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSBTwoDieMSB; + break; + + case FIL_VS_SAMSUNG_2D: + _pfnConvertP2C = _pfnConvertP2C_TwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoDieMSB; + break; + + case FIL_VS_SAMSUNG_2P_2D: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSBTwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSBTwoDieMSB; + break; + + case FIL_VS_SAMSUNG_2P_2D_EXT: + _pfnConvertP2C = _pfnConvertP2C_TwoDie2_7bitPlaneNoPower2; + _pfnConvertC2P = _pfnConvertC2P_TwoDie2_7bitPlaneNoPower2; + break; + + case FIL_VS_TOSHIBA_2P: + _pfnConvertP2C = _pfnConvertP2C_ToshibaTwoDistrict; + _pfnConvertC2P = _pfnConvertC2P_ToshibaTwoDistrict; + break; + + case FIL_VS_TOSHIBA_2P_CACHE: + _pfnConvertP2C = _pfnConvertP2C_ToshibaTwoDistrict; + _pfnConvertC2P = _pfnConvertC2P_ToshibaTwoDistrict; + break; + + case FIL_VS_TOSHIBA_2P_EXT: + _pfnConvertP2C = _pfnConvertP2C_SingleDie_7bitPlaneNoPower2; + _pfnConvertC2P = _pfnConvertC2P_SingleDie_7bitPlaneNoPower2; + break; + + case FIL_VS_TOSHIBA_2P_EXT_CACHE: + _pfnConvertP2C = _pfnConvertP2C_ToshibaTwoDistrictExt; + _pfnConvertC2P = _pfnConvertC2P_ToshibaTwoDistrictExt; + break; + + default: + _pfnConvertP2C = _pfnConvert_Direct; + _pfnConvertC2P = _pfnConvert_Direct; + return FALSE32; + } + return TRUE32; +} +#endif // #if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) + +static BOOL32 _SetBankToCSConvertFunctions(VendorSpecificType vendorSpecificType) +{ +#if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) + void (*_pfnConvertP2CTemp)(UInt32 dwBank, UInt32 dwPpn, UInt32* pdwCE, UInt32* pdwCpn) = NULL; + void (*_pfnConvertC2PTemp)(UInt32 dwCE, UInt32 dwCpn, UInt32* pdwBank, UInt32* pdwPpn) = NULL; + _SetBankToCSConvertFunctionsOld(vendorSpecificType); + + _pfnConvertP2CTemp = _pfnConvertP2C; + _pfnConvertC2PTemp = _pfnConvertC2P; + + switch (VS_GET_FMT(vendorSpecificType)) + { + case VS_FMT_SIMPLE: + _pfnConvertP2C = _pfnConvert_Direct; + _pfnConvertC2P = _pfnConvert_Direct; + break; + + case VS_FMT_2BANKS_LSB: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSB; + break; + + case VS_FMT_2BANKS_MSB: + _pfnConvertP2C = _pfnConvertP2C_TwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoDieMSB; + break; + + case VS_FMT_4BANKS_LSB_MSB_NOPWR2: + _pfnConvertP2C = _pfnConvertP2C_TwoDie2_7bitPlaneNoPower2; + _pfnConvertC2P = _pfnConvertC2P_TwoDie2_7bitPlaneNoPower2; + break; + + case VS_FMT_4BANKS_LSB_MSB: + _pfnConvertP2C = _pfnConvertP2C_TwoPlaneLSBTwoDieMSB; + _pfnConvertC2P = _pfnConvertC2P_TwoPlaneLSBTwoDieMSB; + break; + + case VS_FMT_TOSHIBA_TWO_DISTRICT: + _pfnConvertP2C = _pfnConvertP2C_ToshibaTwoDistrict; + _pfnConvertC2P = _pfnConvertC2P_ToshibaTwoDistrict; + break; + + case VS_FMT_TOSHIBA_TWO_DISTRICT_EXT: + _pfnConvertP2C = _pfnConvertP2C_SingleDie_7bitPlaneNoPower2; + _pfnConvertC2P = _pfnConvertC2P_SingleDie_7bitPlaneNoPower2; + break; + + case VS_FMT_UNKNOWN: + default: + _pfnConvertP2C = _pfnConvert_Direct; + _pfnConvertC2P = _pfnConvert_Direct; + return FALSE32; + } + if (!(_pfnConvertP2CTemp == _pfnConvertP2C && + _pfnConvertC2PTemp == _pfnConvertC2P)) + { + VFL_ERR_PRINT((TEXT("Comparing old and new _SetBankToCSConvertFunctions failure (line:%d)!\n"), __LINE__)); + } +#else + _pfnConvertP2C = _pfnConvert_Direct; + _pfnConvertC2P = _pfnConvert_Direct; +#endif // #if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) + return TRUE32; +} + +#if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) +static UInt16 _GetBanksPerCSOld(VendorSpecificType vendorSpecificType) +{ + UInt16 wBanksPerCS = 0xFFFF; + + switch (vendorSpecificType) + { + case FIL_VS_SIMPLE: + wBanksPerCS = 1; + break; + + case FIL_VS_HYNIX_2P: + wBanksPerCS = 2; + break; + + case FIL_VS_ONFI_2D: + wBanksPerCS = 2; + break; + + case FIL_VS_ONFI_2P: + wBanksPerCS = 2; + break; + + case FIL_VS_ONFI_2P_2D: + wBanksPerCS = 4; + break; + + case FIL_VS_ONFI_2D_CACHE: + wBanksPerCS = 2; + break; + + case FIL_VS_ONFI_2P_CACHE: + wBanksPerCS = 2; + break; + + case FIL_VS_ONFI_2P_2D_CACHE: + wBanksPerCS = 4; + break; + + case FIL_VS_SAMSUNG_2P_2D: + wBanksPerCS = 4; + break; + + case FIL_VS_SAMSUNG_2D: + wBanksPerCS = 2; + break; + + case FIL_VS_TOSHIBA_2P: + wBanksPerCS = 2; + break; + + case FIL_VS_TOSHIBA_2D: + wBanksPerCS = 1; + break; + + case FIL_VS_TOSHIBA_2P_CACHE: + wBanksPerCS = 2; + break; + + case FIL_VS_TOSHIBA_2P_EXT: + wBanksPerCS = 2; + break; + + case FIL_VS_TOSHIBA_2P_EXT_CACHE: + wBanksPerCS = 2; + break; + + case FIL_VS_UNKNOWN: + default: + break; + } + return wBanksPerCS; +} +#endif // #if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) + +static UInt16 _GetBanksPerCS(VendorSpecificType vendorSpecificType) +{ +#if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) + UInt16 wBanksPerCS = 0xFFFF, wBanksPerCSOld; + + wBanksPerCSOld = _GetBanksPerCSOld(vendorSpecificType); + switch (VS_GET_FMT(vendorSpecificType)) + { + case VS_FMT_TOSHIBA_TWO_DIE: + case VS_FMT_SIMPLE: + wBanksPerCS = 1; + break; + + case VS_FMT_TOSHIBA_TWO_DISTRICT: + case VS_FMT_TOSHIBA_TWO_DISTRICT_EXT: + case VS_FMT_2BANKS_MSB: + case VS_FMT_2BANKS_LSB: + wBanksPerCS = 2; + break; + + case VS_FMT_4BANKS_LSB_MSB_NOPWR2: + case VS_FMT_4BANKS_LSB_MSB: + wBanksPerCS = 4; + break; + + case VS_FMT_UNKNOWN: + default: + break; + } + if (wBanksPerCSOld != wBanksPerCS) + { + VFL_ERR_PRINT((TEXT("Comparing old and new _GetBanksPerCS failure (line:%d)!\n"), __LINE__)); + } + return wBanksPerCS; +#else + return 1; +#endif // #if !(defined(AND_FORCE_VS_SIMPLE) && AND_FORCE_VS_SIMPLE) +} + +BOOL32 _GetFactoryBBTBuffer(void* pvoidStructBuffer, UInt32* pdwStructSize) +{ + UInt32 idx; + UInt16 wCS; + UInt8 *pabCursor = (UInt8*)pvoidStructBuffer; + const UInt32 dwOutputBufferSize = CS_TOTAL * BBT_SIZE_PER_CS; + + if (!pvoidStructBuffer && pdwStructSize) + { + *pdwStructSize = dwOutputBufferSize; + return TRUE32; + } + else if (!pvoidStructBuffer || !pdwStructSize || (*pdwStructSize < dwOutputBufferSize)) + { + return FALSE32; + } + + for (wCS = 0; wCS < CS_TOTAL; ++wCS) + { + if (!VFL_ReadBBTWithoutSpecial(wCS, pabCursor)) + { + return FALSE32; + } + + // Find VFL Meta blocks and set them to GOOD + for (idx = 0; + (idx < VFL_INFO_SECTION_SIZE) && (GET_VFLCxt(wCS)->awInfoBlk[idx] != VFL_INVALID_INFO_INDEX); + ++idx) + { + _MarkBlockAsGoodInBBT(pabCursor, GET_VFLCxt(wCS)->awInfoBlk[idx]); + } + + pabCursor += BBT_SIZE_PER_CS; + } + + *pdwStructSize = dwOutputBufferSize; + return TRUE32; +} diff --git a/drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLTypes.h b/drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLTypes.h new file mode 100644 index 0000000..cd1eb99 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Core/VFL/VSVFLTypes.h @@ -0,0 +1,218 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL types definition header */ +/* FILE : VFLTypes.h */ +/* PURPOSE : This header defines Data types which are shared */ +/* by all VFL submodules */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 04-AUG-2003 [HM Jung] : first writing */ +/* 14-JUL-2005 [Jaesung Jung] : reorganize code */ +/* 06-SEP-2005 [Jaesung Jung] : fix from code inspection */ +/* 24-JAN-2006 [Yangsup Lee ] : support un-pair bad block management */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ +#ifndef _VFL_TYPES_H_ +#define _VFL_TYPES_H_ + +#include "WMRConfig.h" + +typedef struct +{ + UInt16 wPagesPerBlock; /* the count of pages per block */ + UInt8 bRefreshThreshold; // number of bit flips beyond which we want to rewrite the page + UInt16 wNumOfCEs; + UInt16 wBlocksPerCS; /* the count of blocks per CS */ + UInt16 wBlocksPerBank; + UInt16 wBlocksPerDie; + UInt16 wDieStride; + UInt16 wBlockStride; + UInt16 wUserBlocksPerCS; + + // Info generated by CalcGlobal + UInt16 wPagesPerSuBlk; /* the count of pages per virtual block */ + UInt16 wBytesPerPage; /* bytes per page (main) */ + + UInt32 dwValidMetaPerLogicalPage; + UInt32 dwTotalMetaPerLogicalPage; + UInt32 dwLogicalPageSize; + + UInt16 wNumOfBank; /* the number of banks */ + UInt16 wNumOfBanksPerCS; + + UInt16 dwVFLAreaStart; /* the block number where VFL area starts */ + +} VSVFLWMRDeviceInfo; + +/*****************************************************************************/ +/* Global variables redefinitions (WMRLayout) */ +/*****************************************************************************/ +#define VFL_AREA_START (stVSVFLWMRDeviceInfo.dwVFLAreaStart) +#define VFL_FIRST_BLK_TO_SEARCH_CXT VFL_AREA_START +#define VFL_LAST_BLK_TO_SEARCH_CXT (VFL_AREA_START + 199) + +#define VFL_INFO_SECTION_START (VFL_AREA_START) +#define VFL_INFO_SECTION_SIZE (4) + +#define FIL_ECC_REFRESH_TRESHOLD (stVSVFLWMRDeviceInfo.bRefreshThreshold) + +#define VFL_RESERVED_SECTION_SIZE_CS (BLOCKS_PER_CS - (_GetNumOfSuBlks() * BANKS_PER_CS)) +#define VFL_RESERVED_SECTION_SIZE_BANK (BLOCKS_PER_BANK - _GetNumOfSuBlks()) + +#define BBT_SIZE_PER_CS ((BLOCKS_PER_CS / 8) + (BLOCKS_PER_CS % 8 ? 1 : 0)) +#if (defined(VFL_SMALL_ADDRESS_BUFFER) && VFL_SMALL_ADDRESS_BUFFER) +#define VSVFL_MAX_BANKS (4) +#else +#define VSVFL_MAX_PHYS_CS (16) +#define VSVFL_MAX_BANKS (VSVFL_MAX_PHYS_CS * AND_MAX_BANKS_PER_CS) /* the total maximum number of bank */ +#endif +#define VFL_SCRUB_LIST_SIZE (20) +#define FTL_FORMAT_STRUCT_SIZE (16) // packed +/*****************************************************************************/ +/* VFL context status(confirm) mark definition */ +/*****************************************************************************/ +#define PAGE_VALID (0x00) + +typedef struct +{ + UInt8 abNewFTLType[4]; + UInt8 abNewNumOfFTLSuBlk[2]; + UInt8 abReserved[9]; + UInt8 bFormatFTL; // 0 - false, 1 - format... +} FTLFormatType; + +/*****************************************************************************/ +/* Data structure for storing the VFL context definition */ +/*****************************************************************************/ +/* NOTICE !!! */ +/* this structure is used directly to load VFL context by WMR_MEMCPY*/ +/* so the byte pad of this structure must be 0 */ +typedef struct +{ + UInt32 dwGlobalCxtAge; /* age for FTL meta information search */ + UInt32 dwCxtAge; /* context age 0xFFFFFFFF --> 0x0 */ + UInt32 dwFTLType; /* FTL identifier */ + + UInt16 wCxtLocation; /* current context block location (Physical) */ + UInt16 wNextCxtPOffset; /* current context page offset information */ + + /* this data is used for summary */ + UInt16 wNumOfInitBadBlk; /* the number of initial bad blocks - used for VFL format */ + UInt16 wNumOfWriteFail; /* the number of failed write operations*/ + UInt16 wNumOfEraseFail; /* the number of failed erase operations */ + + /* bad blocks management table & good block pointer */ + UInt16 awReplacementIdx[AND_MAX_BANKS_PER_CS]; /* index to the last bad block updated in the awBadMapTable per bank + (some might be bad blocks) the array is divided to banks */ + UInt16 awBadMapTable[WMR_MAX_RESERVED_SIZE]; /* remapping table of bad blocks - the UInt 16 value set here is the virtual block (vfl address space) that is being replaced */ + + /* bad blocks management table within VFL info area */ + UInt16 awInfoBlk[VFL_INFO_SECTION_SIZE]; /* physical block addresses where FTL Cxt information is stored */ + + UInt16 wNumOfFTLSuBlk; /* the number of super blocks allocated for the FTL - default id to give all to FTL */ + UInt16 wNumOfVFLSuBlk; /* the total number of available super blocks */ + UInt16 awFTLCxtVbn[FTL_CXT_SECTION_SIZE]; /* page address (FTL virtual addressing space) of FTL Cxt */ + UInt16 wScrubIdx; /* Index for the scrub list */ + UInt16 awScrubList[VFL_SCRUB_LIST_SIZE]; /* scrub list */ + UInt8 abFTLFormat[FTL_FORMAT_STRUCT_SIZE]; + UInt8 abVSFormtType[4]; +} VFLCxt; + +/* VFLMeta size is 2048 bytes(4 sector) */ +#define VFL_META_VERSION 0x00000002 +typedef struct _VFLMeta +{ + VFLCxt stVFLCxt; + UInt8 abReserved[2048 - ((3 * sizeof(UInt32)) + sizeof(VFLCxt))]; + UInt32 dwVersion; + UInt32 dwCheckSum; + UInt32 dwXorSum; +} VFLMeta; + +/*****************************************************************************/ +/* Data structure for VFL context spare area */ +/*****************************************************************************/ +/* spare layout for SLC & MLC */ +typedef struct +{ + UInt32 dwCxtAge; /* context age 0xFFFFFFFF --> 0x0 */ + UInt32 dwReserved; /* reserved */ + UInt8 cStatusMark; /* status (confirm) mark - currently not used for anything */ + UInt8 bSpareType; /* spare type */ + /* reserved for main ECC */ +} VFLSpare; + +#define VFL_SPARE_TYPE_CXT 0x80 + +/*****************************************************************************/ +/* Asynchronous operation management structure & enum definition */ +/*****************************************************************************/ + +/* Device Information Structures and defines */ + +#define BBT_SIZE_PER_CS ((BLOCKS_PER_CS / 8) + (BLOCKS_PER_CS % 8 ? 1 : 0)) + +#define WMR_NUM_OF_ERASE_TRIALS_FOR_INDEX_BLOCKS (4) + +#define VFL_BLOCK_INDEX_MASK (0xFFFF) +#define VFL_INVALID_INFO_INDEX (0xFFFF) +#define VFL_BAD_MAP_TABLE_AVAILABLE_MARK (0xFFF0) +#define VFL_BAD_MAP_TABLE_STRESS_FAIL_MARK (0xFFFD) +#define VFL_BAD_MAP_TABLE_BORROW_MARK (0xFFFE) +#define VFL_BAD_MAP_TABLE_BAD_MARK (0xFFFF) + +#ifdef AND_COLLECT_STATISTICS +typedef struct +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwBlocksErasedCnt; + UInt64 ddwSingleWriteCallCnt; + UInt64 ddwSingleReadCallCnt; + UInt64 ddwSequetialReadCallCnt; + UInt64 ddwScatteredReadCallCnt; + UInt64 ddwMultipleWriteCallCnt; + UInt64 ddwEraseCallCnt; + UInt64 ddwEraseTimeoutFailCnt; + UInt64 ddwBurnInCode; +} VFLStatistics; + +#define VFL_STATISTICS_DESCREPTION { \ + "ddwPagesWrittenCnt", \ + "ddwPagesReadCnt", \ + "ddwBlocksErasedCnt", \ + "ddwSingleWriteCallCnt", \ + "ddwSingleReadCallCnt", \ + "ddwSequetialReadCallCnt", \ + "ddwScatteredReadCallCnt", \ + "ddwMultipleWriteCallCnt", \ + "ddwEraseCallCnt", \ + "ddwEraseTimeoutFailCnt", \ + "ddwBurnInCode", \ +} +#endif /* AND_COLLECT_STATISTICS */ + +#endif /* _VFL_TYPES_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Exam/ANDStats.c b/drivers/flash_nand/raw/Whimory/Exam/ANDStats.c new file mode 100644 index 0000000..f5b89f0 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Exam/ANDStats.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "ANDTypes.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "FPart.h" +#include "FPartTypes.h" +#include "WMRConfig.h" +#include "WMRExam.h" +#include "ANDStats.h" + +static VFLFunctions *stVflFunctions; +static FTLFunctions *stFtlFunctions; + +typedef BOOL32 (*GetStructFunc)(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); + +typedef struct { + UInt32 dwStructLayer; + UInt32 dwStructType; + UInt32 dwStructVersion; +} ExportStructParameters; + + +static ExportStructParameters astrStructsToExport[] = +{ + // header (must be first) + { 0, AND_STRUCT_WMR_EXPORT_ALL, AND_EXPORT_STRUCTURE_VERSION}, + + // WMR Version (FTL & VFL types) + {AND_STRUCT_LAYER_WMR, AND_STRUCT_WMR_VERSION, 0}, + + // VFL_type + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_GET_TYPE, 0}, + + // FTL_type ( FTL/yaFTL) + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_TYPE, 0}, + + // All VFL Meta + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 0, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 1, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 2, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 3, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 4, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 5, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 6, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 7, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 8, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 9, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 10, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 11, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 12, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 13, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 14, 0}, + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 15, 0}, + + //FTL geometry + {AND_STRUCT_LAYER_FTL,AND_STRUCT_FTL_GET_FTL_DEVICEINFO, 0}, + + // FTL + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_FTLCXT, 0}, + + // FTL counters + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_FTL_EC_BINS, 1}, + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_FTL_RC_BINS, 1}, + + // FTL - Stat + {AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_STATISTICS, 0}, + + // VFL - Stat + {AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_STATISTICS, 0}, + + // FIL - Device Info + {AND_STRUCT_LAYER_FIL, AND_STRUCT_FIL_DEVICE_INFO, 0}, + + // FIL - Stat + {AND_STRUCT_LAYER_FIL, AND_STRUCT_FIL_STATISTICS, 0}, + + // footer (must be last) + {0, AND_STRUCT_WMR_EXPORT_ALL_END, AND_EXPORT_STRUCTURE_VERSION}, + +}; + +#define AND_DUMP_DEBUG (0) + +#if AND_DUMP_DEBUG +#define DUMP_VAR(variable) WMR_PRINT(ALWAYS, "%s : %u\n", #variable, (UInt32)(variable)) + + +static void +hexdump(UInt8 *bytes, int count) +{ + int i, j; + + for (i = 0; i < count; i += 16) { + kprintf("%04x:", i); + for (j = 0; (j < 16) && ((i + j) < count); j++) + kprintf(" %02.2x", *bytes++); + kprintf("\n"); + } +} +#else +#define DUMP_VAR(variable) +#endif //AND_DUMP_DEBUG + + + +static GetStructFunc _translateStructLayer (UInt32 dwStructLayer) +{ + switch (dwStructLayer) + { + case AND_STRUCT_LAYER_FTL: + return stFtlFunctions->GetStruct; + case AND_STRUCT_LAYER_VFL: + return stVflFunctions->GetStruct; + case AND_STRUCT_LAYER_FIL: + return FIL_GetStruct; + case AND_STRUCT_LAYER_WMR: + return WMRGetStruct; + default: + return NULL; + } +} + + +static BOOL32 _appendStructToBuffer(void *pvoidExportBuffer, + UInt32 *pdwBufferSize, + UInt32 dwStructLayer, + UInt32 dwStructType, + UInt32 dwStructVersion) +{ + UInt32 dwDataSize; + BOOL32 boolResult; + GetStructFunc fGetStruct = _translateStructLayer(dwStructLayer); + UInt8 *cursor = (UInt8*) pvoidExportBuffer; + + + DUMP_VAR(pvoidExportBuffer); + if (pdwBufferSize) + { + DUMP_VAR(*pdwBufferSize); + } + DUMP_VAR(dwStructLayer); + DUMP_VAR(dwStructType); + DUMP_VAR(dwStructVersion); + + if (fGetStruct) + { + if (pvoidExportBuffer) + { + // leave room for the struct header + cursor += sizeof(ANDExportStruct); + } + dwDataSize = pdwBufferSize ? (*pdwBufferSize - sizeof(ANDExportStruct)) : 0; + boolResult = fGetStruct(dwStructType, cursor, &dwDataSize); + DUMP_VAR(dwDataSize); + } + else + { + // for header and footer + boolResult = TRUE32; + dwDataSize = 0; + } + + if (boolResult) + { +#if AND_DUMP_DEBUG + if (pvoidExportBuffer) + { + hexdump(pvoidExportBuffer, dwDataSize); + } +#endif + if (pdwBufferSize) + { + *pdwBufferSize = dwDataSize + sizeof(ANDExportStruct); + } + + if (pvoidExportBuffer) + { + ANDExportStruct strExport; + + strExport.dwStructID = dwStructType; + strExport.dwStructureVersion = dwStructVersion; + strExport.dwDataSize = dwDataSize; + strExport.dwIndex = 0; // What is this? + + WMR_MEMCPY(pvoidExportBuffer, &strExport, sizeof(ANDExportStruct)); + } + } + else if (pdwBufferSize) + { + *pdwBufferSize = 0; + } + + DUMP_VAR(boolResult); + return boolResult; +} + + + +#define SUB_MIN_ZERO(minuend, subtrahend) (((minuend) > (subtrahend)) ? ((minuend) - (subtrahend)) : 0) + +BOOL32 ANDExportAllStructs(void * pvoidDataBuffer, UInt32 * pdwDataSize) +{ + UInt32 idx; + ExportStructParameters *nextStruct; + const UInt32 dwNumStructures = sizeof(astrStructsToExport) / sizeof(astrStructsToExport[0]); + const UInt32 dwBufferSize = pdwDataSize ? *pdwDataSize : 0; + UInt8 *cursor = (UInt8*) pvoidDataBuffer; + UInt32 dwBufferRead = 0; + UInt32 dwTmpStructSize; + + if (!pdwDataSize) + { + return FALSE32; + } + + // Update globals + stVflFunctions = WMR_GetVFL(); + stFtlFunctions = WMR_GetFTL(); + + nextStruct = &astrStructsToExport[0]; + for (idx = 0; idx < dwNumStructures; ++idx) + { + dwTmpStructSize = SUB_MIN_ZERO(dwBufferSize, dwBufferRead); + _appendStructToBuffer(cursor, + &dwTmpStructSize, + nextStruct->dwStructLayer, + nextStruct->dwStructType, + nextStruct->dwStructVersion); + nextStruct++; + if (cursor) + { + cursor += dwTmpStructSize; + } + dwBufferRead += dwTmpStructSize; + } + + if (pdwDataSize) + { + *pdwDataSize = dwBufferRead; + } + + // pdwDataSize tells the whole story, always pass + return TRUE32; +} + diff --git a/drivers/flash_nand/raw/Whimory/Exam/ANDStats.h b/drivers/flash_nand/raw/Whimory/Exam/ANDStats.h new file mode 100644 index 0000000..1c48377 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Exam/ANDStats.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "WMRTypes.h" + +#ifndef _ANDSTATS_H_ +#define _ANDSTATS_H_ + +BOOL32 ANDExportAllStructs(void * pvoidDataBuffer, UInt32 * pdwDataSize); + +#endif //_ANDSTATS_H_ + + diff --git a/drivers/flash_nand/raw/Whimory/Exam/WMRExam.c b/drivers/flash_nand/raw/Whimory/Exam/WMRExam.c new file mode 100644 index 0000000..5734588 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Exam/WMRExam.c @@ -0,0 +1,1000 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Example */ +/* NAME : Example */ +/* FILE : WMRExam.c */ +/* PURPOSE : the example for whimory initialization */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 12-SEP-2005 [Jaesung Jung] : first writing */ +/* 15-MAR-2006 [Yangsup Lee ] : bad block detection bug fix */ +/* */ +/*****************************************************************************/ +#if (!defined(AND_FPART_ONLY) || !AND_FPART_ONLY) +#include "ANDTypes.h" +#include "WMRConfig.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "FPart.h" +#include "VFL.h" +#include "FTL.h" +#include "FIL.h" +#include "WMRExam.h" +#include "FPartTypes.h" +#include "ANDStats.h" +#include "WMRTest.h" +#else +#include "ANDTypes.h" +#include "WMRConfig.h" +#include "WMROAM.h" +#include "VFLBuffer.h" +#include "FPart.h" +#include "FIL.h" +#include "WMRExam.h" +#include "FPartTypes.h" +#endif + +/*****************************************************************************/ +/* Debug Print #defines */ +/*****************************************************************************/ +#define EXAM_INF_MSG_ON + +#define EXAM_ERR_PRINT(x) WMR_RTL_PRINT(x) +#define EXAM_RTL_PRINT(x) WMR_RTL_PRINT(x) + +#if defined (EXAM_LOG_MSG_ON) +#define EXAM_LOG_PRINT(x) WMR_DBG_PRINT(x) +#else +#define EXAM_LOG_PRINT(x) +#endif + +#if defined (EXAM_INF_MSG_ON) +#define EXAM_INF_PRINT(x) WMR_DBG_PRINT(x) +#else +#define EXAM_INF_PRINT(x) +#endif + +#if (!defined(AND_FPART_ONLY) || !AND_FPART_ONLY) +static ANDDriverSignature g_flashANDSignature; // Keep what was read from flash +static ANDDriverSignature g_scratchANDSignature; // For writing new signatures +static VFLFunctions stVflFunctions; +static FTLFunctions stFtlFunctions; +#endif +static FPartFunctions stFPartFunctions; +static BOOL32 boolFPartInitialized = FALSE32; + +/*****************************************************************************/ +/* Code Implementation */ +/*****************************************************************************/ + +static Int32 _initFPart(UInt32 dwFormatType, UInt32 dwBootAreaSize) +{ + UInt32 dwFPartOptions = 0; + Int32 nRet; + + if (FALSE32 == boolFPartInitialized) + { + WMR_MEMSET(&stFPartFunctions, 0, sizeof(FPartFunctions)); + FPart_Register(&stFPartFunctions); + dwFPartOptions = 0; + dwFPartOptions |= (dwFormatType & WMR_INIT_USE_DEV_UNIQUE_INFO) ? FPART_INIT_OPTION_DEV_UNIQUE : 0; + dwFPartOptions |= (dwFormatType & WMR_INIT_USE_DIAG_CTRL_INFO) ? FPART_INIT_OPTION_DIAG_CTRL : 0; + nRet = stFPartFunctions.Init(FIL_GetFuncTbl(), dwFPartOptions); + if (nRet != TRUE32) + { + return WMR_CRITICAL_ERROR; + } + boolFPartInitialized = TRUE32; + } + return WMR_SUCCESS; +} + +Int32 +WMR_PreInit(UInt32 dwFormatType, UInt32 dwBootAreaSize) +{ + Int32 nRet; + + OAM_Init(); + + nRet = FIL_Init(); + if (nRet != FIL_SUCCESS) + { + return WMR_CRITICAL_ERROR; + } + if (0 == FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS)) + { + EXAM_RTL_PRINT((TEXT("[FTL:MSG] No NAND attached\n"))); + return WMR_CRITICAL_ERROR; + } + + nRet = BUF_Init((UInt16)FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE), + BYTES_PER_METADATA_RAW, + WMR_NUM_BUFFERS); + if (nRet != BUF_SUCCESS) + { + return WMR_CRITICAL_ERROR; + } + + nRet = _initFPart(dwFormatType, dwBootAreaSize); + if (nRet != WMR_SUCCESS) + { + return WMR_CRITICAL_ERROR; + } + + return WMR_SUCCESS; +} + +FPartFunctions * WMR_GetFPart(void) +{ + return &stFPartFunctions; +} + +#if (!defined(AND_FPART_ONLY) || !AND_FPART_ONLY) + +static BOOL32 _isSignatureCompatible(ANDDriverSignature *pstSignature) +{ + const UInt8 bPlatform = WMR_SIGNATURE_PLATFORM(pstSignature->dwMainSignature); + const UInt8 bLayout = WMR_SIGNATURE_LAYOUT(pstSignature->dwMainSignature); + const UInt8 bVFLType = WMR_SIGNATURE_VFL(pstSignature->dwMainSignature); + const UInt32 dw2ndId = WMR_SIGNATURE_FORMATTING_VERSION(pstSignature->dw2ndId); + if ( WMR_PLATFORM_DARWIN != bPlatform) + { + return FALSE32; + } + + if ( (WMR_LAYOUT_SIMPLE != bLayout) && (WMR_LAYOUT_VS != bLayout) ) + { + return FALSE32; + } + + if ( (WMR_M68_VFL != bVFLType) && (WMR_VSVFL != bVFLType) ) + { + return FALSE32; + } + + // Only VS layout supports 2ndID field + if ((WMR_LAYOUT_VS == bLayout) && (dw2ndId > WMR_FORMATTING_VERSION)) + { + return FALSE32; + } + + return TRUE32; +} + +static BOOL32 _selectVFL(BOOL32 boolSignatureFound, + BOOL32 boolAllowVSVFL, + BOOL32 boolSignInBlockZero, + ANDDriverSignature * pOldANDDriverSignature, + ANDDriverSignature * pNewANDDriverSignature) +{ + // decide what VFL to use + if (((boolSignatureFound == TRUE32) && + WMR_SIGNATURE_VFL(pOldANDDriverSignature->dwMainSignature) == WMR_VSVFL) +#ifndef AND_READONLY + || ((boolSignatureFound == FALSE32) && (boolAllowVSVFL == TRUE32)) +#endif + ) + + { + VSVFL_Register(&stVflFunctions); + pNewANDDriverSignature->dwMainSignature = WMR_VSVFL_VS_SIGNATURE; + EXAM_RTL_PRINT((TEXT("[FTL:MSG] VSVFL Register [OK]\n"))); + if (boolSignInBlockZero == FALSE32) + { + stFPartFunctions.SetSignatureStyle(&stFPartFunctions, SIGNATURE_STYLE_RESERVEDBLOCK_HEADER); + } + else + { + EXAM_ERR_PRINT((TEXT("[WMR:ERR] Signature Style RESERVEDBLOCK HEADER has to be used with VSVFL formatting.\n"))); + return FALSE32; + } + if ((WMR_SIGNATURE_METADATA(pOldANDDriverSignature->dw2ndId) == WMR_METADATA_WHITENING)) + { + if (FIL_GetFuncTbl()->SetWhiteningMetadataState) + { + EXAM_RTL_PRINT((TEXT("[WMR:MSG] Metadata whitening is set in NAND signature\n"))); + FIL_GetFuncTbl()->SetWhiteningMetadataState(TRUE32); + } + else + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] Metadata whitening not supported.\n"))); + return FALSE32; + } + } + else if (FIL_GetFuncTbl()->SetWhiteningMetadataState) + { + FIL_GetFuncTbl()->SetWhiteningMetadataState(FALSE32); + } + } + else if (((boolSignatureFound == TRUE32) && + WMR_SIGNATURE_VFL(pOldANDDriverSignature->dwMainSignature) == WMR_M68_VFL) +#ifndef AND_READONLY + || ((boolSignatureFound == FALSE32) && (boolAllowVSVFL == FALSE32)) +#endif + ) + { +#if AND_SUPPORT_LEGACY_VFL + VFL_Register(&stVflFunctions); + pNewANDDriverSignature->dwMainSignature = WMR_VFL_SIGNATURE; + EXAM_RTL_PRINT((TEXT("[FTL:MSG] VFL Register [OK]\n"))); + if (boolSignInBlockZero == TRUE32) + { + stFPartFunctions.SetSignatureStyle(&stFPartFunctions, SIGNATURE_STYLE_BLOCKZERO_NOHEADER); + } + else + { + EXAM_ERR_PRINT((TEXT("[WMR:ERR] Signature Style BLOCKZERO NOHEADER has to be used with VFL formatting.\n"))); + return FALSE32; + } +#else + EXAM_ERR_PRINT((TEXT("[FTL:ERR] Legacy VFL is not supported - init fail\n"))); + return FALSE32; +#endif + } + else + { + EXAM_ERR_PRINT((TEXT("[WMR:ERR] No Valid VFL type found main signature 0x%08X\n"), + pOldANDDriverSignature->dwMainSignature)); + return FALSE32; + } + return TRUE32; +} + +/*****************************************************************************/ +/* */ +/* NAME */ +/* WMR_Init */ +/* DESCRIPTION */ +/* This function inits whimory & format & open. */ +/* PARAMETERS */ +/* pTotalScts [OUT] the count of sectors which user can use. */ +/* RETURN VALUES */ +/* WMR_SUCCESS */ +/* FTL_Open is completed */ +/* WMR_CRITICAL_ERROR */ +/* FTL_Open is failed */ +/* WMR_UNRECOVERABLE_ERROR */ +/* Open failed but we can possibly read syscfg */ +/* NOTES */ +/* */ +/*****************************************************************************/ +Int32 +WMR_Init(UInt32 *pTotalScts, UInt32 * pdwSectorSize, UInt32 * tmpIndexCache, UInt32 dwFormatType, UInt32 dwBootAreaSize) +{ + Int32 nRet; + BOOL32 boolSignatureFound = FALSE32; + volatile BOOL32 boolProductionFormatVerified = TRUE32; + static UInt32 alreadyCalled = 0; + BOOL32 boolFTLRegistered = FALSE32; + BOOL32 boolSignInBlockZero = (dwFormatType & WMR_INIT_SIGNATURE_IN_BLOCKZERO ? TRUE32 : FALSE32); + BOOL32 nandFullRestore = (dwFormatType & WMR_INIT_NAND_RESTORE ? TRUE32 : FALSE32); + UInt32 ftlOpenOptions = 0; +#if (defined(AND_LOW_POWER_MOUNT) && AND_LOW_POWER_MOUNT) + UInt32 dwInitPowerMode = (dwFormatType & WMR_INIT_LOW_POWER_MODE) ? NAND_POWER_MODE_SINGLE_CE : NAND_POWER_MODE_FULL_SPEED; +#endif + BOOL32 boolAllowVSVFL = (dwFormatType & WMR_INIT_ALLOW_VSVFL ? TRUE32 : FALSE32); + BOOL32 boolMetadataWhitening = (dwFormatType & WMR_INIT_METADATA_WHITENING ? TRUE32 : FALSE32); + BOOL32 boolMetadataWhiteningCheck = (dwFormatType & WMR_INIT_METADATA_WHITENING_CHECK ? TRUE32 : FALSE32); + +#ifndef AND_READONLY + BOOL32 boolStatus; + BOOL32 boolProductionFormatCompleted = FALSE32; + BOOL32 bFormatAllowed = (dwFormatType & WMR_INIT_ALLOW_FORMAT ? TRUE32 : FALSE32); + BOOL32 boolAllowYAFTL = (dwFormatType & WMR_INIT_ALLOW_YAFTL ? TRUE32 : FALSE32); + BOOL32 boolRunProductionReformat = (dwFormatType & WMR_INIT_RUN_PRODUCTION_FORMAT ? TRUE32 : FALSE32); + BOOL32 boolRunFTLFormat = (dwFormatType & WMR_INIT_RUN_FTL_FORMAT ? TRUE32 : FALSE32); + WMR_ASSERT(!(boolRunFTLFormat && boolRunProductionReformat)); +#endif + + // make sure we init the functions + WMR_MEMSET(&stVflFunctions, 0, sizeof(VFLFunctions)); + WMR_MEMSET(&stFtlFunctions, 0, sizeof(FTLFunctions)); + + WMR_MEMSET(&g_flashANDSignature, 0, sizeof(ANDDriverSignature)); + WMR_MEMSET(&g_scratchANDSignature, 0, sizeof(ANDDriverSignature)); + + OAM_Init(); + +#ifdef AND_READONLY + EXAM_RTL_PRINT((TEXT("[FTL:MSG] Apple NAND Driver (AND) RO\n"))); +#else + EXAM_RTL_PRINT((TEXT("[FTL:MSG] Apple NAND Driver (AND) RW\n"))); +#endif + if (alreadyCalled) + { + EXAM_ERR_PRINT((TEXT("[WMR:ERR] WMR_Init already called!\n"))); + } + + alreadyCalled++; + + nRet = FIL_Init(); + + if (nRet != FIL_SUCCESS) + { + return WMR_CRITICAL_ERROR; + } +#if (defined(AND_LOW_POWER_MOUNT) && AND_LOW_POWER_MOUNT) + FIL_SetStruct(AND_STRUCT_FIL_POWER_MODE, &dwInitPowerMode, sizeof(UInt32)); +#endif + + EXAM_RTL_PRINT((TEXT("[FTL:MSG] FIL_Init [OK]\n"))); + if (0 == FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS)) { + EXAM_RTL_PRINT((TEXT("[FTL:MSG] No NAND attached\n"))); + return WMR_CRITICAL_ERROR; + } +#if defined(WMR_UNIT_TEST_ENABLED) && WMR_UNIT_TEST_ENABLED + if (!FIL_Test()) + { + return WMR_CRITICAL_ERROR; + } +#endif /* FIL_TEST_ENABLED */ + + nRet = BUF_Init((UInt16)FIL_GetFuncTbl()->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE), BYTES_PER_METADATA_RAW, WMR_NUM_BUFFERS); + + if (nRet != BUF_SUCCESS) + { + return WMR_CRITICAL_ERROR; + } + + EXAM_RTL_PRINT((TEXT("[FTL:MSG] BUF_Init [OK]\n"))); + + nRet = _initFPart(dwFormatType, dwBootAreaSize); + if (nRet != WMR_SUCCESS) + { + return WMR_CRITICAL_ERROR; + } + EXAM_RTL_PRINT((TEXT("[FTL:MSG] FPart Init [OK]\n"))); + + /* signature searching */ + // try old style signature first (quicker) + + if (boolSignInBlockZero == TRUE32) + { + stFPartFunctions.SetSignatureStyle(&stFPartFunctions, SIGNATURE_STYLE_BLOCKZERO_NOHEADER); + } + else + { + stFPartFunctions.SetSignatureStyle(&stFPartFunctions, SIGNATURE_STYLE_RESERVEDBLOCK_HEADER); + } + + if (stFPartFunctions.ReadSignature(&g_flashANDSignature, sizeof(ANDDriverSignature))) + { + if (boolSignInBlockZero == TRUE32) + { + EXAM_RTL_PRINT((TEXT("read old style signature 0x%08X (line:%d)\n"), g_flashANDSignature.dwMainSignature, __LINE__)); + } + else + { + EXAM_RTL_PRINT((TEXT("read new style signature 0x%08X (line:%d)\n"), g_flashANDSignature.dwMainSignature, __LINE__)); + } + + if (_isSignatureCompatible(&g_flashANDSignature)) + { + boolSignatureFound = TRUE32; +#ifndef AND_READONLY + if (boolRunProductionReformat == TRUE32) + { + stFPartFunctions.WriteSignature(NULL, 0); + } +#endif + if (boolMetadataWhiteningCheck) + { + BOOL32 boolSignatureHasMetadataWhitening = (WMR_SIGNATURE_METADATA(g_flashANDSignature.dw2ndId) == WMR_METADATA_WHITENING); + if ( (boolSignatureHasMetadataWhitening == TRUE32 && boolMetadataWhitening == FALSE32) + || (boolSignatureHasMetadataWhitening == FALSE32 && boolMetadataWhitening == TRUE32)) + { +#ifndef AND_READONLY + stFPartFunctions.WriteSignature(NULL, 0); +#endif + EXAM_RTL_PRINT((TEXT("[FTL:ERR] metadata whitening mismatch, please reformat\n"))); + return WMR_UNRECOVERABLE_ERROR; + } + } + } + else + { + EXAM_RTL_PRINT((TEXT("[FTL:WRN] Incompatible Signature!\n"))); + } + } + + /* + * If we have been instructed to run a production reformat, force it by faking a signature + * mismatch + */ +#ifndef AND_READONLY + if (boolRunProductionReformat) + { + boolSignatureFound = FALSE32; + } +#endif // ! AND_READONLY + + /* + * If any of the basic criteria are violated, we are going to have to reformat. + * If this isn't permitted, print a diagnoistic and bail out. + */ + if (!boolSignatureFound) + { + /* + * Verify that we can read the BBT from all banks. + */ +#ifndef AND_READONLY + if (!bFormatAllowed) +#endif + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] NAND format invalid (mismatch, corrupt, read error or blank NAND device)\n"))); + EXAM_RTL_PRINT((TEXT("[WMR:ERR] boolSignatureFound %s boolProductionFormatVerified %s nSig 0x%x\n"), + boolSignatureFound ? "true" : "false", + boolProductionFormatVerified ? "true" : "false", + g_flashANDSignature.dwMainSignature)); + goto fail_readonly; + } +#ifndef AND_READONLY + boolProductionFormatVerified = stFPartFunctions.VerifyProductionFormat(); +#ifdef AND_USE_NOTIFY + /* one or more of the failed criteria will require a reformat operation */ + FIL_GetFuncTbl()->Notify(AND_NOTIFY_REFORMAT); +#endif +#endif //!AND_READONLY + } + + // decide what VFL to use + if (FALSE32 == _selectVFL(boolSignatureFound, boolAllowVSVFL, + boolSignInBlockZero, &g_flashANDSignature, &g_scratchANDSignature)) + { + return WMR_UNRECOVERABLE_ERROR; + } + nRet = stVflFunctions.Init(&stFPartFunctions); + + if (nRet != VFL_SUCCESS) + { + return WMR_UNRECOVERABLE_ERROR; + } + EXAM_RTL_PRINT((TEXT("[FTL:MSG] VFL Init [OK]\n"))); + +#ifndef AND_READONLY + /* + * If we couldn't find the BBT, or the signature is missing (or we are pretending it's missing), + * we need to think about (re)formatting. + */ + if (boolProductionFormatVerified != TRUE32 || boolSignatureFound != TRUE32) + { + Int32 nRetTemp; + if (boolMetadataWhitening) + { + if (FIL_GetFuncTbl()->SetWhiteningMetadataState) + { + EXAM_RTL_PRINT((TEXT("[WMR:INF] Formatting with metadata whitening\n"))); + FIL_GetFuncTbl()->SetWhiteningMetadataState(TRUE32); + } + else + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] Metadata whitening unavailable!\n"))); + return WMR_UNRECOVERABLE_ERROR; + } + } + if (boolProductionFormatVerified == FALSE32) + { + // this is a either virgin device or a device that went through + // power failure during initial format. We have to scan for + // the initial bad blocks and save them as a factory bad-block table. + EXAM_RTL_PRINT((TEXT("[WMR:INF] Calling VFL_ProductionFormat()\n"))); + if (stFPartFunctions.WriteInitialBBT() != TRUE32) + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] Failed VFL_ProductionFormat\n"))); + return WMR_UNRECOVERABLE_ERROR; + } + EXAM_RTL_PRINT((TEXT("[WMR:MSG] Production Format OK!\n"))); + boolProductionFormatCompleted = TRUE32; + } + + if (boolProductionFormatCompleted == FALSE32) + { + EXAM_RTL_PRINT((TEXT("[FTL:MSG] Calling VFL_FactoryReformat()\n"))); + // erase signature before clearing the NAND + stFPartFunctions.WriteSignature(NULL, 0); + stFPartFunctions.FactoryReformat(FALSE32, FALSE32, dwBootAreaSize); + } + + nRetTemp = stVflFunctions.Format(dwBootAreaSize, 0); + + if (nRetTemp != VFL_SUCCESS) + { + return WMR_UNRECOVERABLE_ERROR; + } + + EXAM_RTL_PRINT((TEXT("[FTL:MSG] VFL_Format [OK]\n"))); + + // check if we need a shrinked FTL partition + if ((*pTotalScts) && (*pdwSectorSize)) + { + UInt32 dwPageSize, dwPagesPerSuBlks; + UInt16 wNewFTLSuBlkCnt; + UInt32 dwRequestedPages; + + dwPagesPerSuBlks = (UInt16)stVflFunctions.GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + dwPageSize = (UInt16)stVflFunctions.GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + + dwRequestedPages = (*pTotalScts) * ((*pdwSectorSize) / dwPageSize); + + wNewFTLSuBlkCnt = (UInt16)((UInt32)(110 * dwRequestedPages) / + (dwPagesPerSuBlks * 100)) + 23; + + stVflFunctions.SetStruct(AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS, &wNewFTLSuBlkCnt, sizeof(UInt16)); + } + + // choose the FTL we want to use and init it + if (boolAllowYAFTL == TRUE32) + { +#if (defined (AND_SUPPORT_YAFTL) && AND_SUPPORT_YAFTL) + YAFTL_Register(&stFtlFunctions); + EXAM_RTL_PRINT((TEXT("[FTL:MSG] YAFTL Register [OK]\n"))); +#else + EXAM_RTL_PRINT((TEXT("[FTL:ERR] YAFTL is not supported - init fail\n"))); + return WMR_UNRECOVERABLE_ERROR; +#endif + } + else + { +#if AND_SUPPORT_LEGACY_FTL + EXAM_RTL_PRINT((TEXT("[FTL:MSG] FTL Register [OK]\n"))); + FTL_Register(&stFtlFunctions); +#else + EXAM_RTL_PRINT((TEXT("[FTL:ERR] Legacy FTL is not supported - init fail\n"))); + return WMR_UNRECOVERABLE_ERROR; +#endif + } + boolFTLRegistered = TRUE32; + nRetTemp = stFtlFunctions.Init(&stVflFunctions); + if (nRetTemp != FTL_SUCCESS) + { + EXAM_RTL_PRINT((TEXT("[FTL:ERR] FTL failed Init\n"))); + return WMR_UNRECOVERABLE_ERROR; + } + EXAM_RTL_PRINT((TEXT("[FTL:MSG] FTL Init [OK]\n"))); + nRetTemp = stFtlFunctions.Format(0); + if (nRetTemp != FTL_SUCCESS) + { + EXAM_RTL_PRINT((TEXT("[FTL:ERR] FTL failed Formatting\n"))); + return WMR_UNRECOVERABLE_ERROR; + } + EXAM_RTL_PRINT((TEXT("[FTL:MSG] FTL Format [OK]\n"))); + + /* full reformat, write normal signature */ + // Main signature is set from _selectVFL + g_scratchANDSignature.dw2ndId = WMR_FORMATTING_VERSION; + // determine if metadata whitening is needed based on signature + if (boolMetadataWhitening) + { + g_scratchANDSignature.dw2ndId |= WMR_METADATA_SIGNATURE; + } + /* 5249095 - this should write FTL build info, not kernel version */ + WMR_MEMSET(g_scratchANDSignature.strBuildInfo, 0, WMR_MAX_STR_BUILD_SIZE); + WMR_MEMCPY(g_scratchANDSignature.strBuildInfo, WMR_GETVERSION(), + WMR_MIN(WMR_STRLEN(WMR_GETVERSION()), (WMR_MAX_STR_BUILD_SIZE - 1))); + boolStatus = stFPartFunctions.WriteSignature(&g_scratchANDSignature, sizeof(ANDDriverSignature)); + if (boolStatus) + { + WMR_MEMCPY(&g_flashANDSignature, &g_scratchANDSignature, sizeof(ANDDriverSignature)); + } + else + { + EXAM_RTL_PRINT((TEXT("[FTL:MSG] Write Signature Failed 0x%08X\n"), g_flashANDSignature.dwMainSignature)); + return WMR_CRITICAL_ERROR; + } + + EXAM_RTL_PRINT((TEXT("[FTL:MSG] Write Signature OK 0x%08X\n"), g_flashANDSignature.dwMainSignature)); + { + WMR_MEMSET(&g_scratchANDSignature, 0, sizeof(ANDDriverSignature)); + boolStatus = stFPartFunctions.ReadSignature(&g_scratchANDSignature, sizeof(ANDDriverSignature)); + if (!boolStatus || WMR_MEMCMP(&g_scratchANDSignature, &g_flashANDSignature, sizeof(ANDDriverSignature))) + { + EXAM_RTL_PRINT((TEXT("[FTL:MSG] Read back Signature Failed 0x%08X\n"), g_scratchANDSignature.dwMainSignature)); + return WMR_CRITICAL_ERROR; + } + else + { + EXAM_RTL_PRINT((TEXT("[FTL:MSG] Read back Signature OK\n"))); + } + } + } +#endif // ! AND_READONLY + nRet = stVflFunctions.Open(dwBootAreaSize, 0, 0); + + if (nRet != VFL_SUCCESS) + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] VFL_Open failed\n"))); + WMR_BEEP(1000000); + return WMR_UNRECOVERABLE_ERROR; + } + + EXAM_RTL_PRINT((TEXT("[FTL:MSG] VFL_Open [OK]\n"))); + + if (boolFTLRegistered == FALSE32) + { +#ifndef AND_READONLY + // Check if we wanted to reformat FTL... + if (boolRunFTLFormat) + { + // change the FTL size inside the vfl and mark the FTL + // for format + if ((*pTotalScts) && (*pdwSectorSize)) + { + UInt32 dwPageSize, dwPagesPerSuBlks; + UInt16 wNewFTLSuBlkCnt; + UInt32 dwRequestedPages; + + dwPagesPerSuBlks = (UInt16)stVflFunctions.GetDeviceInfo(AND_DEVINFO_PAGES_PER_SUBLK); + dwPageSize = (UInt16)stVflFunctions.GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + + dwRequestedPages = (*pTotalScts) * ((*pdwSectorSize) / dwPageSize); + + wNewFTLSuBlkCnt = (UInt16)((UInt32)(110 * dwRequestedPages) / + (dwPagesPerSuBlks * 100)) + 23; + stVflFunctions.SetStruct(AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS, &wNewFTLSuBlkCnt, sizeof(UInt16)); + } + else + { + UInt16 wNewFTLSuBlkCnt; + UInt32 dwSize = sizeof(wNewFTLSuBlkCnt); + stVflFunctions.GetStruct(AND_STRUCT_VFL_NUM_OF_SUBLKS, &wNewFTLSuBlkCnt, &dwSize); + stVflFunctions.SetStruct(AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS, &wNewFTLSuBlkCnt, sizeof(UInt16)); + } + } +#endif + + // check what FTL to use here + if (stVflFunctions.GetDeviceInfo(AND_DEVINFO_FTL_TYPE) == FTL_TYPE_YAFTL) + { +#if (defined (AND_SUPPORT_YAFTL) && AND_SUPPORT_YAFTL) + YAFTL_Register(&stFtlFunctions); + EXAM_RTL_PRINT((TEXT("[FTL:MSG] YAFTL Register [OK]\n"))); +#else + EXAM_RTL_PRINT((TEXT("[FTL:ERR] YAFTL is not supported - init fail\n"))); + return WMR_UNRECOVERABLE_ERROR; +#endif + } + else + { +#if AND_SUPPORT_LEGACY_FTL + EXAM_RTL_PRINT((TEXT("[FTL:MSG] FTL Register [OK]\n"))); + FTL_Register(&stFtlFunctions); +#else + EXAM_RTL_PRINT((TEXT("[FTL:ERR] Legacy FTL is not supported - init fail\n"))); + return WMR_UNRECOVERABLE_ERROR; +#endif + } + nRet = stFtlFunctions.Init(&stVflFunctions); + if (nRet != FTL_SUCCESS) + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] FTL Init Fail\n"))); + return WMR_UNRECOVERABLE_ERROR; + } +#ifndef AND_READONLY + if (stVflFunctions.GetDeviceInfo(AND_DEVINFO_FTL_NEED_FORMAT) || + (boolRunFTLFormat == TRUE32)) + { + nRet = stFtlFunctions.Format(0); + if (nRet != FTL_SUCCESS) + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] FTL ReFormat Fail\n"))); + return WMR_UNRECOVERABLE_ERROR; + } + } +#endif + } + + if ((dwFormatType & WMR_INIT_DISABLE_GC_IN_TRIM) == WMR_INIT_DISABLE_GC_IN_TRIM) + { + EXAM_RTL_PRINT((TEXT("FTL_Open will get trim GC disabled settings \n"))); + ftlOpenOptions |= WMR_INIT_DISABLE_GC_IN_TRIM; + } + + if ((dwFormatType & WMR_INIT_SET_INDEX_CACHE_SIZE) == WMR_INIT_SET_INDEX_CACHE_SIZE) + { + EXAM_RTL_PRINT((TEXT("FTL_Open will set index cache to 0x%x \n"),*tmpIndexCache)); + ftlOpenOptions |= WMR_INIT_SET_INDEX_CACHE_SIZE; + ftlOpenOptions |= ((*tmpIndexCache) << 20); + } + + if ( WMR_INIT_OPEN_READONLY == (dwFormatType & WMR_INIT_OPEN_READONLY) ) + { + ftlOpenOptions |= WMR_INIT_OPEN_READONLY; + } + nRet = stFtlFunctions.Open(pTotalScts, pdwSectorSize, nandFullRestore, FALSE32, 0, ftlOpenOptions); + if (nRet != FTL_SUCCESS) + { +#ifdef WMR_ERASE_UNIT_WHEN_OPEN_FAIL + if (!bFormatAllowed) + { + EXAM_RTL_PRINT((TEXT("[WMR:ERR] FTL_Open failed\n"), + nSig, WMR_SIGNATURE)); + goto fail_readonly; + } + + EXAM_RTL_PRINT((TEXT("[WMR:ERR] FTL_Open failed - erasing block 0\n"))); + pLowFuncTbl->Erase(0, 0); +#else + EXAM_RTL_PRINT((TEXT("[WMR:ERR] FTL_Open failed\n"))); + WMR_BEEP(1000000); +#endif + return WMR_UNRECOVERABLE_ERROR; + } + EXAM_RTL_PRINT((TEXT("[FTL:MSG] FTL_Open [OK]\n"))); + + return WMR_SUCCESS; + + fail_readonly: + EXAM_RTL_PRINT((TEXT("******************************************************************************\n"))); + EXAM_RTL_PRINT((TEXT("******************************************************************************\n"))); + EXAM_RTL_PRINT((TEXT("AND: NAND initialisation failed due to format mismatch or uninitialised NAND.\n"))); + EXAM_RTL_PRINT((TEXT("AND: Please reboot with reformatting enabled.\n"))); + EXAM_RTL_PRINT((TEXT("******************************************************************************\n"))); + EXAM_RTL_PRINT((TEXT("******************************************************************************\n"))); + + return WMR_UNRECOVERABLE_ERROR; +} + +BOOL32 WMRGetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + switch(dwStructType) + { + case AND_STRUCT_WMR_VERSION: + { + UInt32 dwSignature = g_flashANDSignature.dwMainSignature; + boolRes = WMR_FILL_STRUCT(pvoidStructBuffer, pdwStructSize, &dwSignature, sizeof(dwSignature)); + break; + } + default: + EXAM_ERR_PRINT((TEXT("[WMR:ERR] WMRGetStruct 0x%X is not identified is WMR data struct identifier!\n"), dwStructType)); + boolRes = FALSE32; + } + return boolRes; +} + + +static BOOL32 _andGetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + BOOL32 boolRes = FALSE32; + + if (dwStructType == LOCKDOWN_EXTRACT_ALL) + { + // Mobile Lockdown - Get All Structures +#if AND_COLLECT_STATISTICS + boolRes = ANDExportAllStructs(pvoidStructBuffer, pdwStructSize); +#endif + } + else if (dwStructType == LOCKDOWN_GET_ALL_SIZE) + { +#if AND_COLLECT_STATISTICS + UInt32 *dwAllSize = (UInt32*) pvoidStructBuffer; + if (dwAllSize && pdwStructSize && (*pdwStructSize >= sizeof(UInt32))) + { + // Mobile Lockdown - Get Size + boolRes = ANDExportAllStructs(NULL, dwAllSize); + *pdwStructSize = sizeof(UInt32); + } + else + { + boolRes = FALSE32; + } +#endif + } + else + { + switch (dwStructType & AND_STRUCT_LAYER_MASK) + { + case AND_STRUCT_LAYER_FTL: + { + boolRes = stFtlFunctions.GetStruct(dwStructType, pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_LAYER_VFL: + { + boolRes = stVflFunctions.GetStruct(dwStructType, pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_LAYER_FIL: + { + boolRes = FIL_GetStruct(dwStructType, pvoidStructBuffer, pdwStructSize); + break; + } + + case AND_STRUCT_LAYER_GETALL: + { +#if AND_COLLECT_STATISTICS + if (dwStructType == AND_STRUCT_WMR_EXPORT_ALL) + { + boolRes = ANDExportAllStructs(pvoidStructBuffer, pdwStructSize); + } + else if (dwStructType == AND_STRUCT_WMR_EXPORT_ALL_GET_SIZE) + { + UInt32 *dwStructSizeVal = (UInt32*) pvoidStructBuffer; + if (dwStructSizeVal && pdwStructSize && (*pdwStructSize >= sizeof(UInt32))) + { + boolRes = ANDExportAllStructs(NULL, dwStructSizeVal); + *pdwStructSize = sizeof(UInt32); + } + } +#endif + break; + } + default: + { + EXAM_ERR_PRINT((TEXT("[WMR:ERR] _andGetStruct 0x%X is not identified !\n"), dwStructType)); + boolRes = FALSE32; + break; + } + } + } + + return boolRes; +} + +static BOOL32 _andPerformFunction(UInt32 dwFunctionSelector, void * pvoidStructBuffer, UInt32 * pdwStructSize) +{ + switch (dwFunctionSelector) + { +#ifndef AND_READONLY + + case _AND_FUNCTION_COMPLETE_EPOCH_UPDATE: + { + WMR_PRINT(ERROR, "Epoch update is deprecated\n"); + return FALSE32; + } + + case AND_FUNCTION_INDEX_CACHE_UPDATE: + { + BOOL32 boolRes = FALSE32; + if (stFtlFunctions.GetStruct && pdwStructSize) + { + boolRes = stFtlFunctions.GetStruct(dwFunctionSelector, NULL, pdwStructSize); + *pdwStructSize = 0; + } + return boolRes; + } + + case AND_FUNCTION_CHANGE_FTL_TYPE: + { + BOOL32 boolRes = FALSE32; + if (stVflFunctions.SetStruct && pdwStructSize) + { + boolRes = stVflFunctions.SetStruct(AND_STRUCT_VFL_NEW_FTLTYPE, pvoidStructBuffer, *pdwStructSize); + } + return boolRes; + } + + case AND_FUNCTION_CHANGE_NUM_OF_SUBLKS: + { + BOOL32 boolRes = FALSE32; + if (stVflFunctions.SetStruct && pdwStructSize) + { + boolRes = stVflFunctions.SetStruct(AND_STRUCT_VFL_NEW_NUM_OF_FTL_SUBLKS, pvoidStructBuffer, *pdwStructSize); + } + return boolRes; + } + + case AND_FUNCTION_SET_BURNIN_CODE: + { + BOOL32 boolRes = FALSE32; + if (stVflFunctions.SetStruct && pdwStructSize) + { + boolRes = stVflFunctions.SetStruct(AND_STRUCT_VFL_BURNIN_CODE, pvoidStructBuffer, *pdwStructSize); + } + return boolRes; + } + + case AND_FUNCTION_ERASE_SIGNATURE: + { + BOOL32 boolRes; + WMR_MEMSET(&g_flashANDSignature, 0, sizeof(ANDDriverSignature)); + boolRes = stFPartFunctions.WriteSignature(&g_flashANDSignature, sizeof(ANDDriverSignature)); + return boolRes; + } + + case AND_FUNCTION_SET_POWER_MODE: + { + BOOL32 boolRes = FALSE32; + if (pdwStructSize) + { + boolRes = FIL_SetStruct(AND_STRUCT_FIL_POWER_MODE, pvoidStructBuffer, *pdwStructSize); + } + return boolRes; + } + + case AND_FUNCTION_NEURALIZE: + { + BOOL32 boolRes; + boolRes = stFPartFunctions.Neuralize(); + return boolRes; + } + + case AND_FUNCTION_SET_TIMINGS: + { + BOOL32 boolRes = FALSE32; + if (pdwStructSize) + { + boolRes = FIL_SetStruct(AND_STRUCT_FIL_SET_TIMINGS, pvoidStructBuffer, *pdwStructSize); + } + return boolRes; + } + + case AND_FUNCTION_SAVE_STATS: + { + BOOL32 boolRes = FALSE32; + if(stFtlFunctions.WriteStats) + { + boolRes = stFtlFunctions.WriteStats(); + return boolRes; + } + } +#endif // ! AND_READONLY + + default: + return FALSE32; + } +} + +BOOL32 WMR_CtrlIO(UInt32 dwCtlrIOType, void * pvoidDataBuffer, UInt32 * pdwDataSize) +{ + if ((dwCtlrIOType & AND_STRUCT_LAYER_MASK) == AND_STRUCT_LAYER_FUNCTIONAL) + { + return _andPerformFunction(dwCtlrIOType, pvoidDataBuffer, pdwDataSize); + } + else + { + return _andGetStruct(dwCtlrIOType, pvoidDataBuffer, pdwDataSize); + } +} + +#if AND_SIMULATOR +void WMR_Close(void) +{ + stFtlFunctions.Close(); + WMR_MEMSET(&stFtlFunctions, 0, sizeof(FTLFunctions)); + stVflFunctions.Close(); + WMR_MEMSET(&stVflFunctions, 0, sizeof(VFLFunctions)); + stFPartFunctions.Close(); + WMR_MEMSET(&stFPartFunctions, 0, sizeof(FPartFunctions)); + boolFPartInitialized = FALSE32; + // NirW - using Ram disk - killing FIL is a pain and irrelevant... +// FIL_Close(); +// WMR_MEMSET(&stDeviceInfo, 0, sizeof(stDeviceInfo)); +} +#endif + +FTLFunctions * WMR_GetFTL(void) +{ + return &stFtlFunctions; +} + +VFLFunctions * WMR_GetVFL(void) +{ + return &stVflFunctions; +} + +#endif // (!defined(AND_FPART_ONLY) || !AND_FPART_ONLY) + diff --git a/drivers/flash_nand/raw/Whimory/Exam/WMRExam.h b/drivers/flash_nand/raw/Whimory/Exam/WMRExam.h new file mode 100644 index 0000000..0a96f38 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Exam/WMRExam.h @@ -0,0 +1,136 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Example */ +/* NAME : Example */ +/* FILE : WMRExam.h */ +/* PURPOSE : the example for whimory initialization */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 12-SEP-2005 [Jaesung Jung] : first writing */ +/* */ +/*****************************************************************************/ +#if (!defined(AND_FPART_ONLY) || !AND_FPART_ONLY) +#include "FTL.h" +#include "VFL.h" +#include "FIL.h" +#else +#include "FPart.h" +#include "FIL.h" +#endif + +#ifndef _WMR_EXAM_H_ +#define _WMR_EXAM_H_ + +/*****************************************************************************/ +/* whimory version signature */ +// Platform Types +#define WMR_PLATFORM_SHIFT (24) +#define WMR_PLATFORM_DARWIN ('C') + +// Layout Types +#define WMR_LAYOUT_SHIFT (16) +#define WMR_LAYOUT_SIMPLE ('0') +#define WMR_LAYOUT_VS ('1') + +// VFL types +#define WMR_VFL_SHIFT (8) +#define WMR_M68_VFL ('0') +#define WMR_VSVFL ('1') + +// default signature goes here +#define WMR_VFL_SIGNATURE ((WMR_PLATFORM_DARWIN << WMR_PLATFORM_SHIFT) | (WMR_LAYOUT_SIMPLE << WMR_LAYOUT_SHIFT) | (WMR_M68_VFL << 8)) /* 'C0' for P2 */ +#define WMR_VSVFL_SIGNATURE ((WMR_PLATFORM_DARWIN << WMR_PLATFORM_SHIFT) | (WMR_LAYOUT_SIMPLE << WMR_LAYOUT_SHIFT) | (WMR_VSVFL << 8)) /* 'C0' for P2 */ +#define WMR_VSVFL_VS_SIGNATURE ((WMR_PLATFORM_DARWIN << WMR_PLATFORM_SHIFT) | (WMR_LAYOUT_VS << WMR_LAYOUT_SHIFT) | (WMR_VSVFL << 8)) /* 'C1' for N72+ */ + +#define WMR_SIGNATURE_EPOCH_MASK (0x000000FF) +#define WMR_SIGNATURE_VFL_MASK (0x0000FF00) +#define WMR_SIGNATURE_LAYOUT_MASK (0x00FF0000) +#define WMR_SIGNATURE_PLATFORM_MASK (0xFF000000) +// signature bit masks for 2nd ID +#define WMR_SIGNATURE_FORMAT_VERSION_MASK (0x0000FFFF) +#define WMR_SIGNATURE_METADATA_MASK (0x00010000) + +#define WMR_SIGNATURE_VFL(_x) (UInt8)(((_x) & WMR_SIGNATURE_VFL_MASK) >> WMR_VFL_SHIFT) +#define WMR_SIGNATURE_LAYOUT(_x) (UInt8)(((_x) & WMR_SIGNATURE_LAYOUT_MASK) >> WMR_LAYOUT_SHIFT) +#define WMR_SIGNATURE_PLATFORM(_x) (UInt8)(((_x) & WMR_SIGNATURE_PLATFORM_MASK) >> WMR_PLATFORM_SHIFT) +#define WMR_SIGNATURE_FORMATTING_VERSION(_x) (UInt8)((_x) & WMR_SIGNATURE_FORMAT_VERSION_MASK) +#define WMR_SIGNATURE_METADATA(_x) (UInt8)(((_x) & WMR_SIGNATURE_METADATA_MASK) >> WMR_METADATA_SHIFT) + +#define WMR_FORMATTING_VERSION_2 ((UInt32)0x00000002) /* May 20th 2007 */ +#define WMR_FORMATTING_VERSION_3 ((UInt32)0x00000003) /* August 22nd 2007 */ +#define WMR_FORMATTING_VERSION_4 ((UInt32)0x00000004) /* July 23rd 2008 */ +#define WMR_FORMATTING_VERSION_5 ((UInt32)0x00000005) /* Dec 1st 2009 */ +#define WMR_FORMATTING_VERSION ((UInt32)0x00000006) /* July 30th 2010 */ + +// Metadata Whitening +#define WMR_METADATA_SHIFT (16) +#define WMR_METADATA_WHITENING_NONE ((UInt32)0x0) +#define WMR_METADATA_WHITENING ((UInt32)0x1) +#define WMR_METADATA_SIGNATURE (WMR_METADATA_WHITENING << WMR_METADATA_SHIFT) + +#define WMR_FORMAT_SUPPORTED(_x) ((_x) <= WMR_FORMATTING_VERSION) + +/* used during epoch updates */ +#define WMR_TEMP_SIGNATURE (('X' << 24) | ('X' << 16) | ('X' << 8) | ('X' << 0)) +/* Return value of WMR_XXX() */ +/*****************************************************************************/ +#define WMR_SUCCESS ANDErrorCodeOk +#define WMR_CRITICAL_ERROR ANDErrorCodeHwErr +#define WMR_UNRECOVERABLE_ERROR ANDErrorCodeUserDataErr + +#define WMR_MAX_STR_BUILD_SIZE (256) + +typedef struct +{ + UInt32 dwMainSignature; // main driver version number + UInt32 dw2ndId; // to be used for undetifying sub versions + UInt8 strBuildInfo[WMR_MAX_STR_BUILD_SIZE]; // kernel / build version that formatted the device +} ANDDriverSignature; + +/*****************************************************************************/ +/* exported function prototype of WMR example */ +/*****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +Int32 WMR_PreInit(UInt32 dwFormatType, UInt32 dwBootAreaSize); + +#if (!defined(AND_FPART_ONLY) || !AND_FPART_ONLY) +Int32 WMR_Init(UInt32 *pTotalScts, UInt32 * pdwSectorSize, UInt32 * tmpIndexCache, UInt32 dwFormatType, UInt32 dwBootAreaSize); +void WMR_Close(void); +BOOL32 WMR_CtrlIO(UInt32 dwCtlrIOType, void * pvoidDataBuffer, UInt32 * pdwDataSize); +BOOL32 WMRGetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); + +FTLFunctions * WMR_GetFTL(void); +VFLFunctions * WMR_GetVFL(void); +#endif // (!defined(AND_FPART_ONLY) || !AND_FPART_ONLY) + +FPartFunctions * WMR_GetFPart(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _FTL_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/ANDTypes.h b/drivers/flash_nand/raw/Whimory/Inc/ANDTypes.h new file mode 100644 index 0000000..0ec62cb --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/ANDTypes.h @@ -0,0 +1,541 @@ +/*****************************************************************************/ +/* */ +/*****************************************************************************/ + +#ifndef _AND_TYPES_H_ +#define _AND_TYPES_H_ + +#include "WMRTypes.h" + +typedef Int32 ANDStatus; + +#define ANDErrorCodeOk (Int32)0 +#define ANDErrorCodeCleanOk (Int32)1 +#define ANDErrorCodeHwErr (Int32)0x80000001 +#define ANDErrorCodeUserDataErr (Int32)0x80000002 +#define ANDErrorCodeOutOfRangeErr (Int32)0x80000003 +#define ANDErrorCodeAlignmentErr (Int32)0x80000004 +#define ANDErrorWriteFailureErr (Int32)0x80000005 +#define ANDErrorCodeAllocFailErr (Int32)0x80000006 +#define ANDErrorCodeNotSupportedErr (Int32)0x80000007 + +#define NAND_UID_RAW_PAGE_BYTES_TO_READ (256) +#define NAND_UID_PPN_BYTES_TO_READ (16) +#define NAND_UID_LEN_RAW (16) +#define NAND_UID_LEN_PPN (16) +//Length of PPN Firmware Version, Package Assembly Code, Controller UID, Controller HW ID +#define NAND_DEV_PARAM_LEN_PPN (16) + +typedef struct +{ + UInt8 ce; + UInt8 cmdSize; + UInt8 addrSize; + UInt8 confirmCmdSize; + UInt8 arrCmd[10]; + UInt8 arrAddr[10]; + UInt8 arrConfirmCmd[10]; + UInt8 buf[NAND_UID_RAW_PAGE_BYTES_TO_READ]; + UInt32 bytesToRead; +} GenericReadRequest; + +typedef struct +{ + UInt8 ce; + UInt8 die; + UInt8 buf[NAND_UID_PPN_BYTES_TO_READ]; +} PpnUIDReadRequest; + +typedef union +{ + struct { + UInt8 DCCYCLE; + UInt8 tRP; + UInt8 tREH; + UInt8 tWP; + UInt8 tWH; + }sdrTimings; + UInt8 ddr_tHALFCYCLE; +}NandTimingParams; + +// ANDAddressStruct - is used to translate logical and virtual +// addresses to physical addresses +typedef struct +{ + UInt32 dwLpn; + UInt32 dwVpn; + UInt32 dwCS; + UInt32 dwPpn; + UInt32 dwColumn; + UInt16 dwCau; +} ANDAddressStruct; + +// Describe the sections of a NAND page that contain data +typedef struct +{ + UInt32 dwNumSegments; + UInt32 dwMetaSegmentIndex; + struct { + UInt32 dwOffset; + UInt32 dwLength; + } pastrSegments[32]; + +} ANDNandLayoutStruct; + +// use this structure to export all the information from the AND driver in a single buffer / file. +typedef struct + { + UInt32 dwStructID; + UInt32 dwStructureVersion; + UInt32 dwDataSize; + UInt32 dwIndex; + } ANDExportStruct; + +typedef struct +{ + UInt16 bank; + UInt16 block; +} SpecialBlockAddress; + +typedef struct +{ + UInt32 dwPhysicalCE; + UInt32 dwPhysicalBlock; + UInt16 wType; +} BorrowBlockAddress; + +#define VFL_VALUE_UNKNOWN (~0) +typedef enum +{ + VFLFailNone, + VFLFailUECC, + VFLFailErase, + VFLFailWrite, + VFLFailEraseTimeOut, + VFLFailWriteTimeOut, + VFLFailRefresh, + VFLFailEnd = 0x7FFFFFFF +} VFLFailureMode; + +#define VFL_MAX_FAILURE_REGIONS (16) +typedef struct +{ + VFLFailureMode mode; + UInt16 wCE[VFL_MAX_FAILURE_REGIONS]; + UInt16 wPhysicalBlock[VFL_MAX_FAILURE_REGIONS]; + UInt32 dwPhysicalPage; +} VFLFailureDetails; + +typedef struct +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwBlocksErasedCnt; + UInt64 ddwSingleWriteCallCnt; + UInt64 ddwSingleReadCallCnt; + UInt64 ddwSequetialReadCallCnt; + UInt64 ddwScatteredReadCallCnt; + UInt64 ddwMultipleWriteCallCnt; + UInt64 ddwEraseCallCnt; +} genVFLStatistics; + +#define TL_BLOCK_FREE 0x1 +#define TL_BLOCK_DATA 0x2 +#define TL_BLOCK_INDEX 0x4 +#define TL_BLOCK_CXT 0x8 +#define TL_BLOCK_DEAD 0x10 +#define TL_BLOCK_DATA_STATIC 0x20 +#define TL_BLOCK_UNKNOWN 0x80 + +typedef struct +{ + UInt8 blockType; + UInt32 blockSizeInLbas; + UInt32 validLbas; +} ANDFTLBlockStruct; + +/*****************************************************************************/ +/* Global Structure Types which should be shared by FTL, VFL, FIL */ +/*****************************************************************************/ + +#define FTL_TYPE_FTL 1 +#define FTL_TYPE_YAFTL 2 +#define FTL_TYPE_SFTL 3 + +#define VFL_TYPE_VFL 1 +#define VFL_TYPE_VSVFL 2 +#define VFL_TYPE_PPNVFL 3 +#define VFL_TYPE_SWISSPPNVFL 4 + + +#define AND_EXPORT_STRUCTURE_VERSION 0x00020001 +#define AND_EXPORT_STRUCTURE_MAJVER(v) (((v) >> 16) & 0xFFFF) +#define AND_EXPORT_STRUCTURE_MINVER(v) (((v) >> 0) & 0xFFFF) +#define AND_EXPORT_STRUCTURE_IS_1_X(v) (1 == AND_EXPORT_STRUCTURE_MAJVER(v)) +#define AND_EXPORT_STRUCTURE_IS_2_X(v) (2 == AND_EXPORT_STRUCTURE_MAJVER(v)) + +#define AND_STATISTICS_SIZE_PER_LAYER (0x200) + +#define LOCKDOWN_EXTRACT_ALL (0xFE000000 | 0x00000100) +#define LOCKDOWN_GET_ALL_SIZE (0xFE000000 | 0x00000200) + +// CtrlIO defines and structures +// defines for data structues queries from user applications +#define AND_STRUCT_SIZE_MASK (0x80000000) // MSb indicates we're requesting the size +#define AND_STRUCT_LAYER_MASK (0x3F000000) // use with & to get the layer struct type +#define AND_STRUCT_INDEX_MASK (0xFFFFFF00) // use with & to clear the index (LSB) +#define AND_STRUCT_CS_MASK (0x000000FF) // use with & to clear the CS +#define AND_STRUCT_SET (0x40000000) // Use this bit to indicate a set operation +#define AND_STRUCT_LAYER_OS (0x0A000000) + +#define AND_STRUCT_LAYER_FTL (0x01000000) +#define AND_STRUCT_LAYER_VFL (0x02000000) +#define AND_STRUCT_LAYER_FIL (0x03000000) +#define AND_STRUCT_LAYER_WMR (0x04000000) +#define AND_STRUCT_LAYER_FUNCTIONAL (0x10000000) +// Operations +#define _AND_FUNCTION_COMPLETE_EPOCH_UPDATE (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000001) // deprecated +#define AND_FUNCTION_INDEX_CACHE_UPDATE (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000200) +#define AND_FUNCTION_CHANGE_FTL_TYPE (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000300) +#define AND_FUNCTION_CHANGE_NUM_OF_SUBLKS (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000400) +#define AND_FUNCTION_SET_BURNIN_CODE (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000500) +#define AND_FUNCTION_ERASE_SIGNATURE (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000600) +#define AND_FUNCTION_SET_POWER_MODE (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000700) +#define AND_FUNCTION_NEURALIZE (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000800) +#define AND_FUNCTION_SET_TIMINGS (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000900) +#define AND_FUNCTION_SAVE_STATS (AND_STRUCT_LAYER_FUNCTIONAL | 0x00000A00) + +// the below is defined in ANDExport.h +#define AND_STRUCT_LAYER_GETALL (0x30000000) + +#define AND_STRUCT_WMR_EXPORT_ALL (AND_STRUCT_LAYER_GETALL | 0x00000100) +#define AND_STRUCT_WMR_EXPORT_ALL_GET_SIZE (AND_STRUCT_LAYER_GETALL | 0x00000200) +#define AND_STRUCT_WMR_EXPORT_ALL_END (AND_STRUCT_LAYER_GETALL | 0x0000FF00) + +// use the LSB for indexing (do not use it for the identifiers) +// OS structures +#define AND_STRUCT_OS_GET_IOS (AND_STRUCT_LAYER_OS | 0x00000100) +#define AND_STRUCT_OS_GET_HIST (AND_STRUCT_LAYER_OS | 0x00000200) +#define AND_STRUCT_OS_SET_LOG_TAG (AND_STRUCT_LAYER_OS | 0x00000300) +#define AND_STRUCT_OS_SET_GMT_TAG (AND_STRUCT_LAYER_OS | 0x00000400) + +// FTL structures +#define AND_STRUCT_FTL_STATISTICS (AND_STRUCT_LAYER_FTL | 0x00000200) +#define AND_STRUCT_FTL_FTLCXT (AND_STRUCT_LAYER_FTL | 0x00000300) +#define AND_STRUCT_FTL_MAPTABLE (AND_STRUCT_LAYER_FTL | 0x00000400) +#define AND_STRUCT_FTL_LOGCXTTABLE (AND_STRUCT_LAYER_FTL | 0x00000500) +#define AND_STRUCT_FTL_ECTABLE (AND_STRUCT_LAYER_FTL | 0x00000600) +#define AND_STRUCT_FTL_RCTABLE (AND_STRUCT_LAYER_FTL | 0x00000700) +#define AND_STRUCT_FTL_GETADDRESS (AND_STRUCT_LAYER_FTL | 0x00000800) +#define AND_STRUCT_FTL_GET_TYPE (AND_STRUCT_LAYER_FTL | 0x00000900) +#define AND_STRUCT_FTL_GET_FTL_STATS_SIZE (AND_STRUCT_LAYER_FTL | 0x00000A00) +#define AND_STRUCT_FTL_GET_FTL_DEVICEINFO_SIZE (AND_STRUCT_LAYER_FTL | 0x00000B00) +#define AND_STRUCT_FTL_GET_FTL_DEVICEINFO (AND_STRUCT_LAYER_FTL | 0x00000C00) +#define AND_STRUCT_FTL_GET_FTL_EC_BINS (AND_STRUCT_LAYER_FTL | 0x00000D00) +#define AND_STRUCT_FTL_GET_FTL_RC_BINS (AND_STRUCT_LAYER_FTL | 0x00000E00) +#define AND_STRUCT_FTL_RECOMMEND_CONTENT_DELETION (AND_STRUCT_LAYER_FTL | 0x00000F00) +#define AND_STRUCT_FTL_IDEAL_SIZE_1K (AND_STRUCT_LAYER_FTL | 0x00001000) +#define AND_STRUCT_FTL_GET_FTL_BLOCK_COUNT (AND_STRUCT_LAYER_FTL | 0x00001100) +#define AND_STRUCT_FTL_GET_FTL_BLOCK_STAT (AND_STRUCT_LAYER_FTL | 0x00001200) +#define AND_STRUCT_FTL_L2V_STRUCT (AND_STRUCT_LAYER_FTL | 0x00001300) +#define AND_STRUCT_FTL_L2V_ROOTS (AND_STRUCT_LAYER_FTL | 0x00001400) +#define AND_STRUCT_FTL_L2V_POOL (AND_STRUCT_LAYER_FTL | 0x00001500) +#define AND_STRUCT_FTL_SB_CYCLES (AND_STRUCT_LAYER_FTL | 0x00001600) +#define AND_STRUCT_FTL_SB_READ_CYCLES (AND_STRUCT_LAYER_FTL | 0x00001700) + +// VFL structures +#define AND_STRUCT_VFL_MASK (AND_STRUCT_LAYER_VFL | 0x0000FF00) +#define AND_STRUCT_VFL_STATISTICS (AND_STRUCT_LAYER_VFL | 0x00000200) +#define AND_STRUCT_VFL_VFLMETA (AND_STRUCT_LAYER_VFL | 0x00000300) +#define AND_STRUCT_VFL_BBT (AND_STRUCT_LAYER_VFL | 0x00000400) +#define AND_STRUCT_VFL_FILSTATISTICS (AND_STRUCT_LAYER_VFL | 0x00000500) +#define AND_STRUCT_VFL_GETADDRESS (AND_STRUCT_LAYER_VFL | 0x00000600) +#define AND_STRUCT_VFL_GROWNBBT (AND_STRUCT_LAYER_VFL | 0x00000700) +#define AND_STRUCT_VFL_GET_TYPE (AND_STRUCT_LAYER_VFL | 0x00000800) +#define AND_STRUCT_VFL_STATISTICS_SIZE (AND_STRUCT_LAYER_VFL | 0x00000900) +#define AND_STRUCT_VFL_DEVICEINFO_SIZE (AND_STRUCT_LAYER_VFL | 0x00000A00) +#define AND_STRUCT_VFL_DEVICEINFO (AND_STRUCT_LAYER_VFL | 0x00000B00) +#define AND_STRUCT_VFL_FTLTYPE (AND_STRUCT_LAYER_VFL | 0x00000C00) +#define AND_STRUCT_VFL_NUM_OF_FTL_SUBLKS (AND_STRUCT_LAYER_VFL | 0x00000D00) +#define AND_STRUCT_VFL_BYTES_PER_PAGE (AND_STRUCT_LAYER_VFL | 0x00000E00) +#define AND_STRUCT_VFL_PAGES_PER_SUBLK (AND_STRUCT_LAYER_VFL | 0x00000F00) +#define AND_STRUCT_VFL_BYTES_PER_META (AND_STRUCT_LAYER_VFL | 0x00001000) +#define AND_STRUCT_VFL_CORRECTABLE_BITS (AND_STRUCT_LAYER_VFL | 0x00001100) +#define AND_STRUCT_VFL_CORRECTABLE_SIZE (AND_STRUCT_LAYER_VFL | 0x00001200) +#define AND_STRUCT_VFL_NUM_OF_SUBLKS (AND_STRUCT_LAYER_VFL | 0x00001300) +#define AND_STRUCT_VFL_NEW_FTLTYPE (AND_STRUCT_LAYER_VFL | 0x00001400) +#define AND_STRUCT_VFL_NEW_NUM_OF_FTL_SUBLKS (AND_STRUCT_LAYER_VFL | 0x00001500) +#define AND_STRUCT_VFL_BURNIN_CODE (AND_STRUCT_LAYER_VFL | 0x00001600) +#define AND_STRUCT_VFL_FACTORY_BBT (AND_STRUCT_LAYER_VFL | 0x00001700) +#define AND_STRUCT_VFL_SIGNATURE_LOCATION (AND_STRUCT_LAYER_VFL | 0x00001800) +#define AND_STRUCT_VFL_PAGES_PER_BLOCK (AND_STRUCT_LAYER_VFL | 0x00001900) +#define AND_STRUCT_VFL_LAST_ERROR (AND_STRUCT_LAYER_VFL | 0x00001A00) +#define AND_STRUCT_VFL_NAND_TYPE (AND_STRUCT_LAYER_VFL | 0x00001B00) +#define AND_STRUCT_VFL_VALID_BYTES_PER_META (AND_STRUCT_LAYER_VFL | 0x00001C00) +#define AND_STRUCT_VFL_FIND_BORROWED_BLOCKS (AND_STRUCT_LAYER_VFL | 0x00001D00) +#define AND_STRUCT_VFL_EXPORTED_LBA_NO (AND_STRUCT_LAYER_VFL | 0x00001E00) +#define AND_STRUCT_VFL_EXPORTED_L2V_POOL (AND_STRUCT_LAYER_VFL | 0x00001F00) +#define AND_STRUCT_VFL_PUBLIC_FBBT (AND_STRUCT_LAYER_VFL | 0x00002000) +#define AND_STRUCT_VFL_NUM_CHANNELS (AND_STRUCT_LAYER_VFL | 0x00002100) +#define AND_STRUCT_VFL_CES_PER_CHANNEL (AND_STRUCT_LAYER_VFL | 0x00002200) +#define AND_STRUCT_VFL_CAUS_PER_CE (AND_STRUCT_LAYER_VFL | 0x00002300) +#define AND_STRUCT_VFL_MAX_TRANS_IN_PAGES (AND_STRUCT_LAYER_VFL | 0x00002400) + +// FIL structures +#define AND_STRUCT_FIL_MASK (AND_STRUCT_LAYER_FIL | 0x0000FF00) // LSB used for bank info +#define AND_STRUCT_FIL_STATISTICS (AND_STRUCT_LAYER_FIL | 0x00000200) // LSB used for bank info +#define AND_STRUCT_FIL_READPAGE (AND_STRUCT_LAYER_FIL | 0x00000300) // LSB used for bank info +#define AND_STRUCT_FIL_STATISTICS_SIZE (AND_STRUCT_LAYER_FIL | 0x00000400) // LSB used for bank info +#define AND_STRUCT_FIL_READTIMING (AND_STRUCT_LAYER_FIL | 0x00000500) +#define AND_STRUCT_FIL_WRITETIMING (AND_STRUCT_LAYER_FIL | 0x00000600) +#define AND_STRUCT_FIL_CHIPID (AND_STRUCT_LAYER_FIL | 0x00000700) +#define AND_STRUCT_FIL_CHANNEL_BITMAP (AND_STRUCT_LAYER_FIL | 0x00000800) +#define AND_STRUCT_FIL_UNIQUEID (AND_STRUCT_LAYER_FIL | 0x00000900) +#define AND_STRUCT_FIL_HYNIX_BBT (AND_STRUCT_LAYER_FIL | 0x00000A00) +#define AND_STRUCT_FIL_POWER_MODE (AND_STRUCT_LAYER_FIL | 0x00000B00) +#define AND_STRUCT_FIL_NAND_LAYOUT (AND_STRUCT_LAYER_FIL | 0x00000C00) +#define AND_STRUCT_FIL_SPARE_SIZE (AND_STRUCT_LAYER_FIL | 0x00000D00) +#define AND_STRUCT_FIL_BITS_PER_CELL (AND_STRUCT_LAYER_FIL | 0x00000E00) +#define AND_STRUCT_FIL_DEVICE_INFO (AND_STRUCT_LAYER_FIL | 0x00000F00) +#define AND_STRUCT_FIL_DIES_PER_CE (AND_STRUCT_LAYER_FIL | 0x00001000) +#define AND_STRUCT_FIL_BLOCKS_PER_CE (AND_STRUCT_LAYER_FIL | 0x00001100) +#define AND_STRUCT_FIL_SET_TIMINGS (AND_STRUCT_LAYER_FIL | 0x00001200) +#define AND_STRUCT_FIL_GET_TIMINGS (AND_STRUCT_LAYER_FIL | 0x00001300) +#define AND_STRUCT_FIL_GET_CE_INFO (AND_STRUCT_LAYER_FIL | 0x00001400) +#define AND_STRUCT_FIL_MFG_ID (AND_STRUCT_LAYER_FIL | 0x00001500) +#define AND_STRUCT_FIL_FW_VERSION (AND_STRUCT_LAYER_FIL | 0x00001600) +#define AND_STRUCT_FIL_PKG_ASSEMBLY_CODE (AND_STRUCT_LAYER_FIL | 0x00001700) +#define AND_STRUCT_FIL_CONTROLLER_UID (AND_STRUCT_LAYER_FIL | 0x00001800) +#define AND_STRUCT_FIL_CONTROLLER_HW_ID (AND_STRUCT_LAYER_FIL | 0x00001900) +#define AND_STRUCT_FIL_LBAS_PER_PAGE (AND_STRUCT_LAYER_FIL | 0x00001A00) + +// WMR structures +#define AND_STRUCT_WMR_VERSION (AND_STRUCT_LAYER_WMR | 0x00000100) +#define AND_STRUCT_WMR_DEVICEINFO (AND_STRUCT_LAYER_WMR | 0x00000200) +#define AND_STRUCT_WMR_LAYOUT (AND_STRUCT_LAYER_WMR | 0x00000300) + +// defines for device info types, these might move to an h file shared by all layers +#define AND_DEVINFO_PAGES_PER_BLOCK (100) +#define AND_DEVINFO_NUM_OF_CS (101) +#define AND_DEVINFO_BBT_TYPE (102) +#define AND_DEVINFO_BLOCKS_PER_CS (103) +#define AND_DEVINFO_BYTES_PER_PAGE (104) +#define AND_DEVINFO_BYTES_PER_SPARE (105) +#define AND_DEVINFO_USER_BLOCKS_PER_CS (106) +#define AND_DEVINFO_VENDOR_SPECIFIC_TYPE (107) +#define AND_DEVINFO_REFRESH_THRESHOLD (108) +#define AND_DEVINFO_BANKS_PER_CS (109) +#define AND_DEVINFO_PAGES_PER_SUBLK (110) +#define AND_DEVINFO_NUM_OF_BANKS (111) +#define AND_DEVINFO_NUM_OF_USER_SUBLK (112) +#define AND_DEVINFO_FTL_TYPE (113) +#define AND_DEVINFO_BYTES_PER_BL_PAGE (114) +#define AND_DEVINFO_CORRECTABLE_BITS (115) +#define AND_DEVINFO_CORRECTABLE_SIZE (116) +#define AND_DEVINFO_FTL_NEED_FORMAT (117) +#define AND_DEVINFO_DIES_PER_CS (118) +#define AND_DEVINFO_BLOCKS_PER_DIE (119) +#define AND_DEVINFO_DIE_STRIDE (120) +#define AND_DEVINFO_BLOCK_STRIDE (121) +#define AND_DEVINFO_LAST_BLOCK (122) +#define AND_DEVINFO_BLOCKS_PER_CAU (123) +#define AND_DEVINFO_CAUS_PER_CE (124) +#define AND_DEVINFO_SLC_PAGES_PER_BLOCK (125) +#define AND_DEVINFO_MLC_PAGES_PER_BLOCK (126) +#define AND_DEVINFO_MATCH_ODDEVEN_CAUS (127) +#define AND_DEVINFO_BITS_PER_CAU_ADDRESS (128) +#define AND_DEVINFO_BITS_PER_PAGE_ADDRESS (130) +#define AND_DEVINFO_BITS_PER_BLOCK_ADDRESS (131) +#define AND_DEVINFO_NUM_OF_CHANNELS (132) +#define AND_DEVINFO_NUM_OF_CES_PER_CHANNEL (133) +#define AND_DEVINFO_PPN_DEVICE (134) +#define AND_DEVINFO_FIL_LBAS_PER_PAGE (135) +#define AND_DEVINFO_FIL_META_VALID_BYTES (136) +#define AND_DEVINFO_FIL_META_BUFFER_BYTES (137) +#define AND_DEVINFO_FIL_MATCH_ODD_EVEN_BLKS (138) +#define AND_DEVINFO_FIL_PREP_BUFFER_ENTRIES (139) +#define AND_DEVINFO_VFL_AVAILABLE_VBAS (140) +#define AND_DEVINFO_ADDR_BITS_BITS_PER_CELL (141) +#define AND_DEVINFO_TOGGLE_DEVICE (142) +#define AND_DEVINFO_L2V_POOL_SIZE (143) +#define AND_DEVINFO_STREAM_BUFFER_MAX (144) + + +// format params +#define WMR_INIT_DISABLE_FORMAT (0x00000000) // default init value +#define WMR_INIT_ALLOW_FORMAT (0x00000001) // allow normal unit format +#define WMR_INIT_RUN_PRODUCTION_FORMAT (0x00000002) // call production format +#define WMR_INIT_ALLOW_VSVFL (0x00000004) // allow VSVFL in case we format +#define WMR_INIT_ALLOW_YAFTL (0x00000008) // allow VSVFL in case we format +#define WMR_INIT_RUN_FTL_FORMAT (0x00000010) // call ftl format and change the FTL size +#define WMR_INIT_SIGNATURE_IN_BLOCKZERO (0x00000020) // signature in block zero +#define WMR_INIT_LOW_POWER_MODE (0x00000040) // driver should use minimum power until notified +#define WMR_INIT_NAND_RESTORE (0x00000080) // force full nand restore during power up +#define WMR_INIT_USE_DEV_UNIQUE_INFO (0x00000100) // allocate a partition for device unique info +#define WMR_INIT_USE_DIAG_CTRL_INFO (0x00000200) // allocate a partition for diag control bits +#define WMR_INIT_METADATA_WHITENING (0x00000400) // device should be formatted with metadata whitening +#define WMR_INIT_METADATA_WHITENING_CHECK (0x00000800) // device should be formatted with metadata whitening if it already isn't +#define _WMR_INIT_ALLOW_ANY_EPOCH (0x00001000) // driver will not fail security epoch check (deprecated) +#define WMR_INIT_DISABLE_GC_IN_TRIM (0x00002000) // disable empty GC in trim +#define WMR_INIT_SET_INDEX_CACHE_SIZE (0x00004000) // disable empty GC in trim +#define WMR_INIT__USE_NEW_DUAL_CHANNEL_ADDRESS (0x00008000) // rdar://9159270 +#define WMR_INIT_OPEN_READONLY (0x00010000) // Disable writes/erase during open rdar://9407663 +#define WMR_INIT_USE_KEEPOUT_AS_BORROW (0x00020000) +#ifdef AND_SIMULATOR +#define WMR_INIT_IGNORE_ERASE_GAP (0x00040000) +#endif + +// flags for external VFL calls +#define AND_EXTERNAL_VFL_TEST_PARTITION (0x00000000) +#define AND_EXTERNAL_VFL_FTL_PARTITION (0x00000001) +#define AND_EXTERNAL_VFL_FULL (0x00000002) + +// factory test conditions +#define VFL_BONFIRE_UNTESTED_CODE (0) +#define VFL_BONFIRE_RMA_CODE (306) + +// FIL defines +typedef enum +{ + INIT_BBT_TOSHIBA_MLC = 1, + INIT_BBT_SAMSUNG_MLC = 2, + INIT_BBT_HYNIX_MLC = 3, + INIT_BBT_SAMSUNG_SLC = 4, + INIT_BBT_INTEL_ONFI = 5, + INIT_BBT_ONFI = 6, + INIT_BBT_MICRON_ONFI = 7, + INIT_BBT_SAMSUNG_MLC_8K = 8, + INIT_BBT_SANDISK_MLC = 9, + INIT_BBT_PPN = 10, + INIT_BBT_BOGUS = 0x0FFFFFFF, // Force 4-byte enum field +} CheckInitialBadType; + +// format definitions +#define VS_FMT_UNKNOWN 0x0000 +#define VS_FMT_SIMPLE 0x0001 +#define VS_FMT_TOSHIBA_TWO_DISTRICT 0x0010 +#define VS_FMT_TOSHIBA_TWO_DISTRICT_EXT 0x0011 +#define VS_FMT_2BANKS_MSB 0x0012 +#define VS_FMT_4BANKS_LSB_MSB 0x0013 +#define VS_FMT_2BANKS_LSB 0x0014 +#define VS_FMT_TOSHIBA_TWO_DIE 0x0015 +#define VS_FMT_4BANKS_LSB_MSB_NOPWR2 0x0016 + +// command definitions +#define VS_CMD_UNKNOWN 0x0000 +#define VS_CMD_SIMPLE 0x0001 +#define VS_CMD_SAMSUNG_2P 0x0010 +#define VS_CMD_ONFI_2D 0x0011 +#define VS_CMD_ONFI_2P 0x0012 +#define VS_CMD_ONFI_2D_CACHE 0x0013 +#define VS_CMD_ONFI_2P_CACHE 0x0014 +#define VS_CMD_TOSHIBA_2P 0x0015 +#define VS_CMD_TOSHIBA_2P_CACHE 0x0016 +#define VS_CMD_TOSHIBA_2D 0x0017 + +typedef UInt32 VendorSpecificType; + +#define VS_TYPE(cmd, fmt) (UInt32)(((UInt32)(cmd) << 16) | ((UInt32)(fmt) & 0x0000FFFF)) +#define VS_GET_CMD(vs) (((UInt32)(vs) >> 16)) +#define VS_GET_FMT(vs) (((UInt32)(vs) & 0x0000FFFF)) + +#define FIL_VS_UNKNOWN VS_TYPE(VS_CMD_UNKNOWN, VS_FMT_UNKNOWN) +#define FIL_VS_SIMPLE VS_TYPE(VS_CMD_SIMPLE, VS_FMT_SIMPLE) +// this is to make the current tables work... +#define FIL_VS_HYNIX_2P VS_TYPE(VS_CMD_SAMSUNG_2P, VS_FMT_2BANKS_LSB) +#define FIL_VS_ONFI_2D VS_TYPE(VS_CMD_ONFI_2D, VS_FMT_2BANKS_MSB) +#define FIL_VS_ONFI_2P VS_TYPE(VS_CMD_ONFI_2P, VS_FMT_2BANKS_LSB) +#define FIL_VS_ONFI_2P_2D VS_TYPE(VS_CMD_ONFI_2P, VS_FMT_4BANKS_LSB_MSB) +#define FIL_VS_ONFI_2D_CACHE VS_TYPE(VS_CMD_ONFI_2D_CACHE, VS_FMT_2BANKS_MSB) +#define FIL_VS_ONFI_2P_CACHE VS_TYPE(VS_CMD_ONFI_2P_CACHE, VS_FMT_2BANKS_LSB) +#define FIL_VS_ONFI_2P_2D_CACHE VS_TYPE(VS_CMD_ONFI_2P_CACHE, VS_FMT_4BANKS_LSB_MSB) +#define FIL_VS_SAMSUNG_2D VS_TYPE(VS_CMD_SIMPLE, VS_FMT_2BANKS_MSB) +#define FIL_VS_SAMSUNG_2P_2D VS_TYPE(VS_CMD_SIMPLE, VS_FMT_4BANKS_LSB_MSB) +#define FIL_VS_SAMSUNG_2P_2D_EXT VS_TYPE(VS_CMD_SIMPLE, VS_FMT_4BANKS_LSB_MSB_NOPWR2) +#define FIL_VS_TOSHIBA_2P VS_TYPE(VS_CMD_TOSHIBA_2P, VS_FMT_TOSHIBA_TWO_DISTRICT) +#define FIL_VS_TOSHIBA_2P_EXT VS_TYPE(VS_CMD_TOSHIBA_2P, VS_FMT_TOSHIBA_TWO_DISTRICT_EXT) +#define FIL_VS_TOSHIBA_2P_CACHE VS_TYPE(VS_CMD_TOSHIBA_2P_CACHE, VS_FMT_TOSHIBA_TWO_DISTRICT) +#define FIL_VS_TOSHIBA_2P_EXT_CACHE VS_TYPE(VS_CMD_TOSHIBA_2P_CACHE, VS_FMT_TOSHIBA_TWO_DISTRICT_EXT) +#define FIL_VS_TOSHIBA_2D VS_TYPE(VS_CMD_TOSHIBA_2D, VS_FMT_TOSHIBA_TWO_DIE) + +//CE status report definitions +#define CE_STATUS_UNINITIALIZED ((UInt16)~0) +#define PAGE_STATUS_UNINITIALIZED ((UInt32)~0) + +//Enumeration for blocks that have failed erase +#define BLOCK_STATUS_UNINITIALIZED ((UInt32)0xFFFFFFFF) + +// ============================================================================= +// Power Mode +// To be used with AND_FUNCTION_SET_POWER_MODE & AND_STRUCT_FIL_POWER_MODE +#define NAND_POWER_MODE_UNKNOWN ((UInt32) 0) +#define NAND_POWER_MODE_FULL_SPEED ((UInt32) 1) +#define NAND_POWER_MODE_SINGLE_CE ((UInt32) 2) +#define NAND_POWER_MODE_STANDBY ((UInt32) 3) + + +#define NAND_DATA_REGION_SYSCFG ((UInt32)1) +#define NAND_DATA_REGION_DIAG_CONTROL ((UInt32)0) + +// Special Blcok Types - PPN VFL / FPart +// Bit allocations: +// [0-7] - code (uniquue per special block type - valid range is 0x00 - 0xEF +// leaving the top to VFL Context +// [8-13] - handler (how the special block shold be procesed - handler can be either supported +// by FPart or other layers. handler handled by other layers can not be persistent. +// [14] - persistent flag (1 - persistent, 0 - not persistent) +// [15] - special bit flag (1 - special block, 0 - block is allocated to virtual block exported by vfl) + +#define AND_SB_BIT_SPEICAL_FLAG (1 << 15) // if this bit is set the block is + // NOT allocated to VBN + // It is either a special block or + // VFL context block + +#define AND_SB_BIT_PERSISTENT_FLAG (1 << 14) // persistent type (need to survive loosing the signature) + +#define andSBGetHandler(_x) ((UInt16)(((_x) & 0x3F00) >> 8)) +#define andSBSetHandler(_x) ((UInt16)(((_x) & 0x3F) << 8)) + +#define AND_SB_HANDLER_SINGLE_VERSION (1) +#define AND_SB_HANDLER_MULTI_VERSION (2) +#define AND_SB_HANDLER_NAND_BOOT (0x30) +#define AND_SB_HANDLER_VFL_CXT (0x3F) + + +#define andSBGetCode(_x) ((UInt16)((_x) & 0x00FF)) +#define andSBSetCode(_x) ((UInt16)((_x) & 0x00FF)) + + +#define AND_SB_CODE_DRIVER_SIGNATURE (0x01) +#define AND_SB_CODE_BLOCK_ZERO (0x02) +#define AND_SB_CODE_NAND_BOOT (0x03) +#define AND_SB_CODE_DIAGNOSTICS (0x04) +#define AND_SB_CODE_UNIQUE_INFO (0x05) +#define AND_SB_CODE_KEEPOUT (0x06) + +#define AND_SB_TYPE_DRIVER_SIGNATURE (AND_SB_BIT_SPEICAL_FLAG | AND_SB_BIT_PERSISTENT_FLAG | andSBSetHandler(AND_SB_HANDLER_SINGLE_VERSION) | andSBSetCode(AND_SB_CODE_DRIVER_SIGNATURE)) +#define AND_SB_TYPE_BLOCK_ZERO (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_NAND_BOOT) | andSBSetCode(AND_SB_CODE_BLOCK_ZERO)) +#define AND_SB_TYPE_NAND_BOOT (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_NAND_BOOT) | andSBSetCode(AND_SB_CODE_NAND_BOOT)) +#define AND_SB_TYPE_DIAGNOSTICS (AND_SB_BIT_SPEICAL_FLAG | AND_SB_BIT_PERSISTENT_FLAG | andSBSetHandler(AND_SB_HANDLER_SINGLE_VERSION) | andSBSetCode(AND_SB_CODE_DIAGNOSTICS)) +#define AND_SB_TYPE_UNIQUE_INFO (AND_SB_BIT_SPEICAL_FLAG | AND_SB_BIT_PERSISTENT_FLAG | andSBSetHandler(AND_SB_HANDLER_SINGLE_VERSION) | andSBSetCode(AND_SB_CODE_UNIQUE_INFO)) +#define AND_SB_TYPE_KEEPOUT_BOOT (AND_SB_BIT_SPEICAL_FLAG | andSBSetHandler(AND_SB_HANDLER_NAND_BOOT) | andSBSetCode(AND_SB_CODE_KEEPOUT)) + +#define NAND_TYPE_RAW (0) +#define NAND_TYPE_PPN (1) + +#define AND_SPARE_TYPE_REGION_FTL (0x00) // allowing FTL to use 5 bits for types +#define AND_SPARE_TYPE_REGION_VFL (0x20) // allowing VFL to use 4 bits for types +#define AND_SPARE_TYPE_REGION_FPART (0x30) // allowing FPART to use 4 bits for types +#define AND_SPARE_TYPE_REGION_BFN (0x40) // allowing BFN to use 4 bits for types + +// Get address special cases definitions +#define AND_GET_ADDRESS_SPECIAL (0xFFFFFF80) +#define AND_GET_ADDRESS_TRIMMED (AND_GET_ADDRESS_SPECIAL + 1) +#define AND_GET_ADDRESS_OUT_OF_RANGE (AND_GET_ADDRESS_SPECIAL + 2) +#define AND_GET_ADDRESS_CACHED_WRITE (AND_GET_ADDRESS_SPECIAL + 3) +#define AND_GET_ADDRESS_UNINITIALIZED (0xFFFFFFFF) + +#define AND_L2V_POOL_SIZE_UNSPECIFIED (0XFFFFFFFF) + +#endif /* _AND_TYPES_H_ */ + diff --git a/drivers/flash_nand/raw/Whimory/Inc/FIL.h b/drivers/flash_nand/raw/Whimory/Inc/FIL.h new file mode 100644 index 0000000..798f013 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/FIL.h @@ -0,0 +1,212 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : FIL */ +/* NAME : Flash Interface Layer header file */ +/* FILE : FIL.h */ +/* PURPOSE : This file contains the definition and protypes of exported */ +/* functions for FIL of Whimory. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 19-JUL-2005 [Jaesung Jung] : first writing */ +/* */ +/*****************************************************************************/ + +#ifndef _FIL_H_ +#define _FIL_H_ + +#include "ANDTypes.h" +#include "WMRFeatures.h" +#include "PPN_FIL.h" + +/*****************************************************************************/ +/* Return value of FIL_XXX() & physical interface function pointer */ +/*****************************************************************************/ +#define FIL_SUCCESS ANDErrorCodeOk +#define FIL_SUCCESS_CLEAN ANDErrorCodeCleanOk +#define FIL_CRITICAL_ERROR ANDErrorCodeHwErr +#define FIL_U_ECC_ERROR ANDErrorCodeUserDataErr +#define FIL_WRITE_FAIL_ERROR ANDErrorWriteFailureErr +#define FIL_UNSUPPORTED_ERROR ANDErrorCodeNotSupportedErr + +/*****************************************************************************/ +/* FIL Function Table Data Structures */ +/*****************************************************************************/ +typedef struct +{ + void (*Reset)(void); + Int32 (*ReadWithECC)(UInt16 wBank, UInt32 nPpn, UInt8 *pDBuf, UInt8 *pSBuf, UInt8 * pbCorrectedBits, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening); + Int32 (*ReadNoECC)(UInt16 wBank, UInt32 nPpn, UInt8 *pDBuf, UInt8 *pSBuf); + Int32 (*ReadMultiplePages)(UInt32 * padwPpn, UInt8* pDBuf, UInt8* pSBuf, UInt16 wNumOfPagesToRead, UInt8 * pbCorrectedBits, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening); + Int32 (*ReadScatteredPages)(UInt16 * pawBank, UInt32 * padwPpn, UInt8* pDBuf, UInt8* pSBuf, UInt16 wNumOfPagesToRead, UInt8 * pbCorrectedBits, UInt8 * pdwaSectorStats, BOOL32 bDisableWhitening); + Int32 (*ReadMaxECC)(UInt16 wBank, UInt32 nPpn, UInt8 *pDBuf); + Int32 (*ReadBLPage)(UInt16 wCS, UInt32 dwPpn, UInt8 *pabData); + Int32 (*WriteBLPage)(UInt16 wCS, UInt32 dwPpn, UInt8 *pabData); + BOOL32 (*Write2ndBootLoader)(UInt8* padw2ndBootLoader, UInt32 dwBLPageCount, UInt32 dwBLOffsetPage); + BOOL32 (*Read2ndBootLoader)(UInt8* padw2ndBootLoader, UInt32 dwBLPageCount); + Int32 (*Erase)(UInt16 wBank, UInt32 wPbn); + Int32 (*Write)(UInt16 wBank, UInt32 nPpn, UInt8 *pDBuf, UInt8 *pSBuf, BOOL32 bDisableWhitening); + Int32 (*WriteScatteredPages)(UInt16 * pawBanks, UInt32 * padwPpn, UInt8 * pabDataBuf, UInt8 * pabMetaBuf, UInt16 wNumOfPagesToWrite, UInt16 * pwFailingCE, BOOL32 bDisableWhitening, UInt32 *pwFailingPageNum); + Int32 (*WriteMultiplePages)(UInt32 * padwPpn, UInt8* pDBuf, UInt8* pSBuf, UInt16 wNumOfPagesToWrite, BOOL32 boolAligned, BOOL32 boolCorrectBank, UInt16 * pwFailingCE, BOOL32 bDisableWhitening, UInt32 *pwFailingPageNum); + Int32 (*EraseMultiple)(UInt16 *pawPbn, BOOL32 boolAligned, BOOL32 boolCorrectBank, UInt16 *failingCE, UInt32 *failingBlock); + Int32 (*WriteNoECC)(UInt16 wBank, UInt32 nPpn, UInt8 *pDBuf, UInt8 *pSBuf); + Int32 (*WriteMaxECC)(UInt16 wBank, UInt32 nPpn, UInt8 *pDBuf); + void (*CalcCurrentTiming)(void); + void (*Notify)(UInt32 notifyCode); + BOOL32 (*Get2ndBootLoaderInfo)(UInt32 * pdwMax2ndLoaderSize, UInt32 * pdw2ndLoaderPageSize); + UInt32 (*GetDeviceInfo)(UInt32 dwParamType); + void (*SetDeviceInfo)(UInt32 dwParamType, UInt32 dwVal); + void (*SetWhiteningState)(BOOL32 enable); + void (*SetWhiteningMetadataState)(BOOL32 enable); + void (*RegisterCurrentTransaction)(UInt64 ddwLba, UInt32 dwNum, void * pDest); + Int32 (*UpdateFirmware)(UInt16 wCS, UInt8 *pDBuf, UInt32 length); + void (*PerformCommandList)(PPNCommandStruct **commands, UInt32 num_commands); +} LowFuncTbl; + +/*****************************************************************************/ +/* Notification values */ +/*****************************************************************************/ +#define AND_NOTIFY_REFORMAT 1 +#define AND_NOTIFY_RECOVER 2 + +/*****************************************************************************/ +/* Statistics gathering definitions */ +/*****************************************************************************/ +typedef struct _FILStatistics +{ + UInt64 ddwPagesWrittenCnt; + UInt64 ddwPagesReadCnt; + UInt64 ddwBlocksErasedCnt; + UInt64 ddwResetCallCnt; + UInt64 ddwReadWithECCCallCnt; + UInt64 ddwReadMaxECCCallCnt; + UInt64 ddwReadNoECCCallCnt; + UInt64 ddwReadMultipleCallCnt; + UInt64 ddwReadScatteredCallCnt; + UInt64 ddwWriteSingleCallCnt; + UInt64 ddwWriteMaxECCCallCnt; + UInt64 ddwWriteMultipleCallCnt; + UInt64 ddwWriteScatteredCallCnt; + UInt64 ddwSingleEraseCallCnt; + UInt64 ddwMultipleEraseCallCnt; + UInt64 ddwReadCleanCnt; + UInt64 ddwReadECCErrorCnt; + UInt64 ddwReadHWErrorCnt; + UInt64 ddwWriteHWErrCnt; + UInt64 ddwWriteNANDErrCnt; + UInt64 ddwEraseHWErrCnt; + UInt64 ddwEraseNANDErrCnt; + UInt64 addwReadBitFlipsCnt[FIL_MAX_ECC_CORRECTION + 1]; // 0 to max number of corrected bits + UInt64 ddwTimeoutCnt; + UInt64 ddwPartialUECCCnt; + UInt64 ddwPartialCleanCnt; + UInt64 ddwReadRefreshCnt; + UInt64 ddwReadRetireCnt; +} FILStatistics; + +#define FIL_STATISTICS_DESCREPTION { \ + "ddwPagesWrittenCnt", \ + "ddwPagesReadCnt", \ + "ddwBlocksErasedCnt", \ + "ddwResetCallCnt", \ + "ddwReadWithECCCallCnt", \ + "ddwReadMaxECCCallCnt", \ + "ddwReadNoECCCallCnt", \ + "ddwReadMultipleCallCnt", \ + "ddwReadScatteredCallCnt", \ + "ddwWriteSingleCallCnt", \ + "ddwWriteMaxECCCallCnt", \ + "ddwWriteMultipleCallCnt", \ + "ddwWriteScatteredCallCnt", \ + "ddwSingleEraseCallCnt", \ + "ddwMultipleEraseCallCnt", \ + "ddwReadCleanCnt", \ + "ddwReadECCErrorCnt", \ + "ddwReadHWErrorCnt", \ + "ddwWriteHWErrCnt", \ + "ddwWriteNANDErrCnt", \ + "ddwEraseHWErrCnt", \ + "ddwEraseNANDErrCnt", \ + "addwReadBitFlipsCnt[0]", \ + "addwReadBitFlipsCnt[1]", \ + "addwReadBitFlipsCnt[2]", \ + "addwReadBitFlipsCnt[3]", \ + "addwReadBitFlipsCnt[4]", \ + "addwReadBitFlipsCnt[5]", \ + "addwReadBitFlipsCnt[6]", \ + "addwReadBitFlipsCnt[7]", \ + "addwReadBitFlipsCnt[8]", \ + "addwReadBitFlipsCnt[9]", \ + "addwReadBitFlipsCnt[10]", \ + "addwReadBitFlipsCnt[11]", \ + "addwReadBitFlipsCnt[12]", \ + "addwReadBitFlipsCnt[13]", \ + "addwReadBitFlipsCnt[14]", \ + "addwReadBitFlipsCnt[15]", \ + "addwReadBitFlipsCnt[16]", \ + "addwReadBitFlipsCnt[17]", \ + "addwReadBitFlipsCnt[18]", \ + "addwReadBitFlipsCnt[19]", \ + "addwReadBitFlipsCnt[20]", \ + "addwReadBitFlipsCnt[21]", \ + "addwReadBitFlipsCnt[22]", \ + "addwReadBitFlipsCnt[23]", \ + "addwReadBitFlipsCnt[24]", \ + "addwReadBitFlipsCnt[25]", \ + "addwReadBitFlipsCnt[26]", \ + "addwReadBitFlipsCnt[27]", \ + "addwReadBitFlipsCnt[28]", \ + "addwReadBitFlipsCnt[29]", \ + "addwReadBitFlipsCnt[30]", \ + "ddwTimeoutCnt", \ + "ddwPartialUECCCnt", \ + "ddwPartialCleanCnt", \ + "ddwReadRefreshCnt", \ + "ddwReadRetireCnt", \ +} + +// Presented to the FMSS as an 18 word array +typedef struct +{ + UInt32 dwReadNoECCCorrection; + UInt32 adwReadBitFlipsCnt[FIL_MAX_ECC_CORRECTION]; + UInt32 dwReadUncorrectableECCError; +} CSStatistics; + +/*****************************************************************************/ +/* Exported Function Prototype of FIL */ +/*****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +Int32 FIL_Init(void); +void FIL_Close(void); +LowFuncTbl *FIL_GetFuncTbl(void); +BOOL32 FIL_GetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); +BOOL32 FIL_SetStruct(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 dwStructSize); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _FIL_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/FILTypes.h b/drivers/flash_nand/raw/Whimory/Inc/FILTypes.h new file mode 100644 index 0000000..563f0bf --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/FILTypes.h @@ -0,0 +1,62 @@ +#ifndef _FIL_TYPES_H_ +#define _FIL_TYPES_H_ + +#include "ANDTypes.h" + +// physical device info (replacing stDeviceInfo) +typedef struct +{ + UInt32 dwDevID; /* Device ID */ + UInt16 wNumOfCS; /* number of CS */ + UInt16 wBlocksPerCS; /* Number of Blocks */ + UInt16 wPagesPerBlock; /* Pages per block */ + UInt16 wSectorsPerPage; /* Sectors per page */ + UInt16 wSpareBytesPerPage; /* Spare bytes per page */ + UInt16 wBanksPerCS; + UInt16 wDiesPerCS; + UInt16 wBlocksPerDie; + UInt16 wDieStride; + UInt16 wBlockStride; + UInt16 wLastBlock; + UInt16 wUserBlocksPerCS; + + CheckInitialBadType checkInitialBadType; + VendorSpecificType vendorSpecificType; + UInt8 bECCThresholdBits; + UInt8 bECCCorrectableBits; + + // timing + UInt8 bWriteCycleNanosecs; + UInt8 bWriteSetupNanosecs; + UInt8 bWriteHoldNanosecs; + + // read cycle + UInt8 bReadCycleNanosecs; + UInt8 bReadSetupNanosecs; + UInt8 bReadHoldNanosecs; + + // read window + UInt8 bReadDelayNanosecs; + UInt8 bReadValidNanosecs; + + // Additions, to keep above footprint the same + UInt32 wNumOfBusses; /* number of busses */ + UInt32 dwBlocksPerCAU; + UInt32 dwCAUsPerCE; + UInt32 dwSLCPagesPerBlock; + UInt32 dwMLCPagesPerBlock; + UInt32 dwMatchOddEvenCAUs; + UInt32 dwBitsPerCAUAddress; + UInt32 dwBitsPerPageAddress; + UInt32 dwBitsPerBlockAddress; + UInt32 ppn; + UInt32 dwPpnVersion; + UInt32 toggle; + UInt32 dwValidMetaPerLogicalPage; + UInt32 dwTotalMetaPerLogicalPage; + UInt32 dwLogicalPageSize; + UInt32 dwMaxTransactionSize; + UInt8 bAddrBitsForBitsPerCell; +} FILDeviceInfo; + +#endif /* _FIL_TYPES_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/FPart.h b/drivers/flash_nand/raw/Whimory/Inc/FPart.h new file mode 100644 index 0000000..5d38a99 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/FPart.h @@ -0,0 +1,155 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL header file */ +/* FILE : VFL.h */ +/* PURPOSE : This file contains the definition and protypes of exported */ +/* functions for VFL. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 18-JUL-2005 [Jaesung Jung] : first writing */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ + +#ifndef _UNDER_VFL_H_ +#define _UNDER_VFL_H_ +#include "FIL.h" +/*****************************************************************************/ +/* Type definition of checksum (confirm) state */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* exported function prototype of VFL */ +/*****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum +{ + SIGNATURE_STYLE_BLOCKZERO_NOHEADER = 100, + SIGNATURE_STYLE_RESERVEDBLOCK_HEADER = 101, + SIGNATURE_STYLE_NOTSET = 250, +} FPartSignatureStyle; + +// Forward declare VFL +//typedef struct _VFLFunctions VFLFunctions; +struct _VFLFunctions; + +#define FPART_INIT_OPTION_DEV_UNIQUE (1 << 0) +#define FPART_INIT_OPTION_DIAG_CTRL (1 << 1) + +typedef struct +{ +#ifndef AND_READONLY + BOOL32 (*WriteInitialBBT)(void); + Int32 (*FactoryReformat)(BOOL32 Force, BOOL32 boolEraseBlockZero, UInt32 dwBootAreaSize); + BOOL32 (*WriteDeviceUniqueInfo)(UInt8 * pabData, UInt32 dwDataBufferSize); + BOOL32 (*WriteDiagnosticInfo)(UInt8 * pabData, UInt32 dwDataBufferSize); + BOOL32 (*WriteSignature)(void * pvoidSignature, UInt32 dwSignatureSize); + BOOL32 (*WriteSpecialBlock)(void * data, UInt32 data_size, UInt16 type); +#endif // ! AND_READONLY + BOOL32 (*Neuralize)(void); + BOOL32 (*ReadDeviceUniqueInfo)(UInt8 * pabData, UInt32 dwDataBufferSize); + BOOL32 (*ReadDiagnosticInfo)(UInt8 * pabData, UInt32 dwDataBufferSize); + BOOL32 (*VerifyProductionFormat)(void); + BOOL32 (*ReadSignature)(void * pvoidSignature, UInt32 dwSignatureSize); + BOOL32 (*Init)(LowFuncTbl *pFILFunctions, UInt32 dwOptions); + void (*SetSignatureStyle)(void * pvoidFPartFunctions, + FPartSignatureStyle fpartSignatureStyle); + BOOL32 (*validateSignatureLocation)(void * signLocationPtr ); + LowFuncTbl* (*GetLowFuncTbl)(void); + UInt32 (*GetMinorVersion)(void); + BOOL32 (*Format)(struct _VFLFunctions *pVFL, UInt32 dwOptions); + BOOL32 (*AllocateSpecialBlockType)(SpecialBlockAddress *blocks, UInt16 count, UInt16 type); + BOOL32 (*IsSpecialBlockTypeAllocated)(UInt16 type); + BOOL32 (*MapSpecialBlocks)(SpecialBlockAddress *blocks, UInt16 *types, UInt16 *count); + BOOL32 (*ReadSpecialBlock)(void *data, UInt32 data_size, UInt16 type); + void (*ChangeCacheState)(BOOL32 validate); + void* (*GetSingleCommandStruct)(void); // allow vfl and fpart to share single operation struct + void (*Close)(void); +} FPartFunctions; + +void FPart_Register(FPartFunctions * pFPartFunctions); +void PPNFPart_Register(FPartFunctions * pFPartFunctions); + +#define PPN_FPart_MAJOR_VER (0) +FPartFunctions *PPN_FPart_GetFunctions(void); + +BOOL32 VFL_ReadBBT(UInt16 wCS, UInt8 * pBBT); +BOOL32 VFL_ReadBBTWithoutSpecial(UInt16 wCS, UInt8 * pBBT); + +/* + + NAME + _MarkBlockAsBadInBBT + DESCRIPTION + This define marks block as bad in the bbt. + PARAMETERS + pBBT [IN] bbt buffer + idx [IN] block index + RETURN VALUES + none + NOTES + + */ + +#define _MarkBlockAsBadInBBT(pBBT, idx) \ + { \ + UInt16 dByteLocation; \ + UInt8 bBit; \ + dByteLocation = ((UInt16)(idx)) >> 3; \ + bBit = (UInt8)(~(1 << (((UInt8)(idx)) & 0x07))); \ + ((UInt8 *)(pBBT))[dByteLocation] &= bBit; \ + } + +/* + + NAME + _MarkBlockAsGoodInBBT + DESCRIPTION + This define marks block as good in the bbt. + PARAMETERS + pBBT [IN] bbt buffer + idx [IN] block index + RETURN VALUES + none + NOTES + + */ +#define _MarkBlockAsGoodInBBT(pBBT, idx) \ + { \ + UInt16 dByteLocation; \ + UInt8 bBit; \ + dByteLocation = ((UInt16)(idx)) >> 3; \ + bBit = (1 << (((UInt8)(idx)) & 0x07)); \ + ((UInt8 *)(pBBT))[dByteLocation] |= bBit; \ + } + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _UNDER_VFL_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/FTL.h b/drivers/flash_nand/raw/Whimory/Inc/FTL.h new file mode 100644 index 0000000..b3a110e --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/FTL.h @@ -0,0 +1,265 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : FTL */ +/* NAME : FTL header file */ +/* FILE : FTL.h */ +/* PURPOSE : This file contains the definition and protypes of exported */ +/* functions for FTL. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 19-JUL-2005 [Jaesung Jung] : first writing */ +/* */ +/*****************************************************************************/ +#include "VFL.h" +#ifndef _FTL_H_ +#define _FTL_H_ + +/*****************************************************************************/ +/* Return value of FTL_XXX() */ +/*****************************************************************************/ +#define FTL_SUCCESS ANDErrorCodeOk +#define FTL_CRITICAL_ERROR ANDErrorCodeHwErr +#define FTL_USERDATA_ERROR ANDErrorCodeUserDataErr +#define FTL_OUT_OF_RANGE_ERROR ANDErrorCodeOutOfRangeErr +#define FTL_ALIGNMENT_ERROR ANDErrorCodeAlignmentErr + +/*****************************************************************************/ +/* exported function prototype of FTL */ +/*****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct +{ + UInt64 lba; + UInt64 span; +} FTLExtent_t; + + +typedef struct +{ + Int32 (*Init)(VFLFunctions *pVFLFunctions); + Int32 (*Open)(UInt32 *pTotalScts, UInt32 * pdwSectorSize, BOOL32 nandFullFormat, BOOL32 justFormatted, UInt32 minor_ver, UInt32 dwOptions); + + Int32 (*Read)(UInt32 nLpn, UInt32 nNumOfScts, UInt8 *pBuf); + Int32 (*ReadSpans)(FTLExtent_t *extents, UInt32 numExtents, UInt8 *pBuf); + void (*Close)(void); + BOOL32 (*GetStruct)(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize); + +#ifndef AND_READONLY + UInt32 (*ConvertUserMBtoFTLSuperblocks)(VFLFunctions *pVFLFunctions, UInt32 dwUserMBs); + Int32 (*Write)(UInt32 nLpn, UInt32 nNumOfScts, UInt8 *pBuf, BOOL32 isStatic); + Int32 (*Format)(UInt32 dwOptions); + Int32 (*WearLevel)(void); + Int32 (*IdleGC)(); + Int32 (*Unmap)(FTLExtent_t *extents, UInt32 numExtents); + BOOL32 (*GarbageCollect)(void); + BOOL32 (*ShutdownNotify)(BOOL32 boolMergeLogs); + BOOL32 (*Drain)(void); + BOOL32 (*WriteStats)(void); +#endif + + UInt32 (*GetMinorVersion)(void); +} FTLFunctions; + +void FTL_Register(FTLFunctions * pFTLFunctions); +#if (defined (AND_SUPPORT_YAFTL) && AND_SUPPORT_YAFTL) +void YAFTL_Register(FTLFunctions * pFTLFunctions); +#define YAFTL_PPN_MAJOR_VER (0) +FTLFunctions *YAFTL_PPN_Register(void); +#define SFTL_PPN_MAJOR_VER (1) +FTLFunctions *SFTL_PPN_Register(void); +#endif + +/*****************************************************************************/ +/* statistics gathering constants */ +/*****************************************************************************/ + +#define FTL_RC_BIN_SIZE(l) ((l)/FTL_NUM_RC_BINS) +#define FTL_NUM_RC_BINS (100) + +#define FTL_EC_BIN_SIZE (FTL_MAX_EC_BIN_VAL/FTL_NUM_EC_BINS) +#define FTL_MAX_EC_BIN_VAL (5000) +#define FTL_NUM_EC_BINS (100) + +typedef struct +{ + UInt32 maxValue; + UInt32 binCount; + UInt16 usage[0]; +} FTLBinsStruct; + +// FTL statistics X-macro: +// this defines all of the stats currently known to SFTL in key name / serialized +// key number form. Stats users (parsers, savers, etc) define X_FTL_doStat to do +// something meaningful. +// The trivial case is the construction of s_statkey_e enum, which provides to C +// code an enumeration of the key name to the key number. +// A stat saver, for instance, compare a key from a blob to the key macro which +// is currently being expanded; if they match, put into a variable inside a struct +// that matches the name of the stat. +// A parser, on the other hand, would convert the symbol into a C string using +// the # preprocessor operator. It then has a string representation of the key +// name that it can print or add to internal data structures for future use. +// +// Let's dissect the enum creation: +// #undef X_FTL_doStat +// -- this undefines the X macro, in case it was previously defined +// #define X_FTL_doStat(_part, _val) S_STATKEY_ ## _part = (_val), +// -- Each time X_FTL_doStat is invoked below, it will take the token, paste +// -- S_STATKEY_ in front, and assign it the value. For instance, this: +// -- X_FTL_doStat(lbas_read, 1) +// -- becomes: +// -- S_STATKEY_ ## lbas_read = (1), +// -- which is interpreted by the preprocessor to mean: +// -- S_STATKEY_lbas_read = (1), +// -- Thus, we've created an enumeration without repeating the origial content. +// typedef enum { +// FTL_doAllStats +// -- this invokes the X macro for all of the ones in the doAllStats list +// S_STATKEY_VFL = 255, +// S_STATKEY_FIL = 254, +// -- these are special cases +// } s_statkey_e; +// -- and we're done! We now have something that looks like: +// typedef enum { +// S_STATKEY_lbas_read = (1), +// S_STATKEY_lbas_written = (2), +// ... +// S_STATKEY_VFL = 255, +// S_STATKEY_VFL = 254, +// } s_statkey_e; +// The neat part is the knowledge of key name/key number is centralized; +// no repetition is required. + +#undef X_FTL_doStat +#define FTL_doAllStats \ + X_FTL_doStat(lbas_read, 1) \ + X_FTL_doStat(lbas_written, 2) \ + X_FTL_doStat(lbas_gc, 3) \ + X_FTL_doStat(lbas_flatten, 4) \ + X_FTL_doStat(xacts_read, 5) \ + X_FTL_doStat(xacts_write, 6) \ + X_FTL_doStat(data_gc, 7) \ + X_FTL_doStat(zero_valid_cross, 8) \ + X_FTL_doStat(valid_lbas, 9) \ + X_FTL_doStat(free_sb, 10) \ + X_FTL_doStat(data_sb, 11) \ + X_FTL_doStat(cxt_sb, 12) \ + X_FTL_doStat(dead_sb, 13) \ + X_FTL_doStat(boot_count, 14) \ + X_FTL_doStat(refresh_gcs, 15) \ + X_FTL_doStat(readCount_gcs, 16) \ + X_FTL_doStat(wearLev_gcs, 17) \ + X_FTL_doStat(shutdowns, 18) \ + X_FTL_doStat(lbas_read_1, 19) \ + X_FTL_doStat(lbas_read_2, 20) \ + X_FTL_doStat(lbas_read_3, 21) \ + X_FTL_doStat(lbas_read_4, 22) \ + X_FTL_doStat(lbas_read_5, 23) \ + X_FTL_doStat(lbas_read_6, 24) \ + X_FTL_doStat(lbas_read_7, 25) \ + X_FTL_doStat(lbas_read_8, 26) \ + X_FTL_doStat(lbas_read_over_8, 27) \ + X_FTL_doStat(lbas_write_1, 28) \ + X_FTL_doStat(lbas_write_2, 29) \ + X_FTL_doStat(lbas_write_3, 30) \ + X_FTL_doStat(lbas_write_4, 31) \ + X_FTL_doStat(lbas_write_5, 32) \ + X_FTL_doStat(lbas_write_6, 33) \ + X_FTL_doStat(lbas_write_7, 34) \ + X_FTL_doStat(lbas_write_8, 35) \ + X_FTL_doStat(lbas_write_over_8, 36) \ + X_FTL_doStat(L2V_pool_free, 37) \ + X_FTL_doStat(L2V_pool_count, 38) \ + X_FTL_doStat(lbas_written_static, 39) \ + X_FTL_doStat(lbas_written_dynamic, 40) \ + X_FTL_doStat(unclean_boot_count, 41) \ + X_FTL_doStat(span_xacts_read, 42) \ + X_FTL_doStat(span_freebies_read, 43) \ +// blank + +#undef X_FTL_doStat +#define X_FTL_doStat(_part, _val) S_STATKEY_ ## _part = (_val), +typedef enum { + FTL_doAllStats + S_STATKEY_VFL = 255, + S_STATKEY_FIL = 254, +} s_statkey_e; +#undef X_FTL_doStat + +#define FTL_makeStatParser(_fname, _VFLFunc, _FILFunc) \ +void (_fname)(const UInt8 *buf, UInt32 bufSize) \ +{ \ + UInt32 len; \ + UInt32 key, size; \ + UInt32 *buf32; \ + UInt64 val64; \ + \ + if (bufSize < sizeof(len)) \ + return; \ + \ + len = *(UInt32*)buf; \ + buf += sizeof(len); \ + bufSize -= sizeof(len); \ + \ + size = (UInt32)(-2); \ + while (len--) { \ + buf += (size + 2) * sizeof(UInt32); /* for prior round */ \ + bufSize -= (size + 2) * sizeof(UInt32); \ + if (bufSize < ((2 * sizeof(UInt32)) + sizeof(UInt64))) \ + break; \ + /* Load key/size/val */ \ + buf32 = (UInt32*)buf; \ + key = buf32[0]; \ + size = buf32[1]; \ + val64 = *(UInt64*)(&buf32[2]); \ + \ + FTL_doAllStats \ + \ + if ((bufSize - (2 * sizeof(UInt32))) < size) \ + break; \ + \ + /* Got here--wasn't caught be easy filter above, so must be some other blob */ \ + if (0 == key) { \ + buf += sizeof(UInt32); \ + continue; \ + } \ + if (S_STATKEY_VFL == key) { \ + (_VFLFunc)(AND_STRUCT_VFL_STATISTICS, &buf32[2], size*sizeof(UInt32)); \ + continue; \ + } \ + if (S_STATKEY_FIL == key) { \ + (_FILFunc)(AND_STRUCT_VFL_FILSTATISTICS, &buf32[2], size*sizeof(UInt32)); \ + continue; \ + } \ + } \ +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _FTL_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/PPN_FIL.h b/drivers/flash_nand/raw/Whimory/Inc/PPN_FIL.h new file mode 100644 index 0000000..21869bb --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/PPN_FIL.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _PPN_FIL_H_ +#define _PPN_FIL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "FILTypes.h" + +typedef UInt8 PPNStatusType; +#define PPN_READ_STATUS_INVALID_DATA (((PPNStatusType)1) << 0) +#define PPN_READ_STATUS_REFRESH (((PPNStatusType)1) << 1) +#define PPN_READ_STATUS_RETIRE (((PPNStatusType)1) << 2) +#define PPN_READ_STATUS_CLEAN (((PPNStatusType)1) << 3) +#define PPN_READ_STATUS_GEB (((PPNStatusType)1) << 4) +#define PPN_READ_STATUS_VALID (((PPNStatusType)1) << 6) +#define PPN_READ_STATUS_WRONG_BITS_PER_CELL (((PPNStatusType)1) << 7) + +#define PPN_OTHERS_STATUS_OP_FAILED (((PPNStatusType)1) << 0) +#define PPN_OTHERS_STATUS_NOT_SUPPORTED (((PPNStatusType)1) << 2) +#define PPN_OTHERS_STATUS_GEB (((PPNStatusType)1) << 4) +#define PPN_OTHERS_STATUS_VALID (((PPNStatusType)1) << 6) + +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM +#define PPN_PROGRAM_STATUS_FAIL (((PPNStatusType)1) << 0) +#define PPN_PROGRAM_STATUS_NOT_PROGRAMMED (((PPNStatusType)1) << 2) + +#define PPN_PROGRAM_STATUS_GEB (((PPNStatusType)1) << 4) + +#define PPN_ERASE_STATUS_FAIL (((PPNStatusType)1) << 0) +#define PPN_ERASE_STATUS_RETIRE (((PPNStatusType)1) << 2) +#define PPN_ERASE_STATUS_GEB (((PPNStatusType)1) << 4) +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM + +typedef UInt32 PPNOptions; +#define PPN_OPTIONS_REPORT_HEALTH (((UInt32)1) << 0) +#define PPN_OPTIONS_GET_PAGE_RMA_INFO (((UInt32)1) << 1) + +// simulator debug options (allocate from the end) +#if (defined (AND_SIMULATOR) && AND_SIMULATOR) +#define PPN_OPTIONS_IGNORE_BAD_BLOCK (((UInt32)1) << 31) +#define PPN_OPTIONS_GENERATE_BAD_BLOCK (((UInt32)1) << 30) +#define PPN_OPTIONS_TAKE_SNAPSHOT (((UInt32)1) << 29) +#else +#define PPN_OPTIONS_IGNORE_BAD_BLOCK (0) // do not set any bits if we are running outside the simulator +#define PPN_OPTIONS_GENERATE_BAD_BLOCK (0) // do not set any bits if we are running outside the simulator +#define PPN_OPTIONS_TAKE_SNAPSHOT (0) // do not set any bits if we are running outside the simulator +#endif + +#define PPN_NO_OPTIONS (0) + +typedef UInt32 PPNCommand; +#define PPN_COMMAND_NONE (0UL) +#define PPN_COMMAND_READ (1UL) +#if !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM || WMR_IBOOT_WRITE_ENABLE +#define PPN_COMMAND_PROGRAM (2UL) +#define PPN_COMMAND_ERASE (3UL) +#endif // !(defined(AND_READONLY)) || AND_SUPPORT_NVRAM +#define PPN_COMMAND_CAUBBT (4UL) + +#define PPN_MAX_CES_PER_BUS 2 +#define PPN_MAX_PAGES_PER_CE 128 +#define PPN_MAX_PAGES 128 + +#define PPN_MAX_MEM_BUFFERS 256 + +#define PPN_VERSION_1_0_0 (0x00010000) +#define PPN_VERSION_1_0_3 (0x00010003) +#define PPN_VERSION_1_5_0 (0x00010500) +#define PPN_VERSION_2_0_0 (0x00020000) +#define PPN_VERSION_ERROR (0x00FEFEFE) +#define PPN_VERSION_BAD_FW (0x00FFFFFF) +#define PPN_VERSION_UNSUPPORTED PPN_VERSION_2_0_0 + +typedef UInt16 ChipEnableType; +typedef UInt8 ChipEnableIndexType; +typedef UInt32 PageAddressType; + +typedef struct +{ + UInt16 length; + UInt16 column; + PageAddressType row; +} RowColLenAddressType; + +typedef struct +{ + FILDeviceInfo *device_info; + void *handle; //opaque to caller + // at least for now, i am adding a bus identifier + UInt16 bus_num; +} BusContext; + +typedef struct +{ + UInt16 offset; // offset inside the mem_entry + UInt8 idx; // what mem entry this is in +} PPNMemoryIndex; + +typedef struct +{ + void *data; + void *meta; + UInt16 num_of_lbas; // lba is a 4KB chunk - limited to 255 entries +} PPNMemoryEntry; + +typedef struct +{ + ChipEnableType ce; + UInt16 pages; + UInt16 offset; +} PPNCommandCeInfo; + +typedef struct +{ + RowColLenAddressType addr; + ChipEnableIndexType ceIdx; + UInt8 lbas; + PPNStatusType status; +} PPNCommandEntry; + +typedef struct +{ + // This section is shared between the A8/A9 and the IOP. + + PPNCommand command; + PPNOptions options; + UInt16 num_pages; + UInt16 lbas; + PPNStatusType page_status_summary; // logical OR of all page statuses + + PPNCommandCeInfo ceInfo[PPN_MAX_CES_PER_BUS]; + PPNCommandEntry entry[PPN_MAX_PAGES]; + + // This section is used by the A8/A9 only + + BusContext context; + + PPNMemoryIndex mem_index[PPN_MAX_PAGES]; + PPNMemoryEntry mem_buffers[PPN_MAX_MEM_BUFFERS]; + UInt16 mem_buffers_count; +} PPNCommandStruct; + +typedef struct +{ + UInt16 channel; + ChipEnableIndexType chip_enable_idx; + ChipEnableType physical_chip_enable; +} PPNChipEnableStruct; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PPN_FIL_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/VFL.h b/drivers/flash_nand/raw/Whimory/Inc/VFL.h new file mode 100644 index 0000000..3afa0a1 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/VFL.h @@ -0,0 +1,171 @@ +/*****************************************************************************/ +/* */ +/* COMPONENT : Rainbow */ +/* MODULE : Virtual Flash Layer */ +/* NAME : VFL header file */ +/* FILE : VFL.h */ +/* PURPOSE : This file contains the definition and protypes of exported */ +/* functions for VFL. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 18-JUL-2005 [Jaesung Jung] : first writing */ +/* 31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling */ +/* */ +/*****************************************************************************/ + +#ifndef _VFL_H_ +#define _VFL_H_ +#include "FPart.h" +#include "VFLBuffer.h" + +/*****************************************************************************/ +/* Return value of VFL_XXX() */ +/*****************************************************************************/ +#define VFL_SUCCESS ANDErrorCodeOk +#define VFL_SUCCESS_CLEAN ANDErrorCodeCleanOk +#define VFL_CRITICAL_ERROR ANDErrorCodeHwErr +#define VFL_U_ECC_ERROR ANDErrorCodeUserDataErr + +/*****************************************************************************/ +/* Type definition of checksum (confirm) state */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* exported function prototype of VFL */ +/*****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define VFL_SPANS_MAX (128) + +// read result flags - 32 Bit +#define VFL_READ_STATUS_REFRESH (1 << 0) +#define VFL_READ_STATUS_RETIRE (1 << 1) +#define VFL_READ_STATUS_UECC (1 << 2) // UECC = invalid data TRUE and clean FALSE +#define VFL_READ_STATUS_CLEAN (1 << 3) // UECC = invalid data TRUE and clean TRUE +#define VFL_READ_STATUS_VALID_DATA (1 << 4) // at least one of the pages had valid data +#define VFL_READ_STATUS_UNIDENTIFIED (1 << 5) // at least one status was something we do not expect +#define VFL_READ_STATUS_ERRS (VFL_READ_STATUS_UECC | VFL_READ_STATUS_RETIRE | VFL_READ_STATUS_REFRESH) +#define VFL_READ_STATUS_ALL (0xFFFFFFFF) + +typedef UInt32 VFLReadStatusType; + +typedef void (*VFL_ReadSpansCB_t)(UInt32 vba, VFLReadStatusType status, UInt8 *meta); +typedef struct +{ + BOOL32 bDisableWhitening; + BOOL32 bMarkECCForScrub; + UInt32 vba[VFL_SPANS_MAX]; + UInt32 count[VFL_SPANS_MAX]; + UInt8 *data[VFL_SPANS_MAX]; + UInt8 *meta[VFL_SPANS_MAX]; + UInt32 len; + VFL_ReadSpansCB_t cb; + UInt32 cbOpt; + VFLReadStatusType op_status; +} VFL_ReadSpans_t; + +typedef struct _VFLFunctions +{ +#ifndef AND_READONLY + Int32 (*Format)(UInt32 dwBootAreaSize, UInt32 dwOptions); + BOOL32 (*AllocateSpecialBlock)(SpecialBlockAddress *allocated_block, UInt16 type); + Int32 (*WriteSinglePage)(UInt32 nVpn, Buffer *pBuf, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening); + Int32 (*Erase)(UInt16 wVbn, BOOL32 bReplaceOnFail); + Int32 (*ChangeFTLCxtVbn)(UInt16 *aFTLCxtVbn); + BOOL32 (*WriteMultiplePagesInVb) + (UInt32 dwVpn, UInt16 wNumPagesToWrite, + UInt8 * pbaData, UInt8 * pbaSpare, BOOL32 boolReplaceBlockOnFail, BOOL32 bDisableWhitening); + BOOL32 (*MarkBlockAsGrownBad)(SpecialBlockAddress *allocated_block); + +#if AND_SUPPORT_BLOCK_BORROWING + BOOL32 (*BorrowSpareBlock)(UInt32 *pdwPhysicalCE, UInt32 *pdwPhysicalBlock, UInt16 wType); +#endif //AND_SUPPORT_BLOCK_BORROWING + + BOOL32 (*ProgramMultipleVbas)(UInt32 vba, UInt16 count, UInt8 *data, UInt8 *meta, + BOOL32 replaceOnPfail, BOOL32 disableWhitening); +#endif // ! AND_READONLY + + Int32 (*Init)(FPartFunctions * pFPartFunctions); + Int32 (*Open)(UInt32 dwBootAreaSize, UInt32 minor_ver, UInt32 dwOptions); + void (*Close)(void); + BOOL32 (*ReadMultiplePagesInVb) + (UInt16 wVbn, UInt16 wStartPOffset, + UInt16 wNumPagesToRead, + UInt8 * pbaData, + UInt8 * pbaSpare, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening); + BOOL32 (*ReadScatteredPagesInVb) + (UInt32 * padwVpn, + UInt16 wNumPagesToRead, + UInt8 * pbaData, UInt8 * pbaSpare, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening, Int32 *actualStatus); + Int32 (*ReadSinglePage)(UInt32 nVpn, Buffer *pBuf, + BOOL32 bCleanCheck, + BOOL32 bMarkECCForScrub, + BOOL32 * pboolNeedRefresh, + UInt8 * pabSectorStats, + BOOL32 bDisableWhitening); + UInt16* (*GetFTLCxtVbn)(void); + BOOL32 (*GetStruct)(UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 * pdwStructSize); + BOOL32 (*SetStruct)(UInt32 dwStructType, + void * pvoidStructBuffer, + UInt32 dwStructSize); + + UInt32 (*GetDeviceInfo)(UInt32 dwParamType); + UInt32 (*GetMinorVersion)(void); + UInt16 (*GetVbasPerVb)(UInt16 wVbn); + + + // new func - read + VFLReadStatusType (*ReadMultipleVbas)(UInt32 vba, UInt16 count, UInt8 *data, UInt8 *meta, + BOOL32 bDisableWhitening, BOOL32 bMarkECCForScrub); + + void (*ReadSpansInit)(VFL_ReadSpans_t *s, VFL_ReadSpansCB_t cb, UInt32 cbOpt, BOOL32 bDisableWhitening, BOOL32 bMarkECCForScrub); + void (*ReadSpansAdd)(VFL_ReadSpans_t *s, UInt32 vba, UInt32 count, UInt8 *data, UInt8 *meta); + VFLReadStatusType (*ReadSpans)(VFL_ReadSpans_t *s); + +} VFLFunctions; + +void VSVFL_Register(VFLFunctions * pVFL_Functions); +void VFL_Register(VFLFunctions * pVFL_Functions); +void PPNVFL_Register(VFLFunctions * pVFL_Functions); + +#define PPN_VFL_MAJOR_VER (1) +VFLFunctions * PPN_VFL_GetFunctions(void); +#define PPN_SVFL_MAJOR_VER (2) +VFLFunctions * PPN_SVFL_GetFunctions(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _VFL_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/WMRConfig.h b/drivers/flash_nand/raw/Whimory/Inc/WMRConfig.h new file mode 100644 index 0000000..477ffda --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/WMRConfig.h @@ -0,0 +1,97 @@ +/*****************************************************************************/ +/* */ +/* PROJECT : Rainbow */ +/* MODULE : Whimory configuration definition heade file */ +/* NAME : Whimory configuration definition */ +/* FILE : WMRConfig.h */ +/* PURPOSE : Configuation definition for Whimory */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* COPYRIGHT 2003-2005, SAMSUNG ELECTRONICS CO., LTD. */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Permission is hereby granted to licensees of Samsung Electronics */ +/* Co., Ltd. products to use or abstract this computer program for the */ +/* sole purpose of implementing a product based on Samsung */ +/* Electronics Co., Ltd. products. No other rights to reproduce, use, */ +/* or disseminate this computer program, whether in part or in whole, */ +/* are granted. */ +/* */ +/* Samsung Electronics Co., Ltd. makes no representation or warranties */ +/* with respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* REVISION HISTORY */ +/* */ +/* 12-JUL-2005 [Jaesung Jung] : first writing */ +/* 03-NOV-2005 [Yangsup Lee ] : Add wear-leveling algorithm */ +/* */ +/*****************************************************************************/ + +#ifndef _WMR_CONFIG_H_ +#define _WMR_CONFIG_H_ + +#include "WMRFeatures.h" + +#if (defined (AND_SUPPORT_2ND_BOOTLOADER) && AND_SUPPORT_2ND_BOOTLOADER && defined (AND_SIGNATURE_IN_BLOCK_ZERO) && AND_SIGNATURE_IN_BLOCK_ZERO) +#error "AND_SUPPORT_2ND_BOOTLOADER & AND_SIGNATURE_IN_BLOCK_ZERO can't both be defined" +#endif + +/*****************************************************************************/ +/* Global Config Definition which should be shared by FTL, VFL, FIL */ +/*****************************************************************************/ +#define WMR_BOOT_AREA_DEFAULT_SIZE (1) /* this will be value used unless unit does boot-from-nand */ +#define AND_MAX_BANKS_PER_CS (8) +#define WMR_SECTOR_SIZE (512) /* the size of sector */ +#if defined(AND_SUPPORT_YAFTL) && AND_SUPPORT_YAFTL +#define WMR_NUM_BUFFERS (10) /* the number of buffers - used by VFLBuffer */ +#else /* defined(AND_SUPPORT_YAFTL) && AND_SUPPORT_YAFTL */ +#if !(defined(AND_READONLY) && AND_READONLY) +#define WMR_NUM_BUFFERS (5) /* the number of buffers - used by VFLBuffer */ +#elif !(defined(WMR_DISABLE_FTL_RECOVERY) && WMR_DISABLE_FTL_RECOVERY) || \ + (defined(AND_COLLECT_STATISTICS) && AND_COLLECT_STATISTICS) +#define WMR_NUM_BUFFERS (2) /* the number of buffers - used by VFLBuffer */ +#else +#define WMR_NUM_BUFFERS (1) /* Used in _FTLRead and VFL_Open */ +#endif +#endif /* defined(AND_SUPPORT_YAFTL) && AND_SUPPORT_YAFTL */ + +#define WMR_SECTORS_PER_PAGE_MIN (4) + +#define WMR_MAX_PAGES_PER_BLOCK (0x100) + +#define WMR_MAX_VB (18000) /* the maximum number of virtual block*/ + +#define WMR_MAX_RESERVED_SIZE (820) /* the maximum count of reserved blocks */ + +#define FTL_METAWEARLEVEL_RATIO (10) // consider bringing this number up +#define WMR_WEAR_LEVEL_FREQUENCY (20) +#define WMR_WEAR_LEVEL_FREQUENCY_DELAY (300) +#define WMR_WEAR_LEVEL_MAX_DIFF (5) +#define WMR_WEAR_LEVEL_MIN_EC_VALUE (3) + +#define DEFAULT_NUMBER_OF_SPECIAL_BLOCKS_CS0 (3) +#define NUMBER_OF_SPECIAL_BLOCKS_NOTCS0 (2) + +#define FTL_READ_REFRESH_LIST_SIZE (5) +#define FTL_RC_TRESHOLD (10000) // to review for real world drivers +#define FTL_READS_SINCE_LAST_REFRESH_MARK_TRASHOLD (200) + +#define YAFTL_RC_THRESHOLD (0xfffd) +#define YAFTL_RC_MULTIPLIER (16) + +#define S_RC_THRESHOLD (250000) + +#define BYTES_PER_METADATA_RAW (12) + +#define VSVFL_USER_BLKS_PER_1K (976) +#define PPNVFL_USER_BLKS_PER_256B (244) +#define VFL_USER_BLKS_PER_1K (968) +#define FTL_CXT_SECTION_SIZE (3) // number of FTL Cxt locations are saved by VFL +#define WMR_BLOCK_ADDRESS_MSB (1<<15) + +#endif /* _WMR_CONFIG_H_ */ diff --git a/drivers/flash_nand/raw/Whimory/Inc/WMRTest.h b/drivers/flash_nand/raw/Whimory/Inc/WMRTest.h new file mode 100644 index 0000000..6c190f5 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Inc/WMRTest.h @@ -0,0 +1,22 @@ +// Copyright (C) 2009 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// + +#include "WMRTypes.h" +#include "FTL.h" +#include "VFL.h" +#include "FIL.h" + +BOOL32 FIL_Test(void); + +BOOL32 WMR_FTL_Test(FTLFunctions *ftl); +BOOL32 WMR_VFL_Test(VFLFunctions *vfl); +BOOL32 WMR_FIL_Test(LowFuncTbl *fil); +BOOL32 WMR_FPart_Test(FPartFunctions *fpart); diff --git a/drivers/flash_nand/raw/Whimory/Test/FILTest.c b/drivers/flash_nand/raw/Whimory/Test/FILTest.c new file mode 100644 index 0000000..b305375 --- /dev/null +++ b/drivers/flash_nand/raw/Whimory/Test/FILTest.c @@ -0,0 +1,901 @@ +// Copyright (C) 2009 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// +// +#include "WMROAM.h" +#include "FIL.h" +#include "WMRTest.h" +#include "WMRConfig.h" +#include "WMRBuf.h" + +#define AND_MAX_BANKS (AND_MAX_BANKS_PER_CS * 32) +#define TEST_DATA_WATERMARK (0xB6) +#define TEST_META_WATERMARK (0xC7) +#define TEST_STATS_WATERMARK (0xD8) + +// Static function definitions +static BOOL32 FILInterfaceTest(UInt16 *blockList); +static BOOL32 InitTestInfo(void); +static const char* FILErrorToString(Int32 filStatus); +static void InitPageListFromBlocks(const UInt16 *blockList, UInt32 *pageList); +static void FillBufferWithCountingPattern(UInt32 *buffer, UInt32 startValue, UInt32 bytes); +static void FillMetaBufferWithPattern(UInt8 *buffer, UInt32 startValue, UInt32 numPages); +static void FILTestHexdump(void *data, UInt32 length); + +// Static variables + +typedef struct +{ + UInt32 pagesPerBlock; + UInt32 numBanks; + UInt32 numCE; + UInt32 bytesPerPage; + UInt32 bytesPerSpare; + UInt32 bufferBytesPerMeta; + UInt32 validBytesPerMeta; + UInt32 bootPageBytes; + UInt32 correctableSectorsPerPage; +} FILTestInfo; + +static FILTestInfo testInfo; +static LowFuncTbl *pFIL = NULL; +static WMR_BufZone_t bufZone; + + +// Public functions +BOOL32 FIL_Test(void) +{ + UInt16 blockList[AND_MAX_BANKS] = { 0 }; + + WMR_BufZone_Init(&bufZone); + + InitTestInfo(); + + return FILInterfaceTest(blockList); +} + +// Local functions + +BOOL32 InitTestInfo(void) +{ + + pFIL = FIL_GetFuncTbl(); + + testInfo.pagesPerBlock = pFIL->GetDeviceInfo(AND_DEVINFO_PAGES_PER_BLOCK); + WMR_ASSERT(testInfo.pagesPerBlock > 0); + testInfo.numBanks = pFIL->GetDeviceInfo(AND_DEVINFO_NUM_OF_BANKS); + WMR_ASSERT(testInfo.numBanks > 0); + testInfo.numCE = pFIL->GetDeviceInfo(AND_DEVINFO_NUM_OF_CS); + WMR_ASSERT(testInfo.numCE > 0); + testInfo.bytesPerPage = pFIL->GetDeviceInfo(AND_DEVINFO_BYTES_PER_PAGE); + WMR_ASSERT(testInfo.bytesPerPage > 0); + testInfo.bytesPerSpare = pFIL->GetDeviceInfo(AND_DEVINFO_BYTES_PER_SPARE); + WMR_ASSERT(testInfo.bytesPerSpare > 0); + testInfo.bufferBytesPerMeta = 12; + testInfo.validBytesPerMeta = 10; + testInfo.bootPageBytes = pFIL->GetDeviceInfo(AND_DEVINFO_BYTES_PER_BL_PAGE); + WMR_ASSERT(testInfo.bootPageBytes > 0); + testInfo.correctableSectorsPerPage = testInfo.bytesPerPage / pFIL->GetDeviceInfo(AND_DEVINFO_CORRECTABLE_SIZE); + WMR_ASSERT(testInfo.correctableSectorsPerPage > 0); + + return TRUE32; +} + +static BOOL32 TestBootloaderBlock(UInt32 ce, UInt32 block, UInt8 *writeDataBuffer, UInt8 *verifyDataBuffer) +{ + UInt32 base_page = block * testInfo.pagesPerBlock; + Int32 andStatus; + UInt32 testSeed = 1234567890; + UInt32 offset; + + // Erase block + WMR_PRINT(ALWAYS, "Erasing CE %d Block %d\n", ce, block); + andStatus = pFIL->Erase(ce, block); + + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Erase failed with %s\n", FILErrorToString(andStatus)); + return FALSE32; + } + + for (offset = 0; offset < testInfo.pagesPerBlock; ++offset) + { + const UInt32 page = base_page + offset; + // Read bootloader page and verify clean + WMR_ASSERT(pFIL->ReadBLPage != NULL); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_PRINT(ALWAYS, "Using ReadBL for clean detect CE %d Page %d\n", (UInt32) ce, page); + andStatus = pFIL->ReadBLPage(ce, page, verifyDataBuffer); + + if (FIL_SUCCESS_CLEAN != andStatus) + { + WMR_PRINT(ALWAYS, "ReadBL Clean Detect failed with %s\n", FILErrorToString(andStatus)); + return FALSE32; + } + + // Write bootloader page + WMR_ASSERT(pFIL->WriteBLPage != NULL); + WMR_PRINT(ALWAYS, "Writing CE %d Page %d\n", (UInt32) ce, page); + FillBufferWithCountingPattern((UInt32*)writeDataBuffer, testSeed++, testInfo.bootPageBytes); + andStatus = pFIL->WriteBLPage(ce, page, writeDataBuffer); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Write failed with %s\n", FILErrorToString(andStatus)); + return FALSE32; + } + + // Read back and verify + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bootPageBytes); + WMR_PRINT(ALWAYS, "ReadBL CE %d Page %d\n", (UInt32) ce, page); + + andStatus = pFIL->ReadBLPage(ce, page, verifyDataBuffer); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "ReadBL readback failed with %s\n", FILErrorToString(andStatus)); + return FALSE32; + } + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.bootPageBytes)) + { + WMR_PRINT(ALWAYS, "Read back contents of boot page failed comparison\n"); + return FALSE32; + } + } + + return TRUE32; +} + +// Block list is assumed to be numBanks long and non-overlapping banks +BOOL32 FILInterfaceTest(UInt16 *blockList) +{ + UInt8 *writeDataBuffer = NULL; + UInt8 *writeMetaBuffer = NULL; + UInt8 *verifyDataBuffer = NULL; + UInt8 *verifyMetaBuffer = NULL; + Int32 andStatus; + UInt32 pageList[2 * AND_MAX_BANKS]; + UInt16 ceList[AND_MAX_BANKS] = { 0 }; + UInt8 *sectorStats = NULL; + UInt32 testSeed = 1234567890; + UInt16 bankIdx; + const UInt32 dataBufferSize = 2 * testInfo.numBanks * testInfo.bytesPerPage; + const UInt32 metaBufferSize = 2 * testInfo.numBanks * testInfo.bytesPerSpare; + const UInt32 sectorStatsSize = 2 * testInfo.numBanks * testInfo.correctableSectorsPerPage; + + + InitPageListFromBlocks(blockList, pageList); + + WMR_PRINT(ALWAYS, "Starting FIL Interface Test\n"); + + writeMetaBuffer = WMR_MALLOC(metaBufferSize); + verifyMetaBuffer = WMR_MALLOC(metaBufferSize); + sectorStats = WMR_MALLOC(sectorStatsSize); + writeDataBuffer = WMR_Buf_Alloc_ForDMA(&bufZone, dataBufferSize); + verifyDataBuffer = WMR_Buf_Alloc_ForDMA(&bufZone, dataBufferSize); + + WMR_BufZone_FinishedAllocs(&bufZone); + + WMR_BufZone_Rebase(&bufZone, (void **)&writeDataBuffer); + WMR_BufZone_Rebase(&bufZone, (void **)&verifyDataBuffer); + + if (!writeDataBuffer || !writeMetaBuffer || !verifyDataBuffer || !verifyMetaBuffer || !sectorStats) + { + WMR_PANIC("Buffer allocations failed"); + goto test_failed; + } + + WMR_BufZone_FinishedRebases(&bufZone); + + // Enable whitening if available + if (pFIL->SetWhiteningState) { + pFIL->SetWhiteningState(TRUE32); + } + if (pFIL->RegisterCurrentTransaction) { + pFIL->RegisterCurrentTransaction(0,0, NULL); + } + + WMR_ASSERT(TestBootloaderBlock(0, 16, writeDataBuffer, verifyDataBuffer)); + + // Erase Block + WMR_ASSERT(pFIL->Erase != NULL); + WMR_PRINT(ALWAYS, "Erasing CE %d Block %d\n", (UInt32) ceList[0], (UInt32) blockList[0]); + andStatus = pFIL->Erase(ceList[0], blockList[0]); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Erase failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Clean check single page + WMR_ASSERT(pFIL->ReadWithECC != NULL); + WMR_PRINT(ALWAYS, "Clean checking CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.bytesPerSpare); + andStatus = pFIL->ReadWithECC(ceList[0], pageList[0], verifyDataBuffer, verifyMetaBuffer, NULL, NULL, FALSE32); + + if (FIL_SUCCESS_CLEAN != andStatus) + { + WMR_PRINT(ALWAYS, "Clean Detect failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Verify ReadNoECC on that page + // XXX put guard bytes at end of buffer to make sure the right number of bytes are read + WMR_ASSERT(pFIL->ReadNoECC != NULL); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.bytesPerSpare); + WMR_PRINT(ALWAYS, "ReadNoECC on clean CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + andStatus = pFIL->ReadNoECC(ceList[0], pageList[0], verifyDataBuffer, verifyMetaBuffer); + + if (FIL_UNSUPPORTED_ERROR == andStatus) + { + WMR_PRINT(ALWAYS, "WARNING: ReadNoECC is unsupported on this platform - formatting will not work\n"); + } + else if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "ReadNoECC failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + else + { + WMR_MEMSET(writeDataBuffer, 0xFF, testInfo.bytesPerPage); + WMR_MEMSET(writeMetaBuffer, 0xFF, testInfo.bytesPerSpare); + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.bytesPerPage)) + { + WMR_PRINT(ALWAYS, "ReadNoECC failed all 1's comparison in data section\n"); + goto test_failed; + } + + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, testInfo.bytesPerSpare)) + { + WMR_PRINT(ALWAYS, "ReadNoECC failed all 1's comparison in spare section\n"); + goto test_failed; + } + } + + + // Clean check multiple pages + WMR_ASSERT(pFIL->ReadScatteredPages != NULL); + InitPageListFromBlocks(blockList, pageList); + // Pick two consecutive pages from the same block + pageList[1] = pageList[testInfo.numBanks]; + ceList[0] = 0; + ceList[1] = 0; + WMR_PRINT(ALWAYS, "Clean checking CE %d Page %d & %d\n", (UInt32) ceList[0], pageList[0], pageList[1]); + andStatus = pFIL->ReadScatteredPages(ceList, pageList, verifyDataBuffer, verifyMetaBuffer, 2, NULL, NULL, FALSE32); + + if (FIL_SUCCESS_CLEAN != andStatus) + { + WMR_PRINT(ALWAYS, "Multi-page clean detect failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Program first page + WMR_ASSERT(pFIL->Write != NULL); + WMR_PRINT(ALWAYS, "Writing CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + FillBufferWithCountingPattern((UInt32*)writeDataBuffer, testSeed++, testInfo.bytesPerPage); + FillMetaBufferWithPattern(writeMetaBuffer, testSeed++, 1); + andStatus = pFIL->Write(ceList[0], pageList[0], writeDataBuffer, writeMetaBuffer, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Write failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Read back and verify + WMR_PRINT(ALWAYS, "Reading back CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.bufferBytesPerMeta); + andStatus = pFIL->ReadWithECC(ceList[0], pageList[0], verifyDataBuffer, verifyMetaBuffer, NULL, NULL, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Read back failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, testInfo.bufferBytesPerMeta)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in meta section\n"); + goto test_failed; + } + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.bytesPerPage)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in data section\n"); + goto test_failed; + } + + + // Verify ReadNoECC finds non-FF data + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.bytesPerSpare); + WMR_PRINT(ALWAYS, "ReadNoECC on written CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + andStatus = pFIL->ReadNoECC(ceList[0], pageList[0], verifyDataBuffer, verifyMetaBuffer); + + if (FIL_UNSUPPORTED_ERROR == andStatus) + { + WMR_PRINT(ALWAYS, "WARNING: ReadNoECC is unsupported on this platform - formatting will not work\n"); + } + else if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "ReadNoECC failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + else + { + WMR_MEMSET(writeDataBuffer, 0xFF, testInfo.bytesPerPage); + WMR_MEMSET(writeMetaBuffer, 0xFF, testInfo.bytesPerSpare); + + if (!WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, testInfo.bytesPerSpare)) + { + WMR_PRINT(ALWAYS, "ReadNoECC read all 1's on a programmed page in meta section\n"); + goto test_failed; + } + + if (!WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.bytesPerPage)) + { + WMR_PRINT(ALWAYS, "ReadNoECC read all 1's on a programmed page in data section\n"); + goto test_failed; + } + } + + + // Read programmed + clean multiple, verify UECC status + InitPageListFromBlocks(blockList, pageList); + // Pick two consecutive pages from the same block + pageList[1] = pageList[testInfo.numBanks]; + ceList[0] = 0; + ceList[1] = 0; + WMR_PRINT(ALWAYS, "Multi-page clean checking mixed CE %d Page %d & %d\n", (UInt32) ceList[0], pageList[0], pageList[1]); + andStatus = pFIL->ReadScatteredPages(ceList, pageList, verifyDataBuffer, verifyMetaBuffer, 2, NULL, NULL, FALSE32); + + if (FIL_U_ECC_ERROR != andStatus) + { + WMR_PRINT(ALWAYS, "Multi-page clean checking mixed detect failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Over-program the first page to induce real UECC + WMR_PRINT(ALWAYS, "Over-programming CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + WMR_MEMSET(writeDataBuffer, 0xA5, testInfo.bytesPerPage); + WMR_MEMSET(writeDataBuffer, 0xA5, testInfo.validBytesPerMeta); + andStatus = pFIL->Write(ceList[0], pageList[0], writeDataBuffer, writeMetaBuffer, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Write failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Read back and verify UECC + WMR_PRINT(ALWAYS, "Reading back expecting UECC on CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.bufferBytesPerMeta); + andStatus = pFIL->ReadWithECC(ceList[0], pageList[0], writeDataBuffer, writeMetaBuffer, NULL, NULL, FALSE32); + + if (FIL_U_ECC_ERROR != andStatus) + { + WMR_PRINT(ALWAYS, "Read with expected UECC failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Program second page + WMR_PRINT(ALWAYS, "Writing CE %d Page %d\n", (UInt32) ceList[1], pageList[1]); + FillBufferWithCountingPattern((UInt32*)writeDataBuffer, testSeed++, testInfo.bytesPerPage); + FillMetaBufferWithPattern(writeMetaBuffer, testSeed++, 1); + andStatus = pFIL->Write(ceList[1], pageList[1], writeDataBuffer, writeMetaBuffer, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Write failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + + // Read back and verify + WMR_PRINT(ALWAYS, "Reading back CE %d Page %d\n", (UInt32) ceList[1], pageList[1]); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.bufferBytesPerMeta); + andStatus = pFIL->ReadWithECC(ceList[1], pageList[1], verifyDataBuffer, verifyMetaBuffer, NULL, NULL, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Read back failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, testInfo.bufferBytesPerMeta)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in meta section\n"); + goto test_failed; + } + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.bytesPerPage)) + { + WMR_PRINT(ALWAYS, "Read back contents failed comparison in data section\n"); + goto test_failed; + } + + + // Read first + second pages and verify UECC status + // Also make sure that reading did not stop on first UECC + WMR_PRINT(ALWAYS, "Multi-page clean checking mixed CE %d Page %d & %d\n", (UInt32) ceList[0], pageList[0], pageList[1]); + + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, 2 * testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, 2 * testInfo.bufferBytesPerMeta); + + andStatus = pFIL->ReadScatteredPages(ceList, pageList, verifyDataBuffer, verifyMetaBuffer, 2, NULL, NULL, FALSE32); + + if (FIL_U_ECC_ERROR != andStatus) + { + WMR_PRINT(ALWAYS, "Multi-page uecc checking mixed detect failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Verify that the read continued after UECC (compare last buffer written versus the second page) + + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer + testInfo.bufferBytesPerMeta, testInfo.bufferBytesPerMeta)) + { + WMR_PRINT(ALWAYS, "Read back contents of second page failed comparison in meta section\n"); + goto test_failed; + } + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer + testInfo.bytesPerPage, testInfo.bytesPerPage)) + { + WMR_PRINT(ALWAYS, "Read back contents of second page failed comparison in data section\n"); + goto test_failed; + } + + // Erase block + WMR_PRINT(ALWAYS, "Erasing CE %d Block %d\n", (UInt32) ceList[0], (UInt32) blockList[0]); + andStatus = pFIL->Erase(ceList[0], blockList[0]); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Erase failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Read bootloader page and verify clean + WMR_ASSERT(pFIL->ReadBLPage != NULL); + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bytesPerPage); + WMR_PRINT(ALWAYS, "Using ReadBL for clean detect CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + andStatus = pFIL->ReadBLPage(ceList[0], pageList[0], verifyDataBuffer); + + if (FIL_SUCCESS_CLEAN != andStatus) + { + WMR_PRINT(ALWAYS, "ReadBL Clean Detect failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Write bootloader page + WMR_ASSERT(pFIL->WriteBLPage != NULL); + WMR_PRINT(ALWAYS, "Writing CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + FillBufferWithCountingPattern((UInt32*)writeDataBuffer, testSeed++, testInfo.bootPageBytes); + andStatus = pFIL->WriteBLPage(ceList[0], pageList[0], writeDataBuffer); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Write failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Read back and verify + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bootPageBytes); + WMR_PRINT(ALWAYS, "ReadBL CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + + andStatus = pFIL->ReadBLPage(ceList[0], pageList[0], verifyDataBuffer); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "ReadBL Clean Detect failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.bootPageBytes)) + { + WMR_PRINT(ALWAYS, "Read back contents of boot page failed comparison\n"); + goto test_failed; + } + + // Over-program the same page + WMR_PRINT(ALWAYS, "Over-program BL page CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + WMR_MEMSET(writeDataBuffer, 0xA5, testInfo.bootPageBytes); + andStatus = pFIL->WriteBLPage(ceList[0], pageList[0], writeDataBuffer); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Write failed with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // Read back and verify UECC + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.bootPageBytes); + WMR_PRINT(ALWAYS, "ReadBL CE %d Page %d\n", (UInt32) ceList[0], pageList[0]); + andStatus = pFIL->ReadBLPage(ceList[0], pageList[0], verifyDataBuffer); + + if (FIL_U_ECC_ERROR != andStatus) + { + WMR_PRINT(ALWAYS, "ReadBL did not detect UECC with %s\n", FILErrorToString(andStatus)); + goto test_failed; + } + + // XXX Write the sections for multiple using VS (need to find paired blocks) + + if (testInfo.numBanks == testInfo.numCE) + { + UInt16 wFailingCE = ~0; + UInt32 wFailingBlock = ~0; + + // Setup up ceList for scattered ops + for (bankIdx = 0; bankIdx < testInfo.numCE; ++bankIdx) + { + ceList[bankIdx] = bankIdx; + pageList[bankIdx] = blockList[bankIdx] * testInfo.pagesPerBlock; //XXX this won't work for block gaps + } + + // Erase multiple blocks + + if (pFIL->EraseMultiple) + { + WMR_PRINT(ALWAYS, "EraseMultiple on %d blocks\n", testInfo.numCE); + andStatus = pFIL->EraseMultiple(blockList, TRUE32, TRUE32, &wFailingCE, &wFailingBlock); + } + else + { + // only works for 1 bank per ce + WMR_PRINT(ALWAYS, "EraseMultiple fallback on %d blocks\n", testInfo.numCE); + for (bankIdx = 0; bankIdx < testInfo.numCE; ++bankIdx) + { + andStatus = pFIL->Erase(bankIdx, blockList[bankIdx]); + if (FIL_SUCCESS != andStatus) + { + wFailingCE = bankIdx; + wFailingBlock = blockList[bankIdx]; + break; + } + } + } + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Erase failed CE %d Block %d with %s\n", wFailingCE, wFailingBlock, FILErrorToString(andStatus)); + goto test_failed; + } + + // Clean check + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.numCE * testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.numCE * testInfo.bufferBytesPerMeta); + WMR_MEMSET(sectorStats, TEST_STATS_WATERMARK, testInfo.numCE * testInfo.correctableSectorsPerPage); + // Only check the first page of each block + WMR_PRINT(ALWAYS, "ReadScatteredPages clean check on %d pages\n", testInfo.numCE); + andStatus = pFIL->ReadScatteredPages(ceList, pageList, verifyDataBuffer, verifyMetaBuffer, testInfo.numCE, NULL, sectorStats, FALSE32); + + if (FIL_SUCCESS_CLEAN != andStatus) + { + WMR_PRINT(ALWAYS, "Readback clean check failed with %s\n", FILErrorToString(andStatus)); + WMR_PRINT(ALWAYS, "Sector Stats:\n"); + FILTestHexdump(sectorStats, testInfo.numCE * testInfo.correctableSectorsPerPage); + goto test_failed; + } + + // Program scattered pages + + + WMR_ASSERT(pFIL->WriteScatteredPages != NULL); + FillBufferWithCountingPattern((UInt32*)writeDataBuffer, testSeed++, testInfo.numCE * testInfo.bytesPerPage); + FillMetaBufferWithPattern(writeMetaBuffer, testSeed++, testInfo.numCE); + WMR_PRINT(ALWAYS, "WriteScatteredPages on %d pages\n", testInfo.numCE); + andStatus = pFIL->WriteScatteredPages(ceList, pageList, writeDataBuffer, writeMetaBuffer, testInfo.numCE, &wFailingCE, FALSE32, NULL); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "WriteScatteredPages failed CE %d with %s\n", wFailingCE, FILErrorToString(andStatus)); + goto test_failed; + } + + // Read back multiple pages + + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.numCE * testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.numCE * testInfo.bufferBytesPerMeta); + WMR_MEMSET(sectorStats, TEST_STATS_WATERMARK, testInfo.numCE * testInfo.correctableSectorsPerPage); + WMR_PRINT(ALWAYS, "ReadScatteredPages verify on %d pages\n", testInfo.numCE); + andStatus = pFIL->ReadScatteredPages(ceList, pageList, verifyDataBuffer, verifyMetaBuffer, testInfo.numCE, NULL, sectorStats, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "ReadScatteredPages failed with %s\n", FILErrorToString(andStatus)); + WMR_PRINT(ALWAYS, "Sector Stats:\n"); + FILTestHexdump(sectorStats, testInfo.numCE * testInfo.correctableSectorsPerPage); + goto test_failed; + } + + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, testInfo.numCE * testInfo.bufferBytesPerMeta)) + { + WMR_PRINT(ALWAYS, "Read back contents of pages failed comparison in meta section\n"); + goto test_failed; + } + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.numCE * testInfo.bytesPerPage)) + { + WMR_PRINT(ALWAYS, "Read back contents of second page failed comparison in data section\n"); + goto test_failed; + } + + if (pFIL->EraseMultiple) + { + WMR_PRINT(ALWAYS, "EraseMultiple on %d blocks\n", testInfo.numCE); + andStatus = pFIL->EraseMultiple(blockList, TRUE32, TRUE32, &wFailingCE, &wFailingBlock); + } + else + { + // only works for 1 bank per ce + WMR_PRINT(ALWAYS, "EraseMultiple fallback on %d blocks\n", testInfo.numCE); + for (bankIdx = 0; bankIdx < testInfo.numCE; ++bankIdx) + { + andStatus = pFIL->Erase(bankIdx, blockList[bankIdx]); + if (FIL_SUCCESS != andStatus) + { + wFailingCE = bankIdx; + wFailingBlock = blockList[bankIdx]; + break; + } + } + } + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "Erase failed CE %d Block %d with %s\n", wFailingCE, wFailingBlock, FILErrorToString(andStatus)); + goto test_failed; + } + + // Clean check + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.numCE * testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.numCE * testInfo.bufferBytesPerMeta); + WMR_MEMSET(sectorStats, TEST_STATS_WATERMARK, testInfo.numCE * testInfo.correctableSectorsPerPage); + +#if (!AND_DISABLE_READ_MULTIPLE) + + // Only check the first page of each block + WMR_PRINT(ALWAYS, "ReadMultiplePages clean check on %d pages\n", testInfo.numCE); + andStatus = pFIL->ReadMultiplePages(pageList, verifyDataBuffer, verifyMetaBuffer, testInfo.numCE, NULL, sectorStats, FALSE32); + + if (FIL_SUCCESS_CLEAN != andStatus) + { + WMR_PRINT(ALWAYS, "Readback clean check failed with %s\n", FILErrorToString(andStatus)); + WMR_PRINT(ALWAYS, "Sector Stats:\n"); + FILTestHexdump(sectorStats, testInfo.numCE * testInfo.correctableSectorsPerPage); + goto test_failed; + } + +#endif /* if (!AND_DISABLE_READ_MULTIPLE) */ + + // Program multiple pages + + FillBufferWithCountingPattern((UInt32*)writeDataBuffer, testSeed++, testInfo.numCE * testInfo.bytesPerPage); + FillMetaBufferWithPattern(writeMetaBuffer, testSeed++, testInfo.numCE); + WMR_PRINT(ALWAYS, "WriteMultiplePages on %d pages\n", testInfo.numCE); + andStatus = pFIL->WriteMultiplePages(pageList, writeDataBuffer, writeMetaBuffer, testInfo.numCE, FALSE32, FALSE32, &wFailingCE, FALSE32, NULL); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "WriteMultiplePages failed CE %d with %s\n", wFailingCE, FILErrorToString(andStatus)); + goto test_failed; + } + + // Read back multiple pages + + WMR_MEMSET(verifyDataBuffer, TEST_DATA_WATERMARK, testInfo.numCE * testInfo.bytesPerPage); + WMR_MEMSET(verifyMetaBuffer, TEST_META_WATERMARK, testInfo.numCE * testInfo.bufferBytesPerMeta); + WMR_MEMSET(sectorStats, TEST_STATS_WATERMARK, testInfo.numCE * testInfo.correctableSectorsPerPage); + +#if (!AND_DISABLE_READ_MULTIPLE) + + WMR_PRINT(ALWAYS, "ReadMultiplePages verify on %d pages\n", testInfo.numCE); + andStatus = pFIL->ReadMultiplePages(pageList, verifyDataBuffer, verifyMetaBuffer, testInfo.numCE, NULL, sectorStats, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "ReadMultiplePages failed with %s\n", FILErrorToString(andStatus)); + WMR_PRINT(ALWAYS, "Sector Stats:\n"); + FILTestHexdump(sectorStats, testInfo.numCE * testInfo.correctableSectorsPerPage); + goto test_failed; + } + +#else /* if (!AND_DISABLE_READ_MULTIPLE) */ + + WMR_PRINT(ALWAYS, "ReadScatteredPages verify on %d pages\n", testInfo.numCE); + andStatus = pFIL->ReadScatteredPages(ceList, pageList, verifyDataBuffer, verifyMetaBuffer, testInfo.numCE, NULL, sectorStats, FALSE32); + + if (FIL_SUCCESS != andStatus) + { + WMR_PRINT(ALWAYS, "ReadScatteredPages failed with %s\n", FILErrorToString(andStatus)); + WMR_PRINT(ALWAYS, "Sector Stats:\n"); + FILTestHexdump(sectorStats, testInfo.numCE * testInfo.correctableSectorsPerPage); + goto test_failed; + } + +#endif /* if (!AND_DISABLE_READ_MULTIPLE) */ + + if (WMR_MEMCMP(writeMetaBuffer, verifyMetaBuffer, testInfo.numCE * testInfo.bufferBytesPerMeta)) + { + WMR_PRINT(ALWAYS, "Read back contents of pages failed comparison in meta section\n"); + goto test_failed; + } + + if (WMR_MEMCMP(writeDataBuffer, verifyDataBuffer, testInfo.numCE * testInfo.bytesPerPage)) + { + WMR_PRINT(ALWAYS, "Read back contents of second page failed comparison in data section\n"); + goto test_failed; + } + + + } + else + { + WMR_PRINT(ALWAYS, "Skipping Multi-Page test on VS formatted part\n"); + } + + (void) testSeed; + + WMR_PRINT(ALWAYS, "Interface Test Passed\n"); + + WMR_BufZone_Free(&bufZone); + + return TRUE32; + +test_failed: + WMR_PRINT(ALWAYS, "Interface Test Failed\n"); + + if (writeMetaBuffer) + { + WMR_FREE(writeMetaBuffer, metaBufferSize); + } + if (verifyMetaBuffer) + { + WMR_FREE(verifyMetaBuffer, metaBufferSize); + } + if (sectorStats) + { + WMR_FREE(sectorStats, sectorStatsSize); + } + + WMR_BufZone_Free(&bufZone); + + return FALSE32; +} + + +const char * FILErrorToString(Int32 filStatus) +{ + + switch (filStatus) + { + case FIL_SUCCESS: + { + return "FIL_SUCCESS"; + } + case FIL_SUCCESS_CLEAN: + { + return "FIL_SUCCESS_CLEAN"; + } + case FIL_CRITICAL_ERROR: + { + return "FIL_CRITICAL_ERROR"; + } + case FIL_U_ECC_ERROR: + { + return "FIL_U_ECC_ERROR"; + } + case FIL_WRITE_FAIL_ERROR: + { + return "FIL_WRITE_FAIL_ERROR"; + } + case FIL_UNSUPPORTED_ERROR: + { + return "FIL_UNSUPPORTED_ERROR"; + } + default: + { + return "UNKNOWN"; + } + } +} + +static void InitPageListFromBlocks(const UInt16 *blockList, UInt32 *pageList) +{ + UInt32 pageIdx; + + // Fill in page list based on provided blocks + // XXX Mind the block gap + for (pageIdx = 0; pageIdx < (2 * testInfo.numBanks); ++pageIdx) + { + pageList[pageIdx] = (blockList[pageIdx % testInfo.numBanks] * testInfo.pagesPerBlock) + (pageIdx / testInfo.numBanks); + } +} + +static void FillBufferWithCountingPattern(UInt32 *buffer, UInt32 startValue, UInt32 bytes) +{ + UInt32 wordIdx; + const UInt32 kWordsToFill = bytes / sizeof(UInt32); + + for (wordIdx = 0; wordIdx < kWordsToFill; wordIdx += 1) + { + if ((wordIdx + 1) == kWordsToFill) + { + // Last word may not be full + UInt8 *endOfBuffer = (UInt8*) &buffer[wordIdx]; + switch (bytes % sizeof(UInt32)) + { + case 0: + endOfBuffer[1] = (startValue >> 24) & 0xFF; + // fall through + case 3: + endOfBuffer[1] = (startValue >> 16) & 0xFF; + // fall through + case 2: + endOfBuffer[1] = (startValue >> 8) & 0xFF; + // fall through + case 1: + endOfBuffer[1] = startValue & 0xFF; + } + } + else + { + buffer[wordIdx] = startValue++; + } + } +} + + +static void FillMetaBufferWithPattern(UInt8 *buffer, UInt32 startValue, UInt32 numPages) +{ + typedef struct + { + UInt32 valid1; + UInt32 valid2; + UInt16 valid3; + UInt16 pad; + } _TestMeta; + + _TestMeta *pTestMeta = (_TestMeta*) buffer; + + while (numPages--) + { + pTestMeta->valid1 = startValue++; + pTestMeta->valid2 = startValue++; + pTestMeta->valid3 = startValue++; + pTestMeta->pad = ~0; + + pTestMeta++; + } +} + +#define HEXDUMP_WIDTH (16) +static void FILTestHexdump(void *data, UInt32 length) +{ + UInt32 i, j; + UInt8 *bytes = (UInt8*) data; + for (i = 0; i < length; i += HEXDUMP_WIDTH) + { + for (j = 0; (j < HEXDUMP_WIDTH) && ((i + j) < length); j++) + { + _WMR_PRINT(" %02x", (UInt32) *bytes++); + } + _WMR_PRINT("\n"); + } +} + diff --git a/drivers/flash_nand/raw/export.txt b/drivers/flash_nand/raw/export.txt new file mode 100644 index 0000000..8d431f9 --- /dev/null +++ b/drivers/flash_nand/raw/export.txt @@ -0,0 +1,5 @@ +_WMR_Init +_WMR_GetFPart +_WMR_PreInit +_WMR_CtrlIO +_raw_nand_init diff --git a/drivers/flash_nand/raw/library.mk b/drivers/flash_nand/raw/library.mk new file mode 100644 index 0000000..7e8a51c --- /dev/null +++ b/drivers/flash_nand/raw/library.mk @@ -0,0 +1,58 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +WHIMORY_DIR := $(GET_LOCAL_DIR) +WHIMORY_BUILD := $(call TOLIBDIR,$(WHIMORY_DIR)/WHIMORY.a) +COMMONLIBS += WHIMORY + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +NAND_DIR := $(patsubst %/,%,$(dir $(GET_LOCAL_DIR))) + +MODULES += \ + drivers/flash_nand/OAM \ + lib/blockdev + +GLOBAL_INCLUDES += \ + $(WHIMORY_DIR)/Whimory/Core/VFL \ + $(WHIMORY_DIR)/Whimory/Core/FTL \ + $(WHIMORY_DIR)/Whimory/Core/FPart \ + $(WHIMORY_DIR)/Whimory/Exam \ + $(WHIMORY_DIR)/Whimory/Inc \ + $(NAND_DIR)/OAM \ + $(NAND_DIR)/OAM/iBoot + +# base library files +WHIMORY_SUBOBJS += \ + $(WHIMORY_DIR)/raw_nand.o \ + $(WHIMORY_DIR)/Whimory/Core/FTL/FTLInterface.o \ + $(WHIMORY_DIR)/Whimory/Core/FPart/FPart.o \ + $(WHIMORY_DIR)/Whimory/Core/FTL/yaFTL.o \ + $(WHIMORY_DIR)/Whimory/Core/FTL/yaFTL_BTOC.o \ + $(WHIMORY_DIR)/Whimory/Core/VFL/VFLBuffer.o \ + $(WHIMORY_DIR)/Whimory/Core/VFL/VFLInterface.o \ + $(WHIMORY_DIR)/Whimory/Core/VFL/VSVFLInterface.o \ + $(WHIMORY_DIR)/Whimory/Exam/WMRExam.o \ + $(WHIMORY_DIR)/Whimory/Test/FILTest.o + +WHIMORY_SUBOBJS := $(call TOLIBOBJDIR,$(WHIMORY_SUBOBJS)) +ALL_DEPS += $(WHIMORY_SUBOBJS:%o=%d) + +WHIMORY_OBJS := $(call TOLIBOBJDIR,$(WHIMORY_DIR)/WHIMORY.o) + +$(WHIMORY_OBJS): $(WHIMORY_SUBOBJS) + @echo LIB_LD $@ + $(_v)$(_LD) $(LIBRARY_LDFLAGS) $(WHIMORY_SUBOBJS) -o $@ -exported_symbols_list $(WHIMORY_DIR)/export.txt + +$(WHIMORY_BUILD): $(WHIMORY_OBJS) + +endif diff --git a/drivers/flash_nand/raw/raw_nand.c b/drivers/flash_nand/raw/raw_nand.c new file mode 100644 index 0000000..c129a92 --- /dev/null +++ b/drivers/flash_nand/raw/raw_nand.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#include "WMRConfig.h" +#include "ANDTypes.h" +#include "FIL.h" +#include "VFLBuffer.h" +#include "VFL.h" +#include "FTL.h" +#include "WMRExam.h" +#include "WMROAM.h" + +extern uint32_t nand_fsys_block_offset; + +static int nand_filesys_init(uint32_t block_size, uint32_t block_count); +static FTLFunctions *TLFuncPtr=NULL; +static int nand_read_block_hook(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count) +{ + Int32 err; + + if (count > 0) { + err = TLFuncPtr->Read(block, count, ptr); + //err = FTL_Read(block, count, ptr); + + if (err != FIL_SUCCESS) { + printf("nand_read_block_hook: failure %d reading block %u, count %zd\n", err, block, count); + return -1; + } + } + return count; +} + +int raw_nand_init(void) +{ + Int32 intRes; + uint32_t block_size, block_count; + uint32_t index_cache = 0; + + dprintf(DEBUG_INFO,"raw_nand_init()\n"); + + // Initialise the FTL + intRes = WMR_Init(&block_count, &block_size, &index_cache, gWhimoryInitParameters, nand_fsys_block_offset); + + if (intRes != WMR_SUCCESS) { + dprintf(DEBUG_CRITICAL, "Raw NAND FTL failed initialisation\n"); + return -1; + } + + if (0 != nand_filesys_init(block_size, block_count)) + return -1; + + return 0; +} + +static int nand_filesys_init(uint32_t block_size, uint32_t block_count) +{ + struct blockdev *nand; + + TLFuncPtr = WMR_GetFTL(); + // build a block device around this NAND + nand = malloc(sizeof(struct blockdev)); + + construct_blockdev(nand, "nand0", (off_t)block_count * block_size, block_size); + + nand->read_block_hook = &nand_read_block_hook; + + register_blockdev(nand); + + /* scan ourselves for partitions and publish subdevices */ + partition_scan_and_publish_subdevices("nand0"); + + return 0; +} diff --git a/drivers/flash_nand/raw/rules.mk b/drivers/flash_nand/raw/rules.mk new file mode 100644 index 0000000..444d162 --- /dev/null +++ b/drivers/flash_nand/raw/rules.mk @@ -0,0 +1,35 @@ +# Copyright (c) 2007-2009 Apple Inc. All rights reserved. +# Copyright (c) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_RAW_NAND=1 + +MODULES += \ + drivers/flash_nand + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/Whimory/Core/FPart \ + $(LOCAL_DIR)/Whimory/Core/VFL \ + $(LOCAL_DIR)/Whimory/Exam + +# +# If a NAND FTL has not been configured, we need some of the raw NAND bits. +# +ifeq ($(WITH_NAND_FTL),) +ALL_OBJS += \ + $(LOCAL_DIR)/Whimory/Core/FPart/FPart.o \ + $(LOCAL_DIR)/Whimory/Core/VFL/VFLBuffer.o \ + $(LOCAL_DIR)/Whimory/Exam/WMRExam.o +else +LIBRARY_MODULES += $(LOCAL_DIR) +endif diff --git a/drivers/flash_nand/rules.mk b/drivers/flash_nand/rules.mk new file mode 100644 index 0000000..c731fa1 --- /dev/null +++ b/drivers/flash_nand/rules.mk @@ -0,0 +1,26 @@ +# Copyright (c) 2007-2009 Apple Inc. All rights reserved. +# Copyright (c) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_NAND=1 + +MODULES += \ + drivers/flash_nand/OAM \ + drivers/flash_nand/id + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/raw/Whimory/Inc \ + $(LOCAL_DIR)/ppn/WhimoryPPN/Core/Misc + +ALL_OBJS += \ + $(LOCAL_DIR)/debug.o diff --git a/drivers/flash_nor/nor.c b/drivers/flash_nor/nor.c new file mode 100644 index 0000000..e7b05eb --- /dev/null +++ b/drivers/flash_nor/nor.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +static int nor_blockdev_read_block(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count) +{ + struct nor_blockdev *ndev = (struct nor_blockdev *)bdev; + int err; + + /* sanity-check the starting block and count */ + if ((block >= ndev->bdev.block_count) || (count > ndev->bdev.block_count)) + return 0; + + /* adjust the operation length if it overruns */ + if (block > (ndev->bdev.block_count - count)) + count = ndev->bdev.block_count - block; + +// dprintf(DEBUG_SPEW, "nor_blockdev_read: dev %p, block %d, count %d\n", bdev, block, count); + + uint32_t cb = count << ndev->bdev.block_shift; + err = ndev->readRange(ndev->handle, ptr, block << ndev->bdev.block_shift, cb); + if (err < 0) return err; + + return count; +} + +#if !READ_ONLY + +static int nor_blockdev_erase_hook(struct blockdev *bdev, off_t offset, uint64_t len) +{ + struct nor_blockdev *ndev = (struct nor_blockdev *)bdev; + int err; + + RELEASE_ASSERT(offset >= 0); + if ((uint64_t)offset >= ndev->bdev.total_len) + return 0; + if ((offset + len) > ndev->bdev.total_len) + len = ndev->bdev.total_len - offset; + + uint32_t cb = len; + err = ndev->eraseRange(ndev->handle, offset, cb); + if (err < 0) return err; + + return 0; +} + +static int nor_blockdev_write_hook(struct blockdev *bdev, const void *ptr, block_addr block, uint32_t count) +{ + struct nor_blockdev *ndev = (struct nor_blockdev *)bdev; + int err; + + if (block >= ndev->bdev.block_count) + return 0; + if ((block + count) > ndev->bdev.block_count) + count = ndev->bdev.block_count - block; + + uint32_t cb = count << ndev->bdev.block_shift; + err = ndev->writeRange(ndev->handle, ptr, block << ndev->bdev.block_shift, cb); + if (err < 0) return err; + + return count; +} + +#endif /* ! READ_ONLY */ + +int flash_nor_register(struct nor_blockdev *nor_bdev, const char *name, uint64_t len, uint32_t block_size) +{ + /* create the block device */ + construct_blockdev(&nor_bdev->bdev, name, len, block_size); + nor_bdev->bdev.read_block_hook = &nor_blockdev_read_block; +#if !READ_ONLY + nor_bdev->bdev.write_block_hook = &nor_blockdev_write_hook; + nor_bdev->bdev.erase_hook = &nor_blockdev_erase_hook; +#endif + + /* register it in the block device namespace */ + register_blockdev((struct blockdev *)nor_bdev); + + return 0; +} + +int flash_nor_init(int which_device) +{ + int ret_spi = -1; + +#if WITH_HW_FLASH_NOR_SPI + extern int flash_spi_init(int which_bus); + + ret_spi = flash_spi_init(which_device); +#else +# error Must configure a supported NOR flash interface. +#endif + + if (ret_spi < 0) { + dprintf(DEBUG_INFO, "flash_nor_init: failed to find any nor devices\n"); + return -1; + } + + return 0; +} diff --git a/drivers/flash_nor/rules.mk b/drivers/flash_nor/rules.mk new file mode 100644 index 0000000..5b16264 --- /dev/null +++ b/drivers/flash_nor/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_FLASH_NOR=1 + +MODULES += \ + lib/blockdev + +ALL_OBJS += \ + $(LOCAL_DIR)/nor.o diff --git a/drivers/flash_nor/spi/rules.mk b/drivers/flash_nor/spi/rules.mk new file mode 100644 index 0000000..35a0189 --- /dev/null +++ b/drivers/flash_nor/spi/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_FLASH_NOR_SPI=1 + +MODULES += \ + drivers/flash_nor + +ALL_OBJS += \ + $(LOCAL_DIR)/spi_flash.o diff --git a/drivers/flash_nor/spi/spi_flash.c b/drivers/flash_nor/spi/spi_flash.c new file mode 100644 index 0000000..69a7dcf --- /dev/null +++ b/drivers/flash_nor/spi/spi_flash.c @@ -0,0 +1,632 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#if WITH_TARGET_CONFIG +# include +#endif +#include +#include + +#define SPI_FLASH_CMD_WRSR (0x01) +#define SPI_FLASH_CMD_BYTE_PROG (0x02) +#define SPI_FLASH_CMD_READ (0x03) +#define SPI_FLASH_CMD_WRDI (0x04) +#define SPI_FLASH_CMD_RDSR (0x05) +#define SPI_FLASH_CMD_WREN (0x06) +#define SPI_FLASH_CMD_ERASE_SECTOR (0x20) +#define SPI_FLASH_CMD_EWSR (0x50) +#define SPI_FLASH_CMD_EBSY (0x70) +#define SPI_FLASH_CMD_DBSY (0x80) +#define SPI_FLASH_CMD_JEDEC_ID (0x9f) +#define SPI_FLASH_CMD_SST_AAI_WORD_PROG (0xad) + +#define SPI_FLASH_STATUS_BUSY (0x01) +#define SPI_FLASH_STATUS_BP (0x3c) +#define SPI_FLASH_STATUS_ATMEL_SPW (0x0c) +#define SPI_FLASH_STATUS_ST_SPW (0x1c) +#define SPI_FLASH_STATUS_BPL (0x80) + +#define SPI_FLASH_JEDEC_ID_SST_25VF080 (0xbf258e) // 1M +#define SPI_FLASH_JEDEC_ID_SST_25WF080 (0xbf2505) // 1M, replaces 25VF080 +#define SPI_FLASH_JEDEC_ID_SST_2M (0xbf2541) +#define SPI_FLASH_JEDEC_ID_ATMEL (0x1f4502) +#define SPI_FLASH_JEDEC_ID_ST_M25PX32 (0x207116) +#define SPI_FLASH_JEDEC_ID_ST_M25PE80 (0x208014) +#define SPI_FLASH_JEDEC_ID_ST_M25P32 (0x202016) +#define SPI_FLASH_JEDEC_ID_ST_M25P64 (0x202017) +#define SPI_FLASH_JEDEC_ID_ST_M25P128 (0x202018) +#define SPI_FLASH_JEDEC_ID_ST_M25PX64 (0x207117) +#define SPI_FLASH_JEDEC_ID_ST_M25PX128 (0x207118) +#define SPI_FLASH_JEDEC_ID_S25FL128P (0x012018) +#define SPI_FLASH_JEDEC_ID_MX25L25735 (0xc22019) +#define SPI_FLASH_JEDEC_ID_EEPROM (0xFFFFFF) + +#define SPI_FLASH_FLAG_PROG_SST (1 << 0) + +struct spi_ndev { + struct nor_blockdev ndev; + + u_int32_t spiBus; + u_int32_t spiChipSelect; + u_int32_t spiFrequency; + u_int32_t spiMode; + + u_int32_t jedecID; + u_int32_t flags; + + u_int32_t blockSize; + u_int32_t blockCount; + + u_int32_t softWriteProtectMask; + u_int32_t progMaxLength; + u_int32_t progAlignMask; + + u_int32_t defaultTimeout; + u_int32_t byteProgramTimeout; + u_int32_t eraseSectorTimeout; +}; + +static int flash_spi_probe(struct spi_ndev *sdev); +static int flash_spi_read_range(uintptr_t handle, u_int8_t *ptr, u_int32_t offset, u_int32_t length); +static int flash_spi_write_range(uintptr_t handle, const u_int8_t *ptr, u_int32_t offset, u_int32_t length); +static int flash_spi_program_chunk(struct spi_ndev *sdev, const u_int8_t *buf, u_int32_t chunk_off, u_int32_t chunk_len); +static int flash_spi_program_chunk_sst(struct spi_ndev *sdev, const u_int8_t *buf, u_int32_t chunk_off, u_int32_t chunk_len); +static int flash_spi_erase_range(uintptr_t handle, u_int32_t offset, u_int32_t length); +static void flash_spi_setup_bus(struct spi_ndev *sdev); +static int flash_spi_wait_busy(struct spi_ndev *sdev, u_int32_t timeout); +static u_int8_t flash_spi_read_rdsr(struct spi_ndev *sdev); +static void flash_spi_write_enable(struct spi_ndev *sdev, bool enable); +static void flash_spi_write_wrsr(struct spi_ndev *sdev, u_int8_t wrsr); +static u_int32_t flash_spi_read_jedec_id(struct spi_ndev *sdev); +static void flash_spi_select(struct spi_ndev *sdev, bool enable); + + +int flash_spi_init(int which_bus) +{ + struct spi_ndev *sdev; + int result; + + sdev = calloc(1, sizeof(struct spi_ndev)); + + switch (which_bus) { +#ifdef SPI_NOR0 + case SPI_NOR0: + sdev->spiBus = SPI_NOR0; +# ifdef GPIO_SPI0_CS + sdev->spiChipSelect = GPIO_SPI0_CS; +# endif + break; +#endif +#ifdef SPI_NOR1 + case SPI_NOR1: + sdev->spiBus = SPI_NOR1; +# ifdef GPIO_SPI1_CS + sdev->spiChipSelect = GPIO_SPI1_CS; +# endif + break; +#endif +#ifdef SPI_NOR3 + case SPI_NOR3: + sdev->spiBus = SPI_NOR3; +# ifdef GPIO_SPI3_CS + sdev->spiChipSelect = GPIO_SPI3_CS; +# endif + break; +#endif + default: + free(sdev); + return -1; + } + + // Get the SPI frequency based upon the platform & boot configuration. + sdev->spiFrequency = platform_get_spi_frequency(); + + sdev->spiMode = (8 << 16) | (0 << 8) | (0 << 0); // Default to 8 bit and mode 0 + + sdev->defaultTimeout = 50 * 1000; // Default timeout is 50ms + + result = flash_spi_probe(sdev); + if (result < 0) { + free(sdev); + return result; + } + + sdev->ndev.handle = (uintptr_t)sdev; + sdev->ndev.readRange = flash_spi_read_range; +#if !READ_ONLY + sdev->ndev.writeRange = flash_spi_write_range; + sdev->ndev.eraseRange = flash_spi_erase_range; +#endif /* ! READ_ONLY */ + + return flash_nor_register(&sdev->ndev, "nor0", sdev->blockCount * sdev->blockSize, sdev->blockSize); +} + +static int flash_spi_read_range(uintptr_t handle, u_int8_t *ptr, u_int32_t offset, u_int32_t length) +{ + int result; + u_int8_t addr[4]; + u_int32_t cnt; + struct spi_ndev *sdev = (struct spi_ndev *)handle; + + flash_spi_setup_bus(sdev); + + result = flash_spi_wait_busy(sdev, sdev->defaultTimeout); + if (result < 0) return -1; + + if (0 /*sdev->jedecID == SPI_FLASH_JEDEC_ID_EEPROM*/) { + for (cnt = 0; cnt < length; cnt++) { + addr[0] = SPI_FLASH_CMD_READ; + addr[1] = ((offset + cnt) >> 16) & 0xff; + addr[2] = ((offset + cnt) >> 8) & 0xff; + addr[3] = ((offset + cnt) >> 0) & 0xff; + + flash_spi_select(sdev, true); + spi_write_etc(sdev->spiBus, addr, 4, 1, 0); // wait, no rx + spi_read_etc(sdev->spiBus, ptr + cnt, 1, 1, 0); // wait, no tx + flash_spi_select(sdev, false); + } + } else { + addr[0] = SPI_FLASH_CMD_READ; + addr[1] = (offset >> 16) & 0xff; + addr[2] = (offset >> 8) & 0xff; + addr[3] = (offset >> 0) & 0xff; + + flash_spi_select(sdev, true); + spi_write_etc(sdev->spiBus, addr, 4, 1, 0); // wait, no rx + spi_read_etc(sdev->spiBus, ptr, length, 1, 0); // wait, no tx + flash_spi_select(sdev, false); + } + + return 0; +} + +#if !READ_ONLY + +static int flash_spi_write_range(uintptr_t handle, const u_int8_t *ptr, u_int32_t offset, u_int32_t length) +{ + int result; + const u_int8_t *buf; + u_int8_t rdsr, *tmpBuf = 0; + u_int32_t cur_len, cur_off, chunk_len, chunk_off, block_mask, tmp, left = length; + struct spi_ndev *sdev = (struct spi_ndev *)handle; + + flash_spi_setup_bus(sdev); + + result = flash_spi_wait_busy(sdev, sdev->defaultTimeout); + if (result < 0) { + return result; + } + + rdsr = flash_spi_read_rdsr(sdev); + if (((rdsr & sdev->softWriteProtectMask) != 0) && ((rdsr & SPI_FLASH_STATUS_BPL) != 0)) { + dprintf(DEBUG_CRITICAL, "flash_spi_write_range: device is read-only\n"); + return -1; + } + + if ((rdsr & sdev->softWriteProtectMask) == sdev->softWriteProtectMask) rdsr |= SPI_FLASH_STATUS_BP; + + flash_spi_write_wrsr(sdev, 0x00); // Set BP[3:0] = 0 + + block_mask = sdev->blockSize - 1; + + cur_off = offset; + while (left != 0) { + cur_len = left; // Assume maximum size + buf = ptr + cur_off - offset; // Assume source buffer + chunk_off = cur_off & ~block_mask; // Find the base offset + chunk_len = sdev->blockSize; // Assume single block + + if ((cur_off & block_mask) != 0) { // Clip size to rest of block + cur_len = sdev->blockSize - (cur_off & block_mask); // when not at the beginning of the block + if (cur_len > left) cur_len = left; + } else if (cur_len >= sdev->blockSize) { + cur_len = cur_len & ~block_mask; // Round to multiple of block size + chunk_len = cur_len; + } + + if (cur_len < sdev->blockSize) { // Handle partial blocks + if (tmpBuf == 0) tmpBuf = malloc(sdev->blockSize); + + tmp = sdev->blockSize; // Pre-read the whole block + result = flash_spi_read_range(handle, tmpBuf, chunk_off, tmp); + if (result < 0) break; + // Copy in the changed bytes + memcpy(tmpBuf + (cur_off & block_mask), buf, cur_len); + + buf = tmpBuf; // Select the side buffer + } + + tmp = chunk_len; // Erase the whole chunk + result = flash_spi_erase_range(handle, chunk_off, tmp); + if (result < 0) break; + + if (sdev->flags & SPI_FLASH_FLAG_PROG_SST) { + result = flash_spi_program_chunk_sst(sdev, buf, chunk_off, chunk_len); + } else { + result = flash_spi_program_chunk(sdev, buf, chunk_off, chunk_len); + } + + if (result < 0) break; + + cur_off += cur_len; + left -= cur_len; + } + + flash_spi_write_wrsr(sdev, rdsr); // Restore BP[3:0] + + if (tmpBuf != 0) free(tmpBuf); + + if (result < 0) { + dprintf(DEBUG_CRITICAL, "flash_spi_write_range: write failed: %d\n", result); + return result; + } + + return 0; +} + +static int flash_spi_program_chunk(struct spi_ndev *sdev, const u_int8_t *buf, u_int32_t chunk_off, u_int32_t chunk_len) +{ + int result = 0; + u_int8_t addr[4]; + u_int32_t prog_len, prog_off = 0; + + while (chunk_len != 0) { + prog_len = (prog_off | sdev->progAlignMask) - prog_off + 1; + if (prog_len > sdev->progMaxLength) prog_len = sdev->progMaxLength; + if (prog_len > chunk_len) prog_len = chunk_len; + + flash_spi_write_enable(sdev, true); + + addr[0] = SPI_FLASH_CMD_BYTE_PROG; + addr[1] = ((chunk_off + prog_off) >> 16) & 0xff; + addr[2] = ((chunk_off + prog_off) >> 8) & 0xff; + addr[3] = ((chunk_off + prog_off) >> 0) & 0xff; + + flash_spi_select(sdev, true); // Write the command and bytes + spi_write_etc(sdev->spiBus, addr, 4, 1, 0); + spi_write_etc(sdev->spiBus, buf + prog_off, prog_len, 1, 0); + flash_spi_select(sdev, false); + spin(1); // CS must be de-asserted for at least 100ns + + // Wait for the bytes to be written + result = flash_spi_wait_busy(sdev, sdev->byteProgramTimeout); + + if (result < 0) break; + + prog_off += prog_len; + chunk_len -= prog_len; + } + + flash_spi_write_enable(sdev, false); + + return result; +} + +static int flash_spi_program_chunk_sst(struct spi_ndev *sdev, const u_int8_t *buf, u_int32_t chunk_off, u_int32_t chunk_len) +{ + int result = 0; + u_int8_t addr[6]; + u_int32_t cnt, tmp; + + flash_spi_write_enable(sdev, true); + + for (cnt = 0; cnt < chunk_len; cnt += 2) { + if (cnt == 0) { + addr[0] = SPI_FLASH_CMD_SST_AAI_WORD_PROG; + addr[1] = (chunk_off >> 16) & 0xff; + addr[2] = (chunk_off >> 8) & 0xff; + addr[3] = (chunk_off >> 0) & 0xff; + addr[4] = buf[cnt + 0]; + addr[5] = buf[cnt + 1]; + tmp = 6; + } else { + addr[0] = SPI_FLASH_CMD_SST_AAI_WORD_PROG; + addr[1] = buf[cnt + 0]; + addr[2] = buf[cnt + 1]; + tmp = 3; + } + + + flash_spi_select(sdev, true); // Write the command and bytes + spi_write_etc(sdev->spiBus, addr, tmp, 1, 0); // wait, no rx + flash_spi_select(sdev, false); + spin(1); // CS must be de-asserted for at least 100ns + + // Wait for the bytes to be written + result = flash_spi_wait_busy(sdev, sdev->byteProgramTimeout); + + if (result < 0) break; + } + + flash_spi_write_enable(sdev, false); + + return result; +} + +static int flash_spi_erase_range(uintptr_t handle, u_int32_t offset, u_int32_t length) +{ + int result; + u_int8_t rdsr, addr[4]; + u_int32_t block_mask, left = length; + struct spi_ndev *sdev = (struct spi_ndev *)handle; + +// if (sdev->jedecID == SPI_FLASH_JEDEC_ID_EEPROM) return 0; + + block_mask = sdev->blockSize - 1; + + if (((offset & block_mask) != 0) || ((left & block_mask) != 0)) { + dprintf(DEBUG_CRITICAL, "flash_spi_erase_range: offset or length not a multiple of erase block size\n"); + return -1; + } + + flash_spi_setup_bus(sdev); + + result = flash_spi_wait_busy(sdev, sdev->defaultTimeout); + if (result < 0) { + return result; + } + + rdsr = flash_spi_read_rdsr(sdev); + if (((rdsr & 0x3C) != 0) && ((rdsr & 0x80) != 0)) { + dprintf(DEBUG_CRITICAL, "flash_spi_erase_range: device is read-only\n"); + return -1; + } + + if ((rdsr & sdev->softWriteProtectMask) == sdev->softWriteProtectMask) rdsr |= SPI_FLASH_STATUS_BP; + + flash_spi_write_wrsr(sdev, 0x00); // Set BP[3:0] = 0 + + while (left != 0) { + flash_spi_write_enable(sdev, true); + + addr[0] = SPI_FLASH_CMD_ERASE_SECTOR; + addr[1] = (offset >> 16) & 0xff; + addr[2] = (offset >> 8) & 0xff; + addr[3] = (offset >> 0) & 0xff; + + flash_spi_select(sdev, true); + spi_write_etc(sdev->spiBus, addr, 4, 1, 0); // wait, no rx + flash_spi_select(sdev, false); + + result = flash_spi_wait_busy(sdev, sdev->eraseSectorTimeout); + if (result < 0) break; + + offset += sdev->blockSize; + left -= sdev->blockSize; + } + + flash_spi_write_wrsr(sdev, rdsr); // Restore BP[3:0] + + if (result < 0) { + dprintf(DEBUG_CRITICAL, "flash_spi_erase_range: erase failed\n"); + return result; + } + + return 0; +} + +#endif /* ! READ_ONLY */ + +static int flash_spi_probe(struct spi_ndev *sdev) +{ + int result; + + flash_spi_setup_bus(sdev); + + result = flash_spi_wait_busy(sdev, sdev->defaultTimeout); + if (result < 0) return result; + + sdev->flags = 0; + + /* default to 4K page, 1MiB device */ + sdev->blockSize = 0x1000; + sdev->blockCount = 0x100; + +#if !READ_ONLY + sdev->jedecID = flash_spi_read_jedec_id(sdev); + + dprintf(DEBUG_INFO, "flash_spi_probe: jedecID: 0x%06lx\n", sdev->jedecID); + + switch (sdev->jedecID) { + case SPI_FLASH_JEDEC_ID_SST_25VF080 : + case SPI_FLASH_JEDEC_ID_SST_2M : + sdev->flags |= SPI_FLASH_FLAG_PROG_SST; + sdev->softWriteProtectMask = SPI_FLASH_STATUS_BP; + sdev->progMaxLength = 1; // One byte buffer + sdev->progAlignMask = 1; // No aligment restriction + sdev->byteProgramTimeout = 10; // Byte program timeout is 10us + sdev->eraseSectorTimeout = 25 * 1000; // Sectory Erase timeout is 25ms + break; + + case SPI_FLASH_JEDEC_ID_SST_25WF080 : + sdev->flags |= SPI_FLASH_FLAG_PROG_SST; + sdev->softWriteProtectMask = SPI_FLASH_STATUS_BP; + sdev->progMaxLength = 1; // One byte buffer + sdev->progAlignMask = 1; // No aligment restriction + sdev->byteProgramTimeout = 25; // Byte program timeout is 25us + sdev->eraseSectorTimeout = 30 * 1000; // Sectory Erase timeout is 30ms + break; + + case SPI_FLASH_JEDEC_ID_ATMEL : + sdev->softWriteProtectMask = SPI_FLASH_STATUS_ATMEL_SPW; + sdev->progMaxLength = 256; // 256 byte buffer + sdev->progAlignMask = 256 - 1; // 256 byte alignment requirement + sdev->byteProgramTimeout = 5 * 1000; // Byte program timeout is 5ms + sdev->eraseSectorTimeout = 200 * 1000; // Sectory Erase timeout is 200ms + break; + + case SPI_FLASH_JEDEC_ID_ST_M25P128 : + case SPI_FLASH_JEDEC_ID_ST_M25P64 : + case SPI_FLASH_JEDEC_ID_ST_M25P32 : + case SPI_FLASH_JEDEC_ID_ST_M25PX128 : + case SPI_FLASH_JEDEC_ID_ST_M25PX64 : + case SPI_FLASH_JEDEC_ID_ST_M25PX32 : + case SPI_FLASH_JEDEC_ID_ST_M25PE80 : + switch (sdev->jedecID) { + case SPI_FLASH_JEDEC_ID_ST_M25P128 : + case SPI_FLASH_JEDEC_ID_ST_M25PX128 : + sdev->blockCount = 0x1000; // 16MiB + break; + case SPI_FLASH_JEDEC_ID_ST_M25P32 : // 64 x 64Kib + sdev->blockSize = 0x10000; + sdev->blockCount = 0x40; + break; + case SPI_FLASH_JEDEC_ID_ST_M25P64 : // 128 x 64Kib + sdev->blockSize = 0x10000; + sdev->blockCount = 0x80; + break; + case SPI_FLASH_JEDEC_ID_ST_M25PX64 : + sdev->blockCount = 0x800; // 8MiB + break; + } + sdev->softWriteProtectMask = SPI_FLASH_STATUS_ST_SPW; + sdev->progMaxLength = 256; // 256 byte buffer + sdev->progAlignMask = 256 - 1; // 256 byte alignment requirement + sdev->byteProgramTimeout = 5 * 1000; // Byte program timeout is 5ms + sdev->eraseSectorTimeout = 150 * 1000; // Sectory Erase timeout is 150ms + break; + + case SPI_FLASH_JEDEC_ID_S25FL128P : + sdev->blockSize = 0x1000; // 64KiB + sdev->blockCount = 0x1000; // 16MiB + sdev->softWriteProtectMask = SPI_FLASH_STATUS_ST_SPW; + sdev->progMaxLength = 256; // 256 byte buffer + sdev->progAlignMask = 256 - 1; // 256 byte alignment requirement + sdev->byteProgramTimeout = 5 * 1000; // Byte program timeout is 5ms + sdev->eraseSectorTimeout = 150 * 1000; // Sectory Erase timeout is 150ms + break; + + case SPI_FLASH_JEDEC_ID_MX25L25735: + sdev->blockSize = 0x1000; // 4KiB + sdev->blockCount = 0x2000; // 32 MiB + sdev->softWriteProtectMask = SPI_FLASH_STATUS_BP; + sdev->progMaxLength = 256; // 256 byte buffer + sdev->progAlignMask = 256 - 1; // 256 byte alignment requirement + sdev->byteProgramTimeout = 5 * 1000; // Byte program timeout is 5ms + sdev->eraseSectorTimeout = 150 * 1000; // Sectory Erase timeout is 150ms + break; + +#if 0 + case SPI_FLASH_JEDEC_ID_EEPROM : + sdev->softWriteProtectMask = SPI_FLASH_STATUS_ATMEL_SPW; + sdev->progMaxLength = 128; // 128 byte buffer + sdev->progAlignMask = 128 - 1; // 128 byte alignment requirement + sdev->byteProgramTimeout = 5 * 1000; // Byte program timeout is 5ms + sdev->eraseSectorTimeout = 1 * 1000; // Sectory Erase timeout is 1ms + break; +#endif + + default : + return -1; + } + +#endif /* ! READ_ONLY */ + + return 0; +} + +static void flash_spi_setup_bus(struct spi_ndev *sdev) +{ + spi_setup(sdev->spiBus, sdev->spiFrequency, (sdev->spiMode >> 16) & 0xff, 1, (sdev->spiMode >> 8) & 0xff, (sdev->spiMode >> 0) & 0xff); +} + +static int flash_spi_wait_busy(struct spi_ndev *sdev, u_int32_t timeout) +{ + u_int8_t data; + bool timeOut; + utime_t startTime = system_time(); + int result = -2; + + do { + timeOut = time_has_elapsed(startTime, timeout); + data = flash_spi_read_rdsr(sdev); + + if ((data & SPI_FLASH_STATUS_BUSY) == 0) result = 0; + } while ((result < 0) && !timeOut); + + if (result < 0) dprintf(DEBUG_INFO, "flash_spi_wait_busy: result: %d\n", result); + + return result; +} + +static u_int8_t flash_spi_read_rdsr(struct spi_ndev *sdev) +{ + u_int8_t data = SPI_FLASH_CMD_RDSR; + + flash_spi_select(sdev, true); + spi_write_etc(sdev->spiBus, &data, 1, 1, 0); // wait, no rx + spi_read_etc(sdev->spiBus, &data, 1, 1, 0); // wait, no tx + flash_spi_select(sdev, false); + + return data; +} + +static void flash_spi_select(struct spi_ndev *sdev, bool enable) +{ +#if defined(GPIO_SPI0_CS) || defined(GPIO_SPI1_CS) + /* this is still bogus */ + gpio_write(sdev->spiChipSelect, enable ? 0 : 1); +#else + spi_select(sdev->spiBus, enable); +#endif +} + +#if !READ_ONLY + +static void flash_spi_write_enable(struct spi_ndev *sdev, bool enable) +{ + u_int8_t data; + + data = enable ? SPI_FLASH_CMD_WREN : SPI_FLASH_CMD_WRDI; + flash_spi_select(sdev, true); + spi_write_etc(sdev->spiBus, &data, 1, 1, 0); // wait, no rx + flash_spi_select(sdev, false); +} + +static void flash_spi_write_wrsr(struct spi_ndev *sdev, u_int8_t wrsr) +{ + u_int8_t data[2]; + u_int8_t done; + + flash_spi_write_enable(sdev, true); + + data[0] = SPI_FLASH_CMD_WRSR; + data[1] = wrsr; + flash_spi_select(sdev, true); + spi_write_etc(sdev->spiBus, data, 2, 1, 0); // wait, no rx + flash_spi_select(sdev, false); + + done = 1; + while (done) { + done = flash_spi_read_rdsr(sdev) & 1; + spin(1); + } +} + +static u_int32_t flash_spi_read_jedec_id(struct spi_ndev *sdev) +{ + u_int8_t addr = SPI_FLASH_CMD_JEDEC_ID; + u_int32_t data = 0; + + flash_spi_select(sdev, true); + spi_write_etc(sdev->spiBus, &addr, 1, 1, 0); // wait, no rx + spi_read_etc(sdev->spiBus, &data, 3, 1, 0); // wait, no tx + flash_spi_select(sdev, false); + + return (data & 0x0000FF00) | ((data >> 16) & 0x000000FF) | ((data << 16) & 0x00FF0000); +} + +#endif /* ! READ_ONLY */ diff --git a/drivers/hdc/boot/rules.mk b/drivers/hdc/boot/rules.mk new file mode 100644 index 0000000..78c505e --- /dev/null +++ b/drivers/hdc/boot/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_SW_H2FMI=1 + +MODULES += \ + lib/blockdev + +ALL_OBJS += \ + $(LOCAL_DIR)/sw_h2fmi.o diff --git a/drivers/hdc/boot/sw_h2fmi.c b/drivers/hdc/boot/sw_h2fmi.c new file mode 100644 index 0000000..5705a55 --- /dev/null +++ b/drivers/hdc/boot/sw_h2fmi.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include "sw_h2fmi_private.h" + +#include +#include +#include +#include + +static int sw_h2fmi_blockdev_read_block(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count) +{ + uint32_t addr_size; + int ret = 0; + uint32_t page_start, page_end; + register uint32_t* dest = (uint32_t*)ptr; + + /* sanity-check the starting block and count */ + if ((block >= bdev->block_count) || (count > bdev->block_count) || (NULL == ptr)) + return ret; + + /* adjust the operation length if it overruns */ + if (block > (bdev->block_count - count)) + count = bdev->block_count - block; + + addr_size = 4; // Any number > 0 will do + page_start = (block / 3); + page_end = ((block + count + 2) / 3); + + /* Reset the device */ + rFASTSIM_H2FMI_CMD = FASTSIM_H2FMI_RESET; + + for (uint32_t page = page_start; page < page_end; page++) { + uint32_t block_addr2, block_addr1, block_addr0; + const uint32_t words_per_loop = 8; + + block_addr2 = ((page) >> 16) & 0xFF; + block_addr1 = ((page) >> 8) & 0xFF; + block_addr0 = ((page) >> 0) & 0xFF; + + /* Send the offset to device */ + rFASTSIM_H2FMI_ADDR0 = ((block_addr1 << 24) | (block_addr0 << 16)); + rFASTSIM_H2FMI_ADDR1 = block_addr2; + rFASTSIM_H2FMI_ADDRNUM = (addr_size & 0x7); + + /* Roll in the data */ + for (uint32_t sector = 0; sector < FASTSIM_H2FMI_BLOCK_PER_PAGE; sector++) { + register uint32_t index = ((FASTSIM_H2FMI_BLOCK_SIZE / sizeof(uint32_t)) / words_per_loop); + do { + register uint32_t tmp0; + register uint32_t tmp1; + register uint32_t tmp2; + register uint32_t tmp3; + register uint32_t tmp4; + register uint32_t tmp5; + register uint32_t tmp6; + register uint32_t tmp7; + + tmp0 = rFASTSIM_H2FMI_DATA_BUF; + tmp1 = rFASTSIM_H2FMI_DATA_BUF; + tmp2 = rFASTSIM_H2FMI_DATA_BUF; + tmp3 = rFASTSIM_H2FMI_DATA_BUF; + tmp4 = rFASTSIM_H2FMI_DATA_BUF; + tmp5 = rFASTSIM_H2FMI_DATA_BUF; + tmp6 = rFASTSIM_H2FMI_DATA_BUF; + tmp7 = rFASTSIM_H2FMI_DATA_BUF; + + if ((((page * 3) + sector) >= block) && (((page * 3) + sector) < (block + count))) { + *dest++ = tmp0; + *dest++ = tmp1; + *dest++ = tmp2; + *dest++ = tmp3; + *dest++ = tmp4; + *dest++ = tmp5; + *dest++ = tmp6; + *dest++ = tmp7; + } + } while (--index); + } + } + + return count; +} + +/* to-do: write and erase */ + +int sw_h2fmi_init(void) +{ + struct blockdev *sw_h2fmi_dev; + + sw_h2fmi_dev = malloc(sizeof(struct blockdev)); + if (sw_h2fmi_dev == NULL) { + dprintf(DEBUG_CRITICAL, "sw_h2fmi_init: failed to create blockdev\n"); + return -3; + } + memset(sw_h2fmi_dev, 0, sizeof(struct blockdev)); + + /* create the block device */ + construct_blockdev(sw_h2fmi_dev, "sw-h2fmi", FASTSIM_H2FMI_BLOCK_SIZE * FASTSIM_H2FMI_BLOCK_NUMBER, FASTSIM_H2FMI_BLOCK_SIZE); + sw_h2fmi_dev->read_block_hook = &sw_h2fmi_blockdev_read_block; + + /* register it in the block device namespace */ + register_blockdev(sw_h2fmi_dev); + + return 0; +} + diff --git a/drivers/hdc/boot/sw_h2fmi_private.h b/drivers/hdc/boot/sw_h2fmi_private.h new file mode 100644 index 0000000..bf34abb --- /dev/null +++ b/drivers/hdc/boot/sw_h2fmi_private.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define FASTSIM_H2FMI_BLOCK_PER_PAGE (3) +#define FASTSIM_H2FMI_BLOCK_SIZE (512) +#define FASTSIM_H2FMI_BLOCK_NUMBER (16384) + +/* Register base and offsets address used for FastSim */ +#define FASTSIM_H2FMI_BASE_ADDR (0x31200000) + +#define rFASTSIM_H2FMI_DATA_BUF (*(volatile u_int32_t *)(FASTSIM_H2FMI_BASE_ADDR + 0x00014)) +#define rFASTSIM_H2FMI_DEBUG0 (*(volatile u_int32_t *)(FASTSIM_H2FMI_BASE_ADDR + 0x0001C)) +#define rFASTSIM_H2FMI_CMD (*(volatile u_int32_t *)(FASTSIM_H2FMI_BASE_ADDR + 0x40014)) +#define rFASTSIM_H2FMI_ADDR0 (*(volatile u_int32_t *)(FASTSIM_H2FMI_BASE_ADDR + 0x40018)) +#define rFASTSIM_H2FMI_ADDR1 (*(volatile u_int32_t *)(FASTSIM_H2FMI_BASE_ADDR + 0x4001C)) +#define rFASTSIM_H2FMI_ADDRNUM (*(volatile u_int32_t *)(FASTSIM_H2FMI_BASE_ADDR + 0x40020)) +#define rFASTSIM_H2FMI_STATUS (*(volatile u_int32_t *)(FASTSIM_H2FMI_BASE_ADDR + 0x40044)) + +/* CMD */ +#define FASTSIM_H2FMI_RESET (0xFF) + diff --git a/drivers/hdc/hdc.c b/drivers/hdc/hdc.c new file mode 100644 index 0000000..af42022 --- /dev/null +++ b/drivers/hdc/hdc.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +//#include +//#include +#include "hdc_private.h" + +static int hdc_read_block_hook(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count) +{ + register uint32_t* dest = (uint32_t*)ptr; + + /* sanity-check the starting block and count */ + if ((block >= bdev->block_count) || (count > bdev->block_count) || (NULL == ptr)) + return 0; + + /* adjust the operation length if it overruns */ + if (block > (bdev->block_count - count)) + count = bdev->block_count - block; + + /* Reset HDC? */ + for (uint32_t block_start = block; block_start < (block + count); block_start++) { + uint32_t hdc_cmd = 0; + + hdc_cmd = HDC_SET_CMD_CMD(hdc_cmd, HDC_CMD_READ); + hdc_cmd = HDC_SET_CMD_CMD(hdc_cmd, HDC_CMD_INT); + hdc_cmd = HDC_SET_CMD_DISK(hdc_cmd, 0); + hdc_cmd = HDC_SET_CMD_LEN(hdc_cmd, 0); + + rHDC_DMA = (uint32_t)dest; + rHDC_FIRST = block_start; + rHDC_CMD = hdc_cmd; + + while (HDC_ST_DONE != HDC_GET_STATUS_ST(rHDC_STATUS)) + ; + dest += (HDC_BLKSIZE / 4); + } + + return count; +} + +int hdc_init(void) +{ + struct blockdev *hdc; + off_t len; + size_t block_size = (HDC_BLKSIZE); + + hdc = malloc(sizeof(struct blockdev)); + if (!hdc) + panic("error allocation hdc block device\n"); + + len = (rHDC_DRV_SIZE) * HDC_BLKSIZE; + construct_blockdev(hdc, "hdc0", len, block_size); + + hdc->read_block_hook = &hdc_read_block_hook; + + register_blockdev(hdc); + + /* scan ourselfs for partitions and publish subdevices */ + partition_scan_and_publish_subdevices("hdc0"); + + return 0; +} + + diff --git a/drivers/hdc/hdc_private.h b/drivers/hdc/hdc_private.h new file mode 100644 index 0000000..95070fc --- /dev/null +++ b/drivers/hdc/hdc_private.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Base address for the fake device */ +#define HDC_BASE_ADDR (0x70000000) + +/* Registers */ +#define rHDC_CMD (*(volatile u_int32_t *)(HDC_BASE_ADDR + 0x000)) +#define rHDC_FIRST (*(volatile u_int32_t *)(HDC_BASE_ADDR + 0x010)) +#define rHDC_STATUS (*(volatile u_int32_t *)(HDC_BASE_ADDR + 0x030)) +#define rHDC_DRV_SIZE (*(volatile u_int32_t *)(HDC_BASE_ADDR + 0x080)) +#define rHDC_DMA (*(volatile u_int32_t *)(HDC_BASE_ADDR + 0x100)) + +/* Register operations */ +#define HDC_SET_CMD_CMD(r,c) ((r) | (((c) & 0xff) << 24)) +#define HDC_SET_CMD_DISK(r,c) ((r) | (((c) & 0xff) << 16)) +#define HDC_SET_CMD_LEN(r,c) ((r) | (((c) & 0xff) << 0)) + +#define HDC_GET_STATUS_ST(r) (((r) >> 24) & 0xff) +#define HDC_GET_STATUS_DISK(r) (((r) >> 16) & 0xff) +#define HDC_GET_STATUS_CNT(r) (((r) >> 0) & 0xffff) + +/* Constant values */ +#define HDC_BLKSIZE (512) +#define HDC_MAX_SIZE (0x1000000000) + +#define HDC_CMD_READ (0x01) +#define HDC_CMD_WRITE (0x02) +#define HDC_CMD_INT (0x80) +#define HDC_CMD_MASK (0X7F) + +#define HDC_ST_READY (0) +#define HDC_ST_BUSY (1) +#define HDC_ST_DONE (2) +#define HDC_ST_ERROR (3) + diff --git a/drivers/hdc/rules.mk b/drivers/hdc/rules.mk new file mode 100644 index 0000000..dd1dc69 --- /dev/null +++ b/drivers/hdc/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_SW_HDC=1 + +MODULES += \ + lib/blockdev + +ALL_OBJS += \ + $(LOCAL_DIR)/hdc.o diff --git a/drivers/hdmi/controller.c b/drivers/hdmi/controller.c new file mode 100644 index 0000000..b4d74a7 --- /dev/null +++ b/drivers/hdmi/controller.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include + +#include + +///////////////////////////////////////// +////////// debug support + +#define HDMI_DEBUG_MASK ( \ + HDMI_DEBUG_INIT | \ + HDMI_DEBUG_ERROR | \ + HDMI_DEBUG_INFO | \ + HDMI_DEBUG_TRAINING | \ + 0) + +#undef HDMI_DEBUG_MASK +#define HDMI_DEBUG_MASK (HDMI_DEBUG_INIT | HDMI_DEBUG_ERROR) + +#define HDMI_DEBUG_INIT (1<<16) // initialisation +#define HDMI_DEBUG_ERROR (1<<17) // errors +#define HDMI_DEBUG_INFO (1<<18) // info +#define HDMI_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((HDMI_DEBUG_ ## _fac) & (HDMI_DEBUG_MASK | HDMI_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "HDMIC: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +///////////////////////////////////////// +////////// consts, macros + +#define kMaxRetry 5 +#define kClockRecoveryDelay 100 +#define kEQDelay 400 +#define kMaxClockRecoveryIterations 100 + + +#define require(assertion, exception_label) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +#define require_action(assertion, exception_label, action) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr(error_code, exception_label) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr_action(error_code, exception_label, action) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + + + +///////////////////////////////////////// +////////// typedefs, enums, structs + +///////////////////////////////////////// +////////// local variables + +static struct video_link_data hdmi_video_data; +static uint32_t hdmi_pixel_clock; + +///////////////////////////////////////// +////////// local functions declaration + + +///////////////////////////////////////// +////////// HDMI global functions + +int hdmi_init() +{ + // defaults to External display, and Master mode + if ( hdmi_controller_start(kHDMIControllerType_HDMI, kHDMIControllerMode_Master) != 0 ) + return -1; + + return 0; +} + +int hdmi_init_with_timing_info(struct display_timing *timing_info) +{ + u_int8_t type; + u_int8_t mode; + u_int32_t display_config; + + display_config = *((uint32_t *)(timing_info->display_config)); + type = (display_config >> kHDMIControllerType_Shift) & kHDMIControllerType_Mask; + mode = (display_config >> kHDMIControllerMode_Shift) & kHDMIControllerMode_Mask; + + hdmi_set_timings(timing_info); + + if ( hdmi_controller_start(type, mode) != 0 ) + return -1; + return 0; +} + +int hdmi_set_timings(struct display_timing *timing_info) +{ + u_int8_t mode; + u_int32_t display_config; + + display_config = *((uint32_t *)(timing_info->display_config)); + mode = (display_config >> kHDMIControllerMode_Shift) & kHDMIControllerMode_Mask; + + bzero(&hdmi_video_data, sizeof(struct video_link_data)); + + hdmi_pixel_clock = timing_info->pixel_clock; + + hdmi_video_data.mirror_mode = (mode == kHDMIControllerMode_Slave) ? true : false; + hdmi_video_data.test_mode = 0; + hdmi_video_data.color.depth = 8; + hdmi_video_data.color.space = kDisplayColorSpacesRGB; + hdmi_video_data.color.range = kDisplayColorDynamicRangeVESA; + hdmi_video_data.color.coefficient = kDisplayColorCoefficientITU601; + hdmi_video_data.timing.axis[0].total = timing_info->h_active + timing_info->h_back_porch + + timing_info->h_front_porch + timing_info->h_pulse_width; + hdmi_video_data.timing.axis[0].active = timing_info->h_active; + hdmi_video_data.timing.axis[0].sync_width = timing_info->h_pulse_width; + hdmi_video_data.timing.axis[0].back_porch = timing_info->h_back_porch; + hdmi_video_data.timing.axis[0].front_porch = timing_info->h_front_porch; + hdmi_video_data.timing.axis[0].sync_rate = 0; + // Hsync polarity: 0 active high, 1 active low + hdmi_video_data.timing.axis[0].sync_polarity = timing_info->neg_hsync ? 0 : 1; + hdmi_video_data.timing.axis[1].total = timing_info->v_active + timing_info->v_back_porch + + timing_info->v_front_porch + timing_info->v_pulse_width; + hdmi_video_data.timing.axis[1].active = timing_info->v_active; + hdmi_video_data.timing.axis[1].sync_width = timing_info->v_pulse_width; + hdmi_video_data.timing.axis[1].back_porch = timing_info->v_back_porch; + hdmi_video_data.timing.axis[1].front_porch = timing_info->v_front_porch; + hdmi_video_data.timing.axis[1].sync_rate = (60 << 16); + // Vsync polarity: 0 active high, 1 active low + hdmi_video_data.timing.axis[1].sync_polarity = timing_info->neg_vsync ? 0 : 1; + + debug(INFO, "vTotal:%d hTotal:%d\n", hdmi_video_data.timing.axis[1].total, hdmi_video_data.timing.axis[0].total); + + // Restrict EDID choices to timings matching these, otherwise the + // framebuffer dimensions will mismatch. + restrict_edid(hdmi_video_data.timing.axis[0].active, + hdmi_video_data.timing.axis[1].active); + + return 0; +} + +void hdmi_quiesce() +{ + hdmi_controller_stop(); +} + +int hdmi_start_video(void) +{ + return hdmi_controller_start_video(&hdmi_video_data, hdmi_pixel_clock); +} + +bool hdmi_video_configured() +{ + return hdmi_controller_video_configured(); +} + +///////////////////////////////////////// +////////// controller global functions + +///////////////////////////////////////// +////////// controller local functions + diff --git a/drivers/hdmi/debug.c b/drivers/hdmi/debug.c new file mode 100644 index 0000000..f26347d --- /dev/null +++ b/drivers/hdmi/debug.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include + +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +static struct video_link_data hdmi_video_data; + +int do_hdmi(int argc, struct cmd_arg *args) +{ + static struct display_timing timing_list[] = + { +#if WITH_HW_DISPLAY_HDMI + { "720p", 0, 74250000, 243, 1280, 220, 110, 40, 720, 20, 5, 5, 0, 0, 0, 0, 24, DISPLAY_TYPE_HDMI, NULL}, +#endif + }; + if (argc < 2) { + puts("not enough arguments.\n"); + goto usage; + } + + if (strcmp("start", args[1].str) == 0) { + + printf("MY PIXEL CLOCK %d\n", timing_list[0].pixel_clock); + hdmi_init(&timing_list[0]); + + bzero(&hdmi_video_data, sizeof(struct video_link_data)); + + hdmi_video_data.mirror_mode = false; + hdmi_video_data.test_mode = 0; + hdmi_video_data.color.depth = 8; + hdmi_video_data.color.space = kDisplayColorSpacesRGB; + hdmi_video_data.color.range = kDisplayColorDynamicRangeVESA; + hdmi_video_data.color.coefficient = kDisplayColorCoefficientITU601; + hdmi_video_data.timing.axis[0].total = timing_list[0].h_active + timing_list[0].h_back_porch + timing_list[0].h_front_porch + timing_list[0].h_pulse_width; + hdmi_video_data.timing.axis[0].active = timing_list[0].h_active; + hdmi_video_data.timing.axis[0].sync_width = timing_list[0].h_pulse_width; + hdmi_video_data.timing.axis[0].back_porch = timing_list[0].h_back_porch; + hdmi_video_data.timing.axis[0].front_porch = timing_list[0].h_front_porch; + hdmi_video_data.timing.axis[0].sync_rate = 0; + hdmi_video_data.timing.axis[0].sync_polarity = 0; + hdmi_video_data.timing.axis[1].total = timing_list[0].v_active + timing_list[0].v_back_porch + timing_list[0].v_front_porch + timing_list[0].v_pulse_width; + hdmi_video_data.timing.axis[1].active = timing_list[0].v_active; + hdmi_video_data.timing.axis[1].sync_width = timing_list[0].v_pulse_width; + hdmi_video_data.timing.axis[1].back_porch = timing_list[0].v_back_porch; + hdmi_video_data.timing.axis[1].front_porch = timing_list[0].v_front_porch; + hdmi_video_data.timing.axis[1].sync_rate = 60 << 16; + hdmi_video_data.timing.axis[1].sync_polarity = 0; + + } else if (strcmp("stop", args[1].str) == 0) { + hdmi_quiesce(); + } else if (strcmp("video", args[1].str) == 0) { + if (strcmp("logo", args[2].str) == 0) { + hdmi_video_data.mirror_mode = false; + hdmi_video_data.test_mode = 0; + + hdmi_controller_start_video(&hdmi_video_data, timing_list[0].pixel_clock); + } + if (strcmp("bist", args[2].str) == 0) { + + hdmi_video_data.mirror_mode = false; + hdmi_video_data.test_mode = 1; + + hdmi_controller_start_video(&hdmi_video_data, timing_list[0].pixel_clock); + } + if (strcmp("mirror", args[2].str) == 0) { + hdmi_video_data.mirror_mode = true; + hdmi_video_data.test_mode = 0; + + hdmi_controller_start_video(&hdmi_video_data, timing_list[0].pixel_clock); + } + } else if (strcmp("readReg", args[1].str) == 0) { + hdmi_read_reg(args[2].n); + } else if (strcmp("writeReg", args[1].str) == 0) { + hdmi_write_reg(args[2].n, args[3].n); + } else { + puts("unrecognized command.\n"); + goto usage; + } + + return 0; + +usage: + printf("%s start\n", args[0].str); + printf("%s video logo\n", args[0].str); + printf("%s video bist\n", args[0].str); + printf("%s video mirror\n", args[0].str); + printf("%s stop\n", args[0].str); + printf("%s readReg\n", args[0].str); + printf("%s writeReg\n", args[0].str); + + return -1; +} + +MENU_COMMAND_DEVELOPMENT(hdmi, do_hdmi, "hdmi stuff", NULL); + +#endif diff --git a/drivers/hdmi/device.c b/drivers/hdmi/device.c new file mode 100644 index 0000000..7f48379 --- /dev/null +++ b/drivers/hdmi/device.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include + +#include +#include +#include + +#include + + +///////////////////////////////////////// +////////// debug support + +#define HDMI_DEBUG_MASK ( \ + HDMI_DEBUG_INIT | \ + HDMI_DEBUG_ERROR | \ + HDMI_DEBUG_INFO | \ + HDMI_DEBUG_TRAINING | \ + 0) + +#undef HDMI_DEBUG_MASK +#define HDMI_DEBUG_MASK (HDMI_DEBUG_INIT | HDMI_DEBUG_ERROR) + +#define HDMI_DEBUG_INIT (1<<16) // initialisation +#define HDMI_DEBUG_INFO (1<<17) // info +#define HDMI_DEBUG_TRAINING (1<<18) // link training +#define HDMI_DEBUG_WAIT (1<<19) // start wait +#define HDMI_DEBUG_ERROR (1<<20) // error +#define HDMI_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((HDMI_DEBUG_ ## _fac) & (HDMI_DEBUG_MASK | HDMI_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "DPD: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +///////////////////////////////////////// +////////// consts + +// Do not delay iBoot by more than this amount from power on (microseconds). +// Give up waiting for a boot logo and carry on at this point. +#define kHDMIDeviceStartTimeout (8 * 1000 * 1000) + +///////////////////////////////////////// +////////// typedefs, enums, structs + +#define require_action(assertion, exception_label, action) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr(error_code, exception_label) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +///////////////////////////////////////// +////////// local variables + + +///////////////////////////////////////// +////////// local functions declaration + +static int set_power(bool enable); + +static struct task_event hdmi_device_start_event = + EVENT_STATIC_INIT(hdmi_device_start_event, false, 0); +static bool hdmi_device_started; +static bool hdmi_device_start_error; +static utime_t hdmi_device_started_time; + +extern utime_t gPowerOnTime; + +///////////////////////////////////////// +////////// hdmi-device global functions + +int hdmi_device_start() +{ + int ret = -1; + + if ( hdmi_device_started ) + return 0; + + + debug(INIT, "starting\n"); + + if ( set_power(true) != 0 ) { + debug(ERROR, "failed to set power\n"); + goto exit; + } + + if ( obtain_edid() == 0 ) { + // Enable info frames if HDMI endpoint connected, so + // we get the right color space. + } else { + // Non-fatal. + debug(ERROR, "Couldn't get EDID\n"); + } + + if ( hdmi_start_video() != 0 ) { + debug(ERROR, "failed to start video\n"); + goto exit; + } + + hdmi_device_started = true; + + ret = 0; + +exit: + if (ret != 0) { + hdmi_device_start_error = true; + debug(ERROR, "error starting device\n"); + } + + hdmi_device_started_time = system_time(); + event_signal(&hdmi_device_start_event); + + return ret; +} + +int hdmi_device_wait_started() +{ + utime_t wait_start = system_time(); + utime_t timeout = gPowerOnTime + kHDMIDeviceStartTimeout; + + if (hdmi_device_started || hdmi_device_start_error) { + debug(WAIT, "HDMI done with %d usecs to spare\n", + (int) (wait_start - hdmi_device_started_time)); + goto exit; + } + + while (!hdmi_device_started && !hdmi_device_start_error) { + utime_t now = system_time(); + if (now >= timeout) { + debug(WAIT, "Timeout waiting for HDMI start\n"); + return -1; + } + event_wait_timeout(&hdmi_device_start_event, timeout - now); + } + debug(WAIT, "Delayed boot by %llu usecs\n", system_time() - wait_start); + exit: + debug(WAIT, "Started waiting %llu usecs after power on\n", + wait_start - gPowerOnTime); + return hdmi_device_start_error ? -1 : 0; +} + +void hdmi_device_stop() +{ + if ( !hdmi_device_started ) + return; + + hdmi_controller_stop_video(); + + set_power(false); + + hdmi_device_started = false; +} + + +///////////////////////////////////////// +////////// hdmi-device local functions + +static int set_power(bool state) +{ + int ret = 0; + + return ret; +} + + diff --git a/drivers/hdmi/edid.h b/drivers/hdmi/edid.h new file mode 100644 index 0000000..f694fef --- /dev/null +++ b/drivers/hdmi/edid.h @@ -0,0 +1,377 @@ +/* + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 2012 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IOKIT_EDID_H +#define _IOKIT_EDID_H + + +#define kEDIDEstablishedTimingsCount 24 +#define kEDIDEstablishedTimingsIIICount 48 + +typedef struct __attribute__((packed)) _EDIDDetailedHeader { + uint8_t header[2]; +}EDIDDetailedHeader; + +//__packed +typedef struct __attribute__((packed)) _EDIDDetailedTiming { + uint8_t pixelClock[2]; + + uint8_t hor_addr_low; + uint8_t hor_blank_low; + uint8_t hor_addr_blank_high; + uint8_t ver_addr_low; + uint8_t ver_blank_low; + uint8_t ver_addr_blank_high; + + uint8_t hor_fporch; // #8 + uint8_t hor_sync; + uint8_t ver_fporch_sync; + + uint8_t hor_ver_porch_sync_high; + uint8_t inmm[3]; // in milimeter + uint8_t hor_border; + uint8_t ver_border; + uint8_t detailed; +} EDIDDetailedTiming; + +typedef struct __attribute__((packed)) _EDIDString{ + uint8_t flag; + char string[13]; +} EDIDString; + +typedef enum { + kEDIDDetailedRangeFlagRateOffsetVerticalMin = (1<<0), + kEDIDDetailedRangeFlagRateOffsetVerticalMax = (1<<1), + kEDIDDetailedRangeFlagRateOffsetHorizontalMin = (1<<2), + kEDIDDetailedRangeFlagRateOffsetHorizontalMax = (1<<3) +} EDIDDetailedRangeFlags; + +enum { + kEDIDDetailedRangeVideoTimingTypeGTF = 0, + kEDIDDetailedRangeVideoTimingTypeRangeLimitsOnly = 1, + kEDIDDetailedRangeVideoTimingTypeSecondaryGTF = 2, + kEDIDDetailedRangeVideoTimingTypeCVT = 4 +}; +typedef uint8_t EDIDDetailedRangeVideoTimingType; + +typedef enum { + kEDIDSupportedAspectFlag15_9 = (1<<3), + kEDIDSupportedAspectFlag5_4 = (1<<4), + kEDIDSupportedAspectFlag16_10 = (1<<5), + kEDIDSupportedAspectFlag16_9 = (1<<6), + kEDIDSupportedAspectFlag4_3 = (1<<7) +} EDIDSupportedAspectFlags; + +typedef enum { + kEDIDPreferredAspectType4_3, + kEDIDPreferredAspectType16_9, + kEDIDPreferredAspectType16_10, + kEDIDPreferredAspectType5_4, + kEDIDPreferredAspectType15_9, + kEDIDPreferredAspectTypeShift = 5, + kEDIDPreferredAspectTypeMask = 0x7, + +} EDIDPreferredAspectType; + +typedef enum { + kEDIDCVTBlankingFlagStandard = (1<<3), + kEDIDCVTBlankingFlagReduced = (1<<4), +} EDIDCVTBlankingFlags; + +typedef enum { + kEDIDDigitalScalingFlagVerticalStretch = (1<<4), + kEDIDDigitalScalingFlagVerticalShrink = (1<<5), + kEDIDDigitalScalingFlagHorizontalStretch = (1<<6), + kEDIDDigitalScalingFlagHorizontalShrink = (1<<7) +} EDIDDigitalScalingFlags; + + +typedef struct __attribute__((packed)) _EDIDDetailedRangeGTF { + uint8_t reserved; + uint8_t breakFrequency; // horizontal freq / 2 (khz) + uint8_t c; // c*2 + uint8_t m[2]; + uint8_t k; + uint8_t j; // j*2 +} EDIDDetailedRangeGTF; + +typedef struct __attribute__((packed)) _EDIDDetailedRangeCVT { + uint8_t version; + // Max. Pix Clk = [(range.maxPixelClockRate) × 10] – [(Byte 12: bits 7-2) × 0.25MHz] + uint8_t precision_activeMaxMSB; // pixel clock precision * 0.25Mhz (bits 7-2) | max active pixels per line MSB (bits 1-0) + uint8_t activeMaxLSB; // max active pixels per line MSB + uint8_t supportedFlags; + uint8_t preferredFlags; + uint8_t scaling; + uint8_t verticalRefreshRate; //hz +} EDIDDetailedRangeCVT; + +typedef struct __attribute__((packed)) _EDIDDetailedRange{ + uint8_t flag; + uint8_t minVerticalRate; + uint8_t maxVerticalRate; + uint8_t minHorizontalRate; + uint8_t maxHorizontalRate; + uint8_t maxPixelClockRate; + + struct { + EDIDDetailedRangeVideoTimingType type; + + union { + EDIDDetailedRangeGTF gtf; + EDIDDetailedRangeCVT cvt; + } data; + }timing; + +} EDIDDetailedRange; + +typedef struct __attribute__((packed)) _EDIDDetailedWhitePoint { + uint8_t index; + uint8_t xyLSB; + uint8_t x; + uint8_t y; + uint8_t gamma; +} EDIDDetailedWhitePoint; + +typedef struct __attribute__((packed)) _EDIDDetailedColorPoint { + EDIDDetailedWhitePoint whitePoint[2]; +} EDIDDetailedColorPoint; + +typedef struct __attribute__((packed)) _EDIDDetailedEstablishedTimingsIII { + uint8_t data[6]; +} EDIDDetailedEstablishedTimingsIII; + +typedef struct __attribute__((packed)) _EDIDDetailedDescriptor { + uint8_t zero[2]; + uint8_t flag; + uint8_t type; + + union { + EDIDString name; + EDIDDetailedRange range; + EDIDDetailedColorPoint color; + uint8_t standard[12]; + uint8_t cvt[12]; + EDIDDetailedEstablishedTimingsIII established; + }data; + +}EDIDDetailedDescriptor; + + +typedef struct __attribute__((packed)) EDIDDetailed { + + union { + EDIDDetailedHeader header; + EDIDDetailedTiming timing; + EDIDDetailedDescriptor descriptor; + } data; + +} EDIDDetailed; + + +typedef struct __attribute__((packed)) _EDIDHeader { + uint8_t header[8]; +} EDIDHeader; + +typedef enum { + kEDIDStandardFeatureFlagGTF = (1<<0), + kEDIDStandardFeatureFlagPreferredNative = (1<<1), + kEDIDStandardFeatureFlagSRGB = (1<<2), + kEDIDStandardFeatureFlagColorDepth = (3<<3), + kEDIDStandardFeatureFlagActiveOff = (1<<5), + kEDIDStandardFeatureFlagSuspend = (1<<6), + kEDIDStandardFeatureFlagStandby = (1<<7) +} EDIDStandardFeatureFlags; + +// STANDARD STUFF +typedef struct __attribute__((packed)) _EDIDStandard { + uint8_t header[8]; + // Vender / Product + uint8_t vendorID[2]; + uint8_t productID[2]; + uint8_t serialNumber[4]; + uint8_t weekOfManu; + uint8_t yearOfManu; + // EDID structure version / rev. + uint8_t version; + uint8_t revision; + // Basic Display Parameters / Features + uint8_t videoInputDef; + uint8_t maxHorzSize; // cm + uint8_t maxVertSize; // cm + uint8_t dispTransferChr; + uint8_t feature; + // Color Characteristics + uint8_t redGreenLowBits; + uint8_t blueWhiteLowBits; + uint8_t redX; + uint8_t redY; + uint8_t greenX; + uint8_t greenY; + uint8_t blueX; + uint8_t blueY; + uint8_t whiteX; + uint8_t whiteY; + // Established Timings + uint8_t established[3]; + // Standard Timing Identification + uint8_t standard[16]; + EDIDDetailed preferred; + EDIDDetailed detailed[3]; + // Extra + uint8_t extensionFlag; + uint8_t checksum; +} EDIDStandard; + + +typedef struct __attribute__((packed)) _EDIDEXTHeader { + uint8_t tag; + uint8_t revision; +} EDIDEXTHeader; + +typedef struct __attribute__((packed)) _EDIDCVT { + uint8_t data[3]; +} EDIDCVT; + +// CEA STUFF + +typedef enum { + kEDIDCEA3DataBlockTypeReserved, + kEDIDCEA3DataBlockTypeAudio, + kEDIDCEA3DataBlockTypeVideo, + kEDIDCEA3DataBlockTypeVenderSpecific, + kEDIDCEA3DataBlockTypeSpeakerAllocation, + kEDIDCEA3DataBlockTypeVESADTC, + kEDIDCEA3DataBlockTypeReserved1, + kEDIDCEA3DataBlockTypeExtended +} EDIDCEA3DataBlockType; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockAudio { + uint8_t descriptor[0]; +} EDIDCEA3DataBlockAudio; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockVideo { + uint8_t descriptor[0]; +} EDIDCEA3DataBlockVideo; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockVendorSpecific { + uint8_t ieeeOui[3]; + uint8_t data[0]; +} EDIDCEA3DataBlockVendorSpecific; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockSpeakerAllocation { + uint8_t data[3]; +} EDIDCEA3DataBlockSpeakerAllocation; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlockExtended { + uint8_t tag; + uint8_t data[31]; +} EDIDCEA3DataBlockExtended; + +typedef struct __attribute__((packed)) _EDIDCEA3DataBlock { + uint8_t flags; + + union { + EDIDCEA3DataBlockAudio audio; + EDIDCEA3DataBlockVideo video; + EDIDCEA3DataBlockVendorSpecific vendor; + EDIDCEA3DataBlockSpeakerAllocation speaker; + EDIDCEA3DataBlockExtended extended; + } data; + +} EDIDCEA3DataBlock; + +typedef struct __attribute__((packed)) _EDIDCEA_1 { + struct { + uint8_t tag; + uint8_t revision; + uint8_t dataOffset; + uint8_t reserved; + } header; + + uint8_t data[123]; + uint8_t checksum; +} EDIDCEA_1; + +typedef struct __attribute__((packed)) _EDIDCEA_2 { + struct { + uint8_t tag; + uint8_t revision; + uint8_t dataOffset; + uint8_t detailedFlags; + } header; + + uint8_t data[123]; + uint8_t checksum; +} EDIDCEA_2; + +typedef struct __attribute__((packed)) _EDIDCEA_3 { + struct { + uint8_t tag; + uint8_t revision; + uint8_t dataLength; + uint8_t detailedFlags; + } header; + uint8_t data[123]; + uint8_t checksum; +} EDIDCEA_3; + +typedef struct __attribute__((packed)) _EDIDCEA { + union { + EDIDEXTHeader header; + EDIDCEA_1 cea1; + EDIDCEA_2 cea2; + EDIDCEA_3 cea3; + } data; +} EDIDCEA; + +typedef struct __attribute__((packed)) _EDIDVTB{ + EDIDEXTHeader header; + uint8_t dtbCount; + uint8_t cvtCount; + uint8_t stCount; + uint8_t data[122]; + uint8_t checksum; +} EDIDVTB; + +typedef enum { + kEDIDTypeCEA = 0x02, + KEDIDTypeVTB = 0x10, + kEDIDTypeDI = 0x40, +} EDIDType; + +// __packed +typedef struct __attribute__((packed)) _EDID{ + union { + EDIDHeader header; + EDIDStandard standard; + EDIDCEA cea; + EDIDVTB vtb; + } data; + +} EDID; + + + +#endif /* _IOKIT_EDID_H */ diff --git a/drivers/hdmi/process_edid.c b/drivers/hdmi/process_edid.c new file mode 100644 index 0000000..6866289 --- /dev/null +++ b/drivers/hdmi/process_edid.c @@ -0,0 +1,1738 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * This file is based on a manual C++-to-C translation of: + * IODisplayPortFamily/IODPService.cpp + * The scoring system and timing collection is simplified. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include "edid.h" + +// I2C address for the EDID rom. +#define kI2CEdidReadDeviceAddr 0xA1 +#define kI2CEdidWriteDeviceAddr 0xA0 + +// H3 DisplayPipe has issues higher than this. +#define kMaxHorizontalActive 1280 + +// Some monitors are slow. Insert microseconds of dumb. +#define kEdidRetryTimeout 5000000 +// Some monitors are suspiciously single-threaded. Don't retry too +// often or they make no forward progress. +#define kEdidRetryDelay 250000 + +///////////////////////////////////////// +////////// debug support + +#define HDMIDEBUG_MASK ( \ + HDMIDEBUG_EDID | \ + HDMIDEBUG_ERROR | \ + HDMIDEBUG_INFO | \ + 0) + +#undef HDMIDEBUG_MASK +#define HDMIDEBUG_MASK HDMIDEBUG_ERROR // (HDMIDEBUG_EDID | HDMIDEBUG_SCORE | HDMIDEBUG_DS | HDMIDEBUG_ERROR | HDMIDEBUG_INFO) + +#define HDMIDEBUG_EDID (1<<16) // EDID parsing +#define HDMIDEBUG_SCORE (1<<17) // Final validation/scoring +#define HDMIDEBUG_DS (1<<18) // Downstream type detection +#define HDMIDEBUG_INFO (1<<19) // info +#define HDMIDEBUG_ERROR (1<<20) // error +#define HDMIDEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((HDMIDEBUG_ ## _fac) & (HDMIDEBUG_MASK | HDMIDEBUG_ALWAYS)) \ + dprintf(DEBUG_INFO, "EDID: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + +typedef struct { + // Slightly compacted vs IODPDisplayTimingElement.cpp + uint16_t horizontal; + uint16_t vertical; + uint32_t rate; +} __IODPTEEstablished; + +typedef enum { + kSupportFlagNone = (0<<0), + kSupportFlagGTF = (1<<0), + kSupportFlagCVT = (1<<1) +} SupportFlags; + +static int process_edid(EDID *edid); +static int verify_edid(EDID *edid, uint8_t *p_checksum); +static int get_edid(uint8_t offset, EDID *edid); +static int process_edid_vtb(EDIDVTB *vtb); +static int process_edid_cvt_timings(uint8_t *data, uint32_t length); +static int process_edid_cea(EDIDCEA *cea); +static int process_edid_cea1(EDIDCEA_1 *cea1); +static int process_edid_cea2(EDIDCEA_2 *cea2); +static int process_edid_cea3(EDIDCEA_3 *cea3); +static int process_edid_cea3_video(EDIDCEA3DataBlockVideo *video, uint32_t length); +static int process_edid_cea3_vendor_specific(EDIDCEA3DataBlockVendorSpecific *vendor, uint32_t length); +static int process_edid_standard(EDIDStandard *standard); +static int process_edid_standard_feature(EDIDStandard *standard); +static int process_edid_standard_timings(uint8_t *data, uint32_t length); +static int process_edid_standard_established_timings(EDIDStandard *standard); +static int process_edid_detailed(EDIDDetailed *detailed); +static int process_edid_detailed_descriptor(EDIDDetailedDescriptor *descriptor); +static int process_edid_detailed_established_timings_iii(EDIDDetailedEstablishedTimingsIII *established); +static int try_standard_timing_id(uint16_t timing_id); +static int try_established_timing_id(uint8_t index); +static int try_established_timing_iii_id(uint8_t establishedID); +static int try_detailed_timing(EDIDDetailedTiming *detailed); +static int try_cvt_timing_id(EDIDCVT *cvt); +static int try_cea_short_id(uint32_t shortVideoID); +static int get_timing_data_for_cea_short_id(uint32_t shortVideoID, struct video_timing_data *timingData); +static int use_dimensions(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_dmt(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_cvt(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_gtf(uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_dimensions_table(const struct video_timing_data * list, uint32_t count, uint32_t horizontal, uint32_t vertical, uint32_t rate); +static int use_timings(struct video_timing_data *data); +static uint16_t read_le16(const void *data, uint32_t offset); +static uint32_t read_le32(const void *data, uint32_t offset); + +static bool s_have_timings; +static bool s_abort_edid; +static struct video_timing_data s_best_timings; +static SupportFlags s_timing_support; +static uint32_t s_restrict_h_active; +static uint32_t s_restrict_v_active; +static int s_ds_type = -1; + + +int obtain_edid(void) +{ + int ret = -1; + EDID edid; + uint8_t ext_block_count; + uint8_t index = 0; + + s_have_timings = false; + bzero(&s_best_timings, sizeof(s_best_timings)); + s_timing_support = kSupportFlagNone; + s_ds_type = kHDMI_tx_mode_DVI; + + ret = get_edid(0, &edid); + debug(EDID, "Obtaining base EDID result=%d\n", ret); + if (ret) goto exit; + + ret = process_edid(&edid); + debug(EDID, "Processing EDID result=%d\n", ret); + if (ret) goto exit; + + ext_block_count = edid.data.standard.extensionFlag; + debug(EDID, "EDID contains %d extensions\n", ext_block_count); + + for (index = 1; index <= ext_block_count; ++index) { + ret = get_edid(index * sizeof(EDID), &edid); + debug(EDID, "Obtaining EDID extension %d result=%d\n", index, ret); + if (ret) goto exit; + + ret = process_edid(&edid); + debug(EDID, "Processing EDID extension %d result=%d\n", index, ret); + if (ret) goto exit; + } + debug(DS, "tx mode %d\n", s_ds_type); + + exit: + return ret; +} + +void abort_edid(void) +{ + s_abort_edid = true; +} + +void restrict_edid(uint32_t h_active, uint32_t v_active) +{ + s_restrict_h_active = h_active; + s_restrict_v_active = v_active; +} + +int get_edid_timings(struct video_timing_data *data) +{ + if (!s_have_timings) return -1; + bcopy(&s_best_timings, data, sizeof(s_best_timings)); + debug(ALWAYS, "EDID: %ux%u%c/%u\n", + s_best_timings.axis[kDisplayAxisTypeHorizontal].active, + s_best_timings.axis[kDisplayAxisTypeVertical].active, + s_best_timings.interlaced ? 'i' : 'p', + s_best_timings.axis[kDisplayAxisTypeVertical].sync_rate >> 16); + return 0; +} + +int get_edid_downstream_type(void) +{ + return s_ds_type; +} + +static int process_edid(EDID *edid) +{ + static const uint8_t edid_standard_header[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; + + debug(EDID, "Processing EDID\n"); + + if (!memcmp(edid->data.header.header, edid_standard_header, sizeof(edid_standard_header))) { + process_edid_standard(&edid->data.standard); + } else { + switch (edid->data.header.header[0]) { + case kEDIDTypeCEA: + process_edid_cea(&edid->data.cea); + break; + case KEDIDTypeVTB: + process_edid_vtb(&edid->data.vtb); + break; + default: + debug(EDID, "Unknown EDID type %d\n", edid->data.header.header[0]); + break; + } + } + return 0; +} + +static int process_edid_vtb(EDIDVTB *vtb) +{ + uint32_t index, length; + uint32_t dtbCount, cvtCount, stCount; + + debug(EDID, "Processing EDID VTB\n"); + + if (1 != vtb->header.revision) goto exit; + + if (!(vtb->dtbCount && vtb->cvtCount && vtb->stCount)) goto exit; + + length = sizeof(vtb->data); + index = 0; + dtbCount = vtb->dtbCount; + cvtCount = vtb->cvtCount; + stCount = vtb->stCount; + while ( indexremaining) + break; + + process_edid_detailed((EDIDDetailed*)&vtb->data[index]); + + index += sizeof(EDIDDetailed); + dtbCount--; + } + else if ( cvtCount ) { + uint32_t cvtLength = cvtCount * sizeof(EDIDCVT); + if (cvtLength>remaining) + break; + + process_edid_cvt_timings(&vtb->data[index], cvtLength); + + index += cvtLength; + cvtCount = 0; + } + else if ( stCount ) { + uint32_t stLength = stCount * sizeof(uint16_t); + if (stLength>remaining) + break; + + process_edid_standard_timings(&vtb->data[index], stLength); + + index += stLength; + stCount = 0; + } + else { + break; + } + } + exit: + return 0; +} + +static int process_edid_cvt_timings(uint8_t *data, uint32_t length) +{ + uint32_t index; + debug(EDID, "Processing EDID CVT timings\n"); + for( index = 0; index < length; index+=sizeof(EDIDCVT) ) { + try_cvt_timing_id((EDIDCVT*)&data[index]); + } + return 0; +} + +static int process_edid_cea(EDIDCEA *cea) +{ + debug(EDID, "Processing CEA EDID\n"); + + switch (cea->data.header.revision) { + case 1: + process_edid_cea1(&cea->data.cea1); + break; + case 2: + process_edid_cea2(&cea->data.cea2); + break; + case 3: + process_edid_cea3(&cea->data.cea3); + break; + default: + break; + } + + return 0; +} + +static int process_edid_cea1(EDIDCEA_1 * cea1) +{ + uint32_t relativeDataOffset; + uint32_t index = 0; + + debug(EDID, "Processing CEA v1 EDID\n"); + if (cea1->header.dataOffset<=sizeof(cea1->header)) return -1; + + relativeDataOffset = cea1->header.dataOffset-sizeof(cea1->header); + while ( relativeDataOffset < sizeof(cea1->data) && (sizeof(cea1->data)-relativeDataOffset) >= sizeof(EDIDDetailed)) { + debug(EDID, "Processing Detailed Timing index %d\n", index++); + process_edid_detailed((EDIDDetailed*)(cea1->data + relativeDataOffset)); + relativeDataOffset += sizeof(EDIDDetailed); + } + + return 0; +} + +static int process_edid_cea2(EDIDCEA_2 * cea2) +{ + debug(EDID, "Processing CEA v2 EDID\n"); + // Don't care about audio/color/overscan. Just pass it along. + return process_edid_cea1((EDIDCEA_1*)cea2); +} + +static int process_edid_cea3(EDIDCEA_3 * cea3) +{ + uint32_t startOffset = 0; + uint32_t length = 0; + uint32_t index = 0; + + debug(EDID, "Processing CEA v3 EDID\n"); + + if (cea3->header.dataLength <= sizeof(cea3->header) || cea3->header.dataLength>sizeof(EDIDCEA_3)) return -1; + + length = cea3->header.dataLength-sizeof(cea3->header); + while ( startOffset < length ) { + EDIDCEA3DataBlock * block = (EDIDCEA3DataBlock*)(cea3->data + startOffset); + EDIDCEA3DataBlockType blockType; + uint32_t blockLength; + uint32_t sectionLength; + + debug(EDID, "Processing CEA v3 EDID Data Block index %d\n", index++); + + // Check for padding + if ( !block->flags ) { + debug(EDID, "Encountered zero padding.\n"); + break; + } + + blockType = (EDIDCEA3DataBlockType)((block->flags>>5) & 0x7); + blockLength = (block->flags) & 0x1f; + + sectionLength = blockLength+sizeof(block->flags); + if ( sectionLength>(length-startOffset) ) return -1; + + debug(EDID, "Processing CEA v3 EDID Data Block type %d of length %d\n", + blockType, blockLength); + + switch ( blockType ) { + case kEDIDCEA3DataBlockTypeAudio: + // Don't care. + // process_edid_cea3_audio((EDIDCEA3DataBlockAudio*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeVideo: + process_edid_cea3_video((EDIDCEA3DataBlockVideo*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeSpeakerAllocation: + // Don't care. + // process_edid_cea3_speaker_allocation((EDIDCEA3DataBlockSpeakerAllocation*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeExtended: + // Don't care. + // process_edid_cea3_extended((EDIDCEA3DataBlockExtended*)&block->data, blockLength); + break; + case kEDIDCEA3DataBlockTypeVenderSpecific: + process_edid_cea3_vendor_specific((EDIDCEA3DataBlockVendorSpecific*)&block->data, blockLength); + break; + default: + break; + } + startOffset += sectionLength; + } + + return process_edid_cea2((EDIDCEA_2*)cea3); +} + +static int process_edid_cea3_video(EDIDCEA3DataBlockVideo * video, uint32_t length) +{ + uint32_t index; + + debug(EDID, "Processing CEA v3 EDID Video\n"); + + for ( index=0; indexdescriptor[index]; + debug(EDID, "Processing CEA ShortID %d\n", id); + try_cea_short_id(video->descriptor[index]); + } + + return 0; +} + +static int process_edid_cea3_vendor_specific(EDIDCEA3DataBlockVendorSpecific *vendor, uint32_t length) +{ + // Only care that this might be a signal we're HDMI. + static const uint8_t hdmi_out[] = { 0x03, 0x0c, 0x00 }; + if (!memcmp(hdmi_out, vendor->ieeeOui, sizeof(hdmi_out))) { + debug(DS, "EDID says oui, we're HDMI\n"); + s_ds_type = kHDMI_tx_mode_HDMI; + } + return 0; +} + +static int process_edid_standard(EDIDStandard *standard) +{ + debug(EDID, "Processing Standard EDID\n"); + + // Don't care about vendor/product IDs, color. + process_edid_standard_feature(standard); + process_edid_standard_established_timings(standard); + process_edid_standard_timings(standard->standard, sizeof(standard->standard)); + process_edid_detailed(&standard->preferred); + process_edid_detailed(&standard->detailed[0]); + process_edid_detailed(&standard->detailed[1]); + process_edid_detailed(&standard->detailed[2]); + + return 0; +} + +static int process_edid_standard_feature(EDIDStandard *standard) +{ + // Don't care about color, just HDMI vs DVI and timings. + if ((s_ds_type != kHDMI_tx_mode_None) && (standard->videoInputDef & (1<<7)) ) { + if ( standard->version == 1 && standard->revision >= 4 ) { + switch (standard->videoInputDef & 0x0F) { + case 0: + case 1: + debug(DS, "EDID says downstream DVI\n"); + s_ds_type = kHDMI_tx_mode_DVI; + break; + case 5: + debug(DS, "EDID says downstream DP\n"); + s_ds_type = kHDMI_tx_mode_HDMI; + break; + default: + debug(DS, "EDID says downstream HDMI\n"); + s_ds_type = kHDMI_tx_mode_HDMI; + break; + } + } + } + + if ( standard->feature & kEDIDStandardFeatureFlagGTF ) { + if ( standard->version == 1 && standard->revision >= 4 ) + s_timing_support = kSupportFlagCVT; + else + s_timing_support = kSupportFlagGTF; + } + return 0; +} + +static int process_edid_standard_timings(uint8_t *standard, uint32_t length) +{ + uint32_t index; + for (index = 0; index < length; index += 2) { + uint16_t timing_id = read_le16(standard, index); + try_standard_timing_id(timing_id); + } + return 0; +} + +static int process_edid_standard_established_timings(EDIDStandard *standard) +{ + uint32_t index; + + debug(EDID, "established=0x%02x established1=0x%02x established2=0x%02x\n", + standard->established[0], + standard->established[1], + standard->established[2]); + + for (index = 0; index < kEDIDEstablishedTimingsCount; ++index) { + if (!(standard->established[index>>3] & (1 << (index % 8)))) + continue; + debug(EDID, "index=%d\n", index); + try_established_timing_id(index); + } + return 0; +} + +static int process_edid_detailed(EDIDDetailed *detailed) +{ + if (detailed->data.header.header[0] == 0 && detailed->data.header.header[1] == 0) { + return process_edid_detailed_descriptor(&(detailed->data.descriptor)); + } else { + return try_detailed_timing(&(detailed->data.timing)); + } +} + +static int process_edid_detailed_descriptor(EDIDDetailedDescriptor *descriptor) +{ + if (!descriptor->flag) return 0; + + switch (descriptor->type) { + case 0xff: //Serial number + // Don't care. + break; + case 0xfd: //Range limits + // IODPService.cpp doesn't use this. + // process_edid_detailed_range(&descriptor->data.range); + break; + case 0xfc: //Monitor name + // Don't care. + break; + case 0xfb: // color point data + // Don't care. + // process_edid_detailed_color_point(&descriptor->data.color); + break; + case 0xfa: // standard timing + process_edid_standard_timings(descriptor->data.standard, sizeof(descriptor->data.standard)); + break; + case 0xf8: // CVT + process_edid_cvt_timings(descriptor->data.cvt, sizeof(descriptor->data.cvt)); + break; + case 0xf7: // established timings III + process_edid_detailed_established_timings_iii(&descriptor->data.established); + default: // DCM + break; + } + + return 0; +} + +static int process_edid_detailed_established_timings_iii(EDIDDetailedEstablishedTimingsIII *established) +{ + uint32_t index; + + debug(EDID, "established=%02x established1=%02x established2=%02x established3=%02x established4=%02x established5=%02x\n", established->data[0], established->data[1], established->data[2], established->data[3], established->data[4], established->data[5]); + + for (index = 0; index < kEDIDEstablishedTimingsCount; ++index) { + debug(EDID, "index=%d mask=%08x\n", index, (1 << (index % 8))); + + if ( !(established->data[index>>3] & (1 << (index % 8))) ) + continue; + + try_established_timing_iii_id(index); + } + + return 0; +} + +static int try_standard_timing_id(uint16_t timing_id) +{ + uint32_t horizontal; + uint32_t vertical = 0; + uint32_t rate; + + debug(EDID, "timing_id 0x%04x\n", timing_id); + + if (timing_id == 0x0101) + return -1; + + horizontal = ((timing_id & 0xff) + 31) * 8; + switch ((timing_id >> 14) & 0x3) { + case 0: + vertical = horizontal * 10 / 16; + break; + case 1: + vertical = horizontal * 3 /43; + break; + case 2: + vertical = horizontal * 4 / 5; + break; + case 3: + vertical = horizontal * 9 / 16; + break; + } + + rate = ((timing_id >> 8) & 0x3f) + 60; + + return use_dimensions(horizontal, vertical, rate << 16); +} + +static int try_established_timing_id(uint8_t established_id) +{ + static const __IODPTEEstablished established_info[] = { + {800, 600, 60<<16}, + {800, 600, 56<<16}, + {640, 480, 75<<16}, + {640, 480, 72<<16}, + {640, 480, 67<<16}, + {640, 480, 60<<16}, + {720, 400, 88<<16}, + {720, 400, 70<<16}, + + {1280, 1024, 75<<16}, + {1024, 768, 75<<16}, + {1024, 768, 70<<16}, + {1024, 768, 60<<16}, + {0,0,0}, //interlaced {1024, 768, 87<<16}, + {832, 624, 75<<16}, + {800, 600, 75<<16}, + {800, 600, 72<<16}, + + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {1152, 870, 75<<16} + }; + + if (established_id >= (sizeof(established_info) / sizeof(__IODPTEEstablished))) + return 0; + + return use_dimensions(established_info[established_id].horizontal, + established_info[established_id].vertical, + established_info[established_id].rate); +} + +static int try_established_timing_iii_id(uint8_t establishedID) +{ + static const __IODPTEEstablished sEstablishedInfo[] = { + {1152, 864, 75<<16}, + {1024, 768, 85<<16}, + {800, 600, 85<<16}, + {848, 480, 60<<16}, + {640, 480, 85<<16}, + {720, 400, 85<<16}, + {640, 400, 85<<16}, + {640, 350, 85<<16}, + + {1280, 1024, 85<<16}, + {1280, 1024, 60<<16}, + {1280, 960, 85<<16}, + {1280, 960, 60<<16}, + {1280, 768, 85<<16}, + {1280, 768, 75<<16}, + {1280, 768, 60<<16}, + {0,0,0}, // Reduced Blanking {1280, 768, 60<<16}, + + {1400, 1050, 75<<16}, + {1400, 1050, 60<<16}, + {0,0,0}, // Reduced Blanking {1400, 1050, 60<<16}, + {1440, 900, 85<<16}, + {1440, 900, 75<<16}, + {1440, 900, 60<<16}, + {0,0,0}, // Reduced Blanking {1440, 900, 60<<16}, + {1360, 768, 60<<16}, + + {1600, 1200, 70<<16}, + {1600, 1200, 65<<16}, + {1600, 1200, 60<<16}, + {1680, 1050, 85<<16}, + {1680, 1050, 75<<16}, + {1680, 1050, 60<<16}, + {0,0,0}, // Reduced Blanking {1680, 1050, 60<<16}, + {1400, 1050, 85<<16}, + + {1920, 1200, 60<<16}, + {0,0,0}, // Reduced Blanking {1920, 1200, 60<<16}, + {1856, 1392, 75<<16}, + {1856, 1392, 60<<16}, + {1792, 1344, 75<<16}, + {1792, 1344, 60<<16}, + {1600, 1200, 85<<16}, + {1600, 1200, 75<<16}, + + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {1920, 1440, 75<<16}, + {1920, 1440, 60<<16}, + {1920, 1200, 85<<16}, + {1920, 1200, 75<<16}, + }; + + if (establishedID >= (sizeof(sEstablishedInfo) / sizeof(__IODPTEEstablished))) + return -1; + + return use_dimensions(sEstablishedInfo[establishedID].horizontal, + sEstablishedInfo[establishedID].vertical, + sEstablishedInfo[establishedID].rate); +} + +static int try_detailed_timing(EDIDDetailedTiming *detailed) +{ + struct video_timing_data _data; + uint32_t value; + uint16_t pixelClock; + int64_t rate, area; + + bzero(&_data, sizeof(_data)); + + value = detailed->hor_addr_low; + value |= (detailed->hor_addr_blank_high & 0xF0) << 4; + _data.axis[kDisplayAxisTypeHorizontal].active = value; + + value = detailed->hor_fporch; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<6))<<2; + _data.axis[kDisplayAxisTypeHorizontal].front_porch = value; + + value = detailed->hor_sync; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<4))<<4; + _data.axis[kDisplayAxisTypeHorizontal].sync_width = value; + + value = detailed->hor_blank_low; + value |= (detailed->hor_addr_blank_high & 0xF) << 8; + if ( value < detailed->hor_border ) + return -1; + value -= detailed->hor_border; + + _data.axis[kDisplayAxisTypeHorizontal].total = value + _data.axis[kDisplayAxisTypeHorizontal].active; + + if ( value < (_data.axis[kDisplayAxisTypeHorizontal].front_porch + _data.axis[kDisplayAxisTypeHorizontal].sync_width) ) { + debug(EDID, "Invaid horizontal blanking\n"); + return -1; + } + + _data.axis[kDisplayAxisTypeHorizontal].back_porch = value - _data.axis[kDisplayAxisTypeHorizontal].front_porch - _data.axis[kDisplayAxisTypeHorizontal].sync_width; + + value = detailed->ver_addr_low; + value |= (detailed->ver_addr_blank_high & 0xF0) << 4; + _data.axis[kDisplayAxisTypeVertical].active = value; + + value = (detailed->ver_fporch_sync & 0xF0) >> 4; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<2))<<2; + _data.axis[kDisplayAxisTypeVertical].front_porch = value; + + value = detailed->ver_fporch_sync & 0x0F; + value |= (detailed->hor_ver_porch_sync_high & (0x3<<0))<<4; + _data.axis[kDisplayAxisTypeVertical].sync_width = value; + + value = detailed->ver_blank_low; + value |= (detailed->ver_addr_blank_high & 0xF) << 8; + if ( value < detailed->ver_border ) { + debug(EDID, "Vertical blank < vertical border\n"); + return -1; + } + + value -= detailed->ver_border; + + _data.axis[kDisplayAxisTypeVertical].total = value + _data.axis[kDisplayAxisTypeVertical].active; + if ( value < (_data.axis[kDisplayAxisTypeVertical].front_porch + _data.axis[kDisplayAxisTypeVertical].sync_width) ) + return -1; + _data.axis[kDisplayAxisTypeVertical].back_porch = value - _data.axis[kDisplayAxisTypeVertical].front_porch - _data.axis[kDisplayAxisTypeVertical].sync_width; + + pixelClock = (detailed->pixelClock[1]<<8) | detailed->pixelClock[0]; + area = _data.axis[kDisplayAxisTypeHorizontal].total * _data.axis[kDisplayAxisTypeVertical].total; + + if ( !area ) + return -1; + + rate = ((((uint64_t)pixelClock) * 10000) << 16) / area; + + // round up + rate += 0x8000; + rate &= 0xffff0000; + + _data.axis[kDisplayAxisTypeVertical].sync_rate = rate; + _data.interlaced = ( detailed->detailed & (1<<7) ) != 0; + + // digital + if ( ( detailed->detailed & (1<<4) ) != 0 ) { + + _data.axis[kDisplayAxisTypeHorizontal].sync_polarity = ( detailed->detailed & (1<<1) ) != 0; + + if ( ( detailed->detailed & (1<<3) ) != 0 ) { + _data.axis[kDisplayAxisTypeVertical].sync_polarity = ( detailed->detailed & (1<<2) ) != 0; + } else { + _data.axis[kDisplayAxisTypeVertical].sync_polarity = _data.axis[kDisplayAxisTypeHorizontal].sync_polarity; + + } + + } + + + if ( !_data.axis[kDisplayAxisTypeVertical].active || !_data.axis[kDisplayAxisTypeHorizontal].active || !_data.axis[kDisplayAxisTypeVertical].sync_rate) + return -1; + + return use_timings(&_data); +} + +static int try_cvt_timing_id(EDIDCVT *cvt) +{ + uint32_t horizontal = 0; + uint32_t vertical; + uint32_t rate; + uint32_t index; + + vertical = (((uint32_t)(cvt->data[1]&0xf0))<<4) | cvt->data[0]; + vertical = ( vertical + 1 ) * 2; + switch ((cvt->data[1]>>2) & 0x3) { + case 0: + horizontal = vertical * 4 / 3; + break; + case 1: + horizontal = vertical * 16 / 9; + break; + case 2: + horizontal = vertical * 16 / 10; + break; + default: + return -1; + } + + index = (cvt->data[2]>>5) & 0x3; + if ( cvt->data[2] & (1<<(4-index)) ) { + static const uint32_t sRates[] = { 50, 60, 75, 80 }; + rate = sRates[index]; + } else { + return -1; + } + + return use_dimensions(horizontal, vertical, rate<<16); +} + +static int try_cea_short_id(uint32_t shortVideoID) +{ + struct video_timing_data data; + debug(EDID, "cea_short_id 0x%08x\n", shortVideoID); + + if (get_timing_data_for_cea_short_id(shortVideoID, &data) != 0) + return -1; + + return use_timings(&data); +} + +static int get_timing_data_for_cea_short_id(uint32_t shortVideoID, struct video_timing_data *timingData) +{ + bzero(timingData, sizeof(struct video_timing_data)); + + switch ( shortVideoID ) { + // 1 640x480p @ 60 + case 1: + timingData->axis[kDisplayAxisTypeHorizontal].total = 800; + timingData->axis[kDisplayAxisTypeHorizontal].active = 640; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 96; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 48; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 2; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 33; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 10; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 2,3 720x480p @ 60 + case 2: + case 3: + timingData->axis[kDisplayAxisTypeHorizontal].total = 858; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 62; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 60; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 4 1280x720p @ 60 + case 4: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1650; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 110; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 7, 8 720(1440)x240p @ 60 + case 8: + case 9: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1716; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 124; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 114; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 38; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 262; + timingData->axis[kDisplayAxisTypeVertical].active = 240; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 15; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 12, 13 (2880)x240p @ 60 + case 12: + case 13: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3432; + timingData->axis[kDisplayAxisTypeHorizontal].active = 2880; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 248; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 228; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 76; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 262; + timingData->axis[kDisplayAxisTypeVertical].active = 240; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 15; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 6,7 720(1440)x480i @ 60 + case 6: + case 7: + timingData->interlaced = true; + // 14,15 720(1440)x480p @ 60 + case 14: + case 15: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1716; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 124; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 120; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 32; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 5 1920x1080i @ 60 + case 5: + timingData->interlaced = true; + // 16 1920x1080p @ 60 + case 16: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2200; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 88; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 21, 22 720(1440)x576i @ 50 + case 21: + case 22: + timingData->interlaced = true; + // 17 18 720x576p @ 50 + case 17: + case 18: + timingData->axis[kDisplayAxisTypeHorizontal].total = 864; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 64; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 68; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 12; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 19 1280x720p @ 50 + case 19: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1980; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 23, 24 720(1440)x288p @ 50 + case 23: + case 24: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1728; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 126; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 138; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 24; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 312; + timingData->axis[kDisplayAxisTypeVertical].active = 288; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 19; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 2; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 27, 28 (2880)x288p @ 50 + case 27: + case 28: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3456; + timingData->axis[kDisplayAxisTypeHorizontal].active = 2880; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 252; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 276; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 48; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 312; + timingData->axis[kDisplayAxisTypeVertical].active = 288; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 3; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 19; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 2; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 29, 30 1440x576p @ 50 + case 29: + case 30: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1728; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 128; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 136; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 24; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 20 1920x1080i @ 50 + case 20: + timingData->interlaced = true; + // 31 1920x1080p @ 50 + case 31: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2640; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 528; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 32 1920x1080p @ 24 + case 32: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2750; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 638; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 24<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 33 1920x1080p @ 25 + case 33: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2640; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 528; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 25<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 34 1920x1080p @ 30 + case 34: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2200; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 88; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1125; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 36; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 4; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 30<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 10, 11 (2880)x480i @ 60 + case 10: + case 11: + timingData->interlaced = true; + // 35, 36 2880x480p @ 60 + case 35: + case 36: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3432; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 248; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 240; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 64; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 60<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 25, 26 (2880)x576i @ 50 + case 25: + case 26: + timingData->interlaced = true; + // 37, 38 2880x576p @ 50 + case 37: + case 38: + timingData->axis[kDisplayAxisTypeHorizontal].total = 3456; + timingData->axis[kDisplayAxisTypeHorizontal].active = 2880; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 256; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 272; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 48; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 39 1920x1080i @ 50 + case 39: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2304; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 168; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 184; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 32; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1250; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 120; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 45; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + + timingData->interlaced = true; + break; + // 40 1920x1080i @ 100 + case 40: + timingData->axis[kDisplayAxisTypeHorizontal].total = 2640; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1920; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 44; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 148; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 528; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 1250; + timingData->axis[kDisplayAxisTypeVertical].active = 1080; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 120; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 45; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 50<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + + timingData->interlaced = true; + break; + // 41 1280x720p @ 100 + case 41: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1980; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 440; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 100<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 44, 45 720(1440)x576i @ 100 + case 44: + case 45: + timingData->interlaced = true; + // 42, 43 720x576p @ 100 + case 42: + case 43: + timingData->axis[kDisplayAxisTypeHorizontal].total = 864; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 64; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 68; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 12; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 100<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 46 1920x1280i @ 120 + case 46: + return -1; + // 47 1280x720p @ 120 + case 47: + timingData->axis[kDisplayAxisTypeHorizontal].total = 1650; + timingData->axis[kDisplayAxisTypeHorizontal].active = 1280; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 40; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 220; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 110; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 1; + + timingData->axis[kDisplayAxisTypeVertical].total = 750; + timingData->axis[kDisplayAxisTypeVertical].active = 720; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 20; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 120<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 1; + break; + // 48, 49 720x480p @ 120 + case 48: + case 49: + timingData->axis[kDisplayAxisTypeHorizontal].total = 858; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 62; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 60; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 120<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 50, 51 720(1440)x480i @ 120 + case 50: + case 51: + return -1; + // 42, 43 720x576p @ 100 + case 52: + case 53: + timingData->axis[kDisplayAxisTypeHorizontal].total = 864; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 64; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 68; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 12; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 625; + timingData->axis[kDisplayAxisTypeVertical].active = 576; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 5; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 39; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 5; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 200<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 54, 55 720(1440)x576i @ 200 + case 54: + case 55: + return -1; + // 56, 57 720x480p @ 240 + case 56: + case 57: + timingData->axis[kDisplayAxisTypeHorizontal].total = 858; + timingData->axis[kDisplayAxisTypeHorizontal].active = 720; + timingData->axis[kDisplayAxisTypeHorizontal].sync_width = 62; + timingData->axis[kDisplayAxisTypeHorizontal].back_porch = 60; + timingData->axis[kDisplayAxisTypeHorizontal].front_porch = 16; + timingData->axis[kDisplayAxisTypeHorizontal].sync_rate = 0; + timingData->axis[kDisplayAxisTypeHorizontal].sync_polarity = 0; + + timingData->axis[kDisplayAxisTypeVertical].total = 525; + timingData->axis[kDisplayAxisTypeVertical].active = 480; + timingData->axis[kDisplayAxisTypeVertical].sync_width = 6; + timingData->axis[kDisplayAxisTypeVertical].back_porch = 30; + timingData->axis[kDisplayAxisTypeVertical].front_porch = 9; + timingData->axis[kDisplayAxisTypeVertical].sync_rate = 240<<16; + timingData->axis[kDisplayAxisTypeVertical].sync_polarity = 0; + break; + // 58, 59 720(1440)x480i @ 240 + case 58: + case 59: + return -1; + // more to come...too lazy right now + default: + return -1; + break; + } + + return 0; +} + +static int use_dimensions(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + int ret = -1; + debug(EDID, "Use dimensions %ux%u %uHz\n", horizontal, vertical, rate >> 16); + if (s_timing_support & kSupportFlagCVT) { + ret = use_dimensions_cvt(horizontal, vertical, rate); + } else if (s_timing_support & kSupportFlagGTF) { + ret = use_dimensions_gtf(horizontal, vertical, rate); + } + if (ret != 0) { + ret = use_dimensions_dmt(horizontal, vertical, rate); + } + return ret; +} + +static int use_dimensions_dmt(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + static const struct video_timing_data sDMTTimingInfo[] = { + {false, {{832, 640, 64, 96, 32, 0, 1}, {445, 350, 3, 60, 32, 85<<16, 0}} }, + {false, {{832, 640, 64, 96, 32, 0, 0}, {445, 400, 3, 41, 1, 85<<16, 1}} }, + {false, {{936, 720, 72, 108, 36, 0, 0}, {446, 400, 3, 42, 1, 85<<16, 1}} }, + {false, {{800, 640, 96, 48, 16, 0, 0}, {525, 480, 2, 33, 10, 60<<16, 0}} }, + {false, {{832, 640, 40, 128, 24, 0, 0}, {520, 480, 3, 28, 9, 72<<16, 0}} }, + {false, {{840, 640, 64, 120, 16, 0, 0}, {500, 480, 3, 16, 1, 75<<16, 0}} }, + {false, {{832, 640, 56, 80, 56, 0, 0}, {509, 480, 3, 25, 1, 85<<16, 0}} }, + {false, {{1024, 800, 72, 128, 24, 0, 1}, {625, 600, 2, 22, 1, 56<<16, 1}} }, + {false, {{1056, 800, 128, 88, 40, 0, 1}, {628, 600, 4, 23, 1, 60<<16, 1}} }, + {false, {{1040, 800, 120, 64, 56, 0, 1}, {666, 600, 6, 23, 37, 72<<16, 1}} }, + {false, {{1056, 800, 80, 160, 16, 0, 1}, {625, 600, 3, 21, 1, 75<<16, 1}} }, + {false, {{1048, 800, 64, 152, 32, 0, 1}, {631, 600, 3, 27, 1, 85<<16, 1}} }, + {false, {{960, 800, 32, 80, 48, 0, 1}, {636, 600, 4, 29, 3, 120<<16, 0}} }, + {false, {{1088, 848, 112, 112, 16, 0, 1}, {517, 480, 8, 23, 6, 60<<16, 1}} }, + {false, {{1344, 1024, 136, 160, 24, 0, 0}, {806, 768, 6, 29, 3, 60<<16, 0}} }, + {false, {{1328, 1024, 136, 144, 24, 0, 0}, {806, 768, 6, 29, 3, 70<<16, 0}} }, + {false, {{1312, 1024, 96, 176, 16, 0, 1}, {800, 768, 3, 28, 1, 75<<16, 1}} }, + {false, {{1376, 1024, 96, 208, 48, 0, 1}, {808, 768, 3, 36, 1, 85<<16, 1}} }, + {false, {{1600, 1152, 128, 256, 64, 0, 1}, {900, 864, 3, 32, 1, 75<<16, 1}} }, + {false, {{1650, 1280, 40, 220, 110, 0, 1}, {750, 720, 5, 20, 5, 60<<16, 1}} }, + {false, {{1664, 1280, 128, 192, 64, 0, 0}, {798, 768, 7, 20, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {805, 768, 7, 27, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {809, 768, 7, 31, 3, 85<<16, 1}} }, + {false, {{1680, 1280, 128, 200, 72, 0, 0}, {831, 800, 6, 22, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {838, 800, 6, 29, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {843, 800, 6, 34, 3, 85<<16, 1}} }, + {false, {{1800, 1280, 112, 312, 96, 0, 1}, {1000, 960, 3, 36, 1, 60<<16, 1}} }, + {false, {{1728, 1280, 160, 224, 64, 0, 1}, {1011, 960, 3, 47, 1, 85<<16, 1}} }, + {false, {{1688, 1280, 112, 248, 48, 0, 1}, {1066, 1024, 3, 38, 1, 60<<16, 1}} }, + {false, {{1688, 1280, 144, 248, 16, 0, 1}, {1066, 1024, 3, 38, 1, 75<<16, 1}} }, + {false, {{1728, 1280, 160, 224, 64, 0, 1}, {1072, 1024, 3, 44, 1, 85<<16, 1}} }, + {false, {{1792, 1360, 112, 256, 64, 0, 1}, {795, 768, 6, 18, 3, 60<<16, 1}} }, + {false, {{1792, 1366, 143, 213, 70, 0, 1}, {798, 768, 3, 24, 3, 60<<16, 1}} }, + {false, {{1864, 1400, 144, 232, 88, 0, 0}, {1089, 1050, 4, 32, 3, 60<<16, 1}} }, + {false, {{1896, 1400, 144, 248, 104, 0, 0}, {1099, 1050, 4, 42, 3, 75<<16, 1}} }, + {false, {{1912, 1400, 152, 256, 104, 0, 0}, {1105, 1050, 4, 48, 3, 85<<16, 1}} }, + {false, {{1904, 1440, 152, 232, 80, 0, 0}, {934, 900, 6, 25, 3, 60<<16, 1}} }, + {false, {{1936, 1440, 152, 248, 96, 0, 0}, {942, 900, 6, 33, 3, 75<<16, 1}} }, + {false, {{1952, 1440, 152, 256, 104, 0, 0}, {948, 900, 6, 39, 3, 85<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 60<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 65<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 70<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 75<<16, 1}} }, + {false, {{2160, 1600, 192, 304, 64, 0, 1}, {1250, 1200, 3, 46, 1, 85<<16, 1}} }, + {false, {{2240, 1680, 176, 280, 104, 0, 0}, {1089, 1050, 6, 30, 3, 60<<16, 1}} }, + {false, {{2272, 1680, 176, 296, 120, 0, 0}, {1099, 1050, 6, 40, 3, 75<<16, 1}} }, + {false, {{2288, 1680, 176, 304, 128, 0, 0}, {1105, 1050, 6, 46, 3, 85<<16, 1}} }, + {false, {{2448, 1792, 200, 328, 128, 0, 0}, {1394, 1344, 3, 46, 1, 60<<16, 1}} }, + {false, {{2456, 1792, 216, 352, 96, 0, 0}, {1417, 1344, 3, 69, 1, 75<<16, 1}} }, + {false, {{2528, 1856, 224, 352, 96, 0, 0}, {1439, 1392, 3, 43, 1, 60<<16, 1}} }, + {false, {{2560, 1856, 224, 352, 128, 0, 0}, {1500, 1392, 3, 104, 1, 75<<16, 1}} }, + {false, {{2200, 1920, 44, 148, 88, 0, 1}, {1125, 1080, 5, 36, 4, 60<<16, 1}} }, + {false, {{2592, 1920, 200, 336, 136, 0, 0}, {1245, 1200, 6, 36, 3, 60<<16, 1}} }, + {false, {{2608, 1920, 208, 344, 136, 0, 0}, {1255, 1200, 6, 46, 3, 75<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1262, 1200, 6, 53, 3, 85<<16, 1}} }, + {false, {{2600, 1920, 208, 344, 128, 0, 0}, {1500, 1440, 3, 56, 1, 60<<16, 1}} }, + {false, {{2640, 1920, 224, 352, 144, 0, 0}, {1500, 1440, 3, 56, 1, 75<<16, 1}} }, + {false, {{3504, 2560, 280, 472, 192, 0, 0}, {1658, 1600, 6, 49, 3, 60<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1672, 1600, 6, 63, 3, 75<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1682, 1600, 6, 73, 3, 85<<16, 1}} } + }; + + return use_dimensions_table(sDMTTimingInfo, (sizeof(sDMTTimingInfo) / sizeof(struct video_timing_data)), horizontal, vertical, rate); +} + +static int use_dimensions_cvt(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + static const struct video_timing_data sCVTTimingInfo[] = { + {false, {{816, 640, 64, 88, 24, 0, 0}, {423, 400, 6, 14, 3, 85<<16, 1}} }, + {false, {{800, 640, 64, 80, 16, 0, 0}, {500, 480, 4, 13, 3, 60<<16, 1}} }, + {false, {{816, 640, 64, 88, 24, 0, 0}, {504, 480, 4, 17, 3, 75<<16, 1}} }, + {false, {{816, 640, 64, 88, 24, 0, 0}, {507, 480, 4, 20, 3, 85<<16, 1}} }, + {false, {{1024, 800, 80, 112, 32, 0, 0}, {624, 600, 4, 17, 3, 60<<16, 1}} }, + {false, {{1040, 800, 80, 120, 40, 0, 0}, {625, 600, 4, 22, 3, 75<<16, 1}} }, + {false, {{1056, 800, 80, 128, 48, 0, 0}, {633, 600, 4, 26, 3, 85<<16, 1}} }, + {false, {{1328, 1024, 104, 152, 48, 0, 0}, {798, 768, 4, 23, 3, 60<<16, 1}} }, + {false, {{1360, 1024, 104, 168, 64, 0, 0}, {805, 768, 4, 30, 3, 75<<16, 1}} }, + {false, {{1376, 1024, 104, 176, 72, 0, 0}, {809, 768, 4, 34, 3, 85<<16, 1}} }, + {false, {{1536, 1152, 120, 192, 72, 0, 0}, {905, 864, 4, 34, 3, 75<<16, 1}} }, + {false, {{1664, 1280, 128, 192, 64, 0, 0}, {748, 720, 5, 20, 3, 60<<16, 1}} }, + {false, {{1664, 1280, 128, 192, 64, 0, 0}, {798, 768, 7, 20, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {805, 768, 7, 27, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {809, 768, 7, 31, 3, 85<<16, 1}} }, + {false, {{1680, 1280, 128, 200, 72, 0, 0}, {831, 800, 6, 22, 3, 60<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {838, 800, 6, 29, 3, 75<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {843, 800, 6, 34, 3, 85<<16, 1}} }, + {false, {{1696, 1280, 128, 208, 80, 0, 0}, {996, 960, 4, 29, 3, 60<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {1011, 960, 4, 44, 3, 85<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {1063, 1024, 7, 29, 3, 60<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {1072, 1024, 7, 38, 3, 75<<16, 1}} }, + {false, {{1744, 1280, 136, 232, 96, 0, 0}, {1078, 1024, 7, 44, 3, 85<<16, 1}} }, + {false, {{1776, 1360, 136, 208, 72, 0, 0}, {798, 768, 5, 22, 3, 60<<16, 1}} }, + {false, {{1864, 1400, 144, 232, 88, 0, 0}, {1089, 1050, 4, 32, 3, 60<<16, 1}} }, + {false, {{1896, 1400, 144, 248, 104, 0, 0}, {1099, 1050, 4, 42, 3, 75<<16, 1}} }, + {false, {{1912, 1400, 152, 256, 104, 0, 0}, {1105, 1050, 4, 48, 3, 85<<16, 1}} }, + {false, {{1904, 1440, 152, 232, 80, 0, 0}, {934, 900, 6, 25, 3, 60<<16, 1}} }, + {false, {{1936, 1440, 152, 248, 96, 0, 0}, {942, 900, 6, 33, 3, 75<<16, 1}} }, + {false, {{1952, 1440, 152, 256, 104, 0, 0}, {948, 900, 6, 39, 3, 85<<16, 1}} }, + {false, {{2160, 1600, 168, 280, 112, 0, 0}, {1245, 1200, 4, 38, 3, 60<<16, 1}} }, + {false, {{2160, 1600, 168, 288, 120, 0, 0}, {1255, 1200, 4, 48, 3, 75<<16, 1}} }, + {false, {{2192, 1600, 168, 296, 128, 0, 0}, {1262, 1200, 4, 55, 3, 85<<16, 1}} }, + {false, {{2240, 1680, 176, 280, 104, 0, 0}, {1089, 1050, 6, 30, 3, 60<<16, 1}} }, + {false, {{2272, 1680, 176, 296, 120, 0, 0}, {1099, 1050, 6, 40, 3, 75<<16, 1}} }, + {false, {{2288, 1680, 176, 304, 128, 0, 0}, {1105, 1050, 6, 46, 3, 85<<16, 1}} }, + {false, {{2432, 1792, 192, 320, 128, 0, 0}, {1393, 1344, 4, 42, 3, 60<<16, 1}} }, + {false, {{2448, 1792, 192, 328, 136, 0, 0}, {1405, 1344, 4, 54, 3, 75<<16, 1}} }, + {false, {{2512, 1856, 200, 328, 128, 0, 0}, {1443, 1392, 4, 44, 3, 60<<16, 1}} }, + {false, {{2544, 1856, 200, 344, 144, 0, 0}, {1456, 1392, 4, 57, 3, 75<<16, 1}} }, + {false, {{2576, 1920, 200, 328, 128, 0, 0}, {1120, 1080, 5, 32, 3, 60<<16, 1}} }, + {false, {{2592, 1920, 200, 336, 136, 0, 0}, {1245, 1200, 6, 36, 3, 60<<16, 1}} }, + {false, {{2608, 1920, 208, 344, 136, 0, 0}, {1255, 1200, 6, 46, 3, 75<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1262, 1200, 6, 53, 3, 85<<16, 1}} }, + {false, {{2608, 1920, 208, 344, 136, 0, 0}, {1493, 1440, 4, 46, 3, 60<<16, 1}} }, + {false, {{2640, 1920, 208, 360, 152, 0, 0}, {1506, 1440, 4, 59, 3, 75<<16, 1}} }, + {false, {{3504, 2560, 280, 472, 192, 0, 0}, {1658, 1600, 6, 49, 3, 60<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1672, 1600, 6, 63, 3, 75<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1682, 1600, 6, 73, 3, 85<<16, 1}} } + }; + + return use_dimensions_table(sCVTTimingInfo, (sizeof(sCVTTimingInfo) / sizeof(struct video_timing_data)), horizontal, vertical, rate); +} + +static int use_dimensions_gtf(uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + static const struct video_timing_data sGTFTimingInfo[] = { + {false, {{816, 640, 64, 88, 24, 0, 0}, {421, 400, 3, 17, 1, 85<<16, 1}} }, + {false, {{800, 640, 64, 80, 16, 0, 0}, {497, 480, 3, 13, 1, 60<<16, 1}} }, + {false, {{816, 640, 64, 88, 24, 0, 0}, {502, 480, 3, 18, 1, 75<<16, 1}} }, + {false, {{832, 640, 64, 96, 32, 0, 0}, {505, 480, 3, 21, 1, 85<<16, 1}} }, + {false, {{1024, 800, 80, 112, 32, 0, 0}, {622, 600, 3, 18, 1, 60<<16, 1}} }, + {false, {{1040, 800, 80, 120, 40, 0, 0}, {627, 600, 3, 23, 1, 75<<16, 1}} }, + {false, {{1056, 800, 88, 128, 40, 0, 0}, {630, 600, 3, 26, 1, 85<<16, 1}} }, + {false, {{1344, 1024, 104, 160, 56, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1360, 1024, 112, 168, 56, 0, 0}, {802, 768, 3, 30, 1, 75<<16, 1}} }, + {false, {{1376, 1024, 112, 176, 64, 0, 0}, {807, 768, 3, 35, 1, 85<<16, 1}} }, + {false, {{1552, 1152, 128, 200, 72, 0, 0}, {902, 864, 3, 34, 1, 75<<16, 1}} }, + {false, {{1664, 1280, 136, 192, 56, 0, 0}, {746, 720, 3, 22, 1, 60<<16, 1}} }, + {false, {{1680, 1280, 136, 200, 64, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {802, 768, 3, 30, 1, 75<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {807, 768, 3, 35, 1, 85<<16, 1}} }, + {false, {{1680, 1280, 136, 200, 64, 0, 0}, {828, 800, 3, 24, 1, 60<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {835, 800, 3, 31, 1, 75<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {840, 800, 3, 36, 1, 85<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {994, 960, 3, 30, 1, 60<<16, 1}} }, + {false, {{1744, 1280, 136, 232, 96, 0, 0}, {1008, 960, 3, 44, 1, 85<<16, 1}} }, + {false, {{1712, 1280, 136, 216, 80, 0, 0}, {1060, 1024, 3, 32, 1, 60<<16, 1}} }, + {false, {{1728, 1280, 136, 224, 88, 0, 0}, {1069, 1024, 3, 44, 1, 75<<16, 1}} }, + {false, {{1744, 1280, 136, 232, 96, 0, 0}, {1075, 1024, 3, 47, 1, 85<<16, 1}} }, + {false, {{1776, 1360, 144, 208, 64, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1800, 1366, 144, 216, 72, 0, 0}, {795, 768, 3, 23, 1, 60<<16, 1}} }, + {false, {{1880, 1400, 152, 240, 88, 0, 0}, {1087, 1050, 3, 33, 1, 60<<16, 1}} }, + {false, {{1896, 1400, 152, 248, 96, 0, 0}, {1096, 1050, 3, 42, 1, 75<<16, 1}} }, + {false, {{1912, 1400, 152, 256, 104, 0, 0}, {1103, 1050, 3, 49, 1, 85<<16, 1}} }, + {false, {{1904, 1440, 152, 232, 80, 0, 0}, {932, 900, 3, 28, 1, 60<<16, 1}} }, + {false, {{1936, 1440, 152, 248, 96, 0, 0}, {940, 900, 3, 36, 1, 75<<16, 1}} }, + {false, {{1952, 1440, 160, 256, 96, 0, 0}, {945, 900, 3, 41, 1, 85<<16, 1}} }, + {false, {{2160, 1600, 176, 280, 104, 0, 0}, {1242, 1200, 3, 38, 1, 60<<16, 1}} }, + {false, {{2192, 1600, 176, 296, 120, 0, 0}, {1253, 1200, 3, 49, 1, 75<<16, 1}} }, + {false, {{2192, 1600, 176, 296, 120, 0, 0}, {1260, 1200, 3, 56, 1, 85<<16, 1}} }, + {false, {{2256, 1680, 184, 288, 104, 0, 0}, {1087, 1050, 3, 33, 1, 60<<16, 1}} }, + {false, {{2288, 1680, 184, 304, 120, 0, 0}, {1096, 1050, 3, 42, 1, 75<<16, 1}} }, + {false, {{2288, 1680, 184, 304, 120, 0, 0}, {1103, 1050, 3, 49, 1, 85<<16, 1}} }, + {false, {{2432, 1792, 192, 320, 128, 0, 0}, {1391, 1344, 3, 43, 1, 60<<16, 1}} }, + {false, {{2464, 1792, 200, 336, 136, 0, 0}, {1403, 1344, 3, 55, 1, 75<<16, 1}} }, + {false, {{2528, 1856, 200, 336, 136, 0, 0}, {1441, 1392, 3, 45, 1, 60<<16, 1}} }, + {false, {{2544, 1856, 200, 344, 144, 0, 0}, {1453, 1392, 3, 57, 1, 75<<16, 1}} }, + {false, {{2576, 1920, 208, 328, 120, 0, 0}, {1118, 1080, 3, 34, 1, 60<<16, 1}} }, + {false, {{2592, 1920, 208, 336, 128, 0, 0}, {1242, 1200, 3, 38, 1, 60<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1253, 1200, 3, 49, 1, 75<<16, 1}} }, + {false, {{2640, 1920, 208, 360, 152, 0, 0}, {1260, 1200, 3, 56, 1, 85<<16, 1}} }, + {false, {{2624, 1920, 208, 352, 144, 0, 0}, {1490, 1440, 3, 46, 1, 60<<16, 1}} }, + {false, {{2640, 1920, 208, 360, 152, 0, 0}, {1503, 1440, 3, 59, 1, 75<<16, 1}} }, + {false, {{3504, 2560, 280, 472, 192, 0, 0}, {1656, 1600, 3, 52, 1, 60<<16, 1}} }, + {false, {{3536, 2560, 280, 488, 208, 0, 0}, {1670, 1600, 3, 66, 1, 75<<16, 1}} }, + {false, {{3552, 2560, 288, 496, 208, 0, 0}, {1680, 1600, 3, 76, 1, 85<<16, 1}} } + }; + + return use_dimensions_table(sGTFTimingInfo, (sizeof(sGTFTimingInfo) / sizeof(struct video_timing_data)), horizontal, vertical, rate); +} + +static int use_dimensions_table(const struct video_timing_data * list, uint32_t count, uint32_t horizontal, uint32_t vertical, uint32_t rate) +{ + const struct video_timing_data * matching = NULL; + uint32_t roundRate = (rate + 0x8000) & 0xffff0000; + uint32_t index; + struct video_timing_data data; + + if ( !list || !count || !horizontal || !vertical || !rate ) + return -1; + + for (index=0; indexaxis[kDisplayAxisTypeHorizontal].active != horizontal ) + continue; + + if ( timing->axis[kDisplayAxisTypeVertical].active != vertical ) + continue; + + if ( (uint32_t) timing->axis[kDisplayAxisTypeVertical].sync_rate != roundRate ) + continue; + + matching = timing; + break; + } + + if ( !matching ) + return -1; + + bcopy(matching, &data, sizeof(data)); + data.axis[kDisplayAxisTypeVertical].sync_rate = rate; + return use_timings(&data); +} + +static int use_timings(struct video_timing_data *data) +{ + bool winner = false; + uint32_t width, height, rate, size, old_rate; + width = data->axis[kDisplayAxisTypeHorizontal].active; + height = data->axis[kDisplayAxisTypeVertical].active; + rate = data->axis[kDisplayAxisTypeVertical].sync_rate; + size = width * height * 4; // Assume RGBx8888 + + debug(SCORE, "Try timings %ux%u%c/%u\n", + width, height, data->interlaced ? 'i' : 'p', rate >> 16); + + // Reject timings we can't support or don't like. + if (hdmi_controller_validate_video(data) != 0) { + debug(SCORE, "Rejecting: bad timings\n"); + return -1; + } else if (s_restrict_h_active && s_restrict_v_active && + (width != s_restrict_h_active || height != s_restrict_v_active)) { + // Restricting to specific dimensions. + debug(SCORE, "Rejecting dimensions not matching %ux%u\n", + s_restrict_h_active, s_restrict_v_active); + return -1; + } else if (width > kMaxHorizontalActive) { + debug(SCORE, "Rejecting: horizontal active %u greater than %u\n", + width, kMaxHorizontalActive); + return -1; + } else if (size > DISPLAY_SIZE) { + debug(SCORE, "Rejecting: total size %u too big for buffer %u bytes\n", + size, (uint32_t)DISPLAY_SIZE); + return -1; + } + + debug(SCORE, "Accepted\n"); + + // Score these new timings vs the best we have so far. Note than wider/taller + // scoring will only occur if restrict_edid() was not used. + if (s_have_timings) { + old_rate = s_best_timings.axis[kDisplayAxisTypeVertical].sync_rate; + } else { + old_rate = 0; + } + + if (!s_have_timings) { + winner = true; + debug(SCORE, "First candidate\n"); + } else if ((rate >= (59 << 16) && rate <= (61 << 16)) && + (old_rate < (59 << 16) || old_rate > (61 << 16))) { + winner = true; + debug(SCORE, "Preferring 60Hz to non-60Hz\n"); + } else if (width > s_best_timings.axis[kDisplayAxisTypeHorizontal].active) { + winner = true; + debug(SCORE, "Preferring wider\n"); + } else if (height > s_best_timings.axis[kDisplayAxisTypeVertical].active) { + winner = true; + debug(SCORE, "Preferring taller\n"); + } + + if (winner) { + s_have_timings = true; + bcopy(data, &s_best_timings, sizeof(s_best_timings)); + } + + return 0; +} + +static int verify_edid(EDID *edid, uint8_t *p_checksum) +{ + uint32_t index; + uint8_t sum; + + debug(EDID, "Validating EDID\n"); + + for (index = 0, sum = 0; index < sizeof(EDID); ++index) { + sum += ((uint8_t *) edid)[index]; + } + + debug(EDID, "EDID checksum of 0x%02x\n", sum); + + if (p_checksum) + *p_checksum = sum; + + return sum == 0 ? 0 : -1; +} + +static int get_edid(uint8_t offset, EDID *edid) +{ + int ret; + uint32_t tries = 0; + uint64_t timer_start; + + timer_start = system_time(); + + do { + uint8_t checksum; + ++tries; + ret = hdmi_controller_read_bytes_i2c(kI2CEdidReadDeviceAddr, offset, + (uint8_t *) edid, sizeof(EDID)); + if (ret) { + debug(EDID, "Failed to read EDID offset=0x%08x ret=0x%08x\n", offset, ret); + if (s_abort_edid) { + // Display is trying to shut down - don't delay it. + debug(ERROR, "EDID retry loop aborted\n"); + break; + } + task_sleep(kEdidRetryDelay); + } else { + ret = verify_edid(edid, &checksum); + debug(EDID, "Verify EDID offset=0x%08x ret=0x%08x checksum=0x%02x\n", offset, ret, checksum); + } + } while (ret != 0 && !time_has_elapsed(timer_start, kEdidRetryTimeout)); + + if (ret == 0) { + debug(EDID, "Got EDID after %d tries, %llu usecs\n", tries, system_time() - timer_start); + } else { + debug(ERROR, "Failed to get EDID after %llu usecs\n", system_time() - timer_start); + } + + return ret; +} + +static uint16_t read_le16(const void *data, uint32_t offset) +{ + const uint8_t *p = (const uint8_t *) data; + uint16_t result = p[offset]; + result |= ((uint16_t) p[offset + 1]) << 8; + return result; +} + +static uint32_t read_le32(const void *data, uint32_t offset) +{ + const uint8_t *p = (const uint8_t *) data; + uint32_t result = p[offset]; + result |= ((uint32_t) p[offset + 1]) << 8; + result |= ((uint32_t) p[offset + 2]) << 16; + result |= ((uint32_t) p[offset + 3]) << 24; + return result; +} diff --git a/drivers/hdmi/rules.mk b/drivers/hdmi/rules.mk new file mode 100644 index 0000000..d94b677 --- /dev/null +++ b/drivers/hdmi/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2012 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += + +ALL_OBJS += \ + $(LOCAL_DIR)/controller.o \ + $(LOCAL_DIR)/device.o \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/process_edid.o diff --git a/drivers/idt/idtp9022/idtp9022.c b/drivers/idt/idtp9022/idtp9022.c new file mode 100644 index 0000000..d6753eb --- /dev/null +++ b/drivers/idt/idtp9022/idtp9022.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void pmu_charger_set_charging(int dock, uint32_t input_current_ma, uint32_t *charge_current_ma); +extern void pmu_charger_print_status(void); + +#define IDT_ADDR_R 0x72 +#define IDT_ADDR_W 0x73 + +// indirect access registers +enum { + I2C_IndData = 0x8800, + I2C_IndAddr_16bH = 0x8801, + I2C_IndAddr_16bL = 0x8802, + I2C_IndControl = 0x8803, + I2C_IndControl_WriteSingle = 0x01, + I2C_IndControl_ReadSingle = 0x02, + I2C_IndControl_Write3Bytes = 0x03, + I2C_IndStatus = 0x8804, + I2C_IndStatus_Busy_flag = (1 << 0), + I2C_IndStatus_Result = (1 << 1), +}; + +// memory locations +enum { + // Accessible locations + + Mem_CustomerID = 0x00D0, + Mem_FWMajorRevHigh = 0x00D2, + Mem_FWMajorRevLow = 0x00D3, + Mem_FWMinorRevHigh = 0x00D4, + Mem_FWMinorRevLow = 0x00D5, + // 0x00D6-0x00DB reserved for data communications + Mem_Status = 0x00DC, + Mem_Status_Reset = (1 << 7), + Mem_Status_DataComm = (1 << 6), + Mem_Status_DOCK_PWR_EN = (1 << 4), + Mem_Status_Vrect = (1 << 0), + Mem_Control = 0x00DD, + Mem_Control_DataCommRequest = (1 << 7), + Mem_Control_DataCommReset = (1 << 6), + Mem_Control_DOCK_PWR_EN = (1 << 4), + Mem_Control_EndOfPower = (1 << 0), + Mem_MeasuredVrect = 0x00DE, + Mem_TargetVrectHigh = 0x00DF, + Mem_TargetVrectLow = 0x00E0, + Mem_FWUpdateKey = 0x00E1, + Mem_FWUpdateKeyUpdateRequest = 0xA5, + Mem_FWUpdateKeyStartExecution = 0x5A, + Mem_FWUpdateChecksumHigh = 0x00E2, + Mem_FWUpdateChecksumLow = 0x00E3, + + // OTP parameters + OTP_ConfigFlags = 0xA840, + OTP_WakeCntrTO = 0xA841, + OTP_IDHeaderByte = 0xA842, + OTP_IDMessageByte = 0xA843, + OTP_IDResponseByte = 0xA844, + OTP_IDBypassResponseByte = 0xA845, + OTP_InitVrectTargetHigh = 0xA84D, + OTP_InitVrectTargetLow = 0xA84E, +}; + +static bool idt_wait_busy(void) +{ + uint8_t status_reg[2] = { (I2C_IndStatus >> 8) & 0xFF, I2C_IndStatus & 0xFF }; + uint8_t status_data; + for (;;) { + if (iic_read(CHARGER_IIC_BUS, IDT_ADDR_R, &status_reg, sizeof(status_reg), &status_data, sizeof(status_data), IIC_NORMAL) != 0) return false; + if ((status_data & I2C_IndStatus_Busy_flag) == 0) break; + task_sleep(100); + } + if ((status_data & I2C_IndStatus_Result) == 0) { + dprintf(DEBUG_CRITICAL, "charger result status: failed\n"); + return false; + } + return true; +} + +static int idt_write_multiple(uint16_t mem, const uint8_t *value, size_t length) +{ + size_t offset = 0; + while (offset < length) { + uint8_t data[6] = { (I2C_IndData >> 8) & 0xFF, I2C_IndData & 0xFF }; + if (offset == 0 || (length - offset) < 3) { + data[2] = value[offset]; + data[3] = ((mem + offset) >> 8) & 0xFF; + data[4] = (mem + offset) & 0xFF; + data[5] = I2C_IndControl_WriteSingle; + offset += 1; + } else { + data[2] = value[offset]; + data[3] = value[offset+1]; + data[4] = value[offset+2]; + data[5] = I2C_IndControl_Write3Bytes; + offset += 3; + } + if (iic_write(CHARGER_IIC_BUS, IDT_ADDR_W, data, sizeof(data)) != 0) return -1; + if (!idt_wait_busy()) return -1; + } + return 0; +} + +static int idt_write_byte(uint16_t mem, uint8_t value) { + return idt_write_multiple(mem, &value, sizeof(value)); +} + +static int idt_read(uint16_t mem, uint8_t *value) +{ + uint8_t data[5] = { (I2C_IndAddr_16bH >> 8) & 0xFF, I2C_IndAddr_16bH & 0xFF, (mem >> 8) & 0xFF, mem & 0xFF, I2C_IndControl_ReadSingle }; + if (iic_write(CHARGER_IIC_BUS, IDT_ADDR_W, data, sizeof(data)) != 0) return -1; + if (!idt_wait_busy()) return -1; + uint8_t reg[2] = { (I2C_IndData >> 8) & 0xFF, I2C_IndData & 0xFF }; + return iic_read(CHARGER_IIC_BUS, IDT_ADDR_R, ®, sizeof(reg), value, sizeof(uint8_t), IIC_NORMAL); +} + +static int idt_write16(uint16_t mem, uint16_t value) +{ + uint8_t data[2] = { (value >> 8) & 0xFF, value & 0xFF }; + return idt_write_multiple(mem, data, sizeof(data)); +} + +static int idt_read16(uint16_t mem, uint16_t *value) +{ + uint8_t hi1, hi2, low; + do { + if (idt_read(mem, &hi1) != 0) return -1; + if (idt_read(mem + 1, &low) != 0) return -1; + if (idt_read(mem, &hi2) != 0) return -1; + } while (hi1 != hi2); + *value = (hi1 << 8) | low; + return 0; +} + +static int charger_read_vrect(uint32_t *milliVolts) +{ + uint8_t data; + if (idt_read(Mem_MeasuredVrect, &data) != 0) return -1; + *milliVolts = ((data * 8) * 24500) / 4095; + return 0; +} + +bool charger_has_external(int dock) +{ + uint8_t status; + + // ignore failures, since that just means nothing's connected + if (idt_read(Mem_Status, &status) != 0) return false; + + return (status & Mem_Status_DOCK_PWR_EN) != 0; +} + +void charger_set_charging(int dock, uint32_t input_current_ma, uint32_t *charge_current_ma) +{ + // call through to PMU to configure charger + pmu_charger_set_charging(dock, input_current_ma, charge_current_ma); + + // do not touch 9022, since we assume iBoot does only open-loop high-voltage charging before handing off to OS or battery trap. +} + +void charger_print_status(void) +{ + pmu_charger_print_status(); + + uint8_t status; + if (idt_read(Mem_Status, &status) != 0) { + dprintf(DEBUG_CRITICAL, "charger: error reading status\n"); + return; + } + + uint32_t vrect; + if (charger_read_vrect(&vrect) != 0) { + dprintf(DEBUG_CRITICAL, "charger: error reading vrect\n"); + } + + printf("charger: status %02x vrect measured %u mV\n", status, vrect); +} diff --git a/drivers/idt/idtp9022/rules.mk b/drivers/idt/idtp9022/rules.mk new file mode 100644 index 0000000..7b25191 --- /dev/null +++ b/drivers/idt/idtp9022/rules.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2013 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CHARGER_IDTP9022=1 \ + WITH_HW_CHARGER=1 + +MODULES += \ + lib/power + +ALL_OBJS += \ + $(LOCAL_DIR)/idtp9022.o diff --git a/drivers/iic/debug.c b/drivers/iic/debug.c new file mode 100644 index 0000000..6452218 --- /dev/null +++ b/drivers/iic/debug.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2008 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + + +static int do_iic(int argc, struct cmd_arg *args) +{ + if (!security_allow_modes(kSecurityModeHWAccess)) { + printf("Permission Denied\n"); + return -1; + } + + if (argc < 3) { +notenoughargs: + puts("not enough arguments.\n"); +usage: + printf("%s read \n", args[0].str); + printf("%s readreg \n", args[0].str); + printf("%s creadreg \n", args[0].str); + printf("%s readreg16 \n", args[0].str); + printf("%s write ...\n", args[0].str); + printf("%s probe \n", args[0].str); + return -1; + } + + int bus = args[2].u; + int addr = args[3].u; + + if (bus < 0 || bus > 3) { + puts("unsupported bus\n"); + return -1; + } + + if (!strcmp("read", args[1].str)) { + uint8_t data[64]; + int err; + size_t len = args[4].u; + + if (len == 0 || len > 64) { + puts("invalid len\n"); + return -1; + } + + err = iic_read(bus, addr, NULL, 0, data, len, IIC_NORMAL); + if (err < 0) { + printf("error %d reading from iic\n", err); + } else { + hexdump(data, len); + } + } else if (!strcmp("readreg", args[1].str)) { + uint8_t data[64]; + uint8_t outdata; + int err; + size_t len = args[5].u; + + if (argc < 6) + goto notenoughargs; + + if (len == 0 || len > 64) { + puts("invalid len\n"); + return -1; + } + + outdata = args[4].u & 0xff; + + err = iic_read(bus, addr, &outdata, 1, data, len, IIC_NORMAL); + if (err < 0) { + printf("error %d reading from iic\n", err); + } else { + hexdump(data, len); + } + } else if (!strcmp("creadreg", args[1].str)) { + uint8_t data[64]; + uint8_t outdata; + int err; + size_t len = args[5].u; + + if (argc < 6) + goto notenoughargs; + + if (len == 0 || len > 64) { + puts("invalid len\n"); + return -1; + } + + outdata = args[4].u & 0xff; + + err = iic_read(bus, addr, &outdata, 1, data, len, IIC_COMBINED); + if (err < 0) { + printf("error %d reading from iic\n", err); + } else { + hexdump(data, len); + } + } else if (!strcmp("readreg16", args[1].str)) { + uint8_t data[64]; + uint16_t outdata; + int err; + size_t len = args[5].u; + + if (argc < 6) + goto notenoughargs; + + if (len == 0 || len > 64) { + puts("invalid len\n"); + return -1; + } + + outdata = swap16(args[4].u & 0xffff); + + err = iic_read(bus, addr, &outdata, 2, data, len, IIC_NORMAL); + if (err < 0) { + printf("error %d reading from iic\n", err); + } else { + hexdump(data, len); + } + } else if (!strcmp("write", args[1].str)) { + u_int8_t data[64]; + size_t len, i; + int err; + + len = argc - 4; + if (len > sizeof(data)) len = sizeof(data); + + for (i = 0; i < len; i++) { + data[i] = args[i+4].u; + } + + printf("writing %zu bytes of data\n", len); + err = iic_write(bus, addr, data, len); + if (err < 0) + printf("error %d writing to iic\n", err); + } else if (!strcmp("probe", args[1].str)) { + + for (addr = 1; addr < 0x7e; addr++) { + if (iic_probe(bus, addr)) + printf("0x%02x: found\n", addr); + } + } else { + puts("unrecognized command.\n"); + goto usage; + } + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(iic, do_iic, "iic read/write", NULL); + +#endif diff --git a/drivers/iic/rules.mk b/drivers/iic/rules.mk new file mode 100644 index 0000000..1527f21 --- /dev/null +++ b/drivers/iic/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_IIC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/swiic.o \ + $(LOCAL_DIR)/debug.o diff --git a/drivers/iic/swiic.c b/drivers/iic/swiic.c new file mode 100644 index 0000000..12fa05a --- /dev/null +++ b/drivers/iic/swiic.c @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* if no hardware IIC, use the software fallback */ +#if !WITH_HW_IIC + +#include +#include +#include +#include +#include +#include +#include + +#ifndef IICS_MASK +#define IICS_MASK ((1 << IICS_COUNT) - 1) +#endif + +static struct iic_soft_device *get_iic_soft_device(int port); +static void iic_soft_setup(struct iic_soft_device *dev); +static void iic_soft_reset_bus(struct iic_soft_device *dev); + +static void _setSCL(struct iic_soft_device *dev, bool assert); +static void _setSDA(struct iic_soft_device *dev, bool assert); +static u_int32_t _getSDA(struct iic_soft_device *dev); +static void _sendStart(struct iic_soft_device *dev); +static void _sendRestart(struct iic_soft_device *dev); +static void _sendStop(struct iic_soft_device *dev); +static void _sendAck(struct iic_soft_device *dev, bool ack); +static bool _writeByte(struct iic_soft_device *dev, u_int8_t data); +static u_int8_t _readByte(struct iic_soft_device *dev, bool ack); + + +/* struct definition */ +struct iic_soft_device { + u_int32_t _i2cPeriod; + u_int32_t _i2cSlaveDevice; + + u_int32_t iicAddressLength; + const u_int8_t *iicAddressBuffer; + u_int32_t iicDataLength; + u_int8_t *iicDataBuffer; + + u_int32_t _i2cDelay; + u_int32_t _i2cSDA; + gpio_t gpio_scl; + gpio_t gpio_sda; +}; + + +void iic_init(void) +{ + int iic; + + dprintf(DEBUG_INFO, "iic_soft_init()\n"); + + for (iic = 0; iic < IICS_COUNT; iic++) + iic_soft_setup(get_iic_soft_device(iic)); +} + +void iic_set_filter(int iic, uint32_t value) {} + +void iic_set_frequency(int iic, u_int32_t frequency) {} + +int iic_read(int iic, u_int8_t address, const void *send_data, size_t send_len, void *data, size_t len, iic_fmt_t fmt) +{ + struct iic_soft_device *dev = get_iic_soft_device(iic); + u_int32_t cnt = 0; + + if (dev == 0) return -1; + if (send_len == 0) return -1; + + dev->_i2cSlaveDevice = address; + + dev->iicAddressLength = send_len; + dev->iicAddressBuffer = (const u_int8_t *)send_data; + dev->iicDataLength = len; + dev->iicDataBuffer = (u_int8_t *)data; + + /* Send slave address */ + _sendStart(dev); + if (!_writeByte(dev, dev->_i2cSlaveDevice & ~(0x1))) { + _sendStop(dev); + return -1; + } + + /* Send address bytes */ + for (cnt = 0; cnt < dev->iicAddressLength; cnt++) { + if (!_writeByte(dev, dev->iicAddressBuffer[cnt])) { + _sendStop(dev); + return -1; + } + } + + if (fmt == IIC_NORMAL) { + /* Stop */ + _sendStop(dev); + _sendStart(dev); + } else { + _sendRestart(dev); + } + + /* Send slave address */ + if (!_writeByte(dev, dev->_i2cSlaveDevice | (0x1))) { + _sendStop(dev); + return -1; + } + /* clock data in */ + for (cnt = 0; cnt < dev->iicDataLength; cnt++) { + dev->iicDataBuffer[cnt] = _readByte(dev, cnt < (dev->iicDataLength -1)); + } + /* Stop */ + _sendStop(dev); + return 0; +} + +int iic_write(int iic, u_int8_t address, const void *data, size_t len) +{ + struct iic_soft_device *dev = get_iic_soft_device(iic); + u_int32_t cnt =0; + + if (dev == 0) return -1; + + dev->_i2cSlaveDevice = address; + + dev->iicAddressLength = 0; + dev->iicAddressBuffer = 0; + dev->iicDataLength = len; + dev->iicDataBuffer = (u_int8_t *)data; + + /* Send slave address */ + _sendStart(dev); + if (!_writeByte(dev, dev->_i2cSlaveDevice & ~(0x1))) { + _sendStop(dev); + return -1; + } + + /* Send data bytes */ + for (cnt = 0; cnt < dev->iicDataLength; cnt++) { + if (!_writeByte(dev, dev->iicDataBuffer[cnt])) { + _sendStop(dev); + return -1; + } + } + + /* Send stop */ + _sendStop(dev); + return 0; +} + +bool iic_probe(int iic, u_int8_t address) +{ + /* might be nice to implement this */ + return false; +} + + +/* Private */ +static struct iic_soft_device _iic_soft_device[] = { +#if IICS_COUNT > 0 + { + .gpio_scl = GPIO_IIC0_SCL, + .gpio_sda = GPIO_IIC0_SDA, + }, +#endif +#if IICS_COUNT > 1 + { + .gpio_scl = GPIO_IIC1_SCL, + .gpio_sda = GPIO_IIC1_SDA, + }, +#endif +#if IICS_COUNT > 2 + { + .gpio_scl = GPIO_IIC2_SCL, + .gpio_sda = GPIO_IIC2_SDA, + } +#endif +}; + +static struct iic_soft_device *get_iic_soft_device(int port) +{ + if (!((1 << port) & IICS_MASK)) + return 0; + return &_iic_soft_device[port]; +} + +static void iic_soft_setup(struct iic_soft_device *dev) +{ + if (dev == 0) return; + + /* set the clock as 400kHz */ +// dev->_i2cPeriod = 2500; +// dev->_i2cDelay = (dev->_i2cPeriod + 3)/4; + + /*reset the bus */ + iic_soft_reset_bus(dev); +} + +static void iic_soft_reset_bus(struct iic_soft_device *dev) +{ + u_int32_t cnt; + + // Write 00 so all devices will complete any partial transaction + // SDA starts low and goes high after the loop + // SCL start and ends the loop high + // The first and last iterations of the loop produce the + // start and stop conditions + + gpio_configure(dev->gpio_sda, GPIO_CFG_OUT_0); + + for (cnt = 0; cnt < (2 * 9 + 1); cnt++) { + gpio_configure(dev->gpio_scl, (cnt & 1) ? GPIO_CFG_OUT_0 : GPIO_CFG_IN); + spin(5); + } + + gpio_configure(dev->gpio_scl, GPIO_CFG_IN); + gpio_configure(dev->gpio_sda, GPIO_CFG_IN); +} + +static void _setSCL(struct iic_soft_device *dev, bool assert) +{ + if (assert) { + gpio_configure(dev->gpio_scl, GPIO_CFG_IN); + } else { + gpio_configure(dev->gpio_scl, GPIO_CFG_OUT_0); + } +} + +static void _setSDA(struct iic_soft_device *dev, bool assert) +{ + if (assert) { + gpio_configure(dev->gpio_sda, GPIO_CFG_IN); + } else { + gpio_configure(dev->gpio_sda, GPIO_CFG_OUT_0); + } +} + +static u_int32_t _getSDA(struct iic_soft_device *dev) +{ + u_int32_t tmp; + + gpio_configure(dev->gpio_sda, GPIO_CFG_IN); + + tmp = gpio_read(dev->gpio_sda); + + return tmp; +} + + +/* Send Start: SDA High -> Low while SCL is high */ +static void _sendStart(struct iic_soft_device *dev) +{ + spin(1); + spin(1); + _setSDA(dev, false); + spin(1); +} + +/* Send Restart: XXX */ +static void _sendRestart(struct iic_soft_device *dev) +{ + _setSCL(dev, false); + spin(1); + _setSDA(dev, true); + spin(1); + _setSCL(dev, true); + spin(1); + _setSDA(dev, false); +} + +/* Send Stop: SDA Low -> High while SCL is high */ +static void _sendStop(struct iic_soft_device *dev) +{ + _setSCL(dev, false); + spin(1); + _setSDA(dev, false); + spin(1); + _setSCL(dev, true); + spin(1); + _setSDA(dev, true); +} + + +static void _sendAck(struct iic_soft_device *dev, bool ack) +{ + _setSCL(dev, false); + spin(1); + _setSDA(dev, !ack); + spin(1); + _setSCL(dev, true); + spin(1); + spin(1); +} + +static bool _writeByte(struct iic_soft_device *dev, u_int8_t data) +{ + u_int32_t cnt; + u_int32_t ack; + + /* Send the byte */ + for (cnt = 0; cnt < 8; cnt++) { + _setSCL(dev, false); + spin(1); + _setSDA(dev, data & 0x80); + spin(1); + _setSCL(dev, true); + spin(1); + spin(1); + + data = (data << 1); + } + + /* Look for the ACK */ + _setSCL(dev, false); + spin(1); + _setSDA(dev, true); + spin(1); + _setSCL(dev, true); + spin(1); + ack = !_getSDA(dev); + spin(1); + + return (ack != 0); +} + +static u_int8_t _readByte(struct iic_soft_device *dev, bool ack) +{ + u_int32_t cnt; + u_int8_t data = 0; + + for (cnt = 0; cnt < 8; cnt++) { + _setSCL(dev, false); + spin(1); + _setSDA(dev, true); + spin(1); + _setSCL(dev, true); + spin(1); + data <<= 1; + data |= _getSDA(dev); + spin(1); + } + _sendAck(dev, ack); + + return data; +} + +#endif /* !WITH_HW_IIC */ diff --git a/drivers/intel/thunderbolt_nhi/nhi.c b/drivers/intel/thunderbolt_nhi/nhi.c new file mode 100644 index 0000000..11a50eb --- /dev/null +++ b/drivers/intel/thunderbolt_nhi/nhi.c @@ -0,0 +1,752 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "nhi_protocol.h" + +#define NHID_INIT (DEBUG_INFO) +// These will lead to deadlock if thunderbolt is used for the serial console +#define NHID_REG (DEBUG_SPEW) +#define NHID_DMA (DEBUG_SPEW) +#define NHID_RXPACKET_DUMP (DEBUG_NEVER) +#define NHID_TXPACKET_DUMP (DEBUG_NEVER) + +#define NHI_PROBE_MAX_BRIDGES (8) +#define NHI_PROBE_MIN_BAR_SIZE (0x40000) + +#define NHI_MAX_RINGS (1) + +#define NHI_BOOKKEEPING_IOVM_BASE (0x80100000) +#define NHI_BOOKKEEPING_PAGES (4) +#define NHI_BOOKKEEPING_SIZE (NHI_BOOKKEEPING_PAGES * DART_PAGE_SIZE) +#define NHI_BUFFER_IOVM_BASE (0x80200000) +#if NHI_BOOKKEEPING_IOVM_BASE + NHI_BOOKKEEPING_SIZE > NHI_BUFFER_IOVM_BASE +#error "NHI bookkeeping and buffer IOVM ranges overlap" +#endif + +typedef struct nhi_ring { + uint64_t buffers_iovm_addr; + uint64_t descriptors_iovm_addr; + uint32_t num_buffers; + uint32_t buffer_size; + uint32_t next_buffer_index; + + // All data structures after this comment are mapped via the + // DART, so software MUST NOT assume they will stay constant. + // Values must be copied to a safe location and then validated + void *buffers; + void *descriptors; +} nhi_ring_t; + +struct nhi { + nhi_ring_t tx_rings[NHI_MAX_RINGS]; + nhi_ring_t rx_rings[NHI_MAX_RINGS]; + + uintptr_t bookkeeping_base; + size_t bookkeeping_size; + size_t bookkeeping_used; + + size_t buffer_space_mapped; + + pci_device_t pci_device; + uintptr_t bar0; + uint32_t dart_id; + pci_device_t upstream_bridge; +}; + +static void nhi_quiesce_pci(nhi_t *nhi); + +static void nhi_write_reg(nhi_t *nhi, uint32_t offset, uint32_t value) +{ + dprintf(NHID_REG, "nhi: write register 0x%05x (0x%llx) <- 0x%08x\n", offset, nhi->bar0 + offset, value); + *(volatile uint32_t *)(nhi->bar0 + offset) = value; +} + +static uint32_t nhi_read_reg(nhi_t *nhi, uint32_t offset) +{ + uint32_t value; + value = *(volatile uint32_t *)(nhi->bar0 + offset); + dprintf(NHID_REG, "nhi: read register 0x%05x (0x%llx) -> 0x%08x\n", offset, nhi->bar0 + offset, value); + return value; +} + +static nhi_rx_buffer_desc_t *nhi_get_rx_buffer_desc(nhi_t *nhi, uint32_t ring_idx, uint32_t buffer_idx) +{ + nhi_ring_t *ring; + + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + + ring = &nhi->rx_rings[ring_idx]; + ASSERT(buffer_idx < ring->num_buffers); + + return (nhi_rx_buffer_desc_t *)ring->descriptors + buffer_idx; +} + +static nhi_tx_buffer_desc_t *nhi_get_tx_buffer_desc(nhi_t *nhi, uint32_t ring_idx, uint32_t buffer_idx) +{ + nhi_ring_t *ring; + + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + + ring = &nhi->tx_rings[ring_idx]; + ASSERT(buffer_idx < ring->num_buffers); + + return (nhi_tx_buffer_desc_t *)ring->descriptors + buffer_idx; +} + +static void *nhi_ring_get_buffer(nhi_ring_t *ring, uint32_t buffer_idx) +{ + ASSERT(ring != NULL); + ASSERT(buffer_idx < ring->num_buffers); + + return (void *)((uint8_t *)ring->buffers + buffer_idx * ring->buffer_size); +} + +static uint64_t nhi_ring_get_buffer_iovm_addr(nhi_ring_t *ring, uint32_t buffer_idx) +{ + ASSERT(ring != NULL); + ASSERT(buffer_idx < ring->num_buffers); + + return ring->buffers_iovm_addr + buffer_idx * ring->buffer_size; +} + +void nhi_debug_write(pci_device_t bridge, uint32_t vcap, uint8_t space, uint8_t port, uint16_t offset, uint32_t value) +{ + uint32_t cmd; + + cmd = offset | (port << 13) | (space << 19) | (1 << 21) | (0 << 22); + + pci_config_write32(bridge, vcap + 0x34, value); + pci_config_write32(bridge, vcap + 0x30, cmd | (1 << 30)); + spin(20); + + for (int retries = 5; retries > 0; retries--) { + do { + cmd = pci_config_read32(bridge, vcap + 0x30); + if ((cmd & (1U << 30)) == 0) + break; + if (cmd == 0xffffffff) + return; + spin(100); + } while(1); + + if (cmd & (1U << 31)) { + spin(2000); + continue; + } + break; + } +} + +uint32_t nhi_debug_read(pci_device_t bridge, uint32_t vcap, uint8_t space, uint8_t port, uint16_t offset) +{ + uint32_t cmd; + + cmd = offset | (port << 13) | (space << 19) | (0 << 22); + + pci_config_write32(bridge, vcap + 0x30, cmd | (1 << 30)); + spin(20); + + for (int retries = 5; retries > 0; retries--) { + do { + cmd = pci_config_read32(bridge, vcap + 0x30); + if ((cmd & (1U << 30)) == 0) + break; + if (cmd == 0xffffffff) + return 0xcdcdcdcd; + spin(100); + } while(1); + + if (cmd & (1U << 31)) { + spin(2000); + continue; + } + return pci_config_read32(bridge, vcap + 0x38); + } + + return 0xabababab; +} + +static void debug_dump_packet(uint8_t *buffer, uint32_t bytes) +{ + for (uint32_t off = 0; off < bytes; off += 4) { + uint32_t dword; + if (off % 16 == 0) + printf("[0x%03x] ", off); + memcpy(&dword, buffer + off, 4); + printf("%08x ", ntohl(dword)); + if (off % 16 == 12) + printf("\n"); + } + if ((bytes) % 16 != 0) + printf("\n"); +} + +void nhi_dump_config_space(pci_device_t bridge) +{ + uint32_t offset; + + offset = pci_find_extended_capability(bridge, 0xb, 0); + if (offset == 0) { + printf("couldn't get vendor-specific ecap\n"); + return; + } + +#if 0 + for (int j = 0; j < 0; j++) { + printf("Port %d port configuration space\n", j); + for (uint32_t i = 0; i < 8; i += 1) { + uint32_t value = nhi_debug_read(bridge, offset, 1, j, i); + spin(1000); + if (i % 4 == 0) + printf("%02x ", i); + printf(" %08x", value); + if (i % 4 == 3) + printf("\n"); + } + } + printf("\n"); + + for (int j = 0; j < 6; j++) { + printf("Port %d path configuration space\n", j); + for (uint32_t i = 0; i < 16; i += 1) { + uint32_t value = nhi_debug_read(bridge, offset, 0, j, i); + spin(1000); + if (i % 4 == 0) + printf("%02x ", i); + printf(" %08x", value); + if (i % 4 == 3) + printf("\n"); + } + } + printf("\n"); +#endif + + printf("Device configuration space\n"); + for (int i = 0; i < 5; i += 1) { + uint32_t value = nhi_debug_read(bridge, offset, 2, 0, i); + spin(1000); + if (i % 4 == 0) + printf("%02x ", i); + printf(" %08x", value); + if (i % 4 == 3) + printf("\n"); + } + printf("\n"); +} + +nhi_t *nhi_init(pci_device_t bridge, uint32_t dart_id) +{ + nhi_t *nhi = NULL; + uint32_t class_code; + uint32_t vendor_id; + uintptr_t bar0; + pci_device_t dev; + pci_device_t temp_bridge; + pci_device_t probed_bridges[NHI_PROBE_MAX_BRIDGES] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + + ASSERT(bridge != NULL); + + temp_bridge = bridge; + for (unsigned i = 0; i < NHI_PROBE_MAX_BRIDGES; i++) { + dev = pci_bridge_probe(temp_bridge, 0, 50000); + if (dev == NULL) + break; + + if (dev == temp_bridge) { + // We got the bridge back. Usually a sign of misconfiguration + // in our PCI stack + dprintf(DEBUG_CRITICAL, "nhi: probe from bridge %s returned itself\n", pci_get_name(temp_bridge)); + dev = NULL; + break; + } + + if (pci_is_bridge(dev)) { + dprintf(NHID_INIT, "nhi: probe found bridge: %s\n", pci_get_name(dev)); + pci_bridge_assign_secondary_bus(dev); + probed_bridges[i] = dev; + temp_bridge = dev; + dev = NULL; + } else { + break; + } + } + + if (dev == NULL) { + dprintf(DEBUG_CRITICAL, "nhi: couldn't find a PCI device\n"); + goto error; + } + + dprintf(NHID_INIT, "nhi: found NHI PCI device %s\n", pci_get_name(dev)); + + class_code = pci_get_class_code(dev); + vendor_id = pci_get_vendor_id(dev); + + if (class_code != NHI_CLASS_CODE) { + dprintf(DEBUG_CRITICAL, "nhi: incorrect class code 0x%x\n", class_code); + goto error; + } + if (vendor_id != NHI_VENDOR_ID) { + dprintf(DEBUG_CRITICAL, "nhi: incorrect vendor ID 0x%x\n", vendor_id); + goto error; + } + + if (pci_get_bar_size(dev, 0) < NHI_PROBE_MIN_BAR_SIZE) { + dprintf(DEBUG_CRITICAL, "nhi: BAR0 size 0x%llx too small\n", pci_get_bar_size(dev, 0)); + goto error; + } + bar0 = pci_map_bar(dev, 0); + if (bar0 == 0) { + dprintf(DEBUG_CRITICAL, "nhi: couldn't map BAR0\n"); + goto error; + } + + dprintf(NHID_INIT, "nhi: BAR0 mapped at 0x%llx\n", bar0); + + nhi = calloc(sizeof(*nhi), 1); + nhi->pci_device = dev; + nhi->bar0 = bar0; + nhi->dart_id = dart_id; + + nhi->bookkeeping_size = NHI_BOOKKEEPING_PAGES * DART_PAGE_SIZE; + nhi->bookkeeping_base = (uintptr_t)memalign(nhi->bookkeeping_size, DART_PAGE_SIZE); + dart_map_page_range(nhi->dart_id, nhi->bookkeeping_base, NHI_BOOKKEEPING_IOVM_BASE, NHI_BOOKKEEPING_PAGES, false); + + pci_bus_master_enable(dev, true); + pci_memory_space_enable(dev, true); + + // set bus master and memory space enable on all the bridges our probe found + for (unsigned i = 0; i < NHI_PROBE_MAX_BRIDGES && probed_bridges[i] != NULL; i++) { + pci_bus_master_enable(probed_bridges[i], true); + pci_memory_space_enable(probed_bridges[i], true); + } + nhi->upstream_bridge = probed_bridges[0]; + + return nhi; + +error: + dprintf(DEBUG_CRITICAL, "nhi: initialization failed\n"); + if (nhi != NULL) { + if (nhi->pci_device != NULL) + nhi_quiesce_pci(nhi); + if (nhi->bookkeeping_base != 0) { + dart_unmap_page_range(nhi->dart_id, NHI_BOOKKEEPING_IOVM_BASE, NHI_BOOKKEEPING_PAGES); + free((void *)nhi->bookkeeping_base); + nhi->bookkeeping_base = 0; + } + + free(nhi); + } else { + for (unsigned i = 0; i < NHI_PROBE_MAX_BRIDGES; i++) { + if (probed_bridges[NHI_PROBE_MAX_BRIDGES - i - 1] == NULL) + continue; + pci_free(probed_bridges[NHI_PROBE_MAX_BRIDGES - i - 1]); + } + if (dev != NULL) + pci_free(dev); + } + return NULL; +} + +static void nhi_quiesce_pci(nhi_t *nhi) +{ + pci_device_t device; + pci_device_t next_device; + + pci_set_powerstate(nhi->pci_device, PCI_PM_POWERSTATE_D3); + + // Disable bridges up to and including the upstream-most one managed by the driver. + // nhi_init will have stored the first bridge it found (if any) while looking for + // the NHI + next_device = nhi->pci_device; + do { + device = next_device; + pci_bus_master_enable(device, false); + pci_memory_space_enable(device, false); + next_device = pci_get_bridge(device); + pci_free(device); + } while (nhi->upstream_bridge != NULL && device != nhi->upstream_bridge); + nhi->upstream_bridge = NULL; + nhi->pci_device = NULL; +} + +void nhi_quiesce_and_free(nhi_t *nhi) +{ + dart_unmap_page_range(nhi->dart_id, NHI_BOOKKEEPING_IOVM_BASE, NHI_BOOKKEEPING_PAGES); + free((void *)nhi->bookkeeping_base); + nhi->bookkeeping_base = 0; + + nhi_quiesce_pci(nhi); + + for (unsigned i = 0; i < NHI_MAX_RINGS; i++) { + if (nhi->tx_rings[i].buffers != NULL) + free(nhi->tx_rings[i].buffers); + } + + for (unsigned i = 0; i < NHI_MAX_RINGS; i++) { + if (nhi->rx_rings[i].buffers != NULL) + free(nhi->rx_rings[i].buffers); + } + + free(nhi); + + dprintf(NHID_INIT, "nhi: quiesced\n"); +} + +static uint64_t nhi_dart_map(nhi_t *nhi, void *addr, size_t bytes) +{ + ASSERT(nhi != NULL); + ASSERT(addr != NULL); + ASSERT(bytes % DART_PAGE_SIZE == 0); + ASSERT(nhi->buffer_space_mapped + bytes > nhi->buffer_space_mapped); + + uint64_t iovmaddr = NHI_BUFFER_IOVM_BASE + nhi->buffer_space_mapped; + uint32_t pages = bytes / DART_PAGE_SIZE; + + dart_map_page_range(nhi->dart_id, (uintptr_t)addr, iovmaddr, pages, false); + + nhi->buffer_space_mapped += bytes; + + return iovmaddr; +} + +static void *nhi_allocate_bookkeeping(nhi_t *nhi, size_t bytes) { + void *allocated; + ASSERT(nhi != NULL); + ASSERT(nhi->bookkeeping_base != 0); + ASSERT(bytes > 0); + ASSERT(bytes <= nhi->bookkeeping_size - nhi->bookkeeping_used); + + allocated = (void *)(nhi->bookkeeping_base + nhi->bookkeeping_used); + nhi->bookkeeping_used += bytes; + + return allocated; +} + +static uint64_t nhi_translate_bookkeeping(nhi_t *nhi, void *addr) { + ASSERT(nhi != NULL); + + ASSERT((uintptr_t)addr >= nhi->bookkeeping_base); + ASSERT((uintptr_t)addr < nhi->bookkeeping_base + nhi->bookkeeping_used); + + return NHI_BOOKKEEPING_IOVM_BASE + (uintptr_t)addr - nhi->bookkeeping_base; +} + +static void nhi_alloc_ring(nhi_t *nhi, nhi_ring_t *ring, uint32_t num_buffers, uint32_t buffer_size) +{ + size_t total_size; + + ASSERT(ring != NULL); + ASSERT(ring->buffers == NULL); + ASSERT(ring->descriptors == NULL); + ASSERT(num_buffers < 0x10000); + ASSERT(buffer_size <= 4096); + + ring->num_buffers = num_buffers; + ring->buffer_size = buffer_size; + + // rx and tx buffer descriptor have the same size + ring->descriptors = nhi_allocate_bookkeeping(nhi, sizeof(nhi_tx_buffer_desc_t) * num_buffers); + ring->descriptors_iovm_addr = nhi_translate_bookkeeping(nhi, ring->descriptors); + + total_size = num_buffers * buffer_size; + total_size = (total_size + DART_PAGE_SIZE - 1) & ~(DART_PAGE_SIZE - 1); + ring->buffers = memalign(total_size, DART_PAGE_SIZE); + ring->buffers_iovm_addr = nhi_dart_map(nhi, ring->buffers, total_size); + +} + +void nhi_init_tx_ring(nhi_t *nhi, uint32_t ring_idx, uint32_t num_buffers, uint32_t buffer_size) +{ + nhi_ring_t *ring; + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t flags; + + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + ASSERT(num_buffers < 0x10000); + ASSERT(buffer_size <= 4096); + ASSERT(buffer_size % 4 == 0); + + dprintf(NHID_INIT, "nhi: tx ring %u init with %u buffers of %u bytes\n", ring_idx, num_buffers, buffer_size); + + ring = &nhi->tx_rings[ring_idx]; + + nhi_alloc_ring(nhi, ring, num_buffers, buffer_size); + + dprintf(NHID_INIT, "nhi: tx ring %u buffers at %p\n", ring_idx, ring->buffers); + dprintf(NHID_INIT, "nhi: tx ring %u buffer descriptors at %p\n", ring_idx, ring->descriptors); + + for (uint32_t i = 0; i < num_buffers; i++) { + nhi_tx_buffer_desc_t *desc; + uint64_t buffer_addr; + + desc = nhi_get_tx_buffer_desc(nhi, ring_idx, i); + memset(desc, 0, sizeof(*desc)); + buffer_addr = nhi_ring_get_buffer_iovm_addr(ring, i); + desc->addr_lo = (uint32_t)buffer_addr; + desc->addr_hi = (uint32_t)(buffer_addr >> 32); + desc->request_status = 1; + desc->descriptor_done = 1; + } + + addr_lo = (uint32_t)ring->descriptors_iovm_addr; + addr_hi = (uint32_t)(ring->descriptors_iovm_addr >> 32); + // buffer size of 4096 is expressed as 0 + nhi_write_reg(nhi, NHI_REG_TX_RING_ADDR_LO(ring_idx), addr_lo); + nhi_write_reg(nhi, NHI_REG_TX_RING_ADDR_HI(ring_idx), addr_hi); + nhi_write_reg(nhi, NHI_REG_TX_RING_SIZE(ring_idx), num_buffers); + + // for now, only support raw mode rings + flags = NHI_TX_TABLE_VALID | NHI_TX_TABLE_RAW_MODE; + nhi_write_reg(nhi, NHI_REG_TX_TABLE_FLAGS(ring_idx), flags); +} + +void nhi_disable_tx_ring(nhi_t *nhi, uint32_t ring_idx) +{ + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + + nhi_write_reg(nhi, NHI_REG_TX_TABLE_FLAGS(ring_idx), 0); +} + +void nhi_init_rx_ring(nhi_t *nhi, uint32_t ring_idx, uint32_t num_buffers, uint32_t buffer_size) +{ + nhi_ring_t *ring; + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t sizes; + uint32_t flags; + + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + ASSERT(num_buffers < 0x10000); + ASSERT(buffer_size >= 256); + ASSERT(buffer_size <= 0x1000); + ASSERT(buffer_size % 4 == 0); + + dprintf(NHID_INIT, "nhi: rx ring %u init with %u buffers of %u bytes\n", ring_idx, num_buffers, buffer_size); + + ring = &nhi->rx_rings[ring_idx]; + + nhi_alloc_ring(nhi, ring, num_buffers, buffer_size); + + dprintf(NHID_INIT, "nhi: rx ring %u buffers at %p\n", ring_idx, ring->buffers); + dprintf(NHID_INIT, "nhi: rx ring %u buffer descriptors at %p\n", ring_idx, ring->descriptors); + + for (uint32_t i = 0; i < num_buffers; i++) { + nhi_rx_buffer_desc_t *desc; + uint64_t buffer_addr; + + desc = nhi_get_rx_buffer_desc(nhi, ring_idx, i); + memset(desc, 0, sizeof(*desc)); + buffer_addr = nhi_ring_get_buffer_iovm_addr(ring, i); + desc->addr_lo = (uint32_t)buffer_addr; + desc->addr_hi = (uint32_t)(buffer_addr >> 32); + desc->request_status = 1; + } + + addr_lo = (uint32_t)ring->descriptors_iovm_addr; + addr_hi = (uint32_t)(ring->descriptors_iovm_addr >> 32); + // buffer size of 4096 is expressed as 0 + sizes = NHI_RX_RING_DESC_RING_SIZE_BUFFER_SIZE(num_buffers, buffer_size); + nhi_write_reg(nhi, NHI_REG_RX_RING_ADDR_LO(ring_idx), addr_lo); + nhi_write_reg(nhi, NHI_REG_RX_RING_ADDR_HI(ring_idx), addr_hi); + nhi_write_reg(nhi, NHI_REG_RX_RING_SIZE_BUFFER_SIZE(ring_idx), sizes); + + // Feed all but the last frame to the NHI... keep the last one back because + // producer == consumer means an empty ring + nhi_write_reg(nhi, NHI_REG_RX_RING_INDEXES(ring_idx), num_buffers - 1); + ring->next_buffer_index = 0; + + // for now, accept every PDF value as start and end of frame + nhi_write_reg(nhi, NHI_REG_RX_TABLE_PDF_BITMASKS(ring_idx), 0xffffffff); + // for now, only support raw mode rings + flags = NHI_RX_TABLE_VALID | NHI_RX_TABLE_RAW_MODE; + nhi_write_reg(nhi, NHI_REG_RX_TABLE_FLAGS(ring_idx), flags); +} + +void nhi_disable_rx_ring(nhi_t *nhi, uint32_t ring_idx) +{ + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + + nhi_write_reg(nhi, NHI_REG_RX_TABLE_FLAGS(ring_idx), 0); +} + +int32_t nhi_send_sgl(nhi_t *nhi, uint32_t ring_idx, const nhi_sgl_t *sgl, uint8_t sof_pdf, uint8_t eof_pdf) +{ + nhi_ring_t *ring; + volatile nhi_tx_buffer_desc_t *desc; + uint32_t bytes = 0; + uint8_t *buffer; + utime_t start_time; + + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + + ring = &nhi->tx_rings[ring_idx]; + desc = nhi_get_tx_buffer_desc(nhi, ring_idx, ring->next_buffer_index); + buffer = nhi_ring_get_buffer(ring, ring->next_buffer_index); + + start_time = system_time(); + while (!desc->descriptor_done) { + if (time_has_elapsed(start_time, 2000000)) + return NHI_STATUS_TIMEOUT; + task_yield(); + platform_memory_barrier(); + } + + dprintf(NHID_DMA, "nhi: tx ring %u queueing buffer %u (%p) for transmit, pdfs %04x/%04x\n", + ring_idx, ring->next_buffer_index, buffer, sof_pdf, eof_pdf); + + while (sgl != NULL) { + ASSERT(bytes + sgl->bytes > bytes); + ASSERT(bytes + sgl->bytes <= ring->buffer_size); + + memcpy(buffer + bytes, sgl->buffer, sgl->bytes); + bytes += sgl->bytes; + + sgl = sgl->next; + } + +#if NHID_TXPACKET_DUMP <= DEBUG_LEVEL + printf("nhi: tx packet:\n"); + debug_dump_packet(buffer, bytes); +#endif + + // Update the DMA descriptor the NHI will DMA from host memory + desc->length = bytes; + desc->sof_pdf = sof_pdf; + desc->eof_pdf = eof_pdf; + desc->descriptor_done = 0; + desc->interrupt_enable = 0; + desc->request_status = 1; + + // Update our internal accounting of the next free descriptor in the ring + ring->next_buffer_index++; + if (ring->next_buffer_index == ring->num_buffers) + ring->next_buffer_index = 0; + + platform_memory_barrier(); + + // And let the NHI know that there's a new descriptor for it to process + nhi_write_reg(nhi, NHI_REG_TX_RING_INDEXES(ring_idx), ring->next_buffer_index << 16); + + return NHI_STATUS_OK; +} + +int32_t nhi_send_buffer(nhi_t *nhi, uint32_t ring_idx, void *buffer, uint32_t bytes, uint8_t sof_pdf, uint8_t eof_pdf) +{ + nhi_sgl_t sgl; + + sgl.buffer = buffer; + sgl.bytes = bytes; + sgl.next = NULL; + + return nhi_send_sgl(nhi, ring_idx, &sgl, sof_pdf, eof_pdf); +} + +bool nhi_rx_buffer_available(nhi_t *nhi, uint32_t ring_idx) +{ + nhi_ring_t *ring; + volatile nhi_rx_buffer_desc_t *next; + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + + ring = &nhi->rx_rings[ring_idx]; + + next = nhi_get_rx_buffer_desc(nhi, ring_idx, ring->next_buffer_index); + + platform_memory_barrier(); + + return next->descriptor_done != 0; +} + +int32_t nhi_rx_buffer(nhi_t *nhi, uint32_t ring_idx, void *buffer, uint32_t bytes, uint8_t *sof_pdf, uint8_t *eof_pdf) +{ + nhi_ring_t *ring; + nhi_rx_buffer_desc_t *next; + nhi_rx_buffer_desc_t descriptor; + int32_t status = NHI_STATUS_UNKNOWN_ERROR; + utime_t start_time; + + ASSERT(nhi != NULL); + ASSERT(ring_idx < NHI_MAX_RINGS); + + ring = &nhi->rx_rings[ring_idx]; + ASSERT(bytes <= ring->buffer_size); + + start_time = system_time(); + while (!nhi_rx_buffer_available(nhi, ring_idx)) { + if (time_has_elapsed(start_time, 2000000)) + return NHI_STATUS_TIMEOUT; + task_yield(); + } + + // XXX: Are we guaranteed that buffer update is atomic and/or length write never + // passes status update write? + next = nhi_get_rx_buffer_desc(nhi, ring_idx, ring->next_buffer_index); + memcpy(&descriptor, next, sizeof(descriptor)); + + platform_memory_barrier(); + + if (descriptor.crc_error) { + dprintf(DEBUG_CRITICAL, "nhi: rx ring %u CRC error\n", ring_idx); + status = NHI_STATUS_CRC_ERROR; + goto done; + } + + if (descriptor.length > bytes) { + dprintf(DEBUG_CRITICAL, "nhi: rx ring %u length overrun (%u vs %u)\n", + ring_idx, descriptor.length, bytes); + status = NHI_STATUS_INVALID_DESCRIPTOR; + goto done; + } + + if (sof_pdf != NULL) + *sof_pdf = descriptor.sof_pdf; + if (eof_pdf != NULL) + *eof_pdf = descriptor.eof_pdf; + + status = descriptor.length; + memcpy(buffer, nhi_ring_get_buffer(ring, ring->next_buffer_index), descriptor.length); + + dprintf(NHID_DMA, "nhi: ring %u rx packet pdfs %x/%x bytes %u\n", ring_idx, + descriptor.sof_pdf, descriptor.eof_pdf, descriptor.length); +#if NHID_RXPACKET_DUMP <= DEBUG_LEVEL + printf("nhi: rx packet:\n"); + debug_dump_packet(buffer, descriptor.length); +#endif + +done: + // Use the buffer we just processed as the free buffer, and give the previous + // free buffer to the DMA engine + nhi_write_reg(nhi, NHI_REG_RX_RING_INDEXES(ring_idx), ring->next_buffer_index); + ring->next_buffer_index++; + if (ring->next_buffer_index == ring->num_buffers) + ring->next_buffer_index = 0; + // Reset the buffer we just processed + next->details = 0; + next->length = ring->buffer_size; + next->request_status = 1; + + return status; +} diff --git a/drivers/intel/thunderbolt_nhi/nhi_protocol.h b/drivers/intel/thunderbolt_nhi/nhi_protocol.h new file mode 100644 index 0000000..e2dc227 --- /dev/null +++ b/drivers/intel/thunderbolt_nhi/nhi_protocol.h @@ -0,0 +1,72 @@ +#ifndef NHI_PROTOCOL_H +#define NHI_PROTOCOL_H + +#define NHI_CLASS_CODE (0x088000) +#define NHI_VENDOR_ID (0x8086) + +typedef struct nhi_rx_buffer_desc { + uint32_t addr_lo; + uint32_t addr_hi; + union { + struct { + uint32_t length:12; + uint32_t eof_pdf:4; + uint32_t sof_pdf:4; + uint32_t crc_error:1; + uint32_t descriptor_done:1; + uint32_t request_status:1; + uint32_t interrupt_enable:1; + uint32_t offset:8; + }; + uint32_t details; + }; + uint32_t timestamp; +} nhi_rx_buffer_desc_t; + +typedef struct nhi_tx_buffer_desc { + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t length:12; + uint32_t eof_pdf:4; + uint32_t sof_pdf:4; + uint32_t isochronous_dma_enable:1; + uint32_t descriptor_done:1; + uint32_t request_status:1; + uint32_t interrupt_enable:1; + uint32_t offset:8; + uint32_t fetch_time; +} nhi_tx_buffer_desc_t; + +typedef struct nhi_ring_desc { + uint32_t addr_lo; + uint32_t addr_hi; + // The NHI documentation says that controller registers + // must be read/written as 32-bit values + uint32_t consumer_idx:16; + uint32_t producer_idx:16; + uint32_t ring_size:16; + uint32_t reserved:16; +} nhi_ring_desc_t; + +#define NHI_REG_TX_RING_ADDR_LO(ring) (0x00000 + (ring) * 0x10) +#define NHI_REG_TX_RING_ADDR_HI(ring) (0x00004 + (ring) * 0x10) +#define NHI_REG_TX_RING_INDEXES(ring) (0x00008 + (ring) * 0x10) +#define NHI_REG_TX_RING_SIZE(ring) (0x0000C + (ring) * 0x10) +#define NHI_REG_RX_RING_ADDR_LO(ring) (0x08000 + (ring) * 0x10) +#define NHI_REG_RX_RING_ADDR_HI(ring) (0x08004 + (ring) * 0x10) +#define NHI_REG_RX_RING_INDEXES(ring) (0x08008 + (ring) * 0x10) +#define NHI_REG_RX_RING_SIZE_BUFFER_SIZE(ring) (0x0800C + (ring) * 0x10) +#define NHI_REG_TX_TABLE_FLAGS(ring) (0x19800 + (ring) * 0x20) +#define NHI_REG_RX_TABLE_FLAGS(ring) (0x29800 + (ring) * 0x20) +#define NHI_REG_RX_TABLE_PDF_BITMASKS(ring) (0x29804 + (ring) * 0x20) + +#define NHI_RX_RING_DESC_RING_SIZE_BUFFER_SIZE(ring_size, buffer_size) \ + ((ring_size & (0xffff)) | (((buffer_size) & (0xfff)) << 16)) + +#define NHI_TX_TABLE_VALID (1 << 31) +#define NHI_TX_TABLE_RAW_MODE (1 << 30) + +#define NHI_RX_TABLE_VALID (1 << 31) +#define NHI_RX_TABLE_RAW_MODE (1 << 30) + +#endif // NHI_PROTOCOL_H diff --git a/drivers/intel/thunderbolt_nhi/rules.mk b/drivers/intel/thunderbolt_nhi/rules.mk new file mode 100644 index 0000000..8f52233 --- /dev/null +++ b/drivers/intel/thunderbolt_nhi/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_THUNDERBOLT_NHI=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/nhi.o + diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c new file mode 100644 index 0000000..7e0d61f --- /dev/null +++ b/drivers/nvme/nvme.c @@ -0,0 +1,2194 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef NVME_DEBUG_LEVEL +#define DEBUG_LEVEL NVME_DEBUG_LEVEL +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nvme_blockdev.h" +#include "nvme_protocol.h" + +#if WITH_MASS_STORAGE +#define NVME_WITH_NORMAL_MODE (1) +#endif + +#define ADMIN_QUEUE_ID (0) +#define IO_QUEUE_ID (1) +#define NUM_QUEUES (2) + +#define MAX_TRANSFER_BLOCKS (512) +#define QUEUE_ENTRIES (16) + +#if MAX_TRANSFER_BLOCKS * 8 > NVME_PAGE_SIZE +#error "NVMe driver assumes PRP list fits in a single page +#endif + +#if !RELEASE_BUILD && WITH_MENU +#define NVME_FW_DOWNLOAD_MIN_LENGTH (4 * 1024) +#define NVME_FW_ACTIVATE_STATUS_SUCCESS (-267) +#define NVME_FW_TYPE_OPERATIONAL 0 +#define NVME_FW_TYPE_BACKUP 1 +#endif + +#define NVME_CONTROLLER_DISABLE_TIMEOUT (5 * 1000 * 1000) +#define NVME_CONTROLLER_SHUTDOWN_TIMEOUT (240 * 1000 * 1000) +#define NVME_NORMAL_CONTROLLER_ENABLE_TIMEOUT (240 * 1000 * 1000) +#define NVME_BOOT_CONTROLLER_ENABLE_TIMEOUT (5 * 1000 * 1000) +#define NVME_ADMIN_TIMEOUT (3 * 1000 * 1000) +#define NVME_BOOT_IO_TIME_PER_LBA (30 * 1000) +#define NVME_NORMAL_IO_TIMEOUT (30 * 1000 * 1000) + +// Eventually these may need to be defined per-platform +#define NVME_IOVM_BOOKKEEPING_BASE (0x80004000) +#define NVME_IOVM_BOOKKEEPING_PAGES (8) +#define NVME_IOVM_BOOKKEEPING_SIZE (NVME_PAGE_SIZE * NVME_IOVM_BOOKKEEPING_PAGES) +#define NVME_IOVM_IO_BASE (NVME_IOVM_BOOKKEEPING_BASE + NVME_IOVM_BOOKKEEPING_SIZE + NVME_PAGE_SIZE) +#define NVME_IOVM_IO_SIZE (MAX_TRANSFER_BLOCKS * NVME_PAGE_SIZE) +#define NVME_IOVM_SCRATCH_END (0xB0000000) + +enum NVMeEmbeddedNamespaceIDs +{ + EmbeddedNamespaceTypeNone = 0, + EmbeddedNamespaceTypeRoot = 1, + EmbeddedNamespaceTypeFirmware = 2, + EmbeddedNamespaceTypeSysConfig = 3, + EmbeddedNamespaceTypeControlBits = 4, + EmbeddedNamespaceTypeNVRAM = 5, + EmbeddedNamespaceTypeEffaceable = 6, + EmbeddedDeviceTypeCalibration = 7, + EmbeddedDeviceTypePanicLog = 8, + EmbeddedNamespaceTypeLLB = 9, + + NumEmbeddedDeviceTypes = 10 +}; + +typedef struct { + uint64_t completions_iovm_addr; + uint32_t head; + uint32_t tail; + uint32_t elements; + uint16_t queue_id; + uint8_t phase:1; + bool created; + + // NOTE: All of the data structures after this comment are mapped via the DART, + // so software MUST NOT assume values will not change. Values should + // be copied into safe locations and then validated prior to use + nvme_completion_t *completions; +} nvme_cq_t; + +typedef struct { + uint64_t commands_iovm_addr; + uint32_t head; + uint32_t tail; + uint32_t elements; + uint16_t queue_id; + bool created; + nvme_cq_t *cq; + + uint16_t last_command_id; + + // NOTE: All of the data structures after this comment are mapped via the DART, + // so software MUST NOT assume values will not change. Values should + // be copied into safe locations and then validated prior to use + nvme_command_t *commands; +} nvme_sq_t; + +typedef struct { + nvme_sq_t sq[NUM_QUEUES]; + nvme_cq_t cq[NUM_QUEUES]; + + nvme_sq_t *admin_sq; + nvme_sq_t *io_sq; + + bool initialized; + bool identified; + bool enabled; +#if NVME_WITH_NORMAL_MODE + uint8_t mode; +#endif + int id; + pci_device_t bridge_dev; + pci_device_t pci_dev; + uintptr_t reg_base; + uint32_t doorbell_stride; + unsigned int dart_id; + + uint16_t vendor_id; + char serial_number[21]; + char model_number[41]; + char firmware_revision[9]; + + uint32_t max_transfer_blocks; + uint32_t num_namespaces; + + uint64_t prp_list_iovm_addr; + + uintptr_t bookkeeping_base; + uintptr_t bookkeeping_next; + uintptr_t bookkeeping_limit; + + uint64_t scratch_iovm_base; + uint32_t scratch_size; + + int last_error; + bool cfs; + // holds Apple-only assertion logging info + uint32_t assert_data[4]; + // holds Apple-only extended debug data + uint32_t edd_data[8]; + + // NOTE: All of the data structures after this comment are mapped via the DART, + // so software MUST NOT assume values will not change. Values should + // be copied into safe locations and then validated prior to use + uint64_t *prp_list; + void *identify_buffer; +} nvme_t; + +#define NVME_DRIVE_CONFIG_BYTE_OFFSET 3100 +#define NVME_GET_BIT_FIELD_VALUE(contents, mask, offset) ( ( contents & mask ) >> offset ) +#define NVME_FIELD_MASK(location, length) ( ( ( 1 << length ) - 1 ) << location ) + +enum +{ + NANDDeviceVendorOffset = 0, + NANDDeviceVendorLen = 3, + NANDDeviceVendorMask = NVME_FIELD_MASK ( NANDDeviceVendorOffset, NANDDeviceVendorLen ), + NANDDeviceLithographyOffset = 3, + NANDDeviceLithographyLen = 4, + NANDDeviceLithographyMask = NVME_FIELD_MASK ( NANDDeviceLithographyOffset, NANDDeviceLithographyLen ), + NANDDeviceDensityOffset = 7, + NANDDeviceDensityLen = 2, + NANDDeviceDensityMask = NVME_FIELD_MASK ( NANDDeviceDensityOffset, NANDDeviceDensityLen ), + NANDDeviceTechnologyOffset = 9, + NANDDeviceTechnologyLen = 3, + NANDDeviceTechnologyMask = NVME_FIELD_MASK ( NANDDeviceTechnologyOffset, NANDDeviceTechnologyLen ), + NANDDeviceNumPlanesOffset = 12, + NANDDeviceNumPlanesLen = 2, + NANDDeviceNumPlanesMask = NVME_FIELD_MASK ( NANDDeviceNumPlanesOffset, NANDDeviceNumPlanesLen ), + NANDDeviceCapacityOffset = 14, + NANDDeviceCapacityLen = 2, + NANDDeviceCapacityMask = NVME_FIELD_MASK ( NANDDeviceCapacityOffset, NANDDeviceCapacityLen ), +}; + +enum +{ + NANDDeviceECCVersionOffset = 0, + NANDDeviceECCVersionLen = 4, + NANDDeviceECCVersionMask = NVME_FIELD_MASK ( NANDDeviceECCVersionOffset, NANDDeviceECCVersionLen ), + NANDDeviceNANDVersionOffset = 4, + NANDDeviceNANDVersionLen = 4, + NANDDeviceNANDVersionMask = NVME_FIELD_MASK ( NANDDeviceNANDVersionOffset, NANDDeviceNANDVersionLen ), +}; + +typedef struct { + NVME_IDCMD_ChipID_E ChipHW : 8; /* S3E/S3X/Etc. */ + NVME_IDCMD_ChipRevMajor_E ChipRevMajor : 4; /* REV_A/REV_B/Etc. */ + uint32_t ChipRevMinor : 4; /* 0/1/2/Etc. */ + uint16_t NandDeviceDescriptor; + uint8_t MSP_ECC_Version; + uint8_t FTL_MajorVersion; + uint8_t FTL_MinorVersion; + uint8_t DM_Version; +} NVME_IDCMD_DriveConfigAndDBVer_T; + +#define SQ_TAIL(_q) ((_q)->commands + (_q)->tail) +#define CQ_HEAD(_q) ((_q)->completions + (_q)->head) + +#define ASSERT_QUEUE_NOT_FULL(_q) ASSERT(((_q)->tail + 1) % (_q)->elements != (_q)->head) + +static void dump_completion(int log_level, nvme_completion_t *completion); +static void dump_command(int log_level, nvme_command_t *command); +static void dump_submission_queue(int log_level, nvme_sq_t *sq); +static void dump_completion_queue(int log_level, nvme_cq_t *cq); +static void dump_controller_state(int log_level, nvme_t *nvme); + +int nvme_update_firmware(int nvme_id, const void *fw_buffer, size_t fw_length); +static int do_nvmefw(int argc, struct cmd_arg *args); + +static void nvme_write_reg32(nvme_t *nvme, uint32_t offset, uint32_t value) +{ + dprintf(DEBUG_SPEW, "nvme: set reg 0x%08x = 0x%08x\n", offset, value); + *(volatile uint32_t *)(nvme->reg_base + offset) = value; +} + +static void nvme_write_reg64(nvme_t *nvme, uint32_t offset, uint64_t value) +{ + dprintf(DEBUG_SPEW, "nvme: set reg 0x%08x = 0x%016llx\n", offset, value); + *(volatile uint32_t *)(nvme->reg_base + offset) = (uint32_t)value; + *(volatile uint32_t *)(nvme->reg_base + offset + 4) = value >> 32; +} + +static bool nvme_check_reg_valid32(uint32_t value) +{ + return value != UINT32_MAX; +} + +static bool nvme_check_reg_valid64(uint64_t value) +{ + return value != UINT64_MAX; +} + +static uint32_t nvme_read_reg32(nvme_t *nvme, uint32_t offset) +{ + uint32_t value; + + dprintf(DEBUG_NEVER, "nvme: read_reg32 0x%08x", offset); + + value = *(volatile uint32_t *)(nvme->reg_base + offset); + + dprintf(DEBUG_NEVER, " == 0x%08x\n", value); + + return value; +} + +static uint64_t nvme_read_reg64(nvme_t *nvme, uint32_t offset) +{ + bool valid = true; + uint32_t low; + uint32_t high; + uint64_t value; + + dprintf(DEBUG_NEVER, "nvme: read_reg64 0x%08x", offset); + + low = *(volatile uint32_t *)(nvme->reg_base + offset); + valid = nvme_check_reg_valid32(low); + + if (valid) { + high = *(volatile uint32_t *)(nvme->reg_base + offset + 4); + + valid = nvme_check_reg_valid32(high); + } + + if (valid) { + value = ((uint64_t)high << 32) | low; + + dprintf(DEBUG_NEVER, " == 0x%016llx\n", value); + + return value; + } else { + dprintf(DEBUG_NEVER, " == invalid\n"); + return UINT64_MAX; + } +} + +static int nvme_poll_reg32(nvme_t *nvme, uint32_t offset, uint32_t required_value, uint32_t timeout_ms) +{ + uint32_t ms_left = timeout_ms; + while (nvme_read_reg32(nvme, offset) != required_value) { + if (ms_left == 0) { + dprintf(DEBUG_CRITICAL, "nvme: timed out polling register. (offset=0x%x, required_value=0x%x, timeout=%d)\n", + offset, required_value, timeout_ms); + return NVME_ERR_POLL_REG_TIMEOUT; + } + spin(1000); + ms_left--; + } + + return NVME_SUCCESS; +} + +static uint64_t nvme_translate_bookkeeping(nvme_t *nvme, void *addr) +{ + uint64_t translated; + translated = (uintptr_t)addr - nvme->bookkeeping_base; + translated += NVME_IOVM_BOOKKEEPING_BASE; + + return translated; +} + +static void * nvme_get_bookkeeping_pages(nvme_t *nvme, uint32_t num_pages) +{ + ASSERT(num_pages > 0); + + void *ret = (void *)nvme->bookkeeping_next; + + nvme->bookkeeping_next += num_pages * NVME_PAGE_SIZE; + + ASSERT(nvme->bookkeeping_base < nvme->bookkeeping_next); + ASSERT(nvme->bookkeeping_next < nvme->bookkeeping_limit); + + return ret; +} + +static void nvme_update_error(nvme_t *nvme, int status) +{ + if (status != NVME_SUCCESS) { + uint32_t csts = nvme_read_reg32(nvme, NVME_REG_CSTS); + + if ((csts & NVME_CSTS_CFS) != 0 && !nvme->cfs) { + nvme->cfs = true; + // This will only work with S3E, but it's the only NVMe device we support for now + for (unsigned i = 0; i < 4; i++) + nvme->assert_data[i] = nvme_read_reg32(nvme, NVME_REG_S3E_ASSERT_ID + i * 4); + for (unsigned i = 0; i < 8; i++) + nvme->edd_data[i] = nvme_read_reg32(nvme, NVME_REG_S3E_ASSERT_EDD0 + i * 4); +#if ( ( PRODUCT_IBOOT || PRODUCT_LLB ) && !RELEASE_BUILD ) + panic("nvme: fatal status, assertion data %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + nvme->assert_data[0], nvme->assert_data[1], nvme->assert_data[2], nvme->assert_data[3], + nvme->edd_data[0], nvme->edd_data[1], nvme->edd_data[2], nvme->edd_data[3], + nvme->edd_data[4], nvme->edd_data[5], nvme->edd_data[6], nvme->edd_data[7]); +#else + dprintf(DEBUG_CRITICAL, "nvme: fatal status, assertion data %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + nvme->assert_data[0], nvme->assert_data[1], nvme->assert_data[2], nvme->assert_data[3], + nvme->edd_data[0], nvme->edd_data[1], nvme->edd_data[2], nvme->edd_data[3], + nvme->edd_data[4], nvme->edd_data[5], nvme->edd_data[6], nvme->edd_data[7]); +#endif + } + + if (nvme->last_error == NVME_SUCCESS) { + dprintf(DEBUG_INFO, "nvme: setting error status %d\n", status); + nvme->last_error = status; + } else { + dprintf(DEBUG_INFO, "nvme: double error %d not recorded\n", status); + } + } +} + +// After some errors, we want to stop sending requests to the device and just fail +// all subsequent API calls. API entry points should check with this function to +// see if such an error has occurred. +static int nvme_get_hard_error(nvme_t *nvme) +{ + if (nvme->cfs) { + return NVME_ERR_CFS; + } + + switch (nvme->last_error) { + case NVME_ERR_ENABLE_TIMEOUT: + case NVME_ERR_DISABLE_TIMEOUT: + case NVME_ERR_INVALID_REG: + case NVME_ERR_ADMIN_CMD_TIMEOUT: + case NVME_ERR_IO_CMD_TIMEOUT: + return nvme->last_error; + default: + return NVME_SUCCESS; + } +} + +static void nvme_sq_init_cmd(nvme_sq_t *sq, nvme_command_t *cmd) +{ + bzero(cmd, sizeof(*cmd)); + sq->last_command_id = ((sq->last_command_id + 1) & 0xff) | sq->queue_id << 8; + cmd->cid = sq->last_command_id; +} + +static void nvme_sq_add_cmd(nvme_sq_t *sq, nvme_command_t *cmd) +{ + ASSERT_QUEUE_NOT_FULL(sq); + + memcpy((void *)SQ_TAIL(sq), cmd, sizeof(*cmd)); + + if (DEBUG_LEVEL >= DEBUG_SPEW) { + dprintf(DEBUG_SPEW, "nvme: Added command to queue 0x%x at index 0x%x\n", sq->queue_id, sq->tail); + dump_command(DEBUG_SPEW, cmd); + } + + sq->tail = sq->tail == (sq->elements - 1) ? 0 : sq->tail + 1; +} + +static void nvme_push_admin_cmd_create_cq(nvme_t *nvme, nvme_cq_t *cq) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_CREATE_CQ; + cmd.prp1 = cq->completions_iovm_addr; + cmd.cdw[10] = ((cq->elements - 1) << 16) | cq->queue_id; + cmd.cdw[11] = NVME_CREATE_CQ_CONTIGUOUS; + + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} + +static void nvme_push_admin_cmd_create_sq(nvme_t *nvme, nvme_sq_t *sq) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_CREATE_SQ; + cmd.prp1 = sq->commands_iovm_addr; + cmd.cdw[10] = ((sq->elements - 1) << 16) | sq->queue_id; + cmd.cdw[11] = sq->cq->queue_id << 16 | NVME_CREATE_SQ_CONTIGUOUS; + + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} + +static void nvme_push_admin_cmd_delete_cq(nvme_t *nvme, nvme_cq_t *cq) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_DELETE_CQ; + cmd.cdw[10] = cq->queue_id; + + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} + +static void nvme_push_admin_cmd_delete_sq(nvme_t *nvme, nvme_sq_t *sq) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_DELETE_SQ; + cmd.cdw[10] = sq->queue_id; + + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} + +static void nvme_push_admin_cmd_identify_namespace(nvme_t *nvme, uint32_t namespace, uint64_t prp) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_IDENTIFY; + cmd.nsid = namespace; + cmd.prp1 = prp; + cmd.cdw[10] = 0; // identify namespace, not controller + + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} + +static void nvme_push_admin_cmd_identify_controller(nvme_t *nvme, uint64_t prp) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_IDENTIFY; + cmd.nsid = 0; + cmd.prp1 = prp; + cmd.cdw[10] = 1; // identify controller + + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} + +#if !RELEASE_BUILD && WITH_MENU +static void nvme_push_admin_cmd_firmware_download(nvme_t *nvme, uint64_t *prp_list, uint32_t num_dwords, uint32_t offset, uint8_t fw_type) +{ + nvme_command_t cmd; + + //setup command + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_FW_DOWNLOAD; + cmd.lprp = 1; + cmd.nsid = 0; + cmd.prp1 = prp_list[0]; + cmd.cdw[10] = num_dwords - 1; // Number of DWORDS (total bytes should be multiple of 4KB). Zero-based parameter.. + cmd.cdw[11] = offset; // Offset (should be multiple of 4KB) + cmd.cdw[12] = fw_type; + + printf ("nvme_update_firmware: Writing NVMe firmware...\n"); + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} + +static void nvme_push_admin_cmd_firmware_activate(nvme_t *nvme, uint8_t fw_type) +{ + nvme_command_t cmd; + + //setup command + nvme_sq_init_cmd(nvme->admin_sq, &cmd); + + cmd.opc = NVME_ADMIN_FW_ACTIVATE; + cmd.cdw[10] = fw_type; + + printf ("nvme_update_firmware: Activating NVMe firmware...\n"); + nvme_sq_add_cmd(nvme->admin_sq, &cmd); +} +#endif + +static void nvme_push_io_cmd_read(nvme_t *nvme, uint32_t namespace, uint64_t *prp_list, uint64_t lba, uint16_t count) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->io_sq, &cmd); + + cmd.opc = NVME_IO_CMD_READ; + cmd.nsid = namespace; + // LPRP: Apple NVMe extension, says that the command targets a contiguous memory range + cmd.lprp = 1; + cmd.prp1 = prp_list[0]; + // Since we set LPRP, we don't need to set PRP2, but we're doing it anyway for + // compatibility with the DV environment, which doesn't know about LPRP mode + if (count == 1) + cmd.prp2 = 0; + else if (count == 2) + cmd.prp2 = prp_list[1]; + else + cmd.prp2 = nvme->prp_list_iovm_addr + sizeof(prp_list[0]); + cmd.cdw[10] = (uint32_t)lba; + cmd.cdw[11] = (uint32_t)(lba >> 32); + cmd.cdw[12] = count - 1; + + nvme_sq_add_cmd(nvme->io_sq, &cmd); +} + +#if NVME_WITH_NORMAL_MODE +void nvme_push_io_cmd_write(nvme_t *nvme, uint32_t namespace, uint64_t *prp_list, uint64_t lba, uint16_t count) +{ + nvme_command_t cmd; + + nvme_sq_init_cmd(nvme->io_sq, &cmd); + + cmd.opc = NVME_IO_CMD_WRITE; + // LPRP: Apple NVMe extension, says that the command targets a contiguous memory range + cmd.lprp = 1; + cmd.nsid = namespace; + cmd.prp1 = prp_list[0]; + // Since we set LPRP, we don't need to set PRP2, but we're doing it anyway for + // compatibility with the DV environment, which doesn't know about LPRP mode + if (count == 1) + cmd.prp2 = 0; + else if (count == 2) + cmd.prp2 = prp_list[1]; + else + cmd.prp2 = (uint64_t)&prp_list[1]; + cmd.cdw[10] = (uint32_t)lba; + cmd.cdw[11] = (uint32_t)(lba >> 32); + cmd.cdw[12] = count - 1; + + nvme_sq_add_cmd(nvme->io_sq, &cmd); +} +#endif + +static void nvme_init_sq(nvme_t *nvme, int queue_id, void *base, uint32_t elements, int cq_queue_id) +{ + nvme_sq_t *sq = &nvme->sq[queue_id]; + + ASSERT(elements * sizeof(nvme_command_t) < NVME_PAGE_SIZE); + + sq->queue_id = queue_id; + sq->commands = (nvme_command_t *)base; + sq->elements = elements; + sq->head = 0; + sq->tail = 0; + sq->cq = &nvme->cq[cq_queue_id]; + + sq->commands_iovm_addr = nvme_translate_bookkeeping(nvme, base); + + dprintf(DEBUG_SPEW, "nvme: submission queue 0x%x at host addr %p pci addr 0x%08llx\n", + queue_id, base, sq->commands_iovm_addr); +} + +static void nvme_init_cq(nvme_t *nvme, int queue_id, void *base, uint32_t elements) +{ + nvme_cq_t *cq = &nvme->cq[queue_id]; + + ASSERT(elements * sizeof(nvme_command_t) < NVME_PAGE_SIZE); + + cq->queue_id = queue_id; + cq->completions = (nvme_completion_t *)base; + cq->elements = elements; + cq->head = 0; + cq->tail = 0; + + cq->completions_iovm_addr = nvme_translate_bookkeeping(nvme, base); + + dprintf(DEBUG_SPEW, "nvme: completion queue 0x%x at host addr %p pci addr 0x%08llx\n", + queue_id, base, cq->completions_iovm_addr); +} + +static int nvme_wait_cq(nvme_t *nvme, nvme_cq_t *cq, utime_t timeout) +{ + int status; + utime_t start_time = system_time(); + uint16_t cmpl_sqid; + uint16_t cmpl_sqhead; + nvme_completion_t completion; + nvme_sq_t *sq; + volatile nvme_completion_t *head; + + head = CQ_HEAD(cq); + while (head->p == cq->phase) { + if (time_has_elapsed(start_time, timeout)) { + dump_completion(DEBUG_SPEW, (nvme_completion_t *)head); + if (cq->queue_id == ADMIN_QUEUE_ID) + status = NVME_ERR_ADMIN_CMD_TIMEOUT; + else + status = NVME_ERR_IO_CMD_TIMEOUT; + +#if (DEBUG_BUILD || DEVELOPMENT_BUILD) && !PRODUCT_IBEC + dprintf(DEBUG_INFO, "nvme: command timed out, triggering assertion\n"); + + // Grab the 0th dword of the outstanding command to write + // to the assert register on S3E. This assumes there's always + // a 1-1 mapping of completion queues to submission queues + // and that we operate with queue depth 1 (both good assumptions + // in iBoot) + nvme_sq_t *sq = &nvme->sq[cq->queue_id]; + uint32_t cmd_dw0 = sq->commands[sq->head].cdw[0]; + // Cause S3E to assert, passing it the failed command to help + // with debug + nvme_write_reg32(nvme, NVME_REG_S3E_TIMEOUT_DEBUG, cmd_dw0); + spin(1000); + // Read and log the assert ID to our serial console + nvme_update_error(nvme, status); + // Dump our submission/completion queues + platform_memory_barrier(); + dump_controller_state(DEBUG_INFO, nvme); + + panic("nvme: timeout waiting for completion on CQ %u at index %u\n", cq->queue_id, cq->head); +#else + dprintf(DEBUG_INFO, "nvme: timeout waiting for completion on CQ %u at index %u\n", cq->queue_id, cq->head); +#endif + + goto done; + } + spin(10); + } + + platform_memory_barrier(); + + // need to copy data out of DMA-visible buffer before validating it + memcpy(&completion, (void *)head, sizeof(completion)); + + if (DEBUG_LEVEL >= DEBUG_SPEW) { + dprintf(DEBUG_SPEW, "nvme: received completion on queue 0x%x at index 0x%x\n", + cq->queue_id, cq->head); + dump_completion(DEBUG_SPEW, &completion); + } + + status = -((head->sct << 8) | head->sc); + + cmpl_sqid = completion.sqid; + cmpl_sqhead = completion.sqhd; + + if (cmpl_sqid > NUM_QUEUES) { + status = NVME_ERR_INVALID_CMPL_SQID; + goto done; + } + sq = &nvme->sq[cmpl_sqid]; + + if (!sq->created) { + status = NVME_ERR_INVALID_CMPL_SQID; + goto done; + } + if (cmpl_sqhead > nvme->sq[cmpl_sqid].elements) { + status = NVME_ERR_INVALID_CMPL_SQHD; + goto done; + } + + nvme->sq[cmpl_sqid].head = cmpl_sqhead; + + if (completion.cid != sq->last_command_id) { + status = NVME_ERR_CMPL_CID_MISMATCH; + goto done; + } + +done: + nvme_update_error(nvme, status); + return status; +} + +static void nvme_pop_cq(nvme_t *nvme, nvme_cq_t *cq) +{ + cq->head++; + if (cq->head == cq->elements) { + cq->head = 0; + cq->phase ^= 1; + } +} + +static void nvme_ring_cq_doorbell(nvme_t *nvme, nvme_cq_t *cq) +{ + uint32_t doorbell = cq->queue_id * 2 + 1; + uint32_t value = cq->head; + uint32_t offset = NVME_REG_SQ0TDBL + (doorbell * nvme->doorbell_stride); + + nvme_write_reg32(nvme, offset, value); +} + +static void nvme_ring_sq_doorbell(nvme_t *nvme, nvme_sq_t *sq) +{ + uint32_t doorbell = sq->queue_id * 2; + uint32_t value = sq->tail; + uint32_t offset = NVME_REG_SQ0TDBL + (doorbell * nvme->doorbell_stride); + + ASSERT(sq->created); + + platform_memory_barrier(); + + nvme_write_reg32(nvme, offset, value); +} + +/* Rings the doorbell for the specified queue, and then waits for the + command to complete. Currently assumes that only a single command + is outstanding */ +static int nvme_wait_for_cmd(nvme_t *nvme, nvme_sq_t *sq, utime_t timeout) +{ + int status; + + nvme_ring_sq_doorbell(nvme, sq); + + status = nvme_wait_cq(nvme, sq->cq, timeout); + + // On timeout, there's nothing to pop from the CQ + if (status != NVME_ERR_IO_CMD_TIMEOUT && status != NVME_ERR_ADMIN_CMD_TIMEOUT) { + nvme_pop_cq(nvme, sq->cq); + nvme_ring_cq_doorbell(nvme, sq->cq); + } + + return status; +} + +static int nvme_create_sq(nvme_t *nvme, nvme_sq_t *sq) +{ + int status; + + ASSERT(sq->queue_id != ADMIN_QUEUE_ID); + ASSERT(!sq->created); + ASSERT(sq->cq->created); + + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + bzero(sq->commands, sizeof(*sq->commands) * sq->elements); + + nvme_push_admin_cmd_create_sq(nvme, sq); + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_ADMIN_TIMEOUT); + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: error %d creating SQ%u\n", status, sq->queue_id); + goto done; + } + + sq->created = true; + +done: + nvme_update_error(nvme, status); + return status; +} + +static int nvme_create_cq(nvme_t *nvme, nvme_cq_t *cq) +{ + int status; + + ASSERT(cq->queue_id != ADMIN_QUEUE_ID); + ASSERT(!cq->created); + + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + bzero(cq->completions, sizeof(*cq->completions) * cq->elements); + + nvme_push_admin_cmd_create_cq(nvme, cq); + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_ADMIN_TIMEOUT); + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: error %d creating CQ%u\n", status, cq->queue_id); + goto done; + } + + cq->created = true; + +done: + nvme_update_error(nvme, status); + return status; +} + +static int nvme_delete_sq(nvme_t *nvme, nvme_sq_t *sq) +{ + int status = NVME_SUCCESS; + + ASSERT(sq->queue_id != ADMIN_QUEUE_ID); + ASSERT(sq->created); + + // In boot mode, we don't send the delete queue command, but + // we still want to update our internal status (see done label) + // so that the switch to normal mode goes smoothly +#if NVME_WITH_NORMAL_MODE + if (nvme->mode != NVME_MODESEL_BOOT) { + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + nvme_push_admin_cmd_delete_sq(nvme, sq); + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_ADMIN_TIMEOUT); + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: error %d deleting SQ%u\n", status, sq->queue_id); + goto done; + } + } +#endif + + goto done; // shuts up compiler for !NVME_WITH_NORMAL_MODE +done: + sq->created = false; + sq->head = 0; + sq->tail = 0; + + nvme_update_error(nvme, status); + return status; +} + +static int nvme_delete_cq(nvme_t *nvme, nvme_cq_t *cq) +{ + int status = NVME_SUCCESS; + + ASSERT(cq->queue_id != ADMIN_QUEUE_ID); + ASSERT(cq->created); + + // In boot mode, we don't send the delete queue command, but + // we still want to update our internal status (see done label) + // so that the switch to normal mode goes smoothly +#if NVME_WITH_NORMAL_MODE + if (nvme->mode != NVME_MODESEL_BOOT) { + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + nvme_push_admin_cmd_delete_cq(nvme, cq); + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_ADMIN_TIMEOUT); + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: error %d deleting CQ%u\n", status, cq->queue_id); + goto done; + } + } +#endif + + goto done; // shuts up compiler for !NVME_WITH_NORMAL_MODE +done: + cq->created = false; + cq->head = 0; + cq->tail = 0; + cq->phase = 0; + + nvme_update_error(nvme, status); + return status; +} + +static int nvme_init_pci(nvme_t *nvme, pci_device_t bridge) +{ + int status; + uint32_t class_code; + uint64_t bar_size; + uintptr_t bar0; + pci_device_t pci_dev; + + // PCIe devices are always device 0 + nvme->bridge_dev = bridge; + pci_dev = pci_bridge_probe(bridge, 0, 100000); + if (pci_dev == NULL) { + dprintf(DEBUG_CRITICAL, "nvme: Probe of pci bridge \"%s\" failed.\n", pci_get_name(bridge)); + status = NVME_ERR_PROBE_FAILED; + goto done; + } + + class_code = pci_get_class_code(pci_dev); + if (class_code != NVME_APPLE_CLASS_CODE) { + dprintf(DEBUG_CRITICAL, "nvme: Found class code 0x%06x, expected 0x%06x\n", + class_code, NVME_APPLE_CLASS_CODE); + status = NVME_ERR_INVALID_CLASS_CODE; + goto done; + } + + bar_size = pci_get_bar_size(pci_dev, 0); + if (bar_size < NVME_APPLE_BAR0_SIZE) { + dprintf(DEBUG_CRITICAL, "nvme: BAR0 (size 0x%llx) not valid\n", bar_size); + status = NVME_ERR_INVALID_BAR; + goto done; + } + +#if !SUPPORT_FPGA +#if !APPLICATION_SECUREROM + pci_enable_pcie_aspm(pci_dev); +#endif +#if !SUB_PLATFORM_T7000 + pci_enable_pcie_ltr(pci_dev); +#if !APPLICATION_SECUREROM + pci_enable_pcie_l1ss(pci_dev); +#endif +#endif +#endif + + bar0 = pci_map_bar(pci_dev, 0); + nvme->reg_base = bar0; + + pci_memory_space_enable(pci_dev, true); + pci_bus_master_enable(pci_dev, true); + + nvme->pci_dev = pci_dev; + + dprintf(DEBUG_SPEW, "nvme: Revision ID 0x%02x\n", pci_get_revision_id(pci_dev)); + dprintf(DEBUG_SPEW, "nvme: BAR0 mapped at host addr 0x%010lx\n", bar0); + + status = NVME_SUCCESS; + +done: + if (status != NVME_SUCCESS && pci_dev != NULL) + pci_free(pci_dev); + + nvme_update_error(nvme, status); + return status; +} + +// Gathers resources that will remain around across +// boot mode to normal transitions +static int nvme_init_resources(nvme_t *nvme) +{ + nvme->bookkeeping_base = (uintptr_t)memalign(NVME_IOVM_BOOKKEEPING_SIZE, NVME_PAGE_SIZE); + nvme->bookkeeping_next = nvme->bookkeeping_base; + nvme->bookkeeping_limit = nvme->bookkeeping_base + NVME_IOVM_BOOKKEEPING_SIZE; + + bzero((void *)nvme->bookkeeping_base, NVME_IOVM_BOOKKEEPING_SIZE); + dart_map_page_range(nvme->dart_id, nvme->bookkeeping_base, + NVME_IOVM_BOOKKEEPING_BASE, NVME_IOVM_BOOKKEEPING_PAGES, false); + + dprintf(DEBUG_SPEW, "nvme: bookkeeping region from 0x%016lx to 0x%016lx\n", nvme->bookkeeping_base, nvme->bookkeeping_limit); + dprintf(DEBUG_SPEW, "nvme: mapped bookkeeping region to 0x%08x\n", NVME_IOVM_BOOKKEEPING_BASE); + + // We assume we only ever have one outstanding transaction, so we only need one + // command's worth of PRPs, which we round up to a single page of PRPs + nvme->prp_list = nvme_get_bookkeeping_pages(nvme, 1); + nvme->prp_list_iovm_addr = nvme_translate_bookkeeping(nvme, nvme->prp_list); + //dart_write_protect_page_range(nvme->dart_id, nvme->prp_list_iovm_addr, 1, true); + + nvme->identify_buffer = nvme_get_bookkeeping_pages(nvme, 1); + + for (int i = 0; i < NUM_QUEUES; i++ ) { + nvme_init_cq(nvme, i, nvme_get_bookkeeping_pages(nvme, 1), QUEUE_ENTRIES); + nvme_init_sq(nvme, i, nvme_get_bookkeeping_pages(nvme, 1), QUEUE_ENTRIES, i); + } + + nvme->admin_sq = &nvme->sq[ADMIN_QUEUE_ID]; + nvme->io_sq = &nvme->sq[IO_QUEUE_ID]; + + return NVME_SUCCESS; +} + +#if NVME_WITH_NORMAL_MODE +static int nvme_setup_scratch_buffer(nvme_t *nvme) +{ + static bool scratch_used = false; + uintptr_t scratch_base; + size_t scratch_size; + uint32_t scratch_size_request; + uint32_t scratch_align_request; + uint64_t scratch_iovm_base; + + // Slightly hackish, but will do until we really need to support + // more than one NVMe controller at once + if (scratch_used) + panic("NVMe driver only supports scratch buffer for a single device"); + scratch_used = true; + + scratch_base = platform_get_memory_region_base(kMemoryRegion_StorageProcessor); + scratch_size = platform_get_memory_region_size(kMemoryRegion_StorageProcessor); + + bzero((void *)scratch_base, scratch_size); + + scratch_size_request = nvme_read_reg32(nvme, NVME_REG_DDRREQSIZE); + if (!nvme_check_reg_valid32(scratch_size_request)) + return NVME_ERR_INVALID_REG; + + scratch_align_request = nvme_read_reg32(nvme, NVME_REG_DDRREQALIGN); + if (!nvme_check_reg_valid32(scratch_align_request)) + return NVME_ERR_INVALID_REG; + + if (scratch_size_request == 0) + return NVME_SUCCESS; + + // Round requested size up to the page size, just in case + if ((scratch_size_request & (NVME_PAGE_SIZE - 1)) != 0) + scratch_size_request = (scratch_size_request + (NVME_PAGE_SIZE - 1)) & (NVME_PAGE_SIZE - 1); + + // We're going to require the alignment to be a power of 2 + if ((scratch_align_request & (scratch_align_request - 1)) != 0) + return NVME_ERR_INVALID_DDRREQALIGN; + + // We're also going to require the alignment to be smaller than the size + // we've allocated for the scratch region + if (scratch_align_request > scratch_size) + return NVME_ERR_INVALID_DDRREQALIGN; + + if (scratch_size_request > scratch_size) + return NVME_ERR_INVALID_DDRREQSIZE; + + // Put everything at the top of the pre-allocated region in PCI address space, respecting + // the alignment request + // NOTE: Right now we're giving all of the memory we have available. We could also give + // just as much as requested, and reclaim the rest of the memory + // NOTE 2: Assuming NVME_IOVM_SCRATCH_END isn't weirdly aligned (should normally be on a GB boundary) + scratch_iovm_base = NVME_IOVM_SCRATCH_END - __max(scratch_size, scratch_align_request); + + // Make sure that nothing pathological happened + if ((scratch_iovm_base & (scratch_align_request - 1)) != 0) + return NVME_ERR_INVALID_DDRREQALIGN; + if (scratch_iovm_base < (NVME_IOVM_IO_BASE + NVME_IOVM_IO_SIZE)) + return NVME_ERR_INVALID_DDRREQSIZE; + + dart_map_page_range(nvme->dart_id, scratch_base, scratch_iovm_base, scratch_size / NVME_PAGE_SIZE, false); + + nvme->scratch_iovm_base = scratch_iovm_base; + nvme->scratch_size = scratch_size; + + dprintf(DEBUG_SPEW, "nvme: scratch host/virt/size %p/0x%llx/0x%zx\n", (void *)scratch_base, scratch_iovm_base, scratch_size); + + nvme_write_reg64(nvme, NVME_REG_DDRBASE, scratch_iovm_base); + nvme_write_reg32(nvme, NVME_REG_DDRSIZE, scratch_size); + + return NVME_SUCCESS; +} +#endif + +static int nvme_set_enable(nvme_t *nvme, bool enable) +{ + utime_t start; + uint32_t cc; + uint32_t csts; + int status; + bool timeout; + + start = system_time(); + + cc = nvme_read_reg32(nvme, NVME_REG_CC); + if (!nvme_check_reg_valid32(cc)) { + status = NVME_ERR_INVALID_REG; + goto done; + } + + if (enable) { + cc |= NVME_CC_EN; + } else { + cc &= ~NVME_CC_EN; + } + + nvme_write_reg32(nvme, NVME_REG_CC, cc); + + while (1) { + if (enable) { +#if NVME_WITH_NORMAL_MODE + if (nvme->mode != NVME_MODESEL_BOOT) + timeout = time_has_elapsed(start, NVME_NORMAL_CONTROLLER_ENABLE_TIMEOUT); + else +#endif + timeout = time_has_elapsed(start, NVME_BOOT_CONTROLLER_ENABLE_TIMEOUT); + } else { + timeout = time_has_elapsed(start, NVME_CONTROLLER_DISABLE_TIMEOUT); + } + + csts = nvme_read_reg32(nvme, NVME_REG_CSTS); + if (!nvme_check_reg_valid32(csts)) { + status = NVME_ERR_INVALID_REG; + goto done; + } + + if (enable) { + if ((csts & NVME_CSTS_RDY) != 0) + break; + + if (timeout) { + dprintf(DEBUG_CRITICAL, "nvme: timeout enabling controller\n"); + status = NVME_ERR_ENABLE_TIMEOUT; + goto done; + } + } else { + if ((csts & NVME_CSTS_RDY) == 0) + break; + + if (timeout) { + dprintf(DEBUG_CRITICAL, "nvme: timeout disabling controller\n"); + status = NVME_ERR_DISABLE_TIMEOUT; + goto done; + } + } + spin(1000); + } + + status = NVME_SUCCESS; + +done: + nvme_update_error(nvme, status); + return status; +} + +static void nvme_quiesce_pci(nvme_t *nvme) +{ + pci_memory_space_enable(nvme->pci_dev, false); + pci_bus_master_enable(nvme->pci_dev, false); + + // Place the PCI device into D3-hot + pci_set_powerstate(nvme->pci_dev, 3); + + pci_free(nvme->pci_dev); + + nvme->pci_dev = NULL; +} + +static int nvme_quiesce_controller(nvme_t *nvme) +{ + int status = NVME_SUCCESS; + + if (nvme->enabled) { + // Before sending the shutdown command, we need to delete any non-admin + // queues that were created. We can only do this if we didn't previously + // run into an issue with the admin queue + // If there was a timeout on an IO queue, it's likely the delete queue + // command will fail. That's fine, we'll just keep going in that case. + // If this ever becomes an issue, we can try aborting the outstanding + // IO command before doing the delete queues commands + if (nvme->io_sq->created) { + status = nvme_delete_sq(nvme, nvme->io_sq); + nvme_update_error(nvme, status); + } + + // completion queues can't be deleted until after associated + // submission queue is deleted + if (nvme->io_sq->cq->created) { + status = nvme_delete_cq(nvme, nvme->io_sq->cq); + nvme_update_error(nvme, status); + } + +#if NVME_WITH_NORMAL_MODE + if ( (nvme->mode != NVME_MODESEL_BOOT) && (nvme_get_hard_error(nvme) == NVME_SUCCESS) ) { + uint32_t cc; + uint32_t csts; + utime_t start; + + start = system_time(); + + cc = nvme_read_reg32 (nvme, NVME_REG_CC); + cc &= ~(NVME_CC_SHN_NORMAL | NVME_CC_SHN_ABRUPT); + cc |= NVME_CC_SHN_NORMAL; + nvme_write_reg32(nvme, NVME_REG_CC, cc); + + // Poll for shutdown complete. + while ((nvme_read_reg32(nvme, NVME_REG_CSTS) & NVME_CSTS_SHST_MASK) != NVME_CSTS_SHST_DONE) { + if (time_has_elapsed(start, NVME_CONTROLLER_SHUTDOWN_TIMEOUT)) { + csts = nvme_read_reg32(nvme, NVME_REG_CSTS); + dprintf(DEBUG_CRITICAL, "nvme: timeout shutting down controller, csts 0x%08x\n", csts); + status = NVME_ERR_SHUTDOWN_TIMEOUT; + break; + } + spin(1000); + } + } +#endif + + nvme_set_enable(nvme, false); + + nvme->enabled = false; + } + +#if NVME_WITH_NORMAL_MODE + // Reset the mode variable + nvme->mode = NVME_MODESEL_MAX; +#endif + + nvme_update_error(nvme, status); + return status; +} + + +// Validates that the controller's capabilities are consistent with NVMe for iOS section 6.2 +static int nvme_parse_cap(nvme_t *nvme) +{ + int status; + uint64_t cap; + uint32_t dstrd; + uint32_t mpsmin; + uint32_t mqes; + + cap = nvme_read_reg64(nvme, NVME_REG_CAP); + if (!nvme_check_reg_valid64(cap)) { + status = NVME_ERR_INVALID_REG; + goto error; + } + + dprintf(DEBUG_SPEW, "nvme: CAP = 0x%016llx\n", cap); + + dstrd = (cap >> 32) & 0xf; + if (dstrd > 7) { + status = NVME_ERR_INVALID_DSTRD; + goto error; + } + nvme->doorbell_stride = 1 << (2 + dstrd); + + mpsmin = (cap >> 48) & 0xf; + if (mpsmin != 0) { + status = NVME_ERR_INVALID_MPSMIN; + goto error; + } + + mqes = (cap >> 0) & 0xffff; + if (mqes < QUEUE_ENTRIES - 1) { + status = NVME_ERR_INVALID_MQES; + goto error; + } + + return NVME_SUCCESS; + +error: + nvme_update_error(nvme, status); + dprintf(DEBUG_CRITICAL, "nvme: error %d validating CAP register\n", status); + return status; +} + +static void nvme_identify_build_vendor_specific_string(NVMeIdentifyControllerStruct *identify_result) +{ +#if NVME_WITH_NORMAL_MODE + + if (identify_result->S3_CHIP_ID < NVME_CHIP_NUM_ID) + dprintf(DEBUG_CRITICAL, "nvme: %s ", NVME_CHIP_STRINGS[identify_result->S3_CHIP_ID]); + else + dprintf(DEBUG_CRITICAL, "nvme: Model Unknown "); + + dprintf(DEBUG_CRITICAL, "%X ", ( 0xA0 + identify_result->S3_CHIP_REVISION)); + + if (NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceVendorMask, NANDDeviceVendorOffset) < NVME_NAND_NUM_VENDORS) + dprintf(DEBUG_CRITICAL, "%s ", NVME_VENDOR_STRINGS[NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceVendorMask, NANDDeviceVendorOffset)]); + else + dprintf(DEBUG_CRITICAL, "Vendor Unknown "); + + if (NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceLithographyMask, NANDDeviceLithographyOffset) < NVME_NAND_NUM_LITHOS) + dprintf(DEBUG_CRITICAL, "%s ", NVME_LITHOGRAPHY_STRINGS[NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceLithographyMask, NANDDeviceLithographyOffset)]); + else + dprintf(DEBUG_CRITICAL, "Lithography Unknown "); + + if (NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceDensityMask, NANDDeviceDensityOffset) < NVME_NAND_NUM_DENSITIES) + dprintf(DEBUG_CRITICAL, "%s ", NVME_DENSITY_STRINGS[NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceDensityMask, NANDDeviceDensityOffset)]); + else + dprintf(DEBUG_CRITICAL, "Density Unknown "); + + if (NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceTechnologyMask, NANDDeviceTechnologyOffset) < NVME_NAND_NUM_DIMENSIONS) + dprintf(DEBUG_CRITICAL, "%s ", NVME_DIMENSIONS_STRINGS[NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceTechnologyMask, NANDDeviceTechnologyOffset)]); + else + dprintf(DEBUG_CRITICAL, "Dimension Unknown "); + + dprintf(DEBUG_CRITICAL, "%d plane %dGB ", + (2 << (NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceNumPlanesMask, NANDDeviceNumPlanesOffset) - 1)), + identify_result->SSD_CAPACITY); + + if (NVME_GET_BIT_FIELD_VALUE(identify_result->S3_DEVICE_DESCRIPTOR, NANDDeviceVendorMask, NANDDeviceVendorOffset) == NVME_NAND_DEVICE_HYNIX) + { + dprintf(DEBUG_CRITICAL, "%s Die ", NVME_CHIP_DIE_STRINGS[NVME_GET_BIT_FIELD_VALUE ( identify_result->S3_ECC_VERSION_NAND_REVISION, NANDDeviceNANDVersionMask, NANDDeviceNANDVersionOffset )] ); + } + + dprintf(DEBUG_CRITICAL, "NAND\n" ); + +#endif +} + +static int nvme_identify_controller(nvme_t *nvme) +{ +#if NVME_WITH_NORMAL_MODE + NVMeIdentifyControllerStruct *identify_result = NULL; + uint64_t iovm_addr; + uint8_t mdts; + int status; + char buildString[kNVMeIdentifyControllerBuildTrainLen+1] = {0}; + + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + iovm_addr = nvme_translate_bookkeeping(nvme, nvme->identify_buffer); + + nvme_push_admin_cmd_identify_controller(nvme, iovm_addr); + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_ADMIN_TIMEOUT); + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: identify controller failed\n"); + goto done; + } + + identify_result = malloc(sizeof(*identify_result)); + memcpy(identify_result, nvme->identify_buffer, sizeof(*identify_result)); + + nvme->vendor_id = identify_result->PCI_VID; + memcpy(nvme->serial_number, identify_result->SERIAL_NUMBER, sizeof(nvme->serial_number) - 1); + memcpy(nvme->model_number, identify_result->MODEL_NUMBER, sizeof(nvme->model_number) - 1); + memcpy(nvme->firmware_revision, identify_result->FW_REVISION, sizeof(nvme->firmware_revision) - 1); + nvme->serial_number[sizeof(nvme->serial_number) - 1] = 0; + nvme->model_number[sizeof(nvme->model_number) - 1] = 0; + nvme->firmware_revision[sizeof(nvme->firmware_revision) - 1] = 0; + + dprintf(DEBUG_INFO, "nvme: identified controller\n"); + dprintf(DEBUG_INFO, "nvme: Vendor ID: 0x%04x\n", nvme->vendor_id); + nvme_identify_build_vendor_specific_string(identify_result); + dprintf(DEBUG_CRITICAL, "nvme: Model Number: %s\n", nvme->model_number); + dprintf(DEBUG_CRITICAL, "nvme: Serial Number: %s\n", nvme->serial_number); + dprintf(DEBUG_CRITICAL, "nvme: Firmware Rev: %s\n", nvme->firmware_revision); + dprintf(DEBUG_CRITICAL, "nvme: chip hw/rev: 0x%02x/0x%02x\n", identify_result->S3_CHIP_ID, identify_result->S3_CHIP_REVISION); + dprintf(DEBUG_CRITICAL, "nvme: nand device: %04x\n", identify_result->S3_DEVICE_DESCRIPTOR); + dprintf(DEBUG_CRITICAL, "nvme: FTL ver: %d.%d\n", identify_result->S3_FTL_MAJOR_VERSION, identify_result->S3_FTL_MINOR_VERSION); + dprintf(DEBUG_CRITICAL, "nvme: MSP/DM vers: %d/%d\n", identify_result->S3_ECC_VERSION_NAND_REVISION, identify_result->S3_DM_VERSION); + + // Get the ASP build string from the vendor specific portion of the identify data. + memcpy(buildString, identify_result->ASP_BUILD_TRAIN, kNVMeIdentifyControllerBuildTrainLen); + dprintf(DEBUG_CRITICAL, "nvme: ASP_BUILD_TRAIN: %s\n", buildString); + + // Probably not necessary, but avoid artifacts ... + bzero (buildString, kNVMeIdentifyControllerBuildTrainLen); + + // Get the MSP build string from the vendor specific portion of the identify data. + memcpy(buildString, identify_result->MSP_BUILD_TRAIN, kNVMeIdentifyControllerBuildTrainLen); + dprintf(DEBUG_CRITICAL, "nvme: MSP_BUILD_TRAIN: %s\n", buildString); + + if (((identify_result->SQ_ENTRY_SIZE & 0xf) > 6) || ((identify_result->SQ_ENTRY_SIZE >> 4) < 6)) { + status = NVME_ERR_INVALID_SQES; + goto done; + } + if (((identify_result->CQ_ENTRY_SIZE & 0xf) > 4) || ((identify_result->CQ_ENTRY_SIZE >> 4) < 4)) { + status = NVME_ERR_INVALID_CQES; + goto done; + } + + mdts = identify_result->MAX_DATA_TRANSFER_SIZE; + if (mdts > 31 || (1 << mdts) > MAX_TRANSFER_BLOCKS) + nvme->max_transfer_blocks = MAX_TRANSFER_BLOCKS; + else + nvme->max_transfer_blocks = 1 << mdts; + + nvme->num_namespaces = identify_result->NUMBER_OF_NAMESPACES; + + status = NVME_SUCCESS; + +done: + if (identify_result != NULL) + free(identify_result); + nvme_update_error(nvme, status); + return status; +#else + nvme->max_transfer_blocks = NVME_BOOT_MAX_TRANSFER_BLOCKS; + nvme->num_namespaces = 6; + + return NVME_SUCCESS; +#endif +} + +static int nvme_init_controller(nvme_t *nvme, uint8_t mode) +{ + uint32_t cc; + int status; + nvme_sq_t *admin_sq; + nvme_cq_t *admin_cq; + + ASSERT(mode < NVME_MODESEL_MAX); + +#if !NVME_WITH_NORMAL_MODE + ASSERT( mode == NVME_MODESEL_BOOT); +#endif + + status = nvme_set_enable(nvme, false); + if (status != NVME_SUCCESS) + goto error; + +#if NVME_WITH_NORMAL_MODE + nvme->mode = mode; + + if (nvme->mode != NVME_MODESEL_BOOT) { + status = nvme_setup_scratch_buffer(nvme); + if (status != NVME_SUCCESS) + goto error; + } +#endif + + status = nvme_parse_cap(nvme); + if (status != NVME_SUCCESS) + goto error; + + admin_sq = nvme->admin_sq; + admin_cq = admin_sq->cq; + + // clean up internal house-keeping if this is our second time through + // the init when switching to normal mode + admin_sq->head = 0; + admin_sq->tail = 0; + admin_sq->cq->head = 0; + admin_sq->cq->tail = 0; + // and make sure there aren't old commands or completions hanging around + bzero(admin_sq->commands, sizeof(*admin_sq->commands) * admin_sq->elements); + bzero(admin_cq->completions, sizeof(*admin_cq->completions) * admin_cq->elements); + + nvme_write_reg32(nvme, NVME_REG_AQA, ((admin_cq->elements - 1) << 16) | (admin_sq->elements - 1)); + nvme_write_reg64(nvme, NVME_REG_ACQ, admin_cq->completions_iovm_addr); + nvme_write_reg64(nvme, NVME_REG_ASQ, admin_sq->commands_iovm_addr); + + // no explicit command is needed to create the admin queues, + // other than the writes to the ACQ and ASQ registers + admin_cq->created = true; + admin_sq->created = true; + + nvme_write_reg32(nvme, NVME_REG_MODESEL, mode); + + cc = NVME_CC_MPS(0) + | NVME_CC_IOSQES(6) + | NVME_CC_IOCQES(4); + nvme_write_reg32(nvme, NVME_REG_CC, cc); + + status = nvme_set_enable(nvme, true); + if (status != NVME_SUCCESS) { + goto error; + } + + nvme->enabled = true; + + if (!nvme->identified) { + status = nvme_identify_controller(nvme); + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "Error %d on identify controller command", status); + goto error; + } + nvme->identified = true; + } + + status = nvme_create_cq(nvme, nvme->io_sq->cq); + if (status != NVME_SUCCESS) + goto error; + + status = nvme_create_sq(nvme, nvme->io_sq); + if (status != NVME_SUCCESS) + goto error; + + return NVME_SUCCESS; + +error: + nvme_quiesce_controller(nvme); + + return status; +} + +#if NVME_WITH_NORMAL_MODE +static int nvme_switch_to_mode(nvme_t *nvme, uint8_t mode) +{ + int status; + + ASSERT(mode < NVME_MODESEL_MAX); + + // Allow only these transitions: + // 1. Boot mode to any other mode + // 2. Normal mode to normal mode + // 3. Readonly mode to readonly and normal mode + if ( (nvme->mode == NVME_MODESEL_BOOT) || ( (nvme->mode == NVME_MODESEL_NORMAL) && (mode == NVME_MODESEL_NORMAL) ) || ((nvme->mode == NVME_MODESEL_READONLY) && ( (mode == NVME_MODESEL_NORMAL) || (mode == NVME_MODESEL_READONLY))) ) { + dprintf(DEBUG_INFO,"nvme: transition from %02x to %02x mode\n", nvme->mode, mode); + } else { + panic("nvme: trying to do transition from %02x to %02x mode\n", nvme->mode, mode); + } + + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + // Return if already in the new mode + if (nvme->mode == mode) + return NVME_SUCCESS; + + // We need to do a whole bunch of teardown, because switching to + // normal mode involves set CC.EN = 0, which resets a lot state + // on the controller + status = nvme_quiesce_controller(nvme); + if (status != NVME_SUCCESS) + goto done; + + // Now re-enable in new mode + status = nvme_init_controller(nvme, mode); + if (status != NVME_SUCCESS) + goto done; + + // We just publushed the boot mode bdevs in nvme_init, so + // publish all other bdevs here. This will also scan for + // partitions on the mass storage namespace + if (mode != NVME_MODESEL_RECOVERY) + nvme_blockdev_init_normal(nvme->id); + +done: + nvme_update_error(nvme, status); + + return status; +} +#endif + + +static nvme_t nvme_controllers[2]; + +static nvme_t *get_nvme_controller(int nvme_id) +{ + + if ((size_t)nvme_id > sizeof(nvme_controllers) / sizeof(nvme_controllers[0])) + panic("Invalid NVMe controller ID %d", nvme_id); + + return &nvme_controllers[nvme_id]; +} + +int nvme_init(int nvme_id, pci_device_t bridge, uint32_t dart_id) +{ + nvme_t *nvme; + int status; + + dprintf(DEBUG_CRITICAL, "nvme: initializing controller %d\n", nvme_id); + + nvme = get_nvme_controller(nvme_id); + + nvme->id = nvme_id; + + // no backsies + ASSERT(!nvme->initialized); + + status = nvme_init_pci(nvme, bridge); + if (status != NVME_SUCCESS) + goto error; + + nvme->initialized = true; + nvme->dart_id = dart_id; + + status = nvme_init_resources(nvme); + if (status != NVME_SUCCESS) + goto error; + + // start out in boot mode + status = nvme_init_controller(nvme, NVME_MODESEL_BOOT); + if (status != NVME_SUCCESS) + goto error; + + nvme_blockdev_init_boot(nvme_id); + + return NVME_SUCCESS; + +error: + dprintf(DEBUG_INFO, "nvme: init failed with status %d\n", status); + nvme_quiesce(nvme_id); + return status; +} + +void nvme_quiesce(int nvme_id) +{ + nvme_t *nvme = get_nvme_controller(nvme_id); + + // We might get asked to quiesce without an enable in the case of SecureROM + // trying to power off the controller even though it wasn't detected on the bus + if (nvme->pci_dev != NULL) { + nvme_quiesce_controller(nvme); + nvme_quiesce_pci(nvme); + dart_disable_translation(nvme->dart_id); + } + + if (nvme->bookkeeping_base != 0) { + dart_unmap_page_range(nvme->dart_id, NVME_IOVM_BOOKKEEPING_BASE, NVME_IOVM_BOOKKEEPING_PAGES); + free((void *)nvme->bookkeeping_base); + nvme->bookkeeping_base = 0; + } + +#if NVME_WITH_NORMAL_MODE + if (nvme->scratch_iovm_base != 0) { + dart_unmap_page_range(nvme->dart_id, nvme->scratch_iovm_base, nvme->scratch_size / NVME_PAGE_SIZE); + nvme->scratch_iovm_base = 0; + nvme->scratch_size = 0; + } +#endif +} + +void nvme_quiesce_all(void) +{ + unsigned int i; + for (i = 0; i < sizeof(nvme_controllers) / sizeof(nvme_controllers[0]); i++) + nvme_quiesce(i); +} + +#if NVME_WITH_NORMAL_MODE +int nvme_flush_namespace(int nvme_id, uint32_t namespace) +{ + nvme_t *nvme = get_nvme_controller(nvme_id); + nvme_command_t cmd; + int status; + + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + nvme_sq_init_cmd(nvme->io_sq, &cmd); + + cmd.opc = NVME_IO_CMD_FLUSH; + cmd.nsid = namespace; + // LPRP: Apple NVMe extension, says that the command targets a contiguous memory range + cmd.lprp = 1; + + nvme_sq_add_cmd(nvme->io_sq, &cmd); + + status = nvme_wait_for_cmd(nvme, nvme->io_sq, NVME_NORMAL_IO_TIMEOUT); + +done: + nvme_update_error(nvme, status); + return status; +} +#endif + +static int nvme_do_io(int nvme_id, uint32_t namespace, void *ptr, uint32_t block, uint32_t count, bool write) +{ + nvme_t *nvme = get_nvme_controller(nvme_id); + int status; + utime_t timeout; + + RELEASE_ASSERT(((uintptr_t)ptr & (NVME_PAGE_SIZE - 1)) == 0); + RELEASE_ASSERT(count > 0 && count <= nvme->max_transfer_blocks); + + if (!nvme->enabled) { + dprintf(DEBUG_CRITICAL, "nvme: controller offline, aborting IO\n"); + return 0; + } + + if (nvme_get_hard_error(nvme) != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: previous fatal error, aborting IO\n"); + return 0; + } + + // NOTE: Securing against attackers accessing past the end of the buffer relies on the + // assumption that the NVMe block size, the NVMe page size, and the DART page size are all equal + // If this assumption ever changes, nvme_blockdev.c and lib/blockdev.c will need to be audited to + // make sure that we still secure against this + dart_map_page_range(nvme->dart_id, (uintptr_t)ptr, NVME_IOVM_IO_BASE, count, write); + + for (uint32_t i = 0; i < count; i++) + nvme->prp_list[i] = NVME_IOVM_IO_BASE + i * NVME_PAGE_SIZE; + + + if (write) { + // boot mode is read-only +#if NVME_WITH_NORMAL_MODE + ASSERT(nvme->mode != NVME_MODESEL_BOOT); + + if (namespace != EmbeddedNamespaceTypeRoot) + { + status = nvme_flush_namespace(nvme_id, namespace); + if (status != NVME_SUCCESS) + goto done; + } + + nvme_push_io_cmd_write(nvme, namespace, nvme->prp_list, block, count); +#else + ASSERT(0); +#endif + } else { + nvme_push_io_cmd_read(nvme, namespace, nvme->prp_list, block, count); + } + + // boot mode official timeout is 30 ms per block, we'll pad + // it a little just to be on the safe side what with it + // going into ROM +#if NVME_WITH_NORMAL_MODE + if (nvme->mode != NVME_MODESEL_BOOT) + timeout = NVME_NORMAL_IO_TIMEOUT; + else +#endif + timeout = count * NVME_BOOT_IO_TIME_PER_LBA + (100 * 1000); + + status = nvme_wait_for_cmd(nvme, nvme->io_sq, timeout); + if (status != NVME_SUCCESS) + goto done; + +#if NVME_WITH_NORMAL_MODE + if (write && (namespace != EmbeddedNamespaceTypeRoot)) + { + status = nvme_flush_namespace(nvme_id, namespace); + if (status != NVME_SUCCESS) + goto done; + + } +#endif + +done: + dart_unmap_page_range(nvme->dart_id, NVME_IOVM_IO_BASE, count); + + nvme_update_error(nvme, status); + + if (status == NVME_SUCCESS) { + return count; + } else { + dprintf(DEBUG_CRITICAL, "nvme: error %d %s %u blocks at LBA %u of nsid %u\n", + status, write ? "writing" : "reading", count, block, namespace); + return 0; + } +} + +int nvme_read_blocks(int nvme_id, uint32_t namespace, void *ptr, uint32_t block, uint32_t count) +{ + return nvme_do_io(nvme_id, namespace, ptr, block, count, false); +} + +int nvme_write_blocks(int nvme_id, uint32_t namespace, const void *ptr, uint32_t block, uint32_t count) +{ + return nvme_do_io(nvme_id, namespace, (void *)ptr, block, count, true); +} + +#if WITH_DEVICETREE +void nvme_update_devicetree (int nvme_id, dt_node_t *node) +{ + nvme_t *nvme = get_nvme_controller(nvme_id); + uint8_t value = 0; + + if (nvme == NULL) + { + dprintf(DEBUG_CRITICAL, "nvme: unable to find a valid nvme device for id %d\n", nvme_id); + return; + } + + if (node == NULL) + { + dprintf(DEBUG_CRITICAL, "nvme: s3e node is NULL\n"); + return; + } + + value = nvme->num_namespaces; + + if (nvme->num_namespaces >= 1) + { + dt_set_prop(node, "namespaces-present", (void * )(&value), 1); + dprintf(DEBUG_CRITICAL, "nvme: setting namespaces-present property %d\n", nvme->num_namespaces); + } + +#if PRODUCT_IBEC + value = 1; + dt_set_prop(node, "ibec-boot", (void * )(&value), 1); +#endif +} +#endif + +int nvme_identify_namespace(int nvme_id, uint32_t nsid, nvme_namespace_params_t *params_out) +{ + nvme_t *nvme = get_nvme_controller(nvme_id); + nvme_identify_namespace_t *identify_result = NULL; + uint64_t iovm_addr; + int status; + int lba_format; + uint32_t block_size; + + status = nvme_get_hard_error(nvme); + if (status != NVME_SUCCESS) + goto done; + + if ( nvme->num_namespaces < nsid ) + { + dprintf(DEBUG_CRITICAL, "nvme: nsid=%u not present\n", nsid); + return NVME_ERR_NOT_ENABLED; + } + + iovm_addr = nvme_translate_bookkeeping(nvme, nvme->identify_buffer); + + nvme_push_admin_cmd_identify_namespace(nvme, nsid, iovm_addr); + + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_ADMIN_TIMEOUT); + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: identify nsid=%u failed status=%d\n", nsid, status); + return status; + } + + identify_result = malloc(sizeof(*identify_result)); + memcpy(identify_result, nvme->identify_buffer, sizeof(*identify_result)); + + dprintf(DEBUG_SPEW, "nvme: identify nsid=%u buffer=%p", nsid, identify_result); + + if (identify_result->ncap == 0 || identify_result->nsze == 0) { + params_out->formatted = false; + dprintf(DEBUG_SPEW, " formatted=FALSE\n"); + } else { + lba_format = identify_result->flbas & 0xf; + + block_size = 1 << identify_result->lbaf[lba_format].lbads; + // XXX: Obviously this is silly, but there are all + // kinds of assumptions about block size == page size right now + if (block_size != NVME_BLOCK_SIZE) { + dprintf(DEBUG_SPEW, "\n"); + dprintf(DEBUG_CRITICAL, "nvme: unsupported block size %u in namesapce %u", block_size, nsid); + params_out->formatted = false; + goto done; + } + + if (identify_result->lbaf[lba_format].ms != 0) { + dprintf(DEBUG_SPEW, "\n"); + dprintf(DEBUG_CRITICAL, "nvme: unsupported metadata size %u in namesapce %u", + identify_result->lbaf[lba_format].ms, nsid); + params_out->formatted = false; + goto done; + } + + params_out->formatted = true; + params_out->num_blocks = identify_result->nsze; + params_out->block_size = block_size; + dprintf(DEBUG_SPEW, " formatted=TRUE block_size=0x%x blocks=0x%llx\n", + block_size, identify_result->nsze); + } + +done: + if (identify_result != NULL) + free(identify_result); + + // unlike most other commands, identify failures can be non-fatal, for example if + // a particular namespace isn't present. + return nvme_get_hard_error(nvme); +} + +uint32_t nvme_get_max_transfer_blocks(int nvme_id) +{ + nvme_t *nvme = get_nvme_controller(nvme_id); + + return nvme->max_transfer_blocks; +} + +#if NVME_WITH_NORMAL_MODE +int nvme_init_mass_storage(int nvme_id) +{ + int status; + nvme_t *nvme; + + nvme = get_nvme_controller(nvme_id); + + if (!nvme->enabled) { + status = NVME_ERR_NOT_ENABLED; + goto done; + } + + status = nvme_switch_to_mode(nvme, NVME_MODESEL_READONLY); + if (status != NVME_SUCCESS) + goto done; + +done: + return status; +} + +int nvme_init_mass_storage_panic(int nvme_id) +{ + + int status; + nvme_t *nvme; + + nvme = get_nvme_controller(nvme_id); + + if (!nvme->enabled) { + status = NVME_ERR_NOT_ENABLED; + goto done; + } + + status = nvme_switch_to_mode(nvme, NVME_MODESEL_RECOVERY); + if (status != NVME_SUCCESS) + goto done; + +done: + + return status; +} +#endif + +#if !RELEASE_BUILD && WITH_MENU +int nvme_update_firmware(int nvme_id, const void *fw_buffer, size_t fw_length) +{ + int err = -1; + void *fw_buffer_aligned = NULL; + uint32_t fw_buffer_aligned_length = fw_length; + uint32_t count = fw_length / NVME_PAGE_SIZE; + uint32_t num_dwords = 0; + nvme_t *nvme; + int status; + + dprintf(DEBUG_INFO, "nvme_update_firmware: fw_buffer %p fw_length %zu count %u\n", fw_buffer, fw_length, count); + + nvme = get_nvme_controller(nvme_id); + + if (!nvme->enabled) { + dprintf(DEBUG_CRITICAL, "nvme: controller offline, aborting IO\n"); + return -1; + } + + if (nvme_get_hard_error(nvme) != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: previous fatal error, aborting IO\n"); + return -1; + } + + // If FW length is not a multiple of 4k then, + // adjust aligned buffer length to the next higher multiple of 4k + if (fw_buffer_aligned_length & (NVME_FW_DOWNLOAD_MIN_LENGTH - 1)) + { + count = ((((fw_buffer_aligned_length / NVME_FW_DOWNLOAD_MIN_LENGTH) + 1) * NVME_FW_DOWNLOAD_MIN_LENGTH) / NVME_PAGE_SIZE); + fw_buffer_aligned_length = count * NVME_PAGE_SIZE; + dprintf(DEBUG_INFO, "nvme_update_firmware: fw_length not a multiple of 4KB. adjusting length to %d. num pages is now %d\n", fw_buffer_aligned_length, count); + } + + if (count > nvme->max_transfer_blocks) { + dprintf(DEBUG_CRITICAL, "nvme_update_firmware: fw_length exceeds max transfer size. aborting update.\n"); + return -1; + } + + //allocate buffer + fw_buffer_aligned = memalign(fw_buffer_aligned_length, NVME_PAGE_SIZE); + bzero(fw_buffer_aligned,fw_buffer_aligned_length); + memcpy(fw_buffer_aligned, fw_buffer, fw_length); + + //map buffer + dart_map_page_range(nvme->dart_id, (uintptr_t)fw_buffer_aligned, NVME_IOVM_IO_BASE, (fw_length / NVME_PAGE_SIZE), true); + + for (uint32_t i = 0; i < count; i++) + nvme->prp_list[i] = NVME_IOVM_IO_BASE + i * NVME_PAGE_SIZE; + + num_dwords = (fw_buffer_aligned_length/4); + + nvme_push_admin_cmd_firmware_download(nvme, nvme->prp_list, num_dwords, 0, NVME_FW_TYPE_OPERATIONAL); + + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_CONTROLLER_SHUTDOWN_TIMEOUT); + + dart_unmap_page_range(nvme->dart_id, NVME_IOVM_IO_BASE, count); + + nvme_update_error(nvme, status); + + if (status != NVME_SUCCESS) { + dprintf(DEBUG_CRITICAL, "nvme: error %d downloading firmware to device %d\n", status, nvme_id); + goto done; + } + + nvme_push_admin_cmd_firmware_activate(nvme, NVME_FW_TYPE_OPERATIONAL); + + status = nvme_wait_for_cmd(nvme, nvme->admin_sq, NVME_CONTROLLER_SHUTDOWN_TIMEOUT); + + // SCT 0x1 STS 0xB indicates controller reset required successful FW activation. + if (status == NVME_FW_ACTIVATE_STATUS_SUCCESS) { + printf("nvme: NVMe FW updated successfully. Reset controller.\n"); + err = 0; + } else { + dprintf(DEBUG_CRITICAL, "nvme: error %d activating firmware on device %d\n", status, nvme_id); + err = status; + } + +done: + free(fw_buffer_aligned); + + return err; +} + +#endif // #if !RELEASE_BUILD && WITH_MENU + +#if NVME_BLOCK_SIZE != NVME_PAGE_SIZE +#error "NVMe driver currently assumes that the page size and block size are the same" +#endif + + +static void dump_completion(int log_level, nvme_completion_t *completion) +{ + dprintf(log_level, " CID:0x%04x SC:0x%02x SCT:%x P:%x DNR:%x CS:0x%08x", + completion->cid, completion->sc, completion->sct, completion->p, completion->dnr, completion->cs); + for(unsigned int i = 0; i < sizeof(*completion)/4; i++) { + if (i % 4 == 0) + dprintf(log_level, "\n DW%02u ", i); + dprintf(log_level, "%08x ", completion->cdw[i]); + } + dprintf(log_level, "\n"); +} + +static void dump_command(int log_level, nvme_command_t *command) +{ + dprintf(log_level, " CID:0x%04x OPC:0x%02x NSID:0x%04x PRP1:0x%08llx PRP2:0x%08llx", + command->cid, command->opc, command->nsid, command->prp1, command->prp2); + for(unsigned int i = 0; i < sizeof(*command)/4; i++) { + if (i % 4 == 0) + dprintf(log_level, "\n DW%02u ", i); + dprintf(log_level, "%08x ", command->cdw[i]); + } + dprintf(log_level, "\n"); +} + +#if DEBUG_BUILD || DEVELOPMENT_BUILD +static void dump_submission_queue(int log_level, nvme_sq_t *sq) +{ + if (sq == NULL) return; + + dprintf(log_level, "== Submission Queue 0x%x ==\n", sq->queue_id); + dprintf(log_level, "Elements:%02x Head:%02x Tail:%02x\n", sq->elements, sq->head, sq->tail); + dprintf(log_level, "Buffer address 0x%010llx (pci 0x%08llx)\n", (uint64_t)sq->commands, sq->commands_iovm_addr); + for (unsigned int i = 0; i < sq->elements; i++) + dump_command(log_level, &sq->commands[i]); +} + +static void dump_completion_queue(int log_level, nvme_cq_t *cq) +{ + if (cq == NULL) return; + + dprintf(log_level, "== Completion Queue 0x%x ==\n", cq->queue_id); + dprintf(log_level, "Elements:%02x Head:%02x Tail:%02x\n", cq->elements, cq->head, cq->tail); + dprintf(log_level, "Buffer address 0x%010llx (pci 0x%08llx)\n", (uint64_t)cq->completions, cq->completions_iovm_addr); + for (unsigned int i = 0; i < cq->elements; i++) + dump_completion(log_level, &cq->completions[i]); +} + +static void dump_controller_state(int log_level, nvme_t *nvme) +{ + for (int i = 0; i < NUM_QUEUES; i++) { + dump_submission_queue(log_level, &nvme->sq[i]); + } + for (int i = 0; i < NUM_QUEUES; i++) { + dump_completion_queue(log_level, &nvme->cq[i]); + } +} +#endif + +#if !RELEASE_BUILD && WITH_MENU +static void print_usage(void) +{ + printf("Usage: \n" + "1. usb get \n" + "2. nvmefw\n" + "-or-\n" + "nvmefw \n"); +} + +static int do_nvmefw(int argc, struct cmd_arg *args) +{ + addr_t buf_ptr; + size_t buf_len; + void *fw_buffer = NULL; + uint32_t fw_length; + + if (argc > 3) + { + return -1; + } + + buf_ptr = (argc > 1) ? args[1].u : env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + buf_len = (argc > 2) ? args[2].u : env_get_uint("filesize", 0); + + if ((buf_len == 0) || (buf_ptr == 0)) + { + print_usage(); + return -1; + } + + if (!security_allow_memory((void*)buf_ptr, buf_len)) + { + printf("do_nvmefw: security_allow_memory failed\n"); + return -2; + } + + fw_buffer = (void *)buf_ptr; + fw_length = (uint32_t)buf_len; + + if ((NULL == fw_buffer)) + { + printf("do_nvmefw: couldn't find the fw payload\n"); + return -3; + } + + return nvme_update_firmware(0, fw_buffer, fw_length); +} + +MENU_COMMAND_DEVELOPMENT(nvmefw, do_nvmefw, "Update NVMe controller firmware", NULL); + +static int send_scratchpad_to_file(const nvme_t *nvme, size_t max_size, const char *filename) +{ + uintptr_t scratch_base; + size_t scratch_size; + + scratch_base = platform_get_memory_region_base(kMemoryRegion_StorageProcessor); + scratch_size = platform_get_memory_region_size(kMemoryRegion_StorageProcessor); + + if (max_size != 0 && scratch_size > max_size) { + scratch_size = max_size; + } + + printf("scratch_base=%p actual_length=%zd filename=%s\n", (void *)scratch_base, scratch_size, filename); + + return usb_send_data_to_file(filename, scratch_size, scratch_base, 0); +} + +static int nvme_get_fa(nvme_t *nvme, const char *out_scratch_filename, const char *out_fa_file_name) +{ + int status; + uint32_t assert_id; + uint32_t fa_size; + + assert_id = nvme_read_reg32(nvme, NVME_REG_S3E_ASSERT_ID); + if (!nvme_check_reg_valid32(assert_id) || assert_id == 0) { + printf("nvmefa error: Drive is not asserted. FA is not available.\n"); + return -1; + } + + nvme_write_reg32(nvme, NVME_REG_FA_ACTION, NVME_FA_ACTION_DO_FLUSH); + status = nvme_poll_reg32(nvme, NVME_REG_FA_STATUS, NVME_FA_STATUS_FLUSH_DONE, 5000); + if (status != NVME_SUCCESS) { + return status; + } + + status = send_scratchpad_to_file(nvme, 0, out_scratch_filename); + if (status != 0) { + printf("nvmefa error: Failed writing scatchpad contents to file. error=%d\n", status); + return status; + } + + nvme_write_reg32(nvme, NVME_REG_FA_ACTION, NVME_FA_ACTION_DO_DUMP_FA); + status = nvme_poll_reg32(nvme, NVME_REG_FA_STATUS, NVME_FA_STATUS_FA_DONE, 5000); + if (status != NVME_SUCCESS) + { + return status; + } + + fa_size = nvme_read_reg32(nvme, NVME_REG_FA_SIZE); + if (!nvme_check_reg_valid32(fa_size) || fa_size == 0) { + printf("nvmefa error: Invalid FA size (0x%x)\n", fa_size); + return -1; + } + + status = send_scratchpad_to_file(nvme, fa_size, out_fa_file_name); + if (status != 0) { + printf("nvmefa error: Failed writing FA contents to file. error=%d\n", status); + return status; + } + + printf("nvmefa: FA was pulled successfully.\n"); + return 0; +} + +static int do_nvme_fa(int argc, struct cmd_arg *args) +{ + nvme_t *nvme = get_nvme_controller(0); + bool need_pci_quiesce = false; + int status; + + if (argc != 3) + { + printf("nvmefa \n"); + return -1; + } + + // If PCI is uninitialized, we need to initialize it ourselves, and quiesce it after we're done. + if (!nvme->pci_dev) { + if (!nvme->bridge_dev) { + printf("nvmefa error: PCI in uninitialized and no bridge device.\n"); + return -1; + } + status = nvme_init_pci(nvme, nvme->bridge_dev); + if (status != 0) { + return -1; + } + need_pci_quiesce = true; + } + + status = nvme_get_fa(nvme, args[1].str, args[2].str); + + if (need_pci_quiesce) { + nvme_quiesce_pci(nvme); + } + return status; +} + +MENU_COMMAND_DEVELOPMENT(nvmefa, do_nvme_fa, "Pull NVMe FA data", NULL); + +#endif // #if !RELEASE_BUILD && WITH_MENU diff --git a/drivers/nvme/nvme_blockdev.c b/drivers/nvme/nvme_blockdev.c new file mode 100644 index 0000000..ffd38b7 --- /dev/null +++ b/drivers/nvme/nvme_blockdev.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nvme_blockdev.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +typedef struct nvme_bdev { + struct blockdev blockdev; + + int nvme_id; + uint32_t nsid; + + uint32_t max_transfer_blocks; + uint32_t dummy_blocks; + uint32_t blocks_per_virtual_block; + + struct list_node node; +} nvme_bdev_t; + +static struct list_node blockdev_list = LIST_INITIAL_VALUE(blockdev_list); + +static nvme_bdev_t *nvme_bdev_for_blockdev(struct blockdev *blockdev) +{ + nvme_bdev_t *entry; + + list_for_every_entry(&blockdev_list, entry, nvme_bdev_t, node) { + if (blockdev == &entry->blockdev) + return entry; + } + + panic("Unknown block device %p", blockdev); +} + +static int nvme_bdev_read(struct blockdev *blockdev, void *ptr, block_addr block, uint32_t count) +{ + nvme_bdev_t *nvme_bdev; + uint32_t real_count; + uint32_t blocks_read; + + nvme_bdev = nvme_bdev_for_blockdev(blockdev); + + // For special namespaces like NVRAM and SysCfg, we lie about the block size + block *= nvme_bdev->blocks_per_virtual_block; + count *= nvme_bdev->blocks_per_virtual_block; + + real_count = __min(count, nvme_bdev->max_transfer_blocks); + + // Hack for Maui platforms not loading syscfg in iBoot + if (nvme_bdev->dummy_blocks > 0) { + if (block < nvme_bdev->dummy_blocks) { + return -1; + } + block -= nvme_bdev->dummy_blocks; + } + + blocks_read = nvme_read_blocks(nvme_bdev->nvme_id, nvme_bdev->nsid, ptr, block, real_count); + + if ( blocks_read ) { + blocks_read /= nvme_bdev->blocks_per_virtual_block; + } + + return blocks_read; +} + +static int nvme_bdev_write(struct blockdev *blockdev, const void *ptr, block_addr block, uint32_t count) +{ + nvme_bdev_t *nvme_bdev; + uint32_t real_count; + uint32_t blocks_written; + + nvme_bdev = nvme_bdev_for_blockdev(blockdev); + + // For special namespaces like NVRAM and SysCfg, we lie about the block size + block *= nvme_bdev->blocks_per_virtual_block; + count *= nvme_bdev->blocks_per_virtual_block; + + real_count = __min(count, nvme_bdev->max_transfer_blocks); + + // Hack for Maui platforms not loading syscfg in iBoot + if (nvme_bdev->dummy_blocks > 0) { + if (block < nvme_bdev->dummy_blocks) { + return -1; + } + block -= nvme_bdev->dummy_blocks; + } + + blocks_written = nvme_write_blocks(nvme_bdev->nvme_id, nvme_bdev->nsid, ptr, block, real_count); + + if ( blocks_written ) { + blocks_written /= nvme_bdev->blocks_per_virtual_block; + } + + return blocks_written; +} + +#if ((PRODUCT_IBEC || PRODUCT_IBOOT) && !RELEASE_BUILD) +static int nvme_bdev_erase(struct blockdev *blockdev, off_t offset, uint64_t length) +{ + nvme_bdev_t *nvme_bdev = NULL; + uint32_t buffer_length = 0; + uint32_t count = 0; + uint32_t real_count = 0; + uint32_t blocks_written = 0; + uint8_t *buffer = NULL; + uint32_t block = 0; + + nvme_bdev = nvme_bdev_for_blockdev(blockdev); + + if((nvme_bdev->nsid != NVME_NAMESPACE_NAND) && (offset > 0)) + { + dprintf(DEBUG_CRITICAL,"erase should start at offset 0 for nsid %d\n", nvme_bdev->nsid); + return -1; + } + + // If offset/length is not a multiple of block size, return error. + if((offset % (nvme_bdev->blocks_per_virtual_block * NVME_BLOCK_SIZE)) + || (length % (nvme_bdev->blocks_per_virtual_block * NVME_BLOCK_SIZE))) + { + dprintf(DEBUG_CRITICAL,"offset/length is not a multiple of block size %d\n", (nvme_bdev->blocks_per_virtual_block * NVME_BLOCK_SIZE)); + return -1; + } + + block = offset/(nvme_bdev->blocks_per_virtual_block * NVME_BLOCK_SIZE); + + // For special namespaces like NVRAM and SysCfg, we lie about the block size + count = length/(nvme_bdev->blocks_per_virtual_block * NVME_BLOCK_SIZE); + + // allocate buffer + buffer_length = count * NVME_BLOCK_SIZE; + buffer = memalign(buffer_length, NVME_BLOCK_SIZE); + + real_count = __min(count, nvme_bdev->max_transfer_blocks); + + // Hack for Maui platforms not loading syscfg in iBoot + if (nvme_bdev->dummy_blocks > 0) { + if (block < nvme_bdev->dummy_blocks) { + return -1; + } + block -= nvme_bdev->dummy_blocks; + } + + dprintf(DEBUG_CRITICAL,"nvme: erasing %d blocks from LBA %d for nsid %d\n", real_count, block, nvme_bdev->nsid); + blocks_written = nvme_write_blocks(nvme_bdev->nvme_id, nvme_bdev->nsid, buffer, block, real_count); + + if ( blocks_written ) { + blocks_written /= nvme_bdev->blocks_per_virtual_block; + } + + free(buffer); + + return blocks_written; +} +#endif + +static nvme_bdev_t *nvme_bdev_create(int nvme_id, uint32_t nsid, uint32_t blocks) +{ + char blockdev_name[16]; + nvme_bdev_t *nvme_bdev; + int result; + uint32_t block_size; + + nvme_bdev = calloc(1, sizeof(*nvme_bdev)); + nvme_bdev->nvme_id = nvme_id; + nvme_bdev->nsid = nsid; + + nvme_bdev->max_transfer_blocks = nvme_get_max_transfer_blocks(nvme_id); + nvme_bdev->blocks_per_virtual_block = 1; + + switch (nsid) { + case NVME_NAMESPACE_NAND: + snprintf(blockdev_name, sizeof(blockdev_name), "nvme_nand%d", nvme_id); + break; + + case NVME_NAMESPACE_FIRMWARE: + snprintf(blockdev_name, sizeof(blockdev_name), "nvme_firmware%d", nvme_id); + break; + + case NVME_NAMESPACE_NVRAM: + strlcpy(blockdev_name, "nvram", sizeof(blockdev_name)); + + // S3E doesn't allow NVRAM partition to be written piecewise, so + // we lie about the blocksize to upper layers to force writes to + // go through in a single operation. Otherwise the blockdev deblocking + // code can generate two writes if the source buffer isn't aligned + nvme_bdev->blocks_per_virtual_block = 2; + break; + + case NVME_NAMESPACE_SYSCFG: + snprintf(blockdev_name, sizeof(blockdev_name), "nvme_syscfg%d", nvme_id); + + // Hack for Maui platforms not loading syscfg in iBoot + nvme_bdev->blocks_per_virtual_block = 2; + nvme_bdev->dummy_blocks = kSysCfgBdevOffset / NVME_BLOCK_SIZE; + blocks += nvme_bdev->dummy_blocks; + break; + + case NVME_NAMESPACE_EFFACEABLE: + snprintf(blockdev_name, sizeof(blockdev_name), "nvme_efface%d", nvme_id); + break; + + case NVME_NAMESPACE_PANICLOG: + strlcpy(blockdev_name, "paniclog", sizeof(blockdev_name)); + nvme_bdev->blocks_per_virtual_block = 256; + break; + + default: + panic("Unknown nvme namespace %d", nsid); + } + + ASSERT(nvme_id < 100); + ASSERT(sizeof(blockdev_name) == sizeof(nvme_bdev->blockdev.name)); + + // For special namespaces like NVRAM and SysCfg, we need to lie about + // the block size + blocks /= nvme_bdev->blocks_per_virtual_block; + block_size = NVME_BLOCK_SIZE * nvme_bdev->blocks_per_virtual_block; + + result = construct_blockdev(&nvme_bdev->blockdev, blockdev_name, (uint64_t)blocks * block_size, block_size); + + if (result != 0) + panic("Couldn't construct blockdev for namespace %d", nsid); + + blockdev_set_buffer_alignment(&nvme_bdev->blockdev, NVME_BLOCK_SIZE); + + nvme_bdev->blockdev.read_block_hook = &nvme_bdev_read; + +#if !NVME_ENABLE_WRITES + if (nsid == NVME_NAMESPACE_NVRAM || nsid == NVME_NAMESPACE_PANICLOG) +#endif + nvme_bdev->blockdev.write_block_hook = &nvme_bdev_write; + +#if ((PRODUCT_IBOOT || PRODUCT_IBEC) && !RELEASE_BUILD) + if (nsid == NVME_NAMESPACE_FIRMWARE) + nvme_bdev->blockdev.erase_hook = &nvme_bdev_erase; +#endif + + if (register_blockdev(&nvme_bdev->blockdev) != 0) { + free(nvme_bdev); + return NULL; + } + + list_add_tail(&blockdev_list, &nvme_bdev->node); + + return nvme_bdev; +} + +static nvme_bdev_t *nvme_bdev_identify_and_create(int nvme_id, uint32_t nsid) +{ + nvme_namespace_params_t params; + int result; + + result = nvme_identify_namespace(nvme_id, nsid, ¶ms); + if (result != NVME_SUCCESS) { + dprintf(DEBUG_SPEW, "nvme: error %d trying to identify nsid %u\n", result, nsid); + return NULL; + } + if (!params.formatted) { + dprintf(DEBUG_SPEW, "nvme: nsid %u not formatted\n", nsid); + return NULL; + } + + dprintf(DEBUG_INFO, "nvme: Creating blkdev for NSID %d num_blocks %llu\n", nsid, params.num_blocks); + return nvme_bdev_create(nvme_id, nsid, params.num_blocks); +} + +int nvme_blockdev_init_boot(int nvme_id) +{ + // In boot mode, we can't determine the size of the namespace ahead of time, + // so it's up to callers to not read past the end of the device, and the NVMe + // driver to return errors as needed +#if !WITH_MASS_STORAGE + nvme_bdev_create(nvme_id, NVME_NAMESPACE_FIRMWARE, INT_MAX); + +#endif + + // These other ones are only in iBoot/iBEC, where we're less concerned about speed + // and thus can do the identify step +#if WITH_MASS_STORAGE + nvme_bdev_identify_and_create(nvme_id, NVME_NAMESPACE_FIRMWARE); +#endif +#if WITH_SYSCFG + nvme_bdev_identify_and_create(nvme_id, NVME_NAMESPACE_SYSCFG); +#endif +#if WITH_NVRAM + nvme_bdev_identify_and_create(nvme_id, NVME_NAMESPACE_NVRAM); +#endif +#if WITH_EFFACEABLE + nvme_bdev_identify_and_create(nvme_id, NVME_NAMESPACE_EFFACEABLE); +#endif + nvme_bdev_identify_and_create(nvme_id, NVME_NAMESPACE_PANICLOG); + + return 0; +} + +#if WITH_MASS_STORAGE +int nvme_blockdev_init_normal(int nvme_id) +{ + nvme_bdev_t *nvme_nand_bdev; + + nvme_nand_bdev = nvme_bdev_identify_and_create(nvme_id, NVME_NAMESPACE_NAND); + + if (nvme_nand_bdev != NULL) { + const char *name = nvme_nand_bdev->blockdev.name; + return partition_scan_and_publish_subdevices(name); + } else { + return -1; + } +} +#endif diff --git a/drivers/nvme/nvme_blockdev.h b/drivers/nvme/nvme_blockdev.h new file mode 100644 index 0000000..7efcd05 --- /dev/null +++ b/drivers/nvme/nvme_blockdev.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef NVME_BLOCKDEV_H +#define NVME_BLOCKDEV_H + +int nvme_blockdev_init_boot(int nvme_id); +int nvme_blockdev_init_normal(int nvme_id); + +#endif // NVME_BLOCKDEV_H diff --git a/drivers/nvme/nvme_protocol.h b/drivers/nvme/nvme_protocol.h new file mode 100644 index 0000000..6345aac --- /dev/null +++ b/drivers/nvme/nvme_protocol.h @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef NVME_PROTOCOL_H +#define NVME_PROTOCOL_H + +#include + +#if( !defined( OSCompileAssert ) ) +# define OSCompileAssert( TEST ) \ + extern int OSCompileAssertFailed[ ( TEST ) ? 1 : -1 ] __unused; +#endif + +typedef union nvme_command { + struct { + uint8_t opc; // CDW[0] bits 0-7 + uint8_t fuse:2; // CDW[0] bits 8-9 + uint8_t reserved0:3; // CDW[0] bits 10-12 + uint8_t lprp:1; // CDW[0] bit 13 + uint8_t reserved1:2; // CDW[0] bits 14-15 + uint16_t cid; // CDW[0] bits 16-31 + uint32_t nsid; // CDW[1] + uint64_t reserved2; // CDW[3:2] + uint64_t mptr; // CDW[5:4] + uint64_t prp1; // CDW[7:6] + uint64_t prp2; // CDW[9:8] + }; + uint32_t cdw[16]; +} nvme_command_t; + +typedef union nvme_completion { + struct { + uint32_t cs; + uint32_t reserved0; + uint16_t sqhd; + uint16_t sqid; + uint16_t cid; + uint16_t p:1; + uint16_t sc:8; + uint16_t sct:3; + uint16_t reserved1:2; + uint16_t m:1; + uint16_t dnr:1; + }; + uint32_t cdw[4]; +} nvme_completion_t; + +typedef struct nvme_identify_namespace { + uint64_t nsze; + uint64_t ncap; + uint64_t nuse; + uint8_t nfeat; + uint8_t nlbaf; + uint8_t flbas; + uint8_t mc; + uint8_t dpc; + uint8_t dps; + uint8_t reserved1[98]; + struct { + uint16_t ms; + uint8_t lbads; + uint8_t rp:2; + uint8_t reserved:6; + } lbaf[16]; + uint8_t reserved2[192]; + uint8_t vs[3712]; +} nvme_identify_namespace_t; + +typedef struct NVMePowerStateDescriptor +{ + uint16_t MAXIMUM_POWER; + uint8_t RESERVED1[2]; + uint32_t ENTRY_LATENCY; + uint32_t EXIT_LATENCY; + uint8_t RELATIVE_READ_THROUGHPUT; + uint8_t RELATIVE_READ_LATENCY; + uint8_t RELATIVE_WRITE_THROUGHPUT; + uint8_t RELATIVE_WRITE_LATENCY; + uint8_t RESERVED2[16]; +} NVMePowerStateDescriptor; + +OSCompileAssert ( sizeof ( NVMePowerStateDescriptor ) == 32 ); + +enum +{ + kNVMeIdentifyControllerSerialNumberLen = 20, + kNVMeIdentifyControllerModelNumberLen = 40, + kNVMeIdentifyControllerFirmwareRevisionLen = 8, + kNVMeIdentifyControllerIEEEOUIIDLen = 3, + kNVMeIdentifyControllerMSPRevisionLen = 16, + kNVMeIdentifyControllerPTSRevisionLen = 12, + kNVMeIdentifyControllerBuildTrainLen = 16, + kNVMeIdentifyControllerNANDTypeLen = 32, + kNVMeIdentifyControllerNANDVendorLen = 16 +}; + +enum +{ + NVME_MODESEL_NORMAL = 0, + NVME_MODESEL_BOOT = 1, + NVME_MODESEL_READONLY = 2, + NVME_MODESEL_RECOVERY = 3, + NVME_MODESEL_MAX = 4 +}; + +#define kNVMeIdentifyControllerNumFuses 8 + +typedef struct NVMeIdentifyControllerStruct +{ + // Controller Capabilites and Features + uint16_t PCI_VID; + uint16_t PCI_SSVID; + uint8_t SERIAL_NUMBER[kNVMeIdentifyControllerSerialNumberLen]; + uint8_t MODEL_NUMBER[kNVMeIdentifyControllerModelNumberLen]; + uint8_t FW_REVISION[kNVMeIdentifyControllerFirmwareRevisionLen]; + uint8_t RECOMMENDED_ARBITRATION_BURST; + uint8_t IEEE_OUI_ID[kNVMeIdentifyControllerIEEEOUIIDLen]; + uint8_t MIC; + uint8_t MAX_DATA_TRANSFER_SIZE; + uint16_t CONTROLLER_ID; + uint8_t RESERVED1[176]; + + // Admin Command Set Attributes + uint16_t OPTIONAL_ADMIN_COMMAND_SUPPORT; + uint8_t ABORT_COMMAND_LIMIT; + uint8_t ASYNC_EVENT_REQUEST_LIMIT; + uint8_t FW_UPDATES; + uint8_t LOG_PAGE_ATTR; + uint8_t ERROR_LOG_PAGE_ENTRIES; + uint8_t NUM_OF_POWER_STATE_SUPPORT; + uint8_t ADMIN_VENDOR_SPECIFIC_COMMAND_CONFIG; + uint8_t AUTONOMOUS_POWER_STATE_TRANSITION_ATTR; + uint8_t RESERVED2[246]; + + // NVM Command Set Attributes + uint8_t SQ_ENTRY_SIZE; + uint8_t CQ_ENTRY_SIZE; + uint8_t RESERVED3[2]; + uint32_t NUMBER_OF_NAMESPACES; + uint16_t OPTIONAL_NVM_COMMAND_SUPPORT; + uint16_t FUSE_OP_SUPPORT; + uint8_t FORMAT_NVM_ATTR; + uint8_t VOLATILE_WRITE_CACHE; + uint16_t ATOMIC_WRITE_UNIT_NORMAL; + uint16_t ATOMIC_WRITE_UNIT_POWER_FAIL; + uint8_t NVM_VENDOR_SPECIFIC_COMMAND_CONFIG; + uint8_t RESERVED4[1]; + uint16_t ATOMIC_COMPARE_AND_WRITE_UNIT; + uint8_t RESERVED5[2]; + uint32_t SGL_SUPPORT; + uint8_t RESERVED6[164]; + + // I/O Command Set Attributes + uint8_t RESERVED7[1344]; + + // Power State Descriptors + NVMePowerStateDescriptor POWER_STATE_DESCRIPTORS[32]; + + // Vendor Specific Runtime Data + uint8_t MSP_REVISION[kNVMeIdentifyControllerMSPRevisionLen]; + uint32_t TIME_TO_READY; + uint32_t TRIMMER_STATUS; + uint8_t BOOT_SOURCE; + uint8_t BOOT_BLOCK_INDEX; + uint8_t RESERVED8[2]; + uint8_t S3_CHIP_ID; + uint8_t S3_CHIP_REVISION; + uint16_t S3_DEVICE_DESCRIPTOR; + uint8_t S3_ECC_VERSION_NAND_REVISION; + uint8_t S3_FTL_MAJOR_VERSION; + uint8_t S3_FTL_MINOR_VERSION; + uint8_t S3_DM_VERSION; + uint8_t S3_CONFIG_VERSION; + uint8_t S3_FORMAT_UTIL_MAJOR_VERSION; + uint8_t RESERVED9[6]; + uint8_t ASP_BUILD_TRAIN[kNVMeIdentifyControllerBuildTrainLen]; + uint8_t MSP_BUILD_TRAIN[kNVMeIdentifyControllerBuildTrainLen]; + uint8_t RESERVED10[436]; + // Vendor Specific Production Data + uint8_t BOARD_TYPE; + uint8_t NAND_TYPE; + uint8_t NAND_VENDOR; + uint8_t DRAM_VENDOR; + uint8_t NOR_VENDOR; + uint8_t CHANNELS_BITMAP; + uint16_t SSD_CAPACITY; + uint8_t CORNER_TYPE; + uint8_t ROM_VERSION; + uint8_t PTS_REVISION[kNVMeIdentifyControllerPTSRevisionLen]; + uint16_t PTS_STATUS_BITMAP; + uint8_t NAND_TYPE_STRING[kNVMeIdentifyControllerNANDTypeLen]; + uint8_t NAND_VENDOR_STRING[kNVMeIdentifyControllerNANDVendorLen]; + uint32_t MAXIMUM_PRIMARY_NS_SIZE; + uint8_t RESERVED11[180]; + uint32_t RAW_FUSES[kNVMeIdentifyControllerNumFuses]; + uint8_t RESERVED12[224]; + +} NVMeIdentifyControllerStruct; + +#define NVME_FUSE_VALUE_FOR_HYNIX 1 +#define NVME_FUSE_VALUE_FOR_SANDISK 3 +#define NVME_FUSE_VALUE_FOR_SAMSUNG 4 +#define NVME_FUSE_VALUE_FOR_TOSHIBA 5 + +typedef enum +{ + NVME_NAND_DEVICE_HYNIX = NVME_FUSE_VALUE_FOR_HYNIX, + NVME_NAND_DEVICE_SANDISK = NVME_FUSE_VALUE_FOR_SANDISK, + NVME_NAND_DEVICE_SAMSUNG = NVME_FUSE_VALUE_FOR_SAMSUNG, + NVME_NAND_DEVICE_TOSHIBA = NVME_FUSE_VALUE_FOR_TOSHIBA, + NVME_NAND_NUM_VENDORS +} NVME_NAND_DEVICE_VENDOR_E; + +typedef enum +{ + NVME_LYTH_1X, + NVME_LYTH_1Y, + NVME_LYTH_1Z, + NVME_NAND_NUM_LITHOS +} NVME_NAND_DEVICE_LITHOGRAPHY_E; + +typedef enum +{ + NVME_NAND_DEV_DENSITY_SLC, + NVME_NAND_DEV_DENSITY_MLC, + NVME_NAND_DEV_DENSITY_TLC, + NVME_NAND_NUM_DENSITIES +} NVME_NAND_DEVICE_DENSITY_E; + +typedef enum +{ + NVME_SINGLE_DIMENSION, + NVME_THREE_DIMENSION, + NVME_NAND_NUM_DIMENSIONS +} NVME_NAND_DEVICE_TECHNOLOGY_E; + +typedef enum { + NVME_CHIP_S3E, + NVME_CHIP_S3X, + NVME_CHIP_NUM_ID +} NVME_IDCMD_ChipID_E; + +typedef enum { + NVME_REV_A, + NVME_REV_B, + NVME_REV_C, + NVME_CHIP_NUM_REV_MAJOR +} NVME_IDCMD_ChipRevMajor_E; + +typedef enum { + B_DIE, + C_DIE, + NUM_DIE_TYPES +} NAND_DEVICE_DIE_TYPE_E; + +const static char *NVME_VENDOR_STRINGS[NVME_NAND_NUM_VENDORS] = +{ + "Invalid", + "Hynix", + "Invalid", + "Sandisk", + "Samsung", + "Toshiba" +}; + +const static char *NVME_LITHOGRAPHY_STRINGS[NVME_NAND_NUM_LITHOS] = +{ + "1x", + "1y", + "1z" +}; + +const static char *NVME_DENSITY_STRINGS[NVME_NAND_NUM_DENSITIES] = +{ + "SLC", + "MLC", + "TLC" +}; + +const static char *NVME_DIMENSIONS_STRINGS[NVME_NAND_NUM_DIMENSIONS] = +{ + "1D", + "3D", +}; + +const static char *NVME_CHIP_STRINGS[NVME_CHIP_NUM_ID] = +{ + "S3E", + "S1X", +}; + +const static char *NVME_CHIP_DIE_STRINGS[NUM_DIE_TYPES] = +{ + "b", + "c" +}; + + +#define NVME_APPLE_CLASS_CODE (0x018002) +#define NVME_APPLE_BAR0_SIZE (0x2000) + +#define NVME_PAGE_SIZE (1<<12) +#define NVME_PAGE_MASK (NVME_PAGE_SIZE - 1) + +#define NVME_ADMIN_DELETE_SQ 0x00 +#define NVME_ADMIN_CREATE_SQ 0x01 +#define NVME_ADMIN_DELETE_CQ 0x04 +#define NVME_ADMIN_CREATE_CQ 0x05 +#define NVME_ADMIN_IDENTIFY 0x06 +#define NVME_ADMIN_SET_FEATURES 0x09 +#define NVME_ADMIN_GET_FEATURES 0x0a +#define NVME_ADMIN_FW_ACTIVATE 0x10 +#define NVME_ADMIN_FW_DOWNLOAD 0x11 + +#define NVME_IO_CMD_FLUSH 0x00 +#define NVME_IO_CMD_WRITE 0x01 +#define NVME_IO_CMD_READ 0x02 +#define NVME_IO_CMD_DATASET_MANAGEMENT 0x09 + +#define NVME_CREATE_SQ_CONTIGUOUS (1<<0) +#define NVME_CREATE_CQ_CONTIGUOUS (1<<0) +#define NVME_CREATE_CQ_INTERRUPT_EN (1<<1) + + +#define NVME_REG_CAP (0x0000) +#define NVME_REG_VS (0x0008) +#define NVME_REG_INTMS (0x000c) +#define NVME_REG_INTMC (0x0010) +#define NVME_REG_CC (0x0014) +#define NVME_REG_CSTS (0x001c) +#define NVME_REG_AQA (0x0024) +#define NVME_REG_ASQ (0x0028) +#define NVME_REG_ACQ (0x0030) +#define NVME_REG_SQ0TDBL (0x1000) +#define NVME_REG_MODESEL (0x1800) +#define NVME_REG_MODESTAT (0x1804) +#define NVME_REG_DDRREQSIZE (0x1808) +#define NVME_REG_DDRREQALIGN (0x180c) +#define NVME_REG_DDRBASE (0x1810) +#define NVME_REG_DDRSIZE (0x1818) + +// S3E-specific registers +#define NVME_REG_S3E_TIMEOUT_DEBUG (0x0550) +#define NVME_REG_S3E_ASSERT_ID (0x1910) +#define NVME_REG_S3E_ASSERT_LOG1 (0x1914) +#define NVME_REG_S3E_ASSERT_LOG2 (0x1918) +#define NVME_REG_S3E_ASSERT_LOG3 (0x191c) +#define NVME_REG_S3E_ASSERT_EDD0 (0x1980) +#define NVME_REG_S3E_ASSERT_EDD1 (0x1984) +#define NVME_REG_S3E_ASSERT_EDD2 (0x1988) +#define NVME_REG_S3E_ASSERT_EDD3 (0x198c) +#define NVME_REG_S3E_ASSERT_EDD4 (0x1990) +#define NVME_REG_S3E_ASSERT_EDD5 (0x1994) +#define NVME_REG_S3E_ASSERT_EDD6 (0x1998) +#define NVME_REG_S3E_ASSERT_EDD7 (0x199c) + +// S3E FA registers +#define NVME_REG_FA_ACTION (0x195C) +#define NVME_REG_FA_STATUS (0x1960) +#define NVME_REG_FA_SIZE (0x1964) + +// S3E FA actions +#define NVME_FA_ACTION_DO_FLUSH 1 +#define NVME_FA_ACTION_DO_DUMP_FA 2 + +// S3E FA status values +#define NVME_FA_STATUS_FLUSH_DONE 1 +#define NVME_FA_STATUS_FA_DONE 2 + +#define NVME_CC_EN (1 << 0) +#define NVME_CC_MPS(x) (x << 7) +#define NVME_CC_SHN_NONE (0 << 14) +#define NVME_CC_SHN_NORMAL (1 << 14) +#define NVME_CC_SHN_ABRUPT (2 << 14) +#define NVME_CC_IOSQES(x) (x << 16) +#define NVME_CC_IOCQES(x) (x << 20) + +#define NVME_CSTS_RDY (1 << 0) +#define NVME_CSTS_CFS (1 << 1) +#define NVME_CSTS_SHST_MASK (3 << 2) +#define NVME_CSTS_SHST_NORMAL (0 << 2) +#define NVME_CSTS_SHST_PROCESSING (1 << 2) +#define NVME_CSTS_SHST_DONE (2 << 2) + +#endif // NVME_PROTOCOL_H diff --git a/drivers/nvme/rules.mk b/drivers/nvme/rules.mk new file mode 100644 index 0000000..0924044 --- /dev/null +++ b/drivers/nvme/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_NVME=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/nvme.o \ + $(LOCAL_DIR)/nvme_blockdev.o diff --git a/drivers/nxp/cbtl1610/cbtl1610.c b/drivers/nxp/cbtl1610/cbtl1610.c new file mode 100644 index 0000000..e37e7c3 --- /dev/null +++ b/drivers/nxp/cbtl1610/cbtl1610.c @@ -0,0 +1,455 @@ +/* + * Copyright (C) 2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CBTL1610_ADDR_R 0x35 +#define CBTL1610_ADDR_W 0x34 + +enum { + DXCTRL = 0x01, + DXCTRL_DX2OVRD = (1 << 7), + DXCTRL_DPDN2SW_mask = (7 << 4), + DXCTRL_DPDN2SW_open = (0 << 4), + DXCTRL_DPDN2SW_usb0 = (1 << 4), + DXCTRL_DPDN2SW_uart0 = (2 << 4), + DXCTRL_DPDN2SW_dig = (3 << 4), + DXCTRL_DPDN2SW_brick_id_p = (4 << 4), + DXCTRL_DPDN2SW_brick_id_n = (5 << 4), + DXCTRL_DPDN2SW_uart2 = (6 << 4), + DXCTRL_DPDN2SW_uart1 = (7 << 4), + DXCTRL_DX1OVRD = (1 << 3), + DXCTRL_DPDN1SW_mask = (7 << 0), + DXCTRL_DPDN1SW_open = (0 << 0), + DXCTRL_DPDN1SW_usb0 = (1 << 0), + DXCTRL_DPDN1SW_uart0 = (2 << 0), + DXCTRL_DPDN1SW_dig = (3 << 0), + DXCTRL_DPDN1SW_brick_id_p = (4 << 0), + DXCTRL_DPDN1SW_brick_id_n = (5 << 0), + DXCTRL_DPDN1SW_usb1 = (6 << 0), + DXCTRL_DPDN1SW_jtag = (7 << 0), + + ACC_CTRL = 0x02, + ACC_CTRL_ACC2OVRD = (1 << 7), + ACC_CTRL_ACC2SW_mask = (7 << 4), + ACC_CTRL_ACC2SW_open = (0 << 4), + ACC_CTRL_ACC2SW_uart1_tx = (1 << 4), + ACC_CTRL_ACC2SW_jtag_clk = (2 << 4), + ACC_CTRL_ACC2SW_acc_pwr = (3 << 4), + ACC_CTRL_ACC2SW_brick_id = (4 << 4), + ACC_CTRL_ACC1OVRD = (1 << 3), + ACC_CTRL_ACC1SW_mask = (7 << 0), + ACC_CTRL_ACC1SW_open = (0 << 0), + ACC_CTRL_ACC1SW_uart1_rx = (1 << 0), + ACC_CTRL_ACC1SW_jtag_dio = (2 << 0), + ACC_CTRL_ACC1SW_acc_pwr = (3 << 0), + ACC_CTRL_ACC1SW_brick_id = (4 << 0), + + DCP_CTRL = 0x03, + DCP_CTRL_IDXSINKEN = (1 << 3), + DCP_CTRL_VDXSRCSW_mask = (7 << 0), + DCP_CTRL_VDXSRCSW_off = (0 << 0), + DCP_CTRL_VDXSRCSW_dp1 = (1 << 0), + DCP_CTRL_VDXSRCSW_dn1 = (2 << 0), + DCP_CTRL_VDXSRCSW_dp2 = (3 << 0), + DCP_CTRL_VDXSRCSW_dn2 = (4 << 0), + + MISC_CTRL = 0x05, + MISC_CTRL_DPDN2_TERM = (1 << 5), + MISC_CTRL_DPDN1_TERM = (1 << 4), + MISC_CTRL_IDBUS_RESET = (1 << 3), + MISC_CTRL_IDBUS_BREAK = (1 << 2), + MISC_CTRL_IDBUS_REORIENT = (1 << 1), + MISC_CTRL_IDBUS_P_INSINK_EN = (1 << 0), + + DIG_ID = 0x06, + DIG_ID_Dx1 = (1 << 3), + DIG_ID_Dx0 = (1 << 2), + DIG_ID_ACCx1 = (1 << 1), + DIG_ID_ACCx0 = (1 << 0), + + FAULT_ENABLE = 0x09, + DYNAMIC_CHRG_PUMP = (1 << 7), + CHECK_VICT = (1 << 6), + CHECK_AGGR = (1 << 5), + PROTECT_UNDER = (1 << 4), + PROTECT_DIG = (1 << 3), + PROTECT_UART = (1 << 2), + PROTECT_USB = (1 << 1), + PROTECT_ACC = (1 << 0), + + EVENT1 = 0x0A, + EVENT1_Dx2_FAULT = (1 << 2), + EVENT1_Dx1_FAULT = (1 << 1), + EVENT1_ACCx_FAULT = (1 << 0), + + STATUS1 = 0x0B, + STATUS1_CMD_PEND = (1 << 0), + + STATUS0 = 0x0C, + STATUS0_IDBUS_CONNECTED = (1 << 7), + STATUS0_IDBUS_ORIENT = (1 << 6), + STATUS0_SWITCH_EN = (1 << 5), + STATUS0_HOST_RESET = (1 << 4), + STATUS0_POWER_GATE_EN = (1 << 3), + STATUS0_CON_DET_L = (1 << 2), + STATUS0_P_IN_STAT_mask = (3 << 0), + STATUS0_P_IN_STAT_brownout = (0 << 0), + STATUS0_P_IN_STAT_maintain = (1 << 0), + STATUS0_P_IN_STAT_ovp = (2 << 0), + STATUS0_P_IN_STAT_insdet = (3 << 0), + + EVENT0 = 0x0D, + EVENT_IO_FAULT = (1 << 7), + EVENT_IDBUS_TIMEOUT = (1 << 6), + EVENT_FIFO_ERR = (1 << 5), + EVENT_FIFO_RDY = (1 << 4), + EVENT_CRC_ERR = (1 << 5), + EVENT_RESP_VALID = (1 << 4), + EVENT_DIGITAL_ID = (1 << 3), + EVENT_CON_DET_L = (1 << 2), + EVENT_IDBUS_WAKE = (1 << 1), + EVENT_P_IN = (1 << 0), + + MASK = 0x0E, + MASK_IO_FAULT = (1 << 7), + MASK_IDBUS_TIMEOUT = (1 << 6), + MASK_CRC_ERR = (1 << 5), + MASK_RESP_VALID = (1 << 4), + MASK_DIGITAL_ID = (1 << 3), + MASK_CON_DET_L = (1 << 2), + MASK_IDBUS_WAKE = (1 << 1), + MASK_P_IN = (1 << 0), + + REV = 0x0F, + REV_VENDOR_ID_shift = (6), + REV_VENDOR_ID_mask = (3 << REV_VENDOR_ID_shift), + REV_VENDOR_ID_nxp = (2 << REV_VENDOR_ID_shift), + REV_BASE_VER_shift = (3), + REV_BASE_VER_mask = (7 << REV_BASE_VER_shift), + REV_METAL_VER_shift = (0), + REV_METAL_VER_mask = (7 << REV_METAL_VER_shift), + + DP1_DP2_UART_CTL = 0x10, + DP1_DP2_UART_CTL_DP2_SLEW_mask = (3 << 2), + DP1_DP2_UART_CTL_DP2_SLEW_10ns = (0 << 2), + DP1_DP2_UART_CTL_DP2_SLEW_20ns = (1 << 2), + DP1_DP2_UART_CTL_DP2_SLEW_40ns = (2 << 2), + DP1_DP2_UART_CTL_DP2_SLEW_80ns = (3 << 2), + DP1_DP2_UART_CTL_DP1_SLEW_mask = (3 << 0), + DP1_DP2_UART_CTL_DP1_SLEW_10ns = (0 << 0), + DP1_DP2_UART_CTL_DP1_SLEW_20ns = (1 << 0), + DP1_DP2_UART_CTL_DP1_SLEW_40ns = (2 << 0), + DP1_DP2_UART_CTL_DP1_SLEW_80ns = (3 << 0), + + AUTH_CTRL0 = 0x11, + AUTH_CTRL0_LOCK_STAT_VALID = (1 << 7), + AUTH_CTRL0_ESN_LOCK_STAT = (1 << 6), + AUTH_CTRL0_KEYSET2_LOCK_STAT = (1 << 5), + AUTH_CTRL0_KEYSET1_LOCK_STAT = (1 << 4), + AUTH_CTRL0_SELECT_AUTH_DOMAIN_mask = (1 << 3), + AUTH_CTRL0_SELECT_AUTH_DOMAIN_0 = (0 << 3), + AUTH_CTRL0_SELECT_AUTH_DOMAIN_1 = (1 << 3), + AUTH_CTRL0_I2C_AUTH_DONE = (1 << 1), + AUTH_CTRL0_I2C_AUTH_START = (1 << 0), + + ACC_FAULT_STATUS = 0x12, + ACC_FAULT_STATUS_RVR_COMP_OUT = (1 << 6), + ACC_FAULT_STATUS_ACC_FINGERS_5 = (1 << 5), + ACC_FAULT_STATUS_ACC_FINGERS_4 = (1 << 4), + ACC_FAULT_STATUS_ACC_FINGERS_3 = (1 << 3), + ACC_FAULT_STATUS_ACC_FINGERS_2 = (1 << 2), + ACC_FAULT_STATUS_ACC_FINGERS_1 = (1 << 1), + ACC_FAULT_STATUS_ACC_FINGERS_0 = (1 << 0), + + ACC_FAULT_CTRL0 = 0x13, + ACC_FAULT_CTRL0_EN_2X_OFFSET = (1 << 7), + ACC_FAULT_CTRL0_BP_DISABLE_ACC_DISCONNECT = (1 << 6), + ACC_FAULT_CTRL0_BP_DEGLITCH_mask = (15 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_no = (0 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_12us = (1 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_36us = (2 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_60us = (3 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_100us = (4 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_200us = (5 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_500us = (6 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_1000us = (7 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_2ms = (8 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_5ms = (9 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_10ms = (10 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_20ms = (11 << 0), + ACC_FAULT_CTRL0_BP_DEGLITCH_50ms = (12 << 0), + + ACC_FAULT_CTRL1 = 0x14, + ACC_FAULT_CTRL1_BP_MODE_mask = (3 << 6), + ACC_FAULT_CTRL1_BP_MODE_no = (0 << 6), + ACC_FAULT_CTRL1_BP_SW_CTRL_mask = (63 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_800mohm = (0 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_270mohm = (32 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_170mohm = (48 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_130mohm = (56 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_100mohm = (52 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_90mohm = (60 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_600mohm = (62 << 0), + ACC_FAULT_CTRL1_BP_SW_CTRL_40mohm = (63 << 0), + + MISC_IO = 0x1D, + MISC_IO_IDBUS_TIMEOUT_mask = (3 << 3), + MISC_IO_IDBUS_TIMEOUT_disabled = (0 << 3), + MISC_IO_IDBUS_TIMEOUT_5s = (1 << 3), + MISC_IO_IDBUS_TIMEOUT_10s = (2 << 3), + MISC_IO_IDBUS_TIMEOUT_30s = (3 << 3), + MISC_IO_UART2_LOOP_BK = (1 << 2), + MISC_IO_UART1_LOOP_BK = (1 << 1), + MISC_IO_UART0_LOOP_BK = (1 << 0), + + CON_DET_SMPL = 0x1E, + CON_DET_SMPL_CON_DET_PULLUP_mask = (3 << 5), + CON_DET_SMPL_CON_DET_PULLUP_20kohm = (0 << 5), + CON_DET_SMPL_CON_DET_PULLUP_40kohm = (1 << 5), + CON_DET_SMPL_CON_DET_PULLUP_60kohm = (2 << 5), + CON_DET_SMPL_CON_DET_PULLUP_80kohm = (3 << 5), + CON_DET_SMPL_SMPL_DUR_mask = (3 << 3), + CON_DET_SMPL_SMPL_DUR_15us = (0 << 3), + CON_DET_SMPL_SMPL_DUR_70us = (1 << 3), + CON_DET_SMPL_SMPL_DUR_130us = (2 << 3), + CON_DET_SMPL_SMPL_DUR_260us = (3 << 3), + CON_DET_SMPL_SMPL_RATE_mask = (3 << 1), + CON_DET_SMPL_SMPL_RATE_660Hz = (0 << 1), + CON_DET_SMPL_SMPL_RATE_265Hz = (1 << 1), + CON_DET_SMPL_SMPL_RATE_130Hz = (2 << 1), + CON_DET_SMPL_SMPL_RATE_70Hz = (3 << 1), + CON_DET_SMPL_SMPL_MODE_mask = (1 << 0), + CON_DET_SMPL_SMPL_MODE_TriStar2 = (0 << 0), + CON_DET_SMPL_SMPL_MODE_TriStar1 = (1 << 0), + + RD_FIFO = 0x1F, + + FIFO0 = 0x20, + FIFO63 = 0x5F, + FIFO_LEN = (FIFO63 - FIFO0 + 1), + + FIFO_MTP2_TIMING = 0x20, + FIFO_KEY_CTRL = 0x21, + FIFO_KEY_CTRL_LOCK_REQ = (1 << 5), + FIFO_KEY_CTRL_ESN = (1 << 4), + FIFO_KEY_CTRL_KEY2_2 = (1 << 3), + FIFO_KEY_CTRL_KEY2_1 = (1 << 2), + FIFO_KEY_CTRL_KEY1_2 = (1 << 1), + FIFO_KEY_CTRL_KEY1_1 = (1 << 0), + FIFO_KEY_ESN_BYTE0 = 0x22, + FIFO_KEY_ESN_BYTE1 = 0x23, + FIFO_KEY_ESN_BYTE2 = 0x24, + FIFO_KEY_ESN_BYTE3 = 0x25, + FIFO_KEY_ESN_BYTE4 = 0x26, + FIFO_KEY_ESN_BYTE5 = 0x27, + FIFO_KEY_ESN_BYTE6 = 0x28, + FIFO_KEY_ESN_BYTE7 = 0x29, + FIFO_MTP2_PRG_CTRL = 0x2E, + FIFO_ENONCE_M_BYTE0 = 0x49, + FIFO_ENONCE_M_BYTE1 = 0x50, + FIFO_ENONCE_M_BYTE2 = 0x51, + FIFO_ENONCE_M_BYTE3 = 0x52, + FIFO_ENONCE_M_BYTE4 = 0x53, + FIFO_ENONCE_M_BYTE5 = 0x54, + FIFO_ENONCE_M_BYTE6 = 0x55, + FIFO_ENONCE_M_BYTE7 = 0x56, + FIFO_ESN_BYTE0 = 0x57, + FIFO_ESN_BYTE1 = 0x58, + FIFO_ESN_BYTE2 = 0x59, + FIFO_ESN_BYTE3 = 0x5A, + FIFO_ESN_BYTE4 = 0x5B, + FIFO_ESN_BYTE5 = 0x5C, + FIFO_ESN_BYTE6 = 0x5D, + FIFO_ESN_BYTE7 = 0x5E, + + FIFO_CTRL1 = 0x60, + FIFO_CTRL1_ULIMITED_RX = (1 << 7), + FIFO_CTRL1_RESP_LENGTH_shift = (1), + FIFO_CTRL1_RESP_LENGTH_mask = (63 << FIFO_CTRL1_RESP_LENGTH_shift), + FIFO_CTRL1_RD_TRIG_LVL_shift = (1), + FIFO_CTRL1_RD_TRIG_LVL_mask = (63 << FIFO_CTRL1_RD_TRIG_LVL_shift), + FIFO_CTRL1_CMD_KILL = (1 << 0), + + FIFO_CTRL0 = 0x61, + FIFO_CTRL0_CMD_LENGTH_shift = (1), + FIFO_CTRL0_CMD_LENGTH_mask = (63 << FIFO_CTRL0_CMD_LENGTH_shift), + FIFO_CTRL0_AID_CMD_SEND = (1 << 0), + + FIFO_FILL_STATUS = 0x62, + FIFO_FILL_STATUS_FIFO_RD_LVL_shift = (0), + FIFO_FILL_STATUS_FIFO_RD_LVL_mask = (127 << FIFO_FILL_STATUS_FIFO_RD_LVL_shift), +}; + +static int tristar_write(uint8_t reg, uint8_t value) +{ + uint8_t data[2] = { reg, value }; + return iic_write(TRISTAR_IIC_BUS, CBTL1610_ADDR_W, data, sizeof(data)); +} + +static int tristar_read(uint8_t reg, uint8_t *data) +{ + return iic_read(TRISTAR_IIC_BUS, CBTL1610_ADDR_R, ®, sizeof(reg), data, sizeof(uint8_t), IIC_NORMAL); +} + +bool cbtl1610_set_usb_brick_detect(int select) +{ + // check status to make sure cable is connected and determine orientation + uint8_t status; + if (tristar_read(STATUS0, &status) != 0) { + return false; + } + if ((status & STATUS0_CON_DET_L) || !(status & STATUS0_IDBUS_CONNECTED)) { + return false; + } + bool orient = (status & STATUS0_IDBUS_ORIENT) == STATUS0_IDBUS_ORIENT; + + // check ID to find out if USB is supported + uint8_t dig_id; + if (tristar_read(DIG_ID, &dig_id) != 0) { + return false; + } + // only Dx=1 or Dx=2 have USB device mode + if (((dig_id & DIG_ID_Dx0) != 0) == ((dig_id & DIG_ID_Dx1) != 0)) { + return false; + } + + uint8_t dxctrl; + uint8_t dcp_ctrl; + + switch (select) { + case kUSB_DP: + case kUSB_CP2: + dxctrl = orient ? (DXCTRL_DX2OVRD | DXCTRL_DPDN2SW_brick_id_p) : (DXCTRL_DX1OVRD | DXCTRL_DPDN1SW_brick_id_p); + break; + + case kUSB_DM: + case kUSB_CP1: + dxctrl = orient ? (DXCTRL_DX2OVRD | DXCTRL_DPDN2SW_brick_id_n) : (DXCTRL_DX1OVRD | DXCTRL_DPDN1SW_brick_id_n); + break; + + case kUSB_NONE: + dxctrl = 0; + break; + + default: + return false; + } + + if (select == kUSB_CP1) { + dcp_ctrl = DCP_CTRL_IDXSINKEN | (orient ? DCP_CTRL_VDXSRCSW_dp2 : DCP_CTRL_VDXSRCSW_dp1); + } else if (select == kUSB_CP2) { + dcp_ctrl = DCP_CTRL_IDXSINKEN | (orient ? DCP_CTRL_VDXSRCSW_dn2 : DCP_CTRL_VDXSRCSW_dn1); + } else { + dcp_ctrl = 0; + } + + tristar_write(DCP_CTRL, dcp_ctrl); + tristar_write(DXCTRL, dxctrl); + + return true; +} + +bool cbtl1610_read_id(uint8_t digital_id[6]) +{ + // check status to make sure cable is connected and ID bus is connected + uint8_t status; + if (tristar_read(STATUS0, &status) != 0) { + return false; + } + if ((status & STATUS0_CON_DET_L) || !(status & STATUS0_IDBUS_CONNECTED)) { + return false; + } + + // FIFO should contain the ID response + uint8_t resp; + if (tristar_read(FIFO0, &resp) != 0) { + return false; + } + + if (resp != 0x75) { + return false; + } + + // read ID + for (int i = 0; i < 6; i++) { + if (tristar_read(FIFO0 + i + 1, &digital_id[i])) { + return false; + } + } + + return true; +} + +bool cbtl1610_enable_acc_pwr(bool enabled) +{ + if (enabled) { + tristar_write(ACC_CTRL, ACC_CTRL_ACC2SW_acc_pwr | ACC_CTRL_ACC1SW_acc_pwr); + } + + power_enable_ldo(ACC_PWR_LDO, enabled); + + if (!enabled) { + tristar_write(ACC_CTRL, 0); + } + + return true; +} + +#if WITH_HW_TRISTAR_THS7383 + +extern bool target_has_tristar2(void); +extern bool ths7383_set_usb_brick_detect(int select); +extern bool ths7383_read_id(uint8_t digital_id[6]); +extern bool ths7383_enable_acc_pwr(bool enabled); + +bool tristar_set_usb_brick_detect(int select) +{ + return target_has_tristar2() ? cbtl1610_set_usb_brick_detect(select) : ths7383_set_usb_brick_detect(select); +} + +bool tristar_read_id(uint8_t digital_id[6]) +{ + return target_has_tristar2() ? cbtl1610_read_id(digital_id) : ths7383_read_id(digital_id); +} + +bool tristar_enable_acc_pwr(bool enabled) +{ + return target_has_tristar2() ? cbtl1610_enable_acc_pwr(enabled) : ths7383_enable_acc_pwr(enabled); +} + +#else // !WITH_HW_TRISTAR_THS7383 + +bool tristar_set_usb_brick_detect(int select) +{ + return cbtl1610_set_usb_brick_detect(select); +} + +bool tristar_read_id(uint8_t digital_id[6]) +{ + return cbtl1610_read_id(digital_id); +} + +bool tristar_enable_acc_pwr(bool enabled) +{ + return cbtl1610_enable_acc_pwr(enabled); +} + +#endif // WITH_HW_TRISTAR_THS7383 \ No newline at end of file diff --git a/drivers/nxp/cbtl1610/rules.mk b/drivers/nxp/cbtl1610/rules.mk new file mode 100644 index 0000000..abcff44 --- /dev/null +++ b/drivers/nxp/cbtl1610/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2011 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_TRISTAR_CBTL1610=1 \ + WITH_HW_TRISTAR=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/cbtl1610.o diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c new file mode 100644 index 0000000..f828f01 --- /dev/null +++ b/drivers/pci/pci.c @@ -0,0 +1,1379 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "pci_private.h" + +#define PDBG_REG DEBUG_SPEW +#define PDBG_SPEW DEBUG_SPEW +#define PDBG_PROBE DEBUG_SPEW +#define PDBG_MAP DEBUG_SPEW + +pci_device_t pci_bridges[256]; + +void pci_init(void) +{ + platform_register_pci_busses(); +} + +static void pci_register_bridge(pci_device_t bridge) +{ + ASSERT(pci_bridges[bridge->secondary_bus] == NULL); + + pci_bridges[bridge->secondary_bus] = bridge; +} + +static void pci_unregister_bridge(pci_device_t bridge) +{ + ASSERT(pci_bridges[bridge->secondary_bus] != NULL); + + pci_bridges[bridge->secondary_bus] = NULL; +} + +pci_device_t pci_create_host_bridge(const char *name, uint8_t bus_num, uint32_t memory_base, uint32_t memory_size, void *priv, pci_config_read_cb_t read_cb, pci_config_write_cb_t write_cb) +{ + pci_device_t new_bridge; + + new_bridge = calloc(sizeof(*new_bridge), 1); + + strlcpy(new_bridge->name, name, sizeof(new_bridge->name)); + new_bridge->secondary_bus = bus_num; + new_bridge->subordinate_bus = bus_num; + new_bridge->memory_base = memory_base; + new_bridge->memory_size = memory_size; + new_bridge->memory_allocated = 0; + new_bridge->config_read = read_cb; + new_bridge->config_write = write_cb; + new_bridge->bridge_priv = priv; + + pci_register_bridge(new_bridge); + + return new_bridge; +} + +// When the host bridge's last child goes away, reset all of the +// allocations to 0, allowing us to reprobe under the host bridge +// again if needed +static void pci_reinitialize_host_bridge(pci_device_t host_bridge) +{ + ASSERT(host_bridge->num_children == 0); + ASSERT(host_bridge->bridge == NULL); + + host_bridge->subordinate_bus = host_bridge->secondary_bus; + host_bridge->memory_allocated = 0; +} + +// 8 bit wide read from the given device/offset under the given bridge +// Function is assumed to be 0 (no multi-function devices) +static uint8_t pci_bridge_config_read8(pci_device_t bridge, uint8_t device_num, uint16_t offset) +{ + uint8_t value; + uint32_t bdfo = PCI_BDFO(bridge->secondary_bus, device_num, 0, offset); + bridge->config_read(bridge->bridge_priv, &value, bdfo, 1); + + dprintf(PDBG_REG, "pci(%02x:%02x:00): 8-bit config read 0x%04x -> 0x%02x\n", + bridge->secondary_bus, device_num, offset, value); + + return value; +} + +// 16 bit wide read from the given device/offset under the given bridge +// Function is assumed to be 0 (no multi-function devices) +static uint16_t pci_bridge_config_read16(pci_device_t bridge, uint8_t device_num, uint16_t offset) +{ + uint16_t value; + uint32_t bdfo = PCI_BDFO(bridge->secondary_bus, device_num, 0, offset); + bridge->config_read(bridge->bridge_priv, &value, bdfo, 2); + + dprintf(PDBG_REG, "pci(%02x:%02x:00): 16-bit config read 0x%04x -> 0x%04x\n", + bridge->secondary_bus, device_num, offset, value); + + return value; +} + +// 32 bit wide read from the given device/offset under the given bridge +// Function is assumed to be 0 (no multi-function devices) +static uint32_t pci_bridge_config_read32(pci_device_t bridge, uint8_t device_num, uint16_t offset) +{ + uint32_t value; + uint32_t bdfo = PCI_BDFO(bridge->secondary_bus, device_num, 0, offset); + bridge->config_read(bridge->bridge_priv, &value, bdfo, 4); + + dprintf(PDBG_REG, "pci(%02x:%02x:00): 32-bit config read 0x%04x -> 0x%08x\n", + bridge->secondary_bus, device_num, offset, value); + + return value; +} + +// 8 bit wide write to the given device/offset under the given bridge +// Function is assumed to be 0 (no multi-function devices) +static void pci_bridge_config_write8(pci_device_t bridge, uint8_t device_num, uint16_t offset, uint8_t value) +{ + uint32_t bdfo = PCI_BDFO(bridge->secondary_bus, device_num, 0, offset); + + dprintf(PDBG_REG, "pci(%02x:%02x:00): 8-bit config write 0x%04x <- 0x%02x\n", + bridge->secondary_bus, device_num, offset, value); + + bridge->config_write(bridge->bridge_priv, &value, bdfo, 1); +} + +// 16 bit wide write to the given device/offset under the given bridge +// Function is assumed to be 0 (no multi-function devices) +static void pci_bridge_config_write16(pci_device_t bridge, uint8_t device_num, uint16_t offset, uint16_t value) +{ + uint32_t bdfo = PCI_BDFO(bridge->secondary_bus, device_num, 0, offset); + + dprintf(PDBG_REG, "pci(%02x:%02x:00): 16-bit config write 0x%04x <- 0x%04x\n", + bridge->secondary_bus, device_num, offset, value); + + bridge->config_write(bridge->bridge_priv, &value, bdfo, 2); +} + +// 32 bit wide write to the given device/offset under the given bridge +// Function is assumed to be 0 (no multi-function devices) +static void pci_bridge_config_write32(pci_device_t bridge, uint8_t device_num, uint16_t offset, uint32_t value) +{ + uint32_t bdfo = PCI_BDFO(bridge->secondary_bus, device_num, 0, offset); + + dprintf(PDBG_REG, "pci(%02x:%02x:00): 32-bit config write 0x%04x <- 0x%08x\n", + bridge->secondary_bus, device_num, offset, value); + + bridge->config_write(bridge->bridge_priv, &value, bdfo, 4); +} + +pci_device_t pci_bridge_probe(pci_device_t bridge, uint8_t device_num, utime_t timeout) +{ + pci_device_t new_dev; + utime_t start_time; + uint8_t bus_num; + uint32_t idreg; + uint16_t pcie_cap; + + if (bridge->devices[device_num] != NULL) + return bridge->devices[device_num]; + + bus_num = bridge->secondary_bus; + + dprintf(PDBG_PROBE, "pci(%02x:%02x:00): probe start\n", bus_num, device_num); + + start_time = system_time(); + do { + idreg = pci_bridge_config_read32(bridge, device_num, PCI_CONFIG_VENDOR_ID); + if ((idreg != 0xffffffff) && (idreg != 0xffff0001)) + break; + } while (!time_has_elapsed(start_time, timeout)); + + if ((idreg == 0xffffffff) || (idreg == 0xffff0001)) { + dprintf(PDBG_PROBE, "pci(%02x:%02x:00): probe timeout\n", bus_num, device_num); + return NULL; + } + + new_dev = calloc(sizeof(*new_dev), 1); + + new_dev->bridge = bridge; + new_dev->device_num = device_num; + snprintf(new_dev->name, sizeof(new_dev->name), "%02x:%02x:%02x", bus_num, device_num, 0); + + // it's safe to use the pci_config_read_XXX functions from here forwards on new_dev + + new_dev->vendor_id = idreg & 0xffff; + new_dev->device_id = (idreg >> 16) & 0xffff; + + idreg = pci_config_read32(new_dev, PCI_CONFIG_REVISION_ID); + new_dev->revision_id = (idreg & 0xff); + new_dev->class_code = ((idreg >> 8) & 0xffffff); + + idreg = pci_config_read8(new_dev, PCI_CONFIG_HEADER_TYPE); + new_dev->header_type = idreg & 0x7f; + new_dev->multifunction = (idreg & 0x80) != 0; + if (new_dev->header_type != 0 && new_dev->header_type != 1) { + dprintf(DEBUG_CRITICAL, "PCI device has unknown header type %d\n", idreg); + dprintf(DEBUG_CRITICAL, "pci(%s): unknown header type %d\n", new_dev->name, idreg); + goto error; + } + + dprintf(PDBG_PROBE, "pci(%s): probed id %04x:%04x rev %02x type %02x class %06x\n", + new_dev->name, new_dev->vendor_id, new_dev->device_id, new_dev->revision_id, + new_dev->header_type, new_dev->class_code); + + if (new_dev->header_type == 0) { + new_dev->num_bars = 6; + } else { + new_dev->num_bars = 2; + // Bridges inherit the config read callbacks from their parents + new_dev->config_read = bridge->config_read; + new_dev->config_write = bridge->config_write; + new_dev->bridge_priv = bridge->bridge_priv; + // And a bridge's primary bus is its parent's secondary bus + new_dev->primary_bus = bus_num; + } + + for (uint32_t i = 0; i < new_dev->num_bars; i++) { + uint32_t bar; + uint32_t original; + uint32_t masked; + uint32_t type; + uint64_t bar_size; + bool is_64; + + bar = PCI_CONFIG_BASE_ADDRESS0 + 4 * i; + + original = pci_config_read32(new_dev, bar); + pci_config_write32(new_dev, bar, 0xffffffff); + masked = pci_config_read32(new_dev, bar); + pci_config_write32(new_dev, bar, original); + + // 0 is unimplemented + if (masked == 0) { + dprintf(PDBG_SPEW, " bar %u unimplemented\n", i); + continue; + } + + // We don't support I/O BARs + if ((masked & 1) != 0) { + dprintf(PDBG_SPEW, " bar %u I/O\n", i); + continue; + } + + type = (masked & 0xf) >> 1; + // type 1 needs to be below 1 MiB, which we don't support, and type 3 is reserved + if (type == 1 || type == 3) { + dprintf(PDBG_SPEW, " bar %u unknown type %u\n", i, type); + continue; + } + + // type 2 is 64-bit + if (type == 2) { + uint64_t masked2; + + // 64-bit is only valid on even BARs + if (i % 2 != 0) + continue; + + original = pci_config_read32(new_dev, bar + 4); + pci_config_write32(new_dev, bar + 4, 0xffffffff); + masked2 = pci_config_read32(new_dev, bar + 4); + pci_config_write32(new_dev, bar + 4, original); + + masked2 <<= 32; + masked2 |= masked; + + bar_size = ~(masked2 & ~0xfULL) + 1; + is_64 = true; + // Mark the next bar as being part of this one + new_dev->bar_64bit[i+1] = true; + } else { + bar_size = ~(masked & ~0xf) + 1; + is_64 = false; + } + + new_dev->bar_size[i] = bar_size; + new_dev->bar_64bit[i] = is_64; + + dprintf(PDBG_PROBE, " bar %u size 0x%llx%s\n", i, bar_size, is_64 ? " (64-bit)" : ""); + + // skip reading the next BAR because we just did it + if (is_64) + i++; + } + + pcie_cap = pci_find_capability(new_dev, PCI_CAP_ID_PCIE); + if (pcie_cap != 0) { + uint16_t cap; + cap = pci_config_read16(new_dev, pcie_cap + PCI_PCIE_CAP_PCIE_CAPABILITIES); + new_dev->pcie_device_port_type = (cap >> 4) & 0xf; + } else { + new_dev->pcie_device_port_type = PCI_PCIE_TYPE_UNKNOWN; + } + + bridge->devices[device_num] = new_dev; + bridge->num_children++; + + return new_dev; + +error: + free(new_dev); + return NULL; +} + +// Called after pci_bridge_probe finds a device that's a bridge in order to set +// the new bridge's secondary and subordinate bus number registers and adjust the +// subordinate bus numbers up the chain so that the new bridge's secondary bus +// is visible to the host bridge +void pci_bridge_assign_secondary_bus(pci_device_t bridge) +{ + pci_device_t parent; + uint8_t parent_subordinate; + + ASSERT(pci_is_bridge(bridge)); + // Can only be called once for a bridge + ASSERT(bridge->secondary_bus == 0); + ASSERT(bridge->subordinate_bus == 0); + // And can't be called on the host bridge + ASSERT(bridge->bridge != NULL); + + parent = bridge->bridge; + parent_subordinate = parent->subordinate_bus; + + // Oops, we're out of buses! + ASSERT(parent_subordinate != 255); + + dprintf(PDBG_MAP, "pci(%s): setting bridge secondary bus 0x%02x\n", + parent->name, parent_subordinate + 1); + + // Bridges start with just their secondary bus under them, more + // probing is needed before giving it control of more buses + bridge->secondary_bus = parent_subordinate + 1; + bridge->subordinate_bus = parent_subordinate + 1; + pci_config_write8(bridge, PCI_CONFIG_SECONDARY_BUS_NUMBER, bridge->secondary_bus); + pci_config_write8(bridge, PCI_CONFIG_SUBORDINATE_BUS_NUMBER, bridge->subordinate_bus); + + // Walk the chain of bridges up to the host bridge, bumping everyone's + // subordinate bus number so that they can see the new bus + while(parent != NULL) { + // If the subordinate buses don't match going all the way up the chain, + // then someone is allocating buses out of order, which can lead to overlap + ASSERT(parent->subordinate_bus == parent_subordinate); + + parent->subordinate_bus = parent_subordinate + 1; + + // Host bridges don't have PCI2PCI bridge registers, but everyone else should + if (parent->bridge != NULL) { + dprintf(PDBG_MAP, "pci(%s): setting bridge bus range %02x:%02x\n", + parent->name, parent->secondary_bus, parent->subordinate_bus); + pci_config_write8(parent, PCI_CONFIG_SUBORDINATE_BUS_NUMBER, parent->subordinate_bus); + } + + parent = parent->bridge; + } + + // Now that we've claimed our secondary bus, register as its owner + pci_register_bridge(bridge); +} + +void pci_bridge_serr_enable(pci_device_t bridge, bool enable) +{ + uint16_t v = pci_config_read16(bridge, PCI_CONFIG_COMMAND); + + if (enable) + v |= PCI_CMD_SERR_ENABLE; + else + v &= ~PCI_CMD_SERR_ENABLE; + + pci_config_write16(bridge, PCI_CONFIG_COMMAND, v); + +} + +void pci_free(pci_device_t dev) +{ + unsigned i; + + for (i = 0; i < sizeof(dev->devices) / sizeof(dev->devices[0]); i++) { + if (dev->devices[i] != NULL) + panic("Freeing PCI bridge \"%s\" before its %uth child \"%s\"", + dev->name, i, dev->devices[i]->name); + } + + if (dev->bridge != NULL) { + dev->bridge->devices[dev->device_num] = NULL; + dev->bridge->num_children--; + // If we just killed the last child of the host bridge, reset the + // allocation trackers in the host bridge. This allows us to reconfigure + // the PCIe system by tearing down all devices and then reprobing from + // the host bridge down. We don't support more complicated reconfiguration. + if (dev->bridge->bridge == NULL && dev->bridge->num_children == 0) { + pci_reinitialize_host_bridge(dev->bridge); + } + + } + + if (pci_is_bridge(dev) && dev->bridge != NULL) + pci_unregister_bridge(dev); + + free(dev); +} + +uint8_t pci_config_read8(pci_device_t dev, uint16_t offset) +{ + pci_device_t bridge; + bridge = dev->bridge; + ASSERT(bridge != NULL); + + return pci_bridge_config_read8(bridge, dev->device_num, offset); +} + +uint16_t pci_config_read16(pci_device_t dev, uint16_t offset) +{ + pci_device_t bridge; + bridge = dev->bridge; + ASSERT(bridge != NULL); + + return pci_bridge_config_read16(bridge, dev->device_num, offset); +} + +uint32_t pci_config_read32(pci_device_t dev, uint16_t offset) +{ + pci_device_t bridge; + bridge = dev->bridge; + ASSERT(bridge != NULL); + + return pci_bridge_config_read32(bridge, dev->device_num, offset); +} + +void pci_config_write8(pci_device_t dev, uint16_t offset, uint8_t value) +{ + pci_device_t bridge; + bridge = dev->bridge; + ASSERT(bridge != NULL); + + pci_bridge_config_write8(bridge, dev->device_num, offset, value); +} + +void pci_config_write16(pci_device_t dev, uint16_t offset, uint16_t value) +{ + pci_device_t bridge; + bridge = dev->bridge; + ASSERT(bridge != NULL); + + pci_bridge_config_write16(dev->bridge, dev->device_num, offset, value); +} + +void pci_config_write32(pci_device_t dev, uint16_t offset, uint32_t value) +{ + pci_device_t bridge; + bridge = dev->bridge; + ASSERT(bridge != NULL); + + pci_bridge_config_write32(bridge, dev->device_num, offset, value); +} + +bool pci_is_bridge(pci_device_t dev) +{ + return dev->header_type == 1; +} + +const char *pci_get_name(pci_device_t dev) +{ + ASSERT(dev != NULL); + return dev->name; +} + +void pci_set_name(pci_device_t dev, const char *name) +{ + ASSERT(strlen(name) < sizeof(dev->name)); + + strlcpy(dev->name, name, sizeof(dev->name)); +} + +pci_device_t pci_get_bridge(pci_device_t dev) +{ + ASSERT(dev != NULL); + return dev->bridge; +} + +uint16_t pci_get_vendor_id(pci_device_t dev) +{ + ASSERT(dev != NULL); + return dev->vendor_id; +} + +uint16_t pci_get_device_id(pci_device_t dev) +{ + ASSERT(dev != NULL); + return dev->device_id; +} + +uint32_t pci_get_class_code(pci_device_t dev) +{ + ASSERT(dev != NULL); + return dev->class_code; +} + +uint8_t pci_get_revision_id(pci_device_t dev) +{ + ASSERT(dev != NULL); + return dev->revision_id; +} + +uint8_t pci_get_header_type(pci_device_t dev) +{ + ASSERT(dev != NULL); + return dev->header_type; +} + +void pci_memory_space_enable(pci_device_t dev, bool enable) +{ + uint16_t cmd = pci_config_read16(dev, PCI_CONFIG_COMMAND); + + if (enable) + cmd |= PCI_CMD_MEMORY_SPACE_ENABLE; + else + cmd &= ~PCI_CMD_MEMORY_SPACE_ENABLE; + + pci_config_write16(dev, PCI_CONFIG_COMMAND, cmd); +} + +void pci_bus_master_enable(pci_device_t dev, bool enable) +{ + uint16_t cmd = pci_config_read16(dev, PCI_CONFIG_COMMAND); + + if (enable) + cmd |= PCI_CMD_BUS_MASTER_ENABLE; + else + cmd &= ~PCI_CMD_BUS_MASTER_ENABLE; + + pci_config_write16(dev, PCI_CONFIG_COMMAND, cmd); +} + +uint64_t pci_get_bar_size(pci_device_t dev, unsigned bar_idx) +{ + ASSERT(dev != NULL); + ASSERT(bar_idx < 6); + ASSERT(dev->header_type == 0 || bar_idx < 2); + return dev->bar_size[bar_idx]; +} + +// This function is recursive, but we shouldn't ever have a deep enough hierarchy to +// run into issues +// There is an assumption in this function that bridges never make allocations from their +// BARs. If that assumption is false, things could get dicey +static bool pci_bridge_expand_memory_space(pci_device_t bridge, uint64_t new_size) +{ + pci_device_t parent; + uint64_t needed; + uint64_t parent_starting_allocation; + + parent = bridge->bridge; + + needed = new_size - bridge->memory_size; + + if (parent != NULL) + dprintf(PDBG_MAP, "pci(%s): expanding bridge memory space to 0x%llx (0x%llx more)\n", + bridge->name, new_size, needed); + + // Do a a sanity check to make sure the allocation amounts agree all + // the way up to the host bridge. If a child bridge's base + size isn't equal to + // its parent bridge's base + allocated, someone is doing allocations out + // of order, and we're hosed. Of course, if nothing has been allocated on + // this bridge, we're ok + if (parent != NULL) { + parent_starting_allocation = parent->memory_allocated; + + if (bridge->memory_size != 0) { + uint64_t bridge_limit = bridge->memory_base + bridge->memory_size; + uint64_t parent_limit = parent->memory_base + parent->memory_allocated; + if (bridge_limit != parent_limit) { + ASSERT(false /* out of order allocations */); + return false; + } + } + + if (!pci_bridge_expand_memory_space(parent, parent->memory_size + needed)) + return false; + } else if (parent == NULL) { + // If we're at the host bridge, make sure it still has addresses left to vend + if (bridge->memory_allocated + needed > bridge->memory_size) { + ASSERT(false /* PCI address space exhausted */); + return false; + } + + // We're good, update the host bridge's counter of allocated memory + bridge->memory_allocated = new_size; + + return true; + } + + // Recursion above finished, we're now unwinding the stack. Everything looks reasonable, + // so go ahead and expand the memory space size. We'll be doing this in reverse order from + // the checks above, doing the host bridge first and walking back down the hierarchy. + // By modifying parent->allocated and bridge->size, we make sure that we don't ever change + // the size of the host bridge's memory_size (which is not PCI-configurable). + // It'll also make sure that there's a chunk that's unallocated in the deepest bridge (the + // one for which this request was made to begin with) + + // But first, if we've never had an allocation, we need to set our base + if (bridge->memory_base == 0) { + bridge->memory_base = parent->memory_base + parent_starting_allocation; + dprintf(PDBG_MAP, "pci(%s): setting bridge memory base 0x%x\n", + bridge->name, bridge->memory_base); + pci_config_write16(bridge, PCI_CONFIG_MEMORY_BASE, (bridge->memory_base >> 16) & ~0xfU); + } + + // Now update our limit to reflect the new size + parent->memory_allocated += needed; + bridge->memory_size += needed; + + dprintf(PDBG_MAP, "pci(%s): setting bridge memory range %08x:%08x\n", + parent->name, bridge->memory_base, bridge->memory_base + bridge->memory_size - 1); + + pci_config_write16(bridge, PCI_CONFIG_MEMORY_LIMIT, + ((bridge->memory_base + bridge->memory_size - 1) >> 16) & ~0xfU); + + // Disable the prefetchable memory base/limit bridge memory range. + pci_config_write16(bridge, PCI_CONFIG_PREFETCHABLE_BASE, 0xFFF0); + pci_config_write16(bridge, PCI_CONFIG_PREFETCHABLE_LIMIT, 0x0000); + + return true; +} + +uintptr_t pci_map_bar(pci_device_t dev, unsigned bar_idx) +{ + pci_device_t bridge; + uint64_t pci_addr; + uintptr_t host_addr; + uint64_t bar_size; + uint64_t allocated; + uint32_t bar_offset; + + ASSERT(bar_idx < dev->num_bars); + // 64-bit BARs can only be even-numbered + if (dev->bar_64bit[bar_idx] && bar_idx % 2 != 0) { + dprintf(DEBUG_CRITICAL, "pci(%s): trying to map odd portion %u of 64-bit bar\n", + dev->name, bar_idx); + return 0; + } + + // BARs can only be mapped once + ASSERT(dev->bar_host_addr[bar_idx] == 0); + + // Make sure the BAR is implemented + bar_size = dev->bar_size[bar_idx]; + if (bar_size == 0) { + dprintf(DEBUG_CRITICAL, "pci(%s): trying to map unimplemented bar %u\n", + dev->name, bar_idx); + return 0; + } + + dprintf(PDBG_MAP, "pci(%s): trying to map bar %u size 0x%llx\n", + dev->name, bar_idx, bar_size); + + bridge = dev->bridge; + + // Figure out how much of the bridge's allocation is used. BARs mappings need to + // be aligned to their size, so if the allocation isn't a multiple of this mapping's + // size, we'll need to mark a bunch of address space as used to make us aligned again + allocated = bridge->memory_allocated; + if (((bar_size - 1) & allocated) != 0) + allocated += bar_size - (allocated & (bar_size - 1)); + + // Can we fit this BAR into the space we already have allocated? + if (allocated + bar_size > bridge->memory_size) { + uint64_t bridge_allocation; + // Putain, we are out of space. We're going to need to ask our ancestors for + // more space. Bridges allocate in 1MB chunks, so start by rounding up + bridge_allocation = allocated + bar_size; + bridge_allocation = (bridge_allocation + 0x100000 - 1) & ~(0x100000ULL - 1); + + dprintf(PDBG_MAP, "pci(%s): 0x%x memory space, 0x%x used (0x%llx aligned)\n", + bridge->name, bridge->memory_size, bridge->memory_allocated, allocated); + + // Ask for our memory space size to be bumped up + if (!pci_bridge_expand_memory_space(bridge, bridge_allocation)) { + dprintf(DEBUG_CRITICAL, "pci(%s): couldn't allocate bridge memory space\n", bridge->name); + return 0; + } + } + + // The bridge has enough memory space, so we'll tack this BAR at the end + // of the allocated region + pci_addr = bridge->memory_base + allocated; + host_addr = platform_map_pci_to_host_addr(pci_addr); + // And then mark the addresses we used as claimed + bridge->memory_allocated = allocated + bar_size; + + dev->bar_pci_addr[bar_idx] = pci_addr; + dev->bar_host_addr[bar_idx] = host_addr; + + dprintf(PDBG_MAP, "pci(%s): mapping bar %u at 0x%llx (host %p) size 0x%llx\n", + dev->name, bar_idx, pci_addr, (void *)host_addr, bar_size); + + bar_offset = PCI_CONFIG_BASE_ADDRESS0 + (4 * bar_idx); + pci_config_write32(dev, bar_offset, (uint32_t)pci_addr); + if (dev->bar_64bit[bar_idx]) + pci_config_write32(dev, bar_offset + 4, (uint32_t)(pci_addr >> 32)); + + return host_addr; +} + +uint16_t pci_find_capability(pci_device_t dev, uint16_t capability_id) +{ + uint16_t status; + uint8_t cap_pointer; + uint16_t id_and_next; + uint8_t this_cap_id; + + // See if we've already cached the offset for a common capability + if (capability_id == PCI_CAP_ID_PM && dev->pm_cap_offset != 0) + return dev->pm_cap_offset; + if (capability_id == PCI_CAP_ID_PCIE && dev->pcie_cap_offset != 0) + return dev->pcie_cap_offset; + + if (dev->first_cap_offset == 0) { + status = pci_config_read16(dev, PCI_CONFIG_STATUS); + if (status == 0xFFFF || (status & PCI_STATUS_CAPABILITIES_LIST) == 0) { + dprintf(DEBUG_INFO, "pci(%s): no capability list\n", dev->name); + return 0; + } + + cap_pointer = pci_config_read8(dev, PCI_CONFIG_CAPABILITIES_PTR); + cap_pointer &= 0xFC; + + if (cap_pointer >= 0x40 && cap_pointer != 0xfc) + dev->first_cap_offset = cap_pointer; + } else { + cap_pointer = dev->first_cap_offset; + } + + while (cap_pointer >= 0x40 && cap_pointer != 0xfc) { + id_and_next = pci_config_read16(dev, cap_pointer); + this_cap_id = (id_and_next & 0xFF); + + // Cache the offsets for common capabilities + if (this_cap_id == PCI_CAP_ID_PM) + dev->pm_cap_offset = cap_pointer; + else if (this_cap_id == PCI_CAP_ID_PCIE) + dev->pcie_cap_offset = cap_pointer; + + if (this_cap_id == capability_id) + return cap_pointer; + + cap_pointer = (id_and_next >> 8) & 0xFC; + } + + dprintf(DEBUG_INFO, "pci(%s): capability 0x%02x not found\n", dev->name, capability_id); + + return 0; +} + +uint16_t pci_find_extended_capability(pci_device_t dev, uint16_t capability_id, uint8_t min_version) +{ + uint32_t header; + uint16_t header_id; + uint8_t header_version; + uint16_t header_pointer; + uint16_t next_pointer; + + header_pointer = 0x100; + + do { + header = pci_config_read32(dev, header_pointer); + if (header == 0 || header == 0xFFFFFFFF) + break; + + header_id = header & 0xFFFF; + header_version = (header >> 16) & 0xF; + next_pointer = (header >> 20) & 0xFFC; + + dprintf(PDBG_PROBE, "found ecap %04x at %04x next %04x\n", header_id, header_pointer, next_pointer); + + if (header_id == capability_id && header_version >= min_version) + return header_pointer; + + header_pointer = next_pointer; + } while (header_pointer != 0); + + return 0; +} + +void pci_set_powerstate(pci_device_t dev, uint8_t powerstate) +{ + uint16_t pme_cap; + uint16_t pmcsr; + + pme_cap = pci_find_capability(dev, PCI_CAP_ID_PM); + if (pme_cap != 0) { + uint32_t offset = pme_cap + PCI_PM_CAP_PMCSR; + + pmcsr = pci_config_read16(dev, offset); + pmcsr = (pmcsr & ~3) | (powerstate & 3); + pci_config_write16(dev, offset, pmcsr); + } +} + +bool pci_enable_pcie_ltr(pci_device_t dev) +{ + uint32_t pcie_offset; + uint32_t ltr_offset; + uint32_t cap2 = 0; + uint32_t control2; + + // The host bridge doesn't have any associated PCIe config space; it's just + // an abstraction for the hardware that translates fabric requests into PCIe + // requests. Return true here to end the recursion below + if (dev->bridge == NULL) + return true; + + pcie_offset = pci_find_capability(dev, PCI_CAP_ID_PCIE); + if (pcie_offset == 0) { + dprintf(DEBUG_INFO, "pci: %s: can't enable LTR on non-PCIe endpoint\n", dev->name); + return false; + } + + cap2 = pci_config_read32(dev, pcie_offset + PCI_PCIE_CAP_DEVICE_CAPABILITIES2); + if ((cap2 & (1 << 11)) == 0) { + dprintf(DEBUG_INFO, "pci: %s: LTR not supported\n", dev->name); + return false; + } + + if (dev->pcie_device_port_type == PCI_PCIE_TYPE_ENDPOINT || + dev->pcie_device_port_type == PCI_PCIE_TYPE_UPSTREAM) { + ltr_offset = pci_find_extended_capability(dev, PCI_EXT_CAP_ID_LTR, 1); + if (ltr_offset == 0) { + dprintf(DEBUG_INFO, "pci: %s: LTR capability not found\n", dev->name); + return false; + } + } else { + ltr_offset = 0; + } + + if (!pci_enable_pcie_ltr(dev->bridge)) + return false; + + control2 = pci_config_read32(dev, pcie_offset + PCI_PCIE_CAP_DEVICE_CONTROL2); + control2 |= (1 << 10); + pci_config_write32(dev, pcie_offset + PCI_PCIE_CAP_DEVICE_CONTROL2, control2); + + // Set a reasonable default for the max LTR value. As far as we can tell, this + // is a pretty meaningless parameter, so we're just hardcoding it for now until + // there's an actual reason to set it to something specific. This capability + // is only present in ports that face upstream + if (ltr_offset != 0) { + // scale of 32^4 = 1,048,576 ns and value of 8 works out to roughly 8 ms + // See PCIe r3.0 section 6.18 and section 7.25 + uint16_t max_latency = 8 | (4 << 10); + pci_config_write16(dev, ltr_offset + PCI_LTR_CAP_MAX_SNOOP_LATENCY, max_latency); + pci_config_write16(dev, ltr_offset + PCI_LTR_CAP_MAX_NO_SNOOP_LATENCY, max_latency); + } + + return true; +} + +void pci_enable_pcie_aspm(pci_device_t dev) +{ + pci_device_t bridge_dev; + uint32_t bridge_pcie_cap; + uint32_t endpoint_pcie_cap; + uint32_t bridge_link_cap; + uint32_t endpoint_link_cap; + uint32_t aspm_support; + uint16_t bridge_link_control; + uint16_t endpoint_link_control; + + bridge_dev = dev->bridge; + + bridge_pcie_cap = pci_find_capability(bridge_dev, PCI_CAP_ID_PCIE); + endpoint_pcie_cap = pci_find_capability(dev, PCI_CAP_ID_PCIE); + + if (bridge_pcie_cap == 0 || endpoint_pcie_cap == 0) { + dprintf(DEBUG_CRITICAL, "pci: %s: Can't enable ASPM, PCIe capability not found\n", dev->name); + return; + } + + bridge_link_cap = pci_config_read32(bridge_dev, bridge_pcie_cap + PCI_PCIE_CAP_LINK_CAPABILITIES); + endpoint_link_cap = pci_config_read32(dev, endpoint_pcie_cap + PCI_PCIE_CAP_LINK_CAPABILITIES); + + // Force enable ASPM+L1SS when S3E doesn't advertise support + // If we ever had to support endpoints other than S3E, we could conditionalize this on the + // S3E VID/PID. For now, this hack is good enough. + endpoint_link_cap |= (0x2 << 10); + + aspm_support = (bridge_link_cap >> 10) & (endpoint_link_cap >> 10) & 0x3; + + // ASPM must be supported at both ends of the link + if (aspm_support == 0) { + dprintf(DEBUG_CRITICAL, "pci: %s: Can't enable ASPM (bridge cap 0x%08x endpoint cap 0x%08x)\n", + dev->name, bridge_link_cap, endpoint_link_cap); + return; + } + + if (aspm_support) { + // PCIe requires us to enable L1 in the upstream port before enabling it downstream + bridge_link_control = pci_config_read16(bridge_dev, bridge_pcie_cap + PCI_PCIE_CAP_LINK_CONTROL); + bridge_link_control &= ~3; + bridge_link_control |= aspm_support; + pci_config_write16(bridge_dev, bridge_pcie_cap + PCI_PCIE_CAP_LINK_CONTROL, bridge_link_control); + + endpoint_link_control = pci_config_read16(dev, endpoint_pcie_cap + PCI_PCIE_CAP_LINK_CONTROL); + endpoint_link_control &= ~3; + endpoint_link_control |= aspm_support; + pci_config_write16(dev, endpoint_pcie_cap + PCI_PCIE_CAP_LINK_CONTROL, endpoint_link_control); + } +} + +void pci_set_pcie_common_clock(pci_device_t dev) +{ + pci_device_t bridge; + uint32_t bridge_offset; + uint32_t dev_offset; + uint32_t control; + + bridge = dev->bridge; + if (bridge == NULL || bridge->bridge == NULL) { + dprintf(DEBUG_CRITICAL, "pci: can't enable common clock on root port bridge\n"); + return; + } + + bridge_offset = pci_find_capability(bridge, PCI_CAP_ID_PCIE); + if (bridge_offset == 0) { + dprintf(DEBUG_CRITICAL, "pci: no express capability upstream\n"); + return; + } + dev_offset = pci_find_capability(dev, PCI_CAP_ID_PCIE); + if (dev_offset == 0) { + dprintf(DEBUG_CRITICAL, "pci: no express capability on endpoint\n"); + return; + } + + control = pci_config_read16(dev, dev_offset + PCI_PCIE_CAP_LINK_CONTROL); + control |= (1 << 6); + pci_config_write16(dev, dev_offset + PCI_PCIE_CAP_LINK_CONTROL, control); + + control = pci_config_read16(bridge, bridge_offset + PCI_PCIE_CAP_LINK_CONTROL); + control |= (1 << 6); + pci_config_write16(bridge, bridge_offset + PCI_PCIE_CAP_LINK_CONTROL, control); +} + +void pci_enable_pcie_cpm(pci_device_t dev) +{ + uint32_t pcie_cap; + uint16_t link_control; + + if (dev->bridge == NULL || dev->bridge->bridge == NULL) { + dprintf(DEBUG_CRITICAL, "pci: %s: can't enable CPM on root port bridge\n", dev->name); + return; + } + + pcie_cap = pci_find_capability(dev, PCI_CAP_ID_PCIE); + + if (pcie_cap == 0) { + dprintf(DEBUG_CRITICAL, "pci: %s: Can't enable CPM, PCIe capability not found\n", dev->name); + return; + } + + link_control = pci_config_read16(dev, pcie_cap + PCI_PCIE_CAP_LINK_CONTROL); + link_control |= (1 << 8); + pci_config_write16(dev, pcie_cap + PCI_PCIE_CAP_LINK_CONTROL, link_control); +} + +void pci_enable_pcie_l1ss(pci_device_t dev) +{ + pci_device_t bridge; + uint32_t bridge_offset; + uint32_t dev_offset; + uint32_t bridge_cap; + uint32_t dev_cap; + uint32_t supported; + uint32_t dev_t_power_on_scale; + uint32_t dev_t_power_on_value; + uint32_t bridge_t_common_mode; + uint32_t dev_t_common_mode; + uint32_t t_common_mode; + uint32_t ltr_threshold; + uint32_t bridge_control1; + uint32_t bridge_control2; + uint32_t dev_control1; + uint32_t dev_control2; + + if (dev->pcie_device_port_type != PCI_PCIE_TYPE_ENDPOINT && + dev->pcie_device_port_type != PCI_PCIE_TYPE_UPSTREAM) { + dprintf(DEBUG_CRITICAL, "pci: %s: can't get L1SS parameters for non-upstream port\n", dev->name); + return; + } + + bridge = dev->bridge; + if (bridge == NULL || bridge->bridge == NULL) { + dprintf(DEBUG_CRITICAL, "pci: %s: can't enable L1SS on root port bridge\n", dev->name); + return; + } + + bridge_offset = pci_find_extended_capability(bridge, PCI_EXT_CAP_ID_L1SS, 1); + if (bridge_offset == 0) { + dprintf(DEBUG_CRITICAL, "pci: %s: no L1SS capability upstream\n", dev->name); + return; + } + dev_offset = pci_find_extended_capability(dev, PCI_EXT_CAP_ID_L1SS, 1); + if (dev_offset == 0) { + dprintf(DEBUG_CRITICAL, "pci: %s: no L1SS capability on endpoint\n", dev->name); + return; + } + + // Make sure upstream and downstream support L1 PM substates, and that they have + // supported substates in common + bridge_cap = pci_config_read32(bridge, bridge_offset + PCI_L1SS_CAP_CAPABILITIES); + dev_cap = pci_config_read32(dev, dev_offset + PCI_L1SS_CAP_CAPABILITIES); + + // Force enable ASPM+L1SS when S3E doesn't advertise support + // If we ever had to support endpoints other than S3E, we could conditionalize this on the + // S3E VID/PID. For now, this hack is good enough. + dev_cap |= 0x1f; + + supported = bridge_cap & dev_cap & 0x1f; + + // L1 substates ECN, section 7.xx.3: "For compatibility with possible future extensions, + // software must not enable L1 PM Substates unless the L1 PM Substates Supported bit in + // the L1 PM Substates Capabilities Register is Set." + // So, we need to make sure that bit 4 is set on both ends, and that some common bits + // are set in bits 0-3 + if ((supported & 0x10) == 0 || (supported & 0xf) == 0) { + dprintf(DEBUG_CRITICAL, "pci: %s: no common L1SS support (dev %08x upstream %08x)\n", + dev->name, dev_cap, bridge_cap); + return; + } + + // Bit 4 just says if L1 is supported in general, but bits 0-3 map directly to control register bits + supported &= 0xf; + + dev_t_power_on_scale = (dev_cap >> 16) & 0x3; + dev_t_power_on_value = (dev_cap >> 19) & 0x1f; + // t_power_on scale needs to be valid on endpoint + if (dev_t_power_on_scale == 3) { + dprintf(DEBUG_CRITICAL, "pci: %s: invalid L1SS t_power_on (dev %08x upstream %08x)\n", + dev->name, dev_cap, bridge_cap); + return; + } + + // The root complex value isn't correct, so we hardcode the t_common_mode value in iBoot/SecureROM + bridge_t_common_mode = platform_get_pcie_l1ss_t_common_mode(); + dev_t_common_mode = (dev_cap >> 8) & 0xff; + t_common_mode = __max(bridge_t_common_mode, dev_t_common_mode); + + ltr_threshold = platform_get_pcie_l1ss_ltr_threshold(); + + // L1SS must be disabled before setting timing parameters + // Disable happens endpoint-first + dev_control1 = pci_config_read32(dev, dev_offset + PCI_L1SS_CAP_CONTROL1); + dev_control1 &= ~0xf; + pci_config_write32(dev, dev_offset + PCI_L1SS_CAP_CONTROL1, dev_control1); + bridge_control1 = pci_config_read32(bridge, bridge_offset + PCI_L1SS_CAP_CONTROL1); + bridge_control1 &= ~0xf; + pci_config_write32(bridge, bridge_offset + PCI_L1SS_CAP_CONTROL1, bridge_control1); + + // set control2 on bridge with t_power_on + bridge_control2 = pci_config_read32(bridge, bridge_offset + PCI_L1SS_CAP_CONTROL2); + bridge_control2 &= ~((0x3 << 0) | (0x1f << 3)); + // t_power_on_scale from endpoint + bridge_control2 |= dev_t_power_on_scale; + bridge_control2 |= dev_t_power_on_value << 3; + pci_config_write32(bridge, bridge_offset + PCI_L1SS_CAP_CONTROL2, bridge_control2); + + // set control2 on endpoint with t_power_on + dev_control2 = pci_config_read32(dev, dev_offset + PCI_L1SS_CAP_CONTROL2); + dev_control2 &= ~((0x3 << 0) | (0x1f << 3)); + // t_power_on_scale from endpoint + dev_control2 |= dev_t_power_on_scale; + dev_control2 |= dev_t_power_on_value << 3; + pci_config_write32(dev, dev_offset + PCI_L1SS_CAP_CONTROL2, dev_control2); + + // set control 1 on root port with t_common_mode, enables and LTR threshold + // enables always need to happen upstream first (opposite of disable) + bridge_control1 |= supported; + if ((supported & ((1 << 3) | (1 << 1))) != 0) { + // t_common_mode and LTR threshold only applies when L1.2 is supported + bridge_control1 &= ~((0xff << 8) | (0x3ff << 16) | (0x7 << 29)); + bridge_control1 |= t_common_mode << 8; + + // set LTR threshold using a 1024 ns scale + bridge_control1 |= ltr_threshold << 16; + bridge_control1 |= 2 << 29; + } + pci_config_write32(bridge, bridge_offset + PCI_L1SS_CAP_CONTROL1, bridge_control1); + + // set control 1 on endpoint with enables and LTR threshold + dev_control1 |= supported; + if ((supported & ((1 << 3) | (1 << 1))) != 0) { + // LTR threshold only applies when L1.2 is supported + dev_control1 &= ~((0x3ff << 16) | (0x7 << 29)); + + // set LTR threshold using a 1024 ns scale + dev_control1 |= ltr_threshold << 16; + dev_control1 |= 2 << 29; + } + pci_config_write32(dev, dev_offset + PCI_L1SS_CAP_CONTROL1, dev_control1); +} + +#if DEBUG_BUILD +static void pci_explore(pci_device_t bridge, bool map_bars) +{ + pci_device_t dev; + + ASSERT(bridge != NULL); + + for (int i = 0; i < 32; i++) { + dev = pci_bridge_probe(bridge, i, 0); + if (dev == NULL) { + continue; + } + + if (map_bars) { + for (int j = 0; j < dev->num_bars; j++) { + if (dev->bar_size[j] != 0 && dev->bar_host_addr[j] == 0) { + pci_map_bar(dev, j); + } + + if (dev->bar_64bit[j]) + j++; + } + } + + if (pci_is_bridge(dev)) { + if (dev->secondary_bus == 0) + pci_bridge_assign_secondary_bus(dev); + pci_explore(dev, map_bars); + } + } +} + +static void pci_show_device(pci_device_t dev) +{ + if (dev->bridge == NULL) { + printf("Host bridge\n"); + return; + } + + printf("Device %s (%02x:%02x:%02x)\n", dev->name, dev->bridge->secondary_bus, dev->device_num, 0); + + printf(" Vendor:%04x Device:%04x Revision:%02x ClassCode:%06x Type:%02x\n", + dev->vendor_id, dev->device_id, dev->revision_id, dev->class_code, dev->header_type); + + if (pci_is_bridge(dev)) { + printf(" PriBus:%02x SecBus:%02x SubBus:%02x\n", + dev->primary_bus, dev->secondary_bus, dev->subordinate_bus); + printf(" MemoryBase:%08x MemoryLimit:%08x (FIXME)\n", // FIXME + dev->memory_base, dev->memory_base + dev->memory_size - 1); + } + + for (uint32_t i = 0; i < dev->num_bars; i++) { + const char *format_str; + + if (dev->bar_size[i] == 0) + continue; + if (dev->bar_64bit[i] && i % 2 != 0) + continue; + + if (dev->bar_64bit[i]) + format_str = " BAR%u MEM %016llx/%016llx (host 0x%llx)\n"; + else + format_str = " BAR%u MEM %08llx/%08llx (host 0x%llx)\n"; + + printf(format_str, i, dev->bar_pci_addr[i], dev->bar_size[i], dev->bar_host_addr[i]); + } +} + +static void pci_list_capabilities(pci_device_t dev) +{ + uint32_t idreg; + uint16_t status; + uint8_t cap_pointer; + uint16_t id_and_next; + + idreg = pci_config_read32(dev, PCI_CONFIG_VENDOR_ID); + if (idreg == 0xffffffff || idreg == 0xffff0001) { + printf("Device not present\n"); + return; + } + + status = pci_config_read16(dev, PCI_CONFIG_STATUS); + if ((status & (1 << 4)) == 0) { + printf("Device has no capabilties list (status 0x%04x)\n", status); + return; + } + + cap_pointer = pci_config_read8(dev, PCI_CONFIG_CAPABILITIES_PTR); + cap_pointer &= 0xFC; + + while (cap_pointer >= 0x40) { + id_and_next = pci_config_read16(dev, cap_pointer); + + printf(" Capability 0x%02x Offset:0x%02x\n", id_and_next & 0xFF, cap_pointer); + + cap_pointer = (id_and_next >> 8) & 0xFC; + } +} + +static void pci_list_extended_capabilities(pci_device_t dev) +{ + uint32_t idreg; + uint32_t header; + uint16_t header_id; + uint8_t header_version; + uint16_t header_pointer; + + idreg = pci_config_read32(dev, PCI_CONFIG_VENDOR_ID); + if (idreg == 0xffffffff || idreg == 0xffff0001) { + printf("Device not present\n"); + return; + } + + header_pointer = 0x100; + + do { + header = pci_config_read32(dev, header_pointer); + if (header == 0 || header == 0xFFFFFFFF) + break; + + header_id = header & 0xFFFF; + header_version = (header >> 16) & 0xF; + + printf(" Extended Capability 0x%04x Ver:0x%02x Offset:0x%04x\n", + header_id, header_version, header_pointer); + + header_pointer = (header >> 20) & 0xFFC; + } while (header_pointer != 0); +} + +static void pci_list(bool verbose) +{ + pci_device_t dev; + + for (int i = 0; i < 256; i++) { + if (pci_bridges[i] == NULL) + continue; + for(int j = 0; j < 32; j++) { + dev = pci_bridges[i]->devices[j]; + if (dev != NULL) { + pci_show_device(dev); + if (verbose) { + pci_list_capabilities(dev); + pci_list_extended_capabilities(dev); + } + } + } + } +} + +static pci_device_t pci_lookup_device(char *address) +{ + char *rest; + char *next; + long bus, device, function; + + bus = strtol(address, &rest, 16); + + if (rest == address || rest[0] != ':') + return NULL; + if (bus < 0 || bus > 255) + return NULL; + + next = rest + 1; + + device = strtol(next, &rest, 16); + if (rest == address || rest[0] != ':') + return NULL; + if (device < 0 || device > 31) + return NULL; + + next = rest + 1; + + function = strtol(next, &rest, 16); + if (rest == address || rest[0] != '\0') + return NULL; + if (function != 0) + return NULL; + + if (pci_bridges[bus] == NULL) + return NULL; + + return pci_bridges[bus]->devices[device]; +} + +static int do_pci_debug_cmd(int argc, struct cmd_arg *args) +{ + int result = -1; + const char *cmd = NULL; + + if (argc >= 2) + cmd = args[1].str; + + if (cmd == NULL) { + result = -1; + } else { + if (strcmp(cmd, "enumerate") == 0) { + bool map_bars = false; + if (argc >= 3 && args[2].str != NULL) { + if (strcmp(args[2].str, "-map") == 0) + map_bars = true; + } + + if (pci_bridges[0] == NULL) { + printf("Can't find host bridge\n"); + result = -1; + } else { + pci_explore(pci_bridges[0], map_bars); + result = 0; + } + } else if (strcmp(cmd, "list") == 0) { + bool verbose = false; + if (argc >= 3 && args[2].str != NULL) { + if (strcmp(args[2].str, "-v") == 0) + verbose = true; + } + pci_list(verbose); + result = 0; + } else if (strcmp(cmd, "aspm") == 0 && argc == 3) { + pci_device_t dev = pci_lookup_device(args[2].str); + if (dev == NULL) { + printf("Couldn't find device \"%s\"\n", args[2].str); + result = -1; + } else { + pci_enable_pcie_aspm(dev); + result = 0; + } + } else if (strcmp(cmd, "cpm") == 0 && argc == 3) { + pci_device_t dev = pci_lookup_device(args[2].str); + if (dev == NULL) { + printf("Couldn't find device \"%s\"\n", args[2].str); + result = -1; + } else { + pci_enable_pcie_cpm(dev); + result = 0; + } + } else if (strcmp(cmd, "l1ss") == 0 && (argc == 3)) { + pci_device_t dev = pci_lookup_device(args[2].str); + if (dev == NULL) { + printf("Couldn't find device \"%s\"\n", args[2].str); + result = -1; + } else { + pci_enable_pcie_l1ss(dev); + result = 0; + } + } else if(strcmp(cmd, "ltr") == 0 && argc == 3) { + pci_device_t dev = pci_lookup_device(args[2].str); + if (dev == NULL) { + printf("Couldn't find device \"%s\"\n", args[2].str); + result = -1; + } else { + pci_enable_pcie_ltr(dev); + result = 0; + } + } + } + + if (result < 0) { + printf("Usage:\n"); + printf("\taspm \t\t - Enables PCIe ASPM on the given device (bb:dd:ff)\n"); + printf("\tcpm \t\t - Enables PCIe CPM on the given device (bb:dd:ff)\n"); + printf("\tenumerate [-map]\t - Enumerates every PCI device reachable from the host bridge\n"); + printf("\tlist [-v]\t\t - Lists all enumerated PCI devices\n"); + printf("\tl1ss \t - Enables PCIe L1SS on the given device (bb:dd:ff)\n"); + printf("\tltr \t\t - Enables PCIe LTR on the given device (bb:dd:ff) and all upstream devices\n"); + } + + return result; +} +#endif + +MENU_COMMAND_DEBUG(pci, do_pci_debug_cmd, "PCI debug commands", NULL); diff --git a/drivers/pci/pci_private.h b/drivers/pci/pci_private.h new file mode 100644 index 0000000..3e2f51c --- /dev/null +++ b/drivers/pci/pci_private.h @@ -0,0 +1,65 @@ +#ifndef PCI_PRIVATE_H +#define PCI_PRIVATE_H + +#include + +struct pci_device { + char name[16]; + uint32_t refcount; + + // This device's number on its bus + uint8_t device_num; + + // Cached copies of config space registers + uint16_t vendor_id; + uint16_t device_id; + uint32_t class_code; + uint8_t revision_id; + uint8_t header_type; + bool multifunction; + + // cached copied of pcie-specific registers + uint8_t pcie_device_port_type; // from PCIe r3 7.8.2 + + // Populated in pci_bridge_probe by probing the BARs + uint8_t num_bars; + uint64_t bar_size[6]; + bool bar_64bit[6]; + uint64_t bar_pci_addr[6]; + uintptr_t bar_host_addr[6]; + + uint16_t first_cap_offset; + uint16_t pcie_cap_offset; + uint16_t pm_cap_offset; + + // The bridge upstream from this device, NULL for the host bridge + pci_device_t bridge; + + ////////// bridge-specific stuff + // Provided by the platform driver to support config reads/writes + pci_config_read_cb_t config_read; + pci_config_write_cb_t config_write; + void *bridge_priv; + + // Caches of the bridge numbering config space registers. For host bridges, + // primary_bus is ignored and secondary/subordinate_bus just track which + // bus numbers have been vended (since host bridges don't have config space) + uint8_t primary_bus; + uint8_t secondary_bus; + uint8_t subordinate_bus; + + // Tracks 32-bit memory space allocations. For now the driver will just support + // 32-bit addresses. 64-bit addresses would be tracked in a separate range, so + // making the type 32-bit is safe + uint32_t memory_base; + uint32_t memory_size; + uint32_t memory_allocated; + + // Keep track of any devices on this bridge's bus + struct pci_device *devices[32]; + // And of how many we've allocated + uint32_t num_children; +}; + + +#endif diff --git a/drivers/pci/rules.mk b/drivers/pci/rules.mk new file mode 100644 index 0000000..c2fe2b5 --- /dev/null +++ b/drivers/pci/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2008 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PCI=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/pci.o diff --git a/drivers/power/hdqgauge/hdqgauge.c b/drivers/power/hdqgauge/hdqgauge.c new file mode 100644 index 0000000..50c56ed --- /dev/null +++ b/drivers/power/hdqgauge/hdqgauge.c @@ -0,0 +1,1602 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +enum +{ + kHDQRegControl = 0x00, + kHDQRegAtRate = 0x02, // pre-Rev A + kHDQRegDebug1 = 0x02, // Rev A FW + kHDQRegAtRateTimeToEmpty = 0x04, // pre-Rev A FW + kHDQRegDebug2 = 0x04, // Rev A FW + kHDQRegTemperature = 0x06, + kHDQRegVoltage = 0x08, + kHDQRegFlags = 0x0a, + kHDQRegNominalAvailableCapacity = 0x0c, + kHDQRegFullAvailableCapacity = 0x0e, + kHDQRegRemainingCapacity = 0x10, + kHDQRegFullChargeCapacity = 0x12, + kHDQRegAverageCurrent = 0x14, + kHDQRegTimeToEmpty = 0x16, + kHDQRegTimeToFull = 0x18, + kHDQRegStandbyCurrent = 0x1a, + kHDQRegStandbyTimeToEmpty = 0x1c, // pre-Rev A FW + kHDQRegPresentDOD = 0x1c, // Rev A FW + kHDQRegMaxLoadCurrent = 0x1e, + kHDQRegMaxLoadTimeToEmpty = 0x20, // pre-Rev A FW + kHDQRegInternal_Temp = 0x20, // Rev A FW + kHDQRegAvailableEnergy = 0x22, + kHDQRegAveragePower = 0x24, + kHDQRegTimeToEmptyAtConstantPower = 0x26, // pre-Rev A FW + kHDQRegOCV_Current = 0x26, // Rev A FW + kHDQRegOCV_Voltage = 0x28, // Rev A FW + kHDQRegCycleCount = 0x2a, + kHDQRegStateOfCharge = 0x2c, + kHDQRegRemCapOverUnder = 0x2e, // Rev A FW + kHDQRegDODatEOC = 0x30, // Rev A FW + kHDQRegTrueRemainingCapacity = 0x32, // Rev A FW + kHDQRegPassedCharge = 0x34, // Rev A FW + kHDQRegDOD0 = 0x36, // Rev A FW + kHDQRegQstart = 0x38, // Rev A FW + + kHDQRegPackConfiguration = 0x3a, + kHDQRegDesignCapacity = 0x3c, + + kHDQRegDataFlashClass = 0x3e, + kHDQRegDataFlashBlock = 0x3f, + kHDQRegBlockData = 0x40, + kHDQRegBlockDataChecksum = 0x60, + kHDQRegBlockDataControl = 0x61, + + kHDQRegNameLen = 0x62, + kHDQRegName = 0x63, + kHDQResScale = 0x6a, // Rev C FW + kHDQIMAX = 0x6c, // enabled in PackConfigurationB (c=64,o=2) + kHDQITMiscStatus = 0x6e, +}; + +enum { + kHDQNotChargingReason = 0x68, // A4 Only + kHDQNominalChargeCapacity = 0x72, // A4 Only + kHDQChargerStatus = 0x74, // A4 Only, Write Only + kHDQChargingCurrent = 0x75, // A4 Only + kHDQChargingVoltage = 0x76, // A4 Only + kHDQChargerAlert = 0x77, // A4 Only +}; + +enum +{ + kHDQControlRegStatus = 0x00, + kHDQControlRegDeviceType = 0x01, + kHDQControlRegFWVersion = 0x02, + kHDQControlRegHWVersion = 0x03, + kHDQControlRegDFChecksum = 0x04, + kHDQControlRegResetData = 0x05, + kHDQControlRegPrevMacWrite = 0x07, + kHDQControlRegChemID = 0x08, + kHDQControlRegSetFullsleep = 0x10, + kHDQControlRegSetHibernate = 0x11, + kHDQControlRegClearHibernate = 0x12, + kHDQControlRegSetShutdown = 0x13, // pre-Rev C FW + kHDQControlRegClearShutdown = 0x14, // pre-Rev C FW + kHDQControlRegClearFullsleep = 0x13, // Rev C FW + kHDQControlRegSetHDQIntEn = 0x15, + kHDQControlRegClearHDQIntEn = 0x16, + kHDQControlRegOpenProtector = 0x17, // Rev B FW + kHDQControlRegEnableDLog = 0x18, // Rev B FW + kHDQControlRegDisableDLog = 0x19, // Rev B FW + kHDQControlRegDFCSAll = 0x1A, // Rev B FW + kHDQControlRegDFCSStaticChecm = 0x1B, // Rev B FW + kHDQCOntrolRegDFCSAllStatic = 0x1c, // Rev B FW + kHDQControlRegSealed = 0x20, + kHDQControlRegITEnable = 0x21, + kHDQCOntrolRegEnableFVCA = 0x23, // Rev C FW + kHDQControlRegCalMode = 0x40, + kHDQControlRegReset = 0x41, +}; + +enum { + kHDQLifetimeBlockA = 0x04, + kHDQLifetimeBlockB = 0x06, +}; + +enum { + kHDQDataSubclassGasGaugingITCfg = 80, + kHDQDataOffsetGasGaugingITCfgSecRelaxTime = 6, + kHDQDataOffsetGasGaugingITCfgAverageTime = 12, + kHDQDataOffsetGasGaugingITCfgMinDODResUpdate = 19, + kHDQDataOffsetGasGaugingITCfgMaxResFactor = 21, + kHDQDataOffsetGasGaugingITCfgMinResFactor = 22, + kHDQDataOffsetGasGaugingITCfgQmaxCapacityError = 45, + kHDQDataOffsetGasGaugingITCfgMaxQmaxChange = 46, + + kHDQDataSubclassGasGaugingState = 82, + kHDQDataOffsetGasGaugingStateAvgPLastRun = 9, + + kHDQDataSubclassRaTablesData = 88, + kHDQDataSubclassRaTablesDataX = 89, + + kHDQDataSealedModeSubclass = -1, + kHDQDataSealedModeBlockManufacturerInfoBlockA = 1, + kHDQDataSealedModeBlockManufacturerInfoBlockB = 2, + kHDQDataSealedModeBlockManufacturerInfoBlockC = 3, + kHDQDataSealedModeBlockLifetimeData = 4, + + kHDQDataOffsetBlockManufacturerInfoBlockCFlags = 0, + kHDQDataOffsetBlockManufacturerInfoBlockCUpdateCount = 1, + kHDQDataOffsetBlockManufacturerInfoBlockCUpdateNeedRA = 2, +}; + +enum { + kHDQControlRegStatusMaskSE = (1 << 15), + kHDQControlRegStatusMaskFAS = (1 << 14), + kHDQControlRegStatusMaskSS = (1 << 13), + kHDQControlRegStatusMaskCSV = (1 << 12), + kHDQControlRegStatusMaskCCA = (1 << 11), + kHDQControlRegStatusMaskBCA = (1 << 10), + kHDQControlRegStatusMaskDLOGEN = (1 << 9), + kHDQControlRegStatusMaskHDQIntEn = (1 << 8), + kHDQControlRegStatusMaskSHUTDOWN = (1 << 7), + kHDQControlRegStatusMaskHIBERNATE = (1 << 6), + kHDQControlRegStatusMaskFULLSLEEP = (1 << 5), + kHDQControlRegStatusMaskSLEEP = (1 << 4), + kHDQControlRegStatusMaskLDMD = (1 << 3), + kHDQControlRegStatusMaskRUP_DIS = (1 << 2), + kHDQControlRegStatusMaskVOK = (1 << 1), + kHDQControlRegStatusMaskQEN = (1 << 0), +}; + +enum { + kHDQNotChargingReasonMaskCHG_WD = (1<<5), + kHDQNotChargingReasonMaskTOO_LONG = (1<<4), +}; + +#define FW_VERSION_NO_SOC1 (0x0109) +#define FW_VERSION_REV_A (0x0119) +#define FW_VERSION_REV_B (0x0132) +#define FW_VERSION_REV_C (0x0310) +#define FW_VERSION_REV_D (0x0313) +#define FW_VERSION_REV_A4 (0x0501) + +#if defined(BATTERY_TRAP_DEBUG) +enum RegisterType { + kRegisterTypeNone=-1, + kRegisterTypeS16=0, // do not change, default value + kRegisterTypeU16=1, + kRegisterTypeU8=2, + kRegisterTypeUC16=10, +}; + +struct RegisterInfo +{ + uint32_t reg; + const char * name[5]; /* PreREVA,REVA,REVB,REVD,A4 */ + enum RegisterType type; + //void *data; + //rfun_t fun; + //char *regName; // this is the true name +}; + +static const struct RegisterInfo infoRegs[] = +{ + { kHDQRegAtRate, { "AtRate", "Debug1", "DataLogIndex" }, kRegisterTypeS16}, + // since this register is dependent on the previous register (all firmware versions) and + // is not safe to read (rev B), do not print it out when dumping the device. + // { kHDQRegAtRateTimeToEmpty, "AtRateTimeToEmpty", "Debug2", "DataLogBuffer" }, + { kHDQRegTemperature, { "Temperature" }, kRegisterTypeU16}, + { kHDQRegVoltage, { "Voltage" }, kRegisterTypeS16}, + { kHDQRegFlags, { "Flags" }, kRegisterTypeS16}, + { kHDQRegNominalAvailableCapacity, { "NominalAvailableCapacity" }, kRegisterTypeS16}, + { kHDQRegFullAvailableCapacity, { "FullAvailableCapacity" }, kRegisterTypeS16}, + { kHDQRegRemainingCapacity, { "RemainingCapacity" }, kRegisterTypeS16}, + { kHDQRegFullChargeCapacity, { "FullChargeCapacity" }, kRegisterTypeS16}, + { kHDQRegAverageCurrent, { "AverageCurrent" }, kRegisterTypeS16}, + { kHDQRegTimeToEmpty, { "TimeToEmpty" }, kRegisterTypeU16}, + { kHDQRegTimeToFull, { "TimeToFull" }, kRegisterTypeU16}, + { kHDQRegStandbyCurrent, { "StandbyCurrent" }, kRegisterTypeS16}, // not on A4 + { kHDQRegStandbyTimeToEmpty, { "StandbyTimeToEmpty", "PresentDOD" }, kRegisterTypeU16}, + { kHDQRegMaxLoadCurrent, { "MaxLoadCurrent" }, kRegisterTypeS16}, // not on A4 + { kHDQRegMaxLoadTimeToEmpty, { "MaxLoadTimeToEmpty", "Internal_Temp" }, kRegisterTypeU16}, + { kHDQRegAvailableEnergy, { "AvailableEnergy", NULL, "Qmax" }, kRegisterTypeU16}, + { kHDQRegAveragePower, { "AveragePower" }, kRegisterTypeU16}, + { kHDQRegTimeToEmptyAtConstantPower, { "TimeToEmptyAtConstantPower", "OCV_Current" }, kRegisterTypeS16}, + { kHDQRegOCV_Voltage, { NULL, "OCV_Voltage" }, kRegisterTypeS16}, + { kHDQRegCycleCount, { "CycleCount" }, kRegisterTypeU16}, + { kHDQRegStateOfCharge, { "StateOfCharge" }, kRegisterTypeS16}, + { kHDQRegRemCapOverUnder, { NULL, "RemCapOverUnder" }, kRegisterTypeS16}, + { kHDQRegDODatEOC, { NULL, "DODatEOC" }, kRegisterTypeS16}, + { kHDQRegTrueRemainingCapacity, { NULL, "TrueRemainingCapacity" }, kRegisterTypeS16}, + { kHDQRegPassedCharge, { NULL, "PassedCharge" }, kRegisterTypeS16}, + { kHDQRegDOD0, { NULL, "DOD0" }, kRegisterTypeU16}, + { kHDQRegQstart, { NULL, "Qstart" }, kRegisterTypeS16}, + { kHDQRegDesignCapacity, { "DesignCapacity" }, kRegisterTypeS16}, + { kHDQIMAX, { NULL, NULL, NULL, "IMAX" }, kRegisterTypeS16}, + + // available only in firmware A4 + { kHDQITMiscStatus, { NULL, NULL, NULL, NULL, "ITMiscStatus" }, kRegisterTypeS16}, + { kHDQNominalChargeCapacity, { NULL, NULL, NULL, NULL, "NCC" }, kRegisterTypeS16}, + + { kHDQControlRegStatus, { "Status" }, kRegisterTypeUC16 }, + { kHDQControlRegDeviceType, { "DeviceType" }, kRegisterTypeUC16 }, + { kHDQControlRegFWVersion, { "FWVersion" }, kRegisterTypeUC16 }, + { kHDQControlRegHWVersion, { "HWVersion" }, kRegisterTypeUC16 }, + { kHDQControlRegChemID, { "ChemID" }, kRegisterTypeUC16 }, + + { 0, { }, kRegisterTypeNone } +}; + +// available only in firmware A4 +static const struct RegisterInfo chargerRegs[] = +{ + { kHDQChargerStatus, { NULL, NULL, NULL, NULL, "ChargerStatus" }, kRegisterTypeU8 }, + { kHDQChargingCurrent, { NULL, NULL, NULL, NULL, "ChargingCurrent" }, kRegisterTypeU8 }, + { kHDQChargingVoltage, { NULL, NULL, NULL, NULL, "ChargingVoltage" }, kRegisterTypeU8 }, + { kHDQNotChargingReason, { NULL, NULL, NULL, NULL, "NotChargingReason" }, kRegisterTypeU8 }, + { kHDQChargerAlert, { NULL, NULL, NULL, NULL, "ChargerAlert" }, kRegisterTypeU8 }, + + { 0, { }, kRegisterTypeNone } +}; +#endif + +static int +uart_break() +{ + uart_send_break(HDQGAUGE_SERIAL_PORT, true); + task_sleep(200); + uart_send_break(HDQGAUGE_SERIAL_PORT, false); + + task_sleep(40); + + while (uart_getc(HDQGAUGE_SERIAL_PORT, false) >= 0) + ; + + return (0); +} + +static int +uart_write(const unsigned char * data, int len) +{ + for (int idx = 0; idx < len; idx++) + if (uart_putc(HDQGAUGE_SERIAL_PORT, data[idx]) < 0) + return -1; + + return 0; +} + +static int +uart_read(unsigned char * data, int len, int timeoutusecs) +{ + utime_t timeout = system_time() + timeoutusecs; + + int idx = 0; + + while (idx < len) + { + int c = uart_getc(HDQGAUGE_SERIAL_PORT, false); + + if (c < 0) + { + if (system_time() > timeout) { + printf("gas gauge read timed out\n"); + return (-1); + } + + task_sleep(190); + } + else + { + data[idx++] = c; + + timeout = system_time() + timeoutusecs; + } + } + + return (len); +} + + +#define SERIAL_LOG 0 + +#if SERIAL_LOG +static void +dumpBuffer(unsigned char * buffer, int length) +{ + int i; + for (i = 0; i < length; i++) + printf(" %02x", buffer[i]); + printf("\n"); +} +#endif + +static int +hdqOp(int command, int commandBits, int readBits) +{ + unsigned char buffer[32]; + int rc, i; + int data; + + if ((commandBits > 32) || (readBits > 32)) + return (-1); + + for (i = 0; i < commandBits; i++) + buffer[i] = (command & (1 << i)) ? 0xfe : 0xc0; + +#if SERIAL_LOG + printf("\tsend: %x\n", command); + dumpBuffer(buffer, commandBits); +#endif + + uart_break(); + + rc = uart_write(buffer, commandBits); + if (rc < 0) + return (rc); + + bzero(buffer, commandBits); + rc = uart_read(buffer, commandBits, 500000); +#if SERIAL_LOG + printf("\tread8 (%d)", rc); + dumpBuffer(buffer, commandBits); +#endif + if (rc < 0) + return (rc); + for (i = 0; i < commandBits; i++) + { + if (buffer[i] != ((command & (1 << i)) ? 0xfe : 0xc0)) + { + printf("hdq read mismatch[%d]\n", i); + return (-1); + } + } + + data = 0; + if (readBits) + { + bzero(buffer, readBits); + rc = uart_read(buffer, readBits, 500000); +#if SERIAL_LOG + printf("\tread8 (%d)", rc); + dumpBuffer(buffer, readBits); +#endif + if (rc < 0) + return (rc); + for (i = 0; i < readBits; i++) + { + if (buffer[i] > 0xF8) + data |= (1 << i); + } + } + + return (data); +} + +static int +hdqRead8(int command) +{ + return (hdqOp(command, 8, 8)); +} + +static int +hdqRead16(int command) +{ + int msb, msb2, lsb, result, retries; + + retries = 0; + result = -1; + do + { + msb = hdqRead8(command + 1); + if (msb < 0) + break; + lsb = hdqRead8(command); + if (lsb < 0) + break; + msb2 = hdqRead8(command + 1); + if (msb2 < 0) + break; + if (msb2 == msb) + result = (lsb | (msb << 8)); + } + while ((result < 0) && (++retries < 10)); + + return (result); +} + +static int +hdqWrite8(int command, int data) +{ + command &= 0xFF; + command |= 0x80; + command |= ((data & 0xFF) << 8); + + return (hdqOp(command, 16, 0)); +} + +static int +controlOp16(int reg) +{ + int rc; + + rc = hdqWrite8(0, reg & 0xff); + if (rc < 0) + return (rc); + rc = hdqWrite8(1, reg >> 8); + if (rc < 0) + return (rc); + + return 0; +} + +static int +controlRead16(int reg) +{ + int rc; + + rc = hdqWrite8(0, reg & 0xff); + if (rc < 0) + return (rc); + rc = hdqWrite8(1, reg >> 8); + if (rc < 0) + return (rc); + + return (hdqRead16(0)); +} + +static int +controlWrite16(int subcommand, int data) +{ + int rc; + + rc = hdqWrite8(kHDQRegControl, (subcommand & 0xFF)); + if (rc < 0) + return (rc); + rc = hdqWrite8(kHDQRegControl + 1, ((subcommand >> 8) & 0xFF)); + if (rc < 0) + return (rc); + + rc = hdqWrite8(kHDQRegControl, (data & 0xFF)); + if (rc < 0) + return (rc); + rc = hdqWrite8(kHDQRegControl + 1, ((data >> 8) & 0xFF)); + + return (rc); +} + +static int +readBlock(int class, int block, unsigned char *blockData) +{ + unsigned char blockDataLocal[32]; + unsigned char sum = 0, cksum; + int rc; + int idx, len, value; + bool sealedMode = (class == kHDQDataSealedModeSubclass); + + if (blockData == NULL) blockData = blockDataLocal; + + rc = hdqWrite8(kHDQRegBlockDataControl, sealedMode ? 1 : 0); + if (rc < 0) + return (rc); + + if (!sealedMode) { + rc = hdqWrite8(kHDQRegDataFlashClass, class); + if (rc < 0) + return (rc); + } + + len = sizeof(blockDataLocal); + rc = hdqWrite8(kHDQRegDataFlashBlock, block); + for (idx = 0; idx < len; idx++) + { + value = hdqRead8(kHDQRegBlockData + idx); + if (value < 0) + return value; + + blockData[idx] = value; + sum += value; + } + cksum = hdqRead8(kHDQRegBlockDataChecksum); + sum += cksum; + + if (sum != 0xff) + return -1; + + return (0); +} + +static int +writeBlock(int class, int block, const unsigned char *blockData) +{ + unsigned char sum = 0, cksum; + int rc, idx; + bool sealedMode = (class == kHDQDataSealedModeSubclass); + + rc = hdqWrite8(kHDQRegBlockDataControl, sealedMode ? 1 : 0); + if (rc < 0) return (rc); + + if (!sealedMode) { + rc = hdqWrite8(kHDQRegDataFlashClass, class); + if (rc < 0) return (rc); + } + + rc = hdqWrite8(kHDQRegDataFlashBlock, block); + + for (idx = 0; idx < 32; idx++) + { + rc = hdqWrite8(kHDQRegBlockData + idx, blockData[idx]); + if (rc != 0) return rc; + + sum += blockData[idx]; + } + cksum = 0xff - sum; + rc = hdqWrite8(kHDQRegBlockDataChecksum, cksum); + + task_sleep(200 * 1000); + + return rc; +} + +static uint16_t gg_firmware_version = 0; + +static void gasgauge_reset(int hard) +{ +#ifdef POWER_GPIO_BATTERY_SWI + power_gpio_configure(POWER_GPIO_BATTERY_SWI, POWER_GPIO_BATTERY_SWI_CONFIG_OUTPUT); + + if ( hard ) { + // SWI low for 3s + power_set_gpio(POWER_GPIO_BATTERY_SWI, 1, 0); + task_sleep(3000 * 1000); + } + + // SWI high for 500ms + power_set_gpio(POWER_GPIO_BATTERY_SWI, 1, 1); + task_sleep(500 * 1000); + + // reset to input + power_gpio_configure(POWER_GPIO_BATTERY_SWI, POWER_GPIO_BATTERY_SWI_CONFIG_INPUT); + power_set_gpio(POWER_GPIO_BATTERY_SWI, 0, 0); + + // allow time for power-on + task_sleep(500 * 1000); +#endif +} + +static void gasgauge_check_reset(void) +{ +#ifdef POWER_GPIO_BATTERY_SWI + if (power_get_gpio(POWER_GPIO_BATTERY_SWI) == 0) { + dprintf(DEBUG_CRITICAL, "gas gauge SWI line low: issuing reset\n"); + gasgauge_reset(0); + } +#endif +} + +static bool +gg_open(void) { +#if WITH_HW_CHARGER_GG_IF + return charger_set_gasgauge_interface(true) == 0; +#endif + return true; +} + +static void +gg_close(void) { +#if WITH_HW_CHARGER_GG_IF + charger_set_gasgauge_interface(false); +#endif +} + +void gasgauge_init(void) +{ + // try not to talk to the gas gauge if we might be in sleep + // N.B. if we were suspended, we would not have placed the gauge + // into full sleep mode. + if (!power_is_suspended()) + { + if (!gg_open()) return; + + gasgauge_check_reset(); + uart_break(); + + // wait for HDQ comms engine to start up + task_sleep(10 * 1000); + + if (gg_firmware_version == 0) { + gg_firmware_version = controlRead16(kHDQControlRegFWVersion); + } + + if (gg_firmware_version >= FW_VERSION_REV_C) { + controlOp16(kHDQControlRegClearFullsleep); + } + + gg_close(); + } +} + +// 0 success, 1 timeout, -1 error +int gasgauge_reset_timer(int debug_print_level, unsigned int timeout) +{ + int success=0; + +#if WITH_HW_CHARGER_GG_IF + if (!gg_open()) return -1; + + gasgauge_check_reset(); + uart_break(); + + if ( gg_firmware_version==0 ) gg_firmware_version = controlRead16(kHDQControlRegFWVersion); + if ( gg_firmware_version>=FW_VERSION_REV_A4 ) { + int ncr; + + dprintf(debug_print_level, "reset_timer (%d):", timeout); + + for ( timeout-- ; 1 ; timeout-- ) { + task_sleep( 1000*1000 ); // one second + + ncr = hdqRead8(kHDQNotChargingReason); + dprintf(debug_print_level, " %#x=%#x", kHDQNotChargingReason, ncr); + + if ( (ncr&kHDQNotChargingReasonMaskTOO_LONG)==0 ) break;// cond cleared + if ( (ncr&kHDQNotChargingReasonMaskCHG_WD)!=0 ) break; // same as clear cond + if ( timeout==0 ) { success=1; break; } + + } + + dprintf(debug_print_level, "\n"); + } + + gg_close(); +#endif + + return success; +} + +#if defined(BATTERY_TRAP_DEBUG) +/* ported from iOS hdqtool */ +static const char* register_name(const struct RegisterInfo * desc, uint16_t fwVersion) +{ + if ( fwVersion==0 ) return NULL; + + if ( fwVersion >= FW_VERSION_REV_A4 ) { + if ( desc->reg==kHDQRegStandbyCurrent ) return NULL; + if ( desc->reg==kHDQRegMaxLoadCurrent ) return NULL; + } + + if ( desc->name[4] && (fwVersion >= FW_VERSION_REV_A4) ) + return desc->name[4]; + if ( desc->name[3] && (fwVersion >= FW_VERSION_REV_D) ) + return desc->name[3]; + // no name changes between REVB and REVC + if ( desc->name[2] && (fwVersion >= FW_VERSION_REV_B) ) + return desc->name[2]; + if ( desc->name[1] && (fwVersion >= FW_VERSION_REV_A) ) + return desc->name[1]; + + return desc->name[0]; // pre REVA +} + +static int read_register(int *data, const struct RegisterInfo * desc) +{ + int result; + + switch ( desc->type ) { + case kRegisterTypeU8: result=hdqRead8(desc->reg); break; + case kRegisterTypeS16: result=hdqRead16(desc->reg); break; + case kRegisterTypeU16: result=hdqRead16(desc->reg); break; + case kRegisterTypeUC16: result=controlRead16(desc->reg); break; + case kRegisterTypeNone: return -1; + default: return -1; + } + if (result >= 0) { + if (desc->type == kRegisterTypeS16) { + *data = (int32_t)((int16_t)result); + } else { + *data = result; + } + } + + return result; +} + +static int dump_device(const struct RegisterInfo *reglist, char * title) +{ +#if 0 + + if (gg_firmware_version>=FW_VERSION_REV_A4) { + dprintf(DEBUG_CRITICAL, "Name: not available\n"); + } else { + char name[16] = { 0 }; + + int len = hdqRead8(kHDQRegNameLen); + if ( len<0 ) + return len; + if (len >= (int)sizeof(name)) + len = sizeof(name)-1; + for (idx = 0; idx < len; idx++) { + value = hdqRead8(kHDQRegName + idx); + if ( value<0 ) + return value; + name[idx]=value&0xff; + } + + name[idx]=0; + dprintf(DEBUG_CRITICAL, "Name: %-16s\n", name); + } +#endif + + printf("%s Registers:\n", title); + for (int idx = 0; reglist[idx].type!=kRegisterTypeNone ; idx++) { + int value; + + const char *name=register_name( ®list[idx], gg_firmware_version); + if ( !name ) continue; + + const int err=read_register(&value, ®list[idx]); + if ( err<0 ) { + printf("0x%02x: error in reading %s\n", reglist[idx].reg, name); + } else { + printf("0x%02x: 0x%04x, %6d", reglist[idx].reg, (uint16_t)value, value); + printf(" %s\n", (name)?name:""); + } + } + + return 0; +} + +static void gasgauge_dump(void) +{ + printf("%s, %d:Dumping Gauge Registers\n", __func__, __LINE__); + + if (!gg_open()) return; + gasgauge_check_reset(); + uart_break(); + if (gg_firmware_version == 0) { + gg_firmware_version = controlRead16(kHDQControlRegFWVersion); + } + + dump_device(infoRegs, "Info"); + dump_device(chargerRegs, "Charger"); + + gg_close(); +} + +static int gasgauge_log(print_level) +{ + static utime_t last_time; + utime_t now = system_time()/1000; + utime_t delta; + + if (now > last_time) + delta = now - last_time; + else + delta = 0; + printf("Gas Gauge Precharge timestamp: %us delta %u.%03us\n", ((uint32_t)now/1000), ((uint32_t)delta)/1000, ((uint32_t)delta)%1000); + last_time = now; +#if WITH_ENV + if (env_get_bool("debug-gg", false)) { + dump_device(infoRegs, "Info"); + dump_device(chargerRegs, "Charger"); + print_level = DEBUG_CRITICAL; + } +#endif + return print_level; +} +#endif + +void gasgauge_print_status(void) +{ + gasgauge_needs_precharge(DEBUG_CRITICAL, false); +} + +// @return 0, no prech?0:1e +// @return 1<<0, needs precharge +// @return 1<<1, needs charger timer reset +// @return -1 error +int gasgauge_needs_precharge(int debug_print_level, bool debug_show_target) +{ + int needs_precharge=0; + int flags, capacity, current, fcc; + int temperature, voltage; + const int gg_flag_mask=target_get_precharge_gg_flag_mask(); + const int boot_battery_capacity=target_get_boot_battery_capacity(); +#if WITH_HW_CHARGER_GG_IF + int ncr, cs, cc, cv, ca; // FW_VERSION_REV_A4 only +#endif + + if (!gg_open()) return false; + + gasgauge_check_reset(); + uart_break(); + + flags = hdqRead16(kHDQRegFlags); + if (flags == -1) goto err; + + if (gg_firmware_version == 0) { + gg_firmware_version = controlRead16(kHDQControlRegFWVersion); + } + + if (gg_firmware_version >= FW_VERSION_REV_A) { + capacity = hdqRead16(kHDQRegTrueRemainingCapacity); + } else { + capacity = hdqRead16(kHDQRegRemainingCapacity); + } + if (capacity == -1) goto err; + + fcc = hdqRead16(kHDQRegFullChargeCapacity); + if (fcc == -1) goto err; + + current = hdqRead16(kHDQRegAverageCurrent); + if (current == -1) goto err; + + temperature = hdqRead16(kHDQRegTemperature); + if (temperature == -1) goto err; + + voltage = hdqRead16(kHDQRegVoltage); + if (voltage == -1) goto err; + + // read charger fields when available, ignore errors +#if WITH_HW_CHARGER_GG_IF + if ( gg_firmware_version>=FW_VERSION_REV_A4 ) { + ncr = hdqRead8(kHDQNotChargingReason); + cs = hdqRead8(kHDQChargerStatus); + cc = hdqRead8(kHDQChargingCurrent); + cv = hdqRead8(kHDQChargingVoltage); + ca = hdqRead8(kHDQChargerAlert); + + if ( ncr&kHDQNotChargingReasonMaskTOO_LONG ) needs_precharge|=GG_NEEDS_RESET; + if ( ncr&kHDQNotChargingReasonMaskCHG_WD ) needs_precharge|=GG_COMMS_WD; + } +#endif + +#if defined(BATTERY_TRAP_DEBUG) + debug_print_level = gasgauge_log(debug_print_level); +#endif + gg_close(); + + // cast values to (int16_t) to extend sign bit for negative numbers (use int + // above so -1 error is distinguished from 0xffff value). + + dprintf(debug_print_level, "gg flags %#x", flags); + if (debug_show_target) dprintf(debug_print_level, " (tgt !& %#x)", gg_flag_mask ); + dprintf(debug_print_level, "; cap %d/%d mAh", (int16_t)capacity, (int16_t)fcc); + if (debug_show_target) dprintf(debug_print_level, " (tgt >= %d)", boot_battery_capacity ); + dprintf(debug_print_level, "; %d mV; %d mA; %d.%d C\n", + (int16_t)voltage, (int16_t)current, + ((int16_t)temperature - 2732) / 10, ((int16_t)temperature - 2732) % 10); + +#if WITH_HW_CHARGER_GG_IF + if ( gg_firmware_version>=FW_VERSION_REV_A4 ) { + dprintf(DEBUG_CRITICAL, "gg charger: 0x%x=0x%x 0x%x=0x%x 0x%x=0x%x 0x%x=0x%x 0x%x=0x%x\n", + kHDQNotChargingReason, ncr, + kHDQChargerStatus, cs, + kHDQChargingCurrent, cc, + kHDQChargingVoltage, cv, + kHDQChargerAlert, ca); + } +#endif + + // require precharge if SOC1 is set (OS shutdown condition), but also + // if pack doesn't have enough charge to make it through OS boot + + if ( ((flags & gg_flag_mask) != 0) || ((int16_t)capacity < boot_battery_capacity ) ) + { + // Firmware version 1.09: EVT1 battery pack, not to be trusted + if (gg_firmware_version == FW_VERSION_NO_SOC1) return 0; + + // SOC1 is set, I need precharge + needs_precharge|=GG_NEEDS_PRECHARGE; + } + + // precharge and/or needs charger reset or nevermind + return needs_precharge; + +err: + gg_close(); + return 0; // should return error, really +} + +void gasgauge_will_shutdown(void) +{ + if (!gg_open()) return; + + gasgauge_check_reset(); + uart_break(); + + task_sleep(10 * 1000); + + if (gg_firmware_version == 0) { + gg_firmware_version = controlRead16(kHDQControlRegFWVersion); + } + + if (gg_firmware_version >= FW_VERSION_REV_C) { + controlOp16(kHDQControlRegSetFullsleep); + } + + gg_close(); +} + +bool gasgauge_full(void) +{ + unsigned int soc; + + const int rc=gasgauge_read_soc( &soc ); + + return ( rc==0 ) && (soc == 100); +} + +int gasgauge_read_soc(unsigned int *soc) +{ + if (!gg_open()) return -1; + + gasgauge_check_reset(); + uart_break(); + + int rc = hdqRead16(kHDQRegStateOfCharge); + + gg_close(); + + if (rc == -1) return -1; + + *soc = rc; + + return 0; +} + +#ifndef GASGAUGE_BATTERYID_BLOCK +#define GASGAUGE_BATTERYID_BLOCK kHDQDataSealedModeBlockManufacturerInfoBlockB +#endif + +int gasgauge_get_battery_id(u_int8_t *buf, int size) +{ + if (!power_has_batterypack()) + return -1; + + if(buf == NULL) + { + dprintf(DEBUG_INFO, "buffer is NULL\n"); + return -1; + } + + if(size > 32) + { + dprintf(DEBUG_INFO, "trying to read more than 32 bytes, size: %d\n", size); + return -1; + } + + + if (!gg_open()) return -1; + + gasgauge_check_reset(); + uart_break(); + + int ret = readBlock(kHDQDataSealedModeSubclass, GASGAUGE_BATTERYID_BLOCK, buf); + + gg_close(); + + return ret; +} + +struct atv_header { + uint8_t table_entries_table_format; + uint8_t checksum; + uint8_t vi_steps_per_entry_revision; + uint8_t table_type; +} __attribute__((packed)); + +struct atv_data_entry { + uint8_t lower_temperature_limit; + uint8_t higher_temperature_limit; + uint8_t current_voltage_value[4]; +} __attribute__((packed)); + +struct atv_table { + struct atv_header header; + struct atv_data_entry data_entry[]; +} __attribute__((packed)); + +static inline uint8_t high_nibble(uint8_t value) { return (value >> 4) & 0x0F; } +static inline uint8_t low_nibble(uint8_t value) { return value & 0x0F; } + +#if defined(GASGAUGE_CHARGETABLE_BLOCK) && !defined(TARGET_USE_CHARGE_TABLE) +#error gas gauge charge table with no default value +#endif + +bool gasgauge_read_charge_table(struct power_charge_limits *table_out, size_t num_elems) +{ + // Returns true if the gas gauge contained a valid charge table and the parameter + // was modified to include it. Returns false if the gas gauge did not have + // a charge table, or it did not fit in the passed-in table size. If false + // is returned, the target of the table parameter will not be modified. + +#ifdef GASGAUGE_CHARGETABLE_BLOCK + uint8_t chargetable_data[32]; + struct atv_table *chargetable = (struct atv_table *)chargetable_data; + uint8_t table_entries; + uint8_t vi_steps_per_entry; + + if (!gg_open()) return false; + + gasgauge_check_reset(); + uart_break(); + + bool ok = false; + int retries = 0; + + while (!ok) + { + if ((++retries) >= 2) + return false; + + if (readBlock(kHDQDataSealedModeSubclass, GASGAUGE_CHARGETABLE_BLOCK, chargetable_data) != 0) + continue; + + // check table type + if (chargetable->header.table_type != 0xFF) { + dprintf(DEBUG_INFO, "gas gauge charge table invalid type: %#x\n", chargetable_data[3]); + continue; + } + + // decode header + table_entries = high_nibble(chargetable->header.table_entries_table_format); + vi_steps_per_entry = high_nibble(chargetable->header.vi_steps_per_entry_revision); + + // make sure not to overflow the table, which has room for the header (four bytes) plus + // up to four entries (six bytes each) + uint8_t table_bytes = offsetof(struct atv_table, data_entry[table_entries]); + + if (table_bytes > sizeof(chargetable_data)) { + dprintf(DEBUG_INFO, "gas gauge charge table inconsistent: %d data entries, %d bytes\n", table_entries, table_bytes); + continue; + } + + // make sure there are enough entries for the input table + if (num_elems < ((table_entries * vi_steps_per_entry))) { + dprintf(DEBUG_INFO, "gas gauge charge table has too many entries: %d only space for %zu\n", (table_entries * vi_steps_per_entry + 1), num_elems); + continue; + } + + // calculate checksum over the data entries (ignore other data in the block) + uint8_t checksum = 0; + for (unsigned i = 0; i < table_bytes; i++) { + checksum += chargetable_data[i]; + } + if ((checksum & 0xFF) != 0x00) { + dprintf(DEBUG_INFO, "gas gauge charge table bad checksum: checksum %#x checksum byte %#x expecting %#x\n", + checksum, chargetable->header.checksum, (256 - ((checksum - chargetable->header.checksum) & 0xFF))); + continue; + } + + ok = true; + } + + gg_close(); + + // fill in the table + unsigned out_idx = 0; + + // decode each data entry + for (int data_entry_idx = 0; data_entry_idx < table_entries; data_entry_idx++) + { + for (int vi_idx = 0; vi_idx < vi_steps_per_entry; vi_idx++) + { + table_out[out_idx].lowerTempLimit = chargetable->data_entry[data_entry_idx].lower_temperature_limit * 100; + table_out[out_idx].upperTempLimit = chargetable->data_entry[data_entry_idx].higher_temperature_limit * 100; + + // do not limit the last entry in the table based on voltage + if ((vi_idx+1) == vi_steps_per_entry) + table_out[out_idx].upperVoltageLimit = USHRT_MAX; + else + table_out[out_idx].upperVoltageLimit = atv_voltage_limit[low_nibble(chargetable->data_entry[data_entry_idx].current_voltage_value[vi_idx])]; + + table_out[out_idx].currentSetting = atv_current_limit[high_nibble(chargetable->data_entry[data_entry_idx].current_voltage_value[vi_idx])]; + out_idx++; + } + } + + // fill out the rest with zeros + while (out_idx < num_elems) + { + table_out[out_idx].upperVoltageLimit = 0; + table_out[out_idx].lowerTempLimit = 0; + table_out[out_idx].upperTempLimit = 0; + table_out[out_idx].currentSetting = 0; + out_idx++; + } + +#if 0 + for (unsigned i = 0 ; i < num_elems; i++) { + dprintf(DEBUG_INFO, "\t{ %lu,\t%ld,\t%ld,\t%lu\t},\t\n", table_out[i].upperVoltageLimit, table_out[i].lowerTempLimit, table_out[i].upperTempLimit, table_out[i].currentSetting); + } +#endif + + return true; +#endif + + return false; +} + +int gasgauge_read_temperature(int *centiCelsius) +{ + if(0 == centiCelsius) return -1; + + if (!gg_open()) return -1; + + gasgauge_check_reset(); + uart_break(); + + int deciKelvin = hdqRead16(kHDQRegTemperature); + + gg_close(); + + if((deciKelvin < 0) || (deciKelvin > 6000)) { + printf("hdqgauge temperature bogus: %ddK\n", deciKelvin); + return -1; + } + *centiCelsius = (deciKelvin-2732) * 10; + return 0; +} + +int gasgauge_read_voltage(unsigned int *milliVolt) +{ + if(0 == milliVolt) return -1; + + if (!gg_open()) return -1; + + gasgauge_check_reset(); + uart_break(); + + unsigned int mV = hdqRead16(kHDQRegVoltage); + + gg_close(); + + if(mV > 6000) { + printf("hdqgauge voltage bogus: %dmV\n", mV); + return -1; + } + *milliVolt = mV; + return 0; +} + +int gasgauge_read_design_capacity(unsigned int *milliAmpHours) +{ + if(0 == milliAmpHours) return -1; + + if (!gg_open()) return -1; + + gasgauge_check_reset(); + uart_break(); + + int mAh = hdqRead16(kHDQRegDesignCapacity); + + gg_close(); + + if (mAh < 0) return -1; + + *milliAmpHours = mAh; + return 0; +} + +#if GG_CHECK_RA_TABLES +struct ra_table_info_t { + uint16_t chemID; + uint16_t R_a[15]; + int16_t avg_p; +}; + +struct ra_table_info_t ra_table_info[] = +{ + /* ATL */ + { 0x126, { 188, 188, 201, 232, 186, 176, 210, 251, 256, 266, 302, 363, 568, 1029, 1251 }, -955 }, + /* LGC */ + { 0x127, { 193, 193, 208, 252, 235, 186, 211, 247, 281, 287, 273, 369, 833, 1514, 1558 }, -937 }, + /* SONY */ + { 0x128, { 230, 230, 232, 253, 187, 169, 200, 236, 224, 214, 256, 301, 492, 973, 1217 }, -949 }, + /* SDI */ + { 0x129, { 165, 165, 204, 252, 186, 178, 200, 176, 175, 193, 208, 186, 240, 598, 1435 }, -938 }, +}; +#define NUM_RA_TABLES (sizeof(ra_table_info)/sizeof(ra_table_info[0])) + +#define RA_UPDATE_TEMPERATURE (2832) /* 283.2K = 10C */ +#define RA_UPDATE_CAPACITY (25) /* percent of design capacity */ +#define RA_UPDATE_FW_VERSION (0x0117) + +static const uint32_t kHDQUnsealKey = 0x36720414; + +static const int kHDQIntervalReset = 3*1000*1000; +static const int kHDQIntervalRelax = 5*1000*1000; + +static bool gg_ra_update_done = false; +static char *gg_ra_update_log = NULL; +static const int gg_ra_update_log_size = 2048; + +static void ra_log_val(const char *label, int value) +{ + size_t offset = strlen(gg_ra_update_log); + snprintf(gg_ra_update_log + offset, gg_ra_update_log_size - offset, "%s%s=%d", (offset == 0) ? "" : ",", label, value); +} + +static void ra_log_block(const char *label, const uint8_t *block) +{ + size_t offset = strlen(gg_ra_update_log); + snprintf(gg_ra_update_log + offset, gg_ra_update_log_size - offset, "%s%s=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + (offset == 0) ? "" : ",", label, block[0], block[1], block[2], block[3], block[4], block[5], block[6], block[7], block[8], block[9], block[10], block[11], block[12], block[13], block[14], block[15], + block[16], block[17], block[18], block[19], block[20], block[21], block[22], block[23], block[24], block[25], block[26], block[27], block[28], block[29], block[30], block[31]); +} +#endif + +bool gasgauge_check_health(unsigned int vbat_mv) +{ +#if GG_CHECK_RA_TABLES + /* If the gas gauge has corrupted resistance tables causing it to report too low + * capacity values (FullChargeCapacity, RemainingCapacity), the device will exhibit poor + * battery life and can get stuck in the battery trap forever. Attempt to detect this case, + * restore the resistance tables to their factory defaults, and hope this fixes the issue. + */ + + // only attempt once per boot + dprintf(DEBUG_SPEW, "gasgauge_check_health: gg_ra_update_done=%d\n", gg_ra_update_done); + if (gg_ra_update_done) + return false; + + // check that the voltage is high enough that: + // - we should have exited by now (e.g., if we're at 3.8V and still in the trap, something is wrong) + // - we have more than enough charge to perform the update without browning out the gauge + dprintf(DEBUG_SPEW, "gasgauge_check_health: vbat_mv=%d\n", vbat_mv); + if (vbat_mv < ALWAYS_BOOT_BATTERY_VOLTAGE) + return false; + + uint16_t temperature = hdqRead16(kHDQRegTemperature); + + // a low temperature can depress the capacity + dprintf(DEBUG_SPEW, "gasgauge_check_health: temp=%d\n", temperature); + if (temperature < RA_UPDATE_TEMPERATURE) + return false; + + int16_t full_charge_capacity = hdqRead16(kHDQRegFullChargeCapacity); + int16_t design_capacity = hdqRead16(kHDQRegDesignCapacity); + + dprintf(DEBUG_SPEW, "gasgauge_check_health: fcc=%d dc=%d\n", full_charge_capacity, design_capacity); + // primary check: the capacity should be lower than any real battery (or negative) + if (full_charge_capacity >= ((design_capacity * RA_UPDATE_CAPACITY) / 100)) + return false; + + // get the battery chemistry and look it up in the table of defaults. + uint16_t chem_id = controlRead16(kHDQControlRegChemID); + + const struct ra_table_info_t *ra_table = NULL; + for (unsigned idx = 0; idx < NUM_RA_TABLES; idx++) { + if (ra_table_info[idx].chemID == chem_id) { + ra_table = &ra_table_info[idx]; + break; + } + } + dprintf(DEBUG_SPEW, "gasgauge_check_health: chem_id=%#x ra_table=%p\n", chem_id, ra_table); + // if it's a chemistry we don't know, do not attempt an update + if (ra_table == NULL) + return false; + + // only apply the update with the firmware version known to exhibit this problem + uint16_t fw_version = controlRead16(kHDQControlRegFWVersion); + dprintf(DEBUG_SPEW, "gasgauge_check_health: fw version=%#x\n", fw_version); + if (fw_version != RA_UPDATE_FW_VERSION) + return false; + + // If a future data flash update corrects this problem and wants to disable this algorithm, + // it can write non-zero to byte zero of Manufacturer Info Block C (zero on all current packs). + uint8_t manufacturer_info_c[32]; + if (readBlock(kHDQDataSealedModeSubclass, kHDQDataSealedModeBlockManufacturerInfoBlockC, manufacturer_info_c) < 0) + return false; + dprintf(DEBUG_SPEW, "gasgauge_check_health: block c: %#x %#x\n", manufacturer_info_c[0], manufacturer_info_c[1]); + if (manufacturer_info_c[kHDQDataOffsetBlockManufacturerInfoBlockCFlags] != 0) + return false; + + dprintf(DEBUG_CRITICAL, "gas gauge full charge capacity %d/%d mAh (vbat %d mV temp %d dK chem ID %#x fw %#x): updating resistance tables\n", full_charge_capacity, design_capacity, vbat_mv, temperature, chem_id, fw_version); + + uint8_t gg_state[32]; + uint8_t ra_table_0[32]; + uint8_t ra_table_x[32]; + + // Create update log + gg_ra_update_log = malloc(gg_ra_update_log_size); + gg_ra_update_log[0] = '\0'; + + ra_log_val("vbat", vbat_mv); + ra_log_val("t", temperature); + ra_log_val("v", hdqRead16(kHDQRegVoltage)); + ra_log_val("ac", hdqRead16(kHDQRegAverageCurrent)); + ra_log_val("f", hdqRead16(kHDQRegFlags)); + ra_log_val("rc", hdqRead16(kHDQRegRemainingCapacity)); + ra_log_val("fcc", full_charge_capacity); + ra_log_val("dc", design_capacity); + ra_log_val("s", controlRead16(kHDQControlRegStatus)); + ra_log_val("fv", fw_version); + ra_log_val("rd", controlRead16(kHDQControlRegResetData)); + ra_log_val("ci", chem_id); + ra_log_block("mic", manufacturer_info_c); + + // unseal gas gauge + controlWrite16(kHDQUnsealKey & 0xFFFF, (kHDQUnsealKey >> 16) & 0xFFFF); + + if (readBlock(kHDQDataSubclassGasGaugingState, 0, gg_state) < 0) + return false; + + if (readBlock(kHDQDataSubclassRaTablesData, 0, ra_table_0) < 0) + return false; + + if (readBlock(kHDQDataSubclassRaTablesDataX, 0, ra_table_x) < 0) + return false; + + ra_log_block("82", gg_state); + ra_log_block("88", ra_table_0); + ra_log_block("89", ra_table_x); + + // update Avg P Last Run + gg_state[kHDQDataOffsetGasGaugingStateAvgPLastRun] = (ra_table->avg_p >> 8) & 0xFF; + gg_state[kHDQDataOffsetGasGaugingStateAvgPLastRun+1] = ra_table->avg_p & 0xFF; + + // update data tables + ra_table_0[0] = 0x00; + ra_table_0[1] = 0x55; + + ra_table_x[0] = 0x00; + ra_table_x[1] = 0x00; + + for (int idx = 0; idx < 15; idx++) { + int offset = 2 + 2*idx; + + ra_table_0[offset] = ra_table_x[offset] = (ra_table->R_a[idx] >> 8) & 0xFF; + ra_table_0[offset+1] = ra_table_x[offset+1] = ra_table->R_a[idx] & 0xFF; + } + + // increment update count and store in manufacturer info Block C + if (manufacturer_info_c[kHDQDataOffsetBlockManufacturerInfoBlockCUpdateCount] < 255) + manufacturer_info_c[kHDQDataOffsetBlockManufacturerInfoBlockCUpdateCount]++; + + // flash new data + writeBlock(kHDQDataSubclassRaTablesDataX, 0, ra_table_x); + writeBlock(kHDQDataSubclassRaTablesData, 0, ra_table_0); + writeBlock(kHDQDataSubclassGasGaugingState, 0, gg_state); + writeBlock(kHDQDataSealedModeSubclass, kHDQDataSealedModeBlockManufacturerInfoBlockC, manufacturer_info_c); + + ra_log_block("82'", gg_state); + ra_log_block("88'", ra_table_0); + ra_log_block("89'", ra_table_x); + + // pause charger to reduce current to the battery + bool charging = power_enable_charging(true, false); + + if (charging) { + // if we were charging, wait for the battery voltage to relax, to + task_sleep(kHDQIntervalRelax); + } + + ra_log_val("ac'", hdqRead16(kHDQRegAverageCurrent)); + + // reset gas gauge + controlRead16(kHDQControlRegReset); + + // wait for reset before communicating with the gauge + task_sleep(kHDQIntervalReset); + + // re-enable charger + power_enable_charging(true, true); + + // log new values + + ra_log_val("t*", hdqRead16(kHDQRegTemperature)); + ra_log_val("v*", hdqRead16(kHDQRegVoltage)); + ra_log_val("ac*", hdqRead16(kHDQRegAverageCurrent)); + ra_log_val("f*", hdqRead16(kHDQRegFlags)); + ra_log_val("rc*", hdqRead16(kHDQRegRemainingCapacity)); + ra_log_val("fcc*", hdqRead16(kHDQRegFullChargeCapacity)); + ra_log_val("dc*", hdqRead16(kHDQRegDesignCapacity)); + ra_log_val("s*", controlRead16(kHDQControlRegStatus)); + ra_log_val("fv*", controlRead16(kHDQControlRegFWVersion)); + ra_log_val("rd*", controlRead16(kHDQControlRegResetData)); + ra_log_val("ci*", controlRead16(kHDQControlRegChemID)); + if (readBlock(kHDQDataSealedModeSubclass, kHDQDataSealedModeBlockManufacturerInfoBlockC, manufacturer_info_c) == 0) + ra_log_block("mic*", manufacturer_info_c); + + gg_ra_update_done = true; + return true; +#endif + + return false; +} + +void gasgauge_late_init(void) +{ +#if GG_CHECK_RA_TABLES + // if the gas gauge resistance tables were updated, make a log in NVRAM + // for the OS to pick up and report. + if (gg_ra_update_done) + { +#if WITH_ENV + env_set("gg-data-update-info", gg_ra_update_log, ENV_PERSISTENT); +#if WITH_NVRAM + nvram_save(); +#endif +#endif + } +#endif +} + + +#if defined(WITH_MENU) && WITH_MENU + +static int +dataBlock(int class, int block, unsigned char *blockData) +{ + unsigned char blockDataLocal[32]; + unsigned char sum = 0, cksum; + int rc; + int idx, len, value; + bool sealedMode = (class == kHDQDataSealedModeSubclass); + + if (blockData == NULL) blockData = blockDataLocal; + + rc = hdqWrite8(kHDQRegBlockDataControl, sealedMode ? 1 : 0); + if (rc < 0) + return (rc); + + if (!sealedMode) { + rc = hdqWrite8(kHDQRegDataFlashClass, class); + if (rc < 0) + return (rc); + } + + printf("Class %d block %d\n", class, block); + + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); + len = sizeof(blockDataLocal); + rc = hdqWrite8(kHDQRegDataFlashBlock, block); + for (idx = 0; idx < len; idx++) + { + if (16 == idx) + printf("\n"); + value = hdqRead8(kHDQRegBlockData + idx); + if (value < 0) + return value; + + blockData[idx] = value; + sum += value; + printf(" %02x", value); + } + cksum = hdqRead8(kHDQRegBlockDataChecksum); + sum += cksum; + printf("\nsum %s, cksum 0x%x\n", (sum == 0xff) ? "ok" : "bad", cksum); + + if (sum != 0xff) + return -1; + + return (0); +} + +static int +writeData(int class, int block, struct cmd_arg *args) +{ + unsigned char oldData[32] = { 0 }; + unsigned char newData[32]; + int idx; + + printf("\nCURRENT DATA:\n\n"); + + dataBlock(class, block, oldData); + + printf("\nNEW DATA (changes \x1b[1;31mhighlighted\x1b[0m):\n\n"); + + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); + for (idx = 0; idx < 32; idx++) + { + if (16 == idx) + printf("\n"); + + newData[idx] = strtoul(args[idx].str, NULL, 16); + if (newData[idx] != oldData[idx]) + printf(" \x1b[1;31m%02x\x1b[0m", newData[idx]); + else + printf(" %02x", newData[idx]); + } + + printf("\nwriting data..."); + if (writeBlock(class, block, newData) == 0) + printf("done:\n\n"); + else + printf("failed!\n\n"); + dataBlock(class, block, 0); + + return 0; +} + +static void +usage(struct cmd_arg *args) +{ + puts("not enough arguments.\n"); + + printf("%s read print reg at addr\n", args[0].str); + printf("%s control print control reg at addr\n", args[0].str); + printf("%s flash dump flash block\n", args[0].str); + printf("%s flashwrite ... \n", args[0].str); + printf("%s reset reset gas gauge (toggle SWI line)\n", args[0].str); + printf("%s unseal unseal gas gauge\n", args[0].str); + printf("%s break no-op\n", args[0].str); +#if defined(BATTERY_TRAP_DEBUG) + printf("%s dump dump gas gauge registers\n", args[0].str); + printf("%s trap call battery trap check\n", args[0].str); +#endif +} + +static int do_hdq(int argc, struct cmd_arg *args) +{ + int16_t value; + int ret = 0; + + if (!gg_open()) { + printf("failed to open gas gauge\n"); + return -1; + } + + uart_break(); + + if (argc < 2) { + ret = -1; + } else if (!strcmp("read", args[1].str) && (argc == 3)) { + value = hdqRead16(args[2].u); + printf("0x%x, %d\n", value, value); + } else if (!strcmp("control", args[1].str) && (argc == 3)) { + value = controlRead16(args[2].u); + printf("0x%x, %d\n", value, value); + } else if (!strcmp("flash", args[1].str) && (argc == 4)) { + dataBlock(args[2].u, args[3].u, NULL); + } else if (!strcmp("flashwrite", args[1].str) && (argc == 36)) { + writeData(args[2].u, args[3].u, &args[4]); + } else if (!strcmp("reset", args[1].str) && (argc == 2)) { + gasgauge_reset(1); // hard reset + } else if (!strcmp("checkreset", args[1].str) && (argc == 2)) { + gasgauge_check_reset(); + } else if (!strcmp("unseal", args[1].str) && (argc == 3)) { + uint32_t key = args[2].u; + controlWrite16(key & 0xFFFF, (key >> 16) & 0xFFFF); + } else if (!strcmp("break", args[1].str) && (argc == 2)) { + // no-op +#if defined(BATTERY_TRAP_DEBUG) + } else if (!strcmp("dump", args[1].str) && (argc == 2)) { + gasgauge_dump(); + } else if (!strcmp("trap", args[1].str) && (argc == 2)) { + gasgauge_needs_precharge(DEBUG_CRITICAL, true); +#endif + } else { + ret = -1; + } + + gg_close(); + + if (ret) + usage(args); + + return ret; +} + +MENU_COMMAND_DEBUG(hdq, do_hdq, "HDQ read/write", NULL); +#endif /* WITH_MENU */ diff --git a/drivers/power/hdqgauge/rules.mk b/drivers/power/hdqgauge/rules.mk new file mode 100644 index 0000000..2c33ef9 --- /dev/null +++ b/drivers/power/hdqgauge/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2009 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_GASGAUGE_HDQ=1 \ + WITH_HW_GASGAUGE=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/hdqgauge.o diff --git a/drivers/primecell/pl080dmac/include/drivers/primecell/pl080dmac.h b/drivers/primecell/pl080dmac/include/drivers/primecell/pl080dmac.h new file mode 100644 index 0000000..4bd2b28 --- /dev/null +++ b/drivers/primecell/pl080dmac/include/drivers/primecell/pl080dmac.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PRIMECELL_PL080DMAC_H +#define __PRIMECELL_PL080DMAC_H + +#include +#include +#include + +struct pl080dmac_channel_config { + uint8_t channel; /* dmac channel */ + uint8_t type; /* source or destination */ + uint32_t config; /* source or destination config register */ + uint32_t control; /* source or destination control register */ + uintptr_t fifo_address; /* source or destination address */ +}; + +struct pl080dmac_config { + uint8_t dmac_clk; + uint32_t dmac_tc_irq; + uint32_t dmac_err_irq; + struct pl080dmac_channel_config dmac_channel_config[PL080DMAC_SUPPORTED_CHANNEL_COUNT]; +}; + +#define PL080DMAC_PERPH_SRC (0) +#define PL080DMAC_PERPH_DEST (1) + +#define PL080DMAC_FLOW_CTRL_DMAC (0) +#define PL080DMAC_FLOW_CTRL_SRC_PERPH (1) +#define PL080DMAC_FLOW_CTRL_DEST_PERPH (2) + +#define PL080DMAC_XFER_WIDTH_BYTE (0) +#define PL080DMAC_XFER_WIDTH_HALF_WORD (1) +#define PL080DMAC_XFER_WIDTH_WORD (2) + +#define PL080DMAC_MAX_TRANSFER_SIZE (0xFA0) /* Transfer size field in Channel_Config register is 12 bits wide (2^12 - 1). 0xFA0 is just a round up. */ + +#endif /* __PRIMECELL_PL080DMAC_H */ diff --git a/drivers/primecell/pl080dmac/pl080dmac.c b/drivers/primecell/pl080dmac/pl080dmac.c new file mode 100644 index 0000000..340caaa --- /dev/null +++ b/drivers/primecell/pl080dmac/pl080dmac.c @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pl080dmac_regs.h" + +#define CHANNEL_STATUS_UNINIT 0 +#define CHANNEL_STATUS_IDLE 1 +#define CHANNEL_STATUS_BUSY 2 +#define CHANNEL_STATUS_BUSY_UNINIT 3 + +struct pl080dmac_channel { + uint8_t status; + + uint32_t actual_xfer_size; + uint32_t current_xfer_size; + uint32_t total_xferred; + + /* callback for async operations */ + dma_completion_function callback; + void *callback_arg; +}; + +static bool pl080dmac_inited[PL080DMAC_COUNT]; +static struct pl080dmac_channel pl080dmac_channels[PL080DMAC_COUNT][PL080DMAC_SUPPORTED_CHANNEL_COUNT]; + +static void pl080dmac_dump_channel(int dma_channel); +static void pl080dmac_tc_int_handler(void *arg); +static void pl080dmac_err_int_handler(void *arg); + +void dma_init() +{ + uint8_t pl080dmac_idx; + + for (pl080dmac_idx = 0; pl080dmac_idx < PL080DMAC_COUNT; pl080dmac_idx++) { + clock_gate(pl080dmac_configs[pl080dmac_idx].dmac_clk, true); + + if (pl080dmac_configs[pl080dmac_idx].dmac_tc_irq) { + set_int_type(pl080dmac_configs[pl080dmac_idx].dmac_tc_irq, INT_TYPE_IRQ | INT_TYPE_LEVEL); + install_int_handler(pl080dmac_configs[pl080dmac_idx].dmac_tc_irq, pl080dmac_tc_int_handler, (void *)pl080dmac_idx); + unmask_int(pl080dmac_configs[pl080dmac_idx].dmac_tc_irq); + } + + if (pl080dmac_configs[pl080dmac_idx].dmac_err_irq) { + set_int_type(pl080dmac_configs[pl080dmac_idx].dmac_err_irq, INT_TYPE_IRQ | INT_TYPE_LEVEL); + install_int_handler(pl080dmac_configs[pl080dmac_idx].dmac_err_irq, pl080dmac_err_int_handler, (void *)pl080dmac_idx); + unmask_int(pl080dmac_configs[pl080dmac_idx].dmac_err_irq); + } + + // Enable DMAC + rPL080DMAC_CFG(pl080dmac_idx) = (1 << 0); + + pl080dmac_inited[pl080dmac_idx] = true; + } +} + +int dma_execute_cmd(uint32_t cmd, int dma_channel, void *src, + void *dst, uint32_t length, uint32_t word_size, + uint32_t burst_size) +{ + struct task_event event; + struct dma_segment seg; + void *fifo; + int32_t ret; + + // build an SGL for the one segment + switch (cmd & DMA_CMD_DIR_MASK) { + case DMA_CMD_DIR_TX: + seg.paddr = (uintptr_t)src; + fifo = dst; + break; + case DMA_CMD_DIR_RX: + seg.paddr = (uintptr_t)dst; + fifo = src; + break; + default: + return -1; + } + seg.length = length; + + // run the operation + event_init(&event, EVENT_FLAG_AUTO_UNSIGNAL, false); + ret = dma_execute_async(cmd, dma_channel, &seg, fifo, length, word_size, burst_size, + (dma_completion_function)event_signal, (void *)&event); + + if (!ret) + // and block waiting for it to complete + event_wait(&event); + + return ret; +} + +int dma_execute_async(uint32_t cmd, int dma_channel, + struct dma_segment *sgl, void *fifo, uint32_t length, + uint32_t word_size, uint32_t burst_size, + dma_completion_function completion, void *completion_arg) +{ + uint8_t dmac_idx; + struct pl080dmac_channel *ch; + const struct pl080dmac_channel_config *ch_config; + uint8_t expected_direction; + uint16_t xfer_size, xfer_width; + + dmac_idx = (dma_channel >> DMA_SELECTOR_SHIFT) & DMA_CHANNEL_MASK; + dma_channel = dma_channel & DMA_CHANNEL_MASK; + ch = &pl080dmac_channels[dmac_idx][dma_channel]; + ch_config = &pl080dmac_configs[dmac_idx].dmac_channel_config[dma_channel]; + expected_direction = (ch_config->type == PL080DMAC_PERPH_SRC) ? DMA_CMD_DIR_RX : DMA_CMD_DIR_TX; + + // sanity check + ASSERT(dmac_idx <= PL080DMAC_COUNT); + ASSERT(dma_channel <= PL080DMAC_CHANNEL_COUNT); + ASSERT(sgl); + ASSERT(length > 0); + ASSERT((uintptr_t)fifo == ch_config->fifo_address); + + // make sure controller is inited + ASSERT(pl080dmac_inited[dmac_idx] != false); + + // word_size and burst_size default are in pl080dmac_config table, overrides not allowed + ASSERT(word_size == 0); + ASSERT(burst_size == 0); + + // validate command + ASSERT((cmd & DMA_CMD_DIR_MASK) == expected_direction); + + // update channel status to busy but not initialized + enter_critical_section(); + ch->status = CHANNEL_STATUS_BUSY_UNINIT; + exit_critical_section(); + + // save the completion + ch->callback = completion; + ch->callback_arg = completion_arg; + + // calcuate transfer size, and cap it to max_trasnfer_size + xfer_width = (expected_direction == DMA_CMD_DIR_RX) ? + (ch_config->control >> 21) & 7 : (ch_config->control >> 18) & 7; + + // make sure length is multiple of transfer width + ASSERT((length % (1 << xfer_width)) == 0); + + xfer_size = length >> xfer_width; + ch->actual_xfer_size = xfer_size; + xfer_size = (xfer_size < PL080DMAC_MAX_TRANSFER_SIZE) ? xfer_size : PL080DMAC_MAX_TRANSFER_SIZE; + ch->current_xfer_size = xfer_size; + ch->total_xferred = 0; + + // initialize and configure channel + // PL080DMAC TRM, section 3.2.7 + // step 2 + rPL080DMAC_INTTCCLR(dmac_idx) = (1 << dma_channel); + rPL080DMAC_INTERRCLR(dmac_idx) = (1 << dma_channel); + // step 3,4,6,7 + if (ch_config->type == PL080DMAC_PERPH_SRC) { + rPL080DMAC_CHCTRL(dmac_idx, dma_channel) = (1 << 31) | (ch_config->control) | xfer_size; + rPL080DMAC_CHCFG(dmac_idx, dma_channel) = (1 << 15) | (1 << 14) | (ch_config->config); + rPL080DMAC_CHSRCADDR(dmac_idx, dma_channel) = ch_config->fifo_address; + rPL080DMAC_CHDESTADDR(dmac_idx, dma_channel) = sgl->paddr; + } else { + rPL080DMAC_CHCTRL(dmac_idx, dma_channel) = (1 << 31) | (ch_config->control) | xfer_size; + rPL080DMAC_CHCFG(dmac_idx, dma_channel) = (1 << 15) | (1 << 14) | (ch_config->config); + rPL080DMAC_CHDESTADDR(dmac_idx, dma_channel) = ch_config->fifo_address; + rPL080DMAC_CHSRCADDR(dmac_idx, dma_channel) = sgl->paddr; + } + // we only support 1 segment (linear dma) + rPL080DMAC_CHLLI(dmac_idx, dma_channel) = 0; + + // update channel status to busy + enter_critical_section(); + ch->status = CHANNEL_STATUS_BUSY; + exit_critical_section(); + + // start channel + rPL080DMAC_CHCFG(dmac_idx, dma_channel) |= (1 << 0); + + return 0; +} + +void dma_cancel(int dma_channel) +{ + uint8_t dmac_idx; + struct pl080dmac_channel *ch; + utime_t start_time; + + dmac_idx = (dma_channel >> DMA_SELECTOR_SHIFT) & DMA_CHANNEL_MASK; + dma_channel = dma_channel & DMA_CHANNEL_MASK; + ch = &pl080dmac_channels[dmac_idx][dma_channel]; + + // make sure controller is inited + ASSERT(pl080dmac_inited[dmac_idx] != false); + + // sanity check + ASSERT(dmac_idx <= PL080DMAC_COUNT); + ASSERT(dma_channel <= PL080DMAC_CHANNEL_COUNT); + + // it's legal but not interesting to cancel a channel that hasn't been initialized + if (CHANNEL_STATUS_UNINIT == ch->status) + return; + + start_time = system_time(); + + rPL080DMAC_CHCFG(dmac_idx, dma_channel) = 0; + while ((rPL080DMAC_ENBLDCHNLS(dmac_idx) >> dma_channel) != 0) { + if (time_has_elapsed(start_time, 10000)) + panic("PL080DMAC%d: channel %d timeout during abort", dmac_idx, dma_channel); + } + + // mark the channel idle + ch->status = CHANNEL_STATUS_IDLE; +} + +void dma_use_int(int dma_channel, bool use) +{ + uint8_t dmac_idx; + + dmac_idx = (dma_channel >> DMA_SELECTOR_SHIFT) & DMA_CHANNEL_MASK; + dma_channel = dma_channel & DMA_CHANNEL_MASK; + + if (use) + rPL080DMAC_CHCFG(dmac_idx, dma_channel) |= ((1 << 14) | (1 << 15)); + else + rPL080DMAC_CHCFG(dmac_idx, dma_channel) &= ~((1 << 14) | (1 << 15)); +} + +bool dma_poll(int dma_channel) +{ + bool ret = false; + struct pl080dmac_channel *ch; + uint8_t dmac_idx; + + dmac_idx = (dma_channel >> DMA_SELECTOR_SHIFT) & DMA_CHANNEL_MASK; + dma_channel = dma_channel & DMA_CHANNEL_MASK; + ch = &pl080dmac_channels[dmac_idx][dma_channel]; + + if (CHANNEL_STATUS_IDLE == ch->status) { + ret = true; + goto exit; + } + + enter_critical_section(); + + if (rPL080DMAC_INTTCSTATUS(dmac_idx) >> dma_channel) + pl080dmac_tc_int_handler((void *)dmac_idx); + else if (rPL080DMAC_INTERRSTATUS(dmac_idx) >> dma_channel) + pl080dmac_err_int_handler((void *)dmac_idx); + + exit_critical_section(); + + if (CHANNEL_STATUS_IDLE == ch->status) { + ret = true; + goto exit; + } + +exit: + return ret; +} + +int dma_set_aes(int dma_channel, struct dma_aes_config *config) +{ + // Not supported (PL080DMAC doesn't support AES) + return -1; +} + +static void pl080dmac_tc_int_handler(void *args) +{ + uint8_t pl080dmac_idx; + uint32_t tc_intsts; + uint8_t ch; + struct pl080dmac_channel *ch_info; + + pl080dmac_idx = (uint8_t)args; + + RELEASE_ASSERT(pl080dmac_idx < PL080DMAC_COUNT); + + tc_intsts = rPL080DMAC_INTTCSTATUS(pl080dmac_idx); + rPL080DMAC_INTTCCLR(pl080dmac_idx) = tc_intsts; + + while(tc_intsts != 0) { + ch = 31 - clz(tc_intsts); + ch_info = &pl080dmac_channels[pl080dmac_idx][ch]; + + ch_info->total_xferred += ch_info->current_xfer_size; + + if (ch_info->total_xferred < ch_info->actual_xfer_size) { + // start again + } + else { + ch_info->status = CHANNEL_STATUS_IDLE; + + // call the user-supplied callback + if (ch_info->callback != NULL) + ch_info->callback(ch_info->callback_arg); + } + + tc_intsts &= ~(1 << ch); + } +} + +static void pl080dmac_err_int_handler(void *args) +{ + uint8_t pl080dmac_idx; + uint32_t err_intsts; + + pl080dmac_idx = (uint8_t)args; + + RELEASE_ASSERT(pl080dmac_idx < PL080DMAC_COUNT); + + err_intsts = rPL080DMAC_INTERRSTATUS(pl080dmac_idx); + rPL080DMAC_INTERRCLR(pl080dmac_idx) = err_intsts; + + panic("PL080DMAC reported error on channels:0x%08x\n", err_intsts); +} diff --git a/drivers/primecell/pl080dmac/pl080dmac_regs.h b/drivers/primecell/pl080dmac/pl080dmac_regs.h new file mode 100644 index 0000000..c5cb056 --- /dev/null +++ b/drivers/primecell/pl080dmac/pl080dmac_regs.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _PL080DMAC_REGS_H +#define _PL080DMAC_REGS_H + +#include + +#define rPL080DMAC_INTSTATUS(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0000) +#define rPL080DMAC_INTTCSTATUS(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0004) +#define rPL080DMAC_INTTCCLR(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0008) +#define rPL080DMAC_INTERRSTATUS(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x000C) +#define rPL080DMAC_INTERRCLR(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0010) +#define rPL080DMAC_RAWINTTCSTATUS(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0014) +#define rPL080DMAC_RAWINTERRSTATUS(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0018) +#define rPL080DMAC_ENBLDCHNLS(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x001C) +#define rPL080DMAC_SOFTBREQ(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0020) +#define rPL080DMAC_SOFTSREQ(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0024) +#define rPL080DMAC_SOFTLBREQ(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0028) +#define rPL080DMAC_SOFTLSREQ(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x002C) +#define rPL080DMAC_CFG(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0030) +#define rPL080DMAC_SYNC(_n) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0034) +#define rPL080DMAC_CHSRCADDR(_n, _c) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0100 + ((_c) * 0x20)) +#define rPL080DMAC_CHDESTADDR(_n, _c) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0104 + ((_c) * 0x20)) +#define rPL080DMAC_CHLLI(_n, _c) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0108 + ((_c) * 0x20)) +#define rPL080DMAC_CHCTRL(_n, _c) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x010C + ((_c) * 0x20)) +#define rPL080DMAC_CHCFG(_n, _c) *(volatile uint32_t *)(PL080DMAC_BASE_ADDR + ((_n) * PL080DMAC_SPACING) + 0x0110 + ((_c) * 0x20)) + +#endif /* _PL080DMAC_REGS_H */ diff --git a/drivers/primecell/pl080dmac/rules.mk b/drivers/primecell/pl080dmac/rules.mk new file mode 100644 index 0000000..fc352e8 --- /dev/null +++ b/drivers/primecell/pl080dmac/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +OPTIONS += \ + WITH_HW_DMA=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/pl080dmac.o diff --git a/drivers/primecell/pl192vic/pl192vic.c b/drivers/primecell/pl192vic/pl192vic.c new file mode 100644 index 0000000..f41d71e --- /dev/null +++ b/drivers/primecell/pl192vic/pl192vic.c @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include + +#include + +#if WITH_HW_EDGEIC +#include +#endif + +#include "pl192vic.h" + +#define MAX_INTS (VICS_COUNT * 32) +static struct interrupt_entry handlers[MAX_INTS]; + +extern void __arm_irq(void); + +#if SUPPORT_SLEEP +struct vic_state { + u_int32_t enabled; + u_int32_t select; +}; + +static struct vic_state vic_saved_state[VICS_COUNT]; + +# define SAVE_ENABLED(_v, _i, _s) \ +do { \ + if (_s) { \ + vic_saved_state[(_v)].enabled |= (1 << (_i)); \ + } else { \ + vic_saved_state[(_v)].enabled &= ~(1<< (_i)); \ + } \ +} while(0) + +# define SAVE_SELECT(_v, _i, _s) \ +do { \ + if (_s) { \ + vic_saved_state[(_v)].select |= (1 << (_i)); \ + } else { \ + vic_saved_state[(_v)].select &= ~(1<< (_i)); \ + } \ +} while(0) + +#else +# define SAVE_ENABLED(_v, _i, _s) +# define SAVE_SELECT(_v, _i, _s) +#endif /* SUPPORT_SLEEP */ + +int interrupt_init(void) +{ + u_int32_t vic, vec; + +#if WITH_HW_EDGEIC + /* clear the pending int source block */ + edgeic_reset(); +#endif + + for (vic = 0; vic < VICS_COUNT; vic++) { + /* mask everything */ + rVICINTENCLEAR(vic) = 0xffffffff; + + /* set all vectors as int */ + rVICINTSELECT(vic) = 0; + + /* unmask all priority levels */ + rVICSWPRIORITYMASK(vic) = 0xffff; + + /* set up all the vector addresses with the vector number */ + for(vec = 0; vec < 32; vec++) { + rVICVECTADDR(vic, vec) = vic * 32 + vec; + } + +#if SUPPORT_SLEEP + /* restore saved state, or initialize to all off */ + rVICINTENABLE(vic) = vic_saved_state[vic].enabled; + rVICINTSELECT(vic) = vic_saved_state[vic].select; + + /* if any vectors are FIQs, unmask FIQ */ + if (vic_saved_state[vic].select != 0) + arm_enable_fiqs(); +#endif + } + /* also enable it */ + exit_critical_section(); + return 0; +} + +void interrupt_mask_all(void) +{ + u_int32_t vic; + + /* mask everything */ + for (vic = 0; vic < VICS_COUNT; vic++) { + rVICINTENCLEAR(vic) = 0xffffffff; + } +} + +void mask_int(u_int32_t vector) +{ + u_int32_t vic = vector / 32; + u_int32_t vec = vector % 32; + + ASSERT(vic < VICS_COUNT); + + enter_critical_section(); + + rVICINTENCLEAR(vic) |= 1 << vec; + + SAVE_ENABLED(vic, vec, false); + + exit_critical_section(); +} + +void unmask_int(u_int32_t vector) +{ + u_int32_t vic = vector / 32; + u_int32_t vec = vector % 32; + + ASSERT(vic < VICS_COUNT); + + enter_critical_section(); + + rVICINTENABLE(vic) |= 1 << vec; + + SAVE_ENABLED(vic, vec, true); + + exit_critical_section(); +} + + +void set_int_type(uint32_t vector, int type) +{ + u_int32_t vic = vector / 32; + u_int32_t vec = vector % 32; + bool edge; + + ASSERT(vic < VICS_COUNT); + + enter_critical_section(); + + if (type & INT_TYPE_FIQ) { + rVICINTSELECT(vic) |= (1 << vec); + SAVE_SELECT(vic, vec, true); + arm_enable_fiqs(); + } else { + rVICINTSELECT(vic) &= ~(1 << vec); + SAVE_SELECT(vic, vec, false); + } + + edge = (type & INT_TYPE_EDGE) != 0; +#if WITH_HW_EDGEIC + handlers[vector].edge = edge; + edgeic_select_edge(vector, edge); +#else + if (edge) + panic("set_int_type: edge not supported\n"); +#endif + + exit_critical_section(); +} + +int install_int_handler(uint32_t vector, int_handler handler, void *arg) +{ + ASSERT(vector < MAX_INTS); + + enter_critical_section(); + + handlers[vector].handler = handler; + handlers[vector].arg = arg; + + exit_critical_section(); + + return 0; +} + +void platform_irq(void) +{ + u_int32_t vic, vector; + + for (vic = 0; vic < VICS_COUNT; vic++) { + if (rVICIRQSTATUS(vic) != 0) { + break; + } + } + if (vic >= VICS_COUNT) { + return; // false alarm + } + + vector = rVICADDR(vic); +// printf("irq: %d\n", vector); + + if (vector < MAX_INTS ) { + + if (handlers[vector].edge) { +#if WITH_HW_EDGEIC + edgeic_clear_interrupt(vector); +#else + panic("platform_irq: edge not supported\n"); +#endif + } + if (handlers[vector].handler) + handlers[vector].handler(handlers[vector].arg); + } else { + void (*crap_isr)(void); + crap_isr = (void (*)(void) )vector; + crap_isr(); + } + + /* EOI the interrupt controller */ + rVICADDR(vic) = 1; +} + +void platform_fiq(void) +{ + u_int32_t vic, pending = 0, vector = 0; + + for (vic = 0; vic < VICS_COUNT; vic++) { + pending = rVICFIQSTATUS(vic); + if (pending != 0) break; + vector += 32; + } + + if (pending == 0) { + return; + } + + vector += __builtin_ctz(pending); +// printf("fiq: 0x%x %d\n", pending, vector); + + if (handlers[vector].handler) + handlers[vector].handler(handlers[vector].arg); +} + +#ifdef IPC_VIC_BASE_ADDR +/* + * Ring our partner's doorbell. + */ +void interrupt_generate_ipc(u_int32_t vector) +{ + u_int32_t vic = vector / 32; + u_int32_t vec = vector % 32; + + rVICIPCSOFTINT(vic) = (1 << vec); +} + +/* + * Clear the doorbell interrupt from our partner. + */ +void interrupt_clear_ipc(u_int32_t vector) +{ + u_int32_t vic = vector / 32; + u_int32_t vec = vector % 32; + + rVICSOFTINTCLEAR(vic) = (1 << vec); +} +#endif + +static void +do_int_panic(void *arg __unused) +{ + int vic, vec; + for (vic = 0; vic < VICS_COUNT; vic++) { + u_int32_t en = rVICINTENABLE(vic); + u_int32_t stat = rVICIRQSTATUS(vic); + + printf("rVICINTENABLE(%d) = 0x%08x\n", vic, en); + printf("rVICIRQSTATUS(%d) = 0x%08x\n", vic, stat); + + for (vec = 0; vec < 32; vec++) { + const int vector = (vic * 32) + vec; + const struct interrupt_entry *entry = &handlers[vector]; + const bool enabled = en & (1 << vec); + const bool requested = stat & (1 << vec); + // Print if it's enabled, requested or has a handler + if (enabled || requested || (NULL != entry->handler)) { + printf("vector[%d]: %s:%d - h=%p\n", vector, + (enabled ? "unmsk" : "mask"), + (requested ? 1 : 0), + entry->handler); + } + } + } +} + +#if APPLICATION_EMBEDDEDIOP +PANIC_HOOK(irq, do_int_panic, NULL); +#endif diff --git a/drivers/primecell/pl192vic/pl192vic.h b/drivers/primecell/pl192vic/pl192vic.h new file mode 100644 index 0000000..93c282d --- /dev/null +++ b/drivers/primecell/pl192vic/pl192vic.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PRIMECELL_PL192VIC_H +#define __PRIMECELL_PL192VIC_H + +#include + +#define rVICIRQSTATUS(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x000)) +#define rVICFIQSTATUS(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x004)) +#define rVICRAWINTR(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x008)) +#define rVICINTSELECT(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x00C)) +#define rVICINTENABLE(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x010)) +#define rVICINTENCLEAR(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x014)) +#define rVICSOFTINT(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x018)) +#define rVICSOFTINTCLEAR(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x01C)) +#define rVICPROTECTION(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x020)) +#define rVICSWPRIORITYMASK(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x024)) +#define rVICPRIORITYDAISY(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x028)) +#define rVICVECTADDR(v, n) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x100 + (n) * 4)) +#define rVICVECTPRIO(n) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x200 + (n) * 4)) +#define rVICADDR(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xF00)) +#define rVICPERID0(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFE0)) +#define rVICPERID1(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFE4)) +#define rVICPERID2(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFE8)) +#define rVICPERID3(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFEC)) +#define rVICPCELLID0(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFF0)) +#define rVICPCELLID1(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFF4)) +#define rVICPCELLID2(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFF8)) +#define rVICPCELLID3(v) (*(volatile u_int32_t *)(VIC_BASE_ADDR + (v) * VIC_STRIDE + 0xFFC)) + +/* + * If the platform has a VIC used for inter-processor communication, + * we need to be able to touch its soft-int register. + */ +#ifdef IPC_VIC_BASE_ADDR +# define rVICIPCSOFTINT(v) (*(volatile u_int32_t *)(IPC_VIC_BASE_ADDR + (v) * VIC_STRIDE + 0x018)) +#endif + +#endif /* __PRIMECELL_PL192VIC_H */ diff --git a/drivers/primecell/pl192vic/rules.mk b/drivers/primecell/pl192vic/rules.mk new file mode 100644 index 0000000..b70d6ca --- /dev/null +++ b/drivers/primecell/pl192vic/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_VIC=1 + +ALL_OBJS += $(LOCAL_DIR)/pl192vic.o diff --git a/drivers/samsung/aes/aes.c b/drivers/samsung/aes/aes.c new file mode 100644 index 0000000..e8899f2 --- /dev/null +++ b/drivers/samsung/aes/aes.c @@ -0,0 +1,604 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "aes.h" + +/* aes driver, copy and customize */ +#define AES_MAX_BOUNCE_BUFFER 64 + +static volatile u_int32_t gAesIrqDoneFlag = 0; +static u_int8_t g_bounce_buffer[AES_MAX_BOUNCE_BUFFER] __attribute__ ((aligned (32))); +static int aes_inited = 0; +static int key_size_to_bytes(enum aes_key_size size) +{ + return 16 + (size * 8); +} + +void aes_init(void) +{ + dprintf(DEBUG_SPEW,"aes_init()\n"); + clock_gate(CLK_AES, true); + + AES_MODULE_POWER_ON(); + AesInit(); + aes_inited = 1; +} + +/*! \fn void AesInit(void) +* \brief power on and initialize AES module +* \param none +* \return none +*/ +u_int32_t AesInit(void) +{ + gAesIrqDoneFlag = 0; +/* install_int_handler(INT_AES, Isr_AesHandler, 0); */ +/* unmask_int(INT_AES); */ + rAES_IRQ_MASK = 0x00000000; /** Mask all interrupt source */ + + return 0; +} + +/*! \fn void AesUninit(void) +* \brief release AES module +* \param none +* \return none +*/ +u_int32_t AesUninit(void) +{ + gAesIrqDoneFlag = 0; + + AES_MODULE_POWER_OFF(); + //rAES_IRQ_MASK = 0x00000000; /** Mask all interrupt source */ + +/* mask_int(INT_AES); */ +// SysResetInterrupt(INT_AES); + + return 0; +} + +/*! \fn void AesOff(void) +* \brief Power Off AES module +* \param none +* \return +*/ +void AesOff(void) +{ + AES_MODULE_POWER_OFF(); /** AES module is disabled and preparation for clock down */ + //while(!(rAES_POWER & 0x02)); /** ready for clock down */ +} + +/*! \fn void _AesSetKeyType(u_int32_t cipherKeyType) +* \brief power off AES module +* \param cipherKeyType cipher key type +* \return none +*/ +void _AesSetKeyType(enum aes_key_type cipherKeyType) +{ + rAES_CIPHERKEY_SEL = cipherKeyType; +#if AES_VERSION > 0 + rAES_COMPLIMENT = ~rAES_CIPHERKEY_SEL; +#endif +} + +/*! \fn void _AesSetKey(u_int8_t *pKeyArr) +* \brief set cipher keys into AES module +* \param[in] pKeyArr 128-bit Key +* \return none +*/ +void _AesSetKey(u_int8_t *pKeyArr) +{ + /*<<< joe.kang@H1 061212: EVT 2 new code 061212*/ + u_int32_t index; + u_int32_t uLength; + volatile u_int32_t * reg; + + if(rAES_CIPHERKEY_SEL == 0) /* 0 is a user defined key */ + { + switch ((rAES_CFG & 0x30)>>4) + { + + case 1: // 192 bit + reg = &rAES_KEY_MM; + uLength = 6; + break; + case 2: // 256 bit + reg = &rAES_KEY_MX; + uLength = 8; + break; + case 0: // 128 bit + default: + reg = &rAES_KEY_X; + uLength = 4; + break; + } + + for(index = 0 ;index < uLength ;index ++) + { +#if AES_VERSION > 0 + *(reg + index) = *(u_int32_t *)(pKeyArr + index * 4); +#else + *(reg + index) = swap32(*(u_int32_t *)(pKeyArr + index * 4)); +#endif + } + } +} +/*! \fn void _AesClearKey(void) +* \brief clear cipher keys into AES module +* \param[in] void +* \return none +*/ +void _AesClearKey(void) +{ + /*<<< joe.kang@H1 061212: EVT 2 new code 061212*/ + memset ((void *) &rAES_KEY_MX, 0, 32); +} + +/*! \fn void _AesClearIV(void) +* \brief clear cipher keys into AES module +* \param[in] void +* \return none +*/ +void _AesClearIV(void) +{ + /*<<< joe.kang@H1 061212: EVT 2 new code 061212*/ + memset ((void *) &rAES_IV_1, 0, 16); +} + + +/*! \fn void AesSoftwareReset(void) +* \brief apply software reset to AES module +* \param none +* \return none +*/ +void AesSoftwareReset(void) +{ + rAES_SWRST = 0x00000001; /** Software Reset for AES */ + rAES_SWRST = 0x00000000; /** No Reset */ +} + +/*! \fn INT32T AesReadyToStart(void); + * @brief This function set configurations for ready to start AES Engine. + * + * @param NONE + * @return 0 if success. others if failed. + * @see AesNotifyComplete + */ +u_int32_t AesReadyToStart(void) +{ + /* Set ready to start */ + gAesIrqDoneFlag = 0; + + return 0; +} + +void AesSetVector(u_int8_t * pLocalIv) +{ + int index; + volatile u_int32_t * reg; + + if (pLocalIv == 0) + { + rAES_IV_1 = 0; + rAES_IV_2 = 0; + rAES_IV_3 = 0; + rAES_IV_4 = 0; + } + else + { + /*<<< joe.kang@H1 061212: EVT 2 new code 061212*/ + reg = &rAES_IV_1; + for(index = 0 ;index < 4 ;index ++) + { +#if AES_VERSION > 0 + *(reg + index) = *(u_int32_t *)(pLocalIv + index * 4); +#else + *(reg + index) = swap32(*(u_int32_t *)(pLocalIv + index * 4)); +#endif + } + } + + return; +} + +/*! \fn void AesStartEncryption(u_int8_t *destAddr, u_int8_t *srcAddr, u_int32_t size, u_int32_t keyType, u_int32_t *keyArr) +* \brief encrypt data +* \param destAddr destination address +* \param srcAddr source address +* \param size number of bytes +* \param[in] keyArr cipher key array +* \return none +*/ +void AesStartEncryption( +u_int8_t *destAddr, +u_int8_t *srcAddr, +u_int8_t *cryptoAddr, +u_int32_t size, +u_int32_t keyType, +u_int8_t *keyArr, +u_int32_t keySize, +bool bChainingMode, +u_int32_t srcSize, +u_int32_t dstSize, +u_int32_t cryptoSize, +u_int8_t *pIv) +{ + /* Ready to start */ + AesReadyToStart(); + + AesSoftwareReset(); + AES_MODULE_POWER_ON(); + // rAES_IRQ_MASK = 0x0000000F; /** Unmask all interrupt source */ + + _AesSetKeyType(keyType); + _AesSetKey(keyArr); + //if(bChainingMode == true) + //AesSetVector(); + /** aes key size : 128bit, stay in pause state & wait for CPU's action, Encryption */ + rAES_CFG = (0x3<<1); + AesSetCryption(true); + AesSetKeySize(keySize); + AesSetChainingMode(bChainingMode); + + AesSetVector(pIv); + + rAES_XFR_NUM = size; /** Total Transfer Number (number of bytes) */ + rAES_TBUF_START = (u_int32_t)destAddr; /** Start Address of Target Buffer (byte aligned) */ + rAES_TBUF_SIZE = dstSize; /** Size of Taget Buffer (byte aligned) */ + + + rAES_SBUF_START = (u_int32_t)srcAddr; /** Start Address of Source Buffer (byte aligned) */ + rAES_SBUF_SIZE = srcSize; /** Size of Source Buffer (byte aligned) */ + + + rAES_CRYPT_START = (u_int32_t)cryptoAddr; /** Starting Address of Encryption in Source Buffer (byte aligned) */ + rAES_CRYPT_SIZE = cryptoSize; /** Size of Encryption (16 byte aligned) */ + + gAesIrqDoneFlag = 0; + + _AesStart(); +} + +/*! \fn void AesStartDecryption(u_int8_t *destAddr, u_int8_t *srcAddr, u_int32_t size, u_int32_t keyType, u_int32_t *keyArr) +* \brief decrypt data +* \param destAddr destination address +* \param srcAddr source address +* \param size number of bytes +* \param[in] keyArr cipher key array +* \return none +*/ +void AesStartDecryption( +u_int8_t *destAddr, +u_int8_t *srcAddr, +u_int8_t *cryptoAddr, +u_int32_t size, +u_int32_t keyType, +u_int8_t *keyArr, +u_int32_t keySize, +bool bChainingMode, +u_int32_t srcSize, +u_int32_t dstSize, +u_int32_t cryptoSize, +u_int8_t *pIv) +{ + /* Ready to start */ + AesReadyToStart(); + + AesSoftwareReset(); + AES_MODULE_POWER_ON(); + + _AesSetKeyType(keyType); + + // rAES_IRQ_MASK = 0x0000000F; /** Unmask all interrupt source */ + + _AesSetKey(keyArr); + + //if(bChainingMode == true) + //AesSetVector(); + /** aes key size : 128bit, stay in pause state & wait for CPU's action, Decryption */ + rAES_CFG = (0x3<<1); + AesSetCryption(false); + AesSetKeySize(keySize); + AesSetChainingMode(bChainingMode); + + AesSetVector(pIv); + + rAES_XFR_NUM = size; + rAES_TBUF_START = (u_int32_t)destAddr; /** Start Address of Target Buffer (number of bytes) */ + rAES_TBUF_SIZE = dstSize; /** Size of Target Buffer (byte aligned) */ + rAES_SBUF_START = (u_int32_t)srcAddr; /** Start Address of Source Buffer (byte aligned) */ + rAES_SBUF_SIZE = srcSize; /** Unmask all interrupt source */ + + + rAES_CRYPT_START = (u_int32_t)cryptoAddr; /** Starting Address of Decryption in Source Buffer (byte aligned) */ + rAES_CRYPT_SIZE = cryptoSize; /** Size of Decryotion (16 byte aligned) */ + + gAesIrqDoneFlag = 0; + + _AesStart(); +} + +/*! \fn void _AesStart(void) +* \brief start aes +* \param none +* \return none +*/ +void _AesStart(void) +{ +#if AES_SYNCH_START + rAES_ENDIAN = (1 << 1); // Set Synch-Start bit +#else + rAES_COMMAND = CMD_AES_START; // Set Asynch-Start bit +#endif +} + +/*! \fn u_int32_t AesGetIrqStatus(void) +* \brief Get IRQ status return +* \param none +* \return none +*/ +u_int32_t +AesGetIrqStatus(void) +{ + return rAES_IRQ; +} + +/*! \fn void AesGetIrqStatus(u_int32_t status) +* \brief Set IRQ status return +* \param IRQ status +* \return none +*/ +void AesSetIrqStatus(u_int32_t status) +{ + rAES_IRQ = status; +} + +/*! \fn INT32T AesNotifyComplete(void); + * @remark This function must be implemented by apple. SAMSUNG just offer + * a reference code. + * + * @brief Nofity AES operation complete. + * @param NONE + * @return @c 0 if success. @c -1 if failed. + * @see AesWaitForComplete, AesReadyToStart + */ +u_int32_t AesNotifyComplete(void) +{ + gAesIrqDoneFlag = 1; + + return 0; +} + +/*! \fn INT32T AesWaitForComplete(void); + * \remark This function must be implemented by apple. SAMSUNG just offer + * a reference code. + * \brief Wait until AES operation complete. + * \param NONE + * \return @c 0 if success. @c -1 if failed. + * \see AesNotifyComplete + */ +u_int32_t +AesWaitForComplete(void) +{ + /* polling until AES I/O complete */ + //while(gAesIrqDoneFlag == 0); + while( 0 == (rAES_IRQ & 0xf) ) ; +#if AES_SYNCH_START + /* synch zeroes XFR_NUM - must wait to avoid racing */ + while( 0 != rAES_XFR_NUM ) ; +#endif + /*<<< joe.kang@H1 061212: EVT 2 new code 061212*/ + _AesClearKey(); + _AesClearIV(); + // clear all pending IRQs + rAES_IRQ = 0xf; + + return 0; +} + +/*! \fn void Isr_AesHandler(void) +* \brief interrupt service routine +* \param none +* \return none +*/ +void Isr_AesHandler(void *arg) +{ + u_int32_t status; + + status = rAES_IRQ; + + dprintf(DEBUG_SPEW,"aes_int: status 0x%x\n", status); +#if 0 + /* check the status */ + if(status & AES_IRQ_XFR_DONE_BIT) + { + gAesIrqDoneFlag = 1; + } + + if(status & AES_IRQ_TBUF_FULL_BIT) + { + g_pRomGlobals->gAesIrqDoneFlag = 1; + } + + if(status & AES_IRQ_SBUF_EMPTY_BIT) + { + ; + } + + if(status & AES_IRQ_ILLEGAL_OP_BIT) + { + ; + } +#endif + + /* clear status register */ + rAES_IRQ = status; + + /* Notify to the module pended */ + if (AesNotifyComplete() != 0) + { + panic("AesNotifyComplete() return !0"); + } +} + +/*! \fn void AesSetKeySize(void) +* \brief set key size +* \param none +* \return none +*/ +void AesSetKeySize(enum aes_key_size keysize) +{ + u_int32_t rdata; + u_int32_t wmask; + u_int32_t wdata; + + wmask = (3<<4); + rdata = rAES_CFG & (~wmask); + + wdata = rdata | (keysize<<4); + rAES_CFG = wdata; +} + +/*! \fn void AesSetChainingMode(void) +* \brief select chaining Mode +* \param none +* \return none +*/ +void AesSetChainingMode(bool bFlag) +{ + u_int32_t rdata; + u_int32_t wmask; + u_int32_t wdata; + + wmask = (1<<3); + rdata = rAES_CFG & (~wmask); + + wdata = rdata | (bFlag<<3); + rAES_CFG = wdata; +} +/*! \fn void AesSetCryption(void) +* \brief select cryption mode +* \param none +* \return none +*/ +void AesSetCryption(bool bFlag) +{ + /** + * bFlag 0: decryption / 1: encryption + */ + u_int32_t rdata; + u_int32_t wmask; + u_int32_t wdata; + + wmask = (1<<0); + rdata = rAES_CFG & (~wmask); + + wdata = rdata | (bFlag<<0); + rAES_CFG = wdata; +} + +bool +AesGetCryption(void) +{ + bool result; + + result = (bool)(rAES_CFG & 0x01); + + return result; +} + +/*! + */ +void +AesSetCommand(u_int32_t cmd) +{ + rAES_COMMAND = cmd; +} + +/*! + */ +void +AesSetSourceConfig(u_int32_t addr, u_int32_t size) +{ + rAES_SBUF_START = addr; + + if(size != 0xffffffff) + { + rAES_SBUF_SIZE = size; + } +} +/*! + */ +void +AesSetCryptConfig(u_int32_t addr, u_int32_t size) +{ + rAES_CRYPT_START = addr; + + if(size != 0xffffffff) + { + rAES_CRYPT_SIZE = size; + } +} + +int +AES_CBC_DecryptInPlace(u_int8_t * pAddr, u_int32_t u32Len, u_int32_t keyType, u_int8_t * pKey, u_int8_t * pIv) +{ + u_int8_t *addr = pAddr; + + aes_init(); + + if ( AES_MAX_BOUNCE_BUFFER >= u32Len ) { + memcpy( g_bounce_buffer, pAddr, u32Len ); + addr = g_bounce_buffer; + } + + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, 0, 0); + AesStartDecryption((u_int8_t *)addr, (u_int8_t *)addr, (u_int8_t *)addr, u32Len, keyType, pKey, 0, 1, u32Len, u32Len, u32Len, pIv); + AesWaitForComplete(); + + if ( AES_MAX_BOUNCE_BUFFER >= u32Len ) { + memcpy( pAddr, addr, u32Len ); + } + + return 0; +} + + +bool +AES_CBC_EncryptInPlace(u_int8_t * pAddr, u_int32_t u32Len, u_int32_t keyType, u_int8_t * pKey, u_int8_t * pIv) +{ + u_int8_t *addr = pAddr; + + aes_init(); + + if ( AES_MAX_BOUNCE_BUFFER >= u32Len ) { + memcpy( g_bounce_buffer, pAddr, u32Len ); + addr = g_bounce_buffer; + } + + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, 0, 0); + AesStartEncryption((u_int8_t *)addr, (u_int8_t *)addr, (u_int8_t *)addr, u32Len, keyType, pKey, 0, 1, u32Len, u32Len, u32Len, pIv); + AesWaitForComplete(); + + if ( AES_MAX_BOUNCE_BUFFER >= u32Len ) { + memcpy( pAddr, addr, u32Len ); + } + + return 0; +} diff --git a/drivers/samsung/aes/aes.h b/drivers/samsung/aes/aes.h new file mode 100644 index 0000000..d9fa9cc --- /dev/null +++ b/drivers/samsung/aes/aes.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef _SAMSUNG_AES_H +#define _SAMSUNG_AES_H + +#include +#include +#include + +__BEGIN_DECLS + +#define rAES_POWER (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x00)) +#define rAES_COMMAND (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x04)) +#define rAES_SWRST (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x08)) +#define rAES_IRQ (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x0C)) +#define rAES_IRQ_MASK (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x10)) +#define rAES_CFG (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x14)) +#define rAES_XFR_NUM (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x18)) +#define rAES_XFR_CNT (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x1C)) +#define rAES_TBUF_START (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x20)) +#define rAES_TBUF_SIZE (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x24)) +#define rAES_SBUF_START (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x28)) +#define rAES_SBUF_SIZE (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x2C)) +#define rAES_CRYPT_START (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x30)) +#define rAES_CRYPT_SIZE (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x34)) +#define rAES_CADDR_TBUF (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x38)) +#define rAES_CADDR_SBUF (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x3C)) +#define rAES_XFR_STATUS (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x40)) +#define rBUS_FIFO_STATUS (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x44)) +#define rAES_FIFO_STATUS (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x48)) +#define rAES_KEY_MX (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x4C)) +#define rAES_KEY_MH (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x50)) +#define rAES_KEY_MM (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x54)) +#define rAES_KEY_ML (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x58)) +#define rAES_KEY_X (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x5C)) +#define rAES_KEY_H (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x60)) +#define rAES_KEY_M (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x64)) +#define rAES_KEY_L (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x68)) +#define rAES_CIPHERKEY_SEL (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x6C)) +#define rAES_ENDIAN (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x70)) +#define rAES_IV_1 (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x74)) +#define rAES_IV_2 (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x78)) +#define rAES_IV_3 (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x7C)) +#define rAES_IV_4 (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x80)) +#define rAES_COMPLIMENT (*(volatile u_int32_t *)(AES_BASE_ADDR + 0x88)) + +#define CMD_AES_STOP 0 //Command Stop (Pause) +#define CMD_AES_START 1 //Command Start (only available in idle state) +#define CMD_AES_ABORT 2 //Command Abort +#define CMD_AES_CONTINUE 3 //Command Continue (only available in pause state) + +#define AES_KEY_TYPE_USER_DEFINE 0 +#define AES_KEY_TYPE_GLOBAL_ID 1 +#define AES_KEY_TYPE_USER_ID 2 + +#define AES_IRQ_XFR_DONE_BIT (1<<0) +#define AES_IRQ_TBUF_FULL_BIT (1<<1) +#define AES_IRQ_SBUF_EMPTY_BIT (1<<2) +#define AES_IRQ_ILLEGAL_OP_BIT (1<<3) + +#define AES_MODULE_POWER_ON() rAES_POWER = 0x00000001 +#define AES_MODULE_POWER_OFF() rAES_POWER = 0x00000000 + +/** +* AES KEY SIZE +*/ +enum aes_key_size { + _AES_KEY_SIZE_128 = 0, + _AES_KEY_SIZE_192, + _AES_KEY_SIZE_256, + + _AES_KEY_SIZE_MAX +}; + + +#define AES_MODE_ECB 0 /*Electronic Codebook*/ +#define AES_MODE_CBC 1 /*Cipher Block Chaining*/ + +u_int32_t AesInit(void); +u_int32_t AesUninit(void); +u_int32_t AesWaitForComplete(void); + +void AesSetKeySize(enum aes_key_size keysize); +void AesSetChainingMode(bool bFlag); +void AesSetCryption(bool bFlag); + +void _AesStart(void); + +__END_DECLS + +#endif /* ! _SAMSUNG_AES_H */ diff --git a/drivers/samsung/aes/rules.mk b/drivers/samsung/aes/rules.mk new file mode 100644 index 0000000..69b657e --- /dev/null +++ b/drivers/samsung/aes/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_OLD_AES=1 + +MODULES += \ + drivers/aes + +ALL_OBJS += $(LOCAL_DIR)/aes.o diff --git a/drivers/samsung/arm7iop/arm7.c b/drivers/samsung/arm7iop/arm7.c new file mode 100644 index 0000000..ff0c43f --- /dev/null +++ b/drivers/samsung/arm7iop/arm7.c @@ -0,0 +1,101 @@ +/* + * Test/debug code to mess with the arm7 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_MENU +#if DEBUG_BUILD + +#define ARM7M_ALIGN (1 << 12) +#define ARM7M_ALIGN_MASK (ARM7M_ALIGN - 1) + +int do_arm7_go(int argc, struct cmd_arg *args) +{ + addr_t addr; + + addr = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + + if (addr & ARM7M_ALIGN_MASK) { + dprintf(DEBUG_CRITICAL, "load address not on a page boundary, cannot remap\n"); + return(-1); + } + dprintf(DEBUG_INFO, "configuring ARM7M for image @ 0x%08x\n", addr); + + /* clock on */ + clock_gate(CLK_ISP, true); + clock_gate(CLK_MSVDX, true); + clock_gate(CLK_ARM7, true); + clock_reset_device(CLK_ARM7); + + /* turn the arm7m off and reset it */ + rARM7M_CTRL = 0; + rARM7M_CTRL = ARM7M_CTRL_RESET; + + /* set up translation */ + rARM7M_AT_BASE = addr; + rARM7M_AT_RANGE = 0x03ff0000; /* give the ARM7 1MiB of DDR */ + + /* start */ + rARM7M_CTRL = ARM7M_CTRL_ENABLE; + + return(0); +} + +MENU_COMMAND_DEBUG(arm7_go, do_arm7_go, "start ARM7M with a downloaded image", NULL); + +int do_arm7_stop(int argc, struct cmd_arg *args) +{ + + /* turn the arm7m off and reset it */ + rARM7M_CTRL = 0; + rARM7M_CTRL = ARM7M_CTRL_RESET; + + /* clock off */ + clock_gate(CLK_ARM7, false); + + return(0); +} + +MENU_COMMAND_DEBUG(arm7_stop, do_arm7_stop, "stop the arm7", NULL); + +#ifdef GPIO_ARM7_DEBUG + +int do_arm7_jtag_select(int argc, struct cmd_arg *args) +{ +#if (GPIO_ARM7_DEBUG_ARM7 >= 0) + gpio_configure_out(GPIO_ARM7_DEBUG, GPIO_ARM7_DEBUG_ARM7); +#else + gpio_configure_in(GPIO_ARM7_DEBUG); +#endif + return(0); +} + +MENU_COMMAND_DEVELOPMENT(arm7_jtag, do_arm7_jtag_select, "switch JTAG from Cortex to ARM7M", NULL); + +int do_cortex_jtag_select(int argc, struct cmd_arg *args) +{ +#if (GPIO_ARM7_DEBUG_CORTEX >= 0) + gpio_configure_out(GPIO_ARM7_DEBUG, GPIO_ARM7_DEBUG_CORTEX); +#else + gpio_configure_in(GPIO_ARM7_DEBUG); +#endif + return(0); +} + +MENU_COMMAND_DEVELOPMENT(cortex_jtag, do_cortex_jtag_select, "switch JTAG from ARM7M to Cortex", NULL); + +#endif /* GPIO_ARM7_DEBUG */ + +#endif /* DEBUG_BUILD */ +#endif /* WITH_MENU */ diff --git a/drivers/samsung/arm7iop/rules.mk b/drivers/samsung/arm7iop/rules.mk new file mode 100644 index 0000000..4c8f04a --- /dev/null +++ b/drivers/samsung/arm7iop/rules.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += ${LOCAL_DIR}/arm7.o + +OPTIONS += WITH_ARM7_DEBUG=1 diff --git a/drivers/samsung/arm7m/arm7m.c b/drivers/samsung/arm7m/arm7m.c new file mode 100644 index 0000000..ed5c380 --- /dev/null +++ b/drivers/samsung/arm7m/arm7m.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Early init is done every time the ARM7 starts. + */ +int +arm7m_init(void) +{ + + /* + * Cache starts off. Invalidate and then turn it on. + */ + rARM7M_CACHE_INV = 1; + rARM7M_CACHE_ON = ARM7M_CACHE_ON_ENABLE; + + return(0); +} + +/* + * Halt waiting for an interrupt. + */ +void +arm7m_halt(void) +{ + /* XXX need to avoid doing this until cache operations are complete */ + rARM7M_SLEEP = 1; +} + +/* + * Cache control + */ +void +arm7m_cache_operation(int operation, void *address, u_int32_t length) +{ + uint32_t actual_base, lines; + + if (length == 0) { + /* + * To perform whole-cache operations, we have to turn the cache off. + * + * Since this introduces both a coherency risk and also since our use + * of the hardware needs to be exclusive, we disable interrupts. + */ + enter_critical_section(); + rARM7M_CACHE_ON = 0; + + if (operation & CACHE_CLEAN) + rARM7M_CACHE_SYNC = 0; + if (operation & CACHE_INVALIDATE) + rARM7M_CACHE_INV = 0; + + /* on the panic path, leave the cache off */ + if (!(operation & CACHE_PANIC)) + rARM7M_CACHE_ON = ARM7M_CACHE_ON_ENABLE; + + exit_critical_section(); + } else { + actual_base = (uint32_t)address; + ASSERT((actual_base & ARM7M_CACHE_LINE_MASK) == actual_base); + ASSERT((length % ARM7M_CACHE_LINE_SIZE) == 0); + + lines = length >> ARM7M_CACHE_LINE_SHIFT; + ASSERT(lines > 0); + + /* + * Disable interrupts to prevent re-entrance from an interrupt + * handler. + */ + enter_critical_section(); + for (;;) { + rARM7M_CLINE_ADDR = actual_base; + if (operation & CACHE_CLEAN) + rARM7M_CLINE_SYNC = 0; + if (operation & CACHE_INVALIDATE) + rARM7M_CLINE_INV = 0; + if (--lines < 1) + break; + actual_base += ARM7M_CACHE_LINE_SIZE; + } + exit_critical_section(); + } +} + +#if SUPPORT_SLEEP +static struct task *sleeping_task; +extern u_int32_t arch_sleep_magic; + +void +platform_sleep(void) +{ + /* + * Disable interrupts; this is matched by the + * exit_critical_section call in interrupt_init on the wake + * path. + */ + enter_critical_section(); + + /* we are the sleeping task */ + sleeping_task = task_get_current_task(); + + /* fool the upcoming test on the sleep path */ + arch_sleep_magic = SLEEP_MAGIC_NOT_ASLEEP; + + /* save our current context - on wake we will return from this call */ + arch_task_context_switch(&sleeping_task->arch, &sleeping_task->arch); + + /* if we are on the wake path, go back */ + if (SLEEP_MAGIC_WAKEY_WAKEY == arch_sleep_magic) + return; + + /* flip the switch and wait for us to go to sleep */ + arch_sleep_magic = SLEEP_MAGIC_WAKEY_WAKEY; + + /* disable and flush the cache, since we're about to be turned off */ + rARM7M_CACHE_ON = 0; + rARM7M_CACHE_SYNC = 0; + + /* XXX really need to know how long the cache operation will take to complete */ + for (;;) { + } +} + +void +platform_wakeup(void) +{ + /* + * Cache starts off. Invalidate and then turn it on. + */ + rARM7M_CACHE_INV = 1; + rARM7M_CACHE_ON = ARM7M_CACHE_ON_ENABLE; + + /* + * The VIC init is sleep/wake friendly - note this unmasks + * interrupts that were unmasked at sleep time, so handlers + * must be ready (or interrupt sources should be masked before + * sleep). + * + * This call also exits the critical section that was entered + * in platform_sleep (current_task has not changed). + */ + interrupt_init(); + + /* kick the callout system to re-evaluate deadlines */ + callout_reset_deadline(); + + /* and switch back to the context that went to sleep */ + arch_task_context_restore(&sleeping_task->arch); + + panic("arch_task_context_restore didn't"); +} +#endif /* SUPPORT_SLEEP */ + diff --git a/drivers/samsung/arm7m/include/drivers/arm7m/arm7m.h b/drivers/samsung/arm7m/include/drivers/arm7m/arm7m.h new file mode 100644 index 0000000..572db51 --- /dev/null +++ b/drivers/samsung/arm7m/include/drivers/arm7m/arm7m.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __ARM7M_H +#define __ARM7M_H + +#include + +__BEGIN_DECLS + +extern int arm7m_init(void); +extern void arm7m_halt(void); +extern void arm7m_cache_operation(int operation, void *address, u_int32_t length); + +__END_DECLS + +#endif diff --git a/drivers/samsung/arm7m/rules.mk b/drivers/samsung/arm7m/rules.mk new file mode 100644 index 0000000..514ef51 --- /dev/null +++ b/drivers/samsung/arm7m/rules.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += ${LOCAL_DIR}/arm7m.o + +GLOBAL_INCLUDES += ${LOCAL_DIR}/include diff --git a/drivers/samsung/clcd_v2/clcd.c b/drivers/samsung/clcd_v2/clcd.c new file mode 100644 index 0000000..24c114c --- /dev/null +++ b/drivers/samsung/clcd_v2/clcd.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#include "clcd_regs.h" + +#ifndef CLCD_VERSION +#error CLCD_VERSION undefined +#endif + +static void clcd_load_gamma_table(u_int32_t lut_id, u_int32_t *lut_data, uint32_t coeff); + +void clcd_enable_clocks(bool enable) +{ + int device; + + if (CLCD_DISPLAYPIPE_BASE_ADDR == DISP0_BASE_ADDR) + device = CLK_DISP0; + else + device = CLK_DISP1; + + // Enable/disable displaypipe and clcd clocks + if (enable) { + clock_gate(device, true); + clock_gate(CLK_CLCD, true); + } + else { + clock_gate(CLK_CLCD, false); + clock_gate(device, false); + } +} + +void clcd_init(struct display_timing *timing) +{ + rCLCD_STATUS = (1 << 8); // Reset CLCD + while (rCLCD_STATUS & (1 << 8)); // Wait for reset complete... + spin(1); // ... and wait some more: + + // Enable sync enable + rCLCD_STATUS = (1 << 2); + + // Bypass and clock gate MIE + rCLCD_CFG = (1 << 1) | (1 << 0); + + +#if DITHER_VERSION == 1 + rCLCD_DITH_CFG = (1 << 31) | (1 << 0); + + // Set dithering constants + rCLCD_DITH_CONST = (2 << 16) | (4 << 8) | (8 << 0); + + if (timing->display_depth <= 18) { +#if CLCD_DITHER_BASE_ADDR + rCLCD_DITHER_METHOD = (4 << 4) | (2 << 0); + rCLCD_DITHER_ENABLE = 1; +#else + rCLCD_DITH_CFG |= (1 << 24) | (1 << 20) | (1 << 16); +#endif + } +#endif + +#if DITHER_VERSION == 2 + //Need to force the bypass dithering in the clcd block + rCLCD_DITH_CFG = (1 << 31) | (1 << 29) | (1 << 0); + rCLCD_DITH_CONST = 0; + + dither_init(timing->display_depth); + dither_set_enable(true); +#endif + + rCLCD_OTF_CON1 = 0; + rCLCD_OTF_CON2 = (timing->neg_vclk << 3) | (timing->neg_hsync << 2) | (timing->neg_vsync << 1) | (timing->neg_vden << 0); + + rCLCD_OTF_TCON1 = (CLCD_OTF_TCON1_VSPP | + CLCD_OTF_TCON1_VBPD(timing->v_back_porch) | + CLCD_OTF_TCON1_VFPD(timing->v_front_porch) | + CLCD_OTF_TCON1_VSPW(timing->v_pulse_width)); +#if defined(TARGET_CLCD_VSPP) && (TARGET_CLCD_VSPP == 0) + rCLCD_OTF_TCON1 &= ~CLCD_OTF_TCON1_VSPP; +#endif + rCLCD_OTF_TCON2 = (CLCD_OTF_TCON2_HBPD(timing->h_back_porch) | + CLCD_OTF_TCON2_HFPD(timing->h_front_porch) | + CLCD_OTF_TCON2_HSPW(timing->h_pulse_width)); + rCLCD_OTF_TCON3 = (CLCD_OTF_TCON3_HOZVAL(timing->h_active) | + CLCD_OTF_TCON3_LINEVAL(timing->v_active)); +} + +bool clcd_get_enable_timing_generator(void) +{ + return ((rCLCD_OTF_CON1 & 1) == 1); +} + +void clcd_enable_timing_generator(bool enable) +{ + if (enable) { + rCLCD_OTF_CON1 |= 1; // Turn OTF on + } + else { + rCLCD_OTF_CON1 &= ~1; // Turn off OTF + while ((rCLCD_OTF_CON1 & (1 << 1)) == 0); // Wait for OTF off + } +} + +void clcd_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl) +{ + RELEASE_ASSERT(red_lut != NULL); + RELEASE_ASSERT(green_lut != NULL); + RELEASE_ASSERT(blue_lut != NULL); + RELEASE_ASSERT(wpcl != NULL); + + // Load the Gamma Correction Table + clcd_load_gamma_table(CLCD_GM_COR_RED, red_lut, wpcl->red); + clcd_load_gamma_table(CLCD_GM_COR_GREEN, green_lut, wpcl->green); + clcd_load_gamma_table(CLCD_GM_COR_BLUE, blue_lut, wpcl->blue); + +#if CLCD_VERSION >= 1 + // Swap to the new Gamma Correction Table + rCLCD_GM_CON = CLCD_GM_CON_GM_CO_TBL_UPDATED; + + // Wait for the swap to complete + while ((rCLCD_GM_CON & CLCD_GM_CON_GM_CO_TBL_UPDATED) != 0); + + // Load the Alternate Gamma Correction Table + clcd_load_gamma_table(CLCD_GM_COR_RED, red_lut, wpcl->red); + clcd_load_gamma_table(CLCD_GM_COR_GREEN, green_lut, wpcl->green); + clcd_load_gamma_table(CLCD_GM_COR_BLUE, blue_lut, wpcl->blue); +#endif + + // Turn on Gamma Correction + rCLCD_GM_CON = CLCD_GM_CON_GM_CO_ENABLE; +} + +static void clcd_load_gamma_table(u_int32_t lut_id, u_int32_t *lut_data, uint32_t coeff) +{ + u_int32_t cnt; + u_int32_t lut_size = (lut_id == CLCD_GM_ENC) ? 225 : 256; + u_int32_t lut_value, lut_value2; + + rCLCD_GM_TBL_ACC_CON = (1 << 16) | (lut_id << 12) | (0 << 0); + + for (cnt = 0; cnt < lut_size; cnt++) { + lut_value = lut_data[cnt]; + + switch (lut_id) { + case CLCD_GM_DEC_RED : + case CLCD_GM_DEC_GREEN : + case CLCD_GM_DEC_BLUE : + break; + + case CLCD_GM_COR_RED : + case CLCD_GM_COR_GREEN : + case CLCD_GM_COR_BLUE : + lut_value2 = (lut_data[cnt + 1] * coeff) >> WpCl_Quotation_Denominator; + lut_value = (lut_value * coeff) >> WpCl_Quotation_Denominator; + lut_value = ((lut_value << 10) & 0x000FFC00) | (lut_value2 & 0x000003FF); + break; + + case CLCD_GM_ENC : + break; + } + + rCLCD_GM_TBL_WDATA = (1 << 31) | lut_value; + } + + rCLCD_GM_TBL_ACC_CON = 0; +} diff --git a/drivers/samsung/clcd_v2/clcd_regs.h b/drivers/samsung/clcd_v2/clcd_regs.h new file mode 100644 index 0000000..9e8cd24 --- /dev/null +++ b/drivers/samsung/clcd_v2/clcd_regs.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __SAMSUNG_CLCD_REGS_H +#define __SAMSUNG_CLCD_REGS_H + +#include + +#define rCLCD_STATUS (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0000)) +#define rCLCD_CFG (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0004)) +#define rCLCD_INT_EN (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0008)) +#define rCLCD_INT_STATUS (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x000C)) +#define rCLCD_VER (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0010)) +#define rCLCD_DITH_CFG (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0014)) +#define rCLCD_DITH_CONST (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0018)) +#define rCLCD_DPHSYNC_CTRL (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0020)) +#define rCLCD_DPVSYNC_CTRL (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0024)) +#define rCLCD_GM_CON (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x002C)) +#define CLCD_GM_CON_GM_CO_ENABLE (1 << 0) +#define CLCD_GM_CON_GM_CO_TBL_UPDATED (1 << 6) +#define rCLCD_GM_STATUS (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0030)) +#define rCLCD_GM_TBL_ACC_CON (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0034)) +#define CLCD_GM_OFF (0) +#define CLCD_GM_DEC_RED (1) +#define CLCD_GM_DEC_GREEN (2) +#define CLCD_GM_DEC_BLUE (3) +#define CLCD_GM_COR_RED (4) +#define CLCD_GM_COR_GREEN (5) +#define CLCD_GM_COR_BLUE (6) +#define CLCD_GM_ENC (7) +#define rCLCD_GM_TBL_WDATA (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0038)) +#define rCLCD_GM_TBL_RDATA (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x003C)) +#define rCLCD_OTF_CON1 (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0050)) +#define rCLCD_OTF_CON2 (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0054)) +#define rCLCD_OTF_TCON1 (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0058)) +#if (DISP_VERSION < 3) +#define CLCD_OTF_TCON1_VSPP (1 << 24) +#define CLCD_OTF_TCON1_VBPD(_l) (((_l)-1) << 16) +#define CLCD_OTF_TCON1_VFPD(_l) (((_l)-1) << 8) +#define CLCD_OTF_TCON1_VSPW(_l) (((_l)-1) << 0) +#else +#define CLCD_OTF_TCON1_VSPP (1 << 30) +#define CLCD_OTF_TCON1_VBPD(_l) (((_l)-1) << 20) +#define CLCD_OTF_TCON1_VFPD(_l) (((_l)-1) << 10) +#define CLCD_OTF_TCON1_VSPW(_l) (((_l)-1) << 0) +#endif +#define rCLCD_OTF_TCON2 (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x005C)) +#if (DISP_VERSION < 4) +#define CLCD_OTF_TCON2_HBPD(_p) (((_p)-1) << 16) +#define CLCD_OTF_TCON2_HFPD(_p) (((_p)-1) << 8) +#define CLCD_OTF_TCON2_HSPW(_p) (((_p)-1) << 0) +#else +#define CLCD_OTF_TCON2_HBPD(_p) (((_p)-1) << 20) +#define CLCD_OTF_TCON2_HFPD(_p) (((_p)-1) << 10) +#define CLCD_OTF_TCON2_HSPW(_p) (((_p)-1) << 0) +#endif +#define rCLCD_OTF_TCON3 (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0060)) +#define CLCD_OTF_TCON3_HOZVAL(_p) (((_p)-1) << 16) +#define CLCD_OTF_TCON3_LINEVAL(_p) (((_p)-1) << 0) +#define rCLCD_OTF_INT_EN (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0064)) +#define rCLCD_OTF_INT_STATUS (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0068)) +#define rCLCD_MIE_SAT_CON (*(volatile u_int32_t *)(CLCD_BASE_ADDR + 0x0074)) + +#define rCLCD_DITHER_ENABLE (*(volatile u_int32_t *)(CLCD_DITHER_BASE_ADDR + 0x0000)) +#define rCLCD_DITHER_METHOD (*(volatile u_int32_t *)(CLCD_DITHER_BASE_ADDR + 0x0004)) + +#endif /* __SAMSUNG_CLCD_REGS_H */ diff --git a/drivers/samsung/clcd_v2/include/drivers/clcd_v2/clcd.h b/drivers/samsung/clcd_v2/include/drivers/clcd_v2/clcd.h new file mode 100644 index 0000000..00ab728 --- /dev/null +++ b/drivers/samsung/clcd_v2/include/drivers/clcd_v2/clcd.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __SAMSUNG_CLCD_V2_H +#define __SAMSUNG_CLCD_V2_H + +void clcd_enable_clocks(bool enable); +void clcd_init(struct display_timing *timing); +bool clcd_get_enable_timing_generator(void); +void clcd_enable_timing_generator(bool enable); +void clcd_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl); + +#endif /* __SAMSUNG_CLCD_V2_H */ diff --git a/drivers/samsung/clcd_v2/rules.mk b/drivers/samsung/clcd_v2/rules.mk new file mode 100644 index 0000000..b53ff6f --- /dev/null +++ b/drivers/samsung/clcd_v2/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + DISPLAYPIPE_BASE_ADDR=CLCD_DISPLAYPIPE_BASE_ADDR \ + WITH_DBE_CLCD=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/clcd.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/samsung/displayport/displayport.c b/drivers/samsung/displayport/displayport.c new file mode 100644 index 0000000..c86d037 --- /dev/null +++ b/drivers/samsung/displayport/displayport.c @@ -0,0 +1,2007 @@ +/* + * Copyright (C) 2010-2013, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "regs.h" + +#if WITH_HW_MCU +#include +#include +#endif + +#ifndef DISPLAYPORT_VERSION +#error "DISPLAYPORT_VERSION must be defined" +#endif + +///////////////////////////////////////// +////////// debug support + +#define DP_DEBUG_MASK ( \ + DP_DEBUG_INIT | \ + DP_DEBUG_ERROR | \ + DP_DEBUG_INFO | \ + DP_DEBUG_INT | \ + DP_DEBUG_VIDEO | \ + DP_DEBUG_AUX | \ + DP_DEBUG_DPCD | \ + DP_DEBUG_PLL | \ + 0) + +#undef DP_DEBUG_MASK +#define DP_DEBUG_MASK (DP_DEBUG_INIT | DP_DEBUG_ERROR) + +#define DP_DEBUG_INIT (1<<16) // initialisation +#define DP_DEBUG_ERROR (1<<17) // errors +#define DP_DEBUG_INFO (1<<18) // info +#define DP_DEBUG_INT (1<<19) // interrupts +#define DP_DEBUG_VIDEO (1<<20) // video +#define DP_DEBUG_AUX (1<<21) // aux channel +#define DP_DEBUG_DPCD (1<<22) // dpcp read/write +#define DP_DEBUG_I2C (1<<23) // i2c read/write +#define DP_DEBUG_PLL (1<<23) // PLL +#define DP_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((DP_DEBUG_ ## _fac) & (DP_DEBUG_MASK | DP_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "DP: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args); \ + } while(0) + + +///////////////////////////////////////// +////////// consts + +// Crude screensaver: Turn off displayport after 3 minutes. +#define kScreenBurnTimeout (3 * 60 * 1000000) +#define kDPAuxRetryDelayUS 5000 + +#define kDisplayPortStackSize 8192 + +#define kLSClock_81mhz 81000000ULL +#define kLSClock_135mhz 135000000ULL +#define kLSClock_171mhz 171000000UL + +#define kLinkRatePhysical_162gbps 1620000000ULL +#define kLinkRatePhysical_270gps 2700000000ULL +#define kLinkRatePhysical_324gps 3240000000ULL + +#define kAUXRetryIntervalUS 5000 +#define kMaxAuxTransactionRetry 100 +#define kMaxI2CTransactionRetry 5 + +#if WITH_HW_DISPLAY_EDP +#define kMaxLaneCount 4 +#elif WITH_HW_HOOVER +#define kMaxLaneCount 4 +#else +#define kMaxLaneCount 2 +#endif + + +#define kDPHPDTimeout (50 * 1000) +#ifdef TARGET_HPD_TO_BL_TIMEOUT +#undef kDPHPDTimeout +#define kDPHPDTimeout TARGET_HPD_TO_BL_TIMEOUT +#endif + +// Calibration settings +#if DISPLAYPORT_VERSION < 3 +#ifndef DPTX_PLL_CTL_VALUE + #define DPTX_PLL_CTL_VALUE 0x15 +#endif + +#ifndef DPTX_ANALOG_CTL_2_VALUE + #define DPTX_ANALOG_CTL_2_VALUE 0x0c +#endif + +#ifndef DPTX_ANALOG_CTL_3_VALUE + #define DPTX_ANALOG_CTL_3_VALUE 0x80 +#endif + +#ifndef DPTX_FINE_PRE_EMPHASIS_VOLTAGE_VALUE + #define DPTX_FINE_PRE_EMPHASIS_VOLTAGE_VALUE 0 +#endif +#else +#ifndef DPTX_PLL_CTL_VALUE + #define DPTX_PLL_CTL_VALUE 0x1d +#endif + +#ifndef DPTX_ANALOG_CTL_2_VALUE + #define DPTX_ANALOG_CTL_2_VALUE 0x0d +#endif + +#ifndef DPTX_ANALOG_CTL_3_VALUE + #define DPTX_ANALOG_CTL_3_VALUE 0x80 +#endif +#endif //DISPLAYPORT_VERSION + +//The display spec for edp requires 134ms from HPD to backlight ON. +//The following time accounts for HPD occurring upto before programming the backlight. +//Depending on the backlight solution, its programming time varies. Best guess is around 10ms. +#define kDPDeviceHPD2BLON (170 * 1000) + +///////////////////////////////////////// +////////// typedefs, enums, structs + +enum { + kDPAuxTranscationStatus_None = -1, + kDPAuxTranscationStatus_Success, + kDPAuxTranscationStatus_IODefer, + kDPAuxTranscationStatus_IOError, + kDPAuxTranscationStatus_OtherError +}; + +enum { + kBaseVoltageType_Neg_120mV, + kBaseVoltageType_Neg_80mV, + kBaseVoltageType_Neg_40mV, + kBaseVoltageType_Pos_0mV, + kBaseVoltageType_Pos_40mV, + kBaseVoltageType_Pos_80mV, + kBaseVoltageType_Pos_120mV, + kBaseVoltageType_Pos_160mV +}; + +struct eq_calibration { + uint32_t swing; + uint32_t swing_max; + uint32_t eq; + uint32_t eq_max; +}; + +struct swing_calibration { + int32_t base; + uint32_t boost; + struct eq_calibration eq_levels[4]; +}; + +struct port_calibration { + struct swing_calibration swing[4]; +}; + +///////////////////////////////////////// +////////// local variables + +static const uint32_t __s_bpp_coeff[3] = {3, 2, 3}; // RGB:3, YCBR422:2, YCBR444:3 + +static addr_t __base_address; + +static struct port_calibration *dp_port_calibration_table; + +static bool dp_voltage_boost; +static u_int32_t dp_voltage_base[kMaxLaneCount]; +static u_int32_t dp_eq_levels[kMaxLaneCount]; +static u_int32_t dp_voltage_levels[kMaxLaneCount]; + +static volatile bool dp_aux_transaction_pending; +static volatile int dp_aux_transaction_status; + +static bool dp_started; +static bool dp_video_started; + +static struct task_event dp_controller_task_event; +static bool dp_interrupt_occurred; + +static u_int8_t dp_controller_type; +static u_int8_t dp_controller_mode; + +static uint32_t dp_controller_common_sta_4_val; +static uint32_t dp_controller_common_sta_3_val; +static uint32_t dp_controller_common_sta_2_val; +static uint32_t dp_controller_common_sta_1_val; +static uint32_t dp_controller_sta_val; + +static struct callout dp_controller_screensaver_callout; + +struct task_event dp_controller_hpd_event; + +static uint32_t dp_max_lane_count; +static uint32_t dp_max_link_rate; +static uint32_t dp_min_lane_count; +static uint32_t dp_min_link_rate; + +static bool dp_supports_downspread; + +///////////////////////////////////////// +////////// local functions declaration + +static int dp_controller_task(void *arg); +static void init_hw(); +static int configure_video(struct video_link_data *data); +static void init_video(bool master); +static void configure_video_timing_mode(struct video_link_data *data); +static void configure_video_mute(struct video_link_data *data, bool mute); +static void configure_video_m_n(struct video_link_data *data); +static int configure_video_color(struct video_link_data *data); +static int configure_video_mode(struct video_link_data *data); +static int validate_video(struct video_link_data *data, u_int32_t *m_vid, u_int32_t *n_vid); +static void configure_video_bist(struct video_link_data *data); +static void interrupt_filter(void *arg); +static void handle_interrupt(void); +static int stop_i2c_transaction(bool read); +static int start_i2c_transaction(uint32_t device_addr, uint32_t addr); +static int commit_aux_transaction(bool use_interrupts, bool deferRetryOnly, u_int32_t max_retry_count); +static int wait_for_aux_done(); +static int read_bytes_i2c_internal(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length); +static void uninit_video(); +static int set_voltage_base(u_int32_t lane, int32_t base); + +static void handle_screensaver_callout(struct callout *co, void *args); + +static uint32_t read_reg(u_int32_t offset); +static void write_reg(u_int32_t offset, uint32_t val); +static void and_reg(u_int32_t offset, uint32_t val); +static void or_reg(u_int32_t offset, uint32_t val); +static void set_bits_in_reg(u_int32_t offset, u_int32_t pos, u_int32_t mask, u_int32_t value); + + +struct dp_controller_config { + addr_t base_address; + u_int32_t clock; + u_int32_t irq; + const char *dt_path; +}; + +static const struct dp_controller_config dp_config[] = { +#if WITH_HW_DISPLAY_DISPLAYPORT +#if DISPLAYPORT_VERSION == 0 + { DISPLAYPORT_BASE_ADDR, CLK_DPLINK, INT_DISPLAYPORT, DP_DTPATH }, +#elif DISPLAYPORT_VERSION >= 1 + { DP_BASE_ADDR, CLK_DPLINK, INT_DPORT0, DP_DTPATH }, +#elif +#error "Not expected" +#endif // DISPLAYPORT_VERSION +#else + { 0, 0, 0, 0 }, +#endif // WITH_HW_DISPLAY_DISPLAYPORT +#if WITH_HW_DISPLAY_EDP + { EDP_BASE_ADDR, CLK_EDPLINK, INT_EDP0, DP_DTPATH }, +#else + { 0, 0, 0, 0 }, +#endif // WITH_HW_DISPLAY_EDP +}; + +///////////////////////////////////////// +////////// controller global functions + +int dp_controller_start(dp_t *dp_link_config) +{ + DTNodePtr node; + char * prop_name; + void * prop_data; + u_int32_t prop_size; + int i; + + if (dp_started) + return 0; + + dp_controller_type = dp_link_config->type; + dp_controller_mode = dp_link_config->mode; + dp_max_lane_count = dp_link_config->lanes; + dp_min_lane_count = dp_link_config->lanes; + dp_max_link_rate = dp_link_config->max_link_rate; + dp_min_link_rate = dp_link_config->min_link_rate; + dp_supports_downspread = dp_link_config->ssc; + + __base_address = dp_config[dp_controller_type].base_address; + + // turn on the clock + clock_gate(dp_config[dp_controller_type].clock, true); + +#if DISPLAYPORT_VERSION == 0 + // reset the hw from PMGR + u_int32_t val; + + val = *(volatile u_int32_t *)(rPMGR_DPLINK_PS) & ~(1 << 8); + *(volatile u_int32_t *)(rPMGR_DPLINK_PS) = (1 << 31) | val; + spin(1); + *(volatile u_int32_t *)(rPMGR_DPLINK_PS) = val; +#else + write_reg(DPTX_SW_RESET, DPTX_SW_RESET_OPERATION); + while (read_reg(DPTX_SW_RESET) != 0) {} +#endif // DISPLAYPORT_VERSION == 0 + + dp_voltage_boost = false; + for (i = 0; i < kMaxLaneCount; i++) + dp_voltage_base[i] = kBaseVoltageType_Pos_0mV; + + // gather calibration data from DeviceTree + if ( FindNode(0, dp_config[dp_controller_type].dt_path, &node) ) { + // link calibration + + prop_name = "calibration_data"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + if ( prop_size != sizeof(struct port_calibration) ) { + debug(ERROR, "calibration-data size mismatch, expected:%zu, read:%u \n", + sizeof(struct port_calibration), prop_size); + return -1; + } + + dp_port_calibration_table = (struct port_calibration *)malloc(prop_size); + + bcopy(prop_data, (void *)dp_port_calibration_table, prop_size); + } + + // max lane count + prop_name = "max_lane_count"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_max_lane_count = *((uint32_t*)prop_data); + } + + // max link rate + prop_name = "max_link_rate"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_max_link_rate = *((uint32_t*)prop_data); + } + + // min lane count + prop_name = "min_lane_count"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_min_lane_count = *((uint32_t*)prop_data); + } + + // min link rate + prop_name = "min_link_rate"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_min_link_rate = *((uint32_t*)prop_data); + } + + // downspread + prop_name = "downspread_support"; + if ( FindProperty(node, &prop_name, &prop_data, &prop_size) ) { + dp_supports_downspread = *((uint32_t*)prop_data); + } + } + + // register interrupt handler + install_int_handler(dp_config[dp_controller_type].irq, interrupt_filter, NULL); + + event_init(&dp_controller_task_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + task_start(task_create("displayport", &dp_controller_task, NULL, kDisplayPortStackSize)); + + event_init(&dp_controller_hpd_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + init_hw(); + + dp_started = true; + + // enable interrupts + write_reg(DPTX_COMMON_INT_MASK_4, DPTX_COMMON_INT_4_HP_CHG | + DPTX_COMMON_INT_4_PLUG | + DPTX_COMMON_INT_4_HPD_LOST); + + unmask_int(dp_config[dp_controller_type].irq); + + debug(INIT, "dp inited\n"); + debug(INIT, "dp_controller_type %d\n", dp_controller_type); + debug(INIT, "dp_controller_mode %d\n", dp_controller_mode); + debug(INIT, "dp_max_lane_count %d\n", dp_max_lane_count); + debug(INIT, "dp_max_link_rate 0x%x\n", dp_max_link_rate); + debug(INIT, "dp_min_link_rate 0x%x\n", dp_min_link_rate); + debug(INIT, "dp_supports_downspread %d\n", dp_supports_downspread); + + return 0; +} + +void dp_controller_stop() +{ + if (!dp_started) + return; + + dp_controller_stop_video(); + + // disable interrupt source + mask_int(dp_config[dp_controller_type].irq); + +#if WITH_HW_MCU +#if WITH_HW_BS + // stop pass through mode + mcu_set_passthrough_mode(false); +#endif + + // Stop background EDID polling. + abort_edid(); + +#endif + + dp_video_started = false; + + dp_device_stop(); + + write_reg(DPTX_COMMON_INT_MASK_1, 0); +#if DISPLAYPORT_VERSION < 3 + write_reg(DPTX_COMMON_INT_MASK_2, 0); + write_reg(DPTX_COMMON_INT_MASK_3, 0); +#endif //DISPLAYPORT_VERSION + write_reg(DPTX_COMMON_INT_MASK_4, 0); + write_reg(DPTX_DP_INT_STA_MASK, 0); + + write_reg(DPTX_COMMON_INT_STA_1, 0xff); +#if DISPLAYPORT_VERSION < 3 + write_reg(DPTX_COMMON_INT_STA_2, 0xff); + write_reg(DPTX_COMMON_INT_STA_3, 0xff); +#endif //DISPLAYPORT_VERSION + write_reg(DPTX_COMMON_INT_STA_4, 0xff); + write_reg(DPTX_DP_INT_STA, 0xff); + + if (dp_controller_type == kDPControllerType_DP) { + callout_dequeue(&dp_controller_screensaver_callout); + } + + // Turn off all functions. + u_int32_t flags; + +#if DISPLAYPORT_VERSION == 0 + flags = DPTX_FUNC_EN_1_VIDCAP | DPTX_FUNC_EN_1_VIDFIF0; +#elif DISPLAYPORT_VERSION >= 1 + flags = DPTX_FUNC_EN_1_SLAVE | DPTX_FUNC_EN_1_MASTER; +#endif // DISPLAYPORT_VERSION + + write_reg(DPTX_FUNC_EN_1, flags | + DPTX_FUNC_EN_1_AUDFIF0 | + DPTX_FUNC_EN_1_AUDCAP | + DPTX_FUNC_EN_1_HDCP | + DPTX_FUNC_EN_1_SW_ALL); + + write_reg(DPTX_FUNC_EN_2, DPTX_FUNC_EN_2_SSC | + DPTX_FUNC_EN_2_AUX | + DPTX_FUNC_EN_2_SERDES_FIFO | + DPTX_FUNC_EN_2_LS_CLK_DOMAIN ); + + // power down the PLL + uint8_t pllLockState; + while(((pllLockState = read_reg(DPTX_DP_DEBUG_CTL)) & DPTX_DP_DEBUG_CTL_PLL_LOCK) == 0) + debug(INFO, "before pllLockState=%d\n", pllLockState); + + and_reg(DPTX_DP_PLL_CTL, DPTX_DP_PLL_CTL_PWR_DN); + debug(INFO, "powered down DP PLL lockstate=%d\n",pllLockState); + + while(((pllLockState = read_reg(DPTX_DP_DEBUG_CTL)) & DPTX_DP_DEBUG_CTL_PLL_LOCK) == 0) + debug(INFO, "after pllLockState=%d\n", pllLockState); + + // clear PLL + write_reg(DPTX_COMMON_INT_STA_1, DPTX_COMMON_INT_1_PLL_LCK_CHG); + and_reg(DPTX_DP_DEBUG_CTL, ~(DPTX_DP_DEBUG_CTL_F_PLL_LOCK | DPTX_DP_DEBUG_CTL_PLL_LOCK_CTRL)); + + write_reg(DPTX_DP_PHY_PD, DPTX_DP_PHY_PWR_DWN); // power down PHY + + // disable the clock + clock_gate(dp_config[dp_controller_type].clock, false); + + if ( dp_port_calibration_table ) { + free(dp_port_calibration_table); + dp_port_calibration_table = NULL; + } + + dp_started = false; +} + +#if WITH_HW_DISPLAY_EDP +// Ensure enough time has passed from HPD and turning the backlight ON +void dp_controller_wait_for_HPD_to_BL(utime_t hpd_time) +{ + utime_t hpd2blON = hpd_time + kDPDeviceHPD2BLON; + utime_t now = system_time(); + utime_t timeleft = 0; + + if (now >= hpd2blON) { + debug(INIT, "no need to wait hpd2blON 0x%llx hpd_time 0x%llx now 0x%llx timeleft 0x%llx\n", hpd2blON, hpd_time, now, timeleft); + return; + } + timeleft = hpd2blON - now; + spin(timeleft); + debug(INIT, "waited hpd2blON 0x%llx hpd_time 0x%llx now 0x%llx timeleft 0x%llx\n", hpd2blON, hpd_time, now, timeleft); +} + +bool dp_controller_wait_for_edp_hpd(utime_t *hpd_time) +{ + bool res; + + res = event_wait_timeout(&dp_controller_hpd_event, kDPHPDTimeout); + *hpd_time = system_time(); + + return res; +} +#endif // WITH_HW_DISPLAY_EDP + +int dp_controller_validate_video(struct video_timing_data *timings) +{ + // Assume basic settings. + struct video_link_data data; + bzero(&data, sizeof(data)); + bcopy(timings, &data.timing, sizeof(*timings)); + data.mirror_mode = false; + data.test_mode = 0; + data.color.depth = 8; + data.color.space = kDisplayColorSpacesRGB; + data.color.range = kDisplayColorDynamicRangeVESA; + data.color.coefficient = kDisplayColorCoefficientITU601; + return validate_video(&data, NULL, NULL); +} + +u_int32_t dp_controller_get_max_lane_count() +{ + return dp_max_lane_count; +} + +u_int32_t dp_controller_get_max_link_rate() +{ + return dp_max_link_rate; +} + +u_int32_t dp_controller_get_min_lane_count() +{ + return dp_min_lane_count; +} + +u_int32_t dp_controller_get_min_link_rate() +{ + return dp_min_link_rate; +} + +int dp_controller_set_link_rate(u_int32_t link_rate) +{ + write_reg(DPTX_LINK_BW_SET, link_rate); + + return 0; +} + +int dp_controller_get_link_rate(u_int32_t *link_rate) +{ + *link_rate = read_reg(DPTX_LINK_BW_SET); + + return 0; +} + +int dp_controller_set_lane_count(uint32_t lane_count) +{ + uint8_t pll_lock_state; + uint8_t reg_val; + uint32_t func_enable_2; + + func_enable_2 = DPTX_FUNC_EN_2_SERDES_FIFO | DPTX_FUNC_EN_2_LS_CLK_DOMAIN; + + if ( dp_supports_downspread ) + func_enable_2 |= DPTX_FUNC_EN_2_SSC; + + // clear PLL + write_reg(DPTX_COMMON_INT_STA_1, DPTX_COMMON_INT_1_PLL_LCK_CHG); + and_reg(DPTX_DP_DEBUG_CTL, ~(DPTX_DP_DEBUG_CTL_F_PLL_LOCK | DPTX_DP_DEBUG_CTL_PLL_LOCK_CTRL)); + + // power up the PLL + write_reg(DPTX_DP_PLL_CTL, DPTX_PLL_CTL_VALUE); + debug(INFO, "powered up DP PLL\n"); + + while(((pll_lock_state = read_reg(DPTX_DP_DEBUG_CTL)) & DPTX_DP_DEBUG_CTL_PLL_LOCK) == 0) { + debug(INFO, "after pllLockState=%d\n", pll_lock_state); + } + + // Since we are adjusting the lane power, we need to hold the phy in reset + or_reg(DPTX_FUNC_EN_2, func_enable_2); + or_reg(DPTX_DP_PHY_TEST, DPTX_DP_PHY_TEST_RST_MACRO); + + // turn off all lanes + reg_val = (DPTX_DP_PHY_CH1_PWR_DWN | DPTX_DP_PHY_CH0_PWR_DWN); +#if DISPLAYPORT_VERSION >= 2 + reg_val |= (DPTX_DP_PHY_CH3_PWR_DWN | DPTX_DP_PHY_CH2_PWR_DWN); +#endif // DISPLAYPORT_VERSION >= 2 +#if DISPLAYPORT_VERSION > 2 && LOW_POWER_MODE == 1 + //to use 300mv we need to enable low-power mode + reg_val |= DPTX_DP_PHY_SEL_LOWPOWER; +#endif // DISPLAYPORT_VERSION > 2 && LOW_POWER_MODE == 1 + write_reg(DPTX_DP_PHY_PD, reg_val); + + switch(lane_count) { +#if DISPLAYPORT_VERSION >= 2 + case 4: + and_reg(DPTX_DP_PHY_PD, ~(DPTX_DP_PHY_CH3_PWR_DWN)); + and_reg(DPTX_DP_PHY_PD, ~(DPTX_DP_PHY_CH2_PWR_DWN)); +#endif // DISPLAYPORT_VERSION >= 2 + + case 2: + and_reg(DPTX_DP_PHY_PD, ~(DPTX_DP_PHY_CH1_PWR_DWN)); + and_reg(DPTX_DP_PHY_PD, ~(DPTX_DP_PHY_CH0_PWR_DWN)); + + case 1: + and_reg(DPTX_DP_PHY_PD, ~(DPTX_DP_PHY_CH0_PWR_DWN)); + break; + } + + debug(INFO, "Setting lane count to %d\n", lane_count); + write_reg(DPTX_LANE_COUNT_SET, lane_count); + + // wait for 100us so that phy pll settles + spin(100); + + and_reg(DPTX_DP_PHY_TEST, ~(DPTX_DP_PHY_TEST_RST_MACRO)); + and_reg(DPTX_FUNC_EN_2, ~func_enable_2); + + return 0; +} + +int dp_controller_get_lane_count(uint32_t * lane_count) +{ + *lane_count = read_reg(DPTX_LANE_COUNT_SET); + + return 0; +} + +bool dp_controller_get_supports_fast_link_training() +{ +#ifdef WITH_HW_HOOVER + return false; +#else + return (true); +#endif +} + +bool dp_controller_get_supports_downspread() +{ + return dp_supports_downspread; +} + +int dp_controller_set_downspread(bool state) +{ + uint32_t regval = DPTX_DP_DN_SPREAD_MOD_FREQ_33Khz; + + if ( state ) + regval |= DPTX_DP_DN_SPREAD_ENABLE; + + write_reg(DPTX_DP_DN_SPREAD_CTL, regval); + + return 0; +} + +int dp_controller_get_downspread(bool *state) +{ + *state = read_reg(DPTX_DP_DN_SPREAD_CTL) & DPTX_DP_DN_SPREAD_ENABLE; + + return 0; +} + +int dp_controller_set_enhanced_mode(bool mode) +{ + if ( mode ) + or_reg(DPTX_SYS_CTL_4, DPTX_SYS_CTL_4_ENHANCED); + else + and_reg(DPTX_SYS_CTL_4, ~(DPTX_SYS_CTL_4_ENHANCED)); + + return 0; +} + +int dp_controller_get_enhanced_mode(bool * mode) +{ + *mode = read_reg(DPTX_SYS_CTL_4) & DPTX_SYS_CTL_4_ENHANCED; + + return 0; +} + +int dp_controller_set_ASSR(bool mode) +{ + if ( mode ) + or_reg(DPTX_DP_TRAINING_PTRN_SET, DPTX_DP_TRAINING_PTRN_SET_SCRM_EDP); + else + and_reg(DPTX_DP_TRAINING_PTRN_SET, ~DPTX_DP_TRAINING_PTRN_SET_SCRM_EDP); + + return 0; +} + +int dp_controller_get_ASSR(bool * mode) +{ + *mode = read_reg(DPTX_DP_TRAINING_PTRN_SET) & DPTX_DP_TRAINING_PTRN_SET_SCRM_EDP; + + return 0; +} + +int dp_controller_get_adjustment_levels(u_int32_t lane, u_int32_t *voltage_swing, u_int32_t *eq) +{ + if ( lane > kMaxLaneCount ) + return -1; + + *eq = dp_eq_levels[lane]; + *voltage_swing = dp_voltage_levels[lane]; + + return 0; +} + +int dp_controller_set_adjustment_levels(u_int32_t lane, u_int32_t voltage_swing, u_int32_t eq, + bool *voltage_max_reached, bool *eq_max_reached) +{ + uint32_t h3_swing; + uint32_t h3_eq; + bool h3_boost; + uint32_t h3_base; + + debug(INFO, "lane=%d maxLaneCount=%d voltage=%d eq=%d\n", lane, kMaxLaneCount, voltage_swing, eq); + + if ( lane > kMaxLaneCount ) + return -1; + + dp_voltage_levels[lane] = voltage_swing; + dp_eq_levels[lane] = eq; + + h3_swing = voltage_swing; + h3_eq = eq; + h3_boost = false; + h3_base = 0; + + if ( dp_port_calibration_table ) { + h3_swing = dp_port_calibration_table->swing[voltage_swing].eq_levels[eq].swing; + h3_eq = dp_port_calibration_table->swing[voltage_swing].eq_levels[eq].eq; + h3_boost = dp_port_calibration_table->swing[voltage_swing].boost; + h3_base = dp_port_calibration_table->swing[voltage_swing].base; + + debug(INFO, "h3Swing=%d h3Eq=%d h3Base=%d hd3Boost=%d \n", h3_swing, h3_eq, h3_base, h3_boost); + + if ( h3_boost ) + or_reg(DPTX_ANALOG_CTL_1, DPTX_ANALOG_CTL_1_TX_SWING_INC_30PER); + else + and_reg(DPTX_ANALOG_CTL_1, ~DPTX_ANALOG_CTL_1_TX_SWING_INC_30PER); + + set_voltage_base(lane, h3_base); + + if ( eq_max_reached ) + *eq_max_reached = dp_port_calibration_table->swing[voltage_swing].eq_levels[eq].eq_max; + if ( voltage_max_reached ) + *voltage_max_reached = dp_port_calibration_table->swing[voltage_swing].eq_levels[eq].swing_max; + } + +#if DISPLAYPORT_VERSION < 3 + write_reg(DPTX_DP_LN0_LINK_TRAINING_CTL + (lane<<2), + (DPTX_FINE_PRE_EMPHASIS_VOLTAGE_VALUE << DPTX_DP_LN_LINK_TRAINING_CTL_FINE_ADJ_PRE_EMPHASIS_SHIFT) | + ((h3_eq << DPTX_DP_LN_LINK_TRAINING_CTL_PRE_SET_SHIFT) & DPTX_DP_LN_LINK_TRAINING_CTL_PRE_SET_MASK) | + ((h3_swing << DPTX_DP_LN_LINK_TRAINING_CTL_DRV_SET_SHIFT) & DPTX_DP_LN_LINK_TRAINING_CTL_DRV_SET_MASK) ); +#else //DISPLAYPORT_VERSION +#if LOW_POWER_MODE == 1 + //14059240: down to 300mv for H6 + write_reg(DPTX_DP_LN0_LINK_TRAINING_CTL + (lane<<2), CHX_SWING_300mV_PRE_EMP1_0dB_PRE_EMP2_0dB); +#else //LOW_POWER_MODE == 1 + write_reg(DPTX_DP_LN0_LINK_TRAINING_CTL + (lane<<2), CHX_SWING_400mV_PRE_EMP1_0dB_PRE_EMP2_0dB_PC0); +#endif //LOW_POWER_MODE == 1 +#endif //DISPLAYPORT_VERSION + + return 0; +} + +int dp_controller_set_training_pattern(u_int32_t value, bool scramble) +{ + uint32_t scram_setting = 0; + +#if WITH_HW_DISPLAY_EDP + scram_setting |= DPTX_DP_TRAINING_PTRN_SET_SCRM_EDP; +#endif + + debug(INFO, "training pattern=%d scrambled=%d\n", value, scramble); + + scram_setting |= scramble ? 0 : DPTX_DP_TRAINING_PTRN_SET_SCRM_DIS; + write_reg(DPTX_DP_TRAINING_PTRN_SET, scram_setting | value); + + return 0; +} + +int dp_controller_get_training_pattern(u_int32_t *pattern, bool *scramble) +{ + uint32_t value = read_reg(DPTX_DP_TRAINING_PTRN_SET); + + if ( scramble ) + *scramble = (value & DPTX_DP_TRAINING_PTRN_SET_SCRM_DIS) == 0; + + if ( pattern ) + *pattern = (value & DPTX_DP_TRAINING_PTRN_SET_SW_MASK); + + return 0; +} + +int dp_controller_read_bytes_dpcd(u_int32_t addr, u_int8_t *data, u_int32_t length) +{ + uint32_t startOffset = 0; + int ret = 0; + + debug(DPCD, "addr=0x%08x data=%p length=%d payload:\n", addr, data, length); + + while (startOffset < length) { + uint32_t actualDataCount; + uint32_t currentDataCount; + uint32_t currentDataIndex; + + currentDataCount = ((length - startOffset) > DPTX_BUF_DATA_COUNT) ? DPTX_BUF_DATA_COUNT: (length - startOffset); + + //Select DPCD device address + write_reg(DPTX_AUX_ADDR_7_0, (addr + startOffset) & 0xFF); + write_reg(DPTX_AUX_ADDR_15_8, ((addr + startOffset)>>8) & 0xFF); + write_reg(DPTX_AUX_ADDR_19_16, ((addr + startOffset)>>16) & 0x0F); + + //Set DPCD read cmd mot = 0 and read 1 bytes + write_reg(DPTX_AUX_CH_CTL_1, ((currentDataCount-1) << DPTX_AUX_CH_CTL_1_AUX_LENGTH_SHIFT) | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_NATIVE | DPTX_AUX_CH_CTL_1_AUX_TX_COMM_READ); + + //Clear Buffer + write_reg(DPTX_BUFFER_DATA_CTL, DPTX_BUFFER_DATA_CTL_CLR); + + //Start Aux transaction + ret = commit_aux_transaction(false, false, kMaxAuxTransactionRetry); + if ( ret != 0 ) + return -1; + + actualDataCount = read_reg(DPTX_BUFFER_DATA_CTL) & 0x1f; + //debug_dpcd("Bytes: length=%d data=", actualDataCount); + debug(DPCD, "Aux data length %d, expecting %d\n", actualDataCount, currentDataCount); + debug(DPCD, "Bytes: "); + + if ( currentDataCount != actualDataCount ) + currentDataCount = __min(actualDataCount, currentDataCount); + + for(currentDataIndex = 0; currentDataIndex < currentDataCount; currentDataIndex++) { + data[startOffset + currentDataIndex] = (uint8_t)read_reg(DPTX_BUF_DATA_0 + (currentDataIndex*sizeof(uint32_t))); + if ( DP_DEBUG_MASK & DP_DEBUG_DPCD ) + printf("%02x ", data[startOffset + currentDataIndex]); + } + if ( DP_DEBUG_MASK & DP_DEBUG_DPCD ) + printf("\n"); + + startOffset += currentDataCount; + } + + return 0; +} + +int dp_controller_read_bytes_i2c(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length) +{ + uint32_t startOffset = 0; + int ret = 0; + + // try the 128 byte read first + if ( read_bytes_i2c_internal(device_addr, addr, data, length) == 0 ) + return 0; + + debug(I2C, "retrying with segmented reads\n"); + + // if that fails, fall back to individual 16 byte reads + while ( startOffset < length ) { + uint32_t currentDataCount = ((length - startOffset) > DPTX_BUF_DATA_COUNT) ? DPTX_BUF_DATA_COUNT: (length - startOffset); + uint32_t retryCount = 0; + + ret = read_bytes_i2c_internal(device_addr, addr + startOffset, data + startOffset, currentDataCount); + + debug(I2C, "segmented read result=0x%08x with %d retries\n", ret, retryCount); + + if ( ret != 0 ) + break; + + startOffset += currentDataCount; + } + return ret; +} + +int dp_controller_write_bytes_dpcd(u_int32_t addr, u_int8_t *data, u_int32_t length) +{ + uint32_t startOffset = 0; + int ret; + + ret = -1; + + debug(DPCD, "addr=0x%08x data=%p length=%d \n", addr, data, length); + + while (startOffset < length) { + uint32_t currentDataCount; + uint32_t currentDataIndex; + + //Clear Buffer + write_reg(DPTX_BUFFER_DATA_CTL, DPTX_BUFFER_DATA_CTL_CLR); + + //Select DPCD device address + write_reg(DPTX_AUX_ADDR_7_0, (addr + startOffset) & 0xFF); + write_reg(DPTX_AUX_ADDR_15_8, ((addr + startOffset)>>8) & 0xFF); + write_reg(DPTX_AUX_ADDR_19_16, ((addr + startOffset)>>16) & 0x0F); + + currentDataCount = ((length - startOffset) > DPTX_BUF_DATA_COUNT) ? + DPTX_BUF_DATA_COUNT: (length - startOffset); + + debug(DPCD, "Bytes: "); + for(currentDataIndex = 0; currentDataIndex < currentDataCount; currentDataIndex++) { + if ( DP_DEBUG_MASK & DP_DEBUG_DPCD ) + printf("%2.2x ", data[startOffset + currentDataIndex]); + write_reg(DPTX_BUF_DATA_0 + (currentDataIndex*sizeof(uint32_t)), + data[startOffset + currentDataIndex]); + } + + //Set DPCD write cmd mot = 0 and write 1 bytes + write_reg(DPTX_AUX_CH_CTL_1, ((currentDataCount - 1) << DPTX_AUX_CH_CTL_1_AUX_LENGTH_SHIFT) | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_NATIVE | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_WRITE); + + //Start Aux transaction + ret = commit_aux_transaction(false, false, kMaxAuxTransactionRetry); + if ( ret != 0 ) + break; + + startOffset += currentDataCount; + } + if ( DP_DEBUG_MASK & DP_DEBUG_DPCD ) + printf("\n"); + + return ret; +} + +int dp_controller_write_bytes_i2c(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length) +{ + uint32_t startOffset = 0; + int ret; + + // start i2c transaction + ret = start_i2c_transaction(device_addr, addr); + if ( ret != 0 ) + goto exit; + + debug(I2C, "addr=0x%08x data=%p length=%d\n", addr, data, length); + + while (startOffset < length) { + uint32_t currentDataCount; + uint32_t currentDataIndex; + + currentDataCount = ((length - startOffset) > DPTX_BUF_DATA_COUNT) ? + DPTX_BUF_DATA_COUNT: (length - startOffset); + + for(currentDataIndex = 0; currentDataIndex < currentDataCount; currentDataIndex++) { + if ( DP_DEBUG_MASK & DP_DEBUG_I2C ) + printf("%2.2x ", data[startOffset + currentDataIndex]); + write_reg(DPTX_BUF_DATA_0 + (currentDataIndex*sizeof(uint32_t)), + data[startOffset + currentDataIndex]); + } + + //Set I2C write cmd 0x04 mot = 1 + write_reg(DPTX_AUX_CH_CTL_1, ((currentDataCount - 1) << DPTX_AUX_CH_CTL_1_AUX_LENGTH_SHIFT) | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_MOT | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_WRITE); + + //Start Aux transaction + ret = commit_aux_transaction(false, true, kMaxI2CTransactionRetry); + if ( ret != 0 ) + break; + + startOffset += currentDataCount; + } + if ( DP_DEBUG_MASK & DP_DEBUG_I2C ) + printf("\n"); + + if ( ret != 0 ) + goto exit; + + ret = stop_i2c_transaction(false); + +exit: + return ret; +} + +int dp_controller_start_video(struct video_link_data *data) +{ +#if WITH_HW_MCU + struct video_link_data edid_data; +#endif + struct video_link_data *timings = NULL; + if ( !dp_started ) + return -1; +#if WITH_HW_MCU + // Overwriting timings with EDID preference. + bcopy(data, &edid_data, sizeof(edid_data)); + if (get_edid_timings(&edid_data.timing) == 0) timings = &edid_data; +#endif + if (timings == NULL) timings = data; + + return configure_video(timings); +} + +int dp_controller_stop_video() +{ + if ( !dp_video_started ) + return -1; + + and_reg(DPTX_VIDEO_CTL_1, ~DPTX_VIDEO_CTL_1_VIDEO_EN); + + dp_video_started = false; + + return 0; +} + +bool dp_controller_video_configured() +{ + return dp_video_started; +} + +//Not supported +bool dp_controller_get_supports_alpm(void) +{ + return false; +} + +int dp_controller_enable_alpm(bool enable, struct video_link_data *data) +{ + return -1; +} + +///////////////////////////////////////// +////////// controller local functions + +static void handle_screensaver_callout(struct callout *co, void *args) +{ + debug(ALWAYS, "Samsung Screensaver\n"); + + display_clear(); +} + +static int dp_controller_task(void *arg) +{ +#if WITH_HW_BS + // Perform this on the displayport task to prevent blocking startup. +# if PRODUCT_IBEC + mcu_set_passthrough_mode(false); +# else + mcu_set_passthrough_mode(true); +# endif +#endif + + // External display, we would like to put screensaver + if (dp_controller_type == kDPControllerType_DP) { + callout_enqueue(&dp_controller_screensaver_callout, kScreenBurnTimeout, handle_screensaver_callout, NULL); + } + + for (;;) { + + event_wait(&dp_controller_task_event); + + // if controller was stopped before dp task got chance to run, exit + if (dp_started == false) { + printf("dp not started\n"); + return 0; + } + + mask_int(dp_config[dp_controller_type].irq); + + if (dp_interrupt_occurred) { + dp_interrupt_occurred = false; + + if (dp_controller_type == kDPControllerType_DP) { + callout_reset(&dp_controller_screensaver_callout, 0); + } + // Invoke bottom half. + handle_interrupt(); + } + + unmask_int(dp_config[dp_controller_type].irq); + } + + return 0; +} + +static void init_hw() +{ + int i; + u_int32_t reg_val; + + //////////////// + // Analog init + + write_reg(DPTX_ANALOG_CTL_1, (DPTX_ANALOG_CTL_1_TX_TERM_CTL_45_OHM_VALUE<= 2 + // power down ch3 ch2 + reg_val |= (DPTX_DP_PHY_CH3_PWR_DWN | DPTX_DP_PHY_CH2_PWR_DWN); +#endif // DISPLAYPORT_VERSION >= 2 +#if DISPLAYPORT_VERSION > 2 && LOW_POWER_MODE == 1 + //to use 300mv we need to enable low-power mode + reg_val |= DPTX_DP_PHY_SEL_LOWPOWER; +#endif // DISPLAYPORT_VERSION > 2 && LOW_POWER_MODE == 1 + write_reg(DPTX_DP_PHY_PD, reg_val); + + // clear PLL + write_reg(DPTX_COMMON_INT_STA_1, DPTX_COMMON_INT_1_PLL_LCK_CHG); + and_reg(DPTX_DP_DEBUG_CTL, ~(DPTX_DP_DEBUG_CTL_F_PLL_LOCK | DPTX_DP_DEBUG_CTL_PLL_LOCK_CTRL)); + + // power up the PLL + uint8_t pllLockState; + while(((pllLockState = read_reg(DPTX_DP_DEBUG_CTL)) & DPTX_DP_DEBUG_CTL_PLL_LOCK) == 0) + debug(INFO, "before pllLockState=%d\n", pllLockState); + + and_reg(DPTX_DP_PLL_CTL, ~(DPTX_DP_PLL_CTL_PWR_DN)); + debug(INFO, "powered up DP PLL lockstate=%d\n", pllLockState); + + while(((pllLockState = read_reg(DPTX_DP_DEBUG_CTL)) & DPTX_DP_DEBUG_CTL_PLL_LOCK) == 0) + debug(INFO, "after pllLockState=%d\n", pllLockState); + + and_reg(DPTX_FUNC_EN_2, ~(DPTX_FUNC_EN_2_SERDES_FIFO | + DPTX_FUNC_EN_2_LS_CLK_DOMAIN | + DPTX_FUNC_EN_2_AUX)); + + //////////////// + // enable Aux + + // power off aux to reset + or_reg(DPTX_FUNC_EN_2, DPTX_FUNC_EN_2_AUX); + + // configure channel defer + write_reg(DPTX_AUX_CH_DEFER_CTL, DPTX_AUX_CH_DEFER_CTL_EN | (0x0<= 2 + case 2: + shift = DPTX_PLL_FILTER_CTL_2_CH2_AMP_SHIFT; + break; + case 3: + shift = DPTX_PLL_FILTER_CTL_2_CH3_AMP_SHIFT; + break; +#endif // DISPLAYPORT_VERSION >= 2 + } + + set_bits_in_reg(DPTX_PLL_FILTER_CTL_2, shift, 0x7 << shift, voltage); +#endif //DISPLAYPORT_VERSION < 3 + + // pre charge delay + spin(10); + + return 0; +} + +static int configure_video(struct video_link_data *data) +{ + debug(VIDEO, "starting to configure video\n"); + + if (dp_video_started) return 0; + + // Uncomment to show the timings we finally decide to use. +#if 0 + debug(ALWAYS, "configure_video with:\n"); + debug(ALWAYS, "mirror_mode: %d\n", data->mirror_mode); + debug(ALWAYS, "test_mode: 0x%08x\n", data->test_mode); + debug(ALWAYS, "color:\n"); + debug(ALWAYS, " depth: %u\n", data->color.depth); + debug(ALWAYS, " space: %u\n", data->color.space); + debug(ALWAYS, " range: %u\n", data->color.range); + debug(ALWAYS, " coefficient: %u\n", data->color.coefficient); + debug(ALWAYS, "timing:\n"); + debug(ALWAYS, " interlaced: %d\n", data->timing.interlaced); + { + int i; + for (i = 0; i < kDisplayAxisCount; ++i) { + debug(ALWAYS, " Axis %d:\n", i); + debug(ALWAYS, " total: %u\n", data->timing.axis[i].total); + debug(ALWAYS, " active: %u\n", data->timing.axis[i].active); + debug(ALWAYS, " sync_width: %u\n", data->timing.axis[i].sync_width); + debug(ALWAYS, " back_porch: %u\n", data->timing.axis[i].back_porch); + debug(ALWAYS, " front_porch: %u\n", data->timing.axis[i].front_porch); + debug(ALWAYS, " sync_rate: %u (%uHz)\n", + data->timing.axis[i].sync_rate, data->timing.axis[i].sync_rate >> 16); + debug(ALWAYS, " sync_polarity: %u\n", data->timing.axis[i].sync_polarity); + } + } +#endif + + init_video((data->mirror_mode ? false : true)); + + if ( configure_video_mode(data) != 0 ) + goto exit; + + if ( configure_video_color(data) != 0 ) + goto exit; + + configure_video_bist(data); + + uint8_t pllLockState; + while(((pllLockState = read_reg(DPTX_DP_DEBUG_CTL)) & DPTX_DP_DEBUG_CTL_PLL_LOCK) == 0) + debug(PLL, "before pllLockState=%d\n", pllLockState); + + configure_video_m_n(data); + + configure_video_mute(data, false); + + configure_video_timing_mode(data); + + // Setup InfoFrame + // RY:Please refer to page 65 of the CEA861 spec + write_reg(DPTX_AVI_DB1, 0); + write_reg(DPTX_AVI_DB2, 0x08); + write_reg(DPTX_AVI_DB3, 0x00); + write_reg(DPTX_AVI_DB4, 0x00); + write_reg(DPTX_AVI_DB5, 0x00); + write_reg(DPTX_AVI_DB6, 0x00); + write_reg(DPTX_AVI_DB7, 0x00); + write_reg(DPTX_AVI_DB8, 0x00); + write_reg(DPTX_AVI_DB9, 0x00); + write_reg(DPTX_AVI_DB10, 0x00); + write_reg(DPTX_AVI_DB11, 0x00); + write_reg(DPTX_AVI_DB12, 0x00); + write_reg(DPTX_AVI_DB13, 0x00); + or_reg(DPTX_PKT_SEND_CTL, DPTX_BF_C_AVI_EN | DPTX_BF_C_AVI_UP); + + // start video + or_reg(DPTX_VIDEO_CTL_1, DPTX_VIDEO_CTL_1_VIDEO_EN); + + dp_video_started = true; + + debug(VIDEO, "finished configuring video\n"); + + return 0; + +exit: + debug(ERROR, "failed to configure video\n"); + dp_video_started = false; + return -1; +} + +static void init_video(bool master) +{ + // configure video + write_reg(DPTX_SYS_CTL_1, 0); // clear force_det and det_ctrl + write_reg(DPTX_VIDEO_CTL_8, (2 << 4) | (0 << 0)); // vid_hres_th and vid_vres_th + write_reg(DPTX_SYS_CTL_2, (0xf << 4)); // clear cha_sta, force_cha and cha_ctrl + write_reg(DPTX_VIDEO_CTL_10, 0); + + and_reg(DPTX_SYS_CTL_3, ~(DPTX_SYS_CTL_3_F_VALID | DPTX_SYS_CTL_3_VALID_CTRL)); + +#if DISPLAYPORT_VERSION == 0 + + // enable vid capture and vid fifo + and_reg(DPTX_FUNC_EN_1, ~(DPTX_FUNC_EN_1_VIDCAP | DPTX_FUNC_EN_1_VIDFIF0)); + +#elif DISPLAYPORT_VERSION >= 1 + + if ( !master ) { + and_reg(DPTX_FUNC_EN_1, ~(DPTX_FUNC_EN_1_SLAVE)); + or_reg(DPTX_FUNC_EN_1, DPTX_FUNC_EN_1_MASTER); + } else { + and_reg(DPTX_FUNC_EN_1, ~(DPTX_FUNC_EN_1_MASTER)); + or_reg(DPTX_FUNC_EN_1, DPTX_FUNC_EN_1_SLAVE); + } + +#endif // DISPLAYPORT_VERSION +} + +static void configure_video_timing_mode(struct video_link_data *data) +{ + if ( data->mirror_mode ) { + // enable video slave mode + or_reg(DPTX_SOC_GENERAL_CTL, DPTX_SOC_GENERAL_CTL_VIDEO_MODE); // slave mode + and_reg(DPTX_SOC_GENERAL_CTL, ~(DPTX_SOC_GENERAL_CTL_VIDEO_MASTER_MODE_EN)); // enable video timing generation + } + else { + // enable video master mode + and_reg(DPTX_SOC_GENERAL_CTL, ~(DPTX_SOC_GENERAL_CTL_VIDEO_MODE)); // master mode + or_reg(DPTX_SOC_GENERAL_CTL, (DPTX_SOC_GENERAL_CTL_VIDEO_MASTER_MODE_EN)); // enable video timing generation + } +} + +static void configure_video_mute(struct video_link_data *data, bool mute) +{ + if ( mute ) + or_reg(DPTX_VIDEO_CTL_1, DPTX_VIDEO_CTL_1_VIDEO_MUTE); + else + and_reg(DPTX_VIDEO_CTL_1, ~(DPTX_VIDEO_CTL_1_VIDEO_MUTE)); +} + +static void configure_video_m_n(struct video_link_data *data) +{ + // using register calcuated M/N + // we are defaulting to operating in master mode + // therefore we are ensuring that async clock + // is being used to calculate M/N + and_reg(DPTX_SYS_CTL_4, ~(DPTX_SYS_CTL_4_FIX_M_VID)); + write_reg(DPTX_N_VID_0, 0); + write_reg(DPTX_N_VID_1, 0x80); + write_reg(DPTX_N_VID_2, 0); +} + +static int configure_video_color(struct video_link_data *data) +{ + uint32_t val; + + // set video color format + switch (data->color.depth) { + case 12: + val = DPTX_VIDEO_CTL_2_IN_BPC_12BIT; + break; + case 10: + val = DPTX_VIDEO_CTL_2_IN_BPC_10BIT; + break; + case 8: + val = DPTX_VIDEO_CTL_2_IN_BPC_8BIT; + break; + case 6: + val = DPTX_VIDEO_CTL_2_IN_BPC_6BIT; + break; + default: + return -1; + } + + // Set color range / space + write_reg(DPTX_VIDEO_CTL_2, (data->color.range << DPTX_VIDEO_CTL_2_IN_D_RANGE_SHIFT) | + val | + data->color.space); + + // set color coeff + set_bits_in_reg(DPTX_VIDEO_CTL_3, DPTX_VIDEO_CTL_3_IN_YC_COEFFI_SHIFT, + DPTX_VIDEO_CTL_3_IN_YC_COEFFI_MASK, data->color.coefficient); + + return 0; +} + +static int configure_video_mode(struct video_link_data *data) +{ + if ( data->mirror_mode ) { + debug(VIDEO, "configuring mirror mode (as slave)\n"); + + //Configure Interlaced for slave mode video + if ( data->timing.interlaced ) + or_reg(DPTX_VIDEO_CTL_10, DPTX_VIDEO_CTL_10_SLAVE_I_SCAN_CFG); + else + and_reg(DPTX_VIDEO_CTL_10, ~DPTX_VIDEO_CTL_10_SLAVE_I_SCAN_CFG); + } + else { + uint32_t mVid; + uint32_t nVid; + + debug(VIDEO, "configuring video as master\n"); + + // The register is inverted: 0->positive, 1->negative sync. + if ( data->timing.axis[kDisplayAxisTypeVertical].sync_polarity ) + and_reg(DPTX_VIDEO_CTL_10, ~DPTX_VIDEO_CTL_10_VSYNC_P_CFG); + else + or_reg(DPTX_VIDEO_CTL_10, DPTX_VIDEO_CTL_10_VSYNC_P_CFG); + + if ( data->timing.axis[kDisplayAxisTypeHorizontal].sync_polarity ) + and_reg(DPTX_VIDEO_CTL_10, ~DPTX_VIDEO_CTL_10_HSYNC_P_CFG); + else + or_reg(DPTX_VIDEO_CTL_10, DPTX_VIDEO_CTL_10_HSYNC_P_CFG); + + if ( validate_video(data, &mVid, &nVid) != 0 ) + return -1; + + // setup video format + write_reg(DPTX_H_TOTAL_MASTER, data->timing.axis[kDisplayAxisTypeHorizontal].total); + write_reg(DPTX_H_F_PORCH_MASTER, data->timing.axis[kDisplayAxisTypeHorizontal].front_porch); + write_reg(DPTX_H_B_PORCH_MASTER, data->timing.axis[kDisplayAxisTypeHorizontal].back_porch); + write_reg(DPTX_H_ACTIVE_MASTER, data->timing.axis[kDisplayAxisTypeHorizontal].active); + + write_reg(DPTX_V_TOTAL_MASTER, data->timing.axis[kDisplayAxisTypeVertical].total); + write_reg(DPTX_V_F_PORCH_MASTER, data->timing.axis[kDisplayAxisTypeVertical].front_porch); + write_reg(DPTX_V_B_PORCH_MASTER, data->timing.axis[kDisplayAxisTypeVertical].back_porch); + write_reg(DPTX_V_ACTIVE_MASTER, data->timing.axis[kDisplayAxisTypeVertical].active); + + if ( data->timing.interlaced ) { + or_reg(DPTX_SOC_GENERAL_CTL, DPTX_SOC_GENERAL_CTL_MASTER_VIDEO_INTERLACE_EN); + } else { + and_reg(DPTX_SOC_GENERAL_CTL, ~(DPTX_SOC_GENERAL_CTL_MASTER_VIDEO_INTERLACE_EN)); + } + + write_reg(DPTX_M_VID_MASTER, mVid); + write_reg(DPTX_N_VID_MASTER, nVid); + write_reg(DPTX_M_VID_GEN_FILTER_TH, 0); // Video Filter Thresold + and_reg(DPTX_DP_M_CAL_CTL, ~(1 << 2)); // disable low-pass filter for m-vid + // enable this if we have filter thresold set + } + + return 0; +} + +static int validate_video(struct video_link_data *data, u_int32_t *m_vid, u_int32_t *n_vid) +{ + uint32_t lr; + uint32_t lc; + uint64_t streamClk, maxStreamClk; + uint32_t bpp; + uint32_t vTotalBppPerFrame; + uint64_t maxAvailableVSyncRate; + uint32_t mVid; + uint32_t nVid; + + nVid = 0; + maxStreamClk = 0; + + streamClk = data->timing.axis[kDisplayAxisTypeVertical].total * + data->timing.axis[kDisplayAxisTypeHorizontal].total; + streamClk *= data->timing.axis[kDisplayAxisTypeVertical].sync_rate; // vTotal * hTotal * vSyncRate + streamClk >>= 16; + + bpp = data->color.depth * __s_bpp_coeff[data->color.space]; + + vTotalBppPerFrame = bpp * + data->timing.axis[kDisplayAxisTypeVertical].total * + data->timing.axis[kDisplayAxisTypeHorizontal].total; + + if (vTotalBppPerFrame == 0) { + // Prevent divide-by-zero. + debug(VIDEO, "Frame is zero sized\n"); + return -1; + } + + // if interlaced + if ( data->timing.interlaced ) { + + // XXX tempoorary hack to not support interlaced for the moment + return -1; + + streamClk >>= 1; + vTotalBppPerFrame >>= 1; + } + + debug(VIDEO, "stream clock=%lld\n", streamClk); + + // get link rate and lane count + lr = read_reg(DPTX_LINK_BW_SET); + lc = read_reg(DPTX_LANE_COUNT_SET); + + if (lc == 0) { + debug(ERROR, "Lane count programmed to zero\n"); + return -1; + } + + if (lr == kLinkRate270Gbps) + maxAvailableVSyncRate = kLinkRatePhysical_270gps; + else + maxAvailableVSyncRate = kLinkRatePhysical_162gbps; + + maxAvailableVSyncRate /= 10; + maxAvailableVSyncRate *= 8; + maxAvailableVSyncRate *= lc; + maxAvailableVSyncRate /= vTotalBppPerFrame; + + // setup M and N, master mode + switch (lr) { + case kLinkRate270Gbps: +#if DISPLAYPORT_VERSION == 0 + maxStreamClk = kLSClock_135mhz; + nVid = kLSClock_135mhz; +#elif DISPLAYPORT_VERSION >= 1 + maxStreamClk = kLSClock_171mhz; + nVid = kLSClock_171mhz; +#endif // DISPLAYPORT_VERSION + break; + case kLinkRate162Gbps: + maxStreamClk = kLSClock_81mhz; + nVid = kLSClock_81mhz; + break; + } + + debug(VIDEO, "max stream clock=%lld\n", maxStreamClk); + + if ( streamClk > maxStreamClk ) { + debug(VIDEO, "stream-clk value is bad, %lld\n", streamClk); + return -1; + } + + mVid = (uint32_t)streamClk; + + debug(VIDEO, "maxAvailableVSyncRate=%lld mVid=%d nVid=%d\n", maxAvailableVSyncRate, mVid,nVid); + + if((uint64_t)data->timing.axis[kDisplayAxisTypeVertical].sync_rate > (maxAvailableVSyncRate<<16)) { + debug(VIDEO, "vsync rate is too high, vSyncRate:%d, maxAvailableVSyncRate:%llu\n", + data->timing.axis[kDisplayAxisTypeVertical].sync_rate, maxAvailableVSyncRate); + return -1; + } + + if ( m_vid ) + *m_vid = mVid; + + if ( n_vid ) + *n_vid = nVid; + + return 0; +} + +static void configure_video_bist(struct video_link_data *data) +{ + // enable bist mode + if ( data->test_mode ) { + write_reg(DPTX_VIDEO_CTL_4, DPTX_VIDEO_CTL_4_BIST_EN | + ((data->test_mode - 1) & DPTX_VIDEO_CTL_4_BIST_TYPE_MASK)); + debug(VIDEO, "Finished Video BIST\n"); + } else { + and_reg(DPTX_VIDEO_CTL_4, ~(DPTX_VIDEO_CTL_4_BIST_EN)); + } +} + +static int read_bytes_i2c_internal(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length) +{ + int ret = 0; + uint32_t startOffset = 0; + uint32_t attemptCount = 0; + uint32_t maxAttempts = kMaxI2CTransactionRetry + 1; + + debug(I2C, "device_addr=0x%08x addr=0x%08x data=%p length=%d payload=\n", device_addr, addr, + data, length); + + // Since we don't allow any retries on commitAuxTransaction, we should really + // retry on the whole transaction, which includes: start, commmit, and stop + while ( attemptCount++ < maxAttempts ) { + int commitRet = 0; + + if ( ret != 0 ) { + debug(I2C, "waiting %dus till next attempt\n", kAUXRetryIntervalUS); + task_sleep(kAUXRetryIntervalUS); + } + + ret = start_i2c_transaction(device_addr, addr); + if ( ret != 0 ) + goto check; + + while (startOffset < length) { + uint32_t actualDataCount; + uint32_t currentDataCount; + uint32_t currentDataIndex; + + currentDataCount = ((length - startOffset) > DPTX_BUF_DATA_COUNT) ? + DPTX_BUF_DATA_COUNT : (length - startOffset); + + //Set I2C write cmd 0x04 mot = 1 + debug(I2C, "startOffset=%d requesting=%d bytes\n", startOffset, currentDataCount); + + write_reg(DPTX_AUX_CH_CTL_1, ((currentDataCount - 1) << DPTX_AUX_CH_CTL_1_AUX_LENGTH_SHIFT) | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_MOT | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_READ); + + write_reg(DPTX_BUFFER_DATA_CTL, DPTX_BUFFER_DATA_CTL_CLR); + + //Start Aux transaction + commitRet = commit_aux_transaction(false, true, kMaxAuxTransactionRetry); + if ( commitRet != 0 ) + break; + + actualDataCount = read_reg(DPTX_BUFFER_DATA_CTL) & 0x1f; + debug(I2C, "i2C data length %d, expecting %d\n", actualDataCount, currentDataCount); + debug(I2C, "Bytes: "); + if ( currentDataCount != actualDataCount ) { + commitRet = kDPAuxTranscationStatus_IOError; + debug(I2C, "Short RX!!!\n"); + break; + } + + for(currentDataIndex = 0; currentDataIndex < currentDataCount; currentDataIndex++) { + data[startOffset + currentDataIndex] = (uint8_t)read_reg(DPTX_BUF_DATA_0 + (currentDataIndex*sizeof(uint32_t))); + if ( DP_DEBUG_MASK & DP_DEBUG_I2C ) + printf("%02x ", data[startOffset + currentDataIndex]); + } + if ( DP_DEBUG_MASK & DP_DEBUG_I2C ) + printf("\n"); + + startOffset += currentDataCount; + } + + check: + // need to call stop regardless of transaction result + ret = stop_i2c_transaction(true); + // if stop and commit was successful, break + // if stop was successfull, but commit was not, assign commit return value to ret + if ( ret == 0 ) { + if ( commitRet == 0 ) + break; + + ret = commitRet; + } + } + + debug(I2C, "result=%d\n", ret); + return ret; +} + +static int wait_for_aux_done() +{ + uint32_t timeout_time = 20; + while (timeout_time-- && (read_reg(DPTX_AUX_CH_STA) & DPTX_AUX_CH_STA_BUSY)) + task_sleep(50); + return (timeout_time == 0) ? -1 : 0; +} + +static int commit_aux_transaction(bool useInterrupts, bool deferRetryOnly, u_int32_t maxRetryCount) +{ + uint32_t retryCount = 0; + int ret; + + ret = -1; + + if ( useInterrupts ) { + debug(AUX, "dp_aux_transaction_pending=%d sleeping\n", dp_aux_transaction_pending); + + // sleep on dp_aux_transaction_pending + while( dp_aux_transaction_pending ) + task_yield(); + + debug(AUX, "dp_aux_transaction_pending=%d waking\n", dp_aux_transaction_pending); + + dp_aux_transaction_pending = true; + } + + for ( retryCount=0; retryCount<= maxRetryCount; retryCount++ ) { + + if ( retryCount ) { + debug(AUX, "waiting %dus till next attempt\n", kAUXRetryIntervalUS); + task_sleep(kAUXRetryIntervalUS); + } + + ret = wait_for_aux_done(); + if ( ret != 0 ) { + debug(ERROR, "Timeout waiting for AUX done\n"); + continue; + } + + // enable interrupt + or_reg(DPTX_DP_INT_STA, DPTX_DP_INT_STA_RPLY_RCV|DPTX_DP_INT_STA_AUX_ERR); + or_reg(DPTX_DP_INT_STA_MASK, DPTX_DP_INT_STA_RPLY_RCV|DPTX_DP_INT_STA_AUX_ERR); + + // start aux + or_reg(DPTX_AUX_CH_CTL_2, DPTX_AUX_CH_CTL_2_AUX_EN); + + dp_aux_transaction_status = kDPAuxTranscationStatus_None; + if ( useInterrupts ) { + debug(AUX, "sleeping on dp_aux_transaction_status\n"); + // sleep on dp_aux_transaction_status + while ( dp_aux_transaction_status == kDPAuxTranscationStatus_None ) + task_yield(); + debug(AUX, "waking on dp_aux_transaction_status\n"); + } + else { + // Wait until interrupt received and aux channel enable auto-clears. + uint32_t int_sta; + for (;;) { + int_sta = read_reg(DPTX_DP_INT_STA) & (DPTX_DP_INT_STA_RPLY_RCV | DPTX_DP_INT_STA_AUX_ERR); + write_reg(DPTX_DP_INT_STA, int_sta); + if (int_sta != 0 && (read_reg(DPTX_AUX_CH_CTL_2) & DPTX_AUX_CH_CTL_2_AUX_EN) == 0) + break; + task_yield(); + } + + if (dp_controller_type == kDPControllerType_DP) { + callout_reset(&dp_controller_screensaver_callout, 0); + } + + if (int_sta & DPTX_DP_INT_STA_AUX_ERR) { + uint8_t aux_err = read_reg(DPTX_AUX_CH_STA) & DPTX_AUX_CH_STA_STATUS_MASK; + debug(AUX, "AUX_STATUS error: %d\n", aux_err); + + dp_aux_transaction_status = ( aux_err == DPTX_AUX_CH_STA_DEFER ) ? kDPAuxTranscationStatus_IODefer : kDPAuxTranscationStatus_IOError; + + } else { + dp_aux_transaction_status = kDPAuxTranscationStatus_Success; + } + } + + // make sure the aux channel is not busy + ret = wait_for_aux_done(); + if ( ret != 0 ) { + and_reg(DPTX_AUX_CH_CTL_2, ~DPTX_AUX_CH_CTL_2_AUX_EN); + debug(ERROR, "Timeout waiting for AUX done\n"); + continue; + } + + debug(AUX, "dp_aux_transaction_status=0x%08x\n", dp_aux_transaction_status); + + ret = dp_aux_transaction_status; + if (ret == kDPAuxTranscationStatus_Success) { + break; + } else if (ret!=kDPAuxTranscationStatus_IODefer && deferRetryOnly ) { + debug(AUX, "Not retrying because error not defer. ret=0x%08x\n", ret); + break; + } + } + + // clear reply receive interrupt + or_reg(DPTX_DP_INT_STA, DPTX_DP_INT_STA_RPLY_RCV|DPTX_DP_INT_STA_AUX_ERR); + and_reg(DPTX_DP_INT_STA_MASK, ~(DPTX_DP_INT_STA_RPLY_RCV|DPTX_DP_INT_STA_AUX_ERR)); + + if ( useInterrupts ) { + dp_aux_transaction_pending = false; + // wake up dp_aux_transaction_pending + debug(AUX, "waking pending dp_aux_transaction_pending\n"); + } + + if ( ret == kDPAuxTranscationStatus_IOError) + debug(AUX, "AUX transaction failed\n"); + + return ret; +} + +static int start_i2c_transaction(uint32_t device_addr, uint32_t addr) +{ + //Clear Buffer + write_reg(DPTX_BUFFER_DATA_CTL, DPTX_BUFFER_DATA_CTL_CLR); + + write_reg(DPTX_AUX_CH_CTL_2, 0); + + write_reg(DPTX_BUFFER_DATA_CTL, DPTX_BUFFER_DATA_CTL_CLR); + + //Select EDID device address + write_reg(DPTX_AUX_ADDR_7_0, (device_addr) & 0xFF); + write_reg(DPTX_AUX_ADDR_15_8, ((device_addr)>>8) & 0xFF); + write_reg(DPTX_AUX_ADDR_19_16, ((device_addr)>>16) & 0x0F); + + //Set reg addr of I2C device. + write_reg(DPTX_BUF_DATA_0, addr); + + //Set I2C write com 0x04 mot = 1 + write_reg(DPTX_AUX_CH_CTL_1, DPTX_AUX_CH_CTL_1_AUX_TX_COMM_MOT | + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_WRITE); + + //Start Aux transaction + return commit_aux_transaction(false, false, kMaxAuxTransactionRetry); +} + +static int stop_i2c_transaction(bool read) +{ + int ret; + + //Turn off MOT bit + write_reg(DPTX_AUX_CH_CTL_1, read ? + DPTX_AUX_CH_CTL_1_AUX_TX_COMM_READ : DPTX_AUX_CH_CTL_1_AUX_TX_COMM_WRITE); + + //Set address only transaction bit + write_reg(DPTX_AUX_CH_CTL_2, DPTX_AUX_CH_CTL_2_AUX_ADDR_ONLY); + + //Terminate Aux transaction + ret = commit_aux_transaction(false, false, kMaxAuxTransactionRetry); + if ( ret != 0 ) + goto exit; + + //Clear address only transaction bit + write_reg(DPTX_AUX_CH_CTL_2, 0); + +exit: + return ret; +} + +static uint32_t read_reg(uint32_t offset) +{ + return(*(volatile uint32_t *)(__base_address + offset)); +} + +static void write_reg(uint32_t offset, uint32_t value) +{ + *(volatile uint32_t *)(__base_address + offset) = value; +} + +static void and_reg(uint32_t offset, uint32_t value) +{ + *(volatile uint32_t *)(__base_address + offset) &= value; +} + +static void or_reg(uint32_t offset, uint32_t value) +{ + *(volatile uint32_t *)(__base_address + offset) |= value; +} + +static void set_bits_in_reg(u_int32_t offset, u_int32_t pos, u_int32_t mask, u_int32_t value) +{ + uint32_t set = read_reg(offset); + + set &= ~mask; + set |= (value << pos); + + write_reg(offset, set); +} diff --git a/drivers/samsung/displayport/include/drivers/displayport/displayport.h b/drivers/samsung/displayport/include/drivers/displayport/displayport.h new file mode 100644 index 0000000..4552f7c --- /dev/null +++ b/drivers/samsung/displayport/include/drivers/displayport/displayport.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef DRIVER_DISPLAYPORT_H +#define DRIVER_DISPLAYPORT_H 1 + +#include +#include + +typedef struct +{ + uint32_t mode : 4; // 3:0 + uint32_t type : 4; // 7:4 + uint32_t min_link_rate : 8; // 15:8 + uint32_t max_link_rate : 8; // 23:16 + uint32_t lanes : 4; // 27:24 + uint32_t ssc : 1; // 28 + uint32_t alpm : 1; // 29 + uint32_t vrr_enable : 1; // 30 + uint32_t vrr_on : 1; // 31 +} dp_t; + +#endif //DRIVER_DISPLAYPORT_H diff --git a/drivers/samsung/displayport/regs.h b/drivers/samsung/displayport/regs.h new file mode 100644 index 0000000..fc39bde --- /dev/null +++ b/drivers/samsung/displayport/regs.h @@ -0,0 +1,912 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Registers for Display Port General Control +#define DPTX_DP_TX_VERSION 0x0010 + +#define DPTX_FUNC_EN_1 0x0018 + + #define DPTX_FUNC_EN_1_VIDCAP (0x1<<6) + #define DPTX_FUNC_EN_1_VIDFIF0 (0x1<<5) + #define DPTX_FUNC_EN_1_AUDFIF0 (0x1<<4) + #define DPTX_FUNC_EN_1_AUDCAP (0x1<<3) + #define DPTX_FUNC_EN_1_HDCP (0x1<<2) + #define DPTX_FUNC_EN_1_SW_ALL (0x1<<0) + +#define DPTX_FUNC_EN_2 0x001C + #define DPTX_FUNC_EN_2_SSC (0x1<<7) + #define DPTX_FUNC_EN_2_AUX (0x1<<2) + #define DPTX_FUNC_EN_2_SERDES_FIFO (0x1<<1) + #define DPTX_FUNC_EN_2_LS_CLK_DOMAIN (0x1<<0) + +#define DPTX_VIDEO_CTL_1 0x0020 + #define DPTX_VIDEO_CTL_1_VIDEO_EN_SHIFT (7) + #define DPTX_VIDEO_CTL_1_VIDEO_EN (0x1<= 3 + #define DPTX_ANALOG_CTL_1_SEL_BG (1<<6) +#endif //DISPLAYPORT_VERSION + + #define DPTX_ANALOG_CTL_1_TX_TERM_CTL_SHIFT 4 + #define DPTX_ANALOG_CTL_1_TX_TERM_CTL_73_OHM_VALUE 0 + #define DPTX_ANALOG_CTL_1_TX_TERM_CTL_50_OHM_VALUE 1 + #define DPTX_ANALOG_CTL_1_TX_TERM_CTL_61_OHM_VALUE 2 + #define DPTX_ANALOG_CTL_1_TX_TERM_CTL_45_OHM_VALUE 3 + + #define DPTX_ANALOG_CTL_1_TX_SWING_INC_30PER (1<<3) + + #define DPTX_ANALOG_CTL_1_TEST_BIT_MASK (0x7) + #define DPTX_ANALOG_CTL_1_TEST_BIT_SHIFT (0) + +#define DPTX_ANALOG_CTL_2 0x0374 + #define DPTX_ANALOG_CTL_2_SEL_CLK_24M (1<<3) + + #define DPTX_ANALOG_CTL_2_TX_DVDD_BIT_MASK (0x7) + #define DPTX_ANALOG_CTL_2_TX_DVDD_BIT_SHIFT (0) + #define DPTX_ANALOG_CTL_2_TX_DVDD_BIT_DVDD (0< +#include +#include +#include +#include +#include +#include + +#include "drex.h" + +#if (TARGET_DREX_CLK_RATIO != 1) && (TARGET_DREX_CLK_RATIO != 2) +#error "Invalid TARGET_DREX_CLK_RATIO" +#endif + +static u_int32_t calc_sdram_refresh(u_int32_t tREFI, int clock); + +static uint8_t drex_mrr(uint8_t address) +{ + uint32_t cmd_type = 9; + uint32_t cmd_addr = ((address >> 6) & 0x3) | ((address & 0x7) << 10); + uint32_t cmd_bank = (address >> 3) & 0x7; + + rDIRECTCMD = (cmd_type << 24) | (cmd_bank << 16) | (cmd_addr); + spin(2); + + return rMRSTATUS; +} + +static void drex_mrw(uint8_t address, uint8_t data) +{ + uint32_t cmd_type = 0; + uint32_t cmd_addr = (address >> 6) | (data << 2) | ((address & 0x7) << 10); + uint32_t cmd_bank = (address >> 3) & 0x7; + + rDIRECTCMD = (cmd_type << 24) | (cmd_bank << 16) | (cmd_addr); + spin(2); +} + +int mcu_initialize_dram(bool resume) +{ +#if !SUPPORT_FPGA + // Change PhyZQControl.ctrl_zq_mode_dds to 4 for DDR2 400MHz. The default value, 7, is for DDR3 667MHz + rPHYZQCONTROL = 0xE3855431; + // Set ctrl_start_point and ctrl_inc, enable differential DQS. + // Set ctrl_dll_on to activate the PHY DLL + rPHYCONTROL0 = (0x10 << 16) | (0x10 << 8) | (0x1 << 3) | (0x1 << 1); + // Set ctrl_shiftc = 5 (90 degree shift), ctrl_ref = 8 + rPHYCONTROL1 = (0x00 << 8) | (0x8 << 4) | 0x5; + // Set ctrl_start + rPHYCONTROL0 = (0x10 << 16) | (0x10 << 8) | (0x1 << 3) | (0x1 << 1) | 0x1; +#endif + rCONCONTROL = 0x0FFF30C0 | ((TARGET_DREX_CLK_RATIO - 1) << 1); + rMEMCONTROL = 0x00202500; + rMEMCONFIG = 0x00F01223; + + // Open page policy for all banks, maximum timeout before closing page + rPRECHCONFIG = 0xFF000000; + // Maximum timeout for going into self-refresh and dynamic power-down + rPWRDNCONFIG = 0xFFFF00FF; + + rTIMINGAREF = TARGET_DREX_TIMING_AREF; + rTIMINGROW = TARGET_DREX_TIMING_ROW; + rTIMINGDATA = TARGET_DREX_TIMING_DATA; + rTIMINGPOWER = TARGET_DREX_TIMING_POWER; + +#if !SUPPORT_FPGA + // Wait for ctrl_locked to be set + while ((rPHYSTATUS & (1 << 2)) == 0); + // Prepare for the Force DLL resynchronization + rPHYCONTROL1 = (0x00 << 8) | (0x8 << 4) | (0x0 << 3) | 0x5; + // Force DLL resynchronization + rPHYCONTROL1 = (0x00 << 8) | (0x8 << 4) | (0x1 << 3) | 0x5; + + // ZQ calibration + // zq_start + rPHYZQCONTROL |= (1 << 1); + // wait for ctrl_zq_end + while ((rPHYSTATUS & (1 << 16)) == 0); + // fp_resync for ZQ result update + rPHYCONTROL1 &= ~(1 << 3); + rPHYCONTROL1 |= 1 << 3; + rPHYCONTROL1 &= ~(1 << 3); + // zq_stop + rPHYZQCONTROL &= ~(1 << 1); +#else + spin(100000); +#endif + + // NOP: exit from active/precharge power down or deep power down + rDIRECTCMD = 0x07000000; + spin(250); + + // MRW63: reset memory devices and do device auto-initialization + drex_mrw(63, 0); + + spin(10); + + // RL = 6, WL = 3 + drex_mrw(2, 4); + + // Drive strength 48-ohm typical + drex_mrw(3, 3); + + // Turn on auto-refresh counter + rCONCONTROL |= (1 << 5); + + // Tunables for QoS, see radar 11065185 + rQOSTMDREX = TARGET_DREX_QOS_TIDEMARK; + rQOSACDREX = TARGET_DREX_QOS_ACCESS; + + return 0; +} + +void mcu_adjust_performance(void) +{ +} + +uint64_t mcu_get_memory_size(void) +{ + return chipid_get_memory_density() * chipid_get_memory_ranks() * (chipid_get_memory_width() / 32); +} diff --git a/drivers/samsung/drex/drex.h b/drivers/samsung/drex/drex.h new file mode 100644 index 0000000..1ed8d9a --- /dev/null +++ b/drivers/samsung/drex/drex.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __SAMSUNG_DREX_H +#define __SAMSUNG_DREX_H + +#include + +#define rCONCONTROL (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x000)) +#define rMEMCONTROL (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x004)) +#define rMEMCONFIG (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x008)) +#define rDIRECTCMD (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x010)) +#define rPRECHCONFIG (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x014)) +#define rPHYCONTROL0 (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x018)) +#define rPHYCONTROL1 (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x01C)) +#define rPHYCONTROL2 (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x020)) +#define rPHYCONTROL3 (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x024)) +#define rPWRDNCONFIG (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x028)) +#define rTIMINGPZQ (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x02C)) +#define rTIMINGAREF (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x030)) +#define rTIMINGROW (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x034)) +#define rTIMINGDATA (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x038)) +#define rTIMINGPOWER (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x03C)) +#define rPHYSTATUS (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x040)) +#define rPHYZQCONTROL (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x044)) +#define rCHIP0STATUS (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x048)) +#define rCHIP1STATUS (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x04C)) +#define rAREFSTATUS (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x050)) +#define rMRSTATUS (*(volatile u_int32_t *)(DREX_BASE_ADDR + 0x054)) + +#define rQOSTMDREX (*(volatile u_int32_t *)(AXI_SPINE_BASE_ADDR + 0x400)) +#define rQOSACDREX (*(volatile u_int32_t *)(AXI_SPINE_BASE_ADDR + 0x404)) + +#endif /* ! __SAMSUNG_DREX_H */ diff --git a/drivers/samsung/drex/rules.mk b/drivers/samsung/drex/rules.mk new file mode 100644 index 0000000..e3e7108 --- /dev/null +++ b/drivers/samsung/drex/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2011 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DREX=1 + +ALL_OBJS += $(LOCAL_DIR)/drex.o diff --git a/drivers/samsung/dwi/dwi.c b/drivers/samsung/dwi/dwi.c new file mode 100644 index 0000000..d0dd638 --- /dev/null +++ b/drivers/samsung/dwi/dwi.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#include "dwi.h" + +#ifndef TARGET_DWI_FREQUENCY +#error TARGET_DWI_FREQUENCY not defined by the target +#endif + +#ifndef TARGET_DWI_TRANSFER_GAP_US +#error TARGET_DWI_TRANSFER_GAP_US not defined by the target +#endif + +int dwi_init(void) +{ + u_int32_t dwi_divider, dwi_transfer_gap; + + clock_gate(CLK_DWI, true); + + dwi_divider = (clock_get_frequency(CLK_NCLK) + TARGET_DWI_FREQUENCY - 1) / TARGET_DWI_FREQUENCY; + dwi_transfer_gap = (clock_get_frequency(CLK_NCLK) * TARGET_DWI_TRANSFER_GAP_US) / 1000000; + + rDWI_CLOCK_CONFIG = DWI_CLOCK_CONFIG_CLOCK_SCALER(dwi_divider) | DWI_CLOCK_CONFIG_TX_CPHA_1; + rDWI_TRANSFER_GAP = dwi_transfer_gap; + + return 0; +} + +int dwi_send_backlight_command(uint32_t backlight_command, uint32_t backlight_level) +{ + rDWI_ITR0_TX_DATA = (backlight_command << 28) | (backlight_level & 0x7FF); + rDWI_ITR0_CONTROL = DWI_TR_CTRL_BYTE_SWAP | DWI_TR_CTRL_BYTE_CNT(4) | DWI_TR_CTRL_TRAN_EN; + + return 0; +} diff --git a/drivers/samsung/dwi/dwi.h b/drivers/samsung/dwi/dwi.h new file mode 100644 index 0000000..db27175 --- /dev/null +++ b/drivers/samsung/dwi/dwi.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __SAMSUNG_DWI_H +#define __SAMSUNG_DWI_H + +#include + +#define rDWI_CLOCK_CONFIG (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0000)) +#define DWI_CLOCK_CONFIG_TX_CPHA_1 (1 << 0) +#define DWI_CLOCK_CONFIG_TX_CPHA_2 (0 << 0) +#define DWI_CLOCK_CONFIG_RX_CPHA_1 (1 << 1) +#define DWI_CLOCK_CONFIG_RX_CPHA_2 (0 << 1) +#define DWI_CLOCK_CONFIG_CPOL_LOW (0 << 2) +#define DWI_CLOCK_CONFIG_CPOL_HIGH (1 << 2) +#define DWI_CLOCK_CONFIG_CLOCK_SCALER(_x) (((_x) - 1) << 16) +#define rDWI_TRANSFER_GAP (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0004)) +#define rDWI_ITR0_CONTROL (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0010)) +#define DWI_TR_CTRL_TRAN_EN (1 << 0) +#define DWI_TR_CTRL_BYTE_CNT(_c) (((_c) - 1) << 4) +#define DWI_TR_CTRL_BYTE_SWAP (1 << 6) +#define DWI_TR_CTRL_BIT_ORDER (1 << 7) +#define DWI_TR_CTRL_INT_EN (1 << 8) +#define rDWI_ITR0_TX_DATA (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0014)) +#define rDWI_ITR0_RX_DATA (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0018)) +#define rDWI_ITR0_INT_STATUS (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x001C)) +#define rDWI_ITR1_CONTROL (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0020)) +#define rDWI_ITR1_TX_DATA (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0024)) +#define rDWI_ITR1_RX_DATA (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0028)) +#define rDWI_ITR1_INT_STATUS (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x002C)) +#define rDWI_ITR1_RAMP_COUNT (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0030)) +#define rDWI_ITR1_DELTAV_ACTIVE (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0034)) +#define rDWI_STR_CONTROL (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0040)) +#define rDWI_STR_TX_DATA (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0044)) +#define rDWI_STR_RX_DATA (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0048)) +#define rDWI_STR_INT_STATUS (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x004C)) +#define rDWI_STR_DELAY (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0050)) +#define rDWI_VERSION (*(volatile u_int32_t *)(DWI_BASE_ADDR + 0x0070)) + +#endif /* ! __SAMSUNG_DWI_H */ diff --git a/drivers/samsung/dwi/rules.mk b/drivers/samsung/dwi/rules.mk new file mode 100644 index 0000000..cd4c486 --- /dev/null +++ b/drivers/samsung/dwi/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DWI=1 + +ALL_OBJS += $(LOCAL_DIR)/dwi.o diff --git a/drivers/samsung/gpio/gpio.c b/drivers/samsung/gpio/gpio.c new file mode 100644 index 0000000..c7663a7 --- /dev/null +++ b/drivers/samsung/gpio/gpio.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#include "gpio.h" + +#if WITH_TARGET_CONFIG +# include +#else +# include +#endif + +u_int32_t gpio_read(gpio_t gpio) +{ + int pad = GPIO2PAD(gpio); + int pin = GPIO2PIN(gpio); + +#if WITH_HW_SPI && defined(GPIO_PAD_SPI) + if (pad == GPIO_PAD_SPI) return spi_gpio_read(pin); +#endif + + return (rPDATn(pad) & (1< GPIO_CFG_MAX) return; + + if (config == GPIO_CFG_DFLT) { + func = (gpio_default_config[pad].pcon >> (pin * 4)) & 0xF; + } else { + func = gpio_config_map[config]; + } + + if (func == PCON_DISABLE) { + rPPIEn(pad) &= ~(1 << pin); + rFSEL = (pad << 16) | (pin << 8) | PCON_IN; + } else { + rFSEL = (pad << 16) | (pin << 8) | func; + rPPIEn(pad) |= (1 << pin); + } + + /* Once we reconfigure, reset the pullup/pulldown to default. This could cause + a glitch on outputs, but will avoid spurious transitions on inputs. We're + between a rock and a hard place because of the GPIO block's design. */ + if (config == GPIO_CFG_DFLT) { + uint16_t pupdn = gpio_default_config[pad].pupdn; + uint16_t pullup = pupdn & (1 << pin); + uint16_t pulldown = (pupdn >> 8) & (1 << pin); + + if ((pullup != 0) && (pulldown != 0)) { + panic("Pullup and pulldown at same time on GPIO 0x%x", gpio); + } else if (pullup != 0) { + rPPURn(pad) |= (1 << pin); + rPPDRn(pad) &= ~(1 << pin); + } else if (pulldown != 0) { + rPPURn(pad) &= ~(1 << pin); + rPPDRn(pad) |= (1 << pin); + } else { + rPPURn(pad) &= ~(1 << pin); + rPPDRn(pad) &= ~(1 << pin); + } + } +} + +void gpio_configure_pupdn(gpio_t gpio, int32_t pupdn) +{ + int pad = GPIO2PAD(gpio); + int pin = 1 << GPIO2PIN(gpio); + + if (pupdn < GPIO_NO_PUPDN) { + /* GPIO_PDN */ + rPPURn(pad) &= ~pin; + rPPDRn(pad) |= pin; + } else if (pupdn > GPIO_NO_PUPDN) { + /* GPIO_PUP */ + rPPURn(pad) |= pin; + rPPDRn(pad) &= ~pin; + } else { + /* GPIO_NO_PUPDN */ + rPPURn(pad) &= ~pin; + rPPDRn(pad) &= ~pin; + } +} + +int gpio_init_pinconfig(void) +{ + int pad; + int pin; + + dprintf(DEBUG_SPEW, "gpio_init_pinconfig()\n"); + + /* XXX is there a safe way to set the pullup/pulldown config and set the pin modes? */ + + /* + * since most of these pins are probably going to default to input coming out of the + * boot rom, we'll set the pullup/pulldown first + */ + + /* load the default pullup/pulldown configuration, disallowing + the pullup and pulldown to be set at the same time */ + for (pad = 0; pad < GPIO_GROUP_COUNT; pad++) { + uint32_t pullup; + uint32_t pulldown; + uint16_t pupdn; + + pupdn = gpio_default_config[pad].pupdn; + pullup = pupdn & 0xFF; + pulldown = (pupdn >> 8) & 0xFF; + if ((pullup & pulldown) != 0) + panic("Pullup and pulldown conflict on pins 0x%x of pad %d", pullup & pulldown, pad); + rPPURn(pad) = pullup; + rPPDRn(pad) = pulldown; + } + + /* load the default PCON values, which should also set initial PDATs for gpio out */ + for (pad = 0; pad < GPIO_GROUP_COUNT; pad++) + { + uint32_t pcon; + uint32_t ppie; + ppie = 0xFF; + pcon = gpio_default_config[pad].pcon; + + for (pin = 0; pin < 8; pin++) { + if (((pcon >> (pin * 4)) & 0xF) == PCON_DISABLE) { + pcon &= ~(0xF << (pin * 4)); + ppie &= ~(1 << pin); + } + } + rPCONn(pad) = pcon; + rPPIEn(pad) = ppie; + } + +#ifdef DEFAULT_ODEN + /* set port configuration for I2Cx and TWC */ + rODEN = DEFAULT_ODEN; +#endif + +#if defined(DEFAULT_DSTR0) + /* set the chip default drive strength */ + rDSTR0 = DEFAULT_DSTR0; +#endif + +#ifdef DEFAULT_OSC_DSTR + /* set oscillator drive strength */ + rOSC_DSTR = DEFAULT_OSC_DSTR; +#endif + + return 0; +} + +#if APPLICATION_IBOOT + +int gpio_diag_pinconfig(void) +{ + return 0; +} + +#endif /* APPLICATION_IBOOT */ diff --git a/drivers/samsung/gpio/gpio.h b/drivers/samsung/gpio/gpio.h new file mode 100644 index 0000000..72a55ae --- /dev/null +++ b/drivers/samsung/gpio/gpio.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __SAMSUNG_GPIO_H +#define __SAMSUNG_GPIO_H + +#include + + +/* Register Offsets for Samsung GPIOs */ +#define rPCONn(n) (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x000 + (n) * 0x20)) +#define rPDATn(n) (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x004 + (n) * 0x20)) +#define rPCTLn(n) (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x008 + (n) * 0x20)) +#define rPPURn(n) (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x00C + (n) * 0x20)) +#define rPPDRn(n) (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x010 + (n) * 0x20)) +#define rPPIEn(n) (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x014 + (n) * 0x20)) + +#define rFSEL (*(volatile u_int32_t *)(GPIO_BASE_ADDR + GPIO_FSEL_OFFSET)) + +#define rDSTR0 (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x380)) +#define rOSC_DSTR (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x388)) + +#define rODEN (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x3C0)) +#define rEMAC0 (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x3C4)) +#define rEMAC1 (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x3C8)) +#define rEMAC2 (*(volatile u_int32_t *)(GPIO_BASE_ADDR + 0x3CC)) + + +/* Base Pin Defines for Samsung GPIOs */ +#define PORT(port, pin) ((u_int32_t)((port) << 8) | pin) +#define GPIO2PIN(gpio) ((gpio) & 0x7) +#define GPIO2PAD(gpio) (((gpio) >> 8) & 0x1f) + +/* Precomputes the PCON register's value */ +#define PCON(pinfunc0, pinfunc1, pinfunc2, pinfunc3, pinfunc4, pinfunc5, pinfunc6, pinfunc7) \ + ((u_int32_t)(((pinfunc0) << 0) | ((pinfunc1) << 4) | ((pinfunc2) << 8) | ((pinfunc3) << 12) | \ + ((pinfunc4) << 16) | ((pinfunc5) << 20) | ((pinfunc6) << 24) | ((pinfunc7) << 28))) + +/* some PCON constants */ +enum { + PCON_IN = 0, + PCON_OUT = 1, + PCON_FUNC2 = 2, + PCON_FUNC3 = 3, + PCON_FUNC4 = 4, + PCON_FUNC5 = 5, + PCON_FUNC6 = 6, + + PCON_DISABLE = 0xd, /* not actually supported by the hardware, implies PCON_IN + and input enable disabled */ + PCON_OUT_0 = 0xe, /* same as PCON_OUT, but also sets PDAT to zero */ + PCON_OUT_1 = 0xf /* same as PCON_OUT, but also sets PDAT to one */ +}; + +/* pull up/down configuration */ +enum { + NO_PUPDN = 0, + PUP = (1 << 0), + PDN = (1 << 8) +}; + +#define PUPDN(pinupdn0, pinupdn1, pinupdn2, pinupdn3, pinupdn4, pinupdn5, pinupdn6, pinupdn7) \ + ((uint16_t)(((pinupdn0) << 0) | ((pinupdn1) << 1) | ((pinupdn2) << 2) | ((pinupdn3) << 3) | \ + ((pinupdn4) << 4) | ((pinupdn5) << 5) | ((pinupdn6) << 6) | ((pinupdn7) << 7))) + +struct gpio_default_config { + uint32_t pcon; + uint16_t pupdn; +}; + +#define PINCONFIG(pcon0, pupdn0, pcon1, pupdn1, pcon2, pupdn2, pcon3, pupdn3, \ + pcon4, pupdn4, pcon5, pupdn5, pcon6, pupdn6, pcon7, pupdn7) \ + { .pcon = PCON(pcon0, pcon1, pcon2, pcon3, pcon4, pcon5, pcon6, pcon7), \ + .pupdn = PUPDN(pupdn0, pupdn1, pupdn2, pupdn3, pupdn4, pupdn5, pupdn6, pupdn7) \ + } + +#endif /* __SAMSUNG_GPIO_H */ diff --git a/drivers/samsung/gpio/rules.mk b/drivers/samsung/gpio/rules.mk new file mode 100644 index 0000000..4503bc5 --- /dev/null +++ b/drivers/samsung/gpio/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_GPIO=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/gpio.o diff --git a/drivers/samsung/hdmi8947/hdmi.c b/drivers/samsung/hdmi8947/hdmi.c new file mode 100644 index 0000000..bbdb642 --- /dev/null +++ b/drivers/samsung/hdmi8947/hdmi.c @@ -0,0 +1,1848 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "hdmi.h" +#include "regs.h" + +#include +#include + + +///////////////////////////////////////// +////////// debug support + +#define HDMI_DEBUG_MASK ( \ + HDMI_DEBUG_INIT | \ + HDMI_DEBUG_ERROR | \ + HDMI_DEBUG_INFO | \ + HDMI_DEBUG_INT | \ + HDMI_DEBUG_VIDEO | \ + HDMI_DEBUG_PLL | \ + HDMI_DEBUG_REG | \ + 0) + +#undef HDMI_DEBUG_MASK +#define HDMI_DEBUG_MASK (HDMI_DEBUG_INIT | HDMI_DEBUG_ERROR) + +#define HDMI_DEBUG_INIT (1<<16) // initialisation +#define HDMI_DEBUG_ERROR (1<<17) // errors +#define HDMI_DEBUG_INFO (1<<18) // info +#define HDMI_DEBUG_INT (1<<19) // interrupts +#define HDMI_DEBUG_VIDEO (1<<20) // video +#define HDMI_DEBUG_REG (1<<22) // register +#define HDMI_DEBUG_I2C (1<<23) // i2c read/write +#define HDMI_DEBUG_PLL (1<<24) // PLL +#define HDMI_DEBUG_ALWAYS (1<<31) // unconditional output + +#define debug(_fac, _fmt, _args...) \ + do { \ + if ((HDMI_DEBUG_ ## _fac) & (HDMI_DEBUG_MASK | HDMI_DEBUG_ALWAYS)) \ + dprintf(DEBUG_CRITICAL, "HDMI: %s, %d: " _fmt, __FUNCTION__, __LINE__, ##_args);\ + } while(0) + +///////////////////////////////////////// +////////// consts, macros + +#define HDMI_DTPATH "arm-io/hdmi" + +// Crude screensaver: Turn off hdmi after 3 minutes. +#define kScreenBurnTimeout (3 * 60 * 1000000) +#define kTMDSMinimumPowerOffIntervalMS 100 +#define kHDMICoreResetIntervalMS 1 // Core reset asserted time: Arbitrary large value +#define kPHYResetIntervalMS 1 // PHY reset signal high time: Minimum 100 microseconds per HDMI 1.4 PHY manual + +#define kHDMIStackSize 8192 + +#define require(assertion, exception_label) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +#define require_action(assertion, exception_label, action) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr(error_code, exception_label) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + +#define require_noerr_action(error_code, exception_label, action) \ + do { \ + if (__builtin_expect(0 != (error_code), 0)) \ + { \ + { \ + action; \ + } \ + goto exception_label; \ + } \ + } while (0) + + + +///////////////////////////////////////// +////////// typedefs, enums, structs + +uint32_t _registers[] = { + 0x00000000, + 0x00010000, + 0x00030000, + 0x00040000, + 0x00050000, + 0x00060000, + 0x00070000, + 0x00017000, + 0x00080000, +}; + +uint32_t _phyConfigRegs[kPHYConfigRegCount/4 + 1] = { + HDMI_BASE_ADDR + HDMIPHYCON0, + HDMI_BASE_ADDR + HDMIPHYCON1, + HDMI_BASE_ADDR + HDMIPHYCON2, + HDMI_BASE_ADDR + HDMIPHYCON3, + HDMI_BASE_ADDR + HDMIPHYCON4, + HDMI_BASE_ADDR + HDMIPHYCON5, + HDMI_BASE_ADDR + HDMIPHYCON6, + HDMI_BASE_ADDR + HDMIPHYCON7, + HDMI_BASE_ADDR + HDMIPHYCON8, +}; + +enum Module { + kCtrlModule = 0, // CTRL_BASE: Controller + kHDMIModule = 1, // HDMI_CORE_BASE: HDMI Core + kSPDIFModule = 2, // SPDIF_BASE: SPDIF Receiver + kI2SModule = 3, // I2S_BASE: I2S Receiver + kTGModule = 4, // TG_BASE: Timing Generator + kEFuseModule = 5, // EFUSE_BASE: E-Fuse + kCECModule = 6, // CEC_BASE: HDMI CEC + kHDCPModule = 7, // HDCP Registers + kI2CModule = 8, // I2C_BASE: I2C to HDMI PHY + kModuleCount = 9 +}; + + +///////////////////////////////////////// +////////// local variables + +static const char hdmi_dt_path[] = HDMI_DTPATH; + +static addr_t __base_address; + +static AppleSamsungHDMITXPHYConfigTableEntry *hdmi_port_phy_cfg_table; +size_t hdmi_port_phy_cfg_table_size; + +const HDMITXPHYConfig *phyConfig; + +uint32_t frame_interval_MS; +struct video_link_data _current_video_link; + +static bool hdmi_started; +static bool hdmi_video_started; + +static u_int8_t hdmi_controller_type; +static u_int8_t hdmi_controller_mode; + +static struct task_event hdmi_controller_task_event; + +static struct callout hdmi_controller_screensaver_callout; + +static bool hdmi_interrupt_occurred; +static uint32_t ctrl_int_status; +static uint32_t iic_int_status; + +///////////////////////////////////////// +////////// local functions declaration + +static int hdmi_controller_task(void *arg); +static int hdmi_phy_regs_task(void *arg); +static int configure_video(struct video_link_data *data, uint32_t pixel_clock); +static void init_video(bool master); +static void configure_video_mute(struct video_link_data *data, bool mute); +static int configure_video_color(const struct video_link_data * data); +static int configure_video_mode(struct video_link_data *data, uint32_t pixel_clock); +static void configure_video_bist(struct video_link_data *data); +static void hdmi_interrupt_filter(void *arg); +static void handle_interrupt(void); +static void uninit_video(); +static int reset(void); +static void power_down_phy(bool fullPowerDown); +static int validate_video_link(struct video_link_data * data, uint32_t pixel_clock, const HDMITXPHYConfig ** pPHYConfig); + +static int set_tx_output_enabled(bool enabled); +static int set_tx_output_mode(int mode); + +static void handle_screensaver_callout(struct callout *co, void *args); + +void set_av_mute_enabled(bool enabled); + +static uint8_t read_reg(uint8_t module, u_int32_t offset); +static uint32_t read_reg32(uint8_t module, u_int32_t offset); +static void write_reg(uint8_t module, u_int32_t offset, uint8_t val); +static void write_reg32(uint8_t module, u_int32_t offset, uint32_t val); +static void and_reg(uint8_t module, u_int32_t offset, uint8_t val); +static void or_reg(uint8_t module, u_int32_t offset, uint8_t val); +static void set_bits_in_reg(uint8_t module, u_int32_t offset, uint8_t pos, uint8_t mask, uint8_t value); +static uint32_t get_bits_in_reg(uint8_t module, uint32_t reg, uint32_t pos, uint32_t mask); +static uint8_t read_phy_reg(uint8_t offset); +static int write_phy_reg(u_int32_t offset, const uint8_t data); +static void or_phy_reg(u_int32_t offset, uint8_t data); +static void and_phy_reg(u_int32_t offset, uint8_t data); +void write_regs(uint8_t module, uint32_t basereg, uint32_t, unsigned int length); +void write_regs_with_data(uint8_t module, uint32_t basereg, uint8_t * data, unsigned int length); +static int write_phy_config_reg(PHYConfigReg reg, uint32_t data); +static int stop_video_link(); +static int complete_video_link(); +static void set_TMDS_power_enabled(bool enabled); +static int bypass_wait = 0; + + +struct hdmi_controller_config { + addr_t base_address; + u_int32_t clock; + u_int32_t irq; + const char *dt_path; +}; + +static const struct hdmi_controller_config hdmi_config[] = { +#if WITH_HW_DISPLAY_HDMI + { HDMI_BASE_ADDR, CLK_HDMI, INT_HDMI_LINK, hdmi_dt_path }, +#else + { 0, 0, 0, 0 }, +#endif // WITH_HW_DISPLAY_HDMI +}; + +struct display_infoframe aviInfoFrame = { + kDisplayInfoFrameTypeAVI, + 0x02, //Version + 0x0d, //length + 0xf3, //checksum + {0x10, 0x68, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 } //data +}; + + +extern AppleSamsungHDMITXPHYConfigTableEntry hdmi_static_config[]; +extern size_t hdmi_static_config_size; + +///////////////////////////////////////// +////////// controller global functions + +int hdmi_controller_start(u_int8_t type, u_int8_t mode) +{ + u_int32_t hpdstate; + + + if (hdmi_started) + return 0; + + hdmi_controller_type = type; + hdmi_controller_mode = mode; + + __base_address = hdmi_config[hdmi_controller_type].base_address; + + // register interrupt handler + install_int_handler(hdmi_config[hdmi_controller_type].irq, hdmi_interrupt_filter, NULL); + event_init(&hdmi_controller_task_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + hdmi_port_phy_cfg_table = (AppleSamsungHDMITXPHYConfigTableEntry *)hdmi_static_config; + hdmi_port_phy_cfg_table_size = hdmi_static_config_size; + + clock_gate(hdmi_config[hdmi_controller_type].clock, true); + + unmask_int(hdmi_config[hdmi_controller_type].irq); + + reset(); + + //power down HDMI PHY, keeping HPD enabled + power_down_phy(false); + + hdmi_started = true; + task_start(task_create("hdmi", &hdmi_controller_task, NULL, kHDMIStackSize)); + + hpdstate = read_reg(kCtrlModule, CTRL_HPD_STATUS); + debug(INIT,"hpdstate=0x%08x\n", hpdstate); + if (hpdstate == 0x00000001) { + hdmi_device_start(); + } + + // clear any pending HPD interrupts (Note: status bits are write-one-to-clear) + write_reg(kCtrlModule, CTRL_INTC_FLAG, CTRL_INTC_FLAG_HPD_CHG); + + // unmask HPD + or_reg(kCtrlModule, CTRL_INTC_CON, CTRL_INTC_CON_EN_GLOBAL|CTRL_INTC_CON_EN_HPD_CHG); + + write_reg(kCtrlModule, CTRL_INTC_FLAG, CTRL_INTC_FLAG_HPD_CHG); + + return 0; +} + +void hdmi_controller_stop() +{ + if (!hdmi_started) { + debug(INT, "hdmi not started. Nothing to do\n"); + return; + } + + hdmi_controller_stop_video(); + + // disable interrupt source + mask_int(hdmi_config[hdmi_controller_type].irq); + + // Stop background EDID polling. + abort_edid(); + + hdmi_video_started = false; + + hdmi_device_stop(); + + if (hdmi_controller_type == kHDMIControllerType_HDMI) { + callout_dequeue(&hdmi_controller_screensaver_callout); + } + + hdmi_started = false; +} + +int hdmi_controller_validate_video(struct video_timing_data *timings) +{ + uint64_t pixel_clock; + + // Assume basic settings. + struct video_link_data data; + + bzero(&data, sizeof(data)); + bcopy(timings, &data.timing, sizeof(*timings)); + data.mirror_mode = false; + data.test_mode = 0; + data.color.depth = 8; + data.color.space = kDisplayColorSpacesRGB; + data.color.range = kDisplayColorDynamicRangeVESA; + data.color.coefficient = kDisplayColorCoefficientITU601; + + pixel_clock = data.timing.axis[kDisplayAxisTypeVertical].total * + data.timing.axis[kDisplayAxisTypeHorizontal].total; + pixel_clock *= data.timing.axis[kDisplayAxisTypeVertical].sync_rate; // vTotal * hTotal * vSyncRate + pixel_clock >>= 16; + + debug(VIDEO, "stream clock=%lld\n", pixel_clock); + + return validate_video_link(&data, pixel_clock, NULL); +} + +int hdmi_controller_read_bytes_i2c(u_int32_t device_addr, u_int8_t addr, u_int8_t *data, u_int32_t length) +{ + uint8_t offset[1]; + + offset[0] = addr; + return (iic_read(HDMI_DDC_IIC_BUS, device_addr, offset, 1, data, length, IIC_COMBINED)); +} + +int hdmi_controller_write_bytes_i2c(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length) +{ + return -1; +} + +int hdmi_controller_start_video(struct video_link_data *data, uint32_t pixel_clock) +{ + struct video_link_data edid_data; + struct video_link_data *timings = NULL; + + if ( !hdmi_started ) + return -1; + + debug(INIT,"Pixel clock %d\n", pixel_clock); + // Overwriting timings with EDID preference. + bcopy(data, &edid_data, sizeof(edid_data)); + if (get_edid_timings(&edid_data.timing) == 0) timings = &edid_data; + + if (timings == NULL) timings = data; + + return configure_video(timings, pixel_clock); +} + +int hdmi_controller_stop_video() +{ + if ( !hdmi_video_started ) + return -1; + + stop_video_link(); + complete_video_link(); + + // unmask HPD + or_reg(kCtrlModule, CTRL_INTC_CON, CTRL_INTC_CON_EN_GLOBAL|CTRL_INTC_CON_EN_HPD_CHG); + + write_reg(kCtrlModule, CTRL_INTC_FLAG, CTRL_INTC_FLAG_HPD_CHG); + + hdmi_video_started = false; + + return 0; +} + +bool hdmi_controller_video_configured() +{ + return hdmi_video_started; +} + +uint8_t hdmi_read_reg(uint32_t offset) +{ + return( read_reg(0, offset) ); +} + +void hdmi_write_reg(uint32_t offset, uint8_t value) +{ + write_reg(0, offset, value); +} +///////////////////////////////////////// +////////// controller local functions + + +static void handle_screensaver_callout(struct callout *co, void *args) +{ + debug(ALWAYS, "HDMI Screensaver\n"); + // set_TMDS_power_enabled calls write_phy_reg which endup calling event_wait_timeout. Such call is not safe when performed in the handling of the callout. + bypass_wait = 1; + set_TMDS_power_enabled(false); + bypass_wait = 0; +} + +static int hdmi_controller_task(void *arg) +{ + if (hdmi_controller_type == kHDMIControllerType_HDMI) { + callout_enqueue(&hdmi_controller_screensaver_callout, kScreenBurnTimeout, handle_screensaver_callout, NULL); + } + + // Perform this on the hdmi task to prevent blocking startup. + for (;;) { + + event_wait(&hdmi_controller_task_event); + + // if controller was stopped before hdmi task got chance to run, exit + if (hdmi_started == false) { + debug(ERROR, "controller task stopped since hdmi stopped\n"); + return 0; + } + + mask_int(hdmi_config[hdmi_controller_type].irq); + + if (hdmi_interrupt_occurred) { + hdmi_interrupt_occurred = false; + + if (hdmi_controller_type == kHDMIControllerType_HDMI) { + callout_reset(&hdmi_controller_screensaver_callout, 0); + } + + // Invoke bottom half. + handle_interrupt(); + } + unmask_int(hdmi_config[hdmi_controller_type].irq); + } + + return 0; +} + +static bool get_hot_plug_detect() +{ + return read_reg(kCtrlModule, CTRL_HPD_STATUS) & CTRL_HPD_STATUS_PLUGGED; +} + +static void hdmi_interrupt_filter(void *arg) +{ + ctrl_int_status = read_reg(kCtrlModule, CTRL_INTC_FLAG); + write_reg(kCtrlModule, CTRL_INTC_FLAG, ctrl_int_status); + + iic_int_status = read_reg32(kI2CModule, IICINT); + write_reg32(kI2CModule, IICINT, iic_int_status); + + debug(INT, "Interrupt received. ctrl_int_status=0x%08x\n", ctrl_int_status); + debug(INT, "Interrupt received. ctrl_int_status=0x%08x iic_int_status=0x%08x\n", ctrl_int_status, iic_int_status); + + hdmi_interrupt_occurred = true; + + event_signal(&hdmi_controller_task_event); +} + +static void handle_interrupt(void) +{ + // Handle unplug event + if ( (ctrl_int_status & CTRL_INTC_FLAG_HPD_UNPLUG) ) { + debug(INT, "HPD_UNPLUG\n"); + + debug(INT, "MUST HANDLE TEAR DOWN\n"); + hdmi_device_stop(); + } + + // Handle plug event + if ( (ctrl_int_status & CTRL_INTC_FLAG_HPD_PLUG) ) { + debug(INT, "HPD_PLUG\n"); + + if ( get_hot_plug_detect() ) { + debug(INT, "MUST HANDLE PLUG IN \n"); + hdmi_device_start(); + + } else { + debug(INT, "MUST HANDLE UNPLUG\n"); + hdmi_device_stop(); + } + } + + // Handle HDCP interrupts + if ((ctrl_int_status & CTRL_INTC_FLAG_HDCP)) { + uint32_t hdcp_int_status; + + debug(INT, "HDCP REALLY!!!\n"); + hdcp_int_status = read_reg(kHDMIModule, HDMI_STATUS); + + // Clear active HDCP interrupts (Note: bit 7 is read-only and not an interrupt source) + write_reg(kHDMIModule, HDMI_STATUS, hdcp_int_status); + } + +} + +static void reset_HDMI_core(void) +{ + // From H4I Power Manager (PMGR) Microarchitecture Specification + // section 7.2 Block Resets (see H4i_UM): + // + // NOTE: Some of the blocks may have CSR bits defined as reset bits, however some of these have + // been disabled. The only valid supported block reset mechanism in H4I is the reset bit in the + // block's power state register. + + //Reset device + clock_reset_device(hdmi_config[hdmi_controller_type].clock); +} + +static void reset_PHY(void) +{ + // Ensure that PHY is powered on (if the PHY power off signal is connected) + and_reg(kCtrlModule, CTRL_PHY_CON_0, ~CTRL_PHY_CON_0_PHY_PWR_OFF); + + // Reset PHY + or_reg(kCtrlModule, CTRL_PHY_RSTOUT, CTRL_HDMI_PHY_RSTOUT_RESET); + task_sleep(kPHYResetIntervalMS); + and_reg(kCtrlModule, CTRL_PHY_RSTOUT, ~(CTRL_HDMI_PHY_RSTOUT_RESET)); + +} + +static void set_TMDS_power_enabled(bool enabled) +{ + uint8_t reg; + uint8_t mask; + static bool tmds_enabled = 0; + + if (tmds_enabled == enabled) + return; + + tmds_enabled = enabled; + reg = PHY_CONFIG_REG1D; + mask = PHY_V1P4_CONFIG_REG1D_I2C_PDEN | PHY_V1P4_CONFIG_REG1D_TX_DRV_PD; + + if (enabled ) { + and_phy_reg(reg, ~mask); + } else { + or_phy_reg(reg, mask); + } +} + +static void power_down_phy(bool fullPowerDown) +{ + + or_phy_reg(PHY_CONFIG_REG1D, PHY_V1P4_CONFIG_REG1D_I2C_PDEN | (fullPowerDown ? PHY_V1P4_CONFIG_REG1D_FULL_PD : PHY_V1P4_CONFIG_REG1D_PD_WITH_HPD)); + debug(INIT,"PHY %s power down\n", fullPowerDown ? "full" : "partial"); + + if ( fullPowerDown ) { + // Power down PHY (if the PHY power off signal is connected) + or_reg(kCtrlModule, CTRL_PHY_CON_0, CTRL_PHY_CON_0_PHY_PWR_OFF); + } +} + +bool get_is_PHY_ready(void) +{ + return ((read_reg(kCtrlModule, CTRL_PHY_STATUS_0) & CTRL_PHY_STATUS_0_PHY_READY) ? true : false) ; +} + +static int reset(void) +{ + debug(INIT,"PHY_CON_0=0x%08x\n", read_reg(kCtrlModule, CTRL_PHY_CON_0)); + // Reset HDMI core and PHY + debug(INIT,"PHYReady=%u\n", get_is_PHY_ready()); + + // Reset HDMI core (Note: core reset disables PHY power in case of 1.4 TX) + reset_HDMI_core(); + + // Reset HDMI PHY + reset_PHY(); + + // Set TMDS bit order + set_bits_in_reg(kHDMIModule, HDMI_CON_0, 0, HDMI_CON_0_ENCODING_RETAIN_BIT_ORDER, 0); + + debug(INIT,"PHYReady=%u\n", get_is_PHY_ready()); + + debug(INIT,"PHY_CON_0=0x%08x\n", read_reg(kCtrlModule, CTRL_PHY_CON_0)); + // Initialize the I2C bridge + // + // - Clear pending interrupts + // - Set configuration options from device tree + // - Unmask Stop interrupt + // - Enable ACK generation + // - Set mode to master transmitter and enable I2C output + + write_reg32(kI2CModule, SW_RESET, kIICSwReset); + do { + write_reg32(kI2CModule, HDMIPHY_ID, PHY_I2C_ADDRESS); + } while (read_reg32(kI2CModule, HDMIPHY_ID) != PHY_I2C_ADDRESS); + + write_reg32(kI2CModule, IICINT, kIICIntAll); // Clear pending interrupts + write_reg32(kI2CModule, IICCON, (IICCONFIG_IICCON | kIICConAckGen)); + write_reg32(kI2CModule, FIFOCON, IICCONFIG_FIFOCON); + write_reg32(kI2CModule, IICBUSCON, IICCONFIG_IICBUSCON); + write_reg32(kI2CModule, TIMEOUT_CON, IICCONFIG_TIMEOUTCON); + write_reg32(kI2CModule, IICSTAT, (kIICStatMaster | kIICStatTx | kIICStatSOE)); + + return 0; +} + + +static int configure_video(struct video_link_data *data, uint32_t pixel_clock) +{ + debug(INIT,"starting to configure video\n"); + + if (hdmi_video_started) return 0; + + // Uncomment to show the timings we finally decide to use. + debug(ALWAYS, "configure_video with:\n"); + debug(ALWAYS, "mirror_mode: %d\n", data->mirror_mode); + debug(ALWAYS, "test_mode: 0x%08x\n", data->test_mode); + debug(ALWAYS, "color:\n"); + debug(ALWAYS, " depth: %u\n", data->color.depth); + debug(ALWAYS, " space: %u\n", data->color.space); + debug(ALWAYS, " range: %u\n", data->color.range); + debug(ALWAYS, " coefficient: %u\n", data->color.coefficient); + debug(ALWAYS, "timing:\n"); + debug(ALWAYS, " interlaced: %d\n", data->timing.interlaced); + { + int i; + for (i = 0; i < kDisplayAxisCount; ++i) { + debug(ALWAYS, " Axis %d:\n", i); + debug(ALWAYS, " total: %u\n", data->timing.axis[i].total); + debug(ALWAYS, " active: %u\n", data->timing.axis[i].active); + debug(ALWAYS, " sync_width: %u\n", data->timing.axis[i].sync_width); + debug(ALWAYS, " back_porch: %u\n", data->timing.axis[i].back_porch); + debug(ALWAYS, " front_porch: %u\n", data->timing.axis[i].front_porch); + debug(ALWAYS, " sync_rate: %u (%uHz)\n", + data->timing.axis[i].sync_rate, data->timing.axis[i].sync_rate >> 16); + debug(ALWAYS, " sync_polarity: %u\n", data->timing.axis[i].sync_polarity); + } + } + + init_video((data->mirror_mode ? false : true)); + + if ( configure_video_mode(data, pixel_clock) != 0 ) { + debug(ERROR,"failed configure_video_mode\n"); + goto exit; + } + + if ( configure_video_color(data) != 0 ) + goto exit; + + configure_video_bist(data); + + configure_video_mute(data, false); + + hdmi_video_started = true; + + debug(VIDEO, "finished configuring video\n"); + + return 0; + +exit: + debug(ERROR, "failed to configure video\n"); + hdmi_video_started = false; + + return -1; +} + +static void init_video(bool master) +{ + debug(INIT,"%s:nothing to do yet\n", __FUNCTION__); +} + +static HDMITXPHYConfigDepth phy_config_depth(uint32_t depth) +{ + HDMITXPHYConfigDepth depthIndex; + switch ( depth ) { + case 12: + depthIndex = kHDMITXPHYConfigDepth12; + break; + + case 10: + depthIndex = kHDMITXPHYConfigDepth10; + break; + + default: + depthIndex = kHDMITXPHYConfigDepth8; + break; + } + return depthIndex; +} + +const HDMITXPHYConfig * find_PHY_config(uint32_t pixelClockHz, uint32_t pixelClockMinHz, uint32_t pixelClockMaxHz, uint32_t colorDepth) +{ + const HDMITXPHYConfig * bestConfig = NULL; + const HDMITXPHYConfigDepth depthIndex = phy_config_depth(colorDepth); + + if ( hdmi_port_phy_cfg_table ) { + const AppleSamsungHDMITXPHYConfigTableEntry * table; + unsigned int rowCount; + uint32_t bestError; + + // Search for an entry with a matching pixel clock + // + // Note: The table must be sorted by pixel clock in ascending order. + // + table = (const AppleSamsungHDMITXPHYConfigTableEntry *)hdmi_port_phy_cfg_table; + rowCount = hdmi_port_phy_cfg_table_size / sizeof table[0]; + bestError = UINT32_MAX; + + for (unsigned int i = 0; i < rowCount; i++) { + uint32_t configPixelClockHz = table[i].pixelClockHz; + uint32_t error; + + debug(INFO,"pixelClockMaxHz %d pixel_clock %d configPixelClockHz %d\n", pixelClockMaxHz, pixelClockHz, configPixelClockHz); + if (configPixelClockHz < pixelClockMinHz) { + goto next; + } + if (configPixelClockHz > pixelClockMaxHz) { + goto exit; + } + + if (table[i].depth[depthIndex].invalid) { + goto next; + } + + if ( configPixelClockHz < pixelClockHz ) { + error = pixelClockHz - configPixelClockHz; + } else { + error = configPixelClockHz - pixelClockHz; + } + + if ( error < bestError ) { + bestError = error; + bestConfig = &table[i].depth[depthIndex].data; + } + + next: + continue; + } + } + +exit: + return bestConfig; +} + +static void configure_video_mute(struct video_link_data *data, bool mute) +{ + set_av_mute_enabled(mute); +} + +static int validate_video_color(const struct video_color_data * color) +{ + int ret = 0; + + if (color->depth < 8 || color->depth > 12) { + ret = -1; + debug(ERROR,"Color depth not supported\n"); + goto exit; + } + + + if (color->space == kDisplayColorSpacesYCbCr422) { + // It is invalid to have a depth other than 8 with YCbCr4:2:2 [see HDMI v1.3 section 6.5]. + if (color->depth != 8) { + ret = -1; + debug(ERROR,"YCbCr4:2:2 requires depth = 8 bits\n"); + goto exit; + } + } + +exit: + return ret; +} + +static int validate_video_timing(const struct video_timing_axis * h, const struct video_timing_axis * v) +{ + int ret = 0; + + if (h->total <= 0 || h->total > kHorizontalTotalLimit) { + ret = -1; + goto exit; + } + + if (v->total <= 0 && v->total > kVerticalTotalLimit) { + ret = -1; + goto exit; + } + + + if (h->active > kHorizontalActiveLimit) { + ret = -1; + goto exit; + } + + if (v->active > kVerticalActiveLimit) { + ret = -1; + goto exit; + } + + + if ((h->total < h->active) || ((h->total - h->active) > kHorizontalBlankLimit)) { + ret = -1; + goto exit; + } + + if ((v->total < v->active) || ((v->total - v->active) > kVerticalBlankLimit)) { + ret = -1; + goto exit; + } + +exit: + return ret; +} + +#define kVideoPixelClkTolleranceNumerator 5 +#define kVideoPixelClkTolleranceDenomiator 1000 + +static inline u_int32_t +ulmin(u_int32_t a, u_int32_t b) +{ + return (a < b ? a : b); +} + +uint32_t _pixelClockLimit = UINT32_MAX; + +static int validate_video_link(struct video_link_data * data, uint32_t pixel_clock, const HDMITXPHYConfig ** pPHYConfig) +{ + const struct video_timing_axis * h = &data->timing.axis[kDisplayAxisTypeHorizontal]; + const struct video_timing_axis * v = &data->timing.axis[kDisplayAxisTypeVertical]; + const struct video_color_data * color = &data->color; + const HDMITXPHYConfig * phyConfig = NULL; + uint32_t pixelClockToleranceHz, pixelClockMinHz, pixelClockMaxHz; + int64_t pixelClockToleranceFixed = pixel_clock; + int ret = 0; + + pixelClockToleranceFixed *= kVideoPixelClkTolleranceNumerator; + pixelClockToleranceFixed /= kVideoPixelClkTolleranceDenomiator; + pixelClockToleranceHz = (uint32_t) pixelClockToleranceFixed; + + // Uncomment to show the timings we finally decide to use. + debug(VIDEO,"Validating link\n"); + debug(VIDEO,"mirror_mode: %d\n", data->mirror_mode); + debug(VIDEO,"test_mode: 0x%08x\n", data->test_mode); + debug(VIDEO,"color:\n"); + debug(VIDEO," depth: %u\n", data->color.depth); + debug(VIDEO," space: %u\n", data->color.space); + debug(VIDEO," range: %u\n", data->color.range); + debug(VIDEO," coefficient: %u\n", data->color.coefficient); + debug(VIDEO,"timing:\n"); + debug(VIDEO," interlaced: %d\n", data->timing.interlaced); + { + int i; + for (i = 0; i < kDisplayAxisCount; ++i) { + debug(VIDEO," Axis %d:\n", i); + debug(VIDEO," total: %u\n", data->timing.axis[i].total); + debug(VIDEO," active: %u\n", data->timing.axis[i].active); + debug(VIDEO," sync_width: %u\n", data->timing.axis[i].sync_width); + debug(VIDEO," back_porch: %u\n", data->timing.axis[i].back_porch); + debug(VIDEO," front_porch: %u\n", data->timing.axis[i].front_porch); + debug(VIDEO," sync_rate: %u (%uHz)\n", + data->timing.axis[i].sync_rate, data->timing.axis[i].sync_rate >> 16); + debug(VIDEO," sync_polarity: %u\n", data->timing.axis[i].sync_polarity); + } + } + + // Interlaced video not supported + if (data->timing.interlaced) { + ret = -1; + debug(VIDEO,"interlaced mode not supported\n"); + goto exit; + } + + // Mirror mode is not supported + if (data->mirror_mode) { + ret = -1; + debug(VIDEO,"Mirror mode not supported\n"); + goto exit; + } + + // Verify that color mode is supported + ret = validate_video_color(color); + if (ret < 0) { + goto exit; + } + + // Calculate target pixel clock range, clamping max value to _pixelClockLimit + pixelClockMinHz = pixel_clock - pixelClockToleranceHz; + pixelClockMaxHz = ulmin(pixel_clock + pixelClockToleranceHz, _pixelClockLimit); + + // Verify that the target pixel clock is within the valid range + if (pixel_clock > _pixelClockLimit) { + ret = -1; + debug(VIDEO,"pixel clock value is too high, %lu\n", (unsigned long)pixel_clock); + goto exit; + } + + // Verify that there is a PHY configuration for the pixel clock + phyConfig = find_PHY_config(pixel_clock, pixelClockMinHz, pixelClockMaxHz, data->color.depth); + if (phyConfig == NULL) { + ret = -1; + debug(VIDEO,"No PHY configuration for required pixel clock: %lu\n", (unsigned long)pixel_clock); + goto exit; + } + + // Return the PHY configuration if requested + if ( pPHYConfig ) { + *pPHYConfig = phyConfig; + } + + // Verify that timing generator parameters are supported + ret = validate_video_timing(h, v); + if (ret < 0) { + debug(VIDEO,"Timing not supported\n"); + goto exit; + } + +exit: + debug(ERROR,"ret=0x%08x\n", ret); + + return ret; +} + +void set_horizontal_blanking(uint32_t value) +{ + // H_BLANK_0:1 + write_regs(kHDMIModule, HDMI_H_BLANK_0, value, 2); +} + +void set_vertical_blanking(uint32_t blanking, uint32_t total) +{ + // V1_BLANK_0:1 + write_regs(kHDMIModule, HDMI_V1_BLANK_0, blanking, 2); + + // V2_BLANK_0:1 + write_regs(kHDMIModule, HDMI_V2_BLANK_0, total, 2); +} + +void set_line_lengths(uint32_t h_line, uint32_t v_line) +{ + debug(VIDEO,"h_line %d, v_line %d\n", h_line, v_line); + // V_LINE_0:1 + write_regs(kHDMIModule, HDMI_V_LINE_0, v_line, 2); + + // H_LINE_0:1 + write_regs(kHDMIModule, HDMI_H_LINE_0, h_line, 2); +} + +void set_bottom_field_extents(uint32_t start, uint32_t end) +{ + // V_BLANK_F0_0:1 + write_regs(kHDMIModule, HDMI_V_BLANK_F0_0, start, 2); + + // V_BLANK_F1_0:1 + write_regs(kHDMIModule, HDMI_V_BLANK_F1_0, end, 2); +} + +void set_horizontal_sync_shape(bool active_high, uint32_t start, uint32_t end) +{ + // HSYNC_POL + write_reg(kHDMIModule, HDMI_HSYNC_POL, !active_high); + + // H_SYNC_START_0:1 + write_regs(kHDMIModule, HDMI_H_SYNC_START_0, start, 2); + + // H_SYNC_END_0:1 + write_regs(kHDMIModule, HDMI_H_SYNC_END_0, end, 2); +} + +void set_vertical_sync_shape(bool active_high, uint32_t vsync1_start, uint32_t vsync1_end, uint32_t vsync2_start, uint32_t vsync2_end) +{ + // VSYNC_POL + write_reg(kHDMIModule, HDMI_VSYNC_POL, !active_high); + + // V_SYNC_LINE_BEF_1_0:1 - top field vsync start + write_regs(kHDMIModule, HDMI_V_SYNC_LINE_BEF_1_0, vsync1_start, 2); + + // V_SYNC_LINE_BEF_2_0:1 - top field vsync end + write_regs(kHDMIModule, HDMI_V_SYNC_LINE_BEF_2_0, vsync1_end, 2); + + // V_SYNC_LINE_AFT_1_0:1 - bottom field vsync start + write_regs(kHDMIModule, HDMI_V_SYNC_LINE_AFT_1_0, vsync2_start, 2); + + // V_SYNC_LINE_AFT_2_0:1 - bottom field vsync end + write_regs(kHDMIModule, HDMI_V_SYNC_LINE_AFT_2_0, vsync2_end, 2); +} + +static void set_bottom_field_transition_point(uint32_t start, uint32_t end) +{ + // V_SYNC_LINE_AFT_PXL_1_0:1 + write_regs(kHDMIModule, HDMI_V_SYNC_LINE_AFT_PXL_1_0, start, 2); + + // V_SYNC_LINE_AFT_PXL_2_0:1 + write_regs(kHDMIModule, HDMI_V_SYNC_LINE_AFT_PXL_2_0, end, 2); +} + +static int configure_timing_generator(const struct video_link_data * data) +{ + const struct video_timing_axis * h = &data->timing.axis[kDisplayAxisTypeHorizontal]; + const struct video_timing_axis * v = &data->timing.axis[kDisplayAxisTypeVertical]; + + uint32_t h_blanking = h->total - h->active; + uint32_t v_blanking = v->total - v->active; + + uint32_t v_bot_start = v->total + v_blanking + 1; // interlaced only + + // Make "line 1" coincident with the first VSYNC, as in CEA formats + uint32_t vsync1_lineno = 1; + uint32_t vsync2_lineno = vsync1_lineno + v->total; // interlaced only + + // Configure Timing Generator related registers + + // TG_CMD + write_reg(kTGModule, TG_CMD, data->timing.interlaced ? TG_CMD_FIELD_EN : 0); + + // TG_CBGEN + // Pixel repititon is not supported + + // TG_H_FSZ_L:TG_H_FSZ_H + write_regs(kTGModule, TG_H_FSZ_L, h->total, 2); + + // TG_HACT_ST_L:TG_HACT_ST_H + write_regs(kTGModule, TG_HACT_ST_L, h_blanking, 2); + + // TG_HACT_SZ_L:TG_HACT_SZ_H + write_regs(kTGModule, TG_HACT_SZ_L, h->active, 2); + + // TG_V_FSZ_L:TG_V_FSZ_H + write_regs(kTGModule, TG_V_FSZ_L, v->total, 2); + + // TG_VSYNC_L:TG_VSYNC_H + write_regs(kTGModule, TG_VSYNC_L, vsync1_lineno, 2); + + // TG_VSYNC2_L:TG_VSYNC2_H (interlaced only) + write_regs(kTGModule, TG_VSYNC2_L, vsync2_lineno, 2); + + // TG_VACT_ST_L:TG_VACT_ST_H + write_regs(kTGModule, TG_VACT_ST_L, v_blanking, 2); + + // TG_VACT_SZ_L:TG_VACT_SZ_H + write_regs(kTGModule, TG_VACT_SZ_L, v->active, 2); + + // TG_FIELD_CHG_L:TG_FIELD_CHG_H (interlaced only) + write_regs(kTGModule, TG_FIELD_CHG_L, vsync2_lineno, 2); + + // TG_VACT_ST2_L:TG_VACT_ST2_H (interlaced only) + write_regs(kTGModule, TG_VACT_ST2_L, v_bot_start, 2); + + // Note: 3D (HDMI 1.4 TX only) not supported + + // TG_VSYNC_TOP_HDMI_L:TG_VSYNC_TOP_HDMI_H + write_regs(kTGModule, TG_VSYNC_TOP_HDMI_L, vsync1_lineno, 2); // same as TG_VSYNC_L:TG_VSYNC_H + + // TG_VSYNC_BOT_HDMI_L:TG_VSYNC_BOT_HDMI_H (interlaced only) + write_regs(kTGModule, TG_VSYNC_BOT_HDMI_L, vsync2_lineno, 2); // same as TG_VSYNC2_L:TG_VSYNC2_H + + // TG_FIELD_TOP_HDMI_L:TG_FIELD_TOP_HDMI_H + write_regs(kTGModule, TG_FIELD_TOP_HDMI_L, vsync1_lineno, 2); // same as TG_VSYNC_L:TG_VSYNC_H + + // TG_FIELD_BOT_HDMI_L:TG_FIELD_BOT_HDMI_H + write_regs(kTGModule, TG_FIELD_BOT_HDMI_L, vsync2_lineno, 2); // same as TG_VSYNC2_L:TG_VSYNC2_H + + // TG_HDMI_TPGEN + // Pixel repititon is not supported + + return 0; +} + +static int configure_video_format(struct video_link_data * data) +{ + const struct video_timing_axis * h = &data->timing.axis[kDisplayAxisTypeHorizontal]; + const struct video_timing_axis * v = &data->timing.axis[kDisplayAxisTypeVertical]; + + uint32_t h_blanking = h->total - h->active; + uint32_t v_blanking = v->total - v->active; + + uint32_t v_line = data->timing.interlaced ? (v->total * 2 + 1) : v->total; + uint32_t v_bot_start = v->total + v_blanking + 1; // interlaced only + + uint32_t hsync_start = h->front_porch - 2; // There is apparently an implicit +2 added to HSYNC_START (compare manual recommended values to CEA-861-D formats) + uint32_t hsync_end = hsync_start + h->sync_width; + + uint32_t vsync1_start = v->front_porch; + uint32_t vsync1_end = vsync1_start + v->sync_width; + + uint32_t vsync2_start = v->total + vsync1_start; // interlaced only + uint32_t vsync2_end = v->total + vsync1_end; // interlaced only + + // The +0.5 vertical lines offset, not included in vsync2_start/end + uint32_t vsync2_h_start = (h->total / 2) + h->front_porch; // interlaced only + uint32_t vsync2_h_end = vsync2_h_start; // interlaced only + uint64_t const64 = 1000; + + + // Calculate frame interval rounded (half up) to nearest millisecond + frame_interval_MS = (((const64 << 32) / v->sync_rate) + 0x8000) >> 16; + + // Configure registers related to video format + + set_horizontal_blanking(h_blanking); + + set_vertical_blanking(v_blanking, v->total); + + set_line_lengths(h->total, v_line); + + // INT_PRO_MODE + write_reg(kHDMIModule, HDMI_INT_PRO_MODE, data->timing.interlaced); + + set_bottom_field_extents(v_bot_start, v_line); // interlaced only + + set_horizontal_sync_shape(h->sync_polarity, hsync_start, hsync_end); + + set_vertical_sync_shape(v->sync_polarity, vsync1_start, vsync1_end, vsync2_start, vsync2_end); + + set_bottom_field_transition_point(vsync2_h_start, vsync2_h_end); + + // HDMI_CON_1[Pxl_rep_num] + // Pixel repititon is not supported + + return 0; +} + +static void set_mute_pixel(struct pixel pixel) +{ + // BLUE_SCREEN_[RGB]_0 - upper half of the least significant 8 bits + write_reg(kHDMIModule, HDMI_BLUE_SCREEN_R_0, (pixel.r >> 4) & 0x0F); + write_reg(kHDMIModule, HDMI_BLUE_SCREEN_G_0, (pixel.g >> 4) & 0x0F); + write_reg(kHDMIModule, HDMI_BLUE_SCREEN_B_0, (pixel.b >> 4) & 0x0F); + + // BLUE_SCREEN_[RGB]_1 - the most significant 8 bits + write_reg(kHDMIModule, HDMI_BLUE_SCREEN_R_1, pixel.r >> 8); + write_reg(kHDMIModule, HDMI_BLUE_SCREEN_G_1, pixel.g >> 8); + write_reg(kHDMIModule, HDMI_BLUE_SCREEN_B_1, pixel.b >> 8); +} + +static void set_color_space(int space) +{ + // Enable or disable YCbCr4:2:2 mode (RGB4:4:4/YCbCr4:4:4 are handled identically) + set_bits_in_reg(kHDMIModule, HDMI_CON_0, 0, HDMI_CON_0_YCBCR422_SEL, space == kDisplayColorSpacesYCbCr422 ? HDMI_CON_0_YCBCR422_SEL : 0); +} + +static int configure_video_pattern(const struct video_link_data * data) +{ + // enable video pattern generation + if ( data->test_mode ) { + or_reg(kHDMIModule, HDMI_VIDEO_PATTERN_GEN, HDMI_VIDEO_PATTERN_GEN_PATTERN_ENABLE); + debug(VIDEO,"Video pattern generation enabled.\n"); + } else { + and_reg(kHDMIModule, HDMI_VIDEO_PATTERN_GEN, ~(HDMI_VIDEO_PATTERN_GEN_PATTERN_ENABLE)); + } + + return 0; +} + +static int set_tx_output_mode(int mode) +{ + uint32_t dvi_mask = HDMI_CON_2_VID_PERIOD_EN | HDMI_CON_2_DVI_BAND_EN; + uint8_t transtaled_mode = (mode == kHDMI_tx_mode_HDMI) ? HDMI_MODE_SEL_MODE_HDMI : HDMI_MODE_SEL_MODE_DVI; + + debug(VIDEO,"%s %d:, Mode %s\n", __FUNCTION__, __LINE__, (mode == kHDMI_tx_mode_HDMI) ? "HDMI" : "DVI"); + // MODE_SEL[1:0] = mode + set_bits_in_reg(kHDMIModule, HDMI_MODE_SEL, HDMI_MODE_SEL_MODE_SHIFT, HDMI_MODE_SEL_MODE_MASK, transtaled_mode); + + // Configure video preamble and guard band + // HDMI_CON_2[Vid_Period_En] = 1 if DVI mode, 0 otherwise + // HDMI_CON_2[Dvi_Band_En] = 1 if DVI mode, 0 otherwise + set_bits_in_reg(kHDMIModule, HDMI_CON_2, 0, dvi_mask, (mode == kHDMI_tx_mode_DVI) ? dvi_mask : 0); + + return 0; +} + +static inline int set_PHY_config_done(bool done) +{ + write_phy_config_reg(kPHYConfigRegModeSet, done ? PHY_CONFIG_MODE_SET_DONE : PHY_CONFIG_MODE_SET_IN_PROGRESS); + return 0; +} + +static int configure_PHY(const HDMITXPHYConfig * config) +{ + uint8_t buf[kPHYConfigRegCount]; + int ret = 0; + int reg; + + // Sanity check (if this fails, it is a programming error) + if (sizeof (*config) != (sizeof (buf) - 2)) { + ret = -1; + goto exit; + } + + // Copy config into data buffer; initialize first & last bytes from registers + buf[kPHYConfigReg00] = read_phy_reg(kPHYConfigReg00); + buf[kPHYConfigReg07] = read_phy_reg(kPHYConfigReg07); + memcpy((uint8_t *)buf + 1, config, sizeof (*config)); + + debug(VIDEO,"PHY_STATUS=0x%08x\n", read_reg(kCtrlModule, CTRL_PHY_STATUS_0)); + + // Configure the PHY + ret = set_PHY_config_done(false); + if (ret < 0) { + debug(ERROR,"set_PHY_config_done: ret %d\n", ret); + goto exit; + } + + for (reg = kPHYConfigReg00; reg != kPHYConfigRegCount; reg++) { + ret = write_phy_config_reg(reg, buf[reg]); + if (ret < 0) { + debug(ERROR,"write_phy_config_reg: ret %d\n", ret); + goto exit; + } + } + + ret = set_PHY_config_done(true); + if (ret < 0) { + debug(ERROR,"set_PHY_config_done: ret %d\n", ret); + goto exit; + } + + debug(VIDEO,"PHY_STATUS=0x%08x\n", read_reg(kCtrlModule, CTRL_PHY_STATUS_0)); + +exit: + return ret; +} +static int wait_for_PHY_ready() +{ + //TODO + while (get_is_PHY_ready() == false) { + task_sleep(kPHYReadyPollIntervalMS); + } + + return 0; +} + +static int set_timing_generator_enabled(bool enabled) +{ + // TG_CMD[TG_EN] = enabled + set_bits_in_reg(kTGModule, TG_CMD, 0, TG_CMD_TG_EN, enabled ? TG_CMD_TG_EN : 0); + + return 0; +} + +static int configure_video_color(const struct video_link_data * data) +{ + static const struct pixel kBlackPixelRGB = + { + .r = 0, + .g = 0, + .b = 0 + }; + + static const struct pixel kBlackPixelYCbCr = + { + .g = 16 << 8, // Y + .b = 128 << 8, // Cb + .r = 128 << 8 // Cr + }; + + const struct video_color_data * color = &data->color; + uint32_t limit_mode; + uint32_t deep_color_mode; + + // Configure the color space + set_color_space(color->space); + + // Configure "blue screen" (actually black, not blue) pixel value + set_mute_pixel((color->space == kDisplayColorSpacesRGB) ? kBlackPixelRGB : kBlackPixelYCbCr); + + // Configure Color space and Pixel limitation + // + // Note: This allows a full-range YCbCr configuration, though HDMI v1.3 + // section 6.6 says "YCBCR components shall always be Limited Range" + // + if ( color->range == kDisplayColorDynamicRangeFull ) { + limit_mode = HDMI_CON_1_PXL_LMT_CTRL_BYPASS_MODE; + } else { + write_reg(kHDMIModule, HDMI_YMIN, kVideoColorLimitedRangeYMin); + write_reg(kHDMIModule, HDMI_YMAX, kVideoColorLimitedRangeYMax); + + if ( color->space == kDisplayColorSpacesRGB ) { + limit_mode = HDMI_CON_1_PXL_LMT_CTRL_RGB_MODE; + } else { + limit_mode = HDMI_CON_1_PXL_LMT_CTRL_YCBCR_MODE; + + write_reg(kHDMIModule, HDMI_CMIN, kVideoColorLimitedRangeCMin); + write_reg(kHDMIModule, HDMI_CMAX, kVideoColorLimitedRangeCMax); + } + } + set_bits_in_reg(kHDMIModule, HDMI_CON_1, HDMI_CON_1_PXL_LMT_CTRL_SHIFT, HDMI_CON_1_PXL_LMT_CTRL_MASK, limit_mode); + + // Configure Color depth + switch ( color->depth ) { + case 12: + deep_color_mode = HDMI_DC_CONTROL_DEEP_COLOR_MODE_12_BPC; + break; + + case 10: + deep_color_mode = HDMI_DC_CONTROL_DEEP_COLOR_MODE_10_BPC; + break; + + default: + deep_color_mode = HDMI_DC_CONTROL_DEEP_COLOR_MODE_8_BPC; + break; + } + set_bits_in_reg(kHDMIModule, HDMI_DC_CONTROL, HDMI_DC_CONTROL_DEEP_COLOR_MODE_SHIFT, HDMI_DC_CONTROL_DEEP_COLOR_MODE_MASK, deep_color_mode); + + return 0; +} + +static int prepare_video_link(struct video_link_data *data, uint32_t pixel_clock) +{ + const HDMITXPHYConfig * phyConfig; + int tx_mode = kHDMI_tx_mode_HDMI; + int ret; + + ret = validate_video_link(data, pixel_clock, &phyConfig); + require_noerr(ret, exit); + + // Use DVI mode if downstream port type is not HDMI + tx_mode = get_edid_downstream_type(); + + ret = configure_video_format(data); + require_noerr(ret, exit); + + ret = configure_timing_generator(data); + require_noerr_action(ret, exit, debug(ERROR,"configure_timing_generator: ret %d\n", ret)); + + ret = configure_video_color(data); + require_noerr_action(ret, exit, debug(ERROR,"configure_timing_generator: ret %d\n", ret)); + + ret = configure_video_pattern(data); + require_noerr_action(ret, exit, debug(ERROR,"configure_video_pattern: ret %d\n", ret)); + + ret = set_tx_output_mode(tx_mode); + require_noerr_action(ret, exit, debug(ERROR,"set_tx_output_mode: ret %d\n", ret)); + + // Note: PHY configuration includes enabling TMDS power. + ret = configure_PHY(phyConfig); + require_noerr_action(ret, exit, debug(ERROR,"configure_PHY: ret %d\n", ret)); + + ret = wait_for_PHY_ready(); + require_noerr_action(ret, exit, debug(ERROR,"wait_for_PHY_ready: ret %d\n", ret)); + + set_TMDS_power_enabled(false); + + // Enable timing generator + ret = set_timing_generator_enabled(true); + require_noerr_action(ret, exit, debug(ERROR,"set_timing_generator_enabled: ret %d\n", ret)); + + return 0; +exit: + debug(ERROR,"error\n"); + return -1; +} + + +static void start_info_frame(struct display_infoframe *infoFrame) +{ + // Configure the InfoFrame header, if needed. + uint8_t header[] = {infoFrame->type, infoFrame->version, infoFrame->length} ; + write_regs_with_data(kHDMIModule, HDMI_AVI_HEADER0, header, sizeof header); + // Set the InfoFrame checksum + write_reg(kHDMIModule, HDMI_AVI_CHECK_SUM, infoFrame->checksum); + // Set the InfoFrame data + write_regs_with_data(kHDMIModule, HDMI_AVI_BYTE01, infoFrame->data, infoFrame->length); + // Configure InfoFrame to be sent at every VSYNC + set_bits_in_reg(kHDMIModule, HDMI_AVI_CON, HDMI_PKT_CON_PKT_TX_CON_SHIFT, HDMI_PKT_CON_PKT_TX_CON_MASK, HDMI_PKT_CON_PKT_TX_CON_SEND_ALWAYS); + +} + +void stop_info_frame(struct display_infoframe * infoFrame) +{ + // Disable transmission of the InfoFrame + set_bits_in_reg(kHDMIModule, HDMI_AVI_CON, HDMI_PKT_CON_PKT_TX_CON_SHIFT, HDMI_PKT_CON_PKT_TX_CON_MASK, HDMI_PKT_CON_PKT_TX_CON_DISABLED); +} + + +static int get_tx_output_mode() +{ + uint32_t reg; + int mode; + + reg = get_bits_in_reg(kHDMIModule, HDMI_MODE_SEL, HDMI_MODE_SEL_MODE_SHIFT, HDMI_MODE_SEL_MODE_MASK); + + mode = reg == HDMI_MODE_SEL_MODE_HDMI ? kHDMI_tx_mode_HDMI : kHDMI_tx_mode_DVI; + debug(VIDEO,"%s %d:, Mode %s\n", __FUNCTION__, __LINE__, (mode == kHDMI_tx_mode_HDMI) ? "HDMI" : "DVI"); + + return mode; +} + +static int start_general_control_packet(const struct video_link_data * data) +{ + const struct video_color_data * color = &data->color; + uint32_t gcp_cd; + bool setSupportsDeepColor = false; + + // Clear GCP data registers + write_regs(kHDMIModule, HDMI_GCP_BYTE1, (uint32_t)0, 3); + + // Note: HDMI v1.3, section 6.5.3 says: + // + // Sources shall only send GCPs with non-zero CD to Sinks that indicate + // support for Deep Color... + // + // Once a Source sends a GCP with non-zero CD to a sink, it should continue + // sending GCPs with non-zero CD at least once per video field even if + // reverting to 24-bit color, as long as the Sink continues to support + // Deep Color. + + // Set color depth (CD) field of General Control Packet + switch ( color->depth ) { + case 12: + gcp_cd = GCP_SB1_CD_36_BPP; + setSupportsDeepColor = true; + break; + + case 10: + gcp_cd = GCP_SB1_CD_30_BPP; + setSupportsDeepColor = true; + break; + + default: + gcp_cd = GCP_SB1_CD_24_BPP; + break; + } + // Set Color Depth + set_bits_in_reg(kHDMIModule, HDMI_GCP_BYTE2, GCP_SB1_CD_SHIFT, GCP_SB1_CD_MASK, + setSupportsDeepColor ? gcp_cd : GCP_SB1_CD_NONE); + + // Set Transmission Frequency + // Always set both VSYNC enables + set_bits_in_reg(kHDMIModule, HDMI_GCP_CON, HDMI_GCP_CON_VSYNC_SHIFT, HDMI_GCP_CON_VSYNC_MASK, HDMI_GCP_CON_VSYNC_BOTH_FIELDS); + + // Configure GCP to be sent at every VSYNC + // GCP_CON[GCP_CON] = (every VSYNC) + set_bits_in_reg(kHDMIModule, HDMI_GCP_CON, HDMI_PKT_CON_PKT_TX_CON_SHIFT, HDMI_PKT_CON_PKT_TX_CON_MASK, HDMI_PKT_CON_PKT_TX_CON_SEND_ALWAYS); + + return 0; +} + +void stop_general_control_packet() +{ + set_bits_in_reg(kHDMIModule, HDMI_GCP_CON, HDMI_PKT_CON_PKT_TX_CON_SHIFT, HDMI_PKT_CON_PKT_TX_CON_MASK, HDMI_PKT_CON_PKT_TX_CON_DISABLED); + + // Clear GCP data registers + write_regs(kHDMIModule, HDMI_GCP_BYTE1, (uint32_t)0, 3); +} + +void set_av_mute_enabled(bool enabled) +{ + set_bits_in_reg(kHDMIModule, HDMI_GCP_BYTE1, 0, GCP_SB0_CLR_AVMUTE|GCP_SB0_SET_AVMUTE, enabled ? GCP_SB0_SET_AVMUTE : GCP_SB0_CLR_AVMUTE); + + // Allow time for updated GCP to be transmitted + task_sleep(frame_interval_MS + 1); + + debug(VIDEO,"AV MUTE %s after %u ms\n", enabled ? "enabled" : "disabled", (unsigned int)(frame_interval_MS + 1)); +} + + +static int start_video_link(struct video_link_data *data) +{ + int tx_mode = get_tx_output_mode(); + int ret; + + if ( tx_mode != kHDMI_tx_mode_DVI ) { + + // start the AVI InfoFrame + start_info_frame(&aviInfoFrame); + + // start the general control packet (GCP) + ret = start_general_control_packet(data); + require_noerr(ret, exit); + + // Enable Set_AVMUTE before enabling HDMI TX output + set_av_mute_enabled(true); + } + + // Enable HDMI core output (to PHY) + ret = set_tx_output_enabled(true); + require_noerr(ret, exit); + + task_sleep(kTMDSMinimumPowerOffIntervalMS); + + set_TMDS_power_enabled(true); + + ret = wait_for_PHY_ready(); + require_noerr(ret, exit); + + if ( tx_mode != kHDMI_tx_mode_DVI ) { + // Allow time for video to stabilize before unmute + task_sleep(kVideoStabilizationIntervalMS); + + // Send Clear_AVMUTE + set_av_mute_enabled(false); + } + + debug(VIDEO,"Finished Configuring Video\n"); + + _current_video_link = *data; + +exit: + return ret; +} + + +static int complete_video_link() +{ + int ret; + + // Disable timing generator + ret = set_timing_generator_enabled(false); + require_noerr(ret, exit); + + // power down HDMI PHY, keeping HPD enabled + power_down_phy(false); + + // Reset TX mode + ret = set_tx_output_mode(kHDMI_tx_mode_None); + require_noerr(ret, exit); + +exit: + return ret; +} + +static int stop_video_link() +{ + int tx_mode = get_tx_output_mode(); + int ret = 0; + + if ( tx_mode != kHDMI_tx_mode_DVI ) { + // Enable AVMUTE + set_av_mute_enabled(true); + } + + bzero(&_current_video_link, sizeof(_current_video_link)); + + // Disable PHY TMDS power (see POWER DOWN SEQUENCE in HDMI TX V1.4 manual) + set_TMDS_power_enabled(false); + + task_sleep(kTMDSMinimumPowerOffIntervalMS); + + if ( tx_mode != kHDMI_tx_mode_DVI ) { + // Clear TX internal AVMUTE state + set_av_mute_enabled(false); + } + + ret = set_tx_output_enabled(false); + require_noerr_action(ret, exit, debug(ERROR,"for set_tx_output_enabled: ret %d\n", ret)); + + if ( tx_mode != kHDMI_tx_mode_DVI ) { + struct display_infoframe local_aviInfoFrame; // dummy + + // stop the general control packet (GCP) + stop_general_control_packet(); + + // Stop info frame + stop_info_frame(&local_aviInfoFrame); + } + + +exit: + return ret; +} + +static int set_tx_output_enabled(bool enabled) +{ + // HDMI_CON_0[SYSTEM_EN] = enabled + set_bits_in_reg(kHDMIModule, HDMI_CON_0, 0, HDMI_CON_0_SYSTEM_EN, enabled ? HDMI_CON_0_SYSTEM_EN : 0); + + return 0; +} + +static int configure_video_mode(struct video_link_data *data, uint32_t pixel_clock) +{ + int ret; + + ret = prepare_video_link(data, pixel_clock); + if (ret < 0) { + debug(ERROR,"failed to prepare_video_link\n"); + return -1; + } + ret = start_video_link(data); + if (ret < 0) { + debug(ERROR,"failed to start_video_link\n"); + return -1; + } + + return 0; +} + +static void configure_video_bist(struct video_link_data *data) +{ + // enable bist mode + if ( data->test_mode ) { + or_reg(kHDMIModule, HDMI_VIDEO_PATTERN_GEN, HDMI_VIDEO_PATTERN_GEN_PATTERN_ENABLE); + debug(VIDEO, "Finished Video BIST\n"); + } else { + and_reg(kHDMIModule, HDMI_VIDEO_PATTERN_GEN, ~(HDMI_VIDEO_PATTERN_GEN_PATTERN_ENABLE)); + } +} + +#define HDMI_REG_OFFSET(size, m, o) \ + *(volatile size *)(__base_address +_registers[m] + o) + +static uint8_t read_reg(uint8_t module, uint32_t offset) +{ + uint8_t val; + uint32_t addr; + + addr = __base_address + _registers[module] + offset; + val = HDMI_REG_OFFSET(uint8_t, module, offset); + debug(REG, "module=%d reg=0x%08x addr=0x%08x value=0x%08x\n", module, offset, addr, val); + return(val); +} + +static uint32_t read_reg32(uint8_t module, u_int32_t offset) +{ + uint32_t val; + uint32_t addr; + + addr = __base_address + _registers[module] + offset; + val = HDMI_REG_OFFSET(uint32_t, module, offset); + debug(REG,"module=%d addr=0x%08x reg=0x%08x value=0x%08x\n", module, addr, offset, val); + return(val); +} + +static void write_reg(uint8_t module, uint32_t offset, uint8_t value) +{ + uint32_t addr; + addr = __base_address + _registers[module] + offset; + HDMI_REG_OFFSET(uint8_t, module, offset) = value; + debug(REG,"module=%d reg=0x%08x addr=0x%08x value=0x%08x\n", module, offset, addr, value); +} + +static void write_reg32(uint8_t module, u_int32_t offset, uint32_t value) +{ + uint32_t addr; + addr = __base_address + _registers[module] + offset; + HDMI_REG_OFFSET(uint32_t, module, offset) = value; + debug(REG,"module=%d reg=0x%08x addr=0x%08x value=0x%08x\n", module, offset, addr, value); +} + +static void and_reg(uint8_t module, uint32_t offset, uint8_t value) +{ + uint32_t addr; + uint8_t reg; + addr = __base_address + _registers[module] + offset; + reg = read_reg(module, offset); + reg &= value; + write_reg(module, offset, reg); +} + +static void or_reg(uint8_t module, uint32_t offset, uint8_t value) +{ + uint32_t addr; + uint8_t reg; + addr = __base_address + _registers[module] + offset; + reg = read_reg(module, offset); + reg |= value; + write_reg(module, offset, reg); +} + +static void set_bits_in_reg(uint8_t module, uint32_t offset, uint8_t pos, uint8_t mask, uint8_t value) +{ + uint8_t set = read_reg(module, offset); + + set &= ~mask; + set |= (value << pos); + + write_reg(module, offset, set); +} + +static uint32_t get_bits_in_reg(uint8_t module, uint32_t reg, uint32_t pos, uint32_t mask) +{ + return (read_reg(module, reg) & mask) >> pos; +} +static uint8_t read_phy_reg(uint8_t reg) +{ + uint32_t Register; + uint8_t data; + uint8_t offset; + uint8_t shift; + + + offset = reg / 4; + shift = reg % 4; + + Register = *(volatile uint32_t *)((uintptr_t)_phyConfigRegs[offset]); + + //Now normalize its value + data = Register >> shift; + + debug(REG, "read_phy_reg: hdmiphycon%x := 0x%08x addr 0x%08x\n", offset, data, _phyConfigRegs[offset]); + + return data; +} + +#define HDMI_IO_RETRIES 20 +bool get_is_PHY_write_in_progress(void) +{ + uint32_t status; + int i; + + for (i = 0; i < HDMI_IO_RETRIES; i++) { + task_sleep(1); //MS + status = read_reg(kI2CModule, HDMIPHYCON_STAT); + if (!(status & HDMIPHYCON_STAT_IN_PROGRESS)) + break; + debug(REG, "Retry: %d HDMIPHYCON_STAT 0x%08x\n", i, status); + + } + + return (status & HDMIPHYCON_STAT_IN_PROGRESS); +} + +#define HDMI_IO_TIMEOUT_US (10 * 1000) + +static int wait_for_PHY_write_completion() +{ + return (get_is_PHY_write_in_progress() ? -1 : 0); +} + +int write_phy_reg(uint32_t reg, const uint8_t data) +{ + int ret = 0; + uint8_t offset; + uint8_t shift; + + require_action((reg < PHY_CONFIG_REG_COUNT), exit, ret = -1); + + require_action(!get_is_PHY_write_in_progress(), exit, ret = -1); + + if (reg == kPHYConfigRegModeSet) { + offset = kPHYConfigRegModeSet; + shift = 0; + } else { + offset = reg / 4; + shift = (reg % 4) * 8; + } + + //Put it in position + *(volatile uint32_t *)((uintptr_t)_phyConfigRegs[offset]) = ((*(volatile uint32_t *)((uintptr_t)_phyConfigRegs[offset])) & ~(0xFF << shift)) | (data << shift); + + if (!bypass_wait && wait_for_PHY_write_completion()) { + debug(INT, "%s %d: done waiting for stop event\n", __FUNCTION__, __LINE__); + } + debug(REG, "%s: reg 0x%08x := 0x%08x\n", __FUNCTION__, reg, *(volatile uint32_t *)((uintptr_t)_phyConfigRegs[offset])); + +exit: + return ret; +} + +static int write_phy_config_reg(PHYConfigReg reg, uint32_t data) +{ + int ret = 0; + uint32_t Register; + + if (get_is_PHY_write_in_progress()) { + debug(ERROR, "%s: Failed cuz write is in progress\n", __FUNCTION__); + ret = -1; + goto exit; + } + uint8_t offset; + uint8_t shift; + + offset = reg / 4; + shift = (reg % 4) * 8; + + //Put it in position + Register = *(volatile uint32_t *)((uintptr_t)_phyConfigRegs[offset]); + Register &= ~(0xFF << shift); + Register |= (data << shift); + + *(volatile uint32_t *)((uintptr_t)_phyConfigRegs[offset]) = Register; + + debug(REG, "HDMIPHYCON%u := 0x%08x\n", offset, Register); + debug(REG, "reg 0x%08x addr 0x%p := 0x%08x\n", reg, (volatile uint32_t *)((uintptr_t)_phyConfigRegs[offset]), Register); + + if (wait_for_PHY_write_completion()) { + debug(REG, "%s %d: done waiting for stop event\n", __FUNCTION__, __LINE__); + } + +exit: + return ret; +} + +static void and_phy_reg(uint32_t offset, uint8_t data) +{ + uint8_t value; + + value = read_phy_reg(offset); + value &= data; + write_phy_reg(offset, value); +} + +static void or_phy_reg(uint32_t offset, uint8_t data) +{ + uint8_t value; + + value = read_phy_reg(offset); + value |= data; + write_phy_reg(offset, value); +} + +void write_regs_with_data(uint8_t module, uint32_t basereg, uint8_t * data, unsigned int length) +{ + for (unsigned int i = 0; i < length; i++) { + write_reg(module, basereg + (4 * i), data[i]); + } +} + +void write_regs(uint8_t module, uint32_t basereg, uint32_t value, unsigned int length) +{ + for (unsigned int i = 0; i < length; i++) { + write_reg(module, basereg + (4 * i), value & 0xff); + value >>= 8; + } +} diff --git a/drivers/samsung/hdmi8947/hdmi.h b/drivers/samsung/hdmi8947/hdmi.h new file mode 100644 index 0000000..ffd76cf --- /dev/null +++ b/drivers/samsung/hdmi8947/hdmi.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef HDMI_H +#define HDMI_H 1 +typedef enum { + kPHYConfigReg00, //HDMIPHYCON0 + kPHYConfigReg01, //HDMIPHYCON0 + kPHYConfigReg02, //HDMIPHYCON0 + kPHYConfigReg03, //HDMIPHYCON0 + kPHYConfigReg04, //HDMIPHYCON1 + kPHYConfigReg05, //HDMIPHYCON1 + kPHYConfigReg06, //HDMIPHYCON1 + kPHYConfigReg07, //HDMIPHYCON1 + kPHYConfigReg08, //HDMIPHYCON2 + kPHYConfigReg09, //HDMIPHYCON2 + kPHYConfigReg0a, //HDMIPHYCON2 + kPHYConfigReg0b, //HDMIPHYCON2 + kPHYConfigReg0c, //HDMIPHYCON3 + kPHYConfigReg0d, //HDMIPHYCON3 + kPHYConfigReg0e, //HDMIPHYCON3 + kPHYConfigReg0f, //HDMIPHYCON3 + kPHYConfigReg10, //HDMIPHYCON4 + kPHYConfigReg11, //HDMIPHYCON4 + kPHYConfigReg12, //HDMIPHYCON4 + kPHYConfigReg13, //HDMIPHYCON4 + kPHYConfigReg14, //HDMIPHYCON5 + kPHYConfigReg15, //HDMIPHYCON5 + kPHYConfigReg16, //HDMIPHYCON5 + kPHYConfigReg17, //HDMIPHYCON5 + kPHYConfigReg18, //HDMIPHYCON6 + kPHYConfigReg19, //HDMIPHYCON6 + kPHYConfigReg1a, //HDMIPHYCON6 + kPHYConfigReg1b, //HDMIPHYCON6 + kPHYConfigReg1c, //HDMIPHYCON7 + kPHYConfigReg1d, //HDMIPHYCON7 + kPHYConfigReg1e, //HDMIPHYCON7 + kPHYConfigRegRSVD, //HDMIPHYCON7 + kPHYConfigRegCount, // count excludes the mode set control register + kPHYConfigRegModeSet = 0x1f, //HDMIPHYCON8 +} PHYConfigReg; + +typedef uint8_t HDMITXPHYConfig[30]; + +typedef enum HDMITXPHYConfigDepth { + kHDMITXPHYConfigDepth8, + kHDMITXPHYConfigDepth10, + kHDMITXPHYConfigDepth12, + kHDMITXPHYConfigDepthCount +} HDMITXPHYConfigDepth; + +typedef struct { + HDMITXPHYConfig data; + uint8_t pad; // Align to multiple of 4 bytes for device tree alignment + uint8_t invalid; // If nonzero, entry is invalid +} HDMITXPHYConfigDepthTableEntry; + +typedef struct HDMITXPHYConfigTableEntry { + uint32_t pixelClockHz; // target pixel clock + HDMITXPHYConfigDepthTableEntry depth[kHDMITXPHYConfigDepthCount]; +} AppleSamsungHDMITXPHYConfigTableEntry; +#endif diff --git a/drivers/samsung/hdmi8947/hdmi_static_config.c b/drivers/samsung/hdmi8947/hdmi_static_config.c new file mode 100644 index 0000000..4b9e0ad --- /dev/null +++ b/drivers/samsung/hdmi8947/hdmi_static_config.c @@ -0,0 +1,919 @@ +#include +#include "hdmi.h" + +// HDMI PHY configuration table - auto-generated by deviceTreePHYConfigGenerator - do not edit +// deviceTreePHYConfigGenerator -i hdmi_static_config -V 1.4 --depth-limit=8 --data-amplitude=0xf --clock-amplitude=16 --slew-rate-control=0 -C --tmds-min=148.5 --data-amplitude=0x1d +AppleSamsungHDMITXPHYConfigTableEntry hdmi_static_config[101] = { + // 0: 23.750 MHz + { + 0x016a6570, // 23750000 Hz + { + { { 0xd1, 0x28, 0x71, 0x40, 0x30, 0xd8, 0x00, 0x80, 0x80, 0xee, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x03, 0x25, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 1: 23.856 MHz + { + 0x016c0380, // 23856000 Hz + { + { { 0xd1, 0x28, 0x71, 0x40, 0x4b, 0xdc, 0x00, 0x80, 0x80, 0xef, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x02, 0x25, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 2: 25.175 MHz + { + 0x018023d8, // 25175000 Hz + { + { { 0xd1, 0x2a, 0x72, 0x40, 0x30, 0xfc, 0x04, 0x83, 0xa0, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 3: 25.200 MHz + { + 0x01808580, // 25200000 Hz + { + { { 0x51, 0x2a, 0x70, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 4: 26.976 MHz + { + 0x019b9d20, // 26975520 Hz + { + { { 0xd4, 0x87, 0x56, 0x40, 0x60, 0xd1, 0x10, 0x09, 0xa0, 0xca, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 5: 27.000 MHz + { + 0x019bfcc0, // 27000000 Hz + { + { { 0x51, 0x2d, 0x70, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 6: 27.027 MHz + { + 0x019c6638, // 27027000 Hz + { + { { 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x09, 0x08, 0x83, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 7: 29.201 MHz + { + 0x01bd9268, // 29201000 Hz + { + { { 0xd4, 0xc3, 0x74, 0x40, 0x4b, 0xcf, 0x20, 0x1d, 0xa0, 0x24, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xd2, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 8: 29.250 MHz + { + 0x01be51d0, // 29250000 Hz + { + { { 0xd1, 0x31, 0x74, 0x40, 0x20, 0xf0, 0x08, 0x87, 0xa0, 0x25, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xd2, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 9: 30.722 MHz + { + 0x01d4c7d0, // 30722000 Hz + { + { { 0xd1, 0x33, 0x74, 0x40, 0x4b, 0x3d, 0x08, 0x45, 0xa0, 0x33, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc8, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 10: 30.750 MHz + { + 0x01d53530, // 30750000 Hz + { + { { 0xd1, 0x33, 0x74, 0x40, 0x20, 0x10, 0x08, 0x85, 0xa0, 0x34, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc8, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 11: 31.500 MHz + { + 0x01e0a6e0, // 31500000 Hz + { + { { 0x52, 0x69, 0x70, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x3b, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc3, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 12: 33.750 MHz + { + 0x0202fbf0, // 33750000 Hz + { + { { 0xd1, 0x38, 0x74, 0x40, 0x20, 0x10, 0x00, 0x80, 0x80, 0x52, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb6, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 13: 35.000 MHz + { + 0x02160ec0, // 35000000 Hz + { + { { 0xd1, 0x3a, 0x75, 0x40, 0x30, 0x20, 0x04, 0x83, 0xa0, 0x5e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb0, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 14: 35.500 MHz + { + 0x021dafe0, // 35500000 Hz + { + { { 0xd1, 0x3b, 0x75, 0x40, 0x30, 0x10, 0x08, 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xad, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 15: 35.714 MHz + { + 0x0220f3d0, // 35714000 Hz + { + { { 0xd2, 0x77, 0x75, 0x40, 0x4b, 0x07, 0x10, 0x49, 0xa0, 0x65, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xac, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 16: 36.000 MHz + { + 0x02255100, // 36000000 Hz + { + { { 0x51, 0x3c, 0x70, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x68, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 17: 38.216 MHz + { + 0x02472140, // 38216000 Hz + { + { { 0xd1, 0x30, 0x52, 0x40, 0x64, 0xd2, 0x00, 0x80, 0x80, 0x1f, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa1, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 18: 38.250 MHz + { + 0x0247a610, // 38250000 Hz + { + { { 0xd1, 0x30, 0x52, 0x40, 0x20, 0xf4, 0x00, 0x80, 0x80, 0x1f, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa1, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 19: 40.000 MHz + { + 0x02625a00, // 40000000 Hz + { + { { 0x51, 0x32, 0x50, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 20: 48.906 MHz + { + 0x02ea3f10, // 48906000 Hz + { + { { 0xd1, 0x3d, 0x55, 0x40, 0x64, 0x35, 0x08, 0x43, 0xa0, 0x6f, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xfb, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 21: 49.000 MHz + { + 0x02ebae40, // 49000000 Hz + { + { { 0xd1, 0x3d, 0x55, 0x40, 0x20, 0x10, 0x08, 0x83, 0xa0, 0x70, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xfb, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 22: 49.500 MHz + { + 0x02f34f60, // 49500000 Hz + { + { { 0xd1, 0x3e, 0x55, 0x40, 0x20, 0xf8, 0x04, 0x81, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf8, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 23: 50.000 MHz + { + 0x02faf080, // 50000000 Hz + { + { { 0x52, 0x7d, 0x50, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x77, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf6, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 24: 53.951 MHz + { + 0x03373a40, // 53951040 Hz + { + { { 0xd1, 0x2d, 0x35, 0x40, 0x78, 0xf3, 0x02, 0x81, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe4, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 25: 54.000 MHz + { + 0x0337f980, // 54000000 Hz + { + { { 0x51, 0x2d, 0x30, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe4, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 26: 54.054 MHz + { + 0x0338cc70, // 54054000 Hz + { + { { 0xd1, 0x2d, 0x32, 0x40, 0x64, 0x09, 0x08, 0x83, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe3, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 27: 56.250 MHz + { + 0x035a4e90, // 56250000 Hz + { + { { 0xd1, 0x2f, 0x32, 0x40, 0x20, 0xf8, 0x08, 0x81, 0xa0, 0x19, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xda, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 28: 56.549 MHz + { + 0x035ede88, // 56549000 Hz + { + { { 0xd1, 0x2f, 0x32, 0x40, 0x7f, 0x3f, 0x08, 0x41, 0xa0, 0x1b, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xd9, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 29: 56.750 MHz + { + 0x0361efb0, // 56750000 Hz + { + { { 0xd1, 0x2f, 0x32, 0x40, 0x30, 0x1c, 0x08, 0x81, 0xa0, 0x1c, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xd9, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 30: 63.500 MHz + { + 0x03c8eee0, // 63500000 Hz + { + { { 0xd1, 0x35, 0x34, 0x40, 0x30, 0xf8, 0x08, 0x83, 0xa0, 0x3e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc2, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 31: 64.109 MHz + { + 0x03d239c7, // 64108999 Hz + { + { { 0xd2, 0x6b, 0x34, 0x40, 0x7f, 0xb3, 0x10, 0x05, 0xa0, 0x41, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc0, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 32: 65.000 MHz + { + 0x03dfd240, // 65000000 Hz + { + { { 0xd1, 0x36, 0x34, 0x40, 0x30, 0x10, 0x04, 0x81, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 33: 68.250 MHz + { + 0x04116990, // 68250000 Hz + { + { { 0xd1, 0x39, 0x35, 0x40, 0x20, 0xf8, 0x08, 0x87, 0xa0, 0x55, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb4, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 34: 71.000 MHz + { + 0x043b5fc0, // 71000000 Hz + { + { { 0xd1, 0x3b, 0x35, 0x40, 0x30, 0x10, 0x08, 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 35: 72.000 MHz + { + 0x044aa200, // 72000000 Hz + { + { { 0x51, 0x3c, 0x30, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x68, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xab, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 36: 73.250 MHz + { + 0x045db4d0, // 73250000 Hz + { + { { 0xd1, 0x3d, 0x35, 0x40, 0x30, 0x04, 0x08, 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 37: 74.250 MHz + { + 0x046cf710, // 74250000 Hz + { + { { 0xd1, 0x3e, 0x35, 0x40, 0x20, 0xf8, 0x04, 0x81, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 38: 74.481 MHz + { + 0x04707d68, // 74481000 Hz + { + { { 0xd3, 0xba, 0x35, 0x40, 0x64, 0x1b, 0x04, 0x41, 0xa0, 0x74, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 39: 74.500 MHz + { + 0x0470c7a0, // 74500000 Hz + { + { { 0xd1, 0x3e, 0x35, 0x40, 0x30, 0x08, 0x04, 0x81, 0xa0, 0x75, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 40: 75.000 MHz + { + 0x047868c0, // 75000000 Hz + { + { { 0x52, 0x7d, 0x30, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x77, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa4, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 41: 78.750 MHz + { + 0x04b1a130, // 78750000 Hz + { + { { 0xd1, 0x21, 0x11, 0x40, 0x20, 0xf4, 0x08, 0x87, 0xa0, 0xc5, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9c, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 42: 79.500 MHz + { + 0x04bd12e0, // 79500000 Hz + { + { { 0xd1, 0x21, 0x11, 0x40, 0x20, 0x08, 0x08, 0x87, 0xa0, 0xc7, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9b, 0x24, 0x01, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 43: 80.136 MHz + { + 0x04c6c740, // 80136000 Hz + { + { { 0xd1, 0x21, 0x11, 0x40, 0x64, 0x4e, 0x08, 0x87, 0xa0, 0xc8, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x33, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 44: 81.804 MHz + { + 0x04e03ae0, // 81804000 Hz + { + { { 0xd1, 0x22, 0x11, 0x40, 0x64, 0x11, 0x04, 0x83, 0xa0, 0xcd, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x2c, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 45: 82.000 MHz + { + 0x04e33880, // 82000000 Hz + { + { { 0xd1, 0x22, 0x11, 0x40, 0x30, 0x10, 0x04, 0x83, 0xa0, 0xcd, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x2c, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 46: 83.462 MHz + { + 0x04f98770, // 83462000 Hz + { + { { 0xd4, 0x8b, 0x16, 0x40, 0x4b, 0x1f, 0x10, 0x05, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x26, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 47: 83.500 MHz + { + 0x04fa1be0, // 83500000 Hz + { + { { 0xd1, 0x23, 0x11, 0x40, 0x30, 0xec, 0x08, 0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x26, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 48: 84.715 MHz + { + 0x050ca5f8, // 84715000 Hz + { + { { 0xd2, 0x47, 0x16, 0x40, 0x78, 0x9f, 0x08, 0x81, 0xa0, 0xd4, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x22, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 49: 84.750 MHz + { + 0x050d2eb0, // 84750000 Hz + { + { { 0xd1, 0x23, 0x11, 0x40, 0x20, 0x14, 0x08, 0x85, 0xa0, 0xd4, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x22, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 50: 85.500 MHz + { + 0x0518a060, // 85500000 Hz + { + { { 0xd1, 0x24, 0x11, 0x40, 0x20, 0xe8, 0x02, 0x81, 0xa0, 0xd6, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x1f, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 51: 85.860 MHz + { + 0x051e1ea0, // 85860000 Hz + { + { { 0xd1, 0x24, 0x11, 0x40, 0x3c, 0xe5, 0x02, 0x81, 0xa0, 0xd7, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x1e, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 52: 88.750 MHz + { + 0x054a37b0, // 88750000 Hz + { + { { 0xd1, 0x25, 0x11, 0x40, 0x30, 0xfe, 0x08, 0x83, 0xa0, 0xde, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x15, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 53: 94.387 MHz + { + 0x05a03b38, // 94387000 Hz + { + { { 0xd1, 0x27, 0x14, 0x40, 0x7f, 0x6f, 0x02, 0x81, 0xa0, 0xec, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x04, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 54: 94.500 MHz + { + 0x05a1f4a0, // 94500000 Hz + { + { { 0xd1, 0x27, 0x11, 0x40, 0x20, 0x18, 0x08, 0x81, 0xa0, 0xec, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x04, 0x25, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 55: 101.000 MHz + { + 0x06052340, // 101000000 Hz + { + { { 0xd1, 0x2a, 0x12, 0x40, 0x30, 0x08, 0x04, 0x83, 0xa0, 0xfd, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf3, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 56: 101.250 MHz + { + 0x0608f3d0, // 101250000 Hz + { + { { 0xd1, 0x2a, 0x12, 0x40, 0x20, 0x0c, 0x04, 0x83, 0xa0, 0xfd, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf3, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 57: 102.104 MHz + { + 0x0615fbc0, // 102104000 Hz + { + { { 0xd2, 0x55, 0x12, 0x40, 0x4b, 0x0d, 0x10, 0x4b, 0xa0, 0xff, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf1, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 58: 102.250 MHz + { + 0x06183610, // 102250000 Hz + { + { { 0xd1, 0x2b, 0x12, 0x40, 0x30, 0xda, 0x08, 0x85, 0xa0, 0x00, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xf0, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 59: 102.977 MHz + { + 0x06234de8, // 102977000 Hz + { + { { 0xd1, 0x2b, 0x12, 0x40, 0x78, 0xa7, 0x08, 0x05, 0xa0, 0x01, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xef, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 60: 104.000 MHz + { + 0x0632ea00, // 104000000 Hz + { + { { 0xd1, 0x2b, 0x12, 0x40, 0x30, 0x20, 0x08, 0x85, 0xa0, 0x04, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xec, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 61: 104.993 MHz + { + 0x064210e8, // 104993000 Hz + { + { { 0xd4, 0xaf, 0x12, 0x40, 0x7f, 0xfd, 0x20, 0x11, 0xa0, 0x06, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xea, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 62: 106.472 MHz + { + 0x0658a240, // 106472000 Hz + { + { { 0xd2, 0x59, 0x12, 0x40, 0x4b, 0xd7, 0x10, 0x47, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe7, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 63: 106.500 MHz + { + 0x06590fa0, // 106500000 Hz + { + { { 0xd1, 0x2c, 0x12, 0x40, 0x20, 0x18, 0x02, 0x81, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe7, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 64: 107.214 MHz + { + 0x0663f4b0, // 107214000 Hz + { + { { 0xd2, 0x59, 0x12, 0x40, 0x64, 0x45, 0x10, 0x47, 0xa0, 0x0c, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe5, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 65: 108.000 MHz + { + 0x066ff300, // 108000000 Hz + { + { { 0x51, 0x2d, 0x10, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe4, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 66: 108.108 MHz + { + 0x067198e0, // 108108000 Hz + { + { { 0xd1, 0x2d, 0x12, 0x40, 0x64, 0x09, 0x08, 0x83, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe3, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 67: 108.883 MHz + { + 0x067d6c38, // 108883000 Hz + { + { { 0xd2, 0x5b, 0x12, 0x40, 0x7f, 0xbd, 0x10, 0x45, 0xa0, 0x10, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe2, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 68: 109.000 MHz + { + 0x067f3540, // 109000000 Hz + { + { { 0xd1, 0x2d, 0x12, 0x40, 0x30, 0x28, 0x08, 0x83, 0xa0, 0x11, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xe1, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 69: 115.500 MHz + { + 0x06e263e0, // 115500000 Hz + { + { { 0xd1, 0x30, 0x12, 0x40, 0x20, 0x08, 0x00, 0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xd5, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 70: 117.500 MHz + { + 0x0700e860, // 117500000 Hz + { + { { 0xd1, 0x31, 0x14, 0x40, 0x30, 0xfc, 0x08, 0x87, 0xa0, 0x26, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xd1, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 71: 118.532 MHz + { + 0x0710a7a0, // 118532000 Hz + { + { { 0xd2, 0x63, 0x14, 0x40, 0x4b, 0xbd, 0x10, 0x0d, 0xa0, 0x28, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xcf, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 72: 119.000 MHz + { + 0x0717cbc0, // 119000000 Hz + { + { { 0xd1, 0x32, 0x14, 0x40, 0x30, 0xd8, 0x04, 0x83, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xcf, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 73: 121.750 MHz + { + 0x0741c1f0, // 121750000 Hz + { + { { 0xd1, 0x33, 0x14, 0x40, 0x30, 0xe6, 0x08, 0x85, 0xa0, 0x30, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xca, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 74: 122.500 MHz + { + 0x074d33a0, // 122500000 Hz + { + { { 0xd1, 0x33, 0x14, 0x40, 0x30, 0x04, 0x08, 0x85, 0xa0, 0x32, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc9, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 75: 122.614 MHz + { + 0x074ef0f0, // 122614000 Hz + { + { { 0xd3, 0x99, 0x16, 0x40, 0x50, 0x13, 0x02, 0x81, 0xa0, 0x33, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc8, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 76: 123.379 MHz + { + 0x075a9d38, // 123379000 Hz + { + { { 0xd2, 0x67, 0x14, 0x40, 0x5b, 0xbd, 0x10, 0x09, 0xa0, 0x34, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xc7, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 77: 130.250 MHz + { + 0x07c37510, // 130250000 Hz + { + { { 0xd1, 0x36, 0x14, 0x40, 0x30, 0x1a, 0x04, 0x81, 0xa0, 0x46, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xbd, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 78: 135.000 MHz + { + 0x080befc0, // 135000000 Hz + { + { { 0xd1, 0x38, 0x14, 0x40, 0x20, 0x10, 0x00, 0x80, 0x80, 0x52, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb6, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 79: 136.488 MHz + { + 0x0822a440, // 136488000 Hz + { + { { 0xd3, 0xab, 0x15, 0x40, 0x64, 0xe6, 0x08, 0x87, 0xa0, 0x55, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb4, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 80: 136.750 MHz + { + 0x0826a3b0, // 136750000 Hz + { + { { 0xd1, 0x39, 0x15, 0x40, 0x30, 0xfe, 0x08, 0x87, 0xa0, 0x56, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb4, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 81: 138.542 MHz + { + 0x0841fbb0, // 138542000 Hz + { + { { 0xd4, 0xe7, 0x15, 0x40, 0x78, 0xe9, 0x20, 0x19, 0xa0, 0x5a, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb1, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 82: 138.750 MHz + { + 0x08452830, // 138750000 Hz + { + { { 0xd1, 0x3a, 0x15, 0x40, 0x20, 0xf4, 0x04, 0x83, 0xa0, 0x5b, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xb1, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 83: 140.250 MHz + { + 0x085c0b90, // 140250000 Hz + { + { { 0xd1, 0x3a, 0x15, 0x40, 0x20, 0x1c, 0x04, 0x83, 0xa0, 0x5f, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xaf, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 84: 146.250 MHz + { + 0x08b79910, // 146250000 Hz + { + { { 0xd1, 0x3d, 0x15, 0x40, 0x20, 0xfc, 0x08, 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa8, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 85: 147.136 MHz + { + 0x08c51e00, // 147136000 Hz + { + { { 0xd1, 0x3d, 0x15, 0x40, 0x4b, 0x2e, 0x08, 0x83, 0xa0, 0x70, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa7, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 86: 148.250 MHz + { + 0x08d61d90, // 148250000 Hz + { + { { 0xd1, 0x3e, 0x15, 0x40, 0x30, 0xea, 0x04, 0x81, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x07, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa6, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 87: 148.500 MHz + { + 0x08d9ee20, // 148500000 Hz + { + { { 0xd1, 0x3e, 0x15, 0x40, 0x20, 0xf8, 0x04, 0x81, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa5, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 88: 149.426 MHz + { + 0x08e80f50, // 149426000 Hz + { + { { 0xd4, 0xf9, 0x15, 0x40, 0x7f, 0x0b, 0x20, 0x07, 0xa0, 0x76, 0xd9, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa4, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 89: 154.000 MHz + { + 0x092dda80, // 154000000 Hz + { + { { 0xd1, 0x20, 0x00, 0x40, 0x30, 0x08, 0x00, 0x80, 0x80, 0xc1, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0xa0, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 90: 155.851 MHz + { + 0x094a18f8, // 155851000 Hz + { + { { 0xd2, 0x41, 0x06, 0x40, 0x7f, 0xc1, 0x08, 0x07, 0xa0, 0xc3, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9e, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 91: 156.000 MHz + { + 0x094c5f00, // 156000000 Hz + { + { { 0x52, 0x41, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc3, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9e, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 92: 156.794 MHz + { + 0x09587c90, // 156794000 Hz + { + { { 0xd4, 0x83, 0x06, 0x40, 0x60, 0xbf, 0x10, 0x4d, 0xa0, 0xc4, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9d, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 93: 157.000 MHz + { + 0x095ba140, // 157000000 Hz + { + { { 0xd1, 0x21, 0x01, 0x40, 0x30, 0xe4, 0x08, 0x87, 0xa0, 0xc4, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9d, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 94: 157.500 MHz + { + 0x09634260, // 157500000 Hz + { + { { 0xd1, 0x21, 0x01, 0x40, 0x20, 0xf4, 0x08, 0x87, 0xa0, 0xc5, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9c, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 95: 159.358 MHz + { + 0x097f9c30, // 159358000 Hz + { + { { 0xd4, 0x85, 0x06, 0x40, 0x78, 0x9f, 0x10, 0x0b, 0xa0, 0xc7, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9a, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 96: 159.500 MHz + { + 0x0981c6e0, // 159500000 Hz + { + { { 0xd1, 0x21, 0x01, 0x40, 0x30, 0x16, 0x08, 0x87, 0xa0, 0xc7, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x9a, 0x24, 0x02, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 97: 160.963 MHz + { + 0x099819b8, // 160963000 Hz + { + { { 0xd2, 0x43, 0x06, 0x40, 0x7f, 0x45, 0x08, 0x05, 0xa0, 0xc9, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x31, 0x25, 0x03, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 98: 161.000 MHz + { + 0x0998aa40, // 161000000 Hz + { + { { 0xd1, 0x22, 0x01, 0x40, 0x30, 0xd4, 0x04, 0x83, 0xa0, 0xc9, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x31, 0x25, 0x03, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 99: 161.750 MHz + { + 0x09a41bf0, // 161750000 Hz + { + { { 0xd1, 0x22, 0x01, 0x40, 0x30, 0xe3, 0x04, 0x83, 0xa0, 0xca, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x30, 0x25, 0x03, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, + // 100: 162.000 MHz + { + 0x09a7ec80, // 162000000 Hz + { + { { 0xd1, 0x22, 0x01, 0x40, 0x20, 0xf0, 0x04, 0x83, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0e, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x82, 0x54, 0x2f, 0x25, 0x03, 0x00, 0x00, 0x01 }, 0, 0 }, // 24 bpp + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 30 bpp (invalid) + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 1 }, // 36 bpp (invalid) + } + }, +}; + + +size_t hdmi_static_config_size = sizeof( hdmi_static_config ); diff --git a/drivers/samsung/hdmi8947/regs.h b/drivers/samsung/hdmi8947/regs.h new file mode 100644 index 0000000..9383fb0 --- /dev/null +++ b/drivers/samsung/hdmi8947/regs.h @@ -0,0 +1,998 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _REGS_H +#define _REGS_H + +#define CTRL_BASE_ADDR (HDMI_BASE_ADDR + 0x00000) //controller +#define HDMI_CORE_BASE_ADDR (HDMI_BASE_ADDR + 0x10000) //HDMI +#define SPDIF_BASE_ADDR (HDMI_BASE_ADDR + 0x30000) //SPDIF receiver +#define I2S_BASE_ADDR (HDMI_BASE_ADDR + 0x40000) //I2S receiver +#define TG_BASE_ADDR (HDMI_BASE_ADDR + 0x50000) //HDMI timing generator +#define E_FUSE_BASE_ADDR (HDMI_BASE_ADDR + 0x60000) //E-FUSE controller +#define CEC_BASE_ADDR (HDMI_BASE_ADDR + 0x70000) //CEC +#define I2C_BASE_ADDR (HDMI_BASE_ADDR + 0x80000) //I2C + +#define PHY_I2C_ADDRESS 0x70 +#define IICCONFIG_IICCON 0x00000201 +#define IICCONFIG_FIFOCON 0x00000000 +#define IICCONFIG_IICBUSCON 0x00000000 +#define IICCONFIG_TIMEOUTCON 0xffffffff +//------------------------------------------------------------------------------ +// MARK: - Generic HDMI - +//------------------------------------------------------------------------------ + +// General Control Packet Subpacket Byte 0 +#define GCP_SB0_CLR_AVMUTE 0x10 +#define GCP_SB0_SET_AVMUTE 0x01 + +// General Control Packet Subpacket Byte 1 +#define GCP_SB1_CD_SHIFT 0 +#define GCP_SB1_CD_MASK 0x07 +#define GCP_SB1_CD_NONE 0 +#define GCP_SB1_CD_24_BPP 4 +#define GCP_SB1_CD_30_BPP 5 +#define GCP_SB1_CD_36_BPP 6 +#define GCP_SB1_CD_48_BPP 7 + +//------------------------------------------------------------------------------ +// MARK: - PHY registers - +// +// Note: +// Register names are in hexadecimal. +// Definitions of registers 01~1E are PHY version dependent. +// The HDMI V1.3 TX may be used with either PHY version (V1.3 or V1.4). +//------------------------------------------------------------------------------ + +#define PHY_CONFIG_REG00 0x00u // (R/W) Unused Reserved register +#define PHY_CONFIG_REG01 0x01u // (R/W) First byte of PHY configuration +#define PHY_CONFIG_REG02 0x02u // (R/W) +#define PHY_CONFIG_REG03 0x03u // (R/W) +#define PHY_CONFIG_REG04 0x04u // (R/W) +#define PHY_CONFIG_REG05 0x05u // (R/W) +#define PHY_CONFIG_REG06 0x06u // (R/W) +#define PHY_CONFIG_REG07 0x07u // (R/W) +#define PHY_CONFIG_REG08 0x08u // (R/W) +#define PHY_CONFIG_REG09 0x09u // (R/W) +#define PHY_CONFIG_REG0A 0x0Au // (R/W) +#define PHY_CONFIG_REG0B 0x0Bu // (R/W) +#define PHY_CONFIG_REG0C 0x0Cu // (R/W) +#define PHY_CONFIG_REG0D 0x0Du // (R/W) +#define PHY_CONFIG_REG0E 0x0Eu // (R/W) +#define PHY_CONFIG_REG0F 0x0Fu // (R/W) +#define PHY_CONFIG_REG10 0x10u // (R/W) +#define PHY_CONFIG_REG11 0x11u // (R/W) +#define PHY_CONFIG_REG12 0x12u // (R/W) +#define PHY_CONFIG_REG13 0x13u // (R/W) +#define PHY_CONFIG_REG14 0x14u // (R/W) +#define PHY_CONFIG_REG15 0x15u // (R/W) +#define PHY_CONFIG_REG16 0x16u // (R/W) +#define PHY_CONFIG_REG17 0x17u // (R/W) +#define PHY_CONFIG_REG18 0x18u // (R/W) +#define PHY_CONFIG_REG19 0x19u // (R/W) +#define PHY_CONFIG_REG1A 0x1Au // (R/W) +#define PHY_CONFIG_REG1B 0x1Bu // (R/W) +#define PHY_CONFIG_REG1C 0x1Cu // (R/W) +#define PHY_CONFIG_REG1D 0x1Du // (R/W) +#define PHY_CONFIG_REG1E 0x1Eu // (R/W) Last byte of PHY configuration + +#define PHY_CONFIG_MODE_SET 0x1Fu // (R/W) Control register for PHY config + #define PHY_CONFIG_MODE_SET_IN_PROGRESS 0x00 // Set this value before loading REG01-REG1E + #define PHY_CONFIG_MODE_SET_DONE 0x80 // Set this value after loading REG01-REG1E + +#define PHY_CONFIG_REG_COUNT 0x20u + +//------------------------------------------------------------------------------ +// MARK: - HDMI v1.3 PHY registers - +//------------------------------------------------------------------------------ + +// REG01 + #define PHY_V1P3_CONFIG_REG01_GEN_PD 0x80 // Sigma delta modulator clock generator Power Down + #define PHY_V1P3_CONFIG_REG01_BIAS_PD 0x20 // Bias Power Down - PLL & Bias required for HPD + +// REG05 + #define PHY_V1P3_CONFIG_REG05_PLL_PD 0x20 // PLL Power Down - PLL & Bias required for HPD + +// REG17 + #define PHY_V1P3_CONFIG_REG17_TX_PD 0x02 // TMDS TX power down + #define PHY_V1P3_CONFIG_REG17_PCG_PD 0x01 // Pixel clock generator Power Down + +//------------------------------------------------------------------------------ +// MARK: - HDMI v1.4 PHY registers - +//------------------------------------------------------------------------------ + +// REG1D + #define PHY_V1P4_CONFIG_REG1D_I2C_PDEN 0x80 // Enable the power down controls below + #define PHY_V1P4_CONFIG_REG1D_PLL_PD 0x40 // PLL & Bias Power Down - PLL & Bias required for HPD + #define PHY_V1P4_CONFIG_REG1D_TX_CLKSER_PD 0x20 // Clock Serializer Power Down + #define PHY_V1P4_CONFIG_REG1D_TX_CLKDRV_PD 0x10 // TMDS Clock Driver Power Down + #define PHY_V1P4_CONFIG_REG1D_TX_DATDRV_PD 0x04 // TMDS Data Driver Power Down + #define PHY_V1P4_CONFIG_REG1D_TX_DATSER_PD 0x02 // TMDS Data Serializer Power Down + #define PHY_V1P4_CONFIG_REG1D_TX_CLK_PD 0x01 // TX Internal Clock Buffer/Divider Power Down + + // TX Power Down bits + #define PHY_V1P4_CONFIG_REG1D_TX_DRV_PD (PHY_V1P4_CONFIG_REG1D_TX_DATDRV_PD |\ + PHY_V1P4_CONFIG_REG1D_TX_CLKDRV_PD) + + // Power Down bits (excluding I2C_PDEN and PLL_PD) + #define PHY_V1P4_CONFIG_REG1D_PD_WITH_HPD (PHY_V1P4_CONFIG_REG1D_TX_CLKSER_PD | \ + PHY_V1P4_CONFIG_REG1D_TX_CLKDRV_PD | \ + PHY_V1P4_CONFIG_REG1D_TX_DATDRV_PD | \ + PHY_V1P4_CONFIG_REG1D_TX_DATSER_PD | \ + PHY_V1P4_CONFIG_REG1D_TX_CLK_PD) + + // All Power Down bits (excluding I2C_PDEN) + #define PHY_V1P4_CONFIG_REG1D_FULL_PD (PHY_V1P4_CONFIG_REG1D_PLL_PD | PHY_V1P4_CONFIG_REG1D_PD_WITH_HPD) + +//------------------------------------------------------------------------------ +// MARK: - Control Registers (CTRL_BASE) - +//------------------------------------------------------------------------------ + + +#define CTRL_INTC_CON 0x0000u // (R/W) Specifies the interrupt control register. [0x00] + #define CTRL_INTC_CON_POL_SHIFT 7 + #define CTRL_INTC_CON_POL_MASK 0x80 + #define CTRL_INTC_CON_POL_HIGH 0 // Active high + #define CTRL_INTC_CON_POL_LOW 1 // Active low + #define CTRL_INTC_CON_EN_GLOBAL 0x40 + #define CTRL_INTC_CON_EN_I2S 0x20 + #define CTRL_INTC_CON_EN_CEC 0x10 + #define CTRL_INTC_CON_EN_HPD_PLUG 0x08 + #define CTRL_INTC_CON_EN_HPD_UNPLUG 0x04 + #define CTRL_INTC_CON_EN_SPDIF 0x02 + #define CTRL_INTC_CON_EN_HDCP 0x01 + + #define CTRL_INTC_CON_EN_HPD_CHG (CTRL_INTC_CON_EN_HPD_PLUG|CTRL_INTC_CON_EN_HPD_UNPLUG) + +#define CTRL_INTC_FLAG 0x0004u // (R/W) Specifies the interrupt flag register. [0x00] + #define CTRL_INTC_FLAG_I2S 0x20 + #define CTRL_INTC_FLAG_CEC 0x10 + #define CTRL_INTC_FLAG_HPD_PLUG 0x08 + #define CTRL_INTC_FLAG_HPD_UNPLUG 0x04 + #define CTRL_INTC_FLAG_SPDIF 0x02 + #define CTRL_INTC_FLAG_HDCP 0x01 + + #define CTRL_INTC_FLAG_HPD_CHG (CTRL_INTC_FLAG_HPD_PLUG|CTRL_INTC_FLAG_HPD_UNPLUG) + +#define CTRL_HDCP_KEY_STATUS 0x0008u // (R/O) Specifies the HDCP key status. [0x00] + #define CTRL_HDCP_KEY_STATUS_LOAD_DONE 0x01 + +#define CTRL_HPD_STATUS 0x000Cu // (R/O) Specifies the value of HPD signal. [0x00] + #define CTRL_HPD_STATUS_PLUGGED 0x01 + +// Common definitions for AUDIO_CLKSEL +#define CTRL_AUDIO_CLK_MASK 0x01 +#define CTRL_AUDIO_CLK_PCLK 0 +#define CTRL_AUDIO_CLK_SPDIF 1 + +// Common definitions for PHY_RSTOUT +#define CTRL_HDMI_PHY_RSTOUT_RESET 0x01 // Reset HDMI PHY (active high) + +// Common definitions for CORE_RSTOUT +#define CTRL_HDMI_CORE_RSTOUT_RESET_F 0x01 // Reset HDMI core (active low) + +//------------------------------------------------------------------------------ +// MARK: - HDMI Core Registers (HDMI_CORE_BASE) - +//------------------------------------------------------------------------------ + +#define HDMI_CON_0 0x0000u // (R/W) Specifies the HDMI system control register 0. [0x00] + #define HDMI_CON_0_BLUE_SCR_EN 0x20 // Enable "blue screen" mode (TX video mute) + #define HDMI_CON_0_ENCODING_RETAIN_BIT_ORDER 0x10 // Reverse (0) or retain (1) + #define HDMI_CON_0_ASP_EN 0x04 + #define HDMI_CON_0_SYSTEM_EN 0x01 + +#define HDMI_CON_1 0x0004u // (R/W) Specifies the HDMI system control register 1. [0x00] + #define HDMI_CON_1_PXL_LMT_CTRL_SHIFT 5 + #define HDMI_CON_1_PXL_LMT_CTRL_MASK 0x60 + #define HDMI_CON_1_PXL_LMT_CTRL_BYPASS_MODE 0 + #define HDMI_CON_1_PXL_LMT_CTRL_RGB_MODE 1 + #define HDMI_CON_1_PXL_LMT_CTRL_YCBCR_MODE 2 + +#define HDMI_CON_2 0x0008u // (R/W) Specifies the HDMI system control register 2. [0x00] + #define HDMI_CON_2_VID_PERIOD_EN 0x20 + #define HDMI_CON_2_DVI_BAND_EN 0x02 + +#define HDMI_STATUS 0x0010u // (R/W) Specifies the HDMI system status register. [0x00] + #define HDMI_STATUS_AUTHEN_ACK 0x80 + #define HDMI_STATUS_AUD_FIFO_OVF_INT 0x40 + #define HDMI_STATUS_UPDATE_Ri_INT 0x10 // Indicates that the {Ri} value should be read (HDCP) + #define HDMI_STATUS_An_WRITE_INT 0x04 // Indicates that the {An} random value is ready (HDCP) + #define HDMI_STATUS_WATCHDOG_INT 0x02 + #define HDMI_STATUS_I2C_INIT_INT 0x01 + +#define HDMI_STATUS_EN 0x0020u // (R/W) Specifies the HDMI system status enable register. [0x00] + #define HDMI_STATUS_EN_AUD_FIFO_OVF_EN 0x40 + #define HDMI_STATUS_EN_UPDATE_Ri_EN 0x10 + #define HDMI_STATUS_EN_An_WRITE_EN 0x04 + #define HDMI_STATUS_EN_WATCHDOG_EN 0x02 + #define HDMI_STATUS_EN_I2C_INIT_EN 0x01 + + // Enable mask including all HDCP interrupts except WATCHDOG_INT, which is not used. + #define HDMI_STATUS_EN_HDCP_EN (HDMI_STATUS_EN_UPDATE_Ri_EN|HDMI_STATUS_EN_An_WRITE_EN|HDMI_STATUS_EN_I2C_INIT_EN) + +#define HDMI_HPD 0x0030u // (R/W) Specifies the HPD control register. [0x00] + #define HDMI_HPD_SW_HPD 0x02 + #define HDMI_HPD_HPD_SEL_SW_HPD 0x01 + +#define HDMI_MODE_SEL 0x0040u // (R/W) Selects the HDMI/DVI mode. [0x00] + #define HDMI_MODE_SEL_MODE_SHIFT 0 + #define HDMI_MODE_SEL_MODE_MASK 0x03 + #define HDMI_MODE_SEL_MODE_DISABLED 0 + #define HDMI_MODE_SEL_MODE_DVI 1 + #define HDMI_MODE_SEL_MODE_HDMI 2 + +#define HDMI_ENC_EN 0x0044u // (R/W) Specifies the HDCP encryption enable register [0x00] + #define HDMI_ENC_EN_HDCP_ENC_EN 0x01 + +//------------------------------------------------------------------------------ +// MARK: - HDMI Video Related Registers - +//------------------------------------------------------------------------------ + +#define HDMI_YMAX 0x0060u // (R/W) Specifies the maximum Y (or R, G, B) pixel value [0xeb] +#define HDMI_YMIN 0x0064u // (R/W) Specifies the minimum Y (or R, G, B) pixel value [0x10] + +#define HDMI_CMAX 0x0068u // (R/W) Specifies the maximum Cb/Cr pixel value [0xf0] +#define HDMI_CMIN 0x006Cu // (R/W) Specifies the minimum Cb/Cr pixel value [0x10] + +#define HDMI_H_BLANK_0 0x00A0u // (R/W) Specifies the horizontal blanking setting [0x00] +#define HDMI_H_BLANK_1 0x00A4u // (R/W) Specifies the horizontal blanking setting [0x00] + +#define HDMI_VSYNC_POL 0x00E4u // (R/W) Specifies the vertical sync polarity control register [0x00] + +#define HDMI_INT_PRO_MODE 0x00E8u // (R/W) Specifies the interlace/progressive control register [0x00] + +//------------------------------------------------------------------------------ +// MARK: - HDMI Audio Related Registers - +//------------------------------------------------------------------------------ + +// Common definitions for HDMI_ASP_CON + #define HDMI_ASP_CON_AUD_TYPE_SHIFT 5 // Audio packet type field position + #define HDMI_ASP_CON_AUD_TYPE_MASK 0x60 + #define HDMI_ASP_CON_AUD_TYPE_ASP 0u // Audio Sample Packet + #define HDMI_ASP_CON_AUD_TYPE_1BIT 1u // One-bit audio packet + #define HDMI_ASP_CON_AUD_TYPE_HBR 2u // High Bit Rate packet + #define HDMI_ASP_CON_AUD_TYPE_DST 3u // Direct Stream Transport packet + + #define HDMI_ASP_CON_AUD_MODE_SHIFT 4 // Audio packet layout field position + #define HDMI_ASP_CON_AUD_MODE_MASK 0x10 + #define HDMI_ASP_CON_AUD_MODE_TWO_CHANNEL 0u // Layout 0 (two-channel mode) + #define HDMI_ASP_CON_AUD_MODE_MULTI_CHANNEL 1u // Layout 1 (multi-channel mode) + + #define HDMI_ASP_CON_SP_PRE_SHIFT 0 // Sample Present field position (not used in two-channel mode) + #define HDMI_ASP_CON_SP_PRE_MASK 0x0F + +// Common definitions for HDMI_ACR_CON: + #define HDMI_ACR_CON_ALT_CTS_RATE_SHIFT 3 // Alternate CTS rate field position + #define HDMI_ACR_CON_ALT_CTS_RATE_MASK 0x18 + #define HDMI_ACR_CON_ALT_CTS_RATE_CONSTANT_CTS 0 // Always use CTS value 1 + #define HDMI_ACR_CON_ALT_CTS_RATE_1_TO_1 1 // 1:1 (CTS value 1 : CTS value 2) + #define HDMI_ACR_CON_ALT_CTS_RATE_2_TO_1 2 // 2:1 (CTS value 1 : CTS value 2) + #define HDMI_ACR_CON_ALT_CTS_RATE_3_TO_1 3 // 3:1 (CTS value 1 : CTS value 2) + + #define HDMI_ACR_CON_ACR_TX_MODE_SHIFT 0 // ACR transmit mode field position + #define HDMI_ACR_CON_ACR_TX_MODE_MASK 0x07 + #define HDMI_ACR_CON_ACR_TX_MODE_DISABLED 0 // Do not transmit the ACR packet + #define HDMI_ACR_CON_ACR_TX_MODE_ONCE 1 // Transmit one packet, when it becomes available + #define HDMI_ACR_CON_ACR_TX_MODE_INTERVAL 2 // Transmit ACR_TXCNT times during every VBI period + #define HDMI_ACR_CON_ACR_TX_MODE_COUNTING 3 // Transfers by counting i_clk_vid for a given CTS value in ACR_CTS0:2 + #define HDMI_ACR_CON_ACR_TX_MODE_MEASURED_CTS 4 // Mesured CTS mode. Note: The 7 LSBs of ACR_N should be zero. + +//------------------------------------------------------------------------------ +// MARK: - HDMI Packet Related Registers - +//------------------------------------------------------------------------------ + +// Common definitions for: +// GCP_CON[GCP_CON] +// ACP_CON[ACP_TX_CON] +// ISRC_CON[ISRC_TX_CON] +// AVI_CON[AVI_TX_CON] +// AUI_CON[AUI_TX_CON] +// MPG_CON[MPG_TX_CON] +// SPD_CON[SPD_TX_CON +// GAMUT_CON[GAMUT_CON] +#define HDMI_PKT_CON_PKT_TX_CON_SHIFT 0 +#define HDMI_PKT_CON_PKT_TX_CON_MASK 0x03 +#define HDMI_PKT_CON_PKT_TX_CON_DISABLED 0 +#define HDMI_PKT_CON_PKT_TX_CON_SEND_ONCE 1 +#define HDMI_PKT_CON_PKT_TX_CON_SEND_ALWAYS 2 + +// Common definitions for GCP_CON +#define HDMI_GCP_CON_VSYNC_SHIFT 2 +#define HDMI_GCP_CON_VSYNC_MASK 0x0C +#define HDMI_GCP_CON_VSYNC_NEITHER_FIELD 0 +#define HDMI_GCP_CON_VSYNC_FIELD2 1 +#define HDMI_GCP_CON_VSYNC_FIELD1 2 +#define HDMI_GCP_CON_VSYNC_BOTH_FIELDS 3 + +// Common definitions for DC_CONTROL +#define HDMI_DC_CONTROL_DEEP_COLOR_MODE_SHIFT 0 +#define HDMI_DC_CONTROL_DEEP_COLOR_MODE_MASK 0x03 +#define HDMI_DC_CONTROL_DEEP_COLOR_MODE_8_BPC (0 << HDMI_DC_CONTROL_DEEP_COLOR_MODE_SHIFT) +#define HDMI_DC_CONTROL_DEEP_COLOR_MODE_10_BPC (1 << HDMI_DC_CONTROL_DEEP_COLOR_MODE_SHIFT) +#define HDMI_DC_CONTROL_DEEP_COLOR_MODE_12_BPC (2 << HDMI_DC_CONTROL_DEEP_COLOR_MODE_SHIFT) + +// Common definitions for VIDEO_PATTERN_GEN +#define HDMI_VIDEO_PATTERN_GEN_PATTERN_ENABLE 1 // Uses internally generated video pattern + +//------------------------------------------------------------------------------ +// MARK: - HDCP Related Registers - +//------------------------------------------------------------------------------ + +#define HDMI_HDCP_SHA1_00 0x0000u // (R/W) Specifies the SHA-1 value from repeater. [0x00] +#define HDMI_HDCP_KSV_LIST_0 0x0050u // (R/W) Specifies the KSV list from repeater. [0x00] + +#define HDMI_HDCP_KSV_LIST_CON 0x0064u // (R/W) Controls the KSV list. [0x01] + #define HDMI_HDCP_KSV_LIST_CON_WRITE 0x08 + #define HDMI_HDCP_KSV_LIST_CON_EMPTY 0x04 + #define HDMI_HDCP_KSV_LIST_CON_END 0x02 + #define HDMI_HDCP_KSV_LIST_CON_READ_DONE 0x01 + +#define HDMI_HDCP_SHA_RESULT 0x0070u // (R/W) Specifies the SHA-1 checking result register. [0x00] + #define HDMI_HDCP_SHA_RESULT_VALID_READY 0x02 + #define HDMI_HDCP_SHA_RESULT_VALID 0x01 + + #define HDMI_HDCP_SHA_RESULT_OK (HDMI_HDCP_SHA_RESULT_VALID_READY|HDMI_HDCP_SHA_RESULT_VALID) + +#define HDMI_HDCP_CTRL1 0x0080u // (R/W) Specifies the HDCP control register1. [0x00] + #define HDMI_HDCP_CTRL1_TIMEOUT 0x04 + #define HDMI_HDCP_CTRL1_CP_DESIRED 0x02 + +#define HDMI_HDCP_CTRL2 0x0084u // (R/W) Specifies the HDCP control register2. [0x00] + #define HDMI_HDCP_CTRL2_REVOCATION_SET 0x01 + +#define HDMI_HDCP_CHECK_RESULT 0x0090u // (R/W) Checks the result of Ri and Pj values. [0x00] + #define HDMI_HDCP_CHECK_RESULT_Ri_SHIFT 0 + #define HDMI_HDCP_CHECK_RESULT_Ri_MASK 0x03 + #define HDMI_HDCP_CHECK_RESULT_Ri_RESET 0 + #define HDMI_HDCP_CHECK_RESULT_Ri_MISMATCH 2 + #define HDMI_HDCP_CHECK_RESULT_Ri_MATCH 3 + +#define HDMI_HDCP_BKSV_0 0x00A0u // (R/W) Specifies the KSV of Rx. [0x00] +#define HDMI_HDCP_AKSV_0 0x00C0u // (R/W) Specifies the KSV of Tx. [0x00] +#define HDMI_HDCP_An_0 0x00E0u // (R/W) Specifies the an value. [0x00] +#define HDMI_HDCP_BCAPS 0x0100u // (R/W) Specifies the BCAPS from Rx. [0x00] +#define HDMI_HDCP_BSTATUS_0 0x0110u // (R/W) Specifies the BSTATUS from Rx. [0x00] +#define HDMI_HDCP_BSTATUS_1 0x0114u // (R/W) Specifies the BSTATUS from Rx. [0x00] +#define HDMI_HDCP_Ri_0 0x0140u // (R/W) Specifies the Ri value of Tx. [0x00] +#define HDMI_HDCP_Ri_1 0x0144u // (R/W) Specifies the Ri value of Tx. [0x00] +#define HDMI_HDCP_I2C_INT 0x0180u // (R/W) Specifies the I2C interrupt flag. [0x00] +#define HDMI_HDCP_AN_INT 0x0190u // (R/W) Specifies the An value ready interrupt flag. [0x00] +#define HDMI_HDCP_WATCHDOG_INT 0x01A0u // (R/W) Specifies the Watchdog interrupt flag. [0x00] +#define HDMI_HDCP_Ri_INT 0x01B0u // (R/W) Specifies the Ri value update interrupt flag. [0x00] + +#define HDMI_HDCP_Ri_COMPARE_0 0x01D0u // (R/W) Specifies the HDCP Ri interrupt frame number index register 0. [0x80] +#define HDMI_HDCP_Ri_COMPARE_1 0x01D4u // (R/W) Specifies the HDCP Ri interrupt frame number index register 1. [0x7f] + #define HDMI_HDCP_Ri_COMPARE_ENABLE 0x80 + #define HDMI_HDCP_FRAME_INDEX_MASK 0x7F + +#define HDMI_HDCP_FRAME_COUNT 0x01E0u // (R/W) Specifies the current value of frame count index in the hardware. [0x00] + +//------------------------------------------------------------------------------ +// MARK: - SPDIF Receiver Registers (SPDIF_BASE) - +//------------------------------------------------------------------------------ + +#define SPDIFIN_CLK_CTRL 0x0000u // (R/W) Specifies the SPDIFIN clock control register. [0x02] +#define SPDIFIN_OP_CTRL 0x0004u // (R/W) Specifies the SPDIFIN operation control register 1. [0x00] +#define SPDIFIN_IRQ_MASK 0x0008u // (R/W) Specifies the SPDIFIN interrupt request mask register. [0x00] +#define SPDIFIN_IRQ_STATUS 0x000Cu // (R/W) Specifies the SPDIFIN interrupt request status register. [0x00] +#define SPDIFIN_CONFIG_1 0x0010u // (R/W) Specifies the SPDIFIN configuration register 1. [0x02] +#define SPDIFIN_CONFIG_2 0x0014u // (R/W) Specifies the SPDIFIN configuration register 2. [0x00] +#define SPDIFIN_USER_VALUE_1 0x0020u // (R/W) Specifies the SPDIFIN user value register 1. [0x00] +#define SPDIFIN_USER_VALUE_2 0x0024u // (R/W) Specifies the SPDIFIN user value register 2. [0x00] +#define SPDIFIN_USER_VALUE_3 0x0028u // (R/W) Specifies the SPDIFIN user value register 3. [0x00] +#define SPDIFIN_USER_VALUE_4 0x002Cu // (R/W) Specifies the SPDIFIN user value register 4. [0x00] +#define SPDIFIN_CH_STATUS_0_1 0x0030u // (R/O) Specifies the SPDIFIN channel status register 0-1. [0x00] +#define SPDIFIN_CH_STATUS_0_2 0x0034u // (R/O) Specifies the SPDIFIN channel status register 0-2. [0x00] +#define SPDIFIN_CH_STATUS_0_3 0x0038u // (R/O) Specifies the SPDIFIN channel status register 0-3. [0x00] +#define SPDIFIN_CH_STATUS_0_4 0x003Cu // (R/O) Specifies the SPDIFIN channel status register 0-4. [0x00] +#define SPDIFIN_CH_STATUS_1 0x0040u // (R/O) Specifies the SPDIFIN channel status register 1. [0x00] +#define SPDIFIN_FRAME_PERIOD_1 0x0048u // (R/O) Specifies the SPDIFIN frame period register 1. [0x00] +#define SPDIFIN_FRAME_PERIOD_2 0x004Cu // (R/O) Specifies the SPDIFIN frame period register 2. [0x00] +#define SPDIFIN_Pc_INFO_1 0x0050u // (R/O) Specifies the SPDIFIN PC info register 1. [0x00] +#define SPDIFIN_Pc_INFO_2 0x0054u // (R/O) Specifies the SPDIFIN PC info register 2. [0x00] +#define SPDIFIN_Pd_INFO_1 0x0058u // (R/O) Specifies the SPDIFIN PD info register 1. [0x00] +#define SPDIFIN_Pd_INFO_2 0x005Cu // (R/O) Specifies the SPDIFIN PD Info register 2. [0x00] +#define SPDIFIN_DATA_BUF_0_1 0x0060u // (R/O) Specifies the SPDIFIN data buffer register 0_1. [0x00] +#define SPDIFIN_DATA_BUF_0_2 0x0064u // (R/O) Specifies the SPDIFIN data buffer register 0_2. [0x00] +#define SPDIFIN_DATA_BUF_0_3 0x0068u // (R/O) Specifies the SPDIFIN data buffer register 0_3. [0x00] +#define SPDIFIN_USER_BUF_0 0x006Cu // (R/O) Specifies the SPDIFIN user buffer register 0. [0x00] +#define SPDIFIN_DATA_BUF_1_1 0x0070u // (R/O) Specifies the SPDIFIN data buffer register 1_1. [0x00] +#define SPDIFIN_DATA_BUF_1_2 0x0074u // (R/O) Specifies the SPDIFIN data buffer register 1_2. [0x00] +#define SPDIFIN_DATA_BUF_1_3 0x0078u // (R/O) Specifies the SPDIFIN data buffer register 1_3. [0x00] +#define SPDIFIN_USER_BUF_1 0x007Cu // (R/O) Specifies the SPDIFIN user buffer register 1. [0x00] + +//------------------------------------------------------------------------------ +// MARK: - I2S Receiver Registers (I2S_BASE) - +//------------------------------------------------------------------------------ + +#define I2S_CLK_CON 0x0000u // (R/W) Specifies the I2S clock enable register. [0x00] + #define I2S_CLK_CON_I2S_EN 0x01 + +#define I2S_CON_1 0x0004u // (R/W) Specifies the I2S control register 1. [0x00] + #define I2S_CON_1_SCLK_POL_SHIFT 1 // SCLK polarity field (r_sc_pol) position + #define I2S_CON_1_SCLK_POL_MASK 0x02 // SCLK polarity field (r_sc_pol) + #define I2S_CON_1_SCLK_POL_FALLING_EDGE 0 // SDATA is syncrhonous to SCLK falling edge + #define I2S_CON_1_SCLK_POL_RISING_EDGE 1 // SDATA is synchronous to SCLK rising edge + + #define I2S_CON_1_LRCLK_POL_SHIFT 0 // LRCLK polarity field (r_ch_pol) position + #define I2S_CON_1_LRCLK_POL_MASK 0x01 // LRCLK polarity field (r_ch_pol) + #define I2S_CON_1_LRCLK_POL_LOW 0 // Left channel for low polarity + #define I2S_CON_1_LRCLK_POL_HIGH 1 // Left channel for high polarity + +#define I2S_CON_2 0x0008u // (R/W) Specifies the I2S control register 2. [0x16] + #define I2S_CON_2_MLSB_SHIFT 6 // I2S bit order field position + #define I2S_CON_2_MLSB_MASK 0x40 + #define I2S_CON_2_MLSB_MSB_FIRST 0 // MSB first mode + #define I2S_CON_2_MLSB_LSB_FIRST 1 // LSB first mode + + #define I2S_CON_2_BIT_CH_SHIFT 4 // Bit clock per frame field position + #define I2S_CON_2_BIT_CH_MASK 0x30 + #define I2S_CON_2_BIT_CH_32FS 0 // Bit clock = 32*Fs + #define I2S_CON_2_BIT_CH_48FS 1 // Bit clock = 48*Fs + + #define I2S_CON_2_DATA_NUM_SHIFT 2 // Serial data bits per channel field position + #define I2S_CON_2_DATA_NUM_MASK 0x0c + #define I2S_CON_2_DATA_NUM_16_BITS 1 // 16 bits per channel + #define I2S_CON_2_DATA_NUM_20_BITS 2 // 20 bits per channel + #define I2S_CON_2_DATA_NUM_24_BITS 3 // 24 bits per channel + + #define I2S_CON_2_I2S_MODE_SHIFT 0 // I2S mode field position + #define I2S_CON_2_I2S_MODE_MASK 0x03 + #define I2S_CON_2_I2S_MODE_BASIC_FORMAT 0 // I2S basic format + #define I2S_CON_2_I2S_MODE_LEFT_JUSTIFIED 2 // Left-justified format + #define I2S_CON_2_I2S_MODE_RIGHT_JUSTIFIED 3 // Right-justified format + +#define I2S_PIN_SEL_0 0x000Cu // (R/W) Specifies the I2S input pin selection register 0. [0x77] + #define I2S_PIN_SEL_0_LRCLK_SHIFT 0 + #define I2S_PIN_SEL_0_LRCLK_MASK 0x07 + + #define I2S_PIN_SEL_0_SCLK_SHIFT 4 + #define I2S_PIN_SEL_0_SCLK_MASK 0x70 + +#define I2S_PIN_SEL_1 0x0010u // (R/W) Specifies the I2S input pin selection register 1. [0x77] + #define I2S_PIN_SEL_1_SDATA0_SHIFT 0 + #define I2S_PIN_SEL_1_SDATA0_MASK 0x07 + + #define I2S_PIN_SEL_1_SDATA1_SHIFT 4 + #define I2S_PIN_SEL_1_SDATA1_MASK 0x70 + +#define I2S_PIN_SEL_2 0x0014u // (R/W) Specifies the I2S input pin selection register 2. [0x77] + #define I2S_PIN_SEL_2_SDATA2_SHIFT 0 + #define I2S_PIN_SEL_2_SDATA2_MASK 0x07 + + #define I2S_PIN_SEL_2_SDATA3_SHIFT 4 + #define I2S_PIN_SEL_2_SDATA3_MASK 0x70 + +#define I2S_PIN_SEL_3 0x0018u // (R/W) Specifies the I2S input pin selection register 3. [0x07] + #define I2S_PIN_SEL_3_DSD_D5_SHIFT 0 + #define I2S_PIN_SEL_3_DSD_D5_MASK 0x07 + +#define I2S_DSD_CON 0x001Cu // (R/W) Specifies the I2S DSD control register. [0x02] + +#define I2S_IN_MUX_CON 0x0020u // (R/W) Specifies the I2S In/Mux control register. [0x60] + #define I2S_IN_MUX_CON_F_NUM_SHIFT 5 + #define I2S_IN_MUX_CON_F_NUM_MASK 0xe0 + #define I2S_IN_MUX_CON_F_NUM_NONE 0 // Does not filter + #define I2S_IN_MUX_CON_F_NUM_2 1 // 2-stage filter + #define I2S_IN_MUX_CON_F_NUM_3 2 // 3-stage filter + #define I2S_IN_MUX_CON_F_NUM_4 3 // 4-stage filter + #define I2S_IN_MUX_CON_F_NUM_5 4 // 5-stage filter + + #define I2S_IN_MUX_CON_IN_EN 0x10 + + #define I2S_IN_MUX_CON_AUDIO_SEL_SHIFT 2 // AUDIO_SEL field position + #define I2S_IN_MUX_CON_AUDIO_SEL_MASK 0x0c + #define I2S_IN_MUX_CON_AUDIO_SEL_SPDIF 0 // Selects SPDIF audio data + #define I2S_IN_MUX_CON_AUDIO_SEL_I2S 1 // Selects I2S audio data + #define I2S_IN_MUX_CON_AUDIO_SEL_DSD 2 // Selects DSD audio data + + #define I2S_IN_MUX_CON_CUV_SEL_SHIFT 1 // CUV_SEL field position + #define I2S_IN_MUX_CON_CUV_SEL_MASK 0x02 + #define I2S_IN_MUX_CON_CUV_SEL_SPDIF 0 // Selects SPDIF CUV data + #define I2S_IN_MUX_CON_CUV_SEL_I2S 1 // Selects I2S CUV data + + #define I2S_IN_MUX_CON_MUX_EN 0x01 + +#define I2S_CH_ST_CON 0x0024u // (R/W) Specifies the I2S channel status control register. [0x00] + #define I2S_CH_ST_CON_RELOAD 0x01 + +#define I2S_CH_ST_REG_COUNT 5 // Number of channel status registers + +#define I2S_CH_ST_0 0x0028u // (R/W) Specifies the I2S channel status block 0. [0x00] +#define I2S_CH_ST_1 0x002Cu // (R/W) Specifies the I2S channel status block 1. [0x00] +#define I2S_CH_ST_2 0x0030u // (R/W) Specifies the I2S channel status block 2. [0x00] +#define I2S_CH_ST_3 0x0034u // (R/W) Specifies the I2S channel status block 3. [0x00] +#define I2S_CH_ST_4 0x0038u // (R/W) Specifies the I2S channel status block 4. [0x00] + +#define I2S_CH_ST_SH_0 0x003Cu // (R/O) Specifies the I2S channel status block shadow register 0. [0x00] +#define I2S_CH_ST_SH_1 0x0040u // (R/O) Specifies the I2S channel status block shadow register 1. [0x00] +#define I2S_CH_ST_SH_2 0x0044u // (R/O) Specifies the I2S channel status block shadow register 2. [0x00] +#define I2S_CH_ST_SH_3 0x0048u // (R/O) Specifies the I2S channel status block shadow register 3. [0x00] +#define I2S_CH_ST_SH_4 0x004Cu // (R/O) Specifies the I2S channel status block shadow register 4. [0x00] + +#define I2S_VD_DATA 0x0050u // (R/W) Specifies the I2S audio sample validity register. [0x00] +#define I2S_MUX_CH 0x0054u // (R/W) Specifies the I2S channel enable register. [0x03] + +#define I2S_MUX_CUV 0x0058u // (R/W) Specifies the I2S CUV enable register. [0x03] + #define I2S_MUX_CUV_R_EN 0x02 + #define I2S_MUX_CUV_L_EN 0x01 + +#define I2S_CH0_L_0 0x0064u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH0_L_1 0x0068u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH0_L_2 0x006Cu // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH0_L_3 0x0070u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH0_R_0 0x0074u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH0_R_1 0x0078u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH0_R_2 0x007Cu // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH0_R_3 0x0080u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_L_0 0x0084u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_L_1 0x0088u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_L_2 0x008Cu // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_L_3 0x0090u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_R_0 0x0094u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_R_1 0x0098u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_R_2 0x009Cu // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH1_R_3 0x00A0u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH2_L_0 0x00A4u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH2_L_1 0x00A8u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH2_L_2 0x00ACu // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH2_L_3 0x00B0u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH2_R_0 0x00B4u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH2_R_1 0x00B8u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH2_R_2 0x00BCu // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_Ch2_R_3 0x00C0u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH3_L_0 0x00C4u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH3_L_1 0x00C8u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH3_L_2 0x00CCu // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH3_R_0 0x00D0u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH3_R_1 0x00D4u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CH3_R_2 0x00D8u // (R/O) Specifies the I2S PCM output data register. [0x00] +#define I2S_CUV_L_R 0x00DCu // (R/O) Specifies the I2S CUV output data register. [0x00] + +//------------------------------------------------------------------------------ +// MARK: - Timing Generator Registers (TG_BASE) - +//------------------------------------------------------------------------------ + +#define TG_CMD 0x0000u // (R/W) Specifies the command register. [0x00] + #define TG_CMD_FIELD_EN 0x02 // Enables field mode (for interlaced formats) + #define TG_CMD_TG_EN 0x01 + +#define TG_CFG 0x0004u // (R/W) Specifies the pixel repetition ratio. [0x00] + +#define TG_H_FSZ_L 0x0018u // (R/W) Specifies the horizontal full size. [0x72] +#define TG_H_FSZ_H 0x001Cu // (R/W) Specifies the horizontal full size. [0x06] + +#define TG_HACT_ST_L 0x0020u // (R/W) Specifies the horizontal active start. [0x05] +#define TG_HACT_ST_H 0x0024u // (R/W) Specifies the horizontal active start. [0x01] + +#define TG_HACT_SZ_L 0x0028u // (R/W) Specifies the horizontal active size. [0x00] +#define TG_HACT_SZ_H 0x002Cu // (R/W) Specifies the horizontal active size. [0x05] + +#define TG_V_FSZ_L 0x0030u // (R/W) Specifies the vertical full line size. [0xEE] +#define TG_V_FSZ_H 0x0034u // (R/W) Specifies the vertical full line size. [0x02] + +#define TG_VSYNC_L 0x0038u // (R/W) Specifies the vertical sync position. [0x01] +#define TG_VSYNC_H 0x003Cu // (R/W) Specifies the vertical sync position. [0x00] + +#define TG_VSYNC2_L 0x0040u // (R/W) Specifies the vertical sync position for bottom field. [0x33] +#define TG_VSYNC2_H 0x0044u // (R/W) Specifies the vertical sync position for bottom field. [0x02] + +#define TG_VACT_ST_L 0x0048u // (R/W) Specifies the vertical sync active start position. [0x1a] +#define TG_VACT_ST_H 0x004Cu // (R/W) Specifies the vertical sync active start position. [0x00] + +#define TG_VACT_SZ_L 0x0050u // (R/W) Specifies the vertical active size. [0xd0] +#define TG_VACT_SZ_H 0x0054u // (R/W) Specifies the vertical active size. [0x02] + +#define TG_FIELD_CHG_L 0x0058u // (R/W) Specifies the HDMI field change position. [0x33] +#define TG_FIELD_CHG_H 0x005Cu // (R/W) Specifies the HDMI field change position. [0x02] + +#define TG_VACT_ST2_L 0x0060u // (R/W) Specifies the HDMI vertical active start position for bottom field. [0x48] +#define TG_VACT_ST2_H 0x0064u // (R/W) Specifies the HDMI vertical active start position for bottom field. [0x02] + +#define TG_VSYNC_TOP_HDMI_L 0x0078u // (R/W) Specifies the HDMI VSYNC position for top field. [0x01] +#define TG_VSYNC_TOP_HDMI_H 0x007Cu // (R/W) Specifies the HDMI VSYNC position for top field. [0x00] + +#define TG_VSYNC_BOT_HDMI_L 0x0080u // (R/W) Specifies the HDMI VSYNC position for bottom field. [0x33] +#define TG_VSYNC_BOT_HDMI_H 0x0084u // (R/W) Specifies the HDMI VSYNC position for bottom field. [0x02] + +#define TG_FIELD_TOP_HDMI_L 0x0088u // (R/W) Specifies the HDMI top field start position. [0x01] +#define TG_FIELD_TOP_HDMI_H 0x008Cu // (R/W) Specifies the HDMI top field start position. [0x00] + +#define TG_FIELD_BOT_HDMI_L 0x0090u // (R/W) Specifies the HDMI bottom field start position. [0X33] +#define TG_FIELD_BOT_HDMI_H 0x0094u // (R/W) Specifies the HDMI bottom field start position. [0x02] + +//------------------------------------------------------------------------------ +// MARK: - HDCP E-Fuse Control Registers (eFUSE_BASE) - +//------------------------------------------------------------------------------ + +#define EFUSE_HDCP_CTRL 0x0000u // ( W) Specifies the HDCP e-fuse reading control. [0x00] + #define EFUSE_HDCP_CTRL_HDCP_KEY_READ 0x01 + +#define EFUSE_HDCP_STATUS 0x0004u // (R/O) Specifies the HDCP e-fuse reading status. [0x00] + #define EFUSE_HDCP_STATUS_ECC_FAIL 0x04 + #define EFUSE_HDCP_STATUS_ECC_BUSY 0x02 + #define EFUSE_HDCP_STATUS_ECC_DONE 0x01 + +#define EFUSE_ADDR_WIDTH 0x0008u // (R/W) Specifies the address width. [0x14] +#define EFUSE_SIGDEV_ASSERT 0x000Cu // (R/W) Specifies the SIGDEV asserting position. [0x00] +#define EFUSE_SIGDEV_DEASSERT 0x0010u // (R/W) Specifies the SIGDEV de-asserting position. [0x08] +#define EFUSE_PRCHG_ASSERT 0x0014u // (R/W) Specifies the PRCHG asserting position. [0x00] +#define EFUSE_PRCHG_DEASSERT 0x0018u // (R/W) Specifies the PRCHG de-asserting position. [0x0C] +#define EFUSE_FSET_ASSERT 0x001Cu // (R/W) Specifies the FSET asserting position. [0x04] +#define EFUSE_FSET_DEASSERT 0x0020u // (R/W) Specifies the FSET de-asserting position. [0x10] +#define EFUSE_SENSING 0x0024u // (R/W) Specifies the sensing width. [0x14] +#define EFUSE_SCK_ASSERT 0x0028u // (R/W) Specifies the SCK asserting position. [0x04] +#define EFUSE_SCK_DEASSERT 0x002Cu // (R/W) Specifies the SCK de-asserting position. [0x0C] +#define EFUSE_SDOUT_OFFSET 0x0030u // (R/W) Specifies the SDOUT offset. [0x10] +#define EFUSE_READ_OFFSET 0x0034u // (R/W) Specifies the READ offset. [0x14] + +#define EFUSE_HDCP_SW_KEY 0x0040u // (R/W) Specifies the software-provided HDCP test key. +#define EFUSE_HDCP_KEY_CTRL 0x0580u // (R/W) Specifies the HDCP key control register. + #define EFUSE_HDCP_KEY_CTRL_WRITE_KEY 0x01 + +//------------------------------------------------------------------------------ +// MARK: - HDMI CEC Registers (CEC_BASE) - +//------------------------------------------------------------------------------ + +#define CEC_TX_STATUS_0 0x0000u // (R/O) Specifies the CEC TX status #0. [0x00] +#define CEC_TX_STATUS_1 0x0004u // (R/O) Specifies the CEC TX status #1. [0x00] +#define CEC_RX_STATUS_0 0x0008u // (R/O) Specifies the CEC RX status #0. [0x00] +#define CEC_RX_STATUS_1 0x000Cu // (R/O) Specifies the CEC Rx status #1. [0x00] +#define CEC_INTR_MASK 0x0010u // (R/W) Specifies the CEC interrupt masking control. [0x00] +#define CEC_INTR_CLEAR 0x0014u // (R/W) Specifies the CEC interrupt clearing control. [0x00] +#define CEC_LOGIC_ADDR 0x0020u // (R/W) Specifies the HDMI Tx logical address. [0x0F] +#define CEC_DIVISOR_0 0x0030u // (R/W) Specifies the divisor used in counting 0.05ms. [0x00] +#define CEC_DIVISOR_1 0x0034u // (R/W) Specifies the divisor used in counting 0.05ms. [0x00] +#define CEC_DIVISOR_2 0x0038u // (R/W) Specifies the divisor used in counting 0.05ms. [0x00] +#define CEC_DIVISOR_3 0x003Cu // (R/W) Specifies the divisor used in counting 0.05ms. [0x00] +#define CEC_TX_CTRL 0x0040u // (R/W) Specifies the CEC Tx control. [0x50] +#define CEC_TX_BYTE_NUM 0x0044u // (R/W) Specifies the number of blocks in a message that has to be sent. [0x00] +#define CEC_TX_STATUS_2 0x0060u // (R/O) Specifies the CEC Tx status #2. [0x00] +#define CEC_TX_STATUS_3 0x0064u // (R/O) Specifies the CEC Tx status #3. [0x00] +#define CEC_TX_BUFFER_0 0x0080u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_1 0x0084u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_2 0x0088u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_3 0x008Cu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_4 0x0090u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_5 0x0094u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_6 0x0098u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_7 0x009Cu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_8 0x00A0u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_9 0x00A4u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_10 0x00A8u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_11 0x00ACu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_12 0x00B0u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_13 0x00B4u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_14 0x00B8u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_TX_BUFFER_15 0x00BCu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_CTRL 0x00C0u // (R/W) Specifies the CEC RX control. [0x00] +#define CEC_RX_STATUS_2 0x00E0u // (R/O) Specifies the CEC RX status #2. [0x00] +#define CEC_RX_STATUS_3 0x00E4u // (R/O) Specifies the CEC RX status #3. [0x00] +#define CEC_RX_BUFFER_0 0x0100u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_1 0x0104u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_2 0x0108u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_3 0x010Cu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_4 0x0110u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_5 0x0114u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_6 0x0118u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_7 0x011Cu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_8 0x0120u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_9 0x0124u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_10 0x0128u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_11 0x012Cu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_12 0x0130u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_13 0x0134u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_14 0x0138u // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_RX_BUFFER_15 0x013Cu // (R/W) Specifies the byte #0 to #15 of CEC message. [0x00] +#define CEC_FILTER_CTRL 0x0180u // (R/W) Specifies the CEC filter control. [0x81] +#define CEC_FILTER_TH 0x0184u // (R/W) Specifies the filter threshold value. [0x03] + +//------------------------------------------------------------------------------ +// MARK: - Control Registers (CTRL_BASE) - +//------------------------------------------------------------------------------ + +#define CTRL_INTC_CON_1 0x0010u // (R/W) Interrupt Control Register 1 [0x00] + +#define CTRL_INTC_FLAG_1 0x0014u // (R/W) Interrupt Flag Register 1 [0x00] + +#define CTRL_PHY_STATUS_0 0x0020u // (R/O) PHY status Register 0 [0x00] + #define CTRL_PHY_STATUS_0_PHY_READY 0x1 + +#define CTRL_PHY_STATUS_CMU 0x0024u // (R/O) PHY CMU status Register [0x00] + +#define CTRL_PHY_STATUS_PLL 0x0028u // (R/O) PHY PLL status Register [0x00] + +#define CTRL_PHY_CON_0 0x0030u // (R/W) PHY Control Register [0x01] + #define CTRL_PHY_CON_0_PHY_PWR_OFF 0x01 + +#define CTRL_HPD_CTRL 0x0040u // (R/W) HPD Signal Control Register [0x02] + +#define CTRL_HPD_ST 0x0044u // (R/W) HPD Status Register [0x00] + +#define CTRL_HPD_TH_x 0x0050u // (R/W) HPD filter threshold value Register [0x00] + +#define CTRL_AUDIO_CLKSEL 0x0070u // (R/W) Selects the audio system clock. [0x01] + +#define CTRL_PHY_RSTOUT 0x0074u // (R/W) Specifies the HDMI PHY reset out. [0x01] + +#define CTRL_PHY_VPLL 0x0078u // (R/O) Specifies the HDMI PHY VPLL monitor. [0x00] + +#define CTRL_PHY_CMU 0x007Cu // (R/O) Specifies the HDMI PHY CMU monitor. [0x00] + +#define CTRL_CORE_RSTOUT 0x0080u // (R/W) Specifies the HDMI TX core software reset. [0x01] + +#define CTRL_HDMI_VERSION_0 0x0100u // (R/O) Specifies the HDMI_LINK Version information. HDMI_VERSION[7:0] [0x08] +#define CTRL_HDMI_VERSION_1 0x0104u // (R/O) Specifies the HDMI_LINK Version information. HDMI_VERSION[15:8] [0x00] +#define CTRL_HDMI_VERSION_2 0x0108u // (R/O) Specifies the HDMI_LINK Version information. HDMI_VERSION[23:16] [0x00] +#define CTRL_HDMI_VERSION_3 0x010Cu // (R/O) Specifies the HDMI_LINK Version information. HDMI_VERSION[31:24] [0x00] + +//------------------------------------------------------------------------------ +// MARK: - HDMI Video Related Registers - +//------------------------------------------------------------------------------ + +// HDMI_CON_0 definitions + #define HDMI_CON_0_YCBCR422_SEL 0x08 // YCbCr Video Input Mode (0=4:4:4, 1=4:2:2) + +#define HDMI_V2_BLANK_0 0x00B0u // (R/W) Specifies the vertical blanking setting. [0x00] +#define HDMI_V2_BLANK_1 0x00B4u // (R/W) Specifies the vertical blanking setting. [0x00] +#define HDMI_V1_BLANK_0 0x00B8u // (R/W) Specifies the vertical blanking setting. [0x00] +#define HDMI_V1_BLANK_1 0x00BCu // (R/W) Specifies the vertical blanking setting. [0x00] + +#define HDMI_V_LINE_0 0x00C0u // (R/W) Specifies the horizontal line setting. [0x00] +#define HDMI_V_LINE_1 0x00C4u // (R/W) Specifies the horizontal line setting. [0x00] +#define HDMI_H_LINE_0 0x00C8u // (R/W) Specifies the vertical line setting. [0x00] +#define HDMI_H_LINE_1 0x00CCu // (R/W) Specifies the vertical line setting. [0x00] + +#define HDMI_HSYNC_POL 0x00E0u // (R/W) Specifies the Horizontal sync polarity control register [0x00] + +#define HDMI_V_BLANK_F0_0 0x0110u // (R/W) Specifies the vertical blanking setting for bottom field. [0xff] +#define HDMI_V_BLANK_F0_1 0x0114u // (R/W) Specifies the vertical blanking setting for bottom field. [0x1f] +#define HDMI_V_BLANK_F1_0 0x0118u // (R/W) Specifies the vertical blanking setting for bottom field. [0xff] +#define HDMI_V_BLANK_F1_1 0x011Cu // (R/W) Specifies the vertical blanking setting for bottom field. [0x1f] + +#define HDMI_H_SYNC_START_0 0x0120u // (R/W) Specifies Horizontal sync generation setting [0x00] +#define HDMI_H_SYNC_START_1 0x0124u // (R/W) Specifies Horizontal sync generation setting [0x00] + +#define HDMI_H_SYNC_END_0 0x0128u // (R/W) Specifies Horizontal sync generation setting [0x00] +#define HDMI_H_SYNC_END_1 0x012Cu // (R/W) Specifies Horizontal sync generation setting [0x00] + +#define HDMI_V_SYNC_LINE_BEF_2_0 0x0130u // (R/W) Specifies Vertical sync generation for top field or frame [0xff] +#define HDMI_V_SYNC_LINE_BEF_2_1 0x0134u // (R/W) Specifies Vertical sync generation for top field or frame [0x1f] +#define HDMI_V_SYNC_LINE_BEF_1_0 0x0138u // (R/W) Specifies Vertical sync generation for top field or frame [0xff] +#define HDMI_V_SYNC_LINE_BEF_1_1 0x013Cu // (R/W) Specifies Vertical sync generation for top field or frame [0x1f] + +#define HDMI_V_SYNC_LINE_AFT_2_0 0x0140u // (R/W) Specifies Vertical sync generation for bottom field - vertical position [0xff] +#define HDMI_V_SYNC_LINE_AFT_2_1 0x0144u // (R/W) Specifies Vertical sync generation for bottom field - vertical position [0x1f] +#define HDMI_V_SYNC_LINE_AFT_1_0 0x0148u // (R/W) Specifies Vertical sync generation for bottom field - vertical position [0xff] +#define HDMI_V_SYNC_LINE_AFT_1_1 0x014Cu // (R/W) Specifies Vertical sync generation for bottom field - vertical position [0x1f] + +#define HDMI_V_SYNC_LINE_AFT_PXL_2_0 0x0150u // (R/W) Specifies Vertical sync generation for bottom field - horizontal position [0xff] +#define HDMI_V_SYNC_LINE_AFT_PXL_2_1 0x0154u // (R/W) Specifies Vertical sync generation for bottom field - horizontal position [0x1f] +#define HDMI_V_SYNC_LINE_AFT_PXL_1_0 0x0158u // (R/W) Specifies Vertical sync generation for bottom field - horizontal position [0xff] +#define HDMI_V_SYNC_LINE_AFT_PXL_1_1 0x015Cu // (R/W) Specifies Vertical sync generation for bottom field - horizontal position [0x1f] + +#define HDMI_V_BLANK_F2_0 0x0160u // (R/W) Specifies Vertical blanking setting for third field [0xff] +#define HDMI_V_BLANK_F2_1 0x0164u // (R/W) Specifies Vertical blanking setting for third field [0x1f] +#define HDMI_V_BLANK_F3_0 0x0168u // (R/W) Specifies Vertical blanking setting for thrid field [0xff] +#define HDMI_V_BLANK_F3_1 0x016Cu // (R/W) Specifies Vertical blanking setting for thrid field [0x1f] + +#define HDMI_V_BLANK_F4_0 0x0170u // (R/W) Specifies Vertical blanking setting for fourth field [0xff] +#define HDMI_V_BLANK_F4_1 0x0174u // (R/W) Specifies Vertical blanking setting for fourth field [0x1f] +#define HDMI_V_BLANK_F5_0 0x0178u // (R/W) Specifies Vertical blanking setting for fourth field [0xff] +#define HDMI_V_BLANK_F5_1 0x017Cu // (R/W) Specifies Vertical blanking setting for fourth field [0x1f] + +#define HDMI_V_SYNC_LINE_AFT_3_0 0x0180u // (R/W) Specifies Vertical sync generation for third field - vertical position [0xff] +#define HDMI_V_SYNC_LINE_AFT_3_1 0x0184u // (R/W) Specifies Vertical sync generation for third field - vertical position [0x1f] +#define HDMI_V_SYNC_LINE_AFT_4_0 0x0188u // (R/W) Specifies Vertical sync generation for third field - vertical position [0xff] +#define HDMI_V_SYNC_LINE_AFT_4_1 0x018Cu // (R/W) Specifies Vertical sync generation for third field - vertical position [0x1f] + +#define HDMI_V_SYNC_LINE_AFT_5_0 0x0190u // (R/W) Specifies Vertical sync generation for fourth field - vertical position [0xff] +#define HDMI_V_SYNC_LINE_AFT_5_1 0x0194u // (R/W) Specifies Vertical sync generation for fourth field - vertical position [0x1f] +#define HDMI_V_SYNC_LINE_AFT_6_0 0x0198u // (R/W) Specifies Vertical sync generation for fourth field - vertical position [0xff] +#define HDMI_V_SYNC_LINE_AFT_6_1 0x019Cu // (R/W) Specifies Vertical sync generation for fourth field - vertical position [0x1f] + +#define HDMI_V_SYNC_LINE_AFT_PXL_3_0 0x01A0u // (R/W) Specifies Vertical sync generation for third field - horizontal position [0xff] +#define HDMI_V_SYNC_LINE_AFT_PXL_3_1 0x01A4u // (R/W) Specifies Vertical sync generation for third field - horizontal position [0x1f] +#define HDMI_V_SYNC_LINE_AFT_PXL_4_0 0x01A8u // (R/W) Specifies Vertical sync generation for third field - horizontal position [0xff] +#define HDMI_V_SYNC_LINE_AFT_PXL_4_1 0x01ACu // (R/W) Specifies Vertical sync generation for third field - horizontal position [0x1f] + +#define HDMI_V_SYNC_LINE_AFT_PXL_5_0 0x01B0u // (R/W) Specifies Vertical sync generation for fourth field - horizontal position [0xff] +#define HDMI_V_SYNC_LINE_AFT_PXL_5_1 0x01B4u // (R/W) Specifies Vertical sync generation for fourth field - horizontal position [0x1f] +#define HDMI_V_SYNC_LINE_AFT_PXL_6_0 0x01B8u // (R/W) Specifies Vertical sync generation for fourth field - horizontal position [0xff] +#define HDMI_V_SYNC_LINE_AFT_PXL_6_1 0x01BCu // (R/W) Specifies Vertical sync generation for fourth field - horizontal position [0x1f] + +#define HDMI_VACT_SPACE1_0 0x01C0u // (R/W) Specifies 1st Vertical Active Space start line [0xff] +#define HDMI_VACT_SPACE1_1 0x01C4u // (R/W) Specifies 1st Vertical Active Space end line [0x1f] +#define HDMI_VACT_SPACE2_0 0x01C8u // (R/W) Specifies 1st Vertical Active Space start line [0xff] +#define HDMI_VACT_SPACE2_1 0x01CCu // (R/W) Specifies 1st Vertical Active Space end line [0x1f] + +#define HDMI_VACT_SPACE3_0 0x01D0u // (R/W) Specifies 2nd Vertical Active Space start line [0xff] +#define HDMI_VACT_SPACE3_1 0x01D4u // (R/W) Specifies 2nd Vertical Active Space end line [0x1f] +#define HDMI_VACT_SPACE4_0 0x01D8u // (R/W) Specifies 2nd Vertical Active Space start line [0xff] +#define HDMI_VACT_SPACE4_1 0x01DCu // (R/W) Specifies 2nd Vertical Active Space end line [0x1f] + +#define HDMI_VACT_SPACE5_0 0x01E0u // (R/W) Specifies 3rd Vertical Active Space start line [0xff] +#define HDMI_VACT_SPACE5_1 0x01E4u // (R/W) Specifies 3rd Vertical Active Space end line [0x1f] +#define HDMI_VACT_SPACE6_0 0x01E8u // (R/W) Specifies 3rd Vertical Active Space start line [0xff] +#define HDMI_VACT_SPACE6_1 0x01ECu // (R/W) Specifies 3rd Vertical Active Space end line [0x1f] + +#define HDMI_GCP_CON 0x0200u // (R/W) Specifies GCP packet control register [0x04] +#define HDMI_GCP_BYTE1 0x0210u // (R/W) Specifies GCP packet body [0x00] +#define HDMI_GCP_BYTE2 0x0214u // (R/W) Specifies GCP packet body [0x00] +#define HDMI_GCP_BYTE3 0x0218u // (R/W) Specifies GCP packet body [0x00] + +//------------------------------------------------------------------------------ +// MARK: - HDMI Audio Related Registers - +//------------------------------------------------------------------------------ + +#define HDMI_ASP_CON 0x0300u // (R/W) Specifies the ASP packet control register. [0x00] +#define HDMI_ASP_SP_FLAT 0x0304u // (R/W) Specifies the ASP packet sp_flat bit control. [0x00] +#define HDMI_ASP_CHCFG0 0x0310u // (R/W) Specifies the ASP audio channel configuration. [0x08] +#define HDMI_ASP_CHCFG1 0x0314u // (R/W) Specifies the ASP audio channel configuration. [0x1a] +#define HDMI_ASP_CHCFG2 0x0318u // (R/W) Specifies the ASP audio channel configuration. [0x2c] +#define HDMI_ASP_CHCFG3 0x031Cu // (R/W) Specifies the ASP audio channel configuration. [0x3e] + +#define HDMI_ACR_CON 0x0400u // (R/W) Specifies the ACR packet control register. [0x00] + +#define HDMI_ACR_MCTS0 0x0410u // (R/W) Specifies the measured CTS value. [0x01] +#define HDMI_ACR_MCTS1 0x0414u // (R/W) Specifies the measured CTS value. [0x00] +#define HDMI_ACR_MCTS2 0x0418u // (R/W) Specifies the measured CTS value. [0x00] + +#define HDMI_ACR_N0 0x0430u // (R/W) Specifies the N value for ACR packet. [0xe8] +#define HDMI_ACR_N1 0x0434u // (R/W) Specifies the N value for ACR packet. [0x03] +#define HDMI_ACR_N2 0x0438u // (R/W) Specifies the N value for ACR packet. [0x00] + +//------------------------------------------------------------------------------ +// MARK: - HDMI Packet Related Registers - +//------------------------------------------------------------------------------ + +#define HDMI_ACP_CON 0x0500u // (R/W) Specifies the ACP packet control register. [0x00] +#define HDMI_ACP_TYPE 0x0514u // (R/W) Specifies the ACP packet header. [0x00] +#define HDMI_ACP_DATA00 0x0520u // (R/W) Specifies the ACP packet body. [0x00] + +#define HDMI_ISRC_CON 0x0600u // (R/W) Specifies the ACR packet control register. [0x00] +#define HDMI_ISRC1_HEADER1 0x0614u // (R/W) Specifies the ISCR1 packet header. [0x00] +#define HDMI_ISRC1_DATA00 0x0620u // (R/W) Specifies the ISRC1 packet body. [0x00] +#define HDMI_ISRC2_DATA00 0x06A0u // (R/W) Specifies the ISRC2 packet body. [0x00] + +#define HDMI_AVI_CON 0x0700u // (R/W) Specifies the AVI packet control register. [0x00] +#define HDMI_AVI_HEADER0 0x0710u // (R/W) Specifies the AVI packet header. [0x00] +#define HDMI_AVI_HEADER1 0x0714u // (R/W) Specifies the AVI packet header. [0x00] +#define HDMI_AVI_HEADER2 0x0718u // (R/W) Specifies the AVI packet header. [0x00] +#define HDMI_AVI_CHECK_SUM 0x071Cu // (R/W) Specifies the AVI packet checksum. [0x00] +#define HDMI_AVI_BYTE01 0x0720u // (R/W) Specifies the AVI packet body. [0x00] + +#define HDMI_AUI_CON 0x0800u // (R/W) Specifies the AUI packet control register. [0x00] +#define HDMI_AUI_HEADER0 0x0810u // (R/W) Specifies AUI packet header. [0x00] +#define HDMI_AUI_HEADER1 0x0814u // (R/W) Specifies AUI packet header. [0x00] +#define HDMI_AUI_HEADER2 0x0818u // (R/W) Specifies AUI packet header. [0x00] +#define HDMI_AUI_CHECK_SUM 0x081Cu // (R/W) Specifies the AUI packet checksum. [0x00] +#define HDMI_AUI_BYTE1 0x0820u // (R/W) Specifies the AUI packet body. [0x00] + +#define HDMI_MPG_CON 0x0900u // (R/W) Specifies the ACR packet control register. [0x00] +#define HDMI_MPG_CHECK_SUM 0x091Cu // (R/W) Specifies the MPG packet checksum. [0x00] +#define HDMI_MPG_BYTE1 0x0920u // (R/W) Specifies the MPG packet body. [0x00] + +#define HDMI_SPD_CON 0x0A00u // (R/W) Specifies the SPD packet control register. [0x00] +#define HDMI_SPD_HEADER0 0x0A10u // (R/W) Specifies the SPD packet header. [0x00] +#define HDMI_SPD_HEADER1 0x0A14u // (R/W) Specifies the SPD packet header. [0x00] +#define HDMI_SPD_HEADER2 0x0A18u // (R/W) Specifies the SPD packet header. [0x00] +#define HDMI_SPD_DATA00 0x0A20u // (R/W) Specifies the SPD packet checksum. [0x00] +#define HDMI_SPD_DATA01 0x0A24u // (R/W) Specifies the SPD packet body. [0x00] + +#define HDMI_GAMUT_CON 0x0B00u // (R/W) Specifies GAMUT packet control register. [0x00] +#define HDMI_GAMUT_HEADER0 0x0B10u // (R/W) Specifies GAMUT packet header. [0x00] +#define HDMI_GAMUT_HEADER1 0x0B14u // (R/W) Specifies GAMUT packet header. [0x00] +#define HDMI_GAMUT_HEADER2 0x0B18u // (R/W) Specifies GAMUT packet header. [0x00] +#define HDMI_GAMUT_METADATA00 0x0B20u // (R/W) Specifies GAMUT packet body. [0x00] + +#define HDMI_VSI_CON 0x0C00u // (R/W) Specifies VSI packet control register. [0x00] +#define HDMI_VSI_HEADER0 0x0C10u // (R/W) Specifies VSI packet header. [0x00] +#define HDMI_VSI_HEADER1 0x0C14u // (R/W) Specifies VSI packet header. [0x00] +#define HDMI_VSI_HEADER2 0x0C18u // (R/W) Specifies VSI packet header. [0x00] +#define HDMI_VSI_DATA00 0x0C20u // (R/W) Specifies VSI packet checksum. [0x00] +#define HDMI_VSI_DATA01 0x0C24u // (R/W) Specifies VSI packet body. [0x00] + +//------------------------------------------------------------------------------ +// MARK: - HDMI Miscellaneous Registers - +//------------------------------------------------------------------------------ + +#define HDMI_DC_CONTROL 0x0D00u // (R/W) Specifies Deep Color Control Register [0x00] + +#define HDMI_VIDEO_PATTERN_GEN 0x0D04u // (R/W) Specifies Video Pattern Generation Register [0x00] + +#define HDMI_An_Seed_Sel 0x0E48u // (R/W) An seed selection register [0xFF] +#define HDMI_An_Seed_0 0x0E58u // (R/W) An seed value register [0x00] +#define HDMI_An_Seed_1 0x0E5Cu // (R/W) An seed value register [0x00] +#define HDMI_An_Seed_2 0x0E60u // (R/W) An seed value register [0x00] +#define HDMI_An_Seed_3 0x0E64u // (R/W) An seed value register [0x00] + +#define HDMI_RGB_ROUND_EN 0xD500u // (R/W) Specifies round enable for 8/10 bit R/G/B in video_receiver [0x00] + +#define HDMI_VACT_SPACE_R_0 0xD504u // (R/W) Specifies vertical active space R [0x00] +#define HDMI_VACT_SPACE_R_1 0xD508u // (R/W) Specifies vertical active space R [0x00] +#define HDMI_VACT_SPACE_G_0 0xD50Cu // (R/W) Specifies vertical active space G [0x00] +#define HDMI_VACT_SPACE_G_1 0xD510u // (R/W) Specifies vertical active space G [0x00] +#define HDMI_VACT_SPACE_B_0 0xD514u // (R/W) Specifies vertical active space B [0x00] +#define HDMI_VACT_SPACE_B_1 0xD518u // (R/W) Specifies vertical active space B [0x00] + +#define HDMI_BLUE_SCREEN_R_0 0xD520u // (R/W) Specifies R Pixel values for blue screen [3:0] [0x00] +#define HDMI_BLUE_SCREEN_R_1 0xD524u // (R/W) Specifies R Pixel values for blue screen [11:4] [0x00] +#define HDMI_BLUE_SCREEN_G_0 0xD528u // (R/W) Specifies G Pixel values for blue screen [3:0] [0x00] +#define HDMI_BLUE_SCREEN_G_1 0xD52Cu // (R/W) Specifies G Pixel values for blue screen [11:4] [0x00] +#define HDMI_BLUE_SCREEN_B_0 0xD530u // (R/W) Specifies B Pixel values for blue screen [3:0] [0x00] +#define HDMI_BLUE_SCREEN_B_1 0xD534u // (R/W) Specifies B Pixel values for blue screen [11:4] [0x00] + +//------------------------------------------------------------------------------ +// MARK: - Timing Generator Registers (TG_BASE) - +//------------------------------------------------------------------------------ + +#define TG_VACT_ST3_L 0x0068u // (R/W) Specifies the HDMI vertical active start position for 3rd bottom field. [0x7B] +#define TG_VACT_ST3_H 0x006Cu // (R/W) Specifies the HDMI vertical active start position for 3rd bottom field. [0x04] + +#define TG_VACT_ST4_L 0x0070u // (R/W) Specifies the HDMI vertical active start position for 4th bottom field. [0xAE] +#define TG_VACT_ST4_H 0x0074u // (R/W) Specifies the HDMI vertical active start position for 4th bottom field. [0x06] + +#define TG_3D_FP 0x00F0u // (R/W) Specifies the Stereoscopy timing enable [0x00] + +//------------------------------------------------------------------------------ +// MARK: - I2C Bridge / HDMI PHY Registers (I2C_BASE) - +//------------------------------------------------------------------------------ + +// Note: Most IIC definitions based on AppleS5L8900XI2C/AppleS5L8747XI2C, which is the same controller + +#define IICCON 0x0000u // (R/W) Control register [0x0000_0000] + #define kIICConAckGen (0x00000080) + #define kIICConBusHold (0x00000010) + +#define IICSTAT 0x0004u // (R/W) Control/status register [0x0000_0000] + #define kIICStatMaster (0x00000080) + #define kIICStatTx (0x00000040) + #define kIICStatBB (0x00000020) + #define kIICStatSOE (0x00000010) + #define kIICStatLRB (0x00000001) + +#define IICADD 0x0008u // (R/W) Bus address register [0x0000_0000] +#define IICDS 0x000Cu // (R/W) Transmit/receive data shift register [0x0000_0000] +#define FIFOCON 0x0018u // (R/W) Tx/Rx FIFO control register [0x0000_0000] +#define FIFOSTAT 0x001Cu // (R/W) Tx/Rx FIFO status register [0x0000_0000] + +#define IICINT 0x0020u // (R/W) Interrupt status register [0x0000_X000] + #define kIICIntAll (0x00003F00u) + #define kIICIntStop (0x00002000u) + #define kIICIntStart (0x00001000u) + #define kIICIntTx (0x00000800u) + #define kIICIntRx (0x00000400u) + #define kIICIntTimeOut (0x00000200u) + #define kIICIntBusHold (0x00000100u) + +#define IICVER 0x0024u // (R/O) Version register [0x0000_0007] +#define SW_RESET 0x002Cu // (R/W) Software reset register [0x0000_0000] + #define kIICSwReset (0x00000001) + +#define IICBUSCON 0x0030u // (R/W) Bus control register [0x0000_0000] +#define TIMEOUT_CON 0x0034u // (R/W) Internal timer setting register [0xFFFF_FFFF] + +#define HDMIPHY_ID 0x0080u // (R/W) I2C device ID of HDMI PHY [0x0000_0000] + +#define HDMIPHYCON_STAT 0x0084u // (R/O) Status of write operation to HDMIPHYCON0~8 [0x0000_0000] + #define HDMIPHYCON_STAT_IN_PROGRESS 0x1 + +#define HDMIPHYCON0 0x80088 // (R/W) Reg00~Reg03 of HDMI PHY [0x101F_9101] +#define HDMIPHYCON1 0x8008C // (R/W) Reg04~Reg07 of HDMI PHY [0x08EF_5B40] +#define HDMIPHYCON2 0x80090 // (R/W) Reg08~Reg0B of HDMI PHY [0xD8B9_2081] +#define HDMIPHYCON3 0x80094 // (R/W) Reg0C~Reg0F of HDMI PHY [0x80AC_A045] +#define HDMIPHYCON4 0x80098 // (R/W) Reg10~Reg13 of HDMI PHY [0x8412_8008] +#define HDMIPHYCON5 0x8009C // (R/W) Reg14~Reg17 of HDMI PHY [0x8624_2408] +#define HDMIPHYCON6 0x800A0 // (R/W) Reg18~Reg1B of HDMI PHY [0x0124_A654] +#define HDMIPHYCON7 0x800A4 // (R/W) Reg1C~Reg1E of HDMI PHY [0x0001_0000] +#define HDMIPHYCON8 0x800A8 // (R/W) Reg1F of HDMI PHY [0x0000_0080] + +#endif /* !_REGS_H */ diff --git a/drivers/samsung/hdmi8947/rules.mk b/drivers/samsung/hdmi8947/rules.mk new file mode 100644 index 0000000..6dedf2f --- /dev/null +++ b/drivers/samsung/hdmi8947/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += + +ALL_OBJS += \ + $(LOCAL_DIR)/hdmi.o \ + $(LOCAL_DIR)/hdmi_static_config.o diff --git a/drivers/samsung/mipi/dsim.c b/drivers/samsung/mipi/dsim.c new file mode 100644 index 0000000..2605839 --- /dev/null +++ b/drivers/samsung/mipi/dsim.c @@ -0,0 +1,507 @@ +/* + * Copyright (C) 2008-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#include "dsim.h" + +#define DISPLAY_CONFIG_PLL_P(x) (((x) >> 26) & 0x03F) +#define DISPLAY_CONFIG_PLL_M(x) (((x) >> 16) & 0x3FF) +#define DISPLAY_CONFIG_PLL_S(x) (((x) >> 12) & 0x007) +#define DISPLAY_CONFIG_PLL_B(x) (((x) >> 8) & 0x00F) +#define DISPLAY_CONFIG_ESC_DIV(x) (((x) >> 4) & 0x00F) +#define DISPLAY_CONFIG_LANES(x) (((x) >> 0) & 0x00F) + +#define DSIM_LANE_MASK ((1 << DSIM_LANE_COUNT) - 1) + +static u_int32_t lane_count; +static u_int32_t lane_mask; +static uint32_t esc_clock_div; + +static bool dsim_enabled; + +int mipi_dsim_init(struct display_timing *timing, enum colorspace color) +{ + bool video_mode = true; + u_int32_t tmp, pll_config, pix_format, afc_code = 0; + u_int32_t config = rDSIM_CONFIG_HfpMode; + bool afc_enable = false; + uint32_t display_config; + + dprintf(DEBUG_CRITICAL, "mipi_dsim_init()\n"); + + memcpy(&display_config, timing->display_config, sizeof(display_config)); + // Extract Lane configuration + lane_count = DISPLAY_CONFIG_LANES(display_config); + lane_mask = (1 << lane_count) - 1; + + // Extract PLL configuration + pll_config = (rDSIM_PLLCTRL_P(DISPLAY_CONFIG_PLL_P(display_config)) | + rDSIM_PLLCTRL_M(DISPLAY_CONFIG_PLL_M(display_config)) | + rDSIM_PLLCTRL_S(DISPLAY_CONFIG_PLL_S(display_config))); + + // Extract Pixel Format + if (timing->display_depth <= 18) pix_format = 5; + else pix_format = 7; + + //Extract escape clock divisor + esc_clock_div = DISPLAY_CONFIG_ESC_DIV(display_config); + + clock_gate(CLK_MIPI, true); + + // Configure clock selections + rDSIM_CLKCTRL = (rDSIM_CLKCTRL_EscClkEn | + ((pll_config == 0) ? rDSIM_CLKCTRL_PllBypass : 0) | + rDSIM_CLKCTRL_ByteClkSrc((pll_config == 0) ? 1 : 0) | // SOC or DSIM PLL + rDSIM_CLKCTRL_EscPrescalar(DISPLAY_CONFIG_ESC_DIV(display_config))); + + // Select frequency band + rDSIM_PLLCTRL = rDSIM_PLLCTRL_FreqBand(DISPLAY_CONFIG_PLL_B(display_config)); + +#ifdef TARGET_DSIM_THS_PREPARE + //Adjust tHS-PREPARE on the phy + rDSIM_PLLCTRL |= rDSIM_PLLCTRL_PreprCtl(TARGET_DSIM_THS_PREPARE); +#endif //TARGET_DSIM_THS_PREPARE + + // Configure PLL if needed + if (pll_config != 0) { +#if DSIM_VERSION == 1 + u_int32_t fin_pll; + + // Assume that AFC will be used + afc_enable = true; + + // Set the AFC code in PHYACCHR + fin_pll = clock_get_frequency(CLK_NCLK) / (1000000 * DISPLAY_CONFIG_PLL_P(display_config)); + + // These code values are only for the 45nm PHY (i.e. DSIM_VERSION == 1) + switch (fin_pll) { + case 6: afc_code = 1; break; + case 7: afc_code = 0; break; + case 8: afc_code = 3; break; + case 9: afc_code = 2; break; + case 10: afc_code = 5; break; + case 11: afc_code = 4; break; + case 12: afc_code = 4; break; + default : afc_enable = false; break; + } +#endif + + // If needed, enable AFC + if (afc_enable) { + rDSIM_PHYACCHR = rDSIM_PHYACCHR_AFC(afc_code) | rDSIM_PHYACCHR_AFC_ENABLE; + } + + rDSIM_PLLTMR = 300000; // 1ms - HACK: assuming 300MHz hperf2 + + rDSIM_PLLCTRL |= pll_config; + rDSIM_PLLCTRL |= rDSIM_PLLCTRL_PllEn; + + while ((rDSIM_STATUS & rDSIM_STATUS_PllStable) == 0); + } + + // Issue software reset + rDSIM_SWRST = rDSIM_SWRST_SwRst; + + // If needed, enable AFC again + if (afc_enable) { + // PLL must be off to change AFC setting + rDSIM_PLLCTRL &= ~rDSIM_PLLCTRL_PllEn; + + rDSIM_PHYACCHR = rDSIM_PHYACCHR_AFC(afc_code) | rDSIM_PHYACCHR_AFC_ENABLE; + + // Turn PLL back on + rDSIM_PLLCTRL |= rDSIM_PLLCTRL_PllEn; + } + + // Wait for software reset to complete + while ((rDSIM_STATUS & rDSIM_STATUS_SwRstRls) == 0); + +#ifdef TARGET_DSIM_DPHYCTL + rDSIM_PHYACCHR |= rDSIM_PHYACCHR_DPHYCTL(TARGET_DSIM_DPHYCTL); +#endif // TARGET_DSIM_DPHYCTL + +#if TARGET_DSIM_DOWN_CODE + rDSIM_PHYACCHR |= rDSIM_PHYACCHR_DOWN_CODE(TARGET_DSIM_DOWN_CODE); + rDSIM_PHYACCHR2 |= rDSIM_PHYACCHR2_DOWN_CODE(TARGET_DSIM_DOWN_CODE); +#endif // TARGET_DSIM_DOWN_CODE + +#ifdef TARGET_DSIM_UP_CODE + rDSIM_PHYACCHR |= rDSIM_PHYACCHR_UP_CODE(TARGET_DSIM_UP_CODE); + rDSIM_PHYACCHR2 |= rDSIM_PHYACCHR2_UP_CODE(TARGET_DSIM_UP_CODE); +#endif // TARGET_DSIM_UP_CODE + +#ifdef TARGET_DSIM_SUPPRESS + rDSIM_SUPPRESS |= TARGET_DSIM_SUPPRESS; +#endif // TARGET_DSIM_SUPPRESS + + // Use the same resolution as CLCD + rDSIM_MDRESOL = (rDSIM_MDRESOL_MainVResol(timing->v_active) | + rDSIM_MDRESOL_MainHResol(timing->h_active)); + +#ifdef TARGET_DISP_VIDEO_MODE + video_mode = TARGET_DISP_VIDEO_MODE; +#endif //TARGET_DISP_VIDEO_MODE + + if (video_mode) { + // The vertical blanking settings are the same as the CLCD settings + rDSIM_MVPORCH = (rDSIM_MVPORCH_CmdAllow(13) | + rDSIM_MVPORCH_StableVfp(timing->v_front_porch) | + rDSIM_MVPORCH_MainVbp(timing->v_back_porch)); + rDSIM_MSYNC = (timing->v_pulse_width << 22); + + // The horizontal blanking settings are constants which are + // sufficent for all lane counts, frequencies and CLCD settings + // Hfp = 15 + // Hbp = 14 + // Hsa = 1 + rDSIM_MHPORCH = (15 << 16) | (14 << 0); + rDSIM_MSYNC |= (1 << 0); + } +#if DSIM_VERSION == 3 + else { + rDSIM_I80_LPVALID_ST = (timing->h_active * 3) + 100; + } +#endif // DSIM_VERSION == 3 + + rDSIM_SSCNT = 0xa; + +#ifdef TARGET_DSIM_CONFIG + config = TARGET_DSIM_CONFIG; +#endif + + rDSIM_CONFIG = (rDSIM_CONFIG_BurstMode | + rDSIM_CONFIG_AutoMode | + config | + rDSIM_CONFIG_MainPixFormat(pix_format) | + rDSIM_CONFIG_NumOfDatLane(DSIM_LANE_COUNT - 1) | + rDSIM_CONFIG_LaneEn(DSIM_LANE_MASK) | + rDSIM_CONFIG_LaneClkEn); + if (video_mode) { + rDSIM_CONFIG |= rDSIM_CONFIG_VideoMode; + } + +#ifdef TARGET_NO_BURST_MODE + if (TARGET_NO_BURST_MODE) { + rDSIM_CONFIG &= ~rDSIM_CONFIG_BurstMode; + } +#endif + rDSIM_CLKCTRL |= (rDSIM_CLKCTRL_ByteClkEn | + rDSIM_CLKCTRL_LaneEscClkEn(DSIM_LANE_MASK) | + rDSIM_CLKCTRL_LaneEscClkEnClk); + + rDSIM_FIFOCTRL = 0x1F; + rDSIM_FIFOTHLD = 0x1FF; + + // Force Stop state on all lanes + rDSIM_ESCMODE = (rDSIM_ESCMODE_CmdLpdt | rDSIM_ESCMODE_ForceStopstate); + spin(1 * 1000); + rDSIM_ESCMODE &= ~rDSIM_ESCMODE_ForceStopstate; + + // Wait for Stop state on all lanes + tmp = rDSIM_STATUS_StopstateClk | rDSIM_STATUS_StopstateDat(DSIM_LANE_MASK); + while ((rDSIM_STATUS & tmp) != tmp); + + // Request ULPS mode on all lanes + rDSIM_ESCMODE = (rDSIM_ESCMODE_CmdLpdt | rDSIM_ESCMODE_TxUlpsClk | rDSIM_ESCMODE_TxUlpsDat); + + // Wait for ULPS mode on all lanes + tmp = rDSIM_STATUS_UlpsClk | rDSIM_STATUS_UlpsDat(DSIM_LANE_MASK); + while ((rDSIM_STATUS & tmp) != tmp); + + // Set the lane configuration + rDSIM_CONFIG &= ~(rDSIM_CONFIG_NumOfDatLaneMsk | rDSIM_CONFIG_LaneEnMsk); + rDSIM_CONFIG |= rDSIM_CONFIG_NumOfDatLane(lane_count - 1) | rDSIM_CONFIG_LaneEn(lane_mask); + + // Enable the configured lanes + rDSIM_CLKCTRL &= ~rDSIM_CLKCTRL_LaneEscClkEnMsk; + rDSIM_CLKCTRL |= rDSIM_CLKCTRL_LaneEscClkEn(lane_mask); + + // Request exit ULPS mode on configured lanes + rDSIM_ESCMODE |= (rDSIM_ESCMODE_TxUlpsClkExit | rDSIM_ESCMODE_TxUlpsExit); + + // Wait for exit ULPS mode on configured lanes + tmp = rDSIM_STATUS_UlpsClk | rDSIM_STATUS_UlpsDat(lane_mask); + while ((rDSIM_STATUS & tmp) != 0); + + // Clear exit ULPS mode request and ULPS mode request + rDSIM_ESCMODE &= ~(rDSIM_ESCMODE_TxUlpsClkExit | rDSIM_ESCMODE_TxUlpsExit); + spin(1 * 1000); + rDSIM_ESCMODE &= ~(rDSIM_ESCMODE_TxUlpsClk | rDSIM_ESCMODE_TxUlpsDat); + + // Wait for Stop state on configured lanes + tmp = rDSIM_STATUS_StopstateClk | rDSIM_STATUS_StopstateDat(lane_mask); + while ((rDSIM_STATUS & tmp) != tmp); + +#if DSIM_VERSION == 3 + if (!video_mode) { + rDSIM_ULPSIN = TARGET_DSI_ULPS_IN_DELAY; + rDSIM_ULPSEND = TARGET_DSI_ULPS_END_DELAY; + rDSIM_ULPSOUT = TARGET_DSI_ULPS_OUT_DELAY; + + // SkiHillVail12S5356c: panic(cpu 0 caller 0x855223df): "_waitUntilPayloadFifoIsEmpty: Timeout Waiting for payload fifo to empty" + rDSIM_ESCMODE |= rDSIM_ESCMODE_Auto_Ulps_Clk; + } + +#endif //DSIM_VERSION == 3 + + dsim_enabled = true; + + return 0; +} + +int mipi_dsim_quiesce(void) +{ + u_int32_t tmp, pllctrl, phyacchr; + + dprintf(DEBUG_CRITICAL, "mipi_dsim_quiesce()\n"); + + if (!dsim_enabled) return 0; + + // Save the PLLCTRL and PHYACCHR settings before software reset + pllctrl = rDSIM_PLLCTRL; + phyacchr = rDSIM_PHYACCHR; + + // Issue software reset + rDSIM_SWRST = rDSIM_SWRST_SwRst; + + // Turn off the PLL if it was on + rDSIM_PLLCTRL = pllctrl & ~rDSIM_PLLCTRL_PllEn; + + // Restore PHYACCHR setting + rDSIM_PHYACCHR = phyacchr; + + // If the PLL was on, turn it back on + rDSIM_PLLCTRL = pllctrl; + + // Wait for reset to complete + while ((rDSIM_STATUS & rDSIM_STATUS_SwRstRls) == 0); + + // Set the lane configuration + rDSIM_CONFIG &= ~(rDSIM_CONFIG_NumOfDatLaneMsk | rDSIM_CONFIG_LaneEnMsk); + rDSIM_CONFIG |= (rDSIM_CONFIG_NumOfDatLane(DSIM_LANE_COUNT - 1) | + rDSIM_CONFIG_LaneEn(DSIM_LANE_MASK) | + rDSIM_CONFIG_LaneClkEn); + + // Enable the configured lanes + rDSIM_CLKCTRL &= ~(rDSIM_CLKCTRL_TxRequestHsClk | rDSIM_CLKCTRL_LaneEscClkEnMsk); + rDSIM_CLKCTRL |= rDSIM_CLKCTRL_LaneEscClkEn(DSIM_LANE_MASK); + + // Force Stop state on all lanes + rDSIM_ESCMODE = (rDSIM_ESCMODE_CmdLpdt | rDSIM_ESCMODE_ForceStopstate); + spin(1 * 1000); + rDSIM_ESCMODE &= ~rDSIM_ESCMODE_ForceStopstate; + + // Wait for Stop state on all lanes + tmp = rDSIM_STATUS_StopstateClk | rDSIM_STATUS_StopstateDat(DSIM_LANE_MASK); + while ((rDSIM_STATUS & tmp) != tmp); + + // Request ULPS mode on all lanes + rDSIM_ESCMODE = (rDSIM_ESCMODE_CmdLpdt | rDSIM_ESCMODE_TxUlpsClk | rDSIM_ESCMODE_TxUlpsDat); + + // Wait for ULPS mode on all lanes + tmp = rDSIM_STATUS_UlpsClk | rDSIM_STATUS_UlpsDat(DSIM_LANE_MASK); + while ((rDSIM_STATUS & tmp) != tmp); + + // Turn off internal clocks + rDSIM_CLKCTRL = 0x00000000; + rDSIM_CONFIG = rDSIM_CONFIG_VideoMode; + rDSIM_ESCMODE = 0x00000000; + rDSIM_PLLCTRL = 0x00000000; + + clock_gate(CLK_MIPI, false); + + dsim_enabled = false; + + return 0; +} + +void mipi_dsim_enable_high_speed(bool enable) +{ + if (enable) { + rDSIM_CLKCTRL |= rDSIM_CLKCTRL_TxRequestHsClk; + while ((rDSIM_STATUS & rDSIM_STATUS_TxReadyHsClk) == 0); + } else { + rDSIM_CLKCTRL &= ~rDSIM_CLKCTRL_TxRequestHsClk; + while ((rDSIM_STATUS & rDSIM_STATUS_TxReadyHsClk) != 0); + } +} + +void mipi_dsim_enable_video(bool enable) +{ + if (enable) { + rDSIM_MDRESOL |= rDSIM_MDRESOL_MainStandby; + } else { + rDSIM_MDRESOL &= ~rDSIM_MDRESOL_MainStandby; + } +} + +int mipi_dsim_send_short_command(u_int8_t cmd, u_int8_t data0, u_int8_t data1) +{ + uint32_t escape_clock_period_us; + uint32_t mipi_byte_clock_frequency; + + mipi_byte_clock_frequency = clock_get_frequency(CLK_MIPI)/ 8; + escape_clock_period_us = (100000000 * esc_clock_div) /mipi_byte_clock_frequency; + escape_clock_period_us = (escape_clock_period_us/100) < 1 ? 1 : (escape_clock_period_us/100); + + rDSIM_PKTHDR = (cmd & 0x3f) | (((u_int32_t)data0) << 8) | (((u_int32_t)data1) << 16); + + //10 ESC clocks before checking the status bit. + spin (10 * escape_clock_period_us); + + //check for command header to have been sent + while ((rDSIM_FIFOCTRL & rDSIM_FIFOCTRL_EmptyHSfr) == 0); + //check for command payload to have been sent + while ((rDSIM_FIFOCTRL & rDSIM_FIFOCTRL_EmptyLSfr) == 0); + + spin(22 + ((343 * 1000000 * esc_clock_div)/mipi_byte_clock_frequency)); + + return 0; +} + +int mipi_dsim_send_long_command(u_int8_t cmd, const u_int8_t *data, u_int32_t length) +{ + u_int32_t cnt, payload = 0; + + for (cnt = 0; cnt < length; cnt++) { + payload = (payload >> 8) | ((u_int32_t)data[cnt] << 24); + if ((cnt & 3) == 3) { + rDSIM_PAYLOAD = payload; + payload = 0; + } + } + if (payload) { + payload >>= 32 - ((length & 3) * 8); + rDSIM_PAYLOAD = payload; + } + + for (cnt = 0; cnt < 5; cnt++) { + rDSIM_PAYLOAD = 0; + } + + length += 20; + return mipi_dsim_send_short_command(cmd, length & 0xff, (length >> 8) & 0xff); +} + +int mipi_dsim_read_short_command(u_int8_t cmd, u_int8_t *data) +{ + u_int32_t tmp, i = 0; + + // Clear pending interrupts + rDSIM_INTSRC = 0xffffffff; + + mipi_dsim_send_short_command(cmd, data[0], data[1]); + + while (1) { + tmp = rDSIM_INTSRC; + + if (tmp & rDSIM_INTSRC_RxAck) return -1; + if (tmp & rDSIM_INTSRC_LpdrTout) return -1; + // Ignore errors for now (not all drivers do ECC) +// if (tmp & rDSIM_INTSRC_AnyError) return -1; + + if (tmp & rDSIM_INTSRC_RxDatDone) break; + + // Hardware timeout depends on having a receiver, and + // completing BTA. This isn't guaranteed for dev boards. + if (++i == 5) { + dprintf(DEBUG_CRITICAL, "mipi: timing out\n"); + return -1; + } + spin(50 * 1000); + } + + while (rDSIM_FIFOCTRL & rDSIM_FIFOCTRL_EmptyRx); + + tmp = rDSIM_RXFIFO; + + switch (tmp & 0x3f) { + case DSIM_RSP_READ_1B: + case DSIM_RSP_DSC_READ_1B: + data[0] = (tmp >> 8) & 0xff; + data[1] = 0; + break; + case DSIM_RSP_READ_2B: + case DSIM_RSP_DSC_READ_2B: + data[0] = (tmp >> 8) & 0xff; + data[1] = (tmp >> 16) & 0xff; + break; + default: + return -1; + } + + return 0; +} + +int mipi_dsim_read_long_command(u_int8_t cmd, u_int8_t *data, u_int32_t *length) +{ + u_int32_t tmp, len, maxlen, i = 0; + + maxlen = *length; + + // Clear pending interrupts + rDSIM_INTSRC = 0xffffffff; + + mipi_dsim_send_short_command(cmd, data[0], data[1]); + + while (1) { + tmp = rDSIM_INTSRC; + + if (tmp & rDSIM_INTSRC_RxAck) return -1; + if (tmp & rDSIM_INTSRC_LpdrTout) return -1; + // Ignore errors for now (not all drivers do ECC) +// if (tmp & rDSIM_INTSRC_AnyError) return -1; + + if (tmp & rDSIM_INTSRC_RxDatDone) break; + + // Hardware timeout depends on having a receiver, and + // completing BTA. This isn't guaranteed for dev boards. + if (++i == 5) { + dprintf(DEBUG_CRITICAL, "mipi: timing out\n"); + return -1; + } + spin(50 * 1000); + } + + while (rDSIM_FIFOCTRL & rDSIM_FIFOCTRL_EmptyRx); + + tmp = rDSIM_RXFIFO; + + switch (tmp & 0x3f) { + case DSIM_RSP_LONG_READ: + case DSIM_RSP_DSC_LONG_READ: + break; + default: + dprintf(DEBUG_CRITICAL, "mipi: weird response %08x\n", tmp); + return -1; + } + + len = (tmp >> 8) & 0xffff; + if (len < maxlen) + *length = len; + + for (i = 0; i < len; i++) { + if ((i % 4) == 0) { + while (rDSIM_FIFOCTRL & rDSIM_FIFOCTRL_EmptyRx); + tmp = rDSIM_RXFIFO; + } + if (i < maxlen) + data[i] = tmp & 0xff; + tmp >>= 8; + } + + return 0; +} diff --git a/drivers/samsung/mipi/dsim.h b/drivers/samsung/mipi/dsim.h new file mode 100644 index 0000000..01dc0d0 --- /dev/null +++ b/drivers/samsung/mipi/dsim.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2008-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __SAMSUNG_DSIM_H +#define __SAMSUNG_DSIM_H + +#include + +#define rDSIM_STATUS (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00)) +#define rDSIM_STATUS_PllStable (0x80000000) +#define rDSIM_STATUS_SwRstRls (0x00100000) +#define rDSIM_STATUS_Direction (0x00010000) +#define rDSIM_STATUS_TxReadyHsClk (0x00000400) +#define rDSIM_STATUS_UlpsClk (0x00000200) +#define rDSIM_STATUS_StopstateClk (0x00000100) +#define rDSIM_STATUS_UlpsDatMsk (0xf << 4) +#define rDSIM_STATUS_UlpsDat(d) (((d) & 0xf) << 4) +#define rDSIM_STATUS_StopstateDatMsk (0xf << 0) +#define rDSIM_STATUS_StopstateDat(d) (((d) & 0xf) << 0) +#define rDSIM_SWRST (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x04)) +#define rDSIM_SWRST_FuncRst (0x00010000) +#define rDSIM_SWRST_SwRst (0x00000001) +#define rDSIM_CLKCTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x08)) +#define rDSIM_CLKCTRL_TxRequestHsClk (0x80000000) +#define rDSIM_CLKCTRL_EscClkEn (0x10000000) +#define rDSIM_CLKCTRL_PllBypass (0x08000000) +#define rDSIM_CLKCTRL_ByteClkSrcMsk (0x3 << 25) +#define rDSIM_CLKCTRL_ByteClkSrc(d) (((d) & 0x3) << 25) +#define rDSIM_CLKCTRL_ByteClkEn (0x01000000) +#define rDSIM_CLKCTRL_LaneEscClkEnMsk (0xf << 20) +#define rDSIM_CLKCTRL_LaneEscClkEn(d) (((d) & 0xf) << 20) +#define rDSIM_CLKCTRL_LaneEscClkEnClk (0x00080000) +#define rDSIM_CLKCTRL_EscPrescalar(d) ((d) & 0xffff) +#define rDSIM_TIMEOUT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0C)) +#define rDSIM_CONFIG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x10)) +#define rDSIM_CONFIG_DPDN_Test_En (0x80000000) +#define rDSIM_CONFIG_TxTypeSfr (0x10000000) +#define rDSIM_CONFIG_SyncInform (0x08000000) +#define rDSIM_CONFIG_BurstMode (0x04000000) +#define rDSIM_CONFIG_VideoMode (0x02000000) +#define rDSIM_CONFIG_AutoMode (0x01000000) +#define rDSIM_CONFIG_HseMode (0x00800000) +#define rDSIM_CONFIG_HfpMode (0x00400000) +#define rDSIM_CONFIG_HbpMode (0x00200000) +#define rDSIM_CONFIG_HsaMode (0x00100000) +#define rDSIM_CONFIG_MainVc(d) (((d) & 0x3) << 18) +#define rDSIM_CONFIG_MainPixFormat(d) (((d) & 0x7) << 12) +#define rDSIM_CONFIG_NumOfDatLaneMsk (0x3 << 5) +#define rDSIM_CONFIG_NumOfDatLane(d) (((d) & 0x3) << 5) +#define rDSIM_CONFIG_LaneEnMsk (0xf << 1) +#define rDSIM_CONFIG_LaneEn(d) (((d) & 0xf) << 1) +#define rDSIM_CONFIG_LaneClkEn (0x00000001) +#define rDSIM_ESCMODE (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x14)) +#define rDSIM_ESCMODE_ForceStopstate (0x00100000) +#define rDSIM_ESCMODE_ForceBTA (0x00010000) +#if DSIM_VERSION == 3 +#define rDSIM_ESCMODE_Auto_Ulps_Data (1 << 9) +#define rDSIM_ESCMODE_Auto_Ulps_Clk (1 << 8) +#endif // DSIM_VERSION == 3 +#define rDSIM_ESCMODE_CmdLpdt (0x00000080) +#define rDSIM_ESCMODE_TxLpdt (0x00000040) +#define rDSIM_ESCMODE_TxTriggerRst (0x00000010) +#define rDSIM_ESCMODE_TxUlpsDat (0x00000008) +#define rDSIM_ESCMODE_TxUlpsExit (0x00000004) +#define rDSIM_ESCMODE_TxUlpsClk (0x00000002) +#define rDSIM_ESCMODE_TxUlpsClkExit (0x00000001) +#define rDSIM_MDRESOL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x18)) +#define rDSIM_MDRESOL_MainStandby (0x80000000) +#define rDSIM_MDRESOL_MainVResol(d) (((d) & 0x7ff) << 16) +#define rDSIM_MDRESOL_MainHResol(d) ((d) & 0x7ff) +#define rDSIM_MVPORCH (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x1C)) +#define rDSIM_MVPORCH_CmdAllow(d) (((d) & 0xf) << 28) +#define rDSIM_MVPORCH_StableVfp(d) (((d) & 0x7ff) << 16) +#define rDSIM_MVPORCH_MainVbp(d) ((d) & 0x7ff) +#define rDSIM_MHPORCH (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x20)) +#define rDSIM_MSYNC (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x24)) +#define rDSIM_SSCNT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x28)) +#define rDSIM_INTSRC (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x2C)) +#define rDSIM_INTSRC_SwRstRelease (0x40000000) +#define rDSIM_INTSRC_PllStable (0x80000000) +#define rDSIM_INTSRC_LpdrTout (0x00200000) +#define rDSIM_INTSRC_RxDatDone (0x00040000) +#define rDSIM_INTSRC_RxAck (0x00010000) +#define rDSIM_INTSRC_AnyError (0x0000ffff) +#define rDSIM_INTMSK (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x30)) +#define rDSIM_PKTHDR (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x34)) +#define rDSIM_PAYLOAD (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x38)) +#define rDSIM_RXFIFO (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x3C)) +#define rDSIM_FIFOTHLD (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x40)) +#define rDSIM_FIFOCTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x44)) +#define rDSIM_FIFOCTRL_FullRx (0x02000000) +#define rDSIM_FIFOCTRL_EmptyRx (0x01000000) +#define rDSIM_FIFOCTRL_FullHSfr (0x00800000) +#define rDSIM_FIFOCTRL_EmptyHSfr (0x00400000) +#define rDSIM_FIFOCTRL_FullLSfr (0x00200000) +#define rDSIM_FIFOCTRL_EmptyLSfr (0x00100000) +#define rDSIM_FIFOCTRL_FullHI80 (0x00080000) +#define rDSIM_FIFOCTRL_EmptyHI80 (0x00040000) +#define rDSIM_FIFOCTRL_FullLI870 (0x00020000) +#define rDSIM_FIFOCTRL_EmptyLI80 (0x00010000) +#define rDSIM_FIFOCTRL_FullHMain (0x00000800) +#define rDSIM_FIFOCTRL_EmptyHMain (0x00000400) +#define rDSIM_FIFOCTRL_FullLMain (0x00000200) +#define rDSIM_FIFOCTRL_EmptyLMain (0x00000100) +#define rDSIM_FIFOCTRL_nInitRx (0x00000010) +#define rDSIM_FIFOCTRL_nInitSfr (0x00000008) +#define rDSIM_FIFOCTRL_nInitI80 (0x00000004) +#define rDSIM_FIFOCTRL_nInitMain (0x00000001) +#define rDSIM_MEMACCHR (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x48)) +#define rDSIM_PLLCTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x4C)) +#define rDSIM_PLLCTRL_HSzeroCtl(d) (((d) & 0xf) << 28) +#define rDSIM_PLLCTRL_FreqBand(d) (((d) & 0xf) << 24) +#define rDSIM_PLLCTRL_PllEn (0x00800000) +#define rDSIM_PLLCTRL_PreprCtl(d) (((d) & 0x7) << 20) +#if DSIM_VERSION == 0 +#define rDSIM_PLLCTRL_P(d) (((d) & 0x3f) << 14) +#define rDSIM_PLLCTRL_M(d) (((d) & 0x3ff) << 4) +#else +#define rDSIM_PLLCTRL_P(d) (((d) & 0x3f) << 13) +#define rDSIM_PLLCTRL_M(d) (((d) & 0x1ff) << 4) +#endif +#define rDSIM_PLLCTRL_S(d) (((d) & 0x7) << 1) +#define rDSIM_PLLCTRL_DpDnSwap (0x00000001) +#define rDSIM_PLLTMR (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x50)) +#define rDSIM_PHYACCHR (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x54)) +#if DSIM_VERSION < 2 +#define rDSIM_PHYACCHR_UP_CODE(d) (((d) & 0xc) << (26 - 2)) +#else +#define rDSIM_PHYACCHR_UP_CODE(d) (0 << 0) +#endif +#define rDSIM_PHYACCHR_AFC_ENABLE (0x00004000) +#define rDSIM_PHYACCHR_DPHYCTL(d) (((d) & 0x3f) << 8) +#define rDSIM_PHYACCHR_AFC(d) (((d) & 0x7) << 5) +#if DSIM_VERSION < 2 +#define rDSIM_PHYACCHR_DOWN_CODE(d) (((d) & 0x1) << (3 - 0)) +#else +#define rDSIM_PHYACCHR_DOWN_CODE(d) (0 << 0) //NOOP +#endif +#define rDSIM_PHYACCHR2 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x58)) +#if DSIM_VERSION < 2 +#define rDSIM_PHYACCHR2_UP_CODE(d) ((((d) & 0x2) << (17 - 1)) | (((d) & 0x1) << (8 - 0))) +#define rDSIM_PHYACCHR2_DOWN_CODE(d) (0 << 0) //NOOP +#else +#define rDSIM_PHYACCHR2_UP_CODE(d) (((d) & 0x7) << 19) +#define rDSIM_PHYACCHR2_DOWN_CODE(d) (((d) & 0x7) << 4) +#endif +#define rDSIM_PHYACCHR2_PrprCtlClk(d) (((d) & 0x7) << 16) + +#if DSIM_VERSION == 3 +#define rDSIM_ULPSIN (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x60)) +#define rDSIM_ULPSOUT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x64)) +#define rDSIM_ULPSEND (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x68)) +#endif //DSIM_VERSION == 3 + +#define rDSIM_SUPPRESS (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x6C)) +#define rDSIM_SUPPRESS_Line_Timeout_Disable (0x00000001) + +#if DSIM_VERSION == 3 +#define rDSIM_I80_LPVALID_ST (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x70)) +#endif //DSIM_VERSION == 3 + +#define rDSIM_VERINFO (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0C)) + +#endif /* __SAMSUNG_DSIM_H */ diff --git a/drivers/samsung/mipi/rules.mk b/drivers/samsung/mipi/rules.mk new file mode 100644 index 0000000..8441e8a --- /dev/null +++ b/drivers/samsung/mipi/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIPI_DSIM=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dsim.o diff --git a/drivers/samsung/pke/AppleS5L8900XPKE-hardware.c b/drivers/samsung/pke/AppleS5L8900XPKE-hardware.c new file mode 100644 index 0000000..c902c89 --- /dev/null +++ b/drivers/samsung/pke/AppleS5L8900XPKE-hardware.c @@ -0,0 +1,717 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include "AppleS5L8900XPKE-hardware.h" + + +#define AppleS5L8900XPKE_hardware_DEBUG 0 +#undef absolutetime_to_nanoseconds + +#if AppleS5L8900XPKE_hardware_DEBUG +static void debug_data(uint8_t *data, size_t length) +{ + uint32_t i=0; + printf("data %p,%d\n" , data, length); + for (i = 0; i < length; i++) { + if( !(i%256) ) + printf("Seg : %p \n", data); + printf("%02X, ", *(data + i)); + if ((i % 16) == 15) + printf("\n"); + } + printf("\n"); +} +#define debug(fmt, args...) printf("AppleS5L8900XPKE-hardware::%s: " fmt "\n", __FUNCTION__ , ##args) +#else +#define debug(fmt, args...) +#define debug_data(data, length) +#endif + + +#if IN_KERNEL +extern uint64_t iodelay_time[3]; +static uint64_t delay_time; +#endif + + +uint32_t +PkeSetMode(uint32_t uSegSize) +{ + uint32_t uWriteVal; + + switch (uSegSize) { + case PKE_SEG_SIZE_256: + uWriteVal = PKE_REGVAL_SEG_SIZE_SEGSIZE_256; + break; + + case PKE_SEG_SIZE_128: + uWriteVal = PKE_REGVAL_SEG_SIZE_SEGSIZE_128; + break; + + case PKE_SEG_SIZE_64: + uWriteVal = PKE_REGVAL_SEG_SIZE_SEGSIZE_64; + break; + + default: + uWriteVal = 0; + debug("error setting segment size/mode\n"); + } + + /* ! write SEG_SIZE and MODE_ID */ + return (uWriteVal | PKE_REGMASK_SEG_SIZE_MUSTBEONE); +} + +uint32_t +PkeGetSegmentCount(uint32_t uSegSize) +{ + /* return segment total number */ + switch (uSegSize) { + case PKE_SEG_SIZE_256: + return PKE_SEG_NUM_CASE256; + case PKE_SEG_SIZE_128: + return PKE_SEG_NUM_CASE128; + case PKE_SEG_SIZE_64: + return PKE_SEG_NUM_CASE64; + default: + return 0; + } +} + +static uint32_t get_precision(uint32_t uBitLen) +{ + uint32_t uPrecision; + + if (uBitLen <= PKE_LEN_BIT_512) { + uPrecision = PKE_SIZE_PREC_0; + } else if ((uBitLen <= PKE_LEN_BIT_1024) && (uBitLen != PKE_LEN_BIT_672) && (uBitLen != PKE_LEN_BIT_864)) { + uPrecision = PKE_SIZE_PREC_1; + } else if ((uBitLen <= PKE_LEN_BIT_1536) && (uBitLen != PKE_LEN_BIT_1280) && (uBitLen != PKE_LEN_BIT_1408)) { + uPrecision = PKE_SIZE_PREC_2; + } else { + uPrecision = PKE_SIZE_PREC_3; + } + return uPrecision; +} + +static uint32_t get_chunkSize(uint32_t uBitLen, uint32_t uPrecision) +{ + uint32_t uDiv, uChunk; + + switch (uPrecision) { + case PKE_SIZE_PREC_0: + if (uBitLen < PKE_LEN_BIT_128) { + uBitLen = PKE_LEN_BIT_128; + } + uDiv = uBitLen >> 5; + uChunk = uDiv; + if (uBitLen - (uChunk << 5)) { + uDiv++; + } + uChunk = --uDiv; + break; + + case PKE_SIZE_PREC_1: + uDiv = uBitLen >> 6; + uChunk = uDiv; + if (uBitLen - (uChunk << 6)) { + uDiv++; + } + uChunk = --uDiv; + break; + + case PKE_SIZE_PREC_2: + uDiv = (uBitLen / 3) >> 5; + uChunk = uDiv; + if (uBitLen - ((uChunk * 3) << 5)) { + uDiv++; + } + uChunk = --uDiv; + break; + + case PKE_SIZE_PREC_3: + uDiv = uBitLen >> 7; + uChunk = uDiv; + if (uBitLen - (uChunk << 7)) { + uDiv++; + } + uChunk = --uDiv; + break; + default: + debug("Unsupported precision value: %u", uPrecision); + uChunk = 0; + } + return (((uChunk << 3) + 8) << 2); +} + +static uint32_t +config_pke_key_len(uint32_t uBitLen) +{ + uint32_t uDiv, uChunk, uPrecision; + + /* 1. Get Precision */ + uPrecision = get_precision(uBitLen); + + /* 2. Get chunck size */ + uChunk = get_chunkSize(uBitLen, uPrecision); + + /* 3. Set precision and chunksize */ + uDiv = ((uChunk >> 2) - 8) | uPrecision; + +#if IN_KERNEL + //Set the IODelay time based on uBitLen. + if (uBitLen <= PKE_LEN_BIT_512) { + delay_time = iodelay_time[0]; + } + else if (uBitLen <= PKE_LEN_BIT_1024) { + delay_time = iodelay_time[1]; + } + else { + delay_time = iodelay_time[2]; + } +#endif + + return uDiv; +} + +static inline uint32_t +RSAPkeSetInOut(uint32_t uDest, uint32_t uSrc1, uint32_t uSrc2) +{ + uint32_t uPosition = 0; + + /*! Set segment ID of src and dest */ + uPosition = ((uSrc1 << PKE_REGSHIFT_SEG_ID_A_SEG_ID) + | (uSrc2 << PKE_REGSHIFT_SEG_ID_B_SEG_ID) + | (uDest << PKE_REGSHIFT_SEG_ID_S_SEG_ID)); + + return uPosition; +} + +static inline bool +RSAPkeRun(volatile struct pke_regs *registers, uint32_t uCmdVal) +{ + /*! Run PKE */ + registers->pke_start = uCmdVal; + +#if IN_KERNEL + IODelay(delay_time); +#endif + + do { + if (!(registers->pke_start & PKE_REGMASK_START_EXEC_ON)) + return true; + } while (1); + + return false; +} + + +static bool shift_left(uint32_t *data, uint32_t data_size) +{ + int prev_carry = 0, cur_carry = 0; + uint32_t itr = 0; + + for (itr=0; itr < (data_size/sizeof(uint32_t)); itr++) { + cur_carry = data[itr] >> 31; + data[itr] = (data[itr] << 1) + prev_carry; + prev_carry = cur_carry; + } + return prev_carry; +} + + +static int32_t highestSetBit(uint32_t *data1, uint32_t data_size) +{ + int32_t ix = data_size/sizeof(uint32_t) - 1; // Most significant word. + + while( ix>=0 && data1[ix]==0) { + ix--; + } + + if(ix < 0) + return -1; //mods is zero. + + uint32_t msNZword = data1[ix]; + uint32_t b = ((ix+1) * sizeof(uint32_t) * DATA_BYTE_TO_BIT) - 1 ; + // Now find the highest set bit. + uint32_t mask = 0x80000000; + while ((msNZword & mask) == 0) { + mask >>= 1; + b--; + } + return b; +} + + +static bool is_greater(uint32_t *data1, uint32_t *data2, uint32_t data_size) +{ + uint32_t itr = data_size/sizeof(uint32_t) - 1; //start at the last word. + + do { + if(data1[itr] > data2[itr]) + return true; + else if(data1[itr] < data2[itr]) + return false; + //check next word; + }while(itr--); + + return false; +} + +/* Do data1 = data1 - data2 */ +static uint32_t sub(uint32_t *data1, uint32_t *data2, uint32_t data_size) +{ + uint32_t borrow = 0; + uint32_t itr = 0; + + for(itr=0; itr < (data_size/sizeof(uint32_t)); itr++) { + if(borrow) { + if(data1[itr] != 0) + borrow = 0; //No need to borrow again. + data1[itr] -= 1; + } + + if( data1[itr] < data2[itr] ) + borrow = 1; + + data1[itr] -= data2[itr]; + } + if(borrow) + return 1; + + return 0; +} + +/*Do data1 = data1 + data2 */ +static uint32_t add(uint32_t *data1, uint32_t *data2, uint32_t data_size) +{ + uint32_t temp; + + int carry = 0; + uint32_t itr = 0; + + for(itr=0; itr < (data_size/sizeof(uint32_t)); itr++) { + temp = data1[itr] + data2[itr] + carry; + if(temp < data1[itr] || (temp == data1[itr] && carry)) + carry = 1; + else + carry = 0; + data1[itr] = temp; + } + return carry; +} + +// The src buffer is assumed to be word aligned at this point. +// The hardware register is 4 byte aligned. +// The data is in little Endian. +static inline void copy_into_segment(volatile uint8_t *memory, uint32_t segment_id, uint32_t segment_size, uint8_t *data, uint32_t length) +{ + volatile uint8_t *dst = memory + segment_id * segment_size; + uint32_t ii=0; + + //Make sure the buffer is word aligned. + //assert((data & 3) == 0); //We don't assert in iBoot. The only interface makes sure we have aligned buffer. + + uint32_t newLength = length & ~3 ; + //Copy words. + for(ii=0; ii<(newLength/4); ii++) + *((uint32_t*)dst + ii) = *((uint32_t*)data + ii); + + //See if you have less than a word left to copy. + if(length & 3) { //have less than 4 bytes left to copy. + uint8_t wordData[4] = {0,0,0,0}; + uint8_t *bytesLeft = data + newLength; + for(ii=0; ii<(length & 3); ii++) { + wordData[ii] = *(bytesLeft + ii); + } + *((uint32_t*)(dst+newLength)) = *((uint32_t*)wordData); + } + + //zero fill the rest of the segment. + uint32_t bytesCopied = ((length+3) & ~3); + uint32_t left = segment_size - bytesCopied; + if(left) { + uint32_t *dest = (uint32_t *)(dst + bytesCopied); + for(ii=0; ii<(left/4); ii++) + *(dest+ii) = 0x00000000; + } +} + +/* Calculate R0 in software. + rzero has memory allocated of size modulus_length and is zero filled. +*/ +bool rsa_cal_R0(uint32_t * const mods, uint32_t modulus_length, uint32_t *rzero) +{ + debug("called"); + + uint32_t precision = get_precision(modulus_length*DATA_BYTE_TO_BIT); + uint32_t chunk_size = get_chunkSize(modulus_length*DATA_BYTE_TO_BIT, precision); + + //precision is 1,2,3,4 instead of 0,1,2,3 + precision += 1; + + /* Compute 2^b */ + uint32_t power = (chunk_size / 16) + 1; + if (precision == 3) + power = power * 3; + power = power + (precision * (chunk_size + 16)); + + //compute the most significant bit set in the modulus. + int32_t b = highestSetBit((uint32_t*)mods, modulus_length); + if(b == -1) + return false; + + //store 2^b in rzero. + bzero(rzero, modulus_length); + rzero[(b/32)] = 1 << (b % 32); + + /* Calculate (2^(power-b) * 2^b) mod M */ + uint32_t itr; + for(itr=0; itr<(power-b); itr++) { + bool carry = shift_left(rzero, modulus_length); //Shift left. + if (carry || is_greater(rzero, mods, modulus_length)) + sub(rzero, (uint32_t*)mods, modulus_length); + } + return true; +} + +/* Compute the value of R^2 using the hardware. + The value of rzero (R0) is calculated in softare and passed into the function + The hardware should be reset before calling this function. + The value of R^2 is returned thru' rsquare (memory for this is allocated before calling this function and of modulus_length size) +*/ +static bool rsa_cal_R2modM(volatile struct pke_regs *registers, volatile uint8_t *memory, uint32_t seg_size, uint32_t * const mods, uint32_t mods_length, uint32_t *rsquare, uint32_t *r2_segid) +{ + debug("called"); + + if(!rsquare) //Need rzero (which should be in rsquare) to proceed + return false; + + //Set the key length; + registers->pke_key_len = config_pke_key_len(mods_length*DATA_BYTE_TO_BIT); + //Set segment size; + registers->pke_seg_size = PkeSetMode(seg_size); + registers->pke_seg_sign = 0; + registers->pke_seg_id = 0; + + /* Use hardware to calculate R1 thru' Rn and finally R^2 */ + //Load modulus always into seg0. + copy_into_segment(memory, mod_segid, seg_size, (uint8_t*)mods, mods_length); + + //based on seg_size compute the seg_ids to store the (2^(power-b) * 2^b) mod M + // and the final value of R^2 + uint32_t rzero_segid, rsq_segid; + switch (seg_size) { + case PKE_SEG_SIZE_256: + rzero_segid = PKE_SEG_ID_05; + rsq_segid = PKE_SEG_ID_06; + break; + case PKE_SEG_SIZE_128: + rzero_segid = PKE_SEG_ID_12; + rsq_segid = PKE_SEG_ID_14; + break; + case PKE_SEG_SIZE_64: + rzero_segid = PKE_SEG_ID_28; + rsq_segid = PKE_SEG_ID_29; + break; + default: + //Should not happen. + return false; + } + //Load the rzero into the hardware. + copy_into_segment(memory, rzero_segid, seg_size, (uint8_t*)rsquare, mods_length); + + uint32_t precision = (registers->pke_key_len&PKE_REGMASK_KEY_LEN_PREC_ID) + 1; + //Compute the number of hardware iterations based on precision. + uint32_t square_count; + if (precision == 1 || precision == 3) + square_count = 4; + else if (precision == 2) + square_count = 5; + else /* precision == 4 */ + square_count = 6; + + //Set pre load modulus on when using the hardware for the first time. + uint32_t start_mask = PKE_REGMASK_START_PLDM_ON | PKE_REGMASK_START_EXEC_ON; + uint32_t itr = 1; + uint32_t temp_segid = rsq_segid; + while (itr <= square_count) { + //setup seg_id pointers on the hardware + registers->pke_seg_id = RSAPkeSetInOut(temp_segid, rzero_segid, rzero_segid); + //kick the hardware. + if(!RSAPkeRun(registers, start_mask)) + return false; + itr++; + if(itr > square_count) + break; + //swap the segids and do the square again. + temp_segid += rzero_segid; + rzero_segid = temp_segid - rzero_segid; + temp_segid -= rzero_segid; + start_mask = PKE_REGMASK_START_EXEC_ON; //dont have to laod M again. + } + + // Check the sign value of temp_segid and add modulus if negative. + uint32_t uRead, uMask; + uMask = (1 << temp_segid); + uRead = registers->pke_seg_sign & uMask; + //If negative then add modulus. + if(uRead) { + add( (uint32_t*)(memory+(temp_segid*seg_size)), (uint32_t*)mods, mods_length); + } + + *r2_segid = temp_segid; + + //Clean up the temp space used. + bzero((uint8_t*) memory+rzero_segid*seg_size, mods_length); + + /* Reset the signbits */ + registers->pke_seg_sign = 0; + memcpy(rsquare, (uint8_t *) memory+rsq_segid*seg_size, mods_length); + return true; +} + + +/* Calculate exponential. + The options parameter passed in indicates if R^2 is passed in or needs to be computed. + Options = 00 => Compute R^2 and don't care about caching. *rsquare is ignored. + Options = 01 => Compute R^2 and return it for caching. *rsquare has mem allocated and is of size modulus_length + Options = 10 => Use passed in R^2 value. + + Reset the hardware before calling this function. +*/ +bool rsa_cal_exp(void *dst, uint32_t *len, uint32_t options, + uint8_t *rsquare, uint32_t *rsquare_length, + uint8_t * const base, uint32_t base_length, + uint8_t * const expn, uint32_t expn_length, + uint8_t * const modulus, uint32_t modulus_length, + volatile struct pke_regs *registers, volatile uint8_t *memory) +{ + debug("called"); + + /* Perform validation checks */ + if(modulus_length % 4) + return false; + + uint32_t segment_size, num_segments; + + if (modulus_length <= (PKE_SEG_SIZE_64)) { + segment_size = PKE_SEG_SIZE_64; + } else if (modulus_length <= (PKE_SEG_SIZE_128)) { + segment_size = PKE_SEG_SIZE_128; + } else if (modulus_length <= (PKE_SEG_SIZE_256)) { + segment_size = PKE_SEG_SIZE_256; + } else + return false; /* key too long */ + + num_segments = PkeGetSegmentCount(segment_size); + + if ( !num_segments || + base_length > segment_size || + expn_length > segment_size || + modulus_length > segment_size) + return false; + + /* Sane input, so proceed */ + + //rsquare segid must always be the last seg ID. + uint32_t rsq_segid = num_segments - 1; + + if( (options&kIOPKEAcceleratorComputeRsquareMask) == 0 ) { //Compute rsquare. + if(!(options&kIOPKEAcceleratorPreProcessingDone)) { //R0 was not cacluated. should only happen in iBoot. + if(!rsquare){ + //should not happen. The expectation is that memory for rsquare should be allocated. + return false; + } + rsa_cal_R0((uint32_t*)modulus, modulus_length, (uint32_t*)rsquare); + } + //Compute R^2 + if(!rsa_cal_R2modM(registers, memory, segment_size, (uint32_t*)modulus, modulus_length, (uint32_t*)rsquare, &rsq_segid)) + return false; + *rsquare_length = modulus_length; + } + else { //This would have been done while calculating R^2. + //Set the key length; + registers->pke_key_len = config_pke_key_len(modulus_length*DATA_BYTE_TO_BIT); + //Set segment size; + registers->pke_seg_size = PkeSetMode(segment_size); + /* Reset the signbits */ + registers->pke_seg_sign = 0; + registers->pke_seg_id = 0; + + //Load modulus into seg0; + copy_into_segment(memory, mod_segid, segment_size, modulus, modulus_length); + //copy the rsquare into the hardware segment. + memcpy((uint8_t*)memory+(rsq_segid*segment_size), rsquare, modulus_length); + } + + /* Compute (base * r^2 mod M) using hardware */ + //Copy base into tmp_segid. + copy_into_segment(memory, tmp_segid, segment_size, base, base_length); + //Setup the segid pointers. + registers->pke_seg_id = RSAPkeSetInOut(iter_segid, tmp_segid, rsq_segid); + + //Kick the hardware with pre load modulus bit set. + if(!RSAPkeRun(registers, (PKE_REGMASK_START_PLDM_ON | PKE_REGMASK_START_EXEC_ON))) + return false; + + /* compute (1*R^2modM) using hardware. */ + registers->pke_seg_size |= PKE_REGVAL_SEG_SIZE_FUNC_ID_A1; // A*1 + //When PKE_REGVAL_SEG_SIZE_FUNC_ID_A1 is set, the hardware ignores the segid_B pointer + registers->pke_seg_id = RSAPkeSetInOut(acum_segid, rsq_segid, rsq_segid); + if(!RSAPkeRun(registers, PKE_REGMASK_START_EXEC_ON)) + return false; + + // Clear the PKE_REGVAL_SEG_SIZE_FUNC_ID_A1 bit. + registers->pke_seg_size &= ~PKE_REGVAL_SEG_SIZE_FUNC_ID_A1; + + /* Run the PKE */ + uint32_t *exp_word = (uint32_t*)expn; + /* word aligned byte length */ + uint32_t uExpLen = ((expn_length + (DATA_WORD_TO_BYTE - 1)) & (~0x3)); + + uint32_t last_word = exp_word[(uExpLen/DATA_WORD_TO_BYTE) - 1]; + uint32_t uIndex = (DATA_WORD_TO_BYTE*DATA_BYTE_TO_BIT) - (highestSetBit(&last_word, DATA_WORD_TO_BYTE) + 1); + for (; uIndex < (uExpLen * DATA_BYTE_TO_BIT); uIndex++) { + unsigned int word; + unsigned int bit; + + uint32_t offset = (uExpLen / DATA_WORD_TO_BYTE) - (uIndex / (DATA_WORD_TO_BYTE * DATA_BYTE_TO_BIT)) - 1; + word = exp_word[offset]; + + registers->pke_seg_id = RSAPkeSetInOut(tmp_segid, acum_segid, acum_segid); + if(!RSAPkeRun(registers, PKE_REGMASK_START_EXEC_ON)) + return false; + + bit = word & (0x80000000 >> (uIndex % (DATA_WORD_TO_BYTE * DATA_BYTE_TO_BIT))); + + if (bit) { + //debug("bit %d set", uIndex); + registers->pke_seg_id = RSAPkeSetInOut(acum_segid, tmp_segid, iter_segid); + if(!RSAPkeRun(registers, PKE_REGMASK_START_EXEC_ON)) + return false; + } else { + memcpy( (uint8_t *) memory + acum_segid * segment_size, + (uint8_t *) memory + tmp_segid * segment_size, + segment_size); + + if (registers->pke_seg_sign & (0x01 << tmp_segid)) + registers->pke_seg_sign |= (0x01 << acum_segid); + else + registers->pke_seg_sign &= ~(0x01 << acum_segid); + } + } + + /* Factor out R^-1 from the result */ + registers->pke_seg_size |= PKE_REGVAL_SEG_SIZE_FUNC_ID_A1; // A*1 + registers->pke_seg_id = RSAPkeSetInOut(tmp_segid, acum_segid, acum_segid); + if (!RSAPkeRun(registers, PKE_REGMASK_START_EXEC_ON)) + return false; + registers->pke_seg_size &= ~PKE_REGVAL_SEG_SIZE_FUNC_ID_A1; // A*B + + // Check the sign value of tmp_segid and add modulus if negative. + uint32_t uRead, uMask; + uMask = (1 << tmp_segid); + uRead = registers->pke_seg_sign & uMask; + //If negative then add modulus. + if(uRead) { + registers->pke_seg_sign &= ~uMask; //clear the sign. + add( (uint32_t*)(memory+(tmp_segid*segment_size)), (uint32_t*)modulus, modulus_length); + } + + /* Copy data out */ + memcpy(dst, (uint8_t*)memory+(tmp_segid*segment_size), modulus_length); + *len = modulus_length; + return true; +} + +#if IN_KERNEL + +bool internalTest(volatile struct pke_regs *registers, volatile uint8_t *memory, uint32_t mod_size, uint64_t *time_micro) +{ + uint8_t buff[mod_size]; + uint32_t segment_size; + + if (mod_size <= (PKE_SEG_SIZE_64)) { + segment_size = PKE_SEG_SIZE_64; + } else if (mod_size <= (PKE_SEG_SIZE_128)) { + segment_size = PKE_SEG_SIZE_128; + } else if (mod_size <= (PKE_SEG_SIZE_256)) { + segment_size = PKE_SEG_SIZE_256; + } else + return false; /* key too long */ + + uint32_t rsq_segid; + switch (segment_size) { + case PKE_SEG_SIZE_256: + rsq_segid = PKE_SEG_ID_06; + break; + case PKE_SEG_SIZE_128: + rsq_segid = PKE_SEG_ID_14; + break; + case PKE_SEG_SIZE_64: + rsq_segid = PKE_SEG_ID_29; + break; + default: + //Should not happen. + return false; + } + + registers->pke_key_len = config_pke_key_len(mod_size*DATA_BYTE_TO_BIT); + //Set segment size; + registers->pke_seg_size = PkeSetMode(segment_size); + /* Reset the signbits */ + registers->pke_seg_sign = 0; + registers->pke_seg_id = 0; + + debug("key: %x, reg_key: %x, modsize:%u, reg_segsize: %u", config_pke_key_len(mod_size*DATA_BYTE_TO_BIT), registers->pke_key_len, mod_size, registers->pke_seg_size); + + //Load modulus into seg0; + memset(buff, 0xF0, mod_size); + copy_into_segment(memory, mod_segid, segment_size, buff, mod_size); + //Set R^2 + memset(buff, 0xE5, mod_size); + copy_into_segment(memory, rsq_segid, segment_size, buff, mod_size); + //Set A + memset(buff, 0xD2, mod_size); + copy_into_segment(memory, iter_segid, segment_size, buff, mod_size); + + + //Setup the segid pointers. + registers->pke_seg_id = RSAPkeSetInOut(iter_segid, tmp_segid, tmp_segid); + + uint64_t tasm0, tasm1, tasm2, asm_ns; + tasm0 = mach_absolute_time(); + tasm1 = mach_absolute_time(); + + //Kick the hardware with pre load modulus bit set. + if(!RSAPkeRun(registers, (PKE_REGMASK_START_PLDM_ON | PKE_REGMASK_START_EXEC_ON))) + return false; + + tasm2 = mach_absolute_time(); + absolutetime_to_nanoseconds( (tasm2 + tasm0 - tasm1 - tasm1), &asm_ns); + //debug("Single multiply time: %lluns\n", asm_ns); + + *time_micro = (asm_ns/1000) - 5; + + //clear the hardware. + registers->pke_key_len = 0; + registers->pke_seg_size = 0; + registers->pke_seg_sign = 0; + registers->pke_seg_id = 0; + + bzero((uint8_t*)memory+(tmp_segid*segment_size), mod_size); + bzero((uint8_t*)memory+(mod_segid*segment_size), mod_size); + bzero((uint8_t*)memory+(iter_segid*segment_size), mod_size); + + return true; +} + +#endif diff --git a/drivers/samsung/pke/AppleS5L8900XPKE-hardware.h b/drivers/samsung/pke/AppleS5L8900XPKE-hardware.h new file mode 100644 index 0000000..53d0aad --- /dev/null +++ b/drivers/samsung/pke/AppleS5L8900XPKE-hardware.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _IOKIT_APPLES5L8900XPKE_HARDWARE_H +#define _IOKIT_APPLES5L8900XPKE_HARDWARE_H + +#define IN_KERNEL 0 + +#if IN_KERNEL +#include +#endif + +struct pke_regs { + uint32_t pke_key_len; // 0x000 +#define S5L8900XPKE_key_len(_precision, _chunk_size) (((_precision) & 0x03) | ((((_chunk_size) / 32) & 0x0f) << 3)) + uint32_t pad004; // 0x004 + uint32_t pke_start; // 0x008 +#define S5L8900XPKE_exec_on (1<<0) +#define S5L8900XPKE_pldm_on (1<<3) + uint32_t pke_seg_id; // 0x00c +#define S5L8900XPKE_seg_ids(_a, _b, _m, _s) (((_a) << 24 ) | ((_b) << 16) | ((_m) << 8) | (_s)) + uint32_t pke_seg_sign; // 0x010 + uint32_t pke_seg_size; // 0x014 +#define S5L8900XPKE_func_id (1<<0) +#define S5L8900XPKE_seg_256 (0x00 << 6) +#define S5L8900XPKE_seg_128 (0x01 << 6) +#define S5L8900XPKE_seg_64 (0x02 << 6) + uint32_t pke_intmode; // 0x018 +#define S5L8900XPKE_interrupt (1<<0) + uint32_t pke_int; // 0x01c +#define S5L8900XPKE_end_int (1<<0) + uint32_t pke_int_mask; // 0x020 +#define S5L8900XPKE_end_mask (1<<0) + uint32_t pke_sw_reset; +#define S5L8900XPKE_reset (1<<0) +}; + + +/* ========================================================================= */ +/* D E F I N E S */ +/* ========================================================================= */ + +#define kIOPKEAcceleratorComputeRsquareMask 0x10 +#define kIOPKEAcceleratorCacheRsquare 0x01 +#define kIOPKEAcceleratorPreProcessingDone 0x100 +#define kIOPKEMaxBits 2048 +#define kIOPKEUserDataEndianessMask (1<<7) + +/** \define + * definition of data format size + */ +#define DATA_WORD_TO_BYTE 4 /*4BYTE=1WORD*/ +#define DATA_BYTE_TO_BIT 8 /*1BYTE=8BIT*/ + +#define DATA_SHIFT_FOR_256 8 /*2^8=256*/ +#define DATA_SHIFT_FOR_128 7 /*2^7=128*/ +#define DATA_SHIFT_FOR_64 6 /*2^6=64*/ + +#define PKE_REGSHIFT_KEY_LEN_CHNK_SZ 3 + +/** \define + * definition of PKE precision size + */ +#define PKE_SIZE_PREC_0 0 /*single*/ +#define PKE_SIZE_PREC_1 1 +#define PKE_SIZE_PREC_2 2 +#define PKE_SIZE_PREC_3 3 + + +/** \define + * definition of PKE key bit length + */ +#define PKE_LEN_BIT_128 128 /* min size of bit length*/ +#define PKE_LEN_BIT_512 512 +#define PKE_LEN_BIT_672 672 +#define PKE_LEN_BIT_864 864 +#define PKE_LEN_BIT_1024 1024 +#define PKE_LEN_BIT_1280 1280 +#define PKE_LEN_BIT_1408 1408 +#define PKE_LEN_BIT_1536 1536 +#define PKE_LEN_BIT_2048 2048 /*max size of bit length*/ + +/** \define + * definition of PKE Segment Size + */ +#define PKE_SEG_SIZE_256 (1< + +.text + +.globl _L_TCR_BASE +.globl _L_SEG_BASE + +# TORNADO2 control area 0x3D000000 +# Segment base address 0x3D000800 +_L_TCR_BASE: .long PKE_BASE_ADDR +_L_SEG_BASE: .long PKE_BASE_ADDR+0x0800 + +# segment ids used for calculation depending on segment size +.set SEG_4, 04 +.set SEG_5, 05 +.set SEG_6, 06 +.set SEG_12, 12 +.set SEG_13, 13 +.set SEG_14, 14 +.set SEG_27, 27 +.set SEG_28, 28 +.set SEG_29, 29 + +L_00000040: .long 0x00000040 +L_00004000: .long 0x00004000 +L_20000000: .long 0x20000000 + +# segment operand operation config +L_04040006: .long 0x04040006 +L_05050004: .long 0x05050004 +L_05050006: .long 0x05050006 +L_06060005: .long 0x06060005 +L_0C0C000E: .long 0x0C0C000E +L_0D0D000C: .long 0x0D0D000C +L_0D0D000E: .long 0x0D0D000E +L_0E0E000D: .long 0x0E0E000D +L_1B1B001D: .long 0x1B1B001D +L_1C1C001D: .long 0x1C1C001D +L_1C1C001b: .long 0x1C1C001b +L_1D1D001C: .long 0x1D1D001C + +# bit test mask +L_80000000: .long 0x80000000 + + +# BIT_LEN is programmer defined real key size. + +############################################### +#### NAME : PkeCalR2modM #### +#### Tornado NAME : tor_cal_R2modM #### +############################################### +.globl _PkeCalR2modM +#================================================ +# Name : PkeCalR2modM(int BIT_LEN) +# Tornado Name : tor_cal_R2modM(int BIT_LEN) +# Function : 1. Clear the last 3 segment area +# 2. Calculate R*2^((C/16)+1) modM value +# 3. Calculate R*RmodM by using TORNADO +# and save this value in Seg6 or Seg14 or Seg29. +# 4. Clear temp segment area. +# Requisite : Modulus value must be copied from memory to Seg0 +# before using this function. +# Argument +# int BIT_LEN : real Key size +#================================================ +_PkeCalR2modM: + stmfd sp!, {r1-r12,lr} +# reserved register values +# r0 = BIT_LEN +# r12= Loop_count(hw_size/32) +#==================== +# Clear CryptoRAM area (Seg4 ~ Seg6) when SEG_SIZE=0 +#==================== +# read SEG_SIZE + ldr r1, _L_TCR_BASE + ldr r2, [r1,$0x14] + and r2, r2, $0xC0 + mov r2, r2, LSR #6 + cmp r2, #1 + bhi clr_64 +# 1 segment = 64byte + blt clr_256 +# 1 segment = 256byte + +## else 1 segment =128byte + ldr r1, =SEG_12 +# Start position + ldr r2,_L_SEG_BASE + orr r1,r2,r1, lsl #7 + ldr r2, =96 + b start_clr +clr_64: + ldr r1, =SEG_27 +# Start position + ldr r2,_L_SEG_BASE + orr r1,r2,r1, lsl #6 + ldr r2, =48 + b start_clr +clr_256: + ldr r1, =SEG_4 +# Start position + ldr r2,_L_SEG_BASE + orr r1,r2,r1, lsl #8 + ldr r2, =192 +start_clr: + mov r3,#0 + mov r4,r3 + mov r5,r3 + mov r6,r3 + mov r7,r3 + mov r8,r3 + mov r9,r3 + mov r10,r3 +clear_loop_cal: + stmia r1!, {r3-r10} + subs r2,r2,#8 + bne clear_loop_cal +#==================================================== +# Calculate Montgomery constant +#==================================================== +# 1. Calculate R0=R*2^((c/16)+1)modM +# 2. Calculate R1,R2, .. Rn +# R[i]=(R[i-1]^2)*R^(-1)modM +# n such that 2^n=p*16 (p=1 ==> n=4 # ... P=4 ==> n=6) +# 3. If final output is neg, change it to pos one +#===================================================== + mov r1,r0 +# save BIT_LEN in r1 +#==================== +# Calculate R0=R*2^((c/16)+1)modM +#==================== + +# cal power=(p*(c+16)+(c/16)+1) + ldr r0, _L_TCR_BASE + ldr r0,[r0] + and r2,r0,#0x03 + add r2,r2,#1 +# p value + and r3,r0,#0x78 + add r3,r3,#0x08 + mov r3,r3, lsl #2 +# c value + mul r12,r2,r3 + mov r12,r12,LSR #5 +# r12= Loop_count(hw_size/32) + add r4,r3,#16 + mul r6,r4,r2 +# r6=p*(c+16) + mov r5,r3, LSR #4 + add r5,r5,#1 +# r5=(c/16)+1 + mov r0, #3 + mov r3,r5 + cmp r2, #3 + muleq r5,r3,r0 +# precision = 0x10 case + add r2,r6,r5 +# store power in r2 + +# calculate b value + ldr r0, _L_SEG_BASE + add r3,r1,#31 + mov r3,r3,LSR #5 +# r3= (BIT_LEN+31)/32 + mov r3,r3,lsl #2 + sub r3,r3,#4 + add r0,r0,r3 +# r0 = MSW address of Modulus + mov r7,r1 +# r7= BIT_LEN + add r7,r7,#0x1F + mov r7,r7,LSR #5 + mov r7,r7,lsl #5 +# r7=(r7+31)/32*32 +next_MSW: +# Searching MSW + cmp r7,#0 + beq end_tor_calR2 +## if r2=0 then goto end_... + ldr r4,[r0],#-4 + cmp r4,#0 + subeq r7,r7,#32 + beq next_MSW + ldr r5,L_80000000 +next_MSB: + ands r6,r4,r5 + subeq r7,r7,#1 + mov r5,r5,LSR #1 + beq next_MSB + +# b = r7 + sub r3,r2,r7 +# r3=power - b + +# b is real bit size of Modulus + +# cal a=8-(power-b)%8 (1<= a <=8) +mod8_loop: + cmp r3,#8 + blt cal_a + sub r3,r3,#8 + b mod8_loop +cal_a: + rsb r3,r3,#8 +# r3=a + +# read SEG_SIZE + ldr r4, _L_TCR_BASE + ldr r8, [r4,#0x14] + and r8, r8, #0xC0 + mov r8, r8, LSR #6 + cmp r8, #1 + bhi cal_64 +# 1 segment = 64byte + blt cal_256 +# 1 segment = 256byte + +## else 1 segment =128byte + ldr r4, =SEG_12 +# Start position + ldr r8,_L_SEG_BASE + orr r4,r8,r4, lsl #7 + b cal_segset_endup +cal_64: + ldr r4, =SEG_28 +# Start position + ldr r8,_L_SEG_BASE + orr r4,r8,r4, lsl #6 + b cal_segset_endup +cal_256: + ldr r4, =SEG_5 +# Start position + ldr r8,_L_SEG_BASE + orr r4,r8,r4, lsl #8 +cal_segset_endup: + sub r5,r7,r3 + mov r6,r5, LSR #5 + add r4,r4,r6, lsl #2 +# r4=SEG_4+((b-a)/32)*4 +mod32_loop: + cmp r5,#32 + blt load_power + sub r5,r5,#32 +# r5=(b-a)%32 + b mod32_loop +load_power: + mov r6,#0x01 + mov r6,r6, lsl r5 + str r6,[r4] +# (0x01<<(BIT_LEN-a)%32) +div_modM: + #loop round value < ((power-b+a)/8) + sub r2,r2,r7 + add r2,r2,r3 + mov r0,r2,LSR #3 +# r0=(power-b+a)/8 + +# reserved reg : r0, r1=BIT_LEN, r12=hw_size/32 + +# available reg :r2-11 + stmfd sp!, {r0} +# available reg :r0,r2-r12 r1=store r12 value while shift_block +#==================== +# Start div_byte +#==================== +start_div_byte: + mov r3,#9 +# 9=8 count value +1 + stmfd sp!,{r3} +# !!tor_dev_byte 8 count value is saved in stack!! + mov r1,r12 +reload_shift: +# read SEG_SIZE + ldr r0, _L_TCR_BASE + ldr r2, [r0,#0x14] + and r2, r2, #0xC0 + mov r2, r2, LSR #6 + cmp r2, #1 + bhi reload_64 +# 1 segment = 64byte + blt reload_256 +# 1 segment = 256byte + +## else 1 segment =128byte + ldr r0, =SEG_12 +# Start position + ldr r2,_L_SEG_BASE + orr r0,r2,r0, lsl #7 + b reload_segset_endup +reload_64: + ldr r0, =SEG_28 +# Start position + ldr r2,_L_SEG_BASE + orr r0,r2,r0, lsl #6 + b reload_segset_endup +reload_256: + ldr r0, =SEG_5 +# Start position + ldr r2,_L_SEG_BASE + orr r0,r2,r0, lsl #8 +reload_segset_endup: + mov r3,#0 +# clr r3 + mov r12,r1 + ldmfd sp!,{r5} + subs r5,r5,#1 + stmfd sp!,{r5} + beq end_div_byte + cmp r12,#8 + blt shift_one +#==================== +# Start shift left operation +#==================== +shift_block: + +# r0=address,r3=carry1,r2=carry2 + +# r4-r11=working reg,r12=shift loop counter + #ldm r0, {r4-r11} + ldmia r0, {r4,r5,r6,r7,r8,r9,r10,r11} + mov r2,r4, LSR #31 +# save carry + add r4,r3,r4, lsl #1 +# shift + mov r3,r5, LSR #31 +# save carry + add r5,r2,r5, lsl #1 +# shift + mov r2,r6, LSR #31 +# save carry + add r6,r3,r6, lsl #1 +# shift + mov r3,r7, LSR #31 +# save carry + add r7,r2,r7, lsl #1 +# shift + mov r2,r8, LSR #31 +# save carry + add r8,r3,r8, lsl #1 +# shift + mov r3,r9, LSR #31 +# save carry + add r9,r2,r9, lsl #1 +# shift + mov r2,r10, LSR #31 +# save carry + add r10,r3,r10, lsl #1 +# shift + mov r3,r11, LSR #31 +# save carry + add r11,r2,r11, lsl #1 +# shift + stmia r0!,{r4-r11} + sub r12,r12,#8 + cmp r12,#8 + bge shift_block +shift_one: + cmp r12,#0 + beq cmp_carry1 + ldr r4,[r0] + mov r2,r4, LSR #31 + add r4,r3,r4, lsl #1 + mov r3,r2 + str r4,[r0],#4 + sub r12,r12,#1 + b shift_one +#==================== +# Start compare operation +#==================== +cmp_carry1: + cmp r3,#0 + bne tor_sub +greater_equal: + +# available reg:r2-r12 + sub r0,r0 ,#4 +# MSW address of power(0xE04XX) + ldr r2, _L_SEG_BASE +# Modulus pointer value + and r3,r0,#0xFF + add r2,r2,r3 +# MSW address of Modulus(0xE00XX) +test_loop: + ldr r3,[r0],#-4 +# r3=power value + ldr r4,[r2],#-4 +# r2=Modulus value + cmp r3,r4 + beq test_loop + bhi tor_sub +# pow>Mod + +# pow +#include +#include +#include +#include +#include +#include + +#include "AppleS5L8900XPKE-hardware.h" + + +#define Pke_Shim_DEBUG 0 + +#if Pke_Shim_DEBUG +static void debug_data(uint8_t *data, size_t length) +{ + uint32_t i=0; + printf("data %p,%d\n" , data, length); + for (i = 0; i < length; i++) { + if( !(i%256) ) + printf("Seg : %p \n", data); + printf("%02X, ", *(data + i)); + if ((i % 16) == 15) + printf("\n"); + } + printf("\n"); +} +#define debug(fmt, args...) printf("pke_new::%s: " fmt "\n", __FUNCTION__ , ##args) +#else +#define debug(fmt, args...) +#define debug_data(data, length) +#endif + + +//PKE hardware memory map. +static volatile struct pke_regs *registers = (struct pke_regs *)PKE_BASE_ADDR; +static volatile uint8_t *memory = (uint8_t*)(PKE_BASE_ADDR + 0x800); + +extern bool rsa_cal_exp(void *dst, uint32_t *len, uint32_t options, + uint8_t *rsquare, uint32_t *rsquare_length, + uint8_t * const base, uint32_t base_length, + uint8_t * const expn, uint32_t expn_length, + uint8_t * const modulus, uint32_t modulus_length, + volatile struct pke_regs *registers, volatile uint8_t *memory); + +bool pke_do_exp(uint8_t *dst, size_t *len, size_t key_length, + uint8_t * const base, size_t base_length, + uint8_t * const expn, size_t expn_length, + uint8_t * const mods, size_t mods_length) +{ + bool ret = false; + uint32_t rsquare[64]; //word aligned 256byte buffer. + uint32_t rlen = sizeof(rsquare); + + clock_gate(CLK_PKE, true); + platform_power_set_gate(PWRBIT_USB, true); + +#if Pke_Shim_DEBUG + utime_t st, et; + st = system_time(); +#endif + ret = rsa_cal_exp(dst, (uint32_t*)len, 0, + (uint8_t*)rsquare, &rlen, + base, (uint32_t)base_length, + expn, (uint32_t)expn_length, + mods, (uint32_t)mods_length, + registers, memory); +#if Pke_Shim_DEBUG + et = system_time(); + debug("rsa_cal_exp took %llu micros for keylen: %lu", (et-st), key_length); + //debug("The result:"); + //debug_data(dst, *len); +#endif + + clock_gate(CLK_PKE, false); + return ret; +} diff --git a/drivers/samsung/pke/rules.mk b/drivers/samsung/pke/rules.mk new file mode 100644 index 0000000..a51d545 --- /dev/null +++ b/drivers/samsung/pke/rules.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2007-2008 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PKE=1 + +MODULES += \ + lib/pki + +ALL_OBJS += \ + $(LOCAL_DIR)/pke.o \ + $(LOCAL_DIR)/AppleS5L8900XPKE-hardware.o diff --git a/drivers/samsung/rgbout/include/drivers/rgbout/rgbout.h b/drivers/samsung/rgbout/include/drivers/rgbout/rgbout.h new file mode 100644 index 0000000..a59d94d --- /dev/null +++ b/drivers/samsung/rgbout/include/drivers/rgbout/rgbout.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __SAMSUNG_RGBOUT_H +#define __SAMSUNG_RGBOUT_H + +void rgbout_enable_clocks(bool enable); +void rgbout_init(struct display_timing *timing); +void rgbout_enable_timing_generator(bool enable); +bool rgbout_get_enable_timing_generator(void); +void rgbout_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl); + +#endif /* __SAMSUNG_RGBOUT_H */ diff --git a/drivers/samsung/rgbout/rgbout.c b/drivers/samsung/rgbout/rgbout.c new file mode 100644 index 0000000..e1a884c --- /dev/null +++ b/drivers/samsung/rgbout/rgbout.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#include "rgbout_regs.h" + +static void rgbout_load_gamma_table(); + +void rgbout_enable_clocks(bool enable) +{ + int device; + +#ifdef DISP0_BASE_ADDR + if (RGBOUT_DISPLAYPIPE_BASE_ADDR == DISP0_BASE_ADDR) { + device = CLK_DISP0; + } else +#endif +#ifdef DISP1_BASE_ADDR + if (RGBOUT_DISPLAYPIPE_BASE_ADDR == DISP1_BASE_ADDR) { + device = CLK_DISP1; + } else +#endif + panic("rgb_enable_clocks: unsupported rgbout_displaypipe_base_addr: %p", (void *)RGBOUT_DISPLAYPIPE_BASE_ADDR); + + // Enable/disable displaypipe and clcd clocks + if (enable) { + clock_gate(device, true); + clock_gate(CLK_RGBOUT, true); + } + else { + clock_gate(CLK_RGBOUT, false); + clock_gate(device, false); + } +} + +void rgbout_init(struct display_timing *timing) +{ + // reset RBOUT + rRGBOUTSRESET = 1; + while((rRGBOUTSRESET & 1) != 0); + + //configure RGBOUT + rRGBOUTDITHCFG = 0; // disable dithering + rRGBOUTOTFCON = 0; // no interlace, frame + rRGBOUTOTFTCON6 = (timing->h_active - 1); // display width + rRGBOUTOTFTCON3 = (timing->v_active - 1); // display height + rRGBOUTCFG = (1 << 5) | (0 << 3) | (3); // color mode - RGB, + // color space conversion - off + // display-module - DP + rRGBOUTPOPLATENCY = (timing->v_pulse_width + timing->v_back_porch - 2); // +} + +bool rgbout_get_enable_timing_generator(void) +{ + return ((rRGBOUTCTL & ((1 << 3) | (1 << 0))) == ((1 << 3) | (1 << 0))); +} + +void rgbout_enable_timing_generator(bool enable) +{ + if (enable) { + rRGBOUTCTL = (1 << 3) | (1 << 0); // set rgbout-on, frontend-ready + } + else { + rRGBOUTSRESET = 1; // reset + while((rRGBOUTSRESET & 1) != 0); + } +} + +void rgbout_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut) +{ + const u_int32_t gamma_data[256] = { + 0x10044,0x11048,0x1204c,0x13050,0x14050,0x14054,0x15058,0x1605c,0x17060,0x18064,0x19068,0x1a06c,0x1b06c,0x1b070,0x1c074,0x1d078,0x1e07c,0x1f080,0x20084,0x21088,0x22088,0x2208c,0x23090,0x24094,0x25098,0x2609c,0x270a0,0x280a4,0x290a4,0x290a8,0x2a0ac,0x2b0b0,0x2c0b4,0x2d0b8,0x2e0bc,0x2f0c0,0x300c4,0x310c4,0x310c8,0x320cc,0x330d0,0x340d4,0x350d8,0x360dc,0x370e0,0x380e0,0x380e4,0x390e8,0x3a0ec,0x3b0f0,0x3c0f4,0x3d0f8,0x3e0fc,0x3f0fc,0x3f100,0x40104,0x41108,0x4210c,0x43110,0x44114,0x45118,0x46118,0x4611c,0x47120,0x48124,0x49128,0x4a12c,0x4b130,0x4c134,0x4d134,0x4d138,0x4e13c,0x4f140,0x50144,0x51148,0x5214c,0x53150,0x54154,0x55154,0x55158,0x5615c,0x57160,0x58164,0x59168,0x5a16c,0x5b170,0x5c170,0x5c174,0x5d178,0x5e17c,0x5f180,0x60184,0x61188,0x6218c,0x6318c,0x63190,0x64194,0x65198,0x6619c,0x671a0,0x681a4,0x691a8,0x6a1a8,0x6a1ac,0x6b1b0,0x6c1b4,0x6d1b8,0x6e1bc,0x6f1c0,0x701c4,0x711c8,0x721c8,0x721cc,0x731d0,0x741d4,0x751d8,0x761dc,0x771e0,0x781e4,0x791e4,0x791e8,0x7a1ec,0x7b1f0,0x7c1f4,0x7d1f8,0x7e1fc,0x7f200,0x80200,0x80204,0x81208,0x8220c,0x83210,0x84214,0x85218,0x8621c,0x8721c,0x87220,0x88224,0x89228,0x8a22c,0x8b230,0x8c234,0x8d238,0x8e238,0x8e23c,0x8f240,0x90244,0x91248,0x9224c,0x93250,0x94254,0x95258,0x96258,0x9625c,0x97260,0x98264,0x99268,0x9a26c,0x9b270,0x9c274,0x9d274,0x9d278,0x9e27c,0x9f280,0xa0284,0xa1288,0xa228c,0xa3290,0xa4290,0xa4294,0xa5298,0xa629c,0xa72a0,0xa82a4,0xa92a8,0xaa2ac,0xab2ac,0xab2b0,0xac2b4,0xad2b8,0xae2bc,0xaf2c0,0xb02c4,0xb12c8,0xb22cc,0xb32cc,0xb32d0,0xb42d4,0xb52d8,0xb62dc,0xb72e0,0xb82e4,0xb92e8,0xba2e8,0xba2ec,0xbb2f0,0xbc2f4,0xbd2f8,0xbe2fc,0xbf300,0xc0304,0xc1304,0xc1308,0xc230c,0xc3310,0xc4314,0xc5318,0xc631c,0xc7320,0xc8320,0xc8324,0xc9328,0xca32c,0xcb330,0xcc334,0xcd338,0xce33c,0xcf33c,0xcf340,0xd0344,0xd1348,0xd234c,0xd3350,0xd4354,0xd5358,0xd635c,0xd735c,0xd7360,0xd8364,0xd9368,0xda36c,0xdb370,0xdc374,0xdd378,0xde378,0xde37c,0xdf380,0xe0384,0xe1388,0xe238c,0xe3390,0xe4394,0xe5394,0xe5398,0xe639c,0xe73a0,0xe83a4,0xe93a8,0xea3ac,0xeb3b0,0xec3b0,0xec3b4,0xed3b8,0xee3bc,0xef3c0,0xef3c0 + }; + int i; + u_int32_t reg_val; + + // set write access for gamma table + reg_val = rRGBOUTGMTBLACCCON; + rRGBOUTGMTBLACCCON = reg_val & ~((1<<16) | (0xf<<12) | (0xff)); + + for (i = 0; i < 256; i++) { + rRGBOUTGMTBLACCCON = reg_val | ((1 << 16) | (0x4 << 12) | (i)); // 0100 gamma for R + rRGBOUTGMTBLWDATA = (0 << 31) | (gamma_data[i] & 0x000FFFFF); + } + + for (i = 0; i < 256; i++) { + rRGBOUTGMTBLACCCON = reg_val | ((1 << 16) | (0x5 << 12) | (i)); // 0101 gamma for G + rRGBOUTGMTBLWDATA = (0 << 31) | (gamma_data[i] & 0x000FFFFF); + } + + for (i = 0; i < 256; i++) { + rRGBOUTGMTBLACCCON = reg_val | ((1 << 16) | (0x6 << 12) | (i)); // 0110 gamma for B + rRGBOUTGMTBLWDATA = (0 << 31) | (gamma_data[i] & 0x000FFFFF); + } + + rRGBOUTGMCON = 0x9; // enable gamma correction +} diff --git a/drivers/samsung/rgbout/rgbout_regs.h b/drivers/samsung/rgbout/rgbout_regs.h new file mode 100644 index 0000000..d385712 --- /dev/null +++ b/drivers/samsung/rgbout/rgbout_regs.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __SAMSUNG_RGBOUT_REGS_H +#define __SAMSUNG_RGBOUT_REGS_H + +#include + +#define rRGBOUTCTL (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x00)) +#define rRGBOUTCFG (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x04)) +#define rRGBOUTSRESET (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x08)) +#define rRGBOUTDITHCFG (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x1C)) +#define rRGBOUTOTFCON (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x24)) +#define rRGBOUTOTFTCON3 (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x34)) +#define rRGBOUTOTFTCON6 (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x40)) +#define rRGBOUTGMCON (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x4C)) +#define rRGBOUTGMTBLACCCON (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x54)) +#define rRGBOUTGMTBLWDATA (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x58)) +#define rRGBOUTPOPLATENCY (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x6C)) +#define rRGBOUTDPCONSTCOLOR (*(volatile u_int32_t *)(RGBOUT_BASE_ADDR + 0x7C)) + +#endif /* __SAMSUNG_RGBOUT_REGS_H */ \ No newline at end of file diff --git a/drivers/samsung/rgbout/rules.mk b/drivers/samsung/rgbout/rules.mk new file mode 100644 index 0000000..8f748b6 --- /dev/null +++ b/drivers/samsung/rgbout/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + DISPLAYPIPE_BASE_ADDR=RGBOUT_DISPLAYPIPE_BASE_ADDR \ + WITH_DBE_RGBOUT=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/rgbout.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/samsung/rosc/rosc.c b/drivers/samsung/rosc/rosc.c new file mode 100644 index 0000000..dfb42f7 --- /dev/null +++ b/drivers/samsung/rosc/rosc.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#include "rosc.h" + +static void rosc_ops(int location, int type, int period); + +static void rosc_ops(int location, int type, int period) +{ + u_int32_t coe = 0; + +#if ROSC_WITH_CLOCK + clock_gate(CLK_ROSC, true); +#endif + coe = ROSC_PRESCALE * (clock_get_frequency(CLK_PCLK)/ROSC_INTERVAL); + /* NOP */ + rROSC_CMD = ROSC_CMD_NOP; + while ((rROSC_CMD & ROSC_CMD_STOP) != 0); + /* Configure the ring osc */ + rROSC_CFG = ROSC_CFG_INT_DURATION | (1<<(ROSC_VTH - type + 3)) | (location<<0); + if (!period) { + u_int32_t res = 0; + /* one shot */ + rROSC_CUR_STAT = 0; + rROSC_CMD = ROSC_CMD_RUN_ONCE; + spin(1 * 1000); + while ((rROSC_CMD & ROSC_CMD_STOP) != 0) { + } + res = rROSC_CUR_STAT; + printf(" current: %dMHz\n", ((res + 2) * coe)/ROSC_1MHZ); + } else { + u_int32_t res1 = 0; + u_int32_t res2 = 0; + + /* Free run */ + rROSC_MAX_STAT = 0; + rROSC_MIN_STAT = 0xFFF; + rROSC_CMD = ROSC_CMD_START; + spin(period * 1000); + rROSC_CMD = ROSC_CMD_STOP; + + while ((rROSC_CMD & ROSC_CMD_STOP) != 0) { + } + res1 = rROSC_MAX_STAT; + res2 = rROSC_MIN_STAT; + printf(" maximum: %dMHz, minimum %dMHz\n", ((res1 + 2) * coe)/ROSC_1MHZ, ((res2 + 2) * coe)/ROSC_1MHZ); + + } +#if ROSC_WITH_CLOCK + clock_gate(CLK_ROSC, false); +#endif + return; +} + +#if defined(WITH_MENU) && WITH_MENU + +static int do_rosc(int argc, struct cmd_arg *args) +{ + int period; + + if (!security_allow_modes(kSecurityModeHWAccess)) { + printf("Permission Denied\n"); + return -1; + } + if (argc < 2) + period = 0; + else + period = args[1].u; + + if (period) { + printf("Ring OSC clock test in free run mode for %d mili seconds\n", period); + } else { + printf("Ring OSC clock test in one shot mode\n"); + } + + for (int i = 0; i < ROSC_NUM; i++) { + for (int j = 0; j < ROSC_VTH; j++) { + if ((1<<(i + j * 5)) & ROSC_MASK) { + switch (j) { + case 0: + printf(" HVT%d", i); + break; + case 1: + printf(" RVT%d", i); + break; + case 2: + printf(" LVT%d", i); + break; + default: + break; + } + rosc_ops(i, j, period); + } + } + } + return 0; +} +MENU_COMMAND_DEBUG(rosc, do_rosc, "Ring OSC reading", NULL); + +#endif diff --git a/drivers/samsung/rosc/rosc.h b/drivers/samsung/rosc/rosc.h new file mode 100644 index 0000000..28bd06d --- /dev/null +++ b/drivers/samsung/rosc/rosc.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_ROSC_H +#define __APPLE_ROSC_H + +#include + +#define ROSC_INTERVAL 0x40000 +#define ROSC_PRESCALE 0x100 +#define ROSC_VTH (3) +#define ROSC_NUM (5) + +#define rROSC_CMD (*(volatile u_int32_t *)(ROSC_BASE_ADDR + 0x000000)) +#define rROSC_CFG (*(volatile u_int32_t *)(ROSC_BASE_ADDR + 0x000004)) +#define rROSC_CUR_STAT (*(volatile u_int32_t *)(ROSC_BASE_ADDR + 0x000008)) +#define rROSC_MAX_STAT (*(volatile u_int32_t *)(ROSC_BASE_ADDR + 0x00000c)) +#define rROSC_MIN_STAT (*(volatile u_int32_t *)(ROSC_BASE_ADDR + 0x000010)) +#define rROSC_VER (*(volatile u_int32_t *)(ROSC_BASE_ADDR + 0x0000A0)) + +#define ROSC_CMD_NOP (0<<0) +#define ROSC_CMD_RUN_ONCE (1<<0) +#define ROSC_CMD_START (2<<0) +#define ROSC_CMD_STOP (3<<0) + +#define ROSC_CFG_INT_DURATION ((ROSC_INTERVAL-1)<<8) +#define ROSC_1MHZ 1000000 +#endif /* ! __APPLE_ROSC_H */ diff --git a/drivers/samsung/rosc/rules.mk b/drivers/samsung/rosc/rules.mk new file mode 100644 index 0000000..c51a9f9 --- /dev/null +++ b/drivers/samsung/rosc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_ROSC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/rosc.o diff --git a/drivers/samsung/sha1/rules.mk b/drivers/samsung/sha1/rules.mk new file mode 100644 index 0000000..f808877 --- /dev/null +++ b/drivers/samsung/sha1/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_SHA1=1 + +MODULES += \ + drivers/sha1 + +ALL_OBJS += \ + $(LOCAL_DIR)/sha1.o diff --git a/drivers/samsung/sha1/sha1.c b/drivers/samsung/sha1/sha1.c new file mode 100644 index 0000000..a914a08 --- /dev/null +++ b/drivers/samsung/sha1/sha1.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "sha1.h" + + +static const sha1_regs sha1_reg = { + &rSHA1_ADDR_CONF, &rSHA1_ADDR_SWRESET, &rSHA1_ADDR_INT_SRC, &rSHA1_ADDR_INT_MASK, + &rSHA1_ADDR_ENDIAN, &rSHA1_ADDR_CODE0, &rSHA1_ADDR_CODE1, &rSHA1_ADDR_CODE2, + &rSHA1_ADDR_CODE3, &rSHA1_ADDR_CODE4, &rSHA1_ADDR_DATA0, &rSHA1_ADDR_DATA1, + &rSHA1_ADDR_DATA2, &rSHA1_ADDR_DATA3, &rSHA1_ADDR_DATA4, &rSHA1_ADDR_DATA5, + &rSHA1_ADDR_DATA6, &rSHA1_ADDR_DATA7, &rSHA1_ADDR_DATA8, &rSHA1_ADDR_DATA9, + &rSHA1_ADDR_DATA10, &rSHA1_ADDR_DATA11, &rSHA1_ADDR_DATA12, &rSHA1_ADDR_DATA13, + &rSHA1_ADDR_DATA14, &rSHA1_ADDR_DATA15, &rSHA1_MASTER_MODE, &rSHA1_MS_START_ADDR, + &rSHA1_MS_SIZE }; +static sha1_status sha1Status = { 0, 0, 0 }; + +static void sha1Run(u_int8_t *buf); +static void Sha1NewInit(void); + +void Sha1NewAddEnd(u_int32_t dataLen, u_int32_t offset, u_int32_t startCmd); + + +static void Sha1NewInit(void) +{ + const sha1_regs *reg; + + reg = &sha1_reg; + clock_gate(CLK_SHA1, true); + + /* wait for SHA-1 engine idle */ + while(*reg->con & (0x1<<0)) + ; + /* Software reset */ + *reg->swreset = 0x1; + *reg->swreset = 0x0; + + /* Reset Configuration Register */ + *reg->con = 0x0; + + /* Always use slave mode */ + *reg->mode = 0x0; + + /* Always use twist / little endian */ + *reg->twist = 0x0; + + sha1Status.cmd = 1; + sha1Status.offset = 0; + sha1Status.length = 0; +} + +/* Fill the frame buffer and send it out + * the buffer size is always 64 bytes + * Caller is responsible to set the End bit and 0 padding + */ +static void sha1Run(u_int8_t *buf) +{ + const sha1_regs *reg; + + reg = &sha1_reg; + + /* Fill the buffer */ + for (int i = 0; i < 16; i++) { + volatile u_int32_t *data; + data = reg->data0; +#if WITH_UNALIGNED_MEM + *(data + i) = ((u_int32_t *)buf)[i]; +#else + *(data + i) = (buf[i*4] << 0)|(buf[i*4+1] << 8)|(buf[i*4+2] << 16)|(buf[i*4+3] << 24); +#endif + } + + /* Run the SHA1 engine */ + if (sha1Status.cmd) { + /* Start new hash code */ + *reg->con &= ~(1<<3); + sha1Status.cmd = 0; + } else { + /* Continue hash code */ + *reg->con |= (1<<3); + } + + *reg->con |= 1<<1; + while(*reg->con & (1<<0)) + ; +} + + +/************************************************************************ + * void sha1_hw_calculate(const void *buf, size_t len, u_int32_t *result) + * -- We are using slave mode only so the code would be portable + * between H1, H2, M1, M2. + * -- Caller's responsibility to make sure buffer can hold 20 bytes + * SHA1 code. + ************************************************************************/ +void sha1_hw_calculate(const void *buf, size_t len, u_int32_t *result) +{ + u_int32_t length, counter; + u_int8_t *frame; + u_int64_t sha1TotalBits; + u_int8_t sha1TotalLenAdd[8]; + const sha1_regs *reg; + + Sha1NewInit(); + + reg = &sha1_reg; + frame = (u_int8_t *)buf; + length = len; + counter =0; + + /* Prepare the 64 bits length */ + sha1TotalBits = len * 8; + sha1TotalLenAdd[0] = ((sha1TotalBits >> 32) & (0xff << 24)) >> 24; + sha1TotalLenAdd[1] = ((sha1TotalBits >> 32) & (0xff << 16)) >> 16; + sha1TotalLenAdd[2] = ((sha1TotalBits >> 32) & (0xff << 8)) >> 8; + sha1TotalLenAdd[3] = ((sha1TotalBits >> 32) & (0xff << 0)) >> 0; + sha1TotalLenAdd[4] = (sha1TotalBits & (0xff << 24)) >> 24; + sha1TotalLenAdd[5] = (sha1TotalBits & (0xff << 16)) >> 16; + sha1TotalLenAdd[6] = (sha1TotalBits & (0xff << 8)) >> 8; + sha1TotalLenAdd[7] = (sha1TotalBits & (0xff << 0)) >> 0; + + while (length > 64) { + sha1Run(&frame[sha1Status.length]); + sha1Status.length += 64; + length -= 64; + counter += 64; + if (0x7FFFF < counter) { + task_yield(); + counter = 0; + } + } + + if (length > 55) { + /* Not enough space for the length bytes */ + u_int8_t frameBuf[64]; + + for (u_int32_t i = 0; i < 64; i++) { + if (length > i) { + frameBuf[i] = frame[sha1Status.length++]; + } else if (length == i) { + frameBuf[i] = 0x80; + } else { + frameBuf[i] = 0x0; + } + } + sha1Run(frameBuf); + + /* Add End bit 0x80 if not added above */ + if (length == 64) { + frameBuf[0] = 0x80; + } else { + frameBuf[0] = 0x0; + } + + /* Start a new frame to hold the length */ + for (int j = 1; j < 56; j++) { + frameBuf[j] = 0x0; + } + + /* Now store the length */ + for (int k = 0; k < 8; k++) { + frameBuf[56 + k] = sha1TotalLenAdd[k]; + } + sha1Run(frameBuf); + } else { + /* Add End bit 0x80 and 0 padding */ + u_int8_t frameBuf[64]; + + for (u_int32_t i = 0; i < 56; i++) { + if (length > i) { + frameBuf[i] = frame[sha1Status.length++]; + } else if (length == i) { + frameBuf[i] = 0x80; + } else { + frameBuf[i] = 0x0; + } + } + + /* Now store the length */ + for (int j = 0; j < 8; j++) { + frameBuf[56 + j] = sha1TotalLenAdd[j]; + } + sha1Run(frameBuf); + + } + + /* Get the result */ + result[0] = *reg->code0; + result[1] = *reg->code1; + result[2] = *reg->code2; + result[3] = *reg->code3; + result[4] = *reg->code4; + + clock_gate(CLK_SHA1, false); +} diff --git a/drivers/samsung/sha1/sha1.h b/drivers/samsung/sha1/sha1.h new file mode 100644 index 0000000..ba66799 --- /dev/null +++ b/drivers/samsung/sha1/sha1.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __SAMSUNG_SHA1_H +#define __SAMSUNG_SHA1_H + +#include + +#define rSHA1_ADDR_CONF (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x00)) +#define rSHA1_ADDR_SWRESET (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x04)) +#define rSHA1_ADDR_INT_SRC (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x08)) +#define rSHA1_ADDR_INT_MASK (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x0C)) +#define rSHA1_ADDR_ENDIAN (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x10)) + +#define rSHA1_ADDR_CODE0 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x20)) +#define rSHA1_ADDR_CODE1 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x24)) +#define rSHA1_ADDR_CODE2 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x28)) +#define rSHA1_ADDR_CODE3 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x2C)) +#define rSHA1_ADDR_CODE4 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x30)) + +#define rSHA1_ADDR_DATA0 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x40)) +#define rSHA1_ADDR_DATA1 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x44)) +#define rSHA1_ADDR_DATA2 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x48)) +#define rSHA1_ADDR_DATA3 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x4C)) +#define rSHA1_ADDR_DATA4 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x50)) +#define rSHA1_ADDR_DATA5 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x54)) +#define rSHA1_ADDR_DATA6 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x58)) +#define rSHA1_ADDR_DATA7 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x5C)) +#define rSHA1_ADDR_DATA8 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x60)) +#define rSHA1_ADDR_DATA9 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x64)) +#define rSHA1_ADDR_DATA10 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x68)) +#define rSHA1_ADDR_DATA11 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x6C)) +#define rSHA1_ADDR_DATA12 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x70)) +#define rSHA1_ADDR_DATA13 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x74)) +#define rSHA1_ADDR_DATA14 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x78)) +#define rSHA1_ADDR_DATA15 (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x7C)) + +#define rSHA1_MASTER_MODE (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x80)) +#define rSHA1_MS_START_ADDR (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x84)) +#define rSHA1_VERISON (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x88)) +#define rSHA1_MS_SIZE (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x8C)) +#define rSHA1_FIFO_PARAM (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x90)) +#define rSHA1_FIFO_CMD (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x94)) +#define rSHA1_TX_FIFO_STAT (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0x98)) +#define rSHA1_TX_FIFO (*(volatile u_int32_t *)(SHA1_BASE_ADDR + 0xA0)) + +struct sha1_regs { + volatile u_int32_t *con; + volatile u_int32_t *swreset; + volatile u_int32_t *int_src; + volatile u_int32_t *int_mask; + volatile u_int32_t *twist; + + volatile u_int32_t *code0; + volatile u_int32_t *code1; + volatile u_int32_t *code2; + volatile u_int32_t *code3; + volatile u_int32_t *code4; + + volatile u_int32_t *data0; + volatile u_int32_t *data1; + volatile u_int32_t *data2; + volatile u_int32_t *data3; + volatile u_int32_t *data4; + volatile u_int32_t *data5; + volatile u_int32_t *data6; + volatile u_int32_t *data7; + volatile u_int32_t *data8; + volatile u_int32_t *data9; + volatile u_int32_t *data10; + volatile u_int32_t *data11; + volatile u_int32_t *data12; + volatile u_int32_t *data13; + volatile u_int32_t *data14; + volatile u_int32_t *data15; + + volatile u_int32_t *mode; + volatile u_int32_t *start_addr; + volatile u_int32_t *ms_size; +}; +typedef struct sha1_regs sha1_regs; + +struct sha1_status { + u_int32_t offset; + u_int32_t cmd; + u_int32_t length; +}; +typedef struct sha1_status sha1_status; + +#endif /* __SAMSUNG_SHA1_H */ diff --git a/drivers/samsung/spi/rules.mk b/drivers/samsung/spi/rules.mk new file mode 100644 index 0000000..600eaa3 --- /dev/null +++ b/drivers/samsung/spi/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_SPI=1 + +ALL_OBJS += $(LOCAL_DIR)/spi.o diff --git a/drivers/samsung/spi/spi.c b/drivers/samsung/spi/spi.c new file mode 100644 index 0000000..d13be5a --- /dev/null +++ b/drivers/samsung/spi/spi.c @@ -0,0 +1,721 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "spi.h" + +#ifndef SPIS_MASK +#define SPIS_MASK ((1 << SPIS_COUNT) - 1) +#endif + +#define SPI_DMA 0 + +#define SPI_AGD_MODE 1 + +//#define DEBUG_SPI_SPEW DEBUG_SPEW +#ifndef DEBUG_SPI_SPEW +#define DEBUG_SPI_SPEW (0x7FFFFFFF) +#endif + +/* previously from libc.h, but it pollutes the namespace there */ +#define BITS_SHIFT(x, high, low) (((x) >> (low)) & ((1<<((high)-(low)+1))-1)) + +/* spi driver, copy and customize */ + +enum spi_clk { + PCLK, + NCLK +}; + +static struct spi_status_t { + int bits; // 8, 16, 32 + int clkpol; // clock polarity + int clkpha; // clock phase + enum spi_clk clk; // PCLK or NCLK + int baud; + bool master; + bool dma; + + /* interrupt driven stuff */ + const void *tx_buf; + size_t tx_pos; + size_t tx_len; + void *rx_buf; + size_t rx_pos; + size_t rx_len; + int overrun_errors; + + struct task_event event; + + uint32_t shadow_spcon; + +#if SPI_DMA + /* dma stuff */ + dma_t tx_dma; + struct iovec tx_iov; + struct dma_xfer_t tx_xfer; + + dma_t rx_dma; + struct iovec rx_iov; + struct dma_xfer_t rx_xfer; +#endif + + /* completion flags */ + volatile int tx_complete; + volatile int rx_complete; +} spi_status[SPIS_COUNT]; + +typedef struct { + volatile uint32_t *spclkcon; + volatile uint32_t *spcon; + volatile uint32_t *spsta; + volatile uint32_t *sppin; + volatile uint32_t *sptdat; + volatile uint32_t *sprdat; + volatile uint32_t *sppre; + volatile uint32_t *spcnt; + volatile uint32_t *spidd; + volatile uint32_t *spirto; + volatile uint32_t *spihangd; + volatile uint32_t *spiswrst; + volatile uint32_t *spiver; + volatile uint32_t *sptdcnt; + uint32_t clock; + uint32_t irq; +} spi_regs_t; + +static const spi_regs_t spi_regs[] = { +#if SPIS_COUNT > 0 + { &rSPCLKCON0, &rSPCON0, &rSPSTA0, &rSPPIN0, &rSPTDAT0, &rSPRDAT0, &rSPPRE0, &rSPCNT0, + &rSPIDD0, &rSPIRTO0, &rSPIHANGD0, &rSPISWRST0, &rSPIVER0, &rSPTDCNT0, CLK_SPI0, INT_SPI0 }, +#endif +#if SPIS_COUNT > 1 + { &rSPCLKCON1, &rSPCON1, &rSPSTA1, &rSPPIN1, &rSPTDAT1, &rSPRDAT1, &rSPPRE1, &rSPCNT1, + &rSPIDD1, &rSPIRTO1, &rSPIHANGD1, &rSPISWRST1, &rSPIVER1, &rSPTDCNT1, CLK_SPI1, INT_SPI1 }, +#endif +#if SPIS_COUNT > 2 + { &rSPCLKCON2, &rSPCON2, &rSPSTA2, &rSPPIN2, &rSPTDAT2, &rSPRDAT2, &rSPPRE2, &rSPCNT2, + &rSPIDD2, &rSPIRTO2, &rSPIHANGD2, &rSPISWRST2, &rSPIVER2, &rSPTDCNT2, CLK_SPI2, INT_SPI2 }, +#endif +#if SPIS_COUNT > 3 + { &rSPCLKCON3, &rSPCON3, &rSPSTA3, &rSPPIN3, &rSPTDAT3, &rSPRDAT3, &rSPPRE3, &rSPCNT3, + &rSPIDD3, &rSPIRTO3, &rSPIHANGD3, &rSPISWRST3, &rSPIVER3, &rSPTDCNT3, CLK_SPI3, INT_SPI3 }, +#endif +#if SPIS_COUNT > 4 + { &rSPCLKCON4, &rSPCON4, &rSPSTA4, &rSPPIN4, &rSPTDAT4, &rSPRDAT4, &rSPPRE4, &rSPCNT4, + &rSPIDD4, &rSPIRTO4, &rSPIHANGD4, &rSPISWRST4, &rSPIVER4, &rSPTDCNT4, CLK_SPI4, INT_SPI4 }, +#endif +}; + +static const spi_regs_t *spiregs(int port) +{ + if (port < 0 || port >= SPIS_COUNT || !(SPIS_MASK & (1 << port))) + panic("Trying to access a nonexisted spi port\n"); + + return &spi_regs[port]; +} + +static void spi_set_port_enable(int port, bool enable) +{ + const spi_regs_t *regs = spiregs(port); + + if (enable) + *regs->spclkcon = 1; + else + *regs->spclkcon = 0; +} + +#if SPI_DMA +static void spi_set_port_dma(int port, bool dma) +{ + if (dma == spi_status[port].dma) + return; + + if (spi_status[port].dma) { + release_dma_channel(spi_status[port].tx_dma); + release_dma_channel(spi_status[port].rx_dma); + spi_status[port].tx_dma = spi_status[port].rx_dma = -1; + } + + if (dma) { + spi_status[port].tx_dma = acquire_dma_channel(DMA_DEVICE_MEMORY, DMA_DEVICE_SPI_0 + port, 1, 1); + spi_status[port].rx_dma = acquire_dma_channel(DMA_DEVICE_SPI_0 + port, DMA_DEVICE_MEMORY, 1, 1); + dprintf(DEBUG_INFO, "spi_set_port_dma: allocated channels, tx %d rx %d\n", spi_status[port].tx_dma, spi_status[port].rx_dma); + } + + spi_status[port].dma = dma; +} +#endif + +static void spi_set_baud(int port, int baud) +{ + const spi_regs_t *regs = spiregs(port); + uint32_t clkrate; + int div; + int actual_baud; + + if (spi_status[port].clk == PCLK) + clkrate = clock_get_frequency(CLK_PCLK); + else + clkrate = clock_get_frequency(CLK_NCLK); + + div = clkrate / baud; +#if SPI_VERSION > 0 + if (div < 1) div = 1; +#else + if (div < 2) div = 2; +#endif + actual_baud = clkrate / div; + + dprintf(DEBUG_SPI_SPEW, "spi_set_baud: port %d clk %s (%d Hz) baud %d, divider %d, actual baud %d\n", + port, (spi_status[port].clk == PCLK) ? "PCLK" : "NCLK", clkrate, baud, div, actual_baud); + + if (div >= (1<<10)) + dprintf(DEBUG_CRITICAL, "spi_set_baud: warning, div 0x%x is too big to fit in register\n", div); + + *regs->sppre = div; + spi_status[port].baud = baud; +} + +//small routine to get the baudrate for a divider +//helper function to be able todo automated testing +static int spi_baud_from_div(int port, int div) +{ + int clkrate; + + if (spi_status[port].clk == PCLK) + clkrate = clock_get_frequency(CLK_PCLK); + else + clkrate = clock_get_frequency(CLK_NCLK); + + if (div < 2) div = 2; + return (clkrate / div); +} + +void spi_set_interdatadelay(int port,int usecs) +{ + const spi_regs_t *regs = spiregs(port); + uint32_t clocks; + + clocks = ((1ULL * clock_get_frequency(CLK_PCLK) * usecs) + 1000000 - 1) / 1000000; + + *regs->spidd = clocks; + dprintf(DEBUG_SPI_SPEW, "spidd: %d\n",*regs->spidd); +} + +void spi_set_clk(int port, enum spi_clk clk) +{ + spi_status[port].clk = clk; +} + +void spi_setup(int port, int baud, int width, bool master, int clkpol, int clkpha) +{ + const spi_regs_t *regs = spiregs(port); + + if (regs == 0) + return; + + spi_set_port_enable(port, false); + + switch (width) { + default: + case 8: + spi_status[port].bits = 0; + break; + case 16: + spi_status[port].bits = 1; + break; + case 32: + spi_status[port].bits = 2; + break; + } + + spi_status[port].clkpol = clkpol ? 1 : 0; + spi_status[port].clkpha = clkpha ? 1 : 0; + spi_set_baud(port, baud); + spi_status[port].master = master; + + /* set up the control register */ + spi_status[port].shadow_spcon = + (spi_status[port].clkpha << SPICON_CPHA_SHIFT) | + (spi_status[port].clkpol << SPICON_CPOL_SHIFT) | + ((spi_status[port].master ? 3 : 0) << SPICON_MASTER_SHIFT) | // if in master mode, enable clock + ((spi_status[port].dma ? 2 : 1) << SPICON_MODE_SHIFT) | + (0 << SPICON_MSBFT_SHIFT) | // MSB first + (((spi_status[port].clk == PCLK) ? 0 : 1) << SPICON_CLK_SEL_SHIFT) | + (spi_status[port].bits << SPICON_BIT_LEN_SHIFT) | // 8/16/32 bit width + (0 << SPICON_DMA_SIZE_SHIFT); // 4 byte IRQ/DMA + *regs->spcon = spi_status[port].shadow_spcon; + + *regs->sppin = (1 << 1); + + spi_set_port_enable(port, true); // the port has to be enabled before you write to the FIFO. + + dprintf(DEBUG_SPI_SPEW, "spcon 0x%x\n", *regs->spcon); +} + +static void spi_flush_tx_fifo(int port) +{ + const spi_regs_t *regs = spiregs(port); + + *regs->spclkcon |= (1<<2); +} + +static void spi_flush_rx_fifo(int port) +{ + const spi_regs_t *regs = spiregs(port); + + *regs->spclkcon |= (1<<3); +} + +static void spi_interrupt(void *arg) +{ + int port = (int)arg; + const spi_regs_t *regs = spiregs(port); + uint32_t status; + uint32_t i; + + status = *regs->spsta; + *regs->spsta = status; + + dprintf(DEBUG_SPI_SPEW, "spi_interrupt(): %d, status 0x%08x / 0x%08x\n", port, status, *regs->spcon); + + if (status & (1 << 3)) { // data collision error + dprintf(DEBUG_SPI_SPEW, "spi_int, port %d: data collision (lost rx bytes)\n", port); + spi_status[port].overrun_errors++; + } + if (status & (1 << 0)) { // rx done + dprintf(DEBUG_SPI_SPEW, "spi_int, port %d: rx done, status 0x%x, tx pos %zu, rx pos %zu\n", + port, status, spi_status[port].tx_pos, spi_status[port].rx_pos); + dprintf(DEBUG_SPI_SPEW, "\ttx fifo %d rx fifo %d\n", + BITS_SHIFT(status, SPSTA_TX_FIFO_BIT_HI, SPSTA_TX_FIFO_BIT_LO), + BITS_SHIFT(status, SPSTA_RX_FIFO_BIT_HI, SPSTA_RX_FIFO_BIT_LO)); + if (!(status & ((1 << 22) | (1 << 1)))) + goto handle_rx; + } + if (status & ((1 << 22) | (1 << 1))) { // transfer done or ready + /* deal with tx */ +handle_tx: + if (spi_status[port].tx_buf) { + if (spi_status[port].tx_pos >= spi_status[port].tx_len) { + /* we're done */ + spi_status[port].tx_complete = 1; + spi_status[port].tx_buf = 0; +#if SPI_VERSION > 0 + spi_status[port].shadow_spcon &= ~(1 << SPICON_IE_TX_SHIFT); + *regs->spcon = spi_status[port].shadow_spcon; +#endif + dprintf(DEBUG_SPI_SPEW, "spi_tx %d: tx done, pos %zu len %zu\n", port, spi_status[port].tx_pos, spi_status[port].tx_len); + } else { + uint32_t txfifo_left = SPI_FIFO_SIZE - BITS_SHIFT(status, SPSTA_TX_FIFO_BIT_HI, SPSTA_TX_FIFO_BIT_LO); + uint32_t to_transfer = spi_status[port].tx_len - spi_status[port].tx_pos; + + to_transfer = __min(txfifo_left, to_transfer); + + dprintf(DEBUG_SPI_SPEW, "spi_tx %d: txfifo_left %d, to_transfer %d, pos %zu, len %zu\n", + port, txfifo_left, to_transfer, spi_status[port].tx_pos, spi_status[port].tx_len); + + for (i=0; i < to_transfer; i++) + *regs->sptdat = ((uint8_t *)spi_status[port].tx_buf)[spi_status[port].tx_pos + i]; + + spi_status[port].tx_pos += to_transfer; + } + } + + /* look for rx */ +handle_rx: + if (spi_status[port].rx_buf) { + uint32_t tmp; + uint32_t rxfifo = BITS_SHIFT(status, SPSTA_RX_FIFO_BIT_HI, SPSTA_RX_FIFO_BIT_LO); + uint32_t to_transfer = spi_status[port].rx_len - spi_status[port].rx_pos; + + to_transfer = __min(rxfifo, to_transfer); + + dprintf(DEBUG_SPI_SPEW, "spi_rx %d: fifo %d, to_transfer %d, pos %zu, len %zu\n", + port, rxfifo, to_transfer, spi_status[port].rx_pos, spi_status[port].rx_len); + + for (i=0; i < to_transfer; i++) { + tmp = *regs->sprdat; +// dprintf(DEBUG_SPI_SPEW, "sprdat: 0x%x\n",tmp); + ((uint8_t *)spi_status[port].rx_buf)[spi_status[port].rx_pos + i] = tmp; //*regs->sprdat; + } + + spi_status[port].rx_pos += to_transfer; + + if (spi_status[port].rx_pos >= spi_status[port].rx_len) { + spi_status[port].rx_complete = 1; + spi_status[port].rx_buf = 0; + spi_status[port].shadow_spcon &= ~(1 << SPICON_IE_RX_SHIFT); + *regs->spcon = spi_status[port].shadow_spcon; + //Hm, so RX finished, is it possible that TX is finished aswell? + goto handle_tx; + } + +#if !SPI_AGD_MODE + if (spi_status[port].tx_buf == 0) { + uint32_t txfifo_left = SPI_FIFO_SIZE - BITS_SHIFT(status, SPSTA_TX_FIFO_BIT_HI, SPSTA_TX_FIFO_BIT_LO); + uint32_t cnt = spi_status[port].rx_len - spi_status[port].rx_pos; + if (cnt > txfifo_left) cnt = txfifo_left; + while (cnt--) *regs->sptdat = 0xff; + } +#endif + } + } + + if ((spi_status[port].tx_buf == 0) && (spi_status[port].rx_buf == 0)) { + spi_status[port].shadow_spcon &= ~(1 << SPICON_IE_TR_SHIFT); + *regs->spcon = spi_status[port].shadow_spcon; + event_signal(&spi_status[port].event); + } +} + +#if SPI_DMA +static void spi_dma_tx_handler(struct dma_xfer_t *xfer, int error) +{ + struct spi_status_t *spi = xfer->user; + + dprintf(DEBUG_SPI_SPEW, "spi_dma_tx_handler(): %d\n", error); + + spi->tx_complete = 1; +} + +static void spi_dma_rx_handler(struct dma_xfer_t *xfer, int error) +{ + struct spi_status_t *spi = xfer->user; + + dprintf(DEBUG_SPI_SPEW, "spi_dma_rx_handler(): %d\n", error); + + spi->rx_complete = 1; +} + +static void spi_cancel_dma(int port) +{ + if(spi_status[port].dma) { + cancel_dma_transfers(spi_status[port].rx_dma); + cancel_dma_transfers(spi_status[port].tx_dma); + } +} +#endif + +bool spi_tx_complete(int port) +{ + return spi_status[port].tx_complete; +} + +bool spi_rx_complete(int port) +{ + return spi_status[port].rx_complete; +} + +int spi_write_etc(int port, const void *buf, size_t len, bool wait, bool with_rx) +{ + const spi_regs_t *regs = spiregs(port); + uint32_t i; + int err = 0; + + dprintf(DEBUG_SPI_SPEW, "spi_write(): port %d (%p) buf %p len %zu\n", port, &spi_status[port], buf, len); + + if (regs == 0) + return -1; + + /* clear the tx & rx fifos */ + spi_flush_tx_fifo(port); + spi_flush_rx_fifo(port); + +#if SPI_DMA + if (spi_status[port].dma) { + spi_status[port].tx_iov.iov_base = (void *)buf; + spi_status[port].tx_iov.iov_len = len; + spi_status[port].tx_xfer.dev_addr = (void *)regs->sptdat; + spi_status[port].tx_xfer.handler = spi_dma_tx_handler; + spi_status[port].tx_xfer.iov = &spi_status[port].tx_iov; + spi_status[port].tx_xfer.niov = 1; + spi_status[port].tx_xfer.user = &spi_status[port]; + spi_status[port].tx_xfer.platform_flags = H1_DMA_FLAG__8BIT_TRANSFER | H1_DMA_FLAG__4_BURST_PERIPHERAL; + spi_status[port].tx_complete = 0; + + if (!with_rx) + *regs->spcnt = 0; + + spi_set_port_enable(port, true); + + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, 0, 0); + err = queue_dma_transfer(spi_status[port].tx_dma, &spi_status[port].tx_xfer); + if (err < 0) { + dprintf(DEBUG_CRITICAL, "error 0x%x queuing tx dma\n", err); + return -1; + } + + if (wait) { + while (!spi_status[port].tx_complete || BITS_SHIFT(regs->spsta, SPSTA_TX_FIFO_BIT_HI, SPSTA_TX_FIFO_BIT_LO)) { + task_yield(); +// dprintf(DEBUG_SPI_SPEW, "spsta 0x%x\n", *regs->spsta); + } + err = len; + } + } else { +#endif + spi_status[port].tx_buf = buf; + spi_status[port].tx_pos = __min(len, 8u); + spi_status[port].tx_len = len; + spi_status[port].tx_complete = 0; + spi_status[port].rx_buf = 0; + spi_status[port].rx_pos = 0; + spi_status[port].rx_len = 0; + + event_unsignal(&spi_status[port].event); + + if (with_rx) { + spi_status[port].shadow_spcon |= (1 << SPICON_IE_RX_SHIFT); + } else { + *regs->spcnt = 0; + } + + for (i=0; i < spi_status[port].tx_pos; i++) + *regs->sptdat = ((uint8_t *)buf)[i]; + +#if SPI_VERSION > 0 + *regs->sptdcnt = len; + spi_status[port].shadow_spcon |= (1 << SPICON_IE_TX_SHIFT); +#endif + + spi_status[port].shadow_spcon |= (1 << SPICON_IE_TR_SHIFT); + *regs->spcon = spi_status[port].shadow_spcon; + + spi_set_port_enable(port, true); + + if (wait) { + while (!spi_status[port].tx_complete) { + event_wait(&spi_status[port].event); + } + + while (BITS_SHIFT(*regs->spsta, SPSTA_TX_FIFO_BIT_HI, SPSTA_TX_FIFO_BIT_LO)); + + err = len; + } +#if SPI_DMA + } +#endif + + return err; +} + +int spi_write(int port, const void *buf, size_t len) +{ + return spi_write_etc(port, buf, len, true, false); +} + +int spi_read_etc(int port, void *buf, size_t len, bool wait, bool with_tx) +{ + const spi_regs_t *regs = spiregs(port); + bool enable_tx_int = false; + int err = 0; + + dprintf(DEBUG_SPI_SPEW, "spi_read(): port %d (%p) buf %p len %zu\n", port, &spi_status[port], buf, len); + + if (regs == 0) + return -1; + + /* clear the tx & rx fifos */ + spi_flush_tx_fifo(port); + spi_flush_rx_fifo(port); + +#if SPI_DMA + if (spi_status[port].dma) { + spi_status[port].rx_iov.iov_base = (void *)buf; + spi_status[port].rx_iov.iov_len = len; + spi_status[port].rx_xfer.dev_addr = (void *)regs->sprdat; + spi_status[port].rx_xfer.handler = spi_dma_rx_handler; + spi_status[port].rx_xfer.iov = &spi_status[port].rx_iov; + spi_status[port].rx_xfer.niov = 1; + spi_status[port].rx_xfer.user = &spi_status[port]; + spi_status[port].rx_xfer.platform_flags = H1_DMA_FLAG__8BIT_TRANSFER | H1_DMA_FLAG__4_BURST_PERIPHERAL; + spi_status[port].rx_complete = 0; + + *regs->spcnt = len; + + spi_set_port_enable(port, true); + + if (!with_tx) { + spi_set_port_enable(port, true); + /* start the transmitter, which should start the receive */ + spi_status[port].shadow_spcon |= (1 << SPICON_AGD_SHIFT); // set auto garbage bit + } + + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, 0, 0); + err = queue_dma_transfer(spi_status[port].rx_dma, &spi_status[port].rx_xfer); + if (err < 0) { + dprintf(DEBUG_CRITICAL, "error 0x%x queuing rx dma\n", err); + return -1; + } + + if (wait) { + while (!spi_status[port].rx_complete) { + task_yield(); +// dprintf(DEBUG_SPI_SPEW, "spsta 0x%x\n", *regs->spsta); + } + if (!with_tx) { + spi_status[port].shadow_spcon &= ~(1 << SPICON_AGD_SHIFT); // clear auto garbage bit + *regs->spcon = spi_status[port].shadow_spcon; + } + err = len; + } + } else { +#endif + spi_status[port].rx_buf = buf; + spi_status[port].rx_pos = 0; + spi_status[port].rx_len = len; + spi_status[port].rx_complete = 0; + spi_status[port].overrun_errors = 0; + spi_status[port].tx_buf = 0; + spi_status[port].tx_pos = 0; + spi_status[port].tx_len = 0; + + event_unsignal(&spi_status[port].event); + + *regs->spcnt = len; + + spi_set_port_enable(port, true); + + if (with_tx) { + enable_tx_int = true; + } else { + /* start the transmitter, which should start the receive */ +#if SPI_AGD_MODE + spi_status[port].shadow_spcon |= (1 << SPICON_AGD_SHIFT); // set auto garbage bit +#else + int cnt = spi_status[port].rx_len - spi_status[port].rx_pos; + if (cnt > SPI_FIFO_SIZE) cnt = SPI_FIFO_SIZE; + while (cnt--) *regs->sptdat = 0xff; + enable_tx_int = true; +#endif + } + +#if SPI_VERSION > 0 + if (enable_tx_int) { + *regs->sptdcnt = len; + spi_status[port].shadow_spcon |= (1 << SPICON_IE_TX_SHIFT); + } +#endif + + spi_status[port].shadow_spcon |= (1 << SPICON_IE_RX_SHIFT) | (1 << SPICON_IE_TR_SHIFT); + *regs->spcon = spi_status[port].shadow_spcon; + + if (wait) { + while (!spi_status[port].rx_complete) { + event_wait(&spi_status[port].event); + } + if (!with_tx) { + spi_status[port].shadow_spcon &= ~(1 << SPICON_AGD_SHIFT); // clear auto garbage bit + *regs->spcon = spi_status[port].shadow_spcon; + } + + err = len; + } +#if SPI_DMA + } +#endif + + return err; +} + +int spi_read(int port, void *buf, size_t len) +{ + return spi_read_etc(port, buf, len, true, false); +} + +void spi_init(void) +{ + uint32_t port; + const spi_regs_t *regs; + + dprintf(DEBUG_CRITICAL, "spi_init()\n"); + + /* clear out the spi structure */ + bzero(spi_status, sizeof(spi_status)); + + for (port = 0; port < SPIS_COUNT; port++) { + regs = spiregs(port); + if (!regs) + continue; + + event_init(&spi_status[port].event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + /* make sure the clock is on for this device */ + clock_gate(regs->clock, true); + + /* default clock source to NCLK */ + spi_status[port].clk = NCLK; + + /* turn off all the spi ports */ + spi_set_port_enable(port, false); + +#if SPI_DMA + /* start off in interrupt driven mode */ + spi_status[port].tx_dma = spi_status[port].rx_dma = -1; + spi_set_port_dma(port, false); +#endif + + /* register interrupt handlers */ + install_int_handler(regs->irq, &spi_interrupt, (void *)port); + unmask_int(regs->irq); + } +} + +uint32_t spi_gpio_read(int port) +{ + const spi_regs_t *regs = spiregs(port); + + if (regs == 0) + return 0; + + return (*regs->sppin >> 1) & 1; +} + +void spi_gpio_write(int port, uint32_t val) +{ + const spi_regs_t *regs = spiregs(port); + + if (regs == 0) + return; + + if (val) *regs->sppin |= (1 << 1); + else *regs->sppin &= ~(1 << 1); +} + +void spi_gpio_configure(int port, uint32_t config) +{ + const spi_regs_t *regs = spiregs(port); + + if (regs == 0) + return; + + switch (config) { + case GPIO_CFG_OUT_0 : + *regs->sppin &= ~(1 << 1); + break; + + case GPIO_CFG_OUT_1 : + *regs->sppin |= (1 << 1); + break; + } +} diff --git a/drivers/samsung/spi/spi.h b/drivers/samsung/spi/spi.h new file mode 100644 index 0000000..687c239 --- /dev/null +++ b/drivers/samsung/spi/spi.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __SAMSUNG_SPI_H +#define __SAMSUNG_SPI_H + +#include + +#define rSPCLKCON0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x00)) +#define rSPCON0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x04)) +#define rSPSTA0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x08)) +#define rSPPIN0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x0C)) +#define rSPTDAT0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x10)) +#define rSPRDAT0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x20)) +#define rSPPRE0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x30)) +#define rSPCNT0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x34)) +#define rSPIDD0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x38)) +#define rSPIRTO0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x3C)) +#define rSPIHANGD0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x40)) +#define rSPISWRST0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x44)) +#define rSPIVER0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x48)) +#define rSPTDCNT0 (*(volatile u_int32_t *)(SPI0_BASE_ADDR + 0x4C)) + +#define rSPCLKCON1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x00)) +#define rSPCON1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x04)) +#define rSPSTA1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x08)) +#define rSPPIN1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x0C)) +#define rSPTDAT1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x10)) +#define rSPRDAT1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x20)) +#define rSPPRE1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x30)) +#define rSPCNT1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x34)) +#define rSPIDD1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x38)) +#define rSPIRTO1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x3C)) +#define rSPIHANGD1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x40)) +#define rSPISWRST1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x44)) +#define rSPIVER1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x48)) +#define rSPTDCNT1 (*(volatile u_int32_t *)(SPI1_BASE_ADDR + 0x4C)) + +#define rSPCLKCON2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x00)) +#define rSPCON2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x04)) +#define rSPSTA2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x08)) +#define rSPPIN2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x0C)) +#define rSPTDAT2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x10)) +#define rSPRDAT2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x20)) +#define rSPPRE2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x30)) +#define rSPCNT2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x34)) +#define rSPIDD2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x38)) +#define rSPIRTO2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x3C)) +#define rSPIHANGD2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x40)) +#define rSPISWRST2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x44)) +#define rSPIVER2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x48)) +#define rSPTDCNT2 (*(volatile u_int32_t *)(SPI2_BASE_ADDR + 0x4C)) + +#define rSPCLKCON3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x00)) +#define rSPCON3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x04)) +#define rSPSTA3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x08)) +#define rSPPIN3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x0C)) +#define rSPTDAT3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x10)) +#define rSPRDAT3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x20)) +#define rSPPRE3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x30)) +#define rSPCNT3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x34)) +#define rSPIDD3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x38)) +#define rSPIRTO3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x3C)) +#define rSPIHANGD3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x40)) +#define rSPISWRST3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x44)) +#define rSPIVER3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x48)) +#define rSPTDCNT3 (*(volatile u_int32_t *)(SPI3_BASE_ADDR + 0x4C)) + +#define rSPCLKCON4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x00)) +#define rSPCON4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x04)) +#define rSPSTA4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x08)) +#define rSPPIN4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x0C)) +#define rSPTDAT4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x10)) +#define rSPRDAT4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x20)) +#define rSPPRE4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x30)) +#define rSPCNT4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x34)) +#define rSPIDD4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x38)) +#define rSPIRTO4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x3C)) +#define rSPIHANGD4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x40)) +#define rSPISWRST4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x44)) +#define rSPIVER4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x48)) +#define rSPTDCNT4 (*(volatile u_int32_t *)(SPI4_BASE_ADDR + 0x4C)) + +#if SPI_VERSION == 0 +#define SPICON_SHIFT_OFFSET0 (0) +#define SPICON_SHIFT_OFFSET1 (0) +#define SPICON_SHIFT_OFFSET2 (0) +#else +#define SPICON_SHIFT_OFFSET0 (2) +#define SPICON_SHIFT_OFFSET1 (3) +#define SPICON_SHIFT_OFFSET2 (-1) +#endif + +#define SPICON_AGD_SHIFT (0) +#define SPICON_CPHA_SHIFT (1) +#define SPICON_CPOL_SHIFT (2) +#define SPICON_MASTER_SHIFT (3) +#define SPICON_CLK_EN_SHIFT (4) +#define SPICON_MODE_SHIFT (5) +#define SPICON_IE_RX_SHIFT (7) +#define SPICON_IE_TR_SHIFT (8) +#define SPICON_IE_MME_SHIFT (9) +#define SPICON_IE_DCE_SHIFT (10) +#define SPICON_MSBFT_SHIFT (11 + SPICON_SHIFT_OFFSET0) +#define SPICON_CLK_SEL_SHIFT (12 + SPICON_SHIFT_OFFSET0) +#define SPICON_BIT_LEN_SHIFT (13 + SPICON_SHIFT_OFFSET0) +#define SPICON_DMA_SIZE_SHIFT (15 + SPICON_SHIFT_OFFSET0) +#define SPICON_DATA_SWAP_SHIFT (16 + SPICON_SHIFT_OFFSET1) +#define SPICON_RX_DELAY_SHIFT (17 + SPICON_SHIFT_OFFSET1) +#define SPICON_IE_TX_SHIFT (21) +#define SPICON_DELAY_SEL_SHIFT (27 + SPICON_SHIFT_OFFSET2) + + +#if SPI_VERSION == 0 +#define SPI_FIFO_BITS (4) +#define SPSTA_TX_FIFO_BIT_LO (4) +#define SPSTA_RX_FIFO_BIT_LO (8) +#else +#define SPI_FIFO_BITS (5) +#define SPSTA_TX_FIFO_BIT_LO (6) +#define SPSTA_RX_FIFO_BIT_LO (11) +#endif + +#define SPSTA_TX_FIFO_BIT_HI (SPSTA_TX_FIFO_BIT_LO + SPI_FIFO_BITS - 1) +#define SPSTA_RX_FIFO_BIT_HI (SPSTA_RX_FIFO_BIT_LO + SPI_FIFO_BITS - 1) +#define SPI_FIFO_SIZE (1 << (SPI_FIFO_BITS - 1)) + +#endif /* __SAMSUNG_SPI_H */ diff --git a/drivers/samsung/swi/rules.mk b/drivers/samsung/swi/rules.mk new file mode 100644 index 0000000..1186650 --- /dev/null +++ b/drivers/samsung/swi/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_SWI=1 + +ALL_OBJS += $(LOCAL_DIR)/swi.o diff --git a/drivers/samsung/swi/swi.c b/drivers/samsung/swi/swi.c new file mode 100644 index 0000000..8930af9 --- /dev/null +++ b/drivers/samsung/swi/swi.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#include "swi.h" + +#define SWI_FREQUENCY (2000000) + +int swi_backlight_enable(u_int32_t iset_code, u_int32_t backlight_level) +{ + u_int32_t swi_div; + + clock_gate(CLK_SWI, true); + + swi_div = (clock_get_frequency(CLK_NCLK) + SWI_FREQUENCY - 1) / SWI_FREQUENCY; + + rSWI_CON = SWI_CON_SWI_CLK_DIV(swi_div - 1) | SWI_CON_SWI_OFF_STATE_HIGH | SWI_CON_SWI_EN; + + /* Some targets support 8 bits, others support 11. Assume that the input value is in range. */ + rSWI_ITR_DATA = 0x0080 | iset_code | ((backlight_level & 0x780) << 1) | (backlight_level & 0x7F); + + rSWI_ITR_COM = SWI_ITR_COM_SWI_ITR_MODE_16BIT | SWI_ITR_COM_SWI_ITR_SET; + while ((rSWI_ITR_COM & SWI_ITR_COM_SWI_ITR_SET) != 0); + +#ifdef GPIO_BACKLIGHT_EN + gpio_write(GPIO_BACKLIGHT_EN, (backlight_level != 0) ? GPIO_BACKLIGHT_POLARITY : !GPIO_BACKLIGHT_POLARITY); +#endif + + return 0; +} diff --git a/drivers/samsung/swi/swi.h b/drivers/samsung/swi/swi.h new file mode 100644 index 0000000..648bfac --- /dev/null +++ b/drivers/samsung/swi/swi.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __SAMSUNG_SWI_H +#define __SAMSUNG_SWI_H + +#include + +#define rSWI_CON (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x00)) +#define SWI_CON_SWI_CLK_DIV(n) (((n) & 0xFF) << 8) +#define SWI_CON_SWI_CLK_SEL_NCLK (0 << 2) +#define SWI_CON_SWI_CLK_SEL_PCLK (1 << 2) +#define SWI_CON_SWI_OFF_STATE_LOW (0 << 1) +#define SWI_CON_SWI_OFF_STATE_HIGH (1 << 1) +#define SWI_CON_SWI_EN (1 << 0) +#define rSWI_SWRESET (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x04)) +#define rSWI_TIMING (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x08)) +#define rSWI_INT_FLAG (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x0C)) +#define rSWI_INT_MASK (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x10)) +#define rSWI_ITR_COM (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x14)) +#define SWI_ITR_COM_SWI_ITR_MODE_8BIT (0 << 1) +#define SWI_ITR_COM_SWI_ITR_MODE_16BIT (1 << 1) +#define SWI_ITR_COM_SWI_ITR_SET (1 << 0) +#define rSWI_ITR_DATA (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x18)) +#define rSWI_STR_COM (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x1C)) +#define rSWI_STR_DATA (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x20)) +#define rSWI_STR_DLY (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x24)) +#define rSWI_HTR_COM (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x28)) +#define rSWI_HTR_DATA (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x2C)) +#define rSWI_VERISON (*(volatile u_int32_t *)(SWI_BASE_ADDR + 0x30)) + +#endif /* ! __SAMSUNG_SWI_H */ diff --git a/drivers/samsung/timer/rules.mk b/drivers/samsung/timer/rules.mk new file mode 100644 index 0000000..2a88625 --- /dev/null +++ b/drivers/samsung/timer/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_TIMER=1 + +ALL_OBJS += $(LOCAL_DIR)/timer.o diff --git a/drivers/samsung/timer/timer.c b/drivers/samsung/timer/timer.c new file mode 100644 index 0000000..1871bdd --- /dev/null +++ b/drivers/samsung/timer/timer.c @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "timer.h" + +/* 16-bit timers */ +#define TIMER_A 0 +#define TIMER_B 1 +#define TIMER_C 2 +#define TIMER_D 3 + +/* 32-bit timers */ +#define TIMER_E 4 +#define TIMER_F 5 +#define TIMER_G 6 +#define TIMER_H 7 + +/* 64-bit timer */ +#define TIMER_64 8 + +#define INVALID_TIMER -1 + +#ifndef TIMER_DEADLINE_TIMER +# if TIMER_DEADLINE_USE16 +# define TIMER_DEADLINE_TIMER TIMER_D +# else +# define TIMER_DEADLINE_TIMER TIMER_E +# endif +#endif + +/* timer16/32 stuff */ +typedef struct { + volatile u_int32_t *tcon; + volatile u_int32_t *tcmd; + volatile u_int32_t *tdata0; + volatile u_int32_t *tdata1; + volatile u_int32_t *tpre; + volatile u_int32_t *tcnt; +} timer_regs_t; + +static const timer_regs_t timer_regs_list[] = { + { &rTACON, &rTACMD, &rTADATA0, &rTADATA1, &rTAPRE, &rTACNT }, + { &rTBCON, &rTBCMD, &rTBDATA0, &rTBDATA1, &rTBPRE, &rTBCNT }, + { &rTCCON, &rTCCMD, &rTCDATA0, &rTCDATA1, &rTCPRE, &rTCCNT }, + { &rTDCON, &rTDCMD, &rTDDATA0, &rTDDATA1, &rTDPRE, &rTDCNT }, + { &rTECON, &rTECMD, &rTEDATA0, &rTEDATA1, &rTEPRE, &rTECNT }, + { &rTFCON, &rTFCMD, &rTFDATA0, &rTFDATA1, &rTFPRE, &rTFCNT }, + { &rTGCON, &rTGCMD, &rTGDATA0, &rTGDATA1, &rTGPRE, &rTGCNT }, + { &rTHCON, &rTHCMD, &rTHDATA0, &rTHDATA1, &rTHPRE, &rTHCNT } +}; +static const timer_regs_t *timer_regs(int timer); + +enum timer_clk { + PCLK, + NCLK, + SLOWCLK, +}; + +typedef struct { + /* configuration */ + enum timer_clk source_clk; + uint32_t divider_bits; + int prescalar; + + /* callout routine */ + void (*ovf_tick)(void); + void (*mat0_tick)(void); + void (*mat1_tick)(void); +} timer_status_t; + +static timer_status_t timer_status[TIMER_H+1]; + +enum timer_mode { + MODE_INTERVAL = 0, + MODE_PWM = 0x2, + MODE_PDM = 0x3, + MODE_ONESHOT_PWM = 0x4, + MODE_ONESHOT_PDM = 0x5, + MODE_CAPTURE = 0x6, +}; + +static void setup_timer(int timer, uint32_t data0, uint32_t data1, enum timer_mode mode, bool countdown, bool countdown_start, bool start_polarity); +static void setup_timer_clk(int timer, enum timer_clk clk, int divider, int prescalar); +static void start_stop_timer(int timer, bool start); + +static void timer_deadline(void); +static void (* timer_deadline_func)(void); + +/* timer 64 stuff */ +static u_int64_t read_timer64(void); + +static int timer64_ticks_per_sec; // for system time +static uint64_t timer64_scale; + +static void timer32_int(void *); +static void timer16_int(void *); + +static u_int64_t read_timer64(void) +{ + u_int32_t low, high; + +retry: + high = rTM64_CNTH; + low = rTM64_CNTL; + if (high != rTM64_CNTH) + goto retry; + + return (u_int64_t)high << 32 | low; +} + +static u_int32_t read_timer(int timer) +{ + const timer_regs_t *regs = timer_regs(timer); + + return *regs->tcnt; +} + +static const timer_regs_t *timer_regs(int timer) +{ + if (timer == TIMER_64) + panic("timer_regs: asked for invalid timer registers\n"); + + return &timer_regs_list[timer]; +} + +static void setup_timer_clk(int timer, enum timer_clk clk, int divider, int prescalar) +{ + if (clk == SLOWCLK) { + timer_status[timer].source_clk = PCLK; + timer_status[timer].divider_bits = 6; + } else { + timer_status[timer].source_clk = clk; + switch (divider) { + case 2: + timer_status[timer].divider_bits = 0; + break; + case 4: + timer_status[timer].divider_bits = 1; + break; + case 16: + timer_status[timer].divider_bits = 2; + break; + case 64: + timer_status[timer].divider_bits = 3; + break; + case 1: + timer_status[timer].divider_bits = 4; + break; + default: + dprintf(DEBUG_CRITICAL, "setup_timer_clk: invalid divider %d\n", divider); + } + } + timer_status[timer].prescalar = prescalar; +} + +static void setup_timer(int timer, uint32_t data0, uint32_t data1, enum timer_mode mode, bool countdown, bool countdown_start, bool start_polarity) +{ + start_stop_timer(timer, false); + + switch (timer) { + case TIMER_A: case TIMER_B: case TIMER_C: case TIMER_D: { + const timer_regs_t *regs = timer_regs(timer); + + /* setup timer (16 bit) */ + *regs->tcon = (start_polarity ? (1<<11) : 0) | + (mode << 3) | + (timer_status[timer].divider_bits<<8) | ((timer_status[timer].source_clk == NCLK) ? (1<<6) : 0) | + (7<<12); // mode, upcount (no downcount feature), divider, clock source, enable all ints + *regs->tpre = timer_status[timer].prescalar; + *regs->tdata0 = data0; + *regs->tdata1 = data1; + *regs->tcmd = 2; // initialize the timer + break; + } + case TIMER_E: case TIMER_F: case TIMER_G: case TIMER_H: { + const timer_regs_t *regs = timer_regs(timer); + + /* setup timer (32 bit) */ + *regs->tcon = (countdown_start ? (1<<28) : 0) | + (countdown ? (1<<24) : 0) | + (start_polarity ? (1<<11) : 0) | + (mode << 3) | + (timer_status[timer].divider_bits<<8) | ((timer_status[timer].source_clk == NCLK) ? (1<<6) : 0) | + (7<<12); // mode, downcount, pwm/pdm start bit, divider, clock source, enable all ints + *regs->tpre = timer_status[timer].prescalar; + *regs->tdata0 = data0; + *regs->tdata1 = data1; + *regs->tcmd = 2; // initialize the timer + break; + } + default: + panic("setup_timer: timer %d not supported\n", timer); + } +} + +static void start_stop_timer(int timer, bool start) +{ + switch (timer) { + case TIMER_A: case TIMER_B: case TIMER_C: case TIMER_D: + case TIMER_E: case TIMER_F: case TIMER_G: case TIMER_H: { + const timer_regs_t *regs = timer_regs(timer); + if (start) + *regs->tcmd = 1; // start it + else + *regs->tcmd = 0; // stop it + break; + } + case TIMER_64: + if (start) + rTM64_CON &= ~0xf; + else + rTM64_CON |= 0xa; + break; + default: + panic("start_stop_timer: timer %d not supported\n", timer); + } +} + +int timer_init(u_int32_t timer) +{ + dprintf(DEBUG_SPEW, "timers_init()\n"); + +#ifndef TIMER_NO_INIT + clock_gate(CLK_TIMER, true); + + /* stop all timers */ + start_stop_timer(TIMER_A, false); + start_stop_timer(TIMER_B, false); + start_stop_timer(TIMER_C, false); + start_stop_timer(TIMER_D, false); + start_stop_timer(TIMER_E, false); + start_stop_timer(TIMER_F, false); + start_stop_timer(TIMER_G, false); + start_stop_timer(TIMER_H, false); + start_stop_timer(TIMER_64, false); + + setup_timer_clk(TIMER_A, NCLK, 2, 0); + setup_timer_clk(TIMER_B, NCLK, 2, 0); + setup_timer_clk(TIMER_C, NCLK, 2, 0); + setup_timer_clk(TIMER_D, NCLK, 2, 0); + setup_timer_clk(TIMER_E, NCLK, 2, 0); + setup_timer_clk(TIMER_F, NCLK, 2, 0); + setup_timer_clk(TIMER_G, NCLK, 2, 0); + setup_timer_clk(TIMER_H, NCLK, 2, 0); + + /* set up the 64-bit timer */ + rTM64_CON = 0xa; // disable it + rTM64_DATA0L = 0xffffffff; + rTM64_DATA0H = 0xffffffff; + rTM64_DATA1L = 0xffffffff; + rTM64_DATA1H = 0xffffffff; + rTM64_CON = (3<<15) | (1 << 4); // set nclk source, prescalar at /2, enable + + /* calculate how fast timer64 is running */ + timer64_ticks_per_sec = clock_get_frequency(CLK_NCLK) / 2; +#else +# ifndef TIMER_TICK_RATE +# error TIMER_TICK_RATE not defined but we did not init the timebase +# endif + timer64_ticks_per_sec = TIMER_TICK_RATE; +#endif + + // Precompute a 44.20 fixed-point representation of the microsecond to ticks conversion rate. + // This limits the maximum number of microseconds that can be represented to 44 bits worth of ticks. + timer64_scale = ((uint64_t)timer64_ticks_per_sec << 20) / (1000 * 1000); + + dprintf(DEBUG_SPEW, "timer64 running at %u Hz, will wrap around in %llu secs\n", + timer64_ticks_per_sec, 0xffffffffffffffffULL / timer64_ticks_per_sec); + + dprintf(DEBUG_SPEW, "using 64-bit timer for system time\n"); + + /* install interrupt handler */ +#if TIMER_DEADLINE_USE16 + install_int_handler(INT_TIMERIRQ, &timer16_int, (void *)1); + unmask_int(INT_TIMERIRQ); +#else + install_int_handler(INT_TIMERFIQ, &timer32_int, (void *)1); + unmask_int(INT_TIMERFIQ); +#endif + + return 0; +} + +void timer_gpio(int timer, int level) +{ + setup_timer(timer, 0, 0, MODE_PWM, false, false, level); +} + +static void timer_handle_int(int timer, u_int32_t status) +{ + if (status & (1<<2)) { + // overflow + if (timer_status[timer].ovf_tick) + timer_status[timer].ovf_tick(); + } + if (status & (1<<1)) { + // int1 + if (timer_status[timer].mat1_tick) + timer_status[timer].mat1_tick(); + } + if (status & (1<<0)) { + // int0 + if (timer_status[timer].mat0_tick) + timer_status[timer].mat0_tick(); + } +} + +static void timer16_int(void *arg) +{ + u_int32_t tcon; + + tcon = rTACON; + if (tcon & (7<<16)) { + timer_handle_int(TIMER_A, tcon >> 16); + rTACON |= tcon & (7<<16); + } + tcon = rTBCON; + if (tcon & (7<<16)) { + timer_handle_int(TIMER_B, tcon >> 16); + rTBCON |= tcon & (7<<16); + } + tcon = rTCCON; + if (tcon & (7<<16)) { + timer_handle_int(TIMER_C, tcon >> 16); + rTCCON |= tcon & (7<<16); + } + tcon = rTDCON; + if (tcon & (7<<16)) { + timer_handle_int(TIMER_D, tcon >> 16); + rTDCON |= tcon & (7<<16); + } +} + +static void timer32_int(void *arg) +{ + u_int32_t tm32_status, tm32_ack, status, cnt; + + tm32_status = rTM32_INT; + tm32_ack = 0; + cnt = 0; + +#if TIMER_VERSION != 0 + status = (tm32_status >> (cnt * 8)) & 0x7; + timer_handle_int(TIMER_H, status); + tm32_ack |= (status << (cnt * 8)); + cnt++; +#endif + status = (tm32_status >> (cnt * 8)) & 0x7; + timer_handle_int(TIMER_G, status); + tm32_ack |= (status << (cnt * 8)); + cnt++; + + status = (tm32_status >> (cnt * 8)) & 0x7; + timer_handle_int(TIMER_F, status); + tm32_ack |= (status << (cnt * 8)); + cnt++; + + status = (tm32_status >> (cnt * 8)) & 0x7; + timer_handle_int(TIMER_E, status); + tm32_ack |= (status << (cnt * 8)); + cnt++; + + rTM32_INT = tm32_ack; +} + +static void timer_deadline(void) +{ + +// printf("deadline interrupt at %llu\n", read_timer64()); + /* stop the timer */ + start_stop_timer(TIMER_DEADLINE_TIMER, false); + + /* call the handler */ + if (timer_deadline_func) + timer_deadline_func(); +} + +u_int64_t timer_get_ticks() +{ + return read_timer64(); +} + +u_int32_t timer_get_tick_rate(void) +{ + return timer64_ticks_per_sec; +} + +utime_t timer_ticks_to_usecs(uint64_t ticks) +{ + return (ticks * 1000 * 1000) / timer64_ticks_per_sec; +} + +uint64_t timer_usecs_to_ticks(utime_t usecs) +{ + return (usecs * timer64_scale) >> 20; +} + +void timer_stop_all(void) +{ +#ifndef TIMER_NO_INIT + /* stop all timers */ + start_stop_timer(TIMER_A, false); + start_stop_timer(TIMER_B, false); + start_stop_timer(TIMER_C, false); + start_stop_timer(TIMER_D, false); + start_stop_timer(TIMER_E, false); + start_stop_timer(TIMER_F, false); + start_stop_timer(TIMER_G, false); + start_stop_timer(TIMER_H, false); + start_stop_timer(TIMER_64, false); +#endif +} + +void timer_deadline_enter(uint64_t deadline, void (* callback)(void)) +{ + uint64_t ticks; + uint32_t decr; + + timer_deadline_func = callback; + if (callback != NULL) { + /* convert absolute deadline to relative time */ + ticks = read_timer64(); + if (deadline <= ticks) { +// printf("setting deadline %llu before current time %llu\n", deadline, ticks); + deadline = 1; + } else { +// printf("setting deadline %llu (0x%llx away)\n", deadline, deadline - ticks); + deadline -= ticks; + } + + /* clamp the deadline to our maximum */ +#if TIMER_DEADLINE_USE16 + decr = (deadline > 0xffff) ? 0xffff : deadline; +#else + decr = (deadline > 0xffffffff) ? 0xffffffff : deadline; +#endif +// printf(" decr 0x%x\n", decr); + + /* + * Start the timer in interval mode. We will stop it when we handle the + * interrupt, so it doesn't really matter as long as we get an interrupt after + * (decr) ticks or so. + */ + timer_status[TIMER_DEADLINE_TIMER].mat0_tick = timer_deadline; + setup_timer(TIMER_DEADLINE_TIMER, decr, 0, MODE_INTERVAL, false, false, 0); + start_stop_timer(TIMER_DEADLINE_TIMER, true); + } else { + /* stop the timer */ + start_stop_timer(TIMER_DEADLINE_TIMER, false); + } +} + +u_int32_t timer_get_entropy(void) +{ + return arch_get_entropy(&rTM64_CNTL); +} + +void wdt_enable(void) +{ + rWDTCON = (1 << 20) | (15 << 16) | (4 << 12) | (0xA << 8); +} + +void wdt_chip_reset(void) +{ + rWDTCON = (1 << 20) | (0 << 16) | (0 << 15) | (0 << 12) | (0 << 8) | (0 << 0); +} diff --git a/drivers/samsung/timer/timer.h b/drivers/samsung/timer/timer.h new file mode 100644 index 0000000..2f5e979 --- /dev/null +++ b/drivers/samsung/timer/timer.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __SAMSUNG_TIMER_H +#define __SAMSUNG_TIMER_H + +#include + +/** +* Timer A +*/ +#define rTACON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x0)) +#define rTACMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x4)) +#define rTADATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x8)) +#define rTADATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xC)) +#define rTAPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x10)) +#define rTACNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x14)) +/** +* Timer B +*/ +#define rTBCON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x20)) +#define rTBCMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x24)) +#define rTBDATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x28)) +#define rTBDATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x2C)) +#define rTBPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x30)) +#define rTBCNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x34)) +/** +* Timer C +*/ +#define rTCCON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x40)) +#define rTCCMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x44)) +#define rTCDATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x48)) +#define rTCDATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x4C)) +#define rTCPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x50)) +#define rTCCNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x54)) +/** +* Timer D +*/ +#define rTDCON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x60)) +#define rTDCMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x64)) +#define rTDDATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x68)) +#define rTDDATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x6C)) +#define rTDPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x70)) +#define rTDCNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x74)) + +//64-Bit Timer Register +#define rTM64_CNTH (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x80)) +#define rTM64_CNTL (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x84)) +#define rTM64_CON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x88)) + +#define rTM64_DATA0H (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x8C)) +#define rTM64_DATA0L (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x90)) +#define rTM64_DATA1H (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x94)) +#define rTM64_DATA1L (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x98)) +/** +* Timer E +*/ +#define rTECON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xA0)) +#define rTECMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xA4)) +#define rTEDATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xA8)) +#define rTEDATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xAC)) +#define rTEPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xB0)) +#define rTECNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xB4)) +/** +* Timer F +*/ +#define rTFCON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xC0)) +#define rTFCMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xC4)) +#define rTFDATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xC8)) +#define rTFDATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xCC)) +#define rTFPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xD0)) +#define rTFCNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xD4)) +/** +* Timer G +*/ +#define rTGCON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xE0)) +#define rTGCMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xE4)) +#define rTGDATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xE8)) +#define rTGDATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xEC)) +#define rTGPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xF0)) +#define rTGCNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xF4)) +/** +* Timer H +*/ +#define rTHCON (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x100)) +#define rTHCMD (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x104)) +#define rTHDATA0 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x108)) +#define rTHDATA1 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x10C)) +#define rTHPRE (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x100)) +#define rTHCNT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x104)) + +#if TIMER_VERSION == 0 +#define rTM32_INT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0xF8)) +#else +#define rTM32_INT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x118)) +#endif + +#define rTM_INT (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x10000)) +/** +* Timer counter register (RO) +*/ +#define rTM32_CNT_E (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x10004)) +#define rTM32_CNT_F (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x10008)) +#define rTM32_CNT_G (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x1000C)) + +#define rTM64_CNTH2 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x10010)) +#define rTM64_CNTL2 (*(volatile u_int32_t *)(TIMER_BASE_ADDR + 0x10014)) + + +#define rWDTCON (*(volatile u_int32_t *)(WDT_BASE_ADDR + 0x00)) +#define rWDTCNT (*(volatile u_int32_t *)(WDT_BASE_ADDR + 0x04)) + +#endif /* __SAMSUNG_TIMER_H */ diff --git a/drivers/samsung/uart/rules.mk b/drivers/samsung/uart/rules.mk new file mode 100644 index 0000000..cd8a91f --- /dev/null +++ b/drivers/samsung/uart/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_UART=1 + +ALL_OBJS += $(LOCAL_DIR)/uart.o diff --git a/drivers/samsung/uart/uart.c b/drivers/samsung/uart/uart.c new file mode 100644 index 0000000..436eb0c --- /dev/null +++ b/drivers/samsung/uart/uart.c @@ -0,0 +1,683 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_TARGET_CONFIG +#include +#elif WITH_PLATFORM_UARTCONFIG +#include +#endif + +#include "uart.h" + +#ifndef UARTS_MASK +#define UARTS_MASK ((1 << UARTS_COUNT) - 1) +#endif + +#ifndef UART_FLOWCONTROL_MASK +#define UART_FLOWCONTROL_MASK (0x0E) +#endif + + +#define UART_RX_LEN 16 + +// defined in sys/debug.c +extern int DebugUartReady; + +static void uart_interrupt(void *); +static int tx_fifo_count(int port); +static int rx_fifo_count(int port); +static void uart_dump_config(int port); +static void uart_clear_rx(int port); +static int uart_rx_complete(int port); +static void uart_clear_tx(int port); +static int uart_tx_complete(int port); +static void drain_rx_fifo(int port); + +typedef struct { + volatile u_int32_t *ulcon; + volatile u_int32_t *ucon; + volatile u_int32_t *ufcon; + volatile u_int32_t *umcon; + volatile u_int32_t *utrstat; + volatile u_int32_t *uerstat; + volatile u_int32_t *ufstat; + volatile u_int32_t *umstat; + volatile u_int32_t *utxh; + volatile u_int32_t *urxh; + volatile u_int32_t *ubrdiv; + volatile u_int32_t *uabrcnt; + int clock; + u_int32_t irq; +} uart_regs_t; + +static const uart_regs_t uart_regs[] = { +#if UARTS_COUNT > 0 + { &rULCON0, &rUCON0, &rUFCON0, &rUMCON0, &rUTRSTAT0, &rUERSTAT0, &rUFSTAT0, &rUMSTAT0, &rUTXH0, &rURXH0, &rUBRDIV0, &rUABRCNT0, CLK_UART0, INT_UART0 }, +#endif +#if UARTS_COUNT > 1 + { &rULCON1, &rUCON1, &rUFCON1, &rUMCON1, &rUTRSTAT1, &rUERSTAT1, &rUFSTAT1, &rUMSTAT1, &rUTXH1, &rURXH1, &rUBRDIV1, &rUABRCNT1, CLK_UART1, INT_UART1 }, +#endif +#if UARTS_COUNT > 2 + { &rULCON2, &rUCON2, &rUFCON2, &rUMCON2, &rUTRSTAT2, &rUERSTAT2, &rUFSTAT2, &rUMSTAT2, &rUTXH2, &rURXH2, &rUBRDIV2, &rUABRCNT2, CLK_UART2, INT_UART2 }, +#endif +#if UARTS_COUNT > 3 + { &rULCON3, &rUCON3, &rUFCON3, &rUMCON3, &rUTRSTAT3, &rUERSTAT3, &rUFSTAT3, &rUMSTAT3, &rUTXH3, &rURXH3, &rUBRDIV3, &rUABRCNT3, CLK_UART3, INT_UART3 }, +#endif +#if UARTS_COUNT > 4 + { &rULCON4, &rUCON4, &rUFCON4, &rUMCON4, &rUTRSTAT4, &rUERSTAT4, &rUFSTAT4, &rUMSTAT4, &rUTXH4, &rURXH4, &rUBRDIV4, &rUABRCNT4, CLK_UART4, INT_UART4 }, +#endif +#if UARTS_COUNT > 5 + { &rULCON5, &rUCON5, &rUFCON5, &rUMCON5, &rUTRSTAT5, &rUERSTAT5, &rUFSTAT5, &rUMSTAT5, &rUTXH5, &rURXH5, &rUBRDIV5, &rUABRCNT5, CLK_UART5, INT_UART5 }, +#endif +#if UARTS_COUNT > 6 + { &rULCON6, &rUCON6, &rUFCON6, &rUMCON6, &rUTRSTAT6, &rUERSTAT6, &rUFSTAT6, &rUMSTAT6, &rUTXH6, &rURXH6, &rUBRDIV6, &rUABRCNT6, CLK_UART6, INT_UART6 }, +#endif +#if UARTS_COUNT > 7 + { &rULCON7, &rUCON7, &rUFCON7, &rUMCON7, &rUTRSTAT7, &rUERSTAT7, &rUFSTAT7, &rUMSTAT7, &rUTXH7, &rURXH7, &rUBRDIV7, &rUABRCNT7, CLK_UART7, INT_UART7 }, +#endif +#if UARTS_COUNT > 8 + { &rULCON8, &rUCON8, &rUFCON8, &rUMCON8, &rUTRSTAT8, &rUERSTAT8, &rUFSTAT8, &rUMSTAT8, &rUTXH8, &rURXH8, &rUBRDIV8, &rUABRCNT8, CLK_UART8, INT_UART8 }, +#endif +#if UARTS_COUNT > 9 +#error "Need to add more entries to uart_regs" +#endif +}; + +enum uart_mode { + MODE_POLL, + MODE_INT, +}; + +enum uart_clk { + PCLK, + NCLK, + SLOWCLK, +}; + +static struct uart_status { + int port; + int baud; + int sample_rate; + bool flow_en; + bool fifo_en; + enum uart_mode mode; + bool nclk; // false is pclk + + /* Interrupt mode */ + CBUFFER rx_cbuf; + + struct task_event rx_event; + + /* completion flags */ + volatile int tx_complete; + volatile int rx_complete; +} uart_status[UARTS_COUNT]; + +static void uart_set_sample_rate(int port, int rate); +static void uart_set_baud_rate(int port, u_int32_t baud_rate); +static void uart_set_flow_control(int port, bool flow); +static void uart_set_fifo_enable(int port, bool enable); +static void uart_set_mode(int port, enum uart_mode mode); +static void uart_set_clk(int port, enum uart_clk clk); + +static int uart_read(int port, void *_buf, size_t len, bool wait); +static int uart_write(int port, const void *_buf, size_t len, bool wait); + +static const uart_regs_t *uregs(int port) +{ + if (port < 0 || port >= UARTS_COUNT || !(UARTS_MASK & (1 << port))) + panic("invalid uart\n"); + + return &uart_regs[port]; +} + +static void uart_set_sample_rate(int port, int rate) +{ + const uart_regs_t *regs = uregs(port); + +#if UART_VERSION == 0 + switch (rate) { + case 4: + *regs->ubrdiv = (*regs->ubrdiv & ~(3<<16)) | (2<<16); + uart_status[port].sample_rate = 4; + break; + case 8: + *regs->ubrdiv = (*regs->ubrdiv & ~(3<<16)) | (1<<16); + uart_status[port].sample_rate = 8; + break; + case 16: + *regs->ubrdiv = (*regs->ubrdiv & ~(3<<16)) | (0<<16); + uart_status[port].sample_rate = 16; + break; + default: + printf("uart_set_sample_rate: invalid rate %d\n", rate); + return; + } +#else + if ((rate < 4) || (rate > 16)) { + printf("uart_set_sample_rate: invalid rate %d\n", rate); + return; + } + *regs->ubrdiv = (*regs->ubrdiv & ~(0xF<<16)) | ((16 - rate)<<16); + uart_status[port].sample_rate = rate; +#endif + + /* based on the new info, set the baud rate */ + uart_set_baud_rate(port, uart_status[port].baud); +} + +static void uart_set_clk(int port, enum uart_clk clk) +{ + const uart_regs_t *regs = uregs(port); + + switch (clk) { + case PCLK: + uart_status[port].nclk = false; + *regs->ucon &= ~(1<<10); + break; + case NCLK: + uart_status[port].nclk = true; + *regs->ucon |= (1<<10); + break; + default: + panic("uart_set_clk: invalid clock\n"); + } + + /* based on the new info, set the baud rate */ + uart_set_baud_rate(port, uart_status[port].baud); +} + +static void uart_set_baud_rate(int port, u_int32_t baud_rate) +{ + const uart_regs_t *regs = uregs(port); + u_int32_t baud_low, actual_baud; + int div; + u_int32_t clk; + + if (uart_status[port].nclk) + clk = clock_get_frequency(CLK_NCLK); + else + clk = clock_get_frequency(CLK_PCLK); +#if UART_CLOCK_SOURCE_OVERRIDE + clk = UART_CLOCK_SOURCE_OVERRIDE; +#endif + if (uart_status[port].sample_rate == 0) { + // sample_rate isn't set yet, can't calculate baud. + return; + } + div = clk / (baud_rate * uart_status[port].sample_rate); + + actual_baud = clk / ((div + 0) * uart_status[port].sample_rate); + baud_low = clk / ((div + 1) * uart_status[port].sample_rate); + + if ((baud_rate - baud_low) < (actual_baud - baud_rate)) { + div++; + actual_baud = baud_low; + } + + *regs->ubrdiv = (*regs->ubrdiv & ~0xFFFF) | (div - 1); + + printf("uart_set_baud_rate: port %d, baud %d, sample %d, divider %d, actual baud %d\n", + port, baud_rate, uart_status[port].sample_rate, div - 1, actual_baud); + + uart_status[port].baud = baud_rate; +} + +static void uart_set_flow_control(int port, bool flow) +{ + const uart_regs_t *regs = uregs(port); + + if (port == 0) { + printf("%s: uart 0 does not support flow control\n", __FUNCTION__); + return; + } + + if (flow) { + *regs->umcon = 0x10; // set auto flow control + } else { + *regs->umcon = 0x01; // assert RTS + } + uart_status[port].flow_en = flow; +} + +static void uart_set_fifo_enable(int port, bool enable) +{ + const uart_regs_t *regs = uregs(port); + + if (enable) { + *regs->ufcon = 0x6; // reset both fifos + *regs->ufcon = (0<<6)|(0<<4)|0x1; // enable fifo, tx trigger level 0, rx trigger level 4 + } else { + *regs->ufcon = 0; // disable all fifos + } + uart_status[port].fifo_en = enable; +} + +static void uart_set_mode(int port, enum uart_mode mode) +{ + const uart_regs_t *regs = uregs(port); + int old_mode; + + printf("uart_set_mode: port %d, mode %d\n", port, mode); + + old_mode = uart_status[port].mode; + uart_status[port].mode = mode; + + switch (mode) { + case MODE_POLL: { + // no interrupts in polled mode + *regs->ucon &= ~((0xf<<11)|(1<<7)); + *regs->ucon = (*regs->ucon & ~0xf) | 0x5; // tx/rx polled/int mode + break; + } + case MODE_INT: { + // interrupt mode + *regs->ucon = (*regs->ucon & ~(0xf<<11)) | ((0xb<<11)|(1<<7)); //enable read/error/timeout and disable write interrupt + *regs->ucon = (*regs->ucon & ~0xf) | 0x5; // tx/rx polled/int mode + break; + } + default: + panic("uart_set_mode: unsupport modei\n "); + + } +} + +static void uart_interrupt(void *arg) +{ + /* to-do: the interrupt routine */ + int port = (int)arg; + const uart_regs_t *regs = uregs(port); + u_int32_t utr_status; + u_int32_t uer_status; + + utr_status = *regs->utrstat; + *regs->utrstat = utr_status; + uer_status = *regs->uerstat; + *regs->uerstat = uer_status; + + if (utr_status & (1 << 6)) { // Error interrupt + /* Error, eat up that byte and move on */ + volatile int hole; + hole = *regs->urxh; + } + + if (utr_status & (3 << 3)) { // Rx or timeout interrupt + CBUFFER *pcb = &uart_status[port].rx_cbuf; + if (uart_status[port].fifo_en) { + while ((rx_fifo_count(port) > 0) && cb_free_space(pcb)) { + cb_putc_unsafe(pcb, *regs->urxh); + } + } else { + if (utr_status & (1 << 0)) { + cb_putc_unsafe(pcb, *regs->urxh); + } + } + /* signal reader */ + event_signal(&uart_status[port].rx_event); + } + return; +} + +static void uart_dump_config(int port) +{ + if (port >= UARTS_COUNT) return; + + if (port < 0) { + for (port = 0; port < UARTS_COUNT; port++) { + uart_dump_config(port); + } + return; + } + + printf("uart %d config: baud %d sample %d flow %d fifo %d ", port, + uart_status[port].baud, uart_status[port].sample_rate, + uart_status[port].flow_en, uart_status[port].fifo_en); + switch (uart_status[port].mode) { + case MODE_POLL: + printf("polled "); + break; + case MODE_INT: + printf("interrupt-mode"); + break; + } + printf("\n"); +} + +static int uart_debug_reader_task(void *arg) +{ + int port = (int)arg; + u_int8_t port_mask = 0; + + switch (port) { +#if defined(DEBUG_SERIAL_PORT) + case DEBUG_SERIAL_PORT : port_mask = kPowerNVRAMiBootDebugIAPSerial; break; +#endif +#if defined(DEBUG_SERIAL_PORT2) + case DEBUG_SERIAL_PORT2 : port_mask = kPowerNVRAMiBootDebugAltSerial; break; +#endif + default: break; + } + + for(;;) { + char c; + int len; + + /* use interrupt mode */ + len = uart_read(port, &c, 1, true); + if ((len > 0) && ((DebugUartReady & port_mask) != 0)) { + debug_pushchar(c); + } + } + return 0; +} + +int uart_init(void) +{ + int port, oversample = 16; + enum uart_clk clock = NCLK; + const uart_regs_t *regs; + +#ifdef UART_CLOCK_OVERRIDE + clock = UART_CLOCK_OVERRIDE; +#endif + +#ifdef UART_OVERSAMPLE_OVERRIDE + oversample = UART_OVERSAMPLE_OVERRIDE; +#endif + + for (port = 0; port < UARTS_COUNT; port++) { + if (!(UARTS_MASK & (1 << port))) + continue; + + regs = uregs(port); + + cb_create(&uart_status[port].rx_cbuf, UART_RX_LEN); + + event_init(&uart_status[port].rx_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + uart_status[port].port = port; + uart_status[port].baud = 115200; + + /* make sure the clock is on for this block */ + clock_gate(regs->clock, true); + + /* put the uarts in a default state */ + *regs->ulcon = 0x03; /* 81N, not IR */ + *regs->ucon = 0x05; /*interrupt/polled mode, PCLK source, all ints disabled */ + +#if defined(HDQGAUGE_SERIAL_PORT) + if (HDQGAUGE_SERIAL_PORT == port) { + uart_status[port].baud = 57600; + *regs->ulcon = 0x07; /* 82N */ + } +#endif + + uart_set_clk(port, clock); + + /* Set sample rate to 16x to avoid issues with the lower ones*/ + uart_set_sample_rate(port, oversample); + + uart_set_flow_control(port, UART_FLOWCONTROL_MASK & (1 << port)); + + uart_set_fifo_enable(port, true); + + uart_set_mode(port, MODE_POLL); + + /* register the interrupt handler */ + install_int_handler(regs->irq, &uart_interrupt, (void *)port); + unmask_int(regs->irq); + } + +#if defined(DEBUG_SERIAL_PORT) + if (DEBUG_SERIAL_PORT != 0) + uart_set_flow_control(DEBUG_SERIAL_PORT, false); + /* the fifo trigger level for Rx can not be zero -- 4 bytes is the lowest, so no fifo */ + uart_set_fifo_enable(DEBUG_SERIAL_PORT, false); + uart_set_mode(DEBUG_SERIAL_PORT, MODE_INT); + task_start(task_create("uart reader", uart_debug_reader_task, (void *)DEBUG_SERIAL_PORT, 0x200)); +#endif +#if defined(DEBUG_SERIAL_PORT2) + if (DEBUG_SERIAL_PORT2 != 0) + uart_set_flow_control(DEBUG_SERIAL_PORT2, false); + /* the fifo trigger level for Rx can not be zero -- 4 bytes is the lowest, so no fifo */ + uart_set_fifo_enable(DEBUG_SERIAL_PORT2, false); + uart_set_mode(DEBUG_SERIAL_PORT2, MODE_INT); + task_start(task_create("uart reader2", uart_debug_reader_task, (void *)DEBUG_SERIAL_PORT2, 0x200)); +#endif + +#if DEBUG_UART_ENABLE_DEFAULT + DebugUartReady |= kPowerNVRAMiBootDebugIAPSerial | kPowerNVRAMiBootDebugAltSerial; +#endif + return 0; +} + +int uart_hw_init_extended(u_int32_t port, u_int32_t baudrate, u_int32_t databits, enum uart_parity parity, u_int32_t stopbits) +{ + const uart_regs_t *regs = uregs(port); + u_int32_t ulcon = 0; + + uart_status[port].baud = baudrate; + + switch (databits) { + case 5: ulcon |= (0 << 0); break; + case 6: ulcon |= (1 << 0); break; + case 7: ulcon |= (2 << 0); break; + case 8: ulcon |= (3 << 0); break; + default: return -1; + } + + switch (parity) { + case PARITY_NONE: ulcon |= (0 << 3); break; + case PARITY_ODD: ulcon |= (4 << 3); break; + case PARITY_EVEN: ulcon |= (5 << 3); break; + default: return -1; + } + + switch(stopbits) { + case 1: ulcon |= (0 << 2); break; + case 2: ulcon |= (1 << 2); break; + default: return -1; + } + + uart_set_fifo_enable(port, false); + + *regs->ulcon = ulcon; + + uart_set_baud_rate(port, uart_status[port].baud); + + uart_set_fifo_enable(port, true); + + return 0; +} + +int uart_hw_set_rx_buf(u_int32_t port, bool interrupt, size_t buffer_len) +{ + /* Reconfigure a port for interrupt/polled and explicit buffer len */ + struct uart_status *st = &uart_status[port]; + *uregs(port)->ucon &= ~(1<<12); // disable interrupt + if (cb_initialized(&st->rx_cbuf)) + cb_free(&st->rx_cbuf); + cb_create(&st->rx_cbuf, buffer_len); + uart_set_mode(port, interrupt ? MODE_INT : MODE_POLL); + return 0; +} + +static int uart_write(int port, const void *_buf, size_t len, bool wait) +{ + const uart_regs_t *regs = uregs(port); + const u_int8_t *buf = (const u_int8_t *)_buf; + u_int32_t i; + switch (uart_status[port].mode) { + case MODE_INT: + case MODE_POLL: { + for (i=0; i < len; i++) { + if (uart_status[port].fifo_en) { + while ((*regs->ufstat) & 0x200) { + } + } else { + while (!((*regs->utrstat) & 0x04)) + ; + } + if (uart_status[port].flow_en) { + while (((*regs->utrstat) & 4) == 0); // Wait Transmitter Empty + while (((*regs->umstat) & 1) == 0); // Wait CTS Asserted + } + *regs->utxh = buf[i]; + } + break; + } + default: + panic("uart_write: unhandled mode\n"); + } + + return len; +} + +static int tx_fifo_count(int port) +{ + const uart_regs_t *regs = uregs(port); + int fifo_count = *regs->ufstat & ((1<<9)|(0xf<<4)); + fifo_count = ((fifo_count >> 4) & 0xf) | (fifo_count >> 5); + return fifo_count; +} + +static int rx_fifo_count(int port) +{ + const uart_regs_t *regs = uregs(port); + int fifo_count = *regs->ufstat & ((1<<8)|0xf); + fifo_count = (fifo_count & 0xf) | (fifo_count >> 4); + return fifo_count; +} + +static void drain_rx_fifo(int port) +{ + volatile char hole; + + if (uart_status[port].fifo_en) { + const uart_regs_t *regs = uregs(port); + + while (rx_fifo_count(port) > 0) { + hole = *regs->urxh; + } + } +} + +static int uart_read(int port, void *_buf, size_t len, bool wait) +{ + const uart_regs_t *regs = uregs(port); + u_int8_t *buf = (u_int8_t *)_buf; + u_int32_t i = 0; + + switch (uart_status[port].mode) { + case MODE_POLL: { + volatile int hole; + for (i=0; i < len; i++) { +retry_polled_read: + if (uart_status[port].fifo_en) { + while (rx_fifo_count(port) == 0) { + if (!wait) + return i; + task_yield(); + } + } else { + while (!((*regs->utrstat) & 0x01)) { + if (!wait) + return i; + task_yield(); + } + } + if (*regs->uerstat) { + /* some sort of error queued up, eat this character and move on */ + hole = *regs->urxh; + goto retry_polled_read; + } + buf[i] = *regs->urxh; + } + break; + } + case MODE_INT: { + /* in interrupt mode, always wait */ + CBUFFER *pcb = &uart_status[port].rx_cbuf; +retry_intr_read: + if (wait && (!cb_readable_size(pcb))) + event_wait(&uart_status[port].rx_event); + + /* disable rx interrupt */ + *regs->ucon &= ~(1<<12); + + i += cb_read_unsafe(pcb, buf + i, len - i); + + /* enable rx interrupt */ + *regs->ucon |= (1<<12); + + if ((i < len) && wait) + goto retry_intr_read; + break; + } + default: + panic("uart_read: unhandled mode\n"); + } + + return i; +} + +static int uart_rx_complete(int port) +{ + return uart_status[port].rx_complete; +} + +int uart_putc(int port, char c) +{ + return uart_write(port, &c, 1, true); +} + +int uart_puts(int port, const char *s) +{ + int len = strlen(s); + uart_write(port, s, len, true); + return 0; +} + +int uart_getc(int port, bool wait) /* returns -1 if no data available */ +{ + char c; + int len; + + len = uart_read(port, &c, 1, wait); + if (len == 0) + return -1; + + return c; +} + +int uart_send_break(int port, bool enable) +{ + const uart_regs_t *regs = uregs(port); + if (enable) + *regs->ucon |= (1 << 4); + else + *regs->ucon &= ~(1 << 4); + + return 0; +} diff --git a/drivers/samsung/uart/uart.h b/drivers/samsung/uart/uart.h new file mode 100644 index 0000000..b3e2aef --- /dev/null +++ b/drivers/samsung/uart/uart.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __SAMSUNG_UART_H +#define __SAMSUNG_UART_H + +#include + +#define rULCON0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x00)) +#define rUCON0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x04)) +#define rUFCON0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x08)) +#define rUMCON0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x0C)) +#define rUTRSTAT0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x10)) +#define rUERSTAT0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x14)) +#define rUFSTAT0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x18)) +#define rUMSTAT0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x1C)) +#define rUBRDIV0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x28)) +#define rUABRCNT0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x2C)) +#define rUTXH0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x20)) +#define rURXH0 (*(volatile u_int32_t *)(UART0_BASE_ADDR + 0x24)) + +#define rULCON1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x00)) +#define rUCON1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x04)) +#define rUFCON1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x08)) +#define rUMCON1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x0C)) +#define rUTRSTAT1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x10)) +#define rUERSTAT1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x14)) +#define rUFSTAT1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x18)) +#define rUMSTAT1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x1C)) +#define rUBRDIV1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x28)) +#define rUABRCNT1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x2C)) +#define rUTXH1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x20)) +#define rURXH1 (*(volatile u_int32_t *)(UART1_BASE_ADDR + 0x24)) + +#define rULCON2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x00)) +#define rUCON2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x04)) +#define rUFCON2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x08)) +#define rUMCON2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x0C)) +#define rUTRSTAT2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x10)) +#define rUERSTAT2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x14)) +#define rUFSTAT2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x18)) +#define rUMSTAT2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x1C)) +#define rUBRDIV2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x28)) +#define rUABRCNT2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x2C)) +#define rUTXH2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x20)) +#define rURXH2 (*(volatile u_int32_t *)(UART2_BASE_ADDR + 0x24)) + +#define rULCON3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x00)) +#define rUCON3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x04)) +#define rUFCON3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x08)) +#define rUMCON3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x0C)) +#define rUTRSTAT3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x10)) +#define rUERSTAT3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x14)) +#define rUFSTAT3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x18)) +#define rUMSTAT3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x1C)) +#define rUBRDIV3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x28)) +#define rUABRCNT3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x2C)) +#define rUTXH3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x20)) +#define rURXH3 (*(volatile u_int32_t *)(UART3_BASE_ADDR + 0x24)) + +#define rULCON4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x00)) +#define rUCON4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x04)) +#define rUFCON4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x08)) +#define rUMCON4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x0C)) +#define rUTRSTAT4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x10)) +#define rUERSTAT4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x14)) +#define rUFSTAT4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x18)) +#define rUMSTAT4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x1C)) +#define rUBRDIV4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x28)) +#define rUABRCNT4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x2C)) +#define rUTXH4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x20)) +#define rURXH4 (*(volatile u_int32_t *)(UART4_BASE_ADDR + 0x24)) + +#define rULCON5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x00)) +#define rUCON5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x04)) +#define rUFCON5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x08)) +#define rUMCON5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x0C)) +#define rUTRSTAT5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x10)) +#define rUERSTAT5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x14)) +#define rUFSTAT5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x18)) +#define rUMSTAT5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x1C)) +#define rUBRDIV5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x28)) +#define rUABRCNT5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x2C)) +#define rUTXH5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x20)) +#define rURXH5 (*(volatile u_int32_t *)(UART5_BASE_ADDR + 0x24)) + +#define rULCON6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x00)) +#define rUCON6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x04)) +#define rUFCON6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x08)) +#define rUMCON6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x0C)) +#define rUTRSTAT6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x10)) +#define rUERSTAT6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x14)) +#define rUFSTAT6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x18)) +#define rUMSTAT6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x1C)) +#define rUBRDIV6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x28)) +#define rUABRCNT6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x2C)) +#define rUTXH6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x20)) +#define rURXH6 (*(volatile u_int32_t *)(UART6_BASE_ADDR + 0x24)) + +#define rULCON7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x00)) +#define rUCON7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x04)) +#define rUFCON7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x08)) +#define rUMCON7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x0C)) +#define rUTRSTAT7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x10)) +#define rUERSTAT7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x14)) +#define rUFSTAT7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x18)) +#define rUMSTAT7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x1C)) +#define rUBRDIV7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x28)) +#define rUABRCNT7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x2C)) +#define rUTXH7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x20)) +#define rURXH7 (*(volatile u_int32_t *)(UART7_BASE_ADDR + 0x24)) + +#define rULCON8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x00)) +#define rUCON8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x04)) +#define rUFCON8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x08)) +#define rUMCON8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x0C)) +#define rUTRSTAT8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x10)) +#define rUERSTAT8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x14)) +#define rUFSTAT8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x18)) +#define rUMSTAT8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x1C)) +#define rUBRDIV8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x28)) +#define rUABRCNT8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x2C)) +#define rUTXH8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x20)) +#define rURXH8 (*(volatile u_int32_t *)(UART8_BASE_ADDR + 0x24)) + +#endif /* __SAMSUNG_UART_H */ diff --git a/drivers/samsung/usbphy/rules.mk b/drivers/samsung/usbphy/rules.mk new file mode 100644 index 0000000..47353ca --- /dev/null +++ b/drivers/samsung/usbphy/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_USBPHY=1 + +ALL_OBJS += $(LOCAL_DIR)/usbphy.o diff --git a/drivers/samsung/usbphy/usbphy.c b/drivers/samsung/usbphy/usbphy.c new file mode 100644 index 0000000..e9b863e --- /dev/null +++ b/drivers/samsung/usbphy/usbphy.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "usbphy.h" + +static bool usb_phy_powered = false; + +// Add support for multiple USB OTG controllers to iBoot +// G1 USBBPHY USB OTG2 bit assignments are totally inconsistent +#if WITH_CONJOINED_USB_PHYS + +#if USBPHY_VERSION > 2 +#error "Conjoined USB PHYs not compatible with PHY version > 2" +#endif + +#define SELECTED_PHY (1) + +#define SET_REG(reg, value) set_reg(reg, SELECTED_PHY, reg##_SHIFT, (value)) +#define SET_REG_BITS(reg, value, mask) set_reg_bits(reg, SELECTED_PHY, reg##_SHIFT, (value), (mask)) +#define GET_REG(reg) get_reg(reg, SELECTED_PHY, reg##_SHIFT) + +static void set_reg(volatile u_int32_t *reg, int index, int shift, u_int32_t value) +{ + u_int32_t mask = ((1 << shift) - 1) << (shift * index); + *reg = (*reg & ~mask) | (value << (shift * index)); +} + +static void set_reg_bits(volatile u_int32_t *reg, int index, int shift, u_int32_t value, u_int32_t mask) +{ + mask = mask << (shift * index); + *reg = (*reg & ~mask) | (value << (shift * index)); +} + +static u_int32_t get_reg(volatile u_int32_t *reg, int index, int shift) +{ + return (*reg >> shift) & ((1 << shift) - 1); +} + +#else + +#define SET_REG(reg, value) *(reg) = (value) +#define SET_REG_BITS(reg, value, mask) *(reg) = (*(reg) & ~(mask)) | (value) +#define GET_REG(reg) *(reg) + +#endif + + +static void gate_clocks(bool enable) +{ + if (enable) { +#if USBPHY_VERSION > 2 + clock_gate(CLK_UPERF, true); +#endif + + clock_gate(CLK_USBOTG, true); + clock_gate(CLK_USBPHY, true); + } else { + clock_gate(CLK_USBOTG, false); + clock_gate(CLK_USBPHY, false); + +#if USBPHY_VERSION > 2 + clock_gate(CLK_UPERF, false); +#endif + } +} + + +//--------------------------------------------------------------------------- +// FUNCTION: usbphy_power_up +// +// DESCRIPTION: Does initial powering up to bring up the PHY +// +// RETURN: None +// +// NOTES: This should be one of the first things done upon startup. +//--------------------------------------------------------------------------- +void usbphy_power_up(void) +{ + u_int32_t clk_sel = 0; + + if (usb_phy_powered) return; + + platform_power_set_gate(PWRBIT_USB, true); + spin(10*1000); + + gate_clocks(true); + + // Clear the StopPclk & GateHclk bits in the power and clock gating register + *USB_PCGCCTL &= ~(PCGCCTL_StopPclk | PCGCCTL_GateHclk); + + spin(100); + +#if USBPHY_VERSION > 1 + *USB_USBHOSTSET = (1 << 9); // enable hsic, this will cause STB and DAT to stay low +#endif + + switch (clock_get_frequency(CLK_USBPHYCLK)) { + case 12000000UL : clk_sel = 0; break; + case 24000000UL : clk_sel = 1; break; + case 48000000UL : clk_sel = 2; break; + default : clk_sel = 3; break; + } + +#if USBPHY_VERSION > 0 + SET_REG(USB_PHYPWR, (0UL<<4) | // powerup analog block + (0UL<<3) | // powerup OTG block + (USBPHY_CLK_TYPE << 1) | // select the reference clock + (0UL<<0)); // disable suspend signal for power save + + SET_REG(USB_UVLDCON, (1 << 2)); // Set vbus_vld_ext_sel + +#else + *USB_PHYPWR = (0UL<<4) | // powerup analog block + (0UL<<3) | // powerup XO block + (USBPHY_CLK_TYPE << 2) | // select the reference for XO block + (0UL<<1) | // powerup PLL + (0UL<<0); // disable suspend signal for power save + + /* Correct the field assinment for version 0 */ + clk_sel ^= 1; +#endif + +#ifdef USBPHY_UOTGTUNE1 + SET_REG(USB_UOTGTUNE1, USBPHY_UOTGTUNE1); +#endif +#ifdef USBPHY_UOTGTUNE2 + SET_REG(USB_UOTGTUNE2, USBPHY_UOTGTUNE2); +#endif + + spin(10); + +#if WITH_CONJOINED_USB_PHYS + // G1: Implement G1-specific USB PHY settings + *USB_URSV |= (1 << 4); +#endif + + SET_REG_BITS(USB_PHYCON, clk_sel, 0x3); + + // reset the PHY + SET_REG_BITS(USB_URSTCON, 1, 1); + spin(20); // need to assert for at least 10us + SET_REG_BITS(USB_URSTCON, 0, 1); + spin(1000); // need to wait for at least 805us + + usb_phy_powered = true; +} + +void usbphy_enable_pullup(void) +{ + if (!usb_phy_powered) + return; + + // Enable D+ PU + SET_REG_BITS(USB_UVLDCON, (1 << 1), (1 << 1)); // Set vbus_vld_ext +} + +//--------------------------------------------------------------------------- +// FUNCTION: usbphy_power_down +// +// DESCRIPTION: Powers down the PHY upon USB shutdown +// +// RETURN: None +// +// NOTES: This should be one of the last things done upon shutdown. +//--------------------------------------------------------------------------- +void usbphy_power_down(void) +{ + platform_power_set_gate(PWRBIT_USB, true); + gate_clocks(true); + + // set bits 0-4 to 1 to power down the PHY + SET_REG(USB_PHYPWR, (1UL<<5)-1); + +#if USBPHY_VERSION == 0 + // assert S/W Reset for PHY_CLK and HCLK Domains + SET_REG_BITS(USB_URSTCON, (1<<2)|(1<<1), (1<<2)|(1<<1)); +#endif + + // assert S/W Reset for PHY + SET_REG_BITS(USB_URSTCON, (1<<0), (1<<0)); + spin(1000); + +#if USBPHY_VERSION > 0 + *USB_UVLDCON &= ~(1 << 1); // Clear vbus_vld_ext + SET_REG_BITS(USB_UVLDCON, 0, (1<<1)); +#endif + + gate_clocks(false); + platform_power_set_gate(PWRBIT_USB, false); + + usb_phy_powered = false; +} + +bool usbphy_is_cable_connected(void) +{ + bool connected; + + if (!usb_phy_powered) { +#if USBPHY_VERSION > 2 + clock_gate(CLK_UPERF, true); +#endif + clock_gate(CLK_USBPHY, true); + } + + connected = (GET_REG(USB_UCONDET) & 1) != 0; + + if (!usb_phy_powered) { +#if USBPHY_VERSION > 2 + clock_gate(CLK_UPERF, false); +#endif + clock_gate(CLK_USBPHY, false); + } + + return connected; +} + +bool usbphy_set_dpdm_monitor(int select) +{ + u_int32_t bits; + + switch (select) { + case kUSB_DP: + bits = 1 << 1; + break; + case kUSB_DM: + bits = 2 << 1; + break; + case kUSB_NONE: + bits = 0 << 1; + break; +#if USBPHY_VERSION >= 4 + case kUSB_DCD: + bits = (1 << 14) | (1 << 13) | (1 << 10) | (1 << 9) | (1 << 1); + break; + case kUSB_CP1: + bits = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (2 << 1); + break; +#endif + default: + return false; + }; + + if (!usb_phy_powered) { +#if USBPHY_VERSION > 2 + clock_gate(CLK_UPERF, true); +#endif + clock_gate(CLK_USBPHY, true); + } + +#if USBPHY_VERSION >= 4 + *USB_UPADCON = (*USB_UPADCON & ((0x3f << 3) | (1 << 0))) | bits; +#else + SET_REG_BITS(USB_UPADCON, bits, 3 << 1); +#endif + + if (!usb_phy_powered) { +#if USBPHY_VERSION > 2 + clock_gate(CLK_UPERF, false); +#endif + clock_gate(CLK_USBPHY, false); + } + + return true; +} + +#if WITH_DEVICETREE +void usbphy_update_device_tree(DTNode *node) +{ + u_int32_t propSize; + char *propName; + void *propData; + u_int32_t phy_tuning2_val; + + phy_tuning2_val = 0; + +#ifdef USBPHY_UOTGTUNE2 + phy_tuning2_val = USBPHY_UOTGTUNE2; +#endif + + // Fill in the phy-tuning-val property + propName = "phy-tuning-val"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(phy_tuning2_val)) { + *(u_int32_t *)propData = phy_tuning2_val; + } + } +} +#endif diff --git a/drivers/samsung/usbphy/usbphy.h b/drivers/samsung/usbphy/usbphy.h new file mode 100644 index 0000000..fbe1853 --- /dev/null +++ b/drivers/samsung/usbphy/usbphy.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __SAMSUNG_USBPHY_H +#define __SAMSUNG_USBPHY_H + +#include +#include +#include + +// HW-OTG control registers +#define USB_PCGCCTL ((volatile u_int32_t *)(USBOTG_BASE_ADDR + 0x0E00)) + +#define PCGCCTL_PhySuspended (1UL << 4) +#define PCGCCTL_RstPdwnModule (1UL << 3) +#define PCGCCTL_PwrClmp (1UL << 2) +#define PCGCCTL_GateHclk (1UL << 1) +#define PCGCCTL_StopPclk (1UL << 0) + +// HS-OTG Phy control registers +#define USB_PHYPWR ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0000)) +#define USB_PHYCON ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0004)) +#define USB_URSTCON ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0008)) +#define USB_UVLDCON ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x001C)) +#define USB_UCONDET ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0028)) +#define USB_URESCON ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0034)) +#define USB_UOTGTUNE1 ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0040)) +#define USB_UOTGTUNE2 ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0044)) +#define USB_UPADCON ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0048)) +#define USB_USBHOSTSET ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0060)) +#define USB_URSV ((volatile u_int32_t *)(USBPHY_BASE_ADDR + 0x0100)) + +// Add support for multiple USB OTG controllers to iBoot +// G1 USBBPHY USB OTG2 bit assignments are totally inconsistent +#define USB_PHYPWR_SHIFT 5 +#define USB_PHYCON_SHIFT 5 +#define USB_URSTCON_SHIFT 5 +#define USB_UVLDCON_SHIFT 9 +#define USB_UCONDET_SHIFT 10 +#define USB_UOTGTUNE1_SHIFT 11 +#define USB_UOTGTUNE2_SHIFT 13 +#define USB_UPADCON_SHIFT 3 + +#endif /* ! __SAMSUNG_USBPHY_H */ diff --git a/drivers/sha1/mozilla_sha.c b/drivers/sha1/mozilla_sha.c new file mode 100644 index 0000000..be2c1fb --- /dev/null +++ b/drivers/sha1/mozilla_sha.c @@ -0,0 +1,164 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is SHA 180-1 Reference Implementation (Compact version) + * + * The Initial Developer of the Original Code is Paul Kocher of + * Cryptography Research. Portions created by Paul Kocher are + * Copyright (C) 1995-9 by Cryptography Research, Inc. All + * Rights Reserved. + * + * Contributor(s): + * + * Paul Kocher + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +#if (!WITH_CORECRYPTO || !WITH_VFP) && !WITH_HW_SHA1 + +#include "mozilla_sha.h" + +static void shaHashBlock(SHA_CTX *ctx); + +void shaInit(SHA_CTX *ctx) { + int i; + + ctx->lenW = 0; + ctx->sizeHi = ctx->sizeLo = 0; + + /* Initialize H with the magic constants (see FIPS180 for constants) + */ + ctx->H[0] = 0x67452301L; + ctx->H[1] = 0xefcdab89L; + ctx->H[2] = 0x98badcfeL; + ctx->H[3] = 0x10325476L; + ctx->H[4] = 0xc3d2e1f0L; + + for (i = 0; i < 80; i++) + ctx->W[i] = 0; +} + + +void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, u_int32_t len) { + u_int32_t i; + + /* Read the data into W and process blocks as they get full + */ + for (i = 0; i < len; i++) { + ctx->W[ctx->lenW / 4] <<= 8; + ctx->W[ctx->lenW / 4] |= (u_int32_t)dataIn[i]; + if ((++ctx->lenW) % 64 == 0) { + shaHashBlock(ctx); + ctx->lenW = 0; + } + ctx->sizeLo += 8; + ctx->sizeHi += (ctx->sizeLo < 8); + } +} + + +void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]) { + unsigned char pad0x80 = 0x80; + unsigned char pad0x00 = 0x00; + unsigned char padlen[8]; + int i; + + /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length + */ + padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255); + padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255); + padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255); + padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255); + padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255); + padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255); + padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255); + padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255); + shaUpdate(ctx, &pad0x80, 1); + while (ctx->lenW != 56) + shaUpdate(ctx, &pad0x00, 1); + shaUpdate(ctx, padlen, 8); + + /* Output hash + */ + for (i = 0; i < 20; i++) { + hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24); + ctx->H[i / 4] <<= 8; + } + + /* + * Re-initialize the context (also zeroizes contents) + */ + shaInit(ctx); +} + +#if 0 +void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) { + SHA_CTX ctx; + + shaInit(&ctx); + shaUpdate(&ctx, dataIn, len); + shaFinal(&ctx, hashout); +} +#endif + + +#define SHA_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n)))) + +static void shaHashBlock(SHA_CTX *ctx) { + int t; + u_int32_t A,B,C,D,E,TEMP; + + for (t = 16; t <= 79; t++) + ctx->W[t] = + SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1); + + A = ctx->H[0]; + B = ctx->H[1]; + C = ctx->H[2]; + D = ctx->H[3]; + E = ctx->H[4]; + + for (t = 0; t <= 19; t++) { + TEMP = SHA_ROTL(A,5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999L; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (t = 20; t <= 39; t++) { + TEMP = SHA_ROTL(A,5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1L; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (t = 40; t <= 59; t++) { + TEMP = SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (t = 60; t <= 79; t++) { + TEMP = SHA_ROTL(A,5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6L; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + + ctx->H[0] += A; + ctx->H[1] += B; + ctx->H[2] += C; + ctx->H[3] += D; + ctx->H[4] += E; +} + +#endif /* (!WITH_CORECRYPTO || !WITH_VFP) && !WITH_HW_SHA1 */ diff --git a/drivers/sha1/mozilla_sha.h b/drivers/sha1/mozilla_sha.h new file mode 100644 index 0000000..db6a323 --- /dev/null +++ b/drivers/sha1/mozilla_sha.h @@ -0,0 +1,57 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is SHA 180-1 Header File + * + * The Initial Developer of the Original Code is Paul Kocher of + * Cryptography Research. Portions created by Paul Kocher are + * Copyright (C) 1995-9 by Cryptography Research, Inc. All + * Rights Reserved. + * + * Contributor(s): + * + * Paul Kocher + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +#ifndef _MOZILLA_SHA_H_ +#define _MOZILLA_SHA_H_ + +#include + +__BEGIN_DECLS + +typedef struct { + u_int32_t H[5]; + u_int32_t W[80]; + int lenW; + u_int32_t sizeHi,sizeLo; +} SHA_CTX; + +void shaInit(SHA_CTX *ctx); +void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, u_int32_t len); +void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]); +// void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]); + +__END_DECLS + +#endif /* _MOZILLA_SHA_H_ */ diff --git a/drivers/sha1/rules.mk b/drivers/sha1/rules.mk new file mode 100644 index 0000000..c21445f --- /dev/null +++ b/drivers/sha1/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_SHA1=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/sha1.o \ + $(LOCAL_DIR)/mozilla_sha.o + diff --git a/drivers/sha1/sha1.c b/drivers/sha1/sha1.c new file mode 100644 index 0000000..b9bb11b --- /dev/null +++ b/drivers/sha1/sha1.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_CORECRYPTO + +#include +#include +#include + +#if WITH_VFP +# define USE_CC_SHA1_OPTIMIZED_IMPLEMENTATION 1 +#endif + +const struct ccdigest_info *sha1_get_ccsha1_ccdigest_info() +{ +#if USE_CC_SHA1_OPTIMIZED_IMPLEMENTATION + return ((const struct ccdigest_info *)ccsha1_di()); +#else + return (&ccsha1_ltc_di); +#endif +} + +void sha1_calculate(const void *buffer, size_t length, void *result) +{ +#if USE_CC_SHA1_OPTIMIZED_IMPLEMENTATION && !WITH_VFP_ALWAYS_ON + arch_task_fp_enable(true); +#endif + + ccdigest(sha1_get_ccsha1_ccdigest_info(), length, buffer, result); +} + +#elif WITH_HW_SHA1 +extern void sha1_hw_calculate(const void *buf, size_t len, u_int32_t *result); + +void sha1_calculate(const void *buffer, size_t length, void *result) +{ + if ((NULL == buffer) || + (NULL == result)) + panic("SHA1: bad parameters"); + + sha1_hw_calculate(buffer, length, result); +} + +#else +# include "mozilla_sha.h" + +void sha1_calculate(const void *buffer, size_t length, void *result) +{ + SHA_CTX ctx; + + shaInit(&ctx); + shaUpdate(&ctx, (unsigned char *)buffer, length); + shaFinal(&ctx, (unsigned char *)result); + /* software sha-1 implementation? */ +} +#endif + +#if WITH_MENU && !WITH_SIMPLE_MENU +static int do_sha1(int argc, struct cmd_arg *args) +{ + u_int8_t hash[20]; + u_int32_t cnt; + + if (argc < 3) { + printf("not enough arguments.\n"); + printf("%s
\n", args[0].str); + return -1; + } + + if (!security_allow_memory((void *)args[1].u, args[2].u)) { + printf("Permission Denied\n"); + return -1; + } + + sha1_calculate((void *)args[1].u, args[2].u, hash); + printf("sha1 of 0x%08lx for 0x%08lx bytes: ", args[1].u, args[2].u); + for (cnt = 0; cnt < 20; cnt++) + printf("%02x%s", hash[cnt], (cnt != 19) ? ":" : "\n"); + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(sha1, do_sha1, "SHA-1 hash of specified memory address range.", NULL); +#endif + + diff --git a/drivers/sha1/tests.c b/drivers/sha1/tests.c new file mode 100644 index 0000000..3b29dcc --- /dev/null +++ b/drivers/sha1/tests.c @@ -0,0 +1,41 @@ +#include +#include +#include + +struct sha1_test { + const char *data; + uint32_t len; + uint8_t expected[20]; +}; + +static struct sha1_test sha1_tests[] = { + { "", 0, { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 } }, + + { "abc", 3, { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, { 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1 } }, + +}; + +void test_sha1(uintptr_t param) +{ + for (unsigned i = 0; i < sizeof sha1_tests / sizeof(sha1_tests[0]); i++) { + struct sha1_test *test = &sha1_tests[i]; + + uint8_t calculated[20]; + + sha1_calculate((void *)test->data, test->len, (void *)calculated); + + TEST_ASSERT_MEM_EQ(calculated, test->expected, sizeof(test->expected)); + } +} + +struct test_suite sha1_suite = { + .name = "sha1", + .test_cases = { + { "sha1", test_sha1, 0, "Tests the sha1_calculate function" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(sha1_suite); diff --git a/drivers/sha1/tests.mk b/drivers/sha1/tests.mk new file mode 100644 index 0000000..c096ce2 --- /dev/null +++ b/drivers/sha1/tests.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := sha1 + +TEST_OBJS := \ + $(LOCAL_DIR)/sha1.o \ + $(LOCAL_DIR)/mozilla_sha.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o diff --git a/drivers/spi/gpio_spi.c b/drivers/spi/gpio_spi.c new file mode 100644 index 0000000..c8c29b8 --- /dev/null +++ b/drivers/spi/gpio_spi.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + +#include +#include + +static void spi_sample_start(void) +{ + /* Assert the clock to begin bit sample */ + gpio_write(GPIO_SPI_SCK, 0); +} + +static void spi_sample_end(void) +{ + /* Deassert the clock to end bit sample */ + gpio_write(GPIO_SPI_SCK, 1); +} + +static unsigned char spi_in(unsigned char bit) +{ + /* If the GPIO is set, then this bit is set, and we return the byte value */ + return (gpio_read(GPIO_SPI_MISO) ? 1 : 0) << bit; +} + +static void spi_out(unsigned char data, unsigned char bit) +{ + /* Write bit to GPIO */ + gpio_write(GPIO_SPI_MOSI, data & (1 << bit)); +} + +void spi_init(void) +{ + /* Assert clock and deassert slave select */ + spi_sample_start( ); + spi_end(); +} + +void spi_start(void) +{ + /* Assert slave select to begin SPI transaction */ + gpio_write(GPIO_SPI_SS, 0); +} + +void spi_end(void) +{ + /* Deassert slave select to end SPI transaction */ + gpio_write(GPIO_SPI_SS, 1); +} + +void spi_read(unsigned char* data) +{ + signed int i; + + /* Start with initial state */ + *data = 0; + + /* Loop every bit */ + for (i = 7; i >= 0; i--) + { + /* Assert clock */ + spi_sample_start(); + + /* Dummy write cycle */ + spi_out(0, 0); + + /* Read one bit */ + *data |= spi_in(i); + + /* Deassert clock */ + spi_sample_end(); + } +} + +void spi_write(unsigned char data) +{ + signed int i; + + /* Loop every bit */ + for (i = 7; i >= 0; i--) + { + /* Assert clock */ + spi_sample_start(); + + /* Write one bit */ + spi_out(data, i); + + /* Dummy read cycle */ + spi_in(0); + + /* Deassert clock */ + spi_sample_end(); + } +} diff --git a/drivers/spi/rules.mk b/drivers/spi/rules.mk new file mode 100644 index 0000000..0e60d2e --- /dev/null +++ b/drivers/spi/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_SPI=1 + +ALL_OBJS += $(LOCAL_DIR)/gpio_spi.o diff --git a/drivers/synopsys/mipi/dsim.c b/drivers/synopsys/mipi/dsim.c new file mode 100644 index 0000000..93e1c71 --- /dev/null +++ b/drivers/synopsys/mipi/dsim.c @@ -0,0 +1,751 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dsim.h" + +#define CEIL_DIV(a,b) (((a)/(b)) + (((a) % (b)) ? 1 : 0)) + +static u_int32_t lane_count; + +static struct phy_settings *phy_settings_info; + +static void mipi_program_phy_test_codes(struct phy_settings *phy_settings_info); +static void mipi_program_phy_hsfreqrange(struct phy_settings *phy_settings_info); +static void mipi_phy_write(uint32_t address, uint8_t *data, uint32_t length); +static void mipi_phy_read_mod_write(uint32_t address, uint8_t mask, uint8_t shift, uint8_t val); +static void mipi_phy_test_reset(bool reset); +static void mipi_phy_toggle_shutdownz(void); +static bool mipi_is_interface_enabled(); + +/* + * The Programming sequences of MIPI DSI can be broken down in the following parts: + * Static configurations + * Main sequence + * Sequence for generic packets + */ +int mipi_dsim_init(struct display_timing *timing, enum colorspace color) +{ + const char *env; + uint32_t dpi_color_coding, vid_size, bytes_per_pixel; + uint64_t lane_byte_clock_period, lane_byte_clock, pixel_clock; + uint64_t esc_clock; + uint32_t total_pixels_per_line; + uint32_t status_mask; + uint32_t cmd_mode; + uint32_t outvact_lpcmd_time, invact_lpcmd_time; + uint32_t hsa_time, hbp_time, hline_time, hss_time; + uint64_t time_calculation; + uint64_t hline_time_ns; + uint32_t max_rd_time; + uint32_t pll_config; + uint32_t hs_freq_range; + mipi_t *display_config; + + dprintf(DEBUG_CRITICAL, "mipi_dsim_init()\n"); + + env = env_get("display-timing"); + if (env == 0) env = ""; + + pll_config = 0; + hs_freq_range = 0; + + display_config = (mipi_t *)(timing->display_config); + assert(display_config != NULL); + + phy_settings_info = &display_config->target_phy_settings; + if (phy_settings_info == 0) { + panic("Failed to find display timing info"); + } + + // Extract Lane configuration + lane_count = display_config->lanes; + +#if DSIM_VERSION > 1 + // Extract PLL configuration + pll_config = DSIM_TOP_PLL_PARAM_P(display_config->pll_p); + pll_config |= DSIM_TOP_PLL_PARAM_M(display_config->pll_m); + pll_config |= DSIM_TOP_PLL_PARAM_N(display_config->pll_n); + + dprintf(DEBUG_CRITICAL,"pll_config 0x%x\n", pll_config); + + // Extract frequence range + hs_freq_range = display_config->hsfreq; +#endif //DSIM_VERSION + + switch (timing->display_depth){ + case 16: + dpi_color_coding = DPI_COLOR_CODING_BIT16_CONF1; + vid_size = timing->h_active; + break; + case 18: + dpi_color_coding = DPI_COLOR_CODING_BIT18_CONF1; + vid_size = timing->h_active & ~3; + break; + case 24: + dpi_color_coding = DPI_COLOR_CODING_BIT24; + vid_size = timing->h_active & ~1; + break; + case 30: + dpi_color_coding = DPI_COLOR_CODING_BIT30; + vid_size = timing->h_active; + break; + default: + panic("unexpected display depth"); + } + bytes_per_pixel = timing->display_depth / 8; + + clock_gate(CLK_MIPI, true); + +#if DSIM_VERSION > 1 + rDSIM_TOP_PLL_CTRL = DSIM_TOP_PLL_CTRL_PLL_CFG_SEL_PHY; +#endif //DSIM_VERSION + + //Reset the block if we detect HW errors + uint32_t tmp = rDSIM_CORE_INT_ST1; + if ((tmp & DSIM_CORE_INT_ST1_ERRORS) != 0) { + clock_reset_device(CLK_MIPI); + } + + rDSIM_CORE_INT_MSK0 = 0; + rDSIM_CORE_INT_MSK1 = 0; + + //Configure byte clock dividers + rDSIM_CORE_CLKMGR_CFG = (DSIM_CORE_CLKMGR_CFG_TO_CLK_DIVISION(1) | DSIM_CORE_CLKMGR_CFG_TX_ESC_CLK_DIVISION(display_config->esc_div)); + + rDSIM_CORE_MODE_CFG = DSIM_CORE_MODE_CFG_COMMAND_MODE; + +#ifndef TARGET_PHY_STOP_WAIT_TIME +#define TARGET_PHY_STOP_WAIT_TIME 0xf +#endif //TARGET_PHY_STOP_WAIT_TIME + + //Configure PHY lanes + rDSIM_CORE_PHY_IF_CFG = DSIM_CORE_PHY_IF_CFG_PHY_STOP_WAIT_TIME(TARGET_PHY_STOP_WAIT_TIME) | DSIM_CORE_PHY_IF_CFG_N_LANES(lane_count - 1); + + //Configure packet handler + rDSIM_CORE_PCKHDL_CFG = DSIM_CORE_PCKHDL_CFG_BTA_EN | DSIM_CORE_PCKHDL_CFG_ECC_RX_EN | DSIM_CORE_PCKHDL_CFG_CRC_RX_EN; + + //Don't support virtual channels + rDSIM_CORE_DPI_VCID = 0; + + //Configure pixel map + rDSIM_CORE_DPI_COLOR_CODING = dpi_color_coding; + rDSIM_TOP_PIXEL_REMAP = dpi_color_coding; + + //rDSIM_CORE_DPI_CFG_POL = (timing->neg_hsync << 2) | (timing->neg_vsync << 1) | (timing->neg_vden << 0); + rDSIM_CORE_DPI_CFG_POL = 0; + + //Configure low power mode + rDSIM_CORE_VID_MODE_CFG = (DSIM_CORE_VID_MODE_CFG_LP_CMD_EN | DSIM_CORE_VID_MODE_CFG_LP_VFP_EN | DSIM_CORE_VID_MODE_CFG_LP_VACT_EN | DSIM_CORE_VID_MODE_CFG_LP_HFP_EN | DSIM_CORE_VID_MODE_CFG_LP_HBP_EN); +#if DSIM_VERSION > 1 + rDSIM_CORE_VID_MODE_CFG |= (DSIM_CORE_VID_MODE_CFG_LP_VBP_EN | DSIM_CORE_VID_MODE_CFG_LP_VSA_EN); +#endif + rDSIM_CORE_VID_MODE_CFG |= DSIM_CORE_VID_MODE_CFG_VID_MODE_TYPE_HORIZONTALEXPANSION; + + //Configure video packetizing + rDSIM_CORE_VID_PKT_SIZE = timing->h_active; + // LEAVE DEFAULT VID_NUM_CHUNKS VID_NULL_SIZE; + + //Configure video timing + pixel_clock = clock_get_frequency(CLK_VCLK0); + lane_byte_clock = CEIL_DIV(clock_get_frequency(CLK_MIPI), 8); + lane_byte_clock_period = CEIL_DIV(1000000000, lane_byte_clock); + total_pixels_per_line = timing->h_active + timing->h_front_porch + timing->h_pulse_width + timing->h_back_porch; + + time_calculation = (timing->h_pulse_width * lane_byte_clock); + time_calculation = CEIL_DIV(time_calculation, pixel_clock); + hsa_time = time_calculation & UINT32_MAX; + + time_calculation = (timing->h_back_porch * lane_byte_clock); + time_calculation = CEIL_DIV(time_calculation, pixel_clock); + hbp_time = time_calculation & UINT32_MAX; + + time_calculation = (total_pixels_per_line * lane_byte_clock); + time_calculation = CEIL_DIV(time_calculation, pixel_clock); + hline_time = time_calculation & UINT32_MAX; + + rDSIM_CORE_VID_HSA_TIME = hsa_time; + rDSIM_CORE_VID_HBP_TIME = hbp_time; + rDSIM_CORE_VID_HLINE_TIME = hline_time; + + rDSIM_CORE_VID_VSA_LINES = timing->v_pulse_width; + rDSIM_CORE_VID_VBP_LINES = timing->v_back_porch; + rDSIM_CORE_VID_VACTIVE_LINES = timing->v_active; + + // Configure LP time to send commands + // Synopsys Mipi dsi: outvact_lpcmd_time programming recommendation seems incorrect + //The synopsys recommended values do not support sending commands while video is active. SEG has provided a WA as explained on the above + //radar + hline_time_ns = CEIL_DIV(pixel_clock, 1000); + hline_time_ns = CEIL_DIV(1000000000, hline_time_ns); + hline_time_ns *= total_pixels_per_line; + hline_time_ns = CEIL_DIV(hline_time_ns, 1000); //ns + + esc_clock = lane_byte_clock_period * display_config->esc_div; + + hss_time = 4 * lane_byte_clock_period; + + outvact_lpcmd_time = (hline_time_ns) - hss_time - (TARGET_HS_2_LP_DATA_TIME * lane_byte_clock_period) + - (TARGET_LP_2_HS_DATA_TIME * lane_byte_clock_period) - (22 * esc_clock) - (2 * esc_clock); + outvact_lpcmd_time = CEIL_DIV(outvact_lpcmd_time, (2 * 8 * esc_clock)); + + rDSIM_CORE_VID_VFP_LINES = timing->v_front_porch - CEIL_DIV(256, outvact_lpcmd_time); + + max_rd_time = hline_time; + + //Set outvact_lpcmd_time to 0 to force sending the command on the last line + outvact_lpcmd_time = 0; + invact_lpcmd_time = 0; + rDSIM_CORE_DPI_LP_CMD_TIM = (outvact_lpcmd_time << 16) | (invact_lpcmd_time << 0); + + //Disable 3D capabilities + rDSIM_CORE_SDF_3D = 0; + + rDSIM_CORE_LPCLK_CTRL = 0; + + //Configure PHY timing + rDSIM_CORE_PHY_TMR_CFG = ((TARGET_HS_2_LP_DATA_TIME & 0xFF) << 24) | ((TARGET_LP_2_HS_DATA_TIME & 0xFF) << 16) | max_rd_time; + + rDSIM_CORE_PHY_TMR_LPCLK_CFG = (TARGET_HS_2_LP_CLOCK_TIME << 16) | (TARGET_LP_2_HS_CLOCK_TIME << 0); + + //Configure packet transmission type + cmd_mode = DSIM_CORE_CMD_MODE_CFG_GEN_LW_TX_LP | + DSIM_CORE_CMD_MODE_CFG_GEN_SR_2P_TX_LP | + DSIM_CORE_CMD_MODE_CFG_GEN_SR_1P_TX_LP | + DSIM_CORE_CMD_MODE_CFG_GEN_SR_0P_TX_LP | + DSIM_CORE_CMD_MODE_CFG_GEN_SW_2P_TX_LP | + DSIM_CORE_CMD_MODE_CFG_GEN_SW_1P_TX_LP | + DSIM_CORE_CMD_MODE_CFG_GEN_SW_0P_TX_LP; +#if DSIM_VERSION == 1 + cmd_mode |= DSIM_CORE_CMD_MODE_CFG_MAX_RD_PKT_SIZE_LP | + DSIM_CORE_CMD_MODE_CFG_DCS_LW_TX_LP | + DSIM_CORE_CMD_MODE_CFG_DCS_SR_0P_TX_LP | + DSIM_CORE_CMD_MODE_CFG_DCS_SW_1P_TX_LP | + DSIM_CORE_CMD_MODE_CFG_DCS_SW_0P_TX_LP; +#endif //DSIM_VERSION + + rDSIM_CORE_CMD_MODE_CFG = cmd_mode; + +#if DSIM_VERSION == 1 + //PHY power up + rDSIM_CORE_PWR_UP = DSIM_CORE_PWR_UP_SHUTDOWNZ; +#endif + + mipi_phy_test_reset( false ); + mipi_phy_test_reset( false ); + mipi_phy_test_reset( true ); +#if DSIM_VERSION > 1 + + // Configure PLL if needed + if (pll_config != 0) { + rDSIM_TOP_PLL_CTRL |= DSIM_TOP_PLL_CTRL_SEQ_OW_ON; + //PHY power up + rDSIM_CORE_PWR_UP = DSIM_CORE_PWR_UP_SHUTDOWNZ; + + //PHY reset + rDSIM_CORE_PHY_RSTZ = DSIM_CORE_PHY_RSTZ_PHY_ENABLECLK; + + rDSIM_TOP_PLL_CTRL |= DSIM_TOP_PLL_CTRL_CLKSELPLL_PLLCLK | DSIM_TOP_PLL_CTRL_HSFREQRANGE(hs_freq_range); + + rDSIM_TOP_PLL_CTRL |= DSIM_TOP_PLL_CTRL_SHADOW_CLEAR; + + //typically becomes 0 in the first read + while ((rDSIM_TOP_PLL_CTRL & DSIM_TOP_PLL_CTRL_SHADOW_CLEAR) != 0); + + rDSIM_TOP_PLL_PARAM = DSIM_TOP_PLL_PARAM_VCOCAP(TARGET_PLL_VCO_CAP) | + DSIM_TOP_PLL_PARAM_VCORANGE(TARGET_VCO_RANGE) | + DSIM_TOP_PLL_PARAM_LPFCTRL(TARGET_LPF_CTRL) | + DSIM_TOP_PLL_PARAM_ICPCTRL(TARGET_ICP_CTR) | + pll_config; + + //wait at least one microsecond (requirement between shadow_clear and updatepll) + spin(2); + + rDSIM_TOP_PLL_CTRL |= DSIM_TOP_PLL_CTRL_UPDATEPLL_ON; + + // wait at least 200 nanoseconds (for updatepll to remain asserted at least four 24 MHz cycles) 8) clear MIPI_DSI_TOP_PLL_CTRL.updatepll + // wait at least 200 nanoseconds (for phylock_hw to clear) + spin(1); + + rDSIM_TOP_PLL_CTRL &= ~DSIM_TOP_PLL_CTRL_UPDATEPLL_ON; + spin(1); +#if WITH_HW_AGC_MIPI_V2 + rDSIM_TOP_AGILE_SEQ1 = TARGET_AGILE_SEQ1; + rDSIM_TOP_AGILE_SEQ2 = TARGET_AGILE_SEQ2; + rDSIM_TOP_PLL_CTRL &= ~DSIM_TOP_PLL_CTRL_SEQ_OW_ON; + + //set up agilie clocking constants + // Maui/Malta MIPI-DSI screen shift due to first first agile command after display on + rDSIM_TOP_AGILE_LINECOUNT |= DSIM_TOP_AGILE_LINECOUNT_CONFIG_MAX; + rDSIM_TOP_AGILE_CTRL &= ~((0x3 << 18) | (0x3 << 16)); //VFRONT + rDSIM_TOP_AGILE_CTRL |= DSIM_TOP_AGILE_CTRL_ENABLE; + +#endif //WITH_HW_AGC_MIPI_V2 + } + +#endif //DSIM_VERSION + + rDSIM_CORE_PHY_RSTZ = DSIM_CORE_PHY_RSTZ_PHY_FORCEPLL | DSIM_CORE_PHY_RSTZ_PHY_ENABLECLK | DSIM_CORE_PHY_RSTZ_PHY_SHUTDOWNZ; + + spin(5); + + rDSIM_CORE_PHY_RSTZ = DSIM_CORE_PHY_RSTZ_PHY_FORCEPLL | DSIM_CORE_PHY_RSTZ_PHY_ENABLECLK | DSIM_CORE_PHY_RSTZ_PHY_SHUTDOWNZ | DSIM_CORE_PHY_RSTZ_PHY_RSTZ; + +#if DSIM_VERSION > 1 + while ((rDSIM_GENERAL_CTRL & DSIM_GENERAL_CTRL_PHYLOCK_HW_LOCK) == 0); +#endif //DSIM_VERSION + +#if DSIM_VERSION == 1 + //Program PHY hsfreqrange registers + mipi_program_phy_hsfreqrange(phy_settings_info); +#endif //DSIM_VERSION + + rDSIM_CORE_LP_RD_TO_CNT = 0x19; + rDSIM_CORE_BTA_TO_CNT = 0x19; + + //Monitor PHY status + status_mask = (DSIM_CORE_PHY_STATUS_PHY_STOPSTATECLKLANE | DSIM_CORE_PHY_STATUS_PHY_STOPSTATE0LANE); + status_mask |= (lane_count >= 2) ? DSIM_CORE_PHY_STATUS_PHY_STOPSTATE1LANE : 0; + status_mask |= (lane_count >= 3) ? DSIM_CORE_PHY_STATUS_PHY_STOPSTATE2LANE : 0; + status_mask |= (lane_count == 4) ? DSIM_CORE_PHY_STATUS_PHY_STOPSTATE3LANE : 0; + + while ((rDSIM_CORE_PHY_STATUS & status_mask) != status_mask); + + return 0; +} + +int mipi_dsim_quiesce(void) +{ + dprintf(DEBUG_CRITICAL, "mipi_dsim_quiesce()\n"); + + if (!mipi_is_interface_enabled()) return 0; + + //Disable interrupts + rDSIM_CORE_INT_MSK0 = 0x1FFFFF; + rDSIM_CORE_INT_MSK1 = 0x1FFF; + + //Need to shutdown core before the phy + // Power off the core + rDSIM_CORE_PWR_UP = 0; + + // Power off PHY + mipi_phy_test_reset( true ); + + rDSIM_CORE_PHY_RSTZ &= ~(DSIM_CORE_PHY_RSTZ_PHY_FORCEPLL | DSIM_CORE_PHY_RSTZ_PHY_SHUTDOWNZ | DSIM_CORE_PHY_RSTZ_PHY_ENABLECLK); + + // Delay from SHUTDOWNZ assertion to RSTZ assertion (T4) + spin( 5 ); + + rDSIM_CORE_PHY_RSTZ &= ~(DSIM_CORE_PHY_RSTZ_PHY_RSTZ); + + clock_gate(CLK_MIPI, false); + + return 0; +} + +void mipi_dsim_enable_high_speed(bool enable) +{ + if (!mipi_is_interface_enabled()) return; + + if (enable) { + //Enable MIPI operation + rDSIM_CORE_LPCLK_CTRL |= DSIM_CORE_LPCLK_CTRL_PHY_TXREQUESTCLKHS; + +#if DSIM_VERSION == 1 + //Program PHY test registers + mipi_program_phy_test_codes(phy_settings_info); + + //handle termination + mipi_phy_read_mod_write(0x21, 0x1f, 2, 2); +#endif + } else { + rDSIM_CORE_LPCLK_CTRL &= ~DSIM_CORE_LPCLK_CTRL_PHY_TXREQUESTCLKHS; + } +} + +void mipi_dsim_enable_video(bool enable) +{ +#if DSIM_VERSION == 1 + uint32_t status_mask; +#endif + + if (!mipi_is_interface_enabled()) return; + + if (enable) { +#if DSIM_VERSION == 1 + // [N61/N56] Fiji MIPI DSI PHY requires shutdownz toggle during power up sequence + //validate no commands are in flight + status_mask = DSIM_CORE_PHY_STATUS_PHY_STOPSTATE0LANE; + status_mask |= (lane_count >= 2) ? DSIM_CORE_PHY_STATUS_PHY_STOPSTATE1LANE : 0; + status_mask |= (lane_count >= 3) ? DSIM_CORE_PHY_STATUS_PHY_STOPSTATE2LANE : 0; + status_mask |= (lane_count == 4) ? DSIM_CORE_PHY_STATUS_PHY_STOPSTATE3LANE : 0; + + while ((rDSIM_CORE_PHY_STATUS & status_mask) != status_mask); + + mipi_phy_toggle_shutdownz(); +#endif + + //Set Video Mode + rDSIM_CORE_MODE_CFG = DSIM_CORE_MODE_CFG_VIDEO_MODE; + } else { + //Set Video Mode + rDSIM_CORE_MODE_CFG = DSIM_CORE_MODE_CFG_COMMAND_MODE; + } +} + +//Programming of generic packets +int mipi_dsim_send_short_command(u_int8_t cmd, u_int8_t data0, u_int8_t data1) +{ + if (!mipi_is_interface_enabled()) return 0; + + //Write packet header + rDSIM_CORE_GEN_HDR = DSIM_CORE_GEN_HDR_GEN_DT(cmd) | DSIM_CORE_GEN_HDR_GEN_WC_LSBYTE(data0) | DSIM_CORE_GEN_HDR_GEN_WC_MSBYTE(data1); + + //Read queue status + while (!(rDSIM_CORE_CMD_PKT_STATUS & DSIM_CORE_CMD_PKT_STATUS_GEN_CMD_EMPTY)); + + return 0; +} + +int mipi_dsim_send_long_command(u_int8_t cmd, const u_int8_t *data, u_int32_t length) +{ + u_int32_t cnt, payload = 0; + + if (!mipi_is_interface_enabled()) return 0; + + for (cnt = 0; cnt < length; cnt++) { + payload = (payload >> 8) | ((u_int32_t)data[cnt] << 24); + if ((cnt & 3) == 3) { + //Write packet data + rDSIM_CORE_GEN_PLD_DATA = payload; + payload = 0; + } + } + if (payload) { + payload >>= 32 - ((length & 3) * 8); + } + + //Need to write to the fifo even if the values are 0's + if (length % 4) + rDSIM_CORE_GEN_PLD_DATA = payload; + + return mipi_dsim_send_short_command(cmd, length & 0xff, (length >> 8) & 0xff); +} + +int mipi_dsim_read_short_command(u_int8_t cmd, u_int8_t *data) +{ + uint32_t tmp, i = 0, status_mask; + + if (!mipi_is_interface_enabled()) return 0; + + // Clear pending interrupts + rDSIM_CORE_INT_ST1 = 0x1FFF; + + mipi_dsim_send_short_command(cmd, data[0], data[1]); + + while (1) { + tmp = rDSIM_CORE_INT_ST1; + + if ((tmp & DSIM_CORE_INT_ST1_ERRORS) != 0) { + dprintf(DEBUG_CRITICAL, "mipi cmd error 0x%x\n", tmp); + return -1; + } + + if ((tmp & DSIM_CORE_INT_ST1_TO_LP_RX) || (tmp & DSIM_CORE_INT_ST1_TO_HS_TX)) { + dprintf(DEBUG_CRITICAL, "mipi: timing out\n"); + return -1; + } + + tmp = rDSIM_CORE_CMD_PKT_STATUS; + status_mask = DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_R_EMPTY | DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_W_EMPTY | + DSIM_CORE_CMD_PKT_STATUS_GEN_CMD_EMPTY; + if (tmp == status_mask) { + break; + } + + // Hardware timeout depends on having a receiver, and + // completing BTA. This isn't guaranteed for dev boards. + if (++i == 5) { + dprintf(DEBUG_CRITICAL, "mipi: timing out\n"); + return -1; + } + spin(50 * 1000); + } + + // Wait for the read data + while ((rDSIM_CORE_CMD_PKT_STATUS & DSIM_CORE_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) != DSIM_CORE_CMD_PKT_STATUS_GEN_RD_CMD_BUSY); + + + tmp = rDSIM_CORE_GEN_PLD_DATA; + + data[0] = (tmp >> 0) & 0xff; + data[1] = (tmp >> 8) & 0xff; + + return 0; +} + +int mipi_dsim_read_long_command(u_int8_t cmd, u_int8_t *data, u_int32_t *length) +{ + u_int32_t tmp, maxlen, i = 0; + + if (!mipi_is_interface_enabled()) return 0; + + maxlen = *length; + + // Clear pending interrupts + rDSIM_CORE_INT_ST1 = 0x1FFF; + + mipi_dsim_send_short_command(cmd, data[0], data[1]); + + while (1) { + tmp = rDSIM_CORE_INT_ST1; + + if ((tmp & DSIM_CORE_INT_ST1_ERRORS) != 0) { + dprintf(DEBUG_CRITICAL, "mipi cmd error 0x%x\n", tmp); + return -1; + } + + if ((tmp & DSIM_CORE_INT_ST1_TO_LP_RX) || (tmp & DSIM_CORE_INT_ST1_TO_HS_TX)) { + dprintf(DEBUG_CRITICAL, "mipi: timing out\n"); + return -1; + } + + // rd_cmd_busy should go low indicating the data is ready + if ( !(rDSIM_CORE_CMD_PKT_STATUS & DSIM_CORE_CMD_PKT_STATUS_GEN_RD_CMD_BUSY)) + break; + + // Hardware timeout depends on having a receiver, and + // completing BTA. This isn't guaranteed for dev boards. + if (++i == 5) { + dprintf(DEBUG_CRITICAL, "mipi_dsim_read_long_command: timing out\n"); + return -1; + } + spin(50 * 1000); + } + + //Unlike other IPs, the FIJI IP strips the response packet header. SW determines how many bytes were + //sent by checking when the FIFO is emtpy and returning how many bytes were read + for (i = 0; i < maxlen; i++) { + if (rDSIM_CORE_CMD_PKT_STATUS & DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_R_EMPTY) + break; + + if (!(i % 4)) { + tmp = rDSIM_CORE_GEN_PLD_DATA; + } + data[i] = tmp & 0xff; + tmp >>= 8; + } + + + while (!(rDSIM_CORE_CMD_PKT_STATUS & DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_R_EMPTY)){ + //empty the fifo + tmp = rDSIM_CORE_GEN_PLD_DATA; + } + + if (i < maxlen) + *length = i; + + return 0; +} + +static void mipi_program_phy_hsfreqrange(struct phy_settings *phy_settings_info) +{ + struct phy_setting_vals *phy_setting_value_ptr; + uint32_t num_of_values; + + num_of_values = 1; + + phy_setting_value_ptr = &(phy_settings_info->phy_setting_values[0]); + mipi_phy_write(phy_setting_value_ptr->test_code, phy_setting_value_ptr->test_data, phy_setting_value_ptr->num_of_data); +} + +static void mipi_program_phy_test_codes(struct phy_settings *phy_settings_info) +{ + struct phy_setting_vals *phy_setting_value_ptr; + uint32_t num_of_values, cnt; + + num_of_values = phy_settings_info->num_of_values; + + //skip first element as it was programmed in the hsfreqrange + for(cnt = 1; cnt < num_of_values; cnt++) { + phy_setting_value_ptr = &(phy_settings_info->phy_setting_values[cnt]); + mipi_phy_write(phy_setting_value_ptr->test_code, phy_setting_value_ptr->test_data, phy_setting_value_ptr->num_of_data); + } +} + +static void mipi_phy_write(uint32_t address, uint8_t *data, uint32_t length) +{ + uint32_t i; + + // Clock High + rDSIM_CORE_PHY_TST_CTRL0 = DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + + //register address + rDSIM_CORE_PHY_TST_CTRL1 = DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDIN(address); + + // Mark this tx as an AddressWrite + rDSIM_CORE_PHY_TST_CTRL1 |= DSIM_CORE_PHY_TST_CTRL1_PHY_TESTEN; + + //Wait 5ns + spin(5); + + // Latch address + rDSIM_CORE_PHY_TST_CTRL0 &= ~DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + + spin(10); + //Get ready for the Write Data + rDSIM_CORE_PHY_TST_CTRL1 &= ~DSIM_CORE_PHY_TST_CTRL1_PHY_TESTEN; + + for (i = 0; i < length; i++) { + rDSIM_CORE_PHY_TST_CTRL1 &= ~DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDIN(0xFF); + rDSIM_CORE_PHY_TST_CTRL1 |= DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDIN(data[i]); + spin(2); + rDSIM_CORE_PHY_TST_CTRL0 |= DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + spin(10); + rDSIM_CORE_PHY_TST_CTRL0 &= ~DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + } +} + +static void mipi_phy_read_mod_write(uint32_t address, uint8_t mask, uint8_t shift, uint8_t val) +{ + uint32_t reg; + + // Clock High + rDSIM_CORE_PHY_TST_CTRL0 = DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + + //register address + rDSIM_CORE_PHY_TST_CTRL1 = DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDIN(address); + + // Mark this tx as an AddressWrite + rDSIM_CORE_PHY_TST_CTRL1 |= DSIM_CORE_PHY_TST_CTRL1_PHY_TESTEN; + + //Wait 5ns + spin(5); + + // Latch address + rDSIM_CORE_PHY_TST_CTRL0 &= ~DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + + spin(10); + + //Get ready for the Write Data + rDSIM_CORE_PHY_TST_CTRL1 &= ~DSIM_CORE_PHY_TST_CTRL1_PHY_TESTEN; + + // From Fiji | MIPI DSI PHY Required test code settings & impact: + // Once the termination resistance is calibrated, read out the calibrated + // value (bit[4:0]) and then force these values thereafter by writing them + // back to bits[6:2] with bits[1:0] = 10 (0x2). This prevents clock lanes + // from recalibrating termination during each PHY reset. + reg = rDSIM_CORE_PHY_TST_CTRL1; + reg = DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDOUT(reg); + reg &= mask; + reg = (reg << shift) | val; + + // DataWrite + rDSIM_CORE_PHY_TST_CTRL1 &= ~DSIM_CORE_PHY_TST_CTRL1_PHY_TESTEN; + + rDSIM_CORE_PHY_TST_CTRL1 &= ~DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDIN(0xFF); + rDSIM_CORE_PHY_TST_CTRL1 |= DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDIN(reg); + + spin(2); + + // Pulse clock to latch data + rDSIM_CORE_PHY_TST_CTRL0 |= DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + + spin(10); + + reg = rDSIM_CORE_PHY_TST_CTRL1; + + rDSIM_CORE_PHY_TST_CTRL0 &= ~DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK; + + spin(2); +} + +static void mipi_phy_test_reset(bool reset) +{ + rDSIM_CORE_PHY_TST_CTRL0 = reset ? DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLR : 0; + + spin(5); +} + +static void mipi_phy_toggle_shutdownz(void) +{ + rDSIM_CORE_PHY_RSTZ &= ~DSIM_CORE_PHY_RSTZ_PHY_SHUTDOWNZ; + spin(1); + rDSIM_CORE_PHY_RSTZ |= DSIM_CORE_PHY_RSTZ_PHY_SHUTDOWNZ; +} + + +static bool mipi_is_interface_enabled() +{ + clock_gate(CLK_MIPI, true); + + if (rDSIM_CORE_PWR_UP == DSIM_CORE_PWR_UP_SHUTDOWNZ) + return true; + + clock_gate(CLK_MIPI, false); + return false; +} + +#if WITH_DEVICETREE + +#include + +int mipi_update_device_tree(DTNode *mipi_node) +{ + uint32_t propSize; + char *propName; + void *propData; + uint32_t sizeofData; + uint32_t cnt; + struct phy_setting_vals *phy_settings_ptr; + struct phy_setting_vals *propdata_phy_settings; + uint32_t size_phy_settings; + + if (phy_settings_info == NULL) { + printf("something is seriously bad\n"); + return -1; + } + + size_phy_settings = sizeof(struct phy_setting_vals); + + propName = "phy-test-num"; + if (FindProperty(mipi_node, &propName, &propData, &propSize)) { + ((u_int32_t *)propData)[0] = phy_settings_info->num_of_values; + } + + propName = "phy-test"; + if (FindProperty(mipi_node, &propName, &propData, &propSize)) { + sizeofData = sizeof(struct phy_setting_vals) * phy_settings_info->num_of_values; + if (propSize < sizeofData) { + printf("device tree doesn't have enough space for data: propSize %d sizeofData %d\n", propSize, sizeofData); + return -1; + } + for (cnt = 0; cnt < phy_settings_info->num_of_values; cnt++) { + + + phy_settings_ptr = &(phy_settings_info->phy_setting_values[cnt]); + propdata_phy_settings = (struct phy_setting_vals *)propData + (cnt * size_phy_settings); + memcpy(propData + (cnt * size_phy_settings), phy_settings_ptr, size_phy_settings); + } + } + + return 0; +} + +#endif diff --git a/drivers/synopsys/mipi/dsim.h b/drivers/synopsys/mipi/dsim.h new file mode 100644 index 0000000..8421cdf --- /dev/null +++ b/drivers/synopsys/mipi/dsim.h @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __SYNOPSYS_DSIM_H +#define __SYNOPSYS_DSIM_H + +#include + +#define rDSIM_CORE_VERSION (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00000)) +#define rDSIM_CORE_PWR_UP (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00004)) +#define DSIM_CORE_PWR_UP_SHUTDOWNZ (1 << 0) +#define rDSIM_CORE_CLKMGR_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00008)) +#define DSIM_CORE_CLKMGR_CFG_TO_CLK_DIVISION(n) ((n) << 8) +#define DSIM_CORE_CLKMGR_CFG_TX_ESC_CLK_DIVISION(n) ((n) << 0) +#define rDSIM_CORE_DPI_VCID (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0000C)) +#define rDSIM_CORE_DPI_COLOR_CODING (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00010)) +#define DPI_COLOR_CODING_BIT16_CONF1 (0x0) +#define DPI_COLOR_CODING_BIT16_CONF2 (0x1) +#define DPI_COLOR_CODING_BIT16_CONF3 (0x2) +#define DPI_COLOR_CODING_BIT18_CONF1 (0x3) +#define DPI_COLOR_CODING_BIT18_CONF2 (0x4) +#define DPI_COLOR_CODING_BIT24 (0x5) +#define DPI_COLOR_CODING_BIT20_422_LOOSELY (0x6) +#define DPI_COLOR_CODING_BIT24_422 (0x7) +#define DPI_COLOR_CODING_BIT16_422 (0x8) +#define DPI_COLOR_CODING_BIT30 (0x9) +#define DPI_COLOR_CODING_BIT36 (0xA) +#define DPI_COLOR_CODING_BIT12_420 (0xB) +#define DPI_COLOR_CODING_BIT12_420_SAME (0xC) +#define DPI_COLOR_CODING_BIT12_420_SAME2 (0xD) +#define DPI_COLOR_CODING_BIT12_420_SAME3 (0xE) +#define DPI_COLOR_CODING_BIT12_420_SAME4 (0xF) +#define rDSIM_CORE_DPI_CFG_POL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00014)) +#define rDSIM_CORE_DPI_LP_CMD_TIM (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00018)) +#define rDSIM_CORE_PCKHDL_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0002C)) +#define DSIM_CORE_PCKHDL_CFG_CRC_RX_EN (1 << 4) +#define DSIM_CORE_PCKHDL_CFG_ECC_RX_EN (1 << 3) +#define DSIM_CORE_PCKHDL_CFG_BTA_EN (1 << 2) +#define DSIM_CORE_PCKHDL_CFG_EOTP_RX_EN (1 << 1) +#define DSIM_CORE_PCKHDL_CFG_EOTP_TX_EN (1 << 0) +#define rDSIM_CORE_GEN_VCID (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00030)) +#define rDSIM_CORE_MODE_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00034)) +#define DSIM_CORE_MODE_CFG_VIDEO_MODE (0 << 0) +#define DSIM_CORE_MODE_CFG_COMMAND_MODE (1 << 0) +#define rDSIM_CORE_VID_MODE_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00038)) +#define DSIM_CORE_VID_MODE_CFG_LP_CMD_EN (1 << 15) +#define DSIM_CORE_VID_MODE_CFG_FRAME_BTA_ACK_EN (1 << 14) +#define DSIM_CORE_VID_MODE_CFG_LP_HFP_EN (1 << 13) +#define DSIM_CORE_VID_MODE_CFG_LP_HBP_EN (1 << 12) +#define DSIM_CORE_VID_MODE_CFG_LP_VACT_EN (1 << 11) +#define DSIM_CORE_VID_MODE_CFG_LP_VFP_EN (1 << 10) +#define DSIM_CORE_VID_MODE_CFG_LP_VBP_EN (1 << 9) +#define DSIM_CORE_VID_MODE_CFG_LP_VSA_EN (1 << 8) +#define DSIM_CORE_VID_MODE_CFG_VID_MODE_TYPE_NONBURSTSYNCPULSE (0 << 0) +#define DSIM_CORE_VID_MODE_CFG_VID_MODE_TYPE_NONBURSTSYNCEVENT (1 << 0) +#define DSIM_CORE_VID_MODE_CFG_VID_MODE_TYPE_BURSTMODE (2 << 0) +#define DSIM_CORE_VID_MODE_CFG_VID_MODE_TYPE_HORIZONTALEXPANSION (3 << 0) +#define rDSIM_CORE_VID_PKT_SIZE (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0003C)) +#define rDSIM_CORE_VID_NUM_CHUNKS (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00040)) +#define rDSIM_CORE_VID_NULL_SIZE (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00044)) +#define rDSIM_CORE_VID_HSA_TIME (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00048)) +#define rDSIM_CORE_VID_HBP_TIME (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0004C)) +#define rDSIM_CORE_VID_HLINE_TIME (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00050)) +#define rDSIM_CORE_VID_VSA_LINES (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00054)) +#define rDSIM_CORE_VID_VBP_LINES (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00058)) +#define rDSIM_CORE_VID_VFP_LINES (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0005C)) +#define rDSIM_CORE_VID_VACTIVE_LINES (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00060)) +#define rDSIM_CORE_CMD_MODE_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00068)) + +#if DSIM_VERSION == 1 +#define DSIM_CORE_CMD_MODE_CFG_MAX_RD_PKT_SIZE_LP (1 << 24) +#define DSIM_CORE_CMD_MODE_CFG_DCS_LW_TX_LP (1 << 19) +#define DSIM_CORE_CMD_MODE_CFG_DCS_SR_0P_TX_LP (1 << 18) +#define DSIM_CORE_CMD_MODE_CFG_DCS_SW_1P_TX_LP (1 << 17) +#define DSIM_CORE_CMD_MODE_CFG_DCS_SW_0P_TX_LP (1 << 16) +#endif //DSIM_VERSION == 1 + +#define DSIM_CORE_CMD_MODE_CFG_GEN_LW_TX_LP (1 << 14) +#define DSIM_CORE_CMD_MODE_CFG_GEN_SR_2P_TX_LP (1 << 13) +#define DSIM_CORE_CMD_MODE_CFG_GEN_SR_1P_TX_LP (1 << 12) +#define DSIM_CORE_CMD_MODE_CFG_GEN_SR_0P_TX_LP (1 << 11) +#define DSIM_CORE_CMD_MODE_CFG_GEN_SW_2P_TX_LP (1 << 10) +#define DSIM_CORE_CMD_MODE_CFG_GEN_SW_1P_TX_LP (1 << 9) +#define DSIM_CORE_CMD_MODE_CFG_GEN_SW_0P_TX_LP (1 << 8) +#define DSIM_CORE_CMD_MODE_CFG_ACK_RQST_EN (1 << 1) +#define DSIM_CORE_CMD_MODE_CFG_TEAR_FX_EN (1 << 0) +#define rDSIM_CORE_GEN_HDR (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0006C)) +#define DSIM_CORE_GEN_HDR_GEN_WC_MSBYTE(n) ((n) << 16) +#define DSIM_CORE_GEN_HDR_GEN_WC_LSBYTE(n) ((n) << 8) +#define DSIM_CORE_GEN_HDR_GEN_VC(n) ((n) << 6) +#define DSIM_CORE_GEN_HDR_GEN_DT(n) ((n) << 0) +#define rDSIM_CORE_GEN_PLD_DATA (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00070)) +#define rDSIM_CORE_CMD_PKT_STATUS (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00074)) +#define DSIM_CORE_CMD_PKT_STATUS_GEN_RD_CMD_BUSY (1 << 6) +#define DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_R_FULL (1 << 5) +#define DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_R_EMPTY (1 << 4) +#define DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_W_FULL (1 << 3) +#define DSIM_CORE_CMD_PKT_STATUS_GEN_PLD_W_EMPTY (1 << 2) +#define DSIM_CORE_CMD_PKT_STATUS_GEN_CMD_FULL (1 << 1) +#define DSIM_CORE_CMD_PKT_STATUS_GEN_CMD_EMPTY (1 << 0) +#define rDSIM_CORE_TO_CNT_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00078)) +#define rDSIM_CORE_HS_RD_TO_CNT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0007C)) +#define rDSIM_CORE_LP_RD_TO_CNT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00080)) +#define rDSIM_CORE_HS_WR_TO_CNT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00084)) +#define rDSIM_CORE_LP_WR_TO_CNT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00088)) +#define rDSIM_CORE_BTA_TO_CNT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0008C)) +#define rDSIM_CORE_SDF_3D (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00090)) +#define rDSIM_CORE_LPCLK_CTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00094)) +#define DSIM_CORE_LPCLK_CTRL_AUTO_CLKLANE_CTRL (1 << 1) +#define DSIM_CORE_LPCLK_CTRL_PHY_TXREQUESTCLKHS (1 << 0) +#define rDSIM_CORE_PHY_TMR_LPCLK_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x00098)) +#define DSIM_CORE_PHY_TMR_LPCLK_CFG_PHY_CLKHS2LP_TIME(n) ((n) << 16) +#define DSIM_CORE_PHY_TMR_LPCLK_CFG_PHY_CLKLP2HS_TIME(n) ((n) << 0) +#define rDSIM_CORE_PHY_TMR_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x0009C)) +#define DSIM_CORE_PHY_TMR_CFG_PHY_HS2LP_TIME(n) ((n) << 24) +#define DSIM_CORE_PHY_TMR_CFG_PHY_LP2HS_TIME(n) ((n) << 16) +#define DSIM_CORE_PHY_TMR_CFG_MAX_RD_TIME(n) ((n) << 0) +#define rDSIM_CORE_PHY_RSTZ (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000A0)) +#define DSIM_CORE_PHY_RSTZ_PHY_FORCEPLL (1 << 3) +#define DSIM_CORE_PHY_RSTZ_PHY_ENABLECLK (1 << 2) +#define DSIM_CORE_PHY_RSTZ_PHY_RSTZ (1 << 1) +#define DSIM_CORE_PHY_RSTZ_PHY_SHUTDOWNZ (1 << 0) +#define rDSIM_CORE_PHY_IF_CFG (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000A4)) +#define DSIM_CORE_PHY_IF_CFG_PHY_STOP_WAIT_TIME(n) ((n) << 8) +#define DSIM_CORE_PHY_IF_CFG_N_LANES(n) ((n) << 0) +#define rDSIM_CORE_PHY_ULPS_CTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000A8)) +#define rDSIM_CORE_PHY_TX_TRIGGERS (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000AC)) +#define rDSIM_CORE_PHY_STATUS (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000B0)) +#define DSIM_CORE_PHY_STATUS_PHY_ULPSACTIVENOT3LANE (1 << 12) +#define DSIM_CORE_PHY_STATUS_PHY_STOPSTATE3LANE (1 << 11) +#define DSIM_CORE_PHY_STATUS_PHY_ULPSACTIVENOT2LANE (1 << 10) +#define DSIM_CORE_PHY_STATUS_PHY_STOPSTATE2LANE (1 << 9) +#define DSIM_CORE_PHY_STATUS_PHY_ULPSACTIVENOT1LANE (1 << 8) +#define DSIM_CORE_PHY_STATUS_PHY_STOPSTATE1LANE (1 << 7) +#define DSIM_CORE_PHY_STATUS_PHY_RXULPSESC0LANE (1 << 6) +#define DSIM_CORE_PHY_STATUS_PHY_ULPSACTIVENOT0LANE (1 << 5) +#define DSIM_CORE_PHY_STATUS_PHY_STOPSTATE0LANE (1 << 4) +#define DSIM_CORE_PHY_STATUS_PHY_ULPSACTIVENOTCLK (1 << 3) +#define DSIM_CORE_PHY_STATUS_PHY_STOPSTATECLKLANE (1 << 2) +#define DSIM_CORE_PHY_STATUS_PHY_DIRECTION (1 << 1) +#define DSIM_CORE_PHY_STATUS_PHY_LOCK (1 << 0) +#define rDSIM_CORE_PHY_TST_CTRL0 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000B4)) +#define DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLK (1 << 1) +#define DSIM_CORE_PHY_TST_CTRL0_PHY_TESTCLR (1 << 0) +#define rDSIM_CORE_PHY_TST_CTRL1 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000B8)) +#define DSIM_CORE_PHY_TST_CTRL1_PHY_TESTEN (1 << 16) +#define DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDOUT(n)(((n) >> 8) & 0xff) +#define DSIM_CORE_PHY_TST_CTRL1_PHY_TESTDIN(n) ((n) << 0) +#define rDSIM_CORE_INT_ST0 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000BC)) +#define DSIM_CORE_INT_ST0_DPHY_ERRORS_4 (1 << 20) +#define DSIM_CORE_INT_ST0_PHY_ERRORS_3 (1 << 19) +#define DSIM_CORE_INT_ST0_PHY_ERRORS_1 (1 << 17) +#define DSIM_CORE_INT_ST0_PHY_ERRORS_0 (1 << 16) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_15 (1 << 15) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_14 (1 << 14) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_13 (1 << 13) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_12 (1 << 12) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_11 (1 << 11) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_10 (1 << 10) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_9 (1 << 9) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_8 (1 << 8) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_7 (1 << 7) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_6 (1 << 6) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_5 (1 << 5) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_4 (1 << 4) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_3 (1 << 3) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_2 (1 << 2) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_1 (1 << 1) +#define DSIM_CORE_INT_ST0_ACK_WITH_ERR_0 (1 << 0) +#define rDSIM_CORE_INT_ST1 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000C0)) +#define DSIM_CORE_INT_ST1_GEN_PLD_RECEV_ERR (1 << 12) +#define DSIM_CORE_INT_ST1_GEN_PLD_RD_ERR (1 << 11) +#define DSIM_CORE_INT_ST1_GEN_PLD_SEND_ERR (1 << 10) +#define DSIM_CORE_INT_ST1_GEN_PLD_WR_ERR (1 << 9) +#define DSIM_CORE_INT_ST1_GEN_CMD_WR_ERR (1 << 8) +#define DSIM_CORE_INT_ST1_DPI_PLD_WR_ERR (1 << 7) +#define DSIM_CORE_INT_ST1_EOPT_ERR (1 << 6) +#define DSIM_CORE_INT_ST1_PKT_SIZE_ERR (1 << 5) +#define DSIM_CORE_INT_ST1_CRC_ERR (1 << 4) +#define DSIM_CORE_INT_ST1_ECC_MILTI_ERR (1 << 3) +#define DSIM_CORE_INT_ST1_ECC_SINGLE_ERR (1 << 2) +#define DSIM_CORE_INT_ST1_TO_LP_RX (1 << 1) +#define DSIM_CORE_INT_ST1_TO_HS_TX (1 << 0) +#define DSIM_CORE_INT_ST1_ERRORS (DSIM_CORE_INT_ST1_GEN_PLD_RECEV_ERR | \ + DSIM_CORE_INT_ST1_GEN_PLD_RD_ERR | \ + DSIM_CORE_INT_ST1_GEN_PLD_SEND_ERR | \ + DSIM_CORE_INT_ST1_GEN_PLD_WR_ERR | \ + DSIM_CORE_INT_ST1_GEN_CMD_WR_ERR | \ + DSIM_CORE_INT_ST1_DPI_PLD_WR_ERR | \ + DSIM_CORE_INT_ST1_EOPT_ERR | \ + DSIM_CORE_INT_ST1_PKT_SIZE_ERR | \ + DSIM_CORE_INT_ST1_CRC_ERR | \ + DSIM_CORE_INT_ST1_ECC_MILTI_ERR | \ + DSIM_CORE_INT_ST1_ECC_SINGLE_ERR) +#define rDSIM_CORE_INT_MSK0 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000C4)) +#define rDSIM_CORE_INT_MSK1 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000C8)) +#define rDSIM_CORE_VID_VBP_HS_LINES (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000D0)) +#define rDSIM_CORE_VID_VFP_HS_LINES (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x000D4)) + +//TOP +#define rDSIM_VERSION (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80000)) + +#define rDSIM_GENERAL_CTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80004)) +#define DSIM_GENERAL_CTRL_HSYNC_MASK_STATUS_ON (1 << 28) +#define DSIM_GENERAL_CTRL_HSYNC_MASK_ENABLE (1 << 27) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_TIMER(n) ((n) << 12) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_DYN (1 << 11) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_OFFSET(n) ((n) << 9) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_ROUND_TOL0 (0 << 7) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_ROUND_TOL1 (1 << 7) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_ROUND_TOL2 (2 << 7) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_ROUND_TOL3 (3 << 7) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_VALID (1 << 6) +#define DSIM_GENERAL_CTRL_VID_HTIME_AUTO_SEL (1 << 5) +#define DSIM_GENERAL_CTRL_PHYLOCK_HW_LOCK (1 << 4) +#define DSIM_GENERAL_CTRL_PHYLOCK_SW_LOCK (1 << 3) +#define DSIM_GENERAL_CTRL_DPISHUTDN (1 << 2) +#define DSIM_GENERAL_CTRL_DPICOLORM_REDUCED (1 << 1) +#define DSIM_GENERAL_CTRL_DPIHALT_HALT (1 << 0) + +#define rDSIM_LANE_SWAP (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80008)) +#define rDSIM_TOP_PIXEL_REMAP (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x8000C)) +#define rDSIM_PIXEL_SWAP (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80010)) +#define rDSIM_TEST_COLOR (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80014)) +#define rDSIM_VID_HSA_TIME (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80018)) +#define rDSIM_VID_HBP_TIME (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x8001C)) +#define rDSIM_VID_HLINE_TIME (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80020)) + +#if DSIM_VERSION > 1 +#define rDSIM_TOP_AGILE_CTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80024)) +#define DSIM_TOP_AGILE_CTRL_HS_PACKET_LATENCY(n) ((n) << 24) +#define DSIM_TOP_AGILE_CTRL_HS_PACKET_STATUS_HS (1 << 23) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_ENABLE_STATUS (1 << 22) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_RESET (1 << 21) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_TRIGGER (1 << 20) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH(n) ((n) << 18) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH_VFRONT DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH(0x0) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH_VSYNC DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH(0x1) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH_VBACK DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH(0x2) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH_VACTIVE DSIM_TOP_AGILE_CTRL_LINECOUNT_FINISH(0x3) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_START(n) ((n) << 16) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_START_VFRONT DSIM_TOP_AGILE_CTRL_LINECOUNT_START(0x0) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_START_VSYNC DSIM_TOP_AGILE_CTRL_LINECOUNT_START(0x1) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_START_VBACK DSIM_TOP_AGILE_CTRL_LINECOUNT_START(0x2) +#define DSIM_TOP_AGILE_CTRL_LINECOUNT_START_VACTIVE DSIM_TOP_AGILE_CTRL_LINECOUNT_START(0x3) +#define DSIM_TOP_AGILE_CTRL_TIMEBASE(n) ((n) << 8) +#define DSIM_TOP_AGILE_CTRL_STATE(n) ((n) << 4) +#define DSIM_TOP_AGILE_CTRL_ENABLE (1 << 3) +#define DSIM_TOP_AGILE_CTRL_USE_TEMP_CLK (1 << 2) +#define DSIM_TOP_AGILE_CTRL_IDLE_FRAME (1 << 1) +#define DSIM_TOP_AGILE_CTRL_VBLANK_ON (1 << 0) + +#define rDSIM_TOP_AGILE_LINECOUNT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80028)) +#define DSIM_TOP_AGILE_LINECOUNT_CONFIG_MAX (0xFFFF) + +#define rDSIM_TOP_AGILE_SEQ1 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x8002c)) +#define rDSIM_TOP_AGILE_SEQ2 (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80030)) + +#define rDSIM_TOP_PLL_CTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80034)) +#define DSIM_TOP_PLL_CTRL_PLL_CFG_SEL_PHY (1 << 31) +#define DSIM_TOP_PLL_CTRL_PLL_SHADOW_CONTROL_PHY (1 << 30) +#define DSIM_TOP_PLL_CTRL_PLL_SHADOW_CONTROL_OBS_PHY (1 << 29) +#define DSIM_TOP_PLL_CTRL_SEQ_OW_ON (1 << 28) +#define DSIM_TOP_PLL_CTRL_UPDATEPLL_ON (1 << 27) +#define DSIM_TOP_PLL_CTRL_CLKSELPLL_MASK (3 << 25) +#define DSIM_TOP_PLL_CTRL_CLKSELPLL_PLLCLK (1 << 25) +#define DSIM_TOP_PLL_CTRL_CLKSELPLL_TEMPCLK (2 << 25) +#define DSIM_TOP_PLL_CTRL_TEMP_MIPI_DSI_CLK_REQ (1 << 24) +#define DSIM_TOP_PLL_CTRL_TEMP_MIPI_DSI_CLK_ACK_ON (1 << 23) +#define DSIM_TOP_PLL_CTRL_CSI_SEL_CSI2 (1 << 10 +#define DSIM_TOP_PLL_CTRL_HSFREQRANGE(n) ((n) << 4) +#define DSIM_TOP_PLL_CTRL_FORCEPLL_ON (1 << 3) +#define DSIM_TOP_PLL_CTRL_SHADOW_CLEAR (1 << 2) +#define DSIM_TOP_PLL_CTRL_FORCE_LOCK (1 << 1) +#define DSIM_TOP_PLL_CTRL_ONPLL_PWRUP (1 << 0) + +#define rDSIM_TOP_PLL_PARAM (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80038)) +#define DSIM_TOP_PLL_PARAM_VCOCAP(n) ((n) << 27) +#define DSIM_TOP_PLL_PARAM_VCORANGE(n) ((n) << 25) +#define DSIM_TOP_PLL_PARAM_LPFCTRL(n) ((n) << 19) +#define DSIM_TOP_PLL_PARAM_ICPCTRL(n) ((n) << 15) +#define DSIM_TOP_PLL_PARAM_P(n) ((n) << 14) +#define DSIM_TOP_PLL_PARAM_M(n) ((n) << 4) +#define DSIM_TOP_PLL_PARAM_N(n) ((n) << 0) + +#define rDSIM_TOP_PLL_PARAM_OBS (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x8003c)) +#define rDSIM_TOP_PLL_LOCK (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80040)) +#define rDSIM_TOP_PLL_TEST (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80044)) +#define rDSIM_TOP_BIST_CTRL (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x80048)) +#define rDSIM_TOP_HSYNC_PREDICT (*(volatile u_int32_t *)(DSIM_BASE_ADDR + 0x8004c)) +#endif //DSIM_VERSION + +#endif /* __SYNOPSYS_DSIM_H */ diff --git a/drivers/synopsys/mipi/include/drivers/mipi/mipi.h b/drivers/synopsys/mipi/include/drivers/mipi/mipi.h new file mode 100644 index 0000000..6f57de2 --- /dev/null +++ b/drivers/synopsys/mipi/include/drivers/mipi/mipi.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __MIPI_DISPLAY_H +#define __MIPI_DISPLAY_H + +#include + +__BEGIN_DECLS + +#define MAX_PHY_VALUES 9 +#define MAX_NUM_OF_TEST_DATA 6 + +struct phy_setting_vals { + uint8_t test_code; + uint8_t num_of_data; + uint8_t test_data[MAX_NUM_OF_TEST_DATA]; +}; + +struct phy_settings { + uint8_t num_of_values; + struct phy_setting_vals phy_setting_values[MAX_PHY_VALUES]; +}; + +typedef struct +{ + uint32_t lanes : 4; // 3:0 + uint32_t esc_div : 4; // 7:4 + uint32_t pll_n : 3; // 10:8 + uint32_t resvd0 : 1; // 11 + uint32_t pll_m : 10; // 21:12 + uint32_t pll_p : 1; // 22 + uint32_t resvd1 : 1; // 23 + uint32_t hsfreq : 8; // 31:24 + struct phy_settings target_phy_settings; +} mipi_t; + +__END_DECLS + +#endif /* __MIPI_DISPLAY_H */ diff --git a/drivers/synopsys/mipi/rules.mk b/drivers/synopsys/mipi/rules.mk new file mode 100644 index 0000000..24dc6d8 --- /dev/null +++ b/drivers/synopsys/mipi/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2008-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIPI_DSIM=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dsim.o + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include diff --git a/drivers/synopsys/usbotg/rules.mk b/drivers/synopsys/usbotg/rules.mk new file mode 100644 index 0000000..0608cd8 --- /dev/null +++ b/drivers/synopsys/usbotg/rules.mk @@ -0,0 +1,23 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# Copyright (C) 2007-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += + +OPTIONS += \ + WITH_HW_USB=1 \ + WITH_HW_SYNOPSYS_OTG=1 + +MODULES += \ + drivers/usb + +ALL_OBJS += \ + $(LOCAL_DIR)/synopsys_otg.o diff --git a/drivers/synopsys/usbotg/synopsys_otg.c b/drivers/synopsys/usbotg/synopsys_otg.c new file mode 100644 index 0000000..d205749 --- /dev/null +++ b/drivers/synopsys/usbotg/synopsys_otg.c @@ -0,0 +1,1691 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_POWER +#include +#endif + +#include "synopsys_otg_regs.h" +#include +#include +#include +#include + +//=================================================================================== +// typedefs, structs +//=================================================================================== + +struct usb_endpoint_instance +{ + u_int32_t endpoint_address; + u_int32_t max_packet_size; + u_int32_t attributes; + u_int32_t bInterval; + + u_int32_t interrupt_status; + + u_int32_t transfer_size; + u_int32_t packet_count; + bool is_active; + + struct usb_endpoint_instance *next_ep; + + struct usb_device_io_request *io_head; + struct usb_device_io_request *io_tail; + + struct usb_device_io_request *completion_head; + struct usb_device_io_request *completion_tail; + + int tx_fifo_number; +}; + + +//=================================================================================== +// Local macros and consts +//=================================================================================== +#define EP_INT_MASK 0x1 +#define MAX_EP0_DMA_SIZE 0x40 +#define MAX_EP_NEEDED 12 // MAX_EP_NUMBER * 2 + EP0 IN/OUT +#define MAX_EP_NUMBER 5 +#define MAX_EPn_DMA_SIZE 0x7ffff +#define MAX_TX_FIFO_SUPPORTED 15 + +#define EP_NUM_MASK (0x7f) +#define EP_DIR_MASK (0x80) + +#define USB_AHBIDLE_TIMEOUT (5 * 1000 * 1000) +#define USB_SFTRST_TIMEOUT (5 * 1000 * 1000) + +#define DEBUG 0 + +#define print(fmt, args...) (void)0 + +#if (DEBUG == 1) +#undef print +#define print(fmt, args...) dprintf(DEBUG_INFO, "%s --- " fmt, __FUNCTION__, ##args) +#endif + +#if (DEBUG == 2) +#undef print +#define print(fmt, args...) usb_print_message_var("%s --- " fmt, __FUNCTION__, ##args) +#endif + +#define ep_to_epnum(ep) ((ep) & EP_NUM_MASK) +#define ep_to_epdir(ep) ((ep) & EP_DIR_MASK) +#define ep_to_epindex(ep) ((2 * ep_to_epnum((ep))) + (ep_to_epdir((ep)) ? 0 : 1)) + +#define DTKNQR1_INTKNWPTR_OFFSET 2 +#define DTKNQR_INTKNWPTR_WIDTH 4 +#define DTKNQR_TOTAL_TOKENS (32 / DTKNQR_INTKNWPTR_WIDTH) + +#define dtknqr_eptkn_get(x, off) (((x) & (0xF << ((off) * DTKNQR_INTKNWPTR_WIDTH))) >> ((off) * DTKNQR_INTKNWPTR_WIDTH)) + +#define SHARED_FIFO_NP_TX_FIFO_NUM 0 + +#define EPDISBLD_TIMEOUT (1 * 1000) +#define FIFOFLSH_TIMEOUT (1 * 1000) +#define NAKEFF_TIMEOUT (1 * 1000) + +enum +{ + // Use different bits for each event type + EVENT_TYPE_NONE = 0, + EVENT_TYPE_INTERRUPT = 1, + EVENT_TYPE_EXIT = 2 +}; + +#define VERSION_300a 0x300a + +//=================================================================================== +// Global and local variables +//=================================================================================== + +static u_int8_t __aligned(CPU_CACHELINE_SIZE) ep0_rx_buffer[EP0_MAX_PACKET_SIZE]; +static u_int8_t setup_pkt_buffer[SETUP_PACKET_LEN]; +static bool setup_pkt_buffer_valid = false; +static struct usb_endpoint_instance synopsys_otg_endpoints[MAX_EP_NEEDED]; +static u_int32_t next_tx_fifo_start_addr = 0; +static u_int8_t tx_fifo_list[MAX_TX_FIFO_SUPPORTED]; +static u_int32_t max_dma_size; +static u_int32_t max_packet_count; + +static u_int32_t core_version; + +static struct task * controller_task = NULL; +static struct task_event usb_task_event; +static struct task_event usb_task_terminate_event; +static u_int32_t usb_task_event_status; +static uint32_t synopsys_otg_gintsts; +static uint32_t synopsys_otg_daintsts; + + +//=================================================================================== +// Local function prototypes +//=================================================================================== +static void synopsys_otg_start_ep0_out(bool data_phase); +static void synopsys_otg_print_endpoints(void); +static void synopsys_otg_start_endpoint_in(u_int32_t endpoint); +static void synopsys_otg_start_endpoint_out(u_int32_t endpoint); +static void synopsys_otg_int_handler(void *blah); +static int set_global_in_nak(void); +static void clear_global_in_nak(void); +static int flush_tx_fifo(int fifo); +static int set_global_out_nak(void); +static void clear_global_out_nak(void); +static int synopsys_otg_stop_endpoint_out(int ep_num); +static int synopsys_otg_stop_endpoint_in(int ep_num); +static void synopsys_otg_disable_in_endpoint(u_int32_t endpoint); +static void synopsys_otg_reset_states(void); +static void enqueue_finished_request(struct usb_endpoint_instance *ep, struct usb_device_io_request *io_req); +static void scavenge_endpoint_finished_list(u_int32_t endpoint); +static void synopsys_otg_go_on_bus(void); + +//=================================================================================== +// Logging stuff +//=================================================================================== + +#if (DEBUG == 2) + +#define MAX_LOG_LEN 100 + +static u_int8_t *log_buffer; +static const int log_buffer_len = (32 * 1024); + +static u_int8_t *writeptr; +static u_int8_t *readptr; + +void usb_print_message_var(char *fmt, ...) +{ + va_list ap; + char buf[MAX_LOG_LEN]; + char *bp = buf; + u_int8_t *end = log_buffer + log_buffer_len; + + va_start(ap, fmt); + vsnprintf(buf, MAX_LOG_LEN, fmt, ap); + va_end(ap); + + while(*bp) { + *writeptr++ = *bp++; + + if(writeptr == end) { + writeptr = log_buffer; + } + + if(writeptr == readptr) { + if(++readptr == end) { + readptr = log_buffer; + } + } + } +} + +void usb_print_log_buffer() +{ + u_int8_t *end = log_buffer + log_buffer_len; + + while(readptr != writeptr) { + printf("%c", *readptr++); + if(readptr == end) + readptr = log_buffer; + } +} + +#endif + +//=================================================================================== +// Local functions +//=================================================================================== + +static u_int32_t read_reg(addr_t address) +{ + return (*(volatile u_int32_t *)(address)); +} + + +static void write_reg(addr_t address, u_int32_t value) +{ + *(volatile u_int32_t *)(address) = value; +} + + +static void or_reg(addr_t address, u_int32_t value) +{ + *(volatile u_int32_t *)(address) = read_reg(address) | value; +} + + +static void and_reg(addr_t address, u_int32_t value) +{ + *(volatile u_int32_t *)(address) = read_reg(address) & value; +} + + +static void set_bits_in_reg(addr_t address, u_int32_t pos, u_int32_t mask, u_int32_t val) +{ + u_int32_t reg_val = *(volatile u_int32_t *)address; + + reg_val &= ~(mask); + reg_val |= (val << pos); + + *(volatile u_int32_t *)address = reg_val; +} + + +static int get_next_tx_fifo_num(void) +{ + int i; + + for(i = 0; i < MAX_TX_FIFO_SUPPORTED; i++) { + if(tx_fifo_list[i] == 0) { + tx_fifo_list[i] = 1; + break; + } + } + + return(i + 1); +} + + +static u_int32_t get_rx_fifo_size(void) +{ + return((4 * 1 + 6) + 2 * ((HS_BULK_EP_MAX_PACKET_SIZE / 4) + 8) + 1); +} + + +static u_int32_t get_np_tx_fifo_size(void) +{ + return((2 * (HS_BULK_EP_MAX_PACKET_SIZE / 4))); +} + + +static u_int32_t get_ep0_tx_fifo_size(void) +{ + return((2 * (HS_BULK_EP_MAX_PACKET_SIZE / 4))); +} + + +static u_int32_t get_endpoint_fifo_number(int endpoint) +{ + return (synopsys_otg_endpoints[ep_to_epindex(endpoint)].tx_fifo_number); +} + + +static void synopsys_otg_print_endpoints(void) +{ + u_int32_t num_dev_eps = 0; + u_int32_t dir = 0; + u_int32_t hwcfg1 = 0; + u_int32_t in_eps = 0; + u_int32_t out_eps = 0; + u_int32_t i; + + num_dev_eps = ((read_reg(DWCUSB_GHWCFG2) >> DWCUSB_GHWCFG2_NUMDEVEPS_SHIFT) & 0xf); + hwcfg1 = read_reg(DWCUSB_GHWCFG1); + + i = 1; + do { + dir = (hwcfg1 >> (i * 2)) & 0x3; + switch(dir) + { + case 0 : /* BI */ + in_eps++; + out_eps++; + print("EP %d BIDIR \n", i); + break; + + case 1 : /* IN */ + in_eps++; + print("EP %d IN \n", i); + break; + + case 2 : /* OUT */ + out_eps++; + print("EP %d OUT \n", i); + break; + + default : + /* Bad value */ + dprintf(DEBUG_INFO, "synopsys_otg_controller : synopsys_otg_set_max_endpoints --- Bad Value \n"); + return ; + } + + i++; + if((in_eps + out_eps) >= num_dev_eps) break; + + } while (true); +} + + +static void synopsys_otg_start_controller(void) +{ + utime_t start_time; + u_int32_t val; + u_int32_t USBTrdTim; + int i; + + val = (read_reg(DWCUSB_GHWCFG3) & DWCUSB_GHWCFG3_PKTSIZEWIDTH_MASK) >> DWCUSB_GHWCFG3_PKTSIZEWIDTH_SHIFT; + max_packet_count = (1 << (val + 4)) - 1; + val = read_reg(DWCUSB_GHWCFG3) & DWCUSB_GHWCFG3_XFERSIZEWIDTH_MASK; + max_dma_size = (1 << (val + 11)) - 1; + + print("MAX_PKT_CNT: %d, MAX_XFERSIZ_CNT: %d\n", max_packet_count, max_dma_size); + + /* Wait for core reset and AHB idle */ + write_reg(DWCUSB_GRSTCTL, DWCUSB_GRSTCTL_CSFTRST); + + start_time = system_time(); + while (read_reg(DWCUSB_GRSTCTL) & DWCUSB_GRSTCTL_CSFTRST) { + if(time_has_elapsed(start_time, USB_SFTRST_TIMEOUT)) { + panic("USB Core Reset timed out \n"); + } + } + + /* Set the soft disconnect bit */ + or_reg(DWCUSB_DCTL, DWCUSB_DCTL_SFTDISCON); + + start_time = system_time(); + while (!(read_reg(DWCUSB_GRSTCTL) & DWCUSB_GRSTCTL_AHBIDLE)) { + if(time_has_elapsed(start_time, USB_AHBIDLE_TIMEOUT)) { + panic("USB AHBIDLE timed out \n"); + } + } + + /* Program GAHBCFG */ + write_reg(DWCUSB_GAHBCFG, DWCUSB_GAHBCFG_DMAEN | USBOTG_AHB_DMA_BURST | DWCUSB_GAHBCFG_GLBLINTRMSK); + +#ifdef USBCFG_TURNAROUND_TIME + USBTrdTim = USBCFG_TURNAROUND_TIME; +#else + USBTrdTim = 5; // Use the default +#endif + + /* Program GUSBCFG */ + write_reg(DWCUSB_GUSBCFG, DWCUSB_GUSBCFG_PHYSEL_HS | + DWCUSB_GUSBCFG_UTMI | + (USBTrdTim << DWCUSB_GUSBCFG_USBTRDTIM_SHIFT) | + DWCUSB_GUSBCFG_PHYIF_16 | + (0 << DWCUSB_GUSBCFG_TOUTCAL_SHIFT)); + + /* Program DCFG */ + write_reg(DWCUSB_DCFG, (0 << DWCUSB_DCFG_DEVADDR_SHIFT) | + DWCUSB_DCFG_NZSTSOUTHSHK | + DWCUSB_DCFG_DEVSPD_HS | + (0 << DWCUSB_DCFG_EPMISCNT_SHIFT)); + + /* mask all the interrupts */ + write_reg(DWCUSB_GINTMSK, 0); + write_reg(DWCUSB_DOEPMSK, 0); + write_reg(DWCUSB_DIEPMSK, 0); + write_reg(DWCUSB_DAINTMSK, 0); + + // clear any pending interrupts + write_reg(DWCUSB_GINTSTS, 0xffffffff); + for(i = MAX_EP_NUMBER; i >= 0; i-- ) { + write_reg(DWCUSB_DIEPINT(i), 0x1f); + write_reg(DWCUSB_DOEPINT(i), 0xf); + } + + /* Program GINTMSK */ + write_reg(DWCUSB_GINTMSK, DWCUSB_GINT_USBRST | + DWCUSB_GINT_ENUMDONE); + + /* Read the OTG Core version */ + core_version = read_reg(DWCUSB_GSNPSID) & 0xffff; +} + +static void synopsys_otg_reset_states(void) +{ + // reset next tx fifo related variables + next_tx_fifo_start_addr = get_ep0_tx_fifo_size() + get_rx_fifo_size(); + memset(tx_fifo_list, 0, MAX_TX_FIFO_SUPPORTED); +} + +static void synopsys_otg_handle_usb_reset(void) +{ + int i; + + synopsys_otg_reset_states(); + + // reset all device related interrupts mask, and clear any pending device related interrupt + write_reg(DWCUSB_DOEPMSK, 0); + write_reg(DWCUSB_DIEPMSK, 0); + write_reg(DWCUSB_DAINTMSK, 0); + for(i = MAX_EP_NUMBER; i >= 0; i--) { + write_reg(DWCUSB_DIEPINT(i), 0x1f); + write_reg(DWCUSB_DOEPINT(i), 0xf); + } + + // If any of the interfaces did not abort their endpoint, we should do it now. + // EP0_OUT should not be aborted. EP0_IN is already aborted. Abort all other endpoints. + for(i = MAX_EP_NUMBER; i > 0; i-- ) { + usb_core_abort_endpoint(USB_DIR_IN | i); + usb_core_abort_endpoint(i); + } + + // reset endpoint instance array + bzero(synopsys_otg_endpoints, sizeof(struct usb_endpoint_instance) * MAX_EP_NEEDED); + + u_int32_t rxFifo = get_rx_fifo_size(); + u_int32_t txFifo0 = get_np_tx_fifo_size(); + + write_reg(DWCUSB_GRXFSIZ, rxFifo); + write_reg(DWCUSB_GNPTXFSIZ, (txFifo0 << DWCUSB_GNPTXFSIZ_NPTXFDEP_SHIFT) | rxFifo); + + synopsys_otg_endpoints[ep_to_epindex(EP0_IN)].endpoint_address = 0x80; + synopsys_otg_endpoints[ep_to_epindex(EP0_IN)].max_packet_size = EP0_MAX_PACKET_SIZE; + synopsys_otg_endpoints[ep_to_epindex(EP0_IN)].tx_fifo_number = 0; + synopsys_otg_endpoints[ep_to_epindex(EP0_IN)].is_active = true; + synopsys_otg_endpoints[ep_to_epindex(EP0_OUT)].endpoint_address = 0; + synopsys_otg_endpoints[ep_to_epindex(EP0_OUT)].max_packet_size = EP0_MAX_PACKET_SIZE; + synopsys_otg_endpoints[ep_to_epindex(EP0_OUT)].is_active = true; + + /// activate EP0 and setup EP0 OUT + write_reg(DWCUSB_DOEPCTL(0), DWCUSB_DEP0CTL_MPS_64); + write_reg(DWCUSB_DIEPCTL(0), (DWCUSB_DEP0CTL_MPS_64)); + + // enable more interrupts + or_reg(DWCUSB_GINTMSK, DWCUSB_GINT_USBSUSP | + DWCUSB_GINT_WKUPINT | + DWCUSB_GINT_OEPINT | + DWCUSB_GINT_IEPINT); + + write_reg(DWCUSB_DOEPMSK, DWCUSB_DOEPINT_SETUP | DWCUSB_DOEPINT_XFERCOMPL | DWCUSB_DOEPINT_AHBERR); + write_reg(DWCUSB_DIEPMSK, DWCUSB_DIEPINT_XFERCOMPL | DWCUSB_DIEPINT_TIMEOUT | DWCUSB_DIEPINT_AHBERR); + + write_reg(DWCUSB_DAINTMSK, 1 | (1 << DWCUSB_DAINT_OEP_SHIFT)); + + synopsys_otg_start_ep0_out(false); +} + + +static void synopsys_otg_handle_enum_done(void) +{ + int is_hs = ((read_reg(DWCUSB_DSTS) & DWCUSB_DSTS_ENUMSPD_MASK) == DWCUSB_DSTS_ENUMSPD_HS); + + if(is_hs) + print("High-speed \n"); + else + print("Full-speed \n"); + + usb_core_event_handler(USB_ENUM_DONE); +} + + +static void synopsys_otg_handle_ep0_out(void) +{ + struct usb_endpoint_instance *ep = &synopsys_otg_endpoints[ep_to_epindex(EP0_OUT)]; + u_int32_t depintsts; + u_int32_t data_rcvd; + bool data_phase = false; + bool is_setup_pkt; + bool is_data_pkt; + + enter_critical_section(); + depintsts = ep->interrupt_status; + ep->interrupt_status = 0; + exit_critical_section(); + + print("DWCUSB_DOEPINT(0) %08x \n", depintsts); + + // On older OTG cores (version < 0x300a) DOEPINT:SETUP interrupt is asserred for setup packets and DOEPINT:XFERCOMPL for data packets. + // As per the definition, the DOEPINT:SETUP bit is set only when the host begins the data / status phase. This means, + // if the host sends back to back setup packets, we will get an interrupt only for the last setup packet. At this point + // we are ready to start decoding the setup packet and prepare the endpoint to receive data / status packet. + // + // In OTG verision 0x300a, XFERCOMPL is asserted whenever it sees either a setup or data packet. We then + // use DOEPINT:STUPKTRCVD bit to identify if this is a setup or a data packet. This means, if the host sends + // back to back setup packets, we will get one XFERCOMPL interrupt for each of them. It is the responsibility of SW + // to buffer the setup packet and decode the last packet later when we get DOEPINT:SETUP interrupt which comes + // when the host begins the data / status phase. + // + // In either case, we should wait for the DOEPINT:SETUP interrupt before decoding the setup packet and preparing + // the endpoint to receive data / status packet. See radar for more details. + + is_setup_pkt = (core_version < VERSION_300a) ? (depintsts & DWCUSB_DOEPINT_SETUP) : (depintsts & DWCUSB_DOEPINT_STUPKTRCVD); + is_data_pkt = (!is_setup_pkt && (depintsts & DWCUSB_DOEPINT_XFERCOMPL)); + + // If we got a setup packet copy the packet into a temporary buffer. If there are back to back setup packets, this buffer + // stores the latest setup packet + if(is_setup_pkt) { + memcpy(setup_pkt_buffer, ep0_rx_buffer, SETUP_PACKET_LEN); + setup_pkt_buffer_valid = true; + } + + // If there is a DOEPINT:SETUP interrupt, we should process the setup packet + if((depintsts & DWCUSB_DOEPINT_SETUP) && setup_pkt_buffer_valid) { + usb_core_handle_usb_control_receive(setup_pkt_buffer, true, SETUP_PACKET_LEN, &data_phase); + setup_pkt_buffer_valid = false; + } + else if(is_data_pkt) { + // Handle the data packet + data_rcvd = EP0_MAX_PACKET_SIZE - (read_reg(DWCUSB_DOEPTSIZ(0)) & DWCUSB_DEP0TSIZ_XFERSIZE_MASK); + usb_core_handle_usb_control_receive(ep0_rx_buffer, false, data_rcvd, &data_phase); + } + + synopsys_otg_start_ep0_out(data_phase); +} + + +static void synopsys_otg_start_ep0_out(bool data_phase) +{ + u_int32_t val; + + write_reg(DWCUSB_DOEPTSIZ(0), (1 << DWCUSB_DEPTSIZ_SUPCNT_SHIFT) | + (1 << DWCUSB_DEPTSIZ_PKTCNT_SHIFT) | + (EP0_MAX_PACKET_SIZE)); + + platform_cache_operation(CACHE_INVALIDATE | CACHE_CLEAN, (void *)ep0_rx_buffer, EP0_MAX_PACKET_SIZE); + + write_reg(DWCUSB_DOEPDMA(0), (uint32_t)ep0_rx_buffer); + + val = DWCUSB_DEPCTL_EPENA; + + if(data_phase) { + val |= DWCUSB_DEPCTL_CNAK; + } + + or_reg(DWCUSB_DOEPCTL(0), val); + + print("EP0 OUT started \n"); +} + + +static void synopsys_otg_handle_endpoint_out(u_int32_t endpoint) +{ + struct usb_device_io_request *finished_req; + u_int32_t ep_num = ep_to_epnum(endpoint); + struct usb_endpoint_instance *ep; + u_int32_t depintsts; + + ep = &synopsys_otg_endpoints[ep_to_epindex(endpoint)]; + depintsts = read_reg(DWCUSB_DOEPINT(ep_num)); + ep->interrupt_status |= depintsts; + write_reg(DWCUSB_DOEPINT(ep_num), depintsts); + + print("ep_num: %d depintsts: %08x \n", ep_num, depintsts); + + if(endpoint == EP0_OUT) { + // Don't do anything. All EP0 requests will be handled in the secondary. + return; + } + + if(depintsts & DWCUSB_DOEPINT_XFERCOMPL) { + u_int32_t eptsizval = 0; + u_int32_t len = 0; + u_int32_t lenMod; + + eptsizval = read_reg(DWCUSB_DOEPTSIZ(ep_num)); + + len = (ep->transfer_size - (int)(eptsizval & DWCUSB_DEPTSIZ_XFERSIZE_MASK)); + + ep->io_head->return_count += len; + print("recvd %d \n", ep->io_head->return_count); + + lenMod = len % ep->max_packet_size; + + if(((len < ep->transfer_size) && lenMod) \ + || (len == 0)) { + ep->transfer_size = 0; + goto done; + } + + // Check following condition - received mutiple of ep mps worth data + a zlp to complete transfer + // There is no simple way to check this in existing hw. So... we know how many packets we wanted to + // receive, and how much we received. If we have received multiple of ep mps and zlp, + // packet count should be decremented by - (data_received / ep_mps + 1) + if(lenMod == 0) { + int lenDiv; + int pktCnt; + + lenDiv = len / ep->max_packet_size; + pktCnt = ep->packet_count - + (int)((eptsizval & DWCUSB_DEPTSIZ_PKTCNT_MASK) >> DWCUSB_DEPTSIZ_PKTCNT_SHIFT); + print("%d %d %d %d\n", ep->packet_count, \ + ((eptsizval & DWCUSB_DEPTSIZ_PKTCNT_MASK) >> DWCUSB_DEPTSIZ_PKTCNT_SHIFT), lenDiv, pktCnt); + if(lenDiv == (pktCnt - 1)) { + ep->packet_count = 0; + ep->transfer_size = 0; + goto done; + } + } + + ep->transfer_size = 0; + ep->packet_count = 0; + + if(ep->io_head->return_count < ep->io_head->io_length) { + synopsys_otg_start_endpoint_out(ep->endpoint_address); + goto next_out_int; + } + + done : + ep->io_head->status = USB_IO_SUCCESS; + + finished_req = ep->io_head; + if(ep->io_head != ep->io_tail) { + ep->io_head = ep->io_head->next; + finished_req->next = NULL; + synopsys_otg_start_endpoint_out(ep->endpoint_address); + } + else { + ep->io_head = ep->io_tail = NULL; + } + + enqueue_finished_request(ep, finished_req); + } + + next_out_int : + + if(depintsts & DWCUSB_DOEPINT_AHBERR) { + panic("AHBERR on endpoint %x at %08x \n", endpoint, read_reg(DWCUSB_DOEPDMA(ep_num))); + } +} + + +static void synopsys_otg_start_endpoint_out(u_int32_t endpoint) +{ + int ep_num; + struct usb_endpoint_instance *ep; + struct usb_device_io_request *req; + u_int32_t xfer_size; + u_int32_t pkt_cnt = 0; + u_int32_t rcvd; + + ep = &synopsys_otg_endpoints[ep_to_epindex(endpoint)]; + + ASSERT(ep->io_head != NULL); + + ep_num = ep_to_epnum(endpoint); + req = ep->io_head; + xfer_size = req->io_length; + rcvd = req->return_count; + + print("ep_num: %d rcvd: %d xfer_size: %d \n", ep_num, rcvd, xfer_size); + + xfer_size = xfer_size - rcvd; + if(xfer_size > max_dma_size) { + xfer_size = max_dma_size; + } + + platform_cache_operation(CACHE_INVALIDATE | CACHE_CLEAN, (void *)(req->io_buffer + rcvd), xfer_size); + + write_reg(DWCUSB_DOEPDMA(ep_num), (uint32_t)req->io_buffer + rcvd); + + /* Program the transfer size and packet count as follows: + * + * pktcnt = N + * xfersize = N * maxpacket + */ + if (xfer_size == 0) { + /* Zero Length Packet */ + xfer_size = ep->max_packet_size; + pkt_cnt = 1; + } + else { + pkt_cnt = (xfer_size + (ep->max_packet_size - 1)) / ep->max_packet_size; + if(pkt_cnt > max_packet_count) { + pkt_cnt = max_packet_count; + } + xfer_size = pkt_cnt * ep->max_packet_size; + } + + ep->transfer_size = xfer_size; + ep->packet_count = pkt_cnt; + + write_reg(DWCUSB_DOEPTSIZ(ep_num), (pkt_cnt << DWCUSB_DEPTSIZ_PKTCNT_SHIFT) | (xfer_size)); + + or_reg(DWCUSB_DOEPCTL(ep_num), DWCUSB_DEPCTL_EPENA | + DWCUSB_DEPCTL_CNAK); + + print("Finish start_endpoint_out(%d) \n", ep_num); +} + + +static void synopsys_otg_handle_endpoint_in(u_int32_t endpoint) +{ + struct usb_device_io_request *finished_req; + int ep_num = ep_to_epnum(endpoint); + struct usb_endpoint_instance *ep; + uint32_t depintsts; + + ep = &synopsys_otg_endpoints[ep_to_epindex(endpoint)]; + depintsts = read_reg(DWCUSB_DIEPINT(ep_num)); + ep->interrupt_status |= depintsts; + write_reg(DWCUSB_DIEPINT(ep_num), depintsts); + + print("DWCUSB_DIEPINT(%d) %08x \n", ep_num, depintsts); + + if(depintsts & DWCUSB_DIEPINT_XFERCOMPL) { + + ep->io_head->return_count += ep->transfer_size; + ep->transfer_size = ep->packet_count = 0; + + print("return_count %d io_size %d \n", ep->io_head->return_count, ep->io_head->io_length); + + if(ep->io_head->return_count < ep->io_head->io_length) { + synopsys_otg_start_endpoint_in(ep->endpoint_address); + goto next_in_int; + } + + ep->io_head->status = USB_IO_SUCCESS; + + finished_req = ep->io_head; + if(ep->io_head != ep->io_tail) { + ep->io_head = ep->io_head->next; + finished_req->next = NULL; + synopsys_otg_start_endpoint_in(ep->endpoint_address); + } + else { + ep->io_head = ep->io_tail = NULL; + } + + enqueue_finished_request(ep, finished_req); + } + + next_in_int : + + if(depintsts & DWCUSB_DIEPINT_TIMEOUT) { + dprintf(DEBUG_INFO, "TIME OUT condition detected for EP %x \n", endpoint); + synopsys_otg_disable_in_endpoint((u_int32_t)endpoint); + synopsys_otg_start_endpoint_in(endpoint); + } + + if(depintsts & DWCUSB_DIEPINT_AHBERR) { + panic("AHBERR on endpoint %x at %08x \n", endpoint, read_reg(DWCUSB_DIEPDMA(ep_num))); + } +} + + +static void synopsys_otg_start_endpoint_in(u_int32_t endpoint) +{ + u_int32_t ep_num; + struct usb_endpoint_instance *ep; + struct usb_device_io_request *req; + u_int32_t max_dma_size_local; + u_int32_t xfer_size; + u_int32_t sent; + u_int32_t pkt_cnt = 0; + + ep = &synopsys_otg_endpoints[ep_to_epindex(endpoint)]; + + ASSERT(ep->io_head != NULL); + + ep_num = ep_to_epnum(endpoint); + req = ep->io_head; + xfer_size = req->io_length; + max_dma_size_local = (ep_num ? max_dma_size : MAX_EP0_DMA_SIZE); + sent = req->return_count; + + print("ep_num: %d sent: %d io_len: %d \n", ep_num, sent, xfer_size); + + xfer_size = xfer_size - sent; + if(xfer_size > max_dma_size_local) { + xfer_size = max_dma_size_local; + } + + platform_cache_operation(CACHE_INVALIDATE | CACHE_CLEAN, (void *)(req->io_buffer + sent), xfer_size); + + write_reg(DWCUSB_DIEPDMA(ep_num), (uint32_t)req->io_buffer + sent); + + print("dma: %08x\n", read_reg(DWCUSB_DIEPDMA(ep_num))); + + if (xfer_size == 0) { + /* Zero Length Packet */ + pkt_cnt = 1; + } + else { + pkt_cnt = (xfer_size - 1 + ep->max_packet_size) / ep->max_packet_size; + if(pkt_cnt > max_packet_count) { + pkt_cnt = max_packet_count; + xfer_size = pkt_cnt * ep->max_packet_size; + } + } + + write_reg(DWCUSB_DIEPTSIZ(ep_num), (1 << DWCUSB_DEPTSIZ_MC_SHIFT) | + (pkt_cnt << DWCUSB_DEPTSIZ_PKTCNT_SHIFT) | + (xfer_size)); + + ep->transfer_size = xfer_size; + ep->packet_count = pkt_cnt; + + print("xfer_size:%d, pkt_cnt:%d\n", xfer_size, pkt_cnt); + + or_reg(DWCUSB_DIEPCTL(ep_num), DWCUSB_DEPCTL_EPENA | + DWCUSB_DEPCTL_CNAK); + + print("Finish start_endpoint_in(%d) \n", ep_num); +} + + +static int set_global_in_nak(void) +{ + int ret = 0; + + write_reg(DWCUSB_GINTSTS, DWCUSB_GINT_GINNAKEFF); + + or_reg(DWCUSB_DCTL, DWCUSB_DCTL_SGNPINNAK); + + utime_t start_time = system_time(); + while((read_reg(DWCUSB_GINTSTS) & DWCUSB_GINT_GINNAKEFF) == 0) { + if(time_has_elapsed(start_time, NAKEFF_TIMEOUT)) { + dprintf(DEBUG_INFO, "synopsys_otg::set_global_in_nak : GINNAKEFF taking longer than expected \n"); + ret = -1; + break; + } + } + + write_reg(DWCUSB_GINTSTS, DWCUSB_GINT_GINNAKEFF); + + return ret; +} + + +static void clear_global_in_nak(void) +{ + or_reg(DWCUSB_DCTL, DWCUSB_DCTL_CGNPINNAK); +} + + +static int flush_tx_fifo(int fifo) +{ + int ret = 0; + + set_bits_in_reg(DWCUSB_GRSTCTL, DWCUSB_GRSTCTL_TXFNUM_SHIFT, DWCUSB_GRSTCTL_TXFNUM_MASK, 0); + or_reg(DWCUSB_GRSTCTL, (fifo << DWCUSB_GRSTCTL_TXFNUM_SHIFT) | DWCUSB_GRSTCTL_TXFFLSH); + + utime_t start_time = system_time(); + while((read_reg(DWCUSB_GRSTCTL) & DWCUSB_GRSTCTL_TXFFLSH) != 0) { + if(time_has_elapsed(start_time, FIFOFLSH_TIMEOUT)) { + dprintf(DEBUG_INFO, "synopsys_otg::flush_tx_fifo : Flushing Fifo %d taking longer than expected \n", fifo); + ret = -1; + break; + } + } + + return ret; +} + + +static void synopsys_otg_disable_in_endpoint(u_int32_t endpoint) +{ + int ep_num = ep_to_epnum(endpoint); + struct usb_endpoint_instance *ep = &synopsys_otg_endpoints[ep_to_epindex(endpoint)]; + utime_t start_time; + int ret = 0; + u_int32_t pkt_cnt; + + print("starting ep %x disable \n", endpoint); + + if((read_reg(DWCUSB_DIEPCTL(ep_num)) & DWCUSB_DEPCTL_EPENA) == 0) { + print("endpoint %x already disabled \n", endpoint); + return; + } + + set_global_in_nak(); + + or_reg(DWCUSB_DIEPCTL(ep_num), DWCUSB_DEPCTL_SNAK); + start_time = system_time(); + while((read_reg(DWCUSB_DIEPINT(ep_num)) & DWCUSB_DIEPINT_IEPNAKEFF) == 0) { + if(time_has_elapsed(start_time, EPDISBLD_TIMEOUT)) { + dprintf(DEBUG_INFO, "synopsys_otg_disable_in_endpoint: NAKEFF not set in time for endpoint %x \n", endpoint); + ret = -1; + break; + } + } + + or_reg(DWCUSB_DIEPCTL(ep_num), DWCUSB_DEPCTL_EPDIS | DWCUSB_DEPCTL_SNAK); + start_time = system_time(); + while((read_reg(DWCUSB_DIEPINT(ep_num)) & DWCUSB_DIEPINT_EPDISBLD) == 0) { + if(time_has_elapsed(start_time, EPDISBLD_TIMEOUT)) { + dprintf(DEBUG_INFO, "synopsys_otg_disable_in_endpoint: endpoint %x not disabled in time \n", endpoint); + ret = -1; + break; + } + } + + if(ret == 0) { + pkt_cnt = 0; + + if(ep_num == 0) { + pkt_cnt = ((read_reg(DWCUSB_DIEPTSIZ(0)) & DWCUSB_DEP0TSIZ_PKTCNT_MASK) >> DWCUSB_DEPTSIZ_PKTCNT_SHIFT); + } + else { + pkt_cnt = ((read_reg(DWCUSB_DIEPTSIZ(ep_num)) & DWCUSB_DEPTSIZ_PKTCNT_MASK) >> DWCUSB_DEPTSIZ_PKTCNT_SHIFT); + } + + if(pkt_cnt == 0) { + ep->io_head->return_count += ep->transfer_size; + } + else { + ep->io_head->return_count += ((ep->packet_count - pkt_cnt) * ep->max_packet_size); + } + } + + flush_tx_fifo(ep->tx_fifo_number); + + clear_global_in_nak(); + + print("endpoint %x disabled \n", endpoint); +} + + +static int set_global_out_nak(void) +{ + int ret = 0; + + write_reg(DWCUSB_GINTSTS, DWCUSB_GINT_GOUTNAKEFF); + + or_reg(DWCUSB_DCTL, DWCUSB_DCTL_SGOUTNAK); + + utime_t start_time = system_time(); + while((read_reg(DWCUSB_GINTSTS) & DWCUSB_GINT_GOUTNAKEFF) == 0) { + if(time_has_elapsed(start_time, 1000)) { + dprintf(DEBUG_INFO, "%s: OUT NAK EFF not set in time \n", __FUNCTION__); + ret = -1; + break; + } + } + + write_reg(DWCUSB_GINTSTS, DWCUSB_GINT_GOUTNAKEFF); + + return ret; +} + + +static void clear_global_out_nak(void) +{ + or_reg(DWCUSB_DCTL, DWCUSB_DCTL_CGOUTNAK); +} + + +static void synopsys_otg_disable_out_endpoint(u_int32_t endpoint) +{ + int ep_num = ep_to_epnum(endpoint); + utime_t start_time; + + print("starting ep %x disable \n", endpoint); + + if((read_reg(DWCUSB_DOEPCTL(ep_num)) & DWCUSB_DEPCTL_EPENA) == 0) { + print("endpoint %x already disabled \n", endpoint); + return; + } + + set_global_out_nak(); + + or_reg(DWCUSB_DOEPCTL(ep_num), DWCUSB_DEPCTL_EPDIS | DWCUSB_DEPCTL_SNAK); + start_time = system_time(); + while((read_reg(DWCUSB_DOEPINT(ep_num)) & DWCUSB_DOEPINT_EPDISBLD) == 0) { + if(time_has_elapsed(start_time, EPDISBLD_TIMEOUT)) { + dprintf(DEBUG_INFO, "synopsys_otg_disable_out_endpoint: endpoint %x not disabled in time \n", endpoint); + break; + } + } + + clear_global_out_nak(); + + print("endpoint %x disabled \n", endpoint); +} + +static void synopsys_otg_int_handler(void *blah) +{ + uint32_t gintsts = read_reg(DWCUSB_GINTSTS); + write_reg(DWCUSB_GINTSTS, gintsts); + print("GINTSTS %08x \n", gintsts); + synopsys_otg_gintsts |= gintsts; + + if(gintsts & (DWCUSB_GINT_OEPINT | DWCUSB_GINT_IEPINT)) { + u_int32_t daint = read_reg(DWCUSB_DAINT); + synopsys_otg_daintsts |= daint; + + if(daint) { + u_int32_t out_daint = (daint & DWCUSB_DAINT_OEP_MASK) >> DWCUSB_DAINT_OEP_SHIFT; + u_int32_t in_daint = (daint & DWCUSB_DAINT_IEP_MASK); + + /* rest of endpoints */ + for(int i = 0; (in_daint || out_daint) && (i <= (MAX_EP_NUMBER)); i++, in_daint >>= 1, out_daint >>= 1) { + if(in_daint & EP_INT_MASK) { + synopsys_otg_handle_endpoint_in(USB_DIR_IN | i); + } + if(out_daint & EP_INT_MASK) { + synopsys_otg_handle_endpoint_out(i); + } + } + } + } + + if((gintsts & read_reg(DWCUSB_GINTMSK)) && !(usb_task_event_status & EVENT_TYPE_INTERRUPT)) + { + usb_task_event_status |= EVENT_TYPE_INTERRUPT; + event_signal(&usb_task_event); + } +} + +static void handle_interrupt() +{ + u_int32_t gintsts; + u_int32_t daint; + + enter_critical_section(); + gintsts = synopsys_otg_gintsts; + daint = synopsys_otg_daintsts; + synopsys_otg_gintsts = 0; + synopsys_otg_daintsts = 0; + usb_task_event_status &= ~EVENT_TYPE_INTERRUPT; + exit_critical_section(); + + print("GINTSTS %08x \n", gintsts); + + if (gintsts & DWCUSB_GINT_WKUPINT) { + print("WKUPINT \n"); + //handle_usb_resume(); + + } + if(gintsts & DWCUSB_GINT_USBSUSP) { + print("USBSUSP \n"); + //handle_usb_suspend(); + + // we get USBSUSP interrupt when cable is disconnected. + // we can use this information to notify stack and PMU driver + if(usbphy_is_cable_connected() == false) { + usb_core_event_handler(CABLE_DISCONNECTED); + synopsys_otg_start_controller(); + synopsys_otg_go_on_bus(); + } + } + if(gintsts & DWCUSB_GINT_USBRST) { + print("USBRST \n"); + usb_core_event_handler(USB_RESET); + synopsys_otg_handle_usb_reset(); + } + if(gintsts & DWCUSB_GINT_ENUMDONE) { + print("USBENUMDONE \n"); + synopsys_otg_handle_enum_done(); + } + + if(gintsts & (DWCUSB_GINT_OEPINT | DWCUSB_GINT_IEPINT)) { + print("DAINT %08x \n", daint); + + if(daint) { + u_int32_t out_daint = (daint & DWCUSB_DAINT_OEP_MASK) >> DWCUSB_DAINT_OEP_SHIFT; + u_int32_t in_daint = (daint & DWCUSB_DAINT_IEP_MASK); + int i; + + if(in_daint & EP_INT_MASK) { + scavenge_endpoint_finished_list(EP0_IN); + } + + if(out_daint & EP_INT_MASK) { + synopsys_otg_handle_ep0_out(); + } + + for(i = 1, in_daint >>= 1, out_daint >>= 1; (in_daint || out_daint) && (i <= (MAX_EP_NUMBER)); i++, in_daint >>= 1, out_daint >>= 1) { + if(in_daint & EP_INT_MASK) { + scavenge_endpoint_finished_list(USB_DIR_IN | i); + } + if(out_daint & EP_INT_MASK) { + scavenge_endpoint_finished_list(i); + } + } + } + } +} + +static void scavenge_endpoint_finished_list(u_int32_t endpoint) +{ + struct usb_endpoint_instance *ep; + struct usb_device_io_request *completed_list; + + ep = &synopsys_otg_endpoints[ep_to_epindex(endpoint)]; + + enter_critical_section(); + completed_list = ep->completion_head; + ep->completion_head = ep->completion_tail = NULL; + exit_critical_section(); + + // Call completion on all finished transactions + while(completed_list) { + struct usb_device_io_request *completed_req = completed_list; + completed_list = completed_req->next; + usb_core_complete_endpoint_io(completed_req); + } +} + +static void enqueue_finished_request(struct usb_endpoint_instance *ep, struct usb_device_io_request *io_req) +{ + ASSERT(ep != NULL); + ASSERT(io_req != NULL); + + io_req->next = NULL; + if(ep->completion_tail) { + ep->completion_tail->next = io_req; + ep->completion_tail = io_req; + } + else { + ep->completion_head = ep->completion_tail = io_req; + } +} + + +static int synopsys_otg_task(void *arg) +{ + for(;;) { + + event_wait(&usb_task_event); + + if(usb_task_event_status & EVENT_TYPE_INTERRUPT) + { + handle_interrupt(); // Invoke bottom half. + } + if(usb_task_event_status & EVENT_TYPE_EXIT) + { + event_signal(&usb_task_terminate_event); + break; + } + } + + return 0; +} + +static int synopsys_otg_init() +{ + usb_task_event_status = EVENT_TYPE_NONE; + event_init(&usb_task_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(&usb_task_terminate_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + task_start((controller_task = task_create("usb", &synopsys_otg_task, NULL, 0x1000))); + + return 0; +} + +static void synopsys_otg_free() +{ +} + +static int synopsys_otg_start(void) +{ + // power up the phy, this will enable OTG clock + usbphy_power_up(); + +#if (DEBUG == 2) + log_buffer = (u_int8_t *)calloc(1, log_buffer_len); + + dprintf(DEBUG_INFO, "USB logging buffer 0x%08x\n", log_buffer); + + writeptr = readptr = log_buffer; +#endif + + synopsys_otg_print_endpoints(); + + bzero(ep0_rx_buffer, EP0_MAX_PACKET_SIZE); + + bzero(synopsys_otg_endpoints, sizeof(struct usb_endpoint_instance) * MAX_EP_NEEDED); + + bzero(tx_fifo_list, MAX_TX_FIFO_SUPPORTED); + + synopsys_otg_start_controller(); + +#ifdef INT_USB_OTG + install_int_handler(INT_USB_OTG, synopsys_otg_int_handler, NULL); + unmask_int(INT_USB_OTG); +#else + // Add support for multiple USB OTG controllers to iBoot + if (USBOTG_BASE_ADDR == USBOTG0_BASE_ADDR) { + install_int_handler(INT_USB_OTG0, synopsys_otg_int_handler, NULL); + unmask_int(INT_USB_OTG0); + } else if (USBOTG_BASE_ADDR == USBOTG1_BASE_ADDR) { + install_int_handler(INT_USB_OTG1, synopsys_otg_int_handler, NULL); + unmask_int(INT_USB_OTG1); + } else { + panic("Invalid USBOTG base address"); + } +#endif + + // Go on bus so that the host can see this + synopsys_otg_go_on_bus(); + + return 0; +} + +static void synopsys_otg_stop(void) +{ + int i; + + // mask our interrupt +#ifdef INT_USB_OTG + mask_int(INT_USB_OTG); +#else + // Add support for multiple USB OTG controllers to iBoot + if (USBOTG_BASE_ADDR == USBOTG0_BASE_ADDR) { + mask_int(INT_USB_OTG0); + } else if (USBOTG_BASE_ADDR == USBOTG1_BASE_ADDR) { + mask_int(INT_USB_OTG1); + } else { + panic("Invalid USBOTG base address"); + } +#endif + + // Stop the controller task + enter_critical_section(); + usb_task_event_status |= EVENT_TYPE_EXIT; + exit_critical_section(); + event_signal(&usb_task_event); + + // Wait for the controller task to finish. But first ensure that we are not in the controller task already. + ASSERT(task_get_current_task() != controller_task); + event_wait(&usb_task_terminate_event); + + // Deactivate all endpoints so that new IOs are not accepted. + for(i = MAX_EP_NUMBER; i > 0; i-- ) { + usb_core_deactivate_endpoint(USB_DIR_IN | i); + usb_core_deactivate_endpoint(i); + } + usb_core_deactivate_endpoint(EP0_IN); + + // mask all the interrupts + write_reg(DWCUSB_GINTMSK, 0); + write_reg(DWCUSB_DOEPMSK, 0); + write_reg(DWCUSB_DIEPMSK, 0); + write_reg(DWCUSB_DAINTMSK, 0); + + // clear any pending interrupts + write_reg(DWCUSB_GINTSTS, 0xffffffff); + for(i = MAX_EP_NUMBER; i >= 0; i-- ) { + write_reg(DWCUSB_DIEPINT(i), 0x1f); + write_reg(DWCUSB_DOEPINT(i), 0xf); + } + + // Clear global interrupt status flags + synopsys_otg_gintsts = 0; + synopsys_otg_daintsts = 0; + + // Set Soft Disconnect bit + or_reg(DWCUSB_DCTL, DWCUSB_DCTL_SFTDISCON); + + // power down the phy, this will disable OTG clock + usbphy_power_down(); + + // uninstall interrupt handler + + // free allocated resources + task_wait_on(controller_task); + task_destroy(controller_task); + controller_task = NULL; + +#if (DEBUG == 2) + if(log_buffer) { + free(log_buffer); + log_buffer = NULL; + } +#endif +} + +static void synopsys_otg_go_on_bus(void) +{ + /* Enable D+ Pull up. */ + usbphy_enable_pullup(); + + // Reset Soft disconnect. Now the host can see the device. + and_reg(DWCUSB_DCTL, ~DWCUSB_DCTL_SFTDISCON); +} + +static void synopsys_otg_set_address(u_int32_t new_address) +{ + enter_critical_section(); + + new_address = (new_address & (DWCUSB_DCFG_DEVADDR_MASK >> DWCUSB_DCFG_DEVADDR_SHIFT)); + set_bits_in_reg(DWCUSB_DCFG, DWCUSB_DCFG_DEVADDR_SHIFT, DWCUSB_DCFG_DEVADDR_MASK, new_address); + + exit_critical_section(); + + print("new_address %d \n", new_address); +} + +static int synopsys_otg_get_connection_speed(void) +{ + int is_hs; + + enter_critical_section(); + is_hs = ((read_reg(DWCUSB_DSTS) & DWCUSB_DSTS_ENUMSPD_MASK) == DWCUSB_DSTS_ENUMSPD_HS); + exit_critical_section(); + + return (is_hs ? CONNECTION_SPEED_HIGH : CONNECTION_SPEED_FULL); +} + +static void synopsys_otg_do_test_mode(u_int32_t selector) +{ + enter_critical_section(); + selector = (selector & (DWCUSB_DCTL_TSTCTL_MASK >> DWCUSB_DCTL_TSTCTL_SHIFT)); + set_bits_in_reg(DWCUSB_DCTL, DWCUSB_DCTL_TSTCTL_SHIFT, DWCUSB_DCTL_TSTCTL_MASK, selector); + exit_critical_section(); +} + +static void synopsys_otg_activate_endpoint(u_int32_t endpoint, int type, int max_packet_size, int interval) +{ + print("ep %x , type %d, mps %d, interval %d \n", endpoint, type, max_packet_size, interval); + + u_int32_t ep_num = ep_to_epnum(endpoint); + u_int32_t ep_dir = ep_to_epdir(endpoint); + u_int32_t ep_idx = ep_to_epindex(endpoint); + addr_t ep_ctl_reg = 0; + u_int32_t ep_daint_msk_shift = 0; + u_int32_t val = 0; + int next_ep = 0; + struct usb_endpoint_instance *ep; + + ASSERT(ep_num <= MAX_EP_NUMBER); + ASSERT(ep_idx < MAX_EP_NEEDED); + + ep = &synopsys_otg_endpoints[ep_idx]; + ASSERT(ep != NULL); + + enter_critical_section(); + + // Check if this endpoint is already active + if(ep->is_active) { + exit_critical_section(); + return; + } + + ep->endpoint_address = endpoint; + ep->max_packet_size = max_packet_size; + ep->attributes = type; + ep->bInterval = interval; + ep->is_active = true; + + val = DWCUSB_DEPCTL_SETD0PID | DWCUSB_DEPCTL_SNAK; + + switch(type | ep_dir) + { + case USB_ENDPOINT_BULK | USB_DIR_IN : + case USB_ENDPOINT_INTERRUPT | USB_DIR_IN : + + ep_ctl_reg = DWCUSB_DIEPCTL(ep_num); + ep_daint_msk_shift = ep_num; + + write_reg(ep_ctl_reg, 0); + + u_int32_t txFifo_n = get_np_tx_fifo_size(); + int next_tx_fifo = get_next_tx_fifo_num(); + + print("ep_num %x, tx_fifo %d\n", ep_num, next_tx_fifo); + + val |= (next_tx_fifo << DWCUSB_DEPCTL_TXFNUM_SHIFT); + write_reg(DWCUSB_DPTXFSIZ(next_tx_fifo), + (txFifo_n << DWCUSB_DIEPTXF_INEPTXFDEP_SHIFT) | next_tx_fifo_start_addr); + ep->tx_fifo_number = next_tx_fifo; + next_tx_fifo_start_addr += txFifo_n; + break; + + case USB_ENDPOINT_BULK | USB_DIR_OUT : + case USB_ENDPOINT_INTERRUPT | USB_DIR_OUT : + ep_ctl_reg = DWCUSB_DOEPCTL(ep_num); + ep_daint_msk_shift = (DWCUSB_DAINT_OEP_SHIFT + ep_num); + write_reg(ep_ctl_reg, 0); + break; + + default: + dprintf(DEBUG_INFO, "synopsys_otg :: activate_endpoint --- trying to activate un-supported \n"); + goto exit; + } + + write_reg(ep_ctl_reg, val | + (type << DWCUSB_DEPCTL_EPTYPE_SHIFT) | + (next_ep << DWCUSB_DEPCTL_NEXTEP_SHIFT) | + DWCUSB_DEPCTL_USBACTEP | + max_packet_size); + + or_reg(DWCUSB_DAINTMSK, (1 << ep_daint_msk_shift)); + +exit: + exit_critical_section(); +} + +static void synopsys_otg_do_endpoint_io(struct usb_device_io_request *req) +{ + struct usb_endpoint_instance *ep; + u_int32_t epindex; + + print("endpoint %x \n", req->endpoint); + + enter_critical_section(); + + ASSERT(ep_to_epnum(req->endpoint) <= MAX_EP_NUMBER); + epindex = ep_to_epindex(req->endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &synopsys_otg_endpoints[epindex]; + ASSERT(ep != NULL); + + req->return_count = 0; + req->status = USB_IO_ERROR; + req->next = NULL; + + // Check validity of endpoint this IO has been submitted to + if(!ep->is_active) + { + print("endpint %x is invalid\n", req->endpoint); + usb_core_complete_endpoint_io(req); + goto exit; + } + + // pending IOs + if(ep->io_head) { + ep->io_tail->next = req; + ep->io_tail = req; + goto exit; + } + + // no Pending IOs + ep->io_head = ep->io_tail = req; + + // start transmitting/receiving the data + if(ep_to_epdir(req->endpoint)) { + synopsys_otg_start_endpoint_in(req->endpoint); + } + else { + synopsys_otg_start_endpoint_out(req->endpoint); + } + +exit: + exit_critical_section(); +} + +static void synopsys_otg_stall_endpoint(u_int32_t endpoint, bool stall) +{ + int ep_dir = ep_to_epdir(endpoint); + int ep_num = ep_to_epnum(endpoint); + + print("stall: %d ep: %x \n", stall, endpoint); + + enter_critical_section(); + + if(ep_num > MAX_EP_NUMBER) { + goto exit; + } + + if(stall) { + or_reg((ep_dir ? DWCUSB_DIEPCTL(ep_num) : DWCUSB_DOEPCTL(ep_num)), DWCUSB_DEPCTL_STALL); + } + else { + if(ep_num == 0) { + /* SC bit, core will clear this bit once a SETUP packet is rcvd */ + goto exit; + } + + and_reg((ep_dir ? DWCUSB_DIEPCTL(ep_num) : DWCUSB_DOEPCTL(ep_num)), ~(DWCUSB_DEPCTL_STALL)); + } + +exit: + exit_critical_section(); +} + +static void synopsys_otg_reset_endpoint_data_toggle(u_int32_t endpoint) +{ + int ep_dir = ep_to_epdir(endpoint); + int ep_num = ep_to_epnum(endpoint); + + print("ep:%02x\n", ep_num); + + enter_critical_section(); + + if(ep_num > MAX_EP_NUMBER) { + goto exit; + } + + or_reg((ep_dir ? DWCUSB_DIEPCTL(ep_num) : DWCUSB_DOEPCTL(ep_num)), DWCUSB_DEPCTL_SETD0PID); + +exit: + exit_critical_section(); +} + +static bool synopsys_otg_is_endpoint_stalled(u_int32_t endpoint) +{ + int ep_dir = ep_to_epdir(endpoint); + int ep_num = ep_to_epnum(endpoint); + bool ret; + + print("ep:%02x\n", ep_num); + + enter_critical_section(); + + if(ep_num > MAX_EP_NUMBER) { + ret = false; + goto exit; + } + + ret = ((read_reg((ep_dir ? DWCUSB_DIEPCTL(ep_num) : DWCUSB_DOEPCTL(ep_num))) & DWCUSB_DEPCTL_STALL) == DWCUSB_DEPCTL_STALL); + +exit: + exit_critical_section(); + + return ret; +} + +static void synopsys_otg_abort_endpoint(u_int32_t endpoint) +{ + struct usb_device_io_request *aborted_list; + struct usb_device_io_request *completed_list; + struct usb_endpoint_instance *ep; + u_int32_t epindex; + u_int32_t ep_num; + + print("endpoint %x \n", endpoint); + + enter_critical_section(); + + ep_num = ep_to_epnum(endpoint); + ASSERT(ep_num <= MAX_EP_NUMBER); + + epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + + ep = &synopsys_otg_endpoints[epindex]; + ASSERT(ep != NULL); + + // Check if this endpoint is valid + if(!ep->is_active) { + exit_critical_section(); + return; + } + + if(ep_to_epdir(endpoint)) { + synopsys_otg_disable_in_endpoint(endpoint); + + // Clear pending interrupts as we are going to abort all IOs + write_reg(DWCUSB_DIEPINT(ep_num), read_reg(DWCUSB_DIEPINT(ep_num))); + } + else { + synopsys_otg_disable_out_endpoint(endpoint); + + // Clear pending interrupts as we are going to abort all IOs + write_reg(DWCUSB_DOEPINT(ep_num), read_reg(DWCUSB_DOEPINT(ep_num))); + } + + ep->interrupt_status = 0; + ep->transfer_size = ep->packet_count = 0; + + completed_list = ep->completion_head; + ep->completion_head = ep->completion_tail = NULL; + + aborted_list = ep->io_head; + ep->io_head = ep->io_tail = NULL; + + exit_critical_section(); + + // First return all completed transactions + while(completed_list) { + struct usb_device_io_request *completed_req = completed_list; + completed_list = completed_req->next; + usb_core_complete_endpoint_io(completed_req); + } + + // Then return the aborted transactions + while(aborted_list) { + struct usb_device_io_request *aborted_req = aborted_list; + aborted_list = aborted_req->next; + aborted_req->status = USB_IO_ABORTED; + usb_core_complete_endpoint_io(aborted_req); + } +} + +static void synopsys_otg_deactivate_endpoint(u_int32_t endpoint) +{ + print("ep %x \n", endpoint); + + u_int32_t ep_num = ep_to_epnum(endpoint); + u_int32_t ep_dir = ep_to_epdir(endpoint); + addr_t ep_ctl_reg = 0; + u_int32_t ep_daint_msk_shift = 0; + addr_t ep_siz_reg = 0; + addr_t ep_int_reg = 0; + addr_t ep_dma_reg = 0; + struct usb_endpoint_instance *ep; + u_int32_t epindex; + + ASSERT(ep_num <= MAX_EP_NUMBER); + epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &synopsys_otg_endpoints[epindex]; + ASSERT(ep != NULL); + + enter_critical_section(); + + if(!ep->is_active) + { + print("endpint %x is invalid\n", endpoint); + goto exit; + } + + if(ep_dir) { + ep_ctl_reg = DWCUSB_DIEPCTL(ep_num); + ep_daint_msk_shift = ep_num; + ep_siz_reg = DWCUSB_DIEPTSIZ(ep_num); + ep_int_reg = DWCUSB_DIEPINT(ep_num); + ep_dma_reg = DWCUSB_DIEPDMA(ep_num); + } + else { + ep_ctl_reg = DWCUSB_DOEPCTL(ep_num); + ep_daint_msk_shift = (DWCUSB_DAINT_OEP_SHIFT + ep_num); + ep_siz_reg = DWCUSB_DOEPTSIZ(ep_num); + ep_int_reg = DWCUSB_DOEPINT(ep_num); + ep_dma_reg = DWCUSB_DOEPDMA(ep_num); + } + + write_reg(ep_ctl_reg, 0); + write_reg(ep_siz_reg, 0); + write_reg(ep_int_reg, 0x1ff); + write_reg(ep_dma_reg, 0); + and_reg(DWCUSB_DAINTMSK, ~(1 << ep_daint_msk_shift)); + + if(ep->tx_fifo_number) { + tx_fifo_list[ep->tx_fifo_number - 1] = 0; + } + + bzero(&synopsys_otg_endpoints[epindex], sizeof(struct usb_endpoint_instance)); + +exit: + exit_critical_section(); +} + +//=================================================================================== +// Global Functions +//=================================================================================== + +static const struct usb_controller_functions synopsys_otg_controller_functions = { + .init = synopsys_otg_init, + .free_func = synopsys_otg_free, + .start = synopsys_otg_start, + .stop = synopsys_otg_stop, + .set_address = synopsys_otg_set_address, + .get_connection_speed = synopsys_otg_get_connection_speed, + .activate_endpoint = synopsys_otg_activate_endpoint, + .do_endpoint_io = synopsys_otg_do_endpoint_io, + .stall_endpoint = synopsys_otg_stall_endpoint, + .reset_endpoint_data_toggle = synopsys_otg_reset_endpoint_data_toggle, + .is_endpoint_stalled = synopsys_otg_is_endpoint_stalled, + .do_test_mode = synopsys_otg_do_test_mode, + .abort_endpoint = synopsys_otg_abort_endpoint, + .deactivate_endpoint = synopsys_otg_deactivate_endpoint, +}; + +const struct usb_controller_functions *synopsys_otg_controller_init() +{ + return &synopsys_otg_controller_functions; +} diff --git a/drivers/synopsys/usbotg/synopsys_otg_regs.h b/drivers/synopsys/usbotg/synopsys_otg_regs.h new file mode 100644 index 0000000..d7c28e0 --- /dev/null +++ b/drivers/synopsys/usbotg/synopsys_otg_regs.h @@ -0,0 +1,779 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _USB_REGISTERS_H_ +#define _USB_REGISTERS_H_ + +#include + +#define USBREG(offset) (USBOTG_BASE_ADDR + (offset)) + +// Register definitions for the Synopsis DWC USB OTG core as +// implemented in the Samsung S5L8900X +// +// Constants were obtained from the header file "_s5l8701.h" +// supplied with the H1 diagnostics and may be subject to +// other licensing conditions. +// +// +// All registers are 32 bits wide. + +/******************************************************************************* + S5L8701 USB Core Global Registers + *******************************************************************************/ + +#define DWCUSB_GOTGCTL USBREG(0x00000000) /* OTG Control and Status Register */ +#define DWCUSB_GOTGINT USBREG(0x00000004) /* OTG Interrupt Register */ +#define DWCUSB_GAHBCFG USBREG(0x00000008) /* Core AHB Configuration Register */ +#define DWCUSB_GUSBCFG USBREG(0x0000000C) /* Core USB Configuration Register */ +#define DWCUSB_GRSTCTL USBREG(0x00000010) /* Core Reset Register */ +#define DWCUSB_GINTSTS USBREG(0x00000014) /* Core Interrupt Status Register */ +#define DWCUSB_GINTMSK USBREG(0x00000018) /* Core Interrupt Mask Register */ +#define DWCUSB_GRXSTSR USBREG(0x0000001C) /* Receive Status Debug Read Register */ +#define DWCUSB_GRXSTSP USBREG(0x00000020) /* Receive Status Read/Pop Register */ +#define DWCUSB_GRXFSIZ USBREG(0x00000024) /* Receive FIFO Size Register */ +#define DWCUSB_GNPTXFSIZ USBREG(0x00000028) /* Non-Periodic Transmit FIFO Size Register */ +#define DWCUSB_GNPTXSTS USBREG(0x0000002C) /* Non-Periodic Transmit FIFO/Queue Status Register */ +#define DWCUSB_GI2CCTL USBREG(0x00000030) /* I2C Access Register */ +#define DWCUSB_GPVNDCTL USBREG(0x00000034) /* PHY Vendor Control Register */ +#define DWCUSB_GGPIO USBREG(0x00000038) /* General Purpose I/O Register */ +#define DWCUSB_GUID USBREG(0x0000003C) /* User ID Register */ +#define DWCUSB_GSNPSID USBREG(0x00000040) /* Synopsys ID Register */ +#define DWCUSB_GHWCFG1 USBREG(0x00000044) /* User HW Config1 Register */ +#define DWCUSB_GHWCFG2 USBREG(0x00000048) /* User HW Config2 Register */ +#define DWCUSB_GHWCFG3 USBREG(0x0000004C) /* User HW Config3 Register */ +#define DWCUSB_GHWCFG4 USBREG(0x00000050) /* User HW Config4 Register */ +#define DWCUSB_HPTXFSIZ USBREG(0x00000100) /* Host Periodic Transmit FIFO Size Register */ +#define DWCUSB_DPTXFSIZ(_n) USBREG(0x00000104 + ((_n) - 1) * 4) /* Device Periodic Transmit FIFO Size Register */ +#define DWCUSB_DIEPTXF(_n) USBREG(0x00000104 + ((_n) - 1) * 4) /* Device IN EP Transmit FIFO Size Register */ + +/* OTG Control and Status Register Bit Definitions */ + +#define DWCUSB_GOTGCTL_BSESVLD 0x00080000 /* B-Session Valid */ +#define DWCUSB_GOTGCTL_ASESVLD 0x00040000 /* A-Session Valid */ +#define DWCUSB_GOTGCTL_DBNCTIME 0x00020000 /* Long/Short Debounce Time, 0:Long, 1:Short */ +#define DWCUSB_GOTGCTL_CONIDSTS_B 0x00010000 /* Connector ID Status, 0:A-Device, 1:B-Device */ +#define DWCUSB_GOTGCTL_DEVHNPEN 0x00000800 /* Device HNP Enabled */ +#define DWCUSB_GOTGCTL_HSTSETHNPEN 0x00000400 /* Host Set HNP Enable */ +#define DWCUSB_GOTGCTL_HNPREQ 0x00000200 /* HNP Request */ +#define DWCUSB_GOTGCTL_HSTNEGSCS 0x00000100 /* Host Negotiation Success */ +#define DWCUSB_GOTGCTL_SESREQ 0x00000002 /* Session Request */ +#define DWCUSB_GOTGCTL_SESREQSCS 0x00000001 /* Session Request Success */ + +/* OTG Interrupt Register Bit Definitions */ + +#define DWCUSB_GOTGINT_DBNCEDONE 0x00080000 /* Debounce Done */ +#define DWCUSB_GOTGINT_ADEVTOUTCHG 0x00040000 /* A-Device Timeout Change */ +#define DWCUSB_GOTGINT_HSTNEGDET 0x00020000 /* Host Negotiation Detected */ +#define DWCUSB_GOTGINT_HSTNEGSUCSTSCHG 0x00000200 /* Host Negotiation Success Status Change */ +#define DWCUSB_GOTGINT_SESREQSUCSTSCHG 0x00000100 /* Session Request Success Status Change */ +#define DWCUSB_GOTGINT_SESENDDET 0x00000004 /* Session End Detect */ + +/* Core AHB Configuration Register Bit Definitions */ + +#define DWCUSB_GAHBCFG_PTXFEMPLVL_HALF 0x00000000 /* Periodic TxFIFO Empty Level, Half Empty */ +#define DWCUSB_GAHBCFG_PTXFEMPLVL_FULL 0x00000100 /* Periodic TxFIFO Empty Level, Completely Empty */ +#define DWCUSB_GAHBCFG_NPTXFEMPLVL_HALF 0x00000000 /* Non-Periodic TxFIFO Empty Level, Half Empty */ +#define DWCUSB_GAHBCFG_NPTXFEMPLVL_FULL 0x00000080 /* Non-Periodic TxFIFO Empty Level, Completely Empty */ +#define DWCUSB_GAHBCFG_DMAEN 0x00000020 /* DMA Enable */ +#define DWCUSB_GAHBCFG_HBST_MASK 0x0000001E /* Burst Length/Type */ +#define DWCUSB_GAHBCFG_HBST_1 0x00000000 /* 1 word */ +#define DWCUSB_GAHBCFG_HBST_4 0x00000002 /* 4 words */ +#define DWCUSB_GAHBCFG_HBST_8 0x00000004 /* 8 words */ +#define DWCUSB_GAHBCFG_HBST_16 0x00000006 /* 16 words */ +#define DWCUSB_GAHBCFG_HBST_32 0x00000008 /* 32 words */ +#define DWCUSB_GAHBCFG_HBST_64 0x0000000A /* 64 words */ +#define DWCUSB_GAHBCFG_HBST_128 0x0000000C /* 128 words */ +#define DWCUSB_GAHBCFG_HBST_256 0x0000000E /* 256 words */ +#define DWCUSB_GAHBCFG_HBST_SINGLE 0x00000000 /* Single */ +#define DWCUSB_GAHBCFG_HBST_INCR 0x00000002 /* INCR */ +#define DWCUSB_GAHBCFG_HBST_INCR4 0x00000006 /* INCR4 */ +#define DWCUSB_GAHBCFG_HBST_INCR8 0x0000000A /* INCR8 */ +#define DWCUSB_GAHBCFG_HBST_INCR16 0x0000000E /* INCR16 */ +#define DWCUSB_GAHBCFG_GLBLINTRMSK 0x00000001 /* Global Interrupt Mask */ + +/* Core USB Configuration Register Bit Definitions */ + +#define DWCUSB_GUSBCFG_OTGI2CSEL 0x00010000 /* UTMIFS I2C Interface Select */ +#define DWCUSB_GUSBCFG_PHYLPWRCLKSEL 0x00008000 /* PHY Low-Power Clock Select */ +#define DWCUSB_GUSBCFG_USBTRDTIM_MASK 0x00003C00 /* USB Turnaround Time */ +#define DWCUSB_GUSBCFG_USBTRDTIM_SHIFT 10 +#define DWCUSB_GUSBCFG_HNPCAP 0x00000200 /* HNP-Capable */ +#define DWCUSB_GUSBCFG_SRPCAP 0x00000100 /* SRP-Capable */ +#define DWCUSB_GUSBCFG_ULPIIF_SDR 0x00000000 /* Single Data Rate ULPI Interface */ +#define DWCUSB_GUSBCFG_ULPIIF_DDR 0x00000080 /* Double Data Rate ULPI Interface */ +#define DWCUSB_GUSBCFG_PHYSEL_HS 0x00000000 /* USB 2.0 High-Speed UTMI+ or ULPI PHY */ +#define DWCUSB_GUSBCFG_PHYSEL_FS 0x00000040 /* USB 1.1 Full-Speed Serial Transceiver */ +#define DWCUSB_GUSBCFG_FSIF_UNI 0x00000000 /* Full-Speed Serial Interface Select, Unidirectional */ +#define DWCUSB_GUSBCFG_FSIF_BI 0x00000020 /* Full-Speed Serial Interface Select, Bidirectional */ +#define DWCUSB_GUSBCFG_UTMI 0x00000000 /* UTMI+ Interface */ +#define DWCUSB_GUSBCFG_ULPI 0x00000010 /* ULPI Interface */ +#define DWCUSB_GUSBCFG_PHYIF_8 0x00000000 /* PHY Interface, 8 bits */ +#define DWCUSB_GUSBCFG_PHYIF_16 0x00000008 /* PHY Interface, 16 bits */ +#define DWCUSB_GUSBCFG_TOUTCAL_MASK 0x00000007 /* HS/FS Timeout Calibration */ +#define DWCUSB_GUSBCFG_TOUTCAL_SHIFT 0 + +/* Core Reset Register Bit Definitions */ + +#define DWCUSB_GRSTCTL_AHBIDLE 0x80000000 /* AHB Master Idle */ +#define DWCUSB_GRSTCTL_DMAREQ 0x40000000 /* DMA Request Signal */ +#define DWCUSB_GRSTCTL_TXFNUM_MASK 0x000007C0 /* TxFIFO Number */ +#define DWCUSB_GRSTCTL_TXFNUM_SHIFT 6 +#define DWCUSB_GRSTCTL_TXFNUM_NP 0x00000000 /* Flush Non-Periodic TxFIFO */ +#define DWCUSB_GRSTCTL_TXFNUM_P(_n) ((_n) << 6) /* Flush Periodic TxFIFO 1 ~ 15 */ +#define DWCUSB_GRSTCTL_TXFNUM_ALL 0x00000400 /* Flush All TxFIFO */ +#define DWCUSB_GRSTCTL_TXFFLSH 0x00000020 /* TxFIFO Flush */ +#define DWCUSB_GRSTCTL_RXFFLSH 0x00000010 /* RxFIFO Flush */ +#define DWCUSB_GRSTCTL_INTKNQFLSH 0x00000008 /* IN TOken Sequence Learning Queue Flush */ +#define DWCUSB_GRSTCTL_FRMCNTRRST 0x00000004 /* Host Frame Counter Reset */ +#define DWCUSB_GRSTCTL_HSFTRST 0x00000002 /* HClk Soft Reset */ +#define DWCUSB_GRSTCTL_CSFTRST 0x00000001 /* Core Soft Reset */ + +/* Core Interrupt Status/Mask Register Bit Definitions */ + +#define DWCUSB_GINT_WKUPINT 0x80000000 /* Resume/Remote Wakeup Detected Interrupt */ +#define DWCUSB_GINT_SESSREQINT 0x40000000 /* Session Request/New Session Detected Interrupt */ +#define DWCUSB_GINT_DISCONNINT 0x20000000 /* Disconnect Detected Interrupt */ +#define DWCUSB_GINT_CONIDSTSCHG 0x10000000 /* Connector ID Status Change */ +#define DWCUSB_GINT_PTXFEMP 0x04000000 /* Periodic TxFIFO Empty */ +#define DWCUSB_GINT_HCHINT 0x02000000 /* Host Channels Interrupt */ +#define DWCUSB_GINT_PRTINT 0x01000000 /* Host Port Interrupt */ +#define DWCUSB_GINT_FETSUSP 0x00400000 /* Data Fetch Suspended */ +#define DWCUSB_GINT_INCOMPLP 0x00200000 /* Incomplete Periodic Transfer */ +#define DWCUSB_GINT_INCOMPLISOOUT 0x00200000 /* Incomplete Isochronous OUT Transfer */ +#define DWCUSB_GINT_INCOMPLISOIN 0x00100000 /* Incomplete Isochronous IN Transfer */ +#define DWCUSB_GINT_OEPINT 0x00080000 /* OUT Endpoints Interrupt */ +#define DWCUSB_GINT_IEPINT 0x00040000 /* IN Endpoints Interrupt */ +#define DWCUSB_GINT_EPMIS 0x00020000 /* Endpoint Mismatch Interrupt */ +#define DWCUSB_GINT_EOPF 0x00008000 /* End of Periodic Frame Interrupt */ +#define DWCUSB_GINT_ISOOUTDROP 0x00004000 /* Isochronous OUT Packet Dropped Interrupt */ +#define DWCUSB_GINT_ENUMDONE 0x00002000 /* Enumeration Done */ +#define DWCUSB_GINT_USBRST 0x00001000 /* USB Reset */ +#define DWCUSB_GINT_USBSUSP 0x00000800 /* USB Suspend */ +#define DWCUSB_GINT_ERLYSUSP 0x00000400 /* Early Suspend */ +#define DWCUSB_GINT_I2CINT 0x00000200 /* I2C Interrupt */ +#define DWCUSB_GINT_I2CCKINT 0x00000100 /* I2C CarKit Interrupt */ +#define DWCUSB_GINT_GOUTNAKEFF 0x00000080 /* Global OUT NAK Effective */ +#define DWCUSB_GINT_GINNAKEFF 0x00000040 /* Global IN NAK Effective */ +#define DWCUSB_GINT_NPTXFEMP 0x00000020 /* Non-Periodic TxFIFO Empty */ +#define DWCUSB_GINT_RXFLVL 0x00000010 /* RxFIFO Non-Empty */ +#define DWCUSB_GINT_SOF 0x00000008 /* Start of (Micro)Frame */ +#define DWCUSB_GINT_OTGINT 0x00000004 /* OTG Interrupt */ +#define DWCUSB_GINT_MODEMIS 0x00000002 /* Mode Mismatch Interrupt */ +#define DWCUSB_GINT_CURMOD_HOST 0x00000001 /* Current Mode of Operation, 0:Device, 1:Host */ + +#define DWCUSB_GINT_OTG_MASK 0x70000006 /* OTG Interrupt */ +#define DWCUSB_GINT_HOST_MASK 0x87200338 /* Device Interrupt */ +#define DWCUSB_GINT_DEVICE_MASK 0x807EFFF8 /* Host Interrupt */ + +/* Host Mode Receive Status Debug Read/Status Read and Pop Register Bit Definitions */ + +#define DWCUSB_HRXSTS_PKTSTS_MASK 0x001E0000 /* Packet Status */ +#define DWCUSB_HRXSTS_PKTSTS_INDATA 0x00040000 /* IN Data Packet Received */ +#define DWCUSB_HRXSTS_PKTSTS_IN 0x00060000 /* IN Transfer Completed */ +#define DWCUSB_HRXSTS_PKTSTS_DTERR 0x000A0000 /* Data Toggle Error */ +#define DWCUSB_HRXSTS_PKTSTS_CHHALT 0x000E0000 /* Channel Halted */ +#define DWCUSB_HRXSTS_DPID_MASK 0x00018000 /* Data PID */ +#define DWCUSB_HRXSTS_DPID_DATA0 0x00000000 /* DATA0 */ +#define DWCUSB_HRXSTS_DPID_DATA1 0x00008000 /* DATA1 */ +#define DWCUSB_HRXSTS_DPID_DATA2 0x00010000 /* DATA2 */ +#define DWCUSB_HRXSTS_DPID_DATAM 0x00018000 /* MDATA */ +#define DWCUSB_HRXSTS_BCNT_MASK 0x00007FF0 /* Byte Count */ +#define DWCUSB_HRXSTS_BCNT_SHIFT 4 +#define DWCUSB_HRXSTS_CHNUM_MASK 0x0000000F /* Channel Number */ + +/* Device Mode Receive Status Debug Read/Status Read and Pop Register Bit Definitions */ + +#define DWCUSB_DRXSTS_FN_MASK 0x01E00000 /* Frame Number */ +#define DWCUSB_DRXSTS_PKTSTS_MASK 0x001E0000 /* Packet Status */ +#define DWCUSB_DRXSTS_PKTSTS_GOUTNAK 0x00020000 /* Global OUT NAK */ +#define DWCUSB_DRXSTS_PKTSTS_OUTDATA 0x00040000 /* OUT Data Packet Received */ +#define DWCUSB_DRXSTS_PKTSTS_OUT 0x00060000 /* OUT Transfer Completed */ +#define DWCUSB_DRXSTS_PKTSTS_SETUP 0x00080000 /* SETUP Transaction Completed */ +#define DWCUSB_DRXSTS_PKTSTS_SETUPDATA 0x000C0000 /* SETUP Data Packet Received */ +#define DWCUSB_DRXSTS_DPID_MASK 0x00018000 /* Data PID */ +#define DWCUSB_DRXSTS_DPID_DATA0 0x00000000 /* DATA0 */ +#define DWCUSB_DRXSTS_DPID_DATA1 0x00008000 /* DATA1 */ +#define DWCUSB_DRXSTS_DPID_DATA2 0x00010000 /* DATA2 */ +#define DWCUSB_DRXSTS_DPID_DATAM 0x00018000 /* MDATA */ +#define DWCUSB_DRXSTS_BCNT_MASK 0x00007FF0 /* Byte Count */ +#define DWCUSB_DRXSTS_BCNT_SHIFT 4 +#define DWCUSB_DRXSTS_CHNUM_MASK 0x0000000F /* Channel Number */ + +/* Receive FIFO Size Register Bit Definitions */ + +#define DWCUSB_GRXFSIZ_RXFDEP_MASK 0x0000FFFF /* RxFIFO Depth, 16~32768 */ + +/* Non-Periodic Transmit FIFO Size Register Bit Definitions */ + +#define DWCUSB_GNPTXFSIZ_NPTXFDEP_MASK 0xFFFF0000 /* Non-Periodic TxFIFO Depth, 16~32768 */ +#define DWCUSB_GNPTXFSIZ_NPTXFDEP_SHIFT 16 +#define DWCUSB_GNPTXFSIZ_NPTXFSTADDR_MASK 0x0000FFFF /* Non-Periodic Transmit RAM Start Address */ +#define DWCUSB_GNPTXFSIZ_NPTXFSTADDR_SHIFT 0 + +/* Non-Periodic Transmit FIFO/Queue Status Register Bit Definitions */ + +#define DWCUSB_GNPTXSTS_NPTXQTOP_MASK 0x7F000000 /* Top of the Non-Periodic Transmit Request Queue */ +#define DWCUSB_GNPTXSTS_NPTXQTOP_SHIFT 24 +#define DWCUSB_GNPTXSTS_NPTXQAVAIL_MASK 0x00FF0000 /* Non-Periodic Transmit Request Queue Space Available */ +#define DWCUSB_GNPTXSTS_NPTXQAVAIL_SHIFT 16 +#define DWCUSB_GNPTXSTS_NPTXFAVAIL_MASK 0x0000FFFF /* Non-Periodic TxFIFO Space Available */ +#define DWCUSB_GNPTXSTS_NPTXFAVAIL_SHIFT 0 + +/* I2C Access Register Bit Definitions */ + +#define DWCUSB_GI2CCTL_BSYDONE 0x80000000 /* I2C Busy/Done */ +#define DWCUSB_GI2CCTL_READ 0x00000000 /* Read */ +#define DWCUSB_GI2CCTL_WRITE 0x40000000 /* Write */ +#define DWCUSB_GI2CCTL_VPVM 0x00000000 /* VP-VM USB Mode */ +#define DWCUSB_GI2CCTL_DATSE0 0x10000000 /* DAT_SE0 USB Mode */ +#define DWCUSB_GI2CCTL_DEVADDR_MASK 0x0C000000 /* I2C Device Address */ +#define DWCUSB_GI2CCTL_DEVADDR_2C 0x00000000 /* 2C */ +#define DWCUSB_GI2CCTL_DEVADDR_2D 0x04000000 /* 2D */ +#define DWCUSB_GI2CCTL_DEVADDR_2E 0x08000000 /* 2E */ +#define DWCUSB_GI2CCTL_DEVADDR_2F 0x0C000000 /* 2F */ +#define DWCUSB_GI2CCTL_SUSPCTL 0x02000000 /* I2C Suspend Control */ +#define DWCUSB_GI2CCTL_ACK 0x01000000 /* I2C ACK */ +#define DWCUSB_GI2CCTL_EN 0x00800000 /* I2C Enable */ +#define DWCUSB_GI2CCTL_ADDR_MASK 0x007F0000 /* I2C Address */ +#define DWCUSB_GI2CCTL_ADDR_SHIFT 16 +#define DWCUSB_GI2CCTL_REGADDR_MASK 0x0000FF00 /* I2C Register Address */ +#define DWCUSB_GI2CCTL_REGADDR_SHIFT 8 +#define DWCUSB_GI2CCTL_RWDATA_MASK 0x000000FF /* I2C Read/Write Data */ +#define DWCUSB_GI2CCTL_RWDATA_SHIFT 0 + +/* PHY Vendor Control Register Bit Definitions */ + +#define DWCUSB_GPVNDCTL_VSTSDONE 0x08000000 /* VStatus Done */ +#define DWCUSB_GPVNDCTL_VSTSBSY 0x04000000 /* VStatus Busy */ +#define DWCUSB_GPVNDCTL_NEWREGREQ 0x02000000 /* New Register Request */ +#define DWCUSB_GPVNDCTL_REGWR 0x00400000 /* Register Write */ +#define DWCUSB_GPVNDCTL_REGADDR_MASK 0x003F0000 /* Register Address */ +#define DWCUSB_GPVNDCTL_REGADDR_SHIFT 16 +#define DWCUSB_GPVNDCTL_VCTRL_MASK 0x0000FF00 /* UTMI+ Vendor Control Register Address */ +#define DWCUSB_GPVNDCTL_VCTRL_SHIFT 8 +#define DWCUSB_GPVNDCTL_REGDATA_MASK 0x000000FF /* Register Data */ +#define DWCUSB_GPVNDCTL_REGDATA_SHIFT 0 + +/* General Purpose I/O Register Bit Definitions */ + +#define DWCUSB_GGPIO_GPO_MASK 0xFFFF0000 /* General Purpose Output */ +#define DWCUSB_GGPIO_GPO_SHIFT 16 +#define DWCUSB_GGPIO_GPI_MASK 0x0000FFFF /* General Purpose Input */ +#define DWCUSB_GGPIO_GPI_SHIFT 0 + +/* User HW Config1 Register Bit Definitions */ + +#define DWCUSB_GHWCFG1_BIDIR 0x00000000 /* BIDIR Endpoint */ +#define DWCUSB_GHWCFG1_IN 0x00000001 /* IN Endpoint */ +#define DWCUSB_GHWCFG1_OUT 0x00000002 /* OUT Endpoint */ +#define DWCUSB_GHWCFG1_EP_MASK 0x00000003 +#define DWCUSB_GHWCFG1_EP_SHIFT 2 + +/* User HW Config2 Register Bit Definitions */ + +#define DWCUSB_GHWCFG2_TKNQDEPTH_MASK 0x3C000000 /* Device Mode IN Token Sequence Learning Queue Depth, 0~30 */ +#define DWCUSB_GHWCFG2_TKNQDEPTH_SHIFT 26 +#define DWCUSB_GHWCFG2_PTXQDEPTH_MASK 0x03000000 /* Host Mode Periodic Request Queue Depth */ +#define DWCUSB_GHWCFG2_PTXQDEPTH_2 0x00000000 +#define DWCUSB_GHWCFG2_PTXQDEPTH_4 0x01000000 +#define DWCUSB_GHWCFG2_PTXQDEPTH_8 0x02000000 +#define DWCUSB_GHWCFG2_NPTXQDEPTH_MASK 0x00C00000 /* Non-Periodic Request Queue Depth */ +#define DWCUSB_GHWCFG2_NPTXQDEPTH_2 0x00000000 +#define DWCUSB_GHWCFG2_NPTXQDEPTH_4 0x00400000 +#define DWCUSB_GHWCFG2_NPTXQDEPTH_8 0x00800000 +#define DWCUSB_GHWCFG2_DYNFIFOSIZING 0x00080000 /* Dynamic FIFO Sizing Enabled */ +#define DWCUSB_GHWCFG2_POUTSUPPORT 0x00040000 /* Periodic OUT Channels Supported in Host Mode */ +#define DWCUSB_GHWCFG2_NUMHSTCHNL_MASK 0x0003C000 /* Number of Host Channels, 0~15 */ +#define DWCUSB_GHWCFG2_NUMHSTCHNL_SHIFT 14 +#define DWCUSB_GHWCFG2_NUMDEVEPS_MASK 0x00003C00 /* Number of Device Endpoints, 0~15 */ +#define DWCUSB_GHWCFG2_NUMDEVEPS_SHIFT 10 +#define DWCUSB_GHWCFG2_FSPHYTYPE_MASK 0x00000300 /* Full-Speed PHY Interface Type */ +#define DWCUSB_GHWCFG2_FSPHYTYPE_NOFS 0x00000000 /* Full-Speed Interface Not supported */ +#define DWCUSB_GHWCFG2_FSPHYTYPE_FS 0x00000100 /* Dedicated Full-Speed Interface */ +#define DWCUSB_GHWCFG2_FSPHYTYPE_UTMI 0x00000200 /* FS Pins Share with UTMI+ Pins */ +#define DWCUSB_GHWCFG2_FSPHYTYPE_ULPI 0x00000300 /* FS Pins Share with ULPI Pins */ +#define DWCUSB_GHWCFG2_HSPHYTYPE_MASK 0x000000C0 /* High-Speed PHY Interface Type */ +#define DWCUSB_GHWCFG2_HSPHYTYPE_NOHS 0x00000000 /* High-Speed Interface Not supported */ +#define DWCUSB_GHWCFG2_HSPHYTYPE_UTMI 0x00000040 /* UTMI+ */ +#define DWCUSB_GHWCFG2_HSPHYTYPE_ULPI 0x00000080 /* ULPI */ +#define DWCUSB_GHWCFG2_HSPHYTYPE_ANY 0x000000C0 /* UTMI+ and ULPI */ +#define DWCUSB_GHWCFG2_MULTIPOINT 0x00000000 /* Multi-Point */ +#define DWCUSB_GHWCFG2_SINGLEPOINT 0x00000020 /* Single-Point */ +#define DWCUSB_GHWCFG2_ARCH_MASK 0x00000018 /* Architecture */ +#define DWCUSB_GHWCFG2_ARCH_SLAVE 0x00000000 /* Slave-Only */ +#define DWCUSB_GHWCFG2_ARCH_EXTDMA 0x00000008 /* External DMA */ +#define DWCUSB_GHWCFG2_ARCH_INTDMA 0x00000010 /* Internal DMA */ +#define DWCUSB_GHWCFG2_MODE_MASK 0x00000007 /* Mode of Operation */ +#define DWCUSB_GHWCFG2_MODE_FULLOTG 0x00000000 /* HNP & SRP Capable OTG */ +#define DWCUSB_GHWCFG2_MODE_SRPOTG 0x00000001 /* SRP Capable OTG */ +#define DWCUSB_GHWCFG2_MODE_MINOTG 0x00000002 /* Non-HNP & Non-SRP Capable OTG */ +#define DWCUSB_GHWCFG2_MODE_SRPDEV 0x00000003 /* SRP Capable Device */ +#define DWCUSB_GHWCFG2_MODE_DEV 0x00000004 /* Non-OTG Device */ +#define DWCUSB_GHWCFG2_MODE_SRPHST 0x00000005 /* SRP Capable Host */ +#define DWCUSB_GHWCFG2_MODE_HOST 0x00000006 /* Non-OTG Host */ + +/* User HW Config3 Register Bit Definitions */ + +#define DWCUSB_GHWCFG3_DFIFODEPTH_MASK 0xFFFF0000 /* DFIFO Depth, 32~32768 */ +#define DWCUSB_GHWCFG3_DFIFODEPTH_SHIFT 16 +#define DWCUSB_GHWCFG3_AHBPHYSYNC 0x00001000 /* AHB and PHY Synchronous */ +#define DWCUSB_GHWCFG3_RSTTYPE_ASYNC 0x00000000 /* Asynchronous Reset */ +#define DWCUSB_GHWCFG3_RSTTYPE_SYNC 0x00000800 /* Synchronous Reset */ +#define DWCUSB_GHWCFG3_OPTFEATURE 0x00000400 /* Optional Features Removed */ +#define DWCUSB_GHWCFG3_VCTRLIF 0x00000200 /* Vendor Control Interface is Available */ +#define DWCUSB_GHWCFG3_I2CIF 0x00000100 /* I2C Interface is Available */ +#define DWCUSB_GHWCFG3_OTGEN 0x00000080 /* OTG Function Enabled */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_MASK 0x00000070 /* Width of Packet Size Counters */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_SHIFT 4 +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_4 0x00000000 /* 4 bits */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_5 0x00000010 /* 5 bits */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_6 0x00000020 /* 6 bits */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_7 0x00000030 /* 7 bits */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_8 0x00000040 /* 8 bits */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_9 0x00000050 /* 9 bits */ +#define DWCUSB_GHWCFG3_PKTSIZEWIDTH_10 0x00000060 /* 10 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_MASK 0x0000000F /* Width of Transfer Size Counters */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_11 0x00000000 /* 11 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_12 0x00000001 /* 12 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_13 0x00000002 /* 13 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_14 0x00000003 /* 14 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_15 0x00000004 /* 15 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_16 0x00000005 /* 16 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_17 0x00000006 /* 17 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_18 0x00000007 /* 18 bits */ +#define DWCUSB_GHWCFG3_XFERSIZEWIDTH_19 0x00000008 /* 19 bits */ + +/* User HW Config4 Register Bit Definitions */ + +#define DWCUSB_GHWCFG4_DEDFIFOMODE 0x02000000 /* Dedicated FIFO Enabled */ +#define DWCUSB_GHWCFG4_SESSENDFLTR 0x01000000 /* "session_end" Filter Enabled */ +#define DWCUSB_GHWCFG4_BVALIDFLTR 0x00800000 /* "b_valid" Filter Enabled */ +#define DWCUSB_GHWCFG4_AVALIDFLTR 0x00400000 /* "a_valid" Filter Enabled */ +#define DWCUSB_GHWCFG4_VBUSVALIDFLTR 0x00200000 /* "vbus_valid" Filter Enabled */ +#define DWCUSB_GHWCFG4_IDDGFLTR 0x00100000 /* "iddig" Filter Enabled */ +#define DWCUSB_GHWCFG4_NUMCTLEPS_MASK 0x000F0000 /* Number of Device Mode Control Endpoints in Addition to Endpoint 0, 0~15 */ +#define DWCUSB_GHWCFG4_NUMCTLEPS_SHIFT 16 +#define DWCUSB_GHWCFG4_HSPHYDWIDTH_MASK 0x0000C000 /* HS PHY Data Width */ +#define DWCUSB_GHWCFG4_HSPHYDWIDTH_8 0x00000000 /* 8 bits */ +#define DWCUSB_GHWCFG4_HSPHYDWIDTH_16 0x00004000 /* 16 bits */ +#define DWCUSB_GHWCFG4_HSPHYDWIDTH_8_16 0x00008000 /* 8/16 bits, S/W Selectable */ +#define DWCUSB_GHWCFG4_AHBFREQ 0x00000020 /* Minimum AHB Frequency Less Than 60 MHz */ +#define DWCUSB_GHWCFG4_ENABLEPWROPT 0x00000010 /* Enable Power Optimization */ +#define DWCUSB_GHWCFG4_NUMDEVPIEPS_MASK 0x0000000F /* Number of Device Mode Periodic IN Endpoints */ +#define DWCUSB_GHWCFG4_NUMDEVPIEPS_SHIFT 0 + +/* Host Periodic Transmit FIFO Size Register Bit Definitions */ + +#define DWCUSB_HPTXFSIZ_PTXFDEP_MASK 0xFFFF0000 /* Host Periodic TxFIFO Depth, 16~32768 */ +#define DWCUSB_HPTXFSIZ_PTXFDEP_SHIFT 16 +#define DWCUSB_HPTXFSIZ_PTXFSTADDR_MASK 0x0000FFFF /* Host Periodic TxFIFO Start Address */ +#define DWCUSB_HPTXFSIZ_PTXFSTADDR_SHIFT 0 + +/* Device Periodic Transmit FIFO Size Register Bit Definitions */ + +#define DWCUSB_DPTXFSIZ_PTXFDEP_MASK 0xFFFF0000 /* Host Periodic TxFIFO Depth, 4~768 */ +#define DWCUSB_DPTXFSIZ_PTXFDEP_SHIFT 16 +#define DWCUSB_DPTXFSIZ_PTXFSTADDR_MASK 0x0000FFFF /* Host Periodic TxFIFO Start Address */ +#define DWCUSB_DPTXFSIZ_PTXFSTADDR_SHIFT 0 + +/* Device IN EP Transmit FIFO Size Register Bit Definitions */ + +#define DWCUSB_DIEPTXF_INEPTXFDEP_MASK 0xFFFF0000 /* Host Periodic TxFIFO Depth, 4~768 */ +#define DWCUSB_DIEPTXF_INEPTXFDEP_SHIFT 16 +#define DWCUSB_DIEPTXF_INEPTXFSTADDR_MASK 0x0000FFFF /* Host Periodic TxFIFO Start Address */ +#define DWCUSB_DIEPTXF_INEPTXFSTADDR_SHIFT 0 + +/******************************************************************************* + S5L8701 USB Core Host Registers + *******************************************************************************/ + +#define DWCUSB_HCFG USBREG(0x00000400) /* Host Configuration Register */ +#define DWCUSB_HFIR USBREG(0x00000404) /* Host Frame Interval Register */ +#define DWCUSB_HNUM USBREG(0x00000408) /* Host Frame Number/Time Remaining Register */ +#define DWCUSB_HPTXSTS USBREG(0x00000410) /* Host Periodic Transmit FIFO/Queue Status Register */ +#define DWCUSB_HAINT USBREG(0x00000414) /* Host All Channels Interrupt Register */ +#define DWCUSB_HAINTMSK USBREG(0x00000418) /* Host All Channels Interrupt Mask Register */ +#define DWCUSB_HPRT USBREG(0x00000440) /* Host Port Control and Status Register */ +#define DWCUSB_HCCHAR(_n) USBREG(0x00000500 + (_n) * 0x20) /* Host Channel Characteristics Register */ +#define DWCUSB_HCSPLT(_n) USBREG(0x00000504 + (_n) * 0x20) /* Host Channel Split Control Register */ +#define DWCUSB_HCINT(_n) USBREG(0x00000508 + (_n) * 0x20) /* Host Channel Interrupt Status Register */ +#define DWCUSB_HCINTMSK(_n) USBREG(0x0000050C + (_n) * 0x20) /* Host Channel Interrupt Mask Register */ +#define DWCUSB_HCTSIZ(_n) USBREG(0x00000510 + (_n) * 0x20) /* Host Channel Transfer Size Register */ +#define DWCUSB_HCDMA(_n) USBREG(0x00000514 + (_n) * 0x20) /* Host Channel DMA Address Register */ + +/* Host Configuration Register Bit Definitions */ + +#define DWCUSB_HCFG_HSFSLSSUPP 0x00000000 /* HS/FS/LS Support */ +#define DWCUSB_HCFG_FSLSSUPP 0x00000004 /* FS/LS Only Support */ +#define DWCUSB_HCFG_FSPCLKSEL_MASK 0x00000003 /* FS PHY Clock */ +#define DWCUSB_HCFG_FSPCLKSEL_30_60 0x00000000 /* FS PHY Clock is 30/60 MHz */ +#define DWCUSB_HCFG_FSPCLKSEL_48 0x00000001 /* FS PHY Clock is 48 MHz */ +#define DWCUSB_HCFG_LSPCLKSEL_MASK 0x00000003 /* LS PHY Clock */ +#define DWCUSB_HCFG_LSPCLKSEL_30_60 0x00000000 /* LS PHY Clock is 30/60 MHz */ +#define DWCUSB_HCFG_LSPCLKSEL_48 0x00000001 /* LS PHY Clock is 48 MHz */ +#define DWCUSB_HCFG_LSPCLKSEL_6 0x00000002 /* LS PHY Clock is 48 MHz */ + +/* Host Frame Interval Register Bit Definitions */ + +#define DWCUSB_HFIR_FRINT_MASK 0x0000FFFF /* Frame Interval */ + +/* Host Frame Number/Time Remaining Register Bit Definitions */ + +#define DWCUSB_HNUM_FRREM_MASK 0xFFFF0000 /* Frame Interval */ +#define DWCUSB_HNUM_FRREM_SHIFT 16 +#define DWCUSB_HNUM_FRNUM_MASK 0x0000FFFF /* Frame Number */ +#define DWCUSB_HNUM_FRNUM_SHIFT 0 + +/* Host Periodic Transmit FIFO/Queue Status Register Bit Definitions */ + +#define DWCUSB_HPTXSTS_PTXQTOP_ODDFRM 0x80000000 /* Send in Odd (Micro)Frame */ +#define DWCUSB_HPTXSTS_PTXQTOP_EPNUM_MASK 0x78000000 /* Channel/Endpoint Number */ +#define DWCUSB_HPTXSTS_PTXQTOP_EPNUM_SHIFT 27 +#define DWCUSB_HPTXSTS_PTXQTOP_TYPE_MASK 0x06000000 +#define DWCUSB_HPTXSTS_PTXQTOP_INOUT 0x00000000 /* IN/OUT */ +#define DWCUSB_HPTXSTS_PTXQTOP_ZLENPKT 0x02000000 /* Zero Length Pzcket */ +#define DWCUSB_HPTXSTS_PTXQTOP_CSPLIT 0x04000000 /* CSPLIT */ +#define DWCUSB_HPTXSTS_PTXQTOP_DISCHCMD 0x06000000 /* Disable Channel Command */ +#define DWCUSB_HPTXSTS_PTXQSPCAVAIL_MASK 0x00FF0000 /* Periodic Transmit Request Queue Space Available */ +#define DWCUSB_HPTXSTS_PTXQSPCAVAIL_SHIFT 16 +#define DWCUSB_HPTXSTS_PTXFSPCAVAIL_MASK 0x0000FFFF /* Periodic Transmit Data FIFO Space Available */ +#define DWCUSB_HPTXSTS_PTXFSPCAVAIL_SHIFT 0 + +/* Host Port Control and Status Register Bit Definitions */ + +#define DWCUSB_HPRT_PRTSPD_MASK 0x00060000 /* Port Speed */ +#define DWCUSB_HPRT_PRTSPD_HS 0x00000000 /* HS */ +#define DWCUSB_HPRT_PRTSPD_FS 0x00020000 /* FS */ +#define DWCUSB_HPRT_PRTSPD_LS 0x00040000 /* LS */ +#define DWCUSB_HPRT_PRTTSTCTL_MASK 0x0001E000 /* Port Test Control */ +#define DWCUSB_DCTL_TSTCTL_SHIFT 4 +#define DWCUSB_HPRT_PRTTSTCTL_NOTEST 0x00000000 /* Test Mode Disabled */ +#define DWCUSB_HPRT_PRTTSTCTL_TJ 0x00000000 /* Test_J Mode */ +#define DWCUSB_HPRT_PRTTSTCTL_TK 0x00000000 /* Test_K Mode */ +#define DWCUSB_HPRT_PRTTSTCTL_TSN 0x00000000 /* Test_SE0_NAK Mode */ +#define DWCUSB_HPRT_PRTTSTCTL_TP 0x00000000 /* Test_Packet Mode */ +#define DWCUSB_HPRT_PRTTSTCTL_TEN 0x00000000 /* Test_Force_Enable */ +#define DWCUSB_HPRT_PRTPWR 0x00001000 /* Port Power, 0:OFF, 1:ON */ +#define DWCUSB_HPRT_PRTLNSTS_MASK 0x00000C00 /* Port Line Status */ +#define DWCUSB_HPRT_PRTLNSTS_DM 0x00000800 /* D- */ +#define DWCUSB_HPRT_PRTLNSTS_DP 0x00000C00 /* D+ */ +#define DWCUSB_HPRT_PRTRST 0x00000100 /* Port Reset */ +#define DWCUSB_HPRT_PRTSUSP 0x00000080 /* Port Suspend */ +#define DWCUSB_HPRT_PRTRES 0x00000040 /* Port Resume */ +#define DWCUSB_HPRT_PRTOVRCURRCHG 0x00000020 /* Port Overcurrent Change */ +#define DWCUSB_HPRT_PRTOVRCURRACT 0x00000010 /* Port Overcurrent Active */ +#define DWCUSB_HPRT_PRTENCHG 0x00000008 /* Port Enable/Disable Change */ +#define DWCUSB_HPRT_PRTEN 0x00000004 /* Port Enable */ +#define DWCUSB_HPRT_PRTCONNDET 0x00000002 /* Port Connect Detected */ +#define DWCUSB_HPRT_PRTCONNSTS 0x00000001 /* Port Connect Status, 0:Detach, 1:Attach */ + +/* Host Channel Characteristics Register Bit Definitions */ + +#define DWCUSB_HCCHAR_CHENA 0x80000000 /* Channel Enable */ +#define DWCUSB_HCCHAR_CHDIS 0x40000000 /* Channel Disable */ +#define DWCUSB_HCCHAR_ODDFRM 0x20000000 /* Odd Frame */ +#define DWCUSB_HCCHAR_DEVADDR_MASK 0x1FC00000 /* Device Address */ +#define DWCUSB_HCCHAR_DEVADDR_SHIFT 22 +#define DWCUSB_HCCHAR_MC_EC_MASK 0x00300000 /* Multi Count / Error Count */ +#define DWCUSB_HCCHAR_MC_EC_SHIFT 20 +#define DWCUSB_HCCHAR_EPTYPE_MASK 0x000C0000 /* Endpoint Type */ +#define DWCUSB_HCCHAR_EPTYPE_CTL 0x00000000 /* Control */ +#define DWCUSB_HCCHAR_EPTYPE_ISO 0x00040000 /* Isochronous */ +#define DWCUSB_HCCHAR_EPTYPE_BULK 0x00080000 /* Bulk */ +#define DWCUSB_HCCHAR_EPTYPE_INT 0x000C0000 /* Interrupt */ +#define DWCUSB_HCCHAR_LSPDDEV 0x00020000 /* Low Speed Device */ +#define DWCUSB_HCCHAR_EPDIR_OUT 0x00000000 /* Endpoint Direction, OUT */ +#define DWCUSB_HCCHAR_EPDIR_IN 0x00008000 /* Endpoint Direction, IN */ +#define DWCUSB_HCCHAR_EPNUM_MASK 0x00007800 /* Endpoint Number */ +#define DWCUSB_HCCHAR_EPNUM_SHIFT 11 +#define DWCUSB_HCCHAR_MPS_MASK 0x000007FF /* Maximum Packet Size */ + +/* Host Channel Split Control Register Bit Definitions */ + +#define DWCUSB_HCSPLT_SPLTENA 0x80000000 /* Split Enable */ +#define DWCUSB_HCSPLT_COMPSPLT 0x00010000 /* Do Complete Split */ +#define DWCUSB_HCSPLT_XACTPOS_MASK 0x0000C000 /* Transaction Position */ +#define DWCUSB_HCSPLT_XACTPOS_ALL 0x0000C000 /* All */ +#define DWCUSB_HCSPLT_XACTPOS_BEGIN 0x00008000 /* Begin */ +#define DWCUSB_HCSPLT_XACTPOS_MID 0x00000000 /* Middle */ +#define DWCUSB_HCSPLT_XACTPOS_END 0x00004000 /* End */ +#define DWCUSB_HCSPLT_HUBADDR_MASK 0x00003F80 /* Hub Address */ +#define DWCUSB_HCSPLT_HUBADDR_SHIFT 7 +#define DWCUSB_HCSPLT_PRTADDR_MASK 0x0000007F /* Port Address */ +#define DWCUSB_HCSPLT_PRTADDR_SHIFT 0 + +/* Host Channel Interrupt Status/Mask Register Bit Definitions */ + +#define DWCUSB_HCINT_DATATGLERR 0x00000400 /* Data Toggle Error */ +#define DWCUSB_HCINT_FRMOVRUN 0x00000200 /* Frame Overrun */ +#define DWCUSB_HCINT_BBLERR 0x00000100 /* Babble Error */ +#define DWCUSB_HCINT_XACTERR 0x00000080 /* Transction Error */ +#define DWCUSB_HCINT_NYET 0x00000040 /* NYET Response Received */ +#define DWCUSB_HCINT_ACK 0x00000020 /* ACK Response Received */ +#define DWCUSB_HCINT_NAK 0x00000010 /* NAK Response Received */ +#define DWCUSB_HCINT_STALL 0x00000008 /* STALL Response Received */ +#define DWCUSB_HCINT_AHBERROR 0x00000004 /* AHB Error */ +#define DWCUSB_HCINT_CHHLTD 0x00000002 /* Channel Halted */ +#define DWCUSB_HCINT_XFERCOMPL 0x00000001 /* Transfer Completed */ + +/* Host Channel Transfer Size Register Bit Definitions */ + +#define DWCUSB_HCTSIZ_DOPNG 0x80000000 /* Do Ping */ +#define DWCUSB_HCTSIZ_PID_MASK 0x60000000 /* PID */ +#define DWCUSB_HCTSIZ_PID_DATA0 0x00000000 /* DATA0 */ +#define DWCUSB_HCTSIZ_PID_DATA1 0x20000000 /* DATA1 */ +#define DWCUSB_HCTSIZ_PID_DATA2 0x40000000 /* DATA2 */ +#define DWCUSB_HCTSIZ_PID_MDATA 0x60000000 /* MDATA/SETUP */ +#define DWCUSB_HCTSIZ_PKTCNT_MASK 0x1FF80000 /* Packet Count */ +#define DWCUSB_HCTSIZ_PKTCNT_SHIFT 19 +#define DWCUSB_HCTSIZ_XFERSIZE_MASK 0x0007FFFF /* Transfer Size */ +#define DWCUSB_HCTSIZ_XFERSIZE_SHIFT 0 + + +/******************************************************************************* + S5L8701 USB Core Device Registers + *******************************************************************************/ + +#define DWCUSB_DCFG USBREG(0x00000800) /* Device Configuration Register */ +#define DWCUSB_DCTL USBREG(0x00000804) /* Device Control Register */ +#define DWCUSB_DSTS USBREG(0x00000808) /* Device Status Register */ +#define DWCUSB_DIEPMSK USBREG(0x00000810) /* Device IN Endpoint Common Interrupt Mask Register */ +#define DWCUSB_DOEPMSK USBREG(0x00000814) /* Device OUT Endpoint Common Interrupt Masl Register */ +#define DWCUSB_DAINT USBREG(0x00000818) /* Device All Endpoint Common Interrupt Register */ +#define DWCUSB_DAINTMSK USBREG(0x0000081C) /* Device All Endpoint Common Interrupt Mask Register */ +#define DWCUSB_DTKNQR1 USBREG(0x00000820) /* Device IN Token Sequence Learning Queue Read Register 1 */ +#define DWCUSB_DTKNQR2 USBREG(0x00000824) /* Device IN Token Sequence Learning Queue Read Register 2 */ +#define DWCUSB_DTKNQR3 USBREG(0x00000830) /* Device IN Token Sequence Learning Queue Read Register 3 */ +#define DWCUSB_DTKNQR4 USBREG(0x00000834) /* Device IN Token Sequence Learning Queue Read Register 4 */ +#define DWCUSB_DVBUSDIS USBREG(0x00000828) /* Device VBUS Discharge Time Register */ +#define DWCUSB_DVBUSPULSE USBREG(0x0000082C) /* Device VBUS Pulsing Time Register */ +#define DWCUSB_DIEPCTL(_n) USBREG(0x00000900 + (_n) * 0x20) /* Device IN Endpoint Control Register */ +#define DWCUSB_DIEPINT(_n) USBREG(0x00000908 + (_n) * 0x20) /* Device IN Endpoint Interrupt Register */ +#define DWCUSB_DIEPTSIZ(_n) USBREG(0x00000910 + (_n) * 0x20) /* Device IN Endpoint Transfer Size Register */ +#define DWCUSB_DIEPDMA(_n) USBREG(0x00000914 + (_n) * 0x20) /* Device IN Endpoint DMA Address Register */ +#define DWCUSB_DOEPCTL(_n) USBREG(0x00000B00 + (_n) * 0x20) /* Device OUT Endpoint Control Register */ +#define DWCUSB_DOEPINT(_n) USBREG(0x00000B08 + (_n) * 0x20) /* Device OUT Endpoint Interrupt Register */ +#define DWCUSB_DOEPTSIZ(_n) USBREG(0x00000B10 + (_n) * 0x20) /* Device OUT Endpoint Transfer Size Register */ +#define DWCUSB_DOEPDMA(_n) USBREG(0x00000B14 + (_n) * 0x20) /* Device OUT Endpoint DMA Address Register */ + +/* Device Configuration Register Bit Definitions */ + +#define DWCUSB_DCFG_EPMISCNT_MASK 0x007C0000 /* IN Endpoint Mismatch Count */ +#define DWCUSB_DCFG_EPMISCNT_SHIFT 18 +#define DWCUSB_DCFG_PERFRINT_MASK 0x00001800 /* Periodic Frame Interval */ +#define DWCUSB_DCFG_PERFRINT_80 0x00000000 /* 80% of the (Micro)Frame Interval */ +#define DWCUSB_DCFG_PERFRINT_85 0x00000800 /* 80% of the (Micro)Frame Interval */ +#define DWCUSB_DCFG_PERFRINT_90 0x00001000 /* 80% of the (Micro)Frame Interval */ +#define DWCUSB_DCFG_PERFRINT_95 0x00001800 /* 80% of the (Micro)Frame Interval */ +#define DWCUSB_DCFG_DEVADDR_MASK 0x000007F0 /* Device Address */ +#define DWCUSB_DCFG_DEVADDR_SHIFT 4 +#define DWCUSB_DCFG_NZSTSOUTHSHK 0x00000004 /* Non-Zero-Length Status OUT Handshake */ +#define DWCUSB_DCFG_DEVSPD_MASK 0x00000003 /* Device Speed */ +#define DWCUSB_DCFG_DEVSPD_HS 0x00000000 /* High Speed, USB 2.0 PHY Clock is 30MHz or 60MHz */ +#define DWCUSB_DCFG_DEVSPD_FS 0x00000001 /* Full Speed, USB 2.0 PHY Clock is 30MHz or 60MHz */ +#define DWCUSB_DCFG_DEVSPD_LS 0x00000002 /* Low Speed, USB 1.1 Transceiver Clock is 6MHz */ +#define DWCUSB_DCFG_DEVSPD_FS_48 0x00000003 /* Full Speed, USB 1.1 Transceiver Clock is 48MHz */ + +/* Device Control Register Bit Definitions */ + +#define DWCUSB_DCTL_PWRONPRGDONE 0x00000800 /* Power-On Programming Done */ +#define DWCUSB_DCTL_CGOUTNAK 0x00000400 /* Clear Global OUT NAK */ +#define DWCUSB_DCTL_SGOUTNAK 0x00000200 /* Set Global OUT NAK */ +#define DWCUSB_DCTL_CGNPINNAK 0x00000100 /* Clear Global Non-Periodic IN NAK */ +#define DWCUSB_DCTL_SGNPINNAK 0x00000080 /* Set Global Non-Periodic IN NAK */ +#define DWCUSB_DCTL_TSTCTL_MASK 0x00000070 /* Test Control */ +#define DWCUSB_DCTL_TSTCTL_NOTEST 0x00000000 /* Test Mode Disabled */ +#define DWCUSB_DCTL_TSTCTL_TJ 0x00000010 /* Test_J Mode */ +#define DWCUSB_DCTL_TSTCTL_TK 0x00000020 /* Test_K Mode */ +#define DWCUSB_DCTL_TSTCTL_TSN 0x00000030 /* Test_SE0_NAK Mode */ +#define DWCUSB_DCTL_TSTCTL_TP 0x00000040 /* Test_Packet Mode */ +#define DWCUSB_DCTL_TSTCTL_TEN 0x00000050 /* Test_Force_Enable */ +#define DWCUSB_DCTL_GOUTNAKSTS 0x00000008 /* Global OUT NAK Status */ +#define DWCUSB_DCTL_GNPINNAKSTS 0x00000004 /* Global Non-Periodic IN NAK Status */ +#define DWCUSB_DCTL_SFTDISCON 0x00000002 /* Soft Disconnect */ +#define DWCUSB_DCTL_RMTWKUPSIG 0x00000001 /* Remote Wakeup Signalling */ + +/* Device Status Register Bit Definitions */ + +#define DWCUSB_DSTS_SOFFN_MASK 0x003FFF00 /* (Micro)Frame Number of the Received SOF */ +#define DWCUSB_DSTS_SOFFN_SHIFT 8 +#define DWCUSB_DSTS_ERRTICERR 0x00000008 /* Erratic Error */ +#define DWCUSB_DSTS_ENUMSPD_MASK 0x00000006 /* Enumerated Speed */ +#define DWCUSB_DSTS_ENUMSPD_HS 0x00000000 /* High Speed(PHY Clock is 30MHz or 60MHz) */ +#define DWCUSB_DSTS_ENUMSPD_FS 0x00000002 /* Full Speed(PHY Clock is 30MHz or 60MHz) */ +#define DWCUSB_DSTS_ENUMSPD_LS 0x00000004 /* Low Speed(PHY Clock is 6MHz) */ +#define DWCUSB_DSTS_ENUMSPD_FS_48 0x00000006 /* Full Speed(PHY Clock is 48MHz) */ +#define DWCUSB_DSTS_SUSPSTS 0x00000001 /* Suspend Status */ + +/* Device IN Endpoint Interrupt Status/Mask Register Bit Definitions */ + +#define DWCUSB_DIEPINT_IEPNAKEFF 0x00000040 /* IN Endpoint NAK Effective */ +#define DWCUSB_DIEPINT_INTKNEPMIS 0x00000020 /* IN Token Received with EP Mismatch */ +#define DWCUSB_DIEPINT_INTKNTXFEMP 0x00000010 /* IN Token Received when TxFIFO Empty */ +#define DWCUSB_DIEPINT_TIMEOUT 0x00000008 /* Timeout Condition(Non-Isochronous Endpoints) */ +#define DWCUSB_DIEPINT_AHBERR 0x00000004 /* AHB Error */ +#define DWCUSB_DIEPINT_EPDISBLD 0x00000002 /* Endpoint Disabled Interrupt */ +#define DWCUSB_DIEPINT_XFERCOMPL 0x00000001 /* Transfer Completed Interrupt */ + +/* Device OUT Endpoint Interrupt Status/Mask Register Bit Definitions */ + +#define DWCUSB_DOEPINT_STUPKTRCVD 0x00008000 /* Setup Packet Received */ +#define DWCUSB_DOEPINT_OUTTKNEPDIS 0x00000010 /* OUT Token Received when EP Disabled */ +#define DWCUSB_DOEPINT_SETUP 0x00000008 /* Setup Phase Done */ +#define DWCUSB_DOEPINT_AHBERR 0x00000004 /* AHB Error */ +#define DWCUSB_DOEPINT_EPDISBLD 0x00000002 /* Endpoint Disabled Interrupt */ +#define DWCUSB_DOEPINT_XFERCOMPL 0x00000001 /* Transfer Completed Interrupt */ + +/* Device All Endpoint Interrupt Status/Mask Register Bit Definitions */ + +#define DWCUSB_DAINT_OEP_MASK 0xFFFF0000 /* OUT Endpoint Interrupt */ +#define DWCUSB_DAINT_OEP_SHIFT 16 +#define DWCUSB_DAINT_IEP_MASK 0x0000FFFF /* IN Endpoint Interrupt */ +#define DWCUSB_DAINT_IEP_SHIFT 0 + +/* Device Endpoint 0 Control Register Bit Definitions */ + +#define DWCUSB_DEP0CTL_EPENA 0x80000000 /* Endpoint Enable */ +#define DWCUSB_DEP0CTL_EPDIS 0x40000000 /* Endpoint Disable */ +#define DWCUSB_DEP0CTL_SNAK 0x08000000 /* Set NAK */ +#define DWCUSB_DEP0CTL_CNAK 0x04000000 /* Clear NAK */ +#define DWCUSB_DEP0CTL_TXFNUM_MASK 0x03C00000 /* TxFIFO Number, Always 0 */ +#define DWCUSB_DEP0CTL_TXFNUM_SHIFT 22 +#define DWCUSB_DEP0CTL_STALL 0x00200000 /* STALL Handshake */ +#define DWCUSB_DEP0CTL_SNP 0x00100000 /* Snoop Mode */ +#define DWCUSB_DEP0CTL_EPTYPE_MASK 0x000C0000 /* Endpoint Type */ +#define DWCUSB_DEP0CTL_EPTYPE_CTL 0x00000000 /* Control */ +#define DWCUSB_DEP0CTL_NAKSTS 0x00020000 /* NAK Status */ +#define DWCUSB_DEP0CTL_USBACTEP 0x00008000 /* USB Active Endpoint, Always 1 */ +#define DWCUSB_DEP0CTL_NEXTEP_MASK 0x00007800 /* Next Endpoint */ +#define DWCUSB_DEP0CTL_NEXTEP_SHIFT 11 +#define DWCUSB_DEP0CTL_MPS_MASK 0x00000003 /* Maximum Packet Size */ +#define DWCUSB_DEP0CTL_MPS_64 0x00000000 /* 64 bytes */ +#define DWCUSB_DEP0CTL_MPS_32 0x00000001 /* 32 bytes */ +#define DWCUSB_DEP0CTL_MPS_16 0x00000002 /* 16 bytes */ +#define DWCUSB_DEP0CTL_MPS_8 0x00000003 /* 8 bytes */ + +/* Device Endpoint-n Control Register Bit Definitions */ + +#define DWCUSB_DEPCTL_EPENA 0x80000000 /* Endpoint Enable */ +#define DWCUSB_DEPCTL_EPDIS 0x40000000 /* Endpoint Disable */ +#define DWCUSB_DEPCTL_SETD1PID 0x20000000 /* Set DATA1 PID, Interrupt/Bulk */ +#define DWCUSB_DEPCTL_SETODDFR 0x20000000 /* Set Odd (Micro)Frame, Isochronous */ +#define DWCUSB_DEPCTL_SETD0PID 0x10000000 /* Set DATA0 PID, Interrupt/Bulk */ +#define DWCUSB_DEPCTL_SETEVENFR 0x10000000 /* Set Even (Micro)Frame, Isochronous */ +#define DWCUSB_DEPCTL_SNAK 0x08000000 /* Set NAK */ +#define DWCUSB_DEPCTL_CNAK 0x04000000 /* Clear NAK */ +#define DWCUSB_DEPCTL_TXFNUM_MASK 0x03C00000 /* TxFIFO Number, 0~15 */ +#define DWCUSB_DEPCTL_TXFNUM_SHIFT 22 +#define DWCUSB_DEPCTL_STALL 0x00200000 /* STALL Handshake */ +#define DWCUSB_DEPCTL_SNP 0x00100000 /* Snoop Mode */ +#define DWCUSB_DEPCTL_EPTYPE_MASK 0x000C0000 /* Endpoint Type */ +#define DWCUSB_DEPCTL_EPTYPE_SHIFT 18 +#define DWCUSB_DEPCTL_EPTYPE_CTL 0x00000000 /* Control */ +#define DWCUSB_DEPCTL_EPTYPE_ISO 0x00040000 /* Isochronous */ +#define DWCUSB_DEPCTL_EPTYPE_BULK 0x00080000 /* Bulk */ +#define DWCUSB_DEPCTL_EPTYPE_INT 0x000C0000 /* Interrupt */ +#define DWCUSB_DEPCTL_NAKSTS 0x00020000 /* NAK Status */ +#define DWCUSB_DEPCTL_DPID_DATA0 0x00000000 /* DATA0 */ +#define DWCUSB_DEPCTL_DPID_DATA1 0x00010000 /* DATA1 */ +#define DWCUSB_DEPCTL_EOFRNUM_MASK 0x00010000 +#define DWCUSB_DEPCTL_FR_EVEN 0x00000000 /* Even (Micro)Frame */ +#define DWCUSB_DEPCTL_FR_ODD 0x00010000 /* Odd (Micro)Frame */ +#define DWCUSB_DEPCTL_USBACTEP 0x00008000 /* USB Active Endpoint */ +#define DWCUSB_DEPCTL_NEXTEP_MASK 0x00007800 /* Next Endpoint */ +#define DWCUSB_DEPCTL_NEXTEP_SHIFT 11 +#define DWCUSB_DEPCTL_MPS_MASK 0x000007FF /* Maximum Packet Size */ +#define DWCUSB_DEPCTL_MPS_SHIFT 0 + +/* Device Endpoint 0 Transfer Size Register Bit Definitions */ + +#define DWCUSB_DEP0TSIZ_SUPCNT_MASK 0x60000000 /* SETUP Packet Count */ +#define DWCUSB_DEP0TSIZ_SUPCNT_SHIFT 29 +#define DWCUSB_DEP0TSIZ_PKTCNT 0x00080000 /* Packet Count, Always 1 */ +#define DWCUSB_DEP0TSIZ_PKTCNT_MASK 0x00080000 +#define DWCUSB_DEP0TSIZ_XFERSIZE_MASK 0x0000007F /* Transfer Size */ +#define DWCUSB_DEP0TSIZ_XFERSIZE_SHIFT 0 + +/* Device Endpoint-n Transfer Size Register Bit Definitions */ + +#define DWCUSB_DEPTSIZ_MC_MASK 0x60000000 /* Multi Count */ +#define DWCUSB_DEPTSIZ_MC_SHIFT 29 +#define DWCUSB_DEPTSIZ_RXDPID_MASK 0x60000000 /* Received Data PID */ +#define DWCUSB_DEPTSIZ_RXDPID_DATA0 0x00000000 /* DATA0 */ +#define DWCUSB_DEPTSIZ_RXDPID_DATA1 0x20000000 /* DATA1 */ +#define DWCUSB_DEPTSIZ_RXDPID_DATA2 0x40000000 /* DATA2 */ +#define DWCUSB_DEPTSIZ_RXDPID_MDATA 0x60000000 /* MDATA */ +#define DWCUSB_DEPTSIZ_SUPCNT_MASK 0x60000000 /* SETUP Packet Count */ +#define DWCUSB_DEPTSIZ_SUPCNT_SHIFT 29 +#define DWCUSB_DEPTSIZ_PKTCNT_MASK 0x1FF80000 /* Packet Count */ +#define DWCUSB_DEPTSIZ_PKTCNT_SHIFT 19 +#define DWCUSB_DEPTSIZ_XFERSIZE_MASK 0x0007FFFF /* Transfer Size */ +#define DWCUSB_DEPTSIZ_XFERSIZE_SHIFT 0 + +/* Device IN Token Sequence Learning Queue Read Register 1 (DTKNQR1) Bits Definitions */ +#define DWCUSB_DTKNQR1_WRAP_MASK 0x00000080 +#define DWCUSB_DTKNQR1_WRAP_SHIFT 7 +#define DWCUSB_DTKNQR1_INTKNWPTR_MASK 0x0000001f + + + +/******************************************************************************* + S5L8701 USB Power and Clock Gating Registers + *******************************************************************************/ + +#define DWCUSB_PCGCR USBREG(0x00000E00) /* Power and Clock Gating Control Register */ + +/* Power and Clock Gating Control Register Bit Definitions */ + +#define DWCUSB_PCGCR_PHYSUSPEND 0x00000010 /* PHY Suspend */ +#define DWCUSB_PCGCR_RSTPDWNMODULE 0x00000008 /* Reset Power-Down Module */ +#define DWCUSB_PCGCR_PWRCLMP 0x00000004 /* Power Clamp */ +#define DWCUSB_PCGCR_GATEHCLK 0x00000002 /* Gate Hclk */ +#define DWCUSB_PCGCR_STOPPCLK 0x00000001 /* Stop Pclk */ + + +/******************************************************************************* + S5L8701 USB Data FIFO Access Registers + *******************************************************************************/ + +#define DWCUSB_FIFO(_n) USBREG(0x00001000 + (_n) * 0x1000) /* Data FIFO Access Register */ + + +/******************************************************************************* + S5L8701 OTG PHY Registers + *******************************************************************************/ + +#define DWCUSB_PHYPWR USBPHYREG(0x00000000) /* USB OTG PHY Power Control Register */ +#define DWCUSB_PHYCON USBPHYREG(0x00000004) /* USB OTG PHY Control Register */ +#define DWCUSB_URSTCON USBPHYREG(0x00000008) /* USB Reset Control Register */ +#define DWCUSB_UCONDET USBPHYREG(0x00000028) /* USB Connection Detect Register*/ + +#define DWCUSB_PHYPWR_ANLGPWRDWN 0x00000008 +#define DWCUSB_PHYPWR_ANLGPWRUP 0x00000000 +#define DWCUSB_PHYPWR_OTGPWRDWN 0x00000008 +#define DWCUSB_PHYPWR_OTGPWRUP 0x00000000 +#define DWCUSB_PHYPWR_REFCLK_CRYSTAL 0x00000002 +#define DWCUSB_PHYPWR_REFCLK_OSCI 0x00000000 +#define DWCUSB_PHYPWR_FRCSUSPNDDIS 0x00000000 +#define DWCUSB_PHYPWR_FRCSUSPNDEN 0x00000001 + +#define DWCUSB_PHYCON_CLK_12MHZ 0x00000000 +#define DWCUSB_PHYCON_CLK_24MHZ 0x00000001 +#define DWCUSB_PHYCON_CLK_48MHZ 0x00000002 + +#define DWCUSB_URSTCON_PHYSWRST 0x00000001 + +#define DWCUSB_UCONDET_VBUS_LEVEL_MASK 0x00000001 /* USB Connection Detect Mask */ +#define DWCUSB_UCONTDET_HOSTDEVICE_MASK 0x00000010 +#define DWCUSB_UCONTDET_HOST 0x00000000 +#define DWCUSB_UCONTDET_DEVICE 0x00000010 + +#endif // _SYNOPSYS_OTG_REGISTERS_H_ diff --git a/drivers/thunderbolt/ipipe.c b/drivers/thunderbolt/ipipe.c new file mode 100644 index 0000000..bfb61c6 --- /dev/null +++ b/drivers/thunderbolt/ipipe.c @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipipe_protocol.h" + +#define IPIPE_FILE_RX_INDEX (1) +#define IPIPE_CONSOLE_INDEX (2) +#define IPIPE_FILE_TX_INDEX (3) + +#define IPIPE_HEADER_LEN (4) + +#define IDBG_PROTO_ERR (DEBUG_CRITICAL) + +struct ipipe { + uint32_t max_packet_size; + ipipe_tx_callback_t *tx_callback; + void *priv; + + uint8_t *tx_buffer; + + bool shutdown; + + bool enabled; + + // Console stuff + struct cbuf *console_output_cbuf; + struct task_event console_out_event; + struct task_event console_out_done_event; + struct task *console_task; + + // File get (including "DFU" mode) stuff + bool file_rx_active; + uint32_t file_rx_len; + uint8_t *file_rx_buffer; + uint32_t file_rx_buffer_len; + struct task_event file_rx_event; +#if !WITH_TBT_MODE_DFU + struct callout file_rx_callout; +#endif +}; + +static int ipipe_console_task(void *arg); +static void ipipe_handle_console_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes); + +static void ipipe_handle_file_rx_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes); +static void ipipe_send_file_rx_ack(ipipe_t *ipipe, uint32_t offset); +static void ipipe_send_file_rx_error(ipipe_t *ipipe, uint32_t offset, uint32_t error); +static void ipipe_file_rx_failed(ipipe_t *ipipe); +static void ipipe_handle_file_rx_callout(struct callout *co, void *arg); + +static void ipipe_handle_file_tx_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes); + +ipipe_t *g_ipipe; + +ipipe_t *ipipe_init(uint32_t max_packet_size, ipipe_tx_callback_t *tx_callback, void *priv) +{ + ipipe_t *ipipe; + + ASSERT(max_packet_size > 64); + + ipipe = calloc(sizeof(*ipipe), 1); + ipipe->max_packet_size = max_packet_size; + ipipe->tx_callback = tx_callback; + ipipe->priv = priv; + + ipipe->tx_buffer = malloc(max_packet_size); + +#if WITH_TBT_MODE_RECOVERY + ipipe->console_output_cbuf = cbuf_create(4096, NULL); + event_init(&ipipe->console_out_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(&ipipe->console_out_done_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + ipipe->console_task = task_create("ipipe_console", ipipe_console_task, ipipe, 0); + task_start(ipipe->console_task); +#endif + + event_init(&ipipe->file_rx_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + g_ipipe = ipipe; + + return ipipe; +} + +void ipipe_quiesce_and_free(ipipe_t *ipipe) +{ + if (g_ipipe == ipipe) + g_ipipe = NULL; + +#if WITH_TBT_MODE_RECOVERY + ipipe->shutdown = true; + event_signal(&ipipe->console_out_event); + task_wait_on(ipipe->console_task); + task_destroy(ipipe->console_task); +#endif + + free(ipipe->tx_buffer); + free(ipipe); +} + +static void ipipe_packet_set_header(uint8_t *packet, uint16_t pipe_idx, uint16_t bytes) +{ + packet[0] = pipe_idx & 0xff; + packet[1] = (pipe_idx >> 8) & 0xff; + packet[2] = (bytes & 0xff); + packet[3] = (bytes >> 8) & 0xff; +} + +static void ipipe_send(ipipe_t *ipipe, uint8_t *packet, uint32_t bytes) +{ + ipipe->tx_callback(ipipe->priv, packet, bytes); +} + +// Process a data packet. Packets are expected to have the following format. +// Invalid packets are simply dropped. +// Bytes 0-1: Pipe number +// Bytes 2-3: Payload size (bytes) +void ipipe_handle_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes) +{ + uint16_t pipe_idx; + uint16_t ipipe_bytes; + const uint8_t *payload; + + // Packet needs to be big enough to hold the iPipe header + if (bytes < IPIPE_HEADER_LEN) { + dprintf(IDBG_PROTO_ERR, "packet length %u too short for header\n", bytes); + return; + } + + pipe_idx = packet[0] | (packet[1] << 8); + ipipe_bytes = packet[2] | (packet[3] << 8); + + // And packet needs to be big enough for header and the payload size listed in the header + if (ipipe_bytes + IPIPE_HEADER_LEN > bytes) { + dprintf(IDBG_PROTO_ERR, "packet length %u too short for payload %u\n", bytes, ipipe_bytes); + return; + } + + payload = packet + IPIPE_HEADER_LEN; + + if (pipe_idx == IPIPE_CONSOLE_INDEX) { + ipipe_handle_console_packet(ipipe, payload, ipipe_bytes); + + } else if (pipe_idx == IPIPE_FILE_RX_INDEX) { + ipipe_handle_file_rx_packet(ipipe, payload, ipipe_bytes); + + } else if (pipe_idx == IPIPE_FILE_TX_INDEX) { + ipipe_handle_file_tx_packet(ipipe, payload, ipipe_bytes); + } +} + +// +// iPipe file RX +// + +void ipipe_start_file_rx(ipipe_t *ipipe, void *load_address, uint32_t length) +{ + if (!security_allow_memory(load_address, length)) { + if (ipipe->file_rx_active) { + ipipe->file_rx_active = false; + event_signal(&ipipe->file_rx_event); + } + ipipe->file_rx_len = 0; + return; + } + + ipipe->file_rx_buffer = load_address; + ipipe->file_rx_buffer_len = length; + ipipe->file_rx_len = 0; + ipipe->file_rx_active = true; +} + +int thunderboot_get_dfu_image(void *load_address, int load_length) +{ + int status = -1; + + ASSERT(load_length > 0); + ASSERT(load_address != NULL); + + ipipe_t *ipipe = g_ipipe; + if (ipipe == NULL) + goto exit; + + ipipe_start_file_rx(ipipe, load_address, load_length); + if (!ipipe->file_rx_active) + return -1; + + event_wait(&ipipe->file_rx_event); + + if (ipipe->file_rx_len == 0) + status = -1; + else + status = ipipe->file_rx_len; + +exit: + return status; +} + +static void ipipe_handle_file_rx_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes) +{ + uint32_t offset; + uint32_t payload_size; + + // packet needs to be big enough for the header + if (bytes < 4) { + ipipe_send_file_rx_error(ipipe, 0, IPIPE_ERR_FRAMING); + return; + } + + offset = packet[0] | (packet[1] << 8) | (packet[2] << 16) | (packet[3] << 24); + payload_size = bytes - 4; + + // in non-DFU mode, hosts can start a transfer with a reset packet (offset 0 and no payload) + // in order to reset back to the default load address. + // in DFU-mode, this is just a no-op + if (offset == 0 && payload_size == 0) { +#if !WITH_TBT_MODE_DFU + ipipe_start_file_rx(ipipe, (void *)DEFAULT_LOAD_ADDRESS, DEFAULT_RAMDISK_SIZE); +#endif + return; + } + + if (!ipipe->file_rx_active) { + ipipe_send_file_rx_error(ipipe, offset, IPIPE_ERR_TBD); + return; + } + + // a payload size of 0 with a non-zero offset means that the transfer is done + if (payload_size == 0) { + ipipe->file_rx_active = false; + if (offset != ipipe->file_rx_len) { + ipipe_send_file_rx_error(ipipe, offset, IPIPE_ERR_TBD); + ipipe->file_rx_len = 0; + } else { + ipipe_send_file_rx_ack(ipipe, ipipe->file_rx_len); + } + event_signal(&ipipe->file_rx_event); + +#if !WITH_TBT_MODE_DFU + callout_dequeue(&ipipe->file_rx_callout); +#endif + } else { + if (offset > ipipe->file_rx_buffer_len || + offset + payload_size < offset || + offset + payload_size > ipipe->file_rx_buffer_len) { + ipipe_send_file_rx_error(ipipe, offset, IPIPE_ERR_TBD); + ipipe_file_rx_failed(ipipe); + return; + } + + if (!security_allow_memory((uint8_t *)ipipe->file_rx_buffer + offset, payload_size)) { + ipipe_send_file_rx_error(ipipe, offset, IPIPE_ERR_TBD); + ipipe_file_rx_failed(ipipe); + return; + } + + memcpy((uint8_t *)ipipe->file_rx_buffer + offset, packet + 4, payload_size); + + if (offset + payload_size > ipipe->file_rx_len) + ipipe->file_rx_len = offset + payload_size; + +#if !WITH_TBT_MODE_DFU + callout_reset(&ipipe->file_rx_callout, 0); +#endif + } + + ipipe_send_file_rx_ack(ipipe, offset); +} + +static void ipipe_file_rx_failed(ipipe_t *ipipe) +{ + ipipe->file_rx_active = false; + ipipe_send_file_rx_error(ipipe, -1, IPIPE_ERR_TBD); + ipipe->file_rx_len = 0; + + dprintf(DEBUG_CRITICAL, "transfer failed\n"); + + event_signal(&ipipe->file_rx_event); +#if !WITH_TBT_MODE_DFU + callout_dequeue(&ipipe->file_rx_callout); +#endif +} + +static void ipipe_send_file_rx_ack(ipipe_t *ipipe, uint32_t offset) +{ + uint8_t *packet = ipipe->tx_buffer; + + ipipe_packet_set_header(packet, IPIPE_FILE_RX_INDEX, 8); + + packet[IPIPE_HEADER_LEN + 0] = offset & 0xff; + packet[IPIPE_HEADER_LEN + 1] = (offset >> 8) & 0xff; + packet[IPIPE_HEADER_LEN + 2] = (offset >> 16) & 0xff; + packet[IPIPE_HEADER_LEN + 3] = (offset >> 24) & 0xff; + + packet[IPIPE_HEADER_LEN + 4] = 0; + packet[IPIPE_HEADER_LEN + 5] = 0; + packet[IPIPE_HEADER_LEN + 6] = 0; + packet[IPIPE_HEADER_LEN + 7] = 0; + + ipipe_send(ipipe, packet, IPIPE_HEADER_LEN + 8); +} + +static void ipipe_send_file_rx_error(ipipe_t *ipipe, uint32_t offset, uint32_t error) +{ + uint8_t *packet = ipipe->tx_buffer; + + ipipe_packet_set_header(packet, IPIPE_FILE_RX_INDEX, 8); + + packet[IPIPE_HEADER_LEN + 0] = offset & 0xff; + packet[IPIPE_HEADER_LEN + 1] = (offset >> 8) & 0xff; + packet[IPIPE_HEADER_LEN + 2] = (offset >> 16) & 0xff; + packet[IPIPE_HEADER_LEN + 3] = (offset >> 24) & 0xff; + + packet[IPIPE_HEADER_LEN + 4] = error & 0xff; + packet[IPIPE_HEADER_LEN + 5] = (error >> 8) & 0xff; + packet[IPIPE_HEADER_LEN + 6] = (error >> 16) & 0xff; + packet[IPIPE_HEADER_LEN + 7] = (error >> 24) & 0xff; + + ipipe_send(ipipe, packet, IPIPE_HEADER_LEN + 8); +} + +// +// iPipe file TX +// + +static void ipipe_handle_file_tx_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes) +{ + // XXX: todo +} + +// +// iPipe console +// + +static void ipipe_handle_console_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes) +{ + for(unsigned i = 0; i < bytes; i++) + debug_pushchar(packet[i]); +} + +static int32_t ipipe_console_flush_write_cbuf(ipipe_t *ipipe) +{ + uint8_t *packet = ipipe->tx_buffer; + uint32_t bytes = 0; + + do { + char c; + if (cbuf_read_char(ipipe->console_output_cbuf, &c) == 0) + break; + packet[IPIPE_HEADER_LEN + bytes] = c; + + bytes++; + } while (bytes + IPIPE_HEADER_LEN < ipipe->max_packet_size); + + if (bytes == 0) + return 0; + + ipipe_packet_set_header(packet, IPIPE_CONSOLE_INDEX, bytes); + + ipipe_send(ipipe, packet, bytes + IPIPE_HEADER_LEN); + + return bytes; +} + +static int ipipe_console_task(void *arg) +{ + ipipe_t *ipipe = (ipipe_t *)arg; + + while(!ipipe->shutdown) { + if (ipipe_console_flush_write_cbuf(ipipe) == 0) + event_wait(&ipipe->console_out_event); + else + event_signal(&ipipe->console_out_done_event); + } + + return 0; +} + +void thunderboot_putchar(int c) +{ + ipipe_t *ipipe = g_ipipe; + + if (ipipe == NULL) + return; + + while (cbuf_write_char(ipipe->console_output_cbuf, c) == 0) + event_wait(&ipipe->console_out_done_event); + + event_signal(&ipipe->console_out_event); +} + +int thunderboot_serial_send_cmd_string(uint8_t *buffer, uint32_t len) +{ + // XXX: this isn't robust to losing the connection mid-command + for (unsigned i = 0; i < len; i++) + thunderboot_putchar(buffer[i]); + + return 0; +} + +static int do_ipipe_puts(int argc, struct cmd_arg *argv) +{ + if (g_ipipe == NULL) { + printf("iPipe not initialized\n"); + return -1; + } + + for (int i = 1; i < argc; i++) { + if (i > 1) + thunderboot_putchar(' '); + for (int j = 0; argv[i].str[j] != 0; j++) + thunderboot_putchar(argv[i].str[j]); + } + + return 0; +} + +void thunderboot_transfer_prepare(void *load_address, uint32_t length) +{ + ipipe_t *ipipe = g_ipipe; + + ipipe_start_file_rx(ipipe, load_address, length); + +#if !WITH_TBT_MODE_DFU + // callout to abort the transfer if more than a second elapses without a packet + callout_enqueue(&ipipe->file_rx_callout, 10000000, ipipe_handle_file_rx_callout, ipipe); +#endif +} + +# if !WITH_TBT_MODE_DFU +static void ipipe_handle_file_rx_callout(struct callout *co, void *arg) +{ + ipipe_t *ipipe = (ipipe_t *)arg; + + printf("TBT timeout\n"); + ipipe_file_rx_failed(ipipe); +} +#endif + +int thunderboot_transfer_wait(void) +{ + ipipe_t *ipipe = g_ipipe; + + while (ipipe->file_rx_active) + event_wait(&ipipe->file_rx_event); + + if (ipipe->file_rx_len == 0) + return -1; + else + return ipipe->file_rx_len; + +} + +MENU_COMMAND_DEBUG(ipipe_puts, do_ipipe_puts, "ipipe puts", NULL); diff --git a/drivers/thunderbolt/ipipe_protocol.h b/drivers/thunderbolt/ipipe_protocol.h new file mode 100644 index 0000000..1f6350c --- /dev/null +++ b/drivers/thunderbolt/ipipe_protocol.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef IPIPE_PROTOCOL_H +#define IPIPE_PROTOCOL_H + +#if 0 +#define IPIPE_CTL_PIPE (0) +#endif + +#define IPIPE_ERR_FRAMING (2) +// XXX: remove this +#define IPIPE_ERR_TBD (0xffffffff) + +#endif diff --git a/drivers/thunderbolt/rules.mk b/drivers/thunderbolt/rules.mk new file mode 100644 index 0000000..3b1e483 --- /dev/null +++ b/drivers/thunderbolt/rules.mk @@ -0,0 +1,61 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +# For now thunderbolt implies thunderboot. May not +# always be the case +OPTIONS += WITH_THUNDERBOLT=1 \ + WITH_THUNDERBOOT=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/tbt_cp_crc.o \ + $(LOCAL_DIR)/tbt_control_port.o \ + $(LOCAL_DIR)/tbt_xdomain.o \ + $(LOCAL_DIR)/thunderboot.o \ + $(LOCAL_DIR)/uuid.o \ + $(LOCAL_DIR)/ipipe.o + +ifeq ($(APPLICATION),SecureROM) +OPTIONS += WITH_TBT_BOOT=1 +endif +ifneq ($(filter $(PRODUCT),LLB,iBSS),) +OPTIONS += WITH_TBT_BOOT=1 +endif + +# SecureROM and iBSS-DFU support +ifneq ($(filter $(OPTIONS), WITH_DFU_MODE=1), ) + +OPTIONS += \ + WITH_TBT_DFU=1 \ + WITH_TBT_MODE_DFU=1 + +endif + +# Recovery mode support +ifneq ($(filter $(OPTIONS), WITH_RECOVERY_MODE=1), ) + +OPTIONS += \ + WITH_TBT_MODE_RECOVERY=1 + +ifneq ($(BUILD),RELEASE) +OPTIONS += \ + WITH_TBT_UPLOAD=0 +# XXX: should be a "1" above +endif + +MODULES += \ + lib/cbuf \ + lib/cksum + +ALL_OBJS += \ + $(LOCAL_DIR)/thunderboot_debug.o + +endif diff --git a/drivers/thunderbolt/tbt_control_port.c b/drivers/thunderbolt/tbt_control_port.c new file mode 100644 index 0000000..93fc2b9 --- /dev/null +++ b/drivers/thunderbolt/tbt_control_port.c @@ -0,0 +1,624 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include "tbt_control_port.h" +#include "tbt_cp_crc.h" +#include "tbt_xdomain.h" +#include "tbt_protocol.h" + +#define CPDBG_DUMP_PACKET DEBUG_NEVER +#define CPDBG_INIT DEBUG_INFO +#define CPDBG_IO DEBUG_SPEW +#define CPDBG_EVENT DEBUG_SPEW + +struct xd_service { + struct list_node list; + // Callback function to handle incoming xdomain requests for this service + tbt_xd_callback_t request_callback; + // Callback function to handle incoming xdomain responses for this service + tbt_xd_callback_t response_callback; + // Private data passed in when the service was register + void *priv; +}; + +struct tbt_cp { + nhi_t *nhi; + uint8_t rx_buffer[256]; + uint8_t tx_buffer[256]; + uint8_t pdf_next_seq[TBT_CFG_MAX_PDF + 1]; + + bool shutdown; + struct task *polling_task; + + struct list_node xd_services; + + uint32_t *read_req_buffer; + uint32_t read_req_header; + uint16_t read_req_quads; + bool read_req_pending; + struct task_event read_event; + + uint32_t write_req_header; + bool write_req_pending; + struct task_event write_event; +}; + +static void tbt_cp_process_xd_request(tbt_cp_t *cp, uint8_t *packet, size_t bytes); +static void tbt_cp_process_xd_response(tbt_cp_t *cp, uint8_t *packet, size_t bytes); +static void tbt_cp_process_read_response(tbt_cp_t *cp, uint8_t *packet, size_t bytes); +static void tbt_cp_process_write_response(tbt_cp_t *cp, uint8_t *packet, size_t bytes); +static void tbt_cp_process_plug_event(tbt_cp_t *cp, uint8_t *packet, size_t bytes); +static void tbt_cp_process_error(tbt_cp_t *cp, uint8_t *packet, size_t bytes); +static int tbt_cp_polling_task(void *arg); + +static tbt_cp_t *g_tbt_cp; + +void tbt_cp_dump_route_string(uint64_t route_string) +{ + if (route_string & (1ULL << 63)) + printf("CM:"); + + printf("%02x", route_string & 0x3F); + + for (int i = 1; i < 7; i++) { + if (((route_string >> (i * 8)) & 0x3F) == 0) + break; + + printf(",%02x", (route_string >> (i * 8)) & 0x3F); + } +} + +uint64_t tbt_cp_packet_get_route_string(const uint8_t *packet) +{ + uint64_t route_string = 0; + + for (int i = 0; i < 8; i++) + route_string |= (uint64_t)packet[i] << ((8 - i - 1) * 8); + + return route_string; +} + +void tbt_cp_packet_set_route_string(uint8_t *packet, uint64_t route_string) +{ + for (int i = 0; i < 8; i++) + packet[i] = route_string >> ((8 - i - 1) * 8); +} + +void tbt_cp_dump_xdomain_message(uint8_t *packet, size_t bytes) +{ +#if CPDBG_DUMP_PACKET <= DEBUG_LEVEL + uint64_t route = tbt_cp_packet_get_route_string(packet); + uint32_t header; + uint32_t seq; + uint32_t payload_len; + char *len_message = ""; + size_t offset; + + memcpy(&header, packet + 8, sizeof(uint32_t)); + header = htonl(header); + seq = (header >> 27) & 0x3; + payload_len = header & 0x3f; + + if (payload_len * 4 > bytes - 12) + len_message = " (INVALID)"; + + printf("Route String: "); + tbt_cp_dump_route_string(route); + printf("\n"); + printf("Length: 0x%02x%s\n", payload_len, len_message); + printf("Sequence Num: 0x%02x\n", seq); + printf("Payload:\n"); + + if (payload_len * 4 > bytes - 12) + payload_len = (bytes - 12) / 4; + + offset = 0; + while (offset < payload_len * 4) { + for (int i = 0; i < 16 && offset < payload_len * 4; i++, offset++) + printf("%02x ", packet[offset + 12]); + printf("\n"); + } +#endif +} + +void tbt_cp_dump_message(uint8_t *packet, size_t bytes) +{ +#if CPDBG_DUMP_PACKET <= DEBUG_LEVEL + uint64_t route = tbt_cp_packet_get_route_string(packet); + uint32_t value; + + printf("Route String: "); + tbt_cp_dump_route_string(route); + printf("\nPayload:\n"); + + for (size_t i = 0; i < bytes - 12; i += 4) { + memcpy(&value, packet + 8 + i, 4); + printf("%08x ", value); + if (i % 16 == 12) + printf("\n"); + } + if ((bytes - 12) % 16 != 0) + printf("\n"); + memcpy(&value, packet + bytes - 4, 4); + printf("CRC: %08x\n", value); +#endif +} + +tbt_cp_t *tbt_cp_create(nhi_t *nhi) +{ + tbt_cp_t *cp; + + cp = calloc(sizeof(*cp), 1); + + dprintf(CPDBG_INIT, "tbt_cp: initializing\n"); + + cp->nhi = nhi; + cp->xd_services = LIST_INITIAL_VALUE(cp->xd_services); + + // Control messages are sent/received on ring 0 + // 16 buffers should be plenty. The packets are 256 bytes each + // These functions will panic if someone already took the ring + nhi_init_tx_ring(nhi, 0, 16, 256); + nhi_init_rx_ring(nhi, 0, 16, 256); + + event_init(&cp->read_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + event_init(&cp->write_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + // start a thread to handle packets for the control port + cp->polling_task = task_create("tbt_polling", tbt_cp_polling_task, cp, 0); + task_start(cp->polling_task); + + // Pointer used for debug command access to the control port, assumes only 1 exists + g_tbt_cp = cp; + + return cp; +} + +void tbt_cp_quiesce_and_free(tbt_cp_t *cp) +{ + cp->shutdown = true; + + task_wait_on(cp->polling_task); + + task_destroy(cp->polling_task); + cp->polling_task = NULL; + + nhi_disable_tx_ring(cp->nhi, 0); + nhi_disable_rx_ring(cp->nhi, 0); + + free(cp); +} + +void *tbt_cp_register_xd_service(tbt_cp_t *cp, tbt_xd_callback_t req_cb, tbt_xd_callback_t resp_cb, void *priv) +{ + struct xd_service *new_service; + + ASSERT(req_cb != NULL); + ASSERT(resp_cb != NULL); + + new_service = calloc(sizeof(*new_service), 1); + new_service->request_callback = req_cb; + new_service->response_callback = resp_cb; + new_service->priv = priv; + + list_add_tail(&cp->xd_services, &new_service->list); + + return (void *)&new_service->list; +} + +void tbt_cp_unregister_xd_service(tbt_cp_t *cp, void *handle) +{ + struct list_node *item = (struct list_node *)handle; + struct xd_service *service; + + if (!list_in_list(item)) + panic("unregistering nonregistered xdomain service"); + + service = containerof(item, struct xd_service, list); + + list_delete(item); + free(service); +} + + +bool tbt_cp_packet_available(tbt_cp_t *cp) +{ + ASSERT(cp != NULL); + + return nhi_rx_buffer_available(cp->nhi, 0); +} + +void tbt_cp_process_packet(tbt_cp_t *cp) +{ + uint8_t eof_pdf; + int32_t bytes; + uint32_t packet_crc; + uint32_t calc_crc; + + bytes = nhi_rx_buffer(cp->nhi, 0, cp->rx_buffer, sizeof(cp->rx_buffer), NULL, &eof_pdf); + + if (bytes < 0) { + dprintf(DEBUG_CRITICAL, "tbt_cp: error %d receiving packet\n", bytes); + return; + } + + // Packet must be big enough for header + CRC + if (bytes < TBT_CFG_HEADER_LEN + 4) { + dprintf(DEBUG_CRITICAL, "tbt_cp: runt packet\n"); + return; + } + + calc_crc = tbt_cp_crc(cp->rx_buffer, bytes - 4); + memcpy(&packet_crc, cp->rx_buffer + bytes - 4, 4); + packet_crc = ntohl(packet_crc); + if (calc_crc != packet_crc) { + dprintf(DEBUG_CRITICAL, "tbt_cp: CRC mismatch %x v %x\n", calc_crc, packet_crc); + return; + } + + switch (eof_pdf) { + case TBT_CFG_READ_PDF: + tbt_cp_dump_message(cp->rx_buffer, bytes); + tbt_cp_process_read_response(cp, cp->rx_buffer, bytes - 4); + break; + case TBT_CFG_WRITE_PDF: + tbt_cp_dump_message(cp->rx_buffer, bytes); + tbt_cp_process_write_response(cp, cp->rx_buffer, bytes - 4); + break; + case TBT_CFG_PLUG_EVENT_PDF: + tbt_cp_process_plug_event(cp, cp->rx_buffer, bytes - 4); + break; + case TBT_CFG_ERROR_PDF: + tbt_cp_dump_message(cp->rx_buffer, bytes); + tbt_cp_process_error(cp, cp->rx_buffer, bytes - 4); + break; + case TBT_CFG_XDOMAIN_REQUEST_PDF: + tbt_cp_dump_xdomain_message(cp->rx_buffer, bytes); + tbt_cp_process_xd_request(cp, cp->rx_buffer, bytes - 4); + break; + case TBT_CFG_XDOMAIN_RESPONSE_PDF: + tbt_cp_dump_xdomain_message(cp->rx_buffer, bytes); + tbt_cp_process_xd_response(cp, cp->rx_buffer, bytes - 4); + break; + default: + dprintf(DEBUG_INFO, "tbt_cp: got unexpected PDF 0x%02x\n", eof_pdf); + tbt_cp_dump_message(cp->rx_buffer, bytes); + break; + } +} + +// Control port packets have a 2-bit sequence number. The OS stack increments the +// sequence number per PDF, so we'll do the same. This function gets the next +// sequence number and increments a 2-bit counter to provide for the subsequent value +uint8_t tbt_cp_next_pdf_seq(tbt_cp_t *cp, uint8_t pdf) +{ + uint8_t next; + + ASSERT(cp != NULL); + ASSERT(pdf <= TBT_CFG_MAX_PDF); + + next = cp->pdf_next_seq[pdf]; + cp->pdf_next_seq[pdf] = (next + 1) & 3; + + return next; +} + +// Queues the given packet to be sent +bool tbt_cp_send(tbt_cp_t *cp, uint8_t pdf, uint8_t *packet, size_t len) +{ + uint32_t crc; + nhi_sgl_t sgl[2]; + + ASSERT(len <= TBT_CFG_MAX_HEADER_AND_PAYLOAD); + + crc = htonl(tbt_cp_crc(packet, len)); + + sgl[0].buffer = packet; + sgl[0].bytes = len; + sgl[0].next = &sgl[1]; + sgl[1].buffer = &crc; + sgl[1].bytes = sizeof(crc); + sgl[1].next = NULL; + + return nhi_send_sgl(cp->nhi, 0, sgl, pdf, pdf) == NHI_STATUS_OK; +} + +void tbt_cp_send_acknowledgement(tbt_cp_t *cp, uint64_t route_string, uint8_t port, uint8_t code) +{ + uint32_t packet[3]; + + packet[0] = route_string >> 32; + packet[1] = route_string; + packet[2] = htonl((port << 8) | code); + + tbt_cp_send(cp, TBT_CFG_ERROR_PDF, (uint8_t *)packet, sizeof(packet)); +} + +bool tbt_cp_read(tbt_cp_t *cp, uint64_t topology_id, uint8_t space, uint8_t port, uint16_t index, uint32_t *buffer, uint16_t quadlets) +{ + bool ret; + uint32_t request[3]; + uint32_t header; + uint8_t pdf = TBT_CFG_READ_PDF; + uint8_t seq = tbt_cp_next_pdf_seq(cp, pdf); + + ASSERT(quadlets < 60); + + dprintf(CPDBG_IO, "tbt_cp: reading %d quads from %08llx %x:%02x:%04x\n", quadlets, topology_id, space, port, index); + + request[0] = htonl(topology_id >> 32); + request[1] = htonl(topology_id & 0xffffffff); + header = 0; + header |= (index & 0x1fff) << 0; + header |= (quadlets & 0x3f) << 13; + header |= (port & 0x3f) << 19; + header |= (space & 0x3) << 25; + header |= seq << 27; + request[2] = htonl(header); + + if (!tbt_cp_send(cp, pdf, (uint8_t *)request, sizeof(request))) + return false; + + // If we ever switch to interrupts, this will need to be reconsidered + cp->read_req_header = header; + cp->read_req_buffer = buffer; + cp->read_req_quads = quadlets; + cp->read_req_pending = true; + + event_wait_timeout(&cp->read_event, 200000); + + // if the read request is no longer pending, then tbt_cp_process_read_response saw a good response + ret = !cp->read_req_pending; + cp->read_req_pending = false; + + if (ret) { + for (unsigned i = 0; i < quadlets; i++) + buffer[i] = ntohl(buffer[i]); + } + + return ret; +} + +bool tbt_cp_write(tbt_cp_t *cp, uint64_t topology_id, uint8_t space, uint8_t port, uint16_t index, const uint32_t *buffer, uint16_t quadlets) +{ + uint8_t pdf = TBT_CFG_WRITE_PDF; + uint8_t seq = tbt_cp_next_pdf_seq(cp, pdf); + uint32_t header; + uint32_t topo_high; + uint32_t topo_low; + uint32_t swapped; + bool ret; + + dprintf(CPDBG_IO, "tbt_cp: write %d quads to %016llx %x:%02x:%04x\n", quadlets, topology_id, space, port, index); + + ASSERT(quadlets < 60); + + topo_high = htonl(topology_id >> 32); + topo_low = htonl(topology_id & 0xffffffff); + header = 0; + header |= (index & 0x1fff) << 0; + header |= (quadlets & 0x3f) << 13; + header |= (port & 0x3f) << 19; + header |= (space & 0x3) << 25; + header |= seq << 27; + header = htonl(header); + + memcpy(cp->tx_buffer + 0, &topo_high, 4); + memcpy(cp->tx_buffer + 4, &topo_low, 4); + memcpy(cp->tx_buffer + 8, &header, 4); + for(uint16_t i = 0; i < quadlets; i++) { + swapped = htonl(buffer[i]); + memcpy(cp->tx_buffer + 12 + 4 * i, &swapped, 4); + } + + if (!tbt_cp_send(cp, pdf, cp->tx_buffer, 12 + 4 * quadlets)) + return false; + + // If we ever use interrupts, this will need to be reordered compared to the send call + cp->write_req_header = ntohl(header); + cp->write_req_pending = true; + + event_wait_timeout(&cp->write_event, 200000); + + // If write_req_pending is false, then tbt_cp_process_write_response saw a good response + ret = !cp->write_req_pending; + cp->write_req_pending = false; + + return true; +} + +static void tbt_cp_process_read_response(tbt_cp_t *cp, uint8_t *packet, size_t bytes) +{ + uint16_t len; + uint32_t header; + + if (!cp->read_req_pending) { + dprintf(DEBUG_CRITICAL, "tbt_cp: spurious read request response\n"); + return; + } + + memcpy(&header, packet + 8, 4); + header = ntohl(header); + len = (header >> 13) & 0x3f; + + dprintf(CPDBG_IO, "tbt_cp: read response header=0x%08x bytes=%u\n", header, (unsigned)bytes); + + // The far end is supposed to just copy the entire header back to us. They seem + // to put garbage in the port number when we aren't reading port space, so + // ignore it in the comparison + if ((header & 0x1E07FFFF) != (cp->read_req_header & 0x1E07FFFF)) { + dprintf(DEBUG_CRITICAL, "tbt_cp: read request header mismatch, got %x expected %x mismatch %x\n", header, cp->read_req_header, header ^ cp->read_req_header); + return; + } + + // Belt and suspenders check on the length, which is included in the header + if (len != cp->read_req_quads) { + dprintf(DEBUG_CRITICAL, "tbt_cp: read request len mismatch, got %u expected %u\n", len, cp->read_req_quads); + return; + } + + if (bytes != (len * 4) + 12) { + dprintf(DEBUG_CRITICAL, "tbt_cp: read request payload len mismatch, got %u expected %u\n", bytes, (len * 4) + 16); + return; + } + + memcpy(cp->read_req_buffer, packet + 12, cp->read_req_quads * 4); + + cp->read_req_pending = false; + + event_signal(&cp->read_event); +} + +static void tbt_cp_process_write_response(tbt_cp_t *cp, uint8_t *packet, size_t bytes) +{ + uint32_t header; + + if (!cp->write_req_pending) { + dprintf(DEBUG_CRITICAL, "tbt_cp: spurious write request response\n"); + return; + } + + memcpy(&header, packet + 8, 4); + header = ntohl(header); + + dprintf(CPDBG_IO, "tbt_cp: write response header=0x%08x bytes=%u\n", header, (unsigned)bytes); + + // The far end is supposed to just copy the entire header back to us. We'll + // mask off the reserved bits, but otherwise everything had better match + if ((header & 0x1fffffff) != cp->write_req_header) { + dprintf(DEBUG_CRITICAL, "tbt_cp: write request header mismatch, got %x expected %x\n", header, cp->read_req_header); + return; + } + cp->write_req_pending = false; + + event_signal(&cp->write_event); +} + +static void tbt_cp_process_plug_event(tbt_cp_t *cp, uint8_t *packet, size_t bytes) +{ + uint64_t route_string; + uint32_t details; + uint8_t port; + + // Send the acknowledgement back to the sender, clearing the CM bit + route_string = tbt_cp_packet_get_route_string(packet); + route_string &= ~(1ULL << 63); + + memcpy(&details, packet + 8, sizeof(details)); + details = ntohl(details); + + port = details & 0x3f; + + dprintf(CPDBG_EVENT, "tbt_cp: Got plug event from %016llx for port %x\n", route_string, port); + + tbt_cp_send_acknowledgement(cp, route_string, port, 7); +} + +static void tbt_cp_process_error(tbt_cp_t *cp, uint8_t *packet, size_t bytes) +{ + uint64_t route_string; + + // XXX + dprintf(DEBUG_INFO, "Got an error packet. We should probably handle these?\n"); + + route_string = tbt_cp_packet_get_route_string(packet); +} + +static void tbt_cp_process_xd_request(tbt_cp_t *cp, uint8_t *packet, size_t bytes) +{ + struct xd_service *service; + + list_for_every_entry(&cp->xd_services, service, struct xd_service, list) { + service->request_callback(cp, packet, bytes, service->priv); + } +} + +static void tbt_cp_process_xd_response(tbt_cp_t *cp, uint8_t *packet, size_t bytes) +{ + struct xd_service *service; + + list_for_every_entry(&cp->xd_services, service, struct xd_service, list) { + service->response_callback(cp, packet, bytes, service->priv); + } +} + +static int tbt_cp_polling_task(void *arg) +{ + tbt_cp_t *cp = (tbt_cp_t *)arg; + + dprintf(CPDBG_INIT, "tbt_cp: polling task started\n"); + + while (!cp->shutdown) { + while (tbt_cp_packet_available(cp)) { + tbt_cp_process_packet(cp); + } + + task_yield(); + } + + dprintf(CPDBG_INIT, "tbt_cp: polling task finished\n"); + + return 0; +} + +#if DEBUG_BUILD +static int do_tbtcp_debug_cmd(int argc, struct cmd_arg *args) +{ + int result = -1; + const char *cmd = NULL; + + // Nothing to do if there's no control port + if (g_tbt_cp == NULL) + return -1; + + if (argc >= 2) + cmd = args[1].str; + + if (cmd != NULL) { + if (strcmp(cmd, "read") == 0 && argc >= 6) { + uint64_t topo_id = args[2].n; + uint8_t space = args[3].n; + uint8_t port = args[4].n; + uint16_t index = args[5].n; + uint32_t buffer; + + if (tbt_cp_read(g_tbt_cp, topo_id, space, port, index, &buffer, 1)) { + printf("0x%08x\n", buffer); + result = 0; + } else { + printf("read failure\n"); + } + } else if (strcmp(cmd, "write") == 0 && argc >= 7) { + uint64_t topo_id = args[2].n; + uint8_t space = args[3].n; + uint8_t port = args[4].n; + uint16_t index = args[5].n; + uint32_t buffer = args[6].n; + + if (tbt_cp_write(g_tbt_cp, topo_id, space, port, index, &buffer, 1)) { + result = 0; + } else { + printf("write failure\n"); + } + } + } + + return result; +} +#endif + +MENU_COMMAND_DEBUG(tbtcp, do_tbtcp_debug_cmd, "TBT control port debug commands", NULL); diff --git a/drivers/thunderbolt/tbt_control_port.h b/drivers/thunderbolt/tbt_control_port.h new file mode 100644 index 0000000..7fbe23a --- /dev/null +++ b/drivers/thunderbolt/tbt_control_port.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TBT_CONTROL_PORT_H +#define TBT_CONTROL_PORT_H + +#include +#include +#include "uuid.h" + +typedef struct tbt_cp tbt_cp_t; +typedef void (*tbt_xd_callback_t)(tbt_cp_t *, const uint8_t *packet, size_t len, void *priv); + +tbt_cp_t *tbt_cp_create(nhi_t *nhi); +void tbt_cp_quiesce_and_free(tbt_cp_t *cp); +void *tbt_cp_register_xd_service(tbt_cp_t *cp, tbt_xd_callback_t req_cb, tbt_xd_callback_t resp_cb, void *priv); +void tbt_cp_unregister_xd_service(tbt_cp_t *cp, void *handle); + +bool tbt_cp_read(tbt_cp_t *cp, uint64_t topology_id, uint8_t space, uint8_t port, uint16_t index, uint32_t *buffer, uint16_t quadlets); +bool tbt_cp_write(tbt_cp_t *cp, uint64_t topology_id, uint8_t space, uint8_t port, uint16_t index, const uint32_t *buffer, uint16_t quadlets); + +bool tbt_cp_packet_available(tbt_cp_t *cp); +void tbt_cp_process_packet(tbt_cp_t *cp); +uint8_t tbt_cp_next_pdf_seq(tbt_cp_t *cp, uint8_t pdf); +bool tbt_cp_send(tbt_cp_t *cp, uint8_t pdf, uint8_t *packet, size_t len); + +uint64_t tbt_cp_packet_get_route_string(const uint8_t *packet); +void tbt_cp_packet_set_route_string(uint8_t *packet, uint64_t route_string); + +#endif diff --git a/drivers/thunderbolt/tbt_cp_crc.c b/drivers/thunderbolt/tbt_cp_crc.c new file mode 100644 index 0000000..6cd9869 --- /dev/null +++ b/drivers/thunderbolt/tbt_cp_crc.c @@ -0,0 +1,109 @@ +#include + +/*****************************************************************/ +/* */ +/* CRC LOOKUP TABLE */ +/* ================ */ +/* The following CRC lookup table was generated automagically */ +/* by the Rocksoft^tm Model CRC Algorithm Table Generation */ +/* Program V1.0 using the following model parameters: */ +/* */ +/* Width : 4 bytes. */ +/* Poly : 0x1EDC6F41L */ +/* Reverse : TRUE. */ +/* */ +/* For more information on the Rocksoft^tm Model CRC Algorithm, */ +/* see the document titled "A Painless Guide to CRC Error */ +/* Detection Algorithms" by Ross Williams */ +/* (ross@guest.adelaide.edu.au.). This document is likely to be */ +/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ +/* */ +/*****************************************************************/ + +uint32_t crctable[256] = +{ + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L +}; + +/*****************************************************************/ +/* End of CRC Lookup Table */ +/*****************************************************************/ + +/*****************************************************************/ +/* ComputeCRC */ +/*****************************************************************/ + +#define TB_INIT 0xFFFFFFFF +#define TB_INIT_REFLECTED 0xFFFFFFFF +#define TB_XOROT 0xFFFFFFFF + +uint32_t tbt_cp_crc(const uint8_t *packet, uint32_t bytes) +{ + uint32_t crc = TB_INIT_REFLECTED; + while (bytes--) + crc = crctable[(crc ^ *packet++) & 0xFFL] ^ (crc >> 8); + return crc ^ TB_XOROT; +} diff --git a/drivers/thunderbolt/tbt_cp_crc.h b/drivers/thunderbolt/tbt_cp_crc.h new file mode 100644 index 0000000..f2d90d1 --- /dev/null +++ b/drivers/thunderbolt/tbt_cp_crc.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TBT_CP_CRC +#define TBT_CP_CRC + +uint32_t tbt_cp_crc(const uint8_t *packet, uint32_t bytes); + +#endif diff --git a/drivers/thunderbolt/tbt_protocol.h b/drivers/thunderbolt/tbt_protocol.h new file mode 100644 index 0000000..3eeb214 --- /dev/null +++ b/drivers/thunderbolt/tbt_protocol.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TBT_PROTOCOL_H +#define TBT_PROTOCOL_H + +#define TBT_CFG_SPACE_PATH (0) +#define TBT_CFG_SPACE_PORT (1) +#define TBT_CFG_SPACE_DEVICE (2) +#define TBT_CFG_SPACE_COUNTERS (3) + +#define TBT_CFG_READ_PDF (1) +#define TBT_CFG_WRITE_PDF (2) +#define TBT_CFG_ERROR_PDF (3) +#define TBT_CFG_NOTIFY_ACK_PDF (4) +#define TBT_CFG_PLUG_EVENT_PDF (5) +#define TBT_CFG_XDOMAIN_REQUEST_PDF (6) +#define TBT_CFG_XDOMAIN_RESPONSE_PDF (7) +#define TBT_CFG_CM_OVERRIDE_PDF (8) +#define TBT_CFG_RESET_PDF (9) +#define TBT_CFG_PREPARE_TO_SLEEP_PDF (13) +#define TBT_CFG_MAX_PDF (15) + +#define TBT_CFG_HEADER_LEN (8) +#define TBT_CFG_MAX_HEADER_AND_PAYLOAD (252) // XXX: Check this. Does NHI give us the first 4 bytes or not? + +#define TBT_CFG_ROUTE_CM_MASK (1ULL << 63) +#define TBT_CFG_ROUTE_STRING_MASK (~(3ULL << 62)) + +#define TBT_XD_REQUEST_HEADER_LEN (TBT_CFG_HEADER_LEN + 4 + 16 + 4) +#define TBT_XD_RESPONSE_HEADER_LEN (TBT_XD_REQUEST_HEADER_LEN) +#define TBT_XD_REQUEST_PROTOCOL_UUID_OFFSET (TBT_CFG_HEADER_LEN + 4) +#define TBT_XD_REQUEST_PACKET_TYPE_OFFSET (TBT_CFG_HEADER_LEN + 4 + 16) +#define TBT_XD_REQUEST_MAX_PAYLOAD (TBT_CFG_MAX_HEADER_AND_PAYLOAD - TBT_XD_REQUEST_HEADER_LEN) +#define TBT_XD_RESPONSE_MAX_PAYLOAD (TBT_XD_REQUEST_MAX_PAYLOAD) + +#define TBT_XD_UUID_REQUEST (1) +#define TBT_XD_UUID_RESPONSE (2) +#define TBT_XD_ROM_READ_REQUEST (3) +#define TBT_XD_ROM_READ_RESPONSE (4) +#define TBT_XD_ROM_CHANGED_REQUEST (5) +#define TBT_XD_ROM_CHANGED_RESPONSE (6) +#define TBT_XD_ERROR_RESPONSE (7) +#define TBT_XD_UUID_V2_REQUEST (12) + +#define TBT_XD_UUID_REQUEST_LEN (TBT_XD_REQUEST_HEADER_LEN) +#define TBT_XD_UUID_RESPONSE_LEN (TBT_XD_RESPONSE_HEADER_LEN + 16) +#define TBT_XD_ROM_CHANGED_REQUEST_LEN (TBT_XD_REQUEST_HEADER_LEN + 16) +#define TBT_XD_ROM_CHANGED_RESPONSE_LEN (TBT_XD_RESPONSE_HEADER_LEN) +#define TBT_XD_ROM_READ_REQUEST_LEN (TBT_XD_REQUEST_HEADER_LEN + 16 + 16 + 4) +#define TBT_XD_ROM_READ_RESPONSE_DATA_OFFSET (16 + 16 + 4 + 4) +#define TBT_XD_ROM_READ_RESPONSE_MAX_DATA (TBT_CFG_MAX_HEADER_AND_PAYLOAD - TBT_XD_RESPONSE_HEADER_LEN - TBT_XD_ROM_READ_RESPONSE_DATA_OFFSET) + +#endif diff --git a/drivers/thunderbolt/tbt_xd_packet.h b/drivers/thunderbolt/tbt_xd_packet.h new file mode 100644 index 0000000..25cc16e --- /dev/null +++ b/drivers/thunderbolt/tbt_xd_packet.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TBT_XD_PACKET_H +#define TBT_XD_PACKET_H + +#include +#include "tbt_protocol.h" + +// Sets the length of field of an xdomain packet. The length is given +// in bytes, but must be a multiple of 4 +static inline void tbt_xd_packet_set_len(uint8_t *packet, uint8_t len) +{ + ASSERT((len & 0x3) == 0); + + // length (in dwords) is in bits 0-5 of the DWORD 2 + // clients include the length of the header when calling, but + // the spec doesn't include the header length, so subtract 12 + packet[11] = (len - 12) >> 2; +} + +// Sets the sequence number field of an xdomain packet. The sequence +// number must be a 2-bit number +static inline void tbt_xd_packet_set_seq(uint8_t *packet, uint8_t seq) +{ + ASSERT((seq & ~0x3U) == 0); + + // sequence number is in bits 27-28 of the DWORD 2 + packet[8] = seq << 3; +} + +// Gets the sequence number field of an xdomain packet +static inline uint8_t tbt_xd_packet_get_seq(const uint8_t *packet) +{ + // sequence number is in bits 27-28 of the DWORD 2 + return (packet[8] >> 3) & 0x3; +} + +/* Sets the protocol UUID of the given xdomain request or response packet to the + * given UUID in Thunderbolt network byte order + */ +static inline void tbt_xd_packet_set_protocol_uuid(uint8_t *packet, const uint8_t *uuid) +{ + memcpy(packet + TBT_XD_REQUEST_PROTOCOL_UUID_OFFSET, uuid, 16); +} + +/* Compares the protocol UUID of the given xdomain request or response packet to the + * given UUID in Thunderbolt network byte order + */ +static inline int tbt_xd_packet_compare_protocol_uuid(const uint8_t *packet, const uint8_t *uuid) +{ + return memcmp(packet + TBT_XD_REQUEST_PROTOCOL_UUID_OFFSET, uuid, 16); +} + +static inline uint32_t tbt_xd_packet_get_type(const uint8_t *packet) +{ + uint32_t packet_type; + memcpy(&packet_type, packet + TBT_XD_REQUEST_PACKET_TYPE_OFFSET, sizeof(packet_type)); + return ntohl(packet_type); +} + +static inline void tbt_xd_packet_set_type(uint8_t *packet, uint32_t packet_type) +{ + packet_type = htonl(packet_type); + memcpy(packet + TBT_XD_REQUEST_PACKET_TYPE_OFFSET, &packet_type, sizeof(packet_type)); +} + +static inline void tbt_xd_packet_get_payload(const uint8_t *packet, void *buffer, size_t offset, size_t bytes) +{ + ASSERT(offset + bytes >= offset); + ASSERT(offset < TBT_XD_REQUEST_MAX_PAYLOAD); + ASSERT(offset + bytes <= TBT_XD_REQUEST_MAX_PAYLOAD); + + memcpy(buffer, packet + TBT_XD_REQUEST_HEADER_LEN + offset, bytes); +} + +static inline void tbt_xd_packet_set_payload(uint8_t *packet, const void *buffer, size_t offset, size_t bytes) +{ + ASSERT(offset + bytes >= offset); + ASSERT(offset < TBT_XD_REQUEST_MAX_PAYLOAD); + ASSERT(offset + bytes <= TBT_XD_REQUEST_MAX_PAYLOAD); + + memcpy(packet + TBT_XD_REQUEST_HEADER_LEN + offset, buffer, bytes); +} + +static inline uint32_t tbt_xd_packet_get_payload_dword(const uint8_t *packet, size_t offset) +{ + uint32_t dword; + tbt_xd_packet_get_payload(packet, &dword, offset, sizeof(dword)); + + return ntohl(dword); +} + +static inline void tbt_xd_packet_set_payload_dword(uint8_t *packet, uint32_t dword, size_t offset) +{ + dword = htonl(dword); + tbt_xd_packet_set_payload(packet, &dword, offset, sizeof(dword)); +} + + +#endif diff --git a/drivers/thunderbolt/tbt_xdomain.c b/drivers/thunderbolt/tbt_xdomain.c new file mode 100644 index 0000000..2c441ea --- /dev/null +++ b/drivers/thunderbolt/tbt_xdomain.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include "tbt_control_port.h" +#include "tbt_protocol.h" +#include "tbt_xdomain.h" +#include "tbt_xd_packet.h" +#include "uuid.h" + +struct tbt_xd_discovery { + tbt_cp_t *control_port; + void *xd_service_handle; + + + // The configuration ROM + const uint32_t *rom; + // The number of 32-bit dwords in the ROM + uint16_t rom_dwords; + // The ROM generation number to send back with ROM read responses + uint32_t rom_generation; + // The xdomain discovery service's UUID in Thunderbolt network order + uint8_t tbt_protocol_uuid[16]; + // The device's UUID in Thunderbolt network order + uint8_t tbt_device_uuid[16]; + + // The route string from the last received xdomain request, used to figure + // out where to send the ROM generation changed packet when a new boot stage + // starts + uint64_t last_route_string; + + // Buffer used to assemble response packets before transmission + uint8_t tx_buffer[TBT_CFG_MAX_HEADER_AND_PAYLOAD]; +}; + +static void tbt_xd_discovery_process_request(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv); +static void tbt_xd_discovery_process_response(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv); +static void tbt_xd_discovery_process_uuid_request(tbt_xd_discovery_t *xdd, const uint8_t *packet, size_t bytes, bool v2); +static void tbt_xd_discovery_process_rom_changed_request(tbt_xd_discovery_t *xdd, const uint8_t *packet, size_t bytes); +static void tbt_xd_discovery_process_rom_read_request(tbt_xd_discovery_t *xdd, const uint8_t *packet, size_t bytes); + +static const uuid_t discovery_uuid = { 0xB638D70E, 0x42FF, 0x40BB, 0x97, 0xC2, { 0x90, 0xE2, 0xC0, 0xB2, 0xFF, 0x07 } }; + +tbt_xd_discovery_t *tbt_xd_discovery_create(tbt_cp_t *cp, const uint32_t *configuration_rom, uint16_t dwords, uint32_t generation) +{ + tbt_xd_discovery_t *xdd; + + xdd = calloc(sizeof(*xdd), 1); + + xdd->control_port = cp; + xdd->rom = configuration_rom; + xdd->rom_dwords = dwords; + xdd->rom_generation = generation; + + uuid_host_to_tbt(&discovery_uuid, xdd->tbt_protocol_uuid); + uuid_host_to_tbt(uuid_get_device_uuid(), xdd->tbt_device_uuid); + + xdd->xd_service_handle = tbt_cp_register_xd_service(cp, tbt_xd_discovery_process_request, tbt_xd_discovery_process_response, xdd); + + return xdd; +} + +void tbt_xd_discovery_quiesce_and_free(tbt_xd_discovery_t *xdd) +{ + tbt_cp_unregister_xd_service(xdd->control_port, xdd->xd_service_handle); + free(xdd); +} + +static void tbt_xd_discovery_process_request(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv) +{ + tbt_xd_discovery_t *xdd = priv; + uint32_t packet_type; + uint64_t route_string; + + // The packet needs to at least be big enough for a protocol UUID and packet type + if (bytes < TBT_XD_REQUEST_HEADER_LEN) { + return; + } + + // Make note of the route string in case we still need to send a ROM changed + // request. We send this request to the last address that sent us an XD request + route_string = tbt_cp_packet_get_route_string(packet); + xdd->last_route_string = route_string & TBT_CFG_ROUTE_STRING_MASK; + + // Now we can check to see if the packet has the discovery protocol's UUID + if (tbt_xd_packet_compare_protocol_uuid(packet, xdd->tbt_protocol_uuid) != 0) + return; + + packet_type = tbt_xd_packet_get_type(packet); + + switch (packet_type) { + case TBT_XD_UUID_REQUEST: + tbt_xd_discovery_process_uuid_request(xdd, packet, bytes, false); + break; + case TBT_XD_ROM_READ_REQUEST: + tbt_xd_discovery_process_rom_read_request(xdd, packet, bytes); + break; + case TBT_XD_ROM_CHANGED_REQUEST: + tbt_xd_discovery_process_rom_changed_request(xdd, packet, bytes); + break; + case TBT_XD_UUID_V2_REQUEST: + tbt_xd_discovery_process_uuid_request(xdd, packet, bytes, true); + break; + } +} + +void tbt_xd_discovery_send_rom_changed_request(tbt_xd_discovery_t *xdd, uint64_t route) +{ + uint8_t *request = xdd->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_REQUEST_PDF; + uint8_t seq; + size_t len; + + memset(request, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + tbt_cp_packet_set_route_string(request, route); + tbt_xd_packet_set_protocol_uuid(request, xdd->tbt_protocol_uuid); + tbt_xd_packet_set_type(request, TBT_XD_ROM_CHANGED_REQUEST); + + tbt_xd_packet_set_payload(request, xdd->tbt_device_uuid, 0, sizeof(xdd->tbt_device_uuid)); + + len = TBT_XD_ROM_CHANGED_REQUEST_LEN; + + seq = tbt_cp_next_pdf_seq(xdd->control_port, pdf); + tbt_xd_packet_set_len(request, len); + tbt_xd_packet_set_seq(request, seq); + + tbt_cp_send(xdd->control_port, pdf, request, len); +} + +static void tbt_xd_discovery_process_response(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv) +{ + uint32_t packet_type; + + packet_type = tbt_xd_packet_get_type(packet); + + switch (packet_type) { + case TBT_XD_ROM_CHANGED_RESPONSE: + break; + case TBT_XD_ERROR_RESPONSE: + break; + } +} + +static void tbt_xd_discovery_process_rom_changed_request(tbt_xd_discovery_t *xdd, const uint8_t *packet, size_t bytes) +{ + uint8_t *response = xdd->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_RESPONSE_PDF; + uint8_t seq; + size_t len; + uint64_t route; + + route = tbt_cp_packet_get_route_string(packet) & TBT_CFG_ROUTE_STRING_MASK; + + memset(response, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + tbt_cp_packet_set_route_string(response, route); + tbt_xd_packet_set_protocol_uuid(response, xdd->tbt_protocol_uuid); + tbt_xd_packet_set_type(response, TBT_XD_ROM_CHANGED_RESPONSE); + + len = TBT_XD_ROM_CHANGED_RESPONSE_LEN; + + seq = tbt_cp_next_pdf_seq(xdd->control_port, pdf); + tbt_xd_packet_set_len(response, len); + tbt_xd_packet_set_seq(response, seq); + + tbt_cp_send(xdd->control_port, pdf, response, len); +} + +static void tbt_xd_discovery_process_uuid_request(tbt_xd_discovery_t *xdd, const uint8_t *packet, size_t bytes, bool v2) +{ + uint8_t *response = xdd->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_RESPONSE_PDF; + uint8_t seq; + size_t len; + uint64_t route; + + route = tbt_cp_packet_get_route_string(packet) & TBT_CFG_ROUTE_STRING_MASK; + + memset(response, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + tbt_cp_packet_set_route_string(response, route); + tbt_xd_packet_set_protocol_uuid(response, xdd->tbt_protocol_uuid); + tbt_xd_packet_set_type(response, TBT_XD_UUID_RESPONSE); + + tbt_xd_packet_set_payload(response, xdd->tbt_device_uuid, 0, sizeof(xdd->tbt_device_uuid)); + + len = TBT_XD_UUID_RESPONSE_LEN; + + if (v2) { + tbt_xd_packet_set_payload_dword(response, route >> 32, sizeof(xdd->tbt_device_uuid)); + tbt_xd_packet_set_payload_dword(response, route, sizeof(xdd->tbt_device_uuid) + 4); + len += 8; + } + + seq = tbt_cp_next_pdf_seq(xdd->control_port, pdf); + tbt_xd_packet_set_len(response, len); + tbt_xd_packet_set_seq(response, seq); + + tbt_cp_send(xdd->control_port, TBT_CFG_XDOMAIN_RESPONSE_PDF, response, len); +} + +static void tbt_xd_discovery_process_rom_read_request(tbt_xd_discovery_t *xdd, const uint8_t *packet, size_t bytes) +{ + uint8_t *response = xdd->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_RESPONSE_PDF; + uint8_t seq; + size_t len; + uint64_t route; + uint8_t host_uuid[16]; + uint32_t offset; + uint16_t response_dwords; + uint32_t offset_and_size; + + if (bytes != TBT_XD_ROM_READ_REQUEST_LEN) { + // XXX: Send error response + return; + } + + route = tbt_cp_packet_get_route_string(packet) & TBT_CFG_ROUTE_STRING_MASK; + offset = tbt_xd_packet_get_payload_dword(packet, 32); + + if (offset >= xdd->rom_dwords) { + // XXX: Send error response + return; + } + + response_dwords = TBT_XD_ROM_READ_RESPONSE_MAX_DATA / 4; + if (xdd->rom_dwords < offset + response_dwords) + response_dwords = xdd->rom_dwords - offset; + + memset(response, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + tbt_cp_packet_set_route_string(response, route); + tbt_xd_packet_set_protocol_uuid(response, xdd->tbt_protocol_uuid); + tbt_xd_packet_set_type(response, TBT_XD_ROM_READ_RESPONSE); + + // Grab the host UUID from the packet, we'll parrot it back in our response + tbt_xd_packet_get_payload(packet, host_uuid, 0, sizeof(host_uuid)); + + // Packet starts with our UUID followed by the host's UUID + tbt_xd_packet_set_payload(response, xdd->tbt_device_uuid, 0, sizeof(xdd->tbt_device_uuid)); + tbt_xd_packet_set_payload(response, host_uuid, 16, sizeof(host_uuid)); + + offset_and_size = offset | (xdd->rom_dwords << 16); + tbt_xd_packet_set_payload_dword(response, offset_and_size, 32); + tbt_xd_packet_set_payload_dword(response, xdd->rom_generation, 36); + + for (int i = 0; i < response_dwords; i++) + tbt_xd_packet_set_payload_dword(response, xdd->rom[offset + i], TBT_XD_ROM_READ_RESPONSE_DATA_OFFSET + i * 4); + + len = TBT_XD_RESPONSE_HEADER_LEN + TBT_XD_ROM_READ_RESPONSE_DATA_OFFSET + 4 * response_dwords; + seq = tbt_cp_next_pdf_seq(xdd->control_port, pdf); + tbt_xd_packet_set_len(response, len); + tbt_xd_packet_set_seq(response, seq); + + tbt_cp_send(xdd->control_port, pdf, response, len); +} + diff --git a/drivers/thunderbolt/tbt_xdomain.h b/drivers/thunderbolt/tbt_xdomain.h new file mode 100644 index 0000000..685a2a7 --- /dev/null +++ b/drivers/thunderbolt/tbt_xdomain.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TBT_XDOMAIN_H +#define TBT_XDOMAIN_H + +#include "tbt_control_port.h" +#include "uuid.h" + +typedef struct tbt_xd_discovery tbt_xd_discovery_t; + +tbt_xd_discovery_t *tbt_xd_discovery_create(tbt_cp_t *cp, const uint32_t *configuration_rom, uint16_t dwords, uint32_t generation); +void tbt_xd_discovery_quiesce_and_free(tbt_xd_discovery_t *xdd); +void tbt_xd_discovery_send_rom_changed_request(tbt_xd_discovery_t *xdd, uint64_t route); + +#endif diff --git a/drivers/thunderbolt/thunderboot.c b/drivers/thunderbolt/thunderboot.c new file mode 100644 index 0000000..95ae417 --- /dev/null +++ b/drivers/thunderbolt/thunderboot.c @@ -0,0 +1,549 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "tbt_control_port.h" +#include "tbt_xdomain.h" +#include "tbt_xd_packet.h" +#include "thunderboot_protocol.h" +#include "uuid.h" + +// We expect the host to be reachable via an xdomain link +// at port 3 of the TBT router connected to the SoC +#define DEFAULT_HOST_ROUTE_STRING (3) + +#if WITH_TBT_MODE_DFU +#define PROTOCOL_SETTINGS (0x00000000) +#else +#define PROTOCOL_SETTINGS (0x00000001) +#endif + +#define TBT_SERVICE_OFFSET (0x22) + +#define XDD_VAL(size) (0x76000000 | (size)) // 'v' - size must be 1, next word has value +#define XDD_TXT(size) (0x74000000 | (size)) // 't' - next word has dword offset +#define XDD_DIR(size) (0x44000000 | (size)) // 'D' - next word has dword offset + +uint32_t TBT_XDP_DEFAULT[] = +{ + 0x55584401, // header + 0x00000018, // size of root directory in dwords + 'vend', 'orid', XDD_VAL(1), 0x00000001, + 'vend', 'orid', XDD_TXT(3), 0x0000001A, + 'devi', 'ceid', XDD_VAL(1), 0x00000001, + 'devi', 'ceid', XDD_TXT(5), 0x0000001D, + 'devi', 'cerv', XDD_VAL(1), 0x00000100, // >0x80000000 is OS + 'indd', 'evp\0', XDD_DIR(24), TBT_SERVICE_OFFSET, + + 'Appl', 'e In', 'c.\0\0', // vendorid text value + 'Appl', 'e Mo', 'bile', ' Dev', 'ice\0', // deviceid text value + + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // UUID placeholder (comes from hash of values below) + 'prtc', 'id\0\0', XDD_VAL(1), 0x00000069, + 'prtc', 'vers', XDD_VAL(1), 0x00000001, + 'prtc', 'revs', XDD_VAL(1), 0x00000000, + 'prtc', 'stns', XDD_VAL(1), PROTOCOL_SETTINGS, + 0xffffffff, 0xffff766e, XDD_TXT(64), 0x0000003A, // USB serial number string pointer (0xffffffxx is vendor-specific range) + + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // USB serial number string placeholder + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +#if APPLICATION_SECUREROM +#define ROM_GENERATION (1) +#elif APPLICATION_IBOOT && (PRODUCT_IBSS || PRODUCT_LLB) +#define ROM_GENERATION (2) +#elif APPLICATION_IBOOT && (PRODUCT_IBOOT) +#define ROM_GENERATION (3) +#elif APPLICATION_IBOOT && (PRODUCT_IBEC) +#define ROM_GENERATION (4) +#else +#error "Unknown Configuration ROM generation" +#endif + +struct thunderboot { + nhi_t *nhi; + tbt_cp_t *cp; + tbt_xd_discovery_t *xdd; + void *xd_service_handle; + + // Buffer for assembling outgoing packets + uint8_t tx_buffer[256]; + + // UUIDs converted to network byte order + uint8_t tbt_protocol_uuid[16]; + uint8_t tbt_device_uuid[16]; + + // handle for iPipe driver (protocol embedded in Thunderboot) + ipipe_t *ipipe; + + bool host_logged_in; + // if the host logged in, the route string of the xdomain link it's on + uint64_t host_route_string; + // host's UUID in network byte order + uint8_t host_uuid[16]; + + struct callout rom_changed_callout; +}; + +static uuid_t thunderboot_protocol_uuid = + { 0xC7C43652, 0xAE71, 0x4577, 0xB2, 0x49, { 0x07, 0xB9, 0xC6, 0xED, 0x40, 0x52 } }; + +static thunderboot_t *g_thunderboot; + +static void thunderboot_handle_xdomain_response(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv); +static void thunderboot_handle_xdomain_request(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv); +static void thunderboot_process_login_request(thunderboot_t *tb, const uint8_t *packet, size_t bytes); +static void thunderboot_process_ping_request(thunderboot_t *tb, const uint8_t *packet, size_t bytes); +static void thunderboot_process_ipipe_request(thunderboot_t *tb, const uint8_t *packet, size_t bytes); +static void thunderboot_send_error_response(thunderboot_t *tb, const uint8_t *packet, uint32_t status); +void thunderboot_ipipe_send(void *priv, const uint8_t *packet, uint32_t bytes); + +thunderboot_t * thunderboot_init(pci_device_t bridge, uint32_t dart_id) +{ + thunderboot_t *tb; + nhi_t *nhi; + const char *serial_number; + const char *more_other; + uint32_t idregs[5]; + uint32_t topology_id[2]; + uint8_t hash[CCSHA1_OUTPUT_SIZE]; + uuid_t service_uuid; + + // Just one thunderboot device allowed right now + ASSERT(g_thunderboot == NULL); + + dprintf(DEBUG_INFO, "thunderboot: initializing\n"); + + nhi = nhi_init(bridge, dart_id); + if (nhi == NULL) { + dprintf(DEBUG_CRITICAL, "thunderboot: couldn't initialize NHI\n"); + return NULL; + } + + tb = calloc(sizeof(*tb), 1); + tb->nhi = nhi; + + // Set up the control port driver and point it at its NHI + tb->cp = tbt_cp_create(tb->nhi); + + if (tbt_cp_read(tb->cp, 0, TBT_CFG_SPACE_DEVICE, 0, 0, idregs, 5)) { + dprintf(DEBUG_INFO, "thunderboot: nhi ID register 0x%x\n", idregs[0]); + } else { + dprintf(DEBUG_CRITICAL, "thunderboot: couldn't read device ID\n"); + goto error; + } + + // The root switch's topology ID is 0. We just need to set it to valid + // so that we can start getting messages + topology_id[1] = 0x80000000U; + topology_id[0] = 0; + if (!tbt_cp_write(tb->cp, 0, TBT_CFG_SPACE_DEVICE, 0, 2, topology_id, 2)) { + dprintf(DEBUG_CRITICAL, "thunderboot: couldn't set topology ID\n"); + goto error; + } + + // Stash some useful UUIDs + uuid_host_to_tbt(&thunderboot_protocol_uuid, tb->tbt_protocol_uuid); + uuid_host_to_tbt(uuid_get_device_uuid(), tb->tbt_device_uuid); + + // Need to fill in runtime details in the xdomain discovery dictionary + serial_number = platform_get_usb_serial_number_string(true); + more_other = platform_get_usb_more_other_string(true); + ASSERT(strlen(serial_number) < 128); + ASSERT(strlen(more_other) < 128); + strlcpy((char *)TBT_XDP_DEFAULT + sizeof(TBT_XDP_DEFAULT) - 256, serial_number, 128); + strlcpy((char *)TBT_XDP_DEFAULT + sizeof(TBT_XDP_DEFAULT) - 256 + strlen(serial_number), more_other, 128); + // strings need to be byte-swapped because... just don't ask + for (size_t i = 0; i < 256 / sizeof(TBT_XDP_DEFAULT[0]); i++) { + size_t offset = (sizeof(TBT_XDP_DEFAULT) - 256) / sizeof(TBT_XDP_DEFAULT[0]) + i; + TBT_XDP_DEFAULT[offset] = htonl(TBT_XDP_DEFAULT[offset]); + } + + // To generate the thunderboot service's UUID, hash the contents of the service directory + sha1_calculate(TBT_XDP_DEFAULT + TBT_SERVICE_OFFSET, sizeof(TBT_XDP_DEFAULT) - 4 * TBT_SERVICE_OFFSET, hash); + uuid_generate_v5(hash, &service_uuid); + memcpy((uint8_t *)(TBT_XDP_DEFAULT + TBT_SERVICE_OFFSET), &service_uuid, sizeof(service_uuid)); + + // route string where we send stuff until we get a login request + tb->host_route_string = DEFAULT_HOST_ROUTE_STRING; + + // Set up the xdomain discovery protocol driver and register is as an xdomain + // packet handler with the control port driver + tb->xdd = tbt_xd_discovery_create(tb->cp, TBT_XDP_DEFAULT, sizeof(TBT_XDP_DEFAULT)/4, ROM_GENERATION); + // Let the host know that they should read our dictionary + tbt_xd_discovery_send_rom_changed_request(tb->xdd, tb->host_route_string); + + // Register ourselves as an xdomain packet handler + tb->xd_service_handle = tbt_cp_register_xd_service(tb->cp, thunderboot_handle_xdomain_request, thunderboot_handle_xdomain_response, tb); + + if (g_thunderboot == NULL) + g_thunderboot = tb; + + // XXX: use the right value here + tb->ipipe = ipipe_init(THUNDERBOOT_SERIAL_REQUEST_MAX_DATA, &thunderboot_ipipe_send, tb); + + dprintf(DEBUG_INFO, "thunderboot: initialized\n"); + + return tb; +error: + thunderboot_quiesce_and_free(tb); + return NULL; +} + +void thunderboot_quiesce_and_free(thunderboot_t *tb) +{ + if (tb == NULL) { + tb = g_thunderboot; + if (tb == NULL) + return; + } + + dprintf(DEBUG_INFO, "thunderboot: quiescing\n"); + + if (tb == g_thunderboot) + g_thunderboot = NULL; + + if (tb->xdd != NULL) + tbt_xd_discovery_quiesce_and_free(tb->xdd); + + if (tb->xd_service_handle != NULL) + tbt_cp_unregister_xd_service(tb->cp, tb->xd_service_handle); + + if (tb->ipipe != NULL) + ipipe_quiesce_and_free(tb->ipipe); + + if (tb->cp != NULL) + tbt_cp_quiesce_and_free(tb->cp); + + if (tb->nhi != NULL) + nhi_quiesce_and_free(tb->nhi); + + free(tb); +} + +static void thunderboot_handle_xdomain_request(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv) +{ + thunderboot_t *tb = priv; + uint32_t packet_type; + + // The packet needs to at least be big enough for a protocol UUID and packet type + if (bytes < THUNDERBOOT_REQUEST_HEADER_LEN) + return; + + // Now we can check to see if the packet has the discovery protocol's UUID + if (tbt_xd_packet_compare_protocol_uuid(packet, tb->tbt_protocol_uuid) != 0) + return; + + packet_type = tbt_xd_packet_get_type(packet); + + if (packet_type != THUNDERBOOT_LOGIN_REQUEST && !tb->host_logged_in) { + dprintf(DEBUG_INFO, "thunderboot: packet received before login\n"); + thunderboot_send_error_response(tb, packet, THUNDERBOOT_STATUS_NOT_LOGGED_IN); + } + + switch (packet_type) { + case THUNDERBOOT_LOGIN_REQUEST: + thunderboot_process_login_request(tb, packet, bytes); + break; + case THUNDERBOOT_PING_REQUEST: + thunderboot_process_ping_request(tb, packet, bytes); + break; + case THUNDERBOOT_IPIPE_REQUEST: + thunderboot_process_ipipe_request(tb, packet, bytes); + break; + default: + thunderboot_send_error_response(tb, packet, THUNDERBOOT_STATUS_UNKNOWN_TYPE); + } +} + +void thunderboot_handle_xdomain_response(tbt_cp_t *cp, const uint8_t *packet, size_t bytes, void *priv) +{ + // Right now we ignore all xdomain responses, but we need to provide + // a handler to the xdomain driver +} + +/* Copies bytes from the packet into the supplied buffer. The offset is relative + * to the first byte after the thunderboot packet type field */ +static void thunderboot_packet_get_payload(const uint8_t *packet, void *buffer, size_t offset, size_t bytes) +{ + size_t xd_offset = offset + THUNDERBOOT_REQUEST_HEADER_LEN - TBT_XD_REQUEST_HEADER_LEN; + tbt_xd_packet_get_payload(packet, buffer, xd_offset, bytes); +} + +/* Copies bytes into the packet from the supplied buffer. The offset is in bytes relative + * to the first byte after the thunderboot packet type field */ +static void thunderboot_packet_set_payload(uint8_t *packet, const void *buffer, size_t offset, size_t bytes) +{ + size_t xd_offset = offset + THUNDERBOOT_REQUEST_HEADER_LEN - TBT_XD_REQUEST_HEADER_LEN; + tbt_xd_packet_set_payload(packet, buffer, xd_offset, bytes); +} + +/* Fetches a 32-bit dword from the packet, converting it from network to host + * byte order. The offset is in bytes relative to the first byte after the + * thunderboot packet type field */ +static uint32_t thunderboot_packet_get_payload_dword(const uint8_t *packet, size_t offset) +{ + uint32_t dword; + thunderboot_packet_get_payload(packet, &dword, offset, 4); + return dword; +} + +/* Sets a 32-bit dword in the packet, converting it to network from host + * byte order. The offset is in bytes relative to the first byte after the + * thunderboot packet type field */ +static void thunderboot_packet_set_payload_dword(uint8_t *packet, uint32_t dword, size_t offset) +{ + thunderboot_packet_set_payload(packet, &dword, offset, 4); +} + +/* Sets a byte in the packet. The offset is in bytes relative to the first byte after the + * thunderboot packet type field */ +static void thunderboot_packet_set_payload_byte(uint8_t *packet, uint8_t byte, size_t offset) +{ + thunderboot_packet_set_payload(packet, &byte, offset, 1); +} + +static void thunderboot_packet_get_sender_uuid(const uint8_t *packet, uint8_t *uuid) +{ + tbt_xd_packet_get_payload(packet, uuid, 0, 16); +} + +static void thunderboot_packet_set_sender_uuid(uint8_t *packet, uint8_t *uuid) +{ + tbt_xd_packet_set_payload(packet, uuid, 0, 16); +} + +static void thunderboot_send_error_response(thunderboot_t *tb, const uint8_t *request, uint32_t status) +{ + uint8_t *packet = tb->tx_buffer; + uint64_t route; + uint8_t pdf = TBT_CFG_XDOMAIN_RESPONSE_PDF; + uint8_t seq; + size_t len; + + route = tbt_cp_packet_get_route_string(request) & TBT_CFG_ROUTE_STRING_MASK; + seq = tbt_xd_packet_get_seq(request); + + memset(packet, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + + tbt_cp_packet_set_route_string(packet, route); + tbt_xd_packet_set_protocol_uuid(packet, tb->tbt_protocol_uuid); + tbt_xd_packet_set_type(packet, THUNDERBOOT_ERROR_RESPONSE); + thunderboot_packet_set_sender_uuid(packet, tb->tbt_device_uuid); + + thunderboot_packet_set_payload_dword(packet, status, 0); + + len = THUNDERBOOT_RESPONSE_HEADER_LEN + 4; + tbt_xd_packet_set_len(packet, len); + tbt_xd_packet_set_seq(packet, seq); + + tbt_cp_send(tb->cp, pdf, packet, len); +} + +static void thunderboot_send_login_response(thunderboot_t *tb, uint64_t route, uint8_t seq, uint32_t status) +{ + uint8_t *packet = tb->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_RESPONSE_PDF; + size_t len; + + memset(packet, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + + tbt_cp_packet_set_route_string(packet, route); + tbt_xd_packet_set_protocol_uuid(packet, tb->tbt_protocol_uuid); + tbt_xd_packet_set_type(packet, THUNDERBOOT_LOGIN_RESPONSE); + thunderboot_packet_set_sender_uuid(packet, tb->tbt_device_uuid); + + thunderboot_packet_set_payload_dword(packet, status, 0); + + len = THUNDERBOOT_RESPONSE_HEADER_LEN + 4; + tbt_xd_packet_set_len(packet, len); + tbt_xd_packet_set_seq(packet, seq); + + tbt_cp_send(tb->cp, pdf, packet, len); +} + +static void thunderboot_process_login_request(thunderboot_t *tb, const uint8_t *packet, size_t bytes) +{ + uint32_t status = THUNDERBOOT_STATUS_OK; + uint64_t route; + uint8_t destination_uuid[16]; + + route = tbt_cp_packet_get_route_string(packet) & TBT_CFG_ROUTE_STRING_MASK; + + if (bytes < THUNDERBOOT_LOGIN_REQUEST_LEN) { + status = THUNDERBOOT_STATUS_MALFORMED; + goto done; + } + + thunderboot_packet_get_payload(packet, destination_uuid, 0, sizeof(destination_uuid)); + + if (memcmp(destination_uuid, tb->tbt_device_uuid, sizeof(destination_uuid)) != 0) { + status = THUNDERBOOT_STATUS_WRONG_UUID; + goto done; + } + + tb->host_route_string = route; + thunderboot_packet_get_sender_uuid(packet, tb->host_uuid); + + if (!tb->host_logged_in) { + tb->host_logged_in = true; + callout_dequeue(&tb->rom_changed_callout); + } + +done: + thunderboot_send_login_response(tb, route, tbt_xd_packet_get_seq(packet), status); + return; +} + +static void thunderboot_send_ping_response(thunderboot_t *tb, uint64_t route, uint8_t seq, uint64_t nonce, uint32_t status) +{ + uint8_t *packet = tb->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_RESPONSE_PDF; + size_t len; + + memset(packet, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + + tbt_cp_packet_set_route_string(packet, route); + tbt_xd_packet_set_protocol_uuid(packet, tb->tbt_protocol_uuid); + tbt_xd_packet_set_type(packet, THUNDERBOOT_PING_RESPONSE); + thunderboot_packet_set_sender_uuid(packet, tb->tbt_device_uuid); + + thunderboot_packet_set_payload_dword(packet, status, 0); + thunderboot_packet_set_payload(packet, &nonce, 4, 8); + + len = THUNDERBOOT_PING_RESPONSE_LEN; + tbt_xd_packet_set_len(packet, len); + tbt_xd_packet_set_seq(packet, seq); + + tbt_cp_send(tb->cp, pdf, packet, len); +} + +static void thunderboot_process_ping_request(thunderboot_t *tb, const uint8_t *packet, size_t bytes) +{ + uint32_t status = THUNDERBOOT_STATUS_OK; + uint64_t route; + uint64_t nonce = 0; + + route = tbt_cp_packet_get_route_string(packet) & TBT_CFG_ROUTE_STRING_MASK; + + if (bytes < THUNDERBOOT_PING_REQUEST_LEN) { + status = THUNDERBOOT_STATUS_MALFORMED; + goto done; + } + + thunderboot_packet_get_payload(packet, &nonce, 0, sizeof(nonce)); + +done: + thunderboot_send_ping_response(tb, route, tbt_xd_packet_get_seq(packet), nonce, status); + return; +} + +static void thunderboot_send_ipipe_response(thunderboot_t *tb, uint64_t route, uint8_t seq, uint32_t status) +{ + uint8_t *packet = tb->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_RESPONSE_PDF; + size_t len; + + memset(packet, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + + tbt_cp_packet_set_route_string(packet, route); + tbt_xd_packet_set_protocol_uuid(packet, tb->tbt_protocol_uuid); + tbt_xd_packet_set_type(packet, THUNDERBOOT_IPIPE_RESPONSE); + thunderboot_packet_set_sender_uuid(packet, tb->tbt_device_uuid); + + thunderboot_packet_set_payload_dword(packet, status, 0); + + len = THUNDERBOOT_RESPONSE_HEADER_LEN + 4; + tbt_xd_packet_set_len(packet, len); + tbt_xd_packet_set_seq(packet, seq); + + tbt_cp_send(tb->cp, pdf, packet, len); +} + +static void thunderboot_process_ipipe_request(thunderboot_t *tb, const uint8_t *packet, size_t bytes) +{ + uint64_t route; + uint32_t payload_size; + const uint8_t *payload; + uint32_t status = THUNDERBOOT_STATUS_OK; + + route = tbt_cp_packet_get_route_string(packet) & TBT_CFG_ROUTE_STRING_MASK; + + if (bytes < THUNDERBOOT_IPIPE_REQUEST_HEADER_LEN) { + status = THUNDERBOOT_STATUS_MALFORMED; + goto done; + } + + payload_size = bytes - THUNDERBOOT_IPIPE_REQUEST_HEADER_LEN; + payload = packet + THUNDERBOOT_IPIPE_REQUEST_HEADER_LEN; + + thunderboot_send_ipipe_response(tb, route, tbt_xd_packet_get_seq(packet), THUNDERBOOT_STATUS_OK); + + ipipe_handle_packet(tb->ipipe, payload, payload_size); + + return; + +done: + thunderboot_send_ipipe_response(tb, route, tbt_xd_packet_get_seq(packet), status); + return; +} + +void thunderboot_ipipe_send(void *priv, const uint8_t *ipipe_packet, uint32_t bytes) +{ + thunderboot_t *tb = (thunderboot_t *)priv; + uint8_t *packet = tb->tx_buffer; + uint8_t pdf = TBT_CFG_XDOMAIN_REQUEST_PDF; + uint8_t seq; + size_t len; + + // XXX: better to queue up serial stuff and not call the send function + // this can be deferred until after the ROM because we don't do serial for the ROM + // Drop packets until the host has logged in + if (!tb->host_logged_in) + return; + + memset(packet, 0, TBT_CFG_MAX_HEADER_AND_PAYLOAD); + + tbt_cp_packet_set_route_string(packet, tb->host_route_string); + tbt_xd_packet_set_protocol_uuid(packet, tb->tbt_protocol_uuid); + tbt_xd_packet_set_type(packet, THUNDERBOOT_IPIPE_REQUEST); + thunderboot_packet_set_sender_uuid(packet, tb->tbt_device_uuid); + + thunderboot_packet_set_payload(packet, ipipe_packet, 0, bytes); + + len = THUNDERBOOT_IPIPE_REQUEST_HEADER_LEN + ((bytes + 3) & ~3); + seq = tbt_cp_next_pdf_seq(tb->cp, pdf); + tbt_xd_packet_set_len(packet, len); + tbt_xd_packet_set_seq(packet, seq); + + tbt_cp_send(tb->cp, pdf, packet, len); +} diff --git a/drivers/thunderbolt/thunderboot_debug.c b/drivers/thunderbolt/thunderboot_debug.c new file mode 100644 index 0000000..0e92b69 --- /dev/null +++ b/drivers/thunderbolt/thunderboot_debug.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + + +//=================================================================================== +// Thunderboot command stuff +//=================================================================================== + +#if defined(WITH_MENU) && WITH_MENU + +#define USB_CMD_STRING_LEN 1024 + +#define USB_SERIAL_CMD_START 0xfc +#define USB_SERIAL_CMD_END 0xfd +#define USB_SERIAL_CMD_START_OFFSET 1 +#define USB_SERIAL_CMD_END_OFFSET 1 +#if WITH_DFU_UPLOAD +#define MAX_NUM_CHAR_IN_INT (12) +#endif // WITH_DFU_UPLOAD + +static u_int8_t usb_cmd_string[USB_CMD_STRING_LEN] __attribute__ ((aligned(CPU_CACHELINE_SIZE))); + +static int tbt_cmd_main(int argc, struct cmd_arg * args); + + +MENU_COMMAND_DEVELOPMENT(tbt, tbt_cmd_main, "run a thunderboot command", NULL); + +static void tbt_print_usage(const char * s) +{ + printf("Usage: \n"); + printf("\t%s get [address] [amount] \n", s); + printf( "\t%s get tftp://servername.com/file.bin [address] [amount] \n", s ); +#if WITH_DFU_UPLOAD + printf( "\t%s put [address] \n", s ); +#endif // WITH_DFU_UPLOAD +} + +static int tbt_cmd_get(int argc, struct cmd_arg *args) +{ + int ret = -1; + + // XXX: We should check to see if a login has happened, and + // fail if not + + const char *prefix = "get "; + const char * fileName = args[0].str; + int notifyHostLen = strlen(prefix) + strlen(fileName) + + USB_SERIAL_CMD_START_OFFSET + USB_SERIAL_CMD_END_OFFSET; + + addr_t address = 0; + uint64_t amount = 0; + + if (notifyHostLen > USB_CMD_STRING_LEN) { + printf("File length too long \n"); + goto error; + } + + if (argc >= 2) { + address = args[1].u; + if(argc >= 3) { + amount = args[2].u; + } + } + + if (address == 0) { + address = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + printf("Defaulting to address %p\n", address); + } + + if (amount > DEFAULT_RAMDISK_SIZE) { + printf("Amount too large \n"); + goto error; + } + + if (amount == 0) { + amount = DEFAULT_RAMDISK_SIZE; + } + + if (!security_allow_memory((void *)address, amount)) { + dprintf(DEBUG_INFO, "Permission Denied\n"); + goto error; + } + + thunderboot_transfer_prepare((void *)address, amount); + bzero((void *)usb_cmd_string, USB_CMD_STRING_LEN); + usb_cmd_string[0] = USB_SERIAL_CMD_START; + memcpy(usb_cmd_string + USB_SERIAL_CMD_START_OFFSET, prefix, strlen(prefix)); + memcpy(usb_cmd_string + USB_SERIAL_CMD_START_OFFSET + strlen(prefix), fileName, + notifyHostLen - USB_SERIAL_CMD_START_OFFSET - USB_SERIAL_CMD_END_OFFSET); + usb_cmd_string[notifyHostLen - 1] = USB_SERIAL_CMD_END; + + ret = thunderboot_serial_send_cmd_string(usb_cmd_string, notifyHostLen); + + if (ret != 0) { + goto error; + } + + ret = thunderboot_transfer_wait(); + + if (ret <= 0) { + goto error; + } + + amount = ret; + + printf("GET complete, amount %d\n", amount); + + // set the file size and return code + env_set_uint("filesize", amount, 0); + + ret = 0; + + return 0; + + error : + printf("GET failed. \n"); + env_set_uint("filesize", 0, 0); + return -1; +} + +static int tbt_cmd_main(int argc, struct cmd_arg *args) +{ + int ret = 0; + const char *s = args[1].str; + + if (s == NULL) { + ret = -1; + } + else { + if (strcmp(s, "get") == 0) { + + if (argc < 3 || argc > 5) { + goto print_usage; + } + + ret = tbt_cmd_get(argc - 2, args + 2); + } +#if 0 && WITH_DFU_UPLOAD + else if(!strcmp(s, "put")) { + + if((argc < 4) || (argc > 5)) { + goto print_usage; + } + + ret = usb_cmd_put(args[2].str, args[3].u, (argc == 5) ? args[4].u : 0, 1); + } +#endif // WITH_DFU_UPLOAD + else { + goto print_usage; + } + } + + return ret; + +print_usage: + tbt_print_usage( args[0].str ); + return 0; + +} + +#endif diff --git a/drivers/thunderbolt/thunderboot_protocol.h b/drivers/thunderbolt/thunderboot_protocol.h new file mode 100644 index 0000000..939e75f --- /dev/null +++ b/drivers/thunderbolt/thunderboot_protocol.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef THUNDERBOOT_PROTOCOL_H +#define THUNDERBOOT_PROTOCOL_H + +#include "tbt_protocol.h" + +#define THUNDERBOOT_LOGIN_REQUEST (1) +#define THUNDERBOOT_LOGIN_RESPONSE (2) +#define THUNDERBOOT_PING_REQUEST (3) +#define THUNDERBOOT_PING_RESPONSE (4) +#define THUNDERBOOT_IPIPE_REQUEST (5) +#define THUNDERBOOT_IPIPE_RESPONSE (6) +#define THUNDERBOOT_ERROR_RESPONSE (255) + +#define THUNDERBOOT_REQUEST_HEADER_LEN (TBT_XD_REQUEST_HEADER_LEN + 16) +#define THUNDERBOOT_RESPONSE_HEADER_LEN (THUNDERBOOT_REQUEST_HEADER_LEN) + +#define THUNDERBOOT_DATA_REQUEST_HEADER_LEN (THUNDERBOOT_REQUEST_HEADER_LEN + 4 + 4) +#define THUNDERBOOT_DATA_REQUEST_MAX_DATA (TBT_CFG_MAX_HEADER_AND_PAYLOAD - THUNDERBOOT_DATA_REQUEST_HEADER_LEN) + +#define THUNDERBOOT_SERIAL_REQUEST_HEADER_LEN (THUNDERBOOT_REQUEST_HEADER_LEN + 4) +#define THUNDERBOOT_SERIAL_REQUEST_MAX_DATA (TBT_CFG_MAX_HEADER_AND_PAYLOAD - THUNDERBOOT_SERIAL_REQUEST_HEADER_LEN) + +#define THUNDERBOOT_IPIPE_REQUEST_HEADER_LEN (THUNDERBOOT_REQUEST_HEADER_LEN) +#define THUNDERBOOT_IPIPE_REQUEST_MAX_DATA (TBT_CFG_MAX_HEADER_AND_PAYLOAD - THUNDERBOOT_IPIPE_REQUEST_HEADER_LEN) + +#define THUNDERBOOT_LOGIN_REQUEST_LEN (THUNDERBOOT_REQUEST_HEADER_LEN + 16) + +#define THUNDERBOOT_PING_REQUEST_LEN (THUNDERBOOT_REQUEST_HEADER_LEN + 8) +#define THUNDERBOOT_PING_RESPONSE_LEN (THUNDERBOOT_PING_REQUEST_LEN + 4 + 8) + +#define THUNDERBOOT_STATUS_OK (0) +#define THUNDERBOOT_STATUS_MALFORMED (1) +#define THUNDERBOOT_STATUS_UNKNOWN_TYPE (2) +#define THUNDERBOOT_STATUS_WRONG_MODE (3) +#define THUNDERBOOT_STATUS_NOT_LOGGED_IN (4) +#define THUNDERBOOT_STATUS_WRONG_UUID (5) + +#endif diff --git a/drivers/thunderbolt/uuid.c b/drivers/thunderbolt/uuid.c new file mode 100644 index 0000000..9a2f225 --- /dev/null +++ b/drivers/thunderbolt/uuid.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include "uuid.h" + +const uuid_t url_namespace_uuid = { 0x6ba7b811, 0x9dad, 0x11d1, 0x80, 0xb4, { 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 } }; + +void uuid_host_to_network(const uuid_t *source, uint8_t *dest) +{ + dest[0] = source->time_low >> 0; + dest[1] = source->time_low >> 8; + dest[2] = source->time_low >> 16; + dest[3] = source->time_low >> 24; + dest[4] = source->time_mid >> 0; + dest[5] = source->time_mid >> 8; + dest[6] = source->time_hi_and_version >> 0; + dest[7] = source->time_hi_and_version >> 8; + dest[8] = source->clock_seq_hi_and_reserved; + dest[9] = source->clock_seq_low; + dest[10] = source->node[0]; + dest[11] = source->node[1]; + dest[12] = source->node[2]; + dest[13] = source->node[3]; + dest[14] = source->node[4]; + dest[15] = source->node[5]; +} + +void uuid_network_to_host(const uint8_t *src, uuid_t *dest) +{ + dest->time_low = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; + dest->time_mid = src[4] << 8 | src[5]; + dest->time_hi_and_version = src[6] << 8 | src[7]; + dest->clock_seq_hi_and_reserved = src[8]; + dest->clock_seq_low = src[9]; + dest->node[0] = src[10]; + dest->node[1] = src[11]; + dest->node[2] = src[12]; + dest->node[3] = src[13]; + dest->node[4] = src[14]; + dest->node[5] = src[15]; +} + +void uuid_host_to_tbt(const uuid_t *source, uint8_t *dest) +{ + uint32_t dword; + + memcpy(dest, (uint8_t *)source, 4); + + memcpy(dest + 6, (uint8_t *)source + 4, 2); + memcpy(dest + 4, (uint8_t *)source + 6, 2); + + memcpy(&dword, (uint8_t *)source + 8, 4); + dword = htonl(dword); + memcpy(dest + 8, &dword, 4); + + memcpy(&dword, (uint8_t *)source + 12, 4); + dword = htonl(dword); + memcpy(dest + 12, &dword, 4); +} + +void uuid_tbt_to_host(const uint8_t *source, uuid_t *dest) +{ + uint32_t dword; + + memcpy((uint8_t *)dest, source, 4); + + memcpy((uint8_t *)dest + 6, source + 4, 2); + memcpy((uint8_t *)dest + 4, source + 6, 2); + + memcpy(&dword, source + 8, 4); + dword = htonl(dword); + memcpy((uint8_t *)dest + 8, &dword, 4); + + memcpy(&dword, source + 12, 4); + dword = htonl(dword); + memcpy((uint8_t *)dest + 12, &dword, 4); +} + +void uuid_generate_v5(const uint8_t *hash, uuid_t *dest) +{ + uuid_network_to_host(hash, dest); + dest->time_hi_and_version &= 0x0FFF; + dest->time_hi_and_version |= 5 << 12; + dest->clock_seq_hi_and_reserved &= 0x3F; + dest->clock_seq_hi_and_reserved |= 0x80; +} + +const uuid_t *uuid_get_device_uuid(void) +{ + uint8_t bytes_to_hash[16 + 33 + 8 + 16 + 1]; + uint8_t hash[CCSHA1_OUTPUT_SIZE]; + char *url; + + static bool uuid_generated = false; + static uuid_t uuid; + + if (!uuid_generated) { + uuid_generated = true; + + uuid_host_to_network(&url_namespace_uuid, bytes_to_hash); + url = (char *)bytes_to_hash + 16; + + const char *format_str = "http://coreos.apple.com/socuuid/%08x/%016llx"; + snprintf(url, sizeof(bytes_to_hash) - 16, format_str, platform_get_chip_id(), platform_get_ecid_id()); + + sha1_calculate(bytes_to_hash, sizeof(bytes_to_hash) - 1, hash); + + uuid_generate_v5(hash, &uuid); + } + + return &uuid; +} + +void uuid_print(const uuid_t *src) +{ + printf("%08x-%04x-%04x-%02x%02x-", src->time_low, src->time_mid, src->time_hi_and_version, + src->clock_seq_hi_and_reserved, src->clock_seq_low); + for (int i = 0; i < 6; i++) + printf("%02x", src->node[i]); +} diff --git a/drivers/thunderbolt/uuid.h b/drivers/thunderbolt/uuid.h new file mode 100644 index 0000000..94c3254 --- /dev/null +++ b/drivers/thunderbolt/uuid.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef UUID_H +#define UUID_H + +typedef struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[6]; +} uuid_t; + +void uuid_host_to_network(const uuid_t *source, uint8_t *dest); +void uuid_network_to_host(const uint8_t *src, uuid_t *dest); +void uuid_host_to_tbt(const uuid_t *source, uint8_t *dest); +void uuid_tbt_to_host(const uint8_t *source, uuid_t *dest); +void uuid_generate_v5(const uint8_t *hash, uuid_t *dest); +const uuid_t *uuid_get_device_uuid(void); +void uuid_print(const uuid_t *src); + +#endif diff --git a/drivers/ti/sn2400/rules.mk b/drivers/ti/sn2400/rules.mk new file mode 100644 index 0000000..cf88b26 --- /dev/null +++ b/drivers/ti/sn2400/rules.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2013 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CHARGER_SN2400=1 \ + WITH_HW_CHARGER_GG_IF=1 \ + WITH_HW_CHARGER=1 + +MODULES += \ + lib/power + +ALL_OBJS += \ + $(LOCAL_DIR)/sn2400.o diff --git a/drivers/ti/sn2400/sn2400.c b/drivers/ti/sn2400/sn2400.c new file mode 100644 index 0000000..535d6d7 --- /dev/null +++ b/drivers/ti/sn2400/sn2400.c @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SN2400_ADDR_R 0xEA +#define SN2400_ADDR_W 0xEB + +static int charger_reset_battery_protection(void); + +enum { + FAULT_LOG = 0x00, + FAULT_LOG_BAT_SHORT = (1 << 0), + + IRQ_1_MASK = 0x01, + IRQ_2_MASK = 0x02, + IRQ_3_MASK = 0x03, + + EVENT_count = 3, + + EVENT_1 = 0x04, + EVENT_1_VBUS_OV = (1 << 7), + EVENT_1_VBUS_UV = (1 << 6), + EVENT_1_VBUS_OC = (1 << 5), + EVENT_1_OVER_TEMP = (1 << 4), + EVENT_1_TEMP_WARNING = (1 << 3), + EVENT_1_BAT_SHORT = (1 << 2), + EVENT_1_MAIN_SHORT = (1 << 1), + EVENT_1_RECOVERY_TIMEOUT = (1 << 0), + + EVENT_2 = 0x05, + EVENT_2_LDO_OCP = (1 << 7), + EVENT_2_BATT_ALERT = (1 << 6), + EVENT_2_MISSING_BATTERY = (1 << 5), + EVENT_2_HDQ_HOST_ALERT = (1 << 4), + EVENT_2_VBUS_VLIM_ACTIVE = (1 << 3), + EVENT_2_ACCUM_OVERFLOW = (1 << 2), + EVENT_2_ADC_DONE = (1 << 1), + EVENT_2_HDQ_INT = (1 << 0), + + EVENT_3 = 0x06, + EVENT_3_MAX_DUTY = (1 << 2), + EVENT_3_ZERO_IBAT = (1 << 1), + EVENT_3_VBUS_DET = (1 << 0), + + SYSTEM_STATE = 0x07, + SYSTEM_STATE_BUCK_EN_STAT = (1 << 7), + SYSTEM_STATE_EXT_OVP_STAT = (1 << 6), + SYSTEM_STATE_VBUS_DET_STAT = (1 << 5), + SYSTEM_STATE_SYS_ALIVE_STAT = (1 << 4), + SYSTEM_STATE_DISCHARGE_BAT_STAT = (1 << 3), + SYSTEM_STATE_IBAT_ZERO = (1 << 2), + SYSTEM_STATE_RECOVERY_STAT = (1 << 1), + SYSTEM_STATE_CHARGE_EN = (1 << 0), + + DC_LIMITER = 0x08, + DC_LIMITER_I_REDUCED = (1 << 6), + DC_LIMITER_BUCK_EN = (1 << 5), + DC_LIMITER_VBUS_LIM = (1 << 4), + DC_LIMITER_ICHG_LIM = (1 << 3), + DC_LIMITER_VBAT_LIM = (1 << 2), + DC_LIMITER_VMAIN_LIM = (1 << 1), + DC_LIMITER_VBUS_VLIM = (1 << 0), + + INPUT_CURRENT_LIMIT = 0x09, + INPUT_CURRENT_LIMIT_base = 90, + INPUT_CURRENT_LIMIT_step = 10, + INPUT_CURRENT_LIMIT_100mA = 0x01, + INPUT_CURRENT_LIMIT_500mA = 0x29, + INPUT_CURRENT_LIMIT_1000mA = 0x5B, + INPUT_CURRENT_LIMIT_1500mA = 0x8D, + INPUT_CURRENT_LIMIT_2000mA = 0xBF, + INPUT_CURRENT_LIMIT_max = INPUT_CURRENT_LIMIT_2000mA, + + POR_INPUT_CURRENT_LIMIT = 0x0A, + ACTUAL_INPUT_CURRENT_LIMIT = 0x0B, + + TARGET_CHARGE_CURRENT = 0x0C, + CHARGE_CURRENT_base = 0, + CHARGE_CURRENT_step = 10, + CHARGE_CURRENT_disabled = 0x00, + CHARGE_CURRENT_10mA = 0x01, + CHARGE_CURRENT_max = 0xFF, + + HOST_CONTROLLED_CHARGE_CURRENT = 0x0D, + ACTUAL_CHARGE_CURRENT = 0x0E, + + TARGET_VOLTAGE_REGULATION = 0x0F, + VOLTAGE_REGULATION_base = 3000, + VOLTAGE_REGULATION_step = 10, + VOLTAGE_REGULATION_3000mV = 0x00, + VOLTAGE_REGULATION_4200mV = 0x78, + VOLTAGE_REGULATION_4300mV = 0x82, + VOLTAGE_REGULATION_4500mV = 0x96, + VOLTAGE_REGULATION_max = VOLTAGE_REGULATION_4500mV, + + CONTROL = 0x10, + CONTROL_EN_ADAPTER_HS = (1 << 4), + CONTROL_USB_SUSP = (1 << 3), + CONTROL_VBUS_IMIL_SEL = (1 << 2), + CONTROL_BUCK_FREQ_SHIFT_mask = (3 << 0), + CONTROL_BUCK_FREQ_SHIFT_normal = (0 << 0), + CONTROL_BUCK_FREQ_SHIFT_plus_150 = (1 << 0), + CONTROL_BUCK_FREQ_SHIFT_minus_150 = (2 << 0), + CONTROL_BUCK_FREQ_SHIFT_spread = (3 << 0), + + ADC_CONTROL = 0x11, + ADC_CONTROL_MANUAL_START = (1 << 4), + ADC_CONTROL_CHANNEL_mask = (7 << 1), + ADC_CONTROL_CHANNEL_vbus = (0 << 1), + ADC_CONTROL_CHANNEL_ibus = (1 << 1), + ADC_CONTROL_CHANNEL_ibat = (2 << 1), + ADC_CONTROL_CHANNEL_vdd_main = (3 << 1), + ADC_CONTROL_CHANNEL_die_temp = (4 << 1), + ADC_CONTROL_CHANNEL_vbat = (5 << 1), + ADC_CONTROL_ACCUM_RESET = (1 << 0), + + ADC_OUTPUT = 0x12, + IBUS_AUTO = 0x13, + VBUS_AUTO = 0x14, + + ADC_IBUS_ACCUMULATION_3 = 0x15, + ADC_IBUS_ACCUMULATION_2 = 0x16, + ADC_IBUS_ACCUMULATION_1 = 0x17, + ADC_VBUS_ACCUMULATION_3 = 0x18, + ADC_VBUS_ACCUMULATION_2 = 0x19, + ADC_VBUS_ACCUMULATION_1 = 0x1A, + SAMPLE_COUNT_2 = 0x1B, + SAMPLE_COUNT_1 = 0x1C, + + HDQ_INTERFACE = 0x1D, + HDQ_INTERFACE_HDQ_MSTR_mask = (3 << 6), + HDQ_INTERFACE_HDQ_MSTR_none = (3 << 6), + HDQ_INTERFACE_HDQ_MSTR_charger = (3 << 6), + HDQ_INTERFACE_HDQ_MSTR_host = (3 << 6), + HDQ_INTERFACE_HDQ_MSTR_bmu = (3 << 6), + HDQ_INTERFACE_HDQ_HOST_EN = (1 << 5), + HDQ_INTERFACE_MISSING_BATTERY = (1 << 4), + HDQ_INTERFACE_MSTR_REQ_CHGR = (1 << 3), + HDQ_INTERFACE_MSTR_REQ_HOST = (1 << 2), + HDQ_INTERFACE_MSTR_REQ_BMU = (1 << 1), + HDQ_INTERFACE_MSTR_FORCE_HOST = (1 << 0), + + TEST_MODE_ENABLE = 0x20, + TEST_MODE_ENABLE_off = 0x00, + TEST_MODE_ENABLE_on = 0xA5, + + TEST_MODE_CONTROL = 0x21, + TEST_MODE_CONTROL_ENB_AUTOCONV = (1 << 5), + TEST_MODE_CONTROL_EN_FORCEMODE = (1 << 4), + TEST_MODE_CONTROL_FORCE_MODE_mask = (3 << 2), + TEST_MODE_CONTROL_FORCE_MODE_stdby = (0 << 2), + TEST_MODE_CONTROL_FORCE_MODE_chgdis = (1 << 2), + TEST_MODE_CONTROL_FORCE_MODE_recov = (2 << 2), + TEST_MODE_CONTROL_FORCE_MODE_normal = (3 << 2), + TEST_MODE_CONTROL_GG_DIS = (1 << 1), + TEST_MODE_CONTROL_SOFT_RESET = (1 << 0), +}; + +static int charger_write(uint8_t reg, uint8_t value) +{ + uint8_t data[2] = { reg, value }; + return iic_write(CHARGER_IIC_BUS, SN2400_ADDR_W, data, sizeof(data)); +} + +static int charger_read(uint8_t reg, uint8_t *data) +{ + return iic_read(CHARGER_IIC_BUS, SN2400_ADDR_R, ®, sizeof(reg), data, sizeof(uint8_t), IIC_NORMAL); +} + +static int charger_readn(uint8_t reg, uint8_t *data, unsigned int count) +{ + return iic_read(CHARGER_IIC_BUS, SN2400_ADDR_R, ®, sizeof(reg), data, count, IIC_NORMAL); +} + +static int charger_read_events(uint8_t data[EVENT_count]) +{ + uint8_t reg = EVENT_1; + return iic_read(CHARGER_IIC_BUS, SN2400_ADDR_R, ®, sizeof(reg), data, EVENT_count, IIC_NORMAL); +} + +static int charger_read_adc(uint8_t channel, uint8_t *result) +{ + uint8_t data = ADC_CONTROL_MANUAL_START | (channel & ADC_CONTROL_CHANNEL_mask); + if (charger_write(ADC_CONTROL, data) != 0) return -1; + + do { + task_sleep(5 * 1000); // data sheet lists 3.7 ms as typ. average time + if (charger_read(ADC_CONTROL, &data) != 0) return -1; + } while (data & ADC_CONTROL_MANUAL_START); + + return charger_read(ADC_OUTPUT, result); +} + +void charger_early_init(void) +{ + // clear any events + uint8_t events[EVENT_count]; + charger_read_events(events); + +#if TARGET_POWER_NEEDS_BATTERY_PROTECTION_RESET && PRODUCT_LLB + // check status for recovery mode + uint8_t data; + if (charger_read(SYSTEM_STATE, &data) == 0) { + dprintf(DEBUG_INFO, "sn2400 : 0x07=%02x\n", data); + if ((data & SYSTEM_STATE_RECOVERY_STAT) != 0) { + charger_reset_battery_protection(); + } + } +#endif +} + +void charger_clear_alternate_usb_current_limit(void) +{ + uint8_t data; + charger_read(CONTROL, &data); + data |= CONTROL_VBUS_IMIL_SEL; + charger_write(CONTROL, data); +} + +bool charger_has_usb(int dock) +{ + uint8_t data; + charger_read(SYSTEM_STATE, &data); + return data & SYSTEM_STATE_VBUS_DET_STAT; +} + +bool charger_has_firewire(int dock) +{ + return false; // FW not supported +} + +bool charger_has_external(int dock) +{ + return false; // Ext. not supported +} + +bool charger_check_usb_change(int dock, bool expected) +{ + uint8_t events[EVENT_count]; + if (charger_read_events(events) != 0) return false; + + if (events[0] & (EVENT_1_VBUS_UV | EVENT_1_VBUS_OV)) return true; + if (events[2] & (EVENT_3_VBUS_DET)) return true; + + return false; +} + +// CBAT, maybe next... +static uint8_t sn2400_adjust_iset(uint32_t iset) +{ + if ( iset==0 ) { + // leave it + } else if ( iset<3 ) { + iset=1; + } else if ( iset (CHARGE_CURRENT_base + (CHARGE_CURRENT_max * CHARGE_CURRENT_step))) { + charge_current = CHARGE_CURRENT_max; + } else { + charge_current = (*charge_current_ma - CHARGE_CURRENT_base) / CHARGE_CURRENT_step; + } + + *charge_current_ma -= CHARGE_CURRENT_base + (charge_current * CHARGE_CURRENT_step); + charger_write(HOST_CONTROLLED_CHARGE_CURRENT, charge_current ) ; + + if (input_current_ma < 100) { + charger_write(INPUT_CURRENT_LIMIT, INPUT_CURRENT_LIMIT_100mA); + + uint8_t data; + if (charger_read(CONTROL, &data) != 0) return; + data |= CONTROL_USB_SUSP; + charger_write(CONTROL, data); + } else { + uint8_t data; + if (charger_read(CONTROL, &data) != 0) return; + if (data & CONTROL_USB_SUSP) { + data &= ~CONTROL_USB_SUSP; + charger_write(CONTROL, data); + + task_sleep(100 * 1000); + } + + if (charger_read(ACTUAL_INPUT_CURRENT_LIMIT, &data) != 0) return; + + uint8_t input_current_limit; + if (input_current_ma > (INPUT_CURRENT_LIMIT_base + (INPUT_CURRENT_LIMIT_max * INPUT_CURRENT_LIMIT_step))) { + input_current_limit = INPUT_CURRENT_LIMIT_max; + } else { + input_current_limit = (input_current_ma - INPUT_CURRENT_LIMIT_base) / INPUT_CURRENT_LIMIT_step; + } + + while (data < input_current_limit) { + data += (100 / INPUT_CURRENT_LIMIT_step); + if (data > input_current_limit) data = input_current_limit; + charger_write(INPUT_CURRENT_LIMIT, sn2400_adjust_iset(data) ); + task_sleep(10 * 1000); + } + } +} + +void charger_clear_usb_state(void) +{ + // empty +} + +bool charger_charge_done(int dock) +{ + uint8_t data; + if (charger_read(SYSTEM_STATE, &data) != 0) return false; + return !(data & SYSTEM_STATE_CHARGE_EN); +} + +bool charger_has_batterypack(int dock) +{ + return true; +} + +uint32_t charger_get_max_charge_current(int dock) +{ + return CHARGE_CURRENT_base + (CHARGE_CURRENT_max * CHARGE_CURRENT_step); +} + +int charger_read_battery_level(uint32_t *milliVolts) +{ + uint8_t adc; + if (charger_read_adc(ADC_CONTROL_CHANNEL_vbat, &adc) != 0) return -1; + *milliVolts = 2500 + (10 * adc); + return 0; +} + +int charger_set_gasgauge_interface(bool enabled) +{ + if (enabled) { + if (charger_write(HDQ_INTERFACE, HDQ_INTERFACE_MSTR_REQ_HOST) != 0) return -1; + + utime_t timeout = system_time() + 1*1000*1000; + for (;;) { + uint8_t data; + if (charger_read(HDQ_INTERFACE, &data) != 0) { + charger_write(HDQ_INTERFACE, 0); + return -1; + } + if (data & HDQ_INTERFACE_HDQ_HOST_EN) break; + if (system_time() > timeout) { + printf("charger HDQ interface request read timed out\n"); + return (-1); + } + task_sleep(10 * 1000); + } + } else { + charger_write(HDQ_INTERFACE, 0); + } + return 0; +} + +int charger_reset_battery_protection(void) +{ + // enter test mode and force charging at 4.3V VBATREG and 10mA + // charging current for 20mS + int ret, ret2; + + dprintf(DEBUG_CRITICAL, "starting battery protection reset...\n"); + // check all PMU temp sensors for "ambient temperature" check + for (int idx = 1; idx <= 4; idx++) { + int temp_cC; + ret = pmu_read_system_temperature(idx, &temp_cC); + if (ret != 0) { + dprintf(DEBUG_CRITICAL, "temp failure\n"); + return -1; + } + if (temp_cC <= 500 || temp_cC >= 4000) { + dprintf(DEBUG_CRITICAL, "system temp %d out of range: %d.%02dC\n", idx, temp_cC / 100, temp_cC % 100); + return -1; + } + } + + ret = charger_write(HOST_CONTROLLED_CHARGE_CURRENT, CHARGE_CURRENT_10mA); + if (ret == 0) ret = charger_write(TEST_MODE_ENABLE, TEST_MODE_ENABLE_on); + if (ret == 0) ret = charger_write(TEST_MODE_CONTROL, TEST_MODE_CONTROL_GG_DIS); + if (ret == 0) ret = charger_write(TARGET_CHARGE_CURRENT, CHARGE_CURRENT_disabled); + if (ret == 0) ret = charger_write(TARGET_VOLTAGE_REGULATION, VOLTAGE_REGULATION_4300mV); + if (ret == 0) ret = charger_write(TARGET_CHARGE_CURRENT, CHARGE_CURRENT_10mA); + + task_sleep(20 * 1000); + + if (ret == 0) ret = charger_write(TARGET_CHARGE_CURRENT, CHARGE_CURRENT_disabled); + if (ret == 0) ret = charger_write(TARGET_VOLTAGE_REGULATION, VOLTAGE_REGULATION_4200mV); + if (ret == 0) ret = charger_write(TEST_MODE_CONTROL, 0x00); + // always attempt to take out of test mode, even on failure + ret2 = charger_write(TEST_MODE_ENABLE, TEST_MODE_ENABLE_off); + if (ret == 0) ret = ret2; + if (ret == 0) ret = charger_write(HOST_CONTROLLED_CHARGE_CURRENT, CHARGE_CURRENT_max); + + dprintf(DEBUG_CRITICAL, "battery protection reset completed: %s\n", (ret == 0) ? "success" : "error"); + + return ret; +} + +void charger_print_status(void) +{ + int rc; + uint8_t data[7]; + + rc=charger_readn(SYSTEM_STATE, data, 2); + if ( rc!=0 ) { + dprintf(DEBUG_CRITICAL, "cannot read %x (%d)\n", SYSTEM_STATE, rc); + } else { + rc=charger_readn(ACTUAL_INPUT_CURRENT_LIMIT, &data[2], 5); + if ( rc!=0 ) { + dprintf(DEBUG_CRITICAL, "cannot read %x (%d)\n", ACTUAL_INPUT_CURRENT_LIMIT, rc); + } else { + dprintf(DEBUG_CRITICAL, "sn2400 : 0x07=%02x 0x08=%02x 0x0b=%02x 0x0c=%02x 0x0d=%02x 0x0e=%02x 0x0f=%02x\n", + data[0], data[1], data[2], data[3], data[4], data[5], data[6]); + } + } +} diff --git a/drivers/ti/ths7383/rules.mk b/drivers/ti/ths7383/rules.mk new file mode 100644 index 0000000..c42c432 --- /dev/null +++ b/drivers/ti/ths7383/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2011 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_TRISTAR_THS7383=1 \ + WITH_HW_TRISTAR=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/ths7383.o diff --git a/drivers/ti/ths7383/ths7383.c b/drivers/ti/ths7383/ths7383.c new file mode 100644 index 0000000..4e9499a --- /dev/null +++ b/drivers/ti/ths7383/ths7383.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define THS7383_ADDR_R 0x35 +#define THS7383_ADDR_W 0x34 + +enum { + DXCTRL = 0x01, + DXCTRL_DX2OVRD = (1 << 7), + DXCTRL_DPDN2SW_mask = (7 << 4), + DXCTRL_DPDN2SW_open = (0 << 4), + DXCTRL_DPDN2SW_usb0 = (1 << 4), + DXCTRL_DPDN2SW_uart0 = (2 << 4), + DXCTRL_DPDN2SW_dig = (3 << 4), + DXCTRL_DPDN2SW_brick_id_p = (4 << 4), + DXCTRL_DPDN2SW_brick_id_n = (5 << 4), + DXCTRL_DPDN2SW_uart2 = (6 << 4), + DXCTRL_DPDN2SW_uart1 = (7 << 4), + DXCTRL_DX1OVRD = (1 << 3), + DXCTRL_DPDN1SW_mask = (7 << 0), + DXCTRL_DPDN1SW_open = (0 << 0), + DXCTRL_DPDN1SW_usb0 = (1 << 0), + DXCTRL_DPDN1SW_uart0 = (2 << 0), + DXCTRL_DPDN1SW_dig = (3 << 0), + DXCTRL_DPDN1SW_brick_id_p = (4 << 0), + DXCTRL_DPDN1SW_brick_id_n = (5 << 0), + DXCTRL_DPDN1SW_usb1 = (6 << 0), + DXCTRL_DPDN1SW_jtag = (7 << 0), + + ACC_CTRL = 0x02, + ACC_CTRL_ACC2OVRD = (1 << 5), + ACC_CTRL_ACC2SW_mask = (3 << 3), + ACC_CTRL_ACC2SW_open = (0 << 3), + ACC_CTRL_ACC2SW_uart1_tx = (1 << 3), + ACC_CTRL_ACC2SW_jtag_clk = (2 << 3), + ACC_CTRL_ACC2SW_acc_pwr = (3 << 3), + ACC_CTRL_ACC1OVRD = (1 << 2), + ACC_CTRL_ACC1SW_mask = (3 << 0), + ACC_CTRL_ACC1SW_open = (0 << 0), + ACC_CTRL_ACC1SW_uart1_rx = (1 << 0), + ACC_CTRL_ACC1SW_jtag_dio = (2 << 0), + ACC_CTRL_ACC1SW_acc_pwr = (3 << 0), + + DCP_CTRL = 0x03, + DCP_CTRL_IDXSINKEN = (1 << 3), + DCP_CTRL_VDXSRCSW_mask = (7 << 0), + DCP_CTRL_VDXSRCSW_off = (0 << 0), + DCP_CTRL_VDXSRCSW_dp1 = (1 << 0), + DCP_CTRL_VDXSRCSW_dn1 = (2 << 0), + DCP_CTRL_VDXSRCSW_dp2 = (3 << 0), + DCP_CTRL_VDXSRCSW_dn2 = (4 << 0), + + MISC_CTRL = 0x05, + MISC_CTRL_IDBUS_RESET = (1 << 3), + MISC_CTRL_IDBUS_BREAK = (1 << 2), + MISC_CTRL_IDBUS_REORIENT = (1 << 1), + MISC_CTRL_IDBUS_P_INSINK_EN = (1 << 0), + + DIG_ID = 0x06, + DIG_ID_Dx1 = (1 << 3), + DIG_ID_Dx0 = (1 << 2), + DIG_ID_ACCx1 = (1 << 1), + DIG_ID_ACCx0 = (1 << 0), + + STATUS1 = 0x0B, + STATUS1_CMD_PEND = (1 << 0), + + STATUS0 = 0x0C, + STATUS0_IDBUS_CONNECTED = (1 << 7), + STATUS0_IDBUS_ORIENT = (1 << 6), + STATUS0_SWITCH_EN = (1 << 5), + STATUS0_HOST_RESET = (1 << 4), + STATUS0_OVP_SW = (1 << 3), + STATUS0_CON_DET_L = (1 << 2), + STATUS0_P_IN_STAT_mask = (3 << 0), + STATUS0_P_IN_STAT_brownout = (0 << 0), + STATUS0_P_IN_STAT_maintain = (1 << 0), + STATUS0_P_IN_STAT_ovp = (2 << 0), + STATUS0_P_IN_STAT_insdet = (3 << 0), + + EVENT = 0x0D, + EVENT_CRC_ERR = (1 << 5), + EVENT_RESP_VALID = (1 << 4), + EVENT_DIGITAL_ID = (1 << 3), + EVENT_CON_DET_L = (1 << 2), + EVENT_IDBUS_WAKE = (1 << 1), + EVENT_P_IN = (1 << 0), + + MASK = 0x0E, + MASK_CRC_ERR = (1 << 5), + MASK_RESP_VALID = (1 << 4), + MASK_DIGITAL_ID = (1 << 3), + MASK_CON_DET_L = (1 << 2), + MASK_IDBUS_WAKE = (1 << 1), + MASK_P_IN = (1 << 0), + + REV = 0x0F, + REV_VENDOR_ID_shift = (6), + REV_VENDOR_ID_mask = (3 << REV_VENDOR_ID_shift), + REV_VENDOR_ID_ti = (1 << REV_VENDOR_ID_shift), + REV_BASE_VER_shift = (3), + REV_BASE_VER_mask = (7 << REV_BASE_VER_shift), + REV_METAL_VER_shift = (0), + REV_METAL_VER_mask = (7 << REV_METAL_VER_shift), + + FIFO0 = 0x20, + FIFO31 = 0x3F, + FIFO_LEN = (FIFO31 - FIFO0 + 1), + + FIFO_CTRL0 = 0x40, + FIFO_CTRL0_CMD_LENGTH_shift = 1, + FIFO_CTRL0_CMD_LENGTH_mask = (31 << FIFO_CTRL0_CMD_LENGTH_shift), + FIFO_CTRL0_AID_CMD_SEND = (1 << 0), + + FIFO_CTRL1 = 0x41, + FIFO_CTRL1_RESP_LENGTH_shift = 1, + FIFO_CTRL1_RESP_LENGTH_mask = (31 << FIFO_CTRL1_RESP_LENGTH_shift), + FIFO_CTRL1_CMD_KILL = (1 << 0), + + VENDOR50 = 0x50, + VENDORFF = 0xFF, +}; + +static int tristar_write(uint8_t reg, uint8_t value) +{ + uint8_t data[2] = { reg, value }; + return iic_write(TRISTAR_IIC_BUS, THS7383_ADDR_W, data, sizeof(data)); +} + +static int tristar_read(uint8_t reg, uint8_t *data) +{ + return iic_read(TRISTAR_IIC_BUS, THS7383_ADDR_R, ®, sizeof(reg), data, sizeof(uint8_t), IIC_NORMAL); +} + +bool ths7383_set_usb_brick_detect(int select) +{ + // check status to make sure cable is connected and determine orientation + uint8_t status; + if (tristar_read(STATUS0, &status) != 0) { + return false; + } + if ((status & STATUS0_CON_DET_L) || !(status & STATUS0_IDBUS_CONNECTED)) { + return false; + } + bool orient = (status & STATUS0_IDBUS_ORIENT) == STATUS0_IDBUS_ORIENT; + + // check ID to find out if USB is supported + uint8_t dig_id; + if (tristar_read(DIG_ID, &dig_id) != 0) { + return false; + } + // only Dx=1 or Dx=2 have USB device mode + if (((dig_id & DIG_ID_Dx0) != 0) == ((dig_id & DIG_ID_Dx1) != 0)) { + return false; + } + + uint8_t dxctrl; + uint8_t dcp_ctrl; + + switch (select) { + case kUSB_DP: + case kUSB_CP2: + dxctrl = orient ? (DXCTRL_DX2OVRD | DXCTRL_DPDN2SW_brick_id_p) : (DXCTRL_DX1OVRD | DXCTRL_DPDN1SW_brick_id_p); + break; + + case kUSB_DM: + case kUSB_CP1: + dxctrl = orient ? (DXCTRL_DX2OVRD | DXCTRL_DPDN2SW_brick_id_n) : (DXCTRL_DX1OVRD | DXCTRL_DPDN1SW_brick_id_n); + break; + + case kUSB_NONE: + dxctrl = 0; + break; + + default: + return false; + } + + if (select == kUSB_CP1) { + dcp_ctrl = DCP_CTRL_IDXSINKEN | (orient ? DCP_CTRL_VDXSRCSW_dp2 : DCP_CTRL_VDXSRCSW_dp1); + } else if (select == kUSB_CP2) { + dcp_ctrl = DCP_CTRL_IDXSINKEN | (orient ? DCP_CTRL_VDXSRCSW_dn2 : DCP_CTRL_VDXSRCSW_dn1); + } else { + dcp_ctrl = 0; + } + + tristar_write(DCP_CTRL, dcp_ctrl); + tristar_write(DXCTRL, dxctrl); + + return true; +} + +bool ths7383_read_id(uint8_t digital_id[6]) +{ + // check status to make sure cable is connected and ID bus is connected + uint8_t status; + if (tristar_read(STATUS0, &status) != 0) { + return false; + } + if ((status & STATUS0_CON_DET_L) || !(status & STATUS0_IDBUS_CONNECTED)) { + return false; + } + + // FIFO should contain the ID response + uint8_t resp; + if (tristar_read(FIFO31, &resp) != 0) { + return false; + } + + // work around 10170313 + if (resp != 0x75) { + tristar_write(MISC_CTRL, MISC_CTRL_IDBUS_REORIENT); + task_sleep(100 * 1000); + tristar_read(FIFO31, &resp); + } + + if (resp != 0x75) { + return false; + } + + // read ID and flip order + for (int i = 0; i < 6; i++) { + if (tristar_read(FIFO31-(i+1), &digital_id[i])) { + return false; + } + } + + return true; +} + +bool ths7383_enable_acc_pwr(bool enabled) +{ + if (enabled) { + tristar_write(ACC_CTRL, ACC_CTRL_ACC2SW_acc_pwr | ACC_CTRL_ACC1SW_acc_pwr); + } + + power_enable_ldo(ACC_PWR_LDO, enabled); + + if (!enabled) { + tristar_write(ACC_CTRL, 0); + } + + return true; +} + +#if !WITH_HW_TRISTAR_CBTL1610 +bool tristar_set_usb_brick_detect(int select) +{ + return ths7383_set_usb_brick_detect(select); +} + +bool tristar_read_id(uint8_t digital_id[6]) +{ + return ths7383_read_id(digital_id); +} + +bool tristar_enable_acc_pwr(bool enabled) +{ + return ths7383_enable_acc_pwr(enabled); +} +#endif // WITH_HW_TRISTAR_CBTL1610 diff --git a/drivers/uart/16x50/16x50.c b/drivers/uart/16x50/16x50.c new file mode 100644 index 0000000..ecc2340 --- /dev/null +++ b/drivers/uart/16x50/16x50.c @@ -0,0 +1,139 @@ +/* -*- tab-width: 8; Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*- + * + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include + +#include "16x50.h" + +static const uint32_t uart_ports[] = { +#ifdef UART0_BASE_ADDR + UART0_BASE_ADDR, +# ifdef UART1_BASE_ADDR + UART1_BASE_ADDR, +# endif +#else +# error No UARTs configured +#endif +}; + +/* + * uart_hw_init + * + * Initialise the port for the requested baudrate. + */ +int +uart_hw_init(uint32_t port, uint32_t baudrate) +{ + return(uart_hw_init_extended(port, baudrate, 8, PARITY_NONE, 1)); +} + +int +uart_hw_init_extended(uint32_t port, + uint32_t baudrate, + uint32_t databits, + enum uart_parity parity, + uint32_t stopbits) +{ + uint32_t divisor; + uint8_t rv; + + /* wait for the UART to be idle before talking to it */ + while (!(rLSR(port) & LSR_THRE)) + ; + + /* this can happen if the plaform defines more ports than the target */ + if (port >= sizeof(uart_ports) / sizeof(uart_ports[0])) + return(-1); + + /* disable interrupts, we poll */ + rIER(port) = 0; + + /* compute LCR */ + rv = LCR_WLS_8; + switch(parity) { + case PARITY_EVEN: + rv |= LCR_PEN | LCR_EPS; + break; + case PARITY_ODD: + rv |= LCR_PEN; + break; + default: + break; + } + switch(stopbits) { + default: + case 1: + rv |= LCR_1_STB; + break; + case 2: + rv |= LCR_2_STB; + break; + } + + divisor = clock_get_frequency(CLK_UART) / (baudrate * 16); + rLCR(port) = rv | LCR_DLAB; /* enable the divisor latch */ + rDLL(port) = divisor & 0xff; + rDLM(port) = (divisor >> 8) & 0xff; + rLCR(port) = rv; /* disable the divisor latch */ + + /* reset & re-enble FIFO with trigger at 1 byte */ + rFCR(port) = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR | FCR_TL1; + + return(0); +} + +int +uart_hw_set_rx_buf(uint32_t port, bool interrupt, size_t buffer_len) +{ + /* optional interface not implemented */ + return -1; +} + +/* + * uart_hw_getc + * + * Get a byte from the port. Returns -1 if there isn't one ready. + */ +int +uart_hw_getc(uint32_t port) +{ + ASSERT((unsigned)port < (sizeof(uart_ports) / sizeof(uart_ports[0]))); + + /* if data ready, return it */ + if (rLSR(port) & LSR_DR) + return(rRBR(port)); + return(-1); +} + +/* + * uart_hw_putc + * + * Write a byte to the port. + */ +int +uart_hw_putc(uint32_t port, char c) +{ + + ASSERT((unsigned)port < (sizeof(uart_ports) / sizeof(uart_ports[0]))); + + /* if we can send the byte, do it */ + if (rLSR(port) & LSR_THRE) { + rTHR(port) = c; + return(0); + } + + /* can't send now, caller will yield and retry */ + return(-1); +} diff --git a/drivers/uart/16x50/16x50.h b/drivers/uart/16x50/16x50.h new file mode 100644 index 0000000..ececf3e --- /dev/null +++ b/drivers/uart/16x50/16x50.h @@ -0,0 +1,95 @@ +/* -*- tab-width: 8; Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*- + * + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +/* + * Register layout for a memory-mapped 16x50-style UART. + * + * Register and bit names/definitions from the National Semiconductor PC16550D datasheet. + * + * Note that the register set described here is a subset containing just those registers + * useful for the iBoot environment. In particular, no modem support registers/definitions + * are included. + */ + +#ifndef __UART_16x50_H +#define __UART_16x50_H + +/* allow an override of the spacing between registers */ +#ifndef UART16x50_REGISTER_STRIDE +# define UART16x50_REGISTER_STRIDE 4 +#endif + +/* allow an override of the datatype used for reading/writing the registers */ +#ifndef UART16x50_REGISTER_TYPE +# define UART16x50_REGISTER_TYPE uint32_t +#endif + +/* produce a pointer to a UART register, assuming base registers in uart_ports */ +#define UART_REG(_port, _offset) \ + (*(volatile UART16x50_REGISTER_TYPE *)((uint8_t *)uart_ports[(_port)] + ((_offset) * UART16x50_REGISTER_STRIDE))) + +// +// UART Registers for UART _port +// +#define rRBR(_port) UART_REG(_port, 0) // receiver buffer register (RO) +#define rTHR(_port) UART_REG(_port, 0) // transmitter holding register (WO) +#define rIER(_port) UART_REG(_port, 1) // interrupt enable register +#define rIIR(_port) UART_REG(_port, 2) // interrupt ident. register (RO) +#define rFCR(_port) UART_REG(_port, 2) // FIFO control register (WO) +#define rLCR(_port) UART_REG(_port, 3) // line control register +#define rLSR(_port) UART_REG(_port, 5) // line status register +#define rDLL(_port) UART_REG(_port, 0) // divisor latch (LS) +#define rDLM(_port) UART_REG(_port, 1) // divisor latch (MS) + +// IER +#define IER_ERBFI (1<<0) // enable received data available interrupt +#define IER_ETBEI (1<<1) // enable transmit holding register empty interrupt +#define IER_ELSI (1<<2) // enable receiver line status interrupt + +// IIR +#define IIR_NOTPEND (1<<0) // interrupt not pending +#define IIR_IID_MASK 0xe // interrupt pending/ID mask +#define IIR_IID_THRE 0x2 // transmitter holding register empty +#define IIR_IID_RBF 0x4 // received data available +#define IIR_IID_LSR 0x6 // receiver line status +#define IIR_IID_CTI 0xc // character timeout indication + +// FCR +#define FCR_FIFO_EN (1<<0) // FIFO enable +#define FCR_RXSR (1<<1) // reciever fifo reset +#define FCR_TXSR (1<<2) // transmitter fifo reset +#define FCR_TL1 (0<<6) // RCVR FIFO trigger level - 1 byte +#define FCR_TL4 (1<<6) // 4 bytes +#define FCR_TL8 (2<<6) // 8 bytes +#define FCR_TL14 (3<<6) // 14 bytes + +// LCR +#define LCR_WLS_8 (3<<0) // 8 bit data (seriously, who uses anything else?) +#define LCR_1_STB (0<<2) // 1 stop bit +#define LCR_2_STB (1<<2) // 2 stop bits +#define LCR_PEN (1<<3) // parity enable +#define LCR_EPS (1<<4) // even parity select +#define LCR_STICK (1<<5) // stick parity +#define LCR_SBRK (1<<6) // set break +#define LCR_DLAB (1<<7) // divisor latch access bit + +// LSR +#define LSR_DR (1<<0) // data ready +#define LSR_OE (1<<1) // overrun +#define LSR_PE (1<<2) // parity error +#define LSR_FE (1<<3) // framing error +#define LSR_BI (1<<4) // break +#define LSR_THRE (1<<5) // transmit holding register empty +#define LSR_TEMT (1<<6) // transmitter empty +#define LSR_RFERR (1<<7) // error in receiver FIFO + +#endif /* __UART_16x50_H */ diff --git a/drivers/uart/16x50/rules.mk b/drivers/uart/16x50/rules.mk new file mode 100644 index 0000000..2f50879 --- /dev/null +++ b/drivers/uart/16x50/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2010 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULES += drivers/uart + +OPTIONS += WITH_UART_16X50=1 \ + WITH_HW_UART=1 + +ALL_OBJS += $(LOCAL_DIR)/16x50.o + diff --git a/drivers/uart/rules.mk b/drivers/uart/rules.mk new file mode 100644 index 0000000..70187d3 --- /dev/null +++ b/drivers/uart/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2009 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_UART=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/uart.o + diff --git a/drivers/uart/uart.c b/drivers/uart/uart.c new file mode 100644 index 0000000..92d8890 --- /dev/null +++ b/drivers/uart/uart.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +#include +#include + +#include + +/* + * Hardware-independent UART support. + */ + +#define UART_BAUDRATE 115200 + +static int uart_reader_task(void *arg); + +/* + * uart_init + * + * Initalise UARTs in the system. + * + * Starts the debug input polling threads as well. + */ +int +uart_init(void) +{ + u_int32_t port; + + /* do base hardware init */ + for (port = 0; port < UARTS_COUNT; port++) + uart_hw_init(port, UART_BAUDRATE); + +#ifdef DEBUG_SERIAL_PORT + /* regular console port */ + task_start(task_create("uart reader", uart_reader_task, (void *)DEBUG_SERIAL_PORT, 0x200)); +#ifdef DEBUG_SERIAL_PORT2 + /* alternate console port */ + task_start(task_create("uart reader", uart_reader_task, (void *)DEBUG_SERIAL_PORT2, 0x200)); +#endif +#endif + +#if DEBUG_UART_ENABLE_DEFAULT + /* enable console ports early */ + DebugUartReady |= kPowerNVRAMiBootDebugIAPSerial | kPowerNVRAMiBootDebugAltSerial; +#endif + + return(0); +} + +/* + * uart_getc + * + * Read a byte from the port, optionally waiting. + * If not waiting, returns -1 if a byte is not available. + */ +int +uart_getc(int port, bool wait) +{ + int c; + + for (;;) { + /* grab a byte */ + c = uart_hw_getc(port); + + /* if we got one, or we're not waiting, return */ + if ((-1 != c) || !wait) + return(c); + + /* give up cycles */ + task_yield(); + } +} + +/* + * uart_puts + * + * Write a nul-terminated string to the port. + */ +int +uart_puts(int port, const char *s) +{ + while(*s) + uart_putc(port, *(s++)); + return(0); +} + +/* + * uart_putc + * + * Write a byte to the port. + */ +int +uart_putc(int port, char c) +{ + /* spin until the byte can be sent */ + while (-1 == uart_hw_putc(port, c)) + task_yield(); + return(0); +} + +/* + * uart_debug_reader_task + * + * This helper task polls the configured serial port and + * feeds bytes read from it into the console input queue. + */ +static int +uart_reader_task(void *arg) +{ + int port = (int)arg; + u_int8_t port_mask; + int c; + + /* work out what the enable mask is for this port */ + switch (port) { +#if defined(DEBUG_SERIAL_PORT) + case DEBUG_SERIAL_PORT: + port_mask = kPowerNVRAMiBootDebugIAPSerial; + break; +#if defined(DEBUG_SERIAL_PORT2) + case DEBUG_SERIAL_PORT2: + port_mask = kPowerNVRAMiBootDebugAltSerial; + break; +#endif +#endif + default: + ASSERT(false); + return(0); + } + + /* loop reading bytes */ + for(;;) { + /* ask the port for a byte, waiting if required */ + c = uart_getc(port, true); + + /* if our port is enabled, feed it to the input queue */ + if (DebugUartReady & port_mask) + debug_pushchar(c); + + /* yield to avoid hogging */ + task_yield(); + } + return(0); +} + diff --git a/drivers/usb/rules.mk b/drivers/usb/rules.mk new file mode 100644 index 0000000..b11fb1c --- /dev/null +++ b/drivers/usb/rules.mk @@ -0,0 +1,55 @@ +# Copyright (C) 2007-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# Base USB Device stack +ALL_OBJS += \ + $(LOCAL_DIR)/usb.o \ + $(LOCAL_DIR)/usb_controller.o \ + $(LOCAL_DIR)/usb_core.o + +ifneq ($(filter $(DOCKFIFOS), bulk),) +ALL_OBJS += \ + $(LOCAL_DIR)/usb_dockfifo_controller.o +endif + +# SecureROM and LLB-DFU support +ifneq ($(filter $(OPTIONS), WITH_DFU_MODE=1), ) + +OPTIONS += \ + WITH_USB_DFU=1 \ + WITH_USB_MODE_DFU=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/usb_dfu.o + +endif + +# Recovery mode support +ifneq ($(filter $(OPTIONS), WITH_RECOVERY_MODE=1), ) + +OPTIONS += \ + WITH_USB_MODE_RECOVERY=1 + +ifeq ($(filter RELEASE ROMRELEASE,$(BUILD)),) +OPTIONS += \ + WITH_BULK_UPLOAD=1 +endif + +MODULES += \ + lib/cbuf \ + lib/cksum + +ALL_OBJS += \ + $(LOCAL_DIR)/usb_debug.o \ + $(LOCAL_DIR)/usb_serial.o \ + $(LOCAL_DIR)/usb_transfer.o + +endif diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c new file mode 100644 index 0000000..cad2747 --- /dev/null +++ b/drivers/usb/usb.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include + +#define require(assertion, exception_label) \ + do { \ + if (__builtin_expect(!(assertion), 0)) \ + { \ + goto exception_label; \ + } \ + } while (0) + + + +#define DFU_MODE_CONFIG_STRING "Apple Mobile Device (DFU Mode)" +#define RECOVERY_MODE_CONFIG_STRING "Apple Mobile Device (Recovery Mode)" + +/////////////////////////////////// +// USB DFU mode - SecureROM only +// USB Recovery mode - iBoot only +/////////////////////////////////// + +static bool usb_inited; + +static void usb_free() +{ + if(!usb_inited) goto early_inited_free; + +#if WITH_USB_MODE_DFU + + usb_dfu_exit(); + +#elif WITH_USB_MODE_RECOVERY + + usb_transfer_exit(); + usb_serial_exit(); + +#endif + + return; + +early_inited_free: + +#if WITH_USB_MODE_RECOVERY + usb_serial_exit(); +#endif + return; +} + +int usb_early_init() +{ +#if WITH_USB_MODE_RECOVERY + if(usb_serial_early_init() != 0) { + usb_free(); + return -1; + } +#endif + + return 0; +} + +int usb_init_with_controller(struct usb_controller_functions *controller_funcs) +{ + if(usb_inited) return 0; + + usb_controller_register(controller_funcs); + +#if WITH_USB_MODE_DFU + + require((usb_core_init(DFU_MODE_CONFIG_STRING) != -1), error); + require((usb_dfu_init() != -1), error); + +#elif WITH_USB_MODE_RECOVERY + + require((usb_core_init(RECOVERY_MODE_CONFIG_STRING) != -1), error); + require((usb_transfer_init() != -1), error); + require((usb_serial_init() != -1), error); + +#endif + + require((usb_core_start() != -1), error); + + usb_inited = true; + + dprintf(DEBUG_INFO, "USB inited \n"); + return 0; + +error: + dprintf(DEBUG_INFO, "failed to start the core\n"); + usb_free(); + return -1; +} + +int usb_init() +{ + // default to Synopsys OTG controller +#if WITH_HW_SYNOPSYS_OTG + extern struct usb_controller_functions *synopsys_otg_controller_init(); + + return usb_init_with_controller(synopsys_otg_controller_init()); +#else +# error "usb_init used without defined USB controller"; +#endif +} + +void usb_quiesce() +{ + if (usb_inited == false) return; + + usb_core_stop(); + usb_free(); + usb_controller_register(NULL); + + usb_inited = false; +} diff --git a/drivers/usb/usb_controller.c b/drivers/usb/usb_controller.c new file mode 100644 index 0000000..ceadabd --- /dev/null +++ b/drivers/usb/usb_controller.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +static struct usb_controller_functions usb_controller_funcs; +static bool usb_controller_registered; + +int usb_controller_register(const struct usb_controller_functions *controller_functions) +{ + dprintf(DEBUG_INFO, "usb_controller_register, %p\n", controller_functions); + if (controller_functions != NULL) { + bcopy((const void *)controller_functions, (void *)&usb_controller_funcs, sizeof(struct usb_controller_functions)); + usb_controller_registered = true; + } + else { + bzero((void *)&usb_controller_funcs, sizeof(struct usb_controller_functions)); + usb_controller_registered = false; + } + + return 0; +} + +int usb_controller_init(void) +{ + RELEASE_ASSERT(usb_controller_funcs.init != NULL); + return usb_controller_funcs.init(); +} + +void usb_controller_free(void) +{ + RELEASE_ASSERT(usb_controller_funcs.free_func != NULL); + usb_controller_funcs.free_func(); +} + +int usb_controller_start(void) +{ + RELEASE_ASSERT(usb_controller_funcs.start != NULL); + return usb_controller_funcs.start(); +} + +void usb_controller_stop(void) +{ + RELEASE_ASSERT(usb_controller_funcs.stop != NULL); + usb_controller_funcs.stop(); +} + +void usb_controller_set_address(u_int32_t new_address) +{ + RELEASE_ASSERT(usb_controller_funcs.set_address != NULL); + usb_controller_funcs.set_address(new_address); +} + +int usb_controller_get_connection_speed(void) +{ + RELEASE_ASSERT(usb_controller_funcs.get_connection_speed != NULL); + return usb_controller_funcs.get_connection_speed(); +} + +void usb_controller_activate_endpoint(u_int32_t endpoint, int type, int max_packet_size, int interval) +{ + RELEASE_ASSERT(usb_controller_funcs.activate_endpoint != NULL); + usb_controller_funcs.activate_endpoint(endpoint, type, max_packet_size, interval); +} + +void usb_controller_do_endpoint_io(struct usb_device_io_request *req) +{ + RELEASE_ASSERT(usb_controller_funcs.do_endpoint_io != NULL); + usb_controller_funcs.do_endpoint_io(req); +} + +void usb_controller_stall_endpoint(u_int32_t endpoint, bool stall) +{ + RELEASE_ASSERT(usb_controller_funcs.stall_endpoint != NULL); + usb_controller_funcs.stall_endpoint(endpoint, stall); +} + +void usb_controller_reset_endpoint_data_toggle(u_int32_t endpoint) +{ + RELEASE_ASSERT(usb_controller_funcs.reset_endpoint_data_toggle != NULL); + usb_controller_funcs.reset_endpoint_data_toggle(endpoint); +} + +bool usb_controller_is_endpoint_stalled(u_int32_t endpoint) +{ + RELEASE_ASSERT(usb_controller_funcs.is_endpoint_stalled != NULL); + return usb_controller_funcs.is_endpoint_stalled(endpoint); +} + +void usb_controller_do_test_mode(u_int32_t selector) +{ + RELEASE_ASSERT(usb_controller_funcs.do_test_mode != NULL); + usb_controller_funcs.do_test_mode(selector); +} + +void usb_controller_abort_endpoint(u_int32_t endpoint) +{ + RELEASE_ASSERT(usb_controller_funcs.abort_endpoint != NULL); + usb_controller_funcs.abort_endpoint(endpoint); +} + +void usb_controller_deactivate_endpoint(u_int32_t endpoint) +{ + RELEASE_ASSERT(usb_controller_funcs.deactivate_endpoint != NULL); + usb_controller_funcs.deactivate_endpoint(endpoint); +} diff --git a/drivers/usb/usb_core.c b/drivers/usb/usb_core.c new file mode 100644 index 0000000..bb2e226 --- /dev/null +++ b/drivers/usb/usb_core.c @@ -0,0 +1,1216 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +//////////////////////////////////////////////////////////////////// +// USB Core +// +// This file implements USB stack which is responsible for +// constructing descriptors, handling all the setup requests, pass +// interface/class specific requests to respective drivers, handle +// vendor specific requests +/////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_HW_POWER +#include +#endif // WITH_HW_POWER + +//=================================================================================== +// Local consts and macros +//=================================================================================== + +#define DEBUG 0 +#if DEBUG +#define print(fmt, args...) printf("%s --- " fmt, __FUNCTION__, ##args) +#else +#define print(fmt, args...) (void)0 +#endif // DEBUG + +#define USB_MAX_STRING_DESCRIPTOR_INDEX 10 +#define USB_STRING_DESCRIPTOR_INDEX_LANGID 0 +#define USB_STRING_DESCRIPTOR_INDEX_NONCE 1 + +#define ADDRESS_0 0 +#define EP0_TX_BUFFER_LENGTH 256 +#define USB_MAX_INTERFACES_SUPPORTED 2 + +#define NO_DATA_PHASE_HANDLER (-2) +#define DEVICE_DATA_PHASE_HANDLER (-1) + +//=================================================================================== +// Global and Local variables +//=================================================================================== + +u_int32_t usb_configuration_string_desc_index = 0; + +static const struct usb_string_descriptor lang_id_string_desc = { + 0x4, + USB_DT_STRING, + {0x09, 0x04} +}; + +static struct usb_string_descriptor* nonce_string_desc = NULL; + +static struct usb_device_descriptor usb_core_device_descriptor = { + USB_DT_DEVICE_SIZE, + USB_DT_DEVICE, + USB_BCD_VERSION, + 0x00, + 0x00, + 0x00, + EP0_MAX_PACKET_SIZE, + 0, + 0, + 0, + 0, + 0, + 0, + 1 +}; + +static struct usb_device_qualifier_descriptor usb_core_device_qualifier_descriptor = { + USB_DT_DEVICE_QUALIFIER_SIZE, + USB_DT_DEVICE_QUALIFIER, + USB_BCD_VERSION, + 0x00, + 0x00, + 0x00, + EP0_MAX_PACKET_SIZE, + 1, + 0 +}; + +static volatile __aligned(CPU_CACHELINE_SIZE) u_int8_t ep0_tx_buffer[EP0_TX_BUFFER_LENGTH]; + +static struct usb_interface_instance *registered_interfaces[USB_MAX_INTERFACES_SUPPORTED]; +static int registered_interfaces_count = 0; + +static u_int8_t *usb_core_hs_configuration_descriptor; +static u_int8_t *usb_core_fs_configuration_descriptor; +static u_int8_t *usb_core_configuration_descriptor; +static u_int8_t *usb_core_other_speed_configuration_descriptor; +static struct usb_string_descriptor *usb_core_string_descriptors[USB_MAX_STRING_DESCRIPTOR_INDEX]; + +static u_int32_t ep0_data_phase_length; +static u_int32_t ep0_data_phase_rcvd; +static u_int8_t *ep0_data_phase_buffer; +static int ep0_data_phase_if_num; // < -1 = nothing to handle the data, -1 = device is handling, >=0 the index of the interface handling it + +static int usb_device_state = DEVICE_ST_INIT; +static struct usb_device_request setup_request; + +static u_int32_t usb_active_config = 0; + +static u_int8_t test_mode_selector; + +#if WITH_HW_POWER +static struct task_event usb_core_event_high_current; +static struct task_event usb_core_event_no_current; +static struct task *task_high_current = NULL; +static struct task *task_no_current = NULL; +#endif // WITH_HW_POWER + +static int usb_core_cable_state; + +#if WITH_RECOVERY_MODE +static struct task *task_usb_req = NULL; +static u_int16_t last_command_id; //last command fully executed, so we can return output in a get request +static u_int16_t current_command_id; //command we are in the process of executing, we set last_command_id to this when completed. +static bool command_is_blind; //is the current command blind or not +static struct task_event vendor_request_event; //so we can signal task level to do the command +static bool command_in_progress; //so we don't attempt to receive a command while we're already processing one. + +static void handle_vendor_device_completion(int data_received); +#endif // WITH_RECOVERY_MODE + +//=================================================================================== +// Local Functions +//=================================================================================== + +static struct usb_device_io_request *alloc_ep0_device_io_request (volatile u_int8_t *io_buffer, int io_length, + void (*callback)(struct usb_device_io_request *)) +{ + struct usb_device_io_request *io_request; + + if(!io_buffer) + ASSERT(io_length <= EP0_TX_BUFFER_LENGTH); + + io_request = calloc(1, sizeof(struct usb_device_io_request)); + + io_request->endpoint = EP0_IN; + if(!io_buffer) + io_request->io_buffer = ep0_tx_buffer; + else + io_request->io_buffer = io_buffer; + io_request->io_length = io_length; + io_request->callback = callback; + + return io_request; +} + +static struct usb_device_io_request *alloc_device_io_request (u_int32_t endpoint, volatile u_int8_t *io_buffer, + int io_length, void (*callback)(struct usb_device_io_request *)) +{ + struct usb_device_io_request *io_request; + + if(endpoint == EP0_IN) + return alloc_ep0_device_io_request(io_buffer, io_length, callback); + + io_request = calloc(1, sizeof(struct usb_device_io_request)); + + io_request->endpoint = endpoint; + io_request->io_buffer = io_buffer; + io_request->io_length = io_length; + io_request->callback = callback; + + return io_request; +} + +static void handle_test_mode_request(struct usb_device_io_request *ioreq) +{ +#if WITH_HW_POWER + // set current draw to 0 for test_j & test_k + if((test_mode_selector == 1) || + (test_mode_selector == 2) || + (test_mode_selector == 3)) { + event_signal(&usb_core_event_no_current); + } +#endif // WITH_HW_POWER + + usb_controller_do_test_mode(test_mode_selector); +} + +static void handle_ep0_data_phase (u_int8_t *rx_buffer, u_int32_t data_rcvd, bool *data_phase) +{ + u_int32_t remaining; + u_int32_t to_copy; + + if((ep0_data_phase_rcvd + data_rcvd) > ep0_data_phase_length) { + usb_controller_stall_endpoint(EP0_IN, true); + goto done; + } + + remaining = ep0_data_phase_length - ep0_data_phase_rcvd; + to_copy = (data_rcvd > remaining) ? remaining : data_rcvd; + + memcpy(ep0_data_phase_buffer, rx_buffer, to_copy); + + ep0_data_phase_buffer += to_copy; + ep0_data_phase_rcvd += to_copy; + + *data_phase = true; + + print("data-phase payload %d of %d\n", ep0_data_phase_rcvd, ep0_data_phase_length); + + if((ep0_data_phase_rcvd == ep0_data_phase_length) || (data_rcvd != EP0_MAX_PACKET_SIZE)) + { +#if WITH_RECOVERY_MODE + if(ep0_data_phase_if_num == DEVICE_DATA_PHASE_HANDLER) { //the device is handling this + handle_vendor_device_completion(ep0_data_phase_rcvd); + } else +#endif // WITH_RECOVERY_MODE + { + if((ep0_data_phase_if_num >= 0) && (ep0_data_phase_if_num < registered_interfaces_count) + && (registered_interfaces[ep0_data_phase_if_num]->non_setup_data_phase_finished_callback)) { + registered_interfaces[ep0_data_phase_if_num]->non_setup_data_phase_finished_callback(ep0_data_phase_rcvd); + usb_core_send_zlp(); //we should check returnval of call and possibly stall + } + } + + goto done; + } + + return; + +done: + ep0_data_phase_rcvd = 0; + ep0_data_phase_length = 0; + ep0_data_phase_buffer = NULL; + ep0_data_phase_if_num = NO_DATA_PHASE_HANDLER; + *data_phase = false; +} + +static struct usb_string_descriptor *get_usb_string_descriptor (int index) +{ + if(index == USB_STRING_DESCRIPTOR_INDEX_LANGID) { + return ((struct usb_string_descriptor *)&lang_id_string_desc); + } + + if(index == USB_STRING_DESCRIPTOR_INDEX_NONCE) { + return nonce_string_desc; + } + + if((index >= USB_MAX_STRING_DESCRIPTOR_INDEX) || (!usb_core_string_descriptors[index])) { + return NULL; + } + + return usb_core_string_descriptors[index]; +} + +static int handle_get_descriptor (struct usb_device_request *request) +{ + size_t actual_length = 0; + + switch(request->wValue >> 8) { + case USB_DT_DEVICE : + actual_length = __min(request->wLength, sizeof(struct usb_device_descriptor)); + RELEASE_ASSERT(actual_length <= EP0_TX_BUFFER_LENGTH); + memcpy((void *)ep0_tx_buffer, (void *)&usb_core_device_descriptor, actual_length); + break; + + case USB_DT_DEVICE_QUALIFIER : + actual_length = __min(request->wLength, sizeof(struct usb_device_qualifier_descriptor)); + RELEASE_ASSERT(actual_length <= EP0_TX_BUFFER_LENGTH); + memcpy((void *)ep0_tx_buffer, (void *)&usb_core_device_qualifier_descriptor, actual_length); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION : + actual_length = __min(request->wLength, ((struct usb_configuration_descriptor *)(usb_core_other_speed_configuration_descriptor))->wTotalLength); + RELEASE_ASSERT(actual_length <= EP0_TX_BUFFER_LENGTH); + memcpy((void *)ep0_tx_buffer, (void *)usb_core_other_speed_configuration_descriptor, actual_length); + ((struct usb_configuration_descriptor *)(ep0_tx_buffer))->bDescriptorType = USB_DT_OTHER_SPEED_CONFIGURATION; + break; + + case USB_DT_CONFIGURATION : + actual_length = __min(request->wLength, ((struct usb_configuration_descriptor *)(usb_core_configuration_descriptor))->wTotalLength); + RELEASE_ASSERT(actual_length <= EP0_TX_BUFFER_LENGTH); + memcpy((void *)ep0_tx_buffer, (void *)usb_core_configuration_descriptor, actual_length); + break; + + case USB_DT_STRING : + { + struct usb_string_descriptor *string_desc = NULL; + + if((string_desc = get_usb_string_descriptor(request->wValue & 0xff))) { + actual_length = __min(request->wLength, string_desc->bLength); + RELEASE_ASSERT(actual_length <= EP0_TX_BUFFER_LENGTH); + memcpy((void *)ep0_tx_buffer, (void *)string_desc, actual_length); + } + } + break; + + default : + return -1; + } + + return actual_length; +} + +static void handle_set_configuration (struct usb_device_request *request) +{ + int i; + + usb_active_config = request->wValue; + + for(i = 0; i < registered_interfaces_count; i++) { + if(registered_interfaces[i] && registered_interfaces[i]->activate_interface) { + registered_interfaces[i]->activate_interface(); + } + } +} + +static int handle_clear_feature (struct usb_device_request *request) +{ + int rc = -1; + + switch(request->bmRequestType & USB_REQ_RECIPIENT_MASK) { + case USB_REQ_RECIPIENT_ENDPOINT : + if(request->wValue != USB_FEATURE_ENDPOINT_HALT) { + goto done; + } + + // Reset the data toggle + usb_controller_reset_endpoint_data_toggle(request->wIndex); + + // Clear endpoint stall + usb_controller_stall_endpoint(request->wIndex, false); + + rc = 0; + break; + + /* Remote wake up not supported, and Test mode cannot be cleared */ + case USB_REQ_RECIPIENT_DEVICE : + default : + goto done; + } + + done : + return rc; +} + +static int handle_set_feature (struct usb_device_request * request , void (**callback)(struct usb_device_io_request *)) +{ + int rc = -1; + + *callback = NULL; + + switch(request->bmRequestType & USB_REQ_RECIPIENT_MASK) { + case USB_REQ_RECIPIENT_DEVICE : + /* Remote wakeup not supported */ + if(request->wValue != USB_FEATURE_TEST_MODE) { + goto done; + } + + if((request->wIndex & 0xff) != 0) { + goto done; + } + + *callback = handle_test_mode_request; + test_mode_selector = (request->wIndex >> 8) & 0xf; + + rc = 0; + break; + + case USB_REQ_RECIPIENT_ENDPOINT : + if(request->wValue != USB_FEATURE_ENDPOINT_HALT) { + goto done; + } + + usb_controller_stall_endpoint(request->wIndex, true); + + rc = 0; + break; + + default : + goto done; + } + + done : + return rc; + +} + +static void standard_device_request_cb (struct usb_device_io_request *req) +{ + if((req->io_length > 0) && ((req->io_length % EP0_MAX_PACKET_SIZE) == 0) && (setup_request.wLength > req->io_length)) { + usb_core_send_zlp(); + } +} + +#if WITH_RECOVERY_MODE + +#define VDR_SIZE 512 +static char *vendor_device_request_rxbuffer; + +//perform a command line sent by host. +static void do_vendor_command(bool isBlind) +{ + bool syntax_error = true; + int rval = -1; + + vendor_device_request_rxbuffer[VDR_SIZE - 1] = 0; //ensure host data is 0 terminated +#if WITH_MENU + syntax_error = process_command_line(vendor_device_request_rxbuffer, &rval); +#endif // WITH_MENU + command_in_progress = false; + if(!syntax_error) { + last_command_id = current_command_id; //save the id of last command executed so we can return results if requested + } + + if(!isBlind) { //if not blind we need to convey success to the host by stalling or sending a zlp + if(syntax_error || rval < 0) { //command doesn't exist or failed, stall the pipe + usb_controller_stall_endpoint(EP0_IN, true); + } + else { + usb_core_send_zlp(); + } + } +} + +//completion routine after the zlp has been sent for a blind request from host +static void handle_blind_vendor_zlp(struct usb_device_io_request *io_request) +{ + //we successfully sent the zlp, so now perform the command + event_signal(&vendor_request_event); +} + +//handler invoked once all data has been received for a vendor-specific-device request from host +static void handle_vendor_device_completion(int data_received) +{ + if(command_is_blind) { //don't execute the command until we've sent the zlp + struct usb_device_io_request *io_request = alloc_ep0_device_io_request(NULL, 0, + handle_blind_vendor_zlp); + if(io_request == NULL) { + usb_controller_stall_endpoint(EP0_IN, true); + dprintf(DEBUG_INFO, "usb_core : usb_core_send_zlp --- alloc ep0 failed \n"); + command_in_progress = false; + return; + } + + usb_controller_do_endpoint_io(io_request); + return; + } + else { + event_signal(&vendor_request_event); //kick it to the task to handle the command line + } +} + +//determine if we handle a given vendor-specific-device request from host +static void handle_vendor_device_request (struct usb_device_request *request) +{ + switch (request->bRequest) { + case PR_VENDOR_REQUEST: + case PR_VENDOR_BLIND_REQUEST: + if(!command_in_progress && ((request->bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE)) { + if(request->wLength && request->wLength <= VDR_SIZE) { + if(!vendor_device_request_rxbuffer) { + vendor_device_request_rxbuffer = malloc(VDR_SIZE); + } + if(vendor_device_request_rxbuffer) { + ep0_data_phase_buffer = (u_int8_t *)vendor_device_request_rxbuffer; + ep0_data_phase_length = request->wLength; + ep0_data_phase_if_num = DEVICE_DATA_PHASE_HANDLER; + command_is_blind = (request->bRequest == PR_VENDOR_BLIND_REQUEST); + current_command_id = request->wValue; + command_in_progress = true; + return; + } + } + } + else if(((request->bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_DEVICE2HOST) && + request->wLength && (request->wValue == last_command_id)) { + int outputlen; + const char *data; + if((data = env_get("cmd-results"))) { + struct usb_device_io_request* ioreq; + outputlen = strlen(data) + 1; + if(outputlen <= request->wLength) { + ioreq = alloc_device_io_request(EP0_IN, (unsigned char *)data, outputlen, + standard_device_request_cb); + if(ioreq) { + usb_controller_do_endpoint_io(ioreq); + return; + } + } + } + } + break; + } + + usb_controller_stall_endpoint(EP0_IN, true); + //usb_controller_stall_endpoint(EP0_OUT, true); +} + +static int vendor_req_task(void *arg) +{ + for(;;) { + // make sure there's something to do + event_wait(&vendor_request_event); + + // make sure menu-task is up to process commands + event_wait(&gMenuTaskReadyEvent); + + // process commands + do_vendor_command(command_is_blind); + } + return 0; +} + +#endif // WITH_RECOVERY_MODE + +static void handle_standard_device_request (struct usb_device_request *request) +{ + int buffer_length = -1; + struct usb_device_io_request *io_request; + void (*callback)(struct usb_device_io_request *) = standard_device_request_cb; + + // handle one that returns data + if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_DEVICE2HOST) { + switch(request->bRequest) { + case USB_REQ_GET_CONFIGURATION : + ep0_tx_buffer[0] = usb_active_config; + buffer_length = 1; + break; + + case USB_REQ_GET_DESCRIPTOR : + buffer_length = handle_get_descriptor(request); + break; + + case USB_REQ_GET_INTERFACE : + buffer_length = 1; + ep0_tx_buffer[0] = 0; + /* XXX should I stall if intf_num is bad or just return 0 */ + if((request->wIndex < registered_interfaces_count) && (registered_interfaces[request->wIndex]->handle_get_interface)) { + ep0_tx_buffer[0] = registered_interfaces[request->wIndex]->handle_get_interface(); + } + break; + + case USB_REQ_GET_STATUS : + buffer_length = 2; + ep0_tx_buffer[0] = ep0_tx_buffer[1] = 0; + if((request->bmRequestType & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_ENDPOINT) { + ep0_tx_buffer[0] = usb_controller_is_endpoint_stalled(request->wIndex); + } + break; + } + } + // handle ones that do not return data + else { + switch(request->bRequest) { + case USB_REQ_CLEAR_FEATURE : + buffer_length = handle_clear_feature(request); + break; + + case USB_REQ_SET_FEATURE: + buffer_length = handle_set_feature(request, &callback); + break; + + case USB_REQ_SET_ADDRESS : + usb_controller_set_address(request->wValue); + buffer_length = 0; + usb_device_state = DEVICE_ST_ADDRESSED; + break; + + case USB_REQ_SET_CONFIGURATION : + buffer_length = 0; + if(usb_active_config != request->wValue) { + handle_set_configuration(request); + } + if(usb_active_config != 0) { + usb_device_state = DEVICE_ST_CONFIGURED; +#if (WITH_HW_POWER && !TARGET_USB_DEVICE_SELF_POWERED) + event_signal(&usb_core_event_high_current); +#endif // WITH_HW_POWER && !TARGET_USB_DEVICE_SELF_POWERED + } + break; + + case USB_REQ_SET_INTERFACE : + buffer_length = -1; + if((request->wIndex < registered_interfaces_count) && (registered_interfaces[request->wIndex]->handle_set_interface)) { + buffer_length = registered_interfaces[request->wIndex]->handle_set_interface(request->wValue); + } + break; + } + } + + if(buffer_length < 0) { + usb_controller_stall_endpoint(EP0_IN, true); + //usb_controller_stall_endpoint(EP0_OUT, true); + print("usb_core : handle_standard_device_request --- Setup Request not handled \n"); + return; + } + else { + if((io_request = alloc_ep0_device_io_request(NULL, buffer_length, callback)) == NULL) { + usb_controller_stall_endpoint(EP0_IN, true); + dprintf(DEBUG_INFO, "usb_core : handle_standard_device_request --- alloc_ep0 failed \n"); + return; + } + } + + usb_controller_do_endpoint_io(io_request); +} + +static struct usb_string_descriptor* usb_alloc_string_descriptor (const char *str) +{ + struct usb_string_descriptor *string_desc; + u_int32_t string_desc_len; + + // substracting 2 for wData[2] + string_desc_len = sizeof(struct usb_string_descriptor) - 2 + 2 * strlen(str); + + if(string_desc_len > 255) + panic("usb_alloc_string_descriptor: string_desc_len > 255\n"); + + string_desc = malloc(string_desc_len); + + string_desc->bLength = string_desc_len; + string_desc->bDescriptorType = USB_DT_STRING; + + u_int16_t *wData = (u_int16_t *)string_desc->wData; + while(*str) { + *wData++ = (u_int16_t)*str++; + } + + return string_desc; +} + +static int usb_create_string_descriptor (const char *str) +{ + int i; + // String desc at index 0 is used for Lang ID + // String desc at index 1 is used for Nonce + for(i = 2; i < USB_MAX_STRING_DESCRIPTOR_INDEX; i++) { + if(usb_core_string_descriptors[i] == NULL) { + usb_core_string_descriptors[i] = usb_alloc_string_descriptor(str); + break; + } + } + + return i; +} + +static void usb_free_string_descriptors (void) +{ + int i; + + for(i = 0; i < USB_MAX_STRING_DESCRIPTOR_INDEX; i++) { + if(usb_core_string_descriptors[i]) { + free(usb_core_string_descriptors[i]); + usb_core_string_descriptors[i] = NULL; + } + } +} + +#if WITH_HW_POWER +static int usb_high_current_task(void *arg) +{ + for(;;) { + event_wait(&usb_core_event_high_current); + + power_set_usb_state(true, false); + } + + return 0; +} + +static int usb_no_current_task(void *arg) +{ + for(;;) { + event_wait(&usb_core_event_no_current); + + power_set_usb_state(false, false); + } + + return 0; +} +#endif // WITH_HW_POWER + +//=================================================================================== +// Global Functions +//=================================================================================== +int usb_core_init (const char *configuration_string_desc) +{ + nonce_string_desc = usb_alloc_string_descriptor(platform_get_usb_more_other_string(true)); + + usb_core_device_descriptor.idVendor = platform_get_usb_vendor_id(); + usb_core_device_descriptor.idProduct = platform_get_usb_product_id(); + usb_core_device_descriptor.bcdDevice = platform_get_usb_device_version(); + usb_core_device_descriptor.iManufacturer = usb_create_string_descriptor(platform_get_usb_manufacturer_string()); + usb_core_device_descriptor.iProduct = usb_create_string_descriptor(platform_get_usb_product_string()); + usb_core_device_descriptor.iSerialNumber = usb_create_string_descriptor(platform_get_usb_serial_number_string(true)); + + usb_configuration_string_desc_index = usb_create_string_descriptor(configuration_string_desc); + + bzero((void *)ep0_tx_buffer, EP0_TX_BUFFER_LENGTH); + + registered_interfaces_count = 0; + +#if WITH_RECOVERY_MODE + //prepare the task-context requets handler + if (task_usb_req == NULL) { + event_init(&vendor_request_event, EVENT_FLAG_AUTO_UNSIGNAL, false); +#if defined(USB_VENDOR_TASK_SIZE) + task_usb_req = task_create("usb req", &vendor_req_task, NULL, USB_VENDOR_TASK_SIZE); + task_start(task_usb_req); +#else + task_usb_req = task_create("usb req", &vendor_req_task, NULL, 0x1C00); + task_start(task_usb_req); +#endif + } +#endif // WITH_RECOVERY_MODE + +#if WITH_HW_POWER + if (task_high_current == NULL) { + event_init(&usb_core_event_high_current, EVENT_FLAG_AUTO_UNSIGNAL, false); + task_high_current = task_create("usb-high-current", &usb_high_current_task, NULL, 0x600); + task_start(task_high_current); + } + + if (task_no_current == NULL) { + event_init(&usb_core_event_no_current, EVENT_FLAG_AUTO_UNSIGNAL, false); + task_no_current = task_create("usb-no-current", &usb_no_current_task, NULL, 0x400); + task_start(task_no_current); + } +#endif // WITH_HW_POWER + + usb_core_cable_state = CABLE_DISCONNECTED; + + return usb_controller_init(); +} + +int usb_core_start() +{ + int i, j, k; + int total_len; + u_int8_t *hs_config_desc; + u_int8_t *fs_config_desc; + u_int8_t *p; + struct usb_configuration_descriptor desc = { + USB_DT_CONFIGURATION_SIZE, + USB_DT_CONFIGURATION, + 0, + 0, + 1, + usb_configuration_string_desc_index, +#if TARGET_USB_DEVICE_SELF_POWERED + (1 << 7) | (1 << 6), + 0 +#else + (1 << 7), + 500/2 +#endif + }; + int other_descs_len; + + if(registered_interfaces_count == 0) { + dprintf(DEBUG_INFO, "usb_core has no registered interfaces\n"); + return -1; + } + +#if WITH_HW_POWER + power_set_usb_enabled(true); +#endif + + desc.bNumInterfaces = registered_interfaces_count; + + // create configuration descriptors + + // Chap-9 compliance tool and some USBHost requires a + // device to provide "other-speed" descriptor. So we need to + // build 2 sets of configuration descriptors here, one for + // high-speed config and other for full-speed config. + // + // First, we will calculate total-length for our configuration + // descriptor. Current implementation requires every function + // driver (like usb-serial, usb-dfu) to provide their list of + // interface descriptors, endpoint descriptors, and other + // functional descriptors. For functional descriptors, we + // assume (as per USB spec), 1st byte store the length of the + // descriptor. + // + // Next, we have our total length, we update this value for + // final configuraiton descriptor. Also, now we know how much + // memory we need to allocate for our config descriptor. + // + // Next - We now start copying various descriptors + // into the memory allocated for the final config + // decriptor. We start with configuration descriptor + // first. Then we will start copying interface descriptors and + // their corresponding endpoint descriptors (trusting the list + // of descriptors supplied by our function drivers). Every + // interface could have an alternate setting, and endpoints + // associated with these alternate settings (>= 0). We are + // using num_of_endpoints information supplied in the + // interface descriptor to figure out if we need to copy + // endpoint descriptors for a particular interface. + // + // So far, this seems straightforward. Two things which + // introduces complexities - + // 1. functional descriptors - these are associated with a + // interface. Currently, we are just copying them after the + // first interface we found. This is not a generic + // solution. This needs to be addressed. + // 2. other-speed descriptor - currently, we are building + // both high and full-speed descriptor together. For FS + // descriptor we need to change max-packet-size for the + // endpoints. Again we are trusting contents provided by our + // function drivers, and just updating them with correct value. + + // Note about string descriptors - currently every interface + // driver will pass list of strings it has, and the + // count. Some interface driver might not have any strings + // associated with them. We are assuming, if an interface + // driver passes us a list with n number of strings, n is + // always same has total # of interface associated with that + // interface driver. + + other_descs_len = 0; + total_len = sizeof(struct usb_configuration_descriptor); + + for(i = 0; i < registered_interfaces_count; i++) { + for(j = 0; j < registered_interfaces[i]->total_interfaces; j++) + total_len += sizeof(struct usb_interface_descriptor); + for(j = 0; j < registered_interfaces[i]->total_other_descs; j++) { + p = (u_int8_t *)(registered_interfaces[i]->other_descs) + other_descs_len; + other_descs_len += p[0]; + total_len += p[0]; + } + for(j = 0; j < registered_interfaces[i]->total_endpoints; j++) + total_len += sizeof(struct usb_endpoint_descriptor); + } + + usb_core_hs_configuration_descriptor = (u_int8_t *)malloc(total_len); + + usb_core_fs_configuration_descriptor = (u_int8_t *)malloc(total_len); + + desc.wTotalLength = total_len; + + memcpy(usb_core_hs_configuration_descriptor, (void *)&desc, sizeof(struct usb_configuration_descriptor)); + memcpy(usb_core_fs_configuration_descriptor, (void *)&desc, sizeof(struct usb_configuration_descriptor)); + + hs_config_desc = usb_core_hs_configuration_descriptor + sizeof(struct usb_configuration_descriptor); + fs_config_desc = usb_core_fs_configuration_descriptor + sizeof(struct usb_configuration_descriptor); + + for(i = 0; i < registered_interfaces_count; i++) { + for(j = 0; j < registered_interfaces[i]->total_interfaces; j++) { + + ASSERT((hs_config_desc + sizeof(struct usb_interface_descriptor)) <= (hs_config_desc + total_len)); + ASSERT((fs_config_desc + sizeof(struct usb_interface_descriptor)) <= (fs_config_desc + total_len)); + + memcpy(hs_config_desc, + (u_int8_t *)(registered_interfaces[i]->interface_descs) + (j * sizeof(struct usb_interface_descriptor)), + sizeof(struct usb_interface_descriptor)); + + memcpy(fs_config_desc, + (u_int8_t *)(registered_interfaces[i]->interface_descs) + (j * sizeof(struct usb_interface_descriptor)), + sizeof(struct usb_interface_descriptor)); + + if(registered_interfaces[i]->string_descs && registered_interfaces[i]->string_descs[j]) { + ((struct usb_interface_descriptor *)hs_config_desc)->iInterface = usb_create_string_descriptor(registered_interfaces[i]->string_descs[j]); + ((struct usb_interface_descriptor *)fs_config_desc)->iInterface = usb_create_string_descriptor(registered_interfaces[i]->string_descs[j]); + } + + p = hs_config_desc; + + hs_config_desc += sizeof(struct usb_interface_descriptor); + fs_config_desc += sizeof(struct usb_interface_descriptor); + + ASSERT((hs_config_desc + other_descs_len) <= (hs_config_desc + total_len)); + ASSERT((fs_config_desc + other_descs_len) <= (fs_config_desc + total_len)); + + if(registered_interfaces[i]->total_other_descs) { + memcpy(hs_config_desc, registered_interfaces[i]->other_descs, other_descs_len); + memcpy(fs_config_desc, registered_interfaces[i]->other_descs, other_descs_len); + + hs_config_desc += other_descs_len; + fs_config_desc += other_descs_len; + } + + if(((struct usb_interface_descriptor *)p)->bNumEndpoints == 0) + continue; + + for(k = 0; k < registered_interfaces[i]->total_endpoints; k++) { + + ASSERT((hs_config_desc + (k * sizeof(struct usb_endpoint_descriptor)) + sizeof(struct usb_endpoint_descriptor)) + <= (hs_config_desc + total_len)); + ASSERT((fs_config_desc + (k * sizeof(struct usb_endpoint_descriptor)) + sizeof(struct usb_endpoint_descriptor)) + <= (fs_config_desc + total_len)); + + memcpy(hs_config_desc + (k * sizeof(struct usb_endpoint_descriptor)), + (u_int8_t *)(registered_interfaces[i]->endpoint_descs) + (k * sizeof(struct usb_endpoint_descriptor)), + sizeof(struct usb_endpoint_descriptor)); + + memcpy(fs_config_desc + (k * USB_DT_ENDPOINT_SIZE), + (u_int8_t *)(registered_interfaces[i]->endpoint_descs) + (k * sizeof(struct usb_endpoint_descriptor)), + sizeof(struct usb_endpoint_descriptor)); + p = fs_config_desc + (k * USB_DT_ENDPOINT_SIZE); + if((((struct usb_endpoint_descriptor *)p)->bDescriptorType == USB_DT_ENDPOINT) && + (((struct usb_endpoint_descriptor *)p)->bmAttributes == USB_ENDPOINT_BULK)) { + ((struct usb_endpoint_descriptor *)p)->wMaxPacketSize = FS_EP_MAX_PACKET_SIZE; + } + } + + hs_config_desc += (registered_interfaces[i]->total_endpoints * sizeof(struct usb_endpoint_descriptor)); + fs_config_desc += (registered_interfaces[i]->total_endpoints * sizeof(struct usb_endpoint_descriptor)); + } + } + + return usb_controller_start(); +} + +void usb_core_register_interface (struct usb_interface_instance *intf) +{ + if(registered_interfaces_count >= USB_MAX_INTERFACES_SUPPORTED) { + dprintf(DEBUG_INFO, "registered interfaces exceed max \n"); + return; + } + + registered_interfaces[registered_interfaces_count] = intf; + registered_interfaces_count++; + +} + +void usb_core_handle_usb_control_receive (u_int8_t *ep0_rx_buffer, bool is_setup, int receive_length, bool *data_phase) +{ + ASSERT(data_phase != NULL); + + *data_phase = false; + + if(is_setup == false) { + if (receive_length == 0) + return; + + ASSERT(ep0_data_phase_buffer != NULL); + handle_ep0_data_phase(ep0_rx_buffer, receive_length, data_phase); + return; + } + + print("process usb setup data \n"); + + memcpy(&setup_request, ep0_rx_buffer, sizeof(setup_request)); + + switch(setup_request.bmRequestType & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_STANDARD : + handle_standard_device_request(&setup_request); + goto success; + +#if WITH_RECOVERY_MODE + case USB_REQ_TYPE_VENDOR : + switch(setup_request.bmRequestType & USB_REQ_RECIPIENT_MASK) { + case USB_REQ_RECIPIENT_DEVICE : + handle_vendor_device_request(&setup_request); + goto success; + + case USB_REQ_RECIPIENT_INTERFACE : + { + int intf_num = setup_request.wIndex; + + if((intf_num >= 0) && (intf_num < registered_interfaces_count) + && (registered_interfaces[intf_num]->handle_vendor_request)) { + int ret = registered_interfaces[intf_num]->handle_vendor_request(&setup_request); + + if((setup_request.bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) { + if (ret > 0) { + ep0_data_phase_length = ret; + ep0_data_phase_if_num = intf_num; + goto success; + } + else if(ret == 0) { + usb_core_send_zlp(); + goto success; + } + } + else if((setup_request.bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_DEVICE2HOST) { + goto success; + } + } + goto error; + } + } +#endif // WITH_RECOVERY_MODE + + case USB_REQ_TYPE_CLASS : + if((setup_request.bmRequestType & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE) { + int intf_num = setup_request.wIndex; + + if((intf_num >= 0) && (intf_num < registered_interfaces_count) + && (registered_interfaces[intf_num]->handle_request)) { + int ret = registered_interfaces[intf_num]->handle_request(&setup_request, + &ep0_data_phase_buffer); + + if((setup_request.bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) { + if (ret > 0) { + ASSERT(ep0_data_phase_buffer != NULL); + ep0_data_phase_length = ret; + ep0_data_phase_if_num = intf_num; + goto success; + } + else if(ret == 0) { + usb_core_send_zlp(); + goto success; + } + } + else if((setup_request.bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_DEVICE2HOST) { + goto success; + } + } + } + +#if WITH_RECOVERY_MODE + error: +#endif // WITH_RECOVERY_MODE + //else fall through + default : + //usb_controller_stall_endpoint(EP0_OUT, true); + usb_controller_stall_endpoint(EP0_IN, true); + *data_phase = false; + dprintf(DEBUG_INFO, "usb_core : usb_core_handle_usb_control_receive --- Request %02x %02x %04x %04x not handled \n", + setup_request.bmRequestType, setup_request.bRequest, setup_request.wIndex, setup_request.wLength); + return; + } + +success: + switch(setup_request.bmRequestType & USB_REQ_DIRECTION_MASK) { + case USB_REQ_DEVICE2HOST : + *data_phase = true; + break; + case USB_REQ_HOST2DEVICE : + *data_phase = (setup_request.wLength > 0); + break; + } +} + +void usb_core_event_handler (int event) +{ + int i; + + switch(event) { + case CABLE_CONNECTED : + break; + + case CABLE_DISCONNECTED : + { + usb_core_cable_state = CABLE_DISCONNECTED; + + for(i = 0; i < registered_interfaces_count; i++) { + if(registered_interfaces[i] && registered_interfaces[i]->deactivate_interface) { + registered_interfaces[i]->deactivate_interface(); + } + } + +#if WITH_HW_POWER + // set current to 0, when cable is gone + event_signal(&usb_core_event_no_current); +#endif // WITH_HW_POWER + } + break; + + case USB_RESET : + print("USB_RESET \n"); + usb_controller_abort_endpoint(EP0_IN); + usb_controller_set_address(ADDRESS_0); + usb_device_state = DEVICE_ST_DEFAULT; + usb_active_config = 0; + ep0_data_phase_if_num = NO_DATA_PHASE_HANDLER; + + // Call reset handler on all interfaces + for(i = 0; i < registered_interfaces_count; i++) { + if(registered_interfaces[i] && registered_interfaces[i]->handle_bus_reset) { + registered_interfaces[i]->handle_bus_reset(); + } + } + + // An USB reset should also deactivate all the interfaces + for(i = 0; i < registered_interfaces_count; i++) { + if(registered_interfaces[i] && registered_interfaces[i]->deactivate_interface) { + registered_interfaces[i]->deactivate_interface(); + } + } + + break; + + case USB_ENUM_DONE : + print("ENUM_DONE event \n"); + + usb_core_cable_state = CABLE_CONNECTED; + + usb_core_configuration_descriptor = usb_core_hs_configuration_descriptor; + usb_core_other_speed_configuration_descriptor = usb_core_fs_configuration_descriptor; + if(usb_controller_get_connection_speed() == CONNECTION_SPEED_FULL) { + usb_core_configuration_descriptor = usb_core_fs_configuration_descriptor; + usb_core_other_speed_configuration_descriptor = usb_core_hs_configuration_descriptor; + } + break; + } +} + +bool usb_core_get_connection_speed (void) +{ + return(usb_controller_get_connection_speed()); +} + +bool usb_core_get_cable_state (void) +{ + return(usb_core_cable_state); +} + +void usb_core_complete_endpoint_io (struct usb_device_io_request *io_req) +{ + if(io_req->callback) { + io_req->callback(io_req); + } + + free(io_req); + io_req = NULL; +} + +void usb_core_do_transfer (int endpoint, u_int8_t *buffer, int length, void (*callback)(struct usb_device_io_request *)) +{ + struct usb_device_io_request *io_request; + + if((io_request = alloc_device_io_request(endpoint, buffer, length, callback)) == NULL) + { + dprintf(DEBUG_INFO, "usb_core_write_data --- alloc device io request failed \n"); + return; + } + + print("starting transfer on %x of size %d \n", endpoint, length); + usb_controller_do_endpoint_io(io_request); +} + +void usb_core_send_zlp (void) +{ + struct usb_device_io_request *io_request = alloc_ep0_device_io_request(NULL, 0, NULL); + + if(io_request == NULL) { + usb_controller_stall_endpoint(EP0_IN, true); + dprintf(DEBUG_INFO, "usb_core : usb_core_send_zlp --- alloc ep0 failed \n"); + return; + } + + usb_controller_do_endpoint_io(io_request); +} + +void usb_core_activate_endpoint (u_int32_t endpoint, int type, int max_packet_size, int interval) +{ + usb_controller_activate_endpoint(endpoint, type, max_packet_size, interval); +} + +void usb_core_abort_endpoint (int endpoint) +{ + usb_controller_abort_endpoint(endpoint); +} + +void usb_core_deactivate_endpoint (u_int32_t endpoint) +{ + usb_controller_abort_endpoint(endpoint); + usb_controller_deactivate_endpoint(endpoint); +} + +void usb_core_stop (void) +{ + usb_controller_stop(); + usb_core_free(); + +#if WITH_HW_POWER + power_set_usb_enabled(false); +#endif // WITH_HW_POWER +} + +void usb_core_free (void) +{ + usb_controller_free(); + + if(usb_core_hs_configuration_descriptor) { + free(usb_core_hs_configuration_descriptor); + usb_core_hs_configuration_descriptor = NULL; + } + + if(usb_core_fs_configuration_descriptor) { + free(usb_core_fs_configuration_descriptor); + usb_core_fs_configuration_descriptor = NULL; + } + +#if WITH_RECOVERY_MODE + if(vendor_device_request_rxbuffer) { + free(vendor_device_request_rxbuffer); + vendor_device_request_rxbuffer = NULL; + } +#endif // WITH_RECOVERY_MODE + + if(nonce_string_desc) { + free(nonce_string_desc); + nonce_string_desc = NULL; + } + + usb_free_string_descriptors(); + registered_interfaces_count = 0; +} diff --git a/drivers/usb/usb_debug.c b/drivers/usb/usb_debug.c new file mode 100644 index 0000000..f73792b --- /dev/null +++ b/drivers/usb/usb_debug.c @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +//=================================================================================== +// USB command stuff +//=================================================================================== + +#if defined(WITH_MENU) && WITH_MENU + +#define USB_CMD_STRING_LEN 1024 + +#define USB_SERIAL_CMD_START 0xfc +#define USB_SERIAL_CMD_END 0xfd +#define USB_SERIAL_CMD_START_OFFSET 1 +#define USB_SERIAL_CMD_END_OFFSET 1 + +static u_int8_t usb_cmd_string[USB_CMD_STRING_LEN] __attribute__ ((aligned(CPU_CACHELINE_SIZE))); + +static int usb_cmd_main(int argc, struct cmd_arg * args); + + +MENU_COMMAND_DEVELOPMENT(usb, usb_cmd_main, "run a USB command", NULL); + +static void usb_print_usage(const char * s) +{ + printf("Usage: \n"); + printf("\t%s get [address] [amount] \n", s); + printf( "\t%s get tftp://servername.com/file.bin [address] [amount] \n", s ); +#if WITH_BULK_UPLOAD + printf( "\t%s put [address] \n", s ); +#endif // WITH_BULK_UPLOAD +} + +#if WITH_BULK_UPLOAD + +static int usb_cmd_put(const char *fileName, uint64_t amount, uintptr_t address, int printCompletionStatus) +{ + int ret = -1; + + if(!fileName) { + printf("File Name is NULL!\n"); + goto error; + } + + if(!amount) { + printf("Amount is 0!\n"); + goto error; + } + + if(usb_serial_is_active() == false) { + printf("PUT failed, run usbterm\n"); + return ret; + } + + const char *prefix = "put "; + int notifyHostLen = strlen(prefix) + strlen(fileName) + + USB_SERIAL_CMD_START_OFFSET + USB_SERIAL_CMD_END_OFFSET; + + if(notifyHostLen > USB_CMD_STRING_LEN) { + printf("File length too long \n"); + goto error; + } + + if(address == 0) { + address = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + printf("Defaulting to address %p\n", (void *)address); + } + + if(!security_allow_memory((void *)address, amount)) { + dprintf(DEBUG_INFO, "Permission Denied\n"); + goto error; + } + + usb_transfer_prepare(USB_TRANSFER_TYPE_BULK_PUT, (void *)address, amount); + + bzero(usb_cmd_string, USB_CMD_STRING_LEN); + usb_cmd_string[0] = USB_SERIAL_CMD_START; + memcpy(usb_cmd_string + USB_SERIAL_CMD_START_OFFSET, prefix, strlen(prefix)); + memcpy(usb_cmd_string + USB_SERIAL_CMD_START_OFFSET + strlen(prefix), fileName, + notifyHostLen - USB_SERIAL_CMD_START_OFFSET - USB_SERIAL_CMD_END_OFFSET); + usb_cmd_string[notifyHostLen - 1] = USB_SERIAL_CMD_END; + + ret = usb_serial_send_cmd_string(usb_cmd_string, notifyHostLen); + if(ret != 0) + goto error; + + ret = usb_transfer_start(); + + if(ret <= 0) { + goto error; + } + + amount = ret; + + if (printCompletionStatus) + printf("PUT complete, amount %llu\n", amount); + + // set the file size and return code + env_set_uint("filesize", amount, 0 ); + + return 0; + +error: + printf("PUT failed. \n"); + env_set_uint("filesize", 0, 0); + return -1; +} + +int usb_send_data_to_file(const char *filename, size_t amount, uintptr_t address, int printCompletionStatus) +{ + return usb_cmd_put(filename, amount, address, printCompletionStatus); +} + +#endif // WITH_BULK_UPLOAD + +static int usb_cmd_get(int argc, struct cmd_arg *args) +{ + int ret = -1; + + if(usb_core_get_cable_state() == CABLE_DISCONNECTED) { + printf("GET failed, cable missing\n"); + return ret; + } + + if(usb_serial_is_active() == false) { + printf("GET failed, run usbterm\n"); + return ret; + } + + const char *prefix = "get "; + const char * fileName = args[0].str; + int notifyHostLen = strlen(prefix) + strlen(fileName) + + USB_SERIAL_CMD_START_OFFSET + USB_SERIAL_CMD_END_OFFSET; + + addr_t address = 0; + uint64_t amount = 0; + + if(notifyHostLen > USB_CMD_STRING_LEN) { + printf("File length too long \n"); + goto error; + } + + if(argc >= 2) { + address = args[1].u; + if(argc >= 3) { + amount = args[2].u; + } + } + + if(address == 0) { + address = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + printf("Defaulting to address %p\n", (void *)address); + } + + if(amount > DEFAULT_RAMDISK_SIZE) { + printf("Amount too large \n"); + goto error; + } + + if(amount == 0) { + amount = DEFAULT_RAMDISK_SIZE; + } + + if(!security_allow_memory((void *)address, amount)) { + dprintf(DEBUG_INFO, "Permission Denied\n"); + goto error; + } + + usb_transfer_prepare(USB_TRANSFER_TYPE_BULK_GET, (void *)address, amount); + bzero((void *)usb_cmd_string, USB_CMD_STRING_LEN); + usb_cmd_string[0] = USB_SERIAL_CMD_START; + memcpy(usb_cmd_string + USB_SERIAL_CMD_START_OFFSET, prefix, strlen(prefix)); + memcpy(usb_cmd_string + USB_SERIAL_CMD_START_OFFSET + strlen(prefix), fileName, + notifyHostLen - USB_SERIAL_CMD_START_OFFSET - USB_SERIAL_CMD_END_OFFSET); + usb_cmd_string[notifyHostLen - 1] = USB_SERIAL_CMD_END; + + ret = usb_serial_send_cmd_string(usb_cmd_string, notifyHostLen); + + if(ret != 0) { + goto error; + } + + ret = usb_transfer_start(); + + if(ret <= 0) { + goto error; + } + + amount = ret; + + printf("GET complete, amount %llu\n", amount); + + // set the file size and return code + env_set_uint( "filesize", amount, 0 ); + + ret = 0; + + return 0; + +error: + printf("GET failed. \n"); + env_set_uint("filesize", 0, 0); + return -1; +} + +static int usb_cmd_main(int argc, struct cmd_arg *args) +{ + int ret = 0; + const char *s = args[1].str; + + if(!s) { + ret = -1; + } + else { + if(!strcmp(s, "get")) { + + if((argc < 3) || (argc > 5)) { + goto print_usage; + } + + ret = usb_cmd_get(argc - 2, args + 2); + } +#if WITH_BULK_UPLOAD + else if(!strcmp(s, "put")) { + + if((argc < 4) || (argc > 5)) { + goto print_usage; + } + + ret = usb_cmd_put(args[2].str, args[3].u, (argc == 5) ? args[4].u : 0, 1); + } +#endif // WITH_BULK_UPLOAD + else { + goto print_usage; + } + } + + return ret; + +print_usage: + usb_print_usage( args[0].str ); + return 0; + +} + +#endif diff --git a/drivers/usb/usb_dfu.c b/drivers/usb/usb_dfu.c new file mode 100644 index 0000000..56362eb --- /dev/null +++ b/drivers/usb/usb_dfu.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +//////////////////////////////////////////////////////////////////// +// USB DFU +// +// This file implements usb dfu protocol (just download). This is used +// in SecureROM. +//////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#define print(fmt, args...) printf("%s --- " fmt, __FUNCTION__, ##args) +#else +#define print(fmt, args...) (void)0 +#endif + + +struct usb_dfu_run_time_descriptor { + uint8_t length; + uint8_t type; + uint8_t bmAttributes; + uint16_t wDetachTimeOut; + uint16_t wTransferSize; +} __attribute__((packed)); + +struct usb_dfu_status_request +{ + UInt8 bStatus; + UInt8 bwPollTimeout[3]; + UInt8 bState; + UInt8 iString; +} __attribute__((packed)); + +enum { + DFU_DETACH = 0, + DFU_DNLOAD, + DFU_UPLOAD, + DFU_GETSTATUS, + DFU_CLR_STATUS, + DFU_GETSTATE, + DFU_ABORT +}; + +enum { + appIDLE, + appDETACH, + dfuIDLE, + dfuDNLOAD_SYNC, + dfuDNBUSY, + dfuDNLOAD_IDLE, + dfuMANIFEST_SYNC, + dfuMANIFEST, + dfuMANIFEST_WAIT_RESET, + dfuUPLOAD_IDLE, + dfuERROR +}; + +enum { + errOK = 0, + errADDRESS = 0x08, + errNOTDONE = 0x09, + errSTALLEDPKT = 0x0f +}; + +#define DD_DFU (0x21) +#define USB_DFU_RUN_TIME_DT_SIZE (7) +#define DFU_MAX_TRANSFER_SIZE (2 * 1024) +#define DETACH_TIMEOUT_MS (10) +#define DFU_FILE_SUFFIX_LENGTH (16) + +//the polling delay we generally report in GETSTATUS requests +#define STANDARD_DELAY_MS 50 + +//the delay we report after completing the file download. I don't think it needs to be different +//from the standard delay but this is what m68 h1 rom does. +#define DL_DONE_DELAY_MS 3000 + +#define DFU_BMATTRIBUTES (1 << 0) // download only + +struct usb_dfu_io_buffer { + u_int8_t bytes[DFU_MAX_TRANSFER_SIZE]; +}; + +static const struct usb_interface_descriptor usb_dfu_interface_descriptor = { + USB_DT_INTERFACE_SIZE, + USB_DT_INTERFACE, + APPLE_USB_DFU_INTF, + 0, + 0, + APPLE_USB_DFU_CLASS, + APPLE_USB_DFU_SUBCLASS, + APPLE_USB_DFU_PROTOCOL, + 0 +}; + +static const struct usb_dfu_run_time_descriptor usb_dfu_run_time_desc = { + USB_DFU_RUN_TIME_DT_SIZE, + DD_DFU, + DFU_BMATTRIBUTES, + DETACH_TIMEOUT_MS, + DFU_MAX_TRANSFER_SIZE +}; + +static bool usb_dfu_inited; +static struct usb_interface_instance usb_dfu_interface_instance; +static struct usb_dfu_status_request status_req; +static struct task_event dfu_event; +static volatile uint8_t dfu_state; +static volatile bool dfu_done; +static struct usb_dfu_io_buffer *io_buffer; +static int completion_status; +static u_int8_t *image_buffer; +static u_int32_t image_buffer_size; +static u_int32_t total_received; +static u_int32_t expecting; + +static void set_status(u_int8_t bStatus, int bwPollTimeout, u_int8_t bState, u_int8_t iString); +static int handle_interface_request(struct usb_device_request *request, uint8_t **out_buffer); +static int handle_dfu_request(struct usb_device_request *setup, uint8_t **buffer); +static void handle_bus_reset(void); +static void data_received(u_int32_t received); + + +int getDFUImage(void* buffer, int maxlen) +{ + dprintf(DEBUG_INFO, "Trying to get a file with DFU.\n" ); + + // save the info provided by our caller + image_buffer = buffer; + image_buffer_size = maxlen; + + print( "Initializing USB...\n" ); +#if WITH_PLATFORM_INIT_USB + if(platform_init_usb() != 0) + goto exit; +#else + if(usb_init() != 0) + goto exit; +#endif + + // wait here till dfu download is finished + while(!dfu_done) event_wait(&dfu_event); + dprintf(DEBUG_INFO, "DFU complete, status=%d\n", completion_status); + +exit: + print( "Exiting USB...\n" ); + usb_quiesce(); + + return completion_status; +} + +int usb_dfu_init() +{ + if(usb_dfu_inited) return 0; + + io_buffer = memalign(sizeof(*io_buffer), CPU_CACHELINE_SIZE); + bzero((void *)io_buffer, sizeof(*io_buffer)); + + set_status(errOK, STANDARD_DELAY_MS, dfuIDLE, 0); + + completion_status = -1; + total_received = 0; + dfu_done = false; + + event_init(&dfu_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + usb_dfu_interface_instance.total_interfaces = APPLE_USB_DFU_TOTAL_INTFS; + usb_dfu_interface_instance.interface_descs = (struct usb_interface_descriptor *)&usb_dfu_interface_descriptor; + usb_dfu_interface_instance.total_other_descs = 1; + usb_dfu_interface_instance.other_descs = (void *)&usb_dfu_run_time_desc; + usb_dfu_interface_instance.handle_request = handle_interface_request; + usb_dfu_interface_instance.non_setup_data_phase_finished_callback = data_received; + usb_dfu_interface_instance.handle_bus_reset = handle_bus_reset; + + usb_core_register_interface(&usb_dfu_interface_instance); + + usb_dfu_inited = true; + + return 0; +} + +void usb_dfu_exit() +{ + if(!usb_dfu_inited) return; + + bzero((void*)&usb_dfu_interface_instance, sizeof(struct usb_interface_instance)); + + if(io_buffer) { + free(io_buffer); + io_buffer = NULL; + } + + usb_dfu_inited = false; +} + + +static void set_status(u_int8_t bStatus, int bwPollTimeout, u_int8_t bState, u_int8_t iString) +{ + status_req.bStatus = bStatus; + status_req.bwPollTimeout[0]= bwPollTimeout & 0xff; + status_req.bwPollTimeout[1]= (bwPollTimeout >> 8) & 0xff; + status_req.bwPollTimeout[2]= (bwPollTimeout >> 16) & 0xff; + dfu_state = status_req.bState = bState; + status_req.iString = iString; +} + +static int handle_interface_request(struct usb_device_request *request, uint8_t **out_buffer) +{ + u_int8_t bRequest = request->bRequest; + u_int16_t wLength = request->wLength; + int ret; + + print("type: %d\n", (request->bmRequestType & USB_REQ_DIRECTION_MASK)); + print("request=%02x wValue=%04x index=%d length=%d\n", bRequest, + request->wValue, request->wIndex, wLength); + + ret = -1; + + // DFU_GETSTATE and DFU_GETSTATUS request are DEVICE2HOST + // request. Response for these requests are copied into + // io_buffer. + // DFU_DNLOAD request is HOST2DEVICE type request. We pass our + // io_buffer to the stack to copy the data from the host. + // + // io_buffer is gauranteed to be larger than any data needs to + // be copied into it. + if((request->bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) + { + if(out_buffer == NULL) + return -1; + + switch(bRequest) + { + case DFU_DNLOAD: + { + if(wLength == 0) { + print("File transfer complete. Waiting for status sync.\n"); + set_status(errOK, STANDARD_DELAY_MS, dfuMANIFEST_SYNC, 0); + } + else { + if(wLength > sizeof(*io_buffer)) { + // cleanest way to recover is to stall here + set_status(errSTALLEDPKT, STANDARD_DELAY_MS, dfuIDLE, 0); + return -1; + } + + *out_buffer = (uint8_t *)io_buffer; + } + expecting = wLength; + ret = wLength; + break; + } + case DFU_CLR_STATUS : + case DFU_ABORT: + { + set_status(errOK, STANDARD_DELAY_MS, dfuIDLE, 0); + + total_received = 0; + + if(!dfu_done) { + completion_status = -1; + dfu_done = true; + event_signal(&dfu_event); + } + ret = 0; + break; + } + } + + return ret; + } + else if((request->bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_DEVICE2HOST) + { + switch(bRequest) { + + case DFU_GETSTATE: + print("Returning state = %d\n", dfu_state); + *(u_int8_t *)io_buffer = dfu_state; + ret = 1; + break; + + case DFU_GETSTATUS: + memcpy((u_int8_t *)io_buffer, (void *)&status_req, sizeof(struct usb_dfu_status_request)); + + if(dfu_state == dfuMANIFEST_SYNC) { + set_status(errOK, DL_DONE_DELAY_MS, dfuMANIFEST, 0); + } + else if(dfu_state == dfuMANIFEST) { + // XXX TODO: validate DFU File Suffix? For now erase them + RELEASE_ASSERT(total_received >= DFU_FILE_SUFFIX_LENGTH); + RELEASE_ASSERT(image_buffer != NULL); + completion_status = total_received - DFU_FILE_SUFFIX_LENGTH; + bzero((void *)&image_buffer[completion_status], DFU_FILE_SUFFIX_LENGTH); + total_received = 0; + + // transitioning to this state will break us out of the file wait loop + set_status(errOK, STANDARD_DELAY_MS, dfuMANIFEST_WAIT_RESET, 0); + } + + ret = sizeof(struct usb_dfu_status_request); + break; + } + + if(ret < 0) + return -1; + + usb_core_do_transfer(EP0_IN, (u_int8_t *)io_buffer, ret, NULL); + + return 0; + } + + return -1; +} + +static void handle_bus_reset(void) +{ + if(dfu_state == dfuMANIFEST_WAIT_RESET) { + dfu_done = true; + event_signal(&dfu_event); + } +} + +static void data_received(u_int32_t received) +{ + print("DFU received %d of %d\n", received, expecting); + + if(received != expecting) { + set_status(errNOTDONE, STANDARD_DELAY_MS, dfuERROR, 0); + } + else if((total_received + received) > image_buffer_size) { + set_status(errADDRESS, STANDARD_DELAY_MS, dfuERROR, 0); + } + else { + if(!security_allow_memory(&image_buffer[total_received], received)) { + dprintf(DEBUG_INFO, "Permission Denied\n"); + completion_status = -1; + dfu_done = true; + event_signal(&dfu_event); + return; + } + + memcpy(&image_buffer[total_received], (void *)io_buffer, received); + total_received += received; + expecting = 0; + set_status(errOK, STANDARD_DELAY_MS, dfuDNLOAD_IDLE, 0); + } +} diff --git a/drivers/usb/usb_dockfifo_controller.c b/drivers/usb/usb_dockfifo_controller.c new file mode 100644 index 0000000..0eacabb --- /dev/null +++ b/drivers/usb/usb_dockfifo_controller.c @@ -0,0 +1,904 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +// #undef DEBUG_LEVEL +// #define DEBUG_LEVEL DEBUG_SPEW + +/* + * 3 bytes header: + * 1byte: endpoint and flags + * bit 7 is direction: + * 0: Host to Device (OUT in USB terms) + * 1: Device to Host (IN in USB terms) + * bit 6 is control packet phase: + * 0: data or N/A + * 1: setup + * bit 5 is fragment continuation: + * 0: last or only packet in fragment + * 1: more packets follow, continuing data + * ep 31: reserved for link control management + * ep 0-30: available + * + * Controller management requests: 1 byte + data + * 1byte: command + * nbytes: data + */ + +#define EP_DIR_OUT (0 << 7) +#define EP_DIR_IN (1 << 7) +#define EP_DIR_MASK (1 << 7) + +#define EP_PHASE_DATA (0 << 6) +#define EP_PHASE_SETUP (1 << 6) +#define EP_PHASE_MASK (1 << 6) + +#define EP_FRAG_LAST (0 << 5) +#define EP_FRAG_MORE (1 << 5) +#define EP_FRAG_MASK (1 << 5) + +#define EP_NUM_MASK 0x1f +#define EP_LINK_CONTROL 0x1f + +#define MAX_EP_NUMBER 5 +#define MAX_EP_NEEDED (MAX_EP_NUMBER * 2 + 2) // 2*EP and EP0 IN/OUT + +#define ep_to_epnum(ep) ((ep) & EP_NUM_MASK) +#define ep_to_epdir(ep) ((ep) & EP_DIR_MASK) +#define ep_to_epindex(ep) ((2 * ep_to_epnum((ep))) + (ep_to_epdir((ep)) ? 0 : 1)) + +enum { + // Host to Device + kCommand_LinkReady = 0x01, // 4 bytes: nonce + kCommand_HostConnect = 0x02, // no data + kCommand_HostDisconnect = 0x03, // no data + kCommand_DeviceBusReset = 0x04, // no data + kCommand_DeviceConnectionSpeed = 0x05, // 1 byte: FS or HS + + // Device to Host + kCommand_LinkReadyAck = 0x81, // 4 bytes: repeat nonce from LinkReady command + kCommand_DeviceConnect = 0x82, // no data + kCommand_DeviceDisconnect = 0x83, // no data + kCommand_ConfigureEndpoint = 0x84, // 2 bytes: ep# (msb is direction), XXX config data to be defined + kCommand_EnableEndpoint = 0x85, // 2 byte: ep#, enable (1) or disable (0) + kCommand_StallEndpoint = 0x86, // 2 byte: ep#, set (1) or clear (0) stall + kCommand_Error = 0xff // 1+ bytes: code, data +}; + +enum { + kError_OK = 0x00, // No error + kError_LinkNotReady = 0x01, // Need LinkReady first +}; + +#define MAX_PAYLOAD_SIZE (512) + +enum { + kEndpointState_Free = 0, + kEndpointState_Allocated_Idle = (1 << 0), + kEndpointState_Allocated_Busy = (1 << 1), + kEndpointState_Allocated_AbortRequested = (1 << 2), + kEndpointState_Allocated_Stalled = (1 << 3), +}; + +struct usb_endpoint_instance +{ + uint32_t endpoint_address; + uint32_t max_packet_size; + uint32_t attributes; + uint32_t bInterval; + + uint32_t state; + struct task_event idle_state_event; + uint32_t remote_available; + + struct usb_device_io_request *io_request; +}; + +static void usb_dockfifo_stall_endpoint(uint32_t endpoint, bool stall); + +static bool usb_dockfifo_link_ready; +static uint8_t usb_connection_speed; +static bool usb_ep0_data_phase_expected; +static struct usb_endpoint_instance usb_dockfifo_endpoints[MAX_EP_NEEDED]; +static struct task *usb_dockfifo_main_task_handle; +static struct task *usb_dockfifo_writer_task_handle; +static struct task_event usb_dockfifo_writer_task_event; +static uint8_t usb_dockfifo_read_buffer_data[MAX_PAYLOAD_SIZE + 1]; +static size_t usb_dockfifo_read_buffer_bytes; + +//======================= +// Local funtions +//======================= + +static void dump_bytes(uint8_t *buffer, size_t size) +{ + int32_t i; + + dprintf(DEBUG_INFO, "===\n"); + for(i = 0; i < (int32_t)size; i++) { + dprintf(DEBUG_INFO, "%02x ", buffer[i]); + } + dprintf(DEBUG_INFO, "\n===\n"); +} + +static int32_t usb_dockfifo_read_data() +{ + static int frame_count = 0; + int32_t ret = dockfifo_bulk_read_frame( + usb_dockfifo_read_buffer_data, + sizeof(usb_dockfifo_read_buffer_data), + &usb_dockfifo_read_buffer_bytes); + if ((ret != 0) || (usb_dockfifo_read_buffer_bytes < 1)) { + dprintf(DEBUG_INFO, "failed to read frame: %d\n", ret); + return ret; + } + dprintf(DEBUG_SPEW, "Receive frame %d\n", ++frame_count); + return 0; +} + +static int32_t usb_dockfifo_send_bytes(const uint8_t *data, size_t size) +{ + static int frame_count = 0; + dprintf(DEBUG_SPEW, "Send frame %d\n", ++frame_count); + int32_t ret = dockfifo_bulk_write_frame(data, size); + if (ret != 0) { + dprintf(DEBUG_INFO, "failed to write frame: %d\n", ret); + return ret; + } + return 0; +} + +static void usb_dockfifo_go_on_bus(bool on) +{ + uint8_t data[2]; + + data[0] = EP_LINK_CONTROL | EP_DIR_IN; + if (on) + data[1] = kCommand_DeviceConnect; + else + data[1] = kCommand_DeviceDisconnect; + usb_dockfifo_send_bytes(data, sizeof(data)); +} + +static void usb_dockfifo_send_error(uint8_t error_code) +{ + dprintf(DEBUG_INFO, "Responding with error 0x%02x\n", error_code); + + uint8_t data[3] = { + EP_LINK_CONTROL | EP_DIR_IN, + kCommand_Error, + error_code + }; + usb_dockfifo_send_bytes(data, sizeof(data)); +} + +static void usb_dockfifo_send_available(uint8_t epnum) +{ + dprintf(DEBUG_SPEW, "ep%02xOUT available\n", epnum); + + uint8_t data[3] = { + epnum | EP_DIR_OUT, + MAX_PAYLOAD_SIZE & 0xff, + (MAX_PAYLOAD_SIZE >> 8) & 0xff + }; + usb_dockfifo_send_bytes(data, sizeof(data)); +} + +static void usb_dockfifo_handle_ready(void) +{ + dprintf(DEBUG_SPEW, "Got READY packet. Replying.\n"); + + // Send ReadyAck. + uint8_t data[8]; + data[0] = EP_LINK_CONTROL | EP_DIR_IN; + data[1] = kCommand_LinkReadyAck; + // Ping back with the same nonce value we received. + memcpy(data + 2, usb_dockfifo_read_buffer_data + 2, 4); + // Inform the host about the max packet size (not including + // endpoint byte) we can receive. + ASSERT(DOCKFIFO_BULK_MRU >= MAX_PAYLOAD_SIZE + 1); + write_le_16(data, 6, MAX_PAYLOAD_SIZE); + + usb_dockfifo_send_bytes(data, sizeof(data)); + + // Accept other packets. + usb_dockfifo_link_ready = true; +} + +static void usb_dockfifo_handle_link_control(void) +{ + // Handle commands from the host. + if (usb_dockfifo_read_buffer_bytes < 2) { + dprintf(DEBUG_INFO, + "Expected LinkControl bytes >= 2, got %d\n", + (int) usb_dockfifo_read_buffer_bytes); + return; + } + uint8_t command = usb_dockfifo_read_buffer_data[1]; + if ((!usb_dockfifo_link_ready) && (command != kCommand_LinkReady)) { + dprintf(DEBUG_INFO, "Require Ready command first, got 0x%02x\n", + command); + // Tell host it needs to reset its session. + usb_dockfifo_send_error(kError_LinkNotReady); + return; + } + + switch (command) { + case kCommand_LinkReady: + dprintf(DEBUG_INFO, "Got Ready command\n"); + usb_dockfifo_handle_ready(); + break; + + case kCommand_HostConnect: + { + dprintf(DEBUG_INFO, "Got HostConnected command\n"); + usb_core_event_handler(CABLE_CONNECTED); + usb_dockfifo_go_on_bus(true); + break; + } + + case kCommand_DeviceBusReset: + dprintf(DEBUG_INFO, "Got DeviceBusReset command\n"); + usb_core_event_handler(USB_RESET); + break; + + case kCommand_DeviceConnectionSpeed: + dprintf(DEBUG_INFO, "Got DeviceConnectionSpeed command\n"); + if (usb_dockfifo_read_buffer_bytes < 3) { + dprintf(DEBUG_INFO, + "Expected 3 bytes for DeviceConnectionSpeed\n"); + break; + } + usb_connection_speed = usb_dockfifo_read_buffer_data[2] ? + CONNECTION_SPEED_HIGH : CONNECTION_SPEED_FULL; + usb_core_event_handler(USB_ENUM_DONE); + break; + + case kCommand_HostDisconnect: + dprintf(DEBUG_INFO, "Got HostDisconnected command\n"); + usb_core_event_handler(CABLE_DISCONNECTED); + usb_dockfifo_go_on_bus(false); + break; + + default: + dprintf(DEBUG_INFO, "Unknown command 0x%02x\n", command); + } +} + +static void usb_dockfifo_handle_endpoint_out(uint32_t endpoint, const uint8_t *buffer, size_t bytes) +{ + dprintf(DEBUG_SPEW, "handle epout %02x %d\n", endpoint, (int) bytes); + // Get endpoint. + size_t epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + uint32_t ep_num = ep_to_epnum(endpoint); + ASSERT((ep_num <= EP_NUM_MASK) && (ep_num != EP_LINK_CONTROL)); + struct usb_endpoint_instance *ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + if ((ep->io_request == NULL) || (ep->state & kEndpointState_Allocated_AbortRequested)) { + dprintf(DEBUG_INFO, "Dropping unexpected data received for endpoint %x, state:%d io_request:%p\n", endpoint, ep->state, ep->io_request); + return; + } + + // Get IO request, transfer size. + struct usb_device_io_request *req = ep->io_request; + ASSERT(req != NULL); + uint32_t xfer_size = req->io_length - req->return_count; + + // Make sure we have space left to copy this data + RELEASE_ASSERT(bytes <= xfer_size); + + // Save data received + memcpy((void *) req->io_buffer + req->return_count, buffer, bytes); + + // Update IO request. + req->return_count += bytes; + + dprintf(DEBUG_SPEW, "ep%02xout now %d/%d\n", + ep_num, (int) req->return_count, (int) req->io_length); + + if ((bytes == ep->max_packet_size) && + (req->return_count < req->io_length) && + ((ep->state & kEndpointState_Allocated_AbortRequested) == 0)) { + // More data to be received + dprintf(DEBUG_SPEW, "More to be received\n"); + usb_dockfifo_send_available(ep_to_epnum(req->endpoint)); + return; + } else { + // Completed transaction, update status and return + dprintf(DEBUG_SPEW, "Completed a transaction\n"); + ep->io_request = NULL; + uint32_t old_state = ep->state; + ep->state = kEndpointState_Allocated_Idle; + event_signal(&ep->idle_state_event); + if (!(old_state & kEndpointState_Allocated_AbortRequested)) { + req->status = USB_IO_SUCCESS; + usb_core_complete_endpoint_io(req); + } + } +} + +static void usb_dockfifo_start_endpoint_in(uint32_t endpoint) +{ + static uint8_t buf[MAX_PAYLOAD_SIZE + 1]; + + // Get endpoint. + size_t epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + uint32_t ep_num = ep_to_epnum(endpoint); + ASSERT((ep_num <= EP_NUM_MASK) && (ep_num != EP_LINK_CONTROL)); + struct usb_endpoint_instance *ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + // Get IO request, transfer size. + struct usb_device_io_request *req = ep->io_request; + ASSERT(req != NULL); + uint32_t xfer_size = req->io_length - req->return_count; + + // Fragment the request if it exceeds max buffer size. + bool fragment = false; + if (xfer_size > MAX_PAYLOAD_SIZE) { + xfer_size = MAX_PAYLOAD_SIZE; + fragment = true; + } + + // Should be some remote buffer space available before this function + // was invoked. + ASSERT(ep->remote_available > 0); + if (xfer_size > ep->remote_available) { + xfer_size = ep->remote_available; + fragment = true; + } + ep->remote_available = 0; + + // Encode the endpoint and transfer flags. + uint8_t encoded_ep = ep_num | EP_DIR_IN; + if (fragment) { + encoded_ep |= EP_FRAG_MORE; + } + + dprintf(DEBUG_SPEW, "ep_num:0x%02x sent:%d io_len:%d xfer:%d frag:%d\n", + ep_num, + (int) req->return_count, + (int) req->io_length, + (int) xfer_size, + (int) fragment); + + // Send encoded endpoint|flags, followed by payload. + buf[0] = encoded_ep; + memcpy(buf + 1, (void *) req->io_buffer + req->return_count, xfer_size); + usb_dockfifo_send_bytes(buf, xfer_size + 1); + dprintf(DEBUG_SPEW, "Sent\n"); + + // Update IO request. + req->return_count += xfer_size; + + if (fragment && ((ep->state & kEndpointState_Allocated_AbortRequested) == 0)) { + // More data needs transmitting for this packet. + event_signal(&usb_dockfifo_writer_task_event); + } else { + // Completed this packet, update status and return + uint32_t old_state = ep->state; + ep->state = kEndpointState_Allocated_Idle; + event_signal(&ep->idle_state_event); + if (!(old_state & kEndpointState_Allocated_AbortRequested)) { + req->status = USB_IO_SUCCESS; + ep->io_request = NULL; + usb_core_complete_endpoint_io(req); + } + } +} + +static bool usb_dockfifo_handle_ep0_data(uint8_t *buf, size_t bytes, + bool *data_phase) +{ + // Fragment into EP0_MAX_PACKET_SIZE chunks. + while (bytes > 0) { + size_t to_receive = EP0_MAX_PACKET_SIZE; + if (to_receive > bytes) { + to_receive = bytes; + } + usb_core_handle_usb_control_receive(buf, false, to_receive, + data_phase); + buf += to_receive; + bytes -= to_receive; + if (bytes > 0 && !*data_phase) { + dprintf(DEBUG_INFO, "Began setup phase in fragment\n"); + return false; + } + } + return true; +} + +static bool usb_dockfifo_dispatch_ep_out(void) +{ + ASSERT(usb_dockfifo_read_buffer_bytes >= 1); + + uint8_t endpoint = usb_dockfifo_read_buffer_data[0]; + ASSERT((endpoint & EP_DIR_MASK) == EP_DIR_OUT); + + switch (endpoint & ~EP_FRAG_MASK) { + case EP_LINK_CONTROL | EP_DIR_OUT: + usb_dockfifo_handle_link_control(); + return true; + + case 0 | EP_PHASE_SETUP | EP_DIR_OUT: + dprintf(DEBUG_SPEW, "Setup packet received\n"); + if (usb_dockfifo_read_buffer_bytes < 1 + SETUP_PACKET_LEN) { + dprintf(DEBUG_INFO, + "Setup packet too small: %d\n", + (int) usb_dockfifo_read_buffer_bytes); + return false; + } + if (usb_dockfifo_read_buffer_bytes > 1 + EP0_MAX_PACKET_SIZE) { + dprintf(DEBUG_INFO, + "Setup packet too big: %d\n", + (int) usb_dockfifo_read_buffer_bytes); + return false; + } + // auto-clear stall if endpoint was previously stalled + usb_dockfifo_stall_endpoint(0x80, false); + usb_ep0_data_phase_expected = false; + usb_core_handle_usb_control_receive( + usb_dockfifo_read_buffer_data + 1, true, + SETUP_PACKET_LEN, + &usb_ep0_data_phase_expected); + return true; + + case 0 | EP_PHASE_DATA | EP_DIR_OUT: + dprintf(DEBUG_SPEW, "Data phase for setup packet\n"); + usb_ep0_data_phase_expected = false; + if (!usb_dockfifo_handle_ep0_data( + usb_dockfifo_read_buffer_data + 1, + usb_dockfifo_read_buffer_bytes - 1, + &usb_ep0_data_phase_expected)) { + return false; + } + return true; + + default: + usb_dockfifo_handle_endpoint_out( + (endpoint & ~EP_FRAG_MASK), + (usb_dockfifo_read_buffer_data + 1), + (usb_dockfifo_read_buffer_bytes - 1)); + return true; + } +} + +static bool usb_dockfifo_dispatch_ep_in(void) +{ + // Update remote_available for this endpoint. + + ASSERT(usb_dockfifo_read_buffer_bytes >= 1); + uint8_t endpoint = usb_dockfifo_read_buffer_data[0]; + ASSERT((endpoint & EP_DIR_MASK) == EP_DIR_IN); + uint32_t ep_num = ep_to_epnum(endpoint); + ASSERT((ep_num <= EP_NUM_MASK) && (ep_num != EP_LINK_CONTROL)); + size_t epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + struct usb_endpoint_instance *ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + if (usb_dockfifo_read_buffer_bytes < 3) { + dprintf(DEBUG_INFO, "Runt EPIN packet\n"); + return false; + } + + uint16_t available = 0; + memcpy(&available, &usb_dockfifo_read_buffer_data[1], + sizeof(available)); + ep->remote_available = available; + dprintf(DEBUG_SPEW, "ep%02x remote_available %d\n", + (int) ep_num, (int) available); + + if (available > 0) { + // Writer task may have been waiting to send data. + event_signal(&usb_dockfifo_writer_task_event); + } + + return true; +} + +static void usb_dockfifo_main_task_session(void) +{ + dprintf(DEBUG_INFO, "DockFifo USB session started\n"); + + // Reset USB state. + usb_core_event_handler(USB_RESET); + + // Require a Ready packet first. + usb_dockfifo_link_ready = false; + + // Wait for DOCK_CONNECT. + while (platform_get_dock_connect() == false) { + dprintf(DEBUG_INFO, "Waiting for dock connect\n"); + task_sleep(100*1000); + } + + // Loop while in a good state. Breaking out of the loop breaks + // the link until a new Ready packet is received. + for (;;) { + dprintf(DEBUG_SPEW, "main loop\n"); + // Read a packet. + usb_dockfifo_read_data(); + if (usb_dockfifo_read_buffer_bytes < 1) { + dprintf(DEBUG_INFO, "Runt packet\n"); + break; + } + + // Get endpoint number. + uint8_t endpoint = usb_dockfifo_read_buffer_data[0]; + dprintf(DEBUG_SPEW, "Got EP%s%02x %s %s %d\n", + (endpoint & EP_DIR_MASK) == EP_DIR_OUT ? "OUT" : "IN", + endpoint & EP_NUM_MASK, + (endpoint & EP_PHASE_MASK) == EP_PHASE_DATA ? + "data" : "setup", + (endpoint & EP_FRAG_MASK) == EP_FRAG_MORE ? + "frag" : "no frag", + (int) (usb_dockfifo_read_buffer_bytes - 1)); + + // If we're not Link-Ready yet, any packet other than + // LinkReady will be responded with an error, but we + // don't need to exit the loop. + if (!usb_dockfifo_link_ready && + endpoint != (EP_LINK_CONTROL | EP_DIR_OUT)) { + dprintf(DEBUG_INFO, "Non-link packet before Ready\n"); + // Tell host it needs to reset its session. + usb_dockfifo_send_error(kError_LinkNotReady); + continue; + } + + // Dispatch based on endpoint. + bool ok; + if ((endpoint & EP_DIR_MASK) == EP_DIR_OUT) { + ok = usb_dockfifo_dispatch_ep_out(); + } else { + ok = usb_dockfifo_dispatch_ep_in(); + } + if (!ok) { + break; + } + } + + dprintf(DEBUG_INFO, "dockfifo USB session ended\n"); +} + +static int usb_dockfifo_main_task(void *args) +{ + for (;;) { + // Keep re-trying sessions. If there are protocol + // errors, restart from scratch. + usb_dockfifo_main_task_session(); + } +} + +static int usb_dockfifo_writer_task(void *args) +{ + for (;;) { + static int32_t current_ep_in; + + event_wait(&usb_dockfifo_writer_task_event); + + // walk through IN endpoints for any pending io's, if nothing pending wait for more work + for (current_ep_in = 0; current_ep_in < MAX_EP_NEEDED; current_ep_in += 2) { + if ((usb_dockfifo_endpoints[current_ep_in].state == kEndpointState_Allocated_Busy) && + (usb_dockfifo_endpoints[current_ep_in].io_request != NULL) && + (usb_dockfifo_endpoints[current_ep_in].remote_available > 0)) + usb_dockfifo_start_endpoint_in(usb_dockfifo_endpoints[current_ep_in].endpoint_address); + } + } + + return 0; +} + +static int usb_dockfifo_init() +{ + bzero(usb_dockfifo_endpoints, sizeof(struct usb_endpoint_instance) * MAX_EP_NEEDED); + + // main task to do initial handshake and enumeration + usb_dockfifo_main_task_handle = task_create("usb_dockfifo main", usb_dockfifo_main_task, NULL, 0x1000); + + // writer task + usb_dockfifo_writer_task_handle = task_create("usb_dockfifo writer", usb_dockfifo_writer_task, NULL, 0x1000); + + event_init(&usb_dockfifo_writer_task_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + return 0; +} + +static void usb_dockfifo_free() +{ +// dockfifo_bulk_quiesce(); +} + +static int usb_dockfifo_start() +{ + event_init(&usb_dockfifo_endpoints[ep_to_epindex(EP0_IN)].idle_state_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + usb_dockfifo_endpoints[ep_to_epindex(EP0_IN)].endpoint_address = 0x80; + usb_dockfifo_endpoints[ep_to_epindex(EP0_IN)].max_packet_size = EP0_MAX_PACKET_SIZE; + usb_dockfifo_endpoints[ep_to_epindex(EP0_IN)].state = kEndpointState_Allocated_Idle; + + event_init(&usb_dockfifo_endpoints[ep_to_epindex(EP0_OUT)].idle_state_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + usb_dockfifo_endpoints[ep_to_epindex(EP0_OUT)].endpoint_address = 0; + usb_dockfifo_endpoints[ep_to_epindex(EP0_OUT)].max_packet_size = EP0_MAX_PACKET_SIZE; + usb_dockfifo_endpoints[ep_to_epindex(EP0_OUT)].state = kEndpointState_Allocated_Idle; + + dockfifo_bulk_init(); + + task_start(usb_dockfifo_main_task_handle); + task_start(usb_dockfifo_writer_task_handle); + + return 0; +} + +static void usb_dockfifo_stop() +{ + usb_dockfifo_go_on_bus(false); +} + +static void usb_dockfifo_set_address(uint32_t new_address) +{ +} + +static int usb_dockfifo_get_connection_speed() +{ + return usb_connection_speed; +} + +static void usb_dockfifo_activate_endpoint(uint32_t endpoint, int type, int max_packet_size, int interval) +{ + uint32_t epindex; + struct usb_endpoint_instance *ep; + + enter_critical_section(); + + ASSERT(ep_to_epnum(endpoint) <= MAX_EP_NUMBER); + epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + if(ep->state != kEndpointState_Free) + goto exit; + + ep->endpoint_address = endpoint; + ep->attributes = type; + ep->max_packet_size = max_packet_size; + ep->bInterval = interval; + event_init(&ep->idle_state_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + ep->state = kEndpointState_Allocated_Idle; + +exit: + exit_critical_section(); +} + +static void usb_dockfifo_do_endpoint_io(struct usb_device_io_request *req) +{ + struct usb_endpoint_instance *ep; + uint32_t epindex; + + dprintf(DEBUG_SPEW, "endpoint %02x len %d\n", req->endpoint, + (int) req->io_length); + + enter_critical_section(); + + ASSERT(ep_to_epnum(req->endpoint) <= MAX_EP_NUMBER); + epindex = ep_to_epindex(req->endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + req->return_count = 0; + req->status = USB_IO_ERROR; + req->next = NULL; + + // make sure endpoint is idle + if(ep->state != kEndpointState_Allocated_Idle) { + dprintf(DEBUG_INFO, "endpoint %x is not idle, state:%x\n", req->endpoint, ep->state); + event_wait(&ep->idle_state_event); + dprintf(DEBUG_INFO, "endpoint %x got idle state\n", + req->endpoint); + } + + // save IO + RELEASE_ASSERT(ep->io_request == NULL); + ep->io_request = req; + + // mark endpoint busy + ep->state = kEndpointState_Allocated_Busy; + event_unsignal(&ep->idle_state_event); + + // start transmitting/receiving the data + if (ep_to_epdir(req->endpoint)) { + dprintf(DEBUG_SPEW, "EP%02x start write len %d\n", + ep_to_epnum(req->endpoint), (int) req->io_length); + event_signal(&usb_dockfifo_writer_task_event); + } else { + dprintf(DEBUG_SPEW, "EP%02x advertise available\n", + ep_to_epnum(req->endpoint)); + usb_dockfifo_send_available(ep_to_epnum(req->endpoint)); + } + + exit_critical_section(); +} + +static void usb_dockfifo_stall_endpoint(uint32_t endpoint, bool stall) +{ + struct usb_endpoint_instance *ep; + uint32_t epindex; + + // Nothing to do for EP0_OUT + if(endpoint == 0) + return; + + enter_critical_section(); + + ASSERT(ep_to_epnum(endpoint) <= MAX_EP_NUMBER); + epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + dprintf(DEBUG_SPEW, "stall endpoint %x, state:%x, stall:%d\n", endpoint, ep->state, stall); + + if (stall) { + // if already stalled, nothing to do + if ((ep->state & kEndpointState_Allocated_Stalled) != 0) + return; + + // wait for endpoint to be idle + if (ep->state != kEndpointState_Allocated_Idle) + event_wait(&ep->idle_state_event); + + ep->state |= kEndpointState_Allocated_Stalled; + } + else { + // if not stalled, nothing to do + if ((ep->state & kEndpointState_Allocated_Stalled) == 0) + return; + } + + // Notify Dock + uint8_t data[] = { + EP_LINK_CONTROL | EP_DIR_IN, + kCommand_StallEndpoint, + endpoint, + stall + }; + usb_dockfifo_send_bytes(data, sizeof(data)); + + if (!stall) { + ep->state = kEndpointState_Allocated_Idle; + event_signal(&ep->idle_state_event); + } + + exit_critical_section(); +} + +static void usb_dockfifo_reset_endpoint_data_toggle(uint32_t endpoint) +{ +} + +static bool usb_dockfifo_is_endpoint_stalled(uint32_t endpoint) +{ + struct usb_endpoint_instance *ep; + uint32_t epindex; + + enter_critical_section(); + + ASSERT(ep_to_epnum(endpoint) <= MAX_EP_NUMBER); + epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + dprintf(DEBUG_SPEW, "endpoint %x, state:%x\n", endpoint, ep->state); + + exit_critical_section(); + + return ((ep->state & kEndpointState_Allocated_Stalled) != 0); +} + +static void usb_dockfifo_do_test_mode(uint32_t selector) +{ +} + +static void usb_dockfifo_abort_endpoint(uint32_t endpoint) +{ + uint32_t epindex; + struct usb_endpoint_instance *ep; + + enter_critical_section(); + + ASSERT(ep_to_epnum(endpoint) <= MAX_EP_NUMBER); + epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + dprintf(DEBUG_SPEW, "abort endpoint %x, state:%x\n", endpoint, ep->state); + + if (ep->state != kEndpointState_Allocated_Busy) + goto exit; + + ep->state |= kEndpointState_Allocated_AbortRequested; + + // wait for endpoint to be idle + if (ep->state != kEndpointState_Allocated_Idle) + event_wait(&ep->idle_state_event); + + ep->io_request->status = USB_IO_ABORTED; + usb_core_complete_endpoint_io(ep->io_request); + ep->io_request = NULL; + + dprintf(DEBUG_SPEW, "abort endpoint %x finished, state:%x\n", endpoint, ep->state); + +exit: + exit_critical_section(); +} + +static void usb_dockfifo_deactivate_endpoint(uint32_t endpoint) +{ + uint32_t epindex; + struct usb_endpoint_instance *ep; + + enter_critical_section(); + + ASSERT(ep_to_epnum(endpoint) <= MAX_EP_NUMBER); + epindex = ep_to_epindex(endpoint); + ASSERT(epindex < MAX_EP_NEEDED); + ep = &usb_dockfifo_endpoints[epindex]; + ASSERT(ep != NULL); + + if(ep->state == kEndpointState_Free) + goto exit; + + usb_dockfifo_abort_endpoint(endpoint); + + bzero(&usb_dockfifo_endpoints[ep_to_epindex(endpoint)], sizeof(struct usb_endpoint_instance)); + +exit: + exit_critical_section(); +} + +static const struct usb_controller_functions usb_dockfifo_controller_functions = { + .init = usb_dockfifo_init, + .free = usb_dockfifo_free, + .start = usb_dockfifo_start, + .stop = usb_dockfifo_stop, + .set_address = usb_dockfifo_set_address, + .get_connection_speed = usb_dockfifo_get_connection_speed, + .activate_endpoint = usb_dockfifo_activate_endpoint, + .do_endpoint_io = usb_dockfifo_do_endpoint_io, + .stall_endpoint = usb_dockfifo_stall_endpoint, + .reset_endpoint_data_toggle = usb_dockfifo_reset_endpoint_data_toggle, + .is_endpoint_stalled = usb_dockfifo_is_endpoint_stalled, + .do_test_mode = usb_dockfifo_do_test_mode, + .abort_endpoint = usb_dockfifo_abort_endpoint, + .deactivate_endpoint = usb_dockfifo_deactivate_endpoint, +}; + +//======================= +// Global funtions +//======================= + +const struct usb_controller_functions *usb_dockfifo_controller_init() +{ + return &usb_dockfifo_controller_functions; +} diff --git a/drivers/usb/usb_serial.c b/drivers/usb/usb_serial.c new file mode 100644 index 0000000..cb84336 --- /dev/null +++ b/drivers/usb/usb_serial.c @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +//////////////////////////////////////////////////////////////////// +// USB Serial +// This file implements usb serial emulation protocol. We have 'usbterm' +// tool on the Mac to enable this. +//////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +//============================================================================================== +// Local conts, macors, structs, typedefs +//============================================================================================== +#define WRITE_CBUF_MAX_CAPACITY (4096) + +#define DEBUG 0 + +#if DEBUG +#define print(fmt, args...) printf("%s --- " fmt, __FUNCTION__, ##args) +#else +#define print(fmt, args...) (void)0 +#endif + +struct usb_serial_buffer { + u_int8_t bytes[HS_BULK_EP_MAX_PACKET_SIZE]; +}; + +//============================================================================================== +// Global and Local variables +//============================================================================================== + +static const struct usb_interface_descriptor usb_serial_interface_descriptors[APPLE_USB_SERIAL_TOTAL_INTFS] = +{ + { + USB_DT_INTERFACE_SIZE, + USB_DT_INTERFACE, + APPLE_USB_SERIAL_INTF, + 0, + 0, + APPLE_USB_SERIAL_CLASS, + APPLE_USB_SERIAL_SUBCLASS, + APPLE_USB_SERIAL_PROTOCOL, + 0 + }, + { + USB_DT_INTERFACE_SIZE, + USB_DT_INTERFACE, + APPLE_USB_SERIAL_INTF, + 1, + APPLE_USB_SERIAL_TOTAL_EPS, + APPLE_USB_SERIAL_CLASS, + APPLE_USB_SERIAL_SUBCLASS, + APPLE_USB_SERIAL_PROTOCOL, + 0 + } +}; + +static const struct usb_endpoint_descriptor usb_serial_endpoint_descriptors[APPLE_USB_SERIAL_TOTAL_EPS] = { + { + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT, + APPLE_USB_SERIAL_EP_BULK_IN, + USB_ENDPOINT_BULK, + HS_BULK_EP_MAX_PACKET_SIZE, + 0 + }, + { + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT, + APPLE_USB_SERIAL_EP_BULK_OUT, + USB_ENDPOINT_BULK, + HS_BULK_EP_MAX_PACKET_SIZE, + 0 + } +}; + +static const char *usb_serial_string_descriptors[APPLE_USB_SERIAL_TOTAL_INTFS] = +{ + NULL, + "Apple USB Serial Interface" +}; + +static struct usb_interface_instance usb_serial_interface_instance; + +static struct usb_serial_buffer *out_buffer; +static struct usb_serial_buffer *in_buffer; +static struct task_event in_buffer_event; + +static struct cbuf *usb_serial_output_cbuf; + +static bool usb_serial_inited; +static volatile bool usb_serial_activated; + +static int current_alt_setting; + +//============================================================================================== +// Functions Prototypes +//============================================================================================== + +static int usb_serial_flush_write_cbuf (bool start_transfer, u_int32_t length); +static void usb_serial_transfer_finished_cb (struct usb_device_io_request *io_request); +static void usb_serial_activate_endpoints (void); +static void usb_serial_deactivate_endpoints (void); +static int usb_serial_get_max_packet_size(void); +static int usb_serial_task_entry(void *arg); + +//============================================================================================== +// Local functions +//============================================================================================== + +static void usb_serial_activate_interface (void) +{ + usb_serial_activate_endpoints(); + usb_core_do_transfer(APPLE_USB_SERIAL_EP_BULK_OUT, (u_int8_t *)out_buffer, sizeof(*out_buffer), usb_serial_transfer_finished_cb); + usb_serial_activated = true; + task_start(task_create("usb_serial", usb_serial_task_entry, NULL, 0x400)); +} + + +static void usb_serial_deactivate_interface (void) +{ + usb_serial_activated = false; + usb_serial_deactivate_endpoints(); +} + +static void usb_serial_activate_endpoints (void) +{ + int i; + + for(i = 0; i < APPLE_USB_SERIAL_TOTAL_EPS; i++) { + usb_core_activate_endpoint(usb_serial_endpoint_descriptors[i].bEndpointAddress, + usb_serial_endpoint_descriptors[i].bmAttributes, + usb_serial_get_max_packet_size(), + usb_serial_endpoint_descriptors[i].bInterval); + } +} + +static void usb_serial_deactivate_endpoints (void) +{ + int i; + + for(i = 0; i < APPLE_USB_SERIAL_TOTAL_EPS; i++) { + usb_core_deactivate_endpoint(usb_serial_endpoint_descriptors[i].bEndpointAddress); + } +} + + +static void usb_serial_transfer_finished_cb (struct usb_device_io_request *io_request) +{ + print("callback %x\n", io_request->endpoint); + + if(io_request->endpoint == APPLE_USB_SERIAL_EP_BULK_OUT) { + if (io_request->status == USB_IO_SUCCESS) { + u_int32_t i = 0; + u_int32_t count; + + count = __min(io_request->return_count, sizeof(*out_buffer)); + + while(i < count) { + debug_pushchar(out_buffer->bytes[i++]); + } + } + else { + dprintf(DEBUG_INFO, "failed to read\n"); + } + + usb_core_do_transfer(APPLE_USB_SERIAL_EP_BULK_OUT, (u_int8_t *)out_buffer, sizeof(*out_buffer), usb_serial_transfer_finished_cb); + } + else if (io_request->endpoint == APPLE_USB_SERIAL_EP_BULK_IN) { + event_signal(&in_buffer_event); + + if (io_request->status != USB_IO_SUCCESS) { + dprintf(DEBUG_INFO, "failed to write\n"); + } + } +} + + +static int usb_serial_handle_set_interface (int value) +{ + switch(value) { + case 0 : + usb_serial_deactivate_interface(); + current_alt_setting = 0; + break; + + case 1 : + usb_serial_activate_interface(); + current_alt_setting = 1; + break; + + default : + return -1; + } + + return 0; +} + + +static int usb_serial_handle_get_interface (void) +{ + return (current_alt_setting); +} + +static int usb_serial_task_entry(void *arg __unused) +{ + while (usb_serial_activated) { + if(usb_serial_flush_write_cbuf(true, sizeof(*in_buffer)) == 0) + { + task_sleep(15 * 1000); + } + } + + return 0; +} + +static int usb_serial_flush_write_cbuf (bool start_transfer, u_int32_t length) +{ + u_int32_t i = 0; + char c = 0; + u_int32_t max_len = __min(length, sizeof(*in_buffer)); + + while(false == event_wait_timeout(&in_buffer_event, 5000 * 1000)) { + if(usb_serial_activated) { + usb_core_abort_endpoint(APPLE_USB_SERIAL_EP_BULK_IN); + } + } + + while(i < max_len) { + if(cbuf_read_char(usb_serial_output_cbuf, &c) == 0) { + break; + } + in_buffer->bytes[i++] = c; + } + + if(i && start_transfer) { + usb_core_do_transfer(APPLE_USB_SERIAL_EP_BULK_IN, (u_int8_t *)in_buffer, i, usb_serial_transfer_finished_cb); + } + else { + event_signal(&in_buffer_event); + } + + return i; // Number of characters written to USB Buffer +} + + +static int usb_serial_get_max_packet_size(void) +{ + int mps; + + if(usb_core_get_connection_speed() == CONNECTION_SPEED_HIGH) { + mps = HS_BULK_EP_MAX_PACKET_SIZE; + } + else { + mps = FS_EP_MAX_PACKET_SIZE; + } + + return mps; +} + +//============================================================================================== +// Global functions +//============================================================================================== + +int usb_serial_early_init (void) +{ + in_buffer = memalign(sizeof(*in_buffer), CPU_CACHELINE_SIZE); + bzero(in_buffer, sizeof(*in_buffer)); + + usb_serial_output_cbuf = cbuf_create(WRITE_CBUF_MAX_CAPACITY, NULL); + if(usb_serial_output_cbuf == NULL) { + usb_serial_inited = false; + dprintf(DEBUG_INFO, "usb_serial_output_cbuf create failed \n"); + return -1; + } + + event_init(&in_buffer_event, EVENT_FLAG_AUTO_UNSIGNAL, true); + usb_serial_inited = true; + + return 0; +} + +int usb_serial_init (void) +{ + if(!usb_serial_inited) { + dprintf(DEBUG_INFO, "usb_serial_early_init failed \n"); + return -1; + } + + usb_serial_activated = false; + current_alt_setting = 0; + + out_buffer = memalign(sizeof(*out_buffer), CPU_CACHELINE_SIZE); + if(out_buffer == NULL) { + dprintf(DEBUG_INFO, "usb_serial:usb_serial_init --- out_buffer memalign failed \n"); + return -1; + } + bzero(out_buffer, sizeof(*out_buffer)); + + usb_serial_interface_instance.total_interfaces = APPLE_USB_SERIAL_TOTAL_INTFS; + usb_serial_interface_instance.interface_descs = (struct usb_interface_descriptor *)&usb_serial_interface_descriptors; + usb_serial_interface_instance.total_endpoints = APPLE_USB_SERIAL_TOTAL_EPS; + usb_serial_interface_instance.endpoint_descs = (struct usb_endpoint_descriptor *)&usb_serial_endpoint_descriptors; + usb_serial_interface_instance.total_string_descs = APPLE_USB_SERIAL_TOTAL_INTFS; + usb_serial_interface_instance.string_descs = (char **)usb_serial_string_descriptors; + usb_serial_interface_instance.deactivate_interface = usb_serial_deactivate_interface; + usb_serial_interface_instance.handle_set_interface = usb_serial_handle_set_interface; + usb_serial_interface_instance.handle_get_interface = usb_serial_handle_get_interface; + + usb_core_register_interface(&usb_serial_interface_instance); + + return 0; +} + +void usb_serial_putchar(int c) +{ + int ret = 0; + + if((ret = cbuf_write_char(usb_serial_output_cbuf, c)) == 0) { + bool start_transfer = false; + u_int32_t len = 1; + + if(usb_serial_activated) { + len = usb_serial_get_max_packet_size(); + start_transfer = true; + } + + usb_serial_flush_write_cbuf(start_transfer, len); + + cbuf_write_char(usb_serial_output_cbuf, c); + } +} + +void usb_serial_exit (void) +{ + if(usb_serial_output_cbuf) { + cbuf_destroy(usb_serial_output_cbuf); + usb_serial_output_cbuf = NULL; + } + + if(in_buffer) { + free(in_buffer); + in_buffer = NULL; + } + + if(out_buffer) { + free(out_buffer); + out_buffer = NULL; + } + + usb_serial_inited = false; +} + +int usb_serial_send_cmd_string(u_int8_t *buffer, u_int32_t len) +{ + if(!usb_serial_activated) { + return -1; + } + + usb_core_do_transfer(APPLE_USB_SERIAL_EP_BULK_IN, buffer, len, NULL); + + return 0; +} + +bool usb_serial_is_active() +{ + return ((current_alt_setting == 1) ? true : false); +} diff --git a/drivers/usb/usb_transfer.c b/drivers/usb/usb_transfer.c new file mode 100644 index 0000000..ae4ae62 --- /dev/null +++ b/drivers/usb/usb_transfer.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +//////////////////////////////////////////////////////////////////// +// USB Bulk Upload + File transfer +// +// This file implements USB Bulk protocol for file uploads; +// and it also implements vendor specific file transfer +// protocol using a bulk pipe. +/////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 + +#if DEBUG +#define print(fmt, args...) printf("%s - " fmt, __FUNCTION__, ##args) +#else +#define print(fmt, args...) (void)0 +#endif + +#ifdef SUPPORT_FPGA +#define TIMEOUT_SCALER (10) +#else +#define TIMEOUT_SCALER (1) +#endif + +#define BULK_HS_TRNSFR_TIMEOUT (15 * 1000 * 1000 * TIMEOUT_SCALER) +#define BULK_FS_TRNSFR_TIMEOUT (30 * 1000 * 1000 * TIMEOUT_SCALER) + +#define ERR_PACKET_LEN (4) +#define ERR_PKT_START (0xfb) +#define ERR_PKT_END (0xfa) + +// File transfer error codes +#define ERR_FILE_SUCCESS 0 +#define ERR_FILE_UNKNOWN_ERROR 1 +#define ERR_FILE_UNEXPECTED_ERROR 2 +#define ERR_FILE_NOT_FOUND 3 +#define ERR_FILE_READ_ERROR 4 +#define ERR_FILE_WRITE_ERROR 5 + +// Personalization related file transfer error codes +#define ERR_PFILE_NOT_IM4P 11 +#define ERR_PFILE_CREATE_FAILED 12 +#define ERR_PFILE_READ_ERROR 13 + +static const struct usb_interface_descriptor usb_trnsfr_interface_descriptor = { + USB_DT_INTERFACE_SIZE, + USB_DT_INTERFACE, + APPLE_USB_TRNSFR_INTF, + 0, + APPLE_USB_TRNSFR_TOTAL_EPS, + APPLE_USB_TRNSFR_CLASS, + APPLE_USB_TRNSFR_SUBCLASS, + APPLE_USB_TRNSFR_PROTOCOL, + 0 +}; + +static const struct usb_endpoint_descriptor usb_trnsfr_endpoint_descriptors [] = { + { + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT, + APPLE_USB_TRNSFR_EP_BULK_OUT, + USB_ENDPOINT_BULK, + HS_BULK_EP_MAX_PACKET_SIZE, + 0 + } +#if WITH_BULK_UPLOAD + , + { + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT, + APPLE_USB_TRNSFR_EP_BULK_IN, + USB_ENDPOINT_BULK, + HS_BULK_EP_MAX_PACKET_SIZE, + 0 + } +#endif +}; + +static struct usb_interface_instance usb_trnsfr_interface_instance; +static struct task_event trnsfr_event; +static volatile bool trnsfr_done; +static int completion_status; +static u_int8_t *image_buffer; +static u_int32_t image_buffer_size; +static struct callout trnsfr_callout; +static u_int32_t max_transfer_len; + +#if WITH_BULK_UPLOAD +static u_int8_t __aligned(CPU_CACHELINE_SIZE) bulk_in_zlp_buffer[sizeof(u_int32_t)]; +static u_int8_t __aligned(CPU_CACHELINE_SIZE) bulk_upload_status_buffer[ERR_PACKET_LEN]; +static void bulk_in_callback(struct usb_device_io_request *io_request); +static void bulk_upload_status_callback(struct usb_device_io_request *io_request); +#endif // WITH_BULK_UPLOAD + +static void activate_interface(void); +static void deactivate_interface(void); +static void bulk_transfer_callback(struct usb_device_io_request *io_request); +static void handle_trnsfr_callout(struct callout *co, void *args); +static int handle_vendor_request(struct usb_device_request *request); +static void transfer_failed(); + +int usb_transfer_init() +{ + completion_status = -1; + image_buffer = NULL; + image_buffer_size = 0; + trnsfr_done = false; + + event_init(&trnsfr_event, EVENT_FLAG_AUTO_UNSIGNAL, false); + + usb_trnsfr_interface_instance.total_interfaces = APPLE_USB_TRNSFR_TOTAL_INTFS; + usb_trnsfr_interface_instance.interface_descs = (struct usb_interface_descriptor *)&usb_trnsfr_interface_descriptor; + usb_trnsfr_interface_instance.total_endpoints = APPLE_USB_TRNSFR_TOTAL_EPS; + usb_trnsfr_interface_instance.endpoint_descs = (struct usb_endpoint_descriptor *)&usb_trnsfr_endpoint_descriptors; + usb_trnsfr_interface_instance.deactivate_interface = deactivate_interface; + usb_trnsfr_interface_instance.activate_interface = activate_interface; +#if WITH_RECOVERY_MODE + usb_trnsfr_interface_instance.handle_vendor_request = handle_vendor_request; +#endif // WITH_RECOVERY_MODE + + usb_core_register_interface(&usb_trnsfr_interface_instance); + + return 0; +} + +void usb_transfer_exit() +{ +} + +void usb_transfer_prepare(int type, void *address, u_int32_t length) +{ + u_int32_t timeout; + + print("\n"); + + timeout = 0; + + completion_status = -1; + image_buffer = address; + image_buffer_size = length; + trnsfr_done = false; + +#if WITH_ENV + env_set_uint("filesize", 0, 0); +#endif // WITH_ENV + + if(type == USB_TRANSFER_TYPE_BULK_GET) { + + max_transfer_len = DEFAULT_RAMDISK_SIZE; + + if(!security_allow_memory((u_int8_t *)image_buffer, max_transfer_len)) { + dprintf(DEBUG_INFO, "Permission denied\n"); + return; + } + + if(usb_core_get_connection_speed() == CONNECTION_SPEED_HIGH) + timeout = BULK_HS_TRNSFR_TIMEOUT; + else + timeout = BULK_FS_TRNSFR_TIMEOUT; + + usb_core_abort_endpoint(APPLE_USB_TRNSFR_EP_BULK_OUT); + + usb_core_do_transfer(APPLE_USB_TRNSFR_EP_BULK_OUT, image_buffer, max_transfer_len, + bulk_transfer_callback); + } +#if WITH_BULK_UPLOAD + else if(type == USB_TRANSFER_TYPE_BULK_PUT) { + + if(!security_allow_memory((u_int8_t *)image_buffer, image_buffer_size)) { + dprintf(DEBUG_INFO, "Permission denied\n"); + return; + } + + timeout = (usb_core_get_connection_speed() == CONNECTION_SPEED_HIGH) ? BULK_HS_TRNSFR_TIMEOUT : BULK_FS_TRNSFR_TIMEOUT; + usb_core_abort_endpoint(APPLE_USB_TRNSFR_EP_BULK_OUT); + usb_core_abort_endpoint(APPLE_USB_TRNSFR_EP_BULK_IN); + + // Queue BULK IN request to upload data to host + usb_core_do_transfer(APPLE_USB_TRNSFR_EP_BULK_IN, image_buffer, image_buffer_size, bulk_in_callback); + + // Keep an active BULK OUT request so that host can communcate failure at any time or communicate success at the end. + // There is no timeout for this request + usb_core_do_transfer(APPLE_USB_TRNSFR_EP_BULK_OUT, bulk_upload_status_buffer, ERR_PACKET_LEN, bulk_upload_status_callback); + } +#endif // WITH_BULK_UPLOAD + + callout_enqueue(&trnsfr_callout, timeout, handle_trnsfr_callout, NULL); +} + +u_int32_t usb_transfer_start() +{ + print("starting\n"); + + while(!trnsfr_done) event_wait(&trnsfr_event); +#if DEBUG_BUILD + dprintf(DEBUG_SPEW, "transfer complete, status=%d\n", completion_status); +#else + dprintf(DEBUG_INFO, "transfer complete, status=%d\n", completion_status); +#endif + + return completion_status; +} + +static void deactivate_interface(void) +{ + usb_core_deactivate_endpoint(APPLE_USB_TRNSFR_EP_BULK_OUT); +#if WITH_BULK_UPLOAD + usb_core_deactivate_endpoint(APPLE_USB_TRNSFR_EP_BULK_IN); +#endif +} + +static void activate_interface(void) +{ + int mps; + + mps = (usb_core_get_connection_speed() == CONNECTION_SPEED_HIGH) ? HS_BULK_EP_MAX_PACKET_SIZE : FS_EP_MAX_PACKET_SIZE; + usb_core_activate_endpoint(APPLE_USB_TRNSFR_EP_BULK_OUT, USB_ENDPOINT_BULK, mps, 0); + +#if WITH_BULK_UPLOAD + usb_core_activate_endpoint(APPLE_USB_TRNSFR_EP_BULK_IN, USB_ENDPOINT_BULK, mps, 0); +#endif +} + +static void handle_trnsfr_callout(struct callout *co, void *args) +{ + print("\n"); + + transfer_failed(); +} + +#if WITH_RECOVERY_MODE +static int handle_vendor_request(struct usb_device_request *request) +{ + int ret; + + ret = -1; + + print("req: %d\n", request->wValue); + + if(request->wValue == PR_RESET_REQUEST) { + PROFILE_1('UHVR'); + usb_transfer_prepare(USB_TRANSFER_TYPE_BULK_GET, (void *)DEFAULT_LOAD_ADDRESS, DEFAULT_RAMDISK_SIZE); + ret = 0; + } + + return ret; +} +#endif // WITH_RECOVERY_MODE + +static void transfer_failed() +{ + print("\n"); + + callout_dequeue(&trnsfr_callout); + completion_status = -1; +#if WITH_ENV + env_set_uint("filesize", 0, 0); +#endif // WITH_ENV + trnsfr_done = true; + event_signal(&trnsfr_event); +} + +static void bulk_transfer_callback(struct usb_device_io_request *io_request) +{ + print("status: %d, count: %d\n", io_request->status, io_request->return_count); + + if(io_request->status != USB_IO_SUCCESS) { + transfer_failed(); + return; + } + + // special case, Error packet handling. + // this length and pattern should not appear in + // normal case, if someone will hit this often + // will make a change. + if(io_request->return_count == ERR_PACKET_LEN) { + u_int8_t *buf = (u_int8_t *)image_buffer; + + if((buf[0] == ERR_PKT_START) && (buf[3] == ERR_PKT_END)) { + switch(buf[2]) + { + case ERR_FILE_UNEXPECTED_ERROR: + dprintf(DEBUG_CRITICAL, "Unexpected error, exiting\n"); + break; + case ERR_FILE_NOT_FOUND: + dprintf(DEBUG_CRITICAL, "File not found or could not be accessed, exiting\n"); + break; + case ERR_FILE_READ_ERROR: + dprintf(DEBUG_CRITICAL, "File read error, exiting\n"); + break; + case ERR_PFILE_NOT_IM4P: + dprintf(DEBUG_CRITICAL, "Not an im4p file, exiting\n"); + break; + case ERR_PFILE_CREATE_FAILED: + dprintf(DEBUG_CRITICAL, "Could not personalize file, exiting\n"); + break; + case ERR_PFILE_READ_ERROR: + dprintf(DEBUG_CRITICAL, "Error reading personalized file, exiting\n"); + break; + case ERR_FILE_UNKNOWN_ERROR: + default: + dprintf(DEBUG_CRITICAL, "Unknown error - %d, exiting\n", buf[2]); + break; + } + + transfer_failed(); + + return; + } + } + +#if WITH_ENV + env_set_uint("filesize", io_request->return_count, 0); +#endif // WITH_ENV + completion_status = io_request->return_count; + callout_dequeue(&trnsfr_callout); + trnsfr_done = true; + event_signal(&trnsfr_event); +} + +#ifdef WITH_BULK_UPLOAD +static void bulk_in_callback(struct usb_device_io_request *io_request) +{ + int mps; + int amount; + + amount = io_request->return_count; + print("status: %d, count: %d\n", io_request->status, amount); + + if(io_request->status == USB_IO_SUCCESS) { + completion_status = amount; + + mps = (usb_core_get_connection_speed() == CONNECTION_SPEED_HIGH) ? HS_BULK_EP_MAX_PACKET_SIZE : FS_EP_MAX_PACKET_SIZE; + if((amount > 0) && ((amount & (mps - 1)) == 0)) + { + // Send an empty packet to indicate end of transfer + usb_core_do_transfer(APPLE_USB_TRNSFR_EP_BULK_IN, bulk_in_zlp_buffer, 0, NULL); + } + + // Restart the timer waiting for the status packet + callout_reset(&trnsfr_callout, 0); + } + else { + completion_status = -1; + } +} +#endif // WITH_BULK_UPLOAD + +#ifdef WITH_BULK_UPLOAD +static void bulk_upload_status_callback(struct usb_device_io_request *io_request) +{ + bool upload_success = false; + + print("status: %d, count: %d\n", io_request->status, io_request->return_count); + if(io_request->status == USB_IO_SUCCESS) { + if(io_request->return_count == ERR_PACKET_LEN) { + if((bulk_upload_status_buffer[0] == ERR_PKT_START) && (bulk_upload_status_buffer[3] == ERR_PKT_END)) { + switch(bulk_upload_status_buffer[2]) { + case ERR_FILE_SUCCESS: + upload_success = true; + break; + case ERR_FILE_UNEXPECTED_ERROR: + printf("Unexpected error, exiting\n"); + break; + case ERR_FILE_NOT_FOUND: + printf("File could not be opened, exiting\n"); + break; + case ERR_FILE_WRITE_ERROR: + printf("File write error, exiting\n"); + break; + case ERR_FILE_UNKNOWN_ERROR: + default: + printf("Unknown error - %d, exiting\n", bulk_upload_status_buffer[2]); + break; + } + } + else { + dprintf(DEBUG_INFO, "Invalid format for status packet\n"); + } + } + else { + dprintf(DEBUG_INFO, "Invalid status packet length - %d\n", io_request->return_count); + } + } + else { + dprintf(DEBUG_INFO, "Status packet failed %x\n", io_request->status); + } + + if(!upload_success) { + usb_core_abort_endpoint(APPLE_USB_TRNSFR_EP_BULK_IN); + } + + trnsfr_done = true; + callout_dequeue(&trnsfr_callout); + event_signal(&trnsfr_event); +} +#endif // WITH_BULK_UPLOAD diff --git a/include/AssertMacros.h b/include/AssertMacros.h new file mode 100644 index 0000000..2deea12 --- /dev/null +++ b/include/AssertMacros.h @@ -0,0 +1,1165 @@ +/* + File: AssertMacros.h + + Contains: This file defines structured error handling and assertion macros for + programming in C. Originally used in QuickDraw GX and later enhanced. + These macros are used throughout Apple's software. + + See "Living In an Exceptional World" by Sean Parent + (develop, The Apple Technical Journal, Issue 11, August/September 1992) + + for the methodology behind these error handling and assertion macros. + + Copyright: © 2002-2007 by Apple Inc., all rights reserved. + + Bugs?: For bug reports, consult the following page on + the World Wide Web: + + http://developer.apple.com/bugreporter/ +*/ +#ifndef __ASSERTMACROS__ +#define __ASSERTMACROS__ + + +/* + * Macro overview: + * + * check(assertion) + * In production builds, pre-processed away + * In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE + * + * verify(assertion) + * In production builds, evaluates assertion and does nothing + * In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE + * + * require(assertion, exceptionLabel) + * In production builds, if the assertion expression evaluates to false, goto exceptionLabel + * In debug builds, if the assertion expression evaluates to false, calls DEBUG_ASSERT_MESSAGE + * and jumps to exceptionLabel + * + * In addition the following suffixes are available: + * + * _noerr Adds "!= 0" to assertion. Useful for asserting and OSStatus or OSErr is noErr (zero) + * _action Adds statement to be executued if assertion fails + * _quiet Suppress call to DEBUG_ASSERT_MESSAGE + * _string Allows you to add explanitory message to DEBUG_ASSERT_MESSAGE + * + * For instance, require_noerr_string(resultCode, label, msg) will do nothing if + * resultCode is zero, otherwise it will call DEBUG_ASSERT_MESSAGE with msg + * and jump to label. + * + * Configuration: + * + * By default all macros generate "production code" (i.e non-debug). If + * DEBUG_ASSERT_PRODUCTION_CODE is defined to zero or DEBUG is defined to non-zero + * while this header is included, the macros will generated debug code. + * + * If DEBUG_ASSERT_COMPONENT_NAME_STRING is defined, all debug messages will + * be prefixed with it. + * + * By default, all messages write to stderr. If you would like to write a custom + * error message formater, defined DEBUG_ASSERT_MESSAGE to your function name. + * + */ + + +/* + * Before including this file, #define DEBUG_ASSERT_COMPONENT_NAME_STRING to + * a C-string containing the name of your client. This string will be passed to + * the DEBUG_ASSERT_MESSAGE macro for inclusion in any assertion messages. + * + * If you do not define DEBUG_ASSERT_COMPONENT_NAME_STRING, the default + * DEBUG_ASSERT_COMPONENT_NAME_STRING value, an empty string, will be used by + * the assertion macros. + */ +#ifndef DEBUG_ASSERT_COMPONENT_NAME_STRING + #define DEBUG_ASSERT_COMPONENT_NAME_STRING "" +#endif + + +/* + * To activate the additional assertion code and messages for non-production builds, + * #define DEBUG_ASSERT_PRODUCTION_CODE to zero before including this file. + * + * If you do not define DEBUG_ASSERT_PRODUCTION_CODE, the default value 1 will be used + * (production code = no assertion code and no messages). + */ +#ifndef DEBUG_ASSERT_PRODUCTION_CODE + #define DEBUG_ASSERT_PRODUCTION_CODE !DEBUG +#endif + + +/* + * DEBUG_ASSERT_MESSAGE(component, assertion, label, error, file, line, errorCode) + * + * Summary: + * All assertion messages are routed through this macro. If you wish to use your + * own routine to display assertion messages, you can override DEBUG_ASSERT_MESSAGE + * by #defining DEBUG_ASSERT_MESSAGE before including this file. + * + * Parameters: + * + * componentNameString: + * A pointer to a string constant containing the name of the + * component this code is part of. This must be a string constant + * (and not a string variable or NULL) because the preprocessor + * concatenates it with other string constants. + * + * assertionString: + * A pointer to a string constant containing the assertion. + * This must be a string constant (and not a string variable or + * NULL) because the Preprocessor concatenates it with other + * string constants. + * + * exceptionLabelString: + * A pointer to a string containing the exceptionLabel, or NULL. + * + * errorString: + * A pointer to the error string, or NULL. DEBUG_ASSERT_MESSAGE macros + * must not attempt to concatenate this string with constant + * character strings. + * + * fileName: + * A pointer to the fileName or pathname (generated by the + * preprocessor __FILE__ identifier), or NULL. + * + * lineNumber: + * The line number in the file (generated by the preprocessor + * __LINE__ identifier), or 0 (zero). + * + * errorCode: + * A value associated with the assertion, or 0. + * + * Here is an example of a DEBUG_ASSERT_MESSAGE macro and a routine which displays + * assertion messsages: + * + * #define DEBUG_ASSERT_COMPONENT_NAME_STRING "MyCoolProgram" + * + * #define DEBUG_ASSERT_MESSAGE(componentNameString, assertionString, \ + * exceptionLabelString, errorString, fileName, lineNumber, errorCode) \ + * MyProgramDebugAssert(componentNameString, assertionString, \ + * exceptionLabelString, errorString, fileName, lineNumber, errorCode) + * + * static void + * MyProgramDebugAssert(const char *componentNameString, const char *assertionString, + * const char *exceptionLabelString, const char *errorString, + * const char *fileName, long lineNumber, int errorCode) + * { + * if ( (assertionString != NULL) && (*assertionString != '\0') ) + * fprintf(stderr, "Assertion failed: %s: %s\n", componentNameString, assertionString); + * else + * fprintf(stderr, "Check failed: %s:\n", componentNameString); + * if ( exceptionLabelString != NULL ) + * fprintf(stderr, " %s\n", exceptionLabelString); + * if ( errorString != NULL ) + * fprintf(stderr, " %s\n", errorString); + * if ( fileName != NULL ) + * fprintf(stderr, " file: %s\n", fileName); + * if ( lineNumber != 0 ) + * fprintf(stderr, " line: %ld\n", lineNumber); + * if ( errorCode != 0 ) + * fprintf(stderr, " error: %d\n", errorCode); + * } + * + * If you do not define DEBUG_ASSERT_MESSAGE, a simple printf to stderr will be used. + */ +#ifndef DEBUG_ASSERT_MESSAGE + #ifdef KERNEL + #include + #define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \ + printf( "AssertMacros: %s, %s file: %s, line: %d\n", assertion, (message!=0) ? message : "", file, line); + #else + #include + #define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \ + fprintf(stderr, "AssertMacros: %s, %s file: %s, line: %d\n", assertion, (message!=0) ? message : "", file, line); + #endif +#endif + + + + + +/* + * debug_string(message) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * message: + * The C string to display. + * + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define debug_string(message) +#else + #define debug_string(message) \ + do \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + "", \ + 0, \ + message, \ + __FILE__, \ + __LINE__, \ + 0); \ + } while ( 0 ) +#endif + + +/* + * check(assertion) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define check(assertion) +#else + #define check(assertion) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + 0, \ + 0, \ + __FILE__, \ + __LINE__, \ + 0); \ + } \ + } while ( 0 ) +#endif + +#define ncheck(assertion) \ + check(!(assertion)) + + +/* + * check_string(assertion, message) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define check_string(assertion, message) +#else + #define check_string(assertion, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + 0, \ + message, \ + __FILE__, \ + __LINE__, \ + 0); \ + } \ + } while ( 0 ) +#endif + +#define ncheck_string(assertion, message) \ + check_string(!(assertion), message) + + +/* + * check_noerr(errorCode) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The errorCode expression to compare with 0. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define check_noerr(errorCode) +#else + #define check_noerr(errorCode) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + 0, \ + 0, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + } \ + } while ( 0 ) +#endif + + +/* + * check_noerr_string(errorCode, message) + * + * Summary: + * Production builds: check_noerr_string() does nothing and produces + * no code. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The errorCode expression to compare to 0. + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define check_noerr_string(errorCode, message) +#else + #define check_noerr_string(errorCode, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + 0, \ + message, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + } \ + } while ( 0 ) +#endif + + +/* + * verify(assertion) + * + * Summary: + * Production builds: evaluate the assertion expression, but ignore + * the result. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define verify(assertion) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + } \ + } while ( 0 ) +#else + #define verify(assertion) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + 0, \ + 0, \ + __FILE__, \ + __LINE__, \ + 0); \ + } \ + } while ( 0 ) +#endif + +#define nverify(assertion) \ + verify(!(assertion)) + + +/* + * verify_string(assertion, message) + * + * Summary: + * Production builds: evaluate the assertion expression, but ignore + * the result. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define verify_string(assertion, message) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + } \ + } while ( 0 ) +#else + #define verify_string(assertion, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + 0, \ + message, \ + __FILE__, \ + __LINE__, \ + 0); \ + } \ + } while ( 0 ) +#endif + +#define nverify_string(assertion, message) \ + verify_string(!(assertion), message) + + +/* + * verify_noerr(errorCode) + * + * Summary: + * Production builds: evaluate the errorCode expression, but ignore + * the result. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define verify_noerr(errorCode) \ + do \ + { \ + if ( 0 != (errorCode) ) \ + { \ + } \ + } while ( 0 ) +#else + #define verify_noerr(errorCode) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + 0, \ + 0, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + } \ + } while ( 0 ) +#endif + + +/* + * verify_noerr_string(errorCode, message) + * + * Summary: + * Production builds: evaluate the errorCode expression, but ignore + * the result. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define verify_noerr_string(errorCode, message) \ + do \ + { \ + if ( 0 != (errorCode) ) \ + { \ + } \ + } while ( 0 ) +#else + #define verify_noerr_string(errorCode, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + 0, \ + message, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + } \ + } while ( 0 ) +#endif + + +/* + * verify_action(assertion, action) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * then execute the action statement or compound statement (block). + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE and then execute the action statement or compound + * statement (block). + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * action: + * The statement or compound statement (block). + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define verify_action(assertion, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + action; \ + } \ + } while ( 0 ) +#else + #define verify_action(assertion, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + 0, \ + 0, \ + __FILE__, \ + __LINE__, \ + 0); \ + { action; } \ + } \ + } while ( 0 ) +#endif + + +/* + * require(assertion, exceptionLabel) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + #exceptionLabel, \ + 0, \ + __FILE__, \ + __LINE__, \ + 0); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +#define nrequire(assertion, exceptionLabel) \ + require(!(assertion), exceptionLabel) + + +/* + * require_action(assertion, exceptionLabel, action) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * execute the action statement or compound statement (block) and then + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound + * statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require_action(assertion, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require_action(assertion, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + #exceptionLabel, \ + 0, \ + __FILE__, \ + __LINE__, \ + 0); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +#define nrequire_action(assertion, exceptionLabel, action) \ + require_action(!(assertion), exceptionLabel, action) + + +/* + * require_quiet(assertion, exceptionLabel) + * + * Summary: + * If the assertion expression evaluates to false, goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + */ +#define require_quiet(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +#define nrequire_quiet(assertion, exceptionLabel) \ + require_quiet(!(assertion), exceptionLabel) + + +/* + * require_action_quiet(assertion, exceptionLabel, action) + * + * Summary: + * If the assertion expression evaluates to false, execute the action + * statement or compound statement (block), and goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#define require_action_quiet(assertion, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +#define nrequire_action_quiet(assertion, exceptionLabel, action) \ + require_action_quiet(!(assertion), exceptionLabel, action) + + +/* + * require_string(assertion, exceptionLabel, message) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require_string(assertion, exceptionLabel, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require_string(assertion, exceptionLabel, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + #exceptionLabel, \ + message, \ + __FILE__, \ + __LINE__, \ + 0); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +#define nrequire_string(assertion, exceptionLabel, string) \ + require_string(!(assertion), exceptionLabel, string) + + +/* + * require_action_string(assertion, exceptionLabel, action, message) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * execute the action statement or compound statement (block), and then + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound + * statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require_action_string(assertion, exceptionLabel, action, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require_action_string(assertion, exceptionLabel, action, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, \ + #exceptionLabel, \ + message, \ + __FILE__, \ + __LINE__, \ + 0); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +#define nrequire_action_string(assertion, exceptionLabel, action, message) \ + require_action_string(!(assertion), exceptionLabel, action, message) + + +/* + * require_noerr(errorCode, exceptionLabel) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require_noerr(errorCode, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require_noerr(errorCode, exceptionLabel) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + #exceptionLabel, \ + 0, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +/* + * require_noerr_action(errorCode, exceptionLabel, action) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * execute the action statement or compound statement (block) and + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE, execute the action statement or + * compound statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require_noerr_action(errorCode, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require_noerr_action(errorCode, exceptionLabel, action) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + #exceptionLabel, \ + 0, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + + +/* + * require_noerr_quiet(errorCode, exceptionLabel) + * + * Summary: + * If the errorCode expression does not equal 0 (noErr), + * goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + */ +#define require_noerr_quiet(errorCode, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + + +/* + * require_noerr_action_quiet(errorCode, exceptionLabel, action) + * + * Summary: + * If the errorCode expression does not equal 0 (noErr), + * execute the action statement or compound statement (block) and + * goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#define require_noerr_action_quiet(errorCode, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + + +/* + * require_noerr_string(errorCode, exceptionLabel, message) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require_noerr_string(errorCode, exceptionLabel, message) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require_noerr_string(errorCode, exceptionLabel, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + #exceptionLabel, \ + message, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + + +/* + * require_noerr_action_string(errorCode, exceptionLabel, action, message) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * execute the action statement or compound statement (block) and + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound + * statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + * + * message: + * The C string to display. + */ +#if DEBUG_ASSERT_PRODUCTION_CODE + #define require_noerr_action_string(errorCode, exceptionLabel, action, message)\ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#else + #define require_noerr_action_string(errorCode, exceptionLabel, action, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", \ + #exceptionLabel, \ + message, \ + __FILE__, \ + __LINE__, \ + evalOnceErrorCode); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + + +#endif /* __ASSERTMACROS__ */ + diff --git a/include/Availability.h b/include/Availability.h new file mode 100644 index 0000000..69e7779 --- /dev/null +++ b/include/Availability.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __AVAILABILITY__ +#define __AVAILABILITY__ + +#define __OSX_AVAILABLE_STARTING(_mac, _iphone) +#define __OSX_AVAILABLE_BUT_DEPRECATED(_macIntro, _macDep, _iphoneIntro, _iphoneDep) +#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_macIntro, _macDep, _iphoneIntro, _iphoneDep, _msg) + +#endif // __AVAILABILITY__ diff --git a/include/arch.h b/include/arch.h new file mode 100644 index 0000000..1729001 --- /dev/null +++ b/include/arch.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __ARCH_H +#define __ARCH_H + +#include +#include + +__BEGIN_DECLS + +struct arch_task; +struct task; + +int arch_cpu_init(bool resume); +int arch_cpu_init_posttasks(void); +int arch_cpu_quiesce(void); + +void arch_halt(void); +void arch_spin(void) __attribute__((noreturn)); + +u_int32_t arch_get_noncached_address(u_int32_t address); + +u_int32_t arch_enable_ints(void); +u_int32_t arch_disable_ints(void); +u_int32_t arch_restore_ints(u_int32_t state); + +/* + * arch_task_create + * + * Initialises the architecture-specific fields in the given task + * such that it can be switched to and run. + */ +int arch_task_create(struct task *); // used internally by task_create() + +/* + * arch_task_context_switch + * + * Switches execution from the current task to a new task. This can be used to + * save the current state by switching from and to the same task. + */ +void arch_task_context_switch(struct arch_task *old, struct arch_task *new_task); + +/* + * arch_task_context_restore + * + * Switches execution to a previously saved state. + */ +void arch_task_context_restore(struct arch_task *restore_context); + +/* + * Prints a backtrace for the current execution context. + */ +void arch_backtrace_current_task(void *stack_base, size_t stack_len); + +/* + * Prints a backtrace for the given task. + */ +void arch_backtrace_task(struct arch_task *arch_task, void *stack_base, size_t stack_len); + +#if WITH_VFP +/* + * arch_task_fp_enable + * + * Enable floating point support for the current task. + */ +bool arch_task_fp_enable(bool enable); +#endif + +/* + * Collects entropy by reading a counter across + * an asynchronous boundary. The returned word + * will ideally contain at least one bit of entropy. + */ +u_int32_t arch_get_entropy(volatile u_int32_t *counter_address); + +extern const char *build_banner_string; +extern const char *build_style_string; +extern const char *build_tag_string; + +extern void _text_start __segment_start_sym(__TEXT); +extern void _text_end __segment_end_sym(__TEXT); +extern void _data_start __segment_start_sym(__DATA); +extern void _data_end __segment_end_sym(__DATA); + +__END_DECLS + +#endif diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 0000000..f12f7cd --- /dev/null +++ b/include/assert.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __ASSERT_H +#define __ASSERT_H + +#include + +#define assert(x) RELEASE_ASSERT(x) + +#endif + diff --git a/include/c++/iostream.h b/include/c++/iostream.h new file mode 100644 index 0000000..6e816a2 --- /dev/null +++ b/include/c++/iostream.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __IOSTREAM_H +#define __IOSTREAM_H + +#include +#include + +struct ostream +{ + ostream & operator << (const char *str) + { + printf("%s", str); + return(*this); + } + + ostream & operator << (char *str) + { + printf("%s", str); + return(*this); + } + + ostream & operator << (int x) + { + printf("%d", x); + return(*this); + } + + ostream & operator << (unsigned int x) + { + printf("%u", x); + return(*this); + } + + ostream & operator << (long long int x) + { + printf("%lld", x); + return(*this); + } + + ostream & operator << (unsigned long long int x) + { + printf("%llu", x); + return(*this); + } + + ostream & operator << (char ch) + { + printf("%c", ch); + return(*this); + } +}; + +struct istream +{ + istream & operator << (char &ch) + { + ch = getchar(); + return(*this); + } + +}; + +extern const char *endl; +extern ostream cout; +extern ostream cerr; +extern istream cin; + +#endif /* __IOSTREAM_H */ diff --git a/include/cbuffer.h b/include/cbuffer.h new file mode 100644 index 0000000..3a89d71 --- /dev/null +++ b/include/cbuffer.h @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef _CBUFER_H_ +#define _CBUFER_H_ + +#include +#include +#include + +__BEGIN_DECLS + +#define CB_ALIGNMENT 64 + +typedef struct _CBUFFER { + uint8_t * head; + uint8_t * tail; + size_t size; + size_t readableSize; + size_t bufferSize; + uint8_t * dataStart; + uint8_t * dataEnd; +} CBUFFER; + +#define cb_fix_high( ptr, pcb ) \ + if( pcb->ptr >= pcb->dataEnd ) { \ + pcb->ptr = pcb->dataStart; \ + } + +#define cb_cs_encap( theCall, retType ) \ + retType ret; \ + enter_critical_section(); \ + ret = theCall; \ + exit_critical_section(); \ + return ret + + + +static inline bool cb_initialized( CBUFFER * pcb ) +{ + return pcb->dataStart?true:false; +} + +static inline int cb_create( CBUFFER * pcb, size_t size ) +{ + // round up + size = (size + CB_ALIGNMENT-1) & ~(CB_ALIGNMENT-1); + pcb->dataStart = (uint8_t *)memalign( size, CB_ALIGNMENT ); + + pcb->head = pcb->tail = pcb->dataStart; + pcb->dataEnd = pcb->dataStart+size; + pcb->size = 0; + pcb->readableSize = 0; + pcb->bufferSize = size; + + return size; +} + +static inline void cb_reset( CBUFFER * pcb ) +{ + enter_critical_section(); + pcb->head = pcb->tail = pcb->dataStart; + pcb->size = 0; + pcb->readableSize = 0; + pcb->bufferSize = pcb->dataEnd - pcb->dataStart; + exit_critical_section(); +} + +static inline uint32_t cb_size( CBUFFER * pcb) +{ + return pcb->size; +} + +static inline uint32_t cb_readable_size( CBUFFER * pcb ) +{ + return pcb->readableSize; +} + +static inline uint8_t * cb_get_head( CBUFFER * pcb ) +{ + return pcb->head; +} + +static inline uint32_t cb_free_space( CBUFFER * pcb ) +{ + return pcb->bufferSize - cb_size(pcb); +} + +static inline uint32_t cb_block_free_space_unsafe( CBUFFER * pcb ) +{ + uint32_t freeTotal = cb_free_space(pcb); + uint32_t freeTillEnd = pcb->dataEnd-pcb->head; + + return __min( freeTotal, freeTillEnd ); +} + + +static inline uint32_t cb_block_free_space( CBUFFER * pcb ) +{ + cb_cs_encap( cb_block_free_space_unsafe( pcb ), uint32_t ); +} + +static inline uint8_t * cb_block_read_ptr_unsafe( CBUFFER * pcb, uint32_t * pamount ) +{ + uint8_t * ret = pcb->tail; + + /*printf( "data 0x%08X, head 0x%08X, tail 0x%08X, data end %08X, size %d\n", + (uint)pcb->dataStart, (uint)pcb->head, (uint)pcb->tail, (uint)pcb->dataEnd, (uint)cb_size( pcb ) ); */ + if( pcb->head <= pcb->tail ){ + // header is past tail, so there is a wrap around + *pamount = pcb->dataEnd-pcb->tail; + pcb->size -= *pamount; + pcb->readableSize -= *pamount; + pcb->tail = pcb->dataStart; + } else { + // we can consume all of it + pcb->tail = pcb->head; + *pamount = pcb->size; + pcb->size = 0; + pcb->readableSize = 0; + } + /*printf( "- data 0x%08X, head 0x%08X, tail 0x%08X, data end %08X, size %d\n", + (uint)pcb->dataStart, (uint)pcb->head, (uint)pcb->tail, (uint)pcb->dataEnd, (uint)cb_size( pcb ) ); */ + return ret; +} + +static inline uint8_t * cb_block_read_ptr( CBUFFER * pcb, uint32_t * pamount ) +{ + cb_cs_encap( cb_block_read_ptr_unsafe( pcb, pamount ), uint8_t * ); +} + +static inline void cb_pre_skip( CBUFFER * pcb, uint32_t amount ) +{ + uint32_t bfs; + enter_critical_section(); + + pcb->size += amount; + + bfs = pcb->dataEnd-pcb->head; + + if( bfs > amount ){ + //printf( "a bfs %d, amount %d\n", bfs, amount ); + pcb->head += amount; + } else { + //printf( "b bfs %d, amount %d\n", bfs, amount ); + pcb->head = pcb->dataStart + amount-bfs; + } + + exit_critical_section(); + +} + +static inline void cb_post_skip( CBUFFER * pcb, uint32_t amount ) +{ + + enter_critical_section(); + + + /*printf( "$ data 0x%08X, head 0x%08X, tail 0x%08X, data end %08X, size %d\n", + (uint)pcb->dataStart, (uint)pcb->head, (uint)pcb->tail, (uint)pcb->dataEnd, (uint)cb_size( pcb ) ); */ + + // update internal count to reflect the new data now available to read + pcb->readableSize += amount; + + + /*printf( "* data 0x%08X, head 0x%08X, tail 0x%08X, data end %08X, size %d\n", + (uint)pcb->dataStart, (uint)pcb->head, (uint)pcb->tail, (uint)pcb->dataEnd, (uint)cb_size( pcb ) ); */ + + exit_critical_section(); + +} + +static inline int cb_putc_unsafe( CBUFFER * pcb, uint8_t c ) +{ + if( cb_free_space( pcb ) ){ + *pcb->head++ = c; + + cb_fix_high( head, pcb ); + + pcb->size++; + pcb->readableSize++; + return c; + } else { + return -1; + } +} + + +static inline int cb_putc( CBUFFER * pcb, uint8_t c ) +{ + cb_cs_encap( cb_putc_unsafe( pcb, c ), int ); +} + +static inline int cb_peekc_unsafe( CBUFFER * pcb ) +{ + if( cb_size( pcb ) ){ + return *pcb->tail; + } else { + return -1; + } +} + + +static inline int cb_peekc( CBUFFER * pcb ) +{ + cb_cs_encap( cb_peekc_unsafe( pcb ), int ); +} + +static inline int cb_getc_unsafe( CBUFFER * pcb ) +{ + if( cb_size( pcb ) ){ + uint8_t ret = *pcb->tail++; + + cb_fix_high( tail, pcb ); + + pcb->size--; + pcb->readableSize--; + + return ret; + } else { + return -1; + } +} + +static inline int cb_getc( CBUFFER * pcb ) +{ + cb_cs_encap( cb_getc_unsafe( pcb ), int ); +} + +static inline uint32_t cb_read_unsafe( CBUFFER * pcb, uint8_t * buffer, size_t size ) +{ + uint32_t readable = cb_readable_size( pcb ); + if( readable ){ + size = __min( size, readable ); + size_t blockSize = pcb->dataEnd-pcb->tail; + + if( blockSize < size ){ + // we must copy some part of the data from tail-->dataEnd + // and then copy the rest from dataStart + memcpy( buffer, pcb->tail, blockSize ); + buffer += blockSize; + + blockSize = size - blockSize; + pcb->tail = pcb->dataStart + blockSize; + memcpy( buffer, pcb->dataStart, blockSize ); + + } else { + // we can copy the entire block from tail + memcpy( buffer, pcb->tail, size ); + + pcb->tail += size; + + } + + pcb->size -= size; + pcb->readableSize -= size; + + return size; + } else { + return 0; + } +} + +static inline uint32_t cb_read( CBUFFER * pcb, uint8_t * buffer, size_t size ) +{ + cb_cs_encap( cb_read_unsafe( pcb, buffer, size ), uint32_t ); +} + +static inline int cb_write_unsafe( CBUFFER * pcb, const uint8_t * buffer, size_t size ) +{ + if( cb_free_space( pcb ) ){ + size = __min( size, pcb->bufferSize-pcb->size ); + size_t blockSize = pcb->dataEnd-pcb->head; + if( blockSize < size ){ + // must write in blocks from head-->dataEnd + // and then from dataStart + memcpy( pcb->head, buffer, blockSize ); + buffer += blockSize; + + blockSize = size - blockSize; + pcb->head = pcb->dataStart + blockSize; + memcpy( pcb->dataStart, buffer, blockSize ); + + } else { + memcpy( pcb->head, buffer, size ); + pcb->head += size; + + } + + pcb->size += size; + pcb->readableSize += size; + + return size; + } else { + return 0; + } +} + + +static inline int cb_write( CBUFFER * pcb, const uint8_t * buffer, size_t size ) +{ + cb_cs_encap( cb_write_unsafe( pcb, buffer, size ), int ); +} + +static inline void cb_free( CBUFFER * pcb ) +{ + free( pcb->dataStart ); + pcb->dataEnd = pcb->dataStart = NULL; +} + +__END_DECLS + +#endif diff --git a/include/compiler.h b/include/compiler.h new file mode 100644 index 0000000..fb84694 --- /dev/null +++ b/include/compiler.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2006,2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __COMPILER_H +#define __COMPILER_H + +#ifndef __ASSEMBLY__ + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#ifndef offsetof +# define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) +#endif +#define clz(_x) __builtin_clz(_x) +#define ctz(_x) __builtin_ctz(_x) + +#define __max(_x, _y) ({ typeof (_x) _a = (_x); typeof (_y) _b = (_y); _a > _b ? _a : _b; }) +#define __min(_x, _y) ({ typeof (_x) _a = (_x); typeof (_y) _b = (_y); _a < _b ? _a : _b; }) + +#ifndef __unused +# define __unused __attribute__((unused)) +#endif +#ifndef __pure +# define __pure __attribute__((pure)) +#endif +#ifndef __printflike +# define __printflike(__fmt,__varargs) __attribute__((__format__ (__printf__, __fmt, __varargs))) +#endif +#ifndef __scanflike +# define __scanflike(__fmt,__varargs) __attribute__((__format__ (__scanf__, __fmt, __varargs))) +#endif + +#ifndef __used +# define __used __attribute__((used)) +#endif +#define __packed __attribute__((packed)) +#define __aligned(x) __attribute__((aligned(x))) +#define __noreturn __attribute__((noreturn)) +#ifndef __always_inline +# define __always_inline __attribute__((always_inline)) +#endif +#define __deprecated __attribute__((deprecated)) +#ifndef __nonnull +#define __nonnull(_x) __attribute__((nonnull _x)) +#endif +#define __malloc __attribute__((malloc)) +#define __warn_unused_result __attribute__((warn_unused_result)) +#define __return_address(_x) __builtin_return_address(_x) +#ifndef __has_feature +# define has_feature(x) 0 +#endif + +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/* + * Statement expressions for determining the start/end of segments and sections. + * + * These are uglier than they should be courtesy of + * No way to generate new segment/section boundary symbols from C code + */ +/* these have to be used at function scope due to their use of statement expressions */ +#ifndef __linux__ + #define __segment_start(_seg) \ + ({extern void *__seg_start_##_seg __asm("segment$start$" #_seg); &__seg_start_##_seg;}) + + #define __segment_end(_seg) \ + ({extern void *__seg_end_##_seg __asm("segment$end$" #_seg); &__seg_end_##_seg;}) + + #define __section_start(_seg, _sec) \ + ({extern void *__sec_start_##_seg##_sec __asm("section$start$" #_seg "$" #_sec); &__sec_start_##_seg##_sec;}) + + #define __section_end(_seg, _sec) \ + ({extern void *__sec_end_##_seg##_sec __asm("section$end$" #_seg "$" #_sec); &__sec_end_##_seg##_sec;}) +#else + #define __section_start(_seg, _sec) ({extern void *__start_##_sec; &__start_##_sec;}) + #define __section_end(_seg, _sec) ({extern void *__stop_##_sec; &__stop_##_sec;}) +#endif + + +/* these work at global scope, when tagged onto the definition of a variable */ +#define __segment_start_sym(_seg) __asm("segment$start$" #_seg) +#define __segment_end_sym(_seg) __asm("segment$end$" #_seg) +#define __section_start_sym(_seg, _sec) __asm("section$start$" #_seg "$" #_sec) +#define __section_end_sym(_seg, _sec) __asm("section$end$" #_seg "$" #_sec) + +#endif /* __ASSEMBLY__ */ +#endif /* __COMPILER_H */ diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 0000000..4340606 --- /dev/null +++ b/include/debug.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DEBUG_H +#define __DEBUG_H + +#include +#include +#include + +#ifndef DEBUG_UART_ENABLE_DEFAULT +# define DEBUG_UART_ENABLE_DEFAULT 0 +#endif + +#define DEBUG_SILENT 0 +#define DEBUG_RELEASE 5 +#define DEBUG_CRITICAL 10 +#define DEBUG_INFO 20 +#define DEBUG_SPEW 30 +#define DEBUG_NEVER 40 + +#ifndef DEBUG_LEVEL +# if DEBUG_BUILD +# define DEBUG_LEVEL DEBUG_INFO +# else +# define DEBUG_LEVEL DEBUG_CRITICAL +# endif +#endif + +#ifndef OBFUSCATED_LOGGING +# if RELEASE_BUILD +# define OBFUSCATED_LOGGING 1 +# else +# define OBFUSCATED_LOGGING 0 +# endif +#endif + +#define dprintf(level, x...) \ + do { \ + if ((level) <= DEBUG_LEVEL) { \ + if (OBFUSCATED_LOGGING && (level) > DEBUG_RELEASE) { printf("%llx:%d\n", DEBUG_FILE_HASH, __LINE__); } \ + else { printf(x); } \ + } \ + } while(0) +#define dhexdump(level, ptr, len) \ + do { \ + if ((level) <= DEBUG_LEVEL) { \ + if (OBFUSCATED_LOGGING && (level) > DEBUG_RELEASE) { printf("%llx:%d\n", DEBUG_FILE_HASH, __LINE__); } \ + else { hexdump(ptr, len); } \ + } \ + } while(0) + +#define __ASSERT(_x, _str) \ +do { \ + if (unlikely(!(_x))) { \ + panic("ASSERT FAILED at (%s:%d)\n", __FILE__, __LINE__);\ + } \ +} while(0) + +#if DEBUG_BUILD || ENABLE_RELEASE_ASSERTS || defined(__clang_analyzer__) +/* for debug builds, turn all the asserts */ +# define RELEASE_ASSERT(_x) __ASSERT(_x, #_x) +# define ASSERT(_x) __ASSERT(_x, #_x) +#else +/* for release, development builds */ +# define RELEASE_ASSERT(_x) __ASSERT(_x, #_x) +# define ASSERT(_x) do {if (_x) {}} while(0) +#endif + +#define static_assert(assertion, error) _Static_assert(assertion, error) + +#if WITH_SIMULATION_TRACE +/* + * To enable postmortem analysis of non-debug code being run in simulation, we allow a platform to + * define two locations to which we will write trace data; one for location, one for parameters. + * This also permits watchpoint debugging using a hardware debugger. + * + * In both cases, the write to the IP trace register stores the address of the current function. + * Following this are either one or two writes to the parameter trace register; the first gives the + * source file line containing the trace statement, the second (if present) the parameter. + */ +#if !defined(SIMULATION_TRACE_IP_REGISTER) || !defined(SIMULATION_TRACE_PARAMETER_REGISTER) +# error Must define SIMULATION_TRACE_IP_REGISTER and SIMULATION_TRACE_PARAMETER_REGISTER if WITH_SIMULATION_TRACE is defined +#endif + +/* + * Trace our passing a location. + */ +#define SIMULATION_TRACE() \ + do { \ + *(uint32_t *)SIMULATION_TRACE_IP_REGISTER = (uint32_t)__func__; \ + *(uint32_t *)SIMULATION_TRACE_PARAMETER_REGISTER = (uint32_t)__LINE__; \ + } while (0) + +/* + * Trace a location and a parameter at that location. + */ +#define SIMULATION_TRACE_VALUE(_x) \ + do { \ + SIMULATION_TRACE(); \ + *(uint32_t *)SIMULATION_TRACE_PARAMETER_REGISTER = (uint32_t)(_x); \ + } while (0) + +#define SIMULATION_TRACE_VALUE2(_x,_y) \ + do { \ + SIMULATION_TRACE(); \ + *(uint32_t *)SIMULATION_TRACE_PARAMETER_REGISTER = (uint32_t)(_x); \ + *(uint32_t *)SIMULATION_TRACE_PARAMETER_REGISTER = (uint32_t)(_y); \ + } while (0) + +#endif /* WITH_SIMULATION_TRACE */ + +#endif /* __DEBUG_H */ diff --git a/include/drivers/aes.h b/include/drivers/aes.h new file mode 100644 index 0000000..f746527 --- /dev/null +++ b/include/drivers/aes.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_AES_H +#define __DRIVERS_AES_H + +#include + +__BEGIN_DECLS + +#define AES_CMD_ENC (0x00000000) +#define AES_CMD_DEC (0x00000001) +#define AES_CMD_DIR_MASK (0x0000000F) +#define AES_CMD_ECB (0x00000000) +#define AES_CMD_CBC (0x00000010) +#define AES_CMD_MODE_MASK (0x000000F0) + +#define AES_KEY_TYPE_USER (0x00000000) +#define AES_KEY_TYPE_UID0 (0x00000100) +#define AES_KEY_TYPE_GID0 (0x00000200) +#define AES_KEY_TYPE_GID1 (0x00000201) +#define AES_KEY_TYPE_MASK (0x00000FFF) + +#define AES_KEY_SIZE_128 (0x00000000) +#define AES_KEY_SIZE_192 (0x10000000) +#define AES_KEY_SIZE_256 (0x20000000) +#define AES_KEY_SIZE_MASK (0xF0000000) + +#define AES_BLOCK_SIZE (16) + +/* + * aes_crypto_cmd - provides access to AES functions + * + * cmd - operation mode: ENC or DEC and EBC or CBC + * src - source buffer and destination buffer for in place operations + * dst - desination buffer, or NULL for in place operations + * len - size in bytes of the operation + * opts - key type and size + * key - key buffer or NULL for non USER key types + * iv - iv buffer or NULL if iv should be all zeros + * + * AES operations may return an error if the requested operation depends + * on hardware resources that are not available. + * + * Bad arguments passed to AES operations will result in a panic. + */ +int aes_crypto_cmd(u_int32_t cmd, void *src, void *dst, size_t len, u_int32_t opts, const void *key, void *iv); + +#define aes_cbc_encrypt(src, dst, len, opts, key, iv) \ + aes_crypto_cmd(AES_CMD_ENC | AES_CMD_CBC, src, dst, len, opts, key, iv) +#define aes_cbc_decrypt(src, dst, len, opts, key, iv) \ + aes_crypto_cmd(AES_CMD_DEC | AES_CMD_CBC, src, dst, len, opts, key, iv) + +/* exported interface from hardware AES driver */ +int aes_hw_crypto_cmd(u_int32_t cmd, void *src, void *dst, size_t len, u_int32_t opts, const void *key, void *iv); + +/* old AES hardware driver protocol, not for new platforms */ +enum aes_key_type { + AES_KEY_TYPE_REGISTER = 0, + AES_KEY_TYPE_GLOBAL, + AES_KEY_TYPE_CHIP +}; + +int AES_CBC_DecryptInPlace(u_int8_t* pAddr, u_int32_t u32Len, u_int32_t keyType, u_int8_t* pKey, u_int8_t* pIv); +bool AES_CBC_EncryptInPlace(u_int8_t* pAddr, u_int32_t u32Len, u_int32_t keyType, u_int8_t* pKey, u_int8_t* pIv); + +__END_DECLS + +#endif /* __DRIVERS_AES_H */ diff --git a/include/drivers/anc_boot.h b/include/drivers/anc_boot.h new file mode 100644 index 0000000..e7c1497 --- /dev/null +++ b/include/drivers/anc_boot.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef ANC_BOOT_H +#define ANC_BOOT_H + +#define ANC_BOOT_MODE_RESET_ALL_CONTROLLERS 0 +#define ANC_BOOT_MODE_RESET_ONE_CONTROLLER 1 +#define ANC_MIN_ALIGNMENT 16 + +extern bool anc_reset(int resetMode); +extern bool anc_firmware_init(void); +extern size_t anc_read_llb(void* data, size_t size); + +#endif + diff --git a/include/drivers/apcie.h b/include/drivers/apcie.h new file mode 100644 index 0000000..7c4c371 --- /dev/null +++ b/include/drivers/apcie.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef APCIE_INIT_H +#define APCIE_INIT_H + +#include +#include +#include + +// 10 second timeout when enabling a link +#define APCIE_ENABLE_TIMEOUT 10000000 + +struct apcie_link_config { + uint32_t perst_gpio; + uint32_t clkreq_gpio; + unsigned int dart_id; + utime_t t_perst_delay; + utime_t t_boot_to_perst; + utime_t t_refclk_to_perst; +}; + +struct apcie_link_status { + bool enabled; +}; + +void apcie_init(void); +void apcie_use_external_refclk(bool use); +void apcie_set_s3e_mode(bool reset_on_enable); + +void apcie_config_read_raw(void *dst, uint32_t bdfo, int size); +void apcie_config_write_raw(const void *src, uint32_t bdfo, int size); + +bool apcie_enable_link(uint32_t link); +void apcie_disable_link(uint32_t link); +void apcie_disable_all(void); +uint32_t apcie_get_link_enable_count(void); +void apcie_setup_root_port_bridge(uint32_t link, struct apcie_link_config *config); +void apcie_update_devicetree(DTNode *apcie_node); +pci_device_t apcie_get_port_bridge(uint32_t link); +void apcie_free_port_bridge(uint32_t link); + +extern struct apcie_link_config platform_apcie_link_configs[]; +extern struct apcie_link_status apcie_link_statuses[]; +extern struct apcie_link_config *apcie_link_configs; + +#endif + diff --git a/include/drivers/asp.h b/include/drivers/asp.h new file mode 100644 index 0000000..e1e02bf --- /dev/null +++ b/include/drivers/asp.h @@ -0,0 +1,9 @@ +#ifndef _ASP_INIT_H +#define _ASP_INIT_H + +int asp_init(void); +int asp_nand_open(void); +int asp_set_default_dies_in_parallel(void); +int asp_disable_uid(void); + +#endif // _ASP_INIT_H diff --git a/include/drivers/buttons.h b/include/drivers/buttons.h new file mode 100644 index 0000000..39a82f4 --- /dev/null +++ b/include/drivers/buttons.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_BUTTONS_H +#define __DRIVERS_BUTTONS_H + +#include + +__BEGIN_DECLS + +enum buttons { + MENU_KEY, + VOLUP_KEY, + VOLDOWN_KEY, +}; + +typedef void (*button_callback)(bool state); + +int buttons_init(void); + +/* Callback is executed in interrupt context */ +void button_callback_register(enum buttons button, button_callback callback); +void button_callback_unregister(enum buttons button, button_callback callback); + +__END_DECLS + +#endif /* __DRIVERS_BUTTONS_H */ diff --git a/include/drivers/charger.h b/include/drivers/charger.h new file mode 100644 index 0000000..ddba0fc --- /dev/null +++ b/include/drivers/charger.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_CHARGER_H +#define __DRIVERS_CHARGER_H + +#include + +__BEGIN_DECLS + +void charger_early_init(void); +void charger_clear_alternate_usb_current_limit(void); +bool charger_has_usb(int dock); +bool charger_has_firewire(int dock); +bool charger_has_external(int dock); +bool charger_check_usb_change(int dock, bool expected); +void charger_set_charging(int dock, uint32_t input_current_ma, uint32_t *charge_current_ma); +void charger_clear_usb_state(void); +bool charger_set_usb_brick_detect(int dock, int select); +bool charger_charge_done(int dock); +bool charger_has_batterypack(int dock); +uint32_t charger_get_max_charge_current(int dock); +int charger_read_battery_temperature(int *centiCelsiusTemperature); +int charger_read_battery_level(uint32_t *milliVolts); +int charger_set_gasgauge_interface(bool enabled); +void charger_print_status(void); + +__END_DECLS + +#endif /* __DRIVERS_CHARGER_H */ + diff --git a/include/drivers/consistent_debug.h b/include/drivers/consistent_debug.h new file mode 100644 index 0000000..afb9da7 --- /dev/null +++ b/include/drivers/consistent_debug.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_CONSISTENT_DEBUG__H +#define __DRIVERS_CONSISTENT_DEBUG__H + + +#include +#include + +// Functions + +// Restores consistent debug state on resume from sleep. +int consistent_debug_resume(void); + +// Set up consistent debug region on cold boot. +int consistent_debug_init(void); + + +/** + * Returns the location of the Consistent Debug Registry + * + * @author jdong (1/25/2013) + * + * @return A pointer to the debug registry if it exists. NULL if + * not yet initialized. + */ +dbg_registry_t* consistent_debug_get_registry(void); + +/** + * Attempt to register a header with the supplied information. + * + * @author jdong (12/10/2012) + * + * @param hdr: A filled-out header. The debug registry will be + * filled in with this information. + * + * @return dbg_record_header_t*: NULL if unsuccessful. + * Otherwise, a pointer to the entry in the debug + * registry. It's already filled out, so in the general + * case one would just check if it's non-NULL. + */ +dbg_record_header_t* consistent_debug_register_header(dbg_record_header_t hdr); + + +/** + * Attempt to deregister a consistent debug header. This might + * have to be done when handing off from a bootloader to an OS, + * or when powering down / resetting a coprocessor. It ensures + * that consumers of a debug region are given a chance to clean + * up before it is no longer valid. + * + * Note the return value. One should initially check that a call + * returns "0" indicating an entry is valid and has been marked + * as being freed. Then, one should poll by calling again with + * the same argument until the return value is 1. + * + * @author jdong (12/14/2012) + * + * @param hdr A pointer to a debug header returned by + * consistent_debug_register_header() + * + * @return -1: Error has occurred. Most likely the value passed + * is not an in-use debug registry header. + * 0: Record is marked as being freed -- waiting for + * the other end to acknowledge it. Check again later. + * 1: Record has been freed and is now unused. + */ +int consistent_debug_unregister_header(dbg_record_header_t *hdr); + + + + +/** + * Update the AP's Progress Report with the given state and + * state argument. + * + */ +void consistent_debug_update_ap_cpr(cp_state_t state, int arg); + +#endif diff --git a/include/drivers/csi.h b/include/drivers/csi.h new file mode 100644 index 0000000..542195d --- /dev/null +++ b/include/drivers/csi.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __CSI_H +#define __CSI_H + +#include +#include + +// +// Public API +// + +typedef enum { + CSI_COPROC_ANS = 0, + CSI_COPROC_SEP, + CSI_COPROC_ISP, + CSI_COPROC_SIO, + CSI_COPROC_MAX +} csi_coproc_t; + +#define IOP_NAME(coproc) \ + (((coproc)==CSI_COPROC_ANS) ? "ANS" : \ + (((coproc)==CSI_COPROC_SEP) ? "SEP" : \ + (((coproc)==CSI_COPROC_ISP) ? "ISP" : \ + (((coproc)==CSI_COPROC_SIO) ? "SIO" : "???")))) + +#define KFW(coproc) \ + (((coproc)==CSI_COPROC_ANS) ? KFW_ANS : \ + (((coproc)==CSI_COPROC_SEP) ? KFW_SEP : \ + (((coproc)==CSI_COPROC_ISP) ? 0 : \ + (((coproc)==CSI_COPROC_SIO) ? KFW_SIO : 0)))) + +typedef enum { + CSI_STATUS_OK = 0, + CSI_STATUS_UNSUPPORTED, + CSI_STATUS_UNAVAILABLE, + CSI_STATUS_ERROR, + CSI_STATUS_NO_FIRMWARE, + CSI_STATUS_BAD_FIRMWARE, + CSI_STATUS_TIMEOUT, + CSI_STATUS_PANIC_RECOVER, + CSI_STATUS_OUT_OF_RESSOURCES, +} csi_status_t; + +#define CSI_STATUS_STR(status) \ + (((status)==CSI_STATUS_OK) ? "OK" : \ + (((status)==CSI_STATUS_UNSUPPORTED) ? "UNSUPPORTED" : \ + (((status)==CSI_STATUS_UNAVAILABLE) ? "UNAVAILABLE" : \ + (((status)==CSI_STATUS_ERROR) ? "ERROR" : \ + (((status)==CSI_STATUS_NO_FIRMWARE) ? "NO_FIRMWARE" : \ + (((status)==CSI_STATUS_BAD_FIRMWARE) ? "BAD_FIRMWARE" : \ + (((status)==CSI_STATUS_TIMEOUT) ? "TIMEOUT" : "???"))))))) + + +typedef uint64_t msg_payload_t; + + +csi_status_t csi_init (csi_coproc_t which_coproc); +csi_status_t csi_late_init (void); + +csi_status_t csi_quiesce (enum boot_target target); + +csi_status_t csi_register_endpoint (csi_coproc_t which_coproc, uint32_t ep, struct task_event *event, void **csi_token, const char **name); + +void* csi_allocate_shared_memory (void *csi_token, uint32_t capacity); +void csi_free_shared_memory (void *sm); + +csi_status_t csi_receive_message (void *csi_token, msg_payload_t *msg_payload); +csi_status_t csi_send_message (void *csi_token, msg_payload_t msg_payload); + +// +// coprocessor feature and status +// + +#define COPROC_FEATURE_NONE (0x0000UL) +#define COPROC_FEATURE_SHUTDOWN_IN_PROGRESS (0x0001UL) +#define COPROC_FEATURE_PANIC_RECOVERY (0x0002UL) +#define COPROC_FEATURE_ALL (0xFFFFFFFFUL) + +typedef uint32_t coproc_feature_t; + +coproc_feature_t csi_get_feature (csi_coproc_t which_coproc); + +static inline bool csi_is_panic_recovery (csi_coproc_t which_coproc) +{ + return (csi_get_feature(which_coproc) & COPROC_FEATURE_PANIC_RECOVERY); +} + +static inline bool csi_is_shutdown_in_progress (csi_coproc_t which_coproc) +{ + return (csi_get_feature(which_coproc) & COPROC_FEATURE_SHUTDOWN_IN_PROGRESS); +} + +#endif /* !defined(__CSI_H) */ diff --git a/include/drivers/dart.h b/include/drivers/dart.h new file mode 100644 index 0000000..22dcf15 --- /dev/null +++ b/include/drivers/dart.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _DART_H +#define _DART_H + +#include + +#define DART_PAGE_SIZE (4096) + +typedef uint32_t dart_iovm_addr_t; + +void dart_init(unsigned int dart_id); +void dart_enable_translation(unsigned int dart_id); +void dart_disable_translation(unsigned int dart_id); +void dart_map_page_range(unsigned int dart_id, uintptr_t paddr, dart_iovm_addr_t vaddr, uint32_t pages, bool write_protect); +void dart_unmap_page_range(unsigned int dart_id, dart_iovm_addr_t vaddr, uint32_t pages); +void dart_write_protect_page_range(unsigned int dart_id, dart_iovm_addr_t vaddr, uint32_t pages, bool write_protect); +void dart_assert_unmapped(unsigned int dart_id); + +#endif diff --git a/include/drivers/display.h b/include/drivers/display.h new file mode 100644 index 0000000..aa4fea3 --- /dev/null +++ b/include/drivers/display.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_DISPLAY_H +#define __DRIVERS_DISPLAY_H + +#include +#include + +__BEGIN_DECLS + +struct display_window { + bool active; + enum colorspace cs; + uint32_t depth; + uint32_t pos_x, pos_y; + uint32_t width, height; + uint32_t stride; + struct canvas c; + void *ptr; // device specific data +}; + +#define kGammaChannelBufferSize (72) +#define kGammaBufferSize (kGammaChannelBufferSize * 3) + +struct display_gamma_table { + uint32_t display_id; + uint32_t display_id_mask; + uint8_t display_gamma_data[kGammaBufferSize]; +}; +typedef struct display_gamma_table display_gamma_table; + +struct syscfg_glcl { + uint8_t minor_vers; + uint8_t major_vers; + uint8_t reserved[2]; + uint8_t gamma_data[kGammaBufferSize]; +}; + +int display_init(void); +int display_quiesce(bool clear_display); +void display_clear(void); + +bool display_get_enable(void); +void display_set_enable(bool enable, uint32_t *color); +bool display_set_rotation(bool rotate180); +void display_delay_frames(uint32_t frames); +void display_set_background_color(uint32_t color); + +struct display_window *display_create_window(uint32_t x, uint32_t y, uint32_t width, uint32_t height, enum colorspace color); +void display_destroy_window(struct display_window *win); +void display_move_window(struct display_window *win, uint32_t x, uint32_t y); +void display_activate_window(struct display_window *win); +void display_deactivate_window(struct display_window *win); +void display_set_window_fb(struct display_window *win, void *fb); + +struct display_info { + addr_t framebuffer; + uint32_t width; + uint32_t height; + uint32_t stride; + uint32_t depth; +}; + +/* after the fact get the information about the current display */ +int display_get_info(struct display_info *info); + +struct display_timing +{ + const char *display_name; + + uint32_t host_clock_id; + uint32_t pixel_clock; + + uint32_t dot_pitch; + + uint32_t h_active; + uint32_t h_back_porch; + uint32_t h_front_porch; + uint32_t h_pulse_width; + uint32_t v_active; + uint32_t v_back_porch; + uint32_t v_front_porch; + uint32_t v_pulse_width; + + bool neg_vclk; + bool neg_hsync; + bool neg_vsync; + bool neg_vden; + + uint32_t display_depth; + uint32_t display_type; + void *display_config; +}; + +#define DISPLAY_TYPE_DUMB (0) +#define DISPLAY_TYPE_SMART (1) +#define DISPLAY_TYPE_MERLOT (2) +#define DISPLAY_TYPE_PINOT (3) +#define DISPLAY_TYPE_TMDS (4) +#define DISPLAY_TYPE_DP (5) +#define DISPLAY_TYPE_EDP (6) +#define DISPLAY_TYPE_HDMI (7) +#define DISPLAY_TYPE_SUMMIT (8) + +__END_DECLS + +#endif /* __DRIVERS_DISPLAY_H */ diff --git a/include/drivers/displayAV.h b/include/drivers/displayAV.h new file mode 100644 index 0000000..61ad7d9 --- /dev/null +++ b/include/drivers/displayAV.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef DRIVERS_DISPLAYAV_H +#define DRIVERS_DISPLAYAV_H 1 + + +enum { + kDisplayAxisTypeHorizontal, + kDisplayAxisTypeVertical, + kDisplayAxisCount +}; + +enum { + kDisplayColorSpacesRGB, + kDisplayColorSpacesYCbCr422, + kDisplayColorSpacesYCbCr444 +}; + +enum { + kDisplayColorDynamicRangeFull, + kDisplayColorDynamicRangeLimited, + kDisplayColorDynamicRangeVESA = kDisplayColorDynamicRangeFull, + kDisplayColorDynamicRangeCEA = kDisplayColorDynamicRangeLimited +}; + +enum { + kDisplayColorCoefficientITU601, + kDisplayColorCoefficientITU709 +}; + +enum { + kDisplayTestModeOff, + kDisplayTestModeColorRamp, + kDisplayTestModeBlackWhiteVLines, + kDisplayTestModeColorSquare, + kDisplayTestModeInvalid, + kDisplayTestModeColorBar32, + kDisplayTestModeColorBar64, + kDisplayTestModeWhiteGrayBlackBar32, + kDisplayTestModeWhiteGrayBlackBar64, + kDisplayTestModeMobileWhiteBar32, + kDisplayTestModeMobileWhiteBar64 +}; + +enum { + kDisplayColorRGBQuantizationRangeDefault, + kDisplayColorRGBQuantizationRangeLimited, + kDisplayColorRGBQuantizationRangeFull +}; + +struct video_color_data { + u_int32_t depth; + u_int32_t space; + u_int32_t range; + u_int32_t coefficient; +}; + +struct video_timing_axis { + uint32_t total; + uint32_t active; + uint32_t sync_width; + uint32_t back_porch; + uint32_t front_porch; + int32_t sync_rate; + uint32_t sync_polarity; +}; + +struct video_timing_data { + bool interlaced; + struct video_timing_axis axis[kDisplayAxisCount]; +}; + +struct video_link_data { + bool mirror_mode; + u_int32_t test_mode; + struct video_color_data color; + struct video_timing_data timing; +}; + + +typedef enum { + kDisplayInfoFrameTypeReserved = 0x80, + kDisplayInfoFrameTypeVendorSpecific = 0x81, + kDisplayInfoFrameTypeAVI = 0x82, + kDisplayInfoFrameTypeProductDescription = 0x83, + kDisplayInfoFrameTypeAudio = 0x84, + kDisplayInfoFrameTypeMPEG = 0x85, + kDisplayInfoFrameTypeMin = kDisplayInfoFrameTypeReserved, + kDisplayInfoFrameTypeMax = kDisplayInfoFrameTypeMPEG, + kDisplayInfoFrameTypeCount = 1 + (kDisplayInfoFrameTypeMax - kDisplayInfoFrameTypeMin) +} display_infoframe_type; + +struct display_infoframe { + display_infoframe_type type; + uint8_t version; + uint8_t length; + uint8_t checksum; + uint8_t data[28]; +}; + +#endif diff --git a/include/drivers/display_pmu.h b/include/drivers/display_pmu.h new file mode 100644 index 0000000..f4c3900 --- /dev/null +++ b/include/drivers/display_pmu.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef DRIVERS_DISPLAY_PMU_H +#define DRIVERS_DISPLAY_PMU_H 1 + +#if WITH_HW_CHESTNUT +#define DISPLAY_PMU_LDO(n) (((n) + 1) << 2) +#endif + +int display_pmu_init(void); +int display_pmu_quiesce(void); +void display_pmu_update_device_tree(const char *node); + +#endif /* DRIVERS_DISPLAY_PMU_H */ + diff --git a/include/drivers/displayport.h b/include/drivers/displayport.h new file mode 100644 index 0000000..670653f --- /dev/null +++ b/include/drivers/displayport.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef DRIVERS_DISPLAYPORT_H +#define DRIVERS_DISPLAYPORT_H 1 + +#include +#include + +#define kDPMaxLanes 4 + + +enum { + kLinkRate000Gbps = 0x0, + kLinkRate162Gbps = 0x6, + kLinkRate270Gbps = 0xa, + kLinkRate324Gbps = 0x0c, + kLinkRate540Gbps = 0x14 +}; + +enum { + kDPVoltageLevel0, + kDPVoltageLevel1, + kDPVoltageLevel2, + kDPVoltageLevel3, + kDPVoltageLevelMin = kDPVoltageLevel0, + kDPVoltageLevelMax = kDPVoltageLevel3 +}; + +enum { + kDPEQLevel0, + kDPEQLevel1, + kDPEQLevel2, + kDPEQLevel3, + kDPEQLevelMin = kDPEQLevel0, + kDPEQLevelMax = kDPEQLevel3 +}; + +enum { + kDPTrainingPatternNone, + kDPTrainingPattern1, + kDPTrainingPattern2, + kDPTrainingPattern3 +}; + +enum { + kDPLaneStatusFlagClockRecoveryDone = (1<<0), + kDPLaneStatusFlagsEQDone = (1<<1), + kDPLaneStatusFlagsSymbolLocked = (1<<2), + kDPLaneStatusFlagsMask = (0x7) +}; + +enum { + kDPAlignmentStatusFlagsDone = (1<<0), + kDPAlignmentStatusFlagsDownstreamChanged = (1<<6), + kDPAlignmentStatusFlagsLinkUpdated = (1<<7), +}; + +enum { + kDPDownstreamTypeDP, + kDPDownstreamTypeVGA, + kDPDownstreamTypeDVI, + kDPDownstreamTypeHDMI, + kDPDownstreamTypeOther, + kDPDownstreamTypeCount +}; + +struct dp_link_training_lane_data { + u_int32_t voltage; + u_int32_t eq; +}; + +struct dp_link_train_data { + bool enhanced_mode; + bool assr; + bool downspread; + bool fast; + u_int32_t lane_count; + u_int32_t link_rate; + struct dp_link_training_lane_data lane[kDPMaxLanes]; +}; + + +// controller config flags + +enum { + kDPControllerMode_Master = 0, + kDPControllerMode_Slave +}; +#define kDPControllerMode_Mask 0xf +#define kDPControllerMode_Shift 4 + +enum { + kDPControllerType_DP = 0, + kDPControllerType_EDP +}; +#define kDPControllerType_Mask 0xf +#define kDPControllerType_Shift 0 + +#include + +// global +int displayport_init(dp_t *dp); +int displayport_init_with_timing_info(struct display_timing *timing_info); +int displayport_set_timings(struct display_timing *timing_info); +int displayport_start_video(void); +int displayport_enable_alpm(bool enable); +bool displayport_video_configured(); +void displayport_quiesce(); + +// eDP support +#if WITH_HW_DISPLAY_EDP +#define kEDPRawPanelIdLength 16 + +int displayport_get_raw_panel_id(u_int8_t *raw_panel_id); +#endif // WITH_HW_DISPLAY_EDP + +// controller +int dp_controller_start(dp_t *); +void dp_controller_stop(); +int dp_controller_validate_video(struct video_timing_data *data); +int dp_controller_read_bytes_dpcd(u_int32_t addr, u_int8_t *data, u_int32_t length); +int dp_controller_read_bytes_i2c(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length); +int dp_controller_write_bytes_dpcd(u_int32_t addr, u_int8_t *data, u_int32_t length); +int dp_controller_write_bytes_i2c(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length); +int dp_controller_train_link(struct dp_link_train_data *data); +int dp_controller_get_adjustment_levels(u_int32_t lane, u_int32_t *voltage_swing, u_int32_t *eq); +int dp_controller_set_adjustment_levels(u_int32_t lane, u_int32_t voltage_swing, u_int32_t eq, + bool *voltage_max_reached, bool *eq_max_reached); +int dp_controller_set_training_pattern(u_int32_t value, bool scramble); +int dp_controller_get_training_pattern(u_int32_t *value, bool *scramble); +int dp_controller_set_link_rate(u_int32_t link_rate); +int dp_controller_get_link_rate(u_int32_t *link_rate); +int dp_controller_set_lane_count(uint32_t lane_count); +int dp_controller_get_lane_count(uint32_t * lane_count); +int dp_controller_set_enhanced_mode(bool mode); +int dp_controller_get_enhanced_mode(bool * mode); +int dp_controller_set_ASSR(bool mode); +int dp_controller_get_ASSR(bool * mode); +int dp_controller_set_downspread(bool state); +int dp_controller_get_downspread(bool *state); +int dp_controller_start_video(struct video_link_data *data); +int dp_controller_stop_video(); +u_int32_t dp_controller_get_max_lane_count(); +u_int32_t dp_controller_get_max_link_rate(); +u_int32_t dp_controller_get_min_lane_count(); +u_int32_t dp_controller_get_min_link_rate(); +bool dp_controller_get_supports_downspread(); +bool dp_controller_get_supports_fast_link_training(); +bool dp_controller_get_supports_alpm(); +int dp_controller_enable_alpm(bool enable, struct video_link_data *data); + +bool dp_controller_video_configured(); +bool dp_controller_wait_for_edp_hpd(utime_t *hpd_time); +void dp_controller_wait_for_HPD_to_BL(utime_t hpd_time); + +void dp_controller_wait_phy_locked(void); + +// device + +int dp_device_start(bool edp_panel); +int dp_device_wait_started(utime_t timeout); +void dp_device_stop(); +int dp_device_get_alignment_status_mask(u_int32_t *mask); +int dp_device_get_lane_status_mask(uint32_t lane, uint32_t *mask); +int dp_device_get_training_pattern(uint32_t *value, bool *scramble); +int dp_device_set_training_pattern(uint32_t value, bool scramble); +int dp_device_get_requested_adjustment_levels(uint32_t lane, u_int32_t *voltage, u_int32_t *eq); +int dp_device_set_adjustment_levels(uint32_t lane, u_int32_t voltage_swing, u_int32_t eq, + bool voltage_max_reached, bool eq_max_reached); +int dp_device_get_enhanced_mode(bool * value); +int dp_device_set_enhanced_mode(bool value); +int dp_device_get_ASSR(bool * value); +int dp_device_set_ASSR(bool value); +int dp_device_get_downspread(bool * value); +int dp_device_set_downspread(bool value); +int dp_device_get_lane_count(uint32_t * value); +int dp_device_set_lane_count(uint32_t value); +int dp_device_get_link_rate(u_int32_t * value); +int dp_device_set_link_rate(u_int32_t value); +int dp_device_hdcp_enable(bool enable); +int dp_device_get_downstream_port_type(int *ret_value); +int dp_device_get_raw_panel_id(u_int8_t *raw_panel_id); +int dp_device_get_sink_count(uint8_t * value); + +bool dp_device_get_supports_fast_link_training(); +bool dp_device_get_supports_alpm(); +int dp_device_enable_alpm(bool enable); +bool dp_device_is_alpm_enabled(); +bool dp_device_get_supports_enhanced_mode(); +bool dp_device_get_supports_assr(); +bool dp_device_get_supports_downspread(); +u_int32_t dp_device_get_revision(); +u_int32_t dp_device_get_max_lane_count(); +u_int32_t dp_device_get_max_link_rate(); + + + +#endif diff --git a/include/drivers/dither.h b/include/drivers/dither.h new file mode 100644 index 0000000..54b019a --- /dev/null +++ b/include/drivers/dither.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_DITHER_H +#define __DRIVERS_DITHER_H + +#include + +__BEGIN_DECLS + +#define DITHER_NONE (0 << 0) +#define DITHER_BLUE_NOISE (1 << 0) +#define DITHER_SPATIO_TEMPORAL (1 << 1) +#define DITHER_ERROR_DIFFUSION (1 << 2) + +#if DITHER_VERSION == 4 +void dither_init(uint32_t display_width, uint32_t display_height, uint32_t display_depth); +#else +void dither_init(uint32_t display_depth); +#endif +void dither_set_enable(bool enable); + +__END_DECLS + +#endif /* __DRIVERS_DITHER_H */ diff --git a/include/drivers/dma.h b/include/drivers/dma.h new file mode 100644 index 0000000..1d20198 --- /dev/null +++ b/include/drivers/dma.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_DMA_H +#define __DRIVERS_DMA_H + +#include + +__BEGIN_DECLS + +#define DMA_CMD_DIR_MEM (0x00000000) +#define DMA_CMD_DIR_TX (0x00000001) +#define DMA_CMD_DIR_RX (0x00000002) +#define DMA_CMD_DIR_MASK (0x00000003) + +void dma_init(void); + +/* + * dma_execute_cmd - simple DMA operation + * + * cmd - operation mode: MEM (MEMORY-MEMORY), TX (MEMORY-DEVICE) or RX (DEVICE-MEMORY) + * dma_channel - dma channel number + * src - source buffer or fifo + * dst - desination buffer or fifo + * length - size in bytes of the operation + * word_size - size in bytes of each word + * burst_size - size in words of each burst + * + * Returns 0 on success or -1 on failure + */ +int dma_execute_cmd(u_int32_t cmd, int dma_channel, + void *src, void *dst, u_int32_t length, + u_int32_t word_size, u_int32_t burst_size); + + +/* + * dma_execute_async - complex async DMA operation + * + * cmd - operation mode: MEM (MEMORY-MEMORY), TX (MEMORY-DEVICE) or RX (DEVICE-MEMORY) + * dma_channel - dma channel number + * sgl - memory scatter/gather list + * fifo - device fifo address + * length - size in bytes of the operation + * word_size - size in bytes of each word + * burst_size - size in words of each burst + * completion - completion callback + * completion_arg - argument passed to callback + * + * Returns 0 on success or -1 on failure + * + */ + +struct dma_segment { + u_int32_t paddr; + u_int32_t length; +}; + +typedef void (* dma_completion_function)(void *); + +int dma_execute_async(u_int32_t cmd, int dma_channel, + struct dma_segment *sgl, void *fifo, u_int32_t length, + u_int32_t word_size, u_int32_t burst_size, + dma_completion_function completion, void *completion_arg); + +void dma_use_int(int dma_channel, bool use); + +bool dma_poll(int dma_channel); + +/* + * dma_cancel - cancel DMA operation on a given channel. + * + * When this returns, the numbered DMA channel is guaranteed to be idle. + */ + +void dma_cancel(int dma_channel); + +/* + * DMA channel encryption + * + * A channel is configured to perform AES en/decryption by calling dma_set_aes() + * with a dma_aes_config structure. If NULL is passed as an argument, encryption + * is disabled for the channel; the en/decryption state is also reset at the completion + * or aborting of the transaction. + * + * The caller is responsible for ensuring the dma_aes_config structure remains valid + * for the duration of the operation. + * + * A constant key is used for a given DMA operation, however the caller may specify + * that a transfer should be broken into constant-sized chunks. For each chunk, the + * iv_func hook will be invoked with the chunk index (offset from 0 at the start of + * the transaction). + * + */ + +struct dma_aes_config { + /* AES configuration */ + u_int32_t command; /* AES_CMD bits from */ + u_int32_t keying; /* AES_KEY bits from */ + void *key; /* AES key for AES_KEY_TYPE_USER */ + + /* IV generation */ + u_int32_t chunk_size; /* AES chunk size */ + void (* iv_func)(void *arg, u_int32_t chunk_index, void *iv_buffer); + void *iv_func_arg; +}; + +int dma_set_aes(int dma_channel, struct dma_aes_config *config); + + +__END_DECLS + +#endif /* __DRIVERS_DMA_H */ diff --git a/include/drivers/dpb.h b/include/drivers/dpb.h new file mode 100644 index 0000000..40ba5c8 --- /dev/null +++ b/include/drivers/dpb.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_DPB_H +#define __DRIVERS_DPB_H + +#include + +__BEGIN_DECLS + +#if DPB_VERSION < 2 +void dpb_init(void); +#else +void dpb_init(uint32_t display_width, uint32_t display_height); +#endif +void dpb_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl); + +__END_DECLS + +#endif /* __DRIVERS_DPB_H */ diff --git a/include/drivers/dram.h b/include/drivers/dram.h new file mode 100644 index 0000000..e556139 --- /dev/null +++ b/include/drivers/dram.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __JEDEC_H +#define __JEDEC_H + +/* Based on JEDEC LPDDR2 spec */ + +enum { + JEDEC_MANUF_ID_RSVD0 = 0, + JEDEC_MANUF_ID_SAMSUNG, + JEDEC_MANUF_ID_QIMONDA, + JEDEC_MANUF_ID_ELPIDA, + JEDEC_MANUF_ID_ETRON, + JEDEC_MANUF_ID_NANYA, + JEDEC_MANUF_ID_HYNIX, + JEDEC_MANUF_ID_MOSEL, + JEDEC_MANUF_ID_WINBOND, + JEDEC_MANUF_ID_ESMT, + JEDEC_MANUF_ID_RSVD1, + JEDEC_MANUF_ID_SPANSION, + JEDEC_MANUF_ID_SST, + JEDEC_MANUF_ID_ZMOS, + JEDEC_MANUF_ID_INTEL, + JEDEC_MANUF_ID_NUMONYX, + JEDEC_MANUF_ID_MICRON, + JEDEC_MANUF_ID_RSVD2, + JEDEC_NUM_MANUF_IDS +}; + +// LPDDR4 vendor ids +#define JEDEC_LPDDR4_MANUF_ID_SAMSUNG JEDEC_MANUF_ID_SAMSUNG +#define JEDEC_LPDDR4_MANUF_ID_HYNIX JEDEC_MANUF_ID_HYNIX +#define JEDEC_LPDDR4_MANUF_ID_MICRON 0xFF +#define JEDEC_LPDDR4_MANUF_ID_ELPIDA JEDEC_LPDDR4_MANUF_ID_MICRON + +enum { + JEDEC_TYPE_S4_SDRAM = 0, + JEDEC_TYPE_S2_SDRAM +}; + +enum { + JEDEC_IO_WIDTH_32 = 0, + JEDEC_IO_WIDTH_16, + JEDEC_IO_WIDTH_8 +}; + +enum { + JEDEC_DENSITY_64Mb = 0, + JEDEC_DENSITY_128Mb, + JEDEC_DENSITY_256Mb, + JEDEC_DENSITY_512Mb, + JEDEC_DENSITY_1Gb, + JEDEC_DENSITY_2Gb, + JEDEC_DENSITY_4Gb, + JEDEC_DENSITY_8Gb, + JEDEC_DENSITY_16Gb, + JEDEC_DENSITY_32Gb +}; + +enum { + JEDEC_LPDDR4_DENSITY_4Gb = 0, + JEDEC_LPDDR4_DENSITY_6Gb, + JEDEC_LPDDR4_DENSITY_8Gb, + JEDEC_LPDDR4_DENSITY_12Gb, + JEDEC_LPDDR4_DENSITY_16Gb, + JEDEC_LPDDR4_DENSITY_24Gb, + JEDEC_LPDDR4_DENSITY_32Gb +}; + + +#define JEDEC_MR8_TYPE_SHIFT (0) +#define JEDEC_MR8_TYPE_MASK (0x3) +#define JEDEC_MR8_DENSITY_SHIFT (2) +#define JEDEC_MR8_DENSITY_MASK (0xF) +#define JEDEC_MR8_WIDTH_SHIFT (6) +#define JEDEC_MR8_WIDTH_MASK (0x3) + +#endif // __JEDEC_H diff --git a/include/drivers/edgeic.h b/include/drivers/edgeic.h new file mode 100644 index 0000000..d048d47 --- /dev/null +++ b/include/drivers/edgeic.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __DRIVERS_EDGEIC_H +#define __DRIVERS_EDGEIC_H + +#include + +__BEGIN_DECLS + +void edgeic_reset(void); +void edgeic_select_edge(u_int32_t vector, bool edge); +void edgeic_clear_interrupt(u_int32_t vector); + +__END_DECLS + +#endif /* __DRIVERS_EDGEIC_H */ diff --git a/include/drivers/ethernet.h b/include/drivers/ethernet.h new file mode 100644 index 0000000..553891d --- /dev/null +++ b/include/drivers/ethernet.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_ETHERNET_H +#define __DRIVERS_ETHERNET_H + +#include +#include + +__BEGIN_DECLS + +typedef struct ethq { + int read,write; + int numentries; + int queue_len; + int queue_len_mask; + + mymbuf_t **packets; // pointer to an array of pointers to mbufs +} ethqueue_t; + +typedef struct ethdstats { + int rxerrors; //Sum of all errors + int txerrors; //Sum of all errors + int runt; //? + int extra; //? + int crc; // crc error + int dribble; //? + int rxmissed; + int txcollisions; + int rxpktok; + int txpktok; + int rxbytes; + int txbytes; +} ethdstats_t; + + +typedef struct ethpriv +{ + ethdstats_t dstats; + ethqueue_t rxqueue; + ethqueue_t txqueue; + char macaddr[6]; +} ethstat_t; + +//Function declarations +// +//eth_init() +//NULL on failure, ptr private data otherwise. +int eth_init(void); + +int eth_start(ethstat_t *); + +int eth_stop(ethstat_t *); + +ethstat_t *eth_get_handle(void); + +int eth_printstatus(ethstat_t *); + +int eth_getpkt(ethstat_t *,char *buffer,int *len); + +int eth_output_packet(ethstat_t *d, const char *pkt,int len,int flag); + +void eth_setmacaddr(ethstat_t *data, const char macaddr[6]); + +void eth_getmacaddr(ethstat_t *data,char *buf); + +void eth_uninit(ethstat_t *data); + +#if WITH_HW_ETHERNET_SWITCH +int eth_switch_init(void); +#endif + + + +__END_DECLS + +#endif /* __DRIVERS_ETHERNET_H */ + diff --git a/include/drivers/flash_nand.h b/include/drivers/flash_nand.h new file mode 100644 index 0000000..43c660c --- /dev/null +++ b/include/drivers/flash_nand.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_FLASH_NAND_H +#define __DRIVERS_FLASH_NAND_H + +#include + +__BEGIN_DECLS + +int flash_nand_init(void); +int flash_nand_id(void); + +#if WITH_HW_BOOTROM_NAND +/* page offset into block zero from which the bootblock should be read */ +#define NAND_BOOTBLOCK_OFFSET 2 + +int nand_read_bootblock(u_int8_t interface, u_int8_t cs, void *buffer, size_t *size); +#endif + +__END_DECLS + +#endif /* __DRIVERS_FLASH_NAND_H */ diff --git a/include/drivers/flash_nor.h b/include/drivers/flash_nor.h new file mode 100644 index 0000000..39f2df5 --- /dev/null +++ b/include/drivers/flash_nor.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_FLASH_NOR_H +#define __DRIVERS_FLASH_NOR_H + +#include +#include + +__BEGIN_DECLS + +struct nor_blockdev { + struct blockdev bdev; + + uintptr_t handle; + + int (* readRange)(uintptr_t handle, uint8_t *ptr, uint32_t offset, uint32_t length); + int (* writeRange)(uintptr_t handle, const uint8_t *ptr, uint32_t offset, uint32_t length); + int (* eraseRange)(uintptr_t handle, uint32_t offset, uint32_t length); +}; + +/* pass -1 for which_device to use the target-defined default device */ +int flash_nor_init(int which_device); +int flash_nor_register(struct nor_blockdev *nor_bdev, const char *name, uint64_t len, uint32_t block_size); + +__END_DECLS + +#endif /* __DRIVERS_FLASH_NOR_H */ diff --git a/include/drivers/gasgauge.h b/include/drivers/gasgauge.h new file mode 100644 index 0000000..fa777f4 --- /dev/null +++ b/include/drivers/gasgauge.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2009 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_GASGAUGE_H +#define __DRIVERS_GASGAUGE_H + +#include +#include + +__BEGIN_DECLS + +void gasgauge_init(void); +void gasgauge_late_init(void); +void gasgauge_print_status(void); + +#define GG_NEEDS_PRECHARGE (1<<0) +#define GG_NEEDS_RESET (1<<1) +#define GG_COMMS_WD (1<<2) + +int gasgauge_needs_precharge(int debug_print_level, bool debug_show_target); +void gasgauge_will_shutdown(void); +bool gasgauge_full(void); +int gasgauge_get_battery_id(u_int8_t *buf, int size); +bool gasgauge_check_health(unsigned int vbat_mv); +bool gasgauge_read_charge_table(struct power_charge_limits *table, size_t num_elems); + +// gasgauge_read_temperature: returns 0 on success +int gasgauge_read_temperature(int *centiCelsiusTemperature); +// gasgauge_read_voltage: returns 0 on success +int gasgauge_read_voltage(unsigned int *milliVolt); +int gasgauge_read_design_capacity(unsigned int *milliAmpHours); +int gasgauge_read_soc(unsigned int *soc); +int gasgauge_reset_timer(int debug_print_level, unsigned int timeout); + +// Gas Gauge Flags +enum { + kHDQRegFlagsMaskOTC = (1 << 15), + kHDQRegFlagsMaskOTD = (1 << 14), + kHDQRegFlagsMaskCHG_INH = (1 << 11), + kHDQRegFlagsMaskXCHG = (1 << 10), + + kHDQRegFlagsMaskIMAXOK = (1 << 13), // Aquarius + kHDQRegFlagsMaskTC2 = (1 << 11), // 0x800 Aquarius + kHDQRegFlagsMaskTC1 = (1 << 10), // 0x400 Aquarius + + kHDQRegFlagsMaskFC = (1 << 9), + kHDQRegFlagsMaskCHG = (1 << 8), + kHDQRegFlagsMaskCCA_REQ = (1 << 5), // Aquarius + kHDQRegFlagsMaskLOWV = (1 << 4), // A4 + kHDQRegFlagsMaskSOC1 = (1 << 2), + kHDQRegFlagsMaskSOCF = (1 << 1), + kHDQRegFlagsMaskDSG = (1 << 0), +}; + +__END_DECLS + +#if (WITH_HW_GASGAUGE && DEBUG_BUILD) +// define BATTERY_TRAP_DEBUG for full gas gauge register dump in gasgauge_needs_precharge +#define BATTERY_TRAP_DEBUG +#endif +#endif /* __DRIVERS_GAUGE_H */ + diff --git a/include/drivers/hdc.h b/include/drivers/hdc.h new file mode 100644 index 0000000..1c25b96 --- /dev/null +++ b/include/drivers/hdc.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_HDC_H +#define __DRIVERS_HDC_H + +#include +#include + +__BEGIN_DECLS + +/* Generic Device defines */ +#define HDC_BLOCK_SIZE 512 + +#define HDC_CMD_READ 0x01 +#define HDC_CMD_WRITE 0x02 +#define HDC_CMD_INT 0x80 +#define HDC_CMD_MASK 0x7F + +#define HDC_ST_READY 0x0 +#define HDC_ST_BUSY 0x1 +#define HDC_ST_DONE 0x2 +#define HDC_ST_ERROR 0x3 + +#define HDC_SET_CMD_CMD(r,c) ((r) | (((c) & 0xff) << 24)) +#define HDC_SET_CMD_DISK(r,c) ((r) | (((c) & 0xff) << 16)) +#define HDC_SET_CMD_LEN(r,c) ((r) | (((c) & 0xff) << 0)) + +#define HDC_GET_STATUS_ST(r) (((r) >> 24) & 0xff) +#define HDC_GET_STATUS_DISK(r) (((r) >> 16) & 0xff) +#define HDC_GET_STATUS_CNT(r) (((r) >> 0) & 0xffff) + + +int hdc_init(void); + +__END_DECLS + +#endif /* __DRIVERS_HDC_H */ diff --git a/include/drivers/hdmi.h b/include/drivers/hdmi.h new file mode 100644 index 0000000..28a8c0a --- /dev/null +++ b/include/drivers/hdmi.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef DRIVERS_HDMI_H +#define DRIVERS_HDMI_H 1 + +#include +#include + +// Color component limits for limited range color +#define kVideoColorLimitedRangeYMin 16 // Also used for RGB +#define kVideoColorLimitedRangeYMax 235 // Also used for RGB +#define kVideoColorLimitedRangeCMin 16 +#define kVideoColorLimitedRangeCMax 240 + +// Timing Generator Limits (max value + 1) +#define kHorizontalTotalLimit 8192u +#define kHorizontalActiveLimit 4096u +#define kHorizontalBlankLimit 4096u +#define kVerticalTotalLimit 2048u +#define kVerticalActiveLimit 2048u +#define kVerticalBlankLimit 2048u + +#define kPHYReadyPollIntervalMS 10 +#define kVideoStabilizationIntervalMS 60 + +// controller config flags + +enum { + kHDMIControllerMode_Master = 0, + kHDMIControllerMode_Slave +}; +#define kHDMIControllerMode_Mask 0xf +#define kHDMIControllerMode_Shift 4 + +enum { + kHDMIControllerType_HDMI = 0, +}; +#define kHDMIControllerType_Mask 0xf +#define kHDMIControllerType_Shift 0 + +enum { + kHDMI_tx_mode_None = 0, + kHDMI_tx_mode_HDMI = 1, + kHDMI_tx_mode_DVI = 2, +} TX_Mode; + +struct pixel { + uint16_t r; // R or Cr + uint16_t g; // G or Y + uint16_t b; // B or Cb +}; + +// global +int hdmi_init(); +int hdmi_init_with_timing_info(struct display_timing *timing_info); +int hdmi_set_timings(struct display_timing *timing_info); +int hdmi_start_video(void); +bool hdmi_video_configured(); +void hdmi_quiesce(); + +// controller +int hdmi_controller_start(u_int8_t type, u_int8_t mode); +void hdmi_controller_stop(); +int hdmi_controller_validate_video(struct video_timing_data *data); +int hdmi_controller_read_bytes_i2c(u_int32_t device_addr, u_int8_t addr, u_int8_t *data, u_int32_t length); +int hdmi_controller_write_bytes_i2c(u_int32_t device_addr, u_int32_t addr, u_int8_t *data, u_int32_t length); +int hdmi_controller_start_video(struct video_link_data *data, uint32_t pixel_clock); +int hdmi_controller_stop_video(); + +uint8_t hdmi_read_reg(uint32_t offset); +void hdmi_write_reg(uint32_t offset, uint8_t value); + +bool hdmi_controller_video_configured(); + +// device + +int hdmi_device_start(); +int hdmi_device_wait_started(); +void hdmi_device_stop(); +#endif diff --git a/include/drivers/iic.h b/include/drivers/iic.h new file mode 100644 index 0000000..16a30a9 --- /dev/null +++ b/include/drivers/iic.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_IIC_H +#define __DRIVERS_IIC_H + +#include + +__BEGIN_DECLS + +typedef enum { + IIC_NORMAL = 1, + IIC_COMBINED = 2, +} iic_fmt_t; + +void iic_init(void); +void iic_set_filter(int iic, uint32_t value); +void iic_set_frequency(int iic, u_int32_t frequency); +int iic_read(int iic, uint8_t address, const void *send_data, size_t send_len, void *data, size_t len, iic_fmt_t fmt); +int iic_write(int iic, uint8_t address, const void *data, size_t len); + +bool iic_probe(int iic, uint8_t address); + +__END_DECLS + +#endif /* __DRIVERS_IIC_H */ diff --git a/include/drivers/iis.h b/include/drivers/iis.h new file mode 100644 index 0000000..aab6e78 --- /dev/null +++ b/include/drivers/iis.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_IIS_H +#define __DRIVERS_IIS_H + +#include +#include +#include + +__BEGIN_DECLS + +void iis_set_master(int iis, bool master); +int iis_set_bcpf(int iis, int bcpf); +int iis_set_usb(int iis, bool usb); +void iis_set_bclk_scaler(int iis, int bclk_scaler); + +void iis_tx(int iis, void *buf, size_t len); + +bool iis_is_done(int iis); +bool iis_wait_done(int iis, int ms); + +__END_DECLS + +#endif /* __DRIVERS_IIS_H */ diff --git a/include/drivers/ipipe.h b/include/drivers/ipipe.h new file mode 100644 index 0000000..080bde5 --- /dev/null +++ b/include/drivers/ipipe.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef IPIPE_H +#define IPIPE_H + +#include + +typedef struct ipipe ipipe_t; + +typedef void (ipipe_tx_callback_t)(void *priv, const uint8_t *packet, uint32_t bytes); + +ipipe_t *ipipe_init(uint32_t max_packet_size, ipipe_tx_callback_t *tx_callback, void *priv); +void ipipe_quiesce_and_free(ipipe_t *ipipe); +void ipipe_handle_packet(ipipe_t *ipipe, const uint8_t *packet, uint32_t bytes); + +#endif diff --git a/include/drivers/mcu.h b/include/drivers/mcu.h new file mode 100644 index 0000000..683fbca --- /dev/null +++ b/include/drivers/mcu.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2010 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_MCU_H +#define __DRIVERS_MCU_H + +#include + +__BEGIN_DECLS + +int mcu_init(void); +int mcu_start_recover(void); +int mcu_start_boot(void); +int mcu_set_passthrough_mode(bool on); +int mcu_send_info_frames(bool on); +int mcu_quiesce_uart(void); + +__END_DECLS + +#endif /* __DRIVERS_MCU_H */ + diff --git a/include/drivers/mipi.h b/include/drivers/mipi.h new file mode 100644 index 0000000..f6a4fbe --- /dev/null +++ b/include/drivers/mipi.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_MIPI_H +#define __DRIVERS_MIPI_H + +#include +#include + +__BEGIN_DECLS + +int mipi_dsim_init(struct display_timing *timing, enum colorspace color); +void mipi_dsim_enable_high_speed(bool enable); +void mipi_dsim_enable_video(bool enable); +int mipi_dsim_quiesce(void); +int mipi_dsim_send_short_command(u_int8_t cmd, u_int8_t data0, u_int8_t data1); +int mipi_dsim_send_long_command(u_int8_t cmd, const u_int8_t *data, u_int32_t length); +int mipi_dsim_read_short_command(u_int8_t cmd, u_int8_t *data); +int mipi_dsim_read_long_command(u_int8_t cmd, u_int8_t *data, u_int32_t *length); + +/* DSIM command types */ +#define DSIM_TYPE_DSC_WRITE 0x05 +#define DSIM_TYPE_DSC_READ 0x06 +#define DSIM_TYPE_GEN_READ_1P 0x14 +#define DSIM_TYPE_DSC_WRITE_1P 0x15 +#define DSIM_TYPE_DSC_READ_2P 0x24 +#define DSIM_TYPE_GEN_LONG_WRITE 0x29 +#define DSIM_TYPE_GEN_LUT_WRITE 0x39 + +/* DSIM response types */ +#define DSIM_RSP_READ_1B 0x11 +#define DSIM_RSP_READ_2B 0x12 +#define DSIM_RSP_LONG_READ 0x1A +#define DSIM_RSP_DSC_LONG_READ 0x1C +#define DSIM_RSP_DSC_READ_1B 0x21 +#define DSIM_RSP_DSC_READ_2B 0x22 + +/* DSIM commands / registers */ +#define DSIM_CMD_NOP 0x00 +#define DSIM_CMD_ENTER_SLEEP 0x10 +#define DSIM_CMD_EXIT_SLEEP 0x11 +#define DSIM_CMD_INVERT_OFF 0x20 +#define DSIM_CMD_INVERT_ON 0x21 +#define DSIM_CMD_DISPLAY_OFF 0x28 +#define DSIM_CMD_DISPLAY_ON 0x29 +#define DSIM_CMD_ADDRESS_MODE 0x36 +#define DSIM_CMD_DEVICE_ID 0xb1 + +__END_DECLS + +#endif /* ! __DRIVERS_MIPI_H */ diff --git a/include/drivers/miu.h b/include/drivers/miu.h new file mode 100644 index 0000000..9694ed0 --- /dev/null +++ b/include/drivers/miu.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_MIU_H +#define __DRIVERS_MIU_H + +#include + +__BEGIN_DECLS + +int mcu_initialize_dram(bool resume); +int mcu_suspend_dram(void); +void mcu_adjust_performance(void); +u_int64_t mcu_get_memory_size(void); + +__END_DECLS + +#endif /* __DRIVERS_MIU_H */ diff --git a/include/drivers/nand_boot.h b/include/drivers/nand_boot.h new file mode 100644 index 0000000..713e77f --- /dev/null +++ b/include/drivers/nand_boot.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _NAND_BOOT_H +#define _NAND_BOOT_H +#if WITH_NAND_BOOT + +#include + +__BEGIN_DECLS + +int nand_boot_init(void); + +__END_DECLS + +#endif /* WITH_NAND_BOOT */ +#endif /* ! _NAND_BOOT_H */ diff --git a/include/drivers/nand_device_tree.h b/include/drivers/nand_device_tree.h new file mode 100644 index 0000000..fcc8448 --- /dev/null +++ b/include/drivers/nand_device_tree.h @@ -0,0 +1,19 @@ +// Copyright (C) 2009 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// + +#include + +#ifndef _NAND_DEVICETREE_H_ + +// Add required NAND properties to the given device-tree node + +void fillNandConfigProperties(DTNode *node); + +#endif //_NAND_DEVICETREE_H_ diff --git a/include/drivers/nand_syscfg.h b/include/drivers/nand_syscfg.h new file mode 100644 index 0000000..7d29c64 --- /dev/null +++ b/include/drivers/nand_syscfg.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _NAND_SYSCFG_H +#define _NAND_SYSCFG_H + +#include + +__BEGIN_DECLS + +int nand_syscfg_init(NandPartInterface * npi); + +__END_DECLS + +#endif /* ! _NAND_SYSCFG_H */ diff --git a/include/drivers/nvme.h b/include/drivers/nvme.h new file mode 100644 index 0000000..84997fc --- /dev/null +++ b/include/drivers/nvme.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef DRIVERS_NVME_H +#define DRIVERS_NVME_H + +#include +#include +#if WITH_DEVICETREE +#include +#endif + +// NVMe for iOS says we can assume IDENTIFY.MDTS >= 8, which translates to 256 blocks +#define NVME_BOOT_MAX_TRANSFER_BLOCKS (256) + +#define NVME_NAMESPACE_NAND 1 +#define NVME_NAMESPACE_FIRMWARE 2 +#define NVME_NAMESPACE_SYSCFG 3 +#define NVME_NAMESPACE_NVRAM 5 +#define NVME_NAMESPACE_EFFACEABLE 6 +#define NVME_NAMESPACE_PANICLOG 7 + +#define NVME_BLOCK_SIZE (1<<12) + +#define NVME_SUCCESS (0) +// Error codes from -1 to -4095 are reserved for NVMe errors +// - Bits 7:0 get the SC field from the completion +// - Bits 11:8 get the SCT field from the completion +// - See the NVMe spec for details on errors from -1 to -4095 +// Error codes from 5000 to 5999 for PCI errors +#define NVME_ERR_PROBE_FAILED (-5000) +#define NVME_ERR_INVALID_CLASS_CODE (-5001) +#define NVME_ERR_INVALID_BAR (-5002) +#define NVME_ERR_INVALID_REG (-5003) +// Error codes from 6000 to 6999 for controller initialization errors +#define NVME_ERR_DISABLE_TIMEOUT (-6000) +#define NVME_ERR_ENABLE_TIMEOUT (-6001) +#define NVME_ERR_SHUTDOWN_TIMEOUT (-6002) +#define NVME_ERR_CFS (-6003) +#define NVME_ERR_POLL_REG_TIMEOUT (-6004) +#define NVME_ERR_INVALID_DSTRD (-6100) +#define NVME_ERR_INVALID_MPSMIN (-6101) +#define NVME_ERR_INVALID_MQES (-6102) +#define NVME_ERR_INVALID_SQES (-6103) +#define NVME_ERR_INVALID_CQES (-6104) +#define NVME_ERR_INVALID_DDRREQALIGN (-6150) +#define NVME_ERR_INVALID_DDRREQSIZE (-6151) +// Error codes from 7000 to 7999 for command processing errors +#define NVME_ERR_INVALID_CMPL_SQID (-7001) +#define NVME_ERR_INVALID_CMPL_SQHD (-7002) +#define NVME_ERR_IO_CMD_TIMEOUT (-7003) +#define NVME_ERR_ADMIN_CMD_TIMEOUT (-7004) +#define NVME_ERR_CMPL_CID_MISMATCH (-7005) +// Error codes from 8000 to 8999 are generic driver errors +#define NVME_ERR_NOT_ENABLED (-8000) + +typedef struct nvme_namespace_params_t { + bool formatted; + uint64_t num_blocks; + uint32_t block_size; +} nvme_namespace_params_t; + +int nvme_init(int nvme_id, pci_device_t bridge, uint32_t dart_id); +void nvme_quiesce(int nvme_id); +void nvme_quiesce_all(void); +int nvme_read_blocks(int nvme_id, uint32_t nsid, void *ptr, uint32_t block, uint32_t count); +int nvme_write_blocks(int nvme_id, uint32_t nsid, const void *ptr, uint32_t block, uint32_t count); +int nvme_identify_namespace(int nvme_id, uint32_t nsid, nvme_namespace_params_t *params_out); +uint32_t nvme_get_max_transfer_blocks(int nvme_id); +int nvme_init_mass_storage(int nvme_id); +int nvme_init_mass_storage_panic(int nvme_id); + +#if WITH_DEVICETREE +void nvme_update_devicetree (int nvme_id, dt_node_t *node); +#endif + +#endif // DRIVERS_NVME_H diff --git a/include/drivers/pci.h b/include/drivers/pci.h new file mode 100644 index 0000000..1f40750 --- /dev/null +++ b/include/drivers/pci.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2008-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_PCI_PCI_H +#define __DRIVERS_PCI_PCI_H + +#include +#include + +typedef void (*pci_config_read_cb_t)(void *priv, void *dst, uint32_t bdfo, int size); +typedef void (*pci_config_write_cb_t)(void *priv, const void *src, uint32_t bdfo, int size); + +typedef struct pci_device * pci_device_t; + +void pci_init(void); +void pci_free(pci_device_t dev); + +// Config space accessors +uint8_t pci_config_read8(pci_device_t dev, uint16_t offset); +uint16_t pci_config_read16(pci_device_t dev, uint16_t offset); +uint32_t pci_config_read32(pci_device_t dev, uint16_t offset); +void pci_config_write8(pci_device_t dev, uint16_t offset, uint8_t value); +void pci_config_write16(pci_device_t dev, uint16_t offset, uint16_t value); +void pci_config_write32(pci_device_t dev, uint16_t offset, uint32_t value); + +uint64_t pci_get_bar_size(pci_device_t dev, unsigned bar_idx); +pci_device_t pci_get_bridge(pci_device_t dev); +uint32_t pci_get_class_code(pci_device_t dev); +uint16_t pci_get_device_id(pci_device_t dev); +uint8_t pci_get_header_type(pci_device_t dev); +uint8_t pci_get_revision_id(pci_device_t dev); +uint16_t pci_get_vendor_id(pci_device_t dev); + +uintptr_t pci_map_bar(pci_device_t dev, unsigned bar_idx); +void pci_bus_master_enable(pci_device_t dev, bool enable); +void pci_memory_space_enable(pci_device_t dev, bool enable); + +// Capabilities +uint16_t pci_find_capability(pci_device_t dev, uint16_t capability_id); +uint16_t pci_find_extended_capability(pci_device_t dev, uint16_t capability_id, uint8_t min_version); + +// Power management +void pci_set_powerstate(pci_device_t dev, uint8_t powerstate); +void pci_enable_pcie_aspm(pci_device_t dev); +void pci_enable_pcie_l1ss(pci_device_t dev); +bool pci_enable_pcie_ltr(pci_device_t dev); + +// Random info +void pci_set_name(pci_device_t dev, const char *name); +const char *pci_get_name(pci_device_t dev); + +// Bridges +bool pci_is_bridge(pci_device_t dev); +pci_device_t pci_create_host_bridge(const char *name, uint8_t bus_num, uint32_t memory_base, uint32_t memory_size, void *priv, pci_config_read_cb_t read_cb, pci_config_write_cb_t write_cb); +pci_device_t pci_bridge_probe(pci_device_t bridge, uint8_t device_num, utime_t timeout); +void pci_bridge_assign_secondary_bus(pci_device_t bridge); +void pci_bridge_serr_enable(pci_device_t dev, bool enable); + +#define PCI_BUS_SHIFT 20 +#define PCI_DEVICE_SHIFT 15 +#define PCI_FUNCTION_SHIFT 12 +#define PCI_BDFO(bus, device, function, offset) ((((uint32_t)bus) << PCI_BUS_SHIFT) | (((uint32_t)device) << PCI_DEVICE_SHIFT) | (((uint32_t)function) << PCI_FUNCTION_SHIFT) | (offset)) +#define PCI_BDF(bus, device, function) (PCI_BDFO((bus), (device), (function), 0)) +#define PCI_DFO(device, function, offset) (PCI_BDFO(0, (device), (function), (offset))) +#define PCI_DFO_MASK ((1 << PCI_BUS_SHIFT)-1) +#define PCI_DEVICE_MASK (0x1F << PCI_DEVICE_SHIFT) +#define PCI_FUNCTION_MASK (0x7 << PCI_FUNCTION_SHIFT) +#define PCI_BUS(bdfo) (bdfo >> PCI_BUS_SHIFT) +#define PCI_DEVICE(bdfo) (((bdfo) & PCI_DEVICE_MASK) >> PCI_DEVICE_SHIFT) +#define PCI_FUNCTION(bdfo) (((bdfo) & PCI_FUNCTION_MASK) >> PCI_FUNCTION_SHIFT) + +#define PCI_CONFIG_VENDOR_ID 0x00 +#define PCI_CONFIG_DEVICE_ID 0x02 +#define PCI_CONFIG_COMMAND 0x04 +#define PCI_CONFIG_STATUS 0x06 +#define PCI_CONFIG_REVISION_ID 0x08 +#define PCI_CONFIG_CLASS_CODE 0x09 +#define PCI_CONFIG_CACHE_LINE_SIZE 0x0C +#define PCI_CONFIG_LATENCY_TIMER 0x0D +#define PCI_CONFIG_HEADER_TYPE 0x0E +#define PCI_CONFIG_BIST 0x0F +#define PCI_CONFIG_BASE_ADDRESS0 0x10 +#define PCI_CONFIG_BASE_ADDRESS1 0x14 +#define PCI_CONFIG_BASE_ADDRESS2 0x18 +#define PCI_CONFIG_BASE_ADDRESS3 0x1C +#define PCI_CONFIG_BASE_ADDRESS4 0x20 +#define PCI_CONFIG_BASE_ADDRESS5 0x24 +#define PCI_CONFIG_CARDBUS_CIS_PTR 0x28 +#define PCI_CONFIG_SUBSYSTEM_VENDOR_ID 0x2C +#define PCI_CONFIG_SUBSYSTEM_ID 0x2E +#define PCI_CONFIG_EXPANSION_ROM_BASE 0x30 +#define PCI_CONFIG_CAPABILITIES_PTR 0x34 +#define PCI_CONFIG_INTERRUPT_LINE 0x3C +#define PCI_CONFIG_INTERRUPT_PIN 0x3D +#define PCI_CONFIG_MINIMUM_GRANT 0x3E +#define PCI_CONFIG_MAXIMUM_LATENCY 0x3F + +#define PCI_CONFIG_PRIMARY_BUS_NUMBER 0x18 +#define PCI_CONFIG_SECONDARY_BUS_NUMBER 0x19 +#define PCI_CONFIG_SUBORDINATE_BUS_NUMBER 0x1A +#define PCI_CONFIG_SECONDARY_LATENCY_TIMER 0x1B +#define PCI_CONFIG_IO_BASE 0x1C +#define PCI_CONFIG_IO_LIMIT 0x1D +#define PCI_CONFIG_SECONDARY_STATUS 0x1E +#define PCI_CONFIG_MEMORY_BASE 0x20 +#define PCI_CONFIG_MEMORY_LIMIT 0x22 +#define PCI_CONFIG_PREFETCHABLE_BASE 0x24 +#define PCI_CONFIG_PREFETCHABLE_LIMIT 0x26 +#define PCI_CONFIG_PREFETCHABLE_BASE_UPPER32 0x28 +#define PCI_CONFIG_PREFETCHABLE_LIMIT_UPPER32 0x2C +#define PCI_CONFIG_IO_BASE_UPPER16 0x30 +#define PCI_CONFIG_IO_LIMIT_UPPER16 0x32 +#define PCI_CONFIG_BRIDGE_CONTROL 0x3E + +#define PCI_CMD_IO_SPACE_ENABLE (1 << 0) +#define PCI_CMD_MEMORY_SPACE_ENABLE (1 << 1) +#define PCI_CMD_BUS_MASTER_ENABLE (1 << 2) +#define PCI_CMD_SERR_ENABLE (1 << 8) + +#define PCI_BRIDGE_CTRL_SERR_ENABLE (1 << 1) + +#define PCI_STATUS_CAPABILITIES_LIST (1 << 4) + +#define PCI_CAP_ID_PM (0x01) + +#define PCI_PM_CAP_PMC (0x02) +#define PCI_PM_CAP_PMCSR (0x04) +#define PCI_PM_CAP_PMCSR_BSE (0x06) +#define PCI_PM_CAP_DATA (0x07) + +#define PCI_PM_POWERSTATE_D0 (0x0) +#define PCI_PM_POWERSTATE_D3 (0x3) + +// PCIe r3.0 section 7.8 +#define PCI_CAP_ID_PCIE (0x10) + +#define PCI_PCIE_CAP_PCIE_CAPABILITIES (0x02) +#define PCI_PCIE_CAP_LINK_CAPABILITIES (0x0C) +#define PCI_PCIE_CAP_LINK_CONTROL (0x10) +#define PCI_PCIE_CAP_DEVICE_CAPABILITIES2 (0x24) +#define PCI_PCIE_CAP_DEVICE_CONTROL2 (0x28) +#define PCI_PCIE_CAP_LINK_CAPABILITIES2 (0x2C) +#define PCI_PCIE_CAP_LINK_CONTROL2 (0x30) + +// PCIe r3.0 section 7.8.2 +#define PCI_PCIE_TYPE_ENDPOINT (0) +#define PCI_PCIE_TYPE_ROOT_PORT (4) +#define PCI_PCIE_TYPE_UPSTREAM (5) +#define PCI_PCIE_TYPE_DOWNSTREAM (6) +#define PCI_PCIE_TYPE_UNKNOWN (UINT8_MAX) // for endpoints without a PCIe capability + +// PCIe r3.0 section 7.8.6/7.8.18 +#define PCI_PCIE_SPEED_GEN1 (0) +#define PCI_PCIE_SPEED_GEN2 (1) +#define PCI_PCIE_SPEED_GEN3 (2) + +// PCIe r3.0 section 7.25 +#define PCI_EXT_CAP_ID_LTR (0x18) + +#define PCI_LTR_CAP_MAX_SNOOP_LATENCY (0x04) +#define PCI_LTR_CAP_MAX_NO_SNOOP_LATENCY (0x06) + +#define PCI_EXT_CAP_ID_L1SS (0x1E) + +#define PCI_L1SS_CAP_CAPABILITIES (0x04) +#define PCI_L1SS_CAP_CONTROL1 (0x08) +#define PCI_L1SS_CAP_CONTROL2 (0x0c) + +#endif diff --git a/include/drivers/phy.h b/include/drivers/phy.h new file mode 100644 index 0000000..069c3c1 --- /dev/null +++ b/include/drivers/phy.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* + * Ethernet PHY support. + */ +#ifndef __DRIVERS_PHY_H +#define __DRIVERS_PHY_H + +#include + +__BEGIN_DECLS + +enum phy_speed { + PHY_SPEED_UNKNOWN, + PHY_SPEED_AUTO, + PHY_SPEED_10, + PHY_SPEED_100, + PHY_SPEED_1000 +}; + +int phy_init(int port); +int phy_set_speed(int port, enum phy_speed speed); +bool phy_get_link(int port); +extern int phy_read_reg(int port, uint32_t reg, uint16_t *data); +extern int phy_write_reg(int port, uint32_t reg, uint16_t data); + +__END_DECLS + +#endif /* __DRIVERS_PHY_H */ diff --git a/include/drivers/pke.h b/include/drivers/pke.h new file mode 100644 index 0000000..a58b1fc --- /dev/null +++ b/include/drivers/pke.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DRIVERS_PKE_H +#define __DRIVERS_PKE_H + +#include + +__BEGIN_DECLS + +bool pke_do_exp(uint8_t *dst, size_t *len, + size_t uKeyLen, + uint8_t * const base, size_t base_length, + uint8_t * const expn, size_t expn_length, + uint8_t * const mods, size_t mods_length); + +__END_DECLS + +#endif /* __DRIVERS_PKE_H */ diff --git a/include/drivers/power.h b/include/drivers/power.h new file mode 100644 index 0000000..0859156 --- /dev/null +++ b/include/drivers/power.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_POWER_H +#define __DRIVERS_POWER_H + +#include + +__BEGIN_DECLS + +#define kPowerBootFlagCold (0) +#define kPowerBootFlagColdButton (1) +#define kPowerBootFlagWarm (2) +#define kPowerBootFlagResumeLost (3) + +int power_init(void); +int power_late_init(void); +int power_backlight_enable(u_int32_t backlight_level); +int power_get_boot_flag(void); + +void power_suspend(void); +void power_shutdown(void); // tell the pmu to pull the plug +int power_set_soc_voltage(unsigned mv, int override); +int power_set_cpu_voltage(unsigned mv, int override); +int power_set_ram_voltage(unsigned mv, int override); + +#define POWER_RAIL_CPU 0 +#define POWER_RAIL_VDD_FIXED 1 +#define POWER_RAIL_SOC 2 +#define POWER_RAIL_CPU_RAM 3 +#define POWER_RAIL_GPU 4 +#define POWER_RAIL_GPU_RAM 5 +// not a rail, might move this to target +#define POWER_RAIL_COUNT 6 + +// @rail one of POWER_RAIL_* (replace power_get_buck_value(), backward compatible) +int power_get_rail_value(int rail, unsigned mv, u_int32_t *buffer); +// @rail one of POWER_RAIL_* (backward compatible with power_convert_dwi_to_mv()) +int power_convert_dwi_to_mv(int rail, u_int32_t dwival); +// deprecated, use power_get_rail_value() ( buck is not the buck# ) +int power_get_buck_value(int buck, unsigned mv, u_int32_t *buffer); + +int power_set_display_voltage_offset(u_int32_t voltage_offset, bool fixed_boost); + +void power_set_usb_state(bool configured, bool suspended); +void power_set_usb_enabled(bool enabed); +int power_set_gpio(u_int32_t gpio, u_int32_t direction, u_int32_t value); +int power_set_ldo(u_int32_t ldo, u_int32_t voltage); +int power_enable_ldo(u_int32_t ldo, bool enable); +bool power_get_gpio(u_int32_t gpio); +void power_gpio_configure(u_int32_t gpio, u_int32_t config); + +bool power_needs_precharge(void); +bool power_needs_thermal_trap(void); +bool power_do_chargetrap(void); +void power_cancel_buttonwait(void); +bool power_is_suspended(void); +void power_will_resume(void); +bool power_has_usb(void); +int power_read_dock_id(unsigned *id); +bool power_get_diags_dock(void); +u_int32_t power_get_boot_battery_level(void); +u_int32_t power_get_battery_level(void); +void power_get_usb_brick_id(uint32_t *id, size_t count); +bool power_has_batterypack(void); +bool power_enable_charging(bool inflow, bool charging); +uint32_t power_get_available_charge_current(void); + +int power_get_nvram(u_int8_t key, u_int8_t *data); +int power_set_nvram(u_int8_t key, u_int8_t data); +void power_clr_events(int wake); + + +#define kPowerNVRAMiBootStateName "iBootState" +#define kPowerNVRAMiBootStateKey (0) + +#define kPowerNVRAMiBootStatePrecharge (1 << 5) // can be or'd with modes below +#define kPowerNVRAMiBootStateThermalTrap (1 << 0) +#define kPowerNVRAMiBootStateModeMask (0xd0) // bits 4, 6 and 7 (keep backwards compatible) +#define kPowerNVRAMiBootStateModeNormalBoot (0x00) +#define kPowerNVRAMiBootStateModeResumed (0x40) +#define kPowerNVRAMiBootStateModeSuspended (0x80) +#define kPowerNVRAMiBootStateModeButtonwaitWithGraphics (0x10) +#define kPowerNVRAMiBootStateModeButtonwaitNoGraphics (0x90) + +#define kPowerNVRAMiBootDebugName "iBootDebug" +#define kPowerNVRAMiBootDebugKey (1) +#define kPowerNVRAMiBootDebugIAPSerial (1 << 0) +#define kPowerNVRAMiBootDebugAltSerial (1 << 1) +#define kPowerNVRAMiBootDebugJtag (1 << 2) +#define kPowerNVRAMiBootDebugEarlyTracing (1 << 3) +#define kPowerNVRAMiBootDebugBatteryTrap (1 << 4) +#define kPowerNVRAMiBootDebugWDTWake (1 << 7) + +#define kPowerNVRAMiBootStageName "iBootStage" +#define kPowerNVRAMiBootStageKey (2) +#define kPowerNVRAMiBootStageOff (0x00) +#define kPowerNVRAMiBootStageLLBStart (0x10) +#define kPowerNVRAMiBootStageLLBEnd (0x1F) +#define kPowerNVRAMiBootStageiBootStart (0x20) +#define kPowerNVRAMiBootStageiBootEnd (0x2F) +#define kPowerNVRAMDiagsStageDiagsBootComplete (0xD0) +#define kPowerNVRAMiBootStagePanicSave (0xE0) +#define kPowerNVRAMiBootStagePanicReboot (0xE1) +#define kPowerNVRAMiBootStagePrechargeReboot (0xE2) +#define kPowerNVRAMiBootStageBooted (0xFF) + +#if PRODUCT_LLB +#define kPowerNVRAMiBootStageProductStart kPowerNVRAMiBootStageLLBStart +#define kPowerNVRAMiBootStageProductEnd kPowerNVRAMiBootStageLLBEnd +#endif + +#if PRODUCT_IBOOT || PRODUCT_IBEC +#define kPowerNVRAMiBootStageProductStart kPowerNVRAMiBootStageiBootStart +#define kPowerNVRAMiBootStageProductEnd kPowerNVRAMiBootStageiBootEnd +#endif + +#if PRODUCT_IBSS +#define kPowerNVRAMiBootStageProductStart kPowerNVRAMiBootStageLLBStart +#define kPowerNVRAMiBootStageProductEnd kPowerNVRAMiBootStageiBootEnd +#endif + +#define kPowerNVRAMiBootErrorCountName "iBootErrorCount" +#define kPowerNVRAMiBootErrorCountKey (3) +#define kPowerNVRAMiBootErrorCountMask (0x0F) +#define kPowerNVRAMiBootErrorPanicShift (4) +#define kPowerNVRAMiBootErrorBootShift (0) + +#define kPowerNVRAMiBootErrorStageName "iBootErrorStage" +#define kPowerNVRAMiBootErrorStageKey (4) + +#define kPowerNVRAMiBootMemCalCAOffset0Key (5) // CA offset need 2 bytes +#define kPowerNVRAMiBootMemCalCAOffset1Key (6) +#define kPowerNVRAMiBootMemCalCAOffset2Key (7) +#define kPowerNVRAMiBootMemCalCAOffset3Key (8) + +#define kPowerNVRAMiBootMemCalCAOffset0Name "iBootMemCalCAOffset0" +#define kPowerNVRAMiBootMemCalCAOffset1Name "iBootMemCalCAOffset1" +#define kPowerNVRAMiBootMemCalCAOffset2Name "iBootMemCalCAOffset2" +#define kPowerNVRAMiBootMemCalCAOffset3Name "iBootMemCalCAOffset3" + +#define kPowerNVRAMiBootBootFlags0Key (9) +#define kPowerNVRAMiBootBootFlags1Key (10) + +#define kPowerNVRAMiBootBootFlags0Name "iBootBootFlags0" +#define kPowerNVRAMiBootBootFlags1Name "iBootBootFlags1" + +#define kPowerNVRAMiBootEnterDFUName "iBootEnterDFU" +#define kPowerNVRAMiBootEnterDFUKey (11) +#define kPowerNVRAMiBootEnterDFURequest (0xA0) +#define kPowerNVRAMiBootEnterDFUOff (0x00) + +#define kPowerNVRAMPropertyCount (12) + +struct power_charge_limits +{ + uint16_t upperVoltageLimit; /* mV */ + int16_t lowerTempLimit; /* cC */ + int16_t upperTempLimit; /* cC */ + uint16_t currentSetting; /* charger-dependent */ +}; + +bool power_load_memory_calibration(void *settings, uint32_t settingsSize); +bool power_store_memory_calibration(void *settings, uint32_t settingsSize); + +void pmu_early_init(void); +void pmu_setup(void); +void pmu_late_init(void); +void pmu_will_resume(void); +void pmu_shutdown(void); +void pmu_suspend(void); +void pmu_set_backlight_enable(uint32_t backlight_level); +u_int32_t pmu_read_brick_id_level(void); +int pmu_read_system_temperature(int idx, int *centiCelsiusTemperature); +void pmu_check_events(bool *powersupply_change_event, + bool *button_event, + bool *other_wake_event); +int pmu_uvwarn_config(int dev, uint32_t thresholdMV); + +bool power_load_voltage_knobs(void *settings, uint32_t settingsSize); +bool power_store_voltage_knobs(void *settings, uint32_t settingsSize); + +utime_t power_get_calendar_time(void); + + +// Dark boot API's + +void power_clear_dark_boot_flag (void); // Clears the dark boot flag from NVRAM. Call on every startup AFTER nvram is writable +void power_disable_dark_boot (void); // Disables dark boot by lighting up display to previous backlight command +void power_dark_boot_checkpoint (void); // Checks for button presses and disables dark boot if needed. +bool power_is_dark_boot (void); // Returns true if we are doing a dark boot. + +// smartport API +// + +#define SMARTPORT_EXT_PWR_IN_SEL 1 +#define SMARTPORT_ACC_PWR_IN_SEL 0 + +int smartport_get_data(int dev, uint16_t reg, uint8_t *byte); // low level, you don't need this +int smartport_get_pwr_in_sel(int dev, uint8_t *sel); // power switch state + + +__END_DECLS + +#endif /* __DRIVERS_POWER_H */ diff --git a/include/drivers/prc.h b/include/drivers/prc.h new file mode 100644 index 0000000..44c471c --- /dev/null +++ b/include/drivers/prc.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_PRC_H +#define __DRIVERS_PRC_H + +#include + +__BEGIN_DECLS + +void prc_init(uint32_t display_width, uint32_t display_height); +void prc_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl); + +__END_DECLS + +#endif /* __DRIVERS_PRC_H */ \ No newline at end of file diff --git a/include/drivers/process_edid.h b/include/drivers/process_edid.h new file mode 100644 index 0000000..7712c38 --- /dev/null +++ b/include/drivers/process_edid.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_HW_MCU + +#ifndef PROCESS_EDID_H +#define PROCESS_EDID_H 1 + +#if WITH_HW_DISPLAY_DISPLAYPORT +#include +#endif + +#if WITH_HW_DISPLAY_HDMI +#include +#endif + +// Collect EDID data and decide on the best scoring display mode. +int obtain_edid(void); + +// Break out of the EDID polling loop. +void abort_edid(void); + +// Reject timings not matching these dimensions. +void restrict_edid(uint32_t h_active, uint32_t v_active); + +// Get previously collected best display mode. +int get_edid_timings(struct video_timing_data *data); + +// Get the detected downstream port type, e.g kDPDownstreamTypeHDMI +int get_edid_downstream_type(void); + +#endif // PROCESS_EDID_H + +#endif // WITH_HW_MCU diff --git a/include/drivers/radio.h b/include/drivers/radio.h new file mode 100644 index 0000000..b24f1eb --- /dev/null +++ b/include/drivers/radio.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_RADIO_H +#define __DRIVERS_RADIO_H + +#include + +#if WITH_DEVICETREE +#include +#endif + +#include + +__BEGIN_DECLS + +bool radio_get_property(enum target_property prop, void *data, int maxdata, int *retlen); +void radio_init(void); +void radio_early_init(void); +void radio_late_init(void); +void radio_quiesce(void); +void radio_power_off(void); + +void radio_init_pins( void ); + +void radio_pmu_power_on(void); +void radio_pmu_power_off(void); + +bool radio_board_present(void); + +#if WITH_DEVICETREE +int radio_update_device_tree(DTNode *radio_node); +#endif + +__END_DECLS + +#endif /* ! __DRIVERS_RADIO_H */ diff --git a/include/drivers/reconfig.h b/include/drivers/reconfig.h new file mode 100644 index 0000000..ac79729 --- /dev/null +++ b/include/drivers/reconfig.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __RECONFIG_H +#define __RECONFIG_H + +#include +#include + +typedef enum { + AWAKE_AOP_DDR_PRE = 0, + AWAKE_AOP_DDR_POST, + AOP_DDR_S2R_AOP_PRE, + AOP_DDR_S2R_AOP_POST, + S2R_AOP_AOP_DDR_PRE, + S2R_AOP_AOP_DDR_POST, + AOP_DDR_AWAKE_PRE, + AOP_DDR_AWAKE_POST, + MAX_STAGE +} reconfig_stage_t; + +enum { + END_COMMAND = 0x0, + WRITE_COMMAND = 0x1, + READ_COMMAND = 0x2, + DELAY_COMMAND = 0x4, + NOP_COMMAND = 0x4, +}; + +typedef struct write_command_t { + uint32_t in_progress; + uint64_t address; + uint32_t is_reg64; + uint32_t offsets[4]; + uint32_t value_count; + uint64_t values[16]; + +} write_command_t; + +typedef enum { + REGION_ONLY, + COMMAND_ONLY, + REGION_AND_COMMAND, +} reconfig_dump_t; + +void reconfig_init(enum boot_target target); + +void reconfig_command_write(reconfig_stage_t stage, uint64_t addr, uint64_t value, uint32_t is_reg64); + +void reconfig_command_read(reconfig_stage_t stage, uint64_t addr, uint64_t value, uint64_t mask, uint32_t retry_cnt, uint32_t is_reg64); + +void reconfig_command_delay(reconfig_stage_t stage, uint32_t delay); + +void reconfig_command_nop(reconfig_stage_t stage); + +void reconfig_command_raw(reconfig_stage_t stage, const uint32_t *cmd, uint32_t cmdItems); + +void reconfig_commit(reconfig_stage_t stage); + +void reconfig_lock(enum boot_target target); + +void dump_reconfig(reconfig_dump_t option); + +static void validate_stage(reconfig_stage_t stage); +static void commit_write_command(reconfig_stage_t stage, write_command_t *wc); +static void bounds_check_stage(reconfig_stage_t stage); +static void reconfig_write_pending(reconfig_stage_t stage); + +// For 64 bit registers the data/mask etc.. need to be aligned to 64 bits +// count * 4 is the register offset from the 64 bit aligned base. So the following should +// tell if we are aligned or not +#define ALIGNED_64(count) ((count) % 2 == 0) +#define ALIGNMENT_MARKER 0xDEADBEEF +#define SEQUENCE_END 0xDEADDEAD + +#endif /* __RECONFIG_H */ diff --git a/include/drivers/rsecc.h b/include/drivers/rsecc.h new file mode 100644 index 0000000..b76192f --- /dev/null +++ b/include/drivers/rsecc.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_RSECC_H +#define __DRIVERS_RSECC_H + +#include + +__BEGIN_DECLS + +enum rsecc_mode { + ECC_4BIT = 0, + ECC_6BIT, + ECC_8BIT, +}; + +int rsecc_encode(enum rsecc_mode mode, int sector_count, const void *datapointer, void *eccbuf); +int rsecc_decode(enum rsecc_mode mode, int sector_count, void *datapointer, const void *eccbuf); + +__END_DECLS + +#endif /* __DRIVERS_RSECC_H */ + + diff --git a/include/drivers/sha1.h b/include/drivers/sha1.h new file mode 100644 index 0000000..f52d6b2 --- /dev/null +++ b/include/drivers/sha1.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_SHA1_H +#define __DRIVERS_SHA1_H + +#include +#include + +#if WITH_CORECRYPTO +#include +#else +#define CCSHA1_OUTPUT_SIZE (20) // bytes +#endif + +__BEGIN_DECLS + +void sha1_calculate(const void *buffer, size_t length, void *result); +#if WITH_CORECRYPTO +const struct ccdigest_info *sha1_get_ccsha1_ccdigest_info(); +#endif + +__END_DECLS + +#endif /* __DRIVERS_SHA1_H */ diff --git a/include/drivers/shmcon.h b/include/drivers/shmcon.h new file mode 100644 index 0000000..fe6cf97 --- /dev/null +++ b/include/drivers/shmcon.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_SHMCON_H +#define __DRIVERS_SHMCON_H + +#include + +/* + * High-level shared memory console interface. + * Port argument exists for compatibility with UART functions + */ +int shmcon_init(void); + +int shmcon_getc(int port, bool wait); +int shmcon_putc(int port, char c); +int shmcon_puts(int port, const char *s); + +int shmcon_set_child(uint64_t phys_address, uint32_t num); + +#endif /* __DRIVERS_SHMCON_H */ diff --git a/include/drivers/spi.h b/include/drivers/spi.h new file mode 100644 index 0000000..697cc5f --- /dev/null +++ b/include/drivers/spi.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_SPI_H +#define __DRIVERS_SPI_H + +#include + +__BEGIN_DECLS + +void spi_setup(int port, int baud, int width, bool master, int clkpol, int clkpha); +int spi_write_etc(int port, const void *buf, size_t len, bool wait, bool with_rx); +int spi_read_etc(int port, void *buf, size_t len, bool wait, bool with_tx); +void spi_select(int port, bool select_state); + +void spi_init(void); + +u_int32_t spi_gpio_read(int port); +void spi_gpio_write(int port, u_int32_t val); +void spi_gpio_configure(int port, u_int32_t config); + +__END_DECLS + +#endif /* __DRIVERS_SPI_H */ diff --git a/include/drivers/sw_h2fmi.h b/include/drivers/sw_h2fmi.h new file mode 100644 index 0000000..c5b795e --- /dev/null +++ b/include/drivers/sw_h2fmi.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_SW_H2FMI_H +#define __DRIVERS_SW_H2FMI_H + +#include +#include + +__BEGIN_DECLS + +int sw_h2fmi_init(void); + +__END_DECLS + +#endif /* __DRIVERS_SW_H2FMI_H */ diff --git a/include/drivers/thermal.h b/include/drivers/thermal.h new file mode 100644 index 0000000..68bdc90 --- /dev/null +++ b/include/drivers/thermal.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_THERMAL_H +#define __DRIVERS_THERMAL_H + +#include + +__BEGIN_DECLS + +/* + * Thermal management. + * + * Thermal status is reported via the following nodes in the MIB: + * + * Thermal.Temperature unit current temperature in degrees Celsius. + * Thermal.Fanspeed current fan speed + */ + +/* + * thermal_init + * + * Initialise the thermal management system. + * + * If the default target is passed as 0, it is assumed the system already + * knows the default. + */ +int thermal_init(u_int32_t default_target); + +/* + * thermal_set_target_temperature + * + * Set the target temperature to be maintained by the thermal system in degrees Celsius. + */ +int thermal_set_target_temperature(u_int32_t temperature); + +/* + * thermal_soft_regulation_fail + * + * Called when the system is no longer able to provide services that may be required + * to perform soft thermal regulation, e.g. during a panic. This allows a soft + * regulation algorithm to e.g. set the cooling system to maximum, as long as care is + * taken. + */ +void thermal_soft_regulation_fail(void); + +__END_DECLS + +#endif /* __DRIVERS_THERMAL_H */ diff --git a/include/drivers/thunderbolt/nhi.h b/include/drivers/thunderbolt/nhi.h new file mode 100644 index 0000000..b794e69 --- /dev/null +++ b/include/drivers/thunderbolt/nhi.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef THUNDERBOLT_NHI_H +#define THUNDERBOLT_NHI_H + +#include +#include + +#define NHI_STATUS_OK (0) +#define NHI_STATUS_UNKNOWN_ERROR (-1) +#define NHI_STATUS_CRC_ERROR (-2) +#define NHI_STATUS_INVALID_DESCRIPTOR (-3) +#define NHI_STATUS_TIMEOUT (-4) + +typedef struct nhi_sgl { + void *buffer; + uint32_t bytes; + struct nhi_sgl *next; +} nhi_sgl_t; + +typedef struct nhi nhi_t; + +nhi_t *nhi_init(pci_device_t bridge, uint32_t dart_id); +void nhi_quiesce_and_free(nhi_t *nhi); +void nhi_init_tx_ring(nhi_t *nhi, uint32_t ring_idx, uint32_t num_buffers, uint32_t buffer_size); +void nhi_init_rx_ring(nhi_t *nhi, uint32_t ring_idx, uint32_t num_buffers, uint32_t buffer_size); +void nhi_disable_tx_ring(nhi_t *nhi, uint32_t ring_idx); +void nhi_disable_rx_ring(nhi_t *nhi, uint32_t ring_idx); +int32_t nhi_send_sgl(nhi_t *nhi, uint32_t ring_idx, const nhi_sgl_t *sgl, uint8_t sof_pdf, uint8_t eof_pdf); +int32_t nhi_send_buffer(nhi_t *nhi, uint32_t ring_idx, void *buffer, uint32_t bytes, uint8_t sof_pdf, uint8_t eof_pdf); +bool nhi_rx_buffer_available(nhi_t *nhi, uint32_t ring_idx); +int32_t nhi_rx_buffer(nhi_t *nhi, uint32_t ring_idx, void *buffer, uint32_t bytes, uint8_t *sof_pdf, uint8_t *eof_pdf); + +#endif diff --git a/include/drivers/thunderbolt/thunderboot.h b/include/drivers/thunderbolt/thunderboot.h new file mode 100644 index 0000000..075017a --- /dev/null +++ b/include/drivers/thunderbolt/thunderboot.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef THUNDERBOOT_H +#define THUNDERBOOT_H + +#include + +typedef struct thunderboot thunderboot_t; + +thunderboot_t * thunderboot_init(pci_device_t bridge, uint32_t dart_id); +void thunderboot_quiesce_and_free(thunderboot_t *tb); + +int thunderboot_get_dfu_image(void *load_address, int load_length); + +void thunderboot_putchar(int c); + +int thunderboot_serial_send_cmd_string(u_int8_t *buffer, u_int32_t len); +void thunderboot_transfer_prepare(void *load_address, uint32_t length); +int thunderboot_transfer_wait(void); + +#endif diff --git a/include/drivers/tristar.h b/include/drivers/tristar.h new file mode 100644 index 0000000..7a85108 --- /dev/null +++ b/include/drivers/tristar.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_TRISTAR_H +#define __DRIVERS_TRISTAR_H + +#include + +__BEGIN_DECLS + +bool tristar_set_usb_brick_detect(int select); +bool tristar_read_id(uint8_t digital_id[6]); +bool tristar_enable_acc_pwr(bool enabled); + +__END_DECLS + +#endif /* __DRIVERS_CHARGER_H */ + diff --git a/include/drivers/uart.h b/include/drivers/uart.h new file mode 100644 index 0000000..4ffac78 --- /dev/null +++ b/include/drivers/uart.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __DRIVERS_UART_H +#define __DRIVERS_UART_H + +#include + +__BEGIN_DECLS + +/* + * High-level UART interface. + */ +int uart_init(void); + +int uart_getc(int port, bool wait); +int uart_puts(int port, const char *s); +int uart_putc(int port, char c); + +int uart_send_break(int port, bool enable); + +/* + * Low-level UART primitives required by the drivers/uart module. + */ +enum uart_parity { + PARITY_NONE, + PARITY_ODD, + PARITY_EVEN +}; +int uart_hw_init(u_int32_t port, u_int32_t baudrate); +int uart_hw_getc(u_int32_t port); +int uart_hw_putc(u_int32_t port, char c); + +/* optional, backdoor for tweaking UART config */ +int uart_hw_init_extended(u_int32_t port, u_int32_t baudrate, u_int32_t databits, + enum uart_parity parity, u_int32_t stopbits); +/* set interrupt mode on/off, explicit buffer size */ +int uart_hw_set_rx_buf(u_int32_t port, bool interrupt, size_t buffer_len); + +__END_DECLS + +#endif /* __DRIVERS_UART_H */ diff --git a/include/drivers/usb/synopsys_otg_public.h b/include/drivers/usb/synopsys_otg_public.h new file mode 100644 index 0000000..3b80adf --- /dev/null +++ b/include/drivers/usb/synopsys_otg_public.h @@ -0,0 +1,95 @@ +#ifndef _SYNOPSYS_OTG_PUBLIC_H_ +#define _SYNOPSYS_OTG_PUBLIC_H_ + +#include +#include + +__BEGIN_DECLS + +//=================================================================================== +// Enums, structs and Typedefs +//=================================================================================== +enum +{ + USB_IO_ERROR = -1, + USB_IO_SUCCESS = 0, + USB_IO_ABORTED +}; + +enum +{ + CABLE_CONNECTED = 0, + CABLE_DISCONNECTED, + USB_RESET, + USB_ENUM_DONE +}; + +enum { + CONNECTION_SPEED_FULL = 0, + CONNECTION_SPEED_HIGH +}; + +struct usb_device_io_request +{ + u_int32_t endpoint; + volatile u_int8_t *io_buffer; + int status; + int io_length; + int return_count; + void (*callback) (struct usb_device_io_request *io_request); + struct usb_device_io_request *next; +}; + +struct usb_endpoint_instance +{ + int endpoint_address; + int max_packet_size; + int attributes; + int bInterval; + + int transfer_size; + int packet_count; + + struct usb_endpoint_instance *next_ep; + + struct usb_device_io_request *io_head; + struct usb_device_io_request *io_tail; + + int tx_fifo_number; +}; + +struct usb_controller_ops +{ + void (*start) (void); + void (*stop) (void); + void (*set_address) (int new_address); + void (*stall_endpoint) (u_int32_t endpoint, bool stall); + void (*reset_endpoint_data_toggle) (u_int32_t endpoint); + bool (*is_endpoint_stalled) (u_int32_t endpoint); + void (*do_endpoint_io) (struct usb_device_io_request *req); + void (*activate_endpoint) (u_int32_t endpoint, int type, int max_packet_size, int interval); + void (*deactivate_endpoint) (u_int32_t endpoint); + void (*abort_endpoint) (u_int32_t endpoint); + void (*do_test_mode)(int test_selector); + int (*get_connection_speed) (void); +}; + +struct usb_interface_instance +{ + int (*interface_request_handler) (struct usb_device_request *request, u_int8_t ** out_data); + void (*non_setup_data_phase_finished_callback) (int data_rcvd); + void (*activate_interface) (void); + void (*bus_reset_handler) (void); + int (*get_interface_handler) (void); + int (*set_interface_handler) (int alt_setting); +}; + +//=================================================================================== +// Global APIs +//=================================================================================== + +void usb_init (void); + +__END_DECLS + +#endif diff --git a/include/drivers/usb/usb_chap9.h b/include/drivers/usb/usb_chap9.h new file mode 100644 index 0000000..2449ac0 --- /dev/null +++ b/include/drivers/usb/usb_chap9.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef _USB_CHAP9_H_ +#define _USB_CHAP9_H_ + +#include + +//==================================================================== +// USB Descriptor Types +//==================================================================== +#define USB_DT_DEVICE 1 +#define USB_DT_CONFIGURATION 2 +#define USB_DT_STRING 3 +#define USB_DT_INTERFACE 4 +#define USB_DT_ENDPOINT 5 +#define USB_DT_DEVICE_QUALIFIER 6 +#define USB_DT_OTHER_SPEED_CONFIGURATION 7 + +//==================================================================== +// USB Endpoints Types +//==================================================================== +#define USB_ENDPOINT_CONTROL 0x00 +#define USB_ENDPOINT_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_BULK 0x02 +#define USB_ENDPOINT_INTERRUPT 0x03 + +//==================================================================== +// USB Standard Request Types +//==================================================================== +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B + +//==================================================================== +// USB Feature Types +//==================================================================== +#define USB_FEATURE_ENDPOINT_HALT 0x00 +#define USB_FEATURE_REMOTE_WAKEUP 0x01 +#define USB_FEATURE_TEST_MODE 0x02 + +//==================================================================== +// USB Device Request Types +//==================================================================== +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 + +//==================================================================== +// USB Class Codes +//==================================================================== +#define USB_CLASS_INTERFACE_SPECIFIC 0 +#define USB_CLASS_VENDOR_SPECIFIC 0xff + +//==================================================================== +// USB Chap9 specific consts +//==================================================================== +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIGURATION_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_DEVICE_QUALIFIER_SIZE 10 +#define USB_DT_STRING_SIZE 6 + +#define USB_DIR_OUT 0 +#define USB_DIR_IN 0x80 + +#define USB_ENDPOINT_MASK 0x03 +#define USB_ENDPOINT_NUMBER_MASK 0x0f +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_BCD_VERSION 0x0200 + +#define USB_REQ_DIRECTION_MASK 0x80 +#define USB_REQ_TYPE_MASK 0x60 +#define USB_REQ_RECIPIENT_MASK 0x1f + +#define USB_REQ_DEVICE2HOST 0x80 +#define USB_REQ_HOST2DEVICE 0x00 + +#define USB_REQ_RECIPIENT_DEVICE 0x00 +#define USB_REQ_RECIPIENT_INTERFACE 0x01 +#define USB_REQ_RECIPIENT_ENDPOINT 0x02 +#define USB_REQ_RECIPIENT_OTHER 0x03 + +#define SETUP_PACKET_LEN 0x8 + +#define EP0_IN 0x80 +#define EP0_OUT 0x0 +//==================================================================== +// Enums, structs and typedefs +//==================================================================== +struct usb_device_request +{ + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; +} __attribute__((packed)); + +struct usb_device_descriptor +{ + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int16_t bcdUSB; + u_int8_t bDeviceClass; + u_int8_t bDeviceSubClass; + u_int8_t bDeviceProtocol; + u_int8_t bMaxPacketSize0; + u_int16_t idVendor; + u_int16_t idProduct; + u_int16_t bcdDevice; + u_int8_t iManufacturer; + u_int8_t iProduct; + u_int8_t iSerialNumber; + u_int8_t bNumConfigurations; +} __attribute__((packed)); + +struct usb_configuration_descriptor +{ + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int16_t wTotalLength; + u_int8_t bNumInterfaces; + u_int8_t bConfigurationValue; + u_int8_t iConfiguration; + u_int8_t bmAttributes; + u_int8_t bMaxPower; +} __attribute__((packed)); + +struct usb_interface_descriptor +{ + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int8_t bInterfaceNumber; + u_int8_t bAlternateSetting; + u_int8_t bNumEndpoints; + u_int8_t bInterfaceClass; + u_int8_t bInterfaceSubClass; + u_int8_t bInterfaceProtocol; + u_int8_t iInterface; +} __attribute__((packed)); + +struct usb_endpoint_descriptor +{ + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int8_t bEndpointAddress; + u_int8_t bmAttributes; + u_int16_t wMaxPacketSize; + u_int8_t bInterval; +} __attribute__((packed)); + +struct usb_string_descriptor +{ + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int8_t wData[2]; +} __attribute__((packed)); + +struct usb_device_qualifier_descriptor +{ + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int16_t bcdUSB; + u_int8_t bDeviceClass; + u_int8_t bDeviceSubClass; + u_int8_t bDeviceProtocol; + u_int8_t bMaxPacketSize0; + u_int8_t bNumConfigurations; + u_int8_t bReserved; +} __attribute__((packed)); + +enum +{ + DEVICE_ST_UNKNOWN = -1, + DEVICE_ST_INIT = 0, + DEVICE_ST_ATTACHED, + DEVICE_ST_POWERED, + DEVICE_ST_DEFAULT, + DEVICE_ST_ADDRESSED, + DEVICE_ST_CONFIGURED, + DEVICE_ST_SUSPENDED +}; + +//==================================================================== +// USB driver specific consts +//==================================================================== +#define EP0_MAX_PACKET_SIZE 0x40 +#define HS_BULK_EP_MAX_PACKET_SIZE 0x200 +#define HS_INT_EP_MAX_PACKET_SIZE 0x40 +#define FS_EP_MAX_PACKET_SIZE 0x40 + +#endif // _USB_CHAP9_H_ + + diff --git a/include/drivers/usb/usb_controller.h b/include/drivers/usb/usb_controller.h new file mode 100644 index 0000000..66026d4 --- /dev/null +++ b/include/drivers/usb/usb_controller.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef _USB_CONTROLLER_H_ +#define _USB_CONTROLLER_H_ + +#include +#include + +__BEGIN_DECLS + +#define MAX_SUPPORTED_USB_CONTROLLER (2) + +typedef enum { + USB_CONTROLLER_synopsys_otg, + USB_CONTROLLER_dbgfifo, +} USB_CONTROLLER_T; + +struct usb_controller_functions { + int (*init)(void); + void (*free_func)(void); + int (*start)(void); + void (*stop)(void); + void (*set_address)(uint32_t new_address); + int (*get_connection_speed)(void); + void (*activate_endpoint)(uint32_t endpoint, int type, int max_packet_size, int interval); + void (*do_endpoint_io)(struct usb_device_io_request *req); + void (*stall_endpoint)(uint32_t endpoint, bool stall); + void (*reset_endpoint_data_toggle)(uint32_t endpoint); + bool (*is_endpoint_stalled)(uint32_t endpoint); + void (*do_test_mode)(uint32_t selector); + void (*abort_endpoint)(uint32_t endpoint); + void (*deactivate_endpoint)(uint32_t endpoint); +}; + +int usb_controller_register(const struct usb_controller_functions *controller_functions); +int usb_controller_init(void); +void usb_controller_free(void); +int usb_controller_start(void); +void usb_controller_stop(void); +void usb_controller_set_address(u_int32_t new_address); +int usb_controller_get_connection_speed(void); +void usb_controller_activate_endpoint(u_int32_t endpoint, int type, int max_packet_size, int interval); +void usb_controller_do_endpoint_io(struct usb_device_io_request *req); +void usb_controller_stall_endpoint(u_int32_t endpoint, bool stall); +void usb_controller_reset_endpoint_data_toggle(u_int32_t endpoint); +bool usb_controller_is_endpoint_stalled(u_int32_t endpoint); +void usb_controller_do_test_mode(u_int32_t selector); +void usb_controller_abort_endpoint(u_int32_t endpoint); +void usb_controller_deactivate_endpoint(u_int32_t endpoint); + +__END_DECLS + +#endif // _USB_CONTROLLER_H_ diff --git a/include/drivers/usb/usb_core.h b/include/drivers/usb/usb_core.h new file mode 100644 index 0000000..5c1475c --- /dev/null +++ b/include/drivers/usb/usb_core.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef _USB_CORE_H_ +#define _USB_CORE_H_ + +#include +#include + +__BEGIN_DECLS + +//=================================================================================== +// consts and macros +//=================================================================================== + +#define APPLE_USB_DFU_INTF 0 +#define APPLE_USB_TRNSFR_INTF APPLE_USB_DFU_INTF +#define APPLE_USB_SERIAL_INTF 0x1 + +#define APPLE_USB_SERIAL_CONFIG_STRING_IDX 4 +#define APPLE_USB_SERIAL_INTF_STRING_INDEX 5 + +#define APPLE_USB_SERIAL_EP_BULK_IN 0x81 +#define APPLE_USB_SERIAL_EP_BULK_OUT 0x2 +#define APPLE_USB_TRNSFR_EP_BULK_OUT 0x4 +#define APPLE_USB_TRNSFR_EP_BULK_IN 0x85 + +#define APPLE_USB_DFU_TOTAL_INTFS 1 +#define APPLE_USB_DFU_CLASS 0xfe +#define APPLE_USB_DFU_SUBCLASS 0x1 +#define APPLE_USB_DFU_PROTOCOL 0x0 + +#define APPLE_USB_SERIAL_TOTAL_EPS 2 +#define APPLE_USB_SERIAL_TOTAL_INTFS 2 +#define APPLE_USB_SERIAL_CLASS 0xff +#define APPLE_USB_SERIAL_SUBCLASS 0xff +#define APPLE_USB_SERIAL_PROTOCOL 0x51 + +#if WITH_BULK_UPLOAD +#define APPLE_USB_TRNSFR_TOTAL_EPS 2 +#else +#define APPLE_USB_TRNSFR_TOTAL_EPS 1 +#endif + +#define APPLE_USB_TRNSFR_TOTAL_INTFS 1 +#define APPLE_USB_DFU_TRNSFR_CLASS 0xfe +#define APPLE_USB_DFU_TRNSFR_SUBCLASS 0x1 +#define APPLE_USB_DFU_TRNSFR_PROTOCOL 0x2 +#define APPLE_USB_TRNSFR_CLASS APPLE_USB_DFU_TRNSFR_CLASS +#define APPLE_USB_TRNSFR_SUBCLASS APPLE_USB_DFU_TRNSFR_SUBCLASS +#define APPLE_USB_TRNSFR_PROTOCOL APPLE_USB_DFU_TRNSFR_PROTOCOL + +//=================================================================================== +// Enums, structs and Typedefs +//=================================================================================== + +enum +{ + USB_IO_ERROR = -1, + USB_IO_SUCCESS = 0, + USB_IO_ABORTED +}; + +enum +{ + CABLE_CONNECTED = 0, + CABLE_DISCONNECTED, + USB_RESET, + USB_ENUM_DONE +}; + +enum { + CONNECTION_SPEED_FULL = 0, + CONNECTION_SPEED_HIGH +}; + +#if WITH_RECOVERY_MODE +enum { + PR_RESET_REQUEST = 0, // put device into reset state before starting restore with bulk blaster protocol + PR_VENDOR_REQUEST = 0, + PR_VENDOR_BLIND_REQUEST // return success on usb before executing the command, primarily for fsboot or reboot +}; +#endif + +struct usb_device_io_request +{ + u_int32_t endpoint; + volatile u_int8_t *io_buffer; + int status; + u_int32_t io_length; + u_int32_t return_count; + void (*callback) (struct usb_device_io_request *io_request); + struct usb_device_io_request *next; +}; + +struct usb_interface_instance +{ + int total_interfaces; + struct usb_interface_descriptor *interface_descs; + int total_other_descs; + void *other_descs; + int total_endpoints; + struct usb_endpoint_descriptor *endpoint_descs; + int total_string_descs; + char **string_descs; + + int (*handle_request) (struct usb_device_request *request, u_int8_t ** out_data); + void (*non_setup_data_phase_finished_callback) (u_int32_t data_rcvd); + void (*activate_interface) (void); + void (*deactivate_interface) (void); + void (*activate_endpoints) (void); + void (*deactivate_endpoints) (void); + void (*handle_bus_reset) (void); + int (*handle_get_interface) (void); + int (*handle_set_interface) (int alt_setting); + int (*handle_vendor_request) (struct usb_device_request *request); +}; + +//=================================================================================== +// Global APIs +//=================================================================================== + +int usb_core_init (const char *config_desc_string); +void usb_core_free (void); +int usb_core_start(); +void usb_core_stop(); +void usb_core_handle_usb_control_receive (u_int8_t *ep0_rx_buffer, bool is_setup, int receive_length, bool *data_phase); +void usb_core_register_interface (struct usb_interface_instance *if_ops); +void usb_core_event_handler (int event); +void usb_core_do_transfer (int endpoint, u_int8_t *buffer, int length, void (*callback)(struct usb_device_io_request *)); +void usb_core_send_zlp (void); +void usb_core_complete_endpoint_io (struct usb_device_io_request *req); +void usb_core_activate_endpoint (u_int32_t endpoint, int type, int max_packet_size, int interval); +void usb_core_deactivate_endpoint (u_int32_t endpoint); +void usb_core_abort_endpoint (int endpoint); +bool usb_core_get_connection_speed (void); +bool usb_core_get_cable_state (void); + +__END_DECLS + +#endif diff --git a/include/drivers/usb/usb_debug.h b/include/drivers/usb/usb_debug.h new file mode 100644 index 0000000..7029075 --- /dev/null +++ b/include/drivers/usb/usb_debug.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +int usb_send_data_to_file(const char *filename, size_t amount, uintptr_t address, int printCompletionStatus); + diff --git a/include/drivers/usb/usb_public.h b/include/drivers/usb/usb_public.h new file mode 100644 index 0000000..3ba0615 --- /dev/null +++ b/include/drivers/usb/usb_public.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef _USB_PUBLIC_H_ +#define _USB_PUBLIC_H_ + +#include + +__BEGIN_DECLS + +enum { + USB_TRANSFER_TYPE_DFU_GET, + USB_TRANSFER_TYPE_DFU_PUT, + USB_TRANSFER_TYPE_BULK_GET, + USB_TRANSFER_TYPE_BULK_PUT +}; + +//=================================================================================== +// Global APIs +//=================================================================================== + +int usb_early_init(); +int usb_init_with_controller(struct usb_controller_functions *controller_funcs); +int usb_init(); +void usb_quiesce(void); + +int getDFUImage(void* buffer, int len); +int usb_dfu_init(void); +void usb_dfu_exit(void); + +int usb_transfer_init(void); +void usb_transfer_exit(void); +void usb_transfer_prepare(int type, void *address, u_int32_t maxlen); +u_int32_t usb_transfer_start(); + +int usb_serial_early_init(void); +int usb_serial_init(void); +void usb_serial_exit(void); +void usb_serial_putchar(int); +int usb_serial_send_cmd_string(u_int8_t *buffer, u_int32_t len); +bool usb_serial_is_active(); + +__END_DECLS + +#endif diff --git a/include/drivers/usbphy.h b/include/drivers/usbphy.h new file mode 100644 index 0000000..71cb928 --- /dev/null +++ b/include/drivers/usbphy.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#ifndef __DRIVERS_USBPHY_H +#define __DRIVERS_USBPHY_H + +#include + +#if WITH_DEVICETREE +#include +#endif + +__BEGIN_DECLS + +void usbphy_power_up(void); +void usbphy_enable_pullup(void); +void usbphy_power_down(void); +bool usbphy_is_cable_connected(void); +bool usbphy_set_dpdm_monitor(int select); +#if WITH_CONJOINED_USB_PHYS +void usbphy_select_phy(int index); +#endif + +#if WITH_DEVICETREE +extern void usbphy_update_device_tree(DTNode *pmgr_node); +#endif + +__END_DECLS + + +#endif + diff --git a/include/drivers/wpc.h b/include/drivers/wpc.h new file mode 100644 index 0000000..217e4da --- /dev/null +++ b/include/drivers/wpc.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DRIVERS_WPC_H +#define __DRIVERS_WPC_H + +#include + +__BEGIN_DECLS + +void wpc_init(uint32_t display_width, uint32_t display_height); +void wpc_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl); + +__END_DECLS + +#endif /* __DRIVERS_WPC_H */ \ No newline at end of file diff --git a/include/endian_tools.h b/include/endian_tools.h new file mode 100644 index 0000000..22ad507 --- /dev/null +++ b/include/endian_tools.h @@ -0,0 +1,51 @@ +#ifndef ENDIAN_TOOLS_H +#define ENDIAN_TOOLS_H 1 + +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +static inline uint16_t read_le_16(const void *buf, size_t offset) +{ + const uint8_t *p = (const uint8_t *) buf + offset; + return + (((uint16_t) p[0]) << 0) | + (((uint16_t) p[1]) << 8); +} + +static inline uint32_t read_le_32(const void *buf, size_t offset) +{ + const uint8_t *p = (const uint8_t *) buf + offset; + return + (((uint32_t) p[0]) << 0) | + (((uint32_t) p[1]) << 8) | + (((uint32_t) p[2]) << 16) | + (((uint32_t) p[3]) << 24); +} + +static inline void write_le_16(void *buf, size_t offset, uint16_t value) +{ + uint8_t *p = (uint8_t *) buf + offset; + p[0] = (value >> 0) & 0xff; + p[1] = (value >> 8) & 0xff; +} + +static inline void write_le_32(void *buf, size_t offset, uint32_t value) +{ + uint8_t *p = (uint8_t *) buf + offset; + p[0] = (value >> 0) & 0xff; + p[1] = (value >> 8) & 0xff; + p[2] = (value >> 16) & 0xff; + p[3] = (value >> 24) & 0xff; +} + +#endif // defined(ENDIAN_TOOLS_H) diff --git a/include/gcc/limits.h b/include/gcc/limits.h new file mode 100644 index 0000000..4091e81 --- /dev/null +++ b/include/gcc/limits.h @@ -0,0 +1,120 @@ +/* This administrivia gets added to the beginning of limits.h + if the system has its own version of limits.h. */ + +/* APPLE LOCAL begin 4401222 */ +#ifndef _LIBC_LIMITS_H_ +/* Use "..." so that we find syslimits.h only in this same directory. */ +#include "syslimits.h" +#endif +/* +#ifdef _GCC_NEXT_LIMITS_H +#include_next +#undef _GCC_NEXT_LIMITS_H +#endif + */ +/* APPLE LOCAL end 4401222 */ +#ifndef _LIMITS_H___ +#define _LIMITS_H___ + +/* Number of bits in a `char'. */ +#undef CHAR_BIT +#define CHAR_BIT __CHAR_BIT__ + +/* Maximum length of a multibyte character. */ +#ifndef MB_LEN_MAX +#define MB_LEN_MAX 1 +#endif + +/* Minimum and maximum values a `signed char' can hold. */ +#undef SCHAR_MIN +#define SCHAR_MIN (-SCHAR_MAX - 1) +#undef SCHAR_MAX +#define SCHAR_MAX __SCHAR_MAX__ + +/* Maximum value an `unsigned char' can hold. (Minimum is 0). */ +#undef UCHAR_MAX +#if __SCHAR_MAX__ == __INT_MAX__ +# define UCHAR_MAX (SCHAR_MAX * 2U + 1U) +#else +# define UCHAR_MAX (SCHAR_MAX * 2 + 1) +#endif + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +# undef CHAR_MIN +# if __SCHAR_MAX__ == __INT_MAX__ +# define CHAR_MIN 0U +# else +# define CHAR_MIN 0 +# endif +# undef CHAR_MAX +# define CHAR_MAX UCHAR_MAX +#else +# undef CHAR_MIN +# define CHAR_MIN SCHAR_MIN +# undef CHAR_MAX +# define CHAR_MAX SCHAR_MAX +#endif + +/* Minimum and maximum values a `signed short int' can hold. */ +#undef SHRT_MIN +#define SHRT_MIN (-SHRT_MAX - 1) +#undef SHRT_MAX +#define SHRT_MAX __SHRT_MAX__ + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0). */ +#undef USHRT_MAX +#if __SHRT_MAX__ == __INT_MAX__ +# define USHRT_MAX (SHRT_MAX * 2U + 1U) +#else +# define USHRT_MAX (SHRT_MAX * 2 + 1) +#endif + +/* Minimum and maximum values a `signed int' can hold. */ +#undef INT_MIN +#define INT_MIN (-INT_MAX - 1) +#undef INT_MAX +#define INT_MAX __INT_MAX__ + +/* Maximum value an `unsigned int' can hold. (Minimum is 0). */ +#undef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1U) + +/* Minimum and maximum values a `signed long int' can hold. + (Same as `int'). */ +#undef LONG_MIN +#define LONG_MIN (-LONG_MAX - 1L) +#undef LONG_MAX +#define LONG_MAX __LONG_MAX__ + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ +#undef ULONG_MAX +#define ULONG_MAX (LONG_MAX * 2UL + 1UL) + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +/* Minimum and maximum values a `signed long long int' can hold. */ +# undef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - 1LL) +# undef LLONG_MAX +# define LLONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +# undef ULLONG_MAX +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +#endif + +#if defined (__GNU_LIBRARY__) ? defined (__USE_GNU) : !defined (__STRICT_ANSI__) +/* Minimum and maximum values a `signed long long int' can hold. */ +# undef LONG_LONG_MIN +# define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL) +# undef LONG_LONG_MAX +# define LONG_LONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +# undef ULONG_LONG_MAX +# define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1ULL) +#endif + +#endif /* _LIMITS_H___ */ +/* APPLE LOCAL begin 4401222 */ +/* APPLE LOCAL end 4401222 */ diff --git a/include/gcc/stdarg.h b/include/gcc/stdarg.h new file mode 100644 index 0000000..f178505 --- /dev/null +++ b/include/gcc/stdarg.h @@ -0,0 +1,133 @@ +/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 7.15 Variable arguments + */ + +#ifndef _STDARG_H +#ifndef _ANSI_STDARG_H_ +#ifndef __need___va_list +#define _STDARG_H +#define _ANSI_STDARG_H_ +#endif /* not __need___va_list */ +#undef __need___va_list + +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST +typedef __builtin_va_list __gnuc_va_list; +#endif + +/* Define the standard macros for the user, + if this invocation was from the user program. */ +#ifdef _STDARG_H + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L +#define va_copy(d,s) __builtin_va_copy(d,s) +#endif +#define __va_copy(d,s) __builtin_va_copy(d,s) + +/* Define va_list, if desired, from __gnuc_va_list. */ +/* We deliberately do not define va_list when called from + stdio.h, because ANSI C says that stdio.h is not supposed to define + va_list. stdio.h needs to have access to that data type, + but must not use that name. It should use the name __gnuc_va_list, + which is safe because it is reserved for the implementation. */ + +#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */ +#undef _VA_LIST +#endif + +#ifdef _BSD_VA_LIST +#undef _BSD_VA_LIST +#endif + +#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST)) +/* SVR4.2 uses _VA_LIST for an internal alias for va_list, + so we must avoid testing it and setting it here. + SVR4 uses _VA_LIST as a flag in stdarg.h, but we should + have no conflict with that. */ +#ifndef _VA_LIST_ +#define _VA_LIST_ +#ifdef __i860__ +#ifndef _VA_LIST +#define _VA_LIST va_list +#endif +#endif /* __i860__ */ +typedef __gnuc_va_list va_list; +#ifdef _SCO_DS +#define __VA_LIST +#endif +#endif /* _VA_LIST_ */ +#else /* not __svr4__ || _SCO_DS */ + +/* The macro _VA_LIST_ is the same thing used by this file in Ultrix. + But on BSD NET2 we must not test or define or undef it. + (Note that the comments in NET 2's ansi.h + are incorrect for _VA_LIST_--see stdio.h!) */ +#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) +/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ +#ifndef _VA_LIST_DEFINED +/* The macro _VA_LIST is used in SCO Unix 3.2. */ +#ifndef _VA_LIST +/* The macro _VA_LIST_T_H is used in the Bull dpx2 */ +#ifndef _VA_LIST_T_H +/* The macro __va_list__ is used by BeOS. */ +#ifndef __va_list__ +typedef __gnuc_va_list va_list; +#endif /* not __va_list__ */ +#endif /* not _VA_LIST_T_H */ +#endif /* not _VA_LIST */ +#endif /* not _VA_LIST_DEFINED */ +#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) +#define _VA_LIST_ +#endif +#ifndef _VA_LIST +#define _VA_LIST +#endif +#ifndef _VA_LIST_DEFINED +#define _VA_LIST_DEFINED +#endif +#ifndef _VA_LIST_T_H +#define _VA_LIST_T_H +#endif +#ifndef __va_list__ +#define __va_list__ +#endif + +#endif /* not _VA_LIST_, except on certain systems */ + +#endif /* not __svr4__ */ + +#endif /* _STDARG_H */ + +#endif /* not _ANSI_STDARG_H_ */ +#endif /* not _STDARG_H */ diff --git a/include/gcc/syslimits.h b/include/gcc/syslimits.h new file mode 100644 index 0000000..a449979 --- /dev/null +++ b/include/gcc/syslimits.h @@ -0,0 +1,8 @@ +/* syslimits.h stands for the system's own limits.h file. + If we can use it ok unmodified, then we install this text. + If fixincludes fixes it, then the fixed version is installed + instead of this text. */ + +#define _GCC_NEXT_LIMITS_H /* tell gcc's limits.h to recurse */ +/* APPLE LOCAL begin 4401222 */ +/* APPLE LOCAL end 4401222 */ diff --git a/include/lib/DERApTicket.h b/include/lib/DERApTicket.h new file mode 100644 index 0000000..c6da436 --- /dev/null +++ b/include/lib/DERApTicket.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef DERAPTICKET_H +#define DERAPTICKET_H + +#include +#include + +/* AP Ticket */ +typedef struct { + DERItem signatureAlgorithm; /* AlgorithmId */ + DERItem body; /* SET OF OCTECT STRING, DER_DEC_SAVE_DER */ + DERItem signature; /* OCTET STRING */ + DERItem certificates; /* SEQUENCE of CERTIFICATE */ +} DERApTicket; + +/* Cert extension */ +typedef struct { + DERItem version; /* current version is 0; omitted until version 1 */ + DERItem override; + DERItem append; /* optional; unsupported in version 0 */ + DERItem remove; /* optional; unsupported in version 0 */ +} DERApTicketCertExtension; + +/* DERItemSpecs to decode into a DERApTicket */ +extern const DERItemSpec DERApTicketItemSpecs[]; +extern const DERSize DERNumApTicketItemSpecs; + +DERReturn +DERApTicketCopyTagData( + const DERItem *container, + DERTag tag, + uint8_t *buffer, + DERSize *ioLength ); + +DERReturn +DERApTicketDecode( + const DERItem * contents, + DERApTicket * outTicket, + DERSize * outNumUsedBytes ); + +DERReturn +DERApTicketValidate( + const DERApTicket *ticket, + bool isRestore ); + +DERReturn +DERApTicketParseLengthFromBuffer( + const uint8_t * buffer, + size_t length, + size_t * outTicketLength ); + +#endif /* DERAPTICKET_H */ diff --git a/include/lib/Image2Format.h b/include/lib/Image2Format.h new file mode 100644 index 0000000..a554dd3 --- /dev/null +++ b/include/lib/Image2Format.h @@ -0,0 +1,111 @@ +/* + * Image2 on-media format. + * + * The I2 layout is described by the I2 superblock, which is located at + * kI2SuperblockOffset from the top of the media. The superblock is a write-once + * item; it should only be updated when the bootblock code is rewritten, implying + * a complete re-initialisation of the media. + * + * Following the superblock there is a reserved area for boot code, after which + * image headers describe individual images. + * + * 0 -------------------- + * + * kI2SuperblockOffset Image2Superblock + * + * isImageGranule -------------------- + * bootcode + * + isBootBlockSize -------------------- + * ... + * + isImageOffset Image2Header + * ... + * + */ + +#if !defined (__LIB_IMAGE2FORMAT_H) +#define __LIB_IMAGE2FORMAT_H 1 +#include + +__BEGIN_DECLS + +/* + * XXX 7561698 isImageOffset is documented inconsistently + * and not used as described above. + */ +typedef struct { + u_int32_t isMagic; +#define kImage2SuperMagic 0x494d4732 /* "IMG2" */ + u_int32_t isImageGranule; /* fundamental block size (bytes) */ + u_int32_t isImageOffset; /* image header offset within granule (image granules) */ + u_int32_t isBootBlockSize; /* size of the bootblock (image granules) */ + u_int32_t isImageAvail; /* total granules available for images. */ + u_int32_t isNvramGranule; /* size of NVRAM blocks (bytes) */ + u_int32_t isNvramOffset; /* offset to first NVRAM block (nvram granules) */ + u_int32_t isFlags; /* flags field reserved for future use */ + u_int32_t isRsvd1; /* reserved 1 for future use */ + u_int32_t isRsvd2; /* reserved 2 for future use */ + u_int32_t isRsvd3; /* reserved 3 for future use */ + u_int32_t isRsvd4; /* reserved 4 for future use */ + u_int32_t isCheck; /* CRC-32 of header fields preceding this one */ +} Image2Superblock; + + +/* + * Image types + */ +typedef u_int32_t Image2ImageType; +#define kImage2ImageTypeWildcard 0x2a2a2a2a /* **** */ +#define kImage2ImageTypeIdent 0x49646e74 /* Idnt - ASCII string identifying the image + * collection */ +#define kImage2ImageTypeDTree 0x64747265 /* dtre */ +#define kImage2ImageTypeDiag 0x64696167 /* diag */ +#define kImage2ImageTypeLogo 0x6c6f676f /* logo */ +#define kImage2ImageTypeiBoot 0x69626f74 /* "ibot" => iBoot */ +#define kImage2ImageTypeLLB 0x6c6c627a /* "llbz" => LLB */ +#define kImage2ImageTypeEOT 0x04040404 /* EOT */ + +/* + * On-media image header. + */ +typedef struct { + u_int32_t ihMagic; +#define kImage2ImageMagic 0x496d6732 /* "Img2" */ + Image2ImageType ihType; + u_int16_t ihRevision; + u_int16_t ihSecurityEpoch; /* Image is from this security epoch */ + u_int32_t ihLoadAddress; /* preferred load address */ + u_int32_t ihDataSize; /* payload data size (bytes) */ + u_int32_t ihEncryptedDataSize; /* payload data size after decryption (bytes) */ + u_int32_t ihAllocationSize; /* allocation size including header (granules) */ + u_int32_t ihOptions; +#define kImage2OptionSignatureTypeExternal (1<<0) /* signature present elsewhere */ +#define kImage2OptionSignatureTypeInternalSHA1 (1<<1) /* SHA-1 hash in ihSignatureData */ +#define kImage2OptionSignatureTypeInternalCRC (1<<2) /* CRC-32 in first word of ihSignatureData*/ +#define kImage2OptionsTrustedImage (1<<8) /* Image was written down with trust */ +#define kImage2OptionsEncryptedImage (1<<9) /* Image body is encrypted */ +#define kImage2OptionsInstalledWithSB (1<<24) /* Image was written with secure boot support */ +#define kImage2OptionsExtensionPresent (1<<30) /* Extension header follows this main */ +#define kImage2OptionsImmutable (1<<31) + u_int32_t ihSignatureData[16]; + u_int32_t ihNextSize; /* Size in bytes of the next extension */ +#define kImage2HeaderExtensionMaxSize 128 + u_int32_t ihCheck; /* CRC-32 of the preceeding fields */ +} Image2Header; +#define kImage2HeaderReservation 1024 + +typedef u_int32_t Image2HeaderExtensionType; +#define kImage2HeaderExtensionVersionString 0x76657273 /* "vers" => version string */ + +typedef struct { + u_int32_t iheCheck; /* CRC-32 of the preceeding fields */ + u_int32_t iheNextSize; /* Size in bytes of te next extension */ + Image2HeaderExtensionType iheType; + u_int32_t ihOptions; +/* Extension prese*/ + u_int32_t iheData; /* extension data. This field is not + written, instead the actual data is. */ +} Image2HeaderExtension; + +__END_DECLS + +#endif /* __LIB_IMAGE2FORMAT_H*/ diff --git a/include/lib/blockdev.h b/include/lib/blockdev.h new file mode 100644 index 0000000..b4b6ede --- /dev/null +++ b/include/lib/blockdev.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2006-2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_BLOCKDEV_H +#define __LIB_BLOCKDEV_H + +#include +#include + +__BEGIN_DECLS + +typedef uint32_t block_addr; + +#define BLOCKDEV_FLAG_NEEDS_ERASE (1 << 0) /* writes do not implicitly erase */ +#define BLOCKDEV_FLAG_UPGRADE_PARTITION (1 << 1) + +struct blockdev { + struct blockdev *next; + uint32_t flags; + + /* geometry */ + uint32_t block_size; + uint32_t block_count; + + uint32_t block_shift; /* calculated from the block size (assumes multiple of 2) */ + uint64_t total_len; + + uint32_t alignment; /* required alignment for source/destination buffers in bytes */ + uint32_t alignment_shift; + + /* io hooks */ + int (*read_hook)(struct blockdev *, void *ptr, off_t offset, uint64_t len); // read bytes + int (*read_block_hook)(struct blockdev *, void *ptr, block_addr block, uint32_t count); // read count blocks + int (*write_hook)(struct blockdev *, const void *ptr, off_t offset, uint64_t len); // write bytes + int (*write_block_hook)(struct blockdev *, const void *ptr, block_addr block, uint32_t count); // write count blocks + int (*erase_hook)(struct blockdev *, off_t offset, uint64_t len); + + /* name */ + char name[16]; + + /* write-protected region */ + off_t protect_start; + off_t protect_end; +}; + +struct blockdev *lookup_blockdev(const char *name); +int register_blockdev(struct blockdev *); +struct blockdev *first_blockdev(void); +struct blockdev *next_blockdev(struct blockdev *dev); + +/* fill out a new blockdev structure with geometry data and default hooks */ +int construct_blockdev(struct blockdev *, const char *name, uint64_t len, uint32_t block_size); + +/* user api */ +#define blockdev_read(bdev, ptr, off, len) (bdev)->read_hook((bdev), ptr, off, len) +#define blockdev_read_block(bdev, ptr, block, count) (bdev)->read_block_hook((bdev), ptr, block, count) +#define blockdev_write(bdev, ptr, off, len) blockdev_write_protected((bdev), ptr, off, len) +#define blockdev_write_block(bdev, ptr, block, count) blockdev_write_block_protected((bdev), ptr, block, count) +#define blockdev_erase(bdev, off, len) (bdev)->erase_hook((bdev), off, len) + +int blockdev_compare(struct blockdev *dev, const void *ptr, off_t bdev_offset, uint64_t len); +int blockdev_set_protection(struct blockdev *dev, off_t offset, uint64_t length); +void blockdev_set_buffer_alignment(struct blockdev *dev, uint32_t alignment); +int blockdev_write_protected(struct blockdev *dev, const void *ptr, off_t offset, uint64_t len); +int blockdev_write_block_protected(struct blockdev *dev, const void *ptr, block_addr block, uint32_t count); + +/* a default memory based block device */ +struct blockdev *create_mem_blockdev(const char *name, void *ptr, uint64_t len, uint32_t block_size); + +/* a subdevice device, which lets you access a range of a device as another device */ +struct blockdev *create_subdev_blockdev(const char *name, struct blockdev *parent, off_t off, uint64_t len, uint32_t block_size); + +__END_DECLS + +#endif diff --git a/include/lib/cbuf.h b/include/lib/cbuf.h new file mode 100644 index 0000000..fe71e2e --- /dev/null +++ b/include/lib/cbuf.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_CBUF_H +#define __LIB_CBUF_H + +#include +#include + +__BEGIN_DECLS + +/* circular buffer implementation */ +struct cbuf { + void *buf; + unsigned int head; + unsigned int tail; + size_t has; + size_t len; + uint32_t len_mask; + + /* optional event for locking */ + struct task_event *event; +}; + +/* create a circular buffer, len must be power of 2 */ +struct cbuf *cbuf_create(size_t len, struct task_event *event); // event is optional +void cbuf_destroy(struct cbuf *); + +/* read/write unstructured data */ +ssize_t cbuf_write_raw(struct cbuf *, const void *data, size_t len); +ssize_t cbuf_read_raw(struct cbuf *, void *data, size_t len); + +/* read/write individual chars */ +ssize_t cbuf_write_char(struct cbuf *, char c); +ssize_t cbuf_read_char(struct cbuf *, char *c); + +/* read/write strings */ +ssize_t cbuf_write_string(struct cbuf *, const char *str); +ssize_t cbuf_read_string(struct cbuf *, char *str, size_t maxlen); + +__END_DECLS + +#endif + diff --git a/include/lib/cksum.h b/include/lib/cksum.h new file mode 100644 index 0000000..7b4decd --- /dev/null +++ b/include/lib/cksum.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_CKSUM_H +#define __LIB_CKSUM_H + +#include +#include + +__BEGIN_DECLS + +/* various checksum & crc routines */ + + /* POSIX 1003.2 checksum (same as cksum command) */ +#define INITIAL_CRC (0) +uint32_t crc(const void *buf, size_t len); + + /* same as above, but on a single byte */ +uint32_t crc_byte(uint32_t thecrc, uint32_t byte_val); + + /* adler32 */ +uint32_t adler32(const uint8_t *buf, long len); + + /* crc32 CCITT*/ +uint32_t update_crc32(uint32_t crc, const uint8_t *buf, int len); + +uint32_t crc32(const uint8_t *buf, int len); + +void siphash(uint8_t *out, const uint8_t *in, size_t inlen, const uint8_t *k); +void siphash_aligned(uint64_t *out, const uint64_t *in_aligned, size_t inlen, const uint64_t *k); + +#define SIPHASH_KEY_SIZE (16) +#define SIPHASH_HASH_SIZE (8) + +__END_DECLS + +#endif + diff --git a/include/lib/devicetree.h b/include/lib/devicetree.h new file mode 100644 index 0000000..ed469cf --- /dev/null +++ b/include/lib/devicetree.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _BOOTX_DEVICE_TREE_H_ +#define _BOOTX_DEVICE_TREE_H_ + +#include +#include +#include + +__BEGIN_DECLS + +#define kPropNameLength (32) +#define kPropValueMaxLength (0x100000) +typedef struct DTProperty DTProperty, *DTPropertyPtr; + +int dt_load(void); +int dt_load_file(const char *path); + +extern addr_t gDeviceTreeAddr; +extern size_t gDeviceTreeSize; + +typedef struct dtnode dt_node_t; + +void dt_init(void); +dt_node_t *dt_deserialize(void *dtaddr, size_t dtlength); +void dt_serialize(dt_node_t *dt, void *buffer, size_t bufferlen); +size_t dt_get_size(void); +dt_node_t *dt_get_root(void); +bool dt_find_node(dt_node_t *root, const char *path, dt_node_t **node); +const char *dt_get_node_name(dt_node_t *node); +bool dt_get_prop(dt_node_t *node, char **prop_name, void **prop_data, uint32_t *prop_size); +bool dt_find_prop(dt_node_t *node, const char *prop_name, void **prop_data, uint32_t *prop_size); +bool dt_has_prop(dt_node_t *node, const char *prop_name); +void dt_set_prop(dt_node_t *node, const char *name, const void *data, uint32_t size); +void dt_set_prop_32(dt_node_t *node, const char *name, uint32_t value); +void dt_set_prop_64(dt_node_t *node, const char *name, uint64_t value); +void dt_set_prop_addr(dt_node_t *node, const char *name, uintptr_t value); +void dt_set_prop_str(dt_node_t *node, const char *name, const char *str); +bool dt_remove_prop(dt_node_t *node, const char *name); +bool dt_rename_prop(dt_node_t *node, const char *name, const char *new_name); +void dt_seal(void); +int dt_num_children(dt_node_t *node); + +dt_node_t *dt_get_child(dt_node_t *node, int n); +dt_node_t *dt_get_next(dt_node_t *node); + +// compatibility with legacy code +typedef dt_node_t DTNode; +typedef dt_node_t * DTNodePtr; +#define FindNode dt_find_node +#define FindProperty dt_get_prop + +__END_DECLS + +#endif /* ! _BOOTX_DEVICE_TREE_H_ */ diff --git a/include/lib/env.h b/include/lib/env.h new file mode 100644 index 0000000..54ae4f5 --- /dev/null +++ b/include/lib/env.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_ENV_H +#define __LIB_ENV_H + +#include + +__BEGIN_DECLS + +/* systemwide environment variables */ +struct env_var { + char *str; + size_t u; + + uint32_t flags; +}; + +#define ENV_PERSISTENT 0x1 /* saved with 'saveenv' or not */ +#define ENV_SHADOW 0x2 // hidden from env_get or not + +const char *env_get(const char *name); +size_t env_get_uint(const char *name, size_t default_val); +bool env_get_bool(const char *name, bool default_val); +const struct env_var *env_get_etc(const char *name); + +int env_set(const char *name, const char *val, uint32_t flags); +int env_set_uint(const char *name, size_t val, uint32_t flags); +int env_unset(const char *name); + +/* supplied by code that wants to blacklist environment variables */ +bool env_blacklist(const char *name, bool write); +bool env_blacklist_nvram(const char *name); + +/* used by the nvram system */ +size_t env_serialize(uint8_t *buf, size_t buf_len); +int env_unserialize(const uint8_t *buf, size_t buf_len); + +/* get an ip address from the environment */ +int env_get_ipaddr(const char *name, uint32_t *ip); +int env_get_ethaddr(const char *name, uint8_t ethaddr[6]); + +__END_DECLS + +#endif + diff --git a/include/lib/fs.h b/include/lib/fs.h new file mode 100644 index 0000000..7070482 --- /dev/null +++ b/include/lib/fs.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_FS_H +#define __LIB_FS_H + +#include +#include + +__BEGIN_DECLS + +/* limits */ +#define FS_MAXNAMLEN 255 /* maximum component name */ +#define FS_MAXPATHLEN 512 /* maximum path length */ + + +/* statfs structure. */ +struct statfs { + uint32_t f_bsize; /* Size of a cluster in bytes. */ + uint32_t f_blocks; /* Number of clusters. */ + uint32_t f_bfree; /* Number of free clusters. */ +}; + +enum file_type { + FILE_TYPE_UNKNOWN = 0, + FILE_TYPE_FILE, + FILE_TYPE_DIR, +}; + +/* directory entry. */ +struct dirent { + uint32_t d_fileno; + uint32_t d_reclen; + uint8_t d_type; + uint8_t d_namlen; + char d_name[FS_MAXNAMLEN + 1]; + + int32_t d_ctime; + int32_t d_atime; + int32_t d_mtime; +}; + +/* stat structure. */ +struct stat { + uint32_t st_ino; /* Inode number. */ + uint32_t st_size; /* Lenght of file (bytes). */ + uint32_t st_blocks; /* Length of file (blocks). */ + enum file_type st_type; + uint32_t st_flags; + int32_t st_ctime; /* Creation time. */ + int32_t st_mtime; /* Modification time. */ + int32_t st_atime; /* Access time. */ +}; + +/* File I/O */ +#define FILE_SEEK_SET 0 +#define FILE_SEEK_CUR 1 +#define FILE_SEEK_END 2 + +/* read only fs ops */ +struct fs_ops { + int (*mount)(void **ctxt, const char *dev); + void (*unmount)(void *ctxt); + int (*fsstat)(void *ctxt, struct statfs *stat); + + void *(*open)(void *ctxt, const char *path, uint8_t flags); + int (*read)(void *filectxt, void *buf, size_t len); + int (*fstat)(void *filectxt, struct stat *st); + off_t (*seek)(void *filectxt, off_t offset, int whence); + void (*close)(void *filectxt); + + void *(*opendir)(void *ctxt, const char *path); + int (*readdir)(void *dirctxt, struct dirent *ent); + void (*rewinddir)(void *dirctxt); + void (*closedir)(void *dirctxt); +}; + +struct fs_struct { + const char *name; + const struct fs_ops *ops; +}; + +/* user fs api */ +int fs_mount(const char *dev, const char *fs_name, const char *mountpoint); +void fs_unmount(const char *dev); +int fs_fsstat(void *fscookie, struct statfs *stat); + +int fs_open(const char *path, uint8_t flags); +int fs_read(int handle, void *buf, size_t len); +int fs_stat(int handle, struct stat *st); +off_t fs_seek(int handle, off_t offset, int whence); +int fs_close(int handle); + +int fs_opendir(const char *path); +int fs_readdir(int handle, struct dirent *ent); +int fs_rewinddir(int handle); +int fs_closedir(int handle); +const char *fs_get_fsname(const int index); + + +/* some debug routines */ +void fs_stat_dump(const struct stat *st); +void fs_statfs_dump(const struct statfs *st); +int fs_dump_dir(const char *dirpath, bool recurse); +void fs_dump_mounts(void); + +/* convenience routines */ +int fs_load_file(const char *path, addr_t addr, size_t *maxsize); + +__END_DECLS + +#endif + diff --git a/include/lib/heap.h b/include/lib/heap.h new file mode 100644 index 0000000..a34419f --- /dev/null +++ b/include/lib/heap.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __HEAP_H +#define __HEAP_H + +#include + +__BEGIN_DECLS + +/* + * The public heap allocation functions will never return NULL. The internal + * implementation will always call panic() if an allocation cannot be + * satisfied. You should not check for NULL being returned as this is a waste + * of code and gives other readers the incorrect impression that this is + * required. + */ + +#define HEAP_COOKIE_SIZE 16 + +void heap_add_chunk(void *chunk, size_t size, bool clear_memory); +void heap_set_cookie(uint8_t *cookie); +u_int32_t heap_get_free_mem(void); +bool heap_is_initialized(void); + +void *heap_malloc(size_t size, const char *caller_name); +void *heap_realloc(void *ptr, size_t size, const char *caller_name); +void *heap_memalign(size_t size, size_t alignment, const char *caller_name); +int heap_posix_memalign(void **memptr, size_t size, size_t alignment, const char *caller_name); +void *heap_calloc(size_t count, size_t size, const char *caller_name); +void heap_free(void *ptr); +void heap_verify(void); + +#ifndef __clang_analyzer__ +#ifndef HEAP_UNITTEST +# if DEBUG_BUILD +# define malloc(_s) heap_malloc(_s, __FUNCTION__) +# define realloc(_p, _s) heap_realloc(_p, _s, __FUNCTION__) +# define memalign(_s, _a) heap_memalign(_s, _a, __FUNCTION__) +# define posix_memalign(_m, _s, _a) heap_posix_memalign(_m, _s, _a, __FUNCTION__) +# define calloc(_c, _s) heap_calloc(_c, _s, __FUNCTION__) +# else +# define malloc(_s) heap_malloc(_s, NULL) +# define realloc(_p, _s) heap_realloc(_p, _s, NULL) +# define memalign(_s, _a) heap_memalign(_s, _a, NULL) +# define posix_memalign(_m, _s, _a) heap_posix_memalign(_m, _s, _a, NULL) +# define calloc(_c, _s) heap_calloc(_c, _s, NULL) +# endif +# define free(_p) heap_free(_p) +#endif // HEAP_UNITTEST +#else // __clang_analyzer__ +// the clang static analyzer needs malloc and friends to have their normal +// names with underscores prepended in order to find things like use after free +void *malloc(size_t size); +void *realloc(void *ptr, size_t size); +void *memalign(size_t size, size_t alignment); +void *calloc(size_t count, size_t size); +void free(void *ptr); +int posix_memalign(void **memptr, size_t alignment, size_t size); +#endif + +/* heap debugging features */ +enum +{ + HEAP_BLOCK__FREE, + HEAP_BLOCK__MALLOC, + HEAP_BLOCK__MEMALIGN, + HEAP_BLOCK__SENTINEL, +}; + +struct walker_info_t +{ + unsigned block_type; + void *raw_block; + size_t block_size; + unsigned extended_info; + uint32_t checksum; + + /* these are only meaningful for HEAP_BLOCK__MALLOC & HEAP_BLOCK__MEMALIGN */ + void *user_block; + size_t user_size; /* only when extended_info != 0 */ + utime_t timestamp; /* only when extended_info != 0 */ + void *requestor; /* only when extended_info != 0 */ + + /* this is only meaningful for HEAP_BLOCK__MEMALIGN, set to zero for HEAP_BLOCK__MALLOC */ + size_t alignment; /* only when extended_info != 0 */ +}; + +typedef int (heap_walker_f)(void *cookie, struct walker_info_t const *); + +__END_DECLS + +#endif + diff --git a/include/lib/image.h b/include/lib/image.h new file mode 100644 index 0000000..7d33637 --- /dev/null +++ b/include/lib/image.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_IMAGE_H +#define __LIB_IMAGE_H + +#include +#include +#include + +__BEGIN_DECLS + +struct image_info { + u_int32_t imageLength; + u_int32_t imageAllocation; + u_int32_t imageType; + u_int32_t imagePrivateMagic; +#define IMAGE_MEMORY_INFO_MAGIC 'Memz' +#define IMAGE2_IMAGE_INFO_MAGIC 'img2' +#define IMAGE3_IMAGE_INFO_MAGIC 'img3' +#define IMAGE4_IMAGE_INFO_MAGIC 'img4' + u_int32_t imageOptions; + void *imagePrivate; +}; + +// images we might be interested in +#define IMAGE_TYPE_ANY 0 // any image type +#define IMAGE_TYPE_DIAG 'diag' // diagnostics +#define IMAGE_TYPE_LLB 'illb' // iboot first-stage loader +#define IMAGE_TYPE_IBOOT 'ibot' // iboot second-stage loader +#define IMAGE_TYPE_IBSS 'ibss' // iboot single stage +#define IMAGE_TYPE_IBEC 'ibec' // iboot epoch change +#define IMAGE_TYPE_DALI 'dali' // dali +#define IMAGE_TYPE_DEVTREE 'dtre' // darwin device tree +#define IMAGE_TYPE_DEVTREE_RESTORE 'rdtr' // darwin device tree for restore +#define IMAGE_TYPE_RAMDISK 'rdsk' // darwin ram disk for restore +#define IMAGE_TYPE_KERNELCACHE 'krnl' // darwin kernel cache +#define IMAGE_TYPE_KERNELCACHE_RESTORE 'rkrn' // darwin kernel cache for restore +#define IMAGE_TYPE_LOGO 'logo' // boot logo image +#define IMAGE_TYPE_RECMODE 'recm' // recovery mode image +#define IMAGE_TYPE_NEEDSERVICE 'nsrv' // need service image +#define IMAGE_TYPE_GLYPHCHRG 'glyC' // glyph charge image +#define IMAGE_TYPE_GLYPHPLUGIN 'glyP' // glyph plug in image +#define IMAGE_TYPE_BATTERYCHARGING0 'chg0' // battery charging image - bright +#define IMAGE_TYPE_BATTERYCHARGING1 'chg1' // battery charging image - dim +#define IMAGE_TYPE_BATTERYLOW0 'bat0' // battery low image - empty +#define IMAGE_TYPE_BATTERYLOW1 'bat1' // battery low image - red (composed onto empty) +#define IMAGE_TYPE_BATTERYFULL 'batF' // battery full image list +#define IMAGE_TYPE_BATTERYFULL_N_TOTAL (18) // total number of images +#define IMAGE_TYPE_BATTERYFULL_N_START (2) // first image that's part of batF list (first two are bat0 and bat1) +#define IMAGE_TYPE_BATTERYFULL_N_RED (4) // last red battery image +#define IMAGE_TYPE_BATTERYFULL_N_FULL (IMAGE_TYPE_BATTERYFULL_N_TOTAL-1) // battery full image +#define IMAGE_TYPE_ENV 'ienv' // environment vars +#define IMAGE_TYPE_TSYS 'tsys' // tsys tester +#define IMAGE_TYPE_MONITOR 'hypr' // monitor/hypervisor +#define IMAGE_TYPE_OS_RESTORE 'rosi' // OS image for restore +#define IMAGE_TYPE_SEP_OS 'sepi' // SEP OS image +#define IMAGE_TYPE_SEP_OS_RESTORE 'rsep' // SEP OS image for restore +#define IMAGE_TYPE_CFE_LOADER 'cfel' // SiVal's CFE loader +#define IMAGE_TYPE_RBM 'rbmt' // SiVal's RBM test +#define IMAGE_TYPE_PHLEET 'phlt' // SiVal's PHLEET test +#define IMAGE_TYPE_PE_RTOS 'pert' // PE's RTOS environment +#define IMAGE_TYPE_HAMMER 'hmmr' // PE's Hammer test +#define IMAGE_TYPE_FDRT 'fdrt' // FDR Trust object for AP +#define IMAGE_TYPE_FDRS 'fdrs' // FDR Trust object for SEP + +// image options +#define IMAGE_OPTION_GREATER_EPOCH (1 << 0) // Allow platform epoch or greater +#define IMAGE_OPTION_REQUIRE_TRUST (1 << 1) // Regardless of security, require image + // trust +#define IMAGE_OPTION_LOCAL_STORAGE (1 << 2) // Image came from local (personalised) storage +#define IMAGE_OPTION_NEW_TRUST_CHAIN (1 << 3) // New chain of trust. Image load library can use this information + // enforce various policies. + +#define IMAGE_OPTION_JUST_LOAD (1 << 8) // Just load the whole image, don't validate or look for a payload +#define IMAGE_OPTION_MEMORY (1 << 9) // Image comes from a memory bdev, so its hash isn't personalized + +// XXX backwards compatibility +#define IMAGE_OPTION_ANY_EPOCH IMAGE_OPTION_GREATER_EPOCH // Allow any epoch for this image + + +// image keybag selectors +#define IMAGE_KEYBAG_SELECTOR_PROD (1) +#define IMAGE_KEYBAG_SELECTOR_DEV (2) + + +/** + * Load an image from a file. + * + * \param[in] path Path including mountpoint from which to read. + * \param[inout] address Address for the buffer used both for file reading and into which + * the resulting image data will be placed. Referenced pointer will + * be zeroed on failure. + * \param[inout] length On input, the size of the buffer. The file must file entirely + * within this size. Updated on return to the size of the image + * data extracted from the image. + * \param[in] types An array of types that the image must conform to one of, + * or NULL if no type checking should be performed. + * \param[in] count The count of image types in the types array, + * or zero if NULL was passed. + * \param[out] actual A pointer to receive the actual type for given image. + * Optional if count is 0 or 1. + * \param[in] options Options to be passed when creating the image. + * + * \return 0 on success. + */ +int +image_load_file( + const char *path, + addr_t *address, + size_t *length, + const uint32_t *types, + uint32_t count, + uint32_t *actual, + uint32_t options); + +/** + * Load an image from memory. + * + * \param[in] fromAddress Address of the buffer containing the image. + * \param[in] fromLength Size of the buffer containing the image. + * \param[inout] address Address for the buffer into which the resulting image data will + * be placed. Referenced pointer will be zeroed on failure. + * \param[inout] length On input, the size of the destination buffer. The image must file + * entirely within this size. Updated on return to the size of the image + * data extracted from the image. + * \param[in] types An array of types that the image must conform to one of, + * or NULL if no type checking should be performed. + * \param[in] count The count of image types in the types array, + * or zero if NULL was passed. + * \param[out] actual A pointer to receive the actual type for given image. + * Optional if count is 0 or 1. + * \param[in] options Options to be passed when creating the image. + * + * \return 0 on success. + */ +int +image_load_memory( + addr_t fromAddress, + size_t fromLength, + addr_t *address, + size_t *length, + const uint32_t *types, + uint32_t count, + uint32_t *actual, + uint32_t options); + + +/** + * Load an image of a given type from the set of known images. + * + * \param[inout] address Address for the buffer into which the resulting image data will + * be placed. Referenced pointer will be zeroed on failure. + * \param[inout] length On input, the size of the destination buffer. The image must file + * entirely within this size. Updated on return to the size of the image + * data extracted from the image. + * \param[in] type The image type to be looked up. + * \param[in] options Options to be passed when creating the image. + * + * \return 0 on success. + */ +int +image_load_type( + addr_t *address, + size_t *length, + uint32_t type, + uint32_t options); + +/* + * Lower-level primitives - avoid when possible. + */ +int +image_search_bdev( + struct blockdev *bdev, + off_t map_offset, + uint32_t imageOptions); + +void +image_free_bdev( + struct blockdev *bdev); + +int +image_load( + struct image_info *image, + const uint32_t *types, + uint32_t count, + uint32_t *actual, + void **load_addr, + size_t *load_len); + +struct image_info * +image_find( + u_int32_t type); + +void +image_dump_list( + bool detailed); + +struct image_info * +image_create_from_memory( + void *address, + size_t length, + uint32_t imageOptions); + +void +image_free( + struct image_info *image); + +__END_DECLS + +#endif diff --git a/include/lib/image4_spi.h b/include/lib/image4_spi.h new file mode 100644 index 0000000..58591cd --- /dev/null +++ b/include/lib/image4_spi.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_IMAGE4_SPI_H +#define __LIB_IMAGE4_SPI_H + + +/* + * An image of type 'image_type' is being loaded. + * + * Return true if you'd like its properties captured, false otherwise. + */ +typedef bool (*image4_start_capture_callback)(uint32_t image_type); + +/* + * Property callbacks for supported property types: + * + * tag: 32-bit property tag (e.g. 'EPRO') + * is_object_property: true for object property, false for manifest property + * + * Note that for the string variant, 'buffer' is only valid within the scope of the callback. + */ +typedef void (*image4_boolean_property_callback)(uint32_t tag, bool is_object_property, bool val); +typedef void (*image4_integer_property_callback)(uint32_t tag, bool is_object_property, uint64_t val); +typedef void (*image4_string_property_callback)(uint32_t tag, bool is_object_property, uint8_t* buffer, size_t length); + + +/* + * Validity callback: + * + * true: Image has been validated -- captured properties can be used + * false: Image is not valid. You should zero out any previously captured properties! + */ +typedef void (*image4_validity_callback)(bool valid); + +/* + * image4_register_property_capture_callbacks + * + * On some targets, we would like to stash away various image4 properties for a particular payload type. + * Register callbacks for property captures, as well as a callback to let you know whether or not the image ended + * up being valid. + * + * Note for security reasons, you are expected to zero out your stored properties if you find out that + * image4_validity_callback is called with false. + */ +extern void +image4_register_property_capture_callbacks(image4_start_capture_callback start_cb, image4_boolean_property_callback bool_cb, + image4_integer_property_callback int_cb, image4_string_property_callback string_cb, + image4_validity_callback validity); + + +#endif \ No newline at end of file diff --git a/include/lib/libc.h b/include/lib/libc.h new file mode 100644 index 0000000..440e648 --- /dev/null +++ b/include/lib/libc.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_LIBC_H +#define __LIB_LIBC_H + +#include +#include + +#if !WITH_HOST_LIBC + +#include +#include +#include + +#define LIBC_FUNC(x) x + +// for compatibility with code that gets is_pow2, ROUNDUP, etc through +// the standard lib headers. new/updated code should include libiboot.h +// directly instead of getting it through libc.h +#include + +#else // WITH_HOST_LIBC + +// Prefix function names with libc_ in order to not collide with the real functions +#define LIBC_FUNC(x) libc_##x + +#endif + +__BEGIN_DECLS + +/* stdio stuff */ +int LIBC_FUNC(puts)(const char *str); +int LIBC_FUNC(getchar)(void); +int LIBC_FUNC(putchar)(int c); + +int LIBC_FUNC(printf)(const char *fmt, ...) __printflike(1, 2); +int LIBC_FUNC(vprintf)(const char *fmt, va_list ap); +int LIBC_FUNC(snprintf)(char *str, size_t size, const char *fmt, ...) __printflike(3, 4); +int LIBC_FUNC(vsnprintf)(char *str, size_t size, const char *fmt, va_list ap); + +/* fake fprintf to accomodate AssertMacros.h */ +#if !WITH_HOST_LIBC +#define stdout 0 +#define stderr 0 +#endif +int LIBC_FUNC(fprintf)(void *stream, const char *fmt, ...) __printflike(2, 3); + +/* string */ +void * LIBC_FUNC(memchr)(void const *, int, size_t); +int LIBC_FUNC(memcmp)(void const *, const void *, size_t); +int LIBC_FUNC(memcmp_secure)(void const *, const void *, size_t); +void * LIBC_FUNC(memcpy)(void *, void const *, size_t); +void * LIBC_FUNC(memmove)(void *, void const *, size_t); +void * LIBC_FUNC(memset)(void *, int, size_t); + +char * LIBC_FUNC(strchr)(char const *, int); +int LIBC_FUNC(strcmp)(char const *, char const *); +size_t LIBC_FUNC(strlen)(char const *); +int LIBC_FUNC(strncmp)(char const *, char const *, size_t); +char * LIBC_FUNC(strpbrk)(char const *, char const *); +char * LIBC_FUNC(strrchr)(char const *, int); +size_t LIBC_FUNC(strspn)(char const *, char const *); +size_t LIBC_FUNC(strcspn)(const char *s, const char *); +char * LIBC_FUNC(strstr)(char const *, char const *); +char * LIBC_FUNC(strtok)(char *, char const *); +int LIBC_FUNC(strcoll)(const char *s1, const char *s2); +size_t LIBC_FUNC(strxfrm)(char *dest, const char *src, size_t n); +char * LIBC_FUNC(strdup)(const char *str); + +/* non standard string */ +void * LIBC_FUNC(bcopy)(void const *, void *, size_t); +void LIBC_FUNC(bzero)(void *, size_t); +size_t LIBC_FUNC(strlcat)(char *, char const *, size_t); +size_t LIBC_FUNC(strlcpy)(char *, char const *, size_t); +int LIBC_FUNC(strncasecmp)(char const *, char const *, size_t); +int LIBC_FUNC(strnicmp)(char const *, char const *, size_t); +size_t LIBC_FUNC(strnlen)(char const *s, size_t count); +char * LIBC_FUNC(strsep)(char **stringp, const char *delim); + +/* secure string functions */ +#if !WITH_HOST_LIBC +#if !defined(__cplusplus) +#if __has_builtin(__builtin___memcpy_chk) + #define memcpy(dest, src, len) __builtin___memcpy_chk(dest, src, len, __builtin_object_size(dest, 0)) +#endif +#if __has_builtin(__builtin___memmove_chk) + #define memmove(dest, src, len) __builtin___memmove_chk(dest, src, len, __builtin_object_size(dest, 0)) +#endif +#if __has_builtin(__builtin___memset_chk) + #define memset(dest, c, len) __builtin___memset_chk(dest, c, len, __builtin_object_size(dest, 0)) +#endif + +#define bcopy(src, dest, len) memcpy(dest, src, len) +#define bzero(dest, len) memset(dest, 0, len) +#if __has_builtin(__builtin___strlcat_chk) + #define strlcat(dest, src, len) __builtin___strlcat_chk(dest, src, len, __builtin_object_size(dest, 1)) +#endif +#if __has_builtin(__builtin___strlcpy_chk) + #define strlcpy(dest, src, len) __builtin___strlcpy_chk(dest, src, len, __builtin_object_size(dest, 1)) +#endif + +#if __has_builtin(__builtin___snprintf_chk) + #define snprintf(dst, size, ...) __builtin___snprintf_chk(dst, size, 0, __builtin_object_size(dst, 1), __VA_ARGS__) +#endif +#if __has_builtin(__builtin___vsnprintf_chk) + #define vsnprintf(dst, size, fmt, ap) __builtin___vsnprintf_chk(dst, size, 0, __builtin_object_size(dst, 1), fmt, ap) +#endif + +#endif // __cplusplus +#endif // !WITH_HOST_LIBC + +/* ctype */ +int LIBC_FUNC(isalnum)(int c); +int LIBC_FUNC(isalpha)(int c); +int LIBC_FUNC(iscntrl)(int c); +int LIBC_FUNC(isdigit)(int c); +int LIBC_FUNC(isgraph)(int c); +int LIBC_FUNC(islower)(int c); +int LIBC_FUNC(isprint)(int c); +int LIBC_FUNC(ispunct)(int c); +int LIBC_FUNC(isspace)(int c); +int LIBC_FUNC(isupper)(int c); +int LIBC_FUNC(isxdigit)(int c); +int LIBC_FUNC(isascii)(int c); +int LIBC_FUNC(toascii)(int c); + +unsigned char LIBC_FUNC(tolower)(unsigned char c); +unsigned char LIBC_FUNC(toupper)(unsigned char c); + +/* errno */ +#if !WITH_HOST_LIBC +extern int errno; +#include +#endif + +/* numbers */ +long LIBC_FUNC(strtol)(const char *nptr, char **endptr, int base); +unsigned long LIBC_FUNC(strtoul)(const char *nptr, char **endptr, int base); +unsigned long long LIBC_FUNC(strtoull)(const char * __restrict nptr, char ** __restrict endptr, int base); +int LIBC_FUNC(atoi)(const char *nptr); + +/* stdlib */ +int LIBC_FUNC(system)(const char *command); +void LIBC_FUNC(exit)(int status); +void LIBC_FUNC(qsort)(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); +void LIBC_FUNC(srand)(unsigned int seed); +int LIBC_FUNC(rand)(void); + +#if !WITH_HOST_LIBC +uint32_t swap32(uint32_t x); +uint16_t swap16(uint16_t x); + +/* ntohl and friends */ +uint32_t LIBC_FUNC(htonl)(uint32_t hostlong); +uint16_t LIBC_FUNC(htons)(uint16_t hostshort); +uint32_t LIBC_FUNC(ntohl)(uint32_t netlong); +uint16_t LIBC_FUNC(ntohs)(uint16_t netshort); +#endif + +__END_DECLS +#endif diff --git a/include/lib/libiboot.h b/include/lib/libiboot.h new file mode 100644 index 0000000..503039f --- /dev/null +++ b/include/lib/libiboot.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_LIBIBOOT_H +#define __LIB_LIBIBOOT_H + +#include + +__BEGIN_DECLS + +/* for powers of 2 only */ +#define ROUNDUP(a, b) (((a) + ((b) - 1)) & (~((b) - 1))) +#define ROUNDDOWN(a, b) (((a) / (b)) * (b)) + +/* some of our own stuff */ +void hexdump(const void *_ptr, size_t len); + +#define is_pow2(n) ((((n)-1) & (n)) == 0) +int log2_int(unsigned int val); + +__END_DECLS + +#endif diff --git a/include/lib/lzss.h b/include/lib/lzss.h new file mode 100644 index 0000000..4b39483 --- /dev/null +++ b/include/lib/lzss.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LIB_LZSS_H +#define __LIB_LZSS_H + +#include +#include + +__BEGIN_DECLS + +uint32_t decompress_lzss(uint8_t * __restrict dst, uint32_t dstlen, const uint8_t * __restrict src, uint32_t srclen); + +__END_DECLS + +#endif diff --git a/include/lib/macho.h b/include/lib/macho.h new file mode 100644 index 0000000..ed16a12 --- /dev/null +++ b/include/lib/macho.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2006-2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_MACHO_H +#define __LIB_MACHO_H + +#include +#include + +__BEGIN_DECLS + +/** + * load a kernelcache from memory, return the entry point + * + * \param[in] addr Address of the kernelcache in memory. + * \param[in] size Size of the kernelcache in memory. + * \param[in] type Type of kernelcache (restore or local boot). + * \param[out] entry Entrypoint recovered from the kernelcache. + * \param[out] boot_args_out Boot arguments to pass to the kernelcache entry point. + * + * \return 0 Kernelcache was loaded successfully. + * \return -2 Kernelcache is too large. + * \return -3 Kernelcache container failed validation (signature, + * wrong system, etc.) + * \return -4 Not a valid kernelcache (bad magic number). + * \return -5 Decompression failed. + * \return -6 Not a valid Mach-o image (bad magic number). + * \return -7 Mach-o load failed. + */ +int load_kernelcache(addr_t addr, size_t size, uint32_t type, addr_t *entry, addr_t *boot_args_out); + +/** + * load a kernelcache from a path, return the entry point + * + * \param[in] path Filesystem path from which to read the kernelcache. + * \param[in] type Type of kernelcache (restore or local boot). + * \param[out] entry Entrypoint recovered from the kernelcache. + * \param[out] boot_args_out Boot arguments to pass to the kernelcache entry point. + * + * \return 0 Kernelcache was loaded successfully. + * \return -2 Kernelcache is too large. + * \return -3 Kernelcache container failed validation (signature, + * wrong system, etc.) + * \return -4 Not a valid kernelcache (bad magic number). + * \return -5 Decompression failed. + * \return -6 Not a valid Mach-o image (bad magic number). + * \return -7 Mach-o load failed. + */ +int load_kernelcache_file(const char *path, uint32_t type, addr_t *entry, addr_t *boot_args_out); + +/** + * load a kernelcache from a known image, return the entry point + * + * \param[in] image Known image from which to read the kernelcache. + * \param[in] type Type of kernelcache (restore or local boot). + * \param[out] entry Entrypoint recovered from the kernelcache. + * \param[out] boot_args_out Boot arguments to pass to the kernelcache entry point. + * + * \return 0 Kernelcache was loaded successfully. + * \return -2 Kernelcache is too large. + * \return -3 Kernelcache container failed validation (signature, + * wrong system, etc.) + * \return -4 Not a valid kernelcache (bad magic number). + * \return -5 Decompression failed. + * \return -6 Not a valid Mach-o image (bad magic number). + * \return -7 Mach-o load failed. + */ +int load_kernelcache_image(struct image_info *image, uint32_t type, addr_t *entry, addr_t *boot_args_out); + +/** + * load a monitor from a path + * + * A loaded monitor is recognised by the kernelcache loader; the + * appropriate entrypoint will be returned at kernelcache load time. + * + * \param[in] path Filesystem path from which to read the kernelcache. + * + * \return 0 Monitor was loaded successfully. + * \return -2 Monitor is too large. + * \return -3 Monitor container failed validation (signature, + * wrong system, etc.) + * \return -6 Not a valid Mach-o image (bad magic number). + * \return -7 Mach-o load failed. + */ +int load_monitor_file(const char *path); + +/** + * load a monitor from a known image + * + * \param[in] address Known image address + * \param[in] size Known image size + * + * \return 0 Monitor was loaded successfully. + * \return -2 Monitor is too large. + * \return -3 Monitor container failed validation (signature, + * wrong system, etc.) + * \return -6 Not a valid Mach-o image (bad magic number). + * \return -7 Mach-o load failed. + */ +int load_monitor_image(addr_t address, size_t size); + +bool macho_valid(addr_t addr); +bool macho_load(addr_t imageAddr, size_t imageSize, addr_t loadAddr, addr_t *virtualBase, addr_t *virtualEnd, addr_t *entryPoint, size_t slide); + +__END_DECLS + +#endif + diff --git a/include/lib/mib.h b/include/lib/mib.h new file mode 100644 index 0000000..1ca4b12 --- /dev/null +++ b/include/lib/mib.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2008-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _MIB_H +#define _MIB_H + +#include +#include +#include +#include + +/* + * Standard MIB application/product definitions. + */ +#define MIB_APP_PROD_UNKNOWN (0) +#define MIB_APP_PROD_SECUREROM (1) +#define MIB_APP_PROD_IBSS (2) +#define MIB_APP_PROD_IBEC (3) +#define MIB_APP_PROD_IBOOT (4) +#define MIB_APP_PROD_LLB (5) +#define MIB_APP_PROD_EMBEDDEDIOP (8) + +__BEGIN_DECLS + +#define OID_SUBSYSTEM(_o) ((_o)>>24) +#define OID_NODE(_o) (((_o)>>16)&0xff) + +#define OID_SUBSYSTEM_MASK (0xff<<24) +#define OID_NODE_MASK (0xff<<16) + +typedef void (* mib_func_t)(uint32_t oid, void *arg, void *value); + +struct mib_func_spec { + mib_func_t func; + void *arg; +}; + +union mib_value { + uint32_t v32; + uint64_t v64; + bool v_bool; + void *v_ptr; + struct mib_func_spec v_func; +}; + +struct mib_node { + uint32_t node_oid; + uint32_t node_type; + union mib_value node_data; +}; + +/* node data types */ +#define kOIDTypeUInt32 (0x00<<16) /* node data is uint32_t */ +#define kOIDTypeInt32 (0x01<<16) /* node data is int32_t */ +#define kOIDTypeUInt64 (0x02<<16) /* node data is uint64_t */ +#define kOIDTypeInt64 (0x03<<16) /* node data is int64_t */ +#if defined(__LP64__) +#define kOIDTypeAddr kOIDTypeUInt64 /* node data is uint64_t */ +#define kOIDTypeSize kOIDTypeUInt64 /* node data is uint64_t */ +#else +#define kOIDTypeAddr kOIDTypeUInt32 /* node data is uint32_t */ +#define kOIDTypeSize kOIDTypeUInt32 /* node data is uint32_t */ +#endif +#define kOIDTypeBoolean (0x04<<16) /* node data is bool */ +#define kOIDTypeString (0x05<<16) /* node data is const char * */ +#define kOIDTypeStruct (0x06<<16) /* node data is void * */ +#define kOIDTypeOIDIndirect (0x07<<16) /* node data is oid (reference to another node) */ + +#define kOIDTypeMask (0xff<<16) +#define kOIDStructSizeMask (0xffff) + +/* node data qualifiers */ +#define kOIDDataIndirect (1<<24) /* data is indirected through v_ptr */ +#define kOIDFunction (2<<24) /* data is obtained by calling v_func */ +#define kOIDWeak (4<<24) /* node only valid if no other node present */ + +# define MIB_CONSTANT(_oid, _type, _value) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_ ## _oid = { \ + .node_oid = _oid, \ + .node_type = _type, \ + .node_data.v64 = (uint64_t)(_value) \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_ ## _oid) + +# define MIB_CONSTANT_WEAK(_oid, _type, _value) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_weak_ ## _oid = { \ + .node_oid = _oid, \ + .node_type = _type | kOIDWeak, \ + .node_data.v64 = (uint64_t)(_value) \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_weak_ ## _oid) + +# define MIB_CONSTANT_PTR(_oid, _type, _value) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_ ## _oid = { \ + .node_oid = _oid, \ + .node_type = _type, \ + .node_data.v_ptr = (_value) \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_ ## _oid) + +# define MIB_CONSTANT_PTR_WEAK(_oid, _type, _value) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_weak_ ## _oid = { \ + .node_oid = _oid, \ + .node_type = _type | kOIDWeak, \ + .node_data.v_ptr = (_value) \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_weak_ ## _oid) + +# define MIB_VARIABLE(_oid, _type, _var) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_##_oid = { \ + .node_oid = _oid, \ + .node_type = _type | kOIDDataIndirect, \ + .node_data.v_ptr = (void *)(&_var) \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_ ## _oid) + +# define MIB_VARIABLE_WEAK(_oid, _type, _var) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_weak_ ## _oid = { \ + .node_oid = _oid, \ + .node_type = _type | kOIDDataIndirect | kOIDWeak, \ + .node_data.v_ptr = (void *)(&_var) \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_weak_ ## _oid) + +# define MIB_FUNCTION(_oid, _type, _func, _arg) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_##_oid = { \ + .node_oid = _oid, \ + .node_type = _type | kOIDFunction, \ + .node_data.v_func = {_func, _arg} \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_ ## _oid) + +# define MIB_FUNCTION_WEAK(_oid, _type, _func, _arg) \ +static const struct mib_node __attribute__((used)) \ +__mib_node_weak_ ## _oid = { \ + .node_oid = _oid, \ + .node_type = _type | kOIDFunction | kOIDWeak, \ + .node_data.v_func = {_func, _arg} \ +}; \ +LINKER_SET_ENTRY(mib, __mib_node_weak_ ## _oid) + + +/* + * Find a node in the MIB. + */ +union mib_value *mib_find_oid(uint32_t oid); + +/* + * Find a node of an expected type in the MIB and return its value. + * Returns false if the OID is not present. + * + * This interface should only be used for optional nodes; if a node + * is expected to exist, use the mib_get_* interfaces to avoid duplicating + * error checking. + */ +bool _mib_find(uint32_t oid, uint32_t node_type, void *value); +bool mib_exists(uint32_t oid, void *value); +/* + * Return the value of an OID expected to be in the MIB; the + * MIB will panic on behalf of the caller if the node is not + * found. + */ +void _mib_get(uint32_t oid, uint32_t node_type, void *value); + +#define MIB_GET_TEMPLATE(stype, type, oid_type) \ + static inline type \ + mib_get_##stype(uint32_t oid) { \ + type ret; \ + _mib_get(oid, oid_type, &ret); \ + return ret; \ + } \ + \ + static inline type \ + mib_get_##stype##_opt(uint32_t oid, type def) { \ + type ret = def; \ + _mib_find(oid, oid_type, &ret); \ + return ret; \ + } + +MIB_GET_TEMPLATE(u32, uint32_t, kOIDTypeUInt32) +MIB_GET_TEMPLATE(s32, int32_t, kOIDTypeInt32) +MIB_GET_TEMPLATE(u64, uint64_t, kOIDTypeUInt32) +MIB_GET_TEMPLATE(s64, int64_t, kOIDTypeInt64) +MIB_GET_TEMPLATE(addr, uintptr_t, kOIDTypeAddr) +MIB_GET_TEMPLATE(size, size_t, kOIDTypeSize) +MIB_GET_TEMPLATE(bool, bool, kOIDTypeBoolean) +MIB_GET_TEMPLATE(str, const char *, kOIDTypeString) +MIB_GET_TEMPLATE(ptr, const void *, kOIDTypeStruct) + +#undef MIB_GET_TEMPLATE + +/* + * MIB node descriptions are automatically generated at build time. + */ +struct mib_description { + uint32_t oid; + const char *desc; +}; + +extern struct mib_description mib_desc[]; + +__END_DECLS + +#endif /* _MIB_H */ diff --git a/include/lib/mib_def.h b/include/lib/mib_def.h new file mode 100644 index 0000000..6bda608 --- /dev/null +++ b/include/lib/mib_def.h @@ -0,0 +1,143 @@ +// Copyright (C) 2014-2015 Apple Inc. All rights reserved. +// +// This document is the property of Apple Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple Inc. +// + +#ifndef _MIB_DEF_H +#define _MIB_DEF_H + +#include +#include + +// Application/Product selection +#if PRODUCT_IBSS +#define MIB_APP_PROD MIB_APP_PROD_IBSS +#elif PRODUCT_IBEC +#define MIB_APP_PROD MIB_APP_PROD_IBEC +#elif PRODUCT_IBOOT +#define MIB_APP_PROD MIB_APP_PROD_IBOOT +#elif PRODUCT_LLB +#define MIB_APP_PROD MIB_APP_PROD_LLB +#elif APPLICATION_EMBEDDEDIOP +#define MIB_APP_PROD MIB_APP_PROD_EMBEDDEDIOP +#elif APPLICATION_SECUREROM +#define MIB_APP_PROD MIB_APP_PROD_SECUREROM +#else +#error "Unknown APPLICATION/PRODUCT" +#endif + +// Standard MIB constants for all platforms and targets +MIB_CONSTANT(kMIBPlatformCacheLineSize, kOIDTypeSize, CPU_CACHELINE_SIZE); +MIB_CONSTANT(kMIBPlatformSDRAMBaseAddress, kOIDTypeAddr, SDRAM_BASE); +MIB_CONSTANT(kMIBPlatformSDRAMSize, kOIDTypeSize, (SDRAM_END - SDRAM_BASE)); +MIB_CONSTANT(kMIBTargetApplicationProduct, kOIDTypeUInt32, MIB_APP_PROD); +MIB_CONSTANT(kMIBPlatformPageSize, kOIDTypeSize, PAGE_SIZE); + +#if WITH_IMAGE4 +MIB_CONSTANT(kMIBPlatformImageFormat, kOIDTypeUInt32, 4); +#elif WITH_IMAGE3 +MIB_CONSTANT(kMIBPlatformImageFormat, kOIDTypeUInt32, 3); +#endif + +#ifdef PLATFORM_ENTROPY_RATIO +MIB_CONSTANT(kMIBPlatformEntropyRatio, kOIDTypeUInt32, PLATFORM_ENTROPY_RATIO); +#endif + +// All of the following depend upon INSECURE_MEMORY_BASE being defined +#ifdef INSECURE_MEMORY_BASE + +#ifdef DEFAULT_DEVICETREE_ADDRESS +MIB_CONSTANT(kMIBTargetDefaultDeviceTreeAddress,kOIDTypeAddr, DEFAULT_DEVICETREE_ADDRESS); +#endif + +#ifdef DEFAULT_DEVICETREE_SIZE +MIB_CONSTANT(kMIBTargetDefaultDeviceTreeSize, kOIDTypeSize, DEFAULT_DEVICETREE_SIZE); +#endif + +#ifdef DEFAULT_FREE_ADDRESS +MIB_CONSTANT(kMIBTargetDefaultFreeAddress, kOIDTypeAddr, DEFAULT_FREE_ADDRESS); +#endif + +#ifdef DEFAULT_LOAD_ADDRESS +MIB_CONSTANT(kMIBTargetDefaultLoadAddress, kOIDTypeAddr, DEFAULT_LOAD_ADDRESS); +#endif + +#ifdef DEFAULT_LOAD_SIZE +MIB_CONSTANT(kMIBTargetDefaultLoadSize, kOIDTypeSize, DEFAULT_LOAD_SIZE); +#endif + +#ifdef DEFAULT_KERNEL_ADDRESS +MIB_CONSTANT(kMIBTargetDefaultKernelAddress, kOIDTypeAddr, DEFAULT_KERNEL_ADDRESS); +#endif + +#ifdef DEFAULT_KERNEL_SIZE +MIB_CONSTANT(kMIBTargetDefaultKernelSize, kOIDTypeSize, DEFAULT_KERNEL_SIZE); +#endif + +#ifdef DEFAULT_RAMDISK_ADDRESS +MIB_CONSTANT(kMIBTargetDefaultRamdiskAddress, kOIDTypeAddr, DEFAULT_RAMDISK_ADDRESS); +#endif + +#ifdef DEFAULT_RAMDISK_SIZE +MIB_CONSTANT(kMIBTargetDefaultRamdiskSize, kOIDTypeSize, DEFAULT_RAMDISK_SIZE); +#endif + +#ifdef DISPLAY_BASE +MIB_CONSTANT(kMIBTargetDisplayBaseAddress, kOIDTypeAddr, DISPLAY_BASE); +#endif + +#endif // INSECURE_MEMORY_BASE + +#ifdef PANIC_BASE +MIB_CONSTANT(kMIBTargetPanicBufferAddress, kOIDTypeAddr, PANIC_BASE); +#endif + +#ifdef PANIC_SIZE +MIB_CONSTANT(kMIBTargetPanicBufferSize, kOIDTypeSize, PANIC_SIZE); +#endif + +#if (PRODUCT_LLB || APPLICATION_SECUREROM) && WITH_NO_RANDOM_HEAP_COOKIE +MIB_CONSTANT(kMIBTargetRandomHeapCookie, kOIDTypeBoolean, false); +#else +MIB_CONSTANT(kMIBTargetRandomHeapCookie, kOIDTypeBoolean, true); +#endif + +// Target-specified MIB weak overrides +#if WITH_HW_ASP +MIB_CONSTANT(kMIBTargetWithHwAsp, kOIDTypeBoolean, true); +#endif + +#if WITH_EFFACEABLE +MIB_CONSTANT(kMIBTargetWithEffaceable, kOIDTypeBoolean, true); +#endif + +#if WITH_FS +MIB_CONSTANT(kMIBTargetWithFileSystem, kOIDTypeBoolean, true); +#endif + +#if WITH_HW_FLASH_NAND +MIB_CONSTANT(kMIBTargetWithHwFlashNand, kOIDTypeBoolean, true); +#endif + +#if WITH_HW_FLASH_NOR +MIB_CONSTANT(kMIBTargetWithHwFlashNor, kOIDTypeBoolean, true); +#endif + +#if WITH_NVME +MIB_CONSTANT(kMIBTargetWithHwNvme, kOIDTypeBoolean, true); +#endif + +#if WITH_LEGACY_PANIC_LOGS +MIB_CONSTANT(kMIBTargetWithLegacyPanicLogs, kOIDTypeBoolean, true); +#endif + +// Get rid of intermediate abstractions +#undef MIB_APP_PROD + +#endif /* _MIB_DEF_H */ + diff --git a/include/lib/net.h b/include/lib/net.h new file mode 100644 index 0000000..74a589e --- /dev/null +++ b/include/lib/net.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_NET_H +#define __LIB_NET_H + +#include + +__BEGIN_DECLS + +int start_network_stack(void); +int stop_network_stack(void); + +/* ip and mac address string manipulation routines */ +void mac2str(uint8_t mac[6], char *ascii, size_t size); +void ip2str(const uint8_t *ip, char *str, size_t size); + +__END_DECLS + +#endif + diff --git a/include/lib/net/arp.h b/include/lib/net/arp.h new file mode 100644 index 0000000..e0eb23b --- /dev/null +++ b/include/lib/net/arp.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __ARP_H__ +#define __ARP_H__ + +#include + +__BEGIN_DECLS + +#define ARP_OFFSET_HTYPE 0 +#define ARP_OFFSET_PTYPE 2 +#define ARP_OFFSET_HLEN 4 +#define ARP_OFFSET_PLEN 5 +#define ARP_OFFSET_OPER 6 +#define ARP_OFFSET_SHA 8 + +int arp_layer(bool on); +int arp_get_macaddr(uint32_t ip,char *mac); +int arp_fill(uint32_t ip, utime_t timeout); /* send arp requests until it is satisfied or timeout */ +void arp_dump_table(void); + +#define ARP_CACHE_SIZE 32 + +typedef struct arp_cache_entry { + uint32_t ip; + char mac[6]; + struct arp_cache_entry *next; +} arp_cache_entry_t; + +typedef struct arp_cache { + arp_cache_entry_t cache[ARP_CACHE_SIZE]; +} arp_cache_t; + +__END_DECLS + +#endif diff --git a/include/lib/net/callbacks.h b/include/lib/net/callbacks.h new file mode 100644 index 0000000..7439fb9 --- /dev/null +++ b/include/lib/net/callbacks.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __CALLBACKS_H__ +#define __CALLBACKS_H__ + +#include + +__BEGIN_DECLS + +typedef int (*callback_handler)(char *data,int offset,int len,void *prevlayerdata); + +struct listentry; + +typedef struct listentry { + int cb_id; + int port; //port/service/etc + callback_handler callback; + struct listentry *next; +} listentry_t; + +typedef struct callbacks { + listentry_t *first; +}callbacks_t; + + +int registerCallback(callbacks_t *,int port,callback_handler cb); +int unregisterCallback(callbacks_t *cbs,int cb_id); +callback_handler find_callback(callbacks_t *cbs,int port); + +__END_DECLS + +#endif + diff --git a/include/lib/net/ethernet.h b/include/lib/net/ethernet.h new file mode 100644 index 0000000..639db3e --- /dev/null +++ b/include/lib/net/ethernet.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __ETHERNET_H__ +#define __ETHERNET_H__ + +#include +#include + +#include "callbacks.h" +#include "xp.h" + +__BEGIN_DECLS + +#define ETHERTYPE_ARP 0x806 +#define ETHERTYPE_IPV4 0x800 + +#define ETHERNET_OFFSET 14 + +int registerEtherTypeHandler(int type,callback_handler cb); +int unregisterEtherTypeHandler(int id); + +int add_eth_and_transmit(mymbuf_t *,char *dstmac,int ethertype); + +void ethernet_init(void); +void ethernet_uninit(void); +void ethernet_workloop(struct callout *c, void *param); +void ethernet_input(mymbuf_t *inputbuf); + +__END_DECLS + +#endif diff --git a/include/lib/net/icmp.h b/include/lib/net/icmp.h new file mode 100644 index 0000000..ba2131d --- /dev/null +++ b/include/lib/net/icmp.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __ICMP_H___ +#define __ICMP_H__ + +#include +#include "callbacks.h" + +__BEGIN_DECLS + +#define ICMP_ECHO 8 +#define ICMP_ECHOREPLY 0 + +int registerICMPHandler(int messagetype,callback_handler cb); +int unregisterICMPHandler(int id); + +int icmp_layer(bool on); + +__END_DECLS + +#endif diff --git a/include/lib/net/ipv4.h b/include/lib/net/ipv4.h new file mode 100644 index 0000000..32d35f8 --- /dev/null +++ b/include/lib/net/ipv4.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __IPV4_H__ +#define __IPV4_H__ + +#include +#include "callbacks.h" +#include "xp.h" + +__BEGIN_DECLS + +#define IPV4_ICMP 1 +#define IPV4_TCP 6 +#define IPV4_UDP 17 + +int ipv4_layer(bool on); +int registerIPV4Handler(int protocol,callback_handler handler); +int unregisterIPV4Handler(int id); + +uint32_t ipv4_get_ip(); +void ipv4_set_ip(uint32_t ip); + +int transmit_and_add_ipv4(mymbuf_t *mbuf,uint32_t dest,int protocol); + +__END_DECLS + +#endif diff --git a/include/lib/net/mbuf.h b/include/lib/net/mbuf.h new file mode 100644 index 0000000..91c947e --- /dev/null +++ b/include/lib/net/mbuf.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_NET_MBUF_H +#define __LIB_NET_MBUF_H + +#include + +__BEGIN_DECLS + +#define USE_BUILTIN_MBUF 1 +#if defined(USE_BUILTIN_MBUF) && USE_BUILTIN_MBUF +struct mbufentry; + +typedef struct mbufentry { + int flag; + int len; + char *data; + struct mbufentry *next; +} mbufentry_t; + +typedef struct mymbuf { + mbufentry_t *first; + int allocated_length; + int current_length; + char *primarydata; + int offset; +}mymbuf_t; +#else +#error "Unsupported platform" +#endif + +mymbuf_t * mbuf_initialize(int packetsize,int header,int trailer); +void mbuf_destroy(mymbuf_t *data); +char* mbuf_head(mymbuf_t *buffer, int len); +char* mbuf_tail(mymbuf_t *buffer, int len); +int mbuf_getlength(mymbuf_t *buffer); +char * mbuf_getlinear(mymbuf_t *buffer); +void mbuf_setlength(mymbuf_t *buffer,int len); +void mbuf_setoffset(mymbuf_t *buffer,int offset); +int mbuf_getallocatedlength(mymbuf_t *buffer); +int mbuf_copy(mymbuf_t *dest, const mymbuf_t *src); + +__END_DECLS + +#endif + diff --git a/include/lib/net/udp.h b/include/lib/net/udp.h new file mode 100644 index 0000000..7f90408 --- /dev/null +++ b/include/lib/net/udp.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __UDP_H__ +#define __UDP_H__ + +#include + +__BEGIN_DECLS + +int transmit_udp(mymbuf_t *data, uint32_t toip,int toport, int fromport); +int unregisterUDPHandler(int id); +int registerUDPHandler(int port,callback_handler cb); +int udp_layer(bool on); + + +typedef struct udpinfo { + uint32_t srcip; + uint16_t srcport; + uint16_t length; +} udpinfo_t; + +__END_DECLS + +#endif diff --git a/include/lib/net/xp.h b/include/lib/net/xp.h new file mode 100644 index 0000000..08ddae6 --- /dev/null +++ b/include/lib/net/xp.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __XP_H__ +#define __XP_H__ + +#include +#include +#include + +__BEGIN_DECLS + +//Card specific instructions. + +int xp_initialize(void); +int xp_getmac(uint8_t *addr); +void xp_packet_input(void *ethptr, mymbuf_t *inputbuf); +//mymbuf_t * xp_get_packet(mymbuf_t *); +int xp_transmit_packet(mymbuf_t *buffer); +#define htons(A) ( (((A) & 0xff00) >> 8) | \ + ((A) & 0x00ff) << 8) +#define htonl(A) ( (((A) & 0xff000000) >> 24) | \ + (((A) & 0x00ff0000) >> 8) | \ + (((A) & 0x0000ff00) << 8) | \ + (((A) & 0x000000ff) << 24)) +#define ntohs htons +#define ntohl htonl + +__END_DECLS + +#endif diff --git a/include/lib/nonce.h b/include/lib/nonce.h new file mode 100644 index 0000000..1c0a88d --- /dev/null +++ b/include/lib/nonce.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2012, 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _NONCE_H_ +#define _NONCE_H_ + +// ============================================================================= + +#include +#include + +#if HASH_OUTPUT_SIZE > 32 // Bytes +#define NONCE_HASH_OUTPUT_SIZE (32) +#else +#define NONCE_HASH_OUTPUT_SIZE HASH_OUTPUT_SIZE +#endif + +int mobile_ap_nonce_consume_nonce(uint64_t *nonce); + +#endif /* _NONCE_H_ */ diff --git a/include/lib/nvram.h b/include/lib/nvram.h new file mode 100644 index 0000000..467077e --- /dev/null +++ b/include/lib/nvram.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_NVRAM_H +#define __LIB_NVRAM_H + +#include +#include + +__BEGIN_DECLS + +int nvram_load(void); +int nvram_save(void); // write out the environment +int nvram_set_panic(const void *base, size_t length); // copy panic log to staging +int nvram_update_devicetree(dt_node_t *node, const char *propname); // copy nvram content to devicetree + +__END_DECLS + +#endif + diff --git a/include/lib/paint.h b/include/lib/paint.h new file mode 100644 index 0000000..4bc38e8 --- /dev/null +++ b/include/lib/paint.h @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_PAINT_H +#define __LIB_PAINT_H + +#include +#include +#include + +__BEGIN_DECLS + +enum colorspace { + CS_4BPP, + CS_8BPP, + CS_RGB332, + CS_RGB565, + CS_ARGB1555, + CS_ARGB4444, + CS_RGB888, + CS_ARGB8888, + CS_ARGB8101010, +}; + +#define ColorIndec4BPP(color) (0) +#define ColorIndex8BPP(color) (0) +#define ColorRGB332(color) (((color >> 6) & 0x03) | ((color >> 11) & 0x1C) | ((color >> 16) & 0xE0)) +#define ColorRGB565(color) (((color >> 3) & 0x001F) | ((color >> 5) & 0x07E0) | ((color >> 8) & 0xF800)) +#define ColorRGB555(color) (((color >> 3) & 0x001F) | ((color >> 6) & 0x03E0) | ((color >> 9) & 0x7C00)) +#define ColorRGB444(color) (((color >> 4) & 0x000F) | ((color >> 8) & 0x00F0) | ((color >> 12) & 0x0F00)) +#define ColorRGB888(color) (color & 0x00FFFFFF) +#define ColorRGB101010(color) (color & 0x3FFFFFFF) +#define ColorA8(color) ((color >> 32)& 0xFF) +#define RGB(r,g,b) (((uint32_t)((r) & 0xFF) << 16) | ((uint32_t)((g) & 0xFF) << 8) | ((uint32_t)((b) & 0xFF) << 0)) +#define RGB_MASK RBG(0xFF, 0xFF, 0xFF) +#define RGB_R(c) ((uint32_t)(((c) >> 16) & 0xFF)) +#define RGB_G(c) ((uint32_t)(((c) >> 8) & 0xFF)) +#define RGB_B(c) ((uint32_t)(((c) >> 0) & 0xFF)) +#define RGB10(r,g,b) (((uint32_t)((r) & 0x3FF) << 20) | ((uint32_t)((g) & 0x3FF) << 10) | ((uint32_t)((b) & 0x3FF) << 0)) +#define RGB10_MASK RBG10(0x3FF, 0x3FF, 0x3FF) +#define RGB10_R(c) ((uint32_t)(((c) >> 20) & 0x3FF)) +#define RGB10_G(c) ((uint32_t)(((c) >> 10) & 0x3FF)) +#define RGB10_B(c) ((uint32_t)(((c) >> 0) & 0x3FF)) +#define DCLR_VERSION(major,minor) ((((major) & 0xFF) << 8) | (((minor) & 0xFF) << 0)) + +#define WpCl_Quotation_Denominator (16) + +#define MAX_NUM_PLANES_PER_CANVAS 2 + +struct syscfg_wpcl { + u_int32_t version; + u_int32_t red; + u_int32_t green; + u_int32_t blue; +}; + +union syscfg_DCLr_RGB { + u_int32_t rgb; + struct { + u_int8_t blue; + u_int8_t green; + u_int8_t red; + u_int8_t reserved; + } component; +}; + +typedef struct syscfg_DClr { + u_int8_t minor_version; + u_int8_t major_version; + u_int8_t reserved_2; + u_int8_t reserved_3; + + union syscfg_DCLr_RGB device_enclosure; + + union syscfg_DCLr_RGB cover_glass; + + u_int8_t reserved_C; + u_int8_t reserved_D; + u_int8_t reserved_E; + u_int8_t reserved_F; +} syscfg_DClr_t; + +typedef enum { + clrcColorUnknown = -1, + clrcColorBlack = 0, + clrcColorWhite = 1, + clrcColorRed = 2, + clrcColorSilver = 3, + clrcColorPink = 4, + clrcColorBlue = 5, + clrcColorYellow = 6, + clrcColorGold = 7, + clrcColorSparrow = 8, + clrcColorCount +} clrcColor; + +typedef struct syscfg_ClrC { + u_int8_t clrcColor; // clrcColor + u_int8_t reserved[15]; +} syscfg_ClrC_t; + +// Color remapping policy options a target may select +enum color_map_policy { + COLOR_MAP_POLICY_NONE, // Common remapping: No color remapping (legacy devices) + COLOR_MAP_POLICY_INVERT, // Common remapping: Invert colors +}; + +// Function pointer typedefs for color remappers. +typedef uint32_t (* map_color_t)(uint64_t color); // Target specific color remapping + +// Color remapping policy data +typedef struct color_policy { + enum color_map_policy policy_type; // Color remapping policy type + void *color_table; // Pointer to policy-specific color table (e.g., a color_policy_invert_t) + uint32_t color_count; // Number of entries in the color table + map_color_t map_color; // Pointer to color remapping function +} color_policy_t; + +// Color remapping table provided by the target for COLOR_MAP_POLICY_INVERT. +typedef struct color_policy_invert { + uint32_t cover_glass; // Cover glass color + bool invert; // Invert bg/fg colors if true +} color_policy_invert_t; + +struct plane { + enum colorspace cs; + void *fb_virt; + void * db_virt; //draw buffer, start: fb_virt + frame size, align to next 4K + u_int32_t plane_size; + u_int32_t pixel_size; + u_int32_t pixel_size_per_channel; + u_int32_t line_x; + u_int32_t width; + u_int32_t height; + u_int32_t stride; + void (* plot)(struct plane *p, u_int32_t x, u_int32_t y, uint64_t color); + u_int32_t (* get_pixel)(struct plane *p, u_int32_t x, u_int32_t y); + void (* hline)(struct plane *p, u_int32_t x, u_int32_t y, u_int32_t len, uint64_t color); + void (* vline)(struct plane *p, u_int32_t x, u_int32_t y, u_int32_t len, uint64_t color); +}; + +struct canvas { + enum colorspace cs; + struct plane planes[MAX_NUM_PLANES_PER_CANVAS]; + uint32_t num_of_active_planes; + void *fb_virt; + uintptr_t fb_phys; + u_int32_t x; + u_int32_t y; + map_color_t map_color; +}; + +int paint_init(void *window, addr_t scratch, size_t scratch_size); +int paint_set_bgcolor(uint16_t bg_red, uint16_t bg_green, uint16_t bg_blue); +int paint_set_picture_for_tag(u_int32_t image_tag); +int paint_set_picture_for_tag_list(u_int32_t image_tag, int image_offset, int image_count); +int paint_set_picture(struct image_info *pict_info); +int paint_set_picture_list(struct image_info *pict_info, int image_offset, int image_count); +int paint_set_picture_from_file(const char *path, uint32_t type); +int paint_update_image(void); + +void paint_install_gamma_table(u_int32_t display_id, + u_int32_t entries, + volatile u_int32_t *red_lut, + volatile u_int32_t *green_lut, + volatile u_int32_t *blue_lut); + +void paint_get_syscfg_wpcl(struct syscfg_wpcl *wpcl); + +color_policy_t *paint_color_map_init(enum colorspace cs); +bool paint_color_map_enable(bool enable); +bool paint_color_map_is_desired(void); +bool paint_color_map_is_enabled(void); +bool paint_color_map_is_invalid(void); +enum color_map_policy paint_get_color_policy(void); +int paint_color_map_get_DClr(syscfg_DClr_t *DClr, size_t size, bool report); + +int paint_displaytest(void); + +struct canvas *get_canvas(void); +void set_canvas(struct canvas *c, void *fb, size_t region_size, uint32_t x, uint32_t y, uint32_t line_x, enum colorspace cs); +void move_canvas(struct canvas *c, void *fb); + +struct plane *get_plane(uint32_t plane_num); + +void plot(struct plane *p, u_int32_t x, u_int32_t y, uint64_t color); +u_int32_t get_pixel(struct plane *p, u_int32_t x, u_int32_t y); +void fill_rect(struct canvas *c, u_int32_t top_x, u_int32_t top_y, u_int32_t w, u_int32_t h, uint64_t color); + + +void display_paint_information(); +void display_paint_canvas(); +void display_paint_plane(uint32_t plane_num); +__END_DECLS + +#endif /* __LIB_PAINT_H */ diff --git a/include/lib/paniclog.h b/include/lib/paniclog.h new file mode 100644 index 0000000..d3c5f13 --- /dev/null +++ b/include/lib/paniclog.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_PANICLOG_H +#define __LIB_PANICLOG_H + +#include + +__BEGIN_DECLS + +void clear_panic_region(unsigned char pattern); +int save_panic_log(void); // move panic log from RAM to NVRAM + +__END_DECLS + +#endif + diff --git a/include/lib/partition.h b/include/lib/partition.h new file mode 100644 index 0000000..4a4ee4f --- /dev/null +++ b/include/lib/partition.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_PARTITION_H +#define __LIB_PARTITION_H + +#include +#include + +__BEGIN_DECLS + +int partition_scan_and_publish_subdevices(const char *dev_name); + +__END_DECLS + +#endif diff --git a/include/lib/pki.h b/include/lib/pki.h new file mode 100644 index 0000000..50820cc --- /dev/null +++ b/include/lib/pki.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_PKI_H +#define __LIB_PKI_H + +#include + +__BEGIN_DECLS + +int verify_signature_with_chain( + void *chain_blob, size_t chain_blob_length, + void *sig_blob, size_t sig_blob_len, + void *hash_blob, size_t hash_blob_len, + void **img3_spec_blob, size_t *img3_spec_blob_len, + void **ticket_spec_blob, size_t *ticket_spec_blob_len); + +__END_DECLS + +#endif diff --git a/include/lib/profile.h b/include/lib/profile.h new file mode 100644 index 0000000..2a76ad6 --- /dev/null +++ b/include/lib/profile.h @@ -0,0 +1,52 @@ +#ifndef __PROFILE_H +#define __PROFILE_H + +#if WITH_PROFILE + +#include +#include + +struct profile_event { + uint32_t time; + addr_t pc; + uint32_t data1; + uint32_t data2; +}; + +struct profile_buffer { + uint32_t magic; + uint32_t count; + uint32_t pc_bytes; + uint32_t timer_ticks_per_sec; + struct profile_event events[]; +}; + +#define PROFILE_2(_data1, _data2) \ + do { \ + addr_t current_pc = 0; \ + __asm__ volatile ("L_%=: adr %0, L_%=" : "=r"(current_pc)); \ + profile(current_pc, (_data1), (_data2)); \ + } while(0) + +#define PROFILE_INIT() profile_init() +#define PROFILE_HANDOFF() profile_handoff() + +#else // !WITH_PROFILE + +#define PROFILE_2(data1, data2) do {} while(0) +#define PROFILE_INIT() do {} while(0) +#define PROFILE_HANDOFF() do {} while(0) + +#endif + +#define PROFILE_1(data1) PROFILE_2((data1), 0) +#define PROFILE() PROFILE_2(0, 0) +#define PROFILE_ENTER(tag) PROFILE_2(((tag) & 0xFFFFFF) | ('<' << 24), 0) +#define PROFILE_EXIT(tag) PROFILE_2(((tag) & 0xFFFFFF) | ('>' << 24), 0) + +void profile_init(void); +void profile(addr_t pc, uint32_t data1, uint32_t data2); +void profile_relocate(void); +void profile_handoff(void); + +#endif diff --git a/include/lib/ramdisk.h b/include/lib/ramdisk.h new file mode 100644 index 0000000..ab13e08 --- /dev/null +++ b/include/lib/ramdisk.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _RAMDISK_H +#define _RAMDISK_H + +#include + +extern int ramdisk_init(void); +extern int load_ramdisk_file(const char *path); +extern int load_ramdisk(addr_t *ramdisk_addr, size_t *ramdisk_size); + +#endif /* _RAMDISK_H */ diff --git a/include/lib/random.h b/include/lib/random.h new file mode 100644 index 0000000..9377c33 --- /dev/null +++ b/include/lib/random.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __LIB_RANDOM_H +#define __LIB_RANDOM_H + +#include + +__BEGIN_DECLS + +// Fills the provided buffer with random data +int random_get_bytes(u_int8_t *buffer, size_t length); +int random_get_bytes_noheap(uint8_t *buffer, size_t length, void *entropy_buffer, size_t entropy_buffer_size); + +#if DEBUG_BUILD +// Fills the provided buffer with random data +// Allows setting the entropy ratio +// This is for debug only +int random_get_bytes_debug(u_int8_t *buffer, size_t length, u_int32_t entropy_ratio); +#endif + +__END_DECLS + +#endif /* __LIB_RANDOM_H */ diff --git a/include/lib/syscfg.h b/include/lib/syscfg.h new file mode 100644 index 0000000..ec18826 --- /dev/null +++ b/include/lib/syscfg.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* + * Read-only support for iPod-style SysCfg data. + */ + +#ifndef __SYSCFG_H +#define __SYSCFG_H + +#include + +__BEGIN_DECLS + +/* where we expect to find the magic number in a bdev */ +#define kSysCfgBdevOffset 0x4000 + +struct syscfgEntry { + u_int32_t seTag; + u_int8_t seData[16]; +}; + +struct syscfgEntryCNTB { + u_int32_t seTag; /* 'CTNB' */ + u_int32_t seRealTag; + u_int32_t seDataSize; + u_int32_t seDataOffset; + u_int32_t reserved; +}; + +struct syscfgMemEntry { + u_int32_t seTag; + u_int8_t seData[16]; + u_int32_t seDataSize; + u_int32_t seDataOffset; +}; + +/* + * Attempt to initialise SysCfg from (bdevName) + * + * Returns true if successful. + */ +bool syscfgInitWithBdev(const char *bdevName); + +/* + * Copy the data for an entry by tag + * + * Look up the provided tag, then copy the upto the size + * bytes into buffer. + * + * Returns -1 if the tag was not found, or the number of bytes copied. + */ +int syscfgCopyDataForTag(u_int32_t tag, u_int8_t *buffer, size_t size); + +/* + * Look up an entry by tag. + * + * Returns false if the tag was not found. If the tag was found, returns true + * and copies the tag's entry into the provided pointer.. + */ +bool syscfgFindByTag(u_int32_t tag, struct syscfgMemEntry *entry); + +/* + * Look up an entry by index. + * + * Returns a pointer to a statically-allocated internal buffer, which + * will remain valid until the next call to syscfgFindByTag or syscfgFindByIndex. + * + * Returns NULL if the index was not found or not valid. + * Returns false if the index was not found or not valid. If the index was found, + * returns true and copies the tag's entry into the provided pointer.. + */ +bool syscfgFindByIndex(u_int32_t index, struct syscfgMemEntry *result); + +/* + * Gets a pointer to the data associated with an entry returned by + * syscfgFindByTag or syscfgFindByIndex + * + * Returns NULL if the entry was invalid + */ +void * syscfgGetData(struct syscfgMemEntry *entry); + +/* + * Gets the size in bytes of the data associated with an entry returned by + * syscfgFindByTag or syscfgFindByIndex + */ +uint32_t syscfgGetSize(struct syscfgMemEntry *entry); + +/* Returns true if the tag is found and populates the given pointers if they are non-NULL */ +bool syscfg_find_tag(uint32_t tag, void **data_out, uint32_t *size_out); + +__END_DECLS + +#endif diff --git a/include/lib/tftp.h b/include/lib/tftp.h new file mode 100644 index 0000000..e9f22b0 --- /dev/null +++ b/include/lib/tftp.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIB_TFTP_H +#define __LIB_TFTP_H + +#include + +__BEGIN_DECLS + +int tftp_transfer(const char *filename, uint32_t ipaddr, char *buffer, int *maxlen, bool write); + +__END_DECLS + +#endif + diff --git a/include/lib/ticket.h b/include/lib/ticket.h new file mode 100644 index 0000000..a1b42f5 --- /dev/null +++ b/include/lib/ticket.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TICKET_H +#define TICKET_H + +#include + +#if 1 +#define TICKETLOG(x, ...) +#else +#define TICKETLOG_ENABLED 1 +#define TICKETLOG(x, ...) printf("%s: " x "\n", __FUNCTION__, ## __VA_ARGS__ ) +#endif + +bool ticket_validation_required(); + +bool ticket_get_hash( uint8_t *buffer, size_t length ); + +int ticket_load(); + +int ticket_load_file( const char *filePath, uintptr_t bufferAddress, size_t bufferLength ); + +bool ticket_validate_image3( uint32_t type, uint32_t expectedType, uint8_t *hashBuffer, size_t hashBufferSize, bool *outIsUntrusted ); + +int ticket_set( const uint8_t *buffer, size_t length, bool isRestore, size_t *outTicketLength ); + +#endif /* TICKET_H */ diff --git a/include/libkern/OSByteOrder.h b/include/libkern/OSByteOrder.h new file mode 100644 index 0000000..40ca6ef --- /dev/null +++ b/include/libkern/OSByteOrder.h @@ -0,0 +1,10 @@ +#ifndef __OSBYTEORDER_H_ +#define __OSBYTEORDER_H_ + +/* This is a horrible hack; remove this header as soon as libcorecrypto stops including it. + */ + +#define OSSwapHostToBigInt32(x) ((uint32_t)(x)) +#define OSSwapHostToBigInt(x) OSSwapHostToBigInt32(x) + +#endif /* __OSBYTEORDER_H_ */ diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000..d142b5f --- /dev/null +++ b/include/list.h @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __LIST_H +#define __LIST_H + +#include +#include + +__BEGIN_DECLS + +#define containerof(ptr, type, member) \ + ((type *)((addr_t)(ptr) - offsetof(type, member))) + +struct list_node { + struct list_node *prev; + struct list_node *next; +}; + +#define LIST_INITIAL_VALUE(list) (struct list_node){ &(list), &(list) } + +static inline void list_initialize(struct list_node *list) +{ + list->prev = list->next = list; +} + +static inline void list_clear_node(struct list_node *item) +{ + item->prev = item->next = 0; +} + +static inline bool list_in_list(struct list_node *item) +{ + if (item->prev == 0 && item->next == 0) + return false; + else + return true; +} + +static inline void list_add_head(struct list_node *list, struct list_node *item) +{ + if (list->next == NULL || list->prev == NULL || list->next->prev != list || list->prev->next != list) + panic("linked list item %p corrupted", list); + item->next = list->next; + item->prev = list; + list->next->prev = item; + list->next = item; +} + +#define list_add_after(entry, new_entry) list_add_head(entry, new_entry) + +static inline void list_add_tail(struct list_node *list, struct list_node *item) +{ + if (list->next == NULL || list->prev == NULL || list->next->prev != list || list->prev->next != list) + panic("linked list item %p corrupted", list); + item->prev = list->prev; + item->next = list; + list->prev->next = item; + list->prev = item; +} + +#define list_add_before(entry, new_entry) list_add_tail(entry, new_entry) + +static inline void list_delete(struct list_node *item) +{ + if (item->next == NULL || item->prev == NULL || item->next->prev != item || item->prev->next != item) + panic("linked list item %p corrupted", item); + item->next->prev = item->prev; + item->prev->next = item->next; + item->prev = item->next = 0; +} + +static inline struct list_node* list_remove_head(struct list_node *list) +{ + if(list->next != list) { + struct list_node *item = list->next; + list_delete(item); + return item; + } else { + return NULL; + } +} + +#define list_remove_head_type(list, type, element) ({\ + struct list_node *__nod = list_remove_head(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_remove_tail(struct list_node *list) +{ + if(list->prev != list) { + struct list_node *item = list->prev; + list_delete(item); + return item; + } else { + return NULL; + } +} + +#define list_remove_tail_type(list, type, element) ({\ + struct list_node *__nod = list_remove_tail(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_peek_head(struct list_node *list) +{ + if(list->next != list) { + return list->next; + } else { + return NULL; + } +} + +#define list_peek_head_type(list, type, element) ({\ + struct list_node *__nod = list_peek_head(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_peek_tail(struct list_node *list) +{ + if(list->prev != list) { + return list->prev; + } else { + return NULL; + } +} + +#define list_peek_tail_type(list, type, element) ({\ + struct list_node *__nod = list_peek_tail(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_next(struct list_node *list, struct list_node *item) +{ + if(item->next != list) + return item->next; + else + return NULL; +} + +#define list_next_type(list, item, type, element) ({\ + struct list_node *__nod = list_next(list, item);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_next_wrap(struct list_node *list, struct list_node *item) +{ + if(item->next != list) + return item->next; + else if(item->next->next != list) + return item->next->next; + else + return NULL; +} + +#define list_next_wrap_type(list, item, type, element) ({\ + struct list_node *__nod = list_next_wrap(list, item);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +// iterates over the list, node should be struct list_node* +#define list_for_every(list, node) \ + for(node = (list)->next; node != (list); node = node->next) + +// iterates over the list in a safe way for deletion of current node +// node and temp_node should be struct list_node* +#define list_for_every_safe(list, node, temp_node) \ + for(node = (list)->next, temp_node = (node)->next;\ + node != (list);\ + node = temp_node, temp_node = (node)->next) + +// iterates over the list, entry should be the container structure type * +#define list_for_every_entry(list, entry, type, member) \ + for((entry) = containerof((list)->next, type, member);\ + &(entry)->member != (list);\ + (entry) = containerof((entry)->member.next, type, member)) + +// iterates over the list in a safe way for deletion of current node +// entry and temp_entry should be the container structure type * +#define list_for_every_entry_safe(list, entry, temp_entry, type, member) \ + for(entry = containerof((list)->next, type, member),\ + temp_entry = containerof((entry)->member.next, type, member);\ + &(entry)->member != (list);\ + entry = temp_entry, temp_entry = containerof((temp_entry)->member.next, type, member)) + +static inline bool list_is_empty(struct list_node *list) +{ + return (list->next == list) ? true : false; +} + +__END_DECLS + +#endif diff --git a/include/non_posix_types.h b/include/non_posix_types.h new file mode 100644 index 0000000..0a361ad --- /dev/null +++ b/include/non_posix_types.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +/** + * \file non_posix_types.h + */ + +#ifndef __NON_POSIX_TYPES_H +#define __NON_POSIX_TYPES_H + +#include + +typedef uint64_t utime_t; +#define INFINITE_UTIME 0xffffffffffffffffULL + +#if defined(__LP64__) +typedef uint64_t addr_t; +#else +typedef uint32_t addr_t; +#endif + +#define MB 0x100000 + +/* just to make NAND code happy */ +typedef int8_t Int8; +typedef int16_t Int16; +typedef int32_t Int32; +typedef int64_t Int64; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +#endif /* __NON_POSIX_TYPES_H */ diff --git a/include/platform.h b/include/platform.h new file mode 100644 index 0000000..68f3e60 --- /dev/null +++ b/include/platform.h @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_H +#define __PLATFORM_H + +/* Define a macro to construct an include path for a sub-platform file. + * Example: #include SUB_PLATFORM_HEADER(pinconfig) + * (where PLATFORM_NAME_UNQUOTED is s5l8999x) + * Expands: #include + */ +#define NOQUOTE(x) x +#define COMBINE3(a,b,c) NOQUOTE(a)NOQUOTE(b)NOQUOTE(c) +#define COMBINE5(a,b,c,d,e) NOQUOTE(a)NOQUOTE(b)NOQUOTE(c)NOQUOTE(d)NOQUOTE(e) +#define SUB_PLATFORM_HEADER(x) +#define SUB_PLATFORM_SOC_HEADER(x) +#define SUB_PLATFORM_SPDS_HEADER(x) +#define SUB_PLATFORM_TARGET_HEADER(x) +#define SUB_PLATFORM_TUNABLE_HEADER(x) + +#ifndef __ASSEMBLY__ + +#include +#include +#include + + +__BEGIN_DECLS + +int platform_early_init(void); +int platform_init(void); +int platform_late_init(void); +int platform_init_hwpins(void); +int platform_init_internal_mem(void); +int platform_init_mainmem(bool resume); +void platform_init_mainmem_map(void); +int platform_init_display(void); +int platform_init_display_mem(addr_t *base, size_t *size); +int platform_init_setup_clocks(void); +int platform_init_power(void); +int platform_init_mass_storage(void); +int platform_init_mass_storage_panic(void); +int platform_init_nmi(void (* handler)(void *), void *arg); +void platform_mmu_setup(bool resume); +int platform_init_usb(); + +int platform_debug_init(void); /* called whenever the system goes into debug mode (command prompt) */ + +void platform_poweroff(void) __noreturn; /* do whatever is needed to power off the device */ +void platform_reset(bool panic) __noreturn; +void platform_system_reset(bool panic) __noreturn; +void platform_halt(void); +void platform_deep_idle(void); +void platform_watchdog_tickle(void); + +void platform_not_supported(void) __noreturn; + +/* + * Cache management operations. + * + * A length of zero indicates that the entire cache should be the target of the operation. + */ +#define CACHE_CLEAN (1<<0) +#define CACHE_INVALIDATE (1<<1) +#define CACHE_DRAIN_WRITE_BUFFER (1<<2) +#define CACHE_PANIC (1<<3) /* do cache operations appropriate for panic path */ +#define CACHE_ICACHE (1<<16) /* DCACHE is the default */ +void platform_cache_operation(int operation, void *address, u_int32_t length); +void platform_memory_barrier(void); + +int platform_quiesce_hardware(enum boot_target target); +int platform_quiesce_display(void); +int platform_bootprep(enum boot_target target); +void platform_set_boot_clocks(enum boot_target target); + +int platform_update_device_tree(void); + +bool platform_get_raw_production_mode(void); +bool platform_get_current_production_mode(void); +void platform_clear_production_mode(); +bool platform_get_secure_mode(void); +u_int32_t platform_get_fuse_modes(void); +u_int32_t platform_get_iboot_flags(void); +u_int32_t platform_get_security_domain(void); +#define kPlatformSecurityDomainManufacturing 0 +#define kPlatformSecurityDomainDarwin 1 +u_int32_t platform_get_security_epoch(void); +u_int32_t platform_get_hardware_epoch(void); +u_int64_t platform_get_nonce(void); +int32_t platform_get_sep_nonce(u_int8_t *nonce); +bool platform_get_core_idle_enable(void); +bool platform_get_ecid_image_personalization_required(void); +u_int32_t platform_get_board_id(void); +u_int32_t platform_get_chip_id(void); +u_int32_t platform_get_chip_revision(void); +u_int64_t platform_get_ecid_id(void); +u_int64_t platform_get_die_id(void); +uint32_t platform_get_fuse_revision(void); +u_int32_t platform_get_boot_config(void); +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, + u_int32_t *boot_flag, u_int32_t *boot_arg); +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, + u_int32_t boot_arg); +int32_t platform_get_boot_manifest_hash(uint8_t *boot_manifest_hash); +int32_t platform_set_boot_manifest_hash(const uint8_t *boot_manifest_hash); +bool platform_get_mix_n_match_prevention_status(void); +void platform_set_mix_n_match_prevention_status(bool); +void platform_sidp_set_rom_manifest(const uint32_t *manifest_hash, size_t manifest_hash_size); +void platform_sidp_lock_rom_manifest(void); +bool platform_sidp_rom_manifest_locked(void); +void platform_sidp_set_boot_manifest(const uint32_t *manifest_hash, size_t manifest_hash_size); +void platform_sidp_lock_boot_manifest(void); +bool platform_sidp_boot_manifest_locked(void); +void platform_sidp_set_mix_n_match(void); +bool platform_get_lock_fuses_required(void); +u_int32_t platform_get_entropy(void); +u_int64_t platform_consume_nonce(void); +bool platform_is_pre_lpddr4(void); +u_int64_t platform_get_memory_size(void); +void platform_set_memory_info(u_int8_t manuf_id, u_int64_t memory_size); +void platform_set_memory_info_with_revids(uint8_t manuf_id, uint64_t memory_size, uint8_t rev_id, uint8_t rev_id2); +u_int8_t platform_get_memory_manufacturer_id(void); +const char *platform_get_memory_manufacturer_string(void); +void platform_get_memory_rev_ids(uint8_t *rev_id, uint8_t *rev_id2); +u_int16_t platform_get_usb_vendor_id(void); +u_int16_t platform_get_usb_product_id(void); +u_int16_t platform_get_usb_device_version(void); +const char *platform_get_usb_manufacturer_string(void); +const char *platform_get_usb_product_string(void); +const char *platform_get_usb_serial_number_string(bool full); +const char *platform_get_usb_more_other_string(bool full); +u_int32_t platform_get_osc_frequency(void); +u_int32_t platform_get_spi_frequency(void); +u_int32_t platform_get_base_soc_voltage(void); +u_int32_t platform_get_base_cpu_voltage(void); +u_int32_t platform_get_base_ram_voltage(void); +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages); +int platform_get_cpu_voltages(u_int32_t count, u_int32_t *voltages); +int platform_get_cpu_ram_voltages(u_int32_t count, u_int32_t *voltages); +int platform_get_cpu_min_voltages(u_int32_t count, u_int32_t *voltages); +int platform_get_ram_voltages(u_int32_t count, u_int32_t *voltages); +int platform_get_gpu_ram_voltages(u_int32_t count, u_int32_t *voltages); +int platform_get_gpu_voltages(u_int32_t count, u_int32_t *voltages); +int platform_convert_voltages(int buck, u_int32_t count, u_int32_t *voltages); +int platform_get_dwi_to_mv(int buck, u_int32_t dwival); +bool platform_get_usb_cable_connected(void); +void platform_set_dfu_status(bool dfu); +bool platform_get_force_dfu(void); +bool platform_get_request_dfu1(void); // Formerly platform_get_hold_key() +bool platform_get_request_dfu2(void); // Formerly platform_get_menu_key() +bool platform_get_dock_connect(); +void platform_set_dock_attention(bool); +uint32_t platform_get_apcie_lane_cfg(void); +uint32_t platform_get_pcie_link_width(uint32_t link); +uint32_t platform_get_pcie_l1ss_ltr_threshold(void); +uint32_t platform_get_pcie_l1ss_t_common_mode(void); +const uint32_t *platform_get_default_gpio_cfg(uint32_t gpioc); +int platform_translate_key_selector(u_int32_t key_selector, u_int32_t *key_opts); +bool platform_provide_spec_blob(const void *common_name, const size_t common_name_length, + const void *serial_number, const size_t serial_number_length, + void **spec_blob, size_t *spec_blob_length); +const char *platform_get_product_id(void); +void platform_set_consistent_debug_root_pointer(uint32_t root); + +enum { kUSB_DP = 1, kUSB_DM = 2, kUSB_NONE = 0, kUSB_DCD = 3, kUSB_CP1 = 4, kUSB_CP2 = 5 }; +bool platform_set_usb_brick_detect(int); + +void platform_disable_keys(u_int32_t gids, u_int32_t uids); +bool platform_keys_disabled(u_int32_t gid, u_int32_t uid); + +void platform_demote_production(); + +#define kPerformanceHigh 0 +#define kPerformanceMedium 1 +#define kPerformanceLow 2 +#define kPerformanceMemory 3 +#define kPerformanceMemoryFull kPerformanceMemory +#define kPerformanceMemoryLow 4 +#define kPerformanceMemoryMid1 5 +#define kPerformanceMemoryMid2 6 +#define kPerformanceMemoryMid kPerformanceMemoryMid2 + +u_int32_t platform_set_performance(u_int32_t performance_level); +uintptr_t platform_map_pci_to_host_addr(uint64_t addr); +uint64_t platform_map_host_to_pci_addr(uintptr_t addr); +void platform_register_pci_busses(void); +void platform_setup_default_environment(void); + +/* EmbeddedIOP platform interfaces */ +void platform_init_iop_doorbell(void (* handler)(void *arg), void *arg); +void platform_ring_host_doorbell(void); +void platform_mask_doorbell(void); +void platform_unmask_doorbell(void); + +#if SUPPORT_SLEEP +#define SLEEP_MAGIC_NOT_ASLEEP 0xffffffff +#define SLEEP_MAGIC_WAKEY_WAKEY 0 +extern u_int32_t arch_sleep_magic; +void platform_wakeup(void); +#endif +void platform_sleep(void); + +// Valid flags for Platform Scratch Memory +#define kPlatformScratchFlagBootStrap (1 << 0) +#define kPlatformScratchFlagNonce (1 << 1) +#define kPlatformScratchFlagMemoryInfo (1 << 2) // current allocation - lower 16 bits: memory size , top 4 bits: vendor id, remaining 12 bits: reserved + // this doesn't apply to H4P. For H4P: all 32 bits allocated for memory size +#define kPlatformScratchFlagVerifyManifestHash (1 << 3) // per Image4 spec, section 2.7.3: tells next stage if its required to verify manifest hash or not +#define kPlatformScratchFlagObjectManifestHashValid (1 << 4) // tells next stage if a valid object manifest hash is passed forward + +void platform_asynchronous_exception(); + +void platform_adjust_memory_layout(void); + +int32_t platform_restore_system(void); + +typedef enum { + kMemoryRegion_StorageProcessor, + kMemoryRegion_ConsistentDebug, + kMemoryRegion_SleepToken, + kMemoryRegion_DramConfig, + kMemoryRegion_Panic, + kMemoryRegion_Display, + kMemoryRegion_Heap, + kMemoryRegion_Stacks, + kMemoryRegion_PageTables, + kMemoryRegion_iBoot, + kMemoryRegion_Kernel, + kMemoryRegion_Monitor, + kMemoryRegion_SecureProcessor, + kMemoryRegion_AOP, + kMemoryRegion_Reconfig, + kMemoryRegion_NumberOfRegions, +} memory_region_type_t; + +uintptr_t platform_get_memory_region_base(memory_region_type_t region); +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region); +size_t platform_get_memory_region_size(memory_region_type_t region); +size_t platform_get_memory_region_size_optional(memory_region_type_t region); +size_t platform_get_display_memory_size(void); + +void platform_dockfifo_access_enable(uint32_t enable_flags); + +void *platform_get_boot_trampoline(void); + + +#if PRODUCT_IBEC || PRODUCT_IBOOT +// Breadcrumbing API's: + +static inline void platform_init_breadcrumbs(void) // Initializes breadcrumbing subsystem. Calling multiple times has no effect. All other breadcrumb API's are no-op until initialization. +{ + extern void _platform_init_breadcrumbs_internal(void); + + _platform_init_breadcrumbs_internal(); +} +static inline void platform_record_breadcrumb(const char* key, const char* val) // Record a key-value breadcrumb +{ + extern void _platform_record_breadcrumb_internal(const char* key, const char* val); + + _platform_record_breadcrumb_internal(key, val); +} +static inline void platform_record_breadcrumb_int(const char* key, int val) // Record an key-integer breadcrumb +{ + extern void _platform_record_breadcrumb_int_internal(const char* key, int val); + _platform_record_breadcrumb_int_internal(key, val); +} +static inline void platform_record_breadcrumb_marker(const char* val) // Records a string marker breadcrumb +{ + extern void _platform_record_breadcrumb_marker_internal(const char* val); + _platform_record_breadcrumb_marker_internal(val); +} +static inline void platform_commit_breadcrumbs(const char* envvar) // Commits the breadcrumb to a NVRAM variable specified by envvar +{ + extern void _platform_commit_breadcrumbs_internal(const char* envvar); + _platform_commit_breadcrumbs_internal(envvar); +} +#else +// Breadcrumbing stubs for unrelated boot stages +static inline void platform_init_breadcrumbs(void) {} +static inline void platform_record_breadcrumb(const char* key __unused, const char* val __unused) {} +static inline void platform_record_breadcrumb_int(const char* key __unused, int val __unused) {} +static inline void platform_record_breadcrumb_marker(const char* val __unused) {} +static inline void platform_commit_breadcrumbs(const char* envvar __unused) {} +#endif + + + +__END_DECLS + +#endif // __ASSEMBLY__ +#endif diff --git a/include/platform/breadcrumbs.h b/include/platform/breadcrumbs.h new file mode 100644 index 0000000..576ee8f --- /dev/null +++ b/include/platform/breadcrumbs.h @@ -0,0 +1,37 @@ +#ifndef __BREADCRUMBS_H +#define __BREADCRUMBS_H + +#define kBCImgLoadImageTooLarge 1 +#define kBCImgLoadCountNotZero 2 +#define kBCImgLoadCountIsZero 3 + +#define kBCImg4TooLarge 1 +#define kBCImg4NullPtr 2 +#define kBCImg4HeaderErr 3 +#define kBCImg4Truncated 4 +#define kBCImg4DecodeInitFail 5 +#define kBCImg4ImageTypeMismatch 6 +#define kBCImg4ManifestInvalid 7 +#define kBCImg4TrustEvalFail 8 +#define kBCImg4BootManifestFail 9 +#define kBCImg4ProdStatusMismatch 10 +#define kBCImg4SecureModeMismatch 11 +#define kBCImg4PayloadDecodeFail 12 +/* gonna skip this value given my luck with OTA changes */ +#define kBCImg4PayloadDecryptFail 14 + + +#define kBCImg3TooLarge 1 +#define kBCImg3NullPtr 2 +#define kBCImg3BDEVReadFail 3 +#define kBCImg3BadMagic 4 +#define kBCImg3UnknownPrivateMagic 5 +#define kBCImg3InstantiationFailed 6 +#define kBCImg3UnacceptedType 7 +#define kBCImg3SignatureValidationFail 8 +#define kBCImg3ConstraintValidationFail 9 +#define kBCImg3GetTagStructFailed 10 +#define kBCImg3DecryptFailed 11 + + +#endif \ No newline at end of file diff --git a/include/platform/chipid.h b/include/platform/chipid.h new file mode 100644 index 0000000..703d65c --- /dev/null +++ b/include/platform/chipid.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_CHIPID_H +#define __PLATFORM_CHIPID_H + +#include + +__BEGIN_DECLS + +#define CHIP_REVISION_A0 0x00 +#define CHIP_REVISION_A1 0x01 +#define CHIP_REVISION_B0 0x10 +#define CHIP_REVISION_B1 0x11 +#define CHIP_REVISION_C0 0x20 +#define CHIP_REVISION_C1 0x21 + +bool chipid_get_production_mode(void); +bool chipid_get_current_production_mode(void); +bool chipid_get_raw_production_mode(void); +void chipid_clear_production_mode(void); +bool chipid_get_secure_mode(void); +u_int32_t chipid_get_security_domain(void); +u_int32_t chipid_get_minimum_epoch(void); +u_int32_t chipid_get_board_id(void); +u_int32_t chipid_get_chip_id(void); +u_int32_t chipid_get_chip_revision(void); +u_int32_t chipid_get_osc_frequency(void); +u_int64_t chipid_get_ecid_id(void); +u_int64_t chipid_get_die_id(void); +uint32_t chipid_get_fuse_revision(void); +bool chipid_get_fuse_lock(void); +void chipid_set_fuse_lock(bool locked); +bool chipid_get_fuse_seal(void); +u_int32_t chipid_get_memory_density(void); +u_int32_t chipid_get_memory_manufacturer(void); +u_int32_t chipid_get_memory_ranks(void); +u_int32_t chipid_get_memory_width(void); +bool chipid_get_memory_dqcal(u_int32_t *cal_data); +u_int32_t chipid_get_package_id(void); +bool chipid_get_read_done(void); + +uint32_t chipid_get_pid(void); + +__END_DECLS + +#endif /* __PLATFORM_CHIPID_H */ + diff --git a/include/platform/clocks.h b/include/platform/clocks.h new file mode 100644 index 0000000..a422509 --- /dev/null +++ b/include/platform/clocks.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_CLOCKS_H +#define __PLATFORM_CLOCKS_H + +#include + +__BEGIN_DECLS + +/* generic clock descriptors */ +#define CLK_CPU 0 +#define CLK_PERIPH 1 +#define CLK_MEM 2 +#define CLK_BUS 3 +#define CLK_FIXED 4 +#define CLK_TIMEBASE 5 +#define HWCLOCK_BASE 6 + +void clock_get_frequencies(u_int32_t *clocks, u_int32_t count); +u_int32_t clock_get_frequency(int clock); +void clock_set_frequency(int clock, u_int32_t divider, u_int32_t pll_p, u_int32_t pll_m, u_int32_t pll_s, u_int32_t pll_t); +u_int32_t clocks_get_performance_divider(void); +void clock_gate(int device, bool enable); +void power_on(int device); +void clock_reset_device(int device); +void clock_set_device_reset(int device, bool set); +bool clock_get_pcie_refclk_good(void); + +void platform_diag_gate_clocks(void); + +int clocks_init(void); +int clocks_set_default(void); +void clocks_quiesce(void); +u_int32_t clocks_set_performance(u_int32_t performance_level); + +__END_DECLS + +#endif /* ! __PLATFORM_CLOCKS_H */ diff --git a/include/platform/gpio.h b/include/platform/gpio.h new file mode 100644 index 0000000..aca75ab --- /dev/null +++ b/include/platform/gpio.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __PLATFORM_GPIO_H +#define __PLATFORM_GPIO_H + +#include + +__BEGIN_DECLS + +typedef uint32_t gpio_t; + +// Macro trickery to allow specifying GPIOs as either port and pin (Samsung GPIO style) +// or by ID number (Apple GPIO controller) +// For compatiblity reasons, the Apple GPIO controller driver expects the packing of the +// ID number to skip bits 4-7 +#define GPIO_PORT_PIN(port, pin) ((gpio_t)(((port) & 0xFF) << 8) | ((pin) & 0xFF)) +#define GPIO_COMPAT_SELECT(_1, _2, NAME, ...) NAME +#define GPIO(...) GPIO_COMPAT_SELECT(__VA_ARGS__, GPIO_PORT_PIN, GPIO_ID)(__VA_ARGS__) + +#define GPIOC(controller, port, pin) ((gpio_t)(((controller) & 0xFF) << 24) | (((port) & 0xFF) << 8) | ((pin) & 0xFF)) +#define GPIO_ID(gpio_id) (GPIO_PORT_PIN(((gpio_id) / 8), ((gpio_id) % 8))) +#define GPIO_PORT(gpio) (((gpio) >> 8) & 0xFF) +#define GPIO_PIN(gpio) ((gpio) & 0xFF) + +#define GPIOC_0 (0) +#define GPIOC_1 (1) + +#define GPIO_NONE (0xFFFFFFFF) + +#define GPIO_CFG_IN 0 +#define GPIO_CFG_OUT 1 +#define GPIO_CFG_OUT_0 2 +#define GPIO_CFG_OUT_1 3 +#define GPIO_CFG_DFLT 4 +#define GPIO_CFG_FUNC0 5 +#define GPIO_CFG_FUNC1 6 +#define GPIO_CFG_FUNC2 7 +#define GPIO_CFG_FUNC(_n) (GPIO_CFG_FUNC0 + (_n)) +#define GPIO_CFG_MAX GPIO_CFG_FUNC(16) + +#define GPIO_NO_PUPDN (0) +#define GPIO_PUP (1) +#define GPIO_PUP_STRONG (2) +#define GPIO_PDN (-1) + +#define GPIO_DRIVE_X1 (0) +#define GPIO_DRIVE_X2 (1) +#define GPIO_DRIVE_X3 (2) +#define GPIO_DRIVE_X4 (3) +#define GPIO_DRIVE_X6 (4) + +#define GPIO_DRIVE_S0 (0) +#define GPIO_DRIVE_S1 (1) +#define GPIO_DRIVE_S2 (2) +#define GPIO_DRIVE_S3 (3) +#define GPIO_DRIVE_S4 (4) +#define GPIO_DRIVE_S5 (5) +#define GPIO_DRIVE_S6 (6) +#define GPIO_DRIVE_S7 (7) +#define GPIO_DRIVE_S8 (8) +#define GPIO_DRIVE_S9 (9) +#define GPIO_DRIVE_S10 (10) +#define GPIO_DRIVE_S11 (11) +#define GPIO_DRIVE_S12 (12) +#define GPIO_DRIVE_S13 (13) +#define GPIO_DRIVE_S14 (14) +#define GPIO_DRIVE_S15 (15) + +int gpio_init_pinconfig(void); /* set up default pin configuration */ +int gpio_init_memory(uint32_t drive_strength); +int gpio_diag_pinconfig(void); /* set up pins for diag use */ +uint32_t gpio_read(gpio_t gpio); +void gpio_write(gpio_t gpio, uint32_t val); +void gpio_configure(gpio_t gpio, uint32_t config); +void gpio_configure_pupdn(gpio_t gpio, int32_t pupdn); +void gpio_fixup_pinconfig(const uint32_t *fixup_list); +uint32_t gpio_get_board_id(void); + +#define gpio_configure_in(gpio) gpio_configure((gpio), GPIO_CFG_IN) +#define gpio_configure_out(gpio, val) gpio_configure((gpio), (val) ? GPIO_CFG_OUT_1 : GPIO_CFG_OUT_0); + +__END_DECLS + +#endif diff --git a/include/platform/int.h b/include/platform/int.h new file mode 100644 index 0000000..9ea7135 --- /dev/null +++ b/include/platform/int.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __PLATFORM_INT_H +#define __PLATFORM_INT_H + +#include + +__BEGIN_DECLS + +/* interrupt controller */ +int interrupt_init(void); +void interrupt_mask_all(void); +void unmask_int(uint32_t vector); +void mask_int(uint32_t vector); + +/* optional for platforms requiring polling masked interrupts */ +bool test_int(uint32_t vector); + +int eint_init(void); +void eint_mask_all(void); +void unmask_eint(uint32_t eint, uint32_t vector); +void mask_eint(uint32_t eint, uint32_t vector); +void eint_trig(uint32_t eint, uint32_t vector, uint32_t trig); +void eint_pol(uint32_t eint, uint32_t vector, uint32_t trig); + +#define INT_TYPE_IRQ 0 +#define INT_TYPE_FIQ 1 +#define INT_TYPE_LEVEL 0 +#define INT_TYPE_EDGE 2 + +void set_int_type(uint32_t vector, int type); +typedef void (*int_handler)(void *arg); +int install_int_handler(uint32_t vector, int_handler handler, void *arg); +int install_eint_handler(uint32_t eint, uint32_t vector, int_handler handler, void *arg); + +struct interrupt_entry { + int_handler handler; + void *arg; + bool edge; + bool int_mask_requested; /* interrupt controller client requested interrupt mask state */ +}; + +/* interprocessor interrupts */ +void interrupt_generate_ipc(uint32_t vector); +void interrupt_clear_ipc(uint32_t vector); + +/* interrupt routines */ +void platform_irq(void); +void platform_fiq(void); + +__END_DECLS + +#endif + diff --git a/include/platform/memmap_defaults.h b/include/platform/memmap_defaults.h new file mode 100644 index 0000000..17512ce --- /dev/null +++ b/include/platform/memmap_defaults.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_MEMMAP_DEFAULTS_H +#define __PLATFORM_MEMMAP_DEFAULTS_H + +// Defines for the default load areas +#define DEFAULT_LOAD_ADDRESS (INSECURE_MEMORY_BASE) +#if SDRAM_LEN >= (1*1024*1024*1024) +# define DEFAULT_LOAD_SIZE (0x10000000ULL) +#else +# define DEFAULT_LOAD_SIZE (0x04000000ULL) +#endif +#define DEFAULT_KERNEL_ADDRESS (DEFAULT_LOAD_ADDRESS + DEFAULT_LOAD_SIZE) +#define DEFAULT_KERNEL_SIZE (0x03F00000ULL) +#define DEFAULT_DEVICETREE_ADDRESS (DEFAULT_KERNEL_ADDRESS + DEFAULT_KERNEL_SIZE) +#define DEFAULT_DEVICETREE_SIZE (0x00100000ULL) +#define DEFAULT_RAMDISK_ADDRESS (DEFAULT_DEVICETREE_ADDRESS + DEFAULT_DEVICETREE_SIZE) +#define DEFAULT_RAMDISK_SIZE (DEFAULT_LOAD_SIZE) +#define DEFAULT_FREE_ADDRESS (DEFAULT_RAMDISK_ADDRESS + DEFAULT_RAMDISK_SIZE) + +#endif /* __PLATFORM_MEMMAP_DEFAULTS_H */ diff --git a/include/platform/miu.h b/include/platform/miu.h new file mode 100644 index 0000000..9d64ecf --- /dev/null +++ b/include/platform/miu.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MIU_H +#define __PLATFORM_MIU_H + +#include + +__BEGIN_DECLS + +int miu_init(void); +int miu_initialize_dram(bool resume); +int miu_initialize_internal_ram(void); +void miu_suspend(void); + +__END_DECLS + +#endif diff --git a/include/platform/pmgr.h b/include/platform/pmgr.h new file mode 100644 index 0000000..3cd631c --- /dev/null +++ b/include/platform/pmgr.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_PMGR_H +#define __PLATFORM_PMGR_H + +#include + +enum pmgr_binning_type_t { + PMGR_BINNING_NONE = 0, + PMGR_BINNING_CPU, + PMGR_BINNING_CPU_SRAM, + PMGR_BINNING_GPU, + PMGR_BINNING_GPU_SRAM, + PMGR_BINNING_SRAM, + PMGR_BINNING_SOC, + PMGR_BINNING_BASE, + PMGR_BINNING_REV, + PMGR_BINNING_GROUP, + PMGR_BINNING_END_OF_LIST, +}; + +#define PMGR_BINNING_GROUP_ALL 0xf +#define PMGR_BINNING_NOTFOUND UINT32_MAX +#define PMGR_BINNING_MODE_NONE 0x3f + +struct pmgr_binning_fuse_to_register { + uint32_t binning_low:12; + uint32_t binning_high:12; + uint32_t register_low:6; + uint32_t register_64bit:1; + uint64_t register_address; +}; + +struct pmgr_binning_mode_to_fuse { + enum pmgr_binning_type_t type; + uint32_t mode:16; + uint32_t bingroup:16; + uint32_t low:11; + uint32_t high:11; + const struct pmgr_binning_fuse_to_register *fuse_to_register; +}; + +struct pmgr_binning_mode_to_const { + uint32_t mv:12; + uint32_t mode:4; + uint32_t type:4; + uint32_t bingroup:4; + uint32_t fuse_revision_minimum:8; +}; + +struct pmgr_binning_voltage_config { + uint32_t safe_voltage:11; + uint32_t mode:6; + uint32_t type:4; +}; + +struct pmgr_binning_voltage_index_to_config { + uint32_t voltage_index:8; + uint32_t safe_voltage:11; + uint32_t mode:6; + uint32_t type:4; + uint32_t bingroup:4; + uint32_t fuse_revision_minimum:8; +}; + +struct pmgr_binning_voltage_index_to_offset { + uint32_t voltage_index:8; + uint32_t fuse_revision_minimum:8; + int32_t offset:15; +}; + +struct pmgr_binning_board_id_to_offsets { + enum pmgr_binning_type_t type; + const struct pmgr_binning_voltage_index_to_offset *voltage_offsets; + uint32_t size:5; + uint32_t chip_rev_min:8; + uint32_t board_id:5; + uint32_t bingroup; +}; + +struct pmgr_binning_vol_adj { + uint64_t volAdj0:20; + uint64_t volAdj1:20; + uint64_t volAdj2:20; + uint64_t volAdj3:20; + uint64_t dvfmMaxAdj:20; + uint64_t dvmrAdj0:20; + uint64_t dvmrAdj1:20; + uint64_t dvmrAdj2:20; +}; + +struct __attribute__((packed)) pmgr_binning_voltadj_entry { + uint32_t voltage_index:8; + uint32_t chip_rev_min:8; + uint32_t fuse_rev_min:8; + struct pmgr_binning_vol_adj voltages; +}; + +// +// Must be defined in platform/SOC/chipid/pmgr_binning_SOC.c +// +extern const struct pmgr_binning_mode_to_fuse pmgr_binning_mode_to_fuse_data[]; +extern const struct pmgr_binning_voltage_config pmgr_binning_voltage_config_sram_data[]; +extern const struct pmgr_binning_mode_to_const pmgr_binning_mode_to_const_data[]; +extern const struct pmgr_binning_voltadj_entry pmgr_binning_voltadj_entry_data[]; +extern const struct pmgr_binning_voltage_index_to_config pmgr_binning_voltage_index_to_config_data[]; +extern const struct pmgr_binning_voltage_index_to_offset pmgr_binning_voltage_index_to_offset_data[]; +extern const struct pmgr_binning_board_id_to_offsets pmgr_binning_board_id_to_offsets_data[]; +extern const uint32_t pmgr_binning_voltage_config_sram_data_size; +extern const uint32_t pmgr_binning_mode_to_const_data_size; +extern const uint32_t pmgr_binning_voltadj_entry_data_size; +extern const uint32_t pmgr_binning_voltage_index_to_config_data_size; +extern const uint32_t pmgr_binning_board_id_to_offsets_data_size; + +// +// Must be defined in platform/SOC/pmgr/pmgr.c +// +extern bool pmgr_platform_set_perf_state(bool gpu, uint32_t state_num, uint32_t *voltage_indexes, uint32_t voltage_index_size); +extern uint32_t pmgr_platform_get_freq(bool gpu, uint32_t voltage_index); +extern bool pmgr_platform_get_perf_state(enum pmgr_binning_type_t type, uint32_t state, uint32_t *voltage, uint32_t *freq); + +// +// Defined in platform/generic/pmgr/pmgr_binning.c +// +// Return values are PMGR_BINNING_NOTFOUND if not found/unknown +// +extern uint32_t pmgr_binning_get_mv(uint32_t voltage_index, bool sram, bool use_binning); +extern uint32_t pmgr_binning_mode_get_mv(enum pmgr_binning_type_t type, uint32_t mode); +extern uint32_t pmgr_binning_mode_get_value(enum pmgr_binning_type_t binning_type, uint32_t mode); +extern uint32_t pmgr_binning_get_base(void); +extern uint32_t pmgr_binning_get_group(void); +extern uint32_t pmgr_binning_get_revision(void); +extern uint32_t pmgr_binning_from_config_data(uint32_t voltage_index, const struct pmgr_binning_voltage_index_to_config **config_data); +extern int32_t pmgr_binning_get_voltage_offset(uint32_t voltage_index, enum pmgr_binning_type_t type); +extern const struct pmgr_binning_vol_adj *pmgr_binning_get_vol_adj(uint32_t chipdid, uint32_t chip_rev, uint32_t voltage_index); + +// +// Defined in platform/generic/pmgr/pmgr_binning_menu.c +// +extern void pmgr_binning_menu_update_states(void); + +#endif diff --git a/include/platform/power.h b/include/platform/power.h new file mode 100644 index 0000000..3f02eaa --- /dev/null +++ b/include/platform/power.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_POWER_H +#define __PLATFORM_POWER_H + +#include + +__BEGIN_DECLS + +void platform_power_init(void); +void platform_power_spin(u_int32_t usecs); + +#if WITH_HW_POWER_GATING + +#include + +void platform_power_set_gate(uint32_t device, bool state); + +#else /* ! WITH_HW_POWER_GATING */ + +#define PWRBIT_ALL (0) +#define PWRBIT_OFF_DEFAULT (0) +#define PWRBIT_OFF_DIAG (0) + +#define platform_power_set_gate(device, state) + +#endif /* WITH_HW_POWER_GATING */ + +__END_DECLS + +#endif /* ! __PLATFORM_POWER_H */ diff --git a/include/platform/timer.h b/include/platform/timer.h new file mode 100644 index 0000000..1ece2f6 --- /dev/null +++ b/include/platform/timer.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TIMER_H +#define __PLATFORM_TIMER_H + +#include + +__BEGIN_DECLS + +/* + * One-time timer initialisation. + */ +int timer_init(u_int32_t timer); + +/* + * Returns the current time in ticks. + */ +u_int64_t timer_get_ticks(void); + +/* + * Returns the tick rate per second. + */ +u_int32_t timer_get_tick_rate(void); + +/* + * Returns the number of microseconds that are equivalent to number of ticks passed in. + */ +utime_t timer_ticks_to_usecs(u_int64_t ticks); + +/* + * Returns the number of ticks that are equivalent to number of microseconds passed in. + */ +u_int64_t timer_usecs_to_ticks(utime_t usecs); + +/* + * Registers a single callback at (at_ticks). + * + * Passing NULL will delete the current callback. + */ +void timer_deadline_enter(u_int64_t at_ticks, void (* callback)(void)); + +/* + * Stop all timers; used when shutting down or handing off to another image. + */ +void timer_stop_all(void); + +/* + * Return a word containing entropy. + */ +u_int32_t timer_get_entropy(void); + +void wdt_enable(void); +void wdt_system_reset(void); +void wdt_chip_reset(void); + + +/****************************************** + Wrapper MACRO for a Register Spin-Loop with Time-Out + */ +#define SPIN_TIMEOUT_WHILE(__expr,__max) \ + do { \ + bool __tmo = false; \ + uint64_t __start = timer_get_ticks(); \ + for (;;) { \ + if ((timer_get_ticks() - __start) >= __max) \ + __tmo = true; \ + if (!(__expr)) \ + break; \ + if (USE_TMO_IN_REGSPIN_LOOP && __tmo) \ + panic("%s:%d spin loop has timed out", \ + __FILE__, __LINE__); \ + } \ + } while (0) + +// If this is ZERO, there will be no Time-Out nor panic +#define USE_TMO_IN_REGSPIN_LOOP 1 + +// Standard Timeout is 1 second +#define SPIN_W_TMO_WHILE(__expr) SPIN_TIMEOUT_WHILE(__expr, 1000000) +#define SPIN_W_TMO_UNTIL(__expr) SPIN_W_TMO_WHILE(!(__expr)) + +__END_DECLS + +#endif + diff --git a/include/platform/tunables.h b/include/platform/tunables.h new file mode 100644 index 0000000..962aaa5 --- /dev/null +++ b/include/platform/tunables.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_TUNABLES_H +#define __PLATFORM_SOC_TUNABLES_H + +#include + +struct __attribute__((packed)) tunable_struct { + int32_t offset:27; + int32_t size:5; + uint32_t mask; + uint32_t value; +}; + +struct __attribute__((packed)) tunable_struct64 { + int32_t offset:27; + int32_t size:5; + uint64_t mask; + uint64_t value; +}; + +struct tunable_struct_unpacked { + int32_t offset; + int32_t size; + uint64_t mask; + uint64_t value; +}; + +struct tunable_chip_struct { + uint32_t chip_rev; + uint64_t base_address; + const struct tunable_struct *tunable; + const struct tunable_struct64 *tunable64; + bool reconfig; +}; + +struct tunable_filtered_chip_struct { + uint32_t chip_rev; + uint32_t starting_address; + uint32_t ending_address; + bool cold_boot; + bool reconfig; +}; + +struct tunable_chip_array { + const struct tunable_chip_struct *tunable_chip; + size_t num_tunable_chips; + uintptr_t dt_base; +}; + +#define TUNABLE_TABLE_END_MARKER { -1, -1, -1, -1 } + +void platform_apply_tunables(const struct tunable_chip_struct *tunable_chips, + uint32_t num_tunable_chips, const char* type); + +uint8_t *platform_apply_dt_tunables(const struct tunable_chip_struct *tunable_chips, + uint32_t num_tunable_chips, uint8_t *buffer, + uintptr_t dt_base, const char *type); +#endif + diff --git a/include/posix/ctype.h b/include/posix/ctype.h new file mode 100644 index 0000000..7baa555 --- /dev/null +++ b/include/posix/ctype.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include diff --git a/include/posix/errno.h b/include/posix/errno.h new file mode 100644 index 0000000..9124358 --- /dev/null +++ b/include/posix/errno.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include diff --git a/include/posix/machine/endian.h b/include/posix/machine/endian.h new file mode 100644 index 0000000..e77621a --- /dev/null +++ b/include/posix/machine/endian.h @@ -0,0 +1 @@ +#define BYTE_ORDER LITTLE_ENDIAN diff --git a/include/posix/stdbool.h b/include/posix/stdbool.h new file mode 100644 index 0000000..b6096df --- /dev/null +++ b/include/posix/stdbool.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef _STDBOOL_H_ +#define _STDBOOL_H_ + +#if !defined(__cplusplus) + +#define false 0 +#define true 1 + +#define bool _Bool +#if __STDC_VERSION__ < 199901L && __GNUC__ < 3 +typedef int _Bool; +#endif + +#endif /* !defined(__cplusplus) */ + +#endif /* _STDBOOL_H_ */ \ No newline at end of file diff --git a/include/posix/stdint.h b/include/posix/stdint.h new file mode 100644 index 0000000..5ea9af5 --- /dev/null +++ b/include/posix/stdint.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include diff --git a/include/posix/stdio.h b/include/posix/stdio.h new file mode 100644 index 0000000..7baa555 --- /dev/null +++ b/include/posix/stdio.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include diff --git a/include/posix/stdlib.h b/include/posix/stdlib.h new file mode 100644 index 0000000..7baa555 --- /dev/null +++ b/include/posix/stdlib.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include diff --git a/include/posix/string.h b/include/posix/string.h new file mode 100644 index 0000000..7baa555 --- /dev/null +++ b/include/posix/string.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include diff --git a/include/posix/sys/cdefs.h b/include/posix/sys/cdefs.h new file mode 100644 index 0000000..e49d33a --- /dev/null +++ b/include/posix/sys/cdefs.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include + +/* Mimic'ing definition in xnu */ +#define __DARWIN_C_FULL 900000L +#define __DARWIN_C_LEVEL __DARWIN_C_FULL diff --git a/include/posix/sys/errno.h b/include/posix/sys/errno.h new file mode 100644 index 0000000..18d32d8 --- /dev/null +++ b/include/posix/sys/errno.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ +/* + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)errno.h 8.5 (Berkeley) 1/21/94 + */ + +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +#include + +/* + * Error codes + */ + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* Device not configured */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EDEADLK 11 /* Resource deadlock avoided */ + /* 11 was EAGAIN */ +#define ENOMEM 12 /* Cannot allocate memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device / Resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* Operation not supported by device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ + +/* math software */ +#define EDOM 33 /* Numerical argument out of domain */ +#define ERANGE 34 /* Result too large */ + +/* non-blocking and interrupt i/o */ +#define EAGAIN 35 /* Resource temporarily unavailable */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ + +/* ipc/network software -- argument errors */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define ENOTSUP 45 /* Operation not supported */ + +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Can't assign requested address */ + +/* ipc/network software -- operational errors */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Network dropped connection on reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Socket is already connected */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define ETOOMANYREFS 59 /* Too many references: can't splice */ +#define ETIMEDOUT 60 /* Operation timed out */ +#define ECONNREFUSED 61 /* Connection refused */ + +#define ELOOP 62 /* Too many levels of symbolic links */ +#define ENAMETOOLONG 63 /* File name too long */ + +/* should be rearranged */ +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#define ENOTEMPTY 66 /* Directory not empty */ + +/* quotas & mush */ +#define EPROCLIM 67 /* Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Disc quota exceeded */ + +/* Network File System */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Too many levels of remote in path */ +#define EBADRPC 72 /* RPC struct is bad */ +#define ERPCMISMATCH 73 /* RPC version wrong */ +#define EPROGUNAVAIL 74 /* RPC prog. not avail */ +#define EPROGMISMATCH 75 /* Program version wrong */ +#define EPROCUNAVAIL 76 /* Bad procedure for program */ + +#define ENOLCK 77 /* No locks available */ +#define ENOSYS 78 /* Function not implemented */ + +#define EFTYPE 79 /* Inappropriate file type or format */ +#define EAUTH 80 /* Authentication error */ +#define ENEEDAUTH 81 /* Need authenticator */ + +/* Intelligent device errors */ +#define EPWROFF 82 /* Device power is off */ +#define EDEVERR 83 /* Device error, e.g. paper out */ + +#define EOVERFLOW 84 /* Value too large to be stored in data type */ + +/* Program loading errors */ +#define EBADEXEC 85 /* Bad executable */ +#define EBADARCH 86 /* Bad CPU type in executable */ +#define ESHLIBVERS 87 /* Shared library version mismatch */ +#define EBADMACHO 88 /* Malformed Macho file */ + +#define ECANCELED 89 /* Operation canceled */ + +#define EIDRM 90 /* Identifier removed */ +#define ENOMSG 91 /* No message of desired type */ +#define EILSEQ 92 /* Illegal byte sequence */ +#define ENOATTR 93 /* Attribute not found */ + +#define EBADMSG 94 /* Bad message */ +#define EMULTIHOP 95 /* Reserved */ +#define ENODATA 96 /* No message available on STREAM */ +#define ENOLINK 97 /* Reserved */ +#define ENOSR 98 /* No STREAM resources */ +#define ENOSTR 99 /* Not a STREAM */ +#define EPROTO 100 /* Protocol error */ +#define ETIME 101 /* STREAM ioctl timeout */ + +#define EOPNOTSUPP 102 /* Operation not supported on socket */ + +#define ENOPOLICY 103 /* No such policy registered */ + +#define ELAST 103 /* Must be equal largest errno */ + +#endif /* _SYS_ERRNO_H_ */ diff --git a/include/posix/sys/types.h b/include/posix/sys/types.h new file mode 100644 index 0000000..4404c84 --- /dev/null +++ b/include/posix/sys/types.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __TYPES_H +#define __TYPES_H + +/////////////////////////////////////////////// +// cdefs.h +/////////////////////////////////////////////// +#if defined(__cplusplus) + +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } + +#define NULL 0 + +#else /* !defined(__cplusplus) */ + +#define __BEGIN_DECLS +#define __END_DECLS + +#define NULL ((void *)0) + +#endif /* defined(__cplusplus) */ + +/////////////////////////////////////////////// +// bsd/arm/types.h +/////////////////////////////////////////////// + +typedef __signed char int8_t; +typedef unsigned char u_int8_t; +typedef short int16_t; +typedef unsigned short u_int16_t; +typedef int int32_t; +typedef unsigned int u_int32_t; +typedef long long int64_t; +typedef unsigned long long u_int64_t; + +#if __LP64__ +typedef int64_t register_t; +#else +typedef int32_t register_t; +#endif + +typedef long intptr_t; +typedef unsigned long uintptr_t; + +#if defined(__SIZE_TYPE__) +typedef __SIZE_TYPE__ size_t; /* sizeof() */ +#else +typedef unsigned long size_t; /* sizeof() */ +#endif +typedef long ssize_t; +#if defined(__PTRDIFF_TYPE__) +typedef __PTRDIFF_TYPE__ ptrdiff_t; /* ptr1 - ptr2 */ +#else +typedef int ptrdiff_t; /* ptr1 - ptr2 */ +#endif +typedef int64_t off_t; +typedef long time_t; +#define INFINITE_TIME 0xffffffffUL + +/////////////////////////////////////////////// +// stdint.h +/////////////////////////////////////////////// + +/* from ISO/IEC 988:1999 spec */ + +/* 7.18.1.1 Exact-width integer types */ +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; +typedef u_int64_t uint64_t; + +/* 7.18.2.1 Limits of exact-width integer types */ +#define INT8_MIN (-127-1) +#define INT16_MIN (-32767-1) +#define INT32_MIN (-2147483647-1) +#define INT64_MIN (-9223372036854775807LL-1LL) + +#define INT8_MAX +127 +#define INT16_MAX +32767 +#define INT32_MAX +2147483647 +#define INT64_MAX +9223372036854775807LL + +#define UINT8_MAX 255 +#define UINT16_MAX 65535 +#define UINT32_MAX 4294967295U +#define UINT64_MAX 18446744073709551615ULL + +/* 7.18.2.4 Limits of integer types capable of holding object pointers */ + +#if __LP64__ +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#else +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#endif + +#if __LP64__ +#define UINTPTR_MAX UINT64_MAX +#else +#define UINTPTR_MAX UINT32_MAX +#endif + +/* 7.18.3 "Other" */ +#if __LP64__ +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX +#else +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX +#endif + +#if __LP64__ +#define SIZE_MAX UINT64_MAX +#else +#define SIZE_MAX UINT32_MAX +#endif + +/////////////////////////////////////////////// +// libkern/libkern/OSTypes.h +/////////////////////////////////////////////// +typedef unsigned char UInt8; +typedef unsigned short UInt16; +typedef unsigned int UInt32; +typedef unsigned long long UInt64; + +typedef signed char SInt8; +typedef signed short SInt16; +typedef signed int SInt32; +typedef signed long long SInt64; + +#include +#include + +#endif /* __TYPES_H */ diff --git a/include/sys.h b/include/sys.h new file mode 100644 index 0000000..464049b --- /dev/null +++ b/include/sys.h @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +/** + * \file sys.h + */ + +/** + * \defgroup API Application Programming Interfaces + * \defgroup SPI System Private Interfaces + */ + +#ifndef __SYS_H +#define __SYS_H + +#include +#include +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +/** + * Formats and displays the supplied message, then stops the system. + * + * The message is formatted by printf, and all formats are supported. + * + * \ingroup API + */ +#if NO_PANIC_STRINGS +# define panic(x...) _panic("", "") +#elif TERSE_PANIC_STRINGS +# define panic(x...) _panic("", "%llx:%d", DEBUG_FILE_HASH, __LINE__) +#else +# define panic(x...) _panic(__func__, x) +#endif + +extern char *gPanicStr; /**< pointer to panic string if panicking \ingroup API*/ +extern const char *gPanicFunc; /**< pointer to function name if panicking \ingroup API*/ + +/** \implements panic \ingroup SPI */ +void _panic(const char *func, const char *fmt, ...) __noreturn; + +/** performs minimal system quiesce and then stops the system \ingroup SPI */ +void halt(void) __noreturn; + +/** + * \def PANIC_HOOK + * Panic hooks + * + * Invoked when the system panics. Hook functions should avoid use of + * system facilities, in particular anything involving interrupts or + * task functions. + * + * \note panic hooks are invoked one at a time in no particular order. + * \ingroup API + */ +#if WITH_PANIC_HOOKS +struct panic_hook +{ + void (*func)(void *arg); /**< the called function */ + void *arg; /**< passed to the called function */ +}; + +# define PANIC_HOOK(_name, _func, _arg) \ + static const struct panic_hook __attribute__((used)) \ + __panic_hook_ ## _name = { \ + _func, \ + _arg \ + }; \ + LINKER_SET_ENTRY(panic_hooks, __panic_hook_ ## _name) +#else +# define PANIC_HOOK(_name, _func, _arg) \ + struct hack +#endif + +/* debug i/o routines */ +extern int DebugUartReady; /**< bits set indicate UARTs ready for debug use \ingroup SPI */ + +/** + * \defgroup debug Debugging Support + * \ingroup SPI + */ + +/** + * initialise debug output + * + * \ingroup debug + */ +void debug_init(void); + +/** + * enable debug output via UART + * + * \param[in] debug_uarts the UART channels to enable + * \ingroup debug + */ +void debug_enable_uarts(int debug_uarts); + +/** + * emit one character to the debug console + * + * \param[in] c the character to be emitted + * \ingroup debug + */ +void debug_putchar(int c); + +/** + * get one character from the debug console + * + * \return the character read + * \ingroup debug + */ +int debug_getchar(void); + +/** + * get one character from the debug console without waiting + * + * \return the character read or -1 if no character is waiting + * \ingroup debug + */ +int debug_getchar_nowait(void); + +/** + * push a character into the input queue + * + * \param[in] c the character to be pushed + * \ingroup debug + */ +int debug_pushchar(int c); + +/** + * run a canned script + * + * \param[in] addr the address of a NUL-terminated buffer containing the script + * \ingroup debug + */ +int debug_run_script(const char *addr); + +#if WITH_APPLICATION_PUTCHAR +/** + * passes a character being output to the debug console on to the application + * + * \note This function is implemented by the application. + * \param[in] c the character being output + * \ingroup debug + */ +void application_putchar(int c); +#endif + +/** + * \defgroup critical_sections Critical Sections + * \ingroup API + */ + +/** + * \fn enter_critical_section + * Enters a critical section, disabling interrupts if they are enabled. + * \ingroup critical_sections + */ +/** + * \fn exit_critical_section + * Exits a critical section, re-enableing interrupts if this is the outermost nested section. + * \ingroup critical_sections + */ +#if DEBUG_CRITICAL_SECTIONS +# define enter_critical_section() _enter_critical_section(__FUNCTION__) +# define exit_critical_section() _exit_critical_section(__FUNCTION__) +void _enter_critical_section(const char *caller); /**< \implements enter_critical_section \ingroup SPI */ +void _exit_critical_section(const char *caller); /**< \implements exit_critical_section \ingroup SPI */ +#else +void enter_critical_section(void); +void exit_critical_section(void); +#endif + +/* the following are only used in interrupt handler glue */ +void _irq_enter_critical_section(void); /**< \ingroup SPI */ +void _irq_exit_critical_section(void); /**< \ingroup SPI */ + +/** + * \defgroup time Time + * \ingroup API + */ + +/** + * \return system uptime in microseconds. + * \ingroup time + */ +utime_t system_time(void); + +/** + * pause for a specified period + * + * \note the system may enter a power-saving mode while waiting + * + * \param[in] usecs time to wait before returning + * \ingroup time + */ +void spin(utime_t usecs); + +/** + * test whether the specified time interval has elapsed + * + * \return true if the interval has elapsed + * \param[in] start_time the value returned by system_time at the start of the interval + * \param[in] timeout the interval duration in microseconds + * \ingroup time + */ +bool time_has_elapsed(utime_t start_time, utime_t timeout); + +/** + * \return calendar time in microseconds since midnight, January 1, 1970 + * \ingroup time + */ +utime_t calendar_time(void); + +/* system initialization */ +void sys_init(void); /**< \ingroup SPI */ +void sys_setup_default_environment(void); /**< \ingroup SPI */ +void sys_load_environment(void); /**< \ingroup SPI */ + +/** + * Initialize stack cookies. + * + * \note Must be called from a stack frame that will never return + * by conventional methods (i.e., return statement or falling + * through the final closing brace). + * \ingroup SPI + */ +void sys_init_stack_cookie(void); + +/** + * \defgroup memory_mapping Memory Mapping + * \ingroup API + */ + +/** + * Structure describing static memory mappings. + * + * This must be defined by the platform. The array is terminated + * by an entry with a length of zero. + * + * If a mapping does not exist with a particular attribute, + * set the field to MAP_NO_ENTRY. + */ +struct mem_static_map_entry { + addr_t cached_base; + addr_t uncached_base; + addr_t physical_base; + size_t size; +}; + +#define MAP_NO_ENTRY (~(uint32_t)0) /**< \ingroup memory_mapping */ +#define MAP_FAILED ((void *)~0) /**< \ingroup memory_mapping */ + +/** platform-defined memory mappings */ +extern struct mem_static_map_entry mem_static_map_entries[]; + +/** + * Finds the static cached mapping for a pointer. + * + * \return cached mapping + * \retval MAP_FAILED no cached mapping exists + * \ingroup memory_mapping + */ +void *mem_static_map_cached(uintptr_t ptr); + +/** + * Finds the static uncached mapping for a pointer. + * + * \return uncached mapping + * \retval MAP_FAILED no uncached mapping exists + * \ingroup memory_mapping + */ +void *mem_static_map_uncached(uintptr_t ptr); + +/** + * Finds the physical address as seen by a bus-master device for a pointer. + * + * \return the physical address the pointer refers to + * \retval MAP_NO_ENTRY there is no physical mapping for this pointer + * \ingroup memory_mapping + */ +uintptr_t mem_static_map_physical(uintptr_t ptr); + +__END_DECLS + +#endif diff --git a/include/sys/boot.h b/include/sys/boot.h new file mode 100644 index 0000000..8855d36 --- /dev/null +++ b/include/sys/boot.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __SYS_BOOT_H +#define __SYS_BOOT_H + +#include +#include + +__BEGIN_DECLS + +/* boot routines */ +enum boot_target { + BOOT_UNKNOWN = 0, + BOOT_HALT, + BOOT_IBOOT, + BOOT_DARWIN, // Darwin restore / boot + BOOT_DARWIN_RESTORE, // resume from RAM + BOOT_DIAGS, + BOOT_TSYS, + BOOT_SECUREROM, + BOOT_MONITOR, + BOOT_DALI, +}; + +/* boot devices */ +enum boot_device { + BOOT_DEVICE_NOR = 0, + BOOT_DEVICE_SPI, + BOOT_DEVICE_NAND, + BOOT_DEVICE_NVME, + BOOT_DEVICE_USBDFU, + BOOT_DEVICE_TBTDFU, + BOOT_DEVICE_XMODEM, +}; + +/* boot flags */ +#define BOOT_FLAG_TEST_MODE (1 << 0) + +void prepare_and_jump(enum boot_target, void *ptr, void *arg) __noreturn; + +/* routines to boot various systems */ +void find_boot_images(void); +int boot_diagnostics(void); +int boot_tsys(void); +int boot_iboot(void); +int mount_bootfs(void); +int mount_bootfs_from_device(const char *device); + +int mount_and_boot_system(void); +int mount_and_upgrade_system(void); +int boot_upgrade_system(void); +int restore_system(void); + +#if WITH_BOOT_STAGE +int boot_check_stage(void); +int boot_set_stage(uint8_t boot_stage); +void boot_check_panic(void); +int boot_clear_error_count(void); +int boot_error_count(uint32_t *boot_fail_count, uint32_t *panic_fail_count); +#endif + +__END_DECLS + +#endif diff --git a/include/sys/callout.h b/include/sys/callout.h new file mode 100644 index 0000000..4c71399 --- /dev/null +++ b/include/sys/callout.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __SYS_CALLOUT_H +#define __SYS_CALLOUT_H + +#include + +__BEGIN_DECLS + +struct callout; +typedef void (*callout_func)(struct callout *, void *); + +struct callout { + struct list_node list; + + /* scheduled time */ + uint64_t sched_ticks; + utime_t delay; + + /* callback and args */ + callout_func callback; + void *arg; +}; + +void callout_enqueue(struct callout *, utime_t delay, callout_func, void *arg); +int callout_dequeue(struct callout *); +int callout_reset(struct callout *, utime_t newdelay); // newdelay = 0 to reuse old delay +void callout_reset_deadline(void); + +__END_DECLS + +#endif + diff --git a/include/sys/hash.h b/include/sys/hash.h new file mode 100644 index 0000000..ff8fee5 --- /dev/null +++ b/include/sys/hash.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple, Inc. + */ +#ifndef __SYS_HASH_H +#define __SYS_HASH_H + +#include + +__BEGIN_DECLS + +#if WITH_SHA2_384 +#if !WITH_CORECRYPTO && !HOST_TEST +#error "WITH_SHA2_384 requires WITH_CORECRYPTO" +#endif + +#include + +#define HASH_OUTPUT_SIZE CCSHA384_OUTPUT_SIZE // bytes + +#else // Assume SHA1 + +#include + +#define HASH_OUTPUT_SIZE CCSHA1_OUTPUT_SIZE // bytes + +#endif + +void hash_calculate(const void *in_ptr, size_t in_len, void *out_ptr, size_t out_len); + +__END_DECLS + +#endif diff --git a/include/sys/linker_set.h b/include/sys/linker_set.h new file mode 100644 index 0000000..aeacc9f --- /dev/null +++ b/include/sys/linker_set.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +/* + * Linker sets. + */ + +#ifndef __LINKER_SET_H__ +#define __LINKER_SET_H__ + +#include + +/* + * Macro evil to generate the awkward Mach-O section specifier format. + * + * These macros should never be used outside this file. + * + * The end result is a line of the form + * + * void const *__set_<_set>_sym_<_sym> __attribute ((section("__Data,<_set>"))) = (void *)&<_sym> + */ +#ifndef __linux__ +# define __LS_VA_STRINGIFY(_x...) #_x +# define __LS_VA_STRCONCAT(_x,_y) __LS_VA_STRINGIFY(_x,_y) +# define __PUT_IN_SECTION(_seg, _sec) __attribute__ ((section(__LS_VA_STRCONCAT(_seg,_sec)))) +#else +# define __PUT_IN_SECTION(_seg, _sec) __attribute__ ((section (#_sec))) +#endif +#define __LINKER_MAKE_SET(_set,_sym) \ + void const *__set_##_set##_sym_##_sym \ + __PUT_IN_SECTION(__TEXT,_set) \ + __attribute__ ((used)) \ + = (void *) &_sym + +// The address sanitizer's metadata results in the size of each global being +// bloated by a factor of 8 +#if !__has_feature(address_sanitizer) +#define __LINKER_SET_STRIDE (1) +#else +#define __LINKER_SET_STRIDE (8) +#endif + +/* + * Public macros. + */ + +#define LINKER_SET_ENTRY(_set,_sym) __LINKER_MAKE_SET(_set,_sym) + +#define LINKER_SET_BEGIN(_set) __section_start(__TEXT, _set) +#define LINKER_SET_LIMIT(_set) __section_end(__TEXT, _set) + + +#define LINKER_SET_FOREACH(_pvar, _set) \ + for (_pvar = LINKER_SET_BEGIN(_set); \ + _pvar < LINKER_SET_LIMIT(_set); \ + _pvar += __LINKER_SET_STRIDE) + +#define LINKER_SET_ITEM(_set, _i) LINKER_SET_BEGIN(_set)[_i] + +#endif /* __LINKER_SET_H__ */ diff --git a/include/sys/menu.h b/include/sys/menu.h new file mode 100644 index 0000000..c409d76 --- /dev/null +++ b/include/sys/menu.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __SYS_MENU_H +#define __SYS_MENU_H + +#include +#include + +__BEGIN_DECLS + +struct cmd_arg { + int n; + size_t u; + size_t h; + bool b; + char *str; +}; + +typedef int (*cmd_func)(int argc, struct cmd_arg *args); + +struct cmd_menu_item { + const char *cmd; + cmd_func func; + const char *help; + void *meta; +}; + +extern utime_t gMenuLastActivityTime; +extern struct task_event gMenuTaskReadyEvent; + +bool process_command_line(char *line, int *last_command_rval); +int menu_task(void *arg); +char *menu_prompt(char *new_prompt); + +extern struct bgcolor g_bgcolor; + +/* + * New-style linker magic menu command registration. + */ +#include +#if WITH_MENU + +#define MENU_COMMAND_PROTOTYPE(_function) \ +int _function(int argc, struct cmd_arg *args) + +#define MENU_COMMAND_HELPER(_command, _function, _help, _meta) \ +MENU_COMMAND_PROTOTYPE(_function); \ +static const struct cmd_menu_item __attribute__((used)) \ +__menu_entry_##_command = { \ + #_command, \ + _function, \ + _help, \ + _meta \ +}; \ +LINKER_SET_ENTRY(menu, __menu_entry_##_command) + +// MENU_COMMAND always gets you a menu command, but when using +// the simple menu (release builds and memory-tight accessories) +// don't compile in the help strings +#if !WITH_SIMPLE_MENU +#define MENU_COMMAND(_c, _f, _h, _m) MENU_COMMAND_HELPER(_c, _f, _h, _m) +#else +#define MENU_COMMAND(_c, _f, _h, _m) MENU_COMMAND_HELPER(_c, _f, "", _m) +#endif + +/* MENU_COMMAND_DEVELOPMENT gets you a menu command in DEVELOPMENT_BUILD and DEBUG_BUILD */ +#if (DEVELOPMENT_BUILD || DEBUG_BUILD) +# define MENU_COMMAND_DEVELOPMENT(_c, _f, _h, _m) MENU_COMMAND(_c, _f, _h, _m) +#else +# define MENU_COMMAND_DEVELOPMENT(_c, _f, _h, _m) struct _hack +#endif + +/* MENU_COMMAND_DEBUG gets you a menu command in DEBUG_BUILD only */ +#if DEBUG_BUILD +# define MENU_COMMAND_DEBUG(_c, _f, _h, _m) MENU_COMMAND(_c, _f, _h, _m) +#else +# define MENU_COMMAND_DEBUG(_c, _f, _h, _m) struct _hack +#endif + +#else +/* no WITH_MENU, nop these out and cause the linker to delete everything else */ +#define MENU_COMMAND(_c, _f, _h, _m) struct _hack +#define MENU_COMMAND_DEVELOPMENT(_c, _f, _h, _m) struct _hack +#define MENU_COMMAND_DEBUG(_c, _f, _h, _m) struct _hack +#endif + +__END_DECLS + +#endif diff --git a/include/sys/security.h b/include/sys/security.h new file mode 100644 index 0000000..def84f6 --- /dev/null +++ b/include/sys/security.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2007-2015 Apple, Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple, Inc. + */ +#ifndef __SYS_SECURITY_H +#define __SYS_SECURITY_H + +#include + +__BEGIN_DECLS + +#define kSecurityModeExUntrust (1 << 4) +#define kSecurityModeKDPEnabled (1 << 5) +#define kSecurityModeDebugCmd (1 << 8) +#define kSecurityModeMemAccess (1 << 16) +#define kSecurityModeHWAccess (1 << 17) +#define kSecurityModeGIDKeyAccess (1 << 18) +#define kSecurityModeUIDKeyAccess (1 << 19) +#define kSecurityModeDevCertAccess (1 << 20) +#define kSecurityModeProdCertAccess (1 << 21) +#define kSecurityOptionClearProduction (1 << 24) +#define kSecurityOptionMixNMatchPrevented (1 << 25) +#define kSecurityOptionBootManifestHashValid (1 << 26) +#define kSecurityOptionLockFuses (1 << 27) +#define kSecurityStatusSecureBoot (1 << 28) +#define kSecurityStatusSystemTrusted (1 << 29) + +#define kSleepTokenKernelOffset (0x80) +#define kSleepTokeniBootOffset (0x90) + +typedef u_int32_t security_mode_t; + + +#define kSecurityImageInvalid (0) +#define kSecurityImageUntrusted (1) +#define kSecurityImageTrusted (2) + +typedef u_int32_t security_image_t; + +int security_init(bool clear_memory); +bool security_allow_modes(security_mode_t modes); +bool security_validate_image(security_image_t image_validity); +bool security_allow_memory(const void *address, size_t length); +void security_protect_memory(const void *address, size_t length, bool protect); +void security_enable_kdp(void); +void security_set_untrusted(void); +void security_set_production_override(bool override); +bool security_get_production_override(void); +void security_create_sleep_token(addr_t address); +bool security_validate_sleep_token(addr_t address); +bool security_get_effective_production_status(bool with_demotion); +void security_set_boot_manifest_hash(u_int8_t *boot_manifest_hash); +bool security_get_boot_manifest_hash(u_int8_t *boot_manifest_hash, u_int32_t hash_length); +void security_set_mix_n_match_prevention_status(bool mix_n_match_enforced); +bool security_get_mix_n_match_prevention_status(void); +void security_set_lock_fuses(void); +bool security_get_lock_fuses(void); +bool security_consolidate_environment(void); +bool security_restore_environment(void); +void security_sidp_seal_rom_manifest(void); +void security_sidp_seal_boot_manifest(bool require_unlocked); + +__END_DECLS + +#endif diff --git a/include/sys/task.h b/include/sys/task.h new file mode 100644 index 0000000..5b161ce --- /dev/null +++ b/include/sys/task.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#ifndef __SYS_TASK_H +#define __SYS_TASK_H + +#include + +#include +#include +#include +#include + +__BEGIN_DECLS + +typedef int (*task_routine)(void *); + +enum task_state { + TASK_INITIAL, + TASK_READY, + TASK_RUNNING, + TASK_BLOCKED, + TASK_SLEEPING, + TASK_FINISHED +}; + +struct task_wait_queue { + struct list_node task_list; +}; + +#define TASK_MAGIC 'task' +#define TASK_MAGIC2 'tsk2' +#define TASK_NAME_MAX 15 +#if defined(__LP64__) +#define TASK_STACK_MIN (16384) +#else +#define TASK_STACK_MIN (512) +#endif + +struct task { + int magic; + + struct list_node task_list_node; + struct list_node queue_node; + + /* track the state of the task (READY, RUNNING, etc) */ + enum task_state state; + + /* interrupt disable count */ + int irq_disable_count; + + /* saved registers, stack pointer */ + struct arch_task arch; + + /* a callout for sleeping */ + struct callout sleep_callout; + + /* to track other tasks waiting on our completion */ + struct task_wait_queue return_waiters; + int return_code; + + /* starting routine and argument */ + task_routine routine; + void *arg; + + /* stack */ + void *stack_base; + size_t stack_len; + + /* debug name of this task */ + char name[TASK_NAME_MAX + 1]; + + /* unique id of this task */ + int task_id; + + int magic2; +}; + +/* statistics */ +struct idle_statistics { + u_int64_t uptime_ticks; + u_int64_t deep_idle_ticks; + u_int64_t deep_idles; + u_int64_t idle_ticks; + u_int64_t idles; + u_int32_t ticksHz; + u_int32_t threshold_us; +}; + +/* the currently running task */ +extern struct task *current_task; + +/* initialize the tasking system */ +void task_init(void); + +/* create a new task */ +struct task *task_create(const char *name, task_routine routine, void *arg, size_t stack_len); +void task_destroy(struct task *); + +/* give up the cpu to another task */ +void task_yield(void); +void task_start(struct task *); +void task_exit(int return_code) __noreturn; +int task_wait_on(struct task *); +void task_block(struct task_wait_queue *); +void task_sleep(utime_t delay); +struct task *task_get_current_task(void); + +/* wait_queue routines */ +void wait_queue_init(struct task_wait_queue *); +void wait_queue_destroy(struct task_wait_queue *); +int wait_queue_wake_all(struct task_wait_queue *); +int wait_queue_wake_one(struct task_wait_queue *); + +/* profile the task manager */ +void task_get_statistics(struct idle_statistics *); + +/* define the application's deep idle policy */ +void task_set_idle_threshold(u_int32_t us); + +/* events */ +struct task_event { + bool signalled; + uint32_t flags; + + struct task_wait_queue wait; +}; + +#define EVENT_STATIC_INIT(_struct, _initial, _flags) \ +{ \ + .signalled = _initial, \ + .flags = _flags, \ + .wait = { .task_list = LIST_INITIAL_VALUE(_struct.wait.task_list) } \ +} + +/* + * event_init + * + * Initialise a task_event structure for use. + */ +void event_init(struct task_event *, uint32_t flags, bool initial_state); + +#define EVENT_FLAG_AUTO_UNSIGNAL 1 + +/* + * event_signal + * + * Signal a task_event, potentially waking one or more tasks waiting on the + * event. If the event is marked EVENT_FLAG_AUTO_UNSIGNAL, only one waiting + * task will be woken each time the event is + * signalled. + */ +void event_signal(struct task_event *); + +/* + * event_unsignal + * + * Clear the is-signalled state of a task_event. This does not affect the + * scheduling state of any tasks that may be waiting on the event. + */ +void event_unsignal(struct task_event *); + +/* + * event_wait + * event_wait_timeout + * + * Wait for a task_event to be signalled. If the event is marked + * EVENT_FLAG_AUTO_UNSIGNAL, only one waiting task will be woken each time the + * event is signalled. + * + * If the timeout expires and the task_event is not signalled, event_wait_timeout + * returns false. + * + * If the timeout is zero, event_wait_timeout will return immediately with the current + * state of the task_event. + */ +void event_wait(struct task_event *); +bool event_wait_timeout(struct task_event *, utime_t delay); + +__END_DECLS + +#endif diff --git a/include/target.h b/include/target.h new file mode 100644 index 0000000..d0b172b --- /dev/null +++ b/include/target.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_H +#define __TARGET_H + +#include +#include +#include + +__BEGIN_DECLS + +enum target_property { + TARGET_PROEPRTY_NONE = 0, + TARGET_PROPERTY_WIFI_MACADDR, + TARGET_PROPERTY_WIFI_CALIBRATION_TX, + TARGET_PROPERTY_WIFI_CALIBRATION_TX_24, + TARGET_PROPERTY_WIFI_CALIBRATION_TX_50, + TARGET_PROPERTY_WIFI_CALIBRATION_RX_24, + TARGET_PROPERTY_WIFI_CALIBRATION_RX_50, + TARGET_PROPERTY_WIFI_CALIBRATION_RX_TEMP, + TARGET_PROPERTY_WIFI_CALIBRATION_FREQ_GROUP_2G, + TARGET_PROPERTY_WIFI_BOARD_SNUM, + TARGET_PROPERTY_WIFI_WCAL, + TARGET_PROPERTY_BT_MACADDR, + TARGET_PROPERTY_ETH_MACADDR, + TARGET_PROPERTY_BB_REGION_SKU, + TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL, + TARGET_PROPERTY_PINTO_MACADDR, + TARGET_PROPERTY_WIFI1_MACADDR, + TARGET_PROPERTY_BT1_MACADDR, + TARGET_PROPERTY_ETH1_MACADDR, + TARGET_PROPERTY_BLUETOOTH_DEV_MACADDR0, + TARGET_PROPERTY_MAX, +}; + +void target_early_init(void); +void target_init(void); +void target_late_init(void); +bool target_config_ap(void); +bool target_config_dev(void); +int target_debug_init(void); +void target_debug(int); +void target_poweroff(void); +void target_setup_default_environment(void); +void target_quiesce_hardware(void); +bool target_should_recover(void); +bool target_should_poweron(bool *cold_boot); +bool target_should_poweroff(bool at_boot); +int target_get_boot_battery_capacity(void); +int target_get_precharge_gg_flag_mask(void); +bool target_needs_chargetrap(void); +bool target_do_chargetrap(void); +void* target_prepare_dali(void); +int target_bootprep(enum boot_target); +int target_init_boot_manifest(void); +int target_pass_boot_manifest(void); +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioic); +bool target_get_property_base(enum target_property prop, void *data, int maxdata, int *retlen); +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen); +int target_update_device_tree(void); +void target_watchdog_tickle(void); +u_int32_t target_lookup_backlight_cal(int index); +uint8_t target_get_lcm_ldos(void); +uint8_t target_lm3534_gpr(uint32_t ctlr); +void * target_get_display_configuration(void); +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy); +int target_dclr_from_clrc(uint8_t *buffer, size_t size); +bool target_is_tethered(void); + +#define LED_NONE 0 +#define LED_GREEN 1 +#define LED_AMBER 2 +#define LED_RED 3 +#define LED_BLUE 4 +#define LED_CYAN 5 +#define LED_WHITE 6 + +void target_set_led(int color); + +__END_DECLS + +#endif diff --git a/lib/blockdev/blockdev.c b/lib/blockdev/blockdev.c new file mode 100644 index 0000000..297c4eb --- /dev/null +++ b/lib/blockdev/blockdev.c @@ -0,0 +1,541 @@ +/* + * Copyright (C) 2006-2014 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#ifndef HOST_TEST +#include +#endif +#include +#include + +static struct blockdev *bdev_list = NULL; + +#define BLOCKSIZE_MOD(dev, val) ((val) & ((1<<((dev)->block_shift)) - 1)) +#define BLOCK_FROM_OFF(dev, off) ((off) >> (dev)->block_shift) +#define BLOCK_TO_OFF(dev, block) ((block) << (dev)->block_shift) +#define ALIGNMENT_MOD(dev, val) ((val) & ((1<<((dev)->alignment_shift)) - 1)) + +static size_t get_cpu_cache_line_size(void) +{ +#ifndef HOST_TEST + return mib_get_size(kMIBPlatformCacheLineSize); +#elif defined CPU_CACHELINE_SIZE + return CPU_CACHELINE_SIZE; +#else +#error "Cache line size is not defined" +#endif +} + +struct blockdev *lookup_blockdev(const char *name) +{ + struct blockdev *dev; + + for (dev = bdev_list; dev; dev = dev->next) { + if (strcmp(dev->name, name) == 0) + return dev; + } + + return NULL; +} + +struct blockdev *first_blockdev(void) +{ + return bdev_list; +} + +struct blockdev *next_blockdev(struct blockdev *dev) +{ + return dev->next; +} + +int register_blockdev(struct blockdev *dev) +{ + ASSERT(dev != NULL); + ASSERT(dev->block_size > 0); + + dprintf(DEBUG_INFO, "register_blockdev: dev %p '%s'\n", dev, dev->name); + + dev->next = bdev_list; + bdev_list = dev; + + return 0; +} + +static void *get_bounce_buf(struct blockdev *dev) +{ + void *result; + uint32_t align = __max(dev->alignment, (uint32_t)get_cpu_cache_line_size()); + uint32_t size = __max(dev->alignment, dev->block_size); + + posix_memalign(&result, align, size); + return result; +} + +/* a reasonable default bytewise read routine in case the block device does not + * choose to override the read_hook. deblocks the device by reading from the read_block hook. + */ +static int blockdev_read_hook(struct blockdev *dev, void *ptr, off_t offset, uint64_t len) +{ + int err; + size_t bytes_read; + block_addr block; + size_t buf_offset; + char *buf = NULL; + + /* trim the read len */ + RELEASE_ASSERT(offset >= 0); + if ((uint64_t)offset >= dev->total_len) + return 0; + if ((offset + len) > dev->total_len) + len = dev->total_len - offset; + + buf_offset = 0; + bytes_read = 0; + block = BLOCK_FROM_OFF(dev, offset); + +// dprintf(DEBUG_INFO, "read: ptr %p, buf_offset %d, bytes_read %zd, block %u, len %d, offset %lld\n", ptr, buf_offset, bytes_read, block, len, offset); + + /* read in partial first block */ + if (BLOCKSIZE_MOD(dev, offset) != 0 || ALIGNMENT_MOD(dev, (uintptr_t)ptr) != 0) { + size_t block_off = BLOCKSIZE_MOD(dev, offset); + size_t toread = __min(len, dev->block_size - block_off); + + buf = get_bounce_buf(dev); + + err = blockdev_read_block(dev, buf, block, 1); + if (err <= 0) + goto done; + + /* copy the partial data */ + memcpy(ptr, buf + block_off, toread); + + block++; + offset += toread; + buf_offset += toread; + bytes_read += toread; + len -= toread; + } + +// dprintf(DEBUG_INFO, "read2: ptr %p, buf_offset %d, bytes_read %zd, block %u, len %d, offset %lld, blockshift %d\n", ptr, buf_offset, bytes_read, block, len, offset, dev->block_shift); + + ASSERT(len == 0 || BLOCKSIZE_MOD(dev, offset) == 0); + + /* handle multiple middle blocks */ + while (len >= dev->block_size) { + size_t blocks_to_read; + size_t alignment_offset; + + blocks_to_read = BLOCK_FROM_OFF(dev, len); + + /* If the buffer we're writing to isn't aligned, shorten the read by a block and + bounce through an aligned address higher up in the buffer. This relies on the block + size being >= the alignment, which is enforced by blockdev_set_buffer_alignment. + For reads of just one block, go through the bounce buffer */ + alignment_offset = ALIGNMENT_MOD(dev, (uintptr_t)ptr + buf_offset); + if (alignment_offset != 0) { + if (blocks_to_read > 1) { + uint8_t *dest; + dest = (uint8_t *)ptr + buf_offset + dev->alignment - alignment_offset; + + err = blockdev_read_block(dev, dest, block, blocks_to_read - 1); + if (err > 0) + memmove((uint8_t *)ptr + buf_offset, dest, BLOCK_TO_OFF(dev, err)); + } else { + if (!buf) + buf = get_bounce_buf(dev); + + err = blockdev_read_block(dev, buf, block, 1); + if (err > 0) + memmove((uint8_t *)ptr + buf_offset, buf, BLOCK_TO_OFF(dev, 1)); + } + } else { + err = blockdev_read_block(dev, (uint8_t *)ptr + buf_offset, block, blocks_to_read); + } + + if (err <= 0) + goto done; + + /* account for blocks read */ + block += err; + buf_offset += BLOCK_TO_OFF(dev, err); + bytes_read += BLOCK_TO_OFF(dev, err); + len -= BLOCK_TO_OFF(dev, err); + } + +// dprintf(DEBUG_INFO, "read3: ptr %p, buf_offset %d, bytes_read %zd, block %ud, len %d, offset %lld\n", ptr, buf_offset, bytes_read, block, len, offset); + + /* handle partial last block */ + if (len > 0) { + ASSERT(len < dev->block_size); + + if (!buf) + buf = get_bounce_buf(dev); + + err = blockdev_read_block(dev, buf, block, 1); + if (err <= 0) + goto done; + + memcpy((uint8_t *)ptr + buf_offset, buf, len); + + bytes_read += len; + } + +done: + if (NULL != buf) + free(buf); + + return bytes_read; +} + + +static int blockdev_read_block_hook(struct blockdev *dev, void *ptr, block_addr block, uint32_t count) +{ + dprintf(DEBUG_CRITICAL, "no reasonable default block read routine\n"); + + return -1; +} + +static int blockdev_write_hook(struct blockdev *dev, const void *ptr, off_t offset, uint64_t len) +{ + int err; + size_t bytes_written; + block_addr block; + size_t buf_offset; + char *buf = NULL; + const void *src; + + /* trim the write len */ + RELEASE_ASSERT(offset >= 0); + if ((uint64_t)offset >= dev->total_len) + return 0; + if ((offset + len) > dev->total_len) + len = dev->total_len - offset; + + buf_offset = 0; + bytes_written = 0; + block = BLOCK_FROM_OFF(dev, offset); + +// dprintf(DEBUG_INFO, "write: ptr %p, buf_offset %d, bytes_written %zd, block %u, len %d, offset %lld\n", ptr, buf_offset, bytes_written, block, len, offset); + + /* write partial first block */ + if (BLOCKSIZE_MOD(dev, offset) != 0 || ALIGNMENT_MOD(dev, offset) != 0) { + size_t block_off = BLOCKSIZE_MOD(dev, offset); + size_t towrite = __min(len, dev->block_size - block_off); + + buf = get_bounce_buf(dev); + + /* read in a buffer */ + err = blockdev_read_block(dev, buf, block, 1); + if (err <= 0) + goto done; + + /* copy the partial data */ + memcpy(buf + block_off, ptr, towrite); + + /* write it back out */ + err = blockdev_write_block(dev, buf, block, 1); + if (err <= 0) + goto done; + + block++; + offset += towrite; + buf_offset += towrite; + bytes_written += towrite; + len -= towrite; + } + +// dprintf(DEBUG_INFO, "write2: ptr %p, buf_offset %d, bytes_written %zd, block %u, len %d, offset %lld, blockshift %d\n", ptr, buf_offset, bytes_written, block, len, offset, dev->block_shift); + + ASSERT(len == 0 || BLOCKSIZE_MOD(dev, offset) == 0); + + /* handle multiple middle blocks */ + while (len >= dev->block_size) { + size_t blocks_to_write; + size_t alignment_offset; + + /* If the buffer we're reading from isn't aligned, bounce buffer each block. iBoot + doesn't care about write performance for big writes, so it's ok for this to be slow */ + alignment_offset = ALIGNMENT_MOD(dev, (uintptr_t)ptr + buf_offset); + if (alignment_offset != 0) { + if (!buf) + buf = get_bounce_buf(dev); + + blocks_to_write = 1; + memcpy(buf, (const uint8_t *)ptr + buf_offset, BLOCK_TO_OFF(dev, blocks_to_write)); + src = buf; + } else { + blocks_to_write = BLOCK_FROM_OFF(dev, len); + src = (const uint8_t *)ptr + buf_offset; + } + + err = blockdev_write_block(dev, src, block, blocks_to_write); + if (err <= 0) + goto done; + + /* account for write */ + block += err; + buf_offset += BLOCK_TO_OFF(dev, err); + bytes_written += BLOCK_TO_OFF(dev, err); + len -= BLOCK_TO_OFF(dev, err); + } + +// dprintf(DEBUG_INFO, "write3: ptr %p, buf_offset %d, bytes_written %zd, block %ud, len %d, offset %lld\n", ptr, buf_offset, bytes_written, block, len, offset); + + /* handle partial last block */ + if (len > 0) { + ASSERT(len < dev->block_size); + + if (!buf) + buf = get_bounce_buf(dev); + + err = blockdev_read_block(dev, buf, block, 1); + if (err <= 0) + goto done; + + memcpy(buf, (uint8_t *)ptr + buf_offset, len); + + err = blockdev_write_block(dev, buf, block, 1); + if (err <= 0) + goto done; + + bytes_written += len; + } + +done: + if (NULL != buf) + free(buf); + + return bytes_written; +} + +static int blockdev_write_block_hook(struct blockdev *dev, const void *ptr, block_addr block, uint32_t count) +{ + dprintf(DEBUG_CRITICAL, "no reasonable default block write routine\n"); + + return -1; +} + +static int blockdev_erase_hook(struct blockdev *dev, off_t offset, uint64_t len) +{ + dprintf(DEBUG_CRITICAL, "no reasonable default erase routine\n"); + + return -1; +} + +/* compare memory with a range of the block device */ +int blockdev_compare(struct blockdev *dev, const void *_ptr, off_t bdev_offset, uint64_t len) +{ + int result; + int err; + uint32_t i; + uint8_t *buf; + const uint8_t *ptr = (const uint8_t *)_ptr; + + posix_memalign((void **)&buf, get_cpu_cache_line_size(), dev->block_size); + + result = 0; + while (len > 0) { + size_t toread = __min(dev->block_size, len); + + err = blockdev_read(dev, buf, bdev_offset, toread); + if (err <= 0) { + dprintf(DEBUG_CRITICAL, "bdev_compare: error reading from device at offset %lld\n", bdev_offset); + result = -1; + goto out; + } + if ((uint32_t)err < toread) { + dprintf(DEBUG_CRITICAL, "bdev_compare: short read from device at offset %lld (read %d)\n", bdev_offset, err); + result = -1; + goto out; + } + + for (i=0; i < toread; i++) { + if (buf[i] != *ptr) { + dprintf(DEBUG_CRITICAL, "difference at offset %lld: dev 0x%02x mem 0x%02x\n", bdev_offset + i, buf[i], *ptr); + result++; + } + ptr++; + } + + len -= toread; + bdev_offset += toread; + } + +out: + free(buf); + return result; +} + +/* write to the bdev safely, avoiding the protected region */ +int blockdev_write_protected(struct blockdev *dev, const void *ptr, off_t offset, uint64_t len) +{ + size_t overlap; + off_t protect_start, protect_end; + uint64_t total_length; + int err; + off_t bytes_written = 0; + +// printf("write_protected: ptr %p offset 0x%llx length 0x%x\n", ptr, offset, len); + protect_start = dev->protect_start; + protect_end = dev->protect_end; + total_length = (uint64_t)offset + len; + // Test for negative offset and overlap + RELEASE_ASSERT(offset >= 0); + RELEASE_ASSERT(total_length >= len); + + /* write the portion before the protected region */ + if (offset < protect_start) { + ASSERT(protect_start >= 0); + if ((offset + len) > (size_t)protect_start) { + overlap = (offset + len) - protect_start; + } else { + overlap = 0; + } +// printf("BDEV: writing first part: 0x%llx/0x%x\n", offset, len - overlap); + err = dev->write_hook(dev, ptr, offset, len - overlap); + if (err < 0) + return err; + bytes_written += err; + } + + /* and write the portion after */ + RELEASE_ASSERT(protect_end >= 0); + if ((offset + len) > (size_t)protect_end) { + if (offset < protect_end) { + overlap = protect_end - offset; + } else { + overlap = 0; + } +// printf("BDEV: writing second part: 0x%llx/0x%x\n", offset + overlap, len - overlap); + err = dev->write_hook(dev, (char *)ptr + overlap, offset + overlap, len - overlap); + if (err < 0) + return err; + bytes_written += err; + } + return bytes_written; +} + + +int blockdev_write_block_protected(struct blockdev *dev, const void *ptr, block_addr block, uint32_t count) +{ + size_t overlap; + size_t protect_start, protect_end; + int err; + uint32_t total_count; + +// printf("write_block_protected: ptr %p block 0x%x count 0x%x\n", ptr, block, count); + protect_start = dev->protect_start >> dev->block_shift; + protect_end = dev->protect_end >> dev->block_shift; + total_count = block + count; + // Test for overlap + RELEASE_ASSERT(total_count >= block); + + /* write the portion before the protected region */ + if (block < protect_start) { + if ((block + count) > protect_start) { + overlap = (block + count) - protect_start; + } else { + overlap = 0; + } +// printf("BDEV: writing first part: 0x%x/0x%x\n", block, count - overlap); + err = dev->write_block_hook(dev, ptr, block, count - overlap); + if (err < 0) /* error */ + return(-1); + if ((uint32_t)err < (count - overlap)) /* short write */ + return(err); + + } + + /* and write the portion after */ + if ((block + count) > protect_end) { + if (block < protect_end) { + overlap = protect_end - block; + } else { + overlap = 0; + } +// printf("BDEV: writing second part: 0x%x/0x%x\n", block + overlap, count - overlap); + err = dev->write_block_hook(dev, (char *)ptr + (overlap << dev->block_shift), block + overlap, count - overlap); + if (err < 0) /* error */ + return(-1); + if ((uint32_t)err < (count - overlap)) /* short write XXX does not handle both ends + * overhanging */ + return(err); + } + return(count); +} + +/* set the protected region */ +int blockdev_set_protection(struct blockdev *dev, off_t offset, uint64_t length) +{ + if (dev->protect_end == dev->protect_start) { + dev->protect_start = offset; + dev->protect_end = offset + length; + dprintf(DEBUG_INFO, "BDEV: protecting 0x%llx-0x%llx\n", dev->protect_start, dev->protect_end); + return(0); + } + return(-1); +} + +/* set the required buffer alignment for read and write buffers */ +void blockdev_set_buffer_alignment(struct blockdev *dev, uint32_t alignment) +{ + ASSERT(dev != NULL); + + ASSERT(is_pow2(alignment)); + + /* Standard hooks don't support an alignment requirement bigger than the block size. + Drivers that need this can just make their blocksize equal to the alignment and + break the alignment-sized blocks into their intrinsic blocksize in their read block hook */ + ASSERT(alignment <= dev->block_size); + + /* can't change the alignment after first setting it */ + ASSERT(dev->alignment == 1 && dev->alignment_shift == 0); + + dev->alignment = alignment; + dev->alignment_shift = log2_int(dev->alignment); +} + +/* + * set up the shared part of the block device structure, and set the default read hooks + * that provide a lot of the base functionality. The specific block device implementation should + * customize the structure further + */ +int construct_blockdev(struct blockdev *dev, const char *name, uint64_t len, uint32_t block_size) +{ + ASSERT(dev != NULL); + ASSERT(is_pow2(block_size)); + ASSERT(strlen(name) < sizeof(dev->name)); + + strlcpy(dev->name, name, sizeof(dev->name)); + dev->flags = 0; + dev->block_size = block_size; + dev->block_shift = log2_int(dev->block_size); + dev->block_count = len >> dev->block_shift; + dev->total_len = len; + dev->alignment = 1; + dev->alignment_shift = 0; + + ASSERT((len >> dev->block_shift) < UINT_MAX); + + dev->read_hook = &blockdev_read_hook; + dev->read_block_hook = &blockdev_read_block_hook; + dev->write_hook = &blockdev_write_hook; + dev->write_block_hook = &blockdev_write_block_hook; + dev->erase_hook = &blockdev_erase_hook; + + dev->protect_start = 0; + dev->protect_end = 0; + + return 0; +} diff --git a/lib/blockdev/debug.c b/lib/blockdev/debug.c new file mode 100644 index 0000000..bd0a86d --- /dev/null +++ b/lib/blockdev/debug.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2007-2011, 2013-2016 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +#define USB_TRANSFER_BLOCKS (1000) + +static int do_slurp (struct blockdev *dev, char *filename, const size_t block_offset) { + int err = 0; + off_t lba; + off_t end; + size_t buf_offset; + const size_t buf_size = dev->block_size * USB_TRANSFER_BLOCKS; + uint8_t * read_buf; + uint8_t * base_buf; + uintptr_t buf_physical; + + + end = dev->total_len >> dev->block_shift; + base_buf = malloc(buf_size); + if (NULL == base_buf) { + printf ("malloc failed\n"); + return -1; + } + buf_physical = mem_static_map_physical((uintptr_t)base_buf); + + printf("slurping lba %zu to %llu\n", block_offset, end); + + buf_offset = 0; + lba = block_offset; + + while (lba < end) { + read_buf = base_buf + buf_offset; + *(UInt32*)read_buf = 0xa5a5a5a5; /* poison buffer */ + err = blockdev_read(dev, read_buf, lba << dev->block_shift, dev->block_size); + if (err < 0){ + printf("blockdev_read returns %d on lba %llu\n\n", err, lba); + // don't stop slurping + } + buf_offset += dev->block_size; + ++lba; + if (buf_offset == buf_size) { + /* + * This issues writes over the USB pipe for USB_TRANSFER_BLOCKS ' worth of + * device blocks. This could be (4096) * 1000 or (8192) * 1000 depending + * on device block size. + */ + err = usb_send_data_to_file(filename, buf_offset, buf_physical, 0); + if (err) { + printf("USB transfer error %d\n", err); + goto out; + } + buf_offset = 0; + printf("Completed to block offset %llu\r", lba); + } + } + + /* Send over the remainder of blocks.. */ + if (buf_offset > 0) { + err = usb_send_data_to_file(filename, buf_offset, buf_physical, 0); + if (err) { + printf("USB transfer error %d\n", err); + goto out; + } + } + +out: + printf("Completed to block offset %llu with code %d\n", lba, err); + + free(base_buf); + return err; +} + + +int do_blockdev(int argc, struct cmd_arg *args) +{ + if (!security_allow_modes(kSecurityModeDebugCmd)) { + printf("Permission Denied\n"); + return -1; + } + + if (argc < 2) { + printf("not enough arguments\n"); +usage: + printf("usage:\n"); + printf("%s list\n", args[0].str); + printf("%s read [
]\n", args[0].str); + printf("%s scan \n", args[0].str); + printf("%s slurp \n", args[0].str); + printf("%s write [] [
]\n", args[0].str); + printf("%s memcmp [] [
]\n", args[0].str); + printf("%s erase \n", args[0].str); + return -1; + } + + if (!strcmp(args[1].str, "list")) { + struct blockdev *dev; + + printf("block device list:\n"); + for (dev = first_blockdev(); dev; dev = next_blockdev(dev)) { + printf("\tdevice '%s': size %lld, block_size %d\n", dev->name, dev->total_len, dev->block_size); + } + } else if (!strcmp(args[1].str, "read") || !strcmp(args[1].str, "write") || !strcmp(args[1].str, "memcmp")) { + if (argc < 4) { + printf("not enough arguments.\n"); + goto usage; + } + + off_t offset = args[3].u; + size_t len; + addr_t addr; + int err; + struct blockdev *dev; + + if (argc >= 5) { + len = args[4].u; + } else { + len = env_get_uint("filesize", 0); + if (len == 0) { + printf("filesize variable invalid or not set, aborting\n"); + return -1; + } + } + + if (argc >= 6) { + addr = args[5].u; + } else { + addr = env_get_uint("loadaddr", mib_get_addr(kMIBTargetDefaultLoadAddress)); + } + + if (!security_allow_memory((void *)addr, len)) { + printf("Permission Denied\n"); + return -1; + } + + dev = lookup_blockdev(args[2].str); + if (!dev) { + printf("couldn't find block device '%s'\n", args[2].str); + return -1; + } + + if (!strcmp(args[1].str, "read")) { + printf("reading %zu bytes from device '%s' to address 0x%llx\n", len, args[2].str, (uint64_t)addr); + err = blockdev_read(dev, (void *)addr, offset, len); + printf("blockdev_read returns %d\n", err); + } else if (!strcmp(args[1].str, "write")) { + printf("writing %zu bytes to device '%s' from address 0x%llx\n", len, args[2].str, (uint64_t)addr); + err = blockdev_write(dev, (void *)addr, offset, len); + printf("blockdev_write returns %d\n", err); + } else { + printf("comparing %zu bytes from device '%s' to address 0x%llx\n", len, args[2].str, (uint64_t)addr); + err = blockdev_compare(dev, (void *)addr, offset, len); + printf("blockdev_compare returns %d\n", err); + } + } else if (!strcmp(args[1].str, "erase")) { + if (argc < 5) { + printf("not enough arguments.\n"); + goto usage; + } + + off_t offset = args[3].u; + size_t len = args[4].u; + int err; + struct blockdev *dev; + + dev = lookup_blockdev(args[2].str); + if (!dev) { + printf("couldn't find block device '%s'\n", args[2].str); + return -1; + } + + err = blockdev_erase(dev, offset, len); + printf("blockdev_erase returns %d\n", err); + } else if (!strcmp(args[1].str, "scan")) { + if (argc < 5) { + printf("not enough arguments.\n"); + goto usage; + } + + off_t lba = (off_t)args[3].u; + size_t len = args[4].u; + int err; + struct blockdev *dev; + off_t end; + uint8_t *buffer; + + dev = lookup_blockdev(args[2].str); + if (!dev) { + printf("couldn't find block device '%s'\n", args[2].str); + return -1; + } + + if (!len || ((off_t)(lba + len) > (off_t)(dev->total_len >> dev->block_shift))){ + end = dev->total_len >> dev->block_shift; + }else{ + end = lba + len; + } + + buffer = malloc(dev->block_size); + + printf("scanning lba %llu to %llu\n", lba, end); + while (lba < end) + { + *buffer = 0xa5; + err = blockdev_read(dev, buffer, lba << dev->block_shift, dev->block_size); + if (err < 0){ + printf("blockdev_read returns %d on lba %llu\n", err, lba); + free(buffer); + return 1; + } + if (lba % 1000 == 0) + printf("lba %zu\r", (size_t)lba); + ++lba; + } + free(buffer); + printf("blockdev scan completed with no errors\n"); + } + else if (!strcmp(args[1].str, "slurp")) { + /* Is it a slurp? */ + if (argc < 3) { + /* bdev slurp device filename */ + printf("slurp invalid arguments \n"); + goto usage; + } + + struct blockdev *dev; + size_t block_offset; + + dev = lookup_blockdev(args[2].str); + block_offset = 0; + + if (!dev) { + printf("could not find blk dev ' %s ' \n", args[2].str); + goto usage; + } + + return do_slurp (dev, args[3].str, block_offset); + + } + else { + printf("unrecognized subcommand.\n"); + goto usage; + } + + return 0; +} + diff --git a/lib/blockdev/library.mk b/lib/blockdev/library.mk new file mode 100644 index 0000000..ffcbc7b --- /dev/null +++ b/lib/blockdev/library.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBBLOCKDEV_DIR := $(GET_LOCAL_DIR) +LIBBLOCKDEV_BUILD := $(call TOLIBDIR,$(LIBBLOCKDEV_DIR)/LIBBLOCKDEV.a) +COMMONLIBS += LIBBLOCKDEV + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBBLOCKDEV_OBJS := \ + $(LIBBLOCKDEV_DIR)/blockdev.o \ + $(LIBBLOCKDEV_DIR)/subdev.o \ + $(LIBBLOCKDEV_DIR)/mem_blockdev.o \ + $(LIBBLOCKDEV_DIR)/debug.o + +LIBBLOCKDEV_OBJS := $(call TOLIBOBJDIR,$(LIBBLOCKDEV_OBJS)) + +ALL_DEPS += $(LIBBLOCKDEV_OBJS:%o=%d) + +$(LIBBLOCKDEV_BUILD): $(LIBBLOCKDEV_OBJS) + +endif diff --git a/lib/blockdev/mem_blockdev.c b/lib/blockdev/mem_blockdev.c new file mode 100644 index 0000000..a91c1e6 --- /dev/null +++ b/lib/blockdev/mem_blockdev.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2006-2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include + +struct mem_blockdev { + struct blockdev bdev; + + /* local data */ + void *ptr; +}; + +static int mem_blockdev_read_block(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count) +{ + struct mem_blockdev *mdev = (struct mem_blockdev *)bdev; + + // no overflow + RELEASE_ASSERT(block + count >= block); + + if (block >= mdev->bdev.block_count) + return 0; + if ((block + count) > mdev->bdev.block_count) + count = mdev->bdev.block_count - block; + + dprintf(DEBUG_SPEW, "mem_blockdev_read: dev %p, ptr %p, block %d, count %d\n", bdev, ptr, block, count); + + memcpy(ptr, (uint8_t *)mdev->ptr + (block << mdev->bdev.block_shift), count << mdev->bdev.block_shift); + + return count; +} + +static int mem_blockdev_read(struct blockdev *bdev, void *ptr, off_t offset, uint64_t len) +{ + struct mem_blockdev *mdev = (struct mem_blockdev *)bdev; + + RELEASE_ASSERT(offset >= 0); + // no overflow + RELEASE_ASSERT((uint64_t)offset + len >= (uint64_t)offset); + + if ((uint64_t)offset >= mdev->bdev.total_len) + return 0; + if ((offset + len) > mdev->bdev.total_len) + len = mdev->bdev.total_len - offset; + + dprintf(DEBUG_SPEW, "mem_blockdev_read: dev %p, ptr %p, off %lld, len %llu\n", bdev, ptr, offset, len); + + memcpy(ptr, (uint8_t *)mdev->ptr + offset, len); + + return len; +} + +struct blockdev *create_mem_blockdev(const char *name, void *ptr, uint64_t len, uint32_t block_size) +{ + struct mem_blockdev *mdev; + + mdev = malloc(sizeof(struct mem_blockdev)); + + construct_blockdev(&mdev->bdev, name, len, block_size); + mdev->ptr = ptr; + + mdev->bdev.read_hook = &mem_blockdev_read; + mdev->bdev.read_block_hook = &mem_blockdev_read_block; + + return &mdev->bdev; +} + diff --git a/lib/blockdev/rules.mk b/lib/blockdev/rules.mk new file mode 100644 index 0000000..71c6a02 --- /dev/null +++ b/lib/blockdev/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2007, 2009-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_BLOCKDEV=1 +LIBRARY_MODULES += lib/blockdev diff --git a/lib/blockdev/subdev.c b/lib/blockdev/subdev.c new file mode 100644 index 0000000..a856430 --- /dev/null +++ b/lib/blockdev/subdev.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2006-2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include + +struct subdev_blockdev { + struct blockdev bdev; + + /* local data */ + struct blockdev *parent_dev; + off_t offset; +}; + +static int subdev_blockdev_read(struct blockdev *bdev, void *ptr, off_t offset, uint64_t len) +{ + struct subdev_blockdev *sdev = (struct subdev_blockdev *)bdev; + + RELEASE_ASSERT(offset >= 0); + if ((uint64_t)offset >= sdev->bdev.total_len) + return 0; + if ((offset + len) > sdev->bdev.total_len) + len = sdev->bdev.total_len - offset; + + return blockdev_read(sdev->parent_dev, ptr, offset + sdev->offset, len); +} + +static int subdev_blockdev_read_block(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count) +{ + struct subdev_blockdev *sdev = (struct subdev_blockdev *)bdev; + + /* since our blocks might not be aligned on parent block boundaries, just punch through to the + * arbitrary alignment read handler and let it deal with it + */ + return subdev_blockdev_read(bdev, ptr, block << sdev->bdev.block_shift, count << sdev->bdev.block_shift); +} + +static int subdev_blockdev_write(struct blockdev *bdev, const void *ptr, off_t offset, uint64_t len) +{ + struct subdev_blockdev *sdev = (struct subdev_blockdev *)bdev; + + RELEASE_ASSERT(offset >= 0); + if ((uint64_t)offset >= sdev->bdev.total_len) + return 0; + if ((offset + len) > sdev->bdev.total_len) + len = sdev->bdev.total_len - offset; + + return blockdev_write(sdev->parent_dev, ptr, offset + sdev->offset, len); +} + +static int subdev_blockdev_write_block(struct blockdev *bdev, const void *ptr, block_addr block, uint32_t count) +{ + struct subdev_blockdev *sdev = (struct subdev_blockdev *)bdev; + + /* since our blocks might not be aligned on parent block boundaries, just punch through to the + * arbitrary alignment write handler and let it deal with it + */ + return subdev_blockdev_write(bdev, ptr, block << sdev->bdev.block_shift, count << sdev->bdev.block_shift); +} + +struct blockdev *create_subdev_blockdev(const char *name, struct blockdev *parent, off_t off, uint64_t len, uint32_t block_size) +{ + struct subdev_blockdev *dev; + + ASSERT(parent); + + dprintf(DEBUG_SPEW, "create_subdev: name '%s' parent '%s' off 0x%llx len 0x%llx bsize 0x%x\n", + name, parent->name, off, len, block_size); + + dev = malloc(sizeof(struct subdev_blockdev)); + + construct_blockdev(&dev->bdev, name, len, block_size); + blockdev_set_buffer_alignment(&dev->bdev, parent->alignment); + dev->parent_dev = parent; + dev->offset = off; + + dev->bdev.read_hook = &subdev_blockdev_read; + dev->bdev.read_block_hook = &subdev_blockdev_read_block; + dev->bdev.write_hook = &subdev_blockdev_write; + dev->bdev.write_block_hook = &subdev_blockdev_write_block; + + return (struct blockdev *)dev; +} + diff --git a/lib/blockdev/tests.c b/lib/blockdev/tests.c new file mode 100644 index 0000000..106a681 --- /dev/null +++ b/lib/blockdev/tests.c @@ -0,0 +1,470 @@ +#include +#include +#include +#include + +struct mock_blockdev { + struct blockdev bdev; + + /* local data */ + void *ptr; +}; + +static int mock_blockdev_read_block(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count) +{ + struct mock_blockdev *mdev = (struct mock_blockdev *)bdev; + + // no overflow + TEST_ASSERT_GTE(block + count, block); + + // buffer must be properly aligned + TEST_ASSERT_EQ((uintptr_t)ptr & (bdev->alignment - 1), 0); + + if (block >= mdev->bdev.block_count) + return 0; + if ((block + count) > mdev->bdev.block_count) + count = mdev->bdev.block_count - block; + + memcpy(ptr, (uint8_t *)mdev->ptr + (block << mdev->bdev.block_shift), count << mdev->bdev.block_shift); + + return count; +} + +static int mock_blockdev_write_block(struct blockdev *bdev, const void *ptr, block_addr block, uint32_t count) +{ + struct mock_blockdev *mdev = (struct mock_blockdev *)bdev; + + // no overflow + TEST_ASSERT_GTE(block + count, block); + + // buffer must be properly aligned + TEST_ASSERT_EQ((uintptr_t)ptr & (bdev->alignment - 1), 0); + + if (block >= mdev->bdev.block_count) + return 0; + if ((block + count) > mdev->bdev.block_count) + count = mdev->bdev.block_count - block; + + memcpy(mdev->ptr + (block << mdev->bdev.block_shift), ptr, count << mdev->bdev.block_shift); + + return count; +} + +struct blockdev *create_mock_blockdev(const char *name, void *ptr, uint64_t len, uint32_t block_size) +{ + struct mock_blockdev *mdev; + + mdev = malloc(sizeof(struct mock_blockdev)); + + construct_blockdev(&mdev->bdev, name, len, block_size); + mdev->ptr = ptr; + + mdev->bdev.read_block_hook = &mock_blockdev_read_block; + mdev->bdev.write_block_hook = &mock_blockdev_write_block; + + return &mdev->bdev; +} + +static void do_blockdev_read_tests(struct blockdev *bdev, uint8_t *backing, size_t backing_size, uint32_t block_size) +{ + uint8_t *readback; + uint8_t *zeroes; + int result; + + readback = malloc(backing_size + 1); + TEST_ASSERT_NOT_NULL(readback); + zeroes = malloc(backing_size); + TEST_ASSERT_NOT_NULL(zeroes); + + memset(zeroes, 0, backing_size); + + // Reading entire buffer should work + memset(readback, 0, backing_size); + result = blockdev_read(bdev, readback, 0, backing_size); + TEST_ASSERT_EQ(result, backing_size); + TEST_ASSERT_MEM_EQ(backing, readback, backing_size); + + // Reading entire buffer unaligned should work + memset(readback + 1, 0, backing_size); + result = blockdev_read(bdev, readback + 1, 0, backing_size); + TEST_ASSERT_EQ(result, backing_size); + TEST_ASSERT_MEM_EQ(backing, readback + 1, backing_size); + + // Reading past the end results in a short read + memset(readback, 0, backing_size); + result = blockdev_read(bdev, readback, backing_size / 2, backing_size); + TEST_ASSERT_EQ(result, backing_size / 2); + // first half of buffer should have result of read + TEST_ASSERT_MEM_EQ(readback, backing + backing_size / 2, backing_size / 2); + // second half should be untouched + TEST_ASSERT_MEM_EQ(readback + backing_size / 2, zeroes, backing_size / 2); + + // Reading totally past the end results in no read + memset(readback, 0, backing_size); + result = blockdev_read(bdev, readback, backing_size + 2, backing_size); + TEST_ASSERT_EQ(result, 0); + // buffer should be totally untouched + TEST_ASSERT_MEM_EQ(readback, zeroes, backing_size); + + // Reads that are weird size should work + uint32_t read_sizes[] = {1, 2, 3, 13, 127, 129, 1023, 1025, 4094, 4097, block_size, block_size - 1, block_size - 2, backing_size - 2, backing_size - 1}; + for (uint32_t i = 0; i < sizeof(read_sizes) / sizeof(read_sizes[0]); i++) { + uint32_t read_size = read_sizes[i]; + if (read_size == 0 || read_size >= backing_size) + continue; + + uint32_t read_offsets[] = {0, 1, 2, 3, 13, 127, 129, 1023, 1025, 4094, 4097, block_size, block_size - 1, block_size - 2, backing_size - 2, backing_size - 1}; + for (uint32_t j = 0; j < sizeof(read_offsets) / sizeof(read_offsets[0]); j++) { + uint32_t read_offset = read_offsets[j]; + if (read_offset >= backing_size || read_offset + read_size >= backing_size) + continue; + tprintf(TEST_INFO, "doing offset=%u size=%u\n", read_offset, read_size); + + // make sure the read succeeds + memset(readback + 1, 0, backing_size); + result = blockdev_read(bdev, readback, read_offset, read_size); + TEST_ASSERT_EQ(result, read_size); + TEST_ASSERT_MEM_EQ(readback, backing + read_offset, read_size); + TEST_ASSERT_MEM_EQ(readback + read_size, zeroes, backing_size - read_size); + + // make sure read succeeds with alignment forced off + memset(readback + 1, 0, backing_size); + result = blockdev_read(bdev, readback + 1, read_offset, read_size); + TEST_ASSERT_EQ(result, read_size); + TEST_ASSERT_MEM_EQ(readback + 1, backing + read_offset, read_size); + TEST_ASSERT_MEM_EQ(readback + 1 + read_size, zeroes, backing_size - read_size); + } + } + + free(readback); + free(zeroes); +} + +static void do_blockdev_read_block_tests(struct blockdev *bdev, uint8_t *backing, size_t backing_size, uint32_t block_size) +{ + uint8_t *readback; + uint8_t *filler; + int result; + uint32_t blocks = backing_size / block_size; + + readback = malloc(backing_size); + TEST_ASSERT_NOT_NULL(readback); + filler = malloc(backing_size + 1); + TEST_ASSERT_NOT_NULL(filler); + + memset(filler, 0xee, backing_size); + + // Reading entire buffer should work + memcpy(readback, filler, backing_size); + result = blockdev_read_block(bdev, readback, 0, blocks); + TEST_ASSERT_EQ(result, blocks); + TEST_ASSERT_MEM_EQ(backing, readback, backing_size); + + // Reading past the end results in a short read + memcpy(readback, filler, backing_size); + result = blockdev_read_block(bdev, readback, blocks / 2, blocks); + TEST_ASSERT_EQ(result, blocks / 2); + // first half of buffer should have result of read + TEST_ASSERT_MEM_EQ(readback, backing + backing_size / 2, backing_size / 2); + // second half should be untouched + TEST_ASSERT_MEM_EQ(readback + backing_size / 2, filler, backing_size / 2); + + // Reading totally past the end results in no read + memcpy(readback, filler, backing_size); + result = blockdev_read_block(bdev, readback, blocks + 2, blocks); + TEST_ASSERT_EQ(result, 0); + // buffer should be totally untouched + TEST_ASSERT_MEM_EQ(readback, filler, backing_size); + + free(readback); + free(filler); +} + +void test_mem_blockdev(uintptr_t param) +{ + struct blockdev *bdev; + uint8_t *backing; + size_t backing_size = 8192; + uint32_t block_size = param; + + backing = malloc(backing_size); + TEST_ASSERT_NOT_NULL(backing); + for (uint32_t i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val = i + 0xaabbccdd; + memcpy(backing + i * sizeof(uint32_t), &val, sizeof(uint32_t)); + } + bdev = create_mem_blockdev("dev", backing, backing_size, block_size); + + do_blockdev_read_tests(bdev, backing, backing_size, block_size); + do_blockdev_read_block_tests(bdev, backing, backing_size, block_size); + + // make sure backing wasn't touched during all the tests + for (unsigned i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val; + memcpy(&val, backing + i * sizeof(uint32_t), sizeof(uint32_t)); + TEST_ASSERT_EQ(val, i + 0xaabbccdd); + } + + free(backing); +} + +void test_blockdev_read_block(uintptr_t param) +{ + struct blockdev *bdev; + uint8_t *backing; + size_t backing_size = 8192; + uint32_t block_size = param; + + backing = malloc(backing_size); + TEST_ASSERT_NOT_NULL(backing); + for (uint32_t i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val = i + 0xaabbccdd; + memcpy(backing + i * sizeof(uint32_t), &val, sizeof(uint32_t)); + } + bdev = create_mock_blockdev("dev1", backing, backing_size, block_size); + do_blockdev_read_block_tests(bdev, backing, backing_size, block_size); + + // make sure backing wasn't touched during all the tests + for (unsigned i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val; + memcpy(&val, backing + i * sizeof(uint32_t), sizeof(uint32_t)); + TEST_ASSERT_EQ(val, i + 0xaabbccdd); + } + + free(backing); +} + +void test_blockdev_read(uintptr_t param) +{ + struct blockdev *bdev; + uint8_t *backing; + size_t backing_size = 8192; + uint32_t block_size = param; + + backing = malloc(backing_size); + TEST_ASSERT_NOT_NULL(backing); + for (uint32_t i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val = i + 0xaabbccdd; + memcpy(backing + i * sizeof(uint32_t), &val, sizeof(uint32_t)); + } + bdev = create_mock_blockdev("dev1", backing, backing_size, block_size); + do_blockdev_read_tests(bdev, backing, backing_size, block_size); + + // make sure backing wasn't touched during all the tests + for (unsigned i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val; + memcpy(&val, backing + i * sizeof(uint32_t), sizeof(uint32_t)); + TEST_ASSERT_EQ(val, i + 0xaabbccdd); + } + + free(backing); +} + +void test_blockdev_set_buffer_alignment_read(uintptr_t param) +{ + struct blockdev *bdev; + uint8_t *backing; + size_t backing_size = 8192; + uint32_t block_size = param; + + backing = malloc(backing_size); + TEST_ASSERT_NOT_NULL(backing); + for (uint32_t i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val = i + 0xaabbccdd; + memcpy(backing + i * sizeof(uint32_t), &val, sizeof(uint32_t)); + } + + bdev = create_mock_blockdev("dev1", backing, backing_size, block_size); + blockdev_set_buffer_alignment(bdev, block_size); + do_blockdev_read_tests(bdev, backing, backing_size, block_size); + + if (block_size > 2) { + bdev = create_mock_blockdev("dev2", backing, backing_size, block_size); + blockdev_set_buffer_alignment(bdev, block_size / 2); + do_blockdev_read_tests(bdev, backing, backing_size, block_size); + } + + // make sure backing wasn't touched during all the tests + for (unsigned i = 0; i < backing_size / sizeof(uint32_t); i++) { + uint32_t val; + memcpy(&val, backing + i * sizeof(uint32_t), sizeof(uint32_t)); + TEST_ASSERT_EQ(val, i + 0xaabbccdd); + } + + free(backing); +} + +static void do_blockdev_write_tests(struct blockdev *bdev, uint8_t *backing, size_t backing_size, uint32_t block_size) +{ + uint8_t *data; + uint8_t *filler; + int result; + + // need some source data we can write to the blockdev with + // easily recognizable patterns + data = malloc(backing_size + sizeof(uint32_t)); + TEST_ASSERT_NOT_NULL(data); + for (uint32_t i = 0; i < backing_size / sizeof(uint32_t) + 1; i++) { + uint32_t val = i + 0xaabbccdd; + memcpy(data + i * sizeof(uint32_t), &val, sizeof(uint32_t)); + } + + filler = malloc(backing_size); + TEST_ASSERT_NOT_NULL(filler); + + memset(filler, 0xee, backing_size); + + // Writing entire buffer should work + memcpy(backing, filler, backing_size); + result = blockdev_write(bdev, data, 0, backing_size); + TEST_ASSERT_EQ(result, backing_size); + TEST_ASSERT_MEM_EQ(backing, data, backing_size); + + // Writing entire buffer unaligned should work + memcpy(backing, filler, backing_size); + result = blockdev_write(bdev, data + 1, 0, backing_size); + TEST_ASSERT_EQ(result, backing_size); + TEST_ASSERT_MEM_EQ(backing, data + 1, backing_size); + + // Writing past the end results in a short write + memcpy(backing, filler, backing_size); + result = blockdev_write(bdev, data, backing_size / 2, backing_size); + TEST_ASSERT_EQ(result, backing_size / 2); + // first half of backing should be untouched + TEST_ASSERT_MEM_EQ(backing, filler, backing_size / 2); + // second half of buffer should have result of write + TEST_ASSERT_MEM_EQ(backing + backing_size / 2, data, backing_size / 2); + + // Reading totally past the end results in no write + memcpy(backing, filler, backing_size); + result = blockdev_write(bdev, data, backing_size + 2, backing_size); + TEST_ASSERT_EQ(result, 0); + // buffer should be totally untouched + TEST_ASSERT_MEM_EQ(backing, filler, backing_size); + + // weird size writes should work + uint32_t write_sizes[] = {1, 2, 3, 13, 127, 129, 1023, 1025, 4094, 4097, block_size, block_size - 1, block_size - 2, backing_size - 2, backing_size - 1}; + for (uint32_t i = 0; i < sizeof(write_sizes) / sizeof(write_sizes[0]); i++) { + uint32_t write_size = write_sizes[i]; + if (write_size == 0 || write_size >= backing_size) + continue; + + uint32_t write_offsets[] = {0, 1, 2, 3, 13, 127, 129, 1023, 1025, 4094, 4097, block_size, block_size - 1, block_size - 2, backing_size - 2, backing_size - 1}; + for (uint32_t j = 0; j < sizeof(write_offsets) / sizeof(write_offsets[0]); j++) { + uint32_t write_offset = write_offsets[j]; + if (write_offset >= backing_size || write_offset + write_size >= backing_size) + continue; + tprintf(TEST_INFO, "doing offset=%u size=%u\n", write_offset, write_size); + + memcpy(backing, filler, backing_size); + result = blockdev_write(bdev, data, write_offset, write_size); + TEST_ASSERT_EQ(result, write_size); + TEST_ASSERT_MEM_EQ(backing + write_offset, data, write_size); + // data before and after write should be untouched + TEST_ASSERT_MEM_EQ(backing, filler, write_offset); + TEST_ASSERT_MEM_EQ(backing + write_offset + write_size, filler, backing_size - write_size - write_offset); + } + } + + free(data); + free(filler); +} + +void test_blockdev_write(uintptr_t param) +{ + struct blockdev *bdev; + uint8_t *backing; + size_t backing_size = 8192; + uint32_t block_size = param; + + backing = malloc(backing_size); + + bdev = create_mock_blockdev("dev1", backing, backing_size, block_size); + do_blockdev_write_tests(bdev, backing, backing_size, block_size); + + if (block_size > 1) { + bdev = create_mock_blockdev("dev2", backing, backing_size, block_size); + blockdev_set_buffer_alignment(bdev, block_size); + do_blockdev_write_tests(bdev, backing, backing_size, block_size); + } + + if (block_size > 2) { + bdev = create_mock_blockdev("dev3", backing, backing_size, block_size); + blockdev_set_buffer_alignment(bdev, block_size / 2); + do_blockdev_write_tests(bdev, backing, backing_size, block_size); + } + + free(backing); +} + +void test_register_blockdev(uintptr_t param) +{ + static uint8_t backing; + struct blockdev *bdev0; + struct blockdev *bdev1; + uint32_t found = 0; + + bdev0 = create_mock_blockdev("lookup-bdev0", &backing, 1, 1); + TEST_ASSERT_NOT_NULL(bdev0); + bdev1 = create_mock_blockdev("lookup-bdev1", &backing, 1, 1); + TEST_ASSERT_NOT_NULL(bdev1); + + TEST_ASSERT_NULL(lookup_blockdev("lookup-bdev0")); + TEST_ASSERT_NULL(lookup_blockdev("lookup-bdev1")); + + TEST_ASSERT_NULL(first_blockdev()); + + register_blockdev(bdev0); + + TEST_ASSERT_PTR_EQ(lookup_blockdev("lookup-bdev0"), bdev0); + TEST_ASSERT_PTR_EQ(first_blockdev(), bdev0); + TEST_ASSERT_NULL(lookup_blockdev("lookup-bdev1")); + + register_blockdev(bdev1); + + TEST_ASSERT_PTR_EQ(lookup_blockdev("lookup-bdev0"), bdev0); + TEST_ASSERT_PTR_EQ(lookup_blockdev("lookup-bdev1"), bdev1); + + for (struct blockdev *bdev = first_blockdev(); bdev != NULL; bdev = next_blockdev(bdev)) { + if (bdev == bdev0) + found |= 1; + if (bdev == bdev1) + found |= 2; + } + TEST_ASSERT_EQ(found, 3); +} + +struct test_suite blockdev_suite = { + .name = "blockdev", + .test_cases = { + { "register_blockdev", test_register_blockdev, 0, "" }, + { "mem_blockdev,1", test_mem_blockdev, 1, "" }, + { "mem_blockdev,2", test_mem_blockdev, 2, "" }, + { "mem_blockdev,4", test_mem_blockdev, 4, "" }, + { "mem_blockdev,1024", test_mem_blockdev, 1024, "" }, + { "blockdev_read_block,1", test_blockdev_read_block, 1, "" }, + { "blockdev_read_block,2", test_blockdev_read_block, 2, "" }, + { "blockdev_read_block,4", test_blockdev_read_block, 4, "" }, + { "blockdev_read_block,1024", test_blockdev_read_block, 1024, "" }, + { "blockdev_read_block,4096", test_blockdev_read_block, 4096, "" }, + { "blockdev_read,1", test_blockdev_read, 1, "" }, + { "blockdev_read,2", test_blockdev_read, 2, "" }, + { "blockdev_read,4", test_blockdev_read, 4, "" }, + { "blockdev_read,1024", test_blockdev_read, 1024, "" }, + { "blockdev_read,4096", test_blockdev_read, 4096, "" }, + { "blockdev_read,8192", test_blockdev_read, 8192, "" }, + { "blockdev_write,1", test_blockdev_write, 1, "" }, + { "blockdev_write,2", test_blockdev_write, 2, "" }, + { "blockdev_write,4", test_blockdev_write, 4, "" }, + { "blockdev_write,1024", test_blockdev_write, 1024, "" }, + { "blockdev_write,4096", test_blockdev_write, 4096, "" }, + { "blockdev_write,8192", test_blockdev_write, 8192, "" }, + { "blockdev_set_buffer_alignment_read,2", test_blockdev_set_buffer_alignment_read, 2, "" }, + { "blockdev_set_buffer_alignment_read,8", test_blockdev_set_buffer_alignment_read, 8, "" }, + { "blockdev_set_buffer_alignment_read,1024", test_blockdev_set_buffer_alignment_read, 1024, "" }, + { "blockdev_set_buffer_alignment_read,4096", test_blockdev_set_buffer_alignment_read, 4096, "" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(blockdev_suite); diff --git a/lib/blockdev/tests.mk b/lib/blockdev/tests.mk new file mode 100644 index 0000000..dc9db74 --- /dev/null +++ b/lib/blockdev/tests.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := blockdev + +TEST_OBJS := \ + lib/libc/log2.o \ + $(LOCAL_DIR)/blockdev.o \ + $(LOCAL_DIR)/mem_blockdev.o \ + $(LOCAL_DIR)/subdev.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o + +TEST_CFLAGS := \ + -DCPU_CACHELINE_SIZE=32 \ + -DHOST_TEST=1 diff --git a/lib/cbuf/cbuf.c b/lib/cbuf/cbuf.c new file mode 100644 index 0000000..f335ac4 --- /dev/null +++ b/lib/cbuf/cbuf.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007, 2011, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#define INC_HEAD(cbuf) ((cbuf)->head = ((cbuf)->head + 1) & (cbuf)->len_mask) +#define INC_TAIL(cbuf) ((cbuf)->tail = ((cbuf)->tail + 1) & (cbuf)->len_mask) + +struct cbuf *cbuf_create(size_t len, struct task_event *event) +{ + struct cbuf *buf; + + if (!is_pow2(len)) + return NULL; + + buf = malloc(sizeof(struct cbuf)); + + buf->buf = malloc(len); + + buf->head = 0; + buf->tail = 0; + buf->has = 0; + buf->len = len; + buf->len_mask = len - 1; + + buf->event = event; + if (buf->event) + event_init(buf->event, 0, false); + + return buf; +} + +void cbuf_destroy(struct cbuf *buf) +{ + if (buf == 0) return; + + free(buf->buf); + free(buf); +} + +ssize_t cbuf_write_char(struct cbuf *buf, char c) +{ + ssize_t ret; + + /* if cbuf not valid, drop the character */ + if (buf == 0) return 1; + + enter_critical_section(); + + if (buf->has == buf->len) { + ret = 0; + goto out; + } + + ((char *)buf->buf)[buf->head] = c; + INC_HEAD(buf); + buf->has++; + ret = 1; + + if (buf->event) + event_signal(buf->event); + +out: + exit_critical_section(); + return ret; +} + +ssize_t cbuf_read_char(struct cbuf *buf, char *c) +{ + ssize_t ret; + + /* if cbuf not valid, return nothing */ + if (buf == 0) return 0; + + enter_critical_section(); + + if (buf->has == 0) { + ret = 0; + goto out; + } + + *c = ((char *)buf->buf)[buf->tail]; + INC_TAIL(buf); + buf->has--; + ret = 1; + +out: + if (buf->event && buf->has == 0) + event_unsignal(buf->event); + + exit_critical_section(); + return ret; +} diff --git a/lib/cbuf/library.mk b/lib/cbuf/library.mk new file mode 100644 index 0000000..d6306cd --- /dev/null +++ b/lib/cbuf/library.mk @@ -0,0 +1,29 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBCBUF_DIR := $(GET_LOCAL_DIR) +LIBCBUF_BUILD := $(call TOLIBDIR,$(LIBCBUF_DIR)/LIBCBUF.a) +COMMONLIBS += LIBCBUF + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +GLOBAL_INCLUDES += $(SRCROOT)/arch/arm/include + +LIBCBUF_OBJS := $(LIBCBUF_DIR)/cbuf.o + +LIBCBUF_OBJS := $(call TOLIBOBJDIR,$(LIBCBUF_OBJS)) + +ALL_DEPS += $(LIBCBUF_OBJS:%o=%d) + +$(LIBCBUF_BUILD): $(LIBCBUF_OBJS) + +endif diff --git a/lib/cbuf/rules.mk b/lib/cbuf/rules.mk new file mode 100644 index 0000000..6cdb2eb --- /dev/null +++ b/lib/cbuf/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +OPTIONS += WITH_CBUF=1 +LIBRARY_MODULES += lib/cbuf + diff --git a/lib/cksum/adler32.c b/lib/cksum/adler32.c new file mode 100644 index 0000000..4969cb0 --- /dev/null +++ b/lib/cksum/adler32.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if (ARCH_ARMv7 && WITH_VFP) || defined(__arm64__) +extern uint32_t adler32_vec(uint32_t, uint32_t, const uint8_t *, long); +#endif + + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5000 +// NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +uint32_t adler32(const uint8_t *buf, long len) +{ + uint32_t s1 = 1; // adler & 0xffff; + uint32_t s2 = 0; // (adler >> 16) & 0xffff; + int k; + +#if (ARCH_ARMv7 && WITH_VFP) || defined(__arm64__) + + /* align buf to 16-byte boundary */ + while ((int)buf & 15) { /* not on a 16-byte boundary */ + len--; + s1 += *buf++; + s2 += s1; + s1 %= BASE; + s2 %= BASE; + } + if (len > 16) { +#if WITH_VFP_ALWAYS_ON + return adler32_vec(s1, s2, buf, len); +#else + bool fp_enabled; + uint32_t result; + + fp_enabled = arch_task_fp_enable(true); + result = adler32_vec(s1, s2, buf, len); + arch_task_fp_enable(fp_enabled); + + return result; +#endif // WITH_VFP_ALWAYS_ON + } +#endif + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} + diff --git a/lib/cksum/arm/adler32vec.S b/lib/cksum/arm/adler32vec.S new file mode 100644 index 0000000..b5fd0e2 --- /dev/null +++ b/lib/cksum/arm/adler32vec.S @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if defined(__arm__) + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +// Note: buf should have been 16-byte aligned in the caller function, + +// uLong adler32_vec(unsigned int adler, unsigned int sum2, const Bytef* buf, int len) { +// unsigned n; +// while (len >= NMAX) { +// len -= NMAX; +// n = NMAX / 16; /* NMAX is divisible by 16 */ +// do { +// DO16(buf); /* 16 sums unrolled */ +// buf += 16; +// } while (--n); +// MOD(adler); +// MOD(sum2); +// } +// if (len) { /* avoid modulos if none remaining */ +// while (len >= 16) { +// len -= 16; +// DO16(buf); +// buf += 16; +// } +// while (len--) { +// adler += *buf++; +// sum2 += adler; +// } +// MOD(adler); +// MOD(sum2); +// } +// return adler | (sum2 << 16); /* return recombined sums */ +// } + + +/* + DO16 vectorization: + given initial unsigned int sum2 and adler, and a new set of 16 input bytes (x[0:15]), it can be shown that + sum2 += (16*adler + 16*x[0] + 15*x[1] + ... + 1*x[15]); + adler += (x[0] + x[1] + ... + x[15]); + + therefore, this is what can be done to vectorize the above computation + 1. 16-byte aligned vector load into q2 (x[0:x15]) + 2. sum2 += (adler<<4); + 3. vmull.u8 (q9,q8),q2,d2 where d2 = (1,1,1,1...,1), (q9,q8) + 16 16-bit elements x[0:15] + 4. vmull.u8 (q11,q10),q2,q0 where q0 = (1,2,3,4...,16), (q11,q10) + 16 16-bit elements (16:1)*x[0:15] + 5. parallel add (with once expansion to 32-bit) (q9,q8) and (q11,q10) all the way to accumulate to adler and sum2 + + In this revision, whenever possible, 2 DO16 loops are combined into a DO32 loop. + 1. 32-byte aligned vector load into q2,q14 (x[0:x31]) + 2. sum2 += (adler<<5); + 3. vmull.u8 (4 q registers),(q2,q14),d2 where d2 = (1,1,1,1...,1), (4 q registers) : 32 16-bit elements x[0:31] + 4. vmull.u8 (4 q registers),(q2,q14),(q0,q15) where q0 = (1,...,32), (4 q regs) : 32 16-bit elements (32:1)*x[0:31] + 5. parallel add (with once expansion to 32-bit) the pair of (4 q regs) all the way to accumulate to adler and sum2 + + This change improves the performance by ~ 0.55 cycle/uncompress byte on ARM Cortex-A8. + +*/ + +/* + MOD implementation: + adler%BASE = adler - floor(adler*(1/BASE))*BASE; where (1/BASE) = 0x80078071 in Q47 + 1. vmull.u32 q2,(adler,sum2),(1/BASE) // *(1/BASE) in Q47 + 2. vshr.u64 q2,q2,#47 // floor function + 3. vpadd.u32 d4,d4,d5 // merge into a double word in d4 + 4. vmls.u32 (adler,sum2),d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE + +*/ + + .text + .align 2 + .globl _adler32_vec +_adler32_vec: + + #define adler r0 + #define sum2 r1 + #define buf r2 + #define len r3 + #define nmax r4 + #define vecs lr // vecs = NMAX/16 + #define n r5 + + #define t r12 + + #define sum2_coeff q0 + #define sum2_coeff0 d0 + #define sum2_coeff1 d1 + #define alder_coeff q1 + #define ones d2 + #define x0_x15 q2 + #define x0_x7 d4 + #define x8_x15 d5 + #define adlersum2 d6 + #define adler16 d25 + + adr t, vec_table // address to vec_table[] + stmfd sp!, {r4, r5, lr} + + vld1.32 {q0-q1},[t,:128]! // loading up coefficients for adler/sum2 computation + vld1.32 {q15},[t,:128]! // for sum2 computation + ldr nmax, [t] // NMAX + + vmov adlersum2, sum2, adler // pack up adler/sum2 into a double register + + cmp len, nmax // len vs NMAX + lsr vecs, nmax, #4 // vecs = NMAX/16; + blt L_len_lessthan_NMAX // if (len < NMAX) skip the while loop + + sub len, nmax // pre-decrement len by NMAX + +L_while_len_ge_NMAX_loop: // while (len>=NMAX) { + + mov n, vecs, lsr #1 // n = NMAX/16; + +L_do_loop: // do { + + vshll.u32 q12, adlersum2, #5 // d25 = (0,32*adler) to be added into (adler,sum2) + vld1.32 {x0_x15},[buf,:128]! // 16-byte input x0:x15 + vmull.u8 q8, x0_x7, ones // 16-bit x0-x7 + vld1.32 {q14}, [buf,:128]! // x16:x31 + vmull.u8 q9, x8_x15, ones // 16-bit x8-x15 + vadd.u32 adlersum2,adler16 // sum2 += old adler*32; + vmull.u8 q12, d28, ones // 16-bit x16-x23 + vmull.u8 q13, d29, ones // 16-bit x24-x31 + vmull.u8 q10, d28, sum2_coeff0 // 16-bit x16*16, x17*15, ..., x23*9 + vmull.u8 q11, d29, sum2_coeff1 // 16-bit x24*8, x25*7, ..., x31*1 + vadd.u16 q8, q8, q9 // q8 = (x0+x8):(x7+x15) 8 16-bit elements for adler + vmull.u8 q9, x0_x7, d30 // 16-bit x0*32,...,x7*25 + vmull.u8 q14, x8_x15, d31 // 16-bit x8*24,...,x15*17 + vadd.u16 q12, q12, q13 // q12 = (x16+x24):(x23+x31) 8 16-bit elements for adler + vadd.u16 q10, q11 // 8 16-bit elements for sum2 + vadd.u16 q8, q12 // 8 16-bit elements for adler + vadd.u16 q9, q14 // 8 16-bit elements for sum2 + vadd.u16 q10, q9 // 8 16-bit elements for sum2 +#if 0 + vpaddl.u16 q8, q8 // 4 32-bit elements for adler + vpaddl.u16 q10, q10 // 4 32-bit elements for sum2 + vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler + vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2 +#else + vadd.u16 d16, d17 + vadd.u16 d20, d21 + vpaddl.u16 d16, d16 + vpaddl.u16 d17, d20 +#endif + vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler + vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input + + subs n, #1 // --n + bgt L_do_loop // } while (--n); + + vshll.u32 q12, adlersum2, #4 // d25 = (0,16*adler) to be added into (adler,sum2) + + vld1.32 {x0_x15},[buf,:128]! // 16-byte input + + vmull.u8 q8, x0_x7, ones // 16-bit x0-x7 + vmull.u8 q9, x8_x15, ones // 16-bit x8-x15 + vmull.u8 q10, x0_x7, sum2_coeff0 // 16-bit x0*16, x1*15, ..., x7*9 + vmull.u8 q11, x8_x15, sum2_coeff1 // 16-bit x8*8, x9*7, ..., x15*1 + + vadd.u16 q8, q8, q9 // 8 16-bit elements for adler + vadd.u16 q10, q10, q11 // 8 16-bit elements for sum2 +#if 0 + vpaddl.u16 q8, q8 // 4 32-bit elements for adler + vpaddl.u16 q10, q10 // 4 32-bit elements for sum2 + vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler + vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2 +#else + vadd.u16 d16, d17 + vadd.u16 d20, d21 + vpaddl.u16 d16, d16 + vpaddl.u16 d17, d20 + +#endif + vadd.u32 adlersum2,adler16 // sum2 += old adler; + vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler + vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input + + // mod(alder,BASE); mod(sum2,BASE); + vmull.u32 q2,adlersum2,d3[1] // alder/BASE, sum2/BASE in Q47 + vshr.u64 q2,q2,#47 // take the integer part + vpadd.u32 d4,d4,d5 // merge into a double word in d4 + vmls.u32 adlersum2,d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE + + subs len, nmax // len -= NMAX; + bge L_while_len_ge_NMAX_loop // repeat while len >= NMAX + + add len, nmax // post-increment len by NMAX + +L_len_lessthan_NMAX: + + cmp len, #0 + beq L_len_is_zero // if len==0, branch to skip the following + + + subs len, #32 // pre-decrement len by 32 + blt L_len_lessthan_32 // if len < 32, branch to L_len16_loop + +L_len32_loop: + + vshll.u32 q12, adlersum2, #5 // d25 = (0,32*adler) to be added into (adler,sum2) + vld1.32 {x0_x15},[buf,:128]! // 16-byte input x0:x15 + vmull.u8 q8, x0_x7, ones // 16-bit x0-x7 + vld1.32 {q14}, [buf,:128]! // x16:x31 + vmull.u8 q9, x8_x15, ones // 16-bit x8-x15 + vadd.u32 adlersum2,adler16 // sum2 += old adler*32; + vmull.u8 q12, d28, ones // 16-bit x16-x23 + vmull.u8 q13, d29, ones // 16-bit x24-x31 + vmull.u8 q10, d28, sum2_coeff0 // 16-bit x16*16, x17*15, ..., x23*9 + vmull.u8 q11, d29, sum2_coeff1 // 16-bit x24*8, x25*7, ..., x31*1 + vadd.u16 q8, q8, q9 // q8 = (x0+x8):(x7+x15) 8 16-bit elements for adler + vmull.u8 q9, x0_x7, d30 // 16-bit x0*32,...,x7*25 + vmull.u8 q14, x8_x15, d31 // 16-bit x8*24,...,x15*17 + vadd.u16 q12, q12, q13 // q12 = (x16+x24):(x23+x31) 8 16-bit elements for adler + vadd.u16 q10, q11 // 8 16-bit elements for sum2 + vadd.u16 q8, q12 // 8 16-bit elements for adler + vadd.u16 q9, q14 // 8 16-bit elements for sum2 + vadd.u16 q10, q9 // 8 16-bit elements for sum2 +#if 0 + vpaddl.u16 q8, q8 // 4 32-bit elements for adler + vpaddl.u16 q10, q10 // 4 32-bit elements for sum2 + vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler + vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2 +#else + vadd.u16 d16, d17 + vadd.u16 d20, d21 + vpaddl.u16 d16, d16 + vpaddl.u16 d17, d20 +#endif + vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler + vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input + + subs len, #32 // len -= 32; + bge L_len32_loop + +L_len_lessthan_32: + + adds len, #(32-16) // post-increment len by 32, then pre-decrement by 16 + blt L_len_lessthan_16 // if len < 16, branch to L_len_lessthan_16 + + vshll.u32 q12, adlersum2, #4 // d25 = (0,16*adler) to be added into (adler,sum2) + + vld1.32 {x0_x15},[buf,:128]! // 16-byte input + + + vmull.u8 q8, x0_x7, ones // 16-bit x0-x7 + vmull.u8 q9, x8_x15, ones // 16-bit x8-x15 + vmull.u8 q10, x0_x7, sum2_coeff0 // 16-bit x0*16, x1*15, ..., x7*9 + vmull.u8 q11, x8_x15, sum2_coeff1 // 16-bit x8*8, x9*7, ..., x15*1 + + vadd.u16 q8, q8, q9 // 8 16-bit elements for adler + vadd.u16 q10, q10, q11 // 8 16-bit elements for sum2 +#if 0 + vpaddl.u16 q8, q8 // 4 32-bit elements for adler + vpaddl.u16 q10, q10 // 4 32-bit elements for sum2 + vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler + vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2 +#else + vadd.u16 d16, d17 + vadd.u16 d20, d21 + vpaddl.u16 d16, d16 + vpaddl.u16 d17, d20 +#endif + subs len, #16 // decrement len by 16 + vadd.u32 adlersum2,adler16 // sum2 += old adler; + vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler + vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input + +L_len_lessthan_16: + adds len, #16 // post-increment len by 16 + beq L_len_is_zero_internal // if len==0, branch to len_is_zero_internal + + // restore adler/sum2 into general registers for remaining (<16) bytes + + vmov sum2, adler, adlersum2 +L_remaining_len_loop: + ldrb t, [buf], #1 // *buf++; + subs len, #1 // len--; + add adler,t // adler += *buf + add sum2,adler // sum2 += adler + bgt L_remaining_len_loop // break if len<=0 + + vmov adlersum2, sum2, adler // move to double register for modulo operation + +L_len_is_zero_internal: + + // mod(alder,BASE); mod(sum2,BASE); + + vmull.u32 q2,adlersum2,d3[1] // alder/BASE, sum2/BASE in Q47 + vshr.u64 q2,q2,#47 // take the integer part + vpadd.u32 d4,d4,d5 // merge into a double word in d4 + vmls.u32 adlersum2,d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE + +L_len_is_zero: + + vmov sum2, adler, adlersum2 // restore adler/sum2 from (s12=sum2, s13=adler) + add r0, adler, sum2, lsl #16 // to return adler | (sum2 << 16); + ldmfd sp!, {r4, r5, pc} // restore registers and return + + + // constants to be loaded into q registers + .align 4 // 16 byte aligned + +vec_table: + + // coefficients for computing sum2 + .long 0x0d0e0f10 // s0 + .long 0x090a0b0c // s1 + .long 0x05060708 // s2 + .long 0x01020304 // s3 + + // coefficients for computing adler + .long 0x01010101 // s4/d2 + .long 0x01010101 // s5 + + .long BASE // s6 : BASE + .long 0x80078071 // s7 : 1/BASE in Q47 + + // q15 : d30.d31 + .long 0x1d1e1f20 // s0 + .long 0x191a1b1c // s1 + .long 0x15161718 // s2 + .long 0x11121314 // s3 + +NMAX_loc: + .long NMAX // NMAX + +#endif // defined(__arm__) + diff --git a/lib/cksum/arm64/adler32vec.S b/lib/cksum/arm64/adler32vec.S new file mode 100644 index 0000000..238cc58 --- /dev/null +++ b/lib/cksum/arm64/adler32vec.S @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if defined(__arm64__) + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +// Note: buf should have been 16-byte aligned in the caller function, + +// uLong adler32_vec(unsigned int adler, unsigned int sum2, const Bytef* buf, int len) { +// unsigned n; +// while (len >= NMAX) { +// len -= NMAX; +// n = NMAX / 16; /* NMAX is divisible by 16 */ +// do { +// DO16(buf); /* 16 sums unrolled */ +// buf += 16; +// } while (--n); +// MOD(adler); +// MOD(sum2); +// } +// if (len) { /* avoid modulos if none remaining */ +// while (len >= 16) { +// len -= 16; +// DO16(buf); +// buf += 16; +// } +// while (len--) { +// adler += *buf++; +// sum2 += adler; +// } +// MOD(adler); +// MOD(sum2); +// } +// return adler | (sum2 << 16); /* return recombined sums */ +// } + + +/* + DO16 vectorization: + given initial unsigned int sum2 and adler, and a new set of 16 input bytes (x[0:15]), it can be shown that + sum2 += (16*adler + 16*x[0] + 15*x[1] + ... + 1*x[15]); + adler += (x[0] + x[1] + ... + x[15]); + + similarly, 2 DO16 = DO32 vectorization: + given initial unsigned int sum2 and adler, and a new set of 32 input bytes (x[0:31]), it can be shown that + sum2 += (32*adler + 32*x[0] + 31*x[1] + ... + 1*x[31]); + adler += (x[0] + x[1] + ... + x[31]); + + NMAX = 5552 + NMAX/16 = 347 = 173*2 + 1 + + therefore, for a block of 5552 bytes + + n = 173; + do { + DO32(buf); buf+=32; + } while (n--); + + DO16(buf); buf+=16; + MOD(adler); + MOD(sum2); + + for a residual remaining len bytes, + while (len >= 32) { + DO32(buf); buf += 32; len -= 32; + } + if (len>=16) { + DO16(buf); buf += 16; len -= 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + + + + + DO32: + pack sum2:adler in a 64-bit register + + 0. sum2 += adler*32; + + sum2:adler += (sum2:adler) << (32+5); + + 1. (32, 31, ..., 1) * ( x0, x1, ..., x31) (v2, v3) * (v0, v1) + umull.8h v4, v2, v0 + umull2.8h v5, v2, v0 + umull.8h v6, v3, v1 + umull2.8h v7, v3, v1 + add.8h v4, v4, v5 + add.8h v6, v6, v7 + add.8h v4, v4, v6 + uaddlv s4, v4.8h + + add sum2, sum2, s4 + + 2. adler += (x0 + x1 + x2 + ... + x31) + + uaddlp v0.8h, v0.16b + uaddlp v1.8h, v1.16b + uaddlv s0, v0.8h + uaddlv s1, v1.8h + add s0, s0, s1 + + add adler, adler, s0 + + + therefore, this is what can be done to vectorize the above computation + 1. 16-byte aligned vector load into q2 (x[0:x15]) + 2. sum2 += (adler<<32); // pack adler/sum2 into a 64-bit word + 3. vmull.u8 (q9,q8),q2,d2 where d2 = (1,1,1,1...,1), (q9,q8) + 16 16-bit elements x[0:15] + 4. vmull.u8 (q11,q10),q2,q0 where q0 = (1,2,3,4...,16), (q11,q10) + 16 16-bit elements (16:1)*x[0:15] + 5. parallel add (with once expansion to 32-bit) (q9,q8) and (q11,q10) all the way to accumulate to adler and sum2 + + In this revision, whenever possible, 2 DO16 loops are combined into a DO32 loop. + 1. 32-byte aligned vector load into q2,q14 (x[0:x31]) + 2. sum2 += (adler<<32); + 3. vmull.u8 (4 q registers),(q2,q14),d2 where d2 = (1,1,1,1...,1), (4 q registers) : 32 16-bit elements x[0:31] + 4. vmull.u8 (4 q registers),(q2,q14),(q0,q15) where q0 = (1,...,32), (4 q regs) : 32 16-bit elements (32:1)*x[0:31] + 5. parallel add (with once expansion to 32-bit) the pair of (4 q regs) all the way to accumulate to adler and sum2 + + This change improves the performance by ~ 0.55 cycle/uncompress byte on ARM Cortex-A8. + +*/ + +/* + MOD implementation: + adler%BASE = adler - floor(adler*(1/BASE))*BASE; where (1/BASE) = 0x80078071 in Q47 + 1. vmull.u32 q2,(adler,sum2),(1/BASE) // *(1/BASE) in Q47 + 2. vshr.u64 q2,q2,#47 // floor function + 3. vpadd.u32 d4,d4,d5 // merge into a double word in d4 + 4. vmls.u32 (adler,sum2),d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE + +*/ + + + .text + .align 2 + .globl _adler32_vec +_adler32_vec: + + + + #define adler w0 + #define sum2 w1 + #define buf x2 + #define len w3 + #define nmax w4 + #define nvec w6 // vecs = NMAX/16 + + #define t x7 + + #define vadlersum2 v5 // only lower part + #define adlersum2 d5 // only lower part + + add x0, x0, x1, lsl #32 + adrp t, vec_table@PAGE + mov nmax, #NMAX // NMAX + add t, t, vec_table@PAGEOFF + ins vadlersum2.d[0], x0 + + +#if KERNEL + sub x6, sp, #8*16 + sub sp, sp, #8*16 + st1.4s {v0,v1,v2,v3},[x6],#4*16 + st1.4s {v4,v5,v6,v7},[x6],#4*16 +#endif + + cmp len, nmax // len vs NMAX + ld1.4s {v0, v1}, [t], #2*16 // loading up coefficients for adler/sum2 computation + ldr d7, [t] // for MOD operation + b.lt L_len_lessthan_NMAX // if (len < NMAX) skip the while loop + + sub len, len, nmax // pre-decrement len by NMAX + +L_while_len_ge_NMAX_loop: // while (len>=NMAX) { + + + // 5552/16 = 173*2 + 1, need 1 DO16 + 173 DO32 + + .macro DO16 + ld1.4s {v2},[buf] // 16 bytes input + shl d6, adlersum2, #(4+32) // adler * 16 + umull.8h v4, v2, v1 // 16*x0, 15*x1, ..., 9*x7 + add adlersum2, adlersum2, d6 // sum2 += adler * 16 + umlal2.8h v4, v2, v1 // 8*x8, 7*x9, ..., 1*x15 + uaddlv h2, v2.16b // x0+x1+x2+...+x15 + uaddlv s4, v4.8h // 16*x0 + 15*x1 + ... + 1*x15 + zip1.2s v4, v2, v4 + add buf, buf, #16 + add.2s vadlersum2, vadlersum2, v4 + .endm + + .macro DO32 + ld1.4s {v2,v3},[buf] // 32 bytes input + shl d6, adlersum2, #(5+32) // adler * 32 + umull.8h v4, v2, v0 // 32*x0, 31*x1, ..., 25*x7 + add adlersum2, adlersum2, d6 // sum2 += adler * 32 + umlal2.8h v4, v2, v0 // accumulate 24*x8, 23*x9, ..., 17*x15 + uaddlv h2, v2.16b // x0+x1+x2+...+x15 and extend from byte to short + umlal.8h v4, v3, v1 // accumulate 16*x16, 15*x17, ..., 9*x23 + uaddlv h6, v3.16b // x16+x17+x18+...+x31 and extend from byte to short + umlal2.8h v4, v3, v1 // accumulate 8*x24, 7*x25, ..., 1*x31 + uaddl.4s v2, v2, v6 // x0+x1+...+x31 and extend from short to int + uaddlv s4, v4.8h // 32*x0 + 31*x1 + ... + 1*x31 + zip1.2s v4, v2, v4 + add buf, buf, #32 + add.2s vadlersum2, vadlersum2, v4 + .endm + + .macro MOD_BASE + umull.2d v2,vadlersum2,v7[1] + ushr.2d v2, v2, #47 + ins v2.s[1], v2.s[2] + mls.2s vadlersum2,v2,v7[0] + .endm + + DO16 + mov nvec, #173 // number of DO32 loops + +0: + DO32 + + subs nvec, nvec, #1 + b.gt 0b + + MOD_BASE // MOD(adler,sum2); + + subs len, len, nmax // pre-decrement len by NMAX + b.ge L_while_len_ge_NMAX_loop // repeat while len >= NMAX + + adds len, len, nmax // post-increment len by NMAX + +L_len_lessthan_NMAX: + + subs len, len, #32 // pre-decrement len by 32 + b.lt L_len_lessthan_32 // if len < 32, branch to len16_loop + +L_len32_loop: + + DO32 + + subs len, len, #32 // len -= 32; + b.ge L_len32_loop + +L_len_lessthan_32: + + tst len, #16 + b.eq 1f + + DO16 + +1: + ands len, len, #15 + b.eq L_len_is_zero + + +L_remaining_len_loop: + ldrb w0, [buf], #1 // *buf++; + sub len, len, #1 + ins v2.d[0], x0 + + add adlersum2, adlersum2, d2 // adler += *buf + shl d6, adlersum2, #32 // shift adler up to sum2 position + add adlersum2, adlersum2, d6 // sum2 += adler + cbnz len, L_remaining_len_loop // break if len<=0 + + +L_len_is_zero: + + + MOD_BASE // mod(alder,BASE); mod(sum2,BASE); + + umov w0, vadlersum2.s[0] // adler + umov w1, vadlersum2.s[1] // sum2 + add w0, w0, w1, lsl #16 // to return adler | (sum2 << 16); + +#if KERNEL + ld1.4s {v0,v1,v2,v3},[sp],#4*16 + ld1.4s {v4,v5,v6,v7},[sp],#4*16 +#endif + + ret lr + + // constants to be loaded into q registers + .align 4 // 16 byte aligned + +vec_table: + + // coefficients for computing sum2 + .long 0x1d1e1f20 // s0 + .long 0x191a1b1c // s1 + .long 0x15161718 // s2 + .long 0x11121314 // s3 + .long 0x0d0e0f10 // s0 + .long 0x090a0b0c // s1 + .long 0x05060708 // s2 + .long 0x01020304 // s3 + + .long BASE // s6 : BASE + .long 0x80078071 // s7 : 1/BASE in Q47 + + + +#endif // __arm64__ diff --git a/lib/cksum/crc.c b/lib/cksum/crc.c new file mode 100644 index 0000000..432d008 --- /dev/null +++ b/lib/cksum/crc.c @@ -0,0 +1,121 @@ +/* $NetBSD: crc.c,v 1.18 2006/09/04 20:01:10 dsl Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * James W. Williams of NASA Goddard Space Flight Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +static const uint32_t crctab[] = { + 0x0, + 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, + 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, + 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, + 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, + 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, + 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, + 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, + 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, + 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, + 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, + 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, + 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, + 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, + 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, + 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, + 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, + 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, + 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, + 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, + 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, + 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, + 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, + 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, + 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, + 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, + 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, + 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, + 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, + 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, + 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, + 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, + 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, + 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, + 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, + 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, + 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, + 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, + 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, + 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, + 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, + 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, + 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 +}; + +#define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] + +/* + * Compute a POSIX 1003.2 checksum. Length is included in the checksum. + */ +uint32_t +crc(const void *buf, size_t len) +{ + const uint8_t *p = buf; + size_t nr = len; + uint32_t thecrc = INITIAL_CRC; + + for (p = buf; nr; p++, nr--) + COMPUTE(thecrc, *p); + + /* Include the length of the buffer. */ + for (; len != 0; len >>= 8) { + COMPUTE(thecrc, len & 0xff); + } + return ~thecrc; +} + +uint32_t +crc_byte(uint32_t thecrc, unsigned int byte_val) +{ + COMPUTE(thecrc, byte_val & 0xff); + return thecrc; +} diff --git a/lib/cksum/crc32.c b/lib/cksum/crc32.c new file mode 100644 index 0000000..c8eac12 --- /dev/null +++ b/lib/cksum/crc32.c @@ -0,0 +1,53 @@ +#include +#include +#include + +/* Table of CRCs of all 8-bit messages. */ +static uint32_t crc32_table[256]; + +/* Flag: has the table been computed? Initially false. */ +static int crc32_table_computed = 0; + +/* Make the table for a fast CRC. */ +static void make_crc32_table(void) +{ + uint32_t c; + int n, k; + + for (n = 0; n < 256; n++) { + c = (uint32_t) n; + for (k = 0; k < 8; k++) { + if (c & 1) + c = 0xedb88320L ^ (c >> 1); + else + c = c >> 1; + } + crc32_table[n] = c; + } + crc32_table_computed = 1; +} + +/* Update a running CRC with the bytes buf[0..len-1]--the CRC + should be initialized to all 1's, and the transmitted value + is the 1's complement of the final running CRC (see the + crc32() routine below). */ + +uint32_t update_crc32(uint32_t crc, const uint8_t *buf, + int len) +{ + uint32_t c = crc; + int n; + + if (!crc32_table_computed) + make_crc32_table(); + for (n = 0; n < len; n++) { + c = crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c; +} + +/* Return the CRC of the bytes buf[0..len-1]. */ +uint32_t crc32(const uint8_t *buf, int len) +{ + return update_crc32(0xffffffffL, buf, len) ^ 0xffffffffL; +} diff --git a/lib/cksum/debug.c b/lib/cksum/debug.c new file mode 100644 index 0000000..7839ca7 --- /dev/null +++ b/lib/cksum/debug.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007-2009, 2013-2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +int do_crc(int argc, struct cmd_arg *args) +{ + if (argc < 3) { + printf("not enough arguments.\n"); + printf("%s
\n", args[0].str); + return -1; + } + + if (!security_allow_memory((void *)args[1].u, args[2].u)) { + printf("Permission Denied\n"); + return -1; + } + + uint32_t crc32 = crc((void *)args[1].u, args[2].u); + printf("crc %u (length %zu)\n", crc32, args[2].u); + + return 0; +} + diff --git a/lib/cksum/library.mk b/lib/cksum/library.mk new file mode 100644 index 0000000..f437337 --- /dev/null +++ b/lib/cksum/library.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBCKSUM_DIR := $(GET_LOCAL_DIR) +LIBCKSUM_BUILD := $(call TOLIBDIR,$(LIBCKSUM_DIR)/LIBCKSUM.a) +COMMONLIBS += LIBCKSUM + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBCKSUM_OBJS := \ + $(LIBCKSUM_DIR)/adler32.o \ + $(LIBCKSUM_DIR)/$(ARCH)/adler32vec.o \ + $(LIBCKSUM_DIR)/crc.o \ + $(LIBCKSUM_DIR)/crc32.o \ + $(LIBCKSUM_DIR)/debug.o \ + $(LIBCKSUM_DIR)/siphash.o + +LIBCKSUM_OBJS := $(call TOLIBOBJDIR,$(LIBCKSUM_OBJS)) + +ALL_DEPS += $(LIBCKSUM_OBJS:%o=%d) + +$(LIBCKSUM_BUILD): $(LIBCKSUM_OBJS) + +endif diff --git a/lib/cksum/rules.mk b/lib/cksum/rules.mk new file mode 100644 index 0000000..d2bd9d8 --- /dev/null +++ b/lib/cksum/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2007-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_CKSUM=1 +LIBRARY_MODULES += lib/cksum diff --git a/lib/cksum/siphash.c b/lib/cksum/siphash.c new file mode 100644 index 0000000..8d85db7 --- /dev/null +++ b/lib/cksum/siphash.c @@ -0,0 +1,220 @@ +/* + SipHash reference C implementation + + Copyright (c) 2012 Jean-Philippe Aumasson + Copyright (c) 2012 Daniel J. Bernstein + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . + */ +#include +#include +#include +#include +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint8_t u8; + +#define cROUNDS 2 +#define dROUNDS 4 + +#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) ) + +#define U32TO8_LE(p, v) \ + (p)[0] = (u8)((v) ); (p)[1] = (u8)((v) >> 8); \ + (p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24); + +#define U64TO8_LE(p, v) \ + U32TO8_LE((p), (u32)((v) )); \ + U32TO8_LE((p) + 4, (u32)((v) >> 32)); + +#define U8TO64_LE(p) \ + (((u64)((p)[0]) ) | \ + ((u64)((p)[1]) << 8) | \ + ((u64)((p)[2]) << 16) | \ + ((u64)((p)[3]) << 24) | \ + ((u64)((p)[4]) << 32) | \ + ((u64)((p)[5]) << 40) | \ + ((u64)((p)[6]) << 48) | \ + ((u64)((p)[7]) << 56)) + +#define SIPROUND \ + do { \ + v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \ + v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \ + v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \ + v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \ + } while(0) + +/* SipHash-2-4 */ +void siphash( uint8_t *out, const uint8_t *in, size_t inlen, const uint8_t *k ) +{ + /* "somepseudorandomlygeneratedbytes" */ + u64 v0 = 0x736f6d6570736575ULL; + u64 v1 = 0x646f72616e646f6dULL; + u64 v2 = 0x6c7967656e657261ULL; + u64 v3 = 0x7465646279746573ULL; + u64 b; + u64 k0 = U8TO64_LE( k ); + u64 k1 = U8TO64_LE( k + 8 ); + u64 m; + int i; + const u8 *end = in + inlen - ( inlen % sizeof( u64 ) ); + const int left = inlen & 7; + b = ( ( u64 )inlen ) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + + for ( ; in != end; in += 8 ) + { + m = U8TO64_LE( in ); +#ifdef SIPHASH_DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) compress %08x %08x\n", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m ); +#endif + v3 ^= m; + + for( i=0; i> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) padding %08x %08x\n", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b ); +#endif + v3 ^= b; + + for( i=0; i> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); +#endif + v2 ^= 0xff; + + for( i=0; i> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) compress %08x %08x\n", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m ); +#endif + v3 ^= m; + + for( i=0; i> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) padding %08x %08x\n", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b ); +#endif + v3 ^= b; + + for( i=0; i> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); +#endif + v2 ^= 0xff; + + for( i=0; i +#include + +struct crc_test { + const char *data; + uint32_t len; + uint32_t expected; +}; + +static struct crc_test crc32_tests[] = { + { "", 0, 0x00000000 }, + { "a", 1, 0xe8b7be43 }, + { "abc", 3, 0x352441c2 }, + { "aaaa", 4, 0xad98e545 }, + { "abcdefghijklmnopqrstuvwxyz", 26, 0x4c2750bd } +}; + +void test_crc32(uintptr_t param) +{ + for (unsigned i = 0; i < sizeof crc32_tests / sizeof(crc32_tests[0]); i++) { + struct crc_test *test = &crc32_tests[i]; + uint32_t calculated = crc32((const uint8_t *)test->data, test->len); + + TEST_ASSERT_EQ(calculated, test->expected); + } +} + +void test_update_crc32(uintptr_t param) +{ + for (unsigned i = 0; i < sizeof crc32_tests / sizeof(crc32_tests[0]); i++) { + struct crc_test *test = &crc32_tests[i]; + + uint32_t calculated = 0xffffffff; + const uint8_t *data = (const uint8_t *)test->data; + + if (test->len != 0) { + calculated = update_crc32(calculated, data, 1); + calculated = update_crc32(calculated, data + 1, test->len - 1); + } else { + calculated = update_crc32(calculated, data, test->len); + } + + calculated ^= 0xffffffff; + + TEST_ASSERT_EQ(calculated, test->expected); + + // updating with data of length 0 shouldn't have an effect + calculated = update_crc32(calculated, (const uint8_t *)"a", 0); + + TEST_ASSERT_EQ(calculated, test->expected); + } +} + +// generated with the "cksum" commandline tool +static struct crc_test crc_tests[] = { + { "", 0, 4294967295 }, + { "a", 1, 1220704766 }, + { "abc", 3, 1219131554 }, + { "aaaa", 4, 3100911197 }, + { "abcdefghijklmnopqrstuvwxyz", 26, 2713270184 }, + { "\0\0\0\0", 4, 3975907619 }, +}; + +void test_crc(uintptr_t data) +{ + for (unsigned i = 0; i < sizeof crc_tests / sizeof(crc_tests[0]); i++) { + struct crc_test *test = &crc_tests[i]; + uint32_t calculated = crc((const uint8_t *)test->data, test->len); + + TEST_ASSERT_EQ(calculated, test->expected); + } +} + +void test_crc_byte(uintptr_t data) +{ + for (unsigned i = 0; i < sizeof crc_tests / sizeof(crc_tests[0]); i++) { + struct crc_test *test = &crc_tests[i]; + uint32_t calculated = INITIAL_CRC; + + for (uint32_t j = 0; j < test->len; j++) + calculated = crc_byte(calculated, ((const uint8_t *)test->data)[j]); + + for (uint32_t n = test->len; n != 0; n >>= 8) + calculated = crc_byte(calculated, n & 0xff); + + calculated = ~calculated; + + TEST_ASSERT_EQ(calculated, test->expected); + } +} + +static struct crc_test adler32_tests[] = { + { "", 0, 0x00000001 }, + { "a", 1, 0x00620062 }, + { "abc", 3, 0x024d0127 }, + { "message digest", 14, 0x29750586 }, + { "abcdefghijklmnopqrstuvwxyz", 26, 0x90860b20 }, +}; + +void test_adler32(uintptr_t data) +{ + for (unsigned i = 0; i < sizeof adler32_tests / sizeof(adler32_tests[0]); i++) { + struct crc_test *test = &adler32_tests[i]; + uint32_t calculated = adler32((const uint8_t *)test->data, test->len); + + TEST_ASSERT_EQ(calculated, test->expected); + } +} + +const uint8_t siphash_vectors[64][SIPHASH_HASH_SIZE] = +{ + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } +}; + +void test_siphash(uintptr_t context) +{ + uint8_t in[64], out[SIPHASH_HASH_SIZE], k[SIPHASH_KEY_SIZE]; + unsigned i; + + for(i = 0; i < 16; ++i) + k[i] = i; + + for(i = 0; i < sizeof(in); ++i) + { + in[i] = i; + siphash(out, in, i, k); + + TEST_ASSERT_MEM_EQ(out, siphash_vectors[i], sizeof(out)); + } +} + +void test_siphash_aligned(uintptr_t context) +{ + uint64_t in_aligned[64 / 8]; + uint64_t out[SIPHASH_HASH_SIZE / 8]; + uint64_t key_aligned[SIPHASH_KEY_SIZE / 8]; + uint8_t *in = (uint8_t *)&in_aligned[0]; + uint8_t *key = (uint8_t *)&key_aligned[0]; + unsigned i; + + for(i = 0; i < 16; ++i) + key[i] = i; + + for(i = 0; i < sizeof(in); ++i) + { + in[i] = i; + siphash_aligned(out, in_aligned, i, key_aligned); + + TEST_ASSERT_MEM_EQ(out, siphash_vectors[i], sizeof(out)); + } +} + +struct test_suite cksum_suite = { + .name = "cksum", + .test_cases = { + { "crc32", test_crc32, 0, "Tests the crc32 checksum function" }, + { "update_crc32", test_update_crc32, 0, "Tests the update_crc32 checksum function" }, + { "crc", test_crc, 0, "Tests the crc POSIX 1003.2 checksum function" }, + { "crc_byte", test_crc_byte, 0, "Tests the crc_byte bytewise POSIX 1003.2 checksum function" }, + { "adler32", test_adler32, 0, "Tests the adler32 checksum function" }, + { "siphash", test_siphash, 0, "Tests the siphash checksum function" }, + { "siphash_aligned", test_siphash_aligned, 0, "Tests the siphash_aligned checksum function" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(cksum_suite); diff --git a/lib/cksum/tests.mk b/lib/cksum/tests.mk new file mode 100644 index 0000000..69556bd --- /dev/null +++ b/lib/cksum/tests.mk @@ -0,0 +1,39 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := cksum + +TEST_OBJS := \ + $(LOCAL_DIR)/adler32.o \ + $(LOCAL_DIR)/crc.o \ + $(LOCAL_DIR)/crc32.o \ + $(LOCAL_DIR)/siphash.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o + +ifeq ($(ARM_ARCH),armv7) +TEST_OBJS += \ + $(LOCAL_DIR)/arm/adler32vec.o +endif + +ifeq ($(ARM_ARCH),armv7k) +TEST_OBJS += \ + $(LOCAL_DIR)/arm/adler32vec.o +endif + +ifeq ($(ARM_ARCH),arm64) +TEST_OBJS += \ + $(LOCAL_DIR)/arm64/adler32vec.o +endif + diff --git a/lib/devicetree/devicetree.c b/lib/devicetree/devicetree.c new file mode 100644 index 0000000..594996a --- /dev/null +++ b/lib/devicetree/devicetree.c @@ -0,0 +1,682 @@ +/* + * Copyright (C) 2014-2015 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include "devicetree_private.h" + +/* + * Device Tree Parsing Library + * + * This library implements the device tree serializer/updater/deserializer. + * + * There should be more stuff here, but for now a quick note. + * + * The dt_size variable contains the size the device tree will have upon + * serialization. Any modification to the deserialized device tree must + * update this variable so that it continues to contain the size the device + * tree will have on re-serialization. This is because other modules need + * to know the size of the device tree in order to properly lay out memory + * (for example, in order to allocate a region of the kernel's memory map) + */ + +static void free_node(dt_node_t *node); +void dt_free(dt_node_t *dt); + +static size_t dt_size; +static dt_node_t *dt_root; +static void *dt_data; +static bool dt_sealed; + +#define ROUND_SIZE(s) (((s) + 3) & ~3) + +void dt_init(void) +{ + dt_size = 0; + if (dt_root != NULL) { + dt_free(dt_root); + dt_root = NULL; + } + dt_data = NULL; + dt_sealed = false; +} + +size_t dt_get_size(void) +{ + return dt_size; +} + +static void free_node(dt_node_t *node) +{ + if (node->props != NULL) { + for (uint32_t i = 0; i < node->nprops; i++) { + if (node->props[i].name_malloced) + free(node->props[i].name); + if (node->props[i].data_malloced) + free(node->props[i].data); + } + free(node->props); + node->props = NULL; + } + if (node->children != NULL) { + for (uint32_t i = 0; i < node->nchildren; i++) { + free_node(&node->children[i]); + } + free(node->children); + node->children = NULL; + } +} + +/* Replaces placeholder values during deserialization. The placeholders are normal strings, + * but the size field has bit 31 set to indicate it's a placeholder. If iBoot successfully + * finds the requested data, it replaces the placeholder value with the requested data + * (and sets bit 31 of the size back to 0). If iBoot doesn't find the requested data, + * it removes the property from the device tree. + * + * Two kinds of placeholders are currently supported: + * syscfg/ - looks up the key 'SKey' in syscfg + * syscfg// - looks up the key 'SKey' in syscfg, and pads/truncates to specified + * length (for compatibility with old-style devicetree placeholders) + * macaddr/ - looks up the mac address envname in the environment using env_get_ethaddr + * zeroes/ - creates a property with bytes zero bytes + * + * Multiple placeholders can be specified, with options separated by commas. The first + * placeholder found is used. + */ +static bool expand_placeholder_prop(dtprop_t *prop) +{ + uint32_t alloc_size; + uint8_t ethaddr[6]; + uint8_t dummy = 0; + void *data = NULL; + uint32_t data_size = 0; + uint32_t data_pad_size = 0; + char *placeholder; + char *next_placeholder; + // make sure placeholder is null-terminated + if (memchr(prop->data, '\0', prop->size) == NULL) { + panic("devicetree placeholder property '%s' missing null terminator", prop->name); + } + + placeholder = prop->data; + next_placeholder = placeholder; + + while ((placeholder = strsep(&next_placeholder, ",")) != NULL) { + if (memcmp(placeholder, "syscfg/", 7) == 0) { + char *details = placeholder + 7; + uint8_t *tag_str; + char *len_str; + uint32_t len; + uint32_t tag; + + tag_str = (uint8_t *)details; + + len_str = details; + strsep(&len_str, "/"); + + if (strlen(details) != 4) { + panic("dt: wrong length on placeholder %s", placeholder); + } + + tag = tag_str[0] << 24 | tag_str[1] << 16 | tag_str[2] << 8 | tag_str[3]; + + if (syscfg_find_tag(tag, &data, &data_size)) { + // For compatibility with old-style devicetree placeholders, a length + // can be specified to truncate/pad the syscfg data to + if (len_str != NULL) { + len = (uint32_t)strtoul(len_str, NULL, 0); + if (len > data_size) { + data_pad_size = len - data_size; + } else { + data_size = len; + } + } + + break; + } + } else if (memcmp(placeholder, "macaddr/", 8) == 0) { + char *details = placeholder + 8; + + if (env_get_ethaddr(details, ethaddr) == 0) { + data = ethaddr; + data_size = sizeof(ethaddr); + break; + } + } else if (memcmp(placeholder, "zeroes/", 7) == 0) { + char *details = placeholder + 7; + + // Set data to a dummy pointer so that data != NULL but request + // copying 0 bytes. The padding will all get zeroed, resulting + // in a property value with the requested number of zeroes + data = &dummy; + data_size = 0; + data_pad_size = (uint32_t)strtoul(details, NULL, 0); + } + + placeholder = next_placeholder; + } + + uint32_t original_size = ROUND_SIZE(prop->size); + + if (data != NULL) { + alloc_size = ROUND_SIZE(data_size + data_pad_size); + + // Since this function is called during initial parsing, we know + // that the storage for the placeholder was in the original devicetree + // buffer and not malloced in a new buffer. We only need a new buffer + // if the new data is longer than the placeholder + if (alloc_size > original_size) { + prop->data = malloc(alloc_size); + prop->data_malloced = true; + } + memcpy(prop->data, data, data_size); + // zero-fill any padding bytes + memset((uint8_t *)prop->data + data_size, 0, alloc_size - data_size); + + prop->size = data_size + data_pad_size; + + return true; + } else { + return false; + } +} + +static bool parse_node(dt_node_t *node, uint8_t **addrptr, const uint8_t *endaddr) +{ + uint8_t *addr = *addrptr; + + if ((size_t)(endaddr - addr) < 2 * sizeof(uint32_t)) + goto error; + + memcpy(&node->nprops, addr, 4); + memcpy(&node->nchildren, addr + 4, 4); + addr += 2 * sizeof(uint32_t); + dt_size += 2 * sizeof(uint32_t); + + // Sanity checks + if (node->nprops > 1024) { + dprintf(DEBUG_INFO, "dt: too many properties\n"); + goto error; + } + if (node->nchildren > 1024) { + dprintf(DEBUG_INFO, "dt: too many children\n"); + goto error; + } + + if (node->nprops > 0) + node->props = calloc(sizeof(*node->props), node->nprops); + if (node->nchildren > 0) + node->children = calloc(sizeof(*node->children), node->nchildren); + + // Parse each property, recording its size, the address of the name, + // and the address of its data. + // We could find the "name" property and cache it here, but instead + // we'll do that if we ever traverse this node looking for a node + // by path. + for(uint32_t i = 0; i < node->nprops; i++) { + dtprop_t *prop; + uint32_t size_and_flags; + bool prop_removed = false; + + ASSERT(addr <= endaddr); + + prop = &node->props[i]; + + if((size_t)(endaddr - addr) < kPropNameLength + sizeof(uint32_t)) { + dprintf(DEBUG_INFO, "dt: not enough bytes for property name '%s'\n", (char *)addr); + goto error; + } + if (memchr(addr, 0, kPropNameLength) == NULL) { + dprintf(DEBUG_INFO, "dt: unterminated property name '%s'\n", (char *)addr); + goto error; + } + + prop->name = (char *)addr; + + memcpy(&size_and_flags, addr + kPropNameLength, sizeof(uint32_t)); + addr += kPropNameLength + sizeof(uint32_t); + + prop->size = size_and_flags & DT_PROP_SIZE_MASK; + + if ((size_t)(endaddr - addr) < ROUND_SIZE(prop->size)) { + dprintf(DEBUG_INFO, "dt: not enough bytes for property '%s'\n", prop->name); + goto error; + } + + prop->data = addr; + addr += ROUND_SIZE(prop->size); + + if (size_and_flags & DT_PROP_FLAG_PLACEHOLDER) { + // if placeholder expansion fails, then recycle the property slot + // we used for the placeholder + prop_removed = !expand_placeholder_prop(prop); + if (prop_removed) { + node->nprops--; + i--; + } + } + + // Account for the size of the property after any placeholder expansion has occurred + if (!prop_removed) + dt_size += kPropNameLength + sizeof(uint32_t) + ROUND_SIZE(prop->size); + } + + for (uint32_t i = 0; i < node->nchildren; i++) { + if (!parse_node(&node->children[i], &addr, endaddr)) + goto error; + } + + *addrptr = addr; + + return true; +error: + free_node(node); + + return false; +} + +dt_node_t *dt_deserialize(void *dtaddr, size_t dtlength) +{ + uint8_t *startptr; + uint8_t *endptr; + dt_node_t *node; + + dt_init(); + + node = calloc(sizeof(*node), 1); + startptr = dtaddr; + endptr = dtaddr + dtlength; + + if (!parse_node(node, &startptr, endptr)) { + dt_size = 0; + free(node); + return NULL; + } + + dt_root = node; + + return node; +} + +void dt_free(dt_node_t *dt) +{ + free_node(dt); + free(dt); +} + +static void write_prop(char *name, void *data, uint32_t data_size, uint8_t **bufptr, uint8_t *end) +{ + uint8_t *buf = *bufptr; + uint32_t prop_buf_size = ROUND_SIZE(data_size); + uint32_t total_size = kPropNameLength + sizeof(uint32_t) + prop_buf_size; + + // no overflow + if (prop_buf_size < data_size || total_size < prop_buf_size) { + panic("devicetree integer overflow"); + } + + // Make sure there's room for the property name and value + if ((size_t)(end - buf) < total_size) { + panic("devicetree buffer overflow"); + } + + // Write property name, padding with zeroes to 32 bytes + memset(buf, 0, kPropNameLength); + strlcpy((char *)buf, name, kPropNameLength); + buf += kPropNameLength; + + // Then property size + memcpy(buf, &data_size, sizeof(uint32_t)); + buf += sizeof(uint32_t); + + // And property value, which won't be present if size is 0 + if (prop_buf_size != 0) { + memcpy(buf, data, data_size); + // Pad if needed to multiple of 4 bytes + if (data_size != prop_buf_size) + memset(buf + data_size, 0, prop_buf_size - data_size); + buf += prop_buf_size; + } + + RELEASE_ASSERT(buf <= end); + + // let caller know how far we wrote + *bufptr = buf; +} + +static void write_node(dt_node_t *node, uint8_t **bufptr, uint8_t *end) +{ + uint8_t *buf = *bufptr; + + RELEASE_ASSERT(*bufptr < end); + + // Make sure there's room for the node header + if ((size_t)(end - buf) < 2 * sizeof(uint32_t)) + panic("devicetree buffer overflow"); + // Write the node header (number of properties, then number of children) + memcpy(buf, &node->nprops, 4); + memcpy(buf + 4, &node->nchildren, 4); + buf += 8; + + // Write out each property + for (uint32_t i = 0; i < node->nprops; i++) { + dtprop_t *prop = &node->props[i]; + + write_prop(prop->name, prop->data, prop->size, &buf, end); + } + + // Write out all of this node's children + for (uint32_t i = 0; i < node->nchildren; i++) { + write_node(&node->children[i], &buf, end); + } + + // Let the caller know how far we wrote + *bufptr = buf; + + RELEASE_ASSERT(*bufptr <= end); +} + +void dt_serialize(dt_node_t *dt, void *buffer, size_t bufferlen) +{ + uint8_t *startptr = buffer; + uint8_t *endptr = startptr + bufferlen; + + if (dt == NULL) + dt = dt_root; + + RELEASE_ASSERT(dt != NULL); + + if (bufferlen < dt_size) + panic("devicetree length %zu > buffer size %zu", dt_size, bufferlen); + + write_node(dt, &startptr, endptr); + + // Make sure dt_size is accurate + ASSERT(startptr == (uint8_t *)buffer + dt_size); +} + +dt_node_t *dt_get_root(void) +{ + return dt_root; +} + +bool dt_find_node(dt_node_t *root, const char *path, dt_node_t **node) +{ + uint32_t path_len; + const char *rest; + + if (root == NULL) { + if (dt_root == NULL) + return false; + root = dt_root; + } + + if(path[0] == '\0') { + *node = root; + return true; + } + + rest = strchr(path, '/'); + if (rest == NULL) { + rest = ""; + path_len = strlen(path); + } else { + path_len = rest - path; + rest++; + } + + for (uint32_t i = 0; i < root->nchildren; i++) { + dt_node_t *child = &root->children[i]; + if (child->name == NULL) { + char *prop_name = "name"; + if (!dt_get_prop(child, &prop_name, &child->name, &child->name_size)) { + dprintf(DEBUG_CRITICAL, "dt: found node with no name: %p\n", child); + continue; + } + } + if (child->name_size == path_len + 1 && memcmp(path, child->name, path_len) == 0) { + return dt_find_node(child, rest, node); + } + } + + return false; +} + +static bool find_prop(dt_node_t *node, const char *name, dtprop_t **prop_out) +{ + ASSERT(node != NULL); + ASSERT(name != NULL); + + for (uint32_t i = 0; i < node->nprops; i++) { + dtprop_t *prop = &node->props[i]; + + if (strncmp(name, prop->name, kPropNameLength) == 0) { + if (prop_out != NULL) + *prop_out = prop; + return true; + } + } + + return false; +} + +bool dt_get_prop(dt_node_t *node, char **prop_name, void **prop_data, uint32_t *prop_size) +{ + dtprop_t *prop; + + ASSERT(node != NULL); + ASSERT(prop_name != NULL && *prop_name != NULL); + + if(find_prop(node, *prop_name, &prop)) { + *prop_name = prop->name; + if (prop_size != NULL) + *prop_size = prop->size; + if (prop_data != NULL) + *prop_data = prop->data; + return true; + } else { + return false; + } +} + +// Like dt_find_prop, but with a less obnoxious interface on prop_name +bool dt_find_prop(dt_node_t *node, const char *prop_name, void **prop_data, uint32_t *prop_size) +{ + dtprop_t *prop; + + ASSERT(node != NULL); + ASSERT(prop_name != NULL); + + if(find_prop(node, prop_name, &prop)) { + if (prop_size != NULL) + *prop_size = prop->size; + if (prop_data != NULL) + *prop_data = prop->data; + return true; + } else { + return false; + } +} + +bool dt_has_prop(dt_node_t *node, const char *prop_name) +{ + return dt_find_prop(node, prop_name, NULL, NULL); +} + +const char *dt_get_node_name(dt_node_t *node) +{ + if (node->name == NULL) { + char *prop_name = "name"; + dt_get_prop(node, &prop_name, &node->name, &node->name_size); + } + + return node->name; +} + +static dtprop_t *add_prop(dt_node_t *node, const char *name) +{ + uint32_t nprops = node->nprops + 1; + dtprop_t *prop; + + ASSERT(strlen(name) < kPropNameLength); + + node->props = realloc(node->props, nprops * sizeof(*node->props)); + + prop = &node->props[nprops - 1]; + memset(prop, 0, sizeof(*prop)); + + prop->name = calloc(kPropNameLength, 1); + strlcpy(prop->name, name, kPropNameLength); + prop->name_malloced = true; + + node->nprops = nprops; + + // The device tree will grow by the size of the property name and length fields + // The caller of this function will account for the growth from the value + dt_size += 4 + kPropNameLength; + + return prop; +} + +void dt_set_prop(dt_node_t *node, const char *name, const void *data, uint32_t size) +{ + dtprop_t *prop; + size_t cur_alloc_size; + size_t new_alloc_size; + + ASSERT(node != NULL); + ASSERT(name != NULL); + ASSERT(size == 0 || data != NULL); + ASSERT(!dt_sealed); + + if (!find_prop(node, name, &prop)) + prop = add_prop(node, name); + + // if we're changing the name, get rid of the cache + if (prop->data == node->name) { + node->name = NULL; + node->name_size = 0; + } + + // Data is always serialized with length padded to 4 bytes + new_alloc_size = ROUND_SIZE(size); + cur_alloc_size = ROUND_SIZE(prop->size); + + // zero-length properties are legal, but malloc(0) isn't + // rest of this file handles prop.data == NULL and prop.size == 0 properly + if (new_alloc_size > 0) { + // Only re-allocate if needed. data_malloced will be false for + // newly created properties because add_prop zeroes the struct + // before returning it + if (cur_alloc_size < new_alloc_size) { + if (!prop->data_malloced) + prop->data = malloc(new_alloc_size); + else + prop->data = realloc(prop->data, new_alloc_size); + prop->data_malloced = true; + } + memcpy(prop->data, data, size); + // zero-fill any padding bytes + memset((uint8_t *)prop->data + size, 0, new_alloc_size - size); + } + + prop->size = size; + + // add_prop accounted for the name and length fields, we just need + // to fgure out the difference from the value. Since add_prop zeroes + // out the struct, for new properties, cur_alloc_size will be 0 + dt_size += new_alloc_size - cur_alloc_size; +} + +void dt_set_prop_32(dt_node_t *node, const char *name, uint32_t value) +{ + dt_set_prop(node, name, &value, sizeof(value)); +} + +void dt_set_prop_64(dt_node_t *node, const char *name, uint64_t value) +{ + dt_set_prop(node, name, &value, sizeof(value)); +} + +void dt_set_prop_addr(dt_node_t *node, const char *name, uintptr_t value) +{ + dt_set_prop(node, name, &value, sizeof(value)); +} + +void dt_set_prop_str(dt_node_t *node, const char *name, const char *str) +{ + dt_set_prop(node, name, str, strlen(str) + 1); +} + +bool dt_remove_prop(dt_node_t *node, const char *name) +{ + ASSERT(node != NULL); + ASSERT(name != NULL); + ASSERT(!dt_sealed); + + for (uint32_t i = 0; i < node->nprops; i++) { + dtprop_t *prop = &node->props[i]; + + if (strncmp(name, prop->name, kPropNameLength) == 0) { + // unlikely, but if we're removing the name, get rid of the cache + if (prop->data == node->name) { + node->name = NULL; + node->name_size = 0; + } + + dt_size -= ROUND_SIZE(prop->size) + 4 + kPropNameLength; + + memmove(prop, prop + 1, (node->nprops - i - 1) * sizeof(*prop)); + node->nprops--; + + return true; + } + } + + return false; +} + +bool dt_rename_prop(dt_node_t *node, const char *name, const char *new_name) +{ + ASSERT(node != NULL); + ASSERT(name != NULL); + ASSERT(new_name != NULL); + ASSERT(!dt_sealed); + + dtprop_t *prop; + size_t new_name_len = strlen(new_name); + + ASSERT(new_name_len < kPropNameLength - 1); + + if (find_prop(node, name, &prop)) { + // unlikely, but if we're renaming the name property, get rid of the cache + if (prop->data == node->name) { + node->name = NULL; + node->name_size = 0; + } + + memset(prop->name, 0, kPropNameLength); + memcpy(prop->name, new_name, new_name_len); + + return true; + } else { + return false; + } +} + +void dt_seal(void) +{ + dt_sealed = true; +} diff --git a/lib/devicetree/devicetree_debug.c b/lib/devicetree/devicetree_debug.c new file mode 100644 index 0000000..6250542 --- /dev/null +++ b/lib/devicetree/devicetree_debug.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include "devicetree_private.h" + +void print_indent(int level) +{ + for (int i = 0; i < level; i++) + putchar(' '); +} + +void print_property(struct dtprop *prop, bool verbose) +{ + uint32_t prop_size; + bool truncated = false; + + printf("%s [0x%x]:", prop->name, prop->size); + + prop_size = prop->size; + if (!verbose && prop_size > 16) { + prop_size = 16; + truncated = true; + } + + for (uint32_t i = 0; i < prop_size; i++) + printf(" %02x", ((uint8_t *)prop->data)[i]); + + if (truncated) + printf(" ..."); + + putchar('\n'); +} + +void dump_tree_int(dt_node_t *node, int indent, bool verbose) +{ + const char *node_name; + + node_name = dt_get_node_name(node); + if (node_name == NULL) + node_name = ""; + + print_indent(indent); + printf("%s {\n", node_name); + indent += 4; + + for (unsigned i = 0; i < node->nprops; i++) { + print_indent(indent); + print_property(&node->props[i], verbose); + } + + for (unsigned i = 0; i < node->nchildren; i++) + dump_tree_int(&node->children[i], indent, verbose); + + indent -= 4; + print_indent(indent); + printf("}\n"); +} + +#if DEBUG_BUILD +void dt_dump(bool verbose) +{ + dump_tree_int(dt_get_root(), 0, verbose); +} +#endif + diff --git a/lib/devicetree/devicetree_load.c b/lib/devicetree/devicetree_load.c new file mode 100644 index 0000000..ec66c20 --- /dev/null +++ b/lib/devicetree/devicetree_load.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2010-2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* load the device tree out of flash into a heap-based piece of memory */ +int dt_load(void) +{ + int result = 0; + addr_t dtaddr; + size_t dtsize; + + /* load to default addresses */ + dtaddr = mib_get_addr(kMIBTargetDefaultDeviceTreeAddress); + dtsize = mib_get_size(kMIBTargetDefaultDeviceTreeSize); + + /* if we don't already have a devicetree, look for a known image containing one */ + if (dt_get_size() == 0) { + + if (image_load_type(&dtaddr, &dtsize, IMAGE_TYPE_DEVTREE, 0) != 0) { + dprintf(DEBUG_INFO, "load_device_tree: failed to find device tree\n"); + return -1; + } + + if (!dt_deserialize((void *)dtaddr, dtsize)) { + dprintf(DEBUG_CRITICAL, "Mal-formed devicetree\n"); + result = -1; + } + } + + /* consolidate environment */ + security_consolidate_environment(); + + return 0; +} + +int dt_load_file(const char *path) +{ + int result = 0; + u_int32_t type; + addr_t dtaddr; + size_t dtsize; + + /* load to default addresses */ + dtaddr = mib_get_addr(kMIBTargetDefaultDeviceTreeAddress); + dtsize = mib_get_size(kMIBTargetDefaultDeviceTreeSize); + + // Image3 requires the non-restore types + if (mib_get_u32(kMIBPlatformImageFormat) == 4) { + // Image4 + type = IMAGE_TYPE_DEVTREE_RESTORE; + } else { + // Image3 + type = IMAGE_TYPE_DEVTREE; + } + + if (image_load_file(path, &dtaddr, &dtsize, &type, 1, NULL, 0) != 0) { + dprintf(DEBUG_INFO, "failed to load devicetree from %s", path); + dt_init(); + return -1; + } + + if (!dt_deserialize((void *)dtaddr, dtsize)) { + dprintf(DEBUG_CRITICAL, "Mal-formed devicetree\n"); + result = -1; + } + + /* consolidate environment */ + security_consolidate_environment(); + + return 0; +} + +int do_devicetree(int argc, struct cmd_arg *argv) +{ + addr_t addr = mib_get_addr(kMIBTargetDefaultLoadAddress); + addr_t dtaddr = mib_get_addr(kMIBTargetDefaultDeviceTreeAddress); + size_t dtsize = mib_get_size(kMIBTargetDefaultDeviceTreeSize); + size_t len; + u_int32_t type; + + len = env_get_uint("filesize", 0); + +#if !RELEASE_BUILD + if ((argc > 3) || ((argc > 1) && !strcmp("help", argv[1].str))) { + printf("usage:\n\t%s [] [
]\n", argv[0].str); + return -1; + } + + addr = env_get_uint("loadaddr", addr); + + if (argc > 1) + len = argv[1].u; + if (argc > 2) + addr = argv[2].u; +#endif + + if (len == 0) { + printf("filesize variable invalid or not set, aborting\n"); + return -1; + } + if (len > dtsize) { + printf("Device Tree too large\n"); + return -1; + } + if (!security_allow_memory((void *)addr, len)) { + printf("Permission Denied\n"); + return -1; + } + + // Image3 requires the non-restore types + if (mib_get_u32(kMIBPlatformImageFormat) == 4) { + // Image4 + type = IMAGE_TYPE_DEVTREE_RESTORE; + } else { + // Image3 + type = IMAGE_TYPE_DEVTREE; + } + + if (image_load_memory(addr, len, &dtaddr, &dtsize, &type, 1, NULL, 0) != 0) { + printf("Device Tree image not valid\n"); + dt_init(); + return -1; + } + + dt_deserialize((void *)dtaddr, dtsize); + + /* consolidate environment */ + security_consolidate_environment(); + + printf("loaded device tree at %p of size 0x%zx, from image at %p\n", (void *)dtaddr, dtsize, (void *)addr); + + return 0; +} + diff --git a/lib/devicetree/devicetree_private.h b/lib/devicetree/devicetree_private.h new file mode 100644 index 0000000..a06b6b3 --- /dev/null +++ b/lib/devicetree/devicetree_private.h @@ -0,0 +1,32 @@ +#ifndef DEVICETREE_PRIVATE_H +#define DEVICETREE_PRIVATE_H +#include +#include + +#define DT_PROP_FLAG_PLACEHOLDER (1 << 31) +#define DT_PROP_FLAGS_MASK (0xf0000000) +#define DT_PROP_SIZE_MASK (~DT_PROP_FLAGS_MASK) + +typedef struct dtprop { + char *name; + void *data; + uint32_t flags; + uint32_t size; + bool name_malloced; + bool data_malloced; +} dtprop_t; + +struct dtnode { + dtprop_t *props; + dt_node_t *children; + uint32_t nprops; + uint32_t nchildren; + // caches name property + void *name; + // caches size of name property + uint32_t name_size; +}; + + + +#endif diff --git a/lib/devicetree/fuzz.c b/lib/devicetree/fuzz.c new file mode 100644 index 0000000..24e1603 --- /dev/null +++ b/lib/devicetree/fuzz.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct blockdev *create_mock_blockdev(const char *name, const char *filename, uint32_t block_size); + +int do_printenv(int argc, void *args); + +int fuzz_main(const char *filename) +{ + void *dt_in_buffer; + void *dt_out_buffer; + size_t dt_in_size; + size_t dt_out_size; + struct stat st; + FILE *f; + int result; + dt_node_t *root; + + // Set up environment + mock_syscfg_add('ABCD', "abcd", 4); + mock_syscfg_add('AAAA', "abcdabcdabcdabcd", 16); + mock_syscfg_add('AAAB', "abcdabcdabcdabc", 15); + mock_syscfg_add('AAAC', "abcdabcdabcdabcda", 17); + + env_set("a", "", 0); + env_set("b", "b", 0); + env_set("c", "cc", 0); + env_set("d", "ddd", 0); + env_set("e", "eeee", 0); + env_set("f", "fffff", 0); + env_set("g", "ggggggggggggggggggggggggggggggggggggggggggg", 0); + env_set("h", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", 0); + env_set("i", "01:02:03:40:50:60", 0); + + // Get input size + result = stat(filename, &st); + TEST_ASSERT_EQ(result, 0); + dt_in_size = st.st_size; + + // Read it + f = fopen(filename, "r"); + TEST_ASSERT_NOT_NULL(f); + + dt_in_buffer = malloc(dt_in_size); + result = fread(dt_in_buffer, 1, dt_in_size, f); + TEST_ASSERT_EQ(result, dt_in_size); + + root = dt_deserialize(dt_in_buffer, dt_in_size); + + if (root != NULL) { + // serialize the unmodified devicetree + dt_out_size = dt_get_size(); + dt_out_buffer = malloc(dt_out_size); + dt_serialize(root, dt_out_buffer, dt_out_size); + free(dt_out_buffer); + + // make some mods + dt_set_prop(root, "a", NULL, 0); + dt_set_prop(root, "b", "abcdefg", 7); + dt_set_prop(root, "c", "abcdefgh", 8); + dt_set_prop(root, "d", "abcdefghi", 9); + dt_remove_prop(root, "e"); + dt_rename_prop(root, "f", "z"); + + dt_node_t *node; + dt_find_node(root, "chosen", &node); + dt_find_node(NULL, "chosen", &node); + dt_find_node(root, "product/camera", &node); + dt_find_node(NULL, "product/camera", &node); + dt_find_node(root, "product/sdfasd", &node); + + // serialize with the modifications + dt_out_size = dt_get_size(); + dt_out_buffer = malloc(dt_out_size); + dt_serialize(root, dt_out_buffer, dt_out_size); + free(dt_out_buffer); + + // causes deserialized devicetree to be freed + dt_init(); + } + + free(dt_in_buffer); + + return result; +} + +// Mock for lib/env +bool +env_blacklist(const char *name, bool write) +{ + return false; +} + +bool +env_blacklist_nvram(const char *name) +{ + return false; +} diff --git a/lib/devicetree/fuzzing-dict.txt b/lib/devicetree/fuzzing-dict.txt new file mode 100644 index 0000000..2e3b039 --- /dev/null +++ b/lib/devicetree/fuzzing-dict.txt @@ -0,0 +1,22 @@ +# +# AFL fuzzing dictionary for device tree +# +# See docs/fuzzing.txt +# +# Pass to afl-fuzz with -x option + +zeroes0="zeroes/0" +zeroes1="zeroes/1" +zeroes2="zeroes/2" +zeroes3="zeroes/3" +zeroes4="zeroes/4" +zeroes5="zeroes/5" +zeroes7="zeroes/7" +zeroes500="zeroes/500" +syscfgAAAA="syscfg/AAAA" +syscfgAAAB="syscfg/AAAB" +syscfgAAAC="syscfg/AAAC" +syscfgABCD="syscfg/ABCD" +macaddr="macaddr/i" +macaddrA="macaddr/a" +macaddrB="macaddr/b" diff --git a/lib/devicetree/library.mk b/lib/devicetree/library.mk new file mode 100644 index 0000000..d1c15db --- /dev/null +++ b/lib/devicetree/library.mk @@ -0,0 +1,29 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBDEVICETREE_DIR := $(GET_LOCAL_DIR) +LIBDEVICETREE_BUILD := $(call TOLIBDIR,$(LIBDEVICETREE_DIR)/LIBDEVICETREE.a) +COMMONLIBS += LIBDEVICETREE + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBDEVICETREE_OBJS := $(LIBDEVICETREE_DIR)/devicetree.o \ + $(LIBDEVICETREE_DIR)/devicetree_load.o \ + $(LIBDEVICETREE_DIR)/devicetree_debug.o + +LIBDEVICETREE_OBJS := $(call TOLIBOBJDIR,$(LIBDEVICETREE_OBJS)) + +ALL_DEPS += $(LIBDEVICETREE_OBJS:%o=%d) + +$(LIBDEVICETREE_BUILD): $(LIBDEVICETREE_OBJS) + +endif diff --git a/lib/devicetree/rules.mk b/lib/devicetree/rules.mk new file mode 100644 index 0000000..29dd054 --- /dev/null +++ b/lib/devicetree/rules.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2007, 2010, 2015 Apple, Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple, Inc. +# + +OPTIONS += WITH_DEVICETREE=1 +LIBRARY_MODULES += lib/devicetree + diff --git a/lib/devicetree/tests-fuzz.mk b/lib/devicetree/tests-fuzz.mk new file mode 100644 index 0000000..938bb6a --- /dev/null +++ b/lib/devicetree/tests-fuzz.mk @@ -0,0 +1,23 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := devicetree-fuzz + +TEST_OBJS := \ + $(LOCAL_DIR)/devicetree.o \ + lib/env/env.o + +TEST_SUPPORT_OBJS += \ + tests/fuzz-main.o \ + tests/mocks/syscfg.o \ + $(LOCAL_DIR)/fuzz.o + diff --git a/lib/devicetree/tests.c b/lib/devicetree/tests.c new file mode 100644 index 0000000..b145534 --- /dev/null +++ b/lib/devicetree/tests.c @@ -0,0 +1,876 @@ +/* + * Copyright (C) 2014-2015 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +typedef struct dt_test_data { + void *input; + const void *expected; + size_t input_size; + size_t expected_size; + uint32_t misc; +} dt_test_data; + +#define DT_TESTCASE(in, out) { \ + .input = (void *)in, \ + .input_size = sizeof(in) - 1, \ + .expected = out, \ + .expected_size = sizeof(out) - 1, \ + .misc = 0 \ +} + +#define DT_TESTCASE_MISC(in, out, misc) { \ + .input = in, \ + .input_size = sizeof(in) - 1, \ + .expected = out, \ + .expected_size = sizeof(out) - 1, \ + .misc = misc \ +} + +#define DT_TESTCASE_FAIL(in) { \ + .input = in, \ + .input_size = sizeof(in) - 1, \ + .expected = NULL, \ + .expected_size = 0, \ + .misc = 0 \ +} + +#define DT_TESTCASE_FAIL_MISC(in, misc) { \ + .input = in, \ + .input_size = sizeof(in) - 1, \ + .expected = NULL, \ + .expected_size = 0, \ + .misc = misc \ +} + +// handy for dumping two buffers side-by-side when tests fail +static void hexdump2(uint8_t *buf1, uint8_t *buf2, size_t size) __unused; +static void hexdump2(uint8_t *buf1, uint8_t *buf2, size_t size) { + for (size_t i = 0; i < size; i += 8) { + printf("%04zx: ", i); + for (size_t j = 0; j < 8; j++) { + if (i + j < size) + printf(" %02x", buf1[i + j]); + else + printf(" "); + } + + printf(" "); + + for (size_t j = 0; j < 8; j++) { + if (i + j < size) + printf(" %02x", buf2[i + j]); + else + printf(" "); + } + + printf(" "); + + for (size_t j = 0; j < 8; j++) { + if (i + j < size) { + uint8_t c = buf1[i + j]; + if (!isprint(c)) + c = '.'; + printf("%c", c); + } else { + printf(" "); + } + } + + printf(" "); + + for (size_t j = 0; j < 8; j++) { + if (i + j < size) { + uint8_t c = buf2[i + j]; + if (!isprint(c)) + c = '.'; + printf("%c", c); + } else { + printf(" "); + } + } + + printf("\n"); + } +} + +dt_node_t *test_common_deserialize(dt_test_data *data) +{ + dt_init(); + + return dt_deserialize((void *)data->input, data->input_size); +} + +void test_common_serialize(dt_test_data *data) +{ + void *serialize_buf; + + TEST_ASSERT_EQ(dt_get_size(), data->expected_size); + + serialize_buf = calloc(data->expected_size, 1); + dt_serialize(0, serialize_buf, data->expected_size); + TEST_ASSERT_MEM_EQ(serialize_buf, data->expected, data->expected_size); + free(serialize_buf); +} + +uint8_t test_dt1[] = + // root node + "\x01\x00\x00\x00" // 1 property + "\x03\x00\x00\x00" // 3 children + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 1st child + "\x03\x00\x00\x00" // 3 properties + "\x00\x00\x00\x00" // 0 children + + // 1st property of 1st child + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x07\x00\x00\x00" // property length 7 + "child1\0\0" + + // 2nd property of 1st child + "property1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x09\x00\x00\x00" // property length 9 + "abcdefghi\0\0\0" + + // 3rd property of 1st child + "property2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x08\x00\x00\x00" // property length 8 + "01234567" + + // 2nd child + "\x03\x00\x00\x00" // 3 properties + "\x01\x00\x00\x00" // 1 child + + // 1st property of 2nd child + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x07\x00\x00\x00" // property length 7 + "child2\0\0" + + // 2nd property of 2nd child + "property1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x00\x00\x00\x00" // property length 0 + "" + + // 3rd property of 2nd child + "property2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x01\x00\x00\x00" // property length 1 + "X\x00\x00\x00" + + // 1st grandchild + "\x02\x00\x00\x00" // 2 properties + "\x00\x00\x00\x00" // 0 children + + // 1st property of 1st grandchild + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0b\x00\x00\x00" // property length 11 + "grandchild\x00\x00" // + + // 2nd property of 1st grandchild + "theprop\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "YYYY" + + // 3rd child + "\x01\x00\x00\x00" // 1 property + "\x00\x00\x00\x00" // 0 children + + // 1st property of 3rd child + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x07\x00\x00\x00" // property length 7 + "child3\0\0"; + +void test_find_property(dt_node_t *node, char *propName, void *expected, uint32_t expected_len) +{ + char *propNameInOut = propName; + void *propData; + uint32_t propSize; + + if (expected != NULL) { + TEST_ASSERT_EQ(FindProperty(node, &propNameInOut, &propData, &propSize), true); + // result should point into the device tree's backing store + TEST_ASSERT_PTR_NEQ(propNameInOut, propName); + TEST_ASSERT_MEM_EQ(propData, expected, expected_len); + TEST_ASSERT_EQ(propSize, expected_len); + } else { + TEST_ASSERT_EQ(FindProperty(node, &propNameInOut, &propData, &propSize), false); + } +} + +void test_devicetree_legacy(uintptr_t param) +{ + dt_node_t *node; + dt_node_t *root; + dt_node_t *child1, *child2, *child3, *grandchild; + + dt_init(); + + // - 1 for null terminator of the string + dt_deserialize(&test_dt1[0], sizeof(test_dt1) - 1); + + // we should be able to find the root of the device tree + TEST_ASSERT_EQ(FindNode(0, "", &root), true); + + // An empty path returns the same node + TEST_ASSERT_EQ(FindNode(root, "", &node), true); + TEST_ASSERT_PTR_EQ(root, node); + + // none of these should be found + TEST_ASSERT_EQ(FindNode(0, "root", &node), false); + TEST_ASSERT_EQ(FindNode(0, "/", &node), false); + TEST_ASSERT_EQ(FindNode(0, "child0", &node), false); + TEST_ASSERT_EQ(FindNode(0, "child1/grandchild", &node), false); + TEST_ASSERT_EQ(FindNode(0, "child2/grandchild2", &node), false); + TEST_ASSERT_EQ(FindNode(0, "child2/grandchild/child", &node), false); + + TEST_ASSERT_EQ(FindNode(0, "child1", &child1), true); + TEST_ASSERT_NOT_NULL(child1); + test_find_property(child1, "name", "child1", strlen("child1") + 1); + test_find_property(child1, "property1", "abcdefghi", 9); + test_find_property(child1, "property2", "01234567", 8); + test_find_property(child1, "someprop", NULL, 0); + + TEST_ASSERT_EQ(FindNode(0, "child2", &child2), true); + TEST_ASSERT_NOT_NULL(child2); + test_find_property(child2, "name", "child2", strlen("child2") + 1); + test_find_property(child2, "property1", "", 0); + test_find_property(child2, "property2", "X", 1); + test_find_property(child2, "someprop", NULL, 0); + + TEST_ASSERT_EQ(FindNode(0, "child3", &child3), true); + TEST_ASSERT_NOT_NULL(child3); + test_find_property(child3, "name", "child3", strlen("child3") + 1); + test_find_property(child3, "property1", NULL, 0); + test_find_property(child3, "property2", NULL, 0); + + TEST_ASSERT_EQ(FindNode(0, "child2/grandchild", &grandchild), true); + TEST_ASSERT_NOT_NULL(grandchild); + test_find_property(grandchild, "name", "grandchild", strlen("grandchild") + 1); + test_find_property(grandchild, "theprop", "YYYY", 4); +} + +void test_dt_get_prop(dt_node_t *node, char *propName, void *expected, uint32_t expected_len) +{ + char *propNameInOut = propName; + void *propData; + uint32_t propSize; + + if (expected != NULL) { + TEST_ASSERT_EQ(dt_get_prop(node, &propNameInOut, &propData, &propSize), true); + // result should point into the device tree's backing store + TEST_ASSERT_PTR_NEQ(propNameInOut, propName); + TEST_ASSERT_MEM_EQ(propData, expected, expected_len); + TEST_ASSERT_EQ(propSize, expected_len); + } else { + TEST_ASSERT_EQ(dt_get_prop(node, &propNameInOut, &propData, &propSize), false); + } +} + +void test_dt_deserialize(uintptr_t context) +{ + dt_node_t *node; + dt_node_t *root; + dt_node_t *child1, *child2, *child3, *grandchild; + + dt_init(); + + // - 1 for null terminator of the string + root = dt_deserialize(&test_dt1[0], sizeof(test_dt1) - 1); + TEST_ASSERT_NOT_NULL(root); + + // size should match the size of the source buffer + TEST_ASSERT_EQ(dt_get_size(), sizeof(test_dt1) - 1); + + // we should be able to find the root of the device tree + TEST_ASSERT_PTR_EQ(dt_get_root(), root); + + // An empty path returns the same node + TEST_ASSERT_EQ(dt_find_node(root, "", &node), true); + TEST_ASSERT_PTR_EQ(root, node); + + // none of these should be found + TEST_ASSERT_EQ(dt_find_node(0, "root", &node), false); + TEST_ASSERT_EQ(dt_find_node(0, "/", &node), false); + TEST_ASSERT_EQ(dt_find_node(0, "child0", &node), false); + TEST_ASSERT_EQ(dt_find_node(0, "child1/grandchild", &node), false); + TEST_ASSERT_EQ(dt_find_node(0, "child2/grandchild2", &node), false); + TEST_ASSERT_EQ(dt_find_node(0, "child2/grandchild/child", &node), false); + + TEST_ASSERT_EQ(dt_find_node(0, "child1", &child1), true); + TEST_ASSERT_NOT_NULL(child1); + test_dt_get_prop(child1, "name", "child1", strlen("child1") + 1); + test_dt_get_prop(child1, "property1", "abcdefghi", 9); + test_dt_get_prop(child1, "property2", "01234567", 8); + test_dt_get_prop(child1, "someprop", NULL, 0); + + TEST_ASSERT_EQ(dt_find_node(0, "child2", &child2), true); + TEST_ASSERT_NOT_NULL(child2); + test_dt_get_prop(child2, "name", "child2", strlen("child2") + 1); + test_dt_get_prop(child2, "property1", "", 0); + test_dt_get_prop(child2, "property2", "X", 1); + test_dt_get_prop(child2, "someprop", NULL, 0); + + TEST_ASSERT_EQ(dt_find_node(0, "child3", &child3), true); + TEST_ASSERT_NOT_NULL(child3); + test_dt_get_prop(child3, "name", "child3", strlen("child3") + 1); + test_dt_get_prop(child3, "property1", NULL, 0); + test_dt_get_prop(child3, "property2", NULL, 0); + + TEST_ASSERT_EQ(dt_find_node(0, "child2/grandchild", &grandchild), true); + TEST_ASSERT_NOT_NULL(grandchild); + test_dt_get_prop(grandchild, "name", "grandchild", strlen("grandchild") + 1); + test_dt_get_prop(grandchild, "theprop", "YYYY", 4); +} + +// Deserialize and then reserialize device tree, +// verify output is identical to input +void test_dt_serialize(uintptr_t context) +{ + dt_test_data data = DT_TESTCASE(test_dt1, test_dt1); + + test_common_deserialize(&data); + test_common_serialize(&data); +} + +// Deserialize and then reserialize device tree using a buffer +// too small for the result, verify that this results in a panic +void test_dt_serialize_too_small(uintptr_t context) +{ + size_t out_buffer_size; + void *serialize_buf; + + dt_test_data data = DT_TESTCASE(test_dt1, test_dt1); + + test_common_deserialize(&data); + dt_init(); + + + if ((int)context >= 0) { + out_buffer_size = context; + } else { + out_buffer_size = data.expected_size - (size_t)(-1 * (int)context); + } + serialize_buf = calloc(out_buffer_size, 1); + + TEST_EXPECT_PANIC(); + + dt_serialize(0, serialize_buf, out_buffer_size); + free(serialize_buf); + + TEST_EXPECT_PANICKED(); +} + +uint8_t test_dt2[] = + // root node + "\x02\x00\x00\x00" // 2 properties + "\x01\x00\x00\x00" // 1 child + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 2nd property of root + "prop\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "QWER" + + // 1st child + "\x03\x00\x00\x00" // 3 properties + "\x00\x00\x00\x00" // 0 children + + // 1st property of 1st child + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x07\x00\x00\x00" // property length 7 + "child1\0\0" + + // 2nd property of 1st child + "prop\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "ASDF" + + // 3rd property of 1st child + "prop2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x00\x00\x00\x00"; // property length 0 + +uint8_t test_dt2_out[] = + // root node + "\x01\x00\x00\x00" // 1 property + "\x01\x00\x00\x00" // 1 child + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 1st child + "\x09\x00\x00\x00" // 9 properties + "\x00\x00\x00\x00" // 0 children + + // 1st property of 1st child + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0e\x00\x00\x00" // property length 14 + "renamed-child\0\0\0" + + // 2nd property of 1st child + "renamed-prop\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "ASDF" + + // 3rd property of 1st child + "prop2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x00\x00\x00\x00" // property length 0 + + // 4th property of 1st child + "newprop32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "\xcd\xab\x34\x12" + + // 5th property of 1st child + "newprop64\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x08\x00\x00\x00" // property length 8 + "\xef\xcd\xab\x90\x78\x56\x34\x12" + + // 6th property of 1st child + "newpropaddr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x08\x00\x00\x00" // property length 8 + "\x88\x77\x66\x55\x44\x33\x22\x11" + + // 7th property of 1st child + "newpropstr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x08\x00\x00\x00" // property length 8 + "strprop\0" + + // 8th property of 1st child + "newpropempty\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x00\x00\x00\x00" // property length 0 + + // 9th property of 1st child + "newpropdata\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0b\x00\x00\x00" // property length 11 + "somedata\0xy\0"; + +void test_dt_update(uintptr_t context) +{ + char *prop_name; + dt_node_t *root; + dt_node_t *node; + + dt_test_data data = DT_TESTCASE(test_dt2, test_dt2_out); + + root = test_common_deserialize(&data); + TEST_ASSERT_NOT_NULL(root); + + // removing a property returns true if it existed + TEST_ASSERT(dt_remove_prop(root, "prop")); + // and false if not + TEST_ASSERT(!dt_remove_prop(root, "prop")); + TEST_ASSERT(!dt_remove_prop(root, "prop2")); + + TEST_ASSERT(dt_find_node(root, "child1", &node)); + + dt_set_prop_32(node, "newprop32", 0x1234abcd); + dt_set_prop_64(node, "newprop64", 0x1234567890abcdefULL); + dt_set_prop_addr(node, "newpropaddr", 0x1122334455667788ULL); + dt_set_prop_str(node, "newpropstr", "strprop"); + dt_set_prop(node, "newpropempty", "", 0); + dt_set_prop(node, "newpropdata", "somedata\0xy", 11); + + // After changing the node's name, it should be findable under + // the new name, and not under the old one + dt_set_prop_str(node, "name", "renamed-child"); + TEST_ASSERT(!dt_find_node(root, "child1", &node)); + TEST_ASSERT(dt_find_node(root, "renamed-child", &node)); + + // After changing the property's name, it should be findable under + // the new name, and not under the old one + prop_name = "prop"; + TEST_ASSERT(dt_get_prop(node, &prop_name, NULL, NULL)); + TEST_ASSERT(dt_rename_prop(node, "prop", "renamed-prop")); + prop_name = "prop"; + TEST_ASSERT(!dt_get_prop(node, &prop_name, NULL, NULL)); + prop_name = "renamed-prop"; + TEST_ASSERT(dt_get_prop(node, &prop_name, NULL, NULL)); + + test_common_serialize(&data); +} + +uint8_t test_dt_update_shorter_in[] = + // root node + "\x04\x00\x00\x00" // 4 properties + "\x00\x00\x00\x00" // 0 children + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 2nd property of root + "prop1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x08\x00\x00\x00" // property length 8 + "12345678" + + // 3rd property of root + "prop2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x07\x00\x00\x00" // property length 7 + "1234567\0" + + // 4th property of root + "prop3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x09\x00\x00\x00" // property length 9 + "123456789\0\0\0" + + // 5th property of root + "prop4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x08\x00\x00\x00" // property length 8 + "12345678"; + +uint8_t test_dt_update_shorter_out[] = + // root node + "\x05\x00\x00\x00" // 5 properties + "\x00\x00\x00\x00" // 0 children + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 2nd property of root + "prop1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "abcd" + + // 3rd property of root + "prop2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "ABCD" + + // 4th property of root + "prop3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "QWER" + + // 5th property of root + "prop4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "ASDFG\0\0\0"; + +void test_dt_update_shorter(uintptr_t context) +{ + dt_node_t *root; + + dt_test_data data = DT_TESTCASE(test_dt_update_shorter_in, test_dt_update_shorter_out); + + root = test_common_deserialize(&data); + TEST_ASSERT_NOT_NULL(root); + + dt_set_prop(root, "prop1", "abcd", 4); + dt_set_prop(root, "prop2", "ABCD", 4); + dt_set_prop(root, "prop3", "QWER", 4); + dt_set_prop(root, "prop4", "ASDFG", 5); + + test_common_serialize(&data); +} + +uint8_t test_dt_placeholders_data[] = + // root node + "\x09\x00\x00\x00" // num properties + "\x00\x00\x00\x00" // num children + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 2nd property of root (valid keys should get filled in) + "prop1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0c\x00\x00\x80" // placeholder property length 12 + "syscfg/ABCD\0" + + // 3rd property of root (invalid keys should get elided) + "prop2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0c\x00\x00\x80" // placeholder property length 12 + "syscfg/NNNN\0" + + // 4th property of root (valid key after invalid key should get filled in) + "prop3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x18\x00\x00\x80" // placeholder property length 24 + "syscfg/NNNN,syscfg/ABCD\0" + + // 5th property of root (1st value found should get copied) + "prop4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x18\x00\x00\x80" // placeholder property length 24 + "syscfg/FFFF,syscfg/ABCD\0" + + // 6th property of root (syscg value longer than placeholder) + "prop5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0c\x00\x00\x80" // placeholder property length 12 + "syscfg/BigE\0" + + // 7th property of root (syscg value truncated) + "prop6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0e\x00\x00\x80" // placeholder property length 14 + "syscfg/BigE/6\0\0\0" + + // 8th property of root (syscg value padded) + "prop7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0f\x00\x00\x80" // placeholder property length 15 + "syscfg/ABCD/12\0\0" + + // 9th property of root (macaddr from environment) + "prop8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x10\x00\x00\x80" // placeholder property length 16 + "macaddr/ethaddr\0"; + +uint8_t test_dt_placeholders_out[] = + // root node + "\x08\x00\x00\x00" // num properties + "\x00\x00\x00\x00" // num children + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 2nd property of root (valid keys should get filled in) + "prop1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x06\x00\x00\x00" // property length 6 + "found!\0\0" + + // 3rd property of root (valid key after invalid key should get filled in) + "prop3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x06\x00\x00\x00" // property length 6 + "found!\0\0" + + // 4th property of root (1st value found should get copied) + "prop4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length 4 + "yess" + + // 5th property of root (syscfg value longer than placeholder) + "prop5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x1a\x00\x00\x00" // property length 26 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\0\0" + + // 6th property of root (syscfg value truncated) + "prop6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x06\x00\x00\x00" // property length 6 + "ABCDEF\0\0" + + // 7th property of root (syscfg value padded) + "prop7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0c\x00\x00\x00" // property length 12 + "found!\0\0\0\0\0\0" + + // 8th property of root (mac address) + "prop8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x06\x00\x00\x00" // property length 6 + "\x01\x02\x03\x40\x50\x60\0\0"; + +void test_dt_placeholders(uintptr_t context) +{ + dt_node_t *root; + + mock_syscfg_reset(); + mock_syscfg_add('ABCD', "found!", strlen("found!")); + mock_syscfg_add('FFFF', "yess", strlen("yess")); + mock_syscfg_add('BigE', "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26); + env_set("ethaddr", "01:02:03:40:50:60", 0); + + dt_test_data data = DT_TESTCASE(test_dt_placeholders_data, test_dt_placeholders_out); + + root = test_common_deserialize(&data); + TEST_ASSERT_NOT_NULL(root); + + test_common_serialize(&data); +} + +uint8_t test_dt_placeholders_zeroes_data[] = + // root node + "\x04\x00\x00\x00" // num properties + "\x00\x00\x00\x00" // num children + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 2nd property of root + "prop1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x09\x00\x00\x80" // property length + "zeroes/2\0\0\0\0" + + // 3nd property of root + "prop2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x09\x00\x00\x80" // property length + "zeroes/4\0\0\0\0" + + // 4th property of root + "prop3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x0c\x00\x00\x80" // property length + "zeroes/0x20\0"; + + +uint8_t test_dt_placeholders_zeroes_out[] = + // root node + "\x04\x00\x00\x00" // num properties + "\x00\x00\x00\x00" // num children + + // 1st property of root + "name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x05\x00\x00\x00" // property length 5 + "root\0\0\0\0" + + // 2nd property of root + "prop1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x02\x00\x00\x00" // property length + "\0\0\0\0" + + // 3nd property of root + "prop2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x04\x00\x00\x00" // property length + "\0\0\0\0" + + // 4th property of root + "prop3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\x20\x00\x00\x00" // property length + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + + +void test_dt_placeholders_zeroes(uintptr_t context) +{ + dt_node_t *root; + + dt_test_data data = DT_TESTCASE(test_dt_placeholders_zeroes_data, test_dt_placeholders_zeroes_out); + + root = test_common_deserialize(&data); + TEST_ASSERT_NOT_NULL(root); + + test_common_serialize(&data); +} + +void test_common_short(dt_test_data *data) +{ + dt_node_t *root; + + // Start by making sure the data is well-formed + root = test_common_deserialize(data); + TEST_ASSERT_NOT_NULL(root); + test_common_serialize(data); + + // Now chop off a byte at a time, verifying we get a failure each time + for (size_t i = 0; i < data->input_size; i++) { + dt_init(); + + root = dt_deserialize((void *)data->input, i); + TEST_ASSERT_NULL(root); + } +} + +void test_dt_short1(uintptr_t context) +{ + uint8_t input_data[] = + "\x00\x00\x00\x00\00\x00\x00\x00" // no properties, no children + ; + + dt_test_data data = DT_TESTCASE(input_data, input_data); + + test_common_short(&data); +} + +void test_dt_short2(uintptr_t context) +{ + uint8_t input_data[] = + "\x01\x00\x00\x00\x00\x00\x00\x00" // one property, no children + "abcdefghijklmnopqrstuvqxzy01234\0" // 31-char name + "\x03\x00\x00\x00" // property len 3 + "abc\0" // property value + ; + + dt_test_data data = DT_TESTCASE(input_data, input_data); + + test_common_short(&data); +} + +void test_dt_short3(uintptr_t context) +{ + uint8_t input_data[] = + "\x01\x00\x00\x00\x01\x00\x00\x00" // one property, one child + "abcdefghijklmnopqrstuvqxzy01234\0" // 31-char name + "\x03\x00\x00\x00" // property len 3 + "abc\0" // property value + "\x00\x00\x00\x00\x00\x00\x00\x00" // no properties, no children + ; + + dt_test_data data = DT_TESTCASE(input_data, input_data); + + test_common_short(&data); +} + +void test_dt_bad_name(uintptr_t context) +{ + uint8_t input_data[] = + "\x01\x00\x00\x00\x00\x00\x00\x00" // one property, no children + "abcdefghijklmnopqrstuvqxzy012345" // 32-char name + "\x03\x00\x00\x00" // property len 3 + "abc\0" // property value + ; + dt_node_t *root; + + dt_test_data data = DT_TESTCASE_FAIL(input_data); + + dt_init(); + root = dt_deserialize(data.input, data.input_size); + TEST_ASSERT_NULL(root); +} + +static struct test_suite devicetree_test_suite = { + .name = "devicetree", + .description = "tests the devicetree parser", + .test_cases = { + { "devicetree_legacy", test_devicetree_legacy, 0 }, + { "dt_deserialize", test_dt_deserialize, 0 }, + { "dt_serialize", test_dt_serialize, 0 }, + { "dt_serialize_too_small0", test_dt_serialize, 0 }, + { "dt_serialize_too_small1", test_dt_serialize, 1 }, + { "dt_serialize_too_small-1", test_dt_serialize, (uintptr_t)-1LL }, + { "dt_update", test_dt_update, 0 }, + { "dt_update_shorter", test_dt_update_shorter, 0 }, + { "dt_placeholders", test_dt_placeholders, 0 }, + { "dt_placeholders_zeroes", test_dt_placeholders_zeroes, 0 }, + { "dt_short1", test_dt_short1, 0 }, + { "dt_short2", test_dt_short2, 0 }, + { "dt_short3", test_dt_short3, 0 }, + { "dt_bad_name", test_dt_bad_name, 0 }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(devicetree_test_suite); + +bool env_blacklist(const char *name, bool write) +{ + return false; +} + +bool env_blacklist_nvram(const char *name) +{ + return false; +} diff --git a/lib/devicetree/tests.mk b/lib/devicetree/tests.mk new file mode 100644 index 0000000..ce176c0 --- /dev/null +++ b/lib/devicetree/tests.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := devicetree + +TEST_OBJS := \ + $(LOCAL_DIR)/devicetree.o \ + lib/env/env.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + tests/mocks/syscfg.o \ + $(LOCAL_DIR)/tests.o diff --git a/lib/effaceable/README b/lib/effaceable/README new file mode 100644 index 0000000..eff94c2 --- /dev/null +++ b/lib/effaceable/README @@ -0,0 +1,9 @@ +Table of Contents: + +README - this file, containing an overview of the contents of the AppleEffaceableStorage project +AppleEffaceableStorage.xcodeproj - xcode project definition bundle for building iokit driver and ios utility command +common - portable core of the effaceable storage implementation, common to all build contexts +docs - various notes and (coming soon) design documents discussing effaceable storage +iboot - code specific to hosting portable core in iBoot context +iokit - code specific to hosting portable core in IOKit context +ios - code providing 'effaceable' command line utility in iOS; used only for user client example and internal development diff --git a/lib/effaceable/common/effaceable_context.h b/lib/effaceable/common/effaceable_context.h new file mode 100644 index 0000000..8e09b18 --- /dev/null +++ b/lib/effaceable/common/effaceable_context.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_CONTEXT_H_ +#define _EFFACEABLE_CONTEXT_H_ + +// ============================================================================= + +struct _effaceable_nand_context +{ + void * buf; + + effaceable_storage_t * storage; + effaceable_system_t * system; + effaceable_nand_hal_t * nand; +}; + +// ============================================================================= + +struct _effaceable_nor_context +{ + effaceable_storage_t * storage; + effaceable_system_t * system; + effaceable_nor_hal_t * nor; +}; + +// ============================================================================= + +struct _effaceable_storage_context +{ + bool enable_full_scan; + bool enable_wipe; + bool is_formatted; + uint32_t generation; + uint32_t group; + void * cache; + void * scratch; + void * sniff; + void * crypt; + void * nonce_hash; + + locker_list_t locker_list; + + effaceable_system_t * system; + effaceable_device_t * device; +}; + +// ============================================================================= + +typedef struct _effaceable_nor_context effaceable_nor_context_t; +typedef struct _effaceable_nand_context effaceable_nand_context_t; +typedef struct _effaceable_storage_context effaceable_storage_context_t; + +// ============================================================================= + +#endif /* _EFFACEABLE_CONTEXT_H_ */ diff --git a/lib/effaceable/common/effaceable_delegation.h b/lib/effaceable/common/effaceable_delegation.h new file mode 100644 index 0000000..a8b49c7 --- /dev/null +++ b/lib/effaceable/common/effaceable_delegation.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_DELEGATION_H_ +#define _EFFACEABLE_DELEGATION_H_ + +// ============================================================================= + +#define isFnAvailable(_me, _it, _fn) (0 != context(_me)->_it->_fn) +#define delegateFn(_me, _it, _fn, ...) context(_me)->_it->_fn(context(_me)->_it, ## __VA_ARGS__) + +// ============================================================================= + +#endif /* _EFFACEABLE_DELEGATION_H_ */ diff --git a/lib/effaceable/common/effaceable_locker.h b/lib/effaceable/common/effaceable_locker.h new file mode 100644 index 0000000..29bcb61 --- /dev/null +++ b/lib/effaceable/common/effaceable_locker.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_LOCKER_H_ +#define _EFFACEABLE_LOCKER_H_ + +#include "queue.h" + +// ============================================================================= + +struct _locker; +struct _locker_list; + +// ----------------------------------------------------------------------------- + +typedef struct _locker locker_t; +typedef TAILQ_HEAD(_locker_list, _locker) locker_list_t; + +// ----------------------------------------------------------------------------- + +struct _locker +{ + TAILQ_ENTRY(_locker) link; + AppleEffaceableStorageLockerHeader header; + uint8_t data[0]; +}; + +// ============================================================================= + +#endif /* _EFFACEABLE_LOCKER_H_ */ diff --git a/lib/effaceable/common/effaceable_nand_core.c b/lib/effaceable/common/effaceable_nand_core.c new file mode 100644 index 0000000..8f1b325 --- /dev/null +++ b/lib/effaceable/common/effaceable_nand_core.c @@ -0,0 +1,465 @@ +/* + * COPYRIGHT (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include + +#include "effaceable_private_types.h" +#include "effaceable_storage_dev.h" +#include "effaceable_nand_core.h" +#include "effaceable_delegation.h" + +// ============================================================================= + +#define debug(...) dlogf(device, __VA_ARGS__ ) + +// ============================================================================= + +extern void +startEffaceableNAND(effaceable_device_t * device, effaceable_system_t * system, effaceable_nand_hal_t * nand, effaceable_storage_t * storage) +{ + initContext(device, system, nand, storage); + initContract(device); + + setBuf(device, allocMem(device, getUnitSize(device))); + + startEffaceableStorage(storage, device, system); +} + +// ----------------------------------------------------------------------------- + +static uint32_t +getGroupCount(effaceable_device_t * device) +{ + return ((uint32_t)(getBankCount(device) * getBlockCount(device))); +} + +static uint32_t +getUnitsPerGroup(effaceable_device_t * device) +{ + return ((uint32_t)(getPageCount(device) - kAppleEffaceableNANDTotalMetaPages)); +} + +static uint32_t +getUnitSize(effaceable_device_t * device) +{ + return getPageSize(device); +} + +static EffaceableReturn +eraseGroup(effaceable_device_t * device, uint32_t group) +{ + const uint32_t bank = mapGroupToBank(device, group); + const uint32_t block = mapGroupToBlock(device, group); + + EffaceableReturn ok = kEffaceableReturnError; + + if (isBlockBad(device, bank, block)) { + // XXX remap block + ok = kEffaceableReturnBadMedia; + } else if (kEffaceableReturnSuccess == (ok = eraseBlock(device, bank, block))) { + openBlock(device, bank, block); + } + + return ok; +} + +static void +openBlock(effaceable_device_t * device, uint32_t bank, uint32_t block) +{ + uint32_t page; + const uint32_t start = 0; + const uint32_t after = kAppleEffaceableNANDOpeningMetaPages; + void * buf = 0; + + buf = getBuf(device); + prepOpenCloseMeta(device, kAppleEffaceableNANDMetaOpenMagic, buf); + for (page = start; page < after; page++) { + writePage(device, bank, block, page, buf, getPageSize(device)); + } +} + +static void +closeBlock(effaceable_device_t * device, uint32_t bank, uint32_t block) +{ + uint32_t page; + const uint32_t start = (getPageCount(device) - kAppleEffaceableNANDClosingMetaPages); + const uint32_t after = getPageCount(device); + void * buf = 0; + + buf = getBuf(device); + prepOpenCloseMeta(device, kAppleEffaceableNANDMetaCloseMagic, buf); + prepCloseContent(device, buf); + for (page = start; page < after; page++) { + writePage(device, bank, block, page, buf, getPageSize(device)); + } +} + +static void +prepOpenCloseMeta(effaceable_device_t * device, uint32_t magic, void * buf) +{ + AppleEffaceableNANDMeta * meta = (AppleEffaceableNANDMeta*)buf; + + whitenMeta(device, meta); + meta->header.magic = magic; + meta->header.version_major = kAppleEffaceableNANDMetaVersionMajorCurrent; + meta->header.version_minor = kAppleEffaceableNANDMetaVersionMinorCurrent; + meta->header.flags = kAppleEffaceableNANDMetaFlagsNone; +} + +static void +prepCloseContent(effaceable_device_t * device, void * buf) +{ + AppleEffaceableNANDMeta * meta = (AppleEffaceableNANDMeta*)buf; + + if (requestPartitionTableDiff(device, meta->content, getMetaContentSize(device))) { + meta->header.flags |= kAppleEffaceableNANDMetaFlagsHasPTabDiff; + debug(INFO, "successfully requested PTabDiff"); + } else { + debug(WARN, "unable to request PTabDiff"); + } +} + +static EffaceableReturn +writeUnit(effaceable_device_t * device, const void * buf, uint32_t group, uint32_t unit) +{ + const uint32_t bank = mapGroupToBank(device, group); + const uint32_t block = mapGroupToBlock(device, group); + const uint32_t page = mapUnitToPage(device, unit); + + EffaceableReturn ok = kEffaceableReturnError; + + if (isBlockBad(device, bank, block)) { + // XXX replace block iff passing below critical good block count threshold + ok = kEffaceableReturnBadMedia; + } else { + if (kEffaceableReturnSuccess == (ok = writePage(device, bank, block, page, buf, getPageSize(device)))) { + // if that was final content page, write block closing meta pages + if ((getUnitsPerGroup(device) - 1) == unit) { + closeBlock(device, bank, block); + } + } + } + + return ok; +} + +static EffaceableReturn +readUnit(effaceable_device_t * device, void * buf, uint32_t group, uint32_t unit) +{ + const uint32_t bank = mapGroupToBank(device, group); + const uint32_t block = mapGroupToBlock(device, group); + const uint32_t page = mapUnitToPage(device, unit); + + EffaceableReturn ok; + + if (isBlockBad(device, bank, block)) { + // XXX replace block iff passing below critical good block count threshold + ok = kEffaceableReturnBadMedia; + } else { + ok = readPage(device, bank, block, page, buf, getPageSize(device)); + } + + return ok; +} + +static uint32_t +mapGroupToBank(effaceable_device_t * device, uint32_t group) +{ + const uint32_t bank = ((uint32_t)group) % getBankCount(device); + // XXX check bounds + return bank; +} + +static uint32_t +mapGroupToBlock(effaceable_device_t * device, uint32_t group) +{ + const uint32_t block = ((uint32_t)group) / getBankCount(device); + // XXX check bounds + return block; +} + +static uint32_t +mapUnitToPage(effaceable_device_t * device, uint32_t unit) +{ + const uint32_t page = ((uint32_t)unit) + kAppleEffaceableNANDOpeningMetaPages; + // XXX check bounds + return page; +} + +// ============================================================================= + +static uint32_t +getCopiesSize(effaceable_device_t * device) +{ + return getCopySize(device) * getCopiesPerUnit(device); +} + +static void +cleanBuffers(effaceable_device_t * device) +{ + setMem(device, getBuf(device), 0, getCopiesSize(device)); +} + +static void +whitenExtra(effaceable_device_t * device, void * buf) +{ + // XXX seems like this should be getting called; why isn't it? + const uint32_t copies_size = getCopiesSize(device); + const uint32_t extra_size = getUnitSize(device) - copies_size; + readRandom(device, ((uint8_t*)buf) + copies_size, extra_size); +} + +static void +whitenMeta(effaceable_device_t * device, void * buf) +{ + readRandom(device, buf, getPageSize(device)); +} + +static void +foundCurrentCloneInGroup(effaceable_device_t * device, uint32_t group) +{ + const uint32_t magic = kAppleEffaceableNANDMetaCloseMagic; + const uint32_t major = kAppleEffaceableNANDMetaVersionMajorPTabDiff; + const uint32_t minor = kAppleEffaceableNANDMetaVersionMinorPTabDiff; + const uint32_t flag = kAppleEffaceableNANDMetaFlagsHasPTabDiff; + + const uint32_t bank = mapGroupToBank(device, group); + const uint32_t block = mapGroupToBlock(device, group); + const uint32_t start = (getPageCount(device) - kAppleEffaceableNANDClosingMetaPages); + const uint32_t after = getPageCount(device); + + void * buf = getBuf(device); + + uint32_t page; + AppleEffaceableNANDMeta * meta; + + for (page = start; page < after; page++) { + debug(INFO, "scanning %lu:%lu:%lu for ptab diff", bank, block, page); + if (kEffaceableReturnSuccess == readPage(device, bank, block, page, buf, getPageSize(device))) { + + meta = (AppleEffaceableNANDMeta *)buf; + if (magic != meta->header.magic) { + debug(ERR, "bad magic for closing page"); + } else if (0 > compareMetaVersions(device, major, minor, meta->header.version_major, meta->header.version_minor)) { + debug(INFO, "meta version precedes ptab diff implementation"); + } else if (flag != (flag & meta->header.flags)) { + debug(INFO, "meta doesn't have ptab diff content"); + } else if (!providePartitionTableDiff(device, meta->content, getMetaContentSize(device))) { + debug(WARN, "ptab diff content rejected"); + } else { + debug(INFO, "successfully provided ptab diff"); + } + + /* readable closing pages should all be identical; no reason to continue */ + break; + } + } +} + +static int +compareMetaVersions(effaceable_device_t * device, uint32_t major1, uint32_t minor1, uint32_t major2, uint32_t minor2) +{ + if (major1 < major2) { + return -1; + } else if (major1 > major2) { + return 1; + } else if (minor1 < minor2) { + return -1; + } else if (minor1 > minor2) { + return 1; + } + return 0; +} + +static uint32_t +getMetaContentSize(effaceable_device_t * device) +{ + return (getPageSize(device) - kAppleEffaceableNANDMetaHeaderSize); +} + +// ----------------------------------------------------------------------------- + +static void +initContract(effaceable_device_t * device) +{ + // hook required operations + device->getGroupCount = getGroupCount; + device->getUnitsPerGroup = getUnitsPerGroup; + device->getUnitSize = getUnitSize; + device->eraseGroup = eraseGroup; + device->writeUnit = writeUnit; + device->readUnit = readUnit; + + // hook optional operations + device->cleanBuffers = cleanBuffers; + device->foundCurrentCloneInGroup = foundCurrentCloneInGroup; + device->updateDynamicProperties = (void *)0; +} + +// ============================================================================= + +static inline effaceable_nand_context_t * context(effaceable_device_t * device) +{ + return (effaceable_nand_context_t *)device->opaque; +} + +// ----------------------------------------------------------------------------- + +static inline void * getBuf(effaceable_device_t * device) +{ + return context(device)->buf; +} + +static inline void * setBuf(effaceable_device_t * device, void * buf) +{ + return context(device)->buf = buf; +} + +// ----------------------------------------------------------------------------- + +static inline uint32_t getCopiesPerUnit(effaceable_device_t * device) +{ + return delegateFn(device, storage, getCopiesPerUnit); +} + +static inline uint32_t getCopySize(effaceable_device_t * device) +{ + return delegateFn(device, storage, getCopySize); +} + +// ----------------------------------------------------------------------------- + +static inline uint32_t getPageSize(effaceable_device_t * device) +{ + return delegateFn(device, nand, getPageSize); +} + +static inline uint32_t getPageCount(effaceable_device_t * device) +{ + return delegateFn(device, nand, getPageCount); +} + +static inline uint32_t getBlockCount(effaceable_device_t * device) +{ + return delegateFn(device, nand, getBlockCount); +} + +static inline uint32_t getBankCount(effaceable_device_t * device) +{ + return delegateFn(device, nand, getBankCount); +} + +static inline bool isBlockBad(effaceable_device_t * device, uint32_t bank, uint32_t block) +{ + return delegateFn(device, nand, isBlockBad, bank, block); +} + +static inline EffaceableReturn eraseBlock(effaceable_device_t * device, uint32_t bank, uint32_t block) +{ + return delegateFn(device, nand, eraseBlock, bank, block); +} + +static inline EffaceableReturn writePage(effaceable_device_t * device, uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length) +{ + return delegateFn(device, nand, writePage, bank, block, page, buf, length); +} + +static inline EffaceableReturn readPage(effaceable_device_t * device, uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length) +{ + return delegateFn(device, nand, readPage, bank, block, page, buf, length); +} + +static inline bool requestPartitionTableDiff(effaceable_device_t * device, void * buf, uint32_t length) +{ + return delegateFn(device, nand, requestPartitionTableDiff, buf, length); +} + +static inline bool providePartitionTableDiff(effaceable_device_t * device, void * buf, uint32_t length) +{ + return delegateFn(device, nand, providePartitionTableDiff, buf, length); +} + +// ----------------------------------------------------------------------------- + +static inline void * allocMem(effaceable_device_t * device, uint32_t size) +{ + return delegateFn(device, system, allocMem, size); +} + +static inline void freeMem(effaceable_device_t * device, void * buf, uint32_t size) +{ + delegateFn(device, system, freeMem, buf, size); +} + +static inline void * setMem(effaceable_device_t * device, void * buf, uint8_t val, uint32_t size) +{ + return delegateFn(device, system, setMem, buf, val, size); +} + +static inline void * moveMem(effaceable_device_t * device, void * dst, const void * src, uint32_t size) +{ + return delegateFn(device, system, moveMem, dst, src, size); +} + +static inline int cmpMem(effaceable_device_t * device, const void * lhs, const void * rhs, uint32_t size) +{ + return delegateFn(device, system, cmpMem, lhs, rhs, size); +} + +static inline void readRandom(effaceable_device_t * device, void * buf, uint32_t size) +{ + delegateFn(device, system, readRandom, buf, size); +} + +static inline uint32_t crc32Sys(effaceable_device_t * device, uint32_t crc, const void * buf, uint32_t size, bool finish) +{ + return delegateFn(device, system, crc32, crc, buf, size, finish); +} + +static inline bool setPropertySys(effaceable_device_t * device, const char * key, uint32_t value) +{ + return delegateFn(device, system, setProperty, key, value); +} + +static inline void panicSys(effaceable_device_t * device, const char * msg) +{ + delegateFn(device, system, panicSys, msg); +} + +static int logf(effaceable_device_t * device, const char * fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = delegateFn(device, system, vlogf, fmt, ap); + va_end(ap); + + return err; +} + +// ----------------------------------------------------------------------------- + +static void +initContext(effaceable_device_t * device, effaceable_system_t * system, effaceable_nand_hal_t * nand, effaceable_storage_t * storage) +{ + device->opaque = system->allocMem(system, sizeof(effaceable_nand_context_t)); + system->setMem(system, context(device), 0, sizeof(effaceable_nand_context_t)); + + context(device)->storage = storage; + context(device)->system = system; + context(device)->nand = nand; +} + +// ============================================================================= diff --git a/lib/effaceable/common/effaceable_nand_core.h b/lib/effaceable/common/effaceable_nand_core.h new file mode 100644 index 0000000..0848e98 --- /dev/null +++ b/lib/effaceable/common/effaceable_nand_core.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_NAND_CORE_H_ +#define _EFFACEABLE_NAND_CORE_H_ + +// ============================================================================= + +// reserve pages at beginning and end of block for future metadata +#define kAppleEffaceableNANDOpeningMetaPages 16 +#define kAppleEffaceableNANDClosingMetaPages 16 +#define kAppleEffaceableNANDTotalMetaPages (kAppleEffaceableNANDOpeningMetaPages + kAppleEffaceableNANDClosingMetaPages) + +#define kAppleEffaceableNANDMetaOpenMagic 'open' +#define kAppleEffaceableNANDMetaCloseMagic 'clos' + +#define kAppleEffaceableNANDMetaVersionMajorUnknown ((uint32_t)0x00000000) +#define kAppleEffaceableNANDMetaVersionMajorInitial ((uint32_t)0x00000001) +#define kAppleEffaceableNANDMetaVersionMajorBungled ((uint32_t)0x00000002) +#define kAppleEffaceableNANDMetaVersionMajorPTabDiff ((uint32_t)0x00000002) +#define kAppleEffaceableNANDMetaVersionMajorCurrent kAppleEffaceableNANDMetaVersionMajorPTabDiff +#define kAppleEffaceableNANDMetaVersionMajorInvalid ((uint32_t)0xFFFFFFFF) + +#define kAppleEffaceableNANDMetaVersionMinorUnknown ((uint32_t)0x00000000) +#define kAppleEffaceableNANDMetaVersionMinorInitial ((uint32_t)0x00000001) +#define kAppleEffaceableNANDMetaVersionMinorBungled ((uint32_t)0x00000002) +#define kAppleEffaceableNANDMetaVersionMinorPTabDiff ((uint32_t)0x00000003) +#define kAppleEffaceableNANDMetaVersionMinorCurrent kAppleEffaceableNANDMetaVersionMinorPTabDiff +#define kAppleEffaceableNANDMetaVersionMinorInvalid ((uint32_t)0xFFFFFFFF) + +#define kAppleEffaceableNANDMetaFlagsNone ((uint32_t)0x00000000) +#define kAppleEffaceableNANDMetaFlagsHasPTabDiff ((uint32_t)0x00000001) + +// ============================================================================= + +// All structures defined here are on-media formats. + +typedef struct +{ + uint32_t magic; + uint32_t version_major; + uint32_t version_minor; + uint32_t flags; + +} __attribute__((__packed__)) AppleEffaceableNANDMetaHeader; + +#define kAppleEffaceableNANDMetaHeaderSize sizeof(AppleEffaceableNANDMetaHeader) + +typedef struct +{ + AppleEffaceableNANDMetaHeader header; + uint8_t content[0]; + +} __attribute__((__packed__)) AppleEffaceableNANDMeta; + +// ============================================================================= + +__BEGIN_DECLS + +// ----------------------------------------------------------------------------- + +static uint32_t getGroupCount(effaceable_device_t * device); +static uint32_t getUnitsPerGroup(effaceable_device_t * device); +static uint32_t getUnitSize(effaceable_device_t * device); +static EffaceableReturn eraseGroup(effaceable_device_t * device, uint32_t group); +static EffaceableReturn writeUnit(effaceable_device_t * device, const void * buf, uint32_t group, uint32_t unit); +static EffaceableReturn readUnit(effaceable_device_t * device, void * buf, uint32_t group, uint32_t unit); + +// ----------------------------------------------------------------------------- + +static void openBlock(effaceable_device_t * device, uint32_t bank, uint32_t block); +static void closeBlock(effaceable_device_t * device, uint32_t bank, uint32_t block); +static void prepOpenCloseMeta(effaceable_device_t * device, uint32_t magic, void * buf); +static void prepCloseContent(effaceable_device_t * device, void * buf); + +// ----------------------------------------------------------------------------- + +static uint32_t mapGroupToBank(effaceable_device_t * device, uint32_t group); +static uint32_t mapGroupToBlock(effaceable_device_t * device, uint32_t group); +static uint32_t mapUnitToPage(effaceable_device_t * device, uint32_t unit); + +// ----------------------------------------------------------------------------- + +static uint32_t getCopiesSize(effaceable_device_t * device); +static void cleanBuffers(effaceable_device_t * device); +static void whitenExtra(effaceable_device_t * device, void * buf); +static void whitenMeta(effaceable_device_t * device, void * buf); +static void foundCurrentCloneInGroup(effaceable_device_t * device, uint32_t group); +static int compareMetaVersions(effaceable_device_t * device, uint32_t major1, uint32_t minor1, uint32_t major2, uint32_t minor2); +static uint32_t getMetaContentSize(effaceable_device_t * device); + +// ----------------------------------------------------------------------------- + +static void initContract(effaceable_device_t * device); + +// ============================================================================= + +static inline void * getBuf(effaceable_device_t * device); +static inline void * setBuf(effaceable_device_t * device, void * buf); + +// ----------------------------------------------------------------------------- + +static inline uint32_t getCopiesPerUnit(effaceable_device_t * device); +static inline uint32_t getCopySize(effaceable_device_t * device); + +// ----------------------------------------------------------------------------- + +static inline uint32_t getPageSize(effaceable_device_t * device); +static inline uint32_t getPageCount(effaceable_device_t * device); +static inline uint32_t getBlockCount(effaceable_device_t * device); +static inline uint32_t getBankCount(effaceable_device_t * device); +static inline bool isBlockBad(effaceable_device_t * device, uint32_t bank, uint32_t block); +static inline EffaceableReturn eraseBlock(effaceable_device_t * device, uint32_t bank, uint32_t block); +static inline EffaceableReturn writePage(effaceable_device_t * device, uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length); +static inline EffaceableReturn readPage(effaceable_device_t * device, uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length); +static inline bool requestPartitionTableDiff(effaceable_device_t * device, void * buf, uint32_t length); +static inline bool providePartitionTableDiff(effaceable_device_t * device, void * buf, uint32_t length); + +// ----------------------------------------------------------------------------- + +static inline void * allocMem(effaceable_device_t * device, uint32_t size); +static inline void freeMem(effaceable_device_t * device, void * buf, uint32_t size); +static inline void * setMem(effaceable_device_t * device, void * buf, uint8_t val, uint32_t size); +static inline void * moveMem(effaceable_device_t * device, void * dst, const void * src, uint32_t size); +static inline int cmpMem(effaceable_device_t * device, const void * lhs, const void * rhs, uint32_t size); +static inline void readRandom(effaceable_device_t * device, void * buf, uint32_t size); +static inline uint32_t crc32Sys(effaceable_device_t * device, uint32_t crc, const void * buf, uint32_t size, bool finish); +static inline bool setPropertySys(effaceable_device_t * device, const char * key, uint32_t value); +static inline void panicSys(effaceable_device_t * device, const char * msg); + +static int logf(effaceable_device_t * device, const char * fmt, ...); + +// ----------------------------------------------------------------------------- + +static void initContext(effaceable_device_t * device, effaceable_system_t * system, effaceable_nand_hal_t * nand, effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +__END_DECLS + +// ============================================================================= + +#endif /* _EFFACEABLE_NAND_CORE_H_ */ diff --git a/lib/effaceable/common/effaceable_nor_core.c b/lib/effaceable/common/effaceable_nor_core.c new file mode 100644 index 0000000..4d5273c --- /dev/null +++ b/lib/effaceable/common/effaceable_nor_core.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include + +#include "effaceable_private_types.h" +#include "effaceable_storage_dev.h" +#include "effaceable_nor_core.h" +#include "effaceable_delegation.h" + +// ============================================================================= + +#define debug(...) dlogf(device, __VA_ARGS__ ) + +// ============================================================================= + +extern void +startEffaceableNOR(effaceable_device_t * device, effaceable_system_t * system, effaceable_nor_hal_t * nor, effaceable_storage_t * storage) +{ + initContext(device, system, nor, storage); + initContract(device); + + startEffaceableStorage(storage, device, system); +} + +// ============================================================================= + +static uint32_t +getGroupCount(effaceable_device_t * device) +{ + return getRegionCount(device); +} + +static uint32_t +getUnitsPerGroup(effaceable_device_t * device) +{ + return 1; +} + +static uint32_t +getUnitSize(effaceable_device_t * device) +{ + return getRegionSize(device, 0); +} + +static EffaceableReturn +eraseGroup(effaceable_device_t * device, uint32_t group) +{ + return eraseRegion(device, group, getUnitSize(device)); +} + +static EffaceableReturn +writeUnit(effaceable_device_t * device, const void * buf, uint32_t group, uint32_t unit) +{ + // XXX assert unit == 0 + return writeRegion(device, group, buf, getUnitSize(device)); +} + +static EffaceableReturn +readUnit(effaceable_device_t * device, void * buf, uint32_t group, uint32_t unit) +{ + // XXX assert unit == 0 + return readRegion(device, group, buf, getUnitSize(device)); +} + +// ============================================================================= + +static void +initContract(effaceable_device_t * device) +{ + // hook required operations + device->getGroupCount = getGroupCount; + device->getUnitsPerGroup = getUnitsPerGroup; + device->getUnitSize = getUnitSize; + device->eraseGroup = eraseGroup; + device->writeUnit = writeUnit; + device->readUnit = readUnit; + + // hook optional operations + device->cleanBuffers = (void *)0; + device->foundCurrentCloneInGroup = (void *)0; + device->updateDynamicProperties = (void *)0; +} + +// ============================================================================= + +static inline effaceable_nor_context_t * context(effaceable_device_t * device) +{ + return (effaceable_nor_context_t *)device->opaque; +} + +// ----------------------------------------------------------------------------- + +static inline uint32_t getCopiesPerUnit(effaceable_device_t * device) +{ + return delegateFn(device, storage, getCopiesPerUnit); +} + +static inline uint32_t getCopySize(effaceable_device_t * device) +{ + return delegateFn(device, storage, getCopySize); +} + +// ----------------------------------------------------------------------------- + +static inline uint32_t getRegionCount(effaceable_device_t * device) +{ + return delegateFn(device, nor, getRegionCount); +} + +static inline uint32_t getRegionSize(effaceable_device_t * device, uint32_t index) +{ + return delegateFn(device, nor, getRegionSize, index); +} + +static inline EffaceableReturn eraseRegion(effaceable_device_t * device, uint32_t index, uint32_t length) +{ + return delegateFn(device, nor, eraseRegion, index, length); +} + +static inline uint32_t writeRegion(effaceable_device_t * device, uint32_t index, const void * buf, uint32_t length) +{ + return delegateFn(device, nor, writeRegion, index, buf, length); +} + +static inline bool readRegion(effaceable_device_t * device, uint32_t index, void * buf, uint32_t length) +{ + return delegateFn(device, nor, readRegion, index, buf, length); +} + +// ----------------------------------------------------------------------------- + +static inline void * allocMem(effaceable_device_t * device, uint32_t size) +{ + return delegateFn(device, system, allocMem, size); +} + +static inline void freeMem(effaceable_device_t * device, void * buf, uint32_t size) +{ + delegateFn(device, system, freeMem, buf, size); +} + +static inline void * setMem(effaceable_device_t * device, void * buf, uint8_t val, uint32_t size) +{ + return delegateFn(device, system, setMem, buf, val, size); +} + +static inline void * moveMem(effaceable_device_t * device, void * dst, const void * src, uint32_t size) +{ + return delegateFn(device, system, moveMem, dst, src, size); +} + +static inline int cmpMem(effaceable_device_t * device, const void * lhs, const void * rhs, uint32_t size) +{ + return delegateFn(device, system, cmpMem, lhs, rhs, size); +} + +static inline void readRandom(effaceable_device_t * device, void * buf, uint32_t size) +{ + delegateFn(device, system, readRandom, buf, size); +} + +static inline uint32_t crc32Sys(effaceable_device_t * device, uint32_t crc, const void * buf, uint32_t size, bool finish) +{ + return delegateFn(device, system, crc32, crc, buf, size, finish); +} + +static inline bool setPropertySys(effaceable_device_t * device, const char * key, uint32_t value) +{ + return delegateFn(device, system, setProperty, key, value); +} + +static inline void panicSys(effaceable_device_t * device, const char * msg) +{ + delegateFn(device, system, panicSys, msg); +} + +static int logf(effaceable_device_t * device, const char * fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = delegateFn(device, system, vlogf, fmt, ap); + va_end(ap); + + return err; +} + +// ============================================================================= + +static void +initContext(effaceable_device_t * device, effaceable_system_t * system, effaceable_nor_hal_t * nor, effaceable_storage_t * storage) +{ + device->opaque = system->allocMem(system, sizeof(effaceable_nor_context_t)); + system->setMem(system, context(device), 0, sizeof(effaceable_nor_context_t)); + + context(device)->system = system; + context(device)->nor = nor; + context(device)->storage = storage; +} + +// ============================================================================= diff --git a/lib/effaceable/common/effaceable_nor_core.h b/lib/effaceable/common/effaceable_nor_core.h new file mode 100644 index 0000000..1eefea1 --- /dev/null +++ b/lib/effaceable/common/effaceable_nor_core.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_NOR_CORE_H_ +#define _EFFACEABLE_NOR_CORE_H_ + +// ============================================================================= + +__BEGIN_DECLS + +// ----------------------------------------------------------------------------- + +static uint32_t getGroupCount(effaceable_device_t * device); +static uint32_t getUnitsPerGroup(effaceable_device_t * device); +static uint32_t getUnitSize(effaceable_device_t * device); +static EffaceableReturn eraseGroup(effaceable_device_t * device, uint32_t group); +static EffaceableReturn writeUnit(effaceable_device_t * device, const void * buf, uint32_t group, uint32_t unit); +static EffaceableReturn readUnit(effaceable_device_t * device, void * buf, uint32_t group, uint32_t unit); + +// ----------------------------------------------------------------------------- + +static void initContract(effaceable_device_t * device); + +// ----------------------------------------------------------------------------- + +static inline uint32_t getCopiesPerUnit(effaceable_device_t * device); +static inline uint32_t getCopySize(effaceable_device_t * device); + +// ----------------------------------------------------------------------------- + +static inline uint32_t getRegionCount(effaceable_device_t * device); +static inline uint32_t getRegionSize(effaceable_device_t * device, uint32_t index); +static inline EffaceableReturn eraseRegion(effaceable_device_t * device, uint32_t index, uint32_t length); +static inline uint32_t writeRegion(effaceable_device_t * device, uint32_t index, const void * buf, uint32_t length); +static inline bool readRegion(effaceable_device_t * device, uint32_t index, void * buf, uint32_t length); + +// ----------------------------------------------------------------------------- + +static inline void * allocMem(effaceable_device_t * device, uint32_t size); +static inline void freeMem(effaceable_device_t * device, void * buf, uint32_t size); +static inline void * setMem(effaceable_device_t * device, void * buf, uint8_t val, uint32_t size); +static inline void * moveMem(effaceable_device_t * device, void * dst, const void * src, uint32_t size); +static inline int cmpMem(effaceable_device_t * device, const void * lhs, const void * rhs, uint32_t size); +static inline void readRandom(effaceable_device_t * device, void * buf, uint32_t size); +static inline uint32_t crc32Sys(effaceable_device_t * device, uint32_t crc, const void * buf, uint32_t size, bool finish); +static inline bool setPropertySys(effaceable_device_t * device, const char * key, uint32_t value); +static inline void panicSys(effaceable_device_t * device, const char * msg); + +static int logf(effaceable_device_t * device, const char * fmt, ...); + +// ----------------------------------------------------------------------------- + +static void initContext(effaceable_device_t * device, effaceable_system_t * system, effaceable_nor_hal_t * nor, effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +__END_DECLS + +// ============================================================================= + +#endif /* _EFFACEABLE_NOR_CORE_H_ */ diff --git a/lib/effaceable/common/effaceable_private_types.h b/lib/effaceable/common/effaceable_private_types.h new file mode 100644 index 0000000..5e65eea --- /dev/null +++ b/lib/effaceable/common/effaceable_private_types.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_PRIVATE_TYPES_H_ +#define _EFFACEABLE_PRIVATE_TYPES_H_ + +// ============================================================================= + +#include +#include "effaceable_locker.h" +#include "effaceable_context.h" + +// ============================================================================= + +// grrrr +#ifndef NULL +#define NULL ((void*)0) +#endif + +// ----------------------------------------------------------------------------- + +#define min(a,b) \ + ({ \ + __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; \ + }) + +// ============================================================================= + +#endif /* _EFFACEABLE_PRIVATE_TYPES_H_ */ diff --git a/lib/effaceable/common/effaceable_storage_core.c b/lib/effaceable/common/effaceable_storage_core.c new file mode 100644 index 0000000..b99bc51 --- /dev/null +++ b/lib/effaceable/common/effaceable_storage_core.c @@ -0,0 +1,1553 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include +#include + +#include "effaceable_private_types.h" +#include "effaceable_storage_dev.h" +#include "effaceable_storage_core.h" +#include "effaceable_delegation.h" + +// ============================================================================= + +#define kAppleEffaceableStorageEnableFullScanDefault false +#define kAppleEffaceableStorageEnableWipeDefault false + +#define kAppleEffaceableStorageGroupInvalid ((uint32_t) -1) +#define kAppleEffaceableStorageMinGroupCount 2 + +// ============================================================================= + +#define debug(...) dlogf(storage, __VA_ARGS__ ) +#define hexdump(...) dhexdump(storage, __VA_ARGS__ ) + +// ============================================================================= + +// debug-only registry keys + +#define kAppleEffaceableStoragePropertyGeneration "Generation" +#define kAppleEffaceableStoragePropertyCapacity "Capacity" +#define kAppleEffaceableStoragePropertyGroupCount "GroupCount" +#define kAppleEffaceableStoragePropertyGroupIndex "GroupIndex" +#define kAppleEffaceableStoragePropertyUnitsPerGroup "UnitsPerGroup" +#define kAppleEffaceableStoragePropertyUnitSize "UnitSize" +#define kAppleEffaceableStoragePropertyCopiesPerUnit "CopiesPerUnit" +#define kAppleEffaceableStoragePropertyCopySize "CopySize" + +// ============================================================================= + +extern void +startEffaceableStorage(effaceable_storage_t * storage, effaceable_device_t * device, effaceable_system_t * system) +{ + initContext(storage, device, system); + initContract(storage); + + setIsFormatted(storage, false); + setGeneration(storage, kAppleEffaceableStorageGenerationUnknown); + setGroup(storage, kAppleEffaceableStorageGroupInvalid); + + setFullScanEnabled(storage, kAppleEffaceableStorageEnableFullScanDefault); + setWipeEnabled(storage, kAppleEffaceableStorageEnableWipeDefault); + + // allocate storage, expecting system contract to do the right thing if no memory available + setCache(storage, allocMem(storage, getCopySize(storage))); + setScratch(storage, allocMem(storage, getCopySize(storage))); + setSniff(storage, allocMem(storage, getCopySize(storage))); + setCrypt(storage, allocMem(storage, getUnitSize(storage))); + + // start with no lockers in memory + TAILQ_INIT(getLockerList(storage)); + + // update initial (static) properties + updateInitialProperties(storage); + + // try to find current clone, if any + findCurrentClone(storage, getScratch(storage), getSniff(storage), getCache(storage)); + + debug(INIT, "started"); +} + +static void +updateInitialProperties(effaceable_storage_t * storage) +{ + // debug properties + setPropertySys(storage, kAppleEffaceableStoragePropertyCapacity, getCapacity(storage)); + setPropertySys(storage, kAppleEffaceableStoragePropertyGroupCount, getGroupCount(storage)); + setPropertySys(storage, kAppleEffaceableStoragePropertyUnitsPerGroup, getUnitsPerGroup(storage)); + setPropertySys(storage, kAppleEffaceableStoragePropertyUnitSize, getUnitSize(storage)); + setPropertySys(storage, kAppleEffaceableStoragePropertyCopiesPerUnit, getCopiesPerUnit(storage)); + setPropertySys(storage, kAppleEffaceableStoragePropertyCopySize, getCopySize(storage)); + + // common properties + setPropertySys(storage, kAppleEffaceableStoragePropertyVersionMajor, kAppleEffaceableStorageVersionMajorCurrent); + setPropertySys(storage, kAppleEffaceableStoragePropertyVersionMinor, kAppleEffaceableStorageVersionMinorCurrent); +} + +// ============================================================================= + +static uint32_t +getCapacity(effaceable_storage_t * storage) +{ + return kAppleEffaceableStorageContentSize; +} + +static bool +isFormatted(effaceable_storage_t * storage) +{ + return getIsFormatted(storage); +} + +// ============================================================================= + +static EffaceableReturn +formatStorage(effaceable_storage_t * storage) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)getCache(storage); + void * tmp_buf = getScratch(storage); + uint32_t group; + uint32_t generation = kAppleEffaceableStorageGenerationInitial; + + debug(INIT, "formatting storage"); + + if (kEffaceableReturnSuccess == (ok = wipeStorage(storage, tmp_buf))) { + setMem(storage, &(clone->content[0]), 0, getCapacity(storage)); + for (group = 0; group < getGroupCount(storage); group++) { + if (kEffaceableReturnSuccess == (ok = writeClone(storage, tmp_buf, clone, group, generation))) { + break; + } else { + if (kEffaceableReturnSuccess != (ok = effaceGroup(storage, tmp_buf, group))) { + debug(ERR, "group %d will neither store a clone nor can it be effaced", group); + break; + } + } + } + if (kEffaceableReturnSuccess == ok) { + setGroup(storage, group); + setGeneration(storage, generation); + setIsFormatted(storage, true); + updateDynamicProperties(storage); + debug(INIT, "format succeeded"); + } else { + debug(ERR, "unable to commit initial generation to any group"); + } + } + + return ok; +} + +static EffaceableReturn +getBytes(effaceable_storage_t * storage, void * client_buf, uint32_t offset, uint32_t count) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)getCache(storage); + + if (0 == client_buf) { + debug(ERR, "cannot get bytes to buffer referenced by NULL pointer\n"); + ok = kEffaceableReturnBadArgument; + } else if ((count > getCapacity(storage)) || (offset > (getCapacity(storage) - count))) { + debug(ERR, "attempting to read past end of content\n"); + ok = kEffaceableReturnBadArgument; + } else if (!getIsFormatted(storage)) { + debug(ERR, "couldn't find the droid you were looking for"); + ok = kEffaceableReturnUnformattedMedia; + } else { + moveMem(storage, client_buf, &(clone->content[offset]), count); + } + + cleanBuffers(storage); + return ok; +} + +static EffaceableReturn +setBytes(effaceable_storage_t * storage, const void * client_buf, uint32_t offset, uint32_t count) +{ + const uint32_t max_attempts = 2; + + EffaceableReturn ok = kEffaceableReturnError; + AppleEffaceableStorageClone * parent_clone; + AppleEffaceableStorageClone * mutant_clone; + void * tmp_buf; + uint32_t parent_group; + uint32_t mutant_group; + uint32_t mutant_generation; + uint32_t attempt; + + if (0 == client_buf) { + debug(ERR, "cannot set bytes from buffer referenced by 0 pointer"); + ok = kEffaceableReturnBadArgument; + } else if ((count > getCapacity(storage)) || (offset > (getCapacity(storage) - count))) { + debug(ERR, "attempting to write past end of content"); + ok = kEffaceableReturnBadArgument; + } else if (!getIsFormatted(storage)) { + debug(ERR, "couldn't find the droid you were looking for"); + ok = kEffaceableReturnUnformattedMedia; + } else { + parent_clone = (AppleEffaceableStorageClone *)getCache(storage); + mutant_clone = (AppleEffaceableStorageClone *)getScratch(storage); + tmp_buf = getSniff(storage); + parent_group = getGroup(storage); + moveMem(storage, mutant_clone, parent_clone, sizeof(AppleEffaceableStorageClone)); + moveMem(storage, &(mutant_clone->content[offset]), client_buf, count); + mutant_generation = parent_clone->header.veiled.generation + 1; + + // AppleEffaceableStorage::setBytesGated needs to attempt commit to N-1 groups before failing + for (mutant_group = nextGroup(storage, parent_group), ok = kEffaceableReturnError; + (mutant_group != parent_group) && (ok != kEffaceableReturnSuccess); + mutant_group = nextGroup(storage, mutant_group)) { + + for (attempt = 1; attempt <= max_attempts; attempt++) { + if (kEffaceableReturnSuccess == (ok = writeClone(storage, tmp_buf, mutant_clone, mutant_group, mutant_generation))) { + setGroup(storage, mutant_group); + setGeneration(storage, mutant_generation); + break; + } else if (kEffaceableReturnSuccess != effaceGroup(storage, tmp_buf, mutant_group)) { + debug(ERR, "unable to either write modified content to or efface group %d\n", mutant_group); + break; + } + } + } + + if (kEffaceableReturnSuccess == ok) { + if (kEffaceableReturnSuccess != effaceGroup(storage, tmp_buf, parent_group)) { + // AppleEffaceableStorage should indicate when best efforts to efface prior generation has failed + } + moveMem(storage, getCache(storage), mutant_clone, getCopySize(storage)); + updateDynamicProperties(storage); + debug(INFO, "generation %d successfully committed to group %d", getGeneration(storage), getGroup(storage)); + } + } + + cleanBuffers(storage); + return ok; +} + +// ============================================================================= + +static EffaceableReturn +eraseGroupLogged(effaceable_storage_t * storage, uint32_t group) +{ + EffaceableReturn ok = eraseGroup(storage, group); + if (kEffaceableReturnSuccess == ok) { + debug(SPEW, "group := %d => success", group); + } else { + debug(SPEW, "group := %d => 0x%08X", group, ok); + } + return ok; +} + +static EffaceableReturn +writeUnitLogged(effaceable_storage_t * storage, const void * io_buf, uint32_t group, uint32_t unit) +{ + EffaceableReturn ok = writeUnit(storage, io_buf, group, unit); + if (kEffaceableReturnSuccess == ok) { + debug(SPEW, "group := %d, unit := %d, buffer := %p => success", group, unit, io_buf); + } else { + debug(SPEW, "group := %d, unit := %d, buffer := %p => 0x%08X", group, unit, io_buf, ok); + } + return ok; +} + +static EffaceableReturn +readUnitLogged(effaceable_storage_t * storage, void * io_buf, uint32_t group, uint32_t unit) +{ + EffaceableReturn ok = readUnit(storage, io_buf, group, unit); + if (kEffaceableReturnSuccess == ok) { + debug(SPEW, "group := %d, unit := %d, buffer := %p => success", group, unit, io_buf); + } else { + debug(SPEW, "group := %d, unit := %d, buffer := %p => 0x%08X", group, unit, io_buf, ok); + } + return ok; +} + +// ============================================================================= + +static void +findCurrentClone(effaceable_storage_t * storage, void * tmp_buf, void * scan_buf, void * clone_buf) +{ + AppleEffaceableStorageClone * scan = (AppleEffaceableStorageClone *)scan_buf; + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)clone_buf; + + uint32_t scan_generation = kAppleEffaceableStorageGenerationUnknown; + uint32_t copy_generation; + uint32_t valid_groups; + uint32_t valid_copies; + uint32_t group; + uint32_t unit; + uint32_t copy; + + // XXX refactor following mess into more manageable chunks + + valid_groups = 0; + for (group = 0; group < getGroupCount(storage); group++) { + valid_copies = 0; + scan_generation = kAppleEffaceableStorageGenerationUnknown; + for (unit = 0; unit < getUnitsPerGroup(storage); unit++) { + if (kEffaceableReturnSuccess != readUnitLogged(storage, getCrypt(storage), group, unit)) { + debug(SPEW, "unable to read unit %d group %d", unit, group); + } else { + for (copy = 0; copy < getCopiesPerUnit(storage); copy++) { + if (kEffaceableReturnSuccess != revealCopy(storage, getCrypt(storage), scan, copy)) { + debug(SPEW, "unable to decipher copy %d unit %d group %d", copy, unit, group); + } else if (!isCopyValid(storage, scan)) { + debug(SPEW, "invalid copy %d unit %d group %d", copy, unit, group); + } else { + copy_generation = scan->header.veiled.generation; + debug(INFO, "valid generation %d @ copy %d unit %d group %d", + copy_generation, copy, unit, group); + if (0 == valid_copies) { + scan_generation = copy_generation; + } else if (copy_generation != scan_generation) { + // XXX inconsistent copies within current scan group + } + if (getGeneration(storage) < scan_generation) { + debug(SPEW, "oldest generation found is now %d; prior was %d", + scan_generation, getGeneration(storage)); + if (0 != valid_groups) { + // this group has older copies + // than prior valid oldest, so + // efface prior oldest + if (kEffaceableReturnSuccess != effaceGroup(storage, tmp_buf, getGroup(storage))) { + // XXX what now? + } + } + setGeneration(storage, scan_generation); + setGroup(storage, group); + moveMem(storage, clone, scan, getCopySize(storage)); + } + valid_copies++; + if (!getFullScanEnabled(storage)) { + // if full scan disabled, stop checking + // copies after first valid one found + break; + } + } + } + } + if (!getFullScanEnabled(storage) && (0 != valid_copies)) { + // if full scan enabled, stop checking copies + // after first valid one found + break; + } + } + if (0 != valid_copies) { + if ((0 != valid_groups) && (getGroup(storage) != group)) { + // already found older valid group; efface current + if (kEffaceableReturnSuccess != effaceGroup(storage, tmp_buf, group)) { + // XXX what now? + } + } + valid_groups++; + } + } + + if (0 != valid_groups) { + foundCurrentCloneInGroup(storage, getGroup(storage)); + } else { + debug(ERR, "unable to find content"); + } + + cleanBuffers(storage); +} + +static bool +isGroupEffaced(effaceable_storage_t * storage, void * tmp_buf, uint32_t group) +{ + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)tmp_buf; + uint32_t valid_copies = 0; + uint32_t unit; + uint32_t copy; + + for (unit = 0; unit < getUnitsPerGroup(storage); unit++) { + if (kEffaceableReturnSuccess == readUnitLogged(storage, getCrypt(storage), group, unit)) { + for (copy = 0; copy < getCopiesPerUnit(storage); copy++) { + if ((kEffaceableReturnSuccess == revealCopy(storage, getCrypt(storage), clone, copy)) && isCopyValid(storage, clone)) { + valid_copies++; + } + } + } + } + + return (valid_copies == 0); +} + +static EffaceableReturn +obscureCopy(effaceable_storage_t * storage, void * clear_buf, void * crypt_buf, uint32_t copy) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + + AppleEffaceableStorageClone * clear_clone = (AppleEffaceableStorageClone *)clear_buf; + AppleEffaceableStorageClone * crypt_clone = &(((AppleEffaceableStorageClone *)crypt_buf)[copy]); + + const uint32_t naked_size = sizeof(AppleEffaceableStorageNaked); + const uint32_t salt_size = kAppleEffaceableStorageSaltSize; + const uint32_t veiled_size = sizeof(AppleEffaceableStorageClone) - naked_size - salt_size; + const uint32_t pad_count = naked_size / sizeof(uint32_t); + + uint32_t index; + + // XXX assert that naked_size == salt_size + + // generate a per-copy random IV + readRandom(storage, &(crypt_clone->header.salt[0]), salt_size); + + // use salt as pad to obscure naked header content + for (index = 0; index < pad_count; index++) { + const uint32_t pad = ((uint32_t *)&(crypt_clone->header.salt[0]))[index]; + ((uint32_t *)&(crypt_clone->header.naked))[index] = (pad ^ ((uint32_t *)&(clear_clone->header.naked))[index]); + } + + debug(SPEW, "encrypting content"); + moveMem(storage, &(crypt_clone->header.veiled), &(clear_clone->header.veiled), veiled_size); + + return ok; +} + +static EffaceableReturn +revealCopy(effaceable_storage_t * storage, void * crypt_buf, void * clear_buf, uint32_t copy) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + + AppleEffaceableStorageClone * clear_clone = (AppleEffaceableStorageClone *)clear_buf; + AppleEffaceableStorageClone * crypt_clone = &(((AppleEffaceableStorageClone *)crypt_buf)[copy]); + + const uint32_t naked_size = sizeof(AppleEffaceableStorageNaked); + const uint32_t salt_size = kAppleEffaceableStorageSaltSize; + const uint32_t veiled_size = sizeof(AppleEffaceableStorageClone) - naked_size - salt_size; + const uint32_t pad_count = naked_size / sizeof(uint32_t); + + uint32_t index; + + // XXX assert that naked_size == salt_size + + // zero clone + setMem(storage, clear_clone, 0, sizeof(AppleEffaceableStorageClone)); + + // use salt as pad to reveal naked header content + for (index = 0; index < pad_count; index++) { + const uint32_t pad = ((uint32_t *)&(crypt_clone->header.salt[0]))[index]; + ((uint32_t *)&(clear_clone->header.naked))[index] = (pad ^ ((uint32_t *)&(crypt_clone->header.naked))[index]); + } + + debug(SPEW, "decrypting content"); + moveMem(storage, &(clear_clone->header.veiled), &(crypt_clone->header.veiled), veiled_size); + + return ok; +} + +static EffaceableReturn +commitClone(effaceable_storage_t * storage, void * clone_buf, uint32_t group) +{ + EffaceableReturn ok = kEffaceableReturnError; + uint32_t written_units = 0; + uint32_t unit; + uint32_t copy; + + for (copy = 0; copy < getCopiesPerUnit(storage); copy++) { + if (kEffaceableReturnSuccess != obscureCopy(storage, clone_buf, getCrypt(storage), copy)) { + debug(WARN, "unable to obscure clone"); + } else { + ok = kEffaceableReturnSuccess; + } + } + + if (kEffaceableReturnSuccess == ok) { + for (unit = 0; unit < getUnitsPerGroup(storage); unit++) { + if (kEffaceableReturnSuccess != (ok = writeUnitLogged(storage, getCrypt(storage), group, unit))) { + debug(WARN, "unable to write unit %d group %d during commit", + unit, group); + } else { + written_units++; + } + } + + if (0 == written_units) { + debug(ERR, "unable to write any units in group %d during commit", group); + ok = kEffaceableReturnIOError; + } else { + debug(SPEW, "committed %d of %d units in group %d", + written_units, getUnitsPerGroup(storage), group); + ok = kEffaceableReturnSuccess; + } + } + + return ok; +} + +static EffaceableReturn +writeClone(effaceable_storage_t * storage, void * tmp_buf, void * clone_buf, uint32_t group, uint32_t generation) +{ + EffaceableReturn ok = kEffaceableReturnError; + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)clone_buf; + + setMem(storage, &(clone->header), 0, sizeof(AppleEffaceableStorageHeader)); + clone->header.naked.magic = kAppleEffaceableStorageMagic; + clone->header.naked.version_major = kAppleEffaceableStorageVersionMajorCurrent; + clone->header.naked.version_minor = kAppleEffaceableStorageVersionMinorCurrent; + clone->header.naked.flags = kAppleEffaceableStorageFlagsNone; + clone->header.veiled.generation = (uint32_t) generation; + clone->header.veiled.checksum = checksumCopy(storage, clone); + + if (kEffaceableReturnSuccess == (ok = commitClone(storage, clone, group))) { + ok = confirmClone(storage, tmp_buf, clone, group); + } + + return ok; +} + +static uint32_t +checksumCopy(effaceable_storage_t * storage, void * clone_buf) +{ + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)clone_buf; + uint32_t crc = crc32Sys(storage, 0, 0, 0, false); + crc = crc32Sys(storage, crc, &(clone->header.naked), sizeof(AppleEffaceableStorageNaked), false); + crc = crc32Sys(storage, crc, &(clone->header.veiled), sizeof(AppleEffaceableStorageVeiled) - sizeof(uint32_t), false); + crc = crc32Sys(storage, crc, &(clone->content[0]), kAppleEffaceableStorageContentSize, true); + return crc; +} + +static EffaceableReturn +wipeStorage(effaceable_storage_t * storage, void * tmp_buf) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + uint32_t efface_count = 0; + uint32_t group; + + if (getIsFormatted(storage) && !getWipeEnabled(storage)) { + debug(ERR, "wipe of formatted storage not permitted without 'effaceable-enable-wipe=1' boot-arg"); + ok = kEffaceableReturnNotPermitted; + } else { + setGroup(storage, kAppleEffaceableStorageGroupInvalid); + setIsFormatted(storage, false); + + for (group = 0; group < getGroupCount(storage); group++) { + if (kEffaceableReturnSuccess == effaceGroup(storage, tmp_buf, group)) { + efface_count++; + } + } + + if (kAppleEffaceableStorageMinGroupCount <= efface_count) { + if (getGroupCount(storage) > efface_count) { + debug(WARN, "only able to efface %d out of %d groups", efface_count, getGroupCount(storage)); + } + ok = kEffaceableReturnSuccess; + } else { + debug(ERR, "unable to efface at least %d out of %d groups", kAppleEffaceableStorageMinGroupCount, getGroupCount(storage)); + ok = kEffaceableReturnBadMedia; + } + } + debug(INIT, "%s", (kEffaceableReturnSuccess == ok) ? "succeeded" : "failed"); + + return ok; +} + +static bool +isCopyValid(effaceable_storage_t * storage, const void * clone_buf) +{ + bool ok = false; + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)clone_buf; + uint32_t checksum; + + if (kAppleEffaceableStorageMagic != clone->header.naked.magic) { + // this is the expected result during scan for all copies other than current generation + debug(SPEW, "bad magic - expect 0x%08X, have 0x%08X", + kAppleEffaceableStorageMagic, clone->header.naked.magic); + } else if (kAppleEffaceableStorageGenerationUnknown == clone->header.veiled.generation) { + debug(ERR, "have 'unknown' generation: 0x%08X", + kAppleEffaceableStorageGenerationUnknown); + } else if (kAppleEffaceableStorageGenerationInvalid == clone->header.veiled.generation) { + debug(ERR, "have 'invalid' generation: 0x%08X", + kAppleEffaceableStorageGenerationInvalid); + } else if (kAppleEffaceableStorageVersionMajorCurrent != clone->header.naked.version_major) { + debug(ERR, "major version mismatch - expect 0x%08X, have 0x%08X", + kAppleEffaceableStorageVersionMajorCurrent, clone->header.naked.version_major); + } else if (kAppleEffaceableStorageVersionMinorUnknown == clone->header.naked.version_minor) { + debug(ERR, "have 'unknown' minor version: 0x%08X", + kAppleEffaceableStorageVersionMinorUnknown); + } else if (kAppleEffaceableStorageVersionMinorInvalid == clone->header.naked.version_minor) { + debug(ERR, "have 'invalid' minor version: 0x%08X", + kAppleEffaceableStorageVersionMinorInvalid); + } else if ((checksum = checksumCopy(storage, clone)) != clone->header.veiled.checksum) { + debug(ERR, "checksum failed - calculated 0x%08X, have 0x%08X", + checksum, clone->header.veiled.checksum); + } else { + debug(SPEW, "copy appears valid; checksum is 0x%08X", checksum); + ok = true; + } + return ok; +} + +static EffaceableReturn +confirmClone(effaceable_storage_t * storage, void * tmp_buf, void * clone_buf, uint32_t group) +{ + EffaceableReturn ok = kEffaceableReturnError; + + AppleEffaceableStorageClone * clone = (AppleEffaceableStorageClone *)clone_buf; + AppleEffaceableStorageClone * twin = (AppleEffaceableStorageClone *)tmp_buf; + uint32_t readable_units = 0; + uint32_t valid_copies = 0; + uint32_t unit; + uint32_t copy; + + for (unit = 0; unit < getUnitsPerGroup(storage); unit++) { + if (kEffaceableReturnSuccess != readUnitLogged(storage, getCrypt(storage), group, unit)) { + debug(WARN, "unable to read back unit %d group %d", unit, group); + } else { + readable_units++; + ok = kEffaceableReturnNotFound; + for (copy = 0; copy < getCopiesPerUnit(storage); copy++) { + if (kEffaceableReturnSuccess != revealCopy(storage, getCrypt(storage), twin, copy)) { + debug(WARN, "couldn't decipher copy %d unit %d group %d", copy, unit, group); + } if (!isCopyValid(storage, twin)) { + debug(WARN, "copy %d unit %d group %d not valid", copy, unit, group); + } else if (0 != cmpMem(storage, &(clone->content), &(twin->content), getCapacity(storage))) { + debug(WARN, "read back differs from original: copy %d unit %d group %d", copy, unit, group); + } else { + valid_copies++; + ok = kEffaceableReturnSuccess; + } + } + if (kEffaceableReturnSuccess != ok) { + debug(WARN, "failed confirmation of all copies in unit %d group %d", unit, group); + debug(SPEW, "clone @ %p:", clone); + debug(SPEW, "crypt @ %p:", getCrypt(storage)); + debug(SPEW, "twin @ %p:", twin); + } + } + } + + if (0 != valid_copies) { + debug(SPEW, "commit confirmed for %d of %d copies found in %d of %d readable units of group %d", + valid_copies, getUnitsPerGroup(storage) * getCopiesPerUnit(storage), readable_units, getUnitsPerGroup(storage), group); + ok = kEffaceableReturnSuccess; + } else if (0 != readable_units) { + debug(ERR, "no valid copies found given %d of %d readable units during confirmation of group %d", + readable_units, getUnitsPerGroup(storage), group); + ok = kEffaceableReturnNotFound; + } else { + debug(ERR, "all %d units unreadable during confirmation of group %d", + getUnitsPerGroup(storage), group); + ok = kEffaceableReturnIOError; + } + + + return ok; +} + +static uint32_t +nextGroup(effaceable_storage_t * storage, uint32_t group) +{ + uint32_t subsequent = group + 1; + return ((getGroupCount(storage) <= subsequent) ? 0 : subsequent); +} + +static EffaceableReturn +effaceGroup(effaceable_storage_t * storage, void * tmp_buf, uint32_t group) +{ + EffaceableReturn ok = kEffaceableReturnError; + + const uint32_t max_attempts = 3; + + uint32_t attempt; + uint32_t unit; + + setMem(storage, getCrypt(storage), 0, getUnitSize(storage)); + for (attempt = 0; attempt < max_attempts; attempt++) { + // erase the group + if (kEffaceableReturnSuccess != eraseGroupLogged(storage, group)) { + debug(WARN, "erase failed on group %d\n", group); + } + // whether or not the erase succeeded, attempt to read each + // unit from the group + if (isGroupEffaced(storage, tmp_buf, group)) { + // if we were unable to read any unit, the group has been + // properly effaced + debug(SPEW, "effaced group %d on attempt %d after erase", group, attempt + 1); + break; + } else { + // if any valid unit was able to be read, attempt to + // overwrite every unit in group with zeros before + // next erase attempt + debug(WARN, "found valid copies after erase on group %d\n", group); + for (unit = 0; unit < getUnitsPerGroup(storage); unit++) { + writeUnitLogged(storage, getCrypt(storage), group, unit); + } + } + } + + if (max_attempts == attempt) { + debug(ERR, "unable to efface group %d after %d attempts", group, attempt); + ok = kEffaceableReturnBadMedia; + } else { + ok = kEffaceableReturnSuccess; + } + + return ok; +} + +static void +cleanBuffers(effaceable_storage_t * storage) +{ + deviceCleanBuffers(storage); + + setMem(storage, getScratch(storage), 0, getCopySize(storage)); + setMem(storage, getSniff(storage), 0, getCopySize(storage)); + setMem(storage, getCrypt(storage), 0, getUnitSize(storage)); +} + +static uint32_t +getCopySize(effaceable_storage_t * storage) +{ + return sizeof(AppleEffaceableStorageClone); +} + +static uint32_t +getCopiesPerUnit(effaceable_storage_t * storage) +{ + return (getUnitSize(storage) / getCopySize(storage)); +} + +static void +foundCurrentCloneInGroup(effaceable_storage_t * storage, uint32_t group) +{ + setIsFormatted(storage, true); + deviceFoundCurrentCloneInGroup(storage, group); + updateDynamicProperties(storage); + debug(INIT, "found current generation, %d, in group %d", getGeneration(storage), group); +} + +static void +updateDynamicProperties(effaceable_storage_t * storage) +{ + deviceUpdateDynamicProperties(storage); + + // debug + // + // XXX conditionalize these + setPropertySys(storage, kAppleEffaceableStoragePropertyGeneration, getGeneration(storage)); + setPropertySys(storage, kAppleEffaceableStoragePropertyGroupIndex, getGroup(storage)); + + // common + setPropertySys(storage, kAppleEffaceableStoragePropertyIsFormatted, getIsFormatted(storage)); +} + +// ============================================================================= + +static EffaceableReturn +getLocker(effaceable_storage_t * storage, uint32_t type_id, void *data, uint32_t *data_size, bool untrusted) +{ + EffaceableReturn result; + bool notprivate = false; + + result = getLockerInternal(storage, type_id, data, data_size, untrusted, notprivate); + return(result); +} + +static EffaceableReturn +getLockerExternal(effaceable_storage_t * storage, uint32_t type_id, void *data, uint32_t *data_size, bool untrusted) +{ + EffaceableReturn result; + bool notprivate = true; + + result = getLockerInternal(storage, type_id, data, data_size, untrusted, notprivate); + return(result); +} + +static EffaceableReturn +getLockerInternal(effaceable_storage_t * storage, uint32_t type_id, void *data, uint32_t *data_size, bool untrusted, bool notprivate) +{ + EffaceableReturn result; + locker_t *lp; + + if (0 != (lp = findLockerForRequest(storage, type_id))) { + + // check permissions on this locker + if (untrusted && (lp->header.type_id & kAppleEffaceableStorageLockerProtected)) { + debug(ERR, "untrusted client tried to read protected key"); + result = kEffaceableReturnNotPrivileged; + goto out; + } + + // check permissions to see if an external client is trying to read driver private locker + if (notprivate && (lp->header.type_id & kAppleEffaceableStorageLockerPrivate)) { + debug(ERR, "external client tried to read private locker"); + result = kEffaceableReturnNotPrivileged; + goto out; + } + + // if the caller supplied a buffer, copy what data will fit + if ((0 != data) && (0 != data_size) && (0 != *data_size)) + moveMem(storage, data, &lp->data[0], min(*data_size, lp->header.data_size)); + + // return actual data size if requested + if (0 != data_size) + *data_size = lp->header.data_size; + + result = kEffaceableReturnSuccess; + } else { + debug(INFO, "getLocker for type not present"); + result = kEffaceableReturnNotFound; + } +out: + discardLockers(storage); + return(result); +} + +static EffaceableReturn +setLocker(effaceable_storage_t * storage, uint32_t type_id, const void *data, uint32_t data_size, bool untrusted) +{ + EffaceableReturn result; + bool notprivate = false; + + result = setLockerInternal(storage, type_id, data, data_size, untrusted, notprivate); + return result; +} + +static EffaceableReturn +setLockerExternal(effaceable_storage_t * storage, uint32_t type_id, const void *data, uint32_t data_size, bool untrusted) +{ + EffaceableReturn result; + bool notprivate = true; + + result = setLockerInternal(storage, type_id, data, data_size, untrusted, notprivate); + return result; +} + +static EffaceableReturn +setLockerInternal(effaceable_storage_t * storage, uint32_t type_id, const void *data, uint32_t data_size, bool untrusted, bool notprivate) +{ + EffaceableReturn result; + locker_t *lp; + uint16_t dataSize; + + // verify that kernel-only options aren't being set by non-kernel clients + if (untrusted && (type_id & kAppleEffaceableStorageLockerProtected)) { + debug(ERR, "untrusted client trying to create protected locker"); + return kEffaceableReturnNotPrivileged; + } + + // check permissions to see if an external client isn't trying to set a driver private locker + if (notprivate && (type_id & kAppleEffaceableStorageLockerPrivate)) { + debug(ERR, "external client tried to write private locker"); + return kEffaceableReturnNotPrivileged; + } + + // cannot set sentinel type + if (type_id == kAppleEffaceableStorageLockerSentinel) { + debug(ERR, "client trying to create locker sentinel"); + return kEffaceableReturnBadArgument; + } + + // look for an existing locker that we might be overwriting and toss it + if (0 != (lp = findLockerForRequest(storage, type_id))) { + + // untrusted client cannot overwrite protected entry + if (untrusted && (lp->header.type_id & kAppleEffaceableStorageLockerProtected)) { + debug(ERR, "untrusted client trying to overwrite protected locker"); + result = kEffaceableReturnNotPrivileged; + goto out; + } + + // external client cannot overwrite driver private locker + if (notprivate && (lp->header.type_id & kAppleEffaceableStorageLockerPrivate)) { + debug(ERR, "external client tried to overwrite private locker"); + result = kEffaceableReturnNotPrivileged; + goto out; + } + + // unlink, overwrite with zeros and then free + TAILQ_REMOVE(getLockerList(storage), lp, link); + dataSize = lp->header.data_size; + setMem(storage, lp, 0, sizeof(*lp) + dataSize); + freeMem(storage, lp, sizeof(*lp) + dataSize); + } + + // allocate a new locker + lp = (locker_t *)allocMem(storage, sizeof(*lp) + data_size); + + // copy data from the request + lp->header.magic = kAppleEffaceableStorageLockerMagic; + lp->header.type_id = type_id; + lp->header.data_size = data_size; + if (data_size > 0) + moveMem(storage, &lp->data[0], data, data_size); + + // insert it into the list + TAILQ_INSERT_HEAD(getLockerList(storage), lp, link); + + // push the updated list back to storage + result = putLockersInStorage(storage); +out: + // discard lockers (may still have them on the error path) + discardLockers(storage); + return result; +} + +static EffaceableReturn +spaceForLocker(effaceable_storage_t * storage, uint32_t type_id, uint32_t *data_space) +{ + EffaceableReturn result; + uint32_t consumed = 0; + locker_t *lp; + + if (0 == data_space) + return(kEffaceableReturnBadArgument); + + // get lockers if we don't have them already cached + if (TAILQ_EMPTY(getLockerList(storage)) && + (kEffaceableReturnSuccess != (result = getLockersFromStorage(storage)))) { + debug(ERR, "failed to get lockers"); + return result; + } + + // scan lockers accounting for space + TAILQ_FOREACH(lp, getLockerList(storage), link) { + // always account for header + consumed += sizeof(*lp); + + // if not the candidate type, data space is spoken for + if ((type_id & ~kAppleEffaceableStorageLockerProtected) != + (lp->header.type_id & ~kAppleEffaceableStorageLockerProtected)) + consumed += lp->header.data_size; + } + + // sanity-check the result + if (consumed > kAppleEffaceableStorageLockerSize) { + debug(ERR, "internal locker overflow"); + result = kEffaceableReturnInternalError; + } else { + *data_space = kAppleEffaceableStorageLockerSize - consumed; + result = kEffaceableReturnSuccess; + } + + // dump lockers + discardLockers(storage); + + return result; +} + +static EffaceableReturn +effaceLocker(effaceable_storage_t * storage, uint32_t type_id, bool untrusted) +{ + EffaceableReturn result; + bool notprivate = false; + + result = effaceLockerInternal(storage, type_id, untrusted, notprivate); + return result; +} + +static EffaceableReturn +effaceLockerExternal(effaceable_storage_t * storage, uint32_t type_id, bool untrusted) +{ + EffaceableReturn result; + bool notprivate = true; + + result = effaceLockerInternal(storage, type_id, untrusted, notprivate); + return result; +} + +static EffaceableReturn +effaceLockerInternal(effaceable_storage_t * storage, uint32_t type_id, bool untrusted, bool notprivate) +{ + EffaceableReturn result; + locker_t *lp; + uint16_t dataSize; + + // cannot efface sentinel type + if (type_id == kAppleEffaceableStorageLockerSentinel) { + debug(ERR, "attempt to efface locker sentinel"); + return kEffaceableReturnBadArgument; + } + + // wildcard efface? + if (kAppleEffaceableStorageLockerWildcard == type_id) { + + // Even discards private lockers + if (untrusted) { + debug(ERR, "attempt to wildcard efface from untrusted client"); + return kEffaceableReturnNotPermitted; + } + + // discard lockers and push to storage - this will effectively write zeroes + // to the entire locker space + discardLockers(storage); + return putLockersInStorage(storage); + + } + // find a locker matching + if (0 != (lp = findLockerForRequest(storage, type_id))) { + + // check permissions on this locker + if (untrusted && (lp->header.type_id & kAppleEffaceableStorageLockerProtected)) { + debug(ERR, "unprivileged client attempting to efface protected locker"); + result = kEffaceableReturnNotPrivileged; + goto out; + } + + // check permissions to see if external client trying to efface driver private locker + if (notprivate && (lp->header.type_id & kAppleEffaceableStorageLockerPrivate)) { + debug(ERR, "external client tried to efface driver private locker"); + result = kEffaceableReturnNotPrivileged; + goto out; + } + + // yank from the list, zero and free + TAILQ_REMOVE(getLockerList(storage), lp, link); + dataSize = lp->header.data_size; + setMem(storage, lp, 0, sizeof(*lp) + dataSize); + freeMem(storage, lp, sizeof(*lp) + dataSize); + + // push the updated list back to storage + result = putLockersInStorage(storage); + } else { + debug(INFO, "attempt to efface nonexistent locker"); + result = kEffaceableReturnNotFound; + } + +out: + discardLockers(storage); + return result; +} + +// ============================================================================= + +static void +appendSentinel(effaceable_storage_t * storage) +{ + locker_t *lp; + + // construct the tail sentinel + lp = (locker_t *)allocMem(storage, sizeof(*lp)); + setMem(storage, lp, 0, sizeof(*lp)); + lp->header.magic = kAppleEffaceableStorageLockerMagic; + lp->header.type_id = kAppleEffaceableStorageLockerSentinel; + TAILQ_INSERT_TAIL(getLockerList(storage), lp, link); +} + +static EffaceableReturn +getLockersFromStorage(effaceable_storage_t * storage) +{ + EffaceableReturn result; + uint8_t *lockerData; + uint32_t cursor; + AppleEffaceableStorageLockerHeader header; + locker_t *lp; + + lockerData = (uint8_t *)allocMem(storage, kAppleEffaceableStorageLockerSize); + + if (kEffaceableReturnSuccess == (result = getBytes(storage, lockerData, + kAppleEffaceableStorageLockerBase, + kAppleEffaceableStorageLockerSize))) { + + TAILQ_INIT(getLockerList(storage)); + cursor = 0; + for (;;) { + // get the next header + moveMem(storage, &header, lockerData + cursor, sizeof(header)); + + // check for header magic + if (header.magic != kAppleEffaceableStorageLockerMagic) + break; + + // check for tail sentinel but don't copy - we will + // re-create when we finish here + if (header.type_id == kAppleEffaceableStorageLockerSentinel) + break; + + // Check for overflow in two phases; we don't + // trust the header data size, so check that + // it's sufficiently small that it's not going + // to overflow anything first. Then check that the + // allocation doesn't overflow our buffer. + if (header.data_size > kAppleEffaceableStorageLockerSize) + break; + if ((cursor + sizeof(header) + header.data_size) > kAppleEffaceableStorageLockerSize) + break; + + // allocate a node + lp = (locker_t *)allocMem(storage, sizeof(*lp) + header.data_size); + moveMem(storage, &lp->header, &header, sizeof(header)); + if (header.data_size > 0) + moveMem(storage, &lp->data, lockerData + cursor + sizeof(header), header.data_size); + + TAILQ_INSERT_TAIL(getLockerList(storage), lp, link); + + // move the cursor + cursor += sizeof(header) + header.data_size; + + // if there's no room for another header, we're done + if ((cursor + sizeof(header)) >= kAppleEffaceableStorageLockerSize) + break; + } + + // add the tail sentinel + appendSentinel(storage); + } + // zero key data out of the buffer before freeing + setMem(storage, lockerData, 0, kAppleEffaceableStorageLockerSize); + freeMem(storage, lockerData, kAppleEffaceableStorageLockerSize); + + return(result); +} + +static EffaceableReturn +putLockersInStorage(effaceable_storage_t * storage) +{ + EffaceableReturn result; + uint8_t *lockerData; + uint32_t cursor; + locker_t *lp; + + lockerData = (uint8_t *)allocMem(storage, kAppleEffaceableStorageLockerSize); + + cursor = 0; + result = kEffaceableReturnSuccess; + TAILQ_FOREACH(lp, getLockerList(storage), link) { + + // verify the node will fit + if ((cursor + sizeof(lp->header) + lp->header.data_size) >= kAppleEffaceableStorageLockerSize) { + debug(ERR, "locker overflow"); + result = kEffaceableReturnNoSpace; + break; + } + + // copy the header + moveMem(storage, lockerData + cursor, &lp->header, sizeof(lp->header)); + cursor += sizeof(lp->header); + + // copy the data + if (lp->header.data_size > 0) { + moveMem(storage, lockerData + cursor, &lp->data[0], lp->header.data_size); + cursor += lp->header.data_size; + } + } + + // only write back if everything fit + if (kEffaceableReturnSuccess == result) + result = setBytes(storage, lockerData, + kAppleEffaceableStorageLockerBase, + kAppleEffaceableStorageLockerSize); + + // zero key data out of the buffer before freeing + setMem(storage, lockerData, 0, kAppleEffaceableStorageLockerSize); + freeMem(storage, lockerData, kAppleEffaceableStorageLockerSize); + + return(result); +} + +static EffaceableReturn +discardLockers(effaceable_storage_t * storage) +{ + locker_t *lp, *lp_temp; + uint16_t dataSize; + + TAILQ_FOREACH_SAFE(lp, getLockerList(storage), link, lp_temp) { + TAILQ_REMOVE(getLockerList(storage), lp, link); + // zero the key data out of the locker before we free it + dataSize = lp->header.data_size; + setMem(storage, lp, 0, sizeof(*lp) + dataSize); + freeMem(storage, lp, sizeof(*lp) + dataSize); + } + TAILQ_INIT(getLockerList(storage)); + return kEffaceableReturnSuccess; +} + +static locker_t * +findLockerForRequest(effaceable_storage_t * storage, uint32_t type_id) +{ + locker_t *lp; + uint32_t request_type, locker_type; + + // do we have lockers in memory? + if (TAILQ_EMPTY(getLockerList(storage))) { + // if we can't get lockers, there's nothing much we can do + if (kEffaceableReturnSuccess != getLockersFromStorage(storage)) + return 0; + } + + // iterate lockers + request_type = type_id & ~kAppleEffaceableStorageLockerProtected; + TAILQ_FOREACH(lp, getLockerList(storage), link) { + + // mask out attribute bits during lookup + locker_type = lp->header.type_id & ~kAppleEffaceableStorageLockerProtected; + if (request_type == locker_type) + return lp; + } + // not found + return 0; +} + +// ----------------------------------------------------------------------------- + +#define SHA1_HASH_SIZE 20 +#define kEffaceableNonceKey ((uint32_t)0x4E6F6E63 /* 'Nonc' */) +#define kEffaceableNonceId (kEffaceableNonceKey | ((uint32_t)kAppleEffaceableStorageLockerProtected)) + +static void logNonce(effaceable_storage_t * storage, uint64_t nonce, void * hash) +{ + // XXX reduce verbosity level prior to submitting + debug(SPEW, "nonce: 0x%016llX", nonce); + + if (0 != hash) { + uint8_t * b = (uint8_t*)hash; + debug(SPEW, "hash: " + "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", + b[ 0], b[ 1], b[ 2], b[ 3], b[ 4], b[ 5], b[ 6], b[ 7], b[ 8], b[ 9], + b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]); + } +} + +static EffaceableReturn generateNonce(effaceable_storage_t * storage, void * hash) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + uint64_t nonce; + void * nonce_hash = getNonceHash(storage); + + // Generate and store nonce only if one hasn't already been + // generated since system start. + if (0 != nonce_hash) { + debug(INFO, "nonce previously generated"); + } else { + + // Generate a 64-bit random number from entropy pool to serve as nonce + // and attempt to store in protected nonce locker. + readRandom(storage, &nonce, sizeof(nonce)); + ok = setLocker(storage, kEffaceableNonceId, &nonce, sizeof(nonce), false); + + // If nonce was successfully stored, calculate and save its SHA1 hash. + if (kEffaceableReturnSuccess != ok) { + debug(ERR, "unable to set nonce"); + } else { + nonce_hash = allocMem(storage, SHA1_HASH_SIZE); + setMem(storage, nonce_hash, 0, SHA1_HASH_SIZE); + + calcSHA1(storage, &nonce, sizeof(nonce), nonce_hash); + setNonceHash(storage, nonce_hash); + + logNonce(storage, nonce, nonce_hash); + debug(INFO, "nonce generated"); + } + } + + // If successful up to this point, copy our copy of nonce hash + // to the buffer supplied by client. + if (kEffaceableReturnSuccess == ok) { + moveMem(storage, hash, nonce_hash, SHA1_HASH_SIZE); + } + + return ok; +} + +static EffaceableReturn consumeNonce(effaceable_storage_t * storage, uint64_t * nonce) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + uint64_t val; + uint32_t size = sizeof(val); + + ok = getLocker(storage, kEffaceableNonceId, &val, &size, false); + + if (kEffaceableReturnSuccess == ok) { + + // Nonce always gets effaced upon consumption. + ok = effaceLocker(storage, kEffaceableNonceId, false); + + if (kEffaceableReturnSuccess != ok) { + debug(ERR, "failed to efface nonce"); + } else { + + logNonce(storage, val, 0); + if (0 != nonce) { + *nonce = val; + debug(INFO, "nonce consumed"); + } else { + debug(INFO, "nonce discarded"); + } + } + } + + return ok; +} + +// ============================================================================= + +static void +initContract(effaceable_storage_t * storage) +{ + // hook operations intended for external use + storage->getLocker = getLockerExternal; + storage->setLocker = setLockerExternal; + storage->spaceForLocker = spaceForLocker; + storage->effaceLocker = effaceLockerExternal; + storage->generateNonce = generateNonce; + storage->consumeNonce = consumeNonce; + storage->formatStorage = formatStorage; + storage->getBytes = getBytes; + storage->wipeStorage = wipeStorage; + storage->getCapacity = getCapacity; + storage->isFormatted = isFormatted; + + // hook operations intended for use by device contracts + storage->getCopiesPerUnit = getCopiesPerUnit; + storage->getCopySize = getCopySize; +} + +// ============================================================================= + +static inline effaceable_storage_context_t * context(effaceable_storage_t * storage) +{ + return (effaceable_storage_context_t *)storage->opaque; +} + +// ----------------------------------------------------------------------------- + +static inline void * getCache(effaceable_storage_t * storage) +{ + return context(storage)->cache; +} + +static inline void * setCache(effaceable_storage_t * storage, void * buf) +{ + return context(storage)->cache = buf; +} + +static inline void * getScratch(effaceable_storage_t * storage) +{ + return context(storage)->scratch; +} + +static inline void * setScratch(effaceable_storage_t * storage, void * buf) +{ + return context(storage)->scratch = buf; +} + +static inline void * getSniff(effaceable_storage_t * storage) +{ + return context(storage)->sniff; +} + +static inline void * setSniff(effaceable_storage_t * storage, void * buf) +{ + return context(storage)->sniff = buf; +} + +static inline void * getCrypt(effaceable_storage_t * storage) +{ + return context(storage)->crypt; +} + +static inline void * setCrypt(effaceable_storage_t * storage, void * buf) +{ + return context(storage)->crypt = buf; +} + +static inline void * getNonceHash(effaceable_storage_t * storage) +{ + return context(storage)->nonce_hash; +} + +static inline void * setNonceHash(effaceable_storage_t * storage, void * buf) +{ + return context(storage)->nonce_hash = buf; +} + +static inline uint32_t getGeneration(effaceable_storage_t * storage) +{ + return context(storage)->generation; +} + +static inline uint32_t setGeneration(effaceable_storage_t * storage, uint32_t generation) +{ + return context(storage)->generation = generation; +} + +static inline uint32_t getGroup(effaceable_storage_t * storage) +{ + return context(storage)->group; +} + +static inline uint32_t setGroup(effaceable_storage_t * storage, uint32_t group) +{ + return context(storage)->group = group; +} + +static inline bool getIsFormatted(effaceable_storage_t * storage) +{ + return context(storage)->is_formatted; +} + +static inline bool setIsFormatted(effaceable_storage_t * storage, bool is_formatted) +{ + return context(storage)->is_formatted = is_formatted; +} + +static inline bool getFullScanEnabled(effaceable_storage_t * storage) +{ + return context(storage)->enable_full_scan; +} + +static inline bool setFullScanEnabled(effaceable_storage_t * storage, bool enable) +{ + return context(storage)->enable_full_scan = enable; +} + +static inline bool getWipeEnabled(effaceable_storage_t * storage) +{ + return context(storage)->enable_wipe; +} + +static inline bool setWipeEnabled(effaceable_storage_t * storage, bool enable) +{ + return context(storage)->enable_wipe = enable; +} + +static inline locker_list_t * getLockerList(effaceable_storage_t * storage) +{ + return &context(storage)->locker_list; +} + +// ----------------------------------------------------------------------------- + +static inline uint32_t getGroupCount(effaceable_storage_t * storage) +{ + return delegateFn(storage, device, getGroupCount); +} + +static inline uint32_t getUnitsPerGroup(effaceable_storage_t * storage) +{ + return delegateFn(storage, device, getUnitsPerGroup); +} + +static inline uint32_t getUnitSize(effaceable_storage_t * storage) +{ + return delegateFn(storage, device, getUnitSize); +} + +static inline bool eraseGroup(effaceable_storage_t * storage, uint32_t group) +{ + return delegateFn(storage, device, eraseGroup, group); +} + +static inline bool writeUnit(effaceable_storage_t * storage, const void * buf, uint32_t group, uint32_t unit) +{ + return delegateFn(storage, device, writeUnit, buf, group, unit); +} + +static inline bool readUnit(effaceable_storage_t * storage, void * buf, uint32_t group, uint32_t unit) +{ + return delegateFn(storage, device, readUnit, buf, group, unit); +} + +// ----------------------------------------------------------------------------- + +static inline void deviceUpdateDynamicProperties(effaceable_storage_t * storage) +{ + if (isFnAvailable(storage, device, updateDynamicProperties)) { + delegateFn(storage, device, updateDynamicProperties); + } +} + +static inline void deviceFoundCurrentCloneInGroup(effaceable_storage_t * storage, uint32_t group) +{ + if (isFnAvailable(storage, device, foundCurrentCloneInGroup)) { + delegateFn(storage, device, foundCurrentCloneInGroup, group); + } +} + +static inline void deviceCleanBuffers(effaceable_storage_t * storage) +{ + if (isFnAvailable(storage, device, cleanBuffers)) { + delegateFn(storage, device, cleanBuffers); + } +} + +// ----------------------------------------------------------------------------- + +static inline void * allocMem(effaceable_storage_t * storage, uint32_t size) +{ + return delegateFn(storage, system, allocMem, size); +} + +static inline void freeMem(effaceable_storage_t * storage, void * buf, uint32_t size) +{ + delegateFn(storage, system, freeMem, buf, size); +} + +static inline void * setMem(effaceable_storage_t * storage, void * buf, uint8_t val, uint32_t size) +{ + return delegateFn(storage, system, setMem, buf, val, size); +} + +static inline void * moveMem(effaceable_storage_t * storage, void * dst, const void * src, uint32_t size) +{ + return delegateFn(storage, system, moveMem, dst, src, size); +} + +static inline int cmpMem(effaceable_storage_t * storage, const void * lhs, const void * rhs, uint32_t size) +{ + return delegateFn(storage, system, cmpMem, lhs, rhs, size); +} + +static inline void readRandom(effaceable_storage_t * storage, void * buf, uint32_t size) +{ + delegateFn(storage, system, readRandom, buf, size); +} + +static inline void calcSHA1(effaceable_storage_t * storage, const void * buf, uint32_t size, void * hash) +{ + delegateFn(storage, system, calcSHA1, buf, size, hash); +} + +static inline uint32_t crc32Sys(effaceable_storage_t * storage, uint32_t crc, const void * buf, uint32_t size, bool finish) +{ + return delegateFn(storage, system, crc32, crc, buf, size, finish); +} + +static inline bool setPropertySys(effaceable_storage_t * storage, const char * key, uint32_t value) +{ + return delegateFn(storage, system, setProperty, key, value); +} + +static inline void panicSys(effaceable_storage_t * storage, const char * msg) +{ + delegateFn(storage, system, panicSys, msg); +} + +static int logf(effaceable_storage_t * storage, const char * fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = delegateFn(storage, system, vlogf, fmt, ap); + va_end(ap); + + return err; +} + +// ----------------------------------------------------------------------------- + +static void +initContext(effaceable_storage_t * storage, effaceable_device_t * device, effaceable_system_t * system) +{ + storage->opaque = system->allocMem(system, sizeof(effaceable_storage_context_t)); + system->setMem(system, context(storage), 0, sizeof(effaceable_storage_context_t)); + + context(storage)->system = system; + context(storage)->device = device; +} + +// ============================================================================= diff --git a/lib/effaceable/common/effaceable_storage_core.h b/lib/effaceable/common/effaceable_storage_core.h new file mode 100644 index 0000000..2211240 --- /dev/null +++ b/lib/effaceable/common/effaceable_storage_core.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_STORAGE_CORE_H_ +#define _EFFACEABLE_STORAGE_CORE_H_ + +// ============================================================================= + +__BEGIN_DECLS + +// ----------------------------------------------------------------------------- + +static void updateInitialProperties(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +static uint32_t extGetCopiesPerUnit(effaceable_storage_t * storage); +static uint32_t extGetCopySize(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +static uint32_t getCopiesPerUnit(effaceable_storage_t * storage); +static uint32_t getCopySize(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +static EffaceableReturn getLocker(effaceable_storage_t * storage, uint32_t type_id, void *data, uint32_t *data_size, bool untrusted); +static EffaceableReturn getLockerExternal(effaceable_storage_t * storage, uint32_t type_id, void *data, uint32_t *data_size, bool untrusted); +static EffaceableReturn getLockerInternal(effaceable_storage_t * storage, uint32_t type_id, void *data, uint32_t *data_size, bool untrusted, bool notprivate); +static EffaceableReturn setLocker(effaceable_storage_t * storage, uint32_t type_id, const void *data, uint32_t data_size, bool untrusted); +static EffaceableReturn setLockerExternal(effaceable_storage_t * storage, uint32_t type_id, const void *data, uint32_t data_size, bool untrusted); +static EffaceableReturn setLockerInternal(effaceable_storage_t * storage, uint32_t type_id, const void *data, uint32_t data_size, bool untrusted, bool notprivate); +static EffaceableReturn spaceForLocker(effaceable_storage_t * storage, uint32_t type_id, uint32_t *data_space); +static EffaceableReturn effaceLocker(effaceable_storage_t * storage, uint32_t type_id, bool untrusted); +static EffaceableReturn effaceLockerExternal(effaceable_storage_t * storage, uint32_t type_id, bool untrusted); +static EffaceableReturn effaceLockerInternal(effaceable_storage_t * storage, uint32_t type_id, bool untrusted, bool notprivate); +static EffaceableReturn getBytes(effaceable_storage_t * storage, void * client_buf, uint32_t offset, uint32_t count); +static EffaceableReturn wipeStorage(effaceable_storage_t * storage, void * tmp_buf); +static uint32_t getCapacity(effaceable_storage_t * storage); +static bool isFormatted(effaceable_storage_t * storage); +static EffaceableReturn formatStorage(effaceable_storage_t * storage); +static EffaceableReturn generateNonce(effaceable_storage_t * storage, void * hash); +static EffaceableReturn consumeNonce(effaceable_storage_t * storage, uint64_t * nonce); + +// ----------------------------------------------------------------------------- + +static EffaceableReturn eraseGroupLogged(effaceable_storage_t * storage, uint32_t group); +static EffaceableReturn writeUnitLogged(effaceable_storage_t * storage, const void * io_buf, uint32_t group, uint32_t unit); +static EffaceableReturn readUnitLogged(effaceable_storage_t * storage, void * io_buf, uint32_t group, uint32_t unit); + +// ----------------------------------------------------------------------------- + +static void findCurrentClone(effaceable_storage_t * storage, void * tmp_buf, void * scan_buf, void * clone_buf); +static bool isGroupEffaced(effaceable_storage_t * storage, void * tmp_buf, uint32_t group); +static EffaceableReturn obscureCopy(effaceable_storage_t * storage, void * clear_buf, void * crypt_buf, uint32_t copy); +static EffaceableReturn revealCopy(effaceable_storage_t * storage, void * crypt_buf, void * clear_buf, uint32_t copy); +static EffaceableReturn commitClone(effaceable_storage_t * storage, void * clone_buf, uint32_t group); +static EffaceableReturn writeClone(effaceable_storage_t * storage, void * tmp_buf, void * clone_buf, uint32_t group, uint32_t generation); +static uint32_t checksumCopy(effaceable_storage_t * storage, void * clone_buf); +static bool isCopyValid(effaceable_storage_t * storage, const void * clone_buf); +static EffaceableReturn confirmClone(effaceable_storage_t * storage, void * tmp_buf, void * clone_buf, uint32_t group); + +// ----------------------------------------------------------------------------- + +static uint32_t nextGroup(effaceable_storage_t * storage, uint32_t group); +static EffaceableReturn effaceGroup(effaceable_storage_t * storage, void * tmp_buf, uint32_t group); + +// ----------------------------------------------------------------------------- + +static locker_t * findLockerForRequest(effaceable_storage_t * storage, uint32_t type_id); +static EffaceableReturn discardLockers(effaceable_storage_t * storage); +static void appendSentinel(effaceable_storage_t * storage); +static locker_t * findLockerForRequest(effaceable_storage_t * storage, uint32_t type_id); +static EffaceableReturn getLockersFromStorage(effaceable_storage_t * storage); +static EffaceableReturn putLockersInStorage(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +static void cleanBuffers(effaceable_storage_t * storage); +static void foundCurrentCloneInGroup(effaceable_storage_t * storage, uint32_t group); +static void updateDynamicProperties(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + + +// ----------------------------------------------------------------------------- + +static void initContract(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +static inline void * getCache(effaceable_storage_t * storage); +static inline void * setCache(effaceable_storage_t * storage, void * buf); + +static inline void * getScratch(effaceable_storage_t * storage); +static inline void * setScratch(effaceable_storage_t * storage, void * buf); + +static inline void * getSniff(effaceable_storage_t * storage); +static inline void * setSniff(effaceable_storage_t * storage, void * buf); + +static inline void * getCrypt(effaceable_storage_t * storage); +static inline void * setCrypt(effaceable_storage_t * storage, void * buf); + +static inline void * getNonceHash(effaceable_storage_t * storage); +static inline void * setNonceHash(effaceable_storage_t * storage, void * buf); + +static inline uint32_t getGeneration(effaceable_storage_t * storage); +static inline uint32_t setGeneration(effaceable_storage_t * storage, uint32_t generation); + +static inline uint32_t getGroup(effaceable_storage_t * storage); +static inline uint32_t setGroup(effaceable_storage_t * storage, uint32_t group); + +static inline bool getIsFormatted(effaceable_storage_t * storage); +static inline bool setIsFormatted(effaceable_storage_t * storage, bool is_formatted); + +static inline bool getFullScanEnabled(effaceable_storage_t * storage); +static inline bool setFullScanEnabled(effaceable_storage_t * storage, bool enable); + +static inline bool getWipeEnabled(effaceable_storage_t * storage); +static inline bool setWipeEnabled(effaceable_storage_t * storage, bool enable); + +static inline locker_list_t * getLockerList(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +static inline uint32_t getGroupCount(effaceable_storage_t * storage); +static inline uint32_t getUnitsPerGroup(effaceable_storage_t * storage); +static inline uint32_t getUnitSize(effaceable_storage_t * storage); +static inline bool eraseGroup(effaceable_storage_t * storage, uint32_t group); +static inline bool writeUnit(effaceable_storage_t * storage, const void * buf, uint32_t group, uint32_t unit); +static inline bool readUnit(effaceable_storage_t * storage, void * buf, uint32_t group, uint32_t unit); + +// ----------------------------------------------------------------------------- + +static inline void deviceCleanBuffers(effaceable_storage_t * storage); +static inline void deviceFoundCurrentCloneInGroup(effaceable_storage_t * storage, uint32_t group); +static inline void deviceUpdateDynamicProperties(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +static inline void * allocMem(effaceable_storage_t * storage, uint32_t size); +static inline void freeMem(effaceable_storage_t * storage, void * buf, uint32_t size); +static inline void * setMem(effaceable_storage_t * storage, void * buf, uint8_t val, uint32_t size); +static inline void * moveMem(effaceable_storage_t * storage, void * dst, const void * src, uint32_t size); +static inline int cmpMem(effaceable_storage_t * storage, const void * lhs, const void * rhs, uint32_t size); +static inline void readRandom(effaceable_storage_t * storage, void * buf, uint32_t size); +static inline void calcSHA1(effaceable_storage_t * storage, const void * buf, uint32_t size, void * hash); +static inline uint32_t crc32Sys(effaceable_storage_t * storage, uint32_t crc, const void * buf, uint32_t size, bool finish); +static inline bool setPropertySys(effaceable_storage_t * storage, const char * key, uint32_t value); +static inline void panicSys(effaceable_storage_t * storage, const char * msg); + +static int logf(effaceable_storage_t * storage, const char * fmt, ...); + +// ----------------------------------------------------------------------------- + +static void initContext(effaceable_storage_t * storage, effaceable_device_t * device, effaceable_system_t * system); + +// ----------------------------------------------------------------------------- + +__END_DECLS + +// ============================================================================= + +#endif /* _EFFACEABLE_STORAGE_CORE_H_ */ diff --git a/lib/effaceable/common/effaceable_storage_dev.h b/lib/effaceable/common/effaceable_storage_dev.h new file mode 100644 index 0000000..20c8559 --- /dev/null +++ b/lib/effaceable/common/effaceable_storage_dev.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// XXX find a better name for this file. perhaps 'effaceable_storage_entry.h'? + +#ifndef _EFFACEABLE_STORAGE_DEV_H_ +#define _EFFACEABLE_STORAGE_DEV_H_ + +// ============================================================================= + +__BEGIN_DECLS + +// ----------------------------------------------------------------------------- + +extern void startEffaceableStorage(effaceable_storage_t * storage, effaceable_device_t * device, effaceable_system_t * system); + +// ----------------------------------------------------------------------------- + +__END_DECLS + +// ============================================================================= + +#endif /* _EFFACEABLE_STORAGE_DEV_H_ */ diff --git a/lib/effaceable/common/include/AppleEffaceableStorageFormat.h b/lib/effaceable/common/include/AppleEffaceableStorageFormat.h new file mode 100644 index 0000000..e4c1c68 --- /dev/null +++ b/lib/effaceable/common/include/AppleEffaceableStorageFormat.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _APPLE_EFFACEABLE_STORAGE_FORMAT_H +#define _APPLE_EFFACEABLE_STORAGE_FORMAT_H + +// ============================================================================= + +#include + +// ============================================================================= + +#define kAppleEffaceableStorageMagic 'Face' + +#define kAppleEffaceableStorageGenerationUnknown ((uint32_t)0x00000000) +#define kAppleEffaceableStorageGenerationInitial ((uint32_t)0x00000001) +#define kAppleEffaceableStorageGenerationInvalid ((uint32_t)0xFFFFFFFF) + +#define kAppleEffaceableStorageVersionMajorUnknown ((uint32_t)0x00000000) +#define kAppleEffaceableStorageVersionMajorInitial ((uint32_t)0x00000001) +#define kAppleEffaceableStorageVersionMajorNonce ((uint32_t)0x00000001) +#define kAppleEffaceableStorageVersionMajorCurrent kAppleEffaceableStorageVersionMajorNonce +#define kAppleEffaceableStorageVersionMajorInvalid ((uint32_t)0xFFFFFFFF) + +#define kAppleEffaceableStorageVersionMinorUnknown ((uint32_t)0x00000000) +#define kAppleEffaceableStorageVersionMinorInitial ((uint32_t)0x00000001) +#define kAppleEffaceableStorageVersionMinorNonce ((uint32_t)0x00000002) +#define kAppleEffaceableStorageVersionMinorCurrent kAppleEffaceableStorageVersionMajorNonce +#define kAppleEffaceableStorageVersionMinorInvalid ((uint32_t)0xFFFFFFFF) + +#define kAppleEffaceableStorageFlagsNone ((uint32_t)0x00000000) + +#define kAppleEffaceableStorageSize 1024 +#define kAppleEffaceableStorageSaltSize 16 +#define kAppleEffaceableStorageReservedSize 24 +#define kAppleEffaceableStorageContentSize (kAppleEffaceableStorageSize - sizeof(AppleEffaceableStorageHeader)) + +#define kAppleEffaceableStorageLockerBase 0 +#define kAppleEffaceableStorageLockerSize (kAppleEffaceableStorageContentSize - kAppleEffaceableStorageLockerBase) + +// ============================================================================= + +// All structures defined here are on-media formats. + +typedef struct +{ + uint32_t magic; + uint32_t version_major; + uint32_t version_minor; + uint32_t flags; + +} __attribute__((__packed__)) AppleEffaceableStorageNaked; + +typedef struct +{ + uint8_t reserved[kAppleEffaceableStorageReservedSize]; + uint32_t generation; + uint32_t checksum; + +} __attribute__((__packed__)) AppleEffaceableStorageVeiled; + +typedef struct +{ + AppleEffaceableStorageNaked naked; + uint8_t salt[kAppleEffaceableStorageSaltSize]; + AppleEffaceableStorageVeiled veiled; + +} __attribute__((__packed__)) AppleEffaceableStorageHeader; + +typedef struct +{ + AppleEffaceableStorageHeader header; + uint8_t content[kAppleEffaceableStorageContentSize]; + +} __attribute__((__packed__)) AppleEffaceableStorageClone; + +typedef struct +{ + uint16_t magic; + uint16_t data_size; + uint32_t type_id; +} __attribute__((__packed__)) AppleEffaceableStorageLockerHeader; + +#define kAppleEffaceableStorageLockerMagic 0x4c6b // 'Lk' +#define kAppleEffaceableStorageLockerSentinel 'DONE' + + +// ============================================================================= + +#endif /* _APPLE_EFFACEABLE_STORAGE_FORMAT_H */ diff --git a/lib/effaceable/common/include/AppleEffaceableStorageKeys.h b/lib/effaceable/common/include/AppleEffaceableStorageKeys.h new file mode 100644 index 0000000..1f4bd60 --- /dev/null +++ b/lib/effaceable/common/include/AppleEffaceableStorageKeys.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _APPLE_EFFACEABLE_STORAGE_KEYS_H +#define _APPLE_EFFACEABLE_STORAGE_KEYS_H + +__BEGIN_DECLS + +// ============================================================================= + +// callPlatformFunction methods +// +// GetLocker +// Returns the contents of the locker type_id, if it exists. +// +// SetLocker +// Updates or creates the locker type_id. +// +// Space +// Returns the largest amount of data that could be stored in a locker +// with type_id, accounting for overwriting any current value. +// +// Efface +// Destroys the locker type_id and all its contents. +// +// GenerateNonce +// Populate private nonce locker with random 64-bit value and return its hash. +// +// type_id +// Unique identifier for the locker. Typically a four-byte ASCII value. +// +// data +// Pointer to read/write data buffer. +// +// data_size +// Buffer/operation size in bytes. Note that for GetLocker this is a +// pointer to an IOByteCount that is updated to the actual size of the +// locker, and for Space this is the amount of space available for +// a locker with type_id. +// +// untrusted +// True if the client is untrusted and should not be allowed to operate +// on protected lockers. +// +// hash +// Pointer to 20 byte buffer into which the nonce hash will be copied. +// +#define kAppleEffaceableStorageFunctionGet "GetLocker" // (type_id, *data, *data_size, untrusted) +#define kAppleEffaceableStorageFunctionSet "SetLocker" // (type_id, *data, data_size, untrusted) +#define kAppleEffaceableStorageFunctionEfface "EffaceLocker" // (type_id, untrusted) +#define kAppleEffaceableStorageFunctionGenerateNonce "GenerateNonce" // (*hash) +#define kAppleEffaceableStorageFunctionSpace "Space" // (type_id, *free_size) + +// When set on a request's type_id, the locker can only be read, overwritten and +// effaced by a kernel client. Cannot be set by a user client. +#define kAppleEffaceableStorageLockerProtected (1<<31) +// Special type for manipulating nonce locker, which is permitted +// only by the effaceable storage driver +#define kAppleEffaceableStorageLockerPrivate (1<<23) + +// These bits must not be set in a locker's type_id. +#define kAppleEffaceableStorageLockerReserved ((1<<15) | (1<<7)) + +// This type_id is considered a wildcard; passed to Efface it will cause +// every locker to be effaced. +#define kAppleEffaceableStorageLockerWildcard '****' + +// ============================================================================= + +#define kAppleEffaceableStorageClassName "AppleEffaceableStorage" + +// DeviceTree properties + +#define kAppleEffaceableStoragePropertyVersionMajor "VersionMajor" +#define kAppleEffaceableStoragePropertyVersionMinor "VersionMinor" +#define kAppleEffaceableStoragePropertyIsFormatted "IsFormatted" + +// UserClient methods + +enum _AppleEffaceableStorageMethod +{ + // Maintenance interface. + kAppleEffaceableStorageMethodGetCapacity, + kAppleEffaceableStorageMethodGetBytes, + kAppleEffaceableStorageMethodSetBytes, + kAppleEffaceableStorageMethodIsFormatted, + kAppleEffaceableStorageMethodFormatStorage, + + // Userclient locker methods. + // + // The type_id argument is always passed in scalarInput[0]. + // + // GetLocker returns the actual size of the locker in scalarOutput[0], + // and if structureOutput/structureOutputSize describe a buffer, as much + // of the locker data as will fit is returned into the buffer. + // + // SetLocker creates or replaces an existing locker with the contents of + // structureInput/structureInputSize. + // + // EffaceLocker destroys the locker. + // + kAppleEffaceableStorageMethodGetLocker, + kAppleEffaceableStorageMethodSetLocker, + kAppleEffaceableStorageMethodEffaceLocker, + kAppleEffaceableStorageMethodSpace, + + // Debug-only interface. + kAppleEffaceableStorageMethodWipeStorage, + + // Nonce support + kAppleEffaceableStorageMethodGenerateNonce, + + kAppleEffaceableStorageMethodCount +}; + +typedef enum _AppleEffaceableStorageMethod AppleEffaceableStorageMethod; + +// ============================================================================= + +__END_DECLS + +#endif /* _APPLE_EFFACEABLE_STORAGE_KEYS_H */ diff --git a/lib/effaceable/common/include/effaceable_contract.h b/lib/effaceable/common/include/effaceable_contract.h new file mode 100644 index 0000000..e7d4087 --- /dev/null +++ b/lib/effaceable/common/include/effaceable_contract.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_CONTRACT_H_ +#define _EFFACEABLE_CONTRACT_H_ + +// ============================================================================= + +#include +#include + +/* horrible that this is necessary */ +#ifndef __cplusplus +# ifndef false +# include +# endif +#endif + +// ============================================================================= + +enum _EffaceableReturn +{ + kEffaceableReturnSuccess = 0, + kEffaceableReturnError, + + kEffaceableReturnNotFound, + kEffaceableReturnUnsupported, + kEffaceableReturnNotPrivileged, + kEffaceableReturnNotPermitted, + kEffaceableReturnBadArgument, + kEffaceableReturnBadMedia, + kEffaceableReturnUnformattedMedia, + kEffaceableReturnIOError, + kEffaceableReturnNoMemory, + kEffaceableReturnNoSpace, + kEffaceableReturnInternalError, + + kEffaceableReturnInvalid +}; + +typedef enum _EffaceableReturn EffaceableReturn; + +// ============================================================================= + +struct _effaceable_storage; +struct _effaceable_device; +struct _effaceable_system; +struct _effaceable_nor_hal; +struct _effaceable_nand_hal; + +// ----------------------------------------------------------------------------- + +typedef struct _effaceable_storage effaceable_storage_t; +typedef struct _effaceable_device effaceable_device_t; + +typedef struct _effaceable_system effaceable_system_t; +typedef struct _effaceable_nor_hal effaceable_nor_hal_t; +typedef struct _effaceable_nand_hal effaceable_nand_hal_t; + +// ============================================================================= + +struct _effaceable_storage +{ + void * opaque; + + /* client api for use externally */ + EffaceableReturn (* getLocker )(effaceable_storage_t * storage, uint32_t type_id, void *data, uint32_t *data_size, bool untrusted); + EffaceableReturn (* setLocker )(effaceable_storage_t * storage, uint32_t type_id, const void *data, uint32_t data_size, bool untrusted); + EffaceableReturn (* spaceForLocker )(effaceable_storage_t * storage, uint32_t type_id, uint32_t *data_space); + EffaceableReturn (* effaceLocker )(effaceable_storage_t * storage, uint32_t type_id, bool untrusted); + EffaceableReturn (* generateNonce )(effaceable_storage_t * storage, void * hash); + EffaceableReturn (* consumeNonce )(effaceable_storage_t * storage, uint64_t * nonce); + + /* management api for use externally */ + EffaceableReturn (* getBytes )(effaceable_storage_t * storage, void * client_buf, uint32_t offset, uint32_t count); + EffaceableReturn (* wipeStorage )(effaceable_storage_t * storage, void * tmp_buf); + uint32_t (* getCapacity )(effaceable_storage_t * storage); + bool (* isFormatted )(effaceable_storage_t * storage); + EffaceableReturn (* formatStorage )(effaceable_storage_t * storage); + + /* spi for use by device-specific controller */ + uint32_t (* getCopiesPerUnit )(effaceable_storage_t * storage); + uint32_t (* getCopySize )(effaceable_storage_t * storage); +}; + +// ----------------------------------------------------------------------------- + +struct _effaceable_device +{ + void * opaque; + + /* device controller must provide concrete implementation of these operations */ + uint32_t (* getGroupCount )(effaceable_device_t * device); + uint32_t (* getUnitsPerGroup )(effaceable_device_t * device); + uint32_t (* getUnitSize )(effaceable_device_t * device); + EffaceableReturn (* eraseGroup )(effaceable_device_t * device, uint32_t group); + EffaceableReturn (* writeUnit )(effaceable_device_t * device, const void * buf, uint32_t group, uint32_t unit); + EffaceableReturn (* readUnit )(effaceable_device_t * device, void * buf, uint32_t group, uint32_t unit); + + /* device controller may optionally extend these device; if NULL, code should not call */ + void (* cleanBuffers )(effaceable_device_t * device); + void (* foundCurrentCloneInGroup )(effaceable_device_t * device, uint32_t group); + void (* updateDynamicProperties )(effaceable_device_t * device); +}; + +// ----------------------------------------------------------------------------- + +struct _effaceable_system +{ + void * opaque; + + /* operating system specific operations must be supplied when starting device */ + void * (* allocMem )(effaceable_system_t * system, uint32_t size); + void (* freeMem )(effaceable_system_t * system, void * buf, uint32_t size); + void * (* setMem )(effaceable_system_t * system, void * buf, uint8_t val, uint32_t size); + void * (* moveMem )(effaceable_system_t * system, void * dst, const void * src, uint32_t size); + int (* cmpMem )(effaceable_system_t * system, const void * lhs, const void * rhs, uint32_t size); + void (* readRandom )(effaceable_system_t * system, void * buf, uint32_t size); + void (* calcSHA1 )(effaceable_system_t * system, const void * buf, uint32_t size, void * hash); + uint32_t (* crc32 )(effaceable_system_t * system, uint32_t crc, const void * buf, uint32_t size, bool finish); + bool (* setProperty )(effaceable_system_t * system, const char * key, uint32_t value); + void (* panicSys )(effaceable_system_t * system, const char * msg); + int (* vlogf )(effaceable_system_t * system, const char * fmt, va_list ap); +}; + +// ----------------------------------------------------------------------------- + +/* contract for NOR HAL operations */ +struct _effaceable_nor_hal +{ + void * opaque; + + /* NOR HAL operations must be supplied when starting device */ + uint32_t (* getRegionCount )(effaceable_nor_hal_t * nor); + uint32_t (* getRegionSize )(effaceable_nor_hal_t * nor, uint32_t index); + EffaceableReturn (* eraseRegion )(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length); + uint32_t (* writeRegion )(effaceable_nor_hal_t * nor, uint32_t index, const void * buf, uint32_t length); + bool (* readRegion )(effaceable_nor_hal_t * nor, uint32_t index, void * buf, uint32_t length); +}; + +// ----------------------------------------------------------------------------- + +/* contract for NAND HAL operations */ +struct _effaceable_nand_hal +{ + void * opaque; + + /* NAND HAL operations must be supplied when starting device */ + uint32_t (* getPageSize )(effaceable_nand_hal_t * nand); + uint32_t (* getPageCount )(effaceable_nand_hal_t * nand); + uint32_t (* getBlockCount )(effaceable_nand_hal_t * nand); + uint32_t (* getBankCount )(effaceable_nand_hal_t * nand); + bool (* isBlockBad )(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block); + EffaceableReturn (* eraseBlock )(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block); + EffaceableReturn (* writePage )(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length); + EffaceableReturn (* readPage )(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length); + bool (* requestPartitionTableDiff )(effaceable_nand_hal_t * nand, void * buf, uint32_t length); + bool (* providePartitionTableDiff )(effaceable_nand_hal_t * nand, void * buf, uint32_t length); +}; + +// ============================================================================= + +__BEGIN_DECLS + +// ----------------------------------------------------------------------------- + +extern void startEffaceableNOR(effaceable_device_t * device, effaceable_system_t * system, effaceable_nor_hal_t * nor, effaceable_storage_t * storage); +extern void startEffaceableNAND(effaceable_device_t * device, effaceable_system_t * system, effaceable_nand_hal_t * nor, effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +__END_DECLS + +// ============================================================================= + +#endif /* _EFFACEABLE_CONTRACT_H_ */ diff --git a/lib/effaceable/common/include/effaceable_debug.h b/lib/effaceable/common/include/effaceable_debug.h new file mode 100644 index 0000000..34663ff --- /dev/null +++ b/lib/effaceable/common/include/effaceable_debug.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_DEBUG_H_ +#define _EFFACEABLE_DEBUG_H_ + +// ============================================================================= + +#define EFFACEABLE_DBGMSK_INIT (1<<0) +#define EFFACEABLE_DBGMSK_ERR (1<<1) +#define EFFACEABLE_DBGMSK_WARN (1<<2) +#define EFFACEABLE_DBGMSK_INFO (1<<3) +#define EFFACEABLE_DBGMSK_SPEW (1<<4) + +// ----------------------------------------------------------------------------- + +#define EFFACEABLE_DBGTAG_INIT "INIT" +#define EFFACEABLE_DBGTAG_ERR "ERR " +#define EFFACEABLE_DBGTAG_WARN "WARN" +#define EFFACEABLE_DBGTAG_INFO "INFO" +#define EFFACEABLE_DBGTAG_SPEW "SPEW" + +// ----------------------------------------------------------------------------- + +#define EFFACEABLE_DEBUG_ALL (EFFACEABLE_DBGMSK_INIT | \ + EFFACEABLE_DBGMSK_ERR | \ + EFFACEABLE_DBGMSK_WARN | \ + EFFACEABLE_DBGMSK_INFO | \ + EFFACEABLE_DBGMSK_SPEW) + +#define EFFACEABLE_DEBUG_MOST (EFFACEABLE_DBGMSK_INIT | \ + EFFACEABLE_DBGMSK_ERR | \ + EFFACEABLE_DBGMSK_WARN | \ + EFFACEABLE_DBGMSK_INFO) + +#define EFFACEABLE_DEBUG_DEFAULT (EFFACEABLE_DBGMSK_INIT | \ + EFFACEABLE_DBGMSK_ERR) + +// ----------------------------------------------------------------------------- + +#define EFFACEABLE_DEBUG EFFACEABLE_DEBUG_DEFAULT + +// ----------------------------------------------------------------------------- + +#if defined(EFFACEABLE_DEBUG) && EFFACEABLE_DEBUG + +# define dlogf(_api, _fac, _fmt, ...) \ + do { \ + if (EFFACEABLE_DBGMSK_##_fac & \ + EFFACEABLE_DEBUG) { \ + logf(_api, "[effaceable:%s] " _fmt "\n", \ + EFFACEABLE_DBGTAG_##_fac , \ + ## __VA_ARGS__ ); \ + } \ + } while(0) + +# define dhexdump(_api, _fac, _buf, _count) \ + do { \ + if (EFFACEABLE_DBGMSK_##_fac & \ + EFFACEABLE_DEBUG) { \ + unsigned _i, _j; \ + for (_i = 0; _i < _count; _i += 16) { \ + logf(_api, "[effaceable:%s] 0x%08x:", \ + EFFACEABLE_DBGTAG_##_fac , \ + ((unsigned) _buf) + _i); \ + for (_j = 0; (_j < 16) && ((_i + _j) < _count); _j++) \ + logf(_api, " %2.2x", ((uint8_t*)_buf)[_i + _j]); \ + logf(_api, "\n"); \ + } \ + } \ + } while(0) + +#else +# define dlogf(...) do { /* nothing */ } while(0) +# define dhexdump(...) do { /* nothing */ } while(0) +#endif + +// ============================================================================= + +#endif /* _EFFACEABLE_DEBUG_H_ */ diff --git a/lib/effaceable/common/queue.h b/lib/effaceable/common/queue.h new file mode 100644 index 0000000..9ccb63e --- /dev/null +++ b/lib/effaceable/common/queue.h @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines five types of data structures: singly-linked lists, + * singly-linked tail queues, lists, tail queues, and circular queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * Note that circle queues are deprecated, because, as the removal log + * in FreeBSD states, "CIRCLEQs are a disgrace to everything Knuth taught + * us in Volume 1 Chapter 2. [...] Use TAILQ instead, it provides the same + * functionality." Code using them will continue to compile, but they + * are no longer documented on the man page. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ CIRCLEQ + * _HEAD + + + + + + * _HEAD_INITIALIZER + + + + - + * _ENTRY + + + + + + * _INIT + + + + + + * _EMPTY + + + + + + * _FIRST + + + + + + * _NEXT + + + + + + * _PREV - - - + + + * _LAST - - + + + + * _FOREACH + + + + + + * _FOREACH_SAFE + + + + - + * _FOREACH_REVERSE - - - + - + * _FOREACH_REVERSE_SAFE - - - + - + * _INSERT_HEAD + + + + + + * _INSERT_BEFORE - + - + + + * _INSERT_AFTER + + + + + + * _INSERT_TAIL - - + + + + * _CONCAT - - + + - + * _REMOVE_AFTER + - + - - + * _REMOVE_HEAD + - + - - + * _REMOVE_HEAD_UNTIL - - + - - + * _REMOVE + + + + + + * _SWAP - + + + - + * + */ +#ifdef QUEUE_MACRO_DEBUG +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + char * lastfile; + int lastline; + char * prevfile; + int prevline; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRASHIT(x) +#endif /* QUEUE_MACRO_DEBUG */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_REMOVE_AFTER(curelm, field); \ + } \ + TRASHIT((elm)->field.sle_next); \ +} while (0) + +#define SLIST_REMOVE_AFTER(elm, field) do { \ + SLIST_NEXT(elm, field) = \ + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + STAILQ_REMOVE_AFTER(head, curelm, field); \ + } \ + TRASHIT((elm)->field.stqe_next); \ +} while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_SWAP(head1, head2, type) do { \ + struct type *swap_first = STAILQ_FIRST(head1); \ + struct type **swap_last = (head1)->stqh_last; \ + STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_FIRST(head2) = swap_first; \ + (head2)->stqh_last = swap_last; \ + if (STAILQ_EMPTY(head1)) \ + (head1)->stqh_last = &STAILQ_FIRST(head1); \ + if (STAILQ_EMPTY(head2)) \ + (head2)->stqh_last = &STAILQ_FIRST(head2); \ +} while (0) + + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#if (defined(_KERNEL) && defined(INVARIANTS)) || defined(QUEUE_MACRO_DEBUG) +#define QMD_LIST_CHECK_HEAD(head, field) do { \ + if (LIST_FIRST((head)) != NULL && \ + LIST_FIRST((head))->field.le_prev != \ + &LIST_FIRST((head))) \ + panic("Bad list head %p first->prev != head", (head)); \ +} while (0) + +#define QMD_LIST_CHECK_NEXT(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL && \ + LIST_NEXT((elm), field)->field.le_prev != \ + &((elm)->field.le_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (0) + +#define QMD_LIST_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.le_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (0) +#else +#define QMD_LIST_CHECK_HEAD(head, field) +#define QMD_LIST_CHECK_NEXT(elm, field) +#define QMD_LIST_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) || QUEUE_MACRO_DEBUG */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + QMD_LIST_CHECK_NEXT(listelm, field); \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_LIST_CHECK_PREV(listelm, field); \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + QMD_LIST_CHECK_HEAD((head), field); \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + QMD_LIST_CHECK_NEXT(elm, field); \ + QMD_LIST_CHECK_PREV(elm, field); \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ + TRASHIT((elm)->field.le_next); \ + TRASHIT((elm)->field.le_prev); \ +} while (0) + +#define LIST_SWAP(head1, head2, type, field) do { \ + struct type *swap_tmp = LIST_FIRST((head1)); \ + LIST_FIRST((head1)) = LIST_FIRST((head2)); \ + LIST_FIRST((head2)) = swap_tmp; \ + if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ + if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ +} while (0) + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + QMD_TRACE_HEAD(head1); \ + QMD_TRACE_HEAD(head2); \ + } \ +} while (0) + +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else { \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT((elm)->field.tqe_next); \ + TRASHIT((elm)->field.tqe_prev); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_SWAP(head1, head2, type, field) do { \ + struct type *swap_first = (head1)->tqh_first; \ + struct type **swap_last = (head1)->tqh_last; \ + (head1)->tqh_first = (head2)->tqh_first; \ + (head1)->tqh_last = (head2)->tqh_last; \ + (head2)->tqh_first = swap_first; \ + (head2)->tqh_last = swap_last; \ + if ((swap_first = (head1)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head1)->tqh_first; \ + else \ + (head1)->tqh_last = &(head1)->tqh_first; \ + if ((swap_first = (head2)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head2)->tqh_first; \ + else \ + (head2)->tqh_last = &(head2)->tqh_first; \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue functions. + */ +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) + +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = (head)->cqh_first; \ + (var) != (void *)(head); \ + (var) = (var)->field.cqe_next) + +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = (void *)(head); \ + (head)->cqh_last = (void *)(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = (void *)(head); \ + if ((head)->cqh_last == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = (void *)(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_LAST(head) ((head)->cqh_last) + +#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) + +#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#ifdef _KERNEL + +#if NOTFB31 + +/* + * XXX insque() and remque() are an old way of handling certain queues. + * They bogusly assumes that all queue heads look alike. + */ + +struct quehead { + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +#ifdef __GNUC__ + +static __inline void +insque(void *a, void *b) +{ + struct quehead *element = (struct quehead *)a, + *head = (struct quehead *)b; + + element->qh_link = head->qh_link; + element->qh_rlink = head; + head->qh_link = element; + element->qh_link->qh_rlink = element; +} + +static __inline void +remque(void *a) +{ + struct quehead *element = (struct quehead *)a; + + element->qh_link->qh_rlink = element->qh_rlink; + element->qh_rlink->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +#else /* !__GNUC__ */ + +void insque(void *a, void *b); +void remque(void *a); + +#endif /* __GNUC__ */ + +#endif +#endif /* _KERNEL */ + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/lib/effaceable/common/rules.mk b/lib/effaceable/common/rules.mk new file mode 100644 index 0000000..956720e --- /dev/null +++ b/lib/effaceable/common/rules.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/include + +ALL_OBJS += \ + $(LOCAL_DIR)/effaceable_storage_core.o \ + $(LOCAL_DIR)/effaceable_nand_core.o \ + $(LOCAL_DIR)/effaceable_nor_core.o diff --git a/lib/effaceable/docs/notes_to_auditors.txt b/lib/effaceable/docs/notes_to_auditors.txt new file mode 100644 index 0000000..6ab7375 --- /dev/null +++ b/lib/effaceable/docs/notes_to_auditors.txt @@ -0,0 +1,18 @@ +Significant changes were made to the structure of the project in the transition between AppleEffaceableStorage-24 and AppleEffaceableStorage-25. + +To assist auditors with their task (and anyone else analyzing the history of the project), it is useful to observe the following points: + + * core logic was refactored from the prior classes into a portable core implementation, located in the 'common' directory + - compare previous ./AppleEffaceableStorage.cpp to current ./common/effaceable_storage_core.c + - compare previous ./AppleEffaceableNAND.cpp to current ./common/effaceable_nand_core.c + - compare previous ./AppleEffaceableNOR.cpp to current ./common/effaceable_nor_core.c + * additional directory restructuring was done to make major implementation components more obvious to the reader + - private headers made available for exither external or internal cross-component use were moved to ./include subdirectory + - remaining IOKit code was moved to the ./iokit subdirectory + - implementation of the 'effaceable' command line utility was moved to the ./ios subdirectory + * more other + - there was also a minor bit of new functionality added to support generation and consumption of the private nonce locker + - the 'moveMem' system function contract uses 'memmove' arg ordering, so 'bcopy' instances replaced have swapped pointer args + - isCopyValid() modified to report real errors; in doing so, structure of logic changed such that all prior checks are negated + - deleted all trailing whitespace (with exception of 'queue.h', since it is imported from 'xnu/bsd/sys/queue.h') + - converted any tabs that crept in to four space hard indent to match style in majority of project (exception: 'queue.h') diff --git a/lib/effaceable/iboot/effaceable_cmd.c b/lib/effaceable/iboot/effaceable_cmd.c new file mode 100644 index 0000000..dc442c6 --- /dev/null +++ b/lib/effaceable/iboot/effaceable_cmd.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include + +#include + +#include +#include +#include + +// ============================================================================= + +static int do_effaceable(int argc, struct cmd_arg *args); +static void printUsage(int argc, struct cmd_arg *args); +static void effaceable_hexdump(const void * buf, uint32_t count); +static int lockerList(void); + +#if DEBUG_BUILD +static int consumeNonce(void); +#endif + +// ============================================================================= + +static int +do_effaceable(int argc, struct cmd_arg *args) +{ + int err; + + if (1 >= argc) { + printUsage(argc, args); + err = 0; + } else if (0 == strcmp("lockers", args[1].str)) { + err = lockerList(); +#if DEBUG_BUILD + } else if (0 == strcmp("nonce", args[1].str)) { + err = consumeNonce(); +#endif + } else { + printUsage(argc, args); + printf("unrecognized subcommand\n"); + err = -1; + } + + return err; +} + +// ============================================================================= + +static void +printUsage(int argc, struct cmd_arg *args) +{ + printf("USAGE: %s \n\n", ((0 < argc) ? args[0].str : "?")); + printf(" Where is one of following\n\n"); + printf(" lockers - list lockers and contents\n"); + +#if DEBUG_BUILD + printf(" nonce - consume nonce; then, report its SHA1 hash and value\n"); +#endif + + printf(" ...(more to come)...\n\n"); +} + +// ============================================================================= + +static void +effaceable_hexdump(const void * buf, uint32_t count) +{ + uint32_t i, j; + for (i = 0; i < count; i += 16) { + printf("0x%08x:", ((uint32_t) buf) + i); + for (j = 0; (j < 16) && ((i + j) < count); j++) { + printf(" %02.2x", ((uint8_t*)buf)[i+j]); + } + printf("\n"); + } +} + +// ============================================================================= + +#define UNTAG(x) \ + \ + (uint8_t)(((x) >> 24) & 0xff), \ + (uint8_t)(((x) >> 16) & 0xff), \ + (uint8_t)(((x) >> 8) & 0xff), \ + (uint8_t)((x) & 0xff) + +// ============================================================================= + +static int +lockerList(void) +{ + uint8_t *buf, *cursor; + uint32_t size; + AppleEffaceableStorageLockerHeader *header; + + size = effaceable_get_capacity(); + if (0 == size) { + printf("ERROR: unable to get capacity\n"); + return -1; + } + + buf = malloc(size); + + if (!effaceable_get_bytes(buf, 0, size)) { + printf("ERROR: unable to read\n"); + return -1; + } + + cursor = buf; + for (;;) { + header = (AppleEffaceableStorageLockerHeader *)cursor; + if (header->magic != kAppleEffaceableStorageLockerMagic) { + printf("WARNING: unexpected magic 0x%04x at %u, expected 0x%04x\n", + header->magic, cursor - buf, kAppleEffaceableStorageLockerMagic); + break; + } + if (header->type_id == kAppleEffaceableStorageLockerSentinel) { + printf("\n"); + break; + } + printf("0x%08x/0x%04x %c%c%c%c %s\n", + header->type_id, + header->data_size, + UNTAG(header->type_id & ~kAppleEffaceableStorageLockerProtected), + (header->type_id & kAppleEffaceableStorageLockerProtected) ? "(protected)" : ""); + cursor += sizeof(*header); + if (header->data_size > 0) { + if ((cursor + header->data_size) > (buf + size)) { + printf("WARNING: data overflows buffer\n"); + break; + } + effaceable_hexdump(cursor, header->data_size); + cursor += header->data_size; + } + if ((cursor + sizeof(*header)) > (buf + size)) { + printf("WARNING: header overflows buffer\n"); + break; + } + } + return 0; +} + +// ============================================================================= + +// XXX correct hard-coding of SHA1 buffer size +#define SHA1_HASH_SIZE 20 + +static int +consumeNonce(void) +{ + uint64_t nonce; + uint8_t hash[SHA1_HASH_SIZE]; + int idx; + + if (!effaceable_consume_nonce(&nonce)) { + printf("ERROR: unable to consume nonce\n"); + return -1; + } + + sha1_calculate(&nonce, sizeof(nonce), hash); + + for (idx = 0; idx < SHA1_HASH_SIZE; idx++) { + printf("%s%02X", (idx ? " " : ""), hash[idx]); + } + printf(" (0x%016llX)\n", nonce); + + return 0; +} + +// ============================================================================= + +MENU_COMMAND_DEBUG(effaceable, do_effaceable, "effaceable storage utilities", NULL); + +// ============================================================================= diff --git a/lib/effaceable/iboot/effaceable_storage.c b/lib/effaceable/iboot/effaceable_storage.c new file mode 100644 index 0000000..10aabc2 --- /dev/null +++ b/lib/effaceable/iboot/effaceable_storage.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include +#include + +#include +#include + +// ============================================================================= + +static int logf(void * ignored, const char * fmt, ...); + +#define debug(...) dlogf((void*)0, __VA_ARGS__ ) + +// ============================================================================= + +static effaceable_storage_t * gEffaceableStorage = (void*)0; + +// ============================================================================= + +extern void registerEffaceableStorage(effaceable_storage_t * storage) +{ + gEffaceableStorage = storage; +} + +// ============================================================================= + +effaceable_storage_t * locateEffaceableStorage(void) +{ + if (0 == gEffaceableStorage) { + debug(ERR, "no storage available"); + } + + return gEffaceableStorage; +} + +bool trustEffaceableContext(void) +{ +#if DEBUG_BUILD + return true; +#else + return false; +#endif +} + +// ============================================================================= + +bool effaceable_get_locker(uint32_t type_id, void * data, uint32_t * data_size) +{ + bool trust = trustEffaceableContext(); + effaceable_storage_t * storage = locateEffaceableStorage(); + + if (0 == storage) { + return false; + } + + if (kEffaceableReturnSuccess != storage->getLocker(storage, type_id, data, data_size, !trust)) { + return false; + } + + return true; +} + +bool effaceable_set_locker(uint32_t type_id, const void * data, uint32_t data_size) +{ + bool trust = trustEffaceableContext(); + effaceable_storage_t * storage = locateEffaceableStorage(); + + if (0 == storage) { + return false; + } + + if (kEffaceableReturnSuccess != storage->setLocker(storage, type_id, data, data_size, !trust)) { + return false; + } + + return true; +} + +bool effaceable_space_for_locker(uint32_t type_id, uint32_t * data_space) +{ + effaceable_storage_t * storage = locateEffaceableStorage(); + + if (0 == storage) { + return false; + } + + if (kEffaceableReturnSuccess != storage->spaceForLocker(storage, type_id, data_space)) { + return false; + } + + return true; +} + +bool effaceable_efface_locker(uint32_t type_id) +{ + bool trust = trustEffaceableContext(); + effaceable_storage_t * storage = locateEffaceableStorage(); + + if (0 == storage) { + return false; + } + + if (kEffaceableReturnSuccess != storage->effaceLocker(storage, type_id, !trust)) { + return false; + } + + return true; +} + +bool effaceable_consume_nonce(uint64_t * nonce) +{ + effaceable_storage_t * storage = locateEffaceableStorage(); + + if (0 == storage) { + return false; + } + + if (kEffaceableReturnSuccess != storage->consumeNonce(storage, nonce)) { + return false; + } + + return true; +} + +// ============================================================================= + +#if DEBUG_BUILD + +bool effaceable_get_bytes(void * client_buf, uint32_t offset, uint32_t count) +{ + effaceable_storage_t * storage = locateEffaceableStorage(); + + if (0 == storage) { + return false; + } + + if (kEffaceableReturnSuccess != storage->getBytes(storage, client_buf, offset, count)) { + return false; + } + + return true; +} + +uint32_t effaceable_get_capacity(void) +{ + effaceable_storage_t * storage = locateEffaceableStorage(); + uint32_t capacity = 0; + + if (0 != storage) { + capacity = storage->getCapacity(storage); + } + + debug(INFO, "capacity is %d bytes", capacity); + + return capacity; +} + +#endif + +// ============================================================================= + +static int logf(void * ignored, const char * fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = vprintf(fmt, ap); + va_end(ap); + + return err; +} + +// ============================================================================= diff --git a/lib/effaceable/iboot/effaceable_system.c b/lib/effaceable/iboot/effaceable_system.c new file mode 100644 index 0000000..30a5b29 --- /dev/null +++ b/lib/effaceable/iboot/effaceable_system.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// ============================================================================= + +#if DEBUG_BUILD +# define USING_STRONG_SEED false +#else +# define USING_STRONG_SEED true +#endif + +// ============================================================================= + +static int logf(void * ignored, const char * fmt, ...); + +#define debug(...) dlogf((void*)0, __VA_ARGS__ ) + +// ============================================================================= + +void * allocMemIboot(effaceable_system_t * system, uint32_t size) +{ + return malloc(size); +} + +void freeMemIboot(effaceable_system_t * system, void * buf, uint32_t size) +{ + free(buf); +} + +void * setMemIboot(effaceable_system_t * system, void * buf, uint8_t val, uint32_t size) +{ + return memset(buf, val, size); +} + +void * moveMemIboot(effaceable_system_t * system, void * dst, const void * src, uint32_t size) +{ + return memmove(dst, src, size); +} + +int cmpMemIboot(effaceable_system_t * system, const void * lhs, const void * rhs, uint32_t size) +{ + return memcmp(lhs, rhs, size); +} + +void readRandomIboot(effaceable_system_t * system, void * buf, uint32_t size) +{ + static bool is_seeded = false; + const unsigned increment = sizeof(int); + uint8_t * cursor = (uint8_t *)buf; + unsigned idx; + + // if we're using a strong seed, draw from the entropy pool to + // re-seed psuedo-random generator the first time function is called + if (!is_seeded && USING_STRONG_SEED) { + unsigned int seed; + random_get_bytes((u_int8_t*)&seed, sizeof(seed)); + srand(seed); + is_seeded = true; + } + + // fill with psuedo-random values by 'int'-sized chunks as long as possible + for (idx = 0; (idx + increment) <= size; idx += increment, cursor += increment) { + *((int*)cursor) = rand(); + } + + // if size doesn't divide evenly by increment, fill fringe bytewise + for (; idx < size; idx++, cursor++) { + *cursor = (uint8_t)rand(); + } +} + +void calcSHA1Iboot(effaceable_system_t * system, const void * buf, uint32_t size, void * hash) +{ + sha1_calculate(buf, size, hash); +} + +uint32_t crc32Iboot(effaceable_system_t * system, uint32_t crc, const void * buf, uint32_t size, bool finish) +{ + uint32_t val; + + if ((0 == crc) && (0 == buf) && (0 == size)) { + val = update_crc32(0xffffffffL, 0, 0); + } else { + val = update_crc32(crc, (unsigned char *)buf, size); + } + + return (finish ? val ^ 0xffffffffL : val); +} + +bool setPropertyIboot(effaceable_system_t * system, const char * key, uint32_t value) +{ + debug(INFO, "%s := %u", key, value); + return true; +} + +void panicIboot(effaceable_system_t * system, const char * msg) +{ + panic("%s", msg); +} + +int vlogfIboot(effaceable_system_t * system, const char * fmt, va_list ap) +{ + return vprintf(fmt, ap); +} + +// ============================================================================= + +extern EffaceableReturn +setupEffaceableSystemContract(effaceable_system_t * system) +{ + system->opaque = 0; + + system->allocMem = allocMemIboot; + system->freeMem = freeMemIboot; + system->setMem = setMemIboot; + system->moveMem = moveMemIboot; + system->cmpMem = cmpMemIboot; + system->readRandom = readRandomIboot; + system->calcSHA1 = calcSHA1Iboot; + system->crc32 = crc32Iboot; + system->setProperty = setPropertyIboot; + system->panicSys = panicIboot; + system->vlogf = vlogfIboot; + + return kEffaceableReturnSuccess; +} + +// ============================================================================= + +static int logf(void * ignored, const char * fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = vprintf(fmt, ap); + va_end(ap); + + return err; +} + +// ============================================================================= diff --git a/lib/effaceable/iboot/include/lib/effaceable.h b/lib/effaceable/iboot/include/lib/effaceable.h new file mode 100644 index 0000000..7e5eee3 --- /dev/null +++ b/lib/effaceable/iboot/include/lib/effaceable.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_STORAGE_API_H_ +#define _EFFACEABLE_STORAGE_API_H_ + +// ============================================================================= + +#include + +// ============================================================================= +// +// iBoot-specific presentation of the effaceable storage API for client use. +// +// ============================================================================= + +bool effaceable_get_locker(uint32_t type_id, void * data, uint32_t * data_size); +bool effaceable_set_locker(uint32_t type_id, const void * data, uint32_t data_size); +bool effaceable_space_for_locker(uint32_t type_id, uint32_t * data_space); +bool effaceable_efface_locker(uint32_t type_id); +bool effaceable_consume_nonce(uint64_t * nonce); + +// ============================================================================= +// +// iBoot-specific presentation of the effaceable storage API for util/devel. +// +// ============================================================================= + +bool effaceable_get_bytes(void * client_buf, uint32_t offset, uint32_t count); +uint32_t effaceable_get_capacity(void); + +// ============================================================================= + +#endif /* _EFFACEABLE_STORAGE_API_H_ */ diff --git a/lib/effaceable/iboot/include/lib/effaceable_impl.h b/lib/effaceable/iboot/include/lib/effaceable_impl.h new file mode 100644 index 0000000..c7a3d6a --- /dev/null +++ b/lib/effaceable/iboot/include/lib/effaceable_impl.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_IMPL_H_ +#define _EFFACEABLE_IMPL_H_ + +// ============================================================================= + +#include + +// ============================================================================= + +__BEGIN_DECLS + +// ----------------------------------------------------------------------------- + +extern EffaceableReturn setupEffaceableSystemContract(effaceable_system_t * system); +extern void registerEffaceableStorage(effaceable_storage_t * storage); + +// ----------------------------------------------------------------------------- + +__END_DECLS + +// ============================================================================= + +#endif /* _EFFACEABLE_IMPL_H_ */ diff --git a/lib/effaceable/iboot/nand/effaceable_nand.c b/lib/effaceable/iboot/nand/effaceable_nand.c new file mode 100644 index 0000000..c572ff2 --- /dev/null +++ b/lib/effaceable/iboot/nand/effaceable_nand.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include + +#include +#include + +#include +#include + +#include + +// ============================================================================= + +struct _context +{ + NandPartInterface * npi; + uint32_t idx; +}; + +typedef struct _context context_t; + +// ============================================================================= + +static inline context_t * context(effaceable_nand_hal_t * nand) +{ + return (context_t*)nand->opaque; +} + +// ============================================================================= + +#define delegateNPI(_me, _fn, ...) context(_me)->npi->_fn(context(_me)->npi->core, context(_me)->idx, ## __VA_ARGS__) + +// ============================================================================= + +static void initContext(effaceable_nand_hal_t * nand, NandPartInterface * npi, uint32_t idx) +{ + context_t * ctx = (context_t*)malloc(sizeof(context_t)); + + ctx->npi = npi; + ctx->idx = idx; + + nand->opaque = ctx; +} + +// ----------------------------------------------------------------------------- + +static uint32_t getPageSizeHook(effaceable_nand_hal_t * nand) +{ + return delegateNPI(nand, get_bytes_per_page); +} + +static uint32_t getPageCountHook(effaceable_nand_hal_t * nand) +{ + return delegateNPI(nand, get_pages_per_block); +} + +static uint32_t getBlockCountHook(effaceable_nand_hal_t * nand) +{ + return delegateNPI(nand, get_block_depth); +} + +static uint32_t getBankCountHook(effaceable_nand_hal_t * nand) +{ + return delegateNPI(nand, get_bank_width); +} + +static bool isBlockBadHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block) +{ + return delegateNPI(nand, is_block_bad, bank, block); +} + +static EffaceableReturn eraseBlockHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block) +{ + return (delegateNPI(nand, erase_block, bank, block) ? kEffaceableReturnSuccess : kEffaceableReturnError); +} + +static EffaceableReturn writePageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length) +{ + return (delegateNPI(nand, write_page, bank, block, page, (void*)buf) ? kEffaceableReturnSuccess : kEffaceableReturnError); +} + +static EffaceableReturn readPageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length) +{ + return (delegateNPI(nand, read_page, bank, block, page, buf, (bool*)0) ? kEffaceableReturnSuccess : kEffaceableReturnError); +} + +static bool requestPartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length) +{ + return delegateNPI(nand, request_ptab_diff, buf, length); +} + +static bool providePartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length) +{ + return delegateNPI(nand, provide_ptab_diff, buf, length); +} + +// ----------------------------------------------------------------------------- + +static void initContract(effaceable_nand_hal_t * nand) +{ + nand->getPageSize = getPageSizeHook; + nand->getPageCount = getPageCountHook; + nand->getBlockCount = getBlockCountHook; + nand->getBankCount = getBankCountHook; + nand->isBlockBad = isBlockBadHook; + nand->eraseBlock = eraseBlockHook; + nand->writePage = writePageHook; + nand->readPage = readPageHook; + nand->requestPartitionTableDiff = requestPartitionTableDiffHook; + nand->providePartitionTableDiff = providePartitionTableDiffHook; +} + +// ============================================================================= + +extern void +effaceable_nand_init(NandPartInterface * npi, uint32_t idx) +{ + effaceable_nand_hal_t * nand = (effaceable_nand_hal_t *)malloc(sizeof(effaceable_nand_hal_t)); + effaceable_device_t * device = (effaceable_device_t *)malloc(sizeof(effaceable_device_t)); + effaceable_system_t * system = (effaceable_system_t *)malloc(sizeof(effaceable_system_t)); + effaceable_storage_t * storage = (effaceable_storage_t *)malloc(sizeof(effaceable_storage_t)); + + initContext(nand, npi, idx); + initContract(nand); + + if (kEffaceableReturnSuccess == setupEffaceableSystemContract(system)) { + + startEffaceableNAND(device, system, nand, storage); + registerEffaceableStorage(storage); + } +} + +// ============================================================================= diff --git a/lib/effaceable/iboot/nand/include/lib/effaceable_nand.h b/lib/effaceable/iboot/nand/include/lib/effaceable_nand.h new file mode 100644 index 0000000..967014d --- /dev/null +++ b/lib/effaceable/iboot/nand/include/lib/effaceable_nand.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_NAND_H_ +#define _EFFACEABLE_NAND_H_ + +// ============================================================================= + +#include + +// ============================================================================= + +void effaceable_nand_init(NandPartInterface * npi, uint32_t idx); + +// ============================================================================= + +#endif /* _EFFACEABLE_NAND_H_ */ diff --git a/lib/effaceable/iboot/nand/rules.mk b/lib/effaceable/iboot/nand/rules.mk new file mode 100644 index 0000000..d61ec7b --- /dev/null +++ b/lib/effaceable/iboot/nand/rules.mk @@ -0,0 +1,32 @@ +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# XXX Clean this kludge up when iBoot two-stage boot changes are submitted. +ifneq ($(PRODUCT),iBSS) + +OPTIONS += \ + WITH_EFFACEABLE_NAND=1 + +MODULES += \ + lib/effaceable/iboot + +# XXX Clean this up when iBoot two-stage boot changes are submitted. +GLOBAL_INCLUDES += \ + drivers/flash_nand/boot \ + $(LOCAL_DIR)/include + +ALL_OBJS += \ + $(LOCAL_DIR)/effaceable_nand.o + +endif + +# XXX Consider relocating this directory to 'iBoot/drivers/apple/effaceable/nand'. diff --git a/lib/effaceable/iboot/nor/effaceable_nor.c b/lib/effaceable/iboot/nor/effaceable_nor.c new file mode 100644 index 0000000..4bcc6e0 --- /dev/null +++ b/lib/effaceable/iboot/nor/effaceable_nor.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include + +#include +#include + +#include +#include +#include + +// ============================================================================= + +#define WITH_EFFACEABLE_NOR_DEBUG 0 + +// ============================================================================= + +static int logf(void * ignored, const char * fmt, ...); + +#define debug(...) dlogf((void*)0, __VA_ARGS__ ) + +// ============================================================================= +// +// Effaceable NOR region definition is currently only supplied by means +// of publishing device tree up to iOS. Currently, in order to get this off +// its feet, I'm about to hard code equivalent information here; however, +// that's obviously not a very good solution going forward (for any of the +// NOR memory map, honestly). +// +// ============================================================================= + +#define NOR_BDEV "nor0" +#define REGION_SIZE ((uint32_t)0x1000) + +static const uint32_t region_offsets[] = {0xFA000, 0xFB000}; + +// ============================================================================= + +void validate(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length) +{ + require(nor != 0, fail_contract); + require(nor->opaque != 0, fail_context); + require(index < sizeof(region_offsets)/sizeof(region_offsets[0]), fail_index); + require(length <= REGION_SIZE, fail_length); + return; + +fail_contract: + panic("contract missing"); + +fail_context: + panic("context missing"); + +fail_index: + panic("bad index"); + +fail_length: + panic("bad length"); +} + +uint32_t getNorOffset(uint32_t index) +{ + return region_offsets[index]; +} + +static void +doHexdump(const void * buf, uint32_t count) +{ + uint32_t i, j; + for (i = 0; i < count; i += 16) { + printf("0x%08x:", ((uint32_t) buf) + i); + for (j = 0; (j < 16) && ((i + j) < count); j++) { + printf(" %2.2x", ((uint8_t*)buf)[i+j]); + } + printf("\n"); + } +} + + +// ============================================================================= + +#define context(nor) ((struct blockdev *)nor->opaque) + +// ============================================================================= + +uint32_t getRegionCountIboot(effaceable_nor_hal_t * nor) +{ + validate(nor, 0, 0); + return sizeof(region_offsets)/sizeof(region_offsets[0]); +} + +uint32_t getRegionSizeIboot(effaceable_nor_hal_t * nor, uint32_t index) +{ + validate(nor, index, 0); + return REGION_SIZE; +} + +EffaceableReturn eraseRegionIboot(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + int err; + + validate(nor, index, length); + + err = blockdev_erase(context(nor), getNorOffset(index), length); + + if (err < 0) { + ok = kEffaceableReturnIOError; + } + debug(INFO, "blockdev_erase on '%s' %s", NOR_BDEV, (kEffaceableReturnSuccess == ok) ? "succeeded" : "failed"); + return ok; +} + +uint32_t writeRegionIboot(effaceable_nor_hal_t * nor, uint32_t index, const void * buf, uint32_t length) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + int err; + + validate(nor, index, length); + + err = blockdev_write(context(nor), buf, getNorOffset(index), length); + + if (err <= 0) { + ok = kEffaceableReturnIOError; + } + debug(INFO, "blockdev_write to '%s' %s", NOR_BDEV, (kEffaceableReturnSuccess == ok) ? "succeeded" : "failed"); + return ok; +} + +bool readRegionIboot(effaceable_nor_hal_t * nor, uint32_t index, void * buf, uint32_t length) +{ + EffaceableReturn ok = kEffaceableReturnSuccess; + int err; + + validate(nor, index, length); + + err = blockdev_read(context(nor), buf, getNorOffset(index), length); + + if (err <= 0) { + ok = kEffaceableReturnIOError; + } else { +#if WITH_EFFACEABLE_NOR_DEBUG + doHexdump(buf, length); +#endif + } + debug(INFO, "blockdev_read from '%s' %s", NOR_BDEV, (kEffaceableReturnSuccess == ok) ? "succeeded" : "failed"); + return kEffaceableReturnSuccess; +} + +// ============================================================================= + +EffaceableReturn +setupEffaceableNorContract(effaceable_nor_hal_t * nor) +{ + nor->opaque = lookup_blockdev(NOR_BDEV); + + if (0 == nor->opaque) { + debug(ERR, "unable to find '%s' blockdev", NOR_BDEV); + return kEffaceableReturnBadMedia; + } + + nor->getRegionCount = getRegionCountIboot; + nor->getRegionSize = getRegionSizeIboot; + nor->eraseRegion = eraseRegionIboot; + nor->writeRegion = writeRegionIboot; + nor->readRegion = readRegionIboot; + + debug(INFO, "nor contract setup complete"); + + return kEffaceableReturnSuccess; +} + +// ============================================================================= + +extern void +effaceable_nor_init(void) +{ + effaceable_nor_hal_t * nor = (effaceable_nor_hal_t *)malloc(sizeof(effaceable_nor_hal_t)); + effaceable_device_t * device = (effaceable_device_t *)malloc(sizeof(effaceable_device_t)); + effaceable_system_t * system = (effaceable_system_t *)malloc(sizeof(effaceable_system_t)); + effaceable_storage_t * storage = (effaceable_storage_t *)malloc(sizeof(effaceable_storage_t)); + + if ((kEffaceableReturnSuccess == setupEffaceableNorContract(nor)) && + (kEffaceableReturnSuccess == setupEffaceableSystemContract(system))) { + + startEffaceableNOR(device, system, nor, storage); + registerEffaceableStorage(storage); + debug(INFO, "registered nor-backed effaceable storage"); + + } else { + + debug(ERR, "failed to init nor-backed effaceable storage"); + } +} + +// ============================================================================= + +static int logf(void * ignored, const char * fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = vprintf(fmt, ap); + va_end(ap); + + return err; +} + +// ============================================================================= diff --git a/lib/effaceable/iboot/nor/include/lib/effaceable_nor.h b/lib/effaceable/iboot/nor/include/lib/effaceable_nor.h new file mode 100644 index 0000000..4a39e57 --- /dev/null +++ b/lib/effaceable/iboot/nor/include/lib/effaceable_nor.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_NOR_H_ +#define _EFFACEABLE_NOR_H_ + +// ============================================================================= + +#include + +// ============================================================================= + +void effaceable_nor_init(void); + +// ============================================================================= + +#endif /* _EFFACEABLE_NOR_H_ */ diff --git a/lib/effaceable/iboot/nor/rules.mk b/lib/effaceable/iboot/nor/rules.mk new file mode 100644 index 0000000..deed594 --- /dev/null +++ b/lib/effaceable/iboot/nor/rules.mk @@ -0,0 +1,30 @@ +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# XXX Clean this kludge up when iBoot two-stage boot changes are submitted. +ifneq ($(PRODUCT),iBSS) + +OPTIONS += \ + WITH_EFFACEABLE_NOR=1 + +MODULES += \ + lib/effaceable/iboot + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/include + +ALL_OBJS += \ + $(LOCAL_DIR)/effaceable_nor.o + +endif + +# XXX Consider relocating this directory to 'iBoot/drivers/apple/effaceable/nand'. diff --git a/lib/effaceable/iboot/rules.mk b/lib/effaceable/iboot/rules.mk new file mode 100644 index 0000000..0ee4446 --- /dev/null +++ b/lib/effaceable/iboot/rules.mk @@ -0,0 +1,25 @@ +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_EFFACEABLE=1 + +MODULES += \ + lib/effaceable/common + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/include + +ALL_OBJS += \ + $(LOCAL_DIR)/effaceable_system.o \ + $(LOCAL_DIR)/effaceable_storage.o \ + $(LOCAL_DIR)/effaceable_cmd.o diff --git a/lib/effaceable/iokit/AppleEffaceableNAND.cpp b/lib/effaceable/iokit/AppleEffaceableNAND.cpp new file mode 100644 index 0000000..89ad27f --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableNAND.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include + +#include "AppleEffaceableNAND.h" + +#include "effaceable_contract.h" +#include "effaceable_debug.h" + +// ============================================================================= + +#define debug(...) dlogf((void*)0, __VA_ARGS__ ) + +// ============================================================================= + +#ifdef super +#undef super +#endif +#define super AppleEffaceableStorage + +OSDefineMetaClassAndStructors(AppleEffaceableNAND, AppleEffaceableStorage); + +// ============================================================================= + +bool +AppleEffaceableNAND::start(IOService *provider) +{ + bool ok = false; + + debug(INFO, "starting"); + + setupNandContract(); + + if (0 == (_partition = OSDynamicCast(IOFlashStoragePartition, provider))) { + debug(ERR, "provider is not an IOFlashStoragePartition"); + } else if (!super::start(provider)) { + debug(ERR, "superclass unable to start"); + } else { + debug(INIT, "started"); + ok = true; + } + + return ok; +} + +// ============================================================================= + +effaceable_nand_hal_t * +AppleEffaceableNAND::nand(void) +{ + return &_nand_hal; +} + +void +AppleEffaceableNAND::setupDeviceContract(void) +{ + startEffaceableNAND(device(), system(), nand(), storage()); +} + +// ============================================================================= + +AppleEffaceableNAND * context(effaceable_nand_hal_t * nand) +{ + AppleEffaceableNAND * context; + + // XXX assert instead? + if (0 == (context = (AppleEffaceableNAND *)nand->opaque)) + panic("null context"); + + return context; +} + +uint32_t getPageSizeHook(effaceable_nand_hal_t * nand) +{ + return context(nand)->getPageSizeNand(); +} + +uint32_t getPageCountHook(effaceable_nand_hal_t * nand) +{ + return context(nand)->getPageCountNand(); +} + +uint32_t getBlockCountHook(effaceable_nand_hal_t * nand) +{ + return context(nand)->getBlockCountNand(); +} + +uint32_t getBankCountHook(effaceable_nand_hal_t * nand) +{ + return context(nand)->getBankCountNand(); +} + +bool isBlockBadHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block) +{ + return context(nand)->isBlockBadNand(bank, block); +} + +EffaceableReturn eraseBlockHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block) +{ + return context(nand)->eraseBlockNand(bank, block); +} + +EffaceableReturn writePageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length) +{ + return context(nand)->writePageNand(bank, block, page, buf, length); +} + +EffaceableReturn readPageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length) +{ + return context(nand)->readPageNand(bank, block, page, buf, length); +} + +bool requestPartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length) +{ + return context(nand)->requestPartitionTableDiffNand(buf, length); +} + +bool providePartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length) +{ + return context(nand)->providePartitionTableDiffNand(buf, length); +} + +// ============================================================================= + +void +AppleEffaceableNAND::setupNandContract(void) +{ + nand()->opaque = this; + + nand()->getPageSize = getPageSizeHook; + nand()->getPageCount = getPageCountHook; + nand()->getBlockCount = getBlockCountHook; + nand()->getBankCount = getBankCountHook; + nand()->isBlockBad = isBlockBadHook; + nand()->eraseBlock = eraseBlockHook; + nand()->writePage = writePageHook; + nand()->readPage = readPageHook; + nand()->requestPartitionTableDiff = requestPartitionTableDiffHook; + nand()->providePartitionTableDiff = providePartitionTableDiffHook; +} + +uint32_t AppleEffaceableNAND::getPageSizeNand(void) +{ + return (IOByteCount)_partition->getPageSize(); +} + +uint32_t AppleEffaceableNAND::getPageCountNand(void) +{ + return _partition->getPagesPerBlock(); +} + +uint32_t AppleEffaceableNAND::getBlockCountNand(void) +{ + return _partition->getBlockCount(); +} + +uint32_t AppleEffaceableNAND::getBankCountNand(void) +{ + return _partition->getBankCount(); +} + +bool AppleEffaceableNAND::isBlockBadNand(uint32_t bank, uint32_t block) +{ + return _partition->isBlockBad(bank, block); +} + +EffaceableReturn AppleEffaceableNAND::eraseBlockNand(uint32_t bank, uint32_t block) +{ + return efReturn(_partition->eraseBlock(bank, block)); +} + +EffaceableReturn AppleEffaceableNAND::writePageNand(uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length) +{ + IOReturn ok; + IOBufferMemoryDescriptor * bmd; + + // XXX It's unfortunate that the IOBMD is necessary; think about how/where to clean it up. + + bmd = IOBufferMemoryDescriptor::withBytes(buf, length, kIODirectionInOut, true); + if (0 == bmd) + panic("no memory"); + + ok = _partition->writePage(bank, block, page, bmd); + + bmd->release(); + + return efReturn(ok); +} + +EffaceableReturn AppleEffaceableNAND::readPageNand(uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length) +{ + IOReturn ok; + IOBufferMemoryDescriptor * bmd; + + // XXX It's unfortunate that the IOBMD is necessary; think about how/where to clean it up. + + bmd = IOBufferMemoryDescriptor::withCapacity(length, kIODirectionInOut, true); + if (0 == bmd) + panic("no memory"); + + ok = _partition->readPage(bank, block, page, bmd); + + if (kIOReturnSuccess == ok) + bmd->readBytes(0, buf, length); + bmd->release(); + + return efReturn(ok); +} + +bool AppleEffaceableNAND::requestPartitionTableDiffNand(void * buf, uint32_t length) +{ + return _partition->requestPartitionTableDiff(buf, length); +} + +bool AppleEffaceableNAND::providePartitionTableDiffNand(void * buf, uint32_t length) +{ + return _partition->providePartitionTableDiff(buf, length); +} + +// ============================================================================= diff --git a/lib/effaceable/iokit/AppleEffaceableNAND.h b/lib/effaceable/iokit/AppleEffaceableNAND.h new file mode 100644 index 0000000..ee204a7 --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableNAND.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _APPLE_EFFACEABLE_NAND_H +#define _APPLE_EFFACEABLE_NAND_H + +#include +#include +#include +#include "AppleEffaceableStorage.h" + +#include "effaceable_contract.h" + +class AppleEffaceableNAND : public AppleEffaceableStorage +{ + OSDeclareDefaultStructors(AppleEffaceableNAND); + +public: + virtual bool start(IOService * provider); + + friend uint32_t getPageSizeHook(effaceable_nand_hal_t * nand); + friend uint32_t getPageCountHook(effaceable_nand_hal_t * nand); + friend uint32_t getBlockCountHook(effaceable_nand_hal_t * nand); + friend uint32_t getBankCountHook(effaceable_nand_hal_t * nand); + friend bool isBlockBadHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block); + friend EffaceableReturn eraseBlockHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block); + friend EffaceableReturn writePageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length); + friend EffaceableReturn readPageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length); + friend bool requestPartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length); + friend bool providePartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length); + +protected: + effaceable_nand_hal_t * nand(void); + + virtual void setupDeviceContract(void); + +private: + void setupNandContract(void); + + uint32_t getPageSizeNand(void); + uint32_t getPageCountNand(void); + uint32_t getBlockCountNand(void); + uint32_t getBankCountNand(void); + bool isBlockBadNand(uint32_t bank, uint32_t block); + EffaceableReturn eraseBlockNand(uint32_t bank, uint32_t block); + EffaceableReturn writePageNand(uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length); + EffaceableReturn readPageNand(uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length); + bool requestPartitionTableDiffNand(void * buf, uint32_t length); + bool providePartitionTableDiffNand(void * buf, uint32_t length); + + IOFlashStoragePartition * _partition; + effaceable_nand_hal_t _nand_hal; +}; + +#endif /* _APPLE_NAND_EFFACEABLE_STORAGE_H */ diff --git a/lib/effaceable/iokit/AppleEffaceableNOR.cpp b/lib/effaceable/iokit/AppleEffaceableNOR.cpp new file mode 100644 index 0000000..667f708 --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableNOR.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include + +#include "AppleEffaceableNOR.h" + +#include "effaceable_contract.h" +#include "effaceable_debug.h" + +// ============================================================================= + +#define debug(...) dlogf((void*)0, __VA_ARGS__ ) + +// ============================================================================= + + +#ifdef super +#undef super +#endif +#define super AppleEffaceableStorage + +OSDefineMetaClassAndStructors(AppleEffaceableNOR, AppleEffaceableStorage); + +// ============================================================================= + +bool +AppleEffaceableNOR::start(IOService *provider) +{ + bool ok = false; + + debug(INFO, "starting"); + + setupNorContract(); + + if (_is_started) { + debug(INFO, "already started"); + ok = true; + } else if (0 == (_nor_flash = OSDynamicCast(AppleARMNORFlashDevice, provider))) { + debug(ERR, "bug in kext matching"); + } else if (!super::start(provider)) { + debug(ERR, "super failed to start"); + } else { + debug(INIT, "started"); + _is_started = true; + ok = true; + } + + return ok; +} + +// ============================================================================= + +effaceable_nor_hal_t * +AppleEffaceableNOR::nor(void) +{ + return &_nor_hal; +} + +void +AppleEffaceableNOR::setupDeviceContract(void) +{ + startEffaceableNOR(device(), system(), nor(), storage()); +} + +// ============================================================================= + +AppleEffaceableNOR * context(effaceable_nor_hal_t * nor) +{ + AppleEffaceableNOR * context; + + // XXX assert instead? + if (0 == (context = (AppleEffaceableNOR *)nor->opaque)) + panic("null context"); + + return context; +} + +uint32_t getRegionCountHook(effaceable_nor_hal_t * nor) +{ + return context(nor)->getRegionCountNor(); +} + +uint32_t getRegionSizeHook(effaceable_nor_hal_t * nor, uint32_t index) +{ + return context(nor)->getRegionSizeNor(index); +} + +EffaceableReturn eraseRegionHook(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length) +{ + return context(nor)->eraseRegionNor(index, length); +} + +uint32_t writeRegionHook(effaceable_nor_hal_t * nor, uint32_t index, const void * buf, uint32_t length) +{ + return context(nor)->writeRegionNor(index, buf, length); +} + +bool readRegionHook(effaceable_nor_hal_t * nor, uint32_t index, void * buf, uint32_t length) +{ + return context(nor)->readRegionNor(index, buf, length); +} + +// ============================================================================= + +void +AppleEffaceableNOR::setupNorContract(void) +{ + nor()->opaque = this; + + nor()->getRegionCount = getRegionCountHook; + nor()->getRegionSize = getRegionSizeHook; + nor()->eraseRegion = eraseRegionHook; + nor()->writeRegion = writeRegionHook; + nor()->readRegion = readRegionHook; +} + +uint32_t +AppleEffaceableNOR::getRegionCountNor(void) +{ + return _nor_flash->getRegionCount(); +} + +uint32_t +AppleEffaceableNOR::getRegionSizeNor(uint32_t index) +{ + return _nor_flash->getRegionSize(index); +} + +EffaceableReturn +AppleEffaceableNOR::eraseRegionNor(uint32_t index, uint32_t length) +{ + return efReturn(_nor_flash->eraseRegion(index, 0, length)); +} + +uint32_t +AppleEffaceableNOR::writeRegionNor(uint32_t index, const void * buf, uint32_t length) +{ + return _nor_flash->writeRegion(index, (const UInt8*)buf, length); +} + +bool +AppleEffaceableNOR::readRegionNor(uint32_t index, void * buf, uint32_t length) +{ + return _nor_flash->readRegion(index, (UInt8*)buf, length); +} + +// ============================================================================= diff --git a/lib/effaceable/iokit/AppleEffaceableNOR.h b/lib/effaceable/iokit/AppleEffaceableNOR.h new file mode 100644 index 0000000..5e50a92 --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableNOR.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _APPLE_EFFACEABLE_NOR_H +#define _APPLE_EFFACEABLE_NOR_H + +#include +#include +#include +#include "AppleEffaceableStorage.h" + +#include "effaceable_contract.h" + +class AppleEffaceableNOR : public AppleEffaceableStorage +{ + OSDeclareAbstractStructors(AppleEffaceableNOR); + +public: + virtual bool start(IOService * provider); + + friend uint32_t getRegionCountHook(effaceable_nor_hal_t * nor); + friend uint32_t getRegionSizeHook(effaceable_nor_hal_t * nor, uint32_t index); + friend EffaceableReturn eraseRegionHook(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length); + friend uint32_t writeRegionHook(effaceable_nor_hal_t * nor, uint32_t index, const void * buf, uint32_t length); + friend bool readRegionHook(effaceable_nor_hal_t * nor, uint32_t index, void * buf, uint32_t length); + +protected: + effaceable_nor_hal_t * nor(void); + + virtual void setupDeviceContract(void); + +private: + void setupNorContract(void); + + uint32_t getRegionCountNor(void); + uint32_t getRegionSizeNor(uint32_t index); + EffaceableReturn eraseRegionNor(uint32_t index, uint32_t length); + uint32_t writeRegionNor(uint32_t index, const void * buf, uint32_t length); + bool readRegionNor(uint32_t index, void * buf, uint32_t length); + + AppleARMNORFlashDevice * _nor_flash; + bool _is_started; + effaceable_nor_hal_t _nor_hal; +}; + +#endif /* _APPLE_EFFACEABLE_NOR_H */ diff --git a/lib/effaceable/iokit/AppleEffaceableStorage.cpp b/lib/effaceable/iokit/AppleEffaceableStorage.cpp new file mode 100644 index 0000000..c2b01ab --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableStorage.cpp @@ -0,0 +1,545 @@ +/* + * Copyright (c) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +#include +#include + +#include +#include +#include + +#include "AppleEffaceableStorageKeys.h" +#include "AppleEffaceableStorageFormat.h" +#include "AppleEffaceableStorage.h" + +#include "effaceable_contract.h" +#include "effaceable_debug.h" + +// ============================================================================= + +#define debug(...) dlogf((void*)0, __VA_ARGS__ ) + +// ============================================================================= + +#ifdef super +#undef super +#endif +#define super IOService + +OSDefineMetaClassAndAbstractStructors(AppleEffaceableStorage, IOService); + +// ============================================================================= + +bool AppleEffaceableStorage::start(IOService *provider) +{ + bool ok = false; + + debug(INFO, "starting"); + + if (!super::start(provider)) { + debug(ERR, "super did not start\n"); + } else if (NULL == (_work_loop = IOWorkLoop::workLoop())) { + debug(ERR, "couldn't init work loop"); + } else if (NULL == (_command_gate = IOCommandGate::commandGate(this))) { + debug(ERR, "couldn't acquire command gate"); + } else if ((NULL == (_function_get = OSSymbol::withCString(kAppleEffaceableStorageFunctionGet))) || + (NULL == (_function_set = OSSymbol::withCString(kAppleEffaceableStorageFunctionSet))) || + (NULL == (_function_space = OSSymbol::withCString(kAppleEffaceableStorageFunctionSpace))) || + (NULL == (_function_efface = OSSymbol::withCString(kAppleEffaceableStorageFunctionEfface))) || + (NULL == (_function_gen_nonce = OSSymbol::withCString(kAppleEffaceableStorageFunctionGenerateNonce)))) { + debug(ERR, "couldn't allocate function symbols"); + } else { + + // add command gate to work loop + getWorkLoop()->addEventSource(_command_gate); + + // commandgate actions +#define _ACTION_CAST(_x) OSMemberFunctionCast(IOCommandGate::Action, this, _x) + _get_action = _ACTION_CAST(&AppleEffaceableStorage::getLockerGated); + _set_action = _ACTION_CAST(&AppleEffaceableStorage::setLockerGated); + _space_action = _ACTION_CAST(&AppleEffaceableStorage::spaceForLockerGated); + _efface_action = _ACTION_CAST(&AppleEffaceableStorage::effaceLockerGated); + _gen_nonce_action = _ACTION_CAST(&AppleEffaceableStorage::generateNonceGated); + _format_action = _ACTION_CAST(&AppleEffaceableStorage::formatStorageGated); + _get_bytes_action = _ACTION_CAST(&AppleEffaceableStorage::getBytesGated); + _wipe_action = _ACTION_CAST(&AppleEffaceableStorage::wipeStorageGated); +#undef _ACTION_CAST + + // initalize portable core + setupSystemContract(); + setupDeviceContract(); + + registerService(); + ok = true; + } + + if (!ok) { + if (NULL != _command_gate) { + _command_gate->release(); + _command_gate = NULL; + } + if (NULL != _work_loop) { + _work_loop->release(); + _work_loop = NULL; + } + } + + return ok; +} + +void +AppleEffaceableStorage::registerService(IOOptionBits options) +{ + const OSSymbol * user_client; + + // hook up the user client + user_client = OSSymbol::withCStringNoCopy("AppleEffaceableStorageUserClient"); + setProperty(gIOUserClientClassKey, (OSObject *)user_client); + user_client->release(); + + super::registerService(options); +} + +IOWorkLoop * +AppleEffaceableStorage::getWorkLoop() const +{ + return _work_loop; +} + +// ============================================================================= + +IOByteCount +AppleEffaceableStorage::getCapacity(void) +{ + return (IOByteCount)storage()->getCapacity(storage()); +} + +bool +AppleEffaceableStorage::isFormatted(void) +{ + return storage()->isFormatted(storage()); +} + +IOReturn +AppleEffaceableStorage::formatStorage(void) +{ + return _command_gate->runAction(_format_action); +} + +IOReturn +AppleEffaceableStorage::getBytes(void * client_buf, IOByteCount offset, IOByteCount count) +{ + if (PE_i_can_has_debugger(NULL)) { + return _command_gate->runAction(_get_bytes_action, (void *) client_buf, (void *) offset, (void *) count); + } else { + return kIOReturnUnsupported; + } +} + +IOReturn +AppleEffaceableStorage::wipeStorage(void) +{ + if (PE_i_can_has_debugger(NULL)) { + return _command_gate->runAction(_wipe_action); + } else { + return kIOReturnUnsupported; + } +} + +IOReturn +AppleEffaceableStorage::getLocker(UInt32 type_id, void *data, IOByteCount *data_size, bool untrusted) +{ + return _command_gate->runAction(_get_action, (void *)type_id, data, (void *)data_size, (void *)untrusted); +} + +IOReturn +AppleEffaceableStorage::setLocker(UInt32 type_id, const void *data, IOByteCount data_size, bool untrusted) +{ + return _command_gate->runAction(_set_action, (void *)type_id, (void *)data, (void *)data_size, (void *)untrusted); +} + +IOReturn +AppleEffaceableStorage::spaceForLocker(UInt32 type_id, IOByteCount *data_space) +{ + return _command_gate->runAction(_space_action, (void *)type_id, (void *)data_space); +} + +IOReturn +AppleEffaceableStorage::effaceLocker(UInt32 type_id, bool untrusted) +{ + return _command_gate->runAction(_efface_action, (void *)type_id, (void *)untrusted); +} + +IOReturn +AppleEffaceableStorage::generateNonce(void * hash) +{ + return _command_gate->runAction(_gen_nonce_action, hash); +} + +IOReturn +AppleEffaceableStorage::callPlatformFunction( + const OSSymbol *functionSymbol, + bool waitForFunction, + void *param1, + void *param2, + void *param3, + void *param4) +{ + if (functionSymbol == _function_get) + return getLocker((UInt32)(uintptr_t)param1, param2, (IOByteCount *)param3, (bool)param4); + + if (functionSymbol == _function_set) + return setLocker((UInt32)(uintptr_t)param1, param2, (IOByteCount)param3, (bool)param4); + + if (functionSymbol == _function_space) + return effaceLocker((UInt32)(uintptr_t)param1, (IOByteCount *)param2); + + if (functionSymbol == _function_efface) + return effaceLocker((UInt32)(uintptr_t)param1, (bool)param2); + + if (functionSymbol == _function_gen_nonce) + return generateNonce(param1); + + return(IOService::callPlatformFunction(functionSymbol, waitForFunction, param1, param2, param3, param4)); +} + +// ============================================================================= + +IOReturn +AppleEffaceableStorage::formatStorageGated(void) +{ + return ioReturn(storage()->formatStorage(storage())); +} + +IOReturn +AppleEffaceableStorage::getBytesGated(void * client_buf, IOByteCount offset, IOByteCount count) +{ + return ioReturn(storage()->getBytes(storage(), client_buf, offset, count)); +} + +IOReturn +AppleEffaceableStorage::wipeStorageGated(void * tmp_buf) +{ + return ioReturn(storage()->wipeStorage(storage(), tmp_buf)); +} + +// ============================================================================= + +IOReturn +AppleEffaceableStorage::getLockerGated(UInt32 type_id, void *data, IOByteCount *data_size, bool untrusted) +{ + return ioReturn(storage()->getLocker(storage(), type_id, data, (uint32_t *)data_size, untrusted)); +} + +IOReturn +AppleEffaceableStorage::setLockerGated(UInt32 type_id, const void *data, IOByteCount data_size, bool untrusted) +{ + return ioReturn(storage()->setLocker(storage(), type_id, data, (uint32_t)data_size, untrusted)); +} + +IOReturn +AppleEffaceableStorage::spaceForLockerGated(UInt32 type_id, IOByteCount *data_space) +{ + return ioReturn(storage()->spaceForLocker(storage(), type_id, (uint32_t *)data_space)); +} + +IOReturn +AppleEffaceableStorage::effaceLockerGated(UInt32 type_id, bool untrusted) +{ + return ioReturn(storage()->effaceLocker(storage(), type_id, untrusted)); +} + +IOReturn +AppleEffaceableStorage::generateNonceGated(void * hash) +{ + return ioReturn(storage()->generateNonce(storage(), hash)); +} + +// ============================================================================= + +effaceable_storage_t * +AppleEffaceableStorage::storage(void) +{ + return &_storage; +} + +effaceable_device_t * +AppleEffaceableStorage::device(void) +{ + return &_device; +} + +effaceable_system_t * +AppleEffaceableStorage::system(void) +{ + return &_system; +} + +EffaceableReturn +AppleEffaceableStorage::efReturn(IOReturn ret) +{ + EffaceableReturn cast = kEffaceableReturnInvalid; + switch (ret) { + case kIOReturnSuccess : cast = kEffaceableReturnSuccess ; break; + case kIOReturnError : cast = kEffaceableReturnError ; break; + case kIOReturnNotFound : cast = kEffaceableReturnNotFound ; break; + case kIOReturnUnsupported : cast = kEffaceableReturnUnsupported ; break; + case kIOReturnNotPrivileged : cast = kEffaceableReturnNotPrivileged ; break; + case kIOReturnNotPermitted : cast = kEffaceableReturnNotPermitted ; break; + case kIOReturnBadArgument : cast = kEffaceableReturnBadArgument ; break; + case kIOReturnBadMedia : cast = kEffaceableReturnBadMedia ; break; + case kIOReturnIOError : cast = kEffaceableReturnIOError ; break; + case kIOReturnNoMemory : cast = kEffaceableReturnNoMemory ; break; + case kIOReturnNoSpace : cast = kEffaceableReturnNoSpace ; break; + case kIOReturnInternalError : cast = kEffaceableReturnInternalError ; break; + case kIOReturnUnformattedMedia : cast = kEffaceableReturnUnformattedMedia; break; + } + return cast; +} + +IOReturn +AppleEffaceableStorage::ioReturn(EffaceableReturn ret) +{ + IOReturn cast = kIOReturnInvalid; + switch (ret) { + case kEffaceableReturnSuccess : cast = kIOReturnSuccess ; break; + case kEffaceableReturnError : cast = kIOReturnError ; break; + case kEffaceableReturnNotFound : cast = kIOReturnNotFound ; break; + case kEffaceableReturnUnsupported : cast = kIOReturnUnsupported ; break; + case kEffaceableReturnNotPrivileged : cast = kIOReturnNotPrivileged ; break; + case kEffaceableReturnNotPermitted : cast = kIOReturnNotPermitted ; break; + case kEffaceableReturnBadArgument : cast = kIOReturnBadArgument ; break; + case kEffaceableReturnBadMedia : cast = kIOReturnBadMedia ; break; + case kEffaceableReturnIOError : cast = kIOReturnIOError ; break; + case kEffaceableReturnNoMemory : cast = kIOReturnNoMemory ; break; + case kEffaceableReturnNoSpace : cast = kIOReturnNoSpace ; break; + case kEffaceableReturnInternalError : cast = kIOReturnInternalError ; break; + case kEffaceableReturnUnformattedMedia : cast = kIOReturnUnformattedMedia; break; + } + return cast; +} + +// ============================================================================= + +int +AppleEffaceableStorage::logf(void * ignored, const char * fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = vlogfSys(fmt, ap); + va_end(ap); + + return err; +} + +// ============================================================================= + +void +AppleEffaceableStorage::handleBootArgs(void) +{ + uint32_t arg_flag = 0; + bool enable_wipe = false; + bool enable_full_scan = false; + + // boot-arg support to enable/disable of media wipe + if (PE_parse_boot_argn("effaceable-enable-wipe", &arg_flag, sizeof (arg_flag)) && arg_flag) { + enable_wipe = (0 != arg_flag); + // XXX plumb down through to core implementation + debug(INIT, "wipe %sabled via boot-arg", enable_wipe ? "en" : "dis"); + } + + // boot-arg support to enable/disable full scan + if (PE_parse_boot_argn("effaceable-enable-full-scan", &arg_flag, sizeof (arg_flag)) && arg_flag) { + enable_full_scan = (0 != arg_flag); + // XXX plumb down through to core implementation + debug(INIT, "full scan %sabled via boot-arg", enable_full_scan ? "en" : "dis"); + } +} + +// ============================================================================= + +AppleEffaceableStorage * context(effaceable_system_t * system) +{ + AppleEffaceableStorage * context; + + // XXX assert instead? + if (NULL == (context = (AppleEffaceableStorage *)system->opaque)) + panic("null context"); + + return context; +} + +void * allocMemHook(effaceable_system_t * system, uint32_t size) +{ + return context(system)->allocMemSys(size); +} + +void freeMemHook(effaceable_system_t * system, void * buf, uint32_t size) +{ + context(system)->freeMemSys(buf, size); +} + +void * setMemHook(effaceable_system_t * system, void * buf, uint8_t val, uint32_t size) +{ + return context(system)->setMemSys(buf, val, size); +} + +void * moveMemHook(effaceable_system_t * system, void * dst, const void * src, uint32_t size) +{ + return context(system)->moveMemSys(dst, src, size); +} + +int cmpMemHook(effaceable_system_t * system, const void * lhs, const void * rhs, uint32_t size) +{ + return context(system)->cmpMemSys(lhs, rhs, size); +} + +void readRandomHook(effaceable_system_t * system, void * buf, uint32_t size) +{ + context(system)->readRandomSys(buf, size); +} + +void calcSHA1Hook(effaceable_system_t * system, const void * buf, uint32_t size, void * hash) +{ + return context(system)->calcSHA1Sys(buf, size, hash); +} + +uint32_t crc32Hook(effaceable_system_t * system, uint32_t crc, const void * buf, uint32_t size, bool ignored) +{ + return context(system)->crc32Sys(crc, buf, size); +} + +bool setPropertyHook(effaceable_system_t * system, const char * key, uint32_t value) +{ + return context(system)->setPropertySys(key, value); +} + +void panicHook(effaceable_system_t * system, const char * msg) +{ + context(system)->panicSys(msg); +} + +int vlogfHook(effaceable_system_t * system, const char * fmt, va_list ap) +{ + return context(system)->vlogfSys(fmt, ap); +} + +// ============================================================================= + +void +AppleEffaceableStorage::setupSystemContract(void) +{ + // XXX convert to appropriate type of AssertMacros + if (sizeof(uint32_t) != sizeof(IOByteCount)) + panic("(sizeof(uint32_t) != sizeof(IOByteCount))"); + + system()->opaque = this; + + system()->allocMem = allocMemHook; + system()->freeMem = freeMemHook; + system()->setMem = setMemHook; + system()->moveMem = moveMemHook; + system()->cmpMem = cmpMemHook; + system()->readRandom = readRandomHook; + system()->calcSHA1 = calcSHA1Hook; + system()->crc32 = crc32Hook; + system()->setProperty = setPropertyHook; + system()->panicSys = panicHook; + system()->vlogf = vlogfHook; +} + +void * +AppleEffaceableStorage::allocMemSys(uint32_t size) +{ + void * buf = IOMalloc(size); + + if (0 == buf) { + panic("no memory"); + } + + return buf; +} + +void +AppleEffaceableStorage::freeMemSys(void * buf, uint32_t size) +{ + IOFree(buf, size); +} + +void * +AppleEffaceableStorage::setMemSys(void * buf, uint8_t val, uint32_t size) +{ + return memset(buf, val, size); +} + +void * +AppleEffaceableStorage::moveMemSys(void * dst, const void * src, uint32_t size) +{ + return memmove(dst, src, size); +} + +int +AppleEffaceableStorage::cmpMemSys(const void * lhs, const void * rhs, uint32_t size) +{ + return memcmp(lhs, rhs, size); +} + +void +AppleEffaceableStorage::readRandomSys(void * buf, uint32_t size) +{ + read_random(buf, size); +} + +void +AppleEffaceableStorage::calcSHA1Sys(const void * buf, uint32_t size, void * hash) +{ + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, buf, size); + SHA1Final(hash, &ctx); +} + +uint32_t +AppleEffaceableStorage::crc32Sys(uint32_t crc, const void * buf, uint32_t size) +{ + return crc32(crc, buf, size); +} + +bool +AppleEffaceableStorage::setPropertySys(const char * key, uint32_t value) +{ + return setProperty(key, value, 32); +} + +void +AppleEffaceableStorage::panicSys(const char * msg) +{ + panic(msg); +} + +int +AppleEffaceableStorage::vlogfSys(const char * fmt, va_list ap) +{ + IOLogv(fmt, ap); + + // XXX Given that IOLogv doesn't return character printed count, + // as least common denominator, it's probably best to reduce vlogf + // contract to void return value. + return 0; +} + +// ============================================================================= diff --git a/lib/effaceable/iokit/AppleEffaceableStorage.h b/lib/effaceable/iokit/AppleEffaceableStorage.h new file mode 100644 index 0000000..f8d62e7 --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableStorage.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _APPLE_EFFACEABLE_STORAGE_H +#define _APPLE_EFFACEABLE_STORAGE_H + +// ============================================================================= + +#include +#include +#include + +#include "AppleEffaceableStorageKeys.h" +#include "effaceable_contract.h" + +// ============================================================================= + +class AppleEffaceableStorage : public IOService +{ + OSDeclareAbstractStructors(AppleEffaceableStorage); + +public: + /* client API */ + IOReturn getLocker(UInt32 type_id, void *data, IOByteCount *data_size, bool untrusted = false); + IOReturn setLocker(UInt32 type_id, const void *data, IOByteCount data_size, bool untrusted = false); + IOReturn spaceForLocker(UInt32 type_id, IOByteCount *data_space); + IOReturn effaceLocker(UInt32 type_id, bool untrusted = false); + IOReturn generateNonce(void * hash); + + /* additional public functions intended for manufacturing and/or diagnostics only */ + IOReturn getBytes(void * client_buf, IOByteCount offset, IOByteCount count); + IOReturn wipeStorage(void); + IOByteCount getCapacity(void); + bool isFormatted(void); + IOReturn formatStorage(void); + +protected: + /* subclass SPI */ + effaceable_storage_t * storage(void); + effaceable_device_t * device(void); + effaceable_system_t * system(void); + + EffaceableReturn efReturn(IOReturn ret); + IOReturn ioReturn(EffaceableReturn ret); + + int logf(void * ignored, const char * fmt, ...); + + virtual void setupDeviceContract(void) = 0; + +public: + /* IOKit hooks */ + virtual bool start(IOService * provider); + virtual void registerService(IOOptionBits options = 0); + virtual IOWorkLoop * getWorkLoop() const; + virtual IOReturn callPlatformFunction(const OSSymbol *functionSymbol, bool waitForFunction, + void *param1, void *param2, void *param3, void *param4); + +private: + /* gated versions of public methods */ + IOReturn wipeStorageGated(void * tmp_buf); + IOReturn formatStorageGated(void); + IOReturn getBytesGated(void * client_buf, IOByteCount offset, IOByteCount count); + IOReturn getLockerGated(UInt32 type_id, void *data, IOByteCount *data_size, bool untrusted); + IOReturn setLockerGated(UInt32 type_id, const void *data, IOByteCount data_size, bool untrusted); + IOReturn spaceForLockerGated(UInt32 type_id, IOByteCount *data_spage); + IOReturn effaceLockerGated(UInt32 type_id, bool untrusted); + IOReturn generateNonceGated(void * hash); + + /* methods to help get portable core setup and configured */ + void setupSystemContract(void); + void handleBootArgs(void); + + /* implementation of portable core system services contract */ + void * allocMemSys(uint32_t size); + void freeMemSys(void * buf, uint32_t size); + void * setMemSys(void * buf, uint8_t val, uint32_t size); + void * moveMemSys(void * dst, const void * src, uint32_t size); + int cmpMemSys(const void * lhs, const void * rhs, uint32_t size); + void readRandomSys(void * buf, uint32_t size); + void calcSHA1Sys(const void * buf, uint32_t size, void * hash); + uint32_t crc32Sys(uint32_t crc, const void * buf, uint32_t size); + bool setPropertySys(const char * key, uint32_t value); + void panicSys(const char * msg); + int vlogfSys(const char * fmt, va_list ap); + +private: + /* friend C function hooks implementing trampoline back to C++ for portable core system contract */ + friend void * allocMemHook(effaceable_system_t * system, uint32_t size); + friend void freeMemHook(effaceable_system_t * system, void * buf, uint32_t size); + friend void * setMemHook(effaceable_system_t * system, void * buf, uint8_t val, uint32_t size); + friend void * moveMemHook(effaceable_system_t * system, void * dst, const void * src, uint32_t size); + friend int cmpMemHook(effaceable_system_t * system, const void * lhs, const void * rhs, uint32_t size); + friend void readRandomHook(effaceable_system_t * system, void * buf, uint32_t size); + friend void calcSHA1Hook(effaceable_system_t * system, const void * buf, uint32_t size, void * hash); + friend uint32_t crc32Hook(effaceable_system_t * system, uint32_t crc, const void * buf, uint32_t size, bool ignored); + friend bool setPropertyHook(effaceable_system_t * system, const char * key, uint32_t value); + friend void panicHook(effaceable_system_t * system, const char * msg); + friend int vlogfHook(effaceable_system_t * system, const char * fmt, va_list ap); + +private: + /* implementation data */ + IOCommandGate * _command_gate; + IOWorkLoop * _work_loop; + const OSSymbol * _function_get; + const OSSymbol * _function_set; + const OSSymbol * _function_space; + const OSSymbol * _function_efface; + const OSSymbol * _function_gen_nonce; + IOCommandGate::Action _get_action; + IOCommandGate::Action _set_action; + IOCommandGate::Action _space_action; + IOCommandGate::Action _efface_action; + IOCommandGate::Action _gen_nonce_action; + IOCommandGate::Action _format_action; + IOCommandGate::Action _wipe_action; + IOCommandGate::Action _get_bytes_action; + effaceable_storage_t _storage; + effaceable_system_t _system; + effaceable_device_t _device; +}; + +// ============================================================================= + +#endif /* _APPLE_EFFACEABLE_STORAGE_H */ diff --git a/lib/effaceable/iokit/AppleEffaceableStorageUserClient.cpp b/lib/effaceable/iokit/AppleEffaceableStorageUserClient.cpp new file mode 100644 index 0000000..f1565f2 --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableStorageUserClient.cpp @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// ============================================================================= + +#include +#include +#include + +#include "AppleEffaceableStorage.h" +#include "AppleEffaceableStorageKeys.h" +#include "AppleEffaceableStorageUserClient.h" + +// ============================================================================= + +// XXX correct hard-coding of SHA1 buffer size +#define SHA1_HASH_SIZE 20 + +// ============================================================================= + +#define APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_INIT (1<<0) +#define APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_ERR (1<<1) +#define APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_WARN (1<<2) +#define APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_INFO (1<<3) +#define APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_SPEW (1<<4) + +#define APPLE_EFFACEABLE_USER_CLIENT_DBGTAG_INIT "INIT" +#define APPLE_EFFACEABLE_USER_CLIENT_DBGTAG_ERR "ERROR" +#define APPLE_EFFACEABLE_USER_CLIENT_DBGTAG_WARN "WARNING" +#define APPLE_EFFACEABLE_USER_CLIENT_DBGTAG_INFO "INFO" +#define APPLE_EFFACEABLE_USER_CLIENT_DBGTAG_SPEW "SPEW" + +#define APPLE_EFFACEABLE_USER_CLIENT_DEBUG_ALL (APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_INIT | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_ERR | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_WARN | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_INFO | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_SPEW) + +#define APPLE_EFFACEABLE_USER_CLIENT_DEBUG_MOST (APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_INIT | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_ERR | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_WARN | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_INFO) + +#define APPLE_EFFACEABLE_USER_CLIENT_DEBUG_DEFAULT (APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_INIT | \ + APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_ERR) + +#ifdef DEBUG_BUILD +# define APPLE_EFFACEABLE_USER_CLIENT_DEBUG APPLE_EFFACEABLE_USER_CLIENT_DEBUG_MOST +#else +# define APPLE_EFFACEABLE_USER_CLIENT_DEBUG APPLE_EFFACEABLE_USER_CLIENT_DEBUG_DEFAULT +#endif + +#if defined(APPLE_EFFACEABLE_USER_CLIENT_DEBUG) && APPLE_EFFACEABLE_USER_CLIENT_DEBUG +# define debug(fac, fmt, args...) \ + do { \ + if (APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_##fac & \ + APPLE_EFFACEABLE_USER_CLIENT_DEBUG) { \ + kprintf("AppleEffaceableStorageUserClient::%s():[%s] " fmt "\n", \ + __FUNCTION__, \ + APPLE_EFFACEABLE_USER_CLIENT_DBGTAG_##fac , \ + ##args ); \ + } \ + } while(0) +# define hexdump(fac, bytes, count) \ + do { \ + if (APPLE_EFFACEABLE_USER_CLIENT_DBGMSK_##fac & \ + APPLE_EFFACEABLE_USER_CLIENT_DEBUG) { \ + uint32_t i, j; \ + for (i = 0; i < count; i += 16) { \ + kprintf("AppleEffaceableStorageUserClient::%s():[%s] 0x%08x:", \ + __FUNCTION__, \ + APPLE_EFFACEABLE_USER_CLIENT_DBGTAG_##fac , \ + ((uint32_t) bytes) + i); \ + for (j = 0; (j < 16) && ((i + j) < count); j++) \ + kprintf(" %2.2x", ((uint8_t*)bytes)[i+j]); \ + kprintf("\n"); \ + } \ + } \ + } while(0) +#else +# define debug(fac, fmt, args...) do { /* nothing */ } while(0) +# define hexdump(fac, bytes, count) do { /* nothing */ } while(0) +#endif + +// ============================================================================= + +#ifdef super +#undef super +#endif +#define super IOUserClient + +OSDefineMetaClassAndStructors(AppleEffaceableStorageUserClient, IOUserClient); + +// ============================================================================= + +bool +AppleEffaceableStorageUserClient::start(IOService *provider) +{ + bool ok = false; + + _provider = OSDynamicCast(AppleEffaceableStorage, provider); + + if (NULL == _provider) { + debug(ERR, "bug in kext matching"); + } else if (!super::start(provider)) { + debug(ERR, "super failed to start"); + } else { + debug(INFO, "started"); + ok = true; + } + + return ok; +} + +IOReturn +AppleEffaceableStorageUserClient::clientClose(void) +{ + terminate(); + return kIOReturnSuccess; +} + +IOReturn +AppleEffaceableStorageUserClient::externalMethod(uint32_t selector, + IOExternalMethodArguments * arguments, + IOExternalMethodDispatch *dispatch, + OSObject *target, + void *reference) +{ + IOReturn ok = kIOReturnSuccess; + bool secure_root; + + // require administrator privilege + if (kIOReturnSuccess != clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator)) { + debug(ERR, "not authorized"); + return kIOReturnNotPrivileged; + } + +#ifdef DEBUG_BUILD + secure_root = true; +#else + // some operations require a secure root + if (kIOReturnSuccess != (ok = _provider->getProvider()->callPlatformFunction("SecureRoot", + false, + _provider->getProvider(), + &secure_root, + 0, 0))) { + debug(ERR, "failed to determine root trust state"); + secure_root = false; + } +#endif // DEBUG_BUILD + + switch (selector) { + case kAppleEffaceableStorageMethodGetCapacity: + + if (arguments->scalarOutputCount != 1) { + debug(ERR, "getCapacity: missing output argument"); + ok = kIOReturnBadArgument; + } else { + arguments->scalarOutput[0] = _provider->getCapacity(); + } + break; + + case kAppleEffaceableStorageMethodIsFormatted: + + if (arguments->scalarOutputCount != 1) { + debug(ERR, "isFormatted: missing output argument"); + ok = kIOReturnBadArgument; + } else { + arguments->scalarOutput[0] = _provider->isFormatted(); + } + break; + + case kAppleEffaceableStorageMethodFormatStorage: + + if (!secure_root) { + debug(ERR, "format attempt from untrusted root"); + } else { + ok = _provider->formatStorage(); + } + break; + + case kAppleEffaceableStorageMethodWipeStorage: + + if (!secure_root) { + debug(ERR, "wipe attempt from untrusted root"); + } else { + ok = _provider->wipeStorage(); + } + break; + + case kAppleEffaceableStorageMethodGetLocker: + + if ((arguments->scalarInputCount != 1) || + (arguments->scalarOutputCount != 1)) { + debug(ERR, "getLocker: missing input/output arguments"); + ok = kIOReturnBadArgument; + } else { + IOByteCount data_size = arguments->structureOutputSize; + ok = _provider->getLocker(arguments->scalarInput[0], + arguments->structureOutput, + &data_size, + !secure_root); + arguments->scalarOutput[0] = data_size; + // if we didn't clip the data, report the actual output size + if (data_size < arguments->structureOutputSize) + arguments->structureOutputSize = data_size; + } + break; + + case kAppleEffaceableStorageMethodSetLocker: + + if ((arguments->scalarInputCount != 1) || + (arguments->structureInputSize < 1)) { + debug(ERR, "setLocker: missing input arguments"); + ok = kIOReturnBadArgument; + } else { + ok = _provider->setLocker(arguments->scalarInput[0], + arguments->structureInput, + arguments->structureInputSize, + !secure_root); + } + break; + + case kAppleEffaceableStorageMethodSpace: + + if ((arguments->scalarInputCount != 1) || + (arguments->scalarOutputCount != 1)) { + debug(ERR, "lockerSpace: missing input/output arguments"); + ok = kIOReturnBadArgument; + } else { + IOByteCount data_space; + ok = _provider->spaceForLocker(arguments->scalarInput[0], + &data_space); + arguments->scalarOutput[0] = data_space; + } + break; + + case kAppleEffaceableStorageMethodEffaceLocker: + + if (arguments->scalarInputCount != 1) { + debug(ERR, "effaceLocker: missing input argument"); + ok = kIOReturnBadArgument; + } else if (!secure_root && arguments->scalarInput[0] == kAppleEffaceableStorageLockerWildcard) { + debug(ERR, "effaceLocker: untrusted attempt to efface by wildcard"); + ok = kIOReturnNotPermitted; + } else { + ok = _provider->effaceLocker(arguments->scalarInput[0], !secure_root); + } + break; + + case kAppleEffaceableStorageMethodGenerateNonce: + + if (arguments->structureOutputSize != SHA1_HASH_SIZE) { + debug(ERR, "generateNonce: missing output argument"); + ok = kIOReturnBadArgument; + } else { + ok = _provider->generateNonce(arguments->structureOutput); + if (kIOReturnSuccess != ok) { + arguments->structureOutputSize = 0; + } + } + break; + +// +// Methods below are not for production use and may only be used when kernel debug enabled via boot-args. +// + + case kAppleEffaceableStorageMethodGetBytes: + + if ((arguments->scalarInputCount != 1) || + (arguments->structureOutputSize < 1)) { + ok = kIOReturnBadArgument; + } else if (!PE_i_can_has_debugger(NULL)) { + debug(ERR, "getBytes is only allowed when kernel debug is enabled"); + ok = kIOReturnUnsupported; + } else { + ok = _provider->getBytes(arguments->structureOutput, arguments->scalarInput[0], arguments->structureOutputSize); + if (kIOReturnSuccess != ok) { + debug(ERR, "getBytes from user client to service failed"); + } else { + debug(SPEW, "read %u bytes from offset %llu", arguments->structureOutputSize, arguments->scalarInput[0]); + } + } + break; + + default: + debug(ERR, "bad selector %u", selector); + ok = kIOReturnUnsupported; + break; + } + + return ok; +} diff --git a/lib/effaceable/iokit/AppleEffaceableStorageUserClient.h b/lib/effaceable/iokit/AppleEffaceableStorageUserClient.h new file mode 100644 index 0000000..e6e720e --- /dev/null +++ b/lib/effaceable/iokit/AppleEffaceableStorageUserClient.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010-11 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _APPLE_EFFACEABLE_USER_CLIENT_H +#define _APPLE_EFFACEABLE_USER_CLIENT_H + +#include +#include "AppleEffaceableStorage.h" + +class AppleEffaceableStorageUserClient : public IOUserClient +{ + OSDeclareAbstractStructors(AppleEffaceableStorageUserClient); + +public: + virtual bool start(IOService * provider); + virtual IOReturn clientClose(void); + virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments * arguments, + IOExternalMethodDispatch * dispatch, OSObject * target, + void * reference); + +private: + AppleEffaceableStorage * _provider; +}; + +#endif /* _APPLE_EFFACEABLE_USER_CLIENT_H */ diff --git a/lib/effaceable/iokit/Info.plist b/lib/effaceable/iokit/Info.plist new file mode 100644 index 0000000..c03c3fb --- /dev/null +++ b/lib/effaceable/iokit/Info.plist @@ -0,0 +1,77 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.apple.driver.AppleEffaceableStorage + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CFBundleShortVersionString + 1.0 + OSBundleCompatibleVersion + 1.0 + IOKitPersonalities + + AppleEffaceableNAND + + CFBundleIdentifier + com.apple.driver.AppleEffaceableStorage + IOClass + AppleEffaceableNAND + IOPropertyMatch + + + Content Hint + Effaceable + + + IOProviderClass + IOFlashMedia + + AppleEffaceableNOR + + CFBundleIdentifier + com.apple.driver.AppleEffaceableStorage + IOClass + AppleEffaceableNOR + IONameMatch + effaceable,nor + IOProviderClass + AppleARMNORFlashDevice + + + OSBundleCompatibleVersion + 1.0.0 + OSBundleLibraries + + com.apple.driver.AppleARMPlatform + 1.0.0 + com.apple.iokit.IOFlashStorage + 1.0.0 + com.apple.kpi.bsd + 8.0 + com.apple.kpi.iokit + 8.0 + com.apple.kpi.libkern + 8.0 + com.apple.kpi.mach + 8.0 + com.apple.kpi.unsupported + 8.0 + + + diff --git a/lib/effaceable/ios/effaceable.c b/lib/effaceable/ios/effaceable.c new file mode 100644 index 0000000..a5ccd2a --- /dev/null +++ b/lib/effaceable/ios/effaceable.c @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "AppleEffaceableStorageKeys.h" +#include "AppleEffaceableStorageFormat.h" +#include "effaceable.h" + +// ============================================================================= + +// XXX correct hard-coding of SHA1 buffer size +#define SHA1_HASH_SIZE 20 + +// ============================================================================= + +bool +connectClient(const char * name, io_service_t * service, io_connect_t * connection) +{ + bool ok = false; + mach_port_t master; + CFDictionaryRef match; + io_service_t found_service; + io_connect_t found_connection; + + if (KERN_SUCCESS != IOMasterPort(MACH_PORT_NULL, &master)) { + warnx("IOMasterPort failed"); + } else if (IO_OBJECT_NULL == (match = IOServiceMatching(name))) { + warnx("IOServiceMatching failed for %s", name); + } else if (IO_OBJECT_NULL == (found_service = IOServiceGetMatchingService(master, match))) { + warnx("IOServiceGetMatchingService failed"); + } else if (KERN_SUCCESS != IOServiceOpen(found_service, mach_task_self(), 0, &found_connection)) { + warnx("IOServiceOpen failed for class '%s'", name); + } else { + *service = found_service; + *connection = found_connection; + ok = true; + } + + if (!ok) { + // XXX clean up + } + + return ok; +} + +bool +wipeStorage(io_connect_t connection) +{ + bool ok = false; + + if (KERN_SUCCESS != IOConnectCallScalarMethod(connection, + kAppleEffaceableStorageMethodWipeStorage, + NULL, + 0, + NULL, + NULL)) { + errx(1, "wipe failed"); + } else { + ok = true; + } + return ok; +} + +bool +getCapacity(io_connect_t connection, IOByteCount * capacity) +{ + bool ok = false; + const uint32_t expected_count = 1; + uint32_t output_count = expected_count; + uint64_t output[output_count]; + + if (KERN_SUCCESS != IOConnectCallScalarMethod(connection, + kAppleEffaceableStorageMethodGetCapacity, + NULL, + 0, + output, + &output_count)) { + warnx("IOConnectCallScalarMethod failed"); + } else if (expected_count != output_count) { + warnx("unexpected scalar output count"); + } else { + *capacity = (IOByteCount) output[0]; + ok = true; + } + return ok; +} + +bool +getBytes(io_connect_t connection, void * buf, IOByteCount offset, IOByteCount count) +{ + bool ok = false; + uint64_t input; + size_t output_count = count; + + input = (uint64_t)offset; + + if (KERN_SUCCESS != IOConnectCallMethod(connection, + kAppleEffaceableStorageMethodGetBytes, + &input, + 1, + NULL, + 0, + NULL, + NULL, + buf, + &output_count)) { + warnx("IOConnectCallMethod failed"); + } else if (count != output_count) { + warnx("unexpected output struct count"); + } else { + ok = true; + } + return ok; +} + +bool +setBytes(io_connect_t connection, const void * buf, IOByteCount offset, IOByteCount count) +{ + bool ok = false; + uint64_t input; + + input = (uint64_t)offset; + + if (KERN_SUCCESS != IOConnectCallMethod(connection, + kAppleEffaceableStorageMethodSetBytes, + &input, + 1, + buf, + count, + NULL, + NULL, + NULL, + NULL)) { + warnx("IOConnectCallMethod failed"); + } else { + ok = true; + } + return ok; +} + +bool +isFormatted(io_connect_t connection, bool * is_formatted) +{ + bool ok = false; + const uint32_t expected_count = 1; + uint32_t output_count = expected_count; + uint64_t output[output_count]; + + if (KERN_SUCCESS != IOConnectCallScalarMethod(connection, + kAppleEffaceableStorageMethodIsFormatted, + NULL, + 0, + output, + &output_count)) { + warnx("IOConnectCallScalarMethod failed"); + } else if (expected_count != output_count) { + warnx("unexpected scalar output count"); + } else { + *is_formatted = (bool) output[0]; + ok = true; + } + return ok; +} + +bool +formatStorage(io_connect_t connection) +{ + bool ok = false; + + if (KERN_SUCCESS != IOConnectCallScalarMethod(connection, + kAppleEffaceableStorageMethodFormatStorage, + NULL, + 0, + NULL, + NULL)) { + warnx("IOConnectCallScalarMethod failed"); + } else { + ok = true; + } + return ok; +} + +// ============================================================================= + +int +main(int argc, char *argv[]) +{ + io_service_t service; + io_connect_t connection; + + if (0 != getuid()) { + errx(1, "must be run as root (uid = %d)", getuid()); + } + + if (!connectClient(kAppleEffaceableStorageClassName, &service, &connection)) { + errx(1, "unable to connect to service"); + } + + // crude command parser...really only intended as test vehicle + if (1 >= argc) { + printUsage(argc, argv); + } else { + if (0 == strcmp("format", argv[1])) { + if (formatStorage(connection)) { + printf("format succeeded\n"); + } else { + printf("format failed\n"); + } + } else if (0 == strcmp("wipe", argv[1])) { + wipeStorage(connection); + } else if (0 == strcmp("test", argv[1])) { + quickTest(connection); + } else if (0 == strcmp("lockers", argv[1])) { + lockerList(connection); + } else if (0 == strcmp("nonce", argv[1])) { + generateNonce(connection); + } else if (2 >= argc) { + printUsage(argc, argv); + } else if (0 == strcmp("efface", argv[1])) { + lockerEfface(connection, argv[2]); + } else if (3 >= argc) { + printUsage(argc, argv); + } else if (0 == strcmp("set", argv[1])) { + lockerSet(connection, argv[2], argv[3]); + } else if (0 == strcmp("get", argv[1])) { + lockerGet(connection, argv[2], argv[3]); + } else { + printUsage(argc, argv); + errx(1, "unrecognized subcommand"); + } + } + + // XXX clean up service and connection + + return 0; +} + +void +printUsage(int argc, char *argv[]) +{ + printf("USAGE: %s \n\n", ((0 < argc) ? argv[0] : "?")); + printf(" Where is one of following\n\n"); + printf(" format - format storage\n"); + printf(" wipe - wipe storage\n"); + printf(" test - perform quick test\n"); + printf(" lockers - list lockers and contents\n"); + printf(" nonce - generate a nonce and report its SHA1 hash\n"); + printf(" set - write into locker \n"); + printf(" get - write from locker \n"); + printf("\n"); +} + +// ============================================================================= + +void +hexdump(const void * buf, IOByteCount count) +{ + int i, j; + for (i = 0; i < count; i += 16) { + printf("0x%08x:", ((unsigned) buf) + i); + for (j = 0; (j < 16) && ((i + j) < count); j++) { + printf(" %2.2x", ((uint8_t*)buf)[i+j]); + } + printf("\n"); + } +} + +void +quickTest(io_connect_t connection) +{ + const IOByteCount count = 64; + IOByteCount offset; + IOByteCount capacity; + void * sbuf = NULL; + void * gbuf = NULL; + unsigned i; + + if (!getCapacity(connection, &capacity)) { + errx(1, "unable to get capacity"); + } + printf("capacity reported as %u; expected 960\n", (unsigned) capacity); + + offset = capacity - count - 1; + sbuf = malloc(count); + gbuf = malloc(count); + + if ((NULL == sbuf) || (NULL == gbuf)) { + errx(1, "failed to allocate buffers"); + } + + if (!getBytes(connection, gbuf, offset, count)) { + errx(1, "unable to get bytes"); + } + printf("read %u bytes from %u offset\n", (unsigned) count, (unsigned) offset); + hexdump(gbuf, count); + + srandom(((unsigned *)gbuf)[0]); + for (i = 0; i < (count / sizeof(long)); i++) { + ((long *)sbuf)[i] = random(); + } + + if (!setBytes(connection, sbuf, offset, count)) { + errx(1, "unable to set bytes"); + } + printf("wrote %u bytes to %u offset\n", (unsigned) count, (unsigned) offset); + hexdump(sbuf, count); + + if (!getBytes(connection, gbuf, offset, count)) { + errx(1, "unable to get bytes"); + } + printf("read %u bytes from %u offset\n", (unsigned) count, (unsigned) offset); + hexdump(gbuf, count); + + if (0 != bcmp(sbuf, gbuf, count)) { + errx(1, "bytes read back differ from those written"); + } + printf("test passed\n"); + + if (NULL != sbuf) { + free(sbuf); + } + if (NULL != gbuf) { + free(gbuf); + } +} + +// ============================================================================= + +#define UNTAG(x) (int)(((x) >> 24) & 0xff),(int)(((x) >> 16) & 0xff),(int)(((x) >> 8) & 0xff),(int)((x) & 0xff) + +void +lockerList(io_connect_t connection) +{ + uint8_t *buf, *cursor; + IOByteCount size; + AppleEffaceableStorageLockerHeader *header; + + if (!getCapacity(connection, &size)) + errx(1, "unable to get capacity"); + if (size != kAppleEffaceableStorageLockerSize) + warnx("size %lu not %lu as expected", size, kAppleEffaceableStorageLockerSize); + buf = malloc(size); + + if (!getBytes(connection, buf, 0, size)) + errx(1, "unable to read"); + + cursor = buf; + for (;;) { + header = (AppleEffaceableStorageLockerHeader *)cursor; + if (header->magic != kAppleEffaceableStorageLockerMagic) { + warnx("unexpected magic 0x%04x at %u, expected 0x%04x", header->magic, cursor - buf, kAppleEffaceableStorageLockerMagic); + break; + } + if (header->type_id == kAppleEffaceableStorageLockerSentinel) { + printf("\n"); + break; + } + printf("0x%08x/0x%04x %c%c%c%c %s\n", + (unsigned)header->type_id, header->data_size, UNTAG(header->type_id), + (header->type_id & kAppleEffaceableStorageLockerProtected) ? "(protected)" : ""); + cursor += sizeof(*header); + if (header->data_size > 0) { + if ((cursor + header->data_size) > (buf + size)) { + warnx("data overflows buffer"); + break; + } + hexdump(cursor, header->data_size); + cursor += header->data_size; + } + if ((cursor + sizeof(*header)) > (buf + size)) { + warnx("header overflows buffer"); + break; + } + } + +} + +void +lockerGet(io_connect_t connection, char *tag, char *file) +{ + UInt32 tagVal; + UInt8 tagStr[4]; + UInt8 buf[1024]; + UInt64 input, output; + uint32_t output_count; + UInt32 output_size; + int fd; + + // get the tag + memset(tagStr, 0, 4); + strncpy((char *)tagStr, tag, 4); + tagVal = ((UInt32)tagStr[0] << 24) + ((UInt32)tagStr[1] << 16) + ((UInt32)tagStr[2] << 8) + (UInt32)tagStr[3]; + + // get the locker + input = tagVal; + output_count = 1; + output_size = sizeof(buf); + if (KERN_SUCCESS != IOConnectCallMethod(connection, // connection + kAppleEffaceableStorageMethodGetLocker, // selector + &input, // input + 1, // input count + NULL, // input struct + 0, // input struct size + &output, // output + &output_count, // output count + &buf, // output struct + &output_size)) { // output struct size + errx(1, "getLocker call failed"); + } + + // write the file + if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0) + err(1, "failed to create %s", file); + warnx("using descriptor %d", fd); + if (write(fd, buf, output_size) != output_size) + err(1, "failed writing %lu bytes to %s (fd %d)", output_size, file, fd); + close(fd); + + exit(0); +} + +void +lockerSet(io_connect_t connection, char *tag, char *file) +{ + UInt32 tagVal; + UInt8 tagStr[4]; + UInt8 buf[1024]; + UInt64 input; + int fd, size; + + // get the tag + memset(tagStr, 0, 4); + strncpy((char *)tagStr, tag, 4); + tagVal = ((UInt32)tagStr[0] << 24) + ((UInt32)tagStr[1] << 16) + ((UInt32)tagStr[2] << 8) + (UInt32)tagStr[3]; + + // read the file + if ((fd = open(file, O_RDONLY)) < 0) + err(1, "failed to open %s", file); + if ((size = read(fd, buf, sizeof(buf))) < 0) + err(1, "failed to read from %s", file); + close(fd); + + + // make the call + input = tagVal; + if (KERN_SUCCESS != IOConnectCallMethod(connection, + kAppleEffaceableStorageMethodSetLocker, + &input, + 1, + &buf, + size, + NULL, + 0, + NULL, + NULL)) { + errx(1, "setLocker call failed"); + } + + exit(0); +} + +void +lockerEfface(io_connect_t connection, char *tag) +{ + UInt32 tagVal; + UInt8 tagStr[4]; + UInt64 input; + + // get the tag + memset(tagStr, 0, 4); + strncpy((char *)tagStr, tag, 4); + tagVal = ((UInt32)tagStr[0] << 24) + ((UInt32)tagStr[1] << 16) + ((UInt32)tagStr[2] << 8) + (UInt32)tagStr[3]; + + // make the call + input = tagVal; + if (KERN_SUCCESS != IOConnectCallMethod(connection, + kAppleEffaceableStorageMethodEffaceLocker, + &input, + 1, + NULL, + 0, + NULL, + 0, + NULL, + NULL)) { + errx(1, "effaceLocker call failed"); + } + exit(0); +} + +void +generateNonce(io_connect_t connection) +{ + + UInt8 buf[SHA1_HASH_SIZE]; + UInt32 output_size = sizeof(buf); + UInt32 idx; + + memset(buf, 0, output_size); + if (KERN_SUCCESS != IOConnectCallMethod(connection, // connection + kAppleEffaceableStorageMethodGenerateNonce, // selector + NULL, // input + 0, // input count + NULL, // input struct + 0, // input struct size + NULL, // output + NULL, // output count + &buf, // output struct + &output_size)) { // output struct size + errx(1, "generateNonce call failed"); + } + + // report the nonce SHA1 hash + for (idx = 0; idx < output_size; idx++) { + printf("%s%02X", (idx ? " " : ""), buf[idx]); + } + printf("\n"); + + exit(0); +} diff --git a/lib/effaceable/ios/effaceable.h b/lib/effaceable/ios/effaceable.h new file mode 100644 index 0000000..60c0672 --- /dev/null +++ b/lib/effaceable/ios/effaceable.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _EFFACEABLE_H +#define _EFFACEABLE_H + +#include + +bool connectClient(const char * name, io_service_t * service, io_connect_t * connection); + +bool wipeStorage(io_connect_t connection); +bool getCapacity(io_connect_t connection, IOByteCount * capacity); +bool getBytes(io_connect_t connection, void * buf, IOByteCount offset, IOByteCount count); +bool setBytes(io_connect_t connection, const void * buf, IOByteCount offset, IOByteCount count); +bool isFormatted(io_connect_t connection, bool * is_formatted); +bool formatStorage(io_connect_t connection); + +int main(int argc, char * argv[]); +void printUsage(int argc, char *argv[]); + +void hexdump(const void * buf, IOByteCount count); +void quickTest(io_connect_t connection); +void lockerList(io_connect_t connection); +void lockerSet(io_connect_t connection, char *tag, char *file); +void lockerGet(io_connect_t connection, char *tag, char *file); +void lockerEfface(io_connect_t connection, char *tag); +void generateNonce(io_connect_t connection); + + +#endif /* _EFFACEABLE_H */ diff --git a/lib/env/env.c b/lib/env/env.c new file mode 100644 index 0000000..d66740d --- /dev/null +++ b/lib/env/env.c @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include + +static struct list_node env_list = LIST_INITIAL_VALUE(env_list); + +#define ENV_VAR_ENTRY_NAME_LEN 64 + +struct env_var_entry { + struct list_node node; + struct env_var var; + char name[ENV_VAR_ENTRY_NAME_LEN]; +}; + +static int str2ip(const char *str, uint32_t *ip); +static int str2mac(const char *str, uint8_t addr[6]); + +#define kIBootHiddenEnvDomain "com.apple.System." + +#if DEBUG_BUILD +static bool nvram_whitelist_override = false; +#else +static const bool nvram_whitelist_override = false; +#endif + +static bool hide_key(const char *str) +{ + if (0 == strncmp(str, kIBootHiddenEnvDomain, sizeof(kIBootHiddenEnvDomain)-1)) + return true; + else + return false; +} + +static struct env_var_entry *find_var_entry(const char *name) +{ + struct env_var_entry *entry; + + list_for_every_entry(&env_list, entry, struct env_var_entry, node) { + if (!strcmp(entry->name, name)) + return entry; + } + return NULL; +} + +const struct env_var *env_get_etc(const char *name) +{ + struct env_var_entry *entry; + + entry = find_var_entry(name); + if (!entry) + return NULL; + + if ((entry->var.flags & ENV_SHADOW) && !nvram_whitelist_override) { + dprintf(DEBUG_CRITICAL, "\x1b[1;5;31mBlocked read\x1b[m from shadowed variable \"%s\"\n", name); + dprintf(DEBUG_CRITICAL, "Disable NVRAM whitelist with DEBUG iBoot command envprot off\n"); + return NULL; + } + + return &entry->var; +} + +const char *env_get(const char *name) +{ + const struct env_var *var; + + var = env_get_etc(name); + if (!var) + return NULL; + + return var->str; +} + +size_t env_get_uint(const char *name, size_t default_val) +{ + const struct env_var *var; + + var = env_get_etc(name); + if (!var) + return default_val; + + return var->u; +} + +bool env_get_bool(const char *name, bool default_val) +{ + const struct env_var *var; + + var = env_get_etc(name); + if (NULL == var) + return default_val; + + if (!strcmp(var->str, "true")) + return true; + if (0 != var->u) + return true; + return false; +} + +static int str2ip(const char *str, uint32_t *ip) +{ + char numstr[16]; + int num; + int field = 0; + const char *ptr; + + if (str == NULL) + return -1; + + *ip = 0; + + ptr = str; + for (field = 0; field < 4; field++) { + char *dot = strchr(ptr, '.'); + + if (dot) { + strlcpy(numstr, ptr, __min((unsigned)(dot - ptr + 1), sizeof(numstr))); + } else { + strlcpy(numstr, ptr, sizeof(numstr)); + } + +// printf("numstr '%s'\n", numstr); + + num = strtol(numstr, NULL, 0); + if (num < 0 || num > 255) { + return -1; + } + *ip |= (num << (8 * field)); + + if (dot) + ptr = dot + 1; + else + break; + } + + return 0; +} + +int env_get_ipaddr(const char *name, uint32_t *ip) +{ + const char *env; + + env = env_get(name); + if (!env) + return -1; + + if (str2ip(env, ip) < 0) + return -1; + + return 0; +} + +static int str2mac(const char *str, uint8_t addr[6]) +{ + char numstr[16]; + int num; + int field = 0; + const char *ptr; + char *endptr; + + if (str == NULL) + return -1; + + addr[0] = addr[1] = addr[2] = addr[3] = addr[4] = addr[5] = 0; + + ptr = str; + for (field = 0; field < 6; field++) { + char *sep = strchr(ptr, ':'); + + if (sep) { + strlcpy(numstr, ptr, __min((unsigned)(sep - ptr + 1), sizeof(numstr))); + } else { + strlcpy(numstr, ptr, sizeof(numstr)); + } + +// printf("numstr '%s'\n", numstr); + + num = strtol(numstr, &endptr, 16); + if (endptr == numstr) { + dprintf(DEBUG_INFO, "malformed MAC address %s\n", str); + return -1; + } + if (num < 0 || num > 255) { + dprintf(DEBUG_INFO, "makformed MAC address %s\n", str); + return -1; + } + addr[field] = num; + + if (sep) + ptr = sep + 1; + else + break; + } + + return 0; +} + +int env_get_ethaddr(const char *name, uint8_t ethaddr[6]) +{ + const char *env; + + env = env_get(name); + if (!env) + return -1; + + if (str2mac(env, ethaddr) < 0) + return -1; + + return 0; +} + +int env_set(const char *name, const char *val, uint32_t flags) +{ + struct env_var_entry *entry; + + if (flags & ENV_PERSISTENT) { + if (env_blacklist_nvram(name)) + flags |= ENV_SHADOW; + } + + /* see if it already exists */ + entry = find_var_entry(name); + if (entry) { + if ((flags & ENV_SHADOW) && !(entry->var.flags & ENV_SHADOW) && !nvram_whitelist_override) { + dprintf(DEBUG_CRITICAL, "\x1b[1;5;31mBlocked shadowed write\x1b[m to variable \"%s\"\n", name); + dprintf(DEBUG_CRITICAL, "Disable NVRAM whitelist with DEBUG iBoot command envprot off\n"); + // If the variable exists, is not on the whitelist for NVRAM variables, + // and the value was generated internally (probably from the default environment), + // refuse to modify the existing value. + // This will result in the variable getting removed from nvram on saveenv, but + // protects us from people removing things from the default environment. + return -1; + } else { + // If the variable exists and either is on the whitelist or was not + // generated internally, delete the old value + env_unset(name); + } + } + + entry = malloc(sizeof(struct env_var_entry)); + + strlcpy(entry->name, name, sizeof(entry->name)); + + entry->var.str = strdup(val); + if (entry->var.str == NULL) { + free(entry); + return -1; + } + + entry->var.u = strtoul(entry->var.str, NULL, 0); + + /* save the flags */ + entry->var.flags = flags; + + list_add_tail(&env_list, &entry->node); + + return 0; +} + +int env_set_uint(const char *name, size_t val, uint32_t flags) +{ + char numbuf[(sizeof(size_t) * 2) + 3]; // plus '3' to store "0x" and null terminator + + snprintf(numbuf, sizeof(numbuf), "0x%lx", val); + + return env_set(name, numbuf, flags); +} + +int env_unset(const char *name) +{ + struct env_var_entry *entry; + + entry = find_var_entry(name); + if (!entry) + return 0; + + list_delete(&entry->node); + + free(entry->var.str); + free(entry); + + return 1; +} + +/* + * used by the nvram code to write the environment out to nvram. + * serialize all of the persistent environment variables with a simple + * =NULL... + * strategy. + */ +size_t env_serialize(uint8_t *buf, size_t buf_len) +{ + size_t offset; + struct env_var_entry *entry; + + offset = 0; + list_for_every_entry(&env_list, entry, struct env_var_entry, node) { + if (entry->var.flags & ENV_PERSISTENT) { + /* print one var into the buffer, avoiding overflow */ + offset += snprintf((void *)(buf + offset), buf_len - offset, "%s=%s", entry->name, entry->var.str) + 1; + + /* effectively require there to always be at least one free byte */ + if (offset >= buf_len) + return(0); + } + } + + return offset; +} + +/* opposite of the above */ +int env_unserialize(const uint8_t *buf, size_t buf_len) +{ + size_t offset; + +#if 0 + dprintf(DEBUG_SPEW, "serialized environment vars:\n"); + dhexdump(DEBUG_SPEW, buf, buf_len); +#endif + + offset = 0; + while (offset < buf_len) { + char envname[64]; + char envval[256]; + uint32_t var_start, var_end; + uint32_t val_start, val_end; + + if (buf[offset] == 0) { + offset++; + continue; + } + + /* find the start and end of the variable name */ + var_start = offset; + for (var_end = var_start; buf[var_end] != '=' && buf[var_end] != 0; var_end++) + ; + if (buf[var_end] == 0) // malformed variable, no '=' + break; + + /* find the start and end of the value component */ + val_start = var_end + 1; /* skip the '=' */ + for (val_end = val_start; buf[val_end] != 0; val_end++) + ; + + /* copy them out */ + strlcpy(envname, (const char *)&buf[var_start], __min(var_end - var_start + 1, sizeof(envname))); + strlcpy(envval, (const char *)&buf[val_start], __min(val_end - val_start + 1, sizeof(envval))); + + dprintf(DEBUG_SPEW, "'%s' = '%s'\n", envname, envval); + + /* load the environment */ + if (strlen(envname) > 0 && strlen(envval) > 0) { + uint32_t flags = ENV_PERSISTENT; + if (env_blacklist_nvram(envname)) + flags |= ENV_SHADOW; + env_set(envname, envval, flags); + } + + offset = val_end + 1; + } + + return 0; +} + +/* for unit testing testing purposes only, remove every environment + * variable + */ +void env_reset(void) +{ + struct env_var_entry *entry; + struct env_var_entry *temp; + + list_for_every_entry_safe(&env_list, entry, temp, struct env_var_entry, node) { + env_unset(entry->name); + } +} + + +/* command prompt routines */ +static void dump_var(const struct env_var_entry *entry) +{ + int i, binary = 0; + uint32_t flags; + + /* filter out non-ascii strings in variable values */ + for (i = 0; i < ENV_VAR_ENTRY_NAME_LEN; i++) { + if (entry->var.str[i] == 0) + break; + if (entry->var.str[i] < 0x20 || entry->var.str[i] > 0x7e) + binary = 1; + } + + flags = entry->var.flags; + printf("%c %s = %s%s%s\n", + (flags & ENV_SHADOW) ? 'S' : ((flags & ENV_PERSISTENT) ? 'P' : ' '), + entry->name, + binary ? "" : "\"", + binary ? "" : entry->var.str, + binary ? "" : "\""); +} + +int do_printenv(int argc, struct cmd_arg *args) +{ + struct env_var_entry *entry; + + if (argc >= 2) { + /* display a single variable */ + entry = find_var_entry(args[1].str); + if (entry) { + if (!hide_key(entry->name)) + dump_var(entry); + } else { + printf("variable %s not set\n", args[1].str); + } + } else { + /* display all variables */ + list_for_every_entry(&env_list, entry, struct env_var_entry, node) { + if (hide_key(entry->name)) continue; + dump_var(entry); + } + } + + return 0; +} + +int do_getenv(int argc, struct cmd_arg *args) +{ + struct env_var_entry *entry; + if(argc != 2) + { +#if !RELEASE_BUILD + printf("%s \n", args[0].str); +#endif + return -1; + } + + entry = find_var_entry(args[1].str); + if(!entry) + return -1; + if(hide_key(entry->name)) + return -1; + if(env_blacklist(entry->name, false)) + return -1; + return env_set("cmd-results", entry->var.str, 0); +} + +int do_setenv(int argc, struct cmd_arg *args) +{ + if (argc < 2) { +#if !RELEASE_BUILD + printf("not enough arguments.\n"); + printf("%s [] ...\n", args[0].str); +#endif + return -1; + } + + if (hide_key(args[1].str)) return -1; + + if (env_blacklist(args[1].str, true)) return -1; + + if (argc < 3) { + env_unset(args[1].str); + } else { + size_t buf_size = 512; + char *envbuf = malloc(buf_size); + int i; + + /* reassemble a string from all the command line args */ + envbuf[0] = 0; + for (i = 2; i < argc; i++) { + strlcat(envbuf, args[i].str, buf_size); + if (i != (argc - 1)) + strlcat(envbuf, " ", buf_size); + } + + env_set(args[1].str, envbuf, ENV_PERSISTENT); + + free(envbuf); + } + + return 0; +} + +int do_clearenv(int argc, struct cmd_arg *args) +{ + struct env_var_entry *entry, *pentry; + + if (argc < 2) { + printf("not enough arguments.\n"); + printf("Usage: It's a two step process. Run the following commands to clear\n"); + printf("\t\tclearenv \n"); + printf("\t\tclearenv 1 \t {confirms the clear}\n"); + printf("ex: clearenv auto-boot boot-args\n"); + printf(" clearenv 1\n"); + return -1; + } + + if (args[1].u == 0) { + printf("Clear pending. Run command \"clearenv 1\" to confirm\n"); + return -1; + } + + /* clear all persistent variables */ + while (1) { + pentry = 0; + list_for_every_entry(&env_list, entry, struct env_var_entry, node) { + if (hide_key(entry->name)) continue; + if (entry->var.flags & ENV_PERSISTENT) { + pentry = entry; + break; + } + } + + if (pentry == 0) break; + + env_unset(pentry->name); + } + + return 0; +} + +#if DEBUG_BUILD +int +do_envprot(int argc, struct cmd_arg *args) +{ + int result = 0; + + if (argc != 2) { + result = -1; + } else { + if (strcmp(args[1].str, "off") == 0) { + nvram_whitelist_override = true; + printf("Disabled NVRAM whitelist\n"); + } else if (strcmp(args[1].str, "on") == 0) { + nvram_whitelist_override = false; + printf("Enabled NVRAM whitelist\n"); + } else { + result = -1; + } + } + + if (result < 0) + printf("Usage: envprot {on | off}\n"); + + return result; +} +#endif diff --git a/lib/env/library.mk b/lib/env/library.mk new file mode 100644 index 0000000..b0f5315 --- /dev/null +++ b/lib/env/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBENV_DIR := $(GET_LOCAL_DIR) +LIBENV_BUILD := $(call TOLIBDIR,$(LIBENV_DIR)/LIBENV.a) +COMMONLIBS += LIBENV + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBENV_OBJS := $(LIBENV_DIR)/env.o + +LIBENV_OBJS := $(call TOLIBOBJDIR,$(LIBENV_OBJS)) + +ALL_DEPS += $(LIBENV_OBJS:%o=%d) + +$(LIBENV_BUILD): $(LIBENV_OBJS) + +endif diff --git a/lib/env/rules.mk b/lib/env/rules.mk new file mode 100644 index 0000000..aa4c811 --- /dev/null +++ b/lib/env/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_ENV=1 +LIBRARY_MODULES += lib/env diff --git a/lib/env/tests.c b/lib/env/tests.c new file mode 100644 index 0000000..f842dcf --- /dev/null +++ b/lib/env/tests.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include + +extern int do_printenv(int argc, void *); +extern void env_reset(void); + +/* Before each test case is called, empty out the environment */ +void test_env_suite_setup(void) +{ + env_reset(); +} + +void test_env(uintptr_t context) +{ + const uint8_t source[] = + "numvar=1234567890\0" + "truevar=true\0" + "falsevar=false\0" + "zerovar=0\0" + "strvar=hi mom 123=abc-_*\0" + "ethaddr=12:34:56:78:ab:cd\0" + "ipaddr=32.1.0.100\0" + "blacklisted=nocando\0" + "com.apple.System.hideme=hidden"; + uint8_t ethaddr[6]; + uint32_t ipaddr; + + TEST_ASSERT_EQ(env_unserialize(source, sizeof(source)), 0); + + // Test getting variables as strings + TEST_ASSERT_STR_EQ(env_get("numvar"), "1234567890"); + TEST_ASSERT_STR_EQ(env_get("truevar"), "true"); + TEST_ASSERT_STR_EQ(env_get("falsevar"), "false"); + TEST_ASSERT_STR_EQ(env_get("zerovar"), "0"); + TEST_ASSERT_STR_EQ(env_get("strvar"), "hi mom 123=abc-_*"); + TEST_ASSERT_STR_EQ(env_get("ethaddr"), "12:34:56:78:ab:cd"); + TEST_ASSERT_STR_EQ(env_get("ipaddr"), "32.1.0.100"); + TEST_ASSERT_STR_EQ(env_get("com.apple.System.hideme"), "hidden"); + + // Test getting variables as booleans + TEST_ASSERT_EQ(env_get_bool("truevar", false), true); + TEST_ASSERT_EQ(env_get_bool("truevar", true), true); + TEST_ASSERT_EQ(env_get_bool("falsevar", false), false); + TEST_ASSERT_EQ(env_get_bool("falsevar", true), false); + TEST_ASSERT_EQ(env_get_bool("zerovar", false), false); + TEST_ASSERT_EQ(env_get_bool("zerovar", true), false); + TEST_ASSERT_EQ(env_get_bool("numvar", false), true); + TEST_ASSERT_EQ(env_get_bool("numvar", true), true); + TEST_ASSERT_EQ(env_get_bool("strvar", false), false); + TEST_ASSERT_EQ(env_get_bool("strvar", true), false); + // Test default value for env_get_bool + TEST_ASSERT_EQ(env_get_bool("notavar", true), true); + TEST_ASSERT_EQ(env_get_bool("notavar", false), false); + + // Test getting variables as numbers + TEST_ASSERT_EQ(env_get_uint("numvar", 0), 1234567890ULL); + // Test default value for env_get_uint + TEST_ASSERT_EQ(env_get_uint("notavar", 123456), 123456); + + // Test getting variables as MAC addresses + TEST_ASSERT_EQ(env_get_ethaddr("ethaddr", ethaddr), 0); + TEST_ASSERT_MEM_EQ(ethaddr, TEST_ARRAY(uint8_t, 0x12, 0x34, 0x56, 0x78, 0xab, 0xcd), sizeof(ethaddr)); + // Test rejecting malformed MAC addresses + TEST_ASSERT_NEQ(env_get_ethaddr("strvar", ethaddr), 0); + TEST_ASSERT_NEQ(env_get_ethaddr("numvar", ethaddr), 0); + TEST_ASSERT_NEQ(env_get_ethaddr("notavar", ethaddr), 0); + + // Test getting variables as IP addresses + TEST_ASSERT_EQ(env_get_ipaddr("ipaddr", &ipaddr), 0); + TEST_ASSERT_EQ(ipaddr, 0x64000120); + + // Test getting a blacklisted variable fails + TEST_ASSERT_NULL(env_get("blacklisted")); + + // Test setting a non-persistent variable + TEST_ASSERT_EQ(env_set("temp", "don't save me", 0), 0); + TEST_ASSERT_STR_EQ(env_get("temp"), "don't save me"); + + // Test setting a persistent variable + TEST_ASSERT_EQ(env_set("persist", "save this var", ENV_PERSISTENT), 0); + TEST_ASSERT_STR_EQ(env_get("persist"), "save this var"); + + // Test env_set_uint + TEST_ASSERT_EQ(env_set_uint("uint", 0xabcd1234, 0), 0); + TEST_ASSERT_EQ(env_get_uint("uint", 0), 0xabcd1234); + + // Test overwriting a persistent variable + TEST_ASSERT_EQ(env_set("overwrite", "will not be saved", ENV_PERSISTENT), 0); + TEST_ASSERT_STR_EQ(env_get("overwrite"), "will not be saved"); + TEST_ASSERT_EQ(env_set("overwrite", "save this value", ENV_PERSISTENT), 0); + TEST_ASSERT_STR_EQ(env_get("overwrite"), "save this value"); + + // Test unsetting a value + TEST_ASSERT_EQ(env_set("unset", "about to unset", ENV_PERSISTENT), 0); + TEST_ASSERT_STR_EQ(env_get("unset"), "about to unset"); + TEST_ASSERT_EQ(env_unset("unset"), 1); + TEST_ASSERT_NULL(env_get("unset")); + // unsetting a non-existant variable should fail + TEST_ASSERT_EQ(env_unset("unset"), 0); + + // Test serializing - everything from the source should be serialized, + // plus persistent variables set with env_set + const uint8_t expected[] = + "numvar=1234567890\0" + "truevar=true\0" + "falsevar=false\0" + "zerovar=0\0" + "strvar=hi mom 123=abc-_*\0" + "ethaddr=12:34:56:78:ab:cd\0" + "ipaddr=32.1.0.100\0" + "blacklisted=nocando\0" + "com.apple.System.hideme=hidden\0" + "persist=save this var\0" + "overwrite=save this value"; + + uint8_t *serialized = malloc(sizeof(expected) * 2); + + TEST_ASSERT_EQ(env_serialize(serialized, sizeof(expected) * 2), sizeof(expected)); + TEST_ASSERT_MEM_EQ(serialized, expected, sizeof(expected)); + + memset(serialized, 0, sizeof(expected)); + TEST_ASSERT_EQ(env_serialize(serialized, sizeof(expected) + 1), sizeof(expected)); + TEST_ASSERT_MEM_EQ(serialized, expected, sizeof(expected)); + + // Too small buffer should fail serialization + TEST_ASSERT_EQ(env_serialize(serialized, sizeof(expected) - 1), 0); +} + +void test_env_max_len_var(uintptr_t context) +{ + int result; + size_t serialized_len; + const char *long_var = + "0001020304050607" + "08090a0b0c0d0e0f" + "1011121314151617" + "18191a1b1c1d1e1f" + "2021222324252627" + "28292a2b2c2d2e2f" + "3031323334353637" + "38393a3b3c3d3e3f" + "4041424344454647" + "48494a4b4c4d4e4f" + "5051525354555657" + "58595a5b5c5d5e5f" + "6061626364656667" + "68696a6b6c6d6e6f" + "7071727374757677" + "78797a7b7c7d7e_"; + + const uint8_t expected[] = + "testvar=" + "0001020304050607" + "08090a0b0c0d0e0f" + "1011121314151617" + "18191a1b1c1d1e1f" + "2021222324252627" + "28292a2b2c2d2e2f" + "3031323334353637" + "38393a3b3c3d3e3f" + "4041424344454647" + "48494a4b4c4d4e4f" + "5051525354555657" + "58595a5b5c5d5e5f" + "6061626364656667" + "68696a6b6c6d6e6f" + "7071727374757677" + "78797a7b7c7d7e_" + "\0testvar2=abc"; + + // Setting the variable should succeed + result = env_set("testvar", long_var, ENV_PERSISTENT); + TEST_ASSERT_EQ(result, 0); + + // Add a dummy variable after testvar for serialization test + result = env_set("testvar2", "abc", ENV_PERSISTENT); + TEST_ASSERT_EQ(result, 0); + + // The variable should read back correctly + TEST_ASSERT_STR_EQ(env_get("testvar"), long_var); + + // The variable should serialize correctly + uint8_t *serialized = malloc(sizeof(expected) * 2); + serialized_len = env_serialize(serialized, sizeof(expected) * 2); + TEST_ASSERT_EQ(serialized_len, sizeof(expected)); + TEST_ASSERT_MEM_EQ(serialized, expected, sizeof(expected)); + + // Clear out the environment to prepare for deserialization + env_reset(); + + // Make sure the environment really was cleared + TEST_ASSERT_NULL(env_get("testvar")); + TEST_ASSERT_NULL(env_get("testvar2")); + + // Now load the environment back in from the serialized buffer + result = env_unserialize(serialized, serialized_len); + TEST_ASSERT_EQ(result, 0); + + // And make sure everything came through OK + TEST_ASSERT_STR_EQ(env_get("testvar"), long_var); + TEST_ASSERT_STR_EQ(env_get("testvar2"), "abc"); +} + +bool env_blacklist(const char *name, bool write) +{ + if (strcmp(name, "set-blacklisted") == 0) + return true; + return false; +} + +bool env_blacklist_nvram(const char *name) +{ + if (strcmp(name, "blacklisted") == 0) + return true; + return false; +} + +static struct test_suite env_test_suite = { + .name = "env", + .description = "tests the environment module", + .setup_function = test_env_suite_setup, + .test_cases = { + { "env", test_env, 0 }, + { "env_max_len_var", test_env_max_len_var, 0 }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(env_test_suite); diff --git a/lib/env/tests.mk b/lib/env/tests.mk new file mode 100644 index 0000000..a8c56e9 --- /dev/null +++ b/lib/env/tests.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := env + +TEST_OBJS := \ + $(LOCAL_DIR)/env.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o diff --git a/lib/fs/debug.c b/lib/fs/debug.c new file mode 100644 index 0000000..d363179 --- /dev/null +++ b/lib/fs/debug.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2007-2009, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +int +fs_cat_file(const char *path) +{ + int filefd; + char buf[512]; + struct stat stat; + off_t resid, readsize; + int i; + + /* open the file */ + filefd = fs_open(path, 0); + if (filefd < 0) + return -1; + + /* stat it */ + fs_stat(filefd, &stat); + + resid = stat.st_size; + while (resid) { + readsize = sizeof(buf); + if (readsize > resid) + readsize = resid; + fs_read(filefd, (void *)buf, readsize); + for (i = 0; i < readsize; i++) + printf("%c", buf[i]); + resid -= readsize; + } + printf("\n"); + + fs_close(filefd); + return(0); +} + +void +fs_stat_dump(const struct stat *st) +{ + printf("STAT (%p):\n", (void *) st); + printf(" st_ino: %x\n", st->st_ino); + printf(" st_size %x\n", st->st_size); + printf(" st_blocks: %x\n", st->st_blocks); + printf(" st_flags: %x\n", st->st_flags); + printf(" st_type: "); + switch (st->st_type) { + case FILE_TYPE_FILE: + printf("FILE\n"); + break; + case FILE_TYPE_DIR: + printf("DIR\n"); + break; + default: + printf("UNKNOWN\n"); + } + + printf(" st_ctime: %x\n", st->st_ctime); + printf(" st_mtime: %x\n", st->st_mtime); + printf(" st_atime: %x\n", st->st_atime); +} + +void +fs_statfs_dump(const struct statfs *st) +{ + printf("STATFS (%p):\n", (void *) st); + printf(" f_bsize: %x\n", st->f_bsize); + printf(" f_blocks: %x\n", st->f_blocks); + printf(" f_bfree: %x\n", st->f_bfree); +} + +int fs_dump_dir(const char *dirpath, bool recurse) +{ + int dirfd; + struct dirent ent; + + printf("fs_dump_dir: dumping contents of directory '%s'\n", dirpath); + + dirfd = fs_opendir(dirpath); + if (dirfd < 0) { + printf("error opening dir '%s'\n", dirpath); + return -1; + } + + while (fs_readdir(dirfd, &ent) >= 0) { + printf("\tname '%s', size %d, type 0x%x\n", ent.d_name, ent.d_reclen, ent.d_type); + } + fs_closedir(dirfd); + + return 0; +} + +int do_fs(int argc, struct cmd_arg *args) +{ + int err; + size_t max_file_size; + + if (!security_allow_modes(kSecurityModeDebugCmd)) { + printf("Permission Denied\n"); + return -1; + } + + if (argc < 2) { +notenoughargs: + printf("not enough arguments.\n"); +usage: + printf("usage:\n"); + printf("%s mount \n", args[0].str); + printf("%s unmount \n", args[0].str); + printf("%s mounts\n", args[0].str); + printf("%s dir \n", args[0].str); + printf("%s load \n", args[0].str); + printf("%s cat \n", args[0].str); + + return 0; + } + + if (!strcmp(args[1].str, "mount")) { + if (argc < 5) + goto notenoughargs; + + err = fs_mount(args[3].str, args[2].str, args[4].str); + printf("mount returned %d\n", err); + } else if (!strcmp(args[1].str, "unmount")) { + if (argc < 3) + goto notenoughargs; + + fs_unmount(args[2].str); + } else if (!strcmp(args[1].str, "mounts")) { + fs_dump_mounts(); + } else if (!strcmp(args[1].str, "dir")) { + if (argc < 3) + goto notenoughargs; + + fs_dump_dir(args[2].str, false); + } else if (!strcmp(args[1].str, "load")) { + if (argc < 4) + goto notenoughargs; + + /* Allow file to be up to 32 MB. */ + max_file_size = 0x02000000; + if (!security_allow_memory((void *)args[3].u, max_file_size)) { + printf("Permission Denied\n"); + return -1; + } + + err = fs_load_file(args[2].str, args[3].u, &max_file_size); + printf("fs_load_file() returns %d\n", err); + if (err < 0) + return err; + + env_set_uint("loadaddr", args[3].u, 0); + env_set_uint("filesize", max_file_size, 0); + } else if (!strcmp(args[1].str, "cat")) { + if (argc < 3) + goto notenoughargs; + + err = fs_cat_file(args[2].str); + } else { + printf("unrecognized subcommand.\n"); + goto usage; + } + + return 0; +} + diff --git a/lib/fs/fs.c b/lib/fs/fs.c new file mode 100644 index 0000000..edb6798 --- /dev/null +++ b/lib/fs/fs.c @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef MAX_FDS +/** Maximum number of open files/directories */ +# define MAX_FDS 16 +#endif + +//#if WITH_HFS +extern const struct fs_ops hfs_fs_ops; +//#endif + +static const struct fs_struct fs_list[] = { +//#if WITH_HFS + { "hfs", &hfs_fs_ops }, +//#endif + { NULL, NULL } +}; + +struct fscookie { + const struct fs_struct *fs; + void *ctxt; +}; + +#define FILEMAGIC 'film' +#define DIRMAGIC 'dirm' + +struct filecookie { + struct list_node node; + struct fscookie *fscookie; + int fd; + void *ctxt; + bool is_dir; +}; + +struct fsmount { + struct list_node node; + struct fscookie *cookie; + size_t mountpoint_len; + char mountpoint[256]; +}; + +/** list of active mountpoints */ +static struct list_node mounts = LIST_INITIAL_VALUE(mounts); + +/** list of open files */ +static struct list_node files = LIST_INITIAL_VALUE(files); + +/** + * Given a file descriptor, obtain the corresponding filecookie. + * + * \param[in] handle The file descriptor to look up. + * + * \return Pointer to the corresponding filecookie structure. + * \retval NULL The file descriptor is not currently allocated. + */ +static struct filecookie *fhtocp(int handle) +{ + struct filecookie *file; + + list_for_every_entry(&files, file, struct filecookie, node) { + if (file->fd == handle) + return file; + } + return NULL; +} + +/** + * Find a valid, unused file descriptor. + * + * \return A file descriptor not currently in use. + * \retval -1 No file descriptors are available. + */ +static int getfd(void) +{ + int fd; + + for (fd = 0; fd < MAX_FDS; fd++) { + if (NULL == fhtocp(fd)) + return fd; + } + return -1; +} + +struct fsmount *path_to_mount(const char *path, const char **outpath) +{ + struct fsmount *mount; + + /* take a path and see if it lies on a mountpoint */ + list_for_every_entry(&mounts, mount, struct fsmount, node) { + if (!strncmp(path, mount->mountpoint, mount->mountpoint_len)) { + if (path[mount->mountpoint_len] == '/') { + /* the leading chars matched the mountpoint exactly and the next char was a / */ + *outpath = &path[mount->mountpoint_len]; +// printf("path_to_mount: path '%s, found mount %p, path '%s', outpath '%s'\n", +// path, mount, mount->mountpoint, *outpath); + return mount; + } + if (path[mount->mountpoint_len] == 0) { + /* the leading chars matched the mountpoint and there was no more string, + * return a / for the file system to chew on */ + *outpath = "/"; + return mount; + } + } + } + + return NULL; +} + +int fs_mount(const char *dev, const char *fs_name, const char *mountpoint) +{ + struct fscookie *cookie; + struct fsmount *mount; + const struct fs_struct *fs; + void *ctxt; + int err; + + ASSERT(dev); + ASSERT(fs_name); + + for (fs = fs_list; fs->name != NULL; fs++) { + if (!strcmp(fs_name, fs->name)) + break; + } + if (fs->name == NULL) { + dprintf(DEBUG_CRITICAL, "fs_mount: fs_name '%s' not in registered fs list\n", fs_name); + return -1; + } + + list_for_every_entry(&mounts, mount, struct fsmount, node) { + if (!strcmp(mountpoint, mount->mountpoint)) { + dprintf(DEBUG_CRITICAL, "fs_mount: mountpoint '%s' already occupied\n", mountpoint); + return -1; + } + } + + err = fs->ops->mount(&ctxt, dev); + if (err < 0) + return err; + + cookie = malloc(sizeof(struct fscookie)); + + cookie->fs = fs; + cookie->ctxt = ctxt; + + /* create a mount structure */ + mount = malloc(sizeof(struct fsmount)); + + mount->cookie = cookie; + strlcpy(mount->mountpoint, mountpoint, sizeof(mount->mountpoint)); + mount->mountpoint_len = strlen(mount->mountpoint); // used in path comparisons + + list_add_tail(&mounts, &mount->node); + + return 0; +} + +void fs_unmount(const char *dev) +{ + struct fsmount *mount; + const char *shortpath; + + ASSERT(dev); + + mount = path_to_mount(dev, &shortpath); + if (!mount) + return; + + ASSERT(mount->cookie != NULL); + + mount->cookie->fs->ops->unmount(mount->cookie->ctxt); + + /* remove the mount structure */ + list_delete(&mount->node); + free(mount->cookie); + free(mount); +} + +int fs_fsstat(void *fscookie, struct statfs *stat) +{ + struct fscookie *cookie = (struct fscookie *)fscookie; + + ASSERT(cookie); + ASSERT(stat); + + return cookie->fs->ops->fsstat(cookie->ctxt, stat); +} + +int fs_open(const char *path, uint8_t flags) +{ + struct fsmount *mount; + void *ctxt; + struct filecookie *fcookie; + const char *shortpath; + int fd; + + ASSERT(path); + + mount = path_to_mount(path, &shortpath); + if (!mount) + return -1; + + if (-1 == (fd = getfd())) + return -1; + + ctxt = mount->cookie->fs->ops->open(mount->cookie->ctxt, shortpath, flags); + if (!ctxt) + return -1; + + fcookie = malloc(sizeof(struct filecookie)); + + fcookie->fscookie = mount->cookie; + fcookie->ctxt = ctxt; + fcookie->is_dir = false; + fcookie->fd = fd; + + list_add_head(&files, &fcookie->node); + + return fcookie->fd; +} + +int fs_read(int handle, void *buf, size_t len) +{ + struct filecookie *fcookie = fhtocp(handle); + + ASSERT(fcookie); + ASSERT(!fcookie->is_dir); + + return fcookie->fscookie->fs->ops->read(fcookie->ctxt, buf, len); +} + +int fs_stat(int handle, struct stat *st) +{ + struct filecookie *fcookie = fhtocp(handle); + + ASSERT(fcookie); + ASSERT(!fcookie->is_dir); + + return fcookie->fscookie->fs->ops->fstat(fcookie->ctxt, st); +} + +off_t fs_seek(int handle, off_t offset, int whence) +{ + struct filecookie *fcookie = fhtocp(handle); + + ASSERT(fcookie); + ASSERT(!fcookie->is_dir); + + return fcookie->fscookie->fs->ops->seek(fcookie->ctxt, offset, whence); +} + +int fs_close(int handle) +{ + struct filecookie *fcookie = fhtocp(handle); + + ASSERT(fcookie); + ASSERT(!fcookie->is_dir); + ASSERT(fcookie->fscookie != NULL); + ASSERT(fcookie->fscookie->fs != NULL); + ASSERT(fcookie->fscookie->fs->ops != NULL); + ASSERT(fcookie->fscookie->fs->ops->close != NULL); + + fcookie->fscookie->fs->ops->close(fcookie->ctxt); + + list_delete(&fcookie->node); + free(fcookie); + + return 0; +} + +int fs_opendir(const char *path) +{ + struct fsmount *mount; + void *ctxt; + struct filecookie *fcookie; + const char *shortpath; + int fd; + + mount = path_to_mount(path, &shortpath); + if (!mount) + return -1; + + if (-1 == (fd = getfd())) + return -1; + + ctxt = mount->cookie->fs->ops->opendir(mount->cookie->ctxt, shortpath); + if (!ctxt) + return -1; + + fcookie = malloc(sizeof(struct filecookie)); + + fcookie->fscookie = mount->cookie; + fcookie->ctxt = ctxt; + fcookie->is_dir = true; + fcookie->fd = fd; + + list_add_head(&files, &fcookie->node); + + return fcookie->fd; +} + +int fs_readdir(int handle, struct dirent *ent) +{ + struct filecookie *fcookie = fhtocp(handle); + + RELEASE_ASSERT(fcookie); + RELEASE_ASSERT(fcookie->is_dir); + + return fcookie->fscookie->fs->ops->readdir(fcookie->ctxt, ent); +} + +int fs_rewinddir(int handle) +{ + struct filecookie *fcookie = fhtocp(handle); + + RELEASE_ASSERT(fcookie); + RELEASE_ASSERT(fcookie->is_dir); + + fcookie->fscookie->fs->ops->rewinddir(fcookie->ctxt); + + return 0; +} + +int fs_closedir(int handle) +{ + struct filecookie *fcookie = fhtocp(handle); + + RELEASE_ASSERT(fcookie); + RELEASE_ASSERT(fcookie->is_dir); + + fcookie->fscookie->fs->ops->closedir(fcookie->ctxt); + + list_delete(&fcookie->node); + free(fcookie); + + return 0; +} + +int fs_load_file(const char *path, addr_t addr, size_t *maxsize) +{ + int filefd; + int result; + struct stat stat; + + RELEASE_ASSERT(maxsize != NULL); + + /* open the file */ + filefd = fs_open(path, 0); + if (filefd < 0) { + platform_record_breadcrumb("fs_load_file", "fs_open_failed"); + return -1; + } + + /* stat it */ + fs_stat(filefd, &stat); + + /* make sure it is not too large */ + if (*maxsize < stat.st_size) { + platform_record_breadcrumb("fs_load_file", "maxsize_exceeded"); + return -1; + } + + if (!security_allow_memory((void *)addr, stat.st_size)) { + platform_record_breadcrumb("fs_load_file", "permission_denied"); + printf("Permission Denied\n"); + return -1; + } + + /* read the entire thing in */ + result = fs_read(filefd, (void *)addr, stat.st_size); + fs_close(filefd); + + if (result < 0 || (unsigned)result != stat.st_size) { + platform_record_breadcrumb("fs_load_file", "read_failed"); + // Zero the buffer in case of a partial read + memset((void *)addr, *maxsize, 0); + + return -1; + } + + *maxsize = stat.st_size; + + return 0; +} + +void fs_dump_mounts(void) +{ + struct fsmount *mount; + + printf("active fs mounts:\n"); + list_for_every_entry(&mounts, mount, struct fsmount, node) { + printf("\t'%s'\n", mount->mountpoint); + } +} + +const char *fs_get_fsname(const int index) +{ + int i; + + for (i = 0; i < index; i++) + if (fs_list[i].name == NULL) + return(NULL); + return(fs_list[i].name); +} diff --git a/lib/fs/hfs/cache.c b/lib/fs/hfs/cache.c new file mode 100644 index 0000000..484df3f --- /dev/null +++ b/lib/fs/hfs/cache.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * cache.c - A simple cache for file systems meta-data. + * + * Copyright (c) 2000 - 2003 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ + +#include +#include +#include +#include +#include + +#include "hfs.h" + +struct CacheEntry { + CICell ih; + time_t time; + off_t offset; +}; +typedef struct CacheEntry CacheEntry; + +#define kCacheSize (kFSCacheSize) +#define kCacheMinBlockSize (0x200) +#define kCacheMaxBlockSize (0x4000) +#define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize) + +static CICell gCacheIH; +static uint32_t gCacheBlockSize; +static uint32_t gCacheNumEntries; +static time_t gCacheTime; +static CacheEntry gCacheEntries[kCacheMaxEntries]; +static uint8_t *gCacheBuffer; + +uint32_t gCacheHits; +uint32_t gCacheMisses; +uint32_t gCacheEvicts; + +void CacheInit(CICell ih, uint32_t blockSize) +{ + if ((blockSize < kCacheMinBlockSize) || + (blockSize >= kCacheMaxBlockSize)) + return; + + if (gCacheBuffer) + free(gCacheBuffer); + posix_memalign((void **)&gCacheBuffer, blockSize, kFSCacheSize); + + gCacheBlockSize = blockSize; + gCacheNumEntries = kCacheSize / gCacheBlockSize; + gCacheTime = 0; + + gCacheHits = 0; + gCacheMisses = 0; + gCacheEvicts = 0; + + bzero(gCacheEntries, sizeof(gCacheEntries)); + + gCacheIH = ih; +} + + +uint32_t CacheRead(CICell ih, uint8_t *buffer, off_t offset, + uint32_t length, bool cache) +{ + uint32_t cnt, oldestEntry = 0, loadCache = 0; + uint32_t result; + CacheEntry *entry; + time_t oldestTime; + + // See if the data can be cached. + if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) { + // Look for the data in the cache. + for (cnt = 0; cnt < gCacheNumEntries; cnt++) { + entry = &gCacheEntries[cnt]; + if ((entry->ih == ih) && (entry->offset == offset)) { + entry->time = ++gCacheTime; + break; + } + } + + // If the data was found copy it to the caller. + if (cnt != gCacheNumEntries) { + memcpy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize); + gCacheHits++; + return gCacheBlockSize; + } + + // Could not find the data in the cache. + loadCache = 1; + } + + // Read the data from the disk. + // CacheRead (in HFS) should return actual amount read + result = (uint32_t) HFSBlockRead(ih, (CICell)buffer, offset, length); + if (cache) gCacheMisses++; + + // Put the data from the disk in the cache if needed and if read completed + // successfully + if (loadCache && (result == length)) { + // Find a free entry. + oldestTime = gCacheTime; + for (cnt = 0; cnt < gCacheNumEntries; cnt++) { + entry = &gCacheEntries[cnt]; + + // Found a free entry. + if (entry->ih == 0) break; + + if (entry->time < oldestTime) { + oldestTime = entry->time; + oldestEntry = cnt; + } + } + + // If no free entry was found, use the oldest. + if (cnt == gCacheNumEntries) { + cnt = oldestEntry; + gCacheEvicts++; + } + + // Copy the data from disk to the new entry. + entry = &gCacheEntries[cnt]; + entry->ih = ih; + entry->time = ++gCacheTime; + entry->offset = offset; + memcpy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize); + } + + return result; +} diff --git a/lib/fs/hfs/fuzz.c b/lib/fs/hfs/fuzz.c new file mode 100644 index 0000000..1ed1321 --- /dev/null +++ b/lib/fs/hfs/fuzz.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include + +struct blockdev *create_mock_blockdev(const char *name, const char *filename, uint32_t block_size); + +void walk(const char *dirpath) +{ + int dirfd; + struct dirent ent; + int result; + + dirfd = fs_opendir(dirpath); + if (dirfd < 0) { + printf("error opening dir '%s'\n", dirpath); + return; + } + + while ((result = fs_readdir(dirfd, &ent)) >= 0) { + size_t subpath_size = strlen(dirpath) + 1 + strlen(ent.d_name) + 1; + char *subpath = malloc(subpath_size); + snprintf(subpath, subpath_size, "%s/%s", dirpath, ent.d_name); + if (ent.d_type == FILE_TYPE_FILE) { + int fd; + printf("%s\n", subpath); + + fd = fs_open(subpath, 0); + if (fd >= 0) { + void *buffer; + struct stat st; + if (fs_stat(fd, &st) >= 0) { + unsigned size = st.st_size; + if (size > 1000000) + size = 1000000; + buffer = malloc(size); + if (fs_read(fd, buffer, size) < 0) { + printf("error reading file '%s'\n", subpath); + } + free(buffer); + } else { + printf("error statting file '%s'\n", subpath); + } + } else { + printf("error opening file '%s'\n", subpath); + } + } else if (ent.d_type == FILE_TYPE_DIR) { + printf("%s/\n", subpath); + walk(subpath); + } + + free(subpath); + } + fs_closedir(dirfd); +} + +int fuzz_main(const char *filename) +{ + struct blockdev *bdev; + int result; + + bdev = create_mock_blockdev("dev", filename, 4096); + register_blockdev(bdev); + + result = fs_mount("dev", "hfs", "/boot"); + + if (result == 0) { + printf("Mount succeeded\n"); + walk("/boot"); + } + + return 0; +} + +// Mock +bool +env_blacklist(const char *name, bool write) +{ + return false; +} + +// Mock +bool +env_blacklist_nvram(const char *name) +{ + return false; +} diff --git a/lib/fs/hfs/hfs.c b/lib/fs/hfs/hfs.c new file mode 100644 index 0000000..1780d05 --- /dev/null +++ b/lib/fs/hfs/hfs.c @@ -0,0 +1,1372 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * hfs.c - File System Module for HFS and HFS+. + * + * Copyright (c) 1999-2004 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ + +#include +#include +#include +#include +#include +#include +#include +#include "hfs.h" +#include "hfs_format.h" + +#define HFS_MAXPATHLEN (512) +#define HFS_MAXNAMLEN (255) + +#define kBlockSize (0x200) +#define kBlockSizeMax (0x10000) + +#define kMDBBaseOffset (2 * kBlockSize) + +#define kBTreeCatalog (0) +#define kBTreeExtents (1) +#define kBTreeSize (256) +#define kDirLevelMax (48) + +static CICell gCurrentIH; +static off_t gAllocationOffset; +static bool gIsHFSPlus; +static uint32_t gBlockSize; +static uint8_t gBTreeHeaderBuffer[HFS_MAXPATHLEN]; +static BTHeaderRec *gBTHeaders[2]; +static uint8_t gHFSPlusHeader[kBlockSize]; +static HFSPlusVolumeHeader *gHFSPlus =(HFSPlusVolumeHeader*)gHFSPlusHeader; +static uint64_t gVolID; +static char gTempStr[kBTreeSize]; + +static int ReadFile(void *file, size_t *length, void *base, off_t offset); +static int GetCatalogEntryInfo(void *entry, uint32_t *flags, time_t *time, off_t *size); +static int ResolvePathToCatalogEntry(const char *filePath, uint32_t *flags, void *entry, uint32_t dirID, off_t *dirIndex, time_t *time, off_t *size); + +static int GetCatalogEntry(off_t *dirIndex, char *name, size_t nameSize, uint32_t *flags, time_t *time, off_t *size); +static int ReadCatalogEntry(const char *fileName, uint32_t dirID, void *entry, off_t *dirIndex); +static int ReadExtentsEntry(uint32_t fileID, uint32_t startBlock, void *entry); + +static int ReadBTreeEntry(uint32_t btree, void *key, uint8_t *entry, off_t *dirIndex); +static int GetBTreeRecord(uint32_t index, uint8_t *nodeBuffer, uint32_t nodeSize, uint8_t **key, uint8_t **data); + +static int ReadExtent(uint8_t *extent, uint32_t extentSize, uint32_t extentFile, off_t offset, uint32_t size, void *buffer, bool cache); + +static uint32_t GetExtentStart(void *extents, uint32_t index); +static uint32_t GetExtentSize(void *extents, uint32_t index); + +static int CompareHFSPlusCatalogKeys(void *key, void *testKey); +static int CompareHFSPlusExtentsKeys(void *key, void *testKey); + +static int32_t BinaryUnicodeCompare (uint16_t * str1, uint32_t length1, uint16_t * str2, uint32_t length2); +static int utf_encodestr(const uint16_t *ucsp, unsigned ucslen, uint8_t *utf8p, size_t bufsize); +static void utf_decodestr(const char *utf8p, uint16_t *ucsp, uint16_t *ucslen, uint32_t bufsize); +static void utf_decodestr255(const char *utf8p, struct HFSUniStr255 *ucsstrp); + + +#if 0 +# define HFSdebug(fmt, args...) printf("%s: " fmt "\n", __FUNCTION__ , ##args) +static inline void +DPrintUTF(uint16_t *ucsp, int length) +{ + while (length--) + printf("%c", (*(ucsp++) & 0xff00) >> 8); +} +#else +# define HFSdebug(fmt, args...) do { } while(0) +# define DPrintUTF(s, l) do { } while(0) +#endif + +static bool +isPowerOf2(uint32_t x) +{ + return ((x & (x-1)) == 0); +} + + +// Sanity-checks some values in the HFS+ header +static bool +ValidateHFSPlusHeader(void) +{ + bool valid = true; + uint32_t blockSize = HFSntohl(&gHFSPlus->blockSize); + + // check signature field + if ((HFSntohs(&gHFSPlus->signature) != kHFSPlusSigWord) && (HFSntohs(&gHFSPlus->signature) != kHFSXSigWord)) { + dprintf(DEBUG_CRITICAL, "Not HFS+ (signature 0x%04x)\n", HFSntohs(&gHFSPlus->signature)); + valid = false; + goto exit; + } + + // check blockSize field + if ((blockSize < kBlockSize) || (blockSize > kBlockSizeMax) || (!isPowerOf2(blockSize))) { + dprintf(DEBUG_CRITICAL, "Bad HFS+ blockSize(0x%08x, 0x%x, 0x%x)\n", blockSize, kBlockSize, kBlockSizeMax); + valid = false; + goto exit; + } + +exit: + return valid; +} + + +static int +SanityCheckBTreeHeader(BTHeaderRec *hdr, off_t fileSize) +{ + uint16_t nodeSize = HFSntohs(&hdr->nodeSize); + + if (!isPowerOf2(nodeSize)) { + HFSdebug("BTree node size is %d, which is not a power of 2\n", nodeSize); + return -1; + } + + if (nodeSize < 512) { + HFSdebug("BTree node size is %d, minimum is 512\n", nodeSize); + return -1; + } + if ((fileSize / nodeSize) != HFSntohl(&hdr->totalNodes)) { + HFSdebug("BTree file size indicates %u nodes, header indicates %u\n", (uint32_t)(fileSize / nodeSize), HFSntohl(&hdr->totalNodes)); + return -1; + } + return 0; +} + +int +HFSInitPartition(CICell ih) +{ + uint32_t extentSize, extentFile, nodeSize, btree; + uint32_t result; + void *extent; + + if (ih == gCurrentIH) + return 0; + dprintf(DEBUG_INFO, "HFSInitPartition: %p\n", ih); + + gAllocationOffset = 0; + gIsHFSPlus = 0; + gBTHeaders[0] = 0; + gBTHeaders[1] = 0; + + // Look for the HFSPlus Header + result = HFSBlockRead(ih, gHFSPlusHeader, gAllocationOffset + kMDBBaseOffset, kBlockSize); + if (result != kBlockSize) { + HFSdebug("Error reading HFS+ header"); + return -1; + } + + // Verify contents of header before continuing + if (!ValidateHFSPlusHeader()) { + gCurrentIH = NULL; + return -1; + } + + gIsHFSPlus = 1; + gBlockSize = HFSntohl(&gHFSPlus->blockSize); + HFSdebug("allocation block size %x", gBlockSize); + if (gBlockSize == 0) { + HFSdebug("Volume block size cannot be zero!"); + return -1; + } + + if (HFSntohl(&gHFSPlus->totalBlocks) == 0) { + HFSdebug("Volume totalBlocks cannot be zero!"); + return -1; + } + + CacheInit(ih, gBlockSize); + gCurrentIH = ih; + + // grab the 64 bit volume ID + memcpy(&gVolID, &gHFSPlus->finderInfo[24], 8); + + // Get the Catalog BTree header + btree = kBTreeCatalog; + extent = &gHFSPlus->catalogFile.extents; + extentSize = HFSntohll(&gHFSPlus->catalogFile.logicalSize); + if (extentSize < 512) { + HFSdebug("Catalog btree file is too short, %lld\n", (off_t)extentSize); + return -1; + } + extentFile = kHFSCatalogFileID; + HFSdebug("reading catalog Btree, extent %p extentSize %x, extentFile %d", extent, extentSize, extentFile); + if (ReadExtent(extent, extentSize, extentFile, 0, kBTreeSize, gBTreeHeaderBuffer + btree * kBTreeSize, 0) != kBTreeSize) { + HFSdebug("Cannot read catalog file header node"); + return -1; + } + gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * kBTreeSize + /*sizeof(BTNodeDescriptor)*/ 14); + + HFSdebug("Catalog BTree header: %p", gBTHeaders[btree]); + HFSdebug(" maximum height (usually leaf nodes) %x", HFSntohs(&gBTHeaders[btree]->treeDepth)); + HFSdebug(" node number of root node %x", HFSntohl(&gBTHeaders[btree]->rootNode)); + HFSdebug(" number of leaf records in all leaf nodes %x", HFSntohl(&gBTHeaders[btree]->leafRecords)); + HFSdebug(" node number of first leaf node %x", HFSntohl(&gBTHeaders[btree]->firstLeafNode)); + HFSdebug(" node number of last leaf node %x", HFSntohl(&gBTHeaders[btree]->lastLeafNode)); + HFSdebug(" size of a node, in bytes %x", HFSntohs(&gBTHeaders[btree]->nodeSize)); + HFSdebug(" total number of nodes in tree %x", HFSntohl(&gBTHeaders[btree]->totalNodes)); + HFSdebug(" number of unused (free) nodes in tree %x", HFSntohl(&gBTHeaders[btree]->freeNodes)); + HFSdebug(" Key string Comparison Type %x", gBTHeaders[btree]->keyCompareType); + HFSdebug(" persistent attributes about the tree %x", HFSntohl(&gBTHeaders[btree]->attributes)); + if (SanityCheckBTreeHeader(gBTHeaders[btree], extentSize) == -1) { + return -1; + } + // Get the Extents BTree header + btree = kBTreeExtents; + extent = &gHFSPlus->extentsFile.extents; + extentSize = HFSntohll(&gHFSPlus->extentsFile.logicalSize); + if (extentSize < 512) { + HFSdebug("Extents overflow btree file is too short, %lld\n", (off_t)extentSize); + return -1; + } + extentFile = kHFSExtentsFileID; + if (ReadExtent(extent, extentSize, extentFile, 0, kBTreeSize, gBTreeHeaderBuffer + btree * kBTreeSize, 0) != kBTreeSize) { + HFSdebug("Cannot read extents overflow file header node"); + return -1; + } + gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * kBTreeSize + /*sizeof(BTNodeDescriptor)*/ 14); + + HFSdebug("Extents BTree header:"); + HFSdebug(" maximum height (usually leaf nodes) %x", HFSntohs(&gBTHeaders[btree]->treeDepth)); + HFSdebug(" node number of root node %x", HFSntohl(&gBTHeaders[btree]->rootNode)); + HFSdebug(" number of leaf records in all leaf nodes %x", HFSntohl(&gBTHeaders[btree]->leafRecords)); + HFSdebug(" node number of first leaf node %x", HFSntohl(&gBTHeaders[btree]->firstLeafNode)); + HFSdebug(" node number of last leaf node %x", HFSntohl(&gBTHeaders[btree]->lastLeafNode)); + HFSdebug(" size of a node, in bytes %x", HFSntohs(&gBTHeaders[btree]->nodeSize)); + HFSdebug(" total number of nodes in tree %x", HFSntohl(&gBTHeaders[btree]->totalNodes)); + HFSdebug(" number of unused (free) nodes in tree %x", HFSntohl(&gBTHeaders[btree]->freeNodes)); + HFSdebug(" Key string Comparison Type %x", gBTHeaders[btree]->keyCompareType); + HFSdebug(" persistent attributes about the tree %x", HFSntohl(&gBTHeaders[btree]->attributes)); + if (SanityCheckBTreeHeader(gBTHeaders[btree], extentSize) == -1) { + return -1; + } + + // If the BTree node size is larger than the block size, reset the cache. + nodeSize = HFSntohs(&gBTHeaders[btree]->nodeSize); + if (nodeSize > gBlockSize) + CacheInit(ih, nodeSize); + + return 0; +} + + +int +HFSDetect(void) +{ + + if (gCurrentIH == NULL) { + dprintf(DEBUG_CRITICAL, "No current device\n"); + return 1; + } + dprintf(DEBUG_INFO, "Filesystem: HFS+\n signature 0x%04x version 0x%04x\n", HFSntohs(&gHFSPlus->signature), HFSntohs(&gHFSPlus->version)); + dprintf(DEBUG_INFO, " allocation block size %d bytes\n total block count %d\n volume size %d Mbytes\n", + HFSntohl(&gHFSPlus->blockSize), HFSntohl(&gHFSPlus->totalBlocks), + (int)((long long)HFSntohl(&gHFSPlus->blockSize) * HFSntohl(&gHFSPlus->totalBlocks) / (1024 * 1024))); + dprintf(DEBUG_INFO, " %d files\n %d folders\n", HFSntohl(&gHFSPlus->fileCount), HFSntohl(&gHFSPlus->folderCount)); + dprintf(DEBUG_INFO, " created 0x%08x\n modified 0x%08x\n backed up 0x%08x\n checked 0x%08x\n", + HFSntohl(&gHFSPlus->createDate), HFSntohl(&gHFSPlus->modifyDate), + HFSntohl(&gHFSPlus->backupDate), HFSntohl(&gHFSPlus->checkedDate)); + + dprintf(DEBUG_INFO, " Allocation file\n"); + dprintf(DEBUG_INFO, " logical size %d clumpSize %d totalBlocks %d\n", + (int)HFSntohll(&gHFSPlus->allocationFile.logicalSize), + HFSntohl(&gHFSPlus->allocationFile.clumpSize), + HFSntohl(&gHFSPlus->allocationFile.totalBlocks)); + dprintf(DEBUG_INFO, " Extents file\n"); + dprintf(DEBUG_INFO, " logical size %d clumpSize %d totalBlocks %d\n", + (int)HFSntohll(&gHFSPlus->extentsFile.logicalSize), + HFSntohl(&gHFSPlus->extentsFile.clumpSize), + HFSntohl(&gHFSPlus->extentsFile.totalBlocks)); + dprintf(DEBUG_INFO, " Catalog file\n"); + dprintf(DEBUG_INFO, " logical size %d clumpSize %d totalBlocks %d\n", + (int)HFSntohll(&gHFSPlus->catalogFile.logicalSize), + HFSntohl(&gHFSPlus->catalogFile.clumpSize), + HFSntohl(&gHFSPlus->catalogFile.totalBlocks)); + dprintf(DEBUG_INFO, " Attributes file\n"); + dprintf(DEBUG_INFO, " logical size %d clumpSize %d totalBlocks %d\n", + (int)HFSntohll(&gHFSPlus->attributesFile.logicalSize), + HFSntohl(&gHFSPlus->attributesFile.clumpSize), + HFSntohl(&gHFSPlus->attributesFile.totalBlocks)); + + return 0; +} + + +int +HFSGetFileInfo(CICell ih, const char *filePath, uint32_t *flags, time_t *time, off_t *size) +{ + char *entry; + uint32_t dirID; + int result; + + HFSdebug("fs %p path %s", ih, filePath); + + entry = (char *)malloc(HFS_MAXPATHLEN); + dirID = kHFSRootFolderID; + + result = ResolvePathToCatalogEntry(filePath, flags, entry, dirID, 0, time, size); + + free(entry); + return result; +} + +int +HFSReadFile(CICell ih, const char *filePath, void *base, off_t offset, size_t length) +{ + char *entry; + uint32_t dirID, flags; + int result; + + entry = (char *)malloc(HFS_MAXPATHLEN); + + dirID = kHFSRootFolderID; + + result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0, NULL, NULL); + if (result != 0) { + dprintf(DEBUG_CRITICAL, "Could not find '%s'\n", filePath); + goto exit; + } + if ((flags & kFileTypeMask) != kFileTypeFlat) { + dprintf(DEBUG_CRITICAL, "'%s' is not a file\n", filePath); + result = -1; + goto exit; + } + + result = ReadFile(entry, &length, base, offset); + if (result == 0) + result = length; + +exit: + HFSdebug("returning %d\n", result); + free(entry); + return result; +} + +int +HFSGetDirEntry(CICell ih, const char *dirPath, off_t *dirIndex, char *name, size_t nameSize, uint32_t *flags, time_t *time, off_t *size) +{ + char *entry; + uint32_t dirID, dirFlags; + int ret = 0; + + if (*dirIndex == -1) + return -1; + + entry = (char *)malloc(HFS_MAXPATHLEN); + dirID = kHFSRootFolderID; + + if (*dirIndex == 0) { + ret = ResolvePathToCatalogEntry(dirPath, &dirFlags, entry, dirID, dirIndex, NULL, NULL); + if (ret != 0) { + ret = -1; + goto exit; + } + + if (*dirIndex == 0) + *dirIndex = -1; + /* if what we looked up didn't give us the header entry for the directory, bail */ + if ((dirFlags & kFileTypeMask) != kFileTypeUnknown) { + dprintf(DEBUG_CRITICAL, "not a directory: '%s' flags %x\n", dirPath, dirFlags); + ret = -1; + goto exit; + } + } + + if (GetCatalogEntry(dirIndex, name, nameSize, flags, time, size) != 0) { + ret = -1; + goto exit; + } + + /* end of the catalog or end of the directory */ + if ((*dirIndex == 0) || ((*flags & kFileTypeMask) == kFileTypeUnknown)) + *dirIndex = -1; + +exit: + free(entry); + return ret; +} + +struct HFSPlusVolumeHeader * +HFSGetVolumeHeader(void) +{ + return(gHFSPlus); +} + +// Private Functions + +static int +ReadFile(void *file, size_t *length_inout, void *base, off_t offset) +{ + size_t length; + void *extents; + uint32_t fileID, fileLength; + HFSPlusCatalogFile *hfsPlusFile = file; + int rv; + + fileID = HFSntohl(&hfsPlusFile->fileID); + fileLength = HFSntohll(&hfsPlusFile->dataFork.logicalSize); + extents = &hfsPlusFile->dataFork.extents; + + length = *length_inout; + + // nothing to do if we're asked to read 0 bytes + if (length == 0) { + return 0; + } + + // Our parameter is a size_t, but the rest of the library treats + // lengths as uint32_t + if (length > UINT32_MAX) { + dprintf(DEBUG_CRITICAL, "Length is too large.\n"); + return -1; + } + + if (offset > UINT32_MAX || offset > fileLength || offset < 0) { + dprintf(DEBUG_CRITICAL, "Offset is too large.\n"); + return -1; + } + + if ((size_t)offset + length < length) { + dprintf(DEBUG_CRITICAL, "Length wraparound.\n"); + return -1; + } + + if ((offset + length) > fileLength) { + length = fileLength - offset; + } + + rv = ReadExtent((uint8_t *)extents, fileLength, fileID, + offset, length, base, 0); + if (rv < 0) { + return -1; + } + *length_inout = rv; + + return 0; +} + +static int +GetCatalogEntryInfo(void *entry, uint32_t *flags, time_t *time, off_t *size) +{ + uint32_t tmpTime = 0; + uint64_t tmpSize = 0; + + HFSdebug("fetching information for file type 0x%04x", HFSntohs((uint16_t *)entry)); + + // Get information about the file. + switch (HFSntohs((uint16_t *)entry)) { + case kHFSFolderRecord : + *flags = kFileTypeDirectory; + tmpTime = HFSntohl((uint32_t *)&((HFSCatalogFolder *)entry)->modifyDate); + break; + + case kHFSPlusFolderRecord : + *flags = kFileTypeDirectory | + (HFSntohs(&((HFSPlusCatalogFolder *)entry)->bsdInfo.fileMode) & kPermMask); + tmpTime = HFSntohl(&((HFSPlusCatalogFolder *)entry)->contentModDate); + break; + + case kHFSFileRecord : + *flags = kFileTypeFlat; + tmpSize = HFSntohl(&((HFSCatalogFile *)entry)->dataLogicalSize); + tmpTime = HFSntohl(&((HFSCatalogFile *)entry)->modifyDate); + break; + + case kHFSPlusFileRecord : + *flags = kFileTypeFlat | + (HFSntohs(&((HFSPlusCatalogFile *)entry)->bsdInfo.fileMode) & kPermMask); + tmpSize = HFSntohll(&((HFSPlusCatalogFile *)entry)->dataFork.logicalSize); + tmpTime = HFSntohl(&((HFSPlusCatalogFile *)entry)->contentModDate); + HFSdebug("file size is %lld", tmpSize); + break; + + case kHFSFileThreadRecord : + case kHFSPlusFileThreadRecord : + case kHFSFolderThreadRecord : + case kHFSPlusFolderThreadRecord : + *flags = kFileTypeUnknown; + tmpTime = 0; + break; + default: + return -1; + } + + if (time != 0) { + // Convert base time from 1904 to 1970. + *time = tmpTime - 2082844800; + } + if (size != 0) + *size = tmpSize; + + return 0; +} + +static int +ResolvePathToCatalogEntry(const char *filePath, uint32_t *flags, void *entry, uint32_t dirID, off_t *dirIndex, time_t *time, off_t *size) +{ + const char *restPath; + int result; + uint32_t cnt, subFolderID = 0; + static uint32_t recursionCnt = 0; + + // Copy the file name to gTempStr + cnt = 0; + result = -1; + + if (kDirLevelMax <= recursionCnt++) { + HFSdebug("Too many levels of directories"); + goto exit; + } + + while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) + cnt++; + + if (cnt >= sizeof(gTempStr)) { + HFSdebug("String too long"); + goto exit; + } + strlcpy(gTempStr, filePath, cnt + 1); + + // Move restPath to the right place. + if (filePath[cnt] != '\0') + cnt++; + restPath = filePath + cnt; + + // gTempStr is a name in the current Dir. + // restPath is the rest of the path if any. + HFSdebug("searching for '%s' with remaining path '%s'", gTempStr, restPath); + + result = ReadCatalogEntry(gTempStr, dirID, entry, dirIndex); + if (result < 0) { + HFSdebug("not found"); + goto exit; + } + if (dirIndex != 0) + HFSdebug("found at index %llx", *dirIndex); + + if (GetCatalogEntryInfo(entry, flags, time, size) < 0) { + HFSdebug("bad catalog entry info"); + result = -1; + goto exit; + } + + // recursively look up child + if ((*flags & kFileTypeMask) == kFileTypeDirectory) { + subFolderID = HFSntohl(&((HFSPlusCatalogFolder *)entry)->folderID); + HFSdebug("looking up '%s' in '%s'", restPath, gTempStr); + result = ResolvePathToCatalogEntry(restPath, flags, entry, subFolderID, dirIndex, time, size); + if (result != 0) { + result = -1; + goto exit; + } + } else { + // if we weren't on the last element of the path, then + // we should have found a directory + if (*restPath != '\0') { + HFSdebug("expected directory"); + result = -1; + goto exit; + } + } + +exit: + HFSdebug("returning %d", result); + recursionCnt--; + return result; +} + +static int +VerifyCatalogKeyBounds(HFSPlusCatalogKey *key, uint8_t *bufend) +{ + int ret = 0; + + // Verify key length is contained inside the node + if ((uint8_t *)&key->keyLength + sizeof(key->keyLength) > bufend) { + HFSdebug("keyLength outside of node"); + ret = -1; + goto exit; + } + // Verify end of key doesn't overflow past end of node + if ((uint8_t *)key + HFSntohs(&key->keyLength) > bufend) { + HFSdebug("Bad keyLength (ends at %p, bufend %p)", (uint8_t *)key + HFSntohs(&key->keyLength), bufend); + ret = -1; + goto exit; + } + // There are actually two lengths to check, the second one gives the + // number of UCS-2 (16-bit) characters in the name + if ((uint8_t *)&key->nodeName.unicode + HFSntohs(&key->nodeName.length) * 2 > bufend) { + HFSdebug("Bad unicode length"); + ret = -1; + goto exit; + } + +exit: + return ret; +} + +static int +GetCatalogEntry(off_t *dirIndex, char *name, size_t nameSize, uint32_t *flags, time_t *time, off_t *size) +{ + uint32_t extentSize, nodeSize, curNode, index; + void *extent; + uint8_t *nodeBuf, *testKey, *entry; + HFSPlusCatalogKey *catalogKey; + BTNodeDescriptor *node; + int result; + int ret = 0; + + extent = &gHFSPlus->catalogFile.extents; + extentSize = HFSntohll(&gHFSPlus->catalogFile.logicalSize); + + nodeSize = HFSntohs(&gBTHeaders[kBTreeCatalog]->nodeSize); + nodeBuf = malloc(nodeSize); + HFSdebug("got nodeBuf %p", nodeBuf); + node = (BTNodeDescriptor *)nodeBuf; + + HFSdebug("dirIndex %p/%lld nodeS5ze %u", dirIndex, *dirIndex, nodeSize); + index = *dirIndex % nodeSize; + curNode = *dirIndex / nodeSize; + HFSdebug("working with index %d curNode %d", index, curNode); + + // Read the BTree node and get the record for index. + result = ReadExtent(extent, extentSize, kHFSCatalogFileID, curNode * nodeSize, nodeSize, nodeBuf, 1); + if (result < 0 || (unsigned)result != nodeSize) { + ret = -1; + goto exit; + } + if (GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry) != 0) { + ret = -1; + goto exit; + } + catalogKey = (HFSPlusCatalogKey *)testKey; + + // Check for overflow + if (VerifyCatalogKeyBounds(catalogKey, nodeBuf + nodeSize) != 0) { + ret = -1; + goto exit; + } + + HFSdebug("got BTnode and index record"); + + if (GetCatalogEntryInfo(entry, flags, time, size) != 0) { + ret = -1; + goto exit; + } + HFSdebug("got entry info"); + + // Get the file name. + if (utf_encodestr(catalogKey->nodeName.unicode, + HFSntohs((uint16_t *)&catalogKey->nodeName.length), + (uint8_t *)name, nameSize) <= 0) { + HFSdebug("failed to UTF encode filename"); + ret = -1; + goto exit; + } + HFSdebug("got file name"); + + // Update dirIndex. + index++; + if (index == HFSntohs(&node->numRecords)) { + index = 0; + curNode = HFSntohl(&node->fLink); + } + + *dirIndex = curNode * nodeSize + index; + HFSdebug("updated forward sibling index"); + +exit: + free(nodeBuf); + + HFSdebug("returning %d", ret); + return ret; +} + +static int +ReadCatalogEntry(const char *fileName, uint32_t dirID, void *entry, off_t *dirIndex) +{ + uint32_t length; + HFSPlusCatalogKey *hfsPlusKey; + int ret; + + length = strlen(fileName); + if (length > HFS_MAXNAMLEN) { + HFSdebug("length overflowed"); + return -1; + } + + hfsPlusKey = malloc(sizeof(HFSPlusCatalogKey)); + // Make the catalog key. + hfsPlusKey->parentID = dirID; + utf_decodestr255((char *)fileName, &hfsPlusKey->nodeName); + HFSdebug("UTF encoded '%s' from length %d to length %d", fileName, length, (int)hfsPlusKey->nodeName.length * 2); + + ret = ReadBTreeEntry(kBTreeCatalog, (char *)hfsPlusKey, entry, dirIndex); + free(hfsPlusKey); + return ret; +} + +static int +ReadExtentsEntry(uint32_t fileID, uint32_t startBlock, void *entry) +{ + HFSPlusExtentKey hfsPlusKey; + + // Make the extents key. + hfsPlusKey.forkType = 0; + hfsPlusKey.fileID = fileID; + hfsPlusKey.startBlock = startBlock; + + return ReadBTreeEntry(kBTreeExtents, &hfsPlusKey, entry, 0); +} + +static int +ReadBTreeEntry(uint32_t btree, void *key, uint8_t *entry, off_t *dirIndex) +{ + uint32_t extentSize; + void *extent; + uint16_t extentFile; + BTHeaderRec *headerRec; + uint8_t *nodeBuf; + BTNodeDescriptor *node; + uint32_t nodeSize, entrySize = 0; + uint32_t curNode, index = 0; + int32_t numRecords, lowerBound, upperBound; + uint8_t *testKey, *recordData; + uint32_t level; + int extentLen; + int result = 0; + int ret = 0; + + // Figure out which tree is being looked at. + if (btree == kBTreeCatalog) { + HFSdebug("working with the catalog BTree"); + extent = &gHFSPlus->catalogFile.extents; + extentSize = HFSntohll(&gHFSPlus->catalogFile.logicalSize); + extentFile = kHFSCatalogFileID; + } else { + HFSdebug("working with the extents BTree"); + extent = &gHFSPlus->extentsFile.extents; + extentSize = HFSntohll(&gHFSPlus->extentsFile.logicalSize); + extentFile = kHFSExtentsFileID; + } + + headerRec = gBTHeaders[btree]; + ASSERT(headerRec != NULL); + + curNode = HFSntohl(&headerRec->rootNode); + level = HFSntohs(&headerRec->treeDepth); + + nodeSize = HFSntohs(&headerRec->nodeSize); + nodeBuf = malloc(nodeSize); + node = (BTNodeDescriptor *)nodeBuf; + HFSdebug("btree %d headers %p curNode %x nodeSize %d nodeBuf %p node %p", + btree, headerRec, curNode, nodeSize, nodeBuf, node); + + while (1) { + HFSdebug("current node %x", curNode); + + // Node 0 is the header node, and is never an index or leaf node. + if (curNode == 0) { + ret = -1; + goto exit; + } + + // Read the current node. + extentLen = ReadExtent(extent, extentSize, extentFile, curNode * nodeSize, nodeSize, nodeBuf, 1); + if (extentLen < 0 || (unsigned)extentLen != nodeSize) { + HFSdebug("short result from ReadExtent"); + ret = -1; + goto exit; + } + + // Make sure the node's height and kind are correct, and numRecords is non-zero. + if (node->height != level) { + HFSdebug("Bad node: height is %d; expected %d", node->height, level); + ret = -1; + goto exit; + } + if (node->kind != (level == 1 ? kBTLeafNode : kBTIndexNode)) { + HFSdebug("Bad node: kind is %d; expected %d", node->kind, + (level == 1 ? kBTLeafNode : kBTIndexNode)); + ret = -1; + goto exit; + } + + numRecords = HFSntohs(&node->numRecords); + + if (numRecords <= 0) { + HFSdebug("Bad node: numRecords must be positive"); + ret = -1; + goto exit; + } + + // Find the matching key. + lowerBound = 0; + upperBound = numRecords - 1; + HFSdebug("node has %d records", upperBound + 1); + while (lowerBound <= upperBound) { + ASSERT(lowerBound >= 0 && upperBound >= 0); + index = ((uint32_t)lowerBound + (uint32_t)upperBound) / 2; + HFSdebug("current record %d (lower %d upper %d)", index, lowerBound, upperBound); + + if(GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData) != 0) { + HFSdebug("GetBTreeRecord failed"); + ret = -1; + goto exit; + } + + if (btree == kBTreeCatalog) { + // catalog keys contain two lengths and GetBTreeRecord only validates + // the first one, so check both lengths to be sure + if (VerifyCatalogKeyBounds((HFSPlusCatalogKey *)testKey, nodeBuf + nodeSize) != 0) { + HFSdebug("VerifyCatalogKeyBounds failed"); + ret = -1; + goto exit; + } + result = CompareHFSPlusCatalogKeys(key, testKey); + } else { + // Unlike catalog keys, extent keys just have the one length + // and GetBTreeRecord validates that length is in the buffer + result = CompareHFSPlusExtentsKeys(key, testKey); + } + HFSdebug("compare result %d", result); + + if (result < 0) + upperBound = index - 1; // search < trial + else if (result > 0) + lowerBound = index + 1; // search > trial + else break; // search = trial + } + HFSdebug("best match %d", index); + + if (result < 0) { + index = upperBound; + if(GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData) != 0) { + ret = -1; + goto exit; + } + } + + // Found the closest key... Recurse on it if this is an index node. + if (node->kind == kBTIndexNode) { + HFSdebug("recursing on index node from %p", recordData); + curNode = HFSntohl((uint32_t *)recordData); + } else { + break; + } + + --level; + } + + // Return error if the file was not found. + if (result != 0) { + HFSdebug("file not found"); + ret = -1; + goto exit; + } + + if (btree == kBTreeCatalog) { + switch (HFSntohs((uint16_t *)recordData)) { + case kHFSFolderRecord : entrySize = 70; break; + case kHFSFileRecord : entrySize = 102; break; + case kHFSFolderThreadRecord : entrySize = 46; break; + case kHFSFileThreadRecord : entrySize = 46; break; + case kHFSPlusFolderRecord : entrySize = 88; break; + case kHFSPlusFileRecord : entrySize = 248; break; + case kHFSPlusFolderThreadRecord : entrySize = 264; break; + case kHFSPlusFileThreadRecord : entrySize = 264; break; + default: + // we don't know how much to copy, so we have to fail + ret = -1; + goto exit; + } + } else { + entrySize = sizeof(HFSPlusExtentRecord); + } + HFSdebug("entrySize %d", entrySize); + + // Check for overflow out of the node + if ((uint8_t *)recordData + entrySize > nodeBuf + nodeSize) { + ret = -1; + goto exit; + } + + memcpy(entry, recordData, entrySize); + + // Update dirIndex. + if (dirIndex != 0) { + index++; + if (index == HFSntohs(&node->numRecords)) { + index = 0; + curNode = HFSntohl(&node->fLink); + } + *dirIndex = curNode * nodeSize + index; + } + +exit: + free(nodeBuf); + + return ret; +} + +static int +GetBTreeRecord(uint32_t index, uint8_t *nodeBuffer, uint32_t nodeSize, uint8_t **key, uint8_t **data) +{ + int ret = 0; + uint32_t keySize; + uint32_t recordOffset; + + // check index range + if ((2 * index + 2) < index || (2 * index + 2) > nodeSize) { + HFSdebug("index value (%d) out of range", index); + ret = -1; + goto exit; + } + + // List of offsets for each record in the BTree node is at the end of the node, + // in reverse order (highest index is closest to the start of the node) + recordOffset = HFSntohs((uint16_t *)(nodeBuffer + (nodeSize - 2 * index - 2))); + *key = nodeBuffer + recordOffset; + + // check key ptr range + if (*key < nodeBuffer || *key > (nodeBuffer + nodeSize - 1)) { + HFSdebug("key ptr (%p) out of range", *key); + ret = -1; + goto exit; + } + + keySize = HFSntohs((uint16_t *)*key); + *data = *key + 2 + keySize; + + // check data ptr range + if (*data < nodeBuffer || *data > (nodeBuffer + nodeSize - 1)) { + HFSdebug("data ptr (%p) out of range", *data); + ret = -1; + goto exit; + } + + HFSdebug("record %d at offset %d (%p) keysize %d data at %p", + index, recordOffset, *key, keySize, *data); + +exit: + return ret; +} + +static int +ReadExtent(uint8_t *extent, uint32_t extentSize, uint32_t extentFile, off_t offset, uint32_t size, void *buffer, bool cache) +{ + uint32_t lastOffset, blockNumber, countedBlocks = 0; + uint32_t nextExtent = 0, sizeRead = 0, readSize; + uint32_t nextExtentBlock, currentExtentBlock = 0; + off_t readOffset; + uint32_t extentDensity, sizeofExtent, currentExtentSize; + uint8_t *currentExtent, *extentBuffer = 0, *bufferPos = buffer; + int result = 0; + + if (offset < 0) { + return -1; + } + + if (offset >= extentSize) { + HFSdebug("offset too large"); + return 0; + } + + extentDensity = kHFSPlusExtentDensity; + sizeofExtent = sizeof(HFSPlusExtentDescriptor); + + lastOffset = offset + size; + HFSdebug("offset %llx size %x", offset, size); + while (offset < lastOffset) { + blockNumber = offset / gBlockSize; + HFSdebug("file blockNumber %x", blockNumber); + + // Find the extent for the offset. + for (; ; nextExtent++) { + HFSdebug("nextExtent %x countedBlocks %x", nextExtent, countedBlocks); + if (nextExtent < extentDensity) { + if ((countedBlocks + GetExtentSize(extent, nextExtent) - 1) < blockNumber) { + HFSdebug("skipping early extent %x blocks", GetExtentSize(extent, nextExtent)); + countedBlocks += GetExtentSize(extent, nextExtent); + continue; + } + + currentExtent = extent + nextExtent * sizeofExtent; + HFSdebug("found offset %llx in extent %x", offset, nextExtent); + break; + } + + if (extentBuffer == 0) { + extentBuffer = malloc(sizeofExtent * extentDensity); + HFSdebug("extent buffer at %p", extentBuffer); + } + + nextExtentBlock = nextExtent / extentDensity; + if (currentExtentBlock != nextExtentBlock) { + // Special Case: Extents File cannot have an extents-overflow + if (extentFile == kHFSExtentsFileID) { + panic("Attempt to read overflow extents for the Extents-overflow file"); + } + + // For all other cases: Read the overflow extent entry for this file from the Extents file + if (ReadExtentsEntry(extentFile, countedBlocks, extentBuffer) != 0) { + result = -1; + goto exit; + } + currentExtentBlock = nextExtentBlock; + } + + currentExtentSize = GetExtentSize(extentBuffer, nextExtent % extentDensity); + + if ((countedBlocks + currentExtentSize - 1) >= blockNumber) { + currentExtent = extentBuffer + sizeofExtent * (nextExtent % extentDensity); + break; + } + + countedBlocks += currentExtentSize; + } + + readOffset = ((blockNumber - countedBlocks) * gBlockSize) + (offset % gBlockSize); + + readSize = GetExtentSize(currentExtent, 0) * gBlockSize - readOffset; + if (readSize > (size - sizeRead)) + readSize = size - sizeRead; + + if (readSize == 0) + break; + + readOffset += (long long)GetExtentStart(currentExtent, 0) * gBlockSize; + + HFSdebug("doing cache read %x/%x", (int)readOffset, readSize); + if (CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset, readSize, cache) != readSize) { + result = -1; + goto exit; + } + + sizeRead += readSize; + offset += readSize; + bufferPos += readSize; + } + +exit: + if (extentBuffer) + free(extentBuffer); + + if (result == 0) + return sizeRead; + else + return result; +} + +static uint32_t +GetExtentStart(void *extents, uint32_t index) +{ + uint32_t start; + HFSPlusExtentDescriptor *hfsPlusExtents = extents; + + start = HFSntohl(&hfsPlusExtents[index].startBlock); + + return start; +} + +static uint32_t +GetExtentSize(void *extents, uint32_t index) +{ + uint32_t size; + HFSPlusExtentDescriptor *hfsPlusExtents = extents; + + size = HFSntohl(&hfsPlusExtents[index].blockCount); + + return size; +} + +/* + * key native endian, testKey FS endian + */ +static int +CompareHFSPlusCatalogKeys(void *key, void *testKey) +{ + HFSPlusCatalogKey *searchKey, *trialKey; + uint32_t searchParentID, trialParentID; + int result; + + searchKey = key; + trialKey = testKey; + + searchParentID = searchKey->parentID; + trialParentID = HFSntohl(&trialKey->parentID); + HFSdebug("SearchParentID %x trialParentID %x", searchParentID, trialParentID); + + // parent dirID is unsigned + if (searchParentID > trialParentID) + result = 1; + else if (searchParentID < trialParentID) + result = -1; + else { +#if 0 + printf(" search name '"); + DPrintUTF(searchKey->nodeName.unicode, searchKey->nodeName.length); + printf("' trial name '"); + DPrintUTF(trialKey->nodeName.unicode, HFSntohs(&trialKey->nodeName.length)); + printf("'\n"); +#endif + // parent dirID's are equal, compare names + if ((searchKey->nodeName.length == 0) || (HFSntohs(&trialKey->nodeName.length) == 0)) { + HFSdebug("search name length %d trial name length %d", + searchKey->nodeName.length, HFSntohs(&trialKey->nodeName.length)); + result = searchKey->nodeName.length - HFSntohs(&trialKey->nodeName.length); + } else { + result = BinaryUnicodeCompare(&searchKey->nodeName.unicode[0], + searchKey->nodeName.length, + &trialKey->nodeName.unicode[0], + HFSntohs(&trialKey->nodeName.length)); + } + } + + return result; +} + +/* + * key native endian, testKey FS endian + */ +static int +CompareHFSPlusExtentsKeys(void *key, void *testKey) +{ + HFSPlusExtentKey *searchKey, *trialKey; + int result; + + searchKey = key; + trialKey = testKey; + + // assume searchKey < trialKey + result = -1; + + if (searchKey->fileID == HFSntohl(&trialKey->fileID)) { + // FileNum's are equal; compare fork types + if (searchKey->forkType == trialKey->forkType) { + // Fork types are equal; compare allocation block number + if (searchKey->startBlock == HFSntohl(&trialKey->startBlock)) { + // Everything is equal + result = 0; + } else { + // Allocation block numbers differ; determine sign + if (searchKey->startBlock > HFSntohl(&trialKey->startBlock)) + result = 1; + } + } else { + // Fork types differ; determine sign + if (searchKey->forkType > trialKey->forkType) + result = 1; + } + } else { + // FileNums differ; determine sign + if (searchKey->fileID > HFSntohl(&trialKey->fileID)) + result = 1; + } + + return result; +} + +// +// BinaryUnicodeCompare - Compare two Unicode strings; produce a relative ordering +// Compared using a 16-bit binary comparison (no case folding) +// +static int32_t +BinaryUnicodeCompare (uint16_t * str1, uint32_t length1, uint16_t * str2, uint32_t length2) +{ + register uint16_t c1, c2; + int32_t bestGuess; + uint32_t length; + + bestGuess = 0; + + if (length1 < length2) { + length = length1; + --bestGuess; + } else if (length1 > length2) { + length = length2; + ++bestGuess; + } else { + length = length1; + } + + while (length--) { + c1 = HFSntohs(str1++); + c2 = HFSntohs(str2++); + + if (c1 > c2) + return (1); + if (c1 < c2) + return (-1); + } + + return (bestGuess); +} + +/* + * UTF-8 (UCS Transformation Format) + * + * The following subset of UTF-8 is used to encode UCS-2 filenames. It + * requires a maximum of three 3 bytes per UCS-2 character. Only the + * shortest encoding required to represent the significant UCS-2 bits + * is legal. + * + * UTF-8 Multibyte Codes + * + * Bytes Bits UCS-2 Min UCS-2 Max UTF-8 Byte Sequence (binary) + * ------------------------------------------------------------------- + * 1 7 0x0000 0x007F 0xxxxxxx + * 2 11 0x0080 0x07FF 110xxxxx 10xxxxxx + * 3 16 0x0800 0xFFFF 1110xxxx 10xxxxxx 10xxxxxx + * ------------------------------------------------------------------- + */ + +/* + * utf_encodestr - Encodes the UCS-2 (Unicode) string at ucsp into a + * null terminated UTF-8 string at utf8p. + * + * inbufsize is the input buffer length in bytes + * ucslen is the number of UCS-2 input characters (not bytes) + * outbufsize is the size of the output buffer in bytes + * + */ +static int +utf_encodestr(const uint16_t *ucsp, unsigned ucslen, uint8_t *utf8p, size_t outbufsize) +{ + uint8_t *bufstart; + uint8_t *bufend; + uint16_t ucs_ch; + + if (outbufsize <= 0) + return -1; + + bufstart = utf8p; + bufend = utf8p + outbufsize - 1; + + while (ucslen-- > 0) { + ucs_ch = HFSntohs(ucsp++); + + if (ucs_ch < 0x0080) { + if (utf8p >= bufend) { + HFSdebug("1 byte character past end of buffer"); + return -1; + } + if (ucs_ch == '\0') + continue; /* skip over embedded NULLs */ + *utf8p++ = ucs_ch; + + } else if (ucs_ch < 0x800) { + if ((utf8p + 1) >= bufend) { + HFSdebug("2 byte character past end of buffer"); + return -1; + } + *utf8p++ = (ucs_ch >> 6) | 0xc0; + *utf8p++ = (ucs_ch & 0x3f) | 0x80; + + } else { + if ((utf8p + 2) >= bufend) { + HFSdebug("3 byte character past end of buffer"); + return -1; + } + *utf8p++ = (ucs_ch >> 12) | 0xe0; + *utf8p++ = ((ucs_ch >> 6) & 0x3f) | 0x80; + *utf8p++ = ((ucs_ch) & 0x3f) | 0x80; + } + + } + + *utf8p = '\0'; + + return utf8p - bufstart; +} + +static void +utf_decodestr255(const char *utf8p, struct HFSUniStr255 *ucsstrp) +{ + utf_decodestr(utf8p, ucsstrp->unicode, &ucsstrp->length, sizeof(ucsstrp->unicode)); +} + +/* + * utf_decodestr - Decodes the null terminated UTF-8 string at + * utf8p into a UCS-2 (Unicode) string at ucsp. + * + * ucslen is the number of UCS-2 output characters (not bytes) + * bufsize is the size of the output buffer in bytes + */ +static void +utf_decodestr(const char *utf8p, uint16_t *ucsp, uint16_t *ucslen, uint32_t bufsize) +{ + uint16_t *bufstart; + uint16_t *bufend; + uint16_t ucs_ch; + uint8_t byte; + + bufstart = ucsp; + bufend = (uint16_t *)((uint8_t *)ucsp + bufsize); + + while ((byte = *utf8p++) != '\0') { + if (ucsp >= bufend) + break; + + /* check for ascii */ + if (byte < 0x80) { + ucs_ch = byte; + + *ucsp++ = HFShtons(ucs_ch); + continue; + } + + switch (byte & 0xf0) { + /* 2 byte sequence*/ + case 0xc0: + case 0xd0: + /* extract bits 6 - 10 from first byte */ + ucs_ch = (byte & 0x1F) << 6; + break; + /* 3 byte sequence*/ + case 0xe0: + /* extract bits 12 - 15 from first byte */ + ucs_ch = (byte & 0x0F) << 6; + + /* extract bits 6 - 11 from second byte */ + if (((byte = *utf8p++) & 0xc0) != 0x80) + goto stop; + + ucs_ch += (byte & 0x3F); + ucs_ch <<= 6; + break; + default: + goto stop; + } + + /* extract bits 0 - 5 from final byte */ + if (((byte = *utf8p++) & 0xc0) != 0x80) + goto stop; + ucs_ch += (byte & 0x3F); + + *ucsp++ = HFShtons(ucs_ch); + } +stop: + *ucslen = ucsp - bufstart; +} diff --git a/lib/fs/hfs/hfs.h b/lib/fs/hfs/hfs.h new file mode 100644 index 0000000..b5956db --- /dev/null +++ b/lib/fs/hfs/hfs.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* Derived from: */ +/* + * fs.h - Externs for the File System Modules + * + * Copyright (c) 1999-2004 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ + +#ifndef _BOOTX_FS_H_ +#define _BOOTX_FS_H_ + +// tunable +#define kFSCacheSize (64 * 1024) + +// File Permissions and Types +enum { + kPermOtherExecute = 1 << 0, + kPermOtherWrite = 1 << 1, + kPermOtherRead = 1 << 2, + kPermGroupExecute = 1 << 3, + kPermGroupWrite = 1 << 4, + kPermGroupRead = 1 << 5, + kPermOwnerExecute = 1 << 6, + kPermOwnerWrite = 1 << 7, + kPermOwnerRead = 1 << 8, + kPermMask = 0x1FF, + kOwnerNotRoot = 1 << 9, + kFileTypeUnknown = 0x0 << 16, + kFileTypeFlat = 0x1 << 16, + kFileTypeDirectory = 0x2 << 16, + kFileTypeLink = 0x3 << 16, + kFileTypeMask = 0x3 << 16 +}; + +typedef void *CICell; + +// Externs for cache.c +extern uint32_t gCacheHits; +extern uint32_t gCacheMisses; +extern uint32_t gCacheEvicts; + +extern void CacheInit(CICell ih, uint32_t chunkSize); +extern uint32_t CacheRead(CICell ih, uint8_t *buffer, off_t offset, + uint32_t length, bool cache); + +// Externs for hfs.c +extern int HFSInitPartition(CICell ih); +extern int HFSDetect(void); +extern int HFSReadFile(CICell ih, const char *filePath, void *base, off_t offset, size_t length); +extern int HFSGetFileInfo(CICell ih, const char *filePath, uint32_t *flags, time_t *time, off_t *size); +extern int HFSGetDirEntry(CICell ih, const char *dirPath, off_t *dirIndex, char *name, size_t nameSize, uint32_t *flags, time_t *time, off_t *size); +extern struct HFSPlusVolumeHeader *HFSGetVolumeHeader(void); + +// Externs for hfs_fs.c +extern int HFSBlockRead(CICell *ih, void *buf, off_t offset, uint32_t length); + +/* + * We may need to work with big-endian data that's not + * aligned. For ARM at least, this is an issue. Rather + * than use swap functions and macrotize, these are explicitly + * called out to avoid alignment issues even on big-endian systems. + * + * No these aren't efficient. No, it doesn't really matter... + */ +static inline u_int64_t +HFSntohll(const void *ov) +{ + unsigned const char *ovb = (unsigned const char *)ov; + + return(((u_int64_t)ovb[0] << 56) + + ((u_int64_t)ovb[1] << 48) + + ((u_int64_t)ovb[2] << 40) + + ((u_int64_t)ovb[3] << 32) + + ((u_int64_t)ovb[4] << 24) + + ((u_int64_t)ovb[5] << 16) + + ((u_int64_t)ovb[6] << 8) + + (u_int64_t)ovb[7]); +} + +static inline u_int32_t +HFSntohl(const void *ov) +{ + unsigned const char *ovb = (unsigned const char *)ov; + + return(((u_int32_t)ovb[0] << 24) + + ((u_int32_t)ovb[1] << 16) + + ((u_int32_t)ovb[2] << 8) + + (u_int32_t)ovb[3]); +} + +static inline u_int16_t +HFSntohs(const void *ov) +{ + unsigned const char *ovb = (unsigned const char *)ov; + + return(((u_int16_t)ovb[0] << 8) + (u_int16_t)ovb[1]); +} + +static inline short +HFShtons(const unsigned short ov) +{ + unsigned short nv; + unsigned char *nvb = (unsigned char *)&nv; + + nvb[0] = (ov >> 8); + nvb[1] = ov & 0xff; + + return(nv); +} + + +#endif /* ! _BOOTX_FS_H_ */ diff --git a/lib/fs/hfs/hfs_format.h b/lib/fs/hfs/hfs_format.h new file mode 100644 index 0000000..488de3a --- /dev/null +++ b/lib/fs/hfs/hfs_format.h @@ -0,0 +1,746 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef __HFS_FORMAT__ +#define __HFS_FORMAT__ + +/* + * hfs_format.c + * + * This file describes the on-disk format for HFS and HFS Plus volumes. + * The HFS Plus volume format is desciibed in detail in Apple Technote 1150. + * + * http://developer.apple.com/technotes/tn/tn1150.html + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* some on-disk hfs structures have 68K alignment (misaligned) */ + +/* Signatures used to differentiate between HFS and HFS Plus volumes */ +enum { + kHFSSigWord = 0x4244, /* 'BD' in ASCII */ + kHFSPlusSigWord = 0x482B, /* 'H+' in ASCII */ + kHFSXSigWord = 0x4858, /* 'HX' in ASCII */ + + kHFSPlusVersion = 0x0004, /* 'H+' volumes are version 4 only */ + kHFSXVersion = 0x0005, /* 'HX' volumes start with version 5 */ + + kHFSPlusMountVersion = 0x31302E30, /* '10.0' for Mac OS X */ + kHFSJMountVersion = 0x4846534a, /* 'HFSJ' for journaled HFS+ on OS X */ + kFSKMountVersion = 0x46534b21 /* 'FSK!' for failed journal replay */ +}; + + +#ifdef __APPLE_API_PRIVATE +/* + * Mac OS X has two special directories on HFS+ volumes for hardlinked files + * and hardlinked directories as well as for open-unlinked files. + * + * These directories and their contents are not exported from the filesystem + * under Mac OS X. + */ +#define HFSPLUSMETADATAFOLDER "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data" +#define HFSPLUS_ARCHIVED_FOLDERS ".Archived_Directories\x0d" + +/* + * Files in the "HFS+ Private Data" folder have one of the following prefixes + * followed by a decimal number (no leading zeros) for the file ID. + * + * Note: Earlier version of Mac OS X used a 32 bit random number for the link + * ref number instead of the file id. + * + * e.g. iNode7182000 and temp3296 + */ +#define HFS_INODE_PREFIX "iNode" +#define HFS_DELETE_PREFIX "temp" + +/* + * Files in the ".Archived_Directories" folder have the following prefix + * followed by a decimal number (no leading zeros) for the file ID. + * + * e.g. dir_555 + */ +#define HFS_DIRINODE_PREFIX "dir_" + +/* + * Hardlink inodes save the head of the link chain in + * an extended attribute named FIRST_LINK_XATTR_NAME. + * The attribute data is the decimal value in ASCII + * of the cnid for the first link in the chain. + * + * This extended attribute is private (i.e. its not + * exported in the getxattr/listxattr POSIX APIs). + */ +#define FIRST_LINK_XATTR_NAME "com.apple.system.hfs.firstlink" +#define FIRST_LINK_XATTR_REC_SIZE (sizeof(HFSPlusAttrData) - 2 + 12) + +#endif /* __APPLE_API_PRIVATE */ + +/* + * Indirect link files (hard links) have the following type/creator. + */ +enum { + kHardLinkFileType = 0x686C6E6B, /* 'hlnk' */ + kHFSPlusCreator = 0x6866732B /* 'hfs+' */ +}; + + +/* + * File type and creator for symbolic links + */ +enum { + kSymLinkFileType = 0x736C6E6B, /* 'slnk' */ + kSymLinkCreator = 0x72686170 /* 'rhap' */ +}; + + +#ifndef _HFSUNISTR255_DEFINED_ +#define _HFSUNISTR255_DEFINED_ +/* Unicode strings are used for HFS Plus file and folder names */ +struct HFSUniStr255 { + uint16_t length; /* number of unicode characters */ + uint16_t unicode[255]; /* unicode characters */ +} __attribute__((aligned(2), packed)); +typedef struct HFSUniStr255 HFSUniStr255; +typedef const HFSUniStr255 *ConstHFSUniStr255Param; +#endif /* _HFSUNISTR255_DEFINED_ */ + +enum { + kHFSMaxVolumeNameChars = 27, + kHFSMaxFileNameChars = 31, + kHFSPlusMaxFileNameChars = 255 +}; + + +/* Extent overflow file data structures */ + +/* HFS Extent key */ +struct HFSExtentKey { + uint8_t keyLength; /* length of key, excluding this field */ + uint8_t forkType; /* 0 = data fork, FF = resource fork */ + uint32_t fileID; /* file ID */ + uint16_t startBlock; /* first file allocation block number in this extent */ +} __attribute__((aligned(2), packed)); +typedef struct HFSExtentKey HFSExtentKey; + +/* HFS Plus Extent key */ +struct HFSPlusExtentKey { + uint16_t keyLength; /* length of key, excluding this field */ + uint8_t forkType; /* 0 = data fork, FF = resource fork */ + uint8_t pad; /* make the other fields align on 32-bit boundary */ + uint32_t fileID; /* file ID */ + uint32_t startBlock; /* first file allocation block number in this extent */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusExtentKey HFSPlusExtentKey; + +/* Number of extent descriptors per extent record */ +enum { + kHFSExtentDensity = 3, + kHFSPlusExtentDensity = 8 +}; + +/* HFS extent descriptor */ +struct HFSExtentDescriptor { + uint16_t startBlock; /* first allocation block */ + uint16_t blockCount; /* number of allocation blocks */ +} __attribute__((aligned(2), packed)); +typedef struct HFSExtentDescriptor HFSExtentDescriptor; + +/* HFS Plus extent descriptor */ +struct HFSPlusExtentDescriptor { + uint32_t startBlock; /* first allocation block */ + uint32_t blockCount; /* number of allocation blocks */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusExtentDescriptor HFSPlusExtentDescriptor; + +/* HFS extent record */ +typedef HFSExtentDescriptor HFSExtentRecord[3]; + +/* HFS Plus extent record */ +typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8]; + + +/* Finder information */ +struct FndrFileInfo { + uint32_t fdType; /* file type */ + uint32_t fdCreator; /* file creator */ + uint16_t fdFlags; /* Finder flags */ + struct { + int16_t v; /* file's location */ + int16_t h; + } fdLocation; + int16_t opaque; +} __attribute__((aligned(2), packed)); +typedef struct FndrFileInfo FndrFileInfo; + +struct FndrDirInfo { + struct { /* folder's window rectangle */ + int16_t top; + int16_t left; + int16_t bottom; + int16_t right; + } frRect; + unsigned short frFlags; /* Finder flags */ + struct { + uint16_t v; /* folder's location */ + uint16_t h; + } frLocation; + int16_t opaque; +} __attribute__((aligned(2), packed)); +typedef struct FndrDirInfo FndrDirInfo; + +struct FndrOpaqueInfo { + int8_t opaque[16]; +} __attribute__((aligned(2), packed)); +typedef struct FndrOpaqueInfo FndrOpaqueInfo; + + +/* HFS Plus Fork data info - 80 bytes */ +struct HFSPlusForkData { + uint64_t logicalSize; /* fork's logical size in bytes */ + uint32_t clumpSize; /* fork's clump size in bytes */ + uint32_t totalBlocks; /* total blocks used by this fork */ + HFSPlusExtentRecord extents; /* initial set of extents */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusForkData HFSPlusForkData; + + +/* Mac OS X has 16 bytes worth of "BSD" info. + * + * Note: Mac OS 9 implementations and applications + * should preserve, but not change, this information. + */ +struct HFSPlusBSDInfo { + uint32_t ownerID; /* user-id of owner or hard link chain previous link */ + uint32_t groupID; /* group-id of owner or hard link chain next link */ + uint8_t adminFlags; /* super-user changeable flags */ + uint8_t ownerFlags; /* owner changeable flags */ + uint16_t fileMode; /* file type and permission bits */ + union { + uint32_t iNodeNum; /* indirect node number (hard links only) */ + uint32_t linkCount; /* links that refer to this indirect node */ + uint32_t rawDevice; /* special file device (FBLK and FCHR only) */ + } special; +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusBSDInfo HFSPlusBSDInfo; + +/* + * Hardlink "links" resolve to an inode + * and the actual uid/gid comes from that + * inode. + * + * We repurpose the links's uid/gid fields + * for the hardlink link chain. The chain + * consists of a doubly linked list of file + * ids. + */ + +#define hl_firstLinkID reserved1 /* Valid only if HasLinkChain flag is set (indirect nodes only) */ + +#define hl_prevLinkID bsdInfo.ownerID /* Valid only if HasLinkChain flag is set */ +#define hl_nextLinkID bsdInfo.groupID /* Valid only if HasLinkChain flag is set */ + +#define hl_linkReference bsdInfo.special.iNodeNum +#define hl_linkCount bsdInfo.special.linkCount + + +/* Catalog file data structures */ + +enum { + kHFSRootParentID = 1, /* Parent ID of the root folder */ + kHFSRootFolderID = 2, /* Folder ID of the root folder */ + kHFSExtentsFileID = 3, /* File ID of the extents file */ + kHFSCatalogFileID = 4, /* File ID of the catalog file */ + kHFSBadBlockFileID = 5, /* File ID of the bad allocation block file */ + kHFSAllocationFileID = 6, /* File ID of the allocation file (HFS Plus only) */ + kHFSStartupFileID = 7, /* File ID of the startup file (HFS Plus only) */ + kHFSAttributesFileID = 8, /* File ID of the attribute file (HFS Plus only) */ + kHFSAttributeDataFileID = 13, /* Used in Mac OS X runtime for extent based attributes */ + /* kHFSAttributeDataFileID is never stored on disk. */ + kHFSRepairCatalogFileID = 14, /* Used when rebuilding Catalog B-tree */ + kHFSBogusExtentFileID = 15, /* Used for exchanging extents in extents file */ + kHFSFirstUserCatalogNodeID = 16 +}; + +/* HFS catalog key */ +struct HFSCatalogKey { + uint8_t keyLength; /* key length (in bytes) */ + uint8_t reserved; /* reserved (set to zero) */ + uint32_t parentID; /* parent folder ID */ + uint8_t nodeName[kHFSMaxFileNameChars + 1]; /* catalog node name */ +} __attribute__((aligned(2), packed)); +typedef struct HFSCatalogKey HFSCatalogKey; + +/* HFS Plus catalog key */ +struct HFSPlusCatalogKey { + uint16_t keyLength; /* key length (in bytes) */ + uint32_t parentID; /* parent folder ID */ + HFSUniStr255 nodeName; /* catalog node name */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusCatalogKey HFSPlusCatalogKey; + +/* Catalog record types */ +enum { + /* HFS Catalog Records */ + kHFSFolderRecord = 0x0100, /* Folder record */ + kHFSFileRecord = 0x0200, /* File record */ + kHFSFolderThreadRecord = 0x0300, /* Folder thread record */ + kHFSFileThreadRecord = 0x0400, /* File thread record */ + + /* HFS Plus Catalog Records */ + kHFSPlusFolderRecord = 1, /* Folder record */ + kHFSPlusFileRecord = 2, /* File record */ + kHFSPlusFolderThreadRecord = 3, /* Folder thread record */ + kHFSPlusFileThreadRecord = 4 /* File thread record */ +}; + + +/* Catalog file record flags */ +enum { + kHFSFileLockedBit = 0x0000, /* file is locked and cannot be written to */ + kHFSFileLockedMask = 0x0001, + + kHFSThreadExistsBit = 0x0001, /* a file thread record exists for this file */ + kHFSThreadExistsMask = 0x0002, + + kHFSHasAttributesBit = 0x0002, /* object has extended attributes */ + kHFSHasAttributesMask = 0x0004, + + kHFSHasSecurityBit = 0x0003, /* object has security data (ACLs) */ + kHFSHasSecurityMask = 0x0008, + + kHFSHasFolderCountBit = 0x0004, /* folder maintains a seperate sub-folder count */ + kHFSHasFolderCountMask = 0x0010, + + kHFSHasLinkChainBit = 0x0005, /* has hardlink chain (inode or link) */ + kHFSHasLinkChainMask = 0x0020, + + kHFSHasChildLinkBit = 0x0006, /* folder has a child that's a dir link */ + kHFSHasChildLinkMask = 0x0040 +}; + + +/* HFS catalog folder record - 70 bytes */ +struct HFSCatalogFolder { + int16_t recordType; /* == kHFSFolderRecord */ + uint16_t flags; /* folder flags */ + uint16_t valence; /* folder valence */ + uint32_t folderID; /* folder ID */ + uint32_t createDate; /* date and time of creation */ + uint32_t modifyDate; /* date and time of last modification */ + uint32_t backupDate; /* date and time of last backup */ + FndrDirInfo userInfo; /* Finder information */ + FndrOpaqueInfo finderInfo; /* additional Finder information */ + uint32_t reserved[4]; /* reserved - initialized as zero */ +} __attribute__((aligned(2), packed)); +typedef struct HFSCatalogFolder HFSCatalogFolder; + +/* HFS Plus catalog folder record - 88 bytes */ +struct HFSPlusCatalogFolder { + int16_t recordType; /* == kHFSPlusFolderRecord */ + uint16_t flags; /* file flags */ + uint32_t valence; /* folder's item count */ + uint32_t folderID; /* folder ID */ + uint32_t createDate; /* date and time of creation */ + uint32_t contentModDate; /* date and time of last content modification */ + uint32_t attributeModDate; /* date and time of last attribute modification */ + uint32_t accessDate; /* date and time of last access (MacOS X only) */ + uint32_t backupDate; /* date and time of last backup */ + HFSPlusBSDInfo bsdInfo; /* permissions (for MacOS X) */ + FndrDirInfo userInfo; /* Finder information */ + FndrOpaqueInfo finderInfo; /* additional Finder information */ + uint32_t textEncoding; /* hint for name conversions */ + uint32_t folderCount; /* number of enclosed folders, active when HasFolderCount is set */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusCatalogFolder HFSPlusCatalogFolder; + +/* HFS catalog file record - 102 bytes */ +struct HFSCatalogFile { + int16_t recordType; /* == kHFSFileRecord */ + uint8_t flags; /* file flags */ + int8_t fileType; /* file type (unused ?) */ + FndrFileInfo userInfo; /* Finder information */ + uint32_t fileID; /* file ID */ + uint16_t dataStartBlock; /* not used - set to zero */ + int32_t dataLogicalSize; /* logical EOF of data fork */ + int32_t dataPhysicalSize; /* physical EOF of data fork */ + uint16_t rsrcStartBlock; /* not used - set to zero */ + int32_t rsrcLogicalSize; /* logical EOF of resource fork */ + int32_t rsrcPhysicalSize; /* physical EOF of resource fork */ + uint32_t createDate; /* date and time of creation */ + uint32_t modifyDate; /* date and time of last modification */ + uint32_t backupDate; /* date and time of last backup */ + FndrOpaqueInfo finderInfo; /* additional Finder information */ + uint16_t clumpSize; /* file clump size (not used) */ + HFSExtentRecord dataExtents; /* first data fork extent record */ + HFSExtentRecord rsrcExtents; /* first resource fork extent record */ + uint32_t reserved; /* reserved - initialized as zero */ +} __attribute__((aligned(2), packed)); +typedef struct HFSCatalogFile HFSCatalogFile; + +/* HFS Plus catalog file record - 248 bytes */ +struct HFSPlusCatalogFile { + int16_t recordType; /* == kHFSPlusFileRecord */ + uint16_t flags; /* file flags */ + uint32_t reserved1; /* reserved - initialized as zero */ + uint32_t fileID; /* file ID */ + uint32_t createDate; /* date and time of creation */ + uint32_t contentModDate; /* date and time of last content modification */ + uint32_t attributeModDate; /* date and time of last attribute modification */ + uint32_t accessDate; /* date and time of last access (MacOS X only) */ + uint32_t backupDate; /* date and time of last backup */ + HFSPlusBSDInfo bsdInfo; /* permissions (for MacOS X) */ + FndrFileInfo userInfo; /* Finder information */ + FndrOpaqueInfo finderInfo; /* additional Finder information */ + uint32_t textEncoding; /* hint for name conversions */ + uint32_t reserved2; /* reserved - initialized as zero */ + + /* Note: these start on double long (64 bit) boundry */ + HFSPlusForkData dataFork; /* size and block data for data fork */ + HFSPlusForkData resourceFork; /* size and block data for resource fork */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusCatalogFile HFSPlusCatalogFile; + +/* HFS catalog thread record - 46 bytes */ +struct HFSCatalogThread { + int16_t recordType; /* == kHFSFolderThreadRecord or kHFSFileThreadRecord */ + int32_t reserved[2]; /* reserved - initialized as zero */ + uint32_t parentID; /* parent ID for this catalog node */ + uint8_t nodeName[kHFSMaxFileNameChars + 1]; /* name of this catalog node */ +} __attribute__((aligned(2), packed)); +typedef struct HFSCatalogThread HFSCatalogThread; + +/* HFS Plus catalog thread record -- 264 bytes */ +struct HFSPlusCatalogThread { + int16_t recordType; /* == kHFSPlusFolderThreadRecord or kHFSPlusFileThreadRecord */ + int16_t reserved; /* reserved - initialized as zero */ + uint32_t parentID; /* parent ID for this catalog node */ + HFSUniStr255 nodeName; /* name of this catalog node (variable length) */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusCatalogThread HFSPlusCatalogThread; + +#ifdef __APPLE_API_UNSTABLE +/* + These are the types of records in the attribute B-tree. The values were + chosen so that they wouldn't conflict with the catalog record types. +*/ +enum { + kHFSPlusAttrInlineData = 0x10, /* attributes whose data fits in a b-tree node */ + kHFSPlusAttrForkData = 0x20, /* extent based attributes (data lives in extents) */ + kHFSPlusAttrExtents = 0x30 /* overflow extents for large attributes */ +}; + + +/* + HFSPlusAttrForkData + For larger attributes, whose value is stored in allocation blocks. + If the attribute has more than 8 extents, there will be additonal + records (of type HFSPlusAttrExtents) for this attribute. +*/ +struct HFSPlusAttrForkData { + uint32_t recordType; /* == kHFSPlusAttrForkData*/ + uint32_t reserved; + HFSPlusForkData theFork; /* size and first extents of value*/ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusAttrForkData HFSPlusAttrForkData; + +/* + HFSPlusAttrExtents + This record contains information about overflow extents for large, + fragmented attributes. +*/ +struct HFSPlusAttrExtents { + uint32_t recordType; /* == kHFSPlusAttrExtents*/ + uint32_t reserved; + HFSPlusExtentRecord extents; /* additional extents*/ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusAttrExtents HFSPlusAttrExtents; + +/* + * Atrributes B-tree Data Record + * + * For small attributes, whose entire value is stored + * within a single B-tree record. + */ +struct HFSPlusAttrData { + uint32_t recordType; /* == kHFSPlusAttrInlineData */ + uint32_t reserved[2]; + uint32_t attrSize; /* size of attribute data in bytes */ + uint8_t attrData[2]; /* variable length */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusAttrData HFSPlusAttrData; + + +/* HFSPlusAttrInlineData is obsolete use HFSPlusAttrData instead */ +struct HFSPlusAttrInlineData { + uint32_t recordType; + uint32_t reserved; + uint32_t logicalSize; + uint8_t userData[2]; +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData; + + +/* A generic Attribute Record*/ +union HFSPlusAttrRecord { + uint32_t recordType; + HFSPlusAttrInlineData inlineData; /* NOT USED */ + HFSPlusAttrData attrData; + HFSPlusAttrForkData forkData; + HFSPlusAttrExtents overflowExtents; +}; +typedef union HFSPlusAttrRecord HFSPlusAttrRecord; + +/* Attribute key */ +enum { kHFSMaxAttrNameLen = 127 }; +struct HFSPlusAttrKey { + uint16_t keyLength; /* key length (in bytes) */ + uint16_t pad; /* set to zero */ + uint32_t fileID; /* file associated with attribute */ + uint32_t startBlock; /* first allocation block number for extents */ + uint16_t attrNameLen; /* number of unicode characters */ + uint16_t attrName[kHFSMaxAttrNameLen]; /* attribute name (Unicode) */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusAttrKey HFSPlusAttrKey; + +#define kHFSPlusAttrKeyMaximumLength (sizeof(HFSPlusAttrKey) - sizeof(uint16_t)) +#define kHFSPlusAttrKeyMinimumLength (kHFSPlusAttrKeyMaximumLength - kHFSMaxAttrNameLen*sizeof(uint16_t)) + +#endif /* __APPLE_API_UNSTABLE */ + + +/* Key and node lengths */ +enum { + kHFSPlusExtentKeyMaximumLength = sizeof(HFSPlusExtentKey) - sizeof(uint16_t), + kHFSExtentKeyMaximumLength = sizeof(HFSExtentKey) - sizeof(uint8_t), + kHFSPlusCatalogKeyMaximumLength = sizeof(HFSPlusCatalogKey) - sizeof(uint16_t), + kHFSPlusCatalogKeyMinimumLength = kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(uint16_t), + kHFSCatalogKeyMaximumLength = sizeof(HFSCatalogKey) - sizeof(uint8_t), + kHFSCatalogKeyMinimumLength = kHFSCatalogKeyMaximumLength - (kHFSMaxFileNameChars + 1) + sizeof(uint8_t), + kHFSPlusCatalogMinNodeSize = 4096, + kHFSPlusExtentMinNodeSize = 512, + kHFSPlusAttrMinNodeSize = 4096 +}; + +/* HFS and HFS Plus volume attribute bits */ +enum { + /* Bits 0-6 are reserved (always cleared by MountVol call) */ + kHFSVolumeHardwareLockBit = 7, /* volume is locked by hardware */ + kHFSVolumeUnmountedBit = 8, /* volume was successfully unmounted */ + kHFSVolumeSparedBlocksBit = 9, /* volume has bad blocks spared */ + kHFSVolumeNoCacheRequiredBit = 10, /* don't cache volume blocks (i.e. RAM or ROM disk) */ + kHFSBootVolumeInconsistentBit = 11, /* boot volume is inconsistent (System 7.6 and later) */ + kHFSCatalogNodeIDsReusedBit = 12, + kHFSVolumeJournaledBit = 13, /* this volume has a journal on it */ + kHFSVolumeInconsistentBit = 14, /* serious inconsistencies detected at runtime */ + kHFSVolumeSoftwareLockBit = 15, /* volume is locked by software */ + + kHFSVolumeHardwareLockMask = 1 << kHFSVolumeHardwareLockBit, + kHFSVolumeUnmountedMask = 1 << kHFSVolumeUnmountedBit, + kHFSVolumeSparedBlocksMask = 1 << kHFSVolumeSparedBlocksBit, + kHFSVolumeNoCacheRequiredMask = 1 << kHFSVolumeNoCacheRequiredBit, + kHFSBootVolumeInconsistentMask = 1 << kHFSBootVolumeInconsistentBit, + kHFSCatalogNodeIDsReusedMask = 1 << kHFSCatalogNodeIDsReusedBit, + kHFSVolumeJournaledMask = 1 << kHFSVolumeJournaledBit, + kHFSVolumeInconsistentMask = 1 << kHFSVolumeInconsistentBit, + kHFSVolumeSoftwareLockMask = 1 << kHFSVolumeSoftwareLockBit, + kHFSMDBAttributesMask = 0x8380 +}; + + +/* HFS Master Directory Block - 162 bytes */ +/* Stored at sector #2 (3rd sector) and second-to-last sector. */ +struct HFSMasterDirectoryBlock { + uint16_t drSigWord; /* == kHFSSigWord */ + uint32_t drCrDate; /* date and time of volume creation */ + uint32_t drLsMod; /* date and time of last modification */ + uint16_t drAtrb; /* volume attributes */ + uint16_t drNmFls; /* number of files in root folder */ + uint16_t drVBMSt; /* first block of volume bitmap */ + uint16_t drAllocPtr; /* start of next allocation search */ + uint16_t drNmAlBlks; /* number of allocation blocks in volume */ + uint32_t drAlBlkSiz; /* size (in bytes) of allocation blocks */ + uint32_t drClpSiz; /* default clump size */ + uint16_t drAlBlSt; /* first allocation block in volume */ + uint32_t drNxtCNID; /* next unused catalog node ID */ + uint16_t drFreeBks; /* number of unused allocation blocks */ + uint8_t drVN[kHFSMaxVolumeNameChars + 1]; /* volume name */ + uint32_t drVolBkUp; /* date and time of last backup */ + uint16_t drVSeqNum; /* volume backup sequence number */ + uint32_t drWrCnt; /* volume write count */ + uint32_t drXTClpSiz; /* clump size for extents overflow file */ + uint32_t drCTClpSiz; /* clump size for catalog file */ + uint16_t drNmRtDirs; /* number of directories in root folder */ + uint32_t drFilCnt; /* number of files in volume */ + uint32_t drDirCnt; /* number of directories in volume */ + uint32_t drFndrInfo[8]; /* information used by the Finder */ + uint16_t drEmbedSigWord; /* embedded volume signature (formerly drVCSize) */ + HFSExtentDescriptor drEmbedExtent; /* embedded volume location and size (formerly drVBMCSize and drCtlCSize) */ + uint32_t drXTFlSize; /* size of extents overflow file */ + HFSExtentRecord drXTExtRec; /* extent record for extents overflow file */ + uint32_t drCTFlSize; /* size of catalog file */ + HFSExtentRecord drCTExtRec; /* extent record for catalog file */ +} __attribute__((aligned(2), packed)); +typedef struct HFSMasterDirectoryBlock HFSMasterDirectoryBlock; + + +#ifdef __APPLE_API_UNSTABLE +#define SET_HFS_TEXT_ENCODING(hint) \ + (0x656e6300 | ((hint) & 0xff)) +#define GET_HFS_TEXT_ENCODING(hint) \ + (((hint) & 0xffffff00) == 0x656e6300 ? (hint) & 0x000000ff : 0xffffffffU) +#endif /* __APPLE_API_UNSTABLE */ + + +/* HFS Plus Volume Header - 512 bytes */ +/* Stored at sector #2 (3rd sector) and second-to-last sector. */ +struct HFSPlusVolumeHeader { + uint16_t signature; /* == kHFSPlusSigWord */ + uint16_t version; /* == kHFSPlusVersion */ + uint32_t attributes; /* volume attributes */ + uint32_t lastMountedVersion; /* implementation version which last mounted volume */ + uint32_t journalInfoBlock; /* block addr of journal info (if volume is journaled, zero otherwise) */ + + uint32_t createDate; /* date and time of volume creation */ + uint32_t modifyDate; /* date and time of last modification */ + uint32_t backupDate; /* date and time of last backup */ + uint32_t checkedDate; /* date and time of last disk check */ + + uint32_t fileCount; /* number of files in volume */ + uint32_t folderCount; /* number of directories in volume */ + + uint32_t blockSize; /* size (in bytes) of allocation blocks */ + uint32_t totalBlocks; /* number of allocation blocks in volume (includes this header and VBM*/ + uint32_t freeBlocks; /* number of unused allocation blocks */ + + uint32_t nextAllocation; /* start of next allocation search */ + uint32_t rsrcClumpSize; /* default resource fork clump size */ + uint32_t dataClumpSize; /* default data fork clump size */ + uint32_t nextCatalogID; /* next unused catalog node ID */ + + uint32_t writeCount; /* volume write count */ + uint64_t encodingsBitmap; /* which encodings have been use on this volume */ + + uint8_t finderInfo[32]; /* information used by the Finder */ + + HFSPlusForkData allocationFile; /* allocation bitmap file */ + HFSPlusForkData extentsFile; /* extents B-tree file */ + HFSPlusForkData catalogFile; /* catalog B-tree file */ + HFSPlusForkData attributesFile; /* extended attributes B-tree file */ + HFSPlusForkData startupFile; /* boot file (secondary loader) */ +} __attribute__((aligned(2), packed)); +typedef struct HFSPlusVolumeHeader HFSPlusVolumeHeader; + + +/* B-tree structures */ + +enum BTreeKeyLimits{ + kMaxKeyLength = 520 +}; + +union BTreeKey{ + uint8_t length8; + uint16_t length16; + uint8_t rawData [kMaxKeyLength+2]; +}; +typedef union BTreeKey BTreeKey; + +/* BTNodeDescriptor -- Every B-tree node starts with these fields. */ +struct BTNodeDescriptor { + uint32_t fLink; /* next node at this level*/ + uint32_t bLink; /* previous node at this level*/ + int8_t kind; /* kind of node (leaf, index, header, map)*/ + uint8_t height; /* zero for header, map; child is one more than parent*/ + uint16_t numRecords; /* number of records in this node*/ + uint16_t reserved; /* reserved - initialized as zero */ +} __attribute__((aligned(2), packed)); +typedef struct BTNodeDescriptor BTNodeDescriptor; + +/* Constants for BTNodeDescriptor kind */ +enum { + kBTLeafNode = -1, + kBTIndexNode = 0, + kBTHeaderNode = 1, + kBTMapNode = 2 +}; + +/* BTHeaderRec -- The first record of a B-tree header node */ +struct BTHeaderRec { + uint16_t treeDepth; /* maximum height (usually leaf nodes) */ + uint32_t rootNode; /* node number of root node */ + uint32_t leafRecords; /* number of leaf records in all leaf nodes */ + uint32_t firstLeafNode; /* node number of first leaf node */ + uint32_t lastLeafNode; /* node number of last leaf node */ + uint16_t nodeSize; /* size of a node, in bytes */ + uint16_t maxKeyLength; /* reserved */ + uint32_t totalNodes; /* total number of nodes in tree */ + uint32_t freeNodes; /* number of unused (free) nodes in tree */ + uint16_t reserved1; /* unused */ + uint32_t clumpSize; /* reserved */ + uint8_t btreeType; /* reserved */ + uint8_t keyCompareType; /* Key string Comparison Type */ + uint32_t attributes; /* persistent attributes about the tree */ + uint32_t reserved3[16]; /* reserved */ +} __attribute__((aligned(2), packed)); +typedef struct BTHeaderRec BTHeaderRec; + +/* Constants for BTHeaderRec attributes */ +enum { + kBTBadCloseMask = 0x00000001, /* reserved */ + kBTBigKeysMask = 0x00000002, /* key length field is 16 bits */ + kBTVariableIndexKeysMask = 0x00000004 /* keys in index nodes are variable length */ +}; + + +/* Catalog Key Name Comparison Type */ +enum { + kHFSCaseFolding = 0xCF, /* case folding (case-insensitive) */ + kHFSBinaryCompare = 0xBC /* binary compare (case-sensitive) */ +}; + +/* JournalInfoBlock - Structure that describes where our journal lives */ +struct JournalInfoBlock { + uint32_t flags; + uint32_t device_signature[8]; // signature used to locate our device. + uint64_t offset; // byte offset to the journal on the device + uint64_t size; // size in bytes of the journal + uint32_t reserved[32]; +} __attribute__((aligned(2), packed)); +typedef struct JournalInfoBlock JournalInfoBlock; + +enum { + kJIJournalInFSMask = 0x00000001, + kJIJournalOnOtherDeviceMask = 0x00000002, + kJIJournalNeedInitMask = 0x00000004 +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* __HFS_FORMAT__ */ diff --git a/lib/fs/hfs/hfs_fs.c b/lib/fs/hfs/hfs_fs.c new file mode 100644 index 0000000..b9ae317 --- /dev/null +++ b/lib/fs/hfs/hfs_fs.c @@ -0,0 +1,385 @@ +/* Copyright 2007-2011 Apple Inc. All rights Reserved */ +/* Copyright 2006 Apple Computer Inc, All Rights Reserved */ + +/* + * Interface shim between the iBoot fs/bdev layers and the HFS code. + */ + +#include +#include +#include +#include +#include +#include +#ifndef HFS_UNITTEST +#include +#endif +#include "hfs.h" +#include "hfs_format.h" + +#if 0 +# define HFSdebug(fmt, args...) printf("%s: " fmt "\n", __FUNCTION__ , ##args) +#else +# define HFSdebug(fmt, args...) do { } while (0) +#endif + +/******************************************************************************* + * fs interface + */ + +static int hfs_mount(void **ctxt, const char *devname); +static void hfs_unmount(void *ctxt); +static int hfs_fsstat(void *ctxt, struct statfs *stat); + +static void *hfs_open(void *ctxt, const char *path, uint8_t flags); +static int hfs_read(void *filectxt, void *buf, size_t len); +static int hfs_fstat(void *filectxt, struct stat *st); +static off_t hfs_seek(void *filectxt, off_t offset, int whence); +static void hfs_close(void *filectxt); + +static void *hfs_opendir(void *ctxt, const char *path); +static int hfs_readdir(void *dirctxt, struct dirent *ent); +static void hfs_rewinddir(void *dirctxt); +static void hfs_closedir(void *dirctxt); + +struct fs_ops hfs_fs_ops = { + hfs_mount, + hfs_unmount, + hfs_fsstat, + + hfs_open, + hfs_read, + hfs_fstat, + hfs_seek, + hfs_close, + + hfs_opendir, + hfs_readdir, + hfs_rewinddir, + hfs_closedir +}; + +struct hfs_context { + struct blockdev *dev; + struct statfs s; + uint32_t blocksize; +}; + +struct hfs_openfile { + struct hfs_context *fs; + char *path; + off_t pos; + struct stat s; +}; + +struct hfs_opendir { + struct hfs_context *fs; + char *path; + off_t pos; +}; + +/* + * Locking. Since the HFS code is not re-entrant, we must ensure + * that only one task calls into it at a time. + */ +#ifndef HFS_UNITTEST +static struct task *hfs_owner_task; + +#define LOCK() \ + do { \ + while (hfs_owner_task != NULL) \ + task_yield(); \ + hfs_owner_task = current_task; \ + } while(0); + +#define UNLOCK() \ + do { \ + hfs_owner_task = NULL; \ + } while(0); +#else +#define LOCK() do {} while(0) +#define UNLOCK() do {} while(0) +#endif + + + +static int +hfs_mount(void **ctxt, const char *devname) +{ + struct hfs_context *cp; + struct HFSPlusVolumeHeader *vh; + int result; + + HFSdebug("mounting '%s'", devname); + result = -1; + + LOCK(); + cp = malloc(sizeof(struct hfs_context)); + + // find the device + if ((cp->dev = lookup_blockdev(devname)) == NULL) + goto out; + + // make sure it's something we recognise + if (HFSInitPartition(cp)) + goto out; + +// HFSDetect(); + + // save FS stat info while we're at it + vh = HFSGetVolumeHeader(); + cp->s.f_bsize = vh->blockSize; + cp->s.f_blocks = vh->totalBlocks; + cp->s.f_bfree = vh->freeBlocks; + + result = 0; +out: + if (result) { + free(cp); + HFSdebug("mount failed"); + } else { + HFSdebug("mounted fs %p", cp); + *ctxt = cp; + } + UNLOCK(); + return(result); +} + +static void +hfs_unmount(void *ctxt) +{ + free(ctxt); +} + +static int +hfs_fsstat(void *ctxt, struct statfs *stat) +{ + struct hfs_context *cp = (struct hfs_context *)ctxt; + + *stat = cp->s; + + return(0); +} + +static void * +hfs_open(void *ctxt, const char *path, uint8_t open_flags) +{ + struct hfs_context *cp = (struct hfs_context *)ctxt; + struct hfs_openfile *of; + uint32_t flags; + uint32_t path_length; + time_t time; + off_t size; + + HFSdebug("%s: openfile", path); + if (path[0] == '/') + path++; + of = NULL; + LOCK(); + + // check for file existence + if (HFSGetFileInfo(cp, path, &flags, &time, &size)) + goto out; + if ((flags & kFileTypeMask) != kFileTypeFlat) + goto out; + + // alloc file and populate path + path_length = strlen(path) + 1; + of = malloc(sizeof(struct hfs_openfile) + path_length); + of->path = (char *)(of + 1); + strlcpy(of->path, path, path_length); + of->pos = 0; + of->fs = cp; + + // Since we have stat information courtesy of checking the file's existence, + // save it away for the inevitable stat. + of->s.st_ino = 0; // XXX + of->s.st_size = size; + of->s.st_blocks = size / cp->s.f_bsize + ((size % cp->s.f_bsize) ? 1 : 0); + of->s.st_type = FILE_TYPE_FILE; + of->s.st_flags = 0; // XXX + of->s.st_ctime = of->s.st_mtime = of->s.st_atime = time; +out: + UNLOCK(); + if (of == NULL) + HFSdebug("openfile failed"); + + return(of); +} + +static int +hfs_read(void *filectxt, void *buf, size_t len) +{ + struct hfs_openfile *of = (struct hfs_openfile *)filectxt; + int result; + + if (of->s.st_type != FILE_TYPE_FILE) + return(-1); + + HFSdebug("%s: read %zu bytes to %p", of->path, len, buf); + + result = HFSReadFile(of->fs, of->path, buf, of->pos, len); + + if (result) + HFSdebug("read returns %d", result); + + if (result > 0) + of->pos += result; + + return(result); +} + +static int +hfs_fstat(void *filectxt, struct stat *st) +{ + struct hfs_openfile *of = (struct hfs_openfile *)filectxt; + + *st = of->s; + return(0); +} + +static off_t +hfs_seek(void *filectxt, off_t offset, int whence) +{ + struct hfs_openfile *of = (struct hfs_openfile *)filectxt; + off_t newpos; + + switch(whence) { + case FILE_SEEK_SET: + newpos = offset; + break; + + case FILE_SEEK_CUR: + newpos = of->pos + offset; + break; + + case FILE_SEEK_END: + newpos = of->s.st_size + offset; + break; + default: + return(-1); + } + if ((newpos < 0) || (newpos > of->s.st_size)) + return(-1); + + HFSdebug("%s: seek to 0x%llx", of->path, newpos); + return((of->pos = newpos)); +} + +static void +hfs_close(void *filectxt) +{ + free(filectxt); +} + +static void * +hfs_opendir(void *ctxt, const char *path) +{ + struct hfs_context *cp = (struct hfs_context *)ctxt; + struct hfs_opendir *od; + uint32_t flags; + uint32_t path_length; + + HFSdebug("%s: opendir", path); + od = NULL; + if (path[0] == '/') + path++; + LOCK(); + + // check for directory existence (/ always exists) + if (path[0] != '\0') { + if (HFSGetFileInfo(cp, path, &flags, 0, 0)) { + HFSdebug("%s: can't get directory info", path); + goto out; + } + } + + // alloc file and populate path + path_length = strlen(path) + 1; + od = malloc(sizeof(struct hfs_opendir) + path_length); + od->path = (char *)(od + 1); + strlcpy(od->path, path, path_length); + od->pos = 0; + od->fs = cp; +out: + UNLOCK(); + if (od == NULL) { + HFSdebug("opendir failed"); + } else { + HFSdebug("opendir OK"); + } + return(od); +} + +static int +hfs_readdir(void *dirctxt, struct dirent *ent) +{ + struct hfs_opendir *od = (struct hfs_opendir *)dirctxt; + uint32_t flags; + time_t time; + off_t size; + int result; + + if (od->pos == -1) + return(-1); // end of directory + HFSdebug("%s: readdir at 0x%llx", od->path, od->pos); + + LOCK(); + if (HFSGetDirEntry(od->fs, od->path, &od->pos, ent->d_name, sizeof(ent->d_name), &flags, &time, &size) >= 0) { + + ent->d_fileno = od->pos; // kinda dubious + RELEASE_ASSERT(size <= INT32_MAX); + ent->d_reclen = size; // ?! seems to be what it's for + switch(flags & kFileTypeMask) { + case kFileTypeFlat: + ent->d_type = FILE_TYPE_FILE; + break; + case kFileTypeDirectory: + ent->d_type = FILE_TYPE_DIR; + break; + default: + ent->d_type = FILE_TYPE_UNKNOWN; + break; + } + ent->d_name[sizeof(ent->d_name) - 1] = '\0'; + ent->d_namlen = strlen(ent->d_name); + ent->d_ctime = ent->d_atime = ent->d_atime = time; + result = 0; + } else { + result = -1; + } + UNLOCK(); + + return(result); +} + +static void +hfs_rewinddir(void *dirctxt) +{ + struct hfs_opendir *od = (struct hfs_opendir *)dirctxt; + + od->pos = 0; +} + +static void +hfs_closedir(void *dirctxt) +{ + free(dirctxt); +} + + +/******************************************************************************* + * bdev interface + * + * Note that the blockdev layer deblocks for us, so this interface is trivial. + */ + +int +HFSBlockRead(CICell *ih, void *buf, off_t offset, uint32_t length) +{ + struct hfs_context *cp = (struct hfs_context *)ih; + + HFSdebug("HFS physical read from 0x%llx/0x%x to %p", (unsigned long long)offset, length, buf); + + return(blockdev_read(cp->dev, buf, offset, length)); +} diff --git a/lib/fs/hfs/library.mk b/lib/fs/hfs/library.mk new file mode 100644 index 0000000..dc799fa --- /dev/null +++ b/lib/fs/hfs/library.mk @@ -0,0 +1,32 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBHFS_DIR := $(GET_LOCAL_DIR) +LIBHFS_BUILD := $(call TOLIBDIR,$(LIBHFS_DIR)/LIBHFS.a) +COMMONLIBS += LIBHFS + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +GLOBAL_INCLUDES += $(SRCROOT)/arch/arm/include + +LIBHFS_OBJS := \ + $(LIBHFS_DIR)/cache.o \ + $(LIBHFS_DIR)/hfs.o \ + $(LIBHFS_DIR)/hfs_fs.o + +LIBHFS_OBJS := $(call TOLIBOBJDIR,$(LIBHFS_OBJS)) + +ALL_DEPS += $(LIBHFS_OBJS:%o=%d) + +$(LIBHFS_BUILD): $(LIBHFS_OBJS) + +endif diff --git a/lib/fs/hfs/rules.mk b/lib/fs/hfs/rules.mk new file mode 100644 index 0000000..e73c4e1 --- /dev/null +++ b/lib/fs/hfs/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2008, 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_HFS=1 +MODULES += lib/fs +LIBRARY_MODULES += lib/fs \ + lib/fs/hfs + diff --git a/lib/fs/hfs/test-hfs-helper.sh b/lib/fs/hfs/test-hfs-helper.sh new file mode 100644 index 0000000..81721b5 --- /dev/null +++ b/lib/fs/hfs/test-hfs-helper.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Return an error if any commands below fail +set -e + +echo "Creating test filesystem" + +HFS_TEMPDIR=$(mktemp -d -t hfstest) + +TESTFS_ROOT=${HFS_TEMPDIR}/testfs_root +export TESTFS_COMPARE_ROOT=${HFS_TEMPDIR}/testfs_compare +export TESTFS_IMAGE=${HFS_TEMPDIR}/testfs.dmg + +DATA_PATTERN=evYya7KUSI1y5Tc05IQftxDuoIz8SlIRHDQLTA + +mkdir $TESTFS_ROOT + +for i in a a/a bb bb/bb-a bb/bb-b ccc dddd eeeee ffffff ggggggg hhhhhhhh iiiiiiiii jjjjjjjjjj kkkkkkkkkkk lllllllllllllllllllllllllllllllllllll m n o p q dir; do mkdir -p ${TESTFS_ROOT}/$i; done + +dd if=/dev/zero of=${TESTFS_ROOT}/dir/testfile0 bs=1 count=0 +dd if=/dev/zero of=${TESTFS_ROOT}/dir/testfile1 bs=1 count=1 +dd if=/dev/zero of=${TESTFS_ROOT}/dir/testfile2 bs=1 count=2 +dd if=/dev/zero of=${TESTFS_ROOT}/dir/testfile512 bs=1 count=512 +dd if=/dev/zero of=${TESTFS_ROOT}/dir/testfile1024 bs=1 count=1024 +for i in {1..1024}; do echo ${DATA_PATTERN} >> ${TESTFS_ROOT}/dir/testfile-${DATA_PATTERN}; done + +echo "Creating disk image for test filesystem" + +hdiutil create -size 4m -srcfolder $TESTFS_ROOT -format UDRW -fs HFSX -layout NONE $TESTFS_IMAGE + +./fs diff --git a/lib/fs/hfs/tests-common.mk b/lib/fs/hfs/tests-common.mk new file mode 100644 index 0000000..03c8893 --- /dev/null +++ b/lib/fs/hfs/tests-common.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_OBJS := \ + lib/libc/log2.o \ + lib/blockdev/blockdev.o \ + lib/blockdev/mem_blockdev.o \ + lib/fs/fs.o \ + lib/fs/debug.o \ + lib/fs/hfs/cache.o \ + lib/fs/hfs/hfs.o \ + lib/fs/hfs/hfs_fs.o + +TEST_SUPPORT_OBJS := \ + lib/env/env.o \ + tests/mocks/blockdev.o \ + tests/mocks/sys/security.o + +TEST_CFLAGS := \ + -DCPU_CACHELINE_SIZE=32 \ + -DHFS_UNITTEST=1 diff --git a/lib/fs/hfs/tests-fuzz.mk b/lib/fs/hfs/tests-fuzz.mk new file mode 100644 index 0000000..c17825f --- /dev/null +++ b/lib/fs/hfs/tests-fuzz.mk @@ -0,0 +1,24 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := fs-fuzz + +include $(LOCAL_DIR)/tests-common.mk + +TEST_SUPPORT_OBJS += \ + tests/fuzz-main.o \ + $(LOCAL_DIR)/fuzz.o + +TEST_CFLAGS += \ + -DNO_MOCK_ASSERTS=1 + +TEST_BUILD_ONLY := YES diff --git a/lib/fs/hfs/tests.c b/lib/fs/hfs/tests.c new file mode 100644 index 0000000..6dc164e --- /dev/null +++ b/lib/fs/hfs/tests.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include + +struct blockdev *create_mock_blockdev(const char *name, const char *filename, uint32_t block_size); + +void test_fs(uintptr_t context) { + struct blockdev *bdev; + int result; + int handle; + void *buffer; + size_t load_size; + size_t buf_size; + + const char *filename = getenv("TESTFS_IMAGE"); + TEST_ASSERT_NOT_NULL(filename); + + bdev = create_mock_blockdev("dev", filename, 4096); + register_blockdev(bdev); + + result = fs_mount("dev", "hfs", "/boot"); + TEST_ASSERT_EQ(result, 0); + + fs_dump_dir("/boot", true); + fs_dump_dir("/boot/dir", true); + + // Opening a non-existant path should fail + handle = fs_opendir("/boot/fake"); + TEST_ASSERT_LT(handle, 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/a")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/a/a")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/bb")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/bb/bb-a")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/bb/bb-b")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/ccc")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/dddd")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/eeeee")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/ffffff")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/ggggggg")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/hhhhhhhh")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/iiiiiiiii")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/jjjjjjjjjj")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/kkkkkkkkkkk")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/lllllllllllllllllllllllllllllllllllll")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/m")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/n")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/o")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/p")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/q")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + TEST_ASSERT_GTE((handle = fs_opendir("/boot/dir")), 0); + TEST_ASSERT_EQ(fs_closedir(handle), 0); + + buf_size = 1024 * 1024; + buffer = malloc(buf_size); + + // Loading non-existant file should fail + load_size = buf_size; + result = fs_load_file("/boot/testfile1", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, -1); + + // Load a file with 1 byte of zeroes + load_size = buf_size; + result = fs_load_file("/boot/dir/testfile1", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, 0); + TEST_ASSERT_EQ(load_size, 1); + + // Load a file with 2 bytes of zeroes + load_size = buf_size; + result = fs_load_file("/boot/dir/testfile2", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, 0); + TEST_ASSERT_EQ(load_size, 2); + + // Load a file with 512 bytes of zeroes + load_size = buf_size; + result = fs_load_file("/boot/dir/testfile512", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, 0); + TEST_ASSERT_EQ(load_size, 512); + + // Load a file with 1024 bytes of zeroes + load_size = buf_size; + result = fs_load_file("/boot/dir/testfile1024", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, 0); + TEST_ASSERT_EQ(load_size, 1024); + + // Load a file with a repeating data pattern + const char *pattern = "evYya7KUSI1y5Tc05IQftxDuoIz8SlIRHDQLTA\n"; + size_t pattern_len = strlen(pattern); + load_size = buf_size; + result = fs_load_file("/boot/dir/testfile-evYya7KUSI1y5Tc05IQftxDuoIz8SlIRHDQLTA", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, 0); + TEST_ASSERT_EQ(load_size, pattern_len * 1024); + char *current = buffer; + for (unsigned i = 0; i < 1024; i++) { + TEST_ASSERT_MEM_EQ(current, pattern, pattern_len); + current += pattern_len; + } + + // Verify a non-existant file is not found in a directory that exists + load_size = buf_size; + result = fs_load_file("/boot/dir/non-existant", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, -1); + + // Verify a existant file is not found in the wrong directory + load_size = buf_size; + result = fs_load_file("/boot/non-existant/testfile1", (addr_t)buffer, &load_size); + TEST_ASSERT_EQ(result, -1); + + free(buffer); +} + +struct test_suite fs_suite = { + .name = "fs", + .test_cases = { + { "fs", test_fs, 0, "" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(fs_suite); + +// Mock +bool +env_blacklist(const char *name, bool write) +{ + return false; +} + +// Mock +bool +env_blacklist_nvram(const char *name) +{ + return false; +} diff --git a/lib/fs/hfs/tests.mk b/lib/fs/hfs/tests.mk new file mode 100644 index 0000000..42f1046 --- /dev/null +++ b/lib/fs/hfs/tests.mk @@ -0,0 +1,29 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := fs + +include $(LOCAL_DIR)/tests-common.mk + +TEST_SUPPORT_OBJS += \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o + +HELPER := test-hfs-helper.sh +HELPER_INSTALL := $(call TOTESTDIR,$(HELPER)) + +$(HELPER_INSTALL): $(LOCAL_DIR)/$(HELPER) + $(_v)cp $< $@ + +EXTRA_TEST_PRODUCTS += $(HELPER_INSTALL) + +TEST_RUN_COMMAND := ./$(HELPER) diff --git a/lib/fs/library.mk b/lib/fs/library.mk new file mode 100644 index 0000000..68609e3 --- /dev/null +++ b/lib/fs/library.mk @@ -0,0 +1,29 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBFS_DIR := $(GET_LOCAL_DIR) +LIBFS_BUILD := $(call TOLIBDIR,$(LIBFS_DIR)/LIBFS.a) +COMMONLIBS += LIBFS + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBFS_OBJS := \ + $(LIBFS_DIR)/fs.o \ + $(LIBFS_DIR)/debug.o + +LIBFS_OBJS := $(call TOLIBOBJDIR,$(LIBFS_OBJS)) + +ALL_DEPS += $(LIBFS_OBJS:%o=%d) + +$(LIBFS_BUILD): $(LIBFS_OBJS) + +endif diff --git a/lib/fs/rules.mk b/lib/fs/rules.mk new file mode 100644 index 0000000..8cf1c5d --- /dev/null +++ b/lib/fs/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2008, 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_FS=1 +MODULES += lib/partition +LIBRARY_MODULES += lib/fs + diff --git a/lib/heap/heap.c b/lib/heap/heap.c new file mode 100644 index 0000000..46816cd --- /dev/null +++ b/lib/heap/heap.c @@ -0,0 +1,1296 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* + * simple heap -- mpetit + * + * a very simple multi-bin immediate coalescing heap. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Right now, we require the chunk size to be at least 2MB to be worth sliding. +#define MINIMUM_HEAP_SIZE_FOR_SLIDE (2 * 1024 * 1024) + +// 12-bits worth of entropy for the mask +#define HEAP_ENTROPY_MASK (0xfffUL) + +// Heap blocks need to be cacheline-size aligned to accomodate legacy drivers +// that don't properly align their DMA buffers. Because the cache line size +// isn't available in libraries, we're going with the largest size of any known +// cache we support +#define HEAP_BLOCK_SIZE (64) + +#define HEAP_CHECKS 1 +#define HEAP_PANIC_CHECKS 1 +#define HEAP_ERROR_PANIC 1 +#define HEAP_ERROR_DUMP 0 +#define TRACE_ALLOCATIONS 0 +#ifndef HEAP_DEBUGGING + #define HEAP_DEBUGGING 0 +#endif + +#if RELEASE_BUILD + #define HEAP_PANIC(b, x) heap_panic("", NULL, "") +#else + #define HEAP_PANIC(b, x) heap_panic(__func__, b, x) +#endif + +#if TRACE_ALLOCATIONS +# define TRACE(a...) printf(a) +#else +# define TRACE(...) do {} while(0) +#endif + +#ifndef HEAP_UNITTEST +// Minimum heap size required for heap sliding +MIB_CONSTANT_WEAK(kMIBTargetMinimumHeapSizeForSlide, kOIDTypeSize, MINIMUM_HEAP_SIZE_FOR_SLIDE); +#endif + +enum +{ + NUM_CHUNKS = 4, + NUM_BINS = 32, +}; + +struct heap_block +{ + // checksum of all members excep _pad, includes next_in_bin and prev_in_bin iff this_free is set + uint64_t checksum; + /* + * In order to get allocations that are cacheline-sized, we have to blow an entire line + * on the heap block. This is a bit inefficient, but allocations need to be I/O safe. + */ + uint32_t _pad[(HEAP_BLOCK_SIZE - 4 * __SIZEOF_SIZE_T__ - 8) / 4]; + // size of this block in units of sizeof(struct heap_block) + size_t this_size; + size_t this_free:1; + size_t prev_free:1; + // size of the previous block in units of sizeof(struct heap_block), + // allows the location of the previous block header to be found + size_t prev_size:(__SIZE_WIDTH__ - 2); + // offset from beginning of block to padding + size_t padding_start; + size_t padding_bytes; +}; + + +struct free_block +{ + struct heap_block common; + struct free_block *next_in_bin; + struct free_block *prev_in_bin; +}; + +struct client_data +{ + uint32_t block_type; + void *requestor; + const char *requestor_name; + utime_t timestamp; + + uint32_t user_size; + uint32_t alignment; +}; + +struct chunk_data +{ + struct heap_block *chunk_base; + uint32_t chunk_size; +}; + +static void heap_panic(char const *func, const void *block, const char *reason); +#if DEBUG_BUILD || HEAP_ERROR_DUMP +static void heap_dump(void); +#endif + +static int chunk_count; +static struct chunk_data lead[NUM_CHUNKS]; +static struct free_block bins[NUM_BINS]; +static u_int32_t free_mem; + +// static initializer is a fallback for cases where +// we can't get a random before enabling the heap +static_assert(SIPHASH_KEY_SIZE == HEAP_COOKIE_SIZE, "heap cookie size and MAC key size mismatch"); +uint64_t g_heap_cookie[HEAP_COOKIE_SIZE] = { 0x64636b783132322fULL, 0xa7fa3a2e367917fcULL }; + +#if HEAP_UNITTEST +void +heap_reinit(void) +{ + chunk_count = 0; + memset(lead, 0, sizeof(lead)); + memset(bins, 0, sizeof(bins)); + free_mem = 0; +} +#endif + +static +size_t +dequantify_size(size_t size) +{ + return size*sizeof(struct heap_block); +} + +static +size_t +quantify_size(size_t size) +{ + return size/sizeof(struct heap_block); +} + +static +size_t +round_size(size_t size) +{ + return (size + sizeof(struct heap_block) - 1) & ~(sizeof(struct heap_block) -1); +} + +static +unsigned +compute_bin(size_t size) +{ + unsigned result; + + size = quantify_size(size); + RELEASE_ASSERT(size >= 1); + + // clz can't operate on > 32-bit values, so return an invalid bin + // number to force grab_chunk to fail and free_list_add to assert + if ((uint64_t)size > UINT32_MAX) { + return NUM_BINS; + } + + result = NUM_BINS - __builtin_clz((uint32_t)size); + RELEASE_ASSERT(result < NUM_BINS); + + return result; +} + +static +size_t +required_size(size_t size) +{ + size += 2*sizeof(struct heap_block) - 1; + + if (size < (2*sizeof(struct heap_block) - 1)) { +#ifdef HEAP_ERROR_PANIC + panic("integer overflow in required_size\n"); +#endif + } + + size &= ~(sizeof(struct heap_block) - 1); + + if (size < sizeof(struct free_block)) { + size = sizeof(struct free_block); + } + + return size; +} + +static +size_t +required_size_for_split(size_t size) +{ + size += sizeof(struct free_block); + + return size; +} +static +size_t +sizeof_block(struct heap_block *b) +{ + return dequantify_size(b->this_size); +} + +static +void * +advance_pointer(void const *p, size_t stride) +{ + uintptr_t val; + + val = (uintptr_t)(p); + val += stride; + + return (void*)(val); +} + +static +void * +recess_pointer(void const *p, size_t stride) +{ + uintptr_t val; + + val = (uintptr_t)(p); + val -= stride; + + return (void*)(val); +} + +static +void * +next_block(struct heap_block const *b) +{ + return advance_pointer(b, dequantify_size(b->this_size)); +} + +static +void * +prev_block(struct heap_block const *b) +{ + return recess_pointer(b, dequantify_size(b->prev_size)); +} + +static +void +verify_block_checksum(struct heap_block const *b) +{ +#if HEAP_CHECKS + uint64_t checksum; + size_t checksumlen = sizeof(struct heap_block) - offsetof(struct heap_block, this_size); + if (b->this_free) + checksumlen += sizeof(struct free_block) - sizeof(struct heap_block); + + siphash_aligned((uint64_t *)&checksum, (const uint64_t *)&b->this_size, checksumlen, g_heap_cookie); + + if (checksum != b->checksum) { + HEAP_PANIC(b, "bad block checksum"); + } +#endif +} + +static +void +calculate_block_checksum(struct heap_block *b) +{ +#if HEAP_CHECKS + size_t checksumlen = sizeof(struct heap_block) - offsetof(struct heap_block, this_size); + if (b->this_free) + checksumlen += sizeof(struct free_block) - sizeof(struct heap_block); + + siphash_aligned((uint64_t *)&b->checksum, (const uint64_t *)&b->this_size, checksumlen, g_heap_cookie); +#endif +} + +static +void +verify_block_padding(struct heap_block const *b) +{ +#if HEAP_CHECKS + size_t padding = b->padding_bytes; + if (padding) { + uint8_t *pad_end = (uint8_t *)b + b->padding_start + padding; + + for(size_t i = 0; i < padding; i++) { + if (*(pad_end - 1 - i) != (uint8_t)((size_t)-1 - i)) { + HEAP_PANIC(b, "bad padding"); + } + } + } + + // Also verify the padding inside the heap block metadata + for (size_t i = 0; i < sizeof(b->_pad) / sizeof(b->_pad[0]); i++) { + if (b->_pad[i] != 0) { + HEAP_PANIC(b, "bad padding"); + } + } +#endif +} + +// Write a predictable pattern from the end of the user-requested +// portion of the heap block to the end of the actual heap block. +// This allows overflows to be detected even if they don't touch +// the next heap block's metadata +static +void +pad_block(struct heap_block *b, size_t user_size) +{ +#if HEAP_CHECKS + uint8_t *pad_start = advance_pointer(b + 1, user_size); + uint8_t *pad_end = (uint8_t *)next_block(b); + size_t padding; + +#if HEAP_DEBUGGING + pad_end -= round_size(sizeof(struct client_data)); +#endif + + padding = (pad_end - pad_start); + + b->padding_bytes = padding; + b->padding_start = pad_start - (uint8_t *)b; + + for (size_t i = 0; i < padding; i++) { + *(pad_end - 1 - i) = (uint8_t)((size_t)-1 - i); + } + + // Also zero out the padding section of the heap block's + // header + memset(b->_pad, 0, sizeof(b->_pad)); +#endif +} + +static +void +free_list_remove(struct free_block *b) +{ + if (b->prev_in_bin == b) + HEAP_PANIC(b, "free list unlink error"); + if (b->next_in_bin == b) + HEAP_PANIC(b, "free list unlink error"); + if (b->prev_in_bin->next_in_bin != b) + HEAP_PANIC(b, "free list unlink error"); + if (b->next_in_bin && b->next_in_bin->prev_in_bin != b) + HEAP_PANIC(b, "free list unlink error"); + + verify_block_checksum(&b->prev_in_bin->common); + b->prev_in_bin->next_in_bin = b->next_in_bin; + calculate_block_checksum(&b->prev_in_bin->common); + + if (b->next_in_bin) { + verify_block_checksum(&b->next_in_bin->common); + b->next_in_bin->prev_in_bin = b->prev_in_bin; + calculate_block_checksum(&b->next_in_bin->common); + } +} + +static +void +free_list_add(struct free_block *b) +{ + struct free_block *bin; + unsigned bin_num; + + bin_num = compute_bin(sizeof_block(&b->common)); + RELEASE_ASSERT(bin_num < NUM_BINS); + + bin = bins + bin_num; + + b->next_in_bin = bin->next_in_bin; + b->prev_in_bin = bin; + if (bin->next_in_bin) { + if (bin->next_in_bin == bin) + HEAP_PANIC(bin, "free list unlink error"); + if (bin->next_in_bin->prev_in_bin != bin) + HEAP_PANIC(bin, "free list unlink error"); + + verify_block_checksum(&bin->next_in_bin->common); + bin->next_in_bin->prev_in_bin = b; + calculate_block_checksum(&bin->next_in_bin->common); + } + bin->next_in_bin = b; + + calculate_block_checksum(&bin->common); +} + +static +void * +split_head(struct heap_block *b, size_t size) +{ + if (!size) { + return b; + } else if (size < sizeof(struct free_block)) { + /* + * the preamble is too small to contain a free block + * so we just append the preamble to the previous block + * + * and edge condition would be that this block is the + * first one, but this situation is skipped by making + * sure the arena starts at an address congurent with + * the size of a free block + */ + struct heap_block *prev; + struct heap_block *next; + struct heap_block *retval; + + prev = prev_block(b); + verify_block_checksum(prev); + next = next_block(b); + verify_block_checksum(next); + + retval = advance_pointer(b, size); + + prev->this_size += quantify_size(size); + next->prev_size -= quantify_size(size); + + retval->prev_free = b->prev_free; + retval->this_free = b->this_free; + retval->prev_size = b->prev_size + quantify_size(size); + retval->this_size = b->this_size - quantify_size(size); + + calculate_block_checksum(retval); + calculate_block_checksum(prev); + calculate_block_checksum(next); + + return retval; + } else { + struct heap_block *next; + struct heap_block *retval; + + next = next_block(b); + verify_block_checksum(next); + + retval = advance_pointer(b, size); + + next->prev_size -= quantify_size(size); + + retval->prev_free = 1; + retval->this_free = b->this_free; + retval->prev_size = quantify_size(size); + retval->this_size = b->this_size - quantify_size(size); + + b->this_free = 1; + b->this_size = quantify_size(size); + free_list_add((struct free_block *)b); + + calculate_block_checksum(b); + calculate_block_checksum(retval); + calculate_block_checksum(next); + + return retval; + } +} + +static +void +split_tail(struct heap_block *b, size_t size, size_t user_size) +{ + struct heap_block *next_one; + size_t block_size; + + verify_block_checksum(b); + + next_one = next_block(b); + verify_block_checksum(next_one); + + block_size = sizeof_block(b); + + if (block_size >= required_size_for_split(size)) { + struct free_block *remainder; + + remainder = advance_pointer(b, size); + + remainder->common.prev_free = 0; + remainder->common.this_free = 1; + remainder->common.prev_size = quantify_size(size); + remainder->common.this_size = b->this_size - remainder->common.prev_size; + free_list_add(remainder); + calculate_block_checksum(&remainder->common); + + b->this_size = quantify_size(size); + + next_one->prev_size = remainder->common.this_size; + } else { + next_one->prev_free = 0; + } + + b->this_free = 0; + + pad_block(b, user_size); + + calculate_block_checksum(b); + calculate_block_checksum(next_one); +} + +static +void * +grab_chunk(size_t size, size_t user_size) +{ + size_t bin; + + for (bin= compute_bin(size); bin< NUM_BINS; bin++) { + struct free_block *curr; + + // the first element of the list isn't a real free block; it just guarantees + // every real free block has a previous block + curr = &bins[bin]; + curr = curr->next_in_bin; + + // iterate the real blocks in the bin + while (curr) { + if (sizeof_block(&curr->common) >= size) { + verify_block_checksum(&curr->common); + + // take the current block out of its bin + free_list_remove(curr); + // if possible, add back any unneeded part of the + // current block to the appropriate bin; + split_tail(&curr->common, size, user_size); + + return curr; + } + + curr = curr->next_in_bin; + } + } + +#if HEAP_ERROR_PANIC +#if HEAP_ERROR_DUMP + heap_dump(); +#endif + panic("heap overflow"); +#endif + return NULL; +} + +// used by heap_memalign to find a chunk of memory whose base satisfies +// the given alignment constraint +static +void * +grab_chunk__constrained(size_t size, size_t constraint, size_t user_size) +{ + size_t bin; + + // search through all the bins, skipping any that are guaranteed to be too small + for (bin= compute_bin(size); bin< NUM_BINS; bin++) { + struct free_block *curr; + + // the first element of the list isn't a real free block; it just guarantees + // every real free block has a previous block + curr = &bins[bin]; + curr = curr->next_in_bin; + + // iterate the real blocks in the bin + while (curr) { + uintptr_t base; + uintptr_t limit; + size_t usable_size; + + // calculate the address of the memory the candidate block holds rounded up to + // required alignment + base = ((uintptr_t)(curr) + sizeof(struct heap_block) + constraint - 1) & ~(constraint - 1); + // and then figure out where the metadata for memory at the required + // alignment would sit + base -= sizeof(struct heap_block); + + // the address of the block following the candidate block + limit = (uintptr_t)(curr) + sizeof_block(&curr->common); + + // first condition, aligned address can't be past the end of the candidate block + if (base < limit) { + // if the requested amount of memory is available between the aligned address + // and the end of the block, we're good + usable_size = limit - base; + if (usable_size >= size) { + verify_block_checksum(&curr->common); + + // pull this block out of its bin + free_list_remove(curr); + + // put the unused portions of the block before and after + // the aligned address onto the appropriate free lists + curr = split_head(&curr->common, base - (uintptr_t)(curr)); + split_tail(&curr->common, size, user_size); + + return curr; + } + } + + curr = curr->next_in_bin; + } + } + +#if HEAP_ERROR_PANIC + panic("heap overflow"); +#endif + return NULL; +} + + +static +struct heap_block * +merge_blocks_left(struct heap_block *left, struct heap_block *right) +{ + // caller will add the new block back into the free list + // (possibly in a new bin to reflect the larger size) + free_list_remove((struct free_block *)(left)); + + left->this_size += right->this_size; + + if (HEAP_CHECKS) { + // the right block is going away, so make sure it no longer + // looks like a real block + right->this_size = 0; + right->prev_size = 0; + right->checksum = 0; + } + + return left; +} + +static +struct heap_block * +merge_blocks_right(struct heap_block *left, struct heap_block *right) +{ + free_list_remove((struct free_block *)(right)); + + left->this_size += right->this_size; + + if (HEAP_CHECKS) { + // the right block is going away, so make sure it no longer + // looks like a real block + right->this_size = 0; + right->prev_size = 0; + right->checksum = 0; + } + + return left; +} + +static +void +fixup_next_after_free(struct heap_block *block) +{ + struct heap_block *next; + + next = next_block(block); + verify_block_checksum(next); + + next->prev_free = 1; + next->prev_size = block->this_size; + + calculate_block_checksum(next); +} + +void * +heap_malloc(size_t size, const char *caller_name) +{ + size_t size_r; + size_t size_d; + struct heap_block *retval; + + /* must allocate at least one byte */ + if (size < 1) { +#if HEAP_ERROR_PANIC + panic("heap_malloc must allocate at least one byte"); +#endif + return 0; + } + enter_critical_section(); + + size_r = required_size(size); + if (HEAP_DEBUGGING) { + size_d = round_size(sizeof(struct client_data)); + } else { + size_d = 0; + } + retval = grab_chunk(size_r + size_d, size); + + free_mem -= sizeof_block(retval); + + if (HEAP_DEBUGGING) { + struct client_data *client; + + client = recess_pointer(next_block(retval), size_d); + + client->block_type = HEAP_BLOCK__MALLOC; + client->requestor = __return_address(0); + client->requestor_name = caller_name ? caller_name : "unknown"; + client->timestamp = system_time(); + client->user_size = size; + client->alignment = 0; + } + + TRACE( + "malloc(%zx, %s) %p -- %p [0x%zx bytes]\n", + size, caller_name ? : "unknown", + retval+1, + (uint8_t *)(retval+1) + sizeof_block(retval) - sizeof(struct heap_block), + sizeof_block(retval) - sizeof(struct heap_block) + ); + + exit_critical_section(); + + if (retval) { + retval += 1; + memset(retval, 0, size); + return retval; + } else { + return NULL; + } +} + +void *heap_calloc(size_t count, size_t size, const char *caller_name) +{ + + // Check for potential 32-bit overflow + if (size && count > (UINT32_MAX / size)) { +#if HEAP_ERROR_PANIC + panic("size * count will overflow 32-bits"); +#endif + return NULL; + } + + // malloc zeroes all returned buffers, no need to do it here + return heap_malloc(count * size, caller_name); +} + +void *heap_realloc(void *ptr, size_t size, const char *caller_name) +{ + struct heap_block *old_block = ((struct heap_block *)ptr) - 1; + void *retval = ptr; + size_t size_o = 0, size_r, size_d; + + enter_critical_section(); + + if (NULL == ptr) { + retval = heap_malloc(size, caller_name); + } else if (0 == size) { +#if HEAP_ERROR_PANIC + panic("size should not be zero"); +#endif + retval = heap_malloc(1, caller_name); + heap_free(ptr); + } else { + verify_block_checksum(old_block); + + size_r = required_size(size); + if (HEAP_DEBUGGING) { + size_d = round_size(sizeof(struct client_data)); + } else { + size_d = 0; + } + size_o = sizeof_block(old_block); + if (size_o < size_r + size_d) { + // pass size_r here because heao_malloc will add size_d + retval = heap_malloc(size_r, caller_name); + if (NULL != retval) { + memcpy(retval, ptr, (size_otimestamp = system_time(); + client->user_size = size; + } + + // we're returning the same block, but need to adjust the amount + // of padding for when we verify it. only adjust downward so that + // we don't have to fill the buffer with padding bytes if the used + // size shrank. the padding doesn't provide real security because + // the pattern is predictable +#if HEAP_CHECKS + uint8_t *pad_start = advance_pointer(old_block + 1, size); + uint8_t *pad_end = (uint8_t *)next_block(old_block); + size_t padding; + +#if HEAP_DEBUGGING + pad_end -= round_size(sizeof(struct client_data)); +#endif + padding = (pad_end - pad_start); + + if (padding < old_block->padding_bytes) { + old_block->padding_bytes = padding; + old_block->padding_start = pad_start - (uint8_t *)old_block; + + calculate_block_checksum(old_block); + } +#endif + } + } + + TRACE( + "realloc(%p, %zx, %s) %p -- %p\n", + ptr, size, + caller_name ? : "unknown", + retval, + ptr); + + exit_critical_section(); + + return retval; +} + +void * +heap_memalign(size_t size, size_t constraint, const char *caller_name) +{ + size_t size_r; + size_t size_d; + struct heap_block *retval; + + /* must allocate at least one byte */ + if (size < 1) { +#if HEAP_ERROR_PANIC + panic("_memalign must allocate at least one byte"); +#endif + return 0; + } + + if (constraint & (constraint-1)) { + /* alignment must be a power of two */ +#if HEAP_ERROR_PANIC + panic("_memalign must be a power of two"); +#endif + return 0; + } + + if (constraint < sizeof(struct free_block)) { + constraint = sizeof(struct free_block); + } + + enter_critical_section(); + + size_r = required_size(size); + if (HEAP_DEBUGGING) { + size_d = round_size(sizeof(struct client_data)); + } else { + size_d = 0; + } + retval = grab_chunk__constrained(size_r + size_d, constraint, size); + + free_mem -= sizeof_block(retval); + + if (HEAP_DEBUGGING) { + struct client_data *client; + + client = recess_pointer(next_block(retval), size_d); + + client->block_type = HEAP_BLOCK__MEMALIGN; + client->requestor = __return_address(0); + client->timestamp = system_time(); + client->user_size = size; + client->alignment = constraint; + } + + TRACE( + "memalign(%zx, %zx, %s) %p -- %p [0x%zx bytes]\n", + size, constraint, caller_name ? : "unknown", + retval+1, + (uint8_t *)(retval+1) + sizeof_block(retval) - sizeof(struct heap_block), + sizeof_block(retval) - sizeof(struct heap_block) + ); + + exit_critical_section(); + + if (retval) { + retval += 1; + memset(retval, 0, size); + return retval; + } else { + return NULL; + } +} + +int +heap_posix_memalign(void **memptr, size_t constraint, size_t size, const char *caller_name) +{ + void *result; + + if (size < 1) { +#if HEAP_ERROR_PANIC + panic("posix_memalign must allocate at least one byte"); +#endif + return EINVAL; + } + + if (constraint & (constraint-1)) { + /* alignment must be a power of two */ +#if HEAP_ERROR_PANIC + panic("posix_memalign must be a power of two"); +#endif + return EINVAL; + } + + result = heap_memalign(size, constraint, caller_name); + + if (result == 0) + return ENOMEM; + + *memptr = result; + return 0; +} + +void +heap_free(void *ptr) +{ + struct heap_block *block; + struct heap_block *left; + struct heap_block *right; + + if (!ptr) { + return; + } + + enter_critical_section(); + + block = ptr; + block -= 1; + + free_mem += sizeof_block(block); + + TRACE( + "free %p -- %p [0x%zx bytes]\n", + block+1, + (uint8_t *)(block+1) + sizeof_block(block) - sizeof(struct heap_block), + sizeof_block(block) - sizeof(struct heap_block) + ); + + verify_block_checksum(block); + + left = prev_block(block); + right = next_block(block); + + if (HEAP_CHECKS) { + if (right == block) { + HEAP_PANIC(block, "unlink error this_size"); + } + if (left == block) { + HEAP_PANIC(block, "unlink error prev_size"); + } + if (prev_block(right) != block) { + HEAP_PANIC(block, "unlink error next's prev_size"); + } + if (next_block(left) != block) { + HEAP_PANIC(block, "unlink error prev's this_size"); + } + if (block->this_free) { + HEAP_PANIC(block, "double free"); + } + + if (block->prev_free && !left->this_free) { + HEAP_PANIC(block, "free bit corrupted"); + } + + verify_block_padding(block); + + // zero the block to detect use after free + memset(block + 1, 0, sizeof_block(block) - sizeof(*block)); + + block->this_free = 1; + } + + if (block->prev_free) { + verify_block_checksum(left); + block = merge_blocks_left(left, block); + } + + verify_block_checksum(right); + if (right->this_free) { + block = merge_blocks_right(block, right); + } + + fixup_next_after_free(block); + + block->this_free = 1; + free_list_add((struct free_block *)block); + calculate_block_checksum(block); + + exit_critical_section(); +} + + +void +heap_add_chunk(void *chunk, size_t size, bool clear_memory) +{ + struct heap_block *front_sentinel; + struct heap_block *slab; + struct heap_block *back_sentinel; + uintptr_t chunk_base; + size_t original_size; + size_t minimum_size_for_slide; + +#if HEAP_CHECKS + ASSERT(sizeof(struct heap_block) == HEAP_BLOCK_SIZE); +#endif + + if (chunk_count >= NUM_CHUNKS) + panic("too many heap chunks (max %d)", NUM_CHUNKS); + + /* unless the caller knowns the chunk is all zeroes, clear it */ + if (clear_memory) + bzero(chunk, size); + + /* align the passed-in chunk and size */ + original_size = size; + chunk_base = ROUNDUP((uintptr_t)chunk, sizeof(struct heap_block)); + size -= chunk_base - (uintptr_t)chunk; + chunk = (void *)chunk_base; + size = round_size(size); + + /* check to make sure that it's larger than the required slide amount */ +#ifndef HEAP_UNITTEST + minimum_size_for_slide = mib_get_size(kMIBTargetMinimumHeapSizeForSlide); +#else + minimum_size_for_slide = MINIMUM_HEAP_SIZE_FOR_SLIDE; +#endif + + /* if it is, we will slide it around */ + if(size > minimum_size_for_slide) { + uint64_t seed = g_heap_cookie[0]; + uint64_t slide_block_size = (HEAP_ENTROPY_MASK * HEAP_BLOCK_SIZE); + uint32_t slide = (seed & HEAP_ENTROPY_MASK) * HEAP_BLOCK_SIZE; + + /* block size must never be larger than the minimum slide size */ + RELEASE_ASSERT(slide_block_size < minimum_size_for_slide); + + /* cut the heap size slightly in order to slide it around. */ + chunk_base += slide; + chunk = (void *)chunk_base; + size -= slide_block_size; + } + + /* verify no underflow */ + if (size > original_size) + panic("heap chunk size underflowed"); + + /* need room for the front and back sentinels, plus + the actual free memory block */ + if (size <= 3 * sizeof(struct heap_block)) + panic("heap chunk too small"); + + /* build out the chunk */ + lead[chunk_count].chunk_base = chunk; + lead[chunk_count].chunk_size = size; + chunk_count++; + + /* front sentinel */ + front_sentinel = chunk; + front_sentinel->prev_free = 0; + front_sentinel->this_free = 0; + front_sentinel->prev_size = 0; + front_sentinel->this_size = 1; + front_sentinel->padding_bytes = 0; + calculate_block_checksum(front_sentinel); + + /* free space */ + slab = next_block(front_sentinel); + slab->prev_free = 0; + slab->this_free = 0; + slab->prev_size = 1; + slab->this_size = quantify_size(size) - 2; + slab->padding_bytes = 0; + calculate_block_checksum(slab); + + /* back sentinel */ + back_sentinel = next_block(slab); + back_sentinel->prev_free = 0; + back_sentinel->this_free = 0; + back_sentinel->prev_size = slab->this_size; + back_sentinel->this_size = 1; + back_sentinel->padding_bytes = 0; + calculate_block_checksum(back_sentinel); + + /* free the free space back into the heap */ + heap_free(slab + 1); +} + +void +heap_set_cookie(uint8_t *cookie) +{ + RELEASE_ASSERT(!heap_is_initialized()); + memcpy(g_heap_cookie, cookie, sizeof(g_heap_cookie)); +} + +u_int32_t +heap_get_free_mem(void) +{ + return free_mem; +} + +bool +heap_is_initialized(void) +{ + return (chunk_count != 0); +} + +static +int +heap_walk(heap_walker_f *walker, void *cookie) +{ + int retval, chunk; + struct heap_block *iter; + struct walker_info_t winfo; + + retval = 0; + + for (chunk = 0; chunk < chunk_count; chunk++) { + + iter = next_block(lead[chunk].chunk_base); + + while (iter && (retval >= 0)) { + + if (iter->this_free) { + winfo.block_type = HEAP_BLOCK__FREE; + winfo.extended_info = 0; + } else if (iter->this_size == 1) { + /* only sentinels can have size 1 */ + winfo.block_type = HEAP_BLOCK__SENTINEL; + winfo.extended_info = 0; + } else { + /* assume malloc for now */ + winfo.block_type = HEAP_BLOCK__MALLOC; + winfo.extended_info = HEAP_DEBUGGING; + } + winfo.raw_block = iter; + winfo.block_size = sizeof_block(iter); + + + if (winfo.block_type == HEAP_BLOCK__MALLOC) { + winfo.user_block = iter + 1; + winfo.user_size = sizeof_block(iter) - sizeof(struct heap_block); + winfo.timestamp = 0; + } + + if (HEAP_DEBUGGING && (winfo.block_type == HEAP_BLOCK__MALLOC)) { + size_t size_d; + struct client_data *client; + + size_d = round_size(sizeof(struct client_data)); + + client = recess_pointer(next_block(iter), size_d); + + winfo.block_type = client->block_type; + winfo.user_size = client->user_size; + winfo.timestamp = client->timestamp; + winfo.requestor = client->requestor; + winfo.alignment = client->alignment; + } + + if (winfo.block_type == HEAP_BLOCK__SENTINEL) { + /* just in case some idiotic user modifies winfo, update loop iterator before calling */ + iter = 0; + } else { + iter = next_block(iter); + } + retval = walker(cookie, &winfo); + } + } + + return 0; +} + +static +int +heap_verify_callback(void *cookie, struct walker_info_t const *info) +{ + struct heap_block *b = info->raw_block; + verify_block_checksum(b); + + // if the block is not free and not a sentinel, it needs to + // have valid padding + if (!b->this_free && b->this_size > 1) { + verify_block_padding(b); + } + + return 0; +} + +void +heap_verify(void) +{ + heap_walk(heap_verify_callback, NULL); +} + +#if HEAP_CHECKS +static +void +heap_panic(char const *func, const void *block, const char *reason) +{ + if (HEAP_PANIC_CHECKS) { + panic("%s: heap error: block %p, %s\n", func, block, reason); + } else { + printf("%s: heap error: %s : please enable HEAP_PANIC_CHECKS\n", func, reason); + } +} +#endif + +#if DEBUG_BUILD || HEAP_ERROR_DUMP +struct malloc_summary { + uint32_t bytes_allocated; + uint32_t bytes_free; + uint32_t allocations; +}; + +static int heap_dump_callback(void *cookie, struct walker_info_t const *info) +{ + struct malloc_summary *summary; + + summary = (struct malloc_summary *)cookie; + summary->allocations++; + + switch (info->block_type) { + case HEAP_BLOCK__FREE: + printf(" %p 0x%zx (free)\n", info->raw_block, info->block_size); + summary->bytes_free += info->block_size; + break; + case HEAP_BLOCK__MALLOC: + printf(" %p 0x%zx malloc @ %p", info->raw_block, info->block_size, info->user_block); + if (info->extended_info) { + printf(" size 0x%zx time %llu requestor %p\n", + info->user_size, info->timestamp, info->requestor); + } + printf("\n"); + summary->bytes_allocated += info->block_size; + break; + case HEAP_BLOCK__MEMALIGN: + printf(" %p 0x%zx aligned @ %p", info->raw_block, info->block_size, info->user_block); + if (info->extended_info) { + printf(" alignment 0x%zx size 0x%zx time %llu requestor %p\n", + info->alignment, info->user_size, info->timestamp, info->requestor); + } + printf("\n"); + summary->bytes_allocated += info->block_size; + break; + case HEAP_BLOCK__SENTINEL: + break; + default: + break; + } + return(0); +} + +/* dump the heap */ +static void heap_dump(void) +{ + struct malloc_summary summary; + + summary.bytes_allocated = 0; + summary.bytes_free = 0; + summary.allocations = 0; + + printf("dumping heap\n"); + + heap_walk(heap_dump_callback, (void *)&summary); + + printf("%d allocations totalling %d bytes in use, %d bytes free\n", + summary.allocations, summary.bytes_allocated, summary.bytes_free); +} +#endif // + +#if DEBUG_BUILD +/* dump the heap */ +int do_malloc(int argc, struct cmd_arg *args) +{ + heap_dump(); + return(0); +} + +#endif // DEBUG_BUILD + diff --git a/lib/heap/libc_stub.c b/lib/heap/libc_stub.c new file mode 100644 index 0000000..723377f --- /dev/null +++ b/lib/heap/libc_stub.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +extern void* heap_malloc(size_t size, const char *caller_name); +extern void* heap_calloc(size_t count, size_t size, const char *caller_name); +extern void* heap_realloc(void *ptr, size_t size, const char *caller_name); +extern void heap_free(void *ptr); +extern void bzero(void *s, size_t n); +extern void* memcpy(void* dest, const void* src, size_t len); +extern void* memset(void* dest, int val, size_t len); + +/* Global stderrp definition */ +void* __stderrp = 0; + + +void* malloc(size_t size) +{ + return heap_malloc(size, NULL); +} + +void* realloc(void *ptr, size_t size) +{ + return heap_realloc(ptr, size, NULL); +} + +void* calloc(size_t count, size_t size) +{ + return heap_calloc(count, size, NULL); +} + +void free(void *ptr) +{ + heap_free(ptr); +} + +void* __memcpy_chk(void* dest, const void* src, size_t len, size_t destSize) +{ + memcpy(dest, src, (len > destSize) ? destSize : len); + return dest; +} + +void* __memset_chk(void* dest, int val, size_t len, size_t destSize) +{ + memset(dest, val, (len > destSize) ? destSize : len); + return dest; +} diff --git a/lib/heap/library.mk b/lib/heap/library.mk new file mode 100644 index 0000000..c29d659 --- /dev/null +++ b/lib/heap/library.mk @@ -0,0 +1,28 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBHEAP_DIR := $(GET_LOCAL_DIR) +LIBHEAP_BUILD := $(call TOLIBDIR,$(LIBHEAP_DIR)/LIBHEAP.a) +COMMONLIBS += LIBHEAP + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBHEAP_OBJS := $(LIBHEAP_DIR)/heap.o \ + $(LIBHEAP_DIR)/libc_stub.o + +LIBHEAP_OBJS := $(call TOLIBOBJDIR,$(LIBHEAP_OBJS)) + +ALL_DEPS += $(LIBHEAP_OBJS:%o=%d) + +$(LIBHEAP_BUILD): $(LIBHEAP_OBJS) + +endif diff --git a/lib/heap/rules.mk b/lib/heap/rules.mk new file mode 100644 index 0000000..c50cc91 --- /dev/null +++ b/lib/heap/rules.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +MODULES += lib/cksum +LIBRARY_MODULES += lib/heap + diff --git a/lib/heap/tests-common.mk b/lib/heap/tests-common.mk new file mode 100644 index 0000000..27ada90 --- /dev/null +++ b/lib/heap/tests-common.mk @@ -0,0 +1,23 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_OBJS := \ + $(LOCAL_DIR)/heap.o \ + lib/cksum/siphash.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + tests/mocks/sys/lock.o \ + $(LOCAL_DIR)/tests.o + +TEST_CFLAGS := \ + -DHEAP_UNITTEST=1 diff --git a/lib/heap/tests-debugging.mk b/lib/heap/tests-debugging.mk new file mode 100644 index 0000000..e100ee7 --- /dev/null +++ b/lib/heap/tests-debugging.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := heap-debugging + +include $(LOCAL_DIR)/tests-common.mk + +TEST_CFLAGS += \ + -DHEAP_DEBUGGING=1 diff --git a/lib/heap/tests.c b/lib/heap/tests.c new file mode 100644 index 0000000..cddf252 --- /dev/null +++ b/lib/heap/tests.c @@ -0,0 +1,856 @@ +#include +#include +#include +#include +#include + +void *heap_arena; + +#define HEAP_BLOCK_SIZE 64 + +#if !HEAP_DEBUGGING + #define HEAP_OVERHEAD (3 * HEAP_BLOCK_SIZE) +#else + #define HEAP_OVERHEAD (4 * HEAP_BLOCK_SIZE) +#endif + +void test_heap_setup_func(void) +{ + extern void heap_reinit(void); + heap_reinit(); +} + +void test_heap_cleanup_func(void) +{ + free(heap_arena); + heap_arena = NULL; +} + +void test_heap_setup_arena(size_t size) +{ + TEST_ASSERT_NULL(heap_arena); + + posix_memalign(&heap_arena, HEAP_BLOCK_SIZE, size); + TEST_ASSERT_NOT_NULL(heap_arena); +} + +void test_heap_add_chunk_size(uintptr_t param) +{ + size_t size = (size_t)param; + + test_heap_setup_arena(param); + + TEST_EXPECT_PANIC(); + + heap_add_chunk(heap_arena, size, true); + + TEST_EXPECT_PANICKED(); +} + +void test_heap_malloc_before_add(uintptr_t param) +{ + TEST_EXPECT_PANIC(); + + heap_malloc(1, ""); + + TEST_EXPECT_PANICKED(); +} + +void test_heap_malloc_too_much1(uintptr_t param) +{ + test_heap_setup_arena(param); + + tprintf(TEST_SPEW, "Adding initial chunk to heap"); + heap_add_chunk(heap_arena, param, true); + tprintf(TEST_SPEW, "Done adding initial chunk to heap"); + + TEST_EXPECT_PANIC(); + // Asking for the size of the heap area should always be a panic + // because of overhead + heap_malloc((size_t)param, ""); + TEST_EXPECT_PANICKED(); +} + +void test_heap_malloc_too_much2(uintptr_t param) +{ + test_heap_setup_arena(param); + heap_add_chunk(heap_arena, param, true); + + TEST_EXPECT_PANIC(); + // This should be just enough to cause an overflow + heap_malloc((size_t)param - HEAP_OVERHEAD + 1, ""); + TEST_EXPECT_PANICKED(); +} + +void test_heap_malloc_too_much3(uintptr_t param) +{ + test_heap_setup_arena(param); + heap_add_chunk(heap_arena, param, true); + + TEST_EXPECT_PANIC(); + heap_malloc(SIZE_MAX, ""); + TEST_EXPECT_PANICKED(); +} + +void test_heap_malloc_too_much4(uintptr_t param) +{ + test_heap_setup_arena(param); + heap_add_chunk(heap_arena, param, true); + + TEST_EXPECT_PANIC(); + heap_malloc(SIZE_MAX - 2 * HEAP_BLOCK_SIZE, ""); + TEST_EXPECT_PANICKED(); +} + +void test_heap_malloc_double_free(uintptr_t param) +{ + void *ptr; + + test_heap_setup_arena(0x1000); + heap_add_chunk(heap_arena, 0x1000, true); + + ptr = heap_malloc(0x100, ""); + heap_free(ptr); + + TEST_EXPECT_PANIC(); + heap_free(ptr); + TEST_EXPECT_PANICKED(); +} + +void test_heap_free_null(uintptr_t param) +{ + test_heap_setup_arena(0x1000); + heap_add_chunk(heap_arena, 0x1000, true); + + heap_free(NULL); + + heap_verify(); +} + +void test_heap_malloc_then_free(uintptr_t param) +{ + uint32_t free_mem; + size_t size; + void *ptr; + + test_heap_setup_arena(param); + heap_add_chunk(heap_arena, param, true); + + free_mem = heap_get_free_mem(); + + size = free_mem - HEAP_OVERHEAD; + + ptr = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr); + memset(ptr, 0xff, size); + + heap_free(ptr); + + TEST_ASSERT_EQ(heap_get_free_mem(), free_mem); + + heap_verify(); +} + +void test_heap_malloc_then_free2(uintptr_t param) +{ + uint32_t free_mem; + void *ptr[2]; + size_t size; + + test_heap_setup_arena(param); + heap_add_chunk(heap_arena, param, true); + + free_mem = heap_get_free_mem(); + + size = free_mem / 2 - HEAP_OVERHEAD; + + ptr[0] = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr[0]); + ptr[1] = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr[1]); + + memset(ptr[0], 0xff, size); + memset(ptr[1], 0xff, size); + + heap_free(ptr[0]); + heap_free(ptr[1]); + + TEST_ASSERT_EQ(heap_get_free_mem(), free_mem); + + ptr[0] = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr[0]); + ptr[1] = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr[1]); + + memset(ptr[0], 0xff, size); + memset(ptr[1], 0xff, size); + + heap_free(ptr[1]); + heap_free(ptr[0]); + + TEST_ASSERT_EQ(heap_get_free_mem(), free_mem); + + heap_verify(); +} + +void test_heap_malloc_then_free3(uintptr_t param) +{ + uint32_t free_mem; + void *ptrs[4]; + + if (param <= 4 * HEAP_OVERHEAD) + param += 4 * HEAP_OVERHEAD; + + test_heap_setup_arena(param); + heap_add_chunk(heap_arena, param, true); + + free_mem = heap_get_free_mem(); + + for (unsigned i = 0; i < 4; i++) { + size_t size = free_mem / 4 - HEAP_OVERHEAD; + ptrs[i] = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptrs[i]); + + memset(ptrs[i], 0xff, size); + } + + heap_free(ptrs[1]); + heap_free(ptrs[3]); + heap_free(ptrs[0]); + heap_free(ptrs[2]); + + TEST_ASSERT_EQ(heap_get_free_mem(), free_mem); + + heap_verify(); +} + +void test_heap_calloc(uintptr_t context) +{ + uint32_t *ptr; + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_calloc(sizeof(uint32_t), 0x1000, ""); + + for (unsigned i = 0; i < 0x1000; i++) + TEST_ASSERT_EQ(ptr[i], 0); + + heap_free(ptr); + + heap_verify(); +} + +void test_heap_calloc_overflow(uintptr_t context) +{ + uint32_t *ptr; + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + TEST_EXPECT_PANIC(); + + ptr = heap_calloc(0x10000, 0x10000, ""); + + TEST_EXPECT_PANICKED(); +} + +void test_heap_realloc(uintptr_t context) +{ + uint32_t *filler; + void *ptr1; + void *ptr2; + size_t initial_free_mem; + size_t size = 0x1000; + size_t arena_size = 0x10000; + + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + initial_free_mem = heap_get_free_mem(); + + // reallocing NULL should be just like malloc + ptr1 = heap_realloc(NULL, size, ""); + TEST_ASSERT_NOT_NULL(ptr1); + memset(ptr1, 0x55, size); + heap_free(ptr1); + + // generate some data to verify copy + filler = malloc(size); + TEST_ASSERT_NOT_NULL(filler); + for (size_t i = 0; i < size / sizeof(*filler); i++) + filler[i] = i; + + ptr1 = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr1); + memcpy(ptr1, filler, size); + + ptr2 = heap_realloc(ptr1, size * 2, ""); + TEST_ASSERT_NOT_NULL(ptr2); + + TEST_ASSERT_MEM_EQ(ptr2, filler, size); + + free(filler); + + heap_free(ptr2); + + heap_verify(); + + TEST_ASSERT_EQ(heap_get_free_mem(), initial_free_mem); + + // double freeing realloced pointer should be an error + TEST_EXPECT_PANIC(); + heap_free(ptr1); + TEST_EXPECT_PANICKED(); +} + +void test_heap_realloc_smaller(uintptr_t context) +{ + size_t size = 0x1800; + size_t arena_size = 0x10000; + size_t initial_free_mem; + void *ptr; + + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + initial_free_mem = heap_get_free_mem(); + + ptr = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr); + + heap_verify(); + + ptr = heap_realloc(ptr, size - 0x800, ""); + TEST_ASSERT_NOT_NULL(ptr); + + heap_verify(); + + ptr = heap_realloc(ptr, size + 0x400, ""); + TEST_ASSERT_NOT_NULL(ptr); + + heap_verify(); + + heap_free(ptr); + + TEST_ASSERT_EQ(heap_get_free_mem(), initial_free_mem); +} + +#if !HEAP_DEBUGGING +void test_heap_realloc_corruption(uintptr_t context) +{ + size_t size = 0x1000; + size_t arena_size = 0x10000; + uint8_t *ptr; + + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr); + + heap_verify(); + + ptr[size + 1] ^= 1; + + TEST_EXPECT_PANIC(); + ptr = heap_realloc(ptr, size * 4, ""); + TEST_EXPECT_PANICKED(); +} +#endif + +void test_heap_realloc_corruption2(uintptr_t context) +{ + size_t size = 0x1000; + size_t arena_size = 0x10000; + uint8_t *ptr; + + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_malloc(size, ""); + TEST_ASSERT_NOT_NULL(ptr); + + heap_verify(); + + ptr[-1] ^= 1; + + TEST_EXPECT_PANIC(); + ptr = heap_realloc(ptr, size, ""); + TEST_EXPECT_PANICKED(); +} + +void test_heap_realloc_odd(uintptr_t context) +{ + uint32_t *filler; + void *ptr1; + void *ptr2; + + size_t size_start = 0x1000 - 32; + size_t size_end = 0x1000 + 32; + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + // generate some data to verify copy + filler = malloc(size_end + 64); + TEST_ASSERT_NOT_NULL(filler); + for (size_t i = 0; i < (size_end + 64) / sizeof(*filler); i++) + filler[i] = i; + + for (size_t size = size_start; size <= size_end; size++) { + for (ssize_t adjust = -64; adjust <= 64; adjust++) { + ptr1 = heap_malloc(size + adjust, ""); + TEST_ASSERT_NOT_NULL(ptr1); + memcpy(ptr1, filler, size + adjust); + + ptr2 = heap_realloc(ptr1, size + adjust, ""); + TEST_ASSERT_NOT_NULL(ptr2); + TEST_ASSERT_MEM_EQ(ptr2, filler, adjust > 0 ? size : size + adjust); + + heap_free(ptr2); + } + } + + free(filler); + + heap_verify(); +} + +void test_heap_memalign(uintptr_t context) +{ + size_t arena_size; + void *ptr; + void *ptrs[4]; + void *filler; + + size_t alignments[] = { 0x10, 0x20, 0x40, 0x100, 0x1000 }; + size_t sizes[] = { 1, 0x10, 0x20, 0x40, 0x100, 0x1000, 0x10000, 0x100000 }; + + arena_size = 6 * 1024 * 1024; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + for (unsigned i = 0; i < sizeof(alignments) / sizeof(alignments[0]); i++) { + size_t alignment = alignments[i]; + tprintf(TEST_INFO, "%s: alignment 0x%zx\n", __FUNCTION__, alignment); + for (unsigned j = 0; j < sizeof(sizes) / sizeof(sizes[0]); j++) { + size_t size = sizes[j]; + tprintf(TEST_INFO, "%s: size 0x%zx\n", __FUNCTION__, size); + + // allocate a single aligned pointer, fill the buffer, then free it + ptr = NULL; + ptr = heap_memalign(size, alignment, ""); + TEST_ASSERT_NOT_NULL(ptr); + TEST_ASSERT_EQ((uintptr_t)ptr & (alignment - 1), 0); + memset(ptr, 0xff, size); + heap_free(ptr); + + filler = malloc(size); + TEST_ASSERT_NOT_NULL(filler); + + // allocate four alignment pointers + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + ptrs[k] = heap_memalign(size, alignment, ""); + TEST_ASSERT_NOT_NULL(ptrs[k]); + TEST_ASSERT_EQ((uintptr_t)ptrs[k] & (alignment - 1), 0); + } + + // fill each buffer + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + memset(filler, k + 1, size); + memcpy(ptrs[k], filler, size); + } + + + // make sure each buffer has the expected contents + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + memset(filler, k + 1, size); + TEST_ASSERT_MEM_EQ((uint8_t *)ptrs[k], filler, size); + } + + // and then free all the buffers + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + heap_free(ptrs[k]); + } + + free(filler); + filler = NULL; + } + } + + heap_verify(); +} + + +void test_heap_memalign_bad_align(uintptr_t param) +{ + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + TEST_EXPECT_PANIC(); + heap_memalign(0x1000, 31, ""); + TEST_EXPECT_PANICKED(); +} + + +void test_heap_memalign_too_much(uintptr_t param) +{ + size_t arena_size = 0x12000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + TEST_EXPECT_PANIC(); + // size looks fine, but alignment is more than the size of the heap + heap_memalign(0x1000, 0x10000, ""); + heap_memalign(0x1000, 0x10000, ""); + TEST_EXPECT_PANICKED(); +} + +void test_heap_posix_memalign(uintptr_t param) +{ + size_t arena_size; + void *ptr; + void *ptrs[4]; + void *filler; + + size_t alignments[] = { 0x10, 0x20, 0x40, 0x100, 0x1000 }; + size_t sizes[] = { 1, 0x10, 0x20, 0x40, 0x100, 0x1000, 0x10000, 0x100000 }; + + arena_size = 6 * 1024 * 1024; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + for (unsigned i = 0; i < sizeof(alignments) / sizeof(alignments[0]); i++) { + size_t alignment = alignments[i]; + tprintf(TEST_INFO, "%s: alignment 0x%zx\n", __FUNCTION__, alignment); + for (unsigned j = 0; j < sizeof(sizes) / sizeof(sizes[0]); j++) { + size_t size = sizes[j]; + tprintf(TEST_INFO, "%s: size 0x%zx\n", __FUNCTION__, size); + + // allocate a single aligned pointer, fill the buffer, then free it + ptr = NULL; + TEST_ASSERT_EQ(heap_posix_memalign(&ptr, alignment, size, ""), 0); + TEST_ASSERT_NOT_NULL(ptr); + TEST_ASSERT_EQ((uintptr_t)ptr & (alignment - 1), 0); + memset(ptr, 0xff, size); + heap_free(ptr); + + filler = malloc(size); + TEST_ASSERT_NOT_NULL(filler); + + // allocate four alignment pointers + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + TEST_ASSERT_EQ(heap_posix_memalign(&ptrs[k], alignment, size, ""), 0); + TEST_ASSERT_NOT_NULL(ptrs[k]); + TEST_ASSERT_EQ((uintptr_t)ptrs[k] & (alignment - 1), 0); + } + + // fill each buffer + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + memset(filler, k + 1, size); + memcpy(ptrs[k], filler, size); + } + + + // make sure each buffer has the expected contents + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + memset(filler, k + 1, size); + TEST_ASSERT_MEM_EQ((uint8_t *)ptrs[k], filler, size); + } + + // and then free all the buffers + for (unsigned k = 0; k < sizeof(ptrs) / sizeof(ptrs[0]); k++) { + heap_free(ptrs[k]); + } + + free(filler); + filler = NULL; + } + } + + heap_verify(); +} + +void test_heap_posix_memalign_bad_align(uintptr_t param) +{ + void *ptr; + + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + TEST_EXPECT_PANIC(); + heap_posix_memalign(&ptr, 31, 0x1000, ""); + TEST_EXPECT_PANICKED(); +} + + +void test_heap_posix_memalign_too_much(uintptr_t param) +{ + void *ptr; + + size_t arena_size = 0x12000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + TEST_EXPECT_PANIC(); + // size looks fine, but alignment is more than the size of the heap + heap_posix_memalign(&ptr, 0x10000, 0x1000, ""); + heap_posix_memalign(&ptr, 0x10000, 0x1000, ""); + TEST_EXPECT_PANICKED(); +} + +void test_heap_corruption(uintptr_t param) +{ + uint8_t *ptr; + + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_malloc(0x100, ""); + ptr[0x100 + param] ^= 1; + + TEST_EXPECT_PANIC(); + heap_free(ptr); + TEST_EXPECT_PANICKED(); +} + +void test_heap_corruption_pad(uintptr_t param) +{ + uint8_t *ptr; + + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_malloc(0x101, ""); + ptr[0x101 + param] ^= 1; + + TEST_EXPECT_PANIC(); + heap_free(ptr); + TEST_EXPECT_PANICKED(); +} + +void test_heap_corruption_pad2(uintptr_t param) +{ + uint8_t *ptr; + + size_t arena_size = 0x10000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_malloc(0xFF, ""); + ptr[0xFF] ^= 1; + + TEST_EXPECT_PANIC(); + heap_free(ptr); + TEST_EXPECT_PANICKED(); +} + +void test_heap_verify(uintptr_t param) +{ + void *ptr; + void *ptrs[500]; + + size_t arena_size = 0x100000; + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_calloc(1, 1, ""); + TEST_ASSERT_NOT_NULL(ptr); + + ptr = heap_calloc(31, 1, ""); + TEST_ASSERT_NOT_NULL(ptr); + + heap_verify(); + + ptr = heap_calloc(0x81, 1, ""); + TEST_ASSERT_NOT_NULL(ptr); + + heap_verify(); + + ptr = heap_calloc(0x1000, 1, ""); + TEST_ASSERT_NOT_NULL(ptr); + heap_free(ptr); + + heap_verify(); + + for (unsigned i = 0; i < sizeof(ptrs) / sizeof(ptrs[0]); i++) { + ptrs[i] = heap_calloc(0x100, 1, ""); + TEST_ASSERT_NOT_NULL(ptrs[i]); + } + + heap_verify(); + + for (unsigned i = 0; i < sizeof(ptrs) / sizeof(ptrs[0]); i += 2) { + heap_free(ptrs[i]); + } + + heap_verify(); + + for (unsigned i = 0; i < sizeof(ptrs) / sizeof(ptrs[0]); i += 2) { + ptrs[i] = heap_calloc(1, 1, ""); + TEST_ASSERT_NOT_NULL(ptrs[i]); + } + + heap_verify(); + + for (unsigned i = 0; i < sizeof(ptrs) / sizeof(ptrs[0]); i++) { + heap_free(ptrs[i]); + } + + heap_verify(); +} + +void test_heap_slide_large(uintptr_t param) +{ + void *ptr; + size_t arena_size = 0x600000; + uintptr_t heap_arena_calculated_offset; + + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_calloc(1, 1, ""); + TEST_ASSERT_NOT_NULL(ptr); + + /* we have 2 sentinel blocks of 64 bytes each. */ + heap_arena_calculated_offset = (uintptr_t)heap_arena + (HEAP_BLOCK_SIZE * 2); + + TEST_ASSERT_EQ(((uintptr_t)ptr != heap_arena_calculated_offset), true); +} + +void test_heap_slide_small(uintptr_t param) +{ + void *ptr; + size_t arena_size = 0x100000; + uintptr_t heap_arena_calculated_offset; + + test_heap_setup_arena(arena_size); + heap_add_chunk(heap_arena, arena_size, true); + + ptr = heap_calloc(1, 1, ""); + TEST_ASSERT_NOT_NULL(ptr); + + /* we have 2 sentinel blocks of 64 bytes each. */ + heap_arena_calculated_offset = (uintptr_t)heap_arena + (HEAP_BLOCK_SIZE * 2); + + TEST_ASSERT_EQ(((uintptr_t)ptr == heap_arena_calculated_offset), true); +} + +static struct test_suite heap_test_suite = { + .name = "heap", + .description = "tests the heap malloc implementation", + .setup_function = test_heap_setup_func, + .cleanup_function = test_heap_cleanup_func, + .test_cases = { + { "chunk_too_small0", test_heap_add_chunk_size, 0 }, + { "chunk_too_small1", test_heap_add_chunk_size, 1 }, + { "chunk_too_small32", test_heap_add_chunk_size, 32 }, + { "chunk_too_small_almost", test_heap_add_chunk_size, 3 * HEAP_BLOCK_SIZE }, + { "malloc_before_add", test_heap_malloc_before_add, 0 }, + { "malloc_too_much1,1k", test_heap_malloc_too_much1, 1024 }, + { "malloc_too_much1,4k", test_heap_malloc_too_much1, 4 * 1024 }, + { "malloc_too_much1,1m", test_heap_malloc_too_much1, 1024 * 1024 }, + { "malloc_too_much2,1k", test_heap_malloc_too_much2, 1024 }, + { "malloc_too_much2,4k", test_heap_malloc_too_much2, 4 * 1024 }, + { "malloc_too_much2,1m", test_heap_malloc_too_much2, 1024 * 1024 }, + { "malloc_too_much3,1k", test_heap_malloc_too_much3, 1024 }, + { "malloc_too_much3,4k", test_heap_malloc_too_much3, 4 * 1024 }, + { "malloc_too_much3,1m", test_heap_malloc_too_much3, 1024 * 1024 }, + { "malloc_too_much4,1k", test_heap_malloc_too_much4, 1024 }, + { "malloc_too_much4,4k", test_heap_malloc_too_much4, 4 * 1024 }, + { "malloc_too_much4,1m", test_heap_malloc_too_much4, 1024 * 1024 }, + { "malloc_double_free", test_heap_malloc_double_free }, + { "free_null", test_heap_free_null }, + { "malloc_then_free,1k", test_heap_malloc_then_free, 1024 }, + { "malloc_then_free,4k", test_heap_malloc_then_free, 4 * 1024 }, + { "malloc_then_free,1m", test_heap_malloc_then_free, 1024 * 1024 }, + { "malloc_then_free2,1k", test_heap_malloc_then_free2, 1024 }, + { "malloc_then_free2,4k", test_heap_malloc_then_free2, 4 * 1024 }, + { "malloc_then_free2,1m", test_heap_malloc_then_free2, 1024 * 1024 }, + { "malloc_then_free3,1k", test_heap_malloc_then_free3, 1024 }, + { "malloc_then_free3,4k", test_heap_malloc_then_free3, 4 * 1024 }, + { "malloc_then_free3,1m", test_heap_malloc_then_free3, 1024 * 1024 }, + { "calloc", test_heap_calloc }, + { "calloc_overflow", test_heap_calloc_overflow }, + { "realloc", test_heap_realloc }, + { "realloc_smaller", test_heap_realloc_smaller }, + { "realloc_corruption2", test_heap_realloc_corruption2 }, + { "realloc_odd", test_heap_realloc_odd }, + { "memalign", test_heap_memalign }, + { "posix_memalign", test_heap_posix_memalign }, + { "posix_memalign_bad_align", test_heap_posix_memalign_bad_align }, + { "posix_memalign_too_much", test_heap_posix_memalign_too_much }, + // the offsets provided by these tests make some assumptions + // about sizeof(size_t) and CPU_CACHELINE_SIZE and assume no debug data +#if !HEAP_DEBUGGING + { "heap_corruption,0", test_heap_corruption, 0 }, + { "heap_corruption,1", test_heap_corruption, 1 }, + { "heap_corruption,2", test_heap_corruption, 2 }, + { "heap_corruption,3", test_heap_corruption, 3 }, + { "heap_corruption,4", test_heap_corruption, 4 }, + { "heap_corruption,5", test_heap_corruption, 5 }, + { "heap_corruption,6", test_heap_corruption, 6 }, + { "heap_corruption,7", test_heap_corruption, 7 }, + { "heap_corruption,8", test_heap_corruption, 8 }, + { "heap_corruption,9", test_heap_corruption, 9 }, + { "heap_corruption,10", test_heap_corruption, 10 }, + { "heap_corruption,11", test_heap_corruption, 11 }, + { "heap_corruption,12", test_heap_corruption, 12 }, + { "heap_corruption,13", test_heap_corruption, 13 }, + { "heap_corruption,14", test_heap_corruption, 14 }, + { "heap_corruption,15", test_heap_corruption, 15 }, + { "heap_corruption,16", test_heap_corruption, 16 }, + { "heap_corruption,17", test_heap_corruption, 17 }, + { "heap_corruption,18", test_heap_corruption, 18 }, + { "heap_corruption,19", test_heap_corruption, 19 }, + { "heap_corruption,20", test_heap_corruption, 20 }, + { "heap_corruption,21", test_heap_corruption, 21 }, + { "heap_corruption,22", test_heap_corruption, 22 }, + { "heap_corruption,23", test_heap_corruption, 23 }, + { "heap_corruption,32", test_heap_corruption, 32 }, + { "heap_corruption,33", test_heap_corruption, 33 }, + { "heap_corruption,34", test_heap_corruption, 34 }, + { "heap_corruption,35", test_heap_corruption, 35 }, + { "heap_corruption,36", test_heap_corruption, 36 }, + { "heap_corruption,37", test_heap_corruption, 37 }, + { "heap_corruption,38", test_heap_corruption, 38 }, + { "heap_corruption,39", test_heap_corruption, 39 }, + { "heap_corruption,40", test_heap_corruption, 40 }, + { "heap_corruption,41", test_heap_corruption, 41 }, + { "heap_corruption,42", test_heap_corruption, 42 }, + { "heap_corruption,43", test_heap_corruption, 43 }, + { "heap_corruption,44", test_heap_corruption, 44 }, + { "heap_corruption,45", test_heap_corruption, 45 }, + { "heap_corruption,46", test_heap_corruption, 46 }, + { "heap_corruption,47", test_heap_corruption, 47 }, + { "realloc_corruption", test_heap_realloc_corruption }, +#endif + { "heap_corruption_pad,0", test_heap_corruption_pad, 0 }, + { "heap_corruption_pad,1", test_heap_corruption_pad, 1 }, + { "heap_corruption_pad,2", test_heap_corruption_pad, 2 }, + { "heap_corruption_pad,3", test_heap_corruption_pad, 3 }, + { "heap_corruption_pad,4", test_heap_corruption_pad, 4 }, + { "heap_corruption_pad,5", test_heap_corruption_pad, 5 }, + { "heap_corruption_pad,6", test_heap_corruption_pad, 6 }, + { "heap_corruption_pad,7", test_heap_corruption_pad, 7 }, + { "heap_corruption_pad,8", test_heap_corruption_pad, 8 }, + { "heap_corruption_pad,31", test_heap_corruption_pad, 31 }, + { "heap_corruption_pad2", test_heap_corruption_pad2 }, + { "heap_verify", test_heap_verify }, + { "heap_slide_large", test_heap_slide_large }, + { "heap_slide_small", test_heap_slide_small }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(heap_test_suite); + +// for when debugging is enabled +utime_t system_time() +{ + return 0; +} diff --git a/lib/heap/tests.mk b/lib/heap/tests.mk new file mode 100644 index 0000000..b89ef00 --- /dev/null +++ b/lib/heap/tests.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := heap + +include $(LOCAL_DIR)/tests-common.mk + +TEST_CFLAGS += \ + -DHEAP_DEBUGGING=1 diff --git a/lib/image/debug.c b/lib/image/debug.c new file mode 100644 index 0000000..ca2a908 --- /dev/null +++ b/lib/image/debug.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +static int do_image(int argc, struct cmd_arg *args) +{ + + bool detailed; + int ret_val; + + if (argc < 2) { + printf("not enough arguments.\n"); + usage: + printf("%s list []\n", args[0].str); + printf("%s load [|memory] [
]\n", args[0].str); + return -1; + } + + if (!strcmp("list", args[1].str)) { + if (argc > 2) + detailed = true; + else + detailed = false; + image_dump_list(detailed); + } else if (!strcmp("load", args[1].str)) { + struct image_info *image; + addr_t source_address; + size_t filesize; + void *addr; + size_t len = 0xFFFFFFFF; + u_int32_t type; + u_int32_t *types = NULL; /* default to any image type */ + u_int32_t count = 0; + + if (argc < 3) { + printf("not enough arguments.\n"); + goto usage; + } + + if (!strcmp(args[2].str, "memory")) { + /* load image from memory */ + + source_address = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + filesize = env_get_uint("filesize", DEFAULT_KERNEL_SIZE); + + if ((image = image_create_from_memory((void *)source_address, filesize, 0)) == NULL) { + printf("image creation failed\n"); + return -1; + } + } else { + /* search for image */ + + type = htonl(*(uint32_t *)args[2].str); + + image = image_find(type); + if (!image) { + printf("could not find image\n"); + return -1; + } + + /* use the image type since it is known */ + types = &type; + count = 1; + } + + if (argc < 4) + addr = (void *)DEFAULT_KERNEL_ADDRESS; + else + addr = (void *)args[3].u; + + ret_val = image_load(image, types, count, NULL, &addr, &len); + if ( 0 <= ret_val ) + printf("successfully loaded image\n"); + else + printf("unable to load image\n"); + } else { + printf("unrecognized command.\n"); + goto usage; + } + + return 0; +} + +MENU_COMMAND_DEBUG(image, do_image, "flash image inspection", NULL); + +#if WITH_IMAGE4 + +static int do_image4_test(int argc, struct cmd_arg *args) +{ + int result = -1, i; + char file_path[FS_MAXPATHLEN]; + bool file_option = false; + u_int32_t image_type; + u_int32_t *image_types = NULL; + u_int32_t image_types_count = 0; + u_int32_t options = 0; + addr_t from_address, to_address = DEFAULT_KERNEL_ADDRESS; + size_t from_size, to_size = DEFAULT_LOAD_SIZE; + bool load_image_type = false; + + from_address = env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + from_size = env_get_uint("filesize", DEFAULT_LOAD_SIZE); + + for (i = 1; i < argc; i++) { + if (strcmp(args[i].str, "-options") == 0) { + options = args[++i].u; + } + else if (strcmp(args[i].str, "-type") == 0) { + image_type = htonl(*(uint32_t *)args[++i].str); + image_types = &image_type; + image_types_count = 1; + } + else if (strcmp(args[i].str, "-file") == 0) { + snprintf(file_path, FS_MAXPATHLEN, "/boot%s", args[++i].str); + file_option = true; + } + else if (strcmp(args[i].str, "-addr") == 0) { + from_address = args[++i].u; + } + else if (strcmp(args[i].str, "-size") == 0) { + from_size = args[++i].u; + } + else if (strcmp(args[i].str, "-load-type") == 0) { + load_image_type = true; + } + else { + goto print_usage; + } + } + + if (file_option) { +#if WITH_FS + result = mount_bootfs(); + if (result == 0) { + result = image_load_file(file_path, &to_address, &to_size, image_types, image_types_count, NULL, options); + fs_unmount("/boot"); + } + else { + dprintf(DEBUG_INFO, "root filesystem mount failed\n"); + } +#else + dprintf(DEBUG_INFO, "file-system support not available\n"); +#endif + } + else if (load_image_type) { + if (image_types_count != 0) + result = image_load_type(&to_address, &to_size, image_type, options); + else + dprintf(DEBUG_INFO, "image type not specified\n"); + } + else { + result = image_load_memory(from_address, from_size, &to_address, &to_size, image_types, image_types_count, NULL, options); + } + + if (result == 0) + dprintf(DEBUG_INFO, "image_load test succeed\n"); + else + dprintf(DEBUG_INFO, "image_load test failed, result:%d\n", result); + + security_restore_environment(); + + return result; + +print_usage: + dprintf(DEBUG_INFO, "image4_test [-file ] [-options ] [-type ] [-load-type] [-addr
] [-size ] [-help]\n"); + dprintf(DEBUG_INFO, "\t- address defaults to $loadadr and size defaults to $filesize\n"); + dprintf(DEBUG_INFO, "\t- load-type option loads image of type specified with '-type' option from nand_firmare partition\n"); + dprintf(DEBUG_INFO, "\t- list option list images stored in nand_firmare partition\n"); + dprintf(DEBUG_INFO, "\t- various options -> require_trust:(1<<1), local_storage:(1<<3), new_trust_chain:(1<<4) \n"); + dprintf(DEBUG_INFO, "\t- various types -> dtre, rdtr, krnl, rkrn, ibss, ibec, illb, ibot, rdsk, logo, rlgo, recm, diag, 0 (any) \n"); + return -1; +} + +MENU_COMMAND_DEBUG(image4_test, do_image4_test, "load and validate image4", NULL); + +#endif + +#endif diff --git a/lib/image/image.c b/lib/image/image.c new file mode 100644 index 0000000..39c6a68 --- /dev/null +++ b/lib/image/image.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_FS +#include +#include +#endif + +#if WITH_IMAGE3 +# include "image3/image3_wrapper.h" +#endif +#if WITH_IMAGE4 +# include "image4/image4_wrapper.h" +#endif + + +#define MAP_SIZE 512 + +#if WITH_IMAGE3 || WITH_IMAGE4 || WITH_ENV +static uint32_t image_version = 0; +#endif + +/* + * Look for a compatible image superblock in the supplied block device. + */ +int +image_search_bdev(struct blockdev *bdev, off_t map_offset, uint32_t imageOptions) +{ + int err; + void *buf = 0; + int images_found = 0; + + posix_memalign(&buf, CPU_CACHELINE_SIZE, MAP_SIZE); + + /* + * Read in the image superblock. + */ + err = blockdev_read(bdev, buf, map_offset, MAP_SIZE); + if (err != MAP_SIZE) + goto exit; + +#if WITH_IMAGE4 + if (images_found == 0) { + images_found = image4_process_superblock(buf, bdev, map_offset, imageOptions); + if (images_found) + image_version = 4; + } +#endif +#if WITH_IMAGE3 + if (images_found == 0) { + images_found = image3_process_superblock((Image2Superblock *)buf, bdev, map_offset, imageOptions); + if (images_found) + image_version = 3; + } +#endif + +#if WITH_ENV + if (image_version) + env_set_uint("image-version", image_version, 0); +#endif + +exit: + if (buf) + free(buf); + + return images_found; +} + +/* + * Free all images found by image_search_bdev(), above, for the specified bdev. + */ +void +image_free_bdev(struct blockdev *bdev) +{ +#if WITH_IMAGE4 + image4_free_bdev(bdev); +#endif +#if WITH_IMAGE3 + image3_free_bdev(bdev); +#endif +} + +/* + * Load an already-known image. + * + * This function is complicated by the desire to support multiple image formats + * at the same time. The logic for images of an unknown type being loaded from + * memory is that if configured, handlers should be tried in a canonical order, + * falling back to a previous version if the loader returns EINVAL. + */ +int +image_load(struct image_info *image, const u_int32_t *types, u_int32_t count, u_int32_t *actual, void **load_addr, size_t *load_len) +{ + void *addr = *load_addr; + size_t len = *load_len; + int ret_val = -1; + + if (NULL == image) + goto exit; + + if (image->imageAllocation > len) { + dprintf(DEBUG_CRITICAL, "image_load: image too large\n"); + platform_record_breadcrumb_int("image_load_pre_fail", kBCImgLoadImageTooLarge); + goto exit; + } + + if ((types == NULL) && (count != 0)) { + dprintf(DEBUG_CRITICAL, "image_load: count must be zero if types is NULL\n"); + platform_record_breadcrumb_int("image_load_pre_fail", kBCImgLoadCountNotZero); + goto exit; + } + + if ((count > 1) && (actual == NULL)) { + dprintf(DEBUG_CRITICAL, "image_load: actual must not be NULL when types has multiple values\n"); + platform_record_breadcrumb_int("image_load_pre_fail", kBCImgLoadCountIsZero); + goto exit; + } + + if (actual != NULL) { + *actual = IMAGE_TYPE_ANY; + } + + dprintf(DEBUG_INFO, "loading image with private magic %x\n", image->imagePrivateMagic); + switch (image->imagePrivateMagic) { +#if WITH_IMAGE4 + case IMAGE4_IMAGE_INFO_MAGIC: + ret_val = image4_load(image, types, count, actual, &addr, &len); + break; +#endif +#if WITH_IMAGE3 + case IMAGE3_IMAGE_INFO_MAGIC: + ret_val = image3_load(image, types, count, actual, &addr, &len); + break; +#endif + case IMAGE_MEMORY_INFO_MAGIC: + dprintf(DEBUG_INFO, "memory image\n"); +#if WITH_IMAGE4 + /* image4 is forgiving, try it first */ + dprintf(DEBUG_INFO, "trying image4\n"); + ret_val = image4_load(image, types, count, actual, &addr, &len); + if (ret_val == 0) { + /* good image4 image */ + break; + } + dprintf(DEBUG_INFO, "image4_load failed\n"); + + /* restore addr & len for next image format's try */ + addr = *load_addr; + len = *load_len; +#endif +#if WITH_IMAGE3 + /* image3 is forgiving, try it second */ + dprintf(DEBUG_INFO, "trying image3\n"); + ret_val = image3_load(image, types, count, actual, &addr, &len); + if (ret_val == 0) { + /* good image3 image */ + break; + } + dprintf(DEBUG_INFO, "image3_load failed\n"); + + /* restore addr & len for next image format's try */ + addr = *load_addr; + len = *load_len; +#endif +#if !(WITH_IMAGE3 || WITH_IMAGE4) + /* raw image */ + memcpy(addr, image->imagePrivate, len); + ret_val = 0; +#endif + break; + + default: + break; + } + +exit: + if (ret_val == 0) { + *load_addr = addr; + *load_len = len; + } else { + *load_addr = 0; + *load_len = 0; + + /* any value other than zero is an error, our callers expect -1 */ + ret_val = -1; + } + + return ret_val; +} + +void +image_dump_list(bool detailed) +{ +#if WITH_IMAGE4 + image4_dump_list(detailed); +#endif +#if WITH_IMAGE3 + image3_dump_list(detailed); +#endif +} + +/* + * Return a handle to the first instance of an image of (type) + */ +struct image_info * +image_find(u_int32_t type) +{ + struct image_info *image = 0; + +#if WITH_IMAGE4 + if (image == 0) image = image4_find(type); +#endif +#if WITH_IMAGE3 + if (image == 0) image = image3_find(type); +#endif + + return image; +} + +/* + * Create an image from a range of memory, rather than finding it on a bdev. + */ +struct image_info * +image_create_from_memory(void *address, size_t length, uint32_t imageOptions) +{ + struct image_info *image = NULL; + + image = malloc(sizeof(struct image_info)); + + image->imageLength = length; + image->imageAllocation = length; + image->imagePrivateMagic = IMAGE_MEMORY_INFO_MAGIC; + image->imageOptions = imageOptions; + image->imagePrivate = address; + + return image; +} + +#if WITH_FS +/* + * Load an image from a file. + */ +int +image_load_file(const char *path, addr_t *address, size_t *length, const u_int32_t *types, u_int32_t count, u_int32_t *actual, u_int32_t options) +{ + struct image_info *image; + int result; + + if (fs_load_file(path, DEFAULT_LOAD_ADDRESS, length)) + return(-1); + if (NULL == (image = image_create_from_memory((void *)DEFAULT_LOAD_ADDRESS, *length, options))) { + platform_record_breadcrumb_marker("ICFM-malloc-fail"); + return(-1); + } + result = image_load(image, types, count, actual, (void **)address, length); + image_free(image); + return(result); +} +#endif + +/* + * Load an image from a memory buffer. + */ +int +image_load_memory(addr_t fromAddress, size_t fromLength, addr_t *address, size_t *length, const u_int32_t *types, u_int32_t count, u_int32_t *actual, u_int32_t options) +{ + struct image_info *image; + int result; + + PROFILE_ENTER('ILM'); + + if (NULL == (image = image_create_from_memory((void *)fromAddress, fromLength, options))) + return(-1); + + result = image_load(image, types, count, actual, (void **)address, length); + image_free(image); + + PROFILE_EXIT('ILM'); + + return(result); +} + +/* + * Find and load an image of the given type from the default image device. + */ +int +image_load_type(addr_t *address, size_t *length, uint32_t type, uint32_t options) +{ + struct image_info *image; + + if (NULL == (image = image_find(type))) + return(-1); + + return(image_load(image, &type, 1, NULL, (void **)address, length)); +} + +/* + * Free an allocated image. + */ +void +image_free(struct image_info *image) +{ + if ((NULL != image) && (image->imagePrivateMagic == IMAGE_MEMORY_INFO_MAGIC)) { + free(image); + } +} diff --git a/lib/image/image3/Image3.c b/lib/image/image3/Image3.c new file mode 100644 index 0000000..ba2dd52 --- /dev/null +++ b/lib/image/image3/Image3.c @@ -0,0 +1,1319 @@ +/* + * Copyright (C) 2007-2011, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include "Image3.h" + +/* KERNEL is defined when building the AppleMobileFileIntegrityKext */ +#ifdef KERNEL + +#include +#include + +#else /* !KERNEL */ + +#ifdef IMAGE3_DEBUG +#include +#endif +#include +#include +#include + +#endif /* !KERNEL */ + +#include + +#ifndef __linux__ +#include +#else +#include +#endif + +#if (BYTE_ORDER == LITTLE_ENDIAN) +# define HTOLE(x) (x) +# define LETOH(x) (x) +# define HTOLELL(x) (x) +# define LETOHLL(x) (x) +#else +# include +# define HTOLE(x) OSSwapHostToLittleInt32(x) +# define LETOH(x) OSSwapLittleToHostInt32(x) +# define HTOLELL(x) OSSwapHostToLittleInt64(x) +# define LETOHLL(x) OSSwapLittleToHostInt64(x) +#endif + +#ifndef offsetof +#if defined(__GNUC__) +#define offsetof(t, d) __builtin_offsetof(t, d) +#else +#error need offsetof definition +#endif +#endif + +#ifdef IMAGE3_DEBUG +# ifdef KERNEL +# include +# else +# include +# endif +# define debug(fmt, args...) printf("I3:%s: " fmt "\n", __FUNCTION__ , ##args) +# define UNTAG(x) (((x) >> 24) & 0xff),(((x) >> 16) & 0xff),(((x) >> 8) & 0xff),((x) & 0xff) +#else +# define debug(fmt, args...) +#endif + +#include "Image3Format.h" + +#define IMAGE3_HASH_SIZE CCSHA1_OUTPUT_SIZE /* SHA-1 hash size */ + +/* + * Internal handle state + */ +typedef struct _Image3InternalState { + Image3ObjectHeader *image; + u_int32_t flags; +# define kImage3ImageWasInstantiated (1<<0) +# define kImage3ImageWasValidated (1<<1) /* validation has been performed */ +# define kImage3ImageIsTrusted (1<<2) /* validation indicates image is trusted */ +# define kImage3ImageWasCreated (1<<16) +# define kImage3ImageIsSigned (1<<17) /* signature has been appended */ +# define kImage3ImageWasAllocated (1<<18) + size_t allocSize; + +#ifdef IMAGE3_CREATOR + int cursor; + int lastTag; +#endif + + struct _Image3InternalState *nestedImage; +} Image3InternalState; + + +/* + * Discards an Image3 working object. + */ +extern void +image3Discard( + Image3ObjectHandle *withHandle) +{ + if (withHandle && *withHandle) { + if ((*withHandle)->image && ((*withHandle)->flags & kImage3ImageWasAllocated)) { + debug("discarding image %p", (*withHandle)->image); + image3Free((*withHandle)->image, (*withHandle)->allocSize); + } + debug("discarding handle %p", *withHandle); + image3Free(*withHandle, sizeof(Image3InternalState)); + *withHandle = NULL; + } +} + +#ifdef IMAGE3_CREATOR + +/* + * Create a new Image3 working object. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + */ +int +image3InstantiateNew( + Image3ObjectHandle *newHandle, + size_t initialAllocation, + u_int32_t imageType) +{ + Image3InternalState *state; + int result; + + if ((state = image3Malloc(sizeof(*state))) == NULL) + return(ENOMEM); + + if (initialAllocation < sizeof(Image3ObjectHeader)) + initialAllocation = sizeof(Image3ObjectHeader); + + if ((state->image = image3Malloc(initialAllocation)) == NULL) { + image3Free(state, sizeof(*state)); + return(ENOMEM); + } + debug("allocated handle %p and initial buffer %p of %u bytes", state, state->image, (unsigned int)initialAllocation); + + memset(state->image, 0, sizeof(*state->image)); + state->image->ihMagic = HTOLE(kImage3HeaderMagic); + state->image->ihType = HTOLE(imageType); + + state->allocSize = initialAllocation; + state->cursor = 0; + state->lastTag = -1; + state->flags = kImage3ImageWasAllocated; + state->nestedImage = NULL; + + /* + * Because of the issue described in rdar://problem/6705064, we need to stop embedding a TYPE tag within leaf certificates. + * (Essentially, the TYPE tag in the embbeded cert has precendence over the TYPE tag in the parent image, causing the + * parent image to assume the type of embdded image; i.e., the parent image type "becomes" 'cert'.) As a quick fix, we detect + * whether this new instantiation is for an embedded image by seeing if the requested imageType is for 'cert'. This + * saves plumbing in a new paramter/flag from the caller for now. + */ + if ((imageType != IMAGE_TYPE_EMBEDCERT) && ((result = image3SetTagUnsignedNumber(state, kImage3TagTypeType, imageType)) != 0)) { + image3Free(state->image, initialAllocation); + image3Free(state, sizeof(*state)); + return(result); + } + + *newHandle = state; + + return(0); +} + +/* + * Finalises an image. + * + * If signImage is set, hashes and signs the image. Reservation length, if non-zero, indicates that the final signed image + * will include tags not currently present in the image. A partial digest is computed, but the size of the reservation is + * required so that ihSignedLength can be set properly for inclusion in the partial hash state. The partial digest is + * constrained to conclude on a 64 byte boundary by adding the appropriate padding following the last tag in the signed portion + * of a finalised image. + * + * Returns: + * 0 Success + */ +int +image3Finalize( + const Image3ObjectHandle withHandle, + void **objectBuffer, + size_t *objectSize, + bool signImage, + size_t reservationSize) +{ + Image3ObjectHeader *hdr; + Image3PartialHash partialHash; + char normalHash[IMAGE3_HASH_SIZE]; + void *hashBuffer = NULL; + size_t hashBufferSize; + size_t hashSize; + int result; + void *signedHash; + size_t signedHashSize; + void *certChain; + size_t certChainSize; + size_t paddingSize; + bool createPartialHash = reservationSize != 0; + + debug("finalising %p", withHandle); + hdr = withHandle->image; + + if (signImage) { + /* pad the image as required to reach a partial hash boundary of 64 bytes */ + paddingSize = (64 - ((sizeof(*hdr) - offsetof(Image3ObjectHeader, ihSignedLength) + withHandle->cursor) % 64)) % 64; + if ((result = image3AdvanceCursorWithZeroPad( + withHandle, + paddingSize)) != 0) { + debug("failed to pad image to partial hashing boundary"); + return(result); + } + + /* update header pointer as the padding above may have reallocated it */ + hdr = withHandle->image; + + /* sign up to this point, remembering that eventual signed length will cover the reserved area */ + hdr->ihSignedLength = HTOLE(withHandle->cursor + reservationSize); + debug("will sign %u bytes for image %p", LETOH(hdr->ihSignedLength), withHandle); + + /* generate hash */ + hashSize = sizeof(*hdr) - offsetof(Image3ObjectHeader, ihSignedLength) + LETOH(hdr->ihSignedLength) - reservationSize; + if (createPartialHash) { + partialHash.masteredReservationLength = HTOLE(reservationSize); + partialHash.masteredSignedLength = HTOLE(LETOH(hdr->ihSignedLength) - reservationSize); + + hashBuffer = &partialHash; + hashBufferSize = sizeof(Image3PartialHash); + image3SHA1Partial(&hdr->ihSignedLength, hashSize, partialHash.sha1_state); + } + else { + hashBuffer = normalHash; + hashBufferSize = IMAGE3_HASH_SIZE; + image3SHA1Generate(&hdr->ihSignedLength, hashSize, hashBuffer); + } + + /* + * sign hash & get cert chain; note well that this is the code path for all cases that update the signed length whether + * or not a signature is applied. When computing hashes, for example, execution passes into image3PKISignHash and then + * terminates before returning. Also, in cases supporting authorized installations, the image is finalized, but no actual + * hash or cert tags are appended. + */ + result = image3PKISignHash( + hashBuffer, + hashBufferSize, + &signedHash, + &signedHashSize, + &certChain, + &certChainSize); + if (result) { + debug("hash signing failed"); + return(result); + } + debug("signed hash size %u @ %p", (unsigned int)signedHashSize, signedHash); + + /* append tags containing signed hash and cert chain if provided */ + if (signedHashSize) { + if ((result = image3SetTagStructure( + withHandle, + kImage3TagTypeSignedHash, + signedHash, + signedHashSize, + 0)) != 0) { + debug("failed to append signed hash tag"); + return(result); + } + } + if (certChainSize) { + if ((result = image3SetTagStructure( + withHandle, + kImage3TagTypeCertificateChain, + certChain, + certChainSize, + 0)) != 0) { + debug("failed to append cert chain tag"); + return(result); + } + } + + /* mark the image as signed and thus immutable */ + withHandle->flags |= kImage3ImageIsSigned; + + /* update header pointer as the tags above may have reallocated it */ + hdr = withHandle->image; + } + + /* fill out the remaining header fields */ + hdr->ihBufferLength = HTOLE(withHandle->cursor); + hdr->ihSkipDistance = HTOLE(sizeof(*hdr) + withHandle->cursor); + + /* hand back the buffer and its final size */ + *objectBuffer = hdr; + *objectSize = LETOH(hdr->ihSkipDistance); + + return(0); +} + +/* + * Set a numeric tag. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + */ +int +image3SetTagSignedNumber( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + int64_t withValue) +{ + Image3TagNumber32 num32; + Image3TagNumber64 num64; + void *num; + int64_t tmp; + size_t size; + + debug("setting tag %c%c%c%c to %lld", UNTAG(withTag), withValue); + + tmp = (withValue > 0) ? -withValue : withValue; + + if ((tmp >> 32) >= -1) { + size = sizeof(num32); + num32.value.s32 = HTOLE(withValue); + num = (void *)&num32; + } else { + size = sizeof(num64); + num64.value.s64 = HTOLELL(withValue); + num = (void *)&num64; + } + + return(image3SetTagStructure(withHandle, withTag, num, sizeof(num), 0)); +} + +int +image3SetTagUnsignedNumber( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + u_int64_t withValue) +{ + Image3TagNumber32 num32; + Image3TagNumber64 num64; + void *num; + size_t size; + + debug("setting tag %c%c%c%c to %llu", UNTAG(withTag), withValue); + + if ((withValue >> 32) == 0) { + size = sizeof(num32); + num32.value.u32 = HTOLE(withValue); + num = (void *)&num32; + } else { + size = sizeof(num64); + num64.value.u64 = HTOLELL(withValue); + num = (void *)&num64; + } + + return(image3SetTagStructure(withHandle, withTag, num, size, 0)); +} + +/* + * Set a string tag. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + */ +int +image3SetTagString( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + char *withValue) +{ + Image3TagString *str; + size_t len; + int result; + + debug("setting tag %c%c%c%c to '%s'", UNTAG(withTag), withValue); + len = strlen(withValue); + + /* allocate the structure with room for the string */ + if ((str = (Image3TagString *)image3Malloc(len + sizeof(*str))) == NULL) + return(ENOMEM); + + str->stringLength = len; + memcpy(str->stringBytes, withValue, len); + + result = image3SetTagStructure(withHandle, withTag, (void *)str, len + sizeof(*str), 0); + + image3Free(str, len + sizeof(*str)); + return(result); +} + +/* + * Set a structure tag. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + * EROFS Image is read-only + */ +int +image3SetTagStructure( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + const void *withValue, + size_t withSize, + int withAlignment) +{ + Image3ObjectHeader *newHeader; + size_t needAlloc; + Image3TagHeader *tagHeader; + u_int32_t dataCursor; + size_t remainderSize; + + debug("setting structure tag %c%c%c%c of %u bytes aligned %d for image %p cursor %u", + UNTAG(withTag), (unsigned int)withSize, withAlignment, withHandle, withHandle->cursor); + + /* once an image is signed, it's immutable */ + if (withHandle->flags & kImage3ImageIsSigned) + return(EROFS); + + /* + * Align the cursor as required. Note that this is fairly hairy, as we have to take the + * image header into account as well, since alignment is relative to the base of the + * image... + */ + if (withAlignment) { + /* forward-align the cursor */ + dataCursor = withHandle->cursor + sizeof(*tagHeader) + sizeof(Image3ObjectHeader); + dataCursor += (withAlignment - (withHandle->cursor % withAlignment)) % withAlignment; + withHandle->cursor = dataCursor - sizeof(*tagHeader) - sizeof(Image3ObjectHeader); + + /* fix up the skip distance from the previous tag */ + if (withHandle->lastTag != -1) { + tagHeader = (Image3TagHeader *)&withHandle->image->ihBuffer[withHandle->lastTag]; + tagHeader->itSkipDistance = HTOLE(withHandle->cursor - withHandle->lastTag); + } + debug("doing aligned insertion with tag at %u and data at %u", withHandle->cursor, dataCursor); + } + + /* calculate remainder, we want to pad payload size to a multiple of 16 to facilitate AES */ + if ((withSize % 16) == 0) { + remainderSize = 0; + } + else { + remainderSize = 16 - (withSize % 16); + } + debug("remainder size is 0x%x", remainderSize, withTag); + + /* check to see whether there's room in the buffer and re-allocate to suit */ + needAlloc = sizeof(*newHeader) + withHandle->cursor + withSize + remainderSize + sizeof(*tagHeader); + if (needAlloc > withHandle->allocSize) { + debug("need allocation of %u but current allocation only good for %u", + (unsigned int)needAlloc, (unsigned int)withHandle->allocSize); + if ((newHeader = realloc(withHandle->image, needAlloc)) == NULL) { + debug("failed to reallocate buffer to add tag"); + return(ENOMEM); + } + debug("image buffer moved %p -> %p", withHandle->image, newHeader); + debug("oldsize was 0x%x, newsize is 0x%x, newsize - oldsize is 0x%x", + withHandle->allocSize, needAlloc, needAlloc - withHandle->allocSize); + withHandle->image = newHeader; + withHandle->allocSize = needAlloc; + } + + /* populate the new tag. itBufferLength is intentionally short by remainderSize. */ + tagHeader = (Image3TagHeader *)&withHandle->image->ihBuffer[withHandle->cursor]; + tagHeader->itTag = HTOLE(withTag); + tagHeader->itBufferLength = HTOLE(withSize); + + /* pad payload size to a multiple of 16 to facilitate AES */ + tagHeader->itSkipDistance = HTOLE(withSize + remainderSize + sizeof(*tagHeader)); + + /* and pad skip distance to a multiple of 4 to keep headers aligned */ + if (LETOH(tagHeader->itSkipDistance) & 3) { + debug("padding skip distance %u to %u", + LETOH(tagHeader->itSkipDistance), + LETOH(tagHeader->itSkipDistance) + 4 - (LETOH(tagHeader->itSkipDistance) & 3)); + tagHeader->itSkipDistance = HTOLE(LETOH(tagHeader->itSkipDistance) + 4 - (LETOH(tagHeader->itSkipDistance) & 3)); + } + + + debug("copying %u bytes of data %p -> %p", (unsigned int)withSize, withValue, tagHeader->itBuffer); + memcpy(tagHeader->itBuffer, withValue, withSize); + debug("padding with %u bytes of zeroes at %p", (unsigned int)remainderSize, tagHeader->itBuffer, tagHeader->itBuffer + withSize); + memset(tagHeader->itBuffer + withSize, 0, remainderSize); + + /* move the cursor */ + withHandle->lastTag = withHandle->cursor; + withHandle->cursor += LETOH(tagHeader->itSkipDistance); + + debug("new cursor is %u", withHandle->cursor); + + /* update this so that _image3PrintImage works */ + withHandle->image->ihBufferLength = HTOLE(withHandle->cursor); + + return(0); +} + +/* + * Advances the cursor with zero padding. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + * EROFS Image is read-only + */ +int +image3AdvanceCursorWithZeroPad( + const Image3ObjectHandle withHandle, + int withSize) +{ + Image3ObjectHeader *newHeader; + size_t needAlloc; + Image3TagHeader *tagHeader; + size_t previousCursor; + + debug("advancing cursor by %u bytes for image %p cursor %u", + (unsigned int)withSize, withHandle, withHandle->cursor); + + /* once an image is signed, it's immutable */ + if (withHandle->flags & kImage3ImageIsSigned) + return(EROFS); + + /* advance the cursor */ + previousCursor = withHandle->cursor; + withHandle->cursor += withSize; + debug("new cursor is %u", withHandle->cursor); + + /* fix up the skip distance from the previous tag */ + if (withHandle->lastTag != -1) { + tagHeader = (Image3TagHeader *)&withHandle->image->ihBuffer[withHandle->lastTag]; + tagHeader->itSkipDistance = HTOLE(withHandle->cursor - withHandle->lastTag); + } + + + /* check to see whether there's room in the buffer and re-allocate to suit */ + needAlloc = sizeof(*newHeader) + withHandle->cursor; + if (needAlloc > withHandle->allocSize) { + debug("need allocation of %u but current allocation only good for %u", + (unsigned int)needAlloc, (unsigned int)withHandle->allocSize); + if ((newHeader = realloc(withHandle->image, needAlloc)) == NULL) { + debug("failed to reallocate buffer to add tag"); + return(ENOMEM); + } + debug("image buffer moved %p -> %p", withHandle->image, newHeader); + withHandle->image = newHeader; + withHandle->allocSize = needAlloc; + } + + /* zero pad */ + bzero(&withHandle->image->ihBuffer[previousCursor], withHandle->cursor - previousCursor); + + /* update this so that _image3PrintImage works */ + withHandle->image->ihBufferLength = HTOLE(withHandle->cursor); + + return(0); +} + +#endif /* IMAGE3_CREATOR */ + +/* + * Take a data buffer that might contain an Image3 object and get a handle to it. + * + * Note that no security validation is performed by this operation. + * + * Returns: + * 0 Success + * ENOMEM Could not allocate handle or buffer + * EINVAL The contents of the buffer are malformed + */ +int +image3InstantiateFromBuffer( + Image3ObjectHandle *newHandle, + const void *fromBuffer, + const size_t bufferSize, + bool copyBuffer) +{ + Image3ObjectHeader *hdr; + Image3InternalState *state; + + debug("instantiating from buffer %p size %u", fromBuffer, (unsigned int)bufferSize); + + /* assume we have a header and do some basic sanity checks */ + hdr = (Image3ObjectHeader *)fromBuffer; + if (bufferSize < sizeof(*hdr)) { + debug("buffer size %llu too small for header size %llu", (unsigned long long)bufferSize, (unsigned long long)sizeof(*hdr)); + return(EINVAL); /* buffer too small to really contain header */ + } + if (LETOH(hdr->ihMagic) != kImage3HeaderMagic) { + debug("bad magic 0x%08x expecting 0x%08x", LETOH(hdr->ihMagic), kImage3HeaderMagic); + return(EINVAL); /* magic must match */ + } + if (LETOH(hdr->ihBufferLength) > (bufferSize - sizeof(*hdr))) { + debug("header length %llu too large for buffer length %llu", + (unsigned long long)(LETOH(hdr->ihBufferLength) + sizeof(*hdr)), (unsigned long long)bufferSize); + return(EINVAL); /* container is too big for buffer */ + } + if (LETOH(hdr->ihSignedLength) > LETOH(hdr->ihBufferLength)) { + debug("signed legnth %u too large for buffer length %u", + LETOH(hdr->ihSignedLength), LETOH(hdr->ihBufferLength)); + return(EINVAL); /* signed length is too large */ + } + if ((LETOH(hdr->ihBufferLength) + sizeof(*hdr)) > LETOH(hdr->ihSkipDistance)) { + debug("skip distance %llu too short for buffer length %llu", + (unsigned long long)(LETOH(hdr->ihBufferLength) + sizeof(*hdr)), (unsigned long long)LETOH(hdr->ihSkipDistance)); + return(EINVAL); /* skip distance falls into container */ + } + + /* the buffer looks OK, allocate our state */ + if ((state = image3Malloc(sizeof(*state))) == NULL) { + debug("failed to allocate state"); + return(ENOMEM); + } + + state->flags = kImage3ImageWasInstantiated; + state->nestedImage = NULL; + + if (LETOH(hdr->ihSignedLength) > 0) { + debug("image claims to be signed, marking immutable"); + state->flags |= kImage3ImageIsSigned; + } else { +#ifdef IMAGE3_CREATOR + Image3TagHeader *tagHeader; + u_int32_t tagCursor; + + /* since we have to be able to realloc, copy to an allocated buffer */ + copyBuffer = true; + + /* + * To get lastTag set correctly, we have to walk the tags in the image. + * + * Note that this is only done in read/write tools and only if the image + * is not signed - in this case we are not concerned with security. + */ + state->cursor = LETOH(hdr->ihBufferLength); + state->lastTag = -1; + if (LETOH(hdr->ihBufferLength) > 0) { + tagCursor = 0; + + for (;;) { + tagHeader = (Image3TagHeader *)&hdr->ihBuffer[tagCursor]; + + /* if the tag points past the end of the image, it's corrupt */ + /* if the skip distance is to small, it's corrupt */ + if ((tagCursor + LETOH(tagHeader->itSkipDistance)) > LETOH(hdr->ihBufferLength)) { + image3Free(state, sizeof(*state)); + debug("tag skip distance %u moves cursor %u outside buffer length %u", + LETOH(tagHeader->itSkipDistance), tagCursor, LETOH(hdr->ihBufferLength)); + return(EINVAL); + } + if ((LETOH(tagHeader->itSkipDistance) < sizeof(*tagHeader))) { + image3Free(state, sizeof(*state)); + debug("tag skip distance %u outside too small", LETOH(tagHeader->itSkipDistance)); + return(EINVAL); + } + + /* if the tag points precisely to the end of the image, we're done */ + if ((tagCursor + LETOH(tagHeader->itSkipDistance)) == LETOH(hdr->ihBufferLength)) { + state->lastTag = tagCursor; + break; + } + + /* skip to the next tag */ + tagCursor += LETOH(tagHeader->itSkipDistance); + } + } +#endif + } + + /* if we were asked, or forced, copy the buffer */ + if (copyBuffer) { + debug("image mutable or copy requested"); + state->allocSize = LETOH(hdr->ihBufferLength) + sizeof(*hdr); + if ((state->image = image3Malloc(state->allocSize)) == NULL) { + image3Free(state, sizeof(*state)); + debug("failed to allocate memory for image copy"); + return(ENOMEM); + } + memcpy(state->image, fromBuffer, state->allocSize); + state->flags |= kImage3ImageWasAllocated; + } else { + state->image = hdr; + state->allocSize = bufferSize; + } + + *newHandle = state; + return(0); +} + +/* + * Validate the signature on an Image3 object. + * + * Note that images from untrusted sources should be handled with *extreme caution* + * until this operation has reported success. + * + * We assume that the ihBufferLength and ihSignedLength fields in the image header + * have already been sanity-checked. + * + * If the object was loaded from local storage where it was expected that it was + * personalised for the device (normally the case) then the kImage3ValidateLocalStorage + * option should be supplied. + * + * Returns: + * 0 Success. + * EINVAL The contents of the buffer are malformed + * ENOMEM Could not allocate working memory + * EPERM Security validation failed + * Other errors may be returned by the PKI or AES infrastructure. + * + * Note to auditors: + * ----------------- + * This code is used on images that have been processed by image3InstantiateFromBuffer. + * As such, it makes the assumption that header fields that are validated there may be + * trusted. In particular, ihBufferLength is trusted to lie within the caller's buffer, + * and ihSignedLength is trusted to be less than or equal to ihBufferLength. + */ +int +image3ValidateSignature( + Image3ObjectHandle withHandle, + u_int32_t expectedType, + u_int32_t validationOptions, + bool *validatedWithEmbeddedSignature) +{ + Image3ObjectHeader *hdr; + Image3TagHeader *hashTag; + Image3TagHeader *certTag; + u_int32_t tagCursor; + char hashBuffer[IMAGE3_HASH_SIZE]; + size_t hashSize; + void *certCustomData; + size_t certCustomDataLength; + int result; + uint8_t *base; + size_t len; + + debug("validating signature on image %p", withHandle); + + /* do we already know whether the image is trusted? */ + if (withHandle->flags & kImage3ImageWasValidated) { + debug("returning cached result %d", (withHandle->flags & kImage3ImageIsTrusted) ? 0 : EPERM); + return((withHandle->flags & kImage3ImageIsTrusted) ? 0 : EPERM); + } + + /* image can be altered below, no second chances */ + withHandle->flags |= kImage3ImageWasValidated; + + /* if the image is not signed, it's not trusted */ + if (!(withHandle->flags & kImage3ImageIsSigned)) { + debug("image is not signed, cannot be considered trusted"); + return(EPERM); + } + + hdr = withHandle->image; + + /* verify that the image is large enough to contain at least one tag header */ + if (LETOH(hdr->ihBufferLength) < sizeof(*hashTag)) { + debug("image too small to be signed"); + return(EINVAL); + } + + /* + * Indirect (ticket) image signature validation. + */ + + /* + * If the image has been personalised by the addition of an ECID in + * the signed range, we need to back that out before generating the + * hash for ticket purposes. + * + * This is transitional, and it can eventually be removed out once + * ticketting is the norm. + * + * In the case of ticket validation after backing out an ECID tag, we + * need to zero out the ECID tag after validation to prevent leakage + * of untrusted data. If ticket validation fails and we fall back to + * embedded image signature validation, we have to keep the ECID tag + */ + uint32_t savedLength; + Image3TagHeader *ecidTag; + uint32_t rewindCount; + + /* save the signed length - we might overwrite it here, but we'll need + to restore it if ticket validation fails and we fall back to embedded + image signature validation */ + savedLength = LETOH(hdr->ihSignedLength); + + /* look backwards to see if the last thing in the signed range is an ECID tag */ + tagCursor = savedLength; + if (tagCursor > (sizeof(Image3TagHeader) + sizeof(Image3TagNumber64))) { + + /* back up to the highest possible address at which we might find the ECID tag */ + tagCursor -= sizeof(Image3TagHeader) + sizeof(Image3TagNumber64); + + /* due to padding, we may have to go back up to 64 bytes further to find the ECID tag */ + rewindCount = 0; + do { + ecidTag = (Image3TagHeader *)&hdr->ihBuffer[tagCursor]; + if ((ecidTag->itTag == kImage3TagTypeUniqueID) && + (ecidTag->itBufferLength == sizeof(Image3TagNumber64))) { + /* this looks like a valid ECID tag - back the signed length up to avoid it */ + hdr->ihSignedLength = HTOLE(tagCursor); + debug("backed signed length up from %u to %u\n", savedLength, tagCursor); + break; + } + /* check whether we can safely rewind further */ + if (tagCursor < 4) + break; + tagCursor -= 4; + rewindCount += 4; + } while (rewindCount <= 64); + } + + /* generate the hash that we expect to find in the ticket */ + hashSize = sizeof(*hdr) - offsetof(Image3ObjectHeader, ihSignedLength) + LETOH(hdr->ihSignedLength); + image3SHA1Generate(&hdr->ihSignedLength, hashSize, hashBuffer); + + /* ask the ticket validator for an opinion on this image */ + result = image3TicketVerifyHash(hashBuffer, sizeof(hashBuffer), LETOH(hdr->ihType), expectedType); + + if (result == 0) { + debug("ticket says this image is trusted"); + goto out_trusted; + } + if (result == EPERM) { + debug("ticket says this image is untrusted"); + return(EPERM); + } + debug("ticket does not like this image"); + + /* + * Embedded image signature validation. + */ + + /* verify that the caller is willing to have us validate with the embedded signature */ + if (validationOptions & kImage3ValidateRequireTicket) { + debug("image requires ticket validation"); + return(EINVAL); + } + + /* restore the signed length to include the ECID tag again */ + hdr->ihSignedLength = HTOLE(savedLength); + + /* verify that the hash tag lies within the image buffer */ + tagCursor = LETOH(hdr->ihSignedLength); + if (tagCursor > (LETOH(hdr->ihBufferLength) - sizeof(*hashTag))) { + debug("hash tag overflows buffer"); + return(EINVAL); + } + /* verify that the hash tag's buffer does not overflow the image buffer */ + hashTag = (Image3TagHeader *)&hdr->ihBuffer[tagCursor]; + if (LETOH(hashTag->itBufferLength) > (LETOH(hdr->ihBufferLength) - tagCursor - sizeof(*hashTag))) { + debug("buffer too small to contain signed hash tag payload"); + return(EINVAL); + } + if (LETOH(hashTag->itTag) != kImage3TagTypeSignedHash) { + debug("buffer does not contain signed hash tag at required location"); + return(EINVAL); + } + + /* move the tag cursor to the location we expect to find the cert chain */ + tagCursor += LETOH(hashTag->itSkipDistance); + + /* check cursort against lower legal bound */ + if (tagCursor < LETOH(hdr->ihSignedLength)) { + debug("skip distance on signed hash tag wraps cursor"); + return(EINVAL); + } + + /* verify that the cert tag lies within the buffer */ + if (tagCursor > (LETOH(hdr->ihBufferLength) - sizeof(*certTag))) { + debug("cert tag overflows buffer"); + return(EINVAL); + } + + /* verify that the cert tag's buffer does not overflow the image buffer */ + certTag = (Image3TagHeader *)&hdr->ihBuffer[tagCursor]; + if (LETOH(certTag->itBufferLength) > (LETOH(hdr->ihBufferLength) - tagCursor - sizeof(*certTag))) { + debug("buffer too small to contain cert chain tag payload"); + return(EINVAL); + } + if (LETOH(certTag->itTag) != kImage3TagTypeCertificateChain) { + debug("buffer does not contain cert chain tag at required location"); + return(EINVAL); + } + + /* fix up the buffer length to precisely describe the image including signature and no more */ + if ((tagCursor + sizeof(*certTag) + LETOH(certTag->itBufferLength)) != LETOH(hdr->ihBufferLength)) { + debug("correcting buffer length from %u to %u", + LETOH(hdr->ihBufferLength), (unsigned int)(tagCursor + sizeof(*certTag) + LETOH(certTag->itBufferLength))); + hdr->ihBufferLength = HTOLE(tagCursor + sizeof(*certTag) + LETOH(certTag->itBufferLength)); + } + + /* hash the signed portions of the buffer */ + hashSize = sizeof(*hdr) - offsetof(Image3ObjectHeader, ihSignedLength) + LETOH(hdr->ihSignedLength); + image3SHA1Generate(&hdr->ihSignedLength, hashSize, hashBuffer); + + /* if the image has come from local storage, the signed hash needs to be decrypted */ + if (validationOptions & kImage3ValidateLocalStorage) { + if (0 != (LETOH(hashTag->itBufferLength) % 16)) { + debug("signed hash buffer length invalid for AES decryption"); + return(EINVAL); + } + debug("decrypting signed hash"); + image3AESDecryptUsingLocalKey(hashTag->itBuffer, LETOH(hashTag->itBufferLength)); + } + + /* call the PKI interface to validate the signature and compare the hash */ + certCustomData = NULL; + certCustomDataLength = 0; + result = image3PKIVerifyHash( + hashBuffer, + IMAGE3_HASH_SIZE, + hashTag->itBuffer, + LETOH(hashTag->itBufferLength), + certTag->itBuffer, + LETOH(certTag->itBufferLength), + &certCustomData, + &certCustomDataLength); + + /* clear the possibly decrypted signature from memory */ + memset(hashTag->itBuffer, 0, LETOH(hashTag->itBufferLength)); + + if (result) { + debug("PKI verification failed (%d)", result); + return(result); + } + debug("PKI verification passed..."); + + /* if the cert validation returned custom data, it should be an image3 image as well */ + if (certCustomData) { + result = image3InstantiateFromBuffer( + &withHandle->nestedImage, + certCustomData, + certCustomDataLength, + true /* copyBuffer */); + if (result) { + debug("failed to instantiate image from certificate custom data"); + return(result); + } + + /* inherit valid/trusted flags from the parent image - not validated separately */ + withHandle->nestedImage->flags |= + kImage3ImageWasValidated | kImage3ImageIsTrusted | kImage3ImageIsSigned; + } + if (validatedWithEmbeddedSignature) + *validatedWithEmbeddedSignature = true; + +out_trusted: + withHandle->flags |= kImage3ImageIsTrusted; + + /* + * Strip the signature and cert chain (and anything that might follow them) out of the buffer + * to prevent any extra data hanging around. + */ + base = (uint8_t *)hdr + sizeof(*hdr) + LETOH(hdr->ihSignedLength); + len = (uint8_t *)hdr + withHandle->allocSize - base; + + memset(base, 0, len); + + hdr->ihBufferLength = HTOLE(LETOH(hdr->ihSignedLength)); + + return(0); +} + +/* + * Test for the presence of a tag in an image. + * + * Returns: + * 0 Success + * EINVAL The buffer is malformed. + * ENOENT The tag was not found. + */ +int +image3TagIsPresent( + const Image3ObjectHandle withHandle, + const u_int32_t withTag) +{ + void *p; + + return(image3GetTagStruct(withHandle, withTag, &p, NULL, 0)); +} + +/* + * Fetch a numeric tag's value. + * + * Returns: + * 0 Success + * EINVAL The buffer is malformed. + * ENOENT The tag was not found. + */ +int +image3GetTagSignedNumber( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + int64_t *toNumber, + int skipCount) +{ + Image3TagNumber *num; + size_t size; + int result; + + size = 0; + if ((result = image3GetTagStruct(withHandle, withTag, (void **)&num, &size, skipCount)) == 0) { + switch (size) { + case sizeof(Image3TagNumber32) : + *toNumber = LETOH(num->number.n32.value.s32); + break; + + case sizeof(Image3TagNumber64) : + *toNumber = LETOHLL(num->number.n64.value.s64); + break; + + default : + result = EINVAL; + break; + } + } + + return(result); +} + +int +image3GetTagUnsignedNumber( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + u_int64_t *toNumber, + int skipCount) +{ + Image3TagNumber *num; + size_t size; + int result; + + size = 0; + if ((result = image3GetTagStruct(withHandle, withTag, (void **)&num, &size, skipCount)) == 0) { + switch (size) { + case sizeof(Image3TagNumber32) : + *toNumber = LETOH(num->number.n32.value.u32); + break; + + case sizeof(Image3TagNumber64) : + *toNumber = LETOHLL(num->number.n64.value.u64); + break; + + default : + result = EINVAL; + break; + } + } + + return(result); +} + +/* + * Fetch a string tag's value. + * + * Returns: + * 0 Success. *toBuffer contains an ASCIIZ string that must be freed by the caller. + * EINVAL The buffer is malformed. + * ENOMEM Not enough memory available to allocate a copy of the string. + * ENOENT The tag was not found. + */ +int +image3GetTagString( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + char **toBuffer, + int skipCount) +{ + Image3TagString *str; + size_t size; + char *buf; + int result; + + size = 0; + if ((result = image3GetTagStruct(withHandle, withTag, (void **)&str, &size, skipCount)) == 0) { + /* validate string structure */ + if (size < sizeof(*str)) /* malformed */ + return(EINVAL); + if ((size - sizeof(*str)) != LETOH(str->stringLength)) /* claimed length overflows allocation */ + return(EINVAL); + + /* make a copy of the string */ + if ((buf = image3Malloc(LETOH(str->stringLength) + 1)) == NULL) { + result = ENOMEM; + } else { + /* copy valid bytes, guarantee NUL termination */ + memcpy(buf, str->stringBytes, str->stringLength); + buf[str->stringLength] = '\0'; + *toBuffer = buf; + } + } + return(result); +} + +/* + * Find a tag by name. + * + * The leading (skipCount) matching tags will be ignored. + * + * The tag 0xffffffff is a wildcard with matches any tag. + * + * Returns: + * 0 Success + * ENOENT The tag was not found. + */ +static int +_image3FindTag( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + Image3TagHeader **forHeader, + size_t *structSize, + int skipCount) +{ + Image3TagHeader *thdr; + u_int8_t *cursor, *bound, *next, *tagEnd; + + /* our starting point */ + cursor = &withHandle->image->ihBuffer[0]; + + /* find the upper boundary of the tag buffer */ + bound = cursor + LETOH(withHandle->image->ihBufferLength); + debug("scanning for tags between %p and %p", cursor, bound); + + /* do not permit the buffer to wrap */ + if (bound < cursor) { + debug("integer wrap computing upper bound"); + return(EINVAL); + } + + /* iterate, making sure that the header fits within the upper boundary */ + while (cursor < bound) { + /* consider the tag at cursor */ + thdr = (Image3TagHeader *)cursor; + + /* do not permit the header to wrap */ + if ((cursor + sizeof(*thdr)) < cursor) { + debug("integer wrap between cursor and tag header end"); + return(EINVAL); + } + + /* if any part of the header is outside the boundary, the buffer is malformed */ + if ((cursor + sizeof(*thdr)) > bound) { + debug("tag header outside search boundary"); + return(EINVAL); + } + + /* if the tag data wraps or crosses the boundary, the buffer is malformed */ + tagEnd = cursor + sizeof(*thdr) + LETOH(thdr->itBufferLength); + if ((tagEnd < (cursor + sizeof(*thdr))) || (tagEnd > bound)) { + debug("tag data violates search boundaries or wraps"); + return(EINVAL); + } + + /* compare tags */ + if ((withTag == 0xffffffff) || (LETOH(thdr->itTag) == withTag)) { + if (skipCount == 0) { + if (structSize) { + /* caller-specified size does not match tag data size */ + if (*structSize && (*structSize != LETOH(thdr->itBufferLength))) { + debug("tag specifies size %u but caller requires %u for tag 0x%x", + (unsigned int)*structSize, LETOH(thdr->itBufferLength), LETOH(thdr->itTag)); + return(EINVAL); + } + + /* tell caller data size */ + *structSize = LETOH(thdr->itBufferLength); + } + debug("found tag at %p", thdr); + *forHeader = thdr; + return(0); + } + skipCount--; + } + + /* validate the skip distance */ + if (LETOH(thdr->itSkipDistance) < (sizeof(*thdr) + LETOH(thdr->itBufferLength))) { + debug("skip distance %u less than the sum of header size and buffer data %u", + LETOH(thdr->itSkipDistance), (unsigned int)(sizeof(*thdr) + LETOH(thdr->itBufferLength))); + return(EINVAL); + } + + /* find the next header */ + next = cursor + LETOH(thdr->itSkipDistance); + + /* do not permit arithmetic wrap */ + if (next < cursor) { + debug("integer wrap advancing cursor"); + return(EINVAL); + } + + cursor = next; + } + return(ENOENT); +} + +/* + * Fetch a direct pointer to a structure tag. Note that this points into the object itself + * and should be used with some caution. + * + * Returns: + * 0 Success. + * EINVAL The buffer is malformed. + * ENOENT The tag was not found. + */ +int +image3GetTagStruct( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + void **structPtr, + size_t *structSize, + int skipCount) +{ + int result; + Image3TagHeader *thdr; + + if ((result = _image3FindTag(withHandle, withTag, &thdr, structSize, skipCount)) != 0) + return(result); + + *structPtr = (void *)&thdr->itBuffer; + return(0); +} + +/* + * Return the nested image's handle (if one exists). + */ +Image3ObjectHandle +image3GetNestedImage(const Image3ObjectHandle withHandle) +{ + return(withHandle->nestedImage); +} + +#ifdef IMAGE3_DEBUG +void +_image3PrintImage(Image3ObjectHandle withHandle) +{ + int result; + int index; + unsigned int i, j; + Image3TagHeader *thdr; + + printf("image skip distance: 0x%x\n", LETOH(withHandle->image->ihSkipDistance)); + printf("image buffer length: 0x%x\n", LETOH(withHandle->image->ihBufferLength)); + printf("image signed length: 0x%x\n\n", LETOH(withHandle->image->ihSignedLength)); + + for (index = 0; ; index++) { + result = _image3FindTag(withHandle, 0xffffffff, &thdr, NULL, index); + if (result != 0) { + if (result != ENOENT) + debug("image scan terminated unexpectedly"); + break; + } + printf("tag: %c%c%c%c\n", UNTAG(LETOH(thdr->itTag))); + printf("skip distance: 0x%x\n", LETOH(thdr->itSkipDistance)); + printf("buffer length: 0x%x\n", LETOH(thdr->itBufferLength)); + printf("---------------------\n"); + + for (i = 0; i < LETOH(thdr->itBufferLength); i += 16) { + printf("%08x: ", i); + for (j = 0; (j < 16) && ((i + j) < LETOH(thdr->itBufferLength)); j++) + printf(" %02x", (unsigned int)thdr->itBuffer[i + j]); + printf("\n"); + } + } +} + +#ifdef IMAGE3_UTILITY + +int +_image3WriteData(Image3ObjectHandle withHandle, const char *path) +{ + int fd; + int result = 0; + Image3TagHeader *thdr; + + fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644); + + if (fd < 0) { + perror("open failed"); + return fd; + } + + /* + * Check to see if the image is encrypted. If so, we don't + * decrypt it here, so there is nothing we can do + */ + result = _image3FindTag(withHandle, kImage3TagTypeKeybag, &thdr, NULL, 0); + if (result == 0) { + debug("image is encrypted, no going back"); + result = -1; + goto out; + } + + result = _image3FindTag(withHandle, kImage3TagTypeData, &thdr, NULL, 0); + if (result != 0) { + debug("couldn't find data section"); + goto out; + } + + write(fd, thdr->itBuffer, thdr->itBufferLength); + + printf("Wrote %s\n", path); + + close(fd); + +out: + return (result); +} + +#endif /* IMAGE3_UTILITY */ + +#endif /* IMAGE3_DEBUG */ diff --git a/lib/image/image3/Image3.h b/lib/image/image3/Image3.h new file mode 100644 index 0000000..c37b29f --- /dev/null +++ b/lib/image/image3/Image3.h @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _IMAGE3_H_ +#define _IMAGE3_H_ + +#include + +#include + +#ifndef false +# include +#endif + + +/* + * All Image3 operations use an Image3ObjectHandle to refer to the image being worked on. + */ +struct _Image3InternalState; +typedef struct _Image3InternalState *Image3ObjectHandle; + +/* + * Discards an Image3 image. + */ +extern void +image3Discard( + Image3ObjectHandle *withHandle); + + +#ifdef IMAGE3_CREATOR +/* + * Create a new Image3 working object. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + */ +extern int +image3InstantiateNew( + Image3ObjectHandle *newHandle, + size_t initialAllocation, + u_int32_t imageType); + +/* + * Finalises an image. + * + * If signImage is set, hashes and signs the image. Reservation length, if non-zero, indicates that the final signed image + * will include tags not currently present in the image. A partial digest is computed, but the size of the reservation is + * required so that ihSignedLength can be set properly for inclusion in the partial hash state. The partial digest is + * constrained to conclude on a 64 byte boundary by adding the appropriate padding following the last tag in the signed portion + * of a finalised image. + * + * Returns: + * 0 Success + */ +extern int +image3Finalize( + const Image3ObjectHandle withHandle, + void **objectBuffer, + size_t *objectSize, + bool signImage, + size_t reservationSize); + +/* + * Set a numeric tag. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + */ +extern int +image3SetTagSignedNumber( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + int64_t withValue); + +extern int +image3SetTagUnsignedNumber( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + u_int64_t withValue); + +/* + * Set a string tag. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + */ +extern int +image3SetTagString( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + char *withValue); + +/* + * Set a structure tag. + * + * Note that the withAlignment field aligns the structure, not the tag. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + */ +extern int +image3SetTagStructure( + const Image3ObjectHandle withHandle, + u_int32_t withTag, + const void *withValue, + size_t withSize, + int withAlignment); + + +/* + * Advances the cursor with zero padding. + * + * Returns: + * 0 Success + * ENOMEM Unable to allocate memory + * EROFS Image is read-only + */ +extern int +image3AdvanceCursorWithZeroPad( + const Image3ObjectHandle withHandle, + int withSize); + +#endif /* IMAGE3_CREATOR */ + + +/* + * Take a data buffer that might contain an Image3 object and get a handle to it. + * + * Note that no security-relatd validation is performed by this operation. + * + * If IMAGE3_CREATOR is defined and the image is mutable, or if copyBuffer is + * true, then the image buffer is copied. Otherwise the image directly references + * the supplied buffer. + * + * Returns: + * 0 Success. + * EINVAL The contents of the buffer are malformed + */ +extern int +image3InstantiateFromBuffer( + Image3ObjectHandle *newHandle, + const void *fromBuffer, + const size_t bufferSize, + bool copyBuffer); + +/* + * Validate the signature on an Image3 object. + * + * Note that images from untrusted sources should be handled with *extreme caution* + * until this operation has reported success. + * + * If the object was loaded from local storage where it was expected that it was + * personalised for the device (normally the case) then the kImage3ValidateLocalStorage + * option should be supplied. + * + * If the object's validity can only be asserted via the ticket API, + * kImage3ValidateRequireTicket should be supplied. + * + * The result of the validation operation is cached, so it is safe to call this function + * multiple times. Once the initial validation operation is performed, the validation + * options are ignored, so knowledge of the source of the object is not required in this + * case. + * + * Returns: + * 0 Success. + * EINVAL The contents of the buffer are malformed or otherwise cannot be validated. + * EPERM Validation failed, the image cannot be trusted. + */ +#define kImage3ValidateLocalStorage (1<<0) +#define kImage3ValidateRequireTicket (1<<2) + +extern int +image3ValidateSignature( + const Image3ObjectHandle withHandle, + const u_int32_t expectedType, + const u_int32_t validationOptions, + bool *validatedWithEmbeddedSignature); + +/* + * Test for the presence of a tag in an image. + * + * Returns: + * 0 Success + * EINVAL The buffer is malformed. + * ENOENT The tag was not found. + */ +extern int +image3TagIsPresent( + const Image3ObjectHandle withHandle, + const u_int32_t withTag); + +/* + * Fetch a numeric tag's value. + * + * Returns: + * 0 Success + * EINVAL The buffer is malformed. + * ENOENT The tag was not found. + */ +extern int +image3GetTagSignedNumber( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + int64_t *toNumber, + int skipCount); + +extern int +image3GetTagUnsignedNumber( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + u_int64_t *toNumber, + int skipCount); + +/* + * Fetch a string tag's value. + * + * Returns: + * 0 Success. *toBuffer contains an ASCIIZ string that must be freed by the caller. + * EINVAL The buffer is malformed. + * ENOENT The tag was not found. + */ +extern int +image3GetTagString( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + char **toBuffer, + int skipCount); + +/* + * Fetch a direct pointer to a structure tag. Note that this points into the image itself + * and should be used with some caution. + * + * The skipCount argument may be used to specify a number of matching tags to be ignored. + * + * Returns: + * 0 Success. + * EINVAL The buffer is malformed. + * ENOENT The tag was not found. + */ +extern int +image3GetTagStruct( + const Image3ObjectHandle withHandle, + const u_int32_t withTag, + void **structPtr, + size_t *structSize, + int skipCount); + +/* + * Compute the digest to be signed into the root ticket. If the image has been previously + * personalized with the old method (with a signature covering an added ECID tag), the digest + * excludes the personalized region. + * + * Although the underlying image3 buffer is returned unmodified, this function may + * temporarily modify the buffer when computing the hash. The buffer must therefore be in a + * writable region of memory. + + */ +extern int +image3GetPrePersonalizedDigest( + const Image3ObjectHandle withHandle, + uint8_t *hashBuffer, + size_t hashBufferLength); + +/* + * Return the nested image's handle (if one exists). + * + * Note that the nested image is only discoverable if an image is authenticated. + */ +Image3ObjectHandle +image3GetNestedImage(const Image3ObjectHandle withHandle); + + +#ifdef IMAGE3_DEBUG +extern void +_image3PrintImage(Image3ObjectHandle withHandle); + +#ifdef IMAGE3_UTILITY +int +_image3WriteData(Image3ObjectHandle withHandle, const char *path); +#endif /* IMAGE3_UTILITY */ + +#endif /* IMAGE3_DEBUG */ + +/* + * Prototypes for external functions that must be supplied. + */ + +/* + * Generate a SHA-1 hash of the supplied buffer. + */ +extern void +image3SHA1Generate(void *dataBuffer, size_t dataSize, void *hashBuffer); + +#ifdef IMAGE3_CREATOR +/* + * Generate a partial SHA-1 hash of the supplied buffer. + */ +void +image3SHA1Partial(void *dataBuffer, size_t dataSize, void *hashBuffer); +#endif /* IMAGE3_CREATOR */ + +/* + * Sign a hash. + */ +extern int +image3PKISignHash( + void *hashBuffer, + size_t hashSize, + void **resultPointer, + size_t *resultSize, + void **certBlobPointer, + size_t *certBlobSize); + +/* + * Verify the signature on a hash. + * + * Returns: + * 0 - image is valid and can be trusted + * EPERM - image is valid but cannot be trusted + * EINVAL - image is not valid, cannot be trusted + */ +extern int +image3PKIVerifyHash( + void *hashBuffer, + size_t hashSize, + void *signedHashBuffer, + size_t signedHashSize, + void *certBlobBuffer, + size_t certBlobSize, + void **certCustomData, + size_t *certCustomDataSize); + +/* + * Validate an image hash using the ticket database. + * + * Returns: + * 0 - image is valid and can be trusted + * EPERM - image is valid but cannot be trusted + * EINVAL - image is not valid, cannot be trusted + */ +extern int +image3TicketVerifyHash( + void *hashBuffer, + size_t hashSize, + uint32_t imageType, + uint32_t expectedType); + +/* + * Decrypt a buffer in-place using AES and a local unit-specific key. + */ +extern int +image3AESDecryptUsingLocalKey(void *buffer, size_t length); + +/* + * Encrypt a buffer in-place using AES and a local unit-specific key. + */ +extern void +image3AESEncryptUsingLocalKey(void *buffer, size_t length); + +/* + * Memory allocator + */ +extern void * +image3Malloc(size_t size); + +/* + * Memory de-allocator + */ +extern void +image3Free(void *ptr, size_t size); + +#endif /* _IMAGE3_H_ */ diff --git a/lib/image/image3/Image3Format.h b/lib/image/image3/Image3Format.h new file mode 100644 index 0000000..d7d1707 --- /dev/null +++ b/lib/image/image3/Image3Format.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2007-2011, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _IMAGE3_FORMAT_H_ +#define _IMAGE3_FORMAT_H_ + +#include + +/* + * All structures defined here are on-media formats. + */ +#pragma pack(push, 1) + +/* + * Fixed object header. + */ +typedef struct _Image3ObjectHeader { + /* these fields are unsigned */ + u_int32_t ihMagic; +#define kImage3HeaderMagic 'Img3' + u_int32_t ihSkipDistance; + u_int32_t ihBufferLength; + + /* fields below are signed */ + u_int32_t ihSignedLength; + u_int32_t ihType; + u_int8_t ihBuffer[]; +} Image3ObjectHeader; + +/* + * Generic tag header. + */ +typedef struct { + u_int32_t itTag; + u_int32_t itSkipDistance; + u_int32_t itBufferLength; + u_int8_t itBuffer[]; +} Image3TagHeader; + +#ifdef IMAGE3_CREATOR +/* + * Partial hash types. + */ +typedef struct { + /* number of valid bytes in the buffer */ + u_int32_t masteredReservationLength; + u_int32_t masteredSignedLength; + u_int8_t sha1_state[CCSHA1_OUTPUT_SIZE]; +} Image3PartialHash; +#endif /* IMAGE3_CREATOR */ + +/* + * Utility tag types. + */ +typedef struct { + /* number of valid bytes in the buffer */ + u_int32_t stringLength; + char stringBytes[]; +} Image3TagString; + +typedef struct { + union { + u_int32_t u32; + int32_t s32; + } value; +} Image3TagNumber32; + +typedef struct { + union { + u_int64_t u64; + int64_t s64; + } value; +} Image3TagNumber64; + +typedef struct { + union { + Image3TagNumber32 n32; + Image3TagNumber64 n64; + } number; +} Image3TagNumber; + +#ifdef IMAGE3_CREATOR +#define IMAGE_TYPE_EMBEDCERT 'cert' /* ihType of image embedded in leaf cert */ +#endif /* IMAGE3_CREATOR */ + +/* + * Defined tags and their datastructures. + */ + +#define kImage3TagTypeData 'DATA' /* opaque */ +#define kImage3TagTypeSignedHash 'SHSH' /* opaque */ +#define kImage3TagTypeCertificateChain 'CERT' /* opaque */ +#define kImage3TagTypeVersion 'VERS' /* string */ +#define kImage3TagTypeSecurityEpoch 'SEPO' /* number */ +#define kImage3TagTypeSecurityDomain 'SDOM' /* number */ +#define kImage3TagTypeProductionStatus 'PROD' /* number */ +#define kImage3TagTypeChipType 'CHIP' /* number */ +#define kImage3TagTypeBoardType 'BORD' /* number */ +#define kImage3TagTypeUniqueID 'ECID' /* number */ +#define kImage3TagTypeRandomPad 'SALT' /* number */ +#define kImage3TagTypeType 'TYPE' /* number */ +#define kImage3TagTypeOverride 'OVRD' /* bitmap */ +#define kImage3TagTypeHardwareEpoch 'CEPO' /* number */ +#define kImage3TagTypeNonce 'NONC' /* opaque */ + +#define kImage3TagTypeKeybag 'KBAG' +typedef struct { + u_int32_t kbSelector; +#define kImage3KeybagSelectorNoKey (0) +#define kImage3KeybagSelectorChipUnique (1) +#define kImage3KeybagSelectorChipUniqueDev (2) + u_int32_t kbKeySize; + u_int8_t kbIVBytes[16]; + u_int8_t kbKeyBytes[32]; +} Image3TagKBAG; + +#define kImage3SecurityDomainManufacturer 0 +#define kImage3SecurityDomainDarwin 1 +#define kImage3SecurityDomainRTXC 3 + +#define kImage3SecurityProductionStatus 1 + +#define kImage3OverrideProductionMode 1 + +/* restore structure packing */ +#pragma pack(pop) + +#endif /* _IMAGE3_FORMAT_H_ */ diff --git a/lib/image/image3/Image3SuperBlock.h b/lib/image/image3/Image3SuperBlock.h new file mode 100644 index 0000000..1c66fa5 --- /dev/null +++ b/lib/image/image3/Image3SuperBlock.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _IMAGE3_SUPER_BLOCK_H_ +#define _IMAGE3_SUPER_BLOCK_H_ + +/* + * All structures defined here are on-media formats. + */ +#pragma pack(push, 1) + +/* + * The I3 layout is described by the superblock, which is located at + * kI2SuperblockOffset from the top of the media. The superblock is a write-once + * item; it should only be updated when the bootblock code is rewritten, implying + * a complete re-initialisation of the media. + * + * Following the superblock there is a reserved area for boot code, after which + * image headers describe individual images. + * + * 0x0 -------------------- + * + * Image3Superblock + * ... + * ... + * 0x8000 -------------------- + * Image3Header + * ... + * Image3Header + * ... + * + */ + +typedef struct { + u_int32_t isMagic; +#define kImage2SuperMagic 0x494d4732 /* "IMG2" */ + u_int32_t isImageGranule; /* fundamental block size (bytes) */ + u_int32_t isImageOffset; /* image header offset within granule (image granules) */ + u_int32_t isBootBlockSize; /* size of the bootblock (image granules) */ + u_int32_t isImageAvail; /* total granules available for images. */ + u_int32_t isNvramGranule; /* size of NVRAM blocks (bytes) */ + u_int32_t isNvramOffset; /* offset to first NVRAM block (nvram granules) */ + u_int32_t isFlags; /* flags field reserved for future use */ + u_int32_t isRsvd1; /* reserved 1 for future use */ + u_int32_t isRsvd2; /* reserved 2 for future use */ + u_int32_t isRsvd3; /* reserved 3 for future use */ + u_int32_t isRsvd4; /* reserved 4 for future use */ + u_int32_t isCheck; /* CRC-32 of header fields preceding this one */ +} Image3Superblock; + +/* Image types */ +#define IMAGE_TYPE_DIAG 'diag' // diagnostics +#define IMAGE_TYPE_IBOOT_LLB 'illb' // iboot (darwin) first-stage loader +#define IMAGE_TYPE_IBOOT 'ibot' // iboot (darwin) loader +#define IMAGE_TYPE_DEVTREE 'dtre' // darwin device tree +#define IMAGE_TYPE_LOGO 'logo' // boot logo image +#define IMAGE_TYPE_RECMODE 'recm' // recovery mode image +#define IMAGE_TYPE_NEEDSERVICE 'nsrv' // recovery mode image +#define IMAGE_TYPE_BATTERYLOW0 'batl' // battery low image - empty +#define IMAGE_TYPE_BATTERYLOW1 'batL' // battery low image - red +#define IMAGE_TYPE_BATTERYCHRG 'batC' // battery charge image +#define IMAGE_TYPE_ENV 'ienv' // environment vars +#define IMAGE_TYPE_TSYS 'tsys' // tsys tester +#define IMAGE_TYPE_CHIME 'beep' // boot chime + +/* restore structure packing */ +#pragma pack(pop) + +#endif /* _IMAGE3_SUPER_BLOCK_H_ */ diff --git a/lib/image/image3/image3_wrapper.c b/lib/image/image3/image3_wrapper.c new file mode 100644 index 0000000..123840f --- /dev/null +++ b/lib/image/image3/image3_wrapper.c @@ -0,0 +1,1473 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_PKI +#include +#endif +#if WITH_TICKET +#include +#endif +#include "image3_wrapper.h" +#include "Image3Format.h" +#include "Image3.h" + +#define UNTAG(x) (((x) >> 24) & 0xff),(((x) >> 16) & 0xff),(((x) >> 8) & 0xff),((x) & 0xff) + +/* some sanity checking of cross-domain constants */ +#if kImage3SecurityDomainManufacturer != kPlatformSecurityDomainManufacturing +# error kImage3SecurityDomainManufacturer != kPlatformSecurityDomainManufacturing +#endif +#if kImage3SecurityDomainDarwin != kPlatformSecurityDomainDarwin +# error kImage3SecurityDomainDarwin != kPlatformSecurityDomainDarwin +#endif +#if kImage3KeybagSelectorChipUnique != IMAGE_KEYBAG_SELECTOR_PROD +# error kImage3KeybagSelectorChipUnique != IMAGE_KEYBAG_SELECTOR_PROD +#endif +#if kImage3KeybagSelectorChipUniqueDev != IMAGE_KEYBAG_SELECTOR_DEV +# error kImage3KeybagSelectorChipUniqueDev != IMAGE_KEYBAG_SELECTOR_DEV +#endif + + +struct image3_info { + struct list_node node; + + struct blockdev *bdev; /* device the image is on */ + off_t devOffset; /* where on the bdev it is */ + + Image3ObjectHandle imageHandle; /* if the image is loaded, its current handle */ + + struct image_info image_info; /* public image_info */ +}; + +static struct list_node images = LIST_INITIAL_VALUE(images); + +enum matching_relation { + REL_EQUAL, + REL_GREATER_EQUAL +}; + + +static int +image3_load_copyobject( + struct image_info *image_info, + void *objectBuffer, + size_t objectSize); + +static int +image3_load_validate_signature( + Image3ObjectHandle objectHandle, + u_int32_t expectedType, + bool requireTrust, + uint32_t validationFlags, + bool *untrustedImage, + bool *imageIncludesConstraints); + +static int +image3_load_validate_constraints( + Image3ObjectHandle objectHandle, + u_int32_t type, + bool requireTrust, + bool allowGreaterEpoch, + bool *clearProduction, + bool *untrustedImage); + +static int +image3_load_decrypt_payload( + Image3ObjectHandle objectHandle, + void *payloadBuffer, + size_t payloadSize, + void *destinationBuffer, + bool untrustedImage); + +static int +verifyIntersectingBits( + Image3ObjectHandle objectHandle, + u_int32_t withTag, + u_int64_t withBits, + bool tagIsRequired, + bool nestedImageOnly, + bool *tagWasPresent); + +static int +verifyNumberRelation( + Image3ObjectHandle objectHandle, + u_int32_t withTag, + u_int64_t requiredValue, + enum matching_relation relation, + bool tagIsRequired, + bool nestedImageOnly, + bool *tagWasPresent); + +static int +verifyMatchingBytes( + Image3ObjectHandle objectHandle, + u_int32_t withTag, + const void *testBytes, + size_t testBytesLength, + bool tagIsRequired, + bool *tagWasPresent); + +/* + * image3_process_superblock + * + * Searches the given bdev looking for image3 images. Returns a count of found + * images. + * + * We use the Image2 superblock format, but with Image3 object containers. + */ +int +image3_process_superblock(Image2Superblock *sblock, struct blockdev *bdev, off_t offset, uint32_t imageOptions) +{ + int imageCount; + Image3ObjectHeader objHeader; + struct image3_info *imageInfo; + int err; + off_t spaceBytes, cursor, residual; + + /* + * Validate the superblock + */ + + /* check magic number and basic integrity */ + if (sblock->isMagic != kImage2SuperMagic) { + dprintf(DEBUG_SPEW, "bad superblock magic\n"); + return(0); + } +#if !IMAGE3_NO_CRC + if (sblock->isCheck != crc32((unsigned char *)sblock, offsetof(Image2Superblock, isCheck))) { + dprintf(DEBUG_SPEW, "superblock CRC mismatch\n"); + return(0); + } +#endif + + /* validate isImageGranule and isImageAvail, assuming bdev->total_len and offset is trusted */ + RELEASE_ASSERT(offset >= 0); + if ((uint64_t)offset > bdev->total_len) { + dprintf(DEBUG_SPEW, "superblock outside blockdev\n"); + return(0); + } + spaceBytes = bdev->total_len - offset; + if ((0 == sblock->isImageGranule) || + (0 == sblock->isImageAvail)) { + dprintf(DEBUG_SPEW, "granule/avail zero\n"); + return(0); + } + if (sblock->isImageGranule > spaceBytes) { + dprintf(DEBUG_SPEW, "granule > allocated space\n"); + return(0); + } + if (sblock->isImageAvail > (spaceBytes / sblock->isImageGranule)) { + dprintf(DEBUG_SPEW, "avail > allocated space\n"); + return(0); + } + + /* validate isBootBlockSize */ + /* XXX 7561698 use of isImageOffset here is inconsistent with doc, seems to be just an adjunct to isBootBlockSize */ + if ((0 == sblock->isBootBlockSize) || + (sblock->isBootBlockSize > sblock->isImageAvail) || + (sblock->isImageOffset > (sblock->isImageAvail - sblock->isBootBlockSize))) { + dprintf(DEBUG_SPEW, "bad bootblock size\n"); + return(0); + } + + /* + * Compute the initial cursor value and residual byte count. + * XXX 7561698 this isn't how isImageOffset is documented to be used. + */ + cursor = ((off_t) sblock->isBootBlockSize + (off_t) sblock->isImageOffset) * (off_t) sblock->isImageGranule + offset; + residual = (off_t) sblock->isImageAvail * (off_t) sblock->isImageGranule; + + /* + * Make sure we don't try to go past the end of the blockdev. The code above is baroque + * and legacy enough that this additional check will just be a soft error. + */ + if (residual + cursor < cursor) { + dprintf(DEBUG_SPEW, "overflow\n"); + return(0); + } + if (residual + cursor > spaceBytes) { + residual = spaceBytes - cursor; + } + + /* + * Scan the image space and build a list of visible images. + */ + for (imageCount = 0; imageCount < IMAGE_MAX_COUNT; imageCount++) { + /* read the next image header */ + err = blockdev_read(bdev, &objHeader, cursor, sizeof(objHeader)); + if (err != sizeof(objHeader)) { + dprintf(DEBUG_SPEW, "error reading image header @ 0x%llx\n", cursor); + break; + } + + /* sanity-check the header */ + if (objHeader.ihMagic != kImage3HeaderMagic) + break; + if (objHeader.ihSkipDistance > residual) + break; + if (objHeader.ihSkipDistance % sblock->isImageGranule) + break; + if ((uint32_t)(objHeader.ihBufferLength + sizeof(Image3ObjectHeader)) < objHeader.ihBufferLength) + break; /* wraparound */ + if ((uint32_t)(objHeader.ihBufferLength + sizeof(Image3ObjectHeader)) > residual) + break; + + /* it will do for now, make a note */ + imageInfo = malloc(sizeof(*imageInfo)); + + /* build our private image info */ + imageInfo->bdev = bdev; + imageInfo->devOffset = cursor; + imageInfo->imageHandle = NULL; + + /* build the public image info */ + imageInfo->image_info.imageLength = objHeader.ihSignedLength; /* overstated */ + imageInfo->image_info.imageAllocation = objHeader.ihBufferLength + sizeof(Image3ObjectHeader); + imageInfo->image_info.imageType = objHeader.ihType; + imageInfo->image_info.imagePrivateMagic = IMAGE3_IMAGE_INFO_MAGIC; + imageInfo->image_info.imageOptions = (imageOptions & IMAGE_OPTION_MEMORY); + imageInfo->image_info.imagePrivate = imageInfo; + + /* append to the list */ + list_add_tail(&images, &imageInfo->node); + + /* advance to the next image */ + if (objHeader.ihSkipDistance < objHeader.ihBufferLength) { + imageCount++; /* account for this image */ + break; /* image terminates normally */ + } + cursor += objHeader.ihSkipDistance; + residual -= objHeader.ihSkipDistance; + } + dprintf(DEBUG_SPEW, "%d images\n", imageCount); + return(imageCount); +} + +/* + * image3_free_bdev + * + * Frees resources for any previously found images on the specified bdev. + * Useful for starting afresh with a new image superblock. + */ +void +image3_free_bdev(struct blockdev *bdev) +{ + struct image3_info *img, *tmp; + + list_for_every_entry_safe(&images, img, tmp, struct image3_info, node) { + if (img->image_info.imagePrivateMagic == IMAGE3_IMAGE_INFO_MAGIC && + img->bdev == bdev) { + list_delete(&img->node); + free(img); + } + } +} + +/* + * image3_find + * + * Returns the image_info handle to the first image of the specified type. + */ +struct image_info * +image3_find(u_int32_t image_type) +{ + struct image3_info *image; + + list_for_every_entry(&images, image, struct image3_info, node) { + if (image->image_info.imageType == image_type) + return(&image->image_info); + } + + return(NULL); +} + +/* + * image3_load + * + * Loads the image, with the DATA tag payload ultimately placed at *load_addr and its + * size in *load_len. + * + * It is the caller's responsibility to ensure that the load address is specified + * and that the buffer is large enough (image_info.imageAllocation). + */ +int +image3_load(struct image_info *image_info, const u_int32_t *types, u_int32_t count, u_int32_t *actual, void **load_addr, size_t *load_len) +{ + int result; + Image3ObjectHandle objectHandle; + void *objectBuffer; + size_t objectSize; + void *payloadBuffer; + size_t payloadSize; + bool fromLocalStorage; + bool untrustedImage; + bool imageIncludesConstraints; + bool clearProduction; + u_int32_t validationFlags; + u_int32_t type; + u_int32_t actualType; + u_int32_t cnt; + bool matchedType; + + /* basic sanity on arguments */ + RELEASE_ASSERT(NULL != image_info); + RELEASE_ASSERT(NULL != load_addr); + RELEASE_ASSERT(NULL != load_len); + RELEASE_ASSERT(0 != *load_len); + + untrustedImage = false; + clearProduction = false; + result = -1; + objectHandle = 0; + objectBuffer = *load_addr; + objectSize = image_info->imageAllocation; + + /* refuse to operate on an object that is larger than the load buffer */ + if (objectSize > *load_len) { + dprintf(DEBUG_INFO, "loaded image too large\n"); + platform_record_breadcrumb_int("image3_fail", kBCImg3TooLarge); + + goto out; + } + + /* refuse to operate on an object buffer at zero */ + if (NULL == objectBuffer) { + dprintf(DEBUG_INFO, "cannot load image with buffer at zero\n"); + platform_record_breadcrumb_int("image3_fail", kBCImg3NullPtr); + goto out; + } + + /* + * Fetch the object into the supplied (presumed safe) buffer. + */ + if (image3_load_copyobject(image_info, objectBuffer, objectSize)) + goto out; + + /* if we are just being asked to load the image whole, we're done here */ + if (image_info->imageOptions & IMAGE_OPTION_JUST_LOAD) { + result = 0; + goto out; + } + + /* + * Instantiate the Image3 object. + */ + dprintf(DEBUG_SPEW, "instantiating image\n"); + if (0 != image3InstantiateFromBuffer( + &objectHandle, + objectBuffer, + objectSize, + false /* copy */)) { + dprintf(DEBUG_INFO, "image instantiation failed\n"); + platform_record_breadcrumb_int("image3_fail", kBCImg3InstantiationFailed); + goto out; + } + + /* + * Assume that the object's type hint is the actual type. + */ + actualType = (*(Image3ObjectHeader **)objectHandle)->ihType; + + /* + * If the caller provided a list of types, + * check if the actual type matches one of + * the types the caller will accept. + */ + if (count != 0) { + matchedType = false; + for (cnt = 0; cnt < count; cnt++) { + if (types[cnt] == actualType) { + matchedType = true; + break; + } + } + + if (!matchedType) { + dprintf(DEBUG_INFO, "image type not accepted by caller\n"); + platform_record_breadcrumb_int("image3_fail", kBCImg3UnacceptedType); + goto out; + } + + type = actualType; + } else { + type = IMAGE_TYPE_ANY; + } + + /* + * Validate the image, either using the ticket library or with the + * included signature. If both local storage and memory are specified, + * local storage wins + */ + fromLocalStorage = + (image_info->imagePrivateMagic == IMAGE3_IMAGE_INFO_MAGIC && + !(image_info->imageOptions & IMAGE_OPTION_MEMORY)) || + (image_info->imageOptions & IMAGE_OPTION_LOCAL_STORAGE); + + validationFlags = (fromLocalStorage ? kImage3ValidateLocalStorage : 0); +#if WITH_TICKET + validationFlags |= (ticket_validation_required() ? kImage3ValidateRequireTicket : 0); +#endif + + imageIncludesConstraints = false; + + if (0 != image3_load_validate_signature(objectHandle, + type, + (image_info->imageOptions & IMAGE_OPTION_REQUIRE_TRUST), + validationFlags, + &untrustedImage, + &imageIncludesConstraints)) { + /* signature validation failed and we are not willing to accept an untrusted image */ + platform_record_breadcrumb_int("image3_fail", kBCImg3SignatureValidationFail); + goto out; + } + + /* + * Apply additional constraints to the image that may further + * reject trust, if they can be provided by the image. + */ + if (imageIncludesConstraints) { + if (0 != image3_load_validate_constraints(objectHandle, + type, + (image_info->imageOptions & IMAGE_OPTION_REQUIRE_TRUST), + (image_info->imageOptions & IMAGE_OPTION_GREATER_EPOCH), + &clearProduction, + &untrustedImage)) { + /* constraint validation failed and we are not willing to accept an invalid image */ + dprintf(DEBUG_INFO, "image is not valid for this device\n"); + platform_record_breadcrumb_int("image3_fail", kBCImg3ConstraintValidationFail); + goto out; + } + } + + /* + * By this point, the image is required to have been validated by either the ticket or + * image3 signature. + */ + + /* + * Find the payload. + */ + dprintf(DEBUG_SPEW, "looking for payload\n"); + payloadSize = 0; /* any size is OK */ + if (0 != image3GetTagStruct( + objectHandle, + kImage3TagTypeData, + &payloadBuffer, + &payloadSize, + 0)) { + dprintf(DEBUG_INFO, "image3GetTagStruct failed for payload lookup\n"); + platform_record_breadcrumb_int("image3_fail", kBCImg3GetTagStructFailed); + goto out; + } + +#if WITH_AES + /* + * Decrypt the payload data if required. Whether or not the payload is encrypted, + * on success it will be moved to the base of the buffer. + */ + if (0 != image3_load_decrypt_payload(objectHandle, + payloadBuffer, + payloadSize, + objectBuffer, + untrustedImage)) { + /* the image is encrypted but we can't decrypt it */ + platform_record_breadcrumb_int("image3_fail", kBCImg3DecryptFailed); + goto out; + } +#else + memmove(objectBuffer, payloadBuffer, payloadSize); +#endif /* WITH_AES */ + + + /* + * All done and OK; pass the actual payload size back to the caller. + */ + *load_len = payloadSize; + result = 0; + + /* + * If the image is trusted, and it has asserted that we should clear the + * production status flag, do that now. + */ + if ((false == untrustedImage) && + (true == clearProduction)) + security_set_production_override(true); + + /* + * Provide the actual type to the caller. + */ + if (actual != NULL) { + *actual = actualType; + } + +out: + /* clean up */ + if (objectHandle) { + image3Discard(&objectHandle); + objectHandle = 0; + } + + /* + * If we failed, nuke the caller's pointers and clear the work buffer. + */ + if (result != 0) { + dprintf(DEBUG_SPEW, "load failed, clearing object buffer\n"); + memset(*load_addr, 0, *load_len); + *load_addr = 0; + *load_len = 0; + } + + return(result); +} + +/* + * image3_load_copyobject + * + * Fetch an image3 object from its current location into the supplied object buffer. + */ +static int +image3_load_copyobject(struct image_info *image_info, void *objectBuffer, size_t objectSize) +{ + struct image3_info *image; + int result; + + PROFILE_ENTER('ILC'); + + RELEASE_ASSERT(NULL != objectBuffer); + RELEASE_ASSERT(0 != objectSize); + + dprintf(DEBUG_SPEW, "loading image %p with buffer %p/%x\n", image_info, objectBuffer, (unsigned)objectSize); + + switch (image_info->imagePrivateMagic) { + case IMAGE3_IMAGE_INFO_MAGIC: + /* + * Fetch the image data from the bdev into the caller-supplied + * scratch buffer. + */ + dprintf(DEBUG_SPEW, "reading image from bdev\n"); + image = (struct image3_info *)(image_info->imagePrivate); + result = blockdev_read(image->bdev, + objectBuffer, + image->devOffset, + objectSize); + if (result != (int)objectSize) { + dprintf(DEBUG_CRITICAL, "blockdev read failed with %d\n", result); + platform_record_breadcrumb_int("image3_fail", kBCImg3BDEVReadFail); + return(-1); + } + break; + + case IMAGE_MEMORY_INFO_MAGIC: + /* + * Copy the image data from the memory buffer into the + * caller-supplied scratch buffer. + * + * If the caller does not supply a buffer, the image is assumed to be in + * 'trusted' memory already and is left where it is. + */ + if (((Image3ObjectHeader *)image_info->imagePrivate)->ihMagic != kImage3HeaderMagic) { + dprintf(DEBUG_INFO, "image magic %x not image3\n", + ((Image3ObjectHeader *)image_info->imagePrivate)->ihMagic); + platform_record_breadcrumb_int("image3_fail", kBCImg3BadMagic); + return(-1); + } + if (objectBuffer != image_info->imagePrivate) { + dprintf(DEBUG_SPEW, "reading image from %p/%x\n", image_info->imagePrivate, (unsigned) objectSize); + memmove(objectBuffer, image_info->imagePrivate, objectSize); + } + break; + + default: + dprintf(DEBUG_INFO, "unrecognised image source type %x\n", image_info->imagePrivateMagic); + platform_record_breadcrumb_int("image3_fail", kBCImg3UnknownPrivateMagic); + return(-1); + } + + PROFILE_EXIT('ILC'); + + return(0); +} + +/* + * image3_load_validate_signature + * + * Validate the signature on the object (if present). + * + * If the image was created from memory and the supplier didn't assert it was from + * local storage, the signature won't have been personalised. + */ +static int +image3_load_validate_signature(Image3ObjectHandle objectHandle, + uint32_t expectedType, + bool requireTrust, + uint32_t validationFlags, + bool *untrustedImage, + bool *imageIncludesConstraints) +{ + int result; + + PROFILE_ENTER('ILV'); + + RELEASE_ASSERT(NULL != objectHandle); + RELEASE_ASSERT(NULL != untrustedImage); + + /* try to validate the signature */ + result = image3ValidateSignature(objectHandle, expectedType, validationFlags, imageIncludesConstraints); + + switch (result) { + case 0: + /* image has a signature and we believe it's valid */ + dprintf(DEBUG_SPEW, "image trusted\n"); + break; + + case EPERM: + /* + * The image is not signed or signature is invalid. + * + * If the image was created with 'enhanced security', this is fatal. Otherwise + * tell the security system and see if it's OK for us to use the image. + * + * Note that the security call may adjust the state of the system in order + * to ensure that it is safe to run untrusted code before replying OK. + */ + dprintf(DEBUG_SPEW, "image not trusted\n"); + if (requireTrust || !security_validate_image(kSecurityImageUntrusted)) { + /* policy says that we aren't allowed to use un-trusted images */ + dprintf(DEBUG_INFO, "image validation failed and untrusted images are not permitted\n"); + return(-1); + } + + /* + * Security system says it's OK to load untrusted images, and the client + * hasn't explicitly asked for a trusted image, so let our caller know that + * this image is *not* trusted, but return success. + */ + *untrustedImage = true; + dprintf(DEBUG_INFO, "untrusted image loaded\n"); + break; + + default: + /* something went wrong */ + dprintf(DEBUG_INFO, "image validation returned %d\n", result); + return(-1); + } + + PROFILE_EXIT('ILV'); + + return(0); +} + +/* + * Validate that constraints supplied by the image are met. + * + * This function currently requires that the image be considered trusted on entry. + */ +static int +image3_load_validate_constraints(Image3ObjectHandle objectHandle, + u_int32_t type, + bool requireTrust, + bool allowGreaterEpoch, + bool *clearProduction, + bool *untrustedImage) +{ + u_int64_t nonce; + u_int8_t nonce_hash[20]; + + PROFILE_ENTER('IVC'); + + RELEASE_ASSERT(NULL != objectHandle); + RELEASE_ASSERT(NULL != clearProduction); + RELEASE_ASSERT(NULL != untrustedImage); + + /* + * Validate that the image has been signed with a certificate that meets + * the following constraints: + * Security Domain of the cert matches the platform + * Production Mode of the cert is allowed by the platform + * Chip ID of the cert matches the platform + */ + + /* + * Verify that the image's cert meets the platform's security domain constraints. + * + * Images must be signed for the security domain advertised by the platform. + */ + dprintf(DEBUG_SPEW, "verifying platform constraints\n"); + /* tag must be present in this case */ + if (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeSecurityDomain, + platform_get_security_domain(), + REL_EQUAL, + true /* tagIsRequired */, + true /* nestedImageOnly */, + NULL /* tagWasPresent */)) { + + dprintf(DEBUG_SPEW, "invalid security domain in certificate\n"); + goto verify_untrusted; + } + + /* + * Verify that the image's cert meets the platform's production status constraints. + * + * If we are in production mode, the image's cert must have a production status tag + * and the tag's value must be correct. + */ + if (platform_get_raw_production_mode()) { + if (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeProductionStatus, + kImage3SecurityProductionStatus, + REL_EQUAL, + true /* tagIsRequired */, + true /* nestedImageOnly */, + NULL /* tagWasPresent */)) { + + dprintf(DEBUG_SPEW, "invalid production status in certificate\n"); + goto verify_untrusted; + } + + /* + * If the client is willing to consider an override of the device's production + * status, check for an override tag. + */ + if (0 != verifyIntersectingBits( + objectHandle, + kImage3TagTypeOverride, + kImage3OverrideProductionMode, + false /* tagIsRequired */, + true /* nestedImageOnly */, + clearProduction /* tagWasPresent */)) { + + dprintf(DEBUG_SPEW, "invalid override tag in certificate\n"); + goto verify_untrusted; + } + } + + /* + * Verify that the image's cert meets the platform's chip id constraints. + * + * Images must be signed for the chip id advertised by the platform. + * + */ + if (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeChipType, + platform_get_chip_id(), + REL_EQUAL, + true /* tagIsRequired */, + true /* nestedImageOnly */, + NULL /* tagWasPresent */)) { + + dprintf(DEBUG_SPEW, "invalid chip type in certificate\n"); + goto verify_untrusted; + } + + /* + * Verify that the image's type matches the requested + * type and that type is not IMAGE_TYPE_ANY. + */ + if ((type != IMAGE_TYPE_ANY) && + (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeType, + type, + REL_EQUAL, + true /* tagIsRequired */, + false /* !nestedImageOnly */, + NULL /* tagWasPresent */))) { + + /* + * If the security system says it's OK to execute untrusted images, + * we say it's OK to execute the wrong type of image, too. + */ + dprintf(DEBUG_SPEW, "invalid image type\n"); + goto verify_untrusted; + } + + /* + * Validate that the image meets the following optional constraints: + * Security Epoch of the image must match the platform + * Hardware Epoch of the image's cert must be valid on the platform + * Board ID of the image much match the platform + * ECID of the image must match the platform + */ + + /* + * Verify that the image is compatible with the current epoch. + * + * If the image is created with explicit permission for epoch mismatch on the + * later side, be permissive, otherwise require an exact match. + */ + if (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeSecurityEpoch, + platform_get_security_epoch(), + (allowGreaterEpoch ? REL_GREATER_EQUAL : REL_EQUAL), + false /* !tagIsRequired */, + false /* !nestedImageOnly */, + NULL /* tagWasPresent */)) { + + dprintf(DEBUG_SPEW, "invalid security epoch\n"); + goto verify_untrusted; + } + + /* + * Verify that the certificate is compatible with the current hardware epoch. + * + * The image must be signed with a certificate that has an epoch greater + * than or equal to the chip's minimum epoch. + */ + if (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeHardwareEpoch, + platform_get_hardware_epoch(), + REL_GREATER_EQUAL, + false /* !tagIsRequired */, + true /* nestedImageOnly */, + NULL /* tagWasPresent*/)) { + + dprintf(DEBUG_SPEW, "invalid hardware epoch\n"); + goto verify_untrusted; + } + + /* + * Look for and check the current chip, board, ECID and nonce against any list supplied with the image. + */ + if (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeBoardType, + platform_get_board_id(), + REL_EQUAL, + false /* !tagIsRequired */, + false /* !nestedImageOnly */, + NULL /* tagWasPresent */)) { + + /* + * If the security system says it's OK to execute untrusted images, + * we say it's OK to execute images tagged for the wrong board too. + */ + dprintf(DEBUG_SPEW, "invalid board type\n"); + goto verify_untrusted; + } + + if (0 != verifyNumberRelation( + objectHandle, + kImage3TagTypeUniqueID, + platform_get_ecid_id(), + REL_EQUAL, + platform_get_ecid_image_personalization_required() /* tagIsRequired? */, + false /* !nestedImageOnly */, + NULL /* tagWasPresent */)) { + + dprintf(DEBUG_SPEW, "invalid unique chip id\n"); + goto verify_untrusted; + } + + nonce = platform_get_nonce(); + sha1_calculate((const void *)&nonce, sizeof(nonce), (void *)nonce_hash); + + if (0 != verifyMatchingBytes( + objectHandle, + kImage3TagTypeNonce, + nonce_hash, + sizeof(nonce_hash), + false /* !tagIsRequired */, + NULL /* tagWasPresent */)) { + + dprintf(DEBUG_SPEW, "invalid nonce\n"); + goto verify_untrusted; + } + + PROFILE_EXIT('IVC'); + + return(0); + +verify_untrusted: + /* + * A constraint has not been met. + * + * If the image was created with 'enhanced security', this is fatal. Otherwise + * tell the security system and see if it's OK for us to use the image. + * + * Note that the security call may adjust the state of the system in order + * to ensure that it is safe to run untrusted code before replying OK. + */ + if (requireTrust || !security_validate_image(kSecurityImageUntrusted)) { + /* policy says that we aren't allowed to use un-trusted images */ + dprintf(DEBUG_INFO, "image validation failed and untrusted images are not permitted\n"); + return(-1); + } + dprintf(DEBUG_CRITICAL, "image validation failed but untrusted images are permitted\n"); + *untrustedImage = true; + + return(0); +} + +#if WITH_AES +/* + * image3_load_decrypt_payload + * + * Decrypt the payload contents if they are encrypted and we can find a key + * that matches. + */ +struct ivkey { + u_int8_t IV[16]; + u_int8_t Key[32]; +} __packed; + +static int +image3_load_decrypt_payload(Image3ObjectHandle objectHandle, + void *payloadBuffer, + size_t payloadSize, + void *destinationBuffer, + bool untrustedImage) +{ + int result; + Image3TagKBAG *keyBag; + u_int32_t platformKeyOpts; + size_t paddedPayloadSize; + size_t keybagSize; + u_int32_t keybagKeyOpts; + size_t keybagKeySize; + struct ivkey keybagIVKey; + + PROFILE_ENTER('IDP'); + + /* + * Note that we cannot assert that the payload size is clean % 16. + * The image3 generation code guarantees that tags are padded such + * that there is always enough space for data items to be decrypted + * without touching data outside the tag, and that any data in a + * tag that's been encyrypted is padded out to suit, however the payload + * size that is visible is the actual byte size of the data. + */ + RELEASE_ASSERT(NULL != payloadBuffer); + RELEASE_ASSERT(0 != payloadSize); + + /* initialise state */ + result = -1; + memset(&keybagIVKey, 0, sizeof(keybagIVKey)); + + /* + * Look for payload encryption keybags, see if there is one for us. + * + * If there is, unpack the key and use it and the decryption to move + * the payload to the head of the buffer. If there are keybags but not one + * for us, that's an error. + * + * If there are no keybags or the image was untrusted, just copy the image directly. + */ + dprintf(DEBUG_SPEW, "checking for encrypted payload\n"); + for (int keybagIndex = 0; ; keybagIndex++) { + + /* + * Fetch the next keybag. + */ + keybagSize = sizeof(*keyBag); + result = image3GetTagStruct( + objectHandle, + kImage3TagTypeKeybag, + (void *)&keyBag, + &keybagSize, + keybagIndex); + if (result == ENOENT) { + if (keybagIndex == 0) { + /* there are no keybags, payload is not encrypted; just move the + payload to the destination and return */ + memmove(destinationBuffer, payloadBuffer, payloadSize); + result = 0; + goto out; + } + /* there were keybags but not one we recognised */ + dprintf(DEBUG_INFO, "failed to find a keybag for this system\n"); + goto out; + } + + /* + * If the image is untrusted but encrypted, refuse to decrypt it. + */ + if (untrustedImage) { + dprintf(DEBUG_INFO, "encrypted image found but we do not trust it\n"); + goto out; + } + + /* work out how big the key is going to be */ + keybagKeyOpts = AES_KEY_TYPE_USER; + switch (keyBag->kbKeySize) { + case 128 : keybagKeyOpts |= AES_KEY_SIZE_128; break; + case 192 : keybagKeyOpts |= AES_KEY_SIZE_192; break; + case 256 : keybagKeyOpts |= AES_KEY_SIZE_256; break; + default: + /* not a valid AES key size, bail */ + dprintf(DEBUG_INFO, "AES key size %d not supported/valid\n", keyBag->kbKeySize); + goto out; + } + keybagKeySize = keyBag->kbKeySize / 8; + RELEASE_ASSERT(keybagKeySize <= sizeof(keybagIVKey.Key)); + + /* copy the IV from the keybag */ + memcpy(&keybagIVKey.IV, keyBag->kbIVBytes, sizeof(keybagIVKey.IV)); + + /* copy the key from the keybag */ + memcpy(&keybagIVKey.Key, keyBag->kbKeyBytes, keybagKeySize); + + switch (keyBag->kbSelector) { + case kImage3KeybagSelectorNoKey: + /* key is not encrypted, just use it as-is */ + dprintf(DEBUG_SPEW, "using non-wrapped AES key\n"); + break; + default: + /* ask platform for key details */ + platformKeyOpts = 0; + if (platform_translate_key_selector(keyBag->kbSelector, &platformKeyOpts) != 0) { + /* we don't recognise this key, spin and try again */ + dprintf(DEBUG_SPEW, "key selector %d not recognised\n", keyBag->kbSelector); + continue; + } + dprintf(DEBUG_SPEW, "using key selector %d\n", keyBag->kbSelector); + if (aes_cbc_decrypt(&keybagIVKey, + &keybagIVKey, + sizeof(keybagIVKey.IV) + keybagKeySize, + platformKeyOpts, + 0, + 0)) { + dprintf(DEBUG_INFO, "cannot decrypt image - hardware AES keys disabled\n"); + goto out; + } + break; + } + + /* + * Decrypt the payload. + * + * Note that if the claimed payload size is not mod16, the buffer + * has been padded by the image3 generator. Note also that at this + * point we trust the container. + */ + if ((payloadSize % 16) != 0) { + paddedPayloadSize = payloadSize + (16 - (payloadSize % 16)); + } else { + paddedPayloadSize = payloadSize; + } + dprintf(DEBUG_SPEW, "AES operation 0x%zx bytes\n", paddedPayloadSize); + result = aes_cbc_decrypt(payloadBuffer, + destinationBuffer, + paddedPayloadSize, + keybagKeyOpts, + &keybagIVKey.Key, + &keybagIVKey.IV); + + /* clear the iv & key from memory */ + memset(&keybagIVKey, 0, sizeof(keybagIVKey)); + + if (result) + dprintf(DEBUG_INFO, "cannot decrypt image - unexpected AES failure"); + goto out; + } + dprintf(DEBUG_INFO, "could not find a compatible keybag\n"); +out: + PROFILE_EXIT('IDP'); + return(result); +} +#endif /* WITH_AES */ + +/* + * Verify that if the image (and optionally the signing cert's embedded image) has the specified + * tag, that there is some intersection between its value and the supplied bits. + */ +static int +verifyIntersectingBits( + Image3ObjectHandle objectHandle, + u_int32_t withTag, + u_int64_t withBits, + bool tagIsRequired, + bool nestedImageOnly, + bool *tagWasPresent) +{ + Image3ObjectHandle nestedObjectHandle; + u_int64_t value; + int result; + int nestedResult; + bool wasPresent; + bool nestedWasPresent; + + result = 0; + wasPresent = false; + + /* + * Check against the nested object handle first if one exists by recursively calling ourself. + * Since tagIsRequired is not set, nestedResult will be 0 if the tag was not present or the relation is valid. + * nestedResult will only be EPERM if the tag was present but the relation was not valid. + * nestedWasPresent will indicate if the tag was present. + */ + if ((nestedObjectHandle = image3GetNestedImage(objectHandle))) { + nestedResult = verifyIntersectingBits(nestedObjectHandle, withTag, withBits, false, false, &nestedWasPresent); + } else { + nestedResult = 0; + nestedWasPresent = false; + } + + if (nestedImageOnly) + goto out; + + /* check the image */ + switch ((result = image3GetTagUnsignedNumber( + objectHandle, + withTag, + &value, 0))) { + case ENOENT: + result = 0; + break; + + case 0: + wasPresent = true; + /* there are stipulated domains, ensure that we intersect */ + if (!(value & withBits)) { + dprintf(DEBUG_INFO, "tag %c%c%c%c value 0x%x missing required bits 0x%x\n", + UNTAG(withTag), (unsigned) value, (unsigned) withBits); + result = EPERM; + } + break; + + default: + /* something bad happened */ + dprintf(DEBUG_INFO, "unexpected error %d while attempting to find tag %c%c%c%c\n", result, UNTAG(withTag)); + break; + } +out: + /* let nestedResult override result */ + if (nestedResult != 0) + result = nestedResult; + + /* merge wasPresent with nestedWasPresent */ + wasPresent |= nestedWasPresent; + + /* if requested, provide wasPresent back to the caller */ + if (tagWasPresent) + *tagWasPresent = wasPresent; + + /* if no tags of the specified type, permission depends on the tag requirement */ + if (tagIsRequired && !wasPresent) + result = EPERM; + + return(result); +} + +/* + * Verify that, if any tags matching withTag are present, that one of them has the testValue. + * + * In the case where the nested image is present, the same applies to both. + */ +static int +verifyNumberRelation( + Image3ObjectHandle objectHandle, + u_int32_t withTag, + u_int64_t testValue, + enum matching_relation relation, + bool tagIsRequired, + bool nestedImageOnly, + bool *tagWasPresent) +{ + Image3ObjectHandle nestedObjectHandle; + u_int64_t value; + int result; + int nestedResult; + int tagInstance; + bool wasPresent; + bool nestedWasPresent; + + result = 0; + wasPresent = false; + + /* + * Check against the nested object handle first if one exists by recursively calling ourself. + * Since tagIsRequired is not set, nestedResult will be 0 if the tag was not present or the relation is valid. + * nestedResult will only be EPERM if the tag was present but the relation was not valid. + * nestedWasPresent will indicate if the tag was present. + */ + if ((nestedObjectHandle = image3GetNestedImage(objectHandle))) { + nestedResult = verifyNumberRelation(nestedObjectHandle, withTag, testValue, relation, false, false, &nestedWasPresent); + } else { + nestedResult = 0; + nestedWasPresent = false; + } + + if (nestedImageOnly) + goto out; + + /* + * Iterate over instances of the tag, looking for a match. + */ + wasPresent = false; + for (tagInstance = 0; ; tagInstance++) { + switch ((result = image3GetTagUnsignedNumber( + objectHandle, + withTag, + &value, + tagInstance))) { + case ENOENT: + if (tagInstance == 0) { + result = 0; + } else { + /* no matching tags of the specified type, permission is denied */ + result = EPERM; + } + goto out; + + case 0: + wasPresent = true; + /* if the value matches, we are done */ + switch (relation) { + case REL_EQUAL: + if (value == testValue) + goto out; + break; + case REL_GREATER_EQUAL: + if (value >= testValue) + goto out; + break; + default: + /* whatever */ + break; + } + break; + + default: + dprintf(DEBUG_INFO, "unexpected error %d while searching for tag %c%c%c%c instance %d\n", + result, UNTAG(withTag), tagInstance); + goto out; + } + } +out: + /* let nestedResult override result */ + if (nestedResult != 0) + result = nestedResult; + + /* merge wasPresent with nestedWasPresent */ + wasPresent |= nestedWasPresent; + + /* If requested, provide wasPresent back to the caller */ + if (tagWasPresent) + *tagWasPresent = wasPresent; + + /* if no tags of the specified type, permission depends on the tag requirement */ + if (tagIsRequired && !wasPresent) + result = EPERM; + + return(result); +} + +/* + * Verify that, if any tags matching withTag are present, that one of them has the testBytes. + * + */ +static int +verifyMatchingBytes( + Image3ObjectHandle objectHandle, + u_int32_t withTag, + const void *testBytes, + size_t testBytesLength, + bool tagIsRequired, + bool *tagWasPresent) +{ + void *bytes; + int result; + int tagInstance; + bool wasPresent; + + result = 0; + wasPresent = false; + bytes = NULL; + + /* + * Iterate over instances of the tag, looking for a match. + */ + wasPresent = false; + for (tagInstance = 0; ; tagInstance++) { + switch ((result = image3GetTagStruct( + objectHandle, + withTag, + (void **)&bytes, + (size_t *)&testBytesLength, + tagInstance))) { + case ENOENT: + if (tagInstance == 0) { + result = 0; + } else { + /* no matching tags of the specified type, permission is denied */ + result = EPERM; + } + goto out; + + case 0: + wasPresent = true; + /* if the value matches, we are done */ + if (memcmp(testBytes, (const void *)bytes, testBytesLength) == 0) + goto out; + break; + + default: + dprintf(DEBUG_INFO, "unexpected error %d while searching for tag %c%c%c%c instance %d\n", + result, UNTAG(withTag), tagInstance); + goto out; + } + } +out: + /* If requested, provide wasPresent back to the caller */ + if (tagWasPresent) + *tagWasPresent = wasPresent; + + /* if no tags of the specified type, permission depends on the tag requirement */ + if (tagIsRequired && !wasPresent) + result = EPERM; + + return(result); +} + +/* + * image3_dump_list + * + * Print the list of currently-known images. + */ +void +image3_dump_list(bool detailed) +{ + struct image3_info *image; + + list_for_every_entry(&images, image, struct image3_info, node) { + + printf("image %p: bdev %p type %c%c%c%c offset 0x%llx", + image, + image->bdev, + UNTAG(image->image_info.imageType), + image->devOffset); + if (image->image_info.imageLength > 0) { + printf(" len 0x%x", + image->image_info.imageLength); + } + printf("\n"); + } +} + +/* + * Support for the Image3 core library. + */ +int +image3AESDecryptUsingLocalKey(void *buffer, size_t length) +{ +#if WITH_AES + unsigned char derivedSeed[16] = {0xdb, 0x1f, 0x5b, 0x33, 0x60, 0x6c, 0x5f, 0x1c, + 0x19, 0x34, 0xaa, 0x66, 0x58, 0x9c, 0x06, 0x61}; + unsigned char derivedKey[16]; + + /* derive the key */ + if (aes_cbc_encrypt(derivedSeed, derivedKey, 16, AES_KEY_SIZE_128 | AES_KEY_TYPE_UID0, NULL, NULL)) + return(-1); + + /* and decrypt with it */ + if (aes_cbc_decrypt(buffer, buffer, length, AES_KEY_SIZE_128 | AES_KEY_TYPE_USER, derivedKey, NULL)) + return(-1); + + /* clear the derived key from memory */ + memset(derivedKey, 0, sizeof(derivedKey)); + return(0); +#else + /* with no AES/local keys, we have no personalisation */ + dprintf(DEBUG_INFO, "image3: no AES, cannot de-personalise\n"); + return(-1); +#endif +} + +void +image3SHA1Generate(void *dataBuffer, size_t dataSize, void *hashBuffer) +{ + sha1_calculate(dataBuffer, dataSize, hashBuffer); +} + +int +image3PKIVerifyHash( + void *hashBuffer, + size_t hashSize, + void *signedHashBuffer, + size_t signedHashSize, + void *certBlobBuffer, + size_t certBlobSize, + void **certCustomData, + size_t *certCustomDataSize) +{ + int result = EPERM; + +#if WITH_PKI + if (!verify_signature_with_chain(certBlobBuffer, certBlobSize, + signedHashBuffer, signedHashSize, hashBuffer, hashSize, + certCustomData, certCustomDataSize, NULL, NULL)) + result = 0; +#else + /* with no PKI, a signed image cannot be trusted */ + dprintf(DEBUG_INFO, "image3: cannot verify hash, no PKI support\n"); +#endif + + return(result); +} + +int +image3TicketVerifyHash(void *hashBuffer, size_t hashSize, uint32_t imageType, uint32_t expectedType) +{ + bool untrusted = false; + bool result = false; + +#if WITH_TICKET + result = ticket_validate_image3(imageType, expectedType, hashBuffer, hashSize, &untrusted); +#endif + + if (result && !untrusted) + return(0); + + if (result && untrusted) + return(EPERM); + + return(EINVAL); +} + +/* + * Memory allocator + * + * Use calloc to guarantee zero-filled memory + */ +void * +image3Malloc(size_t size) +{ + return calloc(size, 1); +} + +/* + * Memory de-allocator + */ +void +image3Free(void *ptr, size_t size __unused) +{ + free(ptr); +} + diff --git a/lib/image/image3/image3_wrapper.h b/lib/image/image3/image3_wrapper.h new file mode 100644 index 0000000..b09eaa2 --- /dev/null +++ b/lib/image/image3/image3_wrapper.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + +/* + * image3_process_superblock + * + * Searches the given bdev looking for image3 images. Returns a count of found + * images. + */ +extern int +image3_process_superblock(Image2Superblock *sblock, struct blockdev *bdev, off_t offset, uint32_t imageOptions); + +/* + * image3_free_bdev + * + * Frees resources for any previously found images on the specified bdev. + * Useful for starting afresh with a new image superblock. + */ +extern void +image3_free_bdev(struct blockdev *bdev); + +/* + * image3_load + * + * Given an image_info handle and type from a previous image_find, load the image and + * return the size and address of the payload (DATA tag). + */ +extern int +image3_load(struct image_info *image, const u_int32_t *types, u_int32_t count, u_int32_t *actual, void **load_addr, size_t *load_len); + +/* + * image3_dump_list + * + * Print the list of images from the currently active bdev, if any. + */ +extern void +image3_dump_list(bool detailed); + + +/* + * image3_find + * + * Returns the image_info handle to the first image of the specified type + * from the currently active bdev, if any. + */ +extern struct image_info * +image3_find(u_int32_t image_type); diff --git a/lib/image/image3/rules.mk b/lib/image/image3/rules.mk new file mode 100644 index 0000000..6349730 --- /dev/null +++ b/lib/image/image3/rules.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_IMAGE3=1 + +MODULES += \ + lib/cksum \ + drivers/sha1 \ + lib/image + +ALL_OBJS += \ + $(LOCAL_DIR)/Image3.o \ + $(LOCAL_DIR)/image3_wrapper.o diff --git a/lib/image/image4/image4_partial.c b/lib/image/image4/image4_partial.c new file mode 100644 index 0000000..72f6d9f --- /dev/null +++ b/lib/image/image4/image4_partial.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "image4_partial.h" + +// TODO - libDER/asn1Types.h is missing ASN1_EOC +#ifndef ASN1_EOC +#define ASN1_EOC 0x00 +#endif + +static int der_expect(const DERItem *bounds, DERTag tag, DERDecodedInfo *info, + bool partial); +static int der_restrict(DERItem *bounds, const DERItem *item); +static int der_compare_ia5string(const DERItem *item, const char *s); +static int der_skip_over(DERItem *bounds, const DERItem *item); +static int der_expect_ia5string(DERItem *bounds, const char *s); + +#ifdef TEST +static void hexdump(const void *buf, size_t len); +#endif + +// Parse a partial buffer enough to identify and get type. +int image4_get_partial(const void *buf, size_t buf_bytes, + uint32_t *ret_type, uint32_t *ret_size) +{ + DERItem bounds; + DERDecodedInfo info; + // See sample Image4 header at the top of this file. + bounds.data = (DERByte *) buf; + bounds.length = buf_bytes; + dprintf(DEBUG_SPEW, "image4_get_partial %p,%u\n", + bounds.data, (unsigned) bounds.length); + + // Outer SEQUENCE. Allow partial. + dprintf(DEBUG_SPEW, "Parse outer SEQUENCE\n"); + if (der_expect(&bounds, ASN1_CONSTR_SEQUENCE, &info, true) != 0) + return -1; + // Infer Image4 size from the bounds of the sequence. + if (ret_size != NULL) { + DERSize offset = info.content.data - bounds.data; + if (offset + info.content.length < offset) { + dprintf(DEBUG_SPEW, "Sneaky size wraparound %llu\n", + (uint64_t) offset + info.content.length); + return -1; + } + *ret_size = offset + info.content.length; + } + // Update bounds to contents of SEQUENCE. + if (der_restrict(&bounds, &info.content) != 0) + return -1; + + // IA5String "IMG4". Update bounds to skip over. + dprintf(DEBUG_SPEW, "Parse IA5String \"IMG4\"\n"); + if (der_expect_ia5string(&bounds, "IMG4") != 0) + return -1; + + // Inner SEQUENCE. Allow partial. + dprintf(DEBUG_SPEW, "Parse inner sequence\n"); + if (der_expect(&bounds, ASN1_CONSTR_SEQUENCE, &info, true) != 0) + return -1; + if (der_restrict(&bounds, &info.content) != 0) + return -1; + + // IA5String "IM4P". Update bounds to skip over. + dprintf(DEBUG_SPEW, "Parse IA5String \"IM4P\"\n"); + if (der_expect_ia5string(&bounds, "IM4P") != 0) + return -1; + + // IA5String "type". We're interested in this one. + dprintf(DEBUG_SPEW, "Parse IA5String type\n"); + if (der_expect(&bounds, ASN1_IA5_STRING, &info, false) != 0) + return -1; + if (info.content.length != sizeof(*ret_type)) { + dprintf(DEBUG_SPEW, "Expected %d byte tag, got %d\n", + (int) sizeof(*ret_type), (int) info.content.length); + return -1; + } + if (ret_type != NULL) { + uint32_t local_type; + memcpy(&local_type, info.content.data, sizeof(local_type)); + *ret_type = swap32(local_type); + } + return 0; +} + +static int +der_expect(const DERItem *bounds, DERTag tag, DERDecodedInfo *info, + bool partial) +{ + DERReturn ret; + dprintf(DEBUG_SPEW, "Bounds %p,%u\n", + bounds->data, (unsigned) bounds->length); + ret = DERDecodeItemPartialBuffer(bounds, info, partial); + if (ret != DR_Success) { + dprintf(DEBUG_SPEW, "Error decoding DER: %d\n", (int) ret); + return ret; + } else if (info->tag != tag) { + dprintf(DEBUG_SPEW, + "Didn't get expected tag 0x%llx, got 0x%llx\n", + (uint64_t) tag, (uint64_t) info->tag); + return -1; + } else { + // Got expected tag. + return 0; + } +} + +static int +der_restrict(DERItem *bounds, const DERItem *item) +{ + // Update *bounds to *item, keeping staying within *bounds. + RELEASE_ASSERT(item->data >= bounds->data); + DERByte *buf_start = bounds->data; + DERByte *buf_end = bounds->data + bounds->length; + // This should have been guaranteed elsewhere, but worth checking. + // Zero length returned *bounds allowed. + if ((item->data < buf_start) || (item->data > buf_end)) { + dprintf(DEBUG_SPEW, "DERItem.data=%p outside bounds %p,%p\n", + item->data, buf_start, buf_end); + return -1; + } + // Set *bounds to *item, then restrict range. + bounds->data = item->data; + bounds->length = __min((size_t)item->length, (size_t)(buf_end - bounds->data)); + return 0; +} + +static int +der_compare_ia5string(const DERItem *item, const char *s) +{ + int cmp; + size_t len = strlen(s); + dprintf(DEBUG_SPEW, "content %p,%u\n", item->data, item->length); + if (item->length != len) { + dprintf(DEBUG_SPEW, "IA5String expected %s but length %d\n", + s, (int) len); + return -1; + } + cmp = memcmp(item->data, s, len); + if (cmp != 0) { + dprintf(DEBUG_SPEW, "Expected %s, got:\n", s); + dhexdump(DEBUG_SPEW, item->data, len); + } + return cmp; +} + +static int +der_skip_over(DERItem *bounds, const DERItem *item) +{ + DERSize skip, offset; + // Calculate number of bytes to move bounds->data to end of *item. + RELEASE_ASSERT(item->data >= bounds->data); + offset = item->data - bounds->data; + skip = offset + item->length; + if ((skip < offset) || (skip > bounds->length)) { + dprintf(DEBUG_SPEW, "Skipping over item -> outside bounds\n"); + return -1; + } + bounds->data += skip; + bounds->length -= skip; + return 0; +} + +static int +der_expect_ia5string(DERItem *bounds, const char *s) +{ + // Get IA5String info, compare data, update bounds to skip over. + DERDecodedInfo info; + if (der_expect(bounds, ASN1_IA5_STRING, &info, false) != 0) + return -1; + if (der_compare_ia5string(&info.content, s) != 0) + return -1; + if (der_skip_over(bounds, &info.content) != 0) + return -1; + return 0; +} + + +#ifdef TEST +// Run test with: +// cc -Werror -Wall -O -o image4_partial image4_partial.c ../../pki/libDER/DER_Decode.c -DTEST -DDEBUG_LEVEL=30 -I../../../include -I../../pki && ./image4_partial +// Try both -m32 and -m64 +#include + +int main() { + static const uint8_t big_img4[] = { // 4GB-1 file + 0x30, 0x84, 0xff, 0xff, 0xff, 0xf9, // SEQUENCE { 4GB-7 + 0x16, 0x04, 0x49, 0x4d, 0x47, 0x34, // IA5String 'IMG4' + 0x30, 0x84, 0xff, 0xff, 0xff, 0xed, // SEQUENCE { 4GB-19 + 0x16, 0x04, 0x49, 0x4d, 0x34, 0x50, // IA5String 'IM4P' + 0x16, 0x04, 0x41, 0x42, 0x43, 0x44, // IA5String 'ABCD' + }; + uint32_t type, size; + int ret = image4_get_partial(big_img4, sizeof(big_img4), + &type, &size); + assert(ret == 0); + assert(memcmp(&type, "ABCD", 4) == 0); + assert(size == 0xffffffff); + printf("Pass\n"); + return 0; +} + +static void hexdump(const void *buf, size_t len) { + const uint8_t *p = buf; + size_t i; + for (i = 0; i < len; ++i) + printf("[%llu] = 0x%02x '%c'\n", (uint64_t) i, p[i], p[i]); +} + +void _panic(const char *func, const char *str, ...) { + va_list args; + va_start(args, str); + printf("\n%s: ", func); + vprintf(str, args); + printf("\n\n"); + va_end(args); + exit(1); +} +#endif // defined(TEST) diff --git a/lib/image/image4/image4_partial.h b/lib/image/image4/image4_partial.h new file mode 100644 index 0000000..047c685 --- /dev/null +++ b/lib/image/image4/image4_partial.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef IMAGE4_PARTIAL_H +#define IMAGE4_PARTIAL_H 1 + +#include + +/* + * Maximum number of bytes needed to ID an Image4 file. + * + * Image4 header for a large (but <4GB) file contains: + * + * SEQUENCE { 30 84 xx xx xx xx + * IA5String 'IMG4' 16 04 49 4d 47 34 + * SEQUENCE { 30 84 yy yy yy yy + * IA5String 'IM4P' 16 04 53 45 50 4f + * IA5String 'abcd' 16 04 aa bb cc dd + */ +#define IMAGE4_ID_BYTES 30 + +// Parse a partial buffer enough to identify and get type. +// Return pointers can be NULL if not needed. +int image4_get_partial(const void *buf, size_t buf_bytes, + uint32_t *ret_type, uint32_t *ret_size); + +#endif // defined(IMAGE4_PARTIAL_H) diff --git a/lib/image/image4/image4_wrapper.c b/lib/image/image4/image4_wrapper.c new file mode 100644 index 0000000..53829c5 --- /dev/null +++ b/lib/image/image4/image4_wrapper.c @@ -0,0 +1,1356 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Current implementation: Image4 Spec 1.0 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "image4_partial.h" +#include "image4_wrapper.h" +#include +#include + +#if !WITH_CORECRYPTO +# error "libImg4Decode requires corecrypto integration" +#endif + +#define AES_KEY_SIZE_BYTES_256 (32) + +#define UNTAG(x) (((x) >> 24) & 0xff),(((x) >> 16) & 0xff),(((x) >> 8) & 0xff),((x) & 0xff) + +typedef enum matching_relation { + REL_EQUAL, + REL_GREATER_EQUAL +} matching_relation_t; + +struct enviornment_properties { + /* information passed from enviornment to image4 validation code */ + uint64_t chip_id; + uint64_t unique_chip_id; + uint64_t chip_epoch; + uint64_t security_domain; + uint64_t board_id; + bool production_status; + bool security_mode; + bool local_boot; + bool verify_manifest_hash; + bool verify_nonce_hash; + uint64_t boot_nonce; + uint8_t boot_manifest_hash[HASH_OUTPUT_SIZE]; + bool valid_boot_manifest_hash; +}; + +struct image_properties { + /* information/actions passed by image4 validation code */ + bool demote_production_status; + bool enable_keys; + bool allow_mix_n_match; + bool effective_production_status; + bool valid_effective_production_status; + bool effective_security_mode; + bool valid_effective_security_mode; + uint8_t manifest_hash[HASH_OUTPUT_SIZE]; + bool valid_manifest; + bool manifest_hash_verified; + uint8_t object_digest[HASH_OUTPUT_SIZE]; +}; + +struct image4_info { + struct list_node node; + struct blockdev *bdev; /* device the image is on */ + off_t devOffset; /* where on the bdev it is */ + struct image_info image_info; /* public image_info */ +}; + +struct image4_wrapper_context { + const Img4 *img4; /* parsed image4, from libImage4Decode */ + const struct enviornment_properties *env_properties; /* info provided by enviornment */ + struct image_properties *img_properties; /* info gathered from parsed image */ +}; + +/* + * image4 callback mechanism used by some targets to copy image4 properties into the + * device tree. See image4_spi.h for additional documentation + */ +static struct { + bool capture_enabled; + + image4_start_capture_callback start_cb; + image4_boolean_property_callback bool_cb; + image4_integer_property_callback int_cb; + image4_string_property_callback string_cb; + image4_validity_callback validity_cb; +} image4_callbacks; + +struct image4_keybag { + u_int32_t kbSelector; +#define kImage4KeybagSelectorNoKey (0) +#define kImage4KeybagSelectorChipUnique (1) +#define kImage4KeybagSelectorChipUniqueDev (2) + u_int32_t kbKeySize; + u_int8_t kbIVBytes[AES_BLOCK_SIZE]; + u_int8_t kbKeyBytes[AES_KEY_SIZE_BYTES_256]; +}; + +static struct list_node images = LIST_INITIAL_VALUE(images); + +static int image4_load_copyobject(struct image_info *image_info, void *objectBuffer, size_t objectSize); +static int image4_validate_property_callback_interposer(uint32_t tag, const Img4Property *value, uint32_t propertyType, void *context); +static int image4_validate_property_callback(uint32_t tag, const Img4Property *value, uint32_t propertyType, void *context); +static int image4_load_decrypt_payload(Img4 *img4, void *payloadBuffer, size_t payloadSize); +static const Img4DecodeImplementation *image4_hash_init(void); + +// chain_validation in libImg4Decode expects this to be declared by client +const struct ccdigest_info *sha1_digest_info; +const struct ccdigest_info *sha384_digest_info; + +/* + * image4_process_superblock + * + * Searches the given bdev looking for image4 images. Returns a count of found + * images. + * + * Image4 objects are in DER format. They are simply concatenated in + * the blockdev, so we need to partially decode each object's header, + * and repeatedly skip over them until we hit an EOC (end-of-content) + * tag or fail to parse. + */ +int +image4_process_superblock(void *sblock, struct blockdev *bdev, off_t offset, uint32_t imageOptions) +{ + uint8_t *buf = malloc(IMAGE4_ID_BYTES); + int count; + dprintf(DEBUG_SPEW, "image4_process_superblock\n"); + for (count = 0; count < IMAGE_MAX_COUNT; ++count) { + struct image4_info *info; + uint32_t type, size; + off_t residual; + uint32_t buf_bytes; + + // Truncate read size to the end of bdev. + if ((uint64_t) offset >= bdev->total_len) { + dprintf(DEBUG_SPEW, "End of bdev\n"); + break; + } + residual = bdev->total_len - offset; + + // Don't read partial headers + if (residual < IMAGE4_ID_BYTES) { + dprintf(DEBUG_SPEW, "End of bdev\n"); + break; + } + + buf_bytes = residual; + // Truncate read size to IMAGE4_ID_BYTES. + if (buf_bytes > IMAGE4_ID_BYTES) + buf_bytes = IMAGE4_ID_BYTES; + + if (sblock != NULL) { + // If this is the first loop, grab bytes from the + // block already provided by the caller. + memcpy(buf, sblock, buf_bytes); + sblock = NULL; + } else { + // Otherwise, fetch the next header from bdev. + // Rely on bdev to detect out of range reads. + int err = blockdev_read(bdev, buf, offset, buf_bytes); + if (err != IMAGE4_ID_BYTES) { + dprintf(DEBUG_SPEW, + "Error reading image @0x%llx: %d\n", + offset, err); + break; + } + } + + // Check if it's an Image4 header and get the type. + if (image4_get_partial(buf, buf_bytes, &type, &size) != 0) { + dprintf(DEBUG_SPEW, "Not Image4 @ 0x%llx\n", offset); + break; + } + + // Images claiming to overflow their block device are up to no good + if (size > (uint64_t)residual) { + dprintf(DEBUG_SPEW, "Size overflows block device @ 0x%llx\n", offset); + break; + } + + // Prepare image4_info. + info = malloc(sizeof(*info)); + info->bdev = bdev; + info->devOffset = offset; + info->image_info.imageLength = size; + info->image_info.imageAllocation = size; + info->image_info.imageType = type; + info->image_info.imagePrivateMagic = IMAGE4_IMAGE_INFO_MAGIC; + info->image_info.imageOptions = imageOptions; + info->image_info.imagePrivate = info; + + // Append to the list + list_add_tail(&images, &info->node); + + // Advance to the next image. + offset += size; + } + free(buf); + return count; +} + +/* + * image4_free_bdev + * + * Frees resources for any previously found images on the specified bdev. + * Useful for starting afresh with a new image superblock. + */ +void +image4_free_bdev(struct blockdev *bdev) +{ + struct image4_info *img, *tmp; + + list_for_every_entry_safe(&images, img, tmp, struct image4_info, node) { + if (img->image_info.imagePrivateMagic == IMAGE4_IMAGE_INFO_MAGIC && + img->bdev == bdev) { + list_delete(&img->node); + free(img); + } + } +} + +/* + * image4_find + * + * Returns the image_info handle to the first image of the specified type. + */ +struct image_info * +image4_find(u_int32_t image_type) +{ + struct image4_info *image; + + list_for_every_entry(&images, image, struct image4_info, node) { + if (image->image_info.imageType == image_type) + return(&image->image_info); + } + + return(NULL); +} + +/* + * image4_load + * + * Loads the image, with the payload ultimately placed at *load_addr and its + * size in *load_len. + * + * It is the caller's responsibility to ensure that the load address is specified + * and that the buffer is large enough (image_info.imageAllocation). + */ +int +image4_load(struct image_info *image_info, const u_int32_t *types, u_int32_t count, u_int32_t *actual, void **load_addr, size_t *load_len) +{ + int result = -1; + void *objectBuffer = NULL; + size_t originalObjectSize = 0; + size_t correctedObjectSize = 0; + Img4 img4; + DERReturn ret; + DERItem item; + void *payloadBuffer; + size_t payloadSize; + bool trustedImage = false; /* treat image as untrusted to start with */ + bool matchedType; + u_int32_t actualType; + u_int32_t cnt; + struct image4_wrapper_context image4_wrapper_context; + struct enviornment_properties env_properties; + struct image_properties img_properties; + const Img4DecodeImplementation *implementation; + + /* basic sanity on arguments */ + RELEASE_ASSERT(NULL != image_info); + RELEASE_ASSERT(NULL != load_addr); + RELEASE_ASSERT(NULL != load_len); + + /* refuse to operate on an object that is larger than the load buffer */ + if (image_info->imageAllocation > *load_len) { + dprintf(DEBUG_INFO, "loaded image too large\n"); + platform_record_breadcrumb_int("image4_load_fail", 1); + goto out; + } + + /* refuse to operate on an object buffer at zero */ + if (NULL == *load_addr) { + dprintf(DEBUG_INFO, "cannot load image with buffer at zero\n"); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4NullPtr); + goto out; + } + + /* initialize locals */ + bzero((void *)&img_properties, sizeof(img_properties)); + + /* initialize enviornment object */ + bzero((void *)&env_properties, sizeof(env_properties)); + env_properties.chip_epoch = (uint64_t)platform_get_hardware_epoch(); + env_properties.chip_id = (uint64_t)platform_get_chip_id(); + env_properties.board_id = (uint64_t)platform_get_board_id(); + env_properties.unique_chip_id = platform_get_ecid_id(); + env_properties.security_domain = (uint64_t)platform_get_security_domain(); + env_properties.production_status = platform_get_raw_production_mode(); + env_properties.security_mode = platform_get_secure_mode(); + env_properties.local_boot = ((image_info->imageOptions & IMAGE_OPTION_LOCAL_STORAGE) == IMAGE_OPTION_LOCAL_STORAGE); + env_properties.verify_nonce_hash = ((image_info->imageOptions & IMAGE_OPTION_NEW_TRUST_CHAIN) == IMAGE_OPTION_NEW_TRUST_CHAIN); + env_properties.verify_manifest_hash = !env_properties.verify_nonce_hash && platform_get_mix_n_match_prevention_status(); + env_properties.valid_boot_manifest_hash = (platform_get_boot_manifest_hash(env_properties.boot_manifest_hash) == 0); + if (env_properties.verify_nonce_hash && !env_properties.local_boot) + env_properties.boot_nonce = platform_get_nonce(); + + /* setup for image4 library */ + implementation = image4_hash_init(); + + /* + * Fetch the object into the supplied (presumed safe) buffer. + */ + objectBuffer = *load_addr; + originalObjectSize = image_info->imageAllocation; + if (image4_load_copyobject(image_info, objectBuffer, originalObjectSize)) + goto out; + + /* if we are just being asked to load the image whole, we're done here */ + if ((image_info->imageOptions & IMAGE_OPTION_JUST_LOAD) == IMAGE_OPTION_JUST_LOAD) { + result = 0; + goto out; + } + + /* Correct image object length, libImg4Decode expects exact length passed from caller. + * If there are extra bytes at the end, erase them. + */ + if (image4_get_partial((const void *)objectBuffer, IMAGE4_ID_BYTES, NULL, (uint32_t *)&correctedObjectSize) != 0) { + dprintf(DEBUG_INFO, "Error parsing Image4 header\n"); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4NullPtr); + goto out; + } + if (correctedObjectSize > originalObjectSize) { + dprintf(DEBUG_INFO, "Truncated Image4: %u vs %u\n", (unsigned) correctedObjectSize, (unsigned) originalObjectSize); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4Truncated); + goto out; + } + bzero((void *)(objectBuffer + correctedObjectSize), (originalObjectSize - correctedObjectSize)); + + /* + * Instantiate the Image4 object. + */ + dprintf(DEBUG_SPEW, "instantiating image\n"); + ret = Img4DecodeInit((const DERByte *) objectBuffer, + (DERSize) correctedObjectSize, + &img4); + if (ret != DR_Success) { + dprintf(DEBUG_INFO, "image instantiation failed, ret: %d\n", (int)ret); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4DecodeInitFail); + + goto out; + } + + /* + * Assume that the object's payload type is the actual type. + */ + Img4DecodeGetPayloadType(&img4, &actualType); + + dprintf(DEBUG_SPEW, "actualType = %x\n", actualType); + if (image4_callbacks.start_cb && image4_callbacks.start_cb(actualType)) { + // Start a capture -- clear out any existing captured state / validity + if (!image4_callbacks.validity_cb) + panic("image4_callbacks.validity_cb is NULL"); + image4_callbacks.validity_cb(false); + image4_callbacks.capture_enabled = true; + } else { + image4_callbacks.capture_enabled = false; + } + + /* + * If the caller provided a list of types, + * check if the actual type matches one of + * the types the caller will accept. + */ + if (count != 0) { + matchedType = false; + for (cnt = 0; cnt < count; cnt++) { + dprintf(DEBUG_SPEW, "types[%x] = %x\n", cnt, types[cnt]); + if (types[cnt] == actualType) { + matchedType = true; + break; + } + } + + if (!matchedType) { + dprintf(DEBUG_INFO, "image type not accepted by caller\n"); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4ImageTypeMismatch); + + goto out; + } + } + + /* + * Check if image contains a manifest + */ + ret = Img4DecodeManifestExists(&img4, &img_properties.valid_manifest); + if ((ret != DR_Success) || !img_properties.valid_manifest) { + dprintf(DEBUG_INFO, "failed manifest exists check, ret: %d, contain_manifest: %d\n", (int)ret, img_properties.valid_manifest); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4ManifestInvalid); + + goto check_untrusted; + } + + /* At this point, we expect img_properties to be updated with useful values */ + + /* + * Save context info to be passed back to the callbacks from the library + */ + image4_wrapper_context.img4 = (const Img4 *) &img4; + image4_wrapper_context.env_properties = (const struct enviornment_properties *) &env_properties; + image4_wrapper_context.img_properties = &img_properties; + + /* + * Image 4 object trust evaluation: steps 7 to 16 + */ + ret = Img4DecodePerformTrustEvaluatation(actualType, + &img4, + (Img4DecodeValidatePropertyCallback) image4_validate_property_callback_interposer, + implementation, + (void *) &image4_wrapper_context); + if (ret != DR_Success) { + dprintf(DEBUG_INFO, "trust evalulation failed, ret: %d\n", (int)ret); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4TrustEvalFail); + + goto check_untrusted; + } + + /* + * Save object manifest hash + */ + RELEASE_ASSERT(Img4DecodeCopyManifestDigest((const Img4 *) &img4, img_properties.manifest_hash, HASH_OUTPUT_SIZE, implementation) == DR_Success); + + /* + * Except first boot stage, each boot-stage is required to verify boot manifest hash if mix-n-match prevention is enforced by previous stage. + * If AllowMixNMatch tag found true, it will break the chain of enforcing mix-n-match prevention. + * If previous stage didn't passed a valid boot manifest hash, skip verifying manifest hash, and tag image untrusted. + * First stage: ROM, or iBoot when performing restore from recovery mode or LLB in DFU mode. + */ + if (env_properties.verify_manifest_hash && !img_properties.allow_mix_n_match) { + if (!env_properties.valid_boot_manifest_hash || (0 != memcmp((const void *)env_properties.boot_manifest_hash, (const void *)img_properties.manifest_hash, HASH_OUTPUT_SIZE))) { + dprintf(DEBUG_INFO, "invalid boot manifest hash, or boot manifest hash failed to match\n"); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4BootManifestFail); + + goto check_untrusted; + } + + img_properties.manifest_hash_verified = true; + } + + /* + * Check effective production status still matches current state of the device, + * if effective production status is valid and security mode + */ + if (img_properties.valid_effective_production_status) { + if (img_properties.effective_production_status != security_get_effective_production_status(img_properties.demote_production_status)) { + dprintf(DEBUG_INFO, "effective production status failed to match\n"); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4ProdStatusMismatch); + + goto check_untrusted; + } + } + + /* + * Check effective secure mode still matches current state of the device, + * if effective secure mode is valid + */ + if (img_properties.valid_effective_security_mode) { + if (img_properties.effective_security_mode != platform_get_secure_mode()) { + dprintf(DEBUG_INFO, "effective security mode failed to match\n"); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4SecureModeMismatch); + + goto check_untrusted; + } + } + + /* Mark image as trusted now */ + trustedImage = true; + +check_untrusted: + /* + * The image is not signed or signature is invalid or a constraint is not met. + * + * If the image was created with 'enhanced security', this is fatal. Otherwise + * tell the security system and see if it's OK for us to use the image. + * + * Note that the security call may adjust the state of the system in order + * to ensure that it is safe to run untrusted code before replying OK. + */ + if (!trustedImage) { + /* Rollback image and enviornment properites updated by image validation callback */ + img_properties.enable_keys = false; + img_properties.demote_production_status = false; + img_properties.effective_production_status = false; + img_properties.effective_security_mode = false; + img_properties.allow_mix_n_match = false; + img_properties.valid_effective_production_status = false; + img_properties.valid_effective_security_mode = false; + +#if WITH_UNTRUSTED_EXECUTION_ALLOWED + /* Only ROM allows untrusted execution if boot-config with TEST_MODE is selected and part is fused non-secure ('S' bit cleared) */ + if (((image_info->imageOptions & IMAGE_OPTION_REQUIRE_TRUST) == 0) && !platform_get_secure_mode()) { + dprintf(DEBUG_INFO, "untrusted execution allowed, continuing\n"); + } + else +#endif + { + /* policy says that we aren't allowed to use un-trusted images */ + dprintf(DEBUG_INFO, "untrusted execution not allowed, exiting\n"); + goto out; + } + } + + /* + * Find the payload. + */ + dprintf(DEBUG_SPEW, "looking for payload\n"); + ret = Img4DecodeGetPayload(&img4, &item); + if (ret != DR_Success) { + dprintf(DEBUG_INFO, "Img4DecodeGetPayload failed: %d\n", (int) ret); + platform_record_breadcrumb_int("image4_load_fail", kBCImg4PayloadDecodeFail); + + goto out; + } + payloadBuffer = item.data; + payloadSize = item.length; + + /* + * Verify that the payload will fit within the output buffer. + */ + if (payloadSize > *load_len) { + dprintf(DEBUG_INFO, "payload size exceeds buffer size\n"); + goto out; + } + +#if WITH_AES + /* + * If keys are requested to be disabled (untrusted image or trusted image with EKEY set to false), + * don't decrypt it. + */ + if (img_properties.enable_keys) { + /* + * Decrypt the payload data + */ + if (0 != image4_load_decrypt_payload(&img4, + payloadBuffer, + payloadSize)) { + /* the image is encrypted but we can't decrypt it */ + platform_record_breadcrumb_int("image4_load_fail", kBCImg4PayloadDecryptFail); + + goto out; + } + } +#endif /* WITH_AES */ + + /* + * All done and OK; copy the payload to the base of the buffer and pass the actual + * payload size back to the caller. + */ + dprintf(DEBUG_SPEW, "copying payload %p->%p\n", payloadBuffer, objectBuffer); + memcpy(objectBuffer, payloadBuffer, payloadSize); + *load_len = payloadSize; + result = 0; + + /* + * Clear remains of image4 from the memory. + * NOTE: Currently in ROM, iBoot first and second stage, image4 object as whole is loaded + * at final destination address. Its processed there, then payload from image4 is moved to + * final destination. This assertion is added to catch if this changes in future, and a more + * exhaustive checks will be needed to guarantee image4 related information is cleared from the + * memory besides payload. + */ + RELEASE_ASSERT(objectBuffer < payloadBuffer); + RELEASE_ASSERT(payloadSize < correctedObjectSize); + bzero((uint8_t *)objectBuffer + payloadSize, correctedObjectSize - payloadSize); + + /* + * Disable keys if object never requested to enable them or image validation failed. + * Also, tell security system to flag GID and UID access. + */ + if (!img_properties.enable_keys) + security_set_untrusted(); + + /* + * If the image is trusted, and it has asserted that we should clear the + * production status flag, do that now. + */ + security_set_production_override(img_properties.demote_production_status); + + /* + * Save current object manifest hash, it will be boot manifest hash for next stage. + * If untrusted (we failed to find a manifest or manifest is not valid), let next stage know manifest is not valid. + */ + if (trustedImage) + security_set_boot_manifest_hash(img_properties.manifest_hash); + else + security_set_boot_manifest_hash(NULL); + + /* + * If ANMN is true and image is trusted, stop enforcing MixNMatch prevention. + * Otherwise, keep enforcing MixNMatch prevention: + * - if current enviornment requires nonce hash and image is trusted + * - if manifest hash is verified which will be true if enviornment started with VerifyManifestHash true, AMNM is false, and image is trusted. + */ + if (!img_properties.allow_mix_n_match && + ((trustedImage && env_properties.verify_nonce_hash) || img_properties.manifest_hash_verified)) + security_set_mix_n_match_prevention_status(true); + else + security_set_mix_n_match_prevention_status(false); + + /* + * If didn't load from local storage, the fuses must be locked + * (For local storage, the platform can delay locking in some rare cases) + */ + if (!env_properties.local_boot) + security_set_lock_fuses(); + + /* + * Provide the actual type to the caller. + */ + if (actual != NULL) { + *actual = actualType; + } + +out: + /* + * If we failed, nuke the caller's pointers and clear the work buffer. + */ + if (result != 0) { + dprintf(DEBUG_SPEW, "load failed, clearing object buffer\n"); + *load_addr = 0; + *load_len = 0; + if (objectBuffer != NULL) { + memset(objectBuffer, 0, originalObjectSize); + } + /* + * If capturing properties, alert caller that the image is invalid + */ + if (image4_callbacks.capture_enabled) + image4_callbacks.validity_cb(false); + } + else { + if (image4_callbacks.capture_enabled) + image4_callbacks.validity_cb(true); + } + + return (result); +} + +/* + * image4_dump_list + * + * Print the list of currently-known images. + */ +void +image4_dump_list(bool detailed) +{ + struct image4_info *image; + + list_for_every_entry(&images, image, struct image4_info, node) { + + printf("image %p: bdev %p type %c%c%c%c offset 0x%llx", + image, + image->bdev, + UNTAG(image->image_info.imageType), + image->devOffset); + if (image->image_info.imageLength > 0) { + printf(" len 0x%x", + image->image_info.imageLength); + } + printf("\n"); + } +} + +/* + * image4_check_magic + * + * Verifies img4 header + */ +static int +image4_check_magic(void *buf, size_t len) +{ + const DERByte *der = (const DERByte *) buf; + uint32_t der_size; + if (len < IMAGE4_ID_BYTES) { + dprintf(DEBUG_INFO, "Runt header size: %u\n", (unsigned) len); + return -1; + } + if (image4_get_partial(der, IMAGE4_ID_BYTES, NULL, &der_size) != 0) { + dprintf(DEBUG_INFO, "Error parsing Image4 header\n"); + return -1; + } + if (der_size > len) { + dprintf(DEBUG_INFO, "Truncated Image4: %u vs %u\n", + (unsigned) der_size, (unsigned) len); + return -1; + } + return 0; +} + +/* + * image4_load_copyobject + * + * Fetch an image4 object from its current location into the supplied object buffer. + */ +static int +image4_load_copyobject(struct image_info *image_info, void *objectBuffer, size_t objectSize) +{ + struct image4_info *image; + int result; + + RELEASE_ASSERT(NULL != objectBuffer); + + dprintf(DEBUG_SPEW, "loading image %p with buffer %p/%x\n", image_info, objectBuffer, (unsigned)objectSize); + + switch (image_info->imagePrivateMagic) { + case IMAGE4_IMAGE_INFO_MAGIC: + /* + * Fetch the image data from the bdev into the caller-supplied + * scratch buffer. + */ + dprintf(DEBUG_SPEW, "reading image from bdev\n"); + image = (struct image4_info *)(image_info->imagePrivate); + result = blockdev_read(image->bdev, + objectBuffer, + image->devOffset, + objectSize); + if (result != (int)objectSize) { + dprintf(DEBUG_CRITICAL, "blockdev read failed with %d\n", result); + return(-1); + } + break; + + case IMAGE_MEMORY_INFO_MAGIC: + /* + * Copy the image data from the memory buffer into the + * caller-supplied scratch buffer. + * + * If the caller does not supply a buffer, the image is assumed to be in + * 'trusted' memory already and is left where it is. + */ + if (image4_check_magic(image_info->imagePrivate, objectSize) != 0) { + dprintf(DEBUG_INFO, "image not image4\n"); + return(-1); + } + if (objectBuffer != image_info->imagePrivate) { + dprintf(DEBUG_SPEW, "reading image from %p/%x\n", image_info->imagePrivate, (unsigned) objectSize); + memmove(objectBuffer, image_info->imagePrivate, objectSize); + } + break; + + default: + dprintf(DEBUG_INFO, "unrecognised image source type %x\n", image_info->imagePrivateMagic); + return(-1); + } + + return(0); +} + +/* image4_verify_number_relation + * + * Verifies equal or greater equal relation for Number properties + * returns:: DR_Success (0): success, -1: doesn't match required_value, DR_xxx: Sequence decode error + * + */ +static int +image4_verify_number_relation(matching_relation_t relation, DERTag tag, const Img4Property *tag_value_item, uint64_t required_value) +{ + DERReturn ret = DR_Success; + uint64_t tag_val = 0; + + if ((ret = Img4DecodeGetPropertyInteger64(tag_value_item, tag, &tag_val)) != DR_Success) { + dprintf(DEBUG_INFO, "tag type not integer, ret: %d\n", (int)ret); + goto out; + } + + switch (relation) { + case REL_EQUAL: + if (tag_val != required_value) + ret = -1; + break; + case REL_GREATER_EQUAL: + if (tag_val < required_value) + ret = -1; + break; + } + +out: + return ret; +} + +/* image4_verify_bool_relation + * + * Verifies equal relation for Boolean properties + * returns:: DR_Success (0): success, -1: doesn't match required_value, DR_xxx: Sequence decode error + * + */ +static int +image4_verify_boolean_relation(DERTag tag, const Img4Property *tag_value_item, bool required_value) +{ + DERReturn ret = DR_Success; + bool tag_val = false; + + if ((ret = Img4DecodeGetPropertyBoolean(tag_value_item, tag, &tag_val)) != DR_Success) { + dprintf(DEBUG_INFO, "tag type not boolean, ret: %d\n", (int)ret); + goto out; + } + + if (tag_val != required_value) + ret = -1; + +out: + return ret; +} + +/* image4_verify_matching_bytes + * + * Verifies bytes matches for Data properties + * returns:: DR_Success (0): success, -1: doesn't match required_value, DR_xxx: Sequence decode error + * + */ +static int +image4_verify_matching_bytes(matching_relation_t relation, DERTag tag, const Img4Property *tag_value_item, const void *required_bytes, size_t required_length) +{ + DERReturn ret = -1; + uint8_t *data; + uint32_t length; + + if (Img4DecodeGetPropertyData(tag_value_item, tag, &data, &length) != DR_Success) { + dprintf(DEBUG_INFO, "tag type not data, ret: %d\n", (int)ret); + goto out; + } + + if (length != required_length) { + goto out; + } + + switch(relation) { + case REL_EQUAL: + if (memcmp(data, required_bytes, required_length) != 0) + goto out; + break; + + case REL_GREATER_EQUAL: + if (memcmp(data, required_bytes, required_length) < 0) + goto out; + break; + } + + ret = DR_Success; + +out: + return ret; +} + +/* + * image4_validate_property_callback_interposer + * + * To support property capturing, libImg4Decode calls this adapter, which either + * directly calls the real image4_validate_property_callback, or captures the + * value and then calls image4_validate_property_callback. + */ +static int +image4_validate_property_callback_interposer(uint32_t tag, const Img4Property *value, uint32_t propertyType, void *context) +{ + /* Captures are only enabled on targets that call + * image4_register_property_capture_callbacks, and the registered type is + * equal to the actualType of the image. + */ + if (image4_callbacks.capture_enabled) + { + switch(value->type) { + case ASN1_BOOLEAN: + if (image4_callbacks.bool_cb) { + bool tag_val; + if (Img4DecodeGetPropertyBoolean(value, tag, &tag_val) == DR_Success) { + image4_callbacks.bool_cb(tag, propertyType == kImg4ObjectProperty, tag_val); + } + } + break; + case ASN1_INTEGER: + if (image4_callbacks.int_cb) { + uint64_t tag_val; + if (Img4DecodeGetPropertyInteger64(value, tag, &tag_val) == DR_Success) { + image4_callbacks.int_cb(tag, propertyType == kImg4ObjectProperty, tag_val); + } + } + break; + case ASN1_OCTET_STRING: + if (image4_callbacks.string_cb) { + uint8_t *data; + uint32_t length; + if (Img4DecodeGetPropertyData(value, tag, &data, &length) == DR_Success) { + image4_callbacks.string_cb(tag, propertyType == kImg4ObjectProperty, data, length); + } + } + break; + default: + panic("Unknown ASN1 type %d\n", value->type); + } + } + + + return image4_validate_property_callback(tag, value, propertyType, context); +} +/* + * image4_validate_property_callback + * + * libImg4Decode will call this function to validate various + * properties in the enviornment + */ +static int +image4_validate_property_callback(uint32_t tag, const Img4Property *value, uint32_t propertyType, void *context) +{ + // ValidatePropertyCallback return type should be DERReturn + // Once this is fixed return more precise errors and for malformed images don't bother executing. + int ret = 0; + const struct image4_wrapper_context *image4_wrapper_context = (const struct image4_wrapper_context *)context; + const struct enviornment_properties *env_properties = image4_wrapper_context->env_properties; + struct image_properties *img_properties = image4_wrapper_context->img_properties; + const Img4 *img4 = image4_wrapper_context->img4; + /* setup for image4 library */ + const Img4DecodeImplementation *implementation = image4_hash_init(); + + switch (propertyType) { + case kImg4ManifestProperty: + switch (tag) { + /* Properties require Equal relation */ + case kImg4Tag_ECID: /* Unique Chip ID (Number) */ + ret = image4_verify_number_relation(REL_EQUAL, + tag, + value, + env_properties->unique_chip_id); + break; + case kImg4Tag_CHIP: /* Chip ID (Number) */ + ret = image4_verify_number_relation(REL_EQUAL, + tag, + value, + env_properties->chip_id); + break; + case kImg4Tag_BORD: /* Board ID (Number) */ + ret = image4_verify_number_relation(REL_EQUAL, + tag, + value, + env_properties->board_id); + break; + case kImg4Tag_SDOM: /* Security Domain (Number) */ + ret = image4_verify_number_relation(REL_EQUAL, + tag, + value, + env_properties->security_domain); + break; + + /* Properties require Greater Equal relation */ + case kImg4Tag_CEPO: /* Certificate Epoch (Number) */ + ret = image4_verify_number_relation(REL_GREATER_EQUAL, + tag, + value, + env_properties->chip_epoch); + break; + + /* Properties require an action */ + case kImg4Tag_AMNM: /* Allow Mix-n-Match (Boolean) */ + ret = image4_verify_boolean_relation(tag, value, true); + if (ret == 0) + img_properties->allow_mix_n_match = true; + else if (ret == -1) + ret = 0; + break; + + /* Properties (Boolean) require must match relation */ + case kImg4Tag_CPRO: /* Certificate Production Status (Boolean) */ + ret = image4_verify_boolean_relation(tag, value, env_properties->production_status); + break; + case kImg4Tag_CSEC: /* Certificate Security Mode (Boolean) */ + ret = image4_verify_boolean_relation(tag, value, env_properties->security_mode); + break; + + /* Properties (Data) require must match relation */ + case kImg4Tag_BNCH: /* Boot Nonce Hash (Data) */ + { + /* + * Default say ok for boot-nonce hash, since its in manifest so it will be called for every object. + * Only verify, when a stage requires verification (in ROM, and in iBoot when doing restore from recovery mode.) + */ + if(env_properties->verify_nonce_hash) { + uint64_t nonce; + uint8_t nonce_hash[HASH_OUTPUT_SIZE]; + + if (env_properties->local_boot) { + DERItem tag_data; + + /* Expects a Boot-nonce in RestoreInfo section */ + if ((ret = Img4DecodeGetRestoreInfoData(img4, + kImg4Tag_BNCN, + &tag_data.data, + &tag_data.length)) == DR_Success) { + if (tag_data.length != sizeof(nonce)) { + dprintf(DEBUG_INFO, "BNCN tag_data length mismatch\n"); + goto out; + } + memcpy((void *)&nonce, (const void *)tag_data.data, (size_t)tag_data.length); + } + else { + dprintf(DEBUG_INFO, "failed to find RestoreInfo, ret: %d\n", (int)ret); + goto out; + } + } + else { + nonce = env_properties->boot_nonce; + } + + hash_calculate((const void *)&nonce, sizeof(nonce), (void *)nonce_hash, sizeof(nonce_hash)); + + // The boot nonce hash (BNCH) is truncated to NONCE_HASH_OUTPUT_SIZE bytes. + ret = image4_verify_matching_bytes(REL_EQUAL, tag, value, (const void *)&nonce_hash, NONCE_HASH_OUTPUT_SIZE); + } + break; + } + + /* Ignore rest */ + default: + dprintf(DEBUG_INFO, "Ignoring unknown tag 0x%08x\n", tag); + break; + } + break; + + case kImg4ObjectProperty: + switch (tag) { + /* Properties require an action */ + case kImg4Tag_DPRO: /* Demote Production Status (Boolean) */ + { + ret = image4_verify_boolean_relation(tag, value, true); + if(ret == 0) + img_properties->demote_production_status = true; + else if (ret == -1) + ret = 0; + break; + } + case kImg4Tag_EKEY: /* Enable Keys (Boolean) */ + ret = image4_verify_boolean_relation(tag, value, true); + if (ret == 0) + img_properties->enable_keys = true; + else if (ret == -1) + ret = 0; + break; + case kImg4Tag_EPRO: /* Effective Production Status (Boolean) */ + img_properties->valid_effective_production_status = true; + ret = image4_verify_boolean_relation(tag, value, true); + /* true: production, false: development */ + if (ret == 0) + img_properties->effective_production_status = true; + else if (ret == -1) + ret = 0; + break; + case kImg4Tag_ESEC: /* Effective Security Mode (Boolean) */ + img_properties->valid_effective_security_mode = true; + ret = image4_verify_boolean_relation(tag, value, true); + /* true: secure, false: non-secure */ + if (ret == 0) + img_properties->effective_security_mode = true; + else if (ret == -1) + ret = 0; + break; + + /* Properties require must match relation */ + case kImg4Tag_DGST: /* Object Digest (Data) */ + { + if ((ret = Img4DecodeCopyPayloadDigest(img4, img_properties->object_digest, HASH_OUTPUT_SIZE, implementation)) != DR_Success) { + dprintf(DEBUG_INFO, "failed to find PayloadHash, ret: %d\n", (int)ret); + goto out; + } + ret = image4_verify_matching_bytes(REL_EQUAL, tag, value, (const void *)img_properties->object_digest, HASH_OUTPUT_SIZE); + break; + } + + /* Ignore rest */ + default: + dprintf(DEBUG_INFO, "Ignoring unknown tag 0x%08x\n", tag); + break; + } + break; + } + +out: + if (ret != 0) + dprintf(DEBUG_INFO, "failed to validate tag 0x%08x, ret:%d\n", tag, ret); + + return ret; +} + +void image4_register_property_capture_callbacks(image4_start_capture_callback start_cb, image4_boolean_property_callback bool_cb, + image4_integer_property_callback int_cb, image4_string_property_callback string_cb, + image4_validity_callback validity) +{ + if (start_cb && !validity) + { + // For security reasons, if the caller is interested in any callbacks for an image type, a validity callback must be provided. + panic("image4_register_property_capture_callbacks: When capturing properties, you must provide a validity callback\n"); + } + else + { + + image4_callbacks.start_cb = start_cb; + image4_callbacks.bool_cb = bool_cb; + image4_callbacks.int_cb = int_cb; + image4_callbacks.string_cb = string_cb; + image4_callbacks.validity_cb = validity; + } + + image4_callbacks.capture_enabled = false; + if (image4_callbacks.validity_cb) + image4_callbacks.validity_cb(false); + + dprintf(DEBUG_SPEW, "image4 callbacks registered.\n"); + +} + +static const Img4DecodeImplementation *image4_hash_init(void) +{ +#if WITH_SHA2_384 + sha384_digest_info = ccsha384_di(); + return &kImg4DecodeSecureBootRsa4kSha384; +#else // SHA1 + sha1_digest_info = sha1_get_ccsha1_ccdigest_info(); + return &kImg4DecodeSecureBootRsa1kSha1; +#endif +} + +#if WITH_AES +/* + * image4_load_decrypt_payload + * + * Decrypt the payload contents if they are encrypted and we can find a key + * that matches. + */ +/* Reference Keybag Schema from image4 DER object : + + 65 116: OCTET STRING, encapsulates { + <30 72> + 67 114: SEQUENCE { + <30 37> + 69 55: SEQUENCE { + <02 01> + 71 1: INTEGER 1 + <04 10> + 74 16: OCTET STRING + : 48 BA A6 12 92 44 61 67 03 72 2D 59 FA 8D 59 3B + <04 20> + 92 32: OCTET STRING + : 30 44 52 34 7F 48 8E BF 7A 63 95 BA 54 6A EE 43 + : 87 4A 2B 99 8C 1F 24 7F 64 51 4C E3 0C 6C 4C 52 + : } + <30 37> + 126 55: SEQUENCE { + <02 01> + 128 1: INTEGER 2 + <04 10> + 131 16: OCTET STRING + : 90 F0 C5 19 3D 08 EA 7D 9B 5E F5 8B 31 EE 7F 9D + <04 20> + 149 32: OCTET STRING + : 06 5F 6B 72 92 56 ED FF A2 B5 07 9C 9B E3 A6 40 + : D1 B8 FD 87 90 80 BA 89 5C E6 84 84 03 9E DF 24 + : } + : } + : } + : } + */ +struct ivkey { + u_int8_t IV[AES_BLOCK_SIZE]; + u_int8_t Key[AES_KEY_SIZE_BYTES_256]; +} __packed; + +static int +image4_load_decrypt_payload(Img4 *img4, void *payloadBuffer, size_t payloadSize) +{ + int result; + DERReturn ret; + DERItem keybagDER; + DERDecodedInfo keybagSequenceInfo; + DERSequence keybagSequence; + u_int32_t platformKeyOpts; + u_int32_t keybagKeyOpts; + size_t keybagKeySize; + struct ivkey keybagIVKey; + struct image4_keybag keyBag; + DERDecodedInfo keyDER; + DERSequence keySequence; + DERDecodedInfo info; + + /* basic sanity on arguments */ + RELEASE_ASSERT(NULL != img4); + + /* initialize locals */ + result = -1; + memset(&keybagIVKey, 0, sizeof(keybagIVKey)); + + /* + * Look for payload encryption keybags, see if there is one for us. + * + * If there is, unpack the key and use it and the decryption to move + * the payload to the head of the buffer. If there are keybags but not one + * for us, that's an error. + * + * If there are no keybags or the image was untrusted, just copy the image directly. + */ + dprintf(DEBUG_INFO, "checking for encrypted payload\n"); + + ret = Img4DecodeGetPayloadKeybag(img4, &keybagDER); + if ((keybagDER.data == NULL) || (keybagDER.length == 0) || (ret == DR_ParamErr)) { + /* there are no keybags, payload is not encrypted */ + result = 0; + dprintf(DEBUG_INFO, "Unencrypted payload\n"); + goto out; + } + else if (ret != DR_Success) { + dprintf(DEBUG_INFO, "failed to find a valid keybag for this system, ret: %d\n", (int) ret); + goto out; + } + + if ((DERDecodeItem(&keybagDER, &keybagSequenceInfo) != DR_Success) || + (DERDecodeSeqContentInit(&keybagSequenceInfo.content, &keybagSequence) != DR_Success)) { + dprintf(DEBUG_INFO, "PayloadKeybag SEQUENCE header malformed\n"); + goto out; + } + + for (;;) { + if ((DERDecodeSeqNext(&keybagSequence, &keyDER) != DR_Success) || + (DERDecodeSeqContentInit(&keyDER.content, &keySequence) != DR_Success)) { + dprintf(DEBUG_INFO, "PayloadKeybag key SEQUENCE header malformed\n"); + goto out; + } + + if ((DERDecodeSeqNext(&keySequence, &info) != DR_Success) || + (DERParseInteger(&info.content, &keyBag.kbSelector) != DR_Success)) { + dprintf(DEBUG_INFO, "PayloadKeybag key bad KeySelector\n"); + goto out; + } + + if (DERDecodeSeqNext(&keySequence, &info) != DR_Success) { + dprintf(DEBUG_INFO, "PayloadKeybag key bad IV\n"); + goto out; + } + if (info.content.length != AES_BLOCK_SIZE) { + dprintf(DEBUG_INFO, "IV wrong size: %u but expected %u\n", + (unsigned) info.content.length, (unsigned) AES_BLOCK_SIZE); + goto out; + } + memcpy(&keyBag.kbIVBytes, info.content.data, sizeof(keyBag.kbIVBytes)); + + if (DERDecodeSeqNext(&keySequence, &info) != DR_Success) { + dprintf(DEBUG_INFO, "PayloadKeybag key bad key\n"); + goto out; + } + keyBag.kbKeySize = info.content.length * 8; + if ((keyBag.kbKeySize != 128) && (keyBag.kbKeySize != 192) && (keyBag.kbKeySize != 256)) { + dprintf(DEBUG_INFO, "Unsupported key size: %d\n", keyBag.kbKeySize); + goto out; + } + memcpy((void *)&keyBag.kbKeyBytes, (const void *)info.content.data, sizeof(keyBag.kbKeyBytes)); + + /* work out how big the key is going to be */ + keybagKeyOpts = AES_KEY_TYPE_USER; + switch (keyBag.kbKeySize) { + case 128 : keybagKeyOpts |= AES_KEY_SIZE_128; break; + case 192 : keybagKeyOpts |= AES_KEY_SIZE_192; break; + case 256 : keybagKeyOpts |= AES_KEY_SIZE_256; break; + default: + /* not a valid AES key size, bail */ + dprintf(DEBUG_INFO, "AES key size %d not supported/valid\n", keyBag.kbKeySize); + goto out; + } + keybagKeySize = keyBag.kbKeySize / 8; + if (!(keybagKeySize <= sizeof(keybagIVKey.Key))) + goto out; + + /* copy the IV from the keybag */ + memcpy(&keybagIVKey.IV, keyBag.kbIVBytes, sizeof(keybagIVKey.IV)); + + /* copy the key from the keybag */ + memcpy(&keybagIVKey.Key, keyBag.kbKeyBytes, keybagKeySize); + + switch (keyBag.kbSelector) { + case kImage4KeybagSelectorChipUnique: + case kImage4KeybagSelectorChipUniqueDev: + /* ask platform for key details */ + platformKeyOpts = 0; + if (platform_translate_key_selector(keyBag.kbSelector, &platformKeyOpts) != 0) { + /* we don't recognise this key, spin and try again */ + dprintf(DEBUG_INFO, "key selector %d not recognised\n", keyBag.kbSelector); + continue; + } + dprintf(DEBUG_INFO, "using key selector %d\n", keyBag.kbSelector); + if (aes_cbc_decrypt(&keybagIVKey, + &keybagIVKey, + sizeof(keybagIVKey.IV) + keybagKeySize, + platformKeyOpts, + 0, + 0)) { + dprintf(DEBUG_INFO, "cannot decrypt image - hardware AES keys disabled\n"); + goto out; + } + break; + default: + /* + * Unknown keybag-selector, bail + */ + dprintf(DEBUG_INFO, "unknown keybag-selector\n"); + goto out; + } + + /* + * Decrypt the payload. + * + * Pad payload size to multiple of 16 bytes (AES_BLOCK_SIZE), if its not padded already. + */ + RELEASE_ASSERT((payloadSize % AES_BLOCK_SIZE) == 0); + dprintf(DEBUG_INFO, "AES operation 0x%zx bytes\n", payloadSize); + result = aes_cbc_decrypt(payloadBuffer, + payloadBuffer, + payloadSize, + keybagKeyOpts, + &keybagIVKey.Key, + &keybagIVKey.IV); + + /* clear the iv & key from memory */ + memset(&keybagIVKey, 0, sizeof(keybagIVKey)); + + if (result) + dprintf(DEBUG_INFO, "cannot decrypt image - unexpected AES failure"); + goto out; + } + +out: + return (result); +} +#endif diff --git a/lib/image/image4/image4_wrapper.h b/lib/image/image4/image4_wrapper.h new file mode 100644 index 0000000..53e46b7 --- /dev/null +++ b/lib/image/image4/image4_wrapper.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef IMAGE4_WRAPPER_H + +/* + * image4_process_superblock + * + * Searches the given bdev looking for image4 images. Returns a count of found + * images. + */ +extern int +image4_process_superblock(void *sblock, struct blockdev *bdev, off_t offset, uint32_t imageOptions); + +/* + * image4_free_bdev + * + * Frees resources for any previously found images on the specified bdev. + * Useful for starting afresh with a new image superblock. + */ +extern void +image4_free_bdev(struct blockdev *bdev); + +/* + * image4_load + * + * Given an image_info handle and type from a previous image_find, load the image and + * return the size and address of the payload (DATA tag). + */ +extern int +image4_load(struct image_info *image, const u_int32_t *types, u_int32_t count, u_int32_t *actual, void **load_addr, size_t *load_len); + +/* + * image4_dump_list + * + * Print the list of images from the currently active bdev, if any. + */ +extern void +image4_dump_list(bool detailed); + + +/* + * image4_find + * + * Returns the image_info handle to the first image of the specified type + * from the currently active bdev, if any. + */ +extern struct image_info * +image4_find(u_int32_t image_type); + +#endif // defined(IMAGE4_WRAPPER_H) diff --git a/lib/image/image4/rules.mk b/lib/image/image4/rules.mk new file mode 100644 index 0000000..db64d19 --- /dev/null +++ b/lib/image/image4/rules.mk @@ -0,0 +1,40 @@ +# Copyright (C) 2012, 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +IMAGE_FORMAT := 4 + +# Hack to link against SDKROOT or PLATFORMROOT until somebody figures +# out why libImg4Decode is bouncing between locations. +IMG4_IN_SDKROOT := $(realpath $(SDKROOT)/usr/local/lib/libImg4Decode_os.a) +IMG4_IN_PLATFORMROOT := $(realpath $(PLATFORMROOT)/usr/local/lib/libImg4Decode_os.a) +ifneq ($(IMG4_IN_SDKROOT),) +EXTERNAL_STATICLIBS += $(IMG4_IN_SDKROOT) +EXTERNAL_INCLUDES += $(SDKROOT)/usr/local/include/ +else + ifneq ($(IMG4_IN_PLATFORMROOT),) +EXTERNAL_STATICLIBS += $(IMG4_IN_PLATFORMROOT) +EXTERNAL_INCLUDES += $(PLATFORMROOT)/usr/local/include/ + else +$(error libImg4Decode.a not found in SDKROOT or PLATFORMROOT) + endif +endif + +OPTIONS += WITH_IMAGE4=1 + +MODULES += \ + drivers/sha1 \ + lib/cksum \ + lib/image \ + lib/pki + +ALL_OBJS += \ + $(LOCAL_DIR)/image4_partial.o \ + $(LOCAL_DIR)/image4_wrapper.o diff --git a/lib/image/rules.mk b/lib/image/rules.mk new file mode 100644 index 0000000..5baf575 --- /dev/null +++ b/lib/image/rules.mk @@ -0,0 +1,14 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/image.o \ + $(LOCAL_DIR)/debug.o diff --git a/lib/libbuiltin/arm/builtin_divide.c b/lib/libbuiltin/arm/builtin_divide.c new file mode 100644 index 0000000..7a72481 --- /dev/null +++ b/lib/libbuiltin/arm/builtin_divide.c @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* The ARM backend of the gcc compiler generates calls to out-of-line + * divide and modulo functions for non-trivial cases. This is due to + * ARM lacking a hardware integer divide instruction in most + * implementations. These magic function names may be different in + * other compilers. + */ + +#if defined(TEST) || (defined(__GNUC__) && defined(__arm__)) + +#include + +#ifdef TEST +static void panic(const char *reason); // Logs an error rather than exit. +#else +#include +#endif + +typedef uint64_t (*func_u64)(uint64_t num, uint64_t den); + +uint64_t __udivdi3(uint64_t num, uint64_t den) +{ + /* Algorithm: + * + * Remove factors of 2, then use binary long multiplication to find + * the greatest integer that can be multiplied by the denonimator + * and have a result less than or equal to the numerator. The answer + * bits are shifted in from the right. This is optimized to reduce + * the number of whole-64-bit operations, with the aim of reducing + * code size, not improving performance. + */ + uint64_t answer = 0; + uint64_t product = 0; + if (den == 0) { + panic("Divide by zero"); + return 0; + } + // Remove factors of 2. + while ((den & 1) == 0) { + den >>= 1; + num >>= 1; + } + // Shift left 'den' all the way to the MSB. + while ((den & (1ULL << 63)) == 0) den <<= 1; + for (;;) { + // Long multiplication step. Try adding 'den' at its current shift. + uint64_t new_product = product + den; + answer <<= 1; + if (new_product > product && new_product <= num) { + // No overflow and product is less than 'num'. This bit must be set. + product = new_product; // Keep track of the running product. + answer |= 1; + } + if (den & 1) break; // Not calculating fractions, so that was the last step. + den >>= 1; + } + return answer; +} + +uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem) +{ + uint64_t answer = __udivdi3(num, den); + *rem = num - answer * den; + return answer; +} + +uint64_t __umoddi3(uint64_t num, uint64_t den) +{ + uint64_t rem; + (void) __udivmoddi4(num, den, &rem); + return rem; +} + +static int64_t apply_signed(int64_t num, int64_t den, func_u64 func, int mod) +{ + int negate = 0; + uint64_t answer; + if (num < 0) { + num = -num; + negate ^= 1; + } + if (den < 0) { + den = -den; + if (!mod) negate ^= 1; // Modulo denominator sign does not affect result. + } + answer = func((uint64_t) num, (uint64_t) den); + if (negate) answer = -answer; + return answer; +} + +int64_t __divdi3(int64_t num, int64_t den) +{ + if (num == INT64_MIN && den == -1) return INT64_MIN; // overflow + else return apply_signed(num, den, __udivdi3, 0); +} + +int64_t __moddi3(int64_t num, int64_t den) +{ + return apply_signed(num, den, __umoddi3, 1); +} + +int64_t __divmoddi4(int64_t num, int64_t den, int64_t *rem) +{ + *rem = __moddi3(num, den); + return __divdi3(num, den); +} + +uint32_t __udivsi3(uint32_t num, uint32_t den) +{ + return (uint32_t) __udivdi3((uint64_t) num, (uint64_t) den); +} + +uint32_t __umodsi3(uint32_t num, uint32_t den) +{ + return (uint32_t) __umoddi3((uint64_t) num, (uint64_t) den); +} + +uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem) +{ + *rem = __umodsi3(num, den); + return __udivsi3(num, den); +} + +int32_t __divsi3(int32_t num, int32_t den) +{ + if (num == INT32_MIN && den == -1) return INT32_MIN; // overflow + else return (int32_t) apply_signed((int64_t) num, (int64_t) den, __udivdi3, 0); +} + +int32_t __modsi3(int32_t num, int32_t den) +{ + return (int32_t) apply_signed((int64_t) num, (int64_t) den, __umoddi3, 1); +} + +int32_t __divmodsi4(int32_t num, int32_t den, int32_t *rem) +{ + *rem = __modsi3(num, den); + return __divsi3(num, den); +} + +#endif // defined(TEST) || (defined(__GNUC__) && defined(__arm__)) + +//////////////////////////////////////////////////////////////////////// + +#ifdef TEST +/* + * Tests: +gcc -arch i386 -g -Wall -o builtin_divide builtin_divide.c -DTEST && ./builtin_divide +gcc -arch x86_64 -g -Wall -o builtin_divide builtin_divide.c -DTEST && ./builtin_divide +*/ + +#include +#include +#include +#include + +static unsigned tested = 0; +static unsigned divide_error_count = 0; + +// func_u64 defined in common section above. +typedef int64_t (*func_s64)(int64_t num, int64_t den); +typedef uint64_t (*func_udm64)(uint64_t num, uint64_t den, uint64_t *rem); +typedef int64_t (*func_sdm64)(int64_t num, int64_t den, int64_t *rem); + +typedef uint32_t (*func_u32)(uint32_t num, uint32_t den); +typedef int32_t (*func_s32)(int32_t num, int32_t den); +typedef uint32_t (*func_udm32)(uint32_t num, uint32_t den, uint32_t *rem); +typedef int32_t (*func_sdm32)(int32_t num, int32_t den, int32_t *rem); + +static void check_result(uint64_t num, uint64_t den, const char *op, + char signed_calc, unsigned bits, + uint64_t my_result, uint64_t compiler_result) +{ + ++tested; + if (my_result == compiler_result) return; + printf("Bad result for %c%u %lld (%llu) %s %lld (%llu)\n", + signed_calc, bits, (int64_t) num, num, op, (int64_t) den, den); + printf("Custom divide result: %lld (%llu)\n", + (int64_t) my_result, my_result); + printf("Compiler result: %lld (%llu)\n", + (int64_t) compiler_result, compiler_result); + exit(1); +} + +static const char *op_to_string(char op) +{ + switch (op) { + case '/': return "divide"; + case '%': return "modulo"; + default: + printf("Bad op '%c'\n", op); + exit(1); + } +} + +static void do_test_64(uint64_t num, uint64_t den, + char op, + func_u64 func_u, func_s64 func_s) +{ + // Test an individual 64 bit function. + uint64_t my_result, compiler_result; + if (den == 0) return; + if (func_s && op == '/' && num == INT64_MIN && den == -1) return; // overflow + if (func_u) { + my_result = func_u(num, den); + if (op == '/') compiler_result = num / den; + else compiler_result = num % den; + } else { + my_result = (uint64_t) func_s((int64_t) num, (int64_t) den); + // Test for overflow. The host may trigger an exception. + if (op == '/') { + if (num == INT64_MIN && den == -1) compiler_result = (uint64_t) INT64_MIN; + else compiler_result = (uint64_t) (((int64_t) num) / ((int64_t) den)); + } else { + if (num == INT64_MIN && den == -1) compiler_result = 0; + else compiler_result = ((int64_t) num) % ((int64_t) den); + } + } + check_result(num, den, op_to_string(op), func_u ? 'u' : 's', 64, + my_result, compiler_result); +} + +static void do_test_32(uint32_t num, uint32_t den, + char op, func_u32 func_u, func_s32 func_s) +{ + // Test an individual 32 bit function. + uint32_t my_result, compiler_result; + if (den == 0) return; + if (func_s && op == '/' && num == INT32_MIN && den == -1) return; // overflow + if (func_u) { + my_result = func_u(num, den); + if (op == '/') compiler_result = num / den; + else compiler_result = num % den; + } else { + my_result = (uint32_t) func_s((int32_t) num, (int32_t) den); + // Test for overflow. The host may trigger an exception. + if (op == '/') { + if (num == INT32_MIN && den == -1) compiler_result = (uint32_t) INT32_MIN; + else compiler_result = (uint32_t) (((int32_t) num) / ((int32_t) den)); + } else { + if (num == INT32_MIN && den == -1) compiler_result = 0; + else compiler_result = ((int32_t) num) % ((int32_t) den); + } + } + check_result(num, den, op_to_string(op), func_u ? 'u' : 's', 32, + my_result, compiler_result); +} + +static void do_test_divmod_64(uint64_t num, uint64_t den, + func_udm64 func_u, func_sdm64 func_s) +{ + // Test an individual 64 bit divmod function matches separate results. + uint64_t my_result, my_remainder, compiler_result, compiler_remainder; + if (den == 0) return; + if (func_s && num == INT64_MIN && den == -1) return; // overflow + if (func_u) { + my_result = func_u(num, den, &my_remainder); + compiler_result = num / den; + compiler_remainder = num % den; + } else { + int64_t my_remainder_s; + my_result = (uint64_t) func_s((int64_t) num, (int64_t) den, + &my_remainder_s); + my_remainder = (int64_t) my_remainder_s; + // Test for overflow. The host may trigger an exception. + if (num == INT64_MIN && den == -1) { + compiler_result = (uint64_t) INT64_MIN; + compiler_remainder = 0; + } else { + compiler_result = (uint64_t) (((int64_t) num) / ((int64_t) den)); + compiler_remainder = (uint64_t) (((int64_t) num) % ((int64_t) den)); + } + } + check_result(num, den, "divmod-result", func_u ? 'u' : 's', 64, + my_result, compiler_result); + check_result(num, den, "divmod-remainder", func_u ? 'u' : 's', 64, + my_remainder, compiler_remainder); +} + +static void do_test_divmod_32(uint32_t num, uint32_t den, + func_udm32 func_u, func_sdm32 func_s) +{ + // Test an individual 32 bit divmod function matches separate results. + uint32_t my_result, my_remainder, compiler_result, compiler_remainder; + if (den == 0) return; + if (func_s && num == INT32_MIN && den == -1) return; // overflow + if (func_u) { + my_result = func_u(num, den, &my_remainder); + compiler_result = num / den; + compiler_remainder = num % den; + } else { + int32_t my_remainder_s; + my_result = (uint32_t) func_s((int32_t) num, (int32_t) den, + &my_remainder_s); + my_remainder = (int32_t) my_remainder_s; + // Test for overflow. The host may trigger an exception. + if (num == INT32_MIN && den == -1) { + compiler_result = (uint32_t) INT64_MIN; + compiler_remainder = 0; + } else { + compiler_result = (uint32_t) (((int32_t) num) / ((int32_t) den)); + compiler_remainder = (uint32_t) (((int32_t) num) % ((int32_t) den)); + } + } + check_result(num, den, "divmod-result", func_u ? 'u' : 's', 32, + my_result, compiler_result); + check_result(num, den, "divmod-remainder", func_u ? 'u' : 's', 32, + my_remainder, compiler_remainder); +} + +static void do_test_all_ops_64(uint64_t num_u64, uint64_t den_u64, + func_u64 func_u_div, func_s64 func_s_div, + func_u64 func_u_mod, func_s64 func_s_mod, + func_udm64 func_u_divmod, + func_sdm64 func_s_divmod) +{ + // Test all combinations of unsigned/signed divide/modulo. + do_test_64(num_u64, den_u64, '/', func_u_div, NULL); + do_test_64(num_u64, den_u64, '%', func_u_mod, NULL); + do_test_64(num_u64, den_u64, '/', NULL, func_s_div); + do_test_64(num_u64, den_u64, '%', NULL, func_s_mod); + do_test_divmod_64(num_u64, den_u64, func_u_divmod, NULL); + do_test_divmod_64(num_u64, den_u64, NULL, func_s_divmod); +} + +static void do_test_all_ops_32(uint32_t num_u32, uint32_t den_u32, + func_u32 func_u_div, func_s32 func_s_div, + func_u32 func_u_mod, func_s32 func_s_mod, + func_udm32 func_u_divmod, + func_sdm32 func_s_divmod) +{ + // Test all combinations of unsigned/signed divide/modulo. + do_test_32(num_u32, den_u32, '/', func_u_div, NULL); + do_test_32(num_u32, den_u32, '%', func_u_mod, NULL); + do_test_32(num_u32, den_u32, '/', NULL, func_s_div); + do_test_32(num_u32, den_u32, '%', NULL, func_s_mod); + do_test_divmod_32(num_u32, den_u32, func_u_divmod, NULL); + do_test_divmod_32(num_u32, den_u32, NULL, func_s_divmod); +} + +static void do_test_all_types(uint64_t num_u64, uint64_t den_u64) +{ + // Test 32 and 64 bit types. + uint32_t num_u32 = (uint32_t) num_u64; + uint32_t den_u32 = (uint32_t) den_u64; + do_test_all_ops_64(num_u64, den_u64, + __udivdi3, __divdi3, __umoddi3, __moddi3, + __udivmoddi4, __divmoddi4); + do_test_all_ops_32(num_u32, den_u32, + __udivsi3, __divsi3, __umodsi3, __modsi3, + __udivmodsi4, __divmodsi4); +} + +static void do_test_all_signs(uint64_t num, uint64_t den) +{ + // Test all combinations of sign. + do_test_all_types(num, den); + do_test_all_types(-num, den); + do_test_all_types(num, -den); + do_test_all_types(-num, -den); +} + +static void do_test_ways(uint64_t num, uint64_t den) +{ + // Test both ways around. + do_test_all_signs(num, den); + do_test_all_signs(den, num); +} + +static void do_test_variants(uint64_t num, uint64_t den) +{ + // Test +/-5 from each num, den. + int i, j; + for (i = -5; i <= 5; ++i) { + uint64_t new_num = num + i; + for (j = -5; j <= 5; ++j) { + uint64_t new_den = den + j; + do_test_ways(new_num, new_den); + } + } +} + +static void panic(const char *reason __attribute__((unused))) +{ + ++divide_error_count; +} + +int main() +{ + static const uint64_t tests[][2] = { + { 0, 1 }, + { 13, 7 }, + { 29, 13 }, + { 13, 29 }, + { 999, 111 }, + { 999, 110 }, + { 999, 112 }, + { 9999, 112 }, + { 65536, 65536 }, + { UINT32_MAX, UINT32_MAX }, + { UINT32_MAX >> 1, UINT32_MAX }, + { UINT32_MAX >> 1, UINT32_MAX >> 1}, + { UINT64_MAX, 1 }, + { UINT64_MAX, 96 }, + { UINT64_MAX, 65536 }, + { UINT64_MAX, UINT32_MAX + 65536 + 71 }, + { UINT64_MAX, UINT32_MAX }, + { UINT64_MAX, UINT64_MAX >> 1 }, + { UINT64_MAX >> 1, UINT64_MAX >> 1 }, + { UINT64_MAX, UINT64_MAX }, + { UINT64_MAX >> 1, UINT64_MAX }, + }; + + size_t t; + for (t = 0; t < sizeof(tests) / sizeof(tests[0]); ++t) { + // Start a HUGE tree of tests for this pair. + do_test_variants(tests[t][0], tests[t][1]); + } + + if (divide_error_count > 0) { + printf("Got %u errors in %u cases, should have had none\n", + divide_error_count, tested); + return 1; + } + + // Test error cases work. + __divdi3(1, 0); + assert(divide_error_count == 1); + __divdi3(INT64_MIN, 0); + assert(divide_error_count == 2); + __divdi3(INT64_MAX, 0); + assert(divide_error_count == 3); + __modsi3(INT32_MIN, 0); + assert(divide_error_count == 4); + + printf("Tested %u cases ok\n", tested); + return 0; +} + +#endif // TEST diff --git a/lib/libbuiltin/arm/rules.mk b/lib/libbuiltin/arm/rules.mk new file mode 100644 index 0000000..b2dd54d --- /dev/null +++ b/lib/libbuiltin/arm/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +LIBBUILTIN_OBJS += \ + $(LOCAL_DIR)/builtin_divide.o + +ARCH_BUILTINOPS := \ + builtin_divide diff --git a/lib/libbuiltin/library.mk b/lib/libbuiltin/library.mk new file mode 100644 index 0000000..43e1604 --- /dev/null +++ b/lib/libbuiltin/library.mk @@ -0,0 +1,41 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBBUILTIN_DIR := $(GET_LOCAL_DIR) +LIBBUILTIN_BUILD := $(call TOLIBDIR,$(LIBBUILTIN_DIR)/LIBBUILTIN.a) +COMMONLIBS += LIBBUILTIN + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +# base library files +LIBBUILTIN_OBJS := + +# handle architecture-specific overrides for gcc builtin functions +ARCH_BUILTINOPS := +-include $(LIBBUILTIN_DIR)/$(ARCH)/rules.mk + +BUILTINOPS := builtin_divide + +# filter out the strops that the arch code doesn't already specify +BUILTINOPS := $(filter-out $(ARCH_BUILTINOPS),$(BUILTINOPS)) +BUILTINOPS_FILES := $(addsuffix .o,$(addprefix $(LIBBUILTIN_DIR)/,$(BUILTINOPS))) + +LIBBUILTIN_OBJS += \ + $(BUILTINOPS_FILES) + +LIBBUILTIN_OBJS := $(call TOLIBOBJDIR,$(LIBBUILTIN_OBJS)) + +$(LIBBUILTIN_BUILD): $(LIBBUILTIN_OBJS) + +ALL_DEPS += $(LIBBUILTIN_OBJS:%o=%d) + +endif diff --git a/lib/libc++/iostream.cpp b/lib/libc++/iostream.cpp new file mode 100644 index 0000000..d45c75c --- /dev/null +++ b/lib/libc++/iostream.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +const char *endl = "\n"; +ostream cout; +ostream cerr; diff --git a/lib/libc++/library.mk b/lib/libc++/library.mk new file mode 100644 index 0000000..148c166 --- /dev/null +++ b/lib/libc++/library.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBCPP_DIR := $(GET_LOCAL_DIR) +LIBCPP_BUILD := $(call TOLIBDIR,$(LIBCPP_DIR)/LIBCPP.a) +COMMONLIBS += LIBCPP + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +# base library files +LIBCPP_OBJS := $(LIBCPP_DIR)/iostream.o \ + $(LIBCPP_DIR)/misc.o \ + $(LIBCPP_DIR)/new.o + +# Do not add this until we sort out why we aren't seeing +# static constructors linked into the built object. +# $(LIBCPP_DIR)/start.o + +LIBCPP_OBJS := $(call TOLIBOBJDIR,$(LIBCPP_OBJS)) +ALL_DEPS += $(LIBCPP_OBJS:%o=%d) + +$(LIBCPP_BUILD): $(LIBCPP_OBJS) + +endif diff --git a/lib/libc++/misc.cpp b/lib/libc++/misc.cpp new file mode 100644 index 0000000..62517f4 --- /dev/null +++ b/lib/libc++/misc.cpp @@ -0,0 +1,14 @@ +#include + +extern "C" void +__cxa_pure_virtual(void) +{ + panic("Pure virtual function called"); +} + +extern "C" int +__cxa_atexit(void (*func)(void*), void* obj, void* dso) +{ + // do nothing + return 0; +} diff --git a/lib/libc++/new.cpp b/lib/libc++/new.cpp new file mode 100644 index 0000000..59e0d9f --- /dev/null +++ b/lib/libc++/new.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +/* + * Minimal new/delete. + */ +void * +operator new(size_t size) throw() +{ + return(malloc(size)); +} + +void * +operator new[](size_t size) throw() +{ + return(malloc(size)); +} + +void +operator delete(void *ptr) throw() +{ + free(ptr); +} + +void +operator delete[](void *ptr) throw() +{ + free(ptr); +} diff --git a/lib/libc++/rules.mk b/lib/libc++/rules.mk new file mode 100644 index 0000000..59b4400 --- /dev/null +++ b/lib/libc++/rules.mk @@ -0,0 +1,19 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +# +# C++ support is enabled by including this module. It affects both +# the library dependency list (by adding libc++) and also the build +# of the actual application. +# + +WITH_CPLUSPLUS := true +OPTIONS += WITH_CPLUSPLUS=1 +LIBRARY_MODULES += lib/libc++ diff --git a/lib/libc/arm/bcopy.S b/lib/libc/arm/bcopy.S new file mode 100644 index 0000000..5add772 --- /dev/null +++ b/lib/libc/arm/bcopy.S @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +.text +.align 2 + + .globl _memcpy + .globl _bcopy + .globl _memmove + +_bcopy: /* void bcopy(const void *src, void *dest, size_t len); */ + mov r3, r0 + mov r0, r1 + mov r1, r3 + +_memcpy: /* void *memcpy(void *dest, const void *src, size_t len); */ +_memmove: /* void *memmove(void *dest, const void *src, size_t len); */ + /* check for zero len or if the pointers are the same */ + cmp r2, #0 + cmpne r0, r1 + bxeq lr + + /* save r0 (return value), r4 (scratch), and r5 (scratch) */ + stmfd sp!, { r0, r4, r5 } + + /* check for overlap. r3 <- distance between src & dest */ + subhs r3, r0, r1 + sublo r3, r1, r0 + cmp r3, r2 /* if distance(src, dest) < len, we have overlap */ + blo Loverlap + +Lnormalforwardcopy: + /* are src and dest dissimilarly word aligned? */ + mov r12, r0, lsl #30 + cmp r12, r1, lsl #30 + bne Lnonwordaligned_forward + + /* if len < 64, do a quick forward copy */ + cmp r2, #64 + blt Lsmallforwardcopy + + /* check for 16 byte src/dest unalignment */ + tst r0, #0xf + bne Lsimilarlyunaligned + + /* check for 32 byte dest unalignment */ + tst r0, #(1<<4) + bne Lunaligned_32 + +Lmorethan64_aligned: + /* save some more registers to use in the copy */ + stmfd sp!, { r6, r7, r10, r11 } + + /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */ + sub r2, r2, #64 + +L64loop: + /* copy 64 bytes at a time */ + ldmia r1!, { r3, r4, r5, r6, r7, r10, r11, r12 } +#if ARCH_ARMv7 + pld [r1, #32] +#endif + stmia r0!, { r3, r4, r5, r6, r7, r10, r11, r12 } + ldmia r1!, { r3, r4, r5, r6, r7, r10, r11, r12 } + subs r2, r2, #64 +#if ARCH_ARMv7 + pld [r1, #32] +#endif + stmia r0!, { r3, r4, r5, r6, r7, r10, r11, r12 } + bge L64loop + + /* restore the scratch registers we just saved */ + ldmfd sp!, { r6, r7, r10, r11 } + + /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */ + adds r2, r2, #64 + beq Lexit + +Llessthan64_aligned: + /* copy 16 bytes at a time until we have < 16 bytes */ + cmp r2, #16 + ldmiage r1!, { r3, r4, r5, r12 } + stmiage r0!, { r3, r4, r5, r12 } + subsge r2, r2, #16 + bgt Llessthan64_aligned + beq Lexit + +Llessthan16_aligned: + mov r2, r2, lsl #28 + msr cpsr_f, r2 + + ldmiami r1!, { r2, r3 } + ldreq r4, [r1], #4 + ldrhcs r5, [r1], #2 + ldrbvs r12, [r1], #1 + + stmiami r0!, { r2, r3 } + streq r4, [r0], #4 + strhcs r5, [r0], #2 + strbvs r12, [r0], #1 + b Lexit + +Lsimilarlyunaligned: + /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */ + mov r12, r0, lsl #28 + rsb r12, r12, #0 + msr cpsr_f, r12 + + ldrbvs r3, [r1], #1 + ldrhcs r4, [r1], #2 + ldreq r5, [r1], #4 + + strbvs r3, [r0], #1 + strhcs r4, [r0], #2 + streq r5, [r0], #4 + + ldmiami r1!, { r3, r4 } + stmiami r0!, { r3, r4 } + + subs r2, r2, r12, lsr #28 + beq Lexit + +Lunaligned_32: + /* bring up to dest 32 byte alignment */ + tst r0, #(1 << 4) + ldmiane r1!, { r3, r4, r5, r12 } + stmiane r0!, { r3, r4, r5, r12 } + subne r2, r2, #16 + + /* we should now be aligned, see what copy method we should use */ + cmp r2, #64 + bge Lmorethan64_aligned + b Llessthan64_aligned + +Lbytewise2: + /* copy 2 bytes at a time */ + subs r2, r2, #2 + + ldrb r3, [r1], #1 + ldrbpl r4, [r1], #1 + + strb r3, [r0], #1 + strbpl r4, [r0], #1 + + bhi Lbytewise2 + b Lexit + +Lbytewise: + /* simple bytewise forward copy */ + ldrb r3, [r1], #1 + subs r2, r2, #1 + strb r3, [r0], #1 + bne Lbytewise + b Lexit + +Lsmallforwardcopy: + /* src and dest are word aligned similarly, less than 64 bytes to copy */ + cmp r2, #4 + blt Lbytewise2 + + /* bytewise copy until word aligned */ + tst r1, #3 +Lwordalignloop: + ldrbne r3, [r1], #1 + strbne r3, [r0], #1 + subne r2, r2, #1 + tstne r1, #3 + bne Lwordalignloop + + cmp r2, #16 + bge Llessthan64_aligned + blt Llessthan16_aligned + +Loverlap: + /* src and dest overlap in some way, len > 0 */ + cmp r0, r1 /* if dest > src */ + bhi Loverlap_srclower + +Loverlap_destlower: + /* dest < src, see if we can still do a fast forward copy or fallback to slow forward copy */ + cmp r3, #64 + bge Lnormalforwardcopy /* overlap is greater than one stride of the copy, use normal copy */ + + cmp r3, #2 + bge Lbytewise2 + b Lbytewise + + /* the following routines deal with having to copy in the reverse direction */ +Loverlap_srclower: + /* src < dest, with overlap */ + + /* src += len; dest += len; */ + add r0, r0, r2 + add r1, r1, r2 + + /* we have to copy in reverse no matter what, test if we can we use a large block reverse copy */ + cmp r2, #64 /* less than 64 bytes to copy? */ + cmpgt r3, #64 /* less than 64 bytes of nonoverlap? */ + blt Lbytewise_reverse + + /* test of src and dest are nonword aligned differently */ + mov r3, r0, lsl #30 + cmp r3, r1, lsl #30 + bne Lbytewise_reverse + + /* test if src and dest are non word aligned or dest is non 16 byte aligned */ + tst r0, #0xf + bne Lunaligned_reverse_similarly + + /* test for dest 32 byte alignment */ + tst r0, #(1<<4) + bne Lunaligned_32_reverse_similarly + + /* 64 byte reverse block copy, src and dest aligned */ +Lmorethan64_aligned_reverse: + /* save some more registers to use in the copy */ + stmfd sp!, { r6, r7, r10, r11 } + + /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */ + sub r2, r2, #64 + +L64loop_reverse: + /* copy 64 bytes at a time */ + ldmdb r1!, { r3, r4, r5, r6, r7, r10, r11, r12 } +#if ARCH_ARMv7 + pld [r1, #-32] +#endif + stmdb r0!, { r3, r4, r5, r6, r7, r10, r11, r12 } + ldmdb r1!, { r3, r4, r5, r6, r7, r10, r11, r12 } + subs r2, r2, #64 +#if ARCH_ARMv7 + pld [r1, #-32] +#endif + stmdb r0!, { r3, r4, r5, r6, r7, r10, r11, r12 } + bge L64loop_reverse + + /* restore the scratch registers we just saved */ + ldmfd sp!, { r6, r7, r10, r11 } + + /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */ + adds r2, r2, #64 + beq Lexit + +Lbytewise_reverse: + ldrb r3, [r1, #-1]! + strb r3, [r0, #-1]! + subs r2, r2, #1 + bne Lbytewise_reverse + b Lexit + +Lunaligned_reverse_similarly: + /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */ + mov r12, r0, lsl #28 + msr cpsr_f, r12 + + ldrbvs r3, [r1, #-1]! + ldrhcs r4, [r1, #-2]! + ldreq r5, [r1, #-4]! + + strbvs r3, [r0, #-1]! + strhcs r4, [r0, #-2]! + streq r5, [r0, #-4]! + + ldmdbmi r1!, { r3, r4 } + stmdbmi r0!, { r3, r4 } + + subs r2, r2, r12, lsr #28 + beq Lexit + +Lunaligned_32_reverse_similarly: + /* bring up to dest 32 byte alignment */ + tst r0, #(1 << 4) + ldmdbne r1!, { r3, r4, r5, r12 } + stmdbne r0!, { r3, r4, r5, r12 } + subne r2, r2, #16 + + /* we should now be aligned, see what copy method we should use */ + cmp r2, #64 + bge Lmorethan64_aligned_reverse + b Lbytewise_reverse + + /* the following routines deal with non word aligned copies */ +Lnonwordaligned_forward: + cmp r2, #8 + blt Lbytewise2 /* not worth the effort with less than 24 bytes total */ + + /* bytewise copy until src word aligned */ + tst r1, #3 +Lwordalignloop2: + ldrbne r3, [r1], #1 + strbne r3, [r0], #1 + subne r2, r2, #1 + tstne r1, #3 + bne Lwordalignloop2 + + /* figure out how the src and dest are unaligned */ + and r3, r0, #3 + cmp r3, #2 + blt Lalign1_forward + beq Lalign2_forward + bgt Lalign3_forward + +Lalign1_forward: + /* the dest pointer is 1 byte off from src */ + mov r12, r2, lsr #2 /* number of words we should copy */ + sub r0, r0, #1 + + /* prime the copy */ + ldrb r4, [r0] /* load D[7:0] */ + +Lalign1_forward_loop: + ldr r3, [r1], #4 /* load S */ + orr r4, r4, r3, lsl #8 /* D[31:8] = S[24:0] */ + str r4, [r0], #4 /* save D */ + mov r4, r3, lsr #24 /* D[7:0] = S[31:25] */ + subs r12, r12, #1 + bne Lalign1_forward_loop + + /* finish the copy off */ + strb r4, [r0], #1 /* save D[7:0] */ + + ands r2, r2, #3 + beq Lexit + b Lbytewise2 + +Lalign2_forward: + /* the dest pointer is 2 bytes off from src */ + mov r12, r2, lsr #2 /* number of words we should copy */ + sub r0, r0, #2 + + /* prime the copy */ + ldrh r4, [r0] /* load D[15:0] */ + +Lalign2_forward_loop: + ldr r3, [r1], #4 /* load S */ + orr r4, r4, r3, lsl #16 /* D[31:16] = S[15:0] */ + str r4, [r0], #4 /* save D */ + mov r4, r3, lsr #16 /* D[15:0] = S[31:15] */ + subs r12, r12, #1 + bne Lalign2_forward_loop + + /* finish the copy off */ + strh r4, [r0], #2 /* save D[15:0] */ + + ands r2, r2, #3 + beq Lexit + b Lbytewise2 + +Lalign3_forward: + /* the dest pointer is 3 bytes off from src */ + mov r12, r2, lsr #2 /* number of words we should copy */ + sub r0, r0, #3 + + /* prime the copy */ + ldr r4, [r0] + and r4, r4, #0x00ffffff /* load D[24:0] */ + +Lalign3_forward_loop: + ldr r3, [r1], #4 /* load S */ + orr r4, r4, r3, lsl #24 /* D[31:25] = S[7:0] */ + str r4, [r0], #4 /* save D */ + mov r4, r3, lsr #8 /* D[24:0] = S[31:8] */ + subs r12, r12, #1 + bne Lalign3_forward_loop + + /* finish the copy off */ + strh r4, [r0], #2 /* save D[15:0] */ + mov r4, r4, lsr #16 + strb r4, [r0], #1 /* save D[23:16] */ + + ands r2, r2, #3 + beq Lexit + b Lbytewise2 + +Lexit: + ldmfd sp!, { r0, r4, r5 } + bx lr + diff --git a/lib/libc/arm/bzero.S b/lib/libc/arm/bzero.S new file mode 100644 index 0000000..660b88a --- /dev/null +++ b/lib/libc/arm/bzero.S @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* + * A reasonably well-optimized bzero/memset. Should work equally well on arm11 and arm9 based + * cores. + * + * The algorithm is to align the destination pointer on a 32 byte boundary and then + * blast data 64 bytes at a time, in two stores of 32 bytes per loop. + */ + .text + .align 2 + + .globl _memset +/* void *memset(void *ptr, int c, size_t len); */ +_memset: + /* move len into r1, unpack c into r2 */ + mov r3, r2 + and r1, r1, #0xff + orr r1, r1, r1, lsl #8 + orr r2, r1, r1, lsl #16 + mov r1, r3 + b Lbzeroengine + + .globl _bzero +/* void bzero(void *ptr, size_t len); */ +_bzero: + /* zero out r2 so we can be just like memset(0) */ + mov r2, #0 + +Lbzeroengine: + /* move the base pointer into r12 and leave r0 alone so that we return the original pointer */ + mov r12, r0 + + /* copy r2 into r3 for 64-bit stores */ + mov r3, r2 + + /* check for zero len */ + cmp r1, #0 + bxeq lr + + /* fall back to a bytewise store for less than 32 bytes */ + cmp r1, #32 + blt L_bytewise + + /* check for 32 byte unaligned ptr */ + tst r12, #0x1f + bne L_unaligned + + /* make sure we have more than 64 bytes to zero */ + cmp r1, #64 + blt L_lessthan64aligned + + /* >= 64 bytes of len, 32 byte aligned */ +L_64ormorealigned: + + /* we need some registers, avoid r9 */ + stmfd sp!, { r4-r8, r10 } + mov r4, r2 + mov r5, r2 + mov r6, r2 + mov r7, r2 + mov r8, r2 + mov r10, r2 + + /* pre-subtract 64 from the len to avoid an extra compare in the loop */ + sub r1, r1, #64 + +L_64loop: + stmia r12!, { r2-r8, r10 } + subs r1, r1, #64 + stmia r12!, { r2-r8, r10 } + bge L_64loop + + /* restore the saved regs */ + ldmfd sp!, { r4-r8, r10 } + + /* check for completion (had previously subtracted an extra 64 from len) */ + adds r1, r1, #64 + bxeq lr + +L_lessthan64aligned: + /* do we have 16 or more bytes left */ + cmp r1, #16 + stmiage r12!, { r2-r3 } + stmiage r12!, { r2-r3 } + subsge r1, r1, #16 + bgt L_lessthan64aligned + bxeq lr + +L_lessthan16aligned: + /* store 0 to 15 bytes */ + mov r1, r1, lsl #28 /* move the remaining len bits [3:0] to the flags area of cpsr */ + msr cpsr_f, r1 + + stmiami r12!, { r2-r3 } /* n is set, store 8 bytes */ + streq r2, [r12], #4 /* z is set, store 4 bytes */ + strhcs r2, [r12], #2 /* c is set, store 2 bytes */ + strbvs r2, [r12], #1 /* v is set, store 1 byte */ + bx lr + +L_bytewise: + /* bytewise copy, 2 bytes at a time, alignment not guaranteed */ + subs r1, r1, #2 + strb r2, [r12], #1 + strbpl r2, [r12], #1 + bhi L_bytewise + bx lr + +L_unaligned: + /* unaligned on 32 byte boundary, store 1-15 bytes until we're 16 byte aligned */ + mov r3, r12, lsl #28 + rsb r3, r3, #0x00000000 + msr cpsr_f, r3 + + strbvs r2, [r12], #1 /* v is set, unaligned in the 1s column */ + strhcs r2, [r12], #2 /* c is set, unaligned in the 2s column */ + streq r2, [r12], #4 /* z is set, unaligned in the 4s column */ + strmi r2, [r12], #4 /* n is set, unaligned in the 8s column */ + strmi r2, [r12], #4 + + subs r1, r1, r3, lsr #28 + bxeq lr + + /* we had previously trashed r3, restore it */ + mov r3, r2 + + /* now make sure we're 32 byte aligned */ + tst r12, #(1 << 4) + stmiane r12!, { r2-r3 } + stmiane r12!, { r2-r3 } + subsne r1, r1, #16 + + /* we're now aligned, check for >= 64 bytes left */ + cmp r1, #64 + bge L_64ormorealigned + b L_lessthan64aligned + diff --git a/lib/libc/arm/rules.mk b/lib/libc/arm/rules.mk new file mode 100644 index 0000000..0bcba13 --- /dev/null +++ b/lib/libc/arm/rules.mk @@ -0,0 +1,24 @@ +# Copyright (C) 2007-2009 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +LIBC_OBJS += \ + $(LOCAL_DIR)/bcopy.o \ + $(LOCAL_DIR)/bzero.o \ + $(LOCAL_DIR)/strlen.o + +ARCH_STROPS := \ + bcopy \ + bzero \ + memset \ + memmove \ + memcpy \ + strlen diff --git a/lib/libc/arm/strlen.S b/lib/libc/arm/strlen.S new file mode 100644 index 0000000..46e662c --- /dev/null +++ b/lib/libc/arm/strlen.S @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + .text + .align 2 + + .globl _strlen +/* int strlen(const char *s); */ +_strlen: + /* save the original pointer */ + mov r12, r0 + + /* see if the string is aligned */ + ands r3, r0, #3 + + /* load the first word, address rounded down */ + bic r0, r0, #3 + ldr r2, [r0], #4 + + /* skip the next part if the string is already aligned */ + beq Laligned + +Lunaligned: + /* unaligned pointer, mask out the bytes that we've read that we should be ignoring */ + cmp r3, #2 + orr r2, r2, #0x000000ff + orrge r2, r2, #0x0000ff00 + orrgt r2, r2, #0x00ff0000 + +Laligned: + /* load 0x01010101 into r1 */ + mov r1, #0x01 + orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + +Laligned_loop: + /* ((x - 0x01010101) & ~x & 0x80808080) == hasnull(word) */ + sub r3, r2, r1 /* x - 0x01010101 */ + bic r3, r3, r2 /* above & ~x */ + tst r3, r1, lsl #7 /* above & 0x80808080 */ + ldreq r2, [r0], #4 /* load next word */ + beq Laligned_loop + + /* we found a nullbyte */ + /* r0 (ptr) has overshot by up to 4 bytes, so subtract off until we find a nullbyte */ + sub r0, r0, #1 + tst r2, #0x000000ff + subeq r0, r0, #1 + tstne r2, #0x0000ff00 + subeq r0, r0, #1 + tstne r2, #0x00ff0000 + subeq r0, r0, #1 + +Lexit: + /* len = ptr - original pointer */ + sub r0, r0, r12 + bx lr + diff --git a/lib/libc/arm64/asm.h b/lib/libc/arm64/asm.h new file mode 100644 index 0000000..e5ae87a --- /dev/null +++ b/lib/libc/arm64/asm.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _ARM_ASM_H_ +#define _ARM_ASM_H_ + +#ifdef __ASSEMBLER__ + +#define PUSH_FRAME \ + stp fp, lr, [sp, #-16]! %% \ + mov fp, sp %% + +#define POP_FRAME \ + mov sp, fp %% \ + ldp fp, lr, [sp], #16 %% + +#endif /* __ASSEMBLER__ */ +#endif /* _ARM_ASM_H_ */ diff --git a/lib/libc/arm64/bcopy.S b/lib/libc/arm64/bcopy.S new file mode 100644 index 0000000..d0a03a5 --- /dev/null +++ b/lib/libc/arm64/bcopy.S @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2012 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + * + * This file implements the following functions for the arm64 architecture. + * + * void bcopy(const void * source, + * void * destination, + * size_t length); + * + * void *memmove(void * destination, + * const void * source, + * size_t n); + * + * void *memcpy(void * restrict destination, + * const void * restrict source, + * size_t n); + * + * All copy n successive bytes from source to destination. Memmove and memcpy + * return destination, whereas bcopy has no return value. Copying takes place + * as if it were through a temporary buffer -- after return destination + * contains exactly the bytes from source, even if the buffers overlap (this is + * not required of memcpy by the C standard; its behavior is undefined if the + * buffers overlap, but we are holding ourselves to the historical behavior of + * this function on MacOS). + */ + +#include "asm.h" + +.globl _bcopy +.globl _memcpy +.globl _memmove + +/***************************************************************************** + * Macros * + *****************************************************************************/ + +#define kSmallCopy 64 + +/***************************************************************************** + * Entrypoints * + *****************************************************************************/ + +.text +.align 5 +_bcopy: +// Translate bcopy into memcpy by swapping the first and second arguments. + mov x3, x0 + mov x0, x1 + mov x1, x3 + +.align 4 +_memcpy: +_memmove: +// Our preference is to copy the data in ascending address order, but if the +// buffers overlap such that the beginning of the destination buffer aliases +// the end of the source buffer, we need to copy in descending address order +// instead to preserve the memmove semantics. We detect this case with the +// test: +// +// destination - source < length (unsigned compare) +// +// If the address of the source buffer is higher than the address of the +// destination buffer, this arithmetic can overflow, but the overflowed value +// can only be smaller than length if the buffers do not overlap, so we don't +// need to worry about false positives due to the overflow (they happen, but +// only in cases where copying in either order is correct). + PUSH_FRAME + sub x3, x0, x1 + cmp x3, x2 + b.cc L_reverse + mov x3, x0 // copy destination pointer + cmp x2, #(kSmallCopy) + b.cc L_forwardSmallCopy + +/***************************************************************************** + * Forward large copy * + *****************************************************************************/ + +// Load the first 32 bytes from src, and compute the number of bytes to the +// first 32-byte aligned location in dst. Even though we are going to copy +// 32 bytes, only those preceeding that 32-byte location "count" towards +// reducing the length of the buffer or advancing the pointers. We will need +// to issue the first load from the advanced src pointer BEFORE the store to +// the unmodified dst pointer. + add x3, x3, #32 + and x3, x3, #-32 // aligned dst + ldp x12,x13,[x1] + ldp x14,x15,[x1, #16] + sub x5, x3, x0 // bytes between original dst and aligned dst + add x1, x1, x5 // update src pointer + +// At this point, data in the following registers is in flight: +// +// x0 original dst pointer +// x1 corresponding location in src buffer. +// x2 length from aligned location in dst to end of buffer. This is +// guaranteed to be >= (64 - 32). +// x3 aligned location in dst buffer. +// x12:x15 first 32 bytes of src buffer. +// +// We now load 32 bytes from x1, and store 32 bytes from x12:x15 to x3. The +// store *may* overlap the first 32 bytes of the load, so in order to get +// correct memmove semantics, the first 32 byte load must occur before the +// store. +// +// After loading these 32 bytes, we advance x1, and decrement the length by +// 64. If the remaining length of the buffer was less than 64, then we jump +// directly to the cleanup path. + ldp x8, x9, [x1] + ldp x10,x11,[x1, #16] + add x1, x1, #32 + sub x2, x2, x5 // update length + stp x12,x13,[x0] // initial unaligned store + stp x14,x15,[x0, #16] // initial unaligned store + subs x2, x2, #64 + b.ls L_forwardCleanup + +L_forwardCopyLoop: +// Main copy loop: +// +// 1. store the 32 bytes loaded in the previous loop iteration +// 2. advance the destination pointer +// 3. load the next 32 bytes +// 4. advance the source pointer +// 5. subtract 32 from the length +// +// The loop is terminated when 32 or fewer bytes remain to be loaded. Those +// trailing 1-32 bytes will be copied in the loop cleanup. + stnp x8, x9, [x3] + stnp x10,x11,[x3, #16] + add x3, x3, #32 + ldnp x8, x9, [x1] + ldnp x10,x11,[x1, #16] + add x1, x1, #32 + subs x2, x2, #32 + b.hi L_forwardCopyLoop + +L_forwardCleanup: +// There are 32 bytes in x8-x11 that were loaded in the previous loop +// iteration, which need to be stored to [x3,x3+32). In addition, between +// 0 and 32 more bytes need to be copied from x1 to x3 + 32. The exact +// number of bytes to copy is x2 + 32. Instead of using smaller conditional +// copies, we simply copy 32 unaligned bytes from x1+x2 to 64+x3+x2. +// This copy may overlap with the first store, so the loads must come before +// the store of the data from the previous loop iteration. + add x1, x1, x2 + ldp x12,x13,[x1] + ldp x14,x15,[x1, #16] + stp x8, x9, [x3] + stp x10,x11,[x3, #16] + add x3, x3, x2 + stp x12,x13,[x3, #32] + stp x14,x15,[x3, #48] + POP_FRAME + ret + +/***************************************************************************** + * forward small copy * + *****************************************************************************/ + +// Copy one quadword at a time until less than 8 bytes remain to be copied. +// At the point of entry to L_forwardSmallCopy, the "calling convention" +// is as follows: +// +// x0 pointer to first byte of destination +// x1 pointer to first byte of source +// x2 length of buffers +// x3 pointer to first byte of destination +0: ldr x6, [x1],#8 + str x6, [x3],#8 +L_forwardSmallCopy: + subs x2, x2, #8 + b.cs 0b + adds x2, x2, #8 + b.eq 2f +1: ldrb w6, [x1],#1 + strb w6, [x3],#1 + subs x2, x2, #1 + b.ne 1b +2: POP_FRAME + ret + +/***************************************************************************** + * Reverse copy engines * + *****************************************************************************/ + +// The reverse copy engines are identical in every way to the forward copy +// engines, except in that they do everything backwards. For this reason, they +// are somewhat more sparsely commented than the forward copy loops. I have +// tried to only comment things that might be somewhat surprising in how they +// differ from the forward implementation. +// +// The one important thing to note is that (almost without fail), x1 and x3 +// will point to ONE BYTE BEYOND the "right-hand edge" of the active buffer +// throughout these copy loops. They are initially advanced to that position +// in the L_reverse jump island. Because of this, whereas the forward copy +// loops generally follow a "copy data, then advance pointers" scheme, in the +// reverse copy loops, we advance the pointers, then copy the data. + +L_reverse: +// As a minor optimization, we early out if dst == src. + cbz x3, L_return +// advance both pointers to the ends of their respective buffers before +// jumping into the appropriate reverse copy loop. + add x4, x0, x2 + add x1, x1, x2 + cmp x2, #(kSmallCopy) + b.cc L_reverseSmallCopy + +/***************************************************************************** + * Reverse large copy * + *****************************************************************************/ + + ldp x12,x13,[x1, #-16] + ldp x14,x15,[x1, #-32] + sub x3, x4, #1 // In the forward copy, we used dst+32 & -32 + and x3, x3, #-32 // to find an aligned location in the dest + sub x5, x4, x3 // buffer. Here we use dst-1 & -32 instead, + sub x1, x1, x5 // because we are going backwards. + sub x2, x2, x5 + ldp x8, x9, [x1, #-16] + ldp x10,x11,[x1, #-32] + stp x12,x13,[x4, #-16] + stp x14,x15,[x4, #-32] + sub x1, x1, #32 + subs x2, x2, #64 + b.ls L_reverseCleanup + +L_reverseCopyLoop: + stnp x8, x9, [x3, #-16] + stnp x10,x11,[x3, #-32] + sub x3, x3, #32 + ldnp x8, x9, [x1, #-16] + ldnp x10,x11,[x1, #-32] + sub x1, x1, #32 + subs x2, x2, #32 + b.hi L_reverseCopyLoop + +L_reverseCleanup: + sub x1, x1, x2 + ldp x12,x13,[x1, #-16] + ldp x14,x15,[x1, #-32] + stp x8, x9, [x3, #-16] + stp x10,x11,[x3, #-32] + stp x12,x13,[x0, #16] // In the forward copy, we need to compute the + stp x14,x15,[x0] // address of these stores, but here we already + POP_FRAME // have a pointer to the start of the buffer. + ret + +/***************************************************************************** + * reverse small copy * + *****************************************************************************/ + +0: ldr x6, [x1,#-8]! + str x6, [x4,#-8]! +L_reverseSmallCopy: + subs x2, x2, #8 + b.cs 0b + adds x2, x2, #8 + b.eq 2f +1: ldrb w6, [x1,#-1]! + strb w6, [x4,#-1]! + subs x2, x2, #1 + b.ne 1b +2: POP_FRAME + ret + +L_return: + POP_FRAME + ret diff --git a/lib/libc/arm64/bzero.S b/lib/libc/arm64/bzero.S new file mode 100644 index 0000000..e71278a --- /dev/null +++ b/lib/libc/arm64/bzero.S @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2012 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + * + * This file implements the following functions for the arm64 architecture: + * + * void bzero(void *buffer, size_t length); + * void __bzero(void *buffer, size_t length); + * void *memset(void *buffer, int value, size_t length); + * + * The first two zero-fill a buffer. The third fills the buffer with the low + * byte of its second argument. + */ + +#include "asm.h" + +.globl _bzero +.globl ___bzero +.globl _memset + +/***************************************************************************** + * bzero entrypoint * + *****************************************************************************/ + +.text +.align 4 +_bzero: +___bzero: + PUSH_FRAME + mov x2, x1 + eor x1, x1, x1 + mov x3, x0 + cmp x2, #128 + b.cc L_memsetSmall + +/***************************************************************************** + * Large buffer zero engine * + *****************************************************************************/ + +L_bzeroLarge: +// Write the first 64 bytes of the buffer without regard to alignment, then +// advance x3 to point to a cacheline-aligned location within the buffer, and +// decrement the length accordingly. + stp x1, x1, [x0] + stp x1, x1, [x0, #16] + stp x1, x1, [x0, #32] + stp x1, x1, [x0, #48] + add x3, x0, #64 + and x3, x3, #-64 + add x2, x2, x0 // end of buffer + add x4, x3, #64 // end of first cacheline to zero + subs x2, x2, x4 // if the end of the buffer comes first, jump + b.ls 1f // directly to the cleanup pass. +0: dc zva, x3 // zero cacheline + add x3, x3, #64 // increment pointer + subs x2, x2, #64 // decrement length + b.hi 0b +1: add x3, x3, x2 // back up pointer to (end of buffer) - 64. + stp x1, x1, [x3] // and store 64 bytes to reach end of buffer. + stp x1, x1, [x3, #16] + stp x1, x1, [x3, #32] + stp x1, x1, [x3, #48] + POP_FRAME + ret + +/***************************************************************************** + * memset entrypoint * + *****************************************************************************/ + +.align 4 +_memset: + PUSH_FRAME + and x1, x1, #0xff + orr x3, xzr,#0x0101010101010101 + mul x1, x1, x3 + mov x3, x0 + cmp x2, #64 + b.cc L_memsetSmall + +/***************************************************************************** + * Large buffer store engine * + *****************************************************************************/ + +L_memsetLarge: +// Write the first 64 bytes of the buffer without regard to alignment, then +// advance x3 to point to an aligned location within the buffer, and +// decrement the length accordingly. + stp x1, x1, [x0] + add x3, x0, #16 + and x3, x3, #-16 + add x2, x2, x0 // end of buffer + add x4, x3, #64 // end of first aligned 64-byte store + subs x2, x2, x4 // if the end of the buffer comes first, jump + b.ls 1f // directly to the cleanup store. +0: stnp x1, x1, [x3] + stnp x1, x1, [x3, #16] + stnp x1, x1, [x3, #32] + stnp x1, x1, [x3, #48] + add x3, x3, #64 + subs x2, x2, #64 + b.hi 0b +1: add x3, x3, x2 // back up pointer to (end of buffer) - 64. + stp x1, x1, [x3] + stp x1, x1, [x3, #16] + stp x1, x1, [x3, #32] + stp x1, x1, [x3, #48] + POP_FRAME + ret + +/***************************************************************************** + * Small buffer store engine * + *****************************************************************************/ + +0: str x1, [x3],#8 +L_memsetSmall: + subs x2, x2, #8 + b.cs 0b + adds x2, x2, #8 + b.eq 2f +1: strb w1, [x3],#1 + subs x2, x2, #1 + b.ne 1b +2: POP_FRAME + ret diff --git a/lib/libc/arm64/memcpy.S b/lib/libc/arm64/memcpy.S new file mode 100644 index 0000000..96198a5 --- /dev/null +++ b/lib/libc/arm64/memcpy.S @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +/* void memcpy_16(uint8_t *dest, const void * src, size_t count); */ + .text + .align 2 + .globl _memcpy_16 +_memcpy_16: + mov x3, x0 + mov x4, x1 +L__memcpy_16_loop: + ldp x5, x6, [x4], #16 + stp x5, x6, [x3], #16 + subs x2, x2, #16 + b.ne L__memcpy_16_loop + ret diff --git a/lib/libc/arm64/memset.S b/lib/libc/arm64/memset.S new file mode 100644 index 0000000..0e362a1 --- /dev/null +++ b/lib/libc/arm64/memset.S @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +/* void memset_16(uint8_t *ptr, uint8_t c, size_t count); */ + .text + .align 2 + .globl _memset_16 +_memset_16: + mov x3, x0 + cbz x1, L__memset_16_loop + orr x1, x1, x1, lsl #8 + orr x1, x1, x1, lsl #16 + orr x1, x1, x1, lsl #32 +L__memset_16_loop: + stp x1, x1, [x3], #16 + subs x2, x2, #16 + b.gt L__memset_16_loop + ret + +/* void bzero_64(uint8_t *ptr, size_t count); */ + .text + .align 2 + .globl _bzero_64 +_bzero_64: + mov x2, x0 +L__bzero_64_loop: + dc zva, x2 + add x2, x2, #64 + subs x1, x1, #64 + b.gt L__bzero_64_loop + ret diff --git a/lib/libc/arm64/rules.mk b/lib/libc/arm64/rules.mk new file mode 100644 index 0000000..ccc3ac0 --- /dev/null +++ b/lib/libc/arm64/rules.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2011-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +LIBC_OBJS += \ + $(LOCAL_DIR)/bcopy.o \ + $(LOCAL_DIR)/bzero.o + +ARCH_STROPS := \ + bcopy \ + bzero \ + memset \ + memmove \ + memcpy diff --git a/lib/libc/atoi.c b/lib/libc/atoi.c new file mode 100644 index 0000000..3f20524 --- /dev/null +++ b/lib/libc/atoi.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +int +atoi(str) + const char *str; +{ + return (int)strtol(str, (char **)NULL, 10); +} diff --git a/lib/libc/ctype.c b/lib/libc/ctype.c new file mode 100644 index 0000000..3969d01 --- /dev/null +++ b/lib/libc/ctype.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + +#define ismask(x) (_ctype[(int)(unsigned char)(x)]) + +static unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ + +unsigned char tolower(unsigned char c) +{ + if(isupper(c)) + c -= 'A'-'a'; + return c; +} + +unsigned char toupper(unsigned char c) +{ + if(islower(c)) + c -= 'a'-'A'; + return c; +} + +int isalnum(int c) +{ + return ((ismask(c)&(_U|_L|_D)) != 0); +} + +int isalpha(int c) +{ + return ((ismask(c)&(_U|_L)) != 0); +} + +int iscntrl(int c) +{ + return ((ismask(c)&(_C)) != 0); +} + +int isdigit(int c) +{ + return ((ismask(c)&(_D)) != 0); +} + +int isgraph(int c) +{ + return ((ismask(c)&(_P|_U|_L|_D)) != 0); +} + +int islower(int c) +{ + return ((ismask(c)&(_L)) != 0); +} + +int isprint(int c) +{ + return ((ismask(c)&(_P|_U|_L|_D|_SP)) != 0); +} + +int ispunct(int c) +{ + return ((ismask(c)&(_P)) != 0); +} + +int isspace(int c) +{ + return ((ismask(c)&(_S)) != 0); +} + +int isupper(int c) +{ + return ((ismask(c)&(_U)) != 0); +} + +int isxdigit(int c) +{ + return ((ismask(c)&(_D|_X)) != 0); +} + +int isascii(int c) +{ + return ((unsigned char)c <= 0x7f); +} + +int toascii(int c) +{ + return ((unsigned char)c & 0x7f); +} + diff --git a/lib/libc/endian.c b/lib/libc/endian.c new file mode 100644 index 0000000..5b109a3 --- /dev/null +++ b/lib/libc/endian.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + +#if ARCH_ARMv7 + +u_int32_t swap32(u_int32_t x) +{ + u_int32_t y; + + __asm__ volatile("rev %0, %1" : "=r" (y) : "r" (x)); + + return y; +} + +u_int16_t swap16(u_int16_t x) +{ + u_int16_t y; + + __asm__ volatile("rev16 %0, %1" : "=r" (y) : "r" (x)); + + return y; +} + +#else + +u_int32_t swap32(u_int32_t x) +{ + return ((((x) << 24) & 0xff000000) | (((x) << 8) & 0x00ff0000) | (((x) >> 8) & 0x0000ff00) | (((x) >> 24) & 0x000000ff)); +} + +u_int16_t swap16(u_int16_t x) +{ + return ((((x) << 8) & 0xff00) | (((x) >> 8) & 0x00ff)); +} + +#endif + +u_int32_t htonl(u_int32_t hostlong) +{ + return swap32(hostlong); +} + +u_int32_t ntohl(u_int32_t netlong) +{ + return swap32(netlong); +} + +u_int16_t htons(u_int16_t hostshort) +{ + return swap16(hostshort); +} + +u_int16_t ntohs(u_int16_t netshort) +{ + return swap16(netshort); +} diff --git a/lib/libc/library.mk b/lib/libc/library.mk new file mode 100644 index 0000000..ca10d9d --- /dev/null +++ b/lib/libc/library.mk @@ -0,0 +1,63 @@ +# Copyright (C) 2007-2010 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBC_DIR := $(GET_LOCAL_DIR) +LIBC_BUILD := $(call TOLIBDIR,$(LIBC_DIR)/LIBC.a) +COMMONLIBS += LIBC + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +# base library files +LIBC_OBJS := \ + $(LIBC_DIR)/atoi.o \ + $(LIBC_DIR)/ctype.o \ + $(LIBC_DIR)/endian.o \ + $(LIBC_DIR)/log2.o \ + $(LIBC_DIR)/memcpy_chk.o \ + $(LIBC_DIR)/memmove_chk.o \ + $(LIBC_DIR)/memset_chk.o \ + $(LIBC_DIR)/misc.o \ + $(LIBC_DIR)/printf.o \ + $(LIBC_DIR)/printf_chk.o \ + $(LIBC_DIR)/qsort.o \ + $(LIBC_DIR)/stdio.o \ + $(LIBC_DIR)/stdlib.o \ + $(LIBC_DIR)/strlcat_chk.o \ + $(LIBC_DIR)/strlcpy_chk.o \ + $(LIBC_DIR)/strtol.o \ + $(LIBC_DIR)/strtoll.o \ + $(LIBC_DIR)/strtoul.o \ + $(LIBC_DIR)/strtoull.o + +# handle architecture-specific overrides for string functions +ARCH_STROPS := +-include $(LIBC_DIR)/$(ARCH)/rules.mk + +STROPS := bcopy bzero memchr memcmp memcpy memmove memscan memset strchr\ + strcmp strcoll strdup strlcat strlcpy strlen strncmp \ + strnicmp strnlen strpbrk strrchr strsep strspn strstr strtok strxfrm + +# filter out the strops that the arch code doesn't already specify +STROPS := $(filter-out $(ARCH_STROPS),$(STROPS)) +STROPS_FILES := $(addsuffix .o,$(addprefix $(LIBC_DIR)/,$(STROPS))) + +LIBC_OBJS += \ + $(STROPS_FILES) + +LIBC_OBJS := $(call TOLIBOBJDIR,$(LIBC_OBJS)) + +$(LIBC_BUILD): $(LIBC_OBJS) + +ALL_DEPS += $(LIBC_OBJS:%o=%d) + +endif diff --git a/lib/libc/log2.c b/lib/libc/log2.c new file mode 100644 index 0000000..e0e85b7 --- /dev/null +++ b/lib/libc/log2.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include + +int log2_int(unsigned int val) +{ + if (val == 0) + return 0; + + return 31 - __builtin_clz(val); +} + diff --git a/lib/libc/memchr.c b/lib/libc/memchr.c new file mode 100644 index 0000000..e0037f5 --- /dev/null +++ b/lib/libc/memchr.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +void * +memchr(void const *buf, int c, size_t len) +{ + size_t i; + unsigned char const *b= buf; + unsigned char x= (c&0xff); + + for(i= 0; i< len; i++) { + if(b[i]== x) { + return (void*)(b+i); + } + } + + return NULL; +} + diff --git a/lib/libc/memcmp.c b/lib/libc/memcmp.c new file mode 100644 index 0000000..3b45522 --- /dev/null +++ b/lib/libc/memcmp.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include + +int +memcmp(const void *cs, const void *ct, size_t count) +{ + const unsigned char *su1, *su2; + signed char res = 0; + + for(su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + if((res = *su1 - *su2) != 0) + break; + return res; +} + +/* + * memcmp_secure + * + * memcmp with constant execution time for a given compare length. + */ +int +memcmp_secure(const void *cs, const void *ct, size_t count) +{ + const unsigned char *su1, *su2; + unsigned char res = 0; + + for(su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + res |= *su1 ^ *su2; + + return res ? 1 : 0; +} diff --git a/lib/libc/memcpy_chk.c b/lib/libc/memcpy_chk.c new file mode 100644 index 0000000..2dd2789 --- /dev/null +++ b/lib/libc/memcpy_chk.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include + +#if defined(memcpy) +#undef memcpy +#endif + +void * +__memcpy_chk(void *dst, void const *src, size_t s, size_t chk_size) +{ + if (unlikely(chk_size < s)) + panic("object size check failed (%zu < %zu)", s, chk_size); + + return memcpy(dst, src, s); +} diff --git a/lib/libc/memmove_chk.c b/lib/libc/memmove_chk.c new file mode 100644 index 0000000..9e1324b --- /dev/null +++ b/lib/libc/memmove_chk.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include + +#if defined(memmove) +#undef memmove +#endif + +void * +__memmove_chk(void *dst, void const *src, size_t s, size_t chk_size) +{ + if (unlikely(chk_size < s)) + panic("object size check failed (%zu < %zu)", s, chk_size); + + return memmove(dst, src, s); +} diff --git a/lib/libc/memscan.c b/lib/libc/memscan.c new file mode 100644 index 0000000..ee992c1 --- /dev/null +++ b/lib/libc/memscan.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +void *memscan(void *addr, int c, size_t size) +{ + unsigned char *p = (unsigned char *)addr; + + while(size) { + if(*p == c) + return (void *)p; + p++; + size--; + } + return (void *)p; +} diff --git a/lib/libc/memset_chk.c b/lib/libc/memset_chk.c new file mode 100644 index 0000000..bef9630 --- /dev/null +++ b/lib/libc/memset_chk.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include + +#if defined(memset) +#undef memset +#endif + +void * +__memset_chk(void *dst, int c, size_t s, size_t chk_size) +{ + if (unlikely(chk_size < s)) + panic("object size check failed (%zu < %zu)", s, chk_size); + + return memset(dst, c, s); +} diff --git a/lib/libc/misc.c b/lib/libc/misc.c new file mode 100644 index 0000000..47ae8af --- /dev/null +++ b/lib/libc/misc.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include + +void hexdump(const void *_ptr, size_t len) +{ + const unsigned char *ptr = _ptr; + unsigned int i; + + printf("hexdump ptr %p, len %zd\n", ptr, len); + + while (len > 0) { + printf("%p: ", ptr); + for (i=0; i < __min(len, 16u); i++) { + printf("%02x ", *ptr); + ptr++; + } + printf("\n"); + if (len < 16) + break; + len -= 16; + } +} + diff --git a/lib/libc/printf.c b/lib/libc/printf.c new file mode 100644 index 0000000..abb5ab7 --- /dev/null +++ b/lib/libc/printf.c @@ -0,0 +1,482 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include + +#if defined(snprintf) + #undef snprintf +#endif +#if defined(vsnprintf) + #undef vsnprintf +#endif + +typedef void (* printf_outfunc_t)(void *arg, char c); + +typedef struct { + printf_outfunc_t func; + size_t size; + char *buf; + size_t offset; +} printf_outfunc_state_t; + +/* Make external libraries which uses AssertMacros header to link successfully */ +void * __stderrp = NULL; + +static int do_printf(printf_outfunc_state_t *state, const char *fmt, va_list ap); + +static void printf_outfunc_state_init(printf_outfunc_state_t *state, printf_outfunc_t func, size_t size, char *buf) +{ + state->func = func; + state->size = size; + state->buf = buf; + state->offset = 0; + + /* Terminate the start of the buffer but not the end. + * See 3.1.10 snprintf unsafe buffer write. + * This guards against an attacker theoretically tampering with 'size' and + * having the ability to place a zero at any memory location. */ + if ((state->buf != NULL) && (state->size > 0)) + state->buf[0] = '\0'; +} + +static void stdout_outfunc(void *arg __unused, char c) +{ + /* Don't emit the trailing NUL, as it's only applicable to sprintf and + * friends + */ + if (c != '\0') + LIBC_FUNC(putchar)(c); +} + +static void string_outfunc(void *arg, char c) +{ + printf_outfunc_state_t *state = (printf_outfunc_state_t *)arg; + if ((state->buf != NULL) && (state->offset < (state->size - 1))) { + state->buf[state->offset++] = c; + /* String will never be unterminated. */ + if (c != '\0') { + state->buf[state->offset] = '\0'; + } + } +} + + +int LIBC_FUNC(fprintf)(void *stream __unused, const char *fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = LIBC_FUNC(vprintf)(fmt, ap); + va_end(ap); + + return err; +} + +int LIBC_FUNC(printf)(const char *fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = LIBC_FUNC(vprintf)(fmt, ap); + va_end(ap); + + return err; +} + +int LIBC_FUNC(vprintf)(const char *fmt, va_list ap) +{ + printf_outfunc_state_t state; + + printf_outfunc_state_init(&state, stdout_outfunc, 0, NULL); + return do_printf(&state, fmt, ap); +} + +int LIBC_FUNC(snprintf)(char *str, size_t size, const char *fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = LIBC_FUNC(vsnprintf)(str, size, fmt, ap); + va_end(ap); + + return err; +} + +int LIBC_FUNC(vsnprintf)(char *str, size_t size, const char *fmt, va_list ap) +{ + printf_outfunc_state_t state; + int result; + char dummy[2]; + + if (size == 0) { + /* string_outfunc doesn't handle zero sized buffers gracefully, + * write into a small safe buffer instead */ + str = dummy; + size = 2; + } + + printf_outfunc_state_init(&state, string_outfunc, size, str); + result = do_printf(&state, fmt, ap); + /* String is always terminated by each call to string_outfunc. */ + + return(result); +} + + +static char *longlong_to_string(char *buf, unsigned long long n, int len, int sign, int showsign, int zeropad) +{ + int pos = len; + int negative = 0; + + if(sign && (long long)n < 0) { + negative = 1; + n = -n; + } + + buf[--pos] = 0; + + /* only do the math if the number is >= 10 */ + while(n >= 10) { + int digit = n % 10; + + n /= 10; + + buf[--pos] = digit + '0'; + } + buf[--pos] = n + '0'; + + /* see if we need to zero pad this */ + while ((len - pos - 1) < zeropad) { + buf[--pos] = '0'; + } + + if(negative) + buf[--pos] = '-'; + else if(showsign) + buf[--pos] = '+'; + + return &buf[pos]; +} + +static char *longlong_to_hexstring(char *buf, unsigned long long u, int len, int caps) +{ + int pos = len; + static const char hextable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + static const char hextable_caps[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + const char *table; + + if(caps) + table = hextable_caps; + else + table = hextable; + + buf[--pos] = 0; + do { + unsigned int digit = u % 16; + u /= 16; + + buf[--pos] = table[digit]; + } while(u != 0); + + return &buf[pos]; +} + +#define LONGFLAG 0x00000001 +#define LONGLONGFLAG 0x00000002 +#define HALFFLAG 0x00000004 +#define HALFHALFFLAG 0x00000008 +#define SIZETFLAG 0x00000010 +#define ALTFLAG 0x00000020 +#define CAPSFLAG 0x00000040 +#define SIGNFLAG 0x00000080 +#define LEADZERO 0x00000100 +#define SEENDOT 0x00000200 +#define PADRIGHT 0x00000400 +#define NUMERIC 0x00000800 + + +static int do_printf(printf_outfunc_state_t *state, const char *fmt, va_list ap) +{ + char c; + unsigned char uc; + const char *s; + const char *prefix_string; + unsigned long long n; + int flags; + size_t chars_written = 0; + char num_buffer[32]; + int nummod[2]; + int curr_mod; + +#define OUTPUT_CHAR(c) do { state->func(state, c); chars_written++; } while(0) + + for(;;) { + /* handle regular chars that aren't format related */ + while((c = *fmt++) != 0) { + if(c == '%') + break; /* we saw a '%', break and start parsing format */ + OUTPUT_CHAR(c); + } + + /* make sure we haven't just hit the end of the string */ + if(c == 0) + break; + + /* reset the format state */ + curr_mod = nummod[0] = nummod[1] = flags = 0; + prefix_string = NULL; + +next_format: + /* grab the next format character */ + c = *fmt++; + if(c == 0) + break; + + switch(c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (c == '0' && nummod[0] == 0) { + flags |= LEADZERO; + goto next_format; + } + nummod[curr_mod] *= 10; + nummod[curr_mod] += (c - '0'); + goto next_format; + case '*': + nummod[curr_mod] = va_arg(ap, int); + goto next_format; + case '.': + if (curr_mod == 0) + curr_mod = 1; + goto next_format; + case '-': + flags |= PADRIGHT; + flags &= ~LEADZERO; + goto next_format; + case '%': + OUTPUT_CHAR('%'); + break; + case 'c': + uc = va_arg(ap, unsigned int); + OUTPUT_CHAR(uc); + break; + case 's': + s = va_arg(ap, const char *); + if(s == 0) + s = ""; + goto _output_string; + case '+': + flags |= SIGNFLAG; + goto next_format; + case '#': + flags |= ALTFLAG; + goto next_format; + case 'l': + if(flags & LONGFLAG) + flags |= LONGLONGFLAG; + flags |= LONGFLAG; + goto next_format; + case 'h': + if(flags & HALFFLAG) + flags |= HALFHALFFLAG; + flags |= HALFFLAG; + goto next_format; + case 'z': + flags |= SIZETFLAG; + goto next_format; + case 'i': + case 'd': + flags |= NUMERIC; + n = (flags & LONGLONGFLAG) ? va_arg(ap, long long) : + (flags & LONGFLAG) ? va_arg(ap, long) : + (flags & HALFHALFFLAG) ? (signed char)va_arg(ap, int) : + (flags & HALFFLAG) ? (short)va_arg(ap, int) : + (flags & SIZETFLAG) ? va_arg(ap, ssize_t) : + va_arg(ap, int); + s = longlong_to_string(num_buffer, n, sizeof(num_buffer), 1, flags & SIGNFLAG, 0); + goto _output_string; + case 'u': + flags |= NUMERIC; + n = (flags & LONGLONGFLAG) ? va_arg(ap, unsigned long long) : + (flags & LONGFLAG) ? va_arg(ap, unsigned long) : + (flags & HALFHALFFLAG) ? (unsigned char)va_arg(ap, unsigned int) : + (flags & HALFFLAG) ? (unsigned short)va_arg(ap, unsigned int) : + (flags & SIZETFLAG) ? va_arg(ap, size_t) : + va_arg(ap, unsigned int); + s = longlong_to_string(num_buffer, n, sizeof(num_buffer), 0, flags & SIGNFLAG, 0); + goto _output_string; + case 'p': +#if !RELEASE_BUILD + flags |= LONGFLAG | ALTFLAG; + goto hex; +#else + // need to consume the argument + n = (unsigned)va_arg(ap, void *); + // but we don't want to print the pointer + s = ""; + goto _output_string; +#endif + case 'X': + flags |= CAPSFLAG; + goto hex; +hex: + case 'x': + flags |= NUMERIC; + n = (flags & LONGLONGFLAG) ? va_arg(ap, unsigned long long) : + (flags & LONGFLAG) ? va_arg(ap, unsigned long) : + (flags & HALFHALFFLAG) ? (unsigned char)va_arg(ap, unsigned int) : + (flags & HALFFLAG) ? (unsigned short)va_arg(ap, unsigned int) : + (flags & SIZETFLAG) ? va_arg(ap, size_t) : + va_arg(ap, unsigned int); + s = longlong_to_hexstring(num_buffer, n, sizeof(num_buffer), flags & CAPSFLAG); + if(flags & ALTFLAG) + prefix_string = "0x"; + goto _output_string; + case 'I': + { + unsigned char *ip, lip[4]; + char ipbuf[4]; + int i; + + /* IP address */ + ip = (unsigned char *)va_arg(ap, void *); + num_buffer[0] = 0; + if (flags & ALTFLAG) { + lip[0] = ip[3]; + lip[1] = ip[2]; + lip[2] = ip[1]; + lip[3] = ip[0]; + } else { + lip[0] = ip[0]; + lip[1] = ip[1]; + lip[2] = ip[2]; + lip[3] = ip[3]; + } + ipbuf[0] = 0; + for (i = 0; i < 4; i++) { + s = longlong_to_string(ipbuf, lip[i], sizeof(ipbuf), 0, 0, 0); + strlcat(num_buffer, s, sizeof(num_buffer)); + if (i < 3) + strlcat(num_buffer, ".", sizeof(num_buffer)); + } + s = num_buffer; + goto _output_string; + + } + case 'M': + { + unsigned char *mac; + + /* ethernet MAC address */ + mac = (unsigned char *)va_arg(ap, void *); + char macbuf[4]; + int i; + + num_buffer[0] = 0; + + for (i = 0; i < 6; i++) { + s = longlong_to_hexstring(macbuf, mac[i], sizeof(macbuf), 0); + strlcat(num_buffer, s, sizeof(num_buffer)); + if (i < 5) + strlcat(num_buffer, ":", sizeof(num_buffer)); + } + s = num_buffer; + goto _output_string; + + } + case 'n': + /* + * XXX Do not implement %n, as it is the main + * basis for printf format-string attacks. + */ + break; + default: + OUTPUT_CHAR('%'); + OUTPUT_CHAR(c); + break; + } + + /* move on to the next field */ + continue; + + /* shared output code */ +_output_string: + if (nummod[0] > 0) { + int output_len = (int)strlen(s); + int prefix_len = prefix_string == NULL ? 0 : (int)strlen(prefix_string); + if (nummod[0] < (output_len + prefix_len)) + nummod[0] = 0; + } + + if (nummod[0] > 0) { + if (!(flags & PADRIGHT)) { + /* lead pad the string with either zero or space */ + char pad = (flags & LEADZERO) ? '0' : ' '; + int len = strlen(s); + if (prefix_string) + len += strlen(prefix_string); + + if (nummod[0] > len) { + len = nummod[0] - len; + nummod[0] -= len; + + // sign bit goes before 0-padding + if ((flags & NUMERIC) && pad == '0' && + (s[0] == '-' || s[0] == '+')) { + OUTPUT_CHAR(*s++); + nummod[0]--; + } + + if (prefix_string && pad == '0') { + while(*prefix_string != 0) + OUTPUT_CHAR(*prefix_string++); + prefix_string = NULL; + } + + while (len-- > 0) + OUTPUT_CHAR(pad); + } + } + } else if (nummod[0] == 0) { + nummod[0] = INT_MAX; + flags &= ~PADRIGHT; /* otherwise we will print a lot of spaces */ + } + if (prefix_string) { + while(*prefix_string != 0 && (nummod[0]-- > 0)) + OUTPUT_CHAR(*prefix_string++); + } + while(*s != 0 && (nummod[0]-- > 0)) + OUTPUT_CHAR(*s++); + if (flags & PADRIGHT) { + while (nummod[0]-- > 0) + OUTPUT_CHAR(' '); + } + continue; + } + + return chars_written; +} diff --git a/lib/libc/printf_chk.c b/lib/libc/printf_chk.c new file mode 100644 index 0000000..d69f34a --- /dev/null +++ b/lib/libc/printf_chk.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include +#include + +#if defined(snprintf) +#undef snprintf +#endif +#if defined(vsnprintf) +#undef vsnprintf +#endif + +int +__snprintf_chk(char *dst, size_t size, int flags __unused, size_t chk_size, const char *fmt, ...) +{ + int result; + va_list ap; + + if (unlikely(chk_size < size)) + panic("object size check failed (%zu < %zu)", size, chk_size); + + va_start(ap, fmt); + result = vsnprintf(dst, size, fmt, ap); + va_end(ap); + + return result; +} + +int +__vsnprintf_chk(char *dst, size_t size, int flags __unused, size_t chk_size, const char *fmt, va_list ap) +{ + if (unlikely(chk_size < size)) + panic("object size check failed (%zu < %zu)", size, chk_size); + + return vsnprintf(dst, size, fmt, ap); +} diff --git a/lib/libc/qsort.c b/lib/libc/qsort.c new file mode 100644 index 0000000..d31afac --- /dev/null +++ b/lib/libc/qsort.c @@ -0,0 +1,194 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#ifdef I_AM_QSORT_R +typedef int cmp_t(void *, const void *, const void *); +#else +typedef int cmp_t(const void *, const void *); +#endif +static inline char *med3(char *, char *, char *, cmp_t *, void *); +static inline void swapfunc(char *, char *, int, int); + +#ifndef min +#define min(a, b) (a) < (b) ? a : b +#endif + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static inline void +swapfunc(a, b, n, swaptype) + char *a, *b; + int n, swaptype; +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#ifdef I_AM_QSORT_R +#define CMP(t, x, y) (cmp((t), (x), (y))) +#else +#define CMP(t, x, y) (cmp((x), (y))) +#endif + +static inline char * +med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk +#ifndef I_AM_QSORT_R +__unused +#endif +) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#ifdef I_AM_QSORT_R +void +qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) +#else +#define thunk NULL +void +qsort(void *a, size_t n, size_t es, cmp_t *cmp) +#endif +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int d, r, swaptype, swap_cnt; + +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min((int)(pd - pc), (int)(pn - pd - es)); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > (int)es) +#ifdef I_AM_QSORT_R + qsort_r(a, r / es, es, thunk, cmp); +#else + qsort(a, r / es, es, cmp); +#endif + if ((r = pd - pc) > (int)es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* qsort(pn - r, r / es, es, cmp);*/ +} diff --git a/lib/libc/stdio.c b/lib/libc/stdio.c new file mode 100644 index 0000000..5d75534 --- /dev/null +++ b/lib/libc/stdio.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +int errno = 0; + +int puts(const char *str) +{ + enter_critical_section(); + while(*str) { + putchar(*str); + str++; + } + exit_critical_section(); + + return 0; +} + +int getchar(void) +{ + char c; + + c = debug_getchar(); + if (c == '\r') + c = '\n'; + return c; +} + +int putchar(int c) +{ + if (c == '\n') + debug_putchar('\r'); + debug_putchar(c); + + return 0; +} + diff --git a/lib/libc/stdlib.c b/lib/libc/stdlib.c new file mode 100644 index 0000000..b62a38b --- /dev/null +++ b/lib/libc/stdlib.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +static int randseed = 12345; + +int system(const char *string) +{ + printf("unsupported: system(%s)\n", string); + return -1; +} + +void exit(int status) +{ + panic("exit(%d) called\n", status); + + for (;;) + ; +} + +int rand(void) +{ + return (randseed = randseed * 12345 + 17); +} + +void srand(unsigned int seed) +{ + randseed = (int)seed; +} diff --git a/lib/libc/strchr.c b/lib/libc/strchr.c new file mode 100644 index 0000000..964d361 --- /dev/null +++ b/lib/libc/strchr.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +char * +strchr(const char *s, int c) +{ + for(; *s != (char) c; ++s) + if (*s == '\0') + return NULL; + return (char *) s; +} diff --git a/lib/libc/strcmp.c b/lib/libc/strcmp.c new file mode 100644 index 0000000..59baa07 --- /dev/null +++ b/lib/libc/strcmp.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +int +strcmp(char const *cs, char const *ct) +{ + signed char __res; + + while(1) { + if((__res = *cs - *ct++) != 0 || !*cs++) + break; + } + + return __res; +} diff --git a/lib/libc/strcoll.c b/lib/libc/strcoll.c new file mode 100644 index 0000000..b4af652 --- /dev/null +++ b/lib/libc/strcoll.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include + +int +strcoll(const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} + diff --git a/lib/libc/strdup.c b/lib/libc/strdup.c new file mode 100644 index 0000000..1f90ade --- /dev/null +++ b/lib/libc/strdup.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +char * +strdup(const char *str) +{ + size_t len; + char *copy; + + len = strlen(str) + 1; + copy = malloc(len); + memcpy(copy, str, len); + return copy; +} + diff --git a/lib/libc/strlcat.c b/lib/libc/strlcat.c new file mode 100644 index 0000000..f49a499 --- /dev/null +++ b/lib/libc/strlcat.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +#if defined(strlcat) +#undef strlcat +#endif + +size_t +strlcat(char *dst, char const *src, size_t s) +{ + size_t i; + size_t j= strnlen(dst, s); + + if(!s || (s== j)) { + return j+strlen(src); + } + + dst+= j; + s-= j; + + for(i= 0; ((i< s-1) && src[i]); i++) { + dst[i]= src[i]; + } + + dst[i]= 0; + + return j + i + strlen(src+i); +} diff --git a/lib/libc/strlcat_chk.c b/lib/libc/strlcat_chk.c new file mode 100644 index 0000000..31972ba --- /dev/null +++ b/lib/libc/strlcat_chk.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +#if defined(strlcat) +#undef strlcat +#endif + +size_t +__strlcat_chk(char *dst, char const *src, size_t s, size_t chk_size) +{ + if (unlikely(chk_size < s)) + panic("object size check failed (%zu < %zu)", s, chk_size); + + return strlcat(dst, src, s); +} diff --git a/lib/libc/strlcpy.c b/lib/libc/strlcpy.c new file mode 100644 index 0000000..10e8058 --- /dev/null +++ b/lib/libc/strlcpy.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include + +#if defined(strlcpy) +#undef strlcpy +#endif + +size_t +strlcpy(char *dst, char const *src, size_t s) +{ + size_t i= 0; + + if(!s) { + return strlen(src); + } + + for(i= 0; ((i< s-1) && src[i]); i++) { + dst[i]= src[i]; + } + + dst[i]= 0; + + return i + strlen(src+i); +} diff --git a/lib/libc/strlcpy_chk.c b/lib/libc/strlcpy_chk.c new file mode 100644 index 0000000..befe026 --- /dev/null +++ b/lib/libc/strlcpy_chk.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include + +#if defined(strlcpy) +#undef strlcpy +#endif + +size_t +__strlcpy_chk(char *dst, char const *src, size_t s, size_t chk_size) +{ + if (unlikely(chk_size < s)) + panic("object size check failed (%zu < %zu)", s, chk_size); + + return strlcpy(dst, src, s); +} diff --git a/lib/libc/strlen.c b/lib/libc/strlen.c new file mode 100644 index 0000000..379239f --- /dev/null +++ b/lib/libc/strlen.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +size_t +strlen(char const *s) +{ + size_t i; + + i= 0; + while(s[i]) { + i+= 1; + } + + return i; +} diff --git a/lib/libc/strncmp.c b/lib/libc/strncmp.c new file mode 100644 index 0000000..b1e21ae --- /dev/null +++ b/lib/libc/strncmp.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +int +strncmp(char const *cs, char const *ct, size_t count) +{ + signed char __res = 0; + + while(count > 0) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + count--; + } + + return __res; +} diff --git a/lib/libc/strnicmp.c b/lib/libc/strnicmp.c new file mode 100644 index 0000000..33ed7d3 --- /dev/null +++ b/lib/libc/strnicmp.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include + +int +strnicmp(char const *s1, char const *s2, size_t len) +{ + unsigned char c1 = '\0'; + unsigned char c2 = '\0'; + + if(len > 0) { + do { + c1 = *s1; c2 = *s2; + s1++; s2++; + if(!c1) + break; + if(!c2) + break; + if(c1 == c2) + continue; + c1 = tolower(c1); + c2 = tolower(c2); + if (c1 != c2) + break; + } while(--len); + } + return (int)c1 - (int)c2; +} diff --git a/lib/libc/strnlen.c b/lib/libc/strnlen.c new file mode 100644 index 0000000..90321c0 --- /dev/null +++ b/lib/libc/strnlen.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +size_t +strnlen(char const *s, size_t count) +{ + const char *sc; + + for(sc = s; count-- && *sc != '\0'; ++sc) + ; + return sc - s; +} diff --git a/lib/libc/strpbrk.c b/lib/libc/strpbrk.c new file mode 100644 index 0000000..ee53eab --- /dev/null +++ b/lib/libc/strpbrk.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +char * +strpbrk(char const *cs, char const *ct) +{ + const char *sc1; + const char *sc2; + + for(sc1 = cs; *sc1 != '\0'; ++sc1) { + for(sc2 = ct; *sc2 != '\0'; ++sc2) { + if(*sc1 == *sc2) + return (char *)sc1; + } + } + + return NULL; +} diff --git a/lib/libc/strrchr.c b/lib/libc/strrchr.c new file mode 100644 index 0000000..5821ae8 --- /dev/null +++ b/lib/libc/strrchr.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +char * +strrchr(char const *s, int c) +{ + char const *last= c?0:s; + + + while(*s) { + if(*s== c) { + last= s; + } + + s+= 1; + } + + return (char *)last; +} diff --git a/lib/libc/strsep.c b/lib/libc/strsep.c new file mode 100644 index 0000000..39cdd68 --- /dev/null +++ b/lib/libc/strsep.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * strsep(char **stringp, const char *delim) +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + + __builtin_unreachable(); +} diff --git a/lib/libc/strspn.c b/lib/libc/strspn.c new file mode 100644 index 0000000..b9e0914 --- /dev/null +++ b/lib/libc/strspn.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +size_t +strspn(char const *s, char const *accept) +{ + const char *p; + const char *a; + size_t count = 0; + + for(p = s; *p != '\0'; ++p) { + for(a = accept; *a != '\0'; ++a) { + if(*p == *a) + break; + } + if(*a == '\0') + return count; + ++count; + } + + return count; +} diff --git a/lib/libc/strstr.c b/lib/libc/strstr.c new file mode 100644 index 0000000..5db4ae9 --- /dev/null +++ b/lib/libc/strstr.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +char * +strstr(char const *s1, char const *s2) +{ + int l1, l2; + + l2 = strlen(s2); + if (!l2) + return (char *)s1; + l1 = strlen(s1); + while(l1 >= l2) { + l1--; + if (!memcmp(s1,s2,l2)) + return (char *)s1; + s1++; + } + return NULL; +} diff --git a/lib/libc/strtok.c b/lib/libc/strtok.c new file mode 100644 index 0000000..341728e --- /dev/null +++ b/lib/libc/strtok.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +static char *___strtok = NULL; + +char * +strtok(char *s, char const *ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} diff --git a/lib/libc/strtol.c b/lib/libc/strtol.c new file mode 100644 index 0000000..b087779 --- /dev/null +++ b/lib/libc/strtol.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + + +/* + * Convert a string to a long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long +strtol(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX + : LONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/lib/libc/strtoll.c b/lib/libc/strtoll.c new file mode 100644 index 0000000..a491291 --- /dev/null +++ b/lib/libc/strtoll.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* + * Convert a string to a long long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long long +strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/lib/libc/strtoul.c b/lib/libc/strtoul.c new file mode 100644 index 0000000..fce8b36 --- /dev/null +++ b/lib/libc/strtoul.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long +strtoul(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/lib/libc/strtoull.c b/lib/libc/strtoull.c new file mode 100644 index 0000000..069651b --- /dev/null +++ b/lib/libc/strtoull.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long long +strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + const char *s; + unsigned long long acc; + char c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULLONG_MAX / base; + cutlim = ULLONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/lib/libc/strxfrm.c b/lib/libc/strxfrm.c new file mode 100644 index 0000000..beef22b --- /dev/null +++ b/lib/libc/strxfrm.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +size_t +strxfrm(char *dest, const char *src, size_t n) +{ + size_t len = strlen(src); + + if(n) { + size_t copy_len = len < n ? len : n - 1; + memcpy(dest, src, copy_len); + dest[copy_len] = 0; + } + return len; +} + diff --git a/lib/libc/test_printf.c b/lib/libc/test_printf.c new file mode 100644 index 0000000..62e4a4c --- /dev/null +++ b/lib/libc/test_printf.c @@ -0,0 +1,401 @@ +#include +#include +#include + +int libc_putchar(int c) +{ + return c; +} + +void test_snprintf(uintptr_t param) +{ + char buf[200]; + int result; + + //////////////////////////////////////////////////////////// + // Tests for format strings without conversion specifiers // + //////////////////////////////////////////////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), ""); + TEST_ASSERT_STR_EQ(buf, ""); + TEST_ASSERT_EQ(result, 0); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "abc"); + TEST_ASSERT_STR_EQ(buf, "abc"); + TEST_ASSERT_EQ(result, 3); + + // short length truncates output, but returns untruncated length + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, 1, "abc"); + TEST_ASSERT_STR_EQ(buf, ""); + TEST_ASSERT_EQ(result, 3); + + // short length truncates output, but returns untruncated length + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, 2, "abc"); + TEST_ASSERT_STR_EQ(buf, "a"); + TEST_ASSERT_EQ(result, 3); + + // length of 0 results in untouched buffer + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, 0, "abc"); + TEST_ASSERT_EQ((uint8_t)buf[0], 1); + TEST_ASSERT_EQ((uint8_t)buf[1], 1); + TEST_ASSERT_EQ((uint8_t)buf[2], 1); + TEST_ASSERT_EQ((uint8_t)buf[3], 1); + TEST_ASSERT_EQ(result, 3); + + ////////////////// + // Tests for %% // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%%"); + TEST_ASSERT_STR_EQ(buf, "%"); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, 1, "%%"); + TEST_ASSERT_STR_EQ(buf, ""); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%%"); + TEST_ASSERT_STR_EQ(buf, "%"); + TEST_ASSERT_EQ(result, 1); + + ////////////////// + // Tests for %s // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%s", "abc"); + TEST_ASSERT_STR_EQ(buf, "abc"); + TEST_ASSERT_EQ(result, 3); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "123%sXYZ", "abc"); + TEST_ASSERT_STR_EQ(buf, "123abcXYZ"); + TEST_ASSERT_EQ(result, 9); + + // truncating in middle of conversion + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, 5, "%s", "abcdefgh"); + TEST_ASSERT_STR_EQ(buf, "abcd"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%10s", "abc"); + TEST_ASSERT_STR_EQ(buf, " abc"); + TEST_ASSERT_EQ(result, 10); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%-10s", "abc"); + TEST_ASSERT_STR_EQ(buf, "abc "); + TEST_ASSERT_EQ(result, 10); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%1s", "abc"); + TEST_ASSERT_STR_EQ(buf, "abc"); + TEST_ASSERT_EQ(result, 3); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%-1s", "abc"); + TEST_ASSERT_STR_EQ(buf, "abc"); + TEST_ASSERT_EQ(result, 3); + + // TODO: truncate in middle of padding + + ////////////////// + // Tests for %c // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%c", 0x20); + TEST_ASSERT_STR_EQ(buf, " "); + TEST_ASSERT_EQ(result, 1); + + ////////////////// + // Tests for %d // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", 0); + TEST_ASSERT_STR_EQ(buf, "0"); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", 1); + TEST_ASSERT_STR_EQ(buf, "1"); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", 1234567890); + TEST_ASSERT_STR_EQ(buf, "1234567890"); + TEST_ASSERT_EQ(result, 10); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", -1); + TEST_ASSERT_STR_EQ(buf, "-1"); + TEST_ASSERT_EQ(result, 2); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", -1234567890); + TEST_ASSERT_STR_EQ(buf, "-1234567890"); + TEST_ASSERT_EQ(result, 11); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", -1234567890); + TEST_ASSERT_STR_EQ(buf, "-1234567890"); + TEST_ASSERT_EQ(result, 11); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", 2147483647); + TEST_ASSERT_STR_EQ(buf, "2147483647"); + TEST_ASSERT_EQ(result, 10); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%d", (int)-2147483648); + TEST_ASSERT_STR_EQ(buf, "-2147483648"); + TEST_ASSERT_EQ(result, 11); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%04d", 1); + TEST_ASSERT_STR_EQ(buf, "0001"); + TEST_ASSERT_EQ(result, 4); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%04d", 12345); + TEST_ASSERT_STR_EQ(buf, "12345"); + TEST_ASSERT_EQ(result, 5); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%04d", -123); + TEST_ASSERT_STR_EQ(buf, "-123"); + TEST_ASSERT_EQ(result, 4); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%04d", -1234); + TEST_ASSERT_STR_EQ(buf, "-1234"); + TEST_ASSERT_EQ(result, 5); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%04d", -12345); + TEST_ASSERT_STR_EQ(buf, "-12345"); + TEST_ASSERT_EQ(result, 6); + + // TODO left and right padding and 0 and ' ' padding in all combos, + // with too much, just enough, and too little + + // TODO '+' flag + + ////////////////// + // Tests for %u // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%u", 0); + TEST_ASSERT_STR_EQ(buf, "0"); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%u", 1); + TEST_ASSERT_STR_EQ(buf, "1"); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%u", 1234567890); + TEST_ASSERT_STR_EQ(buf, "1234567890"); + TEST_ASSERT_EQ(result, 10); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%u", 2147483647); + TEST_ASSERT_STR_EQ(buf, "2147483647"); + TEST_ASSERT_EQ(result, 10); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%u", 4294967295u); + TEST_ASSERT_STR_EQ(buf, "4294967295"); + TEST_ASSERT_EQ(result, 10); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%04u", 1); + TEST_ASSERT_STR_EQ(buf, "0001"); + TEST_ASSERT_EQ(result, 4); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%04u", 12345); + TEST_ASSERT_STR_EQ(buf, "12345"); + TEST_ASSERT_EQ(result, 5); + + ////////////////// + // Tests for %x // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%x", 0); + TEST_ASSERT_STR_EQ(buf, "0"); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%#x", 0); + TEST_ASSERT_STR_EQ(buf, "0x0"); + TEST_ASSERT_EQ(result, 3); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%x", 1); + TEST_ASSERT_STR_EQ(buf, "1"); + TEST_ASSERT_EQ(result, 1); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%#x", 1); + TEST_ASSERT_STR_EQ(buf, "0x1"); + TEST_ASSERT_EQ(result, 3); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%x", 0x1234abcd); + TEST_ASSERT_STR_EQ(buf, "1234abcd"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%x", 0x567890ef); + TEST_ASSERT_STR_EQ(buf, "567890ef"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%x", 0xffffffff); + TEST_ASSERT_STR_EQ(buf, "ffffffff"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%8x", 0x1234); + TEST_ASSERT_STR_EQ(buf, " 1234"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%#8x", 0x1234); + TEST_ASSERT_STR_EQ(buf, " 0x1234"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%08x", 0x1234); + TEST_ASSERT_STR_EQ(buf, "00001234"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%#08x", 0x1234); + TEST_ASSERT_STR_EQ(buf, "0x001234"); + TEST_ASSERT_EQ(result, 8); + + ////////////////// + // Tests for %X // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%X", 0x1234abcd); + TEST_ASSERT_STR_EQ(buf, "1234ABCD"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%X", 0x567890ef); + TEST_ASSERT_STR_EQ(buf, "567890EF"); + TEST_ASSERT_EQ(result, 8); + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%8x", 0x1234); + TEST_ASSERT_STR_EQ(buf, " 1234"); + TEST_ASSERT_EQ(result, 8); + + ////////////////// + // Tests for %p // + ////////////////// + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%p", (void *)0); +#if !RELEASE_BUILD + TEST_ASSERT_STR_EQ(buf, "0x0"); + TEST_ASSERT_EQ(result, 3); +#else + TEST_ASSERT_STR_EQ(buf, ""); + TEST_ASSERT_EQ(result, 5); +#endif + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%p", (void *)0x12345678); +#if !RELEASE_BUILD + TEST_ASSERT_STR_EQ(buf, "0x12345678"); + TEST_ASSERT_EQ(result, 10); +#else + TEST_ASSERT_STR_EQ(buf, ""); + TEST_ASSERT_EQ(result, 5); +#endif + + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%p %d", (void *)0x12345678, 5555); +#if !RELEASE_BUILD + TEST_ASSERT_STR_EQ(buf, "0x12345678 5555"); + TEST_ASSERT_EQ(result, 15); +#else + TEST_ASSERT_STR_EQ(buf, " 5555"); + TEST_ASSERT_EQ(result, 10); +#endif + + // make sure we don't truncate %p conversions when the output is longer + // than the minimum field width + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%3p", (void *)0x12345); +#if !RELEASE_BUILD + TEST_ASSERT_STR_EQ(buf, "0x12345"); + TEST_ASSERT_EQ(result, 7); +#else + TEST_ASSERT_STR_EQ(buf, ""); + TEST_ASSERT_EQ(result, 5); +#endif + + // make sure we don't truncate %p conversions when the output minus the + // 0x is equal to the minimum field width + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%5p", (void *)0x12345); +#if !RELEASE_BUILD + TEST_ASSERT_STR_EQ(buf, "0x12345"); + TEST_ASSERT_EQ(result, 7); +#else + TEST_ASSERT_STR_EQ(buf, ""); + TEST_ASSERT_EQ(result, 5); +#endif + + // minimum field width is inclusive of the 0x + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%7p", (void *)0x12345); +#if !RELEASE_BUILD + TEST_ASSERT_STR_EQ(buf, "0x12345"); + TEST_ASSERT_EQ(result, 7); +#else + TEST_ASSERT_STR_EQ(buf, " "); + TEST_ASSERT_EQ(result, 7); +#endif + + // verify padding occurs on %p when output is smaller than + // minimum field width + memset(buf, 1, sizeof(buf)); + result = libc_snprintf(buf, sizeof(buf), "%9p", (void *)0x12345); +#if !RELEASE_BUILD + TEST_ASSERT_STR_EQ(buf, " 0x12345"); + TEST_ASSERT_EQ(result, 9); +#else + TEST_ASSERT_STR_EQ(buf, " "); + TEST_ASSERT_EQ(result, 9); +#endif +} + +struct test_suite printf_suite = { + .name = "printf", + .test_cases = { + { "snprintf", test_snprintf, 0, "Tests the snprintf function" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(printf_suite); diff --git a/lib/libc/tests-base.mk b/lib/libc/tests-base.mk new file mode 100644 index 0000000..d4039f6 --- /dev/null +++ b/lib/libc/tests-base.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +TEST_OBJS := \ + $(LOCAL_DIR)/printf.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/test_printf.o + diff --git a/lib/libc/tests-release.mk b/lib/libc/tests-release.mk new file mode 100644 index 0000000..fa5d3e1 --- /dev/null +++ b/lib/libc/tests-release.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := libc-release + +include $(LOCAL_DIR)/tests-base.mk + +TEST_CFLAGS += \ + -DRELEASE_BUILD=1 diff --git a/lib/libc/tests.mk b/lib/libc/tests.mk new file mode 100644 index 0000000..28d9a46 --- /dev/null +++ b/lib/libc/tests.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +include $(LOCAL_DIR)/tests-base.mk + +TEST_NAME := libc diff --git a/lib/libcorecrypto/library.mk b/lib/libcorecrypto/library.mk new file mode 100644 index 0000000..885c535 --- /dev/null +++ b/lib/libcorecrypto/library.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +EXTERNAL_STATICLIBS += $(SDKROOT)/usr/local/lib/libcorecrypto_iboot.a + +OPTIONS += \ + WITH_CORECRYPTO=1 \ + MENU_TASK_SIZE=0x3000 \ + USB_VENDOR_TASK_SIZE=0x3000 \ No newline at end of file diff --git a/lib/lzss/arm/lzssdec.S b/lib/lzss/arm/lzssdec.S new file mode 100644 index 0000000..f1b8525 --- /dev/null +++ b/lib/lzss/arm/lzssdec.S @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2011-2012, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef __arm__ + + .text + .syntax unified + + .text + .align 2 + +#define N 4096 /* size of ring buffer - must be power of 2 */ +#define F 18 /* upper limit for match_length */ +#define THRESHOLD 2 /* encode string into position and length if match_length is greater than this */ + + .globl _decompress_lzss_vec +_decompress_lzss_vec: + +// int decompress_lzss( +// u_int8_t * dst, - r0 +// u_int32_t dstlen, - r1 never used +// u_int8_t * src, - r2 +// u_int32_t srclen) - r3 (used once to define srcend) +// { +// u_int8_t text_buf[N + F - 1]; +// u_int8_t * dststart = dst; +// const u_int8_t * srcend = src + srclen; +// int i, j, k, r, c; +// unsigned int flags; + +// dst = dststart; + + mov r12, r0 + +// for (i = 0; i < N - F; i++) text_buf[i] = ' '; + + push {r4-r8,r10-r11,lr} + + mov lr, sp // store sp in lr, need to aligned + mov r4, #0xfffffff0 + and sp, r4 // 16-byte alignment + + mov r5, #32 // r5 = ' '; + sub sp, #N // it appears that text_buf[N] is sufficient, the extra F-1 bytes is never used + + add r5, r5, r5, lsl #8 // r5 = ' '; + mov r4, sp // r1 -> text_buf[0] + add r5, r5, r5, lsl #16 // r5 = ' '; + + mov r1, #(N-F+2) // do extra 2, so that 4080 is a multiple of 16 (255) + +#if WITH_VFP + vdup.32 q0, r5 +#else + mov r6, r5 + mov r7, r5 + mov r8, r5 +#endif + +loop0: +#if WITH_VFP + vst1.f32 {q0}, [r4,:128]! +#else + stmia r4!, {r5-r8} +#endif + subs r1, #16 + bgt loop0 + +// r = N - F; +// flags = 0; + + + mov r4, #N + sub r11, r4, #1 // r11 = N-1, will be used for circular buffering in text_buf[r] + sub r4, #F // r = N-r + mov r1, #0 // flag = 0 + + #define dststart r12 + #define dst r0 + #define flags r1 + #define src r2 + #define srcend r3 + #define r r4 + #define c r5 + #define i r6 + #define j r7 + #define t r8 + #define k r10 + #define text_buf sp + #define Nm1 r11 + + add srcend, src, r3 + +for_loop: + +// for ( ; ; ) { + +// if (((flags >>= 1) & 0x100) == 0) { +// if (src < srcend) c = *src++; else break; +// flags = c | 0xFF00; +// } + + lsr flags, #1 // flags >>= 1 + tst flags, #0x100 // (flags >>= 1) & 0x100) + bne skip1 // if != 0, skip the following + cmp src, srcend // src vs srcend + bge break_for_loop // if (src>=srcend) break_for_loop + ldrb c,[src],#1 // c = *src++ + orr flags,c,#0x00ff00 // flags = c | 0xFF00; + +skip1: + +// if (flags & 1) { + tst flags, #1 + beq skip2 +// if (src < srcend) c = *src++; else break; +// *dst++ = c; +// text_buf[r++] = c; +// r &= (N - 1); + + cmp src, srcend // src vs srcend + bge break_for_loop // if (src>=srcend) break_for_loop + ldrb c,[src],#1 // c = *src++ + strb c,[text_buf,r] // text_buf[r] + add r, #1 // r++ + strb c,[dst],#1 // *dst++ = c; + and r, Nm1 // r &= (N - 1); + b for_loop + +// } else { +skip2: +// if (src < srcend) i = *src++; else break; +// if (src < srcend) j = *src++; else break; + +#if (0) + cmp src, srcend // src vs srcend + bge break_for_loop // if (src>=srcend) break_for_loop + ldrb i,[src],#1 // i = *src++ + cmp src, srcend // src vs srcend + bge break_for_loop // if (src>=srcend) break_for_loop + ldrb j,[src],#1 // j = *src++ +#else + ldrh i,[src],#2 // + cmp src, srcend // + lsr j, i, #8 + bgt break_for_loop + sub i, i, j, lsl #8 + +#endif + +// i |= ((j & 0xF0) << 4); +// j = (j & 0x0F) + THRESHOLD; + + and t, j, #0xf0 // j&0xf0 + and j, #0x0f // j&0x0f + orr i, i, t, lsl #4 // i |= ((j & 0xF0) << 4); + add j, #THRESHOLD // j = (j & 0x0F) + THRESHOLD; + +// for (k = 0; k <= j; k++) { +// c = text_buf[(i + k) & (N - 1)]; +// *dst++ = c; +// text_buf[r++] = c; +// r &= (N - 1); +// } + mov k, #0 + +k_loop: + add t, i, k // (i+k) + and t, Nm1 // (i + k) & (N - 1) + ldrb c, [text_buf, t] // c = text_buf[(i + k) & (N - 1)]; + strb c, [dst], #1 // *dst++ = c; + strb c, [text_buf, r] // text_buf[r] = c; + add r, #1 // r++ + and r, Nm1 // r &= (N - 1); + add k, #1 // k++ + cmp k, j // k vs j + ble k_loop + b for_loop + +// } +// } + +break_for_loop: + sub dst, dststart + + mov sp, lr // lr stores sp before 16-byte alignment + pop {r4-r8,r10-r11,pc} + + + +// return dst - dststart; +// } + +#endif // __arm__ + diff --git a/lib/lzss/arm64/lzssdec.S b/lib/lzss/arm64/lzssdec.S new file mode 100644 index 0000000..b72343c --- /dev/null +++ b/lib/lzss/arm64/lzssdec.S @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef __arm64__ + + .text + .align 2 + +#define N 4096 /* size of ring buffer - must be power of 2 */ +#define F 18 /* upper limit for match_length */ +#define THRESHOLD 2 /* encode string into position and length if match_length is greater than this */ + + .globl _decompress_lzss_vec +_decompress_lzss_vec: + +// int decompress_lzss( +// u_int8_t * dst, - x0 +// u_int32_t dstlen, - x1 never used +// u_int8_t * src, - x2 +// u_int32_t srclen) - x3 (used once to define srcend) +// { +// u_int8_t text_buf[N + F - 1]; +// u_int8_t * dststart = dst; +// const u_int8_t * srcend = src + srclen; +// int i, j, k, r, c; +// unsigned int flags; + + #define dststart x12 + #define dst x0 + #define flags w1 + #define src x2 + #define srcend x3 + #define r w4 + #define c w5 + #define i w6 + #define j w7 + #define t w8 + #define k w10 + #define text_buf sp + #define Nm1 w11 + #define spsave x9 + +// dst = dststart; + + mov spsave, sp // store sp as we need to align sp + mov dststart, dst + +// for (i = 0; i < N - F; i++) text_buf[i] = ' '; + + lsr x1, spsave, #4 // 16-byte alignment + + mov w5, #((32<<8)+32) // r5 = ' '; + lsl x1, x1, #4 // 16-byte alignment + sub sp, x1, #N // it appears that text_buf[N] is sufficient, the extra F-1 bytes is never used + add w5, w5, w5, lsl #16 // r5 = ' '; + mov x4, sp // r1 -> text_buf[0] + + mov x1, #(N-F+2) // do extra 2, so that 4080 is a multiple of 16 (255) + + dup.4s v0, w5 + +0: + st1.4s {v0}, [x4] + add x4, x4, #16 + subs x1, x1, #16 + b.gt 0b + +// r = N - F; +// flags = 0; + + + mov w4, #N + sub w11, w4, #1 // r11 = N-1, will be used for circular buffering in text_buf[r] + sub w4, w4, #F // r = N-r + mov w1, #0 // flag = 0 + + add srcend, src, x3 + +L_for_loop: + +// for ( ; ; ) { + +// if (((flags >>= 1) & 0x100) == 0) { +// if (src < srcend) c = *src++; else break; +// flags = c | 0xFF00; +// } + + lsr flags, flags, #1 // flags >>= 1 + tst flags, #0x100 // (flags >>= 1) & 0x100) + b.ne L_skip1 // if != 0, skip the following + cmp src, srcend // src vs srcend + b.ge L_break_for_loop // if (src>=srcend) break_for_loop + ldrb c,[src],#1 // c = *src++ + orr flags,c,#0x00ff00 // flags = c | 0xFF00; + +L_skip1: + +// if (flags & 1) { + tst flags, #1 + b.eq L_skip2 +// if (src < srcend) c = *src++; else break; +// *dst++ = c; +// text_buf[r++] = c; +// r &= (N - 1); + + cmp src, srcend // src vs srcend + b.ge L_break_for_loop // if (src>=srcend) break_for_loop + ldrb c,[src],#1 // c = *src++ + strb c,[text_buf,r, uxtw] // text_buf[r] + add r, r, #1 // r++ + strb c,[dst],#1 // *dst++ = c; + and r, r, Nm1 // r &= (N - 1); + b L_for_loop + +// } else { +L_skip2: +// if (src < srcend) i = *src++; else break; +// if (src < srcend) j = *src++; else break; + + ldrh i,[src],#2 // + cmp src, srcend // + lsr j, i, #8 + b.gt L_break_for_loop + sub i, i, j, lsl #8 + +// i |= ((j & 0xF0) << 4); +// j = (j & 0x0F) + THRESHOLD; + + and t, j, #0xf0 // j&0xf0 + and j, j, #0x0f // j&0x0f + orr i, i, t, lsl #4 // i |= ((j & 0xF0) << 4); + add j, j, #THRESHOLD // j = (j & 0x0F) + THRESHOLD; + +// for (k = 0; k <= j; k++) { +// c = text_buf[(i + k) & (N - 1)]; +// *dst++ = c; +// text_buf[r++] = c; +// r &= (N - 1); +// } + mov k, #0 + +0: + add t, i, k // (i+k) + and t, t, Nm1 // (i + k) & (N - 1) + ldrb c, [text_buf, t, uxtw] // c = text_buf[(i + k) & (N - 1)]; + strb c, [dst], #1 // *dst++ = c; + strb c, [text_buf, r, uxtw] // text_buf[r] = c; + add r, r, #1 // r++ + and r, r, Nm1 // r &= (N - 1); + add k, k, #1 // k++ + cmp k, j // k vs j + b.le 0b + b L_for_loop + +// } +// } + +L_break_for_loop: + sub x0, dst, dststart + + mov sp, spsave // stores sp before 16-byte alignment + + ret lr + + + +// return dst - dststart; +// } + +#endif // __arm64__ + diff --git a/lib/lzss/library.mk b/lib/lzss/library.mk new file mode 100644 index 0000000..c5adbdb --- /dev/null +++ b/lib/lzss/library.mk @@ -0,0 +1,29 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBLZSS_DIR := $(GET_LOCAL_DIR) +LIBLZSS_BUILD := $(call TOLIBDIR,$(LIBLZSS_DIR)/LIBLZSS.a) +COMMONLIBS += LIBLZSS + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBLZSS_OBJS := \ + $(LIBLZSS_DIR)/lzss.o \ + $(LIBLZSS_DIR)/$(ARCH)/lzssdec.o + +LIBLZSS_OBJS := $(call TOLIBOBJDIR,$(LIBLZSS_OBJS)) + +ALL_DEPS += $(LIBLZSS_OBJS:%o=%d) + +$(LIBLZSS_BUILD): $(LIBLZSS_OBJS) + +endif diff --git a/lib/lzss/lzss.c b/lib/lzss/lzss.c new file mode 100644 index 0000000..606e6c8 --- /dev/null +++ b/lib/lzss/lzss.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +#include +#include + +uint32_t decompress_lzss_vec(uint8_t *dst, uint32_t dstlen, const uint8_t *src, uint32_t srclen); + +#define N 4096 /* size of ring buffer - must be power of 2 */ +#define F 18 /* upper limit for match_length */ +#define THRESHOLD 2 /* encode string into position and length + if match_length is greater than this */ +#define NIL N /* index for root of binary search trees */ +#define TEXT_BUF (N + F - 1) /* size of ring buffer with F-1 extra bytes + to aid string comparison */ + +uint32_t decompress_lzss(uint8_t * __restrict dst, uint32_t dstlen, const uint8_t * __restrict src, uint32_t srclen) +{ +#if (ARCH_ARMv7 && WITH_VFP) || defined(__arm64__) +#if WITH_VFP_ALWAYS_ON + return decompress_lzss_vec(dst, dstlen, src, srclen); +#else + bool fp_enabled; + uint32_t result; + + fp_enabled = arch_task_fp_enable(true); + result = decompress_lzss_vec(dst, dstlen, src, srclen); + arch_task_fp_enable(fp_enabled); + return result; +#endif // WITH_VFP_ALWAYS_ON +#else + uint8_t *text_buf = NULL; + uint8_t *dststart = dst; + uint8_t *dstend = dst + dstlen; + const uint8_t *srcend = src + srclen; + uint32_t i, j, k, r, c; + uint32_t flags; + uint32_t result = 0; + + text_buf = (uint8_t *)malloc(TEXT_BUF); + if (text_buf == NULL) + goto error; + memset(text_buf, ' ', N - F); + + r = N - F; + flags = 0; + for ( ; ; ) { + if (((flags >>= 1) & 0x100) == 0) { + if (src < srcend) { + c = *src++; + } else { + break; + } + flags = c | 0xFF00; /* uses higher byte cleverly */ + } /* to count eight */ + if (flags & 1) { + if (src < srcend) { + c = *src++; + } else { + break; + } + if (dst == dstend) { + goto error; + } + *dst++ = c; + text_buf[r++] = c; + r &= (N - 1); + } else { + if (src < srcend) { + i = *src++; + } else { + break; + } + if (src < srcend) { + j = *src++; + } else { + break; + } + i |= ((j & 0xF0) << 4); + j = (j & 0x0F) + THRESHOLD; + for (k = 0; k <= j; k++) { + c = text_buf[(i + k) & (N - 1)]; + if (dst == dstend) { + goto error; + } + *dst++ = c; + text_buf[r++] = c; + r &= (N - 1); + } + } + } + + result = dst - dststart; + +error: + if (text_buf != NULL) + free(text_buf); + + return result; +#endif +} diff --git a/lib/lzss/rules.mk b/lib/lzss/rules.mk new file mode 100644 index 0000000..8046b3c --- /dev/null +++ b/lib/lzss/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2007, 2012-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_LZSS=1 +LIBRARY_MODULES += lib/lzss diff --git a/lib/lzss/tests.c b/lib/lzss/tests.c new file mode 100644 index 0000000..8d8e5c8 --- /dev/null +++ b/lib/lzss/tests.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include + +struct lzss_test { + const uint8_t *input; + size_t input_len; + const uint8_t *expected; + size_t expected_len; + size_t buf_len; +}; + +struct lzss_test tests[] = { + { + (const uint8_t *)&(const uint8_t[]){ 0xff, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87 }, + 9, + (const uint8_t *)&(const uint8_t[]){ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87 }, + 8, + 4096 + }, +#if 0 + { + (const uint8_t *)&(const uint8_t[]){ 0xff, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x00, 0x00, 0x00 }, + 12, + (const uint8_t *)&(const uint8_t[]){ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x80, 0x81, 0x82 }, + 11, + 4096 + } +#endif +}; + +void test_lzss(uintptr_t param) +{ + struct lzss_test *test = (struct lzss_test *)param; + uint32_t guard = 0xdeadbeef; + uint8_t *dst; + uint32_t result; + + dst = malloc(test->buf_len + sizeof(guard)); + memset(dst, 0xcc, test->buf_len); + + // If the test is expected to succeed, put a guard right + // after the last expected output byte of the buffer; if it's + // expected to fail, just put it at the end of the buffer + if (test->expected_len != 0) + memcpy(dst + test->expected_len, &guard, sizeof(guard)); + else + memcpy(dst + test->buf_len, &guard, sizeof(guard)); + + result = decompress_lzss(dst, test->buf_len, test->input, test->input_len); + TEST_ASSERT_EQ(result, test->expected_len); + + if (test->expected_len != 0) { + TEST_ASSERT_MEM_EQ(dst, test->expected, test->expected_len); + TEST_ASSERT_MEM_EQ(dst + test->expected_len, &guard, sizeof(guard)); + } else { + TEST_ASSERT_MEM_EQ(dst + test->buf_len, &guard, sizeof(guard)); + } + + free(dst); +} + +static struct test_suite lzss_test_suite = { + .name = "lzss", + .description = "tests the lzss implementation", + .test_cases = { + { "lzss", test_lzss, (uintptr_t)&tests[0] }, +#if 0 + { "lzss", test_lzss, (uintptr_t)&tests[1] }, +#endif + TEST_CASE_LAST + } +}; + +TEST_SUITE(lzss_test_suite); diff --git a/lib/lzss/tests.mk b/lib/lzss/tests.mk new file mode 100644 index 0000000..be614eb --- /dev/null +++ b/lib/lzss/tests.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := lzss + +TEST_OBJS := \ + $(LOCAL_DIR)/lzss.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o diff --git a/lib/macho/boot.h b/lib/macho/boot.h new file mode 100644 index 0000000..13d6558 --- /dev/null +++ b/lib/macho/boot.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Taken from pexpert/pexpert/arm/boot.h and pexpert/pexpert/arm64/boot.h +// Modified for iBoot: +// - Fixed incosistent naming in boot-args struct +// - Added monitor_boot_args + +/* + * Copyright (c) 2007-2009 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _PEXPERT_ARM_BOOT_H_ +#define _PEXPERT_ARM_BOOT_H_ + +//#include + +#define BOOT_LINE_LENGTH 256 + +/* + * Video information.. + */ + +struct boot_video { + unsigned long v_baseAddr; /* Base address of video memory */ + unsigned long v_display; /* Display Code (if Applicable */ + unsigned long v_rowBytes; /* Number of bytes per pixel row */ + unsigned long v_width; /* Width */ + unsigned long v_height; /* Height */ + unsigned long v_depth; /* Pixel Depth and other parameters */ +}; + +#define kBootVideoDepthMask (0xFF) +#define kBootVideoDepthDepthShift (0) +#define kBootVideoDepthRotateShift (8) +#define kBootVideoDepthScaleShift (16) + +typedef struct boot_video boot_video; + +/* Boot argument structure - passed into Mach kernel at boot time. + */ +#define kBootArgsRevision 2 +#define kBootArgsVersion1 1 +#define kBootArgsVersion2 2 + +#define kBootFlagDarkBoot 1 + +#if defined(__LP64__) +typedef struct boot_args { + uint16_t revision; /* Revision of boot_args structure */ + uint16_t version; /* Version of boot_args structure */ + uint64_t virtBase; /* Virtual base of memory */ + uint64_t physBase; /* Physical base of memory */ + uint64_t memSize; /* Size of memory */ + uint64_t topOfKernelData; /* Highest physical address used in kernel data area */ + boot_video video; /* Video Information */ + uint32_t machineType; /* Machine Type */ + void *deviceTreeP; /* Base of flattened device tree */ + uint32_t deviceTreeLength; /* Length of flattened tree */ + char commandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ + uint64_t boot_flags; /* Misc boot flags*/ +} boot_args; +#else +typedef struct boot_args { + uint16_t revision; /* Revision of boot_args structure */ + uint16_t version; /* Version of boot_args structure */ + uint32_t virtBase; /* Virtual base of memory */ + uint32_t physBase; /* Physical base of memory */ + uint32_t memSize; /* Size of memory */ + uint32_t topOfKernelData; /* Highest physical address used in kernel data area */ + boot_video video; /* Video Information */ + uint32_t machineType; /* Machine Type */ + void *deviceTreeP; /* Base of flattened device tree */ + uint32_t deviceTreeLength; /* Length of flattened tree */ + char commandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ + uint32_t boot_flags; /* Misc boot flags*/ +} boot_args; +#endif + +#define SOC_DEVICE_TYPE_BUFFER_SIZE 32 + +#define PC_TRACE_BUF_SIZE 1024 + +/* + * Monitor/hypervisor boot argument structure. + */ +#if defined(__LP64__) +typedef struct monitor_boot_args { + uint64_t version; /* structure version - this is version 2 */ + uint64_t virtBase; /* virtual base of memory assigned to the monitor */ + uint64_t physBase; /* physical address corresponding to the virtual base */ + uint64_t memSize; /* size of memory assigned to the monitor */ + uint64_t kernArgs; /* physical address of the kernel boot_args structure */ + uint64_t kernEntry; /* kernel entrypoint */ + uint64_t kernPhysBase; /* physical base of the kernel's address space */ + uint64_t kernPhysSlide; /* offset from kernPhysBase to kernel load address */ + uint64_t kernVirtSlide; /* virtual slide applied to kernel at load time */ +} monitor_boot_args; +#else +typedef struct monitor_boot_args { + uint32_t version; /* structure version - this is version 2 */ + uint32_t virtBase; /* virtual base of memory assigned to the monitor */ + uint32_t physBase; /* physical address corresponding to the virtual base */ + uint32_t memSize; /* size of memory assigned to the monitor */ + uint32_t kernArgs; /* physical address of the kernel boot_args structure */ + uint32_t kernEntry; /* kernel entrypoint */ + uint32_t kernPhysBase; /* physical base of the kernel's address space */ + uint32_t kernPhysSlide; /* offset from kernPhysBase to kernel load address */ + uint32_t kernVirtSlide; /* virtual slide applied to kernel at load time */ +} monitor_boot_args; +#endif + +#endif /* _PEXPERT_ARM_BOOT_H_ */ diff --git a/lib/macho/dt.c b/lib/macho/dt.c new file mode 100644 index 0000000..99215b5 --- /dev/null +++ b/lib/macho/dt.c @@ -0,0 +1,874 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * Copyright (C) 1998-2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#if WITH_HW_GASGAUGE +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_TICKET +#include +#endif +#include +#include +#include +#include +#include +#if WITH_CONSISTENT_DBG +#include +#endif + +extern bool contains_boot_arg(const char *bootArgs, const char *arg, bool prefixmatch); + +#include "boot.h" + +#define kBootPResponceSize (0x12C) +static char gBootPResponse[kBootPResponceSize]; + +#define ROOT_DTPATH "" + +#ifndef ETHERNET_DTPATH +#define ETHERNET_DTPATH "ethernet" +#endif + +#ifndef MULTITOUCH_DTPATH +#define MULTITOUCH_DTPATH "" +#endif + +#ifndef WIFI_DTPATH +#define WIFI_DTPATH "arm-io/sdio" +#endif + +#ifndef PINTO_DTPATH +#define PINTO_DTPATH "" +#endif + +#ifndef BT_DTPATH +#define BT_DTPATH "arm-io/uart3/bluetooth" +#endif +#ifndef BASEBAND_DTPATH +#define BASEBAND_DTPATH "baseband" +#endif + +#ifndef CHARGER_DTPATH +#define CHARGER_DTPATH "charger" +#endif + +#ifndef USBDEVICE_DTPATH +#define USBDEVICE_DTPATH "arm-io/usb-complex/usb-device" +#endif + +int UpdateDeviceTree(const boot_args *boot_args) +{ + DTNodePtr node, chosen; + uint32_t propSize, boot_partition; + char *propName; + void *propData; + const char *str; + int result, noenet = 0; + uint32_t ipaddr; + uint8_t ethaddr[6]; + void *wifiaddr; + const char *dram_vendor_string; + const char *product_id; +#if WITH_SYSCFG + void *batteryId = NULL; + uint32_t batteryIdSize = 0; +#endif + +#if WITH_SYSCFG + // Put the model number in the root node + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "model-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('Mod#', propData, propSize); + } + } + + // Put the regulatory model number in the root node + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "regulatory-model-number"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (syscfgCopyDataForTag('RMd#', propData, propSize) == -1 && ((char *)propData)[0] == 0) + propName[0] = '~'; + } + + // Put the region info in the root node + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "region-info"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('Regn', propData, propSize); + } + } + + // Put the serial number in the root node + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SrNm', propData, propSize); + } + } + + // Put the mlb serial number in the root node + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "mlb-serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('MLB#', propData, propSize); + } + } + + // Put the config number in the root node + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "config-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CFG#', propData, propSize); + } + } + +#endif + + // Find the pram node + if (FindNode(0, "pram", &node)) { + // Fill in the memory range + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uintptr_t *)propData)[0] = platform_get_memory_region_base(kMemoryRegion_Panic); + ((uintptr_t *)propData)[1] = platform_get_memory_region_size(kMemoryRegion_Panic); + } + } + + // Find the vram node + if (FindNode(0, "vram", &node)) { + // Fill in the memory range + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uintptr_t *)propData)[0] = platform_get_memory_region_base(kMemoryRegion_Display); + ((uintptr_t *)propData)[1] = platform_get_memory_region_size(kMemoryRegion_Display); + } + } + +#if defined(SLEEP_TOKEN_BUFFER_BASE) && defined(SLEEP_TOKEN_BUFFER_SIZE) + // Find the stram (sleep-token ram) node + if (FindNode(0, "stram", &node)) { + // Fill in the memory range + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uintptr_t *)propData)[0] = platform_get_memory_region_base(kMemoryRegion_SleepToken); + ((uintptr_t *)propData)[1] = platform_get_memory_region_size(kMemoryRegion_SleepToken); + } + } +#endif + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + dt_set_prop_32(node, "chip-revision", platform_get_chip_revision()); + dt_set_prop_32(node, "fuse-revision", platform_get_fuse_revision()); + } + + if (FindNode(0, "product", &node)) { + propName = "product-id"; + if (FindProperty(node, &propName, &propData, &propSize)) { + product_id = platform_get_product_id(); + memcpy(propData, product_id, propSize); + } + +#if WITH_SYSCFG + propName = "device-color-legacy"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + + propName = "primary-calibration-matrix"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('DPCl', propData, propSize); + + uint32_t *data_ptr = (uint32_t*)propData; + if (data_ptr[0] == 0x01000000) { + for(uint32_t i = 0; i < ((uint32_t)propSize / sizeof(uint32_t)); i ++) { + data_ptr[i] = swap32(data_ptr[i]); + } + } + } + +#if WITH_PAINT + propName = "device-colors"; + if (FindProperty(node, &propName, &propData, &propSize)) { + paint_color_map_get_DClr((syscfg_DClr_t *)propData, propSize, false); + } + propName = "device-color-policy"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize == sizeof(uint32_t)) { + *(uint32_t *)propData = paint_get_color_policy(); + } + } +#endif +#endif + } + + str = env_get("network-type"); + if (str && strcmp(str, "ethernet")) noenet = 1; + + // Find the chosen node. + if (!FindNode(0, "chosen", &chosen)) { + printf("UpdateDeviceTree: failed to find the /chosen node\n"); + return -1; + } + +#if WITH_NVRAM + // race condition possible between + // IODTNVRAM and IONVRAMController (restore loses boot-args) + nvram_update_devicetree(chosen, "nvram-proxy-data"); +#endif + + // Fill in the debug-enabled property + propName = "debug-enabled"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (security_allow_modes(kSecurityModeKDPEnabled)) { + ((uint32_t *)propData)[0] = 1; + } + } + +#if WITH_CONSISTENT_DBG + // Fill in the consistent-debug-root property + propName = "consistent-debug-root"; + if(FindProperty(chosen, &propName, &propData, &propSize)) + { + *(uint64_t*)propData = (uint64_t)(consistent_debug_get_registry()); + } +#endif + + // Fill in the development-cert property + propName = "development-cert"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (security_allow_modes(kSecurityModeDevCertAccess)) { + ((uint32_t *)propData)[0] = 1; + } + } + + // Fill in the production-cert property + propName = "production-cert"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (security_allow_modes(kSecurityModeProdCertAccess)) { + ((uint32_t *)propData)[0] = 1; + } + } + + // Fill in the gid-aes-key property + propName = "gid-aes-key"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (security_allow_modes(kSecurityModeGIDKeyAccess)) { + ((uint32_t *)propData)[0] = 1; + } + } + + // Fill in the uid-aes-key property + propName = "uid-aes-key"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (security_allow_modes(kSecurityModeUIDKeyAccess)) { + ((uint32_t *)propData)[0] = 1; + } + } + + // Fill in the secure-boot property + propName = "secure-boot"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (security_allow_modes(kSecurityStatusSecureBoot)) { + ((uint32_t *)propData)[0] = 1; + } + } + + // Fill in the certificate-production-status (raw production mode) property + propName = "certificate-production-status"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = platform_get_raw_production_mode(); + } + + // Fill in the certificate-security-mode (raw security mode) property + propName = "certificate-security-mode"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = platform_get_secure_mode(); + } + + // Fill in the effective-production-status-ap property + propName = "effective-production-status-ap"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = platform_get_current_production_mode(); + } + + // Fill in the effective-security-mode-ap property + // This is for legacy reasons. As far as the AP is concerned, its effective security mode + // doesn't change with demotion + // Get rid of effective-security-mode-ap device tree property + propName = "effective-security-mode-ap"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = platform_get_secure_mode(); + } + +#if WITH_IMAGE4 + // Fill in the boot-nonce property + propName = "boot-nonce"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + uint64_t boot_nonce = platform_get_nonce(); + memcpy(propData, &boot_nonce, propSize); + } +#endif + + // Fill in the memory vendor info + propName = "dram-vendor"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + dram_vendor_string = platform_get_memory_manufacturer_string(); + strlcpy(propData, dram_vendor_string, propSize); + } + +#if WITH_SYSCFG + // Fill in the software-behavior property + propName = "software-behavior"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SwBh', propData, propSize); + } + + // Fill in the software-bundle-version property + propName = "software-bundle-version"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SBVr', propData, propSize); + } +#endif + + // Fill in the system-trusted property + propName = "system-trusted"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (security_allow_modes(kSecurityStatusSystemTrusted)) { + ((uint32_t *)propData)[0] = 1; + } + } + + // Fill in the board-id property + propName = "board-id"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = platform_get_board_id(); + } + + // Fill in the chip-id property + propName = "chip-id"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = platform_get_chip_id(); + } + + // Fill in the unique-chip-id property + propName = "unique-chip-id"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint64_t *)propData)[0] = platform_get_ecid_id(); + } + + // Fill in the die-id property + propName = "die-id"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint64_t *)propData)[0] = platform_get_die_id(); + } + + // Fill in the random-seed property + propName = "random-seed"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + random_get_bytes(propData, propSize); + } + + // Fill in the firmware-version + propName = "firmware-version"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + strlcpy(propData, XBS_BUILD_TAG, propSize); + } + +#if WITH_TICKET + // Fill in the root-ticket-hash property + propName = "root-ticket-hash"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + uint8_t hash[CCSHA1_OUTPUT_SIZE]; + if (propSize >= sizeof(hash) && ticket_get_hash(hash, sizeof(hash))) { + memcpy(propData, hash, sizeof(hash)); + } + } +#endif + +#if WITH_IMAGE4 + { + uint8_t boot_manifest_hash[HASH_OUTPUT_SIZE]; + + propName = "boot-manifest-hash"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + if (platform_get_boot_manifest_hash(boot_manifest_hash) == 0) { + // Fill in the boot-manifest-hash property + if (propSize >= sizeof(boot_manifest_hash)) { + memcpy(propData, boot_manifest_hash, sizeof(boot_manifest_hash)); + } else { + panic("%s property is too small", propName); + } + } + else { + // Rename the boot-manifest-hash property to mark it invalid + propName[0] = '~'; + } + } + } + + // Fill in the mix-n-match-prevention-status property + propName = "mix-n-match-prevention-status"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = platform_get_mix_n_match_prevention_status(); + } +#endif + + // Fill in the display-rotation + propName = "display-rotation"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = ((boot_args->video.v_depth >> 8) & 0xFF) * 90; + } + + // Fill in the display-rotation + propName = "display-scale"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = ((boot_args->video.v_depth >> 16) & 0xFF) + 1; + } + + // Fill in the bootp-response packet + propName = "bootp-response"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + *gBootPResponse = 2; + + ipaddr = 0; + env_get_ipaddr("ipaddr", &ipaddr); + memcpy(gBootPResponse + 0x10, &ipaddr, 4); + if (env_get("gateway")) { + env_get_ipaddr("gateway", &ipaddr); + memcpy(gBootPResponse + 236, "\143\202\123\143", 4); //dhcp magic cookie + memcpy(gBootPResponse + 236 + 4, "\003\004", 1 + 1); //dhcp tag=3(gateway), len = 4 + memcpy(gBootPResponse + 236 + 6, &ipaddr, 4); //dhcp gateway ip + } + + memcpy(propData, gBootPResponse, kBootPResponceSize); + } + + dt_set_prop_32(chosen, "security-domain", platform_get_security_domain()); + dt_set_prop_32(chosen, "chip-epoch", platform_get_hardware_epoch()); + + // tell the kernel which partition to root off of, unless the user was explicit + if (!contains_boot_arg(boot_args->commandLine, "rd=", true)) { + propName = "root-matching"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { +#if RELEASE_BUILD + boot_partition = 1; +#else + boot_partition = env_get_uint("boot-partition", 0) + 1; +#endif + boot_partition = + // default to the same logic as what is used for loading + // the kernelcache, even if the user loaded that over usb. + // The IOStorageFamily uses 1-indexed partitions + snprintf(propData, propSize, + "IOProviderClassIOMediaIOPropertyMatchPartition ID%u", + boot_partition); + } + } + +#if defined(ASP_BASE) && defined(ASP_SIZE) + // Update ASP region info + if (FindNode(0, "arm-io/ans/iop-ans-nub", &node)) { + propName = "region-base"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uintptr_t *) propData)[0] = platform_get_memory_region_base(kMemoryRegion_StorageProcessor); + } + propName = "region-size"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uintptr_t *) propData)[0] = platform_get_memory_region_size(kMemoryRegion_StorageProcessor); + } + } +#endif + + // Add the platform name to the root node + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "platform-name"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, PLATFORM_NAME_STRING, propSize); + } + } + + // Populate consistent location in device tree with mac addresses for Gestalt + if (FindNode(0, "chosen", &node)) { + propName = "mac-address-ethernet0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("ethaddr")) { + env_get_ethaddr("ethaddr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_ETH_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + + propName = "mac-address-wifi0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("wifiaddr")) { + env_get_ethaddr("wifiaddr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_WIFI_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + + propName = "mac-address-bluetooth0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("btaddr")) { + env_get_ethaddr("btaddr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_BT_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + // Set the ethernet address in "/" + memset(ethaddr, 0, sizeof(ethaddr)); + if (env_get("ethaddr")) { + env_get_ethaddr("ethaddr", ethaddr); + } else { + int retlen = 0; + target_get_property(TARGET_PROPERTY_ETH_MACADDR, ethaddr, 6, &retlen); + } + + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "local-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, ethaddr, 6); + } + } + + // Set the ethernet address is ETHERNET_DTPATH + if (FindNode(0, ETHERNET_DTPATH, &node)) { + propName = "local-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, ethaddr, 6); + if (noenet) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "xxx", propSize); + printf("Ethernet disabled\n"); + } + } + } + } + // store enet mac-address into 'device-mac-address' in 'usb-device' node for tethering + else if (FindNode(0, USBDEVICE_DTPATH, &node)) { + propName = "device-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, ethaddr, 6); + } + } + + // Set the wifi address/calibration in the wifi node (SDIO or HSIC) + if (FindNode(0, WIFI_DTPATH, &node)) { + DTNodePtr usb_node; + propName = "local-mac-address"; + if (FindProperty(node, &propName, &wifiaddr, &propSize)) { + if (env_get("wifiaddr")) { + env_get_ethaddr("wifiaddr", wifiaddr); + } else { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_MACADDR, wifiaddr, 6, &retlen); + } + // store 'wifiaddr' into 'host-mac-address' in 'usb-device' node for tethering + if (FindNode(0, USBDEVICE_DTPATH, &usb_node)) { + propName = "host-mac-address"; + if (FindProperty(usb_node, &propName, &propData, &propSize)) { + memcpy(propData, wifiaddr, 6); + } + } + } + + propName = "tx-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_CALIBRATION_TX, propData, 1024, &retlen); + } + + propName = "tx-calibration-2.4"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_CALIBRATION_TX_24, propData, propSize, &retlen); + } + + propName = "tx-calibration-5.0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_CALIBRATION_TX_50, propData, propSize, &retlen); + } + + propName = "rx-calibration-2.4"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_CALIBRATION_RX_24, propData, propSize, &retlen); + } + + propName = "rx-calibration-5.0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_CALIBRATION_RX_50, propData, propSize, &retlen); + } + + propName = "rx-calibration-temp"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_CALIBRATION_RX_TEMP, propData, propSize, &retlen); + } + + propName = "freq-group-2g-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_CALIBRATION_FREQ_GROUP_2G, propData, propSize, &retlen); + } + + propName = "wireless-board-snum"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_BOARD_SNUM, propData, propSize, &retlen); + } + + propName = "wifi-calibration-msf"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_WIFI_WCAL, propData, propSize, &retlen); + } + } + + if (FindNode(0, BT_DTPATH, &node)) { + // Set the bt address in the bluetooth node + propName = "local-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("btaddr")) { + env_get_ethaddr("btaddr", propData); + } else { + int retlen = 0; + target_get_property(TARGET_PROPERTY_BT_MACADDR, propData, 6, &retlen); + } + } + +#if WITH_SYSCFG + // Update Bluetooth TX and RX calibration data. If calibration data is + // missing, don't publish these properties. + propName = "bluetooth-tx-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (syscfgCopyDataForTag('BTTx', propData, propSize) == -1) + propName[0] = '~'; + + propName = "bluetooth-rx-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + if (syscfgCopyDataForTag('BTRx', propData, propSize) == -1) + propName[0] = '~'; +#endif + } + + //Fill Pinto address + if (FindNode(0, PINTO_DTPATH, &node)) { + // Set the pinto address in the corresponding node + propName = "local-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("pintoaddr")) { + env_get_ethaddr("pintoaddr", propData); + } else { + int retlen = 0; + target_get_property(TARGET_PROPERTY_PINTO_MACADDR, propData, 6, &retlen); + } + } + } + + // Fill in baseband properties as necessary (don't qualify this with presence of the + // radio driver since there may be work to do regardless) + if (FindNode(0, BASEBAND_DTPATH, &node)) { +#if WITH_SYSCFG + propName = "battery-id"; + if (FindProperty(node, &propName, &propData, &propSize)) { +#if WITH_HW_GASGAUGE + if (gasgauge_get_battery_id(propData, propSize) == 0) { + batteryId = propData; + batteryIdSize = propSize; + } + else +#endif + { + syscfgCopyDataForTag('Batt', propData, propSize); + } + } +#endif + + propName = "region-sku"; + if (FindProperty(node, &propName, &propData, &propSize)) { + int retlen = 0; + target_get_property(TARGET_PROPERTY_BB_REGION_SKU, propData, propSize, &retlen); + } + } + + // Put the battery-id, boot-voltage in the charger node + if (FindNode(0, CHARGER_DTPATH, &node)) { +#if WITH_SYSCFG + propName = "battery-id"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if ((batteryId != NULL) && (propSize == batteryIdSize)) { + memcpy(propData, batteryId, propSize); + } +#if WITH_HW_GASGAUGE + else if (gasgauge_get_battery_id(propData, propSize) != 0) +#endif + { + syscfgCopyDataForTag('Batt', propData, propSize); + } + } +#endif + +#if WITH_HW_POWER + propName = "boot-voltage"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = power_get_boot_battery_level(); + } + + propName = "boot-adapter-id"; + if (FindProperty(node, &propName, &propData, &propSize)) { + power_get_usb_brick_id((uint32_t *)propData, propSize / sizeof(uint32_t)); + } +#endif + } + +#if WITH_HW_MERLOT + // Set the lcd panel info in the merlot node + if (FindNode(0, MERLOT_DTPATH, &node)) { + extern const uint32_t gMerlotPanelID, gMerlotInitRegisterCount; + extern const uint8_t *gMerlotInitRegisters; + + propName = "lcd-panel-id"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = gMerlotPanelID; + } + propName = "lcd-init-register-count"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = gMerlotInitRegisterCount; + } + propName = "lcd-init-registers"; + if ((gMerlotInitRegisters != 0) && FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, gMerlotInitRegisters, gMerlotInitRegisterCount * 2); + } + } +#endif + +#if WITH_SYSCFG + // Save the multi-touch calibration + if (FindNode(0, MULTITOUCH_DTPATH, &node)) { + propName = "multi-touch-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('MtCl', propData, propSize); + } + } + + uint32_t sysCfgData = 0; + // Obtain the syscfg entry that identifies when a rear camera is absent + result = syscfgCopyDataForTag('NoBC', (uint8_t *)(&sysCfgData), sizeof(sysCfgData)); + + // Set rear camera information + if (FindNode(0, "arm-io/isp", &node)) { + propName = "camera-rear"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // if bit 0 is 1, then delete rear camera entry + if (result == sizeof(sysCfgData) && (sysCfgData & 0x1)) + propName[0] = '~'; + } + } + + // Also delete rear camera related properties in product/camera if rear camera is absent + if (FindNode(0, "product/camera", &node)) { + + if (result == sizeof(sysCfgData) && (sysCfgData & 0x1)) { + propName = "flash"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + + propName = "rear-burst"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + + propName = "rear-slowmo"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + + propName = "rear-max-video-zoom"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + + propName = "rear-hdr"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + + propName = "panorama"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + + propName = "rear-auto-hdr"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + } + + } + +#endif + + // Let the platform and target make updates + result = platform_update_device_tree(); + if (result < 0) return result; + + // Find the iBoot node under the chosen direectory + // as that's where the boot specific stuff goes. + if (FindNode(0, "chosen/iBoot", &node)) { + // Fill in the boot performance information + extern const uint32_t gPowerOnTime; + extern const uint32_t gDebugPromptTime; + extern const uint32_t gLoadKernelTime; + const uint32_t populateRegistryTime = system_time(); + + propName = "start-time"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = gPowerOnTime; + } + propName = "debug-wait-start"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = gDebugPromptTime; + } + propName = "load-kernel-start"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = gLoadKernelTime; + } + propName = "populate-registry-time"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = populateRegistryTime; + } + } + + return 0; +} diff --git a/lib/macho/kernelcache.c b/lib/macho/kernelcache.c new file mode 100644 index 0000000..5b45abf --- /dev/null +++ b/lib/macho/kernelcache.c @@ -0,0 +1,793 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * Copyright (C) 1998-2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "boot.h" +#include "macho_header.h" + +#if __arm64__ +#define L2_GRANULE (PAGE_SIZE * (PAGE_SIZE / 8)) +#define L2_GRANULE_MASK (L2_GRANULE - 1) +#endif + +#if !WITH_MONITOR +addr_t gKernelEntry; // Kernel entry point +#endif + +/* From dt.c */ +extern int UpdateDeviceTree(const boot_args *boot_args); + +/* From lib/ramdisk/ramdisk.c */ +extern addr_t gRAMDiskAddr; +extern size_t gRAMDiskSize; + +struct compressed_kernel_header { + uint32_t signature; + uint32_t compress_type; + uint32_t adler32; + uint32_t uncompressed_size; + uint32_t compressed_size; + uint32_t reserved[11]; + uint8_t platform_name[64]; + uint8_t root_path[256]; + uint8_t data[]; +}; +typedef struct compressed_kernel_header compressed_kernel_header; + +static int loaded_kernelcache(addr_t secure_addr, size_t secure_size, addr_t *entry, addr_t *boot_args_out); +static int valid_kernelcache(addr_t addr, size_t size); +static size_t decompress_kernelcache(addr_t addr, size_t maxsize); +static addr_t load_kernelcache_object(addr_t addr, size_t size, addr_t *boot_args_out); +static int valid_monitor(addr_t addr, size_t size, addr_t *monitor_addr, size_t *monitor_size); +static void record_kernelcache_segments(addr_t addr, addr_t phys_base); +static void record_kernelcache_segment(addr_t segCmd, addr_t phys_base, addr_t *virt_base); +static bool record_memory_range(char *rangeName, addr_t start, size_t length); +static addr_t alloc_kernel_mem(size_t size); +static void init_kernel_mem_allocator(void); +static addr_t kern_to_phys(addr_t vmaddr, boot_args *boot_args); +static int load_and_set_device_tree(void); + +int +load_kernelcache(addr_t addr, size_t len, uint32_t type, addr_t *entry, addr_t *boot_args_out) +{ + addr_t secure_addr; + size_t secure_size; + + if (len > DEFAULT_KERNEL_SIZE) { + printf("Kernelcache too large\n"); + return -2; + } + + secure_addr = DEFAULT_KERNEL_ADDRESS; + secure_size = DEFAULT_KERNEL_SIZE; + + if (image_load_memory(addr, len, &secure_addr, &secure_size, &type, 1, NULL, 0)) { + printf("Kernelcache image not valid\n"); + return -3; + } + + return(loaded_kernelcache(secure_addr, secure_size, entry, boot_args_out)); +} + +#if WITH_FS +int +load_kernelcache_file(const char *path, uint32_t type, addr_t *entry, addr_t *boot_args_out) +{ + addr_t secure_addr; + size_t secure_size; + + /* + * We could stat the file here to perform a size check, but the load-from-disk + * case is less likely to have an accidentally-oversize kernelcache. + */ + + secure_addr = DEFAULT_KERNEL_ADDRESS; + secure_size = DEFAULT_KERNEL_SIZE; + + PROFILE_ENTER('ILF'); + if (image_load_file(path, &secure_addr, &secure_size, &type, 1, NULL, 0)) { + printf("Kernelcache image not valid\n"); + return -3; + } + PROFILE_EXIT('ILF'); + + return(loaded_kernelcache(secure_addr, secure_size, entry, boot_args_out)); +} +#endif /* WITH_FS */ + +int load_kernelcache_image(struct image_info *image, uint32_t type, addr_t *entry, addr_t *boot_args_out) +{ + addr_t secure_addr; + size_t secure_size; + + secure_addr = DEFAULT_KERNEL_ADDRESS; + secure_size = DEFAULT_KERNEL_SIZE; + + if (image_load(image, &type, 1, NULL, (void **)&secure_addr, &secure_size)) { + printf("Kernelcache image not valid\n"); + return -3; + } + + return(loaded_kernelcache(secure_addr, secure_size, entry, boot_args_out)); +} + + +static int +loaded_kernelcache(addr_t secure_addr, size_t secure_size, addr_t *entry, addr_t *boot_args_out) +{ + addr_t addr; +#if WITH_MONITOR + addr_t monitor_addr; + size_t monitor_size; +#endif + + /* consolidate environment */ + security_consolidate_environment(); + + /* Load and setup devicetree. This needs to happen here to retrieve information regarding + * monitor memory + */ + if (load_and_set_device_tree() != 0) { + printf("Failed to setup devicetree \n"); + return -4; + } + +#if WITH_MONITOR + /* Find total kernelcache file size from compressed header, and look for monitor at the end. + * If theres a monitor, load it now, then load kernelcache + */ + if (valid_monitor(secure_addr, secure_size, &monitor_addr, &monitor_size) != 0) { + load_monitor_image(monitor_addr, monitor_size); + } +#endif + + if (!valid_kernelcache(secure_addr, secure_size)) + return -4; + + PROFILE_ENTER('DKc'); + secure_size = decompress_kernelcache(secure_addr, DEFAULT_KERNEL_SIZE); + if (secure_size == 0) + return -5; + PROFILE_EXIT('DKc'); + + if (!macho_valid(secure_addr)) + return -6; + + security_protect_memory(0, 0, true); + + PROFILE_ENTER('LKO'); + addr = load_kernelcache_object(secure_addr, secure_size, boot_args_out); + PROFILE_EXIT('LKO'); + if (addr == 0) { + /* Re-init security and clear devicetree, ramdisk */ + security_init(true); + + return -7; + } + + *entry = addr; + + return 0; +} + +static int +valid_kernelcache(addr_t addr, size_t size) +{ + compressed_kernel_header *kernel_header; + + kernel_header = (compressed_kernel_header *)addr; + if (ntohl(kernel_header->signature) != 'comp') + return 0; + + return 1; +} + +static size_t +decompress_kernelcache(addr_t addr, size_t maxsize) +{ + compressed_kernel_header *kernel_header; + size_t tmp_size, comp_size, uncomp_size; + uint8_t *uncomp_buffer, *comp_buffer = NULL; + uint32_t kernel_adler32; + size_t result = 0; + + kernel_header = (compressed_kernel_header *)(addr); + if (ntohl(kernel_header->signature) != 'comp') { + dprintf(DEBUG_CRITICAL, "unknown kernelcache signature\n"); + goto exit; + } + + if (ntohl(kernel_header->compress_type) != 'lzss') { + dprintf(DEBUG_CRITICAL, "unknown kernelcache compression type\n"); + goto exit; + } + + dprintf(DEBUG_CRITICAL, "Loading kernel cache at %p\n", (void *)addr); + + // For now, ignore platform name and root path + + // Save the adler32 checksum for the kernel cache + kernel_adler32 = ntohl(kernel_header->adler32); + + // Ensure that the uncompressed kernel cache is not too large + uncomp_size = ntohl(kernel_header->uncompressed_size); + if (uncomp_size > maxsize) { + dprintf(DEBUG_CRITICAL, "Uncompressed size too large: 0x%08lx, max 0x%08lx\n", uncomp_size, maxsize); + goto exit; + } + uncomp_buffer = (uint8_t *)addr; + + // Allocate buffer for the compressed kernel cache + comp_size = ntohl(kernel_header->compressed_size); + comp_buffer = malloc(comp_size); + + // Copy the compressed kernel cache to the new buffer + memcpy(comp_buffer, &kernel_header->data[0], comp_size); + + tmp_size = decompress_lzss(uncomp_buffer, maxsize, comp_buffer, comp_size); + if (tmp_size != uncomp_size) { + dprintf(DEBUG_CRITICAL, "Size mismatch from lzss 0x%08lx, should be 0x%08lx\n", tmp_size, uncomp_size); + goto exit; + } + + if (kernel_adler32 != adler32(uncomp_buffer, uncomp_size)) { + dprintf(DEBUG_CRITICAL, "Adler32 mismatch\n"); + goto exit; + } + + dprintf(DEBUG_CRITICAL, "Uncompressed kernel cache at %p\n", uncomp_buffer); + + result = uncomp_size; + +exit: + // Zero and free the buffer for the compressed kernel cache + if (comp_buffer != 0) { + memset(comp_buffer, 0, comp_size); + free(comp_buffer); + } + + return result; +} + +static int +valid_monitor(addr_t addr, size_t size, addr_t *monitor_addr, size_t *monitor_size) +{ + compressed_kernel_header *kernel_header; + size_t kernel_size; + + *monitor_addr = 0; + *monitor_size = 0; + + kernel_header = (compressed_kernel_header *)addr; + if (ntohl(kernel_header->signature) != 'comp') + return 0; + + kernel_size = ntohl(kernel_header->compressed_size) + sizeof(compressed_kernel_header); + + if (size > kernel_size) { + if (!macho_valid(addr + kernel_size)) { + return 0; + } + + *monitor_addr = addr + kernel_size; + *monitor_size = (size - kernel_size); + + return 1; + } + + return 0; +} + +static int +load_and_set_device_tree(void) +{ + /* Load device-tree here. We need to know size of certain memory regions at this point. + * Example: tz1 region to load monitor + */ + if (dt_load() != 0) { + dprintf(DEBUG_CRITICAL, "failed to load device tree\n"); + return -1; + } + + return 0; +} + +/* + * tokenize the string based on whitespace and look for + * each token to have the specified value/prefix + * + * XXX In general, using this function is an admission + * that you haven't architected things correctly. + * boot-args should normally NOT BE USED for + * communication with anything other than the very + * early stages of the kernel startup process. + * For all other applications, use the DeviceTree. + * + * XXX This is also not terribly well implemented. The + * search can be phrased as a substring search for + * prefixmatch ? " " : " " + * removing much of the manual token scanning. + */ +bool +contains_boot_arg(const char *bootArgs, + const char *arg, + bool prefixmatch) +{ + const char *pos = bootArgs; + size_t tokenlen; + size_t arglen = strlen(arg); + + while (*pos) { + // skip leading whitespace + while (*pos && *pos == ' ') { + pos++; + } + + if (*pos == '\0') { + // got to the end of the string, this arg isn't present + return false; + } + + tokenlen = 0; + while (pos[tokenlen] != '\0' && pos[tokenlen] != ' ') { + tokenlen++; + } + + // the current token may end at a space or the end of the buffer, + // so don't dereference past it + + if (tokenlen >= arglen) { + if (prefixmatch && strncmp(pos, arg, arglen) == 0) { + return true; + } else if (strncmp(pos, arg, tokenlen) == 0) { + return true; + } + } + + pos += tokenlen; + } + + return false; +} + +void update_display_info(boot_args *boot_args) +{ + struct display_info info; + + memset(&info, 0, sizeof(info)); + display_get_info(&info); + + boot_args->video.v_rowBytes = info.stride; + boot_args->video.v_width = info.width; + boot_args->video.v_height = info.height; + boot_args->video.v_depth = info.depth; + boot_args->video.v_baseAddr = (addr_t)info.framebuffer; + boot_args->video.v_display = 1; +} + +static size_t +get_kaslr_random(const char *env_var) +{ + size_t value; + +#if DEBUG_BUILD + // Debug builds can also specify a specific slide for debug reasons + value = env_get_uint(env_var, (size_t)-1); + if (value != (size_t)-1) { + printf("got static value 0x%08lx for %s\n", value, env_var); + return value; + } +#endif + random_get_bytes((void *)&value, sizeof(value)); + + return value; +} + +static void +get_kaslr_slides(uintptr_t kernel_phys_base, size_t kernel_size, size_t *physical_slide_out, size_t *virtual_slide_out) +{ + bool kaslr_off = false; + size_t slide_phys = 0; + size_t slide_virt = 0; + +#if !RELEASE_BUILD + // Non-release builds can disable ASLR for debug reasons + kaslr_off = env_get_bool("kaslr-off", false); +#endif + +#if PAGE_SIZE != 16384 + if (!kaslr_off) { + size_t random_value = get_kaslr_random("kaslr-slide") & 0xff; + if (random_value == 0) + random_value = 0x100; + slide_virt = 0x1000000 + (random_value << 21); + } else { + slide_virt = 0; + } + slide_phys = 0; +#else +#if DEFAULT_KERNEL_SIZE + L2_GRANULE > DEFAULT_LOAD_SIZE +#error "kernelcache loader needs extra space to do physical kernel slide" +#endif + const size_t slide_granule = (1 << 21); + const size_t slide_granule_mask = slide_granule - 1; + const size_t slide_virt_max = 0x100 * (2*1024*1024); + + ASSERT((kernel_phys_base & L2_GRANULE_MASK) == 0); + if (!kaslr_off) { + // Slide the kernel virtually, keeping in the min and max range + // defined above + size_t random_value = get_kaslr_random("kaslr-slide"); + slide_virt = (random_value & ~slide_granule_mask) % slide_virt_max; + if (slide_virt == 0) { + slide_virt = slide_virt_max; + } + + // The virtual and physical addresses need to have the same offset + // within an L2 block (2MiB with 4k pages, 32MiB with 16k). + // By contract the kernel's virtual base address is aligned to an L2 block. + // We asserted above that the physical base address is aligned to an L2 block. + // Under those conditions, guaranteeing the alignment is trivial. + slide_phys = (slide_virt & L2_GRANULE_MASK); + } else { + slide_virt = 0; + slide_phys = 0; + } +#endif + + dprintf(DEBUG_INFO, "KASLR virtual slide: 0x%08zx\n", slide_virt); + dprintf(DEBUG_INFO, "KASLR physical slide: 0x%08zx\n", slide_phys); + + *physical_slide_out = slide_phys; + *virtual_slide_out = slide_virt; +} + + +static addr_t +load_kernelcache_object(addr_t addr, size_t size, addr_t *boot_args_out) +{ + static boot_args boot_args; + const char *bootArgsStr; + addr_t kernel_region_phys; + size_t kernel_region_size; + addr_t kcache_base_kern; + addr_t entry_point_kern; + addr_t entry_point_phys; + addr_t kcache_end_kern; + addr_t ramdisk_kern; + addr_t ramdisk_phys; + addr_t boot_args_kern; + addr_t boot_args_phys; + addr_t devicetree_kern; + addr_t devicetree_phys; + size_t devicetree_size; + addr_t last_alloc_addr_kern; + addr_t last_alloc_addr_phys; + size_t slide_phys; + size_t slide_kern; + + // Reset the kernel memory allocator in case this is our second time through + init_kernel_mem_allocator(); + // Ditto with boot args + memset(&boot_args, 0, sizeof(boot_args)); + + boot_args.revision = kBootArgsRevision; + boot_args.version = kBootArgsVersion1 + platform_get_security_epoch(); + + // Get the region of memory that will be managed by the kernel. + // This is typically above the SEP region (if any) or + // at the base of memory if no SEP + kernel_region_phys = platform_get_memory_region_base(kMemoryRegion_Kernel); + kernel_region_size = platform_get_memory_region_size(kMemoryRegion_Kernel); + + get_kaslr_slides(kernel_region_phys, size, &slide_phys, &slide_kern); + RELEASE_ASSERT(slide_phys + size < kernel_region_size); + + boot_args.physBase = kernel_region_phys; + boot_args.memSize = kernel_region_size; + + // Scan the kernelcache and record the location of segments in the + // /chosen/memory-map node in the devicetree. + record_kernelcache_segments(addr, kernel_region_phys + slide_phys); + + // Load the kernelcache object + macho_load(addr, size, kernel_region_phys + slide_phys, &kcache_base_kern, &kcache_end_kern, &entry_point_kern, slide_kern); + boot_args.virtBase = kcache_base_kern - slide_phys; + // Record the space used by the kernelcache + alloc_kernel_mem(kcache_end_kern); + +#if RELEASE_BUILD + // Force boot-args for RELEASE builds + bootArgsStr = (gRAMDiskAddr == 0) ? "" : "rd=md0 nand-enable-reformat=1 -progress"; +#else + bootArgsStr = env_get("boot-args"); + if (bootArgsStr == 0) + bootArgsStr = ""; +#endif + + if (target_is_tethered()) { + snprintf(boot_args.commandLine, BOOT_LINE_LENGTH, "%s force-usb-power=1 ", bootArgsStr); + } else { + snprintf(boot_args.commandLine, BOOT_LINE_LENGTH, "%s ", bootArgsStr); + } + + if (gRAMDiskAddr != 0) { + uint32_t backlight_level; + if (target_get_property(TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL, &backlight_level, sizeof(backlight_level), NULL)) { + snprintf(boot_args.commandLine, BOOT_LINE_LENGTH, "%s backlight-level=%d ", bootArgsStr, backlight_level); + } + } + + bootArgsStr = boot_args.commandLine; + +#if WITH_HW_POWER + boot_args.boot_flags |= (power_is_dark_boot()) ? kBootFlagDarkBoot : 0; + + dprintf(DEBUG_INFO, "Passing dark boot state: %s\n", power_is_dark_boot() ? "dark" : "not dark"); +#endif + + update_display_info(&boot_args); + + if (contains_boot_arg(bootArgsStr, "-s", false) + || contains_boot_arg(bootArgsStr, "-v", false)) { + boot_args.video.v_display = 0; + } + + if (contains_boot_arg(bootArgsStr, "debug=", true)) { + security_enable_kdp(); + } + +#if WITH_HW_USB + if (contains_boot_arg(bootArgsStr, "force-usb-power=1", false)) { + extern bool force_usb_power; + force_usb_power = true; + } +#endif + + // If we have a ramdisk, allocate kernel memory for it and copy + // it from its load address to the kernel region + if (gRAMDiskAddr != 0) { + ramdisk_kern = alloc_kernel_mem(gRAMDiskSize); + ramdisk_phys = kern_to_phys(ramdisk_kern, &boot_args); + memcpy((void *)ramdisk_phys, (void *)gRAMDiskAddr, gRAMDiskSize); + record_memory_range("RAMDisk", ramdisk_phys, gRAMDiskSize); + } + + // Allocate a kernel memory for the boot args. The boot args + // will get copied to this buffer at the end of this function. + boot_args_kern = alloc_kernel_mem(PAGE_SIZE); + boot_args_phys = kern_to_phys(boot_args_kern, &boot_args); + record_memory_range("BootArgs", boot_args_phys, PAGE_SIZE); + + PROFILE_ENTER('UDT'); + int ret = UpdateDeviceTree(&boot_args); + PROFILE_EXIT('UDT'); + if (ret < 0){ + dprintf(DEBUG_CRITICAL, "UpdateDeviceTree() failed with %d\n", ret); + return (addr_t)(NULL); + } + + // We need to put the size of the device tree into the device tree, but + // doing so could change its size. So, start by recording dummy information + // and then calculate the final device tree size + record_memory_range("DeviceTree", (addr_t)-1, (size_t)-1); + + devicetree_size = dt_get_size(); + + // Allocate kernel memory for the device tree + devicetree_kern = alloc_kernel_mem(devicetree_size); + devicetree_phys = kern_to_phys(devicetree_kern, &boot_args); + // overwrite the dummy entry made previously + record_memory_range("DeviceTree", devicetree_phys, devicetree_size); + + dt_serialize(NULL, (void *)devicetree_phys, devicetree_size); + + // After this point, the device tree must not be modified + dt_seal(); + + boot_args.deviceTreeP = (void *)devicetree_kern; + boot_args.deviceTreeLength = devicetree_size; + + entry_point_phys = kern_to_phys(entry_point_kern, &boot_args); + + last_alloc_addr_kern = (alloc_kernel_mem(0) + 0x3000) & (size_t)~0x3fff; + last_alloc_addr_phys = kern_to_phys(last_alloc_addr_kern, &boot_args); + + boot_args.topOfKernelData = last_alloc_addr_phys; + + dprintf(DEBUG_CRITICAL, "boot_args.commandLine = [%s]\n", boot_args.commandLine); + dprintf(DEBUG_INFO, "boot_args.physBase = [%p], boot_args.virtBase = [%p]\n", (void *)boot_args.physBase, (void *)boot_args.virtBase); + dprintf(DEBUG_INFO, "boot_args.deviceTreeLength = 0x%x, boot_args.deviceTreeP = %p, devicetree_phys = %p\n", + boot_args.deviceTreeLength, (void *)boot_args.deviceTreeP, (void *)devicetree_phys); + dprintf(DEBUG_INFO, "kernel entry point: %p, boot args: %p\n", (void *)entry_point_phys, (void *)boot_args_phys); + + // copy our local boot arg buffer into the kernel memory region for boot args + memset((void *)boot_args_phys, 0, PAGE_SIZE); + memcpy((void *)boot_args_phys, &boot_args, sizeof(boot_args)); + + security_create_sleep_token(SLEEP_TOKEN_BUFFER_BASE + kSleepTokeniBootOffset); + +#if !RELEASE_BUILD && WITH_CONSISTENT_DEBUG + // Astris needs to be able to find the kernel to do coredumps + dbg_record_header_t kernel_region_hdr; + kernel_region_hdr.record_id = kDbgIdXNUKernelRegion; + kernel_region_hdr.physaddr = kernel_region_phys + slide_phys; + kernel_region_hdr.length = kcache_end_kern - kcache_base_kern; + consistent_debug_register_header(kernel_region_hdr); +#endif + +#if WITH_MONITOR + extern addr_t gMonitorArgs; + extern addr_t gMonitorEntry; + monitor_boot_args *mba; + + /* + * Patch the monitor boot-args with the location of the + * now-constructed kernel boot-args. + * Ensure that we pass back the monitor entrypoint, not + * the kernel's. + */ + if (0 != gMonitorArgs) { + mba = (struct monitor_boot_args *)gMonitorArgs; + mba->kernArgs = boot_args_phys; + mba->kernEntry = entry_point_phys; + mba->kernPhysBase = kernel_region_phys; + mba->kernPhysSlide = slide_phys; + mba->kernVirtSlide = slide_kern; + + dprintf(DEBUG_INFO, "monitor entry point: %p, boot args: %p\n", (void *)gMonitorEntry, (void *)gMonitorArgs); + + *boot_args_out = gMonitorArgs; + return gMonitorEntry; + } +#else + gKernelEntry = entry_point_phys; +#endif + + *boot_args_out = boot_args_phys; + return entry_point_phys; +} + +// Private Functions + +/* + * Scan the mach-o kernelcache and record the location + * of interesting segments in the chosen/memory-map node + * of the DeviceTree. + */ +static void +record_kernelcache_segments(addr_t addr, addr_t phys_base) +{ + mach_header_t *mH; + addr_t cmdBase; + addr_t virt_base; + uint32_t index; + + mH = (mach_header_t *)addr; + cmdBase = (addr_t)(mH + 1); + virt_base = 0; + + for (index = 0; index < mH->ncmds; index++) { +#if defined(__LP64__) + if ((((struct load_command *)cmdBase)->cmd) == LC_SEGMENT_64) +#else + if ((((struct load_command *)cmdBase)->cmd) == LC_SEGMENT) +#endif + record_kernelcache_segment(cmdBase, phys_base, &virt_base); + cmdBase += (((struct load_command *)cmdBase)->cmdsize); + } +} + +static void +record_kernelcache_segment(addr_t cmdBase, addr_t phys_base, addr_t *virt_base) +{ + segment_command_t *segCmd; + char rangeName[kPropNameLength]; + addr_t pmaddr; + addr_t vmaddr; + size_t vmsize; + + segCmd = (segment_command_t *)cmdBase; + + vmaddr = segCmd->vmaddr; + vmsize = segCmd->vmsize; + + // if virt_base has not been set let vmaddr select a segment (1MB) + if (*virt_base == 0) { + *virt_base = vmaddr & (addr_t)~0xfffff; + } + + pmaddr = phys_base + vmaddr - *virt_base; + + if (strcmp(segCmd->segname, "__PAGEZERO")) { + // Add the Segment to the memory-map. + snprintf(rangeName, kPropNameLength, "Kernel-%s", segCmd->segname); + record_memory_range(rangeName, pmaddr, vmsize); + } +} + +/* used in the chosen/memory-map node */ +typedef struct MemoryMapFileInfo { + addr_t paddr; + size_t length; +} MemoryMapFileInfo; + +static bool +record_memory_range(char *rangeName, addr_t start, size_t length) +{ + dt_node_t *memory_map; + MemoryMapFileInfo prop_data; + + /* + * Find the /chosen/memory-map node. + */ + if (!dt_find_node(0, "chosen/memory-map", &memory_map)) { + dprintf(DEBUG_INFO, "no /chosen/memory-map in DeviceTree\n"); + return false; + } + + prop_data.paddr = start; + prop_data.length = length; + + dt_set_prop(memory_map, rangeName, &prop_data, sizeof(prop_data)); + + return true; +} + +static addr_t last_kernel_addr; + +static void +init_kernel_mem_allocator(void) +{ + last_kernel_addr = 0; +} + +static addr_t +alloc_kernel_mem(size_t size) +{ + addr_t addr; + + addr = last_kernel_addr; + + last_kernel_addr += (size + PAGE_SIZE - 1) & ~(addr_t)(PAGE_SIZE - 1); + + return addr; +} + +/* + * Convert a kernel-virtual address to a physical address. + */ +static addr_t +kern_to_phys(addr_t vmaddr, boot_args *boot_args) +{ + if (boot_args->virtBase == 0) + panic("kern_to_phys without setting kernel virtual base"); + + return(vmaddr - boot_args->virtBase + boot_args->physBase); +} diff --git a/lib/macho/macho.c b/lib/macho/macho.c new file mode 100644 index 0000000..4c2497d --- /dev/null +++ b/lib/macho/macho.c @@ -0,0 +1,544 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (C) 1998-2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +/* + * macho.c - Functions for decoding a Mach-o Kernel. + * + * Copyright (c) 1998-2006 Apple Computer, Inc. + * + * DRI: Josh de Cesare + */ + +#include +#include +#include + +#include "macho_header.h" + +static addr_t gRelocBase = (addr_t)NULL; +static addr_t gLinkeditBase = (addr_t)NULL; +static uint32_t gLinkeditOffset = 0; +static uint32_t gkalsr_debug = DEBUG_SPEW; + +static bool ProcessSymbols(addr_t cmdBase, size_t slide); + +static bool ProcessRelocations(addr_t cmdBase, size_t slide); + +static segment_command_t *firstsegfromheader(mach_header_t *header); + +static segment_command_t *nextsegfromheader(mach_header_t *header, segment_command_t *seg); + +static section_t *firstsect(segment_command_t *sgp); + +static section_t *nextsect(segment_command_t *sgp, section_t *sp); + +static bool macho_load_segment(addr_t imageAddr, + size_t imageSize, + addr_t segmentAddr, + addr_t loadAddr, + addr_t *virtualBase, + addr_t *virtualEnd, + size_t slide); + +/* + * Check whether something might be a Mach-O object. + */ +bool +macho_valid(addr_t addr) +{ + return(((mach_header_t *)addr)->magic == MH_MAGIC); +} + +bool +macho_slideable(addr_t addr) +{ + mach_header_t *mH; + + mH = (mach_header_t *)addr; + + if (!macho_valid(addr)) + return false; + + return (mH->flags & MH_PIE) != 0; +} + +/* + * Process a mach-o object. + */ +bool +macho_load( + addr_t imageAddr, + size_t imageSize, + addr_t loadAddr, + addr_t *virtualBase, + addr_t *virtualEnd, + addr_t *entryPoint, + size_t slide) +{ + mach_header_t *mH; + uint32_t index; + addr_t cmdBase; + + mH = (mach_header_t *)imageAddr; + cmdBase = (addr_t)(mH + 1); + + *virtualBase = 0; + *virtualEnd = 0; + + gRelocBase = (addr_t)NULL; + gLinkeditBase = (addr_t)NULL; + gLinkeditOffset = 0; + + dprintf(DEBUG_INFO, "mach-o: loading %p->%p\n", (void *)imageAddr, (void *)loadAddr); + dprintf(DEBUG_INFO, " magic 0x%x\n", mH->magic); + dprintf(DEBUG_INFO, " cputype 0x%x\n", mH->cputype); + dprintf(DEBUG_INFO, " cpusubtype 0x%x\n", mH->cpusubtype); + dprintf(DEBUG_INFO, " filetype 0x%x\n", mH->filetype); + dprintf(DEBUG_INFO, " ncmds 0x%x\n", mH->ncmds); + dprintf(DEBUG_INFO, " sizeofcmds 0x%x\n", mH->sizeofcmds); + dprintf(DEBUG_INFO, " flags 0x%x\n", mH->flags); + + for (index = 0; index < mH->ncmds; index++) { + switch(((struct load_command *)cmdBase)->cmd) { +#if defined(__arm__) || defined(__arm64__) + case LC_SEGMENT_ARM: + dprintf(gkalsr_debug, "cmd LC_SEGMENT_ARM:\n"); +#else +# error no support for this architecture +#endif + if (!macho_load_segment(imageAddr, imageSize, cmdBase, loadAddr, virtualBase, virtualEnd, slide)) + return false; + break; + + case LC_UNIXTHREAD: + dprintf(gkalsr_debug, "cmd LC_UNIXTHREAD:\n"); + // plus 8 for flavor and count fields +#if defined(__arm__) || defined(__arm64__) + *entryPoint = ((arm_thread_state_t *)(cmdBase + sizeof(struct thread_command) + 8))->pc; +#else +# error no support for this architecture +#endif + break; + + + case LC_SYMTAB: + dprintf(gkalsr_debug, "cmd LC_SYMTAB:\n"); + if (slide == 0) { + break; + } + if (!ProcessSymbols(cmdBase, slide)) + return false; + break; + + case LC_DYSYMTAB: + dprintf(gkalsr_debug, "cmd LC_DYSYMTAB:\n"); + if (slide == 0) { + break; + } + if (!ProcessRelocations(cmdBase, slide)) + return false; + break; + } + cmdBase += ((struct load_command *)cmdBase)->cmdsize; + } + + if (slide != 0) { + *entryPoint = *entryPoint + slide; + *virtualBase = *virtualBase + slide; + *virtualEnd = *virtualEnd + slide; + } + + dprintf(gkalsr_debug, "macho_load: *entryPoint %p *virtualBase %p *virtualEnd %p\n", + (void *)*entryPoint, (void *)*virtualBase, (void *)*virtualEnd); + + /* + * Clean everything we have just written out to memory. + * + * XXX this should really not be necessary... + */ + platform_cache_operation(CACHE_CLEAN, 0, 0); + return true; +} + + +/* + * Process a Mach-o LC_SEGMENT/LC_SEGMENT_64 command. + */ +static bool +macho_load_segment( + addr_t imageAddr, + size_t imageSize, + addr_t segmentAddr, + addr_t loadAddr, + addr_t *virtualBase, + addr_t *virtualEnd, + size_t slide) +{ + segment_command_t *cmd; + addr_t segmentSourceAddress; + addr_t segmentDestinationAddress; + addr_t segmentVirtualEnd; + size_t segmentLoadSize; + size_t segmentFillSize; + + cmd = (segment_command_t *)segmentAddr; + + /* + * We assume that the first segment in the object + * is lowest in memory, and round it down to the + * nearest megabyte. + */ + if (0 == *virtualBase) { +#if defined(__LP64__) + *virtualBase = cmd->vmaddr & 0xfffffffffff00000ULL; +#else + *virtualBase = cmd->vmaddr & 0xfff00000UL; +#endif + } else { + /* sanity check the segment */ + if (cmd->vmaddr < *virtualBase) + return false; + if ((cmd->vmaddr + cmd->vmsize) < *virtualBase) + return false; + + /* + * XXX should add checks for the file* + * members and sizes + */ + } + + /* + * Mostly ignore the __PAGEZERO segment. + */ + if (!strcmp(cmd->segname, "__PAGEZERO")) + return true; + + /* + * Precalculate various things we are going to + * need to refer to as we copy and fill the segment. + */ + segmentSourceAddress = imageAddr + cmd->fileoff; + segmentDestinationAddress = loadAddr + (cmd->vmaddr - *virtualBase); + segmentLoadSize = __min(cmd->vmsize, cmd->filesize); + segmentFillSize = __min(cmd->vmsize, cmd->vmsize - cmd->filesize); + segmentVirtualEnd = cmd->vmaddr + cmd->vmsize; + + dprintf(DEBUG_INFO, + " %-16.16s %p/%p/%p 0x%zx+0x%zx\n", + cmd->segname, + (void *)segmentDestinationAddress, + (void *)cmd->vmaddr, + (void *)cmd->vmaddr + slide, + segmentLoadSize, + segmentFillSize); + + /* + * Copy the portion of the segment contained in + * the object to its location in the loaded area. + */ + if (segmentLoadSize) { + addr_t segmentEnd = segmentDestinationAddress + segmentLoadSize; + /* no integer overflow */ + RELEASE_ASSERT(segmentEnd > segmentDestinationAddress); + /* don't overwrite the image we're loading from; assumes we always load + * to an address below the image we're loading from + */ + RELEASE_ASSERT((segmentEnd <= imageAddr) || (segmentEnd >= imageAddr + imageSize)); + + memcpy((void *)segmentDestinationAddress, + (void *)segmentSourceAddress, + segmentLoadSize); + } + + /* + * Zero the remaining portion of the segment. + */ + if (segmentFillSize) { + addr_t fillEnd = segmentDestinationAddress + segmentLoadSize + segmentFillSize; + /* no integer overflow */ + RELEASE_ASSERT(fillEnd > segmentDestinationAddress); + /* don't overwrite the image we're loading from; assumes we always load + * to an address below the image we're loading from + */ + RELEASE_ASSERT((fillEnd <= imageAddr) || (fillEnd >= imageAddr + imageSize)); + + memset((void *)(segmentDestinationAddress + segmentLoadSize), + 0, + segmentFillSize); + } + + /* + * Adjust the occupied length if we have extended it. + */ + if (segmentVirtualEnd > *virtualEnd) + *virtualEnd = segmentVirtualEnd; + + if (slide != 0) { + // Remember reloc and linkedit base + if (gRelocBase == (addr_t)NULL) { + gRelocBase = (addr_t)segmentDestinationAddress; + dprintf(gkalsr_debug,"KASLR: gRelocBase = %p\n", (void *)gRelocBase); + } + + if ((gLinkeditBase == (addr_t)NULL) && (!strcmp(cmd->segname, "__LINKEDIT"))) { + gLinkeditBase = (addr_t)segmentDestinationAddress; + gLinkeditOffset = (uint32_t)(cmd->fileoff); + dprintf(gkalsr_debug,"KASR: gLinkeditBase = %p gLinkeditOffset = 0x%x\n", (void *)gLinkeditBase, gLinkeditOffset); + } + + if (strcmp(cmd->segname, "__TEXT") == 0) { + segment_command_t *seg; + section_t *sec; + mach_header_t *mh = (mach_header_t *)segmentDestinationAddress; + + dprintf(gkalsr_debug, "Applying KASLR slide to _mh_execute_header contents:\n"); + for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) { + + dprintf(gkalsr_debug," segment %s: %p -> %p\n", seg->segname, + (void *)seg->vmaddr, (void *)(seg->vmaddr + slide)); + seg->vmaddr += slide; + + for (sec = firstsect(seg); sec != NULL; sec = nextsect(seg, sec)) { + dprintf(gkalsr_debug," -> section %s: %p -> %p\n", sec->sectname, + (void *)sec->addr, (void *)(sec->addr + slide)); + sec->addr += slide; + } + } + } + } + + /* + * Parse segment sections + */ + { + segment_command_t *seg; + section_t *sec; + addr_t sectionDestinationAddress; + + seg = (segment_command_t *)segmentAddr; + for (sec = firstsect(seg); sec != NULL; sec = nextsect(seg, sec)) { + sectionDestinationAddress = loadAddr + (sec->addr - *virtualBase); + + dprintf(gkalsr_debug," -> section %s: %p/%p 0x%llx\n", + sec->sectname, (void *)sectionDestinationAddress, (void *)sec->addr, (uint64_t)sec->size); + /* Slide pointers in __nl_symbol_ptr section */ + if (((sec->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS)) { + void **nl_symbols_ptr; + dprintf(gkalsr_debug,"Slide S_NON_LAZY_SYMBOL_POINTERS \n"); + for (nl_symbols_ptr = (void **)sectionDestinationAddress; + nl_symbols_ptr < (void **)(sectionDestinationAddress+sec->size); + nl_symbols_ptr++) { + if (nl_symbols_ptr == (void **)sectionDestinationAddress) + dprintf(gkalsr_debug," %p : %p -> %p\n", + nl_symbols_ptr, *nl_symbols_ptr, *nl_symbols_ptr + slide); + *nl_symbols_ptr = *nl_symbols_ptr + slide; + } + } + } + } + + return true; +} + + +/* + * Return the first segment_command in the header. + */ +segment_command_t * +firstsegfromheader(mach_header_t *header) +{ + uint32_t i = 0; + segment_command_t *sgp = (segment_command_t *) ((uintptr_t)header + sizeof(*header)); + + for (i = 0; i < header->ncmds; i++){ +#if defined(__arm__) || defined(__arm64__) + if (sgp->cmd == LC_SEGMENT_ARM) + return sgp; +#else +# error no support for this architecture +#endif + sgp = (segment_command_t *)((uintptr_t)sgp + sgp->cmdsize); + } + return (segment_command_t *)NULL; +} + +/* + * This routine operates against any kernel mach segment_command structure + * pointer and the provided kernel header, to obtain the sequentially next + * segment_command structure in that header. + */ +segment_command_t * +nextsegfromheader(mach_header_t *header, + segment_command_t *seg) +{ + uint32_t i = 0; + segment_command_t *sgp = (segment_command_t *) ((uintptr_t)header + sizeof(*header)); + + /* Find the index of the passed-in segment */ + for (i = 0; sgp != seg && i < header->ncmds; i++) { + sgp = (segment_command_t *)((uintptr_t)sgp + sgp->cmdsize); + } + + /* Increment to the next load command */ + i++; + sgp = (segment_command_t *)((uintptr_t)sgp + sgp->cmdsize); + + /* Return the next segment command, if any */ + for (; i < header->ncmds; i++) { +#if defined(__arm__) || defined(__arm64__) + if (sgp->cmd == LC_SEGMENT_ARM) + return sgp; +#else +# error no support for this architecture +#endif + + sgp = (segment_command_t *)((uintptr_t)sgp + sgp->cmdsize); + } + + return (segment_command_t *)NULL; +} + +/* + * This routine can operate against any kernel segment_command structure to + * return the first kernel section immediately following that structure. If + * there are no sections associated with the segment_command structure, it + * returns NULL. + */ +section_t * +firstsect(segment_command_t *sgp) +{ + if (!sgp || sgp->nsects == 0) + return (section_t *)NULL; + + return (section_t *)(sgp + 1); +} + +/* + * This routine can operate against any kernel segment_command structure and + * kernel section to return the next consecutive kernel section immediately + * following the kernel section provided. If there are no sections following + * the provided section, it returns NULL. + */ +section_t * +nextsect(segment_command_t *sgp, section_t *sp) +{ + section_t *fsp = firstsect(sgp); + + if (((uintptr_t)(sp - fsp) + 1) >= sgp->nsects) + return (section_t *)NULL; + + return sp + 1; +} + +bool +ProcessSymbols(addr_t cmdBase, size_t slide) +{ + struct symtab_command *symtab; +#if defined(__LP64__) + struct nlist_64 *sym; +#else + struct nlist *sym; +#endif + uint32_t i; + uint32_t cnt = 0; + + symtab = (struct symtab_command *)cmdBase; + dprintf(gkalsr_debug, "Symbols:\n"); + dprintf(gkalsr_debug, "nsyms: %d, symoff: 0x%x\n", symtab->nsyms, symtab->symoff); + + if (symtab->nsyms == 0) { + dprintf(gkalsr_debug, "No symbols to relocate\n"); + return true; + } + +#if defined(__LP64__) + sym = (struct nlist_64 *)(gLinkeditBase + symtab->symoff - gLinkeditOffset); +#else + sym = (struct nlist *)(gLinkeditBase + symtab->symoff - gLinkeditOffset); +#endif + + for (i = 0; i < symtab->nsyms; i++) { + if (sym[i].n_type & N_STAB) + continue; + sym[i].n_value += slide; + cnt++; + } + dprintf(gkalsr_debug, "KASLR: Relocated %d symbols\n", cnt); + return true; +} + +bool +ProcessRelocations(addr_t cmdBase, size_t slide) +{ + struct dysymtab_command *dysymtab; + + dysymtab = (struct dysymtab_command *)cmdBase; + + dprintf(gkalsr_debug, "Symbols:\n"); + dprintf(gkalsr_debug, "local: %6d @ 0x%x\n", dysymtab->nlocalsym, dysymtab->ilocalsym); + dprintf(gkalsr_debug, "external: %6d @ 0x%x\n", dysymtab->nextdefsym, dysymtab->iextdefsym); + dprintf(gkalsr_debug, "undefined: %6d @ 0x%x\n", dysymtab->nundefsym, dysymtab->iundefsym); + dprintf(gkalsr_debug, "indirect: %6d @ 0x%x\n", dysymtab->nindirectsyms, dysymtab->indirectsymoff); + + dprintf(gkalsr_debug, "Relocation entries:\n"); + dprintf(gkalsr_debug, "local: %6d @ 0x%x\n", dysymtab->nlocrel, dysymtab->locreloff); + dprintf(gkalsr_debug, "external: %6d @ 0x%x\n", dysymtab->nextrel, dysymtab->extreloff); + + if (dysymtab->nlocrel != 0) { + struct relocation_info *relocStart; + struct relocation_info *relocEnd; + struct relocation_info *reloc; + + if (gRelocBase == (addr_t)NULL) { + dprintf(gkalsr_debug, "KASLR: no writeable segment for relocations found\n"); + return false; + } + + if (gLinkeditBase == (addr_t)NULL) { + dprintf(gkalsr_debug, "KASLR: No __LINKEDIT segment found\n"); + return false; + } + + relocStart = (struct relocation_info *)(gLinkeditBase + dysymtab->locreloff - gLinkeditOffset); + relocEnd = &relocStart[dysymtab->nlocrel]; + + dprintf(gkalsr_debug, "KASLR: processing local relocations...\n"); + dprintf(gkalsr_debug, "relocStart = %p, relocEnd = %p\n", relocStart, relocEnd); + + for (reloc = relocStart; reloc < relocEnd; reloc++) { + if ((1 << reloc->r_length) != sizeof(void *)) { + /* 2 to the r_length should be the size of a pointer for all relocations */ + dprintf(gkalsr_debug, "bad local relocation length (%d)\n", reloc->r_length); + return false; + } + if (reloc->r_type != ARM_RELOC_VANILLA) { + dprintf(gkalsr_debug, "unknown local relocation type (%d)\n", reloc->r_type); + return false; + } + if (reloc->r_pcrel != 0) { + dprintf(gkalsr_debug, "bad local relocation r_pcrel"); + return false; + } + if (reloc->r_extern != 0) { + dprintf(gkalsr_debug, "extern relocation found with local relocations\n"); + return false; + } + *((uintptr_t*)(gRelocBase + reloc->r_address)) += slide; + + if (reloc == relocStart) + dprintf(gkalsr_debug, "r_address = 0x%x, gRelocBase + reloc->r_addres = %p\n", + reloc->r_address, (uintptr_t*)(gRelocBase + reloc->r_address)); + } + dprintf(gkalsr_debug, "KASLR: %d local relocations processed\n", dysymtab->nlocrel); + } + + return true; +} diff --git a/lib/macho/macho_header.h b/lib/macho/macho_header.h new file mode 100644 index 0000000..17c2b77 --- /dev/null +++ b/lib/macho/macho_header.h @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * Copyright (C) 1998-2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __MACHO_HEADER_H +#define __MACHO_HEADER_H + +// Taken from osfmk/mach/vm_prot.h +typedef int vm_prot_t; +#define VM_PROT_NONE ((vm_prot_t) 0x00) +#define VM_PROT_READ ((vm_prot_t) 0x01) /* read permission */ +#define VM_PROT_WRITE ((vm_prot_t) 0x02) /* write permission */ +#define VM_PROT_EXECUTE ((vm_prot_t) 0x04) /* execute permission */ + + +// Taken from osfmk/mach/arm/vm_types.h +typedef int integer_t; + +// Taken from osfmk/mach/machine.h + +typedef integer_t cpu_type_t; +typedef integer_t cpu_subtype_t; + +#ifndef __LP64__ +// Taken from mach-o/loader.h + +/* + * The 32-bit mach header appears at the very beginning of the object file for + * 32-bit architectures. + */ +typedef struct mach_header { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ +}mach_header_t; + +/* Constant for the magic field of the mach_header (32-bit architectures) */ +#define MH_MAGIC 0xfeedface /* the mach magic number */ + +#else + +/* + * The 64-bit mach header appears at the very beginning of object files for + * 64-bit architectures. + */ +typedef struct mach_header_64 { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ + uint32_t reserved; /* reserved */ +} mach_header_t; + +/* Constant for the magic field of the mach_header_64 (64-bit architectures) */ +#define MH_MAGIC 0xfeedfacf /* the 64-bit mach magic number */ + +#endif + +/* Constants for the flags field of the mach_header */ +#define MH_PIE 0x200000 /* When this bit is set, the OS will + load the main executable at a + random address. Only used in + MH_EXECUTE filetypes. */ + +/* + * The load commands directly follow the mach_header. The total size of all + * of the commands is given by the sizeofcmds field in the mach_header. All + * load commands must have as their first two fields cmd and cmdsize. The cmd + * field is filled in with a constant for that command type. Each command type + * has a structure specifically for it. The cmdsize field is the size in bytes + * of the particular load command structure plus anything that follows it that + * is a part of the load command (i.e. section structures, strings, etc.). To + * advance to the next load command the cmdsize can be added to the offset or + * pointer of the current load command. The cmdsize for 32-bit architectures + * MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple + * of 8 bytes (these are forever the maximum alignment of any load commands). + * The padded bytes must be zero. All tables in the object file must also + * follow these rules so the file can be memory mapped. Otherwise the pointers + * to these tables will not work well or at all on some machines. With all + * padding zeroed like objects will compare byte for byte. + */ +struct load_command { + uint32_t cmd; /* type of load command */ + uint32_t cmdsize; /* total size of command in bytes */ +}; + +/* Constants for the cmd field of all load commands, the type */ +#define LC_SEGMENT 0x1 /* segment of this file to be mapped */ +#define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ +#define LC_THREAD 0x4 /* thread */ +#define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ +#define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ +#define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be mapped */ + +#ifndef __LP64__ +#define LC_SEGMENT_ARM LC_SEGMENT +#else +#define LC_SEGMENT_ARM LC_SEGMENT_64 +#endif + +#ifndef __LP64__ +/* + * The segment load command indicates that a part of this file is to be + * mapped into the task's address space. The size of this segment in memory, + * vmsize, maybe equal to or larger than the amount to map from this file, + * filesize. The file is mapped starting at fileoff to the beginning of + * the segment in memory, vmaddr. The rest of the memory of the segment, + * if any, is allocated zero fill on demand. The segment's maximum virtual + * memory protection and initial virtual memory protection are specified + * by the maxprot and initprot fields. If the segment has sections then the + * section structures directly follow the segment command and their size is + * reflected in cmdsize. + */ +typedef struct segment_command { /* for 32-bit architectures */ + uint32_t cmd; /* LC_SEGMENT */ + uint32_t cmdsize; /* includes sizeof section structs */ + char segname[16]; /* segment name */ + uint32_t vmaddr; /* memory address of this segment */ + uint32_t vmsize; /* memory size of this segment */ + uint32_t fileoff; /* file offset of this segment */ + uint32_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +} segment_command_t; +#else +/* + * The 64-bit segment load command indicates that a part of this file is to be + * mapped into a 64-bit task's address space. If the 64-bit segment has + * sections then section_64 structures directly follow the 64-bit segment + * command and their size is reflected in cmdsize. + */ +typedef struct segment_command_64 { /* for 64-bit architectures */ + uint32_t cmd; /* LC_SEGMENT_64 */ + uint32_t cmdsize; /* includes sizeof section_64 structs */ + char segname[16]; /* segment name */ + uint64_t vmaddr; /* memory address of this segment */ + uint64_t vmsize; /* memory size of this segment */ + uint64_t fileoff; /* file offset of this segment */ + uint64_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +} segment_command_t; +#endif + +#ifndef __LP64__ +typedef struct section { /* for 32-bit architectures */ + char sectname[16]; /* name of this section */ + char segname[16]; /* segment this section goes in */ + uint32_t addr; /* memory address of this section */ + uint32_t size; /* size in bytes of this section */ + uint32_t offset; /* file offset of this section */ + uint32_t align; /* section alignment (power of 2) */ + uint32_t reloff; /* file offset of relocation entries */ + uint32_t nreloc; /* number of relocation entries */ + uint32_t flags; /* flags (section type and attributes)*/ + uint32_t reserved1; /* reserved (for offset or index) */ + uint32_t reserved2; /* reserved (for count or sizeof) */ +} section_t; +#else +typedef struct section_64 { /* for 64-bit architectures */ + char sectname[16]; /* name of this section */ + char segname[16]; /* segment this section goes in */ + uint64_t addr; /* memory address of this section */ + uint64_t size; /* size in bytes of this section */ + uint32_t offset; /* file offset of this section */ + uint32_t align; /* section alignment (power of 2) */ + uint32_t reloff; /* file offset of relocation entries */ + uint32_t nreloc; /* number of relocation entries */ + uint32_t flags; /* flags (section type and attributes)*/ + uint32_t reserved1; /* reserved (for offset or index) */ + uint32_t reserved2; /* reserved (for count or sizeof) */ + uint32_t reserved3; /* reserved */ +} section_t; +#endif + +/* + * The flags field of a section structure is separated into two parts a section + * type and section attributes. The section types are mutually exclusive (it + * can only have one type) but the section attributes are not (it may have more + * than one attribute). + */ +#define SECTION_TYPE 0x000000ff /* 256 section types */ +#define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes */ + +/* Constants for the type of a section */ +#define S_REGULAR 0x0 /* regular section */ +#define S_ZEROFILL 0x1 /* zero fill on demand section */ +#define S_CSTRING_LITERALS 0x2 /* section with only literal C strings*/ +#define S_4BYTE_LITERALS 0x3 /* section with only 4 byte literals */ +#define S_8BYTE_LITERALS 0x4 /* section with only 8 byte literals */ +#define S_LITERAL_POINTERS 0x5 /* section with only pointers to */ + /* literals */ +/* + * For the two types of symbol pointers sections and the symbol stubs section + * they have indirect symbol table entries. For each of the entries in the + * section the indirect symbol table entries, in corresponding order in the + * indirect symbol table, start at the index stored in the reserved1 field + * of the section structure. Since the indirect symbol table entries + * correspond to the entries in the section the number of indirect symbol table + * entries is inferred from the size of the section divided by the size of the + * entries in the section. For symbol pointers sections the size of the entries + * in the section is 4 bytes and for symbol stubs sections the byte size of the + * stubs is stored in the reserved2 field of the section structure. + */ +#define S_NON_LAZY_SYMBOL_POINTERS 0x6 /* section with only non-lazy + symbol pointers */ +#define S_LAZY_SYMBOL_POINTERS 0x7 /* section with only lazy symbol + pointers */ +#define S_SYMBOL_STUBS 0x8 /* section with only symbol + stubs, byte size of stub in + the reserved2 field */ +#define S_MOD_INIT_FUNC_POINTERS 0x9 /* section with only function + pointers for initialization*/ +#define S_MOD_TERM_FUNC_POINTERS 0xa /* section with only function + pointers for termination */ +#define S_COALESCED 0xb /* section contains symbols that + are to be coalesced */ +#define S_GB_ZEROFILL 0xc /* zero fill on demand section + (that can be larger than 4 + gigabytes) */ +#define S_INTERPOSING 0xd /* section with only pairs of + function pointers for + interposing */ +#define S_16BYTE_LITERALS 0xe /* section with only 16 byte + literals */ +#define S_DTRACE_DOF 0xf /* section contains + DTrace Object Format */ +#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 /* section with only lazy + symbol pointers to lazy + loaded dylibs */ + + +/* + * The symtab_command contains the offsets and sizes of the link-edit 4.3BSD + * "stab" style symbol table information as described in the header files + * and . + */ +struct symtab_command { + uint32_t cmd; /* LC_SYMTAB */ + uint32_t cmdsize; /* sizeof(struct symtab_command) */ + uint32_t symoff; /* symbol table offset */ + uint32_t nsyms; /* number of symbol table entries */ + uint32_t stroff; /* string table offset */ + uint32_t strsize; /* string table size in bytes */ +}; + +/* + * This is the second set of the symbolic information which is used to support + * the data structures for the dynamically link editor. + * + * The original set of symbolic information in the symtab_command which contains + * the symbol and string tables must also be present when this load command is + * present. When this load command is present the symbol table is organized + * into three groups of symbols: + * local symbols (static and debugging symbols) - grouped by module + * defined external symbols - grouped by module (sorted by name if not lib) + * undefined external symbols (sorted by name if MH_BINDATLOAD is not set, + * and in order the were seen by the static + * linker if MH_BINDATLOAD is set) + * In this load command there are offsets and counts to each of the three groups + * of symbols. + * + * This load command contains a the offsets and sizes of the following new + * symbolic information tables: + * table of contents + * module table + * reference symbol table + * indirect symbol table + * The first three tables above (the table of contents, module table and + * reference symbol table) are only present if the file is a dynamically linked + * shared library. For executable and object modules, which are files + * containing only one module, the information that would be in these three + * tables is determined as follows: + * table of contents - the defined external symbols are sorted by name + * module table - the file contains only one module so everything in the + * file is part of the module. + * reference symbol table - is the defined and undefined external symbols + * + * For dynamically linked shared library files this load command also contains + * offsets and sizes to the pool of relocation entries for all sections + * separated into two groups: + * external relocation entries + * local relocation entries + * For executable and object modules the relocation entries continue to hang + * off the section structures. + */ +struct dysymtab_command { + uint32_t cmd; /* LC_DYSYMTAB */ + uint32_t cmdsize; /* sizeof(struct dysymtab_command) */ + + /* + * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command + * are grouped into the following three groups: + * local symbols (further grouped by the module they are from) + * defined external symbols (further grouped by the module they are from) + * undefined symbols + * + * The local symbols are used only for debugging. The dynamic binding + * process may have to use them to indicate to the debugger the local + * symbols for a module that is being bound. + * + * The last two groups are used by the dynamic binding process to do the + * binding (indirectly through the module table and the reference symbol + * table when this is a dynamically linked shared library file). + */ + uint32_t ilocalsym; /* index to local symbols */ + uint32_t nlocalsym; /* number of local symbols */ + + uint32_t iextdefsym;/* index to externally defined symbols */ + uint32_t nextdefsym;/* number of externally defined symbols */ + + uint32_t iundefsym; /* index to undefined symbols */ + uint32_t nundefsym; /* number of undefined symbols */ + + /* + * For the for the dynamic binding process to find which module a symbol + * is defined in the table of contents is used (analogous to the ranlib + * structure in an archive) which maps defined external symbols to modules + * they are defined in. This exists only in a dynamically linked shared + * library file. For executable and object modules the defined external + * symbols are sorted by name and is use as the table of contents. + */ + uint32_t tocoff; /* file offset to table of contents */ + uint32_t ntoc; /* number of entries in table of contents */ + + /* + * To support dynamic binding of "modules" (whole object files) the symbol + * table must reflect the modules that the file was created from. This is + * done by having a module table that has indexes and counts into the merged + * tables for each module. The module structure that these two entries + * refer to is described below. This exists only in a dynamically linked + * shared library file. For executable and object modules the file only + * contains one module so everything in the file belongs to the module. + */ + uint32_t modtaboff; /* file offset to module table */ + uint32_t nmodtab; /* number of module table entries */ + + /* + * To support dynamic module binding the module structure for each module + * indicates the external references (defined and undefined) each module + * makes. For each module there is an offset and a count into the + * reference symbol table for the symbols that the module references. + * This exists only in a dynamically linked shared library file. For + * executable and object modules the defined external symbols and the + * undefined external symbols indicates the external references. + */ + uint32_t extrefsymoff; /* offset to referenced symbol table */ + uint32_t nextrefsyms; /* number of referenced symbol table entries */ + + /* + * The sections that contain "symbol pointers" and "routine stubs" have + * indexes and (implied counts based on the size of the section and fixed + * size of the entry) into the "indirect symbol" table for each pointer + * and stub. For every section of these two types the index into the + * indirect symbol table is stored in the section header in the field + * reserved1. An indirect symbol table entry is simply a 32bit index into + * the symbol table to the symbol that the pointer or stub is referring to. + * The indirect symbol table is ordered to match the entries in the section. + */ + uint32_t indirectsymoff; /* file offset to the indirect symbol table */ + uint32_t nindirectsyms; /* number of indirect symbol table entries */ + + /* + * To support relocating an individual module in a library file quickly the + * external relocation entries for each module in the library need to be + * accessed efficiently. Since the relocation entries can't be accessed + * through the section headers for a library file they are separated into + * groups of local and external entries further grouped by module. In this + * case the presents of this load command who's extreloff, nextrel, + * locreloff and nlocrel fields are non-zero indicates that the relocation + * entries of non-merged sections are not referenced through the section + * structures (and the reloff and nreloc fields in the section headers are + * set to zero). + * + * Since the relocation entries are not accessed through the section headers + * this requires the r_address field to be something other than a section + * offset to identify the item to be relocated. In this case r_address is + * set to the offset from the vmaddr of the first LC_SEGMENT command. + * For MH_SPLIT_SEGS images r_address is set to the the offset from the + * vmaddr of the first read-write LC_SEGMENT command. + * + * The relocation entries are grouped by module and the module table + * entries have indexes and counts into them for the group of external + * relocation entries for that the module. + * + * For sections that are merged across modules there must not be any + * remaining external relocation entries for them (for merged sections + * remaining relocation entries must be local). + */ + uint32_t extreloff; /* offset to external relocation entries */ + uint32_t nextrel; /* number of external relocation entries */ + + /* + * All the local relocation entries are grouped together (they are not + * grouped by their module since they are only used if the object is moved + * from it staticly link edited address). + */ + uint32_t locreloff; /* offset to local relocation entries */ + uint32_t nlocrel; /* number of local relocation entries */ + +}; + +/* + * An indirect symbol table entry is simply a 32bit index into the symbol table + * to the symbol that the pointer or stub is refering to. Unless it is for a + * non-lazy symbol pointer section for a defined symbol which strip(1) as + * removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the + * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. + */ +#define INDIRECT_SYMBOL_LOCAL 0x80000000 +#define INDIRECT_SYMBOL_ABS 0x40000000 + +/* + * Thread commands contain machine-specific data structures suitable for + * use in the thread state primitives. The machine specific data structures + * follow the struct thread_command as follows. + * Each flavor of machine specific data structure is preceded by an unsigned + * long constant for the flavor of that data structure, an uint32_t + * that is the count of longs of the size of the state data structure and then + * the state data structure follows. This triple may be repeated for many + * flavors. The constants for the flavors, counts and state data structure + * definitions are expected to be in the header file . + * These machine specific data structures sizes must be multiples of + * 4 bytes The cmdsize reflects the total size of the thread_command + * and all of the sizes of the constants for the flavors, counts and state + * data structures. + * + * For executable objects that are unix processes there will be one + * thread_command (cmd == LC_UNIXTHREAD) created for it by the link-editor. + * This is the same as a LC_THREAD, except that a stack is automatically + * created (based on the shell's limit for the stack size). Command arguments + * and environment variables are copied onto that stack. + */ +struct thread_command { + uint32_t cmd; /* LC_THREAD or LC_UNIXTHREAD */ + uint32_t cmdsize; /* total size of this command */ + /* uint32_t flavor flavor of thread state */ + /* uint32_t count count of longs in thread state */ + /* struct XXX_thread_state state thread state for this flavor */ + /* ... */ +}; + + +#ifdef __arm__ +// Taken from osfmk/mach/arm/_types.h + +typedef struct arm_thread_state +{ + uint32_t r[13]; /* General purpose register r0-r12 */ + uint32_t sp; /* Stack pointer r13 */ + uint32_t lr; /* Link regisster r14 */ + uint32_t pc; /* Program counter r15 */ + uint32_t cpsr; /* Current program status register */ +} arm_thread_state_t; +#else +#ifdef __arm64__ +// Based from osfmk/mach/arm/_structs.h + +typedef struct arm_thread_state64 +{ + uint64_t x[29]; /* General purpose registers x0-x28 */ + uint64_t fp; /* Frame pointer x29 */ + uint64_t lr; /* Link register x30 */ + uint64_t sp; /* Stack pointer x31 */ + uint64_t pc; /* Program counter */ + uint32_t cpsr; /* Current program status register */ +} arm_thread_state_t; +#endif +#endif + +/* + * Format of a symbol table entry of a Mach-O file for 32-bit architectures. + * Modified from the BSD format. The modifications from the original format + * were changing n_other (an unused field) to n_sect and the addition of the + * N_SECT type. These modifications are required to support symbols in a larger + * number of sections not just the three sections (text, data and bss) in a BSD + * file. + */ + +struct nlist { + union { +#ifndef __LP64__ + char *n_name; /* for use when in-core */ +#endif + int32_t n_strx; /* index into the string table */ + } n_un; + uint8_t n_type; /* type flag, see below */ + uint8_t n_sect; /* section number or NO_SECT */ + int16_t n_desc; /* see */ + uint32_t n_value; /* value of this symbol (or stab offset) */ +}; + +/* + * This is the symbol table entry structure for 64-bit architectures. + */ +struct nlist_64 { + union { + uint32_t n_strx; /* index into the string table */ + } n_un; + uint8_t n_type; /* type flag, see below */ + uint8_t n_sect; /* section number or NO_SECT */ + uint16_t n_desc; /* see */ + uint64_t n_value; /* value of this symbol (or stab offset) */ +}; + +/* + * Symbols with a index into the string table of zero (n_un.n_strx == 0) are + * defined to have a null, "", name. Therefore all string indexes to non null + * names must not have a zero string index. This is bit historical information + * that has never been well documented. + */ + +/* + * The n_type field really contains four fields: + * unsigned char N_STAB:3, + * N_PEXT:1, + * N_TYPE:3, + * N_EXT:1; + * which are used via the following masks. + */ +#define N_STAB 0xe0 /* if any of these bits set, a symbolic debugging entry */ +#define N_PEXT 0x10 /* private external symbol bit */ +#define N_TYPE 0x0e /* mask for the type bits */ +#define N_EXT 0x01 /* external symbol bit, set for external symbols */ + + +/* + * Format of a relocation entry of a Mach-O file. Modified from the 4.3BSD + * format. The modifications from the original format were changing the value + * of the r_symbolnum field for "local" (r_extern == 0) relocation entries. + * This modification is required to support symbols in an arbitrary number of + * sections not just the three sections (text, data and bss) in a 4.3BSD file. + * Also the last 4 bits have had the r_type tag added to them. + */ +struct relocation_info { + int32_t r_address; /* offset in the section to what is being + relocated */ + uint32_t r_symbolnum:24, /* symbol index if r_extern == 1 or section + ordinal if r_extern == 0 */ + r_pcrel:1, /* was relocated pc relative already */ + r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */ + r_extern:1, /* does not include value of sym referenced */ + r_type:4; /* if not 0, machine specific relocation type */ +}; + +enum reloc_type_arm +{ + ARM_RELOC_VANILLA, /* generic relocation as discribed above */ + ARM_RELOC_PAIR, /* the second relocation entry of a pair */ + ARM_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */ + ARM_RELOC_LOCAL_SECTDIFF, /* like ARM_RELOC_SECTDIFF, but the symbol + referenced was local. */ + ARM_RELOC_PB_LA_PTR,/* prebound lazy pointer */ + ARM_RELOC_BR24, /* 24 bit branch displacement (to a word address) */ + ARM_THUMB_RELOC_BR22, /* 22 bit branch displacement (to a half-word + address) */ + ARM_THUMB_32BIT_BRANCH, /* obsolete - a thumb 32-bit branch instruction + possibly needing page-spanning branch workaround */ + + /* + * For these two r_type relocations they always have a pair following them + * and the r_length bits are used differently. The encoding of the + * r_length is as follows: + * low bit of r_length: + * 0 - :lower16: for movw instructions + * 1 - :upper16: for movt instructions + * high bit of r_length: + * 0 - arm instructions + * 1 - thumb instructions + * the other half of the relocated expression is in the following pair + * relocation entry in the the low 16 bits of r_address field. + */ + ARM_RELOC_HALF, + ARM_RELOC_HALF_SECTDIFF +}; + + +#endif /* __MACHO_HEADER_H */ diff --git a/lib/macho/monitor.c b/lib/macho/monitor.c new file mode 100644 index 0000000..41db85b --- /dev/null +++ b/lib/macho/monitor.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_MIU +#include +#endif +#include +#include + +#include "boot.h" + +addr_t gMonitorEntry; +addr_t gMonitorArgs; + +/* + * Only applicable if the platform memory map has allocations for + * a monitor. + */ +#if WITH_MONITOR + +static int loaded_monitor(addr_t secure_addr, size_t secure_size); + +/* + * This expects a known macho image of size 'size' is placed at address 'addr'. + * This is helper function to single monitor + kernel load image, where monitor macho + * is placed at the end of compressed kernelcache, and entire object is wrapped into + * img3/4 format. + */ +int +load_monitor_image(addr_t addr, size_t size) +{ + if (size > platform_get_memory_region_size(kMemoryRegion_Monitor)) { + printf("monitor too large\n"); + return -2; + } + + return (loaded_monitor(addr, size)); +} + +static int +loaded_monitor(addr_t secure_addr, size_t secure_size) +{ + monitor_boot_args *mba; + addr_t virtualBase; + addr_t virtualEnd; + addr_t monitor_base; + addr_t monitor_size; + + if (!macho_valid(secure_addr)) + return -6; + + monitor_base = platform_get_memory_region_base(kMemoryRegion_Monitor); + monitor_size = platform_get_memory_region_size(kMemoryRegion_Monitor); + + if (!macho_load(secure_addr, secure_size, monitor_base, &virtualBase, &virtualEnd, &gMonitorEntry, 0)) + return -7; + + dprintf(DEBUG_INFO, "monitor loaded at virt: %p, phys: %p, entry: %p\n", + (void *)virtualBase, (void *)monitor_base, (void *)gMonitorEntry); + + gMonitorEntry -= virtualBase; + gMonitorEntry += monitor_base; + + mba = (monitor_boot_args *)(monitor_base + monitor_size - sizeof(*mba)); + mba->version = 2; + mba->virtBase = virtualBase; + mba->physBase = monitor_base; + mba->memSize = monitor_size; + gMonitorArgs = (addr_t)mba; + + return 0; +} + +#endif /* WITH_MONITOR */ diff --git a/lib/macho/rules.mk b/lib/macho/rules.mk new file mode 100644 index 0000000..18667ad --- /dev/null +++ b/lib/macho/rules.mk @@ -0,0 +1,23 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += WITH_MACHO=1 +MODULES += \ + lib/cksum \ + lib/devicetree \ + lib/lzss + +ALL_OBJS += \ + $(LOCAL_DIR)/dt.o \ + $(LOCAL_DIR)/kernelcache.o \ + $(LOCAL_DIR)/macho.o \ + $(LOCAL_DIR)/monitor.o + diff --git a/lib/mib/header.mk b/lib/mib/header.mk new file mode 100644 index 0000000..5fc094d --- /dev/null +++ b/lib/mib/header.mk @@ -0,0 +1,24 @@ +# Copyright (C) 2014 Apple, Inc. All rights reserved. +# +# This document is the property of Apple, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +LOCAL_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) + +MIB_HDR_DIR := $(OBJROOT)/build/include/$(LOCAL_DIR) + +MIB_GEN_HDR := $(LOCAL_DIR)/mib_gen_hdr.awk +MIB_BASE := $(LOCAL_DIR)/mib.base + +build: $(MIB_HDR_DIR)/mib_nodes.h + +$(MIB_HDR_DIR)/mib_nodes.h: $(MIB_BASE) $(MIB_GEN_HDR) + @echo GEN $(MIB_HDR_DIR)/mib_nodes.h + $(_v)mkdir -p $(MIB_HDR_DIR) + $(_v)awk -f $(MIB_GEN_HDR) $(MIB_HDR_DIR) $(MIB_BASE) + diff --git a/lib/mib/library.mk b/lib/mib/library.mk new file mode 100644 index 0000000..84f3fb0 --- /dev/null +++ b/lib/mib/library.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBMIB_DIR := $(GET_LOCAL_DIR) +LIBMIB_BUILD := $(call TOLIBDIR,$(LIBMIB_DIR)/LIBMIB.a) +COMMONLIBS += LIBMIB + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBMIB_OBJ_DIR := $(call TOLIBOBJDIR,$(LIBMIB_DIR)) + +MIB_GEN_DEF := $(LIBMIB_DIR)/mib_gen_def.awk +MIB_BASE := $(LIBMIB_DIR)/mib.base + +LIBMIB_OBJS := \ + $(LIBMIB_OBJ_DIR)/mib.o \ + $(LIBMIB_OBJ_DIR)/mib_nodes.o + +$(LIBMIB_BUILD): $(LIBMIB_OBJS) + +$(LIBMIB_OBJ_DIR)/mib_nodes.c: $(MIB_BASE) $(MIB_GEN_DEF) + @echo GEN $(LIBMIB_OBJ_DIR)/mib_nodes.c + $(_v)mkdir -p $(LIBMIB_OBJ_DIR) + $(_v)awk -f $(MIB_GEN_DEF) $(LIBMIB_OBJ_DIR) $(MIB_BASE) + +ALL_DEPS += $(LIBMIB_OBJS:%o=%d) + +endif diff --git a/lib/mib/mib.base b/lib/mib/mib.base new file mode 100644 index 0000000..91aff9e --- /dev/null +++ b/lib/mib/mib.base @@ -0,0 +1,80 @@ +# Copyright (C) 2014-2015 Apple, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple, Inc. +# +######################################## +# List of MIB subsystems and nodes +# defined. Keep sorted alphabetically. +######################################## + +subsystem Build +######################################## +node Banner +node Style +node Tag + +subsystem Platform +######################################## +node CacheLineSize +node EntropyRatio +node ImageFormat +node SDRAMBaseAddress +node SDRAMSize +node PageSize + +subsystem System +######################################## +node BootTime +node IdleTime +node Uptime + +subsystem Target +######################################## +node AcceptGlobalTicket +node ApplicationProduct +node Backlight0I2CAddress +node Backlight1I2CAddress +node Backlight0I2CBus +node Backlight1I2CBus +node BacklightAutoFreqThresh +node DefaultDeviceTreeAddress +node DefaultDeviceTreeSize +node DefaultFreeAddress +node DefaultLoadAddress +node DefaultLoadSize +node DefaultKernelAddress +node DefaultKernelSize +node DefaultRamdiskAddress +node DefaultRamdiskSize +node DisplayBaseAddress +node DisplayCMEngammaTablePtr +node DisplayCMEngammaTableCount +node DisplayCMDegammaTablePtr +node DisplayCMDegammaTableCount +node DisplayCMMatrixTablePtr +node DisplayCMMatrixTableCount +node DisplayGammaTablePtr +node DisplayGammaTableCount +node MinimumHeapSizeForSlide +node NvramNorBankCount +node NvramNorBankSize +node NvramNorOffset +node OsPictureScale +node PanicBufferAddress +node PanicBufferSize +node PanicOnUnknownDclrVersion +node PictureRotate +node PictureScale +node RandomHeapCookie +node WithHwAsp +node WithEffaceable +node WithFileSystem +node WithHwFlashNand +node WithHwFlashNor +node WithHwNvme +node WithLegacyPanicLogs diff --git a/lib/mib/mib.c b/lib/mib/mib.c new file mode 100644 index 0000000..d261bd8 --- /dev/null +++ b/lib/mib/mib.c @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2008, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +static struct mib_node *mib_find_node(u_int32_t oid, bool nofollow); + +/* + * Find a node in the MIB. + */ +static struct mib_node * +mib_find_node(u_int32_t oid, bool nofollow) +{ + void **cursor; + struct mib_node *node; + +restart: + node = NULL; + + /* Scan the static list for non-weak nodes */ + LINKER_SET_FOREACH(cursor, mib) { + node = (struct mib_node *)*cursor; + + if ((oid == node->node_oid) && !(node->node_type & kOIDWeak)) + goto found; + } + + /* and finally give weak nodes a chance */ + LINKER_SET_FOREACH(cursor, mib) { + node = (struct mib_node *)*cursor; + + if (oid == node->node_oid) + goto found; + } + + // not found + return NULL; + +found: + /* handle indirect nodes */ + if (!nofollow && (NULL != node) && (node->node_type == kOIDTypeOIDIndirect)) { + oid = node->node_data.v32; + goto restart; + } + return(node); +} + +/* + * Verify whether a node exists or not + */ +bool mib_exists(uint32_t oid, void *value) +{ + bool retVal = false; + struct mib_node *node; + if(NULL != (node = mib_find_node(oid, false))) { + retVal = true; + if(NULL != value) { + // value of node has been requested + switch (node->node_type & kOIDTypeMask) { + case kOIDTypeUInt32: + *(u_int32_t *)value = node->node_data.v32; + break; + case kOIDTypeInt32: + *(int32_t *)value = node->node_data.v32; + break; + case kOIDTypeUInt64: + *(u_int64_t *)value = node->node_data.v64; + break; + case kOIDTypeInt64: + *(int64_t *)value = node->node_data.v64; + break; + case kOIDTypeBoolean: + *(bool *)value = node->node_data.v_bool; + break; + case kOIDTypeString: + case kOIDTypeStruct: + *(void **)value = node->node_data.v_ptr; + break; + default: + panic("unexpected node type 0x%08x for oid 0x%08x", node->node_type, oid); + } + } + } + return retVal; +} +/* + * Look for a node and return its value if its present. + */ +bool +_mib_find(u_int32_t oid, u_int32_t node_type, void *value) +{ + struct mib_node *node; + + /* find the node */ + if (NULL == (node = mib_find_node(oid, false))) + return(false); + + /* if we have been given a type hint, check it against the node */ + if ((0 != node_type) && (node_type != (node->node_type & kOIDTypeMask))) { + panic("MIB node type mismatch: requested 0x%08x actual 0x%08x for oid 0x%08x", + node_type, node->node_type, oid); + return(false); + } + + if (node->node_type & kOIDFunction) { + /* call node handler function */ + node->node_data.v_func.func(oid, node->node_data.v_func.arg, value); + + } else if (node->node_type & kOIDDataIndirect) { + /* node data is indirected through v_ptr */ + switch (node->node_type & kOIDTypeMask) { + case kOIDTypeUInt32: + *(u_int32_t *)value = *(u_int32_t *)node->node_data.v_ptr; + break; + case kOIDTypeUInt64: + *(u_int64_t *)value = *(u_int64_t *)node->node_data.v_ptr; + break; + case kOIDTypeBoolean: + *(bool *)value = *(bool *)node->node_data.v_ptr; + break; + case kOIDTypeString: + case kOIDTypeStruct: + *(void **)value = *(void **)node->node_data.v_ptr; + break; + default: + panic("unexpected MIB node type 0x%08x for oid 0x%08x", node->node_type, oid); + } + + } else { + /* node data is in the structure */ + switch (node->node_type & kOIDTypeMask) { + case kOIDTypeUInt32: + *(u_int32_t *)value = node->node_data.v32; + break; + case kOIDTypeInt32: + *(int32_t *)value = node->node_data.v32; + break; + case kOIDTypeUInt64: + *(u_int64_t *)value = node->node_data.v64; + break; + case kOIDTypeInt64: + *(int64_t *)value = node->node_data.v64; + break; + case kOIDTypeBoolean: + *(bool *)value = node->node_data.v_bool; + break; + case kOIDTypeString: + case kOIDTypeStruct: + *(void **)value = node->node_data.v_ptr; + break; + default: + panic("unexpected node type 0x%08x for oid 0x%08x", node->node_type, oid); + } + } + return(true); +} + +/* + * Get the value of a node. Panic if it doesn't exist. + */ +void +_mib_get(u_int32_t oid, u_int32_t node_type, void *value) +{ + if (false == _mib_find(oid, node_type, value)) + panic("mib: oid 0x%08x type 0x%08x not found", oid, node_type); +} + +static struct mib_description * +mib_find_ident(u_int32_t oid) +{ + int i; + + for (i = 0; mib_desc[i].desc != NULL; i++) + if (mib_desc[i].oid == oid) + return(mib_desc + i); + return(NULL); +} + +static void +mib_find_oid_ident(u_int32_t oid, const char **subsystem, const char **node) +{ + struct mib_description *md;; + + *subsystem = "????"; + *node = "????"; + + if (NULL != (md = mib_find_ident(oid & OID_SUBSYSTEM_MASK))) { + *subsystem = md->desc; + + if (NULL != (md = mib_find_ident(oid))) + *node = md->desc; + } +} + +void +print_mib_node(struct mib_node *node) +{ + size_t ssize; + const char *s, *n; + u_int32_t ntype; + int cols; + char f = ' ', i = ' ', w = ' '; + + mib_find_oid_ident(node->node_oid, &s, &n); + + if (node->node_type & kOIDDataIndirect) { + i = 'I'; + } + + if (node->node_type & kOIDFunction) { + f = 'F'; + } + + if (node->node_type & kOIDWeak) { + w = 'W'; + } + + printf(" 0x%08x %c%c%c %s.%s ", node->node_oid, f, i, w, s, n); + cols = strlen(s) + strlen(n) + 16; + if (cols < 50) + printf("%*s", 53 - cols, "= "); + + ntype = node->node_type & kOIDTypeMask; + + switch (ntype) { + case kOIDTypeUInt32: + printf("0x%08x / %u / %d\n", + mib_get_u32(node->node_oid), + mib_get_u32(node->node_oid), + mib_get_u32(node->node_oid)); + break; + + case kOIDTypeInt32: + printf("0x%08x / %u / %d\n", + mib_get_s32(node->node_oid), + mib_get_s32(node->node_oid), + mib_get_s32(node->node_oid)); + break; + + case kOIDTypeUInt64: + printf("0x%016llx / %llu / %lld\n", + mib_get_u64(node->node_oid), + mib_get_u64(node->node_oid), + mib_get_u64(node->node_oid)); + break; + + case kOIDTypeInt64: + printf("0x%016llx / %llu / %lld\n", + mib_get_s64(node->node_oid), + mib_get_s64(node->node_oid), + mib_get_s64(node->node_oid)); + break; + + case kOIDTypeBoolean: + printf("%s\n", + mib_get_bool(node->node_oid) ? "true" : "false"); + break; + + case kOIDTypeString: + s = (const char *)mib_get_str(node->node_oid); + printf("%s\n", s); + break; + + case kOIDTypeOIDIndirect: + printf("-> 0x%08x\n", + node->node_data.v32); + break; + + default: + if (kOIDTypeStruct == ntype) { + ssize = node->node_type & kOIDStructSizeMask; + printf("struct\n"); + if (ssize > 0) + hexdump(mib_get_ptr(node->node_oid), (ssize <= 128) ? ssize : 128); + if (ssize > 128) + printf(" ...\n"); + break; + } + printf("unknown type 0x%08x\n", node->node_type); + break; + } +} + +int +do_mib(int argc, struct cmd_arg *args) +{ + void **cursor; + struct mib_node *node; + + printf("MIB dump:\n"); + + /* Scan the static list */ + /* XXX note that this will print duplicates for static nodes that are overridden */ + LINKER_SET_FOREACH(cursor, mib) { + node = (struct mib_node *)*cursor; + print_mib_node(node); + } + return(0); +} + diff --git a/lib/mib/mib_gen_def.awk b/lib/mib/mib_gen_def.awk new file mode 100644 index 0000000..4f00e1e --- /dev/null +++ b/lib/mib/mib_gen_def.awk @@ -0,0 +1,58 @@ +# Copyright (C) 2014 Apple, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple, Inc. +# +function mktemp(template, _cmd, _tmpfile) { + _cmd = "mktemp " template ".XXXXXX" + _cmd | getline _tempfile + close(_cmd) + return _tempfile +} + +BEGIN { + FS="[ \t]*" + if (ARGV[1] == "") { + print "ERROR: Missing path argument for output\n" + exit 1 + } + if (system("test -d " ARGV[1])) { + print "ERROR: " ARGV[1] " is not a directory" + exit 1 + } + deffile = mktemp(ARGV[1] "/mib_nodes.c") + print "/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n" > deffile + print "#include \n" >>deffile + print "#include \n" >>deffile + print "struct mib_description mib_desc[] = {\n" >> deffile + + ssnum = 0 + ssinc = 2 ^ 24 + nnum = 0 + nninc = 2 ^ 16 +} + +$1=="subsystem" { + subsystem = $2 + ssnum += ssinc + + printf "\t{ 0x%08x, \"%s\" },\n", ssnum, subsystem >> deffile +} + +$1=="node" { + node = $2 + type = $3 + nnum += nninc + + printf "\t{ 0x%08x, \"%s\" },\n", ssnum + nnum, node >> deffile +} + +END { + print "\t{ 0x00000000, NULL }\n" >> deffile + print "};\n" >> deffile + system("mv " deffile " " ARGV[1] "/mib_nodes.c") +} diff --git a/lib/mib/mib_gen_hdr.awk b/lib/mib/mib_gen_hdr.awk new file mode 100644 index 0000000..0125dc7 --- /dev/null +++ b/lib/mib/mib_gen_hdr.awk @@ -0,0 +1,53 @@ +# Copyright (C) 2014 Apple, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple, Inc. +# +function mktemp(template, _cmd, _tmpfile) { + _cmd = "mktemp " template ".XXXXXX" + _cmd | getline _tempfile + close(_cmd) + return _tempfile +} + +BEGIN { + FS="[ \t]*" + if (ARGV[1] == "") { + print "ERROR: Missing path argument for output\n" + exit 1 + } + if (system("test -d " ARGV[1])) { + print "ERROR: " ARGV[1] " is not a directory" + exit 1 + } + headerfile = mktemp(ARGV[1] "/mib_nodes.h") + print "/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n" > headerfile + + ssnum = 0 + ssinc = 2 ^ 24 + nnum = 0 + nninc = 2 ^ 16 +} + +$1=="subsystem" { + subsystem = $2 + ssnum += ssinc + + printf "#define kMIBSubsystem%s 0x%08x\n", subsystem, ssnum >> headerfile +} + +$1=="node" { + node = $2 + type = $3 + nnum += nninc + + printf "#define kMIB%s%s 0x%08x\n", subsystem, node, ssnum + nnum >> headerfile +} + +END { + system("mv " headerfile " " ARGV[1] "/mib_nodes.h") +} diff --git a/lib/mib/rules.mk b/lib/mib/rules.mk new file mode 100644 index 0000000..7777689 --- /dev/null +++ b/lib/mib/rules.mk @@ -0,0 +1,11 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBRARY_MODULES += lib/mib diff --git a/lib/net/arp.c b/lib/net/arp.c new file mode 100644 index 0000000..205a5b7 --- /dev/null +++ b/lib/net/arp.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +arp_cache_t arpcache; + +static int arp_transmit(bool reply,char* tomacaddr,uint32_t toip) +{ +//generate packet and send it down to the ethernet layer + mymbuf_t *packet; + char *data; + char dstmac[] = {0xff,0xff,0xff,0xff,0xff,0xff}; + uint32_t srcip; + + + packet = mbuf_initialize(28,14,4); //28byte arp, 14 ethernet, 4 ethernet trailer + data = mbuf_tail(packet,28); + *(uint16_t *)&data[ARP_OFFSET_HTYPE] = htons(1); //ethernet + *(uint16_t *)&data[ARP_OFFSET_PTYPE] = htons(0x0800); //ipv4 + data[ARP_OFFSET_HLEN] = 6; //macaddr is 6 bytes + data[ARP_OFFSET_PLEN] = 4; //ip is 4 bytes + *(uint16_t *)&data[ARP_OFFSET_OPER] = htons(reply ? 2 : 1); + + xp_getmac((uint8_t*)&data[ARP_OFFSET_SHA]); + + srcip = ipv4_get_ip(); + *(uint32_t *)&data[ARP_OFFSET_SHA+6] = htonl(srcip); + + if(tomacaddr == 0) { + memcpy(&data[ARP_OFFSET_SHA+10],"\0\0\0\0\0\0",6); + } else { + memcpy(&data[ARP_OFFSET_SHA+10],tomacaddr,6); + } + toip = htonl(toip); + memcpy(&data[ARP_OFFSET_SHA+16],&toip,4); + + add_eth_and_transmit(packet,dstmac,ETHERTYPE_ARP); + mbuf_destroy(packet); + return 0; +} +int arp_hash(uint32_t ip) +{ + return ip % ARP_CACHE_SIZE; +} + +int arp_cache_add(uint32_t ip, const char *mac) +{ + arp_cache_entry_t *ce = &arpcache.cache[arp_hash(ip)]; + if (ce->ip == 0 || ce->ip == ip) + goto update; + while (ce->next) { + ce = ce->next; + if(ce->ip == ip) + goto update; + } + // Not in the list, add a new entry + ce->next = malloc(sizeof(arp_cache_entry_t)); + ce = ce->next; + ce->next = 0; +update: + ce->ip = ip; + memcpy(ce->mac,mac,6); +// printf("arp: learned %#I at %M\n", &ce->ip, &ce->mac); + return 0; +} + +int arp_cache_get(uint32_t ip,char *mac) +{ + arp_cache_entry_t *ce = &arpcache.cache[arp_hash(ip)]; + + if(ip == ce->ip) + goto found; + while(ce->next) { + ce = ce->next; + if(ip == ce->ip) + goto found; + } + return -1; +found: +// printf("arp: found %#I at %M\n", &ce->ip, &ce->mac); + if (mac) + memcpy(mac,ce->mac,6); + return 0; +} + +void arp_cache_delete(void) +{ + arp_cache_entry_t *ce; + int i; + + for(i=0;inext; + free(ce); + ce = next; + } + } +} + + +void arp_dump_table(void) +{ + arp_cache_entry_t *ce; + int i; + + for(i=0;iip != 0) + printf("ip: %#I\tmac: %M\n", &ce->ip, &ce->mac); + ce = ce->next; + } + } +} + + +int arp_get_macaddr(uint32_t ip, char *outmac) +{ + if(arp_cache_get(ip,outmac) < 0) { +// printf("Sending request for 0x%x\n",ip); + arp_transmit(false,0,ip); + return -1; + } + return 0; +} + +/* send arp requests until it is satisfied or timeout */ +int arp_fill(uint32_t ip, utime_t timeout) +{ + utime_t t; + + t = system_time(); + do { + if (arp_cache_get(ip, NULL) >= 0) + return 0; + + arp_transmit(false, 0, ip); + task_sleep(100*1000); + } while (system_time() - t < timeout); + + return -1; +} + +static int arp_workloop(char *packet,int offset,int len,void *prevlayerdata) +{ + uint16_t htype,ptype; + uint8_t hlen,plen; + uint16_t oper; + unsigned char *buffer = (unsigned char *)packet+offset; + uint32_t itoip,ifromip; + unsigned char *tmp; + + htype = ntohs(*(uint16_t*)&buffer[ARP_OFFSET_HTYPE]); + ptype = ntohs(*(uint16_t*)&buffer[ARP_OFFSET_PTYPE]); + hlen = buffer[ARP_OFFSET_HLEN]; + plen = buffer[ARP_OFFSET_PLEN]; + oper = ntohs(*(uint16_t*)&buffer[ARP_OFFSET_OPER]); + +// printf("arp: 0x%x 0x%x %d %d op %d\n", htype, ptype, hlen, plen, oper); + + if ((htype != 1) || /* ethernet */ + (ptype != 0x800) || /* IPv4 */ + (hlen != 6) || /* 6-byte MAC */ + (plen != 4)) { /* 4-byte protocol address */ +// printf("Not ethernet. Bailing\n"); + return -1; + } + tmp = &buffer[ARP_OFFSET_SHA+hlen]; + ifromip = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3]; + + tmp = &buffer[ARP_OFFSET_SHA+(2*hlen)+plen]; + itoip = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3]; + +// printf("arp: from %#I to %#I\n", &ifromip, &itoip); + + //someone sent out their address + arp_cache_add(ifromip,(char *)&buffer[ARP_OFFSET_SHA]); + + if (oper == 1) { + if (itoip == ipv4_get_ip()) { +// printf("arp: sending reply to %#I\n", &ifromip); + arp_transmit(true,(char *)&buffer[ARP_OFFSET_SHA],ifromip); + } else { +// printf("arp: dest %I not us\n", &itoip); + } + } + + return 0; +} + +int arp_layer(bool on) +{ + static int id = -1; + if(on) { + if(id == -1) { + memset(&arpcache,0,sizeof(arpcache)); + id = registerEtherTypeHandler(ETHERTYPE_ARP,arp_workloop); + } + } else { + if(id >= 0) { + unregisterEtherTypeHandler(id); + arp_cache_delete(); + id = -1; + } + } + return 0; +} diff --git a/lib/net/callbacks.c b/lib/net/callbacks.c new file mode 100644 index 0000000..c03d94b --- /dev/null +++ b/lib/net/callbacks.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include + +int registerCallback(callbacks_t *cbs,int port,callback_handler cb) +{ + listentry_t *cur = cbs->first; + int i = 1; + + while(cur && cur->next) { + cur = cur->next; + i++; + } + if(!cur) { //no elems + cur = cbs->first = malloc(sizeof(listentry_t)); + i = 0; //first. + } else { + cur->next = malloc(sizeof(listentry_t)); + cur = cur->next; + } + cur->next = 0; + cur->callback = cb; + cur->port = port; + cur->cb_id = i; + return cur->cb_id; +} +int unregisterCallback(callbacks_t *cbs,int cb_id) +{ + listentry_t *cur = cbs->first; + listentry_t *prev = 0; + + while(cur) { + if(cur->cb_id == cb_id) { + if(prev == 0) { + cbs->first = cur->next; + } else { + prev->next = cur->next; + } + free(cur); + return 0; + } + prev = cur; + cur = cur->next; + } +return -1; +} + +callback_handler find_callback(callbacks_t *cbs,int port) +{ + listentry_t *cur = cbs->first; + + while(cur) { + if(cur->port == port) { + return cur->callback; + } + cur = cur->next; + } +return 0; + + +} diff --git a/lib/net/debug.c b/lib/net/debug.c new file mode 100644 index 0000000..f869e3b --- /dev/null +++ b/lib/net/debug.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +int do_net(int argc, struct cmd_arg *args) +{ + if (argc < 2) { + puts("not enough arguments.\n"); +usage: + printf("%s init\n", args[0].str); + printf("%s arp\n", args[0].str); + return -1; + } + + if (strcmp("init", args[1].str) == 0) { + start_network_stack(); + } else if (strcmp("arp", args[1].str) == 0) { + arp_dump_table(); + } else { + puts("unrecognized command.\n"); + goto usage; + } + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(net, do_net, "network/ethernet stuff", NULL); + +#endif diff --git a/lib/net/ethernet.c b/lib/net/ethernet.c new file mode 100644 index 0000000..acaf94a --- /dev/null +++ b/lib/net/ethernet.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +//a very minimal Ethernet stack. +//protocol handlers can register for a certain service, and this layer will call their functions when a packet of that type arrive +#include +#include +#include +#include +#include +#include +#include + +//For the different layers +#include +#include +#include +#include + + +static callbacks_t ethercb; + +int registerEtherTypeHandler(int ethertype,callback_handler cb) +{ + return registerCallback(ðercb,ethertype,cb); +} + +int unregisterEtherTypeHandler(int id) +{ + return unregisterCallback(ðercb,id); +} + + +static int parseEtherHeader(char *buff,int len,uint16_t *ethertype) +{ + + //XXX: Check that the destination macaddress matches. + if(ethertype) { + *ethertype = ntohs(*(uint16_t *)(buff+12)); + } + return 0; +} + +void ethernet_init(void) +{ +} + +void ethernet_uninit(void) +{ +} + +void ethernet_input(mymbuf_t *inputbuf) +{ + uint16_t ethertype; + int len; + char *rawbuf; + callback_handler cb; + + len = mbuf_getlength(inputbuf); + rawbuf = mbuf_getlinear(inputbuf); + //This fails if the packet was not directed to us (ie, wrong macaddr) + if(parseEtherHeader(rawbuf,len,ðertype) == 0) { + cb = find_callback(ðercb,ethertype); + if(cb) { + cb(rawbuf,ETHERNET_OFFSET,len,0); + } else { +// printf("Unsupported ethertype 0x%x\n",ethertype); + } + } +} + +#if 0 +//Called from timer (background) or from tsys commandprompt if not background +//Handles maxpkt packages before returning. (Or until it would have to block) +void ethernet_workloop(struct callout *c, void *param) +{ + int i; + uint16_t ethertype; + int len; + char *rawbuf; + callback_handler cb; + int maxpkt = (int)param; +// utime_t now; +// + + callout_reset(c, 0); + + if(!buf) + return; + + for(i = 0;i +#include +#include +#include +#include + +static callbacks_t icmpcb; + +static uint16_t icmp_checksum(uint16_t *data,int len) +{ + uint32_t sum =0; + uint16_t res; + + for(int i=0;i> 16); + res = ~sum; + return res; +} +static int icmp_send_echo(uint32_t toip,uint16_t identifier, uint16_t sequence,char *extradata,int datalen) +{ + mymbuf_t *packet; + char *data; + int ret; + + packet = mbuf_initialize(8+datalen,14+20,0); + data = mbuf_tail(packet,8+datalen); + + data[0] = data[1] = 0; //type and code + data[2] = data[3] = 0; //checksum, will be calculated later + *(uint16_t *)&data[4] = htons(identifier); + *(uint16_t *)&data[6] = htons(sequence); + memcpy(&data[8],extradata,datalen); + *(uint16_t *)&data[2] = icmp_checksum((uint16_t *)data,(8+datalen)>>1); + + ret = transmit_and_add_ipv4(packet,toip,IPV4_ICMP); + mbuf_destroy(packet); + return ret; +} + + +static int icmp_workloop(char *data, int offset, int len,void *srcip) +{ + char *buffer = data+offset; + uint8_t type; + uint8_t code; + uint16_t checksum; + + type = buffer[0]; + code = buffer[1]; + checksum = ntohs(*(uint16_t *)&(buffer[2])); + + switch(type) { + case ICMP_ECHO: + { + uint16_t identifier = ntohs(*(uint16_t *)&(buffer[4])); + uint16_t sequence = ntohs(*(uint16_t *)&(buffer[6])); + char *echodata = buffer+8; + + // printf("Echo %s: ident: 0x%x,sequence: 0x%d\n",(data == ICMP_ECHO) ? "echo" : "reply",identifier,sequence); + icmp_send_echo((uint32_t)srcip,identifier,sequence,echodata,len-offset-8); + } + break; + default: + printf("Unsupported ICMP(%d)\n",type); + } + return 0; +} +int icmp_layer(bool on) +{ + static int id = -1; + if(on) { + if(id == -1) { + id = registerIPV4Handler(IPV4_ICMP,icmp_workloop); + } + } else { + if(id >= 0) { + unregisterIPV4Handler(id); + id = -1; + } + } + return 0; +} +//Just registers a ICMP handler. +int registerICMPHandler(int messagetype,callback_handler cb) +{ + return registerCallback(&icmpcb,messagetype,cb); +} + +int unregisterICMPHandler(int id) +{ + return unregisterCallback(&icmpcb,id); +} diff --git a/lib/net/ipv4.c b/lib/net/ipv4.c new file mode 100644 index 0000000..9b82c77 --- /dev/null +++ b/lib/net/ipv4.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +static callbacks_t ipcb; +static uint32_t sCurrentIP; + + +static int calculate_ipv4_checksum(uint16_t *data, int len) +{ + uint32_t sum = 0; + uint16_t res; + for(int i=0;i> 16); + res = ~sum; + return res; +} +int transmit_and_add_ipv4(mymbuf_t *mbuf,uint32_t dest,int protocol) +{ + int datalen; + uint16_t *header; + char outmac[6]; + uint32_t source; + + datalen = mbuf_getlength(mbuf); + if(datalen > 1480) { + dprintf(DEBUG_INFO, "ipv4: fragmented ip packages not supported\n"); + return -1; + } + header = (uint16_t *)mbuf_head(mbuf,20); + if(!header) { + dprintf(DEBUG_INFO, "ipv4: No room to prepend the ipv4 header\n"); + return -1; + } + header[0] = htons((0x4 << 12) | (5 << 8) ); + header[1] = htons(datalen+20); + header[2] = htons(0xBEEF); + header[3] = 0; + header[4] = htons((0xff << 8) | ((protocol & 0xff ))); + header[5] = 0; //cksum + + source = ipv4_get_ip(); + char *ip = (char*)&header[6]; + ip[0] = (source & 0xff000000) >> 24; + ip[1] = (source & 0xff0000) >> 16; + ip[2] = (source & 0xff00) >> 8; + ip[3] = (source & 0xff); + + ip = (char*)&header[8]; + ip[0] = (dest & 0xff000000) >> 24; + ip[1] = (dest & 0xff0000) >> 16; + ip[2] = (dest & 0xff00) >> 8; + ip[3] = (dest & 0xff); + + header[5] = (calculate_ipv4_checksum(header,10)); + if(arp_get_macaddr(dest,outmac) < 0) { + dprintf(DEBUG_SPEW, "ipv4: No mac address available for 0x%x, dropping and requesting mac for that host.\n",dest); + return -1; + } + add_eth_and_transmit(mbuf,outmac,ETHERTYPE_IPV4); + + return 0; +} + +void ipv4_set_ip(uint32_t ip) +{ + char ipstr[32]; + ip2str((uint8_t *)&ip, ipstr, 32); + dprintf(DEBUG_INFO, "Setting ip to %s\n", ipstr); + sCurrentIP = ip; +} +//Returns our ip in host order. +uint32_t ipv4_get_ip() +{ + return sCurrentIP; +} + +//Called by the ethernet layer when a IPV4 packet was received. +static int ipv4_workloop(char *data,int offset, int len,void *unused) +{ + int headerlen; + int totallen; + int ttl,flags,cksum,protocol; +// char sourceip[16],destip[16]; + char *buf = data+offset; + callback_handler cb; + uint32_t srcip; +// utime_t perftime = system_time(); + + if(((buf[0] & 0xf0)>>4) != 0x4) { + printf("not ipv4 (0x%x)\n",buf[0]&0xf0); + return -1; + } + headerlen = buf[0] & 0xf; + totallen = ntohs(*(uint16_t*)&buf[2]); + flags = buf[6] & 0x7; + if(flags) { + dprintf(DEBUG_SPEW, "ipv4: Fragmented/Packets with flags not supported (0x%x)\n",flags); + return -1; + } + ttl = buf[8]; + protocol = buf[9]; + cksum = ntohs(*(uint16_t*)&buf[9]); +// ipv42str(&buf[12],sourceip); +// ipv42str(&buf[16],destip); +// printf("IPV4 %s -> %s, protocol: %d( headerlen: %d, totallen: %d)\n",sourceip,destip,protocol,headerlen,totallen); + cb = find_callback(&ipcb,protocol); + if(!cb) { +// dprintf(DEBUG_SPEW, "ipv4: Unsupported protocol(0x%x)\n",protocol); + return -1; + } + srcip = buf[12] << 24 | buf[13] << 16 | buf[14] << 8 | buf[15]; + cb(data,offset+(headerlen*sizeof(4)),len,(void*)srcip); +// printf("ipv4 took %ld usec\n", system_time() - perftime); + + return 0; +} + +int ipv4_layer(bool on) +{ + static int id = -1; + if(on) { + if(id == -1) { + id = registerEtherTypeHandler(ETHERTYPE_IPV4,ipv4_workloop); + } + } else { + if(id >= 0) { + unregisterEtherTypeHandler(id); + id = -1; + } + } + return 0; +} + +int registerIPV4Handler(int protocol,callback_handler handler) +{ + return registerCallback(&ipcb,protocol,handler); +} + +int unregisterIPV4Handler(int id) +{ + return unregisterCallback(&ipcb,id); +} diff --git a/lib/net/mbuf.c b/lib/net/mbuf.c new file mode 100644 index 0000000..87f6ced --- /dev/null +++ b/lib/net/mbuf.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include + +#ifndef CPU_CACHELINE_SIZE +# define CPU_CACHELINE_SIZE 32 +#endif + +mymbuf_t * mbuf_initialize(int packetsize,int header,int tail) +{ + mymbuf_t *p = calloc(1, sizeof(mymbuf_t)); + + p->primarydata = memalign(packetsize + header+tail, CPU_CACHELINE_SIZE); + p->offset = header; + p->allocated_length = packetsize+header+tail; + p->current_length = 0; + return p; +} + +char *mbuf_head(mymbuf_t *buffer,int len) +{ +// mbufentry_t **curr = &buffer->first; +// mbufentry_t *last; + + if(len <= buffer->offset && buffer->first == 0) { + char *ret; + //We have space in our buffer, let's just decrease offset and copy the data in + ret = (buffer->primarydata + buffer->offset)-len; + buffer->offset -= len; + buffer->current_length += len; + return ret; + } else { + printf("Request for %d bytes, only %d available\n",len,buffer->offset); + /* + while((*curr)->next) { + curr = &(*curr)->next; + } + // first element + if(*curr == 0) { + buffer->first = malloc(sizeof(mbufentry_t)); + last = buffer->first; + } else { + last = (*curr)->next = malloc(sizeof(mbufentry_t)); + } + last->len = len; + last->data = malloc(len); + last->flag = ENTRY_FLAG_ALLOCATED; + last->next = 0; + memcpy(last->data,indata,len); + buffer->length += len; +*/ + } + return 0; +} + +char *mbuf_tail(mymbuf_t *buffer,int len) +{ + if(buffer->offset+buffer->current_length+len <= buffer->allocated_length) { + char *ret; + ret = buffer->primarydata+buffer->offset + buffer->current_length; + buffer->current_length += len; + return ret; + } else { + return 0; + } +} + +int mbuf_copy(mymbuf_t *dest, const mymbuf_t *src) +{ + if (dest->allocated_length < src->current_length) + return -1; + + dest->offset = 0; + dest->current_length = src->current_length; + memcpy(dest->primarydata, src->primarydata + src->offset, dest->current_length); + + return 0; +} + +int mbuf_getlength(mymbuf_t *buffer) +{ + return buffer->current_length; +} +int mbuf_getallocatedlength(mymbuf_t *buffer) +{ + return buffer->allocated_length; +} + +void mbuf_setlength(mymbuf_t *buffer,int length) +{ + buffer->current_length = length; +} +void mbuf_setoffset(mymbuf_t *buffer,int offset) +{ + buffer->offset = offset; +} + +char *mbuf_getlinear(mymbuf_t *buf) +{ + if(buf->first) { + printf("getlinjear: not supported\n"); + return 0; + } + return buf->primarydata+buf->offset; + +} +void mbuf_destroy(mymbuf_t *buff) +{ + if(buff->first) { + printf("Not supported\n"); + return; + } + free(buff->primarydata); + free(buff); +} diff --git a/lib/net/net.c b/lib/net/net.c new file mode 100644 index 0000000..e086ebc --- /dev/null +++ b/lib/net/net.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +//For the different layers +#include +#include +#include +#include + +#include + +struct callout ethernet_cb; +static bool netstack_initialized = false; + +int start_network_stack(void) +{ + if (netstack_initialized) + return 0; + + dprintf(DEBUG_INFO, "starting net stack\n"); + + /* get all of the environment variables we need up front */ + uint32_t ipaddr; + uint8_t ethaddr[6]; + + if (env_get_ipaddr("ipaddr", &ipaddr) < 0) { + printf("ipaddr environment variable not set or malformed, cannot start net stack\n"); + return -1; + } + + if (env_get_ethaddr("ethaddr", ethaddr)) { + printf("ethaddr environment variable not set or malformed, cannot start net stack\n"); + return -1; + } + + ethernet_init(); + xp_initialize(); + //YUCK! XXX: TODO: + ipv4_layer(true); + + ipv4_set_ip(htonl(ipaddr)); + arp_layer(true); + icmp_layer(true); + udp_layer(true); + +#if WITH_HW_ETHERNET + dprintf(DEBUG_INFO, "starting ethernet\n"); + ethstat_t *eth = eth_get_handle(); + + eth_setmacaddr(eth, (char *)ethaddr); + eth_start(eth); +#endif + +#if 0 + /* start the ethernet work loop */ + callout_enqueue(ðernet_cb, 1000, ethernet_workloop, (void *)100); +#endif + + netstack_initialized = true; + + /* gratuitous arp */ + char mac[6]; + arp_get_macaddr(ipv4_get_ip(), mac); + + return 0; +} + +int stop_network_stack(void) +{ + if (!netstack_initialized) + return 0; + +#if WITH_HW_ETHERNET + ethstat_t *eth = eth_get_handle(); + + eth_stop(eth); +#endif + + ipv4_layer(false); + arp_layer(false); + icmp_layer(false); + udp_layer(false); + ethernet_uninit(); + netstack_initialized = false; + + return 0; +} + + +/* utility routines for dealing with ip and mac address strings */ +void mac2str(uint8_t mac[6], char *ascii, size_t size) +{ + snprintf(ascii, size, "%02x:%02x:%02x:%02x:%02x:%02x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); +} + +void ip2str(const uint8_t *ip, char *str, size_t size) +{ + snprintf(str, size, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]); +} + diff --git a/lib/net/rules.mk b/lib/net/rules.mk new file mode 100644 index 0000000..1d7e2c7 --- /dev/null +++ b/lib/net/rules.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_NET=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/arp.o \ + $(LOCAL_DIR)/callbacks.o \ + $(LOCAL_DIR)/ethernet.o \ + $(LOCAL_DIR)/icmp.o \ + $(LOCAL_DIR)/ipv4.o \ + $(LOCAL_DIR)/mbuf.o \ + $(LOCAL_DIR)/net.o \ + $(LOCAL_DIR)/udp.o \ + $(LOCAL_DIR)/xp.o \ + $(LOCAL_DIR)/debug.o diff --git a/lib/net/udp.c b/lib/net/udp.c new file mode 100644 index 0000000..f2859a0 --- /dev/null +++ b/lib/net/udp.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include + +static callbacks_t udpcb; + +static int udp_workloop(char *data, int offset,int len,void* srcip) +{ + uint16_t sourceport,destport; + uint16_t length,checksum; + char *buffer = data+offset; + callback_handler cb; + udpinfo_t replyinfo; +// utime_t perftime = system_time(); + + sourceport = ntohs(*(uint16_t *)&buffer[0]); + destport = ntohs(*(uint16_t *)&buffer[2]); + + length = ntohs(*(uint16_t *)&buffer[4]); + checksum = ntohs(*(uint16_t *)&buffer[6]); + + cb = find_callback(&udpcb,destport); + if(!cb) { +// printf("No listener on port %d\n"); + } else { + replyinfo.srcip = (uint32_t)srcip; + replyinfo.srcport = sourceport; + replyinfo.length = length - 8; + cb(data,offset+8,len,&replyinfo); + } + //printf("udp handler took %ld usec\n", system_time() - perftime); + + return 0; +} + + +int udp_layer(bool on) +{ + static int id = -1; + if(on) { + if(id == -1) { + id = registerIPV4Handler(IPV4_UDP,udp_workloop); + } + } else { + if(id >= 0) { + unregisterIPV4Handler(id); + id = -1; + } + } + return 0; +} + +int transmit_udp(mymbuf_t *packet, uint32_t toip,int toport, int fromport) +{ + uint16_t *udpbuf; + int len; + + udpbuf = (uint16_t *) mbuf_head(packet,8); + len = mbuf_getlength(packet); + if(!udpbuf) { + printf("No room for udp package. bailing\n"); + return -1; + } + udpbuf[0] = htons(fromport); + udpbuf[1] = htons(toport); + udpbuf[2] = htons(len); + //Checksum for UDP is ..crazy? + //XXX: TODO: Checksum! + udpbuf[3] = 0; + return transmit_and_add_ipv4(packet,toip,IPV4_UDP); +} +int registerUDPHandler(int port,callback_handler cb) +{ + return registerCallback(&udpcb,port,cb); +} + +int unregisterUDPHandler(int id) +{ + return unregisterCallback(&udpcb,id); + +return 0; +} diff --git a/lib/net/xp.c b/lib/net/xp.c new file mode 100644 index 0000000..f992cef --- /dev/null +++ b/lib/net/xp.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* This file contains platform abstractions, implement the required functions for your platform */ +#include +#include +#include +#include +#include + +void *ethptr; + +/* ethernet card is giving us info */ +void xp_packet_input(void *ethptr, mymbuf_t *inputbuf) +{ +// printf("xp_packet_input: buf %p, len %d\n", inputbuf, mbuf_getlength(inputbuf)); + ethernet_input(inputbuf); +} + +#if 0 +mymbuf_t *xp_get_packet(mymbuf_t *inputbuf) +{ + mymbuf_t *mb; + char *buffer; + int len = 1500; + if(!inputbuf) { + mb = mbuf_initialize(1500,0,0); + } else { + if(mbuf_getallocatedlength(inputbuf) < 1500) { + return NULL; + } + mb = inputbuf; + } + buffer = mbuf_getlinear(mb); + + if(eth_getpkt(ethptr,buffer,&len) < 0) { + if(inputbuf != mb) { + mbuf_destroy(mb); + } + return 0; + } + mbuf_setlength(mb,len); + return mb; +} +#endif + +int xp_transmit_packet(mymbuf_t *buffer) +{ + char *rawdata = mbuf_getlinear(buffer); + + if(!rawdata) { + printf("Handle linked mbuf's\n"); + return -1; + } + eth_output_packet(ethptr,rawdata,mbuf_getlength(buffer),0); +return 0; +} + +int xp_getmac(uint8_t *addr) +{ + eth_getmacaddr(ethptr,(char *)addr); +return 0; +} + +int xp_initialize(void) +{ + ethptr = eth_get_handle(); + return 0; +} + + diff --git a/lib/nonce/library.mk b/lib/nonce/library.mk new file mode 100644 index 0000000..785c98d --- /dev/null +++ b/lib/nonce/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBNONCE_DIR := $(GET_LOCAL_DIR) +LIBNONCE_BUILD := $(call TOLIBDIR,$(LIBNONCE_DIR)/LIBNONCE.a) +COMMONLIBS += LIBNONCE + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBNONCE_OBJS := $(LIBNONCE_DIR)/nonce.o + +LIBNONCE_OBJS := $(call TOLIBOBJDIR,$(LIBNONCE_OBJS)) + +ALL_DEPS += $(LIBNONCE_OBJS:%o=%d) + +$(LIBNONCE_BUILD): $(LIBNONCE_OBJS) + +endif diff --git a/lib/nonce/nonce.c b/lib/nonce/nonce.c new file mode 100644 index 0000000..cd86115 --- /dev/null +++ b/lib/nonce/nonce.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *kBootNoncePropertyKey = "com.apple.System.boot-nonce"; +static const size_t kExpectedNonceLength = (sizeof(uint64_t) * 2) + 2; + +int +mobile_ap_nonce_consume_nonce(uint64_t *nonce) +{ + const char* nonce_string; + size_t nonce_length = 0; + int result = 0; + + ASSERT(nonce != NULL); + + *nonce = 0; + nonce_string = env_get(kBootNoncePropertyKey); + + if (nonce_string != NULL) { + dprintf(DEBUG_SPEW, "%s: nonce_string='%s'\n", __func__, nonce_string); + nonce_length = strlen(nonce_string); + dprintf(DEBUG_SPEW, "%s: nonce_length='%zu'\n", __func__, nonce_length); + if (nonce_length == kExpectedNonceLength) { + *nonce = strtoull(nonce_string, NULL, 16); + result = 1; + } else { +#if DEBUG_BUILD + dprintf(DEBUG_CRITICAL, + "%s: nonce value has invalid length %zu %s\n", + __func__, nonce_length, nonce_string); +#else + dprintf(DEBUG_CRITICAL, + "%s: nonce value has invalid length\n", + __func__); +#endif + } + + // The nonce environment variable exists. + // Remove it whether it is valid or not. + if (env_unset(kBootNoncePropertyKey)) { + // Save the updated nvram contents. + if (nvram_save() != 0) { + dprintf(DEBUG_CRITICAL, + "%s: Could not save nvram contents\n", + __func__); + } + } else { + dprintf(DEBUG_CRITICAL, + "%s: could not clear nonce\n", + __func__); + } + } + + return result; +} + + +// ============================================================================= + +static void +print_usage(int argc, struct cmd_arg *args) +{ + printf("USAGE: %s \n\n", ((0 < argc) ? args[0].str : "?")); + printf(" Where is one of following\n\n"); + printf(" get - read the nonce and clear it, then report its hash and value\n"); + printf(" if no nonce was previously set, one is generated\n"); + if (mib_get_bool(kMIBTargetWithEffaceable)) { + return; + } + printf(" clear - clear the nonce\n"); + printf(" consume - read the raw nonce, report its hash and value, and comsume it\n"); + printf(" read - read the raw nonce, report its hash and value, but don't consume it\n"); +} + +static void +print_nonce_and_hash(uint64_t nonce) +{ + uint8_t hash[HASH_OUTPUT_SIZE]; + int idx; + + hash_calculate(&nonce, sizeof(nonce), hash, sizeof(hash)); + + printf("boot-nonce: 0x%016llx\n", nonce); + printf("boot-nonce hash:"); + for (idx = 0; idx < HASH_OUTPUT_SIZE; idx++) { + printf(" %02X", hash[idx]); + } + printf("\n"); +} + +static int +get_nonce(void) +{ + uint64_t nonce; + + nonce = platform_get_nonce(); + print_nonce_and_hash(nonce); + + return 0; +} + +static int +clear_nonce(void) +{ + const char* nonce_string; + + nonce_string = env_get(kBootNoncePropertyKey); + if (nonce_string != NULL) { + if (env_unset(kBootNoncePropertyKey)) { + // Save the updated nvram contents. + if (nvram_save() == 0) { + printf("Boot nonce cleared\n"); + } else { + printf("Failed to update nvram\n"); + } + } else { + printf("Failed to clear boot nonce\n"); + } + } else { + printf("Boot nonce not found\n"); + } + + return 0; +} + +static int +consume_nonce(void) +{ + uint64_t nonce; + + nonce = platform_consume_nonce(); + print_nonce_and_hash(nonce); + + return 0; +} + +static int +read_nonce(void) +{ + uint64_t nonce; + const char* nonce_string; + size_t nonce_length = 0; + + nonce_string = env_get(kBootNoncePropertyKey); + if (nonce_string != NULL) + nonce_length = strlen(nonce_string); + + if (nonce_length != 0) { + // The nonce string must be the exact length of a + // 64-bit integer plus 2 for the "0x" prefix. + if (nonce_length == kExpectedNonceLength) { + nonce = strtoull(nonce_string, NULL, 16); + print_nonce_and_hash(nonce); + } else { + printf("Boot nonce value (%s) has invalid length %zu should be %zu", + nonce_string, nonce_length, kExpectedNonceLength); + } + } else { + printf("Boot nonce not found\n"); + } + + return 0; +} + +int +do_nonce(int argc, struct cmd_arg *args) +{ + int err; + bool with_effaceable = mib_get_bool(kMIBTargetWithEffaceable); + + if (1 >= argc) { + print_usage(argc, args); + err = 0; + } else if (0 == strcmp("get", args[1].str)) { + err = get_nonce(); + } else if (!with_effaceable && (0 == strcmp("clear", args[1].str))) { + err = clear_nonce(); + } else if (!with_effaceable && (0 == strcmp("consume", args[1].str))) { + err = consume_nonce(); + } else if (!with_effaceable && (0 == strcmp("read", args[1].str))) { + err = read_nonce(); + } else { + print_usage(argc, args); + printf("unrecognized subcommand\n"); + err = -1; + } + + return err; +} + diff --git a/lib/nonce/rules.mk b/lib/nonce/rules.mk new file mode 100644 index 0000000..6b02134 --- /dev/null +++ b/lib/nonce/rules.mk @@ -0,0 +1,12 @@ +# Copyright (C) 2014 Apple, Inc. All rights reserved. +# +# This document is the property of Apple, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple, Inc. +# + +OPTIONS += WITH_NONCE=1 +LIBRARY_MODULES += lib/nonce diff --git a/lib/nvram/fuzz.c b/lib/nvram/fuzz.c new file mode 100644 index 0000000..390a6cf --- /dev/null +++ b/lib/nvram/fuzz.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +struct blockdev *create_mock_blockdev(const char *name, const char *filename, uint32_t block_size); + +int do_printenv(int argc, void *args); + +int fuzz_main(const char *filename) +{ + struct blockdev *bdev; + int result; + + bdev = create_mock_blockdev("nvram", filename, 1); + if (bdev != NULL) + register_blockdev(bdev); + + result = nvram_load(); + if (result != 0) { + do_printenv(0, NULL); + nvram_save(); + } + + return result; +} + +// Mock for lib/env +bool +env_blacklist(const char *name, bool write) +{ + return false; +} + +bool +env_blacklist_nvram(const char *name) +{ + return false; +} diff --git a/lib/nvram/library.mk b/lib/nvram/library.mk new file mode 100644 index 0000000..184d5d5 --- /dev/null +++ b/lib/nvram/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBNVRAM_DIR := $(GET_LOCAL_DIR) +LIBNVRAM_BUILD := $(call TOLIBDIR,$(LIBNVRAM_DIR)/LIBNVRAM.a) +COMMONLIBS += LIBNVRAM + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBNVRAM_OBJS := $(LIBNVRAM_DIR)/nvram.o + +LIBNVRAM_OBJS := $(call TOLIBOBJDIR,$(LIBNVRAM_OBJS)) + +ALL_DEPS += $(LIBNVRAM_OBJS:%o=%d) + +$(LIBNVRAM_BUILD): $(LIBNVRAM_OBJS) + +endif diff --git a/lib/nvram/nvram.c b/lib/nvram/nvram.c new file mode 100644 index 0000000..9c1a8fc --- /dev/null +++ b/lib/nvram/nvram.c @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2007-2012 Apple Inc. All rights reserved. + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Regardless of whether it is NOR or NAND providing the backing + * store, NVRAM_BANK_SIZE controls default size of each nvram bank. + */ +#define NVRAM_BANK_SIZE 0x2000 + +/* + * Support for CHRP NVRAM hosting our environment. + */ + +/* this is a somewhat arbitrary and historical value */ +#define NVRAM_MAX_ENV_PARTITION 0x7f0 + +/* Panic info partition */ +#define NVRAM_PANIC_NAME "APL,OSXPanic" +#define NVRAM_PANIC_NAME_TRUNCATED "APL,OSXPani" +#define NVRAM_PANIC_SIZE 0x800 +#define NVRAM_PANIC_SIG 0xa1 + +struct chrp_nvram_header { + uint8_t sig; + uint8_t cksum; + uint16_t len; + char name[12]; + uint8_t data[0]; +}; + +struct apple_nvram_header { + struct chrp_nvram_header chrp; + uint32_t adler; + uint32_t generation; + uint8_t padding[8]; +}; + +/* in memory representation of a nvram partition */ +struct nvram_partition { + struct list_node node; + + uint8_t chrp_sig; + size_t len; + uint8_t *data; + + char name[16]; +}; + +/* in memory representation of a nvram bank (may be multiple ones) */ +struct nvram_bank { + struct list_node node; + + struct list_node part_list; + struct blockdev *dev; + off_t offset; + size_t len; + + uint32_t generation; +}; + +static struct list_node nvram_bank_list = LIST_INITIAL_VALUE(nvram_bank_list); +static struct nvram_bank *newest_bank; +static struct nvram_bank *oldest_bank; + +static uint8_t chrp_checksum(const struct chrp_nvram_header *hdr) +{ + uint16_t sum; + const uint8_t *p; + + /* checksum the header (minus the checksum itself) */ + sum = hdr->sig; + for (p = (const uint8_t *)&hdr->len; p < hdr->data; p++) + sum += *p; + while (sum > 0xff) + sum = (sum & 0xff) + (sum >> 8); + return sum; +} + +static struct nvram_partition *find_part_in_bank(const struct nvram_bank *bank, const char *name) +{ + struct nvram_partition *part; + + list_for_every_entry(&bank->part_list, part, struct nvram_partition, node) { + if (!strcmp(name, part->name)) + return part; + } + return NULL; +} + +/* find the oldest and newest banks */ +static void sort_bank_age(void) +{ + struct nvram_bank *bank; + + list_for_every_entry(&nvram_bank_list, bank, struct nvram_bank, node) { + if (!oldest_bank || bank->generation < oldest_bank->generation) + oldest_bank = bank; + if (!newest_bank || bank->generation > newest_bank->generation) + newest_bank = bank; + } +} + +static int load_bank_partitions(struct nvram_bank *bank, uint8_t *buf) +{ + struct chrp_nvram_header *hdr; + struct nvram_partition *part = NULL; + size_t offset; + + offset = 0x20; + while ((offset + sizeof(struct chrp_nvram_header)) <= bank->len) { + hdr = (struct chrp_nvram_header *)(buf + offset); + +#if 0 + dprintf(DEBUG_SPEW, "nvram: load_bank_partitions: looking at header at offset %u\n", offset); + dhexdump(DEBUG_SPEW, hdr, sizeof(*hdr)); +#endif + + /* verify the checksum */ + if (hdr->cksum != chrp_checksum(hdr)) { +#if !NVRAM_NOCHECKSUM + printf("load_bank_partitions: checksum failure\n"); + goto error_exit; +#endif + } + + /* is it free space? if so, we're done */ + if (hdr->sig == 0x7f) + break; + + /* see if the length makes sense */ + if (((hdr->len * 0x10) + offset > bank->len) || (hdr->len < 1)) { + printf("load_bank_partitions: partition len out of range\n"); + goto error_exit; + } + + /* skip it if it's a known corrupted partition name */ + if (!memcmp(hdr->name, NVRAM_PANIC_NAME_TRUNCATED, 12)) { + /* The last byte shouldn't have been terminated */ + offset += hdr->len * 0x10; + /* This partition should disappear when written back */ + continue; + } + + /* it's good, create a partition */ + part = malloc(sizeof(struct nvram_partition)); + + /* note that 0x10 == sizeof(struct chrp_nvram_header) */ + part->chrp_sig = hdr->sig; + part->len = (hdr->len * 0x10) - 0x10; + ASSERT(sizeof(part->name) >= sizeof(hdr->name) + 1); + memcpy(part->name, hdr->name, sizeof(hdr->name)); + part->name[sizeof(hdr->name)] = '\0'; + part->data = malloc(part->len); + memcpy(part->data, buf + offset + 0x10, part->len); + + dprintf(DEBUG_SPEW, "found partition '%s' at offset %zu, len %zu\n", part->name, offset, part->len); + + /* add it to the bank list */ + list_add_tail(&bank->part_list, &part->node); + + offset += hdr->len * 0x10; + } + + return 0; + +error_exit: + if (part != NULL) { + if (part->data != NULL) + free(part->data); + + free(part); + } + + return -1; +} + +static void process_loaded_bank(struct nvram_bank *bank) +{ + struct nvram_partition *part; + + /* look for the environment variable partition */ + part = find_part_in_bank(bank, "common"); + if (part) { + + env_unserialize(part->data, part->len); + } +} + +static int nvram_save_env(struct nvram_bank *bank) +{ + struct nvram_partition *part; + size_t env_length; + + /* see if there's already a common partition */ + part = find_part_in_bank(bank, "common"); + if (part == NULL) { + /* create a new one */ + part = calloc(1, sizeof(struct nvram_partition)); + part->chrp_sig = 0x70; + strlcpy(part->name, "common", sizeof(part->name)); + part->len = 0; + part->data = NULL; + + list_add_head(&bank->part_list, &part->node); + } + + /* throw away the old data, we're going to overwrite it */ + if (part->data) + free(part->data); + + /* allocate a new buffer for this data */ + part->len = NVRAM_MAX_ENV_PARTITION; + part->data = malloc(part->len); + + /* serialise environment and adjust buffer size to suit */ + env_length = env_serialize(part->data, part->len); + memset(part->data + env_length, 0, part->len - env_length); + + return 0; +} + +static int nvram_prepare_bank(struct nvram_bank *bank, uint8_t *buf) +{ + int err = 0; + struct nvram_partition *part; + struct apple_nvram_header *apple_hdr; + struct chrp_nvram_header *hdr; + size_t offset; + + /* lay down an apple nvram header */ + apple_hdr = (struct apple_nvram_header *)buf; + apple_hdr->chrp.sig = 0x5a; + apple_hdr->chrp.len = 0x2; // 0x20 bytes + memcpy(apple_hdr->chrp.name, "nvram", sizeof("nvram")); + apple_hdr->chrp.cksum = chrp_checksum(&apple_hdr->chrp); + apple_hdr->generation = bank->generation; + + /* iterate through each of the sections in the nvram, laying them out in the buffer */ + offset = 0x20; + list_for_every_entry(&bank->part_list, part, struct nvram_partition, node) { + + /* partition must have data */ + if (0 == part->len) + goto fail; + + /* make sure there is room to establish a header in the buffer */ + if ((offset + sizeof(struct chrp_nvram_header)) > bank->len) + goto fail; + + hdr = (struct chrp_nvram_header *)&buf[offset]; + hdr->sig = part->chrp_sig; + hdr->len = ROUNDUP(part->len + 0x10, 0x10) / 0x10; + memcpy(hdr->name, part->name, sizeof(hdr->name)); + hdr->cksum = chrp_checksum(hdr); + + /* make sure there is room to copy data into the buffer */ + if ((offset + sizeof(struct chrp_nvram_header) + part->len) > bank->len) + goto fail; + + memcpy(hdr->data, part->data, part->len); + + offset += hdr->len * 0x10; + } + + /* write out a free space partition to cover the rest of the buffer, if there's free space */ + if ((offset + sizeof(struct chrp_nvram_header)) <= bank->len) { + hdr = (struct chrp_nvram_header *)&buf[offset]; + hdr->sig = 0x7f; + hdr->len = (bank->len - offset) / 0x10; + memset(hdr->name, 0x77, sizeof(hdr->name)); + hdr->cksum = chrp_checksum(hdr); + } + + /* fill in the adler32 checksum on the apple header */ + apple_hdr->adler = adler32(buf + 0x14, bank->len - 0x14); + +out: + return err; +fail: + err = -1; + goto out; +} + +static int nvram_write_bank(struct nvram_bank *bank) +{ + int err; + uint8_t *buf; + + /* allocate a buffer to stage this in */ + buf = calloc(1, bank->len); + + /* prepare buf with bank data */ + err = nvram_prepare_bank(bank, buf); + if (err) { + dprintf(DEBUG_CRITICAL, "unable to prepare buffer with nvram bank data\n"); + goto out; + } + + /* write it out */ + if (bank->dev) { + dprintf(DEBUG_INFO, "saving nvram contents at bdev '%s', offset 0x%llx, len 0x%zx, gen %d\n", + bank->dev->name, bank->offset, bank->len, bank->generation); + err = blockdev_write(bank->dev, buf, bank->offset, bank->len); + } else { + err = 0; + dprintf(DEBUG_CRITICAL, "nowhere to save environment\n"); + } +#if 0 + printf("would have written this to offset 0x%llx, len %d:\n", bank->offset, bank->len); + hexdump(buf, bank->len); +#endif +out: + free(buf); + return err; +} + +int nvram_save(void) +{ + int err; + + /* overwrite the 'oldest' bank (lowest generation count) */ + if (!oldest_bank) { + printf("nvram_save: no oldest bank previously saved, dropping request\n"); + return 0; + } + + /* find the next generation number to assign this bank */ + if (newest_bank) + oldest_bank->generation = newest_bank->generation + 1; + else + oldest_bank->generation = 1; + + /* write out our environment */ + nvram_save_env(oldest_bank); + + /* write out the bank */ + err = nvram_write_bank(oldest_bank); + if (err < 0) + return err; + + /* we have a new oldest bank, reevaluate */ + sort_bank_age(); + + return 0; +} + +int nvram_set_panic(const void *panic_data, size_t length) +{ + struct nvram_partition *part; + + /* overwrite the 'oldest' bank (lowest generation count) */ + if (!oldest_bank) { + printf("nvram_set_panic: no oldest bank previously saved, dropping request\n"); + return 0; + } + + /* find a panic info partition */ + part = find_part_in_bank(oldest_bank, NVRAM_PANIC_NAME); + if (part == NULL) { + /* create a new one */ + part = calloc(1, sizeof(struct nvram_partition)); + part->chrp_sig = NVRAM_PANIC_SIG; + strlcpy(part->name, NVRAM_PANIC_NAME, sizeof(part->name)); + part->len = NVRAM_PANIC_SIZE; + part->data = malloc(NVRAM_PANIC_SIZE); + + list_add_head(&oldest_bank->part_list, &part->node); + } + if (part->len < 5) { + /* partition not big enough to store anything */ + return -1; + } + + /* the first 4 bytes are the panic length. adjust length to fit. */ + if (length + 4 > part->len) length = part->len - 4; + *(uint32_t *) part->data = length; + + /* copy panic data into the partition. */ + memcpy(part->data + 4, panic_data, length); + + /* zero the remainder of the partition. */ + memset(part->data + 4 + length, 0, part->len - length - 4); + + return 0; +} + +static int nvram_load_dev(struct blockdev *dev, off_t offset, size_t banklen, int count) +{ + int err = 0; + int i; + uint8_t *buf; + int banks_found = 0; + + if (offset < 0) { + offset = dev->total_len + offset; + } + + buf = malloc(banklen); + + for (i=0; i < count; i++, offset += banklen) { + struct nvram_bank *bank; + struct apple_nvram_header *hdr; + + /* read in potential nvram bank */ + if (dev == NULL) { + dprintf(DEBUG_INFO, "nowhere to load environment from; using transient buffer-only solution\n"); + goto bank_fail; + } + + err = blockdev_read(dev, buf, offset, banklen); + if (err <= 0) { + dprintf(DEBUG_INFO, "nvram_load: failed to read potential nvram bank at offset 0x%llx\n", offset); + continue; + } + +#if 0 + printf("potential nvram bank: \n"); + hexdump(buf, banklen); +#endif + + /* see if it starts with a valid header */ + hdr = (struct apple_nvram_header *)buf; + if (hdr->chrp.cksum != chrp_checksum(&hdr->chrp)) { +#if !NVRAM_NOCHECKSUM + dprintf(DEBUG_INFO, "nvram_load: nvram partition at offset 0x%llx failed checksum\n", offset); + goto bank_fail; +#endif + } + + /* do an adler32 of the entire buffer */ + uint32_t adler = adler32(buf + 0x14, banklen - 0x14); + if (adler != hdr->adler) { +#if !NVRAM_NOCHECKSUM + dprintf(DEBUG_INFO, "nvram_load: nvram bank fails adler32\n"); + goto bank_fail; +#endif + } + + /* valid header, lets start building a bank structure */ + bank = malloc(sizeof(struct nvram_bank)); + + list_initialize(&bank->part_list); + bank->dev = dev; + bank->offset = offset; + bank->len = banklen; + bank->generation = hdr->generation; + + /* read in the partitions within the bank */ + err = load_bank_partitions(bank, buf); + if (err < 0) { + // error parsing partitions, free this bank and continue + free(bank); + goto bank_fail; + } + + /* add the bank to the list */ + list_add_tail(&nvram_bank_list, &bank->node); + + banks_found++; + continue; + +bank_fail: + /* we failed to load a bank at a nvram slot, allocate a blank bank */ + bank = malloc(sizeof(struct nvram_bank)); + list_initialize(&bank->part_list); + bank->dev = dev; + bank->offset = offset; + bank->len = banklen; + bank->generation = 0; + + dprintf(DEBUG_INFO, "nvram_load: found invalid or empty bank at 0x%llx, creating blank bank\n", offset); + + /* add the bank to the list */ + banks_found++; + list_add_tail(&nvram_bank_list, &bank->node); + } + + dprintf(DEBUG_INFO, "nvram_load: found %d banks of nvram\n", banks_found); + + if (banks_found) { + /* search through the bank list, sorting by age */ + sort_bank_age(); + + /* do any bank processing on the current (newest) bank */ + process_loaded_bank(newest_bank); + } + + free(buf); + return banks_found; +} + +int nvram_load(void) +{ + int result; + struct blockdev *bdev; + + dprintf(DEBUG_INFO, "loading nvram\n"); + + // Look for a real NVRAM block device + bdev = lookup_blockdev("nvram"); + if (bdev) { + result = nvram_load_dev(bdev, 0, NVRAM_BANK_SIZE, 1); + return result; + } + + /* Fall back to just creating a temporary nvram not backed by any block device */ + return (nvram_load_dev(NULL, 0, NVRAM_BANK_SIZE, 1) ? 0 : -1); +} + +int nvram_update_devicetree(dt_node_t *node, const char *propname) +{ + uint8_t *buf; + int err = -1; + + if (!oldest_bank) { + panic("nvram_update_devicetree: no bank previously saved\n"); + } else if (!newest_bank) { + dprintf(DEBUG_CRITICAL, "nvram_update_devicetree: no content available\n"); + } else { + buf = malloc(newest_bank->len); + /* prepare device tree proper buffer with bank data */ + err = nvram_prepare_bank(newest_bank, buf); + + if (err) { + dprintf(DEBUG_CRITICAL, "nvram_update_devicetree: unable to update devicetree with nvram content\n"); + } else { + dt_set_prop(node, propname, buf, newest_bank->len); + dprintf(DEBUG_INFO, "nvram_update_devicetree: updated devicetree with nvram generation %d\n", + newest_bank->generation); + } + + free(buf); + } + + return err; +} diff --git a/lib/nvram/rules.mk b/lib/nvram/rules.mk new file mode 100644 index 0000000..9001365 --- /dev/null +++ b/lib/nvram/rules.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2008, 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_NVRAM=1 + +MODULES += \ + lib/cksum \ + lib/env \ + lib/heap + +LIBRARY_MODULES += lib/nvram + diff --git a/lib/nvram/tests-common.mk b/lib/nvram/tests-common.mk new file mode 100644 index 0000000..814f6ee --- /dev/null +++ b/lib/nvram/tests-common.mk @@ -0,0 +1,24 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +TEST_OBJS := \ + lib/blockdev/blockdev.o \ + lib/cksum/adler32.o \ + lib/env/env.o \ + lib/libc/log2.o \ + lib/nvram/nvram.o + +TEST_SUPPORT_OBJS := \ + tests/mocks/sys/security.o \ + tests/mocks/syscfg.o \ + lib/devicetree/devicetree.o + +TEST_CFLAGS := \ + -DCPU_CACHELINE_SIZE=32 diff --git a/lib/nvram/tests-fuzz.mk b/lib/nvram/tests-fuzz.mk new file mode 100644 index 0000000..f69a7fa --- /dev/null +++ b/lib/nvram/tests-fuzz.mk @@ -0,0 +1,24 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := nvram-fuzz + +include $(LOCAL_DIR)/tests-common.mk + +TEST_SUPPORT_OBJS += \ + tests/fuzz-main.o \ + tests/mocks/blockdev.o \ + $(LOCAL_DIR)/fuzz.o + +TEST_CFLAGS += \ + -DNVRAM_NOCHECKSUM=1 + diff --git a/lib/nvram/tests.c b/lib/nvram/tests.c new file mode 100644 index 0000000..02cc0ba --- /dev/null +++ b/lib/nvram/tests.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include + +// There aren't any useful test cases here yet, as the nvram +// testing infrastructure was mainly added to allow fuzzing. +// For unit testing, we need a sample NVRAM and then some +// getenv calls + +// For now, this just exercises the the "empty NVRAM" case +static void test_nvram_load(uintptr_t ctx) +{ + struct blockdev *bdev; + int result; + void *backing; + + backing = calloc(8192, 1); + + bdev = create_mem_blockdev("nvram", backing, 8192, 4096); + if (bdev != NULL) + register_blockdev(bdev); + + result = nvram_load(); +} + +struct test_suite nvram_suite = { + .name = "nvram", + .test_cases = { + { "nvram_load", test_nvram_load, 0, "" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(nvram_suite); + +// Mock for lib/env +bool +env_blacklist(const char *name, bool write) +{ + return false; +} + +bool +env_blacklist_nvram(const char *name) +{ + return false; +} diff --git a/lib/nvram/tests.mk b/lib/nvram/tests.mk new file mode 100644 index 0000000..9431c5e --- /dev/null +++ b/lib/nvram/tests.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := nvram + +include $(LOCAL_DIR)/tests-common.mk + +TEST_OBJS += \ + lib/blockdev/mem_blockdev.o + +TEST_SUPPORT_OBJS += \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o diff --git a/lib/paint/library.mk b/lib/paint/library.mk new file mode 100644 index 0000000..827a58c --- /dev/null +++ b/lib/paint/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBPAINT_DIR := $(GET_LOCAL_DIR) +LIBPAINT_BUILD := $(call TOLIBDIR,$(LIBPAINT_DIR)/LIBPAINT.a) +COMMONLIBS += LIBPAINT + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBPAINT_OBJS := $(LIBPAINT_DIR)/paint.o + +LIBPAINT_OBJS := $(call TOLIBOBJDIR,$(LIBPAINT_OBJS)) + +ALL_DEPS += $(LIBPAINT_OBJS:%o=%d) + +$(LIBPAINT_BUILD): $(LIBPAINT_OBJS) + +endif diff --git a/lib/paint/paint.c b/lib/paint/paint.c new file mode 100644 index 0000000..c76f4ea --- /dev/null +++ b/lib/paint/paint.c @@ -0,0 +1,1625 @@ +/* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSCFG_DCLR_COLOR_REPORT 1 // Report colors found in 'DClr' syscfg entry +#if DEBUG_BUILD +#define SYSCFG_DCLR_OVERRIDE 1 // Allow overridding 'DClr' syscfg entry from environment for testing +#else +#define SYSCFG_DCLR_OVERRIDE 0 // Do not honor DClr_Override on non-DEBUG builds. +#endif +#define PANIC_ON_SERIOUS_ERROR 1 // Panic if 'DClr' syscfg processing error +#define PANIC_ON_UNKNOWN_DCLR_COLOR 1 // Panic if 'DClr' syscfg version is unknown or invalid + +// Nothing explicitly defines a kMIBTargetOsPictureRotate factor so use +// the value returned by kMIBTargetPictureRotate for everything. +#define kMIBTargetOsPictureRotate kMIBTargetPictureRotate + +struct iboot_image; +static int paint_draw_picture(struct iboot_image *comp_image_buf, size_t comp_image_len); +static int paint_update_image_argb(void); +static int paint_update_image_wide_gammut(void); + +static void paint_install_gamma_table_channel(uint32_t entries, volatile uint32_t *channel_lut, const uint8_t *bits); +static uint8_t paint_install_gamma_get_2bits(const uint8_t *bits); + +static void plot4(struct plane *p, uint32_t x, uint32_t y, uint64_t color); +static void plot8(struct plane *p, uint32_t x, uint32_t y, uint64_t color); +static void plot16(struct plane *p, uint32_t x, uint32_t y, uint64_t color); +static void plot32(struct plane *p, uint32_t x, uint32_t y, uint64_t color); +static uint32_t get_pixel4(struct plane *p, uint32_t x, uint32_t y); +static uint32_t get_pixel8(struct plane *p, uint32_t x, uint32_t y); +static uint32_t get_pixel16(struct plane *p, uint32_t x, uint32_t y); +static uint32_t get_pixel32(struct plane *p, uint32_t x, uint32_t y); +static void hline4(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void hline8(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void hline16(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void hline32(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void vline4(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void vline8(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void vline16(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void vline32(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color); +static void set_plane(struct plane *p, uint32_t y, uint32_t line_x, size_t plane_size, addr_t plane_fb, addr_t plane_db, enum colorspace cs); + +static void clear_flattened_images(void); + +static bool paint_ready; +static struct canvas *paint_canvas; + +static uint32_t window_height; +static uint32_t window_width; +static uint32_t window_stride; +static uint32_t window_depth; +static uintptr_t window_framebuffer; + +static addr_t compressed_image_base; +static size_t compressed_image_size; + +struct flattened_image { + bool fi_color; + uint32_t fi_width; + uint32_t fi_height; + uint32_t fi_xstart; + uint32_t fi_ystart; + uint32_t fi_xstop; + uint32_t fi_ystop; + uint8_t *fi_buffer; + uint32_t fi_src_pos; +}; + +#define MAX_FLATTENED_IMAGES (0x1000 / sizeof(struct flattened_image)) +static uint32_t flattened_images_count; +static struct flattened_image *flattened_images; +static addr_t flattened_images_base; +static addr_t flattened_images_end; + +static uint64_t background_rgb; +static bool color_map_desired; +static bool color_map_enabled; +static bool color_map_supported; +static bool color_map_invalid; +static color_policy_t color_policy; +#if DEBUG_BUILD +static struct display_window *paint_window; +#endif +static addr_t last_canvas_addr; +static size_t page_size; + +int paint_init(void *window, addr_t scratch, size_t scratch_size) +{ + struct display_window *w = (struct display_window *)window; + int result = -1; + + paint_ready = false; + + if (w == NULL) { + goto out; + } + + paint_canvas = &w->c; + + window_height = w->height; + window_width = w->width; + window_stride = w->stride; + window_depth = w->depth; + + //The framebuffer region should be large enough to include all planes used + window_framebuffer = paint_canvas->fb_phys; + + compressed_image_base = scratch; + compressed_image_size = window_height * window_stride + 0x1000; + + flattened_images = 0; + flattened_images = (struct flattened_image *)(compressed_image_base + compressed_image_size); + flattened_images_base = compressed_image_base + compressed_image_size + 0x1000; + flattened_images_end = scratch + scratch_size; + flattened_images_count = 0; + + if (flattened_images_base >= flattened_images_end) { + dprintf(DEBUG_INFO, "Display Size is too small\n"); + goto out; + } + + background_rgb = 0x00000000; + + paint_ready = true; + +#if DEBUG_BUILD + paint_window = w; +#endif + result = 0; + +out: + return result; +} + +static void clear_flattened_images(void) +{ + if (!paint_ready) + return; + + flattened_images_count = 0; + flattened_images_base = compressed_image_base + compressed_image_size + 0x1000; +} + +int paint_set_bgcolor(uint16_t bg_red, uint16_t bg_green, uint16_t bg_blue) +{ + if (!paint_ready) { + return 0; + } + + if (paint_canvas->cs == CS_ARGB8101010) { + background_rgb = RGB10(bg_red, bg_green, bg_blue); + } else { + background_rgb = RGB(bg_red, bg_green, bg_blue); + } + + return 0; +} + +/* image_data is either 32 or 16 bits per sample with the b_alpha most significant. */ +/* The reset of the data is the rgb or grey data having already been alpha scaled. */ +/* The b_alpha value is scale with the back ground color then added to the rgb value. */ + +struct iboot_image { + char image_signature[8]; // 0x00 - 'iBootIm' + uint32_t image_adler32; // 0x08 + uint32_t image_type; // 0x0C - 'lzss' + uint32_t image_format; // 0x10 - 'argb' or 'grey' + uint16_t image_width; // 0x14 + uint16_t image_height; // 0x16 + int16_t image_h_offset; // 0x18 + int16_t image_v_offset; // 0x1A + uint32_t image_data_length; // 0x1C + uint32_t reserved[8]; // 0x20 + uint8_t image_data[]; // 0x40 +} __attribute__((packed)); +typedef struct iboot_image iboot_image; + +int paint_set_picture_for_tag(uint32_t image_tag) +{ + struct image_info *pict_info = 0; + + if (mib_get_u32(kMIBTargetApplicationProduct) == MIB_APP_PROD_IBOOT) { + pict_info = image_find(image_tag); + if (pict_info == 0) { + dprintf(DEBUG_INFO, "image tag 0x%08x not found\n", image_tag); + } + } + + return paint_set_picture(pict_info); +} + +int paint_set_picture_for_tag_list(uint32_t image_tag, int image_offset, int image_count) +{ + struct image_info *pict_info = 0; + + if (mib_get_u32(kMIBTargetApplicationProduct) == MIB_APP_PROD_IBOOT) { + pict_info = image_find(image_tag); + if (pict_info == 0) { + dprintf(DEBUG_INFO, "image tag 0x%08x not found\n", image_tag); + } + } + + return paint_set_picture_list(pict_info, image_offset, image_count); +} + +int paint_set_picture(struct image_info *pict_info) +{ + return paint_set_picture_list(pict_info, 0, 1); +} + +int paint_set_picture_list(struct image_info *pict_info, int image_offset, int image_count) +{ + void *comp_image_buf; + size_t comp_image_len; + + /* must be initialised */ + if (!paint_ready) { + return 0; + } + + /* if no image, clear the display and all images */ + if (pict_info == 0) { + clear_flattened_images(); + return 0; + } + + /* if we're out of space, we can't do anything */ + if (flattened_images_count >= MAX_FLATTENED_IMAGES) { + return 0; + } + + comp_image_len = pict_info->imageAllocation; + if (comp_image_len > compressed_image_size) { + dprintf(DEBUG_INFO, "compressed image too large\n"); + return -1; + } + comp_image_buf = (uint8_t *)(compressed_image_base); + + /* accept any type (pass NULL) */ + if (image_load(pict_info, NULL, 0, NULL, &comp_image_buf, &comp_image_len) < 0) { + dprintf(DEBUG_INFO, "cannot load image\n"); + return -1; + } + + // before drawing picture, consolidate environment based on image validation result + security_consolidate_environment(); + + for (int idx = 0; idx < image_offset + image_count; idx++) { + iboot_image *ind_comp_image = comp_image_buf; + size_t ind_comp_image_len; + + if (ind_comp_image->image_data_length == 0) { + // old format + ind_comp_image_len = comp_image_len; + } else if ((comp_image_len >= sizeof(iboot_image)) && (comp_image_len >= (sizeof(iboot_image) + ind_comp_image->image_data_length))) { + ind_comp_image_len = sizeof(iboot_image) + ind_comp_image->image_data_length; + } else { + dprintf(DEBUG_INFO, "image length invalid\n"); + return -1; + } + + if (idx >= image_offset) { + int ret = paint_draw_picture(ind_comp_image, ind_comp_image_len); + if (ret != 0) + return ret; + } + + comp_image_buf = ((uint8_t *)comp_image_buf) + ind_comp_image_len; + comp_image_len -= ind_comp_image_len; + } + + return 0; +} + +int paint_set_picture_from_file(const char *path, uint32_t type) +{ + addr_t comp_image_buf; + size_t comp_image_len; + + /* must be initialised */ + if (!paint_ready) { + return 0; + } + + /* if we're out of space, we can't do anything */ + if (flattened_images_count >= MAX_FLATTENED_IMAGES) { + return 0; + } + + comp_image_buf = compressed_image_base; + comp_image_len = compressed_image_size; + if (image_load_file(path, &comp_image_buf, &comp_image_len, &type, 1, NULL, 0)) { + dprintf(DEBUG_INFO, "cannot load image\n"); + return -1; + } + + // before drawing picture, consolidate environment based on image validation result + security_consolidate_environment(); + + return paint_draw_picture((void *)compressed_image_base, comp_image_len); +} + +static int paint_draw_picture(iboot_image *comp_image, size_t comp_image_len) +{ + uint8_t *image_buf, *rot_buf; + uint32_t image_max_len, image_len, image_expected_len, data; + uint32_t *image_src32, *image_dst; + uint16_t *image_src16; + int32_t imagex, imagey, imagexs, imagexe, imageys, imageye; + int32_t imagex_offset, imagey_offset; + int32_t posx, posy, rposx, rposy; + int32_t picture_scale; + int32_t picture_rotate; + bool image_color; + + image_max_len = flattened_images_end - flattened_images_base; + image_buf = (uint8_t *)(flattened_images_base); + + if ((comp_image_len < sizeof(iboot_image)) || + (strncmp(comp_image->image_signature, "iBootIm", 8) != 0) || + (comp_image->image_type != 'lzss') || + ((comp_image->image_format != 'argb') && (comp_image->image_format != 'grey'))) { + dprintf(DEBUG_INFO, "image not valid\n"); + return -1; + } + + image_color = false; + if (comp_image->image_format == 'argb') image_color = true; + + picture_scale = mib_get_u32(kMIBTargetPictureScale); + ASSERT((picture_scale == 1) || (picture_scale == 2)); + picture_rotate = mib_get_s32(kMIBTargetPictureRotate); + + if (picture_rotate == 0) { + imagex = comp_image->image_width * picture_scale; + imagey = comp_image->image_height * picture_scale; + imagex_offset = comp_image->image_h_offset * picture_scale; + imagey_offset = comp_image->image_v_offset * picture_scale; + } else if ((picture_rotate == 90) || (picture_rotate == -90)) { + imagex = comp_image->image_height * picture_scale; + imagey = comp_image->image_width * picture_scale; + imagex_offset = comp_image->image_v_offset * picture_scale * ((picture_rotate == 90) ? -1 : 1); + imagey_offset = comp_image->image_h_offset * picture_scale * ((picture_rotate == 90) ? 1 : -1); + } else { + panic("kMIBTargetPictureRotate value is unsupported: %d", picture_rotate); + } + + imagexs = ((window_width - imagex) / 2) + imagex_offset; + imagexe = imagexs + imagex; + imageys = ((window_height - imagey) / 2) + imagey_offset; + imageye = imageys + imagey; + + if ((imagexs < 0) || (imageys < 0) || (imagexe > (int32_t)window_width) || (imageye > (int32_t)window_height)) { + dprintf(DEBUG_INFO, "image does not fit on screen\n"); + return -1; + } + + image_expected_len = (uint32_t)(imagex / picture_scale) * (uint32_t)(imagey / picture_scale) * (image_color ? 4 : 2); + + if (picture_rotate != 0) { + if ((image_expected_len * 2) > image_max_len) { + dprintf(DEBUG_INFO, "image is too large to be rotate\n"); + return -1; + } + + rot_buf = image_buf; + image_buf += image_expected_len; + image_max_len -= image_expected_len; + } + + image_len = decompress_lzss(image_buf, image_max_len, comp_image->image_data, comp_image_len - sizeof(iboot_image)); + + if (image_len != image_expected_len) { + dprintf(DEBUG_INFO, "image data size does not match expected image size\n"); + return -1; + } + + if (picture_scale == 2) { + image_src16 = (uint16_t *)image_buf + (imagex / picture_scale) * (imagey / picture_scale) - 1; + image_src32 = (uint32_t *)image_buf + (imagex / picture_scale) * (imagey / picture_scale) - 1; + if (image_color) image_dst = (uint32_t *)image_buf + imagex * imagey - 1; + else image_dst = (uint32_t *)image_buf + (imagex / 2) * imagey - 1; + for (posy = 0; posy < (imagey / picture_scale); posy++) { + for (posx = 0; posx < (imagex / picture_scale); posx++) { + if (image_color) { + data = *(image_src32--); + *(image_dst - 0) = data; + *(image_dst - 1) = data; + *(image_dst - imagex - 0) = data; + *(image_dst - imagex - 1) = data; + image_dst -= 2; + } else { + data = *(image_src16--); + data |= data << 16; + *(image_dst) = data; + *(image_dst - imagex / 2) = data; + image_dst -= 1; + } + } + image_dst -= imagex / (image_color ? 1 : 2); + } + } + + if ((picture_rotate == 90) || (picture_rotate == -90)) { + image_src16 = (uint16_t *)image_buf; + image_src32 = (uint32_t *)image_buf; + for (posx = 0; posx < imagex; posx++) { + if (picture_rotate == 90) rposx = imagex - 1 - posx; + else rposx = posx; + for (posy = 0; posy < imagey; posy++) { + if (picture_rotate == 90) rposy = posy; + else rposy = imagey - 1 - posy; + if (image_color) { + ((uint32_t *)rot_buf)[rposy * imagex + rposx] = *(image_src32++); + } else { + ((uint16_t *)rot_buf)[rposy * imagex + rposx] = *(image_src16++); + } + } + } + + image_buf = rot_buf; + } + + flattened_images[flattened_images_count].fi_color = image_color; + flattened_images[flattened_images_count].fi_width = imagex; + flattened_images[flattened_images_count].fi_height = imagey; + flattened_images[flattened_images_count].fi_xstart = imagexs; + flattened_images[flattened_images_count].fi_ystart = imageys; + flattened_images[flattened_images_count].fi_xstop = imagexs + imagex - 1; + flattened_images[flattened_images_count].fi_ystop = imageys + imagey - 1; + flattened_images[flattened_images_count].fi_buffer = image_buf; + + flattened_images_base += image_len * picture_scale * picture_scale; + + flattened_images_count++; + + return 0; +} + +static uint32_t map_bgvalue(uint32_t bgvalue) +{ + if (color_map_enabled && (paint_canvas->map_color != NULL)) { + return paint_canvas->map_color(bgvalue); + } else { + return bgvalue; + } + +} + +static void update_framebuffer(void) +{ + uint32_t i; + size_t frame_size; + + if (!paint_ready) return; + + //copy final pixels from draw buffer to frame buffer + for (i = 0; i < paint_canvas->num_of_active_planes; i++) { + frame_size = paint_canvas->y * paint_canvas->planes[i].line_x * paint_canvas->planes[i].pixel_size / 8; + memcpy( paint_canvas->planes[i].fb_virt, paint_canvas->planes[i].db_virt, frame_size ); + } +} + +int paint_update_image(void) +{ + if (!paint_ready) { + return 0; + } + + if (paint_canvas->cs == CS_ARGB8101010) + return paint_update_image_wide_gammut(); + return paint_update_image_argb(); +} + +static int paint_update_image_argb(void) +{ + uint8_t b_alpha; + uint32_t cnt, x, y, rgbvalue, bgvalue, bg_mask = 0x00FFFFFF; + struct flattened_image *fi; + uint32_t images_xstart = UINT32_MAX; + uint32_t images_xstop = 0; + uint32_t images_ystart = UINT32_MAX; + uint32_t images_ystop = 0; + void (* plot_func)(struct plane *p, u_int32_t x, u_int32_t y, uint64_t color); + + /* If background color is white and there is an image, make the background black */ + if ((flattened_images_count != 0) && (background_rgb == 0x00FFFFFF)) { + bg_mask = 0x00000000; + } + + bgvalue = background_rgb & bg_mask; + bgvalue = map_bgvalue(bgvalue); + + fill_rect(paint_canvas, 0, 0, window_width, window_height, bgvalue); + + for (cnt = 0; cnt < flattened_images_count; cnt++) { + flattened_images[cnt].fi_src_pos = 0; + if (flattened_images[cnt].fi_xstart < images_xstart) + images_xstart = flattened_images[cnt].fi_xstart; + if (flattened_images[cnt].fi_xstop > images_xstop) + images_xstop = flattened_images[cnt].fi_xstop; + if (flattened_images[cnt].fi_ystart < images_ystart) + images_ystart = flattened_images[cnt].fi_ystart; + if (flattened_images[cnt].fi_ystop > images_ystop) + images_ystop = flattened_images[cnt].fi_ystop; + } + + // moving the plot function to the stack saves us some time + // because of -fno-strict-aliasing + plot_func = paint_canvas->planes[0].plot; + + for (y = images_ystart; y <= images_ystop; y++) { + for (x = images_xstart; x <= images_xstop; x++) { + + bgvalue = background_rgb & bg_mask; + + for (cnt = 0; cnt < flattened_images_count; cnt++) { + fi = flattened_images + cnt; + + if ((y < fi->fi_ystart) || (y > fi->fi_ystop)) continue; + if ((x < fi->fi_xstart) || (x > fi->fi_xstop)) continue; + + if (fi->fi_color) { + rgbvalue = ((uint32_t *)fi->fi_buffer)[fi->fi_src_pos++]; + } else { + rgbvalue = ((uint16_t *)fi->fi_buffer)[fi->fi_src_pos++]; + rgbvalue = (rgbvalue << 16) | ((rgbvalue & 0x00FF) << 8) | ((rgbvalue & 0x00FF) << 0); + } + + if (rgbvalue == 0xFFFFFFFF) { + rgbvalue = 0xFF000000; + } + + b_alpha = rgbvalue >> 24; + + if (b_alpha != 0xFF && b_alpha != 0) { + bgvalue = (((((bgvalue & 0x00FF00FF) * b_alpha) + 0x00FF00FF) >> 8) & 0x00FF00FF) | + (((((bgvalue & 0x0000FF00) * b_alpha) + 0x0000FF00) >> 8) & 0x0000FF00); + + bgvalue += rgbvalue; + } else if (b_alpha == 0) { + bgvalue = rgbvalue; + } + } + + bgvalue = map_bgvalue(bgvalue); + plot_func(&(paint_canvas->planes[0]), x, y, bgvalue); + } + } + + update_framebuffer(); + + return 0; +} + +static uint64_t paint_draw_plot_convert_argb_to_wide_gammut(struct flattened_image *fi, uint32_t bgvalue) +{ + uint8_t b_alpha; + uint32_t rgbvalue; + uint64_t tmp = bgvalue; + + if (fi->fi_color) { + rgbvalue = ((uint32_t *)fi->fi_buffer)[fi->fi_src_pos++]; + } else { + rgbvalue = ((uint16_t *)fi->fi_buffer)[fi->fi_src_pos++]; + rgbvalue = (rgbvalue << 16) | ((rgbvalue & 0x00FF) << 8) | ((rgbvalue & 0x00FF) << 0); + } + + if (rgbvalue == 0xFFFFFFFF) { + rgbvalue = 0xFF000000; + } + + b_alpha = rgbvalue >> 24; + + if (b_alpha != 0xFF && b_alpha != 0) { + tmp = (((((tmp & 0x00FF00FF) * b_alpha) + 0x00FF00FF) >> 8) & 0x00FF00FF) | + (((((tmp & 0x0000FF00) * b_alpha) + 0x0000FF00) >> 8) & 0x0000FF00); + + tmp += rgbvalue; + } else if (b_alpha == 0) { + tmp = rgbvalue; + } + //Till now, we have a 32 pixel, convert it to 101010 + tmp = (((uint64_t) b_alpha) << 32) | RGB10(RGB_R(tmp) * 4, RGB_G(tmp) * 4, RGB_B(tmp) * 4); + + return tmp; +} + +static int paint_update_image_wide_gammut(void) +{ + uint32_t cnt, x, y, bgvalue, bg_mask = 0x3FFFFFFF; + struct flattened_image *fi; + uint32_t images_xstart = UINT32_MAX; + uint32_t images_xstop = 0; + uint32_t images_ystart = UINT32_MAX; + uint32_t images_ystop = 0; + void (* plot_func_p0)(struct plane *p, u_int32_t x, u_int32_t y, uint64_t color); + void (* plot_func_p1)(struct plane *p, u_int32_t x, u_int32_t y, uint64_t color); + + /* If background color is white and there is an image, make the background black */ + if ((flattened_images_count != 0) && (background_rgb == 0x3FFFFFFF)) { + bg_mask = 0x00000000; + } + + bgvalue = background_rgb & bg_mask; + bgvalue = map_bgvalue(bgvalue); + + fill_rect(paint_canvas, 0, 0, window_width, window_height, bgvalue); + + for (cnt = 0; cnt < flattened_images_count; cnt++) { + flattened_images[cnt].fi_src_pos = 0; + if (flattened_images[cnt].fi_xstart < images_xstart) + images_xstart = flattened_images[cnt].fi_xstart; + if (flattened_images[cnt].fi_xstop > images_xstop) + images_xstop = flattened_images[cnt].fi_xstop; + if (flattened_images[cnt].fi_ystart < images_ystart) + images_ystart = flattened_images[cnt].fi_ystart; + if (flattened_images[cnt].fi_ystop > images_ystop) + images_ystop = flattened_images[cnt].fi_ystop; + } + + // moving the plot function to the stack saves us some time + // because of -fno-strict-aliasing + plot_func_p0 = paint_canvas->planes[0].plot; + plot_func_p1 = paint_canvas->planes[1].plot; + + for (y = images_ystart; y <= images_ystop; y++) { + for (x = images_xstart; x <= images_xstop; x++) { + + bgvalue = background_rgb & bg_mask; + + for (cnt = 0; cnt < flattened_images_count; cnt++) { + fi = flattened_images + cnt; + + if ((y < fi->fi_ystart) || (y > fi->fi_ystop)) continue; + if ((x < fi->fi_xstart) || (x > fi->fi_xstop)) continue; + + bgvalue = paint_draw_plot_convert_argb_to_wide_gammut(fi, bgvalue); + } + + bgvalue = map_bgvalue(bgvalue); + plot_func_p0(&(paint_canvas->planes[0]), x, y, bgvalue); + plot_func_p1(&(paint_canvas->planes[1]), x, y, bgvalue); + } + } + + update_framebuffer(); + + return 0; +} + +/* after the fact get the information about the current display */ +int display_get_info(struct display_info *info) +{ + uint32_t rotate = ((360 + mib_get_s32(kMIBTargetOsPictureRotate)) / 90) % 4; + uint32_t os_picture_scale = mib_get_u32(kMIBTargetOsPictureScale); + uint32_t depth; + + if (paint_ready) { + info->stride = window_stride; + info->width = window_width; + info->height = window_height; + depth = (paint_canvas->cs == CS_ARGB8101010) ? 30 : window_depth; + info->depth = depth | (rotate << 8) | ((os_picture_scale - 1) << 16); + info->framebuffer = window_framebuffer; + } else { + info->stride = 640 * 4; + info->width = 640; + info->height = 1136; + + /* + * First setting scale as workaround for . + * This lets us use the display properly even if the iBoot display system + * is not active (e.g. fastsim support). + */ + info->depth = 32 | ((os_picture_scale - 1) << 16); + info->framebuffer = (uintptr_t)mib_get_addr(kMIBTargetDisplayBaseAddress); + } + + return 0; +} + +void paint_install_gamma_table(uint32_t display_id, + uint32_t entries, + volatile uint32_t *red_lut, + volatile uint32_t *green_lut, + volatile uint32_t *blue_lut) +{ + unsigned int cnt; + const uint8_t *gamma_data = 0; + uint32_t gamma_table_count; + const display_gamma_table *target_gamma_table_base; + const display_gamma_table *target_gamma_table = 0; +#ifndef PAINT_UNITTEST + static struct syscfg_glcl syscfg_glcl; + + cnt = syscfgCopyDataForTag('GLCl', (uint8_t *)&syscfg_glcl, sizeof(syscfg_glcl)); + if (cnt == sizeof(syscfg_glcl)) { + if (syscfg_glcl.major_vers != 1) { + dprintf(DEBUG_CRITICAL, "paint_install_gamma_table: Unknown version %u.%u\n", + syscfg_glcl.major_vers, syscfg_glcl.minor_vers); + } else { + dprintf(DEBUG_CRITICAL, "int_install_gamma_table: Found syscfg gamma table\n"); + gamma_data = syscfg_glcl.gamma_data; + } + } + + gamma_table_count = mib_get_u32(kMIBTargetDisplayGammaTableCount); +#else + gamma_table_count = 0; +#endif + if (gamma_table_count != 0) { +#ifndef PAINT_UNITTEST + target_gamma_table_base = (const display_gamma_table *)mib_get_ptr(kMIBTargetDisplayGammaTablePtr); +#else + target_gamma_table_base = 0; +#endif + for (cnt = 0; gamma_data == 0 && cnt < gamma_table_count; cnt++) { + target_gamma_table = target_gamma_table_base + cnt; + if ((display_id & target_gamma_table->display_id_mask) == target_gamma_table->display_id) { + dprintf(DEBUG_CRITICAL, "paint_install_gamma_table: Found Gamma table 0x%08x / 0x%08x\n", + target_gamma_table->display_id, target_gamma_table->display_id_mask); + gamma_data = target_gamma_table->display_gamma_data; + } + } + } + + if (gamma_data != 0) { + paint_install_gamma_table_channel(entries, red_lut, gamma_data + kGammaChannelBufferSize * 0); + paint_install_gamma_table_channel(entries, green_lut, gamma_data + kGammaChannelBufferSize * 1); + paint_install_gamma_table_channel(entries, blue_lut, gamma_data + kGammaChannelBufferSize * 2); + } else { + printf("paint_install_gamma_table: No Gamma table found for display_id: 0x%08x\n", display_id); + } + +} + +void paint_get_syscfg_wpcl(struct syscfg_wpcl *wpcl) +{ + int size; + +#ifndef PAINT_UNITTEST + size = syscfgCopyDataForTag('WpCl', (u_int8_t *)wpcl, sizeof(struct syscfg_wpcl)); +#else + size = 0; +#endif + if ((size != sizeof(struct syscfg_wpcl)) || (0 == wpcl->version)) { + wpcl->version = 0; + wpcl->red = wpcl->green = wpcl->blue = (1 << WpCl_Quotation_Denominator); + } +} + +#if DEBUG_BUILD + +static uint32_t displaytest_colors_argb[] = { + 0x00FF0000, 0x00000000, 0x0000FF00, 0x00000000, 0x000000FF, 0x00000000, 0x00FFFFFF, 0x00000000 + }; +#define DISPLAYTEST_COLORS_COUNT_ARGB (sizeof(displaytest_colors_argb) / sizeof(displaytest_colors_argb[0])) + +static uint32_t displaytest_colors_wide_gammut[] = { + 0x3FF00000, 0x00000000, 0x000FFC00, 0x00000000, 0x000003FF, 0x00000000, 0x3FFFFFFF, 0x00000000 +}; +#define DISPLAYTEST_COLORS_COUNT_WG (sizeof(displaytest_colors_wide_gammut) / sizeof(displaytest_colors_wide_gammut[0])) + +int paint_displaytest(void) +{ + uint32_t cnt, displaytes_color_count; + uint32_t *displaytest_colors; + + if (!paint_ready) { + return 0; + } + if (paint_canvas->cs == CS_ARGB8101010) { + displaytest_colors = displaytest_colors_wide_gammut; + displaytes_color_count = DISPLAYTEST_COLORS_COUNT_WG; + } else { + displaytest_colors = displaytest_colors_argb; + displaytes_color_count = DISPLAYTEST_COLORS_COUNT_ARGB; + } + + for (cnt = 0; cnt < displaytes_color_count; cnt++) { + fill_rect(paint_canvas, cnt, cnt, window_width - (2 * cnt), window_height - (2 * cnt), displaytest_colors[cnt]); + } + + update_framebuffer(); + return 0; +} + +#endif + +static uint32_t pig_offset; +static uint32_t pig_bitpos; +static uint8_t pig_data; + +static void paint_install_gamma_table_channel(uint32_t entries, volatile uint32_t *channel_lut, const uint8_t *bits) +{ + uint32_t cnt; + uint16_t lasts; + uint8_t lastc; + int8_t nibble; + + nibble = 0; + lastc = 0; + lasts = 0; + + channel_lut[0] = lasts; + + pig_offset = 0; + pig_bitpos = 0; + pig_data = 0; + + for (cnt = 1; cnt < entries; cnt++) { + switch (paint_install_gamma_get_2bits(bits)) { + case 0: nibble = 0; break; + case 1: nibble = 1; break; + case 3: nibble = -1; break; + case 2: + nibble = paint_install_gamma_get_2bits(bits) | (paint_install_gamma_get_2bits(bits) << 2); + if ((nibble & 8) == 8) nibble |= 0xF0; + break; + } + + if (cnt == 1) nibble += 8; + + lastc += nibble; + lasts += lastc; + channel_lut[cnt] = lasts; + } +} + +static uint8_t paint_install_gamma_get_2bits(const uint8_t *bits) +{ + uint8_t bits2; + + if (pig_bitpos == 0) { + pig_data = bits[pig_offset++]; + } + + bits2 = (pig_data >> pig_bitpos) & 3; + + pig_bitpos += 2; + if (pig_bitpos == 8) pig_bitpos = 0; + + return bits2; +} + +void fill_rect(struct canvas *c, uint32_t top_x, uint32_t top_y, uint32_t w, uint32_t h, uint64_t color) +{ + uint32_t y; + + if (top_x >= c->x || top_y >= c->y) + return; + if (top_x + w > c->x) + w = c->x - top_x; + if (top_y + h > c->y) + h = c->y - top_y; + + for (y = top_y; y < top_y + h; y++) { + struct plane *p0 = &(c->planes[0]); + struct plane *p1 = &(c->planes[1]); + p0->hline(p0, top_x, y, w, color); + if (p1 && p1->hline) p1->hline(p1, top_x, y, w, color); + } +} + +void plot(struct plane *p, uint32_t x, uint32_t y, uint64_t color) +{ + p->plot(p, x, y, color); +} + +uint32_t get_pixel(struct plane *p, uint32_t x, uint32_t y) +{ + return p->get_pixel(p, x, y); +} + + +struct canvas *get_canvas(void) +{ + return paint_canvas; +} + +struct plane *get_plane(uint32_t plane_num) +{ + if (!paint_canvas) + return NULL; + + RELEASE_ASSERT(plane_num < MAX_NUM_PLANES_PER_CANVAS); + return (&(paint_canvas->planes[plane_num])); +} + + +#if SYSCFG_DCLR_OVERRIDE +// Testing function to permit specification of 'DClr' syscfg data in +// environment variables for devices that don't actually have 'DClr' yet. +static int dclrOverride(uint8_t *DClr, size_t length) +{ + unsigned int i, j; + const char *env; + size_t envLength; + uint8_t c; + + if ((DClr == NULL) || (length != sizeof(syscfg_DClr_t))) { + return -1; + } + + env = env_get("DClr_override"); + if (env == NULL) { + return -1; + } + + envLength = strlen(env); + if (envLength != (length * 2)) { + dprintf(DEBUG_CRITICAL, "DClr: DClr_override length is %zu should be %zu\n", envLength, length * 2); + return -1; + } + + for (i = 0; i < length; ++i) { + DClr[i] = 0; + for (j = 0; j < 2; ++j) { + c = *env++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + else { + dprintf(DEBUG_CRITICAL, "DClr: DClr_override: not a hex digit: %c\n", c); + return -1; + } + + DClr[i] += c << (4 * (1 - j)); + } + } + return length; +} +#endif // SYSCFG_DCLR_OVERRIDE + +#if SYSCFG_DCLR_COLOR_REPORT +static void report_color(const char *title, u_int8_t r, u_int8_t g, u_int8_t b) +{ + dprintf(DEBUG_INFO, "DClr: %s R/G/B = %d/%d/%d (0x%08X)\n", title, r, g, b, RGB(r, g, b)); +} +#endif + +int paint_color_map_get_DClr(syscfg_DClr_t *DClr, size_t size, bool report) +{ + int result; + bool die = false; + + // Validate parameters. + if ((DClr == NULL) || (size != sizeof(*DClr))) { + dprintf(DEBUG_CRITICAL, "DClr: paint_color_map_get_DClr: Bad parameters\n"); + die = PANIC_ON_SERIOUS_ERROR; + goto fail; + } + +#if SYSCFG_DCLR_OVERRIDE + result = dclrOverride((uint8_t *)DClr, size); + if (result == sizeof(*DClr)) { + dprintf(DEBUG_INFO, "DClr: Overriding syscfg data from environment\n"); + } else +#endif + { + // Look up the 'DClr' tag from syscfg. +#ifndef PAINT_UNITTEST + result = syscfgCopyDataForTag('DClr', (uint8_t *)DClr, sizeof(*DClr)); +#else + result = 0; +#endif + if (result < 0) { +#ifndef PAINT_UNITTEST + result = target_dclr_from_clrc((uint8_t *)DClr, sizeof(*DClr)); +#else + result = 0; +#endif + if (result < 0) { + dprintf(DEBUG_INFO, + "DClr: syscfg entry not found -- color remapping disabled\n"); + return 0; + } + } + } + + if (result != sizeof(*DClr)) { + dprintf(DEBUG_CRITICAL, "DClr: syscfgCopyDataForTag returned invalid length: %d\n", + result); + // Defer panic to bootprep if an attempt is made to boot an OS with this error enabled. + color_map_invalid |= PANIC_ON_SERIOUS_ERROR; + goto fail; + } + + switch (DCLR_VERSION(DClr->major_version, DClr->minor_version)) { + case DCLR_VERSION(2,0): + if (report) { +#if SYSCFG_DCLR_COLOR_REPORT + report_color("Device enclosure", + DClr->device_enclosure.component.red, + DClr->device_enclosure.component.green, + DClr->device_enclosure.component.blue); + report_color("Device cover glass", + DClr->cover_glass.component.red, + DClr->cover_glass.component.green, + DClr->cover_glass.component.blue); +#endif + } + break; + + default: + dprintf(DEBUG_CRITICAL, "DClr: Unknown version: %d.%d\n", + DClr->major_version, DClr->minor_version); + // Defer panic to bootprep if an attempt is made to boot an OS with this error enabled. + color_map_invalid |= mib_get_bool(kMIBTargetPanicOnUnknownDclrVersion); + goto fail; + } + + return result; + +fail: + if (die) { + panic("DClr: Fatal error"); + } + return 0; +} + +// Standard color remapping function for COLOR_MAP_POLICY_INVERT +static uint32_t invert_color_rbg888(uint64_t color) +{ + color ^= 0x00FFFFFF; + return color; +} + +static uint32_t invert_color_rbg101010(uint64_t color) +{ + color ^= 0x3FFFFFFF; + return color; +} + +void color_map_init(struct canvas *c) +{ + color_policy_t *target_policy; + syscfg_DClr_t DClr; + int result; + bool die = false; + + // Assume color remapping is not supported. + color_map_desired = false; + color_map_enabled = false; + color_map_supported = false; + color_map_invalid = false; + + // Must have a canvas. + if (c == NULL) { + dprintf(DEBUG_CRITICAL, "Bad parameter: color_map_init(NULL)\n"); + die = PANIC_ON_SERIOUS_ERROR; + goto fail; + } + + // We only support the RGB888 colorspace and ARGB8101010. + if ((c->cs != CS_RGB888) && (c->cs != CS_ARGB8101010)) { + dprintf(DEBUG_CRITICAL, "DClr: Only the RBG888 colorspace is supported\n"); + goto fail; + } + + // Ask the target what it's color remapping policy is. +#ifndef PAINT_UNITTEST + target_policy = target_color_map_init(c->cs, &color_policy); +#else + target_policy = 0; +#endif + if (target_policy == NULL) { + goto fail; + } + + switch (target_policy->policy_type) { + case COLOR_MAP_POLICY_NONE: // Standard policy: No color remapping + return; + + case COLOR_MAP_POLICY_INVERT: // Standard policy: Invert colors + { + color_policy_invert_t *color_table; // Target color table + uint32_t cover_glass; // Cover glass color + uint8_t r, g, b; // Color components + unsigned int i; + + // Validate what the target gave us. + if ((target_policy->color_table == NULL) || (target_policy->color_count == 0)) { + dprintf(DEBUG_CRITICAL, "target_color_map_init() returned invalid color table\n"); + die = PANIC_ON_SERIOUS_ERROR; + goto fail; + } + + // Look up the device's 'DClr' syscfg entry. + result = paint_color_map_get_DClr(&DClr, sizeof(DClr), true); + if (result != sizeof(DClr)) { + goto fail; + } + + // Get the cover glass color. + switch (DCLR_VERSION(DClr.major_version, DClr.minor_version)) { + + case DCLR_VERSION(2,0): + r = DClr.cover_glass.component.red; + g = DClr.cover_glass.component.green; + b = DClr.cover_glass.component.blue; + cover_glass = ColorRGB888(DClr.cover_glass.rgb); + break; + + default: + // Should have been caught in color_map_get_DClr(). + // Defer panic to bootprep if an attempt is made to + // boot an OS with this error enabled. + color_map_invalid |= PANIC_ON_SERIOUS_ERROR; + goto fail; + } + + // Get the target's inversion color table. + color_table = (color_policy_invert_t *)(target_policy->color_table); + + // Match the cover glass color against the expected colors for this target. + for (i = 0; i < target_policy->color_count; ++i) { + if (cover_glass == color_table[i].cover_glass) { + break; + } + } + + if (i >= target_policy->color_count) { + dprintf(DEBUG_CRITICAL, + "DClr: Unsupported cover glass color: R/G/B = %d/%d/%d (0x%08X)\n", + r, g, b, cover_glass); + // Defer panic to bootprep if an attempt is made to boot an OS with this error enabled. + color_map_invalid |= PANIC_ON_UNKNOWN_DCLR_COLOR; + goto fail; + } + + dprintf(DEBUG_INFO, "DClr: Color mapping policy is to %s colors\n", + color_table[i].invert ? "invert" : "keep"); + + // If the target policy is to invert the colors, then set the + // color remapping functions. Otherwise, leave the function + // pointers NULL to keep the source background/foreground colors. + if (color_table[i].invert) { + if (c->cs == CS_ARGB8101010) c->map_color = invert_color_rbg101010; + else c->map_color = invert_color_rbg888; + color_map_desired = true; + } + + color_map_supported = true; + return; + } + + default: + dprintf(DEBUG_CRITICAL, "target_color_map_init() returned unknown policy type: 0x%08X\n", + target_policy->policy_type); + die = PANIC_ON_SERIOUS_ERROR; + goto fail; + } + +fail: + color_policy.policy_type = COLOR_MAP_POLICY_NONE; + color_map_desired = false; + color_map_enabled = false; + color_map_supported = false; + + if (die) { + panic("DClr: Fatal error"); + } +} + +bool paint_color_map_enable(bool enable) +{ + bool result = color_map_enabled; + if (!color_map_supported) { + enable = false; + } + color_map_enabled = enable; + dprintf(DEBUG_SPEW, "DClr: Color remapping %sabled\n", + color_map_enabled ? "en" : "dis"); + + return result; +} + +bool paint_color_map_is_desired(void) +{ + return color_map_desired; +} + +bool paint_color_map_is_enabled(void) +{ + return color_map_enabled; +} + +bool paint_color_map_is_invalid(void) +{ + return color_map_invalid; +} + +enum color_map_policy paint_get_color_policy(void) +{ + enum color_map_policy policy = color_policy.policy_type; + + switch (policy) { + case COLOR_MAP_POLICY_NONE: + break; + + case COLOR_MAP_POLICY_INVERT: + if (!color_map_desired) { + policy = COLOR_MAP_POLICY_NONE; + } + break; + + default: + break; + } + + return policy; +} + +static addr_t alloc_display_valid_region_memory(size_t frame_size_in_bytes) +{ + RELEASE_ASSERT(page_size != 0); + RELEASE_ASSERT(last_canvas_addr != 0); + + addr_t addr = last_canvas_addr; + last_canvas_addr += (frame_size_in_bytes + page_size - 1) & ~((addr_t)(page_size - 1)); + + return addr; +} + +void display_init_alloc_mem(void * fb) +{ + page_size = mib_get_size(kMIBPlatformPageSize); + last_canvas_addr = (addr_t) fb; +} + +void set_canvas(struct canvas *c, void *fb, size_t region_size, uint32_t x, uint32_t y, uint32_t line_x, enum colorspace cs) +{ + struct plane *p = &(c->planes[0]); + struct plane *p1 = &(c->planes[1]); + + + switch(cs) { + case CS_4BPP: + c->num_of_active_planes = 1; + p->pixel_size = 4; + p->pixel_size_per_channel = 8; + p->width = x; + p->height = y; + p->stride = line_x * 1; // In bytes + p->plot = &plot4; + p->get_pixel = &get_pixel4; + p->hline = &hline4; + p->vline = &vline4; + break; + case CS_8BPP: + case CS_RGB332: + c->num_of_active_planes = 1; + p->pixel_size = 8; + p->pixel_size_per_channel = 8; + p->width = x; + p->height = y; + p->stride = line_x * 4; // In bytes + p->plot = &plot8; + p->get_pixel = &get_pixel8; + p->hline = &hline8; + p->vline = &vline8; + break; + case CS_RGB565: + case CS_ARGB1555: + case CS_ARGB4444: + c->num_of_active_planes = 1; + p->pixel_size = 16; + p->pixel_size_per_channel = 8; + p->width = x; + p->height = y; + p->stride = line_x * 4; // In bytes + p->plot = &plot16; + p->get_pixel = &get_pixel16; + p->hline = &hline16; + p->vline = &vline16; + break; + case CS_RGB888: + case CS_ARGB8888: + c->num_of_active_planes = 1; + p->pixel_size = 32; + p->pixel_size_per_channel = 8; + p->width = x; + p->height = y; + p->stride = line_x * 4; // In bytes + p->plot = &plot32; + p->get_pixel = &get_pixel32; + p->hline = &hline32; + p->vline = &vline32; + break; + //10-bit RGB components are stored in packed 4 bytes (same as RGB101010) in RGB10 plane. + //8-bit Alpha is stored in packed format in A8 plane + case CS_ARGB8101010: + c->num_of_active_planes = 2; + p->pixel_size = 32; + p->pixel_size_per_channel = 10; + p->width = x; + p->height = y; + p->stride = line_x * 4; // In bytes + p->plot = &plot32; + p->get_pixel = &get_pixel32; + p->hline = &hline32; + p->vline = &vline32; + p1->pixel_size = 8; + p1->pixel_size_per_channel = 8; + p1->width = x; + p1->height = y; + p1->stride = line_x * 1; // In bytes + p1->plot = &plot8; + p1->get_pixel = &get_pixel8; + p1->hline = &hline8; + p1->vline = &vline8; + break; + } + c->fb_virt = fb; + c->fb_phys = (uintptr_t)fb; + c->x = x; + c->y = y; + c->cs = cs; + c->map_color = NULL; + + //as pixel operations take time, directly drawing on canvas will generate blinking on animation + //so move the time consuming process on seperated buffer, and then copy the final result into canvas + //this process requires 2 buffers. The allocation will give the memory for HW used framebuffers, followed by the copies + display_init_alloc_mem(fb); + + addr_t plane_0_fb_addr, plane_0_db_addr, plane_1_fb_addr, plane_1_db_addr; + size_t plane_0_frame_size_in_bytes , plane_1_frame_size_in_bytes; + + plane_0_frame_size_in_bytes = y * line_x * c->planes[0].pixel_size/8; + if (c->num_of_active_planes > 1) plane_1_frame_size_in_bytes = y * line_x * c->planes[1].pixel_size/8; + + //Allocate plane0 framebuffer + plane_0_fb_addr = alloc_display_valid_region_memory(plane_0_frame_size_in_bytes); + //if needed, allocate plane1 framebuffer + if (c->num_of_active_planes > 1) plane_1_fb_addr = alloc_display_valid_region_memory(plane_1_frame_size_in_bytes); + + //Allocate plane0 buffer for drawing + plane_0_db_addr = alloc_display_valid_region_memory(plane_0_frame_size_in_bytes); + //Allocate plane1 buffer for drawing, if needed + if (c->num_of_active_planes > 1) plane_1_db_addr = alloc_display_valid_region_memory(plane_1_frame_size_in_bytes); + + set_plane(&(c->planes[0]), y, line_x, plane_0_frame_size_in_bytes, plane_0_fb_addr, plane_0_db_addr, cs); + if (c->num_of_active_planes > 1) set_plane(&(c->planes[1]), y, line_x, plane_1_frame_size_in_bytes, plane_1_fb_addr, plane_1_db_addr, cs); + + // Initialize color remapping if supported on this device. + color_map_init(c); +} + +static void set_plane(struct plane *p, uint32_t y, uint32_t line_x, size_t plane_size, addr_t plane_fb, addr_t plane_db, enum colorspace cs) +{ + p->line_x = line_x; + p->cs = cs; + p->fb_virt = (void *) plane_fb; + p->plane_size = plane_size; + p->db_virt = (void *) plane_db; +} + +static void plot4(struct plane *p, uint32_t x, uint32_t y, uint64_t color) +{ + panic("plot4 not implemented yet\n"); +} + +static void plot8(struct plane *p, uint32_t x, uint32_t y, uint64_t color) +{ + if (p->cs == CS_8BPP) color = ColorIndex8BPP(color); + else color = ColorRGB332(color); + + ((uint8_t *)p->db_virt)[y * p->line_x + x] = color; +} + +static void plot16(struct plane *p, uint32_t x, uint32_t y, uint64_t color) +{ + if (p->cs == CS_ARGB1555) color = ColorRGB555(color); + else if (p->cs == CS_ARGB4444) color = ColorRGB444(color); + else color = ColorRGB565(color); + + ((uint16_t *)p->db_virt)[y * p->line_x + x] = color; +} + +static void plot32(struct plane *p, uint32_t x, uint32_t y, uint64_t color) +{ + if (p->cs == CS_ARGB8101010) color = ColorRGB101010(color); + else color = ColorRGB888(color); + + ((uint32_t *)p->db_virt)[y * p->line_x + x] = color; +} + +static uint32_t get_pixel4(struct plane *p, uint32_t x, uint32_t y) +{ + panic("get_pixel4 not implemented yet\n"); + + return 0; +} + +static uint32_t get_pixel8(struct plane *p, uint32_t x, uint32_t y) +{ + panic("get_pixel8 not implemented yet\n"); + + return 0; +} + +static uint32_t get_pixel16(struct plane *p, uint32_t x, uint32_t y) +{ + panic("get_pixel16 not implemented yet\n"); + + return 0; + +} + +static uint32_t get_pixel32(struct plane *p, uint32_t x, uint32_t y) +{ + return ((uint32_t *)p->fb_virt)[y * p->line_x + x] & 0x00FFFFFF; +} + +static void hline4(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + panic("hline4 not implemented yet\n"); +} + +static void hline8(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + uint8_t *ptr; + + if (p->cs == CS_8BPP) color = ColorIndex8BPP(color); + else if (p->cs == CS_ARGB8101010) color = ColorA8(color); + else color = ColorRGB332(color); + + ptr = &((uint8_t *)p->db_virt)[y * p->line_x + x]; + while (len > 0) { + *ptr = color; + ptr++; + len--; + } +} + +static void hline16(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + uint16_t *ptr; + + if (p->cs == CS_ARGB1555) color = ColorRGB555(color); + else if (p->cs == CS_ARGB4444) color = ColorRGB444(color); + else color = ColorRGB565(color); + + ptr = &((uint16_t *)p->db_virt)[y * p->line_x + x]; + while (len > 0) { + *ptr = color; + ptr++; + len--; + } +} + +static void hline32(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + uint32_t *ptr; + + if (p->cs == CS_ARGB8101010) color = ColorRGB101010(color); + else color = ColorRGB888(color); + + ptr = &((uint32_t *)p->db_virt)[y * p->line_x + x]; + while (len > 0) { + *ptr = color; + ptr++; + len--; + } +} + +static void vline4(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + panic("vline4 not implemented yet\n"); +} + +static void vline8(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + uint8_t *ptr; + + if (p->cs == CS_8BPP) color = ColorIndex8BPP(color); + else color = ColorRGB332(color); + + ptr = &((uint8_t *)p->db_virt)[y * p->line_x + x]; + while (len > 0) { + *ptr = color; + ptr += p->line_x; + len--; + } +} + +static void vline16(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + uint16_t *ptr; + + if (p->cs == CS_ARGB1555) color = ColorRGB555(color); + else if (p->cs == CS_ARGB4444) color = ColorRGB444(color); + else color = ColorRGB565(color); + + ptr = &((uint16_t *)p->db_virt)[y * p->line_x + x]; + while (len > 0) { + *ptr = color; + ptr += p->line_x; + len--; + } +} + +static void vline32(struct plane *p, uint32_t x, uint32_t y, uint32_t len, uint64_t color) +{ + uint32_t *ptr; + + if (p->cs == CS_ARGB8101010) color = ColorRGB101010(color); + else color = ColorRGB888(color); + + ptr = &((uint32_t *)p->db_virt)[y * p->line_x + x]; + while (len > 0) { + *ptr = color; + ptr += p->line_x; + len--; + } +} + +#if DEBUG_BUILD +static char *cs_to_string(enum colorspace cs) { + + switch (cs) { + case CS_4BPP: return "4BPP"; + case CS_8BPP: return "8BPP"; + case CS_RGB332: return "RGB332"; + case CS_RGB565: return "RGB565"; + case CS_ARGB1555: return "ARGB1555"; + case CS_ARGB4444: return "ARGB4444"; + case CS_RGB888: return "RGB888"; + case CS_ARGB8888: return "ARGB8888"; + case CS_ARGB8101010: return "ARGB8101010"; + } +} + +void dump_paint_plane(struct plane *p, uint32_t plane_num) +{ + printf("\t\tPlane %d\n", plane_num); + printf("\t\t\tcs %s\n", cs_to_string(p->cs)); + printf("\t\t\tfb_virt %p\n", p->fb_virt); + printf("\t\t\tdb_virt %p\n", p->db_virt); + printf("\t\t\tplane_size %u\n", p->plane_size); + printf("\t\t\tpixel_size %u\n", p->pixel_size); + printf("\t\t\tpixel_size_per_channel %u\n", p->pixel_size_per_channel); + printf("\t\t\tline_x %u\n", p->line_x); + printf("\t\t\twidth %u\n", p->width); + printf("\t\t\theight %u\n", p->height); + printf("\t\t\tstride %u\n", p->stride); + printf("\t\t\tplot %p\n", p->plot); + printf("\t\t\tget_pixel %p\n", p->get_pixel); + printf("\t\t\thline %p\n", p->hline); + printf("\t\t\tvline %p\n", p->vline); + +} + +void dump_paint_canvas(struct canvas *c) +{ + printf("\tCanvas:\n"); + printf("\t\tcs %s\n", cs_to_string(c->cs)); + printf("\t\tnum_of_active_planes %u\n", c->num_of_active_planes); + printf("\t\tfb_virt %p\n", c->fb_virt); + printf("\t\tfb_phys %lu\n", c->fb_phys); + printf("\t\tx %u\n", c->x); + printf("\t\ty %u\n", c->y); + printf("\t\tmap_color %p\n", c->map_color); + for (uint32_t i = 0; i < c->num_of_active_planes; i++) { + dump_paint_plane(&(c->planes[i]), i); + } +} + +void dump_paint_information(struct display_window *w) +{ + printf("Window:\n"); + printf("\tactive\t%d\n", w->active); + printf("\tcs\t%d\n", w->cs); + printf("\tdepth\t%d\n", w->depth); + printf("\tpos_x\t%d\n", w->pos_x); + printf("\tpos_y\t%d\n", w->pos_y); + printf("\twidth\t%d\n", w->width); + printf("\theight\t%d\n", w->height); + printf("\tstride\t%d\n", w->stride); + dump_paint_canvas(&(w->c)); +} + +void display_paint_plane(uint32_t plane_num) +{ + struct plane *p = &(paint_canvas->planes[plane_num]); + dump_paint_plane(p, plane_num); +} + +void display_paint_canvas() +{ + dump_paint_canvas(paint_canvas); +} + +void display_paint_information() +{ + dump_paint_information(paint_window); +} +#endif // #if DEBUG_BUILD diff --git a/lib/paint/rules.mk b/lib/paint/rules.mk new file mode 100644 index 0000000..8cd9203 --- /dev/null +++ b/lib/paint/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2008, 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_PAINT=1 +MODULES += lib/lzss +LIBRARY_MODULES += lib/paint + diff --git a/lib/paint/tests.c b/lib/paint/tests.c new file mode 100644 index 0000000..9074f9c --- /dev/null +++ b/lib/paint/tests.c @@ -0,0 +1,212 @@ +#include +#include +#include +#include +#include +#include + +#define LINEAR_STRIDE_ALIGNMENT 64 +#define LINEAR_STRIDE_ALIGNMENT_MASK (LINEAR_STRIDE_ALIGNMENT - 1) +#define MAX_FLATTENED_HD_SIZE 0x1000 + +struct test_paint_data { + struct display_window w; + addr_t fb_base; + size_t fb_size; + enum colorspace color; + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; + addr_t scratch_base; + size_t scratch_size; +}; + +//Test Data +struct test_paint_data test_CS_RGB888_10_x_10 = { + .fb_size = 0, + .color = CS_RGB888, + .x = 0, + .y = 0, + .width = 10, + .height = 10, + .scratch_base = 0, + .scratch_size = 0, +}; + + +//BitMaps +uint8_t CS_RGB888_10_x_10_blue[] = +{ + //10 pixels, stride 64 = 1 horizontal row + //row 1 + //B G R A + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 2 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 3 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 4 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 5 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 6 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 7 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 8 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 9 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + //row 10 + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void test_suite_init_paint(void) +{ +} + +void test_paint_init_with_data(struct test_paint_data *data) +{ + TEST_ASSERT_NOT_NULL(data); + + uint32_t stridelen = data->width; + uint32_t depth; + + switch (data->color) { + case CS_RGB565 : + depth = 16; + break; + + case CS_RGB888 : + depth = 32; + break; + + default : + depth = 0; + break; + } + + data->w.active = false; + data->w.cs = data->color; + data->w.depth = depth; + data->w.pos_x = data->x; + data->w.pos_y = data->y; + data->w.width = data->width; + data->w.height = data->height; + stridelen = (stridelen * depth) / 8; + stridelen = (stridelen + LINEAR_STRIDE_ALIGNMENT_MASK) & ~LINEAR_STRIDE_ALIGNMENT_MASK; + data->w.stride = stridelen; + stridelen = stridelen / (depth/8); + //Minimum is a page + data->fb_size = (data->w.height * data->w.stride + 0xFFF) & ~0xFFF; + data->fb_base = (addr_t) malloc(data->fb_size); + TEST_ASSERT_NOT_NULL(data->fb_base); + + if (data->fb_base) bzero((void *)data->fb_base, data->fb_size); + set_canvas(&(data->w.c), (void *)data->fb_base, data->fb_size, data->width, data->height, stridelen, data->color); + + if (data->scratch_size == 0) { + //if not specified size, the assume fb_size and allocate another buffer + MAX_FLATTENED_HD_SIZE + data->scratch_size = data->fb_size + MAX_FLATTENED_HD_SIZE; + } + data->scratch_base = (addr_t) malloc(data->scratch_size); + bzero((void *)data->scratch_base, data->scratch_size); + TEST_ASSERT_EQ(paint_init((void *)&(data->w), data->scratch_base, data->scratch_size), 0); +} + +void test_paint_cleanup_with_data(struct test_paint_data *data) +{ + TEST_ASSERT_NOT_NULL(data); + TEST_ASSERT_NOT_NULL(data->fb_base); + TEST_ASSERT_NOT_NULL(data->scratch_base); + + free((void *)data->fb_base); + free((void *)data->scratch_base); +} + +static void hexdump(const void *_ptr, size_t len) +{ + const unsigned char *ptr = _ptr; + unsigned int i; + + printf("hexdump ptr %p, len %zd\n", ptr, len); + + while (len > 0) { + printf("%p: ", ptr); + for (i=0; i < __min(len, 16u); i++) { + printf("%02x ", *ptr); + ptr++; + } + printf("\n"); + if (len < 16) + break; + len -= 16; + } +} + +static uint32_t picture_scale_value = 2; +static uint32_t picture_rotate_value = 0; +static size_t page_size = 4 * 1024; +MIB_VARIABLE(kMIBTargetOsPictureScale, kOIDTypeInt32, picture_scale_value); +MIB_VARIABLE(kMIBTargetPictureRotate, kOIDTypeInt32, picture_rotate_value); +MIB_VARIABLE(kMIBPlatformPageSize, kOIDTypeSize, page_size); + +void test_paint_CS_RGB888_blue(uintptr_t param) +{ + struct test_paint_data * data; + data = &test_CS_RGB888_10_x_10; + test_paint_init_with_data(data); + size_t size_to_compare = data->w.height * data->w.stride; + size_t size_blue_bitmap = sizeof(CS_RGB888_10_x_10_blue)/sizeof(CS_RGB888_10_x_10_blue[0]); + + TEST_ASSERT_LTE(size_to_compare, size_blue_bitmap); + paint_set_bgcolor(0, 0, 0xff); + paint_update_image(); + //hexdump((void *)CS_RGB888_10_x_10_blue, size_blue_bitmap); + //hexdump((void *)data->fb_base, data->fb_size); + TEST_ASSERT_MEM_EQ(CS_RGB888_10_x_10_blue, data->fb_base, size_to_compare); + test_paint_cleanup_with_data(data); +} + +static struct test_suite paint_test_suite = { + .name = "paint", + .description = "tests the paint library", + .setup_function = test_suite_init_paint, + .test_cases = { + {"paint_CS_RGB888_blue", test_paint_CS_RGB888_blue, 0 }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(paint_test_suite); diff --git a/lib/paint/tests.mk b/lib/paint/tests.mk new file mode 100644 index 0000000..a491c81 --- /dev/null +++ b/lib/paint/tests.mk @@ -0,0 +1,26 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := paint + +TEST_OBJS := \ + $(LOCAL_DIR)/paint.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + lib/mib/mib.o \ + $(LOCAL_DIR)/tests.o + +TEST_CFLAGS := \ + -DPAINT_UNITTEST=1 + +include lib/mib/test-support.mk diff --git a/lib/paniclog/library.mk b/lib/paniclog/library.mk new file mode 100644 index 0000000..afd9db0 --- /dev/null +++ b/lib/paniclog/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBPANICLOG_DIR := $(GET_LOCAL_DIR) +LIBPANICLOG_BUILD := $(call TOLIBDIR,$(LIBPANICLOG_DIR)/LIBPANICLOG.a) +COMMONLIBS += LIBPANICLOG + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBPANICLOG_OBJS := $(LIBPANICLOG_DIR)/paniclog.o + +LIBPANICLOG_OBJS := $(call TOLIBOBJDIR,$(LIBPANICLOG_OBJS)) + +ALL_DEPS += $(LIBPANICLOG_OBJS:%o=%d) + +$(LIBPANICLOG_BUILD): $(LIBPANICLOG_OBJS) + +endif diff --git a/lib/paniclog/paniclog.c b/lib/paniclog/paniclog.c new file mode 100644 index 0000000..73521b9 --- /dev/null +++ b/lib/paniclog/paniclog.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2010, 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include /* for platform_cache_operation() */ +#include +#include +#include + +/* If the panic ram area is large enough, use copies to improve + * resilience against errors. */ +#define PANIC_MIN_SIZE_FOR_COPIES (16 * 1024) + +/* The number of copies (including the original) to make of the entire + * panic log, including headers, if the area is large enough. This + * provides a minimum of 2664 (after 8->7 bit packing and headers) + * bytes of contained log data. */ +#define PANIC_COPIES 7 + +#define PANIC_BDEV_NAME "paniclog" + +struct vram_panic { + uint32_t magic; + uint32_t crc; + char buf[]; +}; + +void clear_panic_region(unsigned char pattern) +{ + void *panicBufferAddr = (void *)mib_get_addr(kMIBTargetPanicBufferAddress); + size_t panicBufferSize = mib_get_size(kMIBTargetPanicBufferSize); + + /* clear the panic area to a pattern. values other than 0 useful for debug */ + memset(panicBufferAddr, pattern, panicBufferSize); + /* ensure this reaches DRAM */ +#if defined(__arm64__) + /* on coherent archs (H6+), force a cache clean by adding invalidate flag, and specifying address and size */ + platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE | CACHE_DRAIN_WRITE_BUFFER, panicBufferAddr, panicBufferSize); +#else + platform_cache_operation(CACHE_CLEAN | CACHE_DRAIN_WRITE_BUFFER, NULL, 0); +#endif +} + +// arm64 targets only have the new panic log format. +// armv7? targets may have either. +int save_panic_log(void) +{ + struct vram_panic *vpi = NULL; + void *panic_buf = NULL; + uint32_t panic_text_len; + addr_t panicBufferAddr = mib_get_addr(kMIBTargetPanicBufferAddress); + size_t panicBufferSize = mib_get_size(kMIBTargetPanicBufferSize); + +#if !defined(__arm64__) + if (mib_get_bool(kMIBTargetWithLegacyPanicLogs)) { + struct { + unsigned a:7; + unsigned b:7; + unsigned c:7; + unsigned d:7; + unsigned e:7; + unsigned f:7; + unsigned g:7; + unsigned h:7; + } __attribute__((packed)) pack; + + uint32_t panic_size; + int i, panic_copies; + + if (panicBufferSize >= PANIC_MIN_SIZE_FOR_COPIES) { + panic_size = panicBufferSize / PANIC_COPIES; + panic_copies = PANIC_COPIES; + } else { + panic_size = panicBufferSize; + panic_copies = 1; + } + panic_text_len = panic_size - 8; + + /* find an intact copy */ + for (i = 0; i < panic_copies; ++i) { + vpi = (struct vram_panic *) (panicBufferAddr + i * panic_size); + /* check for magic header */ + if (vpi->magic != 0x4F4F5053 /* 'OOPS' */) { + continue; + } + /* check CRC */ + if (vpi->crc != crc32((unsigned char *) vpi->buf, panic_text_len)) { + continue; + } + /* this copy is very likely intact */ + panic_buf = vpi->buf; + break; + } + + /* failed to find an intact copy? */ + if (panic_buf == NULL) { + /* Don't attempt correction. This method should have + * been resilient enough that at least one copy + * survived. Log this CRC error. */ + pack.a = 0x43; /* 'C' */ + pack.b = 0x52; /* 'R' */ + pack.c = 0x43; /* 'C' */ + pack.d = 0x20; /* ' ' */ + pack.e = 0x45; /* 'E' */ + pack.f = 0x52; /* 'R' */ + pack.g = 0x52; /* 'R' */ + pack.h = 0x21; /* '!' */ + panic_buf = &pack; + panic_text_len = sizeof(pack); + } + + /* write the panic to the nvram partition */ + if (nvram_set_panic(panic_buf, panic_text_len) < 0) { + clear_panic_region(0xe1); + return -1; + } + + /* wipe the area so we don't produce duplicate logs */ + clear_panic_region(0); + + /* save nvram */ + if (nvram_save() < 0) { + clear_panic_region(0xe2); + return -1; + } + + return 0; + } +#endif // !defined(__arm64__) + + int err; + struct blockdev *dev; + const char *crc_err = "CRC ERR!"; + + ASSERT(!mib_get_bool(kMIBTargetWithLegacyPanicLogs)); + + panic_text_len = panicBufferSize - 8; + vpi = (struct vram_panic *) panicBufferAddr; + /* check for magic header 'DARN'/'SICK' and CRC value */ + if ((vpi->magic == 0x4441524E || vpi->magic == 0x5349434B) && + vpi->crc == crc32((unsigned char *) vpi->buf, panic_text_len)) { + /* this copy is very likely intact */ + panic_buf = vpi->buf; + } else { + /* failed to match DARN magic header or CRC */ + /* Don't attempt correction. Log this CRC error. */ + panic_buf = (void*)crc_err; + panic_text_len = sizeof(*crc_err); + } + dev = lookup_blockdev(PANIC_BDEV_NAME); + if (!dev) { + dprintf(DEBUG_CRITICAL, "Couldn't find block device '%s'\n", PANIC_BDEV_NAME); + clear_panic_region(0xe1); + return -1; + } + err = blockdev_write(dev, (void *)panic_buf, 0, panic_text_len); + if (err <= 0) { + dprintf(DEBUG_CRITICAL, "blockdev_write to '%s' device failed with return value %d\n", + PANIC_BDEV_NAME, err); + clear_panic_region(0xe2); + return -1; + } + + /* wipe the area so we don't produce duplicate logs */ + clear_panic_region(0); + + return 0; +} + diff --git a/lib/paniclog/rules.mk b/lib/paniclog/rules.mk new file mode 100644 index 0000000..6684dfa --- /dev/null +++ b/lib/paniclog/rules.mk @@ -0,0 +1,12 @@ +# Copyright (c) 2010, 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +MODULES += lib/nvram +LIBRARY_MODULES += lib/paniclog + diff --git a/lib/partition/gpt.c b/lib/partition/gpt.c new file mode 100644 index 0000000..6b863cb --- /dev/null +++ b/lib/partition/gpt.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2010-2011, 2013-2014 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include + +#include "partition_private.h" + +struct gpt_pth { + char sig[8]; +#define PTH_SIGNATURE "EFI PART" + uint32_t revision; +#define PTH_REVISION 0x00010000 + uint32_t hsize; + uint32_t hcrc; + uint32_t reserved; + uint64_t this_lba; + uint64_t backup_lba; + uint64_t first_lba; + uint64_t last_lba; + uint8_t uuid[16]; + uint64_t ptab_lba; + uint32_t ptab_entrycount; + uint32_t ptab_entrysize; + uint32_t ptab_crc; +}; + +struct gpt_pte { + uint8_t ptype_uuid[16]; + uint8_t unique_uuid[16]; + uint64_t first_lba; + uint64_t last_lba; + uint64_t attributes; +#define PATTR_SYSTEM (1ULL<<0) +#define PATTR_READONLY (1ULL<<60) +#define PATTR_HIDDEN (1ULL<<62) +#define PATTR_NOMOUNT (1ULL<<63) + uint16_t name[36]; +}; + + +/* + * Known UUIDs. Note that these are in the inexplicable + * pre-swapped form. + */ + +static uint8_t ptype_hfs[] __unused = { + 0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11, + 0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac +}; + +static uint8_t ptype_bdp[] __unused = { + 0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44, + 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 +}; + +int +gpt_scan(struct blockdev *dev, struct partition_entry *entry_list) +{ + unsigned int entry, part; + off_t cursor; + struct gpt_pth *pth; + struct gpt_pte *pte; + const char *reason; + size_t cacheLineSize = mib_get_size(kMIBPlatformCacheLineSize); + + pth = NULL; + pte = NULL; + entry = 0; + reason = NULL; + + /* allocate buffers */ + pth = memalign(sizeof(*pth), cacheLineSize); + pte = memalign(sizeof(*pte), cacheLineSize); + + /* read the partition table header from LBA 1 */ + if (sizeof(*pth) != blockdev_read(dev, pth, dev->block_size, sizeof(*pth))) { + reason = "read error"; + goto out; + } + if (memcmp(pth->sig, PTH_SIGNATURE, 8)) { + reason = "bad signature"; + goto out; + } + if (PTH_REVISION != pth->revision) { + reason = "bad revision"; + goto out; + } + if (pth->ptab_entrysize < sizeof(*pte)) { + reason = "entries too small"; + goto out; + } + + /* set up to scan partition table entries */ + cursor = pth->ptab_lba << dev->block_shift; + + part = 0; + while ((entry < MAX_PARTITIONS) && (part++ < pth->ptab_entrycount)) { + /* read an entry */ + if (sizeof(*pte) != blockdev_read(dev, pte, cursor, sizeof(*pte))) { + reason = "read error"; + goto out; + } + cursor += pth->ptab_entrysize; + + /* skip no-mount entries */ + if (pte->attributes & PATTR_NOMOUNT) { + continue; + } + + /* assume not valid */ + entry_list[entry].valid = false; + + /* handle recognised partition types */ + dprintf(DEBUG_SPEW, "gpt: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + pte->ptype_uuid[0], pte->ptype_uuid[1], pte->ptype_uuid[2], pte->ptype_uuid[3], + pte->ptype_uuid[4], pte->ptype_uuid[5], pte->ptype_uuid[6], pte->ptype_uuid[7], + pte->ptype_uuid[8], pte->ptype_uuid[9], pte->ptype_uuid[10], pte->ptype_uuid[11], + pte->ptype_uuid[12], pte->ptype_uuid[13], pte->ptype_uuid[14], pte->ptype_uuid[15]); +//#if WITH_HFS + if (!memcmp(pte->ptype_uuid, ptype_hfs, 16)) { + entry_list[entry].valid = true; + entry_list[entry].id = 0xaf; /* HFS+ */ + } +//#endif + if (!entry_list[entry].valid) + continue; + + /* calculate partition layout */ + entry_list[entry].offset = (off_t)pte->first_lba << dev->block_shift; + entry_list[entry].len = (off_t)(pte->last_lba - pte->first_lba + 1) << dev->block_shift; + entry++; + } + +out: + if (NULL != pte) + free(pte); + if (NULL != pth) + free(pth); + if (NULL != reason) + dprintf(DEBUG_INFO, "gpt: %s\n", reason); + return entry; +} diff --git a/lib/partition/library.mk b/lib/partition/library.mk new file mode 100644 index 0000000..7589374 --- /dev/null +++ b/lib/partition/library.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBPARTITION_DIR := $(GET_LOCAL_DIR) +LIBPARTITION_BUILD := $(call TOLIBDIR,$(LIBPARTITION_DIR)/LIBPARTITION.a) +COMMONLIBS += LIBPARTITION + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBPARTITION_OBJS := \ + $(LIBPARTITION_DIR)/gpt.o \ + $(LIBPARTITION_DIR)/lwvm.o \ + $(LIBPARTITION_DIR)/mbr.o \ + $(LIBPARTITION_DIR)/partition.o + +LIBPARTITION_OBJS := $(call TOLIBOBJDIR,$(LIBPARTITION_OBJS)) + +ALL_DEPS += $(LIBPARTITION_OBJS:%o=%d) + +$(LIBPARTITION_BUILD): $(LIBPARTITION_OBJS) + +endif diff --git a/lib/partition/lwvm.c b/lib/partition/lwvm.c new file mode 100644 index 0000000..456b835 --- /dev/null +++ b/lib/partition/lwvm.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2010-2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include + +#include +#include +#include + +/* + * Cutdown types from LwVMFormat.h + */ + +#pragma pack(push, 1) + +#define kLwVMMaxChunks 1024 +#define kLwVMMaxPartitions 8 +#define kLwVMPartitionAttributeEffaceable (1ULL<<48) + +#define LwVM_CME_TO_PARTITION(_CME) (((_CME) >> 12) & 0xf) +#define LwVM_CME_TO_INDEX(_CME) ((_CME) & 0x3ff) + +typedef unsigned char uuid_t[16]; +typedef uint16_t LwVMChunkMapEntry; +typedef uint16_t LwVMChunkIndex; + +static const uuid_t LwVMMediaUUIDv1 = { + 0xB1, 0x89, 0xA5, 0x19, 0x4F, 0x59, 0x4B, 0x1D, + 0xAD, 0x44, 0x1E, 0x12, 0x7A, 0xAF, 0x45, 0x39 +}; + +static const uuid_t LwVMMediaUUIDv2 = { + 0x6A, 0x90, 0x88, 0xCF, 0x8A, 0xFD, 0x63, 0x0A, + 0xE3, 0x51, 0xE2, 0x48, 0x87, 0xE0, 0xB9, 0x8B +}; + +static const uint16_t UpgradePartitionName[] = { + 'U', 'p', 'd', 'a', 't', 'e', '\0', +}; + +typedef struct { + uuid_t miLwVMUUID; + uuid_t miThisUUID; + uint64_t miBaseMediaSize; + uint32_t miPartitionCount; + uint32_t miCRC; // not present in v1 +} LwVMMediaInfo; + +typedef struct { + uuid_t peType; + uuid_t peUUID; + uint64_t peStart; + uint64_t peEnd; + uint64_t peAttributes; + uint16_t peName[36]; +} LwVMPartitionEntry; + +typedef struct +{ + LwVMMediaInfo mhInfo; + uint8_t _pad1[512 - sizeof(LwVMMediaInfo)]; + LwVMPartitionEntry mhPartitionTable[kLwVMMaxPartitions]; + uint8_t _pad2[1536 - + (sizeof(LwVMPartitionEntry) * + kLwVMMaxPartitions)]; + LwVMChunkMapEntry mhChunkMap[kLwVMMaxChunks]; +} LwVMMediaHeader; + +#pragma pack(pop) + + +/* + * LwVM blockdev + */ +struct lwvm_partition { + struct blockdev thisdev; + struct blockdev *parent; + uint32_t chunk_size; /* chunk size in blocks */ + uint32_t chunk_shift; /* log2(chunk_size) */ + uint32_t chunk_count; + uint16_t chunk_map[kLwVMMaxChunks]; /* XXX could dynamically allocate */ +}; + +static void lwvm_scan_partition(struct blockdev *bdev, LwVMMediaHeader *header, int partition); +static int lwvm_read_block(struct blockdev *dev, void *ptr, block_addr block, uint32_t count); + +int +lwvm_scan(struct blockdev *dev) +{ + LwVMMediaHeader *header; + uint32_t i; + int ret; + uint32_t crc; + int tried; + uint32_t chunk_shift, chunk_size; + + ret = -1; + header = NULL; + header = memalign(sizeof(*header), dev->alignment); + memset(header, 0, sizeof(*header)); + + /* do required geometry calculations */ + chunk_shift = 32 - clz((uint32_t)((dev->total_len - 1) / kLwVMMaxChunks)); + chunk_size = 1 << chunk_shift; + + /* read the media header */ + for (tried = 0; tried < 2; tried++) { + /* + * Read either the main header from 0, or the backup header from the last block of the + * first chunk. + */ + if (blockdev_read(dev, + header, + (tried ? (((off_t)chunk_size << dev->block_shift) - dev->block_size) : 0), + sizeof(*header)) + != sizeof(*header)) + continue; + + /* check to see whether it's LwVM */ + if (memcmp(header->mhInfo.miLwVMUUID, LwVMMediaUUIDv2, 16) == 0) { + crc = header->mhInfo.miCRC; + header->mhInfo.miCRC = 0; + if (crc != crc32((void *)header, sizeof(*header))) { + /* v2 but corrupt */ + continue; + } + + if (header->mhInfo.miPartitionCount > kLwVMMaxPartitions) + continue; + + goto valid; + } + if (memcmp(header->mhInfo.miLwVMUUID, LwVMMediaUUIDv1, 16) == 0) { + if (header->mhInfo.miPartitionCount > kLwVMMaxPartitions) + continue; + + goto valid; + } + } + goto out; + +valid: + /* create partitions */ + for (i = 0; i < header->mhInfo.miPartitionCount; i++) + lwvm_scan_partition(dev, header, i); + + ret = header->mhInfo.miPartitionCount; +out: + if (NULL != header) + free(header); + return(ret); +} + +static void +lwvm_scan_partition(struct blockdev *dev, LwVMMediaHeader *header, int partition) +{ + struct lwvm_partition *part; + LwVMChunkMapEntry cme; + LwVMChunkIndex ci; + int i; + char dev_name[32]; + block_addr total_blocks; + uint64_t partition_blockcount; + + if (header->mhPartitionTable[partition].peAttributes & kLwVMPartitionAttributeEffaceable) { +#if DEBUG_BUILD + printf("enumerating effaceable LwVM partition\n"); +#else + /* ignore effaceable partitions, as we can't get their keys */ + return; +#endif + } + part = calloc(sizeof(*part), 1); + + part->parent = dev; + + /* do required geometry calculations */ + total_blocks = dev->total_len >> dev->block_shift; + part->chunk_shift = 32 - clz((uint32_t)((total_blocks - 1) / kLwVMMaxChunks)); + part->chunk_size = 1 << part->chunk_shift; + + /* scan chunk map in header for chunks belonging to this partition */ + for (i = 1; i < kLwVMMaxChunks; i++) { + + cme = header->mhChunkMap[i]; + + /* if it matches this partition */ + if (LwVM_CME_TO_PARTITION(cme) == partition) { + /* register it in the map */ + ci = LwVM_CME_TO_INDEX(cme); + part->chunk_map[ci] = i; + if (ci >= part->chunk_count) + part->chunk_count = ci + 1; + } + } + + partition_blockcount = header->mhPartitionTable[partition].peEnd - header->mhPartitionTable[partition].peStart; + + /* construct the device */ + snprintf(dev_name, sizeof(dev_name), "%s%c", dev->name, 'a' + partition); + construct_blockdev(&part->thisdev, dev_name, partition_blockcount, dev->block_size); + part->thisdev.read_block_hook = &lwvm_read_block; + blockdev_set_buffer_alignment(&part->thisdev, dev->alignment); + + /* Check if this is the upgrade partition */ + if (memcmp(UpgradePartitionName, header->mhPartitionTable[partition].peName, sizeof(UpgradePartitionName)) == 0) { + part->thisdev.flags |= BLOCKDEV_FLAG_UPGRADE_PARTITION; + } + + /* register the device */ + register_blockdev(&part->thisdev); +} + +static int +lwvm_read_block(struct blockdev *dev, void *ptr, block_addr block, uint32_t count) +{ + struct lwvm_partition *part; + LwVMChunkIndex ci; + uint8_t *buf; + off_t offset; + size_t read_size; + block_addr chunk_start; + size_t resid; + int ret; + + part = (struct lwvm_partition *)dev; + buf = (uint8_t *)ptr; + resid = count; + + /* iterate reading from chunk(s) until we are done */ + while (resid > 0) { + + /* + * Compute the chunk index into the partition, and the + * block offset into the chunk. + */ + ci = block >> part->chunk_shift; + offset = block & (part->chunk_size - 1); + + /* are we off the end of the partition? */ + if (ci >= part->chunk_count) + break; + + /* find the starting block for the indexed chunk */ + chunk_start = (block_addr)part->chunk_map[ci] << part->chunk_shift;; + + /* read no more than one chunk */ + ASSERT(offset >= 0); + read_size = __min(resid, part->chunk_size - (size_t)offset); + + /* do the read */ + ret = blockdev_read_block(part->parent, buf, chunk_start + offset, read_size); + if (ret <= 0) + return(ret); + + /* update for data read */ + resid -= ret; + block += ret; + buf += ret << dev->block_shift; + } + return(count - resid); +} diff --git a/lib/partition/mbr.c b/lib/partition/mbr.c new file mode 100644 index 0000000..b824777 --- /dev/null +++ b/lib/partition/mbr.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include + +#include "partition_private.h" + +int +mbr_scan(struct mbr_partition *part, struct blockdev *dev, struct partition_entry *entry_list) +{ + uint32_t i; + int scanned_entries = 0; + + for (i=0; i < MBR_PARTITIONS; i++) { + dprintf(DEBUG_SPEW, "MBR part %d: id 0x%x, startlba %d, sizelba %d\n", i, part[i].sysid, part[i].startlba, part[i].size); + + /* needs to be spiffed up a bit, but detect based on id */ + if (part[i].sysid != 0) { + off_t offset; + off_t len; + + offset = (off_t)part[i].startlba << dev->block_shift; + len = (off_t)part[i].size << dev->block_shift; + + entry_list[scanned_entries].id = part[i].sysid; + entry_list[scanned_entries].valid = true; + entry_list[scanned_entries].offset = offset; + entry_list[scanned_entries].len = len; + dprintf(DEBUG_SPEW, "MBR part %d: id 0x%x, off 0x%llx, size 0x%llx, blocksize %d\n", scanned_entries, part[i].sysid, + entry_list[scanned_entries].offset, entry_list[scanned_entries].len, dev->block_size); + scanned_entries++; + } + } + + return scanned_entries; +} diff --git a/lib/partition/partition.c b/lib/partition/partition.c new file mode 100644 index 0000000..e8126a2 --- /dev/null +++ b/lib/partition/partition.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2007, 2009-2011, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#include "partition_private.h" + +static bool +partition_overlap_check(struct partition_entry *part, int num_entries) +{ + int i, j; + bool overlap; + + overlap = false; + for (i=0; i < num_entries; i++) { + off_t ioff = part[i].offset; + off_t iend = part[i].offset + part[i].len; + for (j=0; j < num_entries; j++) { + if (i == j) + continue; + + off_t joff = part[j].offset; + off_t jend = part[j].offset + part[j].len; + + /* is j's starting offset within i's range */ + if ((joff >= ioff) && (joff < iend)) + overlap = true; + + /* is j's end within i's range */ + if ((jend <= iend) && (jend > ioff)) + overlap = true; + + /* does j completely cover i */ + if ((joff <= ioff) && (jend >= iend)) + overlap = true; + } + } + + if (overlap) + dprintf(DEBUG_INFO, "partition_scan: some partitions overlap, probably garbage partition data\n"); + return overlap; +} + +static bool +partition_extents_check(struct partition_entry *part, int num_entries, struct blockdev *dev) +{ + int i; + bool toobig; + + toobig = false; + for (i=0; i < num_entries; i++) { + if (part[i].offset + part[i].len > dev->total_len) { + dprintf(DEBUG_INFO, "partition %i overshoots size of device\n", i); + toobig = true; + } + } + + return toobig; +} + +static int +partition_scan(struct blockdev *dev, struct partition_entry *entry_list, size_t num_entries) +{ + int scanned_entries; + int err; + struct mbr_partition *part; + int mbr_bytes; + + scanned_entries = 0; + part = NULL; + mbr_bytes = MBR_PARTITIONS * sizeof(struct mbr_partition); + + /* read what we expect to be an MBR from the beginning of the blockdev */ + part = memalign(mbr_bytes, mib_get_size(kMIBPlatformCacheLineSize)); + + /* read *just* the partition table */ + err = blockdev_read(dev, part, MBR_ADDRESS, mbr_bytes); + if (err != mbr_bytes) { + dprintf(DEBUG_INFO, "mbr: read error\n"); + goto out; + } + + /* scan it as an mbr */ + scanned_entries = mbr_scan(part, dev, entry_list); + + /* does it look like it might be GPT? */ + if ((scanned_entries == 1) && (entry_list[0].id == 0xee)) + scanned_entries = gpt_scan(dev, entry_list); + + /* do an overlap check to make sure this is a sort of reasonable layout */ + if (partition_overlap_check(entry_list, scanned_entries)) { + scanned_entries = 0; + goto out; + } +out: + if (NULL != part) + free(part); + return scanned_entries; +} + +int partition_scan_and_publish_subdevices(const char *dev_name) +{ + struct partition_entry entries[MAX_PARTITIONS]; + int found; + int i; + struct blockdev *dev; + + dev = lookup_blockdev(dev_name); + if (!dev) + return -1; + + /* scan for LwVM partitions */ + found = lwvm_scan(dev); + if (found > 0) + return found; + + /* scan for regular partitions */ + found = partition_scan(dev, entries, MAX_PARTITIONS); + for (i=0; i < found; i++) { + /* publish subdevices */ + struct blockdev *subdev; + char subdev_name[32]; + + snprintf(subdev_name, 32, "%s%c", dev_name, 'a' + i); + + // make sure it doesn't already exist + if (lookup_blockdev(subdev_name)) + continue; + + subdev = create_subdev_blockdev(subdev_name, dev, entries[i].offset, entries[i].len, dev->block_size); + if (subdev) + register_blockdev(subdev); + } + + return found; +} diff --git a/lib/partition/partition_private.h b/lib/partition/partition_private.h new file mode 100644 index 0000000..b2f935d --- /dev/null +++ b/lib/partition/partition_private.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006-2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#define MAX_PARTITIONS 8 + +struct partition_entry { + bool valid; + uint32_t id; + off_t offset; + uint64_t len; +}; + +extern int gpt_scan(struct blockdev *dev, struct partition_entry *entry_list); + +#define MBR_PARTITIONS 4 +#define MBR_ADDRESS 0x1be + +struct mbr_partition { + uint8_t bootid; + uint8_t starthead; + uint8_t startsect; + uint8_t startcyl; + uint8_t sysid; + uint8_t endhead; + uint8_t endsect; + uint8_t endcyl; + uint32_t startlba; + uint32_t size; +} __packed; + +extern int mbr_scan(struct mbr_partition *part, struct blockdev *dev, struct partition_entry *entry_list); + +extern int lwvm_scan(struct blockdev *dev); diff --git a/lib/partition/rules.mk b/lib/partition/rules.mk new file mode 100644 index 0000000..e9d442b --- /dev/null +++ b/lib/partition/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 20010, 2013-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +MODULES += lib/cksum +LIBRARY_MODULES += lib/partition +OPTIONS += WITH_PARTITION=1 + diff --git a/lib/pki/apple_ca.h b/lib/pki/apple_ca.h new file mode 100644 index 0000000..363367b --- /dev/null +++ b/lib/pki/apple_ca.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_CA_H +#define __APPLE_CA_H + +#if PKI_CHECK_ANCHOR_BY_SHA1 + +static const unsigned char ROOT_CA_SHA1_HASH[20] = { + 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58, + 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60 }; + +#else + +static const unsigned char ROOT_CA_CERTIFICATE[1215] = { +0x30,0x82,0x04,0xBB,0x30,0x82,0x03,0xA3,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x02, +0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, +0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13, +0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49, +0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70, +0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, +0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06, +0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74, +0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x34,0x32,0x35,0x32,0x31,0x34, +0x30,0x33,0x36,0x5A,0x17,0x0D,0x33,0x35,0x30,0x32,0x30,0x39,0x32,0x31,0x34,0x30, +0x33,0x36,0x5A,0x30,0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, +0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70, +0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B, +0x13,0x1D,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, +0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31, +0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20, +0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A, +0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30, +0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE4,0x91,0xA9,0x09,0x1F,0x91,0xDB,0x1E, +0x47,0x50,0xEB,0x05,0xED,0x5E,0x79,0x84,0x2D,0xEB,0x36,0xA2,0x57,0x4C,0x55,0xEC, +0x8B,0x19,0x89,0xDE,0xF9,0x4B,0x6C,0xF5,0x07,0xAB,0x22,0x30,0x02,0xE8,0x18,0x3E, +0xF8,0x50,0x09,0xD3,0x7F,0x41,0xA8,0x98,0xF9,0xD1,0xCA,0x66,0x9C,0x24,0x6B,0x11, +0xD0,0xA3,0xBB,0xE4,0x1B,0x2A,0xC3,0x1F,0x95,0x9E,0x7A,0x0C,0xA4,0x47,0x8B,0x5B, +0xD4,0x16,0x37,0x33,0xCB,0xC4,0x0F,0x4D,0xCE,0x14,0x69,0xD1,0xC9,0x19,0x72,0xF5, +0x5D,0x0E,0xD5,0x7F,0x5F,0x9B,0xF2,0x25,0x03,0xBA,0x55,0x8F,0x4D,0x5D,0x0D,0xF1, +0x64,0x35,0x23,0x15,0x4B,0x15,0x59,0x1D,0xB3,0x94,0xF7,0xF6,0x9C,0x9E,0xCF,0x50, +0xBA,0xC1,0x58,0x50,0x67,0x8F,0x08,0xB4,0x20,0xF7,0xCB,0xAC,0x2C,0x20,0x6F,0x70, +0xB6,0x3F,0x01,0x30,0x8C,0xB7,0x43,0xCF,0x0F,0x9D,0x3D,0xF3,0x2B,0x49,0x28,0x1A, +0xC8,0xFE,0xCE,0xB5,0xB9,0x0E,0xD9,0x5E,0x1C,0xD6,0xCB,0x3D,0xB5,0x3A,0xAD,0xF4, +0x0F,0x0E,0x00,0x92,0x0B,0xB1,0x21,0x16,0x2E,0x74,0xD5,0x3C,0x0D,0xDB,0x62,0x16, +0xAB,0xA3,0x71,0x92,0x47,0x53,0x55,0xC1,0xAF,0x2F,0x41,0xB3,0xF8,0xFB,0xE3,0x70, +0xCD,0xE6,0xA3,0x4C,0x45,0x7E,0x1F,0x4C,0x6B,0x50,0x96,0x41,0x89,0xC4,0x74,0x62, +0x0B,0x10,0x83,0x41,0x87,0x33,0x8A,0x81,0xB1,0x30,0x58,0xEC,0x5A,0x04,0x32,0x8C, +0x68,0xB3,0x8F,0x1D,0xDE,0x65,0x73,0xFF,0x67,0x5E,0x65,0xBC,0x49,0xD8,0x76,0x9F, +0x33,0x14,0x65,0xA1,0x77,0x94,0xC9,0x2D,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01, +0x7A,0x30,0x82,0x01,0x76,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04, +0x04,0x03,0x02,0x01,0x06,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, +0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, +0x14,0x2B,0xD0,0x69,0x47,0x94,0x76,0x09,0xFE,0xF4,0x6B,0x8D,0x2E,0x40,0xA6,0xF7, +0x47,0x4D,0x7F,0x08,0x5E,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, +0x80,0x14,0x2B,0xD0,0x69,0x47,0x94,0x76,0x09,0xFE,0xF4,0x6B,0x8D,0x2E,0x40,0xA6, +0xF7,0x47,0x4D,0x7F,0x08,0x5E,0x30,0x82,0x01,0x11,0x06,0x03,0x55,0x1D,0x20,0x04, +0x82,0x01,0x08,0x30,0x82,0x01,0x04,0x30,0x82,0x01,0x00,0x06,0x09,0x2A,0x86,0x48, +0x86,0xF7,0x63,0x64,0x05,0x01,0x30,0x81,0xF2,0x30,0x2A,0x06,0x08,0x2B,0x06,0x01, +0x05,0x05,0x07,0x02,0x01,0x16,0x1E,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x77, +0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x61,0x70,0x70, +0x6C,0x65,0x63,0x61,0x2F,0x30,0x81,0xC3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, +0x02,0x02,0x30,0x81,0xB6,0x1A,0x81,0xB3,0x52,0x65,0x6C,0x69,0x61,0x6E,0x63,0x65, +0x20,0x6F,0x6E,0x20,0x74,0x68,0x69,0x73,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69, +0x63,0x61,0x74,0x65,0x20,0x62,0x79,0x20,0x61,0x6E,0x79,0x20,0x70,0x61,0x72,0x74, +0x79,0x20,0x61,0x73,0x73,0x75,0x6D,0x65,0x73,0x20,0x61,0x63,0x63,0x65,0x70,0x74, +0x61,0x6E,0x63,0x65,0x20,0x6F,0x66,0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x65,0x6E, +0x20,0x61,0x70,0x70,0x6C,0x69,0x63,0x61,0x62,0x6C,0x65,0x20,0x73,0x74,0x61,0x6E, +0x64,0x61,0x72,0x64,0x20,0x74,0x65,0x72,0x6D,0x73,0x20,0x61,0x6E,0x64,0x20,0x63, +0x6F,0x6E,0x64,0x69,0x74,0x69,0x6F,0x6E,0x73,0x20,0x6F,0x66,0x20,0x75,0x73,0x65, +0x2C,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x70,0x6F, +0x6C,0x69,0x63,0x79,0x20,0x61,0x6E,0x64,0x20,0x63,0x65,0x72,0x74,0x69,0x66,0x69, +0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x70,0x72,0x61,0x63,0x74,0x69,0x63,0x65,0x20, +0x73,0x74,0x61,0x74,0x65,0x6D,0x65,0x6E,0x74,0x73,0x2E,0x30,0x0D,0x06,0x09,0x2A, +0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x5C, +0x36,0x99,0x4C,0x2D,0x78,0xB7,0xED,0x8C,0x9B,0xDC,0xF3,0x77,0x9B,0xF2,0x76,0xD2, +0x77,0x30,0x4F,0xC1,0x1F,0x85,0x83,0x85,0x1B,0x99,0x3D,0x47,0x37,0xF2,0xA9,0x9B, +0x40,0x8E,0x2C,0xD4,0xB1,0x90,0x12,0xD8,0xBE,0xF4,0x73,0x9B,0xEE,0xD2,0x64,0x0F, +0xCB,0x79,0x4F,0x34,0xD8,0xA2,0x3E,0xF9,0x78,0xFF,0x6B,0xC8,0x07,0xEC,0x7D,0x39, +0x83,0x8B,0x53,0x20,0xD3,0x38,0xC4,0xB1,0xBF,0x9A,0x4F,0x0A,0x6B,0xFF,0x2B,0xFC, +0x59,0xA7,0x05,0x09,0x7C,0x17,0x40,0x56,0x11,0x1E,0x74,0xD3,0xB7,0x8B,0x23,0x3B, +0x47,0xA3,0xD5,0x6F,0x24,0xE2,0xEB,0xD1,0xB7,0x70,0xDF,0x0F,0x45,0xE1,0x27,0xCA, +0xF1,0x6D,0x78,0xED,0xE7,0xB5,0x17,0x17,0xA8,0xDC,0x7E,0x22,0x35,0xCA,0x25,0xD5, +0xD9,0x0F,0xD6,0x6B,0xD4,0xA2,0x24,0x23,0x11,0xF7,0xA1,0xAC,0x8F,0x73,0x81,0x60, +0xC6,0x1B,0x5B,0x09,0x2F,0x92,0xB2,0xF8,0x44,0x48,0xF0,0x60,0x38,0x9E,0x15,0xF5, +0x3D,0x26,0x67,0x20,0x8A,0x33,0x6A,0xF7,0x0D,0x82,0xCF,0xDE,0xEB,0xA3,0x2F,0xF9, +0x53,0x6A,0x5B,0x64,0xC0,0x63,0x33,0x77,0xF7,0x3A,0x07,0x2C,0x56,0xEB,0xDA,0x0F, +0x21,0x0E,0xDA,0xBA,0x73,0x19,0x4F,0xB5,0xD9,0x36,0x7F,0xC1,0x87,0x55,0xD9,0xA7, +0x99,0xB9,0x32,0x42,0xFB,0xD8,0xD5,0x71,0x9E,0x7E,0xA1,0x52,0xB7,0x1B,0xBD,0x93, +0x42,0x24,0x12,0x2A,0xC7,0x0F,0x1D,0xB6,0x4D,0x9C,0x5E,0x63,0xC8,0x4B,0x80,0x17, +0x50,0xAA,0x8A,0xD5,0xDA,0xE4,0xFC,0xD0,0x09,0x07,0x37,0xB0,0x75,0x75,0x21, +}; +#endif /* PKI_CHECK_ANCHOR_BY_SHA1 */ + +#endif /* __APPLE_CA_H */ diff --git a/lib/pki/chain-validation.c b/lib/pki/chain-validation.c new file mode 100644 index 0000000..f4be397 --- /dev/null +++ b/lib/pki/chain-validation.c @@ -0,0 +1,662 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + +#include +#include +#include +#include +#include + +#ifndef WITH_HW_PKE +#include +#include +#include +#include +#endif + +#include +#if DEBUG_BUILD +#ifndef DEBUG_ASSERT_PRODUCTION_CODE +#define DEBUG_ASSERT_PRODUCTION_CODE 0 +#endif +#endif +#include + +#include +#include +#include + +#if PKI_APPLE_ROOT_CA +#include +#else +#include +#endif + +typedef struct { + DERItem subjectKeyID; + DERItem authorityKeyID; + DERItem appleSpecBlob; + DERItem appleSpecTicketBlob; +} DERExtensions; + +static int extension_octet_string_value(DERExtension *extn, bool critical, + DERItem *value) +{ + DERDecodedInfo extn_info; +#if 0 + if (critical) { + /* this is more important to be enforced when issued */ + bool critical; + require_noerr(DERParseBoolean(&extn->critical, false, &critical), out); + require(critical, out); + } +#endif + /* get value */ + require_noerr(DERDecodeItem(&extn->extnValue, &extn_info), out); + require(extn_info.tag == ASN1_OCTET_STRING, out); + *value = extn_info.content; + + return 0; +out: + return -1; +} + +static int extension_sequence_item(DERExtension *extn, bool critical, + DERItem *value) +{ + DERDecodedInfo extn_info; +#if 0 + if (critical) { + /* this is more important to be enforced when issued */ + bool critical; + require_noerr(DERParseBoolean(&extn->critical, false, &critical), out); + require(critical, out); + } +#endif + /* get the sequence */ + require_noerr(DERDecodeItem(&extn->extnValue, &extn_info), out); + require(extn_info.tag == ASN1_CONSTR_SEQUENCE, out); + *value = extn->extnValue; + + return 0; +out: + return -1; +} + +/** + * Find extension with oidAppleSecureBootCertSpec oid and return octet string. + * It's not an error to not find it, but general parse errors are flagged. + */ +static int parse_extensions(DERTBSCert *tbsCert, DERExtensions *extensions) +{ + DERSequence derSeq; + DERTag tag; + DERDecodedInfo currDecoded; + DERExtension extn; + + bzero(extensions, sizeof(*extensions)); + if (tbsCert->extensions.length) { + require_noerr(DERDecodeSeqInit(&tbsCert->extensions, &tag, &derSeq), out); + require(tag == ASN1_CONSTR_SEQUENCE, out); + while (DERDecodeSeqNext(&derSeq, &currDecoded) == DR_Success) { + require(currDecoded.tag == ASN1_CONSTR_SEQUENCE, out); + require_noerr(DERParseSequenceContent(&currDecoded.content, + DERNumExtensionItemSpecs, DERExtensionItemSpecs, + &extn, sizeof(extn)), out); + + if (DEROidCompare(&oidAppleSecureBootTicketCertSpec, &extn.extnID)) { + require_noerr(extension_sequence_item(&extn, false, + &extensions->appleSpecTicketBlob), out); + dprintf(DEBUG_SPEW, "found apple spec (ticket) extension (%p, %u)\n", + extensions->appleSpecTicketBlob.data, + extensions->appleSpecTicketBlob.length); + } + else if (DEROidCompare(&oidAppleSecureBootCertSpec, &extn.extnID)) { + require_noerr(extension_octet_string_value(&extn, false, + &extensions->appleSpecBlob), out); + dprintf(DEBUG_SPEW, "found apple spec (image3) extension (%p, %d)\n", + extensions->appleSpecBlob.data, + extensions->appleSpecBlob.length); + } +#if PKI_CHECK_KEY_IDS + else if (DEROidCompare(&oidSubjectKeyIdentifier, &extn.extnID)) { + require_noerr(extension_octet_string_value(&extn, false, + &extensions->subjectKeyID), out); + dprintf(DEBUG_SPEW, "found subject key id extension (%p, %d)\n", + extensions->subjectKeyID.data, + extensions->subjectKeyID.length); + } + else if (DEROidCompare(&oidAuthorityKeyIdentifier, &extn.extnID)) { + DERAuthorityKeyIdentifier authority_key_id_seq; + require_noerr(DERParseSequence(&extn.extnValue, + DERNumAuthorityKeyIdentifierItemSpecs, + DERAuthorityKeyIdentifierItemSpecs, + &authority_key_id_seq, + sizeof(authority_key_id_seq)), out); + if (authority_key_id_seq.keyIdentifier.length) { + extensions->authorityKeyID = + authority_key_id_seq.keyIdentifier; + dprintf(DEBUG_SPEW, "found auth key id extension (%p, %d)\n", + extensions->authorityKeyID.data, + extensions->authorityKeyID.length); + } + } +#endif + } + } + + return 0; + +out: + return -1; +} + +static inline int dercmp(const DERItem a, const DERItem b) +{ + if (a.length != b.length) + return -1; + if (memcmp(a.data, b.data, a.length)) + return -1; + return 0; +} + +/* Take a byte string and reverse it: giants layout on little endian */ +static int rsa_set_giant(uint8_t *destination, size_t *dest_len, + uint8_t *source, size_t length, bool should_trim) +{ + size_t len = length; + uint8_t *end = source; + uint8_t *dst = destination; + + if(should_trim) { + /* ASN.1 integers may start with a zero to avoid sign interpretation */ + if( len && !(*end) ) { + end++; + len--; + } + } + + /* If it won't fit or zero we won't continue */ + if (!len || len > *dest_len) { + *dest_len = 0; + return -1; + } + + /* Reverse bytes: bignums start with lsb, word size doesn't matter for + little endian */ + uint8_t *src = source+length-1; + while (src >= end) + *dst++ = *src--; + + *dest_len = len; + return 0; +} + +#if WITH_HW_PKE +/* Verify signed encoded digest info with rsa pubKey against signature */ +static int verify_pkcs1_sig(const DERItem *pubKey /* PKCS1 format */, + const DERItem *digest_info, const DERItem *sig) +{ + DERItem keyItem = {(DERByte *)pubKey->data, pubKey->length}; + DERRSAPubKeyPKCS1 decodedKey; + struct { + uint8_t pmod[256]; + uint8_t base[256]; + uint8_t expn[256]; + uint8_t mods[256]; + size_t pmod_length; + size_t base_length; + size_t expn_length; + size_t mods_length; + size_t key_length; + } request; + + require_noerr(DERParseSequence(&keyItem, + DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs, + &decodedKey, sizeof(decodedKey)), out); + + bzero(&request, sizeof(request)); + request.pmod_length = sizeof(request.pmod); + request.base_length = sizeof(request.base); + request.expn_length = sizeof(request.expn); + request.mods_length = sizeof(request.mods); + + //Modulus and expn can have a leading zero padded to indicate a positive num. + //So trim those zeros out. + require_noerr(rsa_set_giant(request.mods, &request.mods_length, + decodedKey.modulus.data, decodedKey.modulus.length, true), out); + require_noerr(rsa_set_giant(request.expn, &request.expn_length, + decodedKey.pubExponent.data, decodedKey.pubExponent.length, true), out); + require_noerr(rsa_set_giant(request.base, &request.base_length, + sig->data, sig->length, false), out); + request.key_length = request.mods_length * 8; + + require(pke_do_exp(request.pmod, &request.pmod_length, + request.key_length, + request.base, request.base_length, + request.expn, request.expn_length, + request.mods, request.mods_length), out); + + /* verify padding: 0x00, 0x01, 0xff**0xff, 0x00, {algid, hash}: */ + + /* minimal pad length; digest_info->length although passed in is fixed. */ + require(request.pmod_length >= digest_info->length + 11, out); + + uint8_t *ptr = request.pmod + request.pmod_length - 1; + uint8_t *end = request.pmod; + uint8_t result = 0; + + /* start with 0 */ + result |= *ptr-- ^ 0; + require(ptr>end, out); + + /* block type 1 */ + result |= *ptr-- ^ 1; + require(ptr>end, out); + + /* all 0xff */ + while (*ptr == 0xff) { + require(ptr>end, out); + ptr--; + } + + /* terminated by 0 */ + result |= *ptr-- ^ 0; + require(ptr>end, out); + + /* digest_info->length bytes left */ + require(end + digest_info->length - 1 == ptr, out); + uint8_t *hash = digest_info->data; + /* match SHA-1 hash */ + while (ptr>=end) { + result |= *ptr-- ^ *hash++; + } + require(result == 0, out); + + return 0; + +out: + return -1; +} +#else /* !WITH_HW_PKE */ +/* + * Verify a PKCS1 signature with an RSA key. Caller is responsible for + * EncodedDigestInfo formatting. + */ +static int verify_pkcs1_sig( + const DERItem *pubKey, /* PKCS1 format */ + const DERItem *toVerify, + const DERItem *sig) +{ + RSAPubGiantKey rsaPubKey; + RSAStatus rrtn; + + GI_CHECK_SP("verifyPkcs1Sig"); + + /* + * Convert PKCS1 format key to native libgRSA key. + * Ideally we'd like to have the key in Apple Custom form, + * with the reciprocal, obtainable from cert, + * Someday maybe. + */ + GI_LOG_SP("calling RSA_DecodePubKey"); + rrtn = RSA_DecodePubKey(pubKey->data, pubKey->length, &rsaPubKey); + require_noerr(rrtn, out); + + GI_LOG_SP("calling RSA_SigVerify"); + rrtn = RSA_SigVerify(&rsaPubKey, RP_PKCS1, + (const gi_uint8 *)toVerify->data, (gi_uint16)toVerify->length, + (const gi_uint8 *)sig->data, (gi_uint16)sig->length); + require_noerr(rrtn, out); + + return 0; + +out: + return -1; +} +#endif + +/* + * Given data to sign or verify, take the SHA1 digest of it and encode the result in + * an EncodedDigestInfo. The result is DER_SHA1_DIGEST_INFO_LEN bytes, allocated by the + * caller. + */ +static int sha1DigestInfo(const DERItem *ptext, unsigned char *digestInfo) + /* DER_SHA1_DIGEST_INFO_LEN bytes RETURNED */ +{ + DERByte digest[DER_SHA1_DIGEST_LEN]; + DERReturn resultLen = DER_SHA1_DIGEST_INFO_LEN; + + /* take the SHA1 digest */ + sha1_calculate(ptext->data, ptext->length, digest); + + /* now roll it into an EncodedDigestInfo */ + return DEREncodeSHA1DigestInfo(digest, DER_SHA1_DIGEST_LEN, + digestInfo, &resultLen); +} + +/* decode an algorithm ID */ +static int decodeAlgId(const DERItem *encodedAlgId, DERAlgorithmId *decodedAlgId) +{ + return DERParseSequenceContent(encodedAlgId, + DERNumAlgorithmIdItemSpecs, DERAlgorithmIdItemSpecs, + decodedAlgId, sizeof(*decodedAlgId)); +} + +/* + * Obtain a PKCS1-format public key from a SubjectPubKeyInfo (tbs.subjectPubKey). + */ +static int decodePubKey(DERItem *pubKeyInfoContent, DERItem *pubKeyPkcs1) +{ + DERSubjPubKeyInfo pubKeyInfo; + DERByte numUnused; + DERAlgorithmId algId; + + /* sequence we're given: encoded DERSubjPubKeyInfo */ + require_noerr(DERParseSequenceContent(pubKeyInfoContent, + DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs, + &pubKeyInfo, sizeof(pubKeyInfo)), out); + + /* verify that this is an RSA key by decoding the AlgId */ + require_noerr(decodeAlgId(&pubKeyInfo.algId, &algId), out); + require(DEROidCompare(&algId.oid, &oidRsa), out); + + /* + * The contents of pubKeyInfo.pubKey is a bit string whose contents + * are a PKCS1 format RSA key. + */ + require_noerr(DERParseBitString(&pubKeyInfo.pubKey, pubKeyPkcs1, &numUnused), out); + + return 0; +out: + return -1; +} + +static int crack_chain(DERItem *certblob, DERItem chain[], DERShort chain_len) +{ + DERItem der_iter = *certblob; + DERShort num = 0; + DERSize used; + DERDecodedInfo topDecode; + + dprintf(DEBUG_SPEW, "PKI: break certificate chain into certs\n"); + + do { + require_noerr(DERDecodeItem(&der_iter, &topDecode), out); + + used = topDecode.content.data + topDecode.content.length - der_iter.data; + + require(used < (128 * 1024), out); //no single cert larger than 128k + require(der_iter.length >= used, out); + + require(num < chain_len, out); + + chain[num].length = used; + chain[num].data = der_iter.data; + + num++; + + der_iter.length -= used; + der_iter.data += used; + + } while (der_iter.length > 0); + +#if PKI_CHECK_ANCHOR_BY_SHA1 + /* require 3 element long chain */ + require(num == chain_len, out); + + /* check SHA-1 of (whole) root certificate (Apple root CA) */ + dprintf(DEBUG_SPEW, "PKI: check SHA-1 of root\n"); + unsigned char sha1[DER_SHA1_DIGEST_LEN]; + sha1_calculate(chain[0].data, chain[0].length, sha1); + require_noerr(memcmp(ROOT_CA_SHA1_HASH, sha1, DER_SHA1_DIGEST_LEN), out); +#else + /* make room for root CA */ + if (num == chain_len - 1) { + DERShort index; + for (index = chain_len - 1; index > 0; index--) + chain[index] = chain[index - 1]; + } + else + require(num == chain_len, out); + + /* use embedded root ca; override if one was passed in */ + dprintf(DEBUG_SPEW, "PKI: anchor chain to %s CA\n", + PKI_APPLE_ROOT_CA ? "Apple" : "fake"); + chain[0].data = (u_int8_t*)&ROOT_CA_CERTIFICATE; + chain[0].length = sizeof(ROOT_CA_CERTIFICATE); +#endif /* PKI_CHECK_ANCHOR_BY_SHA1 */ + + return 0; +out: + return -1; +} + +static int parse_chain(DERItem chain[], DERShort chain_len, + DERSignedCertCrl chainElements[], DERTBSCert tbsCerts[], + DERItem derPubKey[], DERExtensions extensions[]) +{ + DERShort num = 0; + + + /* top level decode */ + for (num = 0; num < chain_len; num++) { + + dprintf(DEBUG_SPEW, "PKI: parse cert %d of %d\n", num + 1, chain_len); + + require_noerr(DERParseSequence(&chain[num], + DERNumSignedCertCrlItemSpecs, DERSignedCertCrlItemSpecs, + &chainElements[num], sizeof(*chainElements)), out); + + require_noerr(DERParseSequence(&chainElements[num].tbs, + DERNumTBSCertItemSpecs, DERTBSCertItemSpecs, + &tbsCerts[num], sizeof(*tbsCerts)), out); + + require_noerr(decodePubKey(&tbsCerts[num].subjectPubKey, &derPubKey[num]), out); + + require_noerr(parse_extensions(&tbsCerts[num], &extensions[num]), out); + } + return 0; +out: + return -1; +} + +static int verify_chain_signatures( + DERItem *issuerPubKey, + DERSignedCertCrl *signedCert) +{ + DERAlgorithmId algId; + unsigned char digestInfo[DER_SHA1_DIGEST_INFO_LEN]; + DERByte numUnused; + DERItem toVerify = { digestInfo, DER_SHA1_DIGEST_INFO_LEN }; + DERItem sigBytes; + + /* figure out which digest to use from the sig algId */ + require_noerr(decodeAlgId(&signedCert->sigAlg, &algId), out); + + /* get the encodedDigestInfo from the digest of the subject's TBSCert */ + require(DEROidCompare(&algId.oid, &oidSha1Rsa), out); + + /* generate digest info from plaintext */ + require_noerr(sha1DigestInfo(&signedCert->tbs, digestInfo), out); + + /* get contents of sig, a bit string, as raw bytes */ + require_noerr(DERParseBitString(&signedCert->sig, &sigBytes, &numUnused), out); + + require_noerr(verify_pkcs1_sig(issuerPubKey, &toVerify, &sigBytes), out); + + return 0; + +out: + return -1; +} + +/* find first value for oid */ +static int find_content_by_oid(const DERItem *rdnSetContent, + const DERItem *oid, DERItem *content) +{ + DERReturn drtn; + DERSequence rdn; + DERDecodedInfo atvContent; + DERAttributeTypeAndValue atv; + + require_noerr(DERDecodeSeqContentInit(rdnSetContent, &rdn), out); + + while ((drtn = DERDecodeSeqNext(&rdn, &atvContent)) == DR_Success) { + + require(atvContent.tag == ASN1_CONSTR_SEQUENCE, out); + + require_noerr(DERParseSequenceContent(&atvContent.content, + DERNumAttributeTypeAndValueItemSpecs, + DERAttributeTypeAndValueItemSpecs, + &atv, sizeof(atv)), out); + + if (DEROidCompare(oid, &atv.type)) { + *content = atv.value; + return 0; + } + } + return drtn; +out: + return -1; +} + + +static int parse_common_name(const DERItem *subject, const DERItem *oid, DERItem *content) +{ + DERSequence derSeq; + DERDecodedInfo currDecoded; + + require_noerr(DERDecodeSeqContentInit(subject, &derSeq), out); + + while (DERDecodeSeqNext(&derSeq, &currDecoded) == DR_Success) { + + require(currDecoded.tag == ASN1_CONSTR_SET, out); + + /* only if we reached the end of a sequence do we keep looking */ + int status = find_content_by_oid(&currDecoded.content, oid, content); + if (status != DR_EndOfSequence) + return status; + } +out: + return -1; +} + + +static int verify_signature_with_hash(DERItem *public_key_pkcs1_rsa, + unsigned char *sig_blob, unsigned sig_blob_len, + unsigned char *hash_blob, unsigned hash_blob_len) +{ + unsigned char digest_data[DER_SHA1_DIGEST_INFO_LEN]; + DERItem signature = { sig_blob, sig_blob_len }; + DERItem digest_info = { digest_data, sizeof(digest_data) }; + + /* generate digest info blob from hash */ + require(hash_blob_len == DER_SHA1_DIGEST_LEN, out); + + require_noerr(DEREncodeSHA1DigestInfo(hash_blob, hash_blob_len, + digest_info.data, &digest_info.length), out); + + /* verify signature */ + return verify_pkcs1_sig(public_key_pkcs1_rsa, &digest_info, &signature); + +out: + return -1; +} + +int verify_signature_with_chain(void *chain_blob, size_t chain_blob_length, + void *sig_blob, size_t sig_blob_len, + void *hash_blob, size_t hash_blob_len, + void **img3_spec_blob, size_t *img3_spec_blob_len, + void **ticket_spec_blob, size_t *ticket_spec_blob_len) +{ + DERShort index; + const uint8_t chain_len = 3; + DERItem chain = { chain_blob, chain_blob_length }; + DERItem certs[chain_len]; + DERSignedCertCrl signedCert[chain_len]; + DERTBSCert tbsCert[chain_len]; + DERItem pubKeyPkcs1[chain_len]; + DERExtensions extensions[chain_len]; + + require_noerr(crack_chain(&chain, certs, chain_len), out); + + require_noerr(parse_chain(certs, chain_len, signedCert, tbsCert, + pubKeyPkcs1, extensions), out); + + /* check linkage */ + index = 1; + while (index < chain_len) { + dprintf(DEBUG_SPEW, "PKI: verify cert %d was issued by %d\n", index, index-1); + require_noerr(dercmp(tbsCert[index-1].subject, + tbsCert[index].issuer), out); +#if PKI_CHECK_KEY_IDS + require_noerr(dercmp(extensions[index-1].subjectKeyID, + extensions[index].authorityKeyID), out); +#endif + require_noerr(verify_chain_signatures(&pubKeyPkcs1[index-1], &signedCert[index]), out); + index++; + } + + /* check common name intermediary cert to restrict to secure boot sub CA */ + DERItem commonName = { NULL, 0 }; + require_noerr(parse_common_name(&tbsCert[1].subject, &oidCommonName, &commonName), out); + // first character (0x13) - ASN1_PRINTABLE_STRING + // second character (0x29) - Length (copied over a cert) + static const DERByte sboot_common_name[] = "\x13\x29""Apple Secure Boot Certification Authority"; + static const DERItem sboot_item = { + .data = (DERByte *)sboot_common_name, + .length = 0x2b + }; + dprintf(DEBUG_SPEW, "PKI: check intermediate cert for common name '%s'\n", sboot_common_name); + require(DEROidCompare(&sboot_item, &commonName), out); + + dprintf(DEBUG_SPEW, "PKI: check payload hash with signature\n"); + require_noerr(verify_signature_with_hash(&pubKeyPkcs1[chain_len-1], + sig_blob, sig_blob_len, hash_blob, hash_blob_len), out); + + /* return pointer to leaf blob in cert chain if it exists */ + if (extensions[chain_len-1].appleSpecTicketBlob.data && + extensions[chain_len-1].appleSpecTicketBlob.length) { + if (ticket_spec_blob != NULL && ticket_spec_blob_len != NULL) { + *ticket_spec_blob = extensions[chain_len-1].appleSpecTicketBlob.data; + *ticket_spec_blob_len = extensions[chain_len-1].appleSpecTicketBlob.length; + dprintf(DEBUG_SPEW, "PKI: parse apple spec id extension (ticket) in leaf: (%p, %zu)\n", *ticket_spec_blob, *ticket_spec_blob_len); + } + } + else if (extensions[chain_len-1].appleSpecBlob.data && + extensions[chain_len-1].appleSpecBlob.length) { + if (img3_spec_blob != NULL && img3_spec_blob_len != NULL) { + *img3_spec_blob = extensions[chain_len-1].appleSpecBlob.data; + *img3_spec_blob_len = extensions[chain_len-1].appleSpecBlob.length; + dprintf(DEBUG_SPEW, "PKI: parse apple spec id extension (image3) in leaf: (%p, %zu)\n", *img3_spec_blob, *img3_spec_blob_len); + } + } +#if NO_DEFAULT_PLATFORM_PROVIDE_SPEC_BLOB + else /* ask the platform to provide a leaf blob */ + { + DERTBSCert *leaf = &tbsCert[chain_len-1]; + DERItem leafCommonName = { NULL, 0 }; + + require_noerr(parse_common_name(&leaf->subject, &oidCommonName, &leafCommonName), out); + + require(platform_provide_spec_blob(leafCommonName.data, leafCommonName.length, + leaf->serialNum.data, leaf->serialNum.length, + img3_spec_blob, img3_spec_blob_len), out); + } +#endif // NO_DEFAULT_PLATFORM_PROVIDE_SPEC_BLOB + + return 0; + +out: + return -1; +} diff --git a/lib/pki/debug.c b/lib/pki/debug.c new file mode 100644 index 0000000..11d3195 --- /dev/null +++ b/lib/pki/debug.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if defined(WITH_MENU) && WITH_MENU + +int do_pki(int argc, struct cmd_arg *args) +{ + int ret_val; + + if (!security_allow_modes(kSecurityModeDebugCmd)) { + printf("Permission Denied\n"); + return -1; + } + + if (argc < 2) { + printf("not enough arguments.\n"); + usage: + printf("%s verify " + " \n", args[0].str); + printf("\tverify-image <8900-1.0-image-data> \n"); + return -1; + } + + void *chain_data, *sig_blob, *hash_blob, *spec_blob; + size_t chain_len, sig_blob_len, hash_blob_len, spec_blob_len; + chain_data = sig_blob = hash_blob = spec_blob = NULL; + chain_len = sig_blob_len = hash_blob_len = spec_blob_len = 0; + + if (!strcmp("verify", args[1].str)) { + + if (argc < 8) { + printf("not enough arguments.\n"); + goto usage; + } + + chain_data = (void *)args[2].u; + chain_len = args[3].u; + + sig_blob = (void *)args[4].u; + sig_blob_len = args[5].u; + + hash_blob = (void *)args[6].u; + hash_blob_len = args[7].u; + + } else if (!strcmp("verify-image", args[1].str)) { + + if (argc < 4) { + printf ("not enough arguments.\n"); + goto usage; + } + + if (!strcmp("89001.0", (void*)args[2].u)) { + printf ("invalid image (only 8900 1.0 images)\n"); + return -1; + } + + uint8_t *payload = (uint8_t*)(args[2].u + 0x800); + uint8_t *signature = payload + *(uint32_t*)(args[2].u + 16); + uint8_t *chain = payload + *(uint32_t*)(args[2].u + 20); + + chain_data = chain; + chain_len = args[2].u + args[3].u - (size_t)chain; + + sig_blob = signature; + sig_blob_len = chain - signature; + + /* abuse part of header as scratch */ + uint8_t sha1_buf[20]; + /* header + image are hashed for rsa verification */ + sha1_calculate((uint8_t*)args[2].u, (size_t)signature - args[2].u, sha1_buf); + //sha1_calculate(payload, signature - payload, sha1_buf); + + hash_blob = sha1_buf; + hash_blob_len = sizeof(sha1_buf); + + } else + return -1; + + ret_val = verify_signature_with_chain(chain_data, chain_len, + sig_blob, sig_blob_len, hash_blob, hash_blob_len, + &spec_blob, &spec_blob_len, NULL, NULL); + + printf("signature verification returned: %d\n", ret_val); + + return 0; +} + +// Turned off to save space, enable as needed +// MENU_COMMAND_DEBUG(pki, do_pki, "PKI", NULL); + +#endif diff --git a/lib/pki/fake_ca.h b/lib/pki/fake_ca.h new file mode 100644 index 0000000..2d29610 --- /dev/null +++ b/lib/pki/fake_ca.h @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + See docs/chain_validation.txt for instructions on using these. + Including this file instead of apple_ca.h will use this chain. + All keys and certs in pem format at the end of the file. +*/ +#ifndef __FAKE_CA_H +#define __FAKE_CA_H + +#if PKI_CHECK_ANCHOR_BY_SHA1 + +static const unsigned char ROOT_CA_SHA1_HASH[20] = { +0xeb, 0xb8, 0xaf, 0x3f, 0x77, 0xe4, 0x9d, 0xdc, 0x73, 0xa4, +0x54, 0x53, 0x8e, 0x40, 0xbb, 0x9c, 0xb1, 0x31, 0xe5, 0x7f +}; + +#else + +static const unsigned char ROOT_CA_CERTIFICATE[931] = { +0x30,0x82,0x03,0x9F,0x30,0x82,0x02,0x87,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, +0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, +0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13, +0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49, +0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70, +0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, +0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x16,0x30,0x14,0x06, +0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20,0x52,0x6F,0x6F,0x74, +0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x37,0x31,0x32,0x30,0x38,0x30,0x31,0x30, +0x38,0x31,0x37,0x5A,0x17,0x0D,0x30,0x38,0x30,0x31,0x30,0x37,0x30,0x31,0x30,0x38, +0x31,0x37,0x5A,0x30,0x62,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, +0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70, +0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B, +0x13,0x1D,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, +0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31, +0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x13,0x0D,0x41,0x70,0x70,0x6C,0x65,0x20, +0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A, +0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30, +0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xCD,0x91,0x86,0x6A,0x55,0x2D,0xE1,0xBA, +0x4F,0x04,0x38,0xD8,0x54,0x96,0xAC,0x7F,0x5C,0x02,0x24,0xC9,0x7C,0x15,0xA1,0x98, +0x08,0x8A,0x0D,0x72,0x00,0x92,0x4F,0x5A,0x86,0x31,0xA4,0x17,0x79,0x9F,0xAB,0x07, +0x11,0xA4,0x59,0x92,0x69,0x77,0x7A,0x7E,0xB3,0x95,0x2D,0x45,0x9B,0x67,0x02,0x15, +0x11,0x6A,0xD5,0xAF,0xC3,0x4E,0x97,0xD5,0xCC,0xE1,0x12,0x4B,0x80,0xE1,0x5E,0xBE, +0x5D,0x65,0x9C,0x5F,0x98,0x32,0xE1,0x31,0x5B,0x18,0xE5,0xBC,0xE0,0x27,0xE7,0xF0, +0xA9,0x1E,0xD7,0xBC,0xA5,0x09,0xC9,0xD5,0x79,0xFD,0x60,0x6A,0x33,0x69,0xFD,0x9C, +0xD2,0xEC,0x67,0x21,0xFB,0x74,0x87,0x99,0x4B,0x12,0xBA,0xCD,0xF9,0xE0,0xC0,0x37, +0x66,0x81,0x67,0x21,0xA6,0x78,0xA7,0x83,0x63,0x2C,0xE7,0xC7,0xCF,0x1C,0x09,0xE3, +0x23,0x29,0x7B,0x9F,0x4D,0x96,0xCC,0x21,0xC6,0x02,0x91,0xB0,0x4E,0xFD,0x6D,0x2F, +0x5B,0x03,0xE2,0xB9,0x35,0xE3,0x34,0xF1,0xCE,0x52,0xDF,0x79,0xE9,0x32,0x76,0x65, +0xE6,0x8B,0xEE,0xAB,0x4E,0x6A,0xBB,0x86,0xE4,0x4B,0x3E,0xB2,0xF7,0x5D,0x52,0x72, +0x11,0x1C,0x53,0x34,0xB6,0xF4,0x3B,0x4C,0x72,0x48,0xCC,0x53,0xD8,0xD8,0x13,0x5F, +0xFA,0x3C,0x35,0xC9,0x48,0x20,0x65,0xB3,0x19,0xEC,0x92,0xEC,0xA9,0xDE,0xF4,0xDB, +0x17,0x85,0xFE,0x16,0xBB,0x14,0x8E,0x85,0x6D,0x9D,0x94,0x5F,0x43,0x40,0x27,0xDE, +0x50,0x7B,0xC2,0x20,0x75,0x32,0x63,0xA9,0xEE,0x00,0x87,0xF3,0x72,0xAC,0x97,0x06, +0xB9,0xE5,0x3B,0x60,0x68,0xED,0x7D,0x3D,0x02,0x03,0x01,0x00,0x01,0xA3,0x60,0x30, +0x5E,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x4A,0x89,0x32,0x92, +0xFE,0x36,0x4C,0x31,0xA5,0x40,0x73,0x48,0xC9,0x2D,0x7F,0xCF,0xB5,0xBC,0x81,0xE1, +0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x4A,0x89,0x32, +0x92,0xFE,0x36,0x4C,0x31,0xA5,0x40,0x73,0x48,0xC9,0x2D,0x7F,0xCF,0xB5,0xBC,0x81, +0xE1,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, +0x01,0xFF,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x07,0x80,0x30, +0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, +0x01,0x01,0x00,0xBC,0x57,0xEF,0x27,0x67,0xCA,0xE0,0xCF,0xA3,0xD3,0xFC,0xFC,0xCE, +0xCB,0xFC,0xD9,0x12,0x24,0x45,0x1B,0xA4,0x57,0xAA,0x87,0x4B,0x8C,0xE2,0xC8,0xF4, +0x50,0x61,0xC6,0xBC,0xDF,0x7B,0x89,0x32,0x87,0x81,0xF8,0xBD,0x4E,0xBE,0x4D,0x2F, +0xF1,0x8F,0xF2,0xAB,0x8B,0x21,0x33,0xF7,0x69,0xEE,0xF6,0xB4,0x51,0x09,0x29,0x59, +0x33,0x2F,0xF6,0x60,0xEE,0xBD,0x7A,0x1D,0x87,0xA5,0x42,0xBA,0x05,0x1E,0x83,0x44, +0x47,0x8D,0xD0,0x9E,0x4C,0x43,0x76,0x23,0xE5,0xE4,0xEF,0xC8,0x5C,0x3C,0x94,0x94, +0x43,0x92,0x38,0x30,0x79,0x8C,0xC2,0x68,0x73,0xB3,0x64,0xE4,0x2A,0xD8,0xBD,0x89, +0x6B,0x59,0xBC,0xA6,0x9A,0xF0,0xCB,0xBD,0x88,0x7C,0xD9,0xAB,0xB1,0x9E,0x11,0x55, +0xB2,0x4B,0x53,0xCF,0xA0,0x06,0xCD,0xED,0x3E,0x27,0xFA,0x48,0xDE,0xD8,0x14,0x29, +0x74,0x8E,0xDA,0xB5,0x61,0x26,0xEE,0xD5,0x61,0xC7,0xE6,0x80,0xFD,0x52,0xA0,0x63, +0xAB,0xDF,0x72,0x7B,0xCA,0xBE,0x3A,0x2D,0xB6,0x01,0x0A,0x75,0x98,0x12,0x33,0x15, +0xA9,0x71,0x66,0xCF,0x1C,0xFB,0x7D,0x15,0xA0,0x06,0xD2,0x4D,0xC8,0x33,0x3E,0xDD, +0x28,0xF9,0xFB,0x3A,0x55,0xCB,0xF0,0x38,0x30,0x72,0xBB,0xB3,0xB8,0xC8,0x1A,0xD8, +0xF8,0xBC,0x83,0xD5,0x34,0xBA,0x54,0xC4,0xB0,0x03,0x56,0xF8,0xEB,0xCC,0x1B,0x66, +0xFA,0xB7,0xB0,0x56,0x21,0x01,0xD6,0xF3,0x81,0xE9,0x45,0xAB,0x72,0x0F,0xC7,0x91, +0xE6,0x49,0x05,0x87,0x18,0x91,0x41,0xF2,0x05,0xC9,0x02,0xA0,0xB2,0xA3,0x05,0xC6, +0x01,0x55,0xC9, +}; + +#endif /* PKI_CHECK_ANCHOR_BY_SHA1 */ + +/* + +CA-cert.pem + +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBADANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET +MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDcxMjA4MDEw +ODE3WhcNMDgwMTA3MDEwODE3WjBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw +bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +FjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDNkYZqVS3huk8EONhUlqx/XAIkyXwVoZgIig1yAJJPWoYxpBd5n6sH +EaRZkml3en6zlS1Fm2cCFRFq1a/DTpfVzOESS4DhXr5dZZxfmDLhMVsY5bzgJ+fw +qR7XvKUJydV5/WBqM2n9nNLsZyH7dIeZSxK6zfngwDdmgWchpning2Ms58fPHAnj +Iyl7n02WzCHGApGwTv1tL1sD4rk14zTxzlLfeekydmXmi+6rTmq7huRLPrL3XVJy +ERxTNLb0O0xySMxT2NgTX/o8NclIIGWzGeyS7Kne9NsXhf4WuxSOhW2dlF9DQCfe +UHvCIHUyY6nuAIfzcqyXBrnlO2Bo7X09AgMBAAGjYDBeMB0GA1UdDgQWBBRKiTKS +/jZMMaVAc0jJLX/PtbyB4TAfBgNVHSMEGDAWgBRKiTKS/jZMMaVAc0jJLX/PtbyB +4TAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQUFAAOC +AQEAvFfvJ2fK4M+j0/z8zsv82RIkRRukV6qHS4ziyPRQYca833uJMoeB+L1Ovk0v +8Y/yq4shM/dp7va0UQkpWTMv9mDuvXodh6VCugUeg0RHjdCeTEN2I+Xk78hcPJSU +Q5I4MHmMwmhzs2TkKti9iWtZvKaa8Mu9iHzZq7GeEVWyS1PPoAbN7T4n+kje2BQp +dI7atWEm7tVhx+aA/VKgY6vfcnvKvjottgEKdZgSMxWpcWbPHPt9FaAG0k3IMz7d +KPn7OlXL8DgwcruzuMga2Pi8g9U0ulTEsANW+OvMG2b6t7BWIQHW84HpRatyD8eR +5kkFhxiRQfIFyQKgsqMFxgFVyQ== +-----END CERTIFICATE----- + + +CA-csr.pem + +-----BEGIN CERTIFICATE REQUEST----- +MIICpzCCAY8CAQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4x +JjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQD +Ew1BcHBsZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +zZGGalUt4bpPBDjYVJasf1wCJMl8FaGYCIoNcgCST1qGMaQXeZ+rBxGkWZJpd3p+ +s5UtRZtnAhURatWvw06X1czhEkuA4V6+XWWcX5gy4TFbGOW84Cfn8Kke17ylCcnV +ef1gajNp/ZzS7Gch+3SHmUsSus354MA3ZoFnIaZ4p4NjLOfHzxwJ4yMpe59Nlswh +xgKRsE79bS9bA+K5NeM08c5S33npMnZl5ovuq05qu4bkSz6y911SchEcUzS29DtM +ckjMU9jYE1/6PDXJSCBlsxnskuyp3vTbF4X+FrsUjoVtnZRfQ0An3lB7wiB1MmOp +7gCH83Kslwa55TtgaO19PQIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAGBMBoLj +HWo543VlbNi8r/x9lBADfumd5g2fcqQnilZbouxVdFmVPRAAwPJXHavkttRytnUI +47+ouL1WJqeltWCviH0MmlzRkFlX76GiwIqgLK53vXMCy34o1RQrKsjdl3uxaYs6 +89EZdF7PHZC2u8nWXBteIXm6BLFd1lJx7bbIoRFTks3FMun422K4BCl1jzsdkztf +94ofavRcNf6xot2zaDHSTEEV0hXxLJxXd8YhaFkM8wS9u17ACgddIjLv0uS3fofP +YR8r7DWJS2aGrGYn6IONbEFWucsyvMAPQ5rP0zC3MdvoNqJosOmVFH55YIO+tG4J +O082aNdGmyFsXF0= +-----END CERTIFICATE REQUEST----- + + +CA-key.pem + +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzZGGalUt4bpPBDjYVJasf1wCJMl8FaGYCIoNcgCST1qGMaQX +eZ+rBxGkWZJpd3p+s5UtRZtnAhURatWvw06X1czhEkuA4V6+XWWcX5gy4TFbGOW8 +4Cfn8Kke17ylCcnVef1gajNp/ZzS7Gch+3SHmUsSus354MA3ZoFnIaZ4p4NjLOfH +zxwJ4yMpe59NlswhxgKRsE79bS9bA+K5NeM08c5S33npMnZl5ovuq05qu4bkSz6y +911SchEcUzS29DtMckjMU9jYE1/6PDXJSCBlsxnskuyp3vTbF4X+FrsUjoVtnZRf +Q0An3lB7wiB1MmOp7gCH83Kslwa55TtgaO19PQIDAQABAoIBAC5lBKgk90j1qnWy +eqiEpQPNeTJiQt4C7XQn7CbpmBvOu3CiryWk8o2S3rvUfncXr1bKeUA3dYUTyi2J +crSqnTwElFtzrO+wWVhs4WD10a3fXMb+uqUAfKllEe/wxHK0GbkBhWwSlH5HkZcH +I7VDtILVXbHJYPbnitlYpTUEBEERz2EoRkIEEKk4wZp2gLleyg5uwnmX+p6yvFN9 +98/ArBQ4Med6heOw4gqUxP/zfBllmMQYoi8jUd+oZlLYJ35bErbeXSwsgCcDtdQw +s6acs9GDjF3+lhgVqUczBcd80jJRWqrJjNDbI0L/t6GxyS/b4qG80vApxgfCJBTY +cGK4cyECgYEA9L9S7gry9sCEQj+2/z2wt1oZh69bSev2QY1hqfYZ0ktAomk5R4h8 +Ta4yJBOnftaTWkEYw6cBm/vMBFNxpYa4BnY6PWQwBh34Y+u9IUPo0zZ4L/j2Et6e +idN8CgC0ZCadbjawY3S6ogyKDJKXKjdn2Fx0gUCx56CjXXiuPScQoiUCgYEA1wUQ +xHj8qyCoX6h11DEQsd1HnFFkD1QPj23YWt8zXTNUn47ODB7lLJDrC75uM+550+os +eOpALQDveOa+cOf9jUs4s8IGPfwxEfr/AJwauty8W7Ps//HAPCuCLIkLJIWLhbDc +RW1bM/xV3uIcdp6cTjnbj6wuV4QRJtJqiQ8i5zkCgYBmZGyzfg0rwlsSxEkw+4Ql +ESLBK1HL2VYLErUbQASJgEYoLFF0ZdtrPEdp5Hccj3TSO426vPHlajBuVuKi13vB +6FBxQqr8xCkY1JUph5muU4lwuH1qY4x8KOgp3yWZCLawV1zwHvO9u/U9UU7AsLFX +SUbMlF5Zg1EVV9m9Z8yDqQKBgAyl2KGl+D7cserGjv/HTxMXUBIK25bnO+8U6AgY +Xv4Zed3U2Zvu6U4gzCKptfPKEFJ90NXf+ZxsFKoI8KTVkJ2SEijIvfNBdWV4XS2d +ARmCyHWgdM1tXABuEr8p5ITmchmQGLTgxN+e9TIiHMiBdfJIBvlBiIxPUW72K5wa +TtRJAoGBALrY77WmwIv5NBl4Bw+NdDXAp7Dnpw8jzfxr4slJzm0Y1iNp8ru5JDiW +TZ0GCK1fCaPpi1SWq/0HaFrLelB0oGjbAG4256MFT/BOkYHc84zlPaBUADeH/kTr +6Xv4rGXdZTE2hMklQABW9xe2S5YHjKhgp0Iqx9R+T85nU/wphiWs +-----END RSA PRIVATE KEY----- + + +intermediate-cert.pem + +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIBEDANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET +MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDcxMjA4MDEw +ODMzWhcNMDgwMTA3MDEwODMzWjB+MQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw +bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +MjAwBgNVBAMTKUFwcGxlIFNlY3VyZSBCb290IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvcWxBbLPL3G9uKlf +zEGg9bBBTm9T2Wzl3/GlkcWZwbaZlutTIr9ywzm454FSBgZd+bhsktYm3JJrJe29 +guj0FGN0x8AnBg0dzqBixGNNwA8YMPEnSxCvbtHxL90QAyv+bggx1MD4eXbuPMpq +n3hgHlLqbMVQsUj8RG95wkRjRfHbQutczqenlz69mxOUd1HY5LzLu+yu2Dm0FSPj +wzCadPTZ3gPos8lBvHt5B2Ty/+6tXHhBYHq4FofmJY0ADRoQrm4Ml8oHtu94Djh+ +UCtXyC8G36to/j5C+FTYB6cPY33hTTlc+8OPBzijYp1h7lrcLvafpfWIZAXbTGg4 +ldxvMwIDAQABo1owWDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHQ4EFgQU +xHwjblG8rtg2lGhCMHm3qSudO7wwHwYDVR0jBBgwFoAUSokykv42TDGlQHNIyS1/ +z7W8geEwDQYJKoZIhvcNAQEFBQADggEBALgw2Fs2N9jZ/BzGMfY6IO7PSMih5kEE +dQB7LLd3a/uKZNqG1ti6hUB3AQyEextndDht+iqNxtdHUs4MCJEwCa+uEVs+KnpL +Hn6x6hSDn2y1br45/o9TVI6k0auq+kHchiU/U8ZNiRoZNU62OsntEyS7qIQJ0iJf +6JhHSm11J3gAg3FmRsWeznO6lnHb04o0XYlmZTguZkzKHOguZC8qlyCnzLgLYOxI +Rpb3kpNcveMHN+0RBXMRIusX5+0x1/qRq7NuDmvEFocDXhcAubO69/mqm1EKbUGP +L6HnZRpVQiGliBP6lCJHdzKYqruVKx0GsBnQIK/GDWgNokddGHO2iEs= +-----END CERTIFICATE----- + + +intermediate-csr.pem + +-----BEGIN CERTIFICATE REQUEST----- +MIICwzCCAasCAQAwfjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4x +JjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTIwMAYDVQQD +EylBcHBsZSBTZWN1cmUgQm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3FsQWyzy9xvbipX8xBoPWwQU5v +U9ls5d/xpZHFmcG2mZbrUyK/csM5uOeBUgYGXfm4bJLWJtySayXtvYLo9BRjdMfA +JwYNHc6gYsRjTcAPGDDxJ0sQr27R8S/dEAMr/m4IMdTA+Hl27jzKap94YB5S6mzF +ULFI/ERvecJEY0Xx20LrXM6np5c+vZsTlHdR2OS8y7vsrtg5tBUj48MwmnT02d4D +6LPJQbx7eQdk8v/urVx4QWB6uBaH5iWNAA0aEK5uDJfKB7bveA44flArV8gvBt+r +aP4+QvhU2AenD2N94U05XPvDjwc4o2KdYe5a3C72n6X1iGQF20xoOJXcbzMCAwEA +AaAAMA0GCSqGSIb3DQEBBQUAA4IBAQAHxnIfeyxIYubX5xR0fpJKS7qA8+g7M5Dh +U8sikodTly6UJCIc0wDNCuJfHbS0r+YB3J0lITqp1vK27bm9mF7R73kAKCv07cHP +s0z1ukBuEJmFmXbhDji4hnsuOTPYI3zX5NT4Tvwh+o5zLHmPolaPe7/oJaVKjySC +Y8hzSc1QWYFuuxeOHBLna6Bma3UPMvHx3Tobx5sw4eh+7K7DPHUFRR8oZBDwZ9st +86LgVnIqjJz5Gh4f+AiZuyVrY6yVYzMEug4oltGcGOPcxnTK+4cfnPM5oSpYbKPz +wsznyTw5sqgMxawUUubs70ObRg05ctsBrlP2wxfUoeZmyIO2cLvz +-----END CERTIFICATE REQUEST----- + + +intermediate-key.pem + +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvcWxBbLPL3G9uKlfzEGg9bBBTm9T2Wzl3/GlkcWZwbaZlutT +Ir9ywzm454FSBgZd+bhsktYm3JJrJe29guj0FGN0x8AnBg0dzqBixGNNwA8YMPEn +SxCvbtHxL90QAyv+bggx1MD4eXbuPMpqn3hgHlLqbMVQsUj8RG95wkRjRfHbQutc +zqenlz69mxOUd1HY5LzLu+yu2Dm0FSPjwzCadPTZ3gPos8lBvHt5B2Ty/+6tXHhB +YHq4FofmJY0ADRoQrm4Ml8oHtu94Djh+UCtXyC8G36to/j5C+FTYB6cPY33hTTlc ++8OPBzijYp1h7lrcLvafpfWIZAXbTGg4ldxvMwIDAQABAoIBAQCvUe5DN3iVel0u +NrwcNh2AHb+XuN4cJrEQfWzbCVUNU6b9eJarqXdayP78Ucr3afZz+F/GIDZy3IpE +1iiYwqKMG34N9IWY35FEDYRxrtRrtQZCYOhOPzH0DdzmvTJH2+MIwGVZCpYDkU5z +twVeIpWaLjwJFRmBT85PYzV3tjqIqFnIzQhU8CRb52MFsyvTSpsycPAaLbnZ2wr2 +KT9gOtCv61SKuTqPm2NhrYL34lJCHORySBe4Ts5vmjX75pBd00eDFTz6Fzwo9ePk +65nV3Vf7CKfqXLyV8ZHLU5xoMaPYvEY/mb1W1J+IsZ77juPAnQQ/aYqdUTDkjsq4 +F5nJ3PlBAoGBAO5Z44eGsKclr1sVNo+QAchZqYSyyFKojKfnZHWztIfXdR9xZksg +zXSPQ0EbGdVK+ETDNZ4FWMCbllx69lLcnig8CN/6XKsKvjkw2mu0aS0I34RmozHo +mk2UV7KN3BLN8n7LSl1nucnI0mLFjZYpBQB/fnCS8F03TSDU97WEoupDAoGBAMvS +9LvcgfOUzIVD/MIJeYYxRJnroUcSijqs3Pp9ReWzRie9W7FOzM4gsSIs/wZh4dce +XIgS8mEobGTQH8dX5GostiKqJQq/E0Oa9i7QDmKOzVYqXjq+RuWu7GDmSb9kZ2g9 +03GItxlwODNIAgpVT3p4FMDvTR+DsDdDF9jrMXBRAoGAFAOKPnQJ208nxU8nsLBX +5fnZaSIV/hLXFLYyUkvPqeRmmkhMXZyYg+QPsqTS630LEcMOeoFabXnjC0rr6hNK +WHiKCjyckWQqiuTWQlr4xeZL1nND2sn8Qu1k28Jbq1yNsyXgza0LBa2ONOr/s48o +M12BQXSlKD6fhFU9o4lKoL8CgYEAoH3XnyUeXkJIWJcUK2VyfyvELL7RGzmKBnGe +/s4tf5UOJLSBwredpKExWQu9M7VXMyABFFR27fH6h9cpbrnSbZgPQnRe/ns+G/mk +52+EJC71mGd8Ex1IjgqSriom38GbewVTvQ49vpYSaq7EjIZoMrLjBJhpTetPkfQO +jwuCvkECgYAqKEjuLbX+nhzQkd6pvz/69fTL1VyHZlvzS/ZDnSuJWQ1EgJDv39Q8 +HLdFqzouNmfPU/dZiTPpOQTy2DYcRnFgwIhxKjrlSI8N3NtAjb5F78GixwfvsxVw ++jh3GPYgL9xXKDDgnaLdkhGNuHR2aEiAWpXlz5PURgSVMqR8tgKZnw== +-----END RSA PRIVATE KEY----- + + +leaf-dev-cert.pem + +-----BEGIN CERTIFICATE----- +MIIDfjCCAmagAwIBAgIBAjANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJVUzET +MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxMjAwBgNVBAMTKUFwcGxlIFNlY3VyZSBCb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTA3MTIwODAxMDg0N1oXDTA4MDEwNzAxMDg0N1ow +dDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xMjAwBgNVBAsTKUFw +cGxlIFNlY3VyZSBCb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQD +ExNTNUw4OTAwIFNlY3VyZSBCb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB +gQDNOqtQo1chTGmwchCu3hh0FcibQJWXGV5aULDbfYZloDLJIXi2B1E7XaGr8NpF +cXYyoZxA1dy9Dl0A1wiiDXa8sw5bhv9LE4FZI4u6+vRmlsebFzjOrsTvDyaAVqF+ +d3MLvEsZKNLYns9OePDchvUzAvA1F2ll8L8EWHb3cHPt8QIDAQABo4GUMIGRMAkG +A1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBSCGlh9KFcEUknDmU4ajg7N +fDvgjzAfBgNVHSMEGDAWgBTEfCNuUbyu2DaUaEIwebepK507vDA3BgoqhkiG92Nk +BgEBAQH/BCYEJDNnbUkkAAAAHAAAAAAAAAAqKioqRE9SUBAAAAAEAAAAAAAAADAN +BgkqhkiG9w0BAQUFAAOCAQEAbDrnROb31daOREElTOgBA6ExiRIz+3KSz/oIyZA3 +7Qz28zwGFjqWQ3u4PIAxypVJn2vxYHDerR1uEkgQBXD+F2pR1rFDSwCKtBZoFpVb +F1cr9t99JaYKwX1BsYnsGWAfRiscDh/QrVEbUOujVkH71KI3qn1N3L0mEftmWSK0 +mZXFvu4l7O/GdCWkPYrfvrImpHhfy/OiyhZq3iddmV4kjyBLiR87Z/hP0g81Ootg +I4LVeeps7Sq4MY2Q7uadq4EmK626DQknGGaiM+571pIqA26waBpHrPLAdMEn6F3G +YOsG5Q2eRj/tEUKr1S9a8UYMDA5uLRMaER92JZhCrfyM9Q== +-----END CERTIFICATE----- + + +leaf-dev-csr.pem + +-----BEGIN CERTIFICATE REQUEST----- +MIIBtDCCAR0CAQAwdDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4x +MjAwBgNVBAsTKUFwcGxlIFNlY3VyZSBCb290IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRwwGgYDVQQDExNTNUw4OTAwIFNlY3VyZSBCb290MIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDNOqtQo1chTGmwchCu3hh0FcibQJWXGV5aULDbfYZloDLJ +IXi2B1E7XaGr8NpFcXYyoZxA1dy9Dl0A1wiiDXa8sw5bhv9LE4FZI4u6+vRmlseb +FzjOrsTvDyaAVqF+d3MLvEsZKNLYns9OePDchvUzAvA1F2ll8L8EWHb3cHPt8QID +AQABoAAwDQYJKoZIhvcNAQEFBQADgYEAGaJSzXCAcED9t+FTz3rLo+MQieQ0r3TI +JC0OStaw/ixYJyp4/BAga7WAPsa35yJFJE+Rh/MeiG2skt4r3kH1w3/yAlfYGCET +XVyFypjE80cPTf6iveGdiBS7+Qx69y5uDnNMFX6XwvOxwjfkMXs0qyIEaSLCcjMW +ipMrF/xrqM4= +-----END CERTIFICATE REQUEST----- + + +leaf-dev-key.pem + +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDNOqtQo1chTGmwchCu3hh0FcibQJWXGV5aULDbfYZloDLJIXi2 +B1E7XaGr8NpFcXYyoZxA1dy9Dl0A1wiiDXa8sw5bhv9LE4FZI4u6+vRmlsebFzjO +rsTvDyaAVqF+d3MLvEsZKNLYns9OePDchvUzAvA1F2ll8L8EWHb3cHPt8QIDAQAB +AoGABR+Fz0mEj0w9By6RxAu/SIaSr215ToBPnqmNAK2tgTPykJrJTKH6ISVBN+2X +RUyDytfF8shj7kRBhhfYG1OCtz+9/jIvhzmq11AtNPK3Pm1i3L2kcD/lMIkqvn6H +Ck7Qif4TqU+CMDBgbsYw9wR5+rXdxUiX3Z2kT6ukcmutk8ECQQDsbgzFfk2MzdVi +ttA8VwwhUtYBY2dKI83zz53x6UDWd8vdlBKuPbzRp5H0ZGK5DzNFBBmy50ZgrGlr +uCR3U4ItAkEA3jd56oto/y4KeqXMFjaGLKXibKbKPFh0nGQU5MrjNODVrkKzXJ3r +NFWPqsU+vhgzF1pmwjdLJB0KWGJ91DKpVQJBANPkIUASXRA3HOm2a9PYM7/dzHw8 +CUMR6a97v9MhuAE+JhB0d3V/US0YoB9GpI+0Rr+w2BNVYOadPnHS+6ORzRUCQHOm +c7D5tT95esKyHzFAVzxNaTYa6A3YC3iJLcaVQQJ4MT1sQWTmW071aLv7w9ezSIPS +7MAPfu/gnU26lLonU7ECQQDUpwN5dnJWRaKyvQbVZ5Zfs9R3+N5rB+dbhaqDCJu5 +rtRR/C4jvPMebqsJqVIedgbED+Ci5IkobXQxsXf9k5SI +-----END RSA PRIVATE KEY----- + + +leaf-prod-cert.pem + +-----BEGIN CERTIFICATE----- +MIIDfjCCAmagAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJVUzET +MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxMjAwBgNVBAMTKUFwcGxlIFNlY3VyZSBCb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTA3MTIwODAxMDg0MVoXDTA4MDEwNzAxMDg0MVow +dDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xMjAwBgNVBAsTKUFw +cGxlIFNlY3VyZSBCb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQD +ExNTNUw4OTAwIFNlY3VyZSBCb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB +gQDPaf0eFpjLc2XOvMNipZd5soFkn8bcu7zUkULxkPKT5ykO8fmfzzJPQIdHNFt3 +6hnJ0y+WCAlWebfVcMXhUOcN2DLbhHKog4+WN/A84dyW3U4JPkJbnAdnxvsNOtmY +6CJMsrX0tYFjMc1/b9KVLve1tEmPQdxq8iAQA9P1oS2AyQIDAQABo4GUMIGRMAkG +A1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTxKP1pOKrSvJj+7r3Lzbki +VNRpFTAfBgNVHSMEGDAWgBTEfCNuUbyu2DaUaEIwebepK507vDA3BgoqhkiG92Nk +BgEBAQH/BCYEJDNnbUkkAAAAHAAAAAAAAAAqKioqRE9SUBAAAAAEAAAAAQAAADAN +BgkqhkiG9w0BAQUFAAOCAQEAZcm1Ea/tIy3vvZsR1ysPukLsXc4/jgE4Yavion53 +LzwGq2cotdrInvnwiILl6QOv1q+ND+h+kOpiNOagX8KPgnjvw3PWeo+EDfqjgBVS +1T+e3c7Bh5bjfxJUdP29X/Np652mTQcgxd1YI/ie1hYzjG5+pjHpDpT79gRnk4MV +/bdzqIXMVPgo5D3vIe4mnrY/TmTj4m13aLzF0FNlidyX5kSPrGfPTnGxnXXrjr/3 +oF28d1PLHVcnkjppxGrKxUqTPJK5NKIVApV0X7VuBeG3hGN4+RDHDYL9brwj1Ub+ +OTQbe1nfsaPh8JDSpXQh4GeRYwi2OOCYM+ooFv46Cx4Pvg== +-----END CERTIFICATE----- + + +leaf-prod-csr.pem + +-----BEGIN CERTIFICATE REQUEST----- +MIIBtDCCAR0CAQAwdDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4x +MjAwBgNVBAsTKUFwcGxlIFNlY3VyZSBCb290IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRwwGgYDVQQDExNTNUw4OTAwIFNlY3VyZSBCb290MIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDPaf0eFpjLc2XOvMNipZd5soFkn8bcu7zUkULxkPKT5ykO +8fmfzzJPQIdHNFt36hnJ0y+WCAlWebfVcMXhUOcN2DLbhHKog4+WN/A84dyW3U4J +PkJbnAdnxvsNOtmY6CJMsrX0tYFjMc1/b9KVLve1tEmPQdxq8iAQA9P1oS2AyQID +AQABoAAwDQYJKoZIhvcNAQEFBQADgYEAgFpUWqgUUGi1jBzRvVQt/jyjA4C7T07y +mpgk3i/tNU8+r/3qT3FsXKPHkdLWat3lJiAKSU87KRDxg4ZLmyKa2qWjr6J5Dz15 +3dtfaGJpH3tkEl39aXNm5NzkVWZ1hunU2MJp1zE6rgdrufOCLr5dehpXlzl4xBjy +8nMROVgE2Ig= +-----END CERTIFICATE REQUEST----- + + +leaf-prod-key.pem + +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDPaf0eFpjLc2XOvMNipZd5soFkn8bcu7zUkULxkPKT5ykO8fmf +zzJPQIdHNFt36hnJ0y+WCAlWebfVcMXhUOcN2DLbhHKog4+WN/A84dyW3U4JPkJb +nAdnxvsNOtmY6CJMsrX0tYFjMc1/b9KVLve1tEmPQdxq8iAQA9P1oS2AyQIDAQAB +AoGALbdRyAj5Apbb0LaAZkTTX0p+BJzG6y4iD8Q4uh/Vp83imd2xxIyZrSgu6P3c +T1D1ACwhJ/N7g2juoQfrRZ9cXaXBrNHkttOPcdo3Ra4pbanGQu1JMpUlIHY5mEMU +zusVJg/RsjfIqOk4NvsbUava8fVTFw0SCdvgT5IE7t391TUCQQD+GwPKxAC8Tn+O +LbToIKyiyO4w0/EpVhdD5RdhBW+zfpLQO3mUs1YGmk487tI9QCNNy8DfV2LK/bDN +F6SrT6EzAkEA0PXbzyJ1XviLH3zQJrGfEHdOIu0mp15l/EC3Qtm1RISDsK7L/KdD +NNtABtgfL6nku9v+ewc0P2kzT0Elyj1OEwJBAIT6rERbyKrDRdupLchg+ReDoatp +7wYb6Lb+V/rNNoSv07MnvNvF8looPJOEw/+L5i3bWIdJGwlyNClQmzuPw6MCQAYf +LdFjsQyXO3wwq+h2S7KvzBo52GgO2+4H91Z+ClF3kGQcut0sCUwDIF0S99bto0Xd +rBbunxk8e8RWpETIhwECQQC62cv5HiWimw6X+qpS3Z/sEgRXbnlqTmtPPIsi3vGW +K7Q0pCXXvTyNSFE81Ds9Pgwn5j5FD1bL4txLBZZZS58r +-----END RSA PRIVATE KEY----- + +*/ + +#endif /* __FAKE_CA_H */ diff --git a/lib/pki/libDER/DER_CertCrl.c b/lib/pki/libDER/DER_CertCrl.c new file mode 100644 index 0000000..aa99661 --- /dev/null +++ b/lib/pki/libDER/DER_CertCrl.c @@ -0,0 +1,319 @@ +/* Copyright (c) 2005-2009 Apple Inc. All Rights Reserved. */ + +/* + * DER_Cert.c - support for decoding X509 certificates + * + * Created Nov. 4 2005 by Doug Mitchell. + */ + +#include +#include +#include + +/* + * DERItemSpecs for X509 certificates. + */ + +/* top level cert with three components */ +const DERItemSpec DERSignedCertCrlItemSpecs[] = +{ + { DER_OFFSET(DERSignedCertCrl, tbs), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS | DER_DEC_SAVE_DER}, + { DER_OFFSET(DERSignedCertCrl, sigAlg), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERSignedCertCrl, sig), + ASN1_BIT_STRING, + DER_DEC_NO_OPTS } +}; + +const DERSize DERNumSignedCertCrlItemSpecs = + sizeof(DERSignedCertCrlItemSpecs) / sizeof(DERItemSpec); + +/* TBS cert */ +const DERItemSpec DERTBSCertItemSpecs[] = +{ + { DER_OFFSET(DERTBSCert, version), + ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, /* version - EXPLICIT */ + { DER_OFFSET(DERTBSCert, serialNum), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, tbsSigAlg), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, issuer), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, validity), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, subject), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCert, subjectPubKey), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + /* libsecurity_asn1 has these two as CONSTRUCTED, but the ASN.1 spec + * doesn't look that way to me. I don't have any certs that have these + * fields.... */ + { DER_OFFSET(DERTBSCert, issuerID), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCert, subjectID), + ASN1_CONTEXT_SPECIFIC | 2, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCert, extensions), + ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumTBSCertItemSpecs = sizeof(DERTBSCertItemSpecs) / sizeof(DERItemSpec); + +/* DERValidity */ +const DERItemSpec DERValidityItemSpecs[] = +{ + { DER_OFFSET(DERValidity, notBefore), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERValidity, notAfter), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; +const DERSize DERNumValidityItemSpecs = + sizeof(DERValidityItemSpecs) / sizeof(DERItemSpec); + +/* DERAttributeTypeAndValue */ +const DERItemSpec DERAttributeTypeAndValueItemSpecs[] = { + { DER_OFFSET(DERAttributeTypeAndValue, type), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERAttributeTypeAndValue, value), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; + +const DERSize DERNumAttributeTypeAndValueItemSpecs = + sizeof(DERAttributeTypeAndValueItemSpecs) / sizeof(DERItemSpec); + +/* DERExtension */ +const DERItemSpec DERExtensionItemSpecs[] = +{ + { DER_OFFSET(DERExtension, extnID), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERExtension, critical), + ASN1_BOOLEAN, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERExtension, extnValue), + ASN1_OCTET_STRING, + DER_DEC_NO_OPTS } +}; +const DERSize DERNumExtensionItemSpecs = + sizeof(DERExtensionItemSpecs) / sizeof(DERItemSpec); + +/* DERBasicConstraints */ +const DERItemSpec DERBasicConstraintsItemSpecs[] = +{ + { DER_OFFSET(DERBasicConstraints, cA), + ASN1_BOOLEAN, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERBasicConstraints, pathLenConstraint), + ASN1_INTEGER, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumBasicConstraintsItemSpecs = + sizeof(DERBasicConstraintsItemSpecs) / sizeof(DERItemSpec); + +/* DERPrivateKeyUsagePeriod. */ +const DERItemSpec DERPrivateKeyUsagePeriodItemSpecs[] = +{ + { DER_OFFSET(DERPrivateKeyUsagePeriod, notBefore), + ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERPrivateKeyUsagePeriod, notAfter), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumPrivateKeyUsagePeriodItemSpecs = + sizeof(DERPrivateKeyUsagePeriodItemSpecs) / sizeof(DERItemSpec); + +/* DERDistributionPoint. */ +const DERItemSpec DERDistributionPointItemSpecs[] = +{ + { DER_OFFSET(DERDistributionPoint, distributionPoint), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERDistributionPoint, reasons), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERDistributionPoint, cRLIssuer), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumDistributionPointItemSpecs = + sizeof(DERDistributionPointItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyInformation. */ +const DERItemSpec DERPolicyInformationItemSpecs[] = +{ + { DER_OFFSET(DERPolicyInformation, policyIdentifier), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERPolicyInformation, policyQualifiers), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumPolicyInformationItemSpecs = + sizeof(DERPolicyInformationItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyQualifierInfo. */ +const DERItemSpec DERPolicyQualifierInfoItemSpecs[] = +{ + { DER_OFFSET(DERPolicyQualifierInfo, policyQualifierID), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERPolicyQualifierInfo, qualifier), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; +const DERSize DERNumPolicyQualifierInfoItemSpecs = + sizeof(DERPolicyQualifierInfoItemSpecs) / sizeof(DERItemSpec); + +/* DERUserNotice. */ +const DERItemSpec DERUserNoticeItemSpecs[] = +{ + { DER_OFFSET(DERUserNotice, noticeRef), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERUserNotice, explicitText), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER } +}; +const DERSize DERNumUserNoticeItemSpecs = + sizeof(DERUserNoticeItemSpecs) / sizeof(DERItemSpec); + +/* DERNoticeReference. */ +const DERItemSpec DERNoticeReferenceItemSpecs[] = +{ + { DER_OFFSET(DERNoticeReference, organization), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERNoticeReference, noticeNumbers), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS } +}; +const DERSize DERNumNoticeReferenceItemSpecs = + sizeof(DERNoticeReferenceItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyMapping. */ +const DERItemSpec DERPolicyMappingItemSpecs[] = +{ + { DER_OFFSET(DERPolicyMapping, issuerDomainPolicy), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERPolicyMapping, subjectDomainPolicy), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS } +}; +const DERSize DERNumPolicyMappingItemSpecs = + sizeof(DERPolicyMappingItemSpecs) / sizeof(DERItemSpec); + +/* DERAccessDescription. */ +const DERItemSpec DERAccessDescriptionItemSpecs[] = +{ + { DER_OFFSET(DERAccessDescription, accessMethod), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERAccessDescription, accessLocation), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } +}; +const DERSize DERNumAccessDescriptionItemSpecs = + sizeof(DERAccessDescriptionItemSpecs) / sizeof(DERItemSpec); + +/* DERAuthorityKeyIdentifier. */ +const DERItemSpec DERAuthorityKeyIdentifierItemSpecs[] = +{ + { DER_OFFSET(DERAuthorityKeyIdentifier, keyIdentifier), + ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertIssuer), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertSerialNumber), + ASN1_CONTEXT_SPECIFIC | 2, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumAuthorityKeyIdentifierItemSpecs = + sizeof(DERAuthorityKeyIdentifierItemSpecs) / sizeof(DERItemSpec); + +/* DEROtherName. */ +const DERItemSpec DEROtherNameItemSpecs[] = +{ + { DER_OFFSET(DEROtherName, typeIdentifier), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DEROtherName, value), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0, + DER_DEC_NO_OPTS }, +}; +const DERSize DERNumOtherNameItemSpecs = + sizeof(DEROtherNameItemSpecs) / sizeof(DERItemSpec); + +/* DERPolicyConstraints. */ +const DERItemSpec DERPolicyConstraintsItemSpecs[] = +{ + { DER_OFFSET(DERPolicyConstraints, requireExplicitPolicy), + ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERPolicyConstraints, inhibitPolicyMapping), + ASN1_CONTEXT_SPECIFIC | 1, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumPolicyConstraintsItemSpecs = + sizeof(DERPolicyConstraintsItemSpecs) / sizeof(DERItemSpec); + +/* DERTBSCrl */ +const DERItemSpec DERTBSCrlItemSpecs[] = +{ + { DER_OFFSET(DERTBSCrl, version), + ASN1_INTEGER, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCrl, tbsSigAlg), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCrl, issuer), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTBSCrl, thisUpdate), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERTBSCrl, nextUpdate), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERTBSCrl, revokedCerts), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERTBSCrl, extensions), + ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL } +}; +const DERSize DERNumTBSCrlItemSpecs = sizeof(DERTBSCrlItemSpecs) / sizeof(DERItemSpec); + +/* DERRevokedCert */ +const DERItemSpec DERRevokedCertItemSpecs[] = +{ + { DER_OFFSET(DERRevokedCert, serialNum), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRevokedCert, revocationDate), + 0, /* no tag - ANY */ + DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERRevokedCert, extensions), + ASN1_CONSTR_SEQUENCE, + DER_DEC_OPTIONAL } +}; + +const DERSize DERNumRevokedCertItemSpecs = + sizeof(DERRevokedCertItemSpecs) / sizeof(DERItemSpec); diff --git a/lib/pki/libDER/DER_CertCrl.h b/lib/pki/libDER/DER_CertCrl.h new file mode 100644 index 0000000..df4e0e3 --- /dev/null +++ b/lib/pki/libDER/DER_CertCrl.h @@ -0,0 +1,233 @@ +/* Copyright (c) 2005-2009 Apple Inc. All Rights Reserved. */ + +/* + * DER_CertCrl.h - support for decoding X509 certificates and CRLs + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _DER_CERT_CRL_H_ +#define _DER_CERT_CRL_H_ + +#include +#include + +__BEGIN_DECLS + +/* + * Top level cert or CRL - the two are identical at this level - three + * components. The tbs field is saved in full DER form for sig verify. + */ +typedef struct { + DERItem tbs; /* sequence, DERTBSCert, DER_DEC_SAVE_DER */ + DERItem sigAlg; /* sequence, DERAlgorithmId */ + DERItem sig; /* bit string */ +} DERSignedCertCrl; + +/* DERItemSpecs to decode into a DERSignedCertCrl */ +extern const DERItemSpec DERSignedCertCrlItemSpecs[]; +extern const DERSize DERNumSignedCertCrlItemSpecs; + +/* TBS cert components */ +typedef struct { + DERItem version; /* integer, optional, EXPLICIT */ + DERItem serialNum; /* integer */ + DERItem tbsSigAlg; /* sequence, DERAlgorithmId */ + DERItem issuer; /* sequence, TBD */ + DERItem validity; /* sequence, DERValidity */ + DERItem subject; /* sequence, TBD */ + DERItem subjectPubKey; /* sequence, DERSubjPubKeyInfo */ + DERItem issuerID; /* bit string, optional */ + DERItem subjectID; /* bit string, optional */ + DERItem extensions; /* sequence, optional, EXPLICIT */ +} DERTBSCert; + +/* DERItemSpecs to decode into a DERTBSCert */ +extern const DERItemSpec DERTBSCertItemSpecs[]; +extern const DERSize DERNumTBSCertItemSpecs; + +/* + * validity - components can be either UTC or generalized time. + * Both are ASN_ANY with DER_DEC_SAVE_DER. + */ +typedef struct { + DERItem notBefore; + DERItem notAfter; +} DERValidity; + +/* DERItemSpecs to decode into a DERValidity */ +extern const DERItemSpec DERValidityItemSpecs[]; +extern const DERSize DERNumValidityItemSpecs; + +/* AttributeTypeAndValue components. */ +typedef struct { + DERItem type; + DERItem value; +} DERAttributeTypeAndValue; + +/* DERItemSpecs to decode into DERAttributeTypeAndValue */ +extern const DERItemSpec DERAttributeTypeAndValueItemSpecs[]; +extern const DERSize DERNumAttributeTypeAndValueItemSpecs; + +/* Extension components */ +typedef struct { + DERItem extnID; + DERItem critical; + DERItem extnValue; +} DERExtension; + +/* DERItemSpecs to decode into DERExtension */ +extern const DERItemSpec DERExtensionItemSpecs[]; +extern const DERSize DERNumExtensionItemSpecs; + +/* BasicConstraints components. */ +typedef struct { + DERItem cA; + DERItem pathLenConstraint; +} DERBasicConstraints; + +/* DERItemSpecs to decode into DERBasicConstraints */ +extern const DERItemSpec DERBasicConstraintsItemSpecs[]; +extern const DERSize DERNumBasicConstraintsItemSpecs; + +/* PrivateKeyUsagePeriod components. */ +typedef struct { + DERItem notBefore; + DERItem notAfter; +} DERPrivateKeyUsagePeriod; + +/* DERItemSpecs to decode into a DERPrivateKeyUsagePeriod */ +extern const DERItemSpec DERPrivateKeyUsagePeriodItemSpecs[]; +extern const DERSize DERNumPrivateKeyUsagePeriodItemSpecs; + +/* DistributionPoint components. */ +typedef struct { + DERItem distributionPoint; + DERItem reasons; + DERItem cRLIssuer; +} DERDistributionPoint; + +/* DERItemSpecs to decode into a DERDistributionPoint */ +extern const DERItemSpec DERDistributionPointItemSpecs[]; +extern const DERSize DERNumDistributionPointItemSpecs; + +/* PolicyInformation components. */ +typedef struct { + DERItem policyIdentifier; + DERItem policyQualifiers; +} DERPolicyInformation; + +/* DERItemSpecs to decode into a DERPolicyInformation */ +extern const DERItemSpec DERPolicyInformationItemSpecs[]; +extern const DERSize DERNumPolicyInformationItemSpecs; + +/* PolicyQualifierInfo components. */ +typedef struct { + DERItem policyQualifierID; + DERItem qualifier; +} DERPolicyQualifierInfo; + +/* DERItemSpecs to decode into a DERPolicyQualifierInfo */ +extern const DERItemSpec DERPolicyQualifierInfoItemSpecs[]; +extern const DERSize DERNumPolicyQualifierInfoItemSpecs; + +/* UserNotice components. */ +typedef struct { + DERItem noticeRef; + DERItem explicitText; +} DERUserNotice; + +/* DERItemSpecs to decode into a DERUserNotice */ +extern const DERItemSpec DERUserNoticeItemSpecs[]; +extern const DERSize DERNumUserNoticeItemSpecs; + +/* NoticeReference components. */ +typedef struct { + DERItem organization; + DERItem noticeNumbers; +} DERNoticeReference; + +/* DERItemSpecs to decode into a DERNoticeReference */ +extern const DERItemSpec DERNoticeReferenceItemSpecs[]; +extern const DERSize DERNumNoticeReferenceItemSpecs; + +/* PolicyMapping components. */ +typedef struct { + DERItem issuerDomainPolicy; + DERItem subjectDomainPolicy; +} DERPolicyMapping; + +/* DERItemSpecs to decode into a DERPolicyMapping */ +extern const DERItemSpec DERPolicyMappingItemSpecs[]; +extern const DERSize DERNumPolicyMappingItemSpecs; + +/* AccessDescription components. */ +typedef struct { + DERItem accessMethod; + DERItem accessLocation; +} DERAccessDescription; + +/* DERItemSpecs to decode into a DERAccessDescription */ +extern const DERItemSpec DERAccessDescriptionItemSpecs[]; +extern const DERSize DERNumAccessDescriptionItemSpecs; + +/* AuthorityKeyIdentifier components. */ +typedef struct { + DERItem keyIdentifier; + DERItem authorityCertIssuer; + DERItem authorityCertSerialNumber; +} DERAuthorityKeyIdentifier; + +/* DERItemSpecs to decode into a DERAuthorityKeyIdentifier */ +extern const DERItemSpec DERAuthorityKeyIdentifierItemSpecs[]; +extern const DERSize DERNumAuthorityKeyIdentifierItemSpecs; + +/* OtherName components. */ +typedef struct { + DERItem typeIdentifier; + DERItem value; +} DEROtherName; + +/* DERItemSpecs to decode into a DEROtherName */ +extern const DERItemSpec DEROtherNameItemSpecs[]; +extern const DERSize DERNumOtherNameItemSpecs; + +/* PolicyConstraints components. */ +typedef struct { + DERItem requireExplicitPolicy; + DERItem inhibitPolicyMapping; +} DERPolicyConstraints; + +/* DERItemSpecs to decode into a DERPolicyConstraints */ +extern const DERItemSpec DERPolicyConstraintsItemSpecs[]; +extern const DERSize DERNumPolicyConstraintsItemSpecs; + +/* TBS CRL */ +typedef struct { + DERItem version; /* integer, optional */ + DERItem tbsSigAlg; /* sequence, DERAlgorithmId */ + DERItem issuer; /* sequence, TBD */ + DERItem thisUpdate; /* ASN_ANY, SAVE_DER */ + DERItem nextUpdate; /* ASN_ANY, SAVE_DER */ + DERItem revokedCerts; /* sequence of DERRevokedCert, optional */ + DERItem extensions; /* sequence, optional, EXPLICIT */ +} DERTBSCrl; + +/* DERItemSpecs to decode into a DERTBSCrl */ +extern const DERItemSpec DERTBSCrlItemSpecs[]; +extern const DERSize DERNumTBSCrlItemSpecs; + +typedef struct { + DERItem serialNum; /* integer */ + DERItem revocationDate; /* time - ASN_ANY, SAVE_DER */ + DERItem extensions; /* sequence, optional, EXPLICIT */ +} DERRevokedCert; + +/* DERItemSpecs to decode into a DERRevokedCert */ +extern const DERItemSpec DERRevokedCertItemSpecs[]; +extern const DERSize DERNumRevokedCertItemSpecs; + +__END_DECLS + +#endif /* _DER_CERT_CRL_H_ */ + diff --git a/lib/pki/libDER/DER_Decode.c b/lib/pki/libDER/DER_Decode.c new file mode 100644 index 0000000..8ca4ab3 --- /dev/null +++ b/lib/pki/libDER/DER_Decode.c @@ -0,0 +1,645 @@ +/* + * Copyright (c) 2005-2010 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * DER_Decode.c - DER decoding routines + */ + +#include +#include + +#include + +#ifndef DER_DECODE_ENABLE +#error Please define DER_DECODE_ENABLE. +#endif + +#if DER_DECODE_ENABLE + +#define DER_DECODE_DEBUG 0 +#if DER_DECODE_DEBUG +#include +#define derDecDbg(a) printf(a) +#define derDecDbg1(a, b) printf(a, b) +#define derDecDbg2(a, b, c) printf(a, b, c) +#define derDecDbg3(a, b, c, d) printf(a, b, c, d) +#else +#define derDecDbg(a) +#define derDecDbg1(a, b) +#define derDecDbg2(a, b, c) +#define derDecDbg3(a, b, c, d) +#endif /* DER_DECODE_DEBUG */ + +/* + * Basic decoding primitive. Only works with: + * + * -- definite length encoding + * -- one-byte tags (unless DER_MULTIBYTE_TAGS is defined) + * -- max content length fits in a DERSize + * + * No malloc or copy of the contents is performed; the returned + * content->content.data is a pointer into the incoming der data. + */ +DERReturn DERDecodeItem( + const DERItem *der, /* data to decode */ + DERDecodedInfo *decoded) /* RETURNED */ +{ + return DERDecodeItemPartialBuffer(der, decoded, false); +} + +/* + * Basic decoding primitive. Allows for decoding with a partial buffer. + * if allowPartialBuffer is true. A partial buffer would normally fail + * because the encoded length would be greater than the size of the buffer passed in. + * Only works with: + * + * -- definite length encoding + * -- one-byte tags (unless DER_MULTIBYTE_TAGS is defined) + * -- max content length fits in a DERSize + * + * No malloc or copy of the contents is performed; the returned + * content->content.data is a pointer into the incoming der data. + */ +DERReturn DERDecodeItemPartialBuffer( + const DERItem *der, /* data to decode */ + DERDecodedInfo *decoded, /* RETURNED */ + bool allowPartialBuffer) +{ + DERByte tag1; /* first tag byte */ + DERByte len1; /* first length byte */ + DERTag tagNumber; /* tag number without class and method bits */ + DERByte *derPtr = der->data; + DERSize derLen = der->length; + + /* The tag decoding below is fully BER complient. We support a max tag + value of 2 ^ ((sizeof(DERTag) * 8) - 3) - 1 so for tag size 1 byte we + support tag values from 0 - 0x1F. For tag size 2 tag values + from 0 - 0x1FFF and for tag size 4 values from 0 - 0x1FFFFFFF. */ + if(derLen < 2) { + return DR_DecodeError; + } + /* Grab the first byte of the tag. */ + tag1 = *derPtr++; + derLen--; + tagNumber = tag1 & 0x1F; + if(tagNumber == 0x1F) { +#ifdef DER_MULTIBYTE_TAGS + /* Long tag form: bit 8 of each octet shall be set to one unless it is + the last octet of the tag */ + const DERTag overflowMask = ((DERTag)0x7F << (sizeof(DERTag) * 8 - 7)); + DERByte tagByte; + tagNumber = 0; + if (*derPtr == 0x80 || *derPtr < 0x1F) + return DR_DecodeError; + do { + if(derLen < 2 || (tagNumber & overflowMask) != 0) { + return DR_DecodeError; + } + tagByte = *derPtr++; + derLen--; + tagNumber = (tagNumber << 7) | (tagByte & 0x7F); + } while((tagByte & 0x80) != 0); + + /* Check for any of the top 3 reserved bits being set. */ + if ((tagNumber & (overflowMask << 4)) != 0) +#endif + return DR_DecodeError; + } + /* Returned tag, top 3 bits are class/method remaining bits are number. */ + decoded->tag = ((DERTag)(tag1 & 0xE0) << ((sizeof(DERTag) - 1) * 8)) | tagNumber; + + /* Tag decoding above ensured we have at least one more input byte left. */ + len1 = *derPtr++; + derLen--; + if(len1 & 0x80) { + /* long length form - first byte is length of length */ + DERSize longLen = 0; /* long form length */ + unsigned dex; + + len1 &= 0x7f; + if((len1 > sizeof(DERSize)) || (len1 > derLen) || len1 == 0 || *derPtr == 0) { + /* no can do */ + return DR_DecodeError; + } + for(dex=0; dex derLen && !allowPartialBuffer) { + /* not enough data left for this encoding */ + return DR_DecodeError; + } + decoded->content.data = derPtr; + decoded->content.length = longLen; + } + else { + /* short length form, len1 is the length */ + if(len1 > derLen && !allowPartialBuffer) { + /* not enough data left for this encoding */ + return DR_DecodeError; + } + decoded->content.data = derPtr; + decoded->content.length = len1; + } + + return DR_Success; +} + +/* + * Given a BIT_STRING, in the form of its raw content bytes, + * obtain the number of unused bits and the raw bit string bytes. + */ +DERReturn DERParseBitString( + const DERItem *contents, + DERItem *bitStringBytes, /* RETURNED */ + DERByte *numUnusedBits) /* RETURNED */ +{ + if(contents->length < 2) { + /* not enough room for actual bits after the unused bits field */ + *numUnusedBits = 0; + bitStringBytes->data = NULL; + bitStringBytes->length = 0; + return DR_Success; + } + *numUnusedBits = contents->data[0]; + bitStringBytes->data = contents->data + 1; + bitStringBytes->length = contents->length - 1; + return DR_Success; +} + +/* + * Given a BOOLEAN, in the form of its raw content bytes, + * obtain it's value. + */ +DERReturn DERParseBoolean( + const DERItem *contents, + bool *value) { /* RETURNED */ + if (contents->length != 1 || + (contents->data[0] != 0 && contents->data[0] != 0xFF)) + return DR_DecodeError; + + *value = contents->data[0] != 0; + return DR_Success; +} + +/* + * Given a BOOLEAN, in the form of its raw content bytes, + * obtain it's value. + */ +DERReturn DERParseBooleanWithDefault( + const DERItem *contents, + bool defaultValue, + bool *value) { /* RETURNED */ + if (contents->length == 0) { + *value = defaultValue; + return DR_Success; + } + return DERParseBoolean(contents, value); +} + +DERReturn DERParseInteger( + const DERItem *contents, + uint32_t *result) { /* RETURNED */ + uint64_t value; + DERReturn drtn = DERParseInteger64(contents, &value); + if (drtn == DR_Success) { + if (value > UINT32_MAX) + drtn = DR_BufOverflow; + else + *result = (uint32_t)value; + } + return drtn; +} + +DERReturn DERParseInteger64( + const DERItem *contents, + uint64_t *result) { /* RETURNED */ + DERSize ix, length = contents->length; + if (length == 0) + return DR_DecodeError; + if (contents->data[0] & 0x80) + return DR_DecodeError; + if (contents->data[0] == 0) { + if (length > 1 && (contents->data[1] & 0x80) == 0) + return DR_DecodeError; + if (length > sizeof(*result) + 1) + return DR_BufOverflow; + } else if (length > sizeof(*result)) { + return DR_BufOverflow; + } + uint64_t value = 0; + for (ix = 0; ix < length; ++ix) { + value <<= 8; + value += contents->data[ix]; + } + *result = value; + return DR_Success; +} + +/* Sequence/set support */ + +/* + * To decode a set or sequence, call DERDecodeSeqInit once, then + * call DERDecodeSeqNext to get each enclosed item. + * DERDecodeSeqNext returns DR_EndOfSequence when no more + * items are available. + */ +DERReturn DERDecodeSeqInit( + const DERItem *der, /* data to decode */ + DERTag *tag, /* RETURNED tag of sequence/set. This will be + * either ASN1_CONSTR_SEQUENCE or ASN1_CONSTR_SET. */ + DERSequence *derSeq) /* RETURNED, to use in DERDecodeSeqNext */ +{ + DERDecodedInfo decoded; + DERReturn drtn; + + drtn = DERDecodeItem(der, &decoded); + if(drtn) { + return drtn; + } + *tag = decoded.tag; + switch(decoded.tag) { + case ASN1_CONSTR_SEQUENCE: + case ASN1_CONSTR_SET: + break; + default: + return DR_UnexpectedTag; + } + derSeq->nextItem = decoded.content.data; + derSeq->end = decoded.content.data + decoded.content.length; + return DR_Success; +} + +/* + * Use this to start in on decoding a sequence's content, when + * the top-level tag and content have already been decoded. + */ +DERReturn DERDecodeSeqContentInit( + const DERItem *content, + DERSequence *derSeq) /* RETURNED, to use in DERDecodeSeqNext */ +{ + /* just prepare for decoding items in content */ + derSeq->nextItem = content->data; + derSeq->end = content->data + content->length; + return DR_Success; +} + +DERReturn DERDecodeSeqNext( + DERSequence *derSeq, + DERDecodedInfo *decoded) /* RETURNED */ +{ + DERReturn drtn; + DERItem item; + + if(derSeq->nextItem >= derSeq->end) { + /* normal termination, contents all used up */ + return DR_EndOfSequence; + } + + /* decode next item */ + item.data = derSeq->nextItem; + item.length = (DERSize)(derSeq->end - derSeq->nextItem); + drtn = DERDecodeItem(&item, decoded); + if(drtn) { + return drtn; + } + + /* skip over the item we just decoded */ + derSeq->nextItem = decoded->content.data + decoded->content.length; + return DR_Success; +} + +/* + * High level sequence parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's + * OK, use DERParseSequenceContent(). + */ +DERReturn DERParseSequence( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero) /* optional */ +{ + DERReturn drtn; + DERDecodedInfo topDecode; + + drtn = DERDecodeItem(der, &topDecode); + if(drtn) { + return drtn; + } + if(topDecode.tag != ASN1_CONSTR_SEQUENCE) { + return DR_UnexpectedTag; + } + return DERParseSequenceContent(&topDecode.content, + numItems, itemSpecs, dest, sizeToZero); +} + +/* high level sequence parse, starting with sequence's content */ +DERReturn DERParseSequenceContent( + const DERItem *content, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero) /* optional */ +{ + DERSequence derSeq; + DERReturn drtn; + DERShort itemDex; + DERByte *currDER; /* full DER encoding of current item */ + + if(sizeToZero) { + DERMemset(dest, 0, sizeToZero); + } + + drtn = DERDecodeSeqContentInit(content, &derSeq); + if(drtn) { + return drtn; + } + + /* main loop */ + for(itemDex=0 ; itemDexoptions; + derDecDbg3("--- currItem %u expectTag 0x%llx currOptions 0x%x\n", + i, currItemSpec->tag, currOptions); + + if((currOptions & DER_DEC_ASN_ANY) || + (foundTag == currItemSpec->tag)) { + /* + * We're good with this one. Cook up destination address + * as appropriate. + */ + if(!(currOptions & DER_DEC_SKIP)) { + derDecDbg1("--- MATCH at currItem %u\n", i); + DERByte *byteDst = (DERByte *)dest + currItemSpec->offset; + DERItem *dst = (DERItem *)byteDst; + *dst = currDecoded.content; + if(currOptions & DER_DEC_SAVE_DER) { + /* recreate full DER encoding of this item */ + derDecDbg1("--- SAVE_DER at currItem %u\n", i); + dst->data = currDER; + dst->length += (currDecoded.content.data - currDER); + } + } + + /* on to next item */ + itemDex = i + 1; + + /* is this the end? */ + if(itemDex == numItems) { + /* normal termination if we consumed everything */ + if (derSeq.nextItem == derSeq.end) + return DR_Success; + else + return DR_DecodeError; + } + else { + /* on to next item */ + foundMatch = 1; + break; + } + } /* ASN_ANY, or match */ + + /* + * If current itemSpec isn't optional, abort - else on to + * next item + */ + if(!(currOptions & DER_DEC_OPTIONAL)) { + derDecDbg1("--- MISMATCH at currItem %u, !OPTIONAL, abort\n", i); + return DR_UnexpectedTag; + } + + /* else this was optional, on to next item */ + } /* searching for tag match */ + + if(foundMatch == 0) { + /* + * Found an item we couldn't match to any tag spec and we're at + * the end. + */ + derDecDbg("--- TAG NOT FOUND, abort\n"); + return DR_UnexpectedTag; + } + + /* else on to next item */ + } /* main loop */ + + /* Template has 0 items if we get here. */ + /* normal termination if we consumed everything, (the sequence was empty) */ + if (derSeq.nextItem == derSeq.end) + return DR_Success; + else + return DR_DecodeError; +} + +#if 0 +/* + * High level sequence parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's + * OK, use DERParseSequenceContent(). + */ +DERReturn DERParseSequenceOf( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize *numDestItems) /* output */ +{ + DERReturn drtn; + DERDecodedInfo topDecode; + + drtn = DERDecodeItem(der, &topDecode); + if(drtn) { + return drtn; + } + if(topDecode.tag != ASN1_CONSTR_SEQUENCE) { + return DR_UnexpectedTag; + } + return DERParseSequenceContent(&topDecode.content, + numItems, itemSpecs, dest, sizeToZero); +} + +/* + * High level set of parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SET - if it's not, and that's + * OK, use DERParseSetOrSequenceOfContent(). + */ +DERReturn DERParseSetOf( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize *numDestItems) /* output */ +{ + DERReturn drtn; + DERDecodedInfo topDecode; + + drtn = DERDecodeItem(der, &topDecode); + if(drtn) { + return drtn; + } + if(topDecode.tag != ASN1_CONSTR_SET) { + return DR_UnexpectedTag; + } + return DERParseSetOrSequenceOfContent(&topDecode.content, + numItems, itemSpecs, dest, numDestItems); +} + +/* High level set of or sequence of parse, starting with set or + sequence's content */ +DERReturn DERParseSetOrSequenceOfContent( + const DERItem *content, + void(*itemHandeler)(void *, const DERDecodedInfo *) + void *itemHandelerContext); +{ + DERSequence derSeq; + DERShort itemDex; + + drtn = DERDecodeSeqContentInit(content, &derSeq); + require_noerr_quiet(drtn, badCert); + + /* main loop */ + for (;;) { + DERDecodedInfo currDecoded; + DERShort i; + DERByte foundTag; + char foundMatch = 0; + + drtn = DERDecodeSeqNext(&derSeq, &currDecoded); + if(drtn) { + /* The only legal error here is DR_EndOfSequence. */ + if(drtn == DR_EndOfSequence) { + /* no more items left in the sequence; success */ + return DR_Success; + } + else { + /* any other error is fatal */ + require_noerr_quiet(drtn, badCert); + } + } /* decode error */ + + /* Each element can be anything. */ + foundTag = currDecoded.tag; + + /* + * We're good with this one. Cook up destination address + * as appropriate. + */ + DERByte *byteDst = (DERByte *)dest + currItemSpec->offset; + DERItem *dst = (DERItem *)byteDst; + *dst = currDecoded.content; + if(currOptions & DER_DEC_SAVE_DER) { + /* recreate full DER encoding of this item */ + derDecDbg1("--- SAVE_DER at currItem %u\n", i); + dst->data = currDER; + dst->length += (currDecoded.content.data - currDER); + } + + /* on to next item */ + itemDex = i + 1; + + /* is this the end? */ + if(itemDex == numItems) { + /* normal termination */ + return DR_Success; + } + else { + /* on to next item */ + foundMatch = 1; + break; + } + + /* + * If current itemSpec isn't optional, abort - else on to + * next item + */ + if(!(currOptions & DER_DEC_OPTIONAL)) { + derDecDbg1("--- MISMATCH at currItem %u, !OPTIONAL, abort\n", i); + return DR_UnexpectedTag; + } + + /* else this was optional, on to next item */ + } /* searching for tag match */ + + if(foundMatch == 0) { + /* + * Found an item we couldn't match to any tag spec and we're at + * the end. + */ + derDecDbg("--- TAG NOT FOUND, abort\n"); + return DR_UnexpectedTag; + } + + /* else on to next item */ + } /* main loop */ + + /* + * If we get here, there appears to be more to process, but we've + * given the caller everything they want. + */ + return DR_Success; + } +} +#endif + +#endif /* DER_DECODE_ENABLE */ diff --git a/lib/pki/libDER/DER_Decode.h b/lib/pki/libDER/DER_Decode.h new file mode 100644 index 0000000..27884ce --- /dev/null +++ b/lib/pki/libDER/DER_Decode.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2005-2010 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * DER_Decode.h - DER decoding routines + */ + +#ifndef _DER_DECODE_H_ +#define _DER_DECODE_H_ + +#include +#include + +__BEGIN_DECLS + +/* + * Decoding one item consists of extracting its tag, a pointer + * to the actual content, and the length of the content. Those + * three are represented by a DERDecodedInfo. + */ +typedef struct { + DERTag tag; + DERItem content; +} DERDecodedInfo; + +/* + * Basic decoding primitive. Only works with: + * + * -- definite length encoding + * -- one-byte tags + * -- max content length fits in a DERSize + * + * No malloc or copy of the contents is performed; the returned + * content->content.data is a pointer into the incoming der data. + */ +DERReturn DERDecodeItem( + const DERItem *der, /* data to decode */ + DERDecodedInfo *decoded); /* RETURNED */ + +/* + * Basic decoding primitive. Allows for decoding with a partial buffer. + * if allowPartialBuffer is true. A partial buffer would normally fail + * because the encoded length would be greater than the size of the buffer passed in. + * Only works with: + * + * -- definite length encoding + * -- one-byte tags (unless DER_MULTIBYTE_TAGS is defined) + * -- max content length fits in a DERSize + * + * No malloc or copy of the contents is performed; the returned + * content->content.data is a pointer into the incoming der data. + */ +DERReturn DERDecodeItemPartialBuffer( + const DERItem *der, /* data to decode */ + DERDecodedInfo *decoded, /* RETURNED */ + bool allowPartialBuffer); + +/* + * Given a BIT_STRING, in the form of its raw content bytes, + * obtain the number of unused bits and the raw bit string bytes. + */ +DERReturn DERParseBitString( + const DERItem *contents, + DERItem *bitStringBytes, /* RETURNED */ + DERByte *numUnusedBits); /* RETURNED */ + +/* + * Given a BOOLEAN, in the form of its raw content bytes, + * obtain it's value. + */ +DERReturn DERParseBoolean( + const DERItem *contents, + bool *value); /* RETURNED */ +DERReturn DERParseBooleanWithDefault( + const DERItem *contents, + bool defaultValue, + bool *value); /* RETURNED */ +/* + * Given a positive INTEGER, in the form of its raw content bytes, + * obtain it's value as a 32 bit or 64 bit quantity. + * Returns DR_BufOverflow if the value is too large to fit in the return type + */ +DERReturn DERParseInteger( + const DERItem *contents, + uint32_t *value); /* RETURNED */ +DERReturn DERParseInteger64( + const DERItem *contents, + uint64_t *value); /* RETURNED */ + +/* + * Sequence/set decode support. + */ + +/* state representing a sequence or set being decoded */ +typedef struct { + DERByte *nextItem; + DERByte *end; +} DERSequence; + +/* + * To decode a set or sequence, call DERDecodeSeqInit or + * DERDecodeSeqContentInit once, then call DERDecodeSeqNext to + * get each enclosed item. + * + * DERDecodeSeqNext returns DR_EndOfSequence when no more + * items are available. + */ + +/* + * Use this to parse the top level sequence's tag and content length. + */ +DERReturn DERDecodeSeqInit( + const DERItem *der, /* data to decode */ + DERTag *tag, /* RETURNED tag of sequence/set. This will be + * either ASN1_CONSTR_SEQUENCE or + * ASN1_CONSTR_SET. */ + DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ + +/* + * Use this to start in on decoding a sequence's content, when + * the top-level tag and content have already been decoded. + */ +DERReturn DERDecodeSeqContentInit( + const DERItem *content, + DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ + +/* obtain the next decoded item in a sequence or set */ +DERReturn DERDecodeSeqNext( + DERSequence *derSeq, + DERDecodedInfo *decoded); /* RETURNED */ + +/* + * High level sequence decode. + */ + +/* + * Per-item decode options. + */ + +/* Explicit default, no options */ +#define DER_DEC_NO_OPTS 0x0000 + +/* This item optional, can be skipped during decode */ +#define DER_DEC_OPTIONAL 0x0001 + +/* Skip the tag check; accept anything. */ +#define DER_DEC_ASN_ANY 0x0002 + +/* Skip item, no write to DERDecodedInfo (but tag check still performed) */ +#define DER_DEC_SKIP 0x0004 + +/* Save full DER encoding in DERDecodedInfo, including tag and length. Normally + * only the content is saved. */ +#define DER_DEC_SAVE_DER 0x0008 + +/* + * High level sequence parse, starting with top-level tag and content. + * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's + * OK, use DERParseSequenceContent(). + * + * These never return DR_EndOfSequence - if an *unexpected* end of sequence + * occurs, return DR_IncompleteSeq. + * + * Results of the decoding of one item are placed in a DERItem whose address + * is the dest arg plus the offset value in the associated DERItemSpec. + * + * Items which are optional (DER_DEC_OPTIONAL) and which are not found, + * leave their associated DERDecodedInfos unmodified. + * + * Processing of a sequence ends on detection of any error or after the + * last DERItemSpec is processed. + * + * The sizeToZero argument, if nonzero, indicates the number of bytes + * starting at dest to zero before processing the sequence. This is + * generally desirable, particularly if there are any DER_DEC_OPTIONAL + * items in the sequence; skipped optional items are detected by the + * caller via a NULL DERDecodedInfo.content.data; if this hasn't been + * explicitly zeroed (generally, by passing a nonzero value of sizeToZero), + * skipped items can't be detected. + */ +DERReturn DERParseSequence( + const DERItem *der, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero); /* optional */ + +/* high level sequence parse, starting with sequence's content */ +DERReturn DERParseSequenceContent( + const DERItem *content, + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + void *dest, /* DERDecodedInfo(s) here RETURNED */ + DERSize sizeToZero); /* optional */ + +__END_DECLS + +#endif /* _DER_DECODE_H_ */ + diff --git a/lib/pki/libDER/DER_Digest.c b/lib/pki/libDER/DER_Digest.c new file mode 100644 index 0000000..df4234e --- /dev/null +++ b/lib/pki/libDER/DER_Digest.c @@ -0,0 +1,162 @@ +/* Copyright (c) 2005-2008,2010 Apple Inc. All Rights Reserved. */ + +/* + * DER_Digest.h - DER encode a DigestInfo + * + * Created Nov. 9 2005 by dmitch + */ + +#include + +/* + * Create an encoded DigestInfo based on the specified SHA1 digest. + * The digest must be 20 bytes long. + * + * Result is placed in caller's buffer, which must be at least of + * length DER_DIGEST_INFO_LEN bytes. + * + * The *resultLen parameter is the available size in the result + * buffer on input, and the actual length of the encoded DigestInfo + * on output. + * + * In the interest of saving code space, this just drops the caller's + * digest into an otherwise hard-coded, fixed, encoded SHA1 DigestInfo. + * Nothing is variable so we know the whole thing. It looks like this: + * + * SEQUENCE OF <33> { + * SEQUENCE OF <9> { + * OID <5>: OID : < 06 05 2B 0E 03 02 1A > + * NULL + * } + * OCTET STRING <20>: + * 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 + * 55 55 55 55 + * } + * + * + * tower.local:digestInfo> hexdump -x /tmp/encodedDigest + * 0000000 3021 3009 0605 2b0e 0302 1a05 0004 1455 + * 0000010 5555 5555 5555 5555 5555 5555 5555 5555 + * * + * 0000020 + */ + +static const unsigned char encodedSha1Digest[] = +{ + 0x30, 0x21, /* top level sequence length 33 */ + 0x30, 0x09, /* algorithm ID, sequence length 9 */ + 0x06, 0x05, /* alg OID, length 5, SHA1 */ + 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, /* NULL parameters */ + 0x04, 0x14 /* integer length 20 */ + /* digest follows */ +}; + +DERReturn DEREncodeSHA1DigestInfo( + const DERByte *sha1Digest, + DERSize sha1DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen) /* IN/OUT */ +{ + DERSize totalLen = sizeof(encodedSha1Digest) + DER_SHA1_DIGEST_LEN; + + if((sha1Digest == NULL) || (sha1DigestLen != DER_SHA1_DIGEST_LEN) || + (result == NULL) || (resultLen == NULL)) { + return DR_ParamErr; + } + if(*resultLen < DER_SHA1_DIGEST_INFO_LEN) { + return DR_BufOverflow; + } + DERMemmove(result, encodedSha1Digest, sizeof(encodedSha1Digest)); + DERMemmove(result + sizeof(encodedSha1Digest), sha1Digest, DER_SHA1_DIGEST_LEN); + *resultLen = totalLen; + return DR_Success; +} + +/* + joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) + csor(3) nistalgorithm(4) hashAlgs(2) sha256(1) + + future ones to add: sha384(2) sha512(3) sha224(4) +*/ +static const unsigned char encodedSha256Digest[] = +{ + 0x30, 0x31, /* top level sequence length 49 */ + 0x30, 0x0d, /* algorithm ID, sequence length 13 */ + 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, + 0x05, 0x00, /* NULL parameters */ + 0x04, 0x20 /* integer length 32 */ + /* digest follows */ +}; + +DERReturn DEREncodeSHA256DigestInfo( + const DERByte *sha256Digest, + DERSize sha256DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen) /* IN/OUT */ +{ + DERSize totalLen = sizeof(encodedSha256Digest) + DER_SHA256_DIGEST_LEN; + + if((sha256Digest == NULL) || (sha256DigestLen != DER_SHA256_DIGEST_LEN) || + (result == NULL) || (resultLen == NULL)) { + return DR_ParamErr; + } + if(*resultLen < DER_SHA256_DIGEST_INFO_LEN) { + return DR_BufOverflow; + } + DERMemmove(result, encodedSha256Digest, sizeof(encodedSha256Digest)); + DERMemmove(result + sizeof(encodedSha256Digest), sha256Digest, DER_SHA256_DIGEST_LEN); + *resultLen = totalLen; + return DR_Success; +} + + +/* Same thing, MD5/MD2 */ +static const unsigned char encodedMdDigest[] = +{ + 0x30, 0x20, /* top level sequence length 32 */ + 0x30, 0x0c, /* algorithm ID, sequence length 12 */ + 0x06, 0x08, /* alg OID, length 8, MD2/MD5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, + 0x05, /* 5 = MD5, 2 = MD2 */ + 0x05, 0x00, /* NULL parameters */ + 0x04, 0x10 /* integer length 16 */ + /* digest follows */ +}; + +#define WHICH_DIGEST_INDEX 13 +#define WHICH_DIGEST_MD2 2 +#define WHICH_DIGEST_MD5 5 + +DERReturn DEREncodeMDDigestInfo( + WhichDigest whichDigest, + const DERByte *mdDigest, + DERSize mdDigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen) /* IN/OUT */ +{ + DERSize totalLen = sizeof(encodedMdDigest) + DER_MD_DIGEST_LEN; + + if((mdDigest == NULL) || (mdDigestLen != DER_MD_DIGEST_LEN) || + (result == NULL) || (resultLen == NULL)) { + return DR_ParamErr; + } + if(*resultLen < totalLen) { + return DR_BufOverflow; + } + DERMemmove(result, encodedMdDigest, sizeof(encodedMdDigest)); + DERMemmove(result + sizeof(encodedMdDigest), mdDigest, DER_MD_DIGEST_LEN); + switch(whichDigest) { + case WD_MD2: + result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD2; + break; + case WD_MD5: + result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD5; + break; + default: + return DR_ParamErr; + } + *resultLen = totalLen; + return DR_Success; +} diff --git a/lib/pki/libDER/DER_Digest.h b/lib/pki/libDER/DER_Digest.h new file mode 100644 index 0000000..d37bae3 --- /dev/null +++ b/lib/pki/libDER/DER_Digest.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2005-2008,2010 Apple Inc. All Rights Reserved. */ + +/* + * DER_Digest.h - DER encode a DigestInfo + * + * Created Nov. 9 2005 by dmitch + */ + +#ifndef _DER_DIGEST_H_ +#define _DER_DIGEST_H_ + +#include + +__BEGIN_DECLS + +/* + * Create an encoded DigestInfo based on the specified SHA1 digest. + * The incoming digest must be 20 bytes long. + * + * Result is placed in caller's buffer, which must be at least of + * length DER_SHA1_DIGEST_INFO_LEN bytes. + * + * The *resultLen parameter is the available size in the result + * buffer on input, and the actual length of the encoded DigestInfo + * on output. + */ +#define DER_SHA1_DIGEST_LEN 20 +#define DER_SHA1_DIGEST_INFO_LEN 35 + +DERReturn DEREncodeSHA1DigestInfo( + const DERByte *sha1Digest, + DERSize sha1DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen); /* IN/OUT */ + +#define DER_SHA256_DIGEST_LEN 32 +#define DER_SHA256_DIGEST_INFO_LEN 51 + +DERReturn DEREncodeSHA256DigestInfo( + const DERByte *sha256Digest, + DERSize sha256DigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen); /* IN/OUT */ + +/* + * Likewise, create an encoded DIgestInfo for specified MD5 or MD2 digest. + */ +#define DER_MD_DIGEST_LEN 16 +#define DER_MD_DIGEST_INFO_LEN 34 + +typedef enum { + WD_MD2 = 1, + WD_MD5 = 2 +} WhichDigest; + +DERReturn DEREncodeMDDigestInfo( + WhichDigest whichDigest, + const DERByte *mdDigest, + DERSize mdDigestLen, + DERByte *result, /* encoded result RETURNED here */ + DERSize *resultLen); /* IN/OUT */ + +/* max sizes you'll need in the general cases */ +#define DER_MAX_DIGEST_LEN DER_SHA256_DIGEST_LEN +#define DER_MAX_ENCODED_INFO_LEN DER_SHA256_DIGEST_INFO_LEN + +__END_DECLS + +#endif /* _DER_DIGEST_H_ */ + diff --git a/lib/pki/libDER/DER_Encode.c b/lib/pki/libDER/DER_Encode.c new file mode 100644 index 0000000..032ba66 --- /dev/null +++ b/lib/pki/libDER/DER_Encode.c @@ -0,0 +1,342 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Encode.h - DER encoding routines + * + * Created Dec. 2 2005 by dmitch + */ + +#include +#include +#include +#include + +#ifndef DER_ENCODE_ENABLE +#error Please define DER_ENCODE_ENABLE. +#endif + +#if DER_ENCODE_ENABLE + +/* calculate size of encoded tag */ +static DERSize DERLengthOfTag( + DERTag tag) +{ + DERSize rtn = 1; + + tag &= ASN1_TAGNUM_MASK; + if (tag >= 0x1F) { + /* Shift 7-bit digits out of the tag integer until it's zero. */ + while(tag != 0) { + rtn++; + tag >>= 7; + } + } + + return rtn; +} + +/* encode tag */ +static DERReturn DEREncodeTag( + DERTag tag, + DERByte *buf, /* encoded length goes here */ + DERSize *inOutLen) /* IN/OUT */ +{ + DERSize outLen = DERLengthOfTag(tag); + DERTag tagNumber = tag & ASN1_TAGNUM_MASK; + DERByte tag1 = (tag >> (sizeof(DERTag) * 8 - 8)) & 0xE0; + + if(outLen > *inOutLen) { + return DR_BufOverflow; + } + + if(outLen == 1) { + /* short form */ + *buf = tag1 | tagNumber; + } + else { + /* long form */ + DERByte *tagBytes = buf + outLen; // l.s. digit of tag + *buf = tag1 | 0x1F; // tag class / method indicator + *--tagBytes = tagNumber & 0x7F; + tagNumber >>= 7; + while(tagNumber != 0) { + *--tagBytes = (tagNumber & 0x7F) | 0x80; + tagNumber >>= 7; + } + } + *inOutLen = outLen; + return DR_Success; +} + +/* calculate size of encoded length */ +DERSize DERLengthOfLength( + DERSize length) +{ + DERSize rtn; + + if(length < 0x80) { + /* short form length */ + return 1; + } + + /* long form - one length-of-length byte plus length bytes */ + rtn = 1; + while(length != 0) { + rtn++; + length >>= 8; + } + return rtn; +} + +/* encode length */ +DERReturn DEREncodeLength( + DERSize length, + DERByte *buf, /* encoded length goes here */ + DERSize *inOutLen) /* IN/OUT */ +{ + DERByte *lenBytes; + DERSize outLen = DERLengthOfLength(length); + + if(outLen > *inOutLen) { + return DR_BufOverflow; + } + + if(length < 0x80) { + /* short form */ + *buf = (DERByte)length; + *inOutLen = 1; + return DR_Success; + } + + /* long form */ + *buf = (outLen - 1) | 0x80; // length of length, long form indicator + lenBytes = buf + outLen - 1; // l.s. digit of length + while(length != 0) { + *lenBytes-- = (DERByte)length; + length >>= 8; + } + *inOutLen = outLen; + return DR_Success; +} + +DERSize DERLengthOfItem( + DERTag tag, + DERSize length) +{ + return DERLengthOfTag(tag) + DERLengthOfLength(length) + length; +} + +DERReturn DEREncodeItem( + DERTag tag, + DERSize length, + const DERByte *src, + DERByte *derOut, /* encoded item goes here */ + DERSize *inOutLen) /* IN/OUT */ +{ + DERReturn drtn; + DERSize itemLen; + DERByte *currPtr = derOut; + DERSize bytesLeft = DERLengthOfItem(tag, length); + if(bytesLeft > *inOutLen) { + return DR_BufOverflow; + } + *inOutLen = bytesLeft; + + /* top level tag */ + itemLen = bytesLeft; + drtn = DEREncodeTag(tag, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + itemLen = bytesLeft; + drtn = DEREncodeLength(length, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + DERMemmove(currPtr, src, length); + + return DR_Success; +} + +static /* calculate the content length of an encoded sequence */ +DERSize DERContentLengthOfEncodedSequence( + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs) +{ + DERSize contentLen = 0; + unsigned dex; + DERSize thisContentLen; + + /* find length of each item */ + for(dex=0; dexoptions; + const DERByte *byteSrc = (const DERByte *)src + currItemSpec->offset; + const DERItem *itemSrc = (const DERItem *)byteSrc; + + if(currOptions & DER_ENC_WRITE_DER) { + /* easy case - no encode */ + contentLen += itemSrc->length; + continue; + } + + if ((currOptions & DER_DEC_OPTIONAL) && itemSrc->length == 0) { + /* If an optional item isn't present we don't encode a + tag and len. */ + continue; + } + + /* + * length of this item = + * tag (one byte) + + * length of length + + * content length + + * optional zero byte for signed integer + */ + contentLen += DERLengthOfTag(currItemSpec->tag); + + /* check need for pad byte before calculating lengthOfLength... */ + thisContentLen = itemSrc->length; + if((currOptions & DER_ENC_SIGNED_INT) && + (itemSrc->length != 0)) { + if(itemSrc->data[0] & 0x80) { + /* insert zero keep it positive */ + thisContentLen++; + } + } + contentLen += DERLengthOfLength(thisContentLen); + contentLen += thisContentLen; + } + return contentLen; +} + +DERReturn DEREncodeSequence( + DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + DERByte *derOut, /* encoded data written here */ + DERSize *inOutLen) /* IN/OUT */ +{ + const DERByte *endPtr = derOut + *inOutLen; + DERByte *currPtr = derOut; + DERSize bytesLeft = *inOutLen; + DERSize contentLen; + DERReturn drtn; + DERSize itemLen; + unsigned dex; + + /* top level tag */ + itemLen = bytesLeft; + drtn = DEREncodeTag(topTag, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + if(currPtr >= endPtr) { + return DR_BufOverflow; + } + + /* content length */ + contentLen = DERContentLengthOfEncodedSequence(src, numItems, itemSpecs); + itemLen = bytesLeft; + drtn = DEREncodeLength(contentLen, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + if(currPtr + contentLen > endPtr) { + return DR_BufOverflow; + } + /* we don't have to check for overflow any more */ + + /* grind thru the items */ + for(dex=0; dexoptions; + const DERByte *byteSrc = (const DERByte *)src + currItemSpec->offset; + const DERItem *itemSrc = (const DERItem *)byteSrc; + int prependZero = 0; + + if(currOptions & DER_ENC_WRITE_DER) { + /* easy case */ + DERMemmove(currPtr, itemSrc->data, itemSrc->length); + currPtr += itemSrc->length; + bytesLeft -= itemSrc->length; + continue; + } + + if ((currOptions & DER_DEC_OPTIONAL) && itemSrc->length == 0) { + /* If an optional item isn't present we skip it. */ + continue; + } + + /* encode one item: first the tag */ + itemLen = bytesLeft; + drtn = DEREncodeTag(currItemSpec->tag, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + + /* do we need to prepend a zero to content? */ + contentLen = itemSrc->length; + if((currOptions & DER_ENC_SIGNED_INT) && + (itemSrc->length != 0)) { + if(itemSrc->data[0] & 0x80) { + /* insert zero keep it positive */ + contentLen++; + prependZero = 1; + } + } + + /* encode content length */ + itemLen = bytesLeft; + drtn = DEREncodeLength(contentLen, currPtr, &itemLen); + if(drtn) { + return drtn; + } + currPtr += itemLen; + bytesLeft -= itemLen; + + /* now the content, with possible leading zero added */ + if(prependZero) { + *currPtr++ = 0; + bytesLeft--; + } + DERMemmove(currPtr, itemSrc->data, itemSrc->length); + currPtr += itemSrc->length; + bytesLeft -= itemSrc->length; + } + *inOutLen = (DERSize)(currPtr - derOut); + return DR_Success; +} + +/* calculate the length of an encoded sequence. */ +DERSize DERLengthOfEncodedSequence( + DERTag topTag, + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs) +{ + DERSize contentLen = DERContentLengthOfEncodedSequence( + src, numItems, itemSpecs); + + return DERLengthOfTag(topTag) + + DERLengthOfLength(contentLen) + + contentLen; +} + +#endif /* DER_ENCODE_ENABLE */ + diff --git a/lib/pki/libDER/DER_Encode.h b/lib/pki/libDER/DER_Encode.h new file mode 100644 index 0000000..3cf2ede --- /dev/null +++ b/lib/pki/libDER/DER_Encode.h @@ -0,0 +1,98 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Encode.h - DER encoding routines + * + * Created Dec. 2 2005 by dmitch + */ + +#ifndef _DER_ENCODE_H_ +#define _DER_ENCODE_H_ + +#include + +__BEGIN_DECLS + +/* + * Max size of an encoded item given its length. + * This includes a possible leading zero prepended to a signed integer + * (see DER_ENC_SIGNED_INT below). + */ +#define DER_MAX_ENCODED_SIZE(len) \ + ( 1 + /* tag */ \ + 5 + /* max length */ \ + 1 + /* possible prepended zero */ \ + len) + +/* calculate size of encoded length */ +DERSize DERLengthOfLength( + DERSize length); + +/* encode length */ +DERReturn DEREncodeLength( + DERSize length, + DERByte *buf, /* encoded length goes here */ + DERSize *inOutLen); /* IN/OUT */ + +/* calculate size of encoded length */ +DERSize DERLengthOfItem( + DERTag tag, + DERSize length); + +/* encode item */ +DERReturn DEREncodeItem( + DERTag tag, + DERSize length, + const DERByte *src, + DERByte *derOut, /* encoded item goes here */ + DERSize *inOutLen); /* IN/OUT */ + +/* + * Per-item encode options. + */ + +/* explicit default, no options */ +#define DER_ENC_NO_OPTS 0x0000 + +/* signed integer check: if incoming m.s. bit is 1, prepend a zero */ +#define DER_ENC_SIGNED_INT 0x0100 + +/* DERItem contains fully encoded item - copy, don't encode */ +#define DER_ENC_WRITE_DER 0x0200 + + +/* + * High-level sequence or set encode support. + * + * The outgoing sequence is expressed as an array of DERItemSpecs, each + * of which corresponds to one item in the encoded sequence. + * + * Normally the tag of the encoded item comes from the associated + * DERItemSpec, and the content comes from the DERItem whose address is + * the src arg plus the offset value in the associated DERItemSpec. + * + * If the DER_ENC_WRITE_DER option is true for a given DERItemSpec then + * no per-item encoding is done; the DER - with tag, length, and content - + * is taken en masse from the associated DERItem. + */ +DERReturn DEREncodeSequence( + DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs, + DERByte *derOut, /* encoded data written here */ + DERSize *inOutLen); /* IN/OUT */ + +/* precalculate the length of an encoded sequence. */ +DERSize DERLengthOfEncodedSequence( + DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ + const void *src, /* generally a ptr to a struct full of + * DERItems */ + DERShort numItems, /* size of itemSpecs[] */ + const DERItemSpec *itemSpecs); + +__END_DECLS + +#endif /* _DER_DECODE_H_ */ + diff --git a/lib/pki/libDER/DER_Keys.c b/lib/pki/libDER/DER_Keys.c new file mode 100644 index 0000000..82e96fe --- /dev/null +++ b/lib/pki/libDER/DER_Keys.c @@ -0,0 +1,167 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Cert.c - support for decoding RSA keys + * + * Created Nov. 8 2005 by Doug Mitchell. + */ + +#include +#include +#include +#include +#include + +#ifndef DER_DECODE_ENABLE +#error Please define DER_DECODE_ENABLE. +#endif +#if DER_DECODE_ENABLE + +/* + * DERItemSpecs for decoding RSA keys. + */ + +/* Algorithm Identifier */ +const DERItemSpec DERAlgorithmIdItemSpecs[] = +{ + { DER_OFFSET(DERAlgorithmId, oid), + ASN1_OBJECT_ID, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERAlgorithmId, params), + 0, /* no tag - any */ + DER_DEC_ASN_ANY | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER } +}; +const DERSize DERNumAlgorithmIdItemSpecs = + sizeof(DERAlgorithmIdItemSpecs) / sizeof(DERItemSpec); + +/* X509 SubjectPublicKeyInfo */ +const DERItemSpec DERSubjPubKeyInfoItemSpecs[] = +{ + { DER_OFFSET(DERSubjPubKeyInfo, algId), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERSubjPubKeyInfo, pubKey), + ASN1_BIT_STRING, + DER_DEC_NO_OPTS }, + +}; +const DERSize DERNumSubjPubKeyInfoItemSpecs = + sizeof(DERSubjPubKeyInfoItemSpecs) / sizeof(DERItemSpec); + +/* + * RSA private key in CRT format + */ +const DERItemSpec DERRSAPrivKeyCRTItemSpecs[] = +{ + /* version, n, e, d - skip */ + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { 0, + ASN1_INTEGER, + DER_DEC_SKIP }, + { DER_OFFSET(DERRSAPrivKeyCRT, p), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, q), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, dp), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, dq), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERRSAPrivKeyCRT, qInv), + ASN1_INTEGER, + DER_DEC_NO_OPTS }, + /* ignore the (optional) rest */ +}; +const DERSize DERNumRSAPrivKeyCRTItemSpecs = + sizeof(DERRSAPrivKeyCRTItemSpecs) / sizeof(DERItemSpec); + +#endif /* DER_DECODE_ENABLE */ + +#if DER_DECODE_ENABLE || DER_ENCODE_ENABLE + +/* RSA public key in PKCS1 format - encode and decode */ +const DERItemSpec DERRSAPubKeyPKCS1ItemSpecs[] = +{ + { DER_OFFSET(DERRSAPubKeyPKCS1, modulus), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAPubKeyPKCS1, pubExponent), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, +}; +const DERSize DERNumRSAPubKeyPKCS1ItemSpecs = + sizeof(DERRSAPubKeyPKCS1ItemSpecs) / sizeof(DERItemSpec); + +/* RSA public key in Apple custome format with reciprocal - encode and decode */ +const DERItemSpec DERRSAPubKeyAppleItemSpecs[] = +{ + { DER_OFFSET(DERRSAPubKeyApple, modulus), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAPubKeyApple, reciprocal), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAPubKeyApple, pubExponent), + ASN1_INTEGER, + DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, +}; +const DERSize DERNumRSAPubKeyAppleItemSpecs = + sizeof(DERRSAPubKeyAppleItemSpecs) / sizeof(DERItemSpec); + + +#endif /* DER_DECODE_ENABLE || DER_ENCODE_ENABLE */ + +#ifndef DER_ENCODE_ENABLE +#error Please define DER_ENCODE_ENABLE. +#endif + +#if DER_ENCODE_ENABLE + +/* RSA Key Pair, encode only */ +const DERItemSpec DERRSAKeyPairItemSpecs[] = +{ + { DER_OFFSET(DERRSAKeyPair, version), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, n), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, e), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, d), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, p), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, q), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, dp), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, dq), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, + { DER_OFFSET(DERRSAKeyPair, qInv), + ASN1_INTEGER, + DER_ENC_SIGNED_INT }, +}; + +const DERSize DERNumRSAKeyPairItemSpecs = + sizeof(DERRSAKeyPairItemSpecs) / sizeof(DERItemSpec); + +#endif /* DER_ENCODE_ENABLE */ + diff --git a/lib/pki/libDER/DER_Keys.h b/lib/pki/libDER/DER_Keys.h new file mode 100644 index 0000000..5f9e289 --- /dev/null +++ b/lib/pki/libDER/DER_Keys.h @@ -0,0 +1,99 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * DER_Keys.h - support for decoding RSA keys + * + * Created Nov. 8 2005 by dmitch + */ + +#ifndef _DER_KEYS_H_ +#define _DER_KEYS_H_ + +#include +#include + +__BEGIN_DECLS + +/* Algorithm Identifier components */ +typedef struct { + DERItem oid; /* OID */ + DERItem params; /* ASN_ANY, optional, DER_DEC_SAVE_DER */ +} DERAlgorithmId; + +/* DERItemSpecs to decode into a DERAlgorithmId */ +extern const DERItemSpec DERAlgorithmIdItemSpecs[]; +extern const DERSize DERNumAlgorithmIdItemSpecs; + +/* X509 SubjectPublicKeyInfo */ +typedef struct { + DERItem algId; /* sequence, DERAlgorithmId */ + DERItem pubKey; /* BIT STRING */ +} DERSubjPubKeyInfo; + +/* DERItemSpecs to decode into a DERSubjPubKeyInfo */ +extern const DERItemSpec DERSubjPubKeyInfoItemSpecs[]; +extern const DERSize DERNumSubjPubKeyInfoItemSpecs; + +/* + * RSA public key in PKCS1 format; this is inside the BIT_STRING in + * DERSubjPubKeyInfo.pubKey. + */ +typedef struct { + DERItem modulus; /* n - INTEGER */ + DERItem pubExponent; /* e - INTEGER */ +} DERRSAPubKeyPKCS1; + +/* DERItemSpecs to decode/encode into/from a DERRSAPubKeyPKCS1 */ +extern const DERItemSpec DERRSAPubKeyPKCS1ItemSpecs[]; +extern const DERSize DERNumRSAPubKeyPKCS1ItemSpecs; + +/* + * RSA public key in custom (to this library) format, including + * the reciprocal. All fields are integers. + */ +typedef struct { + DERItem modulus; /* n */ + DERItem reciprocal; /* reciprocal of modulus */ + DERItem pubExponent; /* e */ +} DERRSAPubKeyApple; + +/* DERItemSpecs to decode/encode into/from a DERRSAPubKeyApple */ +extern const DERItemSpec DERRSAPubKeyAppleItemSpecs[]; +extern const DERSize DERNumRSAPubKeyAppleItemSpecs; + +/* + * RSA Private key, PKCS1 format, CRT option. + * All fields are integers. + */ +typedef struct { + DERItem p; /* p * q = n */ + DERItem q; + DERItem dp; /* d mod (p-1) */ + DERItem dq; /* d mod (q-1) */ + DERItem qInv; +} DERRSAPrivKeyCRT; + +/* DERItemSpecs to decode into a DERRSAPrivKeyCRT */ +extern const DERItemSpec DERRSAPrivKeyCRTItemSpecs[]; +extern const DERSize DERNumRSAPrivKeyCRTItemSpecs; + +/* Fully formed RSA key pair, for generating a PKCS1 private key */ +typedef struct { + DERItem version; + DERItem n; /* modulus */ + DERItem e; /* public exponent */ + DERItem d; /* private exponent */ + DERItem p; /* n = p*q */ + DERItem q; + DERItem dp; /* d mod (p-1) */ + DERItem dq; /* d mod (q-1) */ + DERItem qInv; /* q^(-1) mod p */ +} DERRSAKeyPair; + +/* DERItemSpecs to encode a DERRSAKeyPair */ +extern const DERItemSpec DERRSAKeyPairItemSpecs[]; +extern const DERSize DERNumRSAKeyPairItemSpecs; + +__END_DECLS + +#endif /* _DER_KEYS_H_ */ diff --git a/lib/pki/libDER/asn1Types.h b/lib/pki/libDER/asn1Types.h new file mode 100644 index 0000000..d8d1241 --- /dev/null +++ b/lib/pki/libDER/asn1Types.h @@ -0,0 +1,89 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * asn1Types.h - ASN.1/DER #defines - strictly hard coded per the real world + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _ASN1_TYPES_H_ +#define _ASN1_TYPES_H_ + +#include + +__BEGIN_DECLS + +/* copied from libsecurity_asn1 project */ + +#define ASN1_BOOLEAN 0x01 +#define ASN1_INTEGER 0x02 +#define ASN1_BIT_STRING 0x03 +#define ASN1_OCTET_STRING 0x04 +#define ASN1_NULL 0x05 +#define ASN1_OBJECT_ID 0x06 +#define ASN1_OBJECT_DESCRIPTOR 0x07 +/* External type and instance-of type 0x08 */ +#define ASN1_REAL 0x09 +#define ASN1_ENUMERATED 0x0a +#define ASN1_EMBEDDED_PDV 0x0b +#define ASN1_UTF8_STRING 0x0c +/* 0x0d */ +/* 0x0e */ +/* 0x0f */ +#define ASN1_SEQUENCE 0x10 +#define ASN1_SET 0x11 +#define ASN1_NUMERIC_STRING 0x12 +#define ASN1_PRINTABLE_STRING 0x13 +#define ASN1_T61_STRING 0x14 +#define ASN1_VIDEOTEX_STRING 0x15 +#define ASN1_IA5_STRING 0x16 +#define ASN1_UTC_TIME 0x17 +#define ASN1_GENERALIZED_TIME 0x18 +#define ASN1_GRAPHIC_STRING 0x19 +#define ASN1_VISIBLE_STRING 0x1a +#define ASN1_GENERAL_STRING 0x1b +#define ASN1_UNIVERSAL_STRING 0x1c +/* 0x1d */ +#define ASN1_BMP_STRING 0x1e +#define ASN1_HIGH_TAG_NUMBER 0x1f +#define ASN1_TELETEX_STRING ASN1_T61_STRING + +#ifdef DER_MULTIBYTE_TAGS + +#define ASN1_TAG_MASK ((DERTag)~0) +#define ASN1_TAGNUM_MASK ((DERTag)~((DERTag)7 << (sizeof(DERTag) * 8 - 3))) + +#define ASN1_METHOD_MASK ((DERTag)1 << (sizeof(DERTag) * 8 - 3)) +#define ASN1_PRIMITIVE ((DERTag)0 << (sizeof(DERTag) * 8 - 3)) +#define ASN1_CONSTRUCTED ((DERTag)1 << (sizeof(DERTag) * 8 - 3)) + +#define ASN1_CLASS_MASK ((DERTag)3 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_UNIVERSAL ((DERTag)0 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_APPLICATION ((DERTag)1 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_CONTEXT_SPECIFIC ((DERTag)2 << (sizeof(DERTag) * 8 - 2)) +#define ASN1_PRIVATE ((DERTag)3 << (sizeof(DERTag) * 8 - 2)) + +#else /* DER_MULTIBYTE_TAGS */ + +#define ASN1_TAG_MASK 0xff +#define ASN1_TAGNUM_MASK 0x1f +#define ASN1_METHOD_MASK 0x20 +#define ASN1_PRIMITIVE 0x00 +#define ASN1_CONSTRUCTED 0x20 + +#define ASN1_CLASS_MASK 0xc0 +#define ASN1_UNIVERSAL 0x00 +#define ASN1_APPLICATION 0x40 +#define ASN1_CONTEXT_SPECIFIC 0x80 +#define ASN1_PRIVATE 0xc0 + +#endif /* !DER_MULTIBYTE_TAGS */ + +/* sequence and set appear as the following */ +#define ASN1_CONSTR_SEQUENCE (ASN1_CONSTRUCTED | ASN1_SEQUENCE) +#define ASN1_CONSTR_SET (ASN1_CONSTRUCTED | ASN1_SET) + +__END_DECLS + +#endif /* _ASN1_TYPES_H_ */ + diff --git a/lib/pki/libDER/libDER.h b/lib/pki/libDER/libDER.h new file mode 100644 index 0000000..5ed39e5 --- /dev/null +++ b/lib/pki/libDER/libDER.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libDER.h - main header for libDER, a ROM-capable DER decoding library. + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _LIB_DER_H_ +#define _LIB_DER_H_ + +#include + +__BEGIN_DECLS + +/* + * Error returns generated by this library. + */ +typedef enum { + DR_Success = 0, + DR_EndOfSequence, /* end of sequence or set */ + DR_UnexpectedTag, /* unexpected tag found while decoding */ + DR_DecodeError, /* misc. decoding error (badly formatted DER) */ + DR_Unimplemented, /* function not implemented in this configuration */ + DR_IncompleteSeq, /* incomplete sequence */ + DR_ParamErr, /* incoming parameter error */ + DR_BufOverflow /* buffer overflow */ + /* etc. */ +} DERReturn; + +/* + * Primary representation of a block of memory. + */ +typedef struct { + DERByte *data; + DERSize length; +} DERItem; + +/* + * The structure of a sequence during decode or encode is expressed as + * an array of DERItemSpecs. While decoding or encoding a sequence, + * each item in the sequence corresponds to one DERItemSpec. + */ +typedef struct { + DERSize offset; /* offset of destination DERItem */ + DERTag tag; /* DER tag */ + DERShort options; /* DER_DEC_xxx or DER_ENC_xxx */ +} DERItemSpec; + +/* + * Macro to obtain offset of a DERDecodedInfo within a struct. + * FIXME this is going to need reworking to avoid compiler warnings + * on 64-bit compiles. It'll work OK as long as an offset can't be larger + * than a DERSize, but the cast from a pointer to a DERSize may + * provoke compiler warnings. + */ +#define DER_OFFSET(type, field) ((DERSize)(&((type *)0)->field)) + +__END_DECLS + +#endif /* _LIB_DER_H_ */ + diff --git a/lib/pki/libDER/libDER_config.h b/lib/pki/libDER/libDER_config.h new file mode 100644 index 0000000..46e014e --- /dev/null +++ b/lib/pki/libDER/libDER_config.h @@ -0,0 +1,89 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libDER_config.h - platform dependent #defines and typedefs for libDER + * + * Created Nov. 4 2005 by dmitch + */ + +#ifndef _LIB_DER_CONFIG_H_ +#define _LIB_DER_CONFIG_H_ + +#include +#include +#include + +__BEGIN_DECLS + +/* + * Basic data types: unsigned 8-bit integer, unsigned 32-bit integer + */ +typedef uint8_t DERByte; +typedef uint16_t DERShort; +typedef uint32_t DERSize; + +/* + * Use these #defines of you have memset, memmove, and memcmp; else + * write your own equivalents. + */ + +#define DERMemset(ptr, c, len) memset(ptr, c, len) +#define DERMemmove(dst, src, len) memmove(dst, src, len) +#define DERMemcmp(b1, b2, len) memcmp(b1, b2, len) + + +/*** + *** Compile time options to trim size of the library. + ***/ + +/* enable general DER encode */ +#define DER_ENCODE_ENABLE 1 + +/* enable general DER decode */ +#define DER_DECODE_ENABLE 1 + +#ifndef DER_MULTIBYTE_TAGS +/* enable multibyte tag support. */ +#define DER_MULTIBYTE_TAGS 1 +#endif + +#ifndef DER_TAG_SIZE +/* Iff DER_MULTIBYTE_TAGS is 1 this is the sizeof(DERTag) in bytes. Note that + tags are still encoded and decoded from a minimally encoded DER + represantation. This value determines how big each DERItemSpecs is, we + choose 2 since that makes DERItemSpecs 8 bytes wide. */ +#define DER_TAG_SIZE 8 +#endif + + +/* ---------------------- Do not edit below this line ---------------------- */ + +/* + * Logical representation of a tag (the encoded representation is always in + * the minimal number of bytes). The top 3 bits encode class and method + * The remaining bits encode the tag value. To obtain smaller DERItemSpecs + * sizes, choose the smallest type that fits your needs. Most standard ASN.1 + * usage only needs single byte tags, but ocasionally custom applications + * require a larger tag namespace. + */ +#if DER_MULTIBYTE_TAGS + +#if DER_TAG_SIZE == 1 +typedef uint8_t DERTag; +#elif DER_TAG_SIZE == 2 +typedef uint16_t DERTag; +#elif DER_TAG_SIZE == 4 +typedef uint32_t DERTag; +#elif DER_TAG_SIZE == 8 +typedef uint64_t DERTag; +#else +#error DER_TAG_SIZE invalid +#endif + +#else /* DER_MULTIBYTE_TAGS */ +typedef DERByte DERTag; +#endif /* !DER_MULTIBYTE_TAGS */ + +__END_DECLS + +#endif /* _LIB_DER_CONFIG_H_ */ diff --git a/lib/pki/libDER/oids.c b/lib/pki/libDER/oids.c new file mode 100644 index 0000000..8f1b3b3 --- /dev/null +++ b/lib/pki/libDER/oids.c @@ -0,0 +1,516 @@ +/* Copyright (c) 2005-2013, 2015 Apple Inc. All Rights Reserved. */ + +/* + * oids.c - OID consts + * + * Created Nov. 11 2005 by dmitch + */ + +#include +#include + +#define OID_ISO_CCITT_DIR_SERVICE 85 +#define OID_DS OID_ISO_CCITT_DIR_SERVICE +#define OID_ATTR_TYPE OID_DS, 4 +#define OID_EXTENSION OID_DS, 29 +#define OID_ISO_STANDARD 40 +#define OID_ISO_MEMBER 42 +#define OID_US OID_ISO_MEMBER, 134, 72 + +#define OID_ISO_IDENTIFIED_ORG 43 +#define OID_OSINET OID_ISO_IDENTIFIED_ORG, 4 +#define OID_GOSIP OID_ISO_IDENTIFIED_ORG, 5 +#define OID_DOD OID_ISO_IDENTIFIED_ORG, 6 +#define OID_OIW OID_ISO_IDENTIFIED_ORG, 14 + +/* From the PKCS Standards */ +#define OID_RSA OID_US, 134, 247, 13 +#define OID_RSA_HASH OID_RSA, 2 +#define OID_RSA_ENCRYPT OID_RSA, 3 +#define OID_PKCS OID_RSA, 1 +#define OID_PKCS_1 OID_PKCS, 1 +#define OID_PKCS_2 OID_PKCS, 2 +#define OID_PKCS_3 OID_PKCS, 3 +#define OID_PKCS_4 OID_PKCS, 4 +#define OID_PKCS_5 OID_PKCS, 5 +#define OID_PKCS_6 OID_PKCS, 6 +#define OID_PKCS_7 OID_PKCS, 7 +#define OID_PKCS_8 OID_PKCS, 8 +#define OID_PKCS_9 OID_PKCS, 9 +#define OID_PKCS_10 OID_PKCS, 10 +#define OID_PKCS_11 OID_PKCS, 11 +#define OID_PKCS_12 OID_PKCS, 12 + +/* ANSI X9.62 */ +#define OID_ANSI_X9_62 OID_US, 206, 61 +#define OID_PUBLIC_KEY_TYPE OID_ANSI_X9_62, 2 +#define OID_EC_SIG_TYPE OID_ANSI_X9_62, 4 +#define OID_ECDSA_WITH_SHA2 OID_EC_SIG_TYPE, 3 + +/* ANSI X9.42 */ +#define OID_ANSI_X9_42 OID_US, 206, 62, 2 +#define OID_ANSI_X9_42_SCHEME OID_ANSI_X9_42, 3 +#define OID_ANSI_X9_42_NAMED_SCHEME OID_ANSI_X9_42, 4 + +/* DOD IANA Security releated objects. */ +#define OID_IANA OID_DOD, 1, 5 + +/* Kerberos PKINIT */ +#define OID_KERBv5 OID_IANA, 2 +#define OID_KERBv5_PKINIT OID_KERBv5, 3 + +/* DOD IANA Mechanisms. */ +#define OID_MECHANISMS OID_IANA, 5 + +/* PKIX */ +#define OID_PKIX OID_MECHANISMS, 7 +#define OID_PE OID_PKIX, 1 +#define OID_QT OID_PKIX, 2 +#define OID_KP OID_PKIX, 3 +#define OID_OTHER_NAME OID_PKIX, 8 +#define OID_PDA OID_PKIX, 9 +#define OID_QCS OID_PKIX, 11 +#define OID_AD OID_PKIX, 48 +#define OID_AD_OCSP OID_AD, 1 +#define OID_AD_CAISSUERS OID_AD, 2 + +/* ISAKMP */ +#define OID_ISAKMP OID_MECHANISMS, 8 + +/* ETSI */ +#define OID_ETSI 0x04, 0x00 +#define OID_ETSI_QCS 0x04, 0x00, 0x8E, 0x46, 0x01 + +#define OID_OIW_SECSIG OID_OIW, 3 + +#define OID_OIW_ALGORITHM OID_OIW_SECSIG, 2 + +/* NIST defined digest algorithm arc (2, 16, 840, 1, 101, 3, 4, 2) */ +#define OID_NIST_HASHALG 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02 + +/* + * Apple-specific OID bases + */ + +/* + * apple OBJECT IDENTIFIER ::= + * { iso(1) member-body(2) US(840) 113635 } + * + * BER = 06 06 2A 86 48 86 F7 63 + */ +#define APPLE_OID OID_US, 0x86, 0xf7, 0x63 + +/* appleDataSecurity OBJECT IDENTIFIER ::= + * { apple 100 } + * { 1 2 840 113635 100 } + * + * BER = 06 07 2A 86 48 86 F7 63 64 + */ +#define APPLE_ADS_OID APPLE_OID, 0x64 + +/* + * appleTrustPolicy OBJECT IDENTIFIER ::= + * { appleDataSecurity 1 } + * { 1 2 840 113635 100 1 } + * + * BER = 06 08 2A 86 48 86 F7 63 64 01 + */ +#define APPLE_TP_OID APPLE_ADS_OID, 1 + +/* + * appleSecurityAlgorithm OBJECT IDENTIFIER ::= + * { appleDataSecurity 2 } + * { 1 2 840 113635 100 2 } + * + * BER = 06 08 2A 86 48 86 F7 63 64 02 + */ +#define APPLE_ALG_OID APPLE_ADS_OID, 2 + +/* + * appleDotMacCertificate OBJECT IDENTIFIER ::= + * { appleDataSecurity 3 } + * { 1 2 840 113635 100 3 } + */ +#define APPLE_DOTMAC_CERT_OID APPLE_ADS_OID, 3 + +/* + * Basis of Policy OIDs for .mac TP requests + * + * dotMacCertificateRequest OBJECT IDENTIFIER ::= + * { appleDotMacCertificate 1 } + * { 1 2 840 113635 100 3 1 } + */ +#define APPLE_DOTMAC_CERT_REQ_OID APPLE_DOTMAC_CERT_OID, 1 + +/* + * Basis of .mac Certificate Extensions + * + * dotMacCertificateExtension OBJECT IDENTIFIER ::= + * { appleDotMacCertificate 2 } + * { 1 2 840 113635 100 3 2 } + */ +#define APPLE_DOTMAC_CERT_EXTEN_OID APPLE_DOTMAC_CERT_OID, 2 + +/* + * Basis of .mac Certificate request OID/value identitifiers + * + * dotMacCertificateRequestValues OBJECT IDENTIFIER ::= + * { appleDotMacCertificate 3 } + * { 1 2 840 113635 100 3 3 } + */ +#define APPLE_DOTMAC_CERT_REQ_VALUE_OID APPLE_DOTMAC_CERT_OID, 3 + +/* + * Basis of Apple-specific extended key usages + * + * appleExtendedKeyUsage OBJECT IDENTIFIER ::= + * { appleDataSecurity 4 } + * { 1 2 840 113635 100 4 } + */ +#define APPLE_EKU_OID APPLE_ADS_OID, 4 + +/* + * Basis of Apple Code Signing extended key usages + * appleCodeSigning OBJECT IDENTIFIER ::= + * { appleExtendedKeyUsage 1 } + * { 1 2 840 113635 100 4 1} + */ +#define APPLE_EKU_CODE_SIGNING APPLE_EKU_OID, 1 +#define APPLE_EKU_APPLE_ID APPLE_EKU_OID, 7 +#define APPLE_EKU_SHOEBOX APPLE_EKU_OID, 14 + +/* + * Basis of Apple-specific Certific Policy IDs. + * appleCertificatePolicies OBJECT IDENTIFIER ::= + * { appleDataSecurity 5 } + * { 1 2 840 113635 100 5 } + */ +#define APPLE_CERT_POLICIES APPLE_ADS_OID, 5 + +/* + * Basis of Apple-specific Signing extensions + * { appleDataSecurity 6 } + */ +#define APPLE_CERT_EXT APPLE_ADS_OID, 6 + +/* Apple Intermediate Marker OIDs */ +#define APPLE_CERT_EXT_INTERMEDIATE_MARKER APPLE_CERT_EXT, 2 +/* Apple Apple ID Intermediate Marker */ +#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 3 +/* + * Apple Apple ID Intermediate Marker (New subCA, no longer shared with push notification server cert issuer + * + * appleCertificateExtensionAppleIDIntermediate ::= + * { appleCertificateExtensionIntermediateMarker 7 } + * { 1 2 840 113635 100 6 2 7 } + */ +#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 7 + +#define APPLE_CERT_EXT_APPLE_PUSH_MARKER APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID, 2 + + +#define APPLE_CERT_EXTENSION_CODESIGNING APPLE_CERT_EXT, 1 + +/* Secure Boot Embedded Image3 value, + co-opted by desktop for "Apple Released Code Signature", without value */ +#define APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID APPLE_CERT_EXTENSION_CODESIGNING, 1 +#define APPLE_SBOOT_CERT_EXTEN_SBOOT_TICKET_SPEC_OID APPLE_CERT_EXTENSION_CODESIGNING, 11 +#define APPLE_SBOOT_CERT_EXTEN_IMG4_MANIFEST_SPEC_OID APPLE_CERT_EXTENSION_CODESIGNING, 15 +/* iPhone Provisioning Profile Signing leaf - on the intermediate marker arc? */ +#define APPLE_PROVISIONING_PROFILE_OID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 1 +/* iPhone Application Signing leaf */ +#define APPLE_APP_SIGINING_OID APPLE_CERT_EXTENSION_CODESIGNING, 3 +/* Shoebox card signing leaf */ +#define APPLE_INSTALLER_PACKAGE_SIGNING_EXTERNAL_OID APPLE_CERT_EXTENSION_CODESIGNING, 16 + +/* + * Netscape OIDs. + */ +#define NETSCAPE_BASE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42 + +/* + * Netscape cert extension. + * + * netscape-cert-extension OBJECT IDENTIFIER ::= + * { 2 16 840 1 113730 1 } + * + * BER = 06 08 60 86 48 01 86 F8 42 01 + */ +#define NETSCAPE_CERT_EXTEN NETSCAPE_BASE_OID, 0x01 + +#define NETSCAPE_CERT_POLICY NETSCAPE_BASE_OID, 0x04 + +/* Entrust OIDs. */ +#define ENTRUST_BASE_OID OID_US, 0x86, 0xf6, 0x7d + +/* + * Entrust cert extension. + * + * entrust-cert-extension OBJECT IDENTIFIER ::= + * { 1 2 840 113533 7 65 } + * + * BER = 06 08 2A 86 48 86 F6 7D 07 41 + */ +#define ENTRUST_CERT_EXTEN ENTRUST_BASE_OID, 0x07, 0x41 + +/* Microsfot OIDs. */ +#define MICROSOFT_BASE_OID OID_DOD, 0x01, 0x04, 0x01, 0x82, 0x37 +#define MICROSOFT_ENROLLMENT_OID MICROSOFT_BASE_OID, 0x14 + +/* Algorithm OIDs. */ +static const DERByte + _oidRsa[] = { OID_PKCS_1, 1 }, + _oidMd2Rsa[] = { OID_PKCS_1, 2 }, + _oidMd5Rsa[] = { OID_PKCS_1, 4 }, + _oidSha1Rsa[] = { OID_PKCS_1, 5 }, + _oidSha256Rsa[] = { OID_PKCS_1, 11 }, /* rfc5754 */ + _oidSha384Rsa[] = { OID_PKCS_1, 12 }, /* rfc5754 */ + _oidSha512Rsa[] = { OID_PKCS_1, 13 }, /* rfc5754 */ + _oidSha224Rsa[] = { OID_PKCS_1, 14 }, /* rfc5754 */ + _oidEcPubKey[] = { OID_PUBLIC_KEY_TYPE, 1 }, + _oidSha1Ecdsa[] = { OID_EC_SIG_TYPE, 1 }, /* rfc3279 */ + _oidSha224Ecdsa[] = { OID_ECDSA_WITH_SHA2, 1 }, /* rfc5758 */ + _oidSha256Ecdsa[] = { OID_ECDSA_WITH_SHA2, 2 }, /* rfc5758 */ + _oidSha384Ecdsa[] = { OID_ECDSA_WITH_SHA2, 3 }, /* rfc5758 */ + _oidSha512Ecdsa[] = { OID_ECDSA_WITH_SHA2, 4 }, /* rfc5758 */ + _oidMd2[] = { OID_RSA_HASH, 2 }, + _oidMd4[] = { OID_RSA_HASH, 4 }, + _oidMd5[] = { OID_RSA_HASH, 5 }, + _oidSha1[] = { OID_OIW_ALGORITHM, 26 }, + _oidSha256[] = { OID_NIST_HASHALG, 1 }, + _oidSha384[] = { OID_NIST_HASHALG, 2 }, + _oidSha512[] = { OID_NIST_HASHALG, 3 }, + _oidSha224[] = { OID_NIST_HASHALG, 4 }; + +const DERItem + oidRsa = { (DERByte *)_oidRsa, + sizeof(_oidRsa) }, + oidMd2Rsa = { (DERByte *)_oidMd2Rsa, + sizeof(_oidMd2Rsa) }, + oidMd5Rsa = { (DERByte *)_oidMd5Rsa, + sizeof(_oidMd5Rsa) }, + oidSha1Rsa = { (DERByte *)_oidSha1Rsa, + sizeof(_oidSha1Rsa) }, + oidSha224Rsa = { (DERByte *)_oidSha224Rsa, + sizeof(_oidSha224Rsa) }, + oidSha256Rsa = { (DERByte *)_oidSha256Rsa, + sizeof(_oidSha256Rsa) }, + oidSha384Rsa = { (DERByte *)_oidSha384Rsa, + sizeof(_oidSha384Rsa) }, + oidSha512Rsa = { (DERByte *)_oidSha512Rsa, + sizeof(_oidSha512Rsa) }, + oidEcPubKey = { (DERByte *)_oidEcPubKey, + sizeof(_oidEcPubKey) }, + oidSha1Ecdsa = { (DERByte *)_oidSha1Ecdsa, + sizeof(_oidSha1Ecdsa) }, + oidSha224Ecdsa = { (DERByte *)_oidSha224Ecdsa, + sizeof(_oidSha224Ecdsa) }, + oidSha256Ecdsa = { (DERByte *)_oidSha256Ecdsa, + sizeof(_oidSha256Ecdsa) }, + oidSha384Ecdsa = { (DERByte *)_oidSha384Ecdsa, + sizeof(_oidSha384Ecdsa) }, + oidSha512Ecdsa = { (DERByte *)_oidSha512Ecdsa, + sizeof(_oidSha512Ecdsa) }, + oidMd2 = { (DERByte *)_oidMd2, + sizeof(_oidMd2) }, + oidMd4 = { (DERByte *)_oidMd4, + sizeof(_oidMd4) }, + oidMd5 = { (DERByte *)_oidMd5, + sizeof(_oidMd5) }, + oidSha1 = { (DERByte *)_oidSha1, + sizeof(_oidSha1) }, + oidSha256 = { (DERByte *)_oidSha256, + sizeof(_oidSha256) }, + oidSha384 = { (DERByte *)_oidSha384, + sizeof(_oidSha384) }, + oidSha512 = { (DERByte *)_oidSha512, + sizeof(_oidSha512) }, + oidSha224 = { (DERByte *)_oidSha224, + sizeof(_oidSha224) }; + +/* Extension OIDs. */ +static const DERByte + _oidSubjectKeyIdentifier[] = { OID_EXTENSION, 14 }, + _oidKeyUsage[] = { OID_EXTENSION, 15 }, + _oidPrivateKeyUsagePeriod[] = { OID_EXTENSION, 16 }, + _oidSubjectAltName[] = { OID_EXTENSION, 17 }, + _oidIssuerAltName[] = { OID_EXTENSION, 18 }, + _oidBasicConstraints[] = { OID_EXTENSION, 19 }, + _oidCrlDistributionPoints[] = { OID_EXTENSION, 31 }, + _oidCertificatePolicies[] = { OID_EXTENSION, 32 }, + _oidAnyPolicy[] = { OID_EXTENSION, 32, 0 }, + _oidPolicyMappings[] = { OID_EXTENSION, 33 }, + _oidAuthorityKeyIdentifier[] = { OID_EXTENSION, 35 }, + _oidPolicyConstraints[] = { OID_EXTENSION, 36 }, + _oidExtendedKeyUsage[] = { OID_EXTENSION, 37 }, + _oidAnyExtendedKeyUsage[] = { OID_EXTENSION, 37, 0 }, + _oidInhibitAnyPolicy[] = { OID_EXTENSION, 54 }, + _oidAuthorityInfoAccess[] = { OID_PE, 1 }, + _oidSubjectInfoAccess[] = { OID_PE, 11 }, + _oidAdOCSP[] = { OID_AD_OCSP }, + _oidAdCAIssuer[] = { OID_AD_CAISSUERS }, + _oidNetscapeCertType[] = { NETSCAPE_CERT_EXTEN, 1 }, + _oidEntrustVersInfo[] = { ENTRUST_CERT_EXTEN, 0 }, + _oidMSNTPrincipalName[] = { MICROSOFT_ENROLLMENT_OID, 2, 3 }, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + _oidQtCps[] = { OID_QT, 1 }, + _oidQtUNotice[] = { OID_QT, 2 }, + /* X.501 Name IDs. */ + _oidCommonName[] = { OID_ATTR_TYPE, 3 }, + _oidCountryName[] = { OID_ATTR_TYPE, 6 }, + _oidLocalityName[] = { OID_ATTR_TYPE, 7 }, + _oidStateOrProvinceName[] = { OID_ATTR_TYPE, 8 }, + _oidOrganizationName[] = { OID_ATTR_TYPE, 10 }, + _oidOrganizationalUnitName[] = { OID_ATTR_TYPE, 11 }, + _oidDescription[] = { OID_ATTR_TYPE, 13 }, + _oidEmailAddress[] = { OID_PKCS_9, 1 }, + _oidFriendlyName[] = { OID_PKCS_9, 20 }, + _oidLocalKeyId[] = { OID_PKCS_9, 21 }, + _oidExtendedKeyUsageServerAuth[] = { OID_KP, 1 }, + _oidExtendedKeyUsageClientAuth[] = { OID_KP, 2 }, + _oidExtendedKeyUsageCodeSigning[] = { OID_KP, 3 }, + _oidExtendedKeyUsageEmailProtection[] = { OID_KP, 4 }, + _oidExtendedKeyUsageOCSPSigning[] = { OID_KP, 9 }, + _oidExtendedKeyUsageIPSec[] = { OID_ISAKMP, 2, 2 }, + _oidExtendedKeyUsageMicrosoftSGC[] = { MICROSOFT_BASE_OID, 10, 3, 3 }, + _oidExtendedKeyUsageNetscapeSGC[] = { NETSCAPE_CERT_POLICY, 1 }, + _oidAppleSecureBootCertSpec[] = { APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID }, + _oidAppleSecureBootTicketCertSpec[] = { APPLE_SBOOT_CERT_EXTEN_SBOOT_TICKET_SPEC_OID }, + _oidAppleImg4ManifestCertSpec[] = { + APPLE_SBOOT_CERT_EXTEN_IMG4_MANIFEST_SPEC_OID }, + _oidAppleProvisioningProfile[] = {APPLE_PROVISIONING_PROFILE_OID }, + _oidAppleApplicationSigning[] = { APPLE_APP_SIGINING_OID }, + _oidAppleInstallerPackagingSigningExternal[] = { APPLE_INSTALLER_PACKAGE_SIGNING_EXTERNAL_OID }, + _oidAppleExtendedKeyUsageAppleID[] = { APPLE_EKU_APPLE_ID }, + _oidAppleExtendedKeyUsageShoebox[] = { APPLE_EKU_SHOEBOX }, +#if 0 // unused + _oidApplePushServiceClient[] = { APPLE_CERT_EXT_APPLE_PUSH_MARKER, 2 }, +#endif + _oidAppleIntmMarkerAppleID[] = { APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID }, + _oidAppleIntmMarkerAppleID2[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 }; + +const DERItem + oidSubjectKeyIdentifier = { (DERByte *)_oidSubjectKeyIdentifier, + sizeof(_oidSubjectKeyIdentifier) }, + oidKeyUsage = { (DERByte *)_oidKeyUsage, + sizeof(_oidKeyUsage) }, + oidPrivateKeyUsagePeriod = { (DERByte *)_oidPrivateKeyUsagePeriod, + sizeof(_oidPrivateKeyUsagePeriod) }, + oidSubjectAltName = { (DERByte *)_oidSubjectAltName, + sizeof(_oidSubjectAltName) }, + oidIssuerAltName = { (DERByte *)_oidIssuerAltName, + sizeof(_oidIssuerAltName) }, + oidBasicConstraints = { (DERByte *)_oidBasicConstraints, + sizeof(_oidBasicConstraints) }, + oidCrlDistributionPoints = { (DERByte *)_oidCrlDistributionPoints, + sizeof(_oidCrlDistributionPoints) }, + oidCertificatePolicies = { (DERByte *)_oidCertificatePolicies, + sizeof(_oidCertificatePolicies) }, + oidAnyPolicy = { (DERByte *)_oidAnyPolicy, + sizeof(_oidAnyPolicy) }, + oidPolicyMappings = { (DERByte *)_oidPolicyMappings, + sizeof(_oidPolicyMappings) }, + oidAuthorityKeyIdentifier = { (DERByte *)_oidAuthorityKeyIdentifier, + sizeof(_oidAuthorityKeyIdentifier) }, + oidPolicyConstraints = { (DERByte *)_oidPolicyConstraints, + sizeof(_oidPolicyConstraints) }, + oidExtendedKeyUsage = { (DERByte *)_oidExtendedKeyUsage, + sizeof(_oidExtendedKeyUsage) }, + oidAnyExtendedKeyUsage = { (DERByte *)_oidAnyExtendedKeyUsage, + sizeof(_oidAnyExtendedKeyUsage) }, + oidInhibitAnyPolicy = { (DERByte *)_oidInhibitAnyPolicy, + sizeof(_oidInhibitAnyPolicy) }, + oidAuthorityInfoAccess = { (DERByte *)_oidAuthorityInfoAccess, + sizeof(_oidAuthorityInfoAccess) }, + oidSubjectInfoAccess = { (DERByte *)_oidSubjectInfoAccess, + sizeof(_oidSubjectInfoAccess) }, + oidAdOCSP = { (DERByte *)_oidAdOCSP, + sizeof(_oidAdOCSP) }, + oidAdCAIssuer = { (DERByte *)_oidAdCAIssuer, + sizeof(_oidAdCAIssuer) }, + oidNetscapeCertType = { (DERByte *)_oidNetscapeCertType, + sizeof(_oidNetscapeCertType) }, + oidEntrustVersInfo = { (DERByte *)_oidEntrustVersInfo, + sizeof(_oidEntrustVersInfo) }, + oidMSNTPrincipalName = { (DERByte *)_oidMSNTPrincipalName, + sizeof(_oidMSNTPrincipalName) }, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + oidQtCps = { (DERByte *)_oidQtCps, + sizeof(_oidQtCps) }, + oidQtUNotice = { (DERByte *)_oidQtUNotice, + sizeof(_oidQtUNotice) }, + /* X.501 Name IDs. */ + oidCommonName = { (DERByte *)_oidCommonName, + sizeof(_oidCommonName) }, + oidCountryName = { (DERByte *)_oidCountryName, + sizeof(_oidCountryName) }, + oidLocalityName = { (DERByte *)_oidLocalityName, + sizeof(_oidLocalityName) }, + oidStateOrProvinceName = { (DERByte *)_oidStateOrProvinceName, + sizeof(_oidStateOrProvinceName) }, + oidOrganizationName = { (DERByte *)_oidOrganizationName, + sizeof(_oidOrganizationName) }, + oidOrganizationalUnitName = { (DERByte *)_oidOrganizationalUnitName, + sizeof(_oidOrganizationalUnitName) }, + oidDescription = { (DERByte *)_oidDescription, + sizeof(_oidDescription) }, + oidEmailAddress = { (DERByte *)_oidEmailAddress, + sizeof(_oidEmailAddress) }, + oidFriendlyName = { (DERByte *)_oidFriendlyName, + sizeof(_oidFriendlyName) }, + oidLocalKeyId = { (DERByte *)_oidLocalKeyId, + sizeof(_oidLocalKeyId) }, + oidExtendedKeyUsageServerAuth = { (DERByte *)_oidExtendedKeyUsageServerAuth, + sizeof(_oidExtendedKeyUsageServerAuth) }, + oidExtendedKeyUsageClientAuth = { (DERByte *)_oidExtendedKeyUsageClientAuth, + sizeof(_oidExtendedKeyUsageClientAuth) }, + oidExtendedKeyUsageCodeSigning = { (DERByte *)_oidExtendedKeyUsageCodeSigning, + sizeof(_oidExtendedKeyUsageCodeSigning) }, + oidExtendedKeyUsageEmailProtection = { (DERByte *)_oidExtendedKeyUsageEmailProtection, + sizeof(_oidExtendedKeyUsageEmailProtection) }, + oidExtendedKeyUsageOCSPSigning = { (DERByte *)_oidExtendedKeyUsageOCSPSigning, + sizeof(_oidExtendedKeyUsageOCSPSigning) }, + oidExtendedKeyUsageIPSec = { (DERByte *)_oidExtendedKeyUsageIPSec, + sizeof(_oidExtendedKeyUsageIPSec) }, + oidExtendedKeyUsageMicrosoftSGC = { (DERByte *)_oidExtendedKeyUsageMicrosoftSGC, + sizeof(_oidExtendedKeyUsageMicrosoftSGC) }, + oidExtendedKeyUsageNetscapeSGC = { (DERByte *)_oidExtendedKeyUsageNetscapeSGC, + sizeof(_oidExtendedKeyUsageNetscapeSGC) }, + oidAppleSecureBootCertSpec = { (DERByte *)_oidAppleSecureBootCertSpec, + sizeof(_oidAppleSecureBootCertSpec) }, + oidAppleSecureBootTicketCertSpec = { (DERByte *)_oidAppleSecureBootTicketCertSpec, + sizeof(_oidAppleSecureBootTicketCertSpec) }, + oidAppleImg4ManifestCertSpec = { (DERByte *) + _oidAppleImg4ManifestCertSpec, + sizeof(_oidAppleImg4ManifestCertSpec) }, + oidAppleProvisioningProfile = { (DERByte *)_oidAppleProvisioningProfile, + sizeof(_oidAppleProvisioningProfile) }, + oidAppleApplicationSigning = { (DERByte *)_oidAppleApplicationSigning, + sizeof(_oidAppleApplicationSigning) }, + oidAppleInstallerPackagingSigningExternal = { (DERByte *)_oidAppleInstallerPackagingSigningExternal, + sizeof(_oidAppleInstallerPackagingSigningExternal) }, + oidAppleExtendedKeyUsageAppleID = { (DERByte *)_oidAppleExtendedKeyUsageAppleID, + sizeof(_oidAppleExtendedKeyUsageAppleID) }, + oidAppleExtendedKeyUsageShoebox = { (DERByte *)_oidAppleExtendedKeyUsageShoebox, + sizeof(_oidAppleExtendedKeyUsageShoebox) }, + oidAppleIntmMarkerAppleID = { (DERByte *)_oidAppleIntmMarkerAppleID, + sizeof(_oidAppleIntmMarkerAppleID) }, + oidAppleIntmMarkerAppleID2 = { (DERByte *)_oidAppleIntmMarkerAppleID2, + sizeof(_oidAppleIntmMarkerAppleID2) }, + oidApplePushServiceClient = { (DERByte *)_oidAppleIntmMarkerAppleID2, + sizeof(_oidAppleIntmMarkerAppleID2) }; + + +bool DEROidCompare(const DERItem *oid1, const DERItem *oid2) { + if ((oid1 == NULL) || (oid2 == NULL)) { + return false; + } + if (oid1->length != oid2->length) { + return false; + } + if (!DERMemcmp(oid1->data, oid2->data, oid1->length)) { + return true; + } else { + return false; + } +} diff --git a/lib/pki/libDER/oids.h b/lib/pki/libDER/oids.h new file mode 100644 index 0000000..5cbbc5c --- /dev/null +++ b/lib/pki/libDER/oids.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2005-2009, 2011-2012, 2015 Apple Inc. All Rights Reserved. */ + +/* + * oids.h - declaration of OID consts + * + * Created Nov. 11 2005 by dmitch + */ + +#ifndef _LIB_DER_OIDS_H_ +#define _LIB_DER_OIDS_H_ + +#include +#include + +__BEGIN_DECLS + +/* Algorithm oids. */ +extern const DERItem + oidRsa, /* PKCS1 RSA encryption, used to identify RSA keys */ + oidMd2Rsa, /* PKCS1 md2withRSAEncryption signature alg */ + oidMd5Rsa, /* PKCS1 md5withRSAEncryption signature alg */ + oidSha1Rsa, /* PKCS1 sha1withRSAEncryption signature alg */ + oidSha224Rsa, /* PKCS1 sha224WithRSAEncryption signature alg */ + oidSha256Rsa, /* PKCS1 sha256WithRSAEncryption signature alg */ + oidSha384Rsa, /* PKCS1 sha384WithRSAEncryption signature alg */ + oidSha512Rsa, /* PKCS1 sha512WithRSAEncryption signature alg */ + oidEcPubKey, /* ECDH or ECDSA public key in a certificate */ + oidSha1Ecdsa, /* ECDSA with SHA1 signature alg */ + oidSha224Ecdsa, /* ECDSA with SHA224 signature alg */ + oidSha256Ecdsa, /* ECDSA with SHA256 signature alg */ + oidSha384Ecdsa, /* ECDSA with SHA384 signature alg */ + oidSha512Ecdsa, /* ECDSA with SHA512 signature alg */ + oidMd2, /* OID_RSA_HASH 2 */ + oidMd4, /* OID_RSA_HASH 4 */ + oidMd5, /* OID_RSA_HASH 5 */ + oidSha1, /* OID_OIW_ALGORITHM 26 */ + oidSha256, /* OID_NIST_HASHALG 1 */ + oidSha384, /* OID_NIST_HASHALG 2 */ + oidSha512, /* OID_NIST_HASHALG 3 */ + oidSha224; /* OID_NIST_HASHALG 4 */ + +/* Standard X.509 Cert and CRL extensions. */ +extern const DERItem + oidSubjectKeyIdentifier, + oidKeyUsage, + oidPrivateKeyUsagePeriod, + oidSubjectAltName, + oidIssuerAltName, + oidBasicConstraints, + oidCrlDistributionPoints, + oidCertificatePolicies, + oidAnyPolicy, + oidPolicyMappings, + oidAuthorityKeyIdentifier, + oidPolicyConstraints, + oidExtendedKeyUsage, + oidAnyExtendedKeyUsage, + oidInhibitAnyPolicy, + oidAuthorityInfoAccess, + oidSubjectInfoAccess, + oidAdOCSP, + oidAdCAIssuer, + oidNetscapeCertType, + oidEntrustVersInfo, + oidMSNTPrincipalName, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + oidQtCps, + oidQtUNotice, + /* X.501 Name IDs. */ + oidCommonName, + oidCountryName, + oidLocalityName, + oidStateOrProvinceName, + oidOrganizationName, + oidOrganizationalUnitName, + oidDescription, + oidEmailAddress, + oidFriendlyName, + oidLocalKeyId, + oidExtendedKeyUsageServerAuth, + oidExtendedKeyUsageClientAuth, + oidExtendedKeyUsageCodeSigning, + oidExtendedKeyUsageEmailProtection, + oidExtendedKeyUsageOCSPSigning, + oidExtendedKeyUsageIPSec, + oidExtendedKeyUsageMicrosoftSGC, + oidExtendedKeyUsageNetscapeSGC, + /* Secure Boot Spec oid */ + oidAppleSecureBootCertSpec, + /* Ticket-Based Secure Boot Spec oid */ + oidAppleSecureBootTicketCertSpec, + /* Image4 Manifest Signing Cert Spec */ + oidAppleImg4ManifestCertSpec, + oidAppleProvisioningProfile, + oidAppleApplicationSigning, + oidAppleInstallerPackagingSigningExternal, + oidAppleExtendedKeyUsageAppleID, + oidAppleExtendedKeyUsageShoebox, + oidAppleIntmMarkerAppleID, + oidAppleIntmMarkerAppleID2, + oidApplePushServiceClient; + +/* Compare two decoded OIDs. Returns true iff they are equivalent. */ +bool DEROidCompare(const DERItem *oid1, const DERItem *oid2); + +__END_DECLS + +#endif /* _LIB_DER_UTILS_H_ */ diff --git a/lib/pki/libGiants/giantDebug.c b/lib/pki/libGiants/giantDebug.c new file mode 100644 index 0000000..7a17a86 --- /dev/null +++ b/lib/pki/libGiants/giantDebug.c @@ -0,0 +1,63 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantDebug.c - debugging support + * + * Created Aug. 5 2005 by Doug Mitchell. + */ + +#include +#include + +#if GIANTS_DEBUG + +void GIRaise(const char *str) +{ + printf("Fatal libGiants library error: %s\n", str); + exit(1); +} + + +#endif /* GIANTS_DEBUG */ + +#if GI_STACK_DEBUG + +void *gInitSp; +void *giLowestSp; + +void GI_SET_INIT_SP(void) +{ + gInitSp = GI_GET_SP(); + giLowestSp = NULL; +} + +#ifdef __ppc__ + + +void *GI_GET_SP(void) +{ + void *currsp; + asm("mr %0,r1" : "=r"(currsp) : ); + return currsp; +} + +#else +#ifdef __i386__ +void *GI_GET_SP(void) +{ + register void *sp __asm__("esp"); + return sp; +} +#else +#ifdef __arm__ +void *GI_GET_SP(void) +{ + register void *sp __asm__("r13"); + return sp; +} +#else +#error Need a platform-dependent GI_GET_SP() +#endif +#endif +#endif +#endif /* GI_STACK_DEBUG */ diff --git a/lib/pki/libGiants/giantDebug.h b/lib/pki/libGiants/giantDebug.h new file mode 100644 index 0000000..c64cca1 --- /dev/null +++ b/lib/pki/libGiants/giantDebug.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantDebug.h - debugging support. + * + * Created Aug. 5 2005 by Doug Mitchell. + */ + +#ifndef _GIANT_DEBUG_H_ +#define _GIANT_DEBUG_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GIANTS_DEBUG +/* Should be defined in giantPlatform.h */ +#error Please defgine GIANTS_DEBUG. +#endif + +#if GIANTS_DEBUG + +#include +#include +#include +#include + +#define dbgLog(str) printf(str) + +#define GIASSERT(s) assert(s) + +#else /* GIANTS_DEBUG */ + +#define dbgLog(str) + +#define GIASSERT(s) + +#endif /* GIANTS_DEBUG */ + +#undef NULL +#define NULL ((void *)0) + +#if GIANTS_DEBUG +void GIRaise(const char *str) __attribute((noreturn)); +#else +#define GIRaise(s) +#endif + +/* detect overflow og giant->n[] */ +#define CHECK_GIANT_OFLOW(g) GIASSERT((g)->sign <= (g)->capacity) + +/* stack analysis support */ +#if GI_STACK_DEBUG + +#include + +extern void *gInitSp; +extern void *giLowestSp; + +extern void GI_SET_INIT_SP(void); +extern void *GI_GET_SP(void); + +static inline void GI_CHECK_SP(const char *fcn) +{ + void *currSp = GI_GET_SP(); + if((giLowestSp == NULL) || (currSp < giLowestSp)) { + giLowestSp = currSp; + printf("%s: new min sp %p; stack used %d\n", fcn, + giLowestSp, + gInitSp ? (gInitSp - giLowestSp) : 0); + } +} + +/* this does some fine-grain stack logging regardless of giLowestSp */ +#if GI_STACK_LOG +static inline void GI_LOG_SP(const char *fcn) +{ + void *currSp = GI_GET_SP(); + printf("%s: sp %p; stack used %d\n", + fcn, currSp, + gInitSp ? (gInitSp - currSp) : 0); +} +#else +#define GI_LOG_SP(fcn) +#endif /* GI_STACK_LOG */ +#else /* GI_STACK_DEBUG */ + +#define GI_SET_INIT_SP() +#define GI_GET_SP() +#define GI_CHECK_SP(fcn) +#define GI_LOG_SP(fcn) + +#endif /* GI_STACK_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GIANT_DEBUG_H_ */ diff --git a/lib/pki/libGiants/giantExternal.c b/lib/pki/libGiants/giantExternal.c new file mode 100644 index 0000000..cc1f48b --- /dev/null +++ b/lib/pki/libGiants/giantExternal.c @@ -0,0 +1,191 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantExternal.c - convert between giant integer and external representation + * + * Created Aug. 5 2005 by Doug Mitchell. + */ + +#include +#include +#include +#include + +/* + * Precalculate actual size in bytes needed to serialize a given giant. + */ +gi_uint16 serializeGiantBytes(const giant g) +{ + gi_size numDigits, numZeros, digitByte; + giantDigit digit; + + gtrimSign(g); + numDigits = g->sign; + if(numDigits == 0) { + return 0; + } + /* Count the number of leading 0 bytes in the m.s. digit. */ + numZeros = 0; + digit = g->n[numDigits - 1]; + for(digitByte=0; digitByte>= 8; + if (byte) { + numZeros = 0; + } else { + numZeros++; + } + } + return (numDigits * GIANT_BYTES_PER_DIGIT) - numZeros; +} + +/* + * Serialize, deserialize giants's n[] to/from byte stream. + * First byte of byte stream is the m.s. byte of the resulting giant, + * regardless of the size of giantDigit. + * + * No assumption is made about the alignment of cp. + * + * The numBytes argument indicates the space available on input; + * on return it indicates the actual number of bytes written. + */ +GIReturn serializeGiant( + const giant g, + gi_uint8 *cp, + gi_uint16 *numBytes) /* IN/OUT */ +{ + gi_size digitDex, numDigits, digitByte, totalBytes, bytesLeft; + gi_uint8 *currCp; + giantDigit digit; + + GI_CHECK_SP("serializeGiant"); + if((g == NULL) || (cp == NULL) || (numBytes == NULL)) { + return GR_IllegalArg; + } + totalBytes = serializeGiantBytes(g); + if(totalBytes == 0) { + *numBytes = 0; + return GR_Success; + } + numDigits = g->sign; + if(totalBytes > *numBytes) { + dbgLog("serializeGiant: Insufficient space\n"); + return GR_Overflow; + } + + /* + * Emit bytes starting at the far end of the outgoing byte + * stream, which is the l.s. byte of giant data. In order to prevent + * writing out leading zeros, we special case the m.s. digit. + */ + currCp = cp + totalBytes - 1; + for(digitDex=0; digitDexn[digitDex]; + + for(digitByte=0; digitByte>= 8; + } + } + + /* Handle the m.s. digit, by writing out only as many bytes as are left. + Since we already wrote out numDigits - 1 digits above the answer is: */ + bytesLeft = totalBytes - (numDigits - 1) * GIANT_BYTES_PER_DIGIT; + digit = g->n[digitDex]; + for(digitByte=0; digitByte>= 8; + } + + *numBytes = totalBytes; + return GR_Success; +} + +/* + * Initialize a giant with specified data. Does not have to be + * aligned to giantDigits (as the output of serializeGiant() always + * is). + */ +GIReturn deserializeGiant( + giant g, + const gi_uint8 *cp, + gi_uint16 numBytes) +{ + gi_size numDigits; + giantDigit digit; + giantDigit tempDigit; + gi_size digitDex; + gi_size digitByte; + gi_size dex; + const gi_uint8 *currCp; + + GI_CHECK_SP("deserializeGiant"); + if(g == NULL) { + return GR_IllegalArg; + } + if(numBytes == 0) { + g->sign = 0; + return GR_Success; + } + if(cp == NULL) { + return GR_IllegalArg; + } + + /* + * Trim off leading zeroes, sometimes placed there during DER + * encoding to ensure the number does not appear negative. We + * don't support negative numbers in this module... + */ + + while((*cp == 0) && (numBytes != 0)) { + cp++; + numBytes--; + } + if(numBytes == 0) { + g->sign = 0; + return GR_Success; + } + + numDigits = BYTES_TO_GIANT_DIGITS(numBytes); + if(numDigits > g->capacity) { + return GR_Overflow; + } + + /* + * Start at l.s. byte, at the far end of the byte stream. + */ + digitDex = 0; /* index into g->n[] */ + digit = 0; /* accumulator */ + digitByte = 0; /* byte index into digit */ + currCp = cp + numBytes - 1; + + for(dex=0; dexn[digitDex++] = digit; + + /* reset for next digit */ + digit = 0; + digitByte = 0; + } + } + + /* + * Infer sign/size from non-zero n[] elements + */ + g->sign = numDigits; + gtrimSign(g); + return GR_Success; +} + diff --git a/lib/pki/libGiants/giantExternal.h b/lib/pki/libGiants/giantExternal.h new file mode 100644 index 0000000..780e88d --- /dev/null +++ b/lib/pki/libGiants/giantExternal.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantExternal.h - convert between giant integer and external representation + * + * Created Aug. 5 2005 by Doug Mitchell. + */ + +#ifndef _GIANT_EXTERNAL_H_ +#define _GIANT_EXTERNAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Max size in bytes needed to serialize a giant of given number of digits. + */ +#define MAX_SERIALIZED_GIANT_SIZE(digits) (GIANT_BYTES_PER_DIGIT * digits) + +/* + * Precalculate actual size in bytes needed to serialize a given giant. + */ +gi_uint16 serializeGiantBytes(const giant g); + +/* + * serialize, deserialize giants's n[] to/from byte stream. + * First byte of byte stream is the m.s. byte of the resulting giant, + * regardless of the size of giantDigit. The resulting byte stream + * is suitable for use as the content of a DER-encoded integer. + * + * No assumption is made about the alignment of cp. + * + * The numBytes argument indicates the space available on input; + * on return it indicates the actual number of bytes written. + */ +GIReturn serializeGiant( + const giant g, + gi_uint8 *cp, + gi_uint16 *numBytes); /* IN/OUT */ + +/* + * Initialize a giant with specified data, which may well have come from + * serializeGiant. + */ +GIReturn deserializeGiant( + giant g, + const gi_uint8 *cp, + gi_uint16 numBytes); + +#ifdef __cplusplus +} +#endif + +#endif /* _GIANT_EXTERNAL_H_ */ + diff --git a/lib/pki/libGiants/giantIntegers.c b/lib/pki/libGiants/giantIntegers.c new file mode 100644 index 0000000..3ff4c35 --- /dev/null +++ b/lib/pki/libGiants/giantIntegers.c @@ -0,0 +1,1096 @@ +/* Copyright (c) 1998-2007 Apple Inc. All Rights Reserved. */ + +/* + + giantIntegers.c - library for large-integer arithmetic. + + Revision History + ---------------- + 12/04/98 dmitch/R. Crandall + Fixed a==b bug in addg(). + 10/06/98 ap + Changed to compile with C++. + 13 Apr 98 Fixed shiftright(1) bug in modg_via_recip. + 09 Apr 98 Doug Mitchell at Apple + Major rewrite of core arithmetic routines to make this module + independent of size of giantDigit. + Removed idivg() and radixdiv(). + 20 Jan 98 Doug Mitchell at Apple + Deleted FFT arithmetic; simplified mulg(). + 09 Jan 98 Doug Mitchell and Richard Crandall at Apple + gshiftright() optimization. + 08 Jan 98 Doug Mitchell at Apple + newGiant() returns NULL on malloc failure + 24 Dec 97 Doug Mitchell and Richard Crandall at Apple + New grammarSquare(); optimized modg_via_recip() + 11 Jun 97 Doug Mitchell and Richard Crandall at Apple + Added modg_via_recip(), divg_via_recip(), make_recip() + Added new multiple giant stack mechanism + Fixed potential packing/alignment bug in copyGiant() + Added profiling for borrowGiant(), returnGiant() + Deleted obsolete ifdef'd code + Deleted newgiant() + All calls to borrowGiant() now specify required size (no more + borrowGiant(0) calls) + 08 May 97 Doug Mitchell at Apple + Changed size of giantstruct.n to 1 for Mac build + 05 Feb 97 Doug Mitchell at Apple + newGiant() no longer modifies CurrentMaxShorts or giant stack + Added modg profiling + 01 Feb 97 Doug Mitchell at NeXT + Added iszero() check in gcompg + 17 Jan 97 Richard Crandall, Doug Mitchell at NeXT + Fixed negation bug in gmersennemod() + Fixed n[words-1] == 0 bug in extractbits() + Cleaned up lots of static declarations + 19 Sep 96 Doug Mitchell at NeXT + Fixed --size underflow bug in normal_subg(). + 4 Sep 96 Doug Mitchell at NeXT + Fixed (b +#include +#include +#include +#include + +#ifndef GI_GIANT_LOG2_BITS_PER_DIGIT +#error Please define GI_GIANT_LOG2_BITS_PER_DIGIT +#endif + +#if GIANTS_DEBUG +/* + * counter, acccumulates calls to (giantDigit x giantDigit) multiply. + */ +unsigned numGiantDigitMuls; +unsigned numMulgCommon; +unsigned numGSquareCommon; +#endif + +/* + * Local (heap-allocated) giant support. + */ + +#if !GI_INLINE_SMALL_FUNCS && !GI_MACRO_SMALL_FUNCTIONS + +void initGiant( + giant g, + gi_uint16 capacity, + giantDigit *digits) +{ + GI_CHECK_SP("initGiant"); + g->sign = 0; + g->capacity = capacity; + g->n = digits; +} + +/* call this after declaring a local lgiant and before using it */ +void localGiantAlloc(lgiant *g) +{ + initGiant(&g->g, GIANT_LITTLE_DIGITS, g->_n_); + +} + +/* ditto, for a bgiant */ +extern void localBigGiantAlloc(bgiant *g) +{ + initGiant(&g->g, GIANT_BIG_DIGITS, g->_n_); +} + +/* ditto, for a bgiant */ +void localTriGiantAlloc(tgiant *g) +{ + initGiant(&g->g, GIANT_TRIPLE_DIGITS, g->_n_); +} + +#endif /* !GI_INLINE_SMALL_FUNCS && !GI_MACRO_SMALL_FUNCTIONS */ + +gi_uint16 bitlen(giant n) { + gi_uint16 b = GIANT_BITS_PER_DIGIT; + giantDigit c = 1 << (GIANT_BITS_PER_DIGIT - 1); + giantDigit w; + + GI_CHECK_SP("bitlen"); + if (isZero(n)) { + return(0); + } + w = n->n[n->sign - 1]; + GIASSERT (w != 0); + while((w&c) == 0) { + b--; + c >>= 1; + } + return(GIANT_BITS_PER_DIGIT * (n->sign - 1) + b); +} + +giantDigit bitval(giant n, gi_uint16 pos) +{ + gi_uint16 i = pos >> GI_GIANT_LOG2_BITS_PER_DIGIT; + giantDigit c = 1 << (pos & (GIANT_BITS_PER_DIGIT - 1)); + + GI_CHECK_SP("bitval"); + return((n->n[i]) & c); +} + +gi_uint16 giantNumBytes(giant n) +{ + gi_uint16 bits = bitlen(n); + GI_CHECK_SP("giantNumBytes"); + return (bits + 7) / 8; +} + +/* + * Adjust sign for possible leading (m.s.) zero digits + */ +void gtrimSign(giant g) +{ + int i = g->sign-1; + + GI_CHECK_SP("gtrimSign"); + if(g->sign == 0) { + return; + } + if(g->n[i] != 0) return; + for(--i; i>=0; i--) { + if(g->n[i] != 0) break; + } + g->sign = i+1; +} + +#if !GI_INLINE_SMALL_FUNCS && !GI_MACRO_SMALL_FUNCTIONS +int isone(giant g) { + GI_CHECK_SP("isone"); + return((g->sign == 1) && (g->n[0] == 1)); +} + +int isZero(giant thegiant) { +/* Returns TRUE if thegiant == 0. */ + int count; + int length = thegiant->sign; + giantDigit *numpointer; + + GI_CHECK_SP("isZero"); + if (length) { + numpointer = thegiant->n; + + for(count = 0; countsign, j, bcount=0; + giantDigit dig, c; + + for (j=0;jn[j]; + c = 1; + for (bcount=0;bcountb, respectively */ +{ + gi_uint16 sa = a->sign; + int j; + gi_uint16 sb = b->sign; + giantDigit va; + giantDigit vb; + + if(isZero(a) && isZero(b)) return 0; + if(sa > sb) return(1); + if(sa < sb) return(-1); + + for(j = sa-1; j >= 0; j--) { + va = a->n[j]; vb = b->n[j]; + if (va > vb) return 1; + if (va < vb) return -1; + } + return 0; +} + +/* destgiant becomes equal to srcgiant */ +void gtog(giant srcgiant, giant destgiant) { + + unsigned numbytes; + + GIASSERT(srcgiant != NULL); + GIASSERT(destgiant != NULL); + GIASSERT(srcgiant->sign <= destgiant->capacity); + + GI_CHECK_SP("gtog"); + numbytes = srcgiant->sign * GIANT_BYTES_PER_DIGIT; + Memcpy(destgiant->n, srcgiant->n, numbytes); + destgiant->sign = srcgiant->sign; + CHECK_GIANT_OFLOW(destgiant); +} + +void int_to_giant(gi_uint32 i, giant g) { +/* The giant g becomes set to the integer value i. */ + gi_size dex; + + GI_CHECK_SP("int_to_giant"); + g->sign = 0; + if (i == 0) { + g->n[0] = 0; + return; + } + + if(sizeof(giantDigit) >= sizeof(i)) { + /* guaranteed trivial case */ + g->n[0] = i; + g->sign = 1; + } + else { + /* one loop per digit */ + gi_uint16 scnt = GIANT_BITS_PER_DIGIT; + + for(dex=0; ; dex++) { + g->n[dex] = i & GIANT_DIGIT_MASK; + i >>= scnt; + g->sign++; + if(i == 0) { + break; + } + } + } +} + +/* The integer i becomes set to the giant value g. Returns GR_Overflow if + the giant is too big. */ +GIReturn giant_to_int(giant g, gi_uint32 *i) { + gi_uint16 dex; + gi_uint32 value = 0; + + GI_CHECK_SP("giant_to_int"); + + if (g->sign * GIANT_BYTES_PER_DIGIT > sizeof(*i)) + return GR_Overflow; + + for (dex = g->sign; dex-- > 0;) { + value <<= GIANT_BITS_PER_DIGIT; + value |= g->n[dex]; + } + + *i = value; + return GR_Success; +} + +/*------------- Arithmetic --------------*/ + +/* + * Two implementations of these. Which one is faster depends highly on your + * implementation of giantPortCommon.h and your platform's giantDouble performance. + * If giantDouble arithmetic is fast then use GI_ADDG_INLINE. Otherwise try + * !GI_ADDG_INLINE, measure the two, and pick the best one. + */ +#if GI_ADDG_INLINE + +void iaddg(giantDigit i, giant g) { + gi_size j; + giantDigit carry; + gi_size size = g->sign; + giantDouble tmp; + + if (isZero(g)) { + int_to_giant(i,g); + } + else { + carry = i; + for(j=0; ((jn[j]) + (giantDouble)carry; + carry = tmp >> GIANT_BITS_PER_DIGIT; + g->n[j] = tmp; // implicit truncate to giantDigit + } + if(carry) { + ++g->sign; + CHECK_GIANT_OFLOW(g); + g->n[size] = carry; + } + } +} + +void imulg(giantDigit a, giant g) +{ + giantDigit carry = 0; + gi_size size = g->sign; + gi_size j; + giantDigit *digit = g->n; + giantDouble k; + + GIASSERT((size == 0) || (g->n[size - 1] != 0)); // caller should trim! + GI_CHECK_SP("imulg"); + + for (j=0; j> GIANT_BITS_PER_DIGIT; + *digit = k; // implicit truncation + ++digit; + } + if (carry) + { + *digit = carry; + g->sign = size+1; + return; + } + g->sign = size; + CHECK_GIANT_OFLOW(g); +} + +void +normal_addg( + giant a, + giant b +) +{ + giantDigit carry = 0; + gi_size asize = a->sign, bsize = b->sign; + gi_size j=0; + giantDigit *aptr = a->n, *bptr = b->n; + giantDouble k; + + GI_CHECK_SP("normal_addg"); + if (asize < bsize) + { + for (j=0; j> GIANT_BITS_PER_DIGIT; + *bptr++ = k; + } + for (j=asize; j> GIANT_BITS_PER_DIGIT; + *bptr++ = k; + } + } + else + { + for (j=0; j> GIANT_BITS_PER_DIGIT; + *bptr++ = k; + } + for (j=bsize; j> GIANT_BITS_PER_DIGIT; + *bptr++ = k; + } + } + if (carry) + { + *bptr = 1; ++j; + } + b->sign = j; + CHECK_GIANT_OFLOW(b); +} + +#else /* !GI_ADDG_INLINE */ + +/* + * Use these versions if your giantPortCommon.h is faster than your platform's giantDouble + * arithmetic + */ + +void iaddg(giantDigit i, giant g) { + gi_size j; + giantDigit carry; + gi_size size = g->sign; + + if (isZero(g)) { + int_to_giant(i,g); + } + else { + carry = i; + giantDigit *n = g->n; + for(j=0; ((jn[j] + carry; + carry = tmp >> GIANT_BITS_PER_DIGIT; + g->n[j] = tmp; -- implicit truncate to giantDigit */ + giantDigit sum; + sum = giantAddDigits(*n, carry, &carry); + *n++ = sum; + } + if(carry) { + ++g->sign; + CHECK_GIANT_OFLOW(g); + g->n[size] = carry; + } + } +} + +void imulg(giantDigit a, giant g) +{ + giantDigit carry = 0; + gi_size size = g->sign; + gi_size j; + giantDigit *digit = g->n; + + GI_CHECK_SP("imulg"); + for (j=0; jsign = size+1; + return; + } + g->sign = size; +} + +void +normal_addg( + giant a, + giant b +) +{ + giantDigit carry = 0; + gi_size asize = a->sign, bsize = b->sign; + gi_size j=0; + giantDigit *aptr = a->n, *bptr = b->n; + giantDigit sumHi; + bgiant tmpA; + + GI_CHECK_SP("normal_addg"); + if(a == b) { + /* this routine cannot handle an add in place - make a copy */ + localBigGiantAlloc(&tmpA); + gtog(a, &tmpA.g); + aptr = tmpA.g.n; + } + + if (asize < bsize) + { + for (j=0; jsign = j; + CHECK_GIANT_OFLOW(b); +} + +#endif /* GI_ADDG_INLINE */ + +void normal_subg(giant a, giant b) +/* b := b - a; requires b, a non-negative and b >= a. */ +{ + int j; + int size = b->sign; + giantDigit tmp; + giantDigit borrow1 = 0; + giantDigit borrow2 = 0; + giantDigit *an = a->n; + giantDigit *bn = b->n; + + GI_CHECK_SP("normal_subg"); + GIASSERT(gcompg(b, a) >= 0); /* else we'd come up with a negative result... */ + if(a->sign == 0) { + return; + } + + for (j=0; jsign; ++j) { + if(borrow1 || borrow2) { + tmp = giantSubDigits(bn[j], (giantDigit)1, &borrow1); + } + else { + tmp = bn[j]; + borrow1 = 0; + } + bn[j] = giantSubDigits(tmp, an[j], &borrow2); + } + if(borrow1 || borrow2) { + /* propagate borrow thru remainder of bn[] */ + borrow1 = 1; + for (j=a->sign; j 0) && (b->n[size] == 0)) + ; + b->sign = (b->n[size] == 0)? 0 : size+1; + CHECK_GIANT_OFLOW(b); +} + +/* return the number of leading zeroes in the m.s. digit */ +static gi_uint16 gleadzeroes(giant g) +{ + giantDigit dig = g->n[g->sign - 1]; + gi_uint16 numZeroes = 0; + giantDigit mask = 1 << (GIANT_BITS_PER_DIGIT - 1); + + GIASSERT(!isZero(g)); + + while((dig & mask) == 0) { + numZeroes++; + mask >>= 1; + if(mask == 0) { + /* all zeroes, shouldn't happen */ + GIASSERT(0); + return GIANT_BITS_PER_DIGIT; + } + } + return numZeroes; +} + +/* + * The new gshiftleft costs an extra 280 bytes of code space, but has no measurable + * increase in performance (on G4, gcc 3.3). + */ +#define NEW_SHIFTLEFT 0 + +#if NEW_SHIFTLEFT + + +void gshiftleft(gi_uint16 bits, giant g ) +{ + /* Number of full words/digits to leftshift */ + gi_uint16 wordshift = bits >> GI_GIANT_LOG2_BITS_PER_DIGIT; + /* Number of bits to shift left */ + gi_uint16 leftshift = bits & (GIANT_BITS_PER_DIGIT-1); + gi_uint16 rightshift = GIANT_BITS_PER_DIGIT - leftshift; + gi_uint16 olddigits = g->sign; + /* Leading 0's of high word */ + gi_uint16 lead; + gi_uint16 newdigits; + gi_uint16 j = olddigits - 1; + giantDigit remainder; + gi_uint16 k; + + if (!bits || !olddigits) { + return; + } + lead = gleadzeroes(g); + newdigits = ((bits + (GIANT_BITS_PER_DIGIT-lead) - 1) >> GI_GIANT_LOG2_BITS_PER_DIGIT) + olddigits; + k = newdigits; + + if (!leftshift) { + /* Case 1: Whole word moves */ + Memcpy(g->n + wordshift, g->n, olddigits * GIANT_BYTES_PER_DIGIT); + k = wordshift; + } else if (leftshift <= lead) { + /* Case 2: No bit-wrapping on the high end */ + giantDigit next = g->n[j]; + giantDigit load; + while( j > 0 ) { + load = next; + next = g->n[j-1]; + remainder = next >> rightshift; + g->n[--k] = (load << leftshift) | remainder; + j--; + } + g->n[--k] = next << leftshift; // next == g->n[0] + } else { + /* Case 3: When we left-shift the high bits, they will spill over and use olddigits+wordshift+1 words */ + giantDigit load = g->n[j]; + remainder = 0; + while( j > 0 ) { + g->n[--k] = (load >> rightshift) | remainder; + remainder = load << leftshift; + load = g->n[--j]; + } + g->n[--k] = (load >> rightshift) | remainder; + remainder = load << leftshift; + g->n[--k] = remainder; + } + Bzero(g->n, k * GIANT_BYTES_PER_DIGIT ); // Shift in 0's on the right + g->sign = newdigits; + CHECK_GIANT_OFLOW(g); + return; +} + +#else /* OLD shiftleft */ + +void gshiftleft(gi_uint16 bits, giant g) { +/* shift g left bits bits. Equivalent to g = g*2^bits */ + int rem = bits & (GIANT_BITS_PER_DIGIT - 1); + int crem = GIANT_BITS_PER_DIGIT - rem; + int digits = 1 + (bits >> GI_GIANT_LOG2_BITS_PER_DIGIT); + int size = g->sign; + int j; + int k; + giantDigit carry; + giantDigit dat; + gi_uint16 lead; + gi_uint16 newdigits; + + GI_CHECK_SP("gshiftleft"); + if(!bits) return; + if(!size) return; + + /* rem=0 means we're shifting strictly by digits, no bit shifts. */ + if(rem == 0) { + gshiftwordsleft(digits-1, g); + return; + } + lead = gleadzeroes(g); + newdigits = ((bits + (GIANT_BITS_PER_DIGIT-lead) - 1) >> + GI_GIANT_LOG2_BITS_PER_DIGIT) + size; + + /* + * due to hack of clearing g->n[k] below we can only shift such that + * the result is one digit less than the giant's capacity + */ + //GIASSERT((size+digits) <= (int)g->capacity); + k = size - 1 + digits; // (MSD of result + 1) + carry = 0; + + /* + * normal unaligned case + * FIXME - this writes past g->n[size-1] the first time thru! + */ + for(j=size-1; j>=0; j--) { + dat = g->n[j]; + if(k < newdigits) { + g->n[k--] = (dat >> crem) | carry; + } + else { + k--; + } + carry = (dat << rem); + } + do{ + g->n[k--] = carry; + carry = 0; + } while(k>=0); + + g->sign = newdigits; + CHECK_GIANT_OFLOW(g); +} +#endif /* NEW_SHIFTLEFT */ + +void gshiftright(gi_uint16 bits, giant g) { + /* shift g right bits bits. Equivalent to g = g/2^bits */ + gi_size j; + gi_size size = g->sign; + giantDigit carry; + gi_size digits = bits >> GI_GIANT_LOG2_BITS_PER_DIGIT; + gi_size remain = bits & (GIANT_BITS_PER_DIGIT - 1); + gi_size cremain = GIANT_BITS_PER_DIGIT - remain; + + GI_CHECK_SP("gshiftright"); + if(bits==0) return; + if (digits >= size) { + g->sign = 0; + return; + } + + size -= digits; + + /* Begin OPT: 9 Jan 98 REC. */ + if(remain == 0) { + g->sign = size; + /* FIXME we can do better than this with memmove or pointers... */ + for(j=0; jn[j] = g->n[j+digits]; + } + return; + } + /* End OPT: 9 Jan 98 REC. */ + + for(j=0;jn[j+digits+1]) << cremain; + } + g->n[j] = ((g->n[j+digits]) >> remain ) | carry; + } + if (g->n[size-1] == 0) { + --size; + } + g->sign = size; + CHECK_GIANT_OFLOW(g); +} + +// Right-shift z by s giantDigits +void gshifltwordsright( + gi_uint16 digits, + giant g) +{ + gi_size size = g->sign; + gi_size numBytes; + + GI_CHECK_SP("gshifltwordsright"); + if(digits == 0) { + return; + } + /* not necessary, we won't do anything if it's zero + if(isZero(g)) { + return; + } + */ + if (digits >= size) { + g->sign = 0; + return; + } + + size -= digits; + g->sign = size; + numBytes = size * GIANT_BYTES_PER_DIGIT; + Memcpy(&g->n[0], &g->n[digits], numBytes); +} + +/* shift left by s giantDigits */ +void gshiftwordsleft( + gi_uint16 digits, + giant g) +{ + gi_size dex; + giantDigit *src; + giantDigit *dst; + + GI_CHECK_SP("gshiftwordsleft"); + if(digits == 0) { + return; + } + + /* start copying from m.s. digit */ + src = &g->n[g->sign - 1]; + dst = src + digits; + for(dex=0; dexsign; dex++) { + *dst-- = *src--; + } + Bzero(g->n, digits * GIANT_BYTES_PER_DIGIT); + g->sign += digits; + CHECK_GIANT_OFLOW(g); +} + +/* dest *= a * b */ +void +mulg( + giant a, + giant b) +{ + bgiant dest; + + localBigGiantAlloc(&dest); + GI_CHECK_SP("mulg"); + mulg_common(a, b, &dest.g); + gtog(&dest.g, b); +} + +/* dest *= a * b */ +void +mulg_common( + giant a, + giant b, + giant dest) /* typically a bgiant */ +{ + gi_size i,j; + giantDouble prod1; + giantDouble prod2; + giantDouble carry1=0; + giantDouble carry2=0; + gi_size asize = a->sign, bsize = b->sign; + giantDigit *aptr,*bptr,*destptr; + giantDigit curmul; + giantDigit prevmul; + giantDigit mult1; + giantDigit mult2; + giantDouble prevDigit; + giantDouble prodsum; + + INCR_NUM_MULGS; + GIASSERT(dest->capacity >= (a->sign + b->sign)); + GI_CHECK_SP("mulg_common"); + + if(isZero(a) || isZero(b)) { + dest->sign = 0; + return; + } + Bzero(dest->n, (asize+bsize) * GIANT_BYTES_PER_DIGIT); + + bptr = b->n; + for (i=0; in[0]); + destptr = &(dest->n[i]); + prevDigit = *destptr; + + for (j=0; j> GIANT_BITS_PER_DIGIT; + carry2 = prod2 >> GIANT_BITS_PER_DIGIT; + + prod1 &= GIANT_DIGIT_MASK; + prod2 &= GIANT_DIGIT_MASK; + + prodsum = prod1 + prod2 + prevDigit; + carry1 += prodsum >> GIANT_BITS_PER_DIGIT; + prevDigit = *(destptr+1); + *(destptr++) = prodsum; // implicit truncate + prevmul = curmul; + } + + prod1 = prevDigit + carry1; + prod1 += (giantDouble)prevmul*mult2; + prod1 += carry2; + carry1 = prod1 >> GIANT_BITS_PER_DIGIT; + *(destptr++) = prod1; // implicit truncate + *destptr = carry1; + } + + if (in[0]); + destptr = &(dest->n[i]); + for (j=0; j> GIANT_BITS_PER_DIGIT; + } + *destptr = carry1; + } + } + + bsize += asize; + if (bsize && !carry1) { + --bsize; + } + dest->sign = bsize; +} + +void +grammarSquare ( + giant a) +{ + bgiant dest; + + localBigGiantAlloc(&dest); + GI_CHECK_SP("grammarSquare"); + grammarSquare_common(a, &dest.g); + gtog(&dest.g, a); +} + +void +grammarSquare_common ( + giant a, + giant dest) /* typically a bgiant */ +{ + gi_size i,j; + giantDigit currentDigit; + giantDouble prod; + giantDouble carry=0; + gi_size asize = a->sign; + giantDigit *aptr,*bptr,*destptr; + giantDigit mult; + + INCR_NUM_GSQUARE; + GI_CHECK_SP("grammarSquare_common"); + if(asize == 0) { + /* + * the rest of this routine really is not equipped to handle this, hence + * this trivial special casse + */ + dest->sign = 0; + return; + } + destptr = dest->n; + + aptr = a->n; + + for (i=0; i> GIANT_BITS_PER_DIGIT; + } + + bptr = a->n; + + for (i=0; in[i+1]); + destptr = &(dest->n[2*i+1]); + carry = 0; + + for (j=i+1; j> GIANT_BITS_PER_DIGIT) << 1; + produced = (produced & GIANT_DIGIT_MASK) << 1; + + currentDigit = *destptr; + prod = currentDigit + carry; + prod += produced; + + *(destptr++) = prod; // implicit truncate + carry = prod >> GIANT_BITS_PER_DIGIT; + + carry += carried; + } + + do { + currentDigit = *destptr; + + carried = carry >> GIANT_BITS_PER_DIGIT; + + prod = (carry & GIANT_DIGIT_MASK) + currentDigit; + + *destptr++ = prod; // implicit truncate + + carry = carried + (prod >> GIANT_BITS_PER_DIGIT); + } while (carry); + } + } + + asize += asize; + + currentDigit = dest->n[asize-1]; + currentDigit += carry; + dest->n[asize-1] = currentDigit; + + if (asize && !currentDigit) + --asize; + dest->sign = asize; +} + + +/* + * Clear all of a giant's data fields, for secure erasure of sensitive data. + */ +void clearGiant(giant g) +{ + GI_CHECK_SP("clearGiant"); + Bzero(g->n, g->capacity * GIANT_BYTES_PER_DIGIT); + g->sign = 0; +} + diff --git a/lib/pki/libGiants/giantIntegers.h b/lib/pki/libGiants/giantIntegers.h new file mode 100644 index 0000000..f8f0e73 --- /dev/null +++ b/lib/pki/libGiants/giantIntegers.h @@ -0,0 +1,286 @@ +/* Copyright (c) 1998-2007 Apple Inc. All Rights Reserved. + * + * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT + * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE + * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE + * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER, + * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL + * EXPOSE YOU TO LIABILITY. + *************************************************************************** + * + * giantIntegers.h - large-integer arithmetic library. + */ + +#ifndef _GI_GIANTINTEGERS_H_ +#define _GI_GIANTINTEGERS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* platform-independent digit manipulation macros */ + +#define GIANT_BYTES_PER_DIGIT (sizeof(giantDigit)) +#define GIANT_BITS_PER_DIGIT (8 * GIANT_BYTES_PER_DIGIT) +#define GIANT_DIGIT_MASK ((giantDigit)~0) +#define BYTES_TO_GIANT_DIGITS(x) \ + ((x + GIANT_BYTES_PER_DIGIT - 1) / GIANT_BYTES_PER_DIGIT) + + +/* + * Static giant support; giantstruct->n[] no longer dynamically allocated, but + * hard-coded to the max needed for a particular implementation. This max size + * is a function of the prime size (easy to determine) and the max size of + * giant, in digits relative to the size of the prime, actually needed for the + * math implemented in this library (which is going to be tricky to accurately + * determine). We want to minimize the static size of a giant in order to + * minimize RAM usage. + */ + +#ifndef GI_MAX_PRIME_SIZE_BITS +#error Please #define GI_MAX_PRIME_SIZE_BITS. +#endif + +/* convert that to bytes and digits; these remain fixed */ +#define MAX_PRIME_SIZE_BYTES ((GI_MAX_PRIME_SIZE_BITS + 7) / 8) +#define MAX_PRIME_SIZE_DIGITS BYTES_TO_GIANT_DIGITS(MAX_PRIME_SIZE_BYTES) + +/* + * The number of digits in a minimal giant, requiring only extra space for + * an add. + */ +#define GIANT_LITTLE_DIGITS (MAX_PRIME_SIZE_DIGITS + 1) + +/* + * The number of digits in a max giant, used for mulg and its kin. + */ +#define GIANT_BIG_DIGITS (MAX_PRIME_SIZE_DIGITS * 2) + +/* + * The number of digits in a "triple giant", used sparingly in and + * around make_recip and modg_via_recip only. + * The max observed required size seems to be when doing a mulg on + * two numbers, both of whose signs are s+1. + */ +#define GIANT_TRIPLE_DIGITS ((MAX_PRIME_SIZE_DIGITS * 2) + 2) + +/* Basic giant type with giantDigit array allocated elsewhere */ +typedef struct { + gi_uint16 sign; /* number of giantDigits */ + gi_uint16 capacity; /* largest possible number of giantDigits */ + giantDigit *n; /* n[0] is l.s. digit */ +} giantStruct; + +typedef giantStruct *giant; + +/* + * Giant capable of being allocated on the stack, with capacity + * no greater than GIANT_LITTLE_DIGITS, i.e., a "little giant" or + * lGiant in the SFEE paper. + * + * Use base giantstruct g in any function call requiring a giant. + */ +typedef struct { + giantStruct g; + giantDigit _n_[GIANT_LITTLE_DIGITS]; +} lgiant; + +/* + * "Big giant" "subclass" of standard giant. Use base giantstruct g in + * any function call requiring a giant. + */ +typedef struct { + giantStruct g; + giantDigit _n_[GIANT_BIG_DIGITS]; +} bigGiantStruct; + +typedef bigGiantStruct bgiant; /* for heap allocation */ + +/* + * "Triple giant" "subclass" of standard giant. Used sparingly in and + * around make_recip only. + + */ +typedef struct { + giantStruct g; + giantDigit _n_[GIANT_TRIPLE_DIGITS]; +} tripleGiantStruct; + +typedef tripleGiantStruct tgiant; + +gi_uint16 bitlen(giant n); /* Returns the bit-length n; + * e.g. n=7 returns 3. */ +giantDigit bitval(giant n, gi_uint16 pos); +gi_uint16 giantNumBytes(giant n); +void gtog(giant src, giant dest); /* Copies one giant to another */ +void int_to_giant(gi_uint32 n, giant g); /* Gives a giant an int value */ +GIReturn giant_to_int(giant g, gi_uint32 *i); /* Convent giant to int. */ +gi_uint16 numtrailzeros(giant g); /* # of trailing zero bits in g */ +int gcompg(giant a, giant b); /* Returns 1, 0, -1 as a>b, a=b, asign = 0; + g->capacity = capacity; + g->n = digits; +} + +/* call this after declaring a local lgiant and before using it */ +static GI_INLINE void localGiantAlloc(lgiant *g) +{ + initGiant(&g->g, GIANT_LITTLE_DIGITS, g->_n_); +} + +/* ditto, for a bgiant */ +static GI_INLINE void localBigGiantAlloc(bgiant *g) +{ + initGiant(&g->g, GIANT_BIG_DIGITS, g->_n_); +} + +/* ditto, for a tgiant */ +static GI_INLINE void localTriGiantAlloc(tgiant *g) +{ + initGiant(&g->g, GIANT_TRIPLE_DIGITS, g->_n_); +} + +/* Returns whether g is 1 */ +static GI_INLINE int isone(giant g) +{ + return ((g->sign == 1) && (g->n[0] == 1)); +} + +/* Returns whether g is zero */ +static GI_INLINE int isZero(giant g) +{ + /* we're skipping the !trimmed check here... */ + return (g->sign == 0); +} + +#elif GI_MACRO_SMALL_FUNCTIONS + +#define initGiant(gnt, cap, digs) \ + (gnt)->sign = 0; \ + (gnt)->capacity = cap; \ + (gnt)->n = digs; + +#define localGiantAlloc(lg) initGiant(&((lg)->g), GIANT_LITTLE_DIGITS, (lg)->_n_) +#define localBigGiantAlloc(bg) initGiant(&((bg)->g), GIANT_BIG_DIGITS, (bg)->_n_) +#define localTriGiantAlloc(tg) initGiant(&((tg)->g), GIANT_TRIPLE_DIGITS, (tg)->_n_) + +#define isone(g) (((g)->sign == 1) && ((g)->n[0] == 1)) +#define isZero(g) ((g)->sign == 0) + +#else + +/*** regular C functions ***/ + +/* call this after declaring a local lgiant and before using it */ +extern void localGiantAlloc(lgiant *g); + +/* ditto, for a bgiant */ +extern void localBigGiantAlloc(bgiant *g); + +/* ditto, for a tgiant */ +extern void localTriGiantAlloc(tgiant *g); + +void initGiant( + giant g, + gi_uint16 capacity, + giantDigit *digits); + +int isone(giant g); /* Returns whether g is 1 */ +int isZero(giant g); /* Returns whether g is zero */ + +#endif /* INLINE / MACRO */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GI_GIANTINTEGERS_H_ */ diff --git a/lib/pki/libGiants/giantMemutils.c b/lib/pki/libGiants/giantMemutils.c new file mode 100644 index 0000000..2a2b2b1 --- /dev/null +++ b/lib/pki/libGiants/giantMemutils.c @@ -0,0 +1,48 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantMemutils.c - trivial implementation of memcpy and bzero, for platforms + * without libc versions of those functions. + * + * Created Aug. 8 2005 by Doug Mitchell. + */ + +#include + +#ifndef GI_HAVE_MEMCPY +#error Please define GI_HAVE_MEMCPY. +#endif + +#ifndef GI_HAVE_BZERO +#error Please define GI_HAVE_BZERO. +#endif + +#if !GI_HAVE_MEMCPY + +void *Memcpy(void *dst, const void *src, gi_uint16 len) +{ + gi_size dex; + unsigned char *dstp = (unsigned char *)dst; + const unsigned char *srcp = (const unsigned char *)src; + + for(dex=0; dex +#include + + +#ifndef GI_SMALL_CRT_ENABLE +#error Please define GI_SMALL_CRT_ENABLE. +#endif + +#if GI_SMALL_CRT_ENABLE +/* + * Custom version of the tgiant for GI_SMALL_CRT_ENABLE use. + * Normally a tgiant has 2n+2 digits. The corresponding "small tgiant" + * has n+2 digits. + */ +#define GIANT_SMALL_TRIPLE_DIGITS (MAX_PRIME_SIZE_DIGITS + 2) + +typedef struct { + giantStruct g; + giantDigit _n_[GIANT_SMALL_TRIPLE_DIGITS]; +} smallTGiantStruct; +typedef smallTGiantStruct stgiant; + +static GI_INLINE void localSmallTGiantAlloc(stgiant *g) +{ + initGiant(&g->g, GIANT_SMALL_TRIPLE_DIGITS, g->_n_); +} + +static void rsquareSmall( + giant x, + giant n, + giant recip); +static void rmulgSmall( + giant x, + giant y, + giant n, + giant recip); +static void modg_via_recipSmall( + giant d, + giant r, + giant n); +static void powermodgSmall( + giant base, + giant expo, + giant n, + giant recip, + giant result); +#endif + +/* for lots of grungy low-level debugging */ +#define DEBUG_MODG 0 +#if DEBUG_MODG + +#include +#include + +static void dispGiant( + const char *label, + giant g) +{ + printf("--- %s : ", label); + printGiant(g); +} + +static void dispInt( + const char *label, + unsigned i) +{ + printf("--- %s : %u\n", label, i); +} + +static void dispHeader( + const char *label) +{ + printf("--- %s ---\n", label); +} +static void dispDelim(void) +{ + printf("-------------\n"); +} +#else /* DEBUG_MODG */ +#define dispGiant(l, g) +#define dispInt(l, i) +#define dispDelim() +#define dispHeader(l) +#endif /* DEBUG_MODG */ + +#if GI_MODG_ENABLE + + +/* returns 1 if g has exactly one bit set, else returns zero */ +static int isPowerOfTwo( + giant g) +{ + int foundBit = 0; + gi_uint16 dex; + giantDigit currDigit; + giantDigit mask; + + GI_CHECK_SP("isPowerOfTwo"); + if(isZero(g)) { + return 0; + } + + /* see if m.s. digit has exactly one bit set */ + currDigit = g->n[g->sign - 1]; + /* mask shifts out to zero when done */ + for(mask=0x01; mask != 0; mask <<= 1) { + if(currDigit & mask) { + if(foundBit) { + /* found second bit set: done */ + return 0; + } + else { + /* first '1' bit seen */ + foundBit = 1; + } + } + } + GIASSERT(foundBit != 0); + + /* now we return true iff all the rest of the digits are zero */ + for(dex=0; dexsign-1; dex++) { + if(g->n[dex] != 0) { + return 0; + } + } + return 1; +} + +/* + * Calculate the reciprocal of a demonimator. + */ +void make_recip( + giant d, + giant recip) +/* r becomes the steady-state reciprocal + 2^(2b)/d, where b = bit-length of d-1. */ +{ + int b; + + tgiant tmp1; + bgiant tmp2; + tgiant tmp3; + + GI_CHECK_SP("make_recip (1)"); + if (isZero(d)) { + GIASSERT(0); + return; + } + if(isPowerOfTwo(d)) { + gtog(d, recip); + return; + } + + localTriGiantAlloc(&tmp1); + localBigGiantAlloc(&tmp2); + localTriGiantAlloc(&tmp3); + //localGiantAlloc(&tmpRecip); + + GI_CHECK_SP("make_recip (2)"); + + b = bitlen(d); + int_to_giant(1, recip); + if((b & (GIANT_BITS_PER_DIGIT - 1)) == 0) { + /* digit-aligned */ + gshiftwordsleft(b >> GI_GIANT_LOG2_BITS_PER_DIGIT, recip); + } + else { + gshiftleft(b, recip); + } + gtog(recip, &tmp2.g); + + while(1) { + grammarSquare_common(recip, &tmp1.g); + gshiftright(b, &tmp1.g); + mulg_common(d, &tmp1.g, &tmp3.g); + gshiftright(b, &tmp3.g); + addg(recip, recip); + normal_subg(&tmp3.g, recip); + if(gcompg(recip, &tmp2.g) <= 0) { + break; + } + gtog(recip, &tmp2.g); + } + mulg_common(recip, d, &tmp1.g); + int_to_giant(1, &tmp2.g); + while(bitlen(&tmp1.g) > (2 * b)) { + normal_subg(&tmp2.g, recip); + normal_subg(d, &tmp1.g); + } + CHECK_GIANT_OFLOW(recip); +} + +#define MODG_CTR_LIMIT 3 + +/* + * Optimized modg. + * n := n % d, where r is the precalculated steady-state reciprocal of d. + */ +void modg_via_recip( + giant d, + giant r, + giant n) +{ + int s = bitlen(r)-1; + bgiant tmp1; + tgiant tmp2; + + //dispGiant("d", d); + //dispGiant("r", r); + //dispGiant("n", n); + + GI_CHECK_SP("modg_via_recip(1)"); + GIASSERT(!isZero(r)); + + if(s == 0) { + int_to_giant(0, n); + return; + } + if(gcompg(n, d) < 0) { + /* this mod is a nop: done. */ + return; + } + localBigGiantAlloc(&tmp1); + localTriGiantAlloc(&tmp2); + + do { + unsigned ct = 0; + gtog(n, &tmp1.g); + gshiftright(s-1, &tmp1.g); + + mulg_common(r, &tmp1.g, &tmp2.g); + gshiftright(s+1, &tmp2.g); + mulg_common(d, &tmp2.g, &tmp1.g); + normal_subg(&tmp1.g, n); + + while(++ct <= MODG_CTR_LIMIT) { + if(gcompg(n,d) >= 0) { + normal_subg(d,n); + } + else { + return; + } + } + } while(1); +} + +/* Both n and div are written by this function, with new values: + n := n mod d, + div := floor(n/d). + */ +void divmodg_via_recip( + giant d, + giant r, + giant n, + giant dv) +{ + int s = bitlen(r)-1; + tgiant tmp1; + tgiant tmp2; + + GI_CHECK_SP("divmodg_via_recip(1)"); + GIASSERT(!isZero(r)); + + if(s == 0) { + int_to_giant(0, n); + gtog(n, dv); + return; + } + int_to_giant(0, dv); + if(gcompg(n, d) < 0) { + /* this mod is a nop: done. */ + return; + } + localTriGiantAlloc(&tmp1); + localTriGiantAlloc(&tmp2); + GI_CHECK_SP("divmodg_via_recip(2)"); + + do { + unsigned ct = 0; + gtog(n, &tmp1.g); + gshiftright(s-1, &tmp1.g); + mulg_common(r, &tmp1.g, &tmp2.g); + gshiftright(s+1, &tmp2.g); + mulg_common(d, &tmp2.g, &tmp1.g); + normal_subg(&tmp1.g, n); + addg(&tmp2.g, dv); + while(++ct <= 3) { + if(gcompg(n,d) >= 0) { + normal_subg(d,n); + iaddg(1, dv); + } + else { + return; + } + } + } while(1); +} + +/* x := (x^2) mod n with known reciprocal of n */ +void rsquare( + giant x, + giant n, + giant recip) +{ + bgiant sq; + + GI_CHECK_SP("rsquare(1)"); + localBigGiantAlloc(&sq); + GI_CHECK_SP("rsquare(2)"); + grammarSquare_common(x, &sq.g); + modg_via_recip(n, recip, &sq.g); + gtog(&sq.g, x); +} + +/* y := (x * y) mod n with known reciprocal of n */ +void rmulg( + giant x, + giant y, + giant n, + giant recip) +{ + bgiant prod; + + GI_CHECK_SP("rmulg"); + localBigGiantAlloc(&prod); + mulg_common(x, y, &prod.g); + modg_via_recip(n, recip, &prod.g); + gtog(&prod.g, y); +} + +/* + * result becomes base^expo (mod n). + * Caller knows and gives us reciprocal of n as recip. + * base and result can share the same giant. + */ +void powermodg( + giant base, + giant expo, + giant n, + giant recip, + giant result) +{ + int len, pos; + lgiant bmod; /* saved base mod n */ + + GI_CHECK_SP("powermodg"); + GI_LOG_SP("top of powermodg"); + if(isZero(expo)) { + int_to_giant(1, result); + return; + } + + localGiantAlloc(&bmod); + + if(base != result) { + gtog(base, result); + } + if(gcompg(result, n) >= 0) { + modg_via_recip(n, recip, result); + } + gtog(result, &bmod.g); + + len = bitlen(expo); + if(len == 1) { + return; + } + for(pos = len-2; pos >= 0; pos--) { + rsquare(result, n, recip); // New ring-square. + if (bitval(expo, pos)) { + rmulg(&bmod.g, result, n, recip); + } + } + return; +} + +void modg( + giant d, + giant n) +/* n becomes n%d. n is arbitrary, but the denominator d must be positive! */ +{ + lgiant recip; + + GI_CHECK_SP("modg"); + localGiantAlloc(&recip); + make_recip(d, &recip.g); + modg_via_recip(d, &recip.g, n); +} + +/* + * power/mod using Chinese Remainder Theorem. + * + * result becomes base^d (mod n). + * + * ...but we don't know or need d or n. What we have are + * + * p, q such that n = p*q + * reciprocals of p, q + * dp = d mod (p-1) + * dq = d mod (q-1) + * qinv = q^(1) mod p + */ +void powermodCRT( + giant x, /* base (plaintext/ciphertext) */ + giant p, /* p*q = n */ + giant pRecip, /* reciprocal of p */ + giant q, + giant qRecip, /* reciprocal of p */ + giant dp, /* d mod (p-1) */ + giant dq, /* d mod (q-1) */ + giant qinv, + giant sq, /* scratch, provided and init'd by caller */ + giant result) /* OUTPUT */ +{ + bgiant sp; + int m; + + GI_CHECK_SP("powermodCRT"); + localBigGiantAlloc(&sp); + GIASSERT(sq->capacity >= GIANT_LITTLE_DIGITS); + + /* + * sp := x^dp mod p; + * sq := x^dq mod q; + */ + #if GI_SMALL_CRT_ENABLE + powermodgSmall(x, dp, p, pRecip, &sp.g); + powermodgSmall(x, dq, q, qRecip, sq); + #else + powermodg(x, dp, p, pRecip, &sp.g); + powermodg(x, dq, q, qRecip, sq); + #endif + + /* + * m = gcompg(sp, sq); + * if(m > = 0) + * result = sp-sq; + * else + * result = sq-sp; // Note unsigned subtract always; + */ + m = gcompg(&sp.g, sq); + if(m >= 0) { + gtog(&sp.g, result); + normal_subg(sq, result); + } + else { + gtog(sq, result); + normal_subg(&sp.g, result); + } + + /* + * result = (qinv * result) mod p; + * done with sp, use as scratch now... + */ + mulg_common(result, qinv, &sp.g); + modg_via_recip(p, pRecip, &sp.g); + gtog(&sp.g, result); + + /* + * if( ! isZero(result)) if(m < 0) result = p - result; + */ + if(!isZero(result)) { + if(m < 0) { + gtog(p, &sp.g); + normal_subg(result, &sp.g); + gtog(&sp.g, result); + } + } + + /* + * result *= q; + * result += sq; + */ + mulg_common(result, q, &sp.g); + addg(sq, &sp.g); + gtog(&sp.g, result); +} + +#endif /* GI_MODG_ENABLE */ + +#if GI_INVERSE_MOD_ENABLE + +/* + * Given x, y coprime with x > 0, y > 1, this routine forces + * x := x^(-1) mod modulus. + */ +void ginverseMod( + giant modulus, + giant recip, /* reciprocal of modulus */ + giant x) /* IN/OUT */ +{ + lgiant u, v, a, q, tmp; + unsigned int k = 0; + lgiant uRecip; + + GI_CHECK_SP("ginverseMod"); + localGiantAlloc(&u); + localGiantAlloc(&v); + localGiantAlloc(&a); + localGiantAlloc(&q); + localGiantAlloc(&tmp); + localGiantAlloc(&uRecip); + + dispHeader("ginverseMod top"); + dispGiant("x", x); + dispGiant("modulus", modulus); + dispGiant("recip", recip); + + /* + * 1) (u, v, a, x, k) = (x mod modulus, modulus, 0, 1, 0); + */ + gtog(x, &u.g); + modg_via_recip(modulus, recip, &u.g); + gtog(modulus, &v.g); + /* a is already zero */ + int_to_giant(1, x); + + dispHeader("ginverseMod before loop"); + dispGiant("x", x); + dispGiant("u", &u.g); + dispGiant("v", &v.g); + dispGiant("a", &a.g); + dispInt("k", k); + + /* + * 2) while(u > 1) { + * q = v div u; + * (u, v, a, x, k) = (v mod u, u, x, (a + q*x) mod y, k + 1); + * } + */ + while(!isZero(&u.g) && !isone(&u.g)) { + /* (q,u) := (v div u, v mod u */ + make_recip(&u.g, &uRecip.g); + gtog(&u.g, &tmp.g); /* for a const modulus in divmodg_via_recip() */ + gtog(&v.g, &u.g); /* divisor, then result of mod */ + divmodg_via_recip(&tmp.g, &uRecip.g, &u.g, &q.g); + + /* v := old u */ + gtog(&tmp.g, &v.g); + + /* intermediate: *old* x */ + gtog(x, &tmp.g); + + /* calc new x := a + q*x mod y */ + rmulg(&q.g, x, modulus, recip); + addg(&a.g, x); + modg_via_recip(modulus, recip, x); /* just in case */ + + /* new a := old x */ + gtog(&tmp.g, &a.g); + k++; + + dispDelim(); + dispGiant("x", x); + dispGiant("q", &q.g); + dispGiant("u", &u.g); + dispGiant("v", &v.g); + dispGiant("a", &a.g); + dispInt("k", k); + } + + /* + * 3) if(k odd) x = y - x; // Unsigned (normal_subg) subtract. + */ + if(k & 1) { + gtog(modulus, &u.g); + normal_subg(x, &u.g); + gtog(&u.g, x); + } +} + +#endif /* GI_INVERSE_MOD_ENABLE */ + +#if GI_SMALL_CRT_ENABLE + +/* + * Optional "small giant" routines used only by powermodCRT when + * performing its initial powermodg operations with p and q as the + * modulus; p and q are half the size of MAX_PRIME_SIZE_DIGITS, so + * we implement the following functions with corresponding small + * local giants. + * On PPC, this saves 384 bytes of stack space, at the cost of + * 1407 extra bytes of code. + */ +static void rsquareSmall( + giant x, + giant n, + giant recip) +{ + stgiant sq; + + GI_CHECK_SP("rsquareSmall(1)"); + localSmallTGiantAlloc(&sq); + GI_CHECK_SP("rsquareSmall(2)"); + grammarSquare_common(x, &sq.g); + modg_via_recipSmall(n, recip, &sq.g); + gtog(&sq.g, x); +} + +/* y := (x * y) mod n with known reciprocal of n */ +static void rmulgSmall( + giant x, + giant y, + giant n, + giant recip) +{ + stgiant prod; + + GI_CHECK_SP("rmulgSmall"); + localSmallTGiantAlloc(&prod); + mulg_common(x, y, &prod.g); + modg_via_recipSmall(n, recip, &prod.g); + gtog(&prod.g, y); +} + +/* + * Optimized modg. + * n := n % d, where r is the precalculated steady-state reciprocal of d. + */ +static void modg_via_recipSmall( + giant d, + giant r, + giant n) +{ + int s = bitlen(r)-1; + stgiant tmp1; + stgiant tmp2; + + GI_CHECK_SP("modg_via_recipSmall(1)"); + GIASSERT(!isZero(r)); + + if(s == 0) { + int_to_giant(0, n); + return; + } + if(gcompg(n, d) < 0) { + /* this mod is a nop: done. */ + return; + } + localSmallTGiantAlloc(&tmp1); + localSmallTGiantAlloc(&tmp2); + + do { + unsigned ct = 0; + gtog(n, &tmp1.g); + gshiftright(s-1, &tmp1.g); + + mulg_common(r, &tmp1.g, &tmp2.g); + gshiftright(s+1, &tmp2.g); + mulg_common(d, &tmp2.g, &tmp1.g); + normal_subg(&tmp1.g, n); + + while(++ct <= MODG_CTR_LIMIT) { + if(gcompg(n,d) >= 0) { + normal_subg(d,n); + } + else { + return; + } + } + } while(1); +} + +/* + * result becomes base^expo (mod n). + * Caller knows and gives us reciprocal of n as recip. + * base and result can share the same giant. + * + * This is only used by powermodCRT, which conveniently hands us + * two initialized scratch giants, one bgiant and one stgiant + * so neither we nor any of our callers have to allocate any + * local giants. + */ +static void powermodgSmall( + giant base, + giant expo, + giant n, + giant recip, + giant result) +{ + int len, pos; + lgiant bmod; /* saved base mod n */ + + GI_CHECK_SP("powermodgSmall"); + GI_LOG_SP("top of powermodgSmall"); + if(isZero(expo)) { + int_to_giant(1, result); + return; + } + + localGiantAlloc(&bmod); + + if(base != result) { + gtog(base, result); + } + if(gcompg(result, n) >= 0) { + modg_via_recipSmall(n, recip, result); + } + gtog(result, &bmod.g); + + len = bitlen(expo); + if(len == 1) { + return; + } + for(pos = len-2; pos >= 0; pos--) { + rsquareSmall(result, n, recip); // New ring-square. + if (bitval(expo, pos)) { + rmulgSmall(&bmod.g, result, n, recip); + } + } + return; +} + +#endif /* GI_SMALL_CRT_ENABLE */ diff --git a/lib/pki/libGiants/giantMod.h b/lib/pki/libGiants/giantMod.h new file mode 100644 index 0000000..791138d --- /dev/null +++ b/lib/pki/libGiants/giantMod.h @@ -0,0 +1,124 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantMod.h - modular arithmetic function declarations. + * + * Created Nov. 29 2005 by Doug Mitchell. + */ + +#ifndef _GIANT_MOD_H_ +#define _GIANT_MOD_H_ + +#include + +/* this must be defined in giantPlatform.h */ +#ifndef GI_MODG_ENABLE +#error Please define GI_MODG_ENABLE one way or the other. +#endif + +#if GI_MODG_ENABLE + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Calculate the reciprocal of a demonimator to be used in + * modg_via_recip(). + */ +void make_recip(giant d, giant recip); + +/* + * n := n % d, where r is the precalculated + * steady-state reciprocal of d. + */ +void modg_via_recip( + giant d, + giant r, + giant n); + +/* Both n and div are written by this function, with new values: + n := n mod d, + div := floor(n/d). + */ +void divmodg_via_recip( + giant d, + giant r, + giant n, + giant dv); + +/* x := (x^2) mod n with known reciprocal of n */ +void rsquare( + giant x, + giant n, + giant recip); + +/* y := (x * y) mod n with known reciprocal of n */ +void rmulg( + giant x, + giant y, + giant n, + giant recip); + +/* + * result becomes base^expo (mod n). + * Caller knows and gives us reciprocal of n as recip. + * base and result can share the same giant. + */ +void powermodg( + giant base, + giant expo, + giant n, + giant recip, + giant result); + +/* n becomes n%d. n is arbitrary, but the denominator d must be positive! */ +void modg(giant d,giant n); + +/* + * power/mod using Chinese Remainder Theorem. + * + * result becomes base^d (mod n). + * + * ...but we don't know or need d or n. What we have are + * + * p, q such that n = p*q + * reciprocals of p, q + * dp = d mod (p-1) + * dq = d mod (q-1) + * qinv = q^(1) mod p + * + * Plus one scratch giant, initialized by caller with the capacity at + * least as big as an lgiant. + * + * The base and result arguments can be identical, i.e., an in/out + * parameter. + */ +void powermodCRT( + giant base, /* base (plaintext/ciphertext) */ + giant p, /* p*q = n */ + giant pRecip, /* reciprocal of p */ + giant q, + giant qRecip, /* reciprocal of q */ + giant dp, /* d mod (p-1) */ + giant dq, /* d mod (q-1) */ + giant qinv, + giant scratchLgiant, + giant result); /* OUTPUT */ + +/* + * Given x, y coprime with x > 0, y > 1, this routine forces + * x := x^(-1) mod y. + */ +void ginverseMod( + giant modulus, + giant recip, /* reciprocal of modulus */ + giant x); /* IN/OUT */ + +#ifdef __cplusplus +} +#endif + +#endif /* GI_MODG_ENABLE */ + +#endif /* _GIANT_MOD_H_ */ diff --git a/lib/pki/libGiants/giantPlatform.h b/lib/pki/libGiants/giantPlatform.h new file mode 100644 index 0000000..93abe8b --- /dev/null +++ b/lib/pki/libGiants/giantPlatform.h @@ -0,0 +1,370 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantPlatform.h - platform specific type and routines, must be ported to + * each platform on which this library runs. + */ + +#ifndef _GIANT_PLATFORM_H_ +#define _GIANT_PLATFORM_H_ + +/* + * This is defined true only for development and testing. + * For production code, leave it zero and define your platform + * in this file. + */ + +#define GI_PLATFORM_EMULATE 1 +#if GI_PLATFORM_EMULATE +#include +#else + +/* be sure to #define NDEBUG for deployment builds */ +#define NDEBUG +#ifdef NDEBUG +#define GIANTS_DEBUG 0 +#else +#define GIANTS_DEBUG 1 +#endif + +/* + * Machine-dependent word-size related integer types. + * + * The following integer types must be defined in this module: + * + * gi_uint8 -- unsigned 8 bit (typically "unsigned char") + * gi_uint16 -- unsigned 16 bit, platform/compiler dependent + * gi_uint32 -- unsigned 32-bit integer, platform/compiler dependent + * gi_size -- unsigned, at *least* 16 bits. Could be larger if that's + * more efficient for the platform. For example on a 32-bit + * processor this should be an unsigned 32 bit integer. + * Generally used inside of functions as counters, indices, + * etc. Function parameters which must be portable to + * small processors are expressed as gi_uint16 or + * gi_uint32. + * giantDigit -- see below + * giantDouble -- two giant digits, the result of a giantDigit multiply + * + * giantDigit is the largest native word size for which + * a (giantDigit x giantDigit) hardware multiply (into a giantDouble, + * somehow) is available. This is a crucial data type; the large integer + * artithmetic package uses data types called 'giants' which are mainly + * comprised of arrays of giantDigits. Most of the CPU cycles spent in this + * library are involved in performing arithmetic on these arrays of + * giantDigits. + * + * Our assumption is that the following all always fit into a gi_uint16: + * + * number of bits per giant digit + * number of giant digits in the max base prime in this module + * number of bits in the max base prime in this module + * + * Note we also assume the existence of a 16-bit integer type; arithmetic + * involving this type doesn't have to be particularly fast but it has to be + * usable as a function argument and in simple assignments. Thus 8-bit + * platforms can run this code as long as there is a C type which compiles + * to 16 bits. + * + * These preprocessor symbols also need to be defined for each platform: + * + * GI_GIANT_LOG2_BITS_PER_DIGIT + * The log to base 2 of the size of giantDigit. There + * is no straightforward way for the C preprocessor to figure this one + * out so you have to specify it. For 16-bit giantDigits the value of + * this symbol is 4; for 32-bit giantDigits the value is 5. + * + * GI_GIANT_PORT_INLINE + * 1 : we don't have a platform-specific giant arithmetic module; use the + * inlines in giantPort_Generic.h + * 0 : we have a platform-specific giant arithmetic module + * + * GI_INLINE_SMALL_FUNCS + * 1 : Use 'static inline' for a select set of small (1-3 line) functions. + * Trade more code for faster runtime and less stack usage. The specific + * effect of this flag wil be nighly dependent on your compiler; in some + * cases you might even see smaller code size when this flag is true. + * 0 : Disable this feature, use actual C functions. + * + * GI_MACRO_SMALL_FUNCTIONS + * + * Like GI_INLINE_SMALL_FUNCS, except causes small functions to be implemented + * as macros. For platforms that don't support the 'inline' keyword. Mutually + * exclusive with GI_INLINE_SMALL_FUNCS. + * 1 : Use #defined macros for the functions in question. + * 0 : Disable; use actual C functions. + * + * + * GI_SMALL_CRT_ENABLE + * + * This flag involves a tradeoff between code size and stack usage in the + * giantMod.c module. Setting this flag true increases code size and + * decreases stack usage. + * + * On a G4, the tradeoff is that setting this flag saves 384 bytes of + * stack space, at the cost of 1407 extra bytes of code. + * + * Note: this flag has no effect if GI_MODG_ENABLE is 0. + * + * 0 : disable the small-CRT functions to save code space. + * 1 : enable to the small-CRT functions to save stack space. + * + * GI_HAVE_MEMCPY + * 1 : This platform has memcpy() and we want to use it as the implementation + * of Memcpy() + * 0 : We've provided our own Memcpy() + * + * GI_HAVE_BZERO + * 1 : This platform has bzero() and we want to use it as the implementation + * of Bzero() + * 0 : We've provided our own Bzero() + * + * GI_INLINE + * Used where the 'inline' keyword would normally be used. #define to 'inline' + * if your compiler provides this functionality, else #define it to nothing or + * some other compiler-specific value. + * + * GI_MODG_ENABLE + * + * When nonzero, enables the modular arithmetic functions found in + * giantMod.[ch]. Some applications such as SFEE do not need these functions. + * Other applications, like RSA and BBS, do in fact need them. + * + * 1 : Enable compilation of giantMod.[ch] + * 0 : Disable compilation of giantMod.[ch] + * + * GI_PRIME_TEST_ENABLE + * + * When nonzero, enables the logic in giantPrime.c used to determine + * whether a given giant is prime. Used in RSA key generation. + * + * 1 : Enable compilation of giantPrime.[ch] + * 0 : Disable compilation of giantPrime.[ch] + * + * GI_INVERSE_MOD_ENABLE + * + * When nonzero, enables the ginverseMod() function in giantMod.[ch]. Used + * for RSA key generation and for BBS. + * + * 1 : Enable compilation of ginverseMod() + * 0 : Disable compilation of ginverseMod() + * + * + * Optimization flags + * ------------------ + * + * The following symbols have to be #defined to 0 or 1. See the comments below + * for detailed descritpions of the effects of these flags. + * + * GI_GSQUARE_ENABLE + * GI_OPTIMIZED_MULG + * GI_ADDG_INLINE + */ + +/* These define a 16-bit word size emulated on Mac OS X */ +#include + +typedef unsigned char gi_uint8; +typedef uint16_t gi_uint16; +typedef uint32_t gi_uint32; +typedef uint16_t gi_size; +typedef uint16_t giantDigit; +typedef uint32_t giantDouble; /* two giant digits */ + +#define GI_GIANT_LOG2_BITS_PER_DIGIT 4 + +/* + * Maximum size in bits of base integer in this package. For BBS, this is the + * size of the public 'n' parameter. For asymmetric encryption, it's the + * size of the base prime. + * + * Altering this has no effect on performance, only on memory usage. + * Specifically it affects the amount of stack space used (since all + * giantIntegers in this package are allocated on the stack). + */ +#define GI_MAX_PRIME_SIZE_BITS 4096 + + +/**** + **** Optimization flags + ****/ + +/* + * Sample measurements of the effects of these flags were + * taken on an 800 MHz G4, with a 16 bit giantDigit, running + * the bbsProtocol test with 1024 bit 'n' and 10000 iterations. + * Your mileage will certainly vary; the only way to know for + * sure which is the best value for a particular optimizatiaon + * flag is to measure a real-world case on your platform and then + * make the size-vs.-speed tradeoff decision yourself. + * + * However, in the meantime, all of the functionality in this + * library does work correctly for any value of all of these + * flags. + */ + +/* + * GI_GSQUARE_ENABLE + * + * Set nonzero to disable optimized grammarSquare(). + * Setting nonzero increases code size and increases performance. + * + * Setting this true has the following effects (on 800 MHz G4): + * + * -- adds 384 bytes of code + * -- 7% speedup on private side + * -- 7% speedup on public side + */ +#define GI_GSQUARE_ENABLE 1 + +/* + * GI_OPTIMIZED_MULG + * + * Use old unoptimized, but smaller, mulg if this is zero. + * Setting nonzero increases code size and increases performance. + * + * Setting this true has the following effects (on 800 MHz G4): + * + * -- adds 168 bytes of code + * -- 20% speedup on private side + * -- 18% speedup on public side + */ + +#define GI_OPTIMIZED_MULG 1 + +/* + * GI_ADDG_INLINE + * + * There are two implementations of some core arithmetic routines. + * Which one is faster depends highly on your implementation of the + * routines declared in giantPortCommon.h and implemented in either + * giantPort_Generic.h (as static inlines) or elsewhere (in C or + * possibly assembly language). Performance also depends on your + * platform's giantDouble performance. If giantDouble arithmetic + * is fast then use GI_ADDG_INLINE. Otherwise try !GI_ADDG_INLINE, + * measure the two, and pick the best one. + * + * Setting this false has the following effects (on 800 MHz G4): + * + * -- increases code size 192 bytes + * -- elliptic operations (SFEE) slow down by 50-100% + */ +#define GI_ADDG_INLINE 1 + +/* + * GI_GIANT_PORT_INLINE + * + * true : we don't have a platform-specific giant arithmetic module + * false : we do + * + * If GI_ADDG_INLINE is true, setting this true saves a small amount + * of code with no measurable performance impact. + * + * If GI_ADDG_INLINE is false, setting GI_GIANT_PORT_INLINE to + * true has the following effects: + * + * -- adds 168 bytes of code + * -- 2% speedup on private side + * -- 1% speedup on public side + */ +#define GI_GIANT_PORT_INLINE 0 + +/* + * GI_INLINE_SMALL_FUNCS + * + * When true, uses macros instead of a small number of small functions. + * This is a tradeff of speed and less stack usage vs. code size. + */ +#define GI_INLINE_SMALL_FUNCS 1 + +/* + * GI_MACRO_SMALL_FUNCTIONS + * + * Like GI_INLINE_SMALL_FUNCS, except causes small functions to be implemented + * as macros. For platforms that don't support the 'inline' keyword. + */ +#define GI_MACRO_SMALL_FUNCTIONS 0 + +/* + * GI_SMALL_CRT_ENABLE + * + * This flag involves a tradeoff between code size and stack usage in the + * giantMod.c module. Setting this flag true increases code size and + * decreases stack usage. + * + * On a G4, the tradeoff is that setting this flag saves 384 bytes of + * stack space, at the cost of 1407 extra bytes of code. + * + * Note: this flag has no effect if GI_MODG_ENABLE is 0. + */ +#define GI_SMALL_CRT_ENABLE 1 + + +/**** + **** Library implementation flags + ****/ + +/* standard library functions available here */ +#define GI_HAVE_MEMCPY 1 +#define GI_HAVE_BZERO 1 + +/* enable/disable modular arithmetic */ +#define GI_MODG_ENABLE 1 + +/* enable/disable giantPrime.[ch] - requires GI_MODG_ENABLE! */ +#define GI_PRIME_TEST_ENABLE 1 + +/* enable/disable ginverseMod() */ +#define GI_INVERSE_MOD_ENABLE 1 + +#endif /* GI_PLATFORM_EMULATE */ + +#pragma mark --- Declarations of functions with platform-specific implementations --- + +/* + * You should not have to modify the rest of this file. + */ + +#if GI_HAVE_MEMCPY || GI_HAVE_BZERO +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This platform supports inline keywords. + */ +#define GI_INLINE inline + +#if GI_HAVE_MEMCPY + +#define Memcpy(d, s, l) memcpy(d, s, l) + +#else /* !GI_HAVE_MEMCPY */ + +/* + * memcpy() equivalent + */ +extern void *Memcpy(void *dst, const void *src, gi_uint16 len); + +#endif /* GI_HAVE_MEMCPY */ + +#if GI_HAVE_BZERO + +#define Bzero(b, l) bzero(b, l) + +#else /* !GI_HAVE_BZERO */ + +/* + * bzero() equivalent + */ +extern void Bzero(void *b, gi_uint16 len); + +#endif /* GI_HAVE_BZERO */ + +#ifdef __cplusplus +} +#endif + +#endif /*_GIANT_PLATFORM_H_*/ diff --git a/lib/pki/libGiants/giantPlatformEmulation.h b/lib/pki/libGiants/giantPlatformEmulation.h new file mode 100644 index 0000000..957cd62 --- /dev/null +++ b/lib/pki/libGiants/giantPlatformEmulation.h @@ -0,0 +1,181 @@ +/* Copyright (c) 2004,2006-2007 Apple Inc. All Rights Reserved. + * + * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT + * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE + * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE + * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER, + * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL + * EXPOSE YOU TO LIABILITY. + *************************************************************************** + * + * giantPlatformEmulation.h - #defines for platform emulation. + * + * This file is NOT used in production code. + */ + +#ifndef _GIANT_PLATFORM_EMULATION_H_ +#define _GIANT_PLATFORM_EMULATION_H_ + +#define NDEBUG +#ifdef NDEBUG +#define GIANTS_DEBUG 0 +#else +#define GIANTS_DEBUG 1 +#endif + +/* + * Emulation targets: + * + * #define _FEE_CUSTOM_XXX_CONFIG_ to 1 and fill in these blanks if + * you want to generate a test configuration which is not strictly related + * to the machine you're building for - e.g., build a 16-bit giant package on PPC. + */ + +/* this one for emulating 16-bit CPU on Mac OS X / PPC */ +#define _FEE_CUSTOM_16_CONFIG_ 1 +/* this one for emulating 8-bit CPU on Mac OS X / PPC */ +#define _FEE_CUSTOM_8_CONFIG_ 0 + +#if _FEE_CUSTOM_16_CONFIG_ + +/* 16-bit word size emulated on Mac OS X */ +#include + +typedef unsigned char gi_uint8; +typedef uint16_t gi_uint16; +typedef uint32_t gi_uint32; +typedef uint16_t gi_size; +typedef uint16_t giantDigit; +typedef uint32_t giantDouble; /* two giant digits */ + +#define GI_GIANT_LOG2_BITS_PER_DIGIT 4 + +#elif _FEE_CUSTOM_8_CONFIG_ + +/* 8-bit word size emulated on Mac OS X */ +#include + +typedef unsigned char gi_uint8; +typedef uint16_t gi_uint16; +typedef uint32_t gi_uint32; +typedef uint16_t gi_size; +typedef uint8_t giantDigit; +typedef uint16_t giantDouble; /* two giant digits */ + +#define GI_GIANT_LOG2_BITS_PER_DIGIT 3 + +#elif defined(__APPLE__) && defined(__ppc__) + +/* + * Mac OS X on 32-bit PPC + */ +#include + +typedef unsigned char gi_uint8; +typedef uint16_t gi_uint16; +typedef uint32_t gi_uint32; +typedef uint32_t gi_size; +typedef uint32_t giantDigit; +typedef uint64_t giantDouble; /* two giant digits */ + +#define GI_GIANT_LOG2_BITS_PER_DIGIT 5 + +#elif defined(__APPLE__) && defined(__i386__) + +/* + * Mac OS X on 32-bit Pentium + */ +#include + +typedef unsigned char gi_uint8; +typedef uint16_t gi_uint16; +typedef uint32_t gi_uint32; +typedef uint32_t gi_size; +typedef uint32_t giantDigit; +typedef uint64_t giantDouble; /* two giant digits */ + +#define GI_GIANT_LOG2_BITS_PER_DIGIT 5 + +#else +/* + * Other target goes here. + */ +#error Platform dependent work needed +#endif + +/* + * Maximum size in bits of base integer in this package. For BBS, this is the + * size of the public 'n' parameter. + */ +#define GI_MAX_PRIME_SIZE_BITS 4096 + +/**** + **** Optimization flags + ****/ + +/* + * There are two implementations of some core arithmetic routines. + * Which one is faster depends highly on your implementation of the + * routines declared in giantPortCommon.h and implemented in either + * giantPort_Generic.h (as static inlines) or elsewhere (in C or + * possibly assembly language). Performance also depends on your + * platform's giantDouble performance. If giantDouble arithmetic + * is fast then use GI_ADDG_INLINE. Otherwise try !GI_ADDG_INLINE, + * measure the two, and pick the best one. + */ +#define GI_ADDG_INLINE 1 + +/* + * true : we don't have a platform-specific giant arithmetic module + * false : we do + */ +#define GI_GIANT_PORT_INLINE 1 + +/* + * GI_INLINE_SMALL_FUNCS + * + * When true, uses inlines instead of a small number of small functions. + * This is a tradeff of speed and less stack usage vs. code size. + */ +#define GI_INLINE_SMALL_FUNCS 1 + +/* + * GI_MACRO_SMALL_FUNCTIONS + * + * Like GI_INLINE_SMALL_FUNCS, except causes small functions to be implemented + * as macros. For platforms that don't support the 'inline' keyword. + */ +#define GI_MACRO_SMALL_FUNCTIONS 0 + +/* + * GI_SMALL_CRT_ENABLE + * + * This flag involves a tradeoff between code size and stack usage in the + * giantMod.c module. Setting this flag true increases code size and + * decreases stack usage. + * + * On a G4, the tradeoff is that setting this flag saves 384 bytes of + * stack space, at the cost of 1407 extra bytes of code. + * + * Note: this flag has no effect if GI_MODG_ENABLE is 0. + */ +#define GI_SMALL_CRT_ENABLE 1 + +/**** + **** Library implementation flags + ****/ + +/* standard library functions available here */ +#define GI_HAVE_MEMCPY 1 +#define GI_HAVE_BZERO 1 + +/* enable/disable modular arithmetic */ +#define GI_MODG_ENABLE 1 + +/* enable/disable giantPrime.[ch] */ +#define GI_PRIME_TEST_ENABLE 1 + +/* enable/disable ginverseMod() */ +#define GI_INVERSE_MOD_ENABLE 1 + +#endif /* _GIANT_PLATFORM_EMULATION_H_ */ diff --git a/lib/pki/libGiants/giantPortCommon.h b/lib/pki/libGiants/giantPortCommon.h new file mode 100644 index 0000000..13ea8c3 --- /dev/null +++ b/lib/pki/libGiants/giantPortCommon.h @@ -0,0 +1,98 @@ +/* Copyright (c) 1998,2006-2007 Apple Inc. All Rights Reserved. + * + * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT + * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE + * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE + * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER, + * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL + * EXPOSE YOU TO LIABILITY. + *************************************************************************** + + giantPortCommon.h - common header used to specify and access + platform-dependent giant digit routines. + + Revision History + ---------------- + 1 Sep 98 Doug Mitchell at Apple + Created. + +*******************************/ + +#ifndef _GIANT_PORT_COMMON_H_ +#define _GIANT_PORT_COMMON_H_ + +#include + +/* + * This is a platform-dependent symbol that must be defined elsewhere, + * typically in giantPlatform.h. + */ +#ifndef GI_GIANT_PORT_INLINE +#error Please define GI_GIANT_PORT_INLINE. +#endif + +#if GI_GIANT_PORT_INLINE + +/* + * Vanilla C version using static inlines, should work on any platform, + * though may not be the fastest possible implementation. + */ +#include + +#else /* GI_GIANT_PORT_INLINE */ + +/* + * A platform-dependent implementation of these functions is required. + */ + +/* + * Add two digits, return sum. Carry bit returned as an out parameter. + */ +extern giantDigit giantAddDigits( + giantDigit dig1, + giantDigit dig2, + giantDigit *carry); /* RETURNED, 0 or 1 */ + +/* + * Add a single digit value to a double digit accumulator in place. + * Carry out of the MSD of the accumulator is not handled. + */ +extern void giantAddDouble( + giantDigit *accLow, /* IN/OUT */ + giantDigit *accHigh, /* IN/OUT */ + giantDigit val); + +/* + * Subtract a - b, return difference. Borrow bit returned as an out parameter. + */ +extern giantDigit giantSubDigits( + giantDigit a, + giantDigit b, + giantDigit *borrow); /* RETURNED, 0 or 1 */ + +/* + * Multiply two digits, return two digits. + */ +extern void giantMulDigits( + giantDigit dig1, + giantDigit dig2, + giantDigit *lowProduct, /* RETURNED, low digit */ + giantDigit *hiProduct); /* RETURNED, high digit */ + +#if 0 +/* this is not currently used or needed */ +/* + * Multiply a vector of giantDigits, candVector, by a single giantDigit, + * plierDigit, adding results into prodVector. Returns m.s. digit from + * final multiply; only candLength digits of *prodVector will be written. + */ +extern giantDigit VectorMultiply( + giantDigit plierDigit, + giantDigit *candVector, + gi_size candLength, + giantDigit *prodVector); +#endif + +#endif /* GI_GIANT_PORT_INLINE */ + +#endif /* _GIANT_PORT_COMMON_H_ */ diff --git a/lib/pki/libGiants/giantPort_C.c b/lib/pki/libGiants/giantPort_C.c new file mode 100644 index 0000000..eef90a1 --- /dev/null +++ b/lib/pki/libGiants/giantPort_C.c @@ -0,0 +1,143 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * giantPort_C.h - Generic giant definitions routines, used when + * no platform-specific version is available. + * + * This module works on any size giantDigit up to and including + * the native unsigned int, as long as the platform does indeed + * supply a (2 x giantDigit) unsigned integer, defined (in + * giantPlatform.h) as a giantDouble. + * + * Created Aug. 8 2005 by Doug Mitchell. + */ + +#include +#include +#include +#include + +#ifndef GI_GIANT_PORT_INLINE +#error Please define GI_GIANT_PORT_INLINE. +#endif + +#if !GI_GIANT_PORT_INLINE +/* + * Add two digits, return sum. Carry bit returned as an out parameter. + */ +giantDigit giantAddDigits( + giantDigit dig1, + giantDigit dig2, + giantDigit *carry) /* RETURNED, 0 or 1 */ +{ + giantDigit sum = dig1 + dig2; + + GI_CHECK_SP("giantAddDigits"); + if((sum < dig1) || (sum < dig2)) { + *carry = 1; + } + else { + *carry = 0; + } + return sum; +} + +/* + * Add a single digit value to a double digit accumulator in place. + * Carry out of the MSD of the accumulator is not handled. + */ +void giantAddDouble( + giantDigit *accLow, /* IN/OUT */ + giantDigit *accHigh, /* IN/OUT */ + giantDigit val) +{ + giantDigit sumLo = *accLow + val; + + GI_CHECK_SP("giantAddDouble"); + if((sumLo < *accLow) || (sumLo < val)) { + (*accHigh)++; + /* if it's zero we just overflowed */ + GIASSERT(*accHigh != 0); + } + *accLow = sumLo; +} + +/* + * Subtract a - b, return difference. Borrow bit returned as an out parameter. + */ +giantDigit giantSubDigits( + giantDigit a, + giantDigit b, + giantDigit *borrow) /* RETURNED, 0 or 1 */ +{ + giantDigit diff = a - b; + + GI_CHECK_SP("giantSubDigits"); + if(a < b) { + *borrow = 1; + } + else { + *borrow = 0; + } + return diff; +} + +/* + * Multiply two digits, return two digits. + */ +void giantMulDigits( + giantDigit dig1, + giantDigit dig2, + giantDigit *lowProduct, /* RETURNED, low digit */ + giantDigit *hiProduct) /* RETURNED, high digit */ +{ + giantDouble dprod; + + GI_CHECK_SP("giantMulDigits"); + dprod = (giantDouble)dig1 * (giantDouble)dig2; + *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); + *lowProduct = (giantDigit)dprod; +} + +#if 0 +/* this is currently unused. */ +/* + * Multiply a vector of giantDigits, candVector, by a single giantDigit, + * plierDigit, adding results into prodVector. Returns m.s. digit from + * final multiply; only candLength digits of *prodVector will be written. + */ +giantDigit VectorMultiply( + giantDigit plierDigit, + giantDigit *candVector, + gi_size candLength, + giantDigit *prodVector) +{ + gi_size candDex; // index into multiplicandVector + giantDigit lastCarry = 0; + giantDigit prodLo; + giantDigit prodHi; + + for(candDex=0; candDex +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Add two digits, return sum. Carry bit returned as an out parameter. + */ +static GI_INLINE giantDigit giantAddDigits( + giantDigit dig1, + giantDigit dig2, + giantDigit *carry) /* RETURNED, 0 or 1 */ +{ + giantDigit sum = dig1 + dig2; + + if((sum < dig1) || (sum < dig2)) { + *carry = 1; + } + else { + *carry = 0; + } + return sum; +} + +/* + * Add a single digit value to a double digit accumulator in place. + * Carry out of the MSD of the accumulator is not handled. + */ +static GI_INLINE void giantAddDouble( + giantDigit *accLow, /* IN/OUT */ + giantDigit *accHigh, /* IN/OUT */ + giantDigit val) +{ + giantDigit sumLo = *accLow + val; + + if((sumLo < *accLow) || (sumLo < val)) { + (*accHigh)++; + /* if it's zero we just overflowed */ + GIASSERT(*accHigh != 0); + } + *accLow = sumLo; +} + +/* + * Subtract a - b, return difference. Borrow bit returned as an out parameter. + */ +static GI_INLINE giantDigit giantSubDigits( + giantDigit a, + giantDigit b, + giantDigit *borrow) /* RETURNED, 0 or 1 */ +{ + giantDigit diff = a - b; + + if(a < b) { + *borrow = 1; + } + else { + *borrow = 0; + } + return diff; +} + +/* + * Multiply two digits, return two digits. + */ +static GI_INLINE void giantMulDigits( + giantDigit dig1, + giantDigit dig2, + giantDigit *lowProduct, /* RETURNED, low digit */ + giantDigit *hiProduct) /* RETURNED, high digit */ +{ + giantDouble dprod; + + dprod = (giantDouble)dig1 * (giantDouble)dig2; + *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); + *lowProduct = (giantDigit)dprod; +} + +#if 0 +/* this is not currently used or needed */ + +/* + * Multiply a vector of giantDigits, candVector, by a single giantDigit, + * plierDigit, adding results into prodVector. Returns m.s. digit from + * final multiply; only candLength digits of *prodVector will be written. + */ +static GI_INLINE giantDigit VectorMultiply( + giantDigit plierDigit, + giantDigit *candVector, + gi_size candLength, + giantDigit *prodVector) +{ + gi_size candDex; // index into multiplicandVector + giantDigit lastCarry = 0; + giantDigit prodLo; + giantDigit prodHi; + + for(candDex=0; candDex + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Standard return codes. + */ +typedef enum { + GR_Success = 0, + GR_IllegalArg, /* illegal argument */ + GR_Unimplemented, /* unimplemented function */ + GR_Internal, /* internal library error */ + GR_Overflow, /* caller error, buffer/giant overflow */ +} GIReturn; + +/* + * We administer the namespace for other libraries' return codes here, so + * all can share a common space. + */ +#define SFEE_RETURN_BASE 1000 /* libSFEE */ +#define RSA_RETURN_BASE 2000 /* libgRSA */ +#define LIBCERT_RETURN_BASE 3000 /* libCert */ +#define DH_RETURN_BASE 4000 /* libgDH */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GIANT_TYPES_H_ */ diff --git a/lib/pki/libGiantsUtils/GIReturnString.c b/lib/pki/libGiantsUtils/GIReturnString.c new file mode 100644 index 0000000..2494b9f --- /dev/null +++ b/lib/pki/libGiantsUtils/GIReturnString.c @@ -0,0 +1,25 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* GIReturnString.c - convert a GIReturn to a string */ + +#include +#include + +const char *GIReturnString(GIReturn grtn) +{ + static char unknown[100]; + + switch(grtn) { + case GR_Success: return "GR_Success"; + case GR_IllegalArg: return "GR_IllegalArg"; + case GR_Unimplemented: return "GR_Unimplemented"; + case GR_Internal: return "GR_Internal"; + case GR_Overflow: return "GR_Overflow"; + default: + sprintf(unknown, "Uknown Error (%d)", (int)grtn); + return unknown; + } +} + + + diff --git a/lib/pki/libGiantsUtils/GIReturnString.h b/lib/pki/libGiantsUtils/GIReturnString.h new file mode 100644 index 0000000..af9694d --- /dev/null +++ b/lib/pki/libGiantsUtils/GIReturnString.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* GIReturnString.h - convert a GIReturn to a string */ + +#ifndef _GIANT_RETURN_STRING_H_ +#define _GIANT_RETURN_STRING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern const char *GIReturnString(GIReturn grtn); + +#ifdef __cplusplus +} +#endif + +#endif /* _GIANT_RETURN_STRING_H_ */ diff --git a/lib/pki/libgRSA/libgRSA.c b/lib/pki/libgRSA/libgRSA.c new file mode 100644 index 0000000..8af1e62 --- /dev/null +++ b/lib/pki/libgRSA/libgRSA.c @@ -0,0 +1,383 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libgRSA.h - public API for RSA library based on libGiants + * + * Created Aug. 9 2005 by Doug Mitchell. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SIG_DEBUG 0 +#if SIG_DEBUG +static void showGiant(const char *label, giant g) +{ + printf("%s: ", label); + printGiantHex(g); +} +#else +#define showGiant(l, g) +#endif + +#if RSA_PUB_KEY_ENABLE + +/* lazy evaluation RSAPubGiantKey->recip */ +static void rsaEnsurePubRecip( + RSAPubGiantKey *pubKey) +{ + GI_CHECK_SP("rsaEnsurePubRecip"); + if(pubKey->recip.g.sign != 0) { + return; + } + GI_LOG_SP("rsaEnsurePubRecip calling make_recip"); + make_recip(&pubKey->n.g, &pubKey->recip.g); +} + +#endif /* RSA_PUB_KEY_ENABLE */ + +#if RSA_PRIV_KEY_ENABLE + +/* lazy evaluation RSAPrivGiantKey->{pRecip,qRecip} */ +static void rsaEnsurePrivRecip( + RSAPrivGiantKey *privKey) +{ + GI_CHECK_SP("rsaEnsurePrivRecip"); + if(privKey->pRecip.g.sign != 0) { + return; + } + GI_LOG_SP("rsaEnsurePrivbRecip calling make_recip"); + make_recip(&privKey->p.g, &privKey->pRecip.g); + make_recip(&privKey->q.g, &privKey->qRecip.g); +} + +#endif /* RSA_PRIV_KEY_ENABLE */ + +#if RSA_SIGN_ENABLE + +RSAStatus RSA_Sign( + RSAPrivGiantKey *privKey, /* private key */ + RSAPadding padding, /* RP_None or RP_PKCS1 */ + const gi_uint8 *dataToSign, /* signature over this data */ + gi_uint16 dataToSignLen, /* length of dataToSign */ + #if RSA_SIG_SHARE_GIANT + RSASignBuffer *signBuffer, /* signature RETURNED here */ + #else + gi_uint8 *sig, /* signature, RETURNED */ + #endif + gi_uint16 *sigLen) /* IN/OUT if !RSA_SIG_SHARE_GIANT */ + /* OUT only if RSA_SIG_SHARE_GIANT */ +{ + RSAStatus rtn = RSA_Success; + lgiant ptSigGiant; /* in/out for powermodCRT */ + gi_uint16 modSize; + GIReturn grtn; + #if !RSA_SIG_SHARE_GIANT + /* powermodCRT needs this one way or another */ + lgiant powermodScratch; + #endif + + if((dataToSign == NULL) || (sigLen == NULL) || (privKey == NULL)) { + return RSA_ParamErr; + } + #if RSA_SIG_SHARE_GIANT + if(signBuffer == NULL) { + return RSA_ParamErr; + } + #else + if(sig == NULL) { + return RSA_ParamErr; + } + localGiantAlloc(&powermodScratch); + #endif /* RSA_SIG_SHARE_GIANT */ + + GI_CHECK_SP("RSA_Sign"); + localGiantAlloc(&ptSigGiant); + + rsaEnsurePrivRecip(privKey); + modSize = ((bitlen(&privKey->p.g) + bitlen(&privKey->q.g)) + 7) / 8; + switch(padding) { + case RP_None: + rtn = rsaAddNoPadding(dataToSign, dataToSignLen, &ptSigGiant.g); + break; + + #if RSA_PADDING_PKCS1_ENABLE + case RP_PKCS1: + rtn = rsaAddPkcs1Padding(dataToSign, dataToSignLen, + modSize, RSA_PKCS1_PAD_SIGN, + NULL, /* no RNG for signing */ + &ptSigGiant.g); + break; + #endif /* RSA_PADDING_PKCS1_ENABLE */ + + default: + rtn = RSA_Unimplemented; + break; + } + if(rtn) { + rsaDebug1("RSA_Sign: AddPadding returned %s\n", rsaStatusStr(rtn)); + goto errOut; + } + + #if RSA_SIG_SHARE_GIANT + /* + * We init this. Not caller, not powermodCRT. But not before + * we're done with the signature buffer, which could be the same + * as dataToSign. + */ + localGiantAlloc(&signBuffer->g); + #endif /* RSA_SIG_SHARE_GIANT */ + + /* sig := (ptext ^ d) mod n */ + showGiant("sign ptGiant", &ptSigGiant.g); + powermodCRT(&ptSigGiant.g, + &privKey->p.g, &privKey->pRecip.g, + &privKey->q.g, &privKey->qRecip.g, + &privKey->dp.g, &privKey->dq.g, + &privKey->qInv.g, + #if RSA_SIG_SHARE_GIANT + &signBuffer->g.g, + #else + &powermodScratch.g, + #endif + &ptSigGiant.g); + showGiant("sign sig ", &ptSigGiant.g); + + #if RSA_SIG_SHARE_GIANT + /* our sigLen is not IN/OUT, but the arg to serializeGiant is */ + *sigLen = sizeof(signBuffer->signature); + grtn = serializeGiant(&ptSigGiant.g, signBuffer->signature, sigLen); + #else + grtn = serializeGiant(&ptSigGiant.g, sig, sigLen); + #endif /* RSA_SIG_SHARE_GIANT */ + if(grtn) { + rtn = giantStatusToRSA(grtn); + rsaDebug1("RSA_Sign: serializeGiant returned %s\n", rsaStatusStr(rtn)); + } +errOut: + clearGiant(&ptSigGiant.g); + return rtn; +} +#endif /* RSA_SIGN_ENABLE */ + +#if RSA_VERIFY_ENABLE + +extern RSAStatus RSA_SigVerify( + RSAPubGiantKey *pubKey, /* public key */ + RSAPadding padding, /* RP_None or RP_PKCS1 */ + const gi_uint8 *signedData, /* signature over this data */ + gi_uint16 signedDataLen, /* length of dataToSign */ + const gi_uint8 *sig, /* signature */ + gi_uint16 sigLen) /* length of signature */ +{ + RSAStatus rtn = RSA_Success; + lgiant ptSigGiant; /* plain and decrypted signature */ + GIReturn grtn; + + GI_CHECK_SP("RSA_SigVerify"); + GI_LOG_SP("RSA_SigVerify top"); + if((signedData == NULL) || (sig == NULL)) { + return RSA_ParamErr; + } + if(pubKey == NULL) { + return RSA_ParamErr; + } + + localGiantAlloc(&ptSigGiant); + rsaEnsurePubRecip(pubKey); + + /* signature --> giant */ + grtn = deserializeGiant(&ptSigGiant.g, sig, sigLen); + if(grtn) { + rtn = giantStatusToRSA(grtn); + rsaDebug1("RSA_SigVerify: deserializeGiant (sig) returned %s\n", + rsaStatusStr(rtn)); + return rtn; + } + + /* decrytped sig := (sig ^ e) mod n */ + /* powermodg allows base and result to reside in same giant */ + GI_LOG_SP("calling powermodg"); + showGiant("vfy ptGiant", &ptSigGiant.g); + + powermodg(&ptSigGiant.g, &pubKey->e.g, + &pubKey->n.g, &pubKey->recip.g, + &ptSigGiant.g); + + showGiant("vfy sig ", &ptSigGiant); + + /* check and strip padding, verify data */ + switch(padding) { + case RP_None: + rtn = rsaCheckNoPaddingForSigVfy(&ptSigGiant.g, signedData, signedDataLen); + break; + + #if RSA_PADDING_PKCS1_ENABLE + case RP_PKCS1: + rtn = rsaCheckPkcs1PaddingForSigVfy(&ptSigGiant.g, signedData, signedDataLen); + break; + #endif /* RSA_PADDING_PKCS1_ENABLE */ + + default: + rtn = RSA_Unimplemented; + break; + } + if(rtn) { + rsaDebug1("RSA_SigVerify: CheckPadding returned %s\n", rsaStatusStr(rtn)); + } + + clearGiant(&ptSigGiant.g); + return rtn; +} +#endif /* RSA_VERIFY_ENABLE */ + +#if RSA_ENCRYPT_ENABLE + +extern RSAStatus RSA_Encrypt( + RSAPubGiantKey *pubKey, /* public key */ + RSAPadding padding, /* RP_None, RP_PKCS1, RP_OAEP */ + RSARngCallback *rngCallback, /* required for RP_PKCS1, RP_OAEP */ + const gi_uint8 *plainText, + gi_uint16 plainTextLen, /* length of plainText */ + gi_uint8 *cipherText, + gi_uint16 *cipherTextLen) /* IN/OUT */ +{ + RSAStatus rtn = RSA_Success; + lgiant ptCtGiant; + GIReturn grtn; + gi_uint16 modSize; + + if((plainText == NULL) || (cipherText == NULL) || (cipherTextLen == NULL)) { + return RSA_ParamErr; + } + if(pubKey == NULL) { + return RSA_ParamErr; + } + + GI_CHECK_SP("RSA_Encrypt"); + localGiantAlloc(&ptCtGiant); + rsaEnsurePubRecip(pubKey); + + modSize = giantNumBytes(&pubKey->n.g); + switch(padding) { + case RP_None: + rtn = rsaAddNoPadding(plainText, plainTextLen, &ptCtGiant.g); + break; + + #if RSA_PADDING_PKCS1_ENABLE + case RP_PKCS1: + rtn = rsaAddPkcs1Padding(plainText, plainTextLen, + modSize, RSA_PKCS1_PAD_ENCRYPT, + rngCallback, + &ptCtGiant.g); + break; + #endif /* RSA_PADDING_PKCS1_ENABLE */ + + /* OEAP goes here eventually */ + + default: + rtn = RSA_Unimplemented; + break; + } + if(rtn) { + rsaDebug1("RSA_Encrypt: AddPadding returned %s\n", rsaStatusStr(rtn)); + goto errOut; + } + + /* ctext := (ptext ^ e) mod n */ + /* ptext and ctext can share the same giant */ + powermodg(&ptCtGiant.g, &pubKey->e.g, + &pubKey->n.g, &pubKey->recip.g, + &ptCtGiant.g); + + /* out to caller */ + grtn = serializeGiant(&ptCtGiant.g, cipherText, cipherTextLen); + if(grtn) { + rtn = giantStatusToRSA(grtn); + rsaDebug1("RSA_Encrypt: serializeGiant returned %s\n", rsaStatusStr(rtn)); + } +errOut: + clearGiant(&ptCtGiant.g); + return rtn; +} +#endif /* RSA_ENCRYPT_ENABLE */ + +#if RSA_DECRYPT_ENABLE + +RSAStatus RSA_Decrypt( + RSAPrivGiantKey *privKey, /* private key */ + RSAPadding padding, /* RP_None, RP_PKCS1, RP_OAEP */ + const gi_uint8 *cipherText, + gi_uint16 cipherTextLen, /* length of cipherText */ + gi_uint8 *plainText, + gi_uint16 *plainTextLen) /* IN/OUT */ +{ + RSAStatus rtn = RSA_Success; + lgiant ptCtGiant; + GIReturn grtn; + lgiant powermodScratch; + + if((plainText == NULL) || (cipherText == NULL) || (plainTextLen == NULL) || (privKey == NULL)) { + return RSA_ParamErr; + } + + GI_CHECK_SP("RSA_Decrypt"); + localGiantAlloc(&ptCtGiant); + localGiantAlloc(&powermodScratch); + + rsaEnsurePrivRecip(privKey); + + /* ciphertext --> giant */ + grtn = deserializeGiant(&ptCtGiant.g, cipherText, cipherTextLen); + if(grtn) { + rtn = giantStatusToRSA(grtn); + rsaDebug1("RSA_Decrypt: deserializeGiant (sig) returned %s\n", + rsaStatusStr(rtn)); + goto errOut; + } + + /* plaintext := (ciphertext ^ d) mod n */ + powermodCRT(&ptCtGiant.g, + &privKey->p.g, &privKey->pRecip.g, + &privKey->q.g, &privKey->qRecip.g, + &privKey->dp.g, &privKey->dq.g, + &privKey->qInv.g, + &powermodScratch.g, + &ptCtGiant.g); + + /* check and strip padding */ + switch(padding) { + case RP_None: + rtn = rsaCheckNoPadding(&ptCtGiant.g, plainText, plainTextLen); + break; + + #if RSA_PADDING_PKCS1_ENABLE + case RP_PKCS1: + rtn = rsaCheckPkcs1Padding(&ptCtGiant.g, RSA_PKCS1_PAD_ENCRYPT, + plainText, plainTextLen); + break; + #endif /* RSA_PADDING_PKCS1_ENABLE */ + + /* OAEP here */ + + default: + rtn = RSA_Unimplemented; + break; + } + if(rtn) { + rsaDebug1("RSA_Decrypt: CheckPadding returned %s\n", rsaStatusStr(rtn)); + } + +errOut: + clearGiant(&ptCtGiant.g); + return rtn; +} + +#endif /* RSA_DECRYPT_ENABLE */ + diff --git a/lib/pki/libgRSA/libgRSA.h b/lib/pki/libgRSA/libgRSA.h new file mode 100644 index 0000000..6d04af4 --- /dev/null +++ b/lib/pki/libgRSA/libgRSA.h @@ -0,0 +1,187 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libgRSA.h - public API for RSA library based on libGiants + */ + +#ifndef _LIBGRSA_LIBRSA_H_ +#define _LIBGRSA_LIBRSA_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This file declares the main public functions in the libgRSA library. + * Keys for all of these functions are expressed in "RSAGiantKey" format, + * defined in rsaGiantKey.h. This is the native key format for this + * library. RSAGiantKeys can be obtained in one of two ways: + * + * -- from DER-encoded, PKCS1-style key blobs, using the interface in + * libgRSA_DER.h. + * -- from raw byte strings representing individual key components, using + * the interface in rsaRawKey.h. + */ + +/* + * RSA_SIG_SHARE_GIANT, when true, is an optimization to reduce the stack + * requirements when performing an RSA_Sign operation. When true, caller + * allocates an RSASignBuffer union which contains both a sratch giant + * for use by lower level code and the buffer into which a signature + * will be written at the completion of RSA_Sign(). The input, + * dataToSign, can also be in this RSASignBuffer (i.e., dataToSign + * can equal RSASignBuffer.signature). + */ +#define RSA_SIG_SHARE_GIANT 0 +#if RSA_SIG_SHARE_GIANT + +typedef union { + lgiant g; + gi_uint8 signature[MAX_PRIME_SIZE_BYTES]; +} RSASignBuffer; + +#endif /* RSA_SIG_SHARE_GIANT */ + + +/* + * Given a private key and data to sign, generate a digital signature. + * + * If the padding argument is RP_PKCS1, PKCS1 padding will be performed + * prior to signing. If this argument is RP_None, the incoming data + * will be signed "as is". (OAEP padding is not supported for signing.) + * Note when PKCS1 padding is performed, the maximum length of data that + * can be signed is RSAKey.nLen-11 where RSAKey.nLen is the length of + * the modulus. + * + * NOTE: using RP_None will not work if the first byte of dataToSign + * is zero; there is no way to verify leading zeroes as they got chopped + * off during the calculation. + + * + * If you want a proper PKCS1 style signature, with DER encoding of the + * incoming data - and the data is a SHA1 digest - use RSA_EncodeDigest + * to format the data in an encoded DigestInfo struct before calling + * this routine. + * + * If RSA_SIG_SHARE_GIANT is zero, caller allocates sig, the output buffer, + * into which the signature will be written. This must be at least as large + * as the key's modulus. On input, *sigLen is the size of the available buffer. + * On output it's the size of the signature actually written to sig. + * + * If RSA_SIG_SHARE_GIANT is nonzero, caller allocates the signBuffer of + * type RSASignBuffer; the signature will be written into + * signBuffer->signature and *sigLen will equal the size of the + * signature actually written to signBuffer->signature. + * + * When memory usage is a critical issue, note that the input buffer + * (dataToSign) can be the same as the output buffer (sig, or + * signBuffer->signature, depending on RSA_SIG_SHARE_GIANT). + * + * Returns an RSAStatus as described in libgRSA.h. + */ + +#if RSA_SIG_SHARE_GIANT + +extern RSAStatus RSA_Sign( + RSAPrivGiantKey *privKey, /* private key */ + RSAPadding padding, /* RP_None or RP_PKCS1 */ + const gi_uint8 *dataToSign, /* signature over this data */ + gi_uint16 dataToSignLen, /* length of dataToSign */ + RSASignBuffer *signBuffer, /* signature RETURNED here */ + gi_uint16 *sigLen); /* signature RETURNED here */ + +#else /* !RSA_SIG_SHARE_GIANT */ + +extern RSAStatus RSA_Sign( + RSAPrivGiantKey *privKey, /* private key */ + RSAPadding padding, /* RP_None or RP_PKCS1 */ + const gi_uint8 *dataToSign, /* signature over this data */ + gi_uint16 dataToSignLen, /* length of dataToSign */ + gi_uint8 *sig, /* signature, RETURNED */ + gi_uint16 *sigLen); /* IN/OUT */ + +#endif /* RSA_SIG_SHARE_GIANT */ + +/* + * Given a public key, data which has been signed, and a signature, + * verify the signature. + * + * If the padding argument is RP_PKCS1, PKCS1 padding will be performed + * prior to verification. If this argument is RP_None, the incoming data + * will be verified "as is". (OAEP padding is not supported for verifying.) + * Note when PKCS1 padding is performed, the maximum length of data that + * can be signed and verified is RSAKey.nLen-11 where RSAKey.nLen is the + * length of the modulus. + * + * If you are verifying a proper PKCS1 style signature, with DER encoding + * of the incoming data - and the data is a SHA1 digest - use + * DEREncodeSHA1DigestInfo to format the data in an encoded DigestInfo + * struct before calling this routine. + * + * Returns an RSAStatus as described above. + */ +extern RSAStatus RSA_SigVerify( + RSAPubGiantKey *pubKey, /* public key */ + RSAPadding padding, /* RP_None or RP_PKCS1 */ + const gi_uint8 *signedData, /* signature over this data */ + gi_uint16 signedDataLen, /* length of dataToSign */ + const gi_uint8 *sig, /* signature */ + gi_uint16 sigLen); /* length of signature */ + +/* + * Encrypt a block of plaintext with a public key. + * Resulting ciphertext is the same size as the key's modulus + * (RSAKey.nLen) and is allocated by the caller. + * The cipherTextLen argument, on input, specifies how much + * space is available for the ciphertext; on return, it + * is the actual number of ciphertext bytes written. + * + * When performing RP_PKCS1 or RP_OAEP padding, you must supply + * a callback to a pseudorandom number generator via the rngFcn + * argument. + * + * When memory usage is a critical issue, note that the input buffer + * (plainText) can be the same as the output buffer (cipherText). + * + * Returns an RSAStatus as described above. + */ +extern RSAStatus RSA_Encrypt( + RSAPubGiantKey *pubKey, /* public key */ + RSAPadding padding, /* RP_None, RP_PKCS1, RP_OAEP */ + RSARngCallback *rngCallback, /* required for RP_PKCS1, RP_OAEP */ + const gi_uint8 *plainText, + gi_uint16 plainTextLen, /* length of plainText */ + gi_uint8 *cipherText, + gi_uint16 *cipherTextLen); /* IN/OUT */ + +/* + * Decrypt a block of ciphertext with a private key. The + * ciphertext must be equal in length to the size of the + * key's modulus. The plaintext buffer is allocated by + * the caller' en entry, *plainTextLen is the size of the + * available plaintext buffer; on return, it is the number + * of plaintext bytes actually written. + * + * When memory usage is a critical issue, note that the input buffer + * (cipherText) can be the same as the output buffer (plainText). + * + * Returns an RSAStatus as described above. + */ +extern RSAStatus RSA_Decrypt( + RSAPrivGiantKey *privKey, /* private key */ + RSAPadding padding, /* RP_None, RP_PKCS1, RP_OAEP */ + const gi_uint8 *cipherText, + gi_uint16 cipherTextLen, /* length of cipherText */ + gi_uint8 *plainText, + gi_uint16 *plainTextLen); /* IN/OUT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBRSA_LIBRSA_H_ */ + diff --git a/lib/pki/libgRSA/libgRSA_DER.c b/lib/pki/libgRSA/libgRSA_DER.c new file mode 100644 index 0000000..e620396 --- /dev/null +++ b/lib/pki/libgRSA/libgRSA_DER.c @@ -0,0 +1,440 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libgRSA_DER.c - DER encoding/decoding routines + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef RSA_PKCS1_KEY_ENABLE +#error Please define RSA_PKCS1_KEY_ENABLE. +#endif + +#if RSA_PKCS1_KEY_ENABLE + +#if RSA_PUB_KEY_ENABLE || RSA_PRIV_KEY_ENABLE + +/* init an lgiant, fill it with incoming bytes */ +static RSAStatus rsaSetGiant( + lgiant *g, + DERItem *item) +{ + localGiantAlloc(g); + if(deserializeGiant(&g->g, item->data, item->length)) { + return RSA_BadKeyData; + } + return RSA_Success; +} + +#endif /* RSA_PUB_KEY_ENABLE || RSA_PRIV_KEY_ENABLE */ + +/* + * Decode PKCS1 form keys into RSA{Pub,Priv}GiantKey. + */ + +#if RSA_PUB_KEY_ENABLE + +RSAStatus RSA_DecodePubKey( + const unsigned char *pkcs1Key, + gi_uint16 pkcs1KeyLen, + RSAPubGiantKey *pubKey) /* RETURNED */ +{ + DERReturn drtn; + DERItem keyItem = {(DERByte *)pkcs1Key, pkcs1KeyLen}; + DERRSAPubKeyPKCS1 decodedKey; + RSAStatus rrtn; + + GI_CHECK_SP("RSA_DecodePubKey"); + Bzero(pubKey, sizeof(*pubKey)); + drtn = DERParseSequence(&keyItem, + DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs, + &decodedKey, sizeof(decodedKey)); + if(drtn) { + return RSA_BadKeyData; + } + + /* make_recip called lazily when the key is actually used */ + localGiantAlloc(&pubKey->recip); + + rrtn = rsaSetGiant(&pubKey->n, &decodedKey.modulus); + if(rrtn) { + return rrtn; + } + return rsaSetGiant(&pubKey->e, &decodedKey.pubExponent); +} + +RSAStatus RSA_DecodeApplePubKey( + const unsigned char *pkcs1Key, + gi_uint16 pkcs1KeyLen, + RSAPubGiantKey *pubKey) /* RETURNED */ +{ + DERReturn drtn; + DERItem keyItem = {(DERByte *)pkcs1Key, pkcs1KeyLen}; + DERRSAPubKeyApple decodedKey; + RSAStatus rrtn; + + Bzero(pubKey, sizeof(*pubKey)); + drtn = DERParseSequence(&keyItem, + DERNumRSAPubKeyAppleItemSpecs, DERRSAPubKeyAppleItemSpecs, + &decodedKey, sizeof(decodedKey)); + if(drtn) { + return RSA_BadKeyData; + } + + rrtn = rsaSetGiant(&pubKey->e, &decodedKey.pubExponent); + if(rrtn) { + return rrtn; + } + rrtn = rsaSetGiant(&pubKey->n, &decodedKey.modulus); + if(rrtn) { + return rrtn; + } + rrtn = rsaSetGiant(&pubKey->recip, &decodedKey.reciprocal); + if(rrtn) { + return rrtn; + } + return RSA_Success; +} + +#endif /* RSA_PUB_KEY_ENABLE */ + +#if RSA_PRIV_KEY_ENABLE + +/* init an rsaSgiant, fill it with incoming bytes */ +static RSAStatus rsaSetSGiant( + rsaSgiant *g, + DERItem *item) +{ + localSmallGiantAlloc(g); + if(deserializeGiant(&g->g, item->data, item->length)) { + return RSA_BadKeyData; + } + return RSA_Success; +} + +RSAStatus RSA_DecodePrivKey( + const unsigned char *pkcs1Key, + gi_uint16 pkcs1KeyLen, + RSAPrivGiantKey *privKey) /* RETURNED */ +{ + DERReturn drtn; + DERItem keyItem = {(DERByte *)pkcs1Key, pkcs1KeyLen}; + DERRSAPrivKeyCRT decodedKey; + + Bzero(privKey, sizeof(*privKey)); + drtn = DERParseSequence(&keyItem, + DERNumRSAPrivKeyCRTItemSpecs, DERRSAPrivKeyCRTItemSpecs, + &decodedKey, sizeof(decodedKey)); + if(drtn) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->p, &decodedKey.p)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->q, &decodedKey.q)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->dp, &decodedKey.dp)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->dq, &decodedKey.dq)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->qInv, &decodedKey.qInv)) { + return RSA_BadKeyData; + } + + /* pRecip, qRecip evaluated lazily */ + localSmallGiantAlloc(&privKey->pRecip); + localSmallGiantAlloc(&privKey->qRecip); + + return RSA_Success; +} + +RSAStatus RSA_DecodeKeyPair( + const unsigned char *pkcs1Key, + gi_uint16 pkcs1KeyLen, + RSAFullGiantKey *keyPair) /* RETURNED */ +{ + DERReturn drtn; + DERItem keyItem = {(DERByte *)pkcs1Key, pkcs1KeyLen}; + DERRSAKeyPair decodedKey; + + Bzero(keyPair, sizeof(*keyPair)); + drtn = DERParseSequence(&keyItem, + DERNumRSAKeyPairItemSpecs, DERRSAKeyPairItemSpecs, + &decodedKey, sizeof(decodedKey)); + if(drtn) { + return RSA_BadKeyData; + } + if(rsaSetGiant(&keyPair->pub.n, &decodedKey.n)) { + return RSA_BadKeyData; + } + if(rsaSetGiant(&keyPair->pub.e, &decodedKey.e)) { + return RSA_BadKeyData; + } + if(rsaSetGiant(&keyPair->d, &decodedKey.d)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&keyPair->priv.p, &decodedKey.p)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&keyPair->priv.q, &decodedKey.q)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&keyPair->priv.dp, &decodedKey.dp)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&keyPair->priv.dq, &decodedKey.dq)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&keyPair->priv.qInv, &decodedKey.qInv)) { + return RSA_BadKeyData; + } + + /* recip, pRecip, qRecip evaluated lazily */ + localGiantAlloc(&keyPair->pub.recip); + localSmallGiantAlloc(&keyPair->priv.pRecip); + localSmallGiantAlloc(&keyPair->priv.qRecip); + + return RSA_Success; +} + +#endif /* RSA_PRIV_KEY_ENABLE */ + +#if RSA_KEY_GENERATE_ENABLE + +#define RSA_MAX_GIANT_SIZE MAX_SERIALIZED_GIANT_SIZE(GIANT_LITTLE_DIGITS) + +/* + * Munge a giant (from e.g. a RSAFullGiantKey) into a gi_uint8 array + * and then into a DERItem suitable for encoding. + */ +static RSAStatus rsaGiantToDerItem( + giant g, + gi_uint8 *cp, + gi_uint16 cpLen, + DERItem *derItem) +{ + GIReturn grtn; + gi_uint16 ioLen = cpLen; + gi_uint16 dex; + + /* serialize the giant into DER content */ + grtn = serializeGiant(g, cp, &ioLen); + if(grtn) { + return giantStatusToRSA(grtn); + } + + /* convert the result into a DERItem */ + derItem->data = cp; + derItem->length = ioLen; + + /* trim off leading zeroes (but leave one zero if that's all there is) */ + for(dex=0; dex<(ioLen-1); dex++) { + if(*(derItem->data) != 0) { + break; + } + derItem->data++; + derItem->length--; + } + return RSA_Success; +} + +#if RSA_PUB_KEY_ENABLE + +/* DER encode a public key, PKCS1 format */ +RSAStatus RSA_EncodePubKey( + RSAPubGiantKey *giantKey, + gi_uint8 *pkcs1Key, /* data written here */ + gi_uint32 *inOutLen) /* IN/OUT */ +{ + DERRSAPubKeyPKCS1 derKey; + DERReturn drtn; + RSAStatus rrtn; + DERByte *der = pkcs1Key; + DERSize ioLen = *inOutLen; + + /* serialized giant byte arrays */ + gi_uint8 nChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 eChars[RSA_MAX_GIANT_SIZE]; + + /* giants --> DERItems */ + rrtn = rsaGiantToDerItem(&giantKey->n.g, nChars, RSA_MAX_GIANT_SIZE, + &derKey.modulus); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&giantKey->e.g, eChars, RSA_MAX_GIANT_SIZE, + &derKey.pubExponent); + if(rrtn) { + return rrtn; + } + + /* encode */ + drtn = DEREncodeSequence(ASN1_CONSTR_SEQUENCE, + &derKey, + DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs, + der, + &ioLen); + if(drtn) { + return derStatusToRSA(drtn); + } + + /* success */ + *inOutLen = ioLen; + return RSA_Success; +} + +/* DER encode a public key, custom (to this library) format with reciprocal */ +RSAStatus RSA_EncodeApplePubKey( + RSAPubGiantKey *giantKey, + gi_uint8 *pubKey, /* data written here */ + gi_uint32 *inOutLen) /* IN/OUT */ +{ + DERRSAPubKeyApple derKey; + DERReturn drtn; + RSAStatus rrtn; + DERByte *der = pubKey; + DERSize ioLen = *inOutLen; + bgiant recip; + + /* serialized giant byte arrays */ + gi_uint8 nChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 rChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 eChars[RSA_MAX_GIANT_SIZE]; + + /* calculate the reciprocal */ + localBigGiantAlloc(&recip); + make_recip(&giantKey->n.g, &recip.g); + + /* giants --> DERItems */ + rrtn = rsaGiantToDerItem(&giantKey->n.g, nChars, RSA_MAX_GIANT_SIZE, + &derKey.modulus); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&recip.g, rChars, RSA_MAX_GIANT_SIZE, + &derKey.reciprocal); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&giantKey->e.g, eChars, RSA_MAX_GIANT_SIZE, + &derKey.pubExponent); + if(rrtn) { + return rrtn; + } + + /* encode */ + drtn = DEREncodeSequence(ASN1_CONSTR_SEQUENCE, + &derKey, + DERNumRSAPubKeyAppleItemSpecs, DERRSAPubKeyAppleItemSpecs, + der, + &ioLen); + if(drtn) { + return derStatusToRSA(drtn); + } + + /* success */ + *inOutLen = ioLen; + return RSA_Success; +} + +#endif /* RSA_PUB_KEY_ENABLE */ + +#if RSA_PRIV_KEY_ENABLE + +/* + * Create a PKCS1-formattted private key given a RSAFullGiantKey. + * The inOutLen param contains the number of bytes available in + * *pkcs1Key on entry, adn contains the number of bytes actually + * written to *pkcs1Key on successful return. + */ +RSAStatus RSA_EncodeKeyPair( + RSAFullGiantKey *keyPair, + gi_uint8 *pkcs1Key, /* data written here */ + gi_uint32 *inOutLen) /* IN/OUT */ +{ + DERRSAKeyPair derKey; + DERReturn drtn; + RSAStatus rrtn; + DERByte *der = pkcs1Key; + DERSize ioLen = *inOutLen; + DERByte version = 0; + + /* serialized giant byte arrays */ + gi_uint8 nChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 eChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 dChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 pChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 qChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 dpChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 dqChars[RSA_MAX_GIANT_SIZE]; + gi_uint8 qInvChars[RSA_MAX_GIANT_SIZE]; + + derKey.version.data = &version; + derKey.version.length = 1; + + /* giants --> DERItems */ + rrtn = rsaGiantToDerItem(&keyPair->pub.n.g, nChars, RSA_MAX_GIANT_SIZE, &derKey.n); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&keyPair->pub.e.g, eChars, RSA_MAX_GIANT_SIZE, &derKey.e); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&keyPair->d.g, dChars, RSA_MAX_GIANT_SIZE, &derKey.d); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&keyPair->priv.p.g, pChars, RSA_MAX_GIANT_SIZE, &derKey.p); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&keyPair->priv.q.g, qChars, RSA_MAX_GIANT_SIZE, &derKey.q); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&keyPair->priv.dp.g, dpChars, RSA_MAX_GIANT_SIZE, &derKey.dp); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&keyPair->priv.dq.g, dqChars, RSA_MAX_GIANT_SIZE, &derKey.dq); + if(rrtn) { + return rrtn; + } + rrtn = rsaGiantToDerItem(&keyPair->priv.qInv.g, qInvChars, RSA_MAX_GIANT_SIZE, &derKey.qInv); + if(rrtn) { + return rrtn; + } + + /* encode */ + drtn = DEREncodeSequence(ASN1_CONSTR_SEQUENCE, + &derKey, + DERNumRSAKeyPairItemSpecs, DERRSAKeyPairItemSpecs, + der, + &ioLen); + if(drtn) { + return derStatusToRSA(drtn); + } + + /* success */ + *inOutLen = ioLen; + return RSA_Success; +} + +#endif /* RSA_PRIV_KEY_ENABLE */ + +#endif /* RSA_KEY_GENERATE_ENABLE */ + +#endif /* RSA_PKCS1_KEY_ENABLE */ + diff --git a/lib/pki/libgRSA/libgRSA_DER.h b/lib/pki/libgRSA/libgRSA_DER.h new file mode 100644 index 0000000..a959e5e --- /dev/null +++ b/lib/pki/libgRSA/libgRSA_DER.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libgRSA_DER.h - DER encoding/decoding routines + */ + +#ifndef _LIBGRSA_LIBRSA_DER_H_ +#define _LIBGRSA_LIBRSA_DER_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Decode PKCS1 form keys into RSA{Pub,Priv}GiantKey. + */ +RSAStatus RSA_DecodePubKey( + const unsigned char *pkcs1Key, + gi_uint16 pkcs1KeyLen, + RSAPubGiantKey *pubKey); /* RETURNED */ + +RSAStatus RSA_DecodePrivKey( + const unsigned char *pkcs1Key, + gi_uint16 pkcs1KeyLen, + RSAPrivGiantKey *privKey); /* RETURNED */ + +RSAStatus RSA_DecodeKeyPair( + const unsigned char *pkcs1Key, + gi_uint16 pkcs1KeyLen, + RSAFullGiantKey *keyPair); /* RETURNED */ + +/* + * Decode an custom (to this library) public key with reciprocal. + */ +RSAStatus RSA_DecodeApplePubKey( + const unsigned char *aplePubKey, + gi_uint16 applePubKeyLen, + RSAPubGiantKey *pubKey); /* RETURNED */ + +/* + * Generated key pair encoding support. + */ + +#define RSA_HALF_SIZE(keySizeInBytes) ((keySizeInBytes + 1) / 2) + +/* + * To allocate space on the stack for encoded public and private keys, + * use these macros to determine the max size needed. They are conservative; + * they will almost certainly allocate more space than you really + * end up needing for the encoded keys. + */ +#define RSA_ENCODED_PRIV_KEY_SIZE(keySizeInBytes) \ + DER_MAX_ENCODED_SIZE( \ + DER_MAX_ENCODED_SIZE(1) + /* version */ \ + DER_MAX_ENCODED_SIZE(keySizeInBytes) + /* n */ \ + DER_MAX_ENCODED_SIZE(keySizeInBytes) + /* e */ \ + DER_MAX_ENCODED_SIZE(keySizeInBytes) + /* d */ \ + DER_MAX_ENCODED_SIZE(RSA_HALF_SIZE(keySizeInBytes)) + /* p */ \ + DER_MAX_ENCODED_SIZE(RSA_HALF_SIZE(keySizeInBytes)) + /* q */ \ + DER_MAX_ENCODED_SIZE(RSA_HALF_SIZE(keySizeInBytes)) + /* dp */ \ + DER_MAX_ENCODED_SIZE(RSA_HALF_SIZE(keySizeInBytes)) + /* dq */ \ + DER_MAX_ENCODED_SIZE(RSA_HALF_SIZE(keySizeInBytes))) /* qInv */ + +#define RSA_ENCODED_PUB_KEY_SIZE(keySizeInBytes) \ + DER_MAX_ENCODED_SIZE( \ + DER_MAX_ENCODED_SIZE(keySizeInBytes) + /* n */ \ + DER_MAX_ENCODED_SIZE(keySizeInBytes)) /* e */ + +#define RSA_ENCODED_APPLE_PUB_KEY_SIZE(keySizeInBytes) \ + DER_MAX_ENCODED_SIZE( \ + DER_MAX_ENCODED_SIZE(keySizeInBytes) + /* n */ \ + DER_MAX_ENCODED_SIZE(keySizeInBytes) + /* recip */ \ + GIANT_BYTES_PER_DIGIT + /* recip: one extra digit */ \ + DER_MAX_ENCODED_SIZE(keySizeInBytes)) /* e */ + +/* + * Create PKCS1-formatted public key given a RSAFullGiantKey. + * The inOutLen param contains the number of bytes available in + * *pkcs1Key on entry, adn contains the number of bytes actually + * written to *pkcs1Key on successful return. + */ +RSAStatus RSA_EncodePubKey( + RSAPubGiantKey *giantKey, + gi_uint8 *pkcs1Key, /* data written here */ + gi_uint32 *inOutLen); /* IN/OUT */ + +/* + * Create a PKCS1-formattted private key given a RSAFullGiantKey. + * The inOutLen param contains the number of bytes available in + * *pkcs1Key on entry, adn contains the number of bytes actually + * written to *pkcs1Key on successful return. + */ +RSAStatus RSA_EncodeKeyPair( + RSAFullGiantKey *keyPair, + gi_uint8 *pkcs1Key, /* data written here */ + gi_uint32 *inOutLen); /* IN/OUT */ + +/* + * Create a custom (to this library) DER-encoded public key including + * the reciprocal. + * The inOutLen param contains the number of bytes available in + * *pubKey on entry, adn contains the number of bytes actually + * written to *pkcs1Key on successful return. + */ +RSAStatus RSA_EncodeApplePubKey( + RSAPubGiantKey *giantKey, + gi_uint8 *pubKey, /* data written here */ + gi_uint32 *inOutLen); /* IN/OUT */ + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBGRSA_LIBRSA_DER_H_ */ + diff --git a/lib/pki/libgRSA/libgRSA_config.h b/lib/pki/libgRSA/libgRSA_config.h new file mode 100644 index 0000000..c12b5c7 --- /dev/null +++ b/lib/pki/libgRSA/libgRSA_config.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libgRSA_config.h - #defines controlling what features are enabled in a + * given implementation of this library. + * + * Created Aug. 9 2005 by Doug Mitchell. + */ + +#ifndef _LIBGRSA_LIBRSA_CONFIG_H_ +#define _LIBGRSA_LIBRSA_CONFIG_H_ + +/* one flag for each basic RSA operation */ +#define RSA_SIGN_ENABLE 1 +#define RSA_VERIFY_ENABLE 1 +#define RSA_ENCRYPT_ENABLE 1 +#define RSA_DECRYPT_ENABLE 1 + +/* values inferred from above four flags - do not modify */ +#define RSA_SIGVFY_ENABLE (RSA_SIGN_ENABLE || RSA_VERIFY_ENABLE) +#define RSA_ENCRDECR_ENABLE (RSA_ENCRYPT_ENABLE || RSA_DECRYPT_ENABLE) +#define RSA_PUB_KEY_ENABLE (RSA_VERIFY_ENABLE || RSA_ENCRYPT_ENABLE) +#define RSA_PRIV_KEY_ENABLE (RSA_SIGN_ENABLE || RSA_DECRYPT_ENABLE) + +/* + * Enables DER encoding of DigestInfo for proper PKCS1 signatures + * This is always disabled if !RSA_SIGVFY_ENABLE. + */ +#if RSA_SIGVFY_ENABLE +#define RSA_DER_DIGEST_ENABLE 1 /* your platform's value here */ +#else +#define RSA_DER_DIGEST_ENABLE 0 /* hard coded - do not change */ +#endif + +/* enable support for PKCS1 and OEAP padding */ +#define RSA_PADDING_PKCS1_ENABLE 1 +#define RSA_PADDING_OAEP_ENABLE 0 /* not supported yet */ + +/* enable support for PKCS1 format keys */ +#define RSA_PKCS1_KEY_ENABLE 1 + +/* enable support for raw keys (rsaRawKey.[ch]) */ +#define RSA_RAW_KEY_ENABLE 1 + +/* enable key pair generation */ +#define RSA_KEY_GENERATE_ENABLE 1 + +#endif /* _LIBGRSA_LIBRSA_CONFIG_H_ */ diff --git a/lib/pki/libgRSA/libgRSA_priv.c b/lib/pki/libgRSA/libgRSA_priv.c new file mode 100644 index 0000000..7d81531 --- /dev/null +++ b/lib/pki/libgRSA/libgRSA_priv.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libgRSA_priv.c - private libRSA routines. + * + * Created Aug. 10 2005 by Doug Mitchell. + */ + +#include + +/* convert a libGiants GIReturn to our own RSAStatus */ +RSAStatus giantStatusToRSA(GIReturn grtn) +{ + switch(grtn) { + case GR_Success: return RSA_Success; + case GR_IllegalArg: return RSA_ParamErr; + case GR_Unimplemented: return RSA_Unimplemented; + case GR_Internal: return RSA_InternalError; + case GR_Overflow: return RSA_Overflow; + default: return RSA_OtherError; + } +} + +/* convert a libDER DERReturn to our own RSAStatus */ +RSAStatus derStatusToRSA(DERReturn drtn) +{ + switch(drtn) { + case DR_Success: return RSA_Success; + case DR_ParamErr: return RSA_ParamErr; + case DR_BufOverflow: return RSA_Overflow; + case DR_Unimplemented: return RSA_Unimplemented; + default: return RSA_BadKeyFormat; + } +} + +#ifndef NDEBUG + +#include + +/* be sure to update the mirrored copy in libgRSAUtils when this changes */ +const char *rsaStatusStr(RSAStatus rrtn) +{ + static char unknownStr[100]; + + if(rrtn < RSA_RETURN_BASE) { + if(rrtn == RSA_Success) { + return "RSA_Success"; + } + else { + /* libGiants error */ + return GIReturnString((GIReturn)rrtn); + } + } + switch(rrtn) { + case RSA_BadKeyData: + return "RSA_BadKeyData"; + case RSA_ParamErr: + return "RSA_ParamErr"; + case RSA_IncompleteKey: + return "RSA_IncompleteKey"; + case RSA_VerifyFail: + return "RSA_VerifyFail"; + case RSA_BadSigFormat: + return "RSA_BadSigFormat"; + case RSA_BadDataFormat: + return "RSA_BadDataFormat"; + case RSA_BadKeyFormat: + return "RSA_BadKeyFormat"; + case RSA_InternalError: + return "RSA_InternalError"; + case RSA_Overflow: + return "RSA_Overflow"; + case RSA_Unimplemented: + return "RSA_Unimplemented"; + case RSA_IllegalKeySize: + return "RSA_IllegalKeySize"; + case RSA_OtherError: + return "RSA_OtherError"; + default: + sprintf(unknownStr, "Unknown (%d)", rrtn); + return unknownStr; + } +} + + +#endif /* NDEBUG */ diff --git a/lib/pki/libgRSA/libgRSA_priv.h b/lib/pki/libgRSA/libgRSA_priv.h new file mode 100644 index 0000000..4f96d10 --- /dev/null +++ b/lib/pki/libgRSA/libgRSA_priv.h @@ -0,0 +1,56 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * libgRSA_priv.h - private libRSA routines. + * + * Created Aug. 10 2005 by Doug Mitchell. + */ + +#ifndef _LIBGRSA_RSA_PRIV_H_ +#define _LIBGRSA_RSA_PRIV_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* make sure NDEBUG is #define for deployment build! */ +#define NDEBUG +#ifdef NDEBUG + +#define rsaDebug(s) +#define rsaDebug1(s, a) +#define rsaDebug2(s, a, b) +#define RSAASSERT(s) + +#else /* !NDEBUG */ + +#include +#include + +#define rsaDebug(s) printf(s) +#define rsaDebug1(s, a) printf(s, a) +#define rsaDebug2(s, a, b) printf(s, a, b) + +#define RSAASSERT(s) assert(s) + + +#endif /* !NDEBUG */ + +/* convert a libGiants GIReturn to our own RSAStatus */ +extern RSAStatus giantStatusToRSA(GIReturn grtn); + +/* convert a libDER DERReturn to our own RSAStatus */ +extern RSAStatus derStatusToRSA(DERReturn drtn); + +/* convert an RSAStatus to a string (disabled for NDEBUG builds) */ +extern const char *rsaStatusStr(RSAStatus rrtn); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBGRSA_RSA_PRIV_H_ */ diff --git a/lib/pki/libgRSA/rsaGiantKey.c b/lib/pki/libgRSA/rsaGiantKey.c new file mode 100644 index 0000000..e425d18 --- /dev/null +++ b/lib/pki/libgRSA/rsaGiantKey.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * rsaGiantKey.c + * + * Created Aug. 9 2005 by Doug Mitchell. + */ + +#include +#include +#include + +/* call this after declaring a local lgiant and before using it */ +void localSmallGiantAlloc(rsaSgiant *g) +{ + initGiant(&g->g, RSA_SMALL_GIANT_DIGITS, g->_n_); +} + +/* clear an RSA{Pub,Priv}GiantKey */ +void rsaClearPubGKey( + RSAPubGiantKey *gKey) +{ + Bzero(gKey, sizeof(*gKey)); +} + +void rsaClearPrivGKey( + RSAPrivGiantKey *gKey) +{ + Bzero(gKey, sizeof(*gKey)); +} + +void rsaClearFullGiantKey( + RSAFullGiantKey *gKey) +{ + Bzero(gKey, sizeof(*gKey)); +} + + diff --git a/lib/pki/libgRSA/rsaGiantKey.h b/lib/pki/libgRSA/rsaGiantKey.h new file mode 100644 index 0000000..e28e9aa --- /dev/null +++ b/lib/pki/libgRSA/rsaGiantKey.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * rsaGiantKey.h - internal format of RSA keys, constructors for them. + */ + +#ifndef _LIBGRSA_RSA_GIANT_KEY_H_ +#define _LIBGRSA_RSA_GIANT_KEY_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * A custom "small" giant used to represent some individual fields in a + * RSAFullGiantKey. These fields are typically half the size of the + * modulus. We use MAX_PRIME_SIZE/2 + 1 digits for these. + */ +#define RSA_SMALL_GIANT_DIGITS ((MAX_PRIME_SIZE_DIGITS + 3) / 2) + +typedef struct { + giantStruct g; + giantDigit _n_[RSA_SMALL_GIANT_DIGITS]; +} rsaSmallGiantStruct; + +typedef rsaSmallGiantStruct rsaSgiant; /* for heap allocation */ + +/* call this after declaring a local lgiant and before using it */ +extern void localSmallGiantAlloc(rsaSgiant *g); + +/* RSA public key form native to this library */ +typedef struct { + lgiant e; /* public exponent */ + lgiant n; /* modulus */ + lgiant recip; /* reciprocal of n */ +} RSAPubGiantKey; + +/* RSA private key form native to this library */ +typedef struct { + rsaSgiant p; + rsaSgiant q; + rsaSgiant dp; + rsaSgiant dq; + rsaSgiant qInv; + + /* reciprocals of p and q */ + rsaSgiant pRecip; + rsaSgiant qRecip; +} RSAPrivGiantKey; + +/* + * A full RSA key pair. + */ +typedef struct { + RSAPubGiantKey pub; + lgiant d; /* private exponent */ + RSAPrivGiantKey priv; +} RSAFullGiantKey; + +/* clear an RSA*GiantKey */ +void rsaClearPubGKey( + RSAPubGiantKey *gKey); + +void rsaClearPrivGKey( + RSAPrivGiantKey *gKey); + +void rsaClearFullGiantKey( + RSAFullGiantKey *gKey); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBGRSA_RSA_GIANT_KEY_H_ */ + diff --git a/lib/pki/libgRSA/rsaPadding.c b/lib/pki/libgRSA/rsaPadding.c new file mode 100644 index 0000000..7f18f9a --- /dev/null +++ b/lib/pki/libgRSA/rsaPadding.c @@ -0,0 +1,532 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * rsaPadding.c - PKCS1 and OAEP padding support. + * + * Created Aug. 10 2005 by Doug Mitchell. + */ + +#include +#include +#include +#include +#include +#include + +/* + * RP_None padding routines - just check length and convert between + * byte array and giant + */ +RSAStatus rsaAddNoPadding( + const unsigned char *plainText, + gi_uint16 plainTextLen, + giant result) /* RETURNED */ +{ + GIReturn rtn = deserializeGiant(result, plainText, plainTextLen); + return giantStatusToRSA(rtn); +} + +RSAStatus rsaCheckNoPadding( + giant decryptResult, + unsigned char *plainText, /* data RETURNED here */ + gi_uint16 *plainTextLen) /* IN/OUT */ +{ + GIReturn rtn = serializeGiant(decryptResult, + (gi_uint8 *)plainText, plainTextLen); + return giantStatusToRSA(rtn); +} + +#if RSA_VERIFY_ENABLE + +/* + * Decrement digit ptr and byte index thru a giant's n[], + * going from m.s. byte to l.s. byte. + * -- n[0] is the l.s. digit of a giant + * -- (n[0] & 0xff) is the l.s. byte of that digit + */ +static inline void decrGiantPtrs( + giantDigit **digitPtr, + gi_uint8 *byteDex) +{ + if(*byteDex == 0) { + /* roll to m.s. byte of next l.s. digit */ + (*digitPtr)--; + *byteDex = GIANT_BYTES_PER_DIGIT - 1; + } + else { + (*byteDex)--; + } +} + +/* fetch specified byte from giant's n[] array */ +static inline gi_uint8 getGiantByte( + giantDigit *digitPtr, + gi_uint8 byteDex) +{ + giantDigit digit = *digitPtr; + digit >>= (byteDex * 8); + return (gi_uint8)digit; +} + +/* + * How many bytes are left between current digit/byte markers and + * the start of the giant's data? + */ +static inline gi_size bytesLeftInGiant( + giant g, + giantDigit *digitPtr, + gi_uint8 byteDex) +{ + GIASSERT(digitPtr >= g->n); + return ((digitPtr - g->n) * GIANT_BYTES_PER_DIGIT) + byteDex + 1; +} + + +/* + * Specialized "no padding" check for signature verify operation. + * We don't deserialize the decrypted giant; we do a byte-for- + * byte compare of the expected decrypted value against memory + * passed in to us, in-place in the decrypted giant. + * This saves two stack-allocated byte arrays, each of + * MAX_PRIME_SIZE_BYTES - one here, and one in RSA_SigVerify(). + * + * NOTE: using "no padding" option will not work if the first byte + * (the m.s. byte of the decryptResult giant) is zero; there is + * no way to verify leading zeroes as they got chopped off during + * the calculation. + */ +RSAStatus rsaCheckNoPaddingForSigVfy( + giant decryptResult, + const unsigned char *expectPlainText, + gi_uint16 expectPlainTextLen) +{ + unsigned dex; + giantDigit *digitPtr; + gi_uint8 byteDex; + gi_uint8 giantByte; + gi_size bytesLeft; + + if((expectPlainText == NULL) || (decryptResult == NULL)) { + return RSA_InternalError; + } + if(expectPlainTextLen > MAX_PRIME_SIZE_BYTES) { + return RSA_Overflow; + } + if(decryptResult->sign == 0) { + if(expectPlainTextLen == 0) { + /* Well OK */ + return RSA_Success; + } + else { + rsaDebug("rsaCheckNoPaddingForSigVfy: empty decryptResult\n"); + return RSA_VerifyFail; + } + } + /* + * Prepare for scanning thru giant data, starting at the m.s. byte of the + * m.s. digit. + */ + digitPtr = &decryptResult->n[decryptResult->sign - 1]; + byteDex = GIANT_BYTES_PER_DIGIT - 1; + bytesLeft = bytesLeftInGiant(decryptResult, digitPtr, byteDex); + GIASSERT(bytesLeft != 0); + + /* find first non-zero byte */ + for(;;) { + giantByte = getGiantByte(digitPtr, byteDex); + if(giantByte != 0) { + break; + } + decrGiantPtrs(&digitPtr, &byteDex); + if(--bytesLeft == 0) { + rsaDebug("rsaCheckNoPaddingForSigVfy: non nonzero data found\n"); + return RSA_VerifyFail; + } + } + + if(bytesLeft != expectPlainTextLen) { + rsaDebug("rsaCheckNoPaddingForSigVfy: length mismatch\n"); + return RSA_VerifyFail; + } + + for(dex=0; dex= randSize) { + require_noerr(rstatus = rngCallback(scratch, randSize), errOut); + six = 0; + } + + gi_uint8 b = scratch[six++]; + if (b) { + randBuf[dix] = b; + break; + } + } + } + +errOut: + /* Clear out scratch cause we like being paranoid. */ + Bzero(scratch, randSize); + return rstatus; +} + +/* + * Given plaintext or data to be signed, add PKCS1 padding and place + * the result in a giant. + */ +RSAStatus rsaAddPkcs1Padding( + const unsigned char *plainText, + gi_uint16 plainTextLen, + gi_uint16 totalLength, /* intended total length */ + unsigned char padMarker, /* RSA_PKCS1_PAD_{SIGN,ENCRYPT} */ + RSARngCallback *rngCallback, /* required for RP_PKCS1, RP_OAEP */ + giant result) +{ + unsigned char giantBytes[MAX_PRIME_SIZE_BYTES]; + unsigned char *cp = giantBytes; + unsigned dex; + GIReturn grtn; + RSAStatus rrtn = RSA_Success; + unsigned psLen; /* length of variable length padding string */ + + if((plainText == NULL) || (result == NULL)) { + return RSA_InternalError; + } + if(totalLength > MAX_PRIME_SIZE_BYTES) { + return RSA_Overflow; + } + if(plainTextLen > (totalLength - PKCS1_MIN_PAD_LEN)) { + rsaDebug("rsaAddPkcs1Padding: insuffient space for padding\n"); + return RSA_Overflow; + } + if((padMarker == RSA_PKCS1_PAD_ENCRYPT) && (rngCallback == NULL)) { + rsaDebug("rsaAddPkcs1Padding: RNG required\n"); + return RSA_ParamErr; + } + + *cp++ = 0; + *cp++ = padMarker; + + /* + * RSA_PKCS1_PAD_SIGN: pad with 0xff + * RSA_PKCS1_PAD_ENCRYPT: pad with random nonzero data + */ + psLen = totalLength - plainTextLen - 3; + if(padMarker == RSA_PKCS1_PAD_ENCRYPT) { + /* Fill cp with psLen random nonzero bytes. */ + rrtn = nonZeroRandom(rngCallback, cp, psLen); + if (rrtn) { + rsaDebug1("rsaAddPkcs1Padding: nonZeroRandom returned: %s\n", + rsaStatusStr(rrtn)); + return rrtn; + } + + cp += psLen; + } else { + for(dex=0; dex (MAX_PRIME_SIZE_BYTES - PKCS1_MIN_PAD_LEN)) { + return RSA_Overflow; + } + GI_CHECK_SP("rsaCheckPkcs1PaddingForSigVfy"); + + /* + * Prepare for scanning thru giant data, starting at the m.s. byte of the + * m.s. digit. + */ + digitPtr = &decryptResult->n[decryptResult->sign - 1]; + byteDex = GIANT_BYTES_PER_DIGIT - 1; + + /* + * Padding of the pre-encrypted data is like so: + * + * one byte zero + * one byte pad marker (RSA_PKCS1_PAD_SIGN) + * 8 bytes of 0xff + * one byte of zero + * then the to-be-encrypted data + * + * Leading zeroes are optional: + * + * 1. If: + * -- The key's modulus size is not aligned to a giantDigit, AND + * -- the m.s. byte of decryptResult - which was set to zero when + * the padding was created - is the only byte in the m.s. + * giantDigit (i.e., num_bytes_of_decrypted_data mod + * sizeof(giantDigit) equals one, + * OR + * -- sizeof(giantDigit) == 1 byte + * + * THEN the leading zero will not appear in decryptResult. + * + * 2. If: + * -- The key's modulus size is not aligned to a giantDigit, AND + * -- The m.s. byte of decryptResult is neither the l.s. or the + * m.s. byte of the m.s. giantDigit, + * + * THEN then we'll see extra zeroes at the m.s. digit in decryptResult. + */ + for(;;) { + giantByte = getGiantByte(digitPtr, byteDex); + if(giantByte != 0) { + break; + } + decrGiantPtrs(&digitPtr, &byteDex); + if(digitPtr == decryptResult->n) { + /* + * rolled back to first digit, not enough for 11 bytes of + * padding. + * FIXME rewrite this when sizeof(giantDigit) > 11. :-) + */ + rsaDebug("rsaCheckPkcs1PaddingForSigVfy: no padMarker\n"); + return RSA_BadSigFormat; + } + } + /* we're at the first nonzero byte */ + if(giantByte != RSA_PKCS1_PAD_SIGN) { + rsaDebug("rsaCheckPkcs1PaddingForSigVfy: bad padMarker\n"); + return RSA_BadSigFormat; + } + decrGiantPtrs(&digitPtr, &byteDex); + bytesLeft = bytesLeftInGiant(decryptResult, digitPtr, byteDex); + if(bytesLeft < 9) { + rsaDebug("rsaCheckPkcs1PaddingForSigVfy: no space left for padding\n"); + return RSA_BadSigFormat; + } + + /* + * Now skip over 0xff bytes and then one byte of zero. + */ + do { + giantByte = getGiantByte(digitPtr, byteDex); + decrGiantPtrs(&digitPtr, &byteDex); + bytesLeft--; + if(giantByte == 0xff) { + numFFs++; + continue; + } + else if(giantByte == 0) { + if(numFFs < 8) { + rsaDebug("rsaCheckPkcs1PaddingForSigVfy: insufficient padding\n"); + return RSA_BadSigFormat; + } + /* start of decrypted data */ + break; + } + else { + rsaDebug("rsaCheckPkcs1PaddingForSigVfy: bad padding (not ff)\n"); + return RSA_BadSigFormat; + } + } while(bytesLeft != 0); + + /* We're at the first decrypted data; compare with caller's expected data */ + if(bytesLeft != expectPlainTextLen) { + rsaDebug("rsaCheckPkcs1PaddingForSigVfy: length mismatch\n"); + return RSA_VerifyFail; + } + + for(dex=0; dex +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* PKCS1 padding markers */ +#define RSA_PKCS1_PAD_SIGN 0x01 +#define RSA_PKCS1_PAD_ENCRYPT 0x02 + +/* + * RP_None padding routines - just check length and convert between + * byte array and giant + */ +RSAStatus rsaAddNoPadding( + const unsigned char *plainText, + gi_uint16 plainTextLen, + giant result); /* RETURNED */ + +RSAStatus rsaCheckNoPadding( + giant decryptResult, + unsigned char *plainText, /* data RETURNED here */ + gi_uint16 *plainTextLen); /* IN/OUT */ + +/* + * Specialized "no padding" check for signature verify operation. + * We don't deserialize the decrypted giant; we do a byte-for- + * byte compare of the expected decrypted value against memory + * passed in to us, in-place in the decrypted giant. + * This saves two stack-allocated byte arrays, each of + * MAX_PRIME_SIZE_BYTES - one here, and one in RSA_SigVerify(). + */ +RSAStatus rsaCheckNoPaddingForSigVfy( + giant decryptResult, + const unsigned char *expectPlainText, + gi_uint16 expectPlainTextLen); + +RSAStatus rsaAddPkcs1Padding( + const unsigned char *plainText, + gi_uint16 plainTextLen, + gi_uint16 totalLength, /* intended total length */ + unsigned char padMarker, /* RSA_PKCS1_PAD_{SIGN,ENCRYPT} */ + RSARngCallback *rngCallback, /* required for RP_PKCS1, RP_OAEP */ + giant result); + +/* + * Given decrypted plaintext in the form of a giant, which should + * be the same size as n, verify proper PKCS1 padding and copy + * resulting plaintext and length into caller-supplied buffer. + * On entry, *plainTextLen indicates the size of the available + * plaintext buffer. On return, *plainTextLen indicates the + * number of valid bytes of plaintext recovered. + */ +RSAStatus rsaCheckPkcs1Padding( + giant decryptResult, + unsigned char padMarker, /* RSA_PKCS1_PAD_{SIGN,ENCRYPT} */ + unsigned char *plainText, /* data RETURNED here */ + gi_uint16 *plainTextLen); /* IN/OUT */ + +/* + * Specialized PKCS1 padding check for signature verify operation. + * We don't deserialize the decrypted giant; we check for padding + * in place (in the decrypted giant's n[]), AND we do a byte-for- + * byte compare of the expected decrypted value against memory + * passed in to us. This saves two stack-allocated byte arrays, + * each of MAX_PRIME_SIZE_BYTES - one here, and one in RSA_SigVerify(). + * + * Returns: + * -- RSA_Success, padding good and result compares OK + * -- RSA_VerifyFail, padding good but data miscompare + * -- RSA_BadSigFormat, bad padding + * -- RSA_Overflow, expectPlainText too big for this key with PKCS1 padding + * -- else usual gross errors + */ +RSAStatus rsaCheckPkcs1PaddingForSigVfy( + giant decryptResult, + const unsigned char *expectPlainText, + gi_uint16 expectPlainTextLen); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBGRSA_RSA_PADDING_H_ */ + diff --git a/lib/pki/libgRSA/rsaRawKey.c b/lib/pki/libgRSA/rsaRawKey.c new file mode 100644 index 0000000..e148219 --- /dev/null +++ b/lib/pki/libgRSA/rsaRawKey.c @@ -0,0 +1,120 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * rsaRawKey.h - Typedefs and declarations for RSA keys in raw format + * + * Created Nov. 29 2005 by Doug Mitchell. + */ + +#include +#include +#include +#include + +#ifndef RSA_RAW_KEY_ENABLE +#error Please define RSA_RAW_KEY_ENABLE. +#endif + +#if RSA_RAW_KEY_ENABLE +#if RSA_PUB_KEY_ENABLE || RSA_PRIV_KEY_ENABLE + +/* init an lgiant, fill it with incoming bytes */ +static RSAStatus rsaSetGiant( + lgiant *g, + unsigned char *c, + gi_uint16 cLen) +{ + localGiantAlloc(g); + if(deserializeGiant(&g->g, c, cLen)) { + return RSA_BadKeyData; + } + return RSA_Success; +} + +#endif /* RSA_PUB_KEY_ENABLE || RSA_PRIV_KEY_ENABLE */ + +#if RSA_PUB_KEY_ENABLE + +/* raw (n, e) in API form --> public RSAGiantKey */ +RSAStatus rsaInitPubGKey( + const RSAPubKey *apiKey, + RSAPubGiantKey *pubKey) +{ + if((apiKey == NULL) || (pubKey == NULL)) { + return RSA_ParamErr; + } + if((apiKey->e == NULL) || (apiKey->n == NULL)) { + return RSA_IncompleteKey; + } + if(rsaSetGiant(&pubKey->n, apiKey->n, apiKey->nLen)) { + return RSA_BadKeyData; + } + if(rsaSetGiant(&pubKey->e, apiKey->e, apiKey->eLen)) { + return RSA_BadKeyData; + } + + localGiantAlloc(&pubKey->recip); + if(apiKey->recip) { + /* caller provided reciprocal */ + if(deserializeGiant(&pubKey->recip.g, apiKey->recip, apiKey->recipLen)) { + return RSA_BadKeyData; + } + } + /* else make_recip called lazily when the key is actually used */ + return RSA_Success; +} + +#endif /* RSA_PUB_KEY_ENABLE */ + +#if RSA_PRIV_KEY_ENABLE + +/* init an rsaSgiant, fill it with incoming bytes */ +static RSAStatus rsaSetSGiant( + rsaSgiant *g, + unsigned char *c, + gi_uint16 cLen) +{ + localSmallGiantAlloc(g); + if(deserializeGiant(&g->g, c, cLen)) { + return RSA_BadKeyData; + } + return RSA_Success; +} + +/* raw (p, q, dp, dq, qInv) --> private RSAPrivCRTGiantKey */ +RSAStatus rsaInitPrivGKey( + const RSAPrivKey *apiKey, + RSAPrivGiantKey *privKey) +{ + if((apiKey == NULL) || (privKey == NULL)) { + return RSA_ParamErr; + } + if((apiKey->p == NULL) || (apiKey->q == NULL) || (apiKey->dp == NULL) || + (apiKey->dq == NULL) || (apiKey->qInv == NULL)) { + return RSA_ParamErr; + } + if(rsaSetSGiant(&privKey->p, apiKey->p, apiKey->pLen)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->q, apiKey->q, apiKey->qLen)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->dp, apiKey->dp, apiKey->dpLen)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->dq, apiKey->dq, apiKey->dqLen)) { + return RSA_BadKeyData; + } + if(rsaSetSGiant(&privKey->qInv, apiKey->qInv, apiKey->qInvLen)) { + return RSA_BadKeyData; + } + + /* pRecip, qRecip evaluated lazily */ + localSmallGiantAlloc(&privKey->pRecip); + localSmallGiantAlloc(&privKey->qRecip); + + return RSA_Success; +} + +#endif /* RSA_PRIV_KEY_ENABLE */ +#endif /* RSA_RAW_KEY_ENABLE */ diff --git a/lib/pki/libgRSA/rsaRawKey.h b/lib/pki/libgRSA/rsaRawKey.h new file mode 100644 index 0000000..a465f8f --- /dev/null +++ b/lib/pki/libgRSA/rsaRawKey.h @@ -0,0 +1,72 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * rsaRawKey.h - Typedefs and declarations for RSA keys in raw format + * + * Created Nov. 29 2005 by Doug Mitchell. + */ + +#ifndef _LIBGRSA_RSA_RAW_KEY_H_ +#define _LIBGRSA_RSA_RAW_KEY_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Generic forms of RSA keys, public and private forms. + * All fields are in raw, unformatted binary format, as a byte pointer + * and a length, with the most significant byte first. + * + * The recip field in RSAPubKey is optional; it's the reciprocal of + * the modulus n. Providing this field is an optimization; if it's not + * provided, it will be calculated on the fly at some runtime cost. The + * recip field is not sensitive; it can be distributed and stored with + * no more security concern than the modulus itself. Providing the recip + * field yields approximately 28% speedup on public key operations. + * + * See libgRSAUtils/rsaKeyGen.[ch] or Tools/rsaKeyTool for info + * on obtaining the reciprocal. + */ +typedef struct { + unsigned char *n; /* modulus */ + gi_uint16 nLen; + unsigned char *recip; /* reciprocal of modulus */ + gi_uint16 recipLen; + unsigned char *e; /* public exponent */ + gi_uint16 eLen; +} RSAPubKey; + +/* Private key, CRT form */ +typedef struct { + unsigned char *p; + gi_uint16 pLen; + unsigned char *q; + gi_uint16 qLen; + unsigned char *dp; + gi_uint16 dpLen; + unsigned char *dq; + gi_uint16 dqLen; + unsigned char *qInv; + gi_uint16 qInvLen; +} RSAPrivKey; + +/* raw (n, e) --> public RSAPubGiantKey */ +RSAStatus rsaInitPubGKey( + const RSAPubKey *apiKey, + RSAPubGiantKey *pubKey); + +/* raw (p, q, dp, dq, qInv) --> private RSAPrivGiantKey */ +RSAStatus rsaInitPrivGKey( + const RSAPrivKey *apiKey, + RSAPrivGiantKey *privKey); + + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBGRSA_RSA_CORE_H_ */ diff --git a/lib/pki/libgRSA/rsaTypes.h b/lib/pki/libgRSA/rsaTypes.h new file mode 100644 index 0000000..ae6708d --- /dev/null +++ b/lib/pki/libgRSA/rsaTypes.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */ + +/* + * rsaTypes.h - typedefs for libgRSA + * + * Created Nov. 30 2005 by Doug Mitchell. + */ + +#ifndef _LIBRSA_RSA_TYPES_H_ +#define _LIBRSA_RSA_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * Error returns from this library. + */ +typedef enum { + RSA_Success = 0, + RSA_BadKeyData = RSA_RETURN_BASE, /* bad raw key data */ + RSA_ParamErr, /* parameter error */ + RSA_IncompleteKey, /* one or more RSAKey fields missing */ + RSA_VerifyFail, /* signature verification failed */ + RSA_BadSigFormat, /* improperly formatted signature */ + RSA_BadDataFormat, /* improperly formatted ciphertext */ + RSA_BadKeyFormat, /* improperly formatted public key */ + RSA_InternalError, /* internal error */ + RSA_Overflow, /* insufficent buffer provided */ + RSA_Unimplemented, /* unimplemented in this configuration */ + RSA_IllegalKeySize, /* Unsupported key size */ + RSA_OtherError +} RSAStatus; + +/* + * Padding styles + */ +typedef enum { + RP_None = 0, /* no padding */ + RP_PKCS1, /* PKCS1, for signing and encrypting */ + RP_OAEP /* OAEP, for encrypting only */ +} RSAPadding; + +/* + * Random number callback function. The caller of RSA_Encrypt or + * RSA_GenKeyPair supplies pseudorandom data for OAEP or PKCS1 padding + * generation or for key generation, via this callback. + * + * The destination of the random data is *randBuf, which is memory owned + * and maintained by the caller of this function. + * + * This function should return nonzero if it failed to obtain the number of + * random bytes requested. + */ +typedef int (RSARngCallback)( + gi_uint8 *randBuf, /* random data goes here */ + gi_uint16 randSize); /* byte count */ + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBRSA_RSA_TYPES_H_ */ + diff --git a/lib/pki/library.mk b/lib/pki/library.mk new file mode 100644 index 0000000..626d3b1 --- /dev/null +++ b/lib/pki/library.mk @@ -0,0 +1,47 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBPKI_DIR := $(GET_LOCAL_DIR) +LIBPKI_BUILD := $(call TOLIBDIR,$(LIBPKI_DIR)/LIBPKI.a) +COMMONLIBS += LIBPKI + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +GLOBAL_INCLUDES += $(LIBPKI_DIR) + +LIBPKI_OBJS := \ + $(LIBPKI_DIR)/libDER/DER_CertCrl.o \ + $(LIBPKI_DIR)/libDER/DER_Decode.o \ + $(LIBPKI_DIR)/libDER/DER_Digest.o \ + $(LIBPKI_DIR)/libDER/DER_Encode.o \ + $(LIBPKI_DIR)/libDER/DER_Keys.o \ + $(LIBPKI_DIR)/libDER/oids.o \ + $(LIBPKI_DIR)/libGiants/giantExternal.o \ + $(LIBPKI_DIR)/libGiants/giantIntegers.o \ + $(LIBPKI_DIR)/libGiants/giantMemutils.o \ + $(LIBPKI_DIR)/libGiants/giantPort_C.o \ + $(LIBPKI_DIR)/libGiants/giantMod.o \ + $(LIBPKI_DIR)/libgRSA/rsaGiantKey.o \ + $(LIBPKI_DIR)/libgRSA/libgRSA.o \ + $(LIBPKI_DIR)/libgRSA/rsaPadding.o \ + $(LIBPKI_DIR)/libgRSA/libgRSA_priv.o \ + $(LIBPKI_DIR)/libgRSA/libgRSA_DER.o \ + $(LIBPKI_DIR)/libgRSA/rsaRawKey.o + + +LIBPKI_OBJS := $(call TOLIBOBJDIR,$(LIBPKI_OBJS)) + +$(LIBPKI_BUILD): $(LIBPKI_OBJS) + +ALL_DEPS += $(LIBPKI_OBJS:%o=%d) + +endif diff --git a/lib/pki/rules.mk b/lib/pki/rules.mk new file mode 100644 index 0000000..0005361 --- /dev/null +++ b/lib/pki/rules.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PKI=1 \ + PKI_CHECK_ANCHOR_BY_SHA1=0 \ + PKI_APPLE_ROOT_CA=1 \ + PKI_CHECK_KEY_IDS=1 + +LIBRARY_MODULES += \ + lib/pki + +GLOBAL_INCLUDES += $(LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/chain-validation.o diff --git a/lib/pki/tests/fake-hierarchy-img3-test.txt b/lib/pki/tests/fake-hierarchy-img3-test.txt new file mode 100644 index 0000000..7da2034 --- /dev/null +++ b/lib/pki/tests/fake-hierarchy-img3-test.txt @@ -0,0 +1,86 @@ + +Getting set up with the fake hierarchy: + +Modify lib/pki/rules.mk: set PKI_APPLE_ROOT_CA=0 to switch to the fake hierarchy and build a debug app test, ie. iBSS. +Load the various images +Get the keys and certs and CSRs from lib/pki/fake_ca.h for the intermediate: intermediate-cert.pem intermediate-key.pem, put them into separate .pem files. +Convert intermediate-cert.pem to der using openssl x509 -in intermediate-cert.pem -outform der -out intermediate-cert.der. + +The USB_SERIAL_NUMBER header contains the board specific info, you may need to modify. + +Useful images to create: + +Images that try to set the current settings. Production status, chip and security domain should never be set by image itself. + +img-dev-sdom-chip --development --chipType 0x8720 --domain darwin +img-dev-sdom-chip-epoch --development --chipType 0x8720 --domain darwin --epoch 0 +img-dev-sdom-chip-boardid --development --chipType 0x8720 --domain darwin --boardID 0 +img-dev-sdom-chip-uniqueid --development --chipType 0x8720 --domain darwin --uniqueID 0x???? + +One image to make sure the production switch works as expected. Modify chipid_get_production_mode in platform/*/chipid/chipid.c to simulate a production unit. + +img-prod-sdom-chip --production --chipType 0x8720 --domain darwin + +One leaf for the current settings: + +spec-dev-8720-darwin --development --chipType 0x8720 --domain darwin + +Leafs that modifies one of the settings away from the default (always supposed to come from the cert) + +spec-dev-8720-manu --development --chipType 0x8720 --domain manufacturer +spec-dev-8920-darwin --development --chipType 0x8920 --domain darwin +spec-prod-8720-darwin --production --chipType 0x8720 --domain darwin + +Leafs that modify epoch, boardid or ecid, away from the default (okay for the image to specify if cert doesn't) + +spec-dev-8720-darwin-wrong-epoch --development --chipType 0x8720 --domain darwin --epoch 1 +spec-dev-8720-darwin-wrong-boardid --development --chipType 0x8720 --domain darwin --boardID 1 +spec-dev-8720-darwin-wrong-ecid --development --chipType 0x8720 --domain darwin --uniqueID 0 + +Tests of image and leaf combinations: + +spec-dev-8720-darwin img-dev-sdom-chip OK +spec-dev-8720-manu img-dev-sdom-chip FAIL +spec-dev-8920-darwin img-dev-sdom-chip FAIL +spec-prod-8720-darwin img-dev-sdom-chip OK +spec-prod-8720-darwin img-dev-sdom-chip OK * board set to return production +spec-dev-8720-darwin img-prod-sdom-chip FAIL * board set to return production +spec-dev-8720-darwin-wrong-epoch img-dev-sdom-chip-epoch FAIL +spec-dev-8720-darwin-wrong-boardid img-dev-sdom-chip-boardid FAIL +spec-dev-8720-darwin-wrong-ecid img-dev-sdom-chip-uniqueid FAIL (w/ 32 bit clipped ECID) + +Make img3 specs and put them into the extensions.txt file used during signing: + +make-img3-specs is a shell script that converts img3 blobs into spec extensions to be used when signing. + +make-img3-specs > extensions.txt + +Generating one key that will be shared for all issued leafs: + +openssl req -newkey rsa:1024 -sha1 -days 365 -sha1 \ + -subj "/C=US/O=Apple Inc./OU=Apple Secure Boot Certification Authority/CN=S5L8900 Secure Boot" \ + -nodes -out leaf-csr.pem -keyout leaf-key.pem +(note: common name is not checked in leaf - platform is derived from embedded img3) + +Sign all leafs: + +for i in spec-dev-8720-darwin spec-dev-8720-manu spec-dev-8920-darwin spec-prod-8720-darwin \ + spec-dev-8720-darwin-wrong-epoch spec-dev-8720-darwin-wrong-boardid spec-dev-8720-darwin-wrong-ecid; +do + openssl x509 -req -sha1 -in leaf-csr.pem -CA intermediate-cert.pem -CAkey intermediate-key.pem \ + -set_serial 42 -outform der -out $i.der -extfile extensions.txt -extensions $i +done + +Create and sign images: + +to_binary_hash.c is an emergency hack for conversion from image3maker output. + +The image is generated and signed in the first steps: +image3maker --create --imagefile iBSS.img3 --type ibot --data iBSS.bin +image3maker --hashForSigning --imagefile iBSS.img3 | to_binary_hash > iBSS.hash +openssl rsautl -sign -inkey leaf-key.pem -in iBSS.hash -out iBSS.sig + +It can be tested with various leafs (because all use the same key): +cat intermediate-cert.der spec-dev-8720-darwin.der > chain.der +image3maker --signWithData --signWithSignature iBSS.sig --signWithCertChain chain.der --imagefile iBSS.img3 + diff --git a/lib/pki/tests/intermediate-cert.der b/lib/pki/tests/intermediate-cert.der new file mode 100644 index 0000000000000000000000000000000000000000..d1343e5f6b424c4113c80d2d08f2cd8b6e77eb1a GIT binary patch literal 953 zcmXqLV%}=d#58vSGZP~d6Qh6uFB_*;n@8JsUPeY%RtAG4Lv903Hs(+kHesgFU_)U8 zK@f*an9H%CASYG9GcQ@sP|ZLEB*-l+3lVfqEh@=O%S=uz$;{7Fa4ap!$S=w)sWcQb z5CN%U7UqSh3(C(gQE+xNkQ3)MFgG+ZurM$*urM}`0&+o2b12uKj*4zDGBAL+K@;MJ z;MC;OqErPZuv4(R+n|Y22{~98Ss9p{82K51;#^EkjEoF>k8Wh$bY8!3?~ax6XB-!N z-Qeh#AAB?C>HUvOCmx-7aNEpjuY;BL7ag|T@w_pJjV<=)j+{x?)b32mR(-p->BSe3 z)svTnO&s2LEc%=l^=uiY<|e+2x}*1P{?e}f9mA72o##bWE^K-W5?X ~{!R+leV;TrX76Km^S6Sm#ezz&#h<@5y#8zA>dkq4*+<0Mnd8J6c5dGF z{pYILfn2$c{rU@^r%Hu7DK700{xwC(z1(QVs@+qyW!W}JUQk$nj5mXKk$bE}@wN_c E039`F)Bpeg literal 0 HcmV?d00001 diff --git a/lib/pki/tests/intermediate-key.pem b/lib/pki/tests/intermediate-key.pem new file mode 100644 index 0000000..fa1e97f --- /dev/null +++ b/lib/pki/tests/intermediate-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvcWxBbLPL3G9uKlfzEGg9bBBTm9T2Wzl3/GlkcWZwbaZlutT +Ir9ywzm454FSBgZd+bhsktYm3JJrJe29guj0FGN0x8AnBg0dzqBixGNNwA8YMPEn +SxCvbtHxL90QAyv+bggx1MD4eXbuPMpqn3hgHlLqbMVQsUj8RG95wkRjRfHbQutc +zqenlz69mxOUd1HY5LzLu+yu2Dm0FSPjwzCadPTZ3gPos8lBvHt5B2Ty/+6tXHhB +YHq4FofmJY0ADRoQrm4Ml8oHtu94Djh+UCtXyC8G36to/j5C+FTYB6cPY33hTTlc ++8OPBzijYp1h7lrcLvafpfWIZAXbTGg4ldxvMwIDAQABAoIBAQCvUe5DN3iVel0u +NrwcNh2AHb+XuN4cJrEQfWzbCVUNU6b9eJarqXdayP78Ucr3afZz+F/GIDZy3IpE +1iiYwqKMG34N9IWY35FEDYRxrtRrtQZCYOhOPzH0DdzmvTJH2+MIwGVZCpYDkU5z +twVeIpWaLjwJFRmBT85PYzV3tjqIqFnIzQhU8CRb52MFsyvTSpsycPAaLbnZ2wr2 +KT9gOtCv61SKuTqPm2NhrYL34lJCHORySBe4Ts5vmjX75pBd00eDFTz6Fzwo9ePk +65nV3Vf7CKfqXLyV8ZHLU5xoMaPYvEY/mb1W1J+IsZ77juPAnQQ/aYqdUTDkjsq4 +F5nJ3PlBAoGBAO5Z44eGsKclr1sVNo+QAchZqYSyyFKojKfnZHWztIfXdR9xZksg +zXSPQ0EbGdVK+ETDNZ4FWMCbllx69lLcnig8CN/6XKsKvjkw2mu0aS0I34RmozHo +mk2UV7KN3BLN8n7LSl1nucnI0mLFjZYpBQB/fnCS8F03TSDU97WEoupDAoGBAMvS +9LvcgfOUzIVD/MIJeYYxRJnroUcSijqs3Pp9ReWzRie9W7FOzM4gsSIs/wZh4dce +XIgS8mEobGTQH8dX5GostiKqJQq/E0Oa9i7QDmKOzVYqXjq+RuWu7GDmSb9kZ2g9 +03GItxlwODNIAgpVT3p4FMDvTR+DsDdDF9jrMXBRAoGAFAOKPnQJ208nxU8nsLBX +5fnZaSIV/hLXFLYyUkvPqeRmmkhMXZyYg+QPsqTS630LEcMOeoFabXnjC0rr6hNK +WHiKCjyckWQqiuTWQlr4xeZL1nND2sn8Qu1k28Jbq1yNsyXgza0LBa2ONOr/s48o +M12BQXSlKD6fhFU9o4lKoL8CgYEAoH3XnyUeXkJIWJcUK2VyfyvELL7RGzmKBnGe +/s4tf5UOJLSBwredpKExWQu9M7VXMyABFFR27fH6h9cpbrnSbZgPQnRe/ns+G/mk +52+EJC71mGd8Ex1IjgqSriom38GbewVTvQ49vpYSaq7EjIZoMrLjBJhpTetPkfQO +jwuCvkECgYAqKEjuLbX+nhzQkd6pvz/69fTL1VyHZlvzS/ZDnSuJWQ1EgJDv39Q8 +HLdFqzouNmfPU/dZiTPpOQTy2DYcRnFgwIhxKjrlSI8N3NtAjb5F78GixwfvsxVw ++jh3GPYgL9xXKDDgnaLdkhGNuHR2aEiAWpXlz5PURgSVMqR8tgKZnw== +-----END RSA PRIVATE KEY----- diff --git a/lib/pki/tests/make-img3-specs b/lib/pki/tests/make-img3-specs new file mode 100644 index 0000000..f07640d --- /dev/null +++ b/lib/pki/tests/make-img3-specs @@ -0,0 +1,39 @@ +#!/bin/zsh + +function make-img3-spec() +{ + TEMP_FILE=tmp$$ + image3maker --create --imagefile "${TEMP_FILE}.img3" --type cert $* + if [ $? -ne 0 ]; then exit 1; fi + FILESIZE=$(wc -c < "${TEMP_FILE}.img3") + if [ ${FILESIZE} -gt 127 ]; + then echo script too dumb to encode asn.1 length greater than 127 + exit 1 + fi + printf "1.2.840.113635.100.6.1.1=critical,DER:04:%02X" ${FILESIZE} + od -vt x1 "${TEMP_FILE}.img3" |\ + sed -e 's/^[0-9a-f]*//g' -e 's/ *\([0-9a-f][0-9a-f]\)/:\1/g' |\ + tr -d ' \n' + echo + rm ${TEMP_FILE}.img3 +} + +GENERAL_SPEC="keyUsage = digitalSignature +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always" + +echo "[ spec-dev-8720-darwin ]"; echo ${GENERAL_SPEC}; echo $(make-img3-spec --development --chipType 0x8720 --domain darwin ) +echo +echo "[ spec-dev-8720-manu ]"; echo ${GENERAL_SPEC}; echo $(make-img3-spec --development --chipType 0x8720 --domain manufacturer ) +echo +echo "[ spec-dev-8920-darwin ]"; echo ${GENERAL_SPEC}; echo $(make-img3-spec --development --chipType 0x8920 --domain darwin ) +echo +echo "[ spec-prod-8720-darwin ]"; echo ${GENERAL_SPEC}; echo $(make-img3-spec --production --chipType 0x8720 --domain darwin ) +echo +echo "[ spec-dev-8720-darwin-wrong-epoch ]"; echo ${GENERAL_SPEC}; echo $(make-img3-spec --development --chipType 0x8720 --domain darwin --epoch 1) +echo +echo "[ spec-dev-8720-darwin-wrong-boardid ]"; echo ${GENERAL_SPEC}; echo $(make-img3-spec --development --chipType 0x8720 --domain darwin --boardID 1 ) +echo +echo "[ spec-dev-8720-darwin-wrong-ecid ]"; echo ${GENERAL_SPEC}; echo $(make-img3-spec --development --chipType 0x8720 --domain darwin --uniqueID 0 ) +echo + diff --git a/lib/pki/tests/to_binary_hash.c b/lib/pki/tests/to_binary_hash.c new file mode 100644 index 0000000..d581e59 --- /dev/null +++ b/lib/pki/tests/to_binary_hash.c @@ -0,0 +1,43 @@ + +#include +#include +#include +#include + +// SHA1(iBSS.img3)= b51f78b42bb2d13281b4606b1446eb417625a657 + +unsigned char hex_to_bin(unsigned char hexchar) +{ + unsigned char val = hexchar - '0'; + if (val < 10) + return val; + val -= ('a' - '0' - 10); + if (val < 16) + return val; + return 255; +} + +int main(int argc, char *argv[]) +{ + const unsigned char sha1oid[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, + 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; + const char prefix[] = "SHA1(", postfix[] = ")= "; + char data[80]; + char *hash = fgets(data, sizeof(data), stdin); + if (0 == strncmp(prefix, hash, sizeof(prefix) - 1)) { + hash += sizeof(prefix) - 1; /* leave off null */ + hash = strstr(hash, postfix); + if (!hash) + return -1; + hash += sizeof(postfix) - 1; /* leave off null */ + + int i; + for(i=0; i < sizeof(sha1oid); i++) + putc(sha1oid[i], stdout); + + while (*hash && (*hash != '\n')) { + unsigned char value = hex_to_bin(*hash++) << 4 | hex_to_bin(*hash++); + putc(value, stdout); + } + } +} diff --git a/lib/power/power.c b/lib/power/power.c new file mode 100644 index 0000000..6973846 --- /dev/null +++ b/lib/power/power.c @@ -0,0 +1,1642 @@ +/* + * Copyright (C) 2008-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define POWERCONFIG_CHARGE_TABLE 1 +#include + +#ifndef NUM_DOCKS +#define NUM_DOCKS (1) +#endif + +enum { + kPowerSupplyBattery = 1, + kPowerSupplyFirewire = 2, + kPowerSupplyUSBHost = 3, + kPowerSupplyUSBBrick = 4, + kPowerSupplyUSBCharger = 5, + kPowerSupplyExternal = 6, + kPowerSupplyNum +}; + +bool force_usb_power = false; + +static unsigned int boot_battery_level = -1U; +static bool need_precharge; +static bool need_buttonwait; +static int power_supply_type[NUM_DOCKS]; +static int usb_brick_id[NUM_DOCKS]; +static uint32_t available_charge_current; + +static int battery_delta_target; + +static const char * kPowerSupplyNames[kPowerSupplyNum] = { + "error", "batt", "firewire", "usb host", "usb brick", "usb charger", "external" }; + +static bool +power_set_usb_brick_detect(int dock, int select) +{ +#if WITH_HW_TRISTAR + return tristar_set_usb_brick_detect(select); +#elif WITH_HW_CHARGER + return charger_set_usb_brick_detect(dock, select); +#else + return platform_set_usb_brick_detect(select); +#endif +} + +static unsigned +power_detect_usb_brick(int dock) +{ + static const int dM = 0; + static const int dP = 1; + static const int dNum = 2; + + uint32_t dataVoltage[dNum], dataID[dNum], ratio; + uint32_t brickID; + + usb_brick_id[dock] = 0; + + for (int idx = dM; idx < dNum; idx++) + { + uint32_t dMon = (idx == dP) ? kUSB_DP : kUSB_DM; + + power_set_usb_brick_detect(dock, dMon); + spin(2 * 1000); + dataVoltage[idx] = pmu_read_brick_id_level(); + + // Thresholds based on N20 code, adjusted for 5V scale + if (dataVoltage[idx] <= 2220) { + dataID[idx] = 0; + } else if (dataVoltage[idx] <= 2890) { + dataID[idx] = 1; + } else { + dataID[idx] = 2; + } + + power_set_usb_brick_detect(dock, kUSB_NONE); + } + + ratio = (dataVoltage[dP] == 0) ? 0 : (dataVoltage[dM] * 1000 / dataVoltage[dP]); + + // First apply legacy ratio-based detection for 1A and 2A bricks to ensure + // detection of all bricks correctly identified by previous products. + if ((ratio > 1290) && (ratio <= 1505)) + { + // Ratio 1.34 + brickID = 2; + } + else if ((ratio > 664) && (ratio <= 775)) + { + // Ratio 0.75 + brickID = 4; + } + else + { + // New (N20-based) brick detection method + brickID = 1 + (3 * dataID[dP]) + dataID[dM]; + } + + if (NUM_DOCKS > 1) dprintf(DEBUG_INFO, "dock %d ", dock); + dprintf(DEBUG_INFO, "usb voltage dP %d, dM %d, ratio %d id %d\n", dataVoltage[dP] , dataVoltage[dM], ratio, brickID); + + if ((dataVoltage[dM] < 1000) || (dataVoltage[dP] < 1000)) + { + if (power_set_usb_brick_detect(dock, kUSB_CP1)) { + uint32_t dv; + + // must wait 40ms for a CDP to assert DM voltage source + task_sleep(40 * 1000); + + dv = pmu_read_brick_id_level(); + + power_set_usb_brick_detect(dock, kUSB_NONE); + + if (NUM_DOCKS > 1) dprintf(DEBUG_INFO, "dock %d ", dock); + dprintf(DEBUG_INFO, "usb charger detect voltage dM %d\n", dv); + + // if we see 0.25 to 0.8V, it is a USB charger (at this point, we + // don't try to distinguish DCP from CDP) + if (dv > 250 && dv < 800) { + return kPowerSupplyUSBCharger; + } + } + + return (kPowerSupplyUSBHost); + } + + if ((ratio < 500) || (ratio > 2000)) + return (kPowerSupplyUSBHost); + + usb_brick_id[dock] = brickID; + return kPowerSupplyUSBBrick; +} + +static void +power_determine_power_supply(void) +{ + for (int dock = 0; dock < NUM_DOCKS; dock++) { + int powerSupplyType; + + if (charger_has_external(dock)) + { + powerSupplyType = kPowerSupplyExternal; + } + else if (charger_has_usb(dock)) + { + if (usb_brick_id[dock] != 0) { + powerSupplyType = kPowerSupplyUSBBrick; + } else { + powerSupplyType = power_detect_usb_brick(dock); + } + } + else if (charger_has_firewire(dock)) { + powerSupplyType = kPowerSupplyFirewire; + } + else { + powerSupplyType = kPowerSupplyBattery; + usb_brick_id[dock] = 0; + } + + if (NUM_DOCKS > 1) printf("dock %d ", dock); + printf("power supply type %s", kPowerSupplyNames[powerSupplyType] ); + if (powerSupplyType == kPowerSupplyUSBBrick) { + printf(" id %d", usb_brick_id[dock] ); + } + printf("\n"); + + if (powerSupplyType != power_supply_type[dock]) + { + power_supply_type[dock] = powerSupplyType; + charger_clear_usb_state(); + } + } + +#ifdef GPIO_USB_MUX_SEL + if (NUM_DOCKS > 1) + { + bool mux = (power_supply_type[0] != kPowerSupplyUSBHost) && (power_supply_type[1] == kPowerSupplyUSBHost); + gpio_write(GPIO_USB_MUX_SEL, mux); + } +#endif +} + +// will return charger_get_max_charge_current() unless we have an ATV table. +// not much of a limiting... I guess... +static UInt16 +limit_precharge_current(bool charging) +{ + UInt16 charge_current_limit; + + charge_current_limit = 0; + for (int dock = 0; dock < NUM_DOCKS; dock++) { + charge_current_limit += charger_get_max_charge_current(dock); + } + + if (!charging) { + // If the charge rate is too low to need limiting, don't bother. This avoids needing to + // talk to talk to the gas gauge or measure temperature when waking from sleep (7062950) + return charge_current_limit; + } + + if (!power_has_batterypack()) + return 0; + +#if TARGET_USE_CHARGE_TABLE + // limit charge current in low temperature + unsigned int milliVolts = power_get_battery_level(); + + int centiCelsius; +#if WITH_HW_GASGAUGE + int error = gasgauge_read_temperature(¢iCelsius); +#else + int error = charger_read_battery_temperature(¢iCelsius); +#endif + if (!error) { + // Set charge current to max allowable charge current. + UInt16 limit = 0; // Default - suspend. If temp is higher than table can catch + const struct power_charge_limits *charge_table = pmu_charge_table; + static const size_t num_charge_limits = sizeof(pmu_charge_table)/sizeof(struct power_charge_limits); + +#if WITH_HW_GASGAUGE && TARGET_USE_CHARGE_TABLE + static struct power_charge_limits gg_charge_table[num_charge_limits]; + static bool chargetable_read = false; + if (!chargetable_read) { + chargetable_read = gasgauge_read_charge_table(gg_charge_table, num_charge_limits); + } + if (chargetable_read) { + charge_table = gg_charge_table; + } +#endif + + // Retain last-used charge limit; only switch if no longer applicable + static const struct power_charge_limits *active_limit = NULL; + const struct power_charge_limits *tl = charge_table; + + const struct power_charge_limits *new_limit = NULL; + while (tl < &charge_table[num_charge_limits]) { + if((milliVolts > tl->upperVoltageLimit) || + (centiCelsius < tl->lowerTempLimit) || + (centiCelsius > tl->upperTempLimit)) { + tl++; + continue; + } + new_limit = tl; + break; + } + + // switch to the new limit unless the voltage range is the same and + // we are still within the temperature range of the old limit + if ((new_limit == NULL) || (active_limit == NULL) + || (new_limit->upperVoltageLimit != active_limit->upperVoltageLimit) + || (centiCelsius < active_limit->lowerTempLimit) + || (centiCelsius > active_limit->upperTempLimit)) + { + active_limit = new_limit; + } + + if (active_limit != NULL) { + limit = active_limit->currentSetting; + } + + if (charge_current_limit > limit) { + charge_current_limit = limit; + dprintf(DEBUG_INFO, "Precharge: Battery temp %dcC voltage %dmV, limiting charge current: %dmA\n", centiCelsius, milliVolts, charge_current_limit); + } + } +#endif + + return charge_current_limit; +} + +uint32_t power_get_available_charge_current() +{ + return available_charge_current; +} + +#if TARGET_HAS_SMARTPORT +// orion centric BUT it might work with bellatrix too +int smartport_get_data(int dev, uint16_t reg, uint8_t *byte) +{ + const UInt8 addr[1]={ reg&0xff }; + return iic_read(dev, 0xe0, addr, sizeof(addr), byte, 1, IIC_NORMAL); +} + +// +int smartport_get_pwr_in_sel(int dev, uint8_t *sel) +{ + int rc=smartport_get_data(dev, 0x16, sel); + if ( rc<0 ) return rc; + + switch ( *sel&(0x3<<3) ) { + case 0x10: *sel=SMARTPORT_EXT_PWR_IN_SEL; break; // ext + case 0x08: *sel=SMARTPORT_ACC_PWR_IN_SEL; break; // acc + default: rc=-2; break; // not known + } + + return rc; +} + +#else +int smartport_get_data(int dev, uint16_t reg, uint8_t *byte) { return -1; }; +int smartport_get_pwr_in_sel(int dev, uint8_t *sel) { return -1; }; +#endif + +static bool +power_set_charging(bool critical, bool configured, bool suspended, + bool pause) +{ + dprintf(DEBUG_SPEW, "power_set_charging(critical=%d, configured=%d, suspended=%d, pause=%d)\n", + critical, configured, suspended, pause); + + bool ok = false; + + int max_input_current_limit_dock = 0; + uint32_t dock_input_current_limit[NUM_DOCKS]={ 0 }; + + for (int dock = 0; dock < NUM_DOCKS; dock++) + { + + if ((power_supply_type[dock] == kPowerSupplyUSBHost) && !critical && suspended) { + dock_input_current_limit[dock] = 0; + } + else if (power_supply_type[dock] == kPowerSupplyUSBBrick) { + switch (usb_brick_id[dock]) { + case 1: + dock_input_current_limit[dock] = 500; + break; + + case 2: + dock_input_current_limit[dock] = 1000; + break; + + case 4: + dock_input_current_limit[dock] = 2100; + break; + + case 5: + dock_input_current_limit[dock] = 2400; + break; + + default: + // reserved brick IDs default to 1A + dock_input_current_limit[dock] = 1000; + break; + } + } + else if (power_supply_type[dock] == kPowerSupplyUSBCharger) { + // limit USB charger to 1A even though spec allows 1500mA (13332167) + dock_input_current_limit[dock] = 1000; + } + else if ((power_supply_type[dock] == kPowerSupplyUSBHost) + && (force_usb_power || configured || critical)) { + dock_input_current_limit[dock] = 500; + } + else { + dock_input_current_limit[dock] = 100; + } + + if (power_supply_type[dock] >= kPowerSupplyUSBHost) { + ok = true; + } + + if (dock_input_current_limit[dock] > dock_input_current_limit[max_input_current_limit_dock]) { + max_input_current_limit_dock = dock; + } + + } + + available_charge_current=0; + + uint32_t charge_current_limit = 0; + if ( !pause ) { + available_charge_current = dock_input_current_limit[max_input_current_limit_dock]; + charge_current_limit = limit_precharge_current( available_charge_current > 100 ); // might not limit at all + +#if TARGET_HAS_SMARTPORT + uint8_t sel; + int rc=smartport_get_pwr_in_sel(1, &sel); + if ( rc<0 ) { + } else if ( sel==SMARTPORT_ACC_PWR_IN_SEL ) { // accessory + available_charge_current=500; // J99a Orion power-in support for iBoot + } +#endif + } + // charger_set_charging will subtract from charge_current_limit, and we may need to + // spread the limit across multiple docks. So start with the one with the highest + // current limit, since it is most efficient to use the local power. + for (int i = 0; i < NUM_DOCKS; i++) + { + int dock = (i + max_input_current_limit_dock) % NUM_DOCKS; // start with highest current limit + + // available_charge_current is the MAX unless I have SMARTPORT + uint32_t docklimit=dock_input_current_limit[dock]; + if ( (docklimit>available_charge_current) && available_charge_current) docklimit=available_charge_current; + + charger_set_charging(dock, docklimit, &charge_current_limit); + } + + return ok; +} + +static bool power_charge_done() +{ + if (!power_has_batterypack()) + return false; + +#if WITH_HW_GASGAUGE + return gasgauge_full(); +#else + for (int dock = 0; dock < NUM_DOCKS; dock++) { + if ((power_supply_type[dock] >= kPowerSupplyUSBHost) && !charger_charge_done(dock)) + return false; + } + + return true; +#endif + +} + + +bool +power_enable_charging(bool inflow, bool charging) +{ + return power_set_charging(need_precharge, false, !inflow, !charging); +} + +void +power_set_usb_state(bool configured, bool suspended) +{ + charger_clear_usb_state(); + power_set_charging(false, configured, suspended, false); +} + +void power_set_usb_enabled(bool enabled) +{ +#if WITH_HW_TRISTAR + if (enabled) { + // if there is a B139/B164 attached, provide it power (11991279) + uint8_t digital_id[6]; + if (tristar_read_id(digital_id)) { + // if accessory could be a USB host (USB=2 or USB=3) and needs power for USB (PS bit), enable power + if ((digital_id[0] & (1 << 4)) && (digital_id[2] & (1 << 7))) { + tristar_enable_acc_pwr(true); + } + } + } else { + tristar_enable_acc_pwr(false); + } +#endif +} + +// same as gasgauge_needs_precharge(), reset the charger when needed +// @return 1 when needs precharge, 0 when it doesn't +static int charger_needs_precharge(int debug_print_level, bool debug_show_target) +{ + int state; + + state=gasgauge_needs_precharge(debug_print_level, debug_show_target); + if ( state&GG_COMMS_WD ) { + dprintf(debug_print_level, "comms wd\n"); + + // TODO: recovery procedure? + + } else if ( state&GG_NEEDS_RESET ) { + const int rc=gasgauge_reset_timer(debug_print_level, 8 ); // 8 seconds timeout + if ( rc!=0 ) dprintf(debug_print_level, "reset charge timer failed (%d)", rc); + } + + charger_print_status(); + + return (state&GG_NEEDS_PRECHARGE)!=0; +} + +/* power_init() is only called in iBSS and LLB - not in iBoot or iBEC. */ +int +power_init(void) +{ + u_int8_t data; + + pmu_early_init(); + + if (!power_is_suspended()) { +#if WITH_HW_CHARGER + charger_early_init(); +#endif + +#if TARGET_POWER_NO_BATTERY + need_precharge = power_needs_precharge(); +#else + /* + * Use two different heurestics to determine whether the unit has a working battery installed: + * - no_battery_power: if the voltage is very low, there may be no battery present (or it may be very drained) + * - no_battery_pack: if the pack temperature reads very low, there may be no NTC and hence no battery (or it may be very cold) + * + * In the case where no battery pack is present, we want to avoid either trying to talk + * to the gas gauge (which may not be present) or sitting in the battery trap (which would + * not be charging a real battery). There are two different types of no-battery situations, though: + * If nothing is connected to the battery terminals, both no_battery_power and no_battery_pack will be + * true. More likely (on a dev board or in the factory) we will have a 4V supply attached to the + * battery terminals, but NTC and gas gauge will still be disconnected, so no_battery_power will be + * false but no_battery_pack will be true. + * + * In the latter case, the battery voltage is always well above 3.6V, so only bypass the voltage check + * if both indications (no_battery_power and no_battery_pack) are set. Otherwise, we check + * for a low battery voltage. On a gas gauge-based device, we can therefore assume it's safe to + * check with the gas gauge even when no_battery_power is set, if the voltage is in this range (see + * below). On a device with no gas gauge, the voltage check is the only determination of whether + * is necessary, so we want to be conservative and only skip a battery voltage that would otherwise + * lead to precharge only if both no_battery_power and no_battery_pack are set. + * + * However, since both of these values can be true even when there is a battery, we try to avoid + * making any permanent decisions based on them that will affect the user's ability to use + * the unit later. We also want to avoid a poor user experience for a user that happens to have + * a very dead or very cold battery, although if they have both, there's little we can do + * to distinguish this from a dev board or factory situation. + * + * Note that a "very cold" battery that triggers no_battery_pack is always well below the point + * at which the battery is too cold to charge safely. So battery trap would not necessarily + * help the user recover anyway (although sitting in the trap can warm up the unit simply by + * having the CPU, screen, backlight on). + */ + bool no_battery_power, no_battery_pack; + + no_battery_pack = !power_has_batterypack(); + + // read boot battery voltage with minimal current being drawn, charger disabled + power_set_charging(false, false, false, true); + dprintf(DEBUG_INFO, "battery voltage "); + + if (!charger_read_battery_level(&boot_battery_level)) + dprintf(DEBUG_INFO, "%d mV\n", boot_battery_level); + else + dprintf(DEBUG_INFO, "error\n"); + power_set_charging(false, false, false, false); + + no_battery_power = (boot_battery_level < NO_BATTERY_VOLTAGE); + need_precharge = (!no_battery_power || !no_battery_pack) && (boot_battery_level < MIN_BOOT_BATTERY_VOLTAGE); + +#if WITH_HW_GASGAUGE + /* + * If no_battery_pack is set, need_precharge will still be set if + * NO_BATTERY_VOLTAGE < boot_battery_level < MIN_BOOT_BATTERY_VOLTAGE. This means + * while a very cold, very dead, battery can still bypass battery trap, a + * very cold, mostly dead, battery will not. + * + * If the voltage falls in this range, assume we have a real battery and talk to + * the gas gauge anyway; a fake battery from an external supply should always + * be well above MIN_BOOT_BATTERY_VOLTAGE (3.4-3.6V). + * + * We do not talk to the gas gauge if we're waking from sleep and it's unlikely + * the battery is low: it will delay wakeup by a measurable amount, and wiggling + * the SWI line will confuse the PMU when it looks for wakeup events. + */ + if (!no_battery_pack || need_precharge) { + gasgauge_init(); + + // iOS or charge trap will reset the charge timer if needed + need_precharge = ( gasgauge_needs_precharge(DEBUG_INFO, true)&GG_NEEDS_PRECHARGE) !=0 ; + } +#endif + + if (power_get_nvram(kPowerNVRAMiBootDebugKey, &data) == 0 && (data & kPowerNVRAMiBootDebugBatteryTrap) != 0) { +#if TARGET_FORCE_DEBUG_PRECHARGE + need_precharge = true; +#elif !RELEASE_BUILD && defined(GPIO_RINGER_AB) + if (gpio_read(GPIO_RINGER_AB)) { + need_precharge = true; + } +#endif + } + + power_determine_power_supply(); + power_set_charging(need_precharge || no_battery_power, false, false, no_battery_power && no_battery_pack); +#endif + + // store boot voltage and brick ID for iBoot. Keep backwards compatible with old + // LLB that stored boot voltage in mV: mV truncated to cV with brick ID encoded in lowest + // order decimal digit, encoded in bits [12:0]. Bits [15:14] indicate which dock is + // in use; 1-indexed with zero meaning none. Reserved: bit 13 reserved, "brick ID" zero + UInt16 boot_battery_data = ((boot_battery_level / 10) * 10) & 0x1FFF; + #if NUM_DOCKS > 3 + #error too many docks + #endif + for (int dock = 0; dock < NUM_DOCKS; dock++) { + if (power_supply_type[dock] == kPowerSupplyUSBBrick) { + boot_battery_data |= (dock+1) << 14; + boot_battery_data += usb_brick_id[dock] % 10; + break; + } + } + + // pass boot voltage between LLB and iBoot + power_set_nvram(kPowerNVRAMiBootBootFlags0Key, boot_battery_data & 0xFF); + power_set_nvram(kPowerNVRAMiBootBootFlags1Key, (boot_battery_data >> 8) & 0xFF); + + // this allow charging via ISET + charger_clear_alternate_usb_current_limit(); + } + + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + need_buttonwait = ((data & kPowerNVRAMiBootStateModeMask) == kPowerNVRAMiBootStateModeButtonwaitWithGraphics) + || ((data & kPowerNVRAMiBootStateModeMask) == kPowerNVRAMiBootStateModeButtonwaitNoGraphics); + if (need_precharge) + data |= kPowerNVRAMiBootStatePrecharge; + else + data &= ~kPowerNVRAMiBootStatePrecharge; + power_set_nvram(kPowerNVRAMiBootStateKey, data); + + dprintf(DEBUG_INFO, "need precharge %d set nvram %02x\n", need_precharge, data); + + pmu_setup(); + + return 0; +} + +int +power_late_init(void) +{ + pmu_late_init(); +#if WITH_HW_GASGAUGE + gasgauge_late_init(); +#endif + + return 0; +} + +bool +power_needs_precharge(void) +{ +#if TARGET_POWER_NO_BATTERY + // since power_init() doesn't get called from regular iBoot, this is "the place" to set up + // iBoot properly (we call it from power_init if TARGET_POWER_NO_BATTERY). + // Make sure we have the right power supply type, and force USB power enabled, as if we were + // in precharge on a battery-powered device. + if (-1U == boot_battery_level) { + boot_battery_level = 0; + force_usb_power = true; + power_determine_power_supply(); + power_set_charging(true, false, false, false); + } + + return (false); +#elif PRODUCT_IBSS || PRODUCT_IBEC + return (false); +#elif PRODUCT_LLB + return (need_precharge); +#else + if (need_precharge) return (true); + + u_int8_t data = 0; + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + need_precharge = (0 != (kPowerNVRAMiBootStatePrecharge & data)); + need_buttonwait = ((data & kPowerNVRAMiBootStateModeMask) == kPowerNVRAMiBootStateModeButtonwaitWithGraphics) + || ((data & kPowerNVRAMiBootStateModeMask) == kPowerNVRAMiBootStateModeButtonwaitNoGraphics); + if (need_precharge || (-1U == boot_battery_level)) { + bool no_battery_power; + + // see encoding table in power_init + power_get_nvram(kPowerNVRAMiBootBootFlags1Key, &data); + int dock = (data & 0xC0) >> 6; + boot_battery_level = ((data & 0x1F) << 8); + power_get_nvram(kPowerNVRAMiBootBootFlags0Key, &data); + if (dock > 0) usb_brick_id[dock-1] = ((boot_battery_level | data) % 10); + boot_battery_level = ((boot_battery_level | data) / 10) * 10; + + printf("battery voltage %d mV\n", boot_battery_level); + + if ((boot_battery_level + 50) > TARGET_BOOT_BATTERY_VOLTAGE) + battery_delta_target = 50; // charge at least 50 mV + else + battery_delta_target = TARGET_BOOT_BATTERY_VOLTAGE - boot_battery_level; + no_battery_power = (boot_battery_level < NO_BATTERY_VOLTAGE); + + power_determine_power_supply(); + power_set_charging(need_precharge || no_battery_power, false, false, no_battery_power && !power_has_batterypack()); + } + + return (need_precharge); +#endif +} + +bool +power_needs_thermal_trap(void) +{ + u_int8_t data = 0; + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + return data & kPowerNVRAMiBootStateThermalTrap; +} + +void +power_cancel_buttonwait(void) +{ + if (need_buttonwait) { + u_int8_t data = 0; + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + data &= ~kPowerNVRAMiBootStateModeMask; + data |= kPowerNVRAMiBootStateModeNormalBoot; + power_set_nvram(kPowerNVRAMiBootStateKey, data); + + need_buttonwait = false; + } +} + +u_int32_t +power_get_boot_battery_level(void) +{ + return (boot_battery_level); +} + +void +power_get_usb_brick_id(uint32_t *id, size_t count) +{ + for (unsigned dock = 0; dock < NUM_DOCKS && dock < count; dock++) { + if (power_supply_type[dock] == kPowerSupplyUSBBrick) { + id[dock] = usb_brick_id[dock]; + } else { + id[dock] = 0; + } + } +} + +u_int32_t +power_get_battery_level(void) +{ + uint32_t voltage; + +#if WITH_HW_GASGAUGE + if (gasgauge_read_voltage(&voltage) != 0) + return 0; +#else + if (charger_read_battery_level(&voltage) != 0) + return 0; +#endif + + return voltage; +} + +bool +power_has_batterypack(void) +{ + return charger_has_batterypack(0); +} + +enum +{ + kCheckBatteryInterval = 5 * 1000 * 1000, // 5s + kCheckPowerSupplyInterval = 100 * 1000, // 100ms + kChargingAnimationFrameInterval = 1 * 1000 * 1000, // 1s + kHomeButtonPoweronTimeout = 400 * 1000, // 400ms + kPrechargeDisplayDimTimeout = 8 * 1000 * 1000, // 8s +}; + +enum chargetrap_type_t +{ + kChargetrapPrecharge = 1, + kChargetrapButtonwaitWithGraphics = 2, + kChargetrapButtonwaitNoGraphics = 3, +}; + +enum chargetrap_return_t +{ + kChargetrapReturnSuccess = 0, // conditions of precharge were met + kChargetrapReturnNoCharger = 1, // no charger attached + kChargetrapReturnChargerRemoved = 2, // charger was attached, and then removed +}; + +// round up when charging (same as SpringBoard)... +static int +power_battery_level(unsigned int capacity, unsigned int total_capacity) +{ + int level = (((IMAGE_TYPE_BATTERYFULL_N_TOTAL-1) * capacity) + (total_capacity-1)) / total_capacity; + + // ... only show full battery if completely full... + if ((level == IMAGE_TYPE_BATTERYFULL_N_FULL) && (capacity < total_capacity)) level--; + + // ... and never show the "empty" level... + if (level == 0) level++; + +#if !TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE + // if iPhone, always show red battery until 20% + if ((level > IMAGE_TYPE_BATTERYFULL_N_RED) && ((5 * capacity) <= total_capacity)) level = IMAGE_TYPE_BATTERYFULL_N_RED; +#endif + + return level; +} + +static bool +power_paint_battery_with_capacity(bool precharge, int frameCount, unsigned int capacity, unsigned int total_capacity) +{ + bool ok = true; + + static int current_level = -1; + + int level = power_battery_level(capacity, total_capacity); + + dprintf(DEBUG_SPEW, "power_paint_battery: %d capacity %d/%d\n", level, capacity, total_capacity); + + if ((level == current_level) && (frameCount > 0)) { + return true; + } + + paint_set_picture(0); + + bool batteryImage = true; +#if !WITH_HW_GASGAUGE + batteryImage = precharge || level == IMAGE_TYPE_BATTERYFULL_N_FULL; +#endif + if (!batteryImage) { + if (((frameCount / (kChargingAnimationFrameInterval / kCheckPowerSupplyInterval)) & 1) == 0) { + ok = !paint_set_picture_for_tag(IMAGE_TYPE_BATTERYCHARGING0); + } else { + ok = !paint_set_picture_for_tag(IMAGE_TYPE_BATTERYCHARGING1); + } + } else { + ok = !paint_set_picture_for_tag(IMAGE_TYPE_BATTERYLOW0); + if (ok) { + ok = !paint_set_picture_for_tag(IMAGE_TYPE_BATTERYLOW1); + if (ok && level >= IMAGE_TYPE_BATTERYFULL_N_START) { + ok = !paint_set_picture_for_tag_list(IMAGE_TYPE_BATTERYFULL, 0, 1 + level - IMAGE_TYPE_BATTERYFULL_N_START); + } + } + } + + if (!ok) { + // Default to yellow if there are no pictures. + paint_set_bgcolor(255, 255, 0); + paint_set_picture(0); + } + + paint_update_image(); + + current_level = level; + + return ok; +} + +static bool +power_paint_battery(bool precharge, int frameCount) +{ + unsigned int capacity, total_capacity; + + if (precharge) { + // no need to ask gas gauge + capacity = 0; + total_capacity = 1; + } else { +#if WITH_HW_GASGAUGE + total_capacity=100; + + if (gasgauge_read_soc(&capacity) != 0) { + // gas gauge error; leave screen as is + return true; + } +#else + total_capacity = 1; + capacity = power_charge_done() ? 0 : 1; +#endif + } + + return power_paint_battery_with_capacity(precharge, frameCount, capacity, total_capacity); +} + + +static enum chargetrap_return_t +charger_precharge(enum chargetrap_type_t chargetrap_type) +{ + bool ok; + int pollCount; + unsigned startBatteryLevel, newBatteryLevel, lastChargingBatteryLevel; + utime_t buttonpress_time = 0; + utime_t display_idle_time; + int frameCount = 0; + bool animate, color_map_state; + const char *chargetrap_label; + bool test_buttonwait_with_ringer = false; + uint8_t data; + + if (chargetrap_type != kChargetrapButtonwaitNoGraphics) { + power_set_usb_enabled(true); + } + + // check connection type before starting + power_determine_power_supply(); + + charger_clear_usb_state(); + + ok = power_set_charging(true, false, false, false); + if (!ok) { + +#if WITH_HW_GASGAUGE + // if precharge and no charger, check gas gauge health once anyway + // if charger is attached, we do this later in a more methodical manner. + static bool gg_health_checked = false; + if (!gg_health_checked && (chargetrap_type == kChargetrapPrecharge)) { + gasgauge_check_health(boot_battery_level); + gg_health_checked = true; + } +#endif + + return kChargetrapReturnNoCharger; + } + + +#if !RELEASE_BUILD || TARGET_FORCE_DEBUG_PRECHARGE + if (power_get_nvram(kPowerNVRAMiBootDebugKey, &data) == 0) { + test_buttonwait_with_ringer = (data & kPowerNVRAMiBootDebugBatteryTrap) != 0; + } else { + printf(" Error: cannot read kPowerNVRAMiBootDebugKey\n"); + } +#endif + + + if ( test_buttonwait_with_ringer ) { + chargetrap_label = "debug precharge"; + } else if (chargetrap_type == kChargetrapPrecharge) { + chargetrap_label = "low-battery precharge"; + } else { + chargetrap_label = "power-off simulation"; + } + + + charger_read_battery_level(&startBatteryLevel); + + printf("\nStarting %s: ", chargetrap_label); + if (chargetrap_type == kChargetrapPrecharge) { +#if WITH_HW_GASGAUGE + charger_needs_precharge(DEBUG_CRITICAL, true); // print target and current level +#else + printf("target %d boot %d, now %d mV\n", startBatteryLevel + battery_delta_target, boot_battery_level, startBatteryLevel); +#endif + } else { + printf("waiting for power button or unplug (screen %s)\n", + (chargetrap_type == kChargetrapButtonwaitWithGraphics) ? "on" : "off"); + } + + lastChargingBatteryLevel = newBatteryLevel = startBatteryLevel; + pollCount = 0; + power_set_charging(true, false, false, false); + + animate = (chargetrap_type != kChargetrapButtonwaitNoGraphics); + display_idle_time = system_time(); + + do { + bool powersupply_changed = false; + bool button_event = false; + bool other_wake_event = false; + + if (need_buttonwait) { + bool button = platform_get_request_dfu1(); + + if (button && (buttonpress_time == 0)) + buttonpress_time = system_time(); + else if (!button) + buttonpress_time = 0; + + if ((buttonpress_time != 0) && time_has_elapsed(buttonpress_time, kHomeButtonPoweronTimeout - kCheckPowerSupplyInterval)) { + printf("power button press detected: button wait cancelled\n"); + need_buttonwait = false; + if ((chargetrap_type == kChargetrapButtonwaitWithGraphics) || (chargetrap_type == kChargetrapButtonwaitNoGraphics)) + break; + } + } + + // turn on the display if needed + if (animate && (frameCount == 0)) { + platform_init_display(); + color_map_state = paint_color_map_enable(false); + ok = power_paint_battery(chargetrap_type == kChargetrapPrecharge, frameCount); + if (!ok) { + animate = false; + } + } + + task_sleep(kCheckPowerSupplyInterval); + + if (animate && ((++frameCount % (kChargingAnimationFrameInterval / kCheckPowerSupplyInterval)) == 0)) { + if (chargetrap_type == kChargetrapButtonwaitWithGraphics) { + power_paint_battery(false, frameCount); + } + + // Turn off the screen after a timeout with no user activity. + // If the display is too large to sustain being on at 500mA, we always idle off, but otherwise + // if graphical button-wait is enabled we do not, even in precharge, because the graphical + // button-wait mode is defined as leaving the screen on at all times. +#if TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE + if (true) { +#else + if ((chargetrap_type == kChargetrapPrecharge) && !need_buttonwait) { +#endif + if (system_time() >= (display_idle_time + kPrechargeDisplayDimTimeout)) { + platform_quiesce_display(); + animate = false; + frameCount = 0; + } + } + } + + /* Read & clear interrupts */ + pmu_check_events(&powersupply_changed, &button_event, &other_wake_event); +#if WITH_HW_CHARGER + powersupply_changed = false; + for (int dock = 0; dock < NUM_DOCKS; dock++) { + if (charger_check_usb_change(dock, power_supply_type[dock] >= kPowerSupplyUSBHost)) + powersupply_changed = true; + } +#endif + + if (++pollCount > (kCheckBatteryInterval / kCheckPowerSupplyInterval)) { + pollCount = 0; + dprintf(DEBUG_INFO, "%s: ", chargetrap_label); + + if (charger_read_battery_level(&newBatteryLevel) != 0) + continue; + +#if WITH_HW_GASGAUGE + need_precharge = charger_needs_precharge(DEBUG_INFO, (chargetrap_type == kChargetrapPrecharge)); +#else + if (chargetrap_type == kChargetrapPrecharge) { + dprintf(DEBUG_INFO, "battery level %d mV (target %d mV)\n", newBatteryLevel, startBatteryLevel + battery_delta_target); + } else { + dprintf(DEBUG_INFO, "waiting for power button or unplug (battery level %d mV)\n", newBatteryLevel); + } + + if (need_precharge + && ((newBatteryLevel >= (startBatteryLevel + battery_delta_target)) + || (newBatteryLevel >= (ALWAYS_BOOT_BATTERY_VOLTAGE)))) { + need_precharge = false; + boot_battery_level += (newBatteryLevel - startBatteryLevel); + } +#endif + + if (test_buttonwait_with_ringer) { +#if TARGET_FORCE_DEBUG_PRECHARGE + need_precharge = true; +#elif !RELEASE_BUILD && defined(GPIO_RINGER_AB) + if (gpio_read(GPIO_RINGER_AB)) { + need_precharge = true; + } +#endif + } + + if ((chargetrap_type == kChargetrapPrecharge) && !need_precharge) { + break; + } + +#if WITH_HW_GASGAUGE + if (need_precharge) { + gasgauge_check_health(newBatteryLevel); + } +#endif + + // always reset the charge control in case the current limit has changed due to temperature or voltage + if (!power_set_charging(true, false, false, false)) { + powersupply_changed = true; + } + } + + if (powersupply_changed) + { + power_determine_power_supply(); + ok = power_set_charging(true, false, false, false); + if (!ok) { + boot_battery_level += (lastChargingBatteryLevel - startBatteryLevel); + battery_delta_target -= (lastChargingBatteryLevel - startBatteryLevel); + power_set_charging(true, false, false, false); + if (animate) paint_color_map_enable(color_map_state); + return kChargetrapReturnChargerRemoved; + } + } + else if ((chargetrap_type == kChargetrapButtonwaitNoGraphics) && other_wake_event) + { + // if we are simulating off (kChargetrapButtonwaitNoGraphics) and got an event + // that would have woken a real unit from standby (excluding buttons, which are special), + // boot. This ensures that, e.g., an accessory (7020690) or alarm will turn on the unit. + need_buttonwait = false; + break; + } + else if ((chargetrap_type != kChargetrapButtonwaitNoGraphics) && button_event) + { + // any button event will reset the display-off timer in precharge, + // and turn the screen back off if already dim. + display_idle_time = system_time(); + animate = true; // next loop will re-activate the screen + } + + lastChargingBatteryLevel = newBatteryLevel; + } + while (true); + + power_set_charging(true, false, false, false); + + data = 0; + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + if (!need_precharge) + data &= ~kPowerNVRAMiBootStatePrecharge; + if (!need_buttonwait) { + data &= ~kPowerNVRAMiBootStateModeMask; + data |= kPowerNVRAMiBootStateModeNormalBoot; + } + power_set_nvram(kPowerNVRAMiBootStateKey, data); + + if (animate) paint_color_map_enable(color_map_state); + + return kChargetrapReturnSuccess; +} + +bool +power_do_chargetrap(void) +{ + enum chargetrap_return_t ret; + uint8_t buttonwait_type = 0; + unsigned int stage; + + // There are three different types of charge traps. If more than one applies, show them in this order: + // + // 1. button wait without graphics, used to simulate being completely powered off (screen off) + // 2. precharge (aka battery trap), used when we don't have enough charge to boot (screen displaying low-battery icon) + // 3. button wait with graphics, used when "off" on certain SKUs (screen displaying charging icon) + // + // These are gated by need_buttonwait and power_needs_precharge(), which can be relied on to only ever go + // from true to false. + + if (need_buttonwait) { + u_int8_t data = 0; + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + + buttonwait_type = (data & kPowerNVRAMiBootStateModeMask); + } + + if (need_buttonwait && (buttonwait_type == kPowerNVRAMiBootStateModeButtonwaitNoGraphics)) { + ret = charger_precharge(kChargetrapButtonwaitNoGraphics); + if (ret != kChargetrapReturnSuccess) { + // this mode is one-time; the next boot should always be normal + power_cancel_buttonwait(); + platform_poweroff(); + } + } + + stage = 0; + while (power_needs_precharge() && (stage < 5)) { + bool ok; + + ret = charger_precharge(kChargetrapPrecharge); + if (ret != kChargetrapReturnNoCharger) { + stage = 0; // if any charging occurred, restart battery trap sequence + continue; + } + + platform_init_display(); + bool color_map_state = paint_color_map_enable(false); + paint_set_picture(0); + + ok = !paint_set_picture_for_tag(IMAGE_TYPE_BATTERYLOW0); + if (ok && !(stage++ & 1)) ok = !paint_set_picture_for_tag(IMAGE_TYPE_BATTERYLOW1); + if (ok && + ((power_supply_type[0] == kPowerSupplyFirewire) || + (paint_set_picture_for_tag(IMAGE_TYPE_GLYPHPLUGIN) == 0))) { + paint_set_bgcolor(0, 0, 0); + } else { + paint_set_picture(0); + } + paint_update_image(); + + task_sleep(1 * 1000 * 1000); + + paint_color_map_enable(color_map_state); + } + + if (power_needs_precharge()) { + platform_quiesce_display(); + printf("need battery charge, no power source; shutting down\n"); + power_shutdown(); + } + + if (need_buttonwait && (buttonwait_type == kPowerNVRAMiBootStateModeButtonwaitWithGraphics)) { + ret = charger_precharge(kChargetrapButtonwaitWithGraphics); + if (ret != kChargetrapReturnSuccess) { + platform_poweroff(); + } + } + + power_set_usb_enabled(false); + + return (true); +} + +static int +do_charge_cmd(int argc, struct cmd_arg *args) +{ + unsigned battery_level; + bool enable = true; + + if (!security_allow_modes(kSecurityModeDebugCmd | kSecurityModeHWAccess)) { + printf("Permission Denied\n"); + return -1; + } + +#if WITH_HW_USB + usb_quiesce(); +#endif + + if (argc >= 2) { + if (!strcmp("dis", args[1].str)) { + enable = false; + } + else if (!strcmp("ena", args[1].str)) { + } + else if (!strcmp("trap", args[1].str)) { + } + else if (!strcmp("restart", args[1].str)) { +#if WITH_HW_GASGAUGE + int result; + + result=gasgauge_reset_timer( DEBUG_CRITICAL, 8 ); // 8 seconds timeout + if ( result==0 ) { + result=gasgauge_needs_precharge(DEBUG_INFO, false); + if ( result&GG_NEEDS_RESET ) printf("restart failed %#x\n", result); + } else { + printf("failed (%d)\n", result); + } +#endif + return 0; + } + else if (!strcmp("detect", args[1].str)) { + for (int dock = 0; dock < NUM_DOCKS; dock++) usb_brick_id[dock]=0; + power_determine_power_supply(); + return 0; + } + else if (!strcmp("draw", args[1].str)) { + } + else if (!strcmp("status", args[1].str)) { +#if WITH_HW_GASGAUGE + gasgauge_print_status(); + charger_print_status(); +#endif + return 0; + } + else { + printf("usage:\n\t%s \n", args[0].str); + printf("\t\tena Enable charger.\n"); + printf("\t\tdis Disable charger.\n"); + printf("\t\trestart Reset/Restart Charge timer.\n"); + printf("\t\ttrap Enter trap with target voltage delta.\n"); + printf("\t\tdraw Draw battery logo with specified SoC (percent)\n"); + printf("\t\tdetect Force detect power brick\n"); + printf("\t\tstatus Dump gas gauge and charger status\n"); + } + } + + power_determine_power_supply(); +#if TARGET_HAS_SMARTPORT + uint8_t pwr_in_sel; + int rc=smartport_get_pwr_in_sel(1, &pwr_in_sel); + printf("smartport: pwr_in_sel=%x ", pwr_in_sel); + if ( rc<0 ) { + printf("error %d\n", rc); + } else { + printf("(%s)\n", (pwr_in_sel==SMARTPORT_ACC_PWR_IN_SEL)?"acc":"ext"); + } +#endif + + power_set_charging(false, enable, false, !enable); + + /* read battery voltage */ + printf("battery voltage "); + if (!charger_read_battery_level(&battery_level)) + printf("%d mV\n", battery_level); + else + printf("error\n"); + +#if WITH_HW_GASGAUGE + gasgauge_print_status(); + charger_print_status(); +#endif + + if ((argc >= 2) && !strcmp("trap", args[1].str)) { + boot_battery_level = battery_level; + battery_delta_target = args[2].u; + + enum chargetrap_return_t ret = charger_precharge(kChargetrapPrecharge); + if (ret == kChargetrapReturnSuccess) printf("charger_precharge success\n"); + else if (ret == kChargetrapReturnNoCharger) printf("charger_precharge no charger\n"); + else if (ret == kChargetrapReturnChargerRemoved) printf("charger_precharge charger removed\n"); + } + + if ( strcmp("draw", args[1].str)==0 ) { + if ( argc==3 ) { + // charger draw + power_paint_battery_with_capacity(false, 0, args[2].u, 100); + } else if ( argc==4 ) { + // charger draw + power_paint_battery(args[2].u, args[3].u); + } else if ( argc>4 ) { + // charger draw + power_paint_battery_with_capacity(args[2].u, args[3].u, args[4].u, 100); + } + } + +#if WITH_HW_USB + /* re-initializes usb as a result of the usb_quiesce() call */ + usb_early_init(); + #if WITH_PLATFORM_INIT_USB + if(platform_init_usb() != 0) + usb_quiesce(); + #else + if(usb_init() != 0) + usb_quiesce(); + #endif +#endif + + return 0; +} + +#if WITH_RECOVERY_MODE +MENU_COMMAND_DEBUG(charge, do_charge_cmd, "Manage the charger chip", NULL); +#endif + +static const char *nvram_property_names[kPowerNVRAMPropertyCount] = { + kPowerNVRAMiBootStateName, // kPowerNVRAMiBootStateKey + kPowerNVRAMiBootDebugName, // kPowerNVRAMiBootDebugKey + kPowerNVRAMiBootStageName, // kPowerNVRAMiBootStageKey + kPowerNVRAMiBootErrorCountName, // kPowerNVRAMiBootErrorCountKey + kPowerNVRAMiBootErrorStageName, // kPowerNVRAMiBootErrorStageKey + kPowerNVRAMiBootMemCalCAOffset0Name, + kPowerNVRAMiBootMemCalCAOffset1Name, + kPowerNVRAMiBootMemCalCAOffset2Name, + kPowerNVRAMiBootMemCalCAOffset3Name, + kPowerNVRAMiBootBootFlags0Name, + kPowerNVRAMiBootBootFlags1Name, + kPowerNVRAMiBootEnterDFUName, // kPowerNVRAMiBootEnterDFUKey +}; + +static int +do_power_nvram(int argc, struct cmd_arg *args) +{ + uint32_t cnt; + uint8_t data; + + if (!security_allow_modes(kSecurityModeDebugCmd)) { + printf("Permission Denied\n"); + return -1; + } + + if (argc < 2) { + goto usage; + } + + if (!strcmp("list", args[1].str)) { + for (cnt = 0; cnt < kPowerNVRAMPropertyCount; cnt++) { + if (power_get_nvram(cnt, &data) == 0) { + printf("%x: [%s] 0x%02x\n", cnt, nvram_property_names[cnt], data); + } + } + + } else if (!strcmp("set", args[1].str)) { + if (argc != 4) { + goto usage; + } + + switch (args[2].u) { + case kPowerNVRAMiBootStateKey : + if (!security_allow_modes(kSecurityModeHWAccess)) { + printf("Permission Denied\n"); + return -1; + } + break; + + default: + break; + } + + power_set_nvram(args[2].u, args[3].u); + + } else { + goto usage; + } + + return 0; + +usage: + printf("usage:\n\t%s \n", args[0].str); + printf("\t\tlist List NVRAM Properties.\n"); + printf("\t\tset Set NVRAM Property.\n"); + return -1; +} + +#if WITH_RECOVERY_MODE +MENU_COMMAND_DEBUG(powernvram, do_power_nvram, "Access Power NVRAM.", NULL); +#endif + +void +power_suspend(void) +{ + platform_quiesce_display(); + +#if WITH_HW_MIU + miu_suspend(); +#endif + pmu_set_backlight_enable(0); + + /* enter hibernate mode */ + dprintf(DEBUG_INFO, "pmu suspend\n"); + + pmu_suspend(); +} + +void +power_shutdown(void) +{ + platform_quiesce_display(); + + /* enter standby mode */ + dprintf(DEBUG_INFO, "pmu shutdown\n"); + +#if WITH_HW_GASGAUGE + gasgauge_will_shutdown(); +#endif + + power_clr_events(1); + + pmu_shutdown(); +} + +int +_power_backlight_enable_internal(uint32_t backlight_level) +{ + if (backlight_level) { + if (power_needs_precharge() && (backlight_level > PRECHARGE_BACKLIGHT_LEVEL)) + backlight_level = PRECHARGE_BACKLIGHT_LEVEL; + + } + +#if WITH_HW_LM3534 + extern int lm3534_backlight_enable(uint32_t backlight_level); + + if (lm3534_backlight_enable(backlight_level) != 0) +#endif +#if WITH_HW_LP8559 + extern int lp8559_backlight_enable(uint32_t backlight_level); + + if (lp8559_backlight_enable(backlight_level) != 0) +#endif + { + pmu_set_backlight_enable(backlight_level); + } + + return 0; +} + +void +power_clear_dark_boot_flag(void) +{ +#if PRODUCT_IBOOT + const char* boot_cmd = env_get("boot-command"); + + if (env_get_bool("auto-boot", false) && boot_cmd && strncmp(boot_cmd, "upgrade", 7) == 0) { + // If this is iBoot and we are going to upgrade, + // we don't want to clear dark boot (because iBEC needs to know) + return; + } +#endif + env_unset("darkboot"); + nvram_save(); +} + + +static bool force_disable_dark_boot; + +bool +power_is_dark_boot (void) +{ + static bool dark_boot_init = false; + static bool is_dark_boot = false; + + if (dark_boot_init) + return is_dark_boot && !force_disable_dark_boot; + else { + is_dark_boot = env_get_bool("darkboot", false); + dark_boot_init = true; + return is_dark_boot && !force_disable_dark_boot; + } +} + +static uint32_t requested_backlight_level = 0; + +void +power_dark_boot_checkpoint (void) +{ + if (!power_is_dark_boot()) + return; + // Check buttons and light up screen if needed + bool powersupply_changed = false; + bool button_event = false; + bool other_wake_event = false; + + pmu_check_events(&powersupply_changed, &button_event, &other_wake_event); + + if (button_event) { + dprintf(DEBUG_INFO, "dark boot: found button event\n"); + power_disable_dark_boot(); + return; + } + dprintf(DEBUG_INFO, "dark boot: checkpoint found no pending button presses -- staying dark.\n"); +} + +void +power_disable_dark_boot (void) +{ + force_disable_dark_boot = true; + dprintf(DEBUG_INFO, "dark boot: Lighting up display... (remembered backlight_level: %u)\n", (unsigned int)requested_backlight_level); + _power_backlight_enable_internal(requested_backlight_level); +} + +int +power_backlight_enable(uint32_t backlight_level) +{ +#if !NO_DARK_BOOT + dprintf(DEBUG_INFO, "dark boot: Received backlight level request %u\n", (unsigned int)backlight_level); + requested_backlight_level = backlight_level; + + if (power_is_dark_boot()) { + dprintf(DEBUG_INFO, "dark boot: This is a dark boot, remembering request but leaving backlight_level = 0\n"); + _power_backlight_enable_internal(0); + } else { + return _power_backlight_enable_internal(backlight_level); + } + return 0; +#else + return _power_backlight_enable_internal(backlight_level); +#endif +} + +static int +do_backlight_cmd(int argc, struct cmd_arg *args) +{ + if (argc != 2) { + printf("usage: backlight \n"); + return -1; + } + + if (power_is_dark_boot()) { + printf("[disabling dark boot due to explicit backlight command]\n"); + // This will momentarily set the backlight to a higher level then back to this level + power_disable_dark_boot(); + } + + return power_backlight_enable(args[1].n); +} + +#if WITH_MENU +MENU_COMMAND_DEBUG(backlight, do_backlight_cmd, "set the backlight", NULL); +#endif + +bool +power_has_usb(void) +{ + for (int dock = 0; dock < NUM_DOCKS; dock++) { + if (charger_has_usb(dock)) { + return true; + } + } + + return false; +} + +bool +power_is_suspended(void) +{ + bool suspended = false; +#if WITH_CLASSIC_SUSPEND_TO_RAM +#if PRODUCT_LLB + bool resume_lost = power_get_boot_flag() != kPowerBootFlagWarm; +#else + bool resume_lost = false; +#endif + u_int8_t data = 0; + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + suspended = (data & kPowerNVRAMiBootStateModeMask) == kPowerNVRAMiBootStateModeSuspended; + if (suspended) { + if (resume_lost) { + data &= ~kPowerNVRAMiBootStateModeMask; + data |= kPowerNVRAMiBootStateModeNormalBoot; + power_set_nvram(kPowerNVRAMiBootStateKey, data); + suspended = false; + } + } +#endif // WITH_CLASSIC_SUSPEND_TO_RAM + return suspended; +} + +void +power_will_resume(void) +{ +#if WITH_CLASSIC_SUSPEND_TO_RAM + u_int8_t data = 0; + power_get_nvram(kPowerNVRAMiBootStateKey, &data); + data &= ~kPowerNVRAMiBootStateModeMask; + data |= kPowerNVRAMiBootStateModeResumed; + power_set_nvram(kPowerNVRAMiBootStateKey, data); + + pmu_will_resume(); +#endif // WITH_CLASSIC_SUSPEND_TO_RAM +} + +bool +power_get_diags_dock(void) +{ +#if WITH_HW_TRISTAR + // check the third byte of ID response for DI (diagnostics mode) bit + uint8_t digital_id[6]; + if (!tristar_read_id(digital_id)) return false; + return digital_id[2] & (1 << 4); +#else + unsigned id; + return !power_read_dock_id(&id) && (id == 0x07); +#endif +} diff --git a/lib/power/rules.mk b/lib/power/rules.mk new file mode 100644 index 0000000..b86fb00 --- /dev/null +++ b/lib/power/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2013 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/power.o diff --git a/lib/profile/profile.c b/lib/profile/profile.c new file mode 100644 index 0000000..6df4cfd --- /dev/null +++ b/lib/profile/profile.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +#define MAX_PROFILE_ENTRIES ((PROFILE_BUF_SIZE - sizeof(struct profile_buffer)) / sizeof(struct profile_event)) + +#if PRODUCT_IBSS || PRODUCT_LLB +#if defined PROFILE_BUF_BASE +static struct profile_buffer *profile_buffer = (struct profile_buffer *)PROFILE_BUF_BASE; +#else +#define PROFILE_BUF_SIZE (0x400) +union { + uint8_t buffer[PROFILE_BUF_SIZE]; + struct profile_buffer profile_buffer; +} profile_union; +static struct profile_buffer *profile_buffer = &profile_union.profile_buffer; +#endif +#else +#define PROFILE_BUF_SIZE PANIC_SIZE +static struct profile_buffer *profile_buffer = (struct profile_buffer *)PANIC_BASE; +#endif + +void profile_init(void) +{ +#if PRODUCT_IBSS || PRODUCT_LLB + profile_buffer->magic = 'BTRC'; + profile_buffer->count = 0; + profile_buffer->pc_bytes = sizeof(addr_t); + /* At startup this value isn't known. We'll fill it in at handoff + at which time it should definitely be known */ + profile_buffer->timer_ticks_per_sec = 0; +#endif + PROFILE_1('INIT'); +} + +void profile(addr_t pc, uint32_t data1, uint32_t data2) +{ + struct profile_event *next_entry; + if (profile_buffer->count < MAX_PROFILE_ENTRIES) { + next_entry = &profile_buffer->events[profile_buffer->count++]; + next_entry->time = timer_get_ticks(); + next_entry->pc = pc; + next_entry->data1 = data1; + next_entry->data2 = data2; + }; +} + +extern uint32_t invalidate_time; + +void profile_handoff(void) +{ + PROFILE_ENTER('HOF'); + if ((void *)profile_buffer != (void *)PANIC_BASE) { + size_t buffer_size; + + profile_buffer->timer_ticks_per_sec = timer_get_tick_rate(); + buffer_size = PROFILE_BUF_SIZE > PANIC_SIZE ? PANIC_SIZE : PROFILE_BUF_SIZE; + + bcopy(profile_buffer, (void *)PANIC_BASE, buffer_size); + profile_buffer = (struct profile_buffer *)PANIC_BASE; + } + PROFILE_EXIT('HOF'); +} diff --git a/lib/profile/rules.mk b/lib/profile/rules.mk new file mode 100644 index 0000000..099a00d --- /dev/null +++ b/lib/profile/rules.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2012 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# Don't allow the profiling system to be built in firmware built +# by B&I. The boot profile trashes the panic buffer, which would +# not be a good thing on firmware released to engineering or production +ifneq ($(BUILDING_UNDER_XBS),) +$(error Profiling system must not be included in B&I-built iBoots) +endif + +OPTIONS += WITH_PROFILE=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/profile.o diff --git a/lib/ramdisk/library.mk b/lib/ramdisk/library.mk new file mode 100644 index 0000000..d5ca436 --- /dev/null +++ b/lib/ramdisk/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBRAMDISK_DIR := $(GET_LOCAL_DIR) +LIBRAMDISK_BUILD := $(call TOLIBDIR,$(LIBRAMDISK_DIR)/LIBRAMDISK.a) +COMMONLIBS += LIBRAMDISK + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBRAMDISK_OBJS := $(LIBRAMDISK_DIR)/ramdisk.o + +LIBRAMDISK_OBJS := $(call TOLIBOBJDIR,$(LIBRAMDISK_OBJS)) + +ALL_DEPS += $(LIBRAMDISK_OBJS:%o=%d) + +$(LIBRAMDISK_BUILD): $(LIBRAMDISK_OBJS) + +endif diff --git a/lib/ramdisk/ramdisk.c b/lib/ramdisk/ramdisk.c new file mode 100644 index 0000000..51020fa --- /dev/null +++ b/lib/ramdisk/ramdisk.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +addr_t gRAMDiskAddr = 0; +size_t gRAMDiskSize = 0; + +int ramdisk_init(void) +{ + gRAMDiskAddr = 0; + gRAMDiskSize = 0; + + return 0; +} + +int do_ramdisk(int argc, struct cmd_arg *argv) +{ + addr_t addr = mib_get_addr(kMIBTargetDefaultLoadAddress); + uint32_t len, type; + + len = env_get_uint("filesize", 0); + +#if !RELEASE_BUILD + if ((argc > 3) || ((argc > 1) && !strcmp("help", argv[1].str))) { + printf("usage:\n\t%s [] [
]\n", argv[0].str); + return -1; + } + + addr = env_get_uint("loadaddr", addr); + + if (argc > 1) + len = argv[1].u; + if (argc > 2) + addr = argv[2].u; +#endif + if (len == 0) { + printf("filesize variable invalid or not set, aborting\n"); + return -1; + } + + if (!security_allow_memory((void *)addr, len)) { + printf("Permission Denied\n"); + return -1; + } + + gRAMDiskAddr = mib_get_addr(kMIBTargetDefaultRamdiskAddress); + gRAMDiskSize = len; + type = IMAGE_TYPE_RAMDISK; + if (image_load_memory(addr, len, &gRAMDiskAddr, &gRAMDiskSize, &type, 1, NULL, 0)) { + printf("Ramdisk image not valid\n"); + gRAMDiskAddr = 0; + gRAMDiskSize = 0; + return -1; + } + + /* consolidate environment */ + security_consolidate_environment(); + + dprintf(DEBUG_INFO, "loaded ramdisk at %p of size %#zx, from image at %p\n", (void *)gRAMDiskAddr, gRAMDiskSize, (void *)addr); + + return 0; +} + +int +load_ramdisk_file(const char *path) +{ + u_int32_t type; + + if (!mib_get_bool(kMIBTargetWithFileSystem)) { + return -1; + } + + /* load to default addresses */ + gRAMDiskAddr = mib_get_addr(kMIBTargetDefaultRamdiskAddress); + gRAMDiskSize = mib_get_size(kMIBTargetDefaultRamdiskSize); + + type = IMAGE_TYPE_RAMDISK; + if (image_load_file(path, &gRAMDiskAddr, &gRAMDiskSize, &type, 1, NULL, 0)) { + dprintf(DEBUG_INFO, "failed to load ramdisk from %s\n", path); + gRAMDiskAddr = 0; + gRAMDiskSize = 0; + return -1; + } + + /* consolidate environment */ + security_consolidate_environment(); + + return 0; +} + +int load_ramdisk(addr_t *ramdisk_addr, size_t *ramdisk_size) +{ + if ((gRAMDiskAddr == 0) || (gRAMDiskSize == 0)) { + gRAMDiskAddr = mib_get_addr(kMIBTargetDefaultRamdiskAddress); + gRAMDiskSize = mib_get_size(kMIBTargetDefaultRamdiskSize); + + if (image_load_type(&gRAMDiskAddr, &gRAMDiskSize, IMAGE_TYPE_RAMDISK, 0)) { + gRAMDiskAddr = 0; + gRAMDiskSize = 0; + return -1; + } + } + + if ((gRAMDiskAddr == 0) || (gRAMDiskSize == 0)) { + dprintf(DEBUG_INFO, "ramdisk: failed to find ramdisk\n"); + return -1; + } + + /* consolidate environment */ + security_consolidate_environment(); + + *ramdisk_addr = gRAMDiskAddr; + *ramdisk_size = gRAMDiskSize; + + return 0; +} + diff --git a/lib/ramdisk/rules.mk b/lib/ramdisk/rules.mk new file mode 100644 index 0000000..87da862 --- /dev/null +++ b/lib/ramdisk/rules.mk @@ -0,0 +1,12 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_RAMDISK=1 +LIBRARY_MODULES += lib/ramdisk diff --git a/lib/random/library.mk b/lib/random/library.mk new file mode 100644 index 0000000..103e04b --- /dev/null +++ b/lib/random/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBRANDOM_DIR := $(GET_LOCAL_DIR) +LIBRANDOM_BUILD := $(call TOLIBDIR,$(LIBRANDOM_DIR)/LIBRANDOM.a) +COMMONLIBS += LIBRANDOM + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBRANDOM_OBJS := $(LIBRANDOM_DIR)/random.o + +LIBRANDOM_OBJS := $(call TOLIBOBJDIR,$(LIBRANDOM_OBJS)) + +ALL_DEPS += $(LIBRANDOM_OBJS:%o=%d) + +$(LIBRANDOM_BUILD): $(LIBRANDOM_OBJS) + +endif diff --git a/lib/random/random.c b/lib/random/random.c new file mode 100644 index 0000000..ce8bb6e --- /dev/null +++ b/lib/random/random.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2010-2011, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +static int random_get_bytes_internal(uint8_t *buffer, size_t length, uint32_t entropy_ratio, void *entropy_buffer, size_t entropy_buffer_size); + +int random_get_bytes(uint8_t *buffer, size_t length) +{ + uint32_t entropy_ratio = mib_get_u32(kMIBPlatformEntropyRatio); + return random_get_bytes_internal(buffer, length, entropy_ratio, NULL, 0); +} + +// Called when randomness is needed but the heap is not available to store +// the entropy pool which is instead stored in a caller-provided buffer. +int random_get_bytes_noheap(uint8_t *buffer, size_t length, void *entropy_buffer, size_t entropy_buffer_size) +{ + uint32_t entropy_ratio = mib_get_u32(kMIBPlatformEntropyRatio); + return random_get_bytes_internal(buffer, length, entropy_ratio, entropy_buffer, entropy_buffer_size); +} + +#if DEBUG_BUILD + +int random_get_bytes_debug(uint8_t *buffer, size_t length, uint32_t entropy_ratio) +{ + if (entropy_ratio == 0) { + entropy_ratio = mib_get_u32(kMIBPlatformEntropyRatio); + } + + return random_get_bytes_internal(buffer, length, entropy_ratio, NULL, 0); +} + +#endif + +static uint32_t random_count; +static uint8_t random_pool[CCSHA1_OUTPUT_SIZE]; + +static int random_get_bytes_internal(uint8_t *buffer, size_t length, uint32_t entropy_ratio, void *entropy_buffer, size_t entropy_buffer_size) +{ + uint32_t cnt, chunk, entropy_pool_size; + uint32_t *entropy_pool = NULL; + + entropy_pool_size = entropy_ratio * CCSHA1_OUTPUT_SIZE; + + RELEASE_ASSERT(entropy_buffer == NULL || entropy_pool_size <= entropy_buffer_size); + + while (length > 0) { + // Make random data by calculating a sha-1 hash of entropy data + if (random_count == 0) { + // lazy intialize: we might need to go to the entropy well + // more than once for a big request, or not at all for + // small requests we already have whitened randomness for + if (entropy_pool == NULL) { + if (entropy_buffer == NULL) + entropy_pool = malloc(entropy_pool_size); + else + entropy_pool = entropy_buffer; + } + + for (cnt = 0; cnt < (entropy_pool_size / sizeof(uint32_t)); cnt++) { + entropy_pool[cnt] = platform_get_entropy(); + } + + sha1_calculate(entropy_pool, entropy_pool_size, random_pool); + + random_count = CCSHA1_OUTPUT_SIZE; + } + + chunk = (length >= random_count) ? random_count : length; + memcpy(buffer, random_pool - random_count + CCSHA1_OUTPUT_SIZE, chunk); + + random_count -= chunk; + + buffer += chunk; + length -=chunk; + } + + if (entropy_pool != NULL) { + if (entropy_buffer == NULL) { + free(entropy_pool); + } else { + memset(entropy_buffer, 0, entropy_pool_size); + } + } + + return 0; +} diff --git a/lib/random/rules.mk b/lib/random/rules.mk new file mode 100644 index 0000000..f937dbe --- /dev/null +++ b/lib/random/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2010, 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_RANDOM=1 +LIBRARY_MODULES += lib/random + diff --git a/lib/syscfg/library.mk b/lib/syscfg/library.mk new file mode 100644 index 0000000..d89c1c6 --- /dev/null +++ b/lib/syscfg/library.mk @@ -0,0 +1,27 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBSYSCFG_DIR := $(GET_LOCAL_DIR) +LIBSYSCFG_BUILD := $(call TOLIBDIR,$(LIBSYSCFG_DIR)/LIBSYSCFG.a) +COMMONLIBS += LIBSYSCFG + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBSYSCFG_OBJS := $(LIBSYSCFG_DIR)/syscfg.o + +LIBSYSCFG_OBJS := $(call TOLIBOBJDIR,$(LIBSYSCFG_OBJS)) + +ALL_DEPS += $(LIBSYSCFG_OBJS:%o=%d) + +$(LIBSYSCFG_BUILD): $(LIBSYSCFG_OBJS) + +endif diff --git a/lib/syscfg/rules.mk b/lib/syscfg/rules.mk new file mode 100644 index 0000000..dc45a30 --- /dev/null +++ b/lib/syscfg/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2007, 2011, 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_SYSCFG=1 +LIBRARY_MODULES += lib/syscfg diff --git a/lib/syscfg/syscfg.c b/lib/syscfg/syscfg.c new file mode 100644 index 0000000..b626487 --- /dev/null +++ b/lib/syscfg/syscfg.c @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2007-2012, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +/* + * Support for detecting and reading the iPod-style SysCfg data + */ + +#include +#include +#include +#include +#include +#include + +static u_int32_t syscfgKeyCount; +static uint8_t *syscfgData; +static size_t syscfgDataLength; + +struct syscfgHeader { + u_int32_t shMagic; +#define kSysCfgHeaderMagic 'SCfg' + u_int32_t shSize; + u_int32_t shMaxSize; + u_int32_t shVersion; + u_int32_t shBigEndian; + u_int32_t shKeyCount; +}; + +void syscfg_reinit(void) +{ + free(syscfgData); + syscfgDataLength = 0; + syscfgData = NULL; + syscfgKeyCount = 0; +} + +int +do_syscfg(int argc, struct cmd_arg *args) +{ + struct syscfgHeader hdr; + struct syscfgMemEntry entry; + int index, curArg; + size_t size, i, j; + char *sfx; + bool isExt; + size_t lowExt; + size_t highExt; + size_t extSize = 0; + uint8_t *buffer; + bool showExt = false; + + if (NULL == syscfgData) { + printf("syscfg is not initialized!\n"); + return(0); + } + + if (syscfgDataLength < sizeof(struct syscfgHeader)) + return (0); + + memcpy(&hdr, syscfgData, sizeof(struct syscfgHeader)); + printf("version 0x%08x with %d entries\n\n", hdr.shVersion, hdr.shKeyCount); + + lowExt = hdr.shMaxSize; + highExt = hdr.shSize; + + for (index = 0; ; index++) { + if (!syscfgFindByIndex(index, &entry)) + break; + + if (argc > 1) { + + /* When parameters are present, always show in extended mode */ + showExt = true; + + /* If the first parameter is ext, assume match in all cases by skipping the match block */ + if(strcmp("ext", args[1].str) != 0) { + + /* Scan the list of arguments looking for a match */ + for (curArg = 1; curArg < argc; curArg ++) { + if (((entry.seTag >> 24) & 0xFF) == args[curArg].str[0] && + ((entry.seTag >> 16) & 0xFF) == args[curArg].str[1] && + ((entry.seTag >> 8) & 0xFF) == args[curArg].str[2] && + ((entry.seTag >> 0) & 0xFF) == args[curArg].str[3]) + break; + } + if (curArg == argc) continue; + } + } + + sfx = ""; + + /* Is this a standard entry or an Offset entry? */ + if (entry.seDataOffset != 0) { + size = entry.seDataSize; + if (size > sizeof(entry.seData)) { + + /* The Size of the entry is too big for the structure + * Should it be truncated? */ + if (!showExt) { + size = sizeof(entry.seData); + sfx = "..."; + } + } + if (entry.seDataOffset + entry.seDataSize > hdr.shMaxSize) { + printf("entry->seDataOffset not within syscfgData"); + return(0); + } + + /* Allocate the requested space aligned on 16 bytes to zero + * pad the display. */ + buffer = calloc(1, (size + 15) & ~15); + memcpy(buffer, syscfgData + entry.seDataOffset, size); + + // Calculate the extents of the offset section + if (entry.seDataOffset < lowExt) { + lowExt = entry.seDataOffset; + } + if ((entry.seDataOffset + entry.seDataSize) > highExt) { + highExt = entry.seDataOffset + entry.seDataSize; + } + isExt = true; + } else { + /* allocate enough space to mirror the entrys buffer */ + size = sizeof(entry.seData); + + buffer = malloc(sizeof(entry.seData)); + memcpy(buffer, entry.seData, size); + + isExt = false; + } + printf("0x%08x '%c%c%c%c' %4dB %c ", + entry.seTag, + (entry.seTag >> 24) & 0xff, + (entry.seTag >> 16) & 0xff, + (entry.seTag >> 8) & 0xff, + entry.seTag & 0xff, + entry.seDataSize, + isExt ? '*' : ' '); + + /* Format the data in nice columns */ + for (i = 0; i < size; i += 16 ) { + printf("%*s", (i >= 16) ? 28 : 0, ""); + + /* Starting at the offset, display the data values up to 4 per line. */ + for (j = i; j < (i + 16); j += 4) { + printf("0x%08x ", *((u_int32_t *)&buffer[j])); + } + + printf("%s\n", sfx); + } + + free(buffer); + } + + printf("\n"); + printf("header @ 0-%zu", sizeof(struct syscfgHeader) - 1); + printf("; entries @ %zu-%d", sizeof(struct syscfgHeader), hdr.shSize - 1); + if (lowExt < highExt) { + extSize = highExt - lowExt; + printf("; extra data @ %zu-%zu", lowExt, highExt - 1); + } + printf("; using %zu of %d bytes\n", hdr.shSize + extSize, hdr.shMaxSize); + + return(0); +} + +bool +syscfgInitWithBdev(const char *bdevName) +{ + int result; + struct blockdev *candidate; + struct syscfgHeader hdr; + + if (syscfgData != NULL) + return(false); + + /* look for the suggested bdev */ + if ((candidate = lookup_blockdev(bdevName)) == NULL) { + dprintf(DEBUG_INFO, "syscfg: can't find bdev \"%s\"\n", bdevName); + return(false); + } + + /* Make sure it's big enough */ + if (candidate->total_len <= kSysCfgBdevOffset + sizeof(hdr)) { + dprintf(DEBUG_INFO, "syscfg: bdev size 0x%llx too small\n", candidate->total_len); + return (false); + } + + /* look for the header */ + if (blockdev_read(candidate, &hdr, kSysCfgBdevOffset, sizeof(hdr)) < (int)sizeof(hdr)) { + dprintf(DEBUG_INFO, "syscfg: bdev read fail\n"); + return(false); + } + + if (hdr.shMagic != kSysCfgHeaderMagic) { + dprintf(DEBUG_INFO, "syscfg: bad magic\n"); + return(false); + } + + dprintf(DEBUG_CRITICAL, "syscfg: version 0x%08x with %d entries using %d of %d bytes\n", + hdr.shVersion, hdr.shKeyCount, hdr.shSize, hdr.shMaxSize); + + /* If there is a syscfg there will also be diag info... protect them. */ + blockdev_set_protection(candidate, 0x2000, 0x6000); + + syscfgDataLength = candidate->total_len - kSysCfgBdevOffset; + if (hdr.shSize < syscfgDataLength) + syscfgDataLength = hdr.shMaxSize; + + syscfgData = malloc(syscfgDataLength); + + result = blockdev_read(candidate, syscfgData, kSysCfgBdevOffset, syscfgDataLength); + + if (result < 0 || (size_t)result < syscfgDataLength) { + dprintf(DEBUG_INFO, "syscfg: bdev read fail (%d)\n", result); + syscfg_reinit(); + return false; + } + + syscfgKeyCount = hdr.shKeyCount; + + return(true); +} + +void * +syscfgGetData(struct syscfgMemEntry *entry) +{ + /* Handle data stored externally from the entry */ + if (entry->seDataOffset != 0) { + if (entry->seDataOffset > syscfgDataLength) + return NULL; + if (entry->seDataOffset + entry->seDataSize > syscfgDataLength) + return NULL; + + return syscfgData + entry->seDataOffset; + } else { + return entry->seData; + } +} + +uint32_t +syscfgGetSize(struct syscfgMemEntry *entry) +{ + return entry->seDataSize; +} + +int +syscfgCopyDataForTag(u_int32_t tag, u_int8_t *buffer, size_t size) +{ + bool result; + struct syscfgMemEntry entry; + void *data; + + result = syscfgFindByTag(tag, &entry); + if (!result) + return(-1); + if (size > entry.seDataSize) + size = entry.seDataSize; + + data = syscfgGetData(&entry); + if (data == NULL) + return(-1); + + memcpy(buffer, data, size); + + // XXX check what to do with the assert that was removed from here + return size; +} + +bool +syscfgFindByTag(u_int32_t tag, struct syscfgMemEntry *entry) +{ + static struct syscfgMemEntry temp; + bool result; + u_int32_t index; + + for (index = 0; index < syscfgKeyCount; index++) { + result = syscfgFindByIndex(index, &temp); + if (result && (temp.seTag == tag)) { + memcpy(entry, &temp, sizeof(*entry)); + return true; + } + } + return false; +} + +bool +syscfgFindByIndex(u_int32_t index, struct syscfgMemEntry *result) +{ + struct syscfgEntry entry; + struct syscfgEntryCNTB *entryCNTB; + + if (index >= syscfgKeyCount) + return false; + + size_t offset = sizeof(struct syscfgHeader) + index * sizeof(struct syscfgEntry); + if (offset >= syscfgDataLength || offset + sizeof(struct syscfgEntry) >= syscfgDataLength) + return false; + + memcpy(&entry, syscfgData + offset, sizeof(entry)); + + if (entry.seTag == 'CNTB') { + entryCNTB = (struct syscfgEntryCNTB *)&entry; + result->seTag = entryCNTB->seRealTag; + memset(result->seData, 0, sizeof(result->seData)); + result->seDataSize = entryCNTB->seDataSize; + result->seDataOffset = entryCNTB->seDataOffset; + } else { + result->seTag = entry.seTag; + memcpy(result->seData, entry.seData, sizeof(result->seData)); + result->seDataSize = sizeof(result->seData); + result->seDataOffset = 0; + } + return true; +} + +bool +syscfg_find_tag(uint32_t tag, void **data_out, uint32_t *size_out) +{ + static struct syscfgMemEntry result; + + if (syscfgFindByTag(tag, &result)) { + if (data_out) { + *data_out = syscfgGetData(&result); + } + if (size_out) { + *size_out = syscfgGetSize(&result); + } + + return true; + } else { + return false; + } +} diff --git a/lib/syscfg/tests.c b/lib/syscfg/tests.c new file mode 100644 index 0000000..6b7576f --- /dev/null +++ b/lib/syscfg/tests.c @@ -0,0 +1,252 @@ +#include +#include +#include +#include +#include + +#define TEST_SYSCFG_BLOCKDEV_SIZE 0x8000 + +extern void syscfg_reinit(void); + +const uint32_t test_syscfg_data1[] = +{ + 'SCfg', // magic + 0x1000, // size + 0x1000, // max size + 0x0, // version + 0x0, // big endian (NOT) + 9, // key count + + 'Ent0', // key + 0x0, 0x0, 0x0, 0x0, // data + + 'Ent1', // key + 0x1, 0x1, 0x1, 0x1, // data + + 'Ent2', // key + 0x200, 0x200, // data + 0x200, 0x200, + + 'Ent3', // key + 0x30000, 0x30000, // data + 0x30000, 0x30000, + + 'Ent4', // key + 0x4000000, 0x4000000, // data + 0x4000000, 0x4000000, + + 'CNTB', 'Ent5', + 4, 0x180, 0, // size 4 offset 0x100 + + 'CNTB', 'Ent6', + 8, 0x184, 0, // size 4 offset 0x100 + + 'CNTB', 'Ent7', + 1, 0x18c, 0, // size 1 offset 0x104 + + 'CNTB', 'Ent8', + 32, 0x190, 0, // size 1 offset 0x104 + + // padding, delete an entry here whenever adding an entry above + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + // CNTB block data starts at 0x100 + 0xabcd1234, // for 'Ent5' + 0x11111111, // for 'Ent6' + 0x22222222, // . + 0xDDDDDDAA, // for 'Ent7', only 'AA' part is actually valid + 0x12345678, // for 'Ent8' + 0x23456789, // . + 0x3456789a, // . + 0x456789ab, // . + 0x567891bc, // . + 0x6789abcd, // . + 0x789abcde, // . + 0x89abcdef, // . +}; + +const uint32_t test_syscfg_data3[] = +{ + 'SCfg', // magic + 0x100, // size + 0x100, // max size + 0x0, // version + 0x0, // big endian (NOT) + 4, // key count + + 'CNTB', 'Ent1', + 8, 0xf8, 0, // pointer is right at end of advertised size, but ok + + 'CNTB', 'Ent2', + 4, 0x200, 0, // pointer is past advertised size + + 'CNTB', 'Ent3', + 2, 0xff, 0, // pointer plus size puts over the end + + 'CNTB', 'Ent4', + 32, 0x8000, 0, // pointer is past end of bdev + + // actual CNTB block data is just padded out with zeroes +}; + +// XXX add test with malformed data advertising way too big size + +void test_setup_backing(void *backing, const void *data, size_t data_size) +{ + TEST_ASSERT_NOT_NULL(backing); + + memset(backing, 0, TEST_SYSCFG_BLOCKDEV_SIZE); + + memcpy((uint8_t *)backing + 0x4000, data, data_size); +} + + +void test_syscfg1(uintptr_t param) +{ + struct blockdev *bdev; + + void *backing = malloc(TEST_SYSCFG_BLOCKDEV_SIZE); + + bdev = create_mem_blockdev("syscfg_bdev1", backing, TEST_SYSCFG_BLOCKDEV_SIZE, 0x1000); + TEST_ASSERT_NOT_NULL(bdev); + + register_blockdev(bdev); + + // Initializing with wrong name should result in failure + TEST_ASSERT_EQ(syscfgInitWithBdev("wrong"), false); + // and then a subsequent read should fail + { + uint8_t resultData[16]; + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent0', resultData, sizeof(resultData)), -1); + } + + // Initializing with empty syscfg should result in failure + memset(backing, 0, TEST_SYSCFG_BLOCKDEV_SIZE); + TEST_ASSERT_EQ(syscfgInitWithBdev("syscfg_bdev1"), false); + // and then a subsequent read should fail + { + uint8_t resultData[16]; + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent0', resultData, sizeof(resultData)), -1); + } + + test_setup_backing(backing, test_syscfg_data1, sizeof(test_syscfg_data1)); + + // initializing with a valid syscfg should work + TEST_ASSERT_EQ(syscfgInitWithBdev("syscfg_bdev1"), true); + + { + uint8_t resultData[16]; + + // looking for a non-existant tag should return failure + TEST_ASSERT_EQ(syscfgCopyDataForTag('EntX', resultData, sizeof(resultData)), -1); + + // looking for ones that exist should work + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent0', resultData, sizeof(resultData)), sizeof(resultData)); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 0, 0, 0, 0), sizeof(resultData)); + + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent1', resultData, sizeof(resultData)), sizeof(resultData)); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 1, 1, 1, 1), sizeof(resultData)); + + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent2', resultData, sizeof(resultData)), sizeof(resultData)); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 0x200, 0x200, 0x200, 0x200), sizeof(resultData)); + + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent3', resultData, sizeof(resultData)), sizeof(resultData)); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 0x30000, 0x30000, 0x30000, 0x30000), sizeof(resultData)); + + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent4', resultData, sizeof(resultData)), sizeof(resultData)); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 0x4000000, 0x4000000, 0x4000000, 0x4000000), sizeof(resultData)); + + // Requesting an amount smaller than the entry size results in just that amount + memset(resultData, 0xff, sizeof(resultData)); + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent1', resultData, 4), 4); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 1, 0xffffffff, 0xffffffff, 0xffffffff), sizeof(resultData)); + + } + + { + uint8_t resultData[32]; + + // Requesting an amount bigger than the entry size results in a short read + memset(resultData, 0xff, sizeof(resultData)); + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent1', resultData, sizeof(resultData)), 16); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 1, 1, 1, 1), 16); + TEST_ASSERT_MEM_EQ(resultData + 16, TEST_ARRAY(uint32_t, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), 16); + } + + { + uint8_t resultData[4]; + + // Reading from a CNTB-style entry should work and return the size given in the entry + memset(resultData, 0xff, sizeof(resultData)); + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent5', resultData, sizeof(resultData)), sizeof(resultData)); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 0xabcd1234), sizeof(resultData)); + } + + { + uint8_t resultData[8]; + + // Short reads from CNTB blocks should still result in the short size being returned + memset(resultData, 0xff, sizeof(resultData)); + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent6', resultData, 4), 4); + TEST_ASSERT_MEM_EQ(resultData, TEST_ARRAY(uint32_t, 0x11111111, 0xffffffff), sizeof(resultData)); + } +} + +void test_syscfg2(uintptr_t param) +{ + struct blockdev *bdev; + void *backing = malloc(TEST_SYSCFG_BLOCKDEV_SIZE); + test_setup_backing(backing, test_syscfg_data1, sizeof(test_syscfg_data1)); + + // bdev has the right data in it, but that data is past the end of its advertised length + bdev = create_mem_blockdev("syscfg_bdev2", backing, 0x4000, 0x1000); + + register_blockdev(bdev); + + TEST_ASSERT_EQ(syscfgInitWithBdev("syscfg_bdev2"), false); +} + +void test_syscfg3(uintptr_t param) +{ + struct blockdev *bdev; + uint8_t resultData[8]; + void *backing = malloc(TEST_SYSCFG_BLOCKDEV_SIZE); + + test_setup_backing(backing, test_syscfg_data3, sizeof(test_syscfg_data3)); + + bdev = create_mem_blockdev("syscfg_bdev3", backing, TEST_SYSCFG_BLOCKDEV_SIZE, 0x1000); + + register_blockdev(bdev); + + TEST_ASSERT_EQ(syscfgInitWithBdev("syscfg_bdev3"), true); + + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent1', resultData, 8), 8); + + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent2', resultData, 8), -1); + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent3', resultData, 8), -1); + TEST_ASSERT_EQ(syscfgCopyDataForTag('Ent4', resultData, 8), -1); +} + +// XXX add a test for syscfg_find_tag + +static struct test_suite syscfg_test_suite = { + .name = "syscfg", + .description = "tests the syscfg library", + .setup_function = syscfg_reinit, + .test_cases = { + { "syscfg", test_syscfg1, 0 }, + { "syscfg", test_syscfg2, 0 }, + { "syscfg", test_syscfg3, 0 }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(syscfg_test_suite); diff --git a/lib/syscfg/tests.mk b/lib/syscfg/tests.mk new file mode 100644 index 0000000..269d94f --- /dev/null +++ b/lib/syscfg/tests.mk @@ -0,0 +1,26 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := syscfg + +TEST_OBJS := \ + $(LOCAL_DIR)/syscfg.o \ + lib/blockdev/blockdev.o \ + lib/blockdev/mem_blockdev.o \ + lib/libc/log2.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests.o + +TEST_CFLAGS := \ + -DCPU_CACHELINE_SIZE=32 diff --git a/lib/tftp/debug.c b/lib/tftp/debug.c new file mode 100644 index 0000000..bfa0702 --- /dev/null +++ b/lib/tftp/debug.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +static int tftp_cmd_getter( const uchar * address, uint offset, uint * pamount, void * cookie ) +{ + uchar * baseAddress = (uchar *)cookie; + + if (!security_allow_memory(baseAddress+offset, *pamount)) { + printf("Permission Denied\n"); + return -1; + } + + memcpy( baseAddress+offset, address, *pamount ); + + return 0; +} + + +int do_tftp(int argc, struct cmd_arg *args) +{ + if (argc < 2) { + printf("not enough args.n\n"); +usage: + printf("%s get [
]\n", args[0].str); + printf("%s getscript [
]\n", args[0].str); + return -1; + } + + if (!strcmp("get", args[1].str) || !strcmp("getscript", args[1].str)) { + if (argc < 3) { + printf("not enough arguments.\n"); + goto usage; + } + + int maxlen = 0xffff*512; + char *addr = (char *)env_get_uint("loadaddr", DEFAULT_LOAD_ADDRESS); + int err; + + if (argc >= 4) + addr = (char *)args[3].u; + + uint32_t serverip; + if (env_get_ipaddr("serverip", &serverip) < 0) { + printf("serverip environment variable not set or malformed\n"); + return -1; + } + + err = tftp_transfer(args[2].str, htonl(serverip), addr, &maxlen, false); + + if (err < 0) { + printf("error fetching file\n"); + return err; + } + + /* stick the length into the environment */ + env_set_uint("filesize", maxlen, 0); + + if (!strcmp("getscript", args[1].str)) { + if (err >= 0) { + addr[maxlen] = 0; + debug_run_script(addr); + } + } + } else { + printf("unrecognized command\n"); + goto usage; + } + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(tftp, do_tftp, "tftp via ethernet to/from device", NULL); diff --git a/lib/tftp/rules.mk b/lib/tftp/rules.mk new file mode 100644 index 0000000..4524e69 --- /dev/null +++ b/lib/tftp/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_TFTP=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/tftp.o \ + $(LOCAL_DIR)/debug.o diff --git a/lib/tftp/tftp.c b/lib/tftp/tftp.c new file mode 100644 index 0000000..53ba4eb --- /dev/null +++ b/lib/tftp/tftp.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct { + uint32_t destip; + uint16_t destport; + uint16_t srcport; + mymbuf_t * outgoingbuf; + int errcount; + struct callout timer; + + volatile int complete; + + int operation; + union { + struct r { + char * destbuffer; + int destlen; + int pos; + int blocknum; + }r; + struct { + char * sourcebuffer; + int left; + int blocknum; + }w; + } u; +} tftp_stat; + +#define TFTP_RECEIVE 0 +#define TFTP_SEND 1 + +#define TFTP_BLOCKSIZE 512 +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERR 5 + +static void tftp_resetbuf(void) +{ + mbuf_setlength(tftp_stat.outgoingbuf,0); + mbuf_setoffset(tftp_stat.outgoingbuf,14+20+8); +} + +static int tftp_sendack(uint32_t destip,uint32_t destport,int blocknum) +{ +// mymbuf_t *data = mbuf_initialize(4,14+20+8,0); + uint16_t *rawdata; + tftp_resetbuf(); + rawdata = (uint16_t *)mbuf_tail(tftp_stat.outgoingbuf,4); + + rawdata[0] = htons(TFTP_ACK); + rawdata[1] = htons(blocknum); + + transmit_udp(tftp_stat.outgoingbuf,destip,destport,tftp_stat.srcport); +// mbuf_destroy(data); + return 0; +} + +static int tftp_senddata(uint32_t destip,uint32_t destport, int blocknum, char *inputdata,int datalen) +{ +// mymbuf_t *data = mbuf_initialize(4+datalen,14+20+8,0); + uint16_t *rawdata; + tftp_resetbuf(); + rawdata = (uint16_t *)mbuf_tail(tftp_stat.outgoingbuf,4+datalen); + + rawdata[0] = htons(TFTP_DATA); + rawdata[1] = htons(blocknum); + memcpy((char*)&rawdata[2],inputdata,datalen); + + transmit_udp(tftp_stat.outgoingbuf,destip,destport,tftp_stat.srcport); +// mbuf_destroy(data); + return 0; +} + + +static int tftp_receive_listener(char *buf, int offset,int len, void *arg) +{ + uint16_t *databuf =(uint16_t *)(buf+offset); + uint16_t opcode = ntohs(databuf[0]); + int blocknum; + udpinfo_t *info = (udpinfo_t *)arg; + int sendlength; + int errnum; + int datalen = info->length - 4; //len - offset - 4; //<- would fail if the ethernet added a trailer. + static const char *spinchars = "|/-\\"; + static int spinidx = 0; + static int spincount = 0; + + callout_reset(&tftp_stat.timer, 0); + tftp_stat.destip = info->srcip; + tftp_stat.destport = info->srcport; + blocknum = ntohs(databuf[1]); + +// printf("tftp_recv: opcode %d, blocknum %d\n", opcode, blocknum); + + switch(opcode) { + case TFTP_DATA: + //send ack + if(tftp_stat.u.r.pos + datalen <= tftp_stat.u.r.destlen) { + memcpy(tftp_stat.u.r.destbuffer+tftp_stat.u.r.pos,&databuf[2],datalen); + } else { + printf("Not enough space in databuffer(pos:%d,datalen: %d, destlen: %d\n",tftp_stat.u.r.pos,datalen,tftp_stat.u.r.destlen); + tftp_stat.complete = -1; + return -1; + } + tftp_stat.u.r.pos += datalen; + if(datalen != TFTP_BLOCKSIZE) { + tftp_sendack(info->srcip,info->srcport,blocknum); + tftp_stat.complete = 1; + break; + } + tftp_stat.u.r.blocknum = blocknum; + tftp_sendack(info->srcip,info->srcport,blocknum); + + // a user-comfort UI that uses less space than a bunch of dots + spincount += datalen; + if (spincount >= 65536) { + spincount = 0; + spinidx++; + if (spinchars[spinidx] == 0) + spinidx = 0; + putchar(spinchars[spinidx]); + putchar('\r'); + } + break; + case TFTP_ACK: + //blocknum 0 is ack for our metadata. + if(blocknum != 0) { + tftp_stat.u.w.left -= 512; + if(tftp_stat.u.w.left <= 0) { + tftp_stat.u.w.left = 0; + tftp_stat.complete = 1; + return 0; + } + } + sendlength = __min(tftp_stat.u.w.left,TFTP_BLOCKSIZE); + tftp_stat.u.w.blocknum = blocknum + 1; + + tftp_senddata(tftp_stat.destip,tftp_stat.destport,tftp_stat.u.w.blocknum,tftp_stat.u.w.sourcebuffer+((tftp_stat.u.w.blocknum-1) * TFTP_BLOCKSIZE),sendlength); + break; + case TFTP_ERR: + errnum = ntohs(databuf[1]); + printf("tftp error (%d) (%s)\n",errnum,(char*)&databuf[2]); + tftp_stat.complete = -1; + break; + default: + printf("unkown package %d\n",opcode); + } + return 0; +} + +static void tftp_timeout(struct callout *c, void *arg) +{ + callout_reset(c, 0); + tftp_stat.errcount++; + if(tftp_stat.errcount > 20) { // 10 seconds worth of retransmits + tftp_stat.complete = -1; + return; + } + if(tftp_stat.operation == TFTP_RECEIVE) { + tftp_sendack(tftp_stat.destip,tftp_stat.destport,tftp_stat.u.r.blocknum); + } else if(tftp_stat.operation == TFTP_SEND) { + tftp_senddata(tftp_stat.destip, tftp_stat.destport, tftp_stat.u.w.blocknum, + tftp_stat.u.w.sourcebuffer+((tftp_stat.u.w.blocknum-1) * TFTP_BLOCKSIZE), + __min(tftp_stat.u.w.left,TFTP_BLOCKSIZE)); + } else { + printf("Unknown mode\n"); + tftp_stat.complete = -1; + } + printf("Timeout\n"); +} + +int tftp_transfer(const char *filename, uint32_t ipaddr, char *buffer, int *maxlen, bool write) +{ +#if WITH_NET + char *pktbuf; + int handlerid; + int ret = 0; + utime_t perftime = system_time(); + int kb, filename_length, buf_length; + char serveripstr[32]; + + if(*maxlen > (0xffff * 512)) { + printf("TFTP (without extensions) can only handle max 32M tranfers\n"); + return -1; + } + + if(!security_allow_memory(buffer, *maxlen)) { + printf("Permission Denied\n"); + return -1; + } + + /* try to start the network stack, if it isn't already running */ + ret = start_network_stack(); + if (ret < 0) + return ret; + + ip2str((uint8_t *)&ipaddr, serveripstr, 32); + dprintf(DEBUG_INFO, "tftp: starting transfer of file '%s' on server %s to address %p\n", filename, serveripstr, buffer); + + tftp_stat.outgoingbuf = mbuf_initialize(516,14+20+8,0); //ip head + ether head + + tftp_resetbuf(); + memset(&tftp_stat.u,0,sizeof(tftp_stat.u)); + + if(write) { + tftp_stat.u.w.sourcebuffer = buffer; + tftp_stat.u.w.left = *maxlen; + } else { + tftp_stat.u.r.destbuffer = buffer; + tftp_stat.u.r.destlen = *maxlen; + } + tftp_stat.operation = write ? TFTP_SEND : TFTP_RECEIVE; + tftp_stat.destip = ipaddr; + tftp_stat.destport = 69; + tftp_stat.complete = tftp_stat.errcount = 0; + tftp_stat.srcport = (rand() + 1024) % 65536; + + filename_length = strlen(filename); + pktbuf = mbuf_tail(tftp_stat.outgoingbuf,2+filename_length+1+6); + if (pktbuf == 0) return -1; + buf_length = mbuf_getlength(tftp_stat.outgoingbuf); + *(uint16_t *)&pktbuf[0] = ntohs(write ? TFTP_WRQ : TFTP_RRQ); + strlcpy(&pktbuf[2],filename,buf_length-2); + strlcpy(&pktbuf[filename_length+3],"octet",buf_length-filename_length-3); + + /* try to prepopulate the arp cache */ + arp_fill(tftp_stat.destip, 5*1000*1000); + + handlerid = registerUDPHandler(tftp_stat.srcport,tftp_receive_listener); + if(transmit_udp(tftp_stat.outgoingbuf, tftp_stat.destip, tftp_stat.destport, tftp_stat.srcport) < 0) { + printf("Not able to transmit package.\n"); + unregisterUDPHandler(handlerid); + return -1; + } + //Start timeout handler + + callout_enqueue(&tftp_stat.timer, 500*1000, tftp_timeout, 0); //500ms without activity, send a new package. + while(tftp_stat.complete == 0) + task_yield(); + + if(tftp_stat.complete < 0) { + ret = -1; + goto out; + } + + if(write == false) { + *maxlen = tftp_stat.u.r.pos; + } + perftime = system_time() - perftime; + if(write) { + kb = (*maxlen - tftp_stat.u.w.left)/1024; + } else { + kb = tftp_stat.u.r.pos/1024; + } + + printf("%d KiB (%d bytes) tftp transfer completed at %d.%03d KiB/s\n", + kb, *maxlen, (kb*1000000)/perftime, (kb*1000000)%perftime); + +out: + unregisterUDPHandler(handlerid); + callout_dequeue(&tftp_stat.timer); + mbuf_destroy(tftp_stat.outgoingbuf); + tftp_stat.outgoingbuf = 0; + + return ret; +#else /* !WITH_NET */ + printf ("network not available\n"); + return -1; +#endif /* WITH_NET */ +} diff --git a/lib/ticket/DERApTicket.c b/lib/ticket/DERApTicket.c new file mode 100644 index 0000000..2bfb306 --- /dev/null +++ b/lib/ticket/DERApTicket.c @@ -0,0 +1,544 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* -------------------------------------------------------------------------- */ + +extern size_t sprint_hex(const uint8_t *data, unsigned data_len, char *buf, unsigned buf_len); + +static DERReturn DERApTicketValidateCertExtension( const DERItem *contents ); + +/* -------------------------------------------------------------------------- */ + +const DERItemSpec DERApTicketItemSpecs[] = +{ + { DER_OFFSET(DERApTicket, signatureAlgorithm), + ASN1_CONSTR_SEQUENCE, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERApTicket, body), + ASN1_CONSTR_SET, + DER_DEC_NO_OPTS | DER_DEC_SAVE_DER }, + { DER_OFFSET(DERApTicket, signature), + ASN1_OCTET_STRING, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERApTicket, certificates), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1, + DER_DEC_NO_OPTS } +}; + +const DERSize DERNumApTicketItemSpecs = sizeof(DERApTicketItemSpecs) / sizeof(DERItemSpec); + +/* -------------------------------------------------------------------------- */ + +const DERItemSpec DERApTicketCertExtensionItemSpecs[] = +{ + { DER_OFFSET(DERApTicketCertExtension, version), + ASN1_CONTEXT_SPECIFIC | 0, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERApTicketCertExtension, override), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1, + DER_DEC_NO_OPTS }, + { DER_OFFSET(DERApTicketCertExtension, append), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2, + DER_DEC_OPTIONAL }, + { DER_OFFSET(DERApTicketCertExtension, remove), + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3, + DER_DEC_OPTIONAL } +}; + +const DERSize DERNumApTicketCertExtensionItemSpecs = sizeof(DERApTicketCertExtensionItemSpecs) / sizeof(DERItemSpec); + +/* -------------------------------------------------------------------------- */ + +static DERReturn +GetBuildStringTagForRunningInstance( DERTag *outTag, bool isRestore ) +{ +#if !TICKET_UNITTEST + uint32_t app_prod = mib_get_u32(kMIBTargetApplicationProduct); +#else + uint32_t app_prod = MIB_APP_PROD_IBOOT; +#endif + + switch (app_prod) { + case MIB_APP_PROD_LLB: + /* LLB should not attempt to self-verify against a restore ticket */ + if ( !isRestore ) { + *outTag = 6; + return DR_Success; + } + return -1; + + case MIB_APP_PROD_IBSS: + *outTag = 20; + return DR_Success; + + case MIB_APP_PROD_IBEC: + /* iBEC Should self-verify */ + *outTag = 22; + return DR_Success; + + default: + /* iBoot has no build string tag */ + return -1; + } +} + +/* -------------------------------------------------------------------------- */ + +static DERReturn +DERFindItemWithTag( const DERItem *container, DERTag tag, DERItem *outItem ) +{ + DERReturn derstat = -1; + DERSequence sequence; + DERTag containerTag; + DERDecodedInfo info; +// char debugBuffer[128]; + + derstat = DERDecodeSeqInit( container, &containerTag, &sequence ); + require_action( derstat == DR_Success, exit, TICKETLOG("can't parse top-level container") ); + + int i = 0; + while ( true ) { + derstat = DERDecodeSeqNext( &sequence, &info ); + require( derstat == DR_Success, exit ); + +// sprint_hex(info.content.data, info.content.length, debugBuffer, sizeof(debugBuffer)); +// TICKETLOG( "tag %u length=%u: %s", info.tag & ~ASN1_CONTEXT_SPECIFIC, info.content.length, debugBuffer ); + + if ( info.tag == tag ) { + break; + } + + ++i; + } + + *outItem = info.content; + derstat = DR_Success; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +static DERReturn +DERApTicketFindAndValidateTag( const DERItem *container, DERTag tag, void *requiredValue, unsigned requiredLength ) +{ + DERReturn derstat = -1; + DERItem foundItem; + + derstat = DERFindItemWithTag( container, tag, &foundItem ); + require_action( derstat == DR_Success, exit, TICKETLOG("missing tag (%u)", tag) ); + + require_action( foundItem.length == requiredLength, exit, derstat = -1; + TICKETLOG("tag (%llu) value has incorrect length (%u bytes, expected %u)", (uint64_t) tag, foundItem.length, requiredLength) ); + + if ( memcmp(foundItem.data, requiredValue, requiredLength) != 0 ) { + TICKETLOG( "tag (%llu) value is invalid", (uint64_t) tag ); + derstat = -1; + goto exit; + } + + derstat = DR_Success; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +DERReturn +DERApTicketCopyTagData( const DERItem *container, DERTag tag, uint8_t *buffer, DERSize *ioLength ) +{ + DERReturn derstat = -1; + DERItem item; + + derstat = DERFindItemWithTag( container, tag | ASN1_CONTEXT_SPECIFIC, &item ); + require( derstat == DR_Success, exit ); + + require_action( *ioLength >= item.length, exit, derstat = -1; + TICKETLOG("item data length (%u) is larger than provided buffer length (%u)", item.length, *ioLength) ); + + memcpy( buffer, item.data, item.length ); + *ioLength = item.length; + + derstat = DR_Success; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +/* + * Decode the AP ticket and verify the signature. + * If the ticket structure is malformed or the signature is invalid, returns error. + */ +DERReturn +DERApTicketDecode( const DERItem *contents, DERApTicket *outTicket, DERSize *outNumUsedBytes ) +{ + DERReturn derstat = -1; + int error; + DERDecodedInfo ticketInfo; + DERAlgorithmId algId; + DERItem appleSpec; + uint8_t bodyHash[CCSHA1_OUTPUT_SIZE]; + + bzero( &appleSpec, sizeof(appleSpec) ); + + /* + * Validate the ticket structure and cert chain + */ + derstat = DERDecodeItem( contents, &ticketInfo ); + require_action( derstat == DR_Success, exit, TICKETLOG("malformed ticket") ); + + derstat = DERParseSequenceContent( &(ticketInfo.content), DERNumApTicketItemSpecs, DERApTicketItemSpecs, outTicket, 0 ); + require_action( derstat == DR_Success, exit, TICKETLOG("malformed ticket") ); + + derstat = DERParseSequenceContent( &(outTicket->signatureAlgorithm), DERNumAlgorithmIdItemSpecs, DERAlgorithmIdItemSpecs, &algId, sizeof(algId) ); + require_action( derstat == DR_Success, exit, TICKETLOG("malformed ticket") ); + + if ( !DEROidCompare( &algId.oid, &oidSha1Rsa) || (algId.params.data != NULL)) { + TICKETLOG( "mismatched algorithm" ); + derstat = -1; + goto exit; + } + + sha1_calculate( outTicket->body.data, outTicket->body.length, bodyHash ); + + error = verify_signature_with_chain( + outTicket->certificates.data, outTicket->certificates.length, + outTicket->signature.data, outTicket->signature.length, + bodyHash, sizeof(bodyHash), + NULL, NULL, + (void **) &(appleSpec.data), (size_t *) &(appleSpec.length) ); + + if ( error != 0 ) { + TICKETLOG( "failed signature validation" ); + derstat = -1; + goto exit; + } + +// TICKETLOG( "cert extension: 0x%08x, length=%u", appleSpec.data, appleSpec.length ); +// hexdump( appleSpec.data, appleSpec.length ); + + require_action( appleSpec.data != NULL, exit, derstat = -1; TICKETLOG("missing cert extension") ); + + derstat = DERApTicketValidateCertExtension( &appleSpec ); + require_action( derstat == DR_Success, exit, TICKETLOG("incompatible cert") ); + + derstat = DR_Success; + +exit: + if ( derstat == DR_Success ) { + /* + * "ticketInfo" describes a pointer and length to content within "contents->data". + * The difference of that pointer and "contents->data" is the number of bytes used to describe the content. + * The overall ticket length is the content length summed with the number of bytes used to describe it. + */ + *outNumUsedBytes = ticketInfo.content.length + (ticketInfo.content.data - contents->data); + } + else { + *outNumUsedBytes = 0; + } + + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +/* + * Validate the build string + * + * The root ticket includes "build string" entries for LLB and iBSS that indicate the build + * submission tag (e.g., iBoot-1194) of the iBoot project that was submitted to the build and + * was included in its nomination. + * + * This build string is also stamped into the binary and is accessible via build_tag_string. + * + * To guard against "mix and match" attacks, the executing instance's build string is compared + * against the one in the root ticket; that is, the executing firmware is bound to the ticket + * being validated. + */ +static DERReturn +_DERApTicketValidateBuildString( const DERApTicket *ticket, bool isRestore ) +{ + DERReturn derstat = -1; + DERTag tmp; + DERItem tmpItem; + + if ( GetBuildStringTagForRunningInstance(&tmp, isRestore) == DR_Success ) { + unsigned i, length; + char ticketBuildString[128]; + + derstat = DERFindItemWithTag( &(ticket->body), tmp | ASN1_CONTEXT_SPECIFIC, &tmpItem ); + if ( derstat != DR_Success ) { + TICKETLOG( "missing build string %u", tmp ); + derstat = -1; + goto exit; + } + + require_action( tmpItem.length < sizeof(ticketBuildString), exit, derstat = -1; TICKETLOG("malformed build string") ); + + /* + * Remove any trailing build string turds. + * Manifest "BuildString" entries have an undesired suffix + */ + length = strlcpy( ticketBuildString, (const char *) tmpItem.data, sizeof(ticketBuildString) ); + for ( i = 0; i < length; ++i ) { + if ( ticketBuildString[i] == '~' ) { + ticketBuildString[i] = '\0'; + break; + } + } + + if ( strncmp(build_tag_string, ticketBuildString, sizeof(ticketBuildString)) != 0 ) { + TICKETLOG( "mismatched build string\n ticket: %s\n current: %s", ticketBuildString, build_tag_string ); + derstat = -1; + goto exit; + } + } + + derstat = DR_Success; + goto exit; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +static DERReturn +DERApTicketValidateProductionMode( const DERItem *container ) +{ + DERReturn derstat = -1; + uint32_t tmp32 = platform_get_raw_production_mode(); +#if !TICKET_UNITTEST + bool acceptGlobalTicket = mib_get_bool(kMIBTargetAcceptGlobalTicket); +#else + bool acceptGlobalTicket = false; +#endif + + if (acceptGlobalTicket) { + DERItem tmpItem; + derstat = DERFindItemWithTag( container, 4 | ASN1_CONTEXT_SPECIFIC, &tmpItem ); + require( derstat == DR_Success, exit ); + } + if (!acceptGlobalTicket || tmp32) + { + derstat = DERApTicketFindAndValidateTag( container, 4 | ASN1_CONTEXT_SPECIFIC, &tmp32, sizeof(tmp32) ); + require( derstat == DR_Success, exit ); + } + + derstat = DR_Success; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +static DERReturn +DERApTicketValidateCertExtension( const DERItem *contents ) +{ + DERReturn derstat = -1; + uint32_t tmp32; + DERItem tmpItem; + DERDecodedInfo extensionInfo; + DERApTicketCertExtension extension; + + bzero( &extension, sizeof(extension) ); + + derstat = DERDecodeItem( contents, &extensionInfo ); + require_action( derstat == DR_Success, exit, TICKETLOG("malformed cert extension") ); + + derstat = DERParseSequenceContent( &(extensionInfo.content), DERNumApTicketCertExtensionItemSpecs, DERApTicketCertExtensionItemSpecs, &extension, 0 ); + require_action( derstat == DR_Success, exit, TICKETLOG("malformed cert extension") ); + + /* We only know how to handle version 0 (in which the version tag isn't provided) */ + require_action( extension.version.data == NULL, exit, derstat = -1; TICKETLOG("unsupported extension version") ); + + /* These are provided for future expansion. For now, forbid them.*/ + require_action( extension.append.data == NULL, exit, derstat = -1; TICKETLOG("unsupported extension") ); + require_action( extension.remove.data == NULL, exit, derstat = -1; TICKETLOG("unsupported extension") ); + + /* An override is required */ + require_action( extension.override.data != NULL, exit, derstat = -1; TICKETLOG("incomplete extension") ); + + /* Validate the chipid (tag=2) */ + tmp32 = platform_get_chip_id(); + derstat = DERApTicketFindAndValidateTag( &(extension.override), 2 | ASN1_CONTEXT_SPECIFIC, &tmp32, sizeof(tmp32) ); + require( derstat == DR_Success, exit ); + + /* Validate the production mode (tag=4) */ + derstat = DERApTicketValidateProductionMode( &(extension.override) ); + require_action( derstat == DR_Success, exit, derstat = -1; TICKETLOG("invalid production mode") ); + + /* Validate the security domain (tag=5) */ + tmp32 = platform_get_security_domain(); + derstat = DERApTicketFindAndValidateTag( &(extension.override), 5 | ASN1_CONTEXT_SPECIFIC, &tmp32, sizeof(tmp32) ); + require( derstat == DR_Success, exit ); + + /* Validate the certificate epoch (tag=235) */ + derstat = DERFindItemWithTag( &(extension.override), 235 | ASN1_CONTEXT_SPECIFIC, &tmpItem ); + require_action( derstat == DR_Success, exit, TICKETLOG("missing cert epoch") ); + require_action( tmpItem.length == sizeof(tmp32), exit, derstat = -1; TICKETLOG("malformed cert epoch") ); + memcpy( &tmp32, tmpItem.data, sizeof(tmp32) ); + require_action( platform_get_hardware_epoch() <= tmp32, exit, derstat = -1; TICKETLOG("expired cert epoch") ); + + derstat = DR_Success; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +DERReturn +DERApTicketValidate( const DERApTicket *ticket, bool isRestore ) +{ + DERReturn derstat = -1; + DERItem tmpItem; + uint32_t tmp32; + uint64_t tmp64; + uint8_t nonceHash[CCSHA1_OUTPUT_SIZE]; +#if !TICKET_UNITTEST + bool acceptGlobalTicket = mib_get_u32(kMIBTargetAcceptGlobalTicket); +#else + bool acceptGlobalTicket = false; +#endif + + /* Validate the ecid (tag=1) */ + derstat = DERFindItemWithTag( &(ticket->body), 1 | ASN1_CONTEXT_SPECIFIC, &tmpItem ); + if (!acceptGlobalTicket) { + require( derstat == DR_Success, exit ); + } + + if (derstat == DR_Success ) + { + tmp64 = platform_get_ecid_id(); + derstat = DERApTicketFindAndValidateTag( &(ticket->body), 1 | ASN1_CONTEXT_SPECIFIC, &tmp64, sizeof(tmp64) ); + require( derstat == DR_Success, exit ); + } + + /* Validate the chipid (tag=2) */ + tmp32 = platform_get_chip_id(); + derstat = DERApTicketFindAndValidateTag( &(ticket->body), 2 | ASN1_CONTEXT_SPECIFIC, &tmp32, sizeof(tmp32) ); + require( derstat == DR_Success, exit ); + + /* Validate the boardid (tag=3) */ + tmp32 = platform_get_board_id(); + derstat = DERApTicketFindAndValidateTag( &(ticket->body), 3 | ASN1_CONTEXT_SPECIFIC, &tmp32, sizeof(tmp32) ); + require( derstat == DR_Success, exit ); + + /* Validate the production mode (tag=4) */ + derstat = DERApTicketValidateProductionMode( &(ticket->body) ); + require( derstat == DR_Success, exit ); + + /* Validate the security domain (tag=5) */ + tmp32 = platform_get_security_domain(); + derstat = DERApTicketFindAndValidateTag( &(ticket->body), 5 | ASN1_CONTEXT_SPECIFIC, &tmp32, sizeof(tmp32) ); + require( derstat == DR_Success, exit ); + + /* Validate the build tag */ + derstat = _DERApTicketValidateBuildString( ticket, isRestore ); + require( derstat == DR_Success, exit ); + + /* + * Restore validation is a superset of normal boot validation + */ + if ( isRestore ) { + + /* + * Validate the nonce (tag=18) + */ + derstat = DERFindItemWithTag( &(ticket->body), 18 | ASN1_CONTEXT_SPECIFIC, &tmpItem ); + if ( derstat == DR_Success ) { + if ( tmpItem.length != sizeof(nonceHash) ) { + TICKETLOG( "malformed nonce" ); + derstat = -1; + goto exit; + } + + tmp64 = platform_get_nonce(); + sha1_calculate( &tmp64, sizeof(tmp64), nonceHash ); + + if ( memcmp(nonceHash, tmpItem.data, sizeof(nonceHash)) != 0 ) { +#if TICKETLOG_ENABLED + char hash1[2 * CCSHA1_OUTPUT_SIZE + 1]; + char hash2[2 * CCSHA1_OUTPUT_SIZE + 1]; + sprint_hex( tmpItem.data, tmpItem.length, hash1, sizeof(hash1) ); + sprint_hex( nonceHash, sizeof(nonceHash), hash2, sizeof(hash2) ); +#endif + + TICKETLOG( "mismatched nonce\n ticket: %s\n current: %s", hash1, hash2 ); + derstat = -1; + goto exit; + } + } else { + if (!acceptGlobalTicket) { + TICKETLOG( "missing nonce" ); + derstat = -1; + goto exit; + } + } + } + + derstat = DR_Success; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ + +DERReturn +DERApTicketParseLengthFromBuffer( const uint8_t *buffer, size_t length, size_t *outTicketLength ) +{ + DERReturn derstat = -1; + DERItem ticketItem; + DERDecodedInfo ticketInfo; + + require( buffer != NULL, exit ); + require( outTicketLength != NULL, exit ); + + /* Parse just enough of the buffer to determine the ticket length */ + ticketItem.data = (DERByte *) buffer; + ticketItem.length = (DERSize) length; + + derstat = DERDecodeItem( &ticketItem, &ticketInfo ); + require_action( derstat == DR_Success, exit, TICKETLOG("failed to decode buffer") ); + + /* + * "ticketInfo" describes a pointer and length to content within "buffer". + * The difference of that pointer and "buffer" is the number of bytes used to describe the content. + * The overall ticket length is the content length summed with the number of bytes used to describe it. + */ + *outTicketLength = (size_t) ticketInfo.content.length + (ticketInfo.content.data - buffer); + + derstat = DR_Success; + +exit: + return derstat; +} + +/* -------------------------------------------------------------------------- */ diff --git a/lib/ticket/fuzz.c b/lib/ticket/fuzz.c new file mode 100644 index 0000000..0081e3f --- /dev/null +++ b/lib/ticket/fuzz.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct blockdev *create_mock_blockdev(const char *name, const char *filename, uint32_t block_size); + +int do_printenv(int argc, void *args); + +int fuzz_main(const char *filename) +{ + void *in_buffer; + size_t in_size; + struct stat st; + FILE *f; + int result; + struct blockdev *bdev; + + // Get input size + result = stat(filename, &st); + TEST_ASSERT_EQ(result, 0); + in_size = st.st_size; + + // Read it + f = fopen(filename, "r"); + TEST_ASSERT_NOT_NULL(f); + in_buffer = malloc(in_size); + TEST_ASSERT_NOT_NULL(in_buffer); + result = fread(in_buffer, 1, in_size, f); + TEST_ASSERT_EQ(result, in_size); + + bdev = create_mem_blockdev("nand", in_buffer, in_size, 1); + TEST_ASSERT_NOT_NULL(bdev); + + image_search_bdev(bdev, 0, 0); + + ticket_load(); + + free(in_buffer); + + return 0; +} + +// mocks + +uint32_t platform_get_board_id(void) +{ + return 0; +} + +uint32_t platform_get_chip_id(void) +{ + return 0x8747; +} + +uint64_t platform_get_ecid_id(void) +{ + return 0; +} + +uint64_t platform_get_nonce(void) +{ + return 0; +} + +uint32_t platform_get_security_domain(void) +{ + return 1; +} + +bool platform_get_raw_production_mode(void) +{ + return false; +} + +uint32_t platform_get_hardware_epoch(void) +{ + return 0; +} + +uint32_t platform_get_security_epoch(void) +{ + return 0; +} + +const char *build_tag_string = "iBoot-1234"; + +MIB_CONSTANT_PTR(kMIBBuildTag, kOIDTypeString|kOIDDataIndirect, (void *)&build_tag_string); + +struct mib_description mib_desc[] = {}; + +int fs_load_file(const char *path, addr_t addr, size_t *maxsize) +{ + return -1; +} + +bool security_validate_image(security_image_t image_validity) +{ + return true; +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return false; +} + +void security_set_production_override(bool override) +{ +} + +bool +env_blacklist(const char *name, bool write) +{ + return false; +} + +bool +env_blacklist_nvram(const char *name) +{ + return false; +} diff --git a/lib/ticket/library.mk b/lib/ticket/library.mk new file mode 100644 index 0000000..268e081 --- /dev/null +++ b/lib/ticket/library.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBTICKET_DIR := $(GET_LOCAL_DIR) +LIBTICKET_BUILD := $(call TOLIBDIR,$(LIBTICKET_DIR)/LIBTICKET.a) +COMMONLIBS += LIBTICKET + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +GLOBAL_INCLUDES += $(SRCROOT)/lib/pki + +LIBTICKET_OBJS := $(LIBTICKET_DIR)/ticket.o \ + $(LIBTICKET_DIR)/DERApTicket.o + +LIBTICKET_OBJS := $(call TOLIBOBJDIR,$(LIBTICKET_OBJS)) + +ALL_DEPS += $(LIBTICKET_OBJS:%o=%d) + +$(LIBTICKET_BUILD): $(LIBTICKET_OBJS) + +endif diff --git a/lib/ticket/rules.mk b/lib/ticket/rules.mk new file mode 100644 index 0000000..4c3133b --- /dev/null +++ b/lib/ticket/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2010-2011, 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +OPTIONS += WITH_TICKET=1 +LIBRARY_MODULES += lib/ticket +MODULES += lib/blockdev \ + lib/env \ + lib/image/image3 \ + lib/pki + diff --git a/lib/ticket/tests-fuzz.mk b/lib/ticket/tests-fuzz.mk new file mode 100644 index 0000000..1e1762a --- /dev/null +++ b/lib/ticket/tests-fuzz.mk @@ -0,0 +1,66 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := ticket-fuzz + +TEST_OBJS := \ + $(LOCAL_DIR)/ticket.o \ + $(LOCAL_DIR)/DERApTicket.o \ + lib/image/image.o \ + lib/image/image3/Image3.o \ + lib/image/image3/image3_wrapper.o \ + lib/pki/chain-validation.o \ + lib/pki/libDER/DER_CertCrl.o \ + lib/pki/libDER/DER_Decode.o \ + lib/pki/libDER/DER_Digest.o \ + lib/pki/libDER/DER_Encode.o \ + lib/pki/libDER/DER_Keys.o \ + lib/pki/libDER/oids.o \ + lib/pki/libGiants/giantExternal.o \ + lib/pki/libGiants/giantIntegers.o \ + lib/pki/libGiants/giantMemutils.o \ + lib/pki/libGiants/giantPort_C.o \ + lib/pki/libGiants/giantMod.o \ + lib/pki/libgRSA/rsaGiantKey.o \ + lib/pki/libgRSA/libgRSA.o \ + lib/pki/libgRSA/rsaPadding.o \ + lib/pki/libgRSA/libgRSA_priv.o \ + lib/pki/libgRSA/libgRSA_DER.o \ + lib/pki/libgRSA/rsaRawKey.o \ + drivers/sha1/sha1.o \ + drivers/sha1/mozilla_sha.o + +TEST_SUPPORT_OBJS += \ + lib/blockdev/blockdev.o \ + lib/blockdev/mem_blockdev.o \ + lib/cksum/crc32.o \ + lib/env/env.o \ + lib/mib/mib.o \ + lib/libc/misc.o \ + lib/libc/log2.o \ + tests/fuzz-main.o \ + $(LOCAL_DIR)/fuzz.o + +TEST_INCLUDES += \ + lib/pki + +TEST_CFLAGS += \ + -DTICKET_UNITTEST=1 \ + -DWITH_PKI=1 \ + -DPKI_CHECK_ANCHOR_BY_SHA1=0 \ + -DPKI_APPLE_ROOT_CA=1 \ + -DPKI_CHECK_KEY_IDS=1 \ + -DWITH_IMAGE3=1 \ + -DIMAGE_MAX_COUNT=1 \ + -DCPU_CACHELINE_SIZE=64 \ + -DIMAGE3_NO_CRC=1 + diff --git a/lib/ticket/ticket.c b/lib/ticket/ticket.c new file mode 100644 index 0000000..7539a5a --- /dev/null +++ b/lib/ticket/ticket.c @@ -0,0 +1,557 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* -------------------------------------------------------------------------- */ + +/* Disable TICKET_LOOSE_VERIFICATION for the release build */ +#if !RELEASE_BUILD +#define TICKET_LOOSE_VERIFICATION 1 +#endif + +#define MAX_TICKET_LENGTH 8192 + +/* -------------------------------------------------------------------------- */ + +static uint8_t *gRootTicketBuffer = NULL; +static size_t gRootTicketLength = 0; +static DERApTicket *gRootTicket = NULL; +static uint8_t gRootTicketHashBuffer[CCSHA1_OUTPUT_SIZE]; +static bool gRootTicketIsRestore = false; + +/* -------------------------------------------------------------------------- */ + +size_t sprint_hex(const uint8_t *data, unsigned data_len, char *buf, unsigned buf_len) +{ + static const char kAsciiHexChars[] = "0123456789ABCDEF"; + unsigned i, j; + + /* ensure the output buffer is large enough to contain the hex string */ + if (buf_len < (data_len * 2) + 1) { + j = -1; + goto exit; + } + + j = 0; + for ( i = 0; i < data_len; ++i ) { + uint8_t octet = data[i]; + buf[j++] = kAsciiHexChars[((octet & 0xF0) >> 4)]; + buf[j++] = kAsciiHexChars[(octet & 0x0F)]; + } + + buf[j] = '\0'; + +exit: + return j; +} + +/* -------------------------------------------------------------------------- */ + +typedef struct { + uint32_t type; + uint8_t boot_mode; + uint8_t hash_tag; + uint8_t trust_tag; + uint8_t build_tag; +} image3_ticket_tags; + +#define kTicketBootRestore (0x1U) +#define kTicketBootNormal (0x2U) +#define kTicketBootAny (kTicketBootRestore | kTicketBootNormal) + +static const image3_ticket_tags kImage3TicketTags[] = { +/* type boot_mode hash_tag trust_tag build_tag */ + { IMAGE_TYPE_DIAG, kTicketBootAny, 11, 52, 0, }, + { IMAGE_TYPE_LLB, kTicketBootNormal, 228, 231, 6, }, + { IMAGE_TYPE_IBOOT, kTicketBootAny, 7, 48, 0, }, + { IMAGE_TYPE_DEVTREE, kTicketBootNormal, 9, 50, 0, }, + { IMAGE_TYPE_KERNELCACHE, kTicketBootNormal, 10, 51, 0, }, + { IMAGE_TYPE_LOGO, kTicketBootNormal, 8, 49, 0, }, + { IMAGE_TYPE_NEEDSERVICE, kTicketBootNormal, 17, 58, 0, }, + { IMAGE_TYPE_GLYPHCHRG, kTicketBootNormal, 12, 53, 0, }, + { IMAGE_TYPE_GLYPHPLUGIN, kTicketBootNormal, 13, 54, 0, }, + { IMAGE_TYPE_BATTERYCHARGING0, kTicketBootNormal, 78, 84, 0, }, + { IMAGE_TYPE_BATTERYCHARGING1, kTicketBootNormal, 79, 85, 0, }, + { IMAGE_TYPE_BATTERYLOW0, kTicketBootNormal, 14, 55, 0, }, + { IMAGE_TYPE_BATTERYLOW1, kTicketBootNormal, 15, 56, 0, }, + { IMAGE_TYPE_BATTERYFULL, kTicketBootNormal, 80, 86, 0, }, + { IMAGE_TYPE_RECMODE, kTicketBootAny, 16, 57, 0, }, + { IMAGE_TYPE_IBSS, kTicketBootRestore, 229, 232, 20, }, + { IMAGE_TYPE_IBEC, kTicketBootRestore, 230, 233, 22, }, + { IMAGE_TYPE_LOGO, kTicketBootRestore, 23, 59, 0, }, + { IMAGE_TYPE_DEVTREE, kTicketBootRestore, 24, 60, 0, }, + { IMAGE_TYPE_KERNELCACHE, kTicketBootRestore, 25, 61, 0, }, + { IMAGE_TYPE_RAMDISK, kTicketBootRestore, 26, 62, 0, }, +}; + +/* -------------------------------------------------------------------------- */ + +static const image3_ticket_tags * +ticket_get_image3_tags( uint32_t type ) +{ + /* + * Infer whether this is a normal boot or a restore. + */ + unsigned boot_mode; + uint32_t product = mib_get_u32(kMIBTargetApplicationProduct); + + if ((product == MIB_APP_PROD_IBOOT) || (product == MIB_APP_PROD_LLB)) { + boot_mode = (type == IMAGE_TYPE_IBEC) ? kTicketBootRestore : kTicketBootNormal; + } else { + boot_mode = kTicketBootRestore; + } + + TICKETLOG( " boot mode: %s", (boot_mode == kTicketBootRestore) ? "restore" : "normal" ); + + unsigned i; + unsigned count = sizeof(kImage3TicketTags) / sizeof(kImage3TicketTags[0]); + const image3_ticket_tags *found = NULL; + + for ( i = 0; i < count; ++i ) { + if ( kImage3TicketTags[i].type == type && kImage3TicketTags[i].boot_mode & boot_mode ) { + found = &kImage3TicketTags[i]; + break; + } + } + + return found; +} + +/* -------------------------------------------------------------------------- */ + +bool +ticket_validation_required() +{ + bool required; + + /* + * Revised iBoot ticket policy + * Don't allow replay of old iBECs on customer units + * Modify ticket validation policy for K66 + */ + +#if RELEASE_BUILD + required = !( platform_get_chip_id() == 0x8930 && platform_get_board_id() == 0x10 ); +#else + required = false; +#endif + + return required; +} + +/* -------------------------------------------------------------------------- */ + +bool +ticket_copy_tag_data( DERTag tag, uint8_t *buffer, size_t *ioLength ) +{ + int status = -1; + DERReturn derstat; + DERSize dataLength = (DERSize) *ioLength; + + require_action( gRootTicket != NULL, exit, TICKETLOG("no ticket") ); + + derstat = DERApTicketCopyTagData( &(gRootTicket->body), tag, buffer, &dataLength ); + require( derstat == DR_Success, exit ); + + *ioLength = (size_t) dataLength; + + status = 0; + +exit: + return (status == 0); +} + +/* -------------------------------------------------------------------------- */ + +bool +ticket_validate_image3( uint32_t type, uint32_t expectedType, uint8_t *hashBuffer, size_t hashBufferSize, bool *outIsUntrusted ) +{ + bool valid = false; + const image3_ticket_tags *ticketTags; + uint8_t ticketEntryHashBuffer[CCSHA1_OUTPUT_SIZE]; + size_t ticketEntryHashSize = sizeof(ticketEntryHashBuffer); + uint32_t trustedEncoding; + size_t trustedEncodingSize = sizeof(trustedEncoding); + char hashLog[2 * CCSHA1_OUTPUT_SIZE + 1]; + + TICKETLOG( "examining image: type=0x%08x ('%c%c%c%c')", type, (type >> 24) & 0xFF, (type >> 16) & 0xFF, (type >> 8) & 0xFF, type & 0xFF ); + + if ( expectedType != IMAGE_TYPE_ANY && expectedType != type ) { + TICKETLOG( " expected image: type=0x%08x ('%c%c%c%c')", expectedType, (expectedType >> 24) & 0xFF, (expectedType >> 16) & 0xFF, (expectedType >> 8) & 0xFF, expectedType & 0xFF ); + goto exit; + } + + ticketTags = ticket_get_image3_tags(type); + if (ticketTags == NULL) { + TICKETLOG("this image isn't supported by the ticket model"); + goto exit; + } + + if (ticketTags->boot_mode == kTicketBootRestore && gRootTicket != NULL && !gRootTicketIsRestore) { + TICKETLOG("a restore ticket is required"); + goto exit; + } + + if (!ticket_copy_tag_data(ticketTags->hash_tag, ticketEntryHashBuffer, &ticketEntryHashSize)) { + TICKETLOG("this tag (%d) isn't in the ticket", ticketTags->hash_tag); + goto exit; + } + + if (ticketEntryHashSize != sizeof(ticketEntryHashBuffer)) { + TICKETLOG("unrecognized ticket encoding for hash tag (%d)", ticketTags->hash_tag); + goto exit; + } + + sprint_hex(ticketEntryHashBuffer, sizeof(ticketEntryHashBuffer), hashLog, sizeof(hashLog)); + TICKETLOG(" ticket hash: %s", hashLog); + + sprint_hex(hashBuffer, hashBufferSize, hashLog, sizeof(hashLog)); + TICKETLOG(" image hash: %s", hashLog); + + /* compare hash_buffer to the hash of the image3 */ + if (memcmp(hashBuffer, ticketEntryHashBuffer, sizeof(ticketEntryHashBuffer)) != 0) { + TICKETLOG("this image doesn't match the one specified by ticket tag (%d)", ticketTags->hash_tag); + goto exit; + } + + if (!ticket_copy_tag_data(ticketTags->trust_tag, (void *) &trustedEncoding, &trustedEncodingSize)) { + TICKETLOG("ticket lacks trust tag (%d) for this image; assuming untrusted", ticketTags->trust_tag); + *outIsUntrusted = true; + } + else { + if (trustedEncodingSize != sizeof(trustedEncoding)) { + TICKETLOG("unrecognized ticket encoding for trust tag (%d)", ticketTags->trust_tag); + goto exit; + } + + TICKETLOG(" explicit trust: %s", trustedEncoding ? "yes" : "no"); + *outIsUntrusted = trustedEncoding ? false : true; + } + + valid = true; + +exit: + return valid; +} + +/* -------------------------------------------------------------------------- */ + +int +ticket_set( const uint8_t *buffer, size_t length, bool isRestore, size_t *outTicketLength ) +{ + int status = -1; + DERReturn derstat; + DERItem ticketItem; + size_t ticketLength; + uint8_t *ticketBuffer = NULL; + DERApTicket *apTicket = NULL; + + require( buffer != NULL, exit ); + require( length > 0, exit ); + + /* Parse just enough of the buffer to determine the ticket length */ + derstat = DERApTicketParseLengthFromBuffer( buffer, length, &ticketLength ); + require_action( derstat == DR_Success, exit, TICKETLOG("can't parse ticket length") ); + require_action( ticketLength > 0 && ticketLength < MAX_TICKET_LENGTH, exit, TICKETLOG("unreasonable ticket length: %d bytes", ticketLength) ); + + /* Copy the ticket data to a separate buffer */ + ticketBuffer = (uint8_t *) malloc( ticketLength ); + require_action( ticketBuffer != NULL, exit, TICKETLOG("failed to alloc ticket buffer") ); + memcpy( ticketBuffer, buffer, ticketLength ); + + /* Allocate a ticket structure */ + apTicket = (DERApTicket *) calloc( 1, sizeof(DERApTicket) ); + require_action( apTicket != NULL, exit, TICKETLOG("failed to alloc ticket structure") ); + + /* Decode */ + ticketItem.data = (DERByte *) ticketBuffer; + ticketItem.length = (DERSize) ticketLength; + derstat = DERApTicketDecode( &ticketItem, apTicket, (DERSize *) &ticketLength ); + require_action( derstat == DR_Success, exit, TICKETLOG("malformed ticket") ); + + /* Validate */ + derstat = DERApTicketValidate( apTicket, isRestore ); + +#if TICKET_LOOSE_VERIFICATION + derstat = DR_Success; +#endif + + require_action( derstat == DR_Success, exit, TICKETLOG("ticket rejected") ); + + /* Destroy any older ticket */ + if ( gRootTicketBuffer != NULL ) { + free( gRootTicketBuffer ); + gRootTicketBuffer = NULL; + gRootTicketLength = 0; + } + + if ( gRootTicket != NULL ) { + free( gRootTicket ); + gRootTicket = NULL; + } + + /* Cache this ticket */ + gRootTicketBuffer = ticketBuffer; + gRootTicketLength = ticketLength; + gRootTicket = apTicket; + gRootTicketIsRestore = isRestore; + + /* Cache the new ticket digest */ + sha1_calculate( gRootTicketBuffer, gRootTicketLength, gRootTicketHashBuffer ); + + /* Debug logging */ + { + char hashStr[2 * CCSHA1_OUTPUT_SIZE + 1]; + sprint_hex(gRootTicketHashBuffer, sizeof(gRootTicketHashBuffer), hashStr, sizeof(hashStr)); + TICKETLOG( "cached ticket (%u bytes) hash: %s", ticketLength, hashStr ); + } + + if ( outTicketLength != NULL ) { + *outTicketLength = ticketLength; + } + + /* success */ + status = 0; + +exit: + if ( status != 0 ) { + if ( ticketBuffer != NULL ) { + free( ticketBuffer ); + } + + if ( apTicket != NULL ) { + free( apTicket ); + } + } + + return status; +} + +/* -------------------------------------------------------------------------- */ + +/* + * "ticket" command handler + * This command allows the host to specify a temporary RAM-based ticket. + */ +int +do_ticket( int argc, struct cmd_arg *argv ) +{ + int status = -1; + size_t ticketLength; + size_t bufferLength; + + bufferLength = env_get_uint( "filesize", 0 ); + + require_action( bufferLength > 0, exit, status = -1; TICKETLOG("filesize invalid or not set") ); + require_action( bufferLength < MAX_TICKET_LENGTH, exit, status = -1; TICKETLOG("filesize too large") ); + check( MAX_TICKET_LENGTH <= mib_get_size(kMIBTargetDefaultLoadSize) ); + + status = ticket_set( (uint8_t *) mib_get_addr(kMIBTargetDefaultLoadAddress), bufferLength, true, &ticketLength ); + require( status == 0, exit ); + require_action( ticketLength == bufferLength, exit, status = -1; TICKETLOG("garbage following ticket") ); + + /* success */ + status = 0; + +exit: + return status; +} + + +/* -------------------------------------------------------------------------- */ + +#if DEBUG_BUILD +int +do_ticket_dump( int argc, struct cmd_arg *argv ) +{ + int status = -1; + + if ( gRootTicketBuffer == NULL ) { + printf( "no ticket\n"); + goto exit; + } + + hexdump( gRootTicketBuffer, gRootTicketLength ); + + status = 0; + +exit: + return status; +} +#endif + + +/* -------------------------------------------------------------------------- */ + +bool +ticket_get_hash( uint8_t *buffer, size_t length ) +{ + bool copied; + + if ( gRootTicketBuffer != NULL && length >= sizeof(gRootTicketHashBuffer) ) { + memcpy( buffer, gRootTicketHashBuffer, sizeof(gRootTicketHashBuffer) ); + copied = true; + } + else { + copied = false; + } + + return copied; +} + +/* ========================================================================== */ + + +/* + * Load a ticket from a file. + */ +int +ticket_load_file( const char *filePath, uintptr_t bufferAddress, size_t bufferLength ) +{ + int status = -1; + + size_t fileLength = bufferLength; + size_t ticketLength; + + status = fs_load_file(filePath, bufferAddress, &fileLength); + require_action( status == 0, exit, status = -1; TICKETLOG("failed to load ticket file: %s", filePath) ); + + status = ticket_set( (uint8_t *) bufferAddress, fileLength, true, &ticketLength ); + require_action( status == 0, exit, status = -1; TICKETLOG("unable to set ticket") ); + + require_action( ticketLength == fileLength, exit, status = -1; TICKETLOG("garbage following ticket") ); + + status = 0; + TICKETLOG("successfully loaded ticket file: %s", filePath); + +exit: + return status; +} + +int +do_ticket_file( int argc, struct cmd_arg *args ) +{ + int status = -1; + + require_action( argc == 2, exit, printf("%s \n", args[0].str) ); + + status = ticket_load_file( args[1].str, + mib_get_addr(kMIBTargetDefaultLoadAddress), + mib_get_size(kMIBTargetDefaultLoadSize) ); + require( status == 0, exit ); + + status = 0; + +exit: + return status; +} + + +/* -------------------------------------------------------------------------- */ + +int +ticket_load() +{ + int status = -1; + + struct image_info *imageInfo; + uint8_t *dataBuffer; + size_t dataLength; + size_t ticketLength; + size_t objectLength; + uint8_t *objectBuffer = NULL; + bool restoreTicket; + + /* Find the ticket image */ + imageInfo = image_find( 'SCAB' ); + require_action( imageInfo != NULL, exit, TICKETLOG("no ticket found") ); + require_action( imageInfo->imagePrivateMagic == IMAGE3_IMAGE_INFO_MAGIC, exit, TICKETLOG("ticket is not image3") ); + + /* + * Allocate a buffer for the image and load it into the buffer + * without attempting to validate it. + */ + objectLength = imageInfo->imageAllocation; + objectBuffer = (uint8_t *) malloc( objectLength ); + imageInfo->imageOptions |= IMAGE_OPTION_JUST_LOAD; + + /* + * Accept any type (pass NULL) + */ + if ( image_load(imageInfo, NULL, 0, NULL, (void **)&objectBuffer, &objectLength) ) { + TICKETLOG( "failed to load ticket image3" ); + goto exit; + } + + /* + * The ticket is always supplied in an image3 object with tags in + * the order TYPE, DATA, resulting in an offset from the buffer to + * the actual ticket data of 0x40 bytes. + * + * We don't try to introspect or validate the image here - + * ticket_set below will reject the data if it is not a + * well-formed ticket. + */ + if (objectLength < 0x40) + goto exit; + dataBuffer = objectBuffer + 0x40; + dataLength = objectLength - 0x40; + if (dataLength > MAX_TICKET_LENGTH) + goto exit; + + /* If the ticket comes from a memory blockdev, + use the stricter restore ticket validation */ + restoreTicket = (imageInfo->imageOptions & IMAGE_OPTION_MEMORY) != 0; + + /* + * Parse the ticket data. + */ + status = ticket_set( dataBuffer, dataLength, restoreTicket, &ticketLength ); + +exit: + + if ( objectBuffer != NULL ) { + free( objectBuffer ); + } + + TICKETLOG( "exiting" ); + return status; +} + +/* -------------------------------------------------------------------------- */ + +int +do_ticket_load( int argc, struct cmd_arg *argv ) +{ + int status = -1; + + status = ticket_load(); + require( status == 0, exit ); + + /* success */ + status = 0; + +exit: + return status; +} + +/* -------------------------------------------------------------------------- */ diff --git a/makefiles/build.mk b/makefiles/build.mk new file mode 100644 index 0000000..b717cbc --- /dev/null +++ b/makefiles/build.mk @@ -0,0 +1,186 @@ +# Copyright (C) 2008, 2009-2011, 2013-2015 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +############################################################################### +# Rules for building objects. +# + +_INCLUDES := $(addprefix -I,$(GLOBAL_INCLUDES)) $(addprefix -I,$(EXTERNAL_INCLUDES)) + +# flags always passed to the C compiler +_CFLAGS := $(GLOBAL_CFLAGS) $(CEXTRAFLAGS) $(CWARNFLAGS) + +# flags always passed to the C++ compiler +_CPPFLAGS := $(GLOBAL_CFLAGS) $(CPPEXTRAFLAGS) $(CPPWARNFLAGS) + +# extra flags to bring in the compiler runtime, since we turn it off via -nodefaultlibs +_RUNTIME_FLAGS := -L$(SDKROOT)/usr/local/lib -lcompiler_rt-static $(LIBBUILTIN_BUILD) + +# produce coverage info, but don't add profiling into the built binaries +# this lets us compare coverage from unit tests to the lines built for real targets +ifeq ($(COVERAGE),YES) +_CFLAGS += -ftest-coverage +_CPPFLAGS += -ftest-coverage +endif + +ALL_OBJS := $(call TOBUILDDIR,$(ALL_OBJS)) + +ALL_DEPS += $(ALL_OBJS:%o=%d) + +ALL_STATICLIBS += $(PREBUILT_STATICLIBS) + +# Make everything depend on the contents of makefiles, as they are sneaky +GLOBAL_SRCDEPS += $(MAKEFILE_LIST) + +# Avoid invoking the C++ compiler to link with unless we need it +ifeq ($(WITH_CPLUSPLUS),true) +_LD := $(CPP) +else +_LD := $(CC) +endif + +# +# If the build has defined an info symbol file, we can process it to locate TEXT_BASE rather than +# depending on makefiles to generate it. +# +# Note that this must be lazily resolved, as at the time we run this the file probably doesn't exist. +# Note also the hokey '0x' prefix to the value; nm prints as hex. +# +# XXX For now, don't do this unless TEXT_BASE was never defined at the Makefile level. Later +# we can relax this as platforms stop doing it. +# +ifeq ($(TEXT_BASE),) +ifneq ($(INFO_SYMBOL_FILE),) +SEG1ADDR = -seg1addr 0x$(shell nm $(INFO_SYMBOL_FILE) | grep TEXT_BASE | cut -d ' ' -f 1) +endif +endif + +# Dump all the interesting variables used to build things with +ifeq (0,1) +$(warning _INCLUDES = $(_INCLUDES)) +$(warning _CFLAGS = $(_CFLAGS)) +$(warning _CPPFLAGS = $(_CPPFLAGS)) +$(warning _RUNTIME_FLAGS = $(_RUNTIME_FLAGS)) +$(warning LIBRARY_ALLFLAGS = $(LIBRARY_ALLFLAGS)) +$(warning PRODUCT_ALLFLAGS = $(PRODUCT_ALLFLAGS)) +$(warning GLOBAL_ALLFLAGS = $(GLOBAL_ALLFLAGS)) +$(warning ALL_OBJS = $(ALL_OBJS)) +$(warning ALL_DEPS = $(ALL_DEPS)) +$(warning ALL_OBJS = $(ALL_OBJS)) +endif + +# rules for linked binaries +$(PRODUCT_MACHO): $(LINKER_SCRIPT) $(ALL_OBJS) $(ALL_STATICLIBS) ./tools/macho_post_process.py ./tools/macho.py + @$(MKDIR) + @echo LD $@ using $(_RUNTIME_FLAGS) + $(_v)$(_LD) $(SEG1ADDR) $(GLOBAL_LDFLAGS) $(ALL_OBJS) $(ALL_STATICLIBS) $(ALL_STATICLIBS) $(_RUNTIME_FLAGS) -exported_symbols_list $(LINKER_EXPORTS) -o $@ -Wl,-map,$@.map $(addprefix -Wl,-force_load,$(GLOBAL_LDFORCELIBS)) +ifneq ($(TEXT_FOOTPRINT),) + @total_size=`$(SIZE) -m $@|sed -n 's/^total \([0-9][0-9]*\)/\1/p'`; if [[ $$total_size -gt $$(($(TEXT_FOOTPRINT))) ]]; then \ + echo "ERROR: total size is $$(( $$total_size - $(TEXT_FOOTPRINT) )) bytes larger than TEXT_FOOTPRINT, $(TEXT_FOOTPRINT) bytes, for this platform"; \ + mv $@ $@.OVERSIZED; \ + exit 1; \ + fi +endif + $(_v)./tools/macho_post_process.py --build-tag $(XBS_BUILD_TAG) $@ + +# rules for objects going into the product build directory +$(BUILDDIR)/%.o: %.c $(PRODUCT_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo CC $@ + $(_v)$(CC) $(PRODUCT_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CFLAGS) $(DEBUG_FILE_HASH) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ +ifeq ($(ANALYZE),YES) + @echo ANALYZE $@ + $(_v)$(ANALYZER) $(PRODUCT_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CFLAGS) $(DEBUG_FILE_HASH) $(_INCLUDES) $(ANALYZERFLAGS) $< +endif + +$(BUILDDIR)/%.o: %.cpp $(PRODUCT_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo C++ $@ + $(_v)$(CPP) $(PRODUCT_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CPPFLAGS) $(DEBUG_FILE_HASH) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +$(BUILDDIR)/%.o: %.S $(PRODUCT_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo ASM $@ + $(_v)$(CC) $(PRODUCT_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(GLOBAL_ASFLAGS) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +# rules for source files in the builddir +$(BUILDDIR)/%.o: $(BUILDDIR)/%.c $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo CC $@ + $(_v)$(CC) $(GLOBAL_ALLFLAGS) $(_CFLAGS) -DDEBUG_FILE_HASH=0xbaddadcabadULL $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ +ifeq ($(ANALYZE),YES) + @echo ANALYZE $@ + $(_v)$(ANALYZER) $(GLOBAL_ALLFLAGS) $(_CFLAGS) -DDEBUG_FILE_HASH=0xbaddadcabadULL $(_INCLUDES) $(ANALYZERFLAGS) $< +endif + +$(BUILDDIR)/%.o: $(BUILDDIR)/%.S $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo ASM $@ + $(_v)$(CC) $(GLOBAL_ALLFLAGS) $(GLOBAL_ASFLAGS) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +# a rule for copying precompiled object files to somewhere they can be found at link time +$(BUILDDIR)/%.o: %.o + @$(MKDIR) + @echo CP $@ + $(_v)$(CP) $< $@ + +# +# Rules for objects going into the libdir +# +# Note that these rules should not be exposed in any other phase, to avoid problems with library +# objects being spuriously rebuilt. +# +ifeq ($(MAKEPHASE),libraries) +$(LIBOBJDIR)/%.o: %.c $(LIBRARY_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo LIBCC $@ + $(_v)$(CC) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CFLAGS) $(DEBUG_FILE_HASH) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ +ifeq ($(ANALYZE),YES) + @echo ANALYZE $@ + $(_v)$(ANALYZER) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CFLAGS) $(DEBUG_FILE_HASH) $(_INCLUDES) $(ANALYZERFLAGS) $< +endif + +$(LIBOBJDIR)/%.o: %.cpp $(LIBRARY_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo LIBC++ $@ + $(_v)$(CPP) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CPPFLAGS) $(DEBUG_FILE_HASH) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ +ifeq ($(ANALYZE),YES) + @echo ANALYZE++ $@ + $(_v)$(ANALYZERPP) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CPPFLAGS) $(DEBUG_FILE_HASH) $(_INCLUDES) $(ANALYZERFLAGS) $< +endif + +$(LIBOBJDIR)/%.o: %.S $(LIBRARY_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo LIBASM $@ + $(_v)$(CC) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(GLOBAL_ASFLAGS) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +# rules for source files in the libdir +$(LIBOBJDIR)/%.o: $(LIBOBJDIR)/%.c $(LIBRARY_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo LIBCC $@ + $(_v)$(CC) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CFLAGS) -DDEBUG_FILE_HASH=0xbaddadcabadULL $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ +ifeq ($(ANALYZE),YES) + @echo ANALYZE $@ + $(_v)$(ANALYZER) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(_CFLAGS) -DDEBUG_FILE_HASH=0xbaddadcabadULL $(_INCLUDES) $(ANALYZERFLAGS) $< +endif + +$(LIBOBJDIR)/%.o: $(LIBOBJDIR)/%.S $(LIBRARY_SRCDEPS) $(GLOBAL_SRCDEPS) + @$(MKDIR) + @echo LIBASM $@ + $(_v)$(CC) $(LIBRARY_ALLFLAGS) $(GLOBAL_ALLFLAGS) $(GLOBAL_ASFLAGS) $(_INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +# a rule for copying precompiled object files to somewhere they can be found at link time +$(LIBOBJDIR)/%.o: %.o + @$(MKDIR) + @echo CP $@ + $(_v)$(CP) $< $@ +endif + diff --git a/makefiles/config.mk b/makefiles/config.mk new file mode 100644 index 0000000..a5c2206 --- /dev/null +++ b/makefiles/config.mk @@ -0,0 +1,99 @@ +# Copyright (C) 2007-2015 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +################################################################################ +# Configuration common to all makefiles +# + +# Note that use of '=' assignment is intentional for COPTFLAGS and DEPLOYMENT_TARGET_FLAGS, +# allowing either to be overridden at make invocation for local development purposes. + +# Clang has the concept of "smaller even if it's slightly slower". Use it. +COPTFLAGS = -Oz +# Use these flags to get almost useable stack traces +#COPTFLAGS = -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls + +# Use latest compiler runtime. +ifneq ($(RC_XBS), YES) +ifeq ($(SDK_PRODUCT_NAME),Watch OS) +DEPLOYMENT_TARGET_FLAGS = -mwatchos-version-min=$(SDKVERSION) +else +ifeq ($(SDK_PRODUCT_NAME),Apple TVOS) +DEPLOYMENT_TARGET_FLAGS = -mtvos-version-min=$(SDKVERSION) +else +ifeq ($(SDK_PRODUCT_NAME),iPhone OS) +DEPLOYMENT_TARGET_FLAGS = -miphoneos-version-min=$(SDKVERSION) +endif +endif +endif +endif + +GLOBAL_INCLUDES := include include/posix include/gcc include/c++ $(OBJROOT)/build/include +EXTERNAL_INCLUDES := $(SDKROOT)/usr/local/include/ + +GLOBAL_CFLAGS := -static $(COPTFLAGS) -mno-implicit-float +GLOBAL_CFLAGS += -ffreestanding +GLOBAL_CFLAGS += -fno-common # catches multiple declarations of global variables +GLOBAL_CFLAGS += -funsigned-char -fno-strict-aliasing +GLOBAL_CFLAGS += -fstack-protector-strong + +CEXTRAFLAGS := -nostdinc -std=gnu11 +CPPEXTRAFLAGS := -nostdinc++ -fno-exceptions -fno-rtti -std=gnu++98 + +CWARNFLAGS := -Werror -W -Wall -Wbuiltin-memcpy-chk-size -Wno-multichar -Wno-unused-parameter -Wno-unused-function -Wno-int-to-void-pointer-cast -Wno-tautological-constant-out-of-range-compare +CPPWARNFLAGS := -Werror -W -Wall -Wno-multichar -Wno-unused-parameter -Wno-unused-function + +# Allow GNU-isms. +CWARNFLAGS += -Wno-gnu +CPPWARNFLAGS += -Wno-gnu + +GLOBAL_ASFLAGS := -D__ASSEMBLY__ -Dglobal=globl -Dword=long +GLOBAL_ASFLAGS += -integrated-as + +GLOBAL_ALLFLAGS := -g -DIBOOT=1 $(DEPLOYMENT_TARGET_FLAGS) + +GLOBAL_LDFLAGS := -Wl,-new_linker -Wl,-preload -Wl,-merge_zero_fill_sections +GLOBAL_LDFLAGS += -static -nostartfiles -dead_strip -e _start -nodefaultlibs +GLOBAL_LDFLAGS += $(DEPLOYMENT_TARGET_FLAGS) +GLOBAL_LDFLAGS += -Wl,-sectalign,__TEXT,__cstring,40 +GLOBAL_LDFLAGS += -Wl,-sectalign,__DATA,__data,40 +GLOBAL_LDFLAGS += -Wl,-sectalign,__DATA,__zerofill,40 +#// Hack while waiting for No const variables should end up in __DATA +GLOBAL_LDFLAGS += -Wl,-rename_section,__DATA,__const,__TEXT,__const2 + + +GLOBAL_LDFORCELIBS := + +LIBRARY_LDFLAGS := -Wl,-new_linker -static -nostartfiles -nodefaultlibs -r + +ANALYZERFLAGS = --analyze -D__clang_analyzer__ +ifneq ($(ANALYZE_FORMAT),text) + ANALYZERFLAGS += -Xanalyzer -analyzer-output=html + ANALYZERFLAGS += -o $(OBJROOT)/build/analyzer-html +else + ANALYZERFLAGS += -Xanalyzer -analyzer-output=text +endif +ifneq ($(ANALYZE_VERBOSE),YES) + ANALYZERFLAGS += -Xclang -analyzer-disable-checker -Xclang deadcode.DeadStores +endif + +ifeq ($(SANITIZE),YES) + SANITIZE_CFLAGS := -fsanitize=address + SANITIZE_LDFLAGS := -fsanitize=address +endif + +# Build host platform-specfic stuff here +ifeq ($(BUILD_OS),linux) + + # uint64_t is long on Linux, long long on Darwin + # so just disable format string warnings on Linux + CWARNFLAGS += -Wno-format +endif diff --git a/makefiles/device_map.mk b/makefiles/device_map.mk new file mode 100644 index 0000000..f227bf0 --- /dev/null +++ b/makefiles/device_map.mk @@ -0,0 +1,218 @@ +# Copyright (C) 2010-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +################################################################################ +# Macros for interacting with the device map database. +# + +ifeq ($(DEVICEMAP),) +$(error Cannot locate embedded_device_map - device map queries will fail.) +endif + +# Oh, makefile! This is the only way to escape a comma in some cases. +COMMA := , + +# Transform a whitespace separated list to a comma separated list of +# double-quoted items. +# Example input: iBoot iBSS iBEC iBoot +# Example output: "iBoot", "iBSS", "iBEC", "iBoot" +# Method: +# 1) Enclose each item in <"item",> +# 2) Terminate with +# 3) Remove trailing <,X> +MAKE_SQL_LIST = \ + $(subst $(COMMA)X,,$(foreach i,$(1),\"$(i)\"$(COMMA))X) + +# +# Locate the device map database; this prevents EDM having to locate the +# platform every time it runs. +# +DEVICEMAP_DATABASE ?= $(PLATFORMROOT)/usr/local/standalone/firmware/device_map.db +DEVICEMAP_DBOPT := -db $(DEVICEMAP_DATABASE) + +# +# Returns the set of TARGET values known to the map. +# +DEVICEMAP_TARGETS = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT TargetType \ + FROM Targets \ + GROUP BY TargetType) + +# +# Returns the set of PLATFORM values associated with at least one TARGET. +# +DEVICEMAP_PLATFORMS = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT DISTINCT Platform \ + FROM Targets) + +# +# Returns the set of PRODUCT values defined for the TARGET passed in $1 +# +# Note that this may include product types that we can't generate, so it +# needs to be post-filtered to remove unknown products. +# +DEVICEMAP_PRODUCTS_FOR_TARGET = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT FileType \ + FROM Files \ + INNER JOIN Manifests USING \(manifestID\) \ + INNER JOIN Targets USING \(Target\) \ + WHERE TargetType == \"$(1)\" \ + GROUP BY FileType) + +# +# Returns the chip ID value defined for the TARGET passed in $1 +# +DEVICEMAP_CHIPID_FOR_TARGET = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT ChipID \ + FROM Targets \ + WHERE TargetType == \"$(1)\" \ + GROUP BY ChipID) + +# +# Returns the epoch value defined for the TARGET passed in $1 +# +DEVICEMAP_EPOCH_FOR_TARGET = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT SecurityEpoch \ + FROM Targets \ + WHERE TargetType == \"$(1)\" \ + GROUP BY SecurityEpoch) + +# +# Returns the crypto hash method defined for the TARGET passed in $1 +# +DEVICEMAP_CRYPTO_HASH_FOR_TARGET = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT CryptoHashMethod \ + FROM Targets \ + WHERE TargetType == \"$(1)\" \ + GROUP BY CryptoHashMethod) + +# +# Returns the epoch value defined for the TARGET passed in $1 +# +DEVICEMAP_EPOCH_FOR_PLATFORM = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT DISTINCT SecurityEpoch \ + FROM Targets \ + WHERE Platform == \"$(1)\" \ + GROUP BY SecurityEpoch) + +# +# Returns the crypto hash method defined for the TARGET passed in $1 +# +DEVICEMAP_CRYPTO_HASH_FOR_PLATFORM = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT DISTINCT CryptoHashMethod \ + FROM Targets \ + WHERE Platform == \"$(1)\" \ + GROUP BY CryptoHashMethod) + +# +# Returns the product id value defined for the TARGET passed in $1 +# +DEVICEMAP_PRODUCTID_FOR_TARGET = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT ProductID \ + FROM Targets \ + WHERE TargetType == \"$(1)\" \ + GROUP BY ProductID) + +# +# Returns the image format defined for the PLATFORM passed in $1 +# +DEVICEMAP_IMGFMT_FOR_PLATFORM = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT DISTINCT ImageFormat \ + FROM Targets \ + WHERE Platform == \"$(1)\" \ + ) + +# +# Returns the image format defined for the TARGET passed in $1 +# +DEVICEMAP_IMGFMT_FOR_TARGET = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT DISTINCT ImageFormat \ + FROM Targets \ + WHERE TargetType == \"$(1)\" \ + ) + +# +# Returns a series for target:imageformat:epoch:productid sequences for +# all targets, use the macros below to look up keys in the result +# +DEVICEMAP_TGT_DICT = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -separator : \ + -query SELECT DISTINCT \ + TargetType, ImageFormat, SecurityEpoch, ProductID, CryptoHashMethod \ + FROM Targets \ + ) + +DEVICEMAP_TGT_DICT_IMGFMT = $(word 2,$(subst :, ,$(filter $(2):%,$(1)))) +DEVICEMAP_TGT_DICT_EPOCH = $(word 3,$(subst :, ,$(filter $(2):%,$(1)))) +DEVICEMAP_TGT_DICT_PRODUCTID = $(word 4,$(subst :, ,$(filter $(2):%,$(1)))) +DEVICEMAP_TGT_DICT_CRYPTOHASH = $(word 5,$(subst :, ,$(filter $(2):%,$(1)))) + +# +# Returns a series for target:product:payloadtype tuples for +# all target/product pairs, use the macro below to look up keys in the result +# +DEVICEMAP_TGT_PRODUCT_DICT = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -separator : \ + -query SELECT DISTINCT \ + TargetType, fileType, PayloadType \ + FROM Files \ + INNER JOIN Manifests USING \(manifestID\) \ + INNER JOIN Targets USING \(Target\) \ + WHERE fileType IN \($(call MAKE_SQL_LIST,$(1))\) \ + ) + +DEVICEMAP_TGT_PRODUCT_DICT_PAYLOADTYPE = $(word 3,$(subst :, ,$(filter $(2):$(3):%,$(1)))) + +# +# Returns the PayloadType value defined for object specified by +# PRODUCT passed in $1 +# TARGET passed in $2 +# +DEVICEMAP_PAYLOADTYPE_FOR_OBJECT = $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) \ + -query SELECT DISTINCT PayloadType \ + FROM Files \ + INNER JOIN Manifests USING \(manifestID\) \ + INNER JOIN Targets USING \(Target\) \ + WHERE fileType == \"$(1)\" \ + AND TargetType == \"$(2)\" \ + GROUP BY PayloadType \ + ) + +# +# Returns the set of TARGET values which have at least one firmware file. +# This can be used to elide targets with no firmware. +# +# PRODUCT list is passed in $1, e.g iBoot iBSS iBEC iBoot +# +DEVICEMAP_TARGETS_FOR_PRODUCTS = \ + $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) -query \ + SELECT DISTINCT TargetType \ + FROM Files \ + INNER JOIN Manifests USING \(manifestID\) \ + INNER JOIN Targets USING \(Target\) \ + WHERE fileType IN \($(call MAKE_SQL_LIST,$(1))\)) + +# +# Returns all TARGET-PRODUCT-BUILD tuples where: +# +# TargetType is in list $1 (TARGETS) +# FileType is in list $2 (PRODUCTS) +# BuildStyle is in list $3 (BUILDS) +# +DEVICE_MAP_TPB_FILTERED = \ + $(shell $(DEVICEMAP) $(DEVICEMAP_DBOPT) -query \ + SELECT DISTINCT TargetType, FileType, BuildStyle \ + FROM Files \ + INNER JOIN Manifests USING \(manifestID\) \ + INNER JOIN Targets USING \(Target\) \ + WHERE \ + TargetType IN \($(call MAKE_SQL_LIST,$(1))\) AND \ + FileType IN \($(call MAKE_SQL_LIST,$(2))\) AND \ + BuildStyle IN \($(call MAKE_SQL_LIST,$(3))\) \ + | sed "s/|/-/g") diff --git a/makefiles/format-headerfile.awk b/makefiles/format-headerfile.awk new file mode 100644 index 0000000..4f778ae --- /dev/null +++ b/makefiles/format-headerfile.awk @@ -0,0 +1,73 @@ +# Copyright (c) 2007 Apple Inc. All Rights Reserved +# +# Customise the protocol header file to reflect a specific build of the firmware. +# +# The following environment variables are expected: +# +# OBJFILE Firmware object file +# BINFILE Binary ROM data file +# NM An 'nm' suitable for the object file +# + +BEGIN { FS = ":" } + +# eat lines that ask for it +/EATLINE/ { + next +} + +# by default, copy input to output +$1!="/*SUBST" { + print $0 + next +} + +# read a string value from the environment +$1=="/*SUBST" && $2=="ENVSTR" { + if (ENVIRON[$4] != "") { + printf "%s\"%s\"%s\n", $3, ENVIRON[$4], $5 + } + next +} + +# read a variable from the environment +$1=="/*SUBST" && $2=="ENV" { + if (ENVIRON[$4] != "") { + printf "%s%s%s\n", $3, ENVIRON[$4], $5 + } + next +} + +# look up a variable in the object file +$1=="/*SUBST" && $2=="VAR" { + cmd = sprintf("%s %s | grep \" %s\" | cut -f 1 -d ' '", ENVIRON["NM"], ENVIRON["OBJFILE"], $4) + if (cmd | getline value == 0) { + value = "ffffffff" + } + printf "%s0x%s%s\n", $3, value, $5 + next +} + +# format the binary file as hex and insert it +$1=="/*SUBST" && $2=="FILE" { + format = "cat %s | dd obs=16 conv=osync 2>/dev/null | hexdump -v -e '~\t~ 16/1 ~0x%%02x,~ ~\n~'" + gsub(/~/, "\"", format) + cmd = sprintf(format, ENVIRON["BINFILE"]) + system(cmd) + next +} + +# insert the file named via the environment +$1=="/*SUBST" && $2=="INSERT" { + if (ENVIRON[$3] != "") { + cmd = sprintf("cat %s", ENVIRON[$3]) + system(cmd) + } + next +} + +# eat the next line +$1=="/*SUBST" && $2=="EATLINE" { + next +} + diff --git a/makefiles/headers.mk b/makefiles/headers.mk new file mode 100644 index 0000000..03887e5 --- /dev/null +++ b/makefiles/headers.mk @@ -0,0 +1,47 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +################################################################################ +# Makefile to build global headers common to multiple build targets in the iBoot tree +# +# The list of libraries to build is derived from the contents of the file named +# in HDRLIST, which encodes the global and local path to the header in the format: +# +# @ +# + +ifeq ($(MAKEPHASE),headers) + +HEADER_SPECS := $(shell touch $(HDRLIST) && cat $(HDRLIST)) +HEADER_LIST := $(subst ~,/,$(HEADER_SPECS)) + +BUILD_ACTIONS := $(addprefix build@,$(HEADER_SPECS)) +CLEAN_ACTIONS := $(addprefix clean@,$(HEADER_SPECS)) + +ACTIONS := $(BUILD_ACTIONS) $(CLEAN_ACTIONS) + +$(ACTIONS): $(MAKEFILE_LIST) $(HDRLIST) +$(ACTIONS): spec = $(subst @, ,$@) +$(ACTIONS): action = $(word 1,$(spec)) +$(ACTIONS): header = $(word 3,$(spec)) +$(ACTIONS): module = $(dir $(header)) +$(ACTIONS): + @echo "%%%% $(action) $(header)" + $(_v)$(MAKE) -f $(module)header.mk \ + HEADER=$(header) \ + $(action) + +build: $(BUILD_ACTIONS) + +clean: + $(_v)rm -f $(HEADER_LIST) + +endif + diff --git a/makefiles/lib.mk b/makefiles/lib.mk new file mode 100644 index 0000000..05dff69 --- /dev/null +++ b/makefiles/lib.mk @@ -0,0 +1,100 @@ +# Copyright (C) 2008-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +################################################################################ +# Makefile to build a library common to multiple build targets in the iBoot tree +# +# We expect the following to be set: +# +# MODULE +# Path to a directory containing a library.mk Makefile for the library +# we are going to build. +# +# TAG +# A unique identifier for the library we are going to build. +# +# OPTIONS +# +# Options to pass to the compiler when building the library. +# + +include makefiles/macros.mk +include makefiles/config.mk + +LIBDIR := $(OBJROOT)/build/lib-$(TAG) +LIBOBJDIR := $(addprefix $(LIBDIR)/,$(MODULE)) +GLOBAL_ALLFLAGS += $(OPTIONS) +LIBRARY_LDFLAGS += $(OPTIONS) + +# XXX HACK ALERT +# It would be nice to have both makefile options and compile options encoded in the +# library spec. Currently the only one we need is ARCH, so just hack it for now. +ifneq ($(findstring arm64,$(TAG)),) +ARCH := arm64 +else +ifneq ($(findstring arm,$(TAG)),) +ARCH := arm +endif +endif + +# XXX HACK ALERT +# Libraries don't process options the same way as non-library files. In order +# to get the build flavor in the same format that everything else expects +# we have to play some games. +BUILD := $(lastword $(subst -, ,$(TAG))) +GLOBAL_ALLFLAGS += -D$(BUILD)_BUILD=1 + +# For ROMRELEASE builds, define RELEASE_BUILD so that everything that uses +# BUILD_RELEASE doesn't have to be touched to use ROMRELEASE also. Also, +# libraries must be completely silent and not emit any debug or panic strings +# for ROMRELEASE builds. +ifeq ($(BUILD),ROMRELEASE) +GLOBAL_ALLFLAGS += -DRELEASE_BUILD=1 -DDEBUG_LEVEL=DEBUG_SILENT -DNO_PANIC_STRINGS=1 +endif +ifeq ($(BUILD),RELEASE) +GLOBAL_ALLFLAGS += -DTERSE_PANIC_STRINGS=1 +endif + +# Read the module makefile +# +# The module makefile defines COMMONLIBS containing the names of libraries +# to build. For each entry in COMMONLIBS there is: +# +# o an _BUILD variable which gives the name of the output library. +# o an _OBJS variable which gives the name of the objects to be built into the library. + +include $(MODULE)/library.mk + +TARGETVARS := $(addsuffix _BUILD,$(COMMONLIBS)) +MAKELIBS := $(foreach i,$(TARGETVARS),$(value $i)) + +$(MAKELIBS): objs = $(value $(addsuffix _OBJS,$(basename $(notdir $@)))) +$(MAKELIBS): + @$(MKDIR) + @echo AR $@ + $(_v)$(AR) -crS $@ $(objs) + $(_v)$(RANLIB) $@ + +# Now we can define object build rules +include makefiles/build.mk + +build: $(MAKELIBS) + +clean: + $(_v)rm -rf $(LIBDIR) + +# Empty rule for .d files +%.d: +%.Td: + +ifeq ($(filter $(MAKECMDGOALS), clean), ) +-include $(ALL_DEPS) +endif + diff --git a/makefiles/libraries.mk b/makefiles/libraries.mk new file mode 100644 index 0000000..11c7200 --- /dev/null +++ b/makefiles/libraries.mk @@ -0,0 +1,47 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +################################################################################ +# Makefile to build libraries common to multiple build targets in the iBoot tree +# +# The list of libraries to build is derived from the contents of the file named in LIBLIST, which +# encodes the library module path, library uniquing tag and build options for the library in the +# format: +# +# ~[~[~[~...]]] +# +# It is assumed that the contents of the LIBLIST file have been uniqued and thus +# every library target is unique. +# + +LIBRARY_SPECS := $(shell touch $(LIBLIST) && cat $(LIBLIST)) + +BUILD_ACTIONS := $(addprefix build~,$(LIBRARY_SPECS)) +CLEAN_ACTIONS := $(addprefix clean~,$(LIBRARY_SPECS)) + +ACTIONS := $(BUILD_ACTIONS) $(CLEAN_ACTIONS) + +$(ACTIONS): $(MAKEFILE_LIST) $(LIBLIST) +$(ACTIONS): spec = $(subst ~, ,$@) +$(ACTIONS): action = $(word 1,$(spec)) +$(ACTIONS): module = $(word 2,$(spec)) +$(ACTIONS): tag = $(word 3,$(spec)) +$(ACTIONS): options = $(wordlist 4,$(words $(spec)),$(spec)) +$(ACTIONS): + @echo "%%%% $(action) $(module) as $(tag)" + $(_v)$(MAKE) -f makefiles/lib.mk \ + MODULE=$(module) \ + TAG=$(tag) \ + OPTIONS="$(options)" \ + $(action) + +build: $(BUILD_ACTIONS) + +clean: $(CLEAN_ACTIONS) diff --git a/makefiles/macros.mk b/makefiles/macros.mk new file mode 100644 index 0000000..7258ea4 --- /dev/null +++ b/makefiles/macros.mk @@ -0,0 +1,50 @@ +# Copyright (C) 2009-2011, 2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +TOBUILDDIR = $(addprefix $(BUILDDIR)/,$(1)) +TOHDRDIR = $(addprefix $(HDRDIR)/,$(1)) +TOLIBDIR = $(addprefix $(LIBDIR)/,$(1)) +TOLIBOBJDIR = $(addprefix $(LIBOBJDIR)/,$(1)) +TOSYMDIR = $(addprefix $(SYMDIR)/,$(1)) +TOTOOLSDIR = $(addprefix $(TOOLS_BIN)/,$(1)) +TOTESTDIR = $(addprefix $(TESTDIR)/,$(1)) + +# build the target directory in a rule +MKDIR = if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi + +# gets the local directory of the makefile. Requires GNU make 3.81 +GET_LOCAL_DIR = $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) + +# returns a variable's numeric value or zero if empty +NUMBER = $(or $(1),0) + +# evaluate arithmetic using the bash $(()) construct +EVALUATE = $(shell echo $$(( $(1) ))) + +# add two variables (empty variables count as zero) +ADD = $(call EVALUATE, $(call NUMBER,$(1)) + $(call NUMBER,$(2))) + +# safe case transformations +UPCASE = $(shell echo $(1) | tr a-z A-Z) +DOWNCASE = $(shell echo $(1) | tr A-Z a-z) + +# test whether OPTIONS mentions the argument +OPTION_ISSET = $(patsubst %,true,$(filter $(1),$(OPTIONS)) $(filter $(1)=%,$(OPTIONS))) + +# fetch the value that OPTIONS defines for the argument +OPTION_VALUE = $(patsubst $(1)=%,%,$(filter $(1)=%,$(OPTIONS))) + +# evil hack to get a space as the first argument to $(subst ...) +empty := + +# for generating definition of obfuscated logging ID from filename +HASH_FOR_FILE = $(or $(word 2,$(subst :, ,$(filter $<:%,$(DEBUG_FILENAME_HASHES)))),$(error Error: debug hash not found for source file $< needed for $@)) +DEBUG_FILE_HASH = -DDEBUG_FILE_HASH=0x$(HASH_FOR_FILE)ULL diff --git a/makefiles/main-nested-module.mk b/makefiles/main-nested-module.mk new file mode 100644 index 0000000..c1fe36f --- /dev/null +++ b/makefiles/main-nested-module.mk @@ -0,0 +1,52 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +# +# Handle one iteration of the nested module include logic for main.mk +# +# The caller is expected to set: +# +# MODULES_VAR +# The name of the variable containing modules to include, and +# which will be set by included module makefiles. +# +# MODULE_MAKEFILE +# The name of the makefile in the module directory +# +# LIBDIR +# If the modules being processed are library modules, the root +# of the current library object tree. +# + +# strip modules that the configuration insists we cannot have +# strip modules that we have already included +# use $(sort ...) to remove duplicates in the list +MODULES_TO_INCLUDE := $(sort $(filter-out $(MODULES_ALREADY_INCLUDED),$(filter-out $(MODULES_ELIDE),$($(MODULES_VAR))))) + +# clear the modules variable so that included modules can request dependencies +$(MODULES_VAR) := + +# template for each module we are including +define include_template + LIBOBJDIR := $$(addprefix $$(LIBDIR)/,$$(MODULE)) + MODULE_RULES_FILE := $$(addprefix $$(MODULE)/,$$(MODULE_MAKEFILE)) + include $$(MODULE_RULES_FILE) +endef + +# expand the template and execute +$(foreach MODULE,$(MODULES_TO_INCLUDE),$(eval $(include_template))) + +# remember what we have included +MODULES_ALREADY_INCLUDED+= $(MODULES_TO_INCLUDE) + +# recursively invoke ourself if there are still modules to include +ifneq ($($(MODULES_VAR)),) +include makefiles/main-nested-module.mk +endif diff --git a/makefiles/main.mk b/makefiles/main.mk new file mode 100644 index 0000000..f0b51d2 --- /dev/null +++ b/makefiles/main.mk @@ -0,0 +1,537 @@ +# Copyright (C) 2007-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +############################################################################### +# Makefile to build/install a specific executable from the iBoot source tree +# +# The following must be set by the caller: +# +# CONFIG +# PRODUCT +# BUILD +# XBS_BUILD_TAG +# OBJROOT +# SYMROOT +# +# The following may be set by the caller: +# +# APPLICATION_OPTIONS +# List of options from application to be added to OPTIONS +# +# IMAGE_TYPE +# Installation will generate an image component of the +# specified type. +# +# IMAGE_FORMAT +# Installation will generate images of the format(s) listed. +# Valid formats are 2 and 3 (Image2, Image3 respectively). +# +# DFU_IMAGE +# The generated image will also be installed into the DFU +# install location. +# +# ROM_IMAGE +# Installation will generate a raw binary. +# +# INTEL_HEX +# Installation will generate an Intel Hex format version +# of the binary. ROM_IMAGE_SIZE must be set to a value +# of the form XXk where XX is your average power of 2 +# and larger than the binary image (this causes the +# image to be padded correspondingly). +# +# Environment: +# TOOLCHAIN_PREFIX +# Locate tools somewhere other than on the path. +# +# XXX need something to cause the mach-o to be installed + +include makefiles/macros.mk +include makefiles/config.mk + +#$(warning Building $(SUB_TARGET)-$(PRODUCT) $(CONFIG) $(BUILD) config) + +# Directories +BUILDDIR := $(OBJROOT)/build/$(SUB_TARGET)$(CONFIG)-$(PRODUCT)-$(BUILD) +HDRDIR := $(OBJROOT)/build/include +SYMDIR := $(SYMROOT)/build/$(SUB_TARGET)$(CONFIG)-$(PRODUCT)-$(BUILD) +APPDIR := apps/$(APPLICATION) +LIBDIR := /BAD + +# Built products +PRODUCT_BUILD := $(call TOSYMDIR,$(PRODUCT)) +PRODUCT_MACHO := $(PRODUCT_BUILD).sys +PRODUCT_DSYM := $(PRODUCT_MACHO).dSYM +PRODUCT_BIN := $(PRODUCT_BUILD).bin +PRODUCT_LIBLIST := $(call TOBUILDDIR,$(PRODUCT)).library_list +PRODUCT_HDRLIST := $(call TOBUILDDIR,$(PRODUCT)).header_list + +# Local tools +BHC := $(call TOTOOLSDIR,bhc) +MACHO2BIN := $(call TOTOOLSDIR,Macho2Bin) + +# All sources depend on these +GLOBAL_SRCDEPS := +PRODUCT_SRCDEPS := + +# Global headers live here: +GLOBAL_INCLUDES += $(HDRDIR) + +# Product-related compilation flags +PRODUCT_ALLFLAGS := + +# Object files to build, added to by included rules.mk files. +ALL_OBJS := + +# Deps for object files, computed locally (except for libraries, XXX probably a bug) +ALL_DEPS := + +# Static libraries we build locally. +LOCALLIBS := + +# Static libraries built for us by libraries.mk. +COMMONLIBS := + +# Static libraries someone else already built. +PREBUILT_STATICLIBS := + +# Static libraries imported externally. +EXTERNAL_STATICLIBS := + +# All static libraries. +ALL_STATICLIBS := + +# Additional dependencies for the product. +EXTRA_PRODUCTDEPS := + +# Dependencies for cleaning +CLEAN := + +# Source modules list, added to by included rules.mk files. +MODULES := + +# Module opt-out list, added to by included rules.mk files. +MODULES_ELIDE := + +# Common library module dependency list, added to by included rules.mk files. +LIBRARY_MODULES := + +# Options to be passed to all compiled sources in the form =. -D will be added +# automatically. +OPTIONS := + +# Tag that identifies libraries used/generated by this build +# This is appended by other rules to uniquely identify library builds. +LIBRARY_TAG := + +# Options passed to the library build +LIBRARY_OPTIONS := BUILD=$(BUILD) + +# Compiler options for the library build +LIBRARY_ALLFLAGS := + +# Default is no synch AES +AES_SYNCH_FIXUP := false + +# Expose what we are building to the compiler +# APPLICATION_$(APPLICATION) +# PRODUCT_$(PRODUCT) +# SUB_TARGET_$(SUB_TARGET) +# SUB_TARGET_$(SUB_TARGET)_CONFIG_$(CONFIG) +# CONFIG_$(CONFIG) +APPLICATION_UPPER := $(call UPCASE, $(APPLICATION)) +PRODUCT_UPPER := $(call UPCASE, $(PRODUCT)) +SUB_TARGET_UPPER := $(call UPCASE, $(SUB_TARGET)) +CONFIG_UPPER := $(call UPCASE, $(CONFIG)) +OPTIONS += APPLICATION_$(APPLICATION_UPPER)=1 +# 8208311 +OPTIONS += $(APPLICATION_OPTIONS) +OPTIONS += PRODUCT_$(PRODUCT_UPPER)=1 +OPTIONS += SUB_TARGET_$(SUB_TARGET_UPPER)=1 +OPTIONS += SUB_TARGET_STRING=\"$(SUB_TARGET)\" +OPTIONS += SUB_TARGET_UPPER_STRING=\"$(SUB_TARGET_UPPER)\" +ifneq ($(CONFIG),) +OPTIONS += SUB_TARGET_$(SUB_TARGET_UPPER)_CONFIG_$(CONFIG_UPPER)=1 +OPTIONS += CONFIG_$(CONFIG_UPPER)=1 +endif +OPTIONS += $(BUILD)_BUILD=1 +ifneq ($(CRYPTO_HASH),sha1) +CRYPTO_HASH_UPPER := $(call UPCASE, $(subst -,_,$(CRYPTO_HASH))) +OPTIONS += WITH_$(CRYPTO_HASH_UPPER)=1 +endif + +# Also define RELEASE_BUILD for the ROMRELEASE build flavor so that everything +# uses BUILD_RELEASE doesn't have to be touched to use ROMRELEASE also. +ifeq ($(BUILD),ROMRELEASE) +OPTIONS += RELEASE_BUILD=1 +endif + +# export hacks as options +OPTIONS += $(addprefix HACK_,$(HACKS)) + +# Identifying strings +OPTIONS += BUILD_STYLE=\"$(BUILD)\" +OPTIONS += CONFIG_PROGNAME_STRING=\"$(PRODUCT)\" +OPTIONS += CONFIG_BOARD_STRING=\"$(SUB_TARGET)$(CONFIG)\" + +# can't OPTIONS this as it changes for every non-XBS build +GLOBAL_CFLAGS += -DXBS_BUILD_TAG=\"$(XBS_BUILD_TAG)\" +GLOBAL_ASFLAGS += -DXBS_BUILD_TAG=\"$(XBS_BUILD_TAG)\" + +# deal with the options.h file which is dynamically built from the OPTIONS make variable +OPTIONS_HEADER_FILE := $(call TOSYMDIR,options.h) +OPTIONS_HEADER_FILE_TEMP := $(call TOSYMDIR,options.h.temp) +PRODUCT_ALLFLAGS += -include $(OPTIONS_HEADER_FILE) +PRODUCT_SRCDEPS += $(OPTIONS_HEADER_FILE) + +# Read the application makefile, which may add modules +include $(APPDIR)/application.mk + +# Application may adjust TARGET +TARGET := $(SUB_TARGET) + +# Read the target configuration, which may add modules +# Allow the config file path to be overridden to support +# configs outside of the application's regular location. +CONFIG_FILE ?= $(APPDIR)/config/$(SUB_TARGET)-config.mk +include $(CONFIG_FILE) + +# The target configuration may elect to abort the build of this product +ifeq ($(ABORT),true) +$(warning Build of $(SUB_TARGET)-$(PRODUCT) $(CONFIG) $(BUILD) aborted by configuration) +build: +install: +clean: +library_list: +else + +# Ensure TARGET exists +TARGET_UPPER := $(call UPCASE, $(TARGET)) +OPTIONS += TARGET_$(TARGET_UPPER)=1 +ifneq ($(CONFIG),) +OPTIONS += TARGET_$(TARGET_UPPER)_CONFIG_$(CONFIG_UPPER)=1 +endif + +# Ensure SUB_PLATFORM exists +SUB_PLATFORM ?= $(PLATFORM) +SUB_PLATFORM_UPPER := $(call UPCASE, $(SUB_PLATFORM)) +OPTIONS += SUB_PLATFORM_$(SUB_PLATFORM_UPPER)=1 + +# Create PLATFORM_NAME_STRING, PLATFORM_NAME_UNQUOTED +OPTIONS += PLATFORM_NAME_STRING=\"$(SUB_PLATFORM)\" +OPTIONS += PLATFORM_NAME_UNQUOTED=$(SUB_PLATFORM) + +# Read module configurations +MODULES_ALREADY_INCLUDED:= +MODULES_VAR := MODULES +MODULE_MAKEFILE := rules.mk +include makefiles/main-nested-module.mk + +# Now that we have processed modules, we know where common library objects will be located. +LIBRARY_UNIQUE := $(subst ${empty} ${empty},-,$(sort ${LIBRARY_TAG})) +LIBDIR := $(OBJROOT)/build/lib-$(LIBRARY_UNIQUE)-$(BUILD) + +# Do library modules +MODULES_ALREADY_INCLUDED:= +MODULES_VAR := LIBRARY_MODULES +MODULE_MAKEFILE := library.mk +include makefiles/main-nested-module.mk +LIBRARY_MODULE_LIST := $(sort $(MODULES_ALREADY_INCLUDED)) + +# Compute the static library set based on the build target list. +# We have two sets of static libraries; common libraries are built by libraries.mk, +# whilst local libraries are built here. +# Note local libraries before common libraries to permit local->common depdendencies. +# (We could list both sets twice...) +COMMONLIB_TARGETVARS := $(addsuffix _BUILD,$(COMMONLIBS)) +COMMONLIB_LIBS := $(foreach i,$(COMMONLIB_TARGETVARS),$(value $i)) +LOCALLIB_TARGETVARS := $(addsuffix _BUILD,$(LOCALLIBS)) +LOCALLIB_LIBS := $(foreach i,$(LOCALLIB_TARGETVARS),$(value $i)) +ALL_STATICLIBS += $(LOCALLIB_LIBS) $(COMMONLIB_LIBS) $(EXTERNAL_STATICLIBS) + +# At the very least, installing requires the product be built +INSTALL_PREREQS = $(PRODUCT) + +# If an image type is specified, enable the image format targets +ifneq ($(IMAGE_TYPE),) + ifeq ($(IMAGE_FORMAT),img3) + INSTALL_PREREQS += install-image3 + else + INSTALL_PREREQS += install-image4 + endif +endif + +# If a DFU image is being handled, enable the image format targets +# In Image4, this collides with the DSTROOT products of EmbeddedFirmware +# due to not having a unique extension. It is already installed under +# /image4, which EmbeddedFirmware searches, so we can skip this duplicate. +ifeq ($(DFU_IMAGE),true) + ifeq ($(IMAGE_FORMAT),img3) + INSTALL_PREREQS += install-dfuimage3 + endif +endif + +# If we are generating a plain binary, enable the target +ifeq ($(BINARY_IMAGE),true) +INSTALL_PREREQS += install-binary-image +endif + +# If a Secure ROM image is being handled, enable the target +ifeq ($(ROM_IMAGE),true) +INSTALL_PREREQS += install-romimage +endif + +# Intel Hex output, requires ROM_IMAGE_SIZE be set to pad the image +ifeq ($(INTEL_HEX),true) +INSTALL_PREREQS += install-intelhex +endif + +# If a header file is being generated, enable the target +ifneq ($(IMAGE_WITH_HEADER),) +INSTALL_PREREQS += install-headerfile +endif + +# If additional headers should be installed, enable the target that installs them +ifneq ($(INSTALL_HEADERS),) +INSTALL_PREREQS += install-additional-headers +endif + +# Default to no optional arguments to image3maker +IMAGE3_OPTARGS := + +# If AES synch support is enabled, we need the header to be found. +# This isn't generally safe as there are headers we own that get installed +# there and we end up using a stale version. +ifneq ($(AES_SYNCH_FIXUP),false) +GLOBAL_INCLUDES += /usr/local/standalone/firmware +endif + +build: $(PRODUCT) + +library_list: $(PRODUCT_HDRLIST) $(PRODUCT_LIBLIST) + +$(PRODUCT): $(PRODUCT_BIN) $(PRODUCT_BUILD).size + +install: $(INSTALL_PREREQS) + +install-image3: PRODUCT_IMG = $(PRODUCT_BUILD).img3 +install-image3: $(PRODUCT) + @echo installing Image3 object \'$(IMAGE_TYPE)\' from $(PRODUCT_BIN) + $(_v)$(IMAGE3MAKER) \ + --create \ + --data $(PRODUCT_BIN) \ + --version $(XBS_BUILD_TAG) \ + --type $(IMAGE_TYPE) \ + --imagefile $(PRODUCT_IMG) \ + $(IMAGE3_OPTARGS) + @mkdir -p $(INSTALL_DIR)/image3 + @install -C -m 644 $(PRODUCT_IMG) $(INSTALL_DIR)image3/$(INSTALL_NAME).img3 + +install-dfuimage3: PRODUCT_IMG = $(PRODUCT_BUILD).img3 +install-dfuimage3: $(PRODUCT) install-image3 + @echo installing DFU object $(PRODUCT_IMG) as $(INSTALL_NAME).img3 +ifneq ($(MAX_DFU_SIZE),) + @if test "$(PRODUCT)" = "iBSS"; then \ + tools/check_product_size $(PRODUCT_IMG) $(MAX_DFU_SIZE) "MAX_DFU_SIZE" ; \ + fi +endif + @mkdir -p $(INSTALL_DIR)/dfu + @install -C -m 644 $(PRODUCT_IMG) $(INSTALL_DIR)dfu/$(INSTALL_NAME).img3 + +install-image4: PRODUCT_IMG = $(PRODUCT_BUILD).im4p +install-image4: $(PRODUCT) + @echo installing Image4 object \'$(IMAGE_TYPE)\' from $(PRODUCT_BIN) + $(_v)$(IMG4PAYLOAD) \ + -i $(PRODUCT_BIN) \ + -v $(XBS_BUILD_TAG) \ + -t $(IMAGE_TYPE) \ + -o $(PRODUCT_IMG) +ifneq ($(MAX_DFU_SIZE),) + @if test "$(PRODUCT)" = "iBSS" -o "$(PRODUCT)" = "LLB"; then \ + tools/check_product_size $(PRODUCT_IMG) $(MAX_DFU_SIZE) "MAX_DFU_SIZE"; \ + fi +endif + @mkdir -p $(INSTALL_DIR)/image4 + @install -C -m 644 $(PRODUCT_IMG) $(INSTALL_DIR)image4/$(INSTALL_NAME).im4p + +install-binary-image: $(PRODUCT) + @echo installing binary object $(PRODUCT_BIN) as $(INSTALL_NAME).bin + @mkdir -p $(INSTALL_DIR) + @install -C -m 644 $(PRODUCT_BIN) $(INSTALL_DIR)/$(INSTALL_NAME).bin + +install-romimage: $(PRODUCT) + @echo installing binary object $(PRODUCT_BIN) as $(INSTALL_NAME).bin + @mkdir -p $(INSTALL_DIR)/SecureROM + @install -C -m 644 $(PRODUCT_BIN) $(INSTALL_DIR)SecureROM/$(INSTALL_NAME).bin + +install-intelhex: $(PRODUCT) + @echo installing IntelHex file $(INSTALL_DIR)SecureROM/$(INSTALL_NAME).hex + @$(BHC) -h $(PRODUCT_BIN) $(INSTALL_DIR)SecureROM/$(INSTALL_NAME).hex \ + $(ROM_IMAGE_SIZE) 2>&1 > /dev/null + +install-headerfile: PRODUCT_HEADER = $(PRODUCT_BUILD).h +install-headerfile: $(PRODUCT) + @echo installing binary object $(PRODUCT_BIN) in headerfile $(INSTALL_NAME) using $(IMAGE_WITH_HEADER) + @mkdir -p $(INSTALL_DIR) + @NM=$(NM) \ + OBJFILE=$(PRODUCT_MACHO) \ + BINFILE=$(PRODUCT_BIN) \ + XBS_BUILD_TAG=$(XBS_BUILD_TAG) \ + $(AWK) -f $(SRCROOT)/makefiles/format-headerfile.awk < $(IMAGE_WITH_HEADER) > $(PRODUCT_HEADER) + @install -C -m 644 $(PRODUCT_HEADER) $(INSTALL_DIR)$(INSTALL_NAME) + +# Note that we can't use install -C here as it can race with another +# install's unlink of the destination due to the same header(s) being +# installed by more than one invocation simultaneously. Ssen notes +# in rdar://8317733 that -S doesn't fix this. +install-additional-headers: $(INSTALL_HEADERS) + @echo installing additional headers: $(INSTALL_HEADERS) + @mkdir -p $(INSTALL_DIR) + @test -w $(INSTALL_DIR) || (echo "ERROR: I just created $(INSTALL_DIR) but now I cannot write files to it." && exit 1) + @install -m 644 $(INSTALL_HEADERS) $(INSTALL_DIR) + +# someone can request additional system dependencies +$(PRODUCT): $(EXTRA_PRODUCTDEPS) + +# Produce the prelinked binary image. +# +# Configuration may supply the following options: +# +# BIN_IMAGE_PREFIX +# A binary image to be prepended to the image. +# +# BIN_INCLUDES_BSS +# The image is padded to include the initialised BSS. +# +# BIN_ROUND_UP +# The output image is padded to a multiple of the supplied value. +# +# BIN_FIXUP +# The output image is passed to this command once fully assembled. +# +BIN_ROUND_UP ?= 1 +ifneq ($(BIN_ROUND_UP),1) +ifeq ($(BIN_INCLUDES_BSS),true) +$(error Cannot specify both BIN_ROUND_UP and BIN_INCLUDES_BSS) +endif +endif + +$(PRODUCT_BIN): $(PRODUCT_BUILD).stripped $(PRODUCT_DSYM) $(BIN_IMAGE_PREFIX) + @$(SIZE) $< + @echo BIN $@ +ifneq ($(BIN_IMAGE_PREFIX),) + $(_v)dd if=$(BIN_IMAGE_PREFIX) of=$@ +else + $(_v)dd if=/dev/zero of=$@ count=0 +endif + $(_v)dd if=$< ibs=1 skip=$(shell $(OTOOL) -lv $< | grep -m1 '^ fileoff ' | cut -c 11-) \ + obs=$(BIN_ROUND_UP) conv=osync >> $@ +ifeq ($(BIN_INCLUDES_BSS),true) + @echo PAD $@ + $(_v)dd if=/dev/zero \ + of=$@ \ + bs=1 \ + seek=`stat -f %z $@` \ + count=`expr \`$(SIZE) $< | tail -1 | cut -f 5\` - \`stat -f %z $@\`` +endif +ifneq ($(BIN_FIXUP),) + $(_v)$(BIN_FIXUP) $@ +endif +ifneq ($(AES_SYNCH_FIXUP),false) + $(AES_SYNCH_FIXUP) $(PRODUCT_BUILD) +endif + +$(PRODUCT_DSYM): $(PRODUCT_MACHO) tools/lldb_init_iboot.py tools/lldb_os_iboot.py + @echo dSYM $@ + $(_v)$(DSYMUTIL) --out=$@ $< + @mkdir -p $(PRODUCT_DSYM)/Contents/Resources/Python/ + @install -C -m 644 tools/lldb_init_iboot.py $(PRODUCT_DSYM)/Contents/Resources/Python/$(notdir $(PRODUCT_BUILD))-disabled.py + @install -C -m 644 tools/lldb_os_iboot.py $(PRODUCT_DSYM)/Contents/Resources/Python/lldb_os_iboot.py + +$(PRODUCT_BUILD).stripped: $(PRODUCT_MACHO) + @echo STRIP $@ + $(_v)$(STRIP) -o $@ $< + +$(PRODUCT_BUILD).size: $(PRODUCT_MACHO) + @echo SIZE $@ + $(_v)$(SIZE) $(ALL_OBJS) > $@ + +$(PRODUCT_HDRLIST): $(MAKEFILE_LIST) + $(_v)$(MKDIR) + $(_v)rm -f $(PRODUCT_HDRLIST) + $(_v)touch $(PRODUCT_HDRLIST) + $(_v)for i in $(GLOBAL_HEADERS) ; do \ + echo "$(HDRDIR)@$$i" >> $(PRODUCT_HDRLIST) ; \ + done + +ENCODED_LIBRARY_OPTIONS := $(subst $(empty) ,~,$(addprefix -D,$(strip $(LIBRARY_OPTIONS)))) +ENCODED_LIBRARY_FLAGS := $(subst $(empty) ,~,$(strip $(GLOBAL_ALLFLAGS) $(LIBRARY_ALLFLAGS))) +$(PRODUCT_LIBLIST): $(MAKEFILE_LIST) + $(_v)$(MKDIR) + $(_v)rm -f $(PRODUCT_LIBLIST) + $(_v)touch $(PRODUCT_LIBLIST) + $(_v)for i in $(LIBRARY_MODULE_LIST) ; do \ + echo "$$i~$(LIBRARY_UNIQUE)-$(BUILD)~$(ENCODED_LIBRARY_OPTIONS)~$(ENCODED_LIBRARY_FLAGS)" \ + >> $(PRODUCT_LIBLIST) ; \ + done + $(_v)$(CHECK_LIBLIST) $(PRODUCT_LIBLIST) + +# XXX build static libraries the 'libraries' pass didn't get +# XXX need to differentiate these... +$(LOCALLIB_LIBS): objs = $(value $(addsuffix _OBJS,$(basename $(notdir $@)))) +$(LOCALLIB_LIBS): + @$(MKDIR) + @echo AR $@ + $(_v)$(AR) -crS $@ $(objs) + $(_v)$(RANLIB) $@ + +# build the options.h file from the OPTIONS variable +$(OPTIONS_HEADER_FILE): $(MAKEFILE_LIST) + @$(MKDIR) + @rm -f $(OPTIONS_HEADER_FILE_TEMP); \ + (for o in $(OPTIONS); do \ + echo "#define $$o"; \ + done) | sort | sed s/=/\ / >> $(OPTIONS_HEADER_FILE_TEMP); \ + if [ -f "$(OPTIONS_HEADER_FILE)" ]; then \ + if cmp "$(OPTIONS_HEADER_FILE_TEMP)" "$(OPTIONS_HEADER_FILE)"; then \ + rm -f $(OPTIONS_HEADER_FILE_TEMP) ; \ + else \ + echo UPD $@ ; \ + mv $(OPTIONS_HEADER_FILE_TEMP) $(OPTIONS_HEADER_FILE) ; \ + fi \ + else \ + echo GEN $@ ; \ + mv $(OPTIONS_HEADER_FILE_TEMP) $(OPTIONS_HEADER_FILE) ; \ + fi \ + +# Now we can define object build rules +include makefiles/build.mk + +clean: + $(_v)rm -rf $(BUILDDIR) + +# Defining CLEAN_INCLUDE_TEST turns on this snippet which will cause an +# error on 'make clean' if any directory mentioned in GLOBAL_INCLUDES does not exist +ifneq ($(CLEAN_INCLUDE_TEST),) +clean-include-test: $(filter-out $(BUILDDIR)/include,$(patsubst -I%,%,$(GLOBAL_INCLUDES))) +clean: clean-include-test +endif + +# Empty rule for .d files +%.d: +%.Td: + +ifeq ($(filter $(MAKECMDGOALS), clean), ) +-include $(ALL_DEPS) +endif + +# !ABORT +endif diff --git a/makefiles/test.mk b/makefiles/test.mk new file mode 100644 index 0000000..a7ac6f9 --- /dev/null +++ b/makefiles/test.mk @@ -0,0 +1,97 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +################################################################################ +# XXX update this +# Makefile to build a unit test binary +# +# We expect the following to be set: +# +# TEST_MAKEFILE +# XXX update this +# + +# Read the test makefile after reinitializing all variables the test might test +# + +include makefiles/macros.mk +include makefiles/config.mk + +TEST_OBJS := + +TEST_SUPPORT_OBJS := + +EXTRA_TEST_PRODUCTS := + +# TESTDIR is the directory inside TESTSDIR that houses this test's +# object files and binaries. We need a unique tree per test because +# some source files may be compiled multiple times with different options +TESTDIR = $(TESTSDIR)/$(TEST_NAME) + +include $(TEST_MAKEFILE) + +TESTBIN := $(call TOTESTDIR,$(TEST_NAME)) + +COMMON_CFLAGS := -DWITH_HOST_LIBC=1 -DENABLE_RELEASE_ASSERTS=1 -funsigned-char -fno-strict-aliasing -g -Oz +COMMON_CFLAGS += -fstack-protector-all +COMMON_INCLUDES := $(SRCROOT)/include usr $(SRCROOT)/tests/include $(OBJROOT)/build/include + +# XXX: should fix up tests so that this isn't needed +CWARNFLAGS += -Wno-missing-field-initializers + +ifeq ($(BUILD_OS),linux) +# iBoot assumes some BSDisms are available from the libc, but +# this isn't the case when building with Linux's libc, including +# the required prototypes in every .c file is somewhat of a dirty +# hack, but it gets the job done +COMMON_CFLAGS += -include $(SRCROOT)/tests/include/non-posix.h +TEST_SUPPORT_OBJS += tests/non-posix.o +endif + +ifeq ($(COVERAGE),YES) +COVERAGE_CFLAGS := -ftest-coverage -fprofile-arcs +COMMON_LDFLAGS += -ftest-coverage -fprofile-arcs +endif + +_CFLAGS := $(COMMON_CFLAGS) $(CWARNFLAGS) $(SANITIZE_CFLAGS) $(TEST_CFLAGS) -DHOST_TEST=1 +_INCLUDES := $(addprefix -I,$(TEST_INCLUDES)) $(addprefix -I,$(COMMON_INCLUDES)) +_LDFLAGS := $(COMMON_LDFLAGS) $(SANITIZE_LDFLAGS) $(TEST_LDFLAGS) +ifeq ($(BUILD_OS),darwin) +_LDFLAGS += -Wl,-no_pie +endif + +BUILT_OBJS := $(call TOTESTDIR,$(TEST_OBJS) $(TEST_SUPPORT_OBJS)) +ALL_DEPS += $(BUILT_OBJS:%.o=%.d) + +GLOBAL_SRCDEPS += $(MAKEFILE_LIST) + +# rule to build object files, omitting coverage info for files listed in TEST_SUPPORT_OBJS +$(TESTDIR)/%.o: _cflags = $(_CFLAGS) $(and $(filter-out $(addprefix %,$(TEST_SUPPORT_OBJS)),$@),$(COVERAGE_CFLAGS)) +$(TESTDIR)/%.o: gcda = $(@:%.o=%.gcda) +$(TESTDIR)/%.o: $(SRCROOT)/%.c $(GLOBAL_SRCDEPS) + @echo HOST_CC $@ + @$(MKDIR) + @[ ! -f "$(gcda)" ] || rm "$(gcda)" # remove test coverage data files + $(_v)${HOST_CC} -c -o $@ $(_cflags) $(DEBUG_FILE_HASH) $(_INCLUDES) -MD -MT $@ -MF $(@:%o=%d) $< + +$(TESTBIN): $(BUILT_OBJS) $(GLOBAL_SRCDEPS) + @echo HOST_LD $@ + $(_v)$(HOST_CC) $(_LDFLAGS) -o $@ $(BUILT_OBJS) + +BUILD_PREREQS += $(TESTBIN) $(EXTRA_TEST_PRODUCTS) + +build: $(BUILD_PREREQS) + +ifeq ($(filter $(MAKECMDGOALS), clean), ) +-include $(ALL_DEPS) +endif +# Empty rule for .d files +%.d: +%.Td: diff --git a/makefiles/tests.mk b/makefiles/tests.mk new file mode 100644 index 0000000..36a5e9a --- /dev/null +++ b/makefiles/tests.mk @@ -0,0 +1,129 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +################################################################################ +# Makefile to build unit tests +# +# Currently this only handles unit tests compiled for Mac OS/x86, but +# it should be possible to extend this to also compile for arm and run +# on targets (either in iOS or on bare metal) +# +# To add a test, add its makefile for TEST_MAKEFILES below. Each makefile +# describes a single binary, and must define the following: +# TEST_NAME - The name of the test, will be used to name the binary +# TEST_OBJS - The object files that go into the test +# +# Makefiles may optionally define the following: +# TEST_INCLUDES - List of directories with include files for the test +# TEST_CFLAGS - Flags to pass to the compiler for the test +# TEST_SUPPORT_OBJS - Object files that go into the test without coverage info + +TEST_MAKEFILES := tests/unittest-tests.mk \ + drivers/sha1/tests.mk \ + lib/blockdev/tests.mk \ + lib/cksum/tests.mk \ + lib/devicetree/tests.mk \ + lib/env/tests.mk \ + lib/fs/apfs/tests-fuzz.mk \ + lib/fs/hfs/tests.mk \ + lib/fs/hfs/tests-fuzz.mk \ + lib/heap/tests.mk \ + lib/heap/tests-debugging.mk \ + lib/libc/tests.mk \ + lib/libc/tests-release.mk \ + lib/lzss/tests.mk \ + lib/nvram/tests.mk \ + lib/paint/tests.mk \ + lib/syscfg/tests.mk \ + drivers/sha1/tests.mk \ + sys/tests.mk + +# arch/arm64/tests-mmu.mk \ + +BUILD_ONLY_TEST_MAKEFILES := \ + lib/devicetree/tests-fuzz.mk \ + lib/nvram/tests-fuzz.mk \ + lib/ticket/tests-fuzz.mk + +# +# Gory details follow +# + +include makefiles/macros.mk + +ALL_TEST_MAKEFILES := $(TEST_MAKEFILES) $(BUILD_ONLY_TEST_MAKEFILES) + +ACTIONS := $(addprefix build~,$(ALL_TEST_MAKEFILES)) + +TESTS_FLAVOR ?= tests-$(BUILD_OS) +ifeq ($(COVERAGE),YES) +TESTS_FLAVOR := $(TESTS_FLAVOR)-coverage +endif +ifeq ($(SANITIZE),YES) +TESTS_FLAVOR := $(TESTS_FLAVOR)-sanitize +endif + +export TESTSDIR := $(OBJROOT)/build/$(TESTS_FLAVOR) +RUN_SH := $(TESTSDIR)/run.sh + +$(ACTIONS): $(ALL_TEST_MAKEFILES) $(MAKEFILE_LIST) +$(ACTIONS): spec = $(subst ~, ,$@) +$(ACTIONS): action = $(word 1,$(spec)) +$(ACTIONS): TEST_MAKEFILE = $(word 2,$(spec)) +$(ACTIONS): + @echo %%%% Building tests $(TEST_MAKEFILE) + @$(MAKE) -f makefiles/test.mk \ + TEST_MAKEFILE="$(TEST_MAKEFILE)" + +RUN_TESTBINS := +BUILD_TESTBINS := + +define template +include $$(TEST_MAKEFILE) +TESTBIN := $$(TESTSDIR)/$$(TEST_NAME)/$$(TEST_NAME) + +ifeq ($$(filter $$(TEST_MAKEFILE),$$(BUILD_ONLY_TEST_MAKEFILES)),) +RUN_TESTBINS += $$(TESTBIN) +else +BUILD_TESTBINS += $$(TESTBIN) +endif + +$$(TESTBIN): build~$$(TEST_MAKEFILE) +endef + +$(foreach TEST_MAKEFILE,$(ALL_TEST_MAKEFILES),$(eval $(template))) + +$(RUN_SH): $(RUN_TESTBINS) $(MAKEFILE_LIST) + @$(MKDIR) + $(_v)echo '#!/bin/bash' > $@ + $(_v)echo 'result=0' >> $@ + $(_v)for i in $(RUN_TESTBINS); do \ + echo "echo 'TEST $$i'" >> $@; \ + echo "(cd $$(dirname $$i); ./$$(basename $$i)); test_result=\$$?" >> $@; \ + echo "[[ \$$test_result == 0 ]] || echo '!!! Test Failed:' $$i" >> $@; \ + echo "result=\$$((\$$result || \$$test_result))" >> $@; \ + echo >> $@; \ + done + $(_v)echo 'exit $$result' >> $@ + $(_v)chmod a+x $@ + +.PHONY: build +build: $(RUN_SH) $(BUILD_TESTBINS) + +run: build + @echo + @echo %%%% Running tests + @echo + @$(RUN_SH) +ifeq ($(COVERAGE),YES) + @mkdir -p $(SYMROOT)/build/coverage + @echo COVERAGE + $(_v)./tools/gcovr -b -r $(OBJROOT) --html -o $(SYMROOT)/build/coverage/index.html --html-details +endif diff --git a/makefiles/tools.mk b/makefiles/tools.mk new file mode 100644 index 0000000..7094b30 --- /dev/null +++ b/makefiles/tools.mk @@ -0,0 +1,97 @@ +# -*- make -*- +# Copyright (C) 2007-2014 Apple Inc. All rights reserved. +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +################################################################################ +# Tools used by makefiles. +# +# We look these up just once and cache their paths accordingly. +# This is less important for things that we expect to always exist, but for +# optional tools, xcrun does no negative caching. +# + +export CP := /bin/cp +export AWK := /usr/bin/awk + +# Project local scripts. +export CHECK_LIBLIST := tools/check_liblist.py + +# Note that it's not safe to look up any of the toolchain pieces +# for the 'installsrc' and 'clean' targets, as they can be invoked by the +# project submission process on a system with no tools installed. + +ifeq ($(filter clean installsrc,$(MAKECMDGOALS)),) + +ifeq ($(BUILD_OS),darwin) +# xcrun only makes sense when building on OS X, but even there we +# may sometimes want to use a non-xcode SDK compiler +USE_XCRUN ?= YES +USE_XCRUN_HOST ?= $(USE_XCRUN) +endif + +ifeq ($(USE_XCRUN),YES) + +$(info %%%% locating platform tools with xcrun) + +export CC := $(shell xcrun -sdk $(SDKROOT) -find clang) +export CPP := $(shell xcrun -sdk $(SDKROOT) -find c++) +export SIZE := $(shell xcrun -sdk $(SDKROOT) -find size) +export STRIP := $(shell xcrun -sdk $(SDKROOT) -find strip) +export IMAGE3MAKER := $(shell xcrun -sdk $(SDKROOT) -find image3maker) +export IMG4PAYLOAD := $(shell xcrun -sdk $(SDKROOT) -find img4payload) +export AR := $(shell xcrun -sdk $(SDKROOT) -find ar) +export NM := $(shell xcrun -sdk $(SDKROOT) -find nm) +export RANLIB := $(shell xcrun -sdk $(SDKROOT) -find ranlib) +export DSYMUTIL := $(shell xcrun -sdk $(SDKROOT) -find dsymutil) +export DEVICEMAP := $(shell xcrun -sdk $(SDKROOT) -find embedded_device_map) +export OTOOL := $(shell xcrun -sdk $(SDKROOT) -find otool) +export ANALYZER := $(CC) +export ANALYZERPP := $(CPP) + +# XXX WTF is this? +# this may not exist, so we have to resolve it here +export AES_SYNCH_FIXUP := $(shell xcrun -sdk $(SDKROOT) -find aes-synch-fixup.sh 2>/dev/null || echo /notfound) + +endif + +ifeq ($(USE_XCRUN_HOST),YES) +export HOST_AR := $(shell xcrun -sdk $(HOST_SDKROOT) -find ar) +export HOST_CC := $(shell xcrun -sdk $(HOST_SDKROOT) -find clang) -isysroot $(HOST_SDKROOT) +export HOST_CPP := $(shell xcrun -sdk $(HOST_SDKROOT) -find clang++) -isysroot $(HOST_SDKROOT) +#export HOST_CC := /Users/jfortier/src/PR-afl/afl-0.87b/afl-clang -isysroot $(HOST_SDKROOT) +else +export HOST_AR ?= ar +export HOST_CC ?= clang +export HOST_CPP ?= clang++ +endif + +# Log the paths to all of the tools that we have located, so that there is no +# room for doubt about what we're invoking. + +$(info CP $(CP)) +$(info AWK $(AWK)) +$(info CC $(CC)) +$(info CPP $(CPP)) +$(info SIZE $(SIZE)) +$(info STRIP $(STRIP)) +$(info IMAGE3MAKER $(IMAGE3MAKER)) +$(info IMG4PAYLOAD $(IMG4PAYLOAD)) +$(info AR $(AR)) +$(info NM $(NM)) +$(info RANLIB $(RANLIB)) +$(info DSYMUTIL $(DSYMUTIL)) +$(info DEVICEMAP $(DEVICEMAP)) +$(info OTOOL $(OTOOL)) +$(info HOST_AR $(HOST_AR)) +$(info HOST_CC $(HOST_CC)) +$(info HOST_CPP $(HOST_CPP)) + +endif diff --git a/platform/defaults/chipid_get_raw_production_mode.c b/platform/defaults/chipid_get_raw_production_mode.c new file mode 100644 index 0000000..c49e5e5 --- /dev/null +++ b/platform/defaults/chipid_get_raw_production_mode.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2007-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include + +bool chipid_get_raw_production_mode(void) +{ + bool current_production_mode = chipid_get_current_production_mode(); + u_int32_t minimum_epoch = chipid_get_minimum_epoch(); + + // Pre-H6 platforms only support a "current" view of fuses. + // However, pre-H6 platforms only used epoch greater than 0 for + // production fused chips, so we can infer demotion. + return current_production_mode || (minimum_epoch > 0); +} diff --git a/platform/defaults/formatter.awk b/platform/defaults/formatter.awk new file mode 100644 index 0000000..fefac56 --- /dev/null +++ b/platform/defaults/formatter.awk @@ -0,0 +1,37 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +# Format a trivial function +# +# Input records are formatted as: +# +# $2 : return type +# $3 : function name +# $4 : argument list +# $5 : return value +# +# Caller is expected to set FUNCTION and TEMPLATE +# + +BEGIN { + FS = "[ \t]*:[ \t]*" +} + +$1=="#" { + next +} + +$3==FUNCTION { + if ($2 == "void") { + cmd = sprintf("sed -e \'s/TYPE/%s/g\' -e \'s/FUNCTION/%s/g\' -e \'s/ARGLIST/%s/g\' -e \'s/RETVAL/%s/g\' -e \'s/RET//g\' %s", $2, $3, $4, $5, TEMPLATE) + } else { + cmd = sprintf("sed -e \'s/TYPE/%s/g\' -e \'s/FUNCTION/%s/g\' -e \'s/ARGLIST/%s/g\' -e \'s/RETVAL/%s/g\' -e \'s/RET/return/g\' %s", $2, $3, $4, $5, TEMPLATE) + } + system(cmd) +} diff --git a/platform/defaults/library.mk b/platform/defaults/library.mk new file mode 100644 index 0000000..312218f --- /dev/null +++ b/platform/defaults/library.mk @@ -0,0 +1,49 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# + +LIBPD_DIR := $(GET_LOCAL_DIR) +LIBPD_BUILD := $(call TOLIBDIR,$(LIBPD_DIR)/LIBPD.a) +COMMONLIBS += LIBPD + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +# Build definitions for the target/platform independent parts of the platform defaults code + +SPECIFICATION := $(LIBPD_DIR)/platform.defaults +TEMPLATE := $(LIBPD_DIR)/template.c +LISTER := $(LIBPD_DIR)/lister.awk +FORMATTER := $(LIBPD_DIR)/formatter.awk + +PLATFORM_DEFAULTS := $(shell awk -v TAG=INDEP -f $(LISTER) $(SPECIFICATION)) + +ifneq ($(PLATFORM_DEFAULTS),) + +GENERATED_SRC_DIR := $(call TOLIBOBJDIR,$(LIBPD_DIR)) +GENERATED_NAMES := $(foreach tf,$(PLATFORM_DEFAULTS),$(word 1,$(subst :, ,$(tf)))) +GENERATED_SRCS := $(addprefix $(GENERATED_SRC_DIR)/,$(addsuffix .c,$(GENERATED_NAMES))) +GENERATED_OBJS := $(addprefix $(GENERATED_SRC_DIR)/,$(addsuffix .o,$(GENERATED_NAMES))) + +$(GENERATED_SRCS): $(SPECIFICATION) $(TEMPLATE) $(LISTER) $(FORMATTER) +$(GENERATED_SRCS): func = $(notdir $(@:.c=)) +$(GENERATED_SRCS): + @echo GEN $@ + @mkdir -p $(dir $@) + @awk -v TEMPLATE=$(TEMPLATE) -v FUNCTION=$(func) -f $(FORMATTER) < $(SPECIFICATION) > $@ + +LIBPD_OBJS := $(GENERATED_OBJS) + +$(LIBPD_BUILD): $(LIBPD_OBJS) + +ALL_DEPS += $(LIBPD_OBJS:%o=%d) + +endif +endif diff --git a/platform/defaults/lister.awk b/platform/defaults/lister.awk new file mode 100644 index 0000000..6ea3e22 --- /dev/null +++ b/platform/defaults/lister.awk @@ -0,0 +1,18 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +# Print the function field from lines with tags matching TAG + +BEGIN { + FS = "[ \t]*:[ \t]*" +} + +$1==TAG { + printf("%s ", $3) +} diff --git a/platform/defaults/platform.defaults b/platform/defaults/platform.defaults new file mode 100644 index 0000000..a99bd84 --- /dev/null +++ b/platform/defaults/platform.defaults @@ -0,0 +1,135 @@ +# +# Copyright (C) 2007-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +# +# This file describes default implementations of platform functions. +# +# Each line comprises five fields, separated by ":" +# +# The fields are: +# +# : : : : +# +# The tag field indicates whether the function is independent (INDEP) of or dependent (DEP) on the +# build configuration. Functions marked INDEP are built into a static library keyed off +# LIBRARY_TAG; functions marked DEP are built into a static library for every build pass. + +# chipid +INDEP : bool : chipid_get_production_mode : void : false +INDEP : bool : chipid_get_current_production_mode : void : chipid_get_production_mode() +INDEP : void : chipid_clear_production_mode : void : +INDEP : bool : chipid_get_secure_mode : void : false +INDEP : u_int32_t : chipid_get_security_domain : void : kPlatformSecurityDomainDarwin +INDEP : u_int32_t : chipid_get_minimum_epoch : void : 0 +INDEP : u_int32_t : chipid_get_chip_id : void : 0 +INDEP : u_int32_t : chipid_get_chip_revision : void : 0 +INDEP : u_int64_t : chipid_get_ecid_id : void : 0 +INDEP : u_int64_t : chipid_get_die_id : void : 0 +INDEP : uint32_t : chipid_get_fuse_revision : void : 0 +INDEP : void : chipid_set_fuse_lock : bool locked : +INDEP : bool : chipid_get_memory_dqcal : u_int32_t *cal_data : false +INDEP : u_int32_t : chipid_get_memory_manufacturer : void : 0 + +# platform +INDEP : bool : platform_get_current_production_mode : void : chipid_get_current_production_mode() +INDEP : bool : platform_get_raw_production_mode : void : chipid_get_raw_production_mode() +INDEP : void : platform_clear_production_mode : void : chipid_clear_production_mode() +INDEP : int : platform_early_init : void : 0 +INDEP : int : platform_init : void : 0 +INDEP : int : platform_late_init : void : 0 +INDEP : int : platform_debug_init : void : 0 +INDEP : int : platform_init_hwpins : void : 0 +INDEP : int : platform_init_internal_mem : void : 0 +INDEP : int : platform_init_display : void : 0 +INDEP : int : platform_init_display_mem : addr_t *base, size_t *size : 0 +INDEP : int : platform_init_setup_clocks : void : 0 +INDEP : int : platform_init_power : void : 0 +INDEP : int : platform_init_mass_storage : void : 0 +INDEP : int : platform_init_mass_storage_panic : void : 0 +INDEP : void : platform_mmu_setup : bool resume : +INDEP : u_int32_t : platform_get_boot_config : void : 0 +INDEP : u_int32_t : platform_get_board_id : void : 0 +INDEP : u_int32_t : platform_get_security_domain : void : chipid_get_security_domain() +INDEP : bool : platform_get_secure_mode : void : chipid_get_secure_mode()||chipid_get_raw_production_mode() +INDEP : bool : platform_get_core_idle_enable : void : true +INDEP : bool : platform_get_ecid_image_personalization_required : void : false +INDEP : u_int32_t : platform_get_hardware_epoch : void : chipid_get_minimum_epoch() +INDEP : u_int64_t : platform_get_nonce : void : 0 +INDEP : u_int32_t : platform_get_chip_id : void : chipid_get_chip_id() +INDEP : u_int32_t : platform_get_chip_revision : void : chipid_get_chip_revision() +INDEP : u_int64_t : platform_get_ecid_id : void : chipid_get_ecid_id() +INDEP : u_int64_t : platform_get_die_id : void : chipid_get_die_id() +INDEP : u_int32_t : platform_get_fuse_revision : void : chipid_get_fuse_revision() +INDEP : u_int32_t : platform_get_entropy : void : timer_get_entropy() +INDEP : u_int16_t : platform_get_usb_vendor_id : void : 0x05ac +INDEP : void : platform_set_dfu_status : bool dfu : +INDEP : bool : platform_get_force_dfu : void : false +INDEP : bool : platform_get_request_dfu1 : void : false +INDEP : bool : platform_get_request_dfu2 : void : false +INDEP : bool : platform_get_lock_fuses_required : void : true +INDEP : uint32_t : platform_get_pcie_link_width : uint32_t link : 0 +INDEP : bool : platform_set_usb_brick_detect : int select : false +INDEP : void : platform_halt : void : arch_halt() +INDEP : void : platform_deep_idle : void : platform_halt() +INDEP : int : platform_quiesce_display : void : 0 +INDEP : int : platform_update_device_tree : void : 0 +INDEP : void : platform_sleep : void : +INDEP : const char * : platform_get_usb_manufacturer_string : void : "Apple Inc." +INDEP : u_int16_t : platform_get_usb_device_version : void : 0 +INDEP : int : platform_init_mainmem : bool resume : 0 +INDEP : void : platform_init_mainmem_map : void : +INDEP : int : platform_bootprep : enum boot_target target : 0 +INDEP : int : platform_quiesce_hardware : enum boot_target target : 0 +INDEP : u_int32_t : platform_set_performance : u_int32_t level : kPerformanceHigh +INDEP : bool : platform_provide_spec_blob : const void *common_name, const size_t common_name_length, const void *serial_number, const size_t serial_number_length, void **spec_blob, size_t *spec_blob_length : false +INDEP : void : platform_watchdog_tickle : void : +INDEP : u_int32_t : platform_get_base_cpu_voltage : void : 0 +INDEP : u_int32_t : platform_get_base_ram_voltage : void : 0 +INDEP : int : platform_get_cpu_voltages : u_int32_t count, u_int32_t *voltages : -1 +INDEP : int : platform_get_cpu_min_voltages : u_int32_t count, u_int32_t *voltages : -1 +INDEP : int : platform_get_ram_voltages : u_int32_t count, u_int32_t *voltages : -1 +INDEP : int : platform_get_gpu_ram_voltages : u_int32_t count, u_int32_t *voltages : -1 +INDEP : int : platform_convert_voltages : int buck, u_int32_t count, u_int32_t *voltages : -1 +INDEP : bool : platform_is_pre_lpddr4 : void : true +INDEP : u_int64_t : platform_get_memory_size : void : 0 +INDEP : void : platform_set_memory_info : u_int8_t manuf_id, u_int64_t memory_size : +INDEP : u_int8_t : platform_get_memory_manufacturer_id : void : 0 +INDEP : void : platform_asynchronous_exception : void : +INDEP : void : platform_adjust_memory_layout : void : +INDEP : uint64_t : platform_map_host_to_pci_bus_addr : uintptr_t addr : addr +INDEP : void : platform_setup_default_environment : void : target_setup_default_environment() +INDEP : void * : platform_get_boot_trampoline : void : 0 +INDEP : size_t : platform_get_display_memory_size : void : 0 + +# target +INDEP : color_policy_t * : target_color_map_init : enum colorspace cs, color_policy_t *color_policy : NULL +INDEP : void : target_early_init : void : +INDEP : void : target_init : void : +INDEP : void : target_late_init : void : +INDEP : int : target_debug_init : void : 0 +INDEP : void : target_quiesce_hardware : void : +INDEP : bool : target_should_poweroff : bool at_boot : false +INDEP : bool : target_should_recover : void : false +INDEP : void : target_setup_default_environment : void : +INDEP : int : target_bootprep : enum boot_target target : 0 +INDEP : int : target_update_device_tree : void : 0 +INDEP : void : target_set_led : int color : +INDEP : void : target_watchdog_tickle : void : +INDEP : void : target_debug : int code : +INDEP : u_int32_t : target_lookup_backlight_cal : int index : 0 +INDEP : int : target_dclr_from_clrc : uint8_t *buffer, size_t size : -1 +INDEP : u_int8_t : target_lm3534_gpr : u_int32_t ctlr : 3 +INDEP : void * : target_get_display_configuration : void : 0 + +# application (these really belong somewhere else) +INDEP : bool : env_blacklist : const char *var, bool write : false +INDEP : bool : env_blacklist_nvram : const char *var : false +INDEP : bool : security_allow_memory : const void *address, size_t length : false +INDEP : bool : syscfg_find_tag : uint32_t tag, void **data, uint32_t *size : false diff --git a/platform/defaults/platform_get_default_gpio_cfg.c b/platform/defaults/platform_get_default_gpio_cfg.c new file mode 100644 index 0000000..ad3645f --- /dev/null +++ b/platform/defaults/platform_get_default_gpio_cfg.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#if !WITH_TARGET_CONFIG && WITH_HW_GPIO +#include +#include +#endif + +const uint32_t* platform_get_default_gpio_cfg(uint32_t gpioc) +{ +#if WITH_TARGET_CONFIG + return target_get_default_gpio_cfg(gpioc); +#elif WITH_HW_GPIO + if (gpioc == 0) + return gpio_default_cfg_0; +#ifdef GPIO_1_GROUP_COUNT + if (gpioc == 1) + return gpio_default_cfg_0; +#endif + panic("unknown gpio controller %u", gpioc); +#else + panic("no default pinconfig source"); +#endif +} diff --git a/platform/defaults/platform_get_memory_region.c b/platform/defaults/platform_get_memory_region.c new file mode 100644 index 0000000..74cda53 --- /dev/null +++ b/platform/defaults/platform_get_memory_region.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = SDRAM_BASE + platform_get_memory_size() - PANIC_SIZE; + break; + +#if defined(DISPLAY_BASE) + case kMemoryRegion_Display: + base = SDRAM_BASE + platform_get_memory_size() - platform_get_memory_region_size(kMemoryRegion_Display) - PANIC_SIZE; + break; +#endif + +#if defined(SLEEP_TOKEN_BUFFER_BASE) + case kMemoryRegion_SleepToken: + base = SLEEP_TOKEN_BUFFER_BASE; + break; +#endif + + case kMemoryRegion_Kernel: + base = SDRAM_BASE; + break; + + default: + base = (uintptr_t)-1; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + +#if defined(DISPLAY_SIZE) + case kMemoryRegion_Display: + size = platform_get_display_memory_size(); + ASSERT(size != 0); + break; +#endif + +#if defined(SLEEP_TOKEN_BUFFER_SIZE) + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; +#endif + + case kMemoryRegion_Kernel: +#if defined(DISPLAY_BASE) + size = platform_get_memory_region_base(kMemoryRegion_Display)- platform_get_memory_region_base(kMemoryRegion_Kernel); +#else + size = platform_get_memory_region_base(kMemoryRegion_Panic) - platform_get_memory_region_base(kMemoryRegion_Kernel); +#endif + break; + + default: + size = (size_t)-1; + } + + return size; +} diff --git a/platform/defaults/platform_get_spi_frequency.c b/platform/defaults/platform_get_spi_frequency.c new file mode 100644 index 0000000..e495ac4 --- /dev/null +++ b/platform/defaults/platform_get_spi_frequency.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +u_int32_t platform_get_spi_frequency(void) +{ +#if SUPPORT_FPGA + return 2500000; +#else + return 12000000; +#endif +} + diff --git a/platform/defaults/platform_memory_map.c b/platform/defaults/platform_memory_map.c new file mode 100644 index 0000000..2518315 --- /dev/null +++ b/platform/defaults/platform_memory_map.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +/* + * Default platform memory map; takes advantage of common platform + * defintions about memory sizes and locations. + * + * Note that this definition should only be used for simple applications + * where memory is all cached and identity-mapped. More complicated + * memory arrangements should be described in platform-specific code, + * rather than complicating this table. + * + * For some platforms/targets, SDRAM_LEN is not constant and so we + * have to compute a maximum via other means. + * + */ +#ifndef SDRAM_MAX_LEN +# ifndef SDRAM_BANK_COUNT +# define SDRAM_BANK_COUNT 1 +# endif +# define SDRAM_MAX_LEN (SDRAM_BANK_LEN * SDRAM_BANK_COUNT) +#endif + +#ifndef SRAM_MAX_LEN +# ifndef SRAM_BANK_COUNT +# define SRAM_BANK_COUNT 1 +# endif +# define SRAM_MAX_LEN (SRAM_BANK_LEN * SRAM_BANK_COUNT) +#endif + +struct mem_static_map_entry mem_static_map_entries[] = { + /* cached uncached physical size */ +#ifdef SDRAM_BASE + { SDRAM_BASE, MAP_NO_ENTRY, SDRAM_BASE, SDRAM_MAX_LEN }, +#endif +#ifdef SRAM_BASE + { SRAM_BASE, MAP_NO_ENTRY, SRAM_BASE, SRAM_MAX_LEN }, +#endif + {MAP_NO_ENTRY, MAP_NO_ENTRY, MAP_NO_ENTRY, 0} +}; diff --git a/platform/defaults/platform_restore_system.c b/platform/defaults/platform_restore_system.c new file mode 100644 index 0000000..db17e46 --- /dev/null +++ b/platform/defaults/platform_restore_system.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include + +int32_t platform_restore_system(void) +{ + uint32_t *signature = (uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + kSleepTokenKernelOffset); + + power_will_resume(); + + dprintf(DEBUG_INFO, "restore_system: signature[0]: 0x%08x, signature[1]: 0x%08x\n", + signature[0], signature[1]); + + if ((signature[0] != 'MOSX') || (signature[1] != 'SUSP')) return -1; + + signature[0] = 0; + signature[1] = 0; + + if (!security_validate_sleep_token(SLEEP_TOKEN_BUFFER_BASE + kSleepTokeniBootOffset)) return -1; + + /* Jump to reset vector */ + dprintf(DEBUG_INFO, "restoring kernel\n"); + prepare_and_jump(BOOT_DARWIN_RESTORE, NULL, NULL); + + /* shouldn't get here */ + panic("returned from restore_system\n"); +} diff --git a/platform/defaults/rules.mk b/platform/defaults/rules.mk new file mode 100644 index 0000000..5854eec --- /dev/null +++ b/platform/defaults/rules.mk @@ -0,0 +1,52 @@ +# Copyright (C) 2007-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifeq ($(IMAGE_FORMAT),img3) +ALL_OBJS += \ + $(LOCAL_DIR)/chipid_get_raw_production_mode.o +endif + + +# To avoid having a bunch of little tiny files containing default +# functions, we auto-generate the trivial ones from a specification. +# +# XXX The techniques used here could be generalised to provide +# default implementations for other subsystems. + +# Default functions that are independent of the build configuration +# are built into a static library shared across builds. +LIBRARY_MODULES += $(LOCAL_DIR) + +# +# Library sources +# +# Adding files here is very expensive, as each file +# gets compiled for every target/product/build permutation. +# +PLATFORM_DEFAULT_SRCS := \ + $(LOCAL_DIR)/platform_get_default_gpio_cfg.c \ + $(LOCAL_DIR)/platform_get_memory_region.c \ + $(LOCAL_DIR)/platform_get_spi_frequency.c \ + $(LOCAL_DIR)/platform_memory_map.c \ + $(LOCAL_DIR)/platform_restore_system.c \ + $(LOCAL_DIR)/target_get_boot_battery_capacity.c \ + $(LOCAL_DIR)/target_get_precharge_gg_flag_mask.c \ + $(LOCAL_DIR)/target_get_property.c \ + $(LOCAL_DIR)/target_get_property_base.c + +ALL_DEPS += $(PLATFORM_DEFAULT_SRCS:%c=%d) +PLATFORM_DEFAULT_OBJS := $(call TOBUILDDIR,$(PLATFORM_DEFAULT_SRCS:%c=%o)) + +LOCALLIBS += PLATFORM_DEFAULT + +PLATFORM_DEFAULT_BUILD := $(call TOBUILDDIR,$(LOCAL_DIR)/PLATFORM_DEFAULT.a) + +$(PLATFORM_DEFAULT_BUILD): $(PLATFORM_DEFAULT_OBJS) diff --git a/platform/defaults/target_get_boot_battery_capacity.c b/platform/defaults/target_get_boot_battery_capacity.c new file mode 100644 index 0000000..226dd3f --- /dev/null +++ b/platform/defaults/target_get_boot_battery_capacity.c @@ -0,0 +1,12 @@ +#if WITH_HW_POWER && WITH_TARGET_CONFIG +#include +#include +#include + +#ifdef TARGET_BOOT_BATTERY_CAPACITY +int target_get_boot_battery_capacity(void) +{ + return TARGET_BOOT_BATTERY_CAPACITY; +} +#endif +#endif // WITH_TARGET_CONFIG diff --git a/platform/defaults/target_get_precharge_gg_flag_mask.c b/platform/defaults/target_get_precharge_gg_flag_mask.c new file mode 100644 index 0000000..6a1a52c --- /dev/null +++ b/platform/defaults/target_get_precharge_gg_flag_mask.c @@ -0,0 +1,17 @@ +#if WITH_HW_POWER && WITH_TARGET_CONFIG +#include +#include +#include +#include +#include + +int target_get_precharge_gg_flag_mask(void) +{ +#ifdef TARGET_PRECHARGE_GG_FLAG_MASK + return TARGET_PRECHARGE_GG_FLAG_MASK; +#else + return kHDQRegFlagsMaskSOC1; +#endif +} + +#endif // WITH_TARGET_CONFIG diff --git a/platform/defaults/target_get_property.c b/platform/defaults/target_get_property.c new file mode 100644 index 0000000..b832ca7 --- /dev/null +++ b/platform/defaults/target_get_property.c @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return target_get_property_base(prop, data, maxdata, retlen); +} diff --git a/platform/defaults/target_get_property_base.c b/platform/defaults/target_get_property_base.c new file mode 100644 index 0000000..f563772 --- /dev/null +++ b/platform/defaults/target_get_property_base.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +static const uint32_t prop_map[TARGET_PROPERTY_MAX] = { + [TARGET_PROPERTY_WIFI_MACADDR] = 'WMac', + [TARGET_PROPERTY_WIFI_CALIBRATION_TX_24] = 'W24G', + [TARGET_PROPERTY_WIFI_CALIBRATION_TX_50] = 'W50G', + [TARGET_PROPERTY_WIFI_CALIBRATION_RX_24] = 'W24R', + [TARGET_PROPERTY_WIFI_CALIBRATION_RX_50] = 'W50R', + [TARGET_PROPERTY_WIFI_CALIBRATION_RX_TEMP] = 'WRxT', + [TARGET_PROPERTY_WIFI_CALIBRATION_FREQ_GROUP_2G]= 'FG2G', + [TARGET_PROPERTY_WIFI_WCAL] = 'WCAL', + [TARGET_PROPERTY_WIFI_BOARD_SNUM] = 'WBSn', + [TARGET_PROPERTY_BT_MACADDR] = 'BMac', + [TARGET_PROPERTY_ETH_MACADDR] = 'EMac', + [TARGET_PROPERTY_BB_REGION_SKU] = 'RSKU', + [TARGET_PROPERTY_PINTO_MACADDR] = 'MMac', + [TARGET_PROPERTY_WIFI1_MACADDR] = 'WMc2', + [TARGET_PROPERTY_BT1_MACADDR] = 'BMc2', + [TARGET_PROPERTY_ETH1_MACADDR] = 'EMc2', + [TARGET_PROPERTY_BLUETOOTH_DEV_MACADDR0] = 'RMac', +}; + +bool +target_get_property_base(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((prop < TARGET_PROPERTY_MAX) && (prop_map[prop] != 0)) { + length = syscfgCopyDataForTag(prop_map[prop], data, maxdata); + result = (length == maxdata); + } + + if (retlen != NULL) *retlen = length; + + return result; +} diff --git a/platform/defaults/template.c b/platform/defaults/template.c new file mode 100644 index 0000000..ce6b8ed --- /dev/null +++ b/platform/defaults/template.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2007-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +/* + * Template for trivial default functions. + * + * Add header includes here as required; it's not super-efficient but it works. + */ +#include +#include +#include +#include +#include +#include +#include + +TYPE FUNCTION ( ARGLIST ) +{ + RET RETVAL ; +} diff --git a/platform/generic/breadcrumbs.c b/platform/generic/breadcrumbs.c new file mode 100644 index 0000000..94f7cb0 --- /dev/null +++ b/platform/generic/breadcrumbs.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include + + +#define BREADCRUMB_BUFFER_SIZE 256 // This is arbitrarily sized, should be large enough for + // sensible options of key/value +#define BREADCRUMB_MIN_SIZE 3 // Smallest size of a breadcrumb + +typedef struct { + char* buffer; // Storage for the breadcrumbs + int buffer_len; // Length of breadcrumb buffer + int wrpos; // Current write position +} breadcrumb_store_t; + +static bool initialized = false; + +breadcrumb_store_t breadcrumb_store; + + +static char* bc_cur_pos (void) +{ + ASSERT(breadcrumb_store.wrpos <= breadcrumb_store.buffer_len); + return &breadcrumb_store.buffer[breadcrumb_store.wrpos]; +} + +static int bc_remaining (void) +{ + ASSERT(breadcrumb_store.wrpos <= breadcrumb_store.buffer_len); + return breadcrumb_store.buffer_len - breadcrumb_store.wrpos; +} + +void _platform_init_breadcrumbs_internal(void) +{ + if (!initialized) { + breadcrumb_store.buffer = malloc(BREADCRUMB_BUFFER_SIZE); + breadcrumb_store.wrpos = 0; + breadcrumb_store.buffer_len = BREADCRUMB_BUFFER_SIZE; + + initialized = (breadcrumb_store.buffer != NULL); + dprintf(DEBUG_INFO, "breadcrumb store initialized at %p\n", breadcrumb_store.buffer); + platform_record_breadcrumb_marker("BOOT"); + } +} + +void _platform_record_breadcrumb_internal(const char* key, const char* val) +{ + if (initialized && bc_remaining() > BREADCRUMB_MIN_SIZE) { + int count = (int)snprintf(bc_cur_pos(), bc_remaining(), "%s=%s, ", key, val); + + if (count > 0) + breadcrumb_store.wrpos += strlen(bc_cur_pos()); + } +} + +void _platform_record_breadcrumb_marker_internal(const char* val) +{ + if (initialized && bc_remaining() > BREADCRUMB_MIN_SIZE) { + int count = (int)snprintf(bc_cur_pos(), bc_remaining(), "<%s> ", val); + + if (count > 0) + breadcrumb_store.wrpos += strlen(bc_cur_pos()); + } +} + +void _platform_record_breadcrumb_int_internal(const char* key, int val) +{ + if (initialized && bc_remaining() > BREADCRUMB_MIN_SIZE) { + int count = (int)snprintf(bc_cur_pos(), bc_remaining(), "%s=%d, ", key, val); + + if (count > 0) + breadcrumb_store.wrpos += strlen(bc_cur_pos()); + } +} + +void _platform_commit_breadcrumbs_internal(const char* envvar) +{ + if (initialized) { + platform_record_breadcrumb_marker("DONE"); + // We expect this buffer to always be NULL terminated since it was built using + // snprintf(), but just to be sure, make sure the end of the buffer is terminated. + breadcrumb_store.buffer[breadcrumb_store.buffer_len - 1] = '\0'; + + const char* existing_breadcrumbs = env_get(envvar); + if (existing_breadcrumbs) { + dprintf(DEBUG_INFO, "Existing breadcrumbs found: '%s'\n", existing_breadcrumbs); + // If there's already iBoot breadcrumbs, we should preserve them chronologically + // (earliest first). Since we need to prepend, we might as well swap it with + // a new buffer. + if (bc_remaining() < (int)strlen(existing_breadcrumbs)) { + // Existing breadcrumbs would not fit. Drop the oldest breadcrumbs first + existing_breadcrumbs += ((int)strlen(existing_breadcrumbs) - bc_remaining()); + } + char* tmp_buf = malloc(BREADCRUMB_BUFFER_SIZE); + if (tmp_buf) { + int count = snprintf(tmp_buf, BREADCRUMB_BUFFER_SIZE, "%s%s", existing_breadcrumbs, breadcrumb_store.buffer); + if (count >= 0 && count < BREADCRUMB_BUFFER_SIZE) + breadcrumb_store.wrpos = count; + else + breadcrumb_store.wrpos = 0; + + free(breadcrumb_store.buffer); + breadcrumb_store.buffer = tmp_buf; + } + } + dprintf(DEBUG_INFO, "Committing breadcrumbs [used %d of %d bytes]: Setting '%s'='%s'\n", breadcrumb_store.wrpos, breadcrumb_store.buffer_len, envvar, breadcrumb_store.buffer); + env_set(envvar, breadcrumb_store.buffer, ENV_PERSISTENT); + nvram_save(); + initialized=false; // Stop recording breadcrumbs and make redundant commits a no-op. + } +} \ No newline at end of file diff --git a/platform/generic/default_mib.c b/platform/generic/default_mib.c new file mode 100644 index 0000000..67c2dd1 --- /dev/null +++ b/platform/generic/default_mib.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008,2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if !APPLICATION_SECUREROM + +#include +#include + +// Default MIB Application/Product +MIB_CONSTANT_WEAK(kMIBTargetApplicationProduct, kOIDTypeUInt32, 0); + +// Default MIB build configuration constants +MIB_CONSTANT_WEAK(kMIBTargetWithHwAsp, kOIDTypeBoolean, false); +MIB_CONSTANT_WEAK(kMIBTargetWithEffaceable, kOIDTypeBoolean, false); +MIB_CONSTANT_WEAK(kMIBTargetWithFileSystem, kOIDTypeBoolean, false); +MIB_CONSTANT_WEAK(kMIBTargetWithHwFlashNand, kOIDTypeBoolean, false); +MIB_CONSTANT_WEAK(kMIBTargetWithHwFlashNor, kOIDTypeBoolean, false); +MIB_CONSTANT_WEAK(kMIBTargetWithHwNvme, kOIDTypeBoolean, false); +MIB_CONSTANT_WEAK(kMIBTargetWithLegacyPanicLogs, kOIDTypeBoolean, false); + +// Default MIB target paint constants +MIB_CONSTANT_WEAK(kMIBTargetDisplayGammaTableCount, kOIDTypeUInt32, 0); +MIB_CONSTANT_PTR_WEAK(kMIBTargetDisplayGammaTablePtr, kOIDTypeStruct, NULL); +MIB_CONSTANT_WEAK(kMIBTargetPanicOnUnknownDclrVersion, kOIDTypeBoolean, true); +MIB_CONSTANT_WEAK(kMIBTargetPictureScale, kOIDTypeUInt32, 1); + +// Default MIB NOR configuration +MIB_CONSTANT_WEAK(kMIBTargetNvramNorBankCount, kOIDTypeUInt32, 2); +MIB_CONSTANT_WEAK(kMIBTargetNvramNorBankSize, kOIDTypeSize, 0x2000); +MIB_CONSTANT_WEAK(kMIBTargetNvramNorOffset, kOIDTypeInt32, -(2 * 0x2000)); + +// Default MIB Image3 constants +// Delete this and it's definition in mib.base when all Image3 targets are deprecated. +MIB_CONSTANT_WEAK(kMIBTargetAcceptGlobalTicket, kOIDTypeBoolean, false); + +//Default Color Manager Data +MIB_CONSTANT_WEAK(kMIBTargetDisplayCMEngammaTablePtr, kOIDTypeStruct, NULL); +MIB_CONSTANT_WEAK(kMIBTargetDisplayCMEngammaTableCount, kOIDTypeUInt32, 0); +MIB_CONSTANT_WEAK(kMIBTargetDisplayCMDegammaTablePtr, kOIDTypeStruct, NULL); +MIB_CONSTANT_WEAK(kMIBTargetDisplayCMDegammaTableCount, kOIDTypeUInt32, 0); +MIB_CONSTANT_WEAK(kMIBTargetDisplayCMMatrixTablePtr, kOIDTypeStruct, NULL); +MIB_CONSTANT_WEAK(kMIBTargetDisplayCMMatrixTableCount, kOIDTypeUInt32, 0); + +#endif // !APPLICATION_SECUREROM + diff --git a/platform/generic/defaults.c b/platform/generic/defaults.c new file mode 100644 index 0000000..36b2f07 --- /dev/null +++ b/platform/generic/defaults.c @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* XXX keep this here but blank for now */ diff --git a/platform/generic/library.mk b/platform/generic/library.mk new file mode 100644 index 0000000..6524974 --- /dev/null +++ b/platform/generic/library.mk @@ -0,0 +1,36 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LIBPGINDEP_DIR := $(GET_LOCAL_DIR) +LIBPGINDEP_BUILD:= $(call TOLIBDIR,$(LIBPGINDEP_DIR)/LIBPGINDEP.a) +COMMONLIBS += LIBPGINDEP + +# Force this library's symbols to be imported so that they can't be +# overridden. This library isn't designed with one function per object file +# to allow selective overriding +GLOBAL_LDFORCELIBS += $(LIBPGINDEP_BUILD) + +# Only process the remainder of the makefile if we are building libraries +# +ifeq ($(MAKEPHASE),libraries) + +LIBPGINDEP_OBJS := \ + $(LIBPGINDEP_DIR)/platform_indep.o \ + $(LIBPGINDEP_DIR)/target_indep.o \ + $(LIBPGINDEP_DIR)/target_pass_boot_manifest.o \ + $(LIBPGINDEP_DIR)/breadcrumbs.o + +LIBPGINDEP_OBJS := $(call TOLIBOBJDIR,$(LIBPGINDEP_OBJS)) + +$(LIBPGINDEP_BUILD): $(LIBPGINDEP_OBJS) + +ALL_DEPS += $(LIBPGINDEP_OBJS:%o=%d) + +endif diff --git a/platform/generic/platform_dep.c b/platform/generic/platform_dep.c new file mode 100644 index 0000000..255045e --- /dev/null +++ b/platform/generic/platform_dep.c @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2007-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#if WITH_HW_SEP +#include +#endif +#if WITH_EFFACEABLE +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// platfom_dep holds generic functions that are just defined once for all +// platforms, and are expected to be rebuilt for every target/product + + +#if !PLATFORM_VARIANT_IOP && !PLATFORM_VARIANT_AUDIO +#if (defined(__arm__) || defined(__arm64__)) +# include + +/* + * Default implementation of platform_cache_operation(), assumes the ARM architecture + * supplied functions are available and appropriate. + */ +void platform_cache_operation(int operation, void *address, u_int32_t length) +{ + uintptr_t start, end; + void (*func)(addr_t addr); + + /* all we are willing to do in the panic case is clean the entire cache */ + if (unlikely(operation & CACHE_PANIC)) { + if ((operation & CACHE_CLEAN) && (NULL == address) && (0 == length)) + arm_clean_dcache(); + return; + } + + /* disable interrupts as we don't want to be re-entered */ + enter_critical_section(); + + if ((0 == address) && (0 == length)) { + + /* invalidating the entire cache guarantees a crash */ + ASSERT((operation & (CACHE_CLEAN | CACHE_INVALIDATE)) != CACHE_INVALIDATE); + + /* whole-cache operations */ + switch(operation & (CACHE_CLEAN | CACHE_INVALIDATE)) { + case CACHE_CLEAN: + arm_clean_dcache(); + break; + + case CACHE_CLEAN | CACHE_INVALIDATE: + arm_clean_invalidate_dcache(); + break; + } + } else { + + /* ranged operations by line */ + start = (uintptr_t)address; + end = start + length; + switch (operation & (CACHE_CLEAN | CACHE_INVALIDATE)) { + case CACHE_INVALIDATE: + /* + * Non-aligned range invalidate operations are illegal + * as we may shoot something else sharing the line. + */ + ASSERT(0 == (start % CPU_CACHELINE_SIZE)); + ASSERT(0 == (length % CPU_CACHELINE_SIZE)); + + /* invalidate */ + func = arm_invalidate_dcache_line; + break; + + case CACHE_CLEAN: + /* adjust start to the base of the cacheline */ + start &= ~(CPU_CACHELINE_SIZE - 1); + func = arm_clean_dcache_line; + break; + + case CACHE_CLEAN | CACHE_INVALIDATE: + /* adjust start to the base of the cacheline */ + start &= ~(CPU_CACHELINE_SIZE - 1); + func = arm_clean_invalidate_dcache_line; + break; + default: + func = NULL; + } + /* do it */ + if (likely(NULL != func)) + for (; start < end; start += CPU_CACHELINE_SIZE) + func(start); + } + + /* write buffer is address-agnostic */ + if (operation & CACHE_DRAIN_WRITE_BUFFER) + arm_drain_write_buffer(); + +#if defined(__arm64__) + arm_memory_barrier(); +#endif + + exit_critical_section(); +} + +void platform_memory_barrier(void) +{ + arm_memory_barrier(); +} + +#else +# error no architecture support for platform_cache_operation +#endif /* ARCH_ARM */ +#endif // PLATFORM_VARIANT_IOP + + +// iBoot Flags +// Bit 0 - Restore host should send image capable of restore boot (a.k.a. iBEC). +// Bit 1 - Restore host should send ticket to validate images +// Bit 2 - Restore host should send Image4 images. +// Bit 3 - Current status of Secure fuse bit +// Bit 4 - Current status of Production fuse bit +// Bit 5 - Restore host should send images with SHA2-384 hash + +uint32_t platform_get_iboot_flags(void) +{ + u_int32_t flag_summary = 0; + +#if WITH_RESTORE_STRAP + flag_summary |= (1 << 0); +#endif + +#if WITH_TICKET + flag_summary |= (1 << 1); +#endif + +#if WITH_IMAGE4 + flag_summary |= (1 << 2); +#endif + + if (platform_get_secure_mode()) flag_summary |= (1 << 3); + + if (platform_get_current_production_mode()) flag_summary |= (1 << 4); + +#if WITH_SHA2_384 + flag_summary |= (1 << 5); +#endif + + return flag_summary; +} + +#ifndef PLATFORM_PRODUCT_ID +#define PLATFORM_PRODUCT_ID {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} +#endif + +const char* platform_get_product_id(void) +{ + static const char product_id[] = PLATFORM_PRODUCT_ID; + return product_id; +} + +u_int32_t platform_get_security_epoch(void) +{ +#if WITH_IMAGE4 + return chipid_get_minimum_epoch(); +#else + u_int32_t build_epoch = PLATFORM_SECURITY_EPOCH; + u_int32_t minimum_epoch = chipid_get_minimum_epoch(); + + if (minimum_epoch < build_epoch) minimum_epoch = build_epoch; + + return minimum_epoch; +#endif +} + +#ifndef DEFAULT_RECOVERY_MODE_PRODUCT_ID +#define DEFAULT_RECOVERY_MODE_PRODUCT_ID 0x1281 +#endif + +/* + * platform_get_usb_product_id() - returns the usb product + * + * + */ +uint16_t platform_get_usb_product_id(void) +{ +#if WITH_RECOVERY_MODE + return DEFAULT_RECOVERY_MODE_PRODUCT_ID; +#else + return 0x1226 + (platform_get_security_domain() & 3); +#endif +} + +const char *platform_get_usb_product_string(void) +{ +#if WITH_RECOVERY_MODE + return "Apple Mobile Device (Recovery Mode)"; +#else + return "Apple Mobile Device (DFU Mode)"; +#endif +} + +// gUSBSerialNumber Format: "CPID:xxxx CPRV:xx CPFM:xx SCEP:xx BDID:xx ECID:xxxxxxxxxxxxxxxx IBFL:xx" +// optionally includes " SRTG:[]" +// optionally includes " SRNM:[xxxxxxxxxxxxxxxx]" +static char gUSBSerialNumber[127]; +// Size iBoot SecureROM +// CPID (5 + 4) 9 9 9 +// CPRV + 1 + (5 + 2) 8 17 17 +// CPFM + 1 + (5 + 2) 8 25 25 +// SCEP + 1 + (5 + 2) 8 33 33 +// BDID + 1 + (5 + 2) 8 41 41 +// ECID + 1 + (5 + 16) 22 63 63 +// IBFL + 1 + (5 + 2) 8 71 71 +// SRTG + 1 + (5 + 2 + 24) 32 103 +// SRNM + 1 + (5 + 2 + 16) 24 95 +// nul + 1 1 96 104 + +static u_int32_t gUSBSerialNumberStatus; + +const char *platform_get_usb_serial_number_string(bool full) +{ + char srnm_buf[1 + (5 + 2 + 16) + 1]; + char imei_buf[1 + (5 + 2 + 16) + 1]; + char srtg_buf[1 + (5 + 2 + 24) + 1]; + int srnm_size = 0, imei_size = 0; + + // Return if the request string has already been generated + if (gUSBSerialNumberStatus > 1) return gUSBSerialNumber; + if (!full && (gUSBSerialNumberStatus > 0)) return gUSBSerialNumber; + + // Set the status based on the requested string + gUSBSerialNumberStatus = full ? 2 : 1; + + srtg_buf[0] = '\0'; + srnm_buf[srnm_size] = '\0'; + imei_buf[imei_size] = '\0'; + + snprintf(gUSBSerialNumber, sizeof(gUSBSerialNumber), + "CPID:%04X CPRV:%02X CPFM:%02X SCEP:%02X BDID:%02X ECID:%016llX IBFL:%02X", + platform_get_chip_id(), platform_get_chip_revision(), platform_get_fuse_modes(), + platform_get_security_epoch(), platform_get_board_id(), platform_get_ecid_id(), + platform_get_iboot_flags()); + +#if APPLICATION_SECUREROM + snprintf(srtg_buf, sizeof(srtg_buf), " SRTG:[%s]", build_tag_string); + strlcat(gUSBSerialNumber, srtg_buf, sizeof(gUSBSerialNumber)); +#endif + +#if WITH_SYSCFG + strlcpy(srnm_buf, " SRNM:[", sizeof(srnm_buf)); + srnm_size = syscfgCopyDataForTag('SrNm', (u_int8_t *)(srnm_buf + 7), 16); + if (srnm_size > 0) { + srnm_buf[7 + srnm_size] = '\0'; + strlcat(srnm_buf, "]", sizeof(srnm_buf)); + strlcat(gUSBSerialNumber, srnm_buf, sizeof(gUSBSerialNumber)); + } +#endif + + return gUSBSerialNumber; +} + +// gUSBMoreOther Format: "" +// optionally includes " NONC:xxxxxxxxxxxxxxxx" +// optionally includes " SNON:xxxxxxxxxxxxxxxx" +static char gUSBMoreOther[127]; +// SHA1: +// Size +// NONC + 1 + (5 + (2*20)) 46 +// SNON + 1 + (5 + (2*20)) 46 +// Total 92 +// +// SHA2-384: +// Size +// NONC + 1 + (5 + (2*32)) 70 +// SNON + 1 + (5 + (2*20)) 46 +// Total 116 + +static u_int32_t gUSBMoreOtherStatus; + +const char *platform_get_usb_more_other_string(bool full) +{ + u_int64_t nonc; + u_int8_t nonc_hash[HASH_OUTPUT_SIZE]; + char nonc_buf[1 + (5 + (2 * NONCE_HASH_OUTPUT_SIZE)) + 1]; + u_int8_t i; + + // Return if the request string has already been generated + if (gUSBMoreOtherStatus > 1) return gUSBMoreOther; + if (!full && (gUSBMoreOtherStatus > 0)) return gUSBMoreOther; + + // Set the status based on the requested string + gUSBMoreOtherStatus = full ? 2 : 1; + + nonc_buf[0] = '\0'; + + gUSBMoreOther[0] = '\0'; + + if (full) { + nonc = platform_get_nonce(); + hash_calculate((const void *)&nonc, sizeof(nonc), (void *)nonc_hash, sizeof(nonc_hash)); + + strlcpy(nonc_buf, " NONC:", sizeof(nonc_buf)); + for(i = 0; (i < NONCE_HASH_OUTPUT_SIZE) && (i < HASH_OUTPUT_SIZE); i++) + snprintf((nonc_buf + 1 + 5 + (i * 2)), (sizeof(nonc_buf) - 1 - 5 - (i * 2)), "%02X", nonc_hash[i]); + strlcat(gUSBMoreOther, nonc_buf, sizeof(gUSBMoreOther)); + +#if WITH_HW_SEP + u_int8_t snon[SEP_NONCE_SIZE]; + if (platform_get_sep_nonce(snon) == 0) { + + bzero(nonc_buf, sizeof(nonc_buf)); + strlcpy(nonc_buf, " SNON:", sizeof(nonc_buf)); + for(i = 0; (i < SEP_NONCE_SIZE); i++) + snprintf((nonc_buf + 1 + 5 + (i * 2)), (sizeof(nonc_buf) - 1 - 5 - (i * 2)), "%02X", snon[i]); + strlcat(gUSBMoreOther, nonc_buf, sizeof(gUSBMoreOther)); + } +#endif + } + + // dprintf(DEBUG_INFO, "%s, len=%ld\n", gUSBMoreOther, strlen(gUSBMoreOther)); + + return gUSBMoreOther; +} + +u_int64_t platform_consume_nonce(void) +{ + uint64_t nonce = 0; + const char* how = NULL; + +#if WITH_EFFACEABLE + if (effaceable_consume_nonce(&nonce)) { + how = "effaced"; + } +#elif WITH_NVRAM && WITH_ENV + if (mobile_ap_nonce_consume_nonce(&nonce)) { + how = "consumed"; + } +#endif + +#if WITH_RANDOM + if (!how) { + uint8_t *nonce_bytes = (uint8_t *)&nonce; + int result = random_get_bytes(nonce_bytes, sizeof(nonce)); + RELEASE_ASSERT(result == 0); + if (result == 0) { + how = "generated"; + } + } +#endif + + if (!how) { + nonce = 0; + how = "zeroed"; + } + +#if DEBUG_BUILD + dprintf(DEBUG_INFO, "boot-nonce (%s): 0x%016llX\n", how, nonce); +#endif + + return nonce; +} + +size_t platform_get_display_memory_size(void) +{ + size_t size = 0; + + struct display_info info; + + memset(&info, 0, sizeof(info)); + display_get_info(&info); + + if ((addr_t)info.framebuffer != 0) + size = (uintptr_t)PANIC_BASE - (uintptr_t)info.framebuffer; +#ifdef PURPLE_GFX_MEMORY_LEN + if (size < PURPLE_GFX_MEMORY_LEN) + size = PURPLE_GFX_MEMORY_LEN; +#endif + + return (size); +} diff --git a/platform/generic/platform_indep.c b/platform/generic/platform_indep.c new file mode 100644 index 0000000..d630114 --- /dev/null +++ b/platform/generic/platform_indep.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +// platfom_indep holds generic functions that are just defined once for all +// platforms, and are not expected to be rebuilt for every target/product. +// +// These functions can vary per BUILD, and per architecture, but not per +// PLATFORM, TARGET, PRODUCT, or CONFIG + +void platform_not_supported(void) +{ + dprintf(DEBUG_CRITICAL, "\n"); + dprintf(DEBUG_CRITICAL, "\n"); + dprintf(DEBUG_CRITICAL, "\n"); + dprintf(DEBUG_CRITICAL, "**************************************\n"); + dprintf(DEBUG_CRITICAL, "* *\n"); + dprintf(DEBUG_CRITICAL, "* This unit is not supported *\n"); + dprintf(DEBUG_CRITICAL, "* *\n"); + dprintf(DEBUG_CRITICAL, "**************************************\n"); + while (1); +} + +// Fuse Modes +// Bit 0 - Chip is Secure +// Bit 1 - Chip is Production + +uint32_t platform_get_fuse_modes(void) +{ + u_int32_t fuse_summary = 0; + + if (platform_get_secure_mode()) fuse_summary |= (1 << 0); + + if (platform_get_raw_production_mode()) fuse_summary |= (1 << 1); + + return fuse_summary; +} + +const char *platform_get_memory_manufacturer_string(void) +{ + uint8_t index; + + // This list is based of JEDEC Vendor list in dram.h + // index 0 and 15 are reserverd, we are using them to provide additional information related to the system. + static const char *memory_manufacturer_strings[JEDEC_NUM_MANUF_IDS] = { + "Unknown", + "Samsung", + "Qimonda", + "Elpida", + "Etron", + "Nanya", + "Hynix", + "Mosel", + "Winbond", + "ESMT", + "Reserved", + "Spansion", + "SST", + "ZMOS", + "Intel", + "Numonyx", + "Micron", + "FPGA", + }; + + index = platform_get_memory_manufacturer_id(); + + if(platform_is_pre_lpddr4()) { + + if (index >= JEDEC_NUM_MANUF_IDS) + return NULL; + + return memory_manufacturer_strings[index]; + } else { + switch(index) { + case JEDEC_LPDDR4_MANUF_ID_SAMSUNG: + return "Samsung"; + break; + + case JEDEC_LPDDR4_MANUF_ID_HYNIX: + return "Hynix"; + break; + + case JEDEC_LPDDR4_MANUF_ID_MICRON: + return "Micron"; + break; + + default: + return NULL; + break; + } + } +} + + +uintptr_t platform_get_memory_region_base(memory_region_type_t region) +{ + uintptr_t base = platform_get_memory_region_base_optional(region); + if (base == (uintptr_t)-1) + panic("unsupported region %d base requested\n", (int)region); + + return base; +} + +size_t platform_get_memory_region_size(memory_region_type_t region) +{ + size_t size = platform_get_memory_region_size_optional(region); + + if (size == (size_t)-1) + panic("unsupported region %d size requested\n", region); + + return size; +} + +void platform_apply_tunables(const struct tunable_chip_struct *tunable_chips, uint32_t num_tunable_chips, const char* type) +{ + const struct tunable_struct *tunable; + uintptr_t base_address; + uint32_t chip_rev = platform_get_chip_revision(); + uint32_t i; + uint32_t t; + bool match = false; + + if (num_tunable_chips == 0) + return; + + ASSERT(tunable_chips != NULL); + + // For each bucket of tunable values... + for (i = 0; i < num_tunable_chips; i++) { + + // Tunable for a newer chip revision? + if (tunable_chips[i].chip_rev > chip_rev) { + continue; + } + + // Tunable for an older chip revision? + if (tunable_chips[i].chip_rev < chip_rev) { + + if (match) { + // We've already found all the tunables matching + // this chip revision -- we're done. + break; + } else { + // We haven't found a match yet. Because the tunable + // chip table is supposed to be sorted from highest + // to lowest, finding an older chip revision means + // that there is no entry in the table for this + // chip revision and we'll use the first older one + // we find. + dprintf(DEBUG_SPEW, "%s tunables for chip rev %d not found -- using tunables for chip rev %d\n", + type, chip_rev, tunable_chips[i].chip_rev); + chip_rev = tunable_chips[i].chip_rev; + } + } + + // We've found a matching tunable chip revision (either an exact + // match or the next older chip revision). + match = true; + + // Get the base address and pointer to the tunables data. + tunable = tunable_chips[i].tunable; + ASSERT(tunable != NULL); + base_address = tunable_chips[i].base_address; + + // For each tunable in registers at this base address... + for (t = 0; tunable[t].offset != -1; t++) { + + // Elided tunables have a size of zero, just skip them. + if (tunable[t].size == 0) { + continue; + } + + switch (tunable[t].size) { + case sizeof(uint32_t): + { + volatile uint32_t *addr; + uint32_t new_reg, old_reg, mask, value; + + // Get the address of the register. + addr = (volatile uint32_t *)(base_address + tunable[t].offset); + + // Get the current value of the register. + old_reg = *addr; + mask = (uint32_t)tunable[t].mask; + value = (uint32_t)tunable[t].value; + + // If the tunable needs to be applied, do it. + if ((old_reg & mask) != (value & mask)) { + new_reg = old_reg; + new_reg &= ~mask; + new_reg |= value & mask; + *addr = new_reg; + dprintf(DEBUG_SPEW, "%s tunable addr/mask/value=%p/0x%08x/0x%08x: 0x%08x -> 0x%08x\n", + type, addr, mask, value, old_reg, new_reg); + } else { + dprintf(DEBUG_SPEW, "%s tunable addr/mask/value=%p/0x%08x/0x%08x: already correct 0x%08x\n", + type, addr, mask, value, old_reg); + } + break; + } + + case sizeof(uint64_t): + { + volatile uint64_t *addr; + uint64_t new_reg, old_reg, mask, value; + + // Get the address of the register. + addr = (volatile uint64_t *)(base_address + tunable[t].offset); + + // Get the current value of the register. + old_reg = *addr; + mask = tunable[t].mask; + value = tunable[t].value; + + // If the tunable needs to be applied, do it. + if ((old_reg & mask) != (value & mask)) { + new_reg = old_reg; + new_reg &= ~mask; + new_reg |= value & mask; + *addr = new_reg; + dprintf(DEBUG_SPEW, "%s tunable addr/mask/value=%p/0x%016llx/0x%016llx: 0x%016llx -> 0x%016llx\n", + type, addr, mask, value, old_reg, new_reg); + } else { + dprintf(DEBUG_SPEW, "%s tunable addr/mask/value=%p/0x%016llx/0x%016llx: already correct 0x%016llx\n", + type, addr, mask, value, old_reg); + } + break; + } + + default: + panic("Unsupported tunable register size"); + } + } + } +} + +uint8_t *platform_apply_dt_tunables(const struct tunable_chip_struct *tunable_chips, + uint32_t num_tunable_chips, uint8_t *buffer, + uintptr_t dt_base, const char *type) +{ + const struct tunable_struct *tunable; + struct tunable_struct_unpacked tunable_data; + uintptr_t addr; + uintptr_t base_address; + uint32_t chip_rev = platform_get_chip_revision(); + uint32_t i; + uint32_t t; + bool match = false; + + if (num_tunable_chips == 0) + return buffer; + + ASSERT((tunable_chips != NULL) && (buffer != NULL)); + + // For each bucket of tunable values... + for (i = 0; i < num_tunable_chips; i++) { + + // Tunable for a newer chip revision? + if (tunable_chips[i].chip_rev > chip_rev) { + continue; + } + + // Tunable for an older chip revision? + if (tunable_chips[i].chip_rev < chip_rev) { + + if (match) { + // We've already found all the tunables matching + // this chip revision -- we're done. + break; + } else { + // We haven't found a match yet. Because the tunable + // chip table is supposed to be sorted from highest + // to lowest, finding an older chip revision means + // that there is no entry in the table for this + // chip revision and we'll use the first older one + // we find. + dprintf(DEBUG_SPEW, "%s tunables for chip rev %d not found -- using tunables for chip rev %d\n", + type, chip_rev, tunable_chips[i].chip_rev); + chip_rev = tunable_chips[i].chip_rev; + } + } + + // We've found a matching tunable chip revision (either an exact + // match or the next older chip revision). + match = true; + + // Copy the tunable value and get the base address of the block it pertains to. + tunable = tunable_chips[i].tunable; + ASSERT(tunable != NULL); + base_address = tunable_chips[i].base_address; + + // For each tunable register at this base address... + for (t = 0; tunable[t].offset != -1; t++) { + + // Elided tunables have a size of zero, but pass them + // through in case the driver wants to un-elide them. + + // Copy the tunable data so we can update it. + tunable_data.offset = tunable[t].offset; + tunable_data.size = tunable[t].size; + tunable_data.mask = tunable[t].mask; + tunable_data.value = tunable[t].value; + + addr = base_address + tunable_data.offset; + + // Get the address of the register. + if (dt_base != 0) { + // Adjust the offset to match the reg property in the + // device tree. + tunable_data.offset = (uint32_t)addr - dt_base; + ASSERT(tunable_data.offset != -1); + } + + if (tunable_data.size == -1) { + dprintf(DEBUG_SPEW, "%s DT tunable @ 0x%lx: offset=0x%08x, size=%d, mask=0x%16llx, value=0x%16llx\n", + type, addr, + tunable_data.offset, tunable_data.size, + tunable_data.mask, tunable_data.value); + } else { + dprintf(DEBUG_SPEW, "%s DT tunable @ 0x%lx: offset=0x%08x, size=%d, mask=0x%08llx, value=0x%08llx\n", + type, addr, + tunable_data.offset, tunable_data.size, + tunable_data.mask, tunable_data.value); + } + memcpy(buffer, &tunable_data, sizeof(tunable_data)); + buffer += sizeof(tunable_data); + } + } + return buffer; +} + diff --git a/platform/generic/platform_info.S b/platform/generic/platform_info.S new file mode 100644 index 0000000..6d0f213 --- /dev/null +++ b/platform/generic/platform_info.S @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include + +/* + * Utility file exporting symbols at absolute locations. These + * values are largely useful to the build system before the final + * object is linked, or for diagnosis purposes later. + */ + + /* + * symbol + */ + .macro symbol + .global $0 + .set $0 , $1 + .endmacro + + /* This is used at link time */ + symbol _TEXT_BASE, TEXT_BASE + +#if 0 + /* debug/sanity checks */ + symbol _INSECURE_MEMORY_BASE, INSECURE_MEMORY_BASE + symbol _INSECURE_MEMORY_SIZE, INSECURE_MEMORY_SIZE + symbol _DEFAULT_KERNEL_ADDRESS, DEFAULT_KERNEL_ADDRESS + symbol _DEFAULT_KERNEL_SIZE, DEFAULT_KERNEL_SIZE + symbol _DEFAULT_RAMDISK_ADDRESS, DEFAULT_RAMDISK_ADDRESS + symbol _DEFAULT_RAMDISK_SIZE, DEFAULT_RAMDISK_SIZE + symbol _DEFAULT_DEVICETREE_ADDRESS, DEFAULT_DEVICETREE_ADDRESS + symbol _DEFAULT_DEVICETREE_SIZE, DEFAULT_DEVICETREE_SIZE + + symbol _IBOOT_SIZE, IBOOT_SIZE + symbol _MMU_TT_BASE, MMU_TT_BASE + symbol _MMU_TT_SIZE, MMU_TT_SIZE + symbol _STACK_BASE, STACK_BASE + symbol _STACK_SIZE, STACK_SIZE +#endif \ No newline at end of file diff --git a/platform/generic/pmgr/pmgr_binning.c b/platform/generic/pmgr/pmgr_binning.c new file mode 100644 index 0000000..d010ca7 --- /dev/null +++ b/platform/generic/pmgr/pmgr_binning.c @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +static uint64_t pmgr_binning_read_register(uint64_t address, uint32_t low, uint32_t high, bool reg64) +{ + uint64_t result = 0; + do { + uint64_t current_low; + uint64_t offset; + uint64_t register_value; + + if (reg64) { + offset = high/64; + current_low = offset * 64; + register_value = ((uint64_t *)(address))[offset]; + } else { + offset = high/32; + current_low = offset * 32; + register_value = ((uint32_t *)(address))[offset]; + } + + // Mask useful bit : [current_low:high] + register_value &= (1ULL << (high - current_low + 1)) - 1; + + if (current_low <= low) { + result |= register_value >> (low - current_low); + break; + } + + result |= register_value << (current_low - low); + high = current_low - 1; + } while (1); + + return result; +} + +static uint64_t pmgr_binning_read(const struct pmgr_binning_fuse_to_register *fuse_to_register, uint32_t binning_low, uint32_t binning_high) +{ + uint32_t result = 0; + while (1) { + uint32_t i = 0; + while (fuse_to_register[i].register_address != 0) { + if ((fuse_to_register[i].binning_high >= binning_high) && (fuse_to_register[i].binning_low <= binning_high)) { + break; + } + i++; + } + if (fuse_to_register[i].register_address == 0) { + return PMGR_BINNING_NOTFOUND; + } + + if ((fuse_to_register[i].binning_high >= binning_high) && (fuse_to_register[i].binning_low <= binning_low)) { + result |= pmgr_binning_read_register(fuse_to_register[i].register_address, + binning_low - fuse_to_register[i].binning_low + fuse_to_register[i].register_low, + binning_high - fuse_to_register[i].binning_low + fuse_to_register[i].register_low, + fuse_to_register[i].register_64bit); + break; + } + result |= pmgr_binning_read_register(fuse_to_register[i].register_address, + fuse_to_register[i].register_low, + binning_high - fuse_to_register[i].binning_low + fuse_to_register[i].register_low, + fuse_to_register[i].register_64bit) << (fuse_to_register[i].binning_low - binning_low); + binning_high = fuse_to_register[i].binning_low - 1; + } + return result; +} + +static uint32_t pmgr_binning_from_const_data(enum pmgr_binning_type_t type, uint32_t mode, bool use_binning) +{ + uint32_t i; + for (i = 0; i < pmgr_binning_mode_to_const_data_size; i++) { + if (pmgr_binning_mode_to_const_data[i].type != type) { + continue; + } + if (pmgr_binning_mode_to_const_data[i].mode != mode) { + continue; + } + if ((use_binning) && pmgr_binning_mode_to_const_data[i].bingroup != pmgr_binning_get_group() && pmgr_binning_mode_to_const_data[i].bingroup != PMGR_BINNING_GROUP_ALL) { + continue; + } + if ((use_binning) && (pmgr_binning_get_revision() < pmgr_binning_mode_to_const_data[i].fuse_revision_minimum)) { + continue; + } + if ((!use_binning) && (pmgr_binning_mode_to_const_data[i].fuse_revision_minimum != 0)) { + continue; + } + return pmgr_binning_mode_to_const_data[i].mv; + } + return PMGR_BINNING_NOTFOUND; +} + +uint32_t pmgr_binning_from_config_data(uint32_t voltage_index, const struct pmgr_binning_voltage_index_to_config **config_data) +{ + uint32_t i; + for (i = 0; i < pmgr_binning_voltage_index_to_config_data_size; i++) { + if (pmgr_binning_voltage_index_to_config_data[i].voltage_index != voltage_index) { + continue; + } + if (pmgr_binning_voltage_index_to_config_data[i].bingroup != pmgr_binning_get_group() && pmgr_binning_voltage_index_to_config_data[i].bingroup != PMGR_BINNING_GROUP_ALL) { + continue; + } + if (pmgr_binning_get_revision() < pmgr_binning_voltage_index_to_config_data[i].fuse_revision_minimum) { + continue; + } + *config_data = &pmgr_binning_voltage_index_to_config_data[i]; + + return pmgr_binning_voltage_index_to_config_data[i].safe_voltage; + } + return PMGR_BINNING_NOTFOUND; +} + +int32_t pmgr_binning_get_voltage_offset(uint32_t voltage_index, enum pmgr_binning_type_t type) +{ + uint32_t i; + uint32_t size = 0; + const struct pmgr_binning_voltage_index_to_offset *voltage_index_to_offset; + uint32_t board_id = platform_get_board_id(); + + for (i = 0; i < pmgr_binning_board_id_to_offsets_data_size; i++) { + if (pmgr_binning_board_id_to_offsets_data[i].board_id != board_id) { + continue; + } + if (pmgr_binning_board_id_to_offsets_data[i].type != type) { + continue; + } + if (platform_get_chip_revision() < pmgr_binning_board_id_to_offsets_data[i].chip_rev_min) { + continue; + } + if (pmgr_binning_board_id_to_offsets_data[i].bingroup != pmgr_binning_get_group() && pmgr_binning_board_id_to_offsets_data[i].bingroup != PMGR_BINNING_GROUP_ALL) { + continue; + } + + voltage_index_to_offset = pmgr_binning_board_id_to_offsets_data[i].voltage_offsets; + size = pmgr_binning_board_id_to_offsets_data[i].size; + break; + } + + for (i = 0; i < size; i++) { + if (voltage_index_to_offset[i].voltage_index != voltage_index) { + continue; + } + if (pmgr_binning_get_revision() < voltage_index_to_offset[i].fuse_revision_minimum) { + continue; + } + + return voltage_index_to_offset[i].offset; + } + + return 0; +} + +uint32_t pmgr_binning_mode_get_value(enum pmgr_binning_type_t type, uint32_t mode) +{ + uint32_t i = 0; + do { + if (pmgr_binning_mode_to_fuse_data[i].type == PMGR_BINNING_END_OF_LIST) { + return PMGR_BINNING_NOTFOUND; + } + if (pmgr_binning_mode_to_fuse_data[i].type != type) { + i++; + continue; + } + if (pmgr_binning_mode_to_fuse_data[i].mode != mode) { + i++; + continue; + } + if (type != PMGR_BINNING_GROUP && pmgr_binning_mode_to_fuse_data[i].bingroup != pmgr_binning_get_group() && pmgr_binning_mode_to_fuse_data[i].bingroup != PMGR_BINNING_GROUP_ALL) { + i++; + continue; + } + break; + } while (1); + + if (pmgr_binning_mode_to_fuse_data[i].low > pmgr_binning_mode_to_fuse_data[i].high) { + panic("Invalid low (%u) and high (%u) mode_to_fuse_data for type %u mode %u\n", pmgr_binning_mode_to_fuse_data[i].low, pmgr_binning_mode_to_fuse_data[i].high, type, mode); + } + + uint32_t result = pmgr_binning_read(pmgr_binning_mode_to_fuse_data[i].fuse_to_register, pmgr_binning_mode_to_fuse_data[i].low, pmgr_binning_mode_to_fuse_data[i].high); + return result; +} + +uint32_t pmgr_binning_get_base(void) +{ + static uint32_t base = 0; + if (base == 0) { + base = pmgr_binning_mode_get_value(PMGR_BINNING_BASE, 0); + } + return base; +} + +uint32_t pmgr_binning_get_group(void) +{ + static uint32_t group = 0; + if (group == 0) { + group =pmgr_binning_mode_get_value(PMGR_BINNING_GROUP, 0); + } + return group; +} + +uint32_t pmgr_binning_get_revision(void) +{ + static uint32_t revision = 0; + if (revision == 0) { + revision = pmgr_binning_mode_get_value(PMGR_BINNING_REV, 0); + } + return revision; +} + +uint32_t pmgr_binning_mode_get_mv(enum pmgr_binning_type_t type, uint32_t mode) +{ + uint32_t value = pmgr_binning_mode_get_value(type, mode); + if ((value == PMGR_BINNING_NOTFOUND) || (value == 0)) { + return PMGR_BINNING_NOTFOUND; + } + return 25 * (pmgr_binning_get_base() + 1) + value * 5; +} + +uint32_t pmgr_binning_get_mv(uint32_t voltage_index, bool sram, bool use_binning) +{ + uint32_t voltage; + int32_t voltage_offset; + uint32_t mode; + enum pmgr_binning_type_t type; + + if (sram) { + if (voltage_index >= pmgr_binning_voltage_config_sram_data_size) { + return PMGR_BINNING_NOTFOUND; + } + const struct pmgr_binning_voltage_config *binning_voltage_config; + binning_voltage_config = &pmgr_binning_voltage_config_sram_data[voltage_index]; + + voltage = binning_voltage_config->safe_voltage; + type = binning_voltage_config->type; + mode = binning_voltage_config->mode; + + if ((voltage == 0) && (type != PMGR_BINNING_NONE)){ + return pmgr_binning_from_const_data(type, mode, use_binning); + } + } else { + const struct pmgr_binning_voltage_index_to_config *config_data; + if (pmgr_binning_from_config_data(voltage_index, &config_data) == PMGR_BINNING_NOTFOUND) { + return PMGR_BINNING_NOTFOUND; + } + + voltage = config_data->safe_voltage; + type = config_data->type; + mode = config_data->mode; + + if (use_binning) { + uint32_t voltage_binning = pmgr_binning_mode_get_mv(type, mode); + if (voltage_binning != PMGR_BINNING_NOTFOUND) { + voltage = voltage_binning; + } + } + } + + voltage_offset = pmgr_binning_get_voltage_offset(voltage_index, type); + if ((int32_t)voltage + voltage_offset < 0) { + panic("Invalid voltage offset"); + } + + return voltage + voltage_offset; +} + +const struct pmgr_binning_vol_adj *pmgr_binning_get_vol_adj(uint32_t chipdid, uint32_t chip_rev, uint32_t voltage_index) +{ + uint32_t fuse_rev = pmgr_binning_get_revision(); + + for (size_t i = 0; i < pmgr_binning_voltadj_entry_data_size; i++) { + if (voltage_index != pmgr_binning_voltadj_entry_data[i].voltage_index) { + continue; + } + if ((chip_rev < pmgr_binning_voltadj_entry_data[i].chip_rev_min)) { + continue; + } + if ((fuse_rev < pmgr_binning_voltadj_entry_data[i].fuse_rev_min)) { + continue; + } + return &pmgr_binning_voltadj_entry_data[i].voltages; + } + return NULL; +} diff --git a/platform/generic/pmgr/pmgr_binning_menu.c b/platform/generic/pmgr/pmgr_binning_menu.c new file mode 100644 index 0000000..a3d4f3f --- /dev/null +++ b/platform/generic/pmgr/pmgr_binning_menu.c @@ -0,0 +1,344 @@ +/* + + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if !RELEASE_BUILD && WITH_MENU + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static bool pmgr_binning_menu_override_get_voltage_indexes(bool gpu, uint32_t *voltage_indexes, uint32_t voltage_index_size, uint32_t *voltage_index_found) +{ + uint32_t freq = 0; + uint32_t i = 0; + const char *name = env_get(gpu?"pmgr_gpu_override":"pmgr_cpu_override"); + const struct pmgr_binning_voltage_index_to_config *config_data; + *voltage_index_found = 0; + if (name == NULL) { + return false; + } + + while (i < voltage_index_size) { + if (i > 0) { + name = strchr(name, ','); + if (name == NULL) { + break; + } + name++; + } + + voltage_indexes[i] = atoi(name); + if (pmgr_binning_from_config_data(voltage_indexes[i], &config_data) == PMGR_BINNING_NOTFOUND) { + return false; + } + if ((gpu) && (config_data->type != PMGR_BINNING_GPU)) { + return false; + } + if ((!gpu) && (config_data->type != PMGR_BINNING_CPU)) { + return false; + } + freq = pmgr_platform_get_freq(gpu, voltage_indexes[i]); + if (freq == 0) { + return false; + } + i++; + } + *voltage_index_found = i; + return true; +} + +static bool pmgr_binning_menu_find_safe_voltage(enum pmgr_binning_type_t type, uint32_t mode, + uint32_t *safe_voltage, uint32_t *freq) +{ + uint32_t i; + *freq = 0; + for (i = 0; i < pmgr_binning_voltage_config_sram_data_size; i++) { + if (pmgr_binning_voltage_config_sram_data[i].mode != mode) { + continue; + } + if (pmgr_binning_voltage_config_sram_data[i].type != type) { + continue; + } + *safe_voltage = pmgr_binning_voltage_config_sram_data[i].safe_voltage; + return true; + } + for (i = 0; i < pmgr_binning_voltage_index_to_config_data_size; i++) { + if (pmgr_binning_voltage_index_to_config_data[i].mode != mode) { + continue; + } + if (pmgr_binning_voltage_index_to_config_data[i].type != type) { + continue; + } + if (type == PMGR_BINNING_CPU) { + *freq = pmgr_platform_get_freq(false, pmgr_binning_voltage_index_to_config_data[i].voltage_index); + } else if (type == PMGR_BINNING_GPU) { + *freq = pmgr_platform_get_freq(true, pmgr_binning_voltage_index_to_config_data[i].voltage_index); + } + *safe_voltage = pmgr_binning_voltage_index_to_config_data[i].safe_voltage; + return true; + } + return false; +} + +static void pmgr_binning_menu_print_type(enum pmgr_binning_type_t type) +{ + uint32_t mode; + for (mode = 1; mode < 63; mode++) { + uint32_t result = pmgr_binning_mode_get_value(type, mode); + uint32_t safe_voltage; + uint32_t freq; + if ((result == PMGR_BINNING_NOTFOUND) || (result == 0)) { + continue; + } + printf(" mode %u %u mV (0x%x)", mode, pmgr_binning_mode_get_mv(type, mode), pmgr_binning_mode_get_value(type, mode)); + + if (!pmgr_binning_menu_find_safe_voltage(type, mode, &safe_voltage, &freq)) { + printf(" no safe voltage"); + } else { + printf(" safe voltage %u mV", safe_voltage); + } + + if (freq > 0) { + printf(" %u MHz", freq); + } + printf("\n"); + } +} + +static void pmgr_binning_menu_voltage_config_print(const struct pmgr_binning_voltage_config *voltage_config, uint32_t voltage_index) +{ + const char *name = ""; + uint32_t freq = 0, safe_voltage = 0, mode = 0, type = 0; + bool sram = false; + + if (voltage_config != NULL) { + safe_voltage = voltage_config->safe_voltage; + mode = voltage_config->mode; + type = voltage_config->type; + } + else { + const struct pmgr_binning_voltage_index_to_config *config_data; + if (pmgr_binning_from_config_data(voltage_index, &config_data) == PMGR_BINNING_NOTFOUND) { + return; + } + safe_voltage = config_data->safe_voltage; + mode = config_data->mode; + type = config_data->type; + } + if (type == PMGR_BINNING_NONE) { + return; + } + switch (type) { + case PMGR_BINNING_CPU: + name = "CPU"; + freq = pmgr_platform_get_freq(false, voltage_index); + break; + case PMGR_BINNING_GPU: + name = "GPU"; + freq = pmgr_platform_get_freq(true, voltage_index); + break; + case PMGR_BINNING_SOC: + name = "SOC"; + break; + case PMGR_BINNING_CPU_SRAM: + name = "CPU SRAM"; + sram = true; + break; + case PMGR_BINNING_GPU_SRAM: + name = "GPU SRAM"; + sram = true; + break; + case PMGR_BINNING_SRAM: + name = "SRAM"; + sram = true; + break; + default: + name = "Unknown"; + break; + } + + printf(" %s index %u safe voltage %u mV", + name, + voltage_index, + pmgr_binning_get_mv(voltage_index, sram, false)); + + if (pmgr_binning_mode_get_mv(type, mode) != PMGR_BINNING_NOTFOUND) { + printf(" binning %u mV", pmgr_binning_get_mv(voltage_index, sram, true)); + } else { + printf(" no binning %u mV", pmgr_binning_get_mv(voltage_index, sram, true)); + } + + printf(" offset %d mV", pmgr_binning_get_voltage_offset(voltage_index, type)); + + if (mode != PMGR_BINNING_MODE_NONE && mode > 0) { + printf(" mode %u", mode); + } + + if (freq > 0) { + printf(" %u MHz", freq); + } + + if (sram && safe_voltage == 0) { + uint32_t i; + for (i = 0; i < pmgr_binning_mode_to_const_data_size; i++) { + if (pmgr_binning_mode_to_const_data[i].type != type) { + continue; + } + if (pmgr_binning_mode_to_const_data[i].mode != mode) { + continue; + } + if (pmgr_binning_mode_to_const_data[i].bingroup != pmgr_binning_get_group() && pmgr_binning_mode_to_const_data[i].bingroup != PMGR_BINNING_GROUP_ALL) { + continue; + } + printf(" fuse >= %d %d mV", pmgr_binning_mode_to_const_data[i].fuse_revision_minimum, pmgr_binning_mode_to_const_data[i].mv + pmgr_binning_get_voltage_offset(voltage_index, type)); + } + } + else if (!sram && mode != PMGR_BINNING_MODE_NONE) { + uint32_t i; + for (i = 0; i < pmgr_binning_voltage_index_to_config_data_size; i++) { + if (pmgr_binning_voltage_index_to_config_data[i].voltage_index != voltage_index) { + continue; + } + if (pmgr_binning_voltage_index_to_config_data[i].type != type) { + continue; + } + if (pmgr_binning_voltage_index_to_config_data[i].bingroup != pmgr_binning_get_group() && pmgr_binning_voltage_index_to_config_data[i].bingroup != PMGR_BINNING_GROUP_ALL) { + continue; + } + printf(" fuse >= %d %d mV", pmgr_binning_voltage_index_to_config_data[i].fuse_revision_minimum, pmgr_binning_voltage_index_to_config_data[i].safe_voltage + pmgr_binning_get_voltage_offset(voltage_index, type)); + } + } + printf("\n"); +} + +static void pmgr_binning_menu_current_values_type(enum pmgr_binning_type_t type) +{ + uint32_t i = 0; + uint32_t freq; + uint32_t voltage; + while (pmgr_platform_get_perf_state(type, i, &voltage, &freq)) { + if (freq == 0) { + printf(" state %u: %u mV", i, voltage); + } else { + printf(" state %u: %u Mhz %u mV", i, freq / 1000000, voltage); + } + if ((type == PMGR_BINNING_CPU) && (pmgr_platform_get_perf_state(PMGR_BINNING_CPU_SRAM, i, &voltage, &freq))) { + printf(" SRAM %u mV", voltage); + } + if ((type == PMGR_BINNING_GPU) && (pmgr_platform_get_perf_state(PMGR_BINNING_GPU_SRAM, i, &voltage, &freq))) { + printf(" SRAM %u mV", voltage); + } + printf("\n"); + i++; + } +} + +static int do_pmgr(int argc, struct cmd_arg *args) +{ + uint32_t voltage_indexes[32]; + uint32_t max_voltage_index = 0; + uint32_t voltage_index_found; + if ((argc < 2) || ((strcmp(args[1].str, "binning") != 0) && (strcmp(args[1].str, "values") != 0))) { + printf("Usage\n"); + printf(" pmgr [values | [binning [internal|values]]]\n"); + printf(" pmgr binning: fused value\n"); + printf(" pmgr binning internal: fused value and all known operating points\n"); + printf(" pmgr values: values currently set in PMGR/ACC registers\n"); + return 0; + } + + if ((argc > 1) && (strcmp(args[1].str, "values") == 0)) { + printf("CPU:\n"); + pmgr_binning_menu_current_values_type(PMGR_BINNING_CPU); + printf("GPU:\n"); + pmgr_binning_menu_current_values_type(PMGR_BINNING_GPU); + printf("SOC:\n"); + pmgr_binning_menu_current_values_type(PMGR_BINNING_SOC); + return 0; + } + + printf("Fuse revision %u base %u bin group %u\n", pmgr_binning_get_revision(), pmgr_binning_get_base(), pmgr_binning_get_group()); + printf(" CPU\n"); + pmgr_binning_menu_print_type(PMGR_BINNING_CPU); + printf(" CPU SRAM\n"); + pmgr_binning_menu_print_type(PMGR_BINNING_CPU_SRAM); + printf(" GPU\n"); + pmgr_binning_menu_print_type(PMGR_BINNING_GPU); + printf(" GPU SRAM\n"); + pmgr_binning_menu_print_type(PMGR_BINNING_GPU_SRAM); + printf(" SRAM\n"); + pmgr_binning_menu_print_type(PMGR_BINNING_SRAM); + printf(" SOC\n"); + pmgr_binning_menu_print_type(PMGR_BINNING_SOC); + + if ((argc > 2) && (strcmp(args[2].str, "internal") == 0)) { + uint32_t i; + printf("\n"); + for (i = 0; i < pmgr_binning_voltage_index_to_config_data_size; i++) { + if (pmgr_binning_voltage_index_to_config_data[i].voltage_index > max_voltage_index) { + max_voltage_index = pmgr_binning_voltage_index_to_config_data[i].voltage_index; + } + } + for (i = 0; i <= max_voltage_index; i++) { + pmgr_binning_menu_voltage_config_print(NULL, i); + } + for (i = 0; i < pmgr_binning_voltage_config_sram_data_size; i++) { + pmgr_binning_menu_voltage_config_print(&pmgr_binning_voltage_config_sram_data[i], i); + } + } + + if (pmgr_binning_menu_override_get_voltage_indexes(false, voltage_indexes, sizeof(voltage_indexes)/sizeof(voltage_indexes[0]), &voltage_index_found)) { + uint32_t i; + for (i = 0; i < voltage_index_found; i++) { + if (i == 0) { + printf("\n\nOverridden CPU states:\n"); + } + printf(" state %u ", i + 3); // state 0 (bypass), 1 (securerom) and 2 (current state) are not overridden + pmgr_binning_menu_voltage_config_print(NULL, voltage_indexes[i]); + } + } + if (pmgr_binning_menu_override_get_voltage_indexes(true, voltage_indexes, sizeof(voltage_indexes)/sizeof(voltage_indexes[0]), &voltage_index_found)) { + uint32_t i; + for (i = 0; i < voltage_index_found; i++) { + if (i == 0) { + printf("\n\nOverridden GPU states:\n"); + } + printf(" state %u ", i + 1); // state 0 (off) are not overridden + pmgr_binning_menu_voltage_config_print(NULL, voltage_indexes[i]); + } + } + return 0; +} + +void pmgr_binning_menu_update_states(void) +{ + uint32_t voltage_indexes[32]; + uint32_t voltage_index_found; + + if (pmgr_binning_menu_override_get_voltage_indexes(false, voltage_indexes, sizeof(voltage_indexes)/sizeof(voltage_indexes[0]), &voltage_index_found)) { + pmgr_platform_set_perf_state(false, 3, voltage_indexes, voltage_index_found); + } + if (pmgr_binning_menu_override_get_voltage_indexes(true, voltage_indexes, sizeof(voltage_indexes)/sizeof(voltage_indexes[0]), &voltage_index_found)) { + pmgr_platform_set_perf_state(true, 1, voltage_indexes, voltage_index_found); + } +} + +// _command, _function, _help, _meta +MENU_COMMAND_DEVELOPMENT(pmgr, do_pmgr, "Print pmgr data", NULL); + +#endif // !RELEASE_BUILD && WITH_MENU diff --git a/platform/generic/pmgr/rules.mk b/platform/generic/pmgr/rules.mk new file mode 100644 index 0000000..9539312 --- /dev/null +++ b/platform/generic/pmgr/rules.mk @@ -0,0 +1,42 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# All H8+ chip must use pmgr_binning +PMGR_BINNING=0 + +ifeq ($(SUB_PLATFORM),s8000) +PMGR_BINNING=1 +endif + +ifeq ($(SUB_PLATFORM),s8001) +PMGR_BINNING=1 +endif + +ifeq ($(SUB_PLATFORM),s8003) +PMGR_BINNING=1 +endif + +ifeq ($(PMGR_BINNING),1) +ALL_OBJS += \ + $(LOCAL_DIR)/pmgr_binning.o + +ifneq ($(BUILD),RELEASE) +ifeq ($(PRODUCT),iBoot) +ALL_OBJS += \ + $(LOCAL_DIR)/pmgr_binning_menu.o +endif +ifeq ($(PRODUCT),iBEC) +ALL_OBJS += \ + $(LOCAL_DIR)/pmgr_binning_menu.o +endif +endif +endif + diff --git a/platform/generic/rules.mk b/platform/generic/rules.mk new file mode 100644 index 0000000..212c8f6 --- /dev/null +++ b/platform/generic/rules.mk @@ -0,0 +1,48 @@ +# Copyright (C) 2007-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +# +# Objects that must be built for every target. +# +# Adding files here is very expensive, as each file +# gets compiled for every target/product/build permutation. +# +# + +ifneq ($(APPLICATION),SecureROM) +MODULES += \ + $(LOCAL_DIR)/pmgr +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/default_mib.o \ + $(LOCAL_DIR)/platform_info.o \ + $(LOCAL_DIR)/platform_dep.o \ + $(LOCAL_DIR)/target_dep.o + +# Include library with platform/target/product-independent functions +LIBRARY_MODULES += $(LOCAL_DIR) + +# +# The platform_info file contains symbols with useful information +# +INFO_SYMBOL_FILE := $(call TOBUILDDIR,$(LOCAL_DIR)/platform_info.o) + +# for platform_get_security_epoch() +ifeq ($(DEVMAP_EPOCH),) +OPTIONS += PLATFORM_SECURITY_EPOCH=00 +else +OPTIONS += PLATFORM_SECURITY_EPOCH=$(DEVMAP_EPOCH) +endif + +ifneq ($(DEVMAP_PRODUCT_ID),) +OPTIONS += PLATFORM_PRODUCT_ID=`echo $(DEVMAP_PRODUCT_ID) | sed 's/../0x&,/g' | sed 's/.*/{&}/g'` +endif diff --git a/platform/generic/target_dep.c b/platform/generic/target_dep.c new file mode 100644 index 0000000..08fbbfc --- /dev/null +++ b/platform/generic/target_dep.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +// Target/product dependent functions that aren't expected to be overridden by targets + +bool target_is_tethered(void) +{ +#if WITH_SYSCFG + uint8_t tethcfg[16]; + + if ((syscfgCopyDataForTag('Teth', tethcfg, 16) != -1) && (tethcfg[0] != 0x0)) { + return true; + } +#endif + + return 0 != env_get_uint("is-tethered", 0); +} diff --git a/platform/generic/target_indep.c b/platform/generic/target_indep.c new file mode 100644 index 0000000..31e33cc --- /dev/null +++ b/platform/generic/target_indep.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +bool target_config_ap(void) +{ + static bool valid = false; + static bool result; + + if (!valid) { + result = (platform_get_board_id() & 1) == 0; + valid = true; + } + + return result; +} + +bool target_config_dev(void) +{ + static bool valid = false; + static bool result; + + if (!valid) { + result = (platform_get_board_id() & 1) != 0; + valid = true; + } + + return result; +} diff --git a/platform/generic/target_pass_boot_manifest.c b/platform/generic/target_pass_boot_manifest.c new file mode 100644 index 0000000..2fa1469 --- /dev/null +++ b/platform/generic/target_pass_boot_manifest.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +/** + * Stash away properties in a simple data structure while the image is being validated. + * + * The image4 wrapper extracts out properties before declaring an overall image valid/invalid, + * and we also can load the kernelcache before the device tree. + */ +#define N_BOOL_PROPS 20 +#define N_INT_PROPS 20 +#define N_STRING_PROPS 10 +#define MAX_IMG4_STRING_LEN 64 +typedef struct { + uint32_t tag; + bool val; +} bool_prop_t; +typedef struct { + uint32_t tag; + uint64_t val; +} int_prop_t; +typedef struct { + uint32_t tag; + size_t length; + uint8_t data[MAX_IMG4_STRING_LEN]; +} string_prop_t; + +typedef struct { + bool_prop_t bool_props[N_BOOL_PROPS]; + int_prop_t int_props[N_INT_PROPS]; + string_prop_t string_props[N_STRING_PROPS]; + +} image4_property_collection_t; + +struct { + bool is_valid; + bool cb_encountered_error; + image4_property_collection_t manifest_properties; + image4_property_collection_t manifest_object_properties; +} image4_properties; + +static bool image4_start_cb(uint32_t type) +{ + return (type == IMAGE_TYPE_KERNELCACHE || type == IMAGE_TYPE_KERNELCACHE_RESTORE); +} +static void image4_update_validity(bool is_valid) +{ + if (!is_valid) { + bzero(&image4_properties, sizeof(image4_properties)); + } + image4_properties.is_valid = is_valid; +} +static void image4_bool_cb(uint32_t tag, bool is_object_property, bool val) +{ + bool_prop_t* properties = NULL; + if (is_object_property) { + properties = image4_properties.manifest_object_properties.bool_props; + } else { + properties = image4_properties.manifest_properties.bool_props; + } + + for(int i = 0; i < N_BOOL_PROPS; i++) + { + if(properties[i].tag == 0) + { + properties[i].tag = tag; + properties[i].val = val; + return; + } + } + dprintf(DEBUG_CRITICAL, "Ran out of space storing boolean properties -- please tune N_BOOL_PROPS"); + image4_properties.cb_encountered_error = true; +} +static void image4_int_cb(uint32_t tag, bool is_object_property, uint64_t val) +{ + int_prop_t* properties = NULL; + if (is_object_property) { + properties = image4_properties.manifest_object_properties.int_props; + } else { + properties = image4_properties.manifest_properties.int_props; + } + + for(int i = 0; i < N_INT_PROPS; i++) + { + if(properties[i].tag == 0) + { + properties[i].tag = tag; + properties[i].val = val; + return; + } + } + dprintf(DEBUG_CRITICAL, "Ran out of space storing integer properties -- please tune N_INT_PROPS"); + image4_properties.cb_encountered_error = true; +} +static void image4_string_cb(uint32_t tag, bool is_object_property, uint8_t* data, size_t length) +{ + string_prop_t* properties = NULL; + if (is_object_property) { + properties = image4_properties.manifest_object_properties.string_props; + } else { + properties = image4_properties.manifest_properties.string_props; + } + + for(int i = 0; i < N_STRING_PROPS; i++) + { + if(properties[i].tag == 0) + { + if (length > MAX_IMG4_STRING_LEN) { + dprintf(DEBUG_CRITICAL, "image4_string_cb: Property length %lu exceeds max supported length, %u", length, MAX_IMG4_STRING_LEN); + image4_properties.cb_encountered_error = true; + return; + } + properties[i].tag = tag; + memcpy(properties[i].data, data, length); + properties[i].length = length; + return; + } + } + dprintf(DEBUG_CRITICAL, "Ran out of space storing string properties -- please tune N_STRING_PROPS"); + image4_properties.cb_encountered_error = true; +} +#define IMG4UNTAG(x) (((x) >> 24) & 0xff),(((x) >> 16) & 0xff),(((x) >> 8) & 0xff),((x) & 0xff) + +static int image4_copy_boolean_properties(DTNode* node, bool_prop_t* props) +{ + char entryName[50]; + char* propName; + void* propData; + uint32_t propSize; + for(int i = 0; (i < N_BOOL_PROPS) && (props[i].tag != 0); i++) { + snprintf(entryName, sizeof(entryName), "UnusedBooleanProperty%d", i); + propName = entryName; + if (!FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_CRITICAL, "Ran out of boolean entries %s", propName); + return -1; + } + snprintf(entryName, sizeof(entryName), "%c%c%c%c", IMG4UNTAG(props[i].tag)); + strlcpy(propName, entryName, kPropNameLength); + memcpy(propData, &props[i].val, sizeof(bool)); + } + return 0; +} +static int image4_copy_integer_properties(DTNode* node, int_prop_t* props) +{ + char entryName[50]; + char* propName; + void* propData; + uint32_t propSize; + for(int i = 0; (i < N_INT_PROPS) && (props[i].tag != 0); i++) { + snprintf(entryName, sizeof(entryName), "UnusedIntegerProperty%d", i); + propName = entryName; + if (!FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_CRITICAL, "Ran out of integer entries %s", propName); + return -1; + } + snprintf(entryName, sizeof(entryName), "%c%c%c%c", IMG4UNTAG(props[i].tag)); + strlcpy(propName, entryName, kPropNameLength); + memcpy(propData, &props[i].val, sizeof(uint64_t)); + } + return 0; +} +static int image4_copy_string_properties(DTNode* node, string_prop_t* props) +{ + char entryName[50]; + char* propName; + void* propData; + uint32_t propSize; + for(int i = 0; (i < N_STRING_PROPS) && (props[i].tag != 0); i++) { + snprintf(entryName, sizeof(entryName), "UnusedStringProperty%d", i); + propName = entryName; + if (!FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_CRITICAL, "Ran out of string entries %s", propName); + return -1; + } + if (propSize < props[i].length) { + dprintf(DEBUG_CRITICAL, "DT property size too small to fit string property"); + return -2; + } + + snprintf(entryName, sizeof(entryName), "%c%c%c%c", IMG4UNTAG(props[i].tag)); + strlcpy(propName, entryName, kPropNameLength); + memcpy(propData, &props[i].data, props[i].length); + } + return 0; +} + +static bool initialized; + +int target_init_boot_manifest(void) +{ + image4_register_property_capture_callbacks(image4_start_cb, + image4_bool_cb, image4_int_cb, image4_string_cb, image4_update_validity); + initialized=true; + return 0; +} +int target_pass_boot_manifest(void) +{ + // You must call init before loading the image4 of interest. + if (!initialized) + panic("target_pass_boot_manifest() used without target_init_boot_manifest()"); + + if (!image4_properties.is_valid || image4_properties.cb_encountered_error) { + // Don't touch the DT unless the image is validated. + return -1; + } + const char* ManifestPropertiesPath = "chosen/manifest-properties"; + const char* ManifestObjectPropertiesPath = "chosen/manifest-object-properties"; + DTNode* dtnode; + if (FindNode(0, ManifestPropertiesPath, &dtnode)) { + if (image4_copy_boolean_properties(dtnode, image4_properties.manifest_properties.bool_props)) + return -2; + + if (image4_copy_integer_properties(dtnode, image4_properties.manifest_properties.int_props)) + return -3; + + if (image4_copy_string_properties(dtnode, image4_properties.manifest_properties.string_props)) + return -4; + } else { + dprintf(DEBUG_CRITICAL, "Can't find manifest properties path %s -- Skipping DT patching\n", ManifestPropertiesPath); + return -5; + } + if (FindNode(0, ManifestObjectPropertiesPath, &dtnode)) { + if (image4_copy_boolean_properties(dtnode, image4_properties.manifest_object_properties.bool_props)) + return -6; + if (image4_copy_integer_properties(dtnode, image4_properties.manifest_object_properties.int_props)) + return -7; + if (image4_copy_string_properties(dtnode, image4_properties.manifest_object_properties.string_props)) + return -8; + } else { + dprintf(DEBUG_CRITICAL, "Can't find manifest object properties path %s -- Skipping DT patching\n", ManifestObjectPropertiesPath); + return -9; + } + return 0; +} diff --git a/platform/s5l8747x/asm.S b/platform/s5l8747x/asm.S new file mode 100644 index 0000000..bf3d2f7 --- /dev/null +++ b/platform/s5l8747x/asm.S @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include + + .text + +ARM_FUNCTION _platform_start + +#if WITH_PROFILE && PROFILE_BUF_SIZE > 0 + // Turn on PCLK to TIM64 + mov r2, #0x0200 + movt r2, #0x3c50 + ldr r3, [r2, #4] + bic r3, #(1 << 30) + str r3, [r2, #4] + + // Turn on NCLK to TIM64 + ldr r3, [r2, #0x10] + bic r3, #(1 << 8) + str r3, [r2, #0x10] + + // Enable TIM64 + mov r2, #0x0088 + movt r2, #0x3c70 + // r3 = (r<<15)|(1<<4) + mov r3, #((1 << 15) | (1 << 4)) + movt r3, #1 + str r3, [r2] +#endif + + bx lr + + diff --git a/platform/s5l8747x/chipid/chipid.c b/platform/s5l8747x/chipid/chipid.c new file mode 100644 index 0000000..d295a55 --- /dev/null +++ b/platform/s5l8747x/chipid/chipid.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +bool chipid_get_production_mode(void) +{ + while (!chipid_get_read_done()); + + return ((rCHIPIDL >> 0) & 1) != 0; +} + +bool chipid_get_secure_mode(void) +{ + while (!chipid_get_read_done()); + + return ((rCHIPIDH >> 1) & 1) != 0; +} + +u_int32_t chipid_get_security_domain(void) +{ + while (!chipid_get_read_done()); + +#if SUPPORT_FPGA + return kPlatformSecurityDomainDarwin; +#else + return (rCHIPIDH >> 1) & 3; +#endif +} + +u_int32_t chipid_get_minimum_epoch(void) +{ + while (!chipid_get_read_done()); + + return (rCHIPIDH >> 3) & 0x7F; +} + +bool chipid_get_ecid_image_personalization_required(void) +{ + return ((rCHIPIDH >> 14) & 1) != 0; +} + +u_int32_t chipid_get_board_id(void) +{ + while (!chipid_get_read_done()); + + return (rCHIPIDH >> 10) & 3; +} + +u_int32_t chipid_get_chip_id(void) +{ + while (!chipid_get_read_done()); + + return (rCHIPIDH >> 16) & 0xFFFF; +} + +u_int32_t chipid_get_chip_revision(void) +{ + while (!chipid_get_read_done()); + + return (((rCHIPIDL >> 24) & 0xF) << 4) | (((rCHIPIDL >> 28) & 0xF) << 0); +} + +u_int32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +u_int64_t chipid_get_ecid_id(void) +{ + u_int64_t ecid = 0; + + while (!chipid_get_read_done()); + +#if SUPPORT_FPGA + ecid = 0x000012345678ABCDULL; +#else + /* + * For the sake of the next poor bastard that comes along and has + * to decode the ECID produced by this silliness, the code here + * produces output formatted thus: + * + * 6 4 3 1 + * 3 8 2 6 0 + * ......................lllllllllllllllllllllwwwwwyyyyyyyyxxxxxxxx + * + * l - lot number + * w - wafer number + * y - wafer y position + * x - wafer x position + */ + ecid |= ((rDIEIDL >> 0)) & ((1ULL << (21 - 0)) - 1); // LOT_ID + + ecid <<= (26 - 21); + ecid |= ((rDIEIDL >> 21)) & ((1ULL << (26 - 21)) - 1); // WAFER_NUM + + ecid <<= (10 - 2); + ecid |= ((rDIEIDH >> 2)) & ((1ULL << (10 - 2)) - 1); // Y_POS + + ecid <<= (32 - 26); + ecid |= ((rDIEIDL >> 26)) & ((1ULL << (32 - 26)) - 1); // X_POS_H + + ecid <<= ( 2 - 0); + ecid |= ((rDIEIDH >> 0)) & ((1ULL << ( 2 - 0)) - 1); // X_POS_L +#endif + + return ecid; +} + +u_int64_t chipid_get_die_id(void) +{ + while (!chipid_get_read_done()); + + return ((u_int64_t)rDIEIDH << 32) | rDIEIDL; +} + +// chipid_get_tv_dac_cals +// Saves the three tv dac calibration values in the given array. +// +void chipid_get_tv_dac_cals(u_int32_t *dac_cals) +{ + while (!chipid_get_read_done()); + + dac_cals[0] = (rCHIPIDL >> 9) & 0x1F; + dac_cals[1] = (rCHIPIDL >> 14) & 0x1F; + dac_cals[2] = (rCHIPIDL >> 19) & 0x1F; +} + +bool chipid_get_read_done(void) +{ +#if !SUPPORT_FPGA + return ((rEFUSE_READ_DONE >> 0) & 1) != 0; +#else + return true; +#endif +} + diff --git a/platform/s5l8747x/chipid/rules.mk b/platform/s5l8747x/chipid/rules.mk new file mode 100644 index 0000000..3d20871 --- /dev/null +++ b/platform/s5l8747x/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/s5l8747x/clocks/clocks.c b/platform/s5l8747x/clocks/clocks.c new file mode 100644 index 0000000..f731da5 --- /dev/null +++ b/platform/s5l8747x/clocks/clocks.c @@ -0,0 +1,504 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define PLL_FREQ_TARGET(pllx) (1ULL * pllx##_O * pllx##_M / pllx##_P / (1 << pllx##_S)) + +#define PRESCALE_EN(x) ((x) == 1 ? 0 : 1) +#define CLK_DIV_N(x) ((x) == 1 ? 0 : ((x)/2)-1) + +#if APPLICATION_IBOOT + +//PLL0 @ 800MHz +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 12 +#define PLL0_M 400 +#define PLL0_S 0 +#define PLL0_VSEL 1 // High if 600MHz < Fvco < 864MHz (Fvco = Fin * M / P) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +// PLL1 @ 330MHz +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 4 +#define PLL1_M 110 +#define PLL1_S 1 +#define PLL1_VSEL 1 // High if 600MHz < Fvco < 864MHz (Fvco = Fin * M / P) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +// PLL2 @ 432MHz +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 5 +#define PLL2_M 180 +#define PLL2_S 1 +#define PLL2_VSEL 1 // High if 600MHz < Fvco < 864MHz (Fvco = Fin * M / P) +#define PLL2_T PLL_FREQ_TARGET(PLL2432/) + +#define LOW_PERF_DIV_N (11) +#define MEDIUM_PERF_DIV_N (5) +#define MEMORY_PERF_DIV_N (2) +// With PLL0 @ 800MHz for B0, SCLK_DIV_VAL needs to be at least 2! +#define HIGH_PERF_DIV_N (2) + +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_SECUREROM + +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 6 +#define PLL0_M 133 +#define PLL0_S 2 +#define PLL0_VSEL 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +#define LOW_PERF_DIV_N (1) +#define MEDIUM_PERF_DIV_N (1) +#define MEMORY_PERF_DIV_N (2) +#define HIGH_PERF_DIV_N (1) + +#endif /* APPLICATION_SECUREROM */ + +#define SCLK_PLL 0 +#define FCLK_DIV_N (1) +#define DCLK_DIV_N (1) +#define ACLK_DIV_N (MEMORY_PERF_DIV_N) +#define HCLK_DIV_N (MEMORY_PERF_DIV_N) +#define PCLK_DIV_N (MEMORY_PERF_DIV_N) + +#define NCLK_DIV_N (1) + +/* current clock speeds */ +static u_int32_t clks[CLKGEN_CLK_COUNT]; +static u_int32_t *plls = &clks[CLKGEN_CLK_PLL0]; + +static u_int32_t perf_level; +static u_int32_t perf_div; + +static u_int32_t get_pll(int pll); + +int clocks_init(void) +{ +#if APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) + +#if SUPPORT_FPGA + clks[CLKGEN_CLK_SCLK] = 10000000; + clks[CLKGEN_CLK_FCLK] = 10000000; + clks[CLKGEN_CLK_DCLK] = 10000000; + clks[CLKGEN_CLK_ACLK] = 10000000; + clks[CLKGEN_CLK_HCLK] = 10000000; + clks[CLKGEN_CLK_PCLK] = 10000000; + clks[CLKGEN_CLK_NCLK] = 10000000; + clks[CLKGEN_CLK_USBPHY] = 12000000; + + perf_div = 1; + perf_level = kPerformanceHigh; + +#else +#error "The calculations of vclk0 and vclk1 need to be scrubbed" + int cnt; + int sclk_pll = ((rCLKCON0 >> 12) & 3) - 1; + int sclk_div_n = ((rCLKCON0 >> 0) & 0xF) + 1; + int fclk_div_n = ((rCLKCON1 >> 29) & 1) ? ((((rCLKCON1 >> 24) & 0x1F) + 1) * 2) : 1; + int dclk_div_n = ((rCLKCON1 >> 23) & 1) ? ((((rCLKCON1 >> 18) & 0x1F) + 1) * 2) : 1; + int hclk_div_n = ((rCLKCON1 >> 17) & 1) ? ((((rCLKCON1 >> 12) & 0x1F) + 1) * 2) : 1; + int pclk_div_n = ((rCLKCON1 >> 11) & 1) ? ((((rCLKCON1 >> 6) & 0x1F) + 1) * 2) : 1; + int aclk_div_n = ((rCLKCON1 >> 5) & 1) ? ((((rCLKCON1 >> 0) & 0x1F) + 1) * 2) : 1; + int vclk0_pll = ((rCLKCON2 >> 28) & 3) - 1; + int vclk0_div_n = ((rCLKCON2 >> 16) & 0xF) + 1; + int vclk1_pll = ((rCLKCON2 >> 12) & 3) - 1; + int vclk1_div_n = (((rCLKCON2 >> 0) & 0xF) + 1) * (((rCLKCON2 >> 4) & 0xF) + 1); + + plls[-1] = OSC_FREQ; + for (cnt = 0; cnt < 3; cnt++) plls[cnt] = get_pll(cnt); + + perf_div = sclk_div_n; + + switch (perf_div) { + default : + case HIGH_PERF_DIV_N : perf_level = kPerformanceHigh; break; + case MEDIUM_PERF_DIV_N : perf_level = kPerformanceMedium; break; + case LOW_PERF_DIV_N : perf_level = kPerformanceLow; break; + } + + clks[CLKGEN_CLK_SCLK] = plls[sclk_pll] / HIGH_PERF_DIV_N; + clks[CLKGEN_CLK_FCLK] = clks[CLKGEN_CLK_SCLK] / fclk_div_n; + clks[CLKGEN_CLK_DCLK] = clks[CLKGEN_CLK_SCLK] / dclk_div_n; + clks[CLKGEN_CLK_ACLK] = clks[CLKGEN_CLK_SCLK] / aclk_div_n; + clks[CLKGEN_CLK_HCLK] = clks[CLKGEN_CLK_SCLK] / hclk_div_n; + clks[CLKGEN_CLK_PCLK] = clks[CLKGEN_CLK_SCLK] / pclk_div_n; + clks[CLKGEN_CLK_VCLK0] = plls[vclk0_pll] / vclk0_div_n; + clks[CLKGEN_CLK_VCLK1] = plls[vclk1_pll] / vclk1_div_n; + + clks[CLKGEN_CLK_NCLK] = OSC_FREQ; + + clks[CLKGEN_CLK_USBPHY] = OSC_FREQ; +#endif + +#endif /* APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) */ + + return 0; +} + +static u_int32_t get_pll(int pll) +{ + volatile u_int32_t *pllpms; + u_int32_t pllcon, pms; + u_int64_t freq; + + pllcon = rPLLCON; + + if (((pllcon >> pll) & 1) == 0) return OSC_FREQ; + + switch (pll) { + case 0: + pllpms = &rPLL0PMS; + break; + case 1: + pllpms = &rPLL1PMS; + break; + case 2: + pllpms = &rPLL2PMS; + break; + case 3: + pllpms = &rPLL3PMS; + break; + default: + return 0; + break; + } + + freq = OSC_FREQ; + pms = *pllpms; + + freq *= (pms >> 8) & 0x3FF; // *M + + freq /= (pms >> 24) & 0x3F; // /P + + freq /= 1 << (pms & 0x07); // /2^S + + return freq; +} + +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t vsel) +{ + volatile u_int32_t *pllpms; + volatile u_int32_t *plllcnt; + + switch (pll) { + case 0: + pllpms = &rPLL0PMS; + plllcnt = &rPLL0LCNT; + break; + case 1: + pllpms = &rPLL1PMS; + plllcnt = &rPLL1LCNT; + break; + case 2: + pllpms = &rPLL2PMS; + plllcnt = &rPLL2LCNT; + break; + case 3: + pllpms = &rPLL3PMS; + plllcnt = &rPLL3LCNT; + break; + default: + return; + } + + *pllpms = (vsel << 30) | (p << 24) | (m << 8) | (s << 0); // set p/m/s values + *plllcnt = 300 * 24; // set lock counter for 300us + rPLLCON |= (1<<(0+pll)); // pll power up +#if !SUPPORT_FPGA + while ((rPLLLOCK & (1 << pll)) == 0); // wait for pll to lock +#endif /* ! SUPPORT_FPGA */ + *pllpms = (vsel << 30) | (p << 24) | (m << 8) | (s << 0); // set p/m/s values again + rPLLCON |= (1<<(16+pll)); // pll select output +} + +int clocks_set_default(void) +{ + uint32_t cnt; + + /* Change all the clocks to something safe */ + clocks_quiesce(); + + /* set up the clock tree to our default setting */ + clks[CLKGEN_CLK_OSC] = OSC_FREQ; + +#ifdef PLL0_T + set_pll(0, PLL0_P, PLL0_M, PLL0_S, PLL0_VSEL); +#endif + +#ifdef PLL1_T + set_pll(1, PLL1_P, PLL1_M, PLL1_S, PLL2_VSEL); +#endif + +#ifdef PLL2_T + set_pll(2, PLL2_P, PLL2_M, PLL2_S, PLL2_VSEL); +#endif + +#ifdef PLL3_T + set_pll(3, PLL3_P, PLL3_M, PLL3_S, PLL3_VSEL); +#endif + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < 4; cnt++) plls[cnt] = get_pll(cnt); + + perf_level = kPerformanceHigh; + perf_div = HIGH_PERF_DIV_N; + + clks[CLKGEN_CLK_SCLK] = plls[SCLK_PLL] / perf_div; + clks[CLKGEN_CLK_FCLK] = clks[CLKGEN_CLK_SCLK] / FCLK_DIV_N; + clks[CLKGEN_CLK_DCLK] = clks[CLKGEN_CLK_SCLK] / DCLK_DIV_N; + clks[CLKGEN_CLK_ACLK] = clks[CLKGEN_CLK_SCLK] / ACLK_DIV_N; + clks[CLKGEN_CLK_HCLK] = clks[CLKGEN_CLK_SCLK] / HCLK_DIV_N; + clks[CLKGEN_CLK_PCLK] = clks[CLKGEN_CLK_SCLK] / PCLK_DIV_N; + clks[CLKGEN_CLK_NCLK] = clks[CLKGEN_CLK_OSC] / NCLK_DIV_N; + clks[CLKGEN_CLK_USBPHY] = clks[CLKGEN_CLK_OSC]; + + // switch the useful clocks back to their plls + rCLKCON1 = + (PRESCALE_EN(FCLK_DIV_N)<<29)|(CLK_DIV_N(FCLK_DIV_N)<<24) | // FCLK + (PRESCALE_EN(DCLK_DIV_N)<<23)|(CLK_DIV_N(DCLK_DIV_N)<<18) | // DCLK + (PRESCALE_EN(HCLK_DIV_N)<<17)|(CLK_DIV_N(HCLK_DIV_N)<<12) | // HCLK + (PRESCALE_EN(PCLK_DIV_N)<<11)|(CLK_DIV_N(PCLK_DIV_N)<< 6) | // PCLK + (PRESCALE_EN(ACLK_DIV_N)<< 5)|(CLK_DIV_N(ACLK_DIV_N)<< 0); // ACLK + // must set divider before switching to PLL because of delay in divider taking effect + // Race condition in CLKCON register setting causes unpredictable behavior + rCLKCON0 = ((perf_div-1)<<0); + rCLKCON0 |= ((SCLK_PLL+1)<<12); + rCLKCON2 = (0<<15)|(1<<31); // CLK_OUT0 enable, CLK_OUT1 disable + rCLKCON3 = (1<<31)|(2<<28)|(7<<16) // VCLK_DAC source PLL2, div 7+1, disable + | (1<<15)|(3<<12)|(0<<4)|(0<<0); // RGBOUT_CLK source PLL3, div 1, disable + rCLKCON4 = (1<<31)|(0<<28)|(0<<16) // MCLK1 source OSC, div 1, disable + |(1<<15)|(3<<12)|(0<<4)|(0<<0); // MCLK0 source PLL3, div 1, disable + rCLKCON5 = (1<<31)|(0<<28)|(0<<16) // MCLK3 source OSC, div 1, disable + |(1<<15)|(0<<12)|(0<<0); // MCLK2 source OSC, div 1, disable + + rCLKCON6 = (0<<28)|((NCLK_DIV_N-1)<<16) // NCLK source OSC, enable + |(1<<15)|(2<<12); // MFC_CLK source PLL1, div 0+1, disable + + rCLKCON7 = (0x1F<<27)|(1<<24)|(3<<16) // VMHCLKx source PLL0, div 3+1, disable + |(1<<15)|(1<<12)|(2<<0); // SCALER source PLL0, div 2+1, disable + +#if SUPPORT_FPGA + clks[CLKGEN_CLK_SCLK] = 10000000; + clks[CLKGEN_CLK_FCLK] = 10000000; + clks[CLKGEN_CLK_DCLK] = 10000000; + clks[CLKGEN_CLK_ACLK] = 10000000; + clks[CLKGEN_CLK_HCLK] = 10000000; + clks[CLKGEN_CLK_PCLK] = 10000000; + clks[CLKGEN_CLK_NCLK] = 10000000; + clks[CLKGEN_CLK_USBPHY] = 12000000; +#endif + + return 0; +} + +void clocks_quiesce(void) +{ + // Turn off non-critical device clocks + rCGCON0 = 0x00001CBF; // HCLK to VROM + rCGCON1 = 0x3FC5EFFF; // PCLKs to DREX, Timer64, Cortex-A5 Debug and Sys, AXI, and GPIO + rCGCON2 = 0x0000001F; + rCGCON3 = 0x00000000; // ACLKs to AXI, XMC, and SRAM + rCGCON4 = 0x003DFEFF; // NCLK to DREX and Timer64 on + + // Set OSC to select the 12/24MHz clock + //rPLLCON &= ~(1 << 8); // FIXME + + // Set all of the clocks to use OSC bypass. + // Disable the clocks that will not be used. + rCLKCON0 &= ~(0x3<<12); // Use OSC bypass for SCLK ahead of turning off divider + rCLKCON0 = (1<<30); // MCLK disable, SCLK enable, use OSC bypass, disable prescalar + rCLKCON1 = 0; // FCLK/HCLK/PCLK/ACLK enable, use OSC bypass, disable prescalar + rCLKCON2 = (1<<31)|(1<<15); // CLK_OUT1/CLK_OUT0 disable + rCLKCON3 = (1<<31)|(1<<15); // VCLK_DAC/RGBOUT_VCLK disable + rCLKCON4 = (1<<31)|(1<<15); // MCLK1/MCLK0 disable + rCLKCON5 = (1<<31)|(1<<15); // MCLK3/MCLK2 disable + rCLKCON6 = (1<<15); // NCLK enable, MFC_CLK disable + rCLKCON7 = (0x1F<<27)|(1<<15); // VMHCLKx/SCALER disable + + // Bypass and shut down all PLLs + rPLLCON &= ~0xF0000; + rPLLCON &= ~0x0000F; +} + +u_int32_t clocks_get_performance_divider(void) +{ + return perf_div; +} + +u_int32_t clocks_set_performance(u_int32_t performance_level) +{ + u_int32_t old_perf_level = perf_level; + + switch (performance_level) { + default : performance_level = kPerformanceHigh; + case kPerformanceHigh: perf_div = HIGH_PERF_DIV_N; break; + case kPerformanceMedium: perf_div = MEDIUM_PERF_DIV_N; break; + case kPerformanceLow: perf_div = LOW_PERF_DIV_N; break; + + case kPerformanceMemory : + if (old_perf_level == kPerformanceHigh) goto done; + + perf_div = MEMORY_PERF_DIV_N; + break; + } + + perf_level = performance_level; + + if (old_perf_level == kPerformanceMemory) { + rCLKCON1 = + (PRESCALE_EN(HCLK_DIV_N)<<22)|(CLK_DIV_N(HCLK_DIV_N)<<17) | // HCLK + (PRESCALE_EN(PCLK_DIV_N)<<14)|(CLK_DIV_N(PCLK_DIV_N)<< 9) | // PCLK + (PRESCALE_EN(ACLK_DIV_N)<< 6)|(CLK_DIV_N(ACLK_DIV_N)<< 1); // ACLK + } + + rCLKCON0 = (rCLKCON0 & ~0xF) | ((perf_div - 1) & 0xF); + + if (perf_level == kPerformanceMemory) { + rCLKCON1 = + (PRESCALE_EN(1)<<22)|(CLK_DIV_N(1)<<17) | // HCLK + (PRESCALE_EN(1)<<14)|(CLK_DIV_N(1)<< 9) | // PCLK + (PRESCALE_EN(1)<< 6)|(CLK_DIV_N(1)<< 1); // ACLK + } +done: + return old_perf_level; +} + +u_int32_t clock_get_frequency(int clock) +{ + switch (clock) { + case CLK_CPU: + case CLK_FCLK: + return clks[CLKGEN_CLK_FCLK]; + case CLK_DCLK: + case CLK_MEM: + return clks[CLKGEN_CLK_DCLK]; + case CLK_ACLK: + return clks[CLKGEN_CLK_ACLK]; + case CLK_HCLK: + case CLK_BUS: + return clks[CLKGEN_CLK_HCLK]; + case CLK_PERIPH: + case CLK_PCLK: + return clks[CLKGEN_CLK_PCLK]; + case CLK_NCLK: + case CLK_FIXED: + return clks[CLKGEN_CLK_NCLK]; + case CLK_TIMEBASE: +#if SUPPORT_FPGA + // Rig clock frequency data for G1 FPGA + return clks[CLKGEN_CLK_NCLK] / 2; +#else + return clks[CLKGEN_CLK_NCLK]; +#endif + case CLK_USBPHYCLK: + return clks[CLKGEN_CLK_USBPHY]; + case CLK_MCLK: + default: + return 0; + } +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + /* reset ourselves */ + wdt_chip_reset(); + + while (1); +} + + +void platform_system_reset(bool panic) +{ + dprintf(DEBUG_INFO, "no platform system reset, using normal reset\n"); + platform_reset(panic); +} + +struct clock_gate_entry { + u_int32_t gccon0_mask; + u_int32_t gccon1_mask; + u_int32_t gccon2_mask; + u_int32_t gccon3_mask; + u_int32_t gccon4_mask; +}; + +static const struct clock_gate_entry clock_gate_map[] = +{ + [CLK_AES] = { 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_CHIPID] = { 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_DMAC0] = { 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_DMAC1] = { 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_GPIO] = { 0x00000000, 0x00001000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_IIC0] = { 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00001000 }, + [CLK_IIC1] = { 0x00000000, 0x00000020, 0x00000000, 0x00000000, 0x00002000 }, + [CLK_IIC2] = { 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00004000 }, + [CLK_PKE] = { 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_SHA1] = { 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_SPI0] = { 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00008000 }, + [CLK_SPI1] = { 0x00000000, 0x00000008, 0x00000000, 0x00000000, 0x00010000 }, + [CLK_TIMER] = { 0x00000000, 0x7FC00000, 0x00000000, 0x00000000, 0x000001FF }, + [CLK_UART0] = { 0x00000000, 0x00002000, 0x00000000, 0x00000000, 0x00000200 }, + [CLK_UART1] = { 0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00000400 }, + [CLK_UART2] = { 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000800 }, + [CLK_USBOTG0] = { 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_USBOTG1] = { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_USBPHY] = { 0x00000020, 0x00000800, 0x00000000, 0x00000000, 0x00000000 }, + [CLK_ROSC] = { 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000 }, +}; +#define CLOCK_GATE_MAP_COUNT (sizeof(clock_gate_map) / sizeof(struct clock_gate_entry)) + +void clock_gate(int device, bool enable) +{ + const struct clock_gate_entry *entry = 0; + + if (device > (int)CLOCK_GATE_MAP_COUNT) + panic("Invalid clock gate"); + + entry = &clock_gate_map[device]; + + if (enable) { + rCGCON0 &= ~entry->gccon0_mask; + rCGCON1 &= ~entry->gccon1_mask; + rCGCON2 &= ~entry->gccon2_mask; + rCGCON3 &= ~entry->gccon3_mask; + rCGCON4 &= ~entry->gccon4_mask; + } else { + rCGCON0 |= entry->gccon0_mask; + rCGCON1 |= entry->gccon1_mask; + rCGCON2 |= entry->gccon2_mask; + rCGCON3 |= entry->gccon3_mask; + rCGCON4 |= entry->gccon4_mask; + } +} + diff --git a/platform/s5l8747x/clocks/rules.mk b/platform/s5l8747x/clocks/rules.mk new file mode 100644 index 0000000..a319a5e --- /dev/null +++ b/platform/s5l8747x/clocks/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 + +ALL_OBJS += $(LOCAL_DIR)/clocks.o diff --git a/platform/s5l8747x/include/platform/gpiodef.h b/platform/s5l8747x/include/platform/gpiodef.h new file mode 100644 index 0000000..8906712 --- /dev/null +++ b/platform/s5l8747x/include/platform/gpiodef.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* S5L8747X specific gpio -> pin mappings */ + +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_IIC0_SCL GPIO( 1, 1) +#define GPIO_IIC0_SDA GPIO( 1, 2) +#define GPIO_IIC1_SCL GPIO( 3, 6) +#define GPIO_IIC1_SDA GPIO( 3, 7) + +#define GPIO_BOARD_ID0 GPIO( 2, 3) +#define GPIO_BOARD_ID1 GPIO( 2, 4) +#define GPIO_BOARD_ID2 GPIO( 2, 5) +#define GPIO_BOARD_ID3 GPIO( 2, 6) + +#define GPIO_BOOT_CONFIG0 GPIO( 2, 1) +#define GPIO_BOOT_CONFIG1 GPIO( 2, 2) + +#define GPIO_FORCE_DFU GPIO(3, 4) +#define GPIO_DFU_STATUS GPIO(3, 5) + +#define GPIO_CLK0_OUT GPIO( 3, 0) + +#define SPI_NOR0 (0) +#define SPI_NOR1 (1) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#define GPIO_SPI1_CS GPIO(GPIO_PAD_SPI, 1) +#else +#define GPIO_SPI0_CS GPIO( 1, 3) +#define GPIO_SPI3_CS GPIO( 4, 4) +#endif + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s5l8747x/include/platform/image_devices.h b/platform/s5l8747x/include/platform/image_devices.h new file mode 100644 index 0000000..58614fc --- /dev/null +++ b/platform/s5l8747x/include/platform/image_devices.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { + { "nor0", 0x00000 } +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { + { "nor0", 0x00000 } +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s5l8747x/include/platform/memmap.h b/platform/s5l8747x/include/platform/memmap.h new file mode 100644 index 0000000..b44139c --- /dev/null +++ b/platform/s5l8747x/include/platform/memmap.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +/* S5L8747X hardware memory map */ +#define SDRAM_BASE (0x08000000ULL) +#define SDRAM_BANK_LEN (0x10000000ULL) +#define SDRAM_BANK_COUNT 1 +#define SDRAM_END (SDRAM_BASE + (SDRAM_BANK_LEN * SDRAM_BANK_COUNT)) +#define VROM_BASE (0x20000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00020000ULL) +#define SRAM_BASE (0x22000000ULL) +#define SRAM_BANK_LEN (0x00400000ULL) +#define SRAM_LEN (0x00020000ULL) + +/* Sleep token is stored at first physical page in kernel memory */ +#define SLEEP_TOKEN_BUFFER_BASE (SDRAM_BASE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00004000ULL) +#define PANIC_BASE (SDRAM_END - PANIC_SIZE) + +/* Purple graphics memory, must be 1 MB aligned */ +#define PURPLE_GFX_MEMORY_LEN (0x09600000 - PANIC_SIZE) + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x00100000 - PANIC_SIZE) +#define IBOOT_BASE (PANIC_BASE - IBOOT_SIZE) +#define PROTECTED_REGION_SIZE IBOOT_SIZE + +/* where to stick the mmu tt, default heap and insecure memory*/ +#if APPLICATION_SECUREROM +#define MMU_TT_SIZE (0x1000ULL) +#define MMU_TT_BASE (SRAM_BASE + SRAM_LEN - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN) + +#define STACK_SIZE (0x3000ULL) +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#ifndef __ASSEMBLY__ + +#define INSECURE_MEMORY_BASE (SRAM_BASE) +#define INSECURE_MEMORY_SIZE ((uintptr_t)__segment_start(__DATA) - INSECURE_MEMORY_BASE) + +#endif /* ! __ASSEMBLY__ */ + +#endif /* APPLICATION_SECUREROM */ + +/* iBoot SDRAM map +0x08000000-0x0B000000 - Load area (48 MB) +0x0B000000-0x0DF00000 - Kernel (47 MB) +0x0DF00000-0x0E000000 - Device tree (1 MB) +0x0E000000-0x11000000 - Ramdisk (48 MB) +0x11000000-0x17F00000 - Heap (111 MB) +0x17F00000-0x17FFC000 - iBoot (unused) (1008 kB) +0x17FFC000-0x18000000 - Panic (16kB) +*/ + +#if APPLICATION_IBOOT +#define MMU_TT_SIZE (0x1000ULL) +#define MMU_TT_BASE (TEXT_BASE + TEXT_FOOTPRINT - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN) +#define MMU_NONCACHE1_SIZE (0x10000000ULL) +#define MMU_NONCACHE1_PBASE (0x08000000ULL) +#define MMU_NONCACHE1_VBASE (0x28000000ULL) + +#if WITH_DFU_MODE +#define STACK_SIZE (0x3000ULL) + +#define INSECURE_MEMORY_SIZE (0x00800000ULL) +#define INSECURE_MEMORY_BASE (SDRAM_BASE + ((u_int32_t)platform_get_memory_size()) - INSECURE_MEMORY_SIZE) + +#else /* !WITH_DFU_MODE */ +#define STACK_SIZE (0x0800ULL) + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_KERNEL_ADDRESS - SDRAM_BASE) +#define DEFAULT_LOAD_ADDRESS (INSECURE_MEMORY_BASE) +#define DEFAULT_LOAD_SIZE (0x03000000ULL) +#define DEFAULT_KERNEL_ADDRESS (DEFAULT_LOAD_ADDRESS + DEFAULT_LOAD_SIZE) +#define DEFAULT_KERNEL_SIZE (0x02F00000ULL) +#define DEFAULT_DEVICETREE_ADDRESS (DEFAULT_KERNEL_ADDRESS + DEFAULT_KERNEL_SIZE) +#define DEFAULT_DEVICETREE_SIZE (0x00100000ULL) +#define DEFAULT_RAMDISK_ADDRESS (DEFAULT_DEVICETREE_ADDRESS + DEFAULT_DEVICETREE_SIZE) +#define DEFAULT_RAMDISK_SIZE (0x03000000ULL) +#define DEFAULT_FREE_ADDRESS (DEFAULT_RAMDISK_ADDRESS + DEFAULT_RAMDISK_SIZE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define SECURE_MEMORY_SIZE (IBOOT_BASE - SECURE_MEMORY_BASE) + +#define HEAP_EXT_BASE (DEFAULT_FREE_ADDRESS) +#define HEAP_EXT_SIZE (IBOOT_BASE - HEAP_EXT_BASE) +#endif /* !WITH_DFU_MODE */ + +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +/* Reserved area for boot trace */ +/* WARNING: We're really tight on SRAM on B137. So, the boot trace area overlaps + the initial stack area. We typically only use about 500 bytes of the initial stack, + and once we jump into main_task, we never use the initial stack again. So, as long + as we don't do too much tracing before jumping into main_task, we'll be OK */ +#define PROFILE_BUF_SIZE (0x0800ULL) +#define PROFILE_BUF_BASE (STACK_BASE) + +#define HEAP_END (STACK_BASE) + +#endif /* APPLICATION_IBOOT */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s5l8747x/include/platform/pinconfig.h b/platform/s5l8747x/include/platform/pinconfig.h new file mode 100644 index 0000000..02f3ae1 --- /dev/null +++ b/platform/s5l8747x/include/platform/pinconfig.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default S5L8747X SoC Pin Configuration */ + +static const struct gpio_default_config gpio_default_config[GPIO_GROUP_COUNT] = { +/* P0 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // I2S0_MCK -> + PCON_DISABLE, NO_PUPDN, // I2S0_LRCK -> + PCON_DISABLE, NO_PUPDN, // I2S0_BCK -> + PCON_DISABLE, NO_PUPDN, // I2S0_DOUT -> + PCON_DISABLE, NO_PUPDN, // I2S0_DIN -> + PCON_DISABLE, NO_PUPDN, // UART0_RXD -> + PCON_DISABLE, NO_PUPDN, // UART0_TXD -> + PCON_DISABLE, NO_PUPDN // UART0_NRTS -> + ), +/* P1 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // UART0_NCTS -> + PCON_DISABLE, NO_PUPDN, // I2C0_SCL -> + PCON_DISABLE, NO_PUPDN, // I2C0_SDA -> + PCON_DISABLE, PUP, // SPI0_CEN -> SPI0_CS + PCON_DISABLE, PDN, // SPI0_CLK -> SPI0_CLK + PCON_DISABLE, NO_PUPDN, // SPI0_MOSI -> SPI0_MOSI + PCON_DISABLE, NO_PUPDN, // SPI0_MISO -> SPI0_MISO + PCON_DISABLE, NO_PUPDN // - -> + ), +/* P2 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // GPIO0 -> + PCON_DISABLE, NO_PUPDN, // GPIO1 -> BOOT_CONFIG[0] + PCON_DISABLE, NO_PUPDN, // GPIO2 -> BOOT_CONFIG[1] + PCON_DISABLE, NO_PUPDN, // GPIO3 -> BOARD_ID[1] + PCON_DISABLE, NO_PUPDN, // GPIO4 -> BOARD_ID[2] + PCON_DISABLE, NO_PUPDN, // GPIO5 -> BOARD_ID[3] + PCON_DISABLE, NO_PUPDN, // GPIO6 -> BOARD_ID[4] + PCON_DISABLE, NO_PUPDN // GPIO7 -> + ), +/* P3 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // CLK0_OUT -> + PCON_DISABLE, NO_PUPDN, // CLK1_OUT -> + PCON_DISABLE, NO_PUPDN, // HDMI_HPD -> + PCON_DISABLE, NO_PUPDN, // HDMI_CEC -> + PCON_IN, PDN, // FORCE_DFU -> FORCE_DFU + PCON_DISABLE, PDN, // DFU_STATUS -> DFU_STATUS + PCON_DISABLE, NO_PUPDN, // I2C1_SCL -> + PCON_DISABLE, NO_PUPDN // I2C1_SDA -> + ), +/* P4 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // UART2_RXD -> + PCON_DISABLE, NO_PUPDN, // UART2_TXD -> + PCON_DISABLE, NO_PUPDN, // UART2_NRTS -> + PCON_DISABLE, NO_PUPDN, // UART2_NCTS -> + PCON_DISABLE, NO_PUPDN, // SPI1_CEN -> + PCON_DISABLE, NO_PUPDN, // SPI1_CLK -> + PCON_DISABLE, NO_PUPDN, // SPI1_MOSI -> + PCON_DISABLE, NO_PUPDN // SPI1_MISO -> + ), +/* P5 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // UART1_RXD -> + PCON_DISABLE, NO_PUPDN, // UART1_TXD -> + PCON_DISABLE, NO_PUPDN, // UART1_NRTS -> + PCON_DISABLE, NO_PUPDN, // UART1_NCTS -> + PCON_DISABLE, NO_PUPDN, // VGA_VDEN -> + PCON_DISABLE, NO_PUPDN, // VGA_HSYNC -> + PCON_DISABLE, NO_PUPDN, // VGA_VSYNC -> + PCON_DISABLE, NO_PUPDN // - -> + ), +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s5l8747x/include/platform/soc/chipid.h b/platform/s5l8747x/include/platform/soc/chipid.h new file mode 100644 index 0000000..d8ed6a7 --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/chipid.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include + +#define rEFUSE_READ_DONE (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCHIPIDL (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCHIPIDH (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rDIEIDL (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x0C)) +#define rDIEIDH (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x10)) + +extern bool chipid_get_ecid_image_personalization_required(void); + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s5l8747x/include/platform/soc/clocks.h b/platform/s5l8747x/include/platform/soc/clocks.h new file mode 100644 index 0000000..65377a1 --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/clocks.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CLOCKS_H +#define __PLATFORM_SOC_CLOCKS_H + +#include + +#define rCLKCON0 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x00)) +#define rCLKCON1 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x10)) +#define rCLKCON2 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x20)) +#define rCLKCON3 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x30)) +#define rCLKCON4 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x40)) +#define rCLKCON5 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x50)) +#define rCLKCON6 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x60)) +#define rCLKCON7 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x70)) +#define rPLL0PMS (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x100)) +#define rPLL1PMS (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x104)) +#define rPLL2PMS (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x108)) +#define rPLL3PMS (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x10C)) +#define rPLL0LCNT (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x110)) +#define rPLL1LCNT (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x114)) +#define rPLL2LCNT (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x118)) +#define rPLL3LCNT (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x11C)) +#define rPLLLOCKINT (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x150)) +#define rPLLLOCK (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x154)) +#define rPLLCON (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x158)) +#define rCGCON0 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x200)) +#define rCGCON1 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x204)) +#define rCGCON2 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x208)) +#define rCGCON3 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x20C)) +#define rCGCON4 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x210)) +#define rSWRCON (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x250)) +#define rRSTSR (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x254)) +#define rKEEPMAP (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x300)) +#define rVERSION (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0xA00)) +#define rMONITOR01 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x400)) +#define rMONITOR2 (*(volatile u_int32_t *)(CLKCON_BASE_ADDR + 0x404)) + +enum { + CLKGEN_CLK_OSC = 0, + CLKGEN_CLK_PLL0, + CLKGEN_CLK_PLL1, + CLKGEN_CLK_PLL2, + CLKGEN_CLK_PLL3, + CLKGEN_CLK_SCLK, + CLKGEN_CLK_FCLK, + CLKGEN_CLK_DCLK, + CLKGEN_CLK_ACLK, + CLKGEN_CLK_HCLK, + CLKGEN_CLK_PCLK, + CLKGEN_CLK_NCLK, + CLKGEN_CLK_USBPHY, + CLKGEN_CLK_VCLK0, + CLKGEN_CLK_VCLK1, + CLKGEN_CLK_COUNT +}; + + +#endif /* ! __PLATFORM_SOC_CLOCKS_H */ diff --git a/platform/s5l8747x/include/platform/soc/hwclocks.h b/platform/s5l8747x/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..d92f21d --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/hwclocks.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (27000000UL) +#else +#define OSC_FREQ (24000000UL) +#endif + +#define CLK_FCLK (HWCLOCK_BASE+0) +#define CLK_ACLK (HWCLOCK_BASE+1) +#define CLK_HCLK (HWCLOCK_BASE+2) +#define CLK_PCLK (HWCLOCK_BASE+3) +#define CLK_VCLK0 (HWCLOCK_BASE+4) +#define CLK_VCLK1 (HWCLOCK_BASE+5) +#define CLK_MCLK (HWCLOCK_BASE+6) +#define CLK_NCLK (HWCLOCK_BASE+7) +#define CLK_USBPHYCLK (HWCLOCK_BASE+8) +#define CLK_DCLK (HWCLOCK_BASE+9) + +/* S5L8747X clock gate devices */ +enum { + CLK_AES, + CLK_CHIPID, + CLK_DMAC0, + CLK_DMAC1, + CLK_GPIO, + CLK_IIC0, + CLK_IIC1, + CLK_IIC2, + CLK_PKE, + CLK_SHA1, + CLK_SPI0, + CLK_SPI1, + CLK_TIMER, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_USBOTG0, + CLK_USBOTG1, + CLK_USBPHY, + CLK_ROSC, +}; + +// USB PHY driver expects CLK_USBOTG, so give them what they want +#define CLK_USBOTG CLK_USBOTG1 + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s5l8747x/include/platform/soc/hwisr.h b/platform/s5l8747x/include/platform/soc/hwisr.h new file mode 100644 index 0000000..06deb45 --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/hwisr.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define EINT_G6 0 // External Interrupt 6 +#define EINT_G5 1 // External Interrupt 5 +#define EINT_G4 2 // External Interrupt 4 +#define EINT_G3 3 // External Interrupt 3 +#define INT_SWI 4 // SW Interrupt +#define INT_CMMSTX 5 // COMMS TX Interrupt +#define INT_CMMSRX 6 // COMMS RX Interrupt +#define INT_TIMERFIQ 7 // TIMER FIQ Interrupt +#define INT_TIMERIRQ 8 // TIMER IRQ Interrupt +#define INT_SPI0 9 // SPI0 Interrupt +#define INT_SPI1 10 // SPI1 Interrupt +#define INT_RESERVED11 11 // Reserved +#define INT_VP 12 // VP Interrupt +#define INT_RGBOUT 13 // RGBOUT Interrupt +#define INT_RESERVED14 14 // Reserved +#define INT_RESERVED15 15 // Reserved +#define INT_DMA0 16 // DMA0 Interrupt +#define INT_DMA1 17 // DMA1 Interrupt +#define INT_USB_OTG0 18 // USB OTG0 Interrupt +#define INT_USB_OTG1 19 // USB OTG1 Interrupt +#define INT_RESERVED20 20 // Reserved +#define INT_IIC0 21 // IIC0 Interrupt +#define INT_IIC1 22 // IIC1 Interrupt +#define INT_IIC2 23 // IIC2 Interrupt +#define INT_UART0 24 // UART0 Interrupt +#define INT_UART1 25 // UART1 Interrupt +#define INT_UART2 26 // UART2 Interrupt +#define INT_RESERVED27 27 // Reserved +#define INT_RESERVED28 28 // Reserved +#define INT_RESERVED29 29 // Reserved +#define INT_TVOUT 30 // TVOUT Interrupt +#define EINT_G2 31 // External Interrupt 2 +#define EINT_G1 32 // External Interrupt 1 +#define EINT_G0 33 // External Interrupt 0 +#define INT_RESERED34 34 // Reserved +#define INT_MFC_DEC 35 // MFC DEC Interrupt +#define INT_PKE 36 // PKE Interrupt +#define INT_SCALER 37 // SCALER Interrupt +#define INT_MIXER 38 // MIXER Interrupt +#define INT_AES 39 // AES Interrupt +#define INT_SHA1 40 // SHA1 Interrupt +#define INT_PRNG 41 // PRNG Interrupt +#define INT_SHA2 42 // SHA2 Interrupt +#define INT_RESERVED43 43 // Reserved +#define INT_ADC 44 // ADC Interrupt +#define INT_RESERVED45 45 // Reserved +#define INT_I2S0 46 // I2S Interrupt +#define INT_RESERVED47 47 // Reserved +#define INT_RESERVED48 48 // Reserved +#define INT_RESERVED49 49 // Reserved +#define INT_SUSPEND 50 // SUSPEND Interrupt +#define INT_WDT 51 // WDT Interrupt +#define INT_SPDIF 52 // SPDIF Interrupt +#define INT_RESERVED53 53 // Reserved +#define INT_RESERVED54 54 // Reserved +#define INT_RESERVED55 55 // Reserved +#define INT_RESERVED56 56 // Reserved +#define INT_RESERVED57 57 // Reserved +#define INT_RESERVED58 58 // Reserved +#define INT_HDMI_CEC 59 // HDMI CEC Interrupt +#define INT_HDMI 60 // HDMI Interrupt +#define INT_CLKRSTGEN 61 // CLKRSTGEN Interrupt +#define INT_PMU 62 // PMU Interrupt +#define INT_ARF 63 // ARF Interrupt + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s5l8747x/include/platform/soc/hwregbase.h b/platform/s5l8747x/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..3e47a86 --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/hwregbase.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011 - 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#ifndef HWREG_REMAP +# define HWREG_REMAP(_x) _x +#endif + +#define AIC_VERSION 0 +#define AIC_INT_COUNT (192) +#define PMGR_WDG_VERSION 0 + +/* S5L8747X Reg Base Defs */ + +#define SHA1_BASE_ADDR HWREG_REMAP(0x38000000) + +#define AHB_BASE_ADDR HWREG_REMAP(0x38100000) + +#define DMAC0_BASE_ADDR HWREG_REMAP(0x38200000) +#define DMAC1_BASE_ADDR HWREG_REMAP(0x38700000) + +#define SHA2_BASE_ADDR HWREG_REMAP(0x38300000) + +#define USBOTG0_BASE_ADDR HWREG_REMAP(0x38400000) +#define USB_OHCI_BASE_ADDR HWREG_REMAP(0x38500000) +#define USB_EHCI_BASE_ADDR HWREG_REMAP(0x39800000) +#define USBOTG1_BASE_ADDR HWREG_REMAP(0x39900000) +#define USBOTG_BASE_ADDR (USBOTG1_BASE_ADDR) +#define USBPHY_BASE_ADDR HWREG_REMAP(0x3C400000) +#define USBPHY_VERSION (1) + +#define RGBOUT_BASE_ADDR HWREG_REMAP(0x38900000) + +#define AES_BASE_ADDR HWREG_REMAP(0x38C00000) +#define AES_VERSION (1) + +#define VIC_BASE_ADDR HWREG_REMAP(0x38E00000) +#define VIC_STRIDE (0x00001000) +#define VICS_COUNT (2) + +#define EDGEIC_BASE_ADDR HWREG_REMAP(0x38E02000) + +#define SDO_BASE_ADDR HWREG_REMAP(0x39300000) + +#define AAM_BASE_ADDR HWREG_REMAP(0x39700000) +#define EINT_NUM_GROUPS (7) +#define EINTS_PER_GROUP (32) + +#define SPI0_BASE_ADDR HWREG_REMAP(0x3C300000) +#define SPI1_BASE_ADDR HWREG_REMAP(0x3CE00000) +#define SPI_VERSION (1) +#define SPIS_COUNT (2) + +#define CLKCON_BASE_ADDR HWREG_REMAP(0x3C500000) + +#define IIC0_BASE_ADDR HWREG_REMAP(0x3C600000) +#define IIC1_BASE_ADDR HWREG_REMAP(0x3E500000) +#define IIC2_BASE_ADDR HWREG_REMAP(0x3E400000) +#define IICS_COUNT (3) + +#define TIMER_BASE_ADDR HWREG_REMAP(0x3C700000) +#define TIMER_VERSION (1) + +#define WDT_BASE_ADDR HWREG_REMAP(0x3C800000) + +#define UART0_BASE_ADDR HWREG_REMAP(0x3CC00000) +#define UART1_BASE_ADDR HWREG_REMAP(0x3DB00000) +#define UART2_BASE_ADDR HWREG_REMAP(0x3DC00000) +#define UART_VERSION (1) +#define UARTS_COUNT (3) + +#define GPIO_BASE_ADDR HWREG_REMAP(0x3CF00000) +#define GPIO_FSEL_OFFSET (0x200) +// There are 9 groups listed in the user manual, but the last 3 +// aren't actually implemented. +#define GPIO_GROUP_COUNT (6) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define PKE_BASE_ADDR HWREG_REMAP(0x3D000000) +#define PKE_SW_RESET_AVAILABLE (1) + +#define CHIPID_BASE_ADDR HWREG_REMAP(0x3D100000) + +#define AXI_SPINE_BASE_ADDR HWREG_REMAP(0x3D500000) +#define DREX_BASE_ADDR HWREG_REMAP(0x3D700000) + +#define BUS_BASE_ADDR HWREG_REMAP(0x3E000000) + +#define SRAM_MIU_BASE_ADDR HWREG_REMAP(0x3E100000) + +#define HDMI_LINK_BASE_ADDR HWREG_REMAP(0x3E200000) +#define DITHER_VERSION (1) + +#define HDMI_CEC_BASE_ADDR HWREG_REMAP(0x3E300000) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s5l8747x/include/platform/soc/miu.h b/platform/s5l8747x/include/platform/soc/miu.h new file mode 100644 index 0000000..a6e9bbe --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/miu.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include + +#define rAHB_MST0 (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x004)) +#define rAHB2AXIID_CON (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x040)) +#define rAHB2AXIID0 (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x044)) +#define rAHB2AXIID1 (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x048)) +#define rAHB2AXIID2 (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x04C)) +#define rAHB2AXIID3 (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x050)) +#define rAHB2AXIID4 (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x054)) +#define rLEVEL1SEL (*(volatile u_int32_t *)(AHB_BASE_ADDR + 0x090)) + +#define rPWRDWN_BUS (*(volatile u_int32_t *)(BUS_BASE_ADDR + 0x008)) +#define rREMAP (*(volatile u_int32_t *)(BUS_BASE_ADDR + 0x00C)) +#define rDDR1 (*(volatile u_int32_t *)(BUS_BASE_ADDR + 0x010)) +#define rMFC_ARF_CON (*(volatile u_int32_t *)(BUS_BASE_ADDR + 0x3000)) +#define rMFC_ARF_BASE_ADDR (*(volatile u_int32_t *)(BUS_BASE_ADDR + 0x3004)) +#define rMFC_ARF_ADDR_MASK (*(volatile u_int32_t *)(BUS_BASE_ADDR + 0x3008)) + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s5l8747x/include/platform/soc/power.h b/platform/s5l8747x/include/platform/soc/power.h new file mode 100644 index 0000000..3919970 --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/power.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_POWER_H +#define __PLATFORM_SOC_POWER_H + +#include + +#define rPWRCONF (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x000)) +#define rPWRCMD (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x004)) +#define rOSCCNT (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x038)) +#define rPLLCNT (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x03C)) +#define rSTATESAVE0 (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x044)) +#define rSTATESAVE1 (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x048)) +#define rSTATESAVE2 (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x04C)) +#define rSTATESAVE3 (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x050)) +#define rTMCMD (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x06C)) +#define rTMDATA (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x070)) +#define rTMPRE (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x074)) +#define rTMCNT (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x078)) +#define rTMALARM (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x07C)) +#define rSECCONF (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x104)) +#define rVERSION (*(volatile u_int32_t *)(AAM_BASE_ADDR + 0x108)) + +#endif /* ! __PLATFORM_SOC_POWER_H */ diff --git a/platform/s5l8747x/include/platform/soc/sdo.h b/platform/s5l8747x/include/platform/soc/sdo.h new file mode 100644 index 0000000..6b0783f --- /dev/null +++ b/platform/s5l8747x/include/platform/soc/sdo.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_SDO_H +#define __PLATFORM_SOC_SDO_H + +#include + +#define rDAC0_SCALE (*(volatile u_int32_t *)(SDO_BASE_ADDR + 0x1C)) +#define rDAC1_SCALE (*(volatile u_int32_t *)(SDO_BASE_ADDR + 0x20)) +#define rDAC2_SCALE (*(volatile u_int32_t *)(SDO_BASE_ADDR + 0x24)) + +extern int sdo_init(void); + +#endif /* ! __PLATFORM_SOC_SDO_H */ diff --git a/platform/s5l8747x/include/platform/trampoline.h b/platform/s5l8747x/include/platform/trampoline.h new file mode 100644 index 0000000..3bee5c5 --- /dev/null +++ b/platform/s5l8747x/include/platform/trampoline.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include +#include + +#define SECURITY_REG (AAM_BASE_ADDR + 0x104) +#define ROM_READ_DISABLE (1 << 2) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s5l8747x/include/platform/usbconfig.h b/platform/s5l8747x/include/platform/usbconfig.h new file mode 100644 index 0000000..bbf06ab --- /dev/null +++ b/platform/s5l8747x/include/platform/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#define USBPHY_CLK_TYPE (2) /* Use CLKCORE */ + +#define USBPHY_UOTGTUNE1 (0x347) +#define USBPHY_UOTGTUNE2 (0xE3F) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_SINGLE) + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s5l8747x/init.c b/platform/s5l8747x/init.c new file mode 100644 index 0000000..8557e18 --- /dev/null +++ b/platform/s5l8747x/init.c @@ -0,0 +1,855 @@ +/* + * Copyright (C) 2007-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void platform_init_boot_strap(void); + +static uint8_t boot_debug; + + +int platform_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + /* Verify that SecureROM has been disabled */ + if (((*(volatile u_int32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0) { + panic("SecureROM is enabled"); + } +#endif + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8747x power control driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif +#if WITH_HW_VIC + /* initialize the vic, mask all interrupts */ + interrupt_init(); +#endif +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); +#endif +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_HW_DMA + /* initialize the dma engine */ + dma_init(); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + + return 0; +} + +int platform_late_init(void) +{ + // Chips older then B0 are not supported + if (platform_get_chip_revision() < 0x10) platform_not_supported(); + +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + + return 0; +} + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select the right pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); +#endif + + return 0; +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_DMA +#error "Need to quiesce DMA here if a DMA API is ever added" +#endif +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_VIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + u_int32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + platform_quiesce_display(); + case BOOT_DARWIN: + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + ; // do nothing + } + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + + /* mark usable ram as cached/buffered */ + arm_mmu_map_section_range(SRAM_BASE, SRAM_BASE, ROUNDUP(SRAM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#if APPLICATION_IBOOT + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, kARMMMUNormal, false, false); +#endif +#if APPLICATION_SECUREROM + arm_mmu_map_section_range(VROM_BASE, VROM_BASE, ROUNDUP(VROM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#endif + + /* Remap text base is to zero (for exception vectors) */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUNormalRX, false); + +#ifdef MMU_NONCACHE0_SIZE + /* create the noncached0 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE0_VBASE, MMU_NONCACHE0_PBASE, ROUNDUP(MMU_NONCACHE0_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + +#ifdef MMU_NONCACHE1_SIZE + /* create the noncached1 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE1_VBASE, MMU_NONCACHE1_PBASE, ROUNDUP(MMU_NONCACHE1_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif +} + +int platform_init(void) +{ +#if WITH_HW_SPI + spi_init(); +#endif + +#if APPLICATION_IBOOT + target_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + u_int32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER + boot_set_stage(kPowerNVRAMiBootStageOff); + + power_shutdown(); +#endif + for(;;); +} + +u_int32_t platform_set_performance(u_int32_t performance_level) +{ + u_int32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + u_int32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_CPU); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_MEM); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_BUS); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_PERIPH); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_FIXED); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_TIMEBASE); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_HW_USBPHY + // Fill in the otgphyctrl0 node + if (FindNode(0, "arm-io/otgphyctrl0", &node)) { + usbphy_update_device_tree(node); + } + // Fill in the otgphyctrl1 node + if (FindNode(0, "arm-io/otgphyctrl1", &node)) { + usbphy_update_device_tree(node); + } +#endif + + // Carve mfcram out of base of vram. mfcram node should already have size populated + if (FindNode(0, "mfcram", &node)) { + uint32_t *mfcramPropData; + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + mfcramPropData = propData; + if (FindNode(0, "vram", &node)) { + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint32_t *vramPropData = propData; + mfcramPropData[0] = vramPropData[0]; + vramPropData[0] += mfcramPropData[1]; + vramPropData[1] -= mfcramPropData[1]; + } + } + } + } + + return target_update_device_tree(); +} + +#endif + +static void platform_init_boot_strap(void) +{ + u_int32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rSTATESAVE0[0] set then boot strap already valid + if ((rSTATESAVE0 & 1) != 0) return; + + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + +#if !SUPPORT_FPGA + platform_power_spin(100); // Wait 100us +#endif + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rSTATESAVE0 = (rSTATESAVE0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +u_int32_t platform_get_board_id(void) +{ + u_int32_t board_id; + + ASSERT((rSTATESAVE0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rSTATESAVE0 >> 16) & 0xFF; + +#if SUPPORT_FPGA + board_id = 0x3F; +#endif + + return board_id; +} + +u_int32_t platform_get_boot_config(void) +{ + u_int32_t boot_config; + + boot_config = (rSTATESAVE0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, u_int32_t *boot_flag, u_int32_t *boot_arg) +{ + u_int32_t boot_config = platform_get_boot_config(); + + /* S5L8747X supports one boot device then USB-DFU per boot config. + Unlike other platforms, the USB-DFU device is selectable. */ + +#ifdef HACK_BOOT_CONFIG_OVERRIDE + boot_config = HACK_BOOT_CONFIG_OVERRIDE; +#endif + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case 0: /* SPI 0, then USB0 FDU */ + case 1: /* SPI 0, then USB1 DFU */ + if (index == 0) { + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + } else { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_flag = 0; + *boot_arg = 0; + } + return true; + + case 2: /* SPI 0, then USB0 FDU with TEST_MODE */ + case 3: /* SPI 0, then USB1 DFU with TEST_MODE */ + if (index == 0) { + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + } else { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + } + return true; + + default: + return false; + } +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + u_int32_t enable; + u_int32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +#ifdef SPI_NOR0 +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO( 1, 3), GPIO_CFG_FUNC1, GPIO_CFG_DFLT }, // SPI0_CEN +#else + { GPIO( 1, 3), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_CEN +#endif + { GPIO( 1, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_CLK + { GPIO( 1, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO( 1, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, u_int32_t boot_arg) +{ + const struct boot_interface_pin *pins = 0; + u_int32_t cnt, func, pin_count = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : +#ifdef SPI_NOR0 + if (boot_arg == 0) { + pins = spi0_boot_interface_pins; + pin_count = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } +#endif + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count; cnt++) { + if (enable) { + pin = pins[pin_count - 1 - cnt].pin; + func = pins[pin_count - 1 - cnt].enable; + } else { + pin = pins[cnt].pin; + func = pins[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +u_int64_t platform_get_nonce(void) +{ + u_int64_t nonce; + u_int32_t *nonce_words = (u_int32_t *)&nonce; + u_int8_t *nonce_bytes = (u_int8_t *)&nonce; + + // If rSTATESAVE0[1] set then the nonce has already been generated + if ((rSTATESAVE0 & kPlatformScratchFlagNonce) == 0) { +#if WITH_RANDOM + if (random_get_bytes(nonce_bytes, sizeof(nonce)) != 0) +#endif + { + memset(nonce_bytes, 0, sizeof(nonce)); + } + + rSTATESAVE2 = nonce_words[0]; + rSTATESAVE3 = nonce_words[1]; + + rSTATESAVE0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rSTATESAVE2; + nonce_words[1] = rSTATESAVE3; + } + + return nonce; +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return chipid_get_ecid_image_personalization_required(); +} + +u_int32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +u_int32_t platform_get_base_soc_voltage(void) +{ + return 1200; +} + +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = platform_get_base_soc_voltage(); + } + + return 0; +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ + return gpio_read(GPIO_FORCE_DFU); +} + +int platform_translate_key_selector(u_int32_t key_selector, u_int32_t *key_opts) +{ + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_128; + + return 0; +} + +#if APPLICATION_IBOOT +u_int64_t platform_get_memory_size(void) +{ + return (2 * 128 * 1024 * 1024); +} + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = SDRAM_BASE + platform_get_memory_size() - PANIC_SIZE; + break; + + case kMemoryRegion_Display: + base = SDRAM_BASE + platform_get_memory_size() - PURPLE_GFX_MEMORY_LEN - PANIC_SIZE; + break; + + case kMemoryRegion_Kernel: + base = SDRAM_BASE; + break; + + default: + base = (uintptr_t)-1; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + + case kMemoryRegion_Display: + size = PURPLE_GFX_MEMORY_LEN; + break; + +#if defined(SLEEP_TOKEN_BUFFER_SIZE) + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; + +#endif + + case kMemoryRegion_Kernel: + size = platform_get_memory_size() - PURPLE_GFX_MEMORY_LEN - PANIC_SIZE; + break; + + default: + size = (size_t)-1; + } + + return size; +} + +#endif + diff --git a/platform/s5l8747x/miu/miu.c b/platform/s5l8747x/miu/miu.c new file mode 100644 index 0000000..7a64944 --- /dev/null +++ b/platform/s5l8747x/miu/miu.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* memory controller stuff */ + +#if APPLICATION_IBOOT + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT + /* Turn off alias from 0x10000000 to 0x08000000 */ + rDDR1 = 1; + + /* bring up sdram */ + mcu_initialize_dram(resume); +#endif + return 0; +} + +#endif /* APPLICATION_IBOOT */ + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rSTATESAVE0 and rSTATESAVE1 get cleared + rSTATESAVE0 = 0; + rSTATESAVE1 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of SAVESTATE0 + rSTATESAVE0 &= ~0xFF000000; + rSTATESAVE0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +void +miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rREMAP = (rREMAP & ~3) | (1 << 0) | (1 << 1); // remap, remap_sel = 1 + break; + case REMAP_SDRAM: + rREMAP = (rREMAP & ~3) | (1 << 0) | (0 << 1); // remap, remap_sel = 0 + break; + } +} + +void +miu_setup_mfc_address_filter(void) +{ +#if ((PURPLE_GFX_MEMORY_LEN + PANIC_SIZE) & 0xFFFFF) != 0 +#error "PurpleGfxMemory must be 1 MB-aligned" +#endif + uint32_t range_end = SDRAM_BASE + (uint32_t)platform_get_memory_size(); + uint32_t range_base = range_end - PANIC_SIZE - PURPLE_GFX_MEMORY_LEN; + rMFC_ARF_BASE_ADDR = range_base; + rMFC_ARF_ADDR_MASK = ~(range_end - range_base) & 0xFFF00000; + rMFC_ARF_CON = 1; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in STATESAVE0 matches + if ((rSTATESAVE0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif + + /* remap whatever bank of ram we're in to zero */ + if (TEXT_BASE == SRAM_BASE) + miu_select_remap(REMAP_SRAM); + else if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) + miu_select_remap(REMAP_SDRAM); + +#if APPLICATION_IBOOT + miu_setup_mfc_address_filter(); +#endif + + return 0; +} diff --git a/platform/s5l8747x/miu/rules.mk b/platform/s5l8747x/miu/rules.mk new file mode 100644 index 0000000..ff099fa --- /dev/null +++ b/platform/s5l8747x/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2006 Apple Computer, Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s5l8747x/pmgr/pmgr.c b/platform/s5l8747x/pmgr/pmgr.c new file mode 100644 index 0000000..12d29e7 --- /dev/null +++ b/platform/s5l8747x/pmgr/pmgr.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + + +void platform_power_init(void) +{ + // configure the AAM clock + rPWRCONF = (0 << 25) | (1<<24) | (0<<20) | // AAM clock 12MHz, prescalar on /1 + (2<<16) | // enable 2 synch flip flops + (1<<14) | // enable all OSCs in normal mode + (1<<13) | // enable all OSCs in normal mode + (1<<12) | // enable all OSCs in normal mode + (1<<1); + + rTMCMD = 0; // Stop the AAM timer + rTMPRE = platform_get_osc_frequency() / 1000000; // Set timer prescale for 1 MHz +} + +void platform_power_spin(u_int32_t usecs) +{ + rTMDATA = usecs; + rTMCMD = (1 << 1) | (1 << 0); // Clear and start the AAM timer + + while ((rTMALARM & 1) == 0); // Wait for the timer to fire + + rTMCMD = (1 << 1) | (0 << 0); // Clear and stop the AAM timer +} + +void platform_disable_keys(u_int32_t gid, u_int32_t uid) +{ + if (gid) rSECCONF = 1 << 1; + if (uid) rSECCONF = 1 << 0; +} + + diff --git a/platform/s5l8747x/pmgr/rules.mk b/platform/s5l8747x/pmgr/rules.mk new file mode 100644 index 0000000..51bb648 --- /dev/null +++ b/platform/s5l8747x/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s5l8747x/rules.mk b/platform/s5l8747x/rules.mk new file mode 100644 index 0000000..1bf974e --- /dev/null +++ b/platform/s5l8747x/rules.mk @@ -0,0 +1,92 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +############################################################################## +# Code running on the main CPU +# +ifeq ($(PLATFORM_VARIANT),) + +ARM_ARCH := armv7 +ARM_CPU := cortex-a5 + +# Devmap chip ID based on sub-platform identifier +ifeq ($(SUB_PLATFORM),s5l8747x) +DEVMAP_CHIP_ID := 8747 +endif + +MAX_DFU_SIZE := 98304 + +ifeq ($(TEXT_BANK),srom) +TEXT_BASE := 0x00000000 +endif +ifeq ($(TEXT_BANK),sram) +TEXT_BASE := 0x22000000 +endif +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0x0FF00000 +endif + +OPTIONS += \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + WITH_LEGACY_PANIC_LOGS=1 \ + WITH_NON_COHERENT_DMA=1 \ + WITH_ROM_TRAMPOLINE=1 \ + WITH_CONJOINED_USB_PHYS=1 \ + PLATFORM_ENTROPY_RATIO=60 \ + PLATFORM_IRQ_COUNT=192 \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +GLOBAL_LDFLAGS += -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) +# This selects the start of the DATA segment and the end of the INSECURE_MEMORY area +DATA_BASE := 0x22019000 + +OPTIONS += \ + DATA_BASE="$(DATA_BASE)" + +GLOBAL_LDFLAGS += -segaddr __DATA $(DATA_BASE) + +# Simulation trace uses STATESAVE2 and STATESAVE3 +# We have to duplicate the literal values here as debug.h is +# not necessarily going have hwregbase.h in scope all the time. +OPTIONS += \ + SIMULATION_TRACE_IP_REGISTER=0x3970004c \ + SIMULATION_TRACE_PARAMETER_REGISTER=0x39700050 +endif + +# SecureROM turns off the timers on G1, so turn them back on as early +# as possible to get accurate measurements of boot time. +# By default only do this in development builds though. +ifeq ($(APPLICATION),iBoot) +ifeq ($(BUILD),DEVELOPMENT) +OPTIONS += \ + PLATFORM_START_FUNCTION=_platform_start +endif +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o + +MODULES_ELIDE += lib/libcorecrypto + +endif + diff --git a/platform/s5l8940x/amc/amc_s5l8940x.c b/platform/s5l8940x/amc/amc_s5l8940x.c new file mode 100644 index 0000000..79e60f6 --- /dev/null +++ b/platform/s5l8940x/amc/amc_s5l8940x.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + return amc_init(resume); +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping (void) +{ + amc_configure_default_address_decoding_and_mapping(); +} + +void amc_enable_slow_boot (bool enable) +{ + int slow_freqsel; + + if (enable) { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + rAMC_FREQSEL = amc_params.freqsel; + return; + } + + slow_freqsel = 3; + rAMC_BOOTCLK = (amc_params.bootclkdivsr << 8) | 1; + spin(5); + rAMC_FREQSEL = slow_freqsel; + amc_phy_scale_dll(slow_freqsel, amc_params.bootclkdivsr); + } else { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + return; + } + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_small; + spin(2); + + rAMC_BOOTCLK &= ~1; + spin(5); + rAMC_FREQSEL = amc_params.freqsel; + amc_phy_scale_dll(amc_params.freqsel, 1); + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_guided; + } +} + +void amc_finalize (bool resume) +{ + uint8_t odts; + +#if SUPPORT_FPGA + rAMC_PWRMNGTEN |= 0x00000001; // Sharing clocks between channels so do not enable clock stopping for PD or SR +#else // SUPPORT_FPGA + rAMC_PWRMNGTEN |= 0x00001001; +#endif // SUPPORT_FPGA + + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&odts); + rAMC_ODTS = 0x00010080; // [16] => TempDrtEn, [9:0] RdIntrvl XXX based on tREFI + + rAMC_PWRMNGTEN |= 0x00010000; // Enable srclkoff as well + + if (!resume) { + amc_enable_autorefresh(); + } + +#if !SUPPORT_FPGA + // Turn of Fast Critical Word Forwarding feature and AIU CWF feature + // Disabled for NRT + rAMC_AIUPRT_RD_CWF = 0x0001011f; + rAMC_QBRPARAM = 0x00020200; + rAMC_QBREN = 0x00111001; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + const struct amc_memory_device_info *dev_info; + uint32_t chip_id = platform_get_chip_id(); + uint8_t i; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_SAMSUNG: + + // H4P Samsung 35nm LPDDR2 Transition for N94 + // TMRS for Samsung 46nm part only + if ((chip_id == 0x8940) && (!resume) && (dev_info->rev_id == 0)) { + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xff); + + // Apply Samsung workaround + + // Column Select Line pull in (230ps) TMRS(1) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x80); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x04); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x08); + + // Latch command + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + + // Column Select Line pull in (230ps) TMRS(2) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x40); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x01); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + + // Latch command + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + } + + // Samsung 3xnm DRAMs - not functional + else if ((chip_id == 0x8942) && (!resume) && (dev_info->rev_id == 1) && (dev_info->rev_id2 == 0)) { + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xff); + + // PDL_M(-500ps) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x80); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x01); + + // Latch Command + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + } + + break; + + case JEDEC_MANUF_ID_HYNIX: + + if (dev_info->rev_id == 0) { + if (!resume) { + // Test MRS Exit "just in case" + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + + // Apply Hynix cold clamp disable workaround + // (but only for revid2 == 0 ) + if ((chip_id == 0x8940) && (dev_info->rev_id2 == 0)) { + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xa2); + } + + // IOSTBP Start Time control (600ps delay) + if ((chip_id == 0x8942) && (dev_info->density == JEDEC_DENSITY_1Gb)) { + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + + for (i = 0; i < 13; i++) { + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x99); + } + } + } + +#if !SUB_TARGET_K93 && !SUB_TARGET_K94 && !SUB_TARGET_K95 && !SUB_TARGET_J33 + // H4G UM Update: Modified setting for tMRR timing parameter + // override tMRR to 3 cycles (only if performing dynamic calibration) + if (dev_info->density == JEDEC_DENSITY_2Gb) { + rAMC_MODE_FREQ(0) = amc_params.freq[0].modereg | 0x3; + } +#endif + } else if ((dev_info->rev_id == 1) && (dev_info->rev_id2 == 0)) { + + // Hynix 3xnm workaround solution + if ((chip_id == 0x8942) && (!resume)) { + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + + // Yi Enable +1 step + for (i = 0; i < 4; i++) { + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xf1); + } + + // Yi Pulse +1 step + for (i = 0; i < 4; i++) { + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x94); + } + } + } + break; + + default: + break; + } +} + +// Shift dq offset as needed. +// In the future, it's possible the shift value changes based on SOC or DRAM vendor. +// Thus, we need to have this function per SOC. +void amc_dram_shift_dq_offset (int8_t *dq_offset, uint8_t num_bytes) { + int8_t shift_val; + uint8_t i; + const struct amc_memory_device_info *dev_info; + uint32_t chip_id = platform_get_chip_id(); + + // Do nothing for H4P + if (chip_id == 0x8940) + return; + + // H4A: Need additional DQ WR/RD static offsets + dev_info = amc_get_memory_device_info(); + shift_val = 0; + + switch (dev_info->vendor_id) { + + case JEDEC_MANUF_ID_SAMSUNG: + case JEDEC_MANUF_ID_HYNIX: + + // -3 step shift for DRAMs not used in K93A or J33 + if (dev_info->rev_id > 0) + shift_val = -3; + + break; + + case JEDEC_MANUF_ID_ELPIDA: + + // -3 step shift for DRAMs not used in K93A or J33 + if (dev_info->rev_id > 1) + shift_val = -3; + + break; + + default: + dprintf(DEBUG_INFO, "Not applyig any shift to dq offsets for vendor: %d\n", dev_info->vendor_id); + break; + } + + for (i = 0; i < num_bytes; i++) + dq_offset[i] += shift_val; +} diff --git a/platform/s5l8940x/amc/amc_s5l8947x.c b/platform/s5l8940x/amc/amc_s5l8947x.c new file mode 100644 index 0000000..694dedc --- /dev/null +++ b/platform/s5l8940x/amc/amc_s5l8947x.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + return amc_init(resume); +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping (void) +{ + amc_configure_default_address_decoding_and_mapping(); +} + +void amc_enable_slow_boot (bool enable) +{ + int slow_freqsel; + + if (enable) { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + rAMC_FREQSEL = amc_params.freqsel; + return; + } + + slow_freqsel = 3; + rAMC_BOOTCLK = (amc_params.bootclkdivsr << 8) | 1; + spin(5); + rAMC_FREQSEL = slow_freqsel; + amc_phy_scale_dll(slow_freqsel, amc_params.bootclkdivsr); + } else { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + return; + } + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_small; + spin(2); + + rAMC_BOOTCLK &= ~1; + spin(5); + rAMC_FREQSEL = amc_params.freqsel; + amc_phy_scale_dll(amc_params.freqsel, 1); + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_guided; + } +} + +void amc_finalize (bool resume) +{ + uint8_t odts; + +#if SUPPORT_FPGA + rAMC_PWRMNGTEN |= 0x00000001; // Sharing clocks between channels so do not enable clock stopping for PD or SR +#else + rAMC_PWRMNGTEN |= 0x00011011; +#endif + + rAMC_AREFPARAM |= (0x00001000); // Turn on freq change waiting for refresh and self-refresh exit + + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&odts); + rAMC_ODTS = 0x00010320; // [16] => TempDrtEn, [9:0] RdIntrvl XXX based on tREFI + + if (!resume) { + amc_enable_autorefresh(); + } + +#if SUPPORT_FPGA + rAMC_FREQSEL = amc_params.freqsel; +#endif + +#if !SUPPORT_FPGA + // Turn of Fast Critical Word Forwarding feature and AIU CWF feature + // Disabled for NRT + rAMC_AIUPRT_RD_CWF = 0x00161600; + rAMC_QBRPARAM = 0x00810000; + rAMC_QBREN = 0x00111001; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + // XXX - Possibly look in s5l8950x amc.c to see possible workarounds. + return; +} + +// Shift dq offset as needed. +// In the future, it's possible the shift value changes based on SOC or DRAM vendor. +// Thus, we need to have this function per SOC. +void amc_dram_shift_dq_offset (int8_t *dq_offset, uint8_t num_bytes) { + int8_t shift_val; + uint8_t i; + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + case JEDEC_MANUF_ID_SAMSUNG: + case JEDEC_MANUF_ID_ELPIDA: + + // shift 2 steps + shift_val = -2; + break; + + default: + shift_val = 0; + break; + } + + for (i = 0; i < num_bytes; i++) + dq_offset[i] += shift_val; +} diff --git a/platform/s5l8940x/amc/rules.mk b/platform/s5l8940x/amc/rules.mk new file mode 100644 index 0000000..c29d670 --- /dev/null +++ b/platform/s5l8940x/amc/rules.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2009-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AMC=1 + +ifneq ($(SUB_PLATFORM), s5l8947x) +ALL_OBJS += \ + $(LOCAL_DIR)/amc_s5l8940x.o +else +ALL_OBJS += \ + $(LOCAL_DIR)/amc_s5l8947x.o +endif diff --git a/platform/s5l8940x/chipid/chipid.c b/platform/s5l8940x/chipid/chipid.c new file mode 100644 index 0000000..4086f9a --- /dev/null +++ b/platform/s5l8940x/chipid/chipid.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if SUPPORT_FPGA +#define _rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#undef rCFG_FUSE0 +// XXX ECID (1 << 7)? +// XXX double-check memory values +#define rCFG_FUSE0 ((0 << 31) | (3 << 28) | (0xE << 24) | (2 << 22) | \ + (0 << 9) | (1 << 8) | (3 << 4) | (kPlatformSecurityDomainDarwin << 2) | (0 << 1) | (0 << 0) | \ + _rCFG_FUSE0) +#endif + +#if SUB_PLATFORM_S5L8940X +#define DEFAULT_SOC_VOLTAGE_LOW 1000 +#define DEFAULT_SOC_VOLTAGE_MED 1100 +#define DEFAULT_SOC_VOLTAGE_HIGH 1200 +#define DEFAULT_CPU_VOLTAGE_LOW 1000 +#define DEFAULT_CPU_VOLTAGE_MED 1150 +#define DEFAULT_CPU_VOLTAGE_HIGH 1250 +#define BASE_SOC_VOLTAGE_LOW 875 +#define BASE_SOC_VOLTAGE_MED 975 +#define BASE_SOC_VOLTAGE_HIGH 1075 +#define BASE_CPU_VOLTAGE_LOW 875 +#define BASE_CPU_VOLTAGE_MED 975 +#define BASE_CPU_VOLTAGE_HIGH 1075 +#elif SUB_PLATFORM_S5L8942X +#define DEFAULT_SOC_VOLTAGE_LOW 925 +#define DEFAULT_SOC_VOLTAGE_MED 1000 +#define DEFAULT_SOC_VOLTAGE_HIGH 1100 +#define DEFAULT_CPU_VOLTAGE_LOW 925 +#define DEFAULT_CPU_VOLTAGE_MED 1025 +#define DEFAULT_CPU_VOLTAGE_HIGH 1125 +#define BASE_SOC_VOLTAGE_LOW 800 +#define BASE_SOC_VOLTAGE_MED 825 +#define BASE_SOC_VOLTAGE_HIGH 925 +#define BASE_CPU_VOLTAGE_LOW 800 +#define BASE_CPU_VOLTAGE_MED 875 +#define BASE_CPU_VOLTAGE_HIGH 975 +#elif SUB_PLATFORM_S5L8947X +#define DEFAULT_SOC_VOLTAGE_LOW 1100 +#define DEFAULT_SOC_VOLTAGE_MED 1100 +#define DEFAULT_SOC_VOLTAGE_HIGH 1100 +#define DEFAULT_CPU_VOLTAGE_LOW 1100 +#define DEFAULT_CPU_VOLTAGE_MED 1100 +#define DEFAULT_CPU_VOLTAGE_HIGH 1100 +#define BASE_SOC_VOLTAGE_LOW 1075 +#define BASE_SOC_VOLTAGE_MED 1075 +#define BASE_SOC_VOLTAGE_HIGH 1075 +#define BASE_CPU_VOLTAGE_LOW 1075 +#define BASE_CPU_VOLTAGE_MED 1075 +#define BASE_CPU_VOLTAGE_HIGH 1075 +#endif + +bool chipid_get_production_mode(void) +{ + return ((rCFG_FUSE0 >> 0) & 1) != 0; +} + +void chipid_clear_production_mode(void) +{ +#if SUPPORT_FPGA + _rCFG_FUSE0 &= ~1; +#else + rCFG_FUSE0 &= ~1; +#endif +} + +bool chipid_get_secure_mode(void) +{ + return ((rCFG_FUSE0 >> 1) & 1) != 0; +} + +u_int32_t chipid_get_security_domain(void) +{ + return (rCFG_FUSE0 >> 2) & 3; +} + +u_int32_t chipid_get_board_id(void) +{ + return (rCFG_FUSE0 >> 4) & 3; +} + +bool chipid_get_ecid_image_personalization_required(void) +{ + return ((rCFG_FUSE0 >> 7) & 1) != 0; +} + +u_int32_t chipid_get_minimum_epoch(void) +{ + return (rCFG_FUSE0 >> 9) & 0x7F; +} + +u_int32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_S5L8940X + return 0x8940; +#elif SUB_PLATFORM_S5L8942X + return 0x8942; +#elif SUB_PLATFORM_S5L8947X + return 0x8947; +#endif +} + +u_int32_t chipid_get_chip_revision(void) +{ + return (((rECIDHI >> 13) & 0x7) << 4) | (((rECIDHI >> 10) & 0x7) << 0); +} + +u_int32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +u_int64_t chipid_get_ecid_id(void) +{ + u_int64_t ecid = 0; + +#if SUPPORT_FPGA + ecid = 0x000012345678ABCDULL; +#else + ecid |= ((rECIDLO >> 0)) & ((1ULL << (21 - 0)) - 1); // LOT_ID + + ecid <<= (26 - 21); + ecid |= ((rECIDLO >> 21)) & ((1ULL << (26 - 21)) - 1); // WAFER_NUM + + ecid <<= (10 - 2); + ecid |= ((rECIDHI >> 2)) & ((1ULL << (10 - 2)) - 1); // Y_POS + + ecid <<= (32 - 26); + ecid |= ((rECIDLO >> 26)) & ((1ULL << (32 - 26)) - 1); // X_POS_H + + ecid <<= ( 2 - 0); + ecid |= ((rECIDHI >> 0)) & ((1ULL << ( 2 - 0)) - 1); // X_POS_L +#endif + + return ecid; +} + +u_int64_t chipid_get_die_id(void) +{ + return ((u_int64_t)rECIDHI << 32) | rECIDLO; +} + +u_int32_t chipid_get_soc_voltage(u_int32_t index) +{ + u_int32_t soc_voltage = 0; + u_int32_t soc_bin_offset_data = 0, soc_bin_data = (rCFG_FUSE1 >> 5) & 0x1FF; + int32_t soc_bin_offset; + +#if DEBUG_BUILD && WITH_ENV + soc_bin_offset_data = env_get_uint("soc-bin-offset", 0); + + switch (index) { + case CHIPID_SOC_VOLTAGE_LOW : soc_bin_offset_data = (soc_bin_offset_data >> 0) & 0xff; break; + case CHIPID_SOC_VOLTAGE_MED : soc_bin_offset_data = (soc_bin_offset_data >> 8) & 0xff; break; + case CHIPID_SOC_VOLTAGE_HIGH : soc_bin_offset_data = (soc_bin_offset_data >> 16) & 0xff; break; + default : break; + } +#endif + + // if bin data is all zeros, bin data is not valid + if (soc_bin_data == 0) { + switch (index) { + case CHIPID_SOC_VOLTAGE_LOW : soc_voltage = DEFAULT_SOC_VOLTAGE_LOW; break; + case CHIPID_SOC_VOLTAGE_MED : soc_voltage = DEFAULT_SOC_VOLTAGE_MED; break; + case CHIPID_SOC_VOLTAGE_HIGH : soc_voltage = DEFAULT_SOC_VOLTAGE_HIGH; break; + default : break; + } + } else { + switch (index) { + case CHIPID_SOC_VOLTAGE_LOW : soc_voltage = BASE_SOC_VOLTAGE_LOW + 25 * ((soc_bin_data>>6)&7); break; + case CHIPID_SOC_VOLTAGE_MED : soc_voltage = BASE_SOC_VOLTAGE_MED + 25 * ((soc_bin_data>>3)&7); break; + case CHIPID_SOC_VOLTAGE_HIGH : soc_voltage = BASE_SOC_VOLTAGE_HIGH + 25 * ((soc_bin_data>>0)&7); break; + default : break; + } + } + + soc_bin_offset = soc_bin_offset_data | (((soc_bin_offset_data & 0x80) == 0) ? 0 : 0xffffff00); + soc_bin_offset *= 25; + + return soc_voltage + soc_bin_offset; +} + +u_int32_t chipid_get_cpu_voltage(u_int32_t index) +{ + u_int32_t cpu_voltage = 0; + u_int32_t cpu_bin_offset_data = 0, cpu_bin_data = ((((u_int64_t)rCFG_FUSE1 << 32) | rCFG_FUSE0) >> 28) & 0x1FF; + int32_t cpu_bin_offset; + +#if DEBUG_BUILD && WITH_ENV + cpu_bin_offset_data = env_get_uint("cpu-bin-offset", 0); + + switch (index) { + case CHIPID_CPU_VOLTAGE_LOW : cpu_bin_offset_data = (cpu_bin_offset_data >> 0) & 0xff; break; + case CHIPID_CPU_VOLTAGE_MED : cpu_bin_offset_data = (cpu_bin_offset_data >> 8) & 0xff; break; + case CHIPID_CPU_VOLTAGE_HIGH : cpu_bin_offset_data = (cpu_bin_offset_data >> 16) & 0xff; break; + default : break; + } + +#endif + // if bin data is all zeros, bin data is not valid + if (cpu_bin_data == 0) { + switch (index) { + case CHIPID_CPU_VOLTAGE_LOW : cpu_voltage = DEFAULT_CPU_VOLTAGE_LOW; break; + case CHIPID_CPU_VOLTAGE_MED : cpu_voltage = DEFAULT_CPU_VOLTAGE_MED; break; + case CHIPID_CPU_VOLTAGE_HIGH : cpu_voltage = DEFAULT_CPU_VOLTAGE_HIGH; break; + default : break; + } + } else { + switch (index) { + case CHIPID_CPU_VOLTAGE_LOW : cpu_voltage = BASE_CPU_VOLTAGE_LOW + 25 * ((cpu_bin_data>>6)&7); break; + case CHIPID_CPU_VOLTAGE_MED : cpu_voltage = BASE_CPU_VOLTAGE_MED + 25 * ((cpu_bin_data>>3)&7); break; + case CHIPID_CPU_VOLTAGE_HIGH : cpu_voltage = BASE_CPU_VOLTAGE_HIGH + 25 * ((cpu_bin_data>>0)&7); break; + default : break; + } + } + + cpu_bin_offset = cpu_bin_offset_data | (((cpu_bin_offset_data & 0x80) == 0) ? 0 : 0xffffff00); + cpu_bin_offset *= 25; + + return cpu_voltage + cpu_bin_offset; +} + +bool chipid_get_fuse_lock(void) +{ + return (rCFG_FUSE1 & (1 << 31)) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) rCFG_FUSE1 |= 1 << 31; +} + +u_int32_t chipid_get_memory_density(void) +{ + u_int32_t data = (rCFG_FUSE0 >> 24) & 0x7; + + if (chipid_get_memory_manufacturer() == 0) data = 5; + + return 1 << (24 + data); +} + +u_int32_t chipid_get_memory_manufacturer(void) +{ + return (rCFG_FUSE0 >> 20) & 0xF; +} + +u_int32_t chipid_get_memory_ranks(void) +{ + u_int32_t data = (rCFG_FUSE0 >> 27) & 0x1; + + if (chipid_get_memory_manufacturer() == 0) data = 0; + + return 1 << data; +} + +u_int32_t chipid_get_memory_width(void) +{ + u_int32_t data = (rCFG_FUSE0 >> 18) & 0x3; + + if (chipid_get_memory_manufacturer() == 0) data = 2; + + return 16 << data; +} + +bool chipid_get_memory_dqcal(u_int32_t *cal_data) +{ + /* Swizzle the fuses into a standard format. One word each + * for CH0 read, CH0 write, etc. */ + cal_data[0] = rCFG_FUSE2 & 0xffff; + cal_data[1] = rCFG_FUSE3 & 0xffff; + cal_data[2] = rCFG_FUSE2 >> 16; + cal_data[3] = rCFG_FUSE3 >> 16; + return true; +} diff --git a/platform/s5l8940x/chipid/rules.mk b/platform/s5l8940x/chipid/rules.mk new file mode 100644 index 0000000..29257b1 --- /dev/null +++ b/platform/s5l8940x/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/s5l8940x/include/platform/amcconfig.h b/platform/s5l8940x/include/platform/amcconfig.h new file mode 100644 index 0000000..475bc63 --- /dev/null +++ b/platform/s5l8940x/include/platform/amcconfig.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include SUB_PLATFORM_HEADER(amcconfig) diff --git a/platform/s5l8940x/include/platform/amcconfig_s5l8940x.h b/platform/s5l8940x/include/platform/amcconfig_s5l8940x.h new file mode 100644 index 0000000..008e1bd --- /dev/null +++ b/platform/s5l8940x/include/platform/amcconfig_s5l8940x.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = FLAG_AMC_PARAM_ENABLE_AIU | FLAG_AMC_PARAM_SLOW_BOOT, + + .freqsel = 0, + .tREFi = 0x5d, + .longsrcnt = 0x0802, + .srextrarefcnt = 0x00010000, + .tREFi_1Gb = 0xbb, + .longsrcnt_1Gb = 0x0401, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 6, // rdlat + .phywrlat = 3, + .pdn = 0x33000303, + .read = 0x00000103, + .bustat = 0x00020002, + .derate = 0x28831258, + .mcphyupdate = 0x00000009, // + .pwrmngtparam_small = 0x00013000, + .pwrmngtparam_guided = 0x00fa3000, + .bootclkdivsr = 8, + .aref_freq0 = 0x00100100, + .aref_freq1 = 0x00100000, + .chnldec = 0x00000F00, + .arefparam = 0x06000000, + .readleveling = 0x02000301, + + .freq = { + { // 400MHz + .cas = 0x00000308, + .pch = 0x00030611, + .act = 0x14040908, + .autoref = 0x1834a000, + .selfref = 0x00038060, + .modereg = 0x00240502, + .mifcassch = 0x001f0111, + .mifqmaxctrl = 0x00000000, + }, + { // 200MHz + .cas = 0x00000004, + .pch = 0x00000009, + .act = 0x0a020504, + .autoref = 0x0c1a0000, + .selfref = 0x0001c000, + .modereg = 0x00120000, + .mifcassch = 0x00000000, + .mifqmaxctrl = 0x00000000, + }, + { // 100MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x060d0000, + .selfref = 0x0000e000, + .modereg = 0x00090000, + .mifcassch = 0x00000000, + .mifqmaxctrl = 0x00000000, + }, + { // 50 & 24MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x03070000, + .selfref = 0x00007000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + .mifqmaxctrl = 0x00000001, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + // These settings are common across all H4x and H5P. Channel decode and hashing + // is done in mainline init code. Any tunables that match hardware defaults are + // omitted here. + + { &rAMC_AIUPRT_CFG, 0x00070000 }, // address error enable + { &rAMC_AIUPRT_RD_GEN, 0x00000018 }, // fence read detect on GFX + { &rAMC_AIUPRT_WR, 0x00000001 }, // out-of-order write, ignore B-bit + + { &rAMC_AIU_RDBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_RDMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_WRMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + + { &rAMC_AIU_CPUSPCREQ, 0x00000019 }, // CPU ageout timer + { &rAMC_AIU_GFXSPCREQ, 0x00000032 }, // GFX ageout timer + { &rAMC_AIU_NRTSPCREQ, 0x00000032 }, // Hperf-NRT ageout timer + { &rAMC_AIU_RTSPCREQ, 0x00000019 }, // Hperf-RT ageout timer + { &rAMC_AIU_WPQSCH, 0x10001000 }, // only supported for Hperf-RT + { &rAMC_AIU_THOTLCPUPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLRTPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLNRTPARAM, 0x00000000 }, + { &rAMC_AIU_THOTLGFXPARAM, 0x00000000 }, + { &rAMC_AIU_PUSHEN, 0x00001100 }, // only supported for Hperf-RT + + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJEN, 0x00000001 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + + { &rAMC_MIFACTSCH, 0x00000001 }, + + { &rAMC_PSQRQTIMER0, 0x00000040 }, // RTG bypass up to 64 transactions + { &rAMC_PSQRQTIMER1, 0x00000018 }, // RTY bypass up to 24 transactions + { &rAMC_PSQRQTIMER2, 0x00000020 }, // RTG bypass up to 32 transactions + { &rAMC_PSQRQBRST, 0x040c040c }, // RTR transactions don't affect read burst size + { &rAMC_PSQRQSCHCRD, 0x002028f5 }, // read credits = 2 * write credits + { &rAMC_PSQWQBRST, 0x0208040c }, // RTR reads cause reduced write burst size + { &rAMC_PSQWQSCHCRD, 0x001014f5 }, // write credits = 1/2 * read credits + { &rAMC_MCUQOS, 0x00010f04 }, // RTG=4, RTY=15, enable pick-oldest-RTY + + // Platform specific + + { &rAMC_AIU_RDMAXCRD, 0x2828050a }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_RDREFL, 0x21210408 }, // 5/6 of AIURDMAXCRD fields + { &rAMC_AIU_WRMAXCRD, 0x2828050a }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRREFL, 0x21210408 }, // 5/6 of AIUWRMAXCRD fields + { &rAMC_AIU_THOTLEN, 0x00001111 }, // enable throttling + { &rAMC_PSQWQCTL1, 0x000000C0 }, // ages write out faster than default (1/2 SelfRef) + { &rAMC_MCUQOSLLT, 0x00010104 }, + { &rAMC_PWRMNGTPARAM, 0x01801000 }, // SelfRef timer = 384 cycles + + // There is a bug around write merge, which we believe is avoided + // in current drivers: + // Power and performance measurements of disabling write merging were + // done: + { &rAMC_PSQWQCTL0, 0x00010100 }, // Write merge enable +}; +#endif diff --git a/platform/s5l8940x/include/platform/amcconfig_s5l8942x.h b/platform/s5l8940x/include/platform/amcconfig_s5l8942x.h new file mode 100644 index 0000000..e9af631 --- /dev/null +++ b/platform/s5l8940x/include/platform/amcconfig_s5l8942x.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_RECONFIG | FLAG_AMC_PARAM_ENABLE_AIU), + + .freqsel = 0, + .tREFi = 0x5d, + .longsrcnt = 0x0802, + .srextrarefcnt = 0x00010000, + .tREFi_1Gb = 0xbb, + .longsrcnt_1Gb = 0x0401, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 6, // rdlat + .phywrlat = 3, + .pdn = 0x33000303, + .read = 0x00000103, + .bustat = 0x00020002, + .derate = 0x28831258, + .mcphyupdate = 0x00000009, // + .pwrmngtparam_small = 0x00013000, + .pwrmngtparam_guided = 0x00fa3000, + .bootclkdivsr = 8, + .aref_freq0 = 0x00100100, + .aref_freq1 = 0x00100000, + .chnldec = 0x00000F00, + .arefparam = 0x06000000, + .readleveling = 0x02000301, + + .freq = { + { // 400MHz + .cas = 0x00000308, + .pch = 0x00030611, + .act = 0x14040908, + .autoref = 0x1834a000, + .selfref = 0x00038060, + .modereg = 0x00240502, + .mifcassch = 0x001f0111, + .mifqmaxctrl = 0x00000000, + }, + { // 200MHz + .cas = 0x00000004, + .pch = 0x00000009, + .act = 0x0a020504, + .autoref = 0x0c1a0000, + .selfref = 0x0001c000, + .modereg = 0x00120000, + .mifcassch = 0x00000000, + .mifqmaxctrl = 0x00000000, + }, + { // 100MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x060d0000, + .selfref = 0x0000e000, + .modereg = 0x00090000, + .mifcassch = 0x00000000, + .mifqmaxctrl = 0x00000000, + }, + { // 50 & 24MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x03070000, + .selfref = 0x00007000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + .mifqmaxctrl = 0x00000001, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + // These settings are common across all H4x and H5P. Channel decode and hashing + // is done in mainline init code. Any tunables that match hardware defaults are + // omitted here. + + { &rAMC_AIUPRT_CFG, 0x00070000 }, // address error enable + { &rAMC_AIUPRT_RD_GEN, 0x00000018 }, // fence read detect on GFX + { &rAMC_AIUPRT_WR, 0x00000001 }, // out-of-order write, ignore B-bit + + { &rAMC_AIU_RDBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_RDMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_WRMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + + { &rAMC_AIU_CPUSPCREQ, 0x00000019 }, // CPU ageout timer + { &rAMC_AIU_GFXSPCREQ, 0x00000032 }, // GFX ageout timer + { &rAMC_AIU_NRTSPCREQ, 0x00000032 }, // Hperf-NRT ageout timer + { &rAMC_AIU_RTSPCREQ, 0x00000019 }, // Hperf-RT ageout timer + { &rAMC_AIU_WPQSCH, 0x10001000 }, // only supported for Hperf-RT + { &rAMC_AIU_THOTLCPUPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLRTPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLNRTPARAM, 0x00000000 }, + { &rAMC_AIU_THOTLGFXPARAM, 0x00000000 }, + { &rAMC_AIU_PUSHEN, 0x00001100 }, // only supported for Hperf-RT + + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJEN, 0x00000001 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + + { &rAMC_MIFACTSCH, 0x00000001 }, + + { &rAMC_PSQRQTIMER0, 0x00000040 }, // RTG bypass up to 64 transactions + { &rAMC_PSQRQTIMER1, 0x00000018 }, // RTY bypass up to 24 transactions + { &rAMC_PSQRQTIMER2, 0x00000020 }, // RTG bypass up to 32 transactions + { &rAMC_PSQRQBRST, 0x040c040c }, // RTR transactions don't affect read burst size + { &rAMC_PSQRQSCHCRD, 0x002028f5 }, // read credits = 2 * write credits + { &rAMC_PSQWQBRST, 0x0208040c }, // RTR reads cause reduced write burst size + { &rAMC_PSQWQSCHCRD, 0x001014f5 }, // write credits = 1/2 * read credits + { &rAMC_MCUQOS, 0x00010f04 }, // RTG=4, RTY=15, enable pick-oldest-RTY + + // Platform specific + + { &rAMC_AIU_RDMAXCRD, 0x2828050a }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_RDREFL, 0x21210408 }, // 5/6 of AIURDMAXCRD fields + { &rAMC_AIU_WRMAXCRD, 0x2828050a }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRREFL, 0x21210408 }, // 5/6 of AIUWRMAXCRD fields + { &rAMC_AIU_THOTLEN, 0x00001111 }, // enable throttling + { &rAMC_PSQWQCTL1, 0x000000C0 }, // ages write out faster than default (1/2 SelfRef) + { &rAMC_MCUQOSLLT, 0x00010104 }, + { &rAMC_PWRMNGTPARAM, 0x01801000 }, // SelfRef timer = 384 cycles + + // There is a bug around write merge, which we believe is avoided + // in current drivers: + // Power and performance measurements of disabling write merging were + // done: + { &rAMC_PSQWQCTL0, 0x00010100 }, // Write merge enable +}; +#endif diff --git a/platform/s5l8940x/include/platform/amcconfig_s5l8947x.h b/platform/s5l8940x/include/platform/amcconfig_s5l8947x.h new file mode 100644 index 0000000..2bdc923 --- /dev/null +++ b/platform/s5l8940x/include/platform/amcconfig_s5l8947x.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_RECONFIG | FLAG_AMC_PARAM_ENABLE_AIU | FLAG_AMC_PARAM_MRR_BYTE_SWIZZLE | FLAG_AMC_PARAM_MRR_BIT_SWIZZLE), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .tREFi_1Gb = 0x5d, + .longsrcnt_1Gb = 0x2008, + .rdlat = 8, + .wrlat = 4, + .phyrdlat = 8, + .phywrlat = 4, + .pdn = 0x33000503, + .read = 0x00000103, + .bustat = 0x00222212, + .bustat2 = 0x00222212, + .derate = 0x34b3187b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x22, // MIF: tREFBW violation due to freq change + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x03001000, + .chnldec = 0x00000100, + .chnldec2 = 0x003ffffd, + .arefparam = 0x0600a000, + .bootclkdivsr = 0xa, + .aref_freq0 = 0x00100100, + .aref_freq1 = 0x00100100, + .srextrarefcnt = 0x00010000, + .readleveling = 0x01000301, + + .freq = { + { // 532.8MHz + .cas = 0x0000040a, + .pch = 0x00040817, + .act = 0x1b060c0a, + .autoref = 0x20469000, + .selfref = 0x0004b080, + .modereg = 0x00300502, + .mifcassch = 0x001f0111, + }, + { // 400MHz + .cas = 0x00000008, + .pch = 0x00000012, + .act = 0x14050a08, + .autoref = 0x18340000, + .selfref = 0x00038000, + .modereg = 0x00240000, + .mifcassch = 0x00000010, + }, + { // 106.6MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + .mifcassch = 0x00000000, + }, + { // 53.3MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x04070000, + .selfref = 0x00008000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + // These settings are common across all H4x and H5P. Channel decode and hashing + // is done in mainline init code. Any tunables that match hardware defaults are + // omitted here. + + { &rAMC_AIUPRT_CFG, 0x00070000 }, // address error enable + { &rAMC_AIUPRT_RD_GEN, 0x00000018 }, // fence read detect on GFX + { &rAMC_AIUPRT_WR, 0x00000001 }, // out-of-order write, ignore B-bit + { &rAMC_AIU_RDBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_WRBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_CPUSPCREQ, 0x00000019 }, // CPU ageout timer + { &rAMC_AIU_GFXSPCREQ, 0x00000032 }, // GFX ageout timer + { &rAMC_AIU_NRTSPCREQ, 0x00000032 }, // Hperf-NRT ageout timer + { &rAMC_AIU_RTSPCREQ, 0x00000019 }, // Hperf-RT ageout timer + { &rAMC_AIU_PUSHEN, 0x00001100 }, // only supported for Hperf-RT + + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, // RTG bypass up to 64 transactions + { &rAMC_PSQRQTIMER1, 0x00000018 }, // RTY bypass up to 24 transactions + { &rAMC_PSQRQTIMER2, 0x00000020 }, // RTG bypass up to 32 transactions + { &rAMC_PSQRQBRST, 0x040c040c }, // RTR transactions don't affect read burst size + { &rAMC_PSQRQSCHCRD, 0x002028f5 }, // read credits = 2 * write credits + { &rAMC_PSQWQBRST, 0x0208040c }, // RTR reads cause reduced write burst size + { &rAMC_PSQWQSCHCRD, 0x001014f5 }, // write credits = 1/2 * read credits + { &rAMC_MCUQOS, 0x00010f04 }, // RTG=4, RTY=15, enable pick-oldest-RTY + { &rAMC_ADDRMAP_MODE, 0x00000002 }, // RIBI2 achieves much better performance for both linear and tiled mode frame buffers, and has better power profile as well + { &rAMC_PWRMNGTPARAM, 0x03001000 }, // Use AiuReq to exiting self refresh state. + + // Platform specific + + { &rAMC_AIU_CHNLDEC2, 0x003FFFFD }, // The goal is randomize the channel in most cases to create a balanced distribution. + { &rAMC_AIU_RDMAXCRD, 0x3012097f }, // RT:NRT:CPU:GFX = 48:18:09:MAX + { &rAMC_AIU_RDREFL, 0x280f087f }, // 5/6 of AIURDMAXCRD fields + { &rAMC_AIU_WRMAXCRD, 0x3012097f }, // RT:NRT:CPU:GFX = 48:18:09:MAX + { &rAMC_AIU_WRREFL, 0x280f087f }, // 5/6 of AIUWRMAXCRD fields + + { &rAMC_AIU_ADDRBANKHASH0, 0x00006db6 }, // Enable bank hashing, bank[0] derived from bits 0,3,6,.. + { &rAMC_AIU_ADDRBANKHASH1, 0x00005b6d }, // Enable bank hashing, bank[1] derived from bits 1,4,7,.. + { &rAMC_AIU_ADDRBANKHASH2, 0x000036db }, // Enable bank hashing, bank[2] derived from bits 2,5,8,.. + { &rAMC_AIU_CHNLCRD, 0x00180018 }, + { &rAMC_AIU_LLTSCHCTL, 0x00000001 }, // Ensure LLT traffic from all ports is treated as medium priority request in the AIU arbitration + { &rAMC_MCUQOSLLT, 0x00010108 }, + + { &rAMC_AIU_CHNLTM, 0x40006101 }, + { &rAMC_AIU_WPQSCH, 0x08000800 }, // set starvation counts to 8 + { &rAMC_PSQRQCTL1, 0x0000132a }, + { &rAMC_PSQWQCTL0, 0x00010100 }, // enable write merging + { &rAMC_PSQWQCTL1, 0x00000180 }, // ages write out faster than default (1/2 SelfRef) +}; +#endif diff --git a/platform/s5l8940x/include/platform/amgconfig.h b/platform/s5l8940x/include/platform/amgconfig.h new file mode 100644 index 0000000..49040fd --- /dev/null +++ b/platform/s5l8940x/include/platform/amgconfig.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amg_param struct is defined in drivers/apple/amg/amg.h, and this + * file should only by included from amg.c. + */ + +#if WITH_TARGET_AMG_PARAMS +// Default overrided by ipad2, j33, fpga +#include +#else +// Default shared by n94, k93a, n78 +static const struct amg_params amc_phy_params = { + .flags = 0, + .core_config = 0x00001053, + .read_latency = 0x0000669b, + .gate_offset = 0x08080808, +}; +#endif diff --git a/platform/s5l8940x/include/platform/ampconfig.h b/platform/s5l8940x/include/platform/ampconfig.h new file mode 100644 index 0000000..d5d67c4 --- /dev/null +++ b/platform/s5l8940x/include/platform/ampconfig.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMP_PARAMS +#include +#else +static const struct amp_params amc_phy_params = { + .flags = (FLAG_AMP_PARAM_SUPPORT_FMCLK_OFF | FLAG_AMP_PARAM_FULLDIFFMODE), + .freq = { + { + .scl = 0x08, + .rdcapcfg = 0x00010308, + }, + { + .scl = 0x0b, + .rdcapcfg = 0x00010306, + }, + { + .scl = 0x28, + .rdcapcfg = 0x00010301, + }, + { + .scl = 0x3f, + .rdcapcfg = 0x00010301, + }, + }, +}; +#endif diff --git a/platform/s5l8940x/include/platform/boot_pins.h b/platform/s5l8940x/include/platform/boot_pins.h new file mode 100644 index 0000000..bc2cb9e --- /dev/null +++ b/platform/s5l8940x/include/platform/boot_pins.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_BOOT_PINS_H +#define __PLATFORM_BOOT_PINS_H + +#include +#include +#include + +struct boot_interface_pin { + gpio_t pin; + u_int32_t enable; + u_int32_t disable; +}; + +#include SUB_PLATFORM_HEADER(boot_pins) + +#endif /* ! __PLATFORM_BOOT_PINS_H */ diff --git a/platform/s5l8940x/include/platform/boot_pins_s5l8940x.h b/platform/s5l8940x/include/platform/boot_pins_s5l8940x.h new file mode 100644 index 0000000..69f670f --- /dev/null +++ b/platform/s5l8940x/include/platform/boot_pins_s5l8940x.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_BOOT_PINS_S5L8940X_H +#define __PLATFORM_BOOT_PINS_S5L8940X_H + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(20, 5), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // SPI0_SSIN +#else + { GPIO(20, 5), GPIO_CFG_OUT_1, GPIO_CFG_IN }, // SPI0_SSIN +#endif + { GPIO(20, 2), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // SPI0_SCLK + { GPIO(20, 3), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // SPI0_MOSI + { GPIO(20, 4), GPIO_CFG_FUNC0, GPIO_CFG_IN } // SPI0_MISO +}; + +static const struct boot_interface_pin spi3_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(18, 7), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // SPI3_SSIN +#else + { GPIO(18, 7), GPIO_CFG_OUT_1, GPIO_CFG_IN }, // SPI3_SSIN +#endif + { GPIO(18, 6), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // SPI3_SCLK + { GPIO(18, 4), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // SPI3_MOSI + { GPIO(18, 5), GPIO_CFG_FUNC0, GPIO_CFG_IN } // SPI3_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND + +/* Note: The code in init.c expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi0_boot_interface_pins[] = +{ + { GPIO( 8, 0), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_CEN3 + { GPIO( 8, 1), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_CEN2 + { GPIO( 8, 2), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_CEN1 + { GPIO( 8, 3), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_CEN0 + { GPIO( 8, 4), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_CLE + { GPIO( 8, 5), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_ALE + { GPIO( 8, 6), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_REN + { GPIO( 8, 7), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_WEN + { GPIO(10, 0), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_IO0 + { GPIO( 9, 7), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_IO1 + { GPIO( 9, 6), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_IO2 + { GPIO( 9, 5), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_IO3 + { GPIO( 9, 3), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_IO4 + { GPIO( 9, 2), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_IO5 + { GPIO( 9, 1), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI0_IO6 + { GPIO( 9, 0), GPIO_CFG_FUNC0, GPIO_CFG_IN } // FMI0_IO7 +}; + +/* Note: The code in init.c expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi1_boot_interface_pins[] = +{ + { GPIO(10, 1), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_CEN3 + { GPIO(10, 2), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_CEN2 + { GPIO(10, 3), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_CEN1 + { GPIO(10, 4), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_CEN0 + { GPIO(10, 5), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_CLE + { GPIO(10, 6), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_ALE + { GPIO(10, 7), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_REN + { GPIO(11, 0), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_WEN + { GPIO(12, 0), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_IO0 + { GPIO(12, 1), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_IO1 + { GPIO(11, 7), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_IO2 + { GPIO(11, 6), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_IO3 + { GPIO(11, 4), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_IO4 + { GPIO(11, 3), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_IO5 + { GPIO(11, 2), GPIO_CFG_FUNC0, GPIO_CFG_IN }, // FMI1_IO6 + { GPIO(11, 1), GPIO_CFG_FUNC0, GPIO_CFG_IN } // FMI1_IO7 +}; +#endif /* WITH_HW_BOOTROM_NAND */ + +#endif /* ! __PLATFORM_BOOT_PINS_S5L8940X_H */ diff --git a/platform/s5l8940x/include/platform/boot_pins_s5l8942x.h b/platform/s5l8940x/include/platform/boot_pins_s5l8942x.h new file mode 100644 index 0000000..32b6a24 --- /dev/null +++ b/platform/s5l8940x/include/platform/boot_pins_s5l8942x.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_BOOT_PINS_S5L8942X_H +#define __PLATFORM_BOOT_PINS_S5L8942X_H + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(12, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO(12, 3), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO(12, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO(12, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO(12, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; + +static const struct boot_interface_pin spi3_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(16, 3), GPIO_CFG_FUNC1, GPIO_CFG_DFLT }, // SPI3_SSIN +#else + { GPIO(16, 3), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI3_SSIN +#endif + { GPIO(16, 0), GPIO_CFG_FUNC1, GPIO_CFG_DFLT }, // SPI3_SCLK + { GPIO(16, 1), GPIO_CFG_FUNC1, GPIO_CFG_DFLT }, // SPI3_MOSI + { GPIO(16, 2), GPIO_CFG_FUNC1, GPIO_CFG_DFLT } // SPI3_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND + +/* Note: The code in init.c expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi0_boot_interface_pins[] = +{ + { GPIO(17, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN3 + { GPIO(17, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN2 + { GPIO(17, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN1 + { GPIO(17, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN0 + { GPIO(17, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CLE + { GPIO(17, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_ALE + { GPIO(18, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_REN + { GPIO(18, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_WEN + { GPIO(20, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO0 + { GPIO(20, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO1 + { GPIO(20, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO2 + { GPIO(20, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO3 + { GPIO(18, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO4 + { GPIO(18, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO5 + { GPIO(18, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO6 + { GPIO(18, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI0_IO7 +}; + +/* Note: The code in init.c expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi1_boot_interface_pins[] = +{ + { GPIO(20, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN3 + { GPIO(20, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN2 + { GPIO(20, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN1 + { GPIO(21, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN0 + { GPIO(21, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CLE + { GPIO(21, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_ALE + { GPIO(21, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_REN + { GPIO(21, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_WEN + { GPIO(22, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO0 + { GPIO(22, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO1 + { GPIO(22, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO2 + { GPIO(22, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO3 + { GPIO(22, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO4 + { GPIO(21, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO5 + { GPIO(21, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO6 + { GPIO(21, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI1_IO7 +}; +#endif /* WITH_HW_BOOTROM_NAND */ + +#endif /* ! __PLATFORM_BOOT_PINS_S5L8942X_H */ diff --git a/platform/s5l8940x/include/platform/boot_pins_s5l8947x.h b/platform/s5l8940x/include/platform/boot_pins_s5l8947x.h new file mode 100644 index 0000000..2bd7e6b --- /dev/null +++ b/platform/s5l8940x/include/platform/boot_pins_s5l8947x.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_BOOT_PINS_S5L8947X_H +#define __PLATFORM_BOOT_PINS_S5L8947X_H + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(17, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO(17, 3), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO(17, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO(17, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO(17, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND + +/* Note: The code in init.c expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi0_boot_interface_pins[] = +{ + { GPIO( 5, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN1 + { GPIO( 5, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN0 + { GPIO( 5, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CLE + { GPIO( 5, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_ALE + { GPIO( 5, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_REN + { GPIO( 5, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_WEN + { GPIO( 7, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO0 + { GPIO( 6, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO1 + { GPIO( 6, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO2 + { GPIO( 6, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO3 + { GPIO( 6, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO4 + { GPIO( 6, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO5 + { GPIO( 6, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO6 + { GPIO( 6, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI0_IO7 +}; + +/* Note: The code in init.c expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi1_boot_interface_pins[] = +{ + { GPIO( 7, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN1 + { GPIO( 7, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN0 + { GPIO( 7, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CLE + { GPIO( 7, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_ALE + { GPIO( 7, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_REN + { GPIO( 7, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_WEN + { GPIO( 8, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO0 + { GPIO( 8, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO1 + { GPIO( 8, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO2 + { GPIO( 8, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO3 + { GPIO( 8, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO4 + { GPIO( 8, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO5 + { GPIO( 8, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO6 + { GPIO( 7, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI1_IO7 +}; +#endif /* WITH_HW_BOOTROM_NAND */ + +#endif /* ! __PLATFORM_BOOT_PINS_S5L8947X_H */ diff --git a/platform/s5l8940x/include/platform/gpiodef.h b/platform/s5l8940x/include/platform/gpiodef.h new file mode 100644 index 0000000..338d34d --- /dev/null +++ b/platform/s5l8940x/include/platform/gpiodef.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* S5L8940X specific gpio -> pin mappings */ + +#include +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +#include SUB_PLATFORM_HEADER(gpiodef) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s5l8940x/include/platform/gpiodef_s5l8940x.h b/platform/s5l8940x/include/platform/gpiodef_s5l8940x.h new file mode 100644 index 0000000..77fdd40 --- /dev/null +++ b/platform/s5l8940x/include/platform/gpiodef_s5l8940x.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_S5L8940X_H +#define __PLATFORM_GPIODEF_S5L8940X_H + +/* S5L8940X specific gpio -> pin mappings */ + +#if !SUB_PLATFORM_S5L8940X +#error "Only include for S5L8940X platform" +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_IIC0_SCL GPIO(21, 3) +#define GPIO_IIC0_SDA GPIO(21, 2) +#define GPIO_IIC1_SCL GPIO(21, 5) +#define GPIO_IIC1_SDA GPIO(21, 4) +#define GPIO_IIC2_SCL GPIO(20, 1) +#define GPIO_IIC2_SDA GPIO(20, 0) + +#define GPIO_BOARD_ID0 GPIO(20, 2) +#define GPIO_BOARD_ID1 GPIO(20, 3) +#define GPIO_BOARD_ID2 GPIO(20, 4) +#define GPIO_BOARD_ID3 GPIO( 2, 0) + +#define GPIO_BOOT_CONFIG0 GPIO( 2, 2) +#define GPIO_BOOT_CONFIG1 GPIO( 3, 1) +#define GPIO_BOOT_CONFIG2 GPIO( 3, 4) +#define GPIO_BOOT_CONFIG3 GPIO( 3, 5) + +#define GPIO_REQUEST_DFU1 GPIO( 0, 1) // formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 0, 0) // formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO( 3, 2) +#define GPIO_DFU_STATUS GPIO( 3, 3) + +#define SPI_NOR0 (0) +#define SPI_NOR3 (3) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#define GPIO_SPI3_CS GPIO(GPIO_PAD_SPI, 3) +#else +#define GPIO_SPI0_CS GPIO(20, 5) +#define GPIO_SPI3_CS GPIO(18, 7) +#endif + +#define GPIO_UART1_TXD GPIO( 5, 3) + +#define GPIO_SYSTEM_RESET GPIO(28, 0) + +#endif /* ! __PLATFORM_GPIODEF_S5L8940X_H */ diff --git a/platform/s5l8940x/include/platform/gpiodef_s5l8942x.h b/platform/s5l8940x/include/platform/gpiodef_s5l8942x.h new file mode 100644 index 0000000..b358e1c --- /dev/null +++ b/platform/s5l8940x/include/platform/gpiodef_s5l8942x.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_S5L8942X_H +#define __PLATFORM_GPIODEF_S5L8942X_H + +/* S5L8942X specific gpio -> pin mappings */ + +#if !SUB_PLATFORM_S5L8942X +#error "Only include for S5L8942X platform" +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_IIC0_SCL GPIO( 6, 5) +#define GPIO_IIC0_SDA GPIO( 6, 4) +#define GPIO_IIC1_SCL GPIO( 6, 7) +#define GPIO_IIC1_SDA GPIO( 6, 6) +#define GPIO_IIC2_SCL GPIO(24, 1) +#define GPIO_IIC2_SDA GPIO(24, 0) + +#define GPIO_BOARD_ID0 GPIO(12, 0) +#define GPIO_BOARD_ID1 GPIO(12, 1) +#define GPIO_BOARD_ID2 GPIO(12, 2) +#define GPIO_BOARD_ID3 GPIO( 2, 0) + +#define GPIO_BOOT_CONFIG0 GPIO( 2, 2) +#define GPIO_BOOT_CONFIG1 GPIO( 3, 1) +#define GPIO_BOOT_CONFIG2 GPIO( 3, 4) +#define GPIO_BOOT_CONFIG3 GPIO( 3, 5) + +#define GPIO_REQUEST_DFU1 GPIO( 0, 1) // formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 0, 0) // formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO( 3, 2) +#define GPIO_DFU_STATUS GPIO( 3, 3) + +#define SPI_NOR0 (0) +#define SPI_NOR3 (3) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#define GPIO_SPI3_CS GPIO(GPIO_PAD_SPI, 3) +#else +#define GPIO_SPI0_CS GPIO(12, 3) +#define GPIO_SPI3_CS GPIO(16, 3) +#endif + +#define GPIO_UART1_TXD GPIO( 5, 0) + +#define GPIO_SYSTEM_RESET GPIO(25, 0) + +#endif /* ! __PLATFORM_GPIODEF_S5L8942X_H */ diff --git a/platform/s5l8940x/include/platform/gpiodef_s5l8947x.h b/platform/s5l8940x/include/platform/gpiodef_s5l8947x.h new file mode 100644 index 0000000..f1b2b11 --- /dev/null +++ b/platform/s5l8940x/include/platform/gpiodef_s5l8947x.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_S5L8947X_H +#define __PLATFORM_GPIODEF_S5L8947X_H + +/* S5L8947X specific gpio -> pin mappings */ + +#if !SUB_PLATFORM_S5L8947X +#error "Only include for S5L8947X platform" +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_IIC0_SCL GPIO(17, 1) +#define GPIO_IIC0_SDA GPIO(17, 0) +#define GPIO_IIC1_SCL GPIO( 1, 2) +#define GPIO_IIC1_SDA GPIO( 1, 1) +#define GPIO_IIC2_SCL GPIO( 1, 6) +#define GPIO_IIC2_SDA GPIO( 1, 5) + +#define GPIO_BOARD_ID0 GPIO(17, 3) +#define GPIO_BOARD_ID1 GPIO(17, 4) +#define GPIO_BOARD_ID2 GPIO(17, 5) +#define GPIO_BOARD_ID3 GPIO(14, 0) + +#define GPIO_BOOT_CONFIG0 GPIO(14, 2) +#define GPIO_BOOT_CONFIG1 GPIO(16, 3) +#define GPIO_BOOT_CONFIG2 GPIO(16, 6) +#define GPIO_BOOT_CONFIG3 GPIO(16, 7) + +#define GPIO_REQUEST_DFU1 GPIO(12, 1) // formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO(12, 0) // formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO(16, 4) +#define GPIO_DFU_STATUS GPIO(16, 5) + +#define SPI_NOR0 (0) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#else +#define GPIO_SPI0_CS GPIO(17, 3) +#endif + +#define GPIO_UART1_TXD GPIO( 0, 7) + +#define GPIO_SYSTEM_RESET GPIO( 3, 4) + +#endif /* ! __PLATFORM_GPIODEF_S5L8947X_H */ diff --git a/platform/s5l8940x/include/platform/image_devices.h b/platform/s5l8940x/include/platform/image_devices.h new file mode 100644 index 0000000..970dc02 --- /dev/null +++ b/platform/s5l8940x/include/platform/image_devices.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_firmware", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s5l8940x/include/platform/memconfig.h b/platform/s5l8940x/include/platform/memconfig.h new file mode 100644 index 0000000..f97ba22 --- /dev/null +++ b/platform/s5l8940x/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* S5L8940X SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/s5l8940x/include/platform/memmap.h b/platform/s5l8940x/include/platform/memmap.h new file mode 100644 index 0000000..36e19db --- /dev/null +++ b/platform/s5l8940x/include/platform/memmap.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* + * 0xa0000000 SDRAM_END + * 0x9fffc000 PANIC_BASE + * 0x9ff00000 IBOOT_BASE + * 0x9f000000 DISPLAY_BASE + * 0x9e800000 MONITOR_BASE + */ +/* S5L8940X specific memory map */ +#define SDRAM_BASE (0x80000000ULL) +#define SDRAM_BANK_LEN (0x10000000ULL) +#define SDRAM_BANK_COUNT (2) +#define SDRAM_END (SDRAM_BASE + (SDRAM_BANK_LEN * SDRAM_BANK_COUNT)) +#define VROM_BASE (0x3F000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00010000ULL) +#define SRAM_BASE (0x34000000ULL) +#define SRAM_BANK_LEN (0x00100000ULL) +#define SRAM_LEN (0x00040000ULL) + +/* Sleep token is stored at first physical page in kernel memory */ +#define SLEEP_TOKEN_BUFFER_BASE (SDRAM_BASE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00004000ULL) +#define PANIC_BASE (SDRAM_END - PANIC_SIZE) + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x00100000 - PANIC_SIZE) +#define IBOOT_BASE (PANIC_BASE - IBOOT_SIZE) +#define PROTECTED_REGION_SIZE IBOOT_SIZE + +/* reserved area for display */ +#ifndef DISPLAY_SIZE +#define DISPLAY_SIZE (0x00F00000ULL) +#endif +#define DISPLAY_BASE (IBOOT_BASE - DISPLAY_SIZE) + +/* where to load the monitor/hypervisor */ +#ifdef HACK_MONITOR +#define MONITOR_SIZE (0x00800000ULL) +#else /* !defined(HACK_MONITOR) */ +#define MONITOR_SIZE (0) +#endif /* defined(HACK_MONITOR) */ +#define MONITOR_BASE (DISPLAY_BASE - MONITOR_SIZE) + +/* where to stick the mmu tt, default heap and insecure memory*/ +#if APPLICATION_SECUREROM +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (SRAM_BASE + SRAM_LEN - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN * 3) + +#define STACK_SIZE (0x3000ULL) +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#ifndef __ASSEMBLY__ + +#define INSECURE_MEMORY_BASE (SRAM_BASE) +#define INSECURE_MEMORY_SIZE ((uintptr_t)__segment_start(__DATA) - INSECURE_MEMORY_BASE) + +#endif /* ! __ASSEMBLY__ */ + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (TEXT_BASE + TEXT_FOOTPRINT - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN * 3) +#define MMU_NONCACHE1_SIZE (0x40000000ULL) +#define MMU_NONCACHE1_PBASE (0x80000000ULL) +#define MMU_NONCACHE1_VBASE (0xC0000000ULL) + +#if WITH_DFU_MODE +#define STACK_SIZE (0x3000ULL) + +#define INSECURE_MEMORY_SIZE (0x00200000ULL) +#define INSECURE_MEMORY_BASE (SDRAM_BASE + SDRAM_BANK_LEN - INSECURE_MEMORY_SIZE) + +#define HEAP_EXT_SIZE (0x00100000ULL) +#define HEAP_EXT_BASE (INSECURE_MEMORY_BASE - HEAP_EXT_SIZE) + +#else /* !WITH_DFU_MODE */ +#define STACK_SIZE (0x1000ULL) + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_KERNEL_ADDRESS - SDRAM_BASE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +/* If only 1 bank is populated, this only clears to the alias of + * DISPLAY_BASE in the first bank. If 2 banks are populated, this + * clears all the was to DISPLAY_BASE in the second bank. */ +#define SECURE_MEMORY_SIZE (DISPLAY_BASE - SECURE_MEMORY_BASE - SDRAM_BANK_LEN * 2 + platform_get_memory_size()) + +#define HEAP_EXT_BASE (DEFAULT_FREE_ADDRESS) +#define HEAP_EXT_SIZE (MONITOR_BASE - SDRAM_BANK_LEN - HEAP_EXT_BASE) +#endif /* !WITH_DFU_MODE */ + +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_EMBEDDEDIOP +# if ARCH_ARMv7 +# define MMU_TT_SIZE (0x4000ULL) +# endif + +#define AUDIO_SRAM_RESERVE (0x1000ULL) +#define USB_SRAM_RESERVE (0x10000ULL) + +#if TARGET_S5L8940XAE2 +#define HEAP_EXT_BASE (SRAM_BASE + AUDIO_SRAM_RESERVE) +#define HEAP_EXT_SIZE (SRAM_LEN - AUDIO_SRAM_RESERVE - USB_SRAM_RESERVE) +#endif /* TARGET_S5L8940XAE2 */ + + +#endif /* !APPLICATION_EMBEDDEDIOP */ + +#define SCRATCH_BASE (0x33600000ULL) +#define SCRATCH_LEN (2048) + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s5l8940x/include/platform/pinconfig_s5l8940x.h b/platform/s5l8940x/include/platform/pinconfig_s5l8940x.h new file mode 100644 index 0000000..ffa53ab --- /dev/null +++ b/platform/s5l8940x/include/platform/pinconfig_s5l8940x.h @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_S5L8940X_H +#define __PLATFORM_PINCONFIG_S5L8940X_H + +/* Default S5L8940X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X3 + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY + CFG_IN, // GPIO1 -> HOLD_KEY + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED | PULL_DOWN, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED | PULL_DOWN, // GPIO7 -> + +/* Port 1 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED | PULL_DOWN, // GPIO19 -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED | PULL_DOWN, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + +/* Port 4 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // GPIO39 -> + +/* Port 5 */ + CFG_DISABLED, // EHCI_PORT_PWR[0] -> + CFG_DISABLED, // EHCI_PORT_PWR[1] -> + CFG_DISABLED, // EHCI_PORT_PWR[2] -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + +/* Port 6 */ + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RTXD -> + +/* Port 7 */ + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // UART6_RTSN -> + CFG_DISABLED, // UART6_CTSN -> + CFG_DISABLED, // UART4_TXD/SPI4_MOSI -> + CFG_DISABLED, // UART4_RXD/SPI4_MISO -> + CFG_DISABLED, // UART4_RTSN/SPI4_SCLK -> + CFG_DISABLED, // UART4_CTSN/SPI4_SSIN -> + +/* Port 8 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + +/* Port 9 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO1 -> + +/* Port 10 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + +/* Port 11 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO2 -> + +/* Port 12 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED, // FMI2_CEN3 -> + CFG_DISABLED, // FMI2_CEN2 -> + CFG_DISABLED, // FMI2_CEN1 -> + CFG_DISABLED, // FMI2_CEN0 -> + CFG_DISABLED, // FMI2_CLE -> + CFG_DISABLED, // FMI2_ALE -> + +/* Port 13 */ + CFG_DISABLED, // FMI2_REN -> + CFG_DISABLED, // FMI2_WEN -> + CFG_DISABLED, // FMI2_IO7 -> + CFG_DISABLED, // FMI2_IO6 -> + CFG_DISABLED, // FMI2_IO5 -> + CFG_DISABLED, // FMI2_IO4 -> + CFG_DISABLED, // FMI2_DQS -> + CFG_DISABLED, // FMI2_IO3 -> + +/* Port 14 */ + CFG_DISABLED, // FMI2_IO2 -> + CFG_DISABLED, // FMI2_IO1 -> + CFG_DISABLED, // FMI2_IO0 -> + CFG_DISABLED, // FMI0_CEN7 -> + CFG_DISABLED, // FMI0_CEN6 -> + CFG_DISABLED, // FMI0_CEN5 -> + CFG_DISABLED, // FMI0_CEN4 -> + CFG_DISABLED, // FMI1_CEN7 -> + +/* Port 15 */ + CFG_DISABLED, // FMI1_CEN6 -> + CFG_DISABLED, // FMI1_CEN5 -> + CFG_DISABLED, // FMI1_CEN4 -> + CFG_DISABLED, // FMI3_CEN3 -> + CFG_DISABLED, // FMI3_CEN2 -> + CFG_DISABLED, // FMI3_CEN1 -> + CFG_DISABLED, // FMI3_CEN0 -> + CFG_DISABLED, // FMI3_CLE -> + +/* Port 16 */ + CFG_DISABLED, // FMI3_ALE -> + CFG_DISABLED, // FMI3_REN -> + CFG_DISABLED, // FMI3_WEN -> + CFG_DISABLED, // FMI3_IO7 -> + CFG_DISABLED, // FMI3_IO6 -> + CFG_DISABLED, // FMI3_IO5 -> + CFG_DISABLED, // FMI3_IO4 -> + CFG_DISABLED, // FMI3_DQS -> + +/* Port 17 */ + CFG_DISABLED, // FMI3_IO3 -> + CFG_DISABLED, // FMI3_IO2 -> + CFG_DISABLED, // FMI3_IO1 -> + CFG_DISABLED, // FMI3_IO0 -> + CFG_DISABLED, // FMI2_CEN7 -> + CFG_DISABLED, // FMI2_CEN6 -> + CFG_DISABLED, // FMI2_CEN5 -> + CFG_DISABLED, // FMI2_CEN4 -> + +/* Port 18 */ + CFG_DISABLED, // FMI3_CEN7 -> + CFG_DISABLED, // FMI3_CEN6 -> + CFG_DISABLED, // FMI3_CEN5 -> + CFG_DISABLED, // FMI3_CEN4 -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + +/* Port 19 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 20 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> SPI0_SSIN + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 21 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + +/* Port 22 */ + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SDIO_CLK -> + CFG_DISABLED, // SDIO_CMD -> + CFG_DISABLED, // SDIO_DATA0 -> + CFG_DISABLED, // SDIO_DATA1 -> + CFG_DISABLED, // SDIO_DATA2 -> + CFG_DISABLED, // SDIO_DATA3 -> + +/* Port 23 */ + CFG_DISABLED, // MIPI_VSYNC -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // SWI_DATA -> + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_DO -> + CFG_DISABLED, // DWI_CLK -> + +/* Port 24 */ + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + +/* Port 25 */ + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S2_LRCK -> + +/* Port 26 */ + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + +/* Port 27 */ + CFG_DISABLED, // SPDIF -> + CFG_DISABLED | PULL_DOWN, // GPIO217 -> + CFG_DISABLED, // GPIO218 -> + CFG_DISABLED, // DP_HPD -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 28 */ + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_S5L8940X_H */ diff --git a/platform/s5l8940x/include/platform/pinconfig_s5l8942x.h b/platform/s5l8940x/include/platform/pinconfig_s5l8942x.h new file mode 100644 index 0000000..8579d5d --- /dev/null +++ b/platform/s5l8940x/include/platform/pinconfig_s5l8942x.h @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_S5L8942X_H +#define __PLATFORM_PINCONFIG_S5L8942X_H + +/* Default S5L8942X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X2 +#define FMI_SLEW_RATE SLEW_RATE_SLOW + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY + CFG_IN, // GPIO1 -> HOLD_KEY + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 1 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> KEEPACT + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 3 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + +/* Port 4 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // EHCI_PORT_PWR[0] -> BOARD_REV[0] + CFG_DISABLED, // EHCI_PORT_PWR[1] -> BOARD_REV[1] + CFG_DISABLED, // EHCI_PORT_PWR[2] -> BOARD_REV[2] + +/* Port 5 */ + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + +/* Port 6 */ + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + +/* Port 7 */ + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // UART5_TXD/MIPI_VSYNC -> + CFG_DISABLED, // TMR32_PWM0 + CFG_DISABLED, // TMR32_PWM1 + CFG_DISABLED, // TMR32_PWM2 + +/* Port 8 */ + CFG_DISABLED, // SWI_DATA -> + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_DO -> + CFG_DISABLED, // DWI_CLK -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + +/* Port 9 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_SCLK -> + CFG_DISABLED, // I2S0_DOUT -> + +/* Port 10 */ + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_SCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S2_LRCK -> + +/* Port 11 */ + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + +/* Port 12 */ + CFG_DISABLED, // SPI0_SCLK -> BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 13 */ + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_DISABLED, // UART4_TXD -> SPI3_SCLK/FMI0_CEN7 + CFG_DISABLED, // UART4_RXD -> SPI3_MOSI/FMI0_CEN6 + CFG_DISABLED, // UART4_RTSN -> SPI3_MISO/FMI0_CEN5 + CFG_DISABLED, // UART4_CTSN -> SPI3_SSIN/FMI0_CEN4 + CFG_DISABLED, // SDIO0_DATA3 -> FMI1_CEN7 + CFG_DISABLED, // SDIO0_DATA2 -> FMI1_CEN6 + CFG_DISABLED, // SDIO0_DATA1 -> FMI1_CEN5 + CFG_DISABLED, // SDIO0_DATA0 -> FMI1_CEN4 + +/* Port 17 */ + CFG_DISABLED, // SDIO0_CMD -> + CFG_DISABLED, // SDIO0_CLK -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN3 -> FMI0_RBN0 + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN2 -> FMI0_RBN1 + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + +/* Port 18 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 19 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 20 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN1 -> + +/* Port 21 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO5 -> + +/* Port 22 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 23 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 24 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // UART5_RTXD -> UART5_RXD + CFG_DISABLED, // DP_HPD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 25 */ + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_S5L8942X_H */ diff --git a/platform/s5l8940x/include/platform/pinconfig_s5l8947x.h b/platform/s5l8940x/include/platform/pinconfig_s5l8947x.h new file mode 100644 index 0000000..df58d32 --- /dev/null +++ b/platform/s5l8940x/include/platform/pinconfig_s5l8947x.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_S5L8947X_H +#define __PLATFORM_PINCONFIG_S5L8947X_H + +/* Default S5L8947X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X2 +#define FMI_SLEW_RATE SLEW_RATE_SLOW + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // I2S0_MCK -> + CFG_IN, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // UART1_TXD -> + +/* Port 1 */ + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // HDMI_HPD -> + CFG_DISABLED, // HDMI_CEC -> + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // SPDIF -> + +/* Port 2 */ + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + +/* Port 3 */ + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED | PULL_DOWN, // TST_STPCLK -> + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 4 */ + CFG_DISABLED, // ENET_MDC -> + CFG_DISABLED, // ENET_MDIO -> + CFG_DISABLED, // RMII_CLK -> + CFG_DISABLED, // RMII_RXER -> + CFG_DISABLED, // RMII_TXD[0] -> + CFG_DISABLED, // RMII_CRSDV -> + CFG_DISABLED, // RMII_RXD[0] -> + CFG_DISABLED, // RMII_RXD[1] -> + +/* Port 5 */ + CFG_DISABLED, // RMII_TXD[1] -> + CFG_DISABLED, // RMII_TXEN -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN[1] -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN[0] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + +/* Port 6 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[7] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[6] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[5] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[4] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[3] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[2] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[1] -> + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[0] -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN[1] -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN[0] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[7] -> + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[6] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[5] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[4] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[3] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[2] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[1] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[0] -> + +/* Port 9 */ + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + +/* Port 10 */ + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + +/* Port 11 */ + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + +/* Port 12 */ + CFG_IN, // GPIO0 -> MENU_KEY + CFG_IN, // GPIO1 -> HOLD_KEY + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 13 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 14 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> KEEPACT + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG{2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + +/* Port 17 */ + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> + CFG_DISABLED, // SWI_DATA -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_S5L8947X_H */ diff --git a/platform/s5l8940x/include/platform/soc/chipid.h b/platform/s5l8940x/include/platform/soc/chipid.h new file mode 100644 index 0000000..6c72e67 --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/chipid.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include + +#define rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCFG_FUSE1 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCFG_FUSE2 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rCFG_FUSE3 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x0C)) + +#define rECIDLO (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x10)) +#define rECIDHI (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x14)) + +extern bool chipid_get_ecid_image_personalization_required(void); + +#define CHIPID_SOC_VOLTAGE_LOW (0) +#define CHIPID_SOC_VOLTAGE_MED (1) +#define CHIPID_SOC_VOLTAGE_HIGH (2) +extern u_int32_t chipid_get_soc_voltage(u_int32_t index); + +#define CHIPID_CPU_VOLTAGE_LOW (0) +#define CHIPID_CPU_VOLTAGE_MED (1) +#define CHIPID_CPU_VOLTAGE_HIGH (2) +extern u_int32_t chipid_get_cpu_voltage(u_int32_t index); + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s5l8940x/include/platform/soc/display.h b/platform/s5l8940x/include/platform/soc/display.h new file mode 100644 index 0000000..3d82ea4 --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/display.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables +static struct adfe_v1_tuneable adfe_tuneables[] = +{ + { + .name = "default", + .disp_dpcclkcntl[0] = 0, + .disp_dpbclklvl_clock_off_level[0] = DPBCLKLVL_OFFLVL(0x01f0), + .disp_dpbclklvl_clock_on_level[0] = DPBCLKLVL_ONLVL(0x0180), + .disp_dpusrcstrd[0] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpcqoscnfg[0] = (DPCQOSCNFG_QOS_TIMER(0x0040) | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[0] = DPBQOSLVL_MED_WATERMARK(0x0100), + .disp_dpbqoslvl_high_watermark[0] = DPBQOSLVL_HIGH_WATERMARK(0x0000), + .disp_dpureqcfg[0] = 0, + + .disp_dpcclkcntl[1] = 0, + .disp_dpbclklvl_clock_off_level[1] = DPBCLKLVL_OFFLVL(0x01f0), + .disp_dpbclklvl_clock_on_level[1] = DPBCLKLVL_ONLVL(0x01c0), + .disp_dpusrcstrd[1] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpcqoscnfg[1] = (DPCQOSCNFG_QOS_TIMER(0x0040) | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[1] = DPBQOSLVL_MED_WATERMARK(0x0100), + .disp_dpbqoslvl_high_watermark[1] = DPBQOSLVL_HIGH_WATERMARK(0x0000), + .disp_dpureqcfg[1] = 0, + }, +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/s5l8940x/include/platform/soc/display_timings.h b/platform/s5l8940x/include/platform/soc/display_timings.h new file mode 100644 index 0000000..3b7938e --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/display_timings.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_K93 || SUB_TARGET_K94 || SUB_TARGET_K95 || SUB_TARGET_K93A + { + .display_name = "k48", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 68400000, + .dot_pitch = 132, + .h_active = 1024, + .h_pulse_width = 135, + .h_back_porch = 133, + .h_front_porch = 133, + .v_active = 768, + .v_pulse_width = 12, + .v_back_porch = 10, + .v_front_porch = 10, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 18, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_N94 + { + .display_name = "n94", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 51300000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 73, + .h_back_porch = 71, + .h_front_porch = 71, + .v_active = 960, + .v_pulse_width = 16, + .v_back_porch = 12, + .v_front_porch = 12, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, + + { + .display_name = "n94-2", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 51300000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 73, + .h_back_porch = 71, + .h_front_porch = 71, + .v_active = 960, + .v_pulse_width = 16, + .v_back_porch = 12, + .v_front_porch = 12, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, + + { + .display_name = "d300", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 60350000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 48, + .h_back_porch = 48, + .h_front_porch = 48, + .v_active = 960, + .v_pulse_width = 3, + .v_back_porch = 13, + .v_front_porch = 307, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_P105 || SUB_TARGET_P106 || SUB_TARGET_P107 + { + .display_name = "ipad2b", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 68400000, + .dot_pitch = 163, + .h_active = 768, + .h_pulse_width = 80, + .h_back_porch = 76, + .h_front_porch = 76, + .v_active = 1024, + .v_pulse_width = 40, + .v_back_porch = 38, + .v_front_porch = 38, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 18, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, + + { + .display_name = "ipad2b-p0", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 68400000, + .dot_pitch = 163, + .h_active = 768, + .h_pulse_width = 80, + .h_back_porch = 113, + .h_front_porch = 113, + .v_active = 1024, + .v_pulse_width = 18, + .v_back_porch = 10, + .v_front_porch = 10, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 18, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || WITH_HW_DISPLAY_DISPLAYPORT + { + .display_name = "720p", + .host_clock_id = CLK_VCLK1, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 220, + .h_front_porch = 110, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 20, + .v_front_porch = 5, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_DP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_N78 + { + .display_name = "n41", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 68400000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 40, + .h_back_porch = 40, + .h_front_porch = 40, + .v_active = 1136, + .v_pulse_width = 3, + .v_back_porch = 13, + .v_front_porch = 348, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || WITH_HW_DISPLAY_HDMI + { + .display_name = "720p-hdmi", + .host_clock_id = CLK_VCLK1, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 220, + .h_front_porch = 110, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 20, + .v_front_porch = 5, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_HDMI, + .display_config = NULL, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/s5l8940x/include/platform/soc/hwclocks.h b/platform/s5l8940x/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..8f9a6e6 --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/hwclocks.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#if SUB_PLATFORM_S5L8947X +#define OSC_FREQ (7500000UL) +#else +#define OSC_FREQ (5000000UL) +#endif +#else +#define OSC_FREQ (24000000UL) +#endif + +#define CLK_FCLK (HWCLOCK_BASE+0) +#define CLK_ACLK (HWCLOCK_BASE+1) +#define CLK_HCLK (HWCLOCK_BASE+2) +#define CLK_PCLK (HWCLOCK_BASE+3) +#define CLK_VCLK0 (HWCLOCK_BASE+4) +#define CLK_VCLK1 (HWCLOCK_BASE+5) +#define CLK_MCLK (HWCLOCK_BASE+6) +#define CLK_NCLK (HWCLOCK_BASE+7) +#define CLK_USBPHYCLK (HWCLOCK_BASE+8) +#define CLK_NCOREF (HWCLOCK_BASE+9) +#define CLK_FMI (HWCLOCK_BASE+10) + +/* S5L8940X clock gate devices */ +enum { + CLK_CPU0 = 0, + CLK_CPU1, + CLK_SCU, + CLK_L2RAM0, + CLK_L2RAM1, + CLK_CPU_REGS, + CLK_MCU, + CLK_GFX_SYS, + CLK_GFX_CORES, + CLK_HPERFNRT, + CLK_VDEC, + CLK_SCALER0, + CLK_SCALER1, + CLK_JPG, + CLK_VENCD, + CLK_HPERFRT, + CLK_ISP, + CLK_resv0, + CLK_resv1, + CLK_DISP0, + CLK_DISP1, + CLK_DISPOUT, + CLK_MIPI, + CLK_CLCD, + CLK_TVDAC, + CLK_RGBOUT, + CLK_DPLINK, + CLK_CDIO, + CLK_CDMA, + CLK_IOP, + CLK_UPERF, + CLK_USBOTG, + CLK_USB20, + CLK_USB11, + CLK_USBOHCI0, + CLK_USBOHCI1, + CLK_USBPHY, + CLK_AUDIO, + CLK_I2S0, + CLK_I2S1, + CLK_I2S2, + CLK_I2S3, + CLK_SPDIF, + CLK_HPARK, + CLK_SDIO, + CLK_SHA1, + CLK_SHA2, + CLK_FMI0, + CLK_FMI0BCH, + CLK_FMI1, + CLK_FMI1BCH, + CLK_FMI2, + CLK_FMI2BCH, + CLK_FMI3, + CLK_FMI3BCH, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_SPI4, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_PKE, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_PWM, + CLK_SCRT, + CLK_GPIO, + CLK_SWI, + CLK_DWI, + CLK_DEBUG, + CLK_AIC, +#if SUB_PLATFORM_S5L8947X + CLK_MCA0, + CLK_ETH, + CLK_HDMI, + CLK_ADC, + CLK_USBOTG1, + CLK_USB20_1, + CLK_USBOHCI0_1, + CLK_USBREG1, +#endif +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s5l8940x/include/platform/soc/hwdmachannels.h b/platform/s5l8940x/include/platform/soc/hwdmachannels.h new file mode 100644 index 0000000..a23ccdd --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/hwdmachannels.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_H +#define __PLATFORM_SOC_HWDMACHANNELS_H + +#include + +#include SUB_PLATFORM_HEADER(soc/hwdmachannels) + +#define DMA_SDIO_TIMEOUT_US (10 * 1000) + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_H */ diff --git a/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8940x.h b/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8940x.h new file mode 100644 index 0000000..dfadc5b --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8940x.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_S5L8940X_H +#define __PLATFORM_SOC_HWDMACHANNELS_S5L8940X_H + +#define DMA_MEMORY_TX (1) +#define DMA_MEMORY_RX (2) +#define DMA_SDIO (3) +#define DMA_FMI0DATA (5) +#define DMA_FMI0CHECK (6) +#define DMA_FMI1DATA (7) +#define DMA_FMI1CHECK (8) +#define DMA_FMI2DATA (9) +#define DMA_FMI2CHECK (10) +#define DMA_FMI3DATA (11) +#define DMA_FMI3CHECK (12) + +#define DMA_CHANNEL_COUNT (44) + +#define DMA_CHANNEL_CONFIG \ +{ \ + /* low high AES OK reqID FIFO address */ \ + { 3, 4, false, 0x00, 0x30000020 }, \ + { 3, 4, false, 0x01, 0x301000A0 }, \ + { 3, 4, false, 0x01, 0x30200020 }, \ + { 5, 12, true, 0x00, 0x31200014 }, \ + { 5, 12, true, 0x01, 0x31200018 }, \ + { 5, 12, true, 0x02, 0x31300014 }, \ + { 5, 12, true, 0x03, 0x31300018 }, \ + { 5, 12, true, 0x04, 0x31400014 }, \ + { 5, 12, true, 0x05, 0x31400018 }, \ + { 5, 12, true, 0x06, 0x31500014 }, \ + { 5, 12, true, 0x07, 0x31500018 }, \ +} + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_S5L8940X_H */ diff --git a/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8942x.h b/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8942x.h new file mode 100644 index 0000000..b33098a --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8942x.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_S5L8942X_H +#define __PLATFORM_SOC_HWDMACHANNELS_S5L8942X_H + +#define DMA_MEMORY_TX (1) +#define DMA_MEMORY_RX (2) +#define DMA_SDIO (3) +#define DMA_FMI0DATA (5) +#define DMA_FMI0CHECK (6) +#define DMA_FMI1DATA (7) +#define DMA_FMI1CHECK (8) + +#define DMA_CHANNEL_COUNT (42) + +#define DMA_CHANNEL_CONFIG \ +{ \ + /* low high AES OK reqID FIFO address */ \ + { 3, 4, false, 0x00, 0x30000010 }, \ + { 3, 4, false, 0x00, 0x30000020 }, \ + { 3, 4, false, 0x01, 0x301000A0 }, \ + { 3, 4, false, 0x01, 0x30200020 }, \ + { 5, 8, true, 0x00, 0x31200014 }, \ + { 5, 8, true, 0x01, 0x31200018 }, \ + { 5, 8, true, 0x02, 0x31300014 }, \ + { 5, 8, true, 0x03, 0x31300018 }, \ +} + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_S5L8942X_H */ diff --git a/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8947x.h b/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8947x.h new file mode 100644 index 0000000..3ee4fe8 --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/hwdmachannels_s5l8947x.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_S5L8947X_H +#define __PLATFORM_SOC_HWDMACHANNELS_S5L8947X_H + +#define DMA_MEMORY_TX (1) +#define DMA_MEMORY_RX (2) +#define DMA_FMI0DATA (5) +#define DMA_FMI0CHECK (6) +#define DMA_FMI1DATA (7) +#define DMA_FMI1CHECK (8) + +#define DMA_CHANNEL_COUNT (42) + +#define DMA_CHANNEL_CONFIG \ +{ \ + /* low high AES OK reqID FIFO address */ \ + { 3, 4, false, 0x00, 0x30000010 }, \ + { 3, 4, false, 0x00, 0x30000020 }, \ + { 3, 4, false, 0x01, 0x301000A0 }, \ + { 3, 4, false, 0x01, 0x30200020 }, \ + { 5, 8, true, 0x00, 0x31200014 }, \ + { 5, 8, true, 0x01, 0x31200018 }, \ + { 5, 8, true, 0x02, 0x31300014 }, \ + { 5, 8, true, 0x03, 0x31300018 }, \ +} + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_S5L8947X_H */ diff --git a/platform/s5l8940x/include/platform/soc/hwisr.h b/platform/s5l8940x/include/platform/soc/hwisr.h new file mode 100644 index 0000000..06ed4bc --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/hwisr.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_SWI 5 // SWI Interrupt +#define INT_DWI 6 // DWI Interrupt +#define INT_ISP0 7 // ISP 0 Interrupt +#define INT_ISP1 8 // ISP 1 Interrupt +#define INT_SCALER0 9 // Scaler Interrupt +#define INT_SCALER1 10 // Scaler Interrupt +#define INT_USB_OTG 11 // USB OTG Interrupt +#define INT_USB_EHCI 12 // USB EHCI Interrupt +#define INT_USB_OHCI0 13 // USB OHCI 0 Interrupt +#define INT_USB_OHCI1 14 // USB OHCI 1 Interrupt +#define INT_USB_RES 15 // USB PHY Interrupt +#define INT_PWM 16 // PWM Interrupt +#define INT_PKE 17 // PKE Interrupt +#define INT_IIC0 18 // I2C 0 Interrupt +#define INT_IIC1 19 // I2C 1 Interrupt +#define INT_IIC2 20 // I2C 2 Interrupt +#define INT_UART0 21 // UART 0 Interrupt +#define INT_UART1 22 // UART 1 Interrupt +#define INT_UART2 23 // UART 2 Interrupt +#define INT_UART3 24 // UART 3 Interrupt +#define INT_UART4 25 // UART 4 Interrupt +#define INT_UART5 26 // UART 5 Interrupt +#if SUB_PLATFORM_S5L8947X +#define INT_ETH 27 // Ethernet Interrupt +#else +#define INT_UART6 27 // UART 6 Interrupt +#endif +#define INT_SPI0 28 // SPI 0 Interrupt +#define INT_SPI1 29 // SPI 1 Interrupt +#define INT_SPI2 30 // SPI 2 Interrupt +#define INT_SPI3 31 // SPI 3 Interrupt +#if SUB_PLATFORM_S5L8947X +#define INT_USB_DEV_RES 32 // USB PHY1 Interrupt +#else +#define INT_SPI4 32 // SPI 4 Interrupt +#endif +#define INT_FMI0 33 // FMI 0 Interrupt +#define INT_FMI1 34 // FMI 1 Interrupt +#if SUB_PLATFORM_S5L8947X +#define INT_USB_DEV_OTG 35 // USB OTG1 Interrupt +#define INT_USB_DEV_EHCI 36 // USB EHCI1 Interrupt +#else +#define INT_FMI2 35 // FMI 2 Interrupt +#define INT_FMI3 36 // FMI 3 Interrupt +#endif +#define INT_SHA1 37 // SHA-1 Interrupt +#define INT_SHA2 38 // SHA-1 Interrupt +#define INT_WIFI 39 // WiFi Interrupt +#define INT_TVOUT 40 // TV Out Interrupt +#define INT_MIPI_DSI 41 // MIPI DSI Interrupt +#define INT_CLCD 42 // CLCD Interrupt +#define INT_DISP0 43 // Display Pipe 0 Interrupt +#define INT_DISP1 44 // Display Pipe 1 Interrupt +#define INT_RGBOUT 45 // RGB Out Interrupt +#if SUB_PLATFORM_S5L8947X +#define INT_HDMI_LINK 46 // HDMI link Interrupt +#define INT_HDMI_CEC 47 // HDMI cec Interrupt +#else +#define INT_DPORT0 46 // DisplayPort 0 Interrupt +#define INT_DPORT1 47 // DisplayPort 1 Interrupt +#endif +#define INT_VENC 48 // Video Encoder Interrupt +#define INT_SGX 49 // SGX Interrupt +#define INT_VDEC 50 // Video Decoder Interrupt +#define INT_CDMA_DMAC1 51 // CDMA DMA Channel 1 Interrupt +#define INT_CDMA_DMAC2 52 // CDMA DMA Channel 2 Interrupt +#define INT_CDMA_DMAC3 53 // CDMA DMA Channel 3 Interrupt +#define INT_CDMA_DMAC4 54 // CDMA DMA Channel 4 Interrupt +#define INT_CDMA_DMAC5 55 // CDMA DMA Channel 5 Interrupt +#define INT_CDMA_DMAC6 56 // CDMA DMA Channel 6 Interrupt +#define INT_CDMA_DMAC7 57 // CDMA DMA Channel 7 Interrupt +#define INT_CDMA_DMAC8 58 // CDMA DMA Channel 8 Interrupt +#define INT_CDMA_DMAC9 59 // CDMA DMA Channel 9 Interrupt +#define INT_CDMA_DMAC10 60 // CDMA DMA Channel 10 Interrupt +#define INT_CDMA_DMAC11 61 // CDMA DMA Channel 11 Interrupt +#define INT_CDMA_DMAC12 62 // CDMA DMA Channel 12 Interrupt +#define INT_CDMA_DMAC13 63 // CDMA DMA Channel 13 Interrupt +#define INT_CDMA_DMAC14 64 // CDMA DMA Channel 14 Interrupt +#define INT_CDMA_DMAC15 65 // CDMA DMA Channel 15 Interrupt +#define INT_CDMA_DMAC16 66 // CDMA DMA Channel 16 Interrupt +#define INT_CDMA_DMAC17 67 // CDMA DMA Channel 17 Interrupt +#define INT_CDMA_DMAC18 68 // CDMA DMA Channel 18 Interrupt +#define INT_CDMA_DMAC19 69 // CDMA DMA Channel 19 Interrupt +#define INT_CDMA_DMAC20 70 // CDMA DMA Channel 20 Interrupt +#define INT_CDMA_DMAC21 71 // CDMA DMA Channel 21 Interrupt +#define INT_CDMA_DMAC22 72 // CDMA DMA Channel 22 Interrupt +#define INT_CDMA_DMAC23 73 // CDMA DMA Channel 23 Interrupt +#define INT_CDMA_DMAC24 74 // CDMA DMA Channel 24 Interrupt +#define INT_CDMA_DMAC25 75 // CDMA DMA Channel 25 Interrupt +#define INT_CDMA_DMAC26 76 // CDMA DMA Channel 26 Interrupt +#define INT_CDMA_DMAC27 77 // CDMA DMA Channel 27 Interrupt +#define INT_CDMA_DMAC28 78 // CDMA DMA Channel 28 Interrupt +#define INT_CDMA_DMAC29 79 // CDMA DMA Channel 29 Interrupt +#define INT_CDMA_DMAC30 80 // CDMA DMA Channel 30 Interrupt +#define INT_CDMA_DMAC31 81 // CDMA DMA Channel 31 Interrupt +#define INT_CDMA_DMAC32 82 // CDMA DMA Channel 32 Interrupt +#define INT_CDMA_DMAC33 83 // CDMA DMA Channel 33 Interrupt +#define INT_CDMA_DMAC34 84 // CDMA DMA Channel 34 Interrupt +#define INT_CDMA_DMAC35 85 // CDMA DMA Channel 35 Interrupt +#define INT_CDMA_DMAC36 86 // CDMA DMA Channel 36 Interrupt +#define INT_CDMA_DMAC37 87 // CDMA DMA Channel 37 Interrupt +#define INT_CDMA_DMAC38 88 // CDMA DMA Channel 38 Interrupt +#define INT_CDMA_DMAC39 89 // CDMA DMA Channel 39 Interrupt +#define INT_CDMA_DMAC40 90 // CDMA DMA Channel 40 Interrupt +#define INT_CDMA_DMAC41 91 // CDMA DMA Channel 41 Interrupt +#define INT_CDMA_DMAC42 92 // CDMA DMA Channel 42 Interrupt +#define INT_CDMA_DMAC43 93 // CDMA DMA Channel 43 Interrupt +#define INT_CDMA_DMAC44 94 // CDMA DMA Channel 44 Interrupt + +// Reserved 95 - 96 + +// Audio and Highland Park Interrupts 97 - 115 + +#define INT_AUDIO_CPU_IRQ0 97 // +#define INT_AUDIO_CPU_IRQ1 98 // + +#define INT_HPERFNRT_DART 116 // HPerf-NRT DART Interrupt +#define INT_HPERFRT_DART 117 // HPerf-RT DART Interrupt +#define INT_JPG 118 // JPEG Interrupt +#define INT_GPIO0 119 // GPIO 0 Interrupt +#define INT_GPIO1 120 // GPIO 1 Interrupt +#define INT_MCU 121 // MCU 0 Interrupt +#define INT_MCU0 122 // MCU 0 Interrupt +#define INT_MCU1 123 // MCU 1 Interrupt +#define INT_PIO0 124 // PIO 0 Interrupt +#define INT_PIO1 125 // PIO 1 Interrupt + +// Reserved 126 + +#define INT_IOP_COMMRX 127 // IOP CommRx Interrupt +#define INT_IOP_COMMTX 128 // IOP CommTx Interrupt +#define INT_IOP_PMI 129 // IOP PerfMon Interrupt +#define INT_IOP_CTIIRQ 130 // IOP CTIIRQ Interrupt +#define INT_ISP_COMMRX 131 // IOP CommRx Interrupt +#define INT_ISP_COMMTX 132 // IOP CommTx Interrupt +#define INT_ISP_PMI 133 // IOP PerfMon Interrupt +#define INT_ISP_CTIIRQ 134 // IOP CTIIRQ Interrupt + +#define INT_CPU0_PMI 135 // IOP Perfmon Interrupt +#define INT_CPU0_CTIIRQ 136 // IOP CTI Interrupt +#define INT_CPU0_COMMRX 137 // IOP CommRx Interrupt +#define INT_CPU0_COMMTX 138 // IOP CommTx Interrupt +#define INT_CPU1_PMI 139 // IOP PMI Interrupt +#define INT_CPU1_CTIIRQ 140 // IOP CTI Interrupt +#define INT_CPU1_COMMRX 141 // IOP CommRx Interrupt +#define INT_CPU1_COMMTX 142 // IOP CommTx Interrupt + +#define INT_L2C 143 // PL310 Interrupt + +// Reserved 144 - 151 + +#define INT_PMGR_PMI 152 // PMGR PerfMon Interrupt +#define INT_HPERFNTR_PMI 153 // HPerf-NRT PerfMon Interrupt +#define INT_HPERFRT_PMI 154 // HPerf-RT PerfMon Interrupt +#define INT_DPIPE0_PMI 155 // Display Pipe 0 PerfMon Interrupt +#define INT_DPIPE1_PMI 156 // Display Pipe 1 PerfMon Interrupt + +// Reserved 157 - 159 + +#define INT_ETB_FULL 160 // ETB Full Interrupt + +#if PLATFORM_VARIANT_IOP + +#include + +#define INT_HOST INT_SW2 // Host processor doorbell +#define INT_IOP INT_SW3 // I/O coprocessor doorbell +#define INT_IOP_NMI kAIC_VEC_SW_TMR // I/O coprocessor NMI + +#elif PLATFORM_VARIANT_AUDIO + +#include + +#define INT_HOST AE2_INT_SW0 // Host processor doorbell +#define INT_IOP AE2_INT_SW0 // I/O coprocessor doorbell +#define INT_IOP_NMI AE2_INT_SW1 // I/O coprocessor NMI + +#endif + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s5l8940x/include/platform/soc/hwregbase.h b/platform/s5l8940x/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..4472db6 --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/hwregbase.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +/* S5L8940X/S5L8942X/S5L8947X Reg Base Defs */ + +#define AIC_VERSION 0 +#define AIC_INT_COUNT (192) +#define PMGR_WDG_VERSION 0 + +#if !SUB_PLATFORM_S5L8947X +#define SDIO_BASE_ADDR (0x30000000) + +#define SHA1_BASE_ADDR (0x30100000) +#endif + +#define SHA2_BASE_ADDR (0x30200000) + +#define FMI0_BASE_ADDR (0x31200000) +#define FMI1_BASE_ADDR (0x31300000) +#define FMI2_BASE_ADDR (0x31400000) +#define FMI3_BASE_ADDR (0x31500000) +#define FMI_VERSION (3) +#if !SUB_PLATFORM_S5L8940X +#define FMI_VERSION_MINOR (1) +#endif // SUB_PLATFORM_S5L8942X + +#if !SUB_PLATFORM_S5L8947X +#define SPI0_BASE_ADDR (0x32000000) +#define SPI1_BASE_ADDR (0x32100000) +#define SPI2_BASE_ADDR (0x32200000) +#define SPI3_BASE_ADDR (0x32300000) +#define SPI4_BASE_ADDR (0x32400000) +#define SPI_VERSION (1) +#define SPIS_COUNT (5) +#else +#define SPI0_BASE_ADDR (0x32000000) +#define SPI_VERSION (1) +#define SPIS_COUNT (1) + +#define ADC_BASE_ADDR (0x32100000) +#endif + +#define UART_VERSION (1) +#define UART0_BASE_ADDR (0x32500000) +#define UART1_BASE_ADDR (0x32600000) +#define UART2_BASE_ADDR (0x32700000) +#define UART3_BASE_ADDR (0x32800000) +#define UART4_BASE_ADDR (0x32900000) +#if SUB_PLATFORM_S5L8947X +#define UARTS_COUNT (5) +#elif SUB_PLATFORM_S5L8942X +#define UART5_BASE_ADDR (0x32A00000) +#define UARTS_COUNT (6) +#elif SUB_PLATFORM_S5L8940X +#define UART5_BASE_ADDR (0x32A00000) +#define UART6_BASE_ADDR (0x32B00000) +#define UARTS_COUNT (7) +#endif + +#define PKE_BASE_ADDR (0x33100000) + +#define IIC_BASE_ADDR (0x33200000) +#define IIC_SPACING (0x00100000) +#define IICS_COUNT (3) + +#define AUDIO_BASE_ADDR (0x34000000) + +#define USBPHY_BASE_ADDR (0x36000000) +#if SUB_PLATFORM_S5L8940X +#define USBPHY_VERSION (3) +#else +#define USBPHY_VERSION (4) +#endif + +#define USBOTG_BASE_ADDR (0x36100000) +#define UPERF_WIDGETS_BASE_ADDR (0x36E00000) +#define UPERF_PL301_BASE_ADDR (0x36F00000) + +#define CDMA_BASE_ADDR (0x37000000) +#define CDMA_VERSION 3 + +#if !SUB_PLATFORM_S5L8947X +#define VENC_BASE_ADDR (0x38000000) +#endif + +#define VDEC_BASE_ADDR (0x38100000) + +#define JPEG_BASE_ADDR (0x38200000) + +#define SCALER_BASE_ADDR (0x38300000) +#define SCALER_SPACING (0x00100000) + +#define NRT_DART_BASE_ADDR (0x38B00000) +#define NRT_DART_WIDGETS_BASE_ADDR (0x38C00000) +#define NRT_DART_PL301_BASE_ADDR (0x38D00000) +#define NRT_TOP_WIDGETS_BASE_ADDR (0x38E00000) +#define NRT_TOP_PL301_BASE_ADDR (0x38F00000) + +#define CLCD_BASE_ADDR (0x39200000) +#define CLCD_VERSION (0) +#define CLCD_DITHER_BASE_ADDR (0x39300000) +#define DITHER_VERSION (1) + +#define TVOUT_BASE_ADDR (0x39400000) + +#if !SUB_PLATFORM_S5L8947X +#define DSIM_BASE_ADDR (0x39500000) +#define DSIM_LANE_COUNT (4) +#define DSIM_VERSION (1) +#endif + +#define RGBOUT_BASE_ADDR (0x39600000) + +#if !SUB_PLATFORM_S5L8947X +#define DP_BASE_ADDR (0x39700000) +#define DISPLAYPORT_VERSION (1) +#else +#define HDMI_BASE_ADDR (0x39700000) +#define DPBDITHER_BASE_ADDR (0x39800000) +#endif + +#if !SUB_PLATFORM_S5L8947X +#define ISP_BASE_ADDR (0x3A000000) + +#define DISP0_BASE_ADDR (0x3A100000) +#define CLCD_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#endif +#define DISP1_BASE_ADDR (0x3A200000) +#define RGBOUT_DISPLAYPIPE_BASE_ADDR (DISP1_BASE_ADDR) +#define DISP_VERSION (3) + +#if !SUB_PLATFORM_S5L8947X +#define RT_DART_BASE_ADDR (0x3A400000) +#endif +#define RT_TOP_WIDGETS_BASE_ADDR (0x3A500000) +#define RT_TOP_PL301_BASE_ADDR (0x3A600000) + +#if SUB_PLATFORM_S5L8947X +#define ETHERNET_BASE_ADDR (0x3B000000) +#else +#define HP_BASE_ADDR (0x3B000000) +#endif + +#if SUB_PLATFORM_S5L8947X +#define AMP_BASE_ADDR (0x3D000000) +#define AMP_SPACING (0x00100000) +#else +#define AMG_BASE_ADDR (0x3D000000) +#define AMG_SPACING (0x00100000) +#endif + +#define PL310_BASE_ADDR (0x3E000000) +#define SCU_BASE_ADDR (0x3E100000) + +#define PMGR_BASE_ADDR (0x3F100000) +#define AIC_BASE_ADDR (0x3F200000) + +#define IOP_BASE_ADDR (0x3F300000) + +#define ROSC_BASE_ADDR (0x3F400000) +#define ROSC_MASK (0x57FF) +#define ROSC_WITH_CLOCK (0) + +#define CHIPID_BASE_ADDR (0x3F500000) + +#define SWI_BASE_ADDR (0x3F600000) +#if !SUB_PLATFORM_S5L8947X +#define DWI_BASE_ADDR (0x3F700000) +#endif + +#define AMC_BASE_ADDR (0x3F800000) + +#define GPIO_BASE_ADDR (0x3FA00000) +#define GPIO_VERSION (1) +#if SUB_PLATFORM_S5L8940X +#define GPIO_GROUP_COUNT (29) +#elif SUB_PLATFORM_S5L8942X +#define GPIO_GROUP_COUNT (26) +#elif SUB_PLATFORM_S5L8947X +#define GPIO_GROUP_COUNT (18) +#endif +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define PIO_BASE_ADDR (0x3FB00000) +#define PIO_SPACING (0x00100000) + +#define CIF_BASE_ADDR (0x3FD00000) + +#define CDIO_WIDGETS_BASE_ADDR (0x3FE00000) +#define CDIO_PL301_BASE_ADDR (0x3FF00000) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s5l8940x/include/platform/soc/miu.h b/platform/s5l8940x/include/platform/soc/miu.h new file mode 100644 index 0000000..b4bffeb --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/miu.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rREMAP_CTL (*(volatile u_int32_t *)(PIO_BASE_ADDR + 0x0000)) + +#define rPL310_CONTROL (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x0100)) +#define rPL310_INVAL_WAY (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x077C)) +#define rPL310_FILTER_START (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x0C00)) +#define rPL310_FILTER_END (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x0C04)) + +#define rSCU_CONTROL (*(volatile u_int32_t *)(SCU_BASE_ADDR + 0x0000)) +#define rSCU_POWER_STATUS (*(volatile u_int32_t *)(SCU_BASE_ADDR + 0x0008)) +#define rSCU_TAG_INVAL (*(volatile u_int32_t *)(SCU_BASE_ADDR + 0x000C)) + +#define rCIF_CONTROL (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0000)) +#define rCIF_CLKGATE (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0004)) +#define rCIF_RTLIMIT (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0008)) +#define rCIF_WTLIMIT (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x000C)) +#define rCIF_IDLETMR (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0010)) +#define rCIF_RDREMAP (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0040)) +#define rCIF_WRREMAP (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0044)) + +#define CDIO_IOP_RTLIMIT (0x0008) +#define rCDIO_IOP_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RTLIMIT)) +#define CDIO_IOP_WTLIMIT (0x000C) +#define rCDIO_IOP_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WTLIMIT)) +#define CDIO_IOP_WREQSP (0x001C) +#define rCDIO_IOP_WREQSP (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WREQSP)) +#define CDIO_CDMA_RTLIMIT (0x0028) +#define rCDIO_CDMA_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_RTLIMIT)) +#define CDIO_CDMA_WTLIMIT (0x002C) +#define rCDIO_CDMA_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WTLIMIT)) +#define CDIO_CDMA_WGATHER (0x0030) +#define rCDIO_CDMA_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WGATHER)) +#define CDIO_UPERF_RTLIMIT (0x0048) +#define rCDIO_UPERF_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_RTLIMIT)) +#define CDIO_UPERF_WTLIMIT (0x004C) +#define rCDIO_UPERF_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WTLIMIT)) +#define CDIO_UPERF_WGATHER (0x0050) +#define rCDIO_UPERF_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WGATHER)) +#define CDIO_AUDIO_RTLIMIT (0x0068) +#define rCDIO_AUDIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_RTLIMIT)) +#define CDIO_AUDIO_WTLIMIT (0x006C) +#define rCDIO_AUDIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WTLIMIT)) +#define CDIO_AUDIO_WGATHER (0x0070) +#define rCDIO_AUDIO_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WGATHER)) +#define CDIO_PIO_RTLIMIT (0x00A8) +#define rCDIO_PIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_RTLIMIT)) +#define CDIO_PIO_WTLIMIT (0x00AC) +#define rCDIO_PIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_WTLIMIT)) + +#define CDIO_AR_CHAN_ARB_MI0 (0x0408) +#define rCDIO_AR_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI0)) +#define CDIO_AW_CHAN_ARB_MI0 (0x040C) +#define rCDIO_AW_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI0)) +#define CDIO_AR_CHAN_ARB_MI1 (0x0428) +#define rCDIO_AR_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI1)) +#define CDIO_AW_CHAN_ARB_MI1 (0x042C) +#define rCDIO_AW_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI1)) + +#define UPERF_OTG_QOS (0x0014) +#define rUPERF_OTG_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_QOS)) +#define UPERF_OTG_CACHE (0x0018) +#define rUPERF_OTG_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_CACHE)) +#define UPERF_EHCI_QOS (0x0034) +#define rUPERF_EHCI_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_QOS)) +#define UPERF_EHCI_CACHE (0x0038) +#define rUPERF_EHCI_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_CACHE)) +#define UPERF_OHCI0_QOS (0x0054) +#define rUPERF_OHCI0_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_QOS)) +#define UPERF_OHCI0_CACHE (0x0058) +#define rUPERF_OHCI0_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_CACHE)) +#define UPERF_OHCI1_QOS (0x0074) +#define rUPERF_OHCI1_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_QOS)) +#define UPERF_OHCI1_CACHE (0x0078) +#define rUPERF_OHCI1_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_CACHE)) + +#define HPERF_NRT_DART_DART_RTLIMIT (0x0004) +#define rHPERF_NRT_DART_DART_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_RTLIMIT)) +#define HPERF_NRT_DART_DART_WTLIMIT (0x0008) +#define rHPERF_NRT_DART_DART_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_WTLIMIT)) +#define HPERF_NRT_DART_JPEG0_QOS (0x000C) +#define rHPERF_NRT_DART_JPEG0_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_QOS)) +#define HPERF_NRT_DART_JPEG1_QOS (0x0010) +#define rHPERF_NRT_DART_JPEG1_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG1_QOS)) +#define HPERF_NRT_DART_SCALER0_RTLIMIT (0x001C) +#define rHPERF_NRT_DART_SCALER0_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_RTLIMIT)) +#define HPERF_NRT_DART_SCALER0_WTLIMIT (0x0020) +#define rHPERF_NRT_DART_SCALER0_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_WTLIMIT)) +#define HPERF_NRT_DART_SCALER1_RTLIMIT (0x0030) +#define rHPERF_NRT_DART_SCALER1_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_RTLIMIT)) +#define HPERF_NRT_DART_SCALER1_WTLIMIT (0x0034) +#define rHPERF_NRT_DART_SCALER1_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_WTLIMIT)) + +#define HPERF_NRT_DART_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_DART_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_DART_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_DART_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AW_CHAN_ARB_MI0)) + +#define HPERF_NRT_TOP_TOP_RTLIMIT (0x0000) +#define rHPERF_NRT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_RTLIMIT)) +#define HPERF_NRT_TOP_TOP_WTLIMIT (0x0004) +#define rHPERF_NRT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_RTLIMIT (0x0010) +#define rHPERF_NRT_TOP_VENC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_RTLIMIT)) +#define HPERF_NRT_TOP_VENC_WTLIMIT (0x0014) +#define rHPERF_NRT_TOP_VENC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_WREQSP (0x0018) +#define rHPERF_NRT_TOP_VENC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WREQSP)) +#define HPERF_NRT_TOP_VDEC_RTLIMIT (0x0028) +#define rHPERF_NRT_TOP_VDEC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_RTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WTLIMIT (0x002C) +#define rHPERF_NRT_TOP_VDEC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WREQSP (0x0030) +#define rHPERF_NRT_TOP_VDEC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WREQSP)) +#define HPERF_NRT_TOP_DART_WGATHER (0x0048) +#define rHPERF_NRT_TOP_DART_WGATHER (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_DART_WGATHER)) + +#define HPERF_NRT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AW_CHAN_ARB_MI0)) + +#define HPERF_RT_TOP_DISP0_RTLIMIT (0x0004) +#define rHPERF_RT_TOP_DISP0_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP0_RTLIMIT)) +#define HPERF_RT_TOP_DISP1_RTLIMIT (0x000C) +#define rHPERF_RT_TOP_DISP1_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP1_RTLIMIT)) +#define HPERF_RT_TOP_ISP_RTLIMIT (0x0018) +#define rHPERF_RT_TOP_ISP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_WTLIMIT)) +#define HPERF_RT_TOP_ISP_WTLIMIT (0x001C) +#define rHPERF_RT_TOP_ISP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_RTLIMIT)) +#define HPERF_RT_TOP_TOP_RTLIMIT (0x0020) +#define rHPERF_RT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_WTLIMIT)) +#define HPERF_RT_TOP_TOP_WTLIMIT (0x0024) +#define rHPERF_RT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_RTLIMIT)) + +#define HPERF_RT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_RT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_RT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_RT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AW_CHAN_ARB_MI0)) + + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s5l8940x/include/platform/soc/pmgr.h b/platform/s5l8940x/include/platform/soc/pmgr.h new file mode 100644 index 0000000..a5fe40e --- /dev/null +++ b/platform/s5l8940x/include/platform/soc/pmgr.h @@ -0,0 +1,465 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include + +#define rPMGR_PLL0_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0000)) +#define rPMGR_PLL0_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0004)) +#define rPMGR_PLL1_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0008)) +#define rPMGR_PLL1_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x000C)) +#define rPMGR_PLL2_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0010)) +#define rPMGR_PLL2_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0014)) +#define rPMGR_PLL3_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0018)) +#define rPMGR_PLL3_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x001C)) +#define rPMGR_PLL4_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0020)) +#define rPMGR_PLL4_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0024)) +#define rPMGR_PLLUSB_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0028)) +#define rPMGR_PLLUSB_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x002C)) + +#define rPMGR_PLL_ENABLE (1 << 31) +#define rPMGR_PLL_EXT_BYPASS (1 << 30) +#define rPMGR_PLL_REAL_LOCK (1 << 29) +#define rPMGR_PLL_LOAD (1 << 27) +#define rPMGR_PLL_BYPASS (1 << 23) +#define rPMGR_PLL_P(_p) (((_p) & 0x03f) << 14) +#if (SUB_PLATFORM_S5L8942X || SUB_PLATFORM_S5L8947X) +#define rPMGR_PLL_VSEL(_p) (((_p) & 1) << 13) +#endif +#define rPMGR_PLL_M(_m) (((_m) & 0x3ff) << 3) +#define rPMGR_PLL_S(_s) (((_s) & 0x007) << 0) + +#define rPMGR_PARAM_EXT_AFC(_n) ((_n) << 17) +#define rPMGR_PARAM_AFC_EN (1 << 16) +#define rPMGR_PARAM_LOCK_TIME(_n) ((_n) << 0) + +#define rPMGR_PLL_GATES (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0030)) + +#define rPMGR_DOUBLER_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0034)) + +#define rPMGR_DOUBLER_ENABLE (1 << 31) +#define rPMGR_DOUBLER_EXT_BYPASS (1 << 30) + +#define rPMGR_CPU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0038)) +#define rPMGR_MCU_FIXED_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x003C)) +#define rPMGR_MCU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0040)) +#define rPMGR_PCLK1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0044)) + +#define rPMGR_PREDIV0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0048)) +#define rPMGR_PREDIV1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x004C)) +#define rPMGR_PREDIV2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0050)) +#define rPMGR_PREDIV3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0054)) +#define rPMGR_PREDIV4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0058)) +#define rPMGR_PREDIV5_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x005C)) +#define rPMGR_PREDIV6_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0060)) + +#define rPMGR_MANAGED0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0064)) +#define rPMGR_MANAGED1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0068)) +#define rPMGR_MANAGED2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x006C)) +#define rPMGR_MANAGED3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0070)) +#define rPMGR_MANAGED4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0074)) + +#define rPMGR_VID1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0078)) +#define rPMGR_MEDIUM0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x007C)) +#define rPMGR_VID0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0080)) +#define rPMGR_I2C_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0084)) +#define rPMGR_SDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0088)) +#define rPMGR_MIPI_DSI_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x008C)) +#define rPMGR_AUDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0090)) +#define rPMGR_HPARK_PCLK0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0094)) +#define rPMGR_HPARK_TCLK_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0098)) +#define rPMGR_UPERF_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x009C)) +#define rPMGR_DEBUG_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00A0)) + +#define rPMGR_HPERFRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00A4)) +#define rPMGR_GFX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00A8)) +#define rPMGR_GFX_SLC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00AC)) + +#define rPMGR_HPERFNRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00B0)) +#define rPMGR_ISP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00B4)) +#define rPMGR_IOP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00B8)) +#define rPMGR_CDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00BC)) + +#define rPMGR_LPERFS_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00C0)) +#define rPMGR_PCLK0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00C4)) +#define rPMGR_PCLK2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00C8)) +#define rPMGR_PCLK3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00CC)) + +#define rPMGR_MEDIUM1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00D0)) +#define rPMGR_SPI0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00D4)) +#define rPMGR_SPI1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00D8)) +#define rPMGR_SPI2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00DC)) +#define rPMGR_SPI3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00E0)) +#define rPMGR_SPI4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00E4)) +#define rPMGR_SLEEP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00E8)) +#define rPMGR_USBPHY_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00EC)) +#define rPMGR_USBOHCI_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00F0)) +#define rPMGR_USB12_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00F4)) +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00F8)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00FC)) +#define rPMGR_VENC_MTX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0100)) +#define rPMGR_VENC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0104)) + +#define PMGR_FIRST_CLK_CFG (&rPMGR_CPU_CLK_CFG) +#define PMGR_LAST_CLK_CFG (&rPMGR_VENC_CLK_CFG) +#define PMGR_CLK_CFG_COUNT (((((u_int32_t)(PMGR_LAST_CLK_CFG)) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) + 1) +#define PMGR_CLK_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _CLK_CFG) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) + +#define rPMGR_I2S0_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0110)) +#define rPMGR_I2S0_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0114)) +#define rPMGR_I2S0_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0118)) + +#define rPMGR_I2S1_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0120)) +#define rPMGR_I2S1_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0124)) +#define rPMGR_I2S1_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0128)) + +#define rPMGR_I2S2_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0130)) +#define rPMGR_I2S2_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0134)) +#define rPMGR_I2S2_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0138)) + +#define rPMGR_I2S3_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0140)) +#define rPMGR_I2S3_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0144)) +#define rPMGR_I2S3_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0148)) + +#define rPMGR_SPDIF_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0150)) +#define rPMGR_SPDIF_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0154)) +#define rPMGR_SPDIF_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0158)) + +#define rPMGR_DP_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0160)) +#define rPMGR_DP_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0164)) +#define rPMGR_DP_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0168)) + +#define rPMGR_MCA0_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0170)) +#define rPMGR_MCA0_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0174)) +#define rPMGR_MCA0_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0178)) + +#define rPMGR_CLK_CFG_ENABLE (1 << 31) +#define rPMGR_CLK_CFG_PENDING (1 << 30) +#define rPMGR_CLK_CFG_SRC_SEL(_s) (((_s) & 0x3) << 28) +#define rPMGR_CLK_CFG_SRC_SEL_MASK rPMGR_CLK_CFG_SRC_SEL(3) +#define rPMGR_CLK_CFG_DIVIDER(_d) (((_d) & 0x1f) << 0) +#define rPMGR_CLK_CFG_DIV_MASK rPMGR_CLK_CFG_DIVIDER(0x1f) + +#define PMGR_PERF_STATE_COUNT (16) +#define rPMGR_PERF_STATE_A(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0200 + ((_s) * 0x10))) +#define rPMGR_PERF_STATE_B(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0204 + ((_s) * 0x10))) +#define rPMGR_PERF_STATE_C(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0208 + ((_s) * 0x10))) +#define rPMGR_PERF_STATE_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0300)) + +#define PMGR_PERF_STATE_SEL(_s) (((_s) & 0xF) << 0) +#define PMGR_PERF_STATE_PENDING (0xFF << 16) + +#define kPERF_STATE_BYPASS (0) +#define kPERF_STATE_SECUREROM (1) +#define kPERF_STATE_IBOOT (2) +#define kPERF_STATE_IBOOT_CNT (5) + +#define rPMGR_MCU_CLK_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0400)) + +#define rPMGR_CPU0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1008)) +#define rPMGR_CPU1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x100C)) +#define rPMGR_SCU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1010)) +#define rPMGR_L2RAM0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1014)) +#define rPMGR_L2RAM1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1018)) +#define rPMGR_CPU_REGS_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x101C)) +#define rPMGR_MCU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1020)) +#define rPMGR_GFX_SYS_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1024)) +#define rPMGR_GFX_CORES_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1028)) +#define rPMGR_HPERFNRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x102C)) +#define rPMGR_VDEC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1030)) +#define rPMGR_SCALER0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1034)) +#define rPMGR_SCALER1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1038)) +#define rPMGR_JPG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x103C)) +#define rPMGR_VENCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1040)) +#define rPMGR_HPERFRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1044)) +#define rPMGR_ISP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1048)) +#define rPMGR_DISP0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1054)) +#define rPMGR_DISP1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1058)) +#define rPMGR_DISPOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x105C)) +#define rPMGR_MIPI_DSI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1060)) +#define rPMGR_CLCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1064)) +#define rPMGR_TVOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1068)) +#define rPMGR_RGBOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x106C)) +#define rPMGR_DPLINK_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1070)) +#define rPMGR_CDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1074)) +#define rPMGR_CDMA_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1078)) +#define rPMGR_IOP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x107C)) +#define rPMGR_UPERF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1080)) +#define rPMGR_USBOTG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1084)) +#define rPMGR_USB20_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1088)) +#define rPMGR_USB11_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x108C)) +#define rPMGR_USBOHCI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1090)) +#define rPMGR_USBOHCI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1094)) +#define rPMGR_USBREG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1098)) +#define rPMGR_AUDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x109C)) +#define rPMGR_I2S0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A0)) +#define rPMGR_I2S1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A4)) +#define rPMGR_I2S2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A8)) +#define rPMGR_I2S3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10AC)) +#define rPMGR_SPDIF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B0)) +#define rPMGR_HPARK_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B4)) +#define rPMGR_SDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B8)) +#define rPMGR_SHA1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10BC)) +#define rPMGR_SHA2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C0)) +#define rPMGR_FMI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C4)) +#define rPMGR_FMI0BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C8)) +#define rPMGR_FMI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10CC)) +#define rPMGR_FMI1BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D0)) +#define rPMGR_FMI2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D4)) +#define rPMGR_FMI2BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D8)) +#define rPMGR_FMI3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10DC)) +#define rPMGR_FMI3BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E0)) +#define rPMGR_SPI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E4)) +#define rPMGR_SPI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E8)) +#define rPMGR_SPI2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10EC)) +#define rPMGR_SPI3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F0)) +#define rPMGR_SPI4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F4)) +#define rPMGR_UART0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F8)) +#define rPMGR_UART1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10FC)) +#define rPMGR_UART2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1100)) +#define rPMGR_UART3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1104)) +#define rPMGR_UART4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1108)) +#define rPMGR_UART5_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x110C)) +#define rPMGR_UART6_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1110)) +#define rPMGR_PKE_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1114)) +#define rPMGR_I2C0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1118)) +#define rPMGR_I2C1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x111C)) +#define rPMGR_I2C2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1120)) +#define rPMGR_PWM_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1124)) +#define rPMGR_SCRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1128)) +#define rPMGR_GPIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x112C)) +#define rPMGR_SWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1130)) +#define rPMGR_DWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1134)) +#define rPMGR_DEBUG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1138)) +#define rPMGR_AIC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x113C)) +#define rPMGR_MCA0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1140)) +#ifdef SUB_PLATFORM_S5L8947X +#define rPMGR_ETH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1144)) +#define rPMGR_HDMI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1148)) +#define rPMGR_ADC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x114C)) +#define rPMGR_USBOTG1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1150)) +#define rPMGR_USB20_1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1154)) +#define rPMGR_USBOHCI0_1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1158)) +#define rPMGR_USBREG1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x115C)) +#endif +#define rPMGR_PS_RESET (1 << 31) + +#define PMGR_FIRST_PS (&rPMGR_CPU0_PS) +#if SUB_PLATFORM_S5L8942X +#define PMGR_LAST_PS (&rPMGR_MCA0_PS) +#elif SUB_PLATFORM_S5L8947X +#define PMGR_LAST_PS (&rPMGR_USBREG1_PS) +#else +#define PMGR_LAST_PS (&rPMGR_AIC_PS) +#endif +#define PMGR_DEV_PS_COUNT (((((u_int32_t)(PMGR_LAST_PS)) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + 1) +#define PMGR_PS_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _PS) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + +#define rPMGR_CPU_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1180)) + +#define rPMGR_PWR_GATE_CTL_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1200)) +#define rPMGR_PWR_GATE_CTL_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1204)) +#define rPMGR_PWR_GATE_IOP (1 << 6) +#define rPMGR_PWR_GATE_GFX_MODE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1208)) + +#define rPMGR_CORE_OFFLINE_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1210)) +#define rPMGR_CORE_OFFLINE_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1214)) +#define rPMGR_WAKE_CORES (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1220)) + +#define PMGR_PWR_GATE_TIME_COUNT (15) +#define rPMGR_PWR_GATE_TIME_A(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1238 + ((_n) * 8))) +#define rPMGR_PWR_GATE_TIME_B(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x123C + ((_n) * 8))) +#define rPMGR_PWR_GATE_DBG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E0)) +#define rPMGR_PWR_GATE_DBG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E4)) + +#define rPMGR_TEST_CLK (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2000)) +#define rPMGR_PLL0_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2010)) +#define rPMGR_PLL1_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2014)) +#define rPMGR_PLL2_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2018)) +#define rPMGR_PLL3_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x201C)) +#define rPMGR_PLL4_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2020)) +#define rPMGR_PLLUSB_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2024)) +#define rPMGR_DOUBLER_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2028)) + +#define rPMGR_PLL0_TUNE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2080)) +#define rPMGR_PLL1_TUNE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2084)) +#define rPMGR_PLL2_TUNE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2088)) +#define rPMGR_PLL3_TUNE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x208C)) +#define rPMGR_PLL4_TUNE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2090)) +#define rPMGR_PLLUSB_TUNE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2094)) + +#define rPMGR_PLL_DEBUG_ENABLED (1 << 31) +#define rPMGR_PLL_DEBUG_BYP_ENABLED (1 << 30) +#define rPMGR_PLL_DEBUG_DBG_STPCLK_EN (1 << 24) +#define rPMGR_PLL_DEBUG_LOST_LOCK (1 << 16) +#define rPMGR_PLL_DEBUG_STATE(_r) (((_r) >> 0) & 0xff) + +#define rPMGR_EMA_CTL_CPU (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2100)) +#define rPMGR_EMA_CTL_CPU_SPIN (0x01 << 16) +#define rPMGR_EMA_CTL_SOC (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2104)) +#define rPMGR_EMA_CTL_SOC_SEL (0x1f << 0) +#define rPMGR_EMA_CTL_SOC_SPIN (0x01 << 16) + +#define rPMGR_SRAM_EMA_B0_Pn_LO(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2120 + ((_n) * 8))) +#define rPMGR_SRAM_EMA_B0_Pn_HI(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2124 + ((_n) * 8))) +#define rPMGR_SRAM_EMA_B1_Pn_LO(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x21C0 + ((_n) * 8))) +#define rPMGR_SRAM_EMA_B1_Pn_HI(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x21C4 + ((_n) * 8))) +#if (SUB_PLATFORM_S5L8942X || SUB_PLATFORM_S5L8947X) +#define rPMGR_SRAM_EMA_B2_Pn_LO(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2200 + ((_n) * 8))) +#define rPMGR_SRAM_EMA_B2_Pn_HI(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2204 + ((_n) * 8))) +#endif + +enum { + EMA_CPU = 0, + EMA_MCU = 1, + EMA_GFX_PIPES_SYS = 2, + EMA_GFX_HYDRA = 3, + EMA_VDEC = 4, + EMA_VENC = 5, + EMA_ISP = 6, + EMA_DISP = 7, + EMA_NRT = 8, + EMA_CIF = 9, + EMA_IOP = 10, + EMA_SAUDIO = 11, + EMA_CDMA = 12, + EMA_FMI = 13, + EMA_HPARK = 14, +}; + +#define rPMGR_WDOG_TMR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3020)) +#define rPMGR_WDOG_RST (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3024)) +#define rPMGR_WDOG_INT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3028)) +#define rPMGR_WDOG_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x302C)) + +#define rPMGR_EVENT_TMR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3100)) +#define rPMGR_EVENT_PERIOD (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3104)) +#define rPMGR_EVENT_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3108)) + +#define rPMGR_PERF_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4000)) +#define rPMGR_PERF_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4004)) +#define rPMGR_PERF_CTR0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4020)) +#define rPMGR_PERF_CTR0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4024)) +#define rPMGR_PERF_CFG0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4028)) +#define rPMGR_PERF_CFG0_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x402C)) +#define rPMGR_PERF_CFG0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4030)) +#define rPMGR_PERF_CTR1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4040)) +#define rPMGR_PERF_CTR1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4044)) +#define rPMGR_PERF_CFG1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4048)) +#define rPMGR_PERF_CFG1_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x404C)) +#define rPMGR_PERF_CFG1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4050)) + +#define rPMGR_SCRATCH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6000)) +#define rPMGR_SCRATCH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6004)) +#define rPMGR_SCRATCH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6008)) +#define rPMGR_SCRATCH3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x600C)) +#define rPMGR_SCRATCH4 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6010)) +#define rPMGR_SCRATCH5 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6014)) +#define rPMGR_SCRATCH6 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6018)) +#define rPMGR_SCRATCH7 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x601C)) +#define rPMGR_SCRATCH8 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6020)) +#define rPMGR_SCRATCH9 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6024)) +#define rPMGR_SCRATCH10 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6028)) +#define rPMGR_SCRATCH11 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x602C)) +#define rPMGR_SCRATCH12 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6030)) +#define rPMGR_SCRATCH13 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6034)) +#define rPMGR_SCRATCH14 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6038)) +#define rPMGR_SCRATCH15 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x603C)) + +#define rPMGR_DAC_FS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x7000)) + +#define rPMGR_USB_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x8000)) + +#define rPMGR_SHA_SEL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x9000)) + +#define rPMGR_SECURITY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xA000)) + +#define rPMGR_GFX_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xB000)) + +#define PGMR_GET_PERF_STATE_INDEX(_n, _x) (((_x) >> ((_n) * 4)) & 0xF) +#define PGMR_SET_PERF_STATE_INDEX(_n, _i) (((_i) & 0xF) << ((_n) * 4)) +#define PMGR_PERF_STATE_V(_n) (_n) +#define PMGR_PERF_STATE_P (3) +#define PMGR_PERF_STATE_M(_n) (4 + (_n)) + +enum { + PMGR_CLK_OSC = 0, + PMGR_CLK_PLL0, + PMGR_CLK_PLL1, + PMGR_CLK_PLL2, + PMGR_CLK_PLL3, + PMGR_CLK_PLL4, + PMGR_CLK_PLLUSB, + PMGR_CLK_DOUBLER, + PMGR_CLK_CPU, + PMGR_CLK_MEM, + PMGR_CLK_PIO, + PMGR_CLK_ACP, + PMGR_CLK_MCU_FIXED, + PMGR_CLK_MCU, + PMGR_CLK_PREDIV0, + PMGR_CLK_PREDIV1, + PMGR_CLK_PREDIV2, + PMGR_CLK_PREDIV3, + PMGR_CLK_PREDIV4, + PMGR_CLK_PREDIV5, + PMGR_CLK_PREDIV6, + PMGR_CLK_MANAGED0, + PMGR_CLK_MANAGED1, + PMGR_CLK_MANAGED2, + PMGR_CLK_MANAGED3, + PMGR_CLK_MANAGED4, + PMGR_CLK_MEDIUM0, + PMGR_CLK_MEDIUM1, + PMGR_CLK_VID0, + PMGR_CLK_VID1, + PMGR_CLK_I2C, + PMGR_CLK_SDIO, + PMGR_CLK_MIPI_DSI, + PMGR_CLK_AUDIO, + PMGR_CLK_HPARK_PCLK, + PMGR_CLK_HPARK_TCLK, + PMGR_CLK_UPERF, + PMGR_CLK_DEBUG, + PMGR_CLK_HPERFRT, + PMGR_CLK_GFX, + PMGR_CLK_GFX_SLC, + PMGR_CLK_HPERFNRT, + PMGR_CLK_ISP, + PMGR_CLK_IOP, + PMGR_CLK_CDIO, + PMGR_CLK_LPERFS, + PMGR_CLK_PCLK0, + PMGR_CLK_PCLK1, + PMGR_CLK_PCLK2, + PMGR_CLK_PCLK3, + PMGR_CLK_SPI0, + PMGR_CLK_SPI1, + PMGR_CLK_SPI2, + PMGR_CLK_SPI3, + PMGR_CLK_SPI4, + PMGR_CLK_SLOW, + PMGR_CLK_SLEEP, + PMGR_CLK_USBPHY, + PMGR_CLK_USBOHCI, + PMGR_CLK_USB12, + PMGR_CLK_NCO_REF0, + PMGR_CLK_NCO_REF1, + PMGR_CLK_VENC_MTX, + PMGR_CLK_VENC, + PMGR_CLK_COUNT +}; + +extern void pmgr_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/s5l8940x/include/platform/trampoline.h b/platform/s5l8940x/include/platform/trampoline.h new file mode 100644 index 0000000..32d8ff6 --- /dev/null +++ b/platform/s5l8940x/include/platform/trampoline.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include +#include + +#define SECURITY_REG (PMGR_BASE_ADDR + 0xA000) +#define ROM_READ_DISABLE (1 << 0) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s5l8940x/include/platform/usbconfig.h b/platform/s5l8940x/include/platform/usbconfig.h new file mode 100644 index 0000000..d057183 --- /dev/null +++ b/platform/s5l8940x/include/platform/usbconfig.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2008-2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#define USBPHY_CLK_TYPE (3) /* Use CLKCORE */ + +#if SUB_PLATFORM_S5L8940X +#define USBPHY_UOTGTUNE1 (0x349) +#define USBPHY_UOTGTUNE2 (0xF13) +#elif SUB_PLATFORM_S5L8942X | SUB_PLATFORM_S5L8947X +#define USBPHY_UOTGTUNE1 (0x349) +#define USBPHY_UOTGTUNE2 (0x6FF3) +#endif + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR8) + +#ifdef WITH_TARGET_USB_CONFIG +#include +#endif /* WITH_TARGET_USB_CONFIG */ + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s5l8940x/init.c b/platform/s5l8940x/init.c new file mode 100644 index 0000000..347126c --- /dev/null +++ b/platform/s5l8940x/init.c @@ -0,0 +1,1181 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_EFFACEABLE_NOR +#include +#endif + +extern void dma_init(void); + +static void platform_init_boot_strap(void); + +static uint8_t boot_debug; + +int platform_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + /* Verify that the fuses and that the SecureROM has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile u_int32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled"); + } +#endif + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8940x pmgr driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); +#if !RELEASE_BUILD && (PRODUCT_IBSS || PRODUCT_IBEC) + debug_enable_uarts(3); +#endif +#endif +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_HW_DMA + /* initialize the dma engine */ + dma_init(); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + return 0; +} + + +int platform_late_init(void) +{ + if ((platform_get_chip_id() == 0x8940) && (platform_get_chip_revision() < 0x21)) + platform_not_supported(); + +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_NAND + flash_nand_id(); +#endif + +#if WITH_HW_AMC + extern void mcu_late_init(void); + mcu_late_init(); +#endif + + return 0; +} + + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); + + /* always remap the memory region at this point, regardless of resume, + * because the early MMU init always runs and we have to fix up. */ + platform_init_mainmem_map(); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +#if APPLICATION_IBOOT + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, kARMMMUNormal, true, true); +#endif +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +static bool gDisplayEnabled; + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { + if (!displayInitOnce) { + platform_quiesce_display(); + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + + power_backlight_enable(backlight_level); +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + u_int32_t base_rounded = *base; + u_int32_t end_rounded = *base + *size; + u_int32_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + arm_mmu_map_section_range(base_rounded, base_rounded, size_rounded/MB, kARMMMUWriteCombined, false, true); + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_NAND_FILESYSTEM + flash_nand_init(); +#endif + + return 0; +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + + /* quiesce the panel */ + if (display_quiesce(true) == ENXIO) { + clock_gate(CLK_HPERFRT, false); + clock_gate(CLK_DISPOUT, false); + } +#endif + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + u_int32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + platform_quiesce_display(); + case BOOT_DARWIN: + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + ; // do nothing + } + + /* if we left the fuse unlocked for boot image processing, + * lock it now, after optionally switching from production to + * development fusing. */ + if (security_get_production_override()) + chipid_clear_production_mode(); + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + + /* mark usable ram as cached/buffered, shared */ + arm_mmu_map_section_range(SRAM_BASE, SRAM_BASE, ROUNDUP(SRAM_BANK_LEN, MB)/MB, kARMMMUNormal, false, true); +#if APPLICATION_SECUREROM + arm_mmu_map_section_range(VROM_BASE, VROM_BASE, ROUNDUP(VROM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#endif + + /* Remap text base is to zero (for exception vectors) */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUNormalRX, true); + +#ifdef MMU_NONCACHE0_SIZE + /* create the noncached0 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE0_VBASE, MMU_NONCACHE0_PBASE, ROUNDUP(MMU_NONCACHE0_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + +#ifdef MMU_NONCACHE1_SIZE + /* create the noncached1 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE1_VBASE, MMU_NONCACHE1_PBASE, ROUNDUP(MMU_NONCACHE1_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + + /* in cases where we are running from DRAM, remap it now */ + if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) { + platform_init_mainmem_map(); + } +} + +int platform_init(void) +{ +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_NAND_BOOT + nand_boot_init(); +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + +#if WITH_EFFACEABLE_NOR + effaceable_nor_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + u_int32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +u_int32_t platform_set_performance(u_int32_t performance_level) +{ + u_int32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + u_int32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_CPU); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_MEM); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_BUS); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_PERIPH); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_FIXED); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_TIMEBASE); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(u_int32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_NAND_FILESYSTEM + if (FindNode(0, "arm-io/flash-controller0/disk", &node)) { + fillNandConfigProperties(node); + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + + return target_update_device_tree(); +} + +#endif + +static void platform_init_boot_strap(void) +{ + u_int32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG3, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG3) << 3) | + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +u_int32_t platform_get_board_id(void) +{ + u_int32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +u_int32_t platform_get_boot_config(void) +{ + u_int32_t boot_config; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, u_int32_t *boot_flag, u_int32_t *boot_arg) +{ + u_int32_t boot_config = platform_get_boot_config(); + + /* S5L8940X supports one boot device then USB-DFU per boot config */ + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case 0: /* SPI 0 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 1: /* SPI 3 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 3; + break; + + case 2: /* SPI 0 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case 3: /* SPI 3 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 3; + break; + + case 4: /* FMI0 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 0; + break; + + case 5: /* FMI0 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 0; + break; + + case 6: /* FMI0 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 0; + break; + +/* case 7: Unused */ + + case 8: /* FMI1 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 8; + break; + + case 9: /* FMI1 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 8; + break; + + case 10: /* FMI1 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 8; + break; + +/* case 11: Unused */ + + case 12: /* FMI0/1 2/2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (2 << 8) | (2 << 0); + break; + + case 13: /* FMI0/1 4/4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (4 << 8) | (4 << 0); + break; + + case 14: /* FMI0/1 4/4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = (4 << 8) | (4 << 0); + break; + +/* case 15: Unused */ + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == 1) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, u_int32_t boot_arg) +{ + const struct boot_interface_pin *pins0 = 0; + const struct boot_interface_pin *pins1 = 0; + u_int32_t cnt, func, pin_count0 = 0, pin_count1 = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins0 = spi0_boot_interface_pins; + pin_count0 = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } else if (boot_arg == 3) { +#if !SUB_PLATFORM_S5L8947X + pins0 = spi3_boot_interface_pins; + pin_count0 = (sizeof(spi3_boot_interface_pins) / sizeof(spi3_boot_interface_pins[0])); +#endif + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND + case BOOT_DEVICE_NAND : + pins0 = fmi0_boot_interface_pins; + pin_count0 = (sizeof(fmi0_boot_interface_pins) / sizeof(fmi0_boot_interface_pins[0])); + switch ((boot_arg >> 0) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins0 += 2; + pin_count0 -= 2; + break; + + default: + pins0 = 0; + pin_count0 = 0; + break; + } + + pins1 = fmi1_boot_interface_pins; + pin_count1 = (sizeof(fmi1_boot_interface_pins) / sizeof(fmi1_boot_interface_pins[0])); + switch ((boot_arg >> 8) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins1 += 2; + pin_count1 -= 2; + break; + + default: + pins1 = 0; + pin_count1 = 0; + break; + } + break; +#endif /* WITH_HW_BOOTROM_NAND */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count0; cnt++) { + if (enable) { + pin = pins0[pin_count0 - 1 - cnt].pin; + func = pins0[pin_count0 - 1 - cnt].enable; + } else { + pin = pins0[cnt].pin; + func = pins0[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } + + for (cnt = 0; cnt < pin_count1; cnt++) { + if (enable) { + pin = pins1[pin_count1 - 1 - cnt].pin; + func = pins1[pin_count1 - 1 - cnt].enable; + } else { + pin = pins1[cnt].pin; + func = pins1[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 1 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +u_int64_t platform_get_nonce(void) +{ + u_int64_t nonce; + u_int32_t *nonce_words = (u_int32_t *)&nonce; + +#if WITH_EFFACEABLE && PRODUCT_IBOOT && SUB_PLATFORM_S5L8947X + // N41 : Sundance 10A267 : USER IPSW : iTunes fails with error 21. + // In iboot use key stored in effaceable and cache it + // for later use, rather than using random_get_bytes + // key generated by secure-rom + static bool use_cached_effaceable_key; + if(use_cached_effaceable_key == false) { + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagNonce; + use_cached_effaceable_key = true; + } +#endif + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return chipid_get_ecid_image_personalization_required(); +} + +u_int32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +// Let the target's rules.mk override the high core voltage point +#ifndef TARGET_HIGH_SOC_VOLTAGE +#define TARGET_HIGH_SOC_VOLTAGE CHIPID_SOC_VOLTAGE_HIGH +#endif + +u_int32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_HIGH_SOC_VOLTAGE); +} + +// Let the target's rules.mk override the high cpu voltage point +#ifndef TARGET_HIGH_CPU_VOLTAGE +#define TARGET_HIGH_CPU_VOLTAGE CHIPID_CPU_VOLTAGE_HIGH +#endif + +u_int32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_HIGH_CPU_VOLTAGE); +} + +static const u_int32_t soc_voltage_points[] = { + CHIPID_SOC_VOLTAGE_LOW, + TARGET_HIGH_SOC_VOLTAGE +}; + +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(soc_voltage_points) / sizeof(soc_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_soc_voltage(soc_voltage_points[cnt]); + } + + return 0; +} + +#ifndef TARGET_CPU_VOLTAGE_MASK +#define TARGET_CPU_VOLTAGE_MASK 7 +#endif + +static const u_int32_t cpu_voltage_points[3] = { +#if TARGET_CPU_VOLTAGE_MASK & 1 + CHIPID_CPU_VOLTAGE_LOW, +#endif +#if TARGET_CPU_VOLTAGE_MASK & 2 + CHIPID_CPU_VOLTAGE_MED, +#endif +#if TARGET_CPU_VOLTAGE_MASK & 4 + CHIPID_CPU_VOLTAGE_HIGH, +#endif +}; + +int platform_get_cpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(cpu_voltage_points) / sizeof(cpu_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cpu_voltage_points[cnt]); + } + + return 0; +} + +int platform_convert_voltages(int buck, u_int32_t count, u_int32_t *voltages) +{ +#if WITH_HW_POWER + u_int32_t index; + + if (voltages == 0) return -1; + + for (index = 0; index < count; index++) { + if (0 != power_get_buck_value(buck, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ +#if SUPPORT_FPGA + return !gpio_read(GPIO_FORCE_DFU); +#else + return gpio_read(GPIO_FORCE_DFU); +#endif +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(u_int32_t key_selector, u_int32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +#if APPLICATION_IBOOT +u_int64_t platform_get_memory_size(void) +{ + u_int64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (rPMGR_SCRATCH13 & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +u_int8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 28) & 0xf); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info(u_int8_t manuf_id, u_int64_t memory_size) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 28) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +#endif diff --git a/platform/s5l8940x/iop_init.c b/platform/s5l8940x/iop_init.c new file mode 100644 index 0000000..7dbb906 --- /dev/null +++ b/platform/s5l8940x/iop_init.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Platform memory layout. + * + * The IOP sees SDRAM at its physical location uncached, and has an cached aperture + * visible elsewhere. SDRAM size of up to 1GB is currently supported. + * SRAM is not visible/legally usable. + * + * For some platforms/targets, SDRAM_LEN is not constant and so we + * have to compute a maximum via other means. + * + * Note that the AE2 Sparrow shares this code. + */ +#define MEM_CACHED_BASE (SDRAM_BASE | 0xc0000000) +#define SDRAM_MAX_LEN (SDRAM_BANK_LEN * SDRAM_BANK_COUNT) +struct mem_static_map_entry mem_static_map_entries[] = { + { + MEM_CACHED_BASE, /* cached */ + SDRAM_BASE, /* uncached */ + SDRAM_BASE, /* physical */ + SDRAM_MAX_LEN /* length */ + }, + {MAP_NO_ENTRY, MAP_NO_ENTRY, MAP_NO_ENTRY, 0} +}; + +void platform_mmu_setup(bool resume) +{ + if (false == resume) { + /* Remap text base to zero, outer uncacheable, shared */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUInnerNormalOuterNoncached, true); +#ifdef MAP_SRAM_CACHED + /* Map the SRAM as cacheable, shared */ + arm_mmu_map_section(SRAM_BASE, SRAM_BASE, kARMMMUNormal, true); +#endif // MAP_SRAM_CACHED + /* Remap all of SDRAM through the cacheable aperture, outer uncacheable, shared */ + arm_mmu_map_section_range(MEM_CACHED_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUInnerNormalOuterNoncached, true, false); + /* Remap all of SDRAM through the uncacheable aperture (existing mappings should be there, but be sure) */ + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUStronglyOrdered, false, false); + } +} + +bool platform_get_production_mode(void) +{ + return(true); +} + +bool platform_get_secure_mode(void) +{ + return(true); +} + +void platform_reset(bool panic) +{ + for (;;) + ; +} + +/* + * Early init is done every time the IOP starts. + */ +int +platform_early_init() +{ +#if PLATFORM_VARIANT_IOP + /* In general we want power-gating to be disabled. */ + rPMGR_PWR_GATE_CTL_CLR = rPMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & rPMGR_PWR_GATE_IOP) ; +#endif + + interrupt_init(); + + timer_init(0); + + return(0); +} + +/* + * Halt waiting for an interrupt. + */ +void +platform_halt(void) +{ + arch_halt(); +} + +#if SUPPORT_SLEEP + +#if WITH_IOP_POWER_GATING + +/* + * Deep idle sleep with power gating + */ +void +platform_deep_idle(void) +{ + rPMGR_PWR_GATE_CTL_SET = rPMGR_PWR_GATE_IOP; + while (!(rPMGR_PWR_GATE_CTL_SET & rPMGR_PWR_GATE_IOP)) ; + a5iop_sleep(1); + rPMGR_PWR_GATE_CTL_CLR = rPMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & rPMGR_PWR_GATE_IOP) ; +} + +#endif + +void +platform_sleep(void) +{ + /* We assume power-gating is disabled, which it need to be so + * the IOP wrapper registers don't disappear. */ + a5iop_sleep(0); +} + +#endif + +/* + * Cache control + */ +void +platform_cache_operation(int operation, void *address, u_int32_t length) +{ + a5iop_cache_operation(operation, address, length); +} + +/* + * Host doorbell uses a SWI in the AIC. + */ +static void (* _doorbell_handler)(void *arg); +static void +platform_doorbell_handler(void *arg) +{ + /* clear the doorbell before passing up */ + interrupt_clear_ipc(INT_IOP); + _doorbell_handler(arg); +} + +void +platform_init_iop_doorbell(void (* handler)(void *arg), void *arg) +{ + _doorbell_handler = handler; + install_int_handler(INT_IOP, platform_doorbell_handler, arg); + set_int_type(INT_IOP, INT_TYPE_IRQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP); +} + +void +platform_mask_doorbell(void) +{ + mask_int(INT_IOP); +} + +void +platform_unmask_doorbell(void) +{ + unmask_int(INT_IOP); +} + +void +platform_ring_host_doorbell(void) +{ + interrupt_generate_ipc(INT_HOST); +} + +int +platform_init_nmi(void (*handler)(void *arg), void *arg) +{ +#ifdef INT_IOP_NMI + install_int_handler(INT_IOP_NMI, handler, arg); + set_int_type(INT_IOP_NMI, INT_TYPE_FIQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP_NMI); +#endif + + return(0); +} + +/* + * Clock management. + * + * Currently the IOP does none for this platform. + */ +void clock_gate(int device, bool enable) +{ +} diff --git a/platform/s5l8940x/miu/miu.c b/platform/s5l8940x/miu/miu.c new file mode 100644 index 0000000..499754a --- /dev/null +++ b/platform/s5l8940x/miu/miu.c @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2007-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void miu_configure_bridge(const u_int32_t *bridge_settings); + +#define BRIDGE_SHIFT (16) +#define BRIDGE_MASK (0xFFFF) +#define NRT_DART_WIDGETS (0 << BRIDGE_SHIFT) +#define NRT_DART_BRIDGE (1 << BRIDGE_SHIFT) +#define NRT_TOP_WIDGETS (2 << BRIDGE_SHIFT) +#define NRT_TOP_BRIDGE (3 << BRIDGE_SHIFT) +#define RT_TOP_WIDGETS (4 << BRIDGE_SHIFT) +#define RT_TOP_BRIDGE (5 << BRIDGE_SHIFT) +#define UPERF_WIDGETS (6 << BRIDGE_SHIFT) +#define UPERF_BRIDGE (7 << BRIDGE_SHIFT) +#define CDIO_WIDGETS (8 << BRIDGE_SHIFT) +#define CDIO_BRIDGE (9 << BRIDGE_SHIFT) + +static const u_int32_t bridge_registers[] = { + NRT_DART_WIDGETS_BASE_ADDR, NRT_DART_PL301_BASE_ADDR, + NRT_TOP_WIDGETS_BASE_ADDR, NRT_TOP_PL301_BASE_ADDR, + RT_TOP_WIDGETS_BASE_ADDR, RT_TOP_PL301_BASE_ADDR, + UPERF_WIDGETS_BASE_ADDR, UPERF_PL301_BASE_ADDR, + CDIO_WIDGETS_BASE_ADDR, CDIO_PL301_BASE_ADDR, +}; + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +// The following settings are based on H4P Tunables Revision 0.12 + +static const u_int32_t bridge_settings_static[] = { + // Configure recommended transaction limits in CDIO + CDIO_WIDGETS | CDIO_IOP_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_IOP_WTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_CDMA_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_CDMA_WTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_UPERF_RTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_UPERF_WTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_AUDIO_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_AUDIO_WTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_PIO_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_PIO_WTLIMIT, 0x00000404, + + // Configure recommended bridge settings in CDIO + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x01000001, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x02000002, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x03000003, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x04000004, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x01000001, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x02000002, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x03000003, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x04000004, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x00000000, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x01000001, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x02000002, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x03000003, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x04000004, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x01000001, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x02000002, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x03000003, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x04000004, + + // Configure recommended features in CDIO + CDIO_WIDGETS | CDIO_IOP_WREQSP, 0x00000003, + CDIO_WIDGETS | CDIO_CDMA_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_UPERF_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_AUDIO_WGATHER, 0x00000100, + + // Configure recommended traffic attributes in UPERF + // AxCACHE = Cacheable + // AxUSER = enable Shared bit + UPERF_WIDGETS | UPERF_OTG_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OTG_CACHE, 0x01020102, + UPERF_WIDGETS | UPERF_EHCI_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_EHCI_CACHE, 0x01020102, + UPERF_WIDGETS | UPERF_OHCI0_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI0_CACHE, 0x01020102, + UPERF_WIDGETS | UPERF_OHCI1_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI1_CACHE, 0x01020102, + + 0, 0, + 0, 0 +}; +#endif // APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +#if WITH_DEVICETREE || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static const u_int32_t bridge_settings_dynamic[] = { + // Configure recommended transaction limits in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_RTLIMIT, 0x00000808, + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_WTLIMIT, 0x00000808, + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x02000102, // Scaler0 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x03000103, // Sclaer1 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x02000102, // Scaler0 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x03000103, // Sclaer1 Reduced Priority + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_QOS, 0x01010101, // JPEG0 LLT Traffic for R&W + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_QOS, 0x01010101, // JPEG0 LLT Traffic for R&W + 0, 0, + + // Configure recommended transaction limits in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_RTLIMIT, 0x00001010, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_WTLIMIT, 0x00000808, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_RTLIMIT, 0x00001010, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_WTLIMIT, 0x00000808, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_WTLIMIT, 0x00000F0F, + + // Configure recommended bridge settings in HPerf-NRT Top + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x03000003, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x03000003, + + // Configure recommended features in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_DART_WGATHER, 0x00000000, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_WREQSP, 0x00000003, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_WREQSP, 0x00000003, + 0, 0, + + // Configure recommended transaction limits in HPerf-RT Top + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_WTLIMIT, 0x00000F0F, + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP0_RTLIMIT, 0x00000C0C, + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP1_RTLIMIT, 0x00001010, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_RTLIMIT, 0x00000C0C, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_WTLIMIT, 0x00001010, + + // Configure recommended bridge settings in HPerf-RT Top + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x00000000, + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x01000001, + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x02000002, + 0, 0, + + 0, 0 +}; +#endif // WITH_DEVICETREE || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif + +#if APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC + // Configure recommended transaction limits in CIF + rCIF_RTLIMIT = 0x00000808; + rCIF_WTLIMIT = 0x00000808; + + // Tunables recommendation, for SCU clock-gating + // (will change to 0x80 for ) + rCIF_IDLETMR = 0x00000010; +#endif + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Configure bridges that are statically powered + clock_gate(CLK_UPERF, true); + miu_configure_bridge(bridge_settings_static); + clock_gate(CLK_UPERF, false); +#endif + +#if APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC + // Configure bridges that are dynamically powered + clock_gate(CLK_HPERFNRT, true); + clock_gate(CLK_HPERFRT, true); + miu_configure_bridge(bridge_settings_dynamic); + clock_gate(CLK_HPERFNRT, false); + clock_gate(CLK_HPERFRT, false); + + /* Enable the SCU. Note that we explicitly do NOT touch the + * "power status" register, since the default is supposed to + * be correct, and the real control is in the CPU's "SMP" + * bit. */ + rSCU_TAG_INVAL = 0xff; /* invalidate SCU tags for all CPUs */ + + /* Enable SCU, standby, speculative linefills, and parity */ + rSCU_CONTROL = (1 << 5) | (1 << 3) | (1 << 2) | (1 << 0); +#endif + + /* remap whatever bank of ram we're in to zero */ + if (TEXT_BASE == SRAM_BASE) + miu_select_remap(REMAP_SRAM); + else if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) + miu_select_remap(REMAP_SDRAM); + + return 0; +} + +static void miu_configure_bridge(const u_int32_t *bridge_settings) +{ + volatile u_int32_t *reg; + u_int32_t cnt = 0, bridge, offset, data; + + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + bridge = bridge_settings[cnt] >> BRIDGE_SHIFT; + offset = bridge_settings[cnt] & BRIDGE_MASK; + data = bridge_settings[cnt + 1]; + reg = (volatile u_int32_t *)(bridge_registers[bridge] + offset); + *reg = data; + cnt += 2; + } + cnt += 2; + } +} + +void miu_suspend(void) +{ + /* XXX ? */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rREMAP_CTL = (rREMAP_CTL & ~3) | (1 << 0); // remap_sel = 1 + rPL310_FILTER_START = 0x1; + break; + case REMAP_SDRAM: + rREMAP_CTL = (rREMAP_CTL & ~3) | (2 << 0); // remap_sel = 2 + // Leave low megabyte heading to DRAM for wake-from-sleep, + // Otherwise send everything below DRAM to the PIO block. + // Currently this is for testing only; it is not POR. + rPL310_FILTER_END = 0x80000000; + rPL310_FILTER_START = 0x00100001; + break; + } + + /* read remap register to ensure it has been updated */ + rREMAP_CTL; +} + +void miu_bypass_prep(void) +{ +#if APPLICATION_IBOOT + extern void mcu_bypass_prep(void); + mcu_bypass_prep(); +#endif +} + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + + // Fill in the bridge-settings property + propName = "bridge-settings"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(bridge_settings_dynamic)) { + memcpy(propData, bridge_settings_dynamic, sizeof(bridge_settings_dynamic)); + } + } +} + +#endif diff --git a/platform/s5l8940x/miu/rules.mk b/platform/s5l8940x/miu/rules.mk new file mode 100644 index 0000000..2e9d938 --- /dev/null +++ b/platform/s5l8940x/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s5l8940x/pinconfig_s5l8940x.c b/platform/s5l8940x/pinconfig_s5l8940x.c new file mode 100644 index 0000000..4b2fe75 --- /dev/null +++ b/platform/s5l8940x/pinconfig_s5l8940x.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +/* Default S5L8940X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X3 + +#if !WITH_TARGET_CONFIG +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY + CFG_IN, // GPIO1 -> HOLD_KEY + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED | PULL_DOWN, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED | PULL_DOWN, // GPIO7 -> + +/* Port 1 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED | PULL_DOWN, // GPIO19 -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED | PULL_DOWN, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + +/* Port 4 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // GPIO39 -> + +/* Port 5 */ + CFG_DISABLED, // EHCI_PORT_PWR[0] -> + CFG_DISABLED, // EHCI_PORT_PWR[1] -> + CFG_DISABLED, // EHCI_PORT_PWR[2] -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + +/* Port 6 */ + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RTXD -> + +/* Port 7 */ + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // UART6_RTSN -> + CFG_DISABLED, // UART6_CTSN -> + CFG_DISABLED, // UART4_TXD/SPI4_MOSI -> + CFG_DISABLED, // UART4_RXD/SPI4_MISO -> + CFG_DISABLED, // UART4_RTSN/SPI4_SCLK -> + CFG_DISABLED, // UART4_CTSN/SPI4_SSIN -> + +/* Port 8 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + +/* Port 9 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO1 -> + +/* Port 10 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + +/* Port 11 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO2 -> + +/* Port 12 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED, // FMI2_CEN3 -> + CFG_DISABLED, // FMI2_CEN2 -> + CFG_DISABLED, // FMI2_CEN1 -> + CFG_DISABLED, // FMI2_CEN0 -> + CFG_DISABLED, // FMI2_CLE -> + CFG_DISABLED, // FMI2_ALE -> + +/* Port 13 */ + CFG_DISABLED, // FMI2_REN -> + CFG_DISABLED, // FMI2_WEN -> + CFG_DISABLED, // FMI2_IO7 -> + CFG_DISABLED, // FMI2_IO6 -> + CFG_DISABLED, // FMI2_IO5 -> + CFG_DISABLED, // FMI2_IO4 -> + CFG_DISABLED, // FMI2_DQS -> + CFG_DISABLED, // FMI2_IO3 -> + +/* Port 14 */ + CFG_DISABLED, // FMI2_IO2 -> + CFG_DISABLED, // FMI2_IO1 -> + CFG_DISABLED, // FMI2_IO0 -> + CFG_DISABLED, // FMI0_CEN7 -> + CFG_DISABLED, // FMI0_CEN6 -> + CFG_DISABLED, // FMI0_CEN5 -> + CFG_DISABLED, // FMI0_CEN4 -> + CFG_DISABLED, // FMI1_CEN7 -> + +/* Port 15 */ + CFG_DISABLED, // FMI1_CEN6 -> + CFG_DISABLED, // FMI1_CEN5 -> + CFG_DISABLED, // FMI1_CEN4 -> + CFG_DISABLED, // FMI3_CEN3 -> + CFG_DISABLED, // FMI3_CEN2 -> + CFG_DISABLED, // FMI3_CEN1 -> + CFG_DISABLED, // FMI3_CEN0 -> + CFG_DISABLED, // FMI3_CLE -> + +/* Port 16 */ + CFG_DISABLED, // FMI3_ALE -> + CFG_DISABLED, // FMI3_REN -> + CFG_DISABLED, // FMI3_WEN -> + CFG_DISABLED, // FMI3_IO7 -> + CFG_DISABLED, // FMI3_IO6 -> + CFG_DISABLED, // FMI3_IO5 -> + CFG_DISABLED, // FMI3_IO4 -> + CFG_DISABLED, // FMI3_DQS -> + +/* Port 17 */ + CFG_DISABLED, // FMI3_IO3 -> + CFG_DISABLED, // FMI3_IO2 -> + CFG_DISABLED, // FMI3_IO1 -> + CFG_DISABLED, // FMI3_IO0 -> + CFG_DISABLED, // FMI2_CEN7 -> + CFG_DISABLED, // FMI2_CEN6 -> + CFG_DISABLED, // FMI2_CEN5 -> + CFG_DISABLED, // FMI2_CEN4 -> + +/* Port 18 */ + CFG_DISABLED, // FMI3_CEN7 -> + CFG_DISABLED, // FMI3_CEN6 -> + CFG_DISABLED, // FMI3_CEN5 -> + CFG_DISABLED, // FMI3_CEN4 -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + +/* Port 19 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 20 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> SPI0_SSIN + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 21 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + +/* Port 22 */ + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SDIO_CLK -> + CFG_DISABLED, // SDIO_CMD -> + CFG_DISABLED, // SDIO_DATA0 -> + CFG_DISABLED, // SDIO_DATA1 -> + CFG_DISABLED, // SDIO_DATA2 -> + CFG_DISABLED, // SDIO_DATA3 -> + +/* Port 23 */ + CFG_DISABLED, // MIPI_VSYNC -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // SWI_DATA -> + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_DO -> + CFG_DISABLED, // DWI_CLK -> + +/* Port 24 */ + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + +/* Port 25 */ + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S2_LRCK -> + +/* Port 26 */ + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + +/* Port 27 */ + CFG_DISABLED, // SPDIF -> + CFG_DISABLED | PULL_DOWN, // GPIO217 -> + CFG_DISABLED, // GPIO218 -> + CFG_DISABLED, // DP_HPD -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 28 */ + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +const uint32_t *platform_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} +#endif diff --git a/platform/s5l8940x/pinconfig_s5l8942x.c b/platform/s5l8940x/pinconfig_s5l8942x.c new file mode 100644 index 0000000..c2817c9 --- /dev/null +++ b/platform/s5l8940x/pinconfig_s5l8942x.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +/* Default S5L8942X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X2 +#define FMI_SLEW_RATE SLEW_RATE_SLOW + +#if !WITH_TARGET_CONFIG +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY + CFG_IN, // GPIO1 -> HOLD_KEY + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 1 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> KEEPACT + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 3 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + +/* Port 4 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // EHCI_PORT_PWR[0] -> BOARD_REV[0] + CFG_DISABLED, // EHCI_PORT_PWR[1] -> BOARD_REV[1] + CFG_DISABLED, // EHCI_PORT_PWR[2] -> BOARD_REV[2] + +/* Port 5 */ + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + +/* Port 6 */ + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + +/* Port 7 */ + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // UART5_TXD/MIPI_VSYNC -> + CFG_DISABLED, // TMR32_PWM0 + CFG_DISABLED, // TMR32_PWM1 + CFG_DISABLED, // TMR32_PWM2 + +/* Port 8 */ + CFG_DISABLED, // SWI_DATA -> + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_DO -> + CFG_DISABLED, // DWI_CLK -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + +/* Port 9 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_SCLK -> + CFG_DISABLED, // I2S0_DOUT -> + +/* Port 10 */ + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_SCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S2_LRCK -> + +/* Port 11 */ + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + +/* Port 12 */ + CFG_DISABLED, // SPI0_SCLK -> BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 13 */ + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_DISABLED, // UART4_TXD -> SPI3_SCLK/FMI0_CEN7 + CFG_DISABLED, // UART4_RXD -> SPI3_MOSI/FMI0_CEN6 + CFG_DISABLED, // UART4_RTSN -> SPI3_MISO/FMI0_CEN5 + CFG_DISABLED, // UART4_CTSN -> SPI3_SSIN/FMI0_CEN4 + CFG_DISABLED, // SDIO0_DATA3 -> FMI1_CEN7 + CFG_DISABLED, // SDIO0_DATA2 -> FMI1_CEN6 + CFG_DISABLED, // SDIO0_DATA1 -> FMI1_CEN5 + CFG_DISABLED, // SDIO0_DATA0 -> FMI1_CEN4 + +/* Port 17 */ + CFG_DISABLED, // SDIO0_CMD -> + CFG_DISABLED, // SDIO0_CLK -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN3 -> FMI0_RBN0 + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN2 -> FMI0_RBN1 + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + +/* Port 18 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 19 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 20 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN1 -> + +/* Port 21 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO5 -> + +/* Port 22 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 23 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 24 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // UART5_RTXD -> UART5_RXD + CFG_DISABLED, // DP_HPD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 25 */ + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +const uint32_t *platform_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} +#endif diff --git a/platform/s5l8940x/pinconfig_s5l8947x.c b/platform/s5l8940x/pinconfig_s5l8947x.c new file mode 100644 index 0000000..06c8081 --- /dev/null +++ b/platform/s5l8940x/pinconfig_s5l8947x.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2009-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +/* Default S5L8947X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X2 +#define FMI_SLEW_RATE SLEW_RATE_SLOW + +#if !WITH_TARGET_CONFIG +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // I2S0_MCK -> + CFG_IN, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // UART1_TXD -> + +/* Port 1 */ + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // HDMI_HPD -> + CFG_DISABLED, // HDMI_CEC -> + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // SPDIF -> + +/* Port 2 */ + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + +/* Port 3 */ + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED | PULL_DOWN, // TST_STPCLK -> + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 4 */ + CFG_DISABLED, // ENET_MDC -> + CFG_DISABLED, // ENET_MDIO -> + CFG_DISABLED, // RMII_CLK -> + CFG_DISABLED, // RMII_RXER -> + CFG_DISABLED, // RMII_TXD[0] -> + CFG_DISABLED, // RMII_CRSDV -> + CFG_DISABLED, // RMII_RXD[0] -> + CFG_DISABLED, // RMII_RXD[1] -> + +/* Port 5 */ + CFG_DISABLED, // RMII_TXD[1] -> + CFG_DISABLED, // RMII_TXEN -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN[1] -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN[0] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + +/* Port 6 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[7] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[6] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[5] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[4] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[3] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[2] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[1] -> + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO[0] -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN[1] -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN[0] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[7] -> + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[6] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[5] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[4] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[3] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[2] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[1] -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO[0] -> + +/* Port 9 */ + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + +/* Port 10 */ + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + +/* Port 11 */ + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + CFG_DISABLED, // + +/* Port 12 */ + CFG_IN, // GPIO0 -> MENU_KEY + CFG_IN, // GPIO1 -> HOLD_KEY + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 13 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 14 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> KEEPACT + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG{2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + +/* Port 17 */ + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> + CFG_DISABLED, // SWI_DATA -> +}; + +const uint32_t *platform_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} +#endif diff --git a/platform/s5l8940x/pmgr/pmgr.c b/platform/s5l8940x/pmgr/pmgr.c new file mode 100644 index 0000000..dfd30f6 --- /dev/null +++ b/platform/s5l8940x/pmgr/pmgr.c @@ -0,0 +1,1306 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !APPLICATION_EMBEDDEDIOP + +#define PLL_VCO_TARGET(pllx) (2ULL * pllx##_O * pllx##_M / pllx##_P) +#define PLL_FREQ_TARGET(pllx) (2ULL * pllx##_O * pllx##_M / pllx##_P / (1 << pllx##_S)) + +static u_int32_t clk_divs_bypass[PMGR_CLK_CFG_COUNT] = { + 0x80008421, 0x80000000, 0x80000001, 0x80000001, // cpu, mcu_fixed, mcu, pclk1 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // prediv0, prediv1, prediv2, prediv3 + 0x80000001, 0x80000001, 0x80000001, 0x80000000, // prediv4, prediv5, prediv6, managed0 + 0x80000000, 0x80000000, 0x80000000, 0x80000000, // managed1, managed2, managed3, managed4 + 0x80000001, 0x80000001, 0x80000001, 0xB0000001, // vid1, medium0, vid0, i2c + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // sdio, mipi_dsi, audio, hpark_pclk0 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // hpark_tclk, uperf, debug, hperf_rt + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // gfx, gfx_slc, hperf_nrt, isp + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, 0x8000001f, 0x80000001, // pclk2, pclk3, medium1, spi0 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // spi1, spi2, spi3, spi4 + 0x80000021, 0x80000001, 0x80000001, 0x80000001, // sleep, usbphy, usbohci, usb12 + 0x80000001, 0x80000001, 0x80000000, 0x80000001, // nco_ref0, nco_ref1, venc_mtx, venc +}; + +static u_int32_t perf_state_bypass[3] = { + 0x01010101, 0x03010101, 0x00000001, // defaults, slow mcu_cfg +}; + +struct perf_info { + u_int8_t perf_state; + u_int8_t perf_div; +}; + +#if APPLICATION_IBOOT + +#ifndef TARGET_EMA_CTL_CPU_SEL +#define TARGET_EMA_CTL_CPU_SEL 1 +#endif + +#ifndef TARGET_CPU_SOURCE +#define TARGET_CPU_SOURCE 1 +#endif + +#ifndef TARGET_SPI2_SOURCE +#define TARGET_SPI2_SOURCE 3 +#endif + +#ifndef TARGET_MIPI_DSI_SOURCE +#error TARGET_MIPI_DSI_SOURCE undefined +#endif + +#ifndef TARGET_MANAGED2H_SOURCE +#error TARGET_MANAGED2H_SOURCE undefined +#endif + +#ifndef TARGET_MANAGED2L_SOURCE +#error TARGET_MANAGED2L_SOURCE undefined +#endif + +#ifndef TARGET_MANAGED2H_DIV +#error TARGET_MANAGED2H_DIV undefined +#endif + +#ifndef TARGET_MANAGED2L_DIV +#error TARGET_MANAGED2L_DIV undefined +#endif + +#ifndef TARGET_GFX_SOURCE +#error TARGET_GFX_SOURCE undefined +#endif + +#ifndef TARGET_GFX_SLC_SOURCE +#error TARGET_GFX_SLC_SOURCE undefined +#endif + +#ifndef TARGET_CPU_850M + +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 6 +#define PLL0_M 250 +#define PLL0_S 1 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +#endif + +#if TARGET_CPU_SOURCE == 2 +#if TARGET_CPU_850M + +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 12 +#define PLL1_M 425 +#define PLL1_S 1 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#else /* ! TARGET_CPU_850M */ + +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 6 +#define PLL1_M 200 +#define PLL1_S 1 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#endif /* TARGET_CPU_850M */ +#endif + +#if TARGET_DDR_533M + +// Defined for SUB_PLATFORM_S5L8947X +// Radar - PR-12088495 PR-12142624 PR-12073123 (P & M values changed) +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 14 +#define PLL2_M 311 +#define PLL2_S 1 +#define PLL2_V PLL_VCO_TARGET(PLL2) +#define PLL2_T PLL_FREQ_TARGET(PLL2) + +#else /* TARGET_DDR_533M */ + +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 6 +#define PLL2_M 200 +#define PLL2_S 2 +#define PLL2_V PLL_VCO_TARGET(PLL2) +#define PLL2_T PLL_FREQ_TARGET(PLL2) + +#endif /* TARGET_DDR_533M */ + +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 4 +#define PLL3_M 171 +#define PLL3_S 1 +#define PLL3_V PLL_VCO_TARGET(PLL3) +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +#if (TARGET_CPU_850M && TARGET_DDR_533M) + +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 5 +#define PLL4_M 130 +#define PLL4_S 1 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) + +#endif + +#if TARGET_USE_HSIC + +#if TARGET_DDR_533M +#define PLLUSB USB +#define PLLUSB_O OSC_FREQ +#define PLLUSB_P 5 +#define PLLUSB_M 200 +#define PLLUSB_S 2 +#define PLLUSB_V PLL_VCO_TARGET(PLLUSB) +#define PLLUSB_T PLL_FREQ_TARGET(PLLUSB) +#else +#define PLLUSB USB +#define PLLUSB_O OSC_FREQ +#define PLLUSB_P 4 +#define PLLUSB_M 160 +#define PLLUSB_S 2 +#define PLLUSB_V PLL_VCO_TARGET(PLLUSB) +#define PLLUSB_T PLL_FREQ_TARGET(PLLUSB) +#endif + +#define OHCI_SOURCE (0) +#define D_MEDIUM1 (0x8000000A) + +#else /* ! TARGET_USE_HSIC */ + +#define OHCI_SOURCE (1) +#define D_MEDIUM1 (0x00000000) + +#endif /* TARGET_USE_HSIC */ + +#ifndef TARGET_CPU_SOURCE +#error TARGET_CPU_SOURCE undefined +#else +#define D_CPU (0x80011041 | ((TARGET_CPU_SOURCE) << 28)) +#endif + +#define D_CLK_DOUBLER (0x8000001F) + +#ifndef TARGET_MIPI_DSI_SOURCE +#error TARGET_MIPI_DSI_SOURCE undefined +#else +#define D_MIPI_DSI (0x80000001 | ((TARGET_MIPI_DSI_SOURCE) << 28)) +#endif + +#ifndef TARGET_SPI2_SOURCE +#error TARGET_SPI2_SOURCE undefined +#else +#define D_SPI2 (0x80000001 | ((TARGET_SPI2_SOURCE) << 28)) +#endif + +#ifndef TARGET_IOP_SOURCE +#error TARGET_IOP_SOURCE undefined +#else +#define D_IOP (0x80000001 | ((TARGET_IOP_SOURCE) << 28)) +#endif + +#ifndef TARGET_LPERFS_SOURCE +#error TARGET_LPERFS_SOURCE undefined +#else +#define D_LPERFS (0x80000002 | ((TARGET_LPERFS_SOURCE) << 28)) +#endif + +#ifndef TARGET_HPERFNRT_SOURCE +#error TARGET_HPERFNRT_SOURCE undefined +#else +#define D_HPERFNRT (0x80000001 | ((TARGET_HPERFNRT_SOURCE) << 28)) +#endif + +#if TARGET_USE_PREDIV4 +#define D_PREDIV4 (0x80000000 | (((TARGET_PREDIV4_SOURCE) << 28) | ((TARGET_PREDIV4_DIV) << 0))) +#else +#define D_PREDIV4 (0x00000000) +#endif + +#define D_GFX (0x80000001 | ((TARGET_GFX_SOURCE) << 28)) +#define D_GFX_SLC (0x80000001 | ((TARGET_GFX_SLC_SOURCE) << 28)) + +#define D_OHCI (0x80000001 | ((OHCI_SOURCE) << 28)) + +#ifndef TARGET_PCLK1_SOURCE +#error TARGET_PCLK1_SOURCE undefined +#else +#define D_PCLK1 (0x80000000 | (((TARGET_PCLK1_SOURCE) << 28) | ((TARGET_PCLK1_DIV) << 0))) +#endif + +static u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + D_CPU, 0x80000000, 0x80000001, D_PCLK1, // cpu, mcu_fixed, mcu, pclk1 + 0xA0000005, 0xA0000002, 0xA0000003, 0x00000000, // prediv0, prediv1, prediv2, prediv3 + D_PREDIV4, 0x00000000, 0xA0000014, 0x80000000, // prediv4, prediv5, prediv6, managed0 + 0x00000000, 0x80000000, 0x80000000, 0x80000000, // managed1, managed2, managed3, managed4 + 0xA0000013, 0x80000004, 0xB0000001, 0x80000008, // vid1, medium0, vid0, i2c + 0x80000004, D_MIPI_DSI, 0xA0000002, 0x90000004, // sdio, mipi_dsi, audio, hpark_pclk0 + 0xA0000002, 0xA0000007, 0x80000008, 0x80000001, // hpark_tclk, uperf, debug, hperf_rt + D_GFX, D_GFX_SLC, D_HPERFNRT, 0x80000001, // gfx, gfx_slc, hperf_nrt, isp + D_IOP, 0xB0000001, D_LPERFS, 0x80000001, // iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, D_MEDIUM1, 0xB0000001, // pclk2, pclk3, medium1, spi0 + 0xB0000001, D_SPI2, 0xB0000001, 0xB0000001, // spi1, spi2, spi3, spi4 + 0x80000314, 0x80000001, D_OHCI, 0x80000002, // sleep, usbphy, usbohci, usb12 + 0xA0000001, 0x00000000, 0x80000000, 0x80000002, // nco_ref0, nco_ref1, venc_mtx, venc +}; + +#define PLL_GATES_ACTIVE (1 << 3) + +static struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kPERF_STATE_IBOOT+0, 1 }, + [kPerformanceMedium] = { kPERF_STATE_IBOOT+1, 2 }, + [kPerformanceLow] = { kPERF_STATE_IBOOT+2, 4 }, + [kPerformanceMemory] = { kPERF_STATE_IBOOT+4, 4 }, +}; + +// Configure Full Performance MANAGED2 based on TARGET defines +// TARGETS: n78, n94, k93a, ipad2, j33, s5l8940xfpga, s5l8947xfpga, s5l8942xfpga +#define M_PERF_A0 (0x01000001 | ((((TARGET_MANAGED2H_SOURCE) << 5) | ((TARGET_MANAGED2H_DIV) << 0)) << 16)) // managed3 divide by 1 +#define M_PERF_A1 (0x02000002 | ((((TARGET_MANAGED2L_SOURCE) << 5) | ((TARGET_MANAGED2L_DIV) << 0)) << 16)) // managed3 divide by 2 +#define M_PERF_A2 (0x04000002 | ((((TARGET_MANAGED2L_SOURCE) << 5) | ((TARGET_MANAGED2L_DIV) << 0)) << 16)) // managed3 divide by 4 +#define M_PERF_A3 (0x1F000002 | ((((TARGET_MANAGED2L_SOURCE) << 5) | ((TARGET_MANAGED2L_DIV) << 0)) << 16)) // managed3 divide by 31 + +#define PERF_STATE_ACTIVE kPERF_STATE_IBOOT + +// perf_state_active : These 5 performance state definitions are used in iBoot and as templates +// to then generate the OS Performance Controller states in kext's function +// AppleS5L8940XPerformanceController::generatePerformanceStates +// +// state 0 : High voltage PERF_STATE template +// state 1 : Low voltage PERF_STATE template +// state 2 : Used in iBoot only +// state 3 : Frequency managed clocks template +// (dividers of frequency managed clocks must be set to 0x1F) +// state 4 : Used in iBoot only for memory calibration +#if SUPPORT_FPGA +static u_int32_t perf_state_active[kPERF_STATE_IBOOT_CNT*3] = { + // mcu_cfg=3, mcu_clk and mcu_fixed_clk always divide by 1 + M_PERF_A0, 0x03210122, 0x00000021, // divide by 1 + M_PERF_A1, 0x03210124, 0x00000022, // divide by 2 + M_PERF_A2, 0x03210124, 0x00000022, // divide by 4 + M_PERF_A3, 0x03210124, 0x00000022, // divide by 31 + M_PERF_A2, 0x03210124, 0x00000022, // divide by 4 +}; +#else +static u_int32_t perf_state_active[kPERF_STATE_IBOOT_CNT*3] = { +//PERF_STATE_xA, PERF_STATE_xB, PERF_STATE_xC +#if (TARGET_CPU_850M && TARGET_DDR_533M) + M_PERF_A0, 0x00210141, 0x00000021, // managed3 divide by 1, mcu_clk / 1, mcu_cfg=0 //533 Mhz + M_PERF_A1, 0x00210141, 0x00000022, // managed3 divide by 2, mcu_clk / 1, mcu_cfg=0 //533 Mhz + M_PERF_A2, 0x02210541, 0x00000022, // managed3 divide by 4, mcu_clk / 5, mcu_cfg=2 //106 Mhz + M_PERF_A3, 0x03210A41, 0x00000022, // managed3 divide by 31, mcu_clk / 10, mcu_cfg=3 //53 Mhz + M_PERF_A2, 0x00210141, 0x00000022, // managed3 divide by 4, mcu_clk / 1, mcu_cfg=0 //533 Mhz +#elif TARGET_DDR_256M + M_PERF_A0, 0x00440122, 0x00000021, // managed3 divide by 1, mcu_clk / 1, mcu_cfg=0 + M_PERF_A1, 0x01440224, 0x00000022, // managed3 divide by 2, mcu_clk / 2, mcu_cfg=1 + M_PERF_A2, 0x02440424, 0x00000022, // managed3 divide by 4, mcu_clk / 4, mcu_cfg=2 + M_PERF_A3, 0x03440824, 0x00000022, // managed3 divide by 31, mcu_clk / 8, mcu_cfg=3 + M_PERF_A2, 0x00440124, 0x00000022, // managed3 divide by 4, mcu_clk / 1, mcu_cfg=0 +#else + M_PERF_A0, 0x00210122, 0x00000021, // managed3 divide by 1, mcu_clk / 1, mcu_cfg=0 + M_PERF_A1, 0x01210224, 0x00000022, // managed3 divide by 2, mcu_clk / 2, mcu_cfg=1 + M_PERF_A2, 0x02210424, 0x00000022, // managed3 divide by 4, mcu_clk / 4, mcu_cfg=2 + M_PERF_A3, 0x03210824, 0x00000022, // managed3 divide by 31, mcu_clk / 8, mcu_cfg=3 + M_PERF_A2, 0x00210124, 0x00000022, // managed3 divide by 4, mcu_clk / 1, mcu_cfg=0 +#endif /* (TARGET_CPU_850M && TARGET_DDR_533M) */ +}; +#endif + +#endif + +#if APPLICATION_SECUREROM + +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 6 +#define PLL0_M 125 +#define PLL0_S 2 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 4 +#define PLL3_M 171 +#define PLL3_S 3 +#define PLL3_V PLL_VCO_TARGET(PLL3) +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +static u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x90021041, 0x80000001, 0x80000001, 0xA0000003, // cpu, mcu_fixed, mcu, pclk1 + 0xA0000001, 0x00000000, 0x00000000, 0x00000000, // prediv0, prediv1, prediv2, prediv3 + 0x00000000, 0x00000000, 0x00000000, 0x80000001, // prediv4, prediv5, prediv6, managed0 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // managed1, managed2, managed3, managed4 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // vid1, medium0, vid0, i2c + 0x00000000, 0x00000000, 0x80000002, 0x00000000, // sdio, mipi_dsi, audio, hpark_pclk0 + 0x00000000, 0x80000008, 0x80000008, 0x00000000, // hpark_tclk, uperf, debug, hperf_rt + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // gfx, gfx_slc, hperf_nrt, isp + 0x00000000, 0x80000001, 0x80000001, 0x80000001, // iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, 0x00000000, 0xB0000001, // pclk2, pclk3, medium1, spi0 + 0x80000001, 0x80000001, 0xB0000001, 0x80000001, // spi1, spi2, spi3, spi4 + 0x80000314, 0x80000001, 0x80000001, 0x80000002, // sleep, usbphy, usbohci, usb12 + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // nco_ref0, nco_ref1, venc_mtx, venc +}; +#define PLL_GATES_ACTIVE (1 << 3) + +#define PERF_STATE_ACTIVE kPERF_STATE_SECUREROM +static u_int32_t perf_state_active[3] = { + 0x00000004, 0x03010100, 0x00000000, // managed0, slow mcu_cfg +}; + +static struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kPERF_STATE_SECUREROM, 1 }, + [kPerformanceMedium] = { kPERF_STATE_SECUREROM, 1 }, + [kPerformanceLow] = { kPERF_STATE_SECUREROM, 1 }, + [kPerformanceMemory] = { kPERF_STATE_SECUREROM, 1 }, +}; + +#endif + +/* current clock speeds */ +static u_int32_t clks[PMGR_CLK_COUNT]; +static u_int32_t *plls = &clks[PMGR_CLK_PLL0]; +static u_int32_t perf_level; +static u_int32_t perf_div; + +struct clk_parent { + volatile u_int32_t *divider_reg; + u_int32_t divider_slot; + u_int8_t parents[4]; +}; + +/* Based on PMGR 1.10 */ +static const struct clk_parent clk_parents[PMGR_CLK_COUNT] = { +[PMGR_CLK_OSC] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL0] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL1] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL2] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL3] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL4] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLLUSB] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_DOUBLER] = { &rPMGR_DOUBLER_CTL, 0, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_CPU] = { &rPMGR_CPU_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL0, PMGR_CLK_PLL1, 0 } }, +[PMGR_CLK_MEM] = { &rPMGR_CPU_CLK_CFG, 2, { PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU } }, +[PMGR_CLK_PIO] = { &rPMGR_CPU_CLK_CFG, 3, { PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU } }, +[PMGR_CLK_ACP] = { &rPMGR_CPU_CLK_CFG, 4, { PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU } }, +[PMGR_CLK_MCU_FIXED] = { &rPMGR_MCU_FIXED_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_MCU] = { &rPMGR_MCU_CLK_CFG, 1, { PMGR_CLK_MCU_FIXED, 0, 0, 0 } }, +[PMGR_CLK_PREDIV0] = { &rPMGR_PREDIV0_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV1] = { &rPMGR_PREDIV1_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV2] = { &rPMGR_PREDIV2_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV3] = { &rPMGR_PREDIV3_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV4] = { &rPMGR_PREDIV4_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV5] = { &rPMGR_PREDIV5_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV6] = { &rPMGR_PREDIV6_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_MANAGED0] = { &rPMGR_MANAGED0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV4, PMGR_CLK_PREDIV5 } }, +[PMGR_CLK_MANAGED1] = { &rPMGR_MANAGED1_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MANAGED2] = { &rPMGR_MANAGED2_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MANAGED3] = { &rPMGR_MANAGED3_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MANAGED4] = { &rPMGR_MANAGED4_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV4, PMGR_CLK_PREDIV5 } }, +[PMGR_CLK_MEDIUM0] = { &rPMGR_MEDIUM0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MEDIUM1] = { &rPMGR_MEDIUM1_CLK_CFG, 1, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_VID0] = { &rPMGR_VID0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV6 } }, +[PMGR_CLK_VID1] = { &rPMGR_VID1_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_I2C] = { &rPMGR_I2C_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_OSC } }, +[PMGR_CLK_SDIO] = { &rPMGR_SDIO_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MIPI_DSI] = { &rPMGR_MIPI_DSI_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_AUDIO] = { &rPMGR_AUDIO_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_HPARK_PCLK] = { &rPMGR_HPARK_PCLK0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_HPARK_TCLK] = { &rPMGR_HPARK_TCLK_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_UPERF] = { &rPMGR_UPERF_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_DEBUG] = { &rPMGR_DEBUG_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_OSC } }, +[PMGR_CLK_GFX] = { &rPMGR_GFX_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED4 } }, +[PMGR_CLK_GFX_SLC] = { &rPMGR_GFX_SLC_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED4 } }, +[PMGR_CLK_HPERFNRT] = { &rPMGR_HPERFNRT_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_HPERFRT] = { &rPMGR_HPERFRT_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_ISP] = { &rPMGR_ISP_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_IOP] = { &rPMGR_IOP_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_CDIO] = { &rPMGR_CDIO_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_LPERFS] = { &rPMGR_LPERFS_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_PCLK0] = { &rPMGR_PCLK0_CLK_CFG, 0, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK1] = { &rPMGR_PCLK1_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PCLK2] = { &rPMGR_PCLK2_CLK_CFG, 0, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK3] = { &rPMGR_PCLK3_CLK_CFG, 0, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_SPI0] = { &rPMGR_SPI0_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI1] = { &rPMGR_SPI1_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI2] = { &rPMGR_SPI2_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI3] = { &rPMGR_SPI3_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI4] = { &rPMGR_SPI4_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SLOW] = { &rPMGR_SLEEP_CLK_CFG, 2, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_SLEEP] = { &rPMGR_SLEEP_CLK_CFG, 1, { PMGR_CLK_SLOW, 0, 0, 0 } }, +[PMGR_CLK_USBPHY] = { &rPMGR_USBPHY_CLK_CFG, 0, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_USBOHCI] = { &rPMGR_USBOHCI_CLK_CFG, 0, { PMGR_CLK_MEDIUM1, PMGR_CLK_DOUBLER, 0, 0 } }, +[PMGR_CLK_USB12] = { &rPMGR_USB12_CLK_CFG, 1, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_NCO_REF0] = { &rPMGR_NCO_REF0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_NCO_REF1] = { &rPMGR_NCO_REF1_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VENC_MTX] = { &rPMGR_VENC_MTX_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_VENC] = { &rPMGR_VENC_CLK_CFG, 1, { PMGR_CLK_VENC_MTX, 0, 0, 0 } }, +}; + +static void clocks_get_frequencies(void); +static u_int32_t get_pll(int pll); +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t v); +static void clocks_set_gates(u_int64_t *devices, bool enable); +static void clocks_quiesce_internal(void); +static void update_perf_state(u_int32_t new_perf_state); + +void platform_power_init(void) +{ + +#if (!SUB_PLATFORM_S5L8947X) + // Set Power Gating Parameters for all the power domains + rPMGR_PWR_GATE_TIME_A(1) = (208 << 16); // CPU0 + rPMGR_PWR_GATE_TIME_B(1) = (32 << 26); + rPMGR_PWR_GATE_TIME_A(2) = (208 << 16); // CPU1 + rPMGR_PWR_GATE_TIME_B(2) = (32 << 26); + rPMGR_PWR_GATE_TIME_A(3) = (54 << 16); // SCU + rPMGR_PWR_GATE_TIME_A(4) = (36 << 16); // L2RAM0 + rPMGR_PWR_GATE_TIME_A(5) = (36 << 16); // L2RAM1 + rPMGR_PWR_GATE_TIME_A(6) = (192 << 16) | (2 << 0); // IOP + rPMGR_PWR_GATE_TIME_B(6) = (32 << 26) | (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(7) = (568 << 16) | (7 << 0); // GFX + rPMGR_PWR_GATE_TIME_B(7) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(8) = (621 << 16) | (6 << 0); // HPERF-RT + rPMGR_PWR_GATE_TIME_B(8) = (2 << 16) | (2 << 8) | (9 << 0); + rPMGR_PWR_GATE_TIME_A(9) = (605 << 16) | (9 << 0); // ISP + rPMGR_PWR_GATE_TIME_B(9) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(10) = (366 << 16) | (4 << 0); // HPERF-NRT + rPMGR_PWR_GATE_TIME_B(10) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(11) = (472 << 16) | (6 << 0); // VDEC + rPMGR_PWR_GATE_TIME_B(11) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(12) = (529 << 16) | (8 << 0); // VENC + rPMGR_PWR_GATE_TIME_B(12) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(13) = (275 << 16) | (4 << 0); // FMI + rPMGR_PWR_GATE_TIME_B(13) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(14) = (149 << 16) | (1 << 0); // HPARK + rPMGR_PWR_GATE_TIME_B(14) = (2 << 16) | (2 << 8) | (4 << 0); + +#else + // Set Power Gating Parameters for all the power domains + rPMGR_PWR_GATE_TIME_A(1) = (180 << 16); // CPU0 + rPMGR_PWR_GATE_TIME_B(1) = (32 << 26); + rPMGR_PWR_GATE_TIME_A(3) = (36 << 16); // SCU + rPMGR_PWR_GATE_TIME_A(4) = (15 << 16); // L2RAM0 + rPMGR_PWR_GATE_TIME_A(6) = (35 << 16) | (1 << 0); // IOP + rPMGR_PWR_GATE_TIME_B(6) = (32 << 26) | (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(7) = (160 << 16) | (3 << 0); // GFX + rPMGR_PWR_GATE_TIME_B(7) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(8) = (126 << 16) | (3 << 0); // HPERF-RT + rPMGR_PWR_GATE_TIME_B(8) = (2 << 16) | (2 << 8) | (9 << 0); + rPMGR_PWR_GATE_TIME_A(10) = (76 << 16) | (2 << 0); // HPERF-NRT + rPMGR_PWR_GATE_TIME_B(10) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(11) = (78 << 16) | (2 << 0); // VDEC + rPMGR_PWR_GATE_TIME_B(11) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(13) = (33 << 16) | (1 << 0); // FMI + rPMGR_PWR_GATE_TIME_B(13) = (2 << 16) | (2 << 8) | (4 << 0); +#endif + +#if APPLICATION_IBOOT + /* clear CPU1's reset; it will still be powered down */ + clock_reset_device(CLK_CPU1); +#endif +} + +extern void aic_spin(u_int32_t usecs); + +void platform_power_spin(u_int32_t usecs) +{ + aic_spin(usecs); +} + +int clocks_init(void) +{ +#if APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) + + u_int32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + for (cnt = 0; cnt < 6; cnt++) plls[cnt] = get_pll(cnt); + + /* Calculate our initial performance divider based on CPU_DIVISOR */ + perf_div = (rPMGR_CPU_CLK_CFG & rPMGR_CLK_CFG_DIV_MASK) / (clk_divs_active[0] & rPMGR_CLK_CFG_DIV_MASK); + + /* Match the divider to one of the performance levels */ + if (perf_div == perf_levels[kPerformanceHigh].perf_div) perf_level = kPerformanceHigh; + else if (perf_div == perf_levels[kPerformanceMedium].perf_div) perf_level = kPerformanceMedium; + else if (perf_div == perf_levels[kPerformanceLow].perf_div) perf_level = kPerformanceLow; + + clocks_get_frequencies(); + +#endif /* APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) */ + + return 0; +} + +/* clocks_set_default - called by SecureROM, LLB, iBSS main via + platform_init_setup_clocks, so the current state of the chip is + either POR, or whatever 'quiesce' did when leaving SecureROM. */ +int clocks_set_default(void) +{ + u_int32_t cnt, reg, val, cpu_div; + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + + /* Be sure the bypass performance state is set up */ + rPMGR_PERF_STATE_A(kPERF_STATE_BYPASS) = perf_state_bypass[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_BYPASS) = perf_state_bypass[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_BYPASS) = perf_state_bypass[2]; + +#if APPLICATION_SECUREROM + rPMGR_PERF_STATE_A(kPERF_STATE_SECUREROM) = perf_state_active[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_SECUREROM) = perf_state_active[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_SECUREROM) = perf_state_active[2]; +#endif + +#if APPLICATION_IBOOT + for (cnt = 0; cnt < kPERF_STATE_IBOOT_CNT; cnt++) { + rPMGR_PERF_STATE_A(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt*3) + 0]; + rPMGR_PERF_STATE_B(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt*3) + 1]; + rPMGR_PERF_STATE_C(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt*3) + 2]; + } + + // Save the PERF_STATE configuration in rPMGR_SCRATCH1 + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, kPERF_STATE_IBOOT + 3); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), kPERF_STATE_IBOOT + 2); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), kPERF_STATE_IBOOT + 3); +#endif + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + +#if APPLICATION_IBOOT && !SUPPORT_FPGA + // We must be running at Vnom or greater at this point. Move to the fast EMA bank + // so we can update the incorrect reset values in the slow bank. The fast bank is + // safe as long as we stay above Vmin. + rPMGR_EMA_CTL_CPU = TARGET_EMA_CTL_CPU_SEL; + while (rPMGR_EMA_CTL_CPU & rPMGR_EMA_CTL_CPU_SPIN) ; + rPMGR_EMA_CTL_SOC = rPMGR_EMA_CTL_SOC_SEL; + while (rPMGR_EMA_CTL_SOC & rPMGR_EMA_CTL_SOC_SPIN) ; +#endif /* APPLICATION_IBOOT && !SUPPORT_FPGA*/ + + clks[PMGR_CLK_OSC] = OSC_FREQ; + +#ifdef PLL0_T + set_pll(0, PLL0_P, PLL0_M, PLL0_S, PLL0_V); +#endif + +#ifdef PLL1_T + set_pll(1, PLL1_P, PLL1_M, PLL1_S, PLL1_V); +#endif + +#ifdef PLL2_T + set_pll(2, PLL2_P, PLL2_M, PLL2_S, PLL2_V); +#endif + +#ifdef PLL3_T + set_pll(3, PLL3_P, PLL3_M, PLL3_S, PLL3_V); +#endif + +#ifdef PLL4_T + set_pll(4, PLL4_P, PLL4_M, PLL4_S, PLL4_V); +#endif + +#ifdef PLLUSB_T + set_pll(5, PLLUSB_P, PLLUSB_M, PLLUSB_S, PLLUSB_V); +#endif + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < 6; cnt++) plls[cnt] = get_pll(cnt); + +#if APPLICATION_IBOOT && !TARGET_USE_HSIC + // turn on clock doubler + rPMGR_DOUBLER_CTL = D_CLK_DOUBLER; +#if !SUPPORT_FPGA + while (!(rPMGR_DOUBLER_DEBUG & rPMGR_PLL_DEBUG_ENABLED)) ; +#endif +#endif + + // perf_div needs to be established before touching PMGR_CPU_CLK_CFG + perf_level = kPerformanceLow; + perf_div = perf_levels[perf_level].perf_div; + + // Open the active PLL gates + rPMGR_PLL_GATES = PLL_GATES_ACTIVE; + + // Set all clock dividers to their active values + // Start with CPU then work backwards + for (cnt = 0; cnt < PMGR_CLK_CFG_COUNT; cnt++) { + reg = PMGR_CLK_CFG_COUNT - cnt; + if (reg == PMGR_CLK_CFG_COUNT) reg = 0; + + // Take care of managed clocks before predivs + if (reg == PMGR_CLK_NUM(MANAGED0)) + update_perf_state(kPerformanceLow); + + val = clk_divs_active[reg]; + + // Factor perf_div into PMGR_CPU_CLK_CFG + if (reg == PMGR_CLK_NUM(CPU)) { + cpu_div = val & rPMGR_CLK_CFG_DIV_MASK; + val &= ~rPMGR_CLK_CFG_DIV_MASK; + val |= cpu_div * perf_div; + } + clkcfgs[reg] = val; + // Sleep clock needs special attention: + // instead, we just make sure not to disable it. + + while (clkcfgs[reg] & rPMGR_CLK_CFG_PENDING); + } + + clocks_get_frequencies(); + + return 0; +} + +static void update_perf_state(u_int32_t new_perf_level) +{ + u_int32_t val, cpu_div; + + /* Change the CPU speed (factor old perf_div out, multiple new one in) */ + if (perf_levels[new_perf_level].perf_div != perf_div) { + val = rPMGR_CPU_CLK_CFG; + cpu_div = val & rPMGR_CLK_CFG_DIV_MASK; + cpu_div = (cpu_div / perf_div) * perf_levels[new_perf_level].perf_div; + val = (val & ~rPMGR_CLK_CFG_DIV_MASK) | cpu_div; + rPMGR_CPU_CLK_CFG = val; + while (rPMGR_CPU_CLK_CFG & rPMGR_CLK_CFG_PENDING); + perf_div = perf_levels[new_perf_level].perf_div; + } + + /* Write the new select value */ + rPMGR_PERF_STATE_CTL = PMGR_PERF_STATE_SEL(perf_levels[new_perf_level].perf_state); + + /* Spin while any pending bits are asserted */ + while (rPMGR_PERF_STATE_CTL & PMGR_PERF_STATE_PENDING); +} + +void clocks_quiesce(void) +{ + /* mcu_clk will be changed to bypass clock */ + clks[PMGR_CLK_MCU] = OSC_FREQ; + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + + /* effectively full performance */ + perf_level = kPerformanceHigh; + perf_div = perf_levels[kPerformanceHigh].perf_div; +} + +static void clock_update_range(u_int32_t first, u_int32_t last, u_int32_t clkdata[]) +{ + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + u_int32_t val, reg; + + reg = first; + while (reg <= last) { + val = clkdata[reg]; + clkcfgs[reg] = val; + while (clkcfgs[reg] & rPMGR_CLK_CFG_PENDING); + reg++; + } +} + +static void clocks_quiesce_internal(void) +{ + u_int64_t devices[2]; + + // Critical: AIC, Debug, DWI, GPIO, AUDIO, UPERF, CDMA, CDIO, + // MCU, L2RAM, SCU, CPU0 + devices[0] = 0x000000205800005DULL; + devices[1] = 0x0000000000003A00ULL; + + // Turn on critical device clocks + clocks_set_gates(devices, true); + + // Turn off non-critical device clocks + clocks_set_gates(devices, false); + + // Simplified from PMGR Spec 1.10 Section 3.13.6 (plus changes from Erik) + + // Reset top-level dividers to bypass + clock_update_range(PMGR_CLK_NUM(PCLK1), PMGR_CLK_NUM(PREDIV6), clk_divs_bypass); + clock_update_range(PMGR_CLK_NUM(VID1), PMGR_CLK_NUM(VID1), clk_divs_bypass); +#if APPLICATION_IBOOT + // Prepare to move memory to bypass clock (ensure not high frequency, enable DLL force mode) + rPMGR_PERF_STATE_CTL = PMGR_PERF_STATE_SEL(perf_levels[kPerformanceMedium].perf_state); + while (rPMGR_PERF_STATE_CTL & PMGR_PERF_STATE_PENDING); + miu_bypass_prep(); +#endif + // Reset managed clocks and mcu, venc_mtx + rPMGR_PERF_STATE_CTL = PMGR_PERF_STATE_SEL(kPERF_STATE_BYPASS); + while (rPMGR_PERF_STATE_CTL & PMGR_PERF_STATE_PENDING); + // Reset PLLs and Doubler + rPMGR_PLL0_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL1_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL2_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL3_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL4_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLLUSB_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_DOUBLER_CTL = (rPMGR_PLL_ENABLE | rPMGR_PLL_EXT_BYPASS); +#if !SUPPORT_FPGA + while (!(rPMGR_PLL0_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL1_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL2_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL3_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL4_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLLUSB_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_DOUBLER_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; +#endif + + // Doubler external bypass uses gated version of 24 MHz + // Leave Doubler Enable bit set (for OHCI) + + // Open the PLL Gates + rPMGR_PLL_GATES = (1 << 4) | (1 << 3) | (1 << 2); + + // Reset the lower-level clocks + clock_update_range(PMGR_CLK_NUM(MANAGED0), PMGR_CLK_NUM(VENC), clk_divs_bypass); + + // Clear Enable bit, Doubler will still remain in bypass mode + rPMGR_DOUBLER_CTL &= ~rPMGR_PLL_ENABLE; + + // Reset the CPU clocks + clock_update_range(PMGR_CLK_NUM(CPU), PMGR_CLK_NUM(MCU), clk_divs_bypass); +} + +u_int32_t clocks_set_performance(u_int32_t performance_level) +{ + u_int32_t old_perf_level = perf_level; + + update_perf_state(performance_level); + perf_level = performance_level; + return old_perf_level; +} + +void clock_get_frequencies(u_int32_t *clocks, u_int32_t count) +{ + u_int32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) cnt = count; + + memcpy(clocks, clks, cnt * sizeof(u_int32_t)); +} + +u_int32_t clock_get_frequency(int clock) +{ + switch (clock) { + case CLK_CPU: + case CLK_FCLK: + return clks[PMGR_CLK_CPU]; + case CLK_ACLK: + case CLK_MEM: + return clks[PMGR_CLK_MCU]; + case CLK_HCLK: + case CLK_BUS: + return clks[PMGR_CLK_PIO]; + case CLK_PERIPH: + case CLK_PCLK: + return clks[PMGR_CLK_PCLK0]; + case CLK_FMI: + return clks[PMGR_CLK_PCLK1]; + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + return clks[PMGR_CLK_OSC]; + case CLK_USBPHYCLK: +#if SUPPORT_FPGA + return clks[PMGR_CLK_USBPHY]; /* The reference is special on FPGA */ +#else + return clks[PMGR_CLK_OSC]; /* This is ref_24_clk, not usb_phy_clk */ +#endif + case CLK_NCOREF: + return clks[PMGR_CLK_NCO_REF0]; + case CLK_VCLK0: + return clks[PMGR_CLK_VID0]; + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + return clks[PMGR_CLK_I2C]; + case CLK_MIPI: + return clks[PMGR_CLK_MIPI_DSI]; + case CLK_MCLK: + default: + return 0; + } +} + +void clock_set_frequency(int clock, u_int32_t divider, u_int32_t pll_p, u_int32_t pll_m, u_int32_t pll_s, u_int32_t pll_t) +{ + u_int32_t total_div, prediv6_div, vid0_div; + + switch (clock) { + case CLK_VCLK0: + // Calculate the total divider required + total_div = clks[PMGR_CLK_PLL3] / pll_t; + + // Find the largest prediv6_div that will + // produce the correct total_div + for (prediv6_div = 31; prediv6_div > 1; prediv6_div--) { + if ((total_div % prediv6_div) == 0) break; + } + + // Calculate vid0_div based on the part of + // total_div not in prediv6_div + vid0_div = total_div / prediv6_div; + + // Set the clock dividers to their new values + rPMGR_PREDIV6_CLK_CFG = (rPMGR_PREDIV6_CLK_CFG & ~0x1f) | prediv6_div; + rPMGR_VID0_CLK_CFG = (rPMGR_VID0_CLK_CFG & ~0x1f) | vid0_div; + + // Update the list of frequencies + clks[PMGR_CLK_PREDIV6] = clks[PMGR_CLK_PLL3] / prediv6_div; + clks[PMGR_CLK_VID0] = clks[PMGR_CLK_PREDIV6] / vid0_div; + break; + default: + break; + } +} + +void clock_gate(int device, bool enable) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + if (reg > PMGR_LAST_PS) return; + + // Set the PS field to the requested level + if (enable) *reg |= 0xF; + else *reg &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + while ((*reg & 0xF) != ((*reg >> 4) & 0xF)); +} + +static void clocks_set_gates(u_int64_t *devices, bool enable) +{ + u_int32_t dev, index; + volatile u_int32_t *devpss = PMGR_FIRST_PS; + u_int64_t mask = 1, devmask = 0; + + for (dev = 0, index = -1; dev < PMGR_DEV_PS_COUNT; dev++, mask <<= 1) { + if ((dev % 64) == 0) { + devmask = devices[++index]; + if (enable == false) + devmask ^= -1ULL; + mask = 1; + } + // Skip CPUs + if (dev < PMGR_PS_NUM(SCU)) continue; + if ((devmask & mask) != 0) { + if (enable) devpss[dev] |= 0xF; + else devpss[dev] &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + while ((devpss[dev] & 0xF) != ((devpss[dev] >> 4) & 0xF)); + } + } +} + +void platform_diag_gate_clocks(void) +{ +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + // Use WDOG pin to cause a PMU reset + gpio_configure_out(GPIO_SYSTEM_RESET, 1); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_watchdog_tickle(void) +{ + // Varies by target. This layer between is necessary so that + // we don't go straight from generic code to target. + target_watchdog_tickle(); +} + +static const u_int32_t divider_slot_table[8 * 2] = { + 0x00000000, 0, + 0x0000001F, 0, + 0x000003E0, 5, + 0x00007C00, 10, + 0x000F8000, 15, + 0x00001F00, 8, + 0x001F0000, 16, + 0x1F000000, 24 +}; + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + u_int32_t cnt; + u_int32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_CPU] = 15000000; + clks[PMGR_CLK_MCU] = 10000000; + clks[PMGR_CLK_MCU_FIXED]= 10000000; + clks[PMGR_CLK_USBPHY] = 12000000; + + // keep compiler happy + cnt = (u_int32_t)clk_parents; + cnt = (u_int32_t)divider_slot_table; + +#else + volatile u_int32_t *reg; + u_int32_t cnt, val, src_shift, parent_idx, slot, mask, shift, divider, perf_div_tmp; + u_int64_t freq; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) { + reg = clk_parents[cnt].divider_reg; + if (reg == 0) continue; + + switch (cnt) { + case PMGR_CLK_MANAGED0 : + src_shift = 5; + slot = 1; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED1 : + src_shift = 13; + slot = 5; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED2 : + src_shift = 21; + slot = 6; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED3 : + src_shift = 29; + slot = 7; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED4 : + src_shift = 5; + slot = 1; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[1] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MCU : + src_shift = 32; + slot = 5; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[1] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MCU_FIXED : + src_shift = 21; + slot = 6; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[1] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_VENC_MTX : + src_shift = 5; + slot = 1; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[2] & ~rPMGR_CLK_CFG_ENABLE); + break; + + default : + src_shift = 28; + slot = clk_parents[cnt].divider_slot; + val = *reg; + break; + } + + if ((val & rPMGR_CLK_CFG_ENABLE) == 0) continue; + + parent_idx = clk_parents[cnt].parents[(val >> src_shift) & 3]; + freq = clks[parent_idx]; + + if ((cnt == PMGR_CLK_DOUBLER) && !(val & rPMGR_DOUBLER_EXT_BYPASS)) + freq *= 2; + + if (slot != 0) { + mask = divider_slot_table[slot * 2]; + shift = divider_slot_table[slot * 2 + 1]; + divider = (val & mask) >> shift; + + if (divider == 0) continue; + + switch (cnt) { + case PMGR_CLK_CPU : perf_div_tmp = perf_div; break; + default : perf_div_tmp = 1; break; + } + freq *= perf_div_tmp; + freq /= divider; + } + + clks[cnt] = freq; + } +#endif +} + +static u_int32_t get_pll(int pll) +{ + u_int32_t pllctl; + u_int64_t freq = 0; + + switch (pll) { + case 0: pllctl = rPMGR_PLL0_CTL; break; + case 1: pllctl = rPMGR_PLL1_CTL; break; + case 2: pllctl = rPMGR_PLL2_CTL; break; + case 3: pllctl = rPMGR_PLL3_CTL; break; + case 4: pllctl = rPMGR_PLL4_CTL; break; + case 5: pllctl = rPMGR_PLLUSB_CTL; break; + default: goto exit; break; + } + + if ((pllctl & rPMGR_PLL_ENABLE) == 0) goto exit; + + if ((pllctl & (rPMGR_PLL_EXT_BYPASS | rPMGR_PLL_BYPASS))) { + freq = OSC_FREQ; + } else { + freq = OSC_FREQ * 2; + freq *= (pllctl >> 3) & 0x3FF; // *M + freq /= (pllctl >> 14) & 0x3F; // /P + freq /= 1 << ((pllctl >> 0) & 0x07); // /2^S + } + +exit: + return freq; +} + +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t vco) +{ + volatile u_int32_t *pllctl, *pllparam; +#if (SUB_PLATFORM_S5L8942X || SUB_PLATFORM_S5L8947X) + u_int32_t vsel; +#else + u_int32_t afc; +#endif + + switch (pll) { + case 0: pllctl = &rPMGR_PLL0_CTL; pllparam = &rPMGR_PLL0_PARAM; break; + case 1: pllctl = &rPMGR_PLL1_CTL; pllparam = &rPMGR_PLL1_PARAM; break; + case 2: pllctl = &rPMGR_PLL2_CTL; pllparam = &rPMGR_PLL2_PARAM; break; + case 3: pllctl = &rPMGR_PLL3_CTL; pllparam = &rPMGR_PLL3_PARAM; break; + case 4: pllctl = &rPMGR_PLL4_CTL; pllparam = &rPMGR_PLL4_PARAM; break; + case 5: pllctl = &rPMGR_PLLUSB_CTL; pllparam = &rPMGR_PLLUSB_PARAM; break; + default: return; break; + } + +#if (SUB_PLATFORM_S5L8942X || SUB_PLATFORM_S5L8947X) + // Find the VSEL setting for the desired VCO frequency + if (vco < 1400000000UL) vsel = 0; // 960MHz <= VCO <= 1400MHz + else vsel = 1; // 1400MHz <= VCO <= 2060MHz + + // Set the default lock time (2400 cycles), and enable AFC + // Note: 2400 requires Fref>=2MHz (P<=12) on H4A. + *pllparam = rPMGR_PARAM_AFC_EN | rPMGR_PARAM_LOCK_TIME(2400); + *pllctl = (rPMGR_PLL_ENABLE | rPMGR_PLL_LOAD | + rPMGR_PLL_P(p) | rPMGR_PLL_M(m) | rPMGR_PLL_S(s) | + rPMGR_PLL_VSEL(vsel)); +#else + // Find the AFC setting for the desired VCO frequency + afc = 13; + if (vco < 1100000000UL) afc = 5; + if (vco > 1500000000UL) afc = 28; + + // Set the default lock time (2400 cycles), and disable AFC and use EXT AFC + // Note: 2400 requires Fref>=1MHz (P<=24) on H4P/H4G + *pllparam = rPMGR_PARAM_EXT_AFC(afc) | rPMGR_PARAM_LOCK_TIME(2400); + *pllctl = (rPMGR_PLL_ENABLE | rPMGR_PLL_LOAD | + rPMGR_PLL_P(p) | rPMGR_PLL_M(m) | rPMGR_PLL_S(s)); +#endif + +#if !SUPPORT_FPGA + while ((*pllctl & rPMGR_PLL_REAL_LOCK) == 0); // wait for pll to lock +#endif /* ! SUPPORT_FPGA */ +} + +#endif + +void clock_reset_device(int device) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + switch (device) { + case CLK_CPU1 : + case CLK_FMI0 : + case CLK_FMI1 : + case CLK_FMI2 : + case CLK_FMI3 : + case CLK_IOP : + case CLK_SDIO : +#if SUB_PLATFORM_S5L8947X + case CLK_HDMI : +#endif + *reg |= rPMGR_PS_RESET; + spin(1); + *reg &= ~rPMGR_PS_RESET; + break; + + case CLK_MCU: + // Make sure resets are asserted/deasserted to gfx0, gfx1, hperfrt, hperfnrt + // + rPMGR_GFX_SYS_PS |= rPMGR_PS_RESET; + rPMGR_GFX_CORES_PS |= rPMGR_PS_RESET; + rPMGR_HPERFNRT_PS |= rPMGR_PS_RESET; + rPMGR_HPERFRT_PS |= rPMGR_PS_RESET; + *reg |= rPMGR_PS_RESET; + spin(1); + *reg &= ~rPMGR_PS_RESET; + rPMGR_GFX_SYS_PS &= ~rPMGR_PS_RESET; + rPMGR_GFX_CORES_PS &= ~rPMGR_PS_RESET; + rPMGR_HPERFNRT_PS &= ~rPMGR_PS_RESET; + rPMGR_HPERFRT_PS &= ~rPMGR_PS_RESET; + break; + + default : + break; + } +} + +#if WITH_DEVICETREE + +static const u_int32_t cpu_srcs[] = { 1, 2, 1 }; +static const u_int32_t cpu_divs[] = { 2, 1, 1 }; + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ + u_int32_t cnt, tmp, propSize, propSize2, perf_state_config; + u_int32_t *states, *configs; + u_int64_t pll_freq, period_ns; + u_int32_t cpu_volt; + char *propName; + void *propData; + + // Fill in the voltage1-states and cpu-clk-cfgs properties + + propName = "voltage-states1"; + if (!FindProperty(pmgr_node, &propName, (void *)&states, &propSize)) { + panic("pmgr property voltage-states1 is missing"); + } + + propName = "cpu-clk-cfgs"; + if (!FindProperty(pmgr_node, &propName, (void *)&configs, &propSize2)) { + panic("pmgr property cpu-clk-cfgs is missing"); + } + + if (propSize != (propSize2 * 2)) { + panic("pmgr properties voltage-states1 (vsPerformanceLimit) and cpu-clk-cfgs are not the same size"); + } + if (propSize < (3 * 2 * sizeof(u_int32_t))) { + panic("pmgr property voltage-states1 is too small"); + } + + // Creat a template for the CPU_CLK_CFG values + tmp = rPMGR_CPU_CLK_CFG & ~(rPMGR_CLK_CFG_SRC_SEL_MASK | rPMGR_CLK_CFG_DIV_MASK); + + // Attempt to create voltage states for each of the possible CPU_CLK_CFGs + for (cnt = 0; cnt < 3; cnt++) { + // Get the PLL frequency for this CPU_CLK_CFG + pll_freq = plls[cpu_srcs[cnt] - 1]; + cpu_volt = chipid_get_cpu_voltage(cnt); + if (pll_freq == 0) continue; + + // Calculate the period is ns as a 16.16 fixed point number + period_ns = cpu_divs[cnt] * 1000000000ULL << 16; + period_ns /= pll_freq; + + // Save the period for this voltage state + *(states++) = period_ns; + *(states++) = cpu_volt; + + // Save the CPU_CLK_CFG for this voltage state + *(configs++) = tmp | rPMGR_CLK_CFG_SRC_SEL(cpu_srcs[cnt]) | rPMGR_CLK_CFG_DIVIDER(cpu_divs[cnt]); + } + + // Get the PERF_STATE configuration generated at hardware init + perf_state_config = rPMGR_SCRATCH1; + if (perf_state_config == 0) return; + + // Fill in the firmware-v-perf-states property + propName = "firmware-v-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(u_int32_t))) { + panic("pmgr property firmware-v-perf-states is the wrong size"); + } + // Voltage states are in reverse order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), perf_state_config); + } + + // Fill in the firmware-p-perf-state property + propName = "firmware-p-perf-state"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (1 * sizeof(u_int32_t))) { + panic("pmgr property firmware-p-perf-states is the wrong size"); + } + // There is only one Frequency Managed / Performance state + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, perf_state_config); + } + + // Fill in the firmware-m-perf-states property + propName = "firmware-m-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (4 * sizeof(u_int32_t))) { + panic("pmgr property firmware-m-perf-states is the wrong size"); + } + // Memory states are in the same order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), perf_state_config); + ((u_int32_t *)propData)[2] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), perf_state_config); + ((u_int32_t *)propData)[3] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), perf_state_config); + } +} + +#endif diff --git a/platform/s5l8940x/pmgr/rules.mk b/platform/s5l8940x/pmgr/rules.mk new file mode 100644 index 0000000..8be1463 --- /dev/null +++ b/platform/s5l8940x/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2008 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s5l8940x/rules.mk b/platform/s5l8940x/rules.mk new file mode 100644 index 0000000..1c9b899 --- /dev/null +++ b/platform/s5l8940x/rules.mk @@ -0,0 +1,124 @@ +# Copyright (C) 2009-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +############################################################################## +# Code running on the main CPU +# +ifeq ($(PLATFORM_VARIANT),) + +ARM_CPU := cortex-a9 + +MAX_DFU_SIZE := 180224 + +ifeq ($(TEXT_BANK),srom) +TEXT_BASE := 0x00000000 +endif +ifeq ($(TEXT_BANK),sram) +TEXT_BASE := 0x34000000 +endif +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0x9FF00000 +endif + +# Platform target can override any of these sizes by specifying in target config file (apps/iBoot/$target-config.mk) +ifeq ($(DISPLAY_SIZE),) + DISPLAY_SIZE := 15*1024*1024 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + WITH_LEGACY_PANIC_LOGS=1 \ + WITH_NO_RANDOM_HEAP_COOKIE=1 \ + WITH_NO_RANDOM_STACK_COOKIE=1 \ + WITH_NON_COHERENT_DMA=1 \ + WITH_ROM_TRAMPOLINE=1 \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=192 \ + TEXT_BASE="$(TEXT_BASE)" \ + DISPLAY_SIZE="($(DISPLAY_SIZE)ULL)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" \ + DISPLAY_BASE_NONALIGNED + +# L2_CACHE_SIZE=1048576 \ +# + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) +# This selects the start of the DATA segment and the end of the INSECURE_MEMORY area +DATA_BASE := 0x3402C000 + +OPTIONS += \ + DATA_BASE="$(DATA_BASE)" + +GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) +endif + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig_$(SUB_PLATFORM).o + +endif + +############################################################################## +# Code running on the IOP +# +ifeq ($(PLATFORM_VARIANT),IOP) + +OPTIONS += \ + PLATFORM_VARIANT_IOP=1 \ + AIC_CPU_ID=2 \ + WITH_PLATFORM_HALT=1 \ + SUPPORT_SLEEP=1 \ + WITH_IOP_POWER_GATING=1 \ + DEEP_IDLE_THRESHOLD_US=10000 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o +endif + +############################################################################## +# Code running on the audio engine +# +ifeq ($(PLATFORM_VARIANT),Audio) + +OPTIONS += \ + PLATFORM_VARIANT_AUDIO=1 \ + WITH_PLATFORM_HALT=1 \ + SUPPORT_SLEEP=1 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o + +endif diff --git a/platform/s5l8945x/amc/amc.c b/platform/s5l8945x/amc/amc.c new file mode 100644 index 0000000..23c5e5a --- /dev/null +++ b/platform/s5l8945x/amc/amc.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + return amc_init(resume); +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping (void) +{ + amc_configure_default_address_decoding_and_mapping(); +} + +void amc_enable_slow_boot (bool enable) +{ + int slow_freqsel; + + if (enable) { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + rAMC_FREQSEL = amc_params.freqsel; + return; + } + + slow_freqsel = 3; + rAMC_BOOTCLK = (amc_params.bootclkdivsr << 8) | 1; + spin(5); + rAMC_FREQSEL = slow_freqsel; + amc_phy_scale_dll(slow_freqsel, amc_params.bootclkdivsr); + } else { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + return; + } + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_small; + spin(2); + + rAMC_BOOTCLK &= ~1; + spin(5); + rAMC_FREQSEL = amc_params.freqsel; + amc_phy_scale_dll(amc_params.freqsel, 1); + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_guided; + } +} + +void amc_finalize (bool resume) +{ + uint8_t odts; + +#if SUPPORT_FPGA + rAMC_PWRMNGTEN |= 0x00000001; // Sharing clocks between channels so do not enable clock stopping for PD or SR +#else + rAMC_PWRMNGTEN |= 0x00011011; +#endif + + rAMC_AREFPARAM |= (0x00001000); // Turn on freq change waiting for refresh and self-refresh exit + + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&odts); + rAMC_ODTS = 0x00010080; // [16] => TempDrtEn, [9:0] RdIntrvl XXX based on tREFI + + if (!resume) { + amc_enable_autorefresh(); + } + +#if !SUPPORT_FPGA + // Turn of Fast Critical Word Forwarding feature and AIU CWF feature + // Disabled for NRT + rAMC_AIUPRT_RD_CWF = 0x00363600; + rAMC_QBRPARAM = 0x00810000; + rAMC_QBREN = 0x00111001; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_SAMSUNG: + + // H4P Samsung 35nm LPDDR2 Transition for N94 + // TMRS for Samsung 46nm part only + if ((!resume) && (dev_info->rev_id == 0)) { + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xff); + + // Apply Samsung workaround + + // Column Select Line pull in (230ps) TMRS(1) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x80); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x04); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x08); + + // Latch command + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + + // Column Select Line pull in (230ps) TMRS(2) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x40); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x01); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + + // Latch command + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + } + break; + + case JEDEC_MANUF_ID_HYNIX: + + if (dev_info->rev_id == 0) { + if (!resume && (dev_info->rev_id2 == 0)) { + // Test MRS Exit "just in case" + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xa2); + } + + // H4G UM Update: Modified setting for tMRR timing parameter + // override tMRR to 3 cycles + if (dev_info->density == JEDEC_DENSITY_2Gb) + rAMC_MODE_FREQ(0) = amc_params.freq[0].modereg | 0x3; + } + + break; + default: + break; + } +} + +void amc_dram_shift_dq_offset (int8_t *dq_offset, uint8_t num_bytes) { + // Do nothing for H4G +} + diff --git a/platform/s5l8945x/amc/rules.mk b/platform/s5l8945x/amc/rules.mk new file mode 100644 index 0000000..b10556f --- /dev/null +++ b/platform/s5l8945x/amc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2010-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AMC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/amc.o diff --git a/platform/s5l8945x/chipid/chipid.c b/platform/s5l8945x/chipid/chipid.c new file mode 100644 index 0000000..b31dc96 --- /dev/null +++ b/platform/s5l8945x/chipid/chipid.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if SUPPORT_FPGA +#define _rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#undef rCFG_FUSE0 +// XXX ECID (1 << 7)? +// XXX double-check memory values +#define rCFG_FUSE0 ((0 << 31) | (3 << 28) | (0xE << 24) | (2 << 22) | \ + (0 << 9) | (1 << 8) | (3 << 4) | (kPlatformSecurityDomainDarwin << 2) | (0 << 1) | (0 << 0) | \ + _rCFG_FUSE0) +#endif + +#if SUB_PLATFORM_S5L8945X +#define DEFAULT_SOC_VOLTAGE_LOW 1000 +#define DEFAULT_SOC_VOLTAGE_MED 1100 +#define DEFAULT_SOC_VOLTAGE_HIGH 1200 +#define DEFAULT_CPU_VOLTAGE_LOW 1000 +#define DEFAULT_CPU_VOLTAGE_MED 1150 +#define DEFAULT_CPU_VOLTAGE_HIGH 1250 +#define BASE_SOC_VOLTAGE_LOW 875 +#define BASE_SOC_VOLTAGE_MED 975 +#define BASE_SOC_VOLTAGE_HIGH 1075 +#define BASE_CPU_VOLTAGE_LOW 875 +#define BASE_CPU_VOLTAGE_MED 975 +#define BASE_CPU_VOLTAGE_HIGH 1075 +#endif + +bool chipid_get_production_mode(void) +{ + return ((rCFG_FUSE0 >> 0) & 1) != 0; +} + +void chipid_clear_production_mode(void) +{ +#if SUPPORT_FPGA + _rCFG_FUSE0 &= ~1; +#else + rCFG_FUSE0 &= ~1; +#endif +} + +bool chipid_get_secure_mode(void) +{ + return ((rCFG_FUSE0 >> 1) & 1) != 0; +} + +u_int32_t chipid_get_security_domain(void) +{ + return (rCFG_FUSE0 >> 2) & 3; +} + +u_int32_t chipid_get_board_id(void) +{ + return (rCFG_FUSE0 >> 4) & 3; +} + +bool chipid_get_ecid_image_personalization_required(void) +{ + return ((rCFG_FUSE0 >> 7) & 1) != 0; +} + +u_int32_t chipid_get_minimum_epoch(void) +{ + return (rCFG_FUSE0 >> 9) & 0x7F; +} + +u_int32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_S5L8945X + return 0x8945; +#endif +} + +u_int32_t chipid_get_chip_revision(void) +{ + return (((rECIDHI >> 13) & 0x7) << 4) | (((rECIDHI >> 10) & 0x7) << 0); +} + +u_int32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +u_int64_t chipid_get_ecid_id(void) +{ + u_int64_t ecid = 0; + +#if SUPPORT_FPGA + ecid = 0x000012345678ABCDULL; +#else + ecid |= ((rECIDLO >> 0)) & ((1ULL << (21 - 0)) - 1); // LOT_ID + + ecid <<= (26 - 21); + ecid |= ((rECIDLO >> 21)) & ((1ULL << (26 - 21)) - 1); // WAFER_NUM + + ecid <<= (10 - 2); + ecid |= ((rECIDHI >> 2)) & ((1ULL << (10 - 2)) - 1); // Y_POS + + ecid <<= (32 - 26); + ecid |= ((rECIDLO >> 26)) & ((1ULL << (32 - 26)) - 1); // X_POS_H + + ecid <<= ( 2 - 0); + ecid |= ((rECIDHI >> 0)) & ((1ULL << ( 2 - 0)) - 1); // X_POS_L +#endif + + return ecid; +} + +u_int64_t chipid_get_die_id(void) +{ + return ((u_int64_t)rECIDHI << 32) | rECIDLO; +} + +u_int32_t chipid_get_fused_thermal_70C(void) +{ + return (rCFG_FUSE6 >> 8) & 0xff; +} + +u_int32_t chipid_get_fused_thermal_25C(void) +{ + return rCFG_FUSE6 & 0xff; +} + +u_int32_t chipid_get_fuse_revision(void) +{ + return (rCFG_FUSE1 >> 25) & 0xf; +} + +u_int32_t chipid_get_soc_voltage(u_int32_t index) +{ + u_int32_t soc_voltage = 0; + u_int32_t soc_bin_offset_data = 0, soc_bin_data = (rCFG_FUSE1 >> 5) & 0x1FF; + int32_t soc_bin_offset; + +#if DEBUG_BUILD && WITH_ENV + soc_bin_offset_data = env_get_uint("soc-bin-offset", 0); + + switch (index) { + case CHIPID_SOC_VOLTAGE_LOW : soc_bin_offset_data = (soc_bin_offset_data >> 0) & 0xff; break; + case CHIPID_SOC_VOLTAGE_MED : soc_bin_offset_data = (soc_bin_offset_data >> 8) & 0xff; break; + case CHIPID_SOC_VOLTAGE_HIGH : soc_bin_offset_data = (soc_bin_offset_data >> 16) & 0xff; break; + default : break; + } +#endif + + // if bin data is all zeros, bin data is not valid + if (soc_bin_data == 0) { + switch (index) { + case CHIPID_SOC_VOLTAGE_LOW : soc_voltage = DEFAULT_SOC_VOLTAGE_LOW; break; + case CHIPID_SOC_VOLTAGE_MED : soc_voltage = DEFAULT_SOC_VOLTAGE_MED; break; + case CHIPID_SOC_VOLTAGE_HIGH : soc_voltage = DEFAULT_SOC_VOLTAGE_HIGH; break; + default : break; + } + } else { + switch (index) { + case CHIPID_SOC_VOLTAGE_LOW : soc_voltage = BASE_SOC_VOLTAGE_LOW + 25 * ((soc_bin_data>>6)&7); break; + case CHIPID_SOC_VOLTAGE_MED : soc_voltage = BASE_SOC_VOLTAGE_MED + 25 * ((soc_bin_data>>3)&7); break; + case CHIPID_SOC_VOLTAGE_HIGH : soc_voltage = BASE_SOC_VOLTAGE_HIGH + 25 * ((soc_bin_data>>0)&7); break; + default : break; + } + } + + soc_bin_offset = soc_bin_offset_data | (((soc_bin_offset_data & 0x80) == 0) ? 0 : 0xffffff00); + soc_bin_offset *= 25; + + return soc_voltage + soc_bin_offset; +} + +u_int32_t chipid_get_cpu_voltage(u_int32_t index) +{ + u_int32_t cpu_voltage = 0; + u_int32_t cpu_bin_offset_data = 0, cpu_bin_data = ((((u_int64_t)rCFG_FUSE1 << 32) | rCFG_FUSE0) >> 28) & 0x1FF; + int32_t cpu_bin_offset; + +#if DEBUG_BUILD && WITH_ENV + cpu_bin_offset_data = env_get_uint("core-bin-offset", 0); + + switch (index) { + case CHIPID_CPU_VOLTAGE_LOW : cpu_bin_offset_data = (cpu_bin_offset_data >> 0) & 0xff; break; + case CHIPID_CPU_VOLTAGE_MED : cpu_bin_offset_data = (cpu_bin_offset_data >> 8) & 0xff; break; + case CHIPID_CPU_VOLTAGE_HIGH : cpu_bin_offset_data = (cpu_bin_offset_data >> 16) & 0xff; break; + default : break; + } + +#endif + + // if bin data is all zeros, bin data is not valid + if (cpu_bin_data == 0) { + switch (index) { + case CHIPID_CPU_VOLTAGE_LOW : cpu_voltage = DEFAULT_CPU_VOLTAGE_LOW; break; + case CHIPID_CPU_VOLTAGE_MED : cpu_voltage = DEFAULT_CPU_VOLTAGE_MED; break; + case CHIPID_CPU_VOLTAGE_HIGH : cpu_voltage = DEFAULT_CPU_VOLTAGE_HIGH; break; + default : break; + } + } else { + switch (index) { + case CHIPID_CPU_VOLTAGE_LOW : cpu_voltage = BASE_CPU_VOLTAGE_LOW + 25 * ((cpu_bin_data>>6)&7); break; + case CHIPID_CPU_VOLTAGE_MED : cpu_voltage = BASE_CPU_VOLTAGE_MED + 25 * ((cpu_bin_data>>3)&7); break; + case CHIPID_CPU_VOLTAGE_HIGH : cpu_voltage = BASE_CPU_VOLTAGE_HIGH + 25 * ((cpu_bin_data>>0)&7); break; + default : break; + } + } + + cpu_bin_offset = cpu_bin_offset_data | (((cpu_bin_offset_data & 0x80) == 0) ? 0 : 0xffffff00); + cpu_bin_offset *= 25; + + return cpu_voltage + cpu_bin_offset; +} + +bool chipid_get_fuse_lock(void) +{ + return (rCFG_FUSE1 & (1 << 31)) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) rCFG_FUSE1 |= 1 << 31; +} diff --git a/platform/s5l8945x/chipid/rules.mk b/platform/s5l8945x/chipid/rules.mk new file mode 100644 index 0000000..29257b1 --- /dev/null +++ b/platform/s5l8945x/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2009 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/s5l8945x/include/platform/amcconfig.h b/platform/s5l8945x/include/platform/amcconfig.h new file mode 100644 index 0000000..e74b2f2 --- /dev/null +++ b/platform/s5l8945x/include/platform/amcconfig.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2009-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_RECONFIG | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_ENABLE_AIU), + + .freqsel = 0, + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00010000, + .tREFi_1Gb = 0xbb, + .longsrcnt_1Gb = 0x1004, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 8, // rdlat + 2 + .phywrlat = 3, + .pdn = 0x33000303, + .read = 0x00000103, + .bustat = 0x00222212, + .bustat2 = 0x00222212, + .derate = 0x28831258, + .mcphyupdate = 0x05010009, + .pwrmngtparam_small = 0x00013000, + .pwrmngtparam_guided = 0x00fa3000, + .chnldec = 0x00040000, + .chnldec2 = 0x00555555, + .chnldec4 = 0x00aaaaaa, + .autoref_params = 0x00000022, + .bootclkdivsr = 8, + .arefparam = 0x0600a000, + .aref_freq0 = 0x00100100, + .aref_freq1 = 0x00100000, + .readleveling = 0x01000301, + + .freq = { + { // 400MHz + .cas = 0x00000308, + .pch = 0x00030611, + .act = 0x14040908, + .autoref = 0x1834a000, + .selfref = 0x00038060, + .modereg = 0x00240502, + .mifcassch = 0x001f0111, + .mifqmaxctrl = 0x00000000, + }, + { // 200MHz + .cas = 0x00000004, + .pch = 0x00000009, + .act = 0x0a020504, + .autoref = 0x0c1a0000, + .selfref = 0x0001c000, + .modereg = 0x00120000, + .mifcassch = 0x00000000, + .mifqmaxctrl = 0x00000000, + }, + { // 100MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x060d0000, + .selfref = 0x0000e000, + .modereg = 0x00090000, + .mifcassch = 0x00000000, + .mifqmaxctrl = 0x00000000, + }, + { // 50 & 24MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x03070000, + .selfref = 0x00007000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + .mifqmaxctrl = 0x00000001, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + // These settings are common across all H4x and H5P. Channel decode and hashing + // is done in mainline init code. Any tunables that match hardware defaults are + // omitted here. + + { &rAMC_AIUPRT_CFG, 0x00070000 }, // address error enable + { &rAMC_AIUPRT_RD_GEN, 0x00000018 }, // fence read detect on GFX + { &rAMC_AIUPRT_WR, 0x00000001 }, // out-of-order write, ignore B-bit + + { &rAMC_AIU_RDBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_RDMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_WRMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + + { &rAMC_AIU_CPUSPCREQ, 0x00000019 }, // CPU ageout timer + { &rAMC_AIU_GFXSPCREQ, 0x00000032 }, // GFX ageout timer + { &rAMC_AIU_NRTSPCREQ, 0x00000032 }, // Hperf-NRT ageout timer + { &rAMC_AIU_RTSPCREQ, 0x00000019 }, // Hperf-RT ageout timer + { &rAMC_AIU_WPQSCH, 0x10001000 }, // only supported for Hperf-RT + { &rAMC_AIU_THOTLCPUPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLRTPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLNRTPARAM, 0x00000000 }, + { &rAMC_AIU_THOTLGFXPARAM, 0x00000000 }, + { &rAMC_AIU_PUSHEN, 0x00001100 }, // only supported for Hperf-RT + + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJEN, 0x00000001 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + + { &rAMC_MIFACTSCH, 0x00000001 }, + + { &rAMC_PSQRQTIMER0, 0x00000040 }, // RTG bypass up to 64 transactions + { &rAMC_PSQRQTIMER1, 0x00000018 }, // RTY bypass up to 24 transactions + { &rAMC_PSQRQTIMER2, 0x00000020 }, // RTG bypass up to 32 transactions + { &rAMC_PSQRQBRST, 0x040c040c }, // RTR transactions don't affect read burst size + { &rAMC_PSQRQSCHCRD, 0x002028f5 }, // read credits = 2 * write credits + { &rAMC_PSQWQBRST, 0x0208040c }, // RTR reads cause reduced write burst size + { &rAMC_PSQWQSCHCRD, 0x001014f5 }, // write credits = 1/2 * read credits + { &rAMC_MCUQOS, 0x00010f04 }, // RTG=4, RTY=15, enable pick-oldest-RTY + + // Platform specific + + { &rAMC_AIU_RDMAXCRD, 0x1928047F }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_RDREFL, 0x1421037F }, // 5/6 of AIURDMAXCRD fields + { &rAMC_AIU_WRMAXCRD, 0x1928047F }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRREFL, 0x1421037F }, // 5/6 of AIUWRMAXCRD fields + { &rAMC_AIU_THOTLEN, 0x00000000 }, // enable throttling + { &rAMC_PSQRQCTL1, 0x0000112A }, // ages write out faster than default (1/2 SelfRef) + { &rAMC_PSQWQCTL1, 0x00000180 }, // ages write out faster than default (1/2 SelfRef) + { &rAMC_MCUQOSLLT, 0x00010108 }, + { &rAMC_PWRMNGTPARAM, 0x03001000 }, // SelfRef timer = 384 cycles + + // There is a bug around write merge, which we believe is avoided + // in current drivers: + // Power and performance measurements of disabling write merging were + // done: + { &rAMC_PSQWQCTL0, 0x00010100 }, // Write merge enable + + { &rAMC_AIU_ADDRBANKHASH0, 0x00006db6 }, // Enable bank hashing, bank[0] derived from bits 0,3,6,.. + { &rAMC_AIU_ADDRBANKHASH1, 0x00005b6d }, // Enable bank hashing, bank[1] derived from bits 1,4,7,.. + { &rAMC_AIU_ADDRBANKHASH2, 0x000036db }, // Enable bank hashing, bank[2] derived from bits 2,5,8,.. + { &rAMC_AIU_CHNLCRD, 0x00180018 }, + { &rAMC_AIU_CHNLTM, 0x00006101 }, + { &rAMC_AIU_LLTSCHCTL, 0x00000001 }, // Ensure LLT traffic from all ports is treated as medium priority request in the AIU arbitration +}; +#endif \ No newline at end of file diff --git a/platform/s5l8945x/include/platform/amgconfig.h b/platform/s5l8945x/include/platform/amgconfig.h new file mode 100644 index 0000000..2938e43 --- /dev/null +++ b/platform/s5l8945x/include/platform/amgconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amg_param struct is defined in drivers/apple/amg/amg.h, and this + * file should only by included from amg.c. + */ + +#if WITH_TARGET_AMG_PARAMS +#include +#else +static const struct amg_params amc_phy_params = { + .flags = 0, + .core_config = 0x00001053, + .read_latency = 0x0000669b, + .gate_offset = 0x08080808, +}; +#endif diff --git a/platform/s5l8945x/include/platform/gpiodef.h b/platform/s5l8945x/include/platform/gpiodef.h new file mode 100644 index 0000000..3bdcbd8 --- /dev/null +++ b/platform/s5l8945x/include/platform/gpiodef.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* S5L8945X specific gpio -> pin mappings */ + +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_IIC0_SCL GPIO(12, 4) +#define GPIO_IIC0_SDA GPIO(12, 3) +#define GPIO_IIC1_SCL GPIO(12, 6) +#define GPIO_IIC1_SDA GPIO(12, 5) +#define GPIO_IIC2_SCL GPIO(10, 1) +#define GPIO_IIC2_SDA GPIO(10, 0) + +#define GPIO_BOARD_ID0 GPIO( 1, 0) +#define GPIO_BOARD_ID1 GPIO( 1, 1) +#define GPIO_BOARD_ID2 GPIO( 1, 2) +#define GPIO_BOARD_ID3 GPIO( 6, 4) + +#define GPIO_BOOT_CONFIG0 GPIO( 6, 6) +#define GPIO_BOOT_CONFIG1 GPIO( 7, 5) +#define GPIO_BOOT_CONFIG2 GPIO( 8, 0) +#define GPIO_BOOT_CONFIG3 GPIO( 8, 1) + +#define GPIO_REQUEST_DFU1 GPIO( 4, 5) // formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 4, 4) // formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO( 7, 6) +#define GPIO_DFU_STATUS GPIO( 7, 7) + +#define SPI_NOR0 (0) +#define SPI_NOR3 (3) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#define GPIO_SPI3_CS GPIO(GPIO_PAD_SPI, 3) +#else +#define GPIO_SPI0_CS GPIO( 1, 3) +#define GPIO_SPI3_CS GPIO(19, 5) +#endif + +#define GPIO_UART1_TXD GPIO(10, 2) + +#define GPIO_SYSTEM_RESET GPIO(17, 2) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s5l8945x/include/platform/image_devices.h b/platform/s5l8945x/include/platform/image_devices.h new file mode 100644 index 0000000..6091d97 --- /dev/null +++ b/platform/s5l8945x/include/platform/image_devices.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_firmware", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s5l8945x/include/platform/memconfig.h b/platform/s5l8945x/include/platform/memconfig.h new file mode 100644 index 0000000..1397bff --- /dev/null +++ b/platform/s5l8945x/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* S5L8945X SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/s5l8945x/include/platform/memmap.h b/platform/s5l8945x/include/platform/memmap.h new file mode 100644 index 0000000..bcf2010 --- /dev/null +++ b/platform/s5l8945x/include/platform/memmap.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* S5L8945X specific memory map */ +#define SDRAM_BASE (0x80000000ULL) +#define SDRAM_BANK_LEN (0x20000000ULL) +#define SDRAM_BANK_COUNT (2) +#define SDRAM_END (SDRAM_BASE + (SDRAM_BANK_LEN * SDRAM_BANK_COUNT)) +#define VROM_BASE (0x3F000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00010000ULL) +#define SRAM_BASE (0x34000000ULL) +#define SRAM_BANK_LEN (0x00100000ULL) +#define SRAM_LEN (0x00040000ULL) + +/* Sleep token is stored at first physical page in kernel memory */ +#define SLEEP_TOKEN_BUFFER_BASE (SDRAM_BASE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00004000ULL) +#define PANIC_BASE (SDRAM_END - PANIC_SIZE) + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x00100000 - PANIC_SIZE) +#define IBOOT_BASE (PANIC_BASE - IBOOT_SIZE) +#define PROTECTED_REGION_SIZE IBOOT_SIZE + +/* reserved area for display */ +#define DISPLAY_SIZE (0x03F00000ULL) +#define DISPLAY_BASE (IBOOT_BASE - DISPLAY_SIZE) + +/* where to stick the mmu tt, default heap and insecure memory*/ +#if APPLICATION_SECUREROM +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (SRAM_BASE + SRAM_LEN - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN * 3) + +#define STACK_SIZE (0x3000ULL) +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#ifndef __ASSEMBLY__ + +#define INSECURE_MEMORY_BASE (SRAM_BASE) +#define INSECURE_MEMORY_SIZE ((uintptr_t)__segment_start(__DATA) - INSECURE_MEMORY_BASE) + +#endif /* ! __ASSEMBLY__ */ + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (TEXT_BASE + TEXT_FOOTPRINT - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN * 3) +#define MMU_NONCACHE1_SIZE (0x40000000ULL) +#define MMU_NONCACHE1_PBASE (0x80000000ULL) +#define MMU_NONCACHE1_VBASE (0xC0000000ULL) + +#if WITH_DFU_MODE +#define STACK_SIZE (0x3000ULL) + +#define INSECURE_MEMORY_SIZE (0x00200000ULL) +#define INSECURE_MEMORY_BASE (SDRAM_BASE + SDRAM_BANK_LEN - INSECURE_MEMORY_SIZE) + +#define HEAP_EXT_SIZE (0x00100000ULL) +#define HEAP_EXT_BASE (INSECURE_MEMORY_BASE - HEAP_EXT_SIZE) + +#else /* !WITH_DFU_MODE */ +#define STACK_SIZE (0x1000ULL) + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_KERNEL_ADDRESS - SDRAM_BASE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +/* If only 1 bank is populated, this only clears to the alias of + * DISPLAY_BASE in the first bank. If 2 banks are populated, this + * clears all the was to DISPLAY_BASE in the second bank. */ +#define SECURE_MEMORY_SIZE (DISPLAY_BASE - SECURE_MEMORY_BASE - SDRAM_BANK_LEN * 2 + platform_get_memory_size()) + +#define HEAP_EXT_BASE (DEFAULT_FREE_ADDRESS) +#define HEAP_EXT_SIZE (DISPLAY_BASE - SDRAM_BANK_LEN - HEAP_EXT_BASE) +#endif /* !WITH_DFU_MODE */ + +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#endif /* APPLICATION_IBOOT */ + +#define SCRATCH_BASE (0x33600000ULL) +#define SCRATCH_LEN (2048) + +#if APPLICATION_EMBEDDEDIOP +# if ARCH_ARMv7 +# define MMU_TT_SIZE (0x4000ULL) +# endif + +#define AUDIO_SRAM_RESERVE (0x1000ULL) +#define USB_SRAM_RESERVE (0x10000ULL) + +#if TARGET_S5L8945XAE2 +#define HEAP_EXT_BASE (SRAM_BASE + AUDIO_SRAM_RESERVE) +#define HEAP_EXT_SIZE (SRAM_LEN - AUDIO_SRAM_RESERVE - USB_SRAM_RESERVE) +#endif /* TARGET_S5L8945XAE2 */ + +#endif /* !APPLICATION_EMBEDDEDIOP */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s5l8945x/include/platform/pinconfig.h b/platform/s5l8945x/include/platform/pinconfig.h new file mode 100644 index 0000000..67f70a9 --- /dev/null +++ b/platform/s5l8945x/include/platform/pinconfig.h @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default S5L8945X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X3 + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // UART6_RTSN -> + CFG_DISABLED, // UART6_CTSN -> + +/* Port 1 */ + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> SPI0_SSIN + CFG_DISABLED, // UART4_TXD/SPI4_MOSI -> + CFG_DISABLED, // UART4_RXD/SPI4_MISO -> + CFG_DISABLED, // UART4_RTSN/SPI4_SCLK -> + CFG_DISABLED, // UART4_CTSN/SPI4_SSIN -> + +/* Port 2 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 3 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 4 */ + CFG_DISABLED, // DP_HPD -> + CFG_DISABLED, // EDP_HPD -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + +/* Port 5 */ + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED | PULL_DOWN, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED | PULL_DOWN, // GPIO7 -> + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + +/* Port 6 */ + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED | PULL_DOWN, // GPIO19 -> + +/* Port 7 */ + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED | PULL_DOWN, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED | PULL_DOWN, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + +/* Port 8 */ + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + +/* Port 9 */ + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // GPIO39 -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 10 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + +/* Port 11 */ + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RTXD -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SPI2_SCLK -> + +/* Port 12 */ + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // MIPI_VSYNC -> + +/* Port 13 */ + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // SWI_DATA -> + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_DO -> + CFG_DISABLED, // DWI_CLK -> + CFG_DISABLED, // SENSOR0_RST -> + +/* Port 14 */ + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + +/* Port 15 */ + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + +/* Port 16 */ + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // SPDIF -> + +/* Port 17 */ + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // EHCI_PORT_PWR[0] -> + CFG_DISABLED, // EHCI_PORT_PWR[1] -> + CFG_DISABLED, // EHCI_PORT_PWR[2] -> + CFG_DISABLED, // SDIO_CLK -> + CFG_DISABLED, // SDIO_CMD -> + +/* Port 18 */ + CFG_DISABLED, // SDIO_DATA0 -> + CFG_DISABLED, // SDIO_DATA1 -> + CFG_DISABLED, // SDIO_DATA2 -> + CFG_DISABLED, // SDIO_DATA3 -> + CFG_DISABLED, // GPIO_3V_0 -> + CFG_DISABLED, // GPIO_3V_1 -> + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + +/* Port 19 */ + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // FMI0_CEN7 -> + CFG_DISABLED, // FMI0_CEN6 -> + +/* Port 20 */ + CFG_DISABLED, // FMI0_CEN5 -> + CFG_DISABLED, // FMI0_CEN4 -> + CFG_DISABLED, // FMI1_CEN7 -> + CFG_DISABLED, // FMI1_CEN6 -> + CFG_DISABLED, // FMI1_CEN5 -> + CFG_DISABLED, // FMI1_CEN4 -> + CFG_DISABLED, // FMI2_CEN7 -> + CFG_DISABLED, // FMI2_CEN6 -> + +/* Port 21 */ + CFG_DISABLED, // FMI2_CEN5 -> + CFG_DISABLED, // FMI2_CEN4 -> + CFG_DISABLED, // FMI3_CEN7 -> + CFG_DISABLED, // FMI3_CEN6 -> + CFG_DISABLED, // FMI3_CEN5 -> + CFG_DISABLED, // FMI3_CEN4 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO6 -> + +/* Port 22 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + +/* Port 23 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO7 -> + +/* Port 24 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO0 -> + +/* Port 25 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN0 -> + +/* Port 26 */ + CFG_DISABLED, // FMI2_IO7 -> + CFG_DISABLED, // FMI2_IO6 -> + CFG_DISABLED, // FMI2_IO5 -> + CFG_DISABLED, // FMI2_IO4 -> + CFG_DISABLED, // FMI2_DQS -> + CFG_DISABLED, // FMI2_IO3 -> + CFG_DISABLED, // FMI2_IO2 -> + CFG_DISABLED, // FMI2_IO1 -> + +/* Port 27 */ + CFG_DISABLED, // FMI2_IO0 -> + CFG_DISABLED, // FMI2_REN -> + CFG_DISABLED, // FMI2_WEN -> + CFG_DISABLED, // FMI2_ALE -> + CFG_DISABLED, // FMI2_CLE -> + CFG_DISABLED, // FMI2_CEN3 -> + CFG_DISABLED, // FMI2_CEN2 -> + CFG_DISABLED, // FMI2_CEN1 -> + +/* Port 28 */ + CFG_DISABLED, // FMI2_CEN0 -> + CFG_DISABLED, // FMI3_IO7 -> + CFG_DISABLED, // FMI3_IO6 -> + CFG_DISABLED, // FMI3_IO5 -> + CFG_DISABLED, // FMI3_IO4 -> + CFG_DISABLED, // FMI3_DQS -> + CFG_DISABLED, // FMI3_IO3 -> + CFG_DISABLED, // FMI3_IO2 -> + +/* Port 29 */ + CFG_DISABLED, // FMI3_IO1 -> + CFG_DISABLED, // FMI3_IO0 -> + CFG_DISABLED, // FMI3_REN -> + CFG_DISABLED, // FMI3_WEN -> + CFG_DISABLED, // FMI3_ALE -> + CFG_DISABLED, // FMI3_CLE -> + CFG_DISABLED, // FMI3_CEN3 -> + CFG_DISABLED, // FMI3_CEN2 -> + +/* Port 30 */ + CFG_DISABLED, // FMI3_CEN1 -> + CFG_DISABLED, // FMI3_CEN0 -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s5l8945x/include/platform/soc/chipid.h b/platform/s5l8945x/include/platform/soc/chipid.h new file mode 100644 index 0000000..d11ea47 --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/chipid.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include + +#define rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCFG_FUSE1 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCFG_FUSE2 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rCFG_FUSE3 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x0C)) +#define rCFG_FUSE4 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x18)) +#define rCFG_FUSE5 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x1C)) +#define rCFG_FUSE6 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x20)) +#define rCFG_FUSE7 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x24)) + +#define rECIDLO (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x10)) +#define rECIDHI (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x14)) + +extern bool chipid_get_ecid_image_personalization_required(void); + +#define CHIPID_SOC_VOLTAGE_LOW (0) +#define CHIPID_SOC_VOLTAGE_MED (1) +#define CHIPID_SOC_VOLTAGE_HIGH (2) +extern u_int32_t chipid_get_soc_voltage(u_int32_t index); + +#define CHIPID_CPU_VOLTAGE_LOW (0) +#define CHIPID_CPU_VOLTAGE_MED (1) +#define CHIPID_CPU_VOLTAGE_HIGH (2) +extern u_int32_t chipid_get_cpu_voltage(u_int32_t index); + +extern u_int32_t chipid_get_fused_thermal_70C(void); +extern u_int32_t chipid_get_fused_thermal_25C(void); +extern u_int32_t chipid_get_fuse_revision(void); + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s5l8945x/include/platform/soc/display.h b/platform/s5l8945x/include/platform/soc/display.h new file mode 100644 index 0000000..3d82ea4 --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/display.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables +static struct adfe_v1_tuneable adfe_tuneables[] = +{ + { + .name = "default", + .disp_dpcclkcntl[0] = 0, + .disp_dpbclklvl_clock_off_level[0] = DPBCLKLVL_OFFLVL(0x01f0), + .disp_dpbclklvl_clock_on_level[0] = DPBCLKLVL_ONLVL(0x0180), + .disp_dpusrcstrd[0] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpcqoscnfg[0] = (DPCQOSCNFG_QOS_TIMER(0x0040) | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[0] = DPBQOSLVL_MED_WATERMARK(0x0100), + .disp_dpbqoslvl_high_watermark[0] = DPBQOSLVL_HIGH_WATERMARK(0x0000), + .disp_dpureqcfg[0] = 0, + + .disp_dpcclkcntl[1] = 0, + .disp_dpbclklvl_clock_off_level[1] = DPBCLKLVL_OFFLVL(0x01f0), + .disp_dpbclklvl_clock_on_level[1] = DPBCLKLVL_ONLVL(0x01c0), + .disp_dpusrcstrd[1] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpcqoscnfg[1] = (DPCQOSCNFG_QOS_TIMER(0x0040) | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[1] = DPBQOSLVL_MED_WATERMARK(0x0100), + .disp_dpbqoslvl_high_watermark[1] = DPBQOSLVL_HIGH_WATERMARK(0x0000), + .disp_dpureqcfg[1] = 0, + }, +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/s5l8945x/include/platform/soc/display_timings.h b/platform/s5l8945x/include/platform/soc/display_timings.h new file mode 100644 index 0000000..b4f18bd --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/display_timings.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_J1 || SUB_TARGET_J2 || SUB_TARGET_J2A + { + .display_name = "ipad3", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 205200000, + .dot_pitch = 264, + .h_active = 2048, + .h_back_porch = 80, + .h_front_porch = 48, + .h_pulse_width = 32, + .v_active = 1536, + .v_back_porch = 6, + .v_front_porch = 3, + .v_pulse_width = 4, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + }, +#endif +#if DEBUG_BUILD || WITH_HW_DISPLAY_HDMI + { + .display_name = "720p", + .host_clock_id = CLK_VCLK1, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 110, + .h_front_porch = 220, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 5, + .v_front_porch = 20, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_HDMI, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/s5l8945x/include/platform/soc/hwclocks.h b/platform/s5l8945x/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..fe0202e --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/hwclocks.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (5000000UL) +#else +#define OSC_FREQ (24000000UL) +#endif + +#define CLK_FCLK (HWCLOCK_BASE+0) +#define CLK_ACLK (HWCLOCK_BASE+1) +#define CLK_HCLK (HWCLOCK_BASE+2) +#define CLK_PCLK (HWCLOCK_BASE+3) +#define CLK_VCLK0 (HWCLOCK_BASE+4) +#define CLK_VCLK1 (HWCLOCK_BASE+5) +#define CLK_MCLK (HWCLOCK_BASE+6) +#define CLK_NCLK (HWCLOCK_BASE+7) +#define CLK_USBPHYCLK (HWCLOCK_BASE+8) +#define CLK_NCOREF (HWCLOCK_BASE+9) +#define CLK_FMI (HWCLOCK_BASE+10) + +/* S5L8945X clock gate devices */ +enum { + CLK_CPU0 = 0, + CLK_CPU1, + CLK_SCU, + CLK_L2RAM0, + CLK_L2RAM1, + CLK_CPU_REGS, + CLK_MCU, + CLK_GFX_SYS, + CLK_GFX_CORES, + CLK_HPERFNRT, + CLK_VDEC, + CLK_SCALER0, + CLK_SCALER1, + CLK_JPG0, + CLK_JPG1, + CLK_VENCD, + CLK_HPERFRT, + CLK_ISP, + CLK_resv0, + CLK_DISP0, + CLK_DISP1, + CLK_DISPOUT, + CLK_EDPLINK, + CLK_CLCD, + CLK_TVDAC, + CLK_RGBOUT, + CLK_DPLINK, + CLK_CDIO, + CLK_CDMA, + CLK_IOP, + CLK_UPERF, + CLK_UPERF1, + CLK_USBOTG, + CLK_USB20, + CLK_USB11, + CLK_USBOHCI0, + CLK_USBOHCI1, + CLK_USBPHY, + CLK_USB1_OTG, + CLK_USB1_20, + CLK_USB1_11, + CLK_USB1_OHCI0, + CLK_USB1_OHCI1, + CLK_USB1_PHY, + CLK_AUDIO, + CLK_I2S0, + CLK_I2S1, + CLK_I2S2, + CLK_I2S3, + CLK_SPDIF, + CLK_HPARK, + CLK_SDIO, + CLK_SHA1, + CLK_SHA2, + CLK_FMI0, + CLK_FMI0BCH, + CLK_FMI1, + CLK_FMI1BCH, + CLK_FMI2, + CLK_FMI2BCH, + CLK_FMI3, + CLK_FMI3BCH, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_SPI4, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_PKE, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_PWM, + CLK_SCRT, + CLK_GPIO, + CLK_SWI, + CLK_DWI, + CLK_DEBUG, + CLK_AIC, +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s5l8945x/include/platform/soc/hwdmachannels.h b/platform/s5l8945x/include/platform/soc/hwdmachannels.h new file mode 100644 index 0000000..3cef423 --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/hwdmachannels.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_H +#define __PLATFORM_SOC_HWDMACHANNELS_H + +#define DMA_MEMORY_TX (1) +#define DMA_MEMORY_RX (2) +#define DMA_SDIO (3) +#define DMA_FMI0DATA (5) +#define DMA_FMI0CHECK (6) +#define DMA_FMI1DATA (7) +#define DMA_FMI1CHECK (8) +#define DMA_FMI2DATA (9) +#define DMA_FMI2CHECK (10) +#define DMA_FMI3DATA (11) +#define DMA_FMI3CHECK (12) + +#define DMA_CHANNEL_COUNT (44) + +#define DMA_CHANNEL_CONFIG \ +{ \ + /* low high AES OK reqID FIFO address */ \ + { 3, 4, false, 0x00, 0x30000020 }, \ + { 3, 4, false, 0x01, 0x301000A0 }, \ + { 3, 4, false, 0x01, 0x30200020 }, \ + { 5, 12, true, 0x00, 0x31200014 }, \ + { 5, 12, true, 0x01, 0x31200018 }, \ + { 5, 12, true, 0x02, 0x31300014 }, \ + { 5, 12, true, 0x03, 0x31300018 }, \ + { 5, 12, true, 0x04, 0x31400014 }, \ + { 5, 12, true, 0x05, 0x31400018 }, \ + { 5, 12, true, 0x06, 0x31500014 }, \ + { 5, 12, true, 0x07, 0x31500018 }, \ +} + + +#define DMA_SDIO_TIMEOUT_US (10 * 1000) + + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_H */ diff --git a/platform/s5l8945x/include/platform/soc/hwisr.h b/platform/s5l8945x/include/platform/soc/hwisr.h new file mode 100644 index 0000000..c568b09 --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/hwisr.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 22010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_SWI 5 // SWI Interrupt +#define INT_DWI 6 // DWI Interrupt +#define INT_ISP0 7 // ISP 0 Interrupt +#define INT_ISP1 8 // ISP 1 Interrupt +#define INT_SCALER0 9 // Scaler Interrupt +#define INT_SCALER1 10 // Scaler Interrupt +#define INT_USB_OTG 11 // USB OTG Interrupt +#define INT_USB_EHCI 12 // USB EHCI Interrupt +#define INT_USB_OHCI0 13 // USB OHCI 0 Interrupt +#define INT_USB_OHCI1 14 // USB OHCI 1 Interrupt +#define INT_USB_RES 15 // USB PHY Interrupt +#define INT_PWM 16 // PWM Interrupt +#define INT_PKE 17 // PKE Interrupt +#define INT_IIC0 18 // I2C 0 Interrupt +#define INT_IIC1 19 // I2C 1 Interrupt +#define INT_IIC2 20 // I2C 2 Interrupt +#define INT_UART0 21 // UART 0 Interrupt +#define INT_UART1 22 // UART 1 Interrupt +#define INT_UART2 23 // UART 2 Interrupt +#define INT_UART3 24 // UART 3 Interrupt +#define INT_UART4 25 // UART 4 Interrupt +#define INT_UART5 26 // UART 5 Interrupt +#define INT_UART6 27 // UART 6 Interrupt +#define INT_SPI0 28 // SPI 0 Interrupt +#define INT_SPI1 29 // SPI 1 Interrupt +#define INT_SPI2 30 // SPI 2 Interrupt +#define INT_SPI3 31 // SPI 3 Interrupt +#define INT_SPI4 32 // SPI 4 Interrupt +#define INT_FMI0 33 // FMI 0 Interrupt +#define INT_FMI1 34 // FMI 1 Interrupt +#define INT_FMI2 35 // FMI 2 Interrupt +#define INT_FMI3 36 // FMI 3 Interrupt +#define INT_SHA1 37 // SHA-1 Interrupt +#define INT_SHA2 38 // SHA-1 Interrupt +#define INT_WIFI 39 // WiFi Interrupt +#define INT_TVOUT 40 // TV Out Interrupt +// Reserved 41 +#define INT_CLCD 42 // CLCD Interrupt +#define INT_DISP0 43 // Display Pipe 0 Interrupt +#define INT_DISP1 44 // Display Pipe 1 Interrupt +#define INT_RGBOUT 45 // RGB Out Interrupt +#define INT_DPORT0 46 // DisplayPort 0 Interrupt +#define INT_DPORT1 47 // DisplayPort 1 Interrupt +#define INT_VENC 48 // Video Encoder Interrupt +#define INT_SGX 49 // SGX Interrupt +#define INT_VDEC 50 // Video Decoder Interrupt +#define INT_CDMA_DMAC1 51 // CDMA DMA Channel 1 Interrupt +#define INT_CDMA_DMAC2 52 // CDMA DMA Channel 2 Interrupt +#define INT_CDMA_DMAC3 53 // CDMA DMA Channel 3 Interrupt +#define INT_CDMA_DMAC4 54 // CDMA DMA Channel 4 Interrupt +#define INT_CDMA_DMAC5 55 // CDMA DMA Channel 5 Interrupt +#define INT_CDMA_DMAC6 56 // CDMA DMA Channel 6 Interrupt +#define INT_CDMA_DMAC7 57 // CDMA DMA Channel 7 Interrupt +#define INT_CDMA_DMAC8 58 // CDMA DMA Channel 8 Interrupt +#define INT_CDMA_DMAC9 59 // CDMA DMA Channel 9 Interrupt +#define INT_CDMA_DMAC10 60 // CDMA DMA Channel 10 Interrupt +#define INT_CDMA_DMAC11 61 // CDMA DMA Channel 11 Interrupt +#define INT_CDMA_DMAC12 62 // CDMA DMA Channel 12 Interrupt +#define INT_CDMA_DMAC13 63 // CDMA DMA Channel 13 Interrupt +#define INT_CDMA_DMAC14 64 // CDMA DMA Channel 14 Interrupt +#define INT_CDMA_DMAC15 65 // CDMA DMA Channel 15 Interrupt +#define INT_CDMA_DMAC16 66 // CDMA DMA Channel 16 Interrupt +#define INT_CDMA_DMAC17 67 // CDMA DMA Channel 17 Interrupt +#define INT_CDMA_DMAC18 68 // CDMA DMA Channel 18 Interrupt +#define INT_CDMA_DMAC19 69 // CDMA DMA Channel 19 Interrupt +#define INT_CDMA_DMAC20 70 // CDMA DMA Channel 20 Interrupt +#define INT_CDMA_DMAC21 71 // CDMA DMA Channel 21 Interrupt +#define INT_CDMA_DMAC22 72 // CDMA DMA Channel 22 Interrupt +#define INT_CDMA_DMAC23 73 // CDMA DMA Channel 23 Interrupt +#define INT_CDMA_DMAC24 74 // CDMA DMA Channel 24 Interrupt +#define INT_CDMA_DMAC25 75 // CDMA DMA Channel 25 Interrupt +#define INT_CDMA_DMAC26 76 // CDMA DMA Channel 26 Interrupt +#define INT_CDMA_DMAC27 77 // CDMA DMA Channel 27 Interrupt +#define INT_CDMA_DMAC28 78 // CDMA DMA Channel 28 Interrupt +#define INT_CDMA_DMAC29 79 // CDMA DMA Channel 29 Interrupt +#define INT_CDMA_DMAC30 80 // CDMA DMA Channel 30 Interrupt +#define INT_CDMA_DMAC31 81 // CDMA DMA Channel 31 Interrupt +#define INT_CDMA_DMAC32 82 // CDMA DMA Channel 32 Interrupt +#define INT_CDMA_DMAC33 83 // CDMA DMA Channel 33 Interrupt +#define INT_CDMA_DMAC34 84 // CDMA DMA Channel 34 Interrupt +#define INT_CDMA_DMAC35 85 // CDMA DMA Channel 35 Interrupt +#define INT_CDMA_DMAC36 86 // CDMA DMA Channel 36 Interrupt +#define INT_CDMA_DMAC37 87 // CDMA DMA Channel 37 Interrupt +#define INT_CDMA_DMAC38 88 // CDMA DMA Channel 38 Interrupt +#define INT_CDMA_DMAC39 89 // CDMA DMA Channel 39 Interrupt +#define INT_CDMA_DMAC40 90 // CDMA DMA Channel 40 Interrupt +#define INT_CDMA_DMAC41 91 // CDMA DMA Channel 41 Interrupt +#define INT_CDMA_DMAC42 92 // CDMA DMA Channel 42 Interrupt +#define INT_CDMA_DMAC43 93 // CDMA DMA Channel 43 Interrupt +#define INT_CDMA_DMAC44 94 // CDMA DMA Channel 44 Interrupt + +// Reserved 95 - 96 + +// Audio and Highland Park Interrupts 97 - 115 + +#define INT_AUDIO_CPU_IRQ0 97 // +#define INT_AUDIO_CPU_IRQ1 98 // + +#define INT_HPERFNRT_DART 116 // HPerf-NRT DART Interrupt +#define INT_HPERFRT_DART 117 // HPerf-RT DART Interrupt +#define INT_JPG 118 // JPEG Interrupt +#define INT_GPIO0 119 // GPIO 0 Interrupt +#define INT_GPIO1 120 // GPIO 1 Interrupt +#define INT_MCU 121 // MCU 0 Interrupt +#define INT_MCU0 122 // MCU 0 Interrupt +#define INT_MCU1 123 // MCU 1 Interrupt +#define INT_PIO0 124 // PIO 0 Interrupt +#define INT_PIO1 125 // PIO 1 Interrupt + +// Reserved 126 + +#define INT_IOP_COMMRX 127 // IOP CommRx Interrupt +#define INT_IOP_COMMTX 128 // IOP CommTx Interrupt +#define INT_IOP_PMI 129 // IOP PerfMon Interrupt +#define INT_IOP_CTIIRQ 130 // IOP CTIIRQ Interrupt +#define INT_ISP_COMMRX 131 // IOP CommRx Interrupt +#define INT_ISP_COMMTX 132 // IOP CommTx Interrupt +#define INT_ISP_PMI 133 // IOP PerfMon Interrupt +#define INT_ISP_CTIIRQ 134 // IOP CTIIRQ Interrupt + +#define INT_CPU0_PMI 135 // IOP Perfmon Interrupt +#define INT_CPU0_CTIIRQ 136 // IOP CTI Interrupt +#define INT_CPU0_COMMRX 137 // IOP CommRx Interrupt +#define INT_CPU0_COMMTX 138 // IOP CommTx Interrupt +#define INT_CPU1_PMI 139 // IOP PMI Interrupt +#define INT_CPU1_CTIIRQ 140 // IOP CTI Interrupt +#define INT_CPU1_COMMRX 141 // IOP CommRx Interrupt +#define INT_CPU1_COMMTX 142 // IOP CommTx Interrupt + +#define INT_L2C 143 // PL310 Interrupt + +// Reserved 144 - 151 + +#define INT_PMGR_PMI 152 // PMGR PerfMon Interrupt +#define INT_HPERFNTR_PMI 153 // HPerf-NRT PerfMon Interrupt +#define INT_HPERFRT_PMI 154 // HPerf-RT PerfMon Interrupt +#define INT_DPIPE0_PMI 155 // Display Pipe 0 PerfMon Interrupt +#define INT_DPIPE1_PMI 156 // Display Pipe 1 PerfMon Interrupt + +// Reserved 157 - 159 + +#define INT_ETB_FULL 160 // ETB Full Interrupt + +#define INT_USB1_OTG 161 // USB1 OTG Interrupt +#define INT_USB1_EHCI 162 // USB1 EHCI Interrupt +#define INT_USB1_OHCI0 163 // USB1 OHCI 0 Interrupt +#define INT_USB1_OHCI1 164 // USB1 OHCI 1 Interrupt +#define INT_USB1_RES 165 // USB1 PHY Interrupt +#define INT_JPG1 166 // JPEG1 Interrupt +#define INT_EDP0 167 // EDisplayPort 0 Interrupt +#define INT_EDP1 168 // EDisplayPort 1 Interrupt +#define INT_AES 169 // AES Interrupt +#define INT_THERMAL_TEMP 170 // Thermal Temp Interrupt +#define INT_THERMAL_ALARM 171 // Thermal Alarm Interrupt +#define INT_MCU2 172 // MCU Channel 2 Interrupt +#define INT_MCU3 173 // MCU Channel 3 Interrupt + +// Reserved 174 - 191 + +#if PLATFORM_VARIANT_IOP + +#include + +#define INT_HOST INT_SW2 // Host processor doorbell +#define INT_IOP INT_SW3 // I/O coprocessor doorbell +#define INT_IOP_NMI kAIC_VEC_SW_TMR // I/O coprocessor NMI + +#elif PLATFORM_VARIANT_AUDIO + +#include + +#define INT_HOST AE2_INT_SW0 // Host processor doorbell +#define INT_IOP AE2_INT_SW0 // I/O coprocessor doorbell +#define INT_IOP_NMI AE2_INT_SW1 // I/O coprocessor NMI + +#endif + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s5l8945x/include/platform/soc/hwregbase.h b/platform/s5l8945x/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..21773c5 --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/hwregbase.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +/* S5L8940X Reg Base Defs */ + +#define AIC_VERSION 0 +#define AIC_INT_COUNT (192) +#define PMGR_WDG_VERSION 0 + +#define SDIO_BASE_ADDR (0x30000000) + +#define SHA1_BASE_ADDR (0x30100000) +#define SHA2_BASE_ADDR (0x30200000) + +#define FMI0_BASE_ADDR (0x31200000) +#define FMI1_BASE_ADDR (0x31300000) +#define FMI2_BASE_ADDR (0x31400000) +#define FMI3_BASE_ADDR (0x31500000) +#define FMI_VERSION (4) + +#define SPI0_BASE_ADDR (0x32000000) +#define SPI1_BASE_ADDR (0x32100000) +#define SPI2_BASE_ADDR (0x32200000) +#define SPI3_BASE_ADDR (0x32300000) +#define SPI4_BASE_ADDR (0x32400000) +#define SPI_VERSION (1) +#define SPIS_COUNT (5) + +#define UART0_BASE_ADDR (0x32500000) +#define UART1_BASE_ADDR (0x32600000) +#define UART2_BASE_ADDR (0x32700000) +#define UART3_BASE_ADDR (0x32800000) +#define UART4_BASE_ADDR (0x32900000) +#define UART5_BASE_ADDR (0x32A00000) +#define UART6_BASE_ADDR (0x32B00000) +#define UART_VERSION (1) +#define UARTS_COUNT (7) + +#define PKE_BASE_ADDR (0x33100000) + +#define IIC_BASE_ADDR (0x33200000) +#define IIC_SPACING (0x00100000) +#define IICS_COUNT (3) + +#define AUDIO_BASE_ADDR (0x34000000) + +#define USBPHY_BASE_ADDR (0x36000000) +#define USBPHY_VERSION (3) +#define USBOTG_BASE_ADDR (0x36100000) +#define UPERF_WIDGETS_BASE_ADDR (0x36200000) +#define UPERF_PL301_BASE_ADDR (0x36300000) +#define UPERF1_WIDGETS_BASE_ADDR (0x36A00000) +#define UPERF1_PL301_BASE_ADDR (0x36B00000) + +#define CDMA_BASE_ADDR (0x37000000) +#define CDMA_VERSION 4 + +#define VENC_BASE_ADDR (0x38000000) + +#define VDEC_BASE_ADDR (0x38100000) + +#define JPEG_BASE_ADDR (0x38200000) + +#define SCALER_BASE_ADDR (0x38300000) +#define SCALER_SPACING (0x00100000) + +#define NRT_DART_BASE_ADDR (0x38B00000) +#define NRT_DART_WIDGETS_BASE_ADDR (0x38C00000) +#define NRT_DART_PL301_BASE_ADDR (0x38D00000) +#define NRT_TOP_WIDGETS_BASE_ADDR (0x38E00000) +#define NRT_TOP_PL301_BASE_ADDR (0x38F00000) + +#define CLCD_BASE_ADDR (0x39200000) +#define CLCD_VERSION (0) +#define CLCD_DITHER_BASE_ADDR (0x39300000) +#define DITHER_VERSION (1) + +#define TVOUT_BASE_ADDR (0x39400000) + +#define RGBOUT_BASE_ADDR (0x39600000) +#define RGBOUT_DITHER_BASE_ADDR (0x39800000) + +#define EDP_BASE_ADDR (0x39500000) +#define DP_BASE_ADDR (0x39700000) +#define DISPLAYPORT_VERSION (2) + +#define ISP_BASE_ADDR (0x3A000000) + +#define DISP0_BASE_ADDR (0x3A100000) +#define DISP1_BASE_ADDR (0x3A200000) +#define CLCD_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define RGBOUT_DISPLAYPIPE_BASE_ADDR (DISP1_BASE_ADDR) +#define DISP_VERSION (4) + +#define RT_DART_BASE_ADDR (0x3A400000) +#define RT_TOP_WIDGETS_BASE_ADDR (0x3A500000) +#define RT_TOP_PL301_BASE_ADDR (0x3A600000) + +#define HP_BASE_ADDR (0x3B000000) + +#define AMG_BASE_ADDR (0x3D000000) +#define AMG_SPACING (0x00100000) + +#define PL310_BASE_ADDR (0x3E000000) +#define SCU_BASE_ADDR (0x3E100000) + +#define PMGR_BASE_ADDR (0x3F100000) +#define AIC_BASE_ADDR (0x3F200000) + +#define IOP_BASE_ADDR (0x3F300000) + +#define ROSC_BASE_ADDR (0x3F400000) +#define ROSC_MASK (0x57FF) +#define ROSC_WITH_CLOCK (0) + +#define CHIPID_BASE_ADDR (0x3F500000) + +#define SWI_BASE_ADDR (0x3F600000) +#define DWI_BASE_ADDR (0x3F700000) + +#define AMC_BASE_ADDR (0x3F800000) + +#define GPIO_BASE_ADDR (0x3FA00000) +#define GPIO_VERSION (1) +#define GPIO_GROUP_COUNT (31) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define PIO_BASE_ADDR (0x3FB00000) +#define PIO_SPACING (0x00100000) + +#define CIF_BASE_ADDR (0x3FD00000) + +#define CDIO_WIDGETS_BASE_ADDR (0x3FE00000) +#define CDIO_PL301_BASE_ADDR (0x3FF00000) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s5l8945x/include/platform/soc/miu.h b/platform/s5l8945x/include/platform/soc/miu.h new file mode 100644 index 0000000..a6e4f9b --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/miu.h @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rREMAP_CTL (*(volatile u_int32_t *)(PIO_BASE_ADDR + 0x0000)) + +#define rPL310_CONTROL (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x0100)) +#define rPL310_INVAL_WAY (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x077C)) +#define rPL310_FILTER_START (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x0C00)) +#define rPL310_FILTER_END (*(volatile u_int32_t *)(PL310_BASE_ADDR + 0x0C04)) + +#define rSCU_CONTROL (*(volatile u_int32_t *)(SCU_BASE_ADDR + 0x0000)) +#define rSCU_POWER_STATUS (*(volatile u_int32_t *)(SCU_BASE_ADDR + 0x0008)) +#define rSCU_TAG_INVAL (*(volatile u_int32_t *)(SCU_BASE_ADDR + 0x000C)) + +#define rCIF_CONTROL (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0000)) +#define rCIF_CLKGATE (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0004)) +#define rCIF_RTLIMIT (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0008)) +#define rCIF_WTLIMIT (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x000C)) +#define rCIF_IDLETMR (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0010)) +#define rCIF_RDREMAP (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0040)) +#define rCIF_WRREMAP (*(volatile u_int32_t *)(CIF_BASE_ADDR + 0x0044)) + +#define CDIO_IOP_RTLIMIT (0x0008) +#define rCDIO_IOP_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RTLIMIT)) +#define CDIO_IOP_WTLIMIT (0x000C) +#define rCDIO_IOP_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WTLIMIT)) +#define CDIO_IOP_WREQSP (0x001C) +#define rCDIO_IOP_WREQSP (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WREQSP)) +#define CDIO_CDMA_RTLIMIT (0x0028) +#define rCDIO_CDMA_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_RTLIMIT)) +#define CDIO_CDMA_WTLIMIT (0x002C) +#define rCDIO_CDMA_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WTLIMIT)) +#define CDIO_CDMA_WGATHER (0x0030) +#define rCDIO_CDMA_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WGATHER)) +#define CDIO_UPERF_RTLIMIT (0x0048) +#define rCDIO_UPERF_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_RTLIMIT)) +#define CDIO_UPERF_WTLIMIT (0x004C) +#define rCDIO_UPERF_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WTLIMIT)) +#define CDIO_UPERF_WGATHER (0x0050) +#define rCDIO_UPERF_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WGATHER)) +#define CDIO_AUDIO_RTLIMIT (0x0068) +#define rCDIO_AUDIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_RTLIMIT)) +#define CDIO_AUDIO_WTLIMIT (0x006C) +#define rCDIO_AUDIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WTLIMIT)) +#define CDIO_AUDIO_WGATHER (0x0070) +#define rCDIO_AUDIO_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WGATHER)) +#define CDIO_PIO_RTLIMIT (0x00A8) +#define rCDIO_PIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_RTLIMIT)) +#define CDIO_PIO_WTLIMIT (0x00AC) +#define rCDIO_PIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_WTLIMIT)) +#define CDIO_UPERF1_RTLIMIT (0x00C8) +#define rCDIO_UPERF1_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF1_RTLIMIT)) +#define CDIO_UPERF1_WTLIMIT (0x00CC) +#define rCDIO_UPERF1_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPER1F_WTLIMIT)) +#define CDIO_UPERF1_WGATHER (0x00D0) +#define rCDIO_UPERF1_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF1_WGATHER)) + +#define CDIO_AR_CHAN_ARB_MI0 (0x0408) +#define rCDIO_AR_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI0)) +#define CDIO_AW_CHAN_ARB_MI0 (0x040C) +#define rCDIO_AW_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI0)) +#define CDIO_AR_CHAN_ARB_MI1 (0x0428) +#define rCDIO_AR_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI1)) +#define CDIO_AW_CHAN_ARB_MI1 (0x042C) +#define rCDIO_AW_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI1)) + +#define UPERF_OTG_QOS (0x0014) +#define rUPERF_OTG_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_QOS)) +#define UPERF_OTG_CACHE (0x0018) +#define rUPERF_OTG_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_CACHE)) +#define UPERF_EHCI_QOS (0x0034) +#define rUPERF_EHCI_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_QOS)) +#define UPERF_EHCI_CACHE (0x0038) +#define rUPERF_EHCI_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_CACHE)) +#define UPERF_OHCI0_QOS (0x0054) +#define rUPERF_OHCI0_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_QOS)) +#define UPERF_OHCI0_CACHE (0x0058) +#define rUPERF_OHCI0_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_CACHE)) +#define UPERF_OHCI1_QOS (0x0074) +#define rUPERF_OHCI1_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_QOS)) +#define UPERF_OHCI1_CACHE (0x0078) +#define rUPERF_OHCI1_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_CACHE)) +#define UPERF_RTLIMIT (0x0088) +#define rUPERF_RTLIMIT (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_RTLIMIT)) +#define UPERF_WTLIMIT (0x008C) +#define rUPERF_WTLIMIT (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_WTLIMIT)) + +#define rUPERF1_OTG_QOS (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_OTG_QOS)) +#define rUPERF1_OTG_CACHE (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_OTG_CACHE)) +#define rUPERF1_EHCI_QOS (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_EHCI_QOS)) +#define rUPERF1_EHCI_CACHE (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_EHCI_CACHE)) +#define rUPERF1_OHCI0_QOS (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_OHCI0_QOS)) +#define rUPERF1_OHCI0_CACHE (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_OHCI0_CACHE)) +#define rUPERF1_OHCI1_QOS (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_OHCI1_QOS)) +#define rUPERF1_OHCI1_CACHE (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_OHCI1_CACHE)) +#define rUPERF1_RTLIMIT (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_RTLIMIT)) +#define rUPERF1_WTLIMIT (*(volatile u_int32_t *)(UPERF1_WIDGETS_BASE_ADDR + UPERF_WTLIMIT)) + +#define HPERF_NRT_DART_DART_RTLIMIT (0x0004) +#define rHPERF_NRT_DART_DART_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_RTLIMIT)) +#define HPERF_NRT_DART_DART_WTLIMIT (0x0008) +#define rHPERF_NRT_DART_DART_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_WTLIMIT)) +#define HPERF_NRT_DART_JPEG0_QOS (0x000C) +#define rHPERF_NRT_DART_JPEG0_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_QOS)) +#define HPERF_NRT_DART_JPEG1_QOS (0x0010) +#define rHPERF_NRT_DART_JPEG1_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG1_QOS)) +#define HPERF_NRT_DART_SCALER0_RTLIMIT (0x001C) +#define rHPERF_NRT_DART_SCALER0_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_RTLIMIT)) +#define HPERF_NRT_DART_SCALER0_WTLIMIT (0x0020) +#define rHPERF_NRT_DART_SCALER0_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_WTLIMIT)) +#define HPERF_NRT_DART_SCALER1_RTLIMIT (0x0030) +#define rHPERF_NRT_DART_SCALER1_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_RTLIMIT)) +#define HPERF_NRT_DART_SCALER1_WTLIMIT (0x0034) +#define rHPERF_NRT_DART_SCALER1_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_WTLIMIT)) + +#define HPERF_NRT_DART_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_DART_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_DART_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_DART_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AW_CHAN_ARB_MI0)) + +#define HPERF_NRT_TOP_TOP_RTLIMIT (0x0000) +#define rHPERF_NRT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_RTLIMIT)) +#define HPERF_NRT_TOP_TOP_WTLIMIT (0x0004) +#define rHPERF_NRT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_RTLIMIT (0x0010) +#define rHPERF_NRT_TOP_VENC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_RTLIMIT)) +#define HPERF_NRT_TOP_VENC_WTLIMIT (0x0014) +#define rHPERF_NRT_TOP_VENC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_WREQSP (0x0018) +#define rHPERF_NRT_TOP_VENC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WREQSP)) +#define HPERF_NRT_TOP_VDEC_RTLIMIT (0x0028) +#define rHPERF_NRT_TOP_VDEC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_RTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WTLIMIT (0x002C) +#define rHPERF_NRT_TOP_VDEC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WREQSP (0x0030) +#define rHPERF_NRT_TOP_VDEC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WREQSP)) +#define HPERF_NRT_TOP_DART_WGATHER (0x0048) +#define rHPERF_NRT_TOP_DART_WGATHER (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_DART_WGATHER)) + +#define HPERF_NRT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AW_CHAN_ARB_MI0)) + +#define HPERF_RT_TOP_DISP0_RTLIMIT (0x0004) +#define rHPERF_RT_TOP_DISP0_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP0_RTLIMIT)) +#define HPERF_RT_TOP_DISP1_RTLIMIT (0x000C) +#define rHPERF_RT_TOP_DISP1_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP1_RTLIMIT)) +#define HPERF_RT_TOP_ISP_RTLIMIT (0x0018) +#define rHPERF_RT_TOP_ISP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_WTLIMIT)) +#define HPERF_RT_TOP_ISP_WTLIMIT (0x001C) +#define rHPERF_RT_TOP_ISP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_RTLIMIT)) +#define HPERF_RT_TOP_TOP_RTLIMIT (0x0020) +#define rHPERF_RT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_WTLIMIT)) +#define HPERF_RT_TOP_TOP_WTLIMIT (0x0024) +#define rHPERF_RT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_RTLIMIT)) + +#define HPERF_RT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_RT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_RT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_RT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AW_CHAN_ARB_MI0)) + + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s5l8945x/include/platform/soc/pmgr.h b/platform/s5l8945x/include/platform/soc/pmgr.h new file mode 100644 index 0000000..8394d70 --- /dev/null +++ b/platform/s5l8945x/include/platform/soc/pmgr.h @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include + +#define rPMGR_PLL0_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0000)) +#define rPMGR_PLL0_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0004)) +#define rPMGR_PLL1_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0008)) +#define rPMGR_PLL1_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x000C)) +#define rPMGR_PLL2_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0010)) +#define rPMGR_PLL2_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0014)) +#define rPMGR_PLL3_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0018)) +#define rPMGR_PLL3_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x001C)) +#define rPMGR_PLL4_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0020)) +#define rPMGR_PLL4_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0024)) +#define rPMGR_PLL5_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0028)) +#define rPMGR_PLL5_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x002C)) +#define rPMGR_PLLUSB_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0030)) +#define rPMGR_PLLUSB_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0034)) + +#define rPMGR_PLL_ENABLE (1 << 31) +#define rPMGR_PLL_EXT_BYPASS (1 << 30) +#define rPMGR_PLL_REAL_LOCK (1 << 29) +#define rPMGR_PLL_LOAD (1 << 27) +#define rPMGR_PLL_BYPASS (1 << 23) +#define rPMGR_PLL_P(_p) (((_p) & 0x03f) << 14) +#define rPMGR_PLL_M(_m) (((_m) & 0x3ff) << 3) +#define rPMGR_PLL_S(_s) (((_s) & 0x007) << 0) + +#define rPMGR_PARAM_EXT_AFC(_n) ((_n) << 17) +#define rPMGR_PARAM_AFC_EN (1 << 16) +#define rPMGR_PARAM_LOCK_TIME(_n) ((_n) << 0) + +#define rPMGR_PLL_GATES (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0040)) + +#define rPMGR_DOUBLER_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0044)) + +#define rPMGR_DOUBLER_ENABLE (1 << 31) +#define rPMGR_DOUBLER_EXT_BYPASS (1 << 30) + +#define rPMGR_CPU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0048)) +#define rPMGR_MCU_FIXED_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x004C)) +#define rPMGR_MCU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0050)) +#define rPMGR_PCLK1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0054)) + +#define rPMGR_PREDIV0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0058)) +#define rPMGR_PREDIV1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x005C)) +#define rPMGR_PREDIV2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0060)) +#define rPMGR_PREDIV3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0064)) +#define rPMGR_PREDIV4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0068)) +#define rPMGR_PREDIV5_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x006C)) +#define rPMGR_PREDIV6_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0070)) + +#define rPMGR_MANAGED0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0074)) +#define rPMGR_MANAGED1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0078)) +#define rPMGR_MANAGED2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x007C)) +#define rPMGR_MANAGED3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0080)) +#define rPMGR_MANAGED4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0084)) +#define rPMGR_MANAGED5_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0088)) +#define rPMGR_AES_CORE_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x008C)) + +#define rPMGR_VID1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0090)) +#define rPMGR_MEDIUM0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0094)) +#define rPMGR_VID0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0098)) +#define rPMGR_I2C_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x009C)) +#define rPMGR_SDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00A0)) +#define rPMGR_AUDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00A4)) +#define rPMGR_HPARK_PCLK0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00A8)) +#define rPMGR_HPARK_TCLK_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00AC)) +#define rPMGR_UPERF_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00B0)) +#define rPMGR_DEBUG_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00B4)) + +#define rPMGR_HPERFRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00B8)) +#define rPMGR_GFX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00BC)) +#define rPMGR_GFX_SLC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00C0)) + +#define rPMGR_HPERFNRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00C4)) +#define rPMGR_ISP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00C8)) +#define rPMGR_IOP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00CC)) +#define rPMGR_CDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00D0)) + +#define rPMGR_LPERFS_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00D4)) +#define rPMGR_PCLK0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00D8)) +#define rPMGR_PCLK2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00DC)) +#define rPMGR_PCLK3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00E0)) + +#define rPMGR_MEDIUM1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00E4)) +#define rPMGR_SPI0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00E8)) +#define rPMGR_SPI1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00EC)) +#define rPMGR_SPI2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00F0)) +#define rPMGR_SPI3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00F4)) +#define rPMGR_SPI4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00F8)) +#define rPMGR_SLEEP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x00FC)) +#define rPMGR_USBPHY_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0100)) +#define rPMGR_USBPHY1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0104)) +#define rPMGR_USBOHCI_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0108)) +#define rPMGR_USB12_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x010C)) +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0110)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0114)) +#define rPMGR_NCO_REF2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0118)) +#define rPMGR_VENC_MTX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x011C)) +#define rPMGR_VENC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0120)) + +#define rPMGR_SLV_BUS_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0124)) + +#define PMGR_FIRST_CLK_CFG (&rPMGR_CPU_CLK_CFG) +#define PMGR_LAST_CLK_CFG (&rPMGR_SLV_BUS_CLK_CFG) +#define PMGR_CLK_CFG_COUNT (((((u_int32_t)(PMGR_LAST_CLK_CFG)) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) + 1) +#define PMGR_CLK_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _CLK_CFG) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) + +#define rPMGR_I2S0_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0130)) +#define rPMGR_I2S0_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0134)) +#define rPMGR_I2S0_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0138)) + +#define rPMGR_I2S1_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0140)) +#define rPMGR_I2S1_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0144)) +#define rPMGR_I2S1_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0148)) + +#define rPMGR_I2S2_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0150)) +#define rPMGR_I2S2_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0154)) +#define rPMGR_I2S2_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0158)) + +#define rPMGR_I2S3_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0160)) +#define rPMGR_I2S3_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0164)) +#define rPMGR_I2S3_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0168)) + +#define rPMGR_SPDIF_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0170)) +#define rPMGR_SPDIF_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0174)) +#define rPMGR_SPDIF_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0178)) + +#define rPMGR_DP_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0180)) +#define rPMGR_DP_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0184)) +#define rPMGR_DP_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0188)) + +#define rPMGR_AMC_REF_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01C0)) + +#define rPMGR_MASH_REF_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01C4)) +#define rPMGR_MASH_CFG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01C8)) +#define rPMGR_MASH_CFG2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01CC)) +#define rPMGR_SPREAD_CFG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01D0)) + +#define rPMGR_CLK_CFG_ENABLE (1 << 31) +#define rPMGR_CLK_CFG_PENDING (1 << 30) +#define rPMGR_CLK_CFG_DIVIDER(_d) (((_d) & 0x1f) << 0) +#define rPMGR_CLK_CFG_DIV_MASK rPMGR_CLK_CFG_DIVIDER(0x1f) + +#define PMGR_PERF_STATE_COUNT (16) +#define rPMGR_PERF_STATE_A(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0200 + ((_s) * 0x10))) +#define rPMGR_PERF_STATE_B(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0204 + ((_s) * 0x10))) +#define rPMGR_PERF_STATE_C(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0208 + ((_s) * 0x10))) +#define rPMGR_PERF_STATE_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0300)) + +#define PMGR_PERF_STATE_SEL(_s) (((_s) & 0xF) << 0) +#define PMGR_PERF_STATE_PENDING (0xFF << 16) + +#define kPERF_STATE_BYPASS (0) +#define kPERF_STATE_SECUREROM (1) +#define kPERF_STATE_IBOOT (2) +#define kPERF_STATE_IBOOT_CNT (5) + +#define rPMGR_MCU_CLK_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0400)) + +#define rPMGR_CPU0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1008)) +#define rPMGR_CPU1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x100C)) +#define rPMGR_SCU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1010)) +#define rPMGR_L2RAM0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1014)) +#define rPMGR_L2RAM1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1018)) +#define rPMGR_CPU_REGS_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x101C)) +#define rPMGR_MCU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1020)) +#define rPMGR_GFX_SYS_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1024)) +#define rPMGR_GFX_CORES_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1028)) +#define rPMGR_HPERFNRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x102C)) +#define rPMGR_VDEC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1030)) +#define rPMGR_SCALER0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1034)) +#define rPMGR_SCALER1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1038)) +#define rPMGR_JPG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x103C)) +#define rPMGR_JPG1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1040)) +#define rPMGR_VENCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1044)) +#define rPMGR_HPERFRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1048)) +#define rPMGR_ISP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x104C)) +#define rPMGR_DISP0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1054)) +#define rPMGR_DISP1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1058)) +#define rPMGR_DISPOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x105C)) +#define rPMGR_EDPLINK_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1060)) +#define rPMGR_CLCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1064)) +#define rPMGR_TVOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1068)) +#define rPMGR_RGBOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x106C)) +#define rPMGR_DPLINK_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1070)) +#define rPMGR_CDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1074)) +#define rPMGR_CDMA_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1078)) +#define rPMGR_IOP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x107C)) +#define rPMGR_UPERF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1080)) +#define rPMGR_UPERF1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1084)) +#define rPMGR_USB_OTG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1088)) +#define rPMGR_USB_20_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x108C)) +#define rPMGR_USB_11_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1090)) +#define rPMGR_USB_OHCI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1094)) +#define rPMGR_USB_OHCI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1098)) +#define rPMGR_USB_REG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x109C)) +#define rPMGR_USB1_OTG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A0)) +#define rPMGR_USB1_20_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A4)) +#define rPMGR_USB1_11_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A8)) +#define rPMGR_USB1_OHCI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10AC)) +#define rPMGR_USB1_OHCI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B0)) +#define rPMGR_USB1_REG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B4)) +#define rPMGR_AUDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B8)) +#define rPMGR_I2S0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10BC)) +#define rPMGR_I2S1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C0)) +#define rPMGR_I2S2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C4)) +#define rPMGR_I2S3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C8)) +#define rPMGR_SPDIF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10CC)) +#define rPMGR_HPARK_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D0)) +#define rPMGR_SDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D4)) +#define rPMGR_SHA1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D8)) +#define rPMGR_SHA2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10DC)) +#define rPMGR_FMI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E0)) +#define rPMGR_FMI0BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E4)) +#define rPMGR_FMI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E8)) +#define rPMGR_FMI1BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10EC)) +#define rPMGR_FMI2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F0)) +#define rPMGR_FMI2BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F4)) +#define rPMGR_FMI3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F8)) +#define rPMGR_FMI3BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10FC)) +#define rPMGR_SPI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1100)) +#define rPMGR_SPI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1104)) +#define rPMGR_SPI2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1108)) +#define rPMGR_SPI3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x110C)) +#define rPMGR_SPI4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1110)) +#define rPMGR_UART0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1114)) +#define rPMGR_UART1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1118)) +#define rPMGR_UART2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x111C)) +#define rPMGR_UART3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1120)) +#define rPMGR_UART4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1124)) +#define rPMGR_UART5_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1128)) +#define rPMGR_UART6_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x112C)) +#define rPMGR_PKE_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1130)) +#define rPMGR_I2C0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1134)) +#define rPMGR_I2C1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1138)) +#define rPMGR_I2C2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x113C)) +#define rPMGR_PWM_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1140)) +#define rPMGR_SCRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1144)) +#define rPMGR_GPIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1148)) +#define rPMGR_SWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x114C)) +#define rPMGR_DWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1150)) +#define rPMGR_DEBUG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1154)) +#define rPMGR_AIC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1158)) + +#define rPMGR_PS_RESET (1 << 31) + +#define PMGR_FIRST_PS (&rPMGR_CPU0_PS) +#define PMGR_LAST_PS (&rPMGR_AIC_PS) +#define PMGR_DEV_PS_COUNT (((((u_int32_t)(PMGR_LAST_PS)) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + 1) +#define PMGR_PS_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _PS) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + +#define rPMGR_CPU_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1180)) + +#define rPMGR_PWR_GATE_CTL_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1200)) +#define rPMGR_PWR_GATE_CTL_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1204)) +#define rPMGR_PWR_GATE_IOP (1 << 6) +#define rPMGR_PWR_GATE_GFX_MODE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1208)) + +#define rPMGR_CORE_OFFLINE_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1210)) +#define rPMGR_CORE_OFFLINE_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1214)) +#define rPMGR_WAKE_CORES (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1220)) + +#define PMGR_PWR_GATE_TIME_COUNT (15) +#define rPMGR_PWR_GATE_TIME_A(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1238 + ((_n) * 8))) +#define rPMGR_PWR_GATE_TIME_B(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x123C + ((_n) * 8))) +#define rPMGR_PWR_GATE_DBG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E0)) +#define rPMGR_PWR_GATE_DBG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E4)) + +#define rPMGR_TEST_CLK (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2000)) +#define rPMGR_OSC_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x200C)) +#define rPMGR_PLL0_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2010)) +#define rPMGR_PLL1_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2014)) +#define rPMGR_PLL2_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2018)) +#define rPMGR_PLL3_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x201C)) +#define rPMGR_PLL4_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2020)) +#define rPMGR_PLL5_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2024)) +#define rPMGR_PLLUSB_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2028)) +#define rPMGR_DOUBLER_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x202C)) + +#define rPMGR_PLL_DEBUG_ENABLED (1 << 31) +#define rPMGR_PLL_DEBUG_BYP_ENABLED (1 << 30) +#define rPMGR_PLL_DEBUG_DBG_STPCLK_EN (1 << 24) +#define rPMGR_PLL_DEBUG_LOST_LOCK (1 << 16) +#define rPMGR_PLL_DEBUG_STATE(_r) (((_r) >> 0) & 0xff) + +#define rPMGR_EMA_CTL_CPU (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2100)) +#define rPMGR_EMA_CTL_CPU_SEL (0x01 << 0) +#define rPMGR_EMA_CTL_CPU_SPIN (0x01 << 16) +#define rPMGR_EMA_CTL_SOC (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2104)) +#define rPMGR_EMA_CTL_SOC_SEL (0x1f << 0) // XXX BANK_SEL_DISP? +#define rPMGR_EMA_CTL_SOC_SPIN (0x01 << 16) + +#define rPMGR_SRAM_EMA_B0_Pn_LO(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2120 + ((_n) * 8))) +#define rPMGR_SRAM_EMA_B0_Pn_HI(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2124 + ((_n) * 8))) +#define rPMGR_SRAM_EMA_B1_Pn_LO(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x21C0 + ((_n) * 8))) +#define rPMGR_SRAM_EMA_B1_Pn_HI(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x21C4 + ((_n) * 8))) + +enum { + EMA_CPU = 0, + EMA_MCU = 1, + EMA_GFX_PIPES_SYS = 2, + EMA_GFX_HYDRA = 3, + EMA_VDEC = 4, + EMA_VENC = 5, + EMA_ISP = 6, + EMA_DISP = 7, + EMA_NRT = 8, + EMA_CIF = 9, + EMA_IOP = 10, + EMA_SAUDIO = 11, + EMA_CDMA = 12, + EMA_FMI = 13, + EMA_HPARK = 14, +}; + +#define rPMGR_WDOG_TMR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3020)) +#define rPMGR_WDOG_RST (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3024)) +#define rPMGR_WDOG_INT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3028)) +#define rPMGR_WDOG_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x302C)) + +#define rPMGR_EVENT_TMR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3100)) +#define rPMGR_EVENT_PERIOD (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3104)) +#define rPMGR_EVENT_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3108)) + +#define rPMGR_PERF_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4000)) +#define rPMGR_PERF_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4004)) +#define rPMGR_PERF_CTR0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4020)) +#define rPMGR_PERF_CTR0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4024)) +#define rPMGR_PERF_CFG0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4028)) +#define rPMGR_PERF_CFG0_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x402C)) +#define rPMGR_PERF_CFG0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4030)) +#define rPMGR_PERF_CFG0_HI2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4034)) +#define rPMGR_PERF_CTR1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4040)) +#define rPMGR_PERF_CTR1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4044)) +#define rPMGR_PERF_CFG1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4048)) +#define rPMGR_PERF_CFG1_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x404C)) +#define rPMGR_PERF_CFG1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4050)) +#define rPMGR_PERF_CFG1_HI2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4054)) + +#define rPMGR_SCRATCH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6000)) +#define rPMGR_SCRATCH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6004)) // Used: iBoot->pmgr +#define rPMGR_SCRATCH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6008)) +#define rPMGR_SCRATCH3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x600C)) +#define rPMGR_SCRATCH4 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6010)) +#define rPMGR_SCRATCH5 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6014)) +#define rPMGR_SCRATCH6 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6018)) +#define rPMGR_SCRATCH7 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x601C)) +#define rPMGR_SCRATCH8 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6020)) +#define rPMGR_SCRATCH9 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6024)) +#define rPMGR_SCRATCH10 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6028)) +#define rPMGR_SCRATCH11 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x602C)) +#define rPMGR_SCRATCH12 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6030)) +#define rPMGR_SCRATCH13 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6034)) +#define rPMGR_SCRATCH14 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6038)) +#define rPMGR_SCRATCH15 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x603C)) + +#define rPMGR_DAC_FS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x7000)) + +#define rPMGR_USB_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x8000)) + +#define rPMGR_USB1_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x9000)) + +#define rPMGR_SHA_SEL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xA000)) + +#define rPMGR_SECURITY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xB000)) + +#define rPMGR_GFX_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC000)) + +#define rPMGR_THERMAL_CTL0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xD000)) +#define rPMGR_THERMAL_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xD004)) +#define rPMGR_THERMAL_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xD008)) +#define rPMGR_THERMAL_RDBK (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xD00C)) +#define rPMGR_THERMAL_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xD010)) +#define rPMGR_THERMAL_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xD014)) + +#define PGMR_GET_PERF_STATE_INDEX(_n, _x) (((_x) >> ((_n) * 4)) & 0xF) +#define PGMR_SET_PERF_STATE_INDEX(_n, _i) (((_i) & 0xF) << ((_n) * 4)) +#define PMGR_PERF_STATE_V(_n) (_n) +#define PMGR_PERF_STATE_P (3) +#define PMGR_PERF_STATE_M(_n) (4 + (_n)) + +/* This defines the order of clocks in AppleS5L8945XIO.cpp; keep the table there + * in synch with this one. + */ +enum { + PMGR_CLK_OSC = 0, // 0x00 - OSC + PMGR_CLK_PLL0, // 0x01 - PLL0 + PMGR_CLK_PLL1, // 0x02 - PLL1 + PMGR_CLK_PLL2, // 0x03 - PLL2 + PMGR_CLK_PLL3, // 0x04 - PLL3 + PMGR_CLK_PLL4, // 0x05 - PLL4 + PMGR_CLK_PLL5, // 0x06 - PLL5 + PMGR_CLK_PLLUSB, // 0x07 - PLLUSB + PMGR_CLK_DOUBLER, // 0x08 - DOUBLER + PMGR_CLK_CPU, // 0x09 - CPU + PMGR_CLK_MEM, // 0x0A - MEM + PMGR_CLK_PIO, // 0x0B - PIO + PMGR_CLK_ACP, // 0x0C - ACP + PMGR_CLK_MCU_FIXED, // 0x0D - MCU_FIXED + PMGR_CLK_MCU, // 0x0E - MCU + PMGR_CLK_PREDIV0, // 0x0F - PREDIV0 + PMGR_CLK_PREDIV1, // 0x10 - PREDIV1 + PMGR_CLK_PREDIV2, // 0x11 - PREDIV2 + PMGR_CLK_PREDIV3, // 0x12 - PREDIV3 + PMGR_CLK_PREDIV4, // 0x13 - PREDIV4 + PMGR_CLK_PREDIV5, // 0x14 - PREDIV5 + PMGR_CLK_PREDIV6, // 0x15 - PREDIV6 + PMGR_CLK_MANAGED0, // 0x16 - MANAGED0 + PMGR_CLK_MANAGED1, // 0x17 - MANAGED1 + PMGR_CLK_MANAGED2, // 0x18 - MANAGED2 + PMGR_CLK_MANAGED3, // 0x19 - MANAGED3 + PMGR_CLK_MANAGED4, // 0x1A - MANAGED4 + PMGR_CLK_MANAGED5, // 0x1B - MANAGED5 + PMGR_CLK_AES_CORE, // 0x1C - AES_CORE + PMGR_CLK_MEDIUM0, // 0x1D - MEDIUM0 + PMGR_CLK_MEDIUM1, // 0x1E - MEDIUM1 + PMGR_CLK_VID0, // 0x1F - VID0 + PMGR_CLK_VID1, // 0x20 - VID1 + PMGR_CLK_I2C, // 0x21 - I2C + PMGR_CLK_SDIO, // 0x22 - SDIO + PMGR_CLK_AUDIO, // 0x23 - AUDIO + PMGR_CLK_HPARK_PCLK, // 0x24 - HPARK_PCLK + PMGR_CLK_HPARK_TCLK, // 0x25 - HPARK_TCLK + PMGR_CLK_UPERF, // 0x26 - UPERF + PMGR_CLK_DEBUG, // 0x27 - DEBUG + PMGR_CLK_HPERFRT, // 0x28 - HPERFRT + PMGR_CLK_GFX, // 0x29 - GFX + PMGR_CLK_GFX_SLC, // 0x2A - GFX_SLC + PMGR_CLK_HPERFNRT, // 0x2B - HPERFNRT + PMGR_CLK_ISP, // 0x2C - ISP + PMGR_CLK_IOP, // 0x2D - IOP + PMGR_CLK_CDIO, // 0x2E - CDIO + PMGR_CLK_LPERFS, // 0x2F - LPERFS + PMGR_CLK_PCLK0, // 0x30 - PCLK0 + PMGR_CLK_PCLK1, // 0x31 - PCLK1 + PMGR_CLK_PCLK2, // 0x32 - PCLK2 + PMGR_CLK_PCLK3, // 0x33 - PCLK3 + PMGR_CLK_SPI0, // 0x34 - SPI0 + PMGR_CLK_SPI1, // 0x35 - SPI1 + PMGR_CLK_SPI2, // 0x36 - SPI2 + PMGR_CLK_SPI3, // 0x37 - SPI3 + PMGR_CLK_SPI4, // 0x38 - SPI4 + PMGR_CLK_SLOW, // 0x39 - SLOW + PMGR_CLK_SLEEP, // 0x3A - SLEEP + PMGR_CLK_USBPHY, // 0x3B - USBPHY + PMGR_CLK_USBPHY1, // 0x3C - USBPHY1 + PMGR_CLK_USBOHCI, // 0x3D - USBOHCI + PMGR_CLK_USB12, // 0x3E - USB12 + PMGR_CLK_NCO_REF0, // 0x3F - NCO_REF0 + PMGR_CLK_NCO_REF1, // 0x40 - NCO_REF1 + PMGR_CLK_NCO_REF2, // 0x41 - NCO_REF2 + PMGR_CLK_VENC_MTX, // 0x42 - VENC_MTX + PMGR_CLK_VENC, // 0x43 - VENC + PMGR_CLK_SLV_BUS, // 0x44 - SLV_BUS + PMGR_CLK_COUNT +}; + +extern void pmgr_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/s5l8945x/include/platform/trampoline.h b/platform/s5l8945x/include/platform/trampoline.h new file mode 100644 index 0000000..6ee19d6 --- /dev/null +++ b/platform/s5l8945x/include/platform/trampoline.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include +#include + +#define SECURITY_REG (PMGR_BASE_ADDR + 0xB000) +#define ROM_READ_DISABLE (1 << 0) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s5l8945x/include/platform/usbconfig.h b/platform/s5l8945x/include/platform/usbconfig.h new file mode 100644 index 0000000..6c1a8e2 --- /dev/null +++ b/platform/s5l8945x/include/platform/usbconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#define USBPHY_CLK_TYPE (3) /* Use CLKCORE */ + +#define USBPHY_UVLDCON_VALUE (2) + +#define USBPHY_UOTGTUNE1 (0x349) +#define USBPHY_UOTGTUNE2 (0x733) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR8) + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s5l8945x/init.c b/platform/s5l8945x/init.c new file mode 100644 index 0000000..8ceca15 --- /dev/null +++ b/platform/s5l8945x/init.c @@ -0,0 +1,1229 @@ +/* + * Copyright (C) 2010-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_EFFACEABLE_NOR +#include +#endif + +extern void dma_init(void); + +static void platform_init_boot_strap(void); + +static uint8_t boot_debug; + +int platform_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + /* Verify that the fuses and that the SecureROM has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile u_int32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled"); + } +#endif + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8945x pmgr driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); +#if !RELEASE_BUILD && (PRODUCT_IBSS || PRODUCT_IBEC) + debug_enable_uarts(3); +#endif +#endif +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_HW_DMA + /* initialize the dma engine */ + dma_init(); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + return 0; +} + + +int platform_late_init(void) +{ +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_NAND + flash_nand_id(); +#endif + + return 0; +} + + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); + + /* always remap the memory region at this point, regardless of resume, + * because the early MMU init always runs and we have to fix up. */ + platform_init_mainmem_map(); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +#if APPLICATION_IBOOT + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, kARMMMUNormal, true, true); +#endif +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +static bool gDisplayEnabled; + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { + if (!displayInitOnce) { + platform_quiesce_display(); + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + + power_backlight_enable(backlight_level); +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + u_int32_t base_rounded = *base; + u_int32_t end_rounded = *base + *size; + u_int32_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + arm_mmu_map_section_range(base_rounded, base_rounded, size_rounded/MB, kARMMMUWriteCombined, false, true); + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_NAND_FILESYSTEM + flash_nand_init(); +#endif + + return 0; +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + + /* quiesce the panel */ + if (display_quiesce(true) == ENXIO) { + clock_gate(CLK_HPERFRT, false); + clock_gate(CLK_DISPOUT, false); + } +#endif + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + u_int32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + platform_quiesce_display(); + case BOOT_DARWIN: + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + ; // do nothing + } + + /* if we left the fuse unlocked for boot image processing, + * lock it now, after optionally switching from production to + * development fusing. */ + if (security_get_production_override()) + chipid_clear_production_mode(); + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + + /* mark usable ram as cached/buffered */ + arm_mmu_map_section_range(SRAM_BASE, SRAM_BASE, ROUNDUP(SRAM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#if APPLICATION_SECUREROM + arm_mmu_map_section_range(VROM_BASE, VROM_BASE, ROUNDUP(VROM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#endif + + /* Remap text base is to zero (for exception vectors) */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUNormalRX, false); + +#ifdef MMU_NONCACHE0_SIZE + /* create the noncached0 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE0_VBASE, MMU_NONCACHE0_PBASE, ROUNDUP(MMU_NONCACHE0_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + +#ifdef MMU_NONCACHE1_SIZE + /* create the noncached1 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE1_VBASE, MMU_NONCACHE1_PBASE, ROUNDUP(MMU_NONCACHE1_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + + /* in cases where we are running from DRAM, remap it now */ + if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) { + platform_init_mainmem_map(); + } +} + +int platform_init(void) +{ +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_NAND_BOOT + nand_boot_init(); +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + +#if WITH_EFFACEABLE_NOR + effaceable_nor_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + u_int32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER + boot_set_stage(kPowerNVRAMiBootStageOff); + + power_shutdown(); +#endif + for(;;); +} + +u_int32_t platform_set_performance(u_int32_t performance_level) +{ + u_int32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + u_int32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_CPU); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_MEM); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_BUS); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_PERIPH); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_FIXED); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_TIMEBASE); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(u_int32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_NAND_FILESYSTEM + if (FindNode(0, "arm-io/flash-controller0/disk", &node)) { + fillNandConfigProperties(node); + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl0", &node)) { + usbphy_update_device_tree(node); + } +#endif + + return target_update_device_tree(); +} + +#endif + +static void platform_init_boot_strap(void) +{ + u_int32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG3, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG3) << 3) | + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +u_int32_t platform_get_board_id(void) +{ + u_int32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +u_int32_t platform_get_boot_config(void) +{ + u_int32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, u_int32_t *boot_flag, u_int32_t *boot_arg) +{ + u_int32_t boot_config = platform_get_boot_config(); + + /* S5L8945X supports one boot device then USB-DFU per boot config */ + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case 0: /* SPI 0 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 1: /* SPI 3 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 3; + break; + + case 2: /* SPI 0 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case 3: /* SPI 3 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 3; + break; + + case 4: /* FMI0 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 0; + break; + + case 5: /* FMI0 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 0; + break; + + case 6: /* FMI0 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 0; + break; + +/* case 7: Unused */ + + case 8: /* FMI1 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 8; + break; + + case 9: /* FMI1 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 8; + break; + + case 10: /* FMI1 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 8; + break; + +/* case 11: Unused */ + + case 12: /* FMI0/1 2/2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (2 << 8) | (2 << 0); + break; + + case 13: /* FMI0/1 4/4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (4 << 8) | (4 << 0); + break; + + case 14: /* FMI0/1 4/4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = (4 << 8) | (4 << 0); + break; + +/* case 15: Unused */ + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == 1) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + u_int32_t enable; + u_int32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO( 1, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO( 1, 3), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO( 1, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO( 1, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO( 1, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; + +static const struct boot_interface_pin spi3_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(19, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_SSIN +#else + { GPIO(19, 5), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI3_SSIN +#endif + { GPIO(19, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_SCLK + { GPIO(19, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_MOSI + { GPIO(19, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI3_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND +/* Note: The code below expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi0_boot_interface_pins[] = +{ + { GPIO(23, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN3 + { GPIO(23, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN2 + { GPIO(23, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN1 + { GPIO(23, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN0 + { GPIO(23, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CLE + { GPIO(23, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_ALE + { GPIO(22, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_REN + { GPIO(23, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_WEN + { GPIO(22, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO0 + { GPIO(22, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO1 + { GPIO(22, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO2 + { GPIO(22, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO3 + { GPIO(22, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO4 + { GPIO(22, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO5 + { GPIO(21, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO6 + { GPIO(21, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI0_IO7 +}; + +/* Note: The code below expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi1_boot_interface_pins[] = +{ + { GPIO(25, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN3 + { GPIO(25, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN2 + { GPIO(25, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN1 + { GPIO(25, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN0 + { GPIO(25, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CLE + { GPIO(25, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_ALE + { GPIO(25, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_REN + { GPIO(25, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_WEN + { GPIO(24, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO0 + { GPIO(24, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO1 + { GPIO(24, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO2 + { GPIO(24, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO3 + { GPIO(24, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO4 + { GPIO(24, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO5 + { GPIO(24, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO6 + { GPIO(23, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI1_IO7 +}; +#endif /* WITH_HW_BOOTROM_NAND */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, u_int32_t boot_arg) +{ + const struct boot_interface_pin *pins0 = 0; + const struct boot_interface_pin *pins1 = 0; + u_int32_t cnt, func, pin_count0 = 0, pin_count1 = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins0 = spi0_boot_interface_pins; + pin_count0 = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } else if (boot_arg == 3) { + pins0 = spi3_boot_interface_pins; + pin_count0 = (sizeof(spi3_boot_interface_pins) / sizeof(spi3_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND + case BOOT_DEVICE_NAND : + pins0 = fmi0_boot_interface_pins; + pin_count0 = (sizeof(fmi0_boot_interface_pins) / sizeof(fmi0_boot_interface_pins[0])); + switch ((boot_arg >> 0) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins0 += 2; + pin_count0 -= 2; + break; + + default: + pins0 = 0; + pin_count0 = 0; + break; + } + + pins1 = fmi1_boot_interface_pins; + pin_count1 = (sizeof(fmi1_boot_interface_pins) / sizeof(fmi1_boot_interface_pins[0])); + switch ((boot_arg >> 8) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins1 += 2; + pin_count1 -= 2; + break; + + default: + pins1 = 0; + pin_count1 = 0; + break; + } + break; +#endif /* WITH_HW_BOOTROM_NAND */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count0; cnt++) { + if (enable) { + pin = pins0[pin_count0 - 1 - cnt].pin; + func = pins0[pin_count0 - 1 - cnt].enable; + } else { + pin = pins0[cnt].pin; + func = pins0[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } + + for (cnt = 0; cnt < pin_count1; cnt++) { + if (enable) { + pin = pins1[pin_count1 - 1 - cnt].pin; + func = pins1[pin_count1 - 1 - cnt].enable; + } else { + pin = pins1[cnt].pin; + func = pins1[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 1 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +u_int64_t platform_get_nonce(void) +{ + u_int64_t nonce; + u_int32_t *nonce_words = (u_int32_t *)&nonce; + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return chipid_get_ecid_image_personalization_required(); +} + +u_int32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +// Let the target's rules.mk override the high core voltage point +#ifndef TARGET_HIGH_SOC_VOLTAGE +#define TARGET_HIGH_SOC_VOLTAGE CHIPID_SOC_VOLTAGE_HIGH +#endif + +u_int32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_HIGH_SOC_VOLTAGE); +} + +// Let the target's rules.mk override the high cpu voltage point +#ifndef TARGET_HIGH_CPU_VOLTAGE +#define TARGET_HIGH_CPU_VOLTAGE CHIPID_CPU_VOLTAGE_HIGH +#endif + +u_int32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_HIGH_CPU_VOLTAGE); +} + +static const u_int32_t soc_voltage_points[] = { + CHIPID_SOC_VOLTAGE_MED, + TARGET_HIGH_SOC_VOLTAGE +}; + +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(soc_voltage_points) / sizeof(soc_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_soc_voltage(soc_voltage_points[cnt]); + } + + return 0; +} + +static const u_int32_t cpu_voltage_points[] = { + CHIPID_CPU_VOLTAGE_MED, + TARGET_HIGH_CPU_VOLTAGE +}; + +int platform_get_cpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(cpu_voltage_points) / sizeof(cpu_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cpu_voltage_points[cnt]); + } + + return 0; +} + +int platform_convert_voltages(int buck, u_int32_t count, u_int32_t *voltages) +{ +#if WITH_HW_POWER + u_int32_t index; + + if (voltages == 0) return -1; + + for (index = 0; index < count; index++) { + if (0 != power_get_buck_value(buck, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ +#if SUPPORT_FPGA + return !gpio_read(GPIO_FORCE_DFU); +#else + return gpio_read(GPIO_FORCE_DFU); +#endif +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(u_int32_t key_selector, u_int32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +#if APPLICATION_IBOOT +u_int64_t platform_get_memory_size(void) +{ + u_int64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (rPMGR_SCRATCH13 & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +u_int8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 28) & 0xf); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info(u_int8_t manuf_id, u_int64_t memory_size) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 28) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +#endif diff --git a/platform/s5l8945x/iop_init.c b/platform/s5l8945x/iop_init.c new file mode 100644 index 0000000..e167d81 --- /dev/null +++ b/platform/s5l8945x/iop_init.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Platform memory layout. + * + * The IOP sees SDRAM at its physical location uncached, and has an cached aperture + * visible elsewhere. SDRAM size of up to 1GB is currently supported. + * SRAM is not visible/legally usable. + * + * For some platforms/targets, SDRAM_LEN is not constant and so we + * have to compute a maximum via other means. + * + * Note that the AE2 Sparrow shares this code. + */ +#define MEM_CACHED_BASE (SDRAM_BASE | 0xc0000000) +#define SDRAM_MAX_LEN (SDRAM_BANK_LEN * SDRAM_BANK_COUNT) +struct mem_static_map_entry mem_static_map_entries[] = { + { + MEM_CACHED_BASE, /* cached */ + SDRAM_BASE, /* uncached */ + SDRAM_BASE, /* physical */ + SDRAM_MAX_LEN /* length */ + }, + {MAP_NO_ENTRY, MAP_NO_ENTRY, MAP_NO_ENTRY, 0} +}; + +void platform_mmu_setup(bool resume) +{ + if (false == resume) { + /* Remap text base to zero, outer uncacheable, shared */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUInnerNormalOuterNoncached, true); +#if MAP_SRAM_CACHED + /* Map the SRAM as cacheable, shared */ + arm_mmu_map_section(SRAM_BASE, SRAM_BASE, kARMMMUNormal, true); +#endif // MAP_SRAM_CACHED + /* Remap all of SDRAM through the cacheable aperture, outer uncacheable, shared */ + arm_mmu_map_section_range(MEM_CACHED_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUInnerNormalOuterNoncached, true, false); + /* Remap all of SDRAM through the uncacheable aperture (existing mappings should be there, but be sure) */ + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUStronglyOrdered, false, false); + } +} + +bool platform_get_production_mode(void) +{ + return(true); +} + +bool platform_get_secure_mode(void) +{ + return(true); +} + +void platform_reset(bool panic) +{ + for (;;) + ; +} + +/* + * Early init is done every time the IOP starts. + */ +int +platform_early_init() +{ +#if PLATFORM_VARIANT_IOP + /* In general we want power-gating to be disabled. */ + rPMGR_PWR_GATE_CTL_CLR = rPMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & rPMGR_PWR_GATE_IOP) ; +#endif + + interrupt_init(); + + timer_init(0); + + return(0); +} + +/* + * Halt waiting for an interrupt. + */ +void +platform_halt(void) +{ + arch_halt(); +} + +#if SUPPORT_SLEEP + +#if WITH_IOP_POWER_GATING + +/* + * Deep idle sleep with power gating + */ +void +platform_deep_idle(void) +{ + rPMGR_PWR_GATE_CTL_SET = rPMGR_PWR_GATE_IOP; + while (!(rPMGR_PWR_GATE_CTL_SET & rPMGR_PWR_GATE_IOP)) ; + a5iop_sleep(1); + rPMGR_PWR_GATE_CTL_CLR = rPMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & rPMGR_PWR_GATE_IOP) ; +} + +#endif + +void +platform_sleep(void) +{ + /* We assume power-gating is disabled, which it need to be so + * the IOP wrapper registers don't disappear. */ + a5iop_sleep(0); +} + +#endif + +/* + * Cache control + */ +void +platform_cache_operation(int operation, void *address, u_int32_t length) +{ + a5iop_cache_operation(operation, address, length); +} + +/* + * Host doorbell uses a SWI in the AIC. + */ +static void (* _doorbell_handler)(void *arg); +static void +platform_doorbell_handler(void *arg) +{ + /* clear the doorbell before passing up */ + interrupt_clear_ipc(INT_IOP); + _doorbell_handler(arg); +} + +void +platform_init_iop_doorbell(void (* handler)(void *arg), void *arg) +{ + _doorbell_handler = handler; + install_int_handler(INT_IOP, platform_doorbell_handler, arg); + set_int_type(INT_IOP, INT_TYPE_IRQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP); +} + +void +platform_mask_doorbell(void) +{ + mask_int(INT_IOP); +} + +void +platform_unmask_doorbell(void) +{ + unmask_int(INT_IOP); +} + +void +platform_ring_host_doorbell(void) +{ + interrupt_generate_ipc(INT_HOST); +} + +int +platform_init_nmi(void (*handler)(void *arg), void *arg) +{ +#ifdef INT_IOP_NMI + install_int_handler(INT_IOP_NMI, handler, arg); + set_int_type(INT_IOP_NMI, INT_TYPE_FIQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP_NMI); +#endif + + return(0); +} + +/* + * Clock management. + * + * Currently the IOP does none for this platform. + */ +void clock_gate(int device, bool enable) +{ +} diff --git a/platform/s5l8945x/miu/miu.c b/platform/s5l8945x/miu/miu.c new file mode 100644 index 0000000..9744fda --- /dev/null +++ b/platform/s5l8945x/miu/miu.c @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void miu_configure_bridge(const u_int32_t *bridge_settings); + +#define BRIDGE_SHIFT (16) +#define BRIDGE_MASK (0xFFFF) +#define NRT_DART_WIDGETS (0 << BRIDGE_SHIFT) +#define NRT_DART_BRIDGE (1 << BRIDGE_SHIFT) +#define NRT_TOP_WIDGETS (2 << BRIDGE_SHIFT) +#define NRT_TOP_BRIDGE (3 << BRIDGE_SHIFT) +#define RT_TOP_WIDGETS (4 << BRIDGE_SHIFT) +#define RT_TOP_BRIDGE (5 << BRIDGE_SHIFT) +#define UPERF_WIDGETS (6 << BRIDGE_SHIFT) +#define UPERF_BRIDGE (7 << BRIDGE_SHIFT) +#define CDIO_WIDGETS (8 << BRIDGE_SHIFT) +#define CDIO_BRIDGE (9 << BRIDGE_SHIFT) +#define UPERF1_WIDGETS (10 << BRIDGE_SHIFT) +#define UPERF1_BRIDGE (11 << BRIDGE_SHIFT) + +static const u_int32_t bridge_registers[] = { + NRT_DART_WIDGETS_BASE_ADDR, NRT_DART_PL301_BASE_ADDR, + NRT_TOP_WIDGETS_BASE_ADDR, NRT_TOP_PL301_BASE_ADDR, + RT_TOP_WIDGETS_BASE_ADDR, RT_TOP_PL301_BASE_ADDR, + UPERF_WIDGETS_BASE_ADDR, UPERF_PL301_BASE_ADDR, + CDIO_WIDGETS_BASE_ADDR, CDIO_PL301_BASE_ADDR, + UPERF1_WIDGETS_BASE_ADDR, UPERF1_PL301_BASE_ADDR, +}; + +// The following settings are based on H4 Tunables Revision 0.24 + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static const u_int32_t bridge_settings_static[] = { + // Configure recommended transaction limits in CDIO + CDIO_WIDGETS | CDIO_IOP_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_IOP_WTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_CDMA_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_CDMA_WTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_UPERF_RTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_UPERF_WTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_AUDIO_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_AUDIO_WTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_PIO_RTLIMIT, 0x00000808, + CDIO_WIDGETS | CDIO_PIO_WTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_UPERF1_RTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_UPERF1_WTLIMIT, 0x00000404, + + // Configure recommended bridge settings in CDIO + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x01000001, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x02000002, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x03000003, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x04000004, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x05000005, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x01000001, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x02000002, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x03000003, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x04000004, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x05000005, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x00000000, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x01000001, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x02000002, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x03000003, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x04000004, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x05000005, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x01000001, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x02000002, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x03000003, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x04000004, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x05000005, + + // Configure recommended features in CDIO + CDIO_WIDGETS | CDIO_IOP_WREQSP, 0x00000003, + CDIO_WIDGETS | CDIO_CDMA_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_UPERF_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_AUDIO_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_UPERF1_WGATHER, 0x00000100, + + // Configure recommended traffic attributes in UPERF + // AxCACHE = Cacheable + // AxUSER = enable Shared bit + UPERF_WIDGETS | UPERF_OTG_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OTG_CACHE, 0x01020102, + UPERF_WIDGETS | UPERF_EHCI_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_EHCI_CACHE, 0x01020102, + UPERF_WIDGETS | UPERF_OHCI0_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI0_CACHE, 0x01020102, + UPERF_WIDGETS | UPERF_OHCI1_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI1_CACHE, 0x01020102, + + UPERF1_WIDGETS | UPERF_OTG_QOS, 0x01010101, + UPERF1_WIDGETS | UPERF_OTG_CACHE, 0x01020102, + UPERF1_WIDGETS | UPERF_EHCI_QOS, 0x01010101, + UPERF1_WIDGETS | UPERF_EHCI_CACHE, 0x01020102, + UPERF1_WIDGETS | UPERF_OHCI0_QOS, 0x01010101, + UPERF1_WIDGETS | UPERF_OHCI0_CACHE, 0x01020102, + UPERF1_WIDGETS | UPERF_OHCI1_QOS, 0x01010101, + UPERF1_WIDGETS | UPERF_OHCI1_CACHE, 0x01020102, + + 0, 0, + 0, 0 +}; +#endif // APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +#if WITH_DEVICETREE || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static const u_int32_t bridge_settings_dynamic[] = { + // Configure recommended transaction limits in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_RTLIMIT, 0x00000808, + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_WTLIMIT, 0x00000808, + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x02000102, // Scaler0 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x03000103, // Sclaer1 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x02000102, // Scaler0 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x03000103, // Sclaer1 Reduced Priority + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_QOS, 0x01010101, // JPEG0 LLT Traffic for R&W + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_QOS, 0x01010101, // JPEG0 LLT Traffic for R&W + 0, 0, + + // Configure recommended transaction limits in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_RTLIMIT, 0x00002020, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_WTLIMIT, 0x00000808, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_RTLIMIT, 0x00001010, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_WTLIMIT, 0x00000808, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_WTLIMIT, 0x00000F0F, + + // Configure recommended bridge settings in HPerf-NRT Top + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x03000003, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x03000003, + + // Configure recommended features in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_DART_WGATHER, 0x00000000, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_WREQSP, 0x00000003, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_WREQSP, 0x00000003, + 0, 0, + + // Configure recommended transaction limits in HPerf-RT Top + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_WTLIMIT, 0x00000F0F, + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP0_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP1_RTLIMIT, 0x00001818, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_RTLIMIT, 0x00000C0C, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_WTLIMIT, 0x00001010, + + // Configure recommended bridge settings in HPerf-RT Top + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x00000000, + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x01000001, + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x02000002, + 0, 0, + + 0, 0 +}; +#endif // WITH_DEVICETREE || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif + +#if APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC + // Configure recommended transaction limits in CIF + rCIF_RTLIMIT = 0x00000808; + rCIF_WTLIMIT = 0x00000808; + + // Tunables recommendation, for SCU clock-gating + // (will change to 0x80 for ) + rCIF_IDLETMR = 0x00000010; +#endif + + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Configure bridges that are statically powered + clock_gate(CLK_UPERF, true); + clock_gate(CLK_UPERF1, true); + miu_configure_bridge(bridge_settings_static); + clock_gate(CLK_UPERF1, false); + clock_gate(CLK_UPERF, false); +#endif + +#if APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC + // Configure bridges that are dynamically powered + clock_gate(CLK_HPERFNRT, true); + clock_gate(CLK_HPERFRT, true); + miu_configure_bridge(bridge_settings_dynamic); + clock_gate(CLK_HPERFNRT, false); + clock_gate(CLK_HPERFRT, false); + + /* Enable the SCU. Note that we explicitly do NOT touch the + * "power status" register, since the default is supposed to + * be correct, and the real control is in the CPU's "SMP" + * bit. */ + rSCU_TAG_INVAL = 0xff; /* invalidate SCU tags for all CPUs */ + + /* Enable SCU, standby, speculative linefills, and parity */ + rSCU_CONTROL = (1 << 5) | (1 << 3) | (1 << 2) | (1 << 0); +#endif + + /* remap whatever bank of ram we're in to zero */ + if (TEXT_BASE == SRAM_BASE) + miu_select_remap(REMAP_SRAM); + else if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) + miu_select_remap(REMAP_SDRAM); + + return 0; +} + +static void miu_configure_bridge(const u_int32_t *bridge_settings) +{ + volatile u_int32_t *reg; + u_int32_t cnt = 0, bridge, offset, data; + + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + bridge = bridge_settings[cnt] >> BRIDGE_SHIFT; + offset = bridge_settings[cnt] & BRIDGE_MASK; + data = bridge_settings[cnt + 1]; + reg = (volatile u_int32_t *)(bridge_registers[bridge] + offset); + *reg = data; + cnt += 2; + } + cnt += 2; + } +} + +void miu_suspend(void) +{ + /* XXX ? */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rREMAP_CTL = (rREMAP_CTL & ~3) | (1 << 0); // remap_sel = 1 + rPL310_FILTER_START = 0x1; + break; + case REMAP_SDRAM: + rREMAP_CTL = (rREMAP_CTL & ~3) | (2 << 0); // remap_sel = 2 + // Leave low megabyte heading to DRAM for wake-from-sleep, + // Otherwise send everything below DRAM to the PIO block. + // Currently this is for testing only; it is not POR. + rPL310_FILTER_END = 0x80000000; + rPL310_FILTER_START = 0x00100001; + break; + } + + /* read remap register to ensure it has been updated */ + rREMAP_CTL; +} + +void miu_bypass_prep(void) +{ +#if APPLICATION_IBOOT + extern void mcu_bypass_prep(void); + mcu_bypass_prep(); +#endif +} + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + + // Fill in the bridge-settings property + propName = "bridge-settings"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(bridge_settings_dynamic)) { + memcpy(propData, bridge_settings_dynamic, sizeof(bridge_settings_dynamic)); + } + } +} + +#endif diff --git a/platform/s5l8945x/miu/rules.mk b/platform/s5l8945x/miu/rules.mk new file mode 100644 index 0000000..8849cfe --- /dev/null +++ b/platform/s5l8945x/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s5l8945x/pmgr/pmgr.c b/platform/s5l8945x/pmgr/pmgr.c new file mode 100644 index 0000000..6f736b7 --- /dev/null +++ b/platform/s5l8945x/pmgr/pmgr.c @@ -0,0 +1,1087 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !APPLICATION_EMBEDDEDIOP + +#define PLL_VCO_TARGET(pllx) (2ULL * pllx##_O * pllx##_M / pllx##_P) +#define PLL_FREQ_TARGET(pllx) (2ULL * pllx##_O * pllx##_M / pllx##_P / (1 << pllx##_S)) + +static u_int32_t clk_divs_bypass[PMGR_CLK_CFG_COUNT] = { + 0x80008421, 0x80000000, 0x80000000, 0x80000001, // cpu, mcu_fixed, mcu, pclk1 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // prediv0, prediv1, prediv2, prediv3 + 0x80000001, 0x80000001, 0x80000001, 0x80000000, // prediv4, prediv5, prediv6, managed0 + 0x80000000, 0x80000000, 0x80000000, 0x80000000, // managed1, managed2, managed3, managed4 + 0x80000000, 0x80000000, 0x80000001, 0x80000001, // managed5, aes_core, vid1, medium0 + 0x80000001, 0xB0000001, 0x80000001, 0x80000001, // vid0, i2c, sdio, audio + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // hpark_pclk0, hpark_tclk, uperf, debug + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // hperf_rt, gfx, gfx_slc, hperf_nrt + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // isp, iop, cdio, lperfs, + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // pclk0, pclk2, pclk3, medium1 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // spi0, spi1, spi2, spi3, + 0x80000001, 0x80000021, 0x80000001, 0x80000001, // spi4, sleep, usbphy, usbphy1 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // usbohci, usb12, nco_ref0, nco_ref1 + 0x80000001, 0x80000001, 0x80000000, 0x80000001, // nco_ref2, venc_mtx, venc, slv_bus +}; + +static u_int32_t perf_state_bypass[3] = { + 0x01010101, 0x03010101, 0x00010101, // defaults, slow mcu_cfg +}; +struct perf_info { + u_int8_t perf_state; + u_int8_t perf_div; +}; + +#if APPLICATION_IBOOT + +#ifndef TARGET_PREDIV6_DIV +#define TARGET_PREDIV6_DIV 5 +#endif + +#ifndef TARGET_VID0_DIV +#define TARGET_VID0_DIV 1 +#endif + +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 6 +#define PLL0_M 250 +#define PLL0_S 1 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 6 +#define PLL1_M 200 +#define PLL1_S 1 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 6 +#define PLL2_M 200 +#define PLL2_S 2 +#define PLL2_V PLL_VCO_TARGET(PLL2) +#define PLL2_T PLL_FREQ_TARGET(PLL2) + +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 4 +#define PLL3_M 171 +#define PLL3_S 1 +#define PLL3_V PLL_VCO_TARGET(PLL3) +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +// PLL4 not used on H4G + +#define PLL5 5 +#define PLL5_O OSC_FREQ +#define PLL5_P 4 +#define PLL5_M 100 +#define PLL5_S 1 +#define PLL5_V PLL_VCO_TARGET(PLL5) +#define PLL5_T PLL_FREQ_TARGET(PLL5) + +#define PLLUSB 6 +#define PLLUSB_O OSC_FREQ +#define PLLUSB_P 4 +#define PLLUSB_M 160 +#define PLLUSB_S 2 +#define PLLUSB_V PLL_VCO_TARGET(PLLUSB) +#define PLLUSB_T PLL_FREQ_TARGET(PLLUSB) + +#define D_PREDIV6 (0xA0000000 | TARGET_PREDIV6_DIV) +#define D_VID0 (0xB0000000 | TARGET_VID0_DIV) + +static u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x90011041, 0x80000001, 0x80000001, 0x90000002, // cpu, mcu_fixed, mcu, pclk1 + 0xA0000005, 0xA0000002, 0xA0000003, 0x00000000, // prediv0, prediv1, prediv2, prediv3 + 0x90000001, 0x00000000, D_PREDIV6, 0x80000000, // prediv4, prediv5, prediv6, managed0 + 0x00000000, 0x80000000, 0x80000000, 0x80000000, // managed1, managed2, managed3, managed4 + 0x80000000, 0x80000000, 0xA0000013, 0x80000004, // managed5, aes_core, vid1, medium0 + D_VID0, 0x80000008, 0x80000004, 0xA0000002, // vid0, i2c, sdio, audio + 0x90000004, 0xA0000002, 0xA0000007, 0x80000008, // hpark_pclk0, hpark_tclk, uperf, debug + 0xB0000001, 0x80000001, 0xB0000001, 0xA0000001, // hperf_rt, gfx, gfx_slc, hperf_nrt + 0xA0000001, 0xB0000001, 0xB0000001, 0xB0000002, // isp, iop, cdio, lperfs + 0x80000001, 0x80000001, 0x80000001, 0x8000000A, // pclk0, pclk2, pclk3, medium1 + 0xB0000001, 0xB0000001, 0x80000001, 0xB0000001, // spi0, spi1, spi2, spi3 + 0xB0000001, 0x80000314, 0x80000001, 0x80000001, // spi4, sleep, usbphy, usbphy1 + 0x80000001, 0x80000002, 0xA0000001, 0xB0000001, // usbohci, usb12, nco_ref0, nco_ref1 + 0x00000000, 0xA0000002, 0x80000002, 0xA0000002 // nco_ref2, venc_mtx, venc, slv_bus +}; + +#define PLL_GATES_ACTIVE (0) + +static struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kPERF_STATE_IBOOT+0, 1 }, + [kPerformanceMedium] = { kPERF_STATE_IBOOT+1, 2 }, + [kPerformanceLow] = { kPERF_STATE_IBOOT+2, 4 }, + [kPerformanceMemory] = { kPERF_STATE_IBOOT+4, 4 }, +}; + +#define PERF_STATE_ACTIVE kPERF_STATE_IBOOT +#if SUPPORT_FPGA +// mcu_cfg=3, mcu_clk and mcu_fixed_clk always divide by 1 +static u_int32_t perf_state_active[kPERF_STATE_IBOOT_CNT*3] = { + 0x01010022, 0x03210142, 0x00214142, // divide by 1 + 0x02010023, 0x03210143, 0x00214142, // divide by 2 + 0x04010023, 0x03210143, 0x00214142, // divide by 4 + 0x1f010023, 0x03210143, 0x00214142, // DPSM divider + 0x04010023, 0x03210143, 0x00214142, // divide by 4 +}; +#else +// For rdar://9188170 : we must avoid MCU clock transitions. Lock the MCU to max speed. +static u_int32_t perf_state_active[kPERF_STATE_IBOOT_CNT*3] = { + 0x01010022, 0x00210142, 0x00214142, // divide by 1, mcu_cfg=0 + 0x01010023, 0x00210143, 0x00214142, // divide by 2, mcu_cfg=0 + 0x04010023, 0x00210143, 0x00214142, // divide by 4, mcu_cfg=0 + 0x1f010023, 0x00210143, 0x00214142, // DPSM divider, mcu_cfg=0 + 0x04010023, 0x00210143, 0x00214142, // divide by 4, mcu_cfg=0 +}; +#endif + +#endif // APPLICATION_IBOOT + +#if APPLICATION_SECUREROM + +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 6 +#define PLL0_M 175 +#define PLL0_S 2 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 4 +#define PLL3_M 171 +#define PLL3_S 3 +#define PLL3_V PLL_VCO_TARGET(PLL3) +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +static u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x90021041, 0x80000000, 0x80000000, 0xA0000003, // cpu, mcu_fixed, mcu, pclk1 + 0xA0000001, 0x00000000, 0x00000000, 0x00000000, // prediv0, prediv1, prediv2, prediv3 + 0x00000000, 0x00000000, 0x00000000, 0x80000000, // prediv4, prediv5, prediv6, managed0 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // managed1, managed2, managed3, managed4 + 0x00000000, 0x80000000, 0x00000000, 0x00000000, // managed5, aes_core, vid1, medium0 + 0x00000000, 0x00000000, 0x00000000, 0x80000002, // vid0, i2c, sdio, audio + 0x00000000, 0x00000000, 0x80000008, 0x80000008, // hpark_pclk0, hpark_tclk, uperf, debug + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // hperf_rt, gfx, gfx_slc, hperf_nrt + 0x00000000, 0x00000000, 0x80000001, 0x80000001, // isp, iop, cdio, lperfs + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // pclk0, pclk2, pclk3, medium1 + 0xB0000001, 0x80000001, 0x80000001, 0xB0000001, // spi0, spi1, spi2, spi3 + 0x80000001, 0x80000314, 0x00000000, 0x00000000, // spi4, sleep, usbphy, usbphy1 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // usbohci, usb12, nco_ref0, nco_ref1 + 0x00000000, 0x00000000, 0x00000000, 0x00000000 // nco_ref2, venc_mtx, venc, slv_bus +}; + +#define PLL_GATES_ACTIVE (0) + +#define PERF_STATE_ACTIVE kPERF_STATE_SECUREROM +// For rdar://9188170 : we must avoid MCU clock transitions. Bear this in mind if additional +// perf_states are defined. +static u_int32_t perf_state_active[3] = { + 0x00000004, 0x03010100, 0x00040000, // managed3-0, slow mcu_cfg, aes_core +}; + +static struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kPERF_STATE_SECUREROM, 1 }, + [kPerformanceMedium] = { kPERF_STATE_SECUREROM, 1 }, + [kPerformanceLow] = { kPERF_STATE_SECUREROM, 1 }, + [kPerformanceMemory] = { kPERF_STATE_SECUREROM, 1 }, +}; + +#endif // APPLICATION_SECUREROM + +/* current clock speeds */ +static u_int32_t clks[PMGR_CLK_COUNT]; +static u_int32_t *plls = &clks[PMGR_CLK_PLL0]; +static u_int32_t perf_level; +static u_int32_t perf_div; + +struct clk_parent { + volatile u_int32_t *divider_reg; + u_int32_t divider_slot; + u_int8_t parents[4]; +}; + +/* Based on PMGR 1.16 */ +static const struct clk_parent clk_parents[PMGR_CLK_COUNT] = { +[PMGR_CLK_OSC] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL0] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL1] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL2] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL3] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL4] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL5] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLLUSB] = { 0, 0, { 0, 0, 0, 0 } }, +[PMGR_CLK_DOUBLER] = { &rPMGR_DOUBLER_CTL, 0, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_CPU] = { &rPMGR_CPU_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL0, PMGR_CLK_PLL1, 0 } }, +[PMGR_CLK_MEM] = { &rPMGR_CPU_CLK_CFG, 2, { PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU } }, +[PMGR_CLK_PIO] = { &rPMGR_CPU_CLK_CFG, 3, { PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU } }, +[PMGR_CLK_ACP] = { &rPMGR_CPU_CLK_CFG, 4, { PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU, PMGR_CLK_CPU } }, +[PMGR_CLK_MCU_FIXED] = { &rPMGR_MCU_FIXED_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_MCU] = { &rPMGR_MCU_CLK_CFG, 1, { PMGR_CLK_MCU_FIXED, 0, 0, 0 } }, +[PMGR_CLK_PREDIV0] = { &rPMGR_PREDIV0_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_PREDIV1] = { &rPMGR_PREDIV1_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_PREDIV2] = { &rPMGR_PREDIV2_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_PREDIV3] = { &rPMGR_PREDIV3_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_PREDIV4] = { &rPMGR_PREDIV4_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL5, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV5] = { &rPMGR_PREDIV5_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PREDIV6] = { &rPMGR_PREDIV6_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_MANAGED0] = { &rPMGR_MANAGED0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV4, PMGR_CLK_PREDIV5 } }, +[PMGR_CLK_MANAGED1] = { &rPMGR_MANAGED1_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV5 } }, +[PMGR_CLK_MANAGED2] = { &rPMGR_MANAGED2_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MANAGED3] = { &rPMGR_MANAGED3_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MANAGED4] = { &rPMGR_MANAGED4_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV4, PMGR_CLK_PREDIV5 } }, +[PMGR_CLK_MANAGED5] = { &rPMGR_MANAGED5_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV4, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_AES_CORE] = { &rPMGR_AES_CORE_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PLL2, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MEDIUM0] = { &rPMGR_MEDIUM0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MEDIUM1] = { &rPMGR_MEDIUM1_CLK_CFG, 1, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_VID0] = { &rPMGR_VID0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV6 } }, +[PMGR_CLK_VID1] = { &rPMGR_VID1_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_I2C] = { &rPMGR_I2C_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_OSC } }, +[PMGR_CLK_SDIO] = { &rPMGR_SDIO_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_AUDIO] = { &rPMGR_AUDIO_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_HPARK_PCLK] = { &rPMGR_HPARK_PCLK0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_HPARK_TCLK] = { &rPMGR_HPARK_TCLK_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_UPERF] = { &rPMGR_UPERF_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_DEBUG] = { &rPMGR_DEBUG_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_OSC } }, +[PMGR_CLK_GFX] = { &rPMGR_GFX_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED4 } }, +[PMGR_CLK_GFX_SLC] = { &rPMGR_GFX_SLC_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED4 } }, +[PMGR_CLK_HPERFNRT] = { &rPMGR_HPERFNRT_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_HPERFRT] = { &rPMGR_HPERFRT_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED5 } }, +[PMGR_CLK_ISP] = { &rPMGR_ISP_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_IOP] = { &rPMGR_IOP_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_CDIO] = { &rPMGR_CDIO_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_LPERFS] = { &rPMGR_LPERFS_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED3 } }, +[PMGR_CLK_PCLK0] = { &rPMGR_PCLK0_CLK_CFG, 0, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK1] = { &rPMGR_PCLK1_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4 } }, +[PMGR_CLK_PCLK2] = { &rPMGR_PCLK2_CLK_CFG, 0, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK3] = { &rPMGR_PCLK3_CLK_CFG, 0, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_SPI0] = { &rPMGR_SPI0_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI1] = { &rPMGR_SPI1_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI2] = { &rPMGR_SPI2_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI3] = { &rPMGR_SPI3_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI4] = { &rPMGR_SPI4_CLK_CFG, 0, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SLOW] = { &rPMGR_SLEEP_CLK_CFG, 2, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_SLEEP] = { &rPMGR_SLEEP_CLK_CFG, 1, { PMGR_CLK_SLOW, 0, 0, 0 } }, +[PMGR_CLK_USBPHY] = { &rPMGR_USBPHY_CLK_CFG, 0, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_USBPHY1] = { &rPMGR_USBPHY1_CLK_CFG, 0, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_USBOHCI] = { &rPMGR_USBOHCI_CLK_CFG, 0, { PMGR_CLK_MEDIUM1, PMGR_CLK_DOUBLER, 0, 0 } }, +[PMGR_CLK_USB12] = { &rPMGR_USB12_CLK_CFG, 1, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_NCO_REF0] = { &rPMGR_NCO_REF0_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_NCO_REF1] = { &rPMGR_NCO_REF1_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV4 } }, +[PMGR_CLK_NCO_REF2] = { &rPMGR_NCO_REF2_CLK_CFG, 1, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VENC_MTX] = { &rPMGR_VENC_MTX_CLK_CFG, 1, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL5 } }, +[PMGR_CLK_VENC] = { &rPMGR_VENC_CLK_CFG, 1, { PMGR_CLK_VENC_MTX, 0, 0, 0 } }, +[PMGR_CLK_SLV_BUS] = { &rPMGR_SLV_BUS_CLK_CFG, 1, { PMGR_CLK_MANAGED0, PMGR_CLK_MANAGED1, PMGR_CLK_MANAGED2, PMGR_CLK_MANAGED4 } }, +}; + +static void init_thermal_sensors(void); +static void clocks_get_frequencies(void); +static u_int32_t get_pll(int pll); +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t v); +static void clocks_set_gates(u_int64_t *devices, bool enable); +static void clocks_quiesce_internal(void); +static void update_perf_state(u_int32_t new_perf_state); + +void platform_power_init(void) +{ + // Set Power Gating Parameters for all the power domains + rPMGR_PWR_GATE_TIME_A(1) = (208 << 16); // CPU0 + rPMGR_PWR_GATE_TIME_B(1) = (32 << 26); + rPMGR_PWR_GATE_TIME_A(2) = (208 << 16); // CPU1 + rPMGR_PWR_GATE_TIME_B(2) = (32 << 26); + rPMGR_PWR_GATE_TIME_A(3) = (54 << 16); // SCU + rPMGR_PWR_GATE_TIME_A(4) = (36 << 16); // L2RAM0 + rPMGR_PWR_GATE_TIME_A(5) = (36 << 16); // L2RAM1 + rPMGR_PWR_GATE_TIME_A(6) = (192 << 16) | (2 << 0); // IOP + rPMGR_PWR_GATE_TIME_B(6) = (32 << 26) | (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(7) = (568 << 16) | (7 << 0); // GFX + rPMGR_PWR_GATE_TIME_B(7) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(8) = (621 << 16) | (6 << 0); // HPERF-RT + rPMGR_PWR_GATE_TIME_B(8) = (2 << 16) | (2 << 8) | (9 << 0); + rPMGR_PWR_GATE_TIME_A(9) = (605 << 16) | (9 << 0); // ISP + rPMGR_PWR_GATE_TIME_B(9) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(10) = (366 << 16) | (4 << 0); // HPERF-NRT + rPMGR_PWR_GATE_TIME_B(10) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(11) = (472 << 16) | (6 << 0); // VDEC + rPMGR_PWR_GATE_TIME_B(11) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(12) = (529 << 16) | (8 << 0); // VENC + rPMGR_PWR_GATE_TIME_B(12) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(13) = (275 << 16) | (4 << 0); // FMI + rPMGR_PWR_GATE_TIME_B(13) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(14) = (149 << 16) | (1 << 0); // HPARK + rPMGR_PWR_GATE_TIME_B(14) = (2 << 16) | (2 << 8) | (4 << 0); + +#if APPLICATION_IBOOT + /* clear CPU1's reset; it will still be powered down */ + clock_reset_device(CLK_CPU1); + + // Read thermal Fused values and store into thermal registers. + init_thermal_sensors(); +#endif +} + + +extern void aic_spin(u_int32_t usecs); + +void platform_power_spin(u_int32_t usecs) +{ + aic_spin(usecs); +} + +int clocks_init(void) +{ +#if APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) + + u_int32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + for (cnt = 0; cnt < 7; cnt++) plls[cnt] = get_pll(cnt); + + /* Calculate our initial performance divider based on CPU_DIVISOR */ + perf_div = (rPMGR_CPU_CLK_CFG & rPMGR_CLK_CFG_DIV_MASK) / (clk_divs_active[0] & rPMGR_CLK_CFG_DIV_MASK); + + /* Match the divider to one of the performance levels */ + if (perf_div == perf_levels[kPerformanceHigh].perf_div) perf_level = kPerformanceHigh; + else if (perf_div == perf_levels[kPerformanceMedium].perf_div) perf_level = kPerformanceMedium; + else if (perf_div == perf_levels[kPerformanceLow].perf_div) perf_level = kPerformanceLow; + + clocks_get_frequencies(); + +#endif /* APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) */ + + return 0; +} + +/* clocks_set_default - called by SecureROM, LLB, iBSS main via + platform_init_setup_clocks, so the current state of the chip is + either POR, or whatever 'quiesce' did when leaving SecureROM. */ +int clocks_set_default(void) +{ + u_int32_t cnt, reg, val, cpu_div; + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + + /* Be sure the bypass performance state is set up */ + rPMGR_PERF_STATE_A(kPERF_STATE_BYPASS) = perf_state_bypass[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_BYPASS) = perf_state_bypass[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_BYPASS) = perf_state_bypass[2]; + +#if APPLICATION_SECUREROM + rPMGR_PERF_STATE_A(kPERF_STATE_SECUREROM) = perf_state_active[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_SECUREROM) = perf_state_active[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_SECUREROM) = perf_state_active[2]; +#endif + +#if APPLICATION_IBOOT + for (cnt = 0; cnt < kPERF_STATE_IBOOT_CNT; cnt++) { + rPMGR_PERF_STATE_A(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt*3) + 0]; + rPMGR_PERF_STATE_B(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt*3) + 1]; + rPMGR_PERF_STATE_C(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt*3) + 2]; + } + + // Save the PERF_STATE configuration in rPMGR_SCRATCH1 + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, kPERF_STATE_IBOOT + 3); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), kPERF_STATE_IBOOT + 2); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), kPERF_STATE_IBOOT + 3); +#endif + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + +#if APPLICATION_IBOOT && !SUPPORT_FPGA + // We must be running at Vnom or greater at this point. Move to the fast EMA bank + // so we can update the incorrect reset values in the slow bank. The fast bank is + // safe as long as we stay above Vmin. + rPMGR_EMA_CTL_CPU = rPMGR_EMA_CTL_CPU_SEL; + while (rPMGR_EMA_CTL_CPU & rPMGR_EMA_CTL_CPU_SPIN) ; + rPMGR_EMA_CTL_SOC = rPMGR_EMA_CTL_SOC_SEL; + while (rPMGR_EMA_CTL_SOC & rPMGR_EMA_CTL_SOC_SPIN) ; + + // Fix the busted defaults in bank 0 + rPMGR_SRAM_EMA_B0_Pn_LO(EMA_MCU) = 0x51b4a; /* rdar://problem/7633460 */ + rPMGR_SRAM_EMA_B0_Pn_HI(EMA_DISP) = 0x32176; /* rdar://problem/7709646 */ +#endif /* APPLICATION_IBOOT */ + + clks[PMGR_CLK_OSC] = OSC_FREQ; + +#ifdef PLL0_T + set_pll(0, PLL0_P, PLL0_M, PLL0_S, PLL0_V); +#endif + +#ifdef PLL1_T + set_pll(1, PLL1_P, PLL1_M, PLL1_S, PLL1_V); +#endif + +#ifdef PLL2_T + set_pll(2, PLL2_P, PLL2_M, PLL2_S, PLL2_V); +#endif + +#ifdef PLL3_T + set_pll(3, PLL3_P, PLL3_M, PLL3_S, PLL3_V); +#endif + +#ifdef PLL4_T + set_pll(4, PLL4_P, PLL4_M, PLL4_S, PLL4_V); +#endif + +#ifdef PLL5_T + set_pll(5, PLL5_P, PLL5_M, PLL5_S, PLL5_V); +#endif + +#ifdef PLLUSB_T + set_pll(6, PLLUSB_P, PLLUSB_M, PLLUSB_S, PLLUSB_V); +#endif + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < 7; cnt++) plls[cnt] = get_pll(cnt); + + // perf_div needs to be established before touching PMGR_CPU_CLK_CFG + perf_level = kPerformanceLow; + perf_div = perf_levels[perf_level].perf_div; + + // Open the active PLL gates + rPMGR_PLL_GATES = PLL_GATES_ACTIVE; + + // Set all clock dividers to their active values + // Start with CPU then work backwards + for (cnt = 0; cnt < PMGR_CLK_CFG_COUNT; cnt++) { + reg = PMGR_CLK_CFG_COUNT - cnt; + if (reg == PMGR_CLK_CFG_COUNT) reg = 0; + + // Take care of managed clocks before predivs + if (reg == PMGR_CLK_NUM(MANAGED0)) + update_perf_state(kPerformanceLow); + + val = clk_divs_active[reg]; + + // Factor perf_div into PMGR_CPU_CLK_CFG + if (reg == PMGR_CLK_NUM(CPU)) { + cpu_div = val & rPMGR_CLK_CFG_DIV_MASK; + val &= ~rPMGR_CLK_CFG_DIV_MASK; + val |= cpu_div * perf_div; + } + clkcfgs[reg] = val; + // Sleep clock needs special attention: + // instead, we just make sure not to disable it. + + while (clkcfgs[reg] & rPMGR_CLK_CFG_PENDING); + } + + clocks_get_frequencies(); + + return 0; +} + +static void update_perf_state(u_int32_t new_perf_level) +{ + u_int32_t val, cpu_div; + + /* Change the CPU speed (factor old perf_div out, multiple new one in) */ + if (perf_levels[new_perf_level].perf_div != perf_div) { + val = rPMGR_CPU_CLK_CFG; + cpu_div = val & rPMGR_CLK_CFG_DIV_MASK; + cpu_div = (cpu_div / perf_div) * perf_levels[new_perf_level].perf_div; + val = (val & ~rPMGR_CLK_CFG_DIV_MASK) | cpu_div; + rPMGR_CPU_CLK_CFG = val; + while (rPMGR_CPU_CLK_CFG & rPMGR_CLK_CFG_PENDING); + perf_div = perf_levels[new_perf_level].perf_div; + } + + /* Write the new select value */ + rPMGR_PERF_STATE_CTL = PMGR_PERF_STATE_SEL(perf_levels[new_perf_level].perf_state); + + /* Spin while any pending bits are asserted */ + while (rPMGR_PERF_STATE_CTL & PMGR_PERF_STATE_PENDING); +} + +void clocks_quiesce(void) +{ + /* mcu_clk will be changed to bypass clock */ + clks[PMGR_CLK_MCU] = OSC_FREQ; + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + + /* effectively full performance */ + perf_level = kPerformanceHigh; + perf_div = perf_levels[kPerformanceHigh].perf_div; +} + +static void clock_update_range(u_int32_t first, u_int32_t last, u_int32_t clkdata[]) +{ + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + u_int32_t val, reg; + + reg = first; + while (reg <= last) { + val = clkdata[reg]; + clkcfgs[reg] = val; + while (clkcfgs[reg] & rPMGR_CLK_CFG_PENDING); + reg++; + } +} + +static void clocks_quiesce_internal(void) +{ + u_int64_t devices[2]; + + // Critical: Debug, AIC, DWI, GPIO, AUDIO, UPERF, CDMA, CDIO, + // MCU, L2RAM, SCU, CPU0 + devices[0] = 0x000010005800005DULL; + devices[1] = 0x00000000001D0000ULL; + + // Turn on critical device clocks + clocks_set_gates(devices, true); + + // Turn off non-critical device clocks + clocks_set_gates(devices, false); + + // Simplified from PMGR Spec 1.16 Section 3.13.6 (plus changes from Erik) + + // Reset top-level dividers to bypass + clock_update_range(PMGR_CLK_NUM(PCLK1), PMGR_CLK_NUM(PREDIV6), clk_divs_bypass); + clock_update_range(PMGR_CLK_NUM(VID1), PMGR_CLK_NUM(VID1), clk_divs_bypass); +#if APPLICATION_IBOOT + // Prepare to move memory to bypass clock (ensure not high frequency, enable DLL force mode) + rPMGR_PERF_STATE_CTL = PMGR_PERF_STATE_SEL(perf_levels[kPerformanceMedium].perf_state); + while (rPMGR_PERF_STATE_CTL & PMGR_PERF_STATE_PENDING); + miu_bypass_prep(); +#endif + // Reset managed clocks and mcu, venc_mtx + rPMGR_PERF_STATE_CTL = PMGR_PERF_STATE_SEL(kPERF_STATE_BYPASS); + while (rPMGR_PERF_STATE_CTL & PMGR_PERF_STATE_PENDING); + // Reset PLLs and Doubler + rPMGR_PLL0_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL1_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL2_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL3_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL4_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLL5_CTL = rPMGR_PLL_EXT_BYPASS; + rPMGR_PLLUSB_CTL = rPMGR_PLL_EXT_BYPASS; +#if !SUPPORT_FPGA + while (!(rPMGR_PLL0_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL1_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL2_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL3_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL4_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLL5_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + while (!(rPMGR_PLLUSB_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; +#endif + rPMGR_DOUBLER_CTL = rPMGR_PLL_EXT_BYPASS; + while (!(rPMGR_DOUBLER_DEBUG & rPMGR_PLL_DEBUG_BYP_ENABLED)) ; + // Open the PLL Gates + rPMGR_PLL_GATES = (1 << 5) | (1 << 3) | (1 << 2); + // Reset the lower-level clocks + clock_update_range(PMGR_CLK_NUM(MANAGED0), PMGR_CLK_NUM(SLV_BUS), clk_divs_bypass); + // Reset the CPU clocks + clock_update_range(PMGR_CLK_NUM(CPU), PMGR_CLK_NUM(MCU), clk_divs_bypass); +} + +u_int32_t clocks_set_performance(u_int32_t performance_level) +{ + u_int32_t old_perf_level = perf_level; + + update_perf_state(performance_level); + perf_level = performance_level; + return old_perf_level; +} + +void clock_get_frequencies(u_int32_t *clocks, u_int32_t count) +{ + u_int32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) cnt = count; + + memcpy(clocks, clks, cnt * sizeof(u_int32_t)); +} + +u_int32_t clock_get_frequency(int clock) +{ + switch (clock) { + case CLK_CPU: + case CLK_FCLK: + return clks[PMGR_CLK_CPU]; + case CLK_ACLK: + case CLK_MEM: + return clks[PMGR_CLK_MCU]; + case CLK_HCLK: + case CLK_BUS: + return clks[PMGR_CLK_PIO]; + case CLK_PERIPH: + case CLK_PCLK: + return clks[PMGR_CLK_PCLK0]; + case CLK_FMI: + return clks[PMGR_CLK_PCLK1]; + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + return clks[PMGR_CLK_OSC]; + case CLK_USBPHYCLK: +#if SUPPORT_FPGA + return clks[PMGR_CLK_USBPHY]; /* The reference is special on FPGA */ +#else + return clks[PMGR_CLK_OSC]; /* This is ref_24_clk, not usb_phy_clk */ +#endif + case CLK_NCOREF: + return clks[PMGR_CLK_NCO_REF0]; + case CLK_VCLK0: + return clks[PMGR_CLK_VID0]; + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + return clks[PMGR_CLK_I2C]; + case CLK_MCLK: + default: + return 0; + } +} + +void clock_set_frequency(int clock, u_int32_t divider, u_int32_t pll_p, u_int32_t pll_m, u_int32_t pll_s, u_int32_t pll_t) +{ + switch (clock) { + case CLK_VCLK0: + /* XXX */ + break; + default: + break; + } +} + +void clock_gate(int device, bool enable) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + if (reg > PMGR_LAST_PS) return; + + // Set the PS field to the requested level + if (enable) *reg |= 0xF; + else *reg &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + while ((*reg & 0xF) != ((*reg >> 4) & 0xF)); +} + +static void clocks_set_gates(u_int64_t *devices, bool enable) +{ + u_int32_t dev, index; + volatile u_int32_t *devpss = PMGR_FIRST_PS; + u_int64_t mask = 1, devmask = 0; + + for (dev = 0, index = -1; dev < PMGR_DEV_PS_COUNT; dev++, mask <<= 1) { + if ((dev % 64) == 0) { + devmask = devices[++index]; + if (enable == false) + devmask ^= -1ULL; + mask = 1; + } + // Skip CPUs + if (dev < PMGR_PS_NUM(SCU)) continue; + if ((devmask & mask) != 0) { + if (enable) devpss[dev] |= 0xF; + else devpss[dev] &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + while ((devpss[dev] & 0xF) != ((devpss[dev] >> 4) & 0xF)); + } + } +} + +void platform_diag_gate_clocks(void) +{ +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + // Use WDOG pin to cause a PMU reset + gpio_configure_out(GPIO_SYSTEM_RESET, 1); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_watchdog_tickle(void) +{ + // Varies by target. This layer between is necessary so that + // we don't go straight from generic code to target. + target_watchdog_tickle(); +} + +static const u_int32_t divider_slot_table[8 * 2] = { + 0x00000000, 0, + 0x0000001F, 0, + 0x000003E0, 5, + 0x00007C00, 10, + 0x000F8000, 15, + 0x00001F00, 8, + 0x001F0000, 16, + 0x1F000000, 24 +}; + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + u_int32_t cnt; + u_int32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_CPU] = 15000000; + clks[PMGR_CLK_MCU] = 10000000; + clks[PMGR_CLK_MCU_FIXED]= 10000000; + clks[PMGR_CLK_USBPHY] = 12000000; + + // keep compiler happy + cnt = (u_int32_t)clk_parents; + cnt = (u_int32_t)divider_slot_table; + +#else + volatile u_int32_t *reg; + u_int32_t cnt, val, src_shift, parent_idx, slot, mask, shift, divider, perf_div_tmp; + u_int64_t freq; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) { + reg = clk_parents[cnt].divider_reg; + if (reg == 0) continue; + + switch (cnt) { + case PMGR_CLK_MANAGED0 : + src_shift = 5; + slot = 1; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED1 : + src_shift = 13; + slot = 5; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED2 : + src_shift = 21; + slot = 6; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED3 : + src_shift = 29; + slot = 7; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[0] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED4 : + src_shift = 5; + slot = 1; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[1] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MANAGED5 : + src_shift = 13; + slot = 5; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[2] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_AES_CORE : + src_shift = 21; + slot = 1; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[2] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MCU : + src_shift = 32; + slot = 5; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[1] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_MCU_FIXED : + src_shift = 21; + slot = 6; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[1] & ~rPMGR_CLK_CFG_ENABLE); + break; + + case PMGR_CLK_VENC_MTX : + src_shift = 5; + slot = 1; + val = (*reg & rPMGR_CLK_CFG_ENABLE) | (perf_state_active[2] & ~rPMGR_CLK_CFG_ENABLE); + break; + + default : + src_shift = 28; + slot = clk_parents[cnt].divider_slot; + val = *reg; + break; + } + + if ((val & rPMGR_CLK_CFG_ENABLE) == 0) continue; + + parent_idx = clk_parents[cnt].parents[(val >> src_shift) & 3]; + freq = clks[parent_idx]; + + if ((cnt == PMGR_CLK_DOUBLER) && !(val & rPMGR_DOUBLER_EXT_BYPASS)) + freq *= 2; + + if (slot != 0) { + mask = divider_slot_table[slot * 2]; + shift = divider_slot_table[slot * 2 + 1]; + divider = (val & mask) >> shift; + + if (divider == 0) continue; + + switch (cnt) { + case PMGR_CLK_CPU : perf_div_tmp = perf_div; break; + default : perf_div_tmp = 1; break; + } + freq *= perf_div_tmp; + freq /= divider; + } + + clks[cnt] = freq; + } +#endif +} + +static u_int32_t get_pll(int pll) +{ + u_int32_t pllctl; + u_int64_t freq = 0; + + switch (pll) { + case 0: pllctl = rPMGR_PLL0_CTL; break; + case 1: pllctl = rPMGR_PLL1_CTL; break; + case 2: pllctl = rPMGR_PLL2_CTL; break; + case 3: pllctl = rPMGR_PLL3_CTL; break; + case 4: pllctl = rPMGR_PLL4_CTL; break; + case 5: pllctl = rPMGR_PLLUSB_CTL; break; + default: goto exit; break; + } + + if ((pllctl & rPMGR_PLL_ENABLE) == 0) goto exit; + + if ((pllctl & (rPMGR_PLL_EXT_BYPASS | rPMGR_PLL_BYPASS))) { + freq = OSC_FREQ; + } else { + freq = OSC_FREQ * 2; + freq *= (pllctl >> 3) & 0x3FF; // *M + freq /= (pllctl >> 14) & 0x3F; // /P + freq /= 1 << ((pllctl >> 0) & 0x07); // /2^S + } + +exit: + return freq; +} + +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t vco) +{ + volatile u_int32_t *pllctl, *pllparam; + u_int32_t afc; + + switch (pll) { + case 0: pllctl = &rPMGR_PLL0_CTL; pllparam = &rPMGR_PLL0_PARAM; break; + case 1: pllctl = &rPMGR_PLL1_CTL; pllparam = &rPMGR_PLL1_PARAM; break; + case 2: pllctl = &rPMGR_PLL2_CTL; pllparam = &rPMGR_PLL2_PARAM; break; + case 3: pllctl = &rPMGR_PLL3_CTL; pllparam = &rPMGR_PLL3_PARAM; break; + case 4: pllctl = &rPMGR_PLL4_CTL; pllparam = &rPMGR_PLL4_PARAM; break; + case 5: pllctl = &rPMGR_PLL5_CTL; pllparam = &rPMGR_PLL5_PARAM; break; + case 6: pllctl = &rPMGR_PLLUSB_CTL; pllparam = &rPMGR_PLLUSB_PARAM; break; + default: return; break; + } + + // Find the AFC setting for the desired VCO frequency + afc = 13; + if (vco < 1100000000UL) afc = 5; + if (vco > 1500000000UL) afc = 28; + + // Set the default lock time (2400 cycles), and disable AFC and use EXT AFC + *pllparam = rPMGR_PARAM_EXT_AFC(afc) | rPMGR_PARAM_LOCK_TIME(2400); + + *pllctl = (rPMGR_PLL_ENABLE | rPMGR_PLL_LOAD | + rPMGR_PLL_P(p) | rPMGR_PLL_M(m) | rPMGR_PLL_S(s)); + +#if !SUPPORT_FPGA + while ((*pllctl & rPMGR_PLL_REAL_LOCK) == 0); // wait for pll to lock +#endif /* ! SUPPORT_FPGA */ +} + +#endif // !APPLICATION_EMBEDDEDIOP + +void clock_reset_device(int device) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + switch (device) { + case CLK_CPU1 : + case CLK_FMI0 : + case CLK_FMI1 : + case CLK_FMI2 : + case CLK_FMI3 : + case CLK_IOP : + case CLK_SDIO : + *reg |= rPMGR_PS_RESET; + spin(1); + *reg &= ~rPMGR_PS_RESET; + break; + + case CLK_MCU: + // Make sure resets are asserted/deasserted to gfx0, gfx1, hperfrt, hperfnrt + // + rPMGR_GFX_SYS_PS |= rPMGR_PS_RESET; + rPMGR_GFX_CORES_PS |= rPMGR_PS_RESET; + rPMGR_HPERFNRT_PS |= rPMGR_PS_RESET; + rPMGR_HPERFRT_PS |= rPMGR_PS_RESET; + *reg |= rPMGR_PS_RESET; + spin(1); + *reg &= ~rPMGR_PS_RESET; + rPMGR_GFX_SYS_PS &= ~rPMGR_PS_RESET; + rPMGR_GFX_CORES_PS &= ~rPMGR_PS_RESET; + rPMGR_HPERFNRT_PS &= ~rPMGR_PS_RESET; + rPMGR_HPERFRT_PS &= ~rPMGR_PS_RESET; + break; + + default : + break; + } +} + +#if WITH_DEVICETREE + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ + u_int32_t propSize, perf_state_config; + char *propName; + void *propData; + + // Get the PERF_STATE configuration generated at hardware init + perf_state_config = rPMGR_SCRATCH1; + if (perf_state_config == 0) return; + + // Fill in the firmware-v-perf-states property + propName = "firmware-v-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(u_int32_t))) { + panic("pmgr property firmware-v-perf-states is the wrong size"); + } + // Voltage states are in reverse order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), perf_state_config); + } + + // Fill in the firmware-p-perf-state property + propName = "firmware-p-perf-state"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (1 * sizeof(u_int32_t))) { + panic("pmgr property firmware-p-perf-states is the wrong size"); + } + // There is only one Frequency Managed / Performance state + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, perf_state_config); + } + + // Fill in the firmware-m-perf-states property + propName = "firmware-m-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (4 * sizeof(u_int32_t))) { + panic("pmgr property firmware-m-perf-states is the wrong size"); + } + // Memory states are in the same order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), perf_state_config); + ((u_int32_t *)propData)[2] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), perf_state_config); + ((u_int32_t *)propData)[3] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), perf_state_config); + } +} + +#endif + +void init_thermal_sensors(void) +{ + // Read fused temperature values to calculate slope and offset to be stored + // into rPMGR_THERMAL_CTL2, which is later used to compute real die temperature value. + + u_int32_t fusedTempValueAt70 = chipid_get_fused_thermal_70C(); + u_int32_t fusedTempValueAt25 = chipid_get_fused_thermal_25C(); + u_int32_t tempSlope = 0x100; + + // Grab the 4 bit fuse revision + u_int32_t fuseRevision = chipid_get_fuse_revision(); + + // Should probably make sure we don't divde by zero. + if (fusedTempValueAt25 == fusedTempValueAt70) { + fusedTempValueAt70 = 70; + fusedTempValueAt25 = 25; + dprintf(DEBUG_INFO, "Invalid fuse values\n"); + } + + // 0 means 1 pt calibration fused incorrectly or no calibration. Proto 1 & 2 + // 1 means 1 pt calibration correct, default slope. EVT units. + // 2+ future release, reserved for 2 pt calibration. + if (0 == fuseRevision) { + fusedTempValueAt25 = fusedTempValueAt25 >> 1; + fusedTempValueAt25 = ((fusedTempValueAt70 & 0x1) << 7) | fusedTempValueAt25; + } else if (fuseRevision > 1) { + // 45 = 70 - 25 + tempSlope = (45*256) / (fusedTempValueAt70 - fusedTempValueAt25); + } + + + // Set the PWDN mode on to save power. + rPMGR_THERMAL_CTL0 |= 0x00000004; + // Configure PWDN time. + rPMGR_THERMAL_CTL1 |= 0x00005B00; + + // Calculate the real offset. + u_int32_t realOffset = 25 - ((tempSlope * fusedTempValueAt25) / (tempSlope==0x100 ? 1:256)); + + // Bits 23 16 + // Temp_OFFSET => [8 bit signed integer] + rPMGR_THERMAL_CTL2 = (realOffset & 0xFF) << 16; + + // Bits 9 0 + // TEMP_SLOPE => [2 bit integer| 8 bit decimal] + rPMGR_THERMAL_CTL2 |= tempSlope & 0x3FF; +} diff --git a/platform/s5l8945x/pmgr/rules.mk b/platform/s5l8945x/pmgr/rules.mk new file mode 100644 index 0000000..fa626c5 --- /dev/null +++ b/platform/s5l8945x/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s5l8945x/rules.mk b/platform/s5l8945x/rules.mk new file mode 100644 index 0000000..fe57847 --- /dev/null +++ b/platform/s5l8945x/rules.mk @@ -0,0 +1,122 @@ +# Copyright (C) 2010-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +############################################################################## +# Code running on the main CPU +# +ifeq ($(PLATFORM_VARIANT),) + +ARM_CPU := cortex-a9 + +# Devmap chip ID based on sub-platform identifier +ifeq ($(SUB_PLATFORM),s5l8945x) +DEVMAP_CHIP_ID := 8945 +endif + +MAX_DFU_SIZE := 180224 + +ifeq ($(TEXT_BANK),srom) +TEXT_BASE := 0x00000000 +endif +ifeq ($(TEXT_BANK),sram) +TEXT_BASE := 0x34000000 +endif +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0xBFF00000 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + WITH_LEGACY_PANIC_LOGS=1 \ + WITH_NO_RANDOM_HEAP_COOKIE=1 \ + WITH_NO_RANDOM_STACK_COOKIE=1 \ + WITH_NON_COHERENT_DMA=1 \ + WITH_ROM_TRAMPOLINE=1 \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=192 \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +# L2_CACHE_SIZE=1048576 \ +# + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) +# This selects the start of the DATA segment and the end of the INSECURE_MEMORY area +DATA_BASE := 0x3402C000 + +OPTIONS += \ + DATA_BASE="$(DATA_BASE)" + +GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) +endif + +ALL_OBJS += $(LOCAL_DIR)/init.o + +endif + +############################################################################## +# Code running on the IOP +# +ifeq ($(PLATFORM_VARIANT),IOP) + +OPTIONS += \ + PLATFORM_VARIANT_IOP=1 \ + AIC_CPU_ID=2 \ + WITH_PLATFORM_HALT=1 \ + SUPPORT_SLEEP=1 \ + WITH_IOP_POWER_GATING=1 \ + DEEP_IDLE_THRESHOLD_US=10000 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" \ + SUPPORT_SLEEP=1 + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o +endif + +############################################################################## +# Code running on the audio engine +# +ifeq ($(PLATFORM_VARIANT),Audio) + +OPTIONS += \ + PLATFORM_VARIANT_AUDIO=1 \ + WITH_PLATFORM_HALT=1 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" \ + SUPPORT_SLEEP=1 + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o + +endif diff --git a/platform/s5l8950x/amc/amc.c b/platform/s5l8950x/amc/amc.c new file mode 100644 index 0000000..a6036df --- /dev/null +++ b/platform/s5l8950x/amc/amc.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + return amc_init(resume); +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping (void) +{ + amc_configure_default_address_decoding_and_mapping(); +} + +void amc_enable_slow_boot (bool enable) +{ + int slow_freqsel; + + if (enable) { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + rAMC_FREQSEL = amc_params.freqsel; + return; + } + + slow_freqsel = 3; + rAMC_BOOTCLK = (amc_params.bootclkdivsr << 8) | 1; + spin(1); + rAMC_FREQSEL = slow_freqsel; + amc_phy_scale_dll(slow_freqsel, amc_params.bootclkdivsr); + } else { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + return; + } + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_small; + spin(2); + + rAMC_BOOTCLK &= ~1; + spin(1); + rAMC_FREQSEL = amc_params.freqsel; + amc_phy_scale_dll(amc_params.freqsel, 1); + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_guided; + } +} + +void amc_finalize (bool resume) +{ + uint8_t odts; + +#if SUPPORT_FPGA + rAMC_PWRMNGTEN |= 0x00000001; // Sharing clocks between channels so do not enable clock stopping for PD or SR +#else + rAMC_PWRMNGTEN |= 0x00011011; +#endif + + rAMC_AREFPARAM |= (0x00001000); // Turn on freq change waiting for refresh and self-refresh exit + + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&odts); + rAMC_ODTS = 0x00010320; // [16] => TempDrtEn, [9:0] RdIntrvl XXX based on tREFI + + if (!resume) { + amc_enable_autorefresh(); + } + +#if SUPPORT_FPGA + rAMC_FREQSEL = amc_params.freqsel; +#endif + +#if !SUPPORT_FPGA + // Turn of Fast Critical Word Forwarding feature and AIU CWF feature + // Disabled for NRT + rAMC_AIUPRT_RD_CWF = 0x00161600; + rAMC_QBRPARAM = 0x00810000; + rAMC_QBREN = 0x00111001; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + + if (dev_info->rev_id == 1 && dev_info->rev_id2 == 0) { + if (!resume) { + // TestMRS entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + + // + // tRAS_min default + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xee); + + // + // LSAEN delay default + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xef); + } + } + break; + + default: + break; + } + + return; +} + +// Shift dq offset as needed. +// In the future, it's possible the shift value changes based on SOC or DRAM vendor. +// Thus, we need to have this function per SOC. +void amc_dram_shift_dq_offset (int8_t *dq_offset, uint8_t num_bytes) { + int8_t shift_val; + uint8_t i; + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + case JEDEC_MANUF_ID_SAMSUNG: + case JEDEC_MANUF_ID_ELPIDA: + + // shift 2 steps + shift_val = -2; + break; + + default: + shift_val = 0; + break; + } + + for (i = 0; i < num_bytes; i++) + dq_offset[i] += shift_val; +} diff --git a/platform/s5l8950x/amc/rules.mk b/platform/s5l8950x/amc/rules.mk new file mode 100644 index 0000000..36a6843 --- /dev/null +++ b/platform/s5l8950x/amc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AMC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/amc.o diff --git a/platform/s5l8950x/asm.S b/platform/s5l8950x/asm.S new file mode 100644 index 0000000..2b5991c --- /dev/null +++ b/platform/s5l8950x/asm.S @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + + .text + +ARM_FUNCTION _platform_start + + // Configure the first half of the cache as RAM + mov r2, #0xFF000000 // L2CCONFIG0.AcpMask[7:0] = 0xFF + orr r2, r2, #0x000F0000 // L2CCONFIG0.RamWayMask[7:0] = 0x0F + orr r2, r2, #0x00000002 // L2CCONFIG0.RamEna = 1 + mcr p15, 1, r2, c15, c2, 0 // Write to L2CCONFIG0 + isb // Wait for the write to take effect + bx lr + + +ARM_FUNCTION _miu_read_l2cadrmap + + mrc p15, 1, r0, c15, c2, 4 + bx lr + + +ARM_FUNCTION _miu_write_l2cadrmap + + mcr p15, 1, r0, c15, c2, 4 + isb + bx lr diff --git a/platform/s5l8950x/chipid/chipid.c b/platform/s5l8950x/chipid/chipid.c new file mode 100644 index 0000000..6e482a4 --- /dev/null +++ b/platform/s5l8950x/chipid/chipid.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if SUPPORT_FPGA +#define _rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#undef rCFG_FUSE0 +// XXX ECID (1 << 7)? +// XXX double-check memory values +#define rCFG_FUSE0 ((0 << 31) | (3 << 28) | (0xE << 24) | (2 << 22) | \ + (0 << 9) | (1 << 8) | (3 << 4) | (kPlatformSecurityDomainDarwin << 2) | (0 << 1) | (0 << 0) | \ + _rCFG_FUSE0) +#endif + +#if SUB_PLATFORM_S5L8950X +// H5 Tunables rev 0.59 & H5P Test Plan rev 1.13 +#define MINIMUM_BINNING_VERSION (1) +static u_int32_t default_soc_voltages[CHIPID_SOC_VOLTAGE_COUNT] = { 950, 1000, 1100 }; +static u_int32_t default_cpu_voltages[CHIPID_CPU_VOLTAGE_COUNT] = { 810, 935, 1020, 1065, 1100, 1145, 0, 0 }; +static u_int32_t default_ram_voltages[CHIPID_RAM_VOLTAGE_COUNT] = { 950, 1000 }; +#endif + +static u_int32_t chipid_get_binning_revision(void); +static u_int32_t chipid_get_base_voltage(void); + +bool chipid_get_production_mode(void) +{ + return ((rCFG_FUSE0 >> 0) & 1) != 0; +} + +void chipid_clear_production_mode(void) +{ +#if SUPPORT_FPGA + _rCFG_FUSE0 &= ~1; +#else + rCFG_FUSE0 &= ~1; +#endif +} + +bool chipid_get_secure_mode(void) +{ + return ((rCFG_FUSE0 >> 1) & 1) != 0; +} + +u_int32_t chipid_get_security_domain(void) +{ + return (rCFG_FUSE0 >> 2) & 3; +} + +u_int32_t chipid_get_board_id(void) +{ + return (rCFG_FUSE0 >> 4) & 3; +} + +bool chipid_get_ecid_image_personalization_required(void) +{ + return ((rCFG_FUSE0 >> 7) & 1) != 0; +} + +u_int32_t chipid_get_minimum_epoch(void) +{ + return (rCFG_FUSE0 >> 9) & 0x7F; +} + +u_int32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_S5L8950X + return 0x8950; +#endif +} + +u_int32_t chipid_get_chip_revision(void) +{ + return (((rECIDHI >> 13) & 0x7) << 4) | (((rECIDHI >> 10) & 0x7) << 0); +} + +u_int32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +u_int64_t chipid_get_ecid_id(void) +{ + u_int64_t ecid = 0; + +#if SUPPORT_FPGA + ecid = 0x000012345678ABCDULL; +#else + ecid |= ((rECIDLO >> 0)) & ((1ULL << (21 - 0)) - 1); // LOT_ID + + ecid <<= (26 - 21); + ecid |= ((rECIDLO >> 21)) & ((1ULL << (26 - 21)) - 1); // WAFER_NUM + + ecid <<= (10 - 2); + ecid |= ((rECIDHI >> 2)) & ((1ULL << (10 - 2)) - 1); // Y_POS + + ecid <<= (32 - 26); + ecid |= ((rECIDLO >> 26)) & ((1ULL << (32 - 26)) - 1); // X_POS_H + + ecid <<= ( 2 - 0); + ecid |= ((rECIDHI >> 0)) & ((1ULL << ( 2 - 0)) - 1); // X_POS_L +#endif + + return ecid; +} + +u_int64_t chipid_get_die_id(void) +{ + return ((u_int64_t)rECIDHI << 32) | rECIDLO; +} + +u_int32_t chipid_get_soc_voltage(u_int32_t index) +{ + u_int32_t soc_voltage; + u_int64_t soc_bin_data; + + if (index > CHIPID_SOC_VOLTAGE_COUNT) return 0; + + if (chipid_get_binning_revision() < MINIMUM_BINNING_VERSION) { + // This part is unbinned to the binning version is not supported + // Use the default voltage + soc_voltage = default_soc_voltages[index]; + } else { + // Read the SoC bin data from the fuses + soc_bin_data = ((((u_int64_t)rCFG_FUSE1) << 32) | rCFG_FUSE0) >> 25; + + // Start with the base voltage + soc_voltage = chipid_get_base_voltage(); + + // Add in the correct bin from the "array" + soc_voltage += 5 * ((soc_bin_data >> (index * 7)) & 0x7F); + } + + return soc_voltage; +} + +u_int32_t chipid_get_cpu_voltage(u_int32_t index) +{ + u_int32_t cpu_voltage; + u_int64_t cpu_bin_data; + + if (index > CHIPID_CPU_VOLTAGE_COUNT) return 0; + + if (chipid_get_binning_revision() < MINIMUM_BINNING_VERSION) { + // This part is unbinned to the binning version is not supported + // Use the default voltage + cpu_voltage = default_cpu_voltages[index]; + } else { + // Read the CPU bin data from the fuses + cpu_bin_data = ((((u_int64_t)rDVFM_FUSE(1)) << 32) | rDVFM_FUSE(0)) >> 5; + + // Start with the base voltage + cpu_voltage = chipid_get_base_voltage(); + + // Add in the correct bin from the "array" + cpu_voltage += 5 * ((cpu_bin_data >> (index * 7)) & 0x7F); + } + + return cpu_voltage; +} + +#ifndef TARGET_RAM_VOLTAGE_OFFSET +#define TARGET_RAM_VOLTAGE_OFFSET 0 +#endif + +u_int32_t chipid_get_ram_voltage(u_int32_t index) +{ + u_int32_t ram_voltage; + + if (index > CHIPID_RAM_VOLTAGE_COUNT) return 0; + + // RAM voltage is not binned, use the default voltage + ram_voltage = default_ram_voltages[index] + TARGET_RAM_VOLTAGE_OFFSET; + + return ram_voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return (rCFG_FUSE1 & (1 << 31)) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) rCFG_FUSE1 |= 1 << 31; +} + +int32_t chipid_get_cpu_temp_offset(u_int32_t cpu_number) +{ + int32_t temp_cal; + + switch (cpu_number) { + case 0 : temp_cal = (rDVFM_FUSE(9) >> 0) & 0x7F; break; + case 1 : temp_cal = (rDVFM_FUSE(9) >> 16) & 0x7F; break; + default : return 0; + } + + return 0x3B - temp_cal; +} + +u_int32_t chipid_get_fused_thermal_sensor_70C(u_int32_t sensorID) +{ + u_int32_t temp_cal; + + switch (sensorID) { + case 0: temp_cal = (rCFG_FUSE4 >> 8) & 0x7F; break; + case 1: temp_cal = (rCFG_FUSE4 >> 24) & 0x7F; break; + default : return 0; + } + + return temp_cal; +} + +u_int32_t chipid_get_fused_thermal_sensor_25C(u_int32_t sensorID) +{ + u_int32_t temp_cal; + + switch (sensorID) { + case 0: temp_cal = (rCFG_FUSE4 >> 0) & 0x7F; break; + case 1: temp_cal = (rCFG_FUSE4 >> 16) & 0x7F; break; + default : return 0; + } + + return temp_cal; +} + +u_int32_t chipid_get_fuse_revision(void) +{ + return (rCFG_FUSE0 >> 18) & 0xf; +} + +static u_int32_t chipid_get_binning_revision(void) +{ + return (rDVFM_FUSE(1) >> (61 - 32)) & 7; +} + +static u_int32_t chipid_get_base_voltage(void) +{ + return 25 * (1 + ((rDVFM_FUSE(0) >> 0) & 0x1F)); +} diff --git a/platform/s5l8950x/chipid/rules.mk b/platform/s5l8950x/chipid/rules.mk new file mode 100644 index 0000000..92158a2 --- /dev/null +++ b/platform/s5l8950x/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/s5l8950x/include/platform/amcconfig.h b/platform/s5l8950x/include/platform/amcconfig.h new file mode 100644 index 0000000..343f18e --- /dev/null +++ b/platform/s5l8950x/include/platform/amcconfig.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_RECONFIG | FLAG_AMC_PARAM_ENABLE_AIU), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .tREFi_1Gb = 0x5d, + .longsrcnt_1Gb = 0x2008, + .rdlat = 8, + .wrlat = 4, + .phyrdlat = 8, + .phywrlat = 4, + .pdn = 0x33000503, + .read = 0x00000103, + .bustat = 0x00222212, + .bustat2 = 0x00222212, + .derate = 0x30b3177b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x22, // MIF: tREFBW violation due to freq change + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00000100, + .chnldec2 = 0x003ffffd, + .arefparam = 0x0600a000, + .bootclkdivsr = 10, + .aref_freq0 = 0x00100100, + .aref_freq1 = 0x00100100, + .srextrarefcnt = 0x00010000, + .readleveling = 0x01000301, + + .freq = { + { // 522MHz + .cas = 0x0000040a, + .pch = 0x00040816, + .act = 0x1a060b0a, + .autoref = 0x1f439000, + .selfref = 0x00048080, + .modereg = 0x002f0502, + .mifcassch = 0x001f0111, + }, + { // 400MHz + .cas = 0x00000008, + .pch = 0x00000012, + .act = 0x14050a08, + .autoref = 0x18340000, + .selfref = 0x00038000, + .modereg = 0x00240000, + .mifcassch = 0x00000010, + }, + { // 200MHz + .cas = 0x00000004, + .pch = 0x00000009, + .act = 0x0a030504, + .autoref = 0x0c1a0000, + .selfref = 0x0001c000, + .modereg = 0x00120000, + .mifcassch = 0x00000000, + }, + { // 50 & 24MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x03070000, + .selfref = 0x00007000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + // These settings are common across all H4x and H5P. Channel decode and hashing + // is done in mainline init code. Any tunables that match hardware defaults are + // omitted here. + + { &rAMC_AIUPRT_CFG, 0x00070000 }, // address error enable + { &rAMC_AIUPRT_RD_GEN, 0x00000018 }, // fence read detect on GFX + { &rAMC_AIUPRT_WR, 0x00000001 }, // out-of-order write, ignore B-bit + + { &rAMC_AIU_CHNLDEC2, 0x003FFFFD }, + + { &rAMC_AIU_RDBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_WRBRSTLEN, 0x01010101 }, // burst len is 64B + + { &rAMC_AIU_CPUSPCREQ, 0x00000019 }, // CPU ageout timer + { &rAMC_AIU_GFXSPCREQ, 0x00000032 }, // GFX ageout timer + { &rAMC_AIU_NRTSPCREQ, 0x00000032 }, // Hperf-NRT ageout timer + { &rAMC_AIU_RTSPCREQ, 0x00000019 }, // Hperf-RT ageout timer + { &rAMC_AIU_PUSHEN, 0x00001100 }, // only supported for Hperf-RT + + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJEN, 0x00000001 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + + { &rAMC_MIFACTSCH, 0x00000001 }, + + { &rAMC_PSQRQTIMER0, 0x00000040 }, // RTG bypass up to 64 transactions + { &rAMC_PSQRQTIMER1, 0x00000018 }, // RTY bypass up to 24 transactions + { &rAMC_PSQRQTIMER2, 0x00000020 }, // RTG bypass up to 32 transactions + { &rAMC_PSQRQBRST, 0x040c040c }, // RTR transactions don't affect read burst size + { &rAMC_PSQRQSCHCRD, 0x002028f5 }, // read credits = 2 * write credits + { &rAMC_PSQWQBRST, 0x0208040c }, // RTR reads cause reduced write burst size + { &rAMC_PSQWQSCHCRD, 0x001014f5 }, // write credits = 1/2 * read credits + { &rAMC_MCUQOS, 0x00010f04 }, // RTG=4, RTY=15, enable pick-oldest-RTY + { &rAMC_PWRMNGTPARAM, 0x03001000 }, // SelfRef timer = 384 cycles + + // Platform specific + + { &rAMC_AIU_RDMAXCRD, 0x3012097f }, // RT:NRT:CPU:GFX = 48:18:09:MAX + { &rAMC_AIU_RDREFL, 0x280f087f }, // 5/6 of AIURDMAXCRD fields + { &rAMC_AIU_WRMAXCRD, 0x3012097f }, // RT:NRT:CPU:GFX = 48:18:09:MAX + { &rAMC_AIU_WRREFL, 0x280f087f }, // 5/6 of AIUWRMAXCRD fields + + { &rAMC_AIU_ADDRBANKHASH0, 0x00006db6 }, // Enable bank hashing, bank[0] derived from bits 0,3,6,.. + { &rAMC_AIU_ADDRBANKHASH1, 0x00005b6d }, // Enable bank hashing, bank[1] derived from bits 1,4,7,.. + { &rAMC_AIU_ADDRBANKHASH2, 0x000036db }, // Enable bank hashing, bank[2] derived from bits 2,5,8,.. + { &rAMC_AIU_CHNLCRD, 0x00180018 }, + { &rAMC_AIU_LLTSCHCTL, 0x00000001 }, // Ensure LLT traffic from all ports is treated as medium priority request in the AIU arbitration + { &rAMC_MCUQOSLLT, 0x00010108 }, + + { &rAMC_AIU_CHNLTM, 0x40006101 }, + { &rAMC_AIU_WPQSCH, 0x08000800 }, // set starvation counts to 8 + { &rAMC_PSQRQCTL1, 0x0000132a }, + { &rAMC_PSQWQCTL0, 0x00010100 }, // enable write merging + { &rAMC_PSQWQCTL1, 0x00000180 }, // ages write out faster than default (1/2 SelfRef) +}; +#endif diff --git a/platform/s5l8950x/include/platform/ampconfig.h b/platform/s5l8950x/include/platform/ampconfig.h new file mode 100644 index 0000000..309559f --- /dev/null +++ b/platform/s5l8950x/include/platform/ampconfig.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amp/amp.h, and this + * file should only by included from that amp.c. + */ + +#if WITH_TARGET_AMP_PARAMS +#include +#else +static const struct amp_params amc_phy_params = { + .flags = (FLAG_AMP_PARAM_SUPPORT_FMCLK_OFF | FLAG_AMP_PARAM_FULLDIFFMODE), + .freq = { + { + .scl = 0x08, + .rdcapcfg = 0x00010308, + }, + { + .scl = 0x0b, + .rdcapcfg = 0x00010306, + }, + { + .scl = 0x16, + .rdcapcfg = 0x00010303, + }, + { + .scl = 0x3f, + .rdcapcfg = 0x00010301, + }, + }, +}; +#endif diff --git a/platform/s5l8950x/include/platform/gpiodef.h b/platform/s5l8950x/include/platform/gpiodef.h new file mode 100644 index 0000000..404ead7 --- /dev/null +++ b/platform/s5l8950x/include/platform/gpiodef.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* S5L8950X specific gpio -> pin mappings */ + +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_IIC0_SCL GPIO( 7, 3) +#define GPIO_IIC0_SDA GPIO( 7, 2) +#define GPIO_IIC1_SCL GPIO( 7, 5) +#define GPIO_IIC1_SDA GPIO( 7, 4) +#define GPIO_IIC2_SCL GPIO(11, 1) +#define GPIO_IIC2_SDA GPIO(11, 0) + +#define GPIO_BOARD_ID0 GPIO( 6, 2) +#define GPIO_BOARD_ID1 GPIO( 6, 3) +#define GPIO_BOARD_ID2 GPIO( 6, 4) +#define GPIO_BOARD_ID3 GPIO( 2, 0) + +#define GPIO_BOOT_CONFIG0 GPIO( 2, 2) +#define GPIO_BOOT_CONFIG1 GPIO(25, 5) +#define GPIO_BOOT_CONFIG2 GPIO(26, 0) +#define GPIO_BOOT_CONFIG3 GPIO(26, 1) + +#define GPIO_REQUEST_DFU1 GPIO( 0, 1) // formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 0, 0) // formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO(25, 6) +#define GPIO_DFU_STATUS GPIO(25, 7) + +#define SPI_NOR0 (0) +#define SPI_NOR3 (3) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#define GPIO_SPI3_CS GPIO(GPIO_PAD_SPI, 3) +#else +#define GPIO_SPI0_CS GPIO( 6, 5) +#define GPIO_SPI3_CS GPIO(10, 7) +#endif + +#define GPIO_UART1_TXD GPIO( 3, 0) + +#define GPIO_SYSTEM_RESET GPIO(12, 2) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s5l8950x/include/platform/image_devices.h b/platform/s5l8950x/include/platform/image_devices.h new file mode 100644 index 0000000..1267a5b --- /dev/null +++ b/platform/s5l8950x/include/platform/image_devices.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_firmware", 0x00000 } +#else +#if defined(WITH_SW_H2FMI) + { "sw-h2fmi", 0x0000 } +#else + { "nor0", 0x00000 } +#endif +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s5l8950x/include/platform/memconfig.h b/platform/s5l8950x/include/platform/memconfig.h new file mode 100644 index 0000000..02271bb --- /dev/null +++ b/platform/s5l8950x/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* S5L8950X SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/s5l8950x/include/platform/memmap.h b/platform/s5l8950x/include/platform/memmap.h new file mode 100644 index 0000000..00ba178 --- /dev/null +++ b/platform/s5l8950x/include/platform/memmap.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* S5L8950X specific memory map */ +#define SDRAM_BASE (0x80000000ULL) +#define SDRAM_BANK_LEN (0x20000000ULL) +#define SDRAM_BANK_COUNT (2) +#define SDRAM_END (SDRAM_BASE + (SDRAM_BANK_LEN * SDRAM_BANK_COUNT)) +#define VROM_BASE (0x3F000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00010000ULL) +#define SRAM_BASE (0x10000000ULL) +#define SRAM_BANK_LEN (0x00100000ULL) +#define SRAM_LEN (0x00080000ULL) + +/* Sleep token is stored at first physical page in kernel memory */ +#define SLEEP_TOKEN_BUFFER_BASE (SDRAM_BASE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00004000ULL) +#define PANIC_BASE (SDRAM_END - PANIC_SIZE) + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x00100000 - PANIC_SIZE) +#define IBOOT_BASE (PANIC_BASE - IBOOT_SIZE) +#define PROTECTED_REGION_SIZE IBOOT_SIZE + +/* reserved area for display */ +#define DISPLAY_SIZE (0x00F00000ULL) +#define DISPLAY_BASE (IBOOT_BASE - DISPLAY_SIZE) + +/* where to stick the mmu tt, default heap and insecure memory*/ +#if APPLICATION_SECUREROM +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (SRAM_BASE + SRAM_LEN - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN) + +#define STACK_SIZE (0x3000ULL) +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#ifndef __ASSEMBLY__ + +#define INSECURE_MEMORY_BASE (SRAM_BASE) +#define INSECURE_MEMORY_SIZE ((uintptr_t)__segment_start(__DATA) - INSECURE_MEMORY_BASE) + +#endif /* ! __ASSEMBLY__ */ + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (TEXT_BASE + TEXT_FOOTPRINT - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN * 3) +#define MMU_NONCACHE1_SIZE (0x40000000ULL) +#define MMU_NONCACHE1_PBASE (0x80000000ULL) +#define MMU_NONCACHE1_VBASE (0xC0000000ULL) + +#if WITH_DFU_MODE +#define STACK_SIZE (0x3000ULL) + +#define INSECURE_MEMORY_SIZE (0x00200000ULL) +#define INSECURE_MEMORY_BASE (SDRAM_BASE + SDRAM_BANK_LEN - INSECURE_MEMORY_SIZE) + +#define HEAP_EXT_SIZE (0x00100000ULL) +#define HEAP_EXT_BASE (INSECURE_MEMORY_BASE - HEAP_EXT_SIZE) + +#else /* !WITH_DFU_MODE */ +#define STACK_SIZE (0x1000ULL) + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_KERNEL_ADDRESS - SDRAM_BASE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +/* If only 1 bank is populated, this only clears to the alias of + * DISPLAY_BASE in the first bank. If 2 banks are populated, this + * clears all the was to DISPLAY_BASE in the second bank. */ +#define SECURE_MEMORY_SIZE (DISPLAY_BASE - SECURE_MEMORY_BASE - SDRAM_BANK_LEN * 2 + platform_get_memory_size()) + +#define HEAP_EXT_BASE (DEFAULT_FREE_ADDRESS) +#define HEAP_EXT_SIZE (DISPLAY_BASE - SDRAM_BANK_LEN - HEAP_EXT_BASE) +#endif /* !WITH_DFU_MODE */ + +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_EMBEDDEDIOP +# if ARCH_ARMv7 +# define MMU_TT_SIZE (0x4000ULL) +# endif + +/* We use the SRAM in the AE2 block on AE2 targets. */ +#ifdef SRAM_BASE +#undef SRAM_BASE +#endif +#define SRAM_BASE (0x34000000ULL) + +#ifdef SRAM_BANK_LEN +#undef SRAM_BANK_LEN +#endif +#define SRAM_BANK_LEN (0x00100000ULL) + +#ifdef SRAM_LEN +#undef SRAM_LEN +#endif +#define SRAM_LEN (0x00040000ULL) + +#define AUDIO_SRAM_RESERVE (0x1000ULL) +#define USB_SRAM_RESERVE (0x10000ULL) + +#if TARGET_S5L8950XAE2 +#define HEAP_EXT_BASE (SRAM_BASE + AUDIO_SRAM_RESERVE) +#define HEAP_EXT_SIZE (SRAM_LEN - AUDIO_SRAM_RESERVE - USB_SRAM_RESERVE) +#endif /* TARGET_S5L8950XAE2 */ + +#endif /* !APPLICATION_EMBEDDEDIOP */ + +#define SCRATCH_BASE (0x33600000ULL) +#define SCRATCH_LEN (2048) + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s5l8950x/include/platform/pinconfig.h b/platform/s5l8950x/include/platform/pinconfig.h new file mode 100644 index 0000000..ee4d8a8 --- /dev/null +++ b/platform/s5l8950x/include/platform/pinconfig.h @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default S5L8950X SoC Pin Configuration */ + +#define FMI_DRIVE_STR DRIVE_X2 | SLOW_SLEW + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 1 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // EHCI_PORT_PWR[0] -> + CFG_DISABLED, // EHCI_PORT_PWR[1] -> + CFG_DISABLED, // EHCI_PORT_PWR[2] -> + CFG_DISABLED, // EHCI_PORT_PWR[3] -> + +/* Port 3 */ + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + +/* Port 4 */ + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART4_TXD/SPI4_MOSI -> + CFG_DISABLED, // UART4_RXD/SPI4_MISO -> + CFG_DISABLED, // UART4_RTSN/SPI4_SCLK -> + CFG_DISABLED, // UART4_CTSN/SPI4_SSIN -> + +/* Port 5 */ + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // UART6_RTSN -> + CFG_DISABLED, // UART6_CTSN -> + CFG_DISABLED, // UART5_RXD/UART5_RTXD -> + CFG_DISABLED, // UART5_TXD -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + +/* Port 6 */ + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> SPI0_SSIN + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 7 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + +/* Port 8 */ + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // MIPI_VSYNC -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // SWI_DATA -> + CFG_DISABLED, // DWI_DI -> + +/* Port 9 */ + CFG_DISABLED, // DWI_DO -> + CFG_DISABLED, // DWI_CLK -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_FUNC0, // CPU0_SWITCH -> + CFG_FUNC0, // CPU1_SWITCH -> + +/* Port 10 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + +/* Port 11 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // GPIO_3V0 -> + CFG_DISABLED, // GPIO_3V1 -> + CFG_DISABLED, // DP_HPD -> + CFG_DISABLED, // LPDP_HPD -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + +/* Port 12 */ + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 13 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + +/* Port 17 */ + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> + +/* Port 18 */ + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // I2S4_MCK -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + CFG_DISABLED, // I2S4_DOUT -> + +/* Port 19 */ + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // SPDIF -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_ALE -> + +/* Port 20 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_REN -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_WENN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_DQS -> + +/* Port 21 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI0_DQSN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN7 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN6 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN5 -> + +/* Port 22 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN4 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_REN -> + +/* Port 23 */ + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_WENN -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_DQS -> + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // FMI1_DQSN -> + +/* Port 24 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO2 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN7 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN6 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN5 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN4 -> + +/* Port 25 */ + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + +/* Port 26 */ + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 27 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 28 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // GPIO39 -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s5l8950x/include/platform/soc/chipid.h b/platform/s5l8950x/include/platform/soc/chipid.h new file mode 100644 index 0000000..aa95dfd --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/chipid.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include + +#define rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCFG_FUSE1 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCFG_FUSE2 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rCFG_FUSE3 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x0C)) +#define rCFG_FUSE4 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x10)) +#define rCFG_FUSE5 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x14)) + +#define rECIDLO (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x20)) +#define rECIDHI (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x24)) + +#define rDVFM_FUSE(n) (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x40 + (n) * 4)) + +#define rSCC_FUSE(n) (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x80 + (n) * 4)) + +extern bool chipid_get_ecid_image_personalization_required(void); + +#define CHIPID_SOC_VOLTAGE_COUNT (3) +#define CHIPID_SOC_VOLTAGE_LOW (0) +#define CHIPID_SOC_VOLTAGE_MED (1) +#define CHIPID_SOC_VOLTAGE_HIGH (2) +extern u_int32_t chipid_get_soc_voltage(u_int32_t index); + +#define CHIPID_CPU_VOLTAGE_COUNT (8) +extern u_int32_t chipid_get_cpu_voltage(u_int32_t index); + +#define CHIPID_RAM_VOLTAGE_COUNT (2) +#define CHIPID_RAM_VOLTAGE_LOW (0) +#define CHIPID_RAM_VOLTAGE_HIGH (1) +extern u_int32_t chipid_get_ram_voltage(u_int32_t index); + +extern int32_t chipid_get_cpu_temp_offset(u_int32_t cpu_number); + +extern u_int32_t chipid_get_fused_thermal_sensor_70C(u_int32_t sensorID); +extern u_int32_t chipid_get_fused_thermal_sensor_25C(u_int32_t sensorID); +extern u_int32_t chipid_get_fuse_revision(void); +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s5l8950x/include/platform/soc/display.h b/platform/s5l8950x/include/platform/soc/display.h new file mode 100644 index 0000000..22d95c5 --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/display.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables +static struct adfe_v1_tuneable adfe_tuneables[] = +{ + { + .name = "default", + .disp_dpcclkcntl[0] = 0, + .disp_dpbclklvl_clock_off_level[0] = DPBCLKLVL_OFFLVL(0x03F8), + .disp_dpbclklvl_clock_on_level[0] = DPBCLKLVL_ONLVL(0x0200), + .disp_dpusrcstrd[0] = DPUSRCSTRD_SRCBURST_8BLOCKS, + .disp_dpcqoscnfg[0] = (DPCQOSCNFG_QOS_TIMER(0x0040) | \ + DPCQOSCNFG_UIFIFO_ENABLE | \ + DPCQOSCNFG_VIDFIFO_ENABLE | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[0] = DPBQOSLVL_MED_WATERMARK(0x0180), + .disp_dpbqoslvl_high_watermark[0] = DPBQOSLVL_HIGH_WATERMARK(0x00C0), + .disp_dpureqcfg[0] = 0, + + .disp_dpcclkcntl[1] = 0, + .disp_dpbclklvl_clock_off_level[1] = DPBCLKLVL_OFFLVL(0x03F8), + .disp_dpbclklvl_clock_on_level[1] = DPBCLKLVL_ONLVL(0x03C0), + .disp_dpusrcstrd[1] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpcqoscnfg[1] = (DPCQOSCNFG_QOS_TIMER(0x2000) | \ + DPCQOSCNFG_UIFIFO_ENABLE | \ + DPCQOSCNFG_VIDFIFO_ENABLE | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[1] = DPBQOSLVL_MED_WATERMARK(0x0280), + .disp_dpbqoslvl_high_watermark[1] = DPBQOSLVL_HIGH_WATERMARK(0x0190), + .disp_dpureqcfg[1] = 0, + }, +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/s5l8950x/include/platform/soc/display_timings.h b/platform/s5l8950x/include/platform/soc/display_timings.h new file mode 100644 index 0000000..cc77a24 --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/display_timings.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_N41 || SUB_TARGET_N42 || SUB_TARGET_N48 || SUB_TARGET_N49 + { + .display_name = "n41", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 68400000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 40, + .h_back_porch = 40, + .h_front_porch = 40, + .v_active = 1136, + .v_pulse_width = 3, + .v_back_porch = 13, + .v_front_porch = 348, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, // mipi_dsi_clk @ 513MHz, 4-lane +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/s5l8950x/include/platform/soc/hwclocks.h b/platform/s5l8950x/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..20bd02e --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/hwclocks.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (10000000UL) +#else +#define OSC_FREQ (24000000UL) +#endif + +#define CLK_FCLK (HWCLOCK_BASE+0) +#define CLK_ACLK (HWCLOCK_BASE+1) +#define CLK_HCLK (HWCLOCK_BASE+2) +#define CLK_PCLK (HWCLOCK_BASE+3) +#define CLK_VCLK0 (HWCLOCK_BASE+4) +#define CLK_VCLK1 (HWCLOCK_BASE+5) +#define CLK_MCLK (HWCLOCK_BASE+6) +#define CLK_NCLK (HWCLOCK_BASE+7) +#define CLK_USBPHYCLK (HWCLOCK_BASE+8) +#define CLK_NCOREF (HWCLOCK_BASE+9) +#define CLK_FMI (HWCLOCK_BASE+10) + +/* S5L8950X clock gate devices */ +enum { + CLK_rsvd0 = 0, + CLK_SCC, + CLK_CPU0, + CLK_CPU1, + CLK_L2_BIU, + CLK_L2, + CLK_rsvd1, + CLK_rsvd2, + CLK_MCU, + CLK_GFX_SYS, + CLK_GFX_CORES, + CLK_HPERFNRT, + CLK_VDEC, + CLK_SCALER0, + CLK_SCALER1, + CLK_JPG0, + CLK_JPG1, + CLK_rsvd3, + CLK_VENC, + CLK_HPERFRT, + CLK_ISP, + CLK_LPDP, + CLK_DISP0, + CLK_DISP1, + CLK_DISPOUT, + CLK_MIPI, + CLK_CLCD, + CLK_TVDAC, + CLK_RGBOUT, + CLK_DPLINK, + CLK_CDIO, + CLK_CDMA, + CLK_IOP, + CLK_UPERF, + CLK_USBOTG, + CLK_USB20, + CLK_USB11, + CLK_USBOHCI0, + CLK_USBOHCI1, + CLK_USBPHY, + CLK_AUDIO, + CLK_I2S0, + CLK_I2S1, + CLK_I2S2, + CLK_I2S3, + CLK_SPDIF, + CLK_ADSP, + CLK_SDIO, + CLK_SHA1, + CLK_SHA2, + CLK_FMI0, + CLK_FMI0BCH, + CLK_FMI1, + CLK_FMI1BCH, + CLK_FMI_DLL, + CLK_XMBIST, + CLK_MCA, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_SPI4, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_PKE, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_PWM, + CLK_SCRT, + CLK_GPIO, + CLK_SWI, + CLK_DWI, + CLK_DEBUG, + CLK_AIC, +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s5l8950x/include/platform/soc/hwdmachannels.h b/platform/s5l8950x/include/platform/soc/hwdmachannels.h new file mode 100644 index 0000000..5f28d38 --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/hwdmachannels.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_H +#define __PLATFORM_SOC_HWDMACHANNELS_H + +#define DMA_MEMORY_TX (1) +#define DMA_MEMORY_RX (2) +#define DMA_SDIO (3) +#define DMA_FMI0DATA (5) +#define DMA_FMI0CHECK (6) +#define DMA_FMI1DATA (7) +#define DMA_FMI1CHECK (8) + +#define DMA_CHANNEL_COUNT (44) + +#define DMA_CHANNEL_CONFIG \ +{ \ + /* low high AES OK reqID FIFO address */ \ + { 3, 4, false, 0x00, 0x30000020 }, \ + { 3, 4, false, 0x01, 0x301000A0 }, \ + { 3, 4, false, 0x01, 0x30200020 }, \ + { 5, 8, true, 0x00, 0x31200014 }, \ + { 5, 8, true, 0x01, 0x31200018 }, \ + { 5, 8, true, 0x02, 0x31300014 }, \ + { 5, 8, true, 0x03, 0x31300018 }, \ +} + + +#define DMA_SDIO_TIMEOUT_US (10 * 1000) + + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_H */ diff --git a/platform/s5l8950x/include/platform/soc/hwisr.h b/platform/s5l8950x/include/platform/soc/hwisr.h new file mode 100644 index 0000000..95219fb --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/hwisr.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_SWI 5 // SWI Interrupt +#define INT_DWI 6 // DWI Interrupt +#define INT_ISP0 7 // ISP 0 Interrupt +#define INT_ISP1 8 // ISP 1 Interrupt +#define INT_SCALER0 9 // Scaler Interrupt +#define INT_SCALER1 10 // Scaler Interrupt +#define INT_USB_OTG 11 // USB OTG Interrupt +#define INT_USB_EHCI 12 // USB EHCI Interrupt +#define INT_USB_OHCI0 13 // USB OHCI 0 Interrupt +#define INT_USB_OHCI1 14 // USB OHCI 1 Interrupt +#define INT_USB_RES 15 // USB PHY Interrupt +#define INT_PWM 16 // PWM Interrupt +#define INT_PKE 17 // PKE Interrupt +#define INT_IIC0 18 // I2C 0 Interrupt +#define INT_IIC1 19 // I2C 1 Interrupt +#define INT_IIC2 20 // I2C 2 Interrupt +#define INT_UART0 21 // UART 0 Interrupt +#define INT_UART1 22 // UART 1 Interrupt +#define INT_UART2 23 // UART 2 Interrupt +#define INT_UART3 24 // UART 3 Interrupt +#define INT_UART4 25 // UART 4 Interrupt +#define INT_UART5 26 // UART 5 Interrupt +#define INT_UART6 27 // UART 6 Interrupt +#define INT_SPI0 28 // SPI 0 Interrupt +#define INT_SPI1 29 // SPI 1 Interrupt +#define INT_SPI2 30 // SPI 2 Interrupt +#define INT_SPI3 31 // SPI 3 Interrupt +#define INT_SPI4 32 // SPI 4 Interrupt +#define INT_FMI0 33 // FMI 0 Interrupt +#define INT_FMI1 34 // FMI 1 Interrupt + +// Reserved 35 - 36 + +#define INT_SHA1 37 // SHA-1 Interrupt +#define INT_SHA2 38 // SHA-1 Interrupt +#define INT_WIFI 39 // WiFi Interrupt +#define INT_TVOUT 40 // TV Out Interrupt + +// Reserved 41 + +#define INT_CLCD 42 // CLCD Interrupt +#define INT_DISP0 43 // Display Pipe 0 Interrupt +#define INT_DISP1 44 // Display Pipe 1 Interrupt +#define INT_RGBOUT 45 // RGB Out Interrupt +#define INT_DPORT0 46 // DisplayPort 0 Interrupt +#define INT_DPORT1 47 // DisplayPort 1 Interrupt +#define INT_VENC 48 // Video Encoder Interrupt +#define INT_SGX 49 // SGX Interrupt +#define INT_VDEC 50 // Video Decoder Interrupt +#define INT_CDMA_DMAC1 51 // CDMA DMA Channel 1 Interrupt +#define INT_CDMA_DMAC2 52 // CDMA DMA Channel 2 Interrupt +#define INT_CDMA_DMAC3 53 // CDMA DMA Channel 3 Interrupt +#define INT_CDMA_DMAC4 54 // CDMA DMA Channel 4 Interrupt +#define INT_CDMA_DMAC5 55 // CDMA DMA Channel 5 Interrupt +#define INT_CDMA_DMAC6 56 // CDMA DMA Channel 6 Interrupt +#define INT_CDMA_DMAC7 57 // CDMA DMA Channel 7 Interrupt +#define INT_CDMA_DMAC8 58 // CDMA DMA Channel 8 Interrupt +#define INT_CDMA_DMAC9 59 // CDMA DMA Channel 9 Interrupt +#define INT_CDMA_DMAC10 60 // CDMA DMA Channel 10 Interrupt +#define INT_CDMA_DMAC11 61 // CDMA DMA Channel 11 Interrupt +#define INT_CDMA_DMAC12 62 // CDMA DMA Channel 12 Interrupt +#define INT_CDMA_DMAC13 63 // CDMA DMA Channel 13 Interrupt +#define INT_CDMA_DMAC14 64 // CDMA DMA Channel 14 Interrupt +#define INT_CDMA_DMAC15 65 // CDMA DMA Channel 15 Interrupt +#define INT_CDMA_DMAC16 66 // CDMA DMA Channel 16 Interrupt +#define INT_CDMA_DMAC17 67 // CDMA DMA Channel 17 Interrupt +#define INT_CDMA_DMAC18 68 // CDMA DMA Channel 18 Interrupt +#define INT_CDMA_DMAC19 69 // CDMA DMA Channel 19 Interrupt +#define INT_CDMA_DMAC20 70 // CDMA DMA Channel 20 Interrupt +#define INT_CDMA_DMAC21 71 // CDMA DMA Channel 21 Interrupt +#define INT_CDMA_DMAC22 72 // CDMA DMA Channel 22 Interrupt +#define INT_CDMA_DMAC23 73 // CDMA DMA Channel 23 Interrupt +#define INT_CDMA_DMAC24 74 // CDMA DMA Channel 24 Interrupt +#define INT_CDMA_DMAC25 75 // CDMA DMA Channel 25 Interrupt +#define INT_CDMA_DMAC26 76 // CDMA DMA Channel 26 Interrupt +#define INT_CDMA_DMAC27 77 // CDMA DMA Channel 27 Interrupt +#define INT_CDMA_DMAC28 78 // CDMA DMA Channel 28 Interrupt +#define INT_CDMA_DMAC29 79 // CDMA DMA Channel 29 Interrupt +#define INT_CDMA_DMAC30 80 // CDMA DMA Channel 30 Interrupt +#define INT_CDMA_DMAC31 81 // CDMA DMA Channel 31 Interrupt +#define INT_CDMA_DMAC32 82 // CDMA DMA Channel 32 Interrupt +#define INT_CDMA_DMAC33 83 // CDMA DMA Channel 33 Interrupt +#define INT_CDMA_DMAC34 84 // CDMA DMA Channel 34 Interrupt +#define INT_CDMA_DMAC35 85 // CDMA DMA Channel 35 Interrupt +#define INT_CDMA_DMAC36 86 // CDMA DMA Channel 36 Interrupt +#define INT_CDMA_DMAC37 87 // CDMA DMA Channel 37 Interrupt +#define INT_CDMA_DMAC38 88 // CDMA DMA Channel 38 Interrupt +#define INT_CDMA_DMAC39 89 // CDMA DMA Channel 39 Interrupt +#define INT_CDMA_DMAC40 90 // CDMA DMA Channel 40 Interrupt +#define INT_CDMA_DMAC41 91 // CDMA DMA Channel 41 Interrupt +#define INT_CDMA_DMAC42 92 // CDMA DMA Channel 42 Interrupt +#define INT_CDMA_DMAC43 93 // CDMA DMA Channel 43 Interrupt + +// Reserved 94 - 96 + +// Audio and Highland Park Interrupts 97 - 115 + +#define INT_AUDIO_CPU_IRQ0 97 // +#define INT_AUDIO_CPU_IRQ1 98 // + +#define INT_ADSP_F0 112 // DSP +#define INT_ADSP_F1 113 // DSP +#define INT_ADSP_T0 114 // DSP +#define INT_ADSP_T1 115 // DSP + +#define INT_HPERFNRT_DART 116 // HPerf-NRT DART Interrupt +#define INT_HPERFRT_DART 117 // HPerf-RT DART Interrupt +#define INT_JPEG0 118 // JPEG 0 Interrupt +#define INT_GPIO0 119 // GPIO 0 Interrupt +#define INT_GPIO1 120 // GPIO 1 Interrupt +#define INT_MCU 121 // MCU Interrupt +#define INT_MCU0 122 // MCU Phy 0 Interrupt +#define INT_MCU1 123 // MCU Phy 1 Interrupt +#define INT_PIO0 124 // PIO 0 Interrupt +#define INT_PIO1 125 // PIO 1 Interrupt +#define INT_JPEG1 126 // JPEG 1 Interrupt +#define INT_IOP_COMMRX 127 // IOP CommRx Interrupt +#define INT_IOP_COMMTX 128 // IOP CommTx Interrupt +#define INT_IOP_PMI 129 // IOP PerfMon Interrupt +#define INT_IOP_CTIIRQ 130 // IOP CTIIRQ Interrupt +#define INT_ISP_COMMRX 131 // IOP CommRx Interrupt +#define INT_ISP_COMMTX 132 // IOP CommTx Interrupt +#define INT_ISP_PMI 133 // IOP PerfMon Interrupt +#define INT_ISP_CTIIRQ 134 // IOP CTIIRQ Interrupt + +// Reserved 135 - 136 + +#define INT_CPU0_COMMRX 137 // IOP CommRx Interrupt +#define INT_CPU0_COMMTX 138 // IOP CommTx Interrupt + +// Reserved 139 - 140 + +#define INT_CPU1_COMMRX 141 // IOP CommRx Interrupt +#define INT_CPU1_COMMTX 142 // IOP CommTx Interrupt + +// Reserved 143 + +#define INT_LPDP 144 // Low Power Display Port Interrupt + +// Reserved 145 - 149 + +#define INT_MCU2 150 // MCU Phy 2 Interrupt +#define INT_MCU3 151 // MCU Phy 3 Interrupt +#define INT_PMGR_PMI 152 // PMGR PerfMon Interrupt +#define INT_HPERFNTR_PMI 153 // HPerf-NRT PerfMon Interrupt +#define INT_HPERFRT_PMI 154 // HPerf-RT PerfMon Interrupt +#define INT_DPIPE0_PMI 155 // Display Pipe 0 PerfMon Interrupt +#define INT_DPIPE1_PMI 156 // Display Pipe 1 PerfMon Interrupt + +// Reserved 157 - 159 + +#define INT_ETB_FULL 160 // ETB Full Interrupt + +// Reserved 161 + +#define INT_CPU0_VTIMER 162 // CPU 0 Virtual Timer Interrupt +#define INT_CPU0_DEBUG 163 // CPU 0 Debug Interrupt + +// Reserved 164 + +#define INT_CPU1_VTIMER 165 // CPU 1 Virtual Timer Interrupt +#define INT_CPU1_DEBUG 166 // CPU 1 Debug Interrupt + +// Reserved 167 + +#define INT_MCA 168 // Multi-Channel Audio Interrupt +#define INT_KEYGEN 169 // CDMA Keygen Interrupt +#define INT_THERM_ALARM0 170 // Thermal Alarm 0 Interrupt +#define INT_THERM_ALARM1 171 // Thermal Alarm 1 Interrupt +#define INT_THERM_TEMP0 172 // Thermal Temp 0 Interrupt +#define INT_THERM_TEMP1 173 // Thermal Temp 1 Interrupt + +// Reserved 174 - 191 + +#if PLATFORM_VARIANT_IOP + +#include + +#define INT_HOST INT_SW2 // Host processor doorbell +#define INT_IOP INT_SW3 // I/O coprocessor doorbell +#define INT_IOP_NMI kAIC_VEC_SW_TMR // I/O coprocessor NMI + +#elif PLATFORM_VARIANT_AUDIO + +#include + +#define INT_HOST AE2_INT_SW0 // Host processor doorbell +#define INT_IOP AE2_INT_SW0 // I/O coprocessor doorbell +#define INT_IOP_NMI AE2_INT_SW1 // I/O coprocessor NMI + +#endif + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s5l8950x/include/platform/soc/hwregbase.h b/platform/s5l8950x/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..c627989 --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/hwregbase.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#define AIC_VERSION 0 +#define AIC_INT_COUNT (192) +#define PMGR_WDG_VERSION 0 + +/* S5L8950X Reg Base Defs */ + +#define SDIO_BASE_ADDR (0x30000000) + +#define SHA1_BASE_ADDR (0x30100000) +#define SHA2_BASE_ADDR (0x30200000) + +#define NAND_DLL_BASE_ADDR (0x31000000) +#define FMI0_BASE_ADDR (0x31200000) +#define FMI1_BASE_ADDR (0x31300000) +#define FMI_VERSION (5) + +#define SPI0_BASE_ADDR (0x32000000) +#define SPI1_BASE_ADDR (0x32100000) +#define SPI2_BASE_ADDR (0x32200000) +#define SPI3_BASE_ADDR (0x32300000) +#define SPI4_BASE_ADDR (0x32400000) +#define SPI_VERSION (1) +#define SPIS_COUNT (5) + +#define UART0_BASE_ADDR (0x32500000) +#define UART1_BASE_ADDR (0x32600000) +#define UART2_BASE_ADDR (0x32700000) +#define UART3_BASE_ADDR (0x32800000) +#define UART4_BASE_ADDR (0x32900000) +#define UART5_BASE_ADDR (0x32A00000) +#define UART6_BASE_ADDR (0x32B00000) +#define UART_VERSION (1) +#define UARTS_COUNT (7) + +#define PKE_BASE_ADDR (0x33100000) + +#define IIC_BASE_ADDR (0x33200000) +#define IIC_SPACING (0x00100000) +#define IICS_COUNT (3) + +#define AUDIO_BASE_ADDR (0x34000000) + +#define USBPHY_BASE_ADDR (0x36000000) +#define USBPHY_VERSION (4) +#define USBOTG_BASE_ADDR (0x36100000) +#define UPERF_WIDGETS_BASE_ADDR (0x36E00000) +#define UPERF_PL301_BASE_ADDR (0x36F00000) + +#define CDMA_BASE_ADDR (0x37000000) +#define CDMA_VERSION 5 + +#define VENC_BASE_ADDR (0x38000000) + +#define VDEC_BASE_ADDR (0x38100000) + +#define JPEG0_BASE_ADDR (0x38200000) +#define JPEG1_BASE_ADDR (0x38500000) + +#define SCALER_BASE_ADDR (0x38300000) +#define SCALER_SPACING (0x00100000) + +#define NRT_DART_BASE_ADDR (0x38B00000) + +#define NRT_DART_WIDGETS_BASE_ADDR (0x38C00000) +#define NRT_DART_PL301_BASE_ADDR (0x38D00000) + +#define NRT_TOP_WIDGETS_BASE_ADDR (0x38E00000) +#define NRT_TOP_PL301_BASE_ADDR (0x38F00000) + +#define CLCD_BASE_ADDR (0x39200000) +#define CLCD_VERSION (1) +#define DITHER_VERSION (1) + +#define DITHER0_BASE_ADDR (0x39300000) + +#define TVOUT_BASE_ADDR (0x39400000) + +#define DSIM_BASE_ADDR (0x39500000) +#define DSIM_LANE_COUNT (4) +#define DSIM_VERSION (1) + +#define RGBOUT_BASE_ADDR (0x39600000) + +#define DP_BASE_ADDR (0x39700000) +#define DISPLAYPORT_VERSION (1) + +#define DITHER1_BASE_ADDR (0x39800000) + +#define LPDP_BASE_ADDR (0x39900000) + +#define ISP_BASE_ADDR (0x3A000000) + +#define DISP0_BASE_ADDR (0x3A100000) +#define DISP1_BASE_ADDR (0x3A200000) +#define CLCD_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define RGBOUT_DISPLAYPIPE_BASE_ADDR (DISP1_BASE_ADDR) +#define DISP_VERSION (3) + +#define RT_DART_BASE_ADDR (0x3A400000) + +#define RT_TOP_WIDGETS_BASE_ADDR (0x3A500000) +#define RT_TOP_PL301_BASE_ADDR (0x3A600000) + +#define ADSP_BASE_ADDR (0x3B000000) + +#define AMP_BASE_ADDR (0x3D000000) +#define AMP_SPACING (0x00100000) + +#define SCC_BASE_ADDR (0x3D200000) + +#define PMGR_BASE_ADDR (0x3F100000) + +#define AIC_BASE_ADDR (0x3F200000) + +#define IOP_BASE_ADDR (0x3F300000) + +#define ROSC_BASE_ADDR (0x3F400000) +#define ROSC_MASK (0x57FF) +#define ROSC_WITH_CLOCK (0) + +#define CHIPID_BASE_ADDR (0x3F500000) + +#define SWI_BASE_ADDR (0x3F600000) +#define DWI_BASE_ADDR (0x3F700000) + +#define AMC_BASE_ADDR (0x3F800000) + +#define GPIO_BASE_ADDR (0x3FA00000) +#define GPIO_VERSION (2) +#define GPIO_GROUP_COUNT (29) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define PIO_BASE_ADDR (0x3FB00000) +#define PIO_SPACING (0x00100000) + +#define CIM_BASE_ADDR (0x3FD00000) + +#define CDIO_WIDGETS_BASE_ADDR (0x3FE00000) +#define CDIO_PL301_BASE_ADDR (0x3FF00000) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s5l8950x/include/platform/soc/miu.h b/platform/s5l8950x/include/platform/soc/miu.h new file mode 100644 index 0000000..c404b64 --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/miu.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rREMAP_CTL (*(volatile u_int32_t *)(PIO_BASE_ADDR + 0x0000)) + +#define rCIM_TID_DEST_CONFIG(n) (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x000 + (n) * 4)) +#define rCIM_CONFIG_REG (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x040) +#define rCIM_STATUS_REG0 (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x044) +#define rCIM_STATUS_REG1 (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x048) + +#define CDIO_IOP_RRLIMIT (0x0000) +#define rCDIO_IOP_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RRLIMIT)) +#define CDIO_IOP_WRLIMIT (0x0004) +#define rCDIO_IOP_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WRLIMIT)) +#define CDIO_IOP_RTLIMIT (0x0008) +#define rCDIO_IOP_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RTLIMIT)) +#define CDIO_IOP_WTLIMIT (0x000C) +#define rCDIO_IOP_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WTLIMIT)) +#define CDIO_IOP_WGATHER (0x0010) +#define rCDIO_IOP_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WGATHER)) +#define CDIO_IOP_C_REMAP_EN (0x001C) +#define rCDIO_IOP_C_REMAP_EN (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_C_REMAP_EN)) +#define CDIO_IOP_RC_REMAP(n) (0x0020 + ((n) * 4)) +#define rCDIO_IOP_RC_REMAP(n) (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RC_REMAP(n))) +#define CDIO_IOP_WC_REMAP(n) (0x0030 + ((n) * 4)) +#define rCDIO_IOP_WC_REMAP(n) (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WC_REMAP(n))) +#define CDIO_CDMA_RRLIMIT (0x1000) +#define rCDIO_CDMA_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_RRLIMIT)) +#define CDIO_CDMA_WRLIMIT (0x1004) +#define rCDIO_CDMA_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WRLIMIT)) +#define CDIO_CDMA_RTLIMIT (0x1008) +#define rCDIO_CDMA_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_RTLIMIT)) +#define CDIO_CDMA_WTLIMIT (0x100C) +#define rCDIO_CDMA_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WTLIMIT)) +#define CDIO_CDMA_WGATHER (0x1010) +#define rCDIO_CDMA_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WGATHER)) +#define CDIO_UPERF_RRLIMIT (0x2000) +#define rCDIO_UPERF_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_RRLIMIT)) +#define CDIO_UPERF_WRLIMIT (0x2004) +#define rCDIO_UPERF_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WRLIMIT)) +#define CDIO_UPERF_RTLIMIT (0x2008) +#define rCDIO_UPERF_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_RTLIMIT)) +#define CDIO_UPERF_WTLIMIT (0x200C) +#define rCDIO_UPERF_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WTLIMIT)) +#define CDIO_UPERF_WGATHER (0x2010) +#define rCDIO_UPERF_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WGATHER)) +#define CDIO_AUDIO_RRLIMIT (0x3000) +#define rCDIO_AUDIO_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_RRLIMIT)) +#define CDIO_AUDIO_WRLIMIT (0x3004) +#define rCDIO_AUDIO_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WRLIMIT)) +#define CDIO_AUDIO_RTLIMIT (0x3008) +#define rCDIO_AUDIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_RTLIMIT)) +#define CDIO_AUDIO_WTLIMIT (0x300C) +#define rCDIO_AUDIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WTLIMIT)) +#define CDIO_AUDIO_WGATHER (0x3010) +#define rCDIO_AUDIO_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WGATHER)) +#define CDIO_DAP_QOS (0x4014) +#define rCDIO_DAP_QOS (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_DAP_QOS)) +#define CDIO_DAP_CACHE (0x4018) +#define rCDIO_DAP_CACHE (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_DAP_CACHE)) +#define CDIO_PIO_RTLIMIT (0x5008) +#define rCDIO_PIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_RTLIMIT)) +#define CDIO_PIO_WTLIMIT (0x500C) +#define rCDIO_PIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_WTLIMIT)) +#define CDIO_CIM_RTLIMIT (0x6008) +#define rCDIO_CIM_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CIM_RTLIMIT)) +#define CDIO_CIM_WTLIMIT (0x600C) +#define rCDIO_CIM_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CIM_WTLIMIT)) + +#define CDIO_AR_CHAN_ARB_MI0 (0x0408) +#define rCDIO_AR_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI0)) +#define CDIO_AW_CHAN_ARB_MI0 (0x040C) +#define rCDIO_AW_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI0)) +#define CDIO_AR_CHAN_ARB_MI1 (0x0428) +#define rCDIO_AR_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI1)) +#define CDIO_AW_CHAN_ARB_MI1 (0x042C) +#define rCDIO_AW_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI1)) + +#define UPERF_OTG_QOS (0x0014) +#define rUPERF_OTG_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_QOS)) +#define UPERF_OTG_CACHE (0x0018) +#define rUPERF_OTG_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_CACHE)) +#define UPERF_EHCI_QOS (0x0034) +#define rUPERF_EHCI_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_QOS)) +#define UPERF_EHCI_CACHE (0x0038) +#define rUPERF_EHCI_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_CACHE)) +#define UPERF_OHCI0_QOS (0x0054) +#define rUPERF_OHCI0_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_QOS)) +#define UPERF_OHCI0_CACHE (0x0058) +#define rUPERF_OHCI0_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_CACHE)) +#define UPERF_OHCI1_QOS (0x0074) +#define rUPERF_OHCI1_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_QOS)) +#define UPERF_OHCI1_CACHE (0x0078) +#define rUPERF_OHCI1_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_CACHE)) +#define UPERF_RTLIMIT (0x0088) +#define rUPERF_RTLIMIT (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_RTLIMIT)) +#define UPERF_WTLIMIT (0x008C) +#define rUPERF_WTLIMIT (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_WTLIMIT)) + +#define UPERF_AR_CHAN_ARB_MI (0x0408) +#define rUPERF_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(UPERF_PL301_BASE_ADDR + UPERF_AR_CHAN_ARB_MI0)) +#define UPERF_AW_CHAN_ARB_MI (0x040C) +#define rUPERF_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(UPERF_PL301_BASE_ADDR + UPERF_AW_CHAN_ARB_MI0)) + +#define HPERF_NRT_DART_DART_RTLIMIT (0x0000) +#define rHPERF_NRT_DART_DART_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_RTLIMIT)) +#define HPERF_NRT_DART_DART_WTLIMIT (0x0004) +#define rHPERF_NRT_DART_DART_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_WTLIMIT)) +#define HPERF_NRT_DART_DART_WGATHER (0x0010) +#define rHPERF_NRT_DART_DART_WGATHER (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_WGATHER)) +#define HPERF_NRT_DART_SCALER0_RTLIMIT (0x0108) +#define rHPERF_NRT_DART_SCALER0_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_RTLIMIT)) +#define HPERF_NRT_DART_SCALER0_WTLIMIT (0x010C) +#define rHPERF_NRT_DART_SCALER0_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_WTLIMIT)) +#define HPERF_NRT_DART_SCALER1_RTLIMIT (0x0208) +#define rHPERF_NRT_DART_SCALER1_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_RTLIMIT)) +#define HPERF_NRT_DART_SCALER1_WTLIMIT (0x020C) +#define rHPERF_NRT_DART_SCALER1_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_WTLIMIT)) +#define HPERF_NRT_DART_JPEG0_RTLIMIT (0x0308) +#define rHPERF_NRT_DART_JPEG0_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_RTLIMIT)) +#define HPERF_NRT_DART_JPEG0_WTLIMIT (0x030C) +#define rHPERF_NRT_DART_JPEG0_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_WTLIMIT)) +#define HPERF_NRT_DART_JPEG0_QOS (0x0314) +#define rHPERF_NRT_DART_JPEG0_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_QOS)) +#define HPERF_NRT_DART_JPEG1_RTLIMIT (0x0408) +#define rHPERF_NRT_DART_JPEG1_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_RTLIMIT)) +#define HPERF_NRT_DART_JPEG1_WTLIMIT (0x040C) +#define rHPERF_NRT_DART_JPEG1_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_WTLIMIT)) +#define HPERF_NRT_DART_JPEG1_QOS (0x0414) +#define rHPERF_NRT_DART_JPEG1_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_QOS)) + +#define HPERF_NRT_DART_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_DART_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_DART_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_DART_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AW_CHAN_ARB_MI0)) + +#define HPERF_NRT_TOP_TOP_RTLIMIT (0x0008) +#define rHPERF_NRT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_RTLIMIT)) +#define HPERF_NRT_TOP_TOP_WTLIMIT (0x000C) +#define rHPERF_NRT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_RTLIMIT (0x0108) +#define rHPERF_NRT_TOP_VENC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_RTLIMIT)) +#define HPERF_NRT_TOP_VENC_WTLIMIT (0x010C) +#define rHPERF_NRT_TOP_VENC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_WREQSP (0x0110) +#define rHPERF_NRT_TOP_VENC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WREQSP)) +#define HPERF_NRT_TOP_VDEC_RTLIMIT (0x0208) +#define rHPERF_NRT_TOP_VDEC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_RTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WTLIMIT (0x020C) +#define rHPERF_NRT_TOP_VDEC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WREQSP (0x0210) +#define rHPERF_NRT_TOP_VDEC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WREQSP)) +#define HPERF_NRT_TOP_AUX_RTLIMIT (0x0308) +#define rHPERF_NRT_TOP_AUX_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_RTLIMIT)) +#define HPERF_NRT_TOP_AUX_WTLIMIT (0x030C) +#define rHPERF_NRT_TOP_AUX_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WTLIMIT)) +#define HPERF_NRT_TOP_AUX_WGATHER (0x0310) +#define rHPERF_NRT_TOP_AUX_WGATHER (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_AUX_WGATHER)) + +#define HPERF_NRT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AW_CHAN_ARB_MI0)) + +#define HPERF_RT_TOP_DISP0_RTLIMIT (0x0004) +#define rHPERF_RT_TOP_DISP0_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP0_RTLIMIT)) +#define HPERF_RT_TOP_DISP1_RTLIMIT (0x000C) +#define rHPERF_RT_TOP_DISP1_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP1_RTLIMIT)) +#define HPERF_RT_TOP_ISP_RTLIMIT (0x0018) +#define rHPERF_RT_TOP_ISP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_WTLIMIT)) +#define HPERF_RT_TOP_ISP_WTLIMIT (0x001C) +#define rHPERF_RT_TOP_ISP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_RTLIMIT)) +#define HPERF_RT_TOP_TOP_RTLIMIT (0x0020) +#define rHPERF_RT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_WTLIMIT)) +#define HPERF_RT_TOP_TOP_WTLIMIT (0x0024) +#define rHPERF_RT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_RTLIMIT)) + +#define HPERF_RT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_RT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_RT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_RT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AW_CHAN_ARB_MI0)) + +#define rSCC_CCXPWRCTRL (*(volatile u_int32_t *)(SCC_BASE_ADDR + 0x2603C)) + + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(int step); +extern void miu_update_device_tree(DTNode *pmgr_node); + +extern u_int32_t miu_read_l2cadrmap(void); +extern void miu_write_l2cadrmap(u_int32_t value); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s5l8950x/include/platform/soc/pmgr.h b/platform/s5l8950x/include/platform/soc/pmgr.h new file mode 100644 index 0000000..7590e1e --- /dev/null +++ b/platform/s5l8950x/include/platform/soc/pmgr.h @@ -0,0 +1,538 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include + +#define PMGR_PLL_COUNT (9) + +#define rPMGR_PLL_CTL0(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0000 + ((_n) * 0x18))) +#define PMGR_PLL_ENABLE (1 << 31) +#define PMGR_PLL_EXT_BYPASS (1 << 30) +#define PMGR_PLL_REAL_LOCK (1 << 29) +#define PMGR_PLL_LOAD (1 << 27) +#define PMGR_PLL_BYPASS (1 << 23) + +#define rPMGR_PLL_CTL1(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0004 + ((_n) * 0x18))) +#define PMGR_PLL_MASK (0x1FF) +#define PMGR_PLL_M_SHIFT (18) +#define PMGR_PLL_P_SHIFT (9) +#define PMGR_PLL_S_SHIFT (0) +#define PMGR_PLL_P(_p) (((_p) & PMGR_PLL_MASK) << PMGR_PLL_P_SHIFT) +#define PMGR_PLL_M(_m) (((_m) & PMGR_PLL_MASK) << PMGR_PLL_M_SHIFT) +#define PMGR_PLL_S(_s) (((_s) & PMGR_PLL_MASK) << PMGR_PLL_S_SHIFT) + +#define rPMGR_PLL_PARAM(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0008 + ((_n) * 0x18))) +#define PMGR_PARAM_LOCK_TIME_MASK (0xFFFF) +#define PMGR_PARAM_LOCK_TIME(_n) (((_n) & PMGR_PARAM_LOCK_TIME_MASK) << 0) + +#define rPMGR_PLL_FD(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x000C + ((_n) * 0x18))) + +#define rPMGR_DOUBLER_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0100)) +#define PMGR_DOUBLER_ENABLE (1 << 31) +#define PMGR_DOUBLER_EXT_BYPASS (1 << 30) + +#define rPMGR_CPU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0140)) +#define rPMGR_PLL2_GATE_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0150)) +#define rPMGR_PLL4_GATE_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0154)) +#define rPMGR_PLL5_GATE_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0158)) + +#define rPMGR_MCU_FIXED_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0164)) +#define rPMGR_MCU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0168)) +#define rPMGR_PCLK1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x016C)) +#define rPMGR_GFX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0170)) +#define rPMGR_GFX_SLC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0174)) + +#define rPMGR_PREDIV0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0190)) +#define rPMGR_PREDIV1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0194)) +#define rPMGR_PREDIV2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0198)) +#define rPMGR_PREDIV3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x019C)) +#define rPMGR_PREDIV4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01A0)) +#define rPMGR_PREDIV5_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01A4)) +#define rPMGR_PREDIV6_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01A8)) + +#define rPMGR_VENC_MTX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01D0)) +#define rPMGR_VENC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01D4)) +#define rPMGR_HPERFRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01D8)) +#define rPMGR_GFX_SYS_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01DC)) +#define rPMGR_HPERFNRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01E0)) +#define rPMGR_NRT_MEM_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01E4)) +#define rPMGR_VDEC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01E8)) +#define rPMGR_ISP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01EC)) +#define rPMGR_IOP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01F0)) +#define rPMGR_CDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01F4)) +#define rPMGR_LPERFS_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01F8)) +#define rPMGR_PCLK0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01FC)) +#define rPMGR_PCLK2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0200)) +#define rPMGR_PCLK3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0204)) +#define rPMGR_AES_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0208)) + +#define rPMGR_MEDIUM0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0230)) +#define rPMGR_MEDIUM1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0234)) +#define rPMGR_VID0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0238)) +#define rPMGR_VID1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x023C)) +#define rPMGR_DISPOUT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0240)) +#define rPMGR_I2C_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0244)) +#define rPMGR_SDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0248)) +#define rPMGR_MIPI_DSI_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x024C)) +#define rPMGR_AUDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0250)) +#define rPMGR_ADSP_PCLK0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0254)) +#define rPMGR_ADSP_TCLK_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0258)) +#define rPMGR_ADSP_TSCLK_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x025C)) +#define rPMGR_UPERF_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0260)) +#define rPMGR_DEBUG_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0264)) + +#define rPMGR_SCC_PWR_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0268)) +#define rPMGR_SCC_DMA_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x026C)) + +#define rPMGR_SPI0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0270)) +#define rPMGR_SPI1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0274)) +#define rPMGR_SPI2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0278)) +#define rPMGR_SPI3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x027C)) +#define rPMGR_SPI4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0280)) +#define rPMGR_SLOW_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0284)) +#define rPMGR_SLEEP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0288)) + +#define rPMGR_USBPHY_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x028C)) +#define rPMGR_USBOHCI_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0290)) +#define rPMGR_USB12_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0294)) + +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0298)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x029C)) + +#define rPMGR_USBPHY1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02A4)) +#define rPMGR_USBFREE_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02A8)) + +#define PMGR_FIRST_CLK_CFG (&rPMGR_CPU_CLK_CFG) +#define PMGR_LAST_CLK_CFG (&rPMGR_USBFREE_CLK_CFG) +#define PMGR_CLK_CFG_COUNT (((((u_int32_t)(PMGR_LAST_CLK_CFG)) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) + 1) +#define PMGR_CLK_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _CLK_CFG) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) +#define PMGR_FIRST_MANAGED_CLK_NUM PMGR_CLK_NUM(VENC_MTX) + +#define PMGR_CLK_CFG_ENABLE (1 << 31) +#define PMGR_CLK_CFG_PENDING (1 << 30) +#define PMGR_CLK_CFG_AUTO_DISABLE (1 << 25) +#define PMGR_CLK_CFG_DIVIDER(_d) (((_d) & 0x1F) << 0) +#define PMGR_CLK_CFG_DIV_MASK PMGR_CLK_CFG_DIVIDER(0x1F) + +#define rPMGR_MIPI_AGILE_CLK_MUX_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02A0)) + +#define rPMGR_I2S0_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02B0)) +#define rPMGR_I2S0_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02B4)) +#define rPMGR_I2S0_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02B8)) + +#define rPMGR_I2S1_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02C0)) +#define rPMGR_I2S1_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02C4)) +#define rPMGR_I2S1_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02C8)) + +#define rPMGR_I2S2_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02D0)) +#define rPMGR_I2S2_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02D4)) +#define rPMGR_I2S2_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02D8)) + +#define rPMGR_I2S3_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02E0)) +#define rPMGR_I2S3_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02E4)) +#define rPMGR_I2S3_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02E8)) + +#define rPMGR_SPDIF_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02F0)) +#define rPMGR_SPDIF_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02F4)) +#define rPMGR_SPDIF_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02F8)) + +#define rPMGR_DP_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0300)) +#define rPMGR_DP_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0304)) +#define rPMGR_DP_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0308)) + +#define rPMGR_MCA_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0310)) +#define rPMGR_MCA_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0314)) +#define rPMGR_MCA_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0318)) + +#define rPMGR_ENABLE_CLK_GATE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0330)) + +#define kPERF_STATE_BYPASS (0) +#define kPERF_STATE_SECUREROM (1) +#define kPERF_STATE_IBOOT (2) +#define kPERF_STATE_IBOOT_CNT (5) + +#define PMGR_PERF_STATE_COUNT (16) +#define rPMGR_PERF_STATE_A(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0400 + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_B(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0404 + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_C(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0408 + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_D(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x040C + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_E(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0410 + ((_s) * 0x20))) +#define PMGR_PERF_STATE_E_VOL_SHIFT (0) +#define PMGR_PERF_STATE_E_VOL_MASK (0xFF) + +#define rPMGR_PERF_STATE_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0600)) +#define PMGR_PERF_STATE_SEL_SHIFT (0) +#define PMGR_PERF_STATE_SEL_MASK (0xF) +#define PMGR_PERF_STATE_SEL(_s) (((_s) & PMGR_PERF_STATE_SEL_MASK) << PMGR_PERF_STATE_SEL_SHIFT) +#define PMGR_PERF_STATE_PENDING (0xFFFFFFF << 4) + +#define rPMGR_PERF_STATE_DELAY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0604)) +#define PMGR_PERF_STATE_DELAY_VOL_CHG_FIX_DLY_SHIFT (8) +#define PMGR_PERF_STATE_DELAY_VOL_CHG_VAR_DLY_SHIFT (0) + +#define rPMGR_MCU_CLK_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0620)) + +#define rPMGR_AUTOMATIC_CLK_GATE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0640)) +#define PMGR_ACG_CLK_GEN__ENABLE (1 << 0) +#define PMGR_ACG_PS_ENABLE (1 << 1) +#define PMGR_ACG_NCO_CLK_GEN_ENABLE (1 << 2) + +#define rPMGR_FIRST_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1000)) +#define rPMGR_SCC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1004)) +#define rPMGR_CPU0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1008)) +#define rPMGR_CPU1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x100C)) +#define rPMGR_L2_BIU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1010)) +#define rPMGR_L2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1014)) +#define rPMGR_MCU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1020)) +#define rPMGR_GFX_SYS_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1024)) +#define rPMGR_GFX_CORES_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1028)) +#define rPMGR_HPERFNRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x102C)) +#define rPMGR_VDEC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1030)) +#define rPMGR_SCALER0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1034)) +#define rPMGR_SCALER1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1038)) +#define rPMGR_JPG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x103C)) +#define rPMGR_JPG1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1040)) +#define rPMGR_VENCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1048)) +#define rPMGR_HPERFRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x104C)) +#define rPMGR_ISP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1050)) +#define rPMGR_LPDP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1054)) +#define rPMGR_DISP0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1058)) +#define rPMGR_DISP1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x105C)) +#define rPMGR_DISPOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1060)) +#define rPMGR_MIPI_DSI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1064)) +#define rPMGR_CLCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1068)) +#define rPMGR_TVOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x106C)) +#define rPMGR_RGBOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1070)) +#define rPMGR_DPLINK_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1074)) +#define rPMGR_CDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1078)) +#define rPMGR_CDMA_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x107C)) +#define rPMGR_IOP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1080)) +#define rPMGR_UPERF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1084)) +#define rPMGR_USBOTG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1088)) +#define rPMGR_USB20_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x108C)) +#define rPMGR_USB11_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1090)) +#define rPMGR_USBOHCI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1094)) +#define rPMGR_USBOHCI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1098)) +#define rPMGR_USBREG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x109C)) +#define rPMGR_AUDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A0)) +#define rPMGR_I2S0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A4)) +#define rPMGR_I2S1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A8)) +#define rPMGR_I2S2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10AC)) +#define rPMGR_I2S3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B0)) +#define rPMGR_SPDIF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B4)) +#define rPMGR_ADSP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B8)) +#define rPMGR_SDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10BC)) +#define rPMGR_SHA1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C0)) +#define rPMGR_SHA2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C4)) +#define rPMGR_FMI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C8)) +#define rPMGR_FMI0BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10CC)) +#define rPMGR_FMI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D0)) +#define rPMGR_FMI1BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D4)) +#define rPMGR_FMI_DLL_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D8)) +#define rPMGR_XMBIST_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10DC)) +#define rPMGR_MCA_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E0)) +#define rPMGR_SPI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E4)) +#define rPMGR_SPI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E8)) +#define rPMGR_SPI2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10EC)) +#define rPMGR_SPI3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F0)) +#define rPMGR_SPI4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F4)) +#define rPMGR_UART0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F8)) +#define rPMGR_UART1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10FC)) +#define rPMGR_UART2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1100)) +#define rPMGR_UART3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1104)) +#define rPMGR_UART4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1108)) +#define rPMGR_UART5_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x110C)) +#define rPMGR_UART6_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1110)) +#define rPMGR_PKE_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1114)) +#define rPMGR_I2C0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1118)) +#define rPMGR_I2C1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x111C)) +#define rPMGR_I2C2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1120)) +#define rPMGR_PWM_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1124)) +#define rPMGR_SCRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1128)) +#define rPMGR_GPIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x112C)) +#define rPMGR_SWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1130)) +#define rPMGR_DWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1134)) +#define rPMGR_DEBUG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1138)) +#define rPMGR_AIC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x113C)) + +#define PMGR_PS_RESET (1 << 31) + +#define PMGR_FIRST_PS (&rPMGR_FIRST_PS) +#define PMGR_LAST_PS (&rPMGR_AIC_PS) +#define PMGR_PS_COUNT (((((u_int32_t)(PMGR_LAST_PS)) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + 1) +#define PMGR_PS_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _PS) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + +#define rPMGR_PWR_GATE_CTL_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1200)) +#define rPMGR_PWR_GATE_CTL_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1204)) +#define PMGR_PWR_GATE_IOP (1 << 6) + +#define rPMGR_PWR_GATE_GFX_MODE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1208)) + +#define rPMGR_CORE_OFFLINE_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1210)) +#define rPMGR_CORE_OFFLINE_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1214)) +#define rPMGR_WAKE_CORES (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1220)) + +#define PMGR_PWR_GATE_TIME_COUNT (14) +#define rPMGR_PWR_GATE_TIME_A(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1240 + (((_n) - 1) * 8))) +#define rPMGR_PWR_GATE_TIME_B(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1244 + (((_n) - 1) * 8))) +#define rPMGR_PWR_GATE_DBG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E0)) +#define rPMGR_PWR_GATE_DBG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E4)) + +#define rPMGR_VOLMAN_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1380)) +#define PMGR_VOLMAN_DISABLE_VOL_CHANGE (1 << 10) +#define PMGR_VOLMAN_CPU_SW_OFF_TIME_VALUE(_x) ((_x) << 2) +#define PMGR_VOLMAN_BIT_ORDER_MSB (0 << 1) +#define PMGR_VOLMAN_BIT_ORDER_LSB (1 << 1) +#define PMGR_VOLMAN_BYTE_NO_SWAP (0 << 0) +#define PMGR_VOLMAM_BYTE_SWAP (1 << 0) + +#define kDVFM_STATE_COUNT (8) +#define kDVFM_STATE_BYPASS (0) +#define kDVFM_STATE_SECUREROM (1) +#define kDVFM_STATE_IBOOT (2) + +#define PMGR_DVFM_STATE_COUNT (8) +#define rPMGR_DVFM_CFG0(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1400 + ((_s) * 0x20))) +#define rPMGR_DVFM_CFG1(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1404 + ((_s) * 0x20))) +#define PMGR_DVFM_CFG1_CLK_SRC_SHIFT (18) +#define PMGR_DVFM_CFG1_MIN_VOL_SHIFT (8) +#define PMGR_DVFM_CFG1_SAFE_VOL_SHIFT (0) +#define PMGR_DVFM_CFG1_VOL_MASK (0xFF) +#define rPMGR_DVFM_CFG2(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1408 + ((_s) * 0x20))) +#define PMGR_DVFM_CFG2_SRAM_VOL_SHIFT (24) +#define PMGR_DVFM_CFG2_SRAM_VOL_MASK (0xFF) +#define rPMGR_DVFM_CFG3(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x140C + ((_s) * 0x20))) +#define rPMGR_DVFM_CFG4(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1410 + ((_s) * 0x20))) + +#define rPMGR_DVFM_COMMON_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1600)) +#define rPMGR_DVFM_STA_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1604)) +#define rPMGR_DVFM_CFG_SEL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1608)) +#define rPMGR_DVFM_DELAY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x160C)) +#define PMGR_DVFM_DELAY_VOL_CHG_FIX_DLY_SHIFT (8) +#define PMGR_DVFM_DELAY_VOL_CHG_VAR_DLY_SHIFT (0) +#define rPMGR_DVFM_SRAM_VOL_DELAY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1610)) +#define PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_FIX_DLY_SHIFT (8) +#define PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_VAR_DLY_SHIFT (0) + +#define rPMGR_SENSOR_CMD (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1680)) +#define rPMGR_CORE0_TMP_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1684)) +#define rPMGR_CORE1_TMP_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1688)) +#define rPMGR_CORE0_SPD_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x168C)) +#define rPMGR_CORE1_SPD_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1690)) + +#define rPMGR_APSC_STA_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1700)) +#define PMGR_APSC_PENDING (1 << 31) +#define PMGR_APSC_SCC_MANUAL_CHANGE (1 << 25) +#define PMGR_APSC_SOC_MANUAL_CHANGE (1 << 24) +#define PMGR_APSC_SCC_MANUAL_STATE(_d) (((_d) & 0x7) << 20) +#define PMGR_APSC_SOC_MANUAL_STATE(_p) (((_p) & 0xF) << 8) +#define PMGR_APSC_MANUAL_CHANGE(_d, _p) \ + (PMGR_APSC_SCC_MANUAL_CHANGE | PMGR_APSC_SOC_MANUAL_CHANGE | \ + PMGR_APSC_SCC_MANUAL_STATE(_d) | PMGR_APSC_SOC_MANUAL_STATE(_p)) + +#define rPMGR_SCC_SLEEP_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1704)) +#define rPMGR_SCC_SLEEP_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1708)) +#define rPMGR_SCC_WAKE_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x170C)) +#define rPMGR_SCC_WAKE_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1710)) +#define rPMGR_SCC_MANUAL_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1714)) +#define rPMGR_SCC_MANUAL_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1718)) +#define rPMGR_SOC_SLEEP_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x171C)) +#define rPMGR_SOC_SLEEP_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1720)) +#define rPMGR_SOC_WAKE_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1724)) +#define rPMGR_SOC_WAKE_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1728)) +#define rPMGR_SOC_MANUAL_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x172C)) +#define rPMGR_SOC_MANUAL_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1730)) + +#define rPMGR_TEST_CLK (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2000)) + +#define rPMGR_OSC_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x200C)) +#define rPMGR_PLL_DEBUG(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2010 + ((_n) * 4))) +#define PMGR_PLL_DEBUG_ENABLED (1 << 31) +#define PMGR_PLL_DEBUG_BYP_ENABLED (1 << 30) +#define PMGR_PLL_DEBUG_DBG_STPCLK_EN (1 << 24) +#define PMGR_PLL_DEBUG_FSTATE (1 << 12) +#define PMGR_PLL_DEBUG_STATE(_r) (((_r) >> 0) & 0xFFF) + +#define rPMGR_DOUBLER_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2034)) +#define PMGR_DOUBLER_DEBUG_ENABLED (1 << 31) +#define PMGR_DOUBLER_DEBUG_BYP_ENABLED (1 << 30) + +#define rPMGR_SRAM_EMA_B0_Pn_LO(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2128 + (((_n) - 1) * 8))) +#define rPMGR_SRAM_EMA_B0_Pn_HI(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x212C + (((_n) - 1) * 8))) + +enum { + EMA_MCU = 1, + EMA_GFX_PIPES_SYS = 2, + EMA_GFX_HYDRA = 3, + EMA_VDEC = 4, + EMA_VENC = 5, + EMA_ISP = 6, + EMA_DISP = 7, + EMA_NRT = 8, + EMA_PMGR = 9, + EMA_IOP = 10, + EMA_SAUDIO = 11, + EMA_CDIO = 12, + EMA_FMI = 13, + EMA_ADSP = 14, +}; + +#define rPMGR_WDOG_TMR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3020)) +#define rPMGR_WDOG_RST (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3024)) +#define rPMGR_WDOG_INT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3028)) +#define rPMGR_WDOG_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x302C)) + +#define rPMGR_PERF_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4000)) +#define rPMGR_PERF_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4004)) +#define rPMGR_PERF_CTR0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4020)) +#define rPMGR_PERF_CTR0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4024)) +#define rPMGR_PERF_CFG0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4028)) +#define rPMGR_PERF_CFG0_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x402C)) +#define rPMGR_PERF_CFG0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4030)) +#define rPMGR_PERF_CTR1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4040)) +#define rPMGR_PERF_CTR1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4044)) +#define rPMGR_PERF_CFG1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4048)) +#define rPMGR_PERF_CFG1_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x404C)) +#define rPMGR_PERF_CFG1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4050)) + +#define rPMGR_SCRATCH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6000)) +#define rPMGR_SCRATCH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6004)) +#define rPMGR_SCRATCH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6008)) +#define rPMGR_SCRATCH3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x600C)) +#define rPMGR_SCRATCH4 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6010)) +#define rPMGR_SCRATCH5 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6014)) +#define rPMGR_SCRATCH6 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6018)) +#define rPMGR_SCRATCH7 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x601C)) +#define rPMGR_SCRATCH8 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6020)) +#define rPMGR_SCRATCH9 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6024)) +#define rPMGR_SCRATCH10 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6028)) +#define rPMGR_SCRATCH11 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x602C)) +#define rPMGR_SCRATCH12 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6030)) +#define rPMGR_SCRATCH13 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6034)) +#define rPMGR_SCRATCH14 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6038)) +#define rPMGR_SCRATCH15 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x603C)) + +#define rPMGR_DAC_FS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x7000)) + +#define rPMGR_USB_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x8000)) + +#define rPMGR_SHA_SEL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x9000)) + +#define rPMGR_SECURITY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xA000)) + +#define rPMGR_GFX_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xB000)) + + +#define rPMGR_THERMAL0_CTL0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC000)) +#define rPMGR_THERMAL0_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC004)) +#define rPMGR_THERMAL0_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC008)) +#define rPMGR_THERMAL0_CTL3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC00C)) +#define rPMGR_THERMAL0_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC010)) +#define rPMGR_THERMAL0_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC014)) +#define rPMGR_THERMAL0_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC018)) +#define rPMGR_THERMAL0_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC01C)) +#define rPMGR_THERMAL1_CTL0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC040)) +#define rPMGR_THERMAL1_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC044)) +#define rPMGR_THERMAL1_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC048)) +#define rPMGR_THERMAL1_CTL3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC04C)) +#define rPMGR_THERMAL1_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC050)) +#define rPMGR_THERMAL1_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC054)) +#define rPMGR_THERMAL1_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC058)) +#define rPMGR_THERMAL1_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC05C)) + + +#define PGMR_GET_PERF_STATE_INDEX(_n, _x) (((_x) >> ((_n) * 4)) & 0xF) +#define PGMR_SET_PERF_STATE_INDEX(_n, _i) (((_i) & 0xF) << ((_n) * 4)) +#define PMGR_PERF_STATE_V(_n) (_n) +#define PMGR_PERF_STATE_P (3) +#define PMGR_PERF_STATE_M(_n) (4 + (_n)) + + +enum { + PMGR_CLK_OSC = 0, + PMGR_CLK_PLL0, + PMGR_CLK_PLL1, + PMGR_CLK_PLL2, + PMGR_CLK_PLL3, + PMGR_CLK_PLL4, + PMGR_CLK_PLL5, + PMGR_CLK_PLL6, + PMGR_CLK_PLL7, + PMGR_CLK_PLLUSB, + PMGR_CLK_DOUBLER, + PMGR_CLK_PLL2_GATED, + PMGR_CLK_PLL4_GATED, + PMGR_CLK_PLL5_GATED, + PMGR_CLK_MCU_FIXED, + PMGR_CLK_MCU, + PMGR_CLK_CPU, + PMGR_CLK_PREDIV0, + PMGR_CLK_PREDIV1, + PMGR_CLK_PREDIV2, + PMGR_CLK_PREDIV3, + PMGR_CLK_PREDIV4, + PMGR_CLK_PREDIV5, + PMGR_CLK_PREDIV6, + PMGR_CLK_GFX, + PMGR_CLK_GFX_SLC, + PMGR_CLK_GFX_SYS, + PMGR_CLK_HPERFRT, + PMGR_CLK_DISPOUT, + PMGR_CLK_VID0, + PMGR_CLK_VID1, + PMGR_CLK_MIPI_DSI, + PMGR_CLK_HPERFNRT, + PMGR_CLK_NRT_MEM, + PMGR_CLK_VENC_MTX, + PMGR_CLK_VENC, + PMGR_CLK_VDEC, + PMGR_CLK_ISP, + PMGR_CLK_IOP, + PMGR_CLK_CDIO, + PMGR_CLK_LPERFS, + PMGR_CLK_PCLK0, + PMGR_CLK_PCLK1, + PMGR_CLK_PCLK2, + PMGR_CLK_PCLK3, + PMGR_CLK_AES, + PMGR_CLK_MEDIUM0, + PMGR_CLK_MEDIUM1, + PMGR_CLK_I2C, + PMGR_CLK_SDIO, + PMGR_CLK_AUDIO, + PMGR_CLK_ADSP_PCLK0, + PMGR_CLK_ADSP_TCLK, + PMGR_CLK_ADSP_TSCLK, + PMGR_CLK_UPERF, + PMGR_CLK_DEBUG, + PMGR_CLK_SCC_PWR, + PMGR_CLK_SCC_DMA, + PMGR_CLK_SPI0, + PMGR_CLK_SPI1, + PMGR_CLK_SPI2, + PMGR_CLK_SPI3, + PMGR_CLK_SPI4, + PMGR_CLK_SLOW, + PMGR_CLK_SLEEP, + PMGR_CLK_USBPHY, + PMGR_CLK_USBOHCI, + PMGR_CLK_USB12, + PMGR_CLK_NCO_REF0, + PMGR_CLK_NCO_REF1, + PMGR_CLK_COUNT +}; + +extern void pmgr_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/s5l8950x/include/platform/trampoline.h b/platform/s5l8950x/include/platform/trampoline.h new file mode 100644 index 0000000..32d8ff6 --- /dev/null +++ b/platform/s5l8950x/include/platform/trampoline.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include +#include + +#define SECURITY_REG (PMGR_BASE_ADDR + 0xA000) +#define ROM_READ_DISABLE (1 << 0) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s5l8950x/include/platform/usbconfig.h b/platform/s5l8950x/include/platform/usbconfig.h new file mode 100644 index 0000000..947b018 --- /dev/null +++ b/platform/s5l8950x/include/platform/usbconfig.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#define USBPHY_CLK_TYPE (3) /* Use CLKCORE */ + +#define USBPHY_UOTGTUNE1 (0x749) +#define USBPHY_UOTGTUNE2 (0x2FF3) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +#ifdef WITH_TARGET_USB_CONFIG +#include +#endif /* WITH_TARGET_USB_CONFIG */ + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s5l8950x/init.c b/platform/s5l8950x/init.c new file mode 100644 index 0000000..b5a2ce2 --- /dev/null +++ b/platform/s5l8950x/init.c @@ -0,0 +1,1303 @@ +/* + * Copyright (C) 2010-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_EFFACEABLE_NOR +#include +#endif + +extern void dma_init(void); + +static void platform_init_boot_strap(void); + +static uint8_t boot_debug; + +int platform_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + /* Verify that the fuses and that the SecureROM has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile u_int32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled"); + } +#endif + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8950x pmgr driver */ + platform_power_init(); +#endif + + platform_init_boot_strap(); + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); +#if !RELEASE_BUILD && (PRODUCT_IBSS || PRODUCT_IBEC) + debug_enable_uarts(3); +#endif +#endif +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_HW_DMA + /* initialize the dma engine */ + dma_init(); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + return 0; +} + + +int platform_late_init(void) +{ + // Chips older then C0 are not supported + if (platform_get_chip_revision() < 0x20) platform_not_supported(); + +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_NAND + flash_nand_id(); +#endif + +#if WITH_HW_AMC + extern void mcu_late_init(void); + mcu_late_init(); +#endif + + return 0; +} + + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); + + /* always remap the memory region at this point, regardless of resume, + * because the early MMU init always runs and we have to fix up. */ + platform_init_mainmem_map(); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +#if APPLICATION_IBOOT + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, kARMMMUNormal, true, true); +#endif +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +static bool gDisplayEnabled; + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { +#if WITH_HW_DISPLAY_PMU + display_pmu_init(); +#endif + + if (!displayInitOnce) { + platform_quiesce_display(); + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + + power_backlight_enable(backlight_level); +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + u_int32_t base_rounded = *base; + u_int32_t end_rounded = *base + *size; + u_int32_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + arm_mmu_map_section_range(base_rounded, base_rounded, size_rounded/MB, kARMMMUWriteCombined, false, true); + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_NAND_FILESYSTEM + flash_nand_init(); +#endif + +#if WITH_SW_HDC + hdc_init(); +#endif + return 0; +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + quiesce_clocks = true; +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + + /* quiesce the panel */ + if (display_quiesce(true) == ENXIO) { + clock_gate(CLK_HPERFRT, false); + clock_gate(CLK_DISPOUT, false); + } + +#endif + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + u_int32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + platform_quiesce_display(); + case BOOT_DARWIN: +#if WITH_PAINT + if (paint_color_map_is_invalid()) + panic("Previous DClr errors prevent OS booting"); +#endif + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + ; // do nothing + } + + /* if we left the fuse unlocked for boot image processing, + * lock it now, after optionally switching from production to + * development fusing. */ + if (security_get_production_override()) + chipid_clear_production_mode(); + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + + /* mark usable ram as cached/buffered */ + arm_mmu_map_section_range(SRAM_BASE, SRAM_BASE, ROUNDUP(SRAM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#if APPLICATION_SECUREROM + arm_mmu_map_section_range(VROM_BASE, VROM_BASE, ROUNDUP(VROM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#endif + + /* Remap text base is to zero (for exception vectors) */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUNormalRX, false); + +#ifdef MMU_NONCACHE0_SIZE + /* create the noncached0 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE0_VBASE, MMU_NONCACHE0_PBASE, ROUNDUP(MMU_NONCACHE0_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + +#ifdef MMU_NONCACHE1_SIZE + /* create the noncached1 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE1_VBASE, MMU_NONCACHE1_PBASE, ROUNDUP(MMU_NONCACHE1_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + + /* in cases where we are running from DRAM, remap it now */ + if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) { + platform_init_mainmem_map(); + } +} + +int platform_init(void) +{ +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_NAND_BOOT + nand_boot_init(); +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + +#if WITH_EFFACEABLE_NOR + effaceable_nor_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + u_int32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +u_int32_t platform_set_performance(u_int32_t performance_level) +{ + u_int32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + u_int32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_CPU); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_MEM); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_BUS); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_PERIPH); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_FIXED); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_TIMEBASE); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(u_int32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_NAND_FILESYSTEM + if (FindNode(0, "arm-io/flash-controller0/disk", &node)) { + fillNandConfigProperties(node); + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + + return target_update_device_tree(); +} + +#endif + +static void platform_init_boot_strap(void) +{ + u_int32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG3, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG3) << 3) | + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +u_int32_t platform_get_board_id(void) +{ + u_int32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +u_int32_t platform_get_boot_config(void) +{ + u_int32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, u_int32_t *boot_flag, u_int32_t *boot_arg) +{ + u_int32_t boot_config = platform_get_boot_config(); + + /* S5L8950X supports one boot device then USB-DFU per boot config */ + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case 0: /* SPI 0 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 1: /* SPI 3 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 3; + break; + + case 2: /* SPI 0 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case 3: /* SPI 3 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 3; + break; + + case 4: /* FMI0 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 0; + break; + + case 5: /* FMI0 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 0; + break; + + case 6: /* FMI0 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 0; + break; + +/* case 7: Unused */ + + case 8: /* FMI1 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 8; + break; + + case 9: /* FMI1 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 8; + break; + + case 10: /* FMI1 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 8; + break; + +/* case 11: Unused */ + + case 12: /* FMI0/1 2/2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (2 << 8) | (2 << 0); + break; + + case 13: /* FMI0/1 4/4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (4 << 8) | (4 << 0); + break; + + case 14: /* FMI0/1 4/4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = (4 << 8) | (4 << 0); + break; + +/* case 15: Unused */ + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == 1) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + u_int32_t enable; + u_int32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO( 6, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO( 6, 5), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO( 6, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO( 6, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO( 6, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; + +static const struct boot_interface_pin spi3_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(10, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_SSIN +#else + { GPIO(10, 7), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI3_SSIN +#endif + { GPIO(10, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_SCLK + { GPIO(10, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_MOSI + { GPIO(10, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI3_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND +/* Note: The code below expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi0_boot_interface_pins[] = +{ + { GPIO(19, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN3 + { GPIO(19, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN2 + { GPIO(19, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN1 + { GPIO(19, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN0 + { GPIO(19, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CLE + { GPIO(19, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_ALE + { GPIO(20, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_REN + { GPIO(20, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_WEN + { GPIO(21, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO0 + { GPIO(21, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO1 + { GPIO(21, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO2 + { GPIO(21, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO3 + { GPIO(20, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO4 + { GPIO(20, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO5 + { GPIO(20, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO6 + { GPIO(20, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI0_IO7 +}; + +/* Note: The code below expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi1_boot_interface_pins[] = +{ + { GPIO(22, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN3 + { GPIO(22, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN2 + { GPIO(22, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN1 + { GPIO(22, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN0 + { GPIO(22, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CLE + { GPIO(22, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_ALE + { GPIO(22, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_REN + { GPIO(23, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_WEN + { GPIO(24, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO0 + { GPIO(24, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO1 + { GPIO(24, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO2 + { GPIO(24, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO3 + { GPIO(23, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO4 + { GPIO(23, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO5 + { GPIO(23, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO6 + { GPIO(23, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI1_IO7 +}; +#endif /* WITH_HW_BOOTROM_NAND */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, u_int32_t boot_arg) +{ + const struct boot_interface_pin *pins0 = 0; + const struct boot_interface_pin *pins1 = 0; + u_int32_t cnt, func, pin_count0 = 0, pin_count1 = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins0 = spi0_boot_interface_pins; + pin_count0 = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } else if (boot_arg == 3) { + pins0 = spi3_boot_interface_pins; + pin_count0 = (sizeof(spi3_boot_interface_pins) / sizeof(spi3_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND + case BOOT_DEVICE_NAND : + pins0 = fmi0_boot_interface_pins; + pin_count0 = (sizeof(fmi0_boot_interface_pins) / sizeof(fmi0_boot_interface_pins[0])); + switch ((boot_arg >> 0) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins0 += 2; + pin_count0 -= 2; + break; + + default: + pins0 = 0; + pin_count0 = 0; + break; + } + + pins1 = fmi1_boot_interface_pins; + pin_count1 = (sizeof(fmi1_boot_interface_pins) / sizeof(fmi1_boot_interface_pins[0])); + switch ((boot_arg >> 8) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins1 += 2; + pin_count1 -= 2; + break; + + default: + pins1 = 0; + pin_count1 = 0; + break; + } + break; +#endif /* WITH_HW_BOOTROM_NAND */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count0; cnt++) { + if (enable) { + pin = pins0[pin_count0 - 1 - cnt].pin; + func = pins0[pin_count0 - 1 - cnt].enable; + } else { + pin = pins0[cnt].pin; + func = pins0[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } + + for (cnt = 0; cnt < pin_count1; cnt++) { + if (enable) { + pin = pins1[pin_count1 - 1 - cnt].pin; + func = pins1[pin_count1 - 1 - cnt].enable; + } else { + pin = pins1[cnt].pin; + func = pins1[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 1 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +u_int64_t platform_get_nonce(void) +{ + u_int64_t nonce; + u_int32_t *nonce_words = (u_int32_t *)&nonce; + +#if WITH_EFFACEABLE && PRODUCT_IBOOT + // N41 : Sundance 10A267 : USER IPSW : iTunes fails with error 21. + // In iboot use key stored in effaceable and cache it + // for later use, rather than using random_get_bytes + // key generated by secure-rom + static bool use_cached_effaceable_key; + if(use_cached_effaceable_key == false) { + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagNonce; + use_cached_effaceable_key = true; + } +#endif + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return chipid_get_ecid_image_personalization_required(); +} + +u_int32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +#if WITH_TARGET_CONFIG + +// The target's rules.mk sets the high SoC voltage point +#ifndef TARGET_BOOT_SOC_VOLTAGE +#error TARGET_BOOT_SOC_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} + +// The target's rules.mk sets the high CPU voltage point +#ifndef TARGET_BOOT_CPU_VOLTAGE +#error TARGET_BOOT_CPU_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_BOOT_CPU_VOLTAGE); +} + +// The target's rules.mk sets the high RAM voltage point +#ifndef TARGET_BOOT_RAM_VOLTAGE +#error TARGET_BOOT_RAM_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_ram_voltage(void) +{ + return chipid_get_ram_voltage(TARGET_BOOT_RAM_VOLTAGE); +} + +static const u_int32_t soc_voltage_points[] = { + CHIPID_SOC_VOLTAGE_LOW, + CHIPID_SOC_VOLTAGE_MED, + CHIPID_SOC_VOLTAGE_HIGH +}; + +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(soc_voltage_points) / sizeof(soc_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_soc_voltage(soc_voltage_points[cnt]); + } + + return 0; +} + +int platform_get_cpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cnt); + } + + return 0; +} + +static const u_int32_t ram_voltage_points[] = { + CHIPID_RAM_VOLTAGE_LOW, + CHIPID_RAM_VOLTAGE_HIGH +}; + +int platform_get_ram_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(ram_voltage_points) / sizeof(ram_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_ram_voltage(ram_voltage_points[cnt]); + } + + return 0; +} + +#endif /* WITH_TARGET_CONFIG */ + +int platform_convert_voltages(int buck, u_int32_t count, u_int32_t *voltages) +{ +#if WITH_HW_POWER + u_int32_t index; + + if (voltages == 0) return -1; + + for (index = 0; index < count; index++) { + if (0 != power_get_buck_value(buck, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ +#if SUPPORT_FPGA + return !gpio_read(GPIO_FORCE_DFU); +#else + return gpio_read(GPIO_FORCE_DFU); +#endif +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(u_int32_t key_selector, u_int32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +#if APPLICATION_IBOOT +u_int64_t platform_get_memory_size(void) +{ + u_int64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (rPMGR_SCRATCH13 & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +u_int8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 28) & 0xf); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info(u_int8_t manuf_id, u_int64_t memory_size) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 28) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +#endif diff --git a/platform/s5l8950x/iop_init.c b/platform/s5l8950x/iop_init.c new file mode 100644 index 0000000..bf3fb4b --- /dev/null +++ b/platform/s5l8950x/iop_init.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Platform memory layout. + * + * The IOP sees SDRAM at its physical location uncached, and has an cached aperture + * visible elsewhere. SDRAM size of up to 1GB is currently supported. + * SRAM is not visible/legally usable. + * + * For some platforms/targets, SDRAM_LEN is not constant and so we + * have to compute a maximum via other means. + * + * Note that the AE2 Sparrow shares this code. + */ +#define MEM_CACHED_BASE (SDRAM_BASE | 0xc0000000) +#define SDRAM_MAX_LEN (SDRAM_BANK_LEN * SDRAM_BANK_COUNT) +struct mem_static_map_entry mem_static_map_entries[] = { + { + MEM_CACHED_BASE, /* cached */ + SDRAM_BASE, /* uncached */ + SDRAM_BASE, /* physical */ + SDRAM_MAX_LEN /* length */ + }, + {MAP_NO_ENTRY, MAP_NO_ENTRY, MAP_NO_ENTRY, 0} +}; + +void platform_mmu_setup(bool resume) +{ + if (false == resume) { + /* Note: sharing settings aren't critical, as SCC doesn't see the AxUSER bits + * and the AxCACHE widget does all the heavy lifting. */ + + /* Remap text base to zero, outer uncacheable, shared */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUInnerNormalOuterNoncached, true); +#if MAP_SRAM_CACHED + /* Map the SRAM as cacheable, shared */ + arm_mmu_map_section(SRAM_BASE, SRAM_BASE, kARMMMUNormal, true); +#endif // MAP_SRAM_CACHED + /* Remap all of SDRAM through the cacheable aperture, outer uncacheable, shared */ + arm_mmu_map_section_range(MEM_CACHED_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUInnerNormalOuterNoncached, true, false); + /* Remap all of SDRAM through the uncacheable aperture (existing mappings should be there, but be sure) */ + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUStronglyOrdered, false, false); + } +} + +bool platform_get_production_mode(void) +{ + return(true); +} + +bool platform_get_secure_mode(void) +{ + return(true); +} + +void platform_reset(bool panic) +{ + for (;;) + ; +} + +/* + * Early init is done every time the IOP starts. + */ +int +platform_early_init() +{ +#if PLATFORM_VARIANT_IOP + /* In general we want power-gating to be disabled. */ + rPMGR_PWR_GATE_CTL_CLR = PMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & PMGR_PWR_GATE_IOP) ; +#endif + + interrupt_init(); + + timer_init(0); + + return(0); +} + +/* + * Halt waiting for an interrupt. + */ +void +platform_halt(void) +{ + arch_halt(); +} + +#if SUPPORT_SLEEP + +#if WITH_IOP_POWER_GATING + +/* + * Deep idle sleep with power gating + */ +void +platform_deep_idle(void) +{ + rPMGR_PWR_GATE_CTL_SET = PMGR_PWR_GATE_IOP; + while (!(rPMGR_PWR_GATE_CTL_SET & PMGR_PWR_GATE_IOP)) ; + a5iop_sleep(1); + rPMGR_PWR_GATE_CTL_CLR = PMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & PMGR_PWR_GATE_IOP) ; +} + +#endif + +void +platform_sleep(void) +{ + /* We assume power-gating is disabled, which it need to be so + * the IOP wrapper registers don't disappear. */ + a5iop_sleep(0); +} + +#endif + +/* + * Cache control + */ +void +platform_cache_operation(int operation, void *address, u_int32_t length) +{ + a5iop_cache_operation(operation, address, length); +} + +/* + * Host doorbell uses a SWI in the AIC. + */ +static void (* _doorbell_handler)(void *arg); +static void +platform_doorbell_handler(void *arg) +{ + /* clear the doorbell before passing up */ + interrupt_clear_ipc(INT_IOP); + _doorbell_handler(arg); +} + +void +platform_init_iop_doorbell(void (* handler)(void *arg), void *arg) +{ + _doorbell_handler = handler; + install_int_handler(INT_IOP, platform_doorbell_handler, arg); + set_int_type(INT_IOP, INT_TYPE_IRQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP); +} + +void +platform_mask_doorbell(void) +{ + mask_int(INT_IOP); +} + +void +platform_unmask_doorbell(void) +{ + unmask_int(INT_IOP); +} + +void +platform_ring_host_doorbell(void) +{ + interrupt_generate_ipc(INT_HOST); +} + +int +platform_init_nmi(void (*handler)(void *arg), void *arg) +{ +#ifdef INT_IOP_NMI + install_int_handler(INT_IOP_NMI, handler, arg); + set_int_type(INT_IOP_NMI, INT_TYPE_FIQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP_NMI); +#endif + + return(0); +} + +/* + * Clock management. + * + * Currently the IOP does none for this platform. + */ +void clock_gate(int device, bool enable) +{ +} diff --git a/platform/s5l8950x/miu/miu.c b/platform/s5l8950x/miu/miu.c new file mode 100644 index 0000000..0281857 --- /dev/null +++ b/platform/s5l8950x/miu/miu.c @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void miu_configure_bridge(const u_int32_t *bridge_settings); + +#define BRIDGE_SHIFT (16) +#define BRIDGE_MASK (0xFFFF) +#define NRT_DART_WIDGETS (0 << BRIDGE_SHIFT) +#define NRT_DART_BRIDGE (1 << BRIDGE_SHIFT) +#define NRT_TOP_WIDGETS (2 << BRIDGE_SHIFT) +#define NRT_TOP_BRIDGE (3 << BRIDGE_SHIFT) +#define RT_TOP_WIDGETS (4 << BRIDGE_SHIFT) +#define RT_TOP_BRIDGE (5 << BRIDGE_SHIFT) +#define UPERF_WIDGETS (6 << BRIDGE_SHIFT) +#define UPERF_BRIDGE (7 << BRIDGE_SHIFT) +#define CDIO_WIDGETS (8 << BRIDGE_SHIFT) +#define CDIO_BRIDGE (9 << BRIDGE_SHIFT) + +static const u_int32_t bridge_registers[] = { + NRT_DART_WIDGETS_BASE_ADDR, NRT_DART_PL301_BASE_ADDR, + NRT_TOP_WIDGETS_BASE_ADDR, NRT_TOP_PL301_BASE_ADDR, + RT_TOP_WIDGETS_BASE_ADDR, RT_TOP_PL301_BASE_ADDR, + UPERF_WIDGETS_BASE_ADDR, UPERF_PL301_BASE_ADDR, + CDIO_WIDGETS_BASE_ADDR, CDIO_PL301_BASE_ADDR, +}; + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +// The following settings are based on H5P Tunables Revision 0.46 + +static const u_int32_t bridge_settings_static[] = { + // Configure recommended transaction limits in CDIO + CDIO_WIDGETS | CDIO_IOP_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_IOP_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_IOP_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_IOP_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_CDMA_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_CDMA_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_CDMA_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_CDMA_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_UPERF_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_UPERF_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_UPERF_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_UPERF_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_AUDIO_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_AUDIO_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_AUDIO_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_AUDIO_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_PIO_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_PIO_WTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_CIM_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_CIM_WTLIMIT, 0x00000F0F, + + // Configure recommended bridge settings in CDIO + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x00000000, + + // Configure recommended features in CDIO + CDIO_WIDGETS | CDIO_IOP_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(0), 0xffffbbbb, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(1), 0xfedcba98, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(2), 0xffffbbbb, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(3), 0xfedcba98, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(0), 0x76767676, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(1), 0xfedcfedc, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(2), 0x76767676, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(3), 0xfedcfedc, + CDIO_WIDGETS | CDIO_IOP_C_REMAP_EN, 0x00000003, + CDIO_WIDGETS | CDIO_CDMA_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_UPERF_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_AUDIO_WGATHER, 0x00000100, + + // Configure recommended traffic attributes in UPERF + // LLT Reads and Writes + // AxCACHE = Cacheable + // AxUSER = enable Shared bit + UPERF_WIDGETS | UPERF_OTG_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OTG_CACHE, 0x0107010B, + UPERF_WIDGETS | UPERF_EHCI_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_EHCI_CACHE, 0x0107010B, + UPERF_WIDGETS | UPERF_OHCI0_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI0_CACHE, 0x0107010B, + UPERF_WIDGETS | UPERF_OHCI1_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI1_CACHE, 0x0107010B, + + // Configure recommended bridge settings in UPERF + UPERF_BRIDGE | UPERF_RTLIMIT, 0x00000404, + UPERF_BRIDGE | UPERF_WTLIMIT, 0x00000404, + + 0, 0, + 0, 0 +}; +#endif // APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +#if WITH_DEVICETREE || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static const u_int32_t bridge_settings_dynamic[] = { + // Configure recommended transaction limits in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_RTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_WTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_RTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_WTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_RTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_WTLIMIT, 0x00003F3F, + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x02000002, // Scaler0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x03000003, // Sclaer1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x02000002, // Scaler0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x03000003, // Sclaer1 High Priority + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_QOS, 0x01010101, // JPEG0 LLT Traffic for R&W + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_QOS, 0x01010101, // JPEG1 LLT Traffic for R&W + 0, 0, + + // Configure recommended transaction limits in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_WTLIMIT, 0x00000F0F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_WTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_WTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_AUX_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_AUX_WTLIMIT, 0x00003F3F, + + // Configure recommended bridge settings in HPerf-NRT Top + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x03000003, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x03000003, + + // Configure recommended features in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_AUX_WGATHER, 0x00000100, + 0, 0, + + // Configure recommended transaction limits in HPerf-RT Top + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP0_RTLIMIT, 0x00000909, + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP1_RTLIMIT, 0x00001212, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_WTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_WTLIMIT, 0x00000F0F, + + // Configure recommended bridge settings in HPerf-RT Top + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x00000000, + RT_TOP_BRIDGE | HPERF_RT_TOP_AW_CHAN_ARB_MI, 0x00000000, + 0, 0, + + 0, 0 +}; +#endif // APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Configure bridges that are statically powered + clock_gate(CLK_UPERF, true); + miu_configure_bridge(bridge_settings_static); + clock_gate(CLK_UPERF, false); +#endif + +#if APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC + // Configure bridges that are dynamically powered + clock_gate(CLK_HPERFNRT, true); + clock_gate(CLK_HPERFRT, true); + miu_configure_bridge(bridge_settings_dynamic); + clock_gate(CLK_HPERFNRT, false); + clock_gate(CLK_HPERFRT, false); +#endif + + /* remap whatever bank of ram we're in to zero */ + if (TEXT_BASE == SRAM_BASE) + miu_select_remap(REMAP_SRAM); + else if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) + miu_select_remap(REMAP_SDRAM); + + return 0; +} + +static void miu_configure_bridge(const u_int32_t *bridge_settings) +{ + volatile u_int32_t *reg; + u_int32_t cnt = 0, bridge, offset, data; + + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + bridge = bridge_settings[cnt] >> BRIDGE_SHIFT; + offset = bridge_settings[cnt] & BRIDGE_MASK; + data = bridge_settings[cnt + 1]; + reg = (volatile u_int32_t *)(bridge_registers[bridge] + offset); + *reg = data; + cnt += 2; + } + cnt += 2; + } +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT && WITH_HW_AMC + mcu_initialize_dram(resume); +#endif + + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + u_int32_t tmp; + + switch (sel) { + case REMAP_SRAM: + tmp = miu_read_l2cadrmap() & ~3; + tmp |= 1; // RemapMode = 1 (L2C RAM) + miu_write_l2cadrmap(tmp); + break; + + case REMAP_SDRAM: + tmp = miu_read_l2cadrmap() & ~3; + tmp |= 2; // RemapMode = 2 (MEM) + miu_write_l2cadrmap(tmp); + break; + } +} + +void miu_bypass_prep(int step) +{ +#if APPLICATION_IBOOT && WITH_HW_AMC + extern void mcu_bypass_prep(int step); + mcu_bypass_prep(step); +#endif +} + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ + u_int32_t propSize; + char *propName; + void *propData; + + // Fill in the bridge-settings property + propName = "bridge-settings"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize < sizeof(bridge_settings_dynamic)) { + panic("miu_update_device_tree: bridge-settings property is too small (0x%x)", propSize); + } + memcpy(propData, bridge_settings_dynamic, sizeof(bridge_settings_dynamic)); + } +} + +#endif diff --git a/platform/s5l8950x/miu/rules.mk b/platform/s5l8950x/miu/rules.mk new file mode 100644 index 0000000..8849cfe --- /dev/null +++ b/platform/s5l8950x/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s5l8950x/pmgr/pmgr.c b/platform/s5l8950x/pmgr/pmgr.c new file mode 100644 index 0000000..1ec0bb9 --- /dev/null +++ b/platform/s5l8950x/pmgr/pmgr.c @@ -0,0 +1,1230 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !APPLICATION_EMBEDDEDIOP + +#define PLL_VCO_TARGET(pllx) (2ULL * pllx##_O * ((pllx##_M) + 1) / ((pllx##_P) + 1)) +#define PLL_FREQ_TARGET(pllx) (2ULL * pllx##_O * ((pllx##_M) + 1) / ((pllx##_P) + 1) / ((pllx##_S) + 1)) + +static const u_int32_t clk_divs_bypass[PMGR_CLK_CFG_COUNT] = { + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x140: cpu, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x150: pll2_gate, pll4_gate, pll5_gate, rsvd + 0x00000000, 0x80000001, 0x80000001, 0x80000001, // 0x160: rsvd, mcu_fixed, mcu, pclk1 + 0x80000001, 0x80000001, 0x00000000, 0x00000000, // 0x170: gfx, gfx_slc, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x180: rsvd, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x190: prediv0, prediv1, prediv2, prediv3 + 0x80000001, 0x80000001, 0x80000001, 0x80000000, // 0x1A0: prediv4, prediv5, prediv6, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1B0: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1C0: rsvd, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1D0: venc_mtx, venc, hperf_rt, gfx_sys + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1E0: hperf_nrt, nrt_mem, vdec, isp + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1F0: iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x200: pclk2, pclk3, aes, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x210: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x220: rsvd, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x230: medium0, medium1, vid0, vid1 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x240: dispout, i2c, sdio, mipi_dsi, + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x250: audio, adsp_pclk0, adsp_tclk, adsp_tsclk + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x260: uperf, debug, scc_pwr, scc_dma + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x270: spi0, spi1, spi2, spi3 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x280: spi4, slow, sleep, usbphy + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x290: usbohci, usb12, nco_ref0, nco_ref1 + 0x00000000, 0x80000001, 0x80000001 // 0x2A0: mipi_agile, usbphy1, usbfree +}; + +struct dvfm_state { + u_int32_t pll_pms; + u_int16_t clk_src; + u_int8_t cpu_vi; + u_int8_t ram_vi; +}; + +static const struct dvfm_state dvfm_state_bypass = { + 0, // no PLL + 0, // use OSC + 0, // no cpu voltage + 0 // no ram voltage +}; + +static const u_int32_t perf_state_bypass[1 * 5] = { + 0x01010101, 0x01010101, 0x01010301, 0x01010101, 0x00000100, // defaults, slow mcu_cfg, no voltage change +}; + +struct perf_info { + u_int8_t dvfm_state; + u_int8_t perf_state; +}; + +#if APPLICATION_IBOOT + +#ifndef TARGET_PREDIV5_DIV +#define TARGET_PREDIV5_DIV 20 +#endif + +#ifndef TARGET_VID0_DIV +#define TARGET_VID0_DIV 1 +#endif + +#define PLL0_LOCK_TIME (11 * 24) + +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 2 +#define PLL2_M 49 +#define PLL2_S 0 +#define PLL2_V PLL_VCO_TARGET(PLL2) +#define PLL2_T PLL_FREQ_TARGET(PLL2) + +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 3 +#define PLL4_M 170 +#define PLL4_S 0 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) + +#define PLL5 5 +#define PLL5_O OSC_FREQ +#define PLL5_P 2 +#define PLL5_M 96 +#define PLL5_S 1 +#define PLL5_V PLL_VCO_TARGET(PLL5) +#define PLL5_T PLL_FREQ_TARGET(PLL5) +#define PLL5_LOCK_TIME (10 * 24) + +#define PLL6 6 +#define PLL6_O OSC_FREQ +#define PLL6_P 0 +#define PLL6_M 54 +#define PLL6_S 0 +#define PLL6_V PLL_VCO_TARGET(PLL6) +#define PLL6_T PLL_FREQ_TARGET(PLL6) +#define PLL6_LOCK_TIME (12 * 24) + +#define PLLUSB USB +#define PLLUSB_O OSC_FREQ +#define PLLUSB_P 0 +#define PLLUSB_M 19 +#define PLLUSB_S 0 +#define PLLUSB_V PLL_VCO_TARGET(PLLUSB) +#define PLLUSB_T PLL_FREQ_TARGET(PLLUSB) + +#define D_PREDIV5 (0x90000000 | (TARGET_PREDIV5_DIV)) +#define D_VID0 (0x90000000 | (TARGET_VID0_DIV)) + +static const u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x140: cpu, rsvd, rsvd, rsvd + 0x00000001, 0x80000002, 0x80000001, 0x00000000, // 0x150: pll2_gate, pll4_gate, pll5_gate, rsvd + 0x00000000, 0x80000001, 0x80000001, 0xB0000002, // 0x160: rsvd, mcu_fixed, mcu, pclk1 + 0x80000001, 0x80000001, 0x00000000, 0x00000000, // 0x170: gfx, gfx_slc, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x180: rsvd, rsvd, rsvd, rsvd + 0x90000005, 0x90000004, 0x90000003, 0xA0000001, // 0x190: prediv0, prediv1, prediv2, prediv3 + 0x90000002, D_PREDIV5, 0x90000007, 0x00000000, // 0x1A0: prediv4, prediv5, prediv6, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1B0: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1C0: rsvd, rsvd, rsvd, rsvd + 0x80000001, 0x80000002, 0x80000001, 0x80000001, // 0x1D0: venc_mtx, venc, hperf_rt, gfx_sys + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1E0: hperf_nrt, nrt_mem, vdec, isp + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1F0: iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x200: pclk2, pclk3, aes, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x210: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x220: rsvd, rsvd, rsvd, rsvd + 0x00000001, 0x8000000A, D_VID0, 0x90000013, // 0x230: medium0, medium1, vid0, vid1 + 0x8000000A, 0xB0000001, 0x80000004, 0x80000001, // 0x240: dispout, i2c, sdio, mipi_dsi, + 0x80000001, 0x90000002, 0x80000001, 0x90000001, // 0x250: audio, adsp_pclk0, adsp_tclk, adsp_tsclk + 0xA0000007, 0xA000000E, 0x80000001, 0xA000001F, // 0x260: uperf, debug, scc_pwr, scc_dma + 0xB0000001, 0xB0000001, 0xB0000001, 0xB0000001, // 0x270: spi0, spi1, spi2, spi3 + 0xB0000001, 0x80000018, 0x80000014, 0x80000001, // 0x280: spi4, slow, sleep, usbphy + 0x80000001, 0x80000002, 0xA0000002, 0x00000001, // 0x290: usbohci, usb12, nco_ref0, nco_ref1 + 0x00000000, 0x80000001, 0x80000001 // 0x2A0: mipi_agile, usbphy1, usbfree +}; + +#define DFVM_STATE_ACTIVE kDVFM_STATE_IBOOT +static const struct dvfm_state dvfm_state_active[] = { + { + PMGR_PLL_P(0) | PMGR_PLL_M(24) | PMGR_PLL_S(0), // PLL = 600MHz + 1, // Use Pll0 + 0, // Use CPU voltage 0 + CHIPID_RAM_VOLTAGE_LOW // Use low RAM voltage + }, + { + PMGR_PLL_P(0) | PMGR_PLL_M(34) | PMGR_PLL_S(0), // PLL = 840MHz + 1, // Use Pll0 + 1, // Use CPU voltage 1 + CHIPID_RAM_VOLTAGE_LOW, // Use low RAM voltage + }, + { + PMGR_PLL_P(0) | PMGR_PLL_M(45) | PMGR_PLL_S(0), // PLL = 1104MHz + 1, // Use Pll0 + 3, // Use CPU voltage 3 + CHIPID_RAM_VOLTAGE_HIGH, // Use high RAM voltage + }, +#if SUB_TARGET_N48 || SUB_TARGET_N49 + // lower freq for desense mitigation + { + PMGR_PLL_P(0) | PMGR_PLL_M(52) | PMGR_PLL_S(0), // PLL = 1272MHz + 1, // Use Pll0 + 5, // Use CPU voltage 5 + CHIPID_RAM_VOLTAGE_HIGH, // Use high RAM voltage + } +#else + { + PMGR_PLL_P(0) | PMGR_PLL_M(53) | PMGR_PLL_S(0), // PLL = 1296MHz + 1, // Use Pll0 + 5, // Use CPU voltage 5 + CHIPID_RAM_VOLTAGE_HIGH, // Use high RAM voltage + } +#endif +}; + +#define PERF_STATE_ACTIVE kPERF_STATE_IBOOT +static const u_int32_t perf_state_active[kPERF_STATE_IBOOT_CNT * 5] = { +#if ! SUPPORT_FPGA + 0x21444402, 0x02012101, 0x21426061, 0x41010121, CHIPID_SOC_VOLTAGE_MED, // divide by 1, mcu_cfg=0, high voltage + 0x01454502, 0x23420101, 0x61216121, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 2, mcu_cfg=1, low voltage + 0x01454502, 0x26440201, 0x61216222, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 4, mcu_cfg=2, low voltage + 0x01454502, 0x3f1f1f01, 0x61216328, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 31, mcu_cfg=3, low voltage + 0x01454502, 0x23420101, 0x61216061, 0x41424242, CHIPID_SOC_VOLTAGE_MED, // divide by 4, mcu_cfg=0, med voltage +#else /* SUPPORT_FPGA */ + 0x21444402, 0x02012101, 0x21216361, 0x41010121, CHIPID_SOC_VOLTAGE_MED, // divide by 1, mcu_cfg=3, med voltage + 0x01454502, 0x23420101, 0x61216321, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 2, mcu_cfg=3, low voltage + 0x01454502, 0x26440201, 0x61216322, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 4, mcu_cfg=3, low voltage + 0x01454502, 0x3f1f1f01, 0x61216328, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 31, mcu_cfg=3, low voltage + 0x01454502, 0x23420101, 0x61216361, 0x41424242, CHIPID_SOC_VOLTAGE_MED, // divide by 4, mcu_cfg=3, med voltage +#endif /* ! SUPPORT_FPGA */ +}; + +static const struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+0 }, + [kPerformanceMedium] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+1 }, + [kPerformanceLow] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+2 }, + [kPerformanceMemory] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+4 }, +}; + +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_SECUREROM + +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 3 +#define PLL4_M 170 +#define PLL4_S 3 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) + +static const u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x140: cpu, rsvd, rsvd, rsvd + 0x00000001, 0x80000001, 0x00000001, 0x00000000, // 0x150: pll2_gate, pll4_gate, pll5_gate, rsvd + 0x00000000, 0x80000001, 0x80000001, 0xB0000003, // 0x160: rsvd, mcu_fixed, mcu, pclk1 + 0x00000001, 0x00000001, 0x00000000, 0x00000000, // 0x170: gfx, gfx_slc, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x180: rsvd, rsvd, rsvd, rsvd + 0x90000004, 0x00000001, 0x00000001, 0x00000001, // 0x190: prediv0, prediv1, prediv2, prediv3 + 0x00000001, 0x00000001, 0x00000001, 0x00000000, // 0x1A0: prediv4, prediv5, prediv6, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1B0: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1C0: rsvd, rsvd, rsvd, rsvd + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x1D0: venc_mtx, venc, hperf_rt, gfx_sys + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x1E0: hperf_nrt, nrt_mem, vdec, isp + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1F0: iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x200: pclk2, pclk3, aes, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x210: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x220: rsvd, rsvd, rsvd, rsvd + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x230: medium0, medium1, vid0, vid1 + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x240: dispout, i2c, sdio, mipi_dsi, + 0x80000001, 0x00000001, 0x00000001, 0x00000001, // 0x250: audio, adsp_pclk0, adsp_tclk, adsp_tsclk + 0x80000002, 0xB0000001, 0x80000001, 0x80000006, // 0x260: uperf, debug, scc_pwr, scc_dma + 0xB0000001, 0x00000001, 0x00000001, 0xB0000001, // 0x270: spi0, spi1, spi2, spi3 + 0x00000001, 0x80000018, 0x80000014, 0x80000001, // 0x280: spi4, slow, sleep, usbphy + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x290: usbohci, usb12, nco_ref0, nco_ref1 + 0x00000000, 0x80000001, 0x80000001 // 0x2A0: mipi_agile, usbphy1, usbfree +}; + +#define DFVM_STATE_ACTIVE kDVFM_STATE_SECUREROM +static const struct dvfm_state dvfm_state_active = { + PMGR_PLL_P(1) | PMGR_PLL_M(74) | PMGR_PLL_S(3), // PLL = 225MHz + 1, // Use PLL0 + 0, // no cpu voltage + 0 // no ram voltage +}; + +#define PERF_STATE_ACTIVE kPERF_STATE_SECUREROM +static const u_int32_t perf_state_active[1 * 5] = { + 0x01010101, 0x01010101, 0x01010301, 0x01010101, 0x00000100, // defaults, slow mcu_cfg, no voltage change +}; + +static const struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, + [kPerformanceMedium] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, + [kPerformanceLow] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, + [kPerformanceMemory] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, +}; + +#endif /* APPLICATION_SECUREROM */ + +/* current clock speeds */ +static u_int32_t cpu_clks[kDVFM_STATE_COUNT]; +static u_int32_t clks[PMGR_CLK_COUNT]; +static u_int32_t *plls = &clks[PMGR_CLK_PLL0]; +static u_int32_t perf_level; + +struct clk_parent { + volatile u_int32_t *divider_reg; + u_int32_t divider_type; + u_int32_t divider_offset; + u_int8_t parents[4]; +}; + +/* Based on PMGR 1.10 */ +static const struct clk_parent clk_parents[PMGR_CLK_COUNT] = { +[PMGR_CLK_OSC] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL0] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL1] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL2] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL3] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL4] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL5] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL6] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL7] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLLUSB] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_DOUBLER] = { &rPMGR_DOUBLER_CTL, 0, 0x00, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_PLL2_GATED] = { &rPMGR_PLL2_GATE_CFG, 0, 0x00, { PMGR_CLK_PLL2, 0, 0, 0, } }, +[PMGR_CLK_PLL4_GATED] = { &rPMGR_PLL4_GATE_CFG, 1, 0x00, { PMGR_CLK_PLL4, 0, 0, 0, } }, +[PMGR_CLK_PLL5_GATED] = { &rPMGR_PLL5_GATE_CFG, 0, 0x00, { PMGR_CLK_PLL5, 0, 0, 0, } }, +[PMGR_CLK_MCU_FIXED] = { &rPMGR_MCU_FIXED_CLK_CFG, 2, 0x09, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4_GATED } }, +[PMGR_CLK_MCU] = { &rPMGR_MCU_CLK_CFG, 3, 0x08, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4_GATED } }, +[PMGR_CLK_CPU] = { &rPMGR_CPU_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL0, PMGR_CLK_PLL1, PMGR_CLK_MCU } }, +[PMGR_CLK_PREDIV0] = { &rPMGR_PREDIV0_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV1] = { &rPMGR_PREDIV1_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV2] = { &rPMGR_PREDIV2_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV3] = { &rPMGR_PREDIV3_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV4] = { &rPMGR_PREDIV4_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV5] = { &rPMGR_PREDIV5_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV6] = { &rPMGR_PREDIV6_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_GFX] = { &rPMGR_GFX_CLK_CFG, 3, 0x01, { PMGR_CLK_OSC, PMGR_CLK_PLL5, PMGR_CLK_PLL6, PMGR_CLK_PLL4 } }, +[PMGR_CLK_GFX_SLC] = { &rPMGR_GFX_SLC_CLK_CFG, 3, 0x02, { PMGR_CLK_OSC, PMGR_CLK_PLL5, PMGR_CLK_PLL6, PMGR_CLK_PLL4 } }, +[PMGR_CLK_GFX_SYS] = { &rPMGR_GFX_SYS_CLK_CFG, 3, 0x03, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_HPERFRT] = { &rPMGR_HPERFRT_CLK_CFG, 3, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_DISPOUT] = { &rPMGR_DISPOUT_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VID0] = { &rPMGR_VID0_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV5, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VID1] = { &rPMGR_VID1_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_MIPI_DSI] = { &rPMGR_MIPI_DSI_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV4, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_HPERFNRT] = { &rPMGR_HPERFNRT_CLK_CFG, 3, 0x0D, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_NRT_MEM] = { &rPMGR_NRT_MEM_CLK_CFG, 3, 0x0C, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VENC_MTX] = { &rPMGR_VENC_MTX_CLK_CFG, 3, 0x0B, { PMGR_CLK_PREDIV1, PMGR_CLK_PLLUSB, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VENC] = { &rPMGR_VENC_CLK_CFG, 1, 0x00, { PMGR_CLK_VENC_MTX, 0, 0, 0 } }, +[PMGR_CLK_VDEC] = { &rPMGR_VDEC_CLK_CFG, 3, 0x0E, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_ISP] = { &rPMGR_ISP_CLK_CFG, 3, 0x04, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_IOP] = { &rPMGR_IOP_CLK_CFG, 3, 0x05, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_CDIO] = { &rPMGR_CDIO_CLK_CFG, 3, 0x06, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_LPERFS] = { &rPMGR_LPERFS_CLK_CFG, 3, 0x07, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_PCLK0] = { &rPMGR_PCLK0_CLK_CFG, 0, 0x00, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK1] = { &rPMGR_PCLK1_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4_GATED } }, +[PMGR_CLK_PCLK2] = { &rPMGR_PCLK2_CLK_CFG, 0, 0x00, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK3] = { &rPMGR_PCLK3_CLK_CFG, 0, 0x00, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_AES] = { &rPMGR_AES_CLK_CFG, 3, 0x0F, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MEDIUM0] = { &rPMGR_MEDIUM0_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MEDIUM1] = { &rPMGR_MEDIUM1_CLK_CFG, 1, 0x00, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_I2C] = { &rPMGR_I2C_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV3, PMGR_CLK_OSC } }, +[PMGR_CLK_SDIO] = { &rPMGR_SDIO_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_AUDIO] = { &rPMGR_AUDIO_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_ADSP_PCLK0] = { &rPMGR_ADSP_PCLK0_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_ADSP_TCLK] = { &rPMGR_ADSP_TCLK_CLK_CFG, 3, 0x0A, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV6, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_ADSP_TSCLK] = { &rPMGR_ADSP_TSCLK_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_UPERF] = { &rPMGR_UPERF_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_DEBUG] = { &rPMGR_DEBUG_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_OSC } }, +[PMGR_CLK_SCC_PWR] = { &rPMGR_SCC_PWR_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_SCC_DMA] = { &rPMGR_SCC_DMA_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_SPI0] = { &rPMGR_SPI0_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI1] = { &rPMGR_SPI1_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI2] = { &rPMGR_SPI2_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI3] = { &rPMGR_SPI3_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI4] = { &rPMGR_SPI4_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SLOW] = { &rPMGR_SLOW_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_SLEEP] = { &rPMGR_SLEEP_CLK_CFG, 1, 0x00, { PMGR_CLK_SLOW, 0, 0, 0 } }, +[PMGR_CLK_USBPHY] = { &rPMGR_USBPHY_CLK_CFG, 0, 0x00, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_USBOHCI] = { &rPMGR_USBOHCI_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM1, PMGR_CLK_DOUBLER, 0, 0 } }, +[PMGR_CLK_USB12] = { &rPMGR_USB12_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_NCO_REF0] = { &rPMGR_NCO_REF0_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_NCO_REF1] = { &rPMGR_NCO_REF1_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +}; + +static void init_thermal_sensors(void); +static void clocks_get_frequencies(void); +static u_int32_t get_pll(int pll); +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t v); +static void clocks_set_gates(u_int64_t *devices, bool enable); +static void clocks_quiesce_internal(void); +static void update_perf_state(u_int32_t new_perf_state); + +void platform_power_init(void) +{ +#if APPLICATION_IBOOT + // Configure SCC CCXPWRCTRL to settings from H5P Tunables Revision 0.25 + rSCC_CCXPWRCTRL = 0x88800000; + + // Set Power Gating Parameters for all the power domains + rPMGR_PWR_GATE_TIME_A(1) = (719 << 16); // CPU0 + rPMGR_PWR_GATE_TIME_A(2) = (719 << 16); // CPU1 + rPMGR_PWR_GATE_TIME_A(6) = (34 << 16) | (1 << 0); // IOP + rPMGR_PWR_GATE_TIME_B(6) = (20 << 26) | (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(7) = (147 << 16) | (2 << 0); // GFX + rPMGR_PWR_GATE_TIME_B(7) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(8) = (123 << 16) | (2 << 0); // HPERF-RT + rPMGR_PWR_GATE_TIME_B(8) = (2 << 16) | (2 << 8) | (9 << 0); + rPMGR_PWR_GATE_TIME_A(9) = (139 << 16) | (2 << 0); // ISP + rPMGR_PWR_GATE_TIME_B(9) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(10) = (94 << 16) | (2 << 0); // HPERF-NRT + rPMGR_PWR_GATE_TIME_B(10) = (2 << 16) | (4 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(11) = (70 << 16) | (1 << 0); // VDEC + rPMGR_PWR_GATE_TIME_B(11) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(12) = (107 << 16) | (2 << 0); // VENC + rPMGR_PWR_GATE_TIME_B(12) = (2 << 16) | (4 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(13) = (29 << 16) | (2 << 0); // FMI + rPMGR_PWR_GATE_TIME_B(13) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(14) = (47 << 16) | (1 << 0); // ADSP + rPMGR_PWR_GATE_TIME_B(14) = (2 << 16) | (2 << 8) | (4 << 0); + + // Enable MCU_FIXED_CLK to be enabled/disabled based on request from MCU + rPMGR_ENABLE_CLK_GATE = (1 << 1); + + /* clear CPU1's reset; it will still be powered down */ + clock_reset_device(CLK_CPU1); + + init_thermal_sensors(); +#endif +} + +extern void aic_spin(u_int32_t usecs); + +void platform_power_spin(u_int32_t usecs) +{ + aic_spin(usecs); +} + +int clocks_init(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + + u_int32_t cnt, tmp; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) plls[cnt] = get_pll(cnt); + + // Find the perf_level using PERF_STATE_CTL + tmp = (rPMGR_PERF_STATE_CTL >> PMGR_PERF_STATE_SEL_SHIFT) & PMGR_PERF_STATE_SEL_MASK; + for (perf_level = kPerformanceHigh; perf_level < kPerformanceLow; perf_level++) { + if (perf_levels[perf_level].perf_state == tmp) break; + } + + clocks_get_frequencies(); + +#endif /* (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) */ + + return 0; +} + +/* clocks_set_default - called by SecureROM, LLB, iBSS main via + platform_init_setup_clocks, so the current state of the chip is + either POR, or whatever 'quiesce' did when leaving SecureROM. */ +int clocks_set_default(void) +{ + u_int32_t cnt, count, reg, val; + u_int32_t cpu_vid[kDVFM_STATE_COUNT], ram_vid[2], soc_vid[3]; + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + count = 0; + + for (cnt = 0; cnt < kDVFM_STATE_COUNT; cnt++) { + cpu_vid[cnt] = 0; + } + ram_vid[0] = ram_vid[1] = 0; + soc_vid[0] = soc_vid[1] = soc_vid[2] = 0; + + // Set up the bypass dvfm and performance states + rPMGR_DVFM_CFG0(kDVFM_STATE_BYPASS) = dvfm_state_bypass.pll_pms; + rPMGR_DVFM_CFG1(kDVFM_STATE_BYPASS) = dvfm_state_bypass.clk_src << PMGR_DVFM_CFG1_CLK_SRC_SHIFT; + rPMGR_DVFM_CFG2(kDVFM_STATE_BYPASS) = 0; + rPMGR_DVFM_CFG3(kDVFM_STATE_BYPASS) = 0; + rPMGR_DVFM_CFG4(kDVFM_STATE_BYPASS) = 0; + rPMGR_PERF_STATE_A(kPERF_STATE_BYPASS) = perf_state_bypass[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_BYPASS) = perf_state_bypass[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_BYPASS) = perf_state_bypass[2]; + rPMGR_PERF_STATE_D(kPERF_STATE_BYPASS) = perf_state_bypass[3]; + rPMGR_PERF_STATE_E(kPERF_STATE_BYPASS) = perf_state_bypass[4]; + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + + // Set default PLL parameters and lock time (1260 cycles) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + rPMGR_PLL_PARAM(cnt) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(1260); + } + +#if APPLICATION_SECUREROM + // Set up the active dvfm and performance states for the SecureROM + rPMGR_DVFM_CFG0(kDVFM_STATE_SECUREROM) = dvfm_state_active.pll_pms; + rPMGR_DVFM_CFG1(kDVFM_STATE_SECUREROM) = dvfm_state_active.clk_src << PMGR_DVFM_CFG1_CLK_SRC_SHIFT; + rPMGR_DVFM_CFG2(kDVFM_STATE_SECUREROM) = 0; + rPMGR_DVFM_CFG3(kDVFM_STATE_SECUREROM) = 0; + rPMGR_DVFM_CFG4(kDVFM_STATE_SECUREROM) = 0; + rPMGR_PERF_STATE_A(kPERF_STATE_SECUREROM) = perf_state_active[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_SECUREROM) = perf_state_active[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_SECUREROM) = perf_state_active[2]; + rPMGR_PERF_STATE_D(kPERF_STATE_SECUREROM) = perf_state_active[3]; + rPMGR_PERF_STATE_E(kPERF_STATE_SECUREROM) = perf_state_active[4]; +#endif + +#if APPLICATION_IBOOT + // Find the VID codes for the CPU, RAM and SoC rails + platform_get_cpu_voltages(kDVFM_STATE_COUNT, cpu_vid); + platform_get_ram_voltages(2, ram_vid); + platform_get_soc_voltages(3, soc_vid); + platform_convert_voltages(0, kDVFM_STATE_COUNT, cpu_vid); + platform_convert_voltages(16, 2, ram_vid); + platform_convert_voltages(2, 3, soc_vid); + + count = sizeof(dvfm_state_active) / sizeof(struct dvfm_state); + // Set up the active dvfm and performance states for iBoot + for (cnt = 0; cnt < count; cnt++) { + // Set PLL Configuration + rPMGR_DVFM_CFG0(kDVFM_STATE_IBOOT + cnt) = dvfm_state_active[cnt].pll_pms; + + // Set PLL Source and CPU Voltage Configuration + val = dvfm_state_active[cnt].clk_src << PMGR_DVFM_CFG1_CLK_SRC_SHIFT; + val |= (cpu_vid[dvfm_state_active[cnt].cpu_vi] & PMGR_DVFM_CFG1_VOL_MASK) << PMGR_DVFM_CFG1_SAFE_VOL_SHIFT; + rPMGR_DVFM_CFG1(kDVFM_STATE_IBOOT + cnt) = val; + + // Set SRAM Voltage and Temperature Sensor Region Configuration (0mV, 15.625mV & 31.25mV) + // H5 Tunables Rev 0.60 + val = (0xA << 12) | (0x5 << 6) | (0x0 << 0); + val |= (ram_vid[dvfm_state_active[cnt].ram_vi] & PMGR_DVFM_CFG2_SRAM_VOL_MASK) << PMGR_DVFM_CFG2_SRAM_VOL_SHIFT; + rPMGR_DVFM_CFG2(kDVFM_STATE_IBOOT + cnt) = val; + + // Set Speed Sensor Configuration + rPMGR_DVFM_CFG3(kDVFM_STATE_IBOOT + cnt) = 0; + rPMGR_DVFM_CFG4(kDVFM_STATE_IBOOT + cnt) = 0; + } + + for (cnt = 0; cnt < kPERF_STATE_IBOOT_CNT; cnt++) { + // Set the Clock Sources and Dividers + rPMGR_PERF_STATE_A(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 0]; + rPMGR_PERF_STATE_B(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 1]; + rPMGR_PERF_STATE_C(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 2]; + rPMGR_PERF_STATE_D(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 3]; + + // Set the SoC Voltage Configuration + val = perf_state_active[(cnt * 5) + 4]; + reg = val & PMGR_PERF_STATE_E_VOL_MASK; + val = (val & ~PMGR_PERF_STATE_E_VOL_MASK) | + ((soc_vid[reg] & PMGR_PERF_STATE_E_VOL_MASK) << PMGR_PERF_STATE_E_VOL_SHIFT); + rPMGR_PERF_STATE_E(kPERF_STATE_IBOOT + cnt) = val; + } + + // Save the PERF_STATE configuration in rPMGR_SCRATCH1 + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, kPERF_STATE_IBOOT + 3); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), kPERF_STATE_IBOOT + 2); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), kPERF_STATE_IBOOT + 3); + +#ifdef PLL0_LOCK_TIME + // Override the PLL0 lock time + rPMGR_PLL_PARAM(0) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL0_LOCK_TIME); +#endif /* PLL0_LOCK_TIME */ + +#ifdef PLL1_LOCK_TIME + // Override the PLL1 lock time + rPMGR_PLL_PARAM(1) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL1_LOCK_TIME); +#endif /* PLL1_LOCK_TIME */ + +#ifdef PLL2_LOCK_TIME + // Override the PLL2 lock time + rPMGR_PLL_PARAM(2) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL2_LOCK_TIME); +#endif /* PLL2_LOCK_TIME */ + +#ifdef PLL3_LOCK_TIME + // Override the PLL3 lock time + rPMGR_PLL_PARAM(3) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL3_LOCK_TIME); +#endif /* PLL3_LOCK_TIME */ + +#ifdef PLL4_LOCK_TIME + // Override the PLL4 lock time + rPMGR_PLL_PARAM(4) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL4_LOCK_TIME); +#endif /* PLL4_LOCK_TIME */ + +#ifdef PLL5_LOCK_TIME + // Override the PLL5 lock time + rPMGR_PLL_PARAM(5) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL5_LOCK_TIME); +#endif /* PLL5_LOCK_TIME */ + +#ifdef PLL6_LOCK_TIME + // Override the PLL6 lock time + rPMGR_PLL_PARAM(6) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL6_LOCK_TIME); +#endif /* PLL6_LOCK_TIME */ + +#ifdef PLL7_LOCK_TIME + // Override the PLL7 lock time + rPMGR_PLL_PARAM(7) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLL7_LOCK_TIME); +#endif /* PLL7_LOCK_TIME */ + +#ifdef PLLUSB_LOCK_TIME + // Override the PLLUSB lock time + rPMGR_PLL_PARAM(8) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(PLLUSB_LOCK_TIME); +#endif /* PLLUSB_LOCK_TIME */ + + // Configure SoC Voltage Delay for 12uS plus 6.25mV/uS + rPMGR_PERF_STATE_DELAY = + (144 << PMGR_PERF_STATE_DELAY_VOL_CHG_FIX_DLY_SHIFT) | (12 << PMGR_PERF_STATE_DELAY_VOL_CHG_VAR_DLY_SHIFT); + + // Configure Sensor Interval to about 1ms and + // CPU Voltage Delay for 12uS plus 6.25mV/uS + rPMGR_DVFM_DELAY = + (0 << 28) | (6 << 18) | + (144 << PMGR_DVFM_DELAY_VOL_CHG_FIX_DLY_SHIFT) | (12 << PMGR_DVFM_DELAY_VOL_CHG_VAR_DLY_SHIFT); + + // Configure SRAM Voltage Delay for 12uS plus 6.25mV/uS + rPMGR_DVFM_SRAM_VOL_DELAY = + (144 << PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_FIX_DLY_SHIFT) | (12 << PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_VAR_DLY_SHIFT); + + // Set Static Temperature Sensor Configuration with cut offs at 48C and 23C + // H5 Tunables Rev 0.60 + rPMGR_DVFM_COMMON_CFG = + ((chipid_get_cpu_temp_offset(1) & 0x7F) << 21) | + ((chipid_get_cpu_temp_offset(0) & 0x7F) << 14) | + (0x4F << 7) | (0x39 << 0); + + // Configure Temperature Sensors + rPMGR_SENSOR_CMD = (1 << 20) | (1 << 16) | (0x827 << 0); + + // Set Voltage Control Configuration + rPMGR_VOLMAN_CTL = PMGR_VOLMAN_CPU_SW_OFF_TIME_VALUE(45) | PMGR_VOLMAN_BIT_ORDER_MSB | PMGR_VOLMAM_BYTE_SWAP; + +#if WITH_HW_DWI + extern int dwi_init(void); + dwi_init(); +#endif +#endif + +#ifdef PLL2_T + set_pll(2, PLL2_P, PLL2_M, PLL2_S, PLL2_V); +#endif + +#ifdef PLL3_T + set_pll(3, PLL3_P, PLL3_M, PLL3_S, PLL3_V); +#endif + +#ifdef PLL4_T + set_pll(4, PLL4_P, PLL4_M, PLL4_S, PLL4_V); +#endif + +#ifdef PLL5_T + set_pll(5, PLL5_P, PLL5_M, PLL5_S, PLL5_V); +#endif + +#ifdef PLL6_T + set_pll(6, PLL6_P, PLL6_M, PLL6_S, PLL6_V); +#endif + +#ifdef PLL7_T + set_pll(7, PLL7_P, PLL7_M, PLL7_S, PLL7_V); +#endif + +#ifdef PLLUSB_T + set_pll(8, PLLUSB_P, PLLUSB_M, PLLUSB_S, PLLUSB_V); +#endif + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) plls[cnt] = get_pll(cnt); + + perf_level = kPerformanceLow; + + // Set all clock dividers to their active values + // Start with CPU then work backwards + for (cnt = 0; cnt < PMGR_CLK_CFG_COUNT; cnt++) { + reg = PMGR_CLK_CFG_COUNT - cnt; + if (reg == PMGR_CLK_CFG_COUNT) reg = 0; + + // Take care of managed clocks before predivs + if (reg == PMGR_FIRST_MANAGED_CLK_NUM) + update_perf_state(kPerformanceLow); + + val = clk_divs_active[reg]; + + clkcfgs[reg] = val; + while (clkcfgs[reg] & PMGR_CLK_CFG_PENDING); + } + + clocks_get_frequencies(); + + return 0; +} + +static void update_perf_state(u_int32_t new_perf_level) +{ + // Write the new select value for scc and soc + rPMGR_APSC_STA_CTL = PMGR_APSC_MANUAL_CHANGE(perf_levels[new_perf_level].dvfm_state, perf_levels[new_perf_level].perf_state); + + // Spin while the pending bit is asserted + while ((rPMGR_APSC_STA_CTL & PMGR_APSC_PENDING) != 0); +} + +void clocks_quiesce(void) +{ + /* mcu_clk will be changed to bypass clock */ + clks[PMGR_CLK_MCU] = OSC_FREQ; + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + + /* effectively full performance */ + perf_level = kPerformanceHigh; +} + +static void clock_update_range(u_int32_t first, u_int32_t last, const u_int32_t clkdata[]) +{ + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + u_int32_t val, reg; + + reg = first; + while (reg <= last) { + val = clkdata[reg]; + clkcfgs[reg] = val; + while (clkcfgs[reg] & PMGR_CLK_CFG_PENDING); + reg++; + } +} + +static void clocks_quiesce_internal(void) +{ + u_int32_t cnt; + u_int64_t devices[2]; + + // Disable voltage changes + rPMGR_VOLMAN_CTL = PMGR_VOLMAN_DISABLE_VOL_CHANGE; + + // Critical: AIC, DEBUG, GPIO, UPERF, CDMA, CDIO, + // MCU, L2, L2_BIU, CPU0, SCC + devices[0] = 0x00000002C0000136ULL; + devices[1] = 0x000000000000C800ULL; + + // Turn on critical device clocks + clocks_set_gates(devices, true); + + // Turn off non-critical device clocks + clocks_set_gates(devices, false); + + // Simplified from PMGR Spec 0.045 Section 2.14.4.1 + + // Reset top-level dividers to bypass + clock_update_range(PMGR_CLK_NUM(PCLK1), PMGR_CLK_NUM(PREDIV6), clk_divs_bypass); + clock_update_range(PMGR_CLK_NUM(VID1), PMGR_CLK_NUM(VID1), clk_divs_bypass); + +#if APPLICATION_IBOOT + miu_bypass_prep(0); + + // Prepare to move memory to bypass clock (ensure not high frequency, enable DLL force mode) + rPMGR_APSC_STA_CTL = PMGR_APSC_MANUAL_CHANGE(perf_levels[kPerformanceMedium].dvfm_state, perf_levels[kPerformanceMedium].perf_state); + while ((rPMGR_APSC_STA_CTL & PMGR_APSC_PENDING) != 0); + + miu_bypass_prep(1); +#endif + + // Reset scc and soc managed clocks + rPMGR_APSC_STA_CTL = PMGR_APSC_MANUAL_CHANGE(kDVFM_STATE_BYPASS, kPERF_STATE_BYPASS); + while ((rPMGR_APSC_STA_CTL & PMGR_APSC_PENDING) != 0); + + // Reset PLLs + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + rPMGR_PLL_CTL0(cnt) = PMGR_PLL_EXT_BYPASS; + + // Wait for Bypass Enabled for PLL2 or higher + while ((cnt >= 2) && !(rPMGR_PLL_DEBUG(cnt) & PMGR_PLL_DEBUG_BYP_ENABLED)) ; + } + + // Reset Doubler + rPMGR_DOUBLER_CTL = PMGR_DOUBLER_EXT_BYPASS; + while (!(rPMGR_DOUBLER_DEBUG & PMGR_DOUBLER_DEBUG_BYP_ENABLED)) ; + + // Reset the lower-level clocks + clock_update_range(PMGR_CLK_NUM(VENC_MTX), PMGR_CLK_NUM(NCO_REF1), clk_divs_bypass); + + // Reset the CPU clocks + clock_update_range(PMGR_CLK_NUM(CPU), PMGR_CLK_NUM(MCU), clk_divs_bypass); +} + +u_int32_t clocks_set_performance(u_int32_t performance_level) +{ + u_int32_t old_perf_level = perf_level; + + update_perf_state(performance_level); + perf_level = performance_level; + return old_perf_level; +} + +void clock_get_frequencies(u_int32_t *clocks, u_int32_t count) +{ + u_int32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) cnt = count; + + memcpy(clocks, clks, cnt * sizeof(u_int32_t)); +} + +u_int32_t clock_get_frequency(int clock) +{ + switch (clock) { + case CLK_CPU: + case CLK_FCLK: + return clks[PMGR_CLK_CPU]; + case CLK_ACLK: + case CLK_MEM: + return clks[PMGR_CLK_MCU]; + case CLK_HCLK: + case CLK_BUS: + return clks[PMGR_CLK_CDIO]; + case CLK_PERIPH: + case CLK_PCLK: + return clks[PMGR_CLK_PCLK0]; + case CLK_FMI: + return clks[PMGR_CLK_PCLK1]; + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + return clks[PMGR_CLK_OSC]; + case CLK_USBPHYCLK: +#if SUPPORT_FPGA + return clks[PMGR_CLK_USBPHY]; /* The reference is special on FPGA */ +#else + return clks[PMGR_CLK_OSC]; /* This is ref_24_clk, not usb_phy_clk */ +#endif + case CLK_NCOREF: + return clks[PMGR_CLK_NCO_REF0]; + case CLK_VCLK0: + return clks[PMGR_CLK_VID0]; + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + return clks[PMGR_CLK_I2C]; + case CLK_MIPI: + return clks[PMGR_CLK_MIPI_DSI]; + case CLK_MCLK: + default: + return 0; + } +} + +void clock_set_frequency(int clock, u_int32_t divider, u_int32_t pll_p, u_int32_t pll_m, u_int32_t pll_s, u_int32_t pll_t) +{ + u_int32_t total_div, prediv5_div, vid0_div; + + switch (clock) { + case CLK_VCLK0: + // Calculate the total divider required + total_div = clks[PMGR_CLK_PLL4] / pll_t; + + // Find the largest prediv5_div that will + // produce the correct total_div + for (prediv5_div = 31; prediv5_div > 1; prediv5_div--) { + if ((total_div % prediv5_div) == 0) break; + } + + // Calculate vid0_div based on the part of + // total_div not in prediv6_div + vid0_div = total_div / prediv5_div; + + // Set the clock dividers to their new values + rPMGR_PREDIV5_CLK_CFG = (rPMGR_PREDIV5_CLK_CFG & ~0x1f) | prediv5_div; + rPMGR_VID0_CLK_CFG = (rPMGR_VID0_CLK_CFG & ~0x1f) | vid0_div; + + // Update the list of frequencies + clks[PMGR_CLK_PREDIV5] = clks[PMGR_CLK_PLL4] / prediv5_div; + clks[PMGR_CLK_VID0] = clks[PMGR_CLK_PREDIV5] / vid0_div; + break; + default: + break; + } +} + +void clock_gate(int device, bool enable) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + if (reg > PMGR_LAST_PS) return; + + // Set the PS field to the requested level + if (enable) *reg |= 0xF; + else *reg &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + while ((*reg & 0xF) != ((*reg >> 4) & 0xF)); +} + +static void clocks_set_gates(u_int64_t *devices, bool enable) +{ + u_int32_t dev, index; + volatile u_int32_t *devpss = PMGR_FIRST_PS; + u_int64_t mask = 1, devmask = 0; + + for (dev = 0, index = -1; dev < PMGR_PS_COUNT; dev++, mask <<= 1) { + if ((dev % 64) == 0) { + devmask = devices[++index]; + if (enable == false) + devmask ^= -1ULL; + mask = 1; + } + // Skip SCC + if (dev < PMGR_PS_NUM(MCU)) continue; + if ((devmask & mask) != 0) { + if (enable) devpss[dev] |= 0xF; + else devpss[dev] &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + while ((devpss[dev] & 0xF) != ((devpss[dev] >> 4) & 0xF)); + } + } +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + // Use WDOG pin to cause a PMU reset + gpio_configure_out(GPIO_SYSTEM_RESET, 1); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_watchdog_tickle(void) +{ + // Varies by target. This layer between is necessary so that + // we don't go straight from generic code to target. + target_watchdog_tickle(); +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + u_int32_t cnt; + u_int32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_CPU] = 15000000; + clks[PMGR_CLK_MCU] = 10000000; + clks[PMGR_CLK_MCU_FIXED]= 10000000; + clks[PMGR_CLK_USBPHY] = 12000000; + + for (cnt = 0; cnt < (kDVFM_STATE_IBOOT + 1); cnt++) { + cpu_clks[cnt] = clks[PMGR_CLK_CPU]; + } + + // keep compiler happy + cnt = (u_int32_t)clk_parents; + +#else + volatile u_int32_t *reg; + u_int32_t cnt, val, p, m, s, source, divider, parent_idx; + u_int32_t divider_type, divider_offset; + u_int64_t freq; + u_int8_t *managed = (u_int8_t *)perf_state_active; + + for (cnt = 0; cnt < kDVFM_STATE_COUNT; cnt++) { + // ignore DVFM states with no voltage + if ((rPMGR_DVFM_CFG1(cnt) & 0xFF) == 0) continue; + + // decode the PLL settings + val = rPMGR_DVFM_CFG0(cnt); + p = 1 + ((val >> 9) & 0x1FF); + m = 1 + ((val >> 18) & 0x1FF); + s = 1 + ((val >> 0) & 0x1FF); + + // calculate the frequency + freq = OSC_FREQ; + freq *= m; + freq /= p * s; + + // save the frequency + cpu_clks[cnt] = freq; + } + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) { + reg = clk_parents[cnt].divider_reg; + if (reg == 0) continue; + val = *reg; + + // Check if the clock in enabled + if ((val & PMGR_CLK_CFG_ENABLE) == 0) continue; + + divider_type = clk_parents[cnt].divider_type; + divider_offset = clk_parents[cnt].divider_offset; + + source = 0; + divider = 1; + + switch (divider_type) { + case 1 : // Normal with divider + divider = (val >> 0) & PMGR_CLK_CFG_DIV_MASK; + // fall through + + case 0 : // Normal without divider + source = (val >> 28) & 3; + break; + + case 3 : // Managed with divider + divider = (managed[divider_offset] >> 0) & PMGR_CLK_CFG_DIV_MASK; + // fall through + + case 2 : // Managed without divider + source = (managed[divider_offset] >> 5) & 3; + break; + } + + parent_idx = clk_parents[cnt].parents[source]; + freq = clks[parent_idx]; + + if ((cnt == PMGR_CLK_DOUBLER) && ((val & PMGR_DOUBLER_EXT_BYPASS) != 0)) + freq *= 2; + + freq /= divider; + + clks[cnt] = freq; + } +#endif +} + +static u_int32_t get_pll(int pll) +{ + u_int32_t pll_ctl0, pll_ctl1; + u_int64_t freq = 0; + + if (pll >= PMGR_PLL_COUNT) return 0; + + pll_ctl0 = rPMGR_PLL_CTL0(pll); + pll_ctl1 = rPMGR_PLL_CTL1(pll); + + if ((pll_ctl0 & PMGR_PLL_ENABLE) == 0) return 0; + + if ((pll_ctl0 & (PMGR_PLL_EXT_BYPASS | PMGR_PLL_BYPASS))) { + freq = OSC_FREQ; + } else { + freq = OSC_FREQ; + freq *= 1 + ((pll_ctl1 >> PMGR_PLL_M_SHIFT) & PMGR_PLL_MASK); // *M + freq /= 1 + ((pll_ctl1 >> PMGR_PLL_P_SHIFT) & PMGR_PLL_MASK); // /P + freq /= 1 + ((pll_ctl1 >> PMGR_PLL_S_SHIFT) & PMGR_PLL_MASK); // /S + } + + return freq; +} + +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t vco) +{ + if (pll >= PMGR_PLL_COUNT) return; + + // Set the P, M & S values + rPMGR_PLL_CTL1(pll) = PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s); + + // Enable the PLL and request it load the configuration + rPMGR_PLL_CTL0(pll) = PMGR_PLL_ENABLE | PMGR_PLL_LOAD; + + // Wait for the PLL to lock + while ((rPMGR_PLL_CTL0(pll) & PMGR_PLL_REAL_LOCK) == 0); +} + +#endif + +void clock_reset_device(int device) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + switch (device) { + case CLK_CPU1 : + case CLK_FMI0 : + case CLK_FMI1 : + case CLK_IOP : + case CLK_MCU : + case CLK_SDIO : + *reg |= PMGR_PS_RESET; + spin(1); + *reg &= ~PMGR_PS_RESET; + break; + + default : + break; + } +} + +#if WITH_DEVICETREE + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ + u_int32_t cnt, count, propSize, perf_state_config; + u_int64_t freq, period_ns; + u_int32_t cpu_volt[kDVFM_STATE_COUNT]; + char *propName; + void *propData; + + // Get the PERF_STATE configuration generated at hardware init + perf_state_config = rPMGR_SCRATCH1; + if (perf_state_config == 0) return; + + // Fill in the firmware-v-perf-states property + propName = "firmware-v-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(u_int32_t))) { + panic("pmgr property firmware-v-perf-states is the wrong size"); + } + // Voltage states are in reverse order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), perf_state_config); + } + + // Fill in the firmware-p-perf-state property + propName = "firmware-p-perf-state"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (1 * sizeof(u_int32_t))) { + panic("pmgr property firmware-p-perf-states is the wrong size"); + } + // There is only one Frequency Managed / Performance state + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, perf_state_config); + } + + // Fill in the firmware-m-perf-states property + propName = "firmware-m-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (4 * sizeof(u_int32_t))) { + panic("pmgr property firmware-m-perf-states is the wrong size"); + } + // Memory states are in the same order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), perf_state_config); + ((u_int32_t *)propData)[2] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), perf_state_config); + ((u_int32_t *)propData)[3] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), perf_state_config); + } + + // Fill in the voltage-states1 property + propName = "voltage-states1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + count = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(kDVFM_STATE_COUNT, cpu_volt); + if (count > (kDVFM_STATE_COUNT - kDVFM_STATE_IBOOT)) count = kDVFM_STATE_COUNT - kDVFM_STATE_IBOOT; + for (cnt = 0; cnt < count; cnt++) { + freq = cpu_clks[kDVFM_STATE_IBOOT + cnt]; + if (freq == 0) break; + + // Calculate the period is ns as a 16.16 fixed point number + period_ns = 1000000000ULL << 16; + period_ns /= freq; + + // Save the period and voltage + ((u_int32_t *)propData)[2*cnt] = period_ns; + ((u_int32_t *)propData)[2*cnt+1] = cpu_volt[dvfm_state_active[cnt].cpu_vi]; + } + } +} + +#endif + +void init_thermal_sensors(void) +{ + // Grab the 4 bit fuse revision + u_int32_t fuseRevision = chipid_get_fuse_revision(); + + // Bits [1 - 0] PWRDN Mode and enable. + // Bits [3 - 2] Reserved. + // Bits [ 4 ] Stat mode for Avg Max on. + // Bits [18 - 5] TADC_CFG Tmpsadc configuration bits. + // Bits [31 - 19] Misc interrupt/Alarm stick bits not used. + rPMGR_THERMAL0_CTL0 = 0x000184F0; + rPMGR_THERMAL1_CTL0 = 0x000184F0; + + // Bits [15 - 0] PWRDN_START 20us wait + // Bits [31 - 16] PWRDN_GAP Gap between two readings. + rPMGR_THERMAL0_CTL1 = 0x005B01E4; + rPMGR_THERMAL1_CTL1 = 0x005B01E4; + + // Bits [7 - 0] Conv_Cycle, cycles to wait before data is valid. + // Bits [15 - 8] Enable_Cycle, cycles to wait before adc_en can be deasserted. + // Bits [23 - 16] Finish_gap, Cycles to wait before adc_en can be reasserted. + // Bits [31 - 24] Reserved. + rPMGR_THERMAL0_CTL2 = 0x00100848; + rPMGR_THERMAL1_CTL2 = 0x00100848; + + for (u_int32_t sensorID = 0; sensorID < 2; sensorID++) { + + u_int32_t fusedTempValueAt70 = chipid_get_fused_thermal_sensor_70C(sensorID); + u_int32_t fusedTempValueAt25 = chipid_get_fused_thermal_sensor_25C(sensorID); + u_int32_t tempSlope = 0x100; + + // Should probably make sure we don't divide by zero. + if (fusedTempValueAt25 == fusedTempValueAt70) { + fusedTempValueAt70 = 70; + fusedTempValueAt25 = 25; + dprintf(DEBUG_INFO, "Invalid soc thermal fuse values\n"); + } + + if (fuseRevision > 0) { + // 45 = 70 - 25 + tempSlope = (45*256) / (fusedTempValueAt70 - fusedTempValueAt25); + } else { + dprintf(DEBUG_INFO, "Invalid soc thermal sensor fuse revision number.\n"); + } + + // Calculate the real offset. + u_int32_t realOffset = 25 - ((tempSlope * fusedTempValueAt25) / (tempSlope==0x100 ? 1:256)); + + // Bits 23 16 + // Temp_OFFSET => [8 bit signed integer] + // Bits 9 0 + // TEMP_SLOPE => [2 bit integer| 8 bit decimal] + switch (sensorID) { + case 0: + rPMGR_THERMAL0_CTL3 = (realOffset & 0xFF) << 16; + rPMGR_THERMAL0_CTL3 |= tempSlope & 0x3FF; + break; + case 1: + rPMGR_THERMAL1_CTL3 = (realOffset & 0xFF) << 16; + rPMGR_THERMAL1_CTL3 |= tempSlope & 0x3FF; + break; + } + } +} diff --git a/platform/s5l8950x/pmgr/rules.mk b/platform/s5l8950x/pmgr/rules.mk new file mode 100644 index 0000000..fa626c5 --- /dev/null +++ b/platform/s5l8950x/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s5l8950x/rules.mk b/platform/s5l8950x/rules.mk new file mode 100644 index 0000000..cfdb2b9 --- /dev/null +++ b/platform/s5l8950x/rules.mk @@ -0,0 +1,124 @@ +# Copyright (C) 2010-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +############################################################################## +# Code running on the main CPU +# +ifeq ($(PLATFORM_VARIANT),) + +ARM_CPU := apple-swift + +# Devmap chip ID based on sub-platform identifier +ifeq ($(SUB_PLATFORM),s5l8950x) +DEVMAP_CHIP_ID := 8950 +endif + +MAX_DFU_SIZE := 393216 + +ifeq ($(TEXT_BANK),srom) +TEXT_BASE := 0x00000000 +endif +ifeq ($(TEXT_BANK),sram) +TEXT_BASE := 0x10000000 +endif +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0xBFF00000 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + WITH_LEGACY_PANIC_LOGS=1 \ + WITH_NO_RANDOM_HEAP_COOKIE=1 \ + WITH_NO_RANDOM_STACK_COOKIE=1 \ + WITH_NON_COHERENT_DMA=1 \ + WITH_ROM_TRAMPOLINE=1 \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=192 \ + PLATFORM_START_FUNCTION=_platform_start \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +# L2_CACHE_SIZE=1048576 \ +# + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) +# This selects the start of the DATA segment and the end of the INSECURE_MEMORY area +DATA_BASE := 0x10060000 + +OPTIONS += \ + DATA_BASE="$(DATA_BASE)" + +GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o + +endif + +############################################################################## +# Code running on the IOP +# +ifeq ($(PLATFORM_VARIANT),IOP) + +OPTIONS += \ + PLATFORM_VARIANT_IOP=1 \ + AIC_CPU_ID=2 \ + WITH_PLATFORM_HALT=1 \ + SUPPORT_SLEEP=1 \ + WITH_IOP_POWER_GATING=1 \ + DEEP_IDLE_THRESHOLD_US=10000 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o +endif + +############################################################################## +# Code running on the audio engine +# +ifeq ($(PLATFORM_VARIANT),Audio) + +OPTIONS += \ + PLATFORM_VARIANT_AUDIO=1 \ + WITH_PLATFORM_HALT=1 \ + SUPPORT_SLEEP=1 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o + +endif diff --git a/platform/s5l8955x/amc/amc.c b/platform/s5l8955x/amc/amc.c new file mode 100644 index 0000000..522b47d --- /dev/null +++ b/platform/s5l8955x/amc/amc.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + return amc_init(resume); +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping (void) +{ + amc_configure_default_address_decoding_and_mapping(); +} + +void amc_enable_slow_boot (bool enable) +{ + int slow_freqsel; + + if (enable) { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + rAMC_FREQSEL = amc_params.freqsel; + return; + } + + slow_freqsel = 3; + rAMC_BOOTCLK = (amc_params.bootclkdivsr << 8) | 1; + spin(1); + rAMC_FREQSEL = slow_freqsel; + amc_phy_scale_dll(slow_freqsel, amc_params.bootclkdivsr); + } else { + if ((amc_params.flags & FLAG_AMC_PARAM_SLOW_BOOT) == false) { + return; + } + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_small; + spin(2); + + rAMC_BOOTCLK &= ~1; + spin(5); + rAMC_FREQSEL = amc_params.freqsel; + amc_phy_scale_dll(amc_params.freqsel, 1); + + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_guided; + } +} + +void amc_finalize (bool resume) +{ + uint8_t odts; + +#if SUPPORT_FPGA + rAMC_PWRMNGTEN |= 0x00000001; // Sharing clocks between channels so do not enable clock stopping for PD or SR +#else + rAMC_PWRMNGTEN |= 0x00011011; +#endif + + rAMC_AREFPARAM |= (0x00001000); // Turn on freq change waiting for refresh and self-refresh exit + + amc_mrcmd(MR_READ, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x4, (uintptr_t)&odts); + rAMC_ODTS = 0x00010320; // [16] => TempDrtEn, [9:0] RdIntrvl XXX based on tREFI + + if (!resume) { + amc_enable_autorefresh(); + } + +#if SUPPORT_FPGA + rAMC_FREQSEL = amc_params.freqsel; +#endif + +#if !SUPPORT_FPGA + // Turn of Fast Critical Word Forwarding feature and AIU CWF feature + // Disabled for NRT + rAMC_AIUPRT_RD_CWF = 0x00161600; + rAMC_QBRPARAM = 0x00810000; + rAMC_QBREN = 0x00111001; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + + case JEDEC_MANUF_ID_SAMSUNG: + + // Samsung 3xnm DRAMs - not functional + if ((!resume) && (dev_info->rev_id == 1) && (dev_info->rev_id2 == 0)) { + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xff); + + // PDL_M(-500ps) + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x80); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x20); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x01); + + // Latch Command + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + } + + break; + + case JEDEC_MANUF_ID_HYNIX: + break; + + default: + break; + } + + return; +} + +// Shift dq offset as needed. +// In the future, it's possible the shift value changes based on SOC or DRAM vendor. +// Thus, we need to have this function per SOC. +void amc_dram_shift_dq_offset (int8_t *dq_offset, uint8_t num_bytes) { + int8_t shift_val; + uint8_t i; + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + case JEDEC_MANUF_ID_SAMSUNG: + case JEDEC_MANUF_ID_ELPIDA: + + // shift 2 steps + shift_val = -2; + break; + + default: + shift_val = 0; + break; + } + + for (i = 0; i < num_bytes; i++) + dq_offset[i] += shift_val; +} diff --git a/platform/s5l8955x/amc/rules.mk b/platform/s5l8955x/amc/rules.mk new file mode 100644 index 0000000..36a6843 --- /dev/null +++ b/platform/s5l8955x/amc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AMC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/amc.o diff --git a/platform/s5l8955x/asm.S b/platform/s5l8955x/asm.S new file mode 100644 index 0000000..2b5991c --- /dev/null +++ b/platform/s5l8955x/asm.S @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + + .text + +ARM_FUNCTION _platform_start + + // Configure the first half of the cache as RAM + mov r2, #0xFF000000 // L2CCONFIG0.AcpMask[7:0] = 0xFF + orr r2, r2, #0x000F0000 // L2CCONFIG0.RamWayMask[7:0] = 0x0F + orr r2, r2, #0x00000002 // L2CCONFIG0.RamEna = 1 + mcr p15, 1, r2, c15, c2, 0 // Write to L2CCONFIG0 + isb // Wait for the write to take effect + bx lr + + +ARM_FUNCTION _miu_read_l2cadrmap + + mrc p15, 1, r0, c15, c2, 4 + bx lr + + +ARM_FUNCTION _miu_write_l2cadrmap + + mcr p15, 1, r0, c15, c2, 4 + isb + bx lr diff --git a/platform/s5l8955x/chipid/chipid.c b/platform/s5l8955x/chipid/chipid.c new file mode 100644 index 0000000..23e9fb1 --- /dev/null +++ b/platform/s5l8955x/chipid/chipid.c @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if SUPPORT_FPGA +#define _rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#undef rCFG_FUSE0 +// XXX ECID (1 << 7)? +// XXX double-check memory values +#define rCFG_FUSE0 ((0 << 31) | (3 << 28) | (0xE << 24) | (2 << 22) | \ + (0 << 9) | (1 << 8) | (3 << 4) | (kPlatformSecurityDomainDarwin << 2) | (0 << 1) | (0 << 0) | \ + _rCFG_FUSE0) +#endif + +#if SUB_PLATFORM_S5L8955X +// Based on H5P/H5G tunables v0.63 and H5G Test Plan rev 1.5 +#define MINIMUM_BINNING_VERSION (2) +static u_int32_t default_soc_voltages[CHIPID_SOC_VOLTAGE_COUNT] = { 980, 1030, 1130 }; + /* 600, 1008, 1200, 1296, 1396 - - - MHz */ +static u_int32_t default_cpu_voltages[CHIPID_CPU_VOLTAGE_COUNT] = { 810, 1020, 1100, 1145, 1180, 0, 0, 0}; +static u_int32_t default_ram_voltages[CHIPID_RAM_VOLTAGE_COUNT] = { 950, 1000 }; +#endif + +static u_int32_t chipid_get_binning_revision(void); +static u_int32_t chipid_get_base_voltage(void); + +bool chipid_get_production_mode(void) +{ + return ((rCFG_FUSE0 >> 0) & 1) != 0; +} + +void chipid_clear_production_mode(void) +{ +#if SUPPORT_FPGA + _rCFG_FUSE0 &= ~1; +#else + rCFG_FUSE0 &= ~1; +#endif +} + +bool chipid_get_secure_mode(void) +{ + return ((rCFG_FUSE0 >> 1) & 1) != 0; +} + +u_int32_t chipid_get_security_domain(void) +{ + return (rCFG_FUSE0 >> 2) & 3; +} + +u_int32_t chipid_get_board_id(void) +{ + return (rCFG_FUSE0 >> 4) & 3; +} + +bool chipid_get_ecid_image_personalization_required(void) +{ + return ((rCFG_FUSE0 >> 7) & 1) != 0; +} + +u_int32_t chipid_get_minimum_epoch(void) +{ + return (rCFG_FUSE0 >> 9) & 0x7F; +} + +u_int32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_S5L8955X + return 0x8955; +#endif +} + +u_int32_t chipid_get_chip_revision(void) +{ + return (((rECIDHI >> 13) & 0x7) << 4) | (((rECIDHI >> 10) & 0x7) << 0); +} + +u_int32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +u_int64_t chipid_get_ecid_id(void) +{ + u_int64_t ecid = 0; + +#if SUPPORT_FPGA + ecid = 0x000012345678ABCDULL; +#else + ecid |= ((rECIDLO >> 0)) & ((1ULL << (21 - 0)) - 1); // LOT_ID + + ecid <<= (26 - 21); + ecid |= ((rECIDLO >> 21)) & ((1ULL << (26 - 21)) - 1); // WAFER_NUM + + ecid <<= (10 - 2); + ecid |= ((rECIDHI >> 2)) & ((1ULL << (10 - 2)) - 1); // Y_POS + + ecid <<= (32 - 26); + ecid |= ((rECIDLO >> 26)) & ((1ULL << (32 - 26)) - 1); // X_POS_H + + ecid <<= ( 2 - 0); + ecid |= ((rECIDHI >> 0)) & ((1ULL << ( 2 - 0)) - 1); // X_POS_L +#endif + + return ecid; +} + +u_int64_t chipid_get_die_id(void) +{ + return ((u_int64_t)rECIDHI << 32) | rECIDLO; +} + +u_int32_t chipid_get_soc_voltage(u_int32_t index) +{ + u_int32_t soc_voltage; + u_int64_t soc_bin_data; + + if (index > CHIPID_SOC_VOLTAGE_COUNT) return 0; + + if (chipid_get_binning_revision() < MINIMUM_BINNING_VERSION) { + // This part is unbinned or the binning version is not supported + // Use the default voltage + soc_voltage = default_soc_voltages[index]; + } else { + // Read the SoC bin data from the fuses + soc_bin_data = ((((u_int64_t)rCFG_FUSE1) << 32) | rCFG_FUSE0) >> 25; + + // Start with the base voltage + soc_voltage = chipid_get_base_voltage(); + + // Add in the correct bin from the "array" + soc_voltage += 5 * ((soc_bin_data >> (index * 7)) & 0x7F); + } + + return soc_voltage; +} + +u_int32_t chipid_get_cpu_voltage(u_int32_t index) +{ + u_int32_t cpu_voltage; + u_int64_t cpu_bin_data; + + if (index > CHIPID_CPU_VOLTAGE_COUNT) return 0; + + if (chipid_get_binning_revision() < MINIMUM_BINNING_VERSION) { + // This part is unbinned to the binning version is not supported + // Use the default voltage + cpu_voltage = default_cpu_voltages[index]; + } else { + // Read the CPU bin data from the fuses + cpu_bin_data = ((((u_int64_t)rDVFM_FUSE(1)) << 32) | rDVFM_FUSE(0)) >> 5; + + // Start with the base voltage + cpu_voltage = chipid_get_base_voltage(); + + // Add in the correct bin from the "array" + cpu_voltage += 5 * ((cpu_bin_data >> (index * 7)) & 0x7F); + } + + return cpu_voltage; +} + +u_int32_t chipid_get_ram_voltage(u_int32_t index) +{ + u_int32_t ram_voltage; + + if (index > CHIPID_RAM_VOLTAGE_COUNT) return 0; + + // RAM voltage is not binned, use the default voltage + ram_voltage = default_ram_voltages[index]; + + return ram_voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return (rCFG_FUSE1 & (1 << 31)) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) rCFG_FUSE1 |= 1 << 31; +} + +int32_t chipid_get_cpu_temp_offset(u_int32_t cpu_number) +{ + int32_t temp_cal; + + switch (cpu_number) { + case 0 : temp_cal = (rDVFM_FUSE(9) >> 0) & 0x7F; break; + case 1 : temp_cal = (rDVFM_FUSE(9) >> 16) & 0x7F; break; + default : return 0; + } + + return 0x3B - temp_cal; +} + +u_int32_t chipid_get_fused_thermal_sensor_70C(u_int32_t sensorID) +{ + u_int32_t temp_cal; + + switch (sensorID) { + case 0: temp_cal = (rCFG_FUSE4 >> 8) & 0x7F; break; + case 1: temp_cal = (rCFG_FUSE4 >> 24) & 0x7F; break; + default : return 0; + } + + return temp_cal; +} + +u_int32_t chipid_get_fused_thermal_sensor_25C(u_int32_t sensorID) +{ + u_int32_t temp_cal; + + switch (sensorID) { + case 0: temp_cal = (rCFG_FUSE4 >> 0) & 0x7F; break; + case 1: temp_cal = (rCFG_FUSE4 >> 16) & 0x7F; break; + default : return 0; + } + + return temp_cal; +} + +u_int32_t chipid_get_fuse_revision(void) +{ + return (rCFG_FUSE0 >> 18) & 0xf; +} + +static u_int32_t chipid_get_binning_revision(void) +{ + return (rDVFM_FUSE(1) >> (61 - 32)) & 7; +} + +static u_int32_t chipid_get_base_voltage(void) +{ + return 25 * (1 + ((rDVFM_FUSE(0) >> 0) & 0x1F)); +} + diff --git a/platform/s5l8955x/chipid/rules.mk b/platform/s5l8955x/chipid/rules.mk new file mode 100644 index 0000000..92158a2 --- /dev/null +++ b/platform/s5l8955x/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/s5l8955x/include/platform/amcconfig.h b/platform/s5l8955x/include/platform/amcconfig.h new file mode 100644 index 0000000..c6444d6 --- /dev/null +++ b/platform/s5l8955x/include/platform/amcconfig.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_RECONFIG | FLAG_AMC_PARAM_ENABLE_AIU | FLAG_AMC_PARAM_MRR_BYTE_SWIZZLE), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .tREFi_1Gb = 0x5d, + .longsrcnt_1Gb = 0x2008, + .rdlat = 8, + .wrlat = 4, + .phyrdlat = 10, + .phywrlat = 4, + .pdn = 0x33000503, + .read = 0x00000103, + .bustat = 0x00222212, + .bustat2 = 0x00222212, + .derate = 0x34b3187b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x22, // MIF: tREFBW violation due to freq change + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00000100, + .chnldec2 = 0x00155555, + .chnldec4 = 0x002aaaaa, + .bootclkdivsr = 10, + .arefparam = 0x0600a000, + .aref_freq1 = 0x00100100, + .aref_freq0 = 0x00100100, + .srextrarefcnt = 0x00010000, + .readleveling = 0x01000301, + + .freq = { + { // 522MHz + .cas = 0x0000040a, + .pch = 0x00040817, + .act = 0x1b060c0a, + .autoref = 0x20469000, + .selfref = 0x0004b080, + .modereg = 0x00300502, + .mifcassch = 0x001f0111, + }, + { // 400MHz + .cas = 0x00000008, + .pch = 0x00000012, + .act = 0x14050a08, + .autoref = 0x18340000, + .selfref = 0x00038000, + .modereg = 0x00240000, + .mifcassch = 0x00000010, + }, + { // 200MHz + .cas = 0x00000004, + .pch = 0x00000009, + .act = 0x0a030504, + .autoref = 0x0c1a0000, + .selfref = 0x0001c000, + .modereg = 0x00120000, + .mifcassch = 0x00000000, + }, + { // 50 & 24MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x03070000, + .selfref = 0x00007000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + // These settings are common across all H4x and H5P. Channel decode and hashing + // is done in mainline init code. Any tunables that match hardware defaults are + // omitted here. + + { &rAMC_AIUPRT_CFG, 0x00070000 }, // address error enable + { &rAMC_AIUPRT_RD_GEN, 0x00000018 }, // fence read detect on GFX + { &rAMC_AIUPRT_WR, 0x00000001 }, // out-of-order write, ignore B-bit + + { &rAMC_AIU_CHNLDEC2, 0x00155555 }, + { &rAMC_AIU_CHNLDEC4, 0x002AAAAA }, + + { &rAMC_AIU_RDBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_WRBRSTLEN, 0x01010101 }, // burst len is 64B + + { &rAMC_AIU_CPUSPCREQ, 0x00000019 }, // CPU ageout timer + { &rAMC_AIU_GFXSPCREQ, 0x00000032 }, // GFX ageout timer + { &rAMC_AIU_NRTSPCREQ, 0x00000032 }, // Hperf-NRT ageout timer + { &rAMC_AIU_RTSPCREQ, 0x00000019 }, // Hperf-RT ageout timer + { &rAMC_AIU_PUSHEN, 0x00001100 }, // only supported for Hperf-RT + + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJEN, 0x00000001 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + + { &rAMC_MIFACTSCH, 0x00000001 }, + + { &rAMC_PSQRQTIMER0, 0x00000040 }, // RTG bypass up to 64 transactions + { &rAMC_PSQRQTIMER1, 0x00000018 }, // RTY bypass up to 24 transactions + { &rAMC_PSQRQTIMER2, 0x00000020 }, // RTG bypass up to 32 transactions + { &rAMC_PSQRQBRST, 0x040c040c }, // RTR transactions don't affect read burst size + { &rAMC_PSQRQSCHCRD, 0x002028f5 }, // read credits = 2 * write credits + { &rAMC_PSQWQBRST, 0x0208040c }, // RTR reads cause reduced write burst size + { &rAMC_PSQWQSCHCRD, 0x001014f5 }, // write credits = 1/2 * read credits + { &rAMC_MCUQOS, 0x00010f04 }, // RTG=4, RTY=15, enable pick-oldest-RTY + + // Platform specific + + { &rAMC_AIU_RDMAXCRD, 0x1912047F }, // RT:NRT:CPU:GFX = 25:18:04:MAX + { &rAMC_AIU_RDREFL, 0x140f037f }, // 5/6 of AIURDMAXCRD fields + { &rAMC_AIU_WRMAXCRD, 0x1912047f }, // RT:NRT:CPU:GFX = 25:18:04:MAX + { &rAMC_AIU_WRREFL, 0x140f037f }, // 5/6 of AIUWRMAXCRD fields + + { &rAMC_AIU_ADDRBANKHASH0, 0x00006db6 }, // Enable bank hashing, bank[0] derived from bits 0,3,6,.. + { &rAMC_AIU_ADDRBANKHASH1, 0x00005b6d }, // Enable bank hashing, bank[1] derived from bits 1,4,7,.. + { &rAMC_AIU_ADDRBANKHASH2, 0x000036db }, // Enable bank hashing, bank[2] derived from bits 2,5,8,.. + { &rAMC_AIU_CHNLCRD, 0x00180018 }, + { &rAMC_AIU_LLTSCHCTL, 0x00000001 }, // Ensure LLT traffic from all ports is treated as medium priority request in the AIU arbitration + { &rAMC_MCUQOSLLT, 0x00010108 }, + + { &rAMC_AIU_CHNLTM, 0x40006101 }, + { &rAMC_AIU_WPQSCH, 0x08000800 }, // set starvation counts to 8 + { &rAMC_PSQRQCTL1, 0x0000132a }, + { &rAMC_PSQWQCTL0, 0x00010100 }, // enable write merging + { &rAMC_PSQWQCTL1, 0x00000180 }, // optimized for 4 channels + { &rAMC_PWRMNGTPARAM, 0x03001000 }, // optimized for 4 channels +}; +#endif diff --git a/platform/s5l8955x/include/platform/ampconfig.h b/platform/s5l8955x/include/platform/ampconfig.h new file mode 100644 index 0000000..309559f --- /dev/null +++ b/platform/s5l8955x/include/platform/ampconfig.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amp/amp.h, and this + * file should only by included from that amp.c. + */ + +#if WITH_TARGET_AMP_PARAMS +#include +#else +static const struct amp_params amc_phy_params = { + .flags = (FLAG_AMP_PARAM_SUPPORT_FMCLK_OFF | FLAG_AMP_PARAM_FULLDIFFMODE), + .freq = { + { + .scl = 0x08, + .rdcapcfg = 0x00010308, + }, + { + .scl = 0x0b, + .rdcapcfg = 0x00010306, + }, + { + .scl = 0x16, + .rdcapcfg = 0x00010303, + }, + { + .scl = 0x3f, + .rdcapcfg = 0x00010301, + }, + }, +}; +#endif diff --git a/platform/s5l8955x/include/platform/gpiodef.h b/platform/s5l8955x/include/platform/gpiodef.h new file mode 100644 index 0000000..b865dab --- /dev/null +++ b/platform/s5l8955x/include/platform/gpiodef.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* S5L8955X specific gpio -> pin mappings */ + +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_IIC0_SCL GPIO(15, 1) +#define GPIO_IIC0_SDA GPIO(15, 0) +#define GPIO_IIC1_SCL GPIO(15, 3) +#define GPIO_IIC1_SDA GPIO(15, 2) +#define GPIO_IIC2_SCL GPIO(28, 5) +#define GPIO_IIC2_SDA GPIO(28, 4) + +#define GPIO_BOARD_ID0 GPIO(14, 0) +#define GPIO_BOARD_ID1 GPIO(14, 1) +#define GPIO_BOARD_ID2 GPIO(14, 2) +#define GPIO_BOARD_ID3 GPIO( 4, 6) + +#define GPIO_BOOT_CONFIG0 GPIO( 5, 0) +#define GPIO_BOOT_CONFIG1 GPIO(24, 5) +#define GPIO_BOOT_CONFIG2 GPIO(25, 0) +#define GPIO_BOOT_CONFIG3 GPIO(25, 1) + +#define GPIO_REQUEST_DFU1 GPIO( 0, 1) // formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 0, 0) // formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO(24, 6) +#define GPIO_DFU_STATUS GPIO(24, 7) + +#define SPI_NOR0 (0) +#define SPI_NOR3 (3) + +#if SUPPORT_FPGA +// XXX Need to understand this and possibly correct it. +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#define GPIO_SPI3_CS GPIO(GPIO_PAD_SPI, 3) +#else +#define GPIO_SPI0_CS GPIO(14, 3) +#define GPIO_SPI3_CS GPIO(28, 3) +#endif + +#define GPIO_UART1_TXD GPIO( 5, 2) + +#define GPIO_SYSTEM_RESET GPIO(30, 0) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s5l8955x/include/platform/image_devices.h b/platform/s5l8955x/include/platform/image_devices.h new file mode 100644 index 0000000..1267a5b --- /dev/null +++ b/platform/s5l8955x/include/platform/image_devices.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_firmware", 0x00000 } +#else +#if defined(WITH_SW_H2FMI) + { "sw-h2fmi", 0x0000 } +#else + { "nor0", 0x00000 } +#endif +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s5l8955x/include/platform/memconfig.h b/platform/s5l8955x/include/platform/memconfig.h new file mode 100644 index 0000000..5ee731a --- /dev/null +++ b/platform/s5l8955x/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* S5L8955X SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/s5l8955x/include/platform/memmap.h b/platform/s5l8955x/include/platform/memmap.h new file mode 100644 index 0000000..e5a9792 --- /dev/null +++ b/platform/s5l8955x/include/platform/memmap.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* S5L8955X specific memory map */ +#define SDRAM_BASE (0x80000000ULL) +#define SDRAM_BANK_LEN (0x20000000ULL) +#define SDRAM_BANK_COUNT (2) +#define SDRAM_MAX_LEN (SDRAM_BANK_LEN * SDRAM_BANK_COUNT) +#define SDRAM_END (SDRAM_BASE + SDRAM_MAX_LEN) +#define VROM_BASE (0x3F000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00010000ULL) /* XXX Doesn't match H5P spec. Find out why before changing to match Bali spec. */ +#define SRAM_BASE (0x10000000ULL) +#define SRAM_BANK_LEN (0x00100000ULL) +#define SRAM_LEN (0x00080000ULL) + +/* Sleep token is stored at first physical page in kernel memory */ +#define SLEEP_TOKEN_BUFFER_BASE (SDRAM_BASE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00004000ULL) +#define PANIC_BASE (SDRAM_END - PANIC_SIZE) + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x00100000 - PANIC_SIZE) +#define IBOOT_BASE (PANIC_BASE - IBOOT_SIZE) +#define PROTECTED_REGION_SIZE IBOOT_SIZE + +/* reserved area for display */ +#define DISPLAY_SIZE (0x03F00000ULL) +#define DISPLAY_BASE (IBOOT_BASE - DISPLAY_SIZE) + +/* where to stick the mmu tt, default heap and insecure memory*/ +#if APPLICATION_SECUREROM +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (SRAM_BASE + SRAM_LEN - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN) + +#define STACK_SIZE (0x3000ULL) +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#ifndef __ASSEMBLY__ + +#define INSECURE_MEMORY_BASE (SRAM_BASE) +#define INSECURE_MEMORY_SIZE ((uintptr_t)__segment_start(__DATA) - INSECURE_MEMORY_BASE) + +#endif /* ! __ASSEMBLY__ */ + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT +#define MMU_TT_SIZE (0x4000ULL) +#define MMU_TT_BASE (TEXT_BASE + TEXT_FOOTPRINT - MMU_TT_SIZE) +#define MMU_NONCACHE0_SIZE (SRAM_BANK_LEN) +#define MMU_NONCACHE0_PBASE (SRAM_BASE) +#define MMU_NONCACHE0_VBASE (SRAM_BASE + SRAM_BANK_LEN * 3) +#define MMU_NONCACHE1_SIZE (0x40000000ULL) +#define MMU_NONCACHE1_PBASE (0x80000000ULL) +#define MMU_NONCACHE1_VBASE (0xC0000000ULL) + +#if WITH_DFU_MODE +#define STACK_SIZE (0x3000ULL) + +#define INSECURE_MEMORY_SIZE (0x00200000ULL) +#define INSECURE_MEMORY_BASE (SDRAM_BASE + SDRAM_BANK_LEN - INSECURE_MEMORY_SIZE) + +#define HEAP_EXT_SIZE (0x00100000ULL) +#define HEAP_EXT_BASE (INSECURE_MEMORY_BASE - HEAP_EXT_SIZE) + +#else /* !WITH_DFU_MODE */ +#define STACK_SIZE (0x1000ULL) + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_KERNEL_ADDRESS - SDRAM_BASE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +/* If only 1 bank is populated, this only clears to the alias of + * DISPLAY_BASE in the first bank. If 2 banks are populated, this + * clears all the was to DISPLAY_BASE in the second bank. */ +#define SECURE_MEMORY_SIZE (DISPLAY_BASE - SECURE_MEMORY_BASE - SDRAM_MAX_LEN + ((uint32_t)platform_get_memory_size())) + +#define HEAP_EXT_BASE (DEFAULT_FREE_ADDRESS) +#define HEAP_EXT_SIZE (DISPLAY_BASE - SDRAM_BANK_LEN - HEAP_EXT_BASE) +#endif /* !WITH_DFU_MODE */ + +#define STACK_BASE (MMU_TT_BASE - STACK_SIZE) + +#define HEAP_END (STACK_BASE) + +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_EMBEDDEDIOP +# if ARCH_ARMv7 +# define MMU_TT_SIZE (0x4000ULL) +# endif +#endif /* !APPLICATION_EMBEDDEDIOP */ + +#define SCRATCH_BASE (0x33600000ULL) +#define SCRATCH_LEN (2048) + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s5l8955x/include/platform/pinconfig.h b/platform/s5l8955x/include/platform/pinconfig.h new file mode 100644 index 0000000..a91b3ee --- /dev/null +++ b/platform/s5l8955x/include/platform/pinconfig.h @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default S5L8955X SoC Pin Configuration */ + +#define FMI_DRIVE_STR (DRIVE_X2 | SLOW_SLEW) + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* + * config idx pad connection + * ======== === ======== ================ + */ + +/* Port 0 */ + CFG_IN, // 0: GPIO0 -> Menu Button (DFU) + CFG_IN, // 1: GPIO1 -> Hoid Button (DFU) + CFG_DISABLED, // 2: GPIO2 -> Vol+ + CFG_DISABLED, // 3: GPIO3 -> Vol- + CFG_DISABLED, // 4: GPIO4 -> Ringer + CFG_DISABLED, // 5: GPIO5 -> WLAN wake + CFG_DISABLED, // 6: GPIO6 -> WLAN reset_L + CFG_DISABLED, // 7: GPIO7 -> BT wake + +/* Port 1 */ + CFG_DISABLED, // 8: GPIO10 -> BB reset + CFG_DISABLED, // 9: GPIO11 -> BB reset detect + CFG_DISABLED, // 10: GPIO12 -> Baseband IPC SRDY + CFG_DISABLED, // 11: GPIO13 -> Codec IRQ + CFG_DISABLED, // 12: GPIO14 -> Codec reset + CFG_DISABLED, // 13: GPIO15 -> Diff mic sel_L + CFG_DISABLED, // 14: (reserved) + CFG_DISABLED, // 15: (reserved) + +/* Port 2 */ + CFG_DISABLED, // 16: (reserved) + CFG_DISABLED, // 17: (reserved) + CFG_DISABLED, // 18: (reserved) + CFG_DISABLED, // 19: (reserved) + CFG_DISABLED, // 20: (reserved) + CFG_DISABLED, // 21: (reserved) + CFG_DISABLED, // 22: (reserved) + CFG_DISABLED, // 23: (reserved) + +/* Port 3 */ + CFG_DISABLED, // 24: (reserved) + CFG_DISABLED, // 25: (reserved) + CFG_DISABLED, // 26: (reserved) + CFG_DISABLED, // 27: (reserved) + CFG_DISABLED, // 28: (reserved) + CFG_DISABLED, // 29: (reserved) + CFG_DISABLED, // 30: (reserved) + CFG_DISABLED, // 31: (reserved) + +/* Port 4 */ + CFG_DISABLED, // 32: GPIO8 -> BT reset_L + CFG_DISABLED, // 33: GPIO9 -> RADIO_ON + CFG_DISABLED, // 34: EHCI_PORT_PWR0 -> + CFG_DISABLED, // 35: EHCI_PORT_PWR1 -> + CFG_DISABLED, // 36: EHCI_PORT_PWR2 -> + CFG_DISABLED, // 37: EHCI_PORT_PWR3 -> + CFG_DISABLED, // 38: GPIO16 -> Board ID 3 + CFG_DISABLED, // 39: GPIO17 -> MICEY_PRESENT + +/* Port 5 */ + CFG_DISABLED, // 40: GPIO18 -> PMU IRQ_L/Boot Config Bit 0 + CFG_DISABLED, // 41: GPIO19 -> PMU Keepact + CFG_DISABLED, // 42: UART1_TXD -> BB_USART0 TXD + CFG_DISABLED, // 43: UART1_RXD -> BB_USART0 RXD + CFG_DISABLED, // 44: UART1_RTSN -> BB_USART0 RTSN + CFG_DISABLED, // 45: UART1_CTSN -> BB_USART0 CTSN + CFG_DISABLED | FMI_DRIVE_STR, // 46: FMI0_CEN3 -> NAND Ch. 0 + CFG_DISABLED | FMI_DRIVE_STR, // 47: FMI0_CEN2 -> " + +/* Port 6 */ + CFG_DISABLED | FMI_DRIVE_STR, // 48: FMI0_CEN1 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 49: FMI0_CEN0 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 50: FMI0_CLE -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 51: FMI0_ALE -> " + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // 52: FMI0_REN -> " + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // 53: FMI0_WEN -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 54: FMI0_WENN -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 55: FMI0_IO7 -> " + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 56: FMI0_IO6 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 57: FMI0_IO5 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 58: FMI0_IO4 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 59: FMI0_DQS -> " + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // 60: FMI0_DQSN -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 61: FMI0_IO3 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 62: FMI0_IO2 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 63: FMI0_IO1 -> " + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 64: FMI0_IO0 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 65: FMI0_CEN7 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 66: FMI0_CEN6 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 67: FMI0_CEN5 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 68: FMI0_CEN4 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 69: FMI1_CEN3 -> NAND Ch. 1 + CFG_DISABLED | FMI_DRIVE_STR, // 70: FMI1_CEN2 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 71: FMI1_CEN1 -> " + +/* Port 9 */ + CFG_DISABLED | FMI_DRIVE_STR, // 72: FMI1_CEN0 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 73: FMI1_CLE -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 74: FMI1_ALE -> " + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // 75: FMI1_REN -> " + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // 76: FMI1_WEN -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 77: FMI1_WENN -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 78: FMI1_IO7 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 79: FMI1_IO6 -> " + +/* Port 10 */ + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 80: FMI1_IO5 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 81: FMI1_IO4 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 82: FMI1_DQS -> " + CFG_DISABLED | PULL_UP | FMI_DRIVE_STR, // 83: FMI1_DQSN -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 84: FMI1_IO3 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 85: FMI1_IO2 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 86: FMI1_IO1 -> " + CFG_DISABLED | PULL_DOWN | FMI_DRIVE_STR, // 87: FMI1_IO0 -> " + +/* Port 11 */ + CFG_DISABLED | FMI_DRIVE_STR, // 88: FMI1_CEN7 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 89: FMI1_CEN6 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 90: FMI1_CEN5 -> " + CFG_DISABLED | FMI_DRIVE_STR, // 91: FMI1_CEN4 -> " + CFG_DISABLED, // 92: UART2_TXD -> UMTS debug TXD + CFG_DISABLED, // 93: UART2_RXD -> UMTS debug RXD + CFG_DISABLED, // 94: UART2_RTSN -> UMTS debug RTSN + CFG_DISABLED, // 95: UART2_CTSN -> UMTS debug CTSN + +/* Port 12 */ + CFG_DISABLED, // 96: UART3_TXD -> Bluetooth TXD + CFG_DISABLED, // 97: UART3_RXD -> Bluetooth RXD + CFG_DISABLED, // 98: UART3_RTSN -> Bluetooth RTSN + CFG_DISABLED, // 99: UART3_CTSN -> Bluetooth CTSN + CFG_DISABLED, // 100: UART4_TXD -> GPS? TXD + CFG_DISABLED, // 101: UART4_RXD -> GPS? RXD + CFG_DISABLED, // 102: UART4_RTSN -> GPS? RTSN + CFG_DISABLED, // 103: UART4_CTSN -> GPS? CTSN + +/* Port 13 */ + CFG_DISABLED, // 104: UART6_TXD -> Spare + CFG_DISABLED, // 105: UART6_RXD -> Spare + CFG_DISABLED, // 106: UART6_RTSN -> Spare + CFG_DISABLED, // 107: UART6_CTSN -> Spare + CFG_DISABLED, // 108: SPI1_SCLK -> Touch Panel (Grape) CLK + CFG_DISABLED, // 109: SPI1_MOSI -> Touch Panel (Grape) MOSI + CFG_DISABLED, // 110: SPI1_MISO -> Touch Panel (Grape) MISO + CFG_DISABLED, // 111: SPI1_SSIN -> Touch Panel (Grape) SSIN + +/* Port 14 */ + CFG_DISABLED, // 112: SPI0_SCLK -> Serial ROM CLK/Board ID Bit 0 + CFG_DISABLED, // 113: SPI0_MOSI -> Serial ROM MOSI/Board ID Bit 1 + CFG_DISABLED, // 114: SPI0_MISO -> Serial ROM MISO/Board ID Bit 2 + CFG_DISABLED | PULL_UP, // 115: SPI0_SSIN -> Serial ROM SSIN + CFG_DISABLED, // 116: SPI2_SCLK -> Baseband IPC CLK + CFG_DISABLED, // 117: SPI2_MOSI -> Baseband IPC MOSI + CFG_DISABLED, // 118: SPI2_MISO -> Baseband IPC MISO + CFG_DISABLED, // 119: SPI2_SSIN -> Baseband IPC SSIN + +/* Port 15 */ + CFG_DISABLED, // 120: I2C0_SDA -> PMU, Codec, etc SDA + CFG_DISABLED, // 121: I2C0_SCL -> PMU, Codec, etc SCL + CFG_DISABLED, // 122: I2C1_SDA -> ALS, etc SDA + CFG_DISABLED, // 123: I2C1_SCL -> ALS, etc SCL + CFG_DISABLED, // 124: ISP0_SDA -> + CFG_DISABLED, // 125: ISP0_SCL -> + CFG_DISABLED, // 126: ISP1_SDA -> + CFG_DISABLED, // 127: ISP1_SCL -> + +/* Port 16 */ + CFG_DISABLED, // 128: MIPI_VSYNC -> + CFG_DISABLED, // 129: TMR32_PWM0 -> Highland park 6MHz clock + CFG_DISABLED, // 130: TMR32_PWM1 -> Vibrator + CFG_DISABLED, // 131: TMR32_PWM2 -> + CFG_DISABLED, // 132: SWI_DATA -> Backlight control + CFG_DISABLED, // 133: DWI_DI -> Backlight control + CFG_DISABLED, // 134: DWI_DO -> Backlight control + CFG_DISABLED, // 135: DWI_CLK -> Backlight control + +/* Port 17 */ + CFG_DISABLED, // 136: SENSOR0_RST -> Sensor reset + CFG_DISABLED, // 137: SENSOR0_CLK -> Sensor clk + CFG_DISABLED, // 138: SENSOR1_RST -> Sensor reset + CFG_DISABLED, // 139: SENSOR1_CLK -> Sensor clk + CFG_DISABLED, // 140: (reserved) + CFG_DISABLED, // 141: (reserved) + CFG_DISABLED, // 142: (reserved) + CFG_DISABLED, // 143: (reserved) + +/* Port 18 */ + CFG_DISABLED, // 144: (reserved) + CFG_DISABLED, // 145: (reserved) + CFG_DISABLED, // 146: (reserved) + CFG_DISABLED, // 147: (reserved) + CFG_DISABLED, // 148: (reserved) + CFG_DISABLED, // 149: (reserved) + CFG_DISABLED, // 150: (reserved) + CFG_DISABLED, // 151: (reserved) + +/* Port 19 */ + CFG_DISABLED, // 152: (reserved) + CFG_DISABLED, // 153: (reserved) + CFG_DISABLED, // 154: (reserved) + CFG_DISABLED, // 155: (reserved) + CFG_DISABLED, // 156: (reserved) + CFG_DISABLED, // 157: (reserved) + CFG_DISABLED, // 158: (reserved) + CFG_DISABLED, // 159: (reserved) + +/* Port 20 */ + CFG_DISABLED, // 160: CPU0_SWITCH -> Sensor clk (XXX Suspected to be incorrect. Follow up.) + CFG_DISABLED, // 161: CPU1_SWITCH -> Sensor clk + CFG_DISABLED, // 162: ISP0_PRE_FLASH -> " + CFG_DISABLED, // 163: ISP0_FLASH -> " + CFG_DISABLED, // 164: ISP1_PRE_FLASH -> " + CFG_DISABLED, // 165: ISP1_FLASH -> " + CFG_DISABLED, // 166: I2S0_MCK -> Audio Codec + CFG_DISABLED, // 167: I2S0_LRCK -> " + +/* Port 21 */ + CFG_DISABLED, // 168: I2S0_BCLK -> " + CFG_DISABLED, // 169: I2S0_DOUT -> " + CFG_DISABLED, // 170: I2S0_DIN -> " + CFG_DISABLED, // 171: I2S1_MCK -> Bluetooth + CFG_DISABLED, // 172: I2S1_LRCK -> " + CFG_DISABLED, // 173: I2S1_BCLK -> " + CFG_DISABLED, // 174: I2S1_DOUT -> " + CFG_DISABLED, // 175: I2S1_DIN -> " + +/* Port 22 */ + CFG_DISABLED, // 176: I2S2_MCK -> BB audio + CFG_DISABLED, // 177: I2S2_LRCK -> " + CFG_DISABLED, // 178: I2S2_BCLK -> " + CFG_DISABLED, // 179: I2S2_DOUT -> " + CFG_DISABLED, // 180: I2S2_DIN -> " + CFG_DISABLED, // 181: I2S3_MCK -> + CFG_DISABLED, // 182: I2S3_LRCK -> + CFG_DISABLED, // 183: I2S3_BCLK -> + +/* Port 23 */ + CFG_DISABLED, // 184: I2S3_DOUT -> + CFG_DISABLED, // 185: I2S3_DIN -> + CFG_DISABLED, // 186: I2S4_MCK -> BB audio + CFG_DISABLED, // 187: I2S4_LRCK -> " + CFG_DISABLED, // 188: I2S4_BCLK -> " + CFG_DISABLED, // 189: I2S4_DOUT -> " + CFG_DISABLED, // 190: I2S4_DIN -> " + CFG_DISABLED, // 191: SPDIF -> HDMI Transmitter + +/* Port 24 */ + CFG_DISABLED, // 192: GPIO20 -> Grape reset_L + CFG_DISABLED, // 193: GPIO21 -> Grape IRQ_L + CFG_DISABLED, // 194: GPIO22 -> LCD reset_L + CFG_DISABLED, // 195: GPIO23 -> LCD checksum + CFG_DISABLED, // 196: GPIO24 -> Compass reset_L + CFG_DISABLED, // 197: GPIO25 -> Compass IRQ_L/Boot Config Bit 1 + CFG_IN | PULL_DOWN, // 198: GPIO26 -> DFU force + CFG_DISABLED | PULL_DOWN, // 199: GPIO27 -> DFU status + +/* Port 25 */ + CFG_DISABLED, // 200: GPIO28 -> Accelerometer IRQ_L/Boot Config Bit 2 + CFG_DISABLED, // 201: GPIO29 -> ALS IRQ_L/Boot Config Bit 3 + CFG_DISABLED, // 202: GPIO30 -> GPS reset_ap_L + CFG_DISABLED, // 203: GPIO31 -> GPS standby_ap_L + CFG_DISABLED, // 204: GPIO32 -> GPS_intr_L + CFG_DISABLED, // 205: GPIO33 -> GSM_txburst_int + CFG_DISABLED, // 206: GPIO34 -> FM mux select + CFG_DISABLED, // 207: GPIO35 -> Board reliability test NE + +/* Port 26 */ + CFG_DISABLED, // 208: GPIO36 -> Board reliability test SE + CFG_DISABLED, // 209: GPIO37 -> Board reliability test SW + CFG_DISABLED, // 210: GPIO38 -> Board reliability test NW + CFG_DISABLED, // 211: GPIO39 -> + CFG_DISABLED, // 212: (reserved) + CFG_DISABLED, // 213: (reserved) + CFG_DISABLED, // 214: (reserved) + CFG_DISABLED, // 215: (reserved) + +/* Port 27 */ + CFG_DISABLED, // 216: (reserved) + CFG_DISABLED, // 217: (reserved) + CFG_DISABLED, // 218: (reserved) + CFG_DISABLED, // 219: (reserved) + CFG_DISABLED, // 220: (reserved) + CFG_DISABLED, // 221: (reserved) + CFG_DISABLED, // 222: (reserved) + CFG_DISABLED, // 223: (reserved) + +/* Port 28 */ + CFG_DISABLED, // 224: SPI3_MOSI -> MOSI + CFG_DISABLED, // 225: SPI3_MISO -> MISO + CFG_DISABLED, // 226: SPI3_SCLK -> CLK + CFG_DISABLED, // 227: SPI3_SSIN -> SSIN + CFG_DISABLED, // 228: I2C2_SDA -> ALS/prox + CFG_DISABLED, // 229: I2C2_SCL -> " + CFG_DISABLED, // 230: GPIO_3V0 -> Video amp enable + CFG_DISABLED, // 231: GPIO_3V1 -> SEL_SECURE_BOOT + +/* Port 29 */ + CFG_DISABLED, // 232: DP_HPD -> Hot Plug Detect + CFG_DISABLED, // 233: EDP_HPD -> Hot Plug Detect + CFG_DISABLED, // 234: UART0_TXD -> Dock, UART TXD + CFG_DISABLED, // 235: UART0_RXD -> Dock, UART RXD + CFG_DISABLED, // 236: UART5_RXD -> Battery gas gauge RXD + CFG_DISABLED, // 237: UART5_TXD -> Battery gas gauge TXD + CFG_DISABLED, // 238: TST_CLKOUT -> + CFG_DISABLED, // 239: TST_STPCLK -> + +/* Port 30 */ + CFG_DISABLED, // 240: WDOG -> + CFG_DISABLED, // 241: (reserved) + CFG_DISABLED, // 242: (reserved) + CFG_DISABLED, // 243: (reserved) + CFG_DISABLED, // 244: (reserved) + CFG_DISABLED, // 245: (reserved) + CFG_DISABLED, // 246: (reserved) + CFG_DISABLED, // 247: (reserved) +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s5l8955x/include/platform/soc/chipid.h b/platform/s5l8955x/include/platform/soc/chipid.h new file mode 100644 index 0000000..aa95dfd --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/chipid.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include + +#define rCFG_FUSE0 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCFG_FUSE1 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCFG_FUSE2 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rCFG_FUSE3 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x0C)) +#define rCFG_FUSE4 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x10)) +#define rCFG_FUSE5 (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x14)) + +#define rECIDLO (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x20)) +#define rECIDHI (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x24)) + +#define rDVFM_FUSE(n) (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x40 + (n) * 4)) + +#define rSCC_FUSE(n) (*(volatile u_int32_t *)(CHIPID_BASE_ADDR + 0x80 + (n) * 4)) + +extern bool chipid_get_ecid_image_personalization_required(void); + +#define CHIPID_SOC_VOLTAGE_COUNT (3) +#define CHIPID_SOC_VOLTAGE_LOW (0) +#define CHIPID_SOC_VOLTAGE_MED (1) +#define CHIPID_SOC_VOLTAGE_HIGH (2) +extern u_int32_t chipid_get_soc_voltage(u_int32_t index); + +#define CHIPID_CPU_VOLTAGE_COUNT (8) +extern u_int32_t chipid_get_cpu_voltage(u_int32_t index); + +#define CHIPID_RAM_VOLTAGE_COUNT (2) +#define CHIPID_RAM_VOLTAGE_LOW (0) +#define CHIPID_RAM_VOLTAGE_HIGH (1) +extern u_int32_t chipid_get_ram_voltage(u_int32_t index); + +extern int32_t chipid_get_cpu_temp_offset(u_int32_t cpu_number); + +extern u_int32_t chipid_get_fused_thermal_sensor_70C(u_int32_t sensorID); +extern u_int32_t chipid_get_fused_thermal_sensor_25C(u_int32_t sensorID); +extern u_int32_t chipid_get_fuse_revision(void); +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s5l8955x/include/platform/soc/display.h b/platform/s5l8955x/include/platform/soc/display.h new file mode 100644 index 0000000..d7a9045 --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/display.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables +static struct adfe_v1_tuneable adfe_tuneables[] = +{ + { + .name = "default", + .disp_dpcclkcntl[0] = 0, + .disp_dpbclklvl_clock_off_level[0] = DPBCLKLVL_OFFLVL(0x09F0), + .disp_dpbclklvl_clock_on_level[0] = DPBCLKLVL_ONLVL(0x0780), + .disp_dpusrcstrd[0] = DPUSRCSTRD_SRCBURST_8BLOCKS, + .disp_dpcqoscnfg[0] = (DPCQOSCNFG_QOS_TIMER(0x0040) | \ + DPCQOSCNFG_UIFIFO_ENABLE | \ + DPCQOSCNFG_VIDFIFO_ENABLE | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[0] = DPBQOSLVL_MED_WATERMARK(0x0500), + .disp_dpbqoslvl_high_watermark[0] = DPBQOSLVL_HIGH_WATERMARK(0x0280), + .disp_dpureqcfg[0] = 0, + + .disp_dpcclkcntl[1] = 0, + .disp_dpbclklvl_clock_off_level[1] = DPBCLKLVL_OFFLVL(0x09F0), + .disp_dpbclklvl_clock_on_level[1] = DPBCLKLVL_ONLVL(0x0780), + .disp_dpusrcstrd[1] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpcqoscnfg[1] = (DPCQOSCNFG_QOS_TIMER(0x2000) | \ + DPCQOSCNFG_UIFIFO_ENABLE | \ + DPCQOSCNFG_VIDFIFO_ENABLE | \ + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[1] = DPBQOSLVL_MED_WATERMARK(0x0500), + .disp_dpbqoslvl_high_watermark[1] = DPBQOSLVL_HIGH_WATERMARK(0x0280), + .disp_dpureqcfg[1] = 0, + }, +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/s5l8955x/include/platform/soc/display_timings.h b/platform/s5l8955x/include/platform/soc/display_timings.h new file mode 100644 index 0000000..a54f501 --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/display_timings.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_P101 || SUB_TARGET_P102 || SUB_TARGET_P103 + { + .display_name = "ipad3", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 205200000, + .dot_pitch = 264, + .h_active = 2048, + .h_pulse_width = 32, + .h_back_porch = 80, + .h_front_porch = 48, + .v_active = 1536, + .v_pulse_width = 4, + .v_back_porch = 6, + .v_front_porch = 3, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/s5l8955x/include/platform/soc/hwclocks.h b/platform/s5l8955x/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..5b1e92b --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/hwclocks.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +// XXX Will almost certainly need changes from H5P to Bali. + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ ( 7000000UL) +#else +#define OSC_FREQ (24000000UL) +#endif + +#define CLK_FCLK (HWCLOCK_BASE+0) +#define CLK_ACLK (HWCLOCK_BASE+1) +#define CLK_HCLK (HWCLOCK_BASE+2) +#define CLK_PCLK (HWCLOCK_BASE+3) +#define CLK_VCLK0 (HWCLOCK_BASE+4) +#define CLK_VCLK1 (HWCLOCK_BASE+5) +#define CLK_MCLK (HWCLOCK_BASE+6) +#define CLK_NCLK (HWCLOCK_BASE+7) +#define CLK_USBPHYCLK (HWCLOCK_BASE+8) +#define CLK_NCOREF (HWCLOCK_BASE+9) +#define CLK_FMI (HWCLOCK_BASE+10) + +/* S5L8955X clock gate devices */ +enum { + CLK_rsvd0 = 0, + CLK_SCC, + CLK_CPU0, + CLK_CPU1, + CLK_L2_BIU, + CLK_L2, + CLK_rsvd1, + CLK_rsvd2, + CLK_MCU, + CLK_GFX_SYS, + CLK_GFX_CORES, + CLK_HPERFNRT, + CLK_VDEC, + CLK_SCALER0, + CLK_SCALER1, + CLK_JPG0, + CLK_JPG1, + CLK_rsvd3, + CLK_VENC, + CLK_HPERFRT, + CLK_ISP, + CLK_EDPLINK, + CLK_DISP0, + CLK_DISP1, + CLK_DISPOUT, + CLK_rsvd4, + CLK_CLCD, + CLK_TVDAC, + CLK_RGBOUT, + CLK_DPLINK, + CLK_CDIO, + CLK_CDMA, + CLK_IOP, + CLK_UPERF, + CLK_USBOTG0, + CLK_USB2HOST0, + CLK_USB11HOST, + CLK_USB2HOST0_OHCI, + CLK_USB11HOST_OHCI, + CLK_USBPHY, + CLK_AUDIO, + CLK_I2S0, + CLK_I2S1, + CLK_I2S2, + CLK_I2S3, + CLK_SPDIF, + CLK_rsvd5, + CLK_SDIO, + CLK_SHA1, + CLK_SHA2, + CLK_FMI0, + CLK_FMI0BCH, + CLK_FMI1, + CLK_FMI1BCH, + CLK_FMI_DLL, + CLK_rsvd6, + CLK_MCA, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_SPI4, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_PKE, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_PWM, + CLK_SCRT, + CLK_GPIO, + CLK_SWI, + CLK_DWI, + CLK_DEBUG, + CLK_AIC, + CLK_USB2HOST1, + CLK_USB2HOST1_OHCI, +}; + +// XXX hack for driver expecting prior names until we decide appropriate way to address the renaming +#define CLK_USBOTG CLK_USBOTG0 +#define CLK_USB20 CLK_USB2HOST0 +#define CLK_USB11 CLK_USB11HOST +#define CLK_USBOHCI0 CLK_USB2HOST0_OHCI +#define CLK_USBOHCI1 CLK_USB11HOST_OHCI + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s5l8955x/include/platform/soc/hwdmachannels.h b/platform/s5l8955x/include/platform/soc/hwdmachannels.h new file mode 100644 index 0000000..5f28d38 --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/hwdmachannels.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_H +#define __PLATFORM_SOC_HWDMACHANNELS_H + +#define DMA_MEMORY_TX (1) +#define DMA_MEMORY_RX (2) +#define DMA_SDIO (3) +#define DMA_FMI0DATA (5) +#define DMA_FMI0CHECK (6) +#define DMA_FMI1DATA (7) +#define DMA_FMI1CHECK (8) + +#define DMA_CHANNEL_COUNT (44) + +#define DMA_CHANNEL_CONFIG \ +{ \ + /* low high AES OK reqID FIFO address */ \ + { 3, 4, false, 0x00, 0x30000020 }, \ + { 3, 4, false, 0x01, 0x301000A0 }, \ + { 3, 4, false, 0x01, 0x30200020 }, \ + { 5, 8, true, 0x00, 0x31200014 }, \ + { 5, 8, true, 0x01, 0x31200018 }, \ + { 5, 8, true, 0x02, 0x31300014 }, \ + { 5, 8, true, 0x03, 0x31300018 }, \ +} + + +#define DMA_SDIO_TIMEOUT_US (10 * 1000) + + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_H */ diff --git a/platform/s5l8955x/include/platform/soc/hwisr.h b/platform/s5l8955x/include/platform/soc/hwisr.h new file mode 100644 index 0000000..1a7bc58 --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/hwisr.h @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +// XXX Apply changes from H5P to Bali. + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_SWI 5 // SWI Interrupt +#define INT_DWI 6 // DWI Interrupt +#define INT_ISP0 7 // ISP 0 Interrupt +#define INT_ISP1 8 // ISP 1 Interrupt +#define INT_SCALER0 9 // Scaler Interrupt +#define INT_SCALER1 10 // Scaler Interrupt +#define INT_USB_DEV 11 // USB OTG Interrupt +#define INT_USB2HOST0_EHCI 12 // USB2HOST0 EHCI Interrupt +#define INT_USB2HOST0_OHCI0 13 // USB2HOST0 OHCI 0 Interrupt +#define INT_USB2HOST0_OHCI1 14 // USB2HOST0 OHCI 1 Interrupt +#define INT_USB_RES 15 // USB PHY Interrupt +#define INT_PWM 16 // PWM Interrupt +#define INT_PKE 17 // PKE Interrupt +#define INT_IIC0 18 // I2C 0 Interrupt +#define INT_IIC1 19 // I2C 1 Interrupt +#define INT_IIC2 20 // I2C 2 Interrupt +#define INT_UART0 21 // UART 0 Interrupt +#define INT_UART1 22 // UART 1 Interrupt +#define INT_UART2 23 // UART 2 Interrupt +#define INT_UART3 24 // UART 3 Interrupt +#define INT_UART4 25 // UART 4 Interrupt +#define INT_UART5 26 // UART 5 Interrupt +#define INT_UART6 27 // UART 6 Interrupt +#define INT_SPI0 28 // SPI 0 Interrupt +#define INT_SPI1 29 // SPI 1 Interrupt +#define INT_SPI2 30 // SPI 2 Interrupt +#define INT_SPI3 31 // SPI 3 Interrupt +#define INT_SPI4 32 // SPI 4 Interrupt +#define INT_FMI0 33 // FMI 0 Interrupt +#define INT_FMI1 34 // FMI 1 Interrupt +#define INT_USB2HOST1_EHCI 35 // USB2HOST1 EHCI Interrupt +#define INT_DPB 36 // DPB Interrupt +#define INT_SHA1 37 // SHA-1 Interrupt +#define INT_SHA2 38 // SHA-1 Interrupt +#define INT_WIFI 39 // WiFi Interrupt +#define INT_TVOUT 40 // TV Out Interrupt + +// Reserved 41 + +#define INT_CLCD 42 // CLCD Interrupt +#define INT_DISP0 43 // Display Pipe 0 Interrupt +#define INT_DISP1 44 // Display Pipe 1 Interrupt +#define INT_RGBOUT 45 // RGB Out Interrupt +#define INT_DPORT0 46 // DisplayPort 0 Interrupt +#define INT_DPORT1 47 // DisplayPort 1 Interrupt +#define INT_VENC 48 // Video Encoder Interrupt +#define INT_SGX 49 // SGX Interrupt +#define INT_VDEC 50 // Video Decoder Interrupt +#define INT_CDMA_DMAC1 51 // CDMA DMA Channel 1 Interrupt +#define INT_CDMA_DMAC2 52 // CDMA DMA Channel 2 Interrupt +#define INT_CDMA_DMAC3 53 // CDMA DMA Channel 3 Interrupt +#define INT_CDMA_DMAC4 54 // CDMA DMA Channel 4 Interrupt +#define INT_CDMA_DMAC5 55 // CDMA DMA Channel 5 Interrupt +#define INT_CDMA_DMAC6 56 // CDMA DMA Channel 6 Interrupt +#define INT_CDMA_DMAC7 57 // CDMA DMA Channel 7 Interrupt +#define INT_CDMA_DMAC8 58 // CDMA DMA Channel 8 Interrupt +#define INT_CDMA_DMAC9 59 // CDMA DMA Channel 9 Interrupt +#define INT_CDMA_DMAC10 60 // CDMA DMA Channel 10 Interrupt +#define INT_CDMA_DMAC11 61 // CDMA DMA Channel 11 Interrupt +#define INT_CDMA_DMAC12 62 // CDMA DMA Channel 12 Interrupt +#define INT_CDMA_DMAC13 63 // CDMA DMA Channel 13 Interrupt +#define INT_CDMA_DMAC14 64 // CDMA DMA Channel 14 Interrupt +#define INT_CDMA_DMAC15 65 // CDMA DMA Channel 15 Interrupt +#define INT_CDMA_DMAC16 66 // CDMA DMA Channel 16 Interrupt +#define INT_CDMA_DMAC17 67 // CDMA DMA Channel 17 Interrupt +#define INT_CDMA_DMAC18 68 // CDMA DMA Channel 18 Interrupt +#define INT_CDMA_DMAC19 69 // CDMA DMA Channel 19 Interrupt +#define INT_CDMA_DMAC20 70 // CDMA DMA Channel 20 Interrupt +#define INT_CDMA_DMAC21 71 // CDMA DMA Channel 21 Interrupt +#define INT_CDMA_DMAC22 72 // CDMA DMA Channel 22 Interrupt +#define INT_CDMA_DMAC23 73 // CDMA DMA Channel 23 Interrupt +#define INT_CDMA_DMAC24 74 // CDMA DMA Channel 24 Interrupt +#define INT_CDMA_DMAC25 75 // CDMA DMA Channel 25 Interrupt +#define INT_CDMA_DMAC26 76 // CDMA DMA Channel 26 Interrupt +#define INT_CDMA_DMAC27 77 // CDMA DMA Channel 27 Interrupt +#define INT_CDMA_DMAC28 78 // CDMA DMA Channel 28 Interrupt +#define INT_CDMA_DMAC29 79 // CDMA DMA Channel 29 Interrupt +#define INT_CDMA_DMAC30 80 // CDMA DMA Channel 30 Interrupt +#define INT_CDMA_DMAC31 81 // CDMA DMA Channel 31 Interrupt +#define INT_CDMA_DMAC32 82 // CDMA DMA Channel 32 Interrupt +#define INT_CDMA_DMAC33 83 // CDMA DMA Channel 33 Interrupt +#define INT_CDMA_DMAC34 84 // CDMA DMA Channel 34 Interrupt +#define INT_CDMA_DMAC35 85 // CDMA DMA Channel 35 Interrupt +#define INT_CDMA_DMAC36 86 // CDMA DMA Channel 36 Interrupt +#define INT_CDMA_DMAC37 87 // CDMA DMA Channel 37 Interrupt +#define INT_CDMA_DMAC38 88 // CDMA DMA Channel 38 Interrupt +#define INT_CDMA_DMAC39 89 // CDMA DMA Channel 39 Interrupt +#define INT_CDMA_DMAC40 90 // CDMA DMA Channel 40 Interrupt +#define INT_CDMA_DMAC41 91 // CDMA DMA Channel 41 Interrupt +#define INT_CDMA_DMAC42 92 // CDMA DMA Channel 42 Interrupt +#define INT_CDMA_DMAC43 93 // CDMA DMA Channel 43 Interrupt + +// Reserved 94 + +#define INT_FAILSAFE_EXIT_0 95 // THERMAL FAILSAFE EXIT 0 Interrupt +#define INT_FAILSAFE_EXIT_1 96 // THERMAL FAILSAFE EXIT 1 Interrupt + +// Audio Interrupts 97 - 111 + +#define INT_AUDIO_CPU_IRQ0 97 // AUDIO CPU 0 Interrupt +#define INT_AUDIO_CPU_IRQ1 98 // AUDIO CPU 1 Interrupt +#define INT_AUDIO_I2S0 99 // AUDIO I2S0 Interrupt +#define INT_AUDIO_I2S1 100 // AUDIO I2S1 Interrupt +#define INT_AUDIO_I2S2 101 // AUDIO I2S2 Interrupt +#define INT_AUDIO_I2S3 102 // AUDIO I2S3 Interrupt +#define INT_AUDIO_SPDIF 103 // AUDIO SPDIF Interrupt +#define INT_AUDIO_DP0 104 // AUDIO DisplayPort 0 Interrupt +#define INT_AUDIO_DP1 105 // AUDIO DisplayPort 1 Interrupt +#define INT_AUDIO_DMAC_ERR 106 // AUDIO DMAC ERR Interrupt +#define INT_AUDIO_DMA_TC 107 // AUDIO DMA TC Interrupt +#define INT_AUDIO_PERFMON 108 // AUDIO PERFMON Interrupt +#define INT_AUDIO_DBGCOMMRX 109 // AUDIO DBGCOMMRX Interrupt +#define INT_AUDIO_DBGCOMMTX 110 // AUDIO DBGCOMMTX Interrupt +#define INT_AUDIO_CTI 111 // AUDIO CTI Interrupt + +#define INT_SOC_FAILSAFE_0 112 // THERMAL SOC FAILSAFE 0 Interrupt +#define INT_SOC_FAILSAFE_1 113 // THERMAL SOC FAILSAFE 1 Interrupt +#define INT_FAILSAFE_0 114 // THERMAL FAILSAFE 0 Interrupt +#define INT_FAILSAFE_1 115 // THERMAL FAILSAFE 1 Interrupt + +#define INT_HPERFNRT_DART 116 // HPerf-NRT DART Interrupt +#define INT_HPERFRT_DART 117 // HPerf-RT DART Interrupt +#define INT_JPEG0 118 // JPEG 0 Interrupt +#define INT_GPIO0 119 // GPIO 0 Interrupt +#define INT_GPIO1 120 // GPIO 1 Interrupt +#define INT_MCU 121 // MCU Interrupt +#define INT_MCU0 122 // MCU Phy 0 Interrupt +#define INT_MCU1 123 // MCU Phy 1 Interrupt +#define INT_PIO0 124 // PIO 0 Interrupt +#define INT_PIO1 125 // PIO 1 Interrupt +#define INT_JPEG1 126 // JPEG 1 Interrupt +#define INT_IOP_COMMRX 127 // IOP CommRx Interrupt +#define INT_IOP_COMMTX 128 // IOP CommTx Interrupt +#define INT_IOP_PMI 129 // IOP PerfMon Interrupt +#define INT_IOP_CTIIRQ 130 // IOP CTIIRQ Interrupt +#define INT_ISP_COMMRX 131 // IOP CommRx Interrupt +#define INT_ISP_COMMTX 132 // IOP CommTx Interrupt +#define INT_ISP_PMI 133 // IOP PerfMon Interrupt +#define INT_ISP_CTIIRQ 134 // IOP CTIIRQ Interrupt + +// Reserved 135 - 136 + +#define INT_CPU0_COMMRX 137 // IOP CommRx Interrupt +#define INT_CPU0_COMMTX 138 // IOP CommTx Interrupt + +// Reserved 139 - 140 + +#define INT_CPU1_COMMRX 141 // IOP CommRx Interrupt +#define INT_CPU1_COMMTX 142 // IOP CommTx Interrupt + +// Reserved 143 + +#define INT_EDP0 144 // Embedded Display Port 0 Interrupt +#define INT_EDP1 145 // Embedded Display Port 1 Interrupt + +// Reserved 146 - 149 + +#define INT_MCU2 150 // MCU Phy 2 Interrupt +#define INT_MCU3 151 // MCU Phy 3 Interrupt +#define INT_PMGR_PMI 152 // PMGR PerfMon Interrupt +#define INT_HPERFNTR_PMI 153 // HPerf-NRT PerfMon Interrupt +#define INT_HPERFRT_PMI 154 // HPerf-RT PerfMon Interrupt +#define INT_DPIPE0_PMI 155 // Display Pipe 0 PerfMon Interrupt +#define INT_DPIPE1_PMI 156 // Display Pipe 1 PerfMon Interrupt + +// Reserved 157 - 159 + +#define INT_ETB_FULL 160 // ETB Full Interrupt + +// Reserved 161 + +#define INT_CPU0_VTIMER 162 // CPU 0 Virtual Timer Interrupt +#define INT_CPU0_DEBUG 163 // CPU 0 Debug Interrupt + +// Reserved 164 + +#define INT_CPU1_VTIMER 165 // CPU 1 Virtual Timer Interrupt +#define INT_CPU1_DEBUG 166 // CPU 1 Debug Interrupt + +// Reserved 167 + +#define INT_MCA 168 // Multi-Channel Audio Interrupt +#define INT_KEYGEN 169 // CDMA Keygen Interrupt +#define INT_THERM_ALARM0 170 // Thermal Alarm 0 Interrupt +#define INT_THERM_ALARM1 171 // Thermal Alarm 1 Interrupt +#define INT_THERM_TEMP0 172 // Thermal Temp 0 Interrupt +#define INT_THERM_TEMP1 173 // Thermal Temp 1 Interrupt + +// Reserved 174 - 191 + +// H5P compatibility definitions related to Bali USB renaming. +#define INT_USB_OTG INT_USB_DEV +#define INT_USB_EHCI INT_USB2HOST0_EHCI +#define INT_USB_OHCI0 INT_USB2HOST0_OHCI0 +#define INT_USB_OHCI1 INT_USB2HOST0_OHCI1 + +#if PLATFORM_VARIANT_IOP + +#include + +#define INT_HOST INT_SW2 // Host processor doorbell +#define INT_IOP INT_SW3 // I/O coprocessor doorbell +#define INT_IOP_NMI kAIC_VEC_SW_TMR // I/O coprocessor NMI + +#elif PLATFORM_VARIANT_AUDIO + +#include + +#define INT_HOST AE2_INT_SW0 // Host processor doorbell +#define INT_IOP AE2_INT_SW0 // I/O coprocessor doorbell +#define INT_IOP_NMI AE2_INT_SW1 // I/O coprocessor NMI + +#endif + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s5l8955x/include/platform/soc/hwregbase.h b/platform/s5l8955x/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..c827702 --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/hwregbase.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#define AIC_VERSION 0 +#define AIC_INT_COUNT (192) +#define PMGR_WDG_VERSION 0 + +/* S5L8955X Reg Base Defs */ + +#define SDIO_BASE_ADDR (0x30000000) + +#define SHA1_BASE_ADDR (0x30100000) +#define SHA2_BASE_ADDR (0x30200000) + +#define NAND_DLL_BASE_ADDR (0x31000000) +#define FMI0_BASE_ADDR (0x31200000) +#define FMI1_BASE_ADDR (0x31300000) +#define FMI_VERSION (5) + +#define SPI0_BASE_ADDR (0x32000000) +#define SPI1_BASE_ADDR (0x32100000) +#define SPI2_BASE_ADDR (0x32200000) +#define SPI3_BASE_ADDR (0x32300000) +#define SPI4_BASE_ADDR (0x32400000) +#define SPI_VERSION (1) +#define SPIS_COUNT (5) + +#define UART0_BASE_ADDR (0x32500000) +#define UART1_BASE_ADDR (0x32600000) +#define UART2_BASE_ADDR (0x32700000) +#define UART3_BASE_ADDR (0x32800000) +#define UART4_BASE_ADDR (0x32900000) +#define UART5_BASE_ADDR (0x32A00000) +#define UART6_BASE_ADDR (0x32B00000) +#define UART_VERSION (1) +#define UARTS_COUNT (7) + +#define PKE_BASE_ADDR (0x33100000) + +#define IIC_BASE_ADDR (0x33200000) +#define IIC_SPACING (0x00100000) +#define IICS_COUNT (3) + +#define AUDIO_BASE_ADDR (0x34000000) + +#define USBPHY_BASE_ADDR (0x36000000) +#define USBPHY_VERSION (4) +#define USBOTG_BASE_ADDR (0x36100000) +#define UPERF_WIDGETS_BASE_ADDR (0x36E00000) +#define UPERF_PL301_BASE_ADDR (0x36F00000) + +#define CDMA_BASE_ADDR (0x37000000) +#define CDMA_VERSION 5 + +#define VENC_BASE_ADDR (0x38000000) + +#define VDEC_BASE_ADDR (0x38100000) + +#define JPEG0_BASE_ADDR (0x38200000) +#define JPEG1_BASE_ADDR (0x38500000) + +#define SCALER_BASE_ADDR (0x38300000) +#define SCALER_SPACING (0x00100000) + +#define NRT_DART_BASE_ADDR (0x38B00000) + +#define NRT_DART_WIDGETS_BASE_ADDR (0x38C00000) +#define NRT_DART_PL301_BASE_ADDR (0x38D00000) + +#define NRT_TOP_WIDGETS_BASE_ADDR (0x38E00000) +#define NRT_TOP_PL301_BASE_ADDR (0x38F00000) + +#define CLCD_BASE_ADDR (0x39200000) +#define CLCD_VERSION (1) + +// XXX Different in Bali. +#define DITHER0_BASE_ADDR (0x39300000) +#define DITHER_VERSION (2) +#define DITHER_BASE_ADDR DITHER0_BASE_ADDR + +#define TVOUT_BASE_ADDR (0x39400000) +#define TVOUT_DAC0_SCALE_VALUE (0x782) +#define TVOUT_DAC1_SCALE_VALUE (0x782) +#define TVOUT_DAC2_SCALE_VALUE (0x782) + +// XXX New in Bali. +#define EDP_BASE_ADDR (0x39500000) +#define DISPLAYPORT_VERSION (2) + +// XXX Removed in Bali? +#define DSIM_BASE_ADDR (0x39500000) +#define DSIM_LANE_COUNT (4) +#define DSIM_VERSION (1) + +#define RGBOUT_BASE_ADDR (0x39600000) + +#define DISPLAYPORT_BASE_ADDR (0x39700000) + +// XXX Different in Bali. +//#define DITHER1_BASE_ADDR (0x39800000) + +// XXX New in Bali. +#define ASCALER_BASE_ADDR (0x39900000) +#define DPB_BASE_ADDR (0x39A00000) +#define AAP_BASE_ADDR (0x39B00000) + +// XXX Removed in Bali. +//#define LPDP_BASE_ADDR (0x39900000) + +#define ISP_BASE_ADDR (0x3A000000) + +#define DISP0_BASE_ADDR (0x3A100000) +#define DISP1_BASE_ADDR (0x3A200000) +#define CLCD_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define RGBOUT_DISPLAYPIPE_BASE_ADDR (DISP1_BASE_ADDR) +#define DISP_VERSION (4) + +#define RT_DART_BASE_ADDR (0x3A400000) + +#define RT_TOP_WIDGETS_BASE_ADDR (0x3A500000) +#define RT_TOP_PL301_BASE_ADDR (0x3A600000) + +// XXX Removed in Bali. +//#define ADSP_BASE_ADDR (0x3B000000) + +#define AMP_BASE_ADDR (0x3D000000) +#define AMP_SPACING (0x00100000) + +#define SCC_BASE_ADDR (0x3D200000) + +#define PMGR_BASE_ADDR (0x3F100000) + +#define AIC_BASE_ADDR (0x3F200000) + +#define IOP_BASE_ADDR (0x3F300000) + +// XXX Removed in Bali. +//#define ROSC_BASE_ADDR (0x3F400000) +//#define ROSC_MASK (0x57FF) +//#define ROSC_WITH_CLOCK (0) + +#define CHIPID_BASE_ADDR (0x3F500000) + +#define SWI_BASE_ADDR (0x3F600000) +#define DWI_BASE_ADDR (0x3F700000) + +#define AMC_BASE_ADDR (0x3F800000) + +#define GPIO_BASE_ADDR (0x3FA00000) +#define GPIO_VERSION (2) +#define GPIO_GROUP_COUNT (31) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define PIO_BASE_ADDR (0x3FB00000) +#define PIO_SPACING (0x00100000) + +#define CIM_BASE_ADDR (0x3FD00000) + +#define CDIO_WIDGETS_BASE_ADDR (0x3FE00000) +#define CDIO_PL301_BASE_ADDR (0x3FF00000) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s5l8955x/include/platform/soc/miu.h b/platform/s5l8955x/include/platform/soc/miu.h new file mode 100644 index 0000000..8199abf --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/miu.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rREMAP_CTL (*(volatile u_int32_t *)(PIO_BASE_ADDR + 0x0000)) + +#define rCIM_TID_DEST_CONFIG(n) (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x000 + (n) * 4)) +#define rCIM_CONFIG_REG (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x040) +#define rCIM_STATUS_REG0 (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x044) +#define rCIM_STATUS_REG1 (*(volatile u_int32_t *)(CIM_BASE_ADDR + 0x048) + +#define CDIO_IOP_RRLIMIT (0x0000) +#define rCDIO_IOP_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RRLIMIT)) +#define CDIO_IOP_WRLIMIT (0x0004) +#define rCDIO_IOP_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WRLIMIT)) +#define CDIO_IOP_RTLIMIT (0x0008) +#define rCDIO_IOP_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RTLIMIT)) +#define CDIO_IOP_WTLIMIT (0x000C) +#define rCDIO_IOP_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WTLIMIT)) +#define CDIO_IOP_WGATHER (0x0010) +#define rCDIO_IOP_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WGATHER)) +#define CDIO_IOP_C_REMAP_EN (0x001C) +#define rCDIO_IOP_C_REMAP_EN (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_C_REMAP_EN)) +#define CDIO_IOP_RC_REMAP(n) (0x0020 + ((n) * 4)) +#define rCDIO_IOP_RC_REMAP(n) (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_RC_REMAP(n))) +#define CDIO_IOP_WC_REMAP(n) (0x0030 + ((n) * 4)) +#define rCDIO_IOP_WC_REMAP(n) (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_IOP_WC_REMAP(n))) +#define CDIO_CDMA_RRLIMIT (0x1000) +#define rCDIO_CDMA_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_RRLIMIT)) +#define CDIO_CDMA_WRLIMIT (0x1004) +#define rCDIO_CDMA_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WRLIMIT)) +#define CDIO_CDMA_RTLIMIT (0x1008) +#define rCDIO_CDMA_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_RTLIMIT)) +#define CDIO_CDMA_WTLIMIT (0x100C) +#define rCDIO_CDMA_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WTLIMIT)) +#define CDIO_CDMA_WGATHER (0x1010) +#define rCDIO_CDMA_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CDMA_WGATHER)) +#define CDIO_UPERF_RRLIMIT (0x2000) +#define rCDIO_UPERF_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_RRLIMIT)) +#define CDIO_UPERF_WRLIMIT (0x2004) +#define rCDIO_UPERF_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WRLIMIT)) +#define CDIO_UPERF_RTLIMIT (0x2008) +#define rCDIO_UPERF_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_RTLIMIT)) +#define CDIO_UPERF_WTLIMIT (0x200C) +#define rCDIO_UPERF_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WTLIMIT)) +#define CDIO_UPERF_WGATHER (0x2010) +#define rCDIO_UPERF_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_UPERF_WGATHER)) +#define CDIO_AUDIO_RRLIMIT (0x3000) +#define rCDIO_AUDIO_RRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_RRLIMIT)) +#define CDIO_AUDIO_WRLIMIT (0x3004) +#define rCDIO_AUDIO_WRLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WRLIMIT)) +#define CDIO_AUDIO_RTLIMIT (0x3008) +#define rCDIO_AUDIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_RTLIMIT)) +#define CDIO_AUDIO_WTLIMIT (0x300C) +#define rCDIO_AUDIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WTLIMIT)) +#define CDIO_AUDIO_WGATHER (0x3010) +#define rCDIO_AUDIO_WGATHER (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_AUDIO_WGATHER)) +#define CDIO_PIO_RTLIMIT (0x5008) +#define rCDIO_PIO_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_RTLIMIT)) +#define CDIO_PIO_WTLIMIT (0x500C) +#define rCDIO_PIO_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_PIO_WTLIMIT)) +#define CDIO_CIM_RTLIMIT (0x6008) +#define rCDIO_CIM_RTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CIM_RTLIMIT)) +#define CDIO_CIM_WTLIMIT (0x600C) +#define rCDIO_CIM_WTLIMIT (*(volatile u_int32_t *)(CDIO_WIDGETS_BASE_ADDR + CDIO_CIM_WTLIMIT)) + +#define CDIO_AR_CHAN_ARB_MI0 (0x0408) +#define rCDIO_AR_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI0)) +#define CDIO_AW_CHAN_ARB_MI0 (0x040C) +#define rCDIO_AW_CHAN_ARB_MI0 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI0)) +#define CDIO_AR_CHAN_ARB_MI1 (0x0428) +#define rCDIO_AR_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AR_CHAN_ARB_MI1)) +#define CDIO_AW_CHAN_ARB_MI1 (0x042C) +#define rCDIO_AW_CHAN_ARB_MI1 (*(volatile u_int32_t *)(CDIO_PL301_BASE_ADDR + CDIO_AW_CHAN_ARB_MI1)) + +#define UPERF_OTG_QOS (0x0014) +#define rUPERF_OTG_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_QOS)) +#define UPERF_OTG_CACHE (0x0018) +#define rUPERF_OTG_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OTG_CACHE)) +#define UPERF_EHCI_QOS (0x0034) +#define rUPERF_EHCI_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_QOS)) +#define UPERF_EHCI_CACHE (0x0038) +#define rUPERF_EHCI_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_EHCI_CACHE)) +#define UPERF_OHCI0_QOS (0x0054) +#define rUPERF_OHCI0_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_QOS)) +#define UPERF_OHCI0_CACHE (0x0058) +#define rUPERF_OHCI0_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI0_CACHE)) +#define UPERF_OHCI1_QOS (0x0074) +#define rUPERF_OHCI1_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_QOS)) +#define UPERF_OHCI1_CACHE (0x0078) +#define rUPERF_OHCI1_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_OHCI1_CACHE)) +#define UPERF_RTLIMIT (0x0088) +#define rUPERF_RTLIMIT (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_RTLIMIT)) +#define UPERF_WTLIMIT (0x008C) +#define rUPERF_WTLIMIT (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_WTLIMIT)) +#define UPERF_USB2HOST1EHCI_QOS (0x0094) +#define rUPERF_USB2HOST1EHCI_QOS (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_USB2HOST1EHCI_QOS)) +#define UPERF_USB2HOST1EHCI_CACHE (0x0098) +#define rUPERF_USB2HOST1EHCI_CACHE (*(volatile u_int32_t *)(UPERF_WIDGETS_BASE_ADDR + UPERF_USB2HOST1EHCI_CACHE)) + +#define UPERF_AR_CHAN_ARB_MI (0x0408) +#define rUPERF_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(UPERF_PL301_BASE_ADDR + UPERF_AR_CHAN_ARB_MI0)) +#define UPERF_AW_CHAN_ARB_MI (0x040C) +#define rUPERF_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(UPERF_PL301_BASE_ADDR + UPERF_AW_CHAN_ARB_MI0)) + +#define HPERF_NRT_DART_DART_RTLIMIT (0x0000) +#define rHPERF_NRT_DART_DART_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_RTLIMIT)) +#define HPERF_NRT_DART_DART_WTLIMIT (0x0004) +#define rHPERF_NRT_DART_DART_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_WTLIMIT)) +#define HPERF_NRT_DART_DART_WGATHER (0x0010) +#define rHPERF_NRT_DART_DART_WGATHER (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_DART_WGATHER)) +#define HPERF_NRT_DART_SCALER0_RTLIMIT (0x0108) +#define rHPERF_NRT_DART_SCALER0_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_RTLIMIT)) +#define HPERF_NRT_DART_SCALER0_WTLIMIT (0x010C) +#define rHPERF_NRT_DART_SCALER0_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER0_WTLIMIT)) +#define HPERF_NRT_DART_SCALER1_RTLIMIT (0x0208) +#define rHPERF_NRT_DART_SCALER1_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_RTLIMIT)) +#define HPERF_NRT_DART_SCALER1_WTLIMIT (0x020C) +#define rHPERF_NRT_DART_SCALER1_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_SCALER1_WTLIMIT)) +#define HPERF_NRT_DART_JPEG0_RTLIMIT (0x0308) +#define rHPERF_NRT_DART_JPEG0_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_RTLIMIT)) +#define HPERF_NRT_DART_JPEG0_WTLIMIT (0x030C) +#define rHPERF_NRT_DART_JPEG0_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_WTLIMIT)) +#define HPERF_NRT_DART_JPEG0_QOS (0x0314) +#define rHPERF_NRT_DART_JPEG0_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_QOS)) +#define HPERF_NRT_DART_JPEG1_RTLIMIT (0x0408) +#define rHPERF_NRT_DART_JPEG1_RTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_RTLIMIT)) +#define HPERF_NRT_DART_JPEG1_WTLIMIT (0x040C) +#define rHPERF_NRT_DART_JPEG1_WTLIMIT (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_WTLIMIT)) +#define HPERF_NRT_DART_JPEG1_QOS (0x0414) +#define rHPERF_NRT_DART_JPEG1_QOS (*(volatile u_int32_t *)(NRT_DART_WIDGETS_BASE_ADDR + HPERF_NRT_DART_JPEG0_QOS)) + +#define HPERF_NRT_DART_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_DART_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_DART_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_DART_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_DART_PL301_BASE_ADDR + HPERF_NRT_DART_AW_CHAN_ARB_MI0)) + +#define HPERF_NRT_TOP_TOP_RTLIMIT (0x0008) +#define rHPERF_NRT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_RTLIMIT)) +#define HPERF_NRT_TOP_TOP_WTLIMIT (0x000C) +#define rHPERF_NRT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_TOP_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_RTLIMIT (0x0108) +#define rHPERF_NRT_TOP_VENC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_RTLIMIT)) +#define HPERF_NRT_TOP_VENC_WTLIMIT (0x010C) +#define rHPERF_NRT_TOP_VENC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WTLIMIT)) +#define HPERF_NRT_TOP_VENC_WREQSP (0x0110) +#define rHPERF_NRT_TOP_VENC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VENC_WREQSP)) +#define HPERF_NRT_TOP_VDEC_RTLIMIT (0x0208) +#define rHPERF_NRT_TOP_VDEC_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_RTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WTLIMIT (0x020C) +#define rHPERF_NRT_TOP_VDEC_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WTLIMIT)) +#define HPERF_NRT_TOP_VDEC_WREQSP (0x0210) +#define rHPERF_NRT_TOP_VDEC_WREQSP (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WREQSP)) +#define HPERF_NRT_TOP_AUX_RTLIMIT (0x0308) +#define rHPERF_NRT_TOP_AUX_RTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_RTLIMIT)) +#define HPERF_NRT_TOP_AUX_WTLIMIT (0x030C) +#define rHPERF_NRT_TOP_AUX_WTLIMIT (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_VDEC_WTLIMIT)) +#define HPERF_NRT_TOP_AUX_WGATHER (0x0310) +#define rHPERF_NRT_TOP_AUX_WGATHER (*(volatile u_int32_t *)(NRT_TOP_WIDGETS_BASE_ADDR + HPERF_NRT_TOP_AUX_WGATHER)) + +#define HPERF_NRT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_NRT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_NRT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_NRT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(NRT_TOP_PL301_BASE_ADDR + HPERF_NRT_TOP_AW_CHAN_ARB_MI0)) + +#define HPERF_RT_TOP_DISP0_RTLIMIT (0x0004) +#define rHPERF_RT_TOP_DISP0_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP0_RTLIMIT)) +#define HPERF_RT_TOP_DISP1_RTLIMIT (0x000C) +#define rHPERF_RT_TOP_DISP1_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_DISP1_RTLIMIT)) +#define HPERF_RT_TOP_ISP_RTLIMIT (0x0018) +#define rHPERF_RT_TOP_ISP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_WTLIMIT)) +#define HPERF_RT_TOP_ISP_WTLIMIT (0x001C) +#define rHPERF_RT_TOP_ISP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_ISP_RTLIMIT)) +#define HPERF_RT_TOP_TOP_RTLIMIT (0x0020) +#define rHPERF_RT_TOP_TOP_RTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_WTLIMIT)) +#define HPERF_RT_TOP_TOP_WTLIMIT (0x0024) +#define rHPERF_RT_TOP_TOP_WTLIMIT (*(volatile u_int32_t *)(RT_TOP_WIDGETS_BASE_ADDR + HPERF_RT_TOP_TOP_RTLIMIT)) + +#define HPERF_RT_TOP_AR_CHAN_ARB_MI (0x0408) +#define rHPERF_RT_TOP_AR_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AR_CHAN_ARB_MI0)) +#define HPERF_RT_TOP_AW_CHAN_ARB_MI (0x040C) +#define rHPERF_RT_TOP_AW_CHAN_ARB_MI (*(volatile u_int32_t *)(RT_TOP_PL301_BASE_ADDR + HPERF_RT_TOP_AW_CHAN_ARB_MI0)) + +#define rSCC_CCXPWRCTRL (*(volatile u_int32_t *)(SCC_BASE_ADDR + 0x2603C)) + + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(int step); +extern void miu_update_device_tree(DTNode *pmgr_node); + +extern u_int32_t miu_read_l2cadrmap(void); +extern void miu_write_l2cadrmap(u_int32_t value); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s5l8955x/include/platform/soc/pmgr.h b/platform/s5l8955x/include/platform/soc/pmgr.h new file mode 100644 index 0000000..4fc58f0 --- /dev/null +++ b/platform/s5l8955x/include/platform/soc/pmgr.h @@ -0,0 +1,536 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include + +#define PMGR_PLL_COUNT (8) + +#define rPMGR_PLL_CTL0(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0000 + ((_n) * 0x18))) +#define PMGR_PLL_ENABLE (1 << 31) +#define PMGR_PLL_EXT_BYPASS (1 << 30) +#define PMGR_PLL_REAL_LOCK (1 << 29) +#define PMGR_PLL_LOAD (1 << 27) +#define PMGR_PLL_BYPASS (1 << 23) + +#define rPMGR_PLL_CTL1(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0004 + ((_n) * 0x18))) +#define PMGR_PLL_MASK (0x1FF) +#define PMGR_PLL_M_SHIFT (18) +#define PMGR_PLL_P_SHIFT (9) +#define PMGR_PLL_S_SHIFT (0) +#define PMGR_PLL_P(_p) (((_p) & PMGR_PLL_MASK) << PMGR_PLL_P_SHIFT) +#define PMGR_PLL_M(_m) (((_m) & PMGR_PLL_MASK) << PMGR_PLL_M_SHIFT) +#define PMGR_PLL_S(_s) (((_s) & PMGR_PLL_MASK) << PMGR_PLL_S_SHIFT) + +#define rPMGR_PLL_PARAM(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0008 + ((_n) * 0x18))) +#define PMGR_PARAM_LOCK_TIME_MASK (0xFFFF) +#define PMGR_PARAM_LOCK_TIME(_n) (((_n) & PMGR_PARAM_LOCK_TIME_MASK) << 0) + +#define rPMGR_PLL_FD(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x000C + ((_n) * 0x18))) + +#define rPMGR_DOUBLER_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0100)) +#define PMGR_DOUBLER_ENABLE (1 << 31) +#define PMGR_DOUBLER_EXT_BYPASS (1 << 30) + +#define rPMGR_CPU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0140)) +#define rPMGR_PLL2_GATE_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0150)) +#define rPMGR_PLL4_GATE_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0154)) +#define rPMGR_PLL5_GATE_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0158)) + +#define rPMGR_MCU_FIXED_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0164)) +#define rPMGR_MCU_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0168)) +#define rPMGR_PCLK1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x016C)) +#define rPMGR_GFX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0170)) + +#define rPMGR_PREDIV0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0190)) +#define rPMGR_PREDIV1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0194)) +#define rPMGR_PREDIV2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0198)) +#define rPMGR_PREDIV3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x019C)) +#define rPMGR_PREDIV4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01A0)) +#define rPMGR_PREDIV5_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01A4)) + +#define rPMGR_VENC_MTX_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01D0)) +#define rPMGR_VENC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01D4)) +#define rPMGR_HPERFRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01D8)) +#define rPMGR_GFX_SYS_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01DC)) +#define rPMGR_HPERFNRT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01E0)) +#define rPMGR_NRT_MEM_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01E4)) +#define rPMGR_VDEC_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01E8)) +#define rPMGR_ISP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01EC)) +#define rPMGR_IOP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01F0)) +#define rPMGR_CDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01F4)) +#define rPMGR_LPERFS_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01F8)) +#define rPMGR_PCLK0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x01FC)) +#define rPMGR_PCLK2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0200)) +#define rPMGR_PCLK3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0204)) +#define rPMGR_AES_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0208)) + +#define rPMGR_MEDIUM0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0230)) +#define rPMGR_MEDIUM1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0234)) +#define rPMGR_VID0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0238)) +#define rPMGR_VID1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x023C)) +#define rPMGR_DISPOUT_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0240)) +#define rPMGR_I2C_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0244)) +#define rPMGR_SDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0248)) + +#define rPMGR_AUDIO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0250)) + +#define rPMGR_UPERF_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0260)) +#define rPMGR_DEBUG_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0264)) + +#define rPMGR_SCC_PWR_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0268)) +#define rPMGR_SCC_DMA_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x026C)) + +#define rPMGR_SPI0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0270)) +#define rPMGR_SPI1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0274)) +#define rPMGR_SPI2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0278)) +#define rPMGR_SPI3_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x027C)) +#define rPMGR_SPI4_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0280)) +#define rPMGR_SLOW_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0284)) +#define rPMGR_SLEEP_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0288)) + +#define rPMGR_USB_PHY0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x028C)) +#define rPMGR_USBOHCI_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0290)) +#define rPMGR_USB12_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0294)) + +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0298)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x029C)) +#define rPMGR_NCO_REF2_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02A0)) +#define rPMGR_USB_PHY1_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02A4)) +#define rPMGR_USB_EHCI_FREE_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02A8)) + +#define PMGR_FIRST_CLK_CFG (&rPMGR_CPU_CLK_CFG) +#define PMGR_LAST_CLK_CFG (&rPMGR_USB_EHCI_FREE_CLK_CFG) +#define PMGR_CLK_CFG_COUNT (((((u_int32_t)(PMGR_LAST_CLK_CFG)) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) + 1) +#define PMGR_CLK_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _CLK_CFG) - ((u_int32_t)(PMGR_FIRST_CLK_CFG))) / 4) +#define PMGR_FIRST_MANAGED_CLK_NUM PMGR_CLK_NUM(VENC_MTX) + +#define PMGR_CLK_CFG_ENABLE (1 << 31) +#define PMGR_CLK_CFG_PENDING (1 << 30) +#define PMGR_CLK_CFG_AUTO_DISABLE (1 << 25) +#define PMGR_CLK_CFG_SRC(_d) (((_d) & 0x3) << 28) +#define PMGR_CLK_CFG_SRC_MASK PMGR_CLK_CFG_SRC(0x3) +#define PMGR_CLK_CFG_DIVIDER(_d) (((_d) & 0x1F) << 0) +#define PMGR_CLK_CFG_DIV_MASK PMGR_CLK_CFG_DIVIDER(0x1F) + +#define PMGR_PREDIV4_SRC__OSC PMGR_CLK_CFG_SRC(0x0) +#define PMGR_PREDIV4_SRC__PLL5 PMGR_CLK_CFG_SRC(0x1) +#define PMGR_PREDIV4_SRC__PLL6 PMGR_CLK_CFG_SRC(0x2) +#define PMGR_PREDIV4_SRC__PLL3 PMGR_CLK_CFG_SRC(0x3) + +#define rPMGR_I2S0_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02B0)) +#define rPMGR_I2S0_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02B4)) +#define rPMGR_I2S0_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02B8)) + +#define rPMGR_I2S1_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02C0)) +#define rPMGR_I2S1_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02C4)) +#define rPMGR_I2S1_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02C8)) + +#define rPMGR_I2S2_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02D0)) +#define rPMGR_I2S2_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02D4)) +#define rPMGR_I2S2_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02D8)) + +#define rPMGR_I2S3_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02E0)) +#define rPMGR_I2S3_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02E4)) +#define rPMGR_I2S3_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02E8)) + +#define rPMGR_SPDIF_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02F0)) +#define rPMGR_SPDIF_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02F4)) +#define rPMGR_SPDIF_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x02F8)) + +#define rPMGR_DP_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0300)) +#define rPMGR_DP_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0304)) +#define rPMGR_DP_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0308)) + +#define rPMGR_MCA_NCO_CLK_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0310)) +#define rPMGR_MCA_NCO_N1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0314)) +#define rPMGR_MCA_NCO_N2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0318)) + +#define rPMGR_ENABLE_CLK_GATE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0330)) + +#define kPERF_STATE_BYPASS (0) +#define kPERF_STATE_SECUREROM (1) +#define kPERF_STATE_IBOOT (2) +#define kPERF_STATE_IBOOT_CNT (5) + +#define PMGR_PERF_STATE_COUNT (16) +#define rPMGR_PERF_STATE_A(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0400 + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_B(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0404 + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_C(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0408 + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_D(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x040C + ((_s) * 0x20))) +#define rPMGR_PERF_STATE_E(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0410 + ((_s) * 0x20))) +#define PMGR_PERF_STATE_E_VOL_SHIFT (0) +#define PMGR_PERF_STATE_E_VOL_MASK (0xFF) + +#define rPMGR_PERF_STATE_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0600)) +#define PMGR_PERF_STATE_SEL_SHIFT (0) +#define PMGR_PERF_STATE_SEL_MASK (0xF) +#define PMGR_PERF_STATE_SEL(_s) (((_s) & PMGR_PERF_STATE_SEL_MASK) << PMGR_PERF_STATE_SEL_SHIFT) +#define PMGR_PERF_STATE_PENDING (0xFFFFFFF << 4) + +#define rPMGR_PERF_STATE_DELAY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0604)) +#define PMGR_PERF_STATE_DELAY_VOL_CHG_FIX_DLY_SHIFT (8) +#define PMGR_PERF_STATE_DELAY_VOL_CHG_VAR_DLY_SHIFT (0) + +#define rPMGR_MCU_CLK_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0620)) + +#define rPMGR_AUTOMATIC_CLK_GATE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x0640)) +#define PMGR_ACG_CLK_GEN__ENABLE (1 << 0) +#define PMGR_ACG_PS_ENABLE (1 << 1) +#define PMGR_ACG_NCO_CLK_GEN_ENABLE (1 << 2) + +#define rPMGR_FIRST_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1000)) +#define rPMGR_SCC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1004)) +#define rPMGR_CPU0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1008)) +#define rPMGR_CPU1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x100C)) +#define rPMGR_L2_BIU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1010)) +#define rPMGR_L2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1014)) +#define rPMGR_MCU_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1020)) +#define rPMGR_GFX_SYS_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1024)) +#define rPMGR_GFX_CORES_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1028)) +#define rPMGR_HPERFNRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x102C)) +#define rPMGR_VDEC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1030)) +#define rPMGR_SCALER0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1034)) +#define rPMGR_SCALER1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1038)) +#define rPMGR_JPG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x103C)) +#define rPMGR_JPG1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1040)) +#define rPMGR_VENCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1048)) +#define rPMGR_HPERFRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x104C)) +#define rPMGR_ISP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1050)) +#define rPMGR_EDP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1054)) +#define rPMGR_DISP0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1058)) +#define rPMGR_DISP1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x105C)) +#define rPMGR_DISPOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1060)) + +#define rPMGR_CLCD_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1068)) +#define rPMGR_TVOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x106C)) +#define rPMGR_RGBOUT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1070)) +#define rPMGR_DPLINK_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1074)) +#define rPMGR_CDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1078)) +#define rPMGR_CDMA_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x107C)) +#define rPMGR_IOP_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1080)) +#define rPMGR_UPERF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1084)) +#define rPMGR_USBOTG0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1088)) +#define rPMGR_USB2HOST0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x108C)) +#define rPMGR_USB11HOST_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1090)) +#define rPMGR_USB2HOST0_OHCI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1094)) +#define rPMGR_USB11HOST_OHCI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1098)) +#define rPMGR_USBREG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x109C)) +#define rPMGR_AUDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A0)) +#define rPMGR_I2S0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A4)) +#define rPMGR_I2S1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10A8)) +#define rPMGR_I2S2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10AC)) +#define rPMGR_I2S3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B0)) +#define rPMGR_SPDIF_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10B4)) + +#define rPMGR_SDIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10BC)) +#define rPMGR_SHA1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C0)) +#define rPMGR_SHA2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C4)) +#define rPMGR_FMI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10C8)) +#define rPMGR_FMI0BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10CC)) +#define rPMGR_FMI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D0)) +#define rPMGR_FMI1BCH_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D4)) +#define rPMGR_FMI_DLL_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10D8)) + +#define rPMGR_MCA_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E0)) +#define rPMGR_SPI0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E4)) +#define rPMGR_SPI1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10E8)) +#define rPMGR_SPI2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10EC)) +#define rPMGR_SPI3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F0)) +#define rPMGR_SPI4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F4)) +#define rPMGR_UART0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10F8)) +#define rPMGR_UART1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x10FC)) +#define rPMGR_UART2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1100)) +#define rPMGR_UART3_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1104)) +#define rPMGR_UART4_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1108)) +#define rPMGR_UART5_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x110C)) +#define rPMGR_UART6_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1110)) +#define rPMGR_PKE_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1114)) +#define rPMGR_I2C0_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1118)) +#define rPMGR_I2C1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x111C)) +#define rPMGR_I2C2_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1120)) +#define rPMGR_PWM_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1124)) +#define rPMGR_SCRT_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1128)) +#define rPMGR_GPIO_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x112C)) +#define rPMGR_SWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1130)) +#define rPMGR_DWI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1134)) +#define rPMGR_DEBUG_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1138)) +#define rPMGR_AIC_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x113C)) +#define rPMGR_USB2HOST1_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1140)) +#define rPMGR_USB2HOST1_OHCI_PS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1144)) + +#define PMGR_PS_RESET (1 << 31) + +#define PMGR_FIRST_PS (&rPMGR_FIRST_PS) +#define PMGR_LAST_PS (&rPMGR_USB2HOST1_OHCI_PS) +#define PMGR_PS_COUNT (((((u_int32_t)(PMGR_LAST_PS)) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + 1) +#define PMGR_PS_NUM(_r) (((u_int32_t)&(rPMGR_ ## _r ## _PS) - ((u_int32_t)(PMGR_FIRST_PS))) / 4) + +#define rPMGR_PWR_GATE_CTL_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1200)) +#define rPMGR_PWR_GATE_CTL_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1204)) +#define PMGR_PWR_GATE_IOP (1 << 6) + +#define rPMGR_PWR_GATE_GFX_MODE (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1208)) + +#define rPMGR_CORE_OFFLINE_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1210)) +#define rPMGR_CORE_OFFLINE_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1214)) +#define rPMGR_WAKE_CORES (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1220)) + +#define PMGR_PWR_GATE_TIME_COUNT (15) +#define rPMGR_PWR_GATE_TIME_A(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1240 + (((_n) - 1) * 8))) +#define rPMGR_PWR_GATE_TIME_B(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1244 + (((_n) - 1) * 8))) +#define rPMGR_PWR_GATE_DBG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E0)) +#define rPMGR_PWR_GATE_DBG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x12E4)) + +#define rPMGR_VOLMAN_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1380)) +#define PMGR_VOLMAN_DISABLE_VOL_CHANGE (1 << 10) +#define PMGR_VOLMAN_CPU_SW_OFF_TIME_VALUE(_x) ((_x) << 2) +#define PMGR_VOLMAN_BIT_ORDER_MSB (0 << 1) +#define PMGR_VOLMAN_BIT_ORDER_LSB (1 << 1) +#define PMGR_VOLMAN_BYTE_NO_SWAP (0 << 0) +#define PMGR_VOLMAM_BYTE_SWAP (1 << 0) + +#define kDVFM_STATE_COUNT (8) +#define kDVFM_STATE_BYPASS (0) +#define kDVFM_STATE_SECUREROM (1) +#define kDVFM_STATE_IBOOT (2) + +#define PMGR_DVFM_STATE_COUNT (8) +#define rPMGR_DVFM_CFG0(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1400 + ((_s) * 0x20))) +#define rPMGR_DVFM_CFG1(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1404 + ((_s) * 0x20))) +#define PMGR_DVFM_CFG1_CLK_SRC_SHIFT (18) +#define PMGR_DVFM_CFG1_MIN_VOL_SHIFT (8) +#define PMGR_DVFM_CFG1_SAFE_VOL_SHIFT (0) +#define PMGR_DVFM_CFG1_VOL_MASK (0xFF) +#define rPMGR_DVFM_CFG2(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1408 + ((_s) * 0x20))) +#define PMGR_DVFM_CFG2_SRAM_VOL_SHIFT (24) +#define PMGR_DVFM_CFG2_SRAM_VOL_MASK (0xFF) +#define rPMGR_DVFM_CFG3(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x140C + ((_s) * 0x20))) +#define rPMGR_DVFM_CFG4(_s) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1410 + ((_s) * 0x20))) + +#define rPMGR_DVFM_COMMON_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1600)) +#define rPMGR_DVFM_STA_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1604)) +#define rPMGR_DVFM_CFG_SEL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1608)) +#define rPMGR_DVFM_DELAY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x160C)) +#define PMGR_DVFM_DELAY_VOL_CHG_FIX_DLY_SHIFT (8) +#define PMGR_DVFM_DELAY_VOL_CHG_VAR_DLY_SHIFT (0) +#define rPMGR_DVFM_SRAM_VOL_DELAY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1610)) +#define PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_FIX_DLY_SHIFT (8) +#define PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_VAR_DLY_SHIFT (0) + +#define rPMGR_SENSOR_CMD (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1680)) +#define rPMGR_CORE0_TMP_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1684)) +#define rPMGR_CORE1_TMP_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1688)) +#define rPMGR_CORE0_SPD_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x168C)) +#define rPMGR_CORE1_SPD_SEN_RSLT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1690)) + +#define rPMGR_APSC_STA_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1700)) +#define PMGR_APSC_PENDING (1 << 31) +#define PMGR_APSC_SCC_MANUAL_CHANGE (1 << 25) +#define PMGR_APSC_SOC_MANUAL_CHANGE (1 << 24) +#define PMGR_APSC_SCC_MANUAL_STATE(_d) (((_d) & 0x7) << 20) +#define PMGR_APSC_SOC_MANUAL_STATE(_p) (((_p) & 0xF) << 8) +#define PMGR_APSC_MANUAL_CHANGE(_d, _p) \ + (PMGR_APSC_SCC_MANUAL_CHANGE | PMGR_APSC_SOC_MANUAL_CHANGE | \ + PMGR_APSC_SCC_MANUAL_STATE(_d) | PMGR_APSC_SOC_MANUAL_STATE(_p)) + +#define rPMGR_SCC_SLEEP_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1704)) +#define rPMGR_SCC_SLEEP_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1708)) +#define rPMGR_SCC_WAKE_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x170C)) +#define rPMGR_SCC_WAKE_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1710)) +#define rPMGR_SCC_MANUAL_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1714)) +#define rPMGR_SCC_MANUAL_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1718)) +#define rPMGR_SOC_SLEEP_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x171C)) +#define rPMGR_SOC_SLEEP_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1720)) +#define rPMGR_SOC_WAKE_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1724)) +#define rPMGR_SOC_WAKE_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1728)) +#define rPMGR_SOC_MANUAL_TIME_STAMP_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x172C)) +#define rPMGR_SOC_MANUAL_TIME_STAMP_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x1730)) + +#define rPMGR_TEST_CLK (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2000)) + +#define rPMGR_OSC_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x200C)) +#define rPMGR_PLL_DEBUG(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2010 + ((_n) * 4))) +#define PMGR_PLL_DEBUG_ENABLED (1 << 31) +#define PMGR_PLL_DEBUG_BYP_ENABLED (1 << 30) +#define PMGR_PLL_DEBUG_DBG_STPCLK_EN (1 << 24) +#define PMGR_PLL_DEBUG_FSTATE (1 << 12) +#define PMGR_PLL_DEBUG_STATE(_r) (((_r) >> 0) & 0xFFF) + +#define rPMGR_DOUBLER_DEBUG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2030)) +#define PMGR_DOUBLER_DEBUG_ENABLED (1 << 31) +#define PMGR_DOUBLER_DEBUG_BYP_ENABLED (1 << 30) + +#define rPMGR_SRAM_EMA_B0_Pn_LO(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2128 + (((_n) - 1) * 8))) +#define rPMGR_SRAM_EMA_B0_Pn_HI(_n) (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x212C + (((_n) - 1) * 8))) + +enum { + EMA_MCU = 1, + EMA_GFX_PIPES_SYS = 2, + EMA_GFX_HYDRA = 3, + EMA_VDEC = 4, + EMA_VENC = 5, + EMA_ISP = 6, + EMA_DISP = 7, + EMA_NRT = 8, + EMA_PMGR = 9, + EMA_IOP = 10, + EMA_SAUDIO = 11, + EMA_CDIO = 12, + EMA_FMI = 13, + EMA_ADSP = 14, +}; + +#define rPMGR_WDOG_TMR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3020)) +#define rPMGR_WDOG_RST (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3024)) +#define rPMGR_WDOG_INT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x3028)) +#define rPMGR_WDOG_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x302C)) + +#define rPMGR_PERF_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4000)) +#define rPMGR_PERF_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4004)) +#define rPMGR_PERF_CTR0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4020)) +#define rPMGR_PERF_CTR0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4024)) +#define rPMGR_PERF_CFG0_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4028)) +#define rPMGR_PERF_CFG0_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x402C)) +#define rPMGR_PERF_CFG0_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4030)) +#define rPMGR_PERF_CTR1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4040)) +#define rPMGR_PERF_CTR1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4044)) +#define rPMGR_PERF_CFG1_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4048)) +#define rPMGR_PERF_CFG1_MID (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x404C)) +#define rPMGR_PERF_CFG1_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x4050)) + +#define rPMGR_SCRATCH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6000)) +#define rPMGR_SCRATCH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6004)) +#define rPMGR_SCRATCH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6008)) +#define rPMGR_SCRATCH3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x600C)) +#define rPMGR_SCRATCH4 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6010)) +#define rPMGR_SCRATCH5 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6014)) +#define rPMGR_SCRATCH6 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6018)) +#define rPMGR_SCRATCH7 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x601C)) +#define rPMGR_SCRATCH8 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6020)) +#define rPMGR_SCRATCH9 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6024)) +#define rPMGR_SCRATCH10 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6028)) +#define rPMGR_SCRATCH11 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x602C)) +#define rPMGR_SCRATCH12 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6030)) +#define rPMGR_SCRATCH13 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6034)) +#define rPMGR_SCRATCH14 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x6038)) +#define rPMGR_SCRATCH15 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x603C)) + +#define rPMGR_DAC_FS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x7000)) + +#define rPMGR_USB_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x8000)) + +#define rPMGR_SHA_SEL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x9000)) + +#define rPMGR_SECURITY (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xA000)) + +#define rPMGR_GFX_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xB000)) + + +#define rPMGR_THERMAL0_CTL0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC000)) +#define rPMGR_THERMAL0_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC004)) +#define rPMGR_THERMAL0_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC008)) +#define rPMGR_THERMAL0_CTL3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC00C)) +#define rPMGR_THERMAL0_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC010)) +#define rPMGR_THERMAL0_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC014)) +#define rPMGR_THERMAL0_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC018)) +#define rPMGR_THERMAL0_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC01C)) +#define rPMGR_THERMAL1_CTL0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC040)) +#define rPMGR_THERMAL1_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC044)) +#define rPMGR_THERMAL1_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC048)) +#define rPMGR_THERMAL1_CTL3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC04C)) +#define rPMGR_THERMAL1_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC050)) +#define rPMGR_THERMAL1_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC054)) +#define rPMGR_THERMAL1_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC058)) +#define rPMGR_THERMAL1_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0xC05C)) + + +#define PGMR_GET_PERF_STATE_INDEX(_n, _x) (((_x) >> ((_n) * 4)) & 0xF) +#define PGMR_SET_PERF_STATE_INDEX(_n, _i) (((_i) & 0xF) << ((_n) * 4)) +#define PMGR_PERF_STATE_V(_n) (_n) +#define PMGR_PERF_STATE_P (3) +#define PMGR_PERF_STATE_M(_n) (4 + (_n)) + +enum { + PMGR_CLK_OSC = 0, + PMGR_CLK_PLL0, + PMGR_CLK_PLL1, + PMGR_CLK_PLL2, + PMGR_CLK_PLL3, + PMGR_CLK_PLL4, + PMGR_CLK_PLL5, + PMGR_CLK_PLL6, + PMGR_CLK_PLLUSB, + PMGR_CLK_DOUBLER, + PMGR_CLK_PLL2_GATED, + PMGR_CLK_PLL4_GATED, + PMGR_CLK_PLL5_GATED, + PMGR_CLK_MCU_FIXED, + PMGR_CLK_MCU, + PMGR_CLK_CPU, + PMGR_CLK_PREDIV0, + PMGR_CLK_PREDIV1, + PMGR_CLK_PREDIV2, + PMGR_CLK_PREDIV3, + PMGR_CLK_PREDIV4, + PMGR_CLK_PREDIV5, + PMGR_CLK_GFX, + PMGR_CLK_GFX_SYS, + PMGR_CLK_HPERFRT, + PMGR_CLK_DISPOUT, + PMGR_CLK_VID0, + PMGR_CLK_VID1, + PMGR_CLK_HPERFNRT, + PMGR_CLK_NRT_MEM, + PMGR_CLK_VENC_MTX, + PMGR_CLK_VENC, + PMGR_CLK_VDEC, + PMGR_CLK_ISP, + PMGR_CLK_IOP, + PMGR_CLK_CDIO, + PMGR_CLK_LPERFS, + PMGR_CLK_PCLK0, + PMGR_CLK_PCLK1, + PMGR_CLK_PCLK2, + PMGR_CLK_PCLK3, + PMGR_CLK_AES, + PMGR_CLK_MEDIUM0, + PMGR_CLK_MEDIUM1, + PMGR_CLK_I2C, + PMGR_CLK_SDIO, + PMGR_CLK_AUDIO, + PMGR_CLK_UPERF, + PMGR_CLK_DEBUG, + PMGR_CLK_SCC_PWR, + PMGR_CLK_SCC_DMA, + PMGR_CLK_SPI0, + PMGR_CLK_SPI1, + PMGR_CLK_SPI2, + PMGR_CLK_SPI3, + PMGR_CLK_SPI4, + PMGR_CLK_SLOW, + PMGR_CLK_SLEEP, + PMGR_CLK_USB_PHY0, + PMGR_CLK_USBOHCI, + PMGR_CLK_USB12, + PMGR_CLK_NCO_REF0, + PMGR_CLK_NCO_REF1, + PMGR_CLK_NCO_REF2, + PMGR_CLK_USB_PHY1, + PMGR_CLK_USB_EHCI_FREE, + PMGR_CLK_COUNT +}; + +extern void pmgr_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/s5l8955x/include/platform/trampoline.h b/platform/s5l8955x/include/platform/trampoline.h new file mode 100644 index 0000000..32d8ff6 --- /dev/null +++ b/platform/s5l8955x/include/platform/trampoline.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include +#include + +#define SECURITY_REG (PMGR_BASE_ADDR + 0xA000) +#define ROM_READ_DISABLE (1 << 0) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s5l8955x/include/platform/usbconfig.h b/platform/s5l8955x/include/platform/usbconfig.h new file mode 100644 index 0000000..26cbf07 --- /dev/null +++ b/platform/s5l8955x/include/platform/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#define USBPHY_CLK_TYPE (3) /* Use CLKCORE */ + +#define USBPHY_UOTGTUNE1 (0x649) +#define USBPHY_UOTGTUNE2 (0x2FF3) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s5l8955x/init.c b/platform/s5l8955x/init.c new file mode 100644 index 0000000..8275912 --- /dev/null +++ b/platform/s5l8955x/init.c @@ -0,0 +1,1309 @@ +/* + * Copyright (C) 2010-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_EFFACEABLE_NOR +#include +#endif + +extern void dma_init(void); + +static void platform_init_boot_strap(void); + +static uint8_t boot_debug; + +int platform_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + /* Verify that the fuses and that the SecureROM has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile u_int32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled"); + } +#endif + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8955x pmgr driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_DWI + extern int dwi_init(void); + dwi_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); +#if !RELEASE_BUILD && (PRODUCT_IBSS || PRODUCT_IBEC) + debug_enable_uarts(3); +#endif +#endif +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_HW_DMA + /* initialize the dma engine */ + dma_init(); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + return 0; +} + + +int platform_late_init(void) +{ + // Only support B0 and later + if (platform_get_chip_revision() < 0x10) { + platform_not_supported(); + } + +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_NAND + flash_nand_id(); +#endif + +#if WITH_HW_AMC + extern void mcu_late_init(void); + mcu_late_init(); +#endif + + return 0; +} + + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); + + /* always remap the memory region at this point, regardless of resume, + * because the early MMU init always runs and we have to fix up. */ + platform_init_mainmem_map(); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +#if APPLICATION_IBOOT + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, kARMMMUNormal, true, true); +#endif +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +static bool gDisplayEnabled; + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { + if (!displayInitOnce) { + platform_quiesce_display(); + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + + power_backlight_enable(backlight_level); +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + u_int32_t base_rounded = *base; + u_int32_t end_rounded = *base + *size; + u_int32_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + arm_mmu_map_section_range(base_rounded, base_rounded, size_rounded/MB, kARMMMUWriteCombined, false, true); + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_NAND_FILESYSTEM + flash_nand_init(); +#endif + +#if WITH_SW_HDC + hdc_init(); +#endif + return 0; +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + quiesce_clocks = true; +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + clock_gate(CLK_HPERFRT, true); + clock_gate(CLK_DISPOUT, true); + + /* quiesce the panel */ + if (display_quiesce(true) == ENXIO) { + clock_gate(CLK_HPERFRT, false); + clock_gate(CLK_DISPOUT, false); + } + +#endif + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + u_int32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + platform_quiesce_display(); + case BOOT_DARWIN: + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + ; // do nothing + } + + /* if we left the fuse unlocked for boot image processing, + * lock it now, after optionally switching from production to + * development fusing. */ + if (security_get_production_override()) + chipid_clear_production_mode(); + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + + /* mark usable ram as cached/buffered */ + arm_mmu_map_section_range(SRAM_BASE, SRAM_BASE, ROUNDUP(SRAM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#if APPLICATION_SECUREROM + arm_mmu_map_section_range(VROM_BASE, VROM_BASE, ROUNDUP(VROM_BANK_LEN, MB)/MB, kARMMMUNormal, false, false); +#endif + + /* Remap text base is to zero (for exception vectors) */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUNormalRX, false); + +#ifdef MMU_NONCACHE0_SIZE + /* create the noncached0 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE0_VBASE, MMU_NONCACHE0_PBASE, ROUNDUP(MMU_NONCACHE0_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + +#ifdef MMU_NONCACHE1_SIZE + /* create the noncached1 mapping */ + arm_mmu_map_section_range(MMU_NONCACHE1_VBASE, MMU_NONCACHE1_PBASE, ROUNDUP(MMU_NONCACHE1_SIZE, MB)/MB, kARMMMUStronglyOrdered, false, false); +#endif + + /* in cases where we are running from DRAM, remap it now */ + if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) { + platform_init_mainmem_map(); + } +} + +int platform_init(void) +{ +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_NAND_BOOT + nand_boot_init(); +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + +#if WITH_EFFACEABLE_NOR + effaceable_nor_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + u_int32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +u_int32_t platform_set_performance(u_int32_t performance_level) +{ + u_int32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + u_int32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_CPU); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_MEM); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_BUS); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_PERIPH); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_FIXED); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_TIMEBASE); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(u_int32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_NAND_FILESYSTEM + if (FindNode(0, "arm-io/flash-controller0/disk", &node)) { + fillNandConfigProperties(node); + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + + // H5G A0 support +#if WITH_HW_PLATFORM_CHIPID + if (platform_get_chip_revision() < 0x10) { + if (FindNode(0, "arm-io/clcd", &node)) { + propName = "enable-aap"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + } +#endif + + return target_update_device_tree(); +} + +#endif + +static void platform_init_boot_strap(void) +{ + u_int32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG3, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG3) << 3) | + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +u_int32_t platform_get_board_id(void) +{ + u_int32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +u_int32_t platform_get_boot_config(void) +{ + u_int32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, u_int32_t *boot_flag, u_int32_t *boot_arg) +{ + u_int32_t boot_config = platform_get_boot_config(); + + /* S5L8955X supports one boot device then USB-DFU per boot config */ + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case 0: /* SPI 0 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 1: /* SPI 3 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 3; + break; + + case 2: /* SPI 0 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case 3: /* SPI 3 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 3; + break; + + case 4: /* FMI0 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 0; + break; + + case 5: /* FMI0 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 0; + break; + + case 6: /* FMI0 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 0; + break; + +/* case 7: Unused */ + + case 8: /* FMI1 2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 2 << 8; + break; + + case 9: /* FMI1 4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 4 << 8; + break; + + case 10: /* FMI1 4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 4 << 8; + break; + +/* case 11: Unused */ + + case 12: /* FMI0/1 2/2 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (2 << 8) | (2 << 0); + break; + + case 13: /* FMI0/1 4/4 CS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = (4 << 8) | (4 << 0); + break; + + case 14: /* FMI0/1 4/4 CS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = (4 << 8) | (4 << 0); + break; + +/* case 15: Unused */ + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == 1) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + u_int32_t enable; + u_int32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(14, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO(14, 3), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO(14, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO(14, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO(14, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; + +static const struct boot_interface_pin spi3_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO(28, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_SSIN +#else + { GPIO(28, 4), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI3_SSIN +#endif + { GPIO(28, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_SCLK + { GPIO(28, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI3_MOSI + { GPIO(28, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI3_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND +/* Note: The code below expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi0_boot_interface_pins[] = +{ + { GPIO( 5, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN3 + { GPIO( 5, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN2 + { GPIO( 6, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN1 + { GPIO( 6, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CEN0 + { GPIO( 6, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_CLE + { GPIO( 6, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_ALE + { GPIO( 6, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_REN + { GPIO( 6, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_WEN + { GPIO( 8, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO0 + { GPIO( 7, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO1 + { GPIO( 7, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO2 + { GPIO( 7, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO3 + { GPIO( 7, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO4 + { GPIO( 7, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO5 + { GPIO( 7, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI0_IO6 + { GPIO( 6, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI0_IO7 +}; + +/* Note: The code below expects this table to begin with CS3 through CS0 */ +static const struct boot_interface_pin fmi1_boot_interface_pins[] = +{ + { GPIO( 8, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN3 + { GPIO( 8, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN2 + { GPIO( 8, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN1 + { GPIO( 9, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CEN0 + { GPIO( 9, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_CLE + { GPIO( 9, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_ALE + { GPIO( 9, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_REN + { GPIO( 9, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_WEN + { GPIO(10, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO0 + { GPIO(10, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO1 + { GPIO(10, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO2 + { GPIO(10, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO3 + { GPIO(10, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO4 + { GPIO(10, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO5 + { GPIO( 9, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // FMI1_IO6 + { GPIO( 9, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // FMI1_IO7 +}; +#endif /* WITH_HW_BOOTROM_NAND */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, u_int32_t boot_arg) +{ + const struct boot_interface_pin *pins0 = 0; + const struct boot_interface_pin *pins1 = 0; + u_int32_t cnt, func, pin_count0 = 0, pin_count1 = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins0 = spi0_boot_interface_pins; + pin_count0 = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } else if (boot_arg == 3) { + pins0 = spi3_boot_interface_pins; + pin_count0 = (sizeof(spi3_boot_interface_pins) / sizeof(spi3_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_HW_BOOTROM_NAND + case BOOT_DEVICE_NAND : + pins0 = fmi0_boot_interface_pins; + pin_count0 = (sizeof(fmi0_boot_interface_pins) / sizeof(fmi0_boot_interface_pins[0])); + switch ((boot_arg >> 0) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins0 += 2; + pin_count0 -= 2; + break; + + default: + pins0 = 0; + pin_count0 = 0; + break; + } + + pins1 = fmi1_boot_interface_pins; + pin_count1 = (sizeof(fmi1_boot_interface_pins) / sizeof(fmi1_boot_interface_pins[0])); + switch ((boot_arg >> 8) & 0xFF) { + case 4: /* CS x4 - skip no pin */ + break; + + case 2: /* CS x2 - skip 2 pins */ + pins1 += 2; + pin_count1 -= 2; + break; + + default: + pins1 = 0; + pin_count1 = 0; + break; + } + break; +#endif /* WITH_HW_BOOTROM_NAND */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count0; cnt++) { + if (enable) { + pin = pins0[pin_count0 - 1 - cnt].pin; + func = pins0[pin_count0 - 1 - cnt].enable; + } else { + pin = pins0[cnt].pin; + func = pins0[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } + + for (cnt = 0; cnt < pin_count1; cnt++) { + if (enable) { + pin = pins1[pin_count1 - 1 - cnt].pin; + func = pins1[pin_count1 - 1 - cnt].enable; + } else { + pin = pins1[cnt].pin; + func = pins1[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 1 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +u_int64_t platform_get_nonce(void) +{ + u_int64_t nonce; + u_int32_t *nonce_words = (u_int32_t *)&nonce; + +#if WITH_EFFACEABLE && PRODUCT_IBOOT + // N41 : Sundance 10A267 : USER IPSW : iTunes fails with error 21. + // In iboot use key stored in effaceable and cache it + // for later use, rather than using random_get_bytes + // key generated by secure-rom + static bool use_cached_effaceable_key; + if(use_cached_effaceable_key == false) { + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagNonce; + use_cached_effaceable_key = true; + } +#endif + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return chipid_get_ecid_image_personalization_required(); +} + +u_int32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +#if WITH_TARGET_CONFIG + +// The target's rules.mk sets the high SoC voltage point +#ifndef TARGET_BOOT_SOC_VOLTAGE +#error TARGET_BOOT_SOC_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} + +// The target's rules.mk sets the high CPU voltage point +#ifndef TARGET_BOOT_CPU_VOLTAGE +#error TARGET_BOOT_CPU_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_BOOT_CPU_VOLTAGE); +} + +// The target's rules.mk sets the high RAM voltage point +#ifndef TARGET_BOOT_RAM_VOLTAGE +#error TARGET_BOOT_RAM_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_ram_voltage(void) +{ + return chipid_get_ram_voltage(TARGET_BOOT_RAM_VOLTAGE); +} + +static const u_int32_t soc_voltage_points[] = { + CHIPID_SOC_VOLTAGE_LOW, + CHIPID_SOC_VOLTAGE_MED, + CHIPID_SOC_VOLTAGE_HIGH +}; + +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(soc_voltage_points) / sizeof(soc_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_soc_voltage(soc_voltage_points[cnt]); + } + + return 0; +} + +int platform_get_cpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cnt); + } + + return 0; +} + +static const u_int32_t ram_voltage_points[] = { + CHIPID_RAM_VOLTAGE_LOW, + CHIPID_RAM_VOLTAGE_HIGH +}; + +int platform_get_ram_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt, points = sizeof(ram_voltage_points) / sizeof(ram_voltage_points[0]); + + if (voltages == 0) return -1; + + if (count > points) count = points; + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_ram_voltage(ram_voltage_points[cnt]); + } + + return 0; +} + +#endif /* WITH_TARGET_CONFIG */ + +int platform_convert_voltages(int buck, u_int32_t count, u_int32_t *voltages) +{ +#if WITH_HW_POWER + u_int32_t index; + + if (voltages == 0) return -1; + + for (index = 0; index < count; index++) { + if (0 != power_get_buck_value(buck, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ +#if SUPPORT_FPGA + return !gpio_read(GPIO_FORCE_DFU); +#else + return gpio_read(GPIO_FORCE_DFU); +#endif +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(u_int32_t key_selector, u_int32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +#if APPLICATION_IBOOT +u_int64_t platform_get_memory_size(void) +{ + u_int64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (rPMGR_SCRATCH13 & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +u_int8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 28) & 0xf); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info(u_int8_t manuf_id, u_int64_t memory_size) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 28) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +#endif diff --git a/platform/s5l8955x/iop_init.c b/platform/s5l8955x/iop_init.c new file mode 100644 index 0000000..66eab91 --- /dev/null +++ b/platform/s5l8955x/iop_init.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Platform memory layout. + * + * The IOP sees SDRAM at its physical location uncached, and has an cached aperture + * visible elsewhere. SDRAM size of up to 1GB is currently supported. + * SRAM is not visible/legally usable. + * + * For some platforms/targets, SDRAM_LEN is not constant and so we + * have to compute a maximum via other means. + * + * Note that the AE2 Sparrow shares this code. + */ +#define MEM_CACHED_BASE (SDRAM_BASE | 0xc0000000) +#define SDRAM_MAX_LEN (SDRAM_BANK_LEN * SDRAM_BANK_COUNT) +struct mem_static_map_entry mem_static_map_entries[] = { + { + MEM_CACHED_BASE, /* cached */ + SDRAM_BASE, /* uncached */ + SDRAM_BASE, /* physical */ + SDRAM_MAX_LEN /* length */ + }, + {MAP_NO_ENTRY, MAP_NO_ENTRY, MAP_NO_ENTRY, 0} +}; + +void platform_mmu_setup(bool resume) +{ + if (false == resume) { + /* Note: sharing settings aren't critical, as SCC doesn't see the AxUSER bits + * and the AxCACHE widget does all the heavy lifting. */ + + /* Remap text base to zero, outer uncacheable, shared */ + arm_mmu_map_section(0, TEXT_BASE, kARMMMUInnerNormalOuterNoncached, true); + /* Remap all of SDRAM through the cacheable aperture, outer uncacheable, shared */ + arm_mmu_map_section_range(MEM_CACHED_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUInnerNormalOuterNoncached, true, false); + /* Remap all of SDRAM through the uncacheable aperture (existing mappings should be there, but be sure) */ + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, + kARMMMUStronglyOrdered, false, false); + } +} + +bool platform_get_production_mode(void) +{ + return(true); +} + +bool platform_get_secure_mode(void) +{ + return(true); +} + +void platform_reset(bool panic) +{ + for (;;) + ; +} + +/* + * Early init is done every time the IOP starts. + */ +int +platform_early_init() +{ +#if PLATFORM_VARIANT_IOP + /* In general we want power-gating to be disabled. */ + rPMGR_PWR_GATE_CTL_CLR = PMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & PMGR_PWR_GATE_IOP) ; +#endif + + interrupt_init(); + + timer_init(0); + + return(0); +} + +/* + * Halt waiting for an interrupt. + */ +void +platform_halt(void) +{ + arch_halt(); +} + +#if SUPPORT_SLEEP + +#if WITH_IOP_POWER_GATING + +/* + * Deep idle sleep with power gating + */ +void +platform_deep_idle(void) +{ + rPMGR_PWR_GATE_CTL_SET = PMGR_PWR_GATE_IOP; + while (!(rPMGR_PWR_GATE_CTL_SET & PMGR_PWR_GATE_IOP)) ; + a5iop_sleep(1); + rPMGR_PWR_GATE_CTL_CLR = PMGR_PWR_GATE_IOP; + while (rPMGR_PWR_GATE_CTL_CLR & PMGR_PWR_GATE_IOP) ; +} + +#endif + +void +platform_sleep(void) +{ + /* We assume power-gating is disabled, which it need to be so + * the IOP wrapper registers don't disappear. */ + a5iop_sleep(0); +} + +#endif + +/* + * Cache control + */ +void +platform_cache_operation(int operation, void *address, u_int32_t length) +{ + /* Wrap the operation with interrupt disable to avoid + * reentrance (while allowing the low-level cacheop function + * to be used without bumping the IRQ disable level) */ + enter_critical_section(); + a5iop_cache_operation(operation, address, length); + exit_critical_section(); +} + +/* + * Host doorbell uses a SWI in the AIC. + */ +static void (* _doorbell_handler)(void *arg); +static void +platform_doorbell_handler(void *arg) +{ + /* clear the doorbell before passing up */ + interrupt_clear_ipc(INT_IOP); + _doorbell_handler(arg); +} + +void +platform_init_iop_doorbell(void (* handler)(void *arg), void *arg) +{ + _doorbell_handler = handler; + install_int_handler(INT_IOP, platform_doorbell_handler, arg); + set_int_type(INT_IOP, INT_TYPE_IRQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP); +} + +void +platform_mask_doorbell(void) +{ + mask_int(INT_IOP); +} + +void +platform_unmask_doorbell(void) +{ + unmask_int(INT_IOP); +} + +void +platform_ring_host_doorbell(void) +{ + interrupt_generate_ipc(INT_HOST); +} + +int +platform_init_nmi(void (*handler)(void *arg), void *arg) +{ +#ifdef INT_IOP_NMI + install_int_handler(INT_IOP_NMI, handler, arg); + set_int_type(INT_IOP_NMI, INT_TYPE_FIQ | INT_TYPE_LEVEL); + unmask_int(INT_IOP_NMI); +#endif + + return(0); +} + +/* + * Clock management. + * + * Currently the IOP does none for this platform. + */ +void clock_gate(int device, bool enable) +{ +} diff --git a/platform/s5l8955x/miu/miu.c b/platform/s5l8955x/miu/miu.c new file mode 100644 index 0000000..863a9ea --- /dev/null +++ b/platform/s5l8955x/miu/miu.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2010-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void miu_configure_bridge(const u_int32_t *bridge_settings); + +#define BRIDGE_SHIFT (16) +#define BRIDGE_MASK (0xFFFF) +#define NRT_DART_WIDGETS (0 << BRIDGE_SHIFT) +#define NRT_DART_BRIDGE (1 << BRIDGE_SHIFT) +#define NRT_TOP_WIDGETS (2 << BRIDGE_SHIFT) +#define NRT_TOP_BRIDGE (3 << BRIDGE_SHIFT) +#define RT_TOP_WIDGETS (4 << BRIDGE_SHIFT) +#define RT_TOP_BRIDGE (5 << BRIDGE_SHIFT) +#define UPERF_WIDGETS (6 << BRIDGE_SHIFT) +#define UPERF_BRIDGE (7 << BRIDGE_SHIFT) +#define CDIO_WIDGETS (8 << BRIDGE_SHIFT) +#define CDIO_BRIDGE (9 << BRIDGE_SHIFT) + +static const u_int32_t bridge_registers[] = { + NRT_DART_WIDGETS_BASE_ADDR, NRT_DART_PL301_BASE_ADDR, + NRT_TOP_WIDGETS_BASE_ADDR, NRT_TOP_PL301_BASE_ADDR, + RT_TOP_WIDGETS_BASE_ADDR, RT_TOP_PL301_BASE_ADDR, + UPERF_WIDGETS_BASE_ADDR, UPERF_PL301_BASE_ADDR, + CDIO_WIDGETS_BASE_ADDR, CDIO_PL301_BASE_ADDR, +}; + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +// The following settings are based on H5P/Bali Tunables Revision 0.46 + +static const u_int32_t bridge_settings_static[] = { + // Configure recommended transaction limits in CDIO + CDIO_WIDGETS | CDIO_IOP_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_IOP_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_IOP_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_IOP_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_CDMA_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_CDMA_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_CDMA_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_CDMA_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_UPERF_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_UPERF_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_UPERF_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_UPERF_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_AUDIO_RRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_AUDIO_WRLIMIT, 0x00000000, + CDIO_WIDGETS | CDIO_AUDIO_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_AUDIO_WTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_PIO_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_PIO_WTLIMIT, 0x00000404, + CDIO_WIDGETS | CDIO_CIM_RTLIMIT, 0x00003F3F, + CDIO_WIDGETS | CDIO_CIM_WTLIMIT, 0x00000F0F, + + // Configure recommended bridge settings in CDIO + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI0, 0x00000000, + CDIO_BRIDGE | CDIO_AR_CHAN_ARB_MI1, 0x00000000, + CDIO_BRIDGE | CDIO_AW_CHAN_ARB_MI1, 0x00000000, + + // Configure recommended features in CDIO + CDIO_WIDGETS | CDIO_IOP_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(0), 0xffffbbbb, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(1), 0xfedcba98, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(2), 0xffffbbbb, + CDIO_WIDGETS | CDIO_IOP_RC_REMAP(3), 0xfedcba98, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(0), 0x76767676, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(1), 0xfedcfedc, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(2), 0x76767676, + CDIO_WIDGETS | CDIO_IOP_WC_REMAP(3), 0xfedcfedc, + CDIO_WIDGETS | CDIO_IOP_C_REMAP_EN, 0x00000003, + CDIO_WIDGETS | CDIO_CDMA_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_UPERF_WGATHER, 0x00000100, + CDIO_WIDGETS | CDIO_AUDIO_WGATHER, 0x00000100, + + // Configure recommended traffic attributes in UPERF + // AxCACHE = Cacheable + // AxUSER = enable Shared bit + UPERF_WIDGETS | UPERF_OTG_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OTG_CACHE, 0x0107010B, + UPERF_WIDGETS | UPERF_EHCI_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_EHCI_CACHE, 0x0107010B, + UPERF_WIDGETS | UPERF_OHCI0_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI0_CACHE, 0x0107010B, + UPERF_WIDGETS | UPERF_OHCI1_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_OHCI1_CACHE, 0x0107010B, + UPERF_WIDGETS | UPERF_USB2HOST1EHCI_QOS, 0x01010101, + UPERF_WIDGETS | UPERF_USB2HOST1EHCI_CACHE, 0x0107010B, + + // Configure recommended bridge settings in UPERF + UPERF_BRIDGE | UPERF_RTLIMIT, 0x00000404, + UPERF_BRIDGE | UPERF_WTLIMIT, 0x00000404, + + 0, 0, + 0, 0 +}; +#endif // APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +#if WITH_DEVICETREE || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static const u_int32_t bridge_settings_dynamic[] = { + // Configure recommended transaction limits in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_RTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_DART_WTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER0_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_RTLIMIT, 0x00000707, + NRT_DART_WIDGETS | HPERF_NRT_DART_SCALER1_WTLIMIT, 0x00000404, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_RTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_WTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_RTLIMIT, 0x00003F3F, + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_WTLIMIT, 0x00003F3F, + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x02000002, // Scaler0 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AR_CHAN_ARB_MI, 0x03000003, // Sclaer1 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x00000000, // JPEG0 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x01000001, // JPEG1 High Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x02000002, // Scaler0 Reduced Priority + NRT_DART_BRIDGE | HPERF_NRT_DART_AW_CHAN_ARB_MI, 0x03000003, // Sclaer1 Reduced Priority + + // Configure recommended bridge settings in HPerf-NRT DART + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG0_QOS, 0x01010101, // JPEG0 LLT Traffic for R&W + NRT_DART_WIDGETS | HPERF_NRT_DART_JPEG1_QOS, 0x01010101, // JPEG1 LLT Traffic for R&W + 0, 0, + + // Configure recommended transaction limits in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_TOP_WTLIMIT, 0x00000F0F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VENC_WTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_VDEC_WTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_AUX_RTLIMIT, 0x00003F3F, + NRT_TOP_WIDGETS | HPERF_NRT_TOP_AUX_WTLIMIT, 0x00003F3F, + + // Configure recommended bridge settings in HPerf-NRT Top + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AR_CHAN_ARB_MI, 0x03000003, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x00000000, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x01000001, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x02000002, + NRT_TOP_BRIDGE | HPERF_NRT_TOP_AW_CHAN_ARB_MI, 0x03000003, + + // Configure recommended features in HPerf-NRT Top + NRT_TOP_WIDGETS | HPERF_NRT_TOP_AUX_WGATHER, 0x00000100, + 0, 0, + + // Configure recommended transaction limits in HPerf-RT Top + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP0_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_DISP1_RTLIMIT, 0x00001818, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_ISP_WTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_RTLIMIT, 0x00003F3F, + RT_TOP_WIDGETS | HPERF_RT_TOP_TOP_WTLIMIT, 0x00000F0F, + + // Configure recommended bridge settings in HPerf-RT Top + RT_TOP_BRIDGE | HPERF_RT_TOP_AR_CHAN_ARB_MI, 0x00000000, + RT_TOP_BRIDGE | HPERF_RT_TOP_AW_CHAN_ARB_MI, 0x00000000, + 0, 0, + + 0, 0 +}; +#endif // WITH_DEVICETREE || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif + +#if APPLICATION_SECUREROM || (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Configure bridges that are statically powered + clock_gate(CLK_UPERF, true); + miu_configure_bridge(bridge_settings_static); + clock_gate(CLK_UPERF, false); +#endif + +#if APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC + // Configure bridges that are dynamically powered + clock_gate(CLK_HPERFNRT, true); + clock_gate(CLK_HPERFRT, true); + miu_configure_bridge(bridge_settings_dynamic); + clock_gate(CLK_HPERFNRT, false); + clock_gate(CLK_HPERFRT, false); +#endif + + /* remap whatever bank of ram we're in to zero */ + if (TEXT_BASE == SRAM_BASE) + miu_select_remap(REMAP_SRAM); + else if ((TEXT_BASE >= SDRAM_BASE) && (TEXT_BASE < SDRAM_END)) + miu_select_remap(REMAP_SDRAM); + + return 0; +} + +static void miu_configure_bridge(const u_int32_t *bridge_settings) +{ + volatile u_int32_t *reg; + u_int32_t cnt = 0, bridge, offset, data; + + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + bridge = bridge_settings[cnt] >> BRIDGE_SHIFT; + offset = bridge_settings[cnt] & BRIDGE_MASK; + data = bridge_settings[cnt + 1]; + reg = (volatile u_int32_t *)(bridge_registers[bridge] + offset); + *reg = data; + cnt += 2; + } + cnt += 2; + } +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT && WITH_HW_AMC + mcu_initialize_dram(resume); +#endif + + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + u_int32_t tmp; + + switch (sel) { + case REMAP_SRAM: + tmp = miu_read_l2cadrmap() & ~3; + tmp |= 1; // RemapMode = 1 (L2C RAM) + miu_write_l2cadrmap(tmp); + break; + + case REMAP_SDRAM: + tmp = miu_read_l2cadrmap() & ~3; + tmp |= 2; // RemapMode = 2 (MEM) + miu_write_l2cadrmap(tmp); + break; + } +} + +void miu_bypass_prep(int step) +{ +#if APPLICATION_IBOOT && WITH_HW_AMC + extern void mcu_bypass_prep(int step); + mcu_bypass_prep(step); +#endif +} + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ + uint32_t propSize; + char *propName; + void *propData; + + // Fill in the bridge-settings property + propName = "bridge-settings"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize < sizeof(bridge_settings_dynamic)) { + panic("miu_update_device_tree: bridge-settings property is too small (0x%x)", propSize); + } + memcpy(propData, bridge_settings_dynamic, sizeof(bridge_settings_dynamic)); + } +} + +#endif diff --git a/platform/s5l8955x/miu/rules.mk b/platform/s5l8955x/miu/rules.mk new file mode 100644 index 0000000..8849cfe --- /dev/null +++ b/platform/s5l8955x/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s5l8955x/pmgr/pmgr.c b/platform/s5l8955x/pmgr/pmgr.c new file mode 100644 index 0000000..5f99383 --- /dev/null +++ b/platform/s5l8955x/pmgr/pmgr.c @@ -0,0 +1,1259 @@ +/* + * Copyright (C) 2010-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !APPLICATION_EMBEDDEDIOP + +#define PLL_VCO_TARGET(pllx) (2ULL * pllx##_O * ((pllx##_M) + 1) / ((pllx##_P) + 1)) +#define PLL_FREQ_TARGET(pllx) (2ULL * pllx##_O * ((pllx##_M) + 1) / ((pllx##_P) + 1) / ((pllx##_S) + 1)) + +static u_int32_t clk_divs_bypass[PMGR_CLK_CFG_COUNT] = { + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x140: cpu, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x150: pll2_gate, pll4_gate, pll5_gate, rsvd + 0x00000000, 0x80000001, 0x80000001, 0x80000001, // 0x160: rsvd, mcu_fixed, mcu, pclk1 + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x170: gfx, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x180: rsvd, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x190: prediv0, prediv1, prediv2, prediv3 + 0x80000001, 0x80000001, 0x00000000, 0x00000000, // 0x1A0: prediv4, prediv5, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1B0: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1C0: rsvd, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1D0: venc_mtx, venc, hperf_rt, gfx_sys + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1E0: hperf_nrt, nrt_mem, vdec, isp + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1F0: iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x200: pclk2, pclk3, aes, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x210: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x220: rsvd, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x230: medium0, medium1, vid0, vid1 + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x240: dispout, i2c, sdio, rsvd + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x250: audio, rsvd, rsvd, rsvd + 0x80000001, 0x80000001, 0x82000001, 0x80000001, // 0x260: uperf, debug, scc_pwr, scc_dma + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x270: spi0, spi1, spi2, spi3 + 0x80000001, 0x80000001, 0x82000001, 0x82000001, // 0x280: spi4, slow, sleep, usb_phy0 + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x290: usbohci, usb12, nco_ref0, nco_ref1 + 0x80000001, 0x82000001, 0x82000001, // 0x2A0: nco_ref2, usb_phy1, usb_ehci_free +}; + +struct dvfm_state { + u_int32_t pll_pms; + u_int16_t clk_src; + u_int8_t cpu_vi; + u_int8_t ram_vi; +}; + +static const struct dvfm_state dvfm_state_bypass = { + 0, // no PLL + 0, // use OSC + 0, // no cpu voltage + 0 // no ram voltage +}; + +static u_int32_t perf_state_bypass[1 * 5] = { + 0x01000101, 0x01010101, 0x01000301, 0x01010101, 0x00000100, // defaults, slow mcu_cfg, no voltage change +}; + +struct perf_info { + u_int8_t dvfm_state; + u_int8_t perf_state; +}; + +#if APPLICATION_IBOOT + +#ifndef TARGET_PREDIV5_DIV +#define TARGET_PREDIV5_DIV 5 +#endif + +#ifndef TARGET_VID0_DIV +#define TARGET_VID0_DIV 1 +#endif + +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 2 +#define PLL2_M 49 +#define PLL2_S 0 +#define PLL2_V PLL_VCO_TARGET(PLL2) +#define PLL2_T PLL_FREQ_TARGET(PLL2) + +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 1 +#define PLL3_M 86 +#define PLL3_S 1 +#define PLL3_V PLL_VCO_TARGET(PLL3) +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 3 +#define PLL4_M 170 +#define PLL4_S 0 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) + +#define PLL5 5 +#define PLL5_O OSC_FREQ +#define PLL5_P 2 +#define PLL5_M 96 +#define PLL5_S 1 +#define PLL5_V PLL_VCO_TARGET(PLL5) +#define PLL5_T PLL_FREQ_TARGET(PLL5) + +#define PLL6 6 +#define PLL6_O OSC_FREQ +#define PLL6_P 0 +#define PLL6_M 54 +#define PLL6_S 0 +#define PLL6_V PLL_VCO_TARGET(PLL6) +#define PLL6_T PLL_FREQ_TARGET(PLL6) + +#define PLLUSB USB +#define PLLUSB_O OSC_FREQ +#define PLLUSB_P 0 +#define PLLUSB_M 19 +#define PLLUSB_S 0 +#define PLLUSB_V PLL_VCO_TARGET(PLLUSB) +#define PLLUSB_T PLL_FREQ_TARGET(PLLUSB) + +#define D_PREDIV5 (0x90000000 | (TARGET_PREDIV5_DIV)) +#define D_VID0 (0x90000000 | (TARGET_VID0_DIV)) + +#define D_DISABLED (0x00000001) +#define D_RESERVED (0x00000000) +// Clocks configured with this value are managed by the perf table +// This value just enables the clock and puts in a dummy divider +#define D_PRF_TBL (0x80000001) + +static const u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80000001, D_RESERVED, D_RESERVED, D_RESERVED, // 0x140: cpu, rsvd, rsvd, rsvd + D_DISABLED, 0x80000001, 0x80000001, D_RESERVED, // 0x150: pll2_gate, pll4_gate, pll5_gate, rsvd + D_RESERVED, D_PRF_TBL, D_PRF_TBL, 0xB0000004, // 0x160: rsvd, mcu_fixed, mcu, pclk1 + D_PRF_TBL, D_RESERVED, D_RESERVED, D_RESERVED, // 0x170: gfx, rsvd, rsvd, rsvd + D_RESERVED, D_RESERVED, D_RESERVED, D_RESERVED, // 0x180: rsvd, rsvd, rsvd, rsvd + 0x90000005, 0x90000004, 0x90000003, 0xA0000001, // 0x190: prediv0, prediv1, prediv2, prediv3 + D_DISABLED, D_PREDIV5, D_RESERVED, D_RESERVED, // 0x1A0: prediv4, prediv5, rsvd, rsvd + D_RESERVED, D_RESERVED, D_RESERVED, D_RESERVED, // 0x1B0: rsvd, rsvd, rsvd, rsvd + D_RESERVED, D_RESERVED, D_RESERVED, D_RESERVED, // 0x1C0: rsvd, rsvd, rsvd, rsvd + D_PRF_TBL, 0x80000002, D_PRF_TBL, D_PRF_TBL, // 0x1D0: venc_mtx, venc, hperf_rt, gfx_sys + D_PRF_TBL, D_PRF_TBL, D_PRF_TBL, D_PRF_TBL, // 0x1E0: hperf_nrt, nrt_mem, vdec, isp + D_PRF_TBL, D_PRF_TBL, D_PRF_TBL, D_PRF_TBL, // 0x1F0: iop, cdio, lperfs, pclk0 + D_PRF_TBL, D_PRF_TBL, D_PRF_TBL, D_RESERVED, // 0x200: pclk2, pclk3, aes, rsvd + D_RESERVED, D_RESERVED, D_RESERVED, D_RESERVED, // 0x210: rsvd, rsvd, rsvd, rsvd + D_RESERVED, D_RESERVED, D_RESERVED, D_RESERVED, // 0x220: rsvd, rsvd, rsvd, rsvd + D_DISABLED, 0x8000000A, D_VID0, 0x90000013, // 0x230: medium0, medium1, vid0, vid1 + 0x8000000A, 0xB0000001, D_DISABLED, D_RESERVED, // 0x240: dispout, i2c, sdio, rsvd + 0x80000001, D_RESERVED, D_RESERVED, D_RESERVED, // 0x250: audio, rsvd, rsvd, rsvd + 0xA0000007, 0xA0000002, 0x80000001, 0xA000001F, // 0x260: uperf, debug, scc_pwr, scc_dma + 0xB0000001, 0xB0000001, 0xB0000001, 0xB0000001, // 0x270: spi0, spi1, spi2, spi3 + 0xB0000001, 0x80000018, 0x80000014, 0x80000001, // 0x280: spi4, slow, sleep, usb_phy0 + 0x80000001, 0x80000002, 0xA0000001, D_DISABLED, // 0x290: usbohci, usb12, nco_ref0, nco_ref1 + D_DISABLED, 0x80000001, 0x80000001, // 0x2A0: nco_ref2, usb_phy1, usb_ehci_free +}; + +#define DFVM_STATE_ACTIVE kDVFM_STATE_IBOOT +static const struct dvfm_state dvfm_state_active[] = { + { + PMGR_PLL_P(0) | PMGR_PLL_M(24) | PMGR_PLL_S(0), // PLL = 600MHz + 1, // Use PLL0 + 0, // Use CPU voltage 0 + CHIPID_RAM_VOLTAGE_LOW // Use low RAM voltage + }, + { + PMGR_PLL_P(0) | PMGR_PLL_M(41) | PMGR_PLL_S(0), // PLL = 1008MHz + 1, // Use PLL0 + 1, // Use CPU voltage 1 + CHIPID_RAM_VOLTAGE_HIGH // Use high RAM voltage + }, + { + PMGR_PLL_P(0) | PMGR_PLL_M(49) | PMGR_PLL_S(0), // PLL = 1200MHz + 1, // Use PLL0 + 2, // Use CPU voltage 2 + CHIPID_RAM_VOLTAGE_HIGH // Use high RAM voltage + }, + { + PMGR_PLL_P(0) | PMGR_PLL_M(57) | PMGR_PLL_S(0), // PLL = 1392MHz + 1, // Use PLL0 + 4, // Use CPU voltage 4 + CHIPID_RAM_VOLTAGE_HIGH // Use high RAM voltage + } +}; + +#define PERF_STATE_ACTIVE kPERF_STATE_IBOOT +static const u_int32_t perf_state_active[kPERF_STATE_IBOOT_CNT * 5] = { +#if ! SUPPORT_FPGA + 0x21004441, 0x02012101, 0x21004041, 0x41010121, CHIPID_SOC_VOLTAGE_MED, // divide by 1, mcu_cfg=0, med voltage + 0x01004541, 0x23420101, 0x61004121, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 2, mcu_cfg=1, low voltage + 0x01004541, 0x26440201, 0x61004222, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 4, mcu_cfg=2, low voltage + 0x01004541, 0x3f1f1f01, 0x61004328, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 31, mcu_cfg=3, low voltage + 0x01004541, 0x23420101, 0x61004041, 0x41424242, CHIPID_SOC_VOLTAGE_MED, // divide by 4, mcu_cfg=0, med voltage +#else /* SUPPORT_FPGA */ + 0x21002441, 0x02012101, 0x21004041, 0x41010121, CHIPID_SOC_VOLTAGE_MED, // divide by 1, mcu_cfg=0, med voltage + 0x01002541, 0x23420101, 0x41004121, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 2, mcu_cfg=1, low voltage + 0x01002541, 0x26440201, 0x41004222, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 4, mcu_cfg=2, low voltage + 0x01002541, 0x3f1f1f01, 0x41004328, 0x41424242, CHIPID_SOC_VOLTAGE_LOW, // divide by 31, mcu_cfg=3, low voltage + 0x01002541, 0x23420101, 0x41004041, 0x41424242, CHIPID_SOC_VOLTAGE_MED, // divide by 4, mcu_cfg=0, med voltage +#endif /* ! SUPPORT_FPGA */ +}; + +static const struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+0 }, + [kPerformanceMedium] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+1 }, + [kPerformanceLow] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+2 }, + [kPerformanceMemory] = { kDVFM_STATE_IBOOT+0, kPERF_STATE_IBOOT+4 }, +}; + +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_SECUREROM + +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 3 +#define PLL4_M 170 +#define PLL4_S 3 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) + +static const u_int32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x140: cpu, rsvd, rsvd, rsvd + 0x00000001, 0x80000001, 0x00000001, 0x00000000, // 0x150: pll2_gate, pll4_gate, pll5_gate, rsvd + 0x00000000, 0x80000001, 0x80000001, 0xB0000003, // 0x160: rsvd, mcu_fixed, mcu, pclk1 + 0x00000001, 0x00000000, 0x00000000, 0x00000000, // 0x170: gfx, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x180: rsvd, rsvd, rsvd, rsvd + 0x90000004, 0x00000001, 0x00000001, 0x00000001, // 0x190: prediv0, prediv1, prediv2, prediv3 + 0x00000001, 0x00000001, 0x00000000, 0x00000000, // 0x1A0: prediv4, prediv5, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1B0: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x1C0: rsvd, rsvd, rsvd, rsvd + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x1D0: venc_mtx, venc, hperf_rt, gfx_sys + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x1E0: hperf_nrt, nrt_mem, vdec, isp + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x1F0: iop, cdio, lperfs, pclk0 + 0x80000001, 0x80000001, 0x80000001, 0x00000000, // 0x200: pclk2, pclk3, aes, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x210: rsvd, rsvd, rsvd, rsvd + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0x220: rsvd, rsvd, rsvd, rsvd + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x230: medium0, medium1, vid0, vid1 + 0x00000001, 0x00000001, 0x00000001, 0x00000000, // 0x240: dispout, i2c, sdio, rsvd + 0x80000001, 0x00000000, 0x00000000, 0x00000000, // 0x250: audio, rsvd, rsvd, rsvd + 0x80000002, 0xB0000001, 0x80000001, 0x80000006, // 0x260: uperf, debug, scc_pwr, scc_dma + 0xB0000001, 0x00000001, 0x00000001, 0xB0000001, // 0x270: spi0, spi1, spi2, spi3 + 0x00000001, 0x80000018, 0x80000014, 0x80000001, // 0x280: spi4, slow, sleep, usb_phy0 + 0x00000001, 0x00000001, 0x00000001, 0x00000001, // 0x290: usbohci, usb12, nco_ref0, nco_ref1 + 0x00000001, 0x00000001, 0x00000001, // 0x2A0: nco_ref2, usb_phy1, usb_ehci_free +}; + +#define DFVM_STATE_ACTIVE kDVFM_STATE_SECUREROM +static const struct dvfm_state dvfm_state_active = { + PMGR_PLL_P(1) | PMGR_PLL_M(74) | PMGR_PLL_S(3), // PLL = 225MHz + 1, // Use PLL0 + 0, // no cpu voltage + 0 // no ram voltage +}; + +#define PERF_STATE_ACTIVE kPERF_STATE_SECUREROM +static const u_int32_t perf_state_active[1 * 5] = { + 0x01000101, 0x01010101, 0x01000301, 0x01010101, 0x00000100, // defaults, slow mcu_cfg, no voltage change +}; + +static const struct perf_info perf_levels[] = { + [kPerformanceHigh] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, + [kPerformanceMedium] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, + [kPerformanceLow] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, + [kPerformanceMemory] = { kDVFM_STATE_SECUREROM, kPERF_STATE_SECUREROM }, +}; + +#endif /* APPLICATION_SECUREROM */ + +/* current clock speeds */ +static u_int32_t cpu_clks[kDVFM_STATE_COUNT]; +static u_int32_t clks[PMGR_CLK_COUNT]; +static u_int32_t *plls = &clks[PMGR_CLK_PLL0]; +static u_int32_t perf_level; + +struct clk_parent { + volatile u_int32_t *divider_reg; + u_int32_t divider_type; + u_int32_t divider_offset; + u_int8_t parents[4]; +}; + +/* Based on PMGR 1.10 */ +static const struct clk_parent clk_parents[PMGR_CLK_COUNT] = { +[PMGR_CLK_OSC] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL0] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL1] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL2] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL3] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL4] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL5] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLL6] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_PLLUSB] = { 0, 0, 0x00, { 0, 0, 0, 0 } }, +[PMGR_CLK_DOUBLER] = { &rPMGR_DOUBLER_CTL, 0, 0x00, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_PLL2_GATED] = { &rPMGR_PLL2_GATE_CFG, 0, 0x00, { PMGR_CLK_PLL2, 0, 0, 0, } }, +[PMGR_CLK_PLL4_GATED] = { &rPMGR_PLL4_GATE_CFG, 0, 0x00, { PMGR_CLK_PLL4, 0, 0, 0, } }, +[PMGR_CLK_PLL5_GATED] = { &rPMGR_PLL5_GATE_CFG, 0, 0x00, { PMGR_CLK_PLL5, 0, 0, 0, } }, +[PMGR_CLK_MCU_FIXED] = { &rPMGR_MCU_FIXED_CLK_CFG, 2, 0x09, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4_GATED } }, +[PMGR_CLK_MCU] = { &rPMGR_MCU_CLK_CFG, 3, 0x08, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4_GATED } }, +[PMGR_CLK_CPU] = { &rPMGR_CPU_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL0, PMGR_CLK_PLL1, PMGR_CLK_MCU } }, +[PMGR_CLK_PREDIV0] = { &rPMGR_PREDIV0_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV1] = { &rPMGR_PREDIV1_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV2] = { &rPMGR_PREDIV2_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV3] = { &rPMGR_PREDIV3_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_PREDIV4] = { &rPMGR_PREDIV4_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL5, PMGR_CLK_PLL6, PMGR_CLK_PLL3 } }, +[PMGR_CLK_PREDIV5] = { &rPMGR_PREDIV5_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_GFX] = { &rPMGR_GFX_CLK_CFG, 3, 0x01, { PMGR_CLK_OSC, PMGR_CLK_PLL5, PMGR_CLK_PLL6, PMGR_CLK_PLL4 } }, +[PMGR_CLK_GFX_SYS] = { &rPMGR_GFX_SYS_CLK_CFG, 3, 0x03, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_HPERFRT] = { &rPMGR_HPERFRT_CLK_CFG, 3, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_DISPOUT] = { &rPMGR_DISPOUT_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VID0] = { &rPMGR_VID0_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV5, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VID1] = { &rPMGR_VID1_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL4, PMGR_CLK_PLL5_GATED, PMGR_CLK_PLL2_GATED } }, +[PMGR_CLK_HPERFNRT] = { &rPMGR_HPERFNRT_CLK_CFG, 3, 0x0D, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_NRT_MEM] = { &rPMGR_NRT_MEM_CLK_CFG, 3, 0x0C, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VENC_MTX] = { &rPMGR_VENC_MTX_CLK_CFG, 3, 0x0B, { PMGR_CLK_PREDIV1, PMGR_CLK_PLLUSB, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_VENC] = { &rPMGR_VENC_CLK_CFG, 1, 0x00, { PMGR_CLK_VENC_MTX, 0, 0, 0 } }, +[PMGR_CLK_VDEC] = { &rPMGR_VDEC_CLK_CFG, 3, 0x0E, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_ISP] = { &rPMGR_ISP_CLK_CFG, 3, 0x04, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_IOP] = { &rPMGR_IOP_CLK_CFG, 3, 0x05, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_CDIO] = { &rPMGR_CDIO_CLK_CFG, 3, 0x06, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_LPERFS] = { &rPMGR_LPERFS_CLK_CFG, 3, 0x07, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_PCLK0] = { &rPMGR_PCLK0_CLK_CFG, 0, 0x00, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK1] = { &rPMGR_PCLK1_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, PMGR_CLK_PLL2, PMGR_CLK_PLL3, PMGR_CLK_PLL4_GATED } }, +[PMGR_CLK_PCLK2] = { &rPMGR_PCLK2_CLK_CFG, 0, 0x00, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_PCLK3] = { &rPMGR_PCLK3_CLK_CFG, 0, 0x00, { PMGR_CLK_LPERFS, 0, 0, 0 } }, +[PMGR_CLK_AES] = { &rPMGR_AES_CLK_CFG, 3, 0x0F, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MEDIUM0] = { &rPMGR_MEDIUM0_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_MEDIUM1] = { &rPMGR_MEDIUM1_CLK_CFG, 1, 0x00, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_I2C] = { &rPMGR_I2C_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV3, PMGR_CLK_OSC } }, +[PMGR_CLK_SDIO] = { &rPMGR_SDIO_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_AUDIO] = { &rPMGR_AUDIO_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_UPERF] = { &rPMGR_UPERF_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_DEBUG] = { &rPMGR_DEBUG_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_OSC } }, +[PMGR_CLK_SCC_PWR] = { &rPMGR_SCC_PWR_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_SCC_DMA] = { &rPMGR_SCC_DMA_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_SPI0] = { &rPMGR_SPI0_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI1] = { &rPMGR_SPI1_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI2] = { &rPMGR_SPI2_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI3] = { &rPMGR_SPI3_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SPI4] = { &rPMGR_SPI4_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM0, PMGR_CLK_MEDIUM1, 0, PMGR_CLK_OSC } }, +[PMGR_CLK_SLOW] = { &rPMGR_SLOW_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_SLEEP] = { &rPMGR_SLEEP_CLK_CFG, 1, 0x00, { PMGR_CLK_SLOW, 0, 0, 0 } }, +[PMGR_CLK_USB_PHY0] = { &rPMGR_USB_PHY0_CLK_CFG, 0, 0x00, { PMGR_CLK_PLLUSB, 0, 0, 0 } }, +[PMGR_CLK_USBOHCI] = { &rPMGR_USBOHCI_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM1, PMGR_CLK_DOUBLER, 0, 0 } }, +[PMGR_CLK_USB12] = { &rPMGR_USB12_CLK_CFG, 1, 0x00, { PMGR_CLK_OSC, 0, 0, 0 } }, +[PMGR_CLK_NCO_REF0] = { &rPMGR_NCO_REF0_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_NCO_REF1] = { &rPMGR_NCO_REF1_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_NCO_REF2] = { &rPMGR_NCO_REF2_CLK_CFG, 1, 0x00, { PMGR_CLK_PREDIV0, PMGR_CLK_PREDIV1, PMGR_CLK_PREDIV2, PMGR_CLK_PREDIV3 } }, +[PMGR_CLK_USB_PHY1] = { &rPMGR_USB_PHY1_CLK_CFG, 1, 0x00, { PMGR_CLK_PLLUSB, 0, 0, 0, } }, +[PMGR_CLK_USB_EHCI_FREE]={ &rPMGR_USB_EHCI_FREE_CLK_CFG, 0, 0x00, { PMGR_CLK_MEDIUM1, PMGR_CLK_DOUBLER, 0, 0 } }, +}; + +static void init_thermal_sensors(void); +static void clocks_get_frequencies(void); +static u_int32_t get_pll(int pll); +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t v); +static void clocks_set_gates(u_int64_t *devices, bool enable); +static void clocks_quiesce_internal(void); +static void update_perf_state(u_int32_t new_perf_state); + +static void wait_for_dev_ps_change(u_int32_t dev); +static void wait_for_pending_apsc_change(void); +static void wait_for_pending_clk_cfg_change(u_int32_t reg); +static void wait_for_pll_bypass_enabled(u_int32_t idx); +static void wait_for_pll_lock(u_int32_t idx); +static void wait_for_doubler_bypass_enabled(void); + +void platform_power_init(void) +{ +//#if 0 /* XXX Update for Bali. */ + + // Configure SCC CCXPWRCTRL to settings from H5P Tunables Revision 0.25 + rSCC_CCXPWRCTRL = 0x88800000; + + // Set Power Gating Parameters for all the power domains + // VDD_CPU RAMP_ALL time is larger then expected, rdar://problem/9376764 + rPMGR_PWR_GATE_TIME_A(1) = (720 << 16); // CPU0 + rPMGR_PWR_GATE_TIME_A(2) = (720 << 16); // CPU1 + rPMGR_PWR_GATE_TIME_A(6) = (34 << 16) | (1 << 0); // IOP + rPMGR_PWR_GATE_TIME_B(6) = (20 << 26) | (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(7) = (147 << 16) | (2 << 0); // GFX + rPMGR_PWR_GATE_TIME_B(7) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(8) = (123 << 16) | (2 << 0); // HPERF-RT + rPMGR_PWR_GATE_TIME_B(8) = (2 << 16) | (2 << 8) | (9 << 0); + rPMGR_PWR_GATE_TIME_A(9) = (139 << 16) | (2 << 0); // ISP + rPMGR_PWR_GATE_TIME_B(9) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(10) = (94 << 16) | (2 << 0); // HPERF-NRT + rPMGR_PWR_GATE_TIME_B(10) = (2 << 16) | (4 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(11) = (70 << 16) | (1 << 0); // VDEC + rPMGR_PWR_GATE_TIME_B(11) = (2 << 16) | (2 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(12) = (107 << 16) | (2 << 0); // VENC + rPMGR_PWR_GATE_TIME_B(12) = (2 << 16) | (4 << 8) | (4 << 0); + rPMGR_PWR_GATE_TIME_A(13) = (29 << 16) | (2 << 0); // FMI + rPMGR_PWR_GATE_TIME_B(13) = (2 << 16) | (2 << 8) | (4 << 0); +//#endif + + // Enable MCU_FIXED_CLK to be enabled/disabled based on request from MCU + rPMGR_ENABLE_CLK_GATE = (1 << 1); + +#if APPLICATION_IBOOT + /* clear CPU1's reset; it will still be powered down */ + clock_reset_device(CLK_CPU1); + + init_thermal_sensors(); +#endif +} + +extern void aic_spin(u_int32_t usecs); + +void platform_power_spin(u_int32_t usecs) +{ + aic_spin(usecs); +} + +int clocks_init(void) +{ +#if APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) + + u_int32_t cnt, tmp; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) plls[cnt] = get_pll(cnt); + + // Find the perf_level using PERF_STATE_CTL + tmp = (rPMGR_PERF_STATE_CTL >> PMGR_PERF_STATE_SEL_SHIFT) & PMGR_PERF_STATE_SEL_MASK; + for (perf_level = kPerformanceHigh; perf_level < kPerformanceLow; perf_level++) { + if (perf_levels[perf_level].perf_state == tmp) break; + } + + clocks_get_frequencies(); + +#endif /* APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC) */ + + return 0; +} + +/* clocks_set_default - called by SecureROM, LLB, iBSS main via + platform_init_setup_clocks, so the current state of the chip is + either POR, or whatever 'quiesce' did when leaving SecureROM. */ +int clocks_set_default(void) +{ + u_int32_t cnt, count, reg, val; + u_int32_t cpu_vid[kDVFM_STATE_COUNT], ram_vid[2], soc_vid[3]; + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + count = 0; + + for (cnt = 0; cnt < kDVFM_STATE_COUNT; cnt++) { + cpu_vid[cnt] = 0; + } + ram_vid[0] = ram_vid[1] = 0; + soc_vid[0] = soc_vid[1] = soc_vid[2] = 0; + + // Set up the bypass dvfm and performance states + rPMGR_DVFM_CFG0(kDVFM_STATE_BYPASS) = dvfm_state_bypass.pll_pms; + rPMGR_DVFM_CFG1(kDVFM_STATE_BYPASS) = dvfm_state_bypass.clk_src << PMGR_DVFM_CFG1_CLK_SRC_SHIFT; + rPMGR_DVFM_CFG2(kDVFM_STATE_BYPASS) = 0; + rPMGR_DVFM_CFG3(kDVFM_STATE_BYPASS) = 0; + rPMGR_DVFM_CFG4(kDVFM_STATE_BYPASS) = 0; + rPMGR_PERF_STATE_A(kPERF_STATE_BYPASS) = perf_state_bypass[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_BYPASS) = perf_state_bypass[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_BYPASS) = perf_state_bypass[2]; + rPMGR_PERF_STATE_D(kPERF_STATE_BYPASS) = perf_state_bypass[3]; + rPMGR_PERF_STATE_E(kPERF_STATE_BYPASS) = perf_state_bypass[4]; + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + + // Set default PLL parameters and lock time (1260 cycles) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + rPMGR_PLL_PARAM(cnt) = 0x9AF10000 | PMGR_PARAM_LOCK_TIME(1260); + } + +#if APPLICATION_SECUREROM + // Set up the active dvfm and performance states for the SecureROM + rPMGR_DVFM_CFG0(kDVFM_STATE_SECUREROM) = dvfm_state_active.pll_pms; + rPMGR_DVFM_CFG1(kDVFM_STATE_SECUREROM) = dvfm_state_active.clk_src << PMGR_DVFM_CFG1_CLK_SRC_SHIFT; + rPMGR_DVFM_CFG2(kDVFM_STATE_SECUREROM) = 0; + rPMGR_DVFM_CFG3(kDVFM_STATE_SECUREROM) = 0; + rPMGR_DVFM_CFG4(kDVFM_STATE_SECUREROM) = 0; + rPMGR_PERF_STATE_A(kPERF_STATE_SECUREROM) = perf_state_active[0]; + rPMGR_PERF_STATE_B(kPERF_STATE_SECUREROM) = perf_state_active[1]; + rPMGR_PERF_STATE_C(kPERF_STATE_SECUREROM) = perf_state_active[2]; + rPMGR_PERF_STATE_D(kPERF_STATE_SECUREROM) = perf_state_active[3]; + rPMGR_PERF_STATE_E(kPERF_STATE_SECUREROM) = perf_state_active[4]; +#endif + +#if APPLICATION_IBOOT + // Find the VID codes for the CPU, RAM and SoC rails + platform_get_cpu_voltages(kDVFM_STATE_COUNT, cpu_vid); + platform_get_ram_voltages(2, ram_vid); + platform_get_soc_voltages(3, soc_vid); + platform_convert_voltages(0, kDVFM_STATE_COUNT, cpu_vid); + platform_convert_voltages(16, 2, ram_vid); + platform_convert_voltages(2, 3, soc_vid); + + count = sizeof(dvfm_state_active) / sizeof(struct dvfm_state); + // Set up the active dvfm and performance states for iBoot + for (cnt = 0; cnt < count; cnt++) { + // Set PLL Configuration + rPMGR_DVFM_CFG0(kDVFM_STATE_IBOOT + cnt) = dvfm_state_active[cnt].pll_pms; + + // Set PLL Source and CPU Voltage Configuration + val = dvfm_state_active[cnt].clk_src << PMGR_DVFM_CFG1_CLK_SRC_SHIFT; + val |= (cpu_vid[dvfm_state_active[cnt].cpu_vi] & PMGR_DVFM_CFG1_VOL_MASK) << PMGR_DVFM_CFG1_SAFE_VOL_SHIFT; + rPMGR_DVFM_CFG1(kDVFM_STATE_IBOOT + cnt) = val; + + // Set SRAM Voltage and Temperature Sensor Region Configuration (0mV, 18.75mV & 31.25mV) + // H5 Tunables Rev 0.63 + val = (0xA << 12) | (0x5 << 6) | (0x0 << 0); + val |= (ram_vid[dvfm_state_active[cnt].ram_vi] & PMGR_DVFM_CFG2_SRAM_VOL_MASK) << PMGR_DVFM_CFG2_SRAM_VOL_SHIFT; + rPMGR_DVFM_CFG2(kDVFM_STATE_IBOOT + cnt) = val; + + // Set Speed Sensor Configuration + rPMGR_DVFM_CFG3(kDVFM_STATE_IBOOT + cnt) = 0; + rPMGR_DVFM_CFG4(kDVFM_STATE_IBOOT + cnt) = 0; + } + + for (cnt = 0; cnt < kPERF_STATE_IBOOT_CNT; cnt++) { + // Set the Clock Sources and Dividers + rPMGR_PERF_STATE_A(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 0]; + rPMGR_PERF_STATE_B(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 1]; + rPMGR_PERF_STATE_C(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 2]; + rPMGR_PERF_STATE_D(kPERF_STATE_IBOOT + cnt) = perf_state_active[(cnt * 5) + 3]; + + // Set the SoC Voltage Configuration + val = perf_state_active[(cnt * 5) + 4]; + reg = val & PMGR_PERF_STATE_E_VOL_MASK; + val = (val & ~PMGR_PERF_STATE_E_VOL_MASK) | + ((soc_vid[reg] & PMGR_PERF_STATE_E_VOL_MASK) << PMGR_PERF_STATE_E_VOL_SHIFT); + rPMGR_PERF_STATE_E(kPERF_STATE_IBOOT + cnt) = val; + } + + // Save the PERF_STATE configuration in rPMGR_SCRATCH1 + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, kPERF_STATE_IBOOT + 3); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), kPERF_STATE_IBOOT + 0); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), kPERF_STATE_IBOOT + 1); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), kPERF_STATE_IBOOT + 2); + rPMGR_SCRATCH1 |= PGMR_SET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), kPERF_STATE_IBOOT + 3); +#endif + +#ifdef PLL2_T + set_pll(2, PLL2_P, PLL2_M, PLL2_S, PLL2_V); +#endif + +#ifdef PLL3_T + set_pll(3, PLL3_P, PLL3_M, PLL3_S, PLL3_V); +#endif + +#ifdef PLL4_T + set_pll(4, PLL4_P, PLL4_M, PLL4_S, PLL4_V); +#endif + +#ifdef PLL5_T + set_pll(5, PLL5_P, PLL5_M, PLL5_S, PLL5_V); +#endif + +#ifdef PLL6_T + set_pll(6, PLL6_P, PLL6_M, PLL6_S, PLL6_V); +#endif + +#ifdef PLLUSB_T + set_pll(7, PLLUSB_P, PLLUSB_M, PLLUSB_S, PLLUSB_V); +#endif + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) plls[cnt] = get_pll(cnt); + + perf_level = kPerformanceLow; + + // Set all clock dividers to their active values + // Start with CPU then work backwards + for (cnt = 0; cnt < PMGR_CLK_CFG_COUNT; cnt++) { + reg = PMGR_CLK_CFG_COUNT - cnt; + if (reg == PMGR_CLK_CFG_COUNT) reg = 0; + + // Take care of managed clocks before predivs + if (reg == PMGR_FIRST_MANAGED_CLK_NUM) + update_perf_state(kPerformanceLow); + + val = clk_divs_active[reg]; + + clkcfgs[reg] = val; + // Sleep clock needs special attention: + // instead, we just make sure not to disable it. + + wait_for_pending_clk_cfg_change(reg); + } + + clocks_get_frequencies(); + +#if APPLICATION_IBOOT + // Configure SoC Voltage Delay for 12uS plus 12.5mV/uS + rPMGR_PERF_STATE_DELAY = + (144 << PMGR_PERF_STATE_DELAY_VOL_CHG_FIX_DLY_SHIFT) | (6 << PMGR_PERF_STATE_DELAY_VOL_CHG_VAR_DLY_SHIFT); + + // Configure Sensor Interval to about 1ms and + // Configure CPU Voltage Delay for 12uS plus 12.5mV/uS + rPMGR_DVFM_DELAY = + (0 << 28) | (6 << 18) | + (144 << PMGR_DVFM_DELAY_VOL_CHG_FIX_DLY_SHIFT) | (6 << PMGR_DVFM_DELAY_VOL_CHG_VAR_DLY_SHIFT); + + // Configure SRAM Voltage Delay for 12uS plus 12.5mV/uS + rPMGR_DVFM_SRAM_VOL_DELAY = + (144 << PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_FIX_DLY_SHIFT) | (6 << PMGR_DVFM_SRAM_VOL_DELAY_VOL_CHG_VAR_DLY_SHIFT); + + // Set Static Temperature Sensor Configuration + rPMGR_DVFM_COMMON_CFG = + ((chipid_get_cpu_temp_offset(1) & 0x7F) << 21) | + ((chipid_get_cpu_temp_offset(0) & 0x7F) << 14) | + (0x47 << 7) | (0x32 << 0); + + // Configure Temperature Sensors + rPMGR_SENSOR_CMD = (1 << 20) | (1 << 16) | (0x827 << 0); + + // Set Static DVFM Configuration + rPMGR_DVFM_STA_CTL = 0; + + rPMGR_VOLMAN_CTL = PMGR_VOLMAN_CPU_SW_OFF_TIME_VALUE(45) | PMGR_VOLMAN_BIT_ORDER_MSB | PMGR_VOLMAM_BYTE_SWAP; +#endif + + return 0; +} + +static void update_perf_state(u_int32_t new_perf_level) +{ + // Write the new select value for scc and soc + rPMGR_APSC_STA_CTL = PMGR_APSC_MANUAL_CHANGE(perf_levels[new_perf_level].dvfm_state, perf_levels[new_perf_level].perf_state); + wait_for_pending_apsc_change(); +} + +void clocks_quiesce(void) +{ + /* mcu_clk will be changed to bypass clock */ + clks[PMGR_CLK_MCU] = OSC_FREQ; + + /* Change all the clocks to something safe */ + clocks_quiesce_internal(); + + /* effectively full performance */ + perf_level = kPerformanceHigh; +} + +static void clock_update_range(u_int32_t first, u_int32_t last, const u_int32_t clkdata[]) +{ + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + u_int32_t val, reg; + + reg = first; + while (reg <= last) { + val = clkdata[reg]; + clkcfgs[reg] = val; + wait_for_pending_clk_cfg_change(reg); + reg++; + } +} + +static void clocks_quiesce_internal(void) +{ + u_int32_t cnt; + u_int64_t devices[2]; + + // Disable voltage changes + rPMGR_VOLMAN_CTL = PMGR_VOLMAN_DISABLE_VOL_CHANGE; + + // Critical: AIC, DEBUG, GPIO, UPERF, CDMA, CDIO, + // MCU, L2, L2_BIU, CPU0, SCC + devices[0] = 0x00000002C0000136ULL; + devices[1] = 0x000000000000C800ULL; + + // Turn on critical device clocks + clocks_set_gates(devices, true); + + // Turn off non-critical device clocks + clocks_set_gates(devices, false); + + // Simplified from PMGR Spec 0.045 Section 2.14.4.1 + + // Reset top-level dividers to bypass + clock_update_range(PMGR_CLK_NUM(PCLK1), PMGR_CLK_NUM(PREDIV5), clk_divs_bypass); + clock_update_range(PMGR_CLK_NUM(VID1), PMGR_CLK_NUM(VID1), clk_divs_bypass); + +#if APPLICATION_IBOOT + miu_bypass_prep(0); + + // Prepare to move memory to bypass clock (ensure not high frequency, enable DLL force mode) + rPMGR_APSC_STA_CTL = PMGR_APSC_MANUAL_CHANGE(perf_levels[kPerformanceMedium].dvfm_state, perf_levels[kPerformanceMedium].perf_state); + wait_for_pending_apsc_change(); + + miu_bypass_prep(1); +#endif + + // Reset scc and soc managed clocks + rPMGR_APSC_STA_CTL = PMGR_APSC_MANUAL_CHANGE(kDVFM_STATE_BYPASS, kPERF_STATE_BYPASS); + wait_for_pending_apsc_change(); + + // Reset PLLs + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + rPMGR_PLL_CTL0(cnt) = PMGR_PLL_EXT_BYPASS; + + // Wait for Bypass Enabled for PLL2 or higher + if (cnt >=2) { + wait_for_pll_bypass_enabled(cnt); + } + } + + // Reset Doubler + rPMGR_DOUBLER_CTL = PMGR_DOUBLER_EXT_BYPASS; + wait_for_doubler_bypass_enabled(); + + // Reset the lower-level clocks + clock_update_range(PMGR_CLK_NUM(VENC_MTX), PMGR_CLK_NUM(NCO_REF1), clk_divs_bypass); + + // Reset the CPU clocks + clock_update_range(PMGR_CLK_NUM(CPU), PMGR_CLK_NUM(MCU), clk_divs_bypass); +} + +u_int32_t clocks_set_performance(u_int32_t performance_level) +{ + u_int32_t old_perf_level = perf_level; + + update_perf_state(performance_level); + perf_level = performance_level; + return old_perf_level; +} + +void clock_get_frequencies(u_int32_t *clocks, u_int32_t count) +{ + u_int32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) cnt = count; + + memcpy(clocks, clks, cnt * sizeof(u_int32_t)); +} + +u_int32_t clock_get_frequency(int clock) +{ + switch (clock) { + case CLK_CPU: + case CLK_FCLK: + return clks[PMGR_CLK_CPU]; + case CLK_ACLK: + case CLK_MEM: + return clks[PMGR_CLK_MCU]; + case CLK_HCLK: + case CLK_BUS: + return clks[PMGR_CLK_CDIO]; + case CLK_PERIPH: + case CLK_PCLK: + return clks[PMGR_CLK_PCLK0]; + case CLK_FMI: + return clks[PMGR_CLK_PCLK1]; + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + return clks[PMGR_CLK_OSC]; + case CLK_USBPHYCLK: +#if SUPPORT_FPGA + return clks[PMGR_CLK_USB_PHY0]; /* The reference is special on FPGA */ +#else + return clks[PMGR_CLK_OSC]; /* This is ref_24_clk, not usb_phy_clk */ +#endif + case CLK_NCOREF: + return clks[PMGR_CLK_NCO_REF0]; + case CLK_VCLK0: + return clks[PMGR_CLK_VID0]; + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + return clks[PMGR_CLK_I2C]; + case CLK_MCLK: + default: + return 0; + } +} + +void clock_set_frequency(int clock, u_int32_t divider, u_int32_t pll_p, u_int32_t pll_m, u_int32_t pll_s, u_int32_t pll_t) +{ + u_int32_t total_div, prediv5_div, vid0_div; + + switch (clock) { + case CLK_VCLK0: + // Calculate the total divider required + total_div = clks[PMGR_CLK_PLL4] / pll_t; + + // Find the largest prediv5_div that will + // produce the correct total_div + for (prediv5_div = 31; prediv5_div > 1; prediv5_div--) { + if ((total_div % prediv5_div) == 0) break; + } + + // Calculate vid0_div based on the part of + // total_div not in prediv5_div + vid0_div = total_div / prediv5_div; + + // Set the clock dividers to their new values + rPMGR_PREDIV5_CLK_CFG = (rPMGR_PREDIV5_CLK_CFG & ~0x1f) | prediv5_div; + rPMGR_VID0_CLK_CFG = (rPMGR_VID0_CLK_CFG & ~0x1f) | vid0_div; + + // Update the list of frequencies + clks[PMGR_CLK_PREDIV5] = clks[PMGR_CLK_PLL4] / prediv5_div; + clks[PMGR_CLK_VID0] = clks[PMGR_CLK_PREDIV5] / vid0_div; + break; + default: + break; + } +} + +void clock_gate(int device, bool enable) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + if (reg > PMGR_LAST_PS) return; + + // Set the PS field to the requested level + if (enable) *reg |= 0xF; + else *reg &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + wait_for_dev_ps_change(device); +} + +static void clocks_set_gates(u_int64_t *devices, bool enable) +{ + u_int32_t dev, index; + volatile u_int32_t *devpss = PMGR_FIRST_PS; + u_int64_t mask = 1, devmask = 0; + + for (dev = 0, index = -1; dev < PMGR_PS_COUNT; dev++, mask <<= 1) { + if ((dev % 64) == 0) { + devmask = devices[++index]; + if (enable == false) + devmask ^= -1ULL; + mask = 1; + } + // Skip SCC + if (dev < PMGR_PS_NUM(MCU)) continue; + if ((devmask & mask) != 0) { + if (enable) devpss[dev] |= 0xF; + else devpss[dev] &= ~0xF; + + // Wait for the PS and ACTUAL_PS fields to be equal + wait_for_dev_ps_change(dev); + } + } +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + // Use WDOG pin to cause a PMU reset + gpio_configure_out(GPIO_SYSTEM_RESET, 1); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_watchdog_tickle(void) +{ + // Varies by target. This layer between is necessary so that + // we don't go straight from generic code to target. + target_watchdog_tickle(); +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + u_int32_t cnt; + u_int32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + // From 'https://soc.apple.com/bali/public/fpga/release/a0/int3c_54/int3c_54-1.4/readme.html': + // + // Clock settings: + // --------------- + // MAIN_CLK: 7 MHz (need change UART Baud-rate: mem -memap 0 0x32500028 0xc000e) + // CPU_CLK: 3.5 MHz + // MCU_CLK: 4.5 MHz + // CPM_CLK: 64 MHz + clks[PMGR_CLK_CPU] = 3500000; // CPU + clks[PMGR_CLK_MCU] = 4500000; // DDR + clks[PMGR_CLK_MCU_FIXED] = 7000000; // NCLK (MAIN) + + // XXX Why doesn't the USB clock correspond to the 30MHz + // claimed by fpga team? I'm not touching it because it + // appears to work as-is; however, I'd like to understand why + // this setting is (and has been, looking at H5P FPGA release + // notes) different from their claims. + clks[PMGR_CLK_USB_PHY0] = 12000000; // USB + + for (cnt = 0; cnt < (kDVFM_STATE_IBOOT + 1); cnt++) { + cpu_clks[cnt] = clks[PMGR_CLK_CPU]; + } + // keep compiler happy + cnt = (u_int32_t)clk_parents; + +#else + volatile u_int32_t *reg; + u_int32_t cnt, val, p, m, s, source, divider, parent_idx; + u_int32_t divider_type, divider_offset; + u_int64_t freq; + u_int8_t *managed = (u_int8_t *)perf_state_active; + + for (cnt = 0; cnt < kDVFM_STATE_COUNT; cnt++) { + // ignore DVFM states with no voltage + if ((rPMGR_DVFM_CFG1(cnt) & 0xFF) == 0) continue; + + // decode the PLL settings + val = rPMGR_DVFM_CFG0(cnt); + p = 1 + ((val >> 9) & 0x1FF); + m = 1 + ((val >> 18) & 0x1FF); + s = 1 + ((val >> 0) & 0x1FF); + + // calculate the frequency + freq = OSC_FREQ; + freq *= m; + freq /= p * s; + + // save the frequency + cpu_clks[cnt] = freq; + } + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) { + reg = clk_parents[cnt].divider_reg; + if (reg == 0) continue; + val = *reg; + + // Check if the clock in enabled + if ((val & PMGR_CLK_CFG_ENABLE) == 0) continue; + + divider_type = clk_parents[cnt].divider_type; + divider_offset = clk_parents[cnt].divider_offset; + + source = 0; + divider = 1; + + switch (divider_type) { + case 1 : // Normal with divider + divider = (val >> 0) & PMGR_CLK_CFG_DIV_MASK; + // fall through + + case 0 : // Normal without divider + source = (val >> 28) & 3; + break; + + case 3 : // Managed with divider + divider = (managed[divider_offset] >> 0) & PMGR_CLK_CFG_DIV_MASK; + // fall through + + case 2 : // Managed without divider + source = (managed[divider_offset] >> 5) & 3; + break; + } + + parent_idx = clk_parents[cnt].parents[source]; + freq = clks[parent_idx]; + + if ((cnt == PMGR_CLK_DOUBLER) && ((val & PMGR_DOUBLER_EXT_BYPASS) != 0)) + freq *= 2; + + freq /= divider; + + clks[cnt] = freq; + } +#endif +} + +static u_int32_t get_pll(int pll) +{ + u_int32_t pll_ctl0, pll_ctl1; + u_int64_t freq = 0; + + if (pll >= PMGR_PLL_COUNT) return 0; + + pll_ctl0 = rPMGR_PLL_CTL0(pll); + pll_ctl1 = rPMGR_PLL_CTL1(pll); + + if ((pll_ctl0 & PMGR_PLL_ENABLE) == 0) return 0; + + if ((pll_ctl0 & (PMGR_PLL_EXT_BYPASS | PMGR_PLL_BYPASS))) { + freq = OSC_FREQ; + } else { + freq = OSC_FREQ; + freq *= 1 + ((pll_ctl1 >> PMGR_PLL_M_SHIFT) & PMGR_PLL_MASK); // *M + freq /= 1 + ((pll_ctl1 >> PMGR_PLL_P_SHIFT) & PMGR_PLL_MASK); // /P + freq /= 1 + ((pll_ctl1 >> PMGR_PLL_S_SHIFT) & PMGR_PLL_MASK); // /S + } + + return freq; +} + +static void set_pll(int pll, u_int32_t p, u_int32_t m, u_int32_t s, u_int32_t vco) +{ + if (pll >= PMGR_PLL_COUNT) return; + + // Set the P, M & S values + rPMGR_PLL_CTL1(pll) = PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s); + + // Enable the PLL and request it load the configuration + rPMGR_PLL_CTL0(pll) = PMGR_PLL_ENABLE | PMGR_PLL_LOAD; + + // Wait for the PLL to lock + wait_for_pll_lock(pll); +} + +#endif + +void clock_reset_device(int device) +{ + volatile u_int32_t *reg = PMGR_FIRST_PS + device; + + switch (device) { + case CLK_CPU1 : + case CLK_FMI0 : + case CLK_FMI1 : + case CLK_IOP : + case CLK_MCU : + case CLK_SDIO : + *reg |= PMGR_PS_RESET; + spin(1); + *reg &= ~PMGR_PS_RESET; + break; + + default : + break; + } +} + +#if WITH_DEVICETREE + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ + u_int32_t cnt, count, propSize, perf_state_config; + u_int64_t freq, period_ns; + u_int32_t cpu_volt[kDVFM_STATE_COUNT]; + char *propName; + void *propData; + + // Get the PERF_STATE configuration generated at hardware init + perf_state_config = rPMGR_SCRATCH1; + if (perf_state_config == 0) return; + + // Fill in the firmware-v-perf-states property + propName = "firmware-v-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(u_int32_t))) { + panic("pmgr property firmware-v-perf-states is the wrong size"); + } + // Voltage states are in reverse order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(1), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_V(0), perf_state_config); + } + + // Fill in the firmware-p-perf-state property + propName = "firmware-p-perf-state"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (1 * sizeof(u_int32_t))) { + panic("pmgr property firmware-p-perf-states is the wrong size"); + } + // There is only one Frequency Managed / Performance state + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_P, perf_state_config); + } + + // Fill in the firmware-m-perf-states property + propName = "firmware-m-perf-states"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != (4 * sizeof(u_int32_t))) { + panic("pmgr property firmware-m-perf-states is the wrong size"); + } + // Memory states are in the same order + ((u_int32_t *)propData)[0] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(0), perf_state_config); + ((u_int32_t *)propData)[1] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(1), perf_state_config); + ((u_int32_t *)propData)[2] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(2), perf_state_config); + ((u_int32_t *)propData)[3] = PGMR_GET_PERF_STATE_INDEX(PMGR_PERF_STATE_M(3), perf_state_config); + } + + // Fill in the voltage-states1 property + propName = "voltage-states1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + count = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(kDVFM_STATE_COUNT, cpu_volt); + if (count > (kDVFM_STATE_COUNT - kDVFM_STATE_IBOOT)) count = kDVFM_STATE_COUNT - kDVFM_STATE_IBOOT; + for (cnt = 0; cnt < count; cnt++) { + freq = cpu_clks[kDVFM_STATE_IBOOT + cnt]; + if (freq == 0) break; + + // Calculate the period is ns as a 16.16 fixed point number + period_ns = 1000000000ULL << 16; + period_ns /= freq; + + // Save the period and voltage + ((u_int32_t *)propData)[2*cnt] = period_ns; + ((u_int32_t *)propData)[2*cnt+1] = cpu_volt[dvfm_state_active[cnt].cpu_vi]; + } + } +} + +#endif + +void init_thermal_sensors(void) +{ + // Grab the 4 bit fuse revision + u_int32_t fuseRevision = chipid_get_fuse_revision(); + + // Bits [1 - 0] PWRDN Mode and enable. + // Bits [3 - 2] Reserved. + // Bits [ 4 ] Stat mode for Avg Max on. + // Bits [18 - 5] TADC_CFG Tmpsadc configuration bits. + // Bits [31 - 19] Misc interrupt/Alarm stick bits not used. + rPMGR_THERMAL0_CTL0 = 0x000184F0; + rPMGR_THERMAL1_CTL0 = 0x000184F0; + + // Bits [15 - 0] PWRDN_START 20us wait + // Bits [31 - 16] PWRDN_GAP Gap between two readings. + rPMGR_THERMAL0_CTL1 = 0x005B01E4; + rPMGR_THERMAL1_CTL1 = 0x005B01E4; + + // Bits [7 - 0] Conv_Cycle, cycles to wait before data is valid. + // Bits [15 - 8] Enable_Cycle, cycles to wait before adc_en can be deasserted. + // Bits [23 - 16] Finish_gap, Cycles to wait before adc_en can be reasserted. + // Bits [31 - 24] Reserved. + rPMGR_THERMAL0_CTL2 = 0x00100848; + rPMGR_THERMAL1_CTL2 = 0x00100848; + + for (u_int32_t sensorID = 0; sensorID < 2; sensorID++) { + + u_int32_t fusedTempValueAt70 = chipid_get_fused_thermal_sensor_70C(sensorID); + u_int32_t fusedTempValueAt25 = chipid_get_fused_thermal_sensor_25C(sensorID); + u_int32_t tempSlope = 0x100; + + // If we read nothing from the fuse, then we need to supply some default for + // 1 pt calibration, see: + if ( (fusedTempValueAt25 == 0) && (fusedTempValueAt70 == 0) ) { + + if (sensorID) { + fusedTempValueAt25 = 29; + } else { + fusedTempValueAt25 = 20; + } + + // Forces us to generate a slope of 1.0 + fusedTempValueAt70 = fusedTempValueAt25 + 45; + } + + // Should probably make sure we don't divide by zero. + if (fusedTempValueAt25 == fusedTempValueAt70) { + fusedTempValueAt70 = 70; + fusedTempValueAt25 = 25; + dprintf(DEBUG_INFO, "Invalid soc thermal fuse values\n"); + } + + if (fuseRevision > 0) { + // 45 = 70 - 25 + tempSlope = (45*256) / (fusedTempValueAt70 - fusedTempValueAt25); + } else { + dprintf(DEBUG_INFO, "Invalid soc thermal sensor fuse revision number.\n"); + } + + // Calculate the real offset. + u_int32_t realOffset = 25 - ((tempSlope * fusedTempValueAt25) / (tempSlope==0x100 ? 1:256)); + + // Bits 23 16 + // Temp_OFFSET => [8 bit signed integer] + // Bits 9 0 + // TEMP_SLOPE => [2 bit integer| 8 bit decimal] + switch (sensorID) { + case 0: + rPMGR_THERMAL0_CTL3 = (realOffset & 0xFF) << 16; + rPMGR_THERMAL0_CTL3 |= tempSlope & 0x3FF; + break; + case 1: + rPMGR_THERMAL1_CTL3 = (realOffset & 0xFF) << 16; + rPMGR_THERMAL1_CTL3 |= tempSlope & 0x3FF; + break; + } + } +} + +static void wait_for_dev_ps_change(u_int32_t dev) +{ +//#if ! SUPPORT_FPGA + // Wait for the PS and ACTUAL_PS fields to be equal + volatile u_int32_t *devpss = PMGR_FIRST_PS; + while ((devpss[dev] & 0xF) != ((devpss[dev] >> 4) & 0xF)); +//#endif +} + +static void wait_for_pending_apsc_change(void) +{ +#if ! SUPPORT_FPGA + // Spin while the pending bit is asserted + while ((rPMGR_APSC_STA_CTL & PMGR_APSC_PENDING) != 0); +#endif +} + +static void wait_for_pending_clk_cfg_change(u_int32_t clk) +{ +#if ! SUPPORT_FPGA + // Spin while the pending bit is asserted + volatile u_int32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + while (clkcfgs[clk] & PMGR_CLK_CFG_PENDING); +#endif +} + +static void wait_for_pll_bypass_enabled(u_int32_t pll) +{ +#if ! SUPPORT_FPGA + while (!(rPMGR_PLL_DEBUG(pll) & PMGR_PLL_DEBUG_BYP_ENABLED)); +#endif +} + +static void wait_for_pll_lock(u_int32_t pll) +{ +#if ! SUPPORT_FPGA + while ((rPMGR_PLL_CTL0(pll) & PMGR_PLL_REAL_LOCK) == 0); +#endif +} + +static void wait_for_doubler_bypass_enabled(void) +{ +#if ! SUPPORT_FPGA + while (!(rPMGR_DOUBLER_DEBUG & PMGR_DOUBLER_DEBUG_BYP_ENABLED)) ; +#endif +} diff --git a/platform/s5l8955x/pmgr/rules.mk b/platform/s5l8955x/pmgr/rules.mk new file mode 100644 index 0000000..fa626c5 --- /dev/null +++ b/platform/s5l8955x/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s5l8955x/rules.mk b/platform/s5l8955x/rules.mk new file mode 100644 index 0000000..b0c7c08 --- /dev/null +++ b/platform/s5l8955x/rules.mk @@ -0,0 +1,124 @@ +# Copyright (C) 2010-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +############################################################################## +# Code running on the main CPU +# +ifeq ($(PLATFORM_VARIANT),) + +ARM_CPU := apple-swift + +# Devmap chip ID based on sub-platform identifier +ifeq ($(SUB_PLATFORM),s5l8955x) +DEVMAP_CHIP_ID := 8955 +endif + +MAX_DFU_SIZE := 393216 + +ifeq ($(TEXT_BANK),srom) +TEXT_BASE := 0x00000000 +endif +ifeq ($(TEXT_BANK),sram) +TEXT_BASE := 0x10000000 +endif +ifeq ($(TEXT_BANK),sdram) +TEXT_BASE := 0xBFF00000 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + WITH_LEGACY_PANIC_LOGS=1 \ + WITH_NO_RANDOM_HEAP_COOKIE=1 \ + WITH_NO_RANDOM_STACK_COOKIE=1 \ + WITH_NON_COHERENT_DMA=1 \ + WITH_ROM_TRAMPOLINE=1 \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=192 \ + PLATFORM_START_FUNCTION=_platform_start \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +# L2_CACHE_SIZE=1048576 \ +# + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) +# This selects the start of the DATA segment and the end of the INSECURE_MEMORY area +DATA_BASE := 0x10060000 + +OPTIONS += \ + DATA_BASE="$(DATA_BASE)" + +GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o + +endif + +############################################################################## +# Code running on the IOP +# +ifeq ($(PLATFORM_VARIANT),IOP) + +OPTIONS += \ + PLATFORM_VARIANT_IOP=1 \ + AIC_CPU_ID=2 \ + WITH_PLATFORM_HALT=1 \ + SUPPORT_SLEEP=1 \ + WITH_IOP_POWER_GATING=1 \ + DEEP_IDLE_THRESHOLD_US=10000 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o +endif + +############################################################################## +# Code running on the audio engine +# +ifeq ($(PLATFORM_VARIANT),Audio) + +OPTIONS += \ + PLATFORM_VARIANT_AUDIO=1 \ + WITH_PLATFORM_HALT=1 \ + SUPPORT_SLEEP=1 + +ARM_CPU := cortex-a5 + +TEXT_BASE := 0x0 + +OPTIONS += \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +ALL_OBJS += $(LOCAL_DIR)/iop_init.o + +endif diff --git a/platform/s5l8960x/amc/amc.c b/platform/s5l8960x/amc/amc.c new file mode 100644 index 0000000..d05f509 --- /dev/null +++ b/platform/s5l8960x/amc/amc.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + // Don't perform DRAM initializion if the memory controller is already + // initialized (e.g., for SecureROM validation testing). + if (resume || rAMC_AMCEN == 0) { + clock_gate(CLK_MCU, true); + clock_gate(CLK_MCC, true); + clock_gate(CLK_AMP, true); + + amc_init(resume); + + // Configure MCC + rMCC_MCCEN = 0x00000190; + } + + return 0; +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping(void) +{ + rAMC_ADDRCFG = 0x00020201; + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + if (AMC_NUM_RANKS > 1) + rAMC_ADDRCFG |= 0x01000000; + + rAMC_CHNLDEC = amc_get_params()->chnldec; + + rAMC_ADDRMAP_MODE = 2; // RIBI2 + + rAMC_MCSADDRBNKHASH(0) = 0x00006db6; + rAMC_MCSADDRBNKHASH(1) = 0x00005b6d; + rAMC_MCSADDRBNKHASH(2) = 0x000036db; +} + +void amc_enable_slow_boot (bool enable) +{ + if (enable) { + // switch to slow clock + clocks_set_performance(kPerformanceMemoryLow); + spin(1); + } + else { +#if !SUPPORT_FPGA + // switch back to full-speed + clocks_set_performance(kPerformanceMemoryFull); + spin(1); +#endif + } +} + +// Some AMC features to be changed before calibration starts, and restored after calibration is complete +void amc_calibration_start(bool start) +{ + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + if (start) { + // Disable OdtsRdIntrvl + rAMC_ODTS &= 0xFFFFFC00; + } else { + // Re-enable OdtsRdIntrvl + rAMC_ODTS |= amc_get_params()->odts; + } +} + + +void amc_enable_rddqcal(bool enable) +{ + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + static uint8_t lppr_freq0 = 0; + + if (enable) { + lppr_freq0 = (rAMC_AREFEN_FREQ(0) >> 16) & 1; + rAMC_AREFEN_FREQ(0) &= ~(1 << 16); + rAMC_READ_LEVELING |= 1; + } else { + rAMC_READ_LEVELING &= ~1; + rAMC_AREFEN_FREQ(0) |= (lppr_freq0 << 16); + } +} + +void amc_wrdqcal_start(bool start) +{ + if (start) { + + // Enable WriteMergeEn and WqInOrderEn + rAMC_PSQWQCTL0 = (1 << 8) | (1 << 0); + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + // Set SelfRefTmrVal to max + rAMC_PWRMNGTPARAM |= (0xFFFF << 16); + + // Designer suggests 0xBB, so that writes do not age out + rAMC_PSQWQCTL1 = 0xBB; + + } else { + rAMC_PSQWQCTL0 = 0; + rAMC_PWRMNGTPARAM = amc_get_params()->pwrmngtparam_guided; + // WqAgeOutVal has to be set to 3/4 of SelfRefTmrVal + rAMC_PSQWQCTL1 = (3 * ((amc_get_params()->pwrmngtparam_guided & 0xFFFF0000) >> 16)) >> 2; + + // Enabling clock gating and AutoSR only after wrdqcal is done + rAMC_CLKPWRGATE = 0x050a0000; + rAMC_CLKPWRGATE2 = 0x00010300; + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + rAMC_PWRMNGTEN |= 0x00011011; + } +} + +void amc_finalize (bool resume) +{ + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + rAMC_AREFPARAM |= 0x00001000; // Turn on freq change waiting for refresh and self-refresh exit + + rAMC_QBREN = 0x00110001; + + if (!resume) { + #if SUPPORT_FPGA + rAMC_ODTS = amc_get_params()->odts; + #else + rAMC_ODTS = 0x00010000 | amc_get_params()->odts; + #endif + amc_enable_autorefresh(); + } + + rAMC_ZQC = 0x010c03ff; + rAMC_QBRPARAM = 0x00030000; + rAMC_QBREN = 0x00111001; + +#if SUPPORT_FPGA + rAMC_CLKPWRGATE = 0x050a0000; + rAMC_CLKPWRGATE2 = 0x00010300; + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + rAMC_PWRMNGTEN |= 0x00000010; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + + // Alcatraz: Hynix 29nm DDR margin improvement settings for N5x/J72/J85 PRQ - iBoot + if (dev_info->rev_id == 2 && ((dev_info->rev_id2 == 0) || (dev_info->rev_id2 == 1) || (dev_info->rev_id2 == 2))) { + if (!resume) { + // Test MRS Exit + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + + // Test MRS Entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + + // DCD -13ps + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb4); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x94); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x86); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x83); + + // DCD +35ps + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb4); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xba); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x83); + + // Duty Control: 49% + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb4); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x84); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x86); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x83); + } + } + if (dev_info->rev_id == 1 && dev_info->rev_id2 == 0) { + if (!resume) { + + // TestMRS Exit + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x00); + + // TestMRS entry + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xb0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + + // + // DCD -13ps + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x87); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xc0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x90); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + + // DCD +35ps + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xbb); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xc0); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x8c); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + + // DS up: 10% + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x8f); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x94); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xe0); + } + } + break; + + case JEDEC_MANUF_ID_ELPIDA: + + if (dev_info->rev_id == 2 && ((dev_info->rev_id2 == 0) || (dev_info->rev_id2 == 1) || (dev_info->rev_id2 == 2))) { + if (!resume) { + // Elpida has no TestMRS entry/exit cmd + // Alcatraz: Elpida 25nm DRAM read DQS DCD improvement for N5x/J72/J85 PRQ - iBoot + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xbb); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x27); + } + } + if (dev_info->rev_id == 0 && dev_info->rev_id2 == 0) { + if (!resume) { + // Elpida has no TestMRS entry/exit cmd + // Elpida 38nm needs duty cycle adjustment + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xbb); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x03); + } + } + break; + + default: + break; + } + + return; +} + +// Shift dq offset (for rd and wr) as needed +void amc_dram_shift_dq_offset (int8_t *dq_offset, uint8_t num_bytes) { + int8_t shift_val; + uint8_t i; + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + // shift for each vendor defined in platform amcconfig (for PoP) or target amcconfig (for Discrete) + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + shift_val = amc_get_params()->offset_shift_hynix; + break; + + case JEDEC_MANUF_ID_ELPIDA: + // shift 1 step to the negative side + shift_val = amc_get_params()->offset_shift_elpida; + +#if SUB_TARGET_J71 || SUB_TARGET_J72 || SUB_TARGET_J73 + if (dev_info->rev_id == 2 && (dev_info->rev_id2 <= 2)) + shift_val = amc_get_params()->offset_shift_elpida25nm; +#endif + break; + + default: + shift_val = 0; + break; + } + + // "num_bytes" is actually size of the array, which is number of bits in this case (32) + for (i = 0; i < num_bytes; i++) + dq_offset[i] += shift_val; +} diff --git a/platform/s5l8960x/amc/rules.mk b/platform/s5l8960x/amc/rules.mk new file mode 100644 index 0000000..36a6843 --- /dev/null +++ b/platform/s5l8960x/amc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AMC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/amc.o diff --git a/platform/s5l8960x/asm.S b/platform/s5l8960x/asm.S new file mode 100644 index 0000000..e5c054b --- /dev/null +++ b/platform/s5l8960x/asm.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + .text + .align 2 + .globl _platform_start +_platform_start: + //////////////////////////////////////////////// + // Must preserve X0 and X1 + //////////////////////////////////////////////// + + // Disable RSS non-speculative streaming: + // Do this as early as possible is it can cause incorrect SPR writes. + mrs x2, s3_0_c15_c1_0 // HID1 + orr x2, x2, #(1<<2) // rssDisNsStreaming + msr s3_0_c15_c1_0, x2 // HID1 + isb + + // Enable the L2 cache load/store prefetcher on B0 (and later): + mrs x2, s3_0_c15_c5_0 // HID5 + and x2, x2, #~(3<<44) // B0+: Enable L2C load (bit 44)/store (bit 45) prefetch + msr s3_0_c15_c5_0, x2 // HID5 + isb + ret + + + .align 2 + .globl _platform_halt +_platform_halt: + + // For Cyclone, we must disable the MTLB prefetcher before doing WFI. + // iBoot: implement Cyclone/Typhoon WFI workaround + + mrs x1, s3_0_c15_c2_0 // Read HID2 + orr x0, x1, #(1 << 13) // Set HID2.DisableMTLBPrefetch + msr s3_0_c15_c2_0, x0 // Write HID2 + dsb sy + isb sy + + wfi + + // Re-enable MTLB prefetcher after WFI falls through. + msr s3_0_c15_c2_0, x1 // Restore HID2 + dsb sy + isb sy + + ret + diff --git a/platform/s5l8960x/chipid/chipid.c b/platform/s5l8960x/chipid/chipid.c new file mode 100644 index 0000000..ed09ba4 --- /dev/null +++ b/platform/s5l8960x/chipid/chipid.c @@ -0,0 +1,478 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +#if SUB_PLATFORM_S5L8960X +#define MINIMUM_BINNING_VERSION 1 + +#if SUB_TARGET_N51 || SUB_TARGET_N53 || SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 || SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + +#define DEFAULT_CPU_VOLTAGE_BYPASS 1137 +#define DEFAULT_CPU_VOLTAGE_SECUREROM 1137 +#define DEFAULT_CPU_VOLTAGE_V0 800 +#define DEFAULT_CPU_VOLTAGE_V1 862 +#define DEFAULT_CPU_VOLTAGE_V2 987 +#define DEFAULT_CPU_VOLTAGE_V3 1137 +#define DEFAULT_CPU_VOLTAGE_V4 1200 + +#define BASE_CPU_VOLTAGE_BYPASS 1137 +#define BASE_CPU_VOLTAGE_SECUREROM 1137 +#define BASE_CPU_VOLTAGE_V0 800 +#define BASE_CPU_VOLTAGE_V1 862 +#define BASE_CPU_VOLTAGE_V2 987 +#define BASE_CPU_VOLTAGE_V3 1137 +#define BASE_CPU_VOLTAGE_V4 1200 + +#define DEFAULT_SOC_VOLTAGE 1000 +#define DEFAULT_SRAM_VOLTAGE 1000 + +#if SUB_TARGET_N51 || SUB_TARGET_N53 +// For fuse rev < 3 we don't use higher operating points. +#define SAFE_CPU_VOLTAGE_BYPASS 875 +#define SAFE_CPU_VOLTAGE_SECUREROM 875 +#define SAFE_CPU_VOLTAGE_V0 825 +#define SAFE_CPU_VOLTAGE_V1 865 +#define SAFE_CPU_VOLTAGE_V2 865 +#define SAFE_CPU_VOLTAGE_V3 875 +#define SAFE_CPU_VOLTAGE_V4 950 +#endif + +#elif SUB_TARGET_J34 || SUB_TARGET_J34M || SUB_TARGET_J71 || SUB_TARGET_J72 || SUB_TARGET_J73 + +#define DEFAULT_CPU_VOLTAGE_BYPASS 1137 +#define DEFAULT_CPU_VOLTAGE_SECUREROM 1137 +#define DEFAULT_CPU_VOLTAGE_V0 862 +#define DEFAULT_CPU_VOLTAGE_V1 987 +#define DEFAULT_CPU_VOLTAGE_V2 1137 +#define DEFAULT_CPU_VOLTAGE_V3 1200 +#define DEFAULT_CPU_VOLTAGE_V4 1237 + +#define BASE_CPU_VOLTAGE_BYPASS 1137 +#define BASE_CPU_VOLTAGE_SECUREROM 1137 +#define BASE_CPU_VOLTAGE_V0 862 +#define BASE_CPU_VOLTAGE_V1 987 +#define BASE_CPU_VOLTAGE_V2 1137 +#define BASE_CPU_VOLTAGE_V3 1200 +#define BASE_CPU_VOLTAGE_V4 1237 + +#define DEFAULT_SOC_VOLTAGE 1000 +#define DEFAULT_SRAM_VOLTAGE 1050 + +#else + +#define DEFAULT_CPU_VOLTAGE_BYPASS 875 +#define DEFAULT_CPU_VOLTAGE_SECUREROM 875 +#define DEFAULT_CPU_VOLTAGE_V0 825 +#define DEFAULT_CPU_VOLTAGE_V1 865 +#define DEFAULT_CPU_VOLTAGE_V2 875 +#define DEFAULT_CPU_VOLTAGE_V3 950 + +#define BASE_CPU_VOLTAGE_BYPASS 875 +#define BASE_CPU_VOLTAGE_SECUREROM 875 +#define BASE_CPU_VOLTAGE_V0 825 +#define BASE_CPU_VOLTAGE_V1 865 +#define BASE_CPU_VOLTAGE_V2 875 +#define BASE_CPU_VOLTAGE_V3 950 + +#define DEFAULT_SOC_VOLTAGE 1000 +#define DEFAULT_SRAM_VOLTAGE 1000 + +#endif + + +// GPU voltages in mV. +static uint32_t default_gpu_voltages[kPMGR_GFX_STATE_MAX] = { 0, 950, 1000, 1100, 950, 1000, 1100, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +#endif + +// CCC_PWRCTL_EFUSE_DVFM0.Revision should be the only +// binning rev info for all the binned rails. (rev id starting from 0) +// If CCC_PWRCTL_EFUSE_DVFM0 is 0, we can safely assume that +// this is an unbinned part. +static uint32_t chipid_get_binning_revision(void) +{ + if (rCCC_EFUSE_DVFM(0) == 0) { + return 0; + } else { + // Add 1 to distinguish against an unbinned part. + return ((rCCC_EFUSE_DVFM(0) >> 29) & 0x7) + 1; + } +} + +// (Base Fuse + 1) * 25 +static uint32_t chipid_get_basevoltage(void) +{ + return (((rCCC_EFUSE_DVFM(0) >> 24) & 0x1F) + 1) * 25; +} + +// Here are the mappings for operating points to modes. +// Mode 9: 1392 MHz. (V4 for Discrete and only in Discrete). +// Mode 7: 1296 MHz. (V3 for Discrete, V4 for POP). +// Mode 4: 1128 MHz. (V2 for Discrete, V3 for POP). +// Mode 2: 840 MHz. (V1 for Discrete, V2 for POP). +// Mode 1: 600 MHz. (V0 for Discrete, V1 for POP). +// Mode 5: 396 MHz. (V0 for POP and only in POP). + +static uint32_t get_ccc_mode_for_index(uint32_t volt_index) +{ + static uint32_t v2m[] = { +#if SUB_TARGET_N51 || SUB_TARGET_N53 || SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 || SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + [CHIPID_CPU_VOLTAGE_BYPASS] = 5, + [CHIPID_CPU_VOLTAGE_V0] = 5, + [CHIPID_CPU_VOLTAGE_V1] = 1, + [CHIPID_CPU_VOLTAGE_V2] = 2, + [CHIPID_CPU_VOLTAGE_V3] = 4, + [CHIPID_CPU_VOLTAGE_V4] = 7, +#elif SUB_TARGET_J34 || SUB_TARGET_J34M || SUB_TARGET_J71 || SUB_TARGET_J72 || SUB_TARGET_J73 + [CHIPID_CPU_VOLTAGE_BYPASS] = 1, + [CHIPID_CPU_VOLTAGE_V0] = 1, + [CHIPID_CPU_VOLTAGE_V1] = 2, + [CHIPID_CPU_VOLTAGE_V2] = 4, + [CHIPID_CPU_VOLTAGE_V3] = 7, + [CHIPID_CPU_VOLTAGE_V4] = 9, +#else // By default we will fall back to Jx configuration. + [CHIPID_CPU_VOLTAGE_BYPASS] = 1, + [CHIPID_CPU_VOLTAGE_V0] = 1, + [CHIPID_CPU_VOLTAGE_V1] = 2, + [CHIPID_CPU_VOLTAGE_V2] = 4, + [CHIPID_CPU_VOLTAGE_V3] = 7, + [CHIPID_CPU_VOLTAGE_V4] = 9, +#endif + }; + + return v2m[volt_index]; +} + +static uint32_t get_ccc_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse = 0; + + switch(mode) { + case 9: + binfuse = (rCCC_EFUSE_DVFM(1) >> 25); + break; + case 7: + binfuse = (rCCC_EFUSE_DVFM(1) >> 18); + break; + case 4: + binfuse = (rCCC_EFUSE_DVFM(1) >> 11); + break; + case 2: + binfuse = ((rCCC_EFUSE_DVFM(0) >> 21) & 0x7) | + (((rCCC_EFUSE_DVFM(1) >> 0) & 0xF) << 3); + break; + case 1: + binfuse = (rCCC_EFUSE_DVFM(0) >> 14); + break; + case 5: + binfuse = (rCCC_EFUSE_DVFM(0) >> 0); + break; + } + + return (binfuse & 0x7F); +} + +static uint32_t get_ccc_bin_voltage(uint32_t volt_index) +{ + uint32_t mode = 0, binfuse = 0; + // We will never transition to SECUREROM state + // during normal operation. + // So, for completeness return the default + // voltage value for SecureROM. + if (volt_index == DEFAULT_CPU_VOLTAGE_SECUREROM) + return DEFAULT_CPU_VOLTAGE_SECUREROM; + + uint32_t base_cpu_voltage = chipid_get_basevoltage(); + + mode = get_ccc_mode_for_index(volt_index); + binfuse = get_ccc_binfuse_for_mode(mode); + + return (base_cpu_voltage + binfuse * 5); + +} + +static uint32_t get_soc_binfuse(void) +{ + uint32_t binfuse = 0; + binfuse = (rCFG_FUSE1 >> 21); + + return (binfuse & 0x7F); +} + +static uint32_t get_soc_bin_voltage(void) +{ + uint32_t binfuse = 0; + uint32_t base_soc_voltage = chipid_get_basevoltage(); + + binfuse = get_soc_binfuse(); + + return (base_soc_voltage + binfuse * 5); +} + +static uint32_t get_gpu_binfuse(uint32_t volt_index) +{ + uint32_t binfuse = 0, index = 0; + + // voltages at indices 1,2,3 are repeated for 4,5,6 + index = (volt_index - 1) % 3; + + binfuse = rCFG_FUSE1 >> (index * 7); + + return (binfuse & 0x7F); +} + +static uint32_t get_gpu_bin_voltage(uint32_t volt_index) +{ + uint32_t binfuse = 0; + + uint32_t base_gpu_voltage; + + // For the OFF mode and unused entries we should + // return 0. + if (default_gpu_voltages[volt_index] == 0) + return 0; + + base_gpu_voltage = chipid_get_basevoltage(); + binfuse = get_gpu_binfuse(volt_index); + + return (base_gpu_voltage + binfuse * 5); +} + +bool chipid_get_current_production_mode(void) +{ + return ((rCFG_FUSE0 >> 0) & 1) != 0; +} + +bool chipid_get_raw_production_mode(void) +{ + return ((rCFG_FUSE0_RAW >> 0) & 1) != 0; +} + +void chipid_clear_production_mode(void) +{ + rCFG_FUSE0 &= ~1; +} + +bool chipid_get_secure_mode(void) +{ + // demotion only applies to the SEP, so iBoot always reads + // the raw value for secure mode () + return ((rCFG_FUSE0_RAW >> 1) & 1) != 0; +} + +uint32_t chipid_get_security_domain(void) +{ + return (rCFG_FUSE0 >> 2) & 3; +} + +uint32_t chipid_get_board_id(void) +{ + return (rCFG_FUSE0 >> 4) & 3; +} + +uint32_t chipid_get_minimum_epoch(void) +{ + return (rCFG_FUSE0 >> 9) & 0x7F; +} + +uint32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_S5L8960X + return 0x8960; +#endif +} + +uint32_t chipid_get_chip_revision(void) +{ + return (((rCFG_FUSE0 >> 25) & 0x7) << 4) | (((rCFG_FUSE0 >> 22) & 0x7) << 0); +} + +uint32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +uint64_t chipid_get_ecid_id(void) +{ +#if SUPPORT_FPGA + return (0x000012345678ABCDULL); +#else + return ((uint64_t)rECIDHI << 32) | rECIDLO; +#endif +} + +uint64_t chipid_get_die_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint32_t chipid_get_soc_voltage(uint32_t index) +{ + uint32_t soc_voltage = 0; + + if (chipid_get_binning_revision() < MINIMUM_BINNING_VERSION) { + return DEFAULT_SOC_VOLTAGE; + } else { + soc_voltage = get_soc_bin_voltage(); + } + + return soc_voltage; +} + +uint32_t chipid_get_cpu_voltage(uint32_t index) +{ + uint32_t cpu_voltage = 0; + + if (chipid_get_binning_revision() < MINIMUM_BINNING_VERSION) { + switch(index) { + case CHIPID_CPU_VOLTAGE_BYPASS: + cpu_voltage = DEFAULT_CPU_VOLTAGE_BYPASS; + break; + case CHIPID_CPU_VOLTAGE_SECUREROM: + cpu_voltage = DEFAULT_CPU_VOLTAGE_SECUREROM; + break; + case CHIPID_CPU_VOLTAGE_V0: + cpu_voltage = DEFAULT_CPU_VOLTAGE_V0; + break; + case CHIPID_CPU_VOLTAGE_V1: + cpu_voltage = DEFAULT_CPU_VOLTAGE_V1; + break; + case CHIPID_CPU_VOLTAGE_V2: + cpu_voltage = DEFAULT_CPU_VOLTAGE_V2; + break; + case CHIPID_CPU_VOLTAGE_V3: + cpu_voltage = DEFAULT_CPU_VOLTAGE_V3; + break; +#if SUB_TARGET_N51 || SUB_TARGET_N53 || SUB_TARGET_J34 || SUB_TARGET_J34M || SUB_TARGET_J71 || SUB_TARGET_J72 || SUB_TARGET_J73 || SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 || SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + case CHIPID_CPU_VOLTAGE_V4: + cpu_voltage = DEFAULT_CPU_VOLTAGE_V4; + break; +#endif + } + } else { + cpu_voltage = get_ccc_bin_voltage(index); + } + + return cpu_voltage; +} + + +uint32_t chipid_get_ram_voltage(uint32_t index) +{ + return DEFAULT_SRAM_VOLTAGE; +} + +uint32_t chipid_get_gpu_voltage(uint32_t index) +{ + uint32_t gpu_voltage = 0; + + if (index >= kPMGR_GFX_STATE_MAX) return 0; + + if (chipid_get_binning_revision() < MINIMUM_BINNING_VERSION) { + // Unbinned part. Use default voltage. + gpu_voltage = default_gpu_voltages[index]; + } else { + gpu_voltage = get_gpu_bin_voltage(index); + } + + return gpu_voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return (rCFG_FUSE1 & (1 << 31)) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) rCFG_FUSE1 |= (1 << 31); +} + +bool chipid_valid_thermal_sensor_cal_data_expected(void) +{ +#if SUPPORT_FPGA + return false; +#else + return true; +#endif +} + +uint32_t chipid_get_fused_pmgr_thermal_sensor_cal(uint32_t sensorID, uint32_t bit_offset) +{ + uint32_t temp_cal = 0; + switch (sensorID) { + case 0: temp_cal = (rCFG_FUSE2 >> bit_offset) & 0x1FF; break; + case 1: temp_cal = (rCFG_FUSE3 >> bit_offset) & 0x1FF; break; + default: break; + } + return temp_cal; +} + +uint32_t chipid_get_fused_ccc_thermal_sensor_cal(uint32_t sensorID, uint32_t bit_offset) +{ + uint32_t temp_cal = 0; + switch (sensorID) { + case 0: temp_cal = (rCCC_THEM_EFUSE_TADC0 >> bit_offset) & 0x1FF; break; + case 1: temp_cal = (rCCC_THEM_EFUSE_TADC1 >> bit_offset) & 0x1FF; break; + default: break; + } + return temp_cal; +} + +uint32_t chipid_get_fused_pmgr_thermal_sensor_cal_70C(uint32_t sensorID) +{ + return chipid_get_fused_pmgr_thermal_sensor_cal(sensorID, 9); +} + +uint32_t chipid_get_fused_pmgr_thermal_sensor_cal_25C(uint32_t sensorID) +{ + return chipid_get_fused_pmgr_thermal_sensor_cal(sensorID, 0); +} + +uint32_t chipid_get_fused_ccc_thermal_sensor_cal_70C(uint32_t sensorID) +{ + return chipid_get_fused_ccc_thermal_sensor_cal(sensorID, 9); +} + +uint32_t chipid_get_fused_ccc_thermal_sensor_cal_25C(uint32_t sensorID) +{ + return chipid_get_fused_ccc_thermal_sensor_cal(sensorID, 0); +} + +uint32_t chipid_get_fuse_revision(void) +{ + return (rCFG_FUSE0 >> 18) & 0xf; +} + +uint32_t chipid_get_total_rails_leakage() +{ + // + // Refer to following for details: + // - N51 MLB leakage sort + // - Alcatraz Test Plan document + // + uint32_t total_leakage; + uint32_t leakage_data0; + uint8_t leakage_data1; + + leakage_data0 = rCFG_FUSE5; + leakage_data1 = (rCFG_FUSE4 >> 31) & 1; + + total_leakage = ((leakage_data0 >> 28) & 0xf) + 1; // soc_sram: cfg_fuse4[31:28] + total_leakage += ((leakage_data0 >> 24) & 0xf) + 1; // cpu_sram: cfg_fuse4[27:24] + total_leakage += ((leakage_data0 >> 16) & 0xff) + 1; // gpu: cfg_fuse4[23:16] + total_leakage += ((leakage_data0 >> 8) & 0xff) + 1; // soc: cfg_fuse4[15:8] + total_leakage += ((((leakage_data0 >> 0) & 0xff) << 1) | leakage_data1) + 1; // cpu: cfg_fuse4[7:0], cfg_fuse4[31] + + return total_leakage; +} diff --git a/platform/s5l8960x/chipid/rules.mk b/platform/s5l8960x/chipid/rules.mk new file mode 100644 index 0000000..3d20871 --- /dev/null +++ b/platform/s5l8960x/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/s5l8960x/error_handler/error_handler.c b/platform/s5l8960x/error_handler/error_handler.c new file mode 100644 index 0000000..671fb39 --- /dev/null +++ b/platform/s5l8960x/error_handler/error_handler.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Enables all errors (the remaining bits are perf counters) +#define AMC_IRERRDBG_INTEN_ALLERRORS ((1<<20) |\ + (1<<19)|(1<<17)|(1<<16)|(1<<15)| \ + (1<<14)|(1<<13)) + +// INTSTATUS and IERRDBG bit positions are different. +#define AMC_INTSTATUS_ALLERRORS \ + ((1<<25)|(1<<24)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)) + +#define CP_COM_NORM_MSK_CLR_ALL (0xFFFFFFFF) +#define CP_COM_NORM_MSK_ILLEGAL_COH_INTS ((1<<0) | (1<<14)) + + +static void amc_int_handler(void* arg); +static void cp_int_handler(void *arg); + + +static void enable_cp_checks() +{ + install_int_handler(INT_COHERENCE_PNT_ERR, cp_int_handler, NULL); + if (chipid_get_chip_revision() < 0x10) { + // Alcatraz A0 errata causes spurious illegal coherent access errors + rCP_COM_INT_NORM_MASK_CLR = (CP_COM_NORM_MSK_CLR_ALL & ~CP_COM_NORM_MSK_ILLEGAL_COH_INTS); + rCP_COM_INT_NORM_MASK_SET = CP_COM_NORM_MSK_ILLEGAL_COH_INTS; + } + else + { + rCP_COM_INT_NORM_MASK_CLR = CP_COM_NORM_MSK_CLR_ALL; + } + unmask_int(INT_COHERENCE_PNT_ERR); +} +static void enable_amc_checks() +{ + install_int_handler(INT_MEM_CONTROLLER, amc_int_handler, NULL); + rAMC_INTEN = AMC_IRERRDBG_INTEN_ALLERRORS; + if(rAMC_INTSTATUS & AMC_INTSTATUS_ALLERRORS) { + // AMC Interrupts, unlike the CP ones, don't seem to stick. If an error already exists + // this early in bootup, we won't get an interrupt upon unmask. + amc_int_handler(NULL); + } + rAMC_INTSTATUS = AMC_INTSTATUS_ALLERRORS; + unmask_int(INT_MEM_CONTROLLER); +} +void platform_enable_error_handler() { + + enable_amc_checks(); + enable_cp_checks(); +} + +static void amc_int_handler(void *arg) +{ + (void)arg; + panic("Received unexpected AMC error. AMC_IERRDBG_INTSTATUS = 0x%x\n", rAMC_INTSTATUS); +} + +static void cp_int_handler(void *arg) { + (void)arg; + panic("Received unexpected Coherency Point error. CP_COM_INT_NORM_REQUEST = 0x%x\n", rCP_COM_INT_NORM_REQUEST); +} diff --git a/platform/s5l8960x/error_handler/rules.mk b/platform/s5l8960x/error_handler/rules.mk new file mode 100644 index 0000000..fac279d --- /dev/null +++ b/platform/s5l8960x/error_handler/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PLATFORM_ERROR_HANDLER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/error_handler.o diff --git a/platform/s5l8960x/include/platform/amcconfig.h b/platform/s5l8960x/include/platform/amcconfig.h new file mode 100644 index 0000000..179716f --- /dev/null +++ b/platform/s5l8960x/include/platform/amcconfig.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_ZQCL), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00020000, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 10, + .phywrlat = 2, + .pdn = 0x22000403, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .derate = 0x2483135b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x00000021, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00050000, + .aref_freq0 = 0x00000110, + .schen_default = 0x00000110, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x02, + .pwrmngten_default = 0x00100100, + .mcphyupdate1 = 0x00000001, + .odts = 0x190, + .readleveling = 0x00000300, + .offset_shift_hynix = -2, + .offset_shift_elpida = -1, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + .mifcassch = 0x00000110, + .arefparam = 0x0c022131, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 50MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001728 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQBRST, 0x04100410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOS, 0x00001919 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +}; +#endif diff --git a/platform/s5l8960x/include/platform/ampconfig.h b/platform/s5l8960x/include/platform/ampconfig.h new file mode 100644 index 0000000..9d8cbe0 --- /dev/null +++ b/platform/s5l8960x/include/platform/ampconfig.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amp/amp.h, and this + * file should only by included from that amp.c. + */ + +#if WITH_TARGET_AMP_PARAMS +#include +#else +static struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x0102050f, + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x21020509, + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x41020506, + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61020504, + }, + }, + .drive_strength = 0x14141414, + .cacalib_hw_loops = 8, + .cacalib_sw_loops = 8, +}; +#endif diff --git a/platform/s5l8960x/include/platform/error_handler.h b/platform/s5l8960x/include/platform/error_handler.h new file mode 100644 index 0000000..9a938a5 --- /dev/null +++ b/platform/s5l8960x/include/platform/error_handler.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_ERROR_HANDLER_H +#define __PLATFORM_ERROR_HANDLER_H + + +void platform_enable_error_handler(); + + +#endif // __PLATFORM_ERROR_HANDLER_H diff --git a/platform/s5l8960x/include/platform/gpiodef.h b/platform/s5l8960x/include/platform/gpiodef.h new file mode 100644 index 0000000..80380cf --- /dev/null +++ b/platform/s5l8960x/include/platform/gpiodef.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* S5L8960X specific gpio -> pin mappings */ + +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_BOARD_ID0 GPIO( 9, 0) +#define GPIO_BOARD_ID1 GPIO( 9, 1) +#define GPIO_BOARD_ID2 GPIO( 9, 2) +#define GPIO_BOARD_ID3 GPIO( 2, 2) + +#define GPIO_BOOT_CONFIG0 GPIO( 2, 4) +#define GPIO_BOOT_CONFIG1 GPIO(13, 1) +#define GPIO_BOOT_CONFIG2 GPIO(13, 4) +#define GPIO_BOOT_CONFIG3 GPIO(13, 5) + +#define GPIO_REQUEST_DFU1 GPIO( 0, 3) // formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 0, 2) // formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO(13, 2) +#define GPIO_DFU_STATUS GPIO(13, 3) + +#define SPI_NOR0 (0) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#else +#define GPIO_SPI0_CS GPIO( 9, 3) +#endif + +#define GPIO_IIC0_SCL GPIO(10, 1) +#define GPIO_IIC0_SDA GPIO(10, 0) +#define GPIO_IIC1_SCL GPIO(10, 3) +#define GPIO_IIC1_SDA GPIO(10, 2) +#define GPIO_IIC2_SCL GPIO(12, 5) +#define GPIO_IIC2_SDA GPIO(12, 4) +#define GPIO_IIC3_SCL GPIO(21, 4) +#define GPIO_IIC3_SDA GPIO(21, 3) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s5l8960x/include/platform/image_devices.h b/platform/s5l8960x/include/platform/image_devices.h new file mode 100644 index 0000000..375c347 --- /dev/null +++ b/platform/s5l8960x/include/platform/image_devices.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_HW_ASP) + { "asp_fw", 0x00000 } +#elif defined(WITH_ANC_FIRMWARE) + { "anc_firmware", 0x00000 } +#elif defined(WITH_NAND_BOOT) + { "nand_firmware", 0x00000 } +#elif defined(WITH_SW_H2FMI) + { "sw-h2fmi", 0x0000 } +#else + { "nor0", 0x00000 } +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s5l8960x/include/platform/memconfig.h b/platform/s5l8960x/include/platform/memconfig.h new file mode 100644 index 0000000..b76f0d4 --- /dev/null +++ b/platform/s5l8960x/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* S5L8960X SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/s5l8960x/include/platform/memmap.h b/platform/s5l8960x/include/platform/memmap.h new file mode 100644 index 0000000..6fb1991 --- /dev/null +++ b/platform/s5l8960x/include/platform/memmap.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* S5L8960X specific memory map */ + +/////////////////////////////////////////////////////////////////////////////////// +// 0x800000000 + dram_size ------------------------------- +// | ASP (8MiB) | +// |-----------------------------| +// | TZ1 (1MiB) | +// ------------------------------- +// | Consistent Debug (4KiB) | +// |-----------------------------| +// | Sleep Token Buffer (4KiB) | +// |-----------------------------| +// | Panic (512KiB) | +// |-----------------------------| +// | Display | +// | (Framebuffer + scratch) | +// | | +// | | +// |-----------------------------| +// | | +// | iBoot (Heap) | +// | (Variable size depending | +// | on DISPLAY_SIZE) | +// 0x830180000 --> |-----------------------------| +// | iBoot (Stacks) | +// | (STACKS_SIZE) | +// 0x83017C000 --> |-----------------------------| +// | iBoot (Page Tables) | +// | (PAGE_TABLES_SIZE) | +// 0x830100000 --> |-----------------------------| +// | iBoot (Text + Data) | +// | (TEXT_FOOTPRINT) | +// 0x830000000 --> |-----------------------------| <-- 0x800000000 + dram_size - 256MB +// | | +// | Unused | +// | | +// |-----------------------------| +// | | +// | (Ramdisk) | +// | (Kernel + DeviceTree) | +// | Secure memory | +// | | +// |-----------------------------| +// | | +// | Load region / | +// | Insecure Memory | +// | (overlaps with TZ0) | |-----------------------------| +// | | | TZ0 (varies) | +// 0x800000000 --> ------------------------------- ------------------------------- + +/////////////////////////////////////////////////////////////////////////////////// + +#define SDRAM_BASE (0x800000000ULL) +#define SDRAM_BANK_LEN (SDRAM_LEN) +#define SDRAM_BANK_COUNT (1) +#define SDRAM_END (SDRAM_BASE + SDRAM_LEN) + +// We'll map the DRAM uncached at the end of the cached mapping +#define SDRAM_BASE_UNCACHED (SDRAM_END) + +#define VROM_BASE (0x100000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00080000ULL) +#define VROM_RSVD (0x00100000ULL) // 512 KiB reserved for SecureROM testing, remaining 512 KiB for Data and book-keeping +#define SRAM_BASE (0x180000000ULL) +#define SRAM_LEN (0x000400000ULL) // 4 MiB +#define SRAM_BANK_LEN (SRAM_LEN) +#define SRAM_BANK_COUNT (1) +#define SRAM_END (SRAM_BASE + SRAM_LEN) + +#define IO_BASE (0x200000000ULL) +#define IO_SIZE (0x10000000ULL) + +#define SECUREROM_LOAD_ADDRESS (VROM_BASE) + +/* reserved for ASP */ +// NOTE ASP_SIZE is now defined by the platform or target makefile. +#define ASP_BASE (SDRAM_END - (ASP_SIZE)) + +// Reserved for TZ1/AP Monitor +#define TZ1_SIZE (0x00100000ULL) +#define TZ1_BASE (ASP_BASE - TZ1_SIZE) + +#define CONSISTENT_DEBUG_SIZE (0x00004000ULL) +#define CONSISTENT_DEBUG_BASE (TZ1_BASE - CONSISTENT_DEBUG_SIZE) + +/* reserved area for sleep token info */ +#define SLEEP_TOKEN_BUFFER_SIZE (0x00001000ULL) +#define SLEEP_TOKEN_BUFFER_BASE (CONSISTENT_DEBUG_BASE - SLEEP_TOKEN_BUFFER_SIZE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00080000ULL) +#define PANIC_BASE (SLEEP_TOKEN_BUFFER_BASE - PANIC_SIZE) + +/* reserved area for display */ +// DISPLAY_SIZE comes from platform's rules.mk +#define DISPLAY_BASE (PANIC_BASE - DISPLAY_SIZE) + +// Reserved for TZ0/SEP +// TZ0_SIZE is defined by the platform or target makefile +#define TZ0_BASE (SDRAM_BASE) + +/* where to stick heap and insecure memory */ +#if APPLICATION_SECUREROM + +#define DATA_SIZE (0x00040000ULL) + +#define BOOK_KEEPING_BASE (DATA_BASE + DATA_SIZE) +#define BOOK_KEEPING_SIZE (0x00020000ULL) + +#define BOOT_TRAMPOLINE_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define BOOT_TRAMPOLINE_SIZE (0x1000ULL) + +#define HEAP_BASE (SRAM_BASE + VROM_RSVD) +#if !SUPPORT_FPGA +#define HEAP_SIZE (0x00100000ULL) +#else +#define HEAP_SIZE (0x00080000ULL) +#endif +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#define INSECURE_MEMORY_SIZE (0x00080000ULL) +#define INSECURE_MEMORY_BASE (SRAM_BASE + SRAM_LEN - INSECURE_MEMORY_SIZE) + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT + +#if WITH_DFU_MODE +/* LLB, iBSS DFU */ + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x01400000ULL) +#define IBOOT_BASE (DISPLAY_BASE - IBOOT_SIZE) + +#define INSECURE_MEMORY_SIZE (IBOOT_SIZE) +#define INSECURE_MEMORY_BASE (IBOOT_BASE) + +// SRAM memory map will usually look like the following: +// +// ROM Testing 0x000000 - 0x100000 (1024 KiB) +// Heap 0x100000 - 0x1FEFFF (1020 KiB) +// Guard 0x1FF000 - 0x1FFFFF ( 4 KiB) +// Unused 0x200000 - 0x37FFFF (1536 KiB) +// Code/Data 0x380000 - 0x3DFFFF ( 384 KiB) +// Page Tables 0x3E0000 - 0x3FBFFF ( 112 KiB) +// Stacks 0x3FC000 - 0x3FFFFF ( 16 KiB) + +#define HEAP_BASE (SRAM_BASE + VROM_RSVD) +#if !SUPPORT_FPGA +#define HEAP_SIZE (0x00100000ULL - PAGE_SIZE) +#else +#define HEAP_SIZE (0x00080000ULL - PAGE_SIZE) +#endif +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) + +#define PAGE_TABLES_BASE (TEXT_BASE + TEXT_FOOTPRINT) +#define PAGE_TABLES_SIZE (STACKS_BASE - PAGE_TABLES_BASE) +#define STACKS_BASE (SRAM_BASE + SRAM_LEN - STACKS_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) + +#else /* !WITH_DFU_MODE */ + +/* iBoot, iBEC */ + +// SDRAM memory map will usually look like the following: +// +// iBoot Text 0x830000000 - 0x8300FFFFF ( 1 MiB) +// Page Tables 0x830100000 - 0x83017AFFF (492 KiB) +// Stacks 0x83017B000 - 0x83017EFFF ( 16 KiB) +// Boot trampoline 0x83017F000 - 0x83017FFFF ( 4 KiB) +// Heap 0x830180000 - (DISPLAY_BASE - 1 page) +// Guard (DISPLAY_BASE - 1 page) - DISPLAY_BASE + +/* reserved area for iBoot */ +#define IBOOT_BASE (TEXT_BASE) +#define IBOOT_SIZE (HEAP_END - IBOOT_BASE) + +#define PAGE_TABLES_BASE (IBOOT_BASE + TEXT_FOOTPRINT) +#define PAGE_TABLES_SIZE (0x0007B000ULL) +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) +#define BOOT_TRAMPOLINE_BASE (STACKS_BASE + STACKS_SIZE) +#define BOOT_TRAMPOLINE_SIZE (PAGE_SIZE) + +#define HEAP_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define HEAP_SIZE (DISPLAY_BASE - HEAP_BASE - PAGE_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) +#if (HEAP_GUARD != (DISPLAY_BASE - PAGE_SIZE)) +#error "Memory map configuration error" +#endif + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_LOAD_SIZE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define SECURE_MEMORY_SIZE (DEFAULT_FREE_ADDRESS - SECURE_MEMORY_BASE) + +/* unused area */ +#define UNUSED_MEMORY_BASE (SECURE_MEMORY_BASE + SECURE_MEMORY_SIZE) +#define UNUSED_MEMORY_SIZE (IBOOT_BASE - UNUSED_MEMORY_BASE) + +#endif /* !WITH_DFU_MODE */ + +#endif /* APPLICATION_IBOOT */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s5l8960x/include/platform/pinconfig.h b/platform/s5l8960x/include/platform/pinconfig.h new file mode 100644 index 0000000..05608f6 --- /dev/null +++ b/platform/s5l8960x/include/platform/pinconfig.h @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default S5L8960X SoC Pin Configuration */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // TST_CLKOUT -> + CFG_FUNC0, // WDOG -> + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + +/* Port 1 */ + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + +/* Port 2 */ + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + +/* Port 5 */ + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RXD -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 6 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 7 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 8 */ + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 9 */ + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + +/* Port 10 */ + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + +/* Port 11 */ + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + +/* Port 12 */ + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 13 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + +/* Port 14 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // DISPLAY_SYNC -> + +/* Port 15 */ + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_D0 -> + CFG_DISABLED, // DWI_CLK -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + +/* Port 17 */ + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + +/* Port 18 */ + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 19 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 20 */ + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // SIO_7816UART0_SDA -> + CFG_DISABLED, // SIO_7816UART0_SCL -> + CFG_DISABLED, // SIO_7816UART0_RST -> + CFG_DISABLED, // SIO_7816UART1_SDA -> + CFG_DISABLED, // SIO_7816UART1_SCL -> + +/* Port 21 */ + CFG_DISABLED, // SIO_7816UART0_RST -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 22 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 23 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 24 */ + CFG_DISABLED, // EPD_HPD -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s5l8960x/include/platform/soc/ccc.h b/platform/s5l8960x/include/platform/soc/ccc.h new file mode 100644 index 0000000..f357d64 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/ccc.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_CCC_H +#define __PLATFORM_SOC_CCC_H + +#define rCCC_CPU0_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x000)) +#define rCCC_CPU0_IMPL_CPU_IOACC_CTL_EL3 (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x008)) +#define rCCC_CPU0_IMPL_FED_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x010)) +#define rCCC_CPU0_IMPL_LSU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x018)) +#define rCCC_CPU0_IMPL_MMU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x020)) + +#define CCC0_IMPL_BASE_ADDR (CCC0_SYS_BASE_ADDR + 0x40000) +#define rCCC_CCC_IMPL_CPM_IOACC_CTL_EL3 (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x000)) +#define rCCC_CCC_IMPL_L2C_ERR_STS (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x008)) +#define rCCC_CCC_IMPL_L2C_ERR_ADR (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x010)) +#define rCCC_CCC_IMPL_L2C_ERR_INF (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x018)) + +#define rCCC_CPU1_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU1_SYS_BASE_ADDR + 0x000)) +#define rCCC_CPU2_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU2_SYS_BASE_ADDR + 0x000)) + +#endif /* __PLATFORM_SOC_CCC_H */ diff --git a/platform/s5l8960x/include/platform/soc/chipid.h b/platform/s5l8960x/include/platform/soc/chipid.h new file mode 100644 index 0000000..5b87f97 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/chipid.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include + +#define rCFG_FUSE0 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCFG_FUSE1 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCFG_FUSE2 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rCFG_FUSE3 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x0C)) +#define rCFG_FUSE4 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x10)) +#define rCFG_FUSE5 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x14)) + +#define rECIDLO (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x20)) +#define rECIDHI (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x24)) + +#define rAP_SECURITY (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x40)) +#define rSEP_SECURITY (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x44)) + +#define rCFG_FUSE0_RAW (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x100)) + +uint32_t chipid_get_soc_voltage(uint32_t index); +uint32_t chipid_get_gpu_voltage(uint32_t index); + +#define CHIPID_CPU_VOLTAGE_BYPASS (0) +#define CHIPID_CPU_VOLTAGE_SECUREROM (1) +#define CHIPID_CPU_VOLTAGE_V0 (2) +#define CHIPID_CPU_VOLTAGE_V1 (3) +#define CHIPID_CPU_VOLTAGE_V2 (4) +#define CHIPID_CPU_VOLTAGE_V3 (5) +#define CHIPID_CPU_VOLTAGE_V4 (6) + +// CPU Boot Voltage - Should be cleaned up since not used for H6 +#if SUB_TARGET_N51 || SUB_TARGET_N53 || SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 || SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M +#define CHIPID_CPU_VOLTAGE_MED (CHIPID_CPU_VOLTAGE_V2) +#else +#define CHIPID_CPU_VOLTAGE_MED (CHIPID_CPU_VOLTAGE_V1) +#endif + +uint32_t chipid_get_cpu_voltage(uint32_t index); + +uint32_t chipid_get_ram_voltage(uint32_t index); + +int32_t chipid_get_cpu_temp_offset(uint32_t cpu_number); + +uint32_t chipid_get_fused_pmgr_thermal_sensor_cal_70C(uint32_t sensorID); +uint32_t chipid_get_fused_pmgr_thermal_sensor_cal_25C(uint32_t sensorID); +uint32_t chipid_get_fused_ccc_thermal_sensor_cal_70C(uint32_t sensorID); +uint32_t chipid_get_fused_ccc_thermal_sensor_cal_25C(uint32_t sensorID); +uint32_t chipid_get_fuse_revision(void); + +uint32_t chipid_get_total_rails_leakage(); + +bool chipid_valid_thermal_sensor_cal_data_expected(void); // + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s5l8960x/include/platform/soc/display.h b/platform/s5l8960x/include/platform/soc/display.h new file mode 100644 index 0000000..d478f7c --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/display.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables +static struct adfe_v1_tuneable adfe_tuneables[] = +{ +#if DISPLAY_IPHONE_TUNABLES + { + .name = "default", + .disp_dpcclkcntl[0] = (DPCCLKCNTL_FLOOR(0x20) | + DPCCLKCNTL_PIPE_ENABLE | + DPCCLKCNTL_LB_ENABLE | + DPCCLKCNTL_GATEENAB), + .disp_dpbclklvl_clock_off_level[0] = DPBCLKLVL_OFFLVL(0x7f8), + .disp_dpbclklvl_clock_on_level[0] = DPBCLKLVL_ONLVL(0x1e1), + .disp_dpcqoscnfg[0] = (DPCQOSCNFG_QOS_TIMER(0xFA0) | + DPCQOSCNFG_PIPE_ENABLE | + DPCQOSCNFG_VIDFIFO_ENABLE | + DPCQOSCNFG_UIFIFO_ENABLE | + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[0] = DPBQOSLVL_MED_WATERMARK(0x1d7), + .disp_dpbqoslvl_high_watermark[0] = DPBQOSLVL_HIGH_WATERMARK(0x13a), + .disp_dpureqcfg[0] = DPUREQCFG_REQ_CNT(0x18), + .disp_dpusrcstrd[0] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpvreqcfg[0] = DPVREQCFG_REQ_CNT(0x6), + .disp_dpvsrcstrd[0] = DPVSRCSTRD_SRCBURST_2BLOCKS, + .disp_dpcwbstrd[0] = DPCWBSTRD_DSTBURST_4BLOCKS, + + .disp_dpcclkcntl[1] = (DPCCLKCNTL_FLOOR(0x20) | + DPCCLKCNTL_LB_ENABLE | + DPCCLKCNTL_GATEENAB), + .disp_dpbclklvl_clock_off_level[1] = DPBCLKLVL_OFFLVL(0x7f8), + .disp_dpbclklvl_clock_on_level[1] = DPBCLKLVL_ONLVL(0x1e1), + .disp_dpcqoscnfg[1] = (DPCQOSCNFG_QOS_TIMER(0xFA0) | + DPCQOSCNFG_PIPE_ENABLE | + DPCQOSCNFG_VIDFIFO_ENABLE | + DPCQOSCNFG_UIFIFO_ENABLE | + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[1] = DPBQOSLVL_MED_WATERMARK(0x1d7), + .disp_dpbqoslvl_high_watermark[1] = DPBQOSLVL_HIGH_WATERMARK(0x13a), + .disp_dpureqcfg[1] = DPUREQCFG_REQ_CNT(0x18), + .disp_dpusrcstrd[1] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpvreqcfg[1] = DPVREQCFG_REQ_CNT(0x6), + .disp_dpvsrcstrd[1] = DPVSRCSTRD_SRCBURST_2BLOCKS, + .disp_dpcwbstrd[1] = DPCWBSTRD_DSTBURST_4BLOCKS, + }, +#endif //DISPLAY_IPHONE_TUNABLES + +//Tunables for targets using the the timing based on landscape ipads +#if DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES + { + .name = "default", + .disp_dpcclkcntl[0] = (DPCCLKCNTL_FLOOR(0x20) | + DPCCLKCNTL_LB_ENABLE | + DPCCLKCNTL_GATEENAB), + .disp_dpbclklvl_clock_off_level[0] = DPBCLKLVL_OFFLVL(0x7f8), + .disp_dpbclklvl_clock_on_level[0] = DPBCLKLVL_ONLVL(0x708), + + .disp_dpcqoscnfg[0] = (DPCQOSCNFG_QOS_TIMER(0x5780) | + DPCQOSCNFG_VIDFIFO_ENABLE | + DPCQOSCNFG_UIFIFO_ENABLE | + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[0] = DPBQOSLVL_MED_WATERMARK(0x5dc), + .disp_dpbqoslvl_high_watermark[0] = DPBQOSLVL_HIGH_WATERMARK(0x3e8), + .disp_dpureqcfg[0] = DPUREQCFG_REQ_CNT(0x73), + .disp_dpusrcstrd[0] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpvreqcfg[0] = DPVREQCFG_REQ_CNT(0x39), + .disp_dpvsrcstrd[0] = DPVSRCSTRD_SRCBURST_2BLOCKS, + .disp_dpcwbstrd[0] = DPCWBSTRD_DSTBURST_4BLOCKS, + + .disp_dpcclkcntl[1] = (DPCCLKCNTL_FLOOR(0x20) | + DPCCLKCNTL_LB_ENABLE | + DPCCLKCNTL_GATEENAB), + .disp_dpbclklvl_clock_off_level[1] = DPBCLKLVL_OFFLVL(0x7f8), + .disp_dpbclklvl_clock_on_level[1] = DPBCLKLVL_ONLVL(0x708), + + .disp_dpcqoscnfg[1] = (DPCQOSCNFG_QOS_TIMER(0x5780) | + DPCQOSCNFG_VIDFIFO_ENABLE | + DPCQOSCNFG_UIFIFO_ENABLE | + DPCQOSCNFG_QOS_ENABLE), + .disp_dpbqoslvl_med_watermark[1] = DPBQOSLVL_MED_WATERMARK(0x5dc), + .disp_dpbqoslvl_high_watermark[1] = DPBQOSLVL_HIGH_WATERMARK(0x3e8), + .disp_dpureqcfg[1] = DPUREQCFG_REQ_CNT(0x73), + .disp_dpusrcstrd[1] = DPUSRCSTRD_SRCBURST_4BLOCKS, + .disp_dpvreqcfg[1] = DPVREQCFG_REQ_CNT(0x39), + .disp_dpvsrcstrd[1] = DPVSRCSTRD_SRCBURST_2BLOCKS, + .disp_dpcwbstrd[1] = DPCWBSTRD_DSTBURST_4BLOCKS, + }, + +#if DISPLAY_IPHONE_TUNABLES +#error DISPLAY_IPHONE_TUNABLES set for IPAD +#endif + +#endif //DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/s5l8960x/include/platform/soc/display_color_manager_tables.h b/platform/s5l8960x/include/platform/soc/display_color_manager_tables.h new file mode 100644 index 0000000..d241647 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/display_color_manager_tables.h @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_DISPLAY_COLOR_MANAGER_TABLES_H +#define __PLATFORM_DISPLAY_COLOR_MANAGER_TABLES_H + +//identity matrix +const uint32_t linear_identity_matrix_tables[] = { + 0x00001000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00001000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00001000, 0x00000000, 0x00000000, +}; + +const uint32_t linear_rgb_engamma_tables[] = { + 0x001a0000, + 0x00470033, + 0x00650057, + 0x007c0071, + 0x00900087, + 0x00a20099, + 0x00b100aa, + 0x00c000b9, + 0x00cd00c6, + 0x00d900d3, + 0x00e500df, + 0x00f000eb, + 0x00fa00f5, + 0x01040100, + 0x010e0109, + 0x01170113, + 0x0120011c, + 0x01290124, + 0x0131012d, + 0x01390135, + 0x0141013d, + 0x01480144, + 0x0150014c, + 0x01570153, + 0x015e015a, + 0x01640161, + 0x016b0168, + 0x0172016e, + 0x01780175, + 0x017e017b, + 0x01840181, + 0x018a0187, + 0x0190018e, + 0x01960193, + 0x019c0199, + 0x01a2019f, + 0x01a701a4, + 0x01ac01aa, + 0x01b201af, + 0x01b701b4, + 0x01bc01ba, + 0x01c101bf, + 0x01c601c4, + 0x01cb01c9, + 0x01d001ce, + 0x01d501d3, + 0x01da01d8, + 0x01df01dc, + 0x01e301e1, + 0x01e801e6, + 0x01ec01ea, + 0x01f101ef, + 0x01f501f3, + 0x01fa01f8, + 0x01fe01fc, + 0x02030200, + 0x02070205, + 0x020b0209, + 0x020f020d, + 0x02130211, + 0x02170215, + 0x021b0219, + 0x021f021d, + 0x02230221, + 0x02270225, + 0x022b0229, + 0x022f022d, + 0x02330231, + 0x02370235, + 0x023b0239, + 0x023e023c, + 0x02420240, + 0x02460244, + 0x02490248, + 0x024d024b, + 0x0251024f, + 0x02540252, + 0x02580256, + 0x025b0259, + 0x025f025d, + 0x02620260, + 0x02660264, + 0x02690267, + 0x026c026b, + 0x0270026e, + 0x02730271, + 0x02760275, + 0x027a0278, + 0x027d027b, + 0x0280027f, + 0x02830282, + 0x02870285, + 0x028a0288, + 0x028d028b, + 0x0290028f, + 0x02930292, + 0x02960295, + 0x029a0298, + 0x029d029b, + 0x02a0029e, + 0x02a302a1, + 0x02a602a4, + 0x02a902a7, + 0x02ac02aa, + 0x02af02ad, + 0x02b202b0, + 0x02b502b3, + 0x02b802b6, + 0x02ba02b9, + 0x02bd02bc, + 0x02c002bf, + 0x02c302c2, + 0x02c602c5, + 0x02c902c7, + 0x02cc02ca, + 0x02ce02cd, + 0x02d102d0, + 0x02d402d3, + 0x02d702d5, + 0x02d902d8, + 0x02dc02db, + 0x02df02de, + 0x02e202e0, + 0x02e402e3, + 0x02e702e6, + 0x02ea02e8, + 0x02ec02eb, + 0x02ef02ee, + 0x02f202f0, + 0x02f402f3, + 0x02f702f5, + 0x02f902f8, + 0x02fc02fb, + 0x02ff02fd, + 0x03010300, + 0x03040302, + 0x03060305, + 0x03090307, + 0x030b030a, + 0x030e030c, + 0x0310030f, + 0x03130311, + 0x03150314, + 0x03180316, + 0x031a0319, + 0x031d031b, + 0x031f031e, + 0x03210320, + 0x03240323, + 0x03260325, + 0x03290327, + 0x032b032a, + 0x032d032c, + 0x0330032f, + 0x03320331, + 0x03340333, + 0x03370336, + 0x03390338, + 0x033c033a, + 0x033e033d, + 0x0340033f, + 0x03420341, + 0x03450344, + 0x03470346, + 0x03490348, + 0x034c034a, + 0x034e034d, + 0x0350034f, + 0x03520351, + 0x03550353, + 0x03570356, + 0x03590358, + 0x035b035a, + 0x035d035c, + 0x0360035f, + 0x03620361, + 0x03640363, + 0x03660365, + 0x03680367, + 0x036b0369, + 0x036d036c, + 0x036f036e, + 0x03710370, + 0x03730372, + 0x03750374, + 0x03770376, + 0x037a0378, + 0x037c037b, + 0x037e037d, + 0x0380037f, + 0x03820381, + 0x03840383, + 0x03860385, + 0x03880387, + 0x038a0389, + 0x038c038b, + 0x038e038d, + 0x0390038f, + 0x03920391, + 0x03940393, + 0x03970396, + 0x03990398, + 0x039b039a, + 0x039d039c, + 0x039f039e, + 0x03a103a0, + 0x03a303a2, + 0x03a503a4, + 0x03a703a6, + 0x03a803a8, + 0x03aa03a9, + 0x03ac03ab, + 0x03ae03ad, + 0x03b003af, + 0x03b203b1, + 0x03b403b3, + 0x03b603b5, + 0x03b803b7, + 0x03ba03b9, + 0x03bc03bb, + 0x03be03bd, + 0x03c003bf, + 0x03c203c1, + 0x03c403c3, + 0x03c603c5, + 0x03c703c6, + 0x03c903c8, + 0x03cb03ca, + 0x03cd03cc, + 0x03cf03ce, + 0x03d103d0, + 0x03d303d2, + 0x03d503d4, + 0x03d603d5, + 0x03d803d7, + 0x03da03d9, + 0x03dc03db, + 0x03de03dd, + 0x03e003df, + 0x03e103e1, + 0x03e303e2, + 0x03e503e4, + 0x03e703e6, + 0x03e903e8, + 0x03ea03ea, + 0x03ec03eb, + 0x03ee03ed, + 0x03f003ef, + 0x03f203f1, + 0x03f303f3, + 0x03f503f4, + 0x03f703f6, + 0x03f903f8, + 0x03fb03fa, + 0x03fc03fb, + 0x03fe03fd, + 0x03ff03ff, +}; + +const uint32_t linear_rgb_degamma_tables[] = { + 0x00280000, + 0x0077004f, + 0x00c7009e, + 0x012100f0, + 0x018d0152, + 0x020d01c8, + 0x02a40253, + 0x035002f4, + 0x041403ac, + 0x04f1047c, + 0x05e60565, + 0x06f50667, + 0x081e0783, + 0x096308ba, + 0x0ac40a0c, + 0x0c400b7b, + 0x0ddb0d06, + 0x0f920eaf, + 0x11681076, + 0x135d125b, + 0x1571145f, + 0x17a61683, + 0x19fa18c8, + 0x1c701b2d, + 0x1f071db3, + 0x21c0205b, + 0x249c2325, + 0x279a2612, + 0x2abc2922, + 0x2e022c56, + 0x316c2fae, + 0x34fb332a, + 0x38ae36cb, + 0x3c883a92, + 0x40873e7e, + 0x44ad4290, + 0x48fa46ca, + 0x4d6d4b2a, + 0x52094fb1, + 0x56cc5460, + 0x5bb75938, + 0x60cc5e37, + 0x66096360, + 0x6b7068b2, + 0x70fb6e2e, + 0x76b673d3, + 0x7c9b79a3, + 0x82ab7f9e, + 0x88e685c3, + 0x8f4d8c14, + 0x95e09291, + 0x9c9e9939, + 0xa38aa00e, + 0xaaa2a710, + 0xb1e7ae3f, + 0xb95ab59b, + 0xc0fabd24, + 0xc8c9c4db, + 0xd0c5ccc1, + 0xd8f1d4d5, + 0xe14cdd18, + 0xe9d5e58b, + 0xf28fee2c, + 0xfb78f6fe, + 0xffffffff, +}; + +#endif diff --git a/platform/s5l8960x/include/platform/soc/display_timings.h b/platform/s5l8960x/include/platform/soc/display_timings.h new file mode 100644 index 0000000..765c356 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/display_timings.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_N51 || SUB_TARGET_N53 || SUB_TARGET_CYCLONIC + { + .display_name = "n51", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 61540000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 6, + .h_back_porch = 32, + .h_front_porch = 4, + .v_active = 1136, + .v_pulse_width = 3, + .v_back_porch = 13, + .v_front_porch = 352, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || WITH_HW_DISPLAY_DISPLAYPORT + { + .display_name = "720p", + .host_clock_id = CLK_VCLK1, + .pixel_clock = 00000000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 110, + .h_front_porch = 220, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 5, + .v_front_porch = 20, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_DP, + .display_config = NULL, + }, + + { + .display_name = "720p-j34", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 110, + .h_front_porch = 220, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 5, + .v_front_porch = 20, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_DP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_J71 || SUB_TARGET_J72 || SUB_TARGET_J73 + { + .display_name = "ipad4", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 264, + .h_active = 1536, + .h_pulse_width = 15, + .h_back_porch = 52, + .h_front_porch = 16, + .v_active = 2048, + .v_pulse_width = 1, + .v_back_porch = 3, + .v_front_porch = 7, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 || SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + { + .display_name = "ipad4b", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 326, + .h_active = 1536, + .h_pulse_width = 16, + .h_back_porch = 48, + .h_front_porch = 12, + .v_active = 2048, + .v_pulse_width = 4, + .v_back_porch = 8, + .v_front_porch = 8, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/s5l8960x/include/platform/soc/hwclocks.h b/platform/s5l8960x/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..b6699b7 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/hwclocks.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (5000000UL) +#else +#define OSC_FREQ (24000000UL) +#endif + +// Start from an offset of 128. So that we are safely outside the PS indexes. +#define CLK_FCLK (HWCLOCK_BASE+128) +#define CLK_ACLK (HWCLOCK_BASE+129) +#define CLK_HCLK (HWCLOCK_BASE+130) +#define CLK_PCLK (HWCLOCK_BASE+131) +#define CLK_VCLK0 (HWCLOCK_BASE+132) +#define CLK_VCLK1 (HWCLOCK_BASE+133) +#define CLK_MCLK (HWCLOCK_BASE+134) +#define CLK_NCLK (HWCLOCK_BASE+135) +#define CLK_USBPHYCLK (HWCLOCK_BASE+136) +#define CLK_NCOREF (HWCLOCK_BASE+137) +#define CLK_ANS_LINK (HWCLOCK_BASE+138) + +/* + * S5L8960X clock gate devices. + * Refers to the ps register offsets. + */ +enum { + CLK_CPU0, + CLK_CPU1, + CLK_CPM, + CLK_LIO, + CLK_IOMUX, + CLK_AIC, + CLK_DEBUG, + CLK_DWI, + CLK_GPIO, + CLK_MCA0, + CLK_MCA1, + CLK_MCA2, + CLK_MCA3, + CLK_MCA4, + CLK_PWM0, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_I2C3, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_SECUART0, + CLK_SECUART1, + CLK_AES0, + CLK_SIO, + CLK_SIO_P, + CLK_HSIC0_PHY, + CLK_HSIC1_PHY, + CLK_HSIC2_PHY, + CLK_ISPSENS0, + CLK_ISPSENS1, + CLK_MCC, + CLK_MCU, + CLK_AMP, + CLK_USB, + CLK_USBCTLREG, + CLK_USB2HOST0_OHCI, + CLK_USB2HOST0, + CLK_USB2HOST1_OHCI, + CLK_USB2HOST1, + CLK_USB_OTG, + CLK_SMX, + CLK_SF, + CLK_CP, + CLK_DISP_BUSMUX, + CLK_DISP0, + CLK_MIPI_DSI, + CLK_MIPI = CLK_MIPI_DSI, + CLK_EDPLINK, + CLK_DPLINK = CLK_EDPLINK, + CLK_DISP1, + CLK_ISP, + CLK_MEDIA, + CLK_MSR, + CLK_JPG, + CLK_VDEC, + CLK_VENC, + CLK_ANS, + CLK_ANS_DLL, + CLK_ADSP, + CLK_GFX, + PMGR_LAST_DEVICE, + CLK_SEP = CLK_GFX + 10, +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s5l8960x/include/platform/soc/hwisr.h b/platform/s5l8960x/include/platform/soc/hwisr.h new file mode 100644 index 0000000..b02e53d --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/hwisr.h @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_DWI 5 // DWI Interrupt +#define INT_PMGR_PERF_CNTRS 6 // PMGR Performace Counters Interrupt +#define INT_THERM_TEMP0 7 // Thermal Temp 0 Interrupt +#define INT_THERM_ALARM0 8 // Thermal Alarm 0 Interrupt +#define INT_THERM_TEMP1 9 // Thermal Temp 1 Interrupt +#define INT_THERM_ALARM1 10 // Thermal Alarm 1 Interrupt + +// Reserved 11 - 19 + +#define INT_THERM_FS_ACT0 20 // Thermal Failsafe Active 0 Interrupt +#define INT_THERM_FS_ACT1 21 // Thermal Failsafe Active 1 Interrupt +#define INT_THERM_FS_EXT0 22 // Thermal Failsafe Exit 0 Interrupt +#define INT_THERM_FS_EXT1 23 // Thermal Failsafe Exit 1 Interrupt +#define INT_SOC_THERM_FS_ACT0 24 // SoC Thermal Failsafe Active 0 Interrupt +#define INT_SOC_THERM_FS_ACT1 25 // SoC Thermal Failsafe Active 1 Interrupt + +// Reserved 26 - 31 + +#define INT_ISP_KF_INBOX_EMPTY 32 // ISP KF Inbox Empty Interrupt +#define INT_ISP_KF_INBOX_NOTEMPTY 33 // ISP KF Inbox Not Empty Interrupt +#define INT_ISP_KF_OUTBOX_EMPTY 34 // ISP KF Outbox Empty Interrupt +#define INT_ISP_KF_OUTBOX_NOTEMPTY 35 // ISP KF Outbox Not Empty Interrupt +#define INT_ISP0 36 // ISP 0 Interrupt +#define INT_ISP1 37 // ISP 1 Interrupt +#define INT_ISP2 38 // ISP 2 Interrupt +#define INT_ISP3 39 // ISP 3 Interrupt +#define INT_ISP_DART 40 // ISP DART Interrupt + +// Reserved 41 - 43 + +#define INT_SEP_KF_INBOX_EMPTY 44 // SEP KF Inbox Empty Interrupt +#define INT_SEP_KF_INBOX_NOTEMPTY 45 // SEP KF Inbox Not Empty Interrupt +#define INT_SEP_KF_OUTBOX_EMPTY 46 // SEP KF Outbox Empty Interrupt +#define INT_SEP_KF_OUTBOX_NOTEMPTY 47 // SEP KF Outbox Not Empty Interrupt + +// Reserved 48 - 51 + +#define INT_ANS_KF_INBOX_EMPTY 52 // ANS KF Inbox Empty Interrupt +#define INT_ANS_KF_INBOX_NOTEMPTY 53 // ANS KF Inbox Not Empty Interrupt +#define INT_ANS_KF_OUTBOX_EMPTY 54 // ANS KF Outbox Empty Interrupt +#define INT_ANS_KF_OUTBOX_NOTEMPTY 55 // ANS KF Outbox Not Empty Interrupt +#define INT_ANS_CHNL0 56 // ANS Channel 0 Interrupt +#define INT_ANS_CHNL1 57 // ANS Channel 1 Interrupt + +// Reserved 58 - 63 + +#define INT_DISP0 64 // Display 0 Interrupt +#define INT_DISP0_PERF_CNTRS 65 // Display 0 Performace Counters Interrupt +#define INT_DISP0_BACK_END_VBI 66 // Display 0 Back End VBI Interrupt +#define INT_DISP0_BACK_END_MISC 67 // Display 0 Back End Misc Interrupt +#define INT_MIPIDSI 68 // MIPI DSI Interrupt +#define INT_EDP0 69 // Display Port +#define INT_DPORT0 INT_EDP0 + +// Reserved 70 - 73 + +#define INT_DISP1 74 // Display 1 Interrupt +#define INT_DISP1_PERF_CNTRS 75 // Display 1 Performace Counters Interrupt +#define INT_DISP1_BACK_END 76 // Display 1 Back End Interrupt + +// Reserved 77 - 79 + +#define INT_VDEC 80 // Video Decoder Interrupt + +// Reserved 81 + +#define INT_VENC 82 // Video Encoder Interrupt + +// Reserved 83 + +#define INT_GFX 84 // GFX Interrupt +#define INT_GFX_SLEEP 85 // GFX Sleep Interrupt +#define INT_GFX_WAKE 86 // GFX Wake Interrupt +#define INT_GFX_CHG 87 // GFX Change Interrupt + +// Reserved 88 - 89 + +#define INT_ADSP_F0 90 // ADSP F0 Interrupt +#define INT_ADSP_F1 91 // ADSP F1 Interrupt +#define INT_ADSP_T0 92 // ADSP T0 Interrupt +#define INT_ADSP_T1 93 // ADSP T1 Interrupt + +// Reserved 94 + +#define INT_JPEG 95 // JPEG Interrupt +#define INT_JPEG_ERR 96 // JPEG Error Interrupt +#define INT_JPEG_DART 97 // JPEG DART Interrupt +#define INT_JPEG_DART_PERF 98 // JPEG DART Performance Interrupt + +// Reserved 99 + +#define INT_MSR 100 // MSR Interrupt +#define INT_MSR_SMMU 101 // MSR SMMU Interrupt +#define INT_MSR_DART 102 // MSR DART Interrupt +#define INT_MSR_DAR_PERF 103 // MSR DART Performance Interrupt + +// Reserved 104-107 + +#define INT_GPIO_CLASS0 108 // GPIO Class 0 Interrupt +#define INT_GPIO_CLASS1 109 // GPIO Class 1 Interrupt +#define INT_GPIO_CLASS2 110 // GPIO Class 2 Interrupt +#define INT_GPIO_CLASS3 111 // GPIO Class 3 Interrupt +#define INT_GPIO_CLASS4 112 // GPIO Class 4 Interrupt +#define INT_GPIO_CLASS5 113 // GPIO Class 5 Interrupt +#define INT_GPIO_CLASS6 114 // GPIO Class 6 Interrupt + +// Reserved 115-127 + +#define INT_MEM_CONTROLLER 128 // Memory Controller Interrupt +#define INT_MCU_CHNL0_PHY 129 // MCU Channel 0 PHY +#define INT_MCU_CHNL1_PHY 130 // MCU Channel 0 PHY + +// Reserved 131 + +#define INT_SIO_KF_INBOX_EMPTY 132 // SIO KF Inbox Empty Interrupt +#define INT_SIO_KF_INBOX_NOTEMPTY 133 // SIO KF Inbox Not Empty Interrupt +#define INT_SIO_KF_OUTBOX_EMPTY 134 // SIO KF Outbox Empty Interrupt +#define INT_SIO_KF_OUTBOX_NOTEMPTY 135 // SIO KF Outbox Not Empty Interrupt +#define INT_SPI0 136 // SPI 0 Interrupt +#define INT_SPI1 137 // SPI 1 Interrupt +#define INT_SPI2 138 // SPI 2 Interrupt +#define INT_SPI3 139 // SPI 3 Interrupt +#define INT_UART0 140 // UART 0 Interrupt +#define INT_UART1 141 // UART 1 Interrupt +#define INT_UART2 142 // UART 2 Interrupt +#define INT_UART3 143 // UART 3 Interrupt +#define INT_UART4 144 // UART 4 Interrupt +#define INT_UART5 145 // UART 5 Interrupt +#define INT_UART6 146 // UART 6 Interrupt +#define INT_UART7 147 // UART 7 Interrupt +#define INT_MCA0 148 // Multi-Channel Audio 0 Interrupt +#define INT_MCA1 149 // Multi-Channel Audio 1 Interrupt +#define INT_MCA2 150 // Multi-Channel Audio 2 Interrupt +#define INT_MCA3 151 // Multi-Channel Audio 3 Interrupt +#define INT_MCA4 152 // Multi-Channel Audio 4 Interrupt +#define INT_SEC_UART0 153 // Secure UART 0 Interrupt +#define INT_SEC_UART1 154 // Secure UART 1 Interrupt +#define INT_IIC0 155 // I2C 0 Interrupt +#define INT_IIC1 156 // I2C 1 Interrupt +#define INT_IIC2 157 // I2C 2 Interrupt +#define INT_IIC3 158 // I2C 3 Interrupt +#define INT_PWM 159 // PWM Interrupt +#define INT_AES0 160 // AES 0 Interrupt + +// Reserved 161 + +#define INT_USB_OTG 162 // USB OTG Interrupt +#define INT_USB2HOST0_EHCI 163 // USB EHCI 0 Interrupt +#define INT_USB2HOST0_OHCI 164 // USB OHCI 0 Interrupt +#define INT_USB2HOST1_EHCI 165 // USB EHCI 1 Interrupt + +// Reserved 166 - 167 + +#define INT_USBOTG_RESUME 168 // USB OTG Resume Interrupt +#define INT_USB_20_BATT_CHRG_DET 169 // USB 2.0 Battery Charge Detect Interrupt +#define INT_USB2HOST0_PHY_RESUME 170 // USB Host 0 Resume Interrupt +#define INT_USB2HOST1_PHY_RESUME 171 // USB Host 1 Resume Interrupt + +// Reserved 172 + +#define INT_COHERENCE_PNT_ERR 173 // Coherence Point Error Interrupt +#define INT_COHERENCE_PNT_PERF_CNTRS 174 // Coherence Point Performance Counters Interrupt + +// Reserved 175 + +#define INT_CPU0_COMM_TX 176 // CPU 0 COMM TX Interrupt +#define INT_CPU0_COMM_RX 177 // CPU 0 COMM RX Interrupt +#define INT_CPU0_PMU_IRQ 178 // CPU 0 PMU IRQ Interrupt +#define INT_CPU1_COMM_TX 179 // CPU 1 COMM TX Interrupt +#define INT_CPU1_COMM_RX 180 // CPU 1 COMM RX Interrupt +#define INT_CPU1_PMU_IRQ 181 // CPU 1 PMU IRQ Interrupt + +// Reserved 182 - 184 + +#define INT_CTM_TRIGGER0 185 // CTM Trigger 0 Interrupt +#define INT_CTM_TRIGGER1 186 // CTM Trigger 1 Interrupt +#define INT_CTM_TRIGGER2 187 // CTM Trigger 2 Interrupt +#define INT_CTM_TRIGGER3 188 // CTM Trigger 3 Interrupt + +// Reserved 189 - 191 + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s5l8960x/include/platform/soc/hwregbase.h b/platform/s5l8960x/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..45d56a5 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/hwregbase.h @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#include + +/* S5L8960X Reg Base Defs */ + +#define AMC_BASE_ADDR (IO_BASE + 0x000000000) // AMC Config + +#define SWTCH_FAB_BASE_ADDR (IO_BASE + 0x000800000) // Switch Fabric Config + +#define CP_COM_BASE_ADDR (IO_BASE + 0x000D00000) // CP Common Registers +#define CP_COM_INT_BASE_ADDR (CP_COM_BASE_ADDR + 0x10000) // CP Common Interrupt Config Registers + +// XXX clarify these +#define CP_0_DT_BASE_ADDR (IO_BASE + 0x000D20000) // Dup Tag Config and Debug +#define CP_0_DT_DBG_CA0_ADDR (IO_BASE + 0x000D30000) // Dup Tag Debug backdoor Ram Access For CP0/CA0 +#define CP_0_CCU_CSR_BASE_ADDR (IO_BASE + 0x000D90000) // CTT and MIU Config and Debug +#define CP_1_DT_BASE_ADDR (IO_BASE + 0x000E20000) // Dup Tag Config and Debug +#define CP_1_DT_DBG_CA0_ADDR (IO_BASE + 0x000E30000) // Dup Tag Debug backdoor Ram Access For CP1/CA0 +#define CP_1_CCU_CSR_BASE_ADDR (IO_BASE + 0x000E90000) // CTT and MIU Config and Debug + +#define RGX_CR_BASE_ADDR (IO_BASE + 0x001000000) // G3 Rogue Space +#define GPC_BASE_ADDR (IO_BASE + 0x001e00000) // G3 Power Controller Space + +#define IMGV42AF_AFC_AIU_BASE_ADDR (IO_BASE + 0x001f00000) // IMGv42AF: Local PIO Config Space of AF AIU Block +#define IMGV42AF_AFUSR_BASE_ADDR (IO_BASE + 0x001f02000) // IMGv42AF: Bridge PIO Space + +#define CCC_ROM_TABLE_BASE_ADDR (IO_BASE + 0x002000000) // Cyclone ROM Table +#define CCC_CPU0_DBG_BASE_ADDR (IO_BASE + 0x002010000) // Cyclone CPU0 Debug Registers +#define CCC_CPU0_CTI_BASE_ADDR (IO_BASE + 0x002020000) // Cyclone CPU0 CTI Registers +#define CCC_CPU0_PMU_BASE_ADDR (IO_BASE + 0x002030000) // Cyclone CPU0 PMU Registgers +#define CCC_CPU0_TRC_BASE_ADDR (IO_BASE + 0x002040000) // Cyclone CPU0 TRACE Registers +#define CCC_CPU0_SYS_BASE_ADDR (IO_BASE + 0x002050000) // Cyclone CPU0 Implementation Specific Registers +#define CCC_CPU1_DBG_BASE_ADDR (IO_BASE + 0x002110000) // Cyclone CPU1 Debug Registers +#define CCC_CPU1_CTI_BASE_ADDR (IO_BASE + 0x002120000) // Cyclone CPU1 CTI Registers +#define CCC_CPU1_PMU_BASE_ADDR (IO_BASE + 0x002130000) // Cyclone CPU1 PMU Registgers +#define CCC_CPU1_TRC_BASE_ADDR (IO_BASE + 0x002140000) // Cyclone CPU1 TRACE Registers +#define CCC_CPU1_SYS_BASE_ADDR (IO_BASE + 0x002150000) // Cyclone CPU1 Implementation Specific Registers +#define CCC0_SYS_BASE_ADDR (IO_BASE + 0x002200000) // Cyclone Core Complex Registers +#define CCC_SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config +#define SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config +#define CCC_CAM_BUSMUX_BASE_ADDR (IO_BASE + 0x005000000) // AF Camera BusMux Config + +#define ISP_AFC_AIU_0_BASE_ADDR (IO_BASE + 0x005B00000) // ISP AXI to AF Bridge +#define ISP_AFC_AIU_1_BASE_ADDR (IO_BASE + 0x005B10000) // ISP AXI to AF Bridge +#define ISP_INTR2AXI_BASE_ADDR (IO_BASE + 0x005B20000) // ISP Interrupt to AXI Widget +#define ISP_DART_BASE_ADDR (IO_BASE + 0x005B22000) // ISP DART +#define ISP_SMMU_BASE_ADDR (IO_BASE + 0x005B24000) // ISP SMMU +#define ISP_ISPCTRL_R0_BASE_ADDR (IO_BASE + 0x005B40000) // SISP Region 0 Control +#define ISP_MIPI_CSI_0_BASE_ADDR (IO_BASE + 0x005B80000) // MIPI CSI Controller +#define ISP_MIPI_CSI_1_BASE_ADDR (IO_BASE + 0x005B81000) // MIPI CSI Controller +#define ISP_SMB_0_BASE_ADDR (IO_BASE + 0x005B82000) // SMB Controller +#define ISP_SMB_1_BASE_ADDR (IO_BASE + 0x005B83000) // SMB Controller +#define ISP_FD_BASE_ADDR (IO_BASE + 0x005B84000) // Face Detect +#define ISP_AISP_BASE_ADDR (IO_BASE + 0x005BA0000) // AISP +#define ISP_ISPCTRL_R1_BASE_ADDR (IO_BASE + 0x005BC0000) // SISP Region 1 Control +#define ISP_AKF_BASE_ADDR (IO_BASE + 0x005C00000) // SISP KF Widgets and Config +#define ISP_DISP_BUSMUX_BASE_ADDR (IO_BASE + 0x006000000) // AF Display BusMux Config + +#define DISP0_FAB_BASE_ADDR (IO_BASE + 0x006100000) // DisplayPipe0 AF and AXI Config +#define DISP0_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 Frontend Config +#define DISP0_ADBE_BASE_ADDR (IO_BASE + 0x006300000) // DisplayPipe0 Backend Config +#define DISP0_AAP_BASE_ADDR (IO_BASE + 0x006340000) // DisplayPipe0 Ambient-Adaptive Pixel Config +#define DISP0_DPB_BASE_ADDR (IO_BASE + 0x006380000) // DisplayPipe0 Pixel Backlight Config +#define DISP0_DITHER_BASE_ADDR (IO_BASE + 0x0063C0000) // DisplayPipe0 Dither Config +#define DITHER_BASE_ADDR DISP0_DITHER_BASE_ADDR +#define DITHER_VERSION (3) +#define DISP0_CM_BASE_ADDR (IO_BASE + 0x006300000) // DisplayPipe0 Color Manager +#define DISP_CM_BASE_ADDR DISP0_CM_BASE_ADDR + +#define DISP0_MIPI_DSI_BASE_ADDR (IO_BASE + 0x006400000) // DisplayPipe0 MIPI DSI Config +#define DISP0_DPTX_BASE_ADDR (IO_BASE + 0x006500000) // DisplayPipe0 DisplayPort TX Config + +#define DISP1_FAB_BASE_ADDR (IO_BASE + 0x006900000) // DisplayPipe1 AF and AXI Config +#define DISP1_BASE_ADDR (IO_BASE + 0x006A00000) // DisplayPipe1 Frontend Config +#define DISP1_ADBE_BASE_ADDR (IO_BASE + 0x006B00000) // DisplayPipe1 Backend Config +#define DISP1_MEDIA_BUSMUX_BASE_ADDR (IO_BASE + 0x007000000) // DisplayPipe1 AF Media BusMux Config + +#define MSR_AFC_AIU_BASE_ADDR (IO_BASE + 0x007800000) // MSR AXI2AF AFC_AIU +#define MSR_BASE_ADDR (IO_BASE + 0x007900000) // Memory Scalar Rotator +#define MSR_SMMU_BASE_ADDR (IO_BASE + 0x007904000) // MSR SMMU +#define MSR_DART_BASE_ADDR (IO_BASE + 0x007908000) // DART for MSR SMMU +#define MSR_INTR2AXI_BASE_ADDR (IO_BASE + 0x00790C000) // MSR Interrupt to AXI Widget + +#define AJPEG_AFC_AIU_BASE_ADDR (IO_BASE + 0x007A00000) // AJPEG AXI2AF AFC_AIU +#define AJPEG_INTR2AXI_BASE_ADDR (IO_BASE + 0x007B00000) // AJPEG Interrupt to AXI Widget +#define AJPEG_BASE_ADDR (IO_BASE + 0x007B01000) // AJPEG Wrap +#define AJPEG_DART_BASE_ADDR (IO_BASE + 0x007B03000) // AJPEG DART + +#define VXE_AFC_AIU_BASE_ADDR (IO_BASE + 0x007C00000) // VXE AXI2AF AFC_AIU +#define VXE_INTR2AXI_BASE_ADDR (IO_BASE + 0x007C01000) // VXE Interrupt to AXI Widget +#define VXE_PL301_BASE_ADDR (IO_BASE + 0x007C02000) // VXE PL301 Config +#define VXE_CFG_BASE_ADDR (IO_BASE + 0x007D00000) // VXE Config Registers + +#define VXD_AFC_AIU_BASE_ADDR (IO_BASE + 0x007E00000) // VXD AXI2AF AFC_AIU +#define VXD_INTR2AXI_BASE_ADDR (IO_BASE + 0x007E01000) // VXD Interrupt to AXI Widget +#define VXD_PL301_BASE_ADDR (IO_BASE + 0x007E02000) // VXD PL301 Config +#define VXD_CFG_BASE_ADDR (IO_BASE + 0x007F00000) // VXD Config Registers + +#define ANS_AFC_AIU_BASE_ADDR (IO_BASE + 0x008000000) // ANS AXI2AF AFC_AIU +#define ANS_PL301_BASE_ADDR (IO_BASE + 0x008010000) // ANS PL301 Config +#define ANS_AKF_PL301_TLMT_BASE_ADDR (IO_BASE + 0x008020000) // ANS KF Transaction Limit Widget +#define ANS_AKF_INTR2AXI_BASE_ADDR (IO_BASE + 0x008021000) // ANS KF Interrupt to AXI Widget +#define ANS_ANC_PL301_TLMT_0_BASE_ADDR (IO_BASE + 0x008030000) // ANS NAND Controller Transaction Limit Widget +#define ANS_ANC_PL301_TLMT_1_BASE_ADDR (IO_BASE + 0x008031000) // ANS NAND Controller Transaction Limit Widget +#define ANS_ANC_INTR2AXI_0_BASE_ADDR (IO_BASE + 0x008038000) // ANS NAND Controller Interrupt to AXI Widget +#define ANS_ANC_INTR2AXI_1_BASE_ADDR (IO_BASE + 0x008039000) // ANS NAND Controller Interrupt to AXI Widget +#define ANS_AKF_BASE_ADDR (IO_BASE + 0x008040000) // ANS KF Wrapper +// XXX AKF DBG (IO_BASE + 0x008060000) - (IO_BASE + 0x008070000) +#define ANS_CFG_BASE_BADDR (IO_BASE + 0x008080000) // ANS Config +#define ANS_PPN_N_PL_BASE_ADDR (IO_BASE + 0x008081000) // ANS PPN-N-PL Config +#define ANS_ANC_BASE_ADDR (IO_BASE + 0x008700000) // ANC Broadcast writes to all ANCs +#define ANS_ANC_0_BASE_ADDR (IO_BASE + 0x008800000) // ANS NAND Controller 0 +#define ANS_ANC_1_BASE_ADDR (IO_BASE + 0x008900000) // ANS NAND Controller 1 +#define ANS_IO_BUSMUX_BASE_ADDR (IO_BASE + 0x009000000) // ANS AF IO BusMux Config + +#define IOBUSMUX_BASE_ADDR (IO_BASE + 0x009000000) // IO BusMux Config + +#define SB_BASE_ADDR (IO_BASE + 0x00A000000) // South Bridge + +#define ASIO_MISC_0_BASE_ADDR (IO_BASE + 0x00A000000) // ASIO Shim0 Misc Registers +#define ASIO_AUD_MUX_BASE_ADDR (IO_BASE + 0x00A005000) // ASIO Audio I2S Switch Config +#define ASIO_SPI_BASE_ADDR (IO_BASE + 0x00A080000) // ASIO SPI Device +#define ASIO_SPI_TX_CFG_BASE_ADDR (IO_BASE + 0x00A081000) // ASIO SPI TX DMA Channel +#define ASIO_SPI_RX_CFG_BASE_ADDR (IO_BASE + 0x00A081800) // ASIO SPI RX DMA Channel +#define ASIO_SPI_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A082000) // ASIO SPI TX DMA Shim FIFO +#define ASIO_SPI_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A083000) // ASIO SPI RX DMA Shim FIFO +#define ASIO_UART_BASE_ADDR (IO_BASE + 0x00A0A0000) // ASIO UART Device +#define ASIO_UART_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1000) // ASIO UART TX DMA Channel +#define ASIO_UART_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1800) // ASIO UART RX DMA Channel +#define ASIO_UART_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A2000) // ASIO UART TX DMA Shim FIFO +#define ASIO_UART_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A3000) // ASIO UART RX DMA Shim FIFO +#define ASIO_MCA_BASE_ADDR (IO_BASE + 0x00A0C0000) // ASIO MCA Device +#define ASIO_MCA_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1000) // ASIO MCA TX DMA Channel +#define ASIO_MCA_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1800) // ASIO MCA RX DMA Channel +#define ASIO_MCA_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C2000) // ASIO MCA TX DMA Shim FIFO +#define ASIO_MCA_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C3000) // ASIO MCA RX DMA Shim FIFO +#define ASIO_MISC_1_BASE_ADDR (IO_BASE + 0x00A100000) // ASIO Shim1 Misc Registers +#define ASIO_AES_BASE_ADDR (IO_BASE + 0x00A108000) // ASIO AES Config and DMA Registers +#define ASIO_SMB_0_BASE_ADDR (IO_BASE + 0x00A110000) // ASIO I2C 0 Device +#define ASIO_SMB_1_BASE_ADDR (IO_BASE + 0x00A111000) // ASIO I2C 1 Device +#define ASIO_SMB_2_BASE_ADDR (IO_BASE + 0x00A112000) // ASIO I2C 2 Device +#define ASIO_SMB_3_BASE_ADDR (IO_BASE + 0x00A113000) // ASIO I2C 3 Device +#define ASIO_PWM_BASE_ADDR (IO_BASE + 0x00A118000) // ASIO PWM +#define ASIO_SEP_UART_0_BASE_ADDR (IO_BASE + 0x00A11C000) // ASIO SCR Device 0 +#define ASIO_SEP_UART_1_BASE_ADDR (IO_BASE + 0x00A11D000) // ASIO SCR Device 1 +#define ASIO_AKF_BASE_ADDR (IO_BASE + 0x00AE00000) // ASIO KF Wrapper +// XXX ASIO AKF DBG + +#define ADSP_BASE_ADDR (IO_BASE + 0x00B000000) // Audience Core + +#define AUSB_CTL_REG_BASE_ADDR (IO_BASE + 0x00C000000) // USBCTL Config +#define AUSB_CTL_USB20PHY_REG_OFFSET (0x20) // USB20PHY Register offset within AUSBCTL registers +#define AUSB_OTG_BASE_ADDR (IO_BASE + 0x00C100000) // USB OTG +#define AUSB_USB2HOST0_EHCI_BASE_ADDR (IO_BASE + 0x00C200000) // EHCI0 +#define AUSB_USB2HOST0_OHCI_BASE_ADDR (IO_BASE + 0x00C300000) // OHCI0 +#define AUSB_USB2HOST1_EHCI_BASE_ADDR (IO_BASE + 0x00C400000) // EHCI1 +#define AUSB_USB2HOST1_OHCI_BASE_ADDR (IO_BASE + 0x00C500000) // OHCI1 +#define AUSB_PL301_BASE_ADDR (IO_BASE + 0x00C800000) // AUSB PL301 4-AHB Master to 1-AXI Slave +#define AUSB_PL301_WIDGET_BASE_ADDR (IO_BASE + 0x00C900000) // AUSB PL301 Widget +#define AUSB_INTR2AXI_BASE_ADDR (IO_BASE + 0x00CA00000) // AUSB Interrupt to AXI Widget +#define AUSB_AFIFO_WIDGET_BASE_ADDR (IO_BASE + 0x00CB00000) // AUSB Async FIFO + +#define ASEP_AKF_BASE_ADDR (IO_BASE + 0x00D000000) // ASEP AKF control Registers + +#define PMGR_BASE_ADDR (IO_BASE + 0x00E000000) // PMGR + +#define AIC_BASE_ADDR (IO_BASE + 0x00E100000) // AIC +#define AIC_WIRE_VIRT_BASE_ADDR (IO_BASE + 0x00E110000) // AIC Wrapper + +#define DWI_BASE_ADDR (IO_BASE + 0x00E200000) // DWI + +#define GPIO_BASE_ADDR (IO_BASE + 0x00E300000) // GPIO + +#define AMPS_0_DQ_BASE_ADDR (IO_BASE + 0x00E400000) // AMP 0 DQ DRAM PHY +#define AMPS_0_CA_BASE_ADDR (IO_BASE + 0x00E410000) // AMP 0 CA DRAM PHY +#define AMPS_1_DQ_BASE_ADDR (IO_BASE + 0x00E420000) // AMP 1 DQ DRAM PHY +#define AMPS_1_CA_BASE_ADDR (IO_BASE + 0x00E430000) // AMP 1 CA DRAM PHY + +#define LIO_MEM_PL301_BASE_ADDR (IO_BASE + 0x00E900000) // PL310 for pd_lio memory +#define LIO_PIO_PL310_BASE_ADDR (IO_BASE + 0x00E940000) // PL310 for pd_lio PIO +#define LIO_SIO_AFIFO_WIDGETS_BASE_ADDR (IO_BASE + 0x00E9C0000) // SIO Async FIFO for pd_lio +#define LIO_DAP_AFIFO_WIDGETS_BASE_ADDR (IO_BASE + 0x00E9C8000) // SIO Async FIFO for pd_lio +#define LIO_AFC_AIU_BASE_ADDR (IO_BASE + 0x00F010000) // LIO AXI to AF Bridge + +#define DBG_WRP_BASE_ADDR (IO_BASE + 0x00F000000) // Debug Sub-system Config + +/* iBoot Specific Defs */ + +#define AKF_VERSION (1) + +#define UART0_BASE_ADDR (ASIO_UART_BASE_ADDR) +#define UART1_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x04000) +#define UART2_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x08000) +#define UART3_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x10000) +#define UART5_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x14000) +#define UART6_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x18000) +#define UARTS_COUNT (7) +#define UART_VERSION (1) + +#define SPI0_BASE_ADDR (ASIO_SPI_BASE_ADDR) +#define SPI1_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x04000) +#define SPI2_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x08000) +#define SPI3_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x0C000) +#define SPI_VERSION (1) +#define SPIS_COUNT (4) + +#define IIC_BASE_ADDR (ASIO_SMB_0_BASE_ADDR) +#define IIC_SPACING (0x00001000) +#define IICS_COUNT (4) + +#define USBPHY_VERSION (4) + +#define DSIM_BASE_ADDR (DISP0_MIPI_DSI_BASE_ADDR) +#define DSIM_LANE_COUNT (4) +#define DSIM_VERSION (2) + +#define EDP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define DP_BASE_ADDR (EDP_BASE_ADDR) +#define DISPLAYPORT_VERSION (3) + +#define ADBE_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define DISP_VERSION (5) + +#define AMP_BASE_ADDR (AMPS_0_DQ_BASE_ADDR) +#define AMP_SPACING (0x00020000) +#define AMP_CA_SPACING (0x00010000) + +#define CHIPID_BASE_ADDR (PMGR_BASE_ADDR + 0x2A000) + +#define GPIO_VERSION (3) +#define GPIO_GROUP_COUNT (25) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define AIC_VERSION (1) +#define AIC_INT_COUNT (192) + +#define PMGR_WDG_VERSION (1) + +#define USBOTG_BASE_ADDR (AUSB_OTG_BASE_ADDR) + +#define AES_AP_BASE_ADDR (ASIO_AES_BASE_ADDR) +#define AES_AP_VERSION (0) + +#if SUB_PLATFORM_S5L8970X +#define DART0_BASE_ADDR (PCI_BASE + 0x1002000) +#define DART1_BASE_ADDR (PCI_BASE + 0x2002000) +#define DART2_BASE_ADDR (PCI_BASE + 0x3002000) +#define DART3_BASE_ADDR (PCI_BASE + 0x4002000) + +#define PCIE_PORT0_DART_ID (0) +#define PCIE_PORT1_DART_ID (1) +#define PCIE_PORT2_DART_ID (2) +#define PCIE_PORT3_DART_ID (3) +#define NUM_DARTS (4) +#endif + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s5l8960x/include/platform/soc/miu.h b/platform/s5l8960x/include/platform/soc/miu.h new file mode 100644 index 0000000..2fa10e5 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/miu.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rTZSROMCTRL_ROMADDRREMAP (*(volatile u_int32_t *)(AMC_BASE_ADDR + 0x0904)) +#define rTZSROMCTRL_TZ0REGIONADDR (*(volatile u_int32_t *)(AMC_BASE_ADDR + 0x0908)) +#define rTZSROMCTRL_TZ1REGIONADDR (*(volatile u_int32_t *)(AMC_BASE_ADDR + 0x090C)) +#define rTZSROMCTRL_TZ0LOCK (*(volatile u_int32_t *)(AMC_BASE_ADDR + 0x0910)) +#define rTZSROMCTRL_TZ1LOCK (*(volatile u_int32_t *)(AMC_BASE_ADDR + 0x0914)) + + +#define ASIO_CLK_CTRL (0x100004) +#define rASIO_CLK_CTRL (*(volatile u_int32_t *)(SB_BASE_ADDR + ASIO_CLK_CTRL)) +#define ASIO_AKF_IDLE_CTRL (0xe00024) +#define rASIO_AKF_IDLE_CTRL (*(volatile u_int32_t *)(SB_BASE_ADDR + ASIO_AKF_IDLE_CTRL)) +#define DYN_CLK_GATING (0x49a0000) +#define rDYN_CLK_GATING (*(volatile u_int32_t *)(SB_BASE_ADDR + DYN_CLK_GATING)) +#define SIO_ASYNC_FIFO_SB_RD_RATE_LIMIT (0x49c0000) +#define rSIO_ASYNC_FIFO_SB_RD_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_ASYNC_FIFO_SB_RD_RATE_LIMIT)) +#define SIO_ASYNC_FIFO_SB_WR_RATE_LIMIT (0x49c0004) +#define rSIO_ASYNC_FIFO_SB_WR_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_ASYNC_FIFO_SB_WR_RATE_LIMIT)) +#define SIO_ASYNC_FIFO_SB_WGATHER (0x49c0010) +#define rSIO_ASYNC_FIFO_SB_WGATHER (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_ASYNC_FIFO_SB_WGATHER)) +#define SIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT (0x49e0000) +#define rSIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT)) +#define SIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT (0x49e0004) +#define rSIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT)) +#define SIO_DAPASYNC_FIFO_SB_WGATHER (0x49e0010) +#define rSIO_DAPASYNC_FIFO_SB_WGATHER (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_DAPASYNC_FIFO_SB_WGATHER)) +#define AIU_SB_ARBCFG (0x5010000) +#define rAIU_SB_ARBCFG (*(volatile u_int32_t *)(SB_BASE_ADDR + AIU_SB_ARBCFG)) +#define AIU_SB_CPG_CNTL (0x5010014) +#define rAIU_SB_CPG_CNTL (*(volatile u_int32_t *)(SB_BASE_ADDR + AIU_SB_CPG_CNTL)) + + +#define SOCBUSMUX_ARBCFG (0x0000) +#define rSOCBUSMUX_ARBCFG (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + SOCBUSMUX_ARBCFG)) +#define DWRRCFG_DISPMUX_BULK (0x0008) +#define rDWRRCFG_DISPMUX_BULK (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + DWRRCFG_DISPMUX_BULK)) +#define TLIMIT_LVL0_CAMERAMUX (0x0034) +#define rTLIMIT_LVL0_CAMERAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL0_CAMERAMUX)) +#define TLIMIT_LVL1_CAMERAMUX (0x0038) +#define rTLIMIT_LVL1_CAMERAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL1_CAMERAMUX)) +#define TLIMIT_LVL1_MEDIAMUX (0x0048) +#define rTLIMIT_LVL1_MEDIAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL1_MEDIAMUX)) +#define TLIMIT_LVL2_MEDIAMUX (0x004c) +#define rTLIMIT_LVL2_MEDIAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL2_MEDIAMUX)) +#define TLIMIT_LVL0_IOMUX (0x0054) +#define rTLIMIT_LVL0_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL0_IOMUX)) +#define TLIMIT_LVL1_IOMUX (0x0058) +#define rTLIMIT_LVL1_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL1_IOMUX)) +#define TLIMIT_LVL2_IOMUX (0x005c) +#define rTLIMIT_LVL2_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL2_IOMUX)) +#define TLIMIT_LVL3_IOMUX (0x0060) +#define rTLIMIT_LVL3_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL3_IOMUX)) +#define SOCBUSMUX_CPG_CNTL (0x0088) +#define rSOCBUSMUX_CPG_CNTL (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + SOCBUSMUX_CPG_CNTL)) + + +#define IOBUSMUX_ARBCFG (0x0000) +#define rIOBUSMUX_ARBCFG (*(volatile u_int32_t *)(IOBUSMUX_BASE_ADDR + IOBUSMUX_ARBCFG)) +#define IOBUSMUX_CPG_CNTL (0x001c) +#define rIOBUSMUX_CPG_CNTL (*(volatile u_int32_t *)(IOBUSMUX_BASE_ADDR + IOBUSMUX_CPG_CNTL)) + + +#define SWITCH_FAB_ARBCFG (0x0004) +#define rSWITCH_FAB_ARBCFG (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCH_FAB_ARBCFG)) +#define SWITCH_FAB_PIOLIMIT (0x0028) +#define rSWITCH_FAB_PIOLIMIT (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCH_FAB_PIOLIMIT)) +#define SWITCH_FAB_CPG_CNTL (0x0074) +#define rSWITCH_FAB_CPG_CNTL (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCH_FAB_CPG_CNTL)) + + +#define CP_DYN_CLK_GATING_CTRL (0x000c) +#define rCP_DYN_CLK_GATING_CTRL (*(volatile u_int32_t *)(CP_COM_BASE_ADDR + CP_DYN_CLK_GATING_CTRL)) + + +#define CPCOM_INT_NORM_REQUEST (0x0000) +#define rCP_COM_INT_NORM_REQUEST (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_REQUEST)) +#define CPCOM_INT_NORM_MASK_SET (0x0004) +#define rCP_COM_INT_NORM_MASK_SET (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_SET)) +#define CPCOM_INT_NORM_MASK_CLR (0x0008) +#define rCP_COM_INT_NORM_MASK_CLR (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_CLR)) + +#define LIO_MEMCACHE_DATASETID_OVERRIDE (0x1000) + + +#define MEDIABUSMUX_REGS_ARBCFG (0x000000) +#define MEDIABUSMUX_REGS_DWRRCFG_JPEG_BULK (0x000004) +#define MEDIABUSMUX_REGS_DWRRCFG_MSR_BULK (0x000008) +#define MEDIABUSMUX_REGS_DWRRCFG_VXE_LLT (0x00000c) +#define MEDIABUSMUX_REGS_DWRRCFG_VXE_BULK (0x000010) +#define MEDIABUSMUX_REGS_DWRRCFG_VXD_LLT (0x000014) +#define MEDIABUSMUX_REGS_DWRRCFG_VXD_BULK (0x000018) +#define MEDIABUSMUX_REGS_CPG_CNTL (0x00003c) +#define MEDIABUSMUX_REGS_CPG_CNTL (0x00003c) + +#define MSR_REGS_ARBCFG (0x000000) +#define MSR_REGS_CPG_CNTL (0x000014) +#define MSR_REGS_AW_TLIMIT (0x00001c) +#define MSR_REGS_MEMCACHE_DATASETID_OVERRIDE (0x001000) + +#define AJPEG_REGS_ARBCFG (0x000000) +#define AJPEG_REGS_CPG_CNTL (0x000014) +#define AJPEG_REGS_MEMCACHE_DATASETID_OVERRIDE (0x001000) + +#define VXE_REGS_ARBCFG (0x000000) +#define VXE_REGS_CPG_CNTL (0x000014) +#define VXE_REGS_AR_TLIMIT (0x000020) +#define VXE_REGS_MEMCACHE_HINT_OVERRIDE (0x001004) +#define VXE_REGS_MEMCACHE_DATASETID_OVERRIDE (0x001000) + +#define VENC_INT_IDLE_CTRL (0x030004) +#define VENC_INT_AxCACHE_REMAPPING_REG(_x,_n) (0x030018 + ((_x) * 8) + ((_n) * 4)) + +#define VXD_REGS_ARBCFG (0x000000) +#define VXD_REGS_CPG_CNTL (0x000014) +#define VXD_REGS_MEMCACHE_HINT_OVERRIDE (0x001004) +#define VXD_REGS_MEMCACHE_DATASETID_OVERRIDE (0x001000) + +#define VDEC_INT_IDLE_CTRL (0x030004) +#define VDEC_INT_AxCACHE_REMAPPING_REG(_x,_n) (0x030018 + ((_x) * 8) + ((_n) * 4)) + +#define CAMERABUSMUX_REGS_ARBCFG (0x000000) +#define CAMERABUSMUX_REGS_ISPKF_RT (0x000004) +#define CAMERABUSMUX_REGS_CPG_CNTL (0x00002c) + +#define ISP_DMA_REGS_ARBCFG (0x000000) +#define ISP_DMA_REGS_CPG_CNTL (0x000014) +#define ISP_DMA_REGS_BW_THRESHOLD (0x000018) +#define ISP_DMA_REGS_AW_LIMIT (0x00001c) +#define ISP_DMA_REGS_AR_LIMIT (0x000020) +#define ISP_DMA_REGS_MEMCACHE_DATASETID_OVERRIDE (0x01000) + +#define ISP_KF_REGS_ARBCFG (0x010000) +#define ISP_KF_REGS_CPG_CNTL (0x010014) +#define ISP_KF_REGS_MEMCACHE_DATASETID_OVERRIDE (0x011000) + +#define DISPBUSMUX_REGS_ARBCFG (0x000000) +#define DISPBUSMUX_REGS_DWRRCFG_DP1_BULK (0x000008) +#define DISPBUSMUX_REGS_CPG_CNTL (0x00001c) + +#define DISPLAYPIPE0_REGS_ARBCFG (0x000000) +#define DISPLAYPIPE0_REGS_CPG_CNTL (0x000014) +#define DISPLAYPIPE0_REGS_MEMCACHE_DATASETID_OVERRIDE (0x001000) + +#define DISPLAYPIPE1_REGS_ARBCFG (0x000000) +#define DISPLAYPIPE1_REGS_CPG_CNTL (0x000014) +#define DISPLAYPIPE1_REGS_MEMCACHE_DATASETID_OVERRIDE (0x001000) + +#define ANS_REGS_ARBCFG (0x000000) +#define ANS_REGS_CPG_CNTL (0x000014) +#define ANS_REGS_MEMCACHE_DATASETID_OVERRIDE (0x001000) +#define ANS_KF_TLIMIT_RD (0x020008) +#define ANS_KF_TLIMIT_WR (0x02000c) +#define ANS_ANC0_TLIMIT_RD (0x030008) +#define ANS_ANC0_TLIMIT_WR (0x03000c) +#define ANS_ANC1_TLIMIT_RD (0x031008) +#define ANS_ANC1_TLIMIT_WR (0x03100c) + +#define GFX_REGS_ARBCFG (0x000000) +#define GFX_REGS_CPG_CNTL (0x000014) + +#define GFX_IMG4_AFUSER_REGS_MCCFG_0 (0x000000) +#define GFX_IMG4_AFUSER_REGS_MCCFG_1 (0x000004) +#define GFX_IMG4_AFUSER_REGS_MCCFG_2 (0x000008) +#define GFX_IMG4_AFUSER_REGS_MCCFG_3 (0x00000C) +#define GFX_IMG4_AFUSER_REGS_MCCFG_4 (0x000010) +#define GFX_IMG4_AFUSER_REGS_MCCFG_5 (0x000014) +#define GFX_IMG4_AFUSER_REGS_MCCFG_6 (0x000018) +#define GFX_IMG4_AFUSER_REGS_MCCFG_7 (0x00001C) +#define GFX_IMG4_AFUSER_REGS_MCCFG_8 (0x000020) +#define GFX_IMG4_AFUSER_REGS_MCCFG_9 (0x000024) +#define GFX_IMG4_AFUSER_REGS_MCCFG_10 (0x000028) +#define GFX_IMG4_AFUSER_REGS_MCCFG_11 (0x00002C) +#define GFX_IMG4_AFUSER_REGS_MCCFG_12 (0x000030) +#define GFX_IMG4_AFUSER_REGS_MCCFG_13 (0x000034) +#define GFX_IMG4_AFUSER_REGS_MCCFG_14 (0x000038) +#define GFX_IMG4_AFUSER_REGS_MCCFG_15 (0x00003C) +#define GFX_IMG4_AFUSER_REGS_MCCFG_16 (0x000040) +#define GFX_IMG4_AFUSER_REGS_MCCFG_17 (0x000044) +#define GFX_IMG4_AFUSER_REGS_MCCFG_18 (0x000048) +#define GFX_IMG4_AFUSER_REGS_MCCFG_19 (0x00004C) +#define GFX_IMG4_AFUSER_REGS_MCCFG_20 (0x000050) +#define GFX_IMG4_AFUSER_REGS_MCCFG_21 (0x000054) +#define GFX_IMG4_AFUSER_REGS_MCCFG_22 (0x000058) +#define GFX_IMG4_AFUSER_REGS_MCCFG_23 (0x00005C) +#define GFX_IMG4_AFUSER_REGS_MCCFG_24 (0x000060) +#define GFX_IMG4_AFUSER_REGS_MCCFG_25 (0x000064) +#define GFX_IMG4_AFUSER_REGS_MCCFG_26 (0x000068) +#define GFX_IMG4_AFUSER_REGS_MCCFG_27 (0x00006C) +#define GFX_IMG4_AFUSER_REGS_MCCFG_28 (0x000070) +#define GFX_IMG4_AFUSER_REGS_MCCFG_29 (0x000074) +#define GFX_IMG4_AFUSER_REGS_MCCFG_30 (0x000078) +#define GFX_IMG4_AFUSER_REGS_MCCFG_31 (0x00007C) + +#define AUSB_REGS_RD_RATE_LIMIT (0x001000) +#define AUSB_REGS_WRALIMIT (0x001004) +#define AUSB_REGS_WGATHER (0x001010) + + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s5l8960x/include/platform/soc/pmgr.h b/platform/s5l8960x/include/platform/soc/pmgr.h new file mode 100644 index 0000000..9881070 --- /dev/null +++ b/platform/s5l8960x/include/platform/soc/pmgr.h @@ -0,0 +1,562 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include + +//////////////////////////////////////////////////////////// +// +// PMGR specific +// +//////////////////////////////////////////////////////////// + +#define PMGR_PLL_COUNT (6) + +#define rPMGR_PLL_CTL(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + ((_n) * 0x1000))) +#define PMGR_PLL_ENABLE (1 << 31) +#define PMGR_PLL_LOCKED (1 << 30) +#define PMGR_PLL_LOAD (1 << 29) +#define PMGR_PLL_EXT_BYPASS (1 << 27) +#define PMGR_PLL_ENABLED (1 << 26) +#define PMGR_PLL_BYP_ENABLED (1 << 25) +#define PMGR_PLL_M_SHIFT (12) +#define PMGR_PLL_M_MASK (0x1FF) +#define PMGR_PLL_P_SHIFT (4) +#define PMGR_PLL_P_MASK (0x1F) +#define PMGR_PLL_S_SHIFT (0) +#define PMGR_PLL_S_MASK (0xF) +#define PMGR_PLL_M(_m) (((_m) & PMGR_PLL_M_MASK) << PMGR_PLL_M_SHIFT) +#define PMGR_PLL_P(_p) (((_p) & PMGR_PLL_P_MASK) << PMGR_PLL_P_SHIFT) +#define PMGR_PLL_S(_s) (((_s) & PMGR_PLL_S_MASK) << PMGR_PLL_S_SHIFT) +#define PMGR_PLL_FREQ(_m, _p, _s) ((((_m) * OSC_FREQ) / (_p))/((_s) + 1)) + +#define rPMGR_PLL_CFG(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0004 + ((_n) * 0x1000))) +#define PMGR_PLL_OFF_MODE_SHIFT (30) +#define PMGR_PLL_OFF_MODE_MASK (0x3) +#define PMGR_PLL_VCO_OUT_SEL (1 << 27) +#define PMGR_PLL_LOCK_TIME_MASK (0xFFFF) +#define PMGR_PLL_LOCK_TIME(_n) (((_n) & PMGR_PLL_LOCK_TIME_MASK) << 0) + +#define rPMGR_PLL_ANA_PARAMS(_n, _p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0008 + ((_n) * 0x0004) + ((_p) * 0x1000))) +#define rPMGR_PLL_FD_CTL(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0010 + ((_n) * 0x1000))) +#define rPMGR_PLL_DEBUG(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0014 + ((_n) * 0x1000))) +#define rPMGR_PLL_DELAY_CTL(_n, _p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0018 + ((_n) * 0x0004) + ((_p) * 0x1000))) + +#define rPMGR_MCU_FIXED_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10000)) +#define rPMGR_MCU_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10004)) +#define rPMGR_MIPI_DSI_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10008)) +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1000C)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10010)) +#define rPMGR_NCO_ALG0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10014)) +#define rPMGR_NCO_ALG1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10018)) +#define rPMGR_HSICPHY_REF_12M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1001C)) +#define rPMGR_USB480_0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10020)) +#define rPMGR_USB480_1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10024)) +#define rPMGR_USB_OHCI_48M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10028)) +#define rPMGR_USB_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1002C)) +#define rPMGR_USB_FREE_60M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10030)) +#define rPMGR_ADSP_T_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10034)) +#define rPMGR_ADSP_P_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10038)) +#define rPMGR_ADSP_TS_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1003C)) +#define rPMGR_SIO_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10040)) +#define rPMGR_SIO_P_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10044)) +#define rPMGR_ISP_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10048)) +#define rPMGR_ISP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1004C)) +#define rPMGR_ISP_SENSOR0_REF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10050)) +#define rPMGR_ISP_SENSOR1_REF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10054)) +#define rPMGR_VDEC_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10058)) +#define rPMGR_VENC_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1005C)) +#define rPMGR_VID0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10060)) +#define rPMGR_DISP0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10064)) +#define rPMGR_DISP1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10068)) +#define rPMGR_AJPEG_IP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1006C)) +#define rPMGR_AJPEG_WRAP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10070)) +#define rPMGR_MSR_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10074)) +#define rPMGR_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10078)) +#define rPMGR_ANS_DLL_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1007C)) +#define rPMGR_ANS_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10080)) +#define rPMGR_ANC_LINK_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10084)) +#define rPMGR_LIO_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10088)) +#define rPMGR_MCA0_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1008C)) +#define rPMGR_MCA1_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10090)) +#define rPMGR_MCA2_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10094)) +#define rPMGR_MCA3_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10098)) +#define rPMGR_MCA4_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1009C)) +#define rPMGR_SEP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100A0)) +#define rPMGR_GPIO_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100A4)) +#define rPMGR_SPI0_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100A8)) +#define rPMGR_SPI1_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100AC)) +#define rPMGR_SPI2_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100B0)) +#define rPMGR_SPI3_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100B4)) +#define rPMGR_DEBUG_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100B8)) + +#define PMGR_FIRST_CLK_CFG (&rPMGR_MCU_FIXED_CLK_CFG) +#define PMGR_LAST_CLK_CFG (&rPMGR_DEBUG_CLK_CFG) +#define PMGR_CLK_CFG_COUNT (((((void *)(PMGR_LAST_CLK_CFG)) - ((void *)(PMGR_FIRST_CLK_CFG))) / 4) + 1) +#define PMGR_CLK_NUM(_r) (((void *)&(rPMGR_ ## _r ## _CLK_CFG) - ((void *)(PMGR_FIRST_CLK_CFG))) / 4) + +#define rPMGR_S0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10200)) +#define rPMGR_S1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10204)) +#define rPMGR_S2_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10208)) +#define rPMGR_S3_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1020C)) +#define rPMGR_ISP_REF0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10210)) +#define rPMGR_ISP_REF1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10214)) + +#define PMGR_FIRST_SPARE_CLK_CFG (&rPMGR_S0_CLK_CFG) +#define PMGR_LAST_SPARE_CLK_CFG (&rPMGR_ISP_REF1_CLK_CFG) +#define PMGR_SPARE_CLK_CFG_COUNT (((((void *)(PMGR_LAST_SPARE_CLK_CFG)) - ((void *)(PMGR_FIRST_SPARE_CLK_CFG))) / 4) + 1) + +#define rPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10300)) +#define rPMGR_CLK_DIVIDER_ACG_CFG1 (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10304)) +#define rPMGR_PLL_ACG_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10308)) + #define PMGR_ACG_CFG_PLLX_AUTO_DISABLE(_n) (1 << (_n)) + +#define PMGR_CLK_CFG_ENABLE (1 << 31) +#define PMGR_CLK_CFG_PENDING (1 << 30) +#define PMGR_CLK_CFG_PENDING_SHIFT (30) +#define PMGR_CLK_CFG_SRC_SEL_MASK (0x3F) +#define PMGR_CLK_CFG_CFG_SEL_SHIFT (16) +#define PMGR_CLK_CFG_SRC_SEL_SHIFT (24) +#define PMGR_CLK_CFG_SRC_SEL(_n) ((_n) << PMGR_CLK_CFG_SRC_SEL_SHIFT) +#define PMGR_CLK_CFG_DIVISOR_MASK (0x3F) +#define PMGR_CLK_CFG_DIVISOR(_n) ((_n) << 0) + +#define rPMGR_NCO_CLK_CFG(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x0)) +#define rPMGR_NCO_DIV_INT(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x4)) +#define rPMGR_NCO_DIV_FRAC_N1(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x8)) +#define rPMGR_NCO_DIV_FRAC_N2(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0xc)) +#define rPMGR_NCO_DIV_FRAC_PRIME(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x10)) + +#define PMGR_NUM_NCO 5 + +#define rPMGR_AGILE_CLK_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1b000)) + +#define kPMGR_GFX_STATE_MAX (16) +#define rPMGR_GFX_PERF_STATE_ENTRY(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + 0x1c000)) +#define rPMGR_GFX_PERF_STATE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1c200)) +#define rPMGR_GFX_PERF_STATE_SOCHOT (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1c300)) + +#define rPMGR_CPU0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20000)) +#define rPMGR_CPU1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20008)) +#define rPMGR_CPM_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20010)) +#define rPMGR_LIO_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20018)) +#define rPMGR_IOMUX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20020)) +#define rPMGR_AIC_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20028)) +#define rPMGR_DEBUG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20030)) +#define rPMGR_DWI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20038)) +#define rPMGR_GPIO_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20040)) +#define rPMGR_MCA0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20048)) +#define rPMGR_MCA1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20050)) +#define rPMGR_MCA2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20058)) +#define rPMGR_MCA3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20060)) +#define rPMGR_MCA4_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20068)) +#define rPMGR_PWM0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20070)) +#define rPMGR_I2C0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20078)) +#define rPMGR_I2C1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20080)) +#define rPMGR_I2C2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20088)) +#define rPMGR_I2C3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20090)) +#define rPMGR_SPI0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20098)) +#define rPMGR_SPI1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200A0)) +#define rPMGR_SPI2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200A8)) +#define rPMGR_SPI3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200B0)) +#define rPMGR_UART0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200B8)) +#define rPMGR_UART1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200C0)) +#define rPMGR_UART2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200C8)) +#define rPMGR_UART3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200D0)) +#define rPMGR_UART4_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200D8)) +#define rPMGR_UART5_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200E0)) +#define rPMGR_UART6_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200E8)) +#define rPMGR_SECUART0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200F0)) +#define rPMGR_SECUART1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x200F8)) +#define rPMGR_AES0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20100)) +#define rPMGR_SIO_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20108)) +#define rPMGR_SIO_P_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20110)) +#define rPMGR_HSIC0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20118)) +#define rPMGR_HSIC1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20120)) +#define rPMGR_HSIC2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20128)) +#define rPMGR_ISPSENS0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20130)) +#define rPMGR_ISPSENS1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20138)) +#define rPMGR_MCC_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20140)) +#define rPMGR_MCU_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20148)) +#define rPMGR_AMP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20150)) +#define rPMGR_USB_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20158)) +#define rPMGR_USBCTLREG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20160)) +#define rPMGR_USB2HOST0_OHCI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20168)) +#define rPMGR_USB2HOST0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20170)) +#define rPMGR_USB2HOST1_OHCI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20178)) +#define rPMGR_USB2HOST1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20180)) +#define rPMGR_USB_OTG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20188)) +#define rPMGR_SMX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20190)) +#define rPMGR_SF_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20198)) +#define rPMGR_CP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201A0)) +#define rPMGR_DISP_BUSMUX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201A8)) +#define rPMGR_DISP0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201B0)) +#define rPMGR_MIPI_DSI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201B8)) +#define rPMGR_DP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201C0)) +#define rPMGR_DISP1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201C8)) +#define rPMGR_ISP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201D0)) +#define rPMGR_MEDIA_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201D8)) +#define rPMGR_MSR_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201E0)) +#define rPMGR_JPG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201E8)) +#define rPMGR_VDEC_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201F0)) +#define rPMGR_VENC_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201F8)) +#define rPMGR_ANS_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20200)) +#define rPMGR_ANS_DLL_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20208)) +#define rPMGR_ADSP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20210)) +#define rPMGR_GFX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20218)) +#define rPMGR_SEP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20268)) + +#define PMGR_PS_RESET (1 << 31) +#define PMGR_PS_ACTUAL_PS_SHIFT (4) +#define PMGR_PS_ACTUAL_PS_MASK (0xF) +#define PMGR_PS_MANUAL_PS_MASK (0xF) +#define PMGR_PS_RUN_MAX (0xF) +#define PMGR_PS_CLOCK_OFF (0x4) +#define PMGR_PS_POWER_OFF (0x0) + +#define PMGR_FIRST_PS (&rPMGR_CPU0_PS) +#define PMGR_LAST_PS (&rPMGR_GFX_PS) +#define PMGR_PS_COUNT (((((void *)(PMGR_LAST_PS)) - ((void *)(PMGR_FIRST_PS))) / 8) + 1) +#define PMGR_PS_NUM(_r) (((void *)&(rPMGR_ ## _r ## _PS) - ((void *)(PMGR_FIRST_PS))) / 8) + +#define rPMGR_PWRGATE_CPU0_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20800)) + +#define rPMGR_PWRGATE_AMC_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20830)) +#define rPMGR_PWRGATE_AMC_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20834)) + +#define rPMGR_PWRGATE_USB_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20840)) +#define rPMGR_PWRGATE_USB_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20844)) + +#define rPMGR_PWRGATE_ACS_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20850)) +#define rPMGR_PWRGATE_ACS_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20854)) + +#define rPMGR_PWRGATE_DISP0_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20860)) +#define rPMGR_PWRGATE_DISP0_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20864)) + +#define rPMGR_PWRGATE_DISP1_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20870)) +#define rPMGR_PWRGATE_DISP1_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20874)) + +#define rPMGR_PWRGATE_ISP_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20880)) +#define rPMGR_PWRGATE_ISP_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20884)) + +#define rPMGR_PWRGATE_MEDIA_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20890)) +#define rPMGR_PWRGATE_MEDIA_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20894)) + +#define rPMGR_PWRGATE_DEC_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208a0)) +#define rPMGR_PWRGATE_DEC_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208a4)) + +#define rPMGR_PWRGATE_ENC_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208b0)) +#define rPMGR_PWRGATE_ENC_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208b4)) + +#define rPMGR_PWRGATE_ANS_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208c0)) +#define rPMGR_PWRGATE_ANS_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208c4)) + +#define rPMGR_PWRGATE_ADSP_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208d0)) +#define rPMGR_PWRGATE_ADSP_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208d4)) + +#define rPMGR_PWRGATE_GFX_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208e0)) +#define rPMGR_PWRGATE_GFX_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208e4)) + +#define rPMGR_PWRGATE_SEP_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208f0)) +#define rPMGR_PWRGATE_SEP_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x208f4)) + +#define rPMGR_MCU_ASYNC_RESET (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20a00)) + +#define rPMGR_VOLMAN_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c00)) +#define rPMGR_VOLMAN_SOC_VOLTAGE (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c10)) +#define rPMGR_VOLMAN_SRAM_VOLTAGE (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c14)) +#define rPMGR_VOLMAN_GFX_VOLTAGE (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c18)) +#define rPMGR_VOLMAN_CPU_VOLTAGE (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c1C)) +#define rPMGR_VOLMAN_SOC_DELAY (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c30)) +#define rPMGR_VOLMAN_SRAM_DELAY (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c34)) +#define rPMGR_VOLMAN_GFX_DELAY (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c38)) +#define rPMGR_VOLMAN_CPU_DELAY (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20c3C)) + +#define PMGR_VOLMAN_DISABLE_VOL_CHANGE (1 << 10) + +#define rPMGR_EMA_GFX0 (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x26010)) +#define rPMGR_EMA_GFX1 (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x26014)) + +#define rPMGR_CHIP_WDOG_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27000)) +#define rPMGR_CHIP_WDOG_RST_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27004)) +#define rPMGR_CHIP_WDOG_INTR_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27008)) +#define rPMGR_CHIP_WDOG_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2700c)) +#define rPMGR_SYS_WDOG_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27010)) +#define rPMGR_SYS_WDOG_RST_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27014)) +#define rPMGR_SYS_WDOG_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2701c)) + +#define rPMGR_SCRATCH(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x29000 + ((_n)*4))) +#define rPMGR_SCRATCH0 rPMGR_SCRATCH(0) /* Flags */ +#define rPMGR_SCRATCH1 rPMGR_SCRATCH(1) +#define rPMGR_SCRATCH2 rPMGR_SCRATCH(2) +#define rPMGR_SCRATCH3 rPMGR_SCRATCH(3) +#define rPMGR_SCRATCH4 rPMGR_SCRATCH(4) +#define rPMGR_SCRATCH5 rPMGR_SCRATCH(5) +#define rPMGR_SCRATCH6 rPMGR_SCRATCH(6) +#define rPMGR_SCRATCH7 rPMGR_SCRATCH(7) /* Consistent debug root pointer */ +#define rPMGR_SCRATCH8 rPMGR_SCRATCH(8) +#define rPMGR_SCRATCH9 rPMGR_SCRATCH(9) +#define rPMGR_SCRATCH10 rPMGR_SCRATCH(10) +#define rPMGR_SCRATCH11 rPMGR_SCRATCH(11) +#define rPMGR_SCRATCH12 rPMGR_SCRATCH(12) +#define rPMGR_SCRATCH13 rPMGR_SCRATCH(13) /* Memory info */ +#define rPMGR_SCRATCH14 rPMGR_SCRATCH(14) /* Boot Nonce 0 */ +#define rPMGR_SCRATCH15 rPMGR_SCRATCH(15) /* Boot Nonce 1 */ +#define rPMGR_SCRATCH16 rPMGR_SCRATCH(16) /* Boot Manifest Hash 0 */ +#define rPMGR_SCRATCH17 rPMGR_SCRATCH(17) /* Boot Manifest Hash 1 */ +#define rPMGR_SCRATCH18 rPMGR_SCRATCH(18) /* Boot Manifest Hash 2 */ +#define rPMGR_SCRATCH19 rPMGR_SCRATCH(19) /* Boot Manifest Hash 3 */ +#define rPMGR_SCRATCH20 rPMGR_SCRATCH(20) /* Boot Manifest Hash 4 */ +#define rPMGR_SCRATCH21 rPMGR_SCRATCH(21) +#define rPMGR_SCRATCH22 rPMGR_SCRATCH(22) +#define rPMGR_SCRATCH23 rPMGR_SCRATCH(23) + +#define rPMGR_THERMAL0_CTL0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B000)) +#define rPMGR_THERMAL0_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B004)) +#define rPMGR_THERMAL0_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B008)) +#define rPMGR_THERMAL0_CTL3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B00C)) +#define rPMGR_THERMAL0_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B010)) +#define rPMGR_THERMAL0_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B014)) +#define rPMGR_THERMAL0_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B018)) +#define rPMGR_THERMAL0_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B01C)) +#define rPMGR_THERMAL1_CTL0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B040)) +#define rPMGR_THERMAL1_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B044)) +#define rPMGR_THERMAL1_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B048)) +#define rPMGR_THERMAL1_CTL3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B04C)) +#define rPMGR_THERMAL1_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B050)) +#define rPMGR_THERMAL1_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B054)) +#define rPMGR_THERMAL1_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B058)) +#define rPMGR_THERMAL1_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2B05C)) + +#define rPMGR_SOCHOT_FAILSAFE_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C000)) +#define rPMGR_SOCHOT_FAILSAFE_TRIP_TEMP_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C010)) +#define rPMGR_SOCHOT_FAILSAFE_TRIP_TEMP_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C014)) +#define rPMGR_SOCHOT_FAILSAFE_ASSERT_COUNT_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C018)) +#define rPMGR_SOCHOT_FAILSAFE_ASSERT_COUNT_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C01C)) +#define rPMGR_SOCHOT_FAILSAFE_DEASSERT_COUNT_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C020)) +#define rPMGR_SOCHOT_FAILSAFE_DEASSERT_COUNT_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C024)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT0_COUNT_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C080)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT0_COUNT_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C084)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT1_COUNT_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C088)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT1_COUNT_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C08C)) + + +#define rPMGR_MISC_ACG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x32000)) + +enum { + PMGR_CLK_OSC = 0, + PMGR_CLK_PLL0, + PMGR_CLK_PLL1, + PMGR_CLK_PLL2, + PMGR_CLK_PLL3, + PMGR_CLK_PLL4, + PMGR_CLK_PLL5, + PMGR_CLK_CPU, + PMGR_CLK_MCU_FIXED, + PMGR_CLK_MCU, + PMGR_CLK_MIPI_DSI, + PMGR_CLK_NCO_REF0, + PMGR_CLK_NCO_REF1, + PMGR_CLK_NCO_ALG0, + PMGR_CLK_NCO_ALG1, + PMGR_CLK_HSICPHY_REF_12M, + PMGR_CLK_USB480_0, + PMGR_CLK_USB480_1, + PMGR_CLK_USB_OHCI_48M, + PMGR_CLK_USB, + PMGR_CLK_USB_FREE_60M, + PMGR_CLK_ADSP_T, + PMGR_CLK_ADSP_P, + PMGR_CLK_ADSP_TS, + PMGR_CLK_SIO_C, + PMGR_CLK_SIO_P, + PMGR_CLK_ISP_C, + PMGR_CLK_ISP, + PMGR_CLK_ISP_SENSOR0_REF, + PMGR_CLK_ISP_SENSOR1_REF, + PMGR_CLK_VDEC, + PMGR_CLK_VENC, + PMGR_CLK_VID0, + PMGR_CLK_DISP0, + PMGR_CLK_DISP1, + PMGR_CLK_AJPEG_IP, + PMGR_CLK_AJPEG_WRAP, + PMGR_CLK_MSR, + PMGR_CLK_AF, + PMGR_CLK_ANS_DLL, + PMGR_CLK_ANS_C, + PMGR_CLK_ANC_LINK, + PMGR_CLK_LIO, + PMGR_CLK_MCA0_M, + PMGR_CLK_MCA1_M, + PMGR_CLK_MCA2_M, + PMGR_CLK_MCA3_M, + PMGR_CLK_MCA4_M, + PMGR_CLK_SEP, + PMGR_CLK_GPIO, + PMGR_CLK_SPI0_N, + PMGR_CLK_SPI1_N, + PMGR_CLK_SPI2_N, + PMGR_CLK_SPI3_N, + PMGR_CLK_DEBUG, + PMGR_CLK_S0, + PMGR_CLK_S1, + PMGR_CLK_S2, + PMGR_CLK_S3, + PMGR_CLK_ISP_REF0, + PMGR_CLK_ISP_REF1, + PMGR_CLK_COUNT, + PMGR_CLK_NOT_SUPPORTED +}; + +#define PMGR_CLK_CFG_INDEX(_clk) ((_clk) - PMGR_CLK_MCU_FIXED) +//////////////////////////////////////////////////////////// +// +// CCC specific +// +//////////////////////////////////////////////////////////// + +#define CCC_PWRCTL_BASE (CCC_ROM_TABLE_BASE_ADDR + 0x220000) +#define CCC_CPM_THERMAL_BASE (CCC_ROM_TABLE_BASE_ADDR + 0x230000) + +#define rCCC_PRE_TD_TMR (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x008)) +#define rCCC_PRE_FLUSH_TMR (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x010)) + +#define rCCC_APSC_SCR (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x020)) +#define CCC_APSC_PENDING (1 << 31) +#define CCC_APSC_MANUAL_CHANGE(_d) ((1 << 25) | (((_d) & 0x7) << 22)) + + +#define rCCC_DVFM_CFG (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x040)) +#define rCCC_DVFM_SCR (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x048)) +#define rCCC_DVFM_CFG_SEL (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x050)) +#define rCCC_DVFM_DLY (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x058)) + +#define rCCC_PLL_CFG2 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0F8)) +#define CCC_PLL_CFG2_RELOCKBYS2_S4_MASK (0x6) +#define CCC_PLL_CFG2_RELOCKBYS2_S4_DIV2 (0x6) + +#define kDVFM_STATE_BYPASS (0) +#define kDVFM_STATE_SECUREROM (kDVFM_STATE_BYPASS + 1) +#define kDVFM_STATE_IBOOT (kDVFM_STATE_BYPASS + 2) +#define kDVFM_STATE_V0 (kDVFM_STATE_IBOOT + 0) +#define kDVFM_STATE_V1 (kDVFM_STATE_IBOOT + 1) +#define kDVFM_STATE_V2 (kDVFM_STATE_IBOOT + 2) +#define kDVFM_STATE_V3 (kDVFM_STATE_IBOOT + 3) +#define kDVFM_STATE_V4 (kDVFM_STATE_IBOOT + 4) + +#if SUB_TARGET_N51 || SUB_TARGET_N53 || SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 || SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M +#define kDVFM_STATE_VMAX (kDVFM_STATE_V4) +#define kDVFM_STATE_VNOM (kDVFM_STATE_V3) +#elif SUB_TARGET_J34 || SUB_TARGET_J34M || SUB_TARGET_J71 || SUB_TARGET_J72 || SUB_TARGET_J73 +#define kDVFM_STATE_VMAX (kDVFM_STATE_V4) +#define kDVFM_STATE_VNOM (kDVFM_STATE_V2) +#else +#define kDVFM_STATE_VMAX (kDVFM_STATE_V3) +#define kDVFM_STATE_VNOM (kDVFM_STATE_V2) +#endif + +#define kDVFM_STATE_VBOOST (kDVFM_STATE_VMAX) + +#define kDVFM_STATE_IBOOT_CNT (kDVFM_STATE_VMAX + 1) + +#define kVOLTAGE_STATES1_COUNT (kDVFM_STATE_VMAX - kDVFM_STATE_V0 + 1) +#define kVOLTAGE_STATES1_SIZE (kVOLTAGE_STATES1_COUNT*2) // Minimum size of voltage-state1 property in devicetree + +#define CCC_DVFM_STATE_COUNT (8) +#define rCCC_DVFM_ST(_n) (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x068 + ((_n) * 8))) + +#define CCC_DVFM_ST_PLL_P(_p) (((_p) & 0x1F) << 13) +#define CCC_DVFM_ST_PLL_M(_m) (((_m) & 0x1FF) << 4) +#define CCC_DVFM_ST_PLL_S(_s) (((_s) & 0xF) << 0) +#define CCC_DVFM_ST_SAFE_VOL_SHIFT (56) +#define CCC_DVFM_ST_VOLADJ0(_adj0) ((((uint64_t)_adj0) & 0x3F) << 30) +#define CCC_DVFM_ST_VOLADJ1(_adj1) ((((uint64_t)_adj1) & 0x3F) << 36) +#define CCC_DVFM_ST_VOLADJ2(_adj2) ((((uint64_t)_adj2) & 0x3F) << 42) +#define CCC_DVFM_ST_SAFEVOL(_svol) ((((uint64_t)_svol) & 0xFF) << CCC_DVFM_ST_SAFE_VOL_SHIFT) + +#define rCCC_EFUSE_DVFM(_n) (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0a8 + ((_n) * 8))) + +#define CCC_DVFM_CFG_TEMPTHRES0(_tt0) (((_tt0) & 0x7F) << 0) +#define CCC_DVFM_CFG_TEMPTHRES1(_tt1) (((_tt1) & 0x7F) << 7) +#define CCC_DVFM_CFG_TEMPOFFST0(_to0) (((_to0) & 0x7F) << 14) +#define CCC_DVFM_CFG_TEMPOFFST1(_to1) (((_to1) & 0x7F) << 21) + +#define rCCC_PWRCTRL_MSTR_PLLCTL (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0B8)) + +#define rCCC_PWRCTRL_PLL_SCR0 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0C0)) + +#define rCCC_PWRCTRL_PLL_SCR1 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0C8)) + + +#define rCCC_THRM0_CTL0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x00)) +#define rCCC_THRM0_CTL1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x08)) +#define rCCC_THRM0_CTL2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x10)) +#define rCCC_THRM0_CTL3 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x18)) +#define rCCC_THRM0_RD_BK0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x20)) +#define rCCC_THRM0_RD_BK1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x28)) +#define rCCC_THRM0_SUM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x30)) +#define rCCC_THRM0_SUM_CNT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x38)) +#define rCCC_THRM1_CTL0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x40)) +#define rCCC_THRM1_CTL1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x48)) +#define rCCC_THRM1_CTL2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x50)) +#define rCCC_THRM1_CTL3 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x58)) +#define rCCC_THRM1_RD_BK0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x60)) +#define rCCC_THRM1_RD_BK1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x68)) +#define rCCC_THRM1_SUM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x70)) +#define rCCC_THRM1_SUM_CNT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x78)) +#define rCCC_THRM_FSCTL (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x80)) +#define rCCC_THRM_FSTRIP_T0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x90)) +#define rCCC_THRM_FSTRIP_T1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x98)) +#define rCCC_THRM_FSASRT_CNT0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xA0)) +#define rCCC_THRM_FSASRT_CNT1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xA8)) +#define rCCC_THRM_FSDE_ASRT_CNT0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xB0)) +#define rCCC_THRM_FSDE_ASRT_CNT1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xB8)) +#define rCCC_THRM_FSHOT0_TSTAMP (*(volatile uint64_t*)(CCC_CPM_THERMAL_BASE + 0xC0)) +#define rCCC_THRM_FSHOT1_TSTAMP (*(volatile uint64_t*)(CCC_CPM_THERMAL_BASE + 0xC8)) +#define rCCC_DVFM_EFUSE_TADC0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xD0)) +#define rCCC_DVFM_EFUSE_TADC1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xD8)) +#define rCCC_THEM_EFUSE_TADC0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xE0)) +#define rCCC_THEM_EFUSE_TADC1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xE8)) +#define rCCC_DVFM_FSHOT_IDX (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0xF0)) + + +#define CCC_PLL_P_SHIFT (9) +#define CCC_PLL_P_MASK (0x1F) +#define CCC_PLL_M_SHIFT (18) +#define CCC_PLL_M_MASK (0x1FF) +#define CCC_PLL_S_SHIFT (0) +#define CCC_PLL_S_MASK (0xF) +#define CCC_PLL_M(_m) (((_m) & CCC_PLL_M_MASK) << CCC_PLL_M_SHIFT) +#define CCC_PLL_P(_p) (((_p) & CCC_PLL_P_MASK) << CCC_PLL_P_SHIFT) +#define CCC_PLL_S(_s) (((_s) & CCC_PLL_S_MASK) << CCC_PLL_S_SHIFT) +#define CCC_PLL_ENABLE (1 << 31) +#define CCC_PLL_LOCKED (1 << 29) +#define CCC_PLL_LOAD (1 << 27) + + +//////////////////////////////////////////////////////////// +// +// Externs +// +//////////////////////////////////////////////////////////// + +extern void pmgr_update_device_tree(DTNode *pmgr_node); +extern void pmgr_gfx_update_device_tree(DTNode *gfx_node); +void sochot_pmgr_update_device_tree(DTNode *node); +void sochot_ccc_update_device_tree(DTNode *node); +void temp_sensor_pmgr_update_device_tree(DTNode *node); +void temp_sensor_ccc_update_device_tree(DTNode *node); +void thermal_init(void); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/s5l8960x/include/platform/trampoline.h b/platform/s5l8960x/include/platform/trampoline.h new file mode 100644 index 0000000..190ee09 --- /dev/null +++ b/platform/s5l8960x/include/platform/trampoline.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include + +/* ROM related registers in AMC space */ + +#define SECURITY_REG (AMC_BASE_ADDR + 0x900) +#define ROM_READ_DISABLE (1 << 0) + +#define REMAP_REG (AMC_BASE_ADDR + 0x904) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s5l8960x/include/platform/usbconfig.h b/platform/s5l8960x/include/platform/usbconfig.h new file mode 100644 index 0000000..ae67888 --- /dev/null +++ b/platform/s5l8960x/include/platform/usbconfig.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +/* + * per Alcatraz Tunables 0.23: + */ +#define USBPHY_OTGTUNE0 (0x374493F3) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +/* + * Do we need to extend EHCI DMA Address register with additional bits + * as per AUSBPL301_Widgets Register Specification + */ +#define USBEHCI_ADDR_EXT_WIDGET_EN 1 + +#ifdef WITH_TARGET_USB_CONFIG +#include +#endif /* WITH_TARGET_USB_CONFIG */ + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s5l8960x/init.c b/platform/s5l8960x/init.c new file mode 100644 index 0000000..0b0ef3e --- /dev/null +++ b/platform/s5l8960x/init.c @@ -0,0 +1,1638 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_CONSISTENT_DBG +#include +#endif +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#if WITH_HW_SEP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_PLATFORM_ERROR_HANDLER +#include +#endif +#include +#include +#include +#include +#include + +static void platform_init_boot_strap(void); +static int32_t platform_bootprep_darwin(bool resume); +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val); +static int power_convert_dwi_to_mv_fpga(unsigned int buck, u_int32_t dwival); +static void platform_relocate_securerom(void); + +static uint8_t boot_debug; +static bool gDisplayEnabled; + +int platform_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + /* Verify that the fuses and SecureROM R/W access has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile u_int32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) + panic("Fuses are unlocked or SecureROM is enabled\n"); +#endif + +#if PRODUCT_IBSS || PRODUCT_LLB + /* + * H6 B0 AP-ROM doesn't pass forward ObjectManifestHashValid Flag. Set it here. + * Object manifest hash passed forward by ROM is not valid for image with no manifest. + * ROM executed manifest-less image, if Mix-n-Match is allowed and keys are disabled. + */ + if (chipid_get_chip_revision() < CHIP_REVISION_C0) { + bool mix_n_match_allowed = ((rPMGR_SCRATCH0 & kPlatformScratchFlagVerifyManifestHash) == 0); + bool keys_disabled = platform_keys_disabled(~0, ~0); + bool manifest_less_image = (mix_n_match_allowed && keys_disabled); + + if (!manifest_less_image) + rPMGR_SCRATCH0 |= kPlatformScratchFlagObjectManifestHashValid; + } + +#endif + + /* Enable more Cyclone specific errors */ + ccc_enable_custom_errors(); + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8960x pmgr driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif + +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif + +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); + debug_enable_uarts(3); +#endif + +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif + + // Only B0 and onwards are supported + if (platform_get_chip_revision() < CHIP_REVISION_B0) platform_not_supported(); + + thermal_init(); + +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + + return 0; +} + + +int platform_late_init(void) +{ +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); + + /* turn off DEBUG clock if debug-soc nvram is not true */ + clock_gate(CLK_DEBUG, env_get_bool("debug-soc", false)); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_HW_AMC + extern void mcu_late_init(void); + mcu_late_init(); +#endif + +#if WITH_CSI + csi_late_init(); +#endif + + return 0; +} + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { +#if WITH_HW_DISPLAY_PMU + display_pmu_init(); +#endif + + if (!displayInitOnce) { + platform_quiesce_display(); + clock_gate(CLK_DISP_BUSMUX, true); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + + power_backlight_enable(backlight_level); +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + addr_t base_rounded = *base; + addr_t end_rounded = *base + *size; + size_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_HW_ASP + return (asp_nand_open()); +#else + return 0; +#endif +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + +#if WITH_CSI + csi_quiesce(target); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + quiesce_clocks = true; +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ + +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + clock_gate(CLK_DISP_BUSMUX, true); + + if (display_quiesce(true) == ENXIO) { + clock_gate(CLK_DISP_BUSMUX, false); + } +#endif + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + uint32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: +#if WITH_PAINT + if (paint_color_map_is_invalid()) + panic("Previous DClr errors prevent OS booting"); +#endif + platform_quiesce_display(); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; + break; + + case BOOT_DARWIN: +#if WITH_PAINT + if (paint_color_map_is_invalid()) + panic("Previous DClr errors prevent OS booting"); +#endif + platform_bootprep_darwin(false); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: + platform_quiesce_display(); + break; +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + platform_relocate_securerom(); + miu_select_remap(REMAP_SRAM); +#endif + break; + + case BOOT_MONITOR: + /* clean-invalidate TZ0 & TZ1 regions */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ1_BASE, TZ1_SIZE); + + /* program values */ + rTZSROMCTRL_TZ1REGIONADDR = ((((TZ1_BASE + TZ1_SIZE - 1) >> 20) & 0x3fff) << 16) | (((TZ1_BASE >> 20) & 0x3fff) << 0); + break; + + case BOOT_UNKNOWN: + platform_quiesce_display();; + break; + + default: + ; // do nothing + } + + /* make sure that fuse lock bit is set. */ + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + /* Disable Cyclone specific errors enabled earlier in the boot */ + ccc_disable_custom_errors(); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + +#if APPLICATION_SECUREROM + arm_mmu_map_rx(VROM_BASE, VROM_LEN); + arm_mmu_map_rw(SRAM_BASE, SRAM_LEN); + + // XXX put heap guard in though, and RO pagetables +#else + // Figure out where the linker put our various bits + uintptr_t text_end_aligned = ((uintptr_t)&_text_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + size_t text_size = text_end_aligned - (uintptr_t)&_text_start; + + RELEASE_ASSERT(text_end_aligned <= (uintptr_t)&_data_start); +#if PRODUCT_LLB || PRODUCT_IBSS + arm_mmu_map_rw(SDRAM_BASE, SDRAM_LEN); + // Make an uncached mapping to DRAM (used during memory calibration) + arm_mmu_map_range(SDRAM_BASE_UNCACHED, SDRAM_BASE, SDRAM_LEN, kARMMMUDeviceRW); + + // map through to end of heap read/write + arm_mmu_map_rw(SRAM_BASE, HEAP_END - SRAM_BASE); + + // __TEXT is read/execute, __DATA is read/write + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, PAGE_TABLES_BASE - text_end_aligned); + + // skip mapping the page tables so that they can't be modified + + // map the stacks read-write + arm_mmu_map_rw(STACKS_BASE, SRAM_BASE + SRAM_LEN - STACKS_BASE); +#else + // Most of DRAM gets mapped read/write + arm_mmu_map_rw(SDRAM_BASE, (uintptr_t)&_text_start - SDRAM_BASE); + + // only the text section should be executable, and it should be read only + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, PAGE_TABLES_BASE - text_end_aligned); + + // skip mapping the page tables so that they can't be modified + + // map the stacks read-write + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); + + // map the boot trampoline read/execute + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + + // map the heap read-write, leaving a hole at the end + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + RELEASE_ASSERT(HEAP_BASE + HEAP_SIZE == HEAP_GUARD); + + // and then everything up to the end of DRAM is read/write again + arm_mmu_map_rw(IBOOT_BASE + IBOOT_SIZE, SDRAM_END - (IBOOT_BASE + IBOOT_SIZE)); + +#if DEBUG_BUILD + // Create a virtual mapping for SRAM to allow SecureROM testing + arm_mmu_map_rw(SRAM_BASE, SRAM_LEN); +#endif +#endif +#endif + + // map IO + arm_mmu_map_device_rw(IO_BASE, IO_SIZE); +} + +int platform_init(void) +{ +#if defined(UNUSED_MEMORY_BASE) && (UNUSED_MEMORY_SIZE > 0) + bzero((void *)UNUSED_MEMORY_BASE, UNUSED_MEMORY_SIZE); +#endif + +#if WITH_PLATFORM_ERROR_HANDLER + platform_enable_error_handler(); +#endif + +#if WITH_CONSISTENT_DBG && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + consistent_debug_init(); +#endif +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_ANC_FIRMWARE + anc_firmware_init(); +#endif + +#if WITH_HW_ASP && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + csi_init(CSI_COPROC_ANS); /* coproc switchboard used by nand driver to communicate with ans iop */ + asp_init(); +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + uint32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +uint32_t platform_set_performance(uint32_t performance_level) +{ + uint32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_CPU); + memcpy(propData, &freq, propSize); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_MEM); + memcpy(propData, &freq, propSize); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_BUS); + memcpy(propData, &freq, propSize); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_PERIPH); + memcpy(propData, &freq, propSize); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_FIXED); + memcpy(propData, &freq, propSize); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_TIMEBASE); + memcpy(propData, &freq, propSize); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(uint32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the gfx node + if (FindNode(0, "arm-io/sgx", &node)) { + pmgr_gfx_update_device_tree(node); + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + + // Find the sochot0 and 1 nodes and override/augment EDT as needed + if (FindNode(0, "arm-io/sochot0", &node)) { + sochot_pmgr_update_device_tree(node); + } + if (FindNode(0, "arm-io/sochot1", &node)) { + sochot_ccc_update_device_tree(node); + } + + // Find the PMGR and CCC temperature sensors and override/augment EDT as needed + if (FindNode(0, "arm-io/tempsensor0", &node)) { + temp_sensor_pmgr_update_device_tree(node); + } + if (FindNode(0, "arm-io/tempsensor1", &node)) { + temp_sensor_pmgr_update_device_tree(node); + } + if (FindNode(0, "arm-io/tempsensor2", &node)) { + temp_sensor_ccc_update_device_tree(node); + } + if (FindNode(0, "arm-io/tempsensor3", &node)) { + temp_sensor_ccc_update_device_tree(node); + } + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + + return target_update_device_tree(); +} + +#endif + +uint32_t platform_get_board_id(void) +{ + uint32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +uint32_t platform_get_boot_config(void) +{ + uint32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, uint32_t *boot_flag, uint32_t *boot_arg) +{ + uint32_t boot_config = platform_get_boot_config(); + + /* S5L8960X supports one boot device then USB-DFU per boot config */ + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case 0: /* SPI 0 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 1: /* SPI 0 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case 2: /* ANS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 3: /* ANS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + +/* case 4-15: Unused */ + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == 1) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + uint32_t enable; + uint32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO( 9, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO( 9, 3), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO( 9, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO( 9, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO( 9, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, uint32_t boot_arg) +{ + const struct boot_interface_pin *pins0 = 0; + const struct boot_interface_pin *pins1 = 0; + uint32_t cnt, func, pin_count0 = 0, pin_count1 = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins0 = spi0_boot_interface_pins; + pin_count0 = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_ANC_BOOT + case BOOT_DEVICE_NAND : + /* NAND pins are off to ASP */ + break; +#endif /* WITH_ANC_BOOT */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count0; cnt++) { + if (enable) { + pin = pins0[pin_count0 - 1 - cnt].pin; + func = pins0[pin_count0 - 1 - cnt].enable; + } else { + pin = pins0[cnt].pin; + func = pins0[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } + + for (cnt = 0; cnt < pin_count1; cnt++) { + if (enable) { + pin = pins1[pin_count1 - 1 - cnt].pin; + func = pins1[pin_count1 - 1 - cnt].enable; + } else { + pin = pins1[cnt].pin; + func = pins1[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 1 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +uint64_t platform_get_nonce(void) +{ + uint64_t nonce; + uint32_t *nonce_words = (uint32_t *)&nonce; + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +int32_t platform_get_sep_nonce(uint8_t *nonce) +{ +#if WITH_HW_SEP + return sep_client_get_nonce(nonce); +#else + return -1; +#endif +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return true; +} + +uint32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ + return gpio_read(GPIO_FORCE_DFU); +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(uint32_t key_selector, uint32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +void platform_disable_keys(uint32_t gid, uint32_t uid) +{ + // Disable requested GID and UID in SIO-AES + extern void aes_ap_disable_keys(uint32_t gid, uint32_t uid); + aes_ap_disable_keys(gid, uid); + + // Disable UID in ANS, if UID disable is requested + // XXX TODO: missing UID in ANS +} + +bool platform_keys_disabled(uint32_t gid, uint32_t uid) +{ + bool result; + + // Check SIO + extern bool aes_ap_keys_disabled(uint32_t gid, uint32_t uid); + result = aes_ap_keys_disabled(gid, uid); + + // Check ANS + // XXX TODO: missing ANS piece + + return result; +} + +void platform_demote_production() +{ + chipid_clear_production_mode(); +} + +#if APPLICATION_IBOOT +uint64_t platform_get_memory_size(void) +{ + uint64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (rPMGR_SCRATCH13 & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +uint8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 28) & 0xf); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info(uint8_t manuf_id, uint64_t memory_size) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 28) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +#endif + +extern void boot_handoff_trampoline(void *entry, void *arg); + +void *platform_get_boot_trampoline(void) +{ +#ifdef BOOT_TRAMPOLINE_BASE + return (void *)BOOT_TRAMPOLINE_BASE; +#else + return (void *)boot_handoff_trampoline; +#endif +} + +int32_t platform_restore_system(void) +{ + // XXX kSleepTokenKernelOffset = 0 + uint32_t *signature = (uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0); + +#if WITH_CONSISTENT_DBG + consistent_debug_resume(); +#endif + + power_will_resume(); + + dprintf(DEBUG_INFO, "restore_system: signature[0]: 0x%08x, signature[1]: 0x%08x\n", + signature[0], signature[1]); + + if ((signature[0] != 'MOSX') || (signature[1] != 'SUSP')) return -1; + + signature[0] = 0; + signature[1] = 0; + + platform_bootprep_darwin(true); + + /* Jump to reset vector (first address of physical page of l4 or kernel). Our memory layout expects TZ0 -> TZ1 -> Kernel memory */ + dprintf(DEBUG_INFO, "restoring kernel\n"); + + prepare_and_jump(BOOT_DARWIN_RESTORE, (void *)TZ1_BASE, NULL); + + /* shouldn't get here */ + panic("returned from restore_system\n"); +} + +void platform_asynchronous_exception(void) +{ + ccc_handle_asynchronous_exception(); +} + +int32_t platform_get_boot_manifest_hash(uint8_t *boot_manifest_hash) +{ + RELEASE_ASSERT(boot_manifest_hash != NULL); + + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagObjectManifestHashValid) != 0) { + ((uint32_t *)boot_manifest_hash)[0] = rPMGR_SCRATCH16; + ((uint32_t *)boot_manifest_hash)[1] = rPMGR_SCRATCH17; + ((uint32_t *)boot_manifest_hash)[2] = rPMGR_SCRATCH18; + ((uint32_t *)boot_manifest_hash)[3] = rPMGR_SCRATCH19; + ((uint32_t *)boot_manifest_hash)[4] = rPMGR_SCRATCH20; + + return 0; + } + + return -1; +} + +int32_t platform_set_boot_manifest_hash(const uint8_t *boot_manifest_hash) +{ + if(boot_manifest_hash != NULL) { + rPMGR_SCRATCH16 = ((uint32_t *)boot_manifest_hash)[0]; + rPMGR_SCRATCH17 = ((uint32_t *)boot_manifest_hash)[1]; + rPMGR_SCRATCH18 = ((uint32_t *)boot_manifest_hash)[2]; + rPMGR_SCRATCH19 = ((uint32_t *)boot_manifest_hash)[3]; + rPMGR_SCRATCH20 = ((uint32_t *)boot_manifest_hash)[4]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagObjectManifestHashValid; + } + else { + rPMGR_SCRATCH16 = 0; + rPMGR_SCRATCH17 = 0; + rPMGR_SCRATCH18 = 0; + rPMGR_SCRATCH19 = 0; + rPMGR_SCRATCH20 = 0; + + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagObjectManifestHashValid; + } + + return 0; +} + +bool platform_get_mix_n_match_prevention_status(void) +{ + return ((rPMGR_SCRATCH0 & kPlatformScratchFlagVerifyManifestHash) ? true : false); +} + +void platform_set_mix_n_match_prevention_status(bool mix_n_match_prevented) +{ + if (mix_n_match_prevented) + rPMGR_SCRATCH0 |= kPlatformScratchFlagVerifyManifestHash; + else + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagVerifyManifestHash; +} + +void platform_set_consistent_debug_root_pointer(uint32_t root) +{ + rPMGR_SCRATCH7 = root; +} + +int platform_convert_voltages(int buck, u_int32_t count, u_int32_t *voltages) +{ +#if SUPPORT_FPGA + u_int32_t index; + for (index = 0; index < count; index++) + power_get_buck_value_fpga(buck, voltages[index], &voltages[index]); + return 0; +#elif WITH_HW_POWER + u_int32_t index; + + if (voltages == 0) return -1; + + for (index = 0; index < count; index++) { + if (0 != power_get_buck_value(buck, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +int platform_get_cpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cnt); + } + + return 0; +} + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = PANIC_BASE; + break; + + case kMemoryRegion_StorageProcessor: + base = ASP_BASE; + break; + + case kMemoryRegion_SecureProcessor: + base = TZ0_BASE; + break; + + case kMemoryRegion_Monitor: + base = TZ1_BASE; + break; + + case kMemoryRegion_Kernel: + base = TZ0_BASE + TZ0_SIZE; + break; + + case kMemoryRegion_PageTables: + base = PAGE_TABLES_BASE; + break; + + case kMemoryRegion_Heap: + base = HEAP_BASE; + break; + + case kMemoryRegion_Stacks: + base = STACKS_BASE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + base = CONSISTENT_DEBUG_BASE; + break; + + case kMemoryRegion_SleepToken: + base = SLEEP_TOKEN_BUFFER_BASE; + break; + + case kMemoryRegion_Display: + base = PANIC_BASE - platform_get_memory_region_size(kMemoryRegion_Display); + break; + + case kMemoryRegion_iBoot: + base = IBOOT_BASE; + break; +#endif + + default: + base = (uintptr_t)-1; + break; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + + case kMemoryRegion_StorageProcessor: + size = ASP_SIZE; + break; + + case kMemoryRegion_SecureProcessor: + size = TZ0_SIZE; + break; + + case kMemoryRegion_Monitor: + size = TZ1_SIZE; + break; + + case kMemoryRegion_Kernel: + size = platform_get_memory_region_base(kMemoryRegion_Display) - platform_get_memory_region_base(kMemoryRegion_Kernel); + break; + + case kMemoryRegion_PageTables: + size = PAGE_TABLES_SIZE; + break; + + case kMemoryRegion_Heap: + size = HEAP_SIZE; + break; + + case kMemoryRegion_Stacks: + size = STACKS_SIZE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + size = CONSISTENT_DEBUG_SIZE; + break; + + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; + + case kMemoryRegion_Display: + size = platform_get_display_memory_size(); + ASSERT(size != 0); + break; + + case kMemoryRegion_iBoot: + size = IBOOT_SIZE; + break; +#endif + + default: + size = (size_t)-1; + break; + } + + return size; +} + +int platform_get_gpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_gpu_voltage(cnt); + } + + return 0; +} + +/* + * Gets equivalent mV for a given DWI value for a particular buck. + * PMU code should handle the special case for GPU buck. + */ +int platform_get_dwi_to_mv(int buck, u_int32_t dwival) +{ +#if SUPPORT_FPGA + return power_convert_dwi_to_mv_fpga(buck, dwival); +#elif WITH_HW_POWER + return power_convert_dwi_to_mv(buck, dwival); +#else + return -1; +#endif +} + +#if WITH_TARGET_CONFIG + +// The target's rules.mk sets the high SoC voltage point +#ifndef TARGET_BOOT_SOC_VOLTAGE +#error TARGET_BOOT_SOC_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} + +// The target's rules.mk sets the high CPU voltage point +#ifndef TARGET_BOOT_CPU_VOLTAGE +#error TARGET_BOOT_CPU_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_BOOT_CPU_VOLTAGE); +} + +// The target's rules.mk sets the high RAM voltage point +#ifndef TARGET_BOOT_RAM_VOLTAGE +#error TARGET_BOOT_RAM_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_ram_voltage(void) +{ + return chipid_get_ram_voltage(TARGET_BOOT_RAM_VOLTAGE); +} + +#endif + +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = platform_get_base_soc_voltage(); + } + + return 0; +} + +static void platform_init_boot_strap(void) +{ + uint32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG3, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG3) << 3) | + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +static int32_t platform_bootprep_darwin(bool resume) +{ + /* 1. Setup trustzones */ + + if (!resume) { + /* clean-invalidate TZ0 & TZ1 regions */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ0_BASE, TZ0_SIZE); + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ1_BASE, TZ1_SIZE); + + /* create sleep token */ + /* already created by load_kernelcache call */ + } + else { + /* validate sleep token */ + if (!security_validate_sleep_token(SLEEP_TOKEN_BUFFER_BASE + kSleepTokeniBootOffset)) return -1; + } + + /* program values */ + rTZSROMCTRL_TZ0REGIONADDR = ((((TZ0_BASE + TZ0_SIZE - 1) >> 20) & 0x3fff) << 16) | (((TZ0_BASE >> 20) & 0x3fff) << 0); + rTZSROMCTRL_TZ1REGIONADDR = ((((TZ1_BASE + TZ1_SIZE - 1) >> 20) & 0x3fff) << 16) | (((TZ1_BASE >> 20) & 0x3fff) << 0); + + /* lock TZ0 & TZ1 regions */ + rTZSROMCTRL_TZ0LOCK = (1 << 0); + if ((rTZSROMCTRL_TZ0LOCK & 1) == 0) { + panic("TZ0 failed to lock\n"); + } + rTZSROMCTRL_TZ1LOCK = (1 << 0); + if ((rTZSROMCTRL_TZ1LOCK & 1) == 0) { + panic("TZ1 failed to lock\n"); + } + + /* 2. Override IO_RVBAR */ + + ccc_override_and_lock_iorvbar(TZ1_BASE); + + return 0; +} + +static void platform_relocate_securerom(void) +{ +#if WITH_HW_MIU && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + size_t len; + + // Get the size of the downloaded SecureROM image + len = env_get_uint("filesize", 0); + if (len == 0) + panic("filesize variable invalid or not set, aborting\n"); + + // Move the SecureROM image into place + dprintf(DEBUG_INFO, "relocating 0x%lx byte SecureROM image from SDRAM to SRAM\n", len); + memcpy((void *)SRAM_BASE, (void *)SDRAM_BASE, len); +#endif +} + +#if SUPPORT_FPGA +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val) +{ + if (mv == 0) { + *val = 0; + } else { + *val = (((mv-600)*1000)+3124)/3125; + } + return; +} + +static int power_convert_dwi_to_mv_fpga(unsigned int buck, u_int32_t dwival) +{ + int val = 0; +#if APPLICATION_IBOOT +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + if (buck == BUCK_GPU) { + val = (dwival == 0) ? 0 : (600000 + (3125 * dwival))/1000; + } +#endif + return val; +} +#endif + +#if defined(WITH_MENU) && WITH_MENU + +int do_sleep_token_test(int argc, struct cmd_arg *args) +{ + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0; + + security_create_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90); + + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0x12345678; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0xaabbccdd; + dprintf(DEBUG_INFO, "original info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + if (security_validate_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90) == false) { + dprintf(DEBUG_INFO, "failed to validate token\n"); + return 0; + } + + dprintf(DEBUG_INFO, "saved info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + return 0; +} + +MENU_COMMAND_DEBUG(sleep_token, do_sleep_token_test, "sleep token test - creates and validate it", NULL); + +#endif + +static int get_total_leakage(int argc, struct cmd_arg *args) +{ + dprintf(DEBUG_INFO, "total leakage: %dmA\n", chipid_get_total_rails_leakage()); + return 0; +} +MENU_COMMAND_DEBUG(leakage, get_total_leakage, "total rails leakage read from fuse", NULL); diff --git a/platform/s5l8960x/miu/miu.c b/platform/s5l8960x/miu/miu.c new file mode 100644 index 0000000..0342201 --- /dev/null +++ b/platform/s5l8960x/miu/miu.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void miu_configure_bridge(const u_int32_t *bridge_settings); + +#define STATIC_BRIDGE_SHIFT (28) +#define STATIC_BRIDGE_MASK ((1 << STATIC_BRIDGE_SHIFT) - 1) +#define SB_WIDGETS (0 << STATIC_BRIDGE_SHIFT) +#define SOCBUSMUX_WIDGETS (1 << STATIC_BRIDGE_SHIFT) +#define IOBUSMUX_WIDGETS (2 << STATIC_BRIDGE_SHIFT) +#define SWITCH_FAB_WIDGETS (3 << STATIC_BRIDGE_SHIFT) +#define CP_WIDGETS (4 << STATIC_BRIDGE_SHIFT) +#define LIO_WIDGETS (5 << STATIC_BRIDGE_SHIFT) +#define ANS_WIDGETS (6 << STATIC_BRIDGE_SHIFT) + +static const u_int64_t bridge_registers[] = { + SB_BASE_ADDR, + SOC_BUSMUX_BASE_ADDR, + IOBUSMUX_BASE_ADDR, + SWTCH_FAB_BASE_ADDR, + CP_COM_BASE_ADDR, + LIO_AFC_AIU_BASE_ADDR, + ANS_AFC_AIU_BASE_ADDR +}; + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static const u_int32_t bridge_settings_static[] = { + + SB_WIDGETS | ASIO_CLK_CTRL, 0x03000102, + + SB_WIDGETS | DYN_CLK_GATING, (0x30 << 16) | (0x1 << 4) | (0x1 << 3) | (0x1 << 0), + SB_WIDGETS | SIO_ASYNC_FIFO_SB_RD_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_ASYNC_FIFO_SB_WR_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_ASYNC_FIFO_SB_WGATHER, (0x1 << 8), + + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_WGATHER, (0x1 << 8), + + SB_WIDGETS | AIU_SB_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 12) | 0x4, + 0,0, + + SOCBUSMUX_WIDGETS | DWRRCFG_DISPMUX_BULK, (0x51 << 8) | (0x41 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL0_CAMERAMUX, (0x40 << 8) | (0xff << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_CAMERAMUX, (0x20 << 8) | (0x80 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_MEDIAMUX, (0x60 << 8) | (0x20 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL2_MEDIAMUX, (0x40 << 8) | (0x10 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL0_IOMUX, 0x40, + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_IOMUX, 0x40, + SOCBUSMUX_WIDGETS | TLIMIT_LVL2_IOMUX, 0x30, + SOCBUSMUX_WIDGETS | TLIMIT_LVL3_IOMUX, 0x20, + SOCBUSMUX_WIDGETS | SOCBUSMUX_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 12) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + IOBUSMUX_WIDGETS | IOBUSMUX_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 12) | (0x1 << 10) | (0x4 << 0), + 0,0, + + SWITCH_FAB_WIDGETS | SWITCH_FAB_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 12) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + CP_WIDGETS | CP_DYN_CLK_GATING_CTRL, (0x1 << 4) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1) | (0x1 << 0), + 0,0, + + + LIO_WIDGETS | LIO_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + 0,0, +}; +#endif // (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +// Alert: The ordering effects the device tree entries under pmgr node's reg dictionary. +// If you touch this table, and DISPLAY0 index gets changed, please update miu_update_device_tree. +#if WITH_DEVICETREE && !SUPPORT_FPGA +static const u_int32_t bridge_settings_dynamic[] = { + MEDIABUSMUX_REGS_DWRRCFG_JPEG_BULK, (0x28 << 8) | (0x20 << 0), + MEDIABUSMUX_REGS_DWRRCFG_MSR_BULK, (0x35 << 8) | (0x2a << 0), + MEDIABUSMUX_REGS_DWRRCFG_VXE_LLT, (0x14 << 8) | (0x10 << 0), + MEDIABUSMUX_REGS_DWRRCFG_VXE_BULK, (0x67 << 8) | (0x52 << 0), + MEDIABUSMUX_REGS_DWRRCFG_VXD_LLT, (0x14 << 8) | (0x10 << 0), + MEDIABUSMUX_REGS_DWRRCFG_VXD_BULK, (0x35 << 8) | (0x2a << 0), + MEDIABUSMUX_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 13) | (0x1 << 12) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + MSR_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + MSR_REGS_AW_TLIMIT, (0x28 << 8) | (0x28 << 0), + MSR_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + AJPEG_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + AJPEG_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + VXE_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + VXE_REGS_AR_TLIMIT, (0x10 << 8) | (0x10 << 0), + VXE_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + VXE_REGS_MEMCACHE_HINT_OVERRIDE, (0x1 << 31) | (0x1 << 30) | (0x1 << 16) | (0x4 << 0), + VENC_INT_IDLE_CTRL, (0x1 << 20) | (0x1 << 16) | (0x1 << 12), + VENC_INT_AxCACHE_REMAPPING_REG(0, 0), (0x01234567), + VENC_INT_AxCACHE_REMAPPING_REG(0, 1), (0x89abcd0f), + VENC_INT_AxCACHE_REMAPPING_REG(1, 0), (0x01234567), + VENC_INT_AxCACHE_REMAPPING_REG(1, 1), (0x89abcd0f), + 0,0, + + VXD_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + VXD_REGS_MEMCACHE_HINT_OVERRIDE, (0x1 << 31) | (0x1 << 30) | (0x1 << 16) | (0x4 << 0), + VXD_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + VDEC_INT_IDLE_CTRL, (0x1 << 12), + VDEC_INT_AxCACHE_REMAPPING_REG(0, 0), (0x01234567), + VDEC_INT_AxCACHE_REMAPPING_REG(0, 1), (0x89abcdef), + VDEC_INT_AxCACHE_REMAPPING_REG(1, 0), (0x01234567), + VDEC_INT_AxCACHE_REMAPPING_REG(1, 1), (0x89abcd0f), + 0,0, + + CAMERABUSMUX_REGS_ISPKF_RT, (0x10 << 8) | (0xc << 0), + CAMERABUSMUX_REGS_CPG_CNTL, (0x1 << 31) | (0x4 << 0), + 0,0, + + ISP_DMA_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + ISP_DMA_REGS_BW_THRESHOLD, (0x24 << 16) | (0x10 << 0), + ISP_DMA_REGS_AW_LIMIT, (0x30 << 8) | (0x30 << 0), + ISP_DMA_REGS_AR_LIMIT, (0x40 << 8) | (0x40 << 0), + ISP_DMA_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + + ISP_KF_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + ISP_KF_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + DISPBUSMUX_REGS_DWRRCFG_DP1_BULK, (0x1e << 8) | (0x18 << 0), + DISPBUSMUX_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + // For A0, DISP0 DYN_ENA is disabled in miu_update_device_tree. + DISPLAYPIPE0_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + DISPLAYPIPE0_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + DISPLAYPIPE1_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + DISPLAYPIPE1_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + ANS_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + ANS_REGS_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + ANS_KF_TLIMIT_RD, (0x00000909), + ANS_KF_TLIMIT_WR, (0x00000909), + ANS_ANC0_TLIMIT_RD, (0x00000505), + ANS_ANC0_TLIMIT_WR, (0x00000505), + ANS_ANC1_TLIMIT_RD, (0x00000505), + ANS_ANC1_TLIMIT_WR, (0x00000505), + 0,0, + + GFX_REGS_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x4 << 0), + 0,0, + + GFX_IMG4_AFUSER_REGS_MCCFG_0, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_1, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_2, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_3, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_4, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_5, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_6, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_7, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_8, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_9, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_10, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_11, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_12, (0x0 << 23) | (0xD << 19) | (0x4 << 16) | (0x0 << 15) | (0xD << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_13, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_14, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_15, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_16, (0x0 << 23) | (0xE << 19) | (0x4 << 16) | (0x0 << 15) | (0xE << 11) | (0x2 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_17, (0x0 << 23) | (0xE << 19) | (0x4 << 16) | (0x0 << 15) | (0xE << 11) | (0x2 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_18, (0x0 << 23) | (0xE << 19) | (0x4 << 16) | (0x0 << 15) | (0xE << 11) | (0x2 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_19, (0x0 << 23) | (0xE << 19) | (0x4 << 16) | (0x0 << 15) | (0xE << 11) | (0x2 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_20, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_21, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_22, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_23, (0x0 << 23) | (0xD << 19) | (0x4 << 16) | (0x0 << 15) | (0xD << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_24, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_25, (0x0 << 23) | (0xF << 19) | (0x1 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_26, (0x0 << 23) | (0xF << 19) | (0x1 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_27, (0x0 << 23) | (0xF << 19) | (0x4 << 16) | (0x0 << 15) | (0xF << 11) | (0x4 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_28, (0x0 << 23) | (0xD << 19) | (0x4 << 16) | (0x0 << 15) | (0xD << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_29, (0x0 << 23) | (0xF << 19) | (0x1 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_30, (0x0 << 23) | (0xF << 19) | (0x1 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + GFX_IMG4_AFUSER_REGS_MCCFG_31, (0x0 << 23) | (0xF << 19) | (0x1 << 16) | (0x0 << 15) | (0xF << 11) | (0x1 << 8) | (0x0 << 2) | (0x0 << 1) | (0x1 << 0), + 0,0, + + AUSB_REGS_RD_RATE_LIMIT, (0x0), + AUSB_REGS_WRALIMIT, (0x0), + AUSB_REGS_WGATHER, (0x1 << 8), + 0,0, + + 0,0, +}; +#endif + +extern void ausb_setup_widgets(); + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + miu_configure_bridge(bridge_settings_static); +#endif + ausb_setup_widgets(); + + return 0; +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT && WITH_HW_AMC + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rTZSROMCTRL_ROMADDRREMAP = (rTZSROMCTRL_ROMADDRREMAP & ~3) | (1 << 0); + break; + + case REMAP_SDRAM: + rTZSROMCTRL_ROMADDRREMAP = (rTZSROMCTRL_ROMADDRREMAP & ~3) | (2 << 0); + break; + } +} + +void miu_bypass_prep(void) +{ +} + +static void miu_configure_bridge(const u_int32_t *bridge_settings) +{ + volatile u_int32_t *reg; + u_int32_t cnt = 0, bridge, offset, data; + + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + bridge = bridge_settings[cnt] >> STATIC_BRIDGE_SHIFT; + offset = bridge_settings[cnt] & STATIC_BRIDGE_MASK; + data = bridge_settings[cnt + 1]; + reg = (volatile u_int32_t *)(bridge_registers[bridge] + offset); + *reg = data; + cnt += 2; + } + cnt += 2; + } +} + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ + // XXX TODO: handle this better once we understand tunable story for FPGA +#if !SUPPORT_FPGA + uint32_t propSize; + char *propName; + void *propData; + + // Fill in the bridge-settings property + propName = "bridge-settings"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize < sizeof(bridge_settings_dynamic)) { + panic("miu_update_device_tree: bridge-settings property is too small (0x%x/0x%zx)", propSize, sizeof(bridge_settings_dynamic)); + } + memcpy(propData, bridge_settings_dynamic, sizeof(bridge_settings_dynamic)); + } +#endif +} + +#endif diff --git a/platform/s5l8960x/miu/rules.mk b/platform/s5l8960x/miu/rules.mk new file mode 100644 index 0000000..2328570 --- /dev/null +++ b/platform/s5l8960x/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s5l8960x/pmgr/pmgr.c b/platform/s5l8960x/pmgr/pmgr.c new file mode 100644 index 0000000..03c4b2a --- /dev/null +++ b/platform/s5l8960x/pmgr/pmgr.c @@ -0,0 +1,2331 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void arm_no_wfe_spin(uint32_t usecs); + +struct clock_source { + uint32_t src_clk; + uint32_t factor; +}; + +struct clock_config { + volatile uint32_t *clock_reg; // CLK_CFG Register + struct clock_source sources[12]; // List of sources +}; + +#define PLL_VCO_TARGET(pllx) ((2ULL * (pllx##_O) * (pllx##_M)) / (pllx##_P)) +#define PLL_FREQ_TARGET(pllx) (((pllx##_O) * (pllx##_M)) / (pllx##_P) / ((pllx##_S) + 1)) + +#if APPLICATION_SECUREROM +static uint32_t active_state = kDVFM_STATE_SECUREROM; +#endif + +#if APPLICATION_IBOOT +static uint32_t active_state = kDVFM_STATE_IBOOT; +#endif + +static uint64_t ccc_dvfm_states[] = { + +#if APPLICATION_SECUREROM + // BIU div = 1, disable voltage change sequence, Clk src = Ref clk. + [kDVFM_STATE_BYPASS] = (2ULL << 18) | (1ULL << 22), + + // CCC @ 300 MHz, disable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_SECUREROM] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(50) | + CCC_DVFM_ST_PLL_S(3) | (1ULL << 22) | + (1ULL << 21) | (2ULL << 18), +#else + // BIU div = 1, Clk src = Ref clk. + [kDVFM_STATE_BYPASS] = (2ULL << 18), +#endif + +#if APPLICATION_IBOOT + +#if SUB_TARGET_N51 || SUB_TARGET_N53 || SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 || SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + // CCC V0 + // CCC @ 396 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_IBOOT] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(33) | + CCC_DVFM_ST_PLL_S(1) | (1ULL << 21) | (2ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x6) | CCC_DVFM_ST_VOLADJ2(0xB), + + // CCC V1 + // CCC @ 600 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_V1] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(25) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (2ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x6) | CCC_DVFM_ST_VOLADJ2(0xB), + + // CCC V2 + // CCC @ 840 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2. + [kDVFM_STATE_V2] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(35) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x4) | CCC_DVFM_ST_VOLADJ2(0x8), + + // CCC V3 + // CCC @ 1128 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2 + [kDVFM_STATE_V3] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(47) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x4) | CCC_DVFM_ST_VOLADJ2(0x8), + + // CCC V4 + // CCC @ 1296 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2.5 + [kDVFM_STATE_V4] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(54) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (5ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x0) | CCC_DVFM_ST_VOLADJ2(0x0) + +#elif SUB_TARGET_J34 || SUB_TARGET_J34M || SUB_TARGET_J71 || SUB_TARGET_J72 || SUB_TARGET_J73 + // CCC V0 + // CCC @ 600 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_IBOOT] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(25) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (2ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x6) | CCC_DVFM_ST_VOLADJ2(0xB), + + // CCC V1 + // CCC @ 840 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2. + [kDVFM_STATE_V1] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(35) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x4) | CCC_DVFM_ST_VOLADJ2(0x8), + + // CCC V2 + // CCC @ 1128 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2 + [kDVFM_STATE_V2] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(47) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x4) | CCC_DVFM_ST_VOLADJ2(0x8), + + // CCC V3 + // CCC @ 1296 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2.5 + [kDVFM_STATE_V3] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(54) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (5ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x0) | CCC_DVFM_ST_VOLADJ2(0x0), + + // CCC V4 + // CCC @ 1392 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 3 + [kDVFM_STATE_V4] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(58) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (6ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x0) | CCC_DVFM_ST_VOLADJ2(0x0) + +#else + // CCC V0 + // CCC @ 600 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_IBOOT] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(25) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (2ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x6) | CCC_DVFM_ST_VOLADJ2(0xB), + + // CCC V1 + // CCC @ 672 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2. + [kDVFM_STATE_V1] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(28) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x6) | CCC_DVFM_ST_VOLADJ2(0xB), + + // CCC V2 + // CCC @ 696 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2 + [kDVFM_STATE_V2] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(29) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x4) | CCC_DVFM_ST_VOLADJ2(0x8), + + // CCC V3 + // CCC @ 840 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2 + [kDVFM_STATE_V3] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(35) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18) | + CCC_DVFM_ST_VOLADJ0(0x0) | CCC_DVFM_ST_VOLADJ1(0x4) | CCC_DVFM_ST_VOLADJ2(0x8) +#endif + +#endif +}; + + +#if APPLICATION_IBOOT + +/* PLL0 @840MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 4 +#define PLL0_M 279 +#define PLL0_S 1 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +#if TARGET_DDR_784M +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 3 +#define PLL1_M 98 +#define PLL1_S 0 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#elif TARGET_DDR_740M + +/* PLL1 @740MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 6 +#define PLL1_M 185 +#define PLL1_S 0 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#elif TARGET_DDR_798M + +/* PLL1 @798MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 4 +#define PLL1_M 133 +#define PLL1_S 0 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#else + +/* PLL1 @800MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 3 +#define PLL1_M 100 +#define PLL1_S 0 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#endif + +#if SUB_TARGET_J34 || SUB_TARGET_J34M +/* PLL2 @297MHz */ +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 2 +#define PLL2_M 99 +#define PLL2_S 15 +#define PLL2_V PLL_VCO_TARGET(PLL2) +#define PLL2_T PLL_FREQ_TARGET(PLL2) +#endif + +/* PLL4 @2400MHz (VCO output) */ +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 1 +#define PLL4_M 50 +#define PLL4_S 0 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) +#define PLL4_VCO_ENABLED 1 + +#ifndef TARGET_SPARE0_CLK_CFG +#define TARGET_SPARE0_CLK_CFG 0x00100000 +#endif + +#define VID0_CLKD TARGET_VID0_CLK_CFG + +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x81100000, 0x81100000, 0x80100000, 0x86100000, // 0x10000: mcu_fixed, mcu, mipi_dsi, nco_ref0, + 0x85100000, 0x80100000, 0x88100000, 0x85100000, // 0x10010: nco_ref1, nco_alg0, nco_alg1, hsciphy_ref_12m, + 0x85100000, 0x85100000, 0x85100000, 0x85100000, // 0x10020: usb480_0, usb480_1, usb_ohci_48m, usb, + 0x85100000, 0x00100000, 0x00100000, 0x00100000, // 0x10030: usb_free_60m, adsp_t, adsp_p, adsp_ts, + 0x85100000, 0x80100000, 0x85100000, 0x85100000, // 0x10040: sio_c, sio_p, isp_c, isp, + 0x81100000, 0x82100000, 0x85100000, 0x85100000, // 0x10050: isp_sensor0_ref, isp_sensor1_ref, vdec, venc, + VID0_CLKD, 0x85100000, 0x85100000, 0x85100000, // 0x10060: vid0, disp0, disp1, ajpeg_ip, + 0x85100000, 0x85100000, 0x85100000, 0x00100000, // 0x10070: ajpeg_wrap, msr, af, ans_dll, + 0x8A100000, 0x85100000, 0x85100000, 0x85100000, // 0x10080: ans_c, ans_link, lio, mca0_m, + 0x86100000, 0x87100000, 0x88100000, 0x89100000, // 0x10090: mca1_m, mca2_m, mca3_m, mca4_m, + 0x85100000, 0x86100000, 0x85100000, 0x85100000, // 0x100a0: sep, gpio, spi0_n, spi1_n, + 0x85100000, 0x85100000, 0x85100000 // 0x100b0: spi2_n, spi3_n, debug +}; + +static const uint32_t spare_divs_active[PMGR_SPARE_CLK_CFG_COUNT] = { + TARGET_SPARE0_CLK_CFG, // 0x10200: spare0 + 0x00000000, // 0x10204: spare1 + 0x00000000, // 0x10208: spare2 + 0x00000000, // 0x1020c: spare3 + 0x80100028, // 0x10210: isp_ref0 + 0x80100028 // 0x10214: isp_ref1 +}; + +/* GFX table. The voltage information is maintained in chipid.c */ +struct gfx_state_info { + uint32_t dwi_val; /* will be populated by determining the binning info */ + uint32_t fb_div; + uint32_t pre_div; + uint32_t op_div; +}; + +static struct gfx_state_info gfx_states[] = { + [0] = {0, 0, 0, 0}, /* Power off Rogue state.*/ + [1] = {0, 55, 2, 1}, /* 330 MHz */ + [2] = {0, 65, 2, 1}, /* 390 MHz */ + [3] = {0, 75, 2, 1}, /* 450 MHz */ + [4] = {0, 55, 2, 3}, /* 165 MHz */ + [5] = {0, 65, 2, 3}, /* 195 MHz */ + [6] = {0, 75, 2, 3}, /* 225 MHz */ +#if 0 + [7] = {0, 0, 0, 0}, /* Debug state. chipid.c has a valid voltage for this state. */ +#endif +}; + +static void set_gfx_perf_state(uint32_t state_num, struct gfx_state_info *gfx_state); +static int get_amc_cfg_sel(uint32_t performance_level); +static void set_amc_clk_config(uint32_t src_index, uint32_t cfg_sel); +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_SECUREROM + +/* We need SoC PLL only. */ + +/* PLL4 @1200MHz (VCO output) */ +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 1 +#define PLL4_M 50 +#define PLL4_S 0 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) +#define PLL4_VCO_ENABLED 0 + + +// We won't touch the clk gen's that aren't necessary during SecureROM. +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10000: mcu_fixed, mcu, mipi_dsi, nco_ref0, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10010: nco_ref1, nco_alg0, nco_alg1, hsciphy_ref_12m, + 0x80100000, 0x80100000, 0x80100000, 0x86100000, // 0x10020: usb480_0, usb480_1, usb_ohci_48m, usb, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10030: usb_free_60m, adsp_t, adsp_p, adsp_ts, + 0x85100000, 0x85100000, 0x80100000, 0x80100000, // 0x10040: sio_c, sio_p, isp_c, isp, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10050: isp_sensor0_ref, isp_sensor1_ref, vdec, venc, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10060: vid0, disp0, disp1, ajpeg_ip, + 0x80100000, 0x80100000, 0x85100000, 0x80100000, // 0x10070: ajpeg_wrap, msr, af, ans_dll, + 0x85100000, 0x85100000, 0x85100000, 0x80100000, // 0x10080: ans_c, ans_link, lio, mca0_m, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10090: mca1_m, mca2_m, mca3_m, mca4_m, + 0x85100000, 0x86100000, 0x80100000, 0x80100000, // 0x100a0: sep, gpio, spi0_n, spi1_n, + 0x80100000, 0x80100000, 0x80100000 // 0x100b0: spi2_n, spi3_n, debug +}; + +static const uint32_t spare_divs_active[PMGR_SPARE_CLK_CFG_COUNT] = { + 0x80000001, 0x80000001, 0x80000001, 0x80000001, // 0x10200: s0, s1, s2, s3, + 0x80000001, 0x80000001 // 0x10210: isp_ref0, isp_ref1 +}; + +#endif /* APPLICATION_SECUREROM */ + + +static const struct clock_config clk_configs[PMGR_CLK_COUNT] = { + [PMGR_CLK_MCU_FIXED] = { + &rPMGR_MCU_FIXED_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_PLL1, 1} + } + }, + + [PMGR_CLK_MCU] = { + &rPMGR_MCU_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL1, 2}, + {PMGR_CLK_PLL1, 4}, + {PMGR_CLK_PLL1, 8}, + {PMGR_CLK_PLL1, 16}, + {PMGR_CLK_PLL4, 48} + } + }, + + [PMGR_CLK_MIPI_DSI] = { + &rPMGR_MIPI_DSI_CLK_CFG, + { + {PMGR_CLK_PLL0, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL2, 1} + } + }, + + [PMGR_CLK_NCO_REF0] = { + &rPMGR_NCO_REF0_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 2}, + {PMGR_CLK_PLL4, 7} + } + }, + + [PMGR_CLK_NCO_REF1] = { + &rPMGR_NCO_REF1_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 2}, + {PMGR_CLK_PLL4, 7} + } + }, + + [PMGR_CLK_NCO_ALG0] = { + &rPMGR_NCO_ALG0_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 24}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_NCO_ALG1] = { + &rPMGR_NCO_ALG1_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 24}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_HSICPHY_REF_12M] = { + &rPMGR_HSICPHY_REF_12M_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_OSC, 2} + } + }, + + [PMGR_CLK_USB480_0] = { + &rPMGR_USB480_0_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 5} + } + }, + + [PMGR_CLK_USB480_1] = { + &rPMGR_USB480_1_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 5} + } + }, + + [PMGR_CLK_USB_OHCI_48M] = { + &rPMGR_USB_OHCI_48M_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_USB] = { + &rPMGR_USB_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 20}, + {PMGR_CLK_PLL4, 24}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 50}, + {PMGR_CLK_PLL4, 72}, + {PMGR_CLK_PLL4, 80} + } + }, + + [PMGR_CLK_USB_FREE_60M] = { + &rPMGR_USB_FREE_60M_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 40} + } + }, + + [PMGR_CLK_ADSP_T] = { + &rPMGR_ADSP_T_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 11}, + {PMGR_CLK_PLL4, 14}, + {PMGR_CLK_PLL4, 16} + } + }, + + [PMGR_CLK_ADSP_P] = { + &rPMGR_ADSP_P_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 18}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_ADSP_TS] = { + &rPMGR_ADSP_TS_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 9}, + } + }, + + [PMGR_CLK_SIO_C] = { + &rPMGR_SIO_C_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 5}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 48} + } + }, + + [PMGR_CLK_SIO_P] = { + &rPMGR_SIO_P_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 20}, + {PMGR_CLK_PLL4, 24}, + {PMGR_CLK_PLL4, 30}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 48}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4} + } + }, + + [PMGR_CLK_ISP_C] = { + &rPMGR_ISP_C_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 5}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 48} + } + }, + + [PMGR_CLK_ISP] = { + &rPMGR_ISP_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 12} + } + }, + + [PMGR_CLK_ISP_SENSOR0_REF] = { + &rPMGR_ISP_SENSOR0_REF_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_ISP_REF0, 1}, + {PMGR_CLK_ISP_REF1, 1} + } + }, + + [PMGR_CLK_ISP_SENSOR1_REF] = { + &rPMGR_ISP_SENSOR1_REF_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_ISP_REF0, 1}, + {PMGR_CLK_ISP_REF1, 1} + } + }, + + [PMGR_CLK_VDEC] = { + &rPMGR_VDEC_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_VENC] = { + &rPMGR_VENC_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_VID0] = { + &rPMGR_VID0_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 11}, + {PMGR_CLK_PLL4, 39} + } + }, + + [PMGR_CLK_DISP0] = { + &rPMGR_DISP0_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 14}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_DISP1] = { + &rPMGR_DISP1_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 14}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_AJPEG_IP] = { + &rPMGR_AJPEG_IP_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 11}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_AJPEG_WRAP] = { + &rPMGR_AJPEG_WRAP_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 11}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_MSR] = { + &rPMGR_MSR_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_AF] = { + &rPMGR_AF_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 5}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 12} + } + }, + + [PMGR_CLK_ANS_DLL] = { + &rPMGR_ANS_DLL_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 6} + } + }, + + [PMGR_CLK_ANS_C] = { + &rPMGR_ANS_C_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 5}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 48} + } + }, + + [PMGR_CLK_ANC_LINK] = { + &rPMGR_ANC_LINK_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 9}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 7}, // TODO: rdar://problem/10749966 + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 18}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_LIO] = { + &rPMGR_LIO_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 10}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 14}, + {PMGR_CLK_PLL4, 16}, + {PMGR_CLK_PLL4, 18}, + {PMGR_CLK_PLL4, 20}, + {PMGR_CLK_PLL4, 48} + } + }, + + [PMGR_CLK_MCA0_M] = { + &rPMGR_NCO_CLK_CFG(0), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4} + } + }, + + [PMGR_CLK_MCA1_M] = { + &rPMGR_NCO_CLK_CFG(1), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4} + } + }, + + [PMGR_CLK_MCA2_M] = { + &rPMGR_NCO_CLK_CFG(2), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4} + } + }, + + [PMGR_CLK_MCA3_M] = { + &rPMGR_NCO_CLK_CFG(3), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4} + } + }, + + [PMGR_CLK_MCA4_M] = { + &rPMGR_NCO_CLK_CFG(4), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4} + } + }, + + [PMGR_CLK_SEP] = { + &rPMGR_SEP_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 6}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 12}, + {PMGR_CLK_PLL4, 24} + } + }, + + [PMGR_CLK_GPIO] = { + &rPMGR_GPIO_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 100}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_SPI0_N] = { + &rPMGR_SPI0_N_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 48}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_SPI1_N] = { + &rPMGR_SPI1_N_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 48}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_SPI2_N] = { + &rPMGR_SPI2_N_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 48}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_SPI3_N] = { + &rPMGR_SPI3_N_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 48}, + {PMGR_CLK_PLL4, 50} + } + }, + + [PMGR_CLK_DEBUG] = { + &rPMGR_DEBUG_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_S2, 1}, + {PMGR_CLK_S3, 1}, + {PMGR_CLK_PLL4, 20}, + {PMGR_CLK_PLL4, 24}, + {PMGR_CLK_PLL4, 30}, + {PMGR_CLK_PLL4, 40}, + {PMGR_CLK_PLL4, 48} + } + }, + + [PMGR_CLK_S0] = { + &rPMGR_S0_CLK_CFG, + { + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL2, 1}, + {PMGR_CLK_PLL3, 1}, + {PMGR_CLK_PLL4, 2} + } + }, + + [PMGR_CLK_S1] = { + &rPMGR_S1_CLK_CFG, + { + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL2, 1}, + {PMGR_CLK_PLL3, 1}, + {PMGR_CLK_PLL4, 2} + } + }, + + [PMGR_CLK_S2] = { + &rPMGR_S2_CLK_CFG, + { + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL2, 1}, + {PMGR_CLK_PLL3, 1}, + {PMGR_CLK_PLL4, 2} + } + }, + + [PMGR_CLK_S3] = { + &rPMGR_S3_CLK_CFG, + { + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL2, 1}, + {PMGR_CLK_PLL3, 1}, + {PMGR_CLK_PLL4, 2} + } + }, + + [PMGR_CLK_ISP_REF0] = { + &rPMGR_ISP_REF0_CLK_CFG, + { + {PMGR_CLK_PLL4, 5}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9} + } + }, + + [PMGR_CLK_ISP_REF1] = { + &rPMGR_ISP_REF1_CLK_CFG, + { + {PMGR_CLK_PLL4, 5}, + {PMGR_CLK_PLL4, 7}, + {PMGR_CLK_PLL4, 8}, + {PMGR_CLK_PLL4, 9} + } + }, +}; + +static uint32_t get_apsc_ccc_state(void); +static void set_apsc_ccc_state(uint32_t target_state); +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static void init_thermal_sensors(void); +static void init_sochot(void); +static void init_ccc_thermal_sensors(void); +static void init_ccc_sochot(void); +#endif +static void clocks_get_frequencies(void); +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk); +static uint32_t get_pll(int32_t pll); +static uint32_t get_pll_cpu(void); +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s, bool vco_output); +static uint32_t get_spare(int32_t spare); +static void clocks_set_gates(uint64_t *devices); +static void clocks_quiesce_internal(void); +static void power_on_sep(void); + +// current clock frequencies +static uint32_t clks[PMGR_CLK_COUNT + 1]; + + +void platform_power_spin(uint32_t usecs) +{ + arm_no_wfe_spin(usecs); +} + +int clocks_init(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) + clks[PMGR_CLK_OSC] = OSC_FREQ; + + clocks_get_frequencies(); + +#endif /* (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) */ + + return 0; +} + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +/* + * Look into rdar://problem/11647718 for further details. + * S/W workaround below: + * We need to turn ON the power partitions once. + * Note: CCC, GFX are not effected so we won't touch them. + * ADSP is not used so we leave it that way. + * After SecureROM hands off control we have the following partitions ON + * - Always on (Obviously!) + * - AMC + * - USB + * - ACS + * - ANS + * So we will power ON + * - DISP0 + * - DISP1 + * - MEDIA + * - ISP + * - VDEC + * - VENC. + * and power them down. + */ +static void enable_bira_work_around(void) +{ + + // Turn on the blocks + clock_gate(CLK_DISP_BUSMUX, true); + clock_gate(CLK_DISP1, true); + clock_gate(CLK_MEDIA, true); + clock_gate(CLK_VDEC, true); + clock_gate(CLK_VENC, true); + + // FPGA doesn't have ISP +#if !SUPPORT_FPGA + clock_gate(CLK_ISP, true); + clock_gate(CLK_ISP, false); +#endif + + // Power down in reverse order. + // Note: The PWR_XXX_CFG0 register for these partitions + // enable power down. + clock_gate(CLK_VENC, false); + clock_gate(CLK_VDEC, false); + clock_gate(CLK_MEDIA, false); + clock_gate(CLK_DISP1, false); + clock_gate(CLK_DISP_BUSMUX, false); +} + +/* + * To avoid di/dt voltage drop at the end of PLL relock. rdar://problem/13112194. + */ +static void set_ccc_pll_relock_div2(void) +{ + uint32_t reg; + + reg = rCCC_PLL_CFG2; + reg &= ~CCC_PLL_CFG2_RELOCKBYS2_S4_MASK; + reg |= CCC_PLL_CFG2_RELOCKBYS2_S4_DIV2; + rCCC_PLL_CFG2 = reg; +} + +static void set_nco_clocks(void) +{ + uint32_t i; + + // Enable this NCO with alg_ref0_clk and nco_ref0_clk. + for(i = 0; i < 5; i++) + rPMGR_NCO_CLK_CFG(i) |= (1 << 31); +} + +static void apply_pmgr_tunables() +{ +#define RESET_TIME_MASK (((1 << 8) - 1) << 0) +#define CLAMP_TIME_MASK (((1 << 8) - 1) << 8) +#define CLK_EN_TIME_MASK (((1 << 8) - 1) << 16) +#define _PWRGATE_CFG0(rCFG0, CLK_EN_TIME, CLAMP_TIME, RESET_TIME) \ + regTemp = rCFG0; \ + regTemp &= ~RESET_TIME_MASK; \ + regTemp |= (RESET_TIME << 0); \ + regTemp &= ~CLAMP_TIME_MASK; \ + regTemp |= (CLAMP_TIME << 8); \ + regTemp &= ~CLK_EN_TIME_MASK; \ + regTemp |= (CLK_EN_TIME << 16); \ + rCFG0 = regTemp; + +#define RAMP_PRE_TIME_MASK (((1 << 12) - 1) << 0) +#define RAMP_ALL_TIME_MASK (((1 << 12) - 1) << 16) + +#define _PWRGATE_CFG1(rCFG1, RAMP_ALL_TIME, RAMP_PRE_TIME) \ + regTemp = rCFG1; \ + regTemp &= ~RAMP_PRE_TIME_MASK; \ + regTemp |= (RAMP_PRE_TIME << 0); \ + regTemp &= ~RAMP_ALL_TIME_MASK; \ + regTemp |= (RAMP_ALL_TIME << 16); \ + rCFG1 = regTemp; + + uint32_t regTemp, i; + + // B0, B1 tunables. + + _PWRGATE_CFG0(rPMGR_PWRGATE_AMC_CFG0, 0x2, 0x2, 0x8); + _PWRGATE_CFG1(rPMGR_PWRGATE_AMC_CFG1, 0x25, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_USB_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_USB_CFG1, 0xd, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ACS_CFG0, 0x2, 0x2, 0x7); + _PWRGATE_CFG1(rPMGR_PWRGATE_ACS_CFG1, 0x21, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_DISP0_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_DISP0_CFG1, 0x6a, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_DISP1_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_DISP1_CFG1, 0x40, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ISP_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_ISP_CFG1, 0x63, 0x1); + + _PWRGATE_CFG0(rPMGR_PWRGATE_MEDIA_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_MEDIA_CFG1, 0x50, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_DEC_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_DEC_CFG1, 0x5a, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ENC_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_ENC_CFG1, 0x67, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ANS_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_ANS_CFG1, 0x49, 0x2); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ADSP_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_ADSP_CFG1, 0x1c, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_GFX_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_GFX_CFG1, 0x16, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_SEP_CFG0, 0x3, 0x2, 0x4); + _PWRGATE_CFG1(rPMGR_PWRGATE_SEP_CFG1, 0x3c, 0x0); + + // 2. Apply MCU Async reset timing. + + rPMGR_MCU_ASYNC_RESET = (0x1 << 0) | (0x1 << 4) | (0x1 << 8); + + // 3. Apply VolMan tunables + + rPMGR_VOLMAN_SOC_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + rPMGR_VOLMAN_SRAM_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + rPMGR_VOLMAN_GFX_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + rPMGR_VOLMAN_CPU_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + + // 4. Apply GFX EMA0 & EMA1 tunables. + + rPMGR_EMA_GFX0 = (0x4 << 0) | (0x4 << 5) | (0x4 << 11) | (0x4 << 16) | (0xa << 22) | (0x7 << 26) | (0x7 << 29); + rPMGR_EMA_GFX1 = (0x5 << 0) | (0x4 << 3) | (0x1 << 6) | (0x4 << 10) | (0x4 << 13) | (0x5 << 20) | (0x4 << 23) | (0x3 << 29); + + // 5. PLLx_ANA_PARAMSy tunables + for (i = 0; i < PMGR_PLL_COUNT; i++) { + rPMGR_PLL_ANA_PARAMS(0, i) = 0x61a8308; + rPMGR_PLL_ANA_PARAMS(1, i) = 0xcec0000; + } + + // WA for the lack of a clean SW reset of PD_ANS. + // By enabling power gating we will have a reset when + // PD_ANS is turned back on. + // , + // has further details on this WA. + rPMGR_PWRGATE_ANS_CFG0 |= (1 << 31); + return; +} + +static void apply_ccc_tunables(void) +{ + rCCC_PRE_TD_TMR = 0x4; + rCCC_PRE_FLUSH_TMR = 0x1000; +} +#endif + +/* + * clocks_set_default - called by SecureROM, LLB, iBSS main via + * platform_init_setup_clocks, so the current state of the chip is + * either POR, or whatever 'quiesce' did when leaving SecureROM. + */ + +int clocks_set_default(void) +{ + uint32_t cnt; +#if APPLICATION_IBOOT + u_int32_t cpu_vid[kDVFM_STATE_IBOOT_CNT]; + u_int32_t gpu_vid[kPMGR_GFX_STATE_MAX]; +#endif + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + volatile uint32_t *spare_clkcfgs = PMGR_FIRST_SPARE_CLK_CFG; + + // Setup bypass DVFM state + rCCC_DVFM_ST(kDVFM_STATE_BYPASS) = ccc_dvfm_states[kDVFM_STATE_BYPASS]; + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + if (platform_get_chip_revision() > CHIP_REVISION_B0) { + set_ccc_pll_relock_div2(); + } +#endif + // Change all clocks to something safe + clocks_quiesce_internal(); + + // Setup active DVFM state for the stage of boot. +#if APPLICATION_SECUREROM + rCCC_DVFM_ST(kDVFM_STATE_SECUREROM) = ccc_dvfm_states[kDVFM_STATE_SECUREROM]; +#endif + +#if APPLICATION_IBOOT +#ifndef BUCK_CPU +#error BUCK_CPU not defined for this platform +#endif + // Get the binned voltages and update the CCC DVFM state registers. + platform_get_cpu_voltages(kDVFM_STATE_IBOOT_CNT, cpu_vid); + platform_convert_voltages(BUCK_CPU, kDVFM_STATE_IBOOT_CNT, cpu_vid); + + for (cnt = kDVFM_STATE_IBOOT; cnt < kDVFM_STATE_IBOOT_CNT; cnt++) { + rCCC_DVFM_ST(cnt) = ccc_dvfm_states[cnt] | ((unsigned long long)cpu_vid[cnt] << CCC_DVFM_ST_SAFE_VOL_SHIFT); + } + // APSC sleep state will use the bypass state with V0. + + rCCC_DVFM_ST(kDVFM_STATE_BYPASS) = ccc_dvfm_states[kDVFM_STATE_BYPASS] | ((unsigned long long)cpu_vid[kDVFM_STATE_V0] << CCC_DVFM_ST_SAFE_VOL_SHIFT); + + // To prevent crashes/hangs during update install due to + // mismatch of CCC clock config info between an old LLB and a new EDT+OS + // we can populate the unused entries of the DVFM table with that of + // Vmin, Fmin. That way we will always have a workable entry in the DVFM + // table. + // Assumptions: + // There is always a valid state for iBoot and we will use that to populate the + // empty table entries. + + for (cnt = kDVFM_STATE_IBOOT_CNT; cnt < CCC_DVFM_STATE_COUNT; cnt++) { + rCCC_DVFM_ST(cnt) = ccc_dvfm_states[kDVFM_STATE_IBOOT] | + ((unsigned long long)cpu_vid[kDVFM_STATE_IBOOT] << CCC_DVFM_ST_SAFE_VOL_SHIFT); + } + + // Using one point calibration at the lower reading. + uint32_t tempOffset0 = (rCCC_DVFM_EFUSE_TADC0 & 0x1FF) >> 2; + uint32_t tempOffset1 = (rCCC_DVFM_EFUSE_TADC1 & 0x1FF) >> 2; + + // If device is calibrated with DVFM FUSE values, then we need to subtract this offset. + if (0 != tempOffset0) { + tempOffset0 = (0x38 - tempOffset0) & 0x7F; + } + if (0 != tempOffset1) { + tempOffset1 = (0x38 - tempOffset1) & 0x7F; + } + + // Program TVM thresholds + rCCC_DVFM_CFG |= CCC_DVFM_CFG_TEMPTHRES0(0x34) | CCC_DVFM_CFG_TEMPTHRES1(0x48) | + CCC_DVFM_CFG_TEMPOFFST0(tempOffset0) | CCC_DVFM_CFG_TEMPOFFST1(tempOffset1); + + // Using default programmed value of 1ms. + // rCCC_DVFM_DLY = 0x180000; +#endif + + +#if APPLICATION_IBOOT +#if WITH_HW_DWI + extern int dwi_init(void); + dwi_init(); +#endif +#endif + + set_apsc_ccc_state(active_state); // CCC clock set for this stage of boot. + +#if APPLICATION_IBOOT +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + platform_get_gpu_voltages(sizeof(gfx_states)/sizeof(gfx_states[0]), gpu_vid); + platform_convert_voltages(BUCK_GPU, sizeof(gfx_states)/sizeof(gfx_states[0]), gpu_vid); + + for (cnt = 0; cnt < sizeof(gfx_states)/sizeof(gfx_states[0]); cnt++) { + if (cnt == 0) + gfx_states[cnt].dwi_val = 0; + else + gfx_states[cnt].dwi_val = gpu_vid[cnt]; + + set_gfx_perf_state(cnt, gfx_states); + } + // As per GFX Performance state software Sequence + // Clear the bypass bit in PLL5 + rPMGR_PLL_CTL(5) &= ~(1 << 27); + // PLL5 relock mode is set to 1 to switch to bypass mode while re-locking. + rPMGR_PLL_CFG(5) |= (1 << 24); + // Enable performance state table to control PLL5 + rPMGR_GFX_PERF_STATE_CTL |= (1 << 31); + + // The initial SRAM, SOC, CPU voltages are set by IIC writes to the PMU (in the pmu driver). +#endif + +#ifdef PLL0_T //MIPI +#if WITH_HW_AGC_MIPI + rPMGR_AGILE_CLK_CTL = (1 << 28); + rPMGR_PLL_ACG_CFG |= PMGR_ACG_CFG_PLLX_AUTO_DISABLE(0); +#endif + set_pll(0, PLL0_P, PLL0_M, PLL0_S, 0); +#endif + +#ifdef PLL1_T //Mem + set_pll(1, PLL1_P, PLL1_M, PLL1_S, 0); +#endif + +#ifdef PLL2_T //Unused + set_pll(2, PLL2_P, PLL2_M, PLL2_S, 0); +#endif + +#ifdef PLL3_T //Unused + set_pll(3, PLL3_P, PLL3_M, PLL3_S, 0); +#endif + +#ifdef PLL4_T // SOC + set_pll(4, PLL4_P, PLL4_M, PLL4_S, PLL4_VCO_ENABLED); +#endif + +#ifdef PLL5_T // GFX + set_pll(5, PLL5_P, PLL5_M, PLL5_S, 0); +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Turn on NCO clocks before enabling MCA clocks. + set_nco_clocks(); +#endif + // Set all spare clock divs to their active values + for (cnt = 0; cnt < PMGR_SPARE_CLK_CFG_COUNT; cnt++) { + spare_clkcfgs[cnt] = spare_divs_active[cnt]; + SPIN_W_TMO_WHILE((spare_clkcfgs[cnt] & PMGR_CLK_CFG_PENDING) != 0); + } + + // Set all but the spare clock divs to their active values + for (cnt = 0; cnt < PMGR_CLK_CFG_COUNT; cnt++) { + clkcfgs[cnt] = clk_divs_active[cnt]; + SPIN_W_TMO_WHILE((clkcfgs[cnt] & PMGR_CLK_CFG_PENDING) != 0); + } + + power_on_sep(); + + clocks_get_frequencies(); + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + apply_pmgr_tunables(); + apply_ccc_tunables(); +#endif + return 0; +} + +static uint32_t get_apsc_ccc_state(void) +{ + return ((rCCC_DVFM_CFG_SEL >> 3) & 0x7); +} + +static void set_apsc_ccc_state(uint32_t target_state) +{ + rCCC_APSC_SCR = CCC_APSC_MANUAL_CHANGE(target_state); + SPIN_W_TMO_WHILE((rCCC_APSC_SCR & CCC_APSC_PENDING) != 0); + + return; +} + +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s, bool vco_output) +{ + if (pll >= PMGR_PLL_COUNT) return; + + if (vco_output) rPMGR_PLL_CFG(pll) |= PMGR_PLL_VCO_OUT_SEL; + + rPMGR_PLL_CTL(pll) = (PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s) | + PMGR_PLL_ENABLE | PMGR_PLL_LOAD); + + SPIN_W_TMO_WHILE((rPMGR_PLL_CTL(pll) & PMGR_PLL_LOCKED) == 0); +} + +static uint32_t get_pll_cpu(void) +{ + uint32_t freq; + uint32_t pllctl; + + pllctl = rCCC_PWRCTRL_PLL_SCR1; + + // Fcpu <= ((OSC * M) / P / S+1) + freq = OSC_FREQ; + freq *= (pllctl >> CCC_PLL_M_SHIFT) & CCC_PLL_M_MASK; + freq /= (pllctl >> CCC_PLL_P_SHIFT) & CCC_PLL_P_MASK; + freq /= 1 + ((pllctl >> CCC_PLL_S_SHIFT) & CCC_PLL_S_MASK); + + return freq; +} + +static uint32_t get_pll(int32_t pll) +{ + uint32_t pllctl; + uint64_t freq = 0; + + pllctl = rPMGR_PLL_CTL(pll); + + // If PLL is not enabled, check for External Bypass + if ((pllctl & PMGR_PLL_ENABLE) == 0) { + if ((pllctl & PMGR_PLL_EXT_BYPASS) == 0) + return 0; + else + return OSC_FREQ; + } + + + freq = OSC_FREQ; + + freq *= ((pllctl >> PMGR_PLL_M_SHIFT) & PMGR_PLL_M_MASK); + + if ((rPMGR_PLL_CFG(pll) & PMGR_PLL_VCO_OUT_SEL) == 0) { + freq /= (1 + ((pllctl >> PMGR_PLL_S_SHIFT) & PMGR_PLL_S_MASK)); + } else { + freq *= 2; + } + + freq /= ((pllctl >> PMGR_PLL_P_SHIFT) & PMGR_PLL_P_MASK); + +#if DEBUG_BUILD + if (freq> 0xFFFFFFFF) + panic("Frequency value does not fit in uint32_t"); +#endif + + return (uint32_t)freq; +} + + +static uint32_t get_spare(int32_t spare) +{ + uint32_t reg_val, src_idx, src_clk, src_factor, div; + volatile uint32_t *spare_clkcfg = clk_configs[PMGR_CLK_S0 + spare].clock_reg; + + reg_val = *spare_clkcfg; + + div = reg_val & 0x3F; + + if (((reg_val & PMGR_CLK_CFG_ENABLE) == 0) || div == 0) + return 0; + + src_idx = (reg_val >> 24) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].src_clk; + src_factor = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].factor; + + return (clks[src_clk] / src_factor) / div; +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_CPU] = 5000000; + clks[PMGR_CLK_MCU] = 10000000; + clks[PMGR_CLK_MCU_FIXED]= 10000000; + clks[PMGR_CLK_USB] = 12000000; + +#elif SUB_TARGET_CYCLONIC + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + +#else + uint32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) clks[PMGR_CLK_PLL0 + cnt] = get_pll(cnt); + + // Use get_spare() to establish the frequencies for spare clocks (unconfigured will be skipped) + for (cnt = 0; cnt < PMGR_SPARE_CLK_CFG_COUNT; cnt++) clks[PMGR_CLK_S0 + cnt] = get_spare(cnt); + + clks[PMGR_CLK_CPU] = get_pll_cpu(); + + clocks_get_frequencies_range(PMGR_CLK_MCU_FIXED, PMGR_CLK_DEBUG); +#endif +} + +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk) +{ + volatile uint32_t *reg; + uint32_t cnt, val, src_idx, src_clk, src_factor; + + if (start_clk < PMGR_CLK_MCU_FIXED || end_clk > PMGR_CLK_DEBUG) + return; + + for (cnt = start_clk; cnt <= end_clk; cnt++) { + reg = clk_configs[cnt].clock_reg; + val = *reg; + + if ((val & PMGR_CLK_CFG_ENABLE) == 0) { + clks[cnt] = 0; + continue; + } + + src_idx = (val >> 24) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[cnt].sources[src_idx].src_clk; + src_factor = clk_configs[cnt].sources[src_idx].factor; + clks[cnt] = clks[src_clk] / src_factor; + } +} + +void dump_clock_frequencies() +{ + uint32_t i; + + for (i = 0; i < PMGR_CLK_COUNT; i++) { + dprintf(DEBUG_CRITICAL, "clk[%d] -> %u\n", i, clks[i]); + } +} + +static void clock_update_range(uint32_t first, uint32_t last, const uint32_t clkdata) +{ + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + uint32_t reg; + + reg = first; + while (reg <= last) { + clkcfgs[reg] = clkdata; + SPIN_W_TMO_WHILE(clkcfgs[reg] & PMGR_CLK_CFG_PENDING); + reg++; + } +} + +static void restore_clock_config_state(void) +{ + uint32_t cnt; + + // 2. Write reset value to ACG, CLK_DIVIDER_ACG_CFG, CLK_DIVIDER_ACG_CFG1, and PLL_ACG_CFG + rPMGR_MISC_ACG = 0; + rPMGR_CLK_DIVIDER_ACG_CFG = 0; + rPMGR_CLK_DIVIDER_ACG_CFG1 = 0; + rPMGR_PLL_ACG_CFG = 0; + + // 5. Write reset value for all mux clock configs (excluding spares, mcu, mcu_fixed) + clock_update_range(PMGR_CLK_NUM(MIPI_DSI), PMGR_CLK_NUM(DEBUG), 0x80100000); + + // 6. Write all PLLx_CTL.EXT_BYPASS to 1 + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 1) continue; + + rPMGR_PLL_CTL(cnt) |= PMGR_PLL_EXT_BYPASS; + SPIN_W_TMO_WHILE((rPMGR_PLL_CTL(cnt) & PMGR_PLL_BYP_ENABLED) == 0); + } + + // 8. Make sure PLLs OFF mode is set to powered down. + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 1) continue; // Mem PLL + + rPMGR_PLL_CFG(cnt) |= (2 << 30); // PLL.OFF_MODE = Powered down. + rPMGR_PLL_CTL(cnt) |= (PMGR_PLL_ENABLE | PMGR_PLL_LOAD); + SPIN_W_TMO_WHILE((rPMGR_PLL_CTL(cnt) & PMGR_PLL_LOCKED) == 0); + } + + // 9. Write reset value to all PLLx_CTL + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 1) continue; // Mem PLL + + rPMGR_PLL_CTL(cnt) = 0x0A001010; // Ext bypass, fb_div = 1, pre_div = 1 + SPIN_W_TMO_WHILE((rPMGR_PLL_CTL(cnt) & PMGR_PLL_BYP_ENABLED) == 0); + } + + // 11. Write reset value to spare and ISP_REF0/1 + clock_update_range(PMGR_CLK_NUM(S0), PMGR_CLK_NUM(ISP_REF1), 0x80000001); + + + // 12. Put CPU clock back into its reset default. + rCCC_DVFM_SCR = (1 << 2); // CPU PLL goes to reset mode when off. + set_apsc_ccc_state(kDVFM_STATE_BYPASS); +} + + +static void power_on_sep(void) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + CLK_SEP); + uint32_t val = *reg; + + val &= ~(1 << 28); // Clear Auto_PM_EN + *reg = val; + SPIN_W_TMO_WHILE(((*reg >> 4) & 0xF) != 0xF); // Wait for SEP to turn on. + + return; +} + +static void clocks_quiesce_internal(void) +{ + uint64_t devices[2]; + + // Disable all voltage changes everywhere! + rPMGR_VOLMAN_CTL |= PMGR_VOLMAN_DISABLE_VOL_CHANGE; +#if APPLICATION_IBOOT + rPMGR_VOLMAN_CTL |= 1; // Temporary till B0 chip arrives +#endif + // We don't touch CPU0, CPU1, CPM + // Following devices needs to be on: + // LIO, IOMUX, AIC, DEBUG + // GPIO, SIO_P, SIO, MCC, MCU, + // AMP, USB, USBCTRL, USB OTG, SMX, SF, CP + devices[0] = (0x1ULL << 3) | (0x1ULL << 4) | (0x1ULL << 5) | (0x1ULL << 6) | + (0x1ULL << 8) | (0x1ULL << 33) | (0x1ULL << 34) | (0x1ULL << 40) | (0x1ULL << 41) | + (0x1ULL << 42) | (0x1ULL << 43) | (0x1ULL << 44) | (0x1ULL << 49) | + (0x1ULL << 50) | (0x1ULL << 51) | (0x1ULL << 52); + + // ANS. + devices[1] = (0x1ULL << 0); + + // Turn on/off critical device clocks + clocks_set_gates(devices); + + // Disable performance state table to control PLL5 + rPMGR_GFX_PERF_STATE_CTL = 0; + + restore_clock_config_state(); +} + +void clocks_quiesce(void) +{ + clocks_quiesce_internal(); +} + +uint32_t clocks_set_performance(uint32_t performance_level) +{ +#if APPLICATION_IBOOT + int cfg_sel = -1; + uint32_t src_index; +#endif + uint32_t ccc_state = get_apsc_ccc_state(); + + if (ccc_state != active_state) + set_apsc_ccc_state(active_state); + +#if APPLICATION_IBOOT + if (performance_level == kPerformanceMemoryLow || performance_level == kPerformanceMemoryFull) { + cfg_sel = get_amc_cfg_sel(performance_level); + + if (cfg_sel == -1) + panic("pmgr:cfg_sel not set correctly for configuring amc clock"); + + src_index = (performance_level == kPerformanceMemoryLow) ? 6 : 1; + + set_amc_clk_config(src_index, cfg_sel); + clocks_get_frequencies_range(PMGR_CLK_MCU_FIXED, PMGR_CLK_MCU); + } +#endif + // At this point we should have CCC clock set for this stage of boot. + return kPerformanceHigh; +} + +void clock_get_frequencies(uint32_t *clocks, uint32_t count) +{ + uint32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) cnt = count; + + memcpy(clocks, clks, cnt * sizeof(uint32_t)); +} + +uint32_t clock_get_frequency(int clock) +{ + uint32_t freq = 0; + + // XXX TODO + + switch (clock) { + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + freq = clks[PMGR_CLK_OSC]; + break; + case CLK_PCLK: + case CLK_PERIPH: + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + freq = clks[PMGR_CLK_SIO_P]; + break; + case CLK_MEM: + freq = clks[PMGR_CLK_MCU]; + break; + case CLK_ANS_LINK: + freq = clks[PMGR_CLK_ANC_LINK]; + break; + case CLK_BUS: + freq = clks[PMGR_CLK_LIO]; + break; + case CLK_CPU: + freq = clks[PMGR_CLK_CPU]; + break; + case CLK_MIPI: + freq = clks[PMGR_CLK_MIPI_DSI]; + break; + default: + break; + } + return freq; +} + +void clock_set_frequency(int clock, uint32_t divider, uint32_t pll_p, uint32_t pll_m, uint32_t pll_s, uint32_t pll_t) +{ + return; +} + +void clock_gate(int device, bool enable) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device); + + // Make sure we are within limits. Also we won't touch ADSP. + if ((reg > PMGR_LAST_PS) || (device == CLK_ADSP)) + return; + + // Set the PS field to the requested level + if (enable) + *reg |= PMGR_PS_RUN_MAX; + else + *reg &= ~PMGR_PS_RUN_MAX; + + // Wait for the MANUAL_PS and ACTUAL_PS fields to be equal + SPIN_W_TMO_WHILE((*reg & PMGR_PS_MANUAL_PS_MASK) != ((*reg >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); +} + +static void clocks_set_gates(uint64_t *devices) +{ + uint32_t i, idx = 1; + + // Turn off devices hi to lo order (to meet dependencies). + for (i = PMGR_LAST_DEVICE - 1; i >= CLK_LIO;) { + clock_gate(i, ( (devices[idx] >> ((uint64_t) (i % 64)) ) & 0x1) ); + if (i && ((i % 64) == 0)) + idx--; + + i--; + } + + idx = 0; + + // Turn on devices from lo to hi (to meet dependencies). + for (i = CLK_LIO; ( (i < 128) && (i < PMGR_LAST_DEVICE) ); ) { + if (i && ((i % 64) == 0)) + idx++; + clock_gate(i, ( (devices[idx] >> ((uint64_t) (i % 64)) ) & 0x1) ); + i++; + } + + return; +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_system_reset(); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_power_init(void) +{ + /* Disable Power gating for CPU0, this is needed to avoid WFI from powering down the core */ + /* Remove this once following is addressed: Core 0 power gating enabled by default */ + rPMGR_PWRGATE_CPU0_CFG0 &= ~(1UL << 31); +} + +void thermal_init(void) +{ +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + /* Read thermal fused values and store into thermal registers */ + init_thermal_sensors(); + /* Read thermal fused values and store into thermal registers & init instantenous read for sochot */ + init_ccc_thermal_sensors(); + + /* Setup SoC Sochot 0 & 1 */ + init_sochot(); + /* Setup CCC Sochot 0 & 1 */ + init_ccc_sochot(); +#endif +} + +void platform_watchdog_tickle(void) +{ + // Varies by target. This layer between is necessary so that + // we don't go straight from generic code to target. + target_watchdog_tickle(); +} + +void clock_reset_device(int device) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device); + + // Make sure we are within limits. Also we won't touch ADSP. + if ((device >= PMGR_LAST_DEVICE) || (device == CLK_ADSP)) + return; + + // XXX TODO + switch(device) { + case CLK_MCU: + case CLK_ANS: + case CLK_SIO: + *reg |= PMGR_PS_RESET; + spin(1); + *reg &= ~PMGR_PS_RESET; + break; + + default: + break; + } +} + +#if APPLICATION_IBOOT +static void set_gfx_perf_state(uint32_t state_num, struct gfx_state_info *gfx_state) +{ + uint32_t pll_enable = 0; + + if (state_num >= sizeof(gfx_states)/sizeof(gfx_states[0])) return; + + // This is deductive. If feedback divider is 0 the PLL shouldn't output anything. + pll_enable = gfx_state[state_num].fb_div ? 1 : 0; + + rPMGR_GFX_PERF_STATE_ENTRY(state_num) = ((gfx_state[state_num].dwi_val & 0xFF) << 24) | + ((pll_enable & 0x1) << 21) | + ((gfx_state[state_num].fb_div & 0x1FF) << 12) | + ((gfx_state[state_num].pre_div & 0x1F) << 4) | + (gfx_state[state_num].op_div & 0xF); + return; +} + +static int get_amc_cfg_sel(uint32_t performance_level) +{ + int cfg_sel; + switch(performance_level) { + case kPerformanceMemoryLow: + cfg_sel = 3; + break; + case kPerformanceMemoryFull: + cfg_sel = 0; + break; + default: + cfg_sel = -1; + break; + } + return cfg_sel; +} + +static void set_amc_clk_config(uint32_t src_index, uint32_t cfg_sel) +{ + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + uint32_t mcu_clk_cfg_reg; + + mcu_clk_cfg_reg = clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)]; + + mcu_clk_cfg_reg &= ~(0x7 << PMGR_CLK_CFG_SRC_SEL_SHIFT); + mcu_clk_cfg_reg &= ~(0x3 << PMGR_CLK_CFG_CFG_SEL_SHIFT); + mcu_clk_cfg_reg |= ((src_index & 0x7) << PMGR_CLK_CFG_SRC_SEL_SHIFT); + mcu_clk_cfg_reg |= ((cfg_sel & 0x3) << PMGR_CLK_CFG_CFG_SEL_SHIFT); + + clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)] = mcu_clk_cfg_reg; + + // Wait for Pending bit to clear. + SPIN_W_TMO_WHILE((clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)] >> PMGR_CLK_CFG_PENDING_SHIFT) & 0x1); + + return; +} +#endif + +#if WITH_DEVICETREE +static uint64_t get_freq_from_ccc_state(uint64_t state_entry) +{ + // Fcpu <= ((OSC * M) / P / S+1) + uint64_t freq = OSC_FREQ; + freq *= ((state_entry >> 4) & 0x1FF); + freq /= ((state_entry >> 13) & 0x1F) ? ((state_entry >> 13) & 0x1F) : 1; + freq /= (1 + ((state_entry >> 0) & 0xF)); + + return freq; +} + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ + uint32_t num_freqs = 0; + uint32_t propSize; + uint64_t period_ns; + uint64_t freq = 0; + uint32_t volt; + uint32_t cpu_vid[kDVFM_STATE_IBOOT_CNT]; + + char *propName; + void *propData; + + // Populate the devicetree with relevant values. + propName = "nominal-performance1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property nominal-performance1 is of wrong size."); + + freq = get_freq_from_ccc_state(ccc_dvfm_states[kDVFM_STATE_VNOM]); + if (freq == 0) + panic("pmgr Fnom Operating point not defined correctly"); + + period_ns = 1000000000ULL << 16; + period_ns /= freq; + + ((uint32_t *)propData)[0] = period_ns; + } else { + panic("pmgr property nominal-performance1 not found."); + } + + propName = "boost-performance1"; + // Note: Boost is not mandatory in all platforms. + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property boost-performance1 is of wrong size"); + + freq = get_freq_from_ccc_state(ccc_dvfm_states[kDVFM_STATE_VBOOST]); + if (freq == 0) + panic("pmgr Fboost Operating point not defined correctly"); + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[0] = period_ns; + } + + propName = "voltage-states1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize/sizeof(uint32_t) < kVOLTAGE_STATES1_SIZE) { + panic("pmgr number of states less than required for voltage-states1"); + } + num_freqs = kVOLTAGE_STATES1_COUNT; + platform_get_cpu_voltages(kDVFM_STATE_IBOOT_CNT, cpu_vid); + for (int32_t i = num_freqs - 1, j = 0; i >= 0; i--, j++) { + freq = get_freq_from_ccc_state(ccc_dvfm_states[kDVFM_STATE_VMAX - j]); + volt = cpu_vid[kDVFM_STATE_VMAX - j]; + if (freq != 0) { + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[2*i] = period_ns; + ((uint32_t *)propData)[2*i+1] = volt; + } + } + } + + propName = "total-rails-leakage"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(uint32_t)) { + *(uint32_t *)propData = chipid_get_total_rails_leakage(); + } + } + + return; +} + +void pmgr_gfx_update_device_tree(DTNode *gfx_node) +{ + u_int32_t count, propSize, num_states = 0, state_val; + char *propName; + void *propData; + + propName = "perf-states"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(u_int32_t) * kPMGR_GFX_STATE_MAX)) { + panic("gfx property perf-state has wrong size"); + } + // Read the values programmed into the GFX perf state table + // and populate the device tree. + for (count = 0; count < kPMGR_GFX_STATE_MAX; count++) { + state_val = rPMGR_GFX_PERF_STATE_ENTRY(count); + + // Any but the first entry with a value of 0 marks the end of the number of valid states. + if ((count != 0) && (state_val == 0)) { + num_states = count; + break; + } + + ((u_int32_t *)propData)[count * 2 + 0] = PMGR_PLL_FREQ((state_val >> 12) & 0x1FF, (state_val >> 4) & 0x1F, state_val & 0xF); + ((u_int32_t *)propData)[count * 2 + 1] = platform_get_dwi_to_mv(BUCK_GPU, (state_val >> 24) & 0xFF); + } + + // If all the entries are valid. + if (count == kPMGR_GFX_STATE_MAX) { + num_states = kPMGR_GFX_STATE_MAX; + } + + } + + propName = "perf-state-count"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + *(u_int32_t *)propData = num_states; + } + + return; +} + +static void override_device_tree_property_uint32(DTNode *node, char *propName, uint32_t propValue, bool panicIfMissing) +{ + void *propData; + uint32_t propSize; + + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) { + panic("%s property is of wrong size.", propName); + } + + ((uint32_t *)propData)[0] = propValue; + } else if (panicIfMissing) { + panic("%s property not found.", propName); + } +} + +void sochot_pmgr_update_device_tree(DTNode *node) +{ +} + +void sochot_ccc_update_device_tree(DTNode *node) +{ +} + +void temp_sensor_pmgr_update_device_tree(DTNode *node) +{ +} + +void temp_sensor_ccc_update_device_tree(DTNode *node) +{ +} +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +void init_thermal_sensors(void) +{ + // Bits [1 - 0] PWRDN Mode and enable. + // Bits [ 2 ] Reserved. + // Bits [ 3 ] Stat mode for Avg Max on. + // Bits [18 - 4] TADC_CFG Tmpsadc configuration bits. + // Bits [31 - 19] Misc interrupt/Alarm stick bits not used. + rPMGR_THERMAL0_CTL0 = 0x5278; + rPMGR_THERMAL1_CTL0 = 0x5278; + + // Bits [15 - 0] PWRDN_START 20us wait + // Bits [31 - 16] PWRDN_GAP Gap between two readings. + rPMGR_THERMAL0_CTL1 = 0x019401E4; + rPMGR_THERMAL1_CTL1 = 0x03A801E4; + + // Bits [7 - 0] Conv_Cycle, cycles to wait before data is valid. + // Bits [15 - 8] Enable_Cycle, cycles to wait before adc_en can be deasserted. + // Bits [23 - 16] Finish_gap, Cycles to wait before adc_en can be reasserted. + // Bits [31 - 24] Reserved. + // + // Use default + // + + for (u_int32_t sensorID = 0; sensorID < 2; sensorID++) { + u_int32_t fusedTempValueAt70 = chipid_get_fused_pmgr_thermal_sensor_cal_70C(sensorID); + u_int32_t fusedTempValueAt25 = chipid_get_fused_pmgr_thermal_sensor_cal_25C(sensorID); + u_int32_t tempSlope = 0x100; + + if ((fusedTempValueAt25 == 0) || (fusedTempValueAt70 == 0)) { + if (chipid_valid_thermal_sensor_cal_data_expected()) { + panic("SoC temperature sensor calibration data not found"); + } + } + + // Should probably make sure we don't divide by zero. + if (fusedTempValueAt25 == fusedTempValueAt70) { + fusedTempValueAt70 = 70; + fusedTempValueAt25 = 25; + dprintf(DEBUG_INFO, "Invalid soc thermal fuse values\n"); + } + + // 45 = 70 - 25 + tempSlope = (45*256) / (fusedTempValueAt70 - fusedTempValueAt25); + + // Calculate the real offset. + u_int32_t realOffset = 25 - ((tempSlope * fusedTempValueAt25) / 256); + + // Bits 23 16 + // Temp_OFFSET => [8 bit signed integer] + // Bits 9 0 + // TEMP_SLOPE => [2 bit integer| 8 bit decimal] + switch (sensorID) { + case 0: + rPMGR_THERMAL0_CTL3 = (realOffset & 0xFF) << 16; + rPMGR_THERMAL0_CTL3 |= tempSlope & 0x3FF; + break; + case 1: + rPMGR_THERMAL1_CTL3 = (realOffset & 0xFF) << 16; + rPMGR_THERMAL1_CTL3 |= tempSlope & 0x3FF; + break; + } + } + + // Per 13799299, enable the temperature sensors after applying calibration efuse info and before enabling DVTM + rPMGR_THERMAL0_CTL0 |= 0x01; + rPMGR_THERMAL1_CTL0 |= 0x01; +} + + +void init_sochot(void) +{ + // Majority of work done in kext with EDT configuration + // Setup GFX clock divider + rPMGR_GFX_PERF_STATE_SOCHOT = 0x1; +} + + +void init_ccc_thermal_sensors(void) +{ + // Per 13146352, CCC thermal sensors for B0+ adopt same register interface as PMGR sensors + rCCC_THRM0_CTL0 |= 0x08; + rCCC_THRM1_CTL0 |= 0x08; + + // Bits [15 - 0] PWRDN_START 20us wait + // Bits [31 - 16] PWRDN_GAP Gap between two readings. + rCCC_THRM0_CTL1 = 0x019401E4; + rCCC_THRM1_CTL1 = 0x019401E4; + + // Bits [7 - 0] Conv_Cycle, cycles to wait before data is valid. + // Bits [15 - 8] Enable_Cycle, cycles to wait before adc_en can be deasserted. + // Bits [23 - 16] Finish_gap, Cycles to wait before adc_en can be reasserted. + // Bits [31 - 24] Reserved. + // + // Use default + // + + for (u_int32_t sensorID = 0; sensorID < 2; sensorID++) { + u_int32_t fusedTempValueAt70 = chipid_get_fused_ccc_thermal_sensor_cal_70C(sensorID); + u_int32_t fusedTempValueAt25 = chipid_get_fused_ccc_thermal_sensor_cal_25C(sensorID); + u_int32_t tempSlope = 0x100; + + if ((fusedTempValueAt25 == 0) || (fusedTempValueAt70 == 0)) { + if (chipid_valid_thermal_sensor_cal_data_expected()) { + panic("CCC temperature sensor calibration data not found"); + } + } + + // Should probably make sure we don't divide by zero. + if (fusedTempValueAt25 == fusedTempValueAt70) { + fusedTempValueAt70 = 70; + fusedTempValueAt25 = 25; + dprintf(DEBUG_INFO, "Invalid soc thermal fuse values\n"); + } + + // 45 = 70 - 25 + tempSlope = (45*256) / (fusedTempValueAt70 - fusedTempValueAt25); + + // Calculate the real offset. + u_int32_t realOffset = 25 - ((tempSlope * fusedTempValueAt25) / 256); + + // Bits 23 16 + // Temp_OFFSET => [8 bit signed integer] + // Bits 9 0 + // TEMP_SLOPE => [2 bit integer| 8 bit decimal] + switch (sensorID) { + case 0: + rCCC_THRM0_CTL3 = (realOffset & 0xFF) << 16; + rCCC_THRM0_CTL3 |= tempSlope & 0x3FF; + break; + case 1: + rCCC_THRM1_CTL3 = (realOffset & 0xFF) << 16; + rCCC_THRM1_CTL3 |= tempSlope & 0x3FF; + break; + } + } + + // Per 13799299, enable the temperature sensors after applying calibration efuse info and before enabling DVTM + rCCC_THRM0_CTL0 |= 0x01; + rCCC_THRM1_CTL0 |= 0x01; + +} + + +void init_ccc_sochot(void) +{ + // Setup CCC clock frequency by specifying index into DVFM table. + rCCC_DVFM_FSHOT_IDX = 0x2; +} + +#endif diff --git a/platform/s5l8960x/pmgr/rules.mk b/platform/s5l8960x/pmgr/rules.mk new file mode 100644 index 0000000..fa626c5 --- /dev/null +++ b/platform/s5l8960x/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s5l8960x/rules.mk b/platform/s5l8960x/rules.mk new file mode 100644 index 0000000..4b0f894 --- /dev/null +++ b/platform/s5l8960x/rules.mk @@ -0,0 +1,136 @@ +# Copyright (C) 2011-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +ARM_CPU := apple-cyclone + +# Devmap chip ID based on sub-platform identifier +ifeq ($(SUB_PLATFORM),s5l8960x) + DEVMAP_CHIP_ID := 8960 +endif + +MAX_DFU_SIZE := 524288 + +# SROM is always defined here +ifeq ($(TEXT_BANK),srom) + TEXT_BASE := 0x100000000 +endif + +# Overriding SRAM_LEN is not allowed. +ifeq ($(TEXT_BANK),sram) + # SRAM TEXT_BASE is fixed by SecureROM. + TEXT_BASE := 0x180380000 + + # iBSS/LLB memory configuration + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := 384*1024 + endif +endif + +# Platform target can override SDRAM config by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(SDRAM_LEN),) + SDRAM_LEN := 1*1024*1024*1024 + + # iBoot/iBEC memory configuration + ifeq ($(TEXT_BANK),sdram) + # SDRAM TEXT_BASE is now set such that you don't have to do lots of math to + # calulate the correct value if you change any of the other region sizes: + # TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 256MB + TEXT_BASE := 0x830000000 + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := 1024*1024 + endif + endif +endif + +# Platform target can override any of these sizes by specifying in target config file (apps/iBoot/$target-config.mk) +ifeq ($(ASP_SIZE),) + ASP_SIZE := 8*1024*1024 +endif +ifeq ($(TZ0_SIZE),) + TZ0_SIZE := 4*1024*1024 +endif +ifeq ($(DISPLAY_SIZE),) + DISPLAY_SIZE := 16*1024*1024 +endif + +ifeq ($(TEXT_BASE),) + $(error TEXT_BASE has not been set) +endif +ifeq ($(TEXT_FOOTPRINT),) + $(error TEXT_FOOTPRINT has not been set) +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + ANC_PPNNPL_DS_DRIVE_STRENGTH=7 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_HOLD_TIME=2 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_SETUP_TIME=3 \ + ANC_LINK_SDR_REN_HOLD_TIME=2 \ + ANC_LINK_SDR_REN_SETUP_TIME=3 \ + ANC_LINK_SDR_WEN_HOLD_TIME=2 \ + ANC_LINK_SDR_WEN_SETUP_TIME=3 \ + ANC_LINK_SDR_DATA_CAPTURE_DELAY=1 \ + ANC_LINK_SDR_CLE_ALE_SETUP_TIME=0 \ + ANC_BOOT_CONTROLLERS=2 \ + ANC_TOGGLE_SUPPORTED=1 \ + DISPLAY_SIZE="($(DISPLAY_SIZE)ULL)" \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=256 \ + PLATFORM_START_FUNCTION=_platform_start \ + SDRAM_LEN="$(SDRAM_LEN)ULL" \ + ASP_SIZE="$(ASP_SIZE)ULL" \ + TZ0_SIZE="$(TZ0_SIZE)ULL" \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" \ + WITH_NO_RANDOM_HEAP_COOKIE=1 \ + WITH_NO_RANDOM_STACK_COOKIE=1 + +ifeq ($(APPLICATION),SecureROM) + +OPTIONS += \ + WITH_ROM_TRAMPOLINE=1 + +ifeq ($(CONFIGS),fpga) + SUPPORT_FPGA=1 +endif + +else + +OPTIONS += \ + WITH_MONITOR=1 + +endif + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) +DATA_BASE := 0x180080000 +OPTIONS += \ + DATA_BASE="$(DATA_BASE)" + +GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/trampoline.o diff --git a/platform/s5l8960x/trampoline.S b/platform/s5l8960x/trampoline.S new file mode 100644 index 0000000..0baa554 --- /dev/null +++ b/platform/s5l8960x/trampoline.S @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2012-2014 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#if WITH_ROM_TRAMPOLINE +#include +#endif // WITH_ROM_TRAMPOLINE +#include +#include + +// Set 1 to use clean-invalidate by dup tags instead of architected clean-invalidate by set/way +#define WITH_DUP_TAGS_CLEAN_INVALIDATE 0 + +// Set to 1 to scan the CP dup-tags to see if any non-invalid entries stayed. +#define VERIFY_INVALIDATION 0 + +#define SCR_RW_SHIFT 10 +#define SCR_RW (1 << SCR_RW_SHIFT) +#define SCR_NS 1 +#define SCR_EL1_64_NS (SCR_RW | SCR_NS) +#define CPSR_EL1 (PSR64_MODE_EL1 | PSR64_MODE_SPX | DAIF_ALL) + + +// TODO: Remove dup-tags style set/way invalidate when A0 is deprecated. + +// Clears from X0 to X1 (not including X1). +// Assumes that X0 and X1 are both 64-byte aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1 +1: + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + cmp x0, x1 + b.lo 1b +.endmacro + +// Clears from X0 to X1 (not including X1) using cacheline clear +// operations. +// Assumes that X0 and X1 are both cacheline aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1_CACHE_ON +1: + dc zva, x0 // zero cacheline + add x0, x0, #L1_CACHELINE_SIZE + cmp x0, x1 + b.lo 1b +.endmacro + + .text + .balign 16 + .globl _boot_handoff_trampoline, _boot_handoff_trampoline_end +_boot_handoff_trampoline: + // Save jump address in x27, and next stage boot info into x28. + mov x27, x0 + mov x28, x1 + + // Disable external aborts, interrupts + msr DAIFSet, #(0xf) + +#if !WITH_CLASSIC_SUSPEND_TO_RAM || !PRODUCT_LLB + // Start by clearing the heap. + ldr x0, L_heap_base + ldr x1, L_heap_end + CLEAR_X0_TO_X1_CACHE_ON + + // Clear the stacks area. + ldr x0, L_stacks_base + ldr x1, L_stacks_end + CLEAR_X0_TO_X1_CACHE_ON +#endif // !WITH_SUSPEND_TO_RAM || !PRODUCT_LLB + + // Retire all instructions executed prior to this (may include ROM). + isb sy + + // Disable caches, mmu, stack alignment fault + mov x1, #0 + msr SCTLR_EL3, x1 + dsb sy + isb sy + + // Flush the TLBs - radar 18269688 + tlbi alle3 + dsb sy + isb sy + + // Now running EL3 with MMU off. All accesses are device, secure. + +#if !WITH_CLASSIC_SUSPEND_TO_RAM || !PRODUCT_LLB + // Clear the page tables. + ldr x0, L_page_tables_base + ldr x1, L_page_tables_end + CLEAR_X0_TO_X1 + +#ifdef BOOT_TRAMPOLINE_BASE + // Clear the text area (or data area in ROM) + // This can only be done if the trampoline was copied to a safe location + ldr x0, L_text_base + ldr x1, L_text_end + CLEAR_X0_TO_X1 + + // Clear all the pointers to interesting memory areas + // that were included in the trampoline + adr x0, L_pointers_base + adr x1, L_pointers_end + CLEAR_X0_TO_X1 +#endif +#endif + +#if WITH_ROM_TRAMPOLINE + // Disable R/W access to ROM region + ldr x1, L_rom_trampoline_reg + ldr w2, L_rom_trampoline_val + ldr w3, [x1] + orr w3, w3, w2 + str w3, [x1] + ldr w3, [x1] + + // ROM doesn't pass any info to next stage (LLB) + mov x28, #0 +#endif // WITH_ROM_TRAMPOLINE + +#if !WITH_DUP_TAGS_CLEAN_INVALIDATE + +_architected_set_way_clean_invalidate: + // B0 architected set/way clean-invalidate. + // Register format for "dc cisw" is: + // * 32 bit register + // * Ways in the top bits (31 downwards) + // * Sets starting at bit log2(line size) + // * Level specified near the lowest bits. + // E.g for Cyclone L2 with 64 byte lines, 2K lines, 8 ways: + // [31:29] = way 0..7 + // [28:17] = SBZ + // [16:6] = set 0..2047 (aka "index") + // [5:4] = SBZ + // [3:1] = level = 3'h1 (L2) + // [0] = SBZ + mov x0, #(1 << 1) // x0 = set 0, way 0, level L2 + mov x1, #1 << L2_CACHELINE_SHIFT + mov x2, #1 << (L2_CACHELINE_SHIFT + L2_CACHEINDEX_SHIFT) + mov x3, #1 << (32 - L2_CACHEWAY_SHIFT) + mov x4, #1 << 32 +1: dc cisw, x0 // Clean-invalidate with x0 + // Increment set field. + add x0, x0, x1 // Increment [16:6] + tst x0, x2 // Test for overflow in [17] + b.eq 1b + // Carry set field into way field. + bic x0, x0, x2 // Clear overflow in [17] + add x0, x0, x3 // Increment [31:29] + tst x0, x4 // Test for overflow in [32] + b.eq 1b + // Carry out of way field ends the loop. + // Another dummy TLBI to act as sDsb. + mov x0, #0 + tlbi ASIDE1IS, x0 + dsb sy + isb sy + +#else + +_dup_tags_clean_invalidate: + // Setup EL1 as AArch64, non-secure + mov x1, #SCR_EL1_64_NS + msr SCR_EL3, x1 + // Disable EL1 MMU. + mov x1, #SCTLR_RESERVED & 0xffff + mov x2, #SCTLR_RESERVED & 0xffff0000 + orr x1, x1, x2 + msr SCTLR_EL1, x1 + // Redirect EL1 vectors to 0, which will infinitely abort. We + // should never get an abort here, and can't do anything + // useful if we do anyway. + mov x1, #0 + msr VBAR_EL1, x1 + // Go to EL1. + mov x1, #CPSR_EL1 + msr SPSR_EL3, x1 + adr x1, 1f + msr ELR_EL3, x1 + eret +1: + // Now running EL1 with MMU off. All accesses are device, non-secure. + // Run through dup-tags and clean-invalidate anything marked TZ1=0. + ldr x0, L_ccu0_addr + mov x1, #0 + bl _clean_invalidate_cp_channel + ldr x0, L_ccu1_addr + mov x1, #0 + bl _clean_invalidate_cp_channel + + // Get back to EL3. + adr x0, 1f + smc #0x5ec3 // Secure EL3 (SEC3) +1: + // Now running EL3 with MMU off. All accesses are device, secure. + // Run through dup-tags and clean-invalidate anything marked TZ1=1. + ldr x0, L_ccu0_addr + mov x1, #1 + bl _clean_invalidate_cp_channel + ldr x0, L_ccu1_addr + mov x1, #1 + bl _clean_invalidate_cp_channel + // All L1 and L2 Dcache contents are gone! + +#endif // WITH_DUP_TAGS_CLEAN_INVALIDATE + +_trampoline_finish: +#if VERIFY_INVALIDATION + // Let's "quickly" double-check: all dup-tags should be invalid. + // WARNING: This takes 70 ms when running with quiesced clocks + ldr x0, L_ccu0_addr + bl _verify_invalidated_cp_channel + ldr x0, L_ccu1_addr + bl _verify_invalidated_cp_channel +#endif // VERIFY_INVALIDATION + +#if WITH_ROM_TRAMPOLINE + // Clear remap if enabled to boot this ROM + ldr x1, L_rom_remap_reg + str wzr, [x1] +#endif // WITH_ROM_TRAMPOLINE + + // Reset CPU state + mov x1, #0 + mov x2, #0 + mov x3, #0 + mov x4, #0 + mov x5, #0 + mov x6, #0 + mov x7, #0 + mov x8, #0 + mov x9, #0 + mov x10, #0 + mov x11, #0 + mov x12, #0 + mov x13, #0 + mov x14, #0 + mov x15, #0 + mov x16, #0 + mov x17, #0 + mov x18, #0 + mov x19, #0 + mov x20, #0 + mov x21, #0 + mov x22, #0 + mov x23, #0 + mov x24, #0 + mov x25, #0 + mov x26, #0 + mov x30, x27 // lr = next boot stage PC + mov x0, x28 // x0 = next boot stage info + mov x27, #0 + mov x28, #0 + mov x29, #0 + msr TTBR0_EL3, x1 + msr VBAR_EL3, x1 + msr ELR_EL1, x1 + msr ELR_EL2, x1 + msr ELR_EL3, x1 + msr SPSR_EL1, x1 + msr SPSR_EL2, x1 + msr SPSR_EL3, x1 + msr SP_EL1, x1 + msr SP_EL2, x1 + mov sp, x1 // SP_EL0 + msr SPSel, #1 + mov sp, x1 // SP_EL3 + + // Invalidate I-cache + ic iallu + dsb sy + isb sy + + // Jump to the next stage + ret + +#if WITH_DUP_TAGS_CLEAN_INVALIDATE +_clean_invalidate_cp_channel: + // x0 = pointer to base of channel + // x1 = TZ1 match state, 0=Non-Secure, 1=Secure. + mov x2, #0 // x2 = way = 0..7 +1: mov x3, #0 // x3 = set (index) = 0..1023 +2: ldr w4, [x0], #4 // x4 = duptag for set:x2, way:x3 + ubfx x5, x4, #21, #2 // x5 = duptag[21:20] = state + cmp x5, #0 // Skip this duptag if state=0=invalid + b.eq 9f + ubfx x5, x4, #19, #1 // x5 = TZ1 + cmp x5, x1 // Skip this duptag if TZ1 mismatch + b.ne 9f + ubfx x5, x4, #0, #19 // x5 = address bits[35:17] + lsl x5, x5, #17 + orr x5, x5, x3, lsl #7 // x5 |= index << 7 + // TODO - calculate hash so we know better than accuracy of 2 lines. + dc civac, x5 // Clean-invalidate line. + eor x5, x5, #64 + dc civac, x5 // Clean-invalidate other line of the pair +9: add x3, x3, #1 // Loop over sets (index) + cmp x3, #1024 + b.ne 2b + add x2, x2, #1 // Loop over ways + cmp x2, #8 + b.ne 1b + dsb sy // Memory barrier. + ret +#endif // WITH_DUP_TAGS_CLEAN_INVALIDATE + +#if VERIFY_INVALIDATION +_verify_invalidated_cp_channel: + // x0 = pointer to base of channel + mov x1, #1024 * 8 // Loop over all sets, ways. +1: ldr w2, [x0], #4 // x4 = duptag + ubfx x3, x2, #21, #2 // x5 = duptag[21:20] = state + cmp x3, #0 // Check state=0=invalid + b.ne 9f + sub x1, x1, #1 + cmp x1, #0 + b.ne 1b + ret + // Not really able to panic at this point, so let's just spin. +9: wfe + b 9b +#endif // VERIFY_INVALIDATION + + .balign 8 +L_ccu0_addr: + .8byte CP_0_DT_DBG_CA0_ADDR +L_ccu1_addr: + .8byte CP_1_DT_DBG_CA0_ADDR +L_fuse0_addr: + .8byte CHIPID_BASE_ADDR + 0x00 + +#if WITH_ROM_TRAMPOLINE +L_rom_remap_reg: + .8byte REMAP_REG +L_rom_trampoline_reg: + .8byte SECURITY_REG +L_rom_trampoline_val: + .4byte ROM_READ_DISABLE +#endif // WITH_ROM_TRAMPOLINE + + .balign 64 +L_pointers_base: +#if WITH_ROM_TRAMPOLINE + // in ROM we don't erase TEXT, but we can erase DATA +L_text_base: + .8byte DATA_BASE +L_text_end: + .8byte DATA_BASE + DATA_SIZE +#else + // In non-ROM we erase TEXT_FOOTPRINT, which includes both TEXT and DATA +L_text_base: + .8byte TEXT_BASE +L_text_end: + .8byte TEXT_BASE + TEXT_FOOTPRINT +#endif // WITH_ROM_TRAMPOLINE +L_heap_base: + .8byte HEAP_BASE +L_heap_end: + .8byte HEAP_BASE + HEAP_SIZE +L_stacks_base: + .8byte STACKS_BASE +L_stacks_end: + .8byte STACKS_BASE + STACKS_SIZE +L_page_tables_base: + .8byte PAGE_TABLES_BASE +L_page_tables_end: + .8byte PAGE_TABLES_BASE + PAGE_TABLES_SIZE + .balign 64 +L_pointers_end: + +_boot_handoff_trampoline_end: diff --git a/platform/s7002/amc/amc.c b/platform/s7002/amc/amc.c new file mode 100644 index 0000000..f74b337 --- /dev/null +++ b/platform/s7002/amc/amc.c @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + return amc_init(resume); +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping (void) +{ + rAMC_ADDRCFG = amc_params.addrcfg; + + rAMC_CHNLDEC = amc_params.chnldec; + + rAMC_ADDRMAP_MODE = 2; // RIBI2 + + rAMC_AIU_ADDRBANKHASH2 = amc_params.bankhash2; + rAMC_AIU_ADDRBANKHASH1 = amc_params.bankhash1; + rAMC_AIU_ADDRBANKHASH0 = amc_params.bankhash0; +} + +void amc_enable_slow_boot (bool enable) +{ + if (enable) { + // switch to slow clock + clocks_set_performance(kPerformanceMemoryLow); + spin(1); + } else { +#if !SUPPORT_FPGA + // switch back to full-speed + clocks_set_performance(kPerformanceMemoryFull); + spin(1); +#endif + } +} + +// Some AMC features to be changed before calibration starts, and restored after calibration is complete +void amc_calibration_start(bool start) +{ + if (start) + // Disable OdtsRdIntrvl + rAMC_ODTS &= 0xFFFFFC00; + else + // Re-enable OdtsRdIntrvl + rAMC_ODTS |= amc_params.odts; +} + +void amc_enable_rddqcal(bool enable) +{ + if (enable) + rAMC_READ_LEVELING |= 1; + else + rAMC_READ_LEVELING &= ~1; +} + +void amc_wrdqcal_start(bool start) +{ + if (start) { + // Enable WriteMergeEn and WqInOrderEn + rAMC_PSQWQCTL0 = (1 << 8) | (1 << 0); + + // Set SelfRefTmrVal to max + rAMC_PWRMNGTPARAM |= (0xFFFF << 16); + + // Designer suggests 0xBB, so that writes do not age out + rAMC_PSQWQCTL1 = 0xBB; + } else { + rAMC_PSQWQCTL0 = 0x00010100; + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_guided; + // WqAgeOutVal has to be set to 3/4 of SelfRefTmrVal + rAMC_PSQWQCTL1 = (3 * ((amc_params.pwrmngtparam_guided & 0xFFFF0000) >> 16)) >> 2; + + // Enabling AutoSR only after wrdqcal is done + rAMC_PWRMNGTEN |= 0x00011011; + } +} + +void amc_finalize (bool resume) +{ + rAMC_AREFPARAM |= 0x00001800; + + rAMC_QBREN = 0x00110001; + + if (!resume) { +#if SUPPORT_FPGA + rAMC_ODTS = amc_params.odts; +#else + rAMC_ODTS = 0x00010000 | amc_params.odts; +#endif + amc_enable_autorefresh(); + } + + rAMC_ZQC = 0x010c03ff; +#if !SUPPORT_FPGA + rAMC_AIUPRT_RD_CWF = 0x00323200; +#endif + rAMC_QBRPARAM = 0x00510000; + rAMC_QBREN = 0x00111001; + + rAMC_PSQWQCTL0 = 0x00010100; + +#if SUPPORT_FPGA + rAMC_PWRMNGTEN = 0x00110010; +#else + rAMC_PWRMNGTEN = 0x00111011; + rAMC_PWRMNGTPARAM = amc_params.pwrmngtparam_guided; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + // No work-arounds for Hynix ... yet! + break; + + case JEDEC_MANUF_ID_ELPIDA: + /* Filter only for Elpida 25nm to apply test MRS */ + if ((dev_info->rev_id == 0x2) && (dev_info->rev_id2 <= 0x2)) { // MR6 = 2(25nm) and MR7 = 2(Rev2) + if (!resume) { + // Elpida has no TestMRS entry/exit cmd + // Fiji: Need Duty Cycle Adjust work-around to improve Fiji+Elpida 25nm DDR eye margin + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xbb); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x27); + } + } + break; + + default: + break; + } + + return; +} + +// Shift dq offset as needed. +// In the future, it's possible the shift value changes based on SOC or DRAM vendor. +// Thus, we need to have this function per SOC. +void amc_dram_shift_dq_offset (int8_t *dq_offset, uint8_t num_bytes) { + int8_t shift_val; + uint8_t i; + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + // No shifts defined by SEG yet for M7 + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + case JEDEC_MANUF_ID_SAMSUNG: + case JEDEC_MANUF_ID_ELPIDA: + default: + shift_val = 0; + break; + } + + if (shift_val) + for (i = 0; i < num_bytes; i++) + dq_offset[i] += shift_val; +} +#if WITH_HW_RECONFIG + +#define CALIB_TYPE_CAWRLVL 0 +#define CALIB_TYPE_DQWRLVL 1 + +// M7 MEM Reconfig sequence: remove phyupdates +#if 0 +static void amp_phy_update_reconfig(uint32_t update) +{ + // Release CKE and disable phyupdt to allow normal operation + if (!update) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_TESTMODE(AMP_CA,0), 0, 0); + + // issue phyupdt to block AMC traffic + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_CAPHYUPDTCRTL(0), update, 0); + + // wait for the phyupdt change to take effect. there is only 1 bit in the status reg: bit 0. + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_CAPHYUPDTSTATUS(0)) | RECONFIG_RAM_CMD_READ, (update & 1), 1); + + // CKE must be low when updating dlysel to avoid glitches + if (update) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_TESTMODE(AMP_CA,0), TESTMODE_FORCECKELOW, 0); +} +#endif + +static void amp_wrlvl_program_reconfig(uint32_t calib_type, uint32_t byte) +{ + addr_t codeaddr, dlyaddr; + uint32_t code, dly; + + if (calib_type == CALIB_TYPE_CAWRLVL) { + codeaddr = (addr_t) &rAMP_CAWRLVLSDLLCODE(0); + code = rAMP_CAWRLVLSDLLCODE(0); + dlyaddr = (addr_t) &rAMP_CAWRLVLCLKDLYSEL(0); + dly = rAMP_CAWRLVLCLKDLYSEL(0); + } else { + codeaddr = (addr_t) &rAMP_DQWRLVLSDLLCODE(0, byte); + dlyaddr = (addr_t) &rAMP_DQWRLVLDLYCHAINCTRL(0, byte); + code = rAMP_DQWRLVLSDLLCODE(0, byte); + dly = rAMP_DQWRLVLDLYCHAINCTRL(0, byte); + } + + reconfig_append_command(RECONFIG_TYPE_MEM, codeaddr, code, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, dlyaddr, dly, 0); +} + +void amc_configure_mem_reconfig_ram(void) +{ + uint32_t f, i; +#if !SUPPORT_FPGA + uint32_t byte, bit; +#endif + + /* Step 1: AMC Initial Configuration */ + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLSTS(AMP_DQ,0), 0x00017307, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLSTS(AMP_CA,0), 0x00017307, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_LAT, (amc_params.rdlat << 16) | (amc_params.wrlat << 8), 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PHYRDWRTIM, (amc_params.phywrlat << 16) | (amc_params.phyrdlat << 8) | (amc_params.rdlat - 2), 0); + + for(f = 0; f < AMC_FREQUENCY_SLOTS; f++) { + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_CAS_FREQ(f), amc_params.freq[f].cas, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PCH_FREQ(f), amc_params.freq[f].pch, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ACT_FREQ(f), amc_params.freq[f].act, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AUTO_FREQ(f), amc_params.freq[f].autoref | ((f == 0) ? amc_params.tREFi : 0), 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_SELF_FREQ(f), amc_params.freq[f].selfref, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_MODE_FREQ(f), amc_params.freq[f].modereg, 0); + } + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AUTOREF_PARAMS, amc_params.autoref_params, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PDN, amc_params.pdn, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_DERATE, amc_params.derate, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_RD, amc_params.read, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_BUSTAT, amc_params.bustat, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_BUSTAT_FREQ23, amc_params.bustat2, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_TREFBWBASECYC_FREQ(0), amc_params.freq[0].trefbwbasecyc, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_TREFBWBASECYC_FREQ(1), amc_params.freq[1].trefbwbasecyc, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_TREFBWBASECYC_FREQ(2), amc_params.freq[2].trefbwbasecyc, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_MIFCASSCH_FREQ(0), amc_params.freq[0].mifcassch, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_CH0RNKCFG0, 1, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PWRMNGTEN, amc_params.pwrmngten_default, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_SCHEN, amc_params.schen_default, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_MCPHY_UPDTPARAM1, amc_params.mcphyupdate1, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_MCPHY_UPDTPARAM, amc_params.mcphyupdate, 0); + + // AMCEN + { + uint32_t amc_en = 0x00000001; + + if (amc_params.flags & FLAG_AMC_PARAM_LEGACY) + { + amc_en |= 0x80000000; + } + if (amc_params.flags & FLAG_AMC_PARAM_ENABLE_AIU) + { + amc_en |= 0x10000; + } + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AMCEN, amc_en, 0); + } + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AIU_ADDRBANKHASH2, amc_params.bankhash2, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AIU_ADDRBANKHASH1, amc_params.bankhash1, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AIU_ADDRBANKHASH0, amc_params.bankhash0, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ADDRMAP_MODE, 2, 0); + + /* Step 2: AMP Initial Configurations */ + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_AMPEN(AMP_CA,0), 1, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_AMPEN(AMP_DQ,0), 1, 0); + +#if !SUPPORT_FPGA + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DQDQSDS(0), amc_phy_params.drive_strength, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_NONDQDS(0), amc_phy_params.drive_strength, 0); +#endif + // DIFFMODE_FREQ[n], n=0..3 + for(f = 0; f < AMP_FREQUENCY_SLOTS; f++) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DIFFMODE_FREQ(0,f), 0x00000121, 0); + +#if !SUPPORT_FPGA + // RDnDQm_DESKEW_CTRL, n=0..3, m=0..7 + for(byte = 0; byte < AMP_MAX_RD; byte++) + for(bit = 0; bit < AMP_MAX_DQ; bit++) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_RDDQDESKEW_CTRL(0, byte, bit), 0x00000006, 0); + + // DLLLOCKTIM + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLLOCKTIM(AMP_CA,0), 0x000d0013, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLLOCKTIM(AMP_DQ,0), 0x000d0013, 0); +#endif + + for(f = 0; f < AMP_FREQUENCY_SLOTS; f++) { + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_CAOUTDLLSCL_FREQ(0,f), amc_phy_params.freq[f].caoutdllscl, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DQSINDLLSCL_FREQ(0,f), amc_phy_params.freq[f].dqsindllscl, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_RDCAPCFG_FREQ(AMP_DQ,0,f), amc_phy_params.freq[f].rdcapcfg, 0); + } + +#if !SUPPORT_FPGA + // DLLUPDTCTRL + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTCTRL(AMP_CA,0), 0x00017507, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTCTRL(AMP_DQ,0), 0x00017507, 0); + // IMPAUTOCAL + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_IMPAUTOCAL(AMP_DQ,0), amc_phy_params.imp_auto_cal, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_IMPAUTOCAL(AMP_CA,0), amc_phy_params.imp_auto_cal, 0); +#endif + + // DLLUPDTINTVL +#if !SUPPORT_FPGA + uint32_t dllupdtintvl = 0x10200000; +#else + uint32_t dllupdtintvl = 0; +#endif + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTINTVL(AMP_CA,0), dllupdtintvl, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTINTVL(AMP_DQ,0), dllupdtintvl, 0); + + // DLLEN sequence +#if !SUPPORT_FPGA + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLEN(AMP_CA,0), 0x00000100, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLEN(AMP_DQ,0), 0x00000100, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLEN(AMP_CA,0), 0x00000101, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLEN(AMP_DQ,0), 0x00000101, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLEN(AMP_CA,0), 0x00000100, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLEN(AMP_DQ,0), 0x00000100, 0); +#endif + + // MDLLFREQBINDISABLE +#if !SUPPORT_FPGA + uint32_t mdllfreqbindisable = 0x00000008; +#else + uint32_t mdllfreqbindisable = 0x0000000f; +#endif + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_MDLLFREQBINDISABLE(AMP_CA,0), mdllfreqbindisable, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_MDLLFREQBINDISABLE(AMP_DQ,0), mdllfreqbindisable, 0); + + // DLLUPDTCMD +#if !SUPPORT_FPGA + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTCMD(AMP_CA,0), 0x00000001, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTCMD(AMP_DQ,0), 0x00000001, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_DLLUPDTCMD(AMP_CA,0)) | RECONFIG_RAM_CMD_READ, 0, 1); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_DLLUPDTCMD(AMP_DQ,0)) | RECONFIG_RAM_CMD_READ, 0, 1); +#endif + + // AMPINIT + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_AMPINIT(AMP_CA,0), 0x00000001, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_AMPINIT(AMP_DQ,0), 0x00000001, 0); + // IMPCALCMD sequence +#if !SUPPORT_FPGA + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_IMPCALCMD(AMP_CA,0), 0x00000101, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_IMPCALCMD(AMP_DQ,0), 0x00000101, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_IMPCALCMD(AMP_CA,0)) | RECONFIG_RAM_CMD_READ, 0, 1); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_IMPCALCMD(AMP_DQ,0)) | RECONFIG_RAM_CMD_READ, 0, 1); +#endif + + /* Step 3: Self-Refresh Exit */ + +#if !SUPPORT_FPGA + /* CA calibration offsets */ + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_CASDLLCTRL(0), (1 << 24) | (rAMP_CASDLLCTRL(0)), 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_CASDLLCTRL(0)) | RECONFIG_RAM_CMD_READ, 0, (1 << 24)); + + for (bit = 0; bit < CA_NUM_BITS; bit++) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_CADESKEW_CTRL(0,bit), rAMP_CADESKEW_CTRL(0,bit), 0); + + // ck: skip if 0, since that is reset value + uint32_t caclk = rAMP_CKDESKEW_CTRL(0); + if (caclk) { + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_TESTMODE(AMP_CA,0), TESTMODE_FORCECKELOW, 0); + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DRAMSIGDLY(AMP_CA, 0, 0), rAMP_DRAMSIGDLY(AMP_CA, 0, 0), 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_CSDESKEW_CTRL(0), caclk, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_CKDESKEW_CTRL(0), caclk, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_CKEDESKEW_CTRL(0), caclk, 0); + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_TESTMODE(AMP_CA,0), 0, 0); + } + + /* WrLvl calibration offsets */ + + amp_wrlvl_program_reconfig(CALIB_TYPE_CAWRLVL, 0); + for (byte = 0; byte < DQ_NUM_BYTES; byte++) + amp_wrlvl_program_reconfig(CALIB_TYPE_DQWRLVL, byte); +#endif + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AREFPARAM, amc_params.freq[0].arefparam, 0); + for (f = 1; f < AMC_FREQUENCY_SLOTS; f++) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AREFPARAM_FREQ(f), amc_params.freq[f].arefparam, 0); + +#if !SUPPORT_FPGA + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ODTS, amc_params.odts | 0x00010000, 0); +#else + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ODTS, amc_params.odts, 0); +#endif + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_LONGSR, 0x01000000 | amc_params.longsrcnt | amc_params.srextrarefcnt, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AREFEN_FREQ(3), 0, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AREFEN_FREQ(2), 0, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AREFEN_FREQ(1), amc_params.aref_freq1, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AREFEN_FREQ(0), 0x01011001 | amc_params.aref_freq0, 0); + // INITCMDCH0 + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_CH0INITCMD, 0x1000, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMC_CH0INITCMD) | RECONFIG_RAM_CMD_READ, 0, 0x1000); + + /* Step 4: DRAM Reset, skipped for resume boot */ + + /* Step 5: Topology-specific configuration */ + + // ZQC + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ZQC, 0x00090000, 0); + // MR10: ZQCL + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_CH0MRCMD, 0xab000a01, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMC_CH01MRSTATUS) | RECONFIG_RAM_CMD_READ, 0, 1); + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ZQC, 0x00080000, 0); + // ADDRCFG + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ADDRCFG, amc_params.addrcfg, 0); + // CHNLDEC + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AIU_CHNLDEC, amc_params.chnldec, 0); + + /* Step 6: Switch from boot-clock speed to normal operation speed */ + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_SCHEN, amc_params.schen_default | 0x1, 0); + + /* Step 7: CA and Rddq calibration, skipped for resume boot */ + + /* Step 8: Enable other features */ + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AREFPARAM, amc_params.freq[0].arefparam | 0x00001800, 0); + // ZQC + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_ZQC, 0x010c03ff, 0); + // QBREN + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_QBREN, 0x00110001, 0); + // PSQWQCTRL0 + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PSQWQCTL0, 0x00010100, 0); + + /* Step 9: Enable the Fast Critical Word Forwarding feature */ + + // RD_CWF +#if !SUPPORT_FPGA + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AIUPRT_RD_CWF, 0x00323200, 0); +#else + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_AIUPRT_RD_CWF, 0, 0); +#endif + // QBRPARAM + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_QBRPARAM, 0x00510000, 0); + // QBREN + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_QBREN, 0x00111001, 0); + + /* Step 10: Rddq and Wrdq offsets, restore dllupdtintvl POR value */ + +#if !SUPPORT_FPGA + /* Rddq calibration offsets */ + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DQSDLLCTRL_RD(0, byte), (1 << 24) | rAMP_DQSDLLCTRL_RD(0, byte), 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_DQSDLLCTRL_RD(0, byte)) | RECONFIG_RAM_CMD_READ, 0, (1 << 24)); + + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_RDDQDESKEW_CTRL(0, byte, bit), rAMP_RDDQDESKEW_CTRL(0, byte, bit), 0); + } + + /* Wrdq calibration offsets */ + + for (byte = 0; byte < DQ_NUM_BYTES; byte++) { + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DQSDLLCTRL_WR(0, byte), (1 << 24) | rAMP_DQSDLLCTRL_WR(0, byte), 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_DQSDLLCTRL_WR(0, byte)) | RECONFIG_RAM_CMD_READ, 0, (1 << 24)); + + // rAMP_DQWRLVLDLYCHAINCTRL.WrLvlClk90Dly already restored as part of wrlvl offset restorations + + for (bit = 0; bit < DQ_NUM_BITS_PER_BYTE; bit++) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_WRDQDESKEW_CTRL(0, byte, bit), rAMP_WRDQDESKEW_CTRL(0, byte, bit), 0); + + // DM controlled by DQS register + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_WRDQSDESKEW_CTRL(0, byte), rAMP_WRDQSDESKEW_CTRL(0, byte), 0); + + // DQS controlled by DM register + uint32_t dqs_deskew = rAMP_WRDMDESKEW_CTRL(0, byte); + // skip if 0, since that is reset value + if (dqs_deskew) + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_WRDMDESKEW_CTRL(0, byte), dqs_deskew, 0); + } + + // DLLUPDTCMD + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTCMD(AMP_CA,0), 0x00000001, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTCMD(AMP_DQ,0), 0x00000001, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_DLLUPDTCMD(AMP_CA,0)) | RECONFIG_RAM_CMD_READ, 0, 1); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMP_DLLUPDTCMD(AMP_DQ,0)) | RECONFIG_RAM_CMD_READ, 0, 1); +#endif + + // DLLUPDTINTVL +#if !SUPPORT_FPGA + dllupdtintvl = 0x1020005a; +#else + dllupdtintvl = 0; +#endif + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTINTVL(AMP_CA,0), dllupdtintvl, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_DLLUPDTINTVL(AMP_DQ,0), dllupdtintvl, 0); + + /* Step 11: Enable Power & ClockGating features */ + + // AMPCLK + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_AMPCLK(AMP_CA,0), 0x00010000, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMP_AMPCLK(AMP_DQ,0), 0x00010000, 0); +#if SUPPORT_FPGA + // PWRMNGTEN + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PWRMNGTEN, 0x00110010, 0); +#else + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PWRMNGTEN, 0x00111011, 0); +#endif +#if !SUPPORT_FPGA + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PWRMNGTPARAM, amc_params.pwrmngtparam_guided, 0); + // PSQWQCTL1 + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_PSQWQCTL1, 0x00000120, 0); +#endif + + /* Step 12: Do a ODTS Read */ + + // MR4 + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) &rAMC_CH0MRCMD, 0x00000411, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t) &rAMC_CH01MRSTATUS) | RECONFIG_RAM_CMD_READ, 0, 1); + + /* AMC Tunables */ + for (i = 0; i < sizeof(amc_tunables) / sizeof(amc_tunables[0]); i++) { + if (amc_tunables[i].reg == 0) + break; + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t) amc_tunables[i].reg, amc_tunables[i].value, 0); + } + +} + +#endif // WITH_HW_RECONFIG diff --git a/platform/s7002/amc/rules.mk b/platform/s7002/amc/rules.mk new file mode 100644 index 0000000..d506782 --- /dev/null +++ b/platform/s7002/amc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AMC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/amc.o diff --git a/platform/s7002/asm.S b/platform/s7002/asm.S new file mode 100644 index 0000000..1e2b948 --- /dev/null +++ b/platform/s7002/asm.S @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + +#if APPLICATION_IBOOT && (PRODUCT_IBSS || PRODUCT_LLB) + + .text + .arm + .align 12 + .globl _boot_handoff_trampoline, _boot_handoff_trampoline_end +_boot_handoff_trampoline: + // Reset VBAR to 0 + mov r1, #0 // iBSS and LLB doesn't pass forward anything to next stage. + mcr p15, 0, r1, c12, c0, 0 + isb + bx r0 +_boot_handoff_trampoline_end: + + .text + .arm + .align 12 + .globl _platform_start +_platform_start: + // Use VBAR to relocate exception vectors to binary linked address + mcr p15, 0, r0, c12, c0, 0 + isb + bx lr + +#endif diff --git a/platform/s7002/chipid/chipid.c b/platform/s7002/chipid/chipid.c new file mode 100644 index 0000000..ad4a30a --- /dev/null +++ b/platform/s7002/chipid/chipid.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +bool chipid_get_current_production_mode(void) +{ + return ((rCFG_FUSE0 >> 0) & 1) != 0; +} + +bool chipid_get_raw_production_mode(void) +{ + return ((rCFG_FUSE0_RAW >> 0) & 1) != 0; +} + +void chipid_clear_production_mode(void) +{ + rCFG_FUSE0 &= ~1; +} + +bool chipid_get_secure_mode(void) +{ + // we never demote secure mode on platforms that don't have an SEP + return ((rCFG_FUSE0_RAW >> 1) & 1) != 0; +} + +uint32_t chipid_get_security_domain(void) +{ + return (rCFG_FUSE0 >> 2) & 3; +} + +uint32_t chipid_get_board_id(void) +{ + return (rCFG_FUSE0 >> 4) & 3; +} + +uint32_t chipid_get_minimum_epoch(void) +{ + return (rCFG_FUSE0 >> 9) & 0x7F; +} + +uint32_t chipid_get_chip_id(void) +{ + return 0x7002; +} + +uint32_t chipid_get_chip_revision(void) +{ + return (((rCFG_FUSE0 >> 25) & 0x7) << 4) | (((rCFG_FUSE0 >> 22) & 0x7) << 0); +} + +uint32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +uint64_t chipid_get_ecid_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint64_t chipid_get_die_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint32_t chipid_get_soc_voltage(uint32_t index) +{ + uint32_t soc_voltage = 0; + + return soc_voltage; +} + +uint32_t chipid_get_cpu_voltage(uint32_t index) +{ + uint32_t cpu_voltage = 0; + + return cpu_voltage; +} + + +uint32_t chipid_get_ram_voltage(uint32_t index) +{ + uint32_t sram_voltage = 0; + + return sram_voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return (rCFG_FUSE1 & (1 << 31)) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) rCFG_FUSE1 |= (1 << 31); +} + +uint32_t chipid_get_fuse_revision(void) +{ + return (rCFG_FUSE0 >> 18) & 0xf; +} + +uint32_t chipid_get_total_rails_leakage() +{ + uint32_t total_leakage; + uint32_t leakage_data0; + uint8_t leakage_data1; + + leakage_data0 = rCFG_FUSE5; + leakage_data1 = (rCFG_FUSE4 >> 31) & 1; + + total_leakage = ((leakage_data0 >> 28) & 0xf) + 1; // soc_sram: cfg_fuse4[31:28] + total_leakage += ((leakage_data0 >> 24) & 0xf) + 1; // cpu_sram: cfg_fuse4[27:24] + total_leakage += ((leakage_data0 >> 16) & 0xff) + 1; // gpu: cfg_fuse4[23:16] + total_leakage += ((leakage_data0 >> 8) & 0xff) + 1; // soc: cfg_fuse4[15:8] + total_leakage += ((((leakage_data0 >> 0) & 0xff) << 1) | leakage_data1) + 1; // cpu: cfg_fuse4[7:0], cfg_fuse4[31] + + return total_leakage; +} diff --git a/platform/s7002/chipid/rules.mk b/platform/s7002/chipid/rules.mk new file mode 100644 index 0000000..240c155 --- /dev/null +++ b/platform/s7002/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/s7002/include/platform/amcconfig.h b/platform/s7002/include/platform/amcconfig.h new file mode 100644 index 0000000..1b7e1ac --- /dev/null +++ b/platform/s7002/include/platform/amcconfig.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .flags = FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_ENABLE_AIU | FLAG_AMC_PARAM_LEGACY | FLAG_AMC_PARAM_ZQCL, + + .freqsel = 3, + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = (0x2 << 16), + .rdlat = 4, + .wrlat = 2, + .phyrdlat = 8, + .phywrlat = 1, + .pdn = 0x22000303, + .read = 0x00000102, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .derate = 0x1c620d46, + .mcphyupdate = 0x05030000, + .mcphyupdate1 = 0x00000004, + .autoref_params = 0x1a1a1a1a, + .chnldec = 0x00050001, + .qbrparam = 0x00510000, + .odts = 0x190, + .aref_freq0 = 0x00000110, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01803000, + .schen_default = 0x00000110, + .pwrmngten_default = 0x00100100, + .addrcfg = 0x00020201, + .bankhash0 = 0x00006db6, + .bankhash1 = 0x00005b6d, + .bankhash2 = 0x000036db, + .bootclkdivsr = 1, + .mr1 = 0xc4, + .mr3 = 0x2, + .mr2 = 0x6, + .mr63 = 0xfc, + .readleveling = 0x00000300, + + .freq = { + { // 533MHz + .cas = 0x00000206, + .pch = 0x0002040c, + .act = 0x0c040706, + .autoref = 0x11240000, + .selfref = 0x00026040, + .modereg = 0x20190762, + .arefparam = 0x0c022131, + .mifcassch = 0x00000110, + .trefbwbasecyc = 0x0000002d, + }, + { // 266MHz + .cas = 0x00000004, + .pch = 0x00000007, + .act = 0x06020404, + .autoref = 0x09120000, + .selfref = 0x00014000, + .modereg = 0x000d0000, + .arefparam = 0x00000101, + .mifcassch = 0x00000000, + .trefbwbasecyc = 0x00000017, + }, + { // 133MHz + .cas = 0x00000002, + .pch = 0x00000004, + .act = 0x04010302, + .autoref = 0x050a0000, + .selfref = 0x0000a000, + .modereg = 0x00070000, + .arefparam = 0x00000101, + .mifcassch = 0x00000000, + .trefbwbasecyc = 0x0000000c, + }, + { // 24MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02030000, + .selfref = 0x00003000, + .modereg = 0x00020000, + .arefparam = 0x00000101, + .mifcassch = 0x00000010, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_AIUPRT_CFG, 0x00070000}, + { &rAMC_AIUPRT_RD_GEN, 0x80000018}, + { &rAMC_AIU_CHNLCRD, 0x00180018}, + { &rAMC_AIU_CHNLTM, 0x40003101}, + { &rAMC_AIU_RDBRSTLEN, 0x01010101}, + { &rAMC_AIU_RDMAXCRD, 0x3012097f}, + { &rAMC_AIU_RDREFL, 0x280f087f}, + { &rAMC_AIU_WRBRSTLEN, 0x01010101}, + { &rAMC_AIU_WRMAXCRD, 0x3012097f}, + { &rAMC_AIU_WRREFL, 0x280f087f}, + { &rAMC_AIU_CPUSPCREQ, 0x00000013}, + { &rAMC_AIU_GFXSPCREQ, 0x00000019}, + { &rAMC_AIU_NRTSPCREQ, 0x00000019}, + { &rAMC_AIU_RTSPCREQ, 0x00000013}, + { &rAMC_AIU_WPQSCH, 0x08000800}, + { &rAMC_AIU_THOTLEN, 0x00000030}, + { &rAMC_AIU_THOTLCPUPARAM, 0x00000084}, + { &rAMC_AIU_THOTLRTPARAM, 0x00000084}, + { &rAMC_AIU_THOTLNRTPARAM, 0x00000080}, + { &rAMC_AIU_THOTLGFXPARAM, 0x00000080}, + { &rAMC_AIU_PUSHEN, 0x00001100}, + { &rAMC_AIU_THOTLCPUPARAM2, 0x00c00040}, + { &rAMC_AIU_THOTLRTPARAM2, 0x00c00040}, + { &rAMC_AIU_THOTLNRTPARAM2, 0x00000040}, + { &rAMC_AIU_THOTLGFXPARAM2, 0x00000040}, + { &rAMC_AIU_LLTSCHCTL, 0x00000001}, + { &rAMC_OPIDLETMR, 0x00200000}, + { &rAMC_OPTMRADJPARAM, 0x20400064}, + { &rAMC_MIFACTSCH, 0x00000001}, + { &rAMC_PSQRQCTL0, 0x01010000}, + { &rAMC_PSQRQCTL1, 0x0000132a}, + { &rAMC_PSQRQTIMER0, 0x00000018}, + { &rAMC_PSQRQTIMER1, 0x00000006}, + { &rAMC_PSQRQTIMER2, 0x00000020}, + { &rAMC_PSQRQBRST, 0x040c040c}, + { &rAMC_PSQRQSCHCRD, 0x002028f5}, + { &rAMC_PSQWQCTL1, 0x00000180}, + { &rAMC_PSQWQBRST, 0x02020208}, + { &rAMC_PSQWQSCHCRD, 0x000405f5}, + { &rAMC_MCUQOS, 0x00010f04}, + { &rAMC_MCUQOSLLT, 0x00010108}, + + {0, 0}, +}; +#endif diff --git a/platform/s7002/include/platform/ampconfig.h b/platform/s7002/include/platform/ampconfig.h new file mode 100644 index 0000000..0f25383 --- /dev/null +++ b/platform/s7002/include/platform/ampconfig.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amp/amp.h, and this + * file should only by included from that amp.c. + */ + +#if WITH_TARGET_AMP_PARAMS +#include +#else +static struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x2102050b, + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x31020507, + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x51020505, + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61020504, + }, + }, + .drive_strength = 0x12121212, + .cacalib_hw_loops = 8, + .cacalib_sw_loops = 8, + .wrlvl_togglephyupdt = true, + .imp_auto_cal = 0x001103ac, +}; +#endif diff --git a/platform/s7002/include/platform/dmin.h b/platform/s7002/include/platform/dmin.h new file mode 100644 index 0000000..1495889 --- /dev/null +++ b/platform/s7002/include/platform/dmin.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + /* + * Dmin.h is provided by the diags team, defining the 'DMin' key's format + * The contents below are copy-pasted verbatim from header files supplied by Diags. + */ + + +#ifndef _DMin_h_ +#define _DMin_h_ + +/* vim: set ts=4 sw=4 softtabstop=4 noexpandtab */ + +#include + +#ifndef MULTICHARACTER_LITERAL +# define MULTICHARACTER_LITERAL(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) +#endif + +enum { + kEnclosureNone = 0, + kEnclosureAlumLight6063 = 1, + kEnclosureAlumDark6063 = 2, + kEnclosureAlumLight7003 = 3, + kEnclosureAlumDark7003 = 4, + kEnclosureSUSMirror = 5, + kEnclosureSUSBrushed = 6, + kEnclosureSUSBlackPVD = 7, + kEnclosureMaverickYellow = 8, + kEnclosureMaverickRose = 9, + kEnclosureZirconiaWhite = 10, + kEnclosureGlass = 11, +}; +typedef uint32_t EnclosureType_t; // goes with above enum + +enum { + kFCMTypeNone = 0, + kFCMTypeOnyx = 1, + kFCMTypeGlass = 2, +}; +typedef uint32_t FCMType_t; // goes with above + +enum { + kBCMWindowTypeNone = 0, + kBCMWindowTypeOnyx = 1, + kBCMWindowTypeGlass = 2, +}; +typedef uint32_t BCMWindowType_t; + +enum { + kBCMLensTypeNone = 0, + kBCMLensTypeNormal = 1, + kBCMLensTypeFresnel = 2, +}; +typedef uint32_t BCMLensType_t; + +enum { + kBCMLEDTypeNone = 0, + kBCMLEDTypeNormal = 1, + kBCMLEDTypeNew = 2, +}; +typedef uint32_t BCMPTLEDType_t; + +enum { + kBCMPlatinumTypeNone = 0, + kBCMPlatinumTypeProtoN_34 = 1, + kBCMPlatinumTypeProtoC = 2, +}; +typedef uint32_t BCMPTSensorType_t; + +/* Version 2 information - added Lisa Bits */ + +enum { + kLisaOpAmpNone = 0, + kLisaOpAmpMAX4321 = 1, + kLisaOpAmpLMV693 = 2, + kLisaOpAmpLMV881 = 3, +}; +typedef uint32_t LisaOpAmpType_t; + +enum { + kLisaSensorICNone = 0, + kLisaSensorICA0 = 1, + kLisaSensorICB0 = 2, +}; +typedef uint32_t LisaSensorICType_t; + +enum { + kLisaWheelNone = 0, + kLisaWheelLF31 = 1, + kLisaWheelLF31LowDiffusion = 2, + kLisaWheelLF31HighStripeVar = 3, + kLisaWheelLF31pSLaser = 4, + kLisaWheelLF45 = 5, + kLisaWheelSantek = 6, + kLisaWheelNisseiBlack = 7, + kLisaWheelNissei = 8, + kLisaWheelHeptagonGrind = 9, + kLisaWheelHeptagonFormed = 10 +}; +typedef uint32_t LisaWheelType_t; + +enum { + kLisaKnurlNone = 0, + kLisaKnurlProtoN = 1, +}; +typedef uint32_t LisaKnurlType_t; + +/* Pack the structure, do not allow compiler padding */ +typedef struct __attribute__((packed)) { + EnclosureType_t topEnclosure; // See enum at the top + EnclosureType_t botEnclosure; // Same values here + FCMType_t fcmType; // Onyx or Glass + uint32_t fcmARCoated; // 0x00000000 = no AR coating, 0x00000001 = AR coating + uint32_t fcmInkColor; // 0x00RRGGBB (little endian, 32-bit word, just like DClr) + BCMWindowType_t bcmWindow; // Onyx or Glass + BCMLensType_t bcmLens; // Normal or Fresnel + BCMPTSensorType_t bcmPTSensorType; // 3 or 4 + BCMPTLEDType_t bcmPTLEDType; // Normal or "New" +} DMin_v1_t; + +typedef struct __attribute__((packed)) { + EnclosureType_t topEnclosure; // See enum at the top + EnclosureType_t botEnclosure; // Same values here + FCMType_t fcmType; // Onyx or Glass + uint32_t fcmARCoated; // 0x00000000 = no AR coating, 0x00000001 = AR coating + uint32_t fcmInkColor; // 0x00RRGGBB (little endian, 32-bit word, just like DClr) + BCMWindowType_t bcmWindow; // Onyx or Glass + BCMLensType_t bcmLens; // Normal or Fresnel + BCMPTSensorType_t bcmPTSensorType; // 3 or 4 + BCMPTLEDType_t bcmPTLEDType; // Normal or "New" + + // v2 bits + LisaOpAmpType_t lisaOAType; + LisaSensorICType_t lisaSensorIC; + LisaWheelType_t lisaEncoderWheel; + LisaKnurlType_t lisaKnurl; +} DMin_v2_t; + +#define DMIN_VERSION_1 0x00000001 +#define DMIN_VERSION_2 0x00000002 + +typedef struct { + uint32_t version; // Set to DMIN_VERSION_2 + union { + DMin_v1_t v1; // if version == DMIN_VERSION_1, use this struct + DMin_v2_t v2; // if version == DMIN_VERSION_2, use this struct + }; // Anonymous union to bridge between v1 and any later version +}DMin_t; + +#define SYSCFG_DEVICE_MATERIAL_INFO_SIZE (sizeof(DMin_t)) /* v1 = 40 bytes, v2 = 56 bytes */ +#define SYSCFG_DEVICE_MATERIAL_INFO MULTICHARACTER_LITERAL('D','M','i','n') + +#endif /* _DMin_h_ */ diff --git a/platform/s7002/include/platform/dockfifo_config.h b/platform/s7002/include/platform/dockfifo_config.h new file mode 100644 index 0000000..52c730c --- /dev/null +++ b/platform/s7002/include/platform/dockfifo_config.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DOCKFIFO_CONFIG_H +#define __DOCKFIFO_CONFIG_H + +#include +#include +#include + +// Fifo enumeration +#define DOCKFIFO_UART_WRITE (DOCKFIFO_0) +#define DOCKFIFO_UART_READ (DOCKFIFO_1) +#define DOCKFIFO_BULK_WRITE (DOCKFIFO_2) +#define DOCKFIFO_BULK_READ (DOCKFIFO_3) + +static const struct dockfifo_config dockfifo_configs[] = { + /* read/write clock interrupt fifo name */ + { DOCKFIFO_W, CLK_DOCKFIFO, DBGFIFO_0_NOT_EMPTY, "uart write" }, + { DOCKFIFO_R, CLK_DOCKFIFO, DBGFIFO_1_NOT_EMPTY, "uart read" }, + { DOCKFIFO_W, CLK_DOCKFIFO, DBGFIFO_2_NOT_EMPTY, "bulk write" }, + { DOCKFIFO_R, CLK_DOCKFIFO, DBGFIFO_3_NOT_EMPTY, "bulk read" }, +}; + +#endif /* __DOCKFIFO_CONFIG_H */ diff --git a/platform/s7002/include/platform/gpiodef.h b/platform/s7002/include/platform/gpiodef.h new file mode 100644 index 0000000..72cf06b --- /dev/null +++ b/platform/s7002/include/platform/gpiodef.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* S7002 specific gpio -> pin mappings */ + +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_BOARD_ID0 GPIOC(GPIO_AP, 12, 1) +#define GPIO_BOARD_ID1 GPIOC(GPIO_AP, 12, 2) +#define GPIO_BOARD_ID2 GPIOC(GPIO_AP, 12, 3) +#define GPIO_BOARD_ID3 GPIOC(GPIO_AP, 4, 6) +#define GPIO_BERMUDA_TO_AP_CTS GPIOC(GPIO_AP, 8, 1) + +#define GPIO_BOOT_CONFIG0 GPIOC(GPIO_AP, 4, 2) +#define GPIO_BOOT_CONFIG1 GPIOC(GPIO_AP, 4, 3) +#define GPIO_BOOT_CONFIG2 GPIOC(GPIO_AP, 4, 4) +#define GPIO_BOOT_CONFIG3 GPIOC(GPIO_AP, 4, 5) + +#define GPIO_BOARD_REV0 GPIOC(GPIO_AP, 4, 7) +#define GPIO_BOARD_REV1 GPIOC(GPIO_AP, 5, 0) +#define GPIO_BOARD_REV2 GPIOC(GPIO_AP, 5, 1) +#define GPIO_BOARD_REV3 GPIOC(GPIO_AP, 5, 2) + +#define GPIO_REQUEST_DFU1 GPIOC(GPIO_SPU, 0, 0) +#define GPIO_REQUEST_DFU2 GPIOC(GPIO_SPU, 0, 1) +#define GPIO_FORCE_DFU GPIOC(GPIO_SPU, 2, 6) +#define GPIO_DFU_STATUS GPIOC(GPIO_SPU, 2, 5) +#define GPIO_DOCK_CONNECT GPIOC(GPIO_SPU, 0, 2) +#define GPIO_DOCK_ATTENTION GPIOC(GPIO_SPU, 3, 2) + +#define SPI_NOR0 (0) + +#define GPIO_SPI0_CS GPIOC(GPIO_AP, 12, 4) + +#define GPIO_IIC0_SCL GPIOC(GPIO_AP, 11, 7) +#define GPIO_IIC0_SDA GPIOC(GPIO_AP, 11, 6) +#define GPIO_IIC1_SCL GPIOC(GPIO_AP, 6, 1) +#define GPIO_IIC1_SDA GPIOC(GPIO_AP, 6, 0) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s7002/include/platform/image_devices.h b/platform/s7002/include/platform/image_devices.h new file mode 100644 index 0000000..3c6a785 --- /dev/null +++ b/platform/s7002/include/platform/image_devices.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_HW_ASP) + { "asp_fw", 0x00000 }, + + #if defined(WITH_LLB_NVRAM) + { "anc_firmware", 0x00000 } // iBoot->Dali may also use ANC firmware instead of ASP + #endif + #if WITH_LLB_BLKDEV + , { "anc_llb", 0x00000 } // iBoot->Dali needs to read Dali out of block0 + #endif +#elif defined(WITH_ANC_FIRMWARE) + { "anc_firmware", 0x00000 } + #if WITH_LLB_BLKDEV + , { "anc_llb", 0x00000 } + #endif +#else + { "nor0", 0x00000 } +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s7002/include/platform/memconfig.h b/platform/s7002/include/platform/memconfig.h new file mode 100644 index 0000000..53cf08a --- /dev/null +++ b/platform/s7002/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* Stub */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/s7002/include/platform/memmap.h b/platform/s7002/include/platform/memmap.h new file mode 100644 index 0000000..20b9a96 --- /dev/null +++ b/platform/s7002/include/platform/memmap.h @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* S7002 specific memory map */ + +/////////////////////////////////////////////////////////////////////////////////// +// 0x80000000 + dram_size --> ------------------------------- +// | Sleep Token Buffer (1KiB) | +// |-----------------------------| +// | Panic (512KiB) | +// |-----------------------------| +// | Display (16MiB) | +// | (Framebuffer + scratch) | +// | | +// | | +// | | +// |-----------------------------| +// | iBoot (32MiB) | +// | (Text + Data + Stacks ) | +// | (Page Tables + Heap) | +// | | +// |-----------------------------| +// | Unused | +// | | +// | | +// | | +// | | +// |-----------------------------| +// | | +// | (Ramdisk) | +// | (Kernel + DeviceTree) | +// | Secure memory | +// |-----------------------------| +// | | +// | | +// | Load region / | +// | Insecure Memory | +// | | +// | | +// | | +// 0x80000000 --> ------------------------------- +/////////////////////////////////////////////////////////////////////////////////// + +#define SDRAM_BASE (0x80000000ULL) +#define SDRAM_BANK_LEN (SDRAM_LEN) +#define SDRAM_BANK_COUNT (1) +#define SDRAM_END (SDRAM_BASE + SDRAM_LEN) +#define SDRAM_BASE_UNCACHED (SDRAM_END) + +#define VROM_BASE (0x40000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00040000ULL) + +#define SRAM_BASE (0x46000000ULL) +#define SRAM_LEN (0x00048000ULL) +#define SRAM_BANK_LEN (SRAM_LEN) +#define SRAM_BANK_COUNT (1) +#define SRAM_END (SRAM_BASE + SRAM_LEN) + +#define IO_BASE (0x40000000ULL) +#define IO_SIZE (0x20000000ULL) + +/* custom ROM is stored at first physical page DRAM, and booted by enabling remap */ +#define SECUREROM_LOAD_ADDRESS (SDRAM_BASE) + +/* sleep token is stored at first physical page in kernel memory */ +#define SLEEP_TOKEN_BUFFER_BASE (SDRAM_BASE) +#define SLEEP_TOKEN_BUFFER_SIZE (1024) + +/* reserved area for ASP */ +#define ASP_SIZE (0x00500000ULL) +#define ASP_BASE (SDRAM_END - ASP_SIZE) + +#define CONSISTENT_DEBUG_SIZE (0x00004000ULL) +#define CONSISTENT_DEBUG_BASE (ASP_BASE - CONSISTENT_DEBUG_SIZE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00080000ULL) +#define PANIC_BASE (CONSISTENT_DEBUG_BASE - PANIC_SIZE) + +/* reserved area for display + * DISPLAY_SIZE comes from platform's rules.mk + */ +#define DISPLAY_BASE (PANIC_BASE - DISPLAY_SIZE) + +/* where to stick heap and insecure memory */ +#if APPLICATION_SECUREROM + +#define INSECURE_MEMORY_SIZE (SRAM_END - HEAP_END) +#define INSECURE_MEMORY_BASE (HEAP_END) + +#define DATA_SIZE (0x00007000ULL) + +#define BOOK_KEEPING_BASE (DATA_BASE + DATA_SIZE) +#define BOOT_TRAMPOLINE_BASE (BOOK_KEEPING_BASE) +#define BOOT_TRAMPOLINE_SIZE (0x00001000ULL) +#define MMU_TT_BASE (BOOK_KEEPING_BASE + BOOT_TRAMPOLINE_SIZE) +#define MMU_TT_SIZE (0x00004000ULL) +#define STACK_BASE (BOOK_KEEPING_BASE + BOOT_TRAMPOLINE_SIZE + MMU_TT_SIZE) +#define STACK_SIZE (0x00004000ULL) +#define BOOK_KEEPING_SIZE (BOOT_TRAMPOLINE_SIZE + STACK_SIZE + MMU_TT_SIZE) + +#define HEAP_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define HEAP_SIZE (0x00008000ULL) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT + +#if WITH_DFU_MODE +/* LLB, iBSS DFU */ + +/* reserved area for iBoot (aligned to 1MB boundary) */ +#define IBOOT_SIZE (0x02000000ULL + 0x100000ULL - (PANIC_SIZE + DISPLAY_SIZE)) +#define IBOOT_BASE (DISPLAY_BASE - IBOOT_SIZE) + +#define INSECURE_MEMORY_SIZE (IBOOT_SIZE) +#define INSECURE_MEMORY_BASE (IBOOT_BASE) + +#define STACK_SIZE (0x00004000ULL) +#define MMU_TT_SIZE (0x00004000ULL) +#define BOOK_KEEPING_SIZE (STACK_SIZE + MMU_TT_SIZE) +#define BOOK_KEEPING_BASE (SRAM_BASE) +#define MMU_TT_BASE (BOOK_KEEPING_BASE) +#define STACK_BASE (BOOK_KEEPING_BASE + MMU_TT_SIZE) + +#define HEAP_SIZE (TEXT_BASE - HEAP_BASE) +#define HEAP_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#else /* !WITH_DFU_MODE */ + +#if WITH_RECOVERY_MODE_IBSS + +/* reserved area for iBoot (aligned to 1MB boundary) */ +#define IBOOT_SIZE (0x02000000ULL + 0x100000ULL - (PANIC_SIZE + DISPLAY_SIZE)) +#define IBOOT_BASE (DISPLAY_BASE - IBOOT_SIZE) + +#define INSECURE_MEMORY_SIZE (IBOOT_SIZE) +#define INSECURE_MEMORY_BASE (IBOOT_BASE) + +#define STACK_SIZE (0x00004000ULL) +#define MMU_TT_SIZE (0x00004000ULL) +#define BOOK_KEEPING_SIZE (STACK_SIZE + MMU_TT_SIZE) +#define BOOK_KEEPING_BASE (TEXT_BASE + TEXT_FOOTPRINT) +#define MMU_TT_BASE (BOOK_KEEPING_BASE) +#define STACK_BASE (BOOK_KEEPING_BASE + MMU_TT_SIZE) + +#define HEAP_SIZE (SRAM_END - HEAP_BASE) +#define HEAP_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#else + +/* iBoot, iBEC */ + +#define IBOOT_BASE (TEXT_BASE) +#define IBOOT_SIZE (HEAP_END - IBOOT_BASE) + +#define BOOK_KEEPING_BASE (IBOOT_BASE + TEXT_FOOTPRINT) +#define MMU_TT_BASE (BOOK_KEEPING_BASE) +#define MMU_TT_SIZE (0x00004000ULL) +#define STACK_BASE (BOOK_KEEPING_BASE + MMU_TT_SIZE) +#define STACK_SIZE (0x00004000ULL) +#define BOOK_KEEPING_SIZE (STACK_SIZE + MMU_TT_SIZE) + +#define HEAP_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define HEAP_SIZE (DISPLAY_BASE - HEAP_BASE - PAGE_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) +#if (HEAP_GUARD != (DISPLAY_BASE - PAGE_SIZE)) +#error "Memory map configuration error" +#endif + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_LOAD_SIZE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define SECURE_MEMORY_SIZE (DEFAULT_FREE_ADDRESS - SECURE_MEMORY_BASE) + +/* unused area */ +#define UNUSED_MEMORY_BASE (SECURE_MEMORY_BASE + SECURE_MEMORY_SIZE) +#define UNUSED_MEMORY_SIZE (IBOOT_BASE - UNUSED_MEMORY_BASE) + +#endif /* WITH_RECOVERY_MODE_IBSS */ + +#endif /* !WITH_DFU_MODE */ + +#endif /* APPLICATION_IBOOT */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s7002/include/platform/pinconfig.h b/platform/s7002/include/platform/pinconfig.h new file mode 100644 index 0000000..6909be3 --- /dev/null +++ b/platform/s7002/include/platform/pinconfig.h @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default S7002 SoC Pin Configuration */ +#define NAND_DRIVE_STR (DRIVE_X2 | SLOW_SLEW) + +static const uint32_t gpio_default_cfg[GPIO_0_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // SD_CLKOUT -> + CFG_DISABLED, // SD_CMD_IO -> + CFG_DISABLED, // SD_DATA_IO[0] -> + CFG_DISABLED, // SD_DATA_IO[1] -> + CFG_DISABLED, // SD_DATA_IO[2] -> + CFG_DISABLED, // SD_DATA_IO[3] -> + +/* Port 1 */ + CFG_DISABLED, // SDIO_IRQ -> + CFG_DISABLED, // WL_HOST_WAKE -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO3 -> BOOT_CONFIG[1] + CFG_DISABLED, // GPIO4 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO5 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO6 -> BOARD_ID[3] + CFG_DISABLED, // GPIO7 -> + +/* Port 5 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 6 */ + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + +/* Port 7 */ + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + +/* Port 8 */ + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART3_RTXD -> + CFG_DISABLED, // CLK32K_OUT -> + CFG_DISABLED, // TEST_CLKOUT -> + CFG_DISABLED, // GPIO16 -> + +/* Port 9 */ + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // TMR32_PWM3 -> + CFG_DISABLED, // DISP_TE -> + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED | NAND_DRIVE_STR, // NAND_CEN[0] -> + +/* Port 10 */ + CFG_DISABLED | NAND_DRIVE_STR, // NAND_CEN[1] -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[7] -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[6] -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[5] -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[4] -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_DQS -> + CFG_DISABLED | PULL_UP | NAND_DRIVE_STR, // NAND_REN -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[3] -> + +/* Port 11 */ + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[2] -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[1] -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_IO[0] -> + CFG_DISABLED | PULL_UP | NAND_DRIVE_STR, // NAND_WEN -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_CLE -> + CFG_DISABLED | PULL_DOWN | NAND_DRIVE_STR, // NAND_ALE -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + +/* Port 12 */ + CFG_DISABLED, // DISPLAY_SYNC -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // SPI1_SCLK -> + +/* Port 13 */ + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // GPIO24 -> + +/* Port 14 */ + CFG_DISABLED, // GPIO25 -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 15 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_DISABLED, // ENET_MDC -> + CFG_DISABLED, // ENET_MDIO -> + CFG_DISABLED, // RMII_RXER -> + CFG_DISABLED, // RMII_TXEN -> + CFG_DISABLED, // RMII_CLK -> + CFG_DISABLED, // RMII_TXD[0] -> + CFG_DISABLED, // RMII_TXD[1] -> + CFG_DISABLED, // RMII_RXD[0] -> + +/* Port 17 */ + CFG_DISABLED, // RMII_RXD[1] -> + CFG_DISABLED, // RMII_RXD[0] -> + CFG_DISABLED, // RMII_CRSDV -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // REQUEST_DFU1 -> + CFG_IN, // REQUEST_DFU2 -> + CFG_IN | PULL_DOWN, // DOCK_CONNECT -> + CFG_DISABLED, // CLK32K_IN -> + CFG_DISABLED, // SPU_UART0_TXD -> + CFG_DISABLED, // SPU_UART0_RXD -> + CFG_DISABLED, // SPU_UART0_RTSN -> + CFG_DISABLED, // SPU_UART0_CTSN -> + +/* Port 1 */ + CFG_DISABLED, // SPU_UART1_TXD -> + CFG_DISABLED, // SPU_UART1_RXD -> + CFG_DISABLED, // SPU_UART1_RTSN -> + CFG_DISABLED, // SPU_UART1_CTSN -> + CFG_DISABLED, // SPU_GPIO[0] -> + CFG_DISABLED, // SPU_GPIO[1] -> + CFG_DISABLED, // SPU_GPIO[2] -> + CFG_DISABLED, // SPU_GPIO[3] -> + +/* Port 2 */ + CFG_DISABLED, // SPU_GPIO[4] -> + CFG_DISABLED, // SPU_GPIO[5] -> + CFG_DISABLED, // SPU_GPIO[6] -> + CFG_DISABLED, // SPU_GPIO[7] -> + CFG_DISABLED, // SPU_GPIO[8] -> + CFG_DISABLED | PULL_DOWN, // DFU_STATUS -> + CFG_IN | PULL_DOWN, // FORCE_DFU -> + CFG_DISABLED, // POWER_GOOD -> + +/* Port 3 */ + CFG_DISABLED, // SOC_VDD_HI_LO -> + CFG_DISABLED, // SOC_VDD_ALL_ON -> + CFG_DISABLED | PULL_DOWN, // DOCK_ATTENTION -> + CFG_DISABLED, // PMU_HOST_WAKE -> + CFG_DISABLED, // SPU_SPI_SCLK -> + CFG_DISABLED, // SPU_SPI_MOSI -> + CFG_DISABLED, // SPU_SPI_MISO -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[0] -> + +/* Port 4 */ + CFG_DISABLED, // SPU_SPI_CS_TRIG[1] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[2] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[3] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[4] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[5] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[6] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[7] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[8] -> + +/* Port 5 */ + CFG_DISABLED, // SPU_SPI_CS_TRIG[9] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[10] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[11] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[12] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[13] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[14] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[15] -> + CFG_DISABLED, // SPU_GPIO[9] -> + +/* Port 6 */ + CFG_DISABLED, // SPU_I2C_SDA -> + CFG_DISABLED, // SPU_I2C_SCL -> + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 7 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 8 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // RESETN -> RESET_L + CFG_DISABLED, // JTAG_TRSTN -> + CFG_DISABLED, // JTAG_SEL -> + CFG_DISABLED, // JTAG_TCK -> + CFG_DISABLED, // JTAG_TMS -> + CFG_DISABLED, // JTAG_TRTCK -> + CFG_DISABLED, // JTAG_TDO -> + +/* Port 9 */ + CFG_DISABLED, // JTAG_TDI -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s7002/include/platform/pl080dmac_config.h b/platform/s7002/include/platform/pl080dmac_config.h new file mode 100644 index 0000000..999a2b0 --- /dev/null +++ b/platform/s7002/include/platform/pl080dmac_config.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PL080DMAC_CONFIG_H +#define __PL080DMAC_CONFIG_H + +#include +#include +#include +#include + +/* LIO Integration spec contains details on PL080DMAC configuration */ + +static const struct pl080dmac_config pl080dmac_configs[PL080DMAC_COUNT] = { + { + CLK_DMARX, + INT_DMA_RX_TC, + INT_DMA_RX_ERR, + { + /* channel type config reg control reg fifo_address */ + { 0x0, PL080DMAC_PERPH_SRC, 0x00001014, 0x0A489000, 0x47380080 }, + }, + }, + { + CLK_DMATX, + INT_DMA_TX_TC, + INT_DMA_TX_ERR, + { + /* channel type config reg control reg fifo_address */ + { 0x0, PL080DMAC_PERPH_DEST, 0x00000a80, 0x05489000, 0x47380040 }, + }, + }, +}; + +#endif /* __PL080DMAC_CONFIG_H */ + diff --git a/platform/s7002/include/platform/soc/chipid.h b/platform/s7002/include/platform/soc/chipid.h new file mode 100644 index 0000000..dca152e --- /dev/null +++ b/platform/s7002/include/platform/soc/chipid.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include + +#define rCFG_FUSE0 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCFG_FUSE1 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCFG_FUSE2 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rCFG_FUSE3 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x0C)) +#define rCFG_FUSE4 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x10)) +#define rCFG_FUSE5 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x14)) + +#define rECIDLO (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x80)) +#define rECIDHI (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x84)) + +#define rCFG_FUSE0_RAW (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x100)) + +uint32_t chipid_get_total_rails_leakage(); +uint32_t chipid_get_soc_voltage(uint32_t index); +uint32_t chipid_get_fuse_revision(void); + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s7002/include/platform/soc/display.h b/platform/s7002/include/platform/soc/display.h new file mode 100644 index 0000000..bacae2e --- /dev/null +++ b/platform/s7002/include/platform/soc/display.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ + { + .name = "default", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x130), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x1f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x7d0) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x130), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x128), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x118), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x114), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x24) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcenab = ADPCENAB_IDEAL_ARB_ENAB, + }, +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/s7002/include/platform/soc/display_timings.h b/platform/s7002/include/platform/soc/display_timings.h new file mode 100644 index 0000000..cd5c8e5 --- /dev/null +++ b/platform/s7002/include/platform/soc/display_timings.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_N27 || SUB_TARGET_N28 || SUB_TARGET_N27A || SUB_TARGET_N28A || SUB_TARGET_S7002SIM + { + .display_name = "C1", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 6412500, + .dot_pitch = 326, + .h_active = 232, + .h_pulse_width = 2, + .h_back_porch = 44, + .h_front_porch = 42, + .v_active = 288, + .v_pulse_width = 1, + .v_back_porch = 23, + .v_front_porch = 22, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = NULL, + }, + + { + .display_name = "POR_DISP_S", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 22200000, + .dot_pitch = 326, + .h_active = 272, + .h_pulse_width = 8, + .h_back_porch = 8, + .h_front_porch = 16, + .v_active = 340, + .v_pulse_width = 1, + .v_back_porch = 1, + .v_front_porch = 43, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = NULL, + }, + + { + .display_name = "POR_DISP_B", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 22200000, + .dot_pitch = 326, + .h_active = 312, + .h_pulse_width = 8, + .h_back_porch = 8, + .h_front_porch = 16, + .v_active = 390, + .v_pulse_width = 1, + .v_back_porch = 1, + .v_front_porch = 38, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = NULL, + }, + + { + .display_name = "POR_DISP_B_VID", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 12000000, + .dot_pitch = 326, + .h_active = 312, + .h_pulse_width = 4, + .h_back_porch = 102, + .h_front_porch = 42, + .v_active = 390, + .v_pulse_width = 1, + .v_back_porch = 23, + .v_front_porch = 22, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = NULL, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/s7002/include/platform/soc/hwclocks.h b/platform/s7002/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..61bba80 --- /dev/null +++ b/platform/s7002/include/platform/soc/hwclocks.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (5000000UL) +#else +#define OSC_FREQ (24000000UL) +#endif + +// Start from an offset of 128. So that we are safely outside the PS indexes. +#define CLK_FCLK (HWCLOCK_BASE+128) +#define CLK_ACLK (HWCLOCK_BASE+129) +#define CLK_HCLK (HWCLOCK_BASE+130) +#define CLK_PCLK (HWCLOCK_BASE+131) +#define CLK_VCLK0 (HWCLOCK_BASE+132) +#define CLK_VCLK1 (HWCLOCK_BASE+133) +#define CLK_MCLK (HWCLOCK_BASE+134) +#define CLK_NCLK (HWCLOCK_BASE+135) +#define CLK_USBPHYCLK (HWCLOCK_BASE+136) +#define CLK_NCOREF (HWCLOCK_BASE+137) +#define CLK_ANS_LINK (HWCLOCK_BASE+138) + +/* + * S7002 clock gate devices. + * Refers to the ps register offsets. + */ +enum { + CLK_CPU0, + CLK_AIC, + CLK_SPU, + CLK_SPU_AKF, + CLK_SPU_UART0, + CLK_SPU_UART1, + CLK_SPU_SMB, + CLK_SPU_SGPIO, + CLK_DOCKFIFO, + CLK_MCU, + CLK_AMP, + CLK_PIOSYS, + CLK_DISP0, + CLK_MIPI_DSI, + CLK_MIPI = CLK_MIPI_DSI, + CLK_MSR, + CLK_MEDIA, + CLK_ANS, + CLK_GFX, + CLK_SDIO, + CLK_LIO, + CLK_GPIO, + CLK_MCA0, + CLK_MCA1, + CLK_SPI0, + CLK_SPI1, + CLK_DMATX, + CLK_DMARX, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_AES0, + CLK_I2C0, + CLK_I2C1, + CLK_PWM0, + CLK_AUE, + CLK_USB = CLK_AUE, + CLK_USB_M7, + CLK_USBCTLREG = CLK_USB_M7, + CLK_USB_OTG = CLK_USB_M7, + CLK_ETH, + CLK_VDEC, + PMGR_LAST_DEVICE, +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s7002/include/platform/soc/hwdmachannels.h b/platform/s7002/include/platform/soc/hwdmachannels.h new file mode 100644 index 0000000..cb31726 --- /dev/null +++ b/platform/s7002/include/platform/soc/hwdmachannels.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWDMACHANNELS_H +#define __PLATFORM_SOC_HWDMACHANNELS_H + +#define DMA_AES_RD (0) +#define DMA_AES_WR ((1 << DMA_SELECTOR_SHIFT) | (0)) + +#define DMA_SELECTOR_SHIFT (4) +#define DMA_SELECTOR_MASK (0xf) +#define DMA_CHANNEL_MASK (0xf) + +#define PL080DMAC_SUPPORTED_CHANNEL_COUNT (1) + +#endif /* ! __PLATFORM_SOC_HWDMACHANNELS_H */ diff --git a/platform/s7002/include/platform/soc/hwisr.h b/platform/s7002/include/platform/soc/hwisr.h new file mode 100644 index 0000000..1ffd944 --- /dev/null +++ b/platform/s7002/include/platform/soc/hwisr.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt + +// Reserved 4 + +#define INT_WDT 5 // Watchdog Timer Interrupt + +// Reserved 6 + +#define INT_ANS_KF_INBOX_EMPTY 7 // ANS KF Inbox Empty Interrupt +#define INT_ANS_KF_INBOX_NOTEMPTY 8 // ANS KF Inbox Not Empty Interrupt +#define INT_ANS_KF_OUTBOX_EMPTY 9 // ANS KF Outbox Empty Interrupt +#define INT_ANS_KF_OUTBOX_NOTEMPTY 10 // ANS KF Outbox Not Empty Interrupt +#define INT_ANS_CHNL0 11 // ANS Channel 0 Interrupt + +// Reserved 12 + +#define INT_ENET 13 + +#define INT_USB_OTG 14 // USB OTG Interrupt +#define INT_USB_20_BATT_CHRG_DET 15 // USB 2.0 Battery Charge Detect Interrupt +#define INT_USBOTG_RESUME 16 // USB OTG Resume Interrupt + +// Reserved 17 + +#define INT_GPIO_CLASS0 18 // GPIO Class 0 Interrupt +#define INT_GPIO_CLASS1 19 // GPIO Class 1 Interrupt +#define INT_GPIO_CLASS2 20 // GPIO Class 2 Interrupt +#define INT_GPIO_CLASS3 21 // GPIO Class 3 Interrupt +#define INT_GPIO_CLASS4 22 // GPIO Class 4 Interrupt +#define INT_GPIO_CLASS5 23 // GPIO Class 5 Interrupt +#define INT_GPIO_CLASS6 24 // GPIO Class 6 Interrupt + +// Reserved 25 + +#define INT_MEM_CONTROLLER 26 // Memory Controller Interrupt + +// Reserved 27 + +#define INT_CPU0_PMU_IRQ 28 // CPU 0 PMU IRQ Interrupt +#define INT_CPU0_CTI_IRQ 29 // CPU 0 CTI Interrupt +#define INT_CPU0_COMM_TX 30 // CPU 0 COMM TX Interrupt +#define INT_CPU0_COMM_RX 31 // CPU 0 COMM RX Interrupt +#define INT_CPU0_AXI_ERR_IRQ 32 // CPU 0 AXI Error IRQ Interrupt +#define INT_CPU0_CX_ETB_FUKK 33 // CPU 0 CXETB Full Interrupt + +#define INT_DISP0 35 // Display Interrupt + +// Reserved 46 + +#define INT_DISP_DART 37 // Display DART Interrupt +#define INT_DISP_SMMU 38 // Display SMMU Interrupt +#define INT_DISP_BACK_END_VBI 39 // Display Back End VBI Interrupt +#define INT_DISP_BACK_END_VFTG_IDLE 40 // Display Back End VFTG Idle Interrupt +#define INT_DISP_BACK_END_VBL_CNTR 41 // Display Back End VBL Counter Interrupt +#define INT_MIPIDSI 42 // MIPI DSI Interrupt + +// Reserved 43 + +#define INT_GFX 44 // GFX Interrupt + +// Reserved 45-46 + +#define INT_MSR 47 // MSR Interrupt +#define INT_MSR_SMMU 48 // MSR SMMU Interrupt +#define INT_MSR_DART 49 // MSR DART Interrupt +#define INT_MSR_SMMU_PERF 50 // MSR SMMU Performance Interrupt +#define INT_MSR_DART_PERF 51 // MSR DART Performance Interrupt + +// Reserved 52 + +#define INT_PIO 53 // PIO IRQ + +// Reserved 54 + +#define INT_DMA_RX_TC 55 // DMA Rx Transfer Complete Interrupt +#define INT_DMA_RX_ERR 56 // DMA Rx Error Interrupt +#define INT_DMA_TX_TC 57 // DMA Tx Transfer Complete Interrupt +#define INT_DMA_TX_ERR 58 // DMA Tx Error Interrupt + +// Reserved 59 + +#define INT_SPI0 60 // SPI 0 Interrupt +#define INT_SPI1 61 // SPI 1 Interrupt + +// Reserved 62 + +#define INT_UART0 63 // UART 0 Interrupt +#define INT_UART1 64 // UART 1 Interrupt +#define INT_UART2 65 // UART 2 Interrupt +#define INT_UART3 66 // UART 3 Interrupt +#define INT_UART4 67 // UART 4 Interrupt + +// Reserved 68 + +#define INT_PWM0 69 // PWM0 Interrupt + +// Reserved 70 + +#define INT_MCA0 71 // Multi-Channel Audio 0 Interrupt +#define INT_MCA1 72 // Multi-Channel Audio 1 Interrupt + +// Reserved 73 + +#define INT_IIC0 74 // I2C 0 Interrupt +#define INT_IIC1 75 // I2C 1 Interrupt + +// Reserved 76 + +#define INT_AES 77 // AES Interrupt + +// Reserved 78 + +#define INT_VDEC 79 // Video Decoder + +// Reserved 80 + +#define INT_SDIO_KF_INBOX_EMPTY 81 // ANS KF Inbox Empty Interrupt +#define INT_SDIO_KF_INBOX_NOTEMPTY 82 // ANS KF Inbox Not Empty Interrupt +#define INT_SDIO_KF_OUTBOX_EMPTY 83 // ANS KF Outbox Empty Interrupt +#define INT_SDIO_KF_OUTBOX_NOTEMPTY 84 // ANS KF Outbox Not Empty Interrupt +#define INT_SDIO_SDHC_WAKEUP 85 // SDIO SDHC Wakeup +#define INT_SDIO_SDHC_INT 86 // SDIO SDHC Tnterrupt +#define INT_SDIO_CARD_INT 87 // SDIO SDHC Interrupt +#define INT_SDIO_IRQ 88 // SDIO IRQ +#define INT_SDIO_WL_HOST_WAKE_INT 89 // SDIO Host Wake Interrupt + +// Reserved 90 + +// 91 - 117 SPU interrupts + +#define DBGFIFO_0_NOT_EMPTY 118 // DebugFifo 0 Not Empty Interrupt +#define DBGFIFO_1_NOT_EMPTY 119 // DebugFifo 1 Not Empty Interrupt +#define DBGFIFO_2_NOT_EMPTY 120 // DebugFifo 2 Not Empty Interrupt +#define DBGFIFO_3_NOT_EMPTY 121 // DebugFifo 3 Not Empty Interrupt +#define DBGFIFO_4_NOT_EMPTY 122 // DebugFifo 4 Not Empty Interrupt +#define DBGFIFO_5_NOT_EMPTY 123 // DebugFifo 5 Not Empty Interrupt +#define DBGFIFO_6_NOT_EMPTY 124 // DebugFifo 6 Not Empty Interrupt +#define DBGFIFO_7_NOT_EMPTY 125 // DebugFifo 7 Not Empty Interrupt + +// Reserved 126 - 127 + + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s7002/include/platform/soc/hwregbase.h b/platform/s7002/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..1e3ad87 --- /dev/null +++ b/platform/s7002/include/platform/soc/hwregbase.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#include + +/* S7002 Reg Base Defs */ + +// Memory Subsystem +#define SECUREROM_BASE_ADDR (IO_BASE + 0x00000000) // SecureROM access through PIO +#define PIO_BASE_ADDR (IO_BASE + 0x00100000) // PIO Config +#define CPU_FABRIC_BASE_ADDR (IO_BASE + 0x00101000) // PL301 Config +#define NRT_FABRIC_BASE_ADDR (IO_BASE + 0x00102000) // PL301 Config +#define CPU_BASE_ADDR (IO_BASE + 0x00103000) // AP Config +#define AMC_BASE_ADDR (IO_BASE + 0x00200000) // AMC Config +#define AMPS_DQ_BASE_ADDR (IO_BASE + 0x00300000) // AMP DQ DRAM Phy +#define AMPS_CA_BASE_ADDR (IO_BASE + 0x00310000) // AMP CA DRAM Phy + +// MSR Subsystem +#define MSR_BASE_ADDR (IO_BASE + 0x01000000) // MSR Config +#define MSR_SMMU_BASE_ADDR (IO_BASE + 0x01004000) // MSR SMMU +#define MSR_DART_BASE_ADDR (IO_BASE + 0x01008000) // MSR DART +#define VDEC_BASE_ADDR (IO_BASE + 0x02000000) // VXD394 Video Decoder +#define SGX544_SC_BASE_ADDR (IO_BASE + 0x02800000) // SGX544-SC Space + +// Display Subsystem +#define DISP_ADP_BASE_ADDR (IO_BASE + 0x03200000) // Display pipe configuration +#define DISP0_BASE_ADDR DISP_ADP_BASE_ADDR +#define DISP_ADP_SMMU_BASE_ADDR (IO_BASE + 0x03300000) // Display pipe SMMU configuration +#define DISP_ADE_BASE_ADDR (IO_BASE + 0x03400000) // DBE Timing controller +#define DISP0_ADBE_BASE_ADDR DISP_ADE_BASE_ADDR +#define DISP_AAP_BASE_ADDR (IO_BASE + 0x03440000) // DBE Ambient-Adaptive Pixel +#define DISP_DITHER_BASE_ADDR (IO_BASE + 0x034C0000) // DBE Dither +#define DISP_MIPI_DSI_BASE_ADDR (IO_BASE + 0x03600000) // MIPI DSI Core configuration + +// ANS Subsystem +#define ANS_PL301_BASE_ADDR (IO_BASE + 0x04010000) // ANS PL301 Configuration +#define ANS_PL301_TLIMIT0_BASE_ADDR (IO_BASE + 0x04020000) // ANS Cortex-A7 Transaction Limit +#define ANS_PL301_TLIMIT1_BASE_ADDR (IO_BASE + 0x04030000) // ANS NAND controoler Transaction Limit +#define ANS_AKF_BASE_ADDR (IO_BASE + 0x04040000) // ANS Cortex-A7 and wrapper +// ANS KF Debug registers +#define ANS_CFG_BASE_ADDR (IO_BASE + 0x04080000) // ANS Config +#define ANS_PPN_N_PL_BASE_ADDR (IO_BASE + 0x04081000) +#define ANS_ANC_BASE_ADDR (IO_BASE + 0x04800000) // NAND Controller + +// SDIO Subsystem +#define SDIO_PL301_BASE_ADDR (IO_BASE + 0x05010000) // SDIO PL301 Configuration +#define SDIO_PL301_TLIMIT0_BASE_ADDR (IO_BASE + 0x05020000) // SDIO Cortex-A7 Transaction Limit +#define SDIO_PL301_TLIMIT1_BASE_ADDR (IO_BASE + 0x05030000) // SDIO controller Transaction Limit +#define SDIO_AKF_BASE_ADDR (IO_BASE + 0x05040000) // SDIO Cortex-A7 and wrapper +// SDIO KF Debug registers +#define SDIO_CFG_BASE_ADDR (IO_BASE + 0x05080000) // SDIO Config + +// SPU Subsystem +#define SPU_SRAM_A_BASE_ADDR (IO_BASE + 0x06000000) // SPU Local SRAM-A +#define SPU_SRAM_B_BASE_ADDR (IO_BASE + 0x06040000) // SPU Local SRAM-B +#define SPU_SRAM_SIZE (0x48000) // SPU SRAM size is 288 KB +#define SPU_CPU_PL301_BASE_ADDR (IO_BASE + 0x06410000) // SPU CPU PL301 Configuration +#define SPU_SRAM_PL301_BASE_ADDR (IO_BASE + 0x06411000) // SPU SRAM PL301 Configuration +#define SPU_MEM_PL301_BASE_ADDR (IO_BASE + 0x06412000) // SPU MEM PL301 Configuration +#define SPU_AKF_BASE_ADDR (IO_BASE + 0x06500000) // SPU Cortex-A7 and wrapper +// SPU KF Debug registers +#define SPU_SPI_BASE_ADDR (IO_BASE + 0x06600000) // SPU SPI Device +#define SPU_SEQUENCER_BASE_ADDR (IO_BASE + 0x06700000) // SPU Sequencer configuration +#define SPU_SMB_BASE_ADDR (IO_BASE + 0x06800000) // SPU I2C +#define SPU_GPIO_BASE_ADDR (IO_BASE + 0x06810000) // SPU GPIO +#define SPU_UART_BASE_ADDR (IO_BASE + 0x06820000) // SPU UART +#define SPU_SOC_RECONFIG_BASE_ADDR (IO_BASE + 0x06900000) // SPU SOC ReConfig +#define SPU_AIC_WRAP_BASE_ADDR (IO_BASE + 0x06A00000) // AIC +#define SPU_AIC_BASE_ADDR (IO_BASE + 0x06B00000) // AIC +#define SPU_PMGR_BASE_ADDR (IO_BASE + 0x06C00000) // PMGR +#define SPU_DBG_FIFO_0_BASE_ADDR (IO_BASE + 0x06E00000) // Debug FIFO [0] registers +#define SPU_DBG_FIFO_1_BASE_ADDR (IO_BASE + 0x06E03000) // Debug FIFO [1] registers +#define SPU_DBG_FIFO_2_BASE_ADDR (IO_BASE + 0x06E06000) // Debug FIFO [2] registers +#define SPU_DBG_FIFO_3_BASE_ADDR (IO_BASE + 0x06E09000) // Debug FIFO [3] registers +#define SPU_DBG_FIFO_4_BASE_ADDR (IO_BASE + 0x06E0C000) // Debug FIFO [4] registers +#define SPU_DBG_FIFO_5_BASE_ADDR (IO_BASE + 0x06E0F000) // Debug FIFO [5] registers +#define SPU_DBG_FIFO_6_BASE_ADDR (IO_BASE + 0x06E12000) // Debug FIFO [6] registers +#define SPU_DBG_FIFO_7_BASE_ADDR (IO_BASE + 0x06E15000) // Debug FIFO [7] registers +#define SPU_DBG_WRAP_BASE_ADDR (IO_BASE + 0x06EB0000) // Debug sub-system config space + +// LIO Subsystem +#define LIO_MISC_BASE_ADDR (IO_BASE + 0x07000000) // Miscellaneous registers +#define LIO_AUD_MUX_BASE_ADDR (IO_BASE + 0x07004000) // Audio I2S Switch registers +#define LIO_PWM_BASE_ADDR (IO_BASE + 0x07010000) // PWM Device registers +#define LIO_SMB_0_BASE_ADDR (IO_BASE + 0x07020000) // I2C Device registers +#define LIO_GPIO_BASE_ADDR (IO_BASE + 0x07100000) // GPIO +#define LIO_SPI_BASE_ADDR (IO_BASE + 0x07200000) // SPI Device registers +#define LIO_UART_BASE_ADDR (IO_BASE + 0x07230000) // UART Device registers +#define LIO_MCA_BASE_ADDR (IO_BASE + 0x07240000) // MCA Device registers +#define LIO_DMAC_BASE_ADDR (IO_BASE + 0x07300000) // PL080 DMAC registers +#define LIO_AES_BASE_ADDR (IO_BASE + 0x07380000) // AES + +// AUE Subsystem +#define AUE_USBCONT_BASE_ADDR (IO_BASE + 0x08000000) // USB Control +#define AUE_USBOTG_BASE_ADDR (IO_BASE + 0x08100000) // USBOTG +#define AUE_AUSB_WIDGETS_BASE_ADDR (IO_BASE + 0x08200000) // AUSB Widgets +#define AUE_AUSB_AFIFO_WDGTS_BASE_ADDR (IO_BASE + 0x08300000) // AUSB Async Fifo Widgets +#define AUE_PL301_BASE_ADDR (IO_BASE + 0x08800000) // AUE PL301 Configuration + +/* iBoot Specific Defs */ + +#define AKF_VERSION (1) + +#define UART0_BASE_ADDR (LIO_UART_BASE_ADDR) +#define UART1_BASE_ADDR (LIO_UART_BASE_ADDR + 0x04000) +#define UART2_BASE_ADDR (LIO_UART_BASE_ADDR + 0x08000) +#define UART3_BASE_ADDR (LIO_UART_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (LIO_UART_BASE_ADDR + 0x10000) +#define UARTS_COUNT (5) +#define UART_VERSION (1) + +#define SPI0_BASE_ADDR (LIO_SPI_BASE_ADDR) +#define SPI1_BASE_ADDR (LIO_SPI_BASE_ADDR + 0x04000) +#define SPI_VERSION (1) +#define SPIS_COUNT (2) + +#define IIC_BASE_ADDR (LIO_SMB_0_BASE_ADDR) +#define IIC_SPACING (0x00004000) +#define IICS_COUNT (2) + +#define DSIM_BASE_ADDR (DISP_MIPI_DSI_BASE_ADDR) +#define DSIM_LANE_COUNT (1) +#define DSIM_VERSION (3) + +#define ADBE_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define DISP_VERSION (5) +#define ADP_VERSION (1) + +#define AMP_BASE_ADDR (AMPS_DQ_BASE_ADDR) +#define AMP_SPACING (0) +#define AMP_CA_SPACING (0x00010000) + +#if !CONFIG_SIM +#define AMP_REG_OFFSET (4) +#else + // FIXME M7 fastsim has an Alcatraz-y AMP until M7: update AMC/AMP for M7 +#define AMP_REG_OFFSET (0) +#endif + +#define PMGR_BASE_ADDR (SPU_PMGR_BASE_ADDR) +#define CHIPID_BASE_ADDR (PMGR_BASE_ADDR + 0x2A000) +#define PMGR_WDG_VERSION (1) + +#define GPIOC_COUNT (2) +#define GPIO_VERSION (4) +#define GPIO_BASE_ADDR (LIO_GPIO_BASE_ADDR) +#define GPIO_0_GROUP_COUNT (18) +#define GPIO_GROUP_COUNT (GPIO_0_GROUP_COUNT) +#define GPIO_1_BASE_ADDR (SPU_GPIO_BASE_ADDR) +#define GPIO_1_GROUP_COUNT (10) +#define GPIO_AP (GPIOC_0) +#define GPIO_SPU (GPIOC_1) + +#define AIC_BASE_ADDR (SPU_AIC_BASE_ADDR) +#define AIC_VERSION (1) +#define AIC_INT_COUNT (192) + +#define PL080DMAC_BASE_ADDR (LIO_DMAC_BASE_ADDR) +#define PL080DMAC_SPACING (0x4000) +#define PL080DMAC_COUNT (2) +#define PL080DMAC_CHANNEL_COUNT (8) + +#define USBOTG_BASE_ADDR (AUE_USBOTG_BASE_ADDR) +#define AUSB_CTL_REG_BASE_ADDR (AUE_USBCONT_BASE_ADDR) +#define AUSB_CTL_USB20PHY_REG_OFFSET (0x30) +#define AUSB_USB20PHY_ONLY_VERSION (1) +#define AUSB_PL301_WIDGET_BASE_ADDR (AUE_PL301_BASE_ADDR) + +#define AES_S7002_BASE_ADDR (LIO_AES_BASE_ADDR) +#define AES_S7002_VERSION (1) + +#define DBGFIFO_0_BASE_ADDR (SPU_DBG_FIFO_0_BASE_ADDR) +#define DBGFIFO_SPACING (0x3000) +#define DBGFIFO_COUNT (8) + +#define RECONFIG_RAM_SIZE_IN_WORDS (1024) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s7002/include/platform/soc/miu.h b/platform/s7002/include/platform/soc/miu.h new file mode 100644 index 0000000..1546797 --- /dev/null +++ b/platform/s7002/include/platform/soc/miu.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +// CPU Fabric Widget Registers (base address @ CPU_FABRIC_BASE_ADDR) +#define CPU_Fabric_pl301Wrap0_AMCRDRATELIMIT (0x0000) // AMC Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AMCWRALIMIT (0x0004) // AMC Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AMCRTRLIMIT (0x0008) // AMC Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_AMCWTRLIMIT (0x000c) // AMC Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_SPURDRATELIMIT (0x0040) // SPU Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_SPUWRALIMIT (0x0044) // SPU Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_SPURTRLIMIT (0x0048) // SPU Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_SPUWTRLIMIT (0x004c) // SPU Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_SPUWGATHER (0x0050) // SPU Write Gather Register +#define CPU_Fabric_pl301Wrap0_LIOWGATHER (0x0090) // LIO Write Gather Register +#define CPU_Fabric_pl301Wrap0_AUERDRATELIMIT (0x00c0) // AUE Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AUEWRALIMIT (0x00c4) // AUE Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AUERTRLIMIT (0x00c8) // AUE Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_AUEWTRLIMIT (0x00cc) // AUE Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_AUEWGATHER (0x00d0) // AUE Write Gather Register +#define CPU_Fabric_pl301Wrap0_ANSRDRATELIMIT (0x0100) // ANS Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_ANSWRALIMIT (0x0104) // ANS Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_ANSRTRLIMIT (0x0108) // ANS Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_ANSWTRLIMIT (0x010c) // ANS Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_ANSWGATHER (0x0110) // ANS Write Gather Register +#define CPU_Fabric_pl301Wrap0_AXI0_ARCHANARBMI0 (0x0408) // Configured AR channel arbitration value for MI 0 + +// NRT Fabric Widget Registers (base address @ NRT_FABRIC_BASE_ADDR) +#define NRT_Fabric_pl301Wrap1_AMCRDRATELIMIT (0x0000) // AMC Read Rate Limit Register +#define NRT_Fabric_pl301Wrap1_AMCWRALIMIT (0x0004) // AMC Write Rate Limit Register +#define NRT_Fabric_pl301Wrap1_AMCRTRLIMIT (0x0008) // AMC Read Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_AMCWTRLIMIT (0x000c) // AMC Write Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_MSRRDRATELIMIT (0x0040) // MSR Read Rate Limit Register +#define NRT_Fabric_pl301Wrap1_MSRWRALIMIT (0x0044) // MSR Write Rate Limit Register +#define NRT_Fabric_pl301Wrap1_MSRRTRLIMIT (0x0048) // MSR Read Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_MSRWTRLIMIT (0x004c) // MSR Write Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_SDIORDRATELIMIT (0x0080) // SDIO Read Rate Limit Register +#define NRT_Fabric_pl301Wrap1_SDIOWRALIMIT (0x0084) // SDIO Write Rate Limit Register +#define NRT_Fabric_pl301Wrap1_SDIORTRLIMIT (0x0088) // SDIO Read Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_SDIOWTRLIMIT (0x008c) // SDIO Write Transactions Limit Register + +#define rFABRIC_REMAP_REG *(volatile uint32_t *)(PMGR_BASE_ADDR + 0x31000) +#define rPIO_REMAP_CTL *(volatile uint32_t *)(PIO_BASE_ADDR + 0x00) + +enum remap_select { + REMAP_SRAM = 1, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); +extern void miu_configure_bridge_soc_reconfig_ram(void); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s7002/include/platform/soc/pmgr.h b/platform/s7002/include/platform/soc/pmgr.h new file mode 100644 index 0000000..41c5b4f --- /dev/null +++ b/platform/s7002/include/platform/soc/pmgr.h @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include + +enum { + PMGR_CLK_OSC = 0, + PMGR_CLK_PLL0, + PMGR_CLK_GPIO, + PMGR_CLK_SOURCE_FIRST = PMGR_CLK_GPIO, + PMGR_CLK_MCU, + PMGR_CLK_MCU_FIXED, + PMGR_CLK_GFX, + PMGR_CLK_MIPI_DSI, + PMGR_CLK_VID, + PMGR_CLK_MEDIA, + PMGR_CLK_DISP, + PMGR_CLK_SDIO, + PMGR_CLK_ANS, + PMGR_CLK_PIO, + PMGR_CLK_LIO, + PMGR_CLK_AUE, + PMGR_CLK_USB, + PMGR_CLK_SPI0_N, + PMGR_CLK_SPI1_N, + PMGR_CLK_NCO_REF0, + PMGR_CLK_NCO_REF1, + PMGR_CLK_NCO_ALG0, + PMGR_CLK_NCO_ALG1, + PMGR_CLK_MCA0_M, + PMGR_CLK_MCA1_M, + PMGR_CLK_SOURCE_LAST = PMGR_CLK_MCA1_M, + PMGR_CLK_S0, + PMGR_CLK_S1, + PMGR_CLK_COUNT, + PMGR_CLK_NOT_SUPPORTED +}; + +#define PMGR_CLK_CFG_INDEX(_clk) ((_clk) - PMGR_CLK_GPIO) + +// PLL Config Regs +#define rPMGR_PLL0_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0000)) + #define PMGR_PLL_ENABLE (1 << 31) + #define PMGR_PLL_LOAD (1 << 29) + #define PMGR_PLL_PENDING (1 << 25) + #define PMGR_PLL_M_SHIFT (12) + #define PMGR_PLL_M_MASK (0x1FF) + #define PMGR_PLL_P_SHIFT (4) + #define PMGR_PLL_P_MASK (0x1F) + #define PMGR_PLL_S_SHIFT (0) + #define PMGR_PLL_S_MASK (0xF) + #define PMGR_PLL_M(_m) (((_m) & PMGR_PLL_M_MASK) << PMGR_PLL_M_SHIFT) + #define PMGR_PLL_P(_p) (((_p) & PMGR_PLL_P_MASK) << PMGR_PLL_P_SHIFT) + #define PMGR_PLL_S(_s) (((_s) & PMGR_PLL_S_MASK) << PMGR_PLL_S_SHIFT) + #define PMGR_PLL_FREQ(_m, _p, _s) ((((_m) * OSC_FREQ) / (_p))/((_s) + 1)) + +#define rPMGR_PLL0_EXT_BYPASS_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0004)) + #define PMGR_PLL_BYP_ENABLED (1 << 31) + #define PMGR_PLL_PLL_ENABLED (1 << 30) + #define PMGR_PLL_EXT_BYPASS (1 << 0) + +#define rPMGR_PLL0_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0008)) +#define rPMGR_PLL0_ANA_PARAMS0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x000c)) +#define rPMGR_PLL0_ANA_PARAMS1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0010)) +//#define rPMGR_PLL0_FD_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0014)) +//#define rPMGR_PLL0_FRAC (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0018)) +//#define rPMGR_PLL0_DEBUG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x001c)) +//#define rPMGR_PLL0_DEBUG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0020)) +#define rPMGR_PLL0_PLL_DELAY_CTL0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0024)) +#define rPMGR_PLL0_PLL_DELAY_CTL1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x0028)) + +// General Clocks Config Regs +#define rPMGR_GPIO_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10000)) +#define rPMGR_MCU_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10004)) +#define rPMGR_MCU_FIXED_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10008)) +#define rPMGR_GFX_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x1000c)) +#define rPMGR_MIPI_DSI_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10010)) +#define rPMGR_VID_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10014)) +#define PMGR_MEDIA_CLK_CFG (0x10018) +#define rPMGR_MEDIA_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_MEDIA_CLK_CFG)) +#define rPMGR_DISP_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x1001c)) +#define rPMGR_SDIO_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10020)) +#define rPMGR_ANS_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10024)) +#define rPMGR_PIO_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10028)) +#define rPMGR_LIO_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x1002c)) +#define rPMGR_AUE_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10030)) +#define rPMGR_USB_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10034)) +#define rPMGR_SPI0_N_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10038)) +#define rPMGR_SPI1_N_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x1003c)) +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10040)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10044)) +#define rPMGR_NCO_ALG0_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10048)) +#define rPMGR_NCO_ALG1_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x1004c)) +#define rPMGR_MCA0_M_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10050)) +#define rPMGR_MCA1_M_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10054)) + +#define PMGR_FIRST_CLK_CFG (&rPMGR_GPIO_CLK_CFG) +#define PMGR_LAST_CLK_CFG (&rPMGR_MCA1_M_CLK_CFG) +#define PMGR_CLK_CFG_COUNT (((((void *)(PMGR_LAST_CLK_CFG)) - ((void *)(PMGR_FIRST_CLK_CFG))) / 4) + 1) +#define PMGR_CLK_NUM(_r) (((void *)&(rPMGR_ ## _r ## _CLK_CFG) - ((void *)(PMGR_FIRST_CLK_CFG))) / 4) + +// Spare Clocks Config Regs +#define rPMGR_S0_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10200)) +#define rPMGR_S1_CLK_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10204)) + +#define PMGR_FIRST_SPARE_CLK_CFG (&rPMGR_S0_CLK_CFG) +#define PMGR_LAST_SPARE_CLK_CFG (&rPMGR_S1_CLK_CFG) +#define PMGR_SPARE_CLK_CFG_COUNT (((((void *)(PMGR_LAST_SPARE_CLK_CFG)) - ((void *)(PMGR_FIRST_SPARE_CLK_CFG))) / 4) + 1) +#define PMGR_SPARE_CLK_NUM(_r) (((void *)&(rPMGR_ ## _r ## _CLK_CFG) - ((void *)(PMGR_FIRST_SPARE_CLK_CFG))) / 4) + +// CLK_CFG Bits +#define PMGR_CLK_CFG_ENABLE (1 << 31) +#define PMGR_CLK_CFG_PENDING (1 << 30) +#define PMGR_CLK_CFG_PENDING_SHIFT (30) +#define PMGR_CLK_CFG_SRC_SEL_MASK (0x3F) +#define PMGR_CLK_CFG_CFG_SEL_SHIFT (16) +#define PMGR_CLK_CFG_SRC_SEL_SHIFT (24) +#define PMGR_CLK_CFG_SRC_SEL(_n) ((_n) << PMGR_CLK_CFG_SRC_SEL_SHIFT) +#define PMGR_CLK_CFG_DIVISOR_MASK (0x3F) +#define PMGR_CLK_CFG_DIVISOR(_n) ((_n) << 0) + +// NCO Config block +#define rPMGR_NCO_CLK_CFG(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x0)) + +// Misc Clock Tree Power Saving Regs +#define rPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10300)) +#define rPMGR_CLK_POWER_CONFIG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x10304)) + +//PERF_STATE +#define rPMGR_SOC_PERF_STATE_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x1a000)) + +// Power State Regs +#define rPMGR_CPU_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20000)) +#define rPMGR_AIC_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20008)) +#define rPMGR_SPU_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20010)) +#define rPMGR_SPU_AKF_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20018)) +#define rPMGR_SPU_UART0_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20020)) +#define rPMGR_SPU_UART1_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20028)) +#define rPMGR_SPU_SMB_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20030)) +#define rPMGR_SPU_SGPIO_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20038)) +#define rPMGR_DOCKFIFO_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20040)) +#define rPMGR_MCU_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20048)) +#define rPMGR_AMP_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20050)) +#define rPMGR_PIOSYS_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20058)) +#define rPMGR_DISP_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20060)) +#define rPMGR_MIPI_DSI_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20068)) +#define PMGR_MSR_PS (0x20070) +#define rPMGR_MSR_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_MSR_PS)) +#define rPMGR_MEDIA_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20078)) +#define rPMGR_ANS_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20080)) +#define rPMGR_GFX_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20088)) +#define rPMGR_SDIO_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20090)) +#define rPMGR_LIO_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20098)) +#define rPMGR_GPIO_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200a0)) +#define rPMGR_MCA0_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200a8)) +#define rPMGR_MCA1_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200b0)) +#define rPMGR_SPI0_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200b8)) +#define rPMGR_SPI1_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200c0)) +#define rPMGR_DMATX_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200c8)) +#define rPMGR_DMARX_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200d0)) +#define rPMGR_UART0_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200d8)) +#define rPMGR_UART1_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200e0)) +#define rPMGR_UART2_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200e8)) +#define rPMGR_UART3_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200f0)) +#define rPMGR_UART4_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x200f8)) +#define rPMGR_AES_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20100)) +#define rPMGR_I2C0_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20108)) +#define rPMGR_I2C1_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20110)) +#define rPMGR_PWM0_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20118)) +#define rPMGR_AUE_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20120)) +#define rPMGR_USB_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20128)) +#define rPMGR_ETH_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20130)) +#define rPMGR_VDEC_PS (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x20138)) + +#define rSPU_PMGR_DEBUG_PS (*(volatile uint32_t *) (SPU_SEQUENCER_BASE_ADDR + 0x03004)) + +#define PMGR_PS_RESET (1 << 31) +#define PMGR_PS_ACTUAL_PS_SHIFT (4) +#define PMGR_PS_ACTUAL_PS_MASK (0xF) +#define PMGR_PS_MANUAL_PS_MASK (0xF) +#define PMGR_PS_RUN_MAX (0xF) +#define PMGR_PS_CLOCK_OFF (0x4) +#define PMGR_PS_POWER_OFF (0x0) + +#define PMGR_FIRST_PS (&rPMGR_CPU_PS) +#define PMGR_LAST_PS (&rPMGR_VDEC_PS) +#define PMGR_PS_COUNT (((((void *)(PMGR_LAST_PS)) - ((void *)(PMGR_FIRST_PS))) / 8) + 1) +#define PMGR_PS_NUM(_r) (((void *)&(rPMGR_ ## _r ## _PS) - ((void *)(PMGR_FIRST_PS))) / 8) + +// Power Gate Tunable Regs +#define rPMGR_PWR_CPU_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22000)) +#define rPMGR_PWR_CPU_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22004)) +#define rPMGR_PWR_CPU_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22008)) +#define rPMGR_PWR_CPU_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2200c)) +#define rPMGR_PWR_AMCPIO_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22010)) +#define rPMGR_PWR_AMCPIO_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22014)) +#define rPMGR_PWR_AMCPIO_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22018)) +#define rPMGR_PWR_AMCPIO_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2201c)) +#define rPMGR_PWR_DISP_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22020)) +#define rPMGR_PWR_DISP_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22024)) +#define rPMGR_PWR_DISP_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22028)) +#define rPMGR_PWR_DISP_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2202c)) +#define rPMGR_PWR_DISP_BE_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22030)) +#define rPMGR_PWR_DISP_BE_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22034)) +#define rPMGR_PWR_DISP_BE_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22038)) +#define rPMGR_PWR_DISP_BE_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2203c)) +#define rPMGR_PWR_MSR_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22040)) +#define rPMGR_PWR_MSR_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22044)) +#define rPMGR_PWR_MSR_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22048)) +#define rPMGR_PWR_MSR_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2204c)) +#define rPMGR_PWR_ANS_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22050)) +#define rPMGR_PWR_ANS_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22054)) +#define rPMGR_PWR_ANS_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22058)) +#define rPMGR_PWR_ANS_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2205c)) +#define rPMGR_PWR_GFX_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22060)) +#define rPMGR_PWR_GFX_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22064)) +#define rPMGR_PWR_GFX_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22068)) +#define rPMGR_PWR_GFX_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2206c)) +#define rPMGR_PWR_SDIO_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22070)) +#define rPMGR_PWR_SDIO_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22074)) +#define rPMGR_PWR_SDIO_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22078)) +#define rPMGR_PWR_SDIO_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2207c)) +#define rPMGR_PWR_LIO_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22080)) +#define rPMGR_PWR_LIO_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22084)) +#define rPMGR_PWR_LIO_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22088)) +#define rPMGR_PWR_LIO_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2208c)) +#define rPMGR_PWR_AUE_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22090)) +#define rPMGR_PWR_AUE_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22094)) +#define rPMGR_PWR_AUE_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22098)) +#define rPMGR_PWR_AUE_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2209c)) +#define rPMGR_PWR_VDEC_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220a0)) +#define rPMGR_PWR_VDEC_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220a4)) +#define rPMGR_PWR_VDEC_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220a8)) +#define rPMGR_PWR_VDEC_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220ac)) +#define rPMGR_MCU_ASYNC_RESET (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22300)) + +// EMA Tunable Regs +#define rPMGR_EMA_SOC0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x26000)) +#define rPMGR_EMA_SOC1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x26004)) + +// Timer Regs +#define rPMGR_CHIP_WDOG_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27000)) +#define rPMGR_CHIP_WDOG_RST_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27004)) +#define rPMGR_CHIP_WDOG_INTR_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27008)) +#define rPMGR_CHIP_WDOG_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2700c)) +#define rPMGR_SYS_WDOG_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27010)) +#define rPMGR_SYS_WDOG_RST_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27014)) +#define rPMGR_SYS_WDOG_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2701c)) +#define rPMGR_EVENT_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27100)) +#define rPMGR_EVENT_TMR_PERIOD (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27104)) +#define rPMGR_EVENT_TMR_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27108)) +#define rPMGR_INTERVAL_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27200)) +#define rPMGR_INTERVAL_TMR_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27204)) + +#define rPMGR_SCRATCH(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x29000 + ((_n)*4))) +#define rPMGR_SCRATCH0 rPMGR_SCRATCH(0) /* Flags */ +#define rPMGR_SCRATCH1 rPMGR_SCRATCH(1) +#define rPMGR_SCRATCH2 rPMGR_SCRATCH(2) +#define rPMGR_SCRATCH3 rPMGR_SCRATCH(3) +#define rPMGR_SCRATCH4 rPMGR_SCRATCH(4) +#define rPMGR_SCRATCH5 rPMGR_SCRATCH(5) +#define rPMGR_SCRATCH6 rPMGR_SCRATCH(6) +#define rPMGR_SCRATCH7 rPMGR_SCRATCH(7) /* Consistent debug root pointer */ +#define rPMGR_SCRATCH8 rPMGR_SCRATCH(8) +#define rPMGR_SCRATCH9 rPMGR_SCRATCH(9) +#define rPMGR_SCRATCH10 rPMGR_SCRATCH(10) +#define rPMGR_SCRATCH11 rPMGR_SCRATCH(11) +#define rPMGR_SCRATCH12 rPMGR_SCRATCH(12) +#define rPMGR_SCRATCH13 rPMGR_SCRATCH(13) /* Memory info */ +#define rPMGR_SCRATCH14 rPMGR_SCRATCH(14) /* Boot Nonce 0 */ +#define rPMGR_SCRATCH15 rPMGR_SCRATCH(15) /* Boot Nonce 1 */ +#define rPMGR_SCRATCH16 rPMGR_SCRATCH(16) /* Boot Manifest Hash 0 */ +#define rPMGR_SCRATCH17 rPMGR_SCRATCH(17) /* Boot Manifest Hash 1 */ +#define rPMGR_SCRATCH18 rPMGR_SCRATCH(18) /* Boot Manifest Hash 2 */ +#define rPMGR_SCRATCH19 rPMGR_SCRATCH(19) /* Boot Manifest Hash 3 */ +#define rPMGR_SCRATCH20 rPMGR_SCRATCH(20) /* Boot Manifest Hash 4 */ +#define rPMGR_SCRATCH21 rPMGR_SCRATCH(21) +#define rPMGR_SCRATCH22 rPMGR_SCRATCH(22) +#define rPMGR_SCRATCH23 rPMGR_SCRATCH(23) + +#define rPMGR_SECURITY (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x31020)) + +#define rPMGR_MISC_GFX_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x31040)) + +#define rPMGR_MISC_ACG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x32000)) + +extern void pmgr_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/s7002/include/platform/soc/reconfig.h b/platform/s7002/include/platform/soc/reconfig.h new file mode 100644 index 0000000..b845d7e --- /dev/null +++ b/platform/s7002/include/platform/soc/reconfig.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_RECONFIG_H +#define __PLATFORM_RECONFIG_H + +#include + +#define rRECONFIG_CONFIGURATION *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0000) +#define rRECONFIG_CONFIG_MEM *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0004) +#define rRECONFIG_TIMEOUT_MEM *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0008) +#define rRECONFIG_INTERRUPT_MEM *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x000C) +#define rRECONFIG_CONFIG_SOC *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0010) +#define rRECONFIG_TIMEOUT_SOC *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0014) +#define rRECONFIG_INTERRUPT_SOC *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0018) +#define rRECONFIG_CONFIG_AKF *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x001C) +#define rRECONFIG_TIMEOUT_AKF *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0020) +#define rRECONFIG_INTERRUPT_AKF *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x0024) + + +#define rRECONFIG_RAM_CMD(i) *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x1000 + (i * 4)) +#define rRECONFIG_RAM_DATA(i) *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x2000 + (i * 4)) +#define rRECONFIG_RAM_MASK(i) *(volatile uint32_t *)(SPU_SOC_RECONFIG_BASE_ADDR + 0x3000 + (i * 4)) + +#define RECONFIG_RAM_CMD_READ (1 << 0) + +// Removing this debug region now that reconfig engine/code seems to be working fine +// Do not use this space since SPU may have reclaimed it +#if 0 +// last page of SPU SRAM allocated to RECONFIG for reconfig debug purposes +#define RECONFIG_DEBUG_SPACE (SPU_SRAM_A_BASE_ADDR + SPU_SRAM_SIZE - PAGE_SIZE) +#endif + +typedef enum {RECONFIG_TYPE_MEM, RECONFIG_TYPE_SOC, RECONFIG_TYPE_AKF} reconfig_type_t; + + +/** + * Adds a reconfig command of the given type to the reconfig buffer + * + * Note that the reconfig driver expects you to program in all the RECONFIG_TYPE_MEM commands, + * followed by SOC commands, followed by AKF commands. The driver will panic if you attempt to program + * the block in a different sequence. + * + **/ +void reconfig_append_command(reconfig_type_t type, uint32_t cmd, uint32_t data, uint32_t mask); + +/** + * Program the RECONFIG_CONFIG_{SOC/MEM/AKF} registers with the start / counts, and enables the reconfig block. + * + * Call this after you've fully reprogrammed the reconfig memory using reconfig_append_command() + **/ +void reconfig_commit(); + + +/** + * Prints the contents of the reconfig buffer via printf. For debugging purposes only + **/ +void reconfig_dbg_dump_contents(void); + +#endif /* __PLATFORM_RECONFIG_H */ diff --git a/platform/s7002/include/platform/soc/spu.h b/platform/s7002/include/platform/soc/spu.h new file mode 100644 index 0000000..de45e9c --- /dev/null +++ b/platform/s7002/include/platform/soc/spu.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_SPU_H +#define __PLATFORM_SOC_SPU_H + +#include + +#define rSPU_AKF_AXI_BASE (*(volatile uint32_t *) (SPU_AKF_BASE_ADDR + 0x8)) +#define rSPU_AKF_AXI_BASE_EXT (*(volatile uint32_t *) (SPU_AKF_BASE_ADDR + 0xC)) +#define rSPU_AKF_AXI_START (*(volatile uint32_t *) (SPU_AKF_BASE_ADDR + 0x10)) +#define rSPU_AKF_AXI_END (*(volatile uint32_t *) (SPU_AKF_BASE_ADDR + 0x18)) +#define rSPU_AKF_AXI_EN (*(volatile uint32_t *) (SPU_AKF_BASE_ADDR + 0x20)) +#define rSPU_AKF_AXI_IDLE_CTRL (*(volatile uint32_t *) (SPU_AKF_BASE_ADDR + 0x24)) +#define rSPU_AKF_AXI_CPU_CTRL (*(volatile uint32_t *) (SPU_AKF_BASE_ADDR + 0x28)) + +#define SP_AKF_AXI_CPU_CTRL_RUN (1 << 4) + +#endif /* ! __PLATFORM_SOC_SPU_H */ diff --git a/platform/s7002/include/platform/trampoline.h b/platform/s7002/include/platform/trampoline.h new file mode 100644 index 0000000..a1094b0 --- /dev/null +++ b/platform/s7002/include/platform/trampoline.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include + +/* ROM related registers in PMGR space */ + +#define SECURITY_REG (PMGR_BASE_ADDR + 0x31020) +#define ROM_READ_DISABLE (1 << 4) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s7002/include/platform/usbconfig.h b/platform/s7002/include/platform/usbconfig.h new file mode 100644 index 0000000..4294429 --- /dev/null +++ b/platform/s7002/include/platform/usbconfig.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#ifdef WITH_TARGET_USB_CONFIG +#include +#endif /* WITH_TARGET_USB_CONFIG */ + +#define USBPHY_OTGTUNE0 (0x374413F3) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s7002/init.c b/platform/s7002/init.c new file mode 100644 index 0000000..d7af688 --- /dev/null +++ b/platform/s7002/init.c @@ -0,0 +1,1566 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#if WITH_HW_DOCKFIFO_UART || WITH_HW_DOCKFIFO_BULK +#include +#endif +#if WITH_CONSISTENT_DBG +#include +#endif +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uint8_t boot_debug; +static bool gDisplayEnabled; + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + uint32_t enable; + uint32_t disable; +}; + +#if WITH_ANC_BOOT +/* Note: The code below expects this table to begin with CS1 through CS0 */ +static const struct boot_interface_pin nand_boot_interface_pins[] = +{ + { GPIO(10, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_CEN0 + { GPIO( 9, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_CEN1 + { GPIO(11, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_CLE + { GPIO(11, 5), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_ALE + { GPIO(10, 6), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_REN + { GPIO(11, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_WEN + { GPIO(11, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO0 + { GPIO(11, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO1 + { GPIO(11, 0), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO2 + { GPIO(10, 7), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO3 + { GPIO(10, 4), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO4 + { GPIO(10, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO5 + { GPIO(10, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO6 + { GPIO(10, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // NAND_IO7 +}; +#endif /* WITH_ANC_BOOT */ + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ + { GPIO(12, 4), GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN + { GPIO(12, 1), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO(12, 2), GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO(12, 3), GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +static void platform_init_boot_strap(void); +static void platform_bootprep_darwin(void); + +extern void amc_configure_mem_reconfig_ram(void); + +int platform_early_init(void) +{ +#if APPLICATION_IBOOT && (PRODUCT_LLB || PRODUCT_IBSS) + /* Verify that the fuses and SecureROM R/W access has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile uint32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) + panic("Fuses are unlocked or SecureROM is enabled\n"); +#endif + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8960x pmgr driver */ + platform_power_init(); +#endif + +#if WITH_CONSISTENT_DBG && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + consistent_debug_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif + +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif + +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif + +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); + debug_enable_uarts(3); +#endif + +#if WITH_HW_DOCKFIFO_UART + /* do whatever uart initialization we need to get a simple console */ + dockfifo_uart_init(); + debug_enable_uarts(3); +#endif + +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif + +#if WITH_IIC + iic_init(); +#endif + +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_HW_DMA + /* initialize the dma engine */ + dma_init(); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + + return 0; +} + +int platform_late_init(void) +{ +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_CSI + csi_late_init(); +#endif + + return 0; +} + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if (PRODUCT_LLB || PRODUCT_IBSS) && WITH_HW_DOCKFIFO_UART + // Enable all DockFIFO's used by platform in LLB () + platform_dockfifo_access_enable((1) | (1<<1) | (1<<2) | (1<<3)); +#endif + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); + + /* always remap the memory region at this point, regardless of resume, + * because the early MMU init always runs and we have to fix up. */ + platform_init_mainmem_map(); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { + if (!displayInitOnce) { + platform_quiesce_display(); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } else { +#if PRODUCT_IBSS + /* + * WARNING: With move to DFU-mode iBSS, this will never be + * reached. Thus, it should either be eliminated or + * refactored to make sense, perhaps by changing + * condition from PRODUCT_IBSS to WITH_RESTORE_BOOT. + */ + debug_enable_uarts(3); +#endif + } + if (env_get_uint("display-rotation", 0) == 1) + { + display_set_rotation(true); + } +#endif + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + addr_t base_rounded = *base; + addr_t end_rounded = *base + *size; + size_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + arm_mmu_map_section_range(base_rounded, base_rounded, size_rounded/MB, kARMMMUWriteCombined, false, true); + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_HW_ASP + return (asp_nand_open()); +#else + return 0; +#endif +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + +#if WITH_CSI + csi_quiesce(target); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + /* quiesce the clcd panel */ + display_quiesce(true); +#endif + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + uint32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + platform_quiesce_display(); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* Darwin only gets the UID on resume */ + uids = 1; + gids = 0; + break; + + case BOOT_DARWIN: + /* setup Reconfig block, program MEM and SOC configs */ + platform_bootprep_darwin(); + + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + /* Leave the GIDs alone since we Need them to + generate a special key for stockholm + pairing. GIDs will be disabled by the + AppleS7002AES driver once the special key + has been + generated. */ + uids = 1; + gids = ~0; + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: + platform_quiesce_display(); + break; +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_MONITOR: + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + default: + ; // do nothing + } + + /* make sure that fuse lock bit is set. */ + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + + /* mark usable ram as cached/buffered, shared */ + arm_mmu_map_section_range(SRAM_BASE, SRAM_BASE, ROUNDUP(SRAM_BANK_LEN, MB)/MB, kARMMMUNormal, true, false); +#if APPLICATION_SECUREROM + arm_mmu_map_section_range(VROM_BASE, VROM_BASE, ROUNDUP(VROM_BANK_LEN, MB)/MB, kARMMMUNormal, true, false); +#endif + +#if !(PRODUCT_IBSS || PRODUCT_LLB) + arm_mmu_map_section(0, TEXT_BASE, kARMMMUNormalRX, true); +#endif + + /* in cases where we are running from DRAM, remap it now */ +#if APPLICATION_IBOOT + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, kARMMMUNormal, true, false); +#endif +} + +int platform_init(void) +{ + bool __unused skip_ans = false; + +#if WITH_HW_SPI + spi_init(); +#endif + +#if PRODUCT_IBOOT && WITH_TARGET_CHARGETRAP + // Skip ANS initialization if booting into Dali mode from iBoot -- we can use ANC NVRAM. + if (target_needs_chargetrap()) { + skip_ans = true; + } +#endif + + +#if WITH_HW_ASP && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + if (!skip_ans) { + csi_init(CSI_COPROC_ANS); /* coproc switchboard used by nand driver to communicate with ans iop */ + asp_init(); + } +#endif + +#if WITH_ANC_FIRMWARE +// For iBoot, ANC_FIRMWARE is only used when booting into Dali mode (e.g. skip_ans is set) +#if PRODUCT_IBOOT + if (skip_ans) { + anc_firmware_init(); + } +#else +// For other boot stages, ANC_FIRMWARE is used whenever it's present + anc_firmware_init(); +#endif // PRODUCT_IBOOT +#endif // WITH_ANC_FIRMWARE + +#if WITH_TARGET_CONFIG + target_init(); +#endif + + return 0; +} + +int platform_init_usb() +{ + int ret = 0; + +#if WITH_HW_DOCKFIFO_BULK + /* BOOT_CONFIG[3] is reserved to select between USB or DebugFifo to move data. + * BOOT_CONFIG[0..3] is read and saved in rPMGR_SCRATCH0 (bits 15..8) + */ + if (((rPMGR_SCRATCH0 >> 11) & 1) == 0) { + extern struct usb_controller_functions *usb_dockfifo_controller_init(); + ret = usb_init_with_controller(usb_dockfifo_controller_init()); + } + else +#endif + { +#if WITH_HW_SYNOPSYS_OTG + extern struct usb_controller_functions *synopsys_otg_controller_init(); + ret = usb_init_with_controller(synopsys_otg_controller_init()); +#endif + } + + return ret; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + platform_init_usb(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +uint32_t platform_set_performance(uint32_t performance_level) +{ + uint32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_CPU); + memcpy(propData, &freq, propSize); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_MEM); + memcpy(propData, &freq, propSize); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_BUS); + memcpy(propData, &freq, propSize); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_PERIPH); + memcpy(propData, &freq, propSize); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_FIXED); + memcpy(propData, &freq, propSize); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_TIMEBASE); + memcpy(propData, &freq, propSize); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(uint32_t)); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + + return target_update_device_tree(); +} + +#endif + +uint32_t platform_get_board_id(void) +{ + uint32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +uint32_t platform_get_boot_config(void) +{ + uint32_t boot_config; + +#if WITH_HW_DOCKFIFO_BULK + /* + * BOOT_CONFIG[3] is reserved, if its set system will use USB else DockFifo for moving data. + * Boot-config is essentially 3 bits on M7 BOOT_CONFIG[0..2] + */ + boot_config = (rPMGR_SCRATCH0 >> 8) & 0x07; +#else + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; +#endif + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, uint32_t *boot_flag, uint32_t *boot_arg) +{ + uint32_t boot_config = platform_get_boot_config(); + + /* S7002 supports one boot device then USB-DFU or Bulk-DockFifo-DFU per boot config */ + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case 0: /* SPI 0 */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 1: /* SPI 0 Test Mode */ + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case 2: /* ANS */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 0; + break; + + case 3: /* ANS Test Mode */ + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + /* case 4-15: Unused */ + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == 1) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +#if WITH_HW_POWER +uint32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} +#endif + +int platform_get_soc_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = platform_get_base_soc_voltage(); + } + + return 0; +} + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, uint32_t boot_arg) +{ + const struct boot_interface_pin *pins = 0; + uint32_t cnt, func, pin_count = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins = spi0_boot_interface_pins; + pin_count = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_ANC_BOOT + case BOOT_DEVICE_NAND : + pins = nand_boot_interface_pins; + pin_count = (sizeof(nand_boot_interface_pins) / sizeof(nand_boot_interface_pins[0])); + + break; +#endif /* WITH_ANC_BOOT */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count; cnt++) { + if (enable) { + pin = pins[pin_count - 1 - cnt].pin; + func = pins[pin_count - 1 - cnt].enable; + } else { + pin = pins[cnt].pin; + func = pins[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +uint64_t platform_get_nonce(void) +{ + uint64_t nonce; + uint32_t *nonce_words = (uint32_t *)&nonce; + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return true; +} + +uint32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_DOCKFIFO_BULK + /* BOOT_CONFIG[3] is reserved to select between USB or DebugFifo to move data. + * BOOT_CONFIG[0..3] is read and saved in rPMGR_SCRATCH0 (bits 15..8) + */ + if (((rPMGR_SCRATCH0 >> 11) & 1) == 0) { + return platform_get_dock_connect(); + } + else +#endif + { +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif + } +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ + return gpio_read(GPIO_FORCE_DFU); +} + +bool platform_get_request_dfu1(void) +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +bool platform_get_dock_connect(void) +{ +#if CONFIG_FPGA || CONFIG_SIM + return true; +#else + return gpio_read(GPIO_DOCK_CONNECT); +#endif +} + +void platform_set_dock_attention(bool value) +{ + gpio_write(GPIO_DOCK_ATTENTION, value); +} + +int platform_translate_key_selector(uint32_t key_selector, uint32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +void platform_disable_keys(uint32_t gid, uint32_t uid) +{ + uint32_t key_disable = (((gid & 0x1) << 1) | ((uid & 0x3) << 2)); + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return; + + rPMGR_SECURITY = key_disable; +} + +bool platform_keys_disabled(uint32_t gid, uint32_t uid) +{ + uint32_t key_disabled; + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return true; + + key_disabled = rPMGR_SECURITY; + + return (key_disabled & (((gid & 0x1) << 1) | ((uid & 0x3) << 2))); +} + +void platform_demote_production() +{ + chipid_clear_production_mode(); +} + +#if APPLICATION_IBOOT +uint64_t platform_get_memory_size(void) +{ + uint64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (rPMGR_SCRATCH13 & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +uint8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 28) & 0xf); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info(uint8_t manuf_id, uint64_t memory_size) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 28) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} +#endif + +int32_t platform_get_boot_manifest_hash(uint8_t *boot_manifest_hash) +{ + RELEASE_ASSERT(boot_manifest_hash != NULL); + + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagObjectManifestHashValid) != 0) { + ((uint32_t *)boot_manifest_hash)[0] = rPMGR_SCRATCH16; + ((uint32_t *)boot_manifest_hash)[1] = rPMGR_SCRATCH17; + ((uint32_t *)boot_manifest_hash)[2] = rPMGR_SCRATCH18; + ((uint32_t *)boot_manifest_hash)[3] = rPMGR_SCRATCH19; + ((uint32_t *)boot_manifest_hash)[4] = rPMGR_SCRATCH20; + + return 0; + } + + return -1; +} + +int32_t platform_set_boot_manifest_hash(const uint8_t *boot_manifest_hash) +{ + if(boot_manifest_hash != NULL) { + rPMGR_SCRATCH16 = ((uint32_t *)boot_manifest_hash)[0]; + rPMGR_SCRATCH17 = ((uint32_t *)boot_manifest_hash)[1]; + rPMGR_SCRATCH18 = ((uint32_t *)boot_manifest_hash)[2]; + rPMGR_SCRATCH19 = ((uint32_t *)boot_manifest_hash)[3]; + rPMGR_SCRATCH20 = ((uint32_t *)boot_manifest_hash)[4]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagObjectManifestHashValid; + } + else { + rPMGR_SCRATCH16 = 0; + rPMGR_SCRATCH17 = 0; + rPMGR_SCRATCH18 = 0; + rPMGR_SCRATCH19 = 0; + rPMGR_SCRATCH20 = 0; + + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagObjectManifestHashValid; + } + + return 0; +} + +bool platform_get_mix_n_match_prevention_status(void) +{ + return ((rPMGR_SCRATCH0 & kPlatformScratchFlagVerifyManifestHash) ? true : false); +} + +void platform_set_mix_n_match_prevention_status(bool mix_n_match_prevented) +{ + if (mix_n_match_prevented) + rPMGR_SCRATCH0 |= kPlatformScratchFlagVerifyManifestHash; + else + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagVerifyManifestHash; +} + +void platform_set_consistent_debug_root_pointer(uint32_t root) +{ + rPMGR_SCRATCH7 = root; +} + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = PANIC_BASE; + break; + + case kMemoryRegion_StorageProcessor: + base = ASP_BASE; + break; + + case kMemoryRegion_Kernel: + base = SDRAM_BASE; + break; + + case kMemoryRegion_Heap: + base = HEAP_BASE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_SleepToken: + base = SLEEP_TOKEN_BUFFER_BASE; + break; + + case kMemoryRegion_Display: + base = PANIC_BASE - platform_get_memory_region_size(kMemoryRegion_Display); + break; + + case kMemoryRegion_iBoot: + base = IBOOT_BASE; + break; +#endif + + default: + base = (uintptr_t)-1; + break; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + + case kMemoryRegion_StorageProcessor: + size = ASP_SIZE; + break; + + case kMemoryRegion_Kernel: + size = platform_get_memory_region_base(kMemoryRegion_Display) - platform_get_memory_region_base(kMemoryRegion_Kernel); + break; + + case kMemoryRegion_Heap: + size = HEAP_SIZE; + break; + + +#if APPLICATION_IBOOT + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; + + case kMemoryRegion_Display: + size = platform_get_display_memory_size(); + ASSERT(size != 0); + break; + + case kMemoryRegion_iBoot: + size = IBOOT_SIZE; + break; +#endif + + default: + size = (size_t)-1; + break; + } + + return size; +} + +void platform_dockfifo_access_enable(uint32_t enable_flags) +{ + uintptr_t dbgfifo_access_reg = (SPU_DBG_WRAP_BASE_ADDR + 0x1094); // DEBUG_FIFO_ACCESS_ENABLE register + + uint32_t curr_value = (*(volatile uint32_t *)dbgfifo_access_reg); + + dprintf(DEBUG_SPEW, "platform_dockfifo_access_enable: dbgfifo_access_reg:0x%08x, requested:0x%08x\n", curr_value, enable_flags); + + if (curr_value) + panic("DEBUG_FIFO_ACCESS_ENABLE already nonzero (0x%08x), this can cause a hang due to ", curr_value); + + (*(volatile uint32_t *)dbgfifo_access_reg) = enable_flags; + + dprintf(DEBUG_SPEW, "platform_dockfifo_access_enable: finished, dbgfifo_access_reg:0x%08x \n", (*(volatile uint32_t *)dbgfifo_access_reg)); +} + +#if WITH_BOOT_TRAMPOLINE +extern uintptr_t boot_handoff_trampoline; + +void *platform_get_boot_trampoline(void) +{ + return (void *)&boot_handoff_trampoline; +} +#endif /* WITH_BOOT_TRAMPOLINE */ + +static void platform_init_boot_strap(void) +{ + uint32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG3, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG3) << 3) | + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +static void platform_configure_soc_reconfig_ram() +{ + // M7: ANP PHY reset at chipPads power-up (STR) + reconfig_append_command(RECONFIG_TYPE_SOC, (addr_t)(&rPMGR_ANS_PS), 0xF, 0x0); + reconfig_append_command(RECONFIG_TYPE_SOC, ((addr_t)(&rPMGR_ANS_PS)) | RECONFIG_RAM_CMD_READ, (0xF << 4), (0xF << 4)); + + // Set remap to SDRAM + reconfig_append_command(RECONFIG_TYPE_SOC, (addr_t)(&rFABRIC_REMAP_REG), 1, 0x0); + + // Reconfigure GPIO block - reg GPIO_GPIO_NPL_IN_EN, set bit 0 (GPIO_NPL_IN_EN) + reconfig_append_command(RECONFIG_TYPE_SOC, 0x47100c48, 1, 0x0); + + // Reconfigure static SoC bridge tunables. + miu_configure_bridge_soc_reconfig_ram(); +} + +static void platform_configure_akf_reconfig_ram() +{ + reconfig_append_command(RECONFIG_TYPE_AKF, (addr_t) &rSPU_AKF_AXI_BASE, SPU_SRAM_A_BASE_ADDR, 0); + reconfig_append_command(RECONFIG_TYPE_AKF, (addr_t) &rSPU_AKF_AXI_BASE_EXT, 0, 0); + reconfig_append_command(RECONFIG_TYPE_AKF, (addr_t) &rSPU_AKF_AXI_END, SPU_SRAM_SIZE, 0); + reconfig_append_command(RECONFIG_TYPE_AKF, (addr_t) &rSPU_AKF_AXI_EN, 1, 0); + // SPU software to re-enable gating + reconfig_append_command(RECONFIG_TYPE_AKF, (addr_t) &rSPU_AKF_AXI_IDLE_CTRL, 0, 0); + reconfig_append_command(RECONFIG_TYPE_AKF, (addr_t) &rSPU_AKF_AXI_CPU_CTRL, SP_AKF_AXI_CPU_CTRL_RUN, 0); +} + +static void platform_bootprep_darwin() +{ + + // Configure MEM config + + // Ugliness is M7: ReconfigMem and PerfState Change + // + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t)&rPMGR_SOC_PERF_STATE_CTL, 0x3, 0); + + amc_configure_mem_reconfig_ram(); + +#if SUPPORT_FPGA + // enable, 24 MHz + uint32_t mcu_fixed_clk_cfg = (1 << 31) | (0 << 24) | (1 << 20); + // enable, 24 MHz, cfg_sel = 3 + uint32_t mcu_clk_cfg = (1 << 31) | (0 << 24) | (1 << 20) | (3 << 16); +#else + // enable, 533 MHz + uint32_t mcu_fixed_clk_cfg = (1 << 31) | (1 << 24) | (1 << 20); + // enable, 533 MHz, cfg_sel = 0 + uint32_t mcu_clk_cfg = (1 << 31) | (3 << 24) | (1 << 20) | (0 << 16); +#endif + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t)&rPMGR_MCU_FIXED_CLK_CFG, mcu_fixed_clk_cfg, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t)&rPMGR_MCU_FIXED_CLK_CFG) | RECONFIG_RAM_CMD_READ, 0, (1 << 30)); + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t)&rPMGR_MCU_CLK_CFG, mcu_clk_cfg, 0); + reconfig_append_command(RECONFIG_TYPE_MEM, ((addr_t)&rPMGR_MCU_CLK_CFG) | RECONFIG_RAM_CMD_READ, 0, (1 << 30)); + + reconfig_append_command(RECONFIG_TYPE_MEM, (addr_t)&rPMGR_SOC_PERF_STATE_CTL, 0x7, 0); + + // Configure SOC config + platform_configure_soc_reconfig_ram(); + + // Configure AKF config + platform_configure_akf_reconfig_ram(); + + reconfig_commit(); + + // Apply reconfig timeout tunables + rRECONFIG_TIMEOUT_AKF = 0x1b71b00; + rRECONFIG_TIMEOUT_SOC = 0x1b71b00; + rRECONFIG_TIMEOUT_MEM = 0x1b71b00; +} + +#if defined(WITH_MENU) && WITH_MENU + +static int do_m7_str_test(int argc, struct cmd_arg *args) __noreturn; + +static int do_m7_str_test(int argc, struct cmd_arg *args) +{ + dprintf(DEBUG_INFO, "starting M7 STR test...\n"); + + // Turn following PS off + *(volatile uint32_t *)0x46c20088 = 0; + *(volatile uint32_t *)0x46c20068 = 0; + *(volatile uint32_t *)0x46c20060 = 0; + *(volatile uint32_t *)0x46c20070 = 0; + *(volatile uint32_t *)0x46c20080 = 0; + *(volatile uint32_t *)0x46c20120 = 0; + *(volatile uint32_t *)0x46c20128 = 0; + *(volatile uint32_t *)0x46c20130 = 0; + *(volatile uint32_t *)0x46c20138 = 0; + *(volatile uint32_t *)0x46c20090 = 0; + *(volatile uint32_t *)0x46c200c8 = 0; + *(volatile uint32_t *)0x46c200d0 = 0; + + // Enable auto power gating for MCU, AMP, PIOSYS, LIO + *(volatile uint32_t *)0x46c20048 |= (1 << 28); + *(volatile uint32_t *)0x46c20050 |= (1 << 28); + *(volatile uint32_t *)0x46c20058 |= (1 << 28); + *(volatile uint32_t *)0x46c20098 |= (1 << 28); + + // Enable power gating for AMCPIO domain + *(volatile uint32_t *)0x46c22010 |= (1 << 31); + + // Program perf-state table + *(volatile uint32_t *)0x46c1a010 = (0<<8)|(1<<7)|(3<<4); + *(volatile uint32_t *)0x46c1a020 = (3<<8)|(0<<7)|(0<<4); + *(volatile uint32_t *)0x46c1a030 = (3<<8)|(0<<7)|(0<<4); + *(volatile uint32_t *)0x46c1a000 = 0x7; // enable all perf states + + // Enable global ACG + *(volatile uint32_t *)0x46c32000 = 1; + + // MEM config + *(volatile uint32_t *)0x46901000 = 0x46030000; + *(volatile uint32_t *)0x46902000 = 0xfefefefe; + *(volatile uint32_t *)0x46901004 = 0x46030004; + *(volatile uint32_t *)0x46902004 = 0xfefefefe; + + // SOC config + *(volatile uint32_t *)0x46901010 = 0x46030010; + *(volatile uint32_t *)0x46902010 = 0xfefefefe; + *(volatile uint32_t *)0x46901014 = 0x46030014; + *(volatile uint32_t *)0x46902014 = 0xfefefefe; + + // AKF config + *(volatile uint32_t *)0x46901020 = 0x46030020; + *(volatile uint32_t *)0x46902020 = 0xfefefefe; + *(volatile uint32_t *)0x46901024 = 0x46030024; + *(volatile uint32_t *)0x46902024 = 0xfefefefe; + + // Setup and enable Reconfig + *(volatile uint32_t *)0x46900004 = (2<<16); + *(volatile uint32_t *)0x46900010 = (2<<16 | 0x4); + *(volatile uint32_t *)0x4690001C = (2<<16 | 0x8); + *(volatile uint32_t *)0x46900000 |= 1<<16; + + // Unmask wakeup sources + *(volatile uint32_t *)0x46706000 = 0xffffffff; + *(volatile uint32_t *)0x46707000 = 0; + *(volatile uint32_t *)0x46707004 = 0x8; + *(volatile uint32_t *)0x46707010 = 0x1; + + // // Confirm debugger is not preventing power down + // dprintf(DEBUG_INFO, "Confirming CSYSWRUP: %08x\n", *(volatile uint32_t *)0x46eb1030); + // ASSERT(*(volatile uint32_t *)0x46eb1030 == 0); + // + // Capture current time (SCM system time) + time_t current_time = *(volatile uint32_t *)0x46705208; + dprintf(DEBUG_INFO, "starting to STR. time %ld..\n", current_time); + current_time = *(volatile uint32_t *)0x46705208; + + // Program wake up time + *(volatile uint32_t *)0x46705210 = (current_time + 0x10000); + *(volatile uint32_t *)0x46705214 = 0x80000000; + + dprintf(DEBUG_INFO, "into STR\n"); + + // Enable STR sequence + *(volatile uint32_t *)0x46c27308 = 1; + + while(1); +} + +MENU_COMMAND_DEBUG(m7_str, do_m7_str_test, "M7 Suspend to RAM test", NULL); + + +static int do_m7_str_dram_test(int argc, struct cmd_arg *args) __noreturn; + +static int do_m7_str_dram_test(int argc, struct cmd_arg *args) +{ + dprintf(DEBUG_INFO, "starting M7 STR DRAM test...\n"); + + platform_bootprep_darwin(); + +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + + /* make sure timers and whatnot aren't running */ + platform_quiesce_hardware(BOOT_IBOOT); + + // Turn following PS off + *(volatile uint32_t *)0x46c20088 = 0; + *(volatile uint32_t *)0x46c20068 = 0; + *(volatile uint32_t *)0x46c20060 = 0; + *(volatile uint32_t *)0x46c20070 = 0; + *(volatile uint32_t *)0x46c20080 = 0; + *(volatile uint32_t *)0x46c20120 = 0; + *(volatile uint32_t *)0x46c20128 = 0; + *(volatile uint32_t *)0x46c20130 = 0; + *(volatile uint32_t *)0x46c20138 = 0; + *(volatile uint32_t *)0x46c20090 = 0; + *(volatile uint32_t *)0x46c200c8 = 0; + *(volatile uint32_t *)0x46c200d0 = 0; + + // Enable auto power gating for MCU, AMP, PIOSYS, LIO + *(volatile uint32_t *)0x46c20048 |= (1 << 28); + *(volatile uint32_t *)0x46c20050 |= (1 << 28); + *(volatile uint32_t *)0x46c20058 |= (1 << 28); + *(volatile uint32_t *)0x46c20098 |= (1 << 28); + + // Enable power gating for AMCPIO domain + *(volatile uint32_t *)0x46c22010 |= (1 << 31); + + *(volatile uint32_t *)0x46c22080 |= (1 << 31); + *(volatile uint32_t *)0x46c22050 |= (1 << 31); + *(volatile uint32_t *)0x46c22090 |= (1 << 31); + *(volatile uint32_t *)0x46c22000 |= (1 << 31); + + + // Program perf-state table + *(volatile uint32_t *)0x46c1a010 = (0<<8)|(1<<7)|(3<<4); + *(volatile uint32_t *)0x46c1a020 = (3<<8)|(0<<7)|(0<<4); + *(volatile uint32_t *)0x46c1a030 = (3<<8)|(0<<7)|(0<<4); + *(volatile uint32_t *)0x46c1a000 = 0x7; // enable all perf states + + // Enable global ACG + *(volatile uint32_t *)0x46c32000 = 1; + + // timeout in Reconfig + // *(volatile uint32_t *)0x46900014 = 0x186A0 | (1<<24); + // *(volatile uint32_t *)0x46900008 = 0x186A0 | (1<<24); + + // Unmask wakeup sources + *(volatile uint32_t *)0x46706000 = 0xffffffff; + *(volatile uint32_t *)0x46707000 = 0; + *(volatile uint32_t *)0x46707004 = 0x8; + *(volatile uint32_t *)0x46707010 = 0x1; + + // // Confirm debugger is not preventing power down + // dprintf(DEBUG_INFO, "Confirming CSYSWRUP: %08x\n", *(volatile uint32_t *)0x46eb1030); + // ASSERT(*(volatile uint32_t *)0x46eb1030 == 0); + + // Capture current time (SCM system time) + time_t current_time = *(volatile uint32_t *)0x46705208; + dprintf(DEBUG_INFO, "starting to STR. time %ld..\n", current_time); + current_time = *(volatile uint32_t *)0x46705208; + + // Program wake up time + *(volatile uint32_t *)0x46705210 = (current_time + 0x10000); + *(volatile uint32_t *)0x46705214 = 0x80000000; + + dprintf(DEBUG_INFO, "into STR\n"); + + // Enable STR sequence + *(volatile uint32_t *)0x46c27304 = 0x5DC0; // 1ms + *(volatile uint32_t *)0x46c27308 = 1; + + while(1); +} + +MENU_COMMAND_DEBUG(m7_str_dram, do_m7_str_dram_test, "M7 Suspend to RAM DRAM test", NULL); + +#endif diff --git a/platform/s7002/miu/miu.c b/platform/s7002/miu/miu.c new file mode 100644 index 0000000..55395f9 --- /dev/null +++ b/platform/s7002/miu/miu.c @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (APPLICATION_IBOOT) + +static void miu_configure_bridge(const u_int32_t *bridge_settings); + +#define STATIC_BRIDGE_SHIFT (28) +#define STATIC_BRIDGE_OFFSET_MASK ((1 << STATIC_BRIDGE_SHIFT) - 1) + +#define PMGR_REGISTERS (0 << STATIC_BRIDGE_SHIFT) +#define CPU_FABRIC_WIDGETS (1 << STATIC_BRIDGE_SHIFT) +#define NRT_FABRIC_WIDGETS (2 << STATIC_BRIDGE_SHIFT) + +static const u_int32_t bridge_registers[] = { + PMGR_BASE_ADDR, + CPU_FABRIC_BASE_ADDR, + NRT_FABRIC_BASE_ADDR, +}; + +// This array is composed of 3-item tuples consisting of: +// Bridge id | register offset (with optional | RECONFIG_RAM_CMD_READ) +// Register data value or comparison value if RECONFIG_RAM_CMD_READ is specified +// Mask value if RECONFIG_RAM_CMD_READ is specified (used only by reconfig engine) +static const u_int32_t bridge_settings_static[] = { + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AMCRDRATELIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AMCWRALIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AMCRTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AMCWTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_SPURDRATELIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_SPUWRALIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_SPURTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_SPUWTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_SPUWGATHER, (0x01 << 8), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_LIOWGATHER, (0x01 << 8), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AUERDRATELIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AUEWRALIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AUERTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AUEWTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AUEWGATHER, (0x01 << 8), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_ANSRDRATELIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_ANSWRALIMIT, 0, 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_ANSRTRLIMIT, (0x08 << 8) | (0x08 << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_ANSWTRLIMIT, (0x05 << 8) | (0x05 << 0), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_ANSWGATHER, (0x01 << 8), 0, + CPU_FABRIC_WIDGETS | CPU_Fabric_pl301Wrap0_AXI0_ARCHANARBMI0, 0, 0, + + // Turn on the clock that controls the NRT Fabric widgets. The MSR clock + // is behind the Media clock so we turn it on to keep the Media clock + // from gating. + PMGR_REGISTERS | PMGR_MSR_PS, (0x1 << 8) | (0x1 << 9) | (0xf << 0), 0, + PMGR_REGISTERS | PMGR_MEDIA_CLK_CFG, 0x80100000, 0, + PMGR_REGISTERS | PMGR_MEDIA_CLK_CFG | RECONFIG_RAM_CMD_READ,0, 0x40000000, + + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_AMCRDRATELIMIT, 0, 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_AMCWRALIMIT, 0, 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_AMCRTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_AMCWTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_MSRRDRATELIMIT, 0, 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_MSRWRALIMIT, 0, 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_MSRRTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_MSRWTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_SDIORDRATELIMIT, 0, 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_SDIOWRALIMIT, 0, 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_SDIORTRLIMIT, (0x3f << 8) | (0x3f << 0), 0, + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_SDIOWTRLIMIT, (0x04 << 8) | (0x04 << 0), 0, + // Need a read to make sure writes are pushed out to the fabric + // before the following steps are executed. + NRT_FABRIC_WIDGETS | NRT_Fabric_pl301Wrap1_SDIOWTRLIMIT | RECONFIG_RAM_CMD_READ, (0x04 << 8) | (0x04 << 0), (0xf << 8) | (0xf << 0), + + // Reprogram the clock configuration to its expected value. + // NOTE: We can't write PMGR_MSR_PS back to its original value here. + // Attempting to do so will result in a hang. + PMGR_REGISTERS | PMGR_MEDIA_CLK_CFG, 0x83100000, 0, + PMGR_REGISTERS | PMGR_MEDIA_CLK_CFG | RECONFIG_RAM_CMD_READ,0, 0x40000000, +}; + +#endif // APPLICATION_IBOOT + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + miu_configure_bridge(bridge_settings_static); +#endif + + return 0; +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT && WITH_HW_AMC + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rPIO_REMAP_CTL = (rPIO_REMAP_CTL & ~1) | (1 << 0); // Resources mapped to address 0x0 are now remapped SPU_SRAM + break; + + case REMAP_SDRAM: + rFABRIC_REMAP_REG = (rFABRIC_REMAP_REG & ~1) | (1 << 0); // 0x0000_0000 to 0x0010_0000 is mapped to DRAM + break; + + // reset back to default behavior + default: + rPIO_REMAP_CTL = 0; + rFABRIC_REMAP_REG = 0; + break; + } +} + +void miu_bypass_prep(void) +{ +} + +#if (APPLICATION_IBOOT && (PRODUCT_IBSS || PRODUCT_LLB)) +static void miu_configure_bridge(const u_int32_t *bridge_settings) +{ + volatile u_int32_t *reg; + u_int32_t bridge, offset, data, mask; + u_int32_t i; + + for (i = 0; i < ARRAY_SIZE(bridge_settings_static); i += 3) { + bridge = bridge_settings[i] >> STATIC_BRIDGE_SHIFT; + offset = bridge_settings[i] & STATIC_BRIDGE_OFFSET_MASK & ~RECONFIG_RAM_CMD_READ; + data = bridge_settings[i + 1]; + reg = (volatile u_int32_t *)(bridge_registers[bridge] + offset); + if (bridge_settings[i] & RECONFIG_RAM_CMD_READ) { + mask = bridge_settings_static[i + 2]; + SPIN_W_TMO_UNTIL((*reg & mask) == data); + } else { + *reg = data; + } + } +} +#endif // (APPLICATION_IBOOT && (PRODUCT_IBSS || PRODUCT_LLB)) + +#if APPLICATION_IBOOT +void miu_configure_bridge_soc_reconfig_ram(void) +{ + addr_t reg; + u_int32_t bridge, offset, data, mask; + u_int32_t i; + + for (i = 0; i < ARRAY_SIZE(bridge_settings_static); i += 3) { + bridge = bridge_settings_static[i] >> STATIC_BRIDGE_SHIFT; + offset = bridge_settings_static[i] & STATIC_BRIDGE_OFFSET_MASK; + data = bridge_settings_static[i + 1]; + mask = bridge_settings_static[i + 2]; + reg = (addr_t)(bridge_registers[bridge] + offset); + reconfig_append_command(RECONFIG_TYPE_SOC, reg, data, mask); + } +} +#endif // APPLICATION_IBOOT + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ + // Nothing to do here +} + +#endif diff --git a/platform/s7002/miu/rules.mk b/platform/s7002/miu/rules.mk new file mode 100644 index 0000000..77b88cb --- /dev/null +++ b/platform/s7002/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s7002/pmgr/pmgr.c b/platform/s7002/pmgr/pmgr.c new file mode 100644 index 0000000..2fe0bd8 --- /dev/null +++ b/platform/s7002/pmgr/pmgr.c @@ -0,0 +1,1173 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PLL_VCO_TARGET(pllx) ((2ULL * (pllx##_O) * (pllx##_M)) / (pllx##_P)) +#define PLL_FREQ_TARGET(pllx) (((pllx##_O) * (pllx##_M)) / (pllx##_P) / ((pllx##_S) + 1)) + +struct clock_source { + uint32_t src_clk; + uint32_t factor; +}; + +struct clock_config { + volatile uint32_t *clock_reg; // CLK_CFG Register + struct clock_source sources[8]; // List of sources +}; + +/* ******************************************************************************** */ +#if APPLICATION_IBOOT + +/* PLL0 @532.8MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 5 +#define PLL0_M 111 +#define PLL0_S 0 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80100000, // gpio on 24MHz + 0x83100000, // mcu on 533MHz, mcu_cfg_sel 0 (highest freq) + 0x81100000, // mcu_fixed on 533MHz + 0x84100000, // gfx on 133.25MHz + 0x83100000, // mipi_dsi on 533MHz + 0x83100000, // vid on 22.21MHz + 0x83100000, // media on 133.25MHz + 0x83100000, // disp on 106.6MHz + 0x84100000, // sdio on 88.8MHz + 0x83100000, // ans on 106.6MHz + 0x83100000, // pio on 106.6MHz + 0x83100000, // lio on 106.6MHz + 0x83100000, // aue on 106.6MHz + 0x83100000, // usb on 53.3MHz + 0x83100000, // spi0 on 53.3MHz + 0x83100000, // spi1 on 53.3MHz + 0x83100000, // nco_ref0 on 266.5MHz + 0x83100000, // nco_ref1 on 266.5MHz + 0x80100000, // nco_alg0 on 24MHz + 0x80100000, // nco_alg1 on 24MHz + 0x83100000, // mca0_m on nco_ref0 + 0x84100000 // mca1_m on nco_ref1 +}; + +static const uint32_t spare_divs_active[PMGR_SPARE_CLK_CFG_COUNT] = { + 0x00000000, // s0 off + 0x00000000 // s1 off +}; + +#endif /* APPLICATION_IBOOT */ +/* ******************************************************************************** */ +#if APPLICATION_SECUREROM + +/* PLL0 @266.4MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 10 +#define PLL0_M 111 +#define PLL0_S 0 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +// We won't touch the clk gen's that aren't necessary during SecureROM. +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80100000, // gpio on 24MHz + 0x83100000, // mcu on 266.4MHz, mcu_cfg_sel 0 (highest freq) + 0x81100000, // mcu_fixed on 266.4MHz + 0x80100000, // gfx on 24MHz + 0x80100000, // mipi_dsi on 24MHz + 0x80100000, // vid on 24MHz + 0x80100000, // media on 24MHz + 0x80100000, // disp on 24MHz + 0x80100000, // sdio on 24MHz + 0x83100000, // ans on 53.3MHz + 0x83100000, // pio on 53.3MHz + 0x80100000, // lio on 24MHz + 0x80100000, // aue on 24MHz + 0x84100000, // usb on 53.3MHz + 0x80100000, // spi0 on 24MHz + 0x80100000, // spi1 on 24MHz + 0x80100000, // nco_ref0 on 24MHz + 0x80100000, // nco_ref1 on 24MHz + 0x80100000, // nco_alg0 on 24MHz + 0x80100000, // nco_alg1 on 24MHz + 0x80100000, // mca0_m on 24MHz + 0x80100000 // mca1_m on 24MHz +}; + +static const uint32_t spare_divs_active[PMGR_SPARE_CLK_CFG_COUNT] = { + 0x80000001, // s0 on 266.4MHz + 0x80000001 // s1 on 266.4MHz +}; + +#endif /* APPLICATION_SECUREROM */ +/* ******************************************************************************** */ +#define CLOCK_SOURCES_MAX 8 + +static const struct clock_config clk_configs[PMGR_CLK_COUNT] = { + [PMGR_CLK_GPIO] = { + &rPMGR_GPIO_CLK_CFG, + { + {PMGR_CLK_OSC, 1} + } + }, + + [PMGR_CLK_MCU] = { + &rPMGR_MCU_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 1}, + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 3}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 5}, + } + }, + + [PMGR_CLK_MCU_FIXED] = { + &rPMGR_MCU_FIXED_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_PLL0, 1}, + } + }, + + [PMGR_CLK_GFX] = { + &rPMGR_GFX_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 3}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + } + }, + + [PMGR_CLK_MIPI_DSI] = { + &rPMGR_MIPI_DSI_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 1}, + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + } + }, + + [PMGR_CLK_VID] = { + &rPMGR_VID_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 24}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 3}, + {PMGR_CLK_OSC, 4}, + } + }, + + [PMGR_CLK_MEDIA] = { + &rPMGR_MEDIA_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + } + }, + + [PMGR_CLK_DISP] = { + &rPMGR_DISP_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + } + }, + + [PMGR_CLK_SDIO] = { + &rPMGR_SDIO_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + } + }, + + [PMGR_CLK_ANS] = { + &rPMGR_ANS_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + } + }, + + [PMGR_CLK_PIO] = { + &rPMGR_PIO_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_OSC, 4}, + } + }, + + [PMGR_CLK_LIO] = { + &rPMGR_LIO_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_OSC, 4}, + } + }, + + [PMGR_CLK_AUE] = { + &rPMGR_AUE_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 5}, + {PMGR_CLK_PLL0, 4}, + } + }, + + [PMGR_CLK_USB] = { + &rPMGR_USB_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 5}, + } + }, + + [PMGR_CLK_SPI0_N] = { + &rPMGR_SPI0_N_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 20}, + } + }, + + [PMGR_CLK_SPI1_N] = { + &rPMGR_SPI1_N_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 20}, + } + }, + + [PMGR_CLK_NCO_REF0] = { + &rPMGR_NCO_REF0_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 4}, + } + }, + + [PMGR_CLK_NCO_REF1] = { + &rPMGR_NCO_REF1_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 4}, + } + }, + + [PMGR_CLK_NCO_ALG0] = { + &rPMGR_NCO_ALG0_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 10}, + } + }, + + [PMGR_CLK_NCO_ALG1] = { + &rPMGR_NCO_ALG1_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 10}, + } + }, + + [PMGR_CLK_MCA0_M] = { + &rPMGR_MCA0_M_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4}, + } + }, + + [PMGR_CLK_MCA1_M] = { + &rPMGR_MCA1_M_CLK_CFG, + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_NOT_SUPPORTED, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4}, + } + }, + + [PMGR_CLK_S0] = { + &rPMGR_S0_CLK_CFG, + { + {PMGR_CLK_PLL0, 1}, + } + }, + + [PMGR_CLK_S1] = { + &rPMGR_S1_CLK_CFG, + { + {PMGR_CLK_PLL0, 1}, } + }, + +}; + +/* ******************************************************************************** */ + +static void set_pll(uint32_t p, uint32_t m, uint32_t s); +static uint32_t get_pll_frequency(); +static uint32_t get_spare_frequency(uint32_t cnt); + +static void clocks_get_frequencies(void); +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk); +static void clocks_quiesce_internal(void); + +static void apply_pmgr_tunables(); + +static void update_memory_clk_config(uint32_t performance_level); + +// current clock frequencies +static uint32_t clks[PMGR_CLK_COUNT + 1]; + +/* ******************************************************************************** */ + +static void set_pll(uint32_t p, uint32_t m, uint32_t s) +{ + rPMGR_PLL0_CTL = (PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s) | PMGR_PLL_LOAD); + while ((rPMGR_PLL0_CTL & PMGR_PLL_PENDING) == 1); + + rPMGR_PLL0_EXT_BYPASS_CFG &= ~PMGR_PLL_EXT_BYPASS; + while ((rPMGR_PLL0_EXT_BYPASS_CFG & PMGR_PLL_BYP_ENABLED) != 0); + + rPMGR_PLL0_CTL |= PMGR_PLL_ENABLE; + while ((rPMGR_PLL0_CTL & PMGR_PLL_PENDING) == 1); +} + +static uint32_t get_pll_frequency() +{ + uint32_t pllctl, bypcfg; + uint64_t freq = 0; + + pllctl = rPMGR_PLL0_CTL; + bypcfg = rPMGR_PLL0_EXT_BYPASS_CFG; + + // If PLL is not enabled, check for External Bypass + if ((pllctl & PMGR_PLL_ENABLE) == 0) { + if ((bypcfg & PMGR_PLL_EXT_BYPASS) == 0) + return 0; + else + return OSC_FREQ; + } + + freq = OSC_FREQ; + freq *= ((pllctl >> PMGR_PLL_M_SHIFT) & PMGR_PLL_M_MASK); + freq /= ((pllctl >> PMGR_PLL_P_SHIFT) & PMGR_PLL_P_MASK); + freq /= (1 + ((pllctl >> PMGR_PLL_S_SHIFT) & PMGR_PLL_S_MASK)); + +#if DEBUG_BUILD + if (freq> 0xFFFFFFFF) + panic("Frequency value does not fit in uint32_t"); +#endif + + return (uint32_t)freq; +} + +static uint32_t get_spare_frequency(uint32_t spare) +{ + uint32_t reg_val, src_idx, src_clk, src_factor, div; + volatile uint32_t *spare_clkcfg = clk_configs[PMGR_CLK_S0 + spare].clock_reg; + + reg_val = *spare_clkcfg; + + div = reg_val & 0x3F; + + if (((reg_val & PMGR_CLK_CFG_ENABLE) == 0) || div == 0) + return 0; + + src_idx = 0; // Source index is always 0 because only spare source is PLL0 + src_clk = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].src_clk; + src_factor = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].factor; + + return (clks[src_clk] / src_factor) / div; +} + +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk) +{ + volatile uint32_t *reg; + uint32_t cnt, val, src_idx, src_clk, src_factor; + + if (start_clk < PMGR_CLK_GPIO || end_clk > PMGR_CLK_MCA1_M) + return; + + for (cnt = start_clk; cnt <= end_clk; cnt++) { + reg = clk_configs[cnt].clock_reg; + val = *reg; + + if ((val & PMGR_CLK_CFG_ENABLE) == 0) { + clks[cnt] = 0; + continue; + } + + src_idx = (val >> 24) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[cnt].sources[src_idx].src_clk; + src_factor = clk_configs[cnt].sources[src_idx].factor; + clks[cnt] = clks[src_clk] / src_factor; + } +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + { + clks[cnt] = freq; + } + + clks[PMGR_CLK_MCU] = 10000000; + clks[PMGR_CLK_MCU_FIXED]= 10000000; + clks[PMGR_CLK_USB] = 12000000; + +#elif CONFIG_SIM + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + +#else + uint32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Use get_pll_frerquency() to establish the frequency (unconfigured PLLs will bypass OSC) + clks[PMGR_CLK_PLL0] = get_pll_frequency(); + + // Use get_spare_frequencies() to establish the frequencies for spare clocks (unconfigured will be skipped) + for (cnt = 0; cnt < PMGR_SPARE_CLK_CFG_COUNT; cnt++) + { + clks[PMGR_CLK_S0 + cnt] = get_spare_frequency(cnt); + } + + clocks_get_frequencies_range(PMGR_CLK_GPIO, PMGR_CLK_MCA1_M); +#endif +} + +int clocks_init(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) + clocks_get_frequencies(); +#endif /* (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) */ + return 0; +} + +static bool clk_mipi_req_on = false; +static bool clk_disp0_req_on = false; + +void clock_gate(int device, bool enable) +{ + + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device); + + // Make sure we are within limits + if (reg > PMGR_LAST_PS) + return; + + // Workaround for / + // Keep track of the pending requests for CLK_DISP0 and CLK_MIPI_DSI + switch(device) + { + case CLK_DISP0: + clk_disp0_req_on = enable; + break; + case CLK_MIPI_DSI: + clk_mipi_req_on = enable; + break; + } + + if (!enable && ((device == CLK_DISP0) || (device == CLK_MIPI_DSI))) + { + // Workaround for + // if requesting DISP0 or MIPI off, make sure both are requested off before effecting the change. + if (clk_disp0_req_on || clk_mipi_req_on) + return; + + // Otherwise clock_gate the other one before clock gating this one. + int device2 = (device == CLK_DISP0) ? CLK_MIPI_DSI : CLK_DISP0; + volatile uint32_t *reg2 = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device2); + *reg2 &= ~PMGR_PS_RUN_MAX; + while ((*reg2 & PMGR_PS_MANUAL_PS_MASK) != ((*reg2 >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); + } + // Set the PS field to the requested level + if (enable) + *reg |= PMGR_PS_RUN_MAX; + else + *reg &= ~PMGR_PS_RUN_MAX; // i.e. set PMGR_PS_POWER_OFF + + // Wait for the MANUAL_PS and ACTUAL_PS fields to be equal + while ((*reg & PMGR_PS_MANUAL_PS_MASK) != ((*reg >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); + + // Workaround for + // If device == MIPI_DSI | DISP, turn the enable the other one as well + if (enable && ((device == CLK_DISP0) || (device == CLK_MIPI_DSI))) + { + int device2 = (device == CLK_DISP0) ? CLK_MIPI_DSI : CLK_DISP0; + volatile uint32_t *reg2 = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device2); + *reg2 |= PMGR_PS_RUN_MAX; + while ((*reg2 & PMGR_PS_MANUAL_PS_MASK) != ((*reg2 >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); + } +} + +static void restore_clock_config_reset_state() +{ + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + uint32_t reg; + + // 2. Write reset value to ACG, CLK_DIVIDER_ACG_CFG, CLK_DIVIDER_ACG_CFG1, and PLL_ACG_CFG + rPMGR_MISC_ACG = 0; + rPMGR_CLK_DIVIDER_ACG_CFG = 0; + rPMGR_CLK_POWER_CONFIG = 0; + + // 5. Write reset value for all mux clock configs (excluding spares, mcu, mcu_fixed) + reg = PMGR_CLK_NUM(GPIO); + while (reg <= PMGR_CLK_NUM(MCA1_M)) { + if ((reg == PMGR_CLK_NUM(MCU)) || (reg == PMGR_CLK_NUM(MCU_FIXED))) goto skip; + clkcfgs[reg] = 0x80100000; + while (clkcfgs[reg] & PMGR_CLK_CFG_PENDING); +skip: + reg++; + } + + // 6. Write to MCU and MCU_FIXED to allow memory to run at 24MHz + update_memory_clk_config(kPerformanceMemoryLow); + + // 7. Write PLL0_EXT_BYPASS_CFG.EXT_BYPASS to 1 + rPMGR_PLL0_EXT_BYPASS_CFG |= PMGR_PLL_EXT_BYPASS; + while ((rPMGR_PLL0_EXT_BYPASS_CFG & PMGR_PLL_BYP_ENABLED) == 0); + + // 8. Write reset value to PLL0_CTL + rPMGR_PLL0_CTL = 0x00001010; + + // 10. Write reset value spares + reg = PMGR_SPARE_CLK_NUM(S0); + while (reg <= PMGR_SPARE_CLK_NUM(S1)) { + clkcfgs[reg] = 0x80000001; + while (clkcfgs[reg] & PMGR_CLK_CFG_PENDING); + reg++; + } +} + +static void clocks_quiesce_internal(void) +{ + //clock_gate(PMGR_CPU, 1); + clock_gate(CLK_AIC, 1); + clock_gate(CLK_LIO, 1); + clock_gate(CLK_GPIO, 1); + clock_gate(CLK_MCU, 1); + clock_gate(CLK_AMP, 1); + clock_gate(CLK_PIOSYS, 1); + clock_gate(CLK_SPU, 1); + clock_gate(CLK_SPU_SGPIO, 1); + clock_gate(CLK_AUE, 1); + clock_gate(CLK_USB_M7, 1); + clock_gate(CLK_AES0, 1); + clock_gate(CLK_DOCKFIFO, 1); + clock_gate(CLK_ANS, 1); + + // DEBUG_PS lives in SPU, enable it as well + rSPU_PMGR_DEBUG_PS |= PMGR_PS_RUN_MAX; + while ((rSPU_PMGR_DEBUG_PS & PMGR_PS_MANUAL_PS_MASK) != ((rSPU_PMGR_DEBUG_PS >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); + + clock_gate(CLK_SPU_AKF, 0); + // SPU_SMB_PS needs to be clocked on in iBoot and/or not touched by iOS sleep/wake + // SPU_*_PS should be on by default, without them in EDT the OS should then leave them alone. + clock_gate(CLK_SPU_UART0, 1); + clock_gate(CLK_SPU_UART1, 1); + clock_gate(CLK_SPU_SMB, 1); + + clock_gate(CLK_DISP0, 0); + clock_gate(CLK_MIPI_DSI, 0); + clock_gate(CLK_MSR, 0); + clock_gate(CLK_GFX, 0); + clock_gate(CLK_SDIO, 0); + clock_gate(CLK_MCA0, 0); + clock_gate(CLK_MCA1, 0); + clock_gate(CLK_SPI0, 0); + clock_gate(CLK_SPI1, 0); + clock_gate(CLK_DMATX, 0); + clock_gate(CLK_DMARX, 0); + clock_gate(CLK_UART0, 0); + clock_gate(CLK_UART1, 0); + clock_gate(CLK_UART2, 0); + clock_gate(CLK_UART3, 0); + clock_gate(CLK_UART4, 0); + clock_gate(CLK_I2C0, 0); + clock_gate(CLK_I2C1, 0); + clock_gate(CLK_PWM0, 0); + + clock_gate(CLK_ETH, 0); + clock_gate(CLK_VDEC, 0); + + restore_clock_config_reset_state(); +} + +static void apply_pmgr_tunables() +{ +#define CLAMP_TIME_MASK (((1 << 8) - 1) << 8) +#define CLK_EN_TIME_MASK (((1 << 8) - 1) << 16) +#define SRAM_PG_EN_TIME_MASK (((1 << 3) - 1) << 24) +#define SRAM_PG_DIS_TIME_MASK (((1 << 3) - 1) << 27) +#define _PWRGATE_CFG0(rCFG0, CLAMP_TIME, CLK_EN_TIME, SRAM_PG_EN_TIME, SRAM_PG_DIS_TIME) \ + regTemp = rCFG0; \ + regTemp &= ~CLAMP_TIME_MASK; \ + regTemp |= (CLAMP_TIME << 8); \ + regTemp &= ~CLK_EN_TIME_MASK; \ + regTemp |= (CLK_EN_TIME << 16); \ + regTemp &= ~SRAM_PG_EN_TIME_MASK; \ + regTemp |= (SRAM_PG_EN_TIME << 24); \ + regTemp &= ~SRAM_PG_DIS_TIME_MASK; \ + regTemp |= (SRAM_PG_DIS_TIME << 27); \ + rCFG0 = regTemp; + +#define RAMP_PRE_TIME_MASK (((1 << 12) - 1) << 0) +#define RAMP_ALL_TIME_MASK (((1 << 12) - 1) << 16) +#define _PWRGATE_CFG1(rCFG1, RAMP_PRE_TIME, RAMP_ALL_TIME) \ + regTemp = rCFG1; \ + regTemp &= ~RAMP_PRE_TIME_MASK; \ + regTemp |= (RAMP_PRE_TIME << 0); \ + regTemp &= ~RAMP_ALL_TIME_MASK; \ + regTemp |= (RAMP_ALL_TIME << 16); \ + rCFG1 = regTemp; + +#define RESET_DOWN_TIME_MASK (0xFF << 0) +#define RESET_UP_TIME_MASK (0xFF << 8) +#define RESET_OFF_TIME_MASK (0xFF << 16) +#define _PWRGATE_CFG2(rCFG2, RESET_DOWN_TIME, RESET_UP_TIME, RESET_OFF_TIME) \ + regTemp = rCFG2; \ + regTemp &= ~RESET_DOWN_TIME_MASK; \ + regTemp |= (RESET_DOWN_TIME << 0); \ + regTemp &= ~RESET_UP_TIME_MASK; \ + regTemp |= (RESET_UP_TIME << 8); \ + regTemp &= ~RESET_OFF_TIME_MASK; \ + regTemp |= (RESET_OFF_TIME << 16); \ + rCFG2 = regTemp; + + uint32_t regTemp; + + _PWRGATE_CFG0(rPMGR_PWR_CPU_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_CPU_CFG1, 0x4, 0x6b); + _PWRGATE_CFG2(rPMGR_PWR_CPU_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_AMCPIO_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_AMCPIO_CFG1, 0x0, 0x1); + _PWRGATE_CFG2(rPMGR_PWR_AMCPIO_CFG2, 0x28, 0x28, 0x28); + + _PWRGATE_CFG0(rPMGR_PWR_DISP_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_DISP_CFG1, 0x5, 0x66); + _PWRGATE_CFG2(rPMGR_PWR_DISP_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_DISP_BE_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_DISP_BE_CFG1, 0x1, 0x1b); + _PWRGATE_CFG2(rPMGR_PWR_DISP_BE_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_MSR_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_MSR_CFG1, 0x3, 0x3a); + _PWRGATE_CFG2(rPMGR_PWR_MSR_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_ANS_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_ANS_CFG1, 0x2, 0x78); + _PWRGATE_CFG2(rPMGR_PWR_ANS_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_GFX_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_GFX_CFG1, 0x3, 0x49); + _PWRGATE_CFG2(rPMGR_PWR_GFX_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_SDIO_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_SDIO_CFG1, 0x2, 0x3a); + _PWRGATE_CFG2(rPMGR_PWR_SDIO_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_LIO_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_LIO_CFG1, 0x1, 0x31); + _PWRGATE_CFG2(rPMGR_PWR_LIO_CFG2, 0x8, 0xc, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_AUE_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_AUE_CFG1, 0x1, 0x1f); + _PWRGATE_CFG2(rPMGR_PWR_AUE_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWR_VDEC_CFG0, 0x3, 0x4, 0x4, 0x4); + _PWRGATE_CFG1(rPMGR_PWR_VDEC_CFG1, 0x3, 0x30); + _PWRGATE_CFG2(rPMGR_PWR_VDEC_CFG2, 0x8, 0x8, 0x8); + + rPMGR_MCU_ASYNC_RESET = (0x1 << 28) | (0x1 << 24) | (0x1 << 20) | (0x1 << 16) | (0x1 << 8) | (0x1 << 4) | (0x1 << 0); + + rPMGR_MISC_GFX_CTL = (0x1 << 0); +} + +static void update_memory_clk_config(uint32_t performance_level) +{ + int32_t cfg_sel = -1; + uint32_t src_index; + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + uint32_t mcu_clk_cfg_reg, mcu_fixed_clk_cfg_reg; + uint8_t current_mcu_fixed_clk; + + switch(performance_level) { + case kPerformanceMemoryLow: + cfg_sel = 3; + break; + + case kPerformanceMemoryFull: + cfg_sel = 0; + break; + } + + if (cfg_sel == -1) + panic("pmgr:cfg_sel not set correctly for configuring amc clock"); + + src_index = (performance_level == kPerformanceMemoryLow) ? 0 : 3; + + mcu_clk_cfg_reg = clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)]; + mcu_fixed_clk_cfg_reg = clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU_FIXED)]; + + mcu_clk_cfg_reg &= ~(0x7 << PMGR_CLK_CFG_SRC_SEL_SHIFT); + mcu_clk_cfg_reg &= ~(0x3 << PMGR_CLK_CFG_CFG_SEL_SHIFT); + mcu_clk_cfg_reg |= ((src_index & 0x7) << PMGR_CLK_CFG_SRC_SEL_SHIFT); + mcu_clk_cfg_reg |= ((cfg_sel & 0x3) << PMGR_CLK_CFG_CFG_SEL_SHIFT); + + current_mcu_fixed_clk = (mcu_fixed_clk_cfg_reg >> PMGR_CLK_CFG_SRC_SEL_SHIFT) & 0x1; + + mcu_fixed_clk_cfg_reg &= ~(1 << PMGR_CLK_CFG_SRC_SEL_SHIFT); + mcu_fixed_clk_cfg_reg |= ((src_index & 0x1) << PMGR_CLK_CFG_SRC_SEL_SHIFT); + + if (current_mcu_fixed_clk == 0) { + clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU_FIXED)] = mcu_fixed_clk_cfg_reg; + while ((clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU_FIXED)] >> PMGR_CLK_CFG_PENDING_SHIFT) & 0x1); + clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)] = mcu_clk_cfg_reg; + while ((clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)] >> PMGR_CLK_CFG_PENDING_SHIFT) & 0x1); + } + else { + clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)] = mcu_clk_cfg_reg; + while ((clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU)] >> PMGR_CLK_CFG_PENDING_SHIFT) & 0x1); + clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU_FIXED)] = mcu_fixed_clk_cfg_reg; + while ((clkcfgs[PMGR_CLK_CFG_INDEX(PMGR_CLK_MCU_FIXED)] >> PMGR_CLK_CFG_PENDING_SHIFT) & 0x1); + } +} + +static void set_nco_clocks(void) +{ + // Enable this NCO with alg_ref0_clk and nco_ref0_clk. + rPMGR_NCO_CLK_CFG(0) |= (1 << 31); + rPMGR_NCO_CLK_CFG(1) |= (1 << 31); +} + +/* + * clocks_set_default - called by SecureROM, LLB, iBSS main via + * platform_init_setup_clocks, so the current state of the chip is + * either POR, or whatever 'quiesce' did when leaving SecureROM. + */ +int clocks_set_default(void) +{ + uint32_t cnt; + volatile uint32_t *spare_clkcfgs = PMGR_FIRST_SPARE_CLK_CFG; + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Change all clocks to something safe + clocks_quiesce_internal(); + +#ifdef PLL0_T + set_pll(PLL0_P, PLL0_M, PLL0_S); +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Turn on NCO clocks before enabling MCA clocks. + set_nco_clocks(); +#endif + + // Set all spare clock divs to their active values + for (cnt = 0; cnt < PMGR_SPARE_CLK_CFG_COUNT; cnt++) { + spare_clkcfgs[cnt] = spare_divs_active[cnt]; + while ((spare_clkcfgs[cnt] & PMGR_CLK_CFG_PENDING) != 0); + } + + // Set all but the spare clock divs to their active values + for (cnt = 0; cnt < PMGR_CLK_CFG_COUNT; cnt++) { + clkcfgs[cnt] = clk_divs_active[cnt]; + while ((clkcfgs[cnt] & PMGR_CLK_CFG_PENDING) != 0); + } + + clocks_get_frequencies(); + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + apply_pmgr_tunables(); +#endif + return 0; +} + +void clocks_quiesce(void) +{ + clocks_quiesce_internal(); +} + +uint32_t clocks_set_performance(uint32_t performance_level) +{ +#if APPLICATION_IBOOT + if (performance_level == kPerformanceMemoryLow || performance_level == kPerformanceMemoryFull) { + update_memory_clk_config(performance_level); + clocks_get_frequencies_range(PMGR_CLK_MCU_FIXED, PMGR_CLK_MCU); + } +#endif + + return kPerformanceHigh; +} + +void clock_get_frequencies(uint32_t *clocks, uint32_t count) +{ + uint32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) cnt = count; + + memcpy(clocks, clks, cnt * sizeof(uint32_t)); +} + +uint32_t clock_get_frequency(int clock) +{ + uint32_t freq = OSC_FREQ; + + switch (clock) { + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + freq = clks[PMGR_CLK_OSC]; + break; + case CLK_ANS_LINK: + freq = clks[PMGR_CLK_ANS]; + break; + case CLK_BUS: + case CLK_PCLK: + case CLK_PERIPH: + freq = clks[PMGR_CLK_LIO]; + break; + case CLK_MEM: + freq = clks[PMGR_CLK_MCU]; + break; + case CLK_CPU: + freq = clks[PMGR_CLK_MCU]; + break; + case CLK_MIPI: + freq = clks[PMGR_CLK_MIPI_DSI]; + break; + default: + break; + } + + return freq; +} + +static void clock_update_frequency(uint32_t clk, uint32_t freq) +{ + uint32_t src_idx, src_clk, src_factor, reg; + bool freq_supported = false; + volatile uint32_t *clkcfg = clk_configs[clk].clock_reg; + + if (freq == 0) + { + return; + } + + for (src_idx = 0; src_idx < CLOCK_SOURCES_MAX && clk_configs[clk].sources[src_idx].factor != 0; src_idx++) + { + src_clk = clk_configs[clk].sources[src_idx].src_clk; + src_factor = clk_configs[clk].sources[src_idx].factor; + + // Round the requested frequency to closest MHz value and check if we have a match + if ((freq / 1000000) == ((clks[src_clk] / src_factor) / 1000000)) + { + freq_supported = true; + break; + } + } + + if (freq_supported) + { + // Configure clock + reg = *clkcfg; + reg &= ~(PMGR_CLK_CFG_SRC_SEL_MASK << PMGR_CLK_CFG_SRC_SEL_SHIFT); + reg |= (src_idx & PMGR_CLK_CFG_SRC_SEL_MASK) << PMGR_CLK_CFG_SRC_SEL_SHIFT; + *clkcfg = reg; + while (*clkcfg & PMGR_CLK_CFG_PENDING); + } +} + +void clock_set_frequency(int clock, uint32_t divider, uint32_t pll_p, uint32_t pll_m, uint32_t pll_s, uint32_t pll_t) +{ + uint32_t clk = PMGR_CLK_OSC; + + switch (clock) { + + case CLK_VCLK0: + clk = PMGR_CLK_VID; + break; + + default: + break; + } + + if (clk >= PMGR_CLK_SOURCE_FIRST && clk <= PMGR_CLK_SOURCE_LAST) { + clock_update_frequency(clk, pll_t); + clocks_get_frequencies_range(clk, clk); + } +} + +void clock_reset_device(int device) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device); + + switch (device) { + case CLK_MCU: + default: + *reg |= PMGR_PS_RESET; + spin(1); + *reg &= ~PMGR_PS_RESET; + break; + } +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_system_reset(); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_power_init(void) +{ +} + +void platform_power_spin(uint32_t usecs) +{ + extern void aic_spin(uint32_t usecs); + aic_spin(usecs); +} + +#if WITH_DEVICETREE +void pmgr_update_device_tree(DTNode *pmgr_node) +{ +} +#endif + +/* + * Timer support + */ +#define DECR_MAX_COUNT (INT32_MAX) + +static void timer_deadline(void *arg); +static void (* timer_deadline_func)(void); + +int timer_init(uint32_t timer) +{ + /* Allow only banked access to CPU's own timer */ + if (timer != 0) return -1; + + rPMGR_INTERVAL_TMR_CTL = (1 << 0) | (1 << 8); + + return 0; +} + +void timer_stop_all(void) +{ + rPMGR_INTERVAL_TMR_CTL &= ~(1 << 0); + rPMGR_INTERVAL_TMR_CTL = (1 << 8); +} + +void timer_deadline_enter(uint64_t deadline, void (* func)(void)) +{ + uint64_t ticks; + uint32_t decr; + + timer_deadline_func = func; + if (func) { +// printf("installing deadline %p\n", func); + + /* convert absolute deadline to relative time */ + ticks = timer_get_ticks(); + if (deadline <= ticks) { + // If the desired deadline would be 0 or negative, we ensure it is at least 1 tick + // in order to fire the timer immediately and not wrap around. + deadline = 1; + } else { + deadline -= ticks; + } + + /* clamp the deadline to our maximum, which is about 178 seconds */ + decr = (deadline > DECR_MAX_COUNT) ? DECR_MAX_COUNT : deadline; +// printf(" using decrementer count %u\n", decr); + + /* Reprogramme the desired count */ + rPMGR_INTERVAL_TMR = DECR_MAX_COUNT; + rPMGR_INTERVAL_TMR_CTL = (1 << 0) | (1 << 8); + rPMGR_INTERVAL_TMR = decr; + + } else { + rPMGR_INTERVAL_TMR_CTL &= ~(1 << 0); + rPMGR_INTERVAL_TMR_CTL = (1 << 8); + } +} + +void platform_fiq() +{ + /* clear FIQ and disable decrementer */ + rPMGR_INTERVAL_TMR_CTL &= ~(1 << 0); + rPMGR_INTERVAL_TMR_CTL = (1 << 8); + + /* if we have a callback, invoke it now */ + if (timer_deadline_func) { + timer_deadline_func(); + } +} + +utime_t timer_ticks_to_usecs(uint64_t ticks) +{ +#if (OSC_FREQ % 1000000) == 0 + return ticks / (OSC_FREQ / 1000000); +#else +#error "The code below has overflow issues. Make sure you really want to use it" + return (ticks * 1000 * 1000) / OSC_FREQ; +#endif +} + +uint64_t timer_usecs_to_ticks(utime_t usecs) +{ +#if (OSC_FREQ % 1000000) == 0 + return usecs * (OSC_FREQ / 1000000); +#else +#error "The code below has overflow issues. Make sure you really want to use it" + uint64_t timer_scale = ((uint64_t)(OSC_FREQ) << 20) / (1000 * 1000); + return (ticks * timer_scale) >> 20; +#endif +} + +uint32_t timer_get_tick_rate(void) +{ + return OSC_FREQ; +} + +uint64_t timer_get_ticks(void) +{ + extern uint64_t aic_get_ticks(void); + + return (aic_get_ticks()); +} diff --git a/platform/s7002/pmgr/rules.mk b/platform/s7002/pmgr/rules.mk new file mode 100644 index 0000000..f64871a --- /dev/null +++ b/platform/s7002/pmgr/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_TIMER=1 \ + WITH_FIQ_TIMER=1 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s7002/reconfig/reconfig.c b/platform/s7002/reconfig/reconfig.c new file mode 100644 index 0000000..88f0218 --- /dev/null +++ b/platform/s7002/reconfig/reconfig.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include + +#define ENCODE_RECONFIG_CONFIG(start, count) ((((count) & 0x3ff) << 16) | ((start & 0x3ff) << 0)) + + +typedef struct { + uint32_t mem_reconfig_count; + uint32_t soc_reconfig_count; + uint32_t akf_reconfig_count; +} reconfig_stat_t; + +static reconfig_stat_t reconfig_stat; + +void reconfig_append_command(reconfig_type_t type, uint32_t cmd, uint32_t data, uint32_t mask) +{ + uint32_t reconfig_offset = 0; + uint32_t *reconfig_count_ptr = NULL; + + // First, a basic check that reconfig is being programmed in the right order (mem -> soc -> akf) + switch (type) + { + case RECONFIG_TYPE_MEM: + ASSERT(reconfig_stat.soc_reconfig_count == 0); + ASSERT(reconfig_stat.akf_reconfig_count == 0); + reconfig_offset = reconfig_stat.mem_reconfig_count; + reconfig_count_ptr = &reconfig_stat.mem_reconfig_count; + break; + case RECONFIG_TYPE_SOC: + ASSERT(reconfig_stat.mem_reconfig_count != 0); + ASSERT(reconfig_stat.akf_reconfig_count == 0); + reconfig_offset = reconfig_stat.mem_reconfig_count + reconfig_stat.soc_reconfig_count; + reconfig_count_ptr = &reconfig_stat.soc_reconfig_count; + break; + case RECONFIG_TYPE_AKF: + ASSERT(reconfig_stat.mem_reconfig_count != 0); + ASSERT(reconfig_stat.soc_reconfig_count != 0); + reconfig_offset = reconfig_stat.mem_reconfig_count + reconfig_stat.soc_reconfig_count + reconfig_stat.akf_reconfig_count; + reconfig_count_ptr = &reconfig_stat.akf_reconfig_count; + break; + default: + panic("Unknown reconfig type: %d", type); + } + + if(reconfig_offset >= RECONFIG_RAM_SIZE_IN_WORDS - 1) + { + panic("Out of reconfig space!"); + } + + rRECONFIG_RAM_CMD(reconfig_offset) = cmd; + rRECONFIG_RAM_DATA(reconfig_offset) = data; + rRECONFIG_RAM_MASK(reconfig_offset) = mask; + + (*reconfig_count_ptr)++; +} + +void reconfig_commit() +{ + // Encode start/range + rRECONFIG_CONFIG_MEM = ENCODE_RECONFIG_CONFIG(0, reconfig_stat.mem_reconfig_count); + rRECONFIG_CONFIG_SOC = ENCODE_RECONFIG_CONFIG(reconfig_stat.mem_reconfig_count, reconfig_stat.soc_reconfig_count); + rRECONFIG_CONFIG_AKF = ENCODE_RECONFIG_CONFIG(reconfig_stat.mem_reconfig_count + reconfig_stat.soc_reconfig_count, reconfig_stat.akf_reconfig_count); + + + // Enable Reconfig engine + rRECONFIG_CONFIGURATION |= (1 << 16); +} + +void reconfig_dbg_dump_contents(void) +{ + printf("==== MEM RECONFIG COMMANDS ====\n"); + printf("INDEX\t\tCMD\t\tDATA\t\tMASK\n"); + for(uint32_t i = 0; i < reconfig_stat.mem_reconfig_count; i++) + { + printf("%d\t\t0x%08x\t\t0x%08x\t\t0x%08x\n", i, rRECONFIG_RAM_CMD(i), rRECONFIG_RAM_DATA(i), rRECONFIG_RAM_MASK(i)); + } + printf("==== SOC RECONFIG COMMANDS ====\n"); + printf("INDEX\t\tCMD\t\tDATA\t\tMASK\n"); + for(uint32_t i = reconfig_stat.mem_reconfig_count; i < reconfig_stat.mem_reconfig_count + reconfig_stat.soc_reconfig_count; i++) + { + printf("%d\t\t0x%08x\t\t0x%08x\t\t0x%08x\n", i, rRECONFIG_RAM_CMD(i), rRECONFIG_RAM_DATA(i), rRECONFIG_RAM_MASK(i)); + } + printf("==== AKF RECONFIG COMMANDS ====\n"); + printf("INDEX\t\tCMD\t\tDATA\t\tMASK\n"); + for(uint32_t i = reconfig_stat.mem_reconfig_count + reconfig_stat.soc_reconfig_count; i < reconfig_stat.mem_reconfig_count + reconfig_stat.akf_reconfig_count; i++) + { + printf("%d\t\t0x%08x\t\t0x%08x\t\t0x%08x\n", i, rRECONFIG_RAM_CMD(i), rRECONFIG_RAM_DATA(i), rRECONFIG_RAM_MASK(i)); + } + printf("reconfig_commit: RECONFIG_CONFIG_MEM = 0x%x, CONFIG_SOC = 0x%x, CONFIG_AKF=0x%x\n", rRECONFIG_CONFIG_MEM, rRECONFIG_CONFIG_SOC, rRECONFIG_CONFIG_AKF); +} diff --git a/platform/s7002/reconfig/rules.mk b/platform/s7002/reconfig/rules.mk new file mode 100644 index 0000000..fc1470d --- /dev/null +++ b/platform/s7002/reconfig/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_RECONFIG=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/reconfig.o diff --git a/platform/s7002/rules.mk b/platform/s7002/rules.mk new file mode 100644 index 0000000..74fb831 --- /dev/null +++ b/platform/s7002/rules.mk @@ -0,0 +1,136 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +ARM_CPU := cortex-a7 + +# Devmap chip ID +DEVMAP_CHIP_ID := 7002 + +IRQ_STACK_SIZE := 4096 + +# srom is always defined in here +ifeq ($(TEXT_BANK),srom) + TEXT_BASE := 0x00000000 +endif + +# Overriding SRAM_LEN is not allowed. +ifeq ($(TEXT_BANK),sram) + # SRAM TEXT_BASE is fixed by SecureROM. + TEXT_BASE := 0x46018000 + + # iBSS/LLB memory configuration + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT:= 180*1024 + endif +endif + +# platform target can override sdram config by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(SDRAM_LEN),) + SDRAM_LEN := 512*1024*1024 + + # iBoot/iBEC memory configuration + ifeq ($(TEXT_BANK),sdram) + # SDRAM TEXT_BASE is now set such that you don't have to do lots of math to + # calulate the correct value if you change any of the other region sizes: + # TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 64MB + TEXT_BASE := 0x9C000000 + + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := 1024*1024 + endif + endif +endif + +ifeq ($(TEXT_BANK),srom) + MAX_DFU_SIZE := 128*1024 +endif +ifeq ($(TEXT_BANK),sram) + MAX_DFU_SIZE := 192*1024 +endif + +# platform target can override display size config by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(DISPLAY_SIZE),) + DISPLAY_SIZE := 4*1024*1024 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + L2_CACHE_SIZE=256*1024 \ + L2_CACHE_SETS=9 \ + WITH_NON_COHERENT_DMA=1 \ + ANC_PPNNPL_DS_DRIVE_STRENGTH=6 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_HOLD_TIME=1 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_SETUP_TIME=1 \ + ANC_LINK_SDR_REN_HOLD_TIME=2 \ + ANC_LINK_SDR_REN_SETUP_TIME=3 \ + ANC_LINK_SDR_WEN_HOLD_TIME=2 \ + ANC_LINK_SDR_WEN_SETUP_TIME=3 \ + ANC_LINK_SDR_DATA_CAPTURE_DELAY=0 \ + ANC_LINK_SDR_CLE_ALE_SETUP_TIME=0 \ + ANC_BOOT_CONTROLLERS=1 \ + ANC_TOGGLE_SUPPORTED=0 \ + ASP_LLB_OVERRIDE_NUM_BLKS=253*2 \ + DISPLAY_SIZE="($(DISPLAY_SIZE)ULL)" \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=128 \ + SDRAM_LEN="$(SDRAM_LEN)ULL" \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + WITH_NO_RANDOM_HEAP_COOKIE=1 \ + WITH_NO_RANDOM_STACK_COOKIE=1 \ + WITH_PLATFORM_INIT_USB=1 \ + CLEAN_INV_CACHE_ON_QUIESCE=1 + +# This platform contains corecrypto, needs large idle task stack for DFU stages. +ifeq ($(PRODUCT),iBSS) + OPTIONS += \ + IDLE_TASK_SIZE=0x3000 \ + PLATFORM_START_FUNCTION=_platform_start \ + WITH_BOOT_TRAMPOLINE=1 +endif + +ifeq ($(PRODUCT),LLB) + OPTIONS += \ + IDLE_TASK_SIZE=0x3000 \ + PLATFORM_START_FUNCTION=_platform_start \ + WITH_BOOT_TRAMPOLINE=1 +endif + +ifeq ($(APPLICATION),SecureROM) + DATA_BASE := 0x46000000 + OPTIONS += \ + IDLE_TASK_SIZE=0x3000 + WITH_ROM_TRAMPOLINE=1 \ + DATA_BASE="$(DATA_BASE)" + + GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) + ifeq ($(CONFIGS),fpga) + OPTIONS += \ + SUPPORT_FPGA=1 + endif +endif + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o diff --git a/platform/s8000/apcie/apcie_v2.c b/platform/s8000/apcie/apcie_v2.c new file mode 100644 index 0000000..d13c03c --- /dev/null +++ b/platform/s8000/apcie/apcie_v2.c @@ -0,0 +1,1571 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef APCIE_DEBUG_LEVEL +#define DEBUG_LEVEL APCIE_DEBUG_LEVEL +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include SUB_PLATFORM_SPDS_HEADER(apcie_common) +#include SUB_PLATFORM_SPDS_HEADER(apcie_config) +#include SUB_PLATFORM_SPDS_HEADER(x2_pcie_rc) + +#include SUB_PLATFORM_TUNABLE_HEADER(apcie_common) +#include SUB_PLATFORM_TUNABLE_HEADER(apcie_config) + +#if SUB_PLATFORM_S8000 +#include SUB_PLATFORM_SPDS_HEADER(ausp_shm) +#include SUB_PLATFORM_SPDS_HEADER(ausr_shm_cfg) +#include SUB_PLATFORM_SPDS_HEADER(ausr_cfg) +#include SUB_PLATFORM_SPDS_HEADER(aust_shm_cfg) +#include SUB_PLATFORM_TUNABLE_HEADER(ausr_cfg) +#include SUB_PLATFORM_TUNABLE_HEADER(ausr_shm_cfg) +#include SUB_PLATFORM_TUNABLE_HEADER(aust_shm_cfg) +#include SUB_PLATFORM_TUNABLE_HEADER(x1_pcie_rc) +#include SUB_PLATFORM_TUNABLE_HEADER(x2_pcie_rc) +#elif SUB_PLATFORM_S8001 +#include SUB_PLATFORM_SPDS_HEADER(apcie_phy_glue) +#include SUB_PLATFORM_SPDS_HEADER(pma_cmn_registers) +#include SUB_PLATFORM_SPDS_HEADER(pma_rx_lane_registers) +#include SUB_PLATFORM_SPDS_HEADER(pma_tx_lane_registers) +#include SUB_PLATFORM_TUNABLE_HEADER(apcie_phy_glue) +#include SUB_PLATFORM_TUNABLE_HEADER(x2_pcie_rc) +#elif SUB_PLATFORM_S8003 +#include SUB_PLATFORM_SPDS_HEADER(apcie_phy_glue) +#include SUB_PLATFORM_SPDS_HEADER(pma_cmn_registers) +#include SUB_PLATFORM_SPDS_HEADER(pma_rx_lane_registers) +#include SUB_PLATFORM_SPDS_HEADER(pma_tx_lane_registers) +#include SUB_PLATFORM_TUNABLE_HEADER(x1_pcie_rc) +#include SUB_PLATFORM_TUNABLE_HEADER(x2_pcie_rc) +#include SUB_PLATFORM_TUNABLE_HEADER(apcie_phy_glue) +#include SUB_PLATFORM_TUNABLE_HEADER(x1_pcie_rc) +#include SUB_PLATFORM_TUNABLE_HEADER(x2_pcie_rc) +#endif + +#define MAX_DT_PROPERTY_SIZE 4096 + +//////////////////////////////////////////////////////////////////////////////// + +// Common tunables + +#if SUB_PLATFORM_S8000 + +// S8000 B0 +static const struct tunable_struct common_tunable_b0[] = { + PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8000_B0 +}; + +// S8000 C0 +static const struct tunable_struct common_tunable_c0[] = { + PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8000_C0 +}; + +// S8000 chip revision table +static const struct tunable_chip_struct tunables_pcie_common[] = { + {CHIP_REVISION_C0, APCIE_COMMON_BASE_ADDR, common_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, APCIE_COMMON_BASE_ADDR, common_tunable_b0, NULL, false}, +}; + +#elif SUB_PLATFORM_S8001 + +// S8001 A0 +static const struct tunable_struct common_tunable_a0[] = { + PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8001_A0 +}; + +// S8001 B0 +static const struct tunable_struct common_tunable_b0[] = { + PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8001_B0 +}; + +// S8001 chip revision table +static const struct tunable_chip_struct tunables_pcie_common[] = { + {CHIP_REVISION_B0, APCIE_COMMON_BASE_ADDR, common_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_COMMON_BASE_ADDR, common_tunable_a0, NULL, false}, +}; + +#elif SUB_PLATFORM_S8003 + +// S8003 A0 +static const struct tunable_struct common_tunable_a0[] = { + PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8003_A0 +}; + +// S8003 A1 +static const struct tunable_struct common_tunable_a1[] = { + PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8003_A1 +}; + +// S8003 chip revision table +static const struct tunable_chip_struct tunables_pcie_common[] = { + {CHIP_REVISION_A1, APCIE_COMMON_BASE_ADDR, common_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, APCIE_COMMON_BASE_ADDR, common_tunable_a0, NULL, false}, +}; + +#endif // SUB_PLATFORM_S800x + +//////////////////////////////////////////////////////////////////////////////// + +// Config tunables + +#if SUB_PLATFORM_S8000 + +// S8000 B0 +static const struct tunable_struct port0_config_tunable_b0[] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct port1_config_tunable_b0[] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct port2_config_tunable_b0[] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct port3_config_tunable_b0[] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 +}; + +// S8000 C0 +static const struct tunable_struct port0_config_tunable_c0[] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct port1_config_tunable_c0[] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct port2_config_tunable_c0[] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct port3_config_tunable_c0[] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 +}; + +// S8000 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_port_0[] = { + {CHIP_REVISION_C0, APCIE_PORT_BASE_ADDR(0), port0_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(0), port0_config_tunable_b0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_1[] = { + {CHIP_REVISION_C0, APCIE_PORT_BASE_ADDR(1), port1_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(1), port1_config_tunable_b0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_2[] = { + {CHIP_REVISION_C0, APCIE_PORT_BASE_ADDR(2), port2_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(2), port2_config_tunable_b0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_3[] = { + {CHIP_REVISION_C0, APCIE_PORT_BASE_ADDR(3), port3_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(3), port3_config_tunable_b0, NULL, false}, +}; + +// S8000 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_ports[APCIE_NUM_LINKS] = { + { tunables_pcie_config_port_0, ARRAY_SIZE(tunables_pcie_config_port_0), 0 }, + { tunables_pcie_config_port_1, ARRAY_SIZE(tunables_pcie_config_port_1), 0 }, + { tunables_pcie_config_port_2, ARRAY_SIZE(tunables_pcie_config_port_2), 0 }, + { tunables_pcie_config_port_3, ARRAY_SIZE(tunables_pcie_config_port_3), 0 }, +}; + +#elif SUB_PLATFORM_S8001 + +// S8001 A0 +static const struct tunable_struct port0_config_tunable_a0[] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct port1_config_tunable_a0[] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct port2_config_tunable_a0[] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct port3_config_tunable_a0[] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct port4_config_tunable_a0[] = { + PCIE_APCIE_PORT4_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct port5_config_tunable_a0[] = { + PCIE_APCIE_PORT5_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 +}; + + +// S8001 B0 +static const struct tunable_struct port0_config_tunable_b0 [] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct port1_config_tunable_b0 [] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct port2_config_tunable_b0 [] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct port3_config_tunable_b0 [] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct port4_config_tunable_b0 [] = { + PCIE_APCIE_PORT4_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct port5_config_tunable_b0 [] = { + PCIE_APCIE_PORT5_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 +}; + +// S8001 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_port_0[] = { + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(0), port0_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(0), port0_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_1[] = { + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(1), port1_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(1), port1_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_2[] = { + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(2), port2_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(2), port2_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_3[] = { + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(3), port3_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(3), port3_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_4[] = { + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(4), port4_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(4), port4_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_5[] = { + {CHIP_REVISION_B0, APCIE_PORT_BASE_ADDR(5), port5_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(5), port5_config_tunable_a0, NULL, false}, +}; + +// S8001 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_ports[APCIE_NUM_LINKS] = { + { tunables_pcie_config_port_0, ARRAY_SIZE(tunables_pcie_config_port_0), 0 }, + { tunables_pcie_config_port_1, ARRAY_SIZE(tunables_pcie_config_port_1), 0 }, + { tunables_pcie_config_port_2, ARRAY_SIZE(tunables_pcie_config_port_2), 0 }, + { tunables_pcie_config_port_3, ARRAY_SIZE(tunables_pcie_config_port_3), 0 }, + { tunables_pcie_config_port_4, ARRAY_SIZE(tunables_pcie_config_port_4), 0 }, + { tunables_pcie_config_port_5, ARRAY_SIZE(tunables_pcie_config_port_5), 0 }, +}; + +#elif SUB_PLATFORM_S8003 + +// S8003 A0 +static const struct tunable_struct port0_config_tunable_a0[] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct port1_config_tunable_a0[] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct port2_config_tunable_a0[] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct port3_config_tunable_a0[] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 +}; + +// S8003 A1 +static const struct tunable_struct port0_config_tunable_a1[] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct port1_config_tunable_a1[] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct port2_config_tunable_a1[] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct port3_config_tunable_a1[] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 +}; + + +// S8003 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_port_0[] = { + {CHIP_REVISION_A1, APCIE_PORT_BASE_ADDR(0), port0_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(0), port0_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_1[] = { + {CHIP_REVISION_A1, APCIE_PORT_BASE_ADDR(1), port1_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(1), port1_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_2[] = { + {CHIP_REVISION_A1, APCIE_PORT_BASE_ADDR(2), port2_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(2), port2_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_3[] = { + {CHIP_REVISION_A1, APCIE_PORT_BASE_ADDR(3), port3_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(3), port3_config_tunable_a0, NULL, false}, +}; + +// S8003 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_ports[APCIE_NUM_LINKS] = { + { tunables_pcie_config_port_0, ARRAY_SIZE(tunables_pcie_config_port_0), 0 }, + { tunables_pcie_config_port_1, ARRAY_SIZE(tunables_pcie_config_port_1), 0 }, + { tunables_pcie_config_port_2, ARRAY_SIZE(tunables_pcie_config_port_2), 0 }, + { tunables_pcie_config_port_3, ARRAY_SIZE(tunables_pcie_config_port_3), 0 }, +}; + +#endif // SUB_PLATFORM_S800x + +//////////////////////////////////////////////////////////////////////////////// + +// PCIe root complex tunables + +#if SUB_PLATFORM_S8000 + +// S8000 B0 +static const struct tunable_struct rc0_config_tunable_b0[] = { + PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct rc1_config_tunable_b0[] = { + PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct rc2_config_tunable_b0[] = { + PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct rc3_config_tunable_b0[] = { + PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8000_B0 +}; + +// S8000 C0 +static const struct tunable_struct rc0_config_tunable_c0[] = { + PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct rc1_config_tunable_c0[] = { + PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct rc2_config_tunable_c0[] = { + PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct rc3_config_tunable_c0[] = { + PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8000_C0 +}; + +// S8000 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_rc_0[] = { + {CHIP_REVISION_C0, PCIE_PORT_BASE_ADDR(0), rc0_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(0), rc0_config_tunable_b0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_1[] = { + {CHIP_REVISION_C0, PCIE_PORT_BASE_ADDR(1), rc1_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(1), rc1_config_tunable_b0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_2[] = { + {CHIP_REVISION_C0, PCIE_PORT_BASE_ADDR(2), rc2_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(2), rc2_config_tunable_b0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_3[] = { + {CHIP_REVISION_C0, PCIE_PORT_BASE_ADDR(3), rc3_config_tunable_c0, NULL, false}, + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(3), rc3_config_tunable_b0, NULL, false}, +}; + +// S8000 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_rc[APCIE_NUM_LINKS] = { + { tunables_pcie_config_rc_0, ARRAY_SIZE(tunables_pcie_config_rc_0), 0 }, + { tunables_pcie_config_rc_1, ARRAY_SIZE(tunables_pcie_config_rc_1), 0 }, + { tunables_pcie_config_rc_2, ARRAY_SIZE(tunables_pcie_config_rc_2), 0 }, + { tunables_pcie_config_rc_3, ARRAY_SIZE(tunables_pcie_config_rc_3), 0 }, +}; + +#elif SUB_PLATFORM_S8001 + +// S8001 A0 +static const struct tunable_struct rc0_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct rc1_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct rc2_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct rc3_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct rc4_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC4_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct rc5_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC5_DEFAULT_TUNABLES_S8001_A0 +}; + + +// S8001 B0 +static const struct tunable_struct rc0_config_tunable_b0 [] = { + PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct rc1_config_tunable_b0 [] = { + PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct rc2_config_tunable_b0 [] = { + PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct rc3_config_tunable_b0 [] = { + PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct rc4_config_tunable_b0 [] = { + PCIE_PCIE_CONFIG_PCIE_RC4_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct rc5_config_tunable_b0 [] = { + PCIE_PCIE_CONFIG_PCIE_RC5_DEFAULT_TUNABLES_S8001_B0 +}; + +// S8001 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_rc_0[] = { + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(0), rc0_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(0), rc0_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_1[] = { + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(1), rc1_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(1), rc1_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_2[] = { + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(2), rc2_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(2), rc2_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_3[] = { + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(3), rc3_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(3), rc3_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_4[] = { + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(4), rc4_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(4), rc4_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_5[] = { + {CHIP_REVISION_B0, PCIE_PORT_BASE_ADDR(5), rc5_config_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(5), rc5_config_tunable_a0, NULL, false}, +}; + +// S8001 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_rc[APCIE_NUM_LINKS] = { + { tunables_pcie_config_rc_0, ARRAY_SIZE(tunables_pcie_config_rc_0), 0 }, + { tunables_pcie_config_rc_1, ARRAY_SIZE(tunables_pcie_config_rc_1), 0 }, + { tunables_pcie_config_rc_2, ARRAY_SIZE(tunables_pcie_config_rc_2), 0 }, + { tunables_pcie_config_rc_3, ARRAY_SIZE(tunables_pcie_config_rc_3), 0 }, + { tunables_pcie_config_rc_4, ARRAY_SIZE(tunables_pcie_config_rc_4), 0 }, + { tunables_pcie_config_rc_5, ARRAY_SIZE(tunables_pcie_config_rc_5), 0 }, +}; + +#elif SUB_PLATFORM_S8003 + +// S8003 A0 +static const struct tunable_struct rc0_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct rc1_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct rc2_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct rc3_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8003_A0 +}; + +// S8003 A1 +static const struct tunable_struct rc0_config_tunable_a1[] = { + PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct rc1_config_tunable_a1[] = { + PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct rc2_config_tunable_a1[] = { + PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct rc3_config_tunable_a1[] = { + PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8003_A1 +}; + + +// S8003 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_rc_0[] = { + {CHIP_REVISION_A1, PCIE_PORT_BASE_ADDR(0), rc0_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(0), rc0_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_1[] = { + {CHIP_REVISION_A1, PCIE_PORT_BASE_ADDR(1), rc1_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(1), rc1_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_2[] = { + {CHIP_REVISION_A1, PCIE_PORT_BASE_ADDR(2), rc2_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(2), rc2_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_3[] = { + {CHIP_REVISION_A1, PCIE_PORT_BASE_ADDR(3), rc3_config_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(3), rc3_config_tunable_a0, NULL, false}, +}; + +// S8003 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_rc[APCIE_NUM_LINKS] = { + { tunables_pcie_config_rc_0, ARRAY_SIZE(tunables_pcie_config_rc_0), 0 }, + { tunables_pcie_config_rc_1, ARRAY_SIZE(tunables_pcie_config_rc_1), 0 }, + { tunables_pcie_config_rc_2, ARRAY_SIZE(tunables_pcie_config_rc_2), 0 }, + { tunables_pcie_config_rc_3, ARRAY_SIZE(tunables_pcie_config_rc_3), 0 }, +}; + +#endif // SUB_PLATFORM_S800x + +//////////////////////////////////////////////////////////////////////////////// + +// PHY tunables + +#if SUB_PLATFORM_S8000 + +// S8000 ALL +/* Maui tunables spec section 6.6: PCIE Tx De-emphasis and Rx Equalization Settings */ +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA \ +{ AUST_SHM_CFG_BLK_CFG2_TXA_OFFSET, sizeof(uint32_t), 0xffffffff, 0x0000212a}, + +#define PCIE_APCIE_PHY_AUSR0_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA \ +{ AUSR_SHM_CFG_BLK_RXA_CFG1_OFFSET, sizeof(uint32_t), 0xffffffff, 0x00000520}, + +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA \ +{ AUST_SHM_CFG_BLK_CFG2_TXA_OFFSET, sizeof(uint32_t), 0xffffffff, 0x0000212a}, + +#define PCIE_APCIE_PHY_AUSR1_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA \ +{ AUSR_SHM_CFG_BLK_RXA_CFG1_OFFSET, sizeof(uint32_t), 0xffffffff, 0x00000520}, + +// S8000 B0 +static const struct tunable_struct phy_aust0_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUST0_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUST0_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_aust1_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUST1_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUST1_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_aust2_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUST2_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_aust3_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUST3_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_aust4_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUST4_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr0_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR0_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr1_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR1_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr2_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR2_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr3_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR3_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr4_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR4_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr0_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR0_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUSR0_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr1_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR1_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUSR1_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr2_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR2_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr3_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR3_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct phy_ausr4_shm_cfg_tunable_b0[] = { + PCIE_APCIE_PHY_AUSR4_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 +}; + + +// S8000 C0 +static const struct tunable_struct phy_aust0_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUST0_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUST0_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_aust1_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUST1_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUST1_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_aust2_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUST2_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_aust3_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUST3_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_aust4_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUST4_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr0_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR0_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr1_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR1_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr2_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR2_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr3_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR3_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr4_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR4_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr0_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR0_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUSR0_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr1_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR1_SHM_CFG_DEFAULT_TUNABLES_S8000_ALL_EXTRA + PCIE_APCIE_PHY_AUSR1_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr2_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR2_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr3_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR3_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct phy_ausr4_shm_cfg_tunable_c0[] = { + PCIE_APCIE_PHY_AUSR4_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 +}; + +// Must be sorted from newest to oldest chip revision. +static const struct tunable_chip_struct tunables_pcie_phy[] = { + {CHIP_REVISION_C0, APCIE_PHY_AUST0_SHM_CFG_BASE_ADDR, phy_aust0_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUST1_SHM_CFG_BASE_ADDR, phy_aust1_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUST2_SHM_CFG_BASE_ADDR, phy_aust2_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUST3_SHM_CFG_BASE_ADDR, phy_aust3_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUST4_SHM_CFG_BASE_ADDR, phy_aust4_shm_cfg_tunable_c0, NULL, false}, + + {CHIP_REVISION_C0, APCIE_PHY_AUSR0_CFG_BASE_ADDR, phy_ausr0_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR1_CFG_BASE_ADDR, phy_ausr1_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR2_CFG_BASE_ADDR, phy_ausr2_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR3_CFG_BASE_ADDR, phy_ausr3_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR4_CFG_BASE_ADDR, phy_ausr4_cfg_tunable_c0, NULL, false}, + + {CHIP_REVISION_C0, APCIE_PHY_AUSR0_SHM_CFG_BASE_ADDR, phy_ausr0_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR1_SHM_CFG_BASE_ADDR, phy_ausr1_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR2_SHM_CFG_BASE_ADDR, phy_ausr2_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR3_SHM_CFG_BASE_ADDR, phy_ausr3_shm_cfg_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, APCIE_PHY_AUSR4_SHM_CFG_BASE_ADDR, phy_ausr4_shm_cfg_tunable_c0, NULL, false}, + + {CHIP_REVISION_B0, APCIE_PHY_AUST0_SHM_CFG_BASE_ADDR, phy_aust0_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUST1_SHM_CFG_BASE_ADDR, phy_aust1_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUST2_SHM_CFG_BASE_ADDR, phy_aust2_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUST3_SHM_CFG_BASE_ADDR, phy_aust3_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUST4_SHM_CFG_BASE_ADDR, phy_aust4_shm_cfg_tunable_b0, NULL, false}, + + {CHIP_REVISION_B0, APCIE_PHY_AUSR0_CFG_BASE_ADDR, phy_ausr0_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR1_CFG_BASE_ADDR, phy_ausr1_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR2_CFG_BASE_ADDR, phy_ausr2_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR3_CFG_BASE_ADDR, phy_ausr3_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR4_CFG_BASE_ADDR, phy_ausr4_cfg_tunable_b0, NULL, false}, + + {CHIP_REVISION_B0, APCIE_PHY_AUSR0_SHM_CFG_BASE_ADDR, phy_ausr0_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR1_SHM_CFG_BASE_ADDR, phy_ausr1_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR2_SHM_CFG_BASE_ADDR, phy_ausr2_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR3_SHM_CFG_BASE_ADDR, phy_ausr3_shm_cfg_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSR4_SHM_CFG_BASE_ADDR, phy_ausr4_shm_cfg_tunable_b0, NULL, false}, +}; + +// S0000 B0/C0 fuse-based PHY tunables updated at runtime. +static struct tunable_struct phy_values_efuse[] = { + { AUSP_SHM_BLK_CFG_BIAS_OFFSET, + sizeof(uint32_t), + AUSP_SHM_BLK_CFG_BIAS_CURRENT_CAL_RX_UMASK, + 0 // Value updated at runtime + }, + { AUSP_SHM_BLK_PLL_VCO_CFG_OFFSET, + sizeof(uint32_t), + AUSP_SHM_BLK_PLL_VCO_CFG_PLL_V2I_I_SET_UMASK | AUSP_SHM_BLK_PLL_VCO_CFG_PLL_V2I_PI_SET_UMASK, + 0 // Value updated at runtime + }, + TUNABLE_TABLE_END_MARKER +}; + +static const struct tunable_chip_struct tunables_pcie_phy_efuse[] = { + {CHIP_REVISION_C0, APCIE_PHY_AUSP_SHM_BASE_ADDR, phy_values_efuse, NULL, false}, + {CHIP_REVISION_B0, APCIE_PHY_AUSP_SHM_BASE_ADDR, phy_values_efuse, NULL, false}, +}; + +#elif SUB_PLATFORM_S8001 + +// S8001 A0 +static const struct tunable_struct phy_glue_tunable_a0[] = { + PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8001_A0 +}; + +// S8001 B0 +static const struct tunable_struct phy_glue_tunable_b0[] = { + PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_chip_struct tunables_pcie_phy[] = { + {CHIP_REVISION_B0, APCIE_PHY_BASE_ADDR, phy_glue_tunable_b0, NULL, false}, + {CHIP_REVISION_A0, APCIE_PHY_BASE_ADDR, phy_glue_tunable_a0, NULL, false}, +}; + +#elif SUB_PLATFORM_S8003 + +// S8003 A0 +static const struct tunable_struct phy_glue_tunable_a0[] = { + PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8003_A0 +}; + +// S8003 A1 +static const struct tunable_struct phy_glue_tunable_a1[] = { + PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_chip_struct tunables_pcie_phy[] = { + {CHIP_REVISION_A1, APCIE_PHY_BASE_ADDR, phy_glue_tunable_a1, NULL, false}, + {CHIP_REVISION_A0, APCIE_PHY_BASE_ADDR, phy_glue_tunable_a0, NULL, false}, +}; + +#endif // SUB_PLATFORM_S800x + +//////////////////////////////////////////////////////////////////////////////// + +static bool s3e_mode; +static uint32_t link_enable_count; +static bool s3e_reset_on_enable_disable; + +#define PORT_STRIDE (APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_OFFSET - APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_OFFSET) + +#define SET_REG(reg, value) set_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET, (value)) +#define GET_REG(reg) get_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET) +#define OR_REG(reg, value) or_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET, (value)) +#define AND_REG(reg, value) and_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET, (value)) + +#define PORT_REG(reg, port) (APCIE_COMMON_BLK_APCIE_ ## reg ## _0_OFFSET) + (PORT_STRIDE * (port)) +#define SET_PORT_REG(reg, port, value) set_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), value) +#define GET_PORT_REG(reg, port) get_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port)) +#define OR_PORT_REG(reg, port, value) or_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), value) +#define AND_PORT_REG(reg, port, value) and_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), value) + +#define PORT_REG_BIT_SHIFT(reg, bit) (APCIE_COMMON_BLK_APCIE_ ## reg ## _0_ ## bit ## _SHIFT) +#define SET_PORT_REG_BIT(reg, port, b) or_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), 1 << PORT_REG_BIT_SHIFT(reg, b)) +#define CLR_PORT_REG_BIT(reg, port, b) and_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), ~(1 << PORT_REG_BIT_SHIFT(reg, b))) +#define GET_PORT_REG_BIT(reg, port, b) ((get_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port)) >> PORT_REG_BIT_SHIFT(reg, b)) & 1) + +#define PHY_SET_REG(reg, value) set_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET, (value)) +#define PHY_GET_REG(reg) get_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET) +#define PHY_OR_REG(reg, value) or_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET, (value)) +#define PHY_AND_REG(reg, value) and_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET, (value)) + +#if SUB_PLATFORM_S8001 || SUB_PLATFORM_S8003 +#define SET_PMA_CMN_REG(reg, value) set_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET, (value)) +#define GET_PMA_CMN_REG(reg) get_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET) +#define OR_PMA_CMN_REG(reg, value) or_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET, (value)) +#define AND_PMA_CMN_REG(reg, value) and_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET, (value)) + +#define PMA_RX_REG(reg, lane) (PMA_RX_LANE_REGISTERS_BLK_ ## reg ## _OFFSET) + (APCIE_PHY_PMA_RX_LANE_STRIDE * (lane)) +#define SET_PMA_RX_REG(reg, lane, value) set_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane), value) +#define GET_PMA_RX_REG(reg, lane) get_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane)) +#define OR_PMA_RX_REG(reg, lane, value) or_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane), value) +#define AND_PMA_RX_REG(reg, lane, value) and_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane), value) + +#define PMA_TX_REG(reg, lane) (PMA_TX_LANE_REGISTERS_BLK_ ## reg ## _OFFSET) + (APCIE_PHY_PMA_TX_LANE_STRIDE * (lane)) +#define SET_PMA_TX_REG(reg, lane, value) set_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane), value) +#define GET_PMA_TX_REG(reg, lane) get_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane)) +#define OR_PMA_TX_REG(reg, lane, value) or_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane), value) +#define AND_PMA_TX_REG(reg, lane, value) and_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane), value) +#endif + +static void set_reg(uint64_t base, uint32_t offset, uint32_t value) +{ + dprintf(DEBUG_SPEW, "apcie: set_reg[0x%llx] = 0x%x\n", base + offset, value); + *(volatile uint32_t *)(base + offset) = value; +} + +static uint32_t get_reg(uint64_t base, uint32_t offset) +{ + uint32_t value; + + dprintf(DEBUG_SPEW, "acpie: get_reg[0x%llx]", base + offset); + value = *(volatile uint32_t *)(base + offset); + + dprintf(DEBUG_SPEW, " = 0x%x\n", value); + return value; +} + +static void or_reg(uint64_t base, uint32_t offset, uint32_t value) +{ + uint32_t orig; + + orig = get_reg(base, offset); + set_reg(base, offset, orig | value); +} + +static void and_reg(uint64_t base, uint32_t offset, uint32_t value) +{ + uint32_t orig; + + orig = get_reg(base, offset); + set_reg(base, offset, orig & value); +} + + +#if SUB_PLATFORM_S8000 +static uint32_t get_ausp_shm_reg(uint32_t offset) +{ + uint32_t value; + + value = *(volatile uint32_t *)(APCIE_PHY_AUSP_SHM_BASE_ADDR + offset); + + return value; +} + +static void set_ausp_shm_reg(uint32_t offset, uint32_t value) +{ + *(volatile uint32_t *)(APCIE_PHY_AUSP_SHM_BASE_ADDR + offset) = value; +} +#endif + +void apcie_set_s3e_mode(bool reset_on_enable) +{ + s3e_mode = true; + s3e_reset_on_enable_disable = reset_on_enable; +} + +static void apcie_enable_root_complex(void) +{ + // 1. Turn on PCIE in PCIE_PS register + clock_gate(CLK_PCIE, true); + // 2. Enable the 24Mhz clock + clock_gate(CLK_PCIE_AUX, true); + // 4. Enable the ref clock + clock_gate(CLK_PCIE_REF, true); + // 5. Enable the PCIe links + clock_gate(CLK_PCIE_LINK0, true); + clock_gate(CLK_PCIE_LINK1, true); + clock_gate(CLK_PCIE_LINK2, true); + clock_gate(CLK_PCIE_LINK3, true); +#if SUB_PLATFORM_S8001 + clock_gate(CLK_PCIE_LINK4, true); + clock_gate(CLK_PCIE_LINK5, true); +#endif + + // Apply common tunables. + platform_apply_tunables(tunables_pcie_common, ARRAY_SIZE(tunables_pcie_common), "PCIe common"); + + if (s3e_mode) { + + if (s3e_reset_on_enable_disable) { +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + AND_REG(NANDRST_CTRL, ~1); +#elif SUB_PLATFORM_S8001 + AND_PORT_REG(NANDRST_CTRL, 0, ~1); +#endif + } + + gpio_configure(GPIO_NAND_SYS_CLK, GPIO_CFG_FUNC0); + OR_REG(NANDSYSCLK_CTRL, 1); + // S3e spec requires 32 24 Mhz clock cycles from NANDSYSCLK to reset deassertion. + // But, APCIe spec requires we wait 100 microseconds (Maui_aPCIe_Spec section 5.4) + spin(100); + + // De-assert S3E_RESET_N if it's already enabled. Except when platform specified + // s3e_reset_on_enable_disable (for example, in iBEC), we only de-assert the reset, and + // then leave it de-asserted +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + OR_REG(NANDRST_CTRL, 1); +#elif SUB_PLATFORM_S8001 + OR_PORT_REG(NANDRST_CTRL, 0, 1); +#endif + } + + // 7.Select APCIE lane configuration + SET_REG(LANE_CFG, (1 << 4) | platform_get_apcie_lane_cfg()); + + // 8. PCIe Phy is powered up: + // APCIE_PHY_POWERUP_STS.powerup_done is set by the HW when Phy power-up sequence is completed + while((GET_REG(PHY_POWERUP_STS) & 1) == 0) + spin(1); + + // 9. Software de-asserts phy_apb_reset_n + OR_REG(PHY_CONFIG_RST_CTRL, 1); + + // Update the fuse-based PHY tunables. +#if SUB_PLATFORM_S8000 + phy_values_efuse[0].value = AUSP_SHM_BLK_CFG_BIAS_CURRENT_CAL_RX_INSRT(chipid_get_pcie_rx_ldo()); + phy_values_efuse[1].value = AUSP_SHM_BLK_PLL_VCO_CFG_PLL_V2I_I_SET_INSRT(chipid_get_pcie_txpll_vco_v2i_i_set()) | + AUSP_SHM_BLK_PLL_VCO_CFG_PLL_V2I_PI_SET_INSRT(chipid_get_pcie_txpll_vco_v2i_pi_set()); + + // Apply fuse-based tunable values + platform_apply_tunables(tunables_pcie_phy_efuse, ARRAY_SIZE(tunables_pcie_phy_efuse), "PCIe PHY fused"); +#endif + + // Apply SPDS-generated tunable values + platform_apply_tunables(tunables_pcie_phy, ARRAY_SIZE(tunables_pcie_phy), "PCIe PHY"); + + // 11. When internal REFCLK is selected, SW must ensure that REFCLK provided by PCIe + // REFCLK PLL is stable before proceeding to link bring-up + while ((GET_REG(PHY_POWERUP_STS) & (1 << 4)) == 0) + spin(1); +} + +static void apcie_disable_root_complex(void) +{ + if (s3e_reset_on_enable_disable) { +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + AND_REG(NANDRST_CTRL, ~1); +#elif SUB_PLATFORM_S8001 + AND_PORT_REG(NANDRST_CTRL, 0, ~1); +#endif + } + + // See for related discussion on the link resets + // We need to assert reset to the individual link power domains, and then to the main one + clock_set_device_reset(CLK_PCIE_LINK0, true); + clock_set_device_reset(CLK_PCIE_LINK1, true); + clock_set_device_reset(CLK_PCIE_LINK2, true); + clock_set_device_reset(CLK_PCIE_LINK3, true); +#if SUB_PLATFORM_S8001 + clock_set_device_reset(CLK_PCIE_LINK4, true); + clock_set_device_reset(CLK_PCIE_LINK5, true); +#endif + clock_set_device_reset(CLK_PCIE, true); + + spin(10); + + clock_gate(CLK_PCIE_LINK0, false); + clock_gate(CLK_PCIE_LINK1, false); + clock_gate(CLK_PCIE_LINK2, false); + clock_gate(CLK_PCIE_LINK3, false); +#if SUB_PLATFORM_S8001 + clock_gate(CLK_PCIE_LINK4, false); + clock_gate(CLK_PCIE_LINK5, false); +#endif + clock_gate(CLK_PCIE_AUX, false); + clock_gate(CLK_PCIE_REF, false); + clock_gate(CLK_PCIE, false); + + clock_set_device_reset(CLK_PCIE, false); + clock_set_device_reset(CLK_PCIE_LINK0, false); + clock_set_device_reset(CLK_PCIE_LINK1, false); + clock_set_device_reset(CLK_PCIE_LINK2, false); + clock_set_device_reset(CLK_PCIE_LINK3, false); +#if SUB_PLATFORM_S8001 + clock_set_device_reset(CLK_PCIE_LINK4, false); + clock_set_device_reset(CLK_PCIE_LINK5, false); +#endif +} + +// Implements the enable sequence from APCIe spec section 6.1 as it applies to +// APCIE_COMMON registers. The portion of the sequence that affects the APCIE_CONFIG +// registers is handled in common code +static void apcie_enable_link_hardware(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + dprintf(DEBUG_INFO, "apcie: Enabling link %d\n", link); + + dprintf(DEBUG_SPEW, "setting PERST\n"); + // Make sure PERST# starts out as asserted + CLR_PORT_REG_BIT(PORT_RST_CTRL, link, APCIE_PERST_N); + + dprintf(DEBUG_SPEW, "enabling REFCLK\n"); + // 1) 100Mhz REFCLK to the link partners is enabled + SET_PORT_REG_BIT(PORT_REFCLK_CTRL, link, REFCLK_EN); + + // (2) and (3) are done in the common code before calling this function + + // 4) Update link configuration + // skip this step in SecureROM/iBoot + + dprintf(DEBUG_SPEW, "enabling port\n"); + // 5) Enable target PCIE link by setting APCIE_PORT_CTRL_{0/1/2/3}.port_en + SET_PORT_REG_BIT(PORT_CTRL, link, PORT_EN); + + dprintf(DEBUG_SPEW, "waiting for PHY cal\n"); + // 5d) Software must wait until APCIE_PHY_CAL_STS_{0/1/2/3}.cal_done is set + while (GET_PORT_REG_BIT(PHY_CAL_STS, link, CAL_DONE) == 0) + spin(10); + +#if SUPPORT_FPGA + SET_PORT_REG_BIT(PORT_CTRL, link, MUXED_AUXCLK_AUTO_DIS); +#endif + + dprintf(DEBUG_SPEW, "clearing PERST\n"); + // 6) De-assert PERST# for the target PCIE link. + SET_PORT_REG_BIT(PORT_RST_CTRL, link, APCIE_PERST_N); + + // 7) Enable dynamic REFCLK clock gating + // skip this step in SecureROM/iBoot +} + +static void apcie_disable_link_hardware(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + CLR_PORT_REG_BIT(PORT_RST_CTRL, link, APCIE_PERST_N); + + CLR_PORT_REG_BIT(PORT_REFCLK_CTRL, link, REFCLK_EN); + CLR_PORT_REG_BIT(PORT_CTRL, link, PORT_EN); +} + +bool apcie_enable_link(uint32_t link) +{ + struct apcie_link_config *config = &apcie_link_configs[link]; + struct apcie_link_status *status = &apcie_link_statuses[link]; + utime_t start; + uint32_t force_width; + + ASSERT(link < APCIE_NUM_LINKS); + + if (status->enabled) + return true; + + // Clocks to PCIe don't default to on since it isn't used in POR configurations + if (link_enable_count == 0) { + apcie_enable_root_complex(); + } + + // Make sure PERST# starts out as asserted + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + gpio_configure(config->clkreq_gpio, GPIO_CFG_IN); + + // wait for CLKREQ# to be asserted + dprintf(DEBUG_INFO, "apcie: waiting for clkreq..."); + start = system_time(); + while (gpio_read(config->clkreq_gpio) != 0) { + if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) { + dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for CLKREQ# on link %u\n", link); + goto cleanup; + } + spin(1); + } + dprintf(DEBUG_INFO, " done\n"); + + gpio_configure(config->clkreq_gpio, GPIO_CFG_FUNC0); + + // Do required initialization in APCIE_COMMON registers + apcie_enable_link_hardware(link); + + // Apply root complex config tunables + platform_apply_tunables(tunables_pcie_config_rc[link].tunable_chip, + tunables_pcie_config_rc[link].num_tunable_chips, + "PCIe config"); + + // Apply APCIe config port tunables + platform_apply_tunables(tunables_pcie_config_ports[link].tunable_chip, + tunables_pcie_config_ports[link].num_tunable_chips, + "APCIe config"); + + // PCIe spec requires a 100 microsecond delay from REFCLK starting + // to PERST being deasserted + spin(100); + + // 5) De-assert PERST# for the target PCIE link. + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_1); + + // Limit link speed to Gen1 + rAPCIE_PCIE_CAP_LINK_CONTROL2(link) = (rAPCIE_PCIE_CAP_LINK_CONTROL2(link) & ~0xfU) | 1; + + // Limit link width if requested by the platform. If the platform returns 0, + // let the hardware autonegotiate the width using its default parameters + force_width = platform_get_pcie_link_width(link); + if (force_width != 0) { + ASSERT(force_width <= 2); + + uint32_t gen2_ctrl; + gen2_ctrl = rAPCIE_PORT_LOGIC_GEN2_CTRL(link); + gen2_ctrl &= ~(0x1ff << 8); + gen2_ctrl |= (force_width << 8); + rAPCIE_PORT_LOGIC_GEN2_CTRL(link) = gen2_ctrl; + + uint32_t port_link_ctrl; + port_link_ctrl = rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(link); + port_link_ctrl &= ~(0x3f << 16); + port_link_ctrl |= ((1 << (force_width - 1)) << 16); + rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(link) = port_link_ctrl; + } + +#if SUB_PLATFORM_S8001 + // ECO_124 SNPS Gen3 PCIE RC IP's LTSSM gets stuck when exiting L0 and entering L1 - Enable ECO + rAPCIE_CONFIG_SPACE32(link, X2_PCIE_RC_X2_PCIE_DSP_PF0_PORT_LOGIC_SLAVE_STATE_OVR_OFF_OFFSET) |= 1; +#endif + + rAPCIE_COUNTER_COMMAND(link) = APCIE_COUNTER_CLEAR | APCIE_COUNTER_ENABLE; + +#if SUB_PLATFORM_S8001 || SUB_PLATFORM_S8003 + // Disable PHY powergating: Re-enable ASPM+L1SS for all Endpoints [Malta] + uint32_t lane_cfg = platform_get_apcie_lane_cfg(); + uint32_t phy_sig_mask; + uint32_t phy_reg; + +#if SUB_PLATFORM_S8001 + uint32_t link_widths[][6] = { + [APCIE_LANE_CFG_X1_X1_X1_X1_X1_X1] = { 1, 1, 1, 1, 1, 1}, + [APCIE_LANE_CFG_X2_X1_X1_X1_X1] = { 2, 0, 1, 1, 1, 1}, + [APCIE_LANE_CFG_X1_X1_X2_X1_X1] = { 1, 1, 2, 0, 1, 1}, + [APCIE_LANE_CFG_X2_X2_X1_X1] = { 2, 0, 2, 0, 1, 1}, + [APCIE_LANE_CFG_X1_X1_X1_X1_X2] = { 1, 1, 1, 1, 2, 0}, + [APCIE_LANE_CFG_X2_X1_X1_X2] = { 2, 0, 1, 1, 2, 0}, + [APCIE_LANE_CFG_X1_X1_X2_X2] = { 1, 1, 2, 0, 2, 0}, + [APCIE_LANE_CFG_X2_X2_X2] = { 2, 0, 2, 0, 2, 0}, + }; + + ASSERT(lane_cfg < sizeof(link_widths) / sizeof(link_widths[0])); + ASSERT(link < sizeof(link_widths[0]) / sizeof(link_widths[0][0])); + + uint32_t link_width = link_widths[lane_cfg][link]; + ASSERT(link_width != 0); + + phy_sig_mask = (link_width | 1) << link; +#elif SUB_PLATFORM_S8003 + switch (link) { + case 0: + phy_sig_mask = (lane_cfg == APCIE_LANE_CFG_X1_X1_X1_X1) ? 0x01 : 0x03; + break; + case 1: + phy_sig_mask = 0x04; + break; + case 2: + phy_sig_mask = (lane_cfg == APCIE_LANE_CFG_X2_X1_X2) ? 0x18 : 0x08; + break; + case 3: + ASSERT(lane_cfg != APCIE_LANE_CFG_X2_X1_X2); + phy_sig_mask = 0x10; + break; + default: + panic("Invalid PCIe link: %d", link); + } +#else +#error "Invalid platform" +#endif + + // Wait for the phy lanes to power up. + while ((PHY_GET_REG(PCIE_PHY_SIG) & phy_sig_mask) != phy_sig_mask) { + spin(10); + } + + // Disable PCIE PHY common block power gating. + OR_PMA_CMN_REG(CMN_CDIAG_FUNC_PWR_CTRL, PMA_CMN_REGISTERS_BLK_CMN_CDIAG_FUNC_PWR_CTRL_14_UMASK); + OR_PMA_CMN_REG(CMN_CDIAG_XCTRL_PWR_CTRL, PMA_CMN_REGISTERS_BLK_CMN_CDIAG_XCTRL_PWR_CTRL_14_UMASK); + + // Update common PHY PLL timers. + phy_reg = GET_PMA_CMN_REG(CMN_SSM_PLLPRE_TMR); + phy_reg &= ~PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLPRE_TMR_11_0_UMASK; + phy_reg |= PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLPRE_TMR_11_0_INSRT(0x64); + SET_PMA_CMN_REG(CMN_SSM_PLLPRE_TMR, phy_reg); + phy_reg = GET_PMA_CMN_REG(CMN_SSM_PLLLOCK_TMR); + phy_reg &= ~PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLLOCK_TMR_11_0_UMASK; + phy_reg |= PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLLOCK_TMR_11_0_INSRT(0x19); + SET_PMA_CMN_REG(CMN_SSM_PLLLOCK_TMR, phy_reg); + + // For each lane... + for (uint32_t lane = 0; phy_sig_mask != 0; lane++, phy_sig_mask >>= 1) { + // ... if we're enabling this lane ... + if (phy_sig_mask & 1) { + // ... disable power gating ... + OR_PMA_TX_REG(XCVR_DIAG_FUNC_PWR_CTRL, lane, PMA_TX_LANE_REGISTERS_BLK_XCVR_DIAG_FUNC_PWR_CTRL_14_UMASK); + + // ... and disable transmitter boost ... + SET_PMA_TX_REG(TX_DIAG_TX_BOOST, lane, 0); + + // ... and update the lane calibration timer ... + phy_reg = GET_PMA_TX_REG(XCVR_PSM_LANECAL_TMR, lane); + phy_reg &= ~PMA_TX_LANE_REGISTERS_BLK_XCVR_PSM_LANECAL_TMR_11_0_UMASK; + phy_reg |= PMA_TX_LANE_REGISTERS_BLK_XCVR_PSM_LANECAL_TMR_11_0_INSRT(0x600); + SET_PMA_TX_REG(XCVR_PSM_LANECAL_TMR, lane, phy_reg); + + // ... and improve SIG DET performance ... + SET_PMA_RX_REG(RX_DIAG_SIGDET_TUNE, lane, 0x3105); + + // ... and improve PI stability ... + phy_reg = GET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM3, lane); + phy_reg &= ~PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM3_7_0_UMASK; + phy_reg |= PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM3_7_0_INSRT(0x9f); + SET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM3, lane, phy_reg); + + phy_reg = GET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM5, lane); + phy_reg &= ~PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM5_7_0_UMASK; + phy_reg |= PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM5_7_0_INSRT(0x01); + SET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM5, lane, phy_reg); + + // ... and improve CDR performace. + phy_reg = GET_PMA_RX_REG(RX_CDRLF_CNFG, lane); + phy_reg &= ~PMA_RX_LANE_REGISTERS_BLK_RX_CDRLF_CNFG_4_0_UMASK; + phy_reg |= PMA_RX_LANE_REGISTERS_BLK_RX_CDRLF_CNFG_4_0_INSRT(0xa); + SET_PMA_RX_REG(RX_CDRLF_CNFG, lane, phy_reg); + + // NOTE: Because iBoot always forces links to Gen1 speed, + // the steps for non-Gen1 speeds have been omitted. + + // ... and increase the margin of PI to avoid AER errors and link down ... + SET_PMA_RX_REG(RX_IQPI_ILL_LOCK_CALCNT_START0, lane, 0xa9); + SET_PMA_RX_REG(RX_EPI_ILL_LOCK_CALCNT_START0, lane, 0xa9); + SET_PMA_RX_REG(RX_IQPI_ILL_LOCK_CALCNT_START1, lane, 0x14d); + SET_PMA_RX_REG(RX_EPI_ILL_LOCK_CALCNT_START1, lane, 0x14d); + } + } +#endif // SUB_PLATFORM_S8001 || SUB_PLATFORM_S8003 + + // 6c) Software sets LINKCFG.ltssm_en to start link training + rAPCIE_CONFIG_LINKCFG(link) |= APCIE_CONFIG_LINKCFG_LTSSM_EN; + + start = system_time(); + while ((rAPCIE_CONFIG_LINKSTS(link) & APCIE_CONFIG_LINKSTS_LINK_STATUS) == 0) { + if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) { + uint32_t linkpmgrsts; + dprintf(DEBUG_CRITICAL, "apcie: Timeout waiting for LinkUp on link %u\n", link); + dprintf(DEBUG_CRITICAL, "apcie: LINKSTS 0x%08x\n", rAPCIE_CONFIG_LINKSTS(link)); + linkpmgrsts = rAPCIE_CONFIG_LINKPMGRSTS(link); + dprintf(DEBUG_CRITICAL, "apcie: LINKPMGRSTS 0x%08x (LTSSM state %d)\n", linkpmgrsts, (linkpmgrsts >> 9) & 0x1F); + + goto cleanup; + } + spin(10); + } + + status->enabled = true; + link_enable_count++; + + dart_init(config->dart_id); + + apcie_setup_root_port_bridge(link, config); + + return true; + +cleanup: + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + spin(10); + gpio_configure(config->perst_gpio, GPIO_CFG_DFLT); + gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT); + + apcie_disable_link_hardware(link); + + if (link_enable_count == 0) { + apcie_disable_root_complex(); + } + + return false; +} + +void apcie_disable_link(uint32_t link) +{ + struct apcie_link_config *config = &apcie_link_configs[link]; + struct apcie_link_status *status = &apcie_link_statuses[link]; + utime_t start; + + ASSERT(link < APCIE_NUM_LINKS); + + if (!status->enabled) + return; + + dprintf(DEBUG_INFO, "apcie: Disabling link %d\n", link); + + rAPCIE_COUNTER_COMMAND(link) = 0; + + // Request PMETO and clear the previous status indications + rAPCIE_CONFIG_PMETO(link) = 1 | (3 << 4); + + start = system_time(); + while (rAPCIE_CONFIG_PMETO(link) & 1) { + if (time_has_elapsed(start, 10000)) { + dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for PME_To_Ack, continuing\n"); + break; + } + spin(10); + } + + start = system_time(); + while ((rAPCIE_CONFIG_LINKSTS(link) & APCIE_CONFIG_LINKSTS_L2_STATE) == 0) { + if (time_has_elapsed(start, 10000)) { + dprintf(DEBUG_CRITICAL, "apcie: link did not go into L2, continuing\n"); + break; + } + spin(10); + } + + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + // delay to allow PERST# signal to settle before letting the pulldown hold it low + // and to allow the endpoint to handle PERST# before removing REFCLK + spin(25); + gpio_configure(config->perst_gpio, GPIO_CFG_DFLT); + gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT); + +#if DEBUG_BUILD + dart_assert_unmapped(config->dart_id); +#endif + + apcie_disable_link_hardware(link); + + status->enabled = false; + link_enable_count--; + + if (link_enable_count == 0) { + apcie_disable_root_complex(); + } + + apcie_free_port_bridge(link); +} + +uint32_t apcie_get_link_enable_count(void) +{ + return link_enable_count; +} + +#if WITH_DEVICETREE +void apcie_update_devicetree(DTNode *apcie_node) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + uint8_t *dt_prop = (uint8_t *)malloc(MAX_DT_PROPERTY_SIZE); + uint8_t *next_dt_prop; + char bridge[16]; + + // Apply common tunables. + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_common, + ARRAY_SIZE(tunables_pcie_common), + next_dt_prop, + 0, // Already at the correct offset + "apcie common"); + + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + dt_set_prop(apcie_node, "apcie-common-tunables", dt_prop, propSize); + + // Apply port-specific config tunables. + for (uint32_t i = 0; i < APCIE_NUM_LINKS; i++) { + snprintf(bridge, sizeof(bridge), "pci-bridge%d", i); + if (dt_find_node(apcie_node, bridge, &node)) { + // APCIe port config tunables. + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_config_ports[i].tunable_chip, + tunables_pcie_config_ports[i].num_tunable_chips, + next_dt_prop, + tunables_pcie_config_ports[i].dt_base, + bridge); + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + dt_set_prop(node, "apcie-config-tunables", dt_prop, propSize); + + // PCIe root complex config tunables. + snprintf(bridge, sizeof(bridge), "pcie-rc%d", i); + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_config_rc[i].tunable_chip, + tunables_pcie_config_rc[i].num_tunable_chips, + next_dt_prop, + tunables_pcie_config_rc[i].dt_base, + bridge); + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + dt_set_prop(node, "pcie-rc-tunables", dt_prop, propSize); + } else { + dprintf(DEBUG_INFO,"PCIe bridge node %s not found -- skipping tunable update\n", bridge); + } + } + +#if SUB_PLATFORM_S8000 + // Apply fuse-based PHY tunables. + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_phy_efuse, + ARRAY_SIZE(tunables_pcie_phy_efuse), + next_dt_prop, + APCIE_PHY_BASE_ADDR, + "PCIe PHY fused"); +#endif + + // Apply SPDS PHY tunables. + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_phy, + ARRAY_SIZE(tunables_pcie_phy), + next_dt_prop, + APCIE_PHY_BASE_ADDR, + "PCIe PHY"); + + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + + dt_set_prop(apcie_node, "phy-params", dt_prop, propSize); + free(dt_prop); + dt_prop = next_dt_prop = NULL; + + // Enable Maui A1 errata if necessary + if (platform_get_chip_revision() < CHIP_REVISION_B0) { + propName = "maui-a1-errata"; + if (FindProperty(apcie_node, &propName, &propData, &propSize)) { + ASSERT(propSize == sizeof(uint32_t)); + *(uint32_t *)propData = 1; + } + } +} +#endif + +struct apcie_link_config platform_apcie_link_configs[APCIE_NUM_LINKS] = { + [0] = { + .perst_gpio = GPIO_PCIE0_PERST, + .clkreq_gpio = GPIO_PCIE0_CLKREQ, + .dart_id = PCIE_PORT0_DART_ID, + }, + [1] = { + .perst_gpio = GPIO_PCIE1_PERST, + .clkreq_gpio = GPIO_PCIE1_CLKREQ, + .dart_id = PCIE_PORT1_DART_ID, + }, + [2] = { + .perst_gpio = GPIO_PCIE2_PERST, + .clkreq_gpio = GPIO_PCIE2_CLKREQ, + .dart_id = PCIE_PORT2_DART_ID, + }, + [3] = { + .perst_gpio = GPIO_PCIE3_PERST, + .clkreq_gpio = GPIO_PCIE3_CLKREQ, + .dart_id = PCIE_PORT3_DART_ID, + }, +#if SUB_PLATFORM_S8001 + [4] = { + .perst_gpio = GPIO_PCIE4_PERST, + .clkreq_gpio = GPIO_PCIE4_CLKREQ, + .dart_id = PCIE_PORT4_DART_ID, + }, + [5] = { + .perst_gpio = GPIO_PCIE5_PERST, + .clkreq_gpio = GPIO_PCIE5_CLKREQ, + .dart_id = PCIE_PORT5_DART_ID, + }, +#endif +}; + +void platform_register_pci_busses(void) +{ + apcie_init(); +} + +uint64_t platform_map_host_to_pci_addr(uintptr_t addr) +{ + // Right now we're only supporting 32-bit PCI addresses + // for aPCIe, so just lop off the top 32 bits + return addr & 0xFFFFFFFF; +} + +uintptr_t platform_map_pci_to_host_addr(uint64_t addr) +{ + // Right now we're only supporting 32-bit PCI addresses + // for aPCIe + ASSERT((addr & ~0xFFFFFFFFULL) == 0); + return PCI_32BIT_BASE + (addr & (PCI_32BIT_LEN - 1)); +} diff --git a/platform/s8000/apcie/rules.mk b/platform/s8000/apcie/rules.mk new file mode 100644 index 0000000..356e0d8 --- /dev/null +++ b/platform/s8000/apcie/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/apcie_v2.o \ diff --git a/platform/s8000/asm.S b/platform/s8000/asm.S new file mode 100644 index 0000000..d199972 --- /dev/null +++ b/platform/s8000/asm.S @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(minipmgr) + + .text + .balign 4 + .globl _platform_start +_platform_start: +#if !APPLICATION_SECUREROM + //////////////////////////////////////////////// + // Must preserve X0 and X1 + //////////////////////////////////////////////// + + // Enable the L2 cache load/store prefetcher. + mrs x2, s3_0_c15_c5_0 // HID5 + and x2, x2, #~(3<<44) // Enable L2C load (bit 44)/store (bit 45) prefetch + msr s3_0_c15_c5_0, x2 // HID5 + isb +#endif + + ret + + .balign 8 + diff --git a/platform/s8000/chipid/chipid.c b/platform/s8000/chipid/chipid.c new file mode 100644 index 0000000..ecbdab7 --- /dev/null +++ b/platform/s8000/chipid/chipid.c @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include + + +#if SUB_PLATFORM_S8000 +#define MINIMUM_FUSE_REVISION 0x8 +#elif SUB_PLATFORM_S8001 +#define MINIMUM_FUSE_REVISION 0x6 +#elif SUB_PLATFORM_S8003 +#define MINIMUM_FUSE_REVISION 0x3 +#else +#error "Unknown platform" +#endif + +bool chipid_get_current_production_mode(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_XTRCT(rCFG_FUSE0) != 0; +} + +bool chipid_get_raw_production_mode(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_XTRCT(rCFG_FUSE0_RAW) != 0; +} + +void chipid_clear_production_mode(void) +{ + rCFG_FUSE0 &= ~MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_UMASK; +} + +bool chipid_get_secure_mode(void) +{ + // demotion only applies to the SEP, so iBoot always reads + // the raw value for secure mode () + return MINIPMGR_FUSE_CFG_FUSE0_SECURE_MODE_XTRCT(rCFG_FUSE0_RAW); +} + +uint32_t chipid_get_security_domain(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_SECURITY_DOMAIN_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_board_id(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_BID_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_minimum_epoch(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_MINIMUM_EPOCH_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_S8000 + return 0x8000; +#elif SUB_PLATFORM_S8001 + return 0x8001; +#elif SUB_PLATFORM_S8003 + return 0x8003; +#else +#error "Unknown platform" +#endif +} + +uint32_t chipid_get_chip_revision(void) +{ + // we use 4 bits for base layer and 4 bits for metal, + // the fuses use 3 for each +#if defined(MINIPMGR_FUSE_CFG_FUSE4_DEV_VERSION_XTRCT) + uint32_t fuse_val = MINIPMGR_FUSE_CFG_FUSE4_DEV_VERSION_XTRCT(rCFG_FUSE4); + + return (fuse_val & 0x7) | (((fuse_val >> 3) & 0x7) << 4); +#elif defined(MINIPMGR_FUSE_CFG_FUSE4_CHIP_REV_MAJOR_XTRCT) + uint32_t fuse = rCFG_FUSE4; + return ((MINIPMGR_FUSE_CFG_FUSE4_CHIP_REV_MAJOR_XTRCT(fuse) << 4) | + (MINIPMGR_FUSE_CFG_FUSE4_CHIP_REV_MINOR_XTRCT(fuse))); +#else +#error "SPDS doesn't contain expected chip rev extraction defines" +#endif +} + +uint32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +uint64_t chipid_get_ecid_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint64_t chipid_get_die_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint32_t chipid_get_cpu_voltage(uint32_t index) +{ + uint32_t voltage = pmgr_binning_get_mv(index, false, chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION); + + if (voltage == PMGR_BINNING_NOTFOUND) + panic("Invalid CPU voltage index %d\n", index); + + return voltage; + +} + +uint32_t chipid_get_cpu_sram_voltage(uint32_t index) +{ + uint32_t voltage = pmgr_binning_get_mv(index, true, chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION); + + if (voltage == PMGR_BINNING_NOTFOUND) + panic("Invalid CPU SRAM voltage index %d\n", index); + + return voltage; +} + +uint32_t chipid_get_soc_voltage(uint32_t index) +{ + uint32_t voltage; + +#if SUB_PLATFORM_S8001 +#if SUB_TARGET_J99A | SUB_TARGET_J98A + index = CHIPID_SOC_VOLTAGE_VMIN; +#else + index = CHIPID_SOC_VOLTAGE_VNOM; +#endif +#endif + voltage = pmgr_binning_get_mv(index, false, chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION); + + if (voltage == PMGR_BINNING_NOTFOUND) + panic("Invalid SOC voltage index %d\n", index); + + return voltage; +} + +uint32_t chipid_get_gpu_voltage(uint32_t index) +{ + uint32_t voltage = pmgr_binning_get_mv(index, false, chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION); + + if (voltage == PMGR_BINNING_NOTFOUND) + panic("Invalid GPU voltage index %d\n", index); + + return voltage; + +} + +uint32_t chipid_get_gpu_sram_voltage(uint32_t index) +{ + uint32_t voltage = pmgr_binning_get_mv(index, true, chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION); + + if (voltage == PMGR_BINNING_NOTFOUND) + panic("Invalid GPU SRAM voltage index %d\n", index); + + return voltage; +} + +uint32_t chipid_get_sram_voltage(uint32_t index) +{ + uint32_t voltage = pmgr_binning_get_mv(CHIPID_VOLTAGE_FIXED, true, chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION); + + if (voltage == PMGR_BINNING_NOTFOUND) + panic("Invalid SRAM voltage index %d\n", index); + + return voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return MINIPMGR_FUSE_CFG_FUSE1_AP_LOCK_XTRCT(rCFG_FUSE1) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) { + rCFG_FUSE1 |= MINIPMGR_FUSE_CFG_FUSE1_AP_LOCK_INSRT(1); + asm("dsb sy"); + if (!chipid_get_fuse_lock()) { + panic("Failed to lock fuses\n"); + } + } +} + +bool chipid_get_fuse_seal(void) +{ + return MINIPMGR_FUSE_CFG_FUSE1_SEAL_FUSES_XTRCT(rCFG_FUSE1) != 0; +} + +uint32_t chipid_get_lpo_trim(void) +{ +#if SUB_PLATFORM_S8000 + // LPO clock doesn't lock with fused TRIM value but does with 0 trim + if (chipid_get_fuse_revision() < 3) + return 0x20; + else +#endif + return MINIPMGR_FUSE_CFG_FUSE2_LPO_TRIM_XTRCT(rCFG_FUSE2); +} + +#if SUB_PLATFORM_S8000 +uint32_t chipid_get_pcie_txpll_vco_v2i_i_set(void) +{ + return MINIPMGR_FUSE_CFG_FUSE3_PCIE_TXPLL_VCO_V2I_I_SET_XTRCT(rCFG_FUSE3); +} + +uint32_t chipid_get_pcie_txpll_vco_v2i_pi_set(void) +{ + return MINIPMGR_FUSE_CFG_FUSE3_PCIE_TXPLL_VCO_V2I_PI_SET_XTRCT(rCFG_FUSE3); +} + +uint32_t chipid_get_pcie_refpll_vco_v2i_i_set(void) +{ + return MINIPMGR_FUSE_CFG_FUSE4_PCIE_REFPLL_VCO_V2I_I_SET_XTRCT(rCFG_FUSE4); +} + +uint32_t chipid_get_pcie_refpll_vco_v2i_pi_set(void) +{ + return MINIPMGR_FUSE_CFG_FUSE4_PCIE_REFPLL_VCO_V2I_PI_SET_XTRCT(rCFG_FUSE4); +} + +uint32_t chipid_get_pcie_rx_ldo(void) +{ + return MINIPMGR_FUSE_CFG_FUSE3_PCIE_RX_LDO_XTRCT(rCFG_FUSE3); +} +#elif SUB_PLATFORM_S8001 || SUB_PLATFORM_S8003 +uint32_t chipid_get_pcie_refpll_fcal_vco_digctrl(void) +{ + return MINIPMGR_FUSE_CFG_FUSE4_PCIE_REFPLL_FCAL_VCO_DIGCTRL_XTRCT(rCFG_FUSE4); +} +#endif + +uint32_t chipid_get_soc_temp_sensor_trim(uint32_t sensor_index) +{ + uint32_t sensor_trim; + +#if SUB_PLATFORM_S8000 && defined(MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_TRIMG_UMASK) + + // S8000 A1 + if (chipid_get_chip_revision() == CHIP_REVISION_A1) { + switch (sensor_index) { + case 0: + return MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_XTRCT_V1(rCFG_FUSE2); + case 1: + return MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN1_XTRCT_V1(rCFG_FUSE2); + case 2: + return MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN2_XTRCT_V1(rCFG_FUSE3); + default: + panic("invalid thermal sensor %u", sensor_index); + } + } +#endif + + // S8000 B0/C0, S8001 A0/B0, S8003 A0/A1 + switch (sensor_index) { + case 0: + sensor_trim = rCFG_FUSE2; + sensor_trim &= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_TRIMG_UMASK | MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_TRIMO_UMASK; + sensor_trim >>= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_TRIMG_SHIFT; + return sensor_trim; + case 1: + sensor_trim = rCFG_FUSE2; + sensor_trim &= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN1_TRIMG_UMASK | MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN1_TRIMO_UMASK; + sensor_trim >>= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN1_TRIMG_SHIFT; + return sensor_trim; + case 2: + sensor_trim = rCFG_FUSE3; + sensor_trim &= MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN2_TRIMG_UMASK | MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN2_TRIMO_UMASK; + sensor_trim >>= MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN2_TRIMG_SHIFT; + return sensor_trim; + +#if SUB_PLATFORM_S8001 + case 3: + sensor_trim = rCFG_FUSE3; + sensor_trim &= MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN3_TRIMG_UMASK | MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN3_TRIMO_UMASK; + sensor_trim >>= MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN3_TRIMG_SHIFT; + return sensor_trim; +#endif + + default: + panic("invalid thermal sensor %u", sensor_index); + } +} + +uint32_t chipid_get_fuse_revision(void) +{ + uint32_t version = pmgr_binning_get_revision(); + if (version == PMGR_BINNING_NOTFOUND) { + return 0; + } + return version; +} + +uint32_t chipid_get_total_rails_leakage() +{ + // FIXME + return 0; +} + +#if SUPPORT_FPGA + +#define FPGA_HAS_INT3 (FPGA_HAS_DISP | FPGA_HAS_MEDIA | FPGA_HAS_JPEG | FPGA_HAS_MSR | FPGA_HAS_VXD) + +uint32_t chipid_get_fpga_block_instantiation(void) +{ + // Hardware blocks instantiated. + uint32_t blocks = (rECID_FUSE3 >> 18) & 0xF; + uint32_t mask = FPGA_HAS_ALWAYS; + + switch (blocks) { + // INT2 := ACC + AF + AMC + SouthBridge + PCIE + case 0x1: + break; + + // INT2GFX := INT2 + GFX + case 0x2: + mask |= FPGA_HAS_GFX; + break; + + // INT3 := INT2 + DISP + MEDIA + JPEG + MSR + VXD + case 0x8: + mask |= FPGA_HAS_INT3; + break; + + // INT3GFX := INT3 + GFX + case 0xA: + mask |= (FPGA_HAS_INT3 | FPGA_HAS_GFX); + break; + + default: + panic("Unknown hardware block instantiation: 0x%x", blocks); + } + + return mask; +} +#endif diff --git a/platform/s8000/chipid/dvfmperf.c b/platform/s8000/chipid/dvfmperf.c new file mode 100644 index 0000000..128ea61 --- /dev/null +++ b/platform/s8000/chipid/dvfmperf.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * This file is only a database of the performance sate for CPU and GPU, regarding the kind of chip + * or board, it has no access to the chip. + */ +#include +#include + +// These array are the first iteration, the next part will include reference to board id, board rev, fuse rev. + +static const enum chipid_voltage_index s8000_cpu[] = { + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_600, + CHIPID_CPU_VOLTAGE_912, + CHIPID_CPU_VOLTAGE_1200, + CHIPID_CPU_VOLTAGE_1512, + CHIPID_CPU_VOLTAGE_1800, + CHIPID_CPU_VOLTAGE_1848, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_1512_WA, + CHIPID_CPU_VOLTAGE_1200_WA, + CHIPID_CPU_VOLTAGE_396_WA, +}; + +static const enum chipid_voltage_index s8003_cpu[] = { + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_600, + CHIPID_CPU_VOLTAGE_912, + CHIPID_CPU_VOLTAGE_1200, + CHIPID_CPU_VOLTAGE_1512, + CHIPID_CPU_VOLTAGE_1800, + CHIPID_CPU_VOLTAGE_1848, +}; + +static const enum chipid_voltage_index s8000a1_cpu[] = { + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_600, + CHIPID_CPU_VOLTAGE_912, + CHIPID_CPU_VOLTAGE_1200, + CHIPID_CPU_VOLTAGE_1512, + CHIPID_CPU_VOLTAGE_1800, + CHIPID_CPU_VOLTAGE_1896, +}; + +static const enum chipid_voltage_index s8000_gpu[] = { + CHIPID_GPU_VOLTAGE_OFF, + CHIPID_GPU_VOLTAGE_340, + CHIPID_GPU_VOLTAGE_474, + CHIPID_GPU_VOLTAGE_550, + CHIPID_GPU_VOLTAGE_723, +}; + +static const enum chipid_voltage_index s8003_gpu[] = { + CHIPID_GPU_VOLTAGE_OFF, + CHIPID_GPU_VOLTAGE_340, + CHIPID_GPU_VOLTAGE_474, + CHIPID_GPU_VOLTAGE_550, + CHIPID_GPU_VOLTAGE_723, +}; + +static const enum chipid_voltage_index s8000a1_gpu[] = { + CHIPID_GPU_VOLTAGE_OFF, + CHIPID_GPU_VOLTAGE_340, + CHIPID_GPU_VOLTAGE_474, + CHIPID_GPU_VOLTAGE_550, + CHIPID_GPU_VOLTAGE_616, +}; + +static const enum chipid_voltage_index s8001_cpu[] = { + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_396, + CHIPID_CPU_VOLTAGE_720, + CHIPID_CPU_VOLTAGE_1080, + CHIPID_CPU_VOLTAGE_1440, + CHIPID_CPU_VOLTAGE_1800, + CHIPID_CPU_VOLTAGE_2160, + CHIPID_CPU_VOLTAGE_2256_1core, +}; + +static const enum chipid_voltage_index s8001_gpu[] = { + CHIPID_GPU_VOLTAGE_OFF, + CHIPID_GPU_VOLTAGE_360, + CHIPID_GPU_VOLTAGE_520, + CHIPID_GPU_VOLTAGE_650, + CHIPID_GPU_VOLTAGE_723, +}; + +static const enum chipid_voltage_index s8000_soc[] = { + CHIPID_SOC_VOLTAGE_BYPASS, + CHIPID_SOC_VOLTAGE_SECUREROM, + CHIPID_SOC_VOLTAGE_VMIN, + CHIPID_SOC_VOLTAGE_VNOM, +}; + +static const enum chipid_voltage_index s8003_soc[] = { + CHIPID_SOC_VOLTAGE_BYPASS, + CHIPID_SOC_VOLTAGE_SECUREROM, + CHIPID_SOC_VOLTAGE_VMIN, + CHIPID_SOC_VOLTAGE_VNOM, +}; + +static const enum chipid_voltage_index s8001_soc[] = { + CHIPID_SOC_VOLTAGE_BYPASS, + CHIPID_SOC_VOLTAGE_SECUREROM, + CHIPID_SOC_VOLTAGE_VMIN, + CHIPID_SOC_VOLTAGE_VMIN, +}; + +static const enum chipid_voltage_index s8001_j127_gpu[] = { + CHIPID_GPU_VOLTAGE_OFF, + CHIPID_GPU_VOLTAGE_360, + CHIPID_GPU_VOLTAGE_520, + CHIPID_GPU_VOLTAGE_650, + CHIPID_GPU_VOLTAGE_723, + CHIPID_GPU_VOLTAGE_804, +}; + +static const enum chipid_voltage_index s8001_j105_cpu[] = { + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_2256, +}; + +static const enum chipid_voltage_index s8001_j105_soc[] = { + CHIPID_SOC_VOLTAGE_BYPASS, + CHIPID_SOC_VOLTAGE_SECUREROM, + CHIPID_SOC_VOLTAGE_VMIN, + CHIPID_SOC_VOLTAGE_VMIN, +}; + +static const enum chipid_voltage_index s8001_j105_gpu[] = { + CHIPID_GPU_VOLTAGE_OFF, + CHIPID_GPU_VOLTAGE_723, +}; + +static const enum chipid_voltage_index s8001_j127_soc[] = { + CHIPID_SOC_VOLTAGE_BYPASS, + CHIPID_SOC_VOLTAGE_SECUREROM, + CHIPID_SOC_VOLTAGE_VNOM, + CHIPID_SOC_VOLTAGE_VNOM, +}; + +static const enum chipid_voltage_index s8001_j99a_soc[] = { + CHIPID_SOC_VOLTAGE_BYPASS, + CHIPID_SOC_VOLTAGE_SECUREROM, + CHIPID_SOC_VOLTAGE_VMIN, + CHIPID_SOC_VOLTAGE_VMIN, +}; + +struct dvfmperf { + uint32_t chip_id; + uint32_t chip_rev; + uint32_t board_id; + const enum chipid_voltage_index *voltage_indexes; + uint32_t size; +}; + + +// The dvfmperfs arays must be sorted to have : +// - BOARD_ID_NONE always coming last for chip/chip revision +// - Highest chip revision coming first +static const struct dvfmperf dvfmperfs_cpu[] = { // Entry with highest chip revision must come first + {0x8000, CHIP_REVISION_B0, BOARD_ID_NONE, s8000_cpu, sizeof(s8000_cpu)/sizeof(s8000_cpu[0])}, + {0x8000, CHIP_REVISION_A1, BOARD_ID_NONE, s8000a1_cpu, sizeof(s8000a1_cpu)/sizeof(s8000a1_cpu[0])}, + {0x8003, CHIP_REVISION_A0, BOARD_ID_NONE, s8003_cpu, sizeof(s8003_cpu)/sizeof(s8003_cpu[0])}, + {0x8001, CHIP_REVISION_A0, J105_AP_BOARD_ID, s8001_j105_cpu, sizeof(s8001_j105_cpu)/sizeof(s8001_j105_cpu[0])}, + {0x8001, CHIP_REVISION_A0, J105_DEV_BOARD_ID, s8001_j105_cpu, sizeof(s8001_j105_cpu)/sizeof(s8001_j105_cpu[0])}, + {0x8001, CHIP_REVISION_A0, BOARD_ID_NONE, s8001_cpu, sizeof(s8001_cpu)/sizeof(s8000_cpu[0])}, +}; + +static const struct dvfmperf dvfmperfs_gpu[] = { // Entry with highest chip revision must come first + {0x8000, CHIP_REVISION_B0, BOARD_ID_NONE, s8000_gpu, sizeof(s8000_gpu)/sizeof(s8000_gpu[0])}, + {0x8000, CHIP_REVISION_A1, BOARD_ID_NONE, s8000a1_gpu, sizeof(s8000a1_gpu)/sizeof(s8000a1_gpu[0])}, + {0x8003, CHIP_REVISION_A0, BOARD_ID_NONE, s8003_gpu, sizeof(s8003_gpu)/sizeof(s8003_gpu[0])}, + {0x8001, CHIP_REVISION_A0, J128_AP_BOARD_ID, s8001_j127_gpu, sizeof(s8001_j127_gpu)/sizeof(s8001_j127_gpu[0])}, + {0x8001, CHIP_REVISION_A0, J128_DEV_BOARD_ID, s8001_j127_gpu, sizeof(s8001_j127_gpu)/sizeof(s8001_j127_gpu[0])}, + {0x8001, CHIP_REVISION_A0, J127_AP_BOARD_ID, s8001_j127_gpu, sizeof(s8001_j127_gpu)/sizeof(s8001_j127_gpu[0])}, + {0x8001, CHIP_REVISION_A0, J127_DEV_BOARD_ID, s8001_j127_gpu, sizeof(s8001_j127_gpu)/sizeof(s8001_j127_gpu[0])}, + {0x8001, CHIP_REVISION_A0, J105_AP_BOARD_ID, s8001_j105_gpu, sizeof(s8001_j105_gpu)/sizeof(s8001_j105_gpu[0])}, + {0x8001, CHIP_REVISION_A0, J105_DEV_BOARD_ID, s8001_j105_gpu, sizeof(s8001_j105_gpu)/sizeof(s8001_j105_gpu[0])}, + {0x8001, CHIP_REVISION_A0, BOARD_ID_NONE, s8001_gpu, sizeof(s8001_gpu)/sizeof(s8001_gpu[0])}, +}; + +static const struct dvfmperf dvfmperfs_soc[] = { // Entry with highest chip revision must come first + {0x8000, CHIP_REVISION_B0, BOARD_ID_NONE, s8000_soc, sizeof(s8000_soc)/sizeof(s8000_soc[0])}, + {0x8003, CHIP_REVISION_A0, BOARD_ID_NONE, s8003_soc, sizeof(s8003_soc)/sizeof(s8003_soc[0])}, + {0x8001, CHIP_REVISION_A0, J105_AP_BOARD_ID, s8001_j105_soc, sizeof(s8001_j105_soc)/sizeof(s8001_j105_soc[0])}, + {0x8001, CHIP_REVISION_A0, J105_DEV_BOARD_ID, s8001_j105_soc, sizeof(s8001_j105_soc)/sizeof(s8001_j105_soc[0])}, + {0x8001, CHIP_REVISION_A0, J128_AP_BOARD_ID, s8001_j127_soc, sizeof(s8001_j127_soc)/sizeof(s8001_j127_soc[0])}, + {0x8001, CHIP_REVISION_A0, J128_DEV_BOARD_ID, s8001_j127_soc, sizeof(s8001_j127_soc)/sizeof(s8001_j127_soc[0])}, + {0x8001, CHIP_REVISION_A0, J127_AP_BOARD_ID, s8001_j127_soc, sizeof(s8001_j127_soc)/sizeof(s8001_j127_soc[0])}, + {0x8001, CHIP_REVISION_A0, J127_DEV_BOARD_ID, s8001_j127_soc, sizeof(s8001_j127_soc)/sizeof(s8001_j127_soc[0])}, + {0x8001, CHIP_REVISION_A0, J99A_AP_BOARD_ID, s8001_j99a_soc, sizeof(s8001_j99a_soc)/sizeof(s8001_j99a_soc[0])}, + {0x8001, CHIP_REVISION_A0, J99A_DEV_BOARD_ID, s8001_j99a_soc, sizeof(s8001_j99a_soc)/sizeof(s8001_j99a_soc[0])}, + {0x8001, CHIP_REVISION_A0, J98A_AP_BOARD_ID, s8001_j99a_soc, sizeof(s8001_j99a_soc)/sizeof(s8001_j99a_soc[0])}, + {0x8001, CHIP_REVISION_A0, J98A_DEV_BOARD_ID, s8001_j99a_soc, sizeof(s8001_j99a_soc)/sizeof(s8001_j99a_soc[0])}, + {0x8001, CHIP_REVISION_A0, BOARD_ID_NONE, s8001_soc, sizeof(s8001_soc)/sizeof(s8001_soc[0])}, +}; + +enum chipid_voltage_index dvfmperf_get_voltage_index(uint32_t index, enum chipid_voltage_type voltage_type) +{ + const struct dvfmperf *dvfmperfs; + enum chipid_voltage_index voltage_index_for_filling; + uint32_t chip_id = chipid_get_chip_id(); + uint32_t chip_rev = chipid_get_chip_revision(); + uint32_t board_id = platform_get_board_id(); + uint32_t i; + uint32_t size = 0; + + switch (voltage_type) { + case CHIPID_CPU_VOLTAGE: + dvfmperfs = dvfmperfs_cpu; + voltage_index_for_filling = CHIPID_CPU_VOLTAGE_396; + size = sizeof(dvfmperfs_cpu)/sizeof(dvfmperfs_cpu[0]); + break; + case CHIPID_GPU_VOLTAGE: + dvfmperfs = dvfmperfs_gpu; + size = sizeof(dvfmperfs_gpu)/sizeof(dvfmperfs_gpu[0]); + voltage_index_for_filling = CHIPID_GPU_VOLTAGE_OFF; + break; + case CHIPID_SOC_VOLTAGE: + dvfmperfs = dvfmperfs_soc; + size = sizeof(dvfmperfs_soc)/sizeof(dvfmperfs_soc[0]); + break; + default: + panic("Invalid voltage type\n"); + voltage_index_for_filling = CHIPID_GPU_VOLTAGE_OFF; // prevent compiler warning + dvfmperfs = NULL; // Prevent compiler warning + break; + } + + + for (i = 0; i < size; i++) { + if (chip_id != dvfmperfs[i].chip_id) { + continue; + } + if (chip_rev < dvfmperfs[i].chip_rev) { + continue; + } + if ((board_id != dvfmperfs[i].board_id) && (dvfmperfs[i].board_id != BOARD_ID_NONE)) { + continue; + } + if (index >= dvfmperfs[i].size) { + if (voltage_type == CHIPID_SOC_VOLTAGE) { + if (dvfmperfs[i].size < 4) { + panic("Invalid number of SOC perf states"); + } + voltage_index_for_filling = dvfmperfs[i].voltage_indexes[2]; + } + return voltage_index_for_filling; + } + return dvfmperfs[i].voltage_indexes[index]; + } + panic("Unknown voltage for current chip\n"); + return CHIPID_GPU_VOLTAGE_OFF; // Never reach this code +} diff --git a/platform/s8000/chipid/operating_point.c b/platform/s8000/chipid/operating_point.c new file mode 100644 index 0000000..33aec2f --- /dev/null +++ b/platform/s8000/chipid/operating_point.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * This file is only a database of the frequencies used by CPU and GPU, it has no access + * To the chip. + */ +#include +#include +#include + +#define CHIP_ID_ALL 0 +#define DELIMITER CHIPID_ALL_VOLTAGE_LAST + +static const struct operating_point_params operating_point_params[] = { + // GPU + {.chipid_max = DELIMITER, .chip_id = 0x8000, .voltage_type = CHIPID_GPU_VOLTAGE}, + // P M S + // | | | + {{.gpu = {CHIPID_GPU_VOLTAGE_OFF,0,0, 0, 0, 0}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_340,0,0, 2,170, 5}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_474,0,0, 2,158, 3}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_550,0,0, 3,275, 3}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_616,0,0, 3,154, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_723,0,0, 1, 90, 2}}}, // It's 720 now for Change GPU & SoC PLL settings to recover yield + {{.gpu = {CHIPID_GPU_VOLTAGE_804,0,0, 1, 67, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_850,0,0, 6,425, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_900,0,0, 1, 75, 1}}}, + + {.chipid_max = DELIMITER, .chip_id = 0x8003, .voltage_type = CHIPID_GPU_VOLTAGE}, + // P M S + // | | | + {{.gpu = {CHIPID_GPU_VOLTAGE_OFF,0,0, 0, 0, 0}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_340,0,0, 2, 85, 2}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_474,0,0, 2, 79, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_550,0,0, 4,275, 2}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_723,0,0, 4,241, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_804,0,0, 1, 67, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_850,0,0, 6,425, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_900,0,0, 1, 75, 1}}}, + + {.chipid_max = DELIMITER, .chip_id = 0x8001, .voltage_type = CHIPID_GPU_VOLTAGE}, + // P M S + // | | | + {{.gpu = {CHIPID_GPU_VOLTAGE_OFF,0,0, 0, 0, 0}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_360,0,0, 1, 60, 3}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_520,0,0, 1, 65, 2}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_650,0,0, 6,325, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_723,0,0, 4,241, 1}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_800,0,0, 3,100, 0}}}, + {{.gpu = {CHIPID_GPU_VOLTAGE_804,0,0, 1, 67, 1}}}, + + + // S8000 B0 + {.chipid_max = DELIMITER, .chip_id = 0x8000, .voltage_type = CHIPID_CPU_VOLTAGE, .chip_rev = CHIP_REVISION_B0}, + // bypass + // | clkSrc + // | | P M S biuDiv4HiVol + // | | | | | | biuDiv4LoVol + // | | | | | | | dvmrMaxWgt + // | | | | | | | | iexrfCfgWrData + // | | | | | | | | | iexrfCfgWrIdxa + // | | | | | | | | | | iexrfCfgWrIdxb + // | | | | | | | | | | | exrfCfgWrIdxmuxsel + // | | | | | | | | | | | | nrgAccScaleTab(Ext) + // | | | | | | | | | | | | | lkgEstTab(Ext) + // | | | | | | | | | | | | | | dpe0DvfmTab(Ext) + // | | | | | | | | | | | | | | | + {{{CHIPID_CPU_VOLTAGE_BYPASS, 0, 0, 0, 0, 0, 2, 2, 0xf, 1, 0, 0, 0, 0x1, 0x1, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_SECUREROM,1, 1, 1, 50, 3, 2, 2, 0xf, 1, 0, 0, 0, 0x1, 0x1, 0xff}}}, // 300MHz + {{{CHIPID_CPU_VOLTAGE_396, 0, 1, 1, 66, 3, 2, 2, 0xf, 1, 0, 0, 0, 0x37, 0x30, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_600, 0, 1, 1, 75, 2, 2, 3, 0xf, 1, 0, 0, 0, 0x3e, 0x1f, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_912, 0, 1, 1, 76, 1, 4, 4, 0xf, 1, 0, 0, 0, 0x53, 0x14, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1200, 0, 1, 1, 50, 0, 4, 5, 0xf, 1, 0, 0, 0, 0x66, 0x0f, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1512, 0, 1, 1, 63, 0, 5, 6, 0xf, 1, 0, 0, 0, 0x88, 0x0c, 0xd7}}}, + {{{CHIPID_CPU_VOLTAGE_1800, 0, 1, 1, 75, 0, 6, 7, 0xf, 1, 0, 0, 0, 0xbf, 0x0b, 0x97}}}, + {{{CHIPID_CPU_VOLTAGE_1848, 0, 1, 1, 77, 0, 6, 7, 0x2, 1, 0, 0, 0, 0xbf, 0x0a, 0x93}}}, + {{{CHIPID_CPU_VOLTAGE_1896, 0, 1, 1, 79, 0, 6, 7, 0x2, 1, 0, 0, 0, 0xc5, 0x16, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1992, 0, 1, 1, 83, 0, 6, 7, 0xf, 1, 0, 0, 0, 0xc8, 0x15, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_2112, 0, 1, 1, 88, 0, 7, 0, 0x2, 1, 0, 0, 0, 0xc8, 0x14, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_396_WA, 0, 1, 1, 82, 4, 2, 2, 0xf, 1, 0, 0, 0, 0x37, 0x30, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1200_WA, 0, 1, 1, 76, 1, 4, 5, 0xf, 1, 0, 0, 0, 0x66, 0x0f, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1512_WA, 0, 1, 1, 76, 1, 5, 6, 0xf, 1, 0, 0, 0, 0x88, 0x0c, 0xd7}}}, + + // S8000 A1 + {.chipid_max = DELIMITER, .chip_id = 0x8000, .voltage_type = CHIPID_CPU_VOLTAGE}, + // bypass + // | clkSrc + // | | P M S biuDiv4HiVol + // | | | | | | biuDiv4LoVol + // | | | | | | | dvmrMaxWgt + // | | | | | | | | iexrfCfgWrData + // | | | | | | | | | iexrfCfgWrIdxa + // | | | | | | | | | | iexrfCfgWrIdxb + // | | | | | | | | | | | exrfCfgWrIdxmuxsel + // | | | | | | | | | | | | nrgAccScaleTab(Ext) + // | | | | | | | | | | | | | lkgEstTab(Ext) + // | | | | | | | | | | | | | | dpe0DvfmTab(Ext) + // | | | | | | | | | | | | | | | + {{{CHIPID_CPU_VOLTAGE_BYPASS, 0, 0, 0, 0, 0, 2, 2, 0xf, 0, 0, 0, 0, 0x1, 0x1, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_SECUREROM,1, 1, 1, 50, 3, 2, 2, 0xf, 0, 0, 0, 0, 0x1, 0x1, 0xff}}}, // 300MHz + {{{CHIPID_CPU_VOLTAGE_396, 0, 1, 1, 66, 3, 2, 2, 0xf, 0, 0, 0, 0, 0x3e, 0x46, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_600, 0, 1, 1, 50, 1, 2, 3, 0xf, 0, 0, 0, 0, 0x44, 0x2f, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_912, 0, 1, 1, 76, 1, 4, 4, 0xf, 0, 0, 0, 0, 0x5b, 0x1d, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1200, 0, 1, 1, 50, 0, 4, 5, 0xf, 0, 0, 0, 0, 0x74, 0x16, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1512, 0, 1, 1, 63, 0, 5, 6, 0xf, 0, 0, 0, 0, 0x91, 0x11, 0xd7}}}, + {{{CHIPID_CPU_VOLTAGE_1800, 0, 1, 1, 75, 0, 6, 7, 0xf, 0, 0, 0, 0, 0xaf, 0x0f, 0x97}}}, + {{{CHIPID_CPU_VOLTAGE_1896, 0, 1, 1, 79, 0, 6, 7, 0x2, 0, 0, 0, 0, 0xbc, 0x0e, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1992, 0, 1, 1, 83, 0, 6, 7, 0xf, 0, 0, 0, 0, 0xc8, 0x0d, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_2112, 0, 1, 1, 88, 0, 7, 0, 0x2, 0, 0, 0, 0, 0xc8, 0x0c, 0xff}}}, + + // S8001 + {.chipid_max = DELIMITER, .chip_id = 0x8001, .voltage_type = CHIPID_CPU_VOLTAGE}, + // bypass + // | clkSrc + // | | P M S biuDiv4HiVol + // | | | | | | biuDiv4LoVol + // | | | | | | | dvmrMaxWgt + // | | | | | | | | iexrfCfgWrData + // | | | | | | | | | iexrfCfgWrIdxa + // | | | | | | | | | | iexrfCfgWrIdxb + // | | | | | | | | | | | exrfCfgWrIdxmuxsel + // | | | | | | | | | | | | nrgAccScaleTab(Ext) + // | | | | | | | | | | | | | lkgEstTab(Ext) + // | | | | | | | | | | | | | | dpe0DvfmTab(Ext) + // | | | | | | | | | | | | | | | + {{{CHIPID_CPU_VOLTAGE_BYPASS, 0, 0, 0, 0, 0, 2, 2, 0xf, 0, 0, 0, 0, 0x1, 0x1, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_SECUREROM,1, 1, 1, 75, 6, 2, 2, 0xf, 0, 0, 0, 0, 0x1, 0x1, 0xff}}}, // 300MHz + {{{CHIPID_CPU_VOLTAGE_396, 0, 1, 1, 66, 3, 2, 2, 0xf, 0, 0, 0, 0, 0x3d, 0x2b, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_720, 0, 1, 1, 90, 2, 2, 2, 0xf, 0, 0, 0, 0, 0x4a, 0x17, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1080, 0, 1, 1, 90, 1, 3, 3, 0xf, 0, 0, 0, 0, 0x58, 0x0e, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1440, 0, 1, 1, 60, 0, 4, 4, 0xf, 0, 0, 0, 0, 0x6b, 0x0a, 0xfb}}}, + {{{CHIPID_CPU_VOLTAGE_1800, 0, 1, 1, 75, 0, 5, 5, 0xf, 0, 0, 0, 0, 0x99, 0x08, 0xa8}}}, + {{{CHIPID_CPU_VOLTAGE_2160, 0, 1, 1, 90, 0, 5, 5, 0xf, 0, 0, 0, 0, 0xc1, 0x06, 0x7c}}}, + {{{CHIPID_CPU_VOLTAGE_2256_1core,0,1, 1, 94, 0, 5, 5, 0x2, 0, 0, 0, 0, 0xc1, 0x06, 0x77}}}, + {{{CHIPID_CPU_VOLTAGE_2256, 0, 1, 1, 94, 0, 5, 5, 0xf, 0, 0, 0, 0, 0xc1, 0x06, 0x77}}}, + {{{CHIPID_CPU_VOLTAGE_2352, 0, 1, 1, 98, 0, 5, 5, 0xf, 0, 0, 0, 0, 0xe0, 0x0d, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_2448, 0, 1, 1, 102,0, 6, 6, 0x2, 0, 0, 0, 0, 0xe0, 0x0d, 0xff}}}, + + // S8003 + {.chipid_max = DELIMITER, .chip_id = 0x8003, .voltage_type = CHIPID_CPU_VOLTAGE}, + // bypass + // | clkSrc + // | | P M S biuDiv4HiVol + // | | | | | | biuDiv4LoVol + // | | | | | | | dvmrMaxWgt + // | | | | | | | | iexrfCfgWrData + // | | | | | | | | | iexrfCfgWrIdxa + // | | | | | | | | | | iexrfCfgWrIdxb + // | | | | | | | | | | | exrfCfgWrIdxmuxsel + // | | | | | | | | | | | | nrgAccScaleTab(Ext) + // | | | | | | | | | | | | | lkgEstTab(Ext) + // | | | | | | | | | | | | | | dpe0DvfmTab(Ext) + // | | | | | | | | | | | | | | | + {{{CHIPID_CPU_VOLTAGE_BYPASS, 0, 0, 0, 0, 0, 2, 2, 0xf, 0, 0, 0, 0, 0x1, 0x1, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_SECUREROM,1, 1, 1, 75, 6, 2, 2, 0xf, 0, 0, 0, 0, 0x1, 0x1, 0xff}}}, // 300MHz + {{{CHIPID_CPU_VOLTAGE_396, 0, 1, 1, 66, 3, 2, 2, 0xf, 0, 0, 0, 0, 0x3a, 0x2c, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_600, 0, 1, 1, 75, 2, 2, 3, 0xf, 0, 0, 0, 0, 0x40, 0x1c, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_912, 0, 1, 1, 76, 1, 4, 4, 0xf, 0, 0, 0, 0, 0x4f, 0x11, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1200, 0, 1, 1,100, 1, 4, 5, 0xf, 0, 0, 0, 0, 0x5e, 0x0d, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1512, 0, 1, 1, 63, 0, 5, 6, 0xf, 0, 0, 0, 0, 0x73, 0x0a, 0xe7}}}, + {{{CHIPID_CPU_VOLTAGE_1800, 0, 1, 1, 75, 0, 6, 7, 0xf, 0, 0, 0, 0, 0x82, 0x08, 0xb6}}}, + {{{CHIPID_CPU_VOLTAGE_1848, 0, 1, 1, 77, 0, 6, 7, 0x2, 0, 0, 0, 0, 0x82, 0x08, 0xb1}}}, + {{{CHIPID_CPU_VOLTAGE_1896, 0, 1, 1, 79, 0, 6, 7, 0xf, 0, 0, 0, 0, 0xa7, 0x10, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_1992, 0, 1, 1, 83, 0, 6, 7, 0xf, 0, 0, 0, 0, 0xb2, 0x10, 0xff}}}, + {{{CHIPID_CPU_VOLTAGE_2112, 0, 1, 1, 88, 0, 7, 0, 0x2, 0, 0, 0, 0, 0xbf, 0x0f, 0xff}}}, +}; + +const struct operating_point_params *operating_point_get_params(enum chipid_voltage_index voltage_index, enum chipid_voltage_type voltage_type) +{ + uint64_t chip_id = chipid_get_chip_id(); + uint64_t chip_rev = chipid_get_chip_revision(); + uint64_t chip_id_in_array = 0; + uint64_t chip_rev_in_array = 0; + size_t size = sizeof(operating_point_params)/sizeof(operating_point_params[0]); + enum chipid_voltage_type voltage_type_in_array = CHIPID_CPU_VOLTAGE; + + size_t found = size; + for (size_t i = 0; i < size; i++) { + if (operating_point_params[i].voltage_index == DELIMITER) { + chip_id_in_array = operating_point_params[i].chip_id; + chip_rev_in_array = operating_point_params[i].chip_rev; + voltage_type_in_array = operating_point_params[i].voltage_type; + continue; + } + if ((voltage_type_in_array != voltage_type)) { + continue; + } + if (chip_rev_in_array > chip_rev) { + continue; + } + if ((operating_point_params[i].voltage_index == voltage_index) && ((chip_id_in_array == CHIP_ID_ALL) || (chip_id_in_array == chip_id))) { + found = i; + break; + } + } + if (found == size) { + panic("%s Index %d not found for chipId 0x%llx\n", + __func__, voltage_index, chip_id); + } + return &operating_point_params[found]; +} diff --git a/platform/s8000/chipid/pmgr_binning_s8000.c b/platform/s8000/chipid/pmgr_binning_s8000.c new file mode 100644 index 0000000..18e53b1 --- /dev/null +++ b/platform/s8000/chipid/pmgr_binning_s8000.c @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// +// Please update test plan version to know what is the reference. +// +// Maui Test Plan Version 2.26 +// Maui Tunables Specification Revision 0.80 +// + +#include +#include + +// +// Fuses in MINIPMGR are linearly mapped +// +static const struct pmgr_binning_fuse_to_register minipmgr_fuse_register[] = { + // binning_low + // | binning_high + // | | register_low + // | | | register_64bit + // | | | | register_address + // | | | | | + { 0, 369, 0, 0, AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_OFFSET}, + { 0, 0, 0, 0, 0}, +}; + +// +// Fuses in ACC (UDR) are sparsely mapped +// +static const struct pmgr_binning_fuse_to_register acc_fuse_register[] = { + // binning_low + // | binning_high + // | | register_low + // | | | register_64bit + // | | | | register_address + // | | | | | + { 0, 2, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_EXT2_OFFSET}, + { 3, 6, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_EXT2_OFFSET}, + { 7, 9, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST1_EXT2_OFFSET}, + { 10, 13, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST1_EXT2_OFFSET}, + { 14, 16, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST2_EXT2_OFFSET}, + { 17, 20, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST2_EXT2_OFFSET}, + { 21, 23, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST3_EXT2_OFFSET}, + { 24, 27, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST3_EXT2_OFFSET}, + { 28, 30, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST4_EXT2_OFFSET}, + { 31, 34, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST4_EXT2_OFFSET}, + { 35, 37, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST5_EXT2_OFFSET}, + { 38, 41, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST5_EXT2_OFFSET}, + { 42, 44, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST6_EXT2_OFFSET}, + { 45, 48, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST6_EXT2_OFFSET}, + { 40, 51, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST7_EXT2_OFFSET}, + { 52, 55, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST7_EXT2_OFFSET}, + { 56, 58, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST8_EXT2_OFFSET}, + { 59, 62, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST8_EXT2_OFFSET}, + { 112, 114,29, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 115, 119,24, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 120, 127,16, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 0, 0, 0, 0, 0}, +}; + + +const struct pmgr_binning_mode_to_fuse pmgr_binning_mode_to_fuse_data[] = { + // + // CPU + // + + //type + //| mode + //| | bingroup + //| | | low + //| | | | high + //| | | | | fuse_to_register + //| | | | | | + {PMGR_BINNING_CPU, 1, PMGR_BINNING_GROUP_ALL, 7, 13, acc_fuse_register}, + {PMGR_BINNING_CPU, 2, PMGR_BINNING_GROUP_ALL, 14, 20, acc_fuse_register}, + {PMGR_BINNING_CPU, 3, PMGR_BINNING_GROUP_ALL, 21, 27, acc_fuse_register}, + {PMGR_BINNING_CPU, 4, PMGR_BINNING_GROUP_ALL, 28, 34, acc_fuse_register}, + {PMGR_BINNING_CPU, 5, PMGR_BINNING_GROUP_ALL, 35, 41, acc_fuse_register}, + {PMGR_BINNING_CPU, 6, PMGR_BINNING_GROUP_ALL, 42, 48, acc_fuse_register}, + {PMGR_BINNING_CPU, 7, PMGR_BINNING_GROUP_ALL, 49, 55, acc_fuse_register}, + {PMGR_BINNING_CPU, 8, PMGR_BINNING_GROUP_ALL, 56, 62, acc_fuse_register}, + + // + // GPU/SOC + // + + //type + //| mode + //| | bingroup + //| | | low + //| | | | high + //| | | | | fuse_to_register + //| | | | | | + {PMGR_BINNING_GPU, 1, PMGR_BINNING_GROUP_ALL, 238, 244, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 2, PMGR_BINNING_GROUP_ALL, 245, 251, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 3, PMGR_BINNING_GROUP_ALL, 252, 258, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 4, PMGR_BINNING_GROUP_ALL, 259, 265, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 5, PMGR_BINNING_GROUP_ALL, 217, 223, minipmgr_fuse_register}, + + {PMGR_BINNING_SOC, 1, PMGR_BINNING_GROUP_ALL, 224, 230, minipmgr_fuse_register}, + {PMGR_BINNING_SOC, 2, PMGR_BINNING_GROUP_ALL, 231, 237, minipmgr_fuse_register}, + + {PMGR_BINNING_BASE, 0, PMGR_BINNING_GROUP_ALL, 115, 119, acc_fuse_register}, + + {PMGR_BINNING_REV, 0, PMGR_BINNING_GROUP_ALL, 142, 147, minipmgr_fuse_register}, + + {PMGR_BINNING_GROUP, 0, PMGR_BINNING_GROUP_ALL, 268, 269, minipmgr_fuse_register}, + + {PMGR_BINNING_END_OF_LIST, 0, PMGR_BINNING_GROUP_ALL, 0, 0, NULL}, +}; + +// +// Group-specific entries must come before the corresponding entry with PMGR_BINNING_GROUP_ALL. +// +const struct pmgr_binning_voltage_index_to_config pmgr_binning_voltage_index_to_config_data[] = { + // voltage index + // | safe voltage + // | | mode + // | | | type + // | | | | binning group + // | | | | | fuse revision minimun + // | | | | | | + {CHIPID_CPU_VOLTAGE_BYPASS, 610, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_SECUREROM, 610, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_396, 610, 1, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_600, 641, 2, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_912, 742, 3, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1200, 836, 4, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1512, 937, 5, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1800, 1090, 6, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1848, 1090, 6, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1896, 1090, 7, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1992, 1100, 8, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + + {CHIPID_CPU_VOLTAGE_396_WA, 610, 1, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1200_WA, 836, 4, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1512_WA, 937, 5, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + + // SEG-characterization + {CHIPID_CPU_VOLTAGE_2112, 1100, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + + {CHIPID_SOC_VOLTAGE_BYPASS, 725, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_SOC_VOLTAGE_SECUREROM, 725, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_SOC_VOLTAGE_VMIN, 725, 1, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_SOC_VOLTAGE_VNOM, 825, 2, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + + {CHIPID_GPU_VOLTAGE_OFF, 0, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_340, 700, 1, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_474, 800, 2, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_550, 920, 3, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_616, 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_723, 1030, 4, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + // SEG-characterization + {CHIPID_GPU_VOLTAGE_804, 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_850, 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_900, 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, +}; + +// +// Safe voltage of 0 and binning mode != PMGR_BINNING_MODE_NONE +// means data are store in pmgr_binning_mode_to_const_data +// +const struct pmgr_binning_voltage_config pmgr_binning_voltage_config_sram_data[] = { + // safe voltage (0 means lookup data in pmgr_binning_mode_to_const_data) + // | mode + // | | type + // | | | + [CHIPID_CPU_VOLTAGE_BYPASS] = { 800, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_SECUREROM] = { 800, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_396] = { 0, 1, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_600] = { 0, 2, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_912] = { 0, 3, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1200] = { 0, 4, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1512] = { 0, 5, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1800] = { 0, 6, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1848] = { 0, 6, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1896] = {1090, 7, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1992] = {1100, 8, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_2112] = {1100, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_396_WA] = { 0, 1, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1200_WA] = { 0, 4, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1512_WA] = { 0, 5, PMGR_BINNING_CPU_SRAM}, + + [CHIPID_GPU_VOLTAGE_OFF] = { 0, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_340] = { 0, 1, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_474] = { 0, 2, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_550] = { 0, 3, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_616] = { 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_723] = { 0, 4, PMGR_BINNING_GPU_SRAM}, + // SEG-characterization + [CHIPID_GPU_VOLTAGE_804] = { 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_850] = { 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_900] = { 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + + [CHIPID_VOLTAGE_FIXED] = {850, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SRAM}, +}; + +// +// Group-specific entries must come before the corresponding entry with PMGR_BINNING_GROUP_ALL. +// +const struct pmgr_binning_mode_to_const pmgr_binning_mode_to_const_data[] = { + // Voltage + // | Mode + // | | Type + // | | | Binning group + // | | | | fuse revision minimun + // | | | | | + { 810, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_N69U, 15}, + { 940, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_N69U, 15}, + {1055, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_N69U, 15}, + + { 830, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 9}, + { 960, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 9}, + {1025, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 9}, + + { 840, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 8}, + { 940, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 8}, + {1030, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 8}, + + { 800, 1, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 2, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 3, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 836, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 937, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1090, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + + { 830, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69U, 15}, + { 855, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69U, 15}, + { 965, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69U, 15}, + + { 820, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 9}, + { 835, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 9}, + { 955, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 9}, + + // GPU fuse rev 8 GPU_SRAM = fuse rev 0 (safe voltage) + + { 800, 1, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 920, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1030, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, +}; + +static const struct pmgr_binning_voltage_index_to_offset n69u_cpu_offsets[] = { +// voltage index +// | fuse revision minimum +// | | offset +// | | | + {CHIPID_CPU_VOLTAGE_912, 0, 25}, + {CHIPID_CPU_VOLTAGE_1200, 0, 15}, + {CHIPID_CPU_VOLTAGE_1200_WA, 0, 15}, +}; + +static const struct pmgr_binning_voltage_index_to_offset n69u_gpu_offsets[] = { +// voltage index +// | fuse revision minimum +// | | offset +// | | | + {CHIPID_GPU_VOLTAGE_550, 0, 20}, + {CHIPID_GPU_VOLTAGE_723, 0, 30}, +}; + +const struct pmgr_binning_board_id_to_offsets pmgr_binning_board_id_to_offsets_data[] = { +// type +// | voltage offset array +// | | voltage offset array size +// | | | chip rev +// | | | | board id +// | | | | | binning group +// | | | | | | + {PMGR_BINNING_CPU, n69u_cpu_offsets, sizeof(n69u_cpu_offsets)/sizeof(n69u_cpu_offsets[0]), CHIP_REVISION_C0, N69U_AP_BOARD_ID, PMGR_BINNING_GROUP_ALL}, + {PMGR_BINNING_CPU, n69u_cpu_offsets, sizeof(n69u_cpu_offsets)/sizeof(n69u_cpu_offsets[0]), CHIP_REVISION_C0, N69U_DEV_BOARD_ID, PMGR_BINNING_GROUP_ALL}, + {PMGR_BINNING_GPU, n69u_gpu_offsets, sizeof(n69u_gpu_offsets)/sizeof(n69u_gpu_offsets[0]), CHIP_REVISION_C0, N69U_AP_BOARD_ID, PMGR_BINNING_NOTFOUND}, + {PMGR_BINNING_GPU, n69u_gpu_offsets, sizeof(n69u_gpu_offsets)/sizeof(n69u_gpu_offsets[0]), CHIP_REVISION_C0, N69U_DEV_BOARD_ID, PMGR_BINNING_NOTFOUND}, +}; + +// .voltages = {volAdj0, volAdj1, volAdj2, volAdj3, dvfmMaxAdj, dvmrAdj0, dvmrAdj1, dvmrAdj2} + +const struct pmgr_binning_voltadj_entry pmgr_binning_voltadj_entry_data[] = { + // + // CPU + // + {CHIPID_CPU_VOLTAGE_BYPASS, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_SOC_VOLTAGE_SECUREROM, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 0, 0, 0, 0}}, + + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | dvfmMaxAdj + // | | | | | dvmrAdj0 + // | | | | | | dvmrAdj1 + // | | | | | | | dvmrAdj2 + // | | | | | | | | + // S8000 >= C0 (fuse rev >= 10) | | | | | | | | + {CHIPID_CPU_VOLTAGE_396, CHIP_REVISION_B0,10, .voltages = { 0, 9375, 18750, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_396_WA,CHIP_REVISION_B0,10,.voltages = { 0, 9375, 18750, 18750, 40625, 0, 0, 0}}, + // | | | | | | | | + // S8000 >= B0 | | | | | | | | + {CHIPID_CPU_VOLTAGE_396, CHIP_REVISION_B0, 0, .voltages = { 0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_600, CHIP_REVISION_B0, 0, .voltages = { 0, 3125, 21875, 21875, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_912, CHIP_REVISION_B0, 0, .voltages = { 0, 3125, 18750, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1200, CHIP_REVISION_B0, 0, .voltages = { 0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1512, CHIP_REVISION_B0, 0, .voltages = { 0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1800, CHIP_REVISION_B0, 0, .voltages = { 28125, 28125, 0, 0, 40625, 12500, 12500, 0}}, + {CHIPID_CPU_VOLTAGE_1848, CHIP_REVISION_B0, 0, .voltages = { 28125, 28125, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_396_WA,CHIP_REVISION_B0,0, .voltages = { 0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1200_WA,CHIP_REVISION_B0,0,.voltages = { 0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1512_WA,CHIP_REVISION_B0,0,.voltages = { 0, 0, 0, 0, 40625, 0, 0, 0}}, + + // S8000 >= A1 + {CHIPID_CPU_VOLTAGE_396, CHIP_REVISION_A1, 0, .voltages = {0, 9375, 18750, 25000, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_600, CHIP_REVISION_A1, 0, .voltages = {0, 9375, 18750, 25000, 40625, 3125, 3125, 0}}, + {CHIPID_CPU_VOLTAGE_912, CHIP_REVISION_A1, 0, .voltages = {0, 6250, 12500, 18750, 40625, 6250, 6250, 0}}, + {CHIPID_CPU_VOLTAGE_1200, CHIP_REVISION_A1, 0, .voltages = {0, 6250, 12500, 18750, 40625, 9375, 9375, 0}}, + {CHIPID_CPU_VOLTAGE_1512, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 18750,15625, 3125}}, + {CHIPID_CPU_VOLTAGE_1800, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 25000,21875, 3125}}, + {CHIPID_CPU_VOLTAGE_1896, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 3125, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1992, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 28125,25000, 3125}}, + {CHIPID_CPU_VOLTAGE_2112, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 3125, 0, 0}}, + + // S8000 A0 + {CHIPID_CPU_VOLTAGE_396, CHIP_REVISION_A0, 0, .voltages = {0, 9375, 18750, 25000, 40620, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_600, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 0, 0, 0, 0}}, + + // + // SOC + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | N/A + // | | | | | N/A + // | | | | | | N/A + // | | | | | | | N/A + // | | | | | | | | + {CHIPID_SOC_VOLTAGE_VMIN, CHIP_REVISION_B0, 0, .voltages = {0, 0, 18750, 18750,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_VNOM, CHIP_REVISION_B0, 0, .voltages = {0, 0, 12500, 12500,0,0,0,0}}, + + {CHIPID_SOC_VOLTAGE_VMIN, CHIP_REVISION_A0, 0, .voltages = {0, 12500, 25000, 25000,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_VNOM, CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 12500,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_BYPASS,CHIP_REVISION_A0,0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_SECUREROM,CHIP_REVISION_A0,0,.voltages={0, 0, 0, 0,0,0,0,0}}, + + // + // GFX + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | N/A + // | | | | | N/A + // | | | | | | N/A + // | | | | | | | N/A + // | | | | | | | | + {CHIPID_GPU_VOLTAGE_340, CHIP_REVISION_B0, 0, .voltages = {0, 12500, 21875, 25000,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_474, CHIP_REVISION_B0, 0, .voltages = {0, 6250, 15625, 12500,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_550, CHIP_REVISION_B0, 0, .voltages = {0, 0, 9375, 0,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_723, CHIP_REVISION_B0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + + + {CHIPID_GPU_VOLTAGE_340, CHIP_REVISION_A1, 0, .voltages = {0, 12500, 25000, 25000,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_474, CHIP_REVISION_A1, 0, .voltages = {0, 6250, 12500, 12500,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_550, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_723, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, +}; + + +const uint32_t pmgr_binning_voltage_config_sram_data_size = +sizeof(pmgr_binning_voltage_config_sram_data)/sizeof(pmgr_binning_voltage_config_sram_data[0]); +const uint32_t pmgr_binning_mode_to_const_data_size = sizeof(pmgr_binning_mode_to_const_data)/sizeof(pmgr_binning_mode_to_const_data[0]); +const uint32_t pmgr_binning_voltadj_entry_data_size = sizeof(pmgr_binning_voltadj_entry_data) / sizeof(pmgr_binning_voltadj_entry_data[0]); +const uint32_t pmgr_binning_voltage_index_to_config_data_size = sizeof(pmgr_binning_voltage_index_to_config_data)/sizeof(pmgr_binning_voltage_index_to_config_data[0]); +const uint32_t pmgr_binning_board_id_to_offsets_data_size = sizeof(pmgr_binning_board_id_to_offsets_data)/sizeof(pmgr_binning_board_id_to_offsets_data[0]); diff --git a/platform/s8000/chipid/pmgr_binning_s8001.c b/platform/s8000/chipid/pmgr_binning_s8001.c new file mode 100644 index 0000000..d6e9857 --- /dev/null +++ b/platform/s8000/chipid/pmgr_binning_s8001.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// +// Please update test plan version to know what is the reference. +// +// Elba Test Plan Version 1.6 +// Elba Tunables Specification Revision 0.46 +// + +#include +#include + +// +// Fuses in MINIPMGR are linearly mapped +// +static const struct pmgr_binning_fuse_to_register minipmgr_fuse_register[] = { + // binning_low + // | binning_high + // | | register_low + // | | | register_64bit + // | | | | register_address + // | | | | | + { 0, 369, 0, 0, AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_OFFSET}, + { 0, 0, 0, 0, 0}, +}; + +// +// Fuses in ACC (UDR) are sparsely mapped +// +static const struct pmgr_binning_fuse_to_register acc_fuse_register[] = { + // binning_low + // | binning_high + // | | register_low + // | | | register_64bit + // | | | | register_address + // | | | | | + { 0, 2, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_EXT2_OFFSET}, + { 3, 6, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_EXT2_OFFSET}, + { 7, 9, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST1_EXT2_OFFSET}, + { 10, 13, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST1_EXT2_OFFSET}, + { 14, 16, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST2_EXT2_OFFSET}, + { 17, 20, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST2_EXT2_OFFSET}, + { 21, 23, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST3_EXT2_OFFSET}, + { 24, 27, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST3_EXT2_OFFSET}, + { 28, 30, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST4_EXT2_OFFSET}, + { 31, 34, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST4_EXT2_OFFSET}, + { 35, 37, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST5_EXT2_OFFSET}, + { 38, 41, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST5_EXT2_OFFSET}, + { 42, 44, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST6_EXT2_OFFSET}, + { 45, 48, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST6_EXT2_OFFSET}, + { 40, 51, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST7_EXT2_OFFSET}, + { 52, 55, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST7_EXT2_OFFSET}, + { 56, 58, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST8_EXT2_OFFSET}, + { 59, 62, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST8_EXT2_OFFSET}, + { 112, 114,29, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 115, 119,24, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 120, 127,16, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 0, 0, 0, 0, 0}, +}; + +const struct pmgr_binning_mode_to_fuse pmgr_binning_mode_to_fuse_data[] = { + // + // CPU + // + + //type + //| mode + //| | bingroup + //| | | low + //| | | | high + //| | | | | fuse_to_register + //| | | | | | + {PMGR_BINNING_CPU, 1, PMGR_BINNING_GROUP_ALL, 0, 6, acc_fuse_register}, + {PMGR_BINNING_CPU, 2, PMGR_BINNING_GROUP_ALL, 7, 13, acc_fuse_register}, + {PMGR_BINNING_CPU, 3, PMGR_BINNING_GROUP_ALL, 14, 20, acc_fuse_register}, + {PMGR_BINNING_CPU, 4, PMGR_BINNING_GROUP_ALL, 21, 27, acc_fuse_register}, + {PMGR_BINNING_CPU, 5, PMGR_BINNING_GROUP_ALL, 28, 34, acc_fuse_register}, + {PMGR_BINNING_CPU, 6, PMGR_BINNING_GROUP_ALL, 35, 41, acc_fuse_register}, + {PMGR_BINNING_CPU, 7, PMGR_BINNING_GROUP_ALL, 42, 48, acc_fuse_register}, + {PMGR_BINNING_CPU, 8, PMGR_BINNING_GROUP_ALL, 49, 55, acc_fuse_register}, + + // + // GPU/SOC + // + + //type + //| mode + //| | bingroup + //| | | low + //| | | | high + //| | | | | fuse_to_register + //| | | | | | + {PMGR_BINNING_GPU, 1, PMGR_BINNING_GROUP_ALL, 238, 244, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 2, PMGR_BINNING_GROUP_ALL, 245, 251, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 3, PMGR_BINNING_GROUP_ALL, 252, 258, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 4, PMGR_BINNING_GROUP_ALL, 259, 265, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 5, PMGR_BINNING_GROUP_ALL, 266, 272, minipmgr_fuse_register}, + + {PMGR_BINNING_SOC, 1, PMGR_BINNING_GROUP_ALL, 224, 230, minipmgr_fuse_register}, + {PMGR_BINNING_SOC, 2, PMGR_BINNING_GROUP_ALL, 231, 237, minipmgr_fuse_register}, + + {PMGR_BINNING_BASE, 0, PMGR_BINNING_GROUP_ALL, 115, 119, acc_fuse_register}, + + {PMGR_BINNING_REV, 0, PMGR_BINNING_GROUP_ALL, 142, 147, minipmgr_fuse_register}, + + + {PMGR_BINNING_END_OF_LIST, 0, PMGR_BINNING_GROUP_ALL, 0, 0, NULL}, +}; + +// +// Group-specific entries must come before the corresponding entry with PMGR_BINNING_GROUP_ALL. +// +const struct pmgr_binning_voltage_index_to_config pmgr_binning_voltage_index_to_config_data[] = { + // voltage index + // | safe voltage + // | | mode + // | | | type + // | | | | binning group + // | | | | | fuse revision minimun + // | | | | | | + {CHIPID_CPU_VOLTAGE_BYPASS, 606, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_SECUREROM, 606, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_396, 606, 1, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_720, 606, 2, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1080, 720, 3, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1440, 833, 4, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1800, 947, 5, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_2160, 1060, 6, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_2256_1core, 1060, 6, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_2256, 1090, 7, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_2352, 1130, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_2448, 1130, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + + // There is only one SOC voltage state on S8001 + // But Test Plan named MS001 for J99a and MS002 for J127 + // and this is like S8000 which call MS1 for VMIN and MS2 for VNOM + {CHIPID_SOC_VOLTAGE_VMIN, 800, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_SOC_VOLTAGE_VNOM, 900, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + + {CHIPID_GPU_VOLTAGE_OFF, 0, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_360, 670, 1, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_520, 800, 2, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_650, 920, 3, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_723, 1030, 4, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_800, 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_804, 1100, 5, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, +}; + +// +// Safe voltage of 0 and binning mode != PMGR_BINNING_MODE_NONE +// means data are store in pmgr_binning_mode_to_const_data +// +const struct pmgr_binning_voltage_config pmgr_binning_voltage_config_sram_data[] = { + // safe voltage (0 means lookup data in pmgr_binning_mode_to_const_data) + // | mode + // | | type + // | | | + [CHIPID_CPU_VOLTAGE_396] = { 0, 1, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_720] = { 0, 2, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1080] = { 0, 3, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1440] = { 0, 4, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1800] = { 0, 5, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_2160] = { 0, 6, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_2256_1core] = { 0, 7, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_2256] = { 1090, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_2352] = { 1130, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_2448] = { 1130, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + + [CHIPID_GPU_VOLTAGE_OFF] = { 0, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_360] = { 0, 1, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_520] = { 0, 2, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_650] = { 0, 3, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_723] = { 0, 4, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_800] = { 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_804] = { 0, 5, PMGR_BINNING_GPU_SRAM}, + + [CHIPID_VOLTAGE_FIXED] = { 900, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SRAM}, +}; + +// +// Group-specific entries must come before the corresponding entry with PMGR_BINNING_GROUP_ALL. +// +const struct pmgr_binning_mode_to_const pmgr_binning_mode_to_const_data[] = { + // Voltage + // | Mode + // | | Type + // | | | Binning group + // | | | | fuse revision minimun + // | | | | | + { 820, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 8}, + { 930, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 8}, + { 990, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 8}, + {1000, 7, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 8}, + + { 835, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 6}, + { 885, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 6}, + {1000, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 6}, + {1000, 7, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 6}, + + { 800, 1, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 2, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 3, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 833, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 947, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1060, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1060, 7, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + + {1100, 5, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 10}, + + { 850, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 6}, + { 930, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 6}, + {1000, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 6}, + + { 800, 1, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 920, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1030, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1100, 5, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, +}; + +const struct pmgr_binning_board_id_to_offsets pmgr_binning_board_id_to_offsets_data[] = { +// type +// | voltage offset array +// | | voltage offset array size +// | | | chip rev +// | | | | board id +// | | | | | binning group +// | | | | | | +}; + +// .voltages = {volAdj0, volAdj1, volAdj2, volAdj3, dvfmMaxAdj, dvmrAdj0, dvmrAdj1, dvmrAdj2} + +const struct pmgr_binning_voltadj_entry pmgr_binning_voltadj_entry_data[] = { + // + // CPU + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | dvfmMaxAdj + // | | | | | dvmrAdj0 + // | | | | | | dvmrAdj1 + // | | | | | | | dvmrAdj2 + // | | | | | | | | + {CHIPID_CPU_VOLTAGE_396 , CHIP_REVISION_B0, 0, .voltages = {0, 9375, 18750, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_720 , CHIP_REVISION_B0, 0, .voltages = {0, 0, 18750, 21875, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1080, CHIP_REVISION_B0, 0, .voltages = {0, 0, 15625, 15625, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1440, CHIP_REVISION_B0, 0, .voltages = {0, 0, 12500, 12500, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1800, CHIP_REVISION_B0, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_2160, CHIP_REVISION_B0, 0, .voltages = {21875,0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_2256_1core,CHIP_REVISION_B0,0,.voltages={21875,0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_2256, CHIP_REVISION_B0, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_2352, CHIP_REVISION_B0, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_2448, CHIP_REVISION_B0, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + + + {CHIPID_CPU_VOLTAGE_BYPASS,CHIP_REVISION_A0,0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_SOC_VOLTAGE_SECUREROM,CHIP_REVISION_A0,0,.voltages={0, 0, 0, 0, 0, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_396 , CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_720 , CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1080, CHIP_REVISION_A0, 0, .voltages = {0, 3125, 6250, 12500, 40625, 6250, 6250, 0}}, + {CHIPID_CPU_VOLTAGE_1440, CHIP_REVISION_A0, 0, .voltages = {0, 3125, 6250, 12500, 40625, 9375, 9375, 0}}, + {CHIPID_CPU_VOLTAGE_1800, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 18750, 15625, 3125}}, + {CHIPID_CPU_VOLTAGE_2160, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 25000, 21875, 3125}}, + {CHIPID_CPU_VOLTAGE_2256_1core,CHIP_REVISION_A0,0,.voltages={0, 0, 0, 0, 40625, 3125, 0, 0}}, + {CHIPID_CPU_VOLTAGE_2256, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 25000, 21875, 3125}}, + {CHIPID_CPU_VOLTAGE_2352, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 28125, 25000, 3125}}, + {CHIPID_CPU_VOLTAGE_2448, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 3125, 0, 0}}, + + // GFX + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | N/A + // | | | | | N/A + // | | | | | | N/A + // | | | | | | | N/A + // | | | | | | | | + {CHIPID_GPU_VOLTAGE_360, CHIP_REVISION_B0, 0, .voltages = {0, 3125, 18750, 21875,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_520, CHIP_REVISION_B0, 0, .voltages = {0, 0, 12500, 12500,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_650, CHIP_REVISION_B0, 0, .voltages = {0, 0, 6125, 6125,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_723, CHIP_REVISION_B0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_804, CHIP_REVISION_B0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + + {CHIPID_GPU_VOLTAGE_360, CHIP_REVISION_A0, 0, .voltages = {0, 12500, 25000, 25000,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_520, CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 12500,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_650, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_723, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_804, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, +}; + +const uint32_t pmgr_binning_voltage_config_sram_data_size = +sizeof(pmgr_binning_voltage_config_sram_data)/sizeof(pmgr_binning_voltage_config_sram_data[0]); +const uint32_t pmgr_binning_mode_to_const_data_size = sizeof(pmgr_binning_mode_to_const_data)/sizeof(pmgr_binning_mode_to_const_data[0]); +const uint32_t pmgr_binning_voltadj_entry_data_size = sizeof(pmgr_binning_voltadj_entry_data) / sizeof(pmgr_binning_voltadj_entry_data[0]); +const uint32_t pmgr_binning_voltage_index_to_config_data_size = sizeof(pmgr_binning_voltage_index_to_config_data)/sizeof(pmgr_binning_voltage_index_to_config_data[0]); +const uint32_t pmgr_binning_board_id_to_offsets_data_size = sizeof(pmgr_binning_board_id_to_offsets_data)/sizeof(pmgr_binning_board_id_to_offsets_data[0]); diff --git a/platform/s8000/chipid/pmgr_binning_s8003.c b/platform/s8000/chipid/pmgr_binning_s8003.c new file mode 100644 index 0000000..5c20601 --- /dev/null +++ b/platform/s8000/chipid/pmgr_binning_s8003.c @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// +// Please update test plan version to know what is the reference. +// +// Malta Test Plan Version 1.6 +// Malta Tunables Specification Revision 0.47 (for volt_adj) +// + +#include +#include + +// +// Fuses in MINIPMGR are linearly mapped +// +static const struct pmgr_binning_fuse_to_register minipmgr_fuse_register[] = { + // binning_low + // | binning_high + // | | register_low + // | | | register_64bit + // | | | | register_address + // | | | | | + { 0, 369, 0, 0, AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_OFFSET}, + { 0, 0, 0, 0, 0}, +}; + +// +// Fuses in ACC (UDR) are sparsely mapped +// +static const struct pmgr_binning_fuse_to_register acc_fuse_register[] = { + // binning_low + // | binning_high + // | | register_low + // | | | register_64bit + // | | | | register_address + // | | | | | + { 0, 2, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_EXT2_OFFSET}, + { 3, 6, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_EXT2_OFFSET}, + { 7, 9, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST1_EXT2_OFFSET}, + { 10, 13, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST1_EXT2_OFFSET}, + { 14, 16, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST2_EXT2_OFFSET}, + { 17, 20, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST2_EXT2_OFFSET}, + { 21, 23, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST3_EXT2_OFFSET}, + { 24, 27, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST3_EXT2_OFFSET}, + { 28, 30, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST4_EXT2_OFFSET}, + { 31, 34, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST4_EXT2_OFFSET}, + { 35, 37, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST5_EXT2_OFFSET}, + { 38, 41, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST5_EXT2_OFFSET}, + { 42, 44, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST6_EXT2_OFFSET}, + { 45, 48, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST6_EXT2_OFFSET}, + { 49, 51, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST7_EXT2_OFFSET}, + { 52, 55, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST7_EXT2_OFFSET}, + { 56, 58, 0, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST8_EXT2_OFFSET}, + { 59, 62, 4, 1, ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST8_EXT2_OFFSET}, + { 112, 114,29, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 115, 119,24, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 120, 127,16, 0, ACC_BASE_ADDR + ACC_PWRCTL_EFUSE_REV_OFFSET}, + { 0, 0, 0, 0, 0}, +}; + +// +// Group-specific entries must come before the corresponding entry with PMGR_BINNING_GROUP_ALL. +// + +const struct pmgr_binning_mode_to_fuse pmgr_binning_mode_to_fuse_data[] = { + // + // CPU + // + + //type + //| mode + //| | bingroup + //| | | low + //| | | | high + //| | | | | fuse_to_register + //| | | | | | + {PMGR_BINNING_CPU, 1, PMGR_BINNING_GROUP_ALL, 0, 6, acc_fuse_register}, + {PMGR_BINNING_CPU, 2, PMGR_BINNING_GROUP_ALL, 7, 13, acc_fuse_register}, + {PMGR_BINNING_CPU, 3, PMGR_BINNING_GROUP_ALL, 14, 20, acc_fuse_register}, + {PMGR_BINNING_CPU, 4, PMGR_BINNING_GROUP_ALL, 21, 27, acc_fuse_register}, + {PMGR_BINNING_CPU, 5, PMGR_BINNING_GROUP_ALL, 28, 34, acc_fuse_register}, + {PMGR_BINNING_CPU, 6, PMGR_BINNING_GROUP_ALL, 35, 41, acc_fuse_register}, + {PMGR_BINNING_CPU, 7, PMGR_BINNING_GROUP_ALL, 42, 48, acc_fuse_register}, + {PMGR_BINNING_CPU, 8, PMGR_BINNING_GROUP_ALL, 49, 55, acc_fuse_register}, + {PMGR_BINNING_CPU, 9, PMGR_BINNING_GROUP_ALL, 56, 62, acc_fuse_register}, + + // + // GPU/SOC + // + + //type + //| mode + //| | bingroup + //| | | low + //| | | | high + //| | | | | fuse_to_register + //| | | | | | + {PMGR_BINNING_GPU, 1, PMGR_BINNING_GROUP_ALL, 238, 244, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 2, PMGR_BINNING_GROUP_ALL, 245, 251, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 3, PMGR_BINNING_GROUP_ALL, 252, 258, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 4, PMGR_BINNING_GROUP_ALL, 259, 265, minipmgr_fuse_register}, + {PMGR_BINNING_GPU, 5, PMGR_BINNING_GROUP_ALL, 266, 272, minipmgr_fuse_register}, + + {PMGR_BINNING_SOC, 1, PMGR_BINNING_GROUP_ALL, 224, 230, minipmgr_fuse_register}, + {PMGR_BINNING_SOC, 2, PMGR_BINNING_GROUP_ALL, 231, 237, minipmgr_fuse_register}, + + {PMGR_BINNING_BASE, 0, PMGR_BINNING_GROUP_ALL, 115, 119, acc_fuse_register}, + + {PMGR_BINNING_REV, 0, PMGR_BINNING_GROUP_ALL, 142, 147, minipmgr_fuse_register}, + + {PMGR_BINNING_GROUP, 0, PMGR_BINNING_GROUP_ALL, 318, 319, minipmgr_fuse_register}, + + {PMGR_BINNING_END_OF_LIST, 0, PMGR_BINNING_GROUP_ALL, 0, 0, NULL}, +}; + +// +// Group-specific entries must come before the corresponding entry with PMGR_BINNING_GROUP_ALL. +// +const struct pmgr_binning_voltage_index_to_config pmgr_binning_voltage_index_to_config_data[] = { + // voltage index + // | safe voltage + // | | mode + // | | | type + // | | | | binning group + // | | | | | fuse revision minimun + // | | | | | | + {CHIPID_CPU_VOLTAGE_BYPASS, 606, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_SECUREROM, 606, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_396, 606, 1, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_600, 606, 2, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_912, 667, 3, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1200, 757, 4, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1512, 856, 5, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1800, 947, 6, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1848, 977, 6, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + // SEG-characterization + {CHIPID_CPU_VOLTAGE_1896, 977, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_1992, 1007, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_CPU_VOLTAGE_2112, 1045, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU, PMGR_BINNING_GROUP_ALL, 0}, + + {CHIPID_SOC_VOLTAGE_BYPASS, 670, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_SOC_VOLTAGE_SECUREROM, 670, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_SOC_VOLTAGE_VMIN, 670, 1, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_SOC_VOLTAGE_VNOM, 800, 2, PMGR_BINNING_SOC, PMGR_BINNING_GROUP_ALL, 0}, + + {CHIPID_GPU_VOLTAGE_OFF, 0, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_340, 670, 1, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_474, 800, 2, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_550, 920, 3, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_723, 1030, 4, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_804, 1080, 5, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + // SEG-characterization + {CHIPID_GPU_VOLTAGE_850, 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, + {CHIPID_GPU_VOLTAGE_900, 1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU, PMGR_BINNING_GROUP_ALL, 0}, +}; + +// +// Safe voltage of 0 and binning mode != PMGR_BINNING_MODE_NONE +// means data are store in pmgr_binning_mode_to_const_data +// +const struct pmgr_binning_voltage_config pmgr_binning_voltage_config_sram_data[] = { + // safe voltage (0 means lookup data in pmgr_binning_mode_to_const_data) + // | mode + // | | type + // | | | + [CHIPID_CPU_VOLTAGE_BYPASS] = { 800, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_SECUREROM] = { 800, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_396] = { 0, 1, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_600] = { 0, 2, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_912] = { 0, 3, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1200] = { 0, 4, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1512] = { 0, 5, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1800] = { 0, 6, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1848] = { 0, 6, PMGR_BINNING_CPU_SRAM}, + // SEG-characterization + [CHIPID_CPU_VOLTAGE_1896] = { 977, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_1992] = {1007, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + [CHIPID_CPU_VOLTAGE_2112] = {1045, PMGR_BINNING_MODE_NONE, PMGR_BINNING_CPU_SRAM}, + + [CHIPID_GPU_VOLTAGE_OFF] = { 0, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_340] = { 0, 1, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_474] = { 0, 2, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_550] = { 0, 3, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_723] = { 0, 4, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_804] = { 0, 5, PMGR_BINNING_GPU_SRAM}, + // SEG-characterization + [CHIPID_GPU_VOLTAGE_850] = {1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + [CHIPID_GPU_VOLTAGE_900] = {1030, PMGR_BINNING_MODE_NONE, PMGR_BINNING_GPU_SRAM}, + + [CHIPID_VOLTAGE_FIXED] = { 900, PMGR_BINNING_MODE_NONE, PMGR_BINNING_SRAM}, +}; + + +// +// SRAM has 3 "safe voltage" one from fuse rev 0,1,2, one for fuse rev 3,4 and one from fuse rev 5. +// Group-specific entries must come before the corresponding entry with PMGR_BINNING_GROUP_ALL. +// +const struct pmgr_binning_mode_to_const pmgr_binning_mode_to_const_data[] = { + // voltage + // | mode + // | | type + // | | | binning group + // | | | | fuse revision minimun + // | | | | | + { 800, 1, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 800, 2, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 800, 3, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 800, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 840, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 915, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + + { 800, 1, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + { 800, 2, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + { 800, 3, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + { 840, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + { 940, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + { 960, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + + { 800, 1, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 2, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 3, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 4, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 852, 5, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 947, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 915, 6, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1060, 7, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1130, 8, PMGR_BINNING_CPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + + // GPU - N69 + { 865, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 5}, + { 895, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 5}, + {1005, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 5}, + + { 865, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 3}, + { 895, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 3}, + {1005, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 3}, + + { 865, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 0}, + { 895, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 0}, + {1005, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_N69, 0}, + + // GPU - ALL + { 800, 1, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 840, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 875, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + { 985, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 5}, + + { 800, 1, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + { 800, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + { 920, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + {1025, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 3}, + + { 800, 1, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 800, 2, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + { 920, 3, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1030, 4, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, + {1080, 5, PMGR_BINNING_GPU_SRAM, PMGR_BINNING_GROUP_ALL, 0}, +}; + +static const struct pmgr_binning_voltage_index_to_offset n69_cpu_offsets[] = { +// voltage index +// | fuse revision minimum +// | | offset +// | | | + {CHIPID_CPU_VOLTAGE_1200, 0, 15}, +}; + +const struct pmgr_binning_board_id_to_offsets pmgr_binning_board_id_to_offsets_data[] = { +// type +// | voltage offset array +// | | voltage offset array size +// | | | chip rev +// | | | | board id +// | | | | | binning group +// | | | | | | + {PMGR_BINNING_CPU, n69_cpu_offsets, sizeof(n69_cpu_offsets)/sizeof(n69_cpu_offsets[0]), CHIP_REVISION_A1, N69_AP_BOARD_ID, PMGR_BINNING_GROUP_ALL}, + {PMGR_BINNING_CPU, n69_cpu_offsets, sizeof(n69_cpu_offsets)/sizeof(n69_cpu_offsets[0]), CHIP_REVISION_A1, N69_DEV_BOARD_ID, PMGR_BINNING_GROUP_ALL}, +}; + +// .voltages = {volAdj0, volAdj1, volAdj2, volAdj3, dvfmMaxAdj, dvmrAdj0, dvmrAdj1, dvmrAdj2} + +const struct pmgr_binning_voltadj_entry pmgr_binning_voltadj_entry_data[] = { + // + // CPU + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | dvfmMaxAdj + // | | | | | dvmrAdj0 + // | | | | | | dvmrAdj1 + // | | | | | | | dvmrAdj2 + // | | | | | | | | + {CHIPID_CPU_VOLTAGE_396, CHIP_REVISION_A1, 6, .voltages = {0, 9375, 18750, 18750, 40625, 0, 0, 0}}, + + {CHIPID_CPU_VOLTAGE_396, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_600, CHIP_REVISION_A1, 0, .voltages = {0, 0, 18750, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_912, CHIP_REVISION_A1, 0, .voltages = {0, 0, 18750, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1200, CHIP_REVISION_A1, 0, .voltages = {0, 0, 15625, 15625, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1512, CHIP_REVISION_A1, 0, .voltages = {0, 0, 6250, 6250, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1800, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_1848, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + + + {CHIPID_CPU_VOLTAGE_BYPASS,CHIP_REVISION_A0,0, .voltages = {0, 0, 0, 0, 40625, 0, 0, 0}}, + {CHIPID_SOC_VOLTAGE_SECUREROM,CHIP_REVISION_A0,0,.voltages={0, 0, 0, 0, 0, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_396, CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_600, CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 18750, 40625, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_912, CHIP_REVISION_A0, 0, .voltages = {0, 3125, 6250, 12500, 40625, 3125, 3125, 0}}, + {CHIPID_CPU_VOLTAGE_1200, CHIP_REVISION_A0, 0, .voltages = {0, 3125, 6250, 12500, 40625, 6250, 6250, 0}}, + {CHIPID_CPU_VOLTAGE_1512, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 15625,12500, 3125}}, + {CHIPID_CPU_VOLTAGE_1800, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 18750,15625, 3125}}, + {CHIPID_CPU_VOLTAGE_1848, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 18750,15625, 3125}}, + {CHIPID_CPU_VOLTAGE_1896, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 18750,15625, 3125}}, + {CHIPID_CPU_VOLTAGE_1992, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 21870,18750, 3125}}, + {CHIPID_CPU_VOLTAGE_2112, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 40625, 25000,21875, 3125}}, + + // + // SOC + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | N/A + // | | | | | N/A + // | | | | | | N/A + // | | | | | | | N/A + // | | | | | | | | + {CHIPID_SOC_VOLTAGE_VMIN, CHIP_REVISION_A1, 0, .voltages = {0, 3125, 15625, 18750,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_VNOM, CHIP_REVISION_A1, 0, .voltages = {0, 0, 12500, 12500,0,0,0,0}}, + + {CHIPID_SOC_VOLTAGE_VMIN, CHIP_REVISION_A0, 0, .voltages = {0, 12500, 25000, 25000,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_VNOM, CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 12500,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_BYPASS,CHIP_REVISION_A0, 0, .voltages ={0, 0, 0, 0,0,0,0,0}}, + {CHIPID_SOC_VOLTAGE_SECUREROM,CHIP_REVISION_A0,0,.voltages={0, 0, 0, 0,0,0,0,0}}, + + // + // GFX + // + // volAdj0 + // | volAdj1 + // | | volAdj2 + // | | | volAdj3 + // | | | | N/A + // | | | | | N/A + // | | | | | | N/A + // | | | | | | | N/A + // | | | | | | | | + {CHIPID_GPU_VOLTAGE_340, CHIP_REVISION_A1, 0, .voltages = {0, 3125, 15625, 18750,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_474, CHIP_REVISION_A1, 0, .voltages = {0, 0, 12500, 12500,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_550, CHIP_REVISION_A1, 0, .voltages = {0, 0, 3125, 3125,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_723, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_804, CHIP_REVISION_A1, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + + {CHIPID_GPU_VOLTAGE_340, CHIP_REVISION_A0, 0, .voltages = {0, 12500, 25000, 25000,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_474, CHIP_REVISION_A0, 0, .voltages = {0, 6250, 12500, 12500,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_550, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, + {CHIPID_GPU_VOLTAGE_723, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0,0,0,0,0}}, +}; + + +const uint32_t pmgr_binning_voltage_config_sram_data_size = +sizeof(pmgr_binning_voltage_config_sram_data)/sizeof(pmgr_binning_voltage_config_sram_data[0]); +const uint32_t pmgr_binning_mode_to_const_data_size = sizeof(pmgr_binning_mode_to_const_data)/sizeof(pmgr_binning_mode_to_const_data[0]); +const uint32_t pmgr_binning_voltadj_entry_data_size = sizeof(pmgr_binning_voltadj_entry_data) / sizeof(pmgr_binning_voltadj_entry_data[0]); +const uint32_t pmgr_binning_voltage_index_to_config_data_size = sizeof(pmgr_binning_voltage_index_to_config_data)/sizeof(pmgr_binning_voltage_index_to_config_data[0]); +const uint32_t pmgr_binning_board_id_to_offsets_data_size = sizeof(pmgr_binning_board_id_to_offsets_data)/sizeof(pmgr_binning_board_id_to_offsets_data[0]); diff --git a/platform/s8000/chipid/rules.mk b/platform/s8000/chipid/rules.mk new file mode 100644 index 0000000..0230818 --- /dev/null +++ b/platform/s8000/chipid/rules.mk @@ -0,0 +1,42 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/chipid.o \ + $(LOCAL_DIR)/operating_point.o \ + $(LOCAL_DIR)/dvfmperf.o \ + $(LOCAL_DIR)/tunables_pmgr_product.o + +ifeq ($(SUB_PLATFORM),s8000) +ALL_OBJS += \ + $(LOCAL_DIR)/tunables_pmgr_s8000.o \ + $(LOCAL_DIR)/pmgr_binning_s8000.o +endif + +ifeq ($(SUB_PLATFORM),s8001) +ALL_OBJS += \ + $(LOCAL_DIR)/tunables_pmgr_s8001.o \ + $(LOCAL_DIR)/pmgr_binning_s8001.o + + ifeq ($(TARGET),ipad6b) + ALL_OBJS += \ + $(LOCAL_DIR)/tunables_pmgr_s8001_ipad6b.o + endif +endif + +ifeq ($(SUB_PLATFORM),s8003) +ALL_OBJS += \ + $(LOCAL_DIR)/tunables_pmgr_s8003.o \ + $(LOCAL_DIR)/pmgr_binning_s8003.o +endif diff --git a/platform/s8000/chipid/tunables_pmgr_product.c b/platform/s8000/chipid/tunables_pmgr_product.c new file mode 100644 index 0000000..5f8122b --- /dev/null +++ b/platform/s8000/chipid/tunables_pmgr_product.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* This file contains Tunables for s8001 products without product tunables */ + +#include + +const struct tunable_chip_struct tunables_pmgr_product[] __attribute__((weak)) = { + {0, 0, NULL, NULL, 0} +}; \ No newline at end of file diff --git a/platform/s8000/chipid/tunables_pmgr_s8000.c b/platform/s8000/chipid/tunables_pmgr_s8000.c new file mode 100644 index 0000000..0f87e82 --- /dev/null +++ b/platform/s8000/chipid/tunables_pmgr_s8000.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* This file contains Tunables for s8000 */ + +#include +#include +#include +#include + +/**************************************** BEGIN CHIP_REVISION_ALL ****************************************/ +// Maui: Add PMGR_PLL_PCIE_CFG.LOCK_MODE tunable to SPDS +// Add support for product / platform specific tunables +// Add GFX TVM tunables in PDF tunables to SPDS tunables +// Add SOC TVM tunables in PDF tunables to SPDS tunables +#define SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_EXTRA \ +{ /*! PLL0_CFG */ 0x00004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! PLL1_CFG */ 0x04004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! PLL_PCIE_CFG */ 0x18004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! VOLMAN_SOC_DELAY */ 0xa001c, sizeof(uint32_t), 0xfffffcffu, 0xbb81642fu}, \ +{ /*! VOLMAN_GFX_SRAM_DELAY */ 0xa0020, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_CPU_SRAM_DELAY */ 0xa0024, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_GFX_DELAY */ 0xa0028, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_CPU_DELAY */ 0xa002c, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! SOC_TVM_THRESH0 */ 0xc8004, sizeof(uint32_t), 0x000001ffu, 0x00000000u}, \ +{ /*! SOC_TVM_THRESH1 */ 0xc8008, sizeof(uint32_t), 0x000001ffu, 0x00000019u}, \ +{ /*! SOC_TVM_THRESH2 */ 0xc800c, sizeof(uint32_t), 0x000001ffu, 0x00000032u}, \ +{ /*! SOC_TVM_TEMP0_CFG */ 0xc8010, sizeof(uint32_t), 0x01ff01ffu, 0x001c01f4u}, \ +{ /*! SOC_TVM_TEMP1_CFG */ 0xc8014, sizeof(uint32_t), 0x01ff01ffu, 0x001c01f4u}, \ +{ /*! SOC_TVM_TEMP2_CFG */ 0xc8018, sizeof(uint32_t), 0x01ff01ffu, 0x001c01f4u}, \ +{ /*! GFX_TVM_CTL */ 0xc8200, sizeof(uint32_t), 0x00000f00u, 0x00000f00u}, \ +{ /*! GFX_TVM_THRESH0 */ 0xc8204, sizeof(uint32_t), 0x000001ffu, 0x00000000u}, \ +{ /*! GFX_TVM_THRESH1 */ 0xc8208, sizeof(uint32_t), 0x000001ffu, 0x00000019u}, \ +{ /*! GFX_TVM_THRESH2 */ 0xc820c, sizeof(uint32_t), 0x000001ffu, 0x00000032u}, \ +{ /*! GFX_TVM_TEMP0_CFG */ 0xc8210, sizeof(uint32_t), 0x01ff01ffu, 0x001501f9u}, \ +{ /*! GFX_TVM_TEMP1_CFG */ 0xc8214, sizeof(uint32_t), 0x01ff01ffu, 0x001501f9u}, \ +{ /*! GFX_TVM_TEMP2_CFG */ 0xc8218, sizeof(uint32_t), 0x01ff01ffu, 0x001501f9u} + +// Add CPU TVM tunables in tunables PDF to SPDS tunables +// Add DVMR tunables in tunables PDF to SPDS tunables +#define ACC_DEFAULT_TUNABLES_S8000_EXTRA \ +/* Configure temperature ranges and measurement offsets for DVFM/DVTM */ \ +/* temp_thread0 0x8 temp_thresh1 0x21 temp_offset0 0 temp_offset1 0 */ \ +{ /* ACC_PWRCTL_DVFM_CFG */ 0x220040, sizeof(uint32_t), 0x0fffffffu, 0x00001088u}, \ +/* temp_thresh2 0x3a temp_offset2 0 */ \ +{ /* ACC_PWRCTL_DVFM_CFG1 */ 0x220058, sizeof(uint32_t), 0x001fffffu, 0x0000003au}, \ +{ /* ACC_PWRCTL_DVMR_SCR */ 0x2206b8, sizeof(uint64_t), 0x00000fffu, 0x000000421} + +#define SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_EXTRA \ +/* Ensure that LPO OFF_MODE is set appropriately */ \ +{ /*! MINIPMGR_LPO_CFG */ 0x00004, sizeof(uint32_t), 0xc0000000u, 0x80000000u } + +// SwitchFabric Hash lock bit is not set +#define SWITCHFABRIC_DEFAULT_TUNABLES_S8000_EXTRA \ +{ /*! SWITCHFABRIC_REGS_AMAP_LOCK */ 0x00000, sizeof(uint32_t), 0x00000001u, 0x00000001u } +/**************************************** END CHIP_REVISION_ALL ****************************************/ + +/**************************************** BEGIN CHIP_REVISION_C0 ****************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct tunable_struct pmsasyncfifo_tunable_c0[] = { + SOUTH_BRIDGE_PMSASYNCFIFO_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct pmgr_tunable_c0[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct minipmgr_tunable_c0[] = { + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct64 acc_tunable_c0[] = { + ACC_DEFAULT_TUNABLES_S8000_EXTRA, + ACC_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct socbusmux_tunable_c0[] = { + SOCBUSMUX_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct switchfabric_tunable_c0[] = { + SWITCHFABRIC_DEFAULT_TUNABLES_S8000_EXTRA, + SWITCHFABRIC_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct pms_csr_tunable_c0[] = { + SOUTH_BRIDGE_PMS_PMS_CSR_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct sb_glue_tunable_c0[] = { + SOUTH_BRIDGE_DYNAMIC_CLK_GATING_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct afc_aiu_sb_tunable_c0[] = { + SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct asio_misc1_tunable_c0[] = { + SOUTH_BRIDGE_ASIO_MISC1_DEFAULT_TUNABLES_S8000_C0 +}; + +static const struct tunable_struct cp_com_tunable_c0[] = { + CP_CP_COM_DEFAULT_TUNABLES_S8000_C0 +}; +/***************************************** END CHIP_REVISION_C0 *****************************************/ + +/**************************************** BEGIN CHIP_REVISION_B0 ****************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_B0_EXTRA \ +/* Maui MCC EMA setting change to 3% */ \ +{ /*! EMA_FIXED_SOC1 */ 0xac004, sizeof(uint32_t), 0x07fff000u, 0x030d1000u} + +static const struct tunable_struct pmsasyncfifo_tunable_b0[] = { + SOUTH_BRIDGE_PMSASYNCFIFO_DEFAULT_TUNABLES_S8000_B0, +}; + +static const struct tunable_struct pmgr_tunable_b0[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_B0_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct minipmgr_tunable_b0[] = { + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct64 acc_tunable_b0[] = { + ACC_DEFAULT_TUNABLES_S8000_EXTRA, + ACC_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct socbusmux_tunable_b0[] = { + SOCBUSMUX_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct switchfabric_tunable_b0[] = { + SWITCHFABRIC_DEFAULT_TUNABLES_S8000_EXTRA, + SWITCHFABRIC_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct pms_csr_tunable_b0[] = { + SOUTH_BRIDGE_PMS_PMS_CSR_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct sb_glue_tunable_b0[] = { + SOUTH_BRIDGE_DYNAMIC_CLK_GATING_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct afc_aiu_sb_tunable_b0[] = { + SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct asio_misc1_tunable_b0[] = { + SOUTH_BRIDGE_ASIO_MISC1_DEFAULT_TUNABLES_S8000_B0 +}; + +static const struct tunable_struct cp_com_tunable_b0[] = { + CP_CP_COM_DEFAULT_TUNABLES_S8000_B0 +}; +/***************************************** END CHIP_REVISION_B0 *****************************************/ + +/**************************************** BEGIN CHIP_REVISION_A1 ****************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_A1_EXTRA \ +/* iBoot to set M$ EMAA register to new value to increase Maui Yield */ \ +{ /*! EMA_FIXED_SOC1 */ 0xac004, sizeof(uint32_t), 0x07fff000u, 0x032d1000u} + +// Maui: Add PMGR THERMAL tunables to SPDS for Maui A1 +#define SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_A1_THERMAL_EXTRA \ +{ /*! PMGR_THERMAL_0_PIECE0 */ 0xc0028, sizeof(uint32_t), 0x7ffffu, 0x7943bu }, \ +{ /*! PMGR_THERMAL_0_PIECE1 */ 0xc002c, sizeof(uint32_t), 0xffc7ffffu, 0x5007d02fu }, \ +{ /*! PMGR_THERMAL_0_PIECE2 */ 0xc0030, sizeof(uint32_t), 0xffc7ffffu, 0x95c02426u }, \ +{ /*! PMGR_THERMAL_1_PIECE0 */ 0xc0128, sizeof(uint32_t), 0x7ffffu, 0x7943bu }, \ +{ /*! PMGR_THERMAL_1_PIECE1 */ 0xc012c, sizeof(uint32_t), 0xffc7ffffu, 0x5007d02fu }, \ +{ /*! PMGR_THERMAL_1_PIECE2 */ 0xc0130, sizeof(uint32_t), 0xffc7ffffu, 0x95c02426u }, \ +{ /*! PMGR_THERMAL_2_PIECE0 */ 0xc0228, sizeof(uint32_t), 0x7ffffu, 0x7943bu }, \ +{ /*! PMGR_THERMAL_2_PIECE1 */ 0xc022c, sizeof(uint32_t), 0xffc7ffffu, 0x5007d02fu }, \ +{ /*! PMGR_THERMAL_2_PIECE2 */ 0xc0230, sizeof(uint32_t), 0xffc7ffffu, 0x95c02426u } + +#define SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_A1_EXTRA \ +/* 19300047 */ \ +{ /*! MINIPMGR_LPO_CFG */ 0x00004, sizeof(uint32_t), 0x30000000u, 0x00000000u } + +static const struct tunable_struct pmsasyncfifo_tunable_a1[] = { + SOUTH_BRIDGE_PMSASYNCFIFO_DEFAULT_TUNABLES_S8000_A1, +}; + +static const struct tunable_struct pmgr_tunable_a1[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_A1_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_A1_THERMAL_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct minipmgr_tunable_a1[] = { + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_A1_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct64 acc_tunable_a1[] = { + ACC_DEFAULT_TUNABLES_S8000_EXTRA, + ACC_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct socbusmux_tunable_a1[] = { + SOCBUSMUX_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct switchfabric_tunable_a1[] = { + SWITCHFABRIC_DEFAULT_TUNABLES_S8000_EXTRA, + SWITCHFABRIC_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct pms_csr_tunable_a1[] = { + SOUTH_BRIDGE_PMS_PMS_CSR_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct sb_glue_tunable_a1[] = { + SOUTH_BRIDGE_DYNAMIC_CLK_GATING_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct afc_aiu_sb_tunable_a1[] = { + SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct asio_misc1_tunable_a1[] = { + SOUTH_BRIDGE_ASIO_MISC1_DEFAULT_TUNABLES_S8000_A1 +}; + +static const struct tunable_struct cp_com_tunable_a1[] = { + CP_CP_COM_DEFAULT_TUNABLES_S8000_A1 +}; +/***************************************** END CHIP_REVISION_A1 *****************************************/ + +// For each chip, highest revision must come first. +// Notice reconfig == false for minipmgr, since it's an AOP. +const struct tunable_chip_struct tunables_pmgr[] = { + // C0 + {CHIP_REVISION_C0, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8000_C0, pmgr_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, SOUTH_BRIDGE_AOP_MINIPMGR_PADDR_S8000_C0, minipmgr_tunable_c0, NULL, false}, + {CHIP_REVISION_C0, ACC_PADDR_S8000_C0, NULL, acc_tunable_c0, true}, + {CHIP_REVISION_C0, SOUTH_BRIDGE_PMSASYNCFIFO_PADDR_S8000_C0, pmsasyncfifo_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, SOCBUSMUX_PADDR_S8000_C0, socbusmux_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, SWITCHFABRIC_PADDR_S8000_C0, switchfabric_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, SOUTH_BRIDGE_PMS_PMS_CSR_PADDR_S8000_C0, pms_csr_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, SOUTH_BRIDGE_DYNAMIC_CLK_GATING_PADDR_S8000_C0, sb_glue_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_PADDR_S8000_C0, afc_aiu_sb_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, SOUTH_BRIDGE_ASIO_MISC1_PADDR_S8000_C0, asio_misc1_tunable_c0, NULL, true}, + {CHIP_REVISION_C0, CP_CP_COM_PADDR_S8000_C0, cp_com_tunable_c0, NULL, true}, + + // B0 + {CHIP_REVISION_B0, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8000_B0, pmgr_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_AOP_MINIPMGR_PADDR_S8000_B0, minipmgr_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, ACC_PADDR_S8000_B0, NULL, acc_tunable_b0, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_PMSASYNCFIFO_PADDR_S8000_B0, pmsasyncfifo_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOCBUSMUX_PADDR_S8000_B0, socbusmux_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SWITCHFABRIC_PADDR_S8000_B0, switchfabric_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_PMS_PMS_CSR_PADDR_S8000_B0, pms_csr_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_DYNAMIC_CLK_GATING_PADDR_S8000_B0, sb_glue_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_PADDR_S8000_B0, afc_aiu_sb_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_ASIO_MISC1_PADDR_S8000_B0, asio_misc1_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, CP_CP_COM_PADDR_S8000_B0, cp_com_tunable_b0, NULL, true}, + + // A1 + {CHIP_REVISION_A1, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8000_A1, pmgr_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_AOP_MINIPMGR_PADDR_S8000_A1, minipmgr_tunable_a1, NULL, false}, + {CHIP_REVISION_A1, ACC_PADDR_S8000_A1, NULL, acc_tunable_a1, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_PMSASYNCFIFO_PADDR_S8000_A1, pmsasyncfifo_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOCBUSMUX_PADDR_S8000_A1, socbusmux_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SWITCHFABRIC_PADDR_S8000_A1, switchfabric_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_PMS_PMS_CSR_PADDR_S8000_A1, pms_csr_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_DYNAMIC_CLK_GATING_PADDR_S8000_A1, sb_glue_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_PADDR_S8000_A1, afc_aiu_sb_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_ASIO_MISC1_PADDR_S8000_A1, asio_misc1_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, CP_CP_COM_PADDR_S8000_A1, cp_com_tunable_a1, NULL, true}, + + {0, 0, NULL, NULL, 0} +}; diff --git a/platform/s8000/chipid/tunables_pmgr_s8001.c b/platform/s8000/chipid/tunables_pmgr_s8001.c new file mode 100644 index 0000000..a864f6c --- /dev/null +++ b/platform/s8000/chipid/tunables_pmgr_s8001.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* This file contains Tunables for s8001 */ + +#include +#include +#include +#include + +/**************************************** BEGIN CHIP_REVISION_ALL ****************************************/ +// Add support for product / platform specific tunables +// Add PMGR MISC_CFG_DISP.SEL_DISP_PMGR_DWI_VSYNC tunable to SPDS tunables +#define SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_EXTRA \ +{ /*! PLL0_CFG */ 0x00004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! PLL1_CFG */ 0x04004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! PLL6_CFG */ 0x18004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! PLL7_CFG */ 0x1c004, sizeof(uint32_t), 0xc0000000u, 0x00000000u}, \ +{ /*! VOLMAN_SOC_DELAY */ 0xa001c, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_GFX_SRAM_DELAY */ 0xa0020, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_CPU_SRAM_DELAY */ 0xa0024, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_GFX_DELAY */ 0xa0028, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_CPU_DELAY */ 0xa002c, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! MISC_CFG_DISP_OFFSET */ 0xdc040, sizeof(uint32_t), 0x00000001u, 0x00000000u} + +// Add CPU TVM tunables in tunables PDF to SPDS tunables +// Add DVMR tunables in tunables PDF to SPDS tunables +#define ACC_DEFAULT_TUNABLES_S8001_EXTRA \ +/* Configure temperature ranges and measurement offsets for DVFM/DVTM */ \ +/* temp_thread0 0x8 temp_thresh1 0x21 temp_offset0 0 temp_offset1 0 */ \ +{ /* ACC_PWRCTL_DVFM_CFG */ 0x220040, sizeof(uint32_t), 0x0fffffffu, 0x00001088u}, \ +/* temp_thresh2 0x3a temp_offset2 0 */ \ +{ /* ACC_PWRCTL_DVFM_CFG1 */ 0x220058, sizeof(uint32_t), 0x001fffffu, 0x0000003au}, \ +{ /* ACC_PWRCTL_DVMR_SCR */ 0x2206b8, sizeof(uint64_t), 0x00000fffu, 0x000000421} + +#define SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8001_EXTRA \ +/* Ensure that LPO OFF_MODE is set appropriately */ \ +{ /*! MINIPMGR_LPO_CFG */ 0x00004, sizeof(uint32_t), 0xc0000000u, 0x80000000u } + +// SwitchFabric Hash lock bit is not set +#define SWITCHFABRIC_DEFAULT_TUNABLES_S8001_EXTRA \ +{ /*! SWITCHFABRIC_REGS_AMAP_LOCK */ 0x00000, sizeof(uint32_t), 0x00000001u, 0x00000001u } +/**************************************** END CHIP_REVISION_ALL ****************************************/ + +/**************************************** BEGIN CHIP_REVISION_B0 ****************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const struct tunable_struct pmsasyncfifo_tunable_b0[] = { + SOUTH_BRIDGE_PMSASYNCFIFO_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct pmgr_tunable_b0[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct minipmgr_tunable_b0[] = { + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8001_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct64 acc_tunable_b0[] = { + ACC_DEFAULT_TUNABLES_S8001_EXTRA, + ACC_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct socbusmux_tunable_b0[] = { + SOCBUSMUX_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct switchfabric_tunable_b0[] = { + SWITCHFABRIC_DEFAULT_TUNABLES_S8001_EXTRA, + SWITCHFABRIC_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct pms_csr_tunable_b0[] = { + SOUTH_BRIDGE_PMS_PMS_CSR_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct sb_glue_tunable_b0[] = { + SOUTH_BRIDGE_DYNAMIC_CLK_GATING_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct afc_aiu_sb_tunable_b0[] = { + SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct asio_misc1_tunable_b0[] = { + SOUTH_BRIDGE_ASIO_MISC1_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct cp0_cp_com_tunable_b0[] = { + CP0_CP_COM_DEFAULT_TUNABLES_S8001_B0 +}; + +static const struct tunable_struct cp1_cp_com_tunable_b0[] = { + CP1_CP_COM_DEFAULT_TUNABLES_S8001_B0 +}; + +/***************************************** END CHIP_REVISION_B0 *****************************************/ + +/**************************************** BEGIN CHIP_REVISION_A0 ****************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct tunable_struct pmsasyncfifo_tunable_a0[] = { + SOUTH_BRIDGE_PMSASYNCFIFO_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct pmgr_tunable_a0[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct minipmgr_tunable_a0[] = { + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8001_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct64 acc_tunable_a0[] = { + ACC_DEFAULT_TUNABLES_S8001_EXTRA, + ACC_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct socbusmux_tunable_a0[] = { + SOCBUSMUX_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct switchfabric_tunable_a0[] = { + SWITCHFABRIC_DEFAULT_TUNABLES_S8001_EXTRA, + SWITCHFABRIC_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct pms_csr_tunable_a0[] = { + SOUTH_BRIDGE_PMS_PMS_CSR_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct sb_glue_tunable_a0[] = { + SOUTH_BRIDGE_DYNAMIC_CLK_GATING_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct afc_aiu_sb_tunable_a0[] = { + SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct asio_misc1_tunable_a0[] = { + SOUTH_BRIDGE_ASIO_MISC1_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct cp0_cp_com_tunable_a0[] = { + CP0_CP_COM_DEFAULT_TUNABLES_S8001_A0 +}; + +static const struct tunable_struct cp1_cp_com_tunable_a0[] = { + CP1_CP_COM_DEFAULT_TUNABLES_S8001_A0 +}; +/***************************************** END CHIP_REVISION_A0 *****************************************/ + +// For each chip, highest revision must come first. +// Notice reconfig == false for minipmgr, since it's an AOP. +const struct tunable_chip_struct tunables_pmgr[] = { + // B0 + {CHIP_REVISION_B0, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8001_B0, pmgr_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_AOP_MINIPMGR_PADDR_S8001_B0, minipmgr_tunable_b0, NULL, false}, + {CHIP_REVISION_B0, ACC_PADDR_S8001_B0, NULL, acc_tunable_b0, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_PMSASYNCFIFO_PADDR_S8001_B0, pmsasyncfifo_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOCBUSMUX_PADDR_S8001_B0, socbusmux_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SWITCHFABRIC_PADDR_S8001_B0, switchfabric_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_PMS_PMS_CSR_PADDR_S8001_B0, pms_csr_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_DYNAMIC_CLK_GATING_PADDR_S8001_B0, sb_glue_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_PADDR_S8001_B0, afc_aiu_sb_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, SOUTH_BRIDGE_ASIO_MISC1_PADDR_S8001_B0, asio_misc1_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, CP0_CP_COM_PADDR_S8001_B0, cp0_cp_com_tunable_b0, NULL, true}, + {CHIP_REVISION_B0, CP1_CP_COM_PADDR_S8001_B0, cp1_cp_com_tunable_b0, NULL, true}, + + // A0 + {CHIP_REVISION_A0, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8001_A0, pmgr_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_AOP_MINIPMGR_PADDR_S8001_A0, minipmgr_tunable_a0, NULL, false}, + {CHIP_REVISION_A0, ACC_PADDR_S8001_A0, NULL, acc_tunable_a0, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_PMSASYNCFIFO_PADDR_S8001_A0, pmsasyncfifo_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOCBUSMUX_PADDR_S8001_A0, socbusmux_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SWITCHFABRIC_PADDR_S8001_A0, switchfabric_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_PMS_PMS_CSR_PADDR_S8001_A0, pms_csr_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_DYNAMIC_CLK_GATING_PADDR_S8001_A0, sb_glue_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_PADDR_S8001_A0, afc_aiu_sb_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_ASIO_MISC1_PADDR_S8001_A0, asio_misc1_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, CP0_CP_COM_PADDR_S8001_A0, cp0_cp_com_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, CP1_CP_COM_PADDR_S8001_A0, cp1_cp_com_tunable_a0, NULL, true}, + + {0, 0, NULL, NULL, 0} +}; diff --git a/platform/s8000/chipid/tunables_pmgr_s8001_ipad6b.c b/platform/s8000/chipid/tunables_pmgr_s8001_ipad6b.c new file mode 100644 index 0000000..adb68eb --- /dev/null +++ b/platform/s8000/chipid/tunables_pmgr_s8001_ipad6b.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* This file contains Tunables for s8001 ipad6b */ + +#include +#include +#include +#include + +/**************************************** BEGIN CHIP_REVISION_ALL ****************************************/ +// Update iBoot/PMGR driver settings for enabling UV_WARN for J127/J105 +#define SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_IPAD6B_EXTRA \ +{ /*! GFX_THROTTLE_DITHER0_INT */ 0x7403c, sizeof(uint32_t), 0xffffffffu, 0x480000u}, \ +{ /*! GFX_THROTTLE_DITHER0 */ 0x74040, sizeof(uint32_t), 0xffffffffu, 0x10555u}, \ +{ /*! GFX_THROTTLE_DITHER1 */ 0x74044, sizeof(uint32_t), 0xffffffffu, 0x106dbu}, \ +{ /*! GFX_THROTTLE_DITHER2 */ 0x74048, sizeof(uint32_t), 0xffffffffu, 0x10fffu}, \ +{ /*! GFX_THROTTLE_DITHER3 */ 0x7404c, sizeof(uint32_t), 0xffffffffu, 0x00fffu}, \ +{ /*! GFX_THROTTLE_DITHER4 */ 0x74050, sizeof(uint32_t), 0xffffffffu, 0x00fffu}, \ +{ /*! GFX_THROTTLE_DITHER5 */ 0x74054, sizeof(uint32_t), 0xffffffffu, 0x00fffu}, \ +{ /*! GFX_THROTTLE_SRC2_CTL */ 0x74078, sizeof(uint32_t), 0xffffffffu, 0x00003u}, \ +{ /*! GFX_THROTTLE_SRC2_ASSERT_COUNT */ 0x7407c, sizeof(uint32_t), 0xffffffffu, 0x00000u}, \ +{ /*! GFX_THROTTLE_SRC2_DEASSERT_COUNT */ 0x74080, sizeof(uint32_t), 0xffffffffu, 0x00000u}, \ +{ /*! GFX_THROTTLE_SRC2_MIN_ACTIVE_COUNT */ 0x74084, sizeof(uint32_t), 0xffffffffu, 0x00000u}, \ +{ /*! GFX_PERF_CFG4 */ 0xfc140, sizeof(uint32_t), 0xffffffffu, 0x10003u}, \ +{ /*! GFX_PERF_CFG5 */ 0xfc150, sizeof(uint32_t), 0xffffffffu, 0x10001u}, \ +{ /*! GFX_PERF_CTL */ 0xfc000, sizeof(uint32_t), 0xffffffffu, 0x00003u}, \ +{ -1, -1, -1, -1 } +/**************************************** END CHIP_REVISION_ALL ****************************************/ + +/**************************************** BEGIN CHIP_REVISION_B0 ****************************************/ +#include + +static const struct tunable_struct pmgr_tunable_b0[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_IPAD6B_EXTRA +}; + +/***************************************** END CHIP_REVISION_B0 *****************************************/ + +/**************************************** BEGIN CHIP_REVISION_A0 ****************************************/ +#include + +static const struct tunable_struct pmgr_tunable_a0[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8001_IPAD6B_EXTRA +}; + +/***************************************** END CHIP_REVISION_A0 *****************************************/ + +// For each chip, highest revision must come first. +// Notice reconfig == false for minipmgr, since it's an AOP. +const struct tunable_chip_struct tunables_pmgr_product[] = { + // B0 + {CHIP_REVISION_B0, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8001_B0, pmgr_tunable_b0, NULL, true}, + + // A0 + {CHIP_REVISION_A0, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8001_A0, pmgr_tunable_a0, NULL, true}, + + {0, 0, NULL, NULL, 0} +}; \ No newline at end of file diff --git a/platform/s8000/chipid/tunables_pmgr_s8003.c b/platform/s8000/chipid/tunables_pmgr_s8003.c new file mode 100644 index 0000000..3199fc5 --- /dev/null +++ b/platform/s8000/chipid/tunables_pmgr_s8003.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* This file contains Tunables for s8003 */ + +#include +#include +#include +#include + +/**************************************** BEGIN CHIP_REVISION_ALL ****************************************/ +// Add support for product / platform specific tunables +#define SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8003_EXTRA \ +{ /*! PLL0_CFG */ 0x00004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! PLL1_CFG */ 0x04004, sizeof(uint32_t), 0xc0000000u, 0x40000000u}, \ +{ /*! VOLMAN_SOC_DELAY */ 0xa001c, sizeof(uint32_t), 0xfffffcffu, 0xbb81642fu}, \ +{ /*! VOLMAN_GFX_SRAM_DELAY */ 0xa0020, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_CPU_SRAM_DELAY */ 0xa0024, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_GFX_DELAY */ 0xa0028, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u}, \ +{ /*! VOLMAN_CPU_DELAY */ 0xa002c, sizeof(uint32_t), 0xfffffcffu, 0xbb816405u} + +// Add DVMR tunables in tunables PDF to SPDS tunables +// Add CPU TVM tunables in tunables PDF to SPDS tunables +#define ACC_DEFAULT_TUNABLES_S8003_EXTRA \ +/* Configure temperature ranges and measurement offsets for DVFM/DVTM */ \ +/* temp_thread0 0x8 temp_thresh1 0x21 temp_offset0 0 temp_offset1 0 */ \ +{ /* ACC_PWRCTL_DVFM_CFG */ 0x220040, sizeof(uint32_t), 0x0fffffffu, 0x00001088u}, \ +/* temp_thresh2 0x3a temp_offset2 0 */ \ +{ /* ACC_PWRCTL_DVFM_CFG1 */ 0x220058, sizeof(uint32_t), 0x001fffffu, 0x0000003au}, \ +{ /* ACC_PWRCTL_DVMR_SCR */ 0x2206b8, sizeof(uint64_t), 0x00000fffu, 0x000000421} + +#define SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8003_EXTRA \ +/* Ensure that LPO OFF_MODE is set appropriately */ \ +{ /*! MINIPMGR_LPO_CFG */ 0x00004, sizeof(uint32_t), 0xc0000000u, 0x80000000u } + +// SwitchFabric Hash lock bit is not set +#define SWITCHFABRIC_DEFAULT_TUNABLES_S8003_EXTRA \ +{ /*! SWITCHFABRIC_REGS_AMAP_LOCK */ 0x00000, sizeof(uint32_t), 0x00000001u, 0x00000001u } +/**************************************** END CHIP_REVISION_ALL ****************************************/ + +/**************************************** BEGIN CHIP_REVISION_A1 ****************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct tunable_struct pmsasyncfifo_tunable_a1[] = { + SOUTH_BRIDGE_PMSASYNCFIFO_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct pmgr_tunable_a1[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8003_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct minipmgr_tunable_a1[] = { + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8003_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct64 acc_tunable_a1[] = { + ACC_DEFAULT_TUNABLES_S8003_EXTRA, + ACC_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct socbusmux_tunable_a1[] = { + SOCBUSMUX_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct switchfabric_tunable_a1[] = { + SWITCHFABRIC_DEFAULT_TUNABLES_S8003_EXTRA, + SWITCHFABRIC_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct pms_csr_tunable_a1[] = { + SOUTH_BRIDGE_PMS_PMS_CSR_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct sb_glue_tunable_a1[] = { + SOUTH_BRIDGE_DYNAMIC_CLK_GATING_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct afc_aiu_sb_tunable_a1[] = { + SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct asio_misc1_tunable_a1[] = { + SOUTH_BRIDGE_ASIO_MISC1_DEFAULT_TUNABLES_S8003_A1 +}; + +static const struct tunable_struct cp_com_tunable_a1[] = { + CP_CP_COM_DEFAULT_TUNABLES_S8003_A1 +}; +/***************************************** END CHIP_REVISION_A1 *****************************************/ + +/**************************************** BEGIN CHIP_REVISION_A0 ****************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct tunable_struct pmsasyncfifo_tunable_a0[] = { + SOUTH_BRIDGE_PMSASYNCFIFO_DEFAULT_TUNABLES_S8003_A0, +}; + +static const struct tunable_struct pmgr_tunable_a0[] = { + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8003_EXTRA, + SOUTH_BRIDGE_PMS_PMGR_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct minipmgr_tunable_a0[] = { + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8003_EXTRA, + SOUTH_BRIDGE_AOP_MINIPMGR_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct64 acc_tunable_a0[] = { + ACC_DEFAULT_TUNABLES_S8003_EXTRA, + ACC_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct socbusmux_tunable_a0[] = { + SOCBUSMUX_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct switchfabric_tunable_a0[] = { + SWITCHFABRIC_DEFAULT_TUNABLES_S8003_EXTRA, + SWITCHFABRIC_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct pms_csr_tunable_a0[] = { + SOUTH_BRIDGE_PMS_PMS_CSR_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct sb_glue_tunable_a0[] = { + SOUTH_BRIDGE_DYNAMIC_CLK_GATING_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct afc_aiu_sb_tunable_a0[] = { + SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct asio_misc1_tunable_a0[] = { + SOUTH_BRIDGE_ASIO_MISC1_DEFAULT_TUNABLES_S8003_A0 +}; + +static const struct tunable_struct cp_com_tunable_a0[] = { + CP_CP_COM_DEFAULT_TUNABLES_S8003_A0 +}; +/***************************************** END CHIP_REVISION_A0 *****************************************/ + +// For each chip, highest revision must come first. +// Notice reconfig == false for minipmgr, since it's an AOP. +const struct tunable_chip_struct tunables_pmgr[] = { + // A1 + {CHIP_REVISION_A1, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8003_A1, pmgr_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_AOP_MINIPMGR_PADDR_S8003_A1, minipmgr_tunable_a1, NULL, false}, + {CHIP_REVISION_A1, ACC_PADDR_S8003_A1, NULL, acc_tunable_a1, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_PMSASYNCFIFO_PADDR_S8003_A1, pmsasyncfifo_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOCBUSMUX_PADDR_S8003_A1, socbusmux_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SWITCHFABRIC_PADDR_S8003_A1, switchfabric_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_PMS_PMS_CSR_PADDR_S8003_A1, pms_csr_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_DYNAMIC_CLK_GATING_PADDR_S8003_A1, sb_glue_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_PADDR_S8003_A1, afc_aiu_sb_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, SOUTH_BRIDGE_ASIO_MISC1_PADDR_S8003_A1, asio_misc1_tunable_a1, NULL, true}, + {CHIP_REVISION_A1, CP_CP_COM_PADDR_S8003_A1, cp_com_tunable_a1, NULL, true}, + + // A0 + {CHIP_REVISION_A0, SOUTH_BRIDGE_PMS_PMGR_PADDR_S8003_A0, pmgr_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_AOP_MINIPMGR_PADDR_S8003_A0, minipmgr_tunable_a0, NULL, false}, + {CHIP_REVISION_A0, ACC_PADDR_S8003_A0, NULL, acc_tunable_a0, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_PMSASYNCFIFO_PADDR_S8003_A0, pmsasyncfifo_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOCBUSMUX_PADDR_S8003_A0, socbusmux_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SWITCHFABRIC_PADDR_S8003_A0, switchfabric_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_PMS_PMS_CSR_PADDR_S8003_A0, pms_csr_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_DYNAMIC_CLK_GATING_PADDR_S8003_A0, sb_glue_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_SBR_AXI2AF_AFC_AIU_SB_PADDR_S8003_A0, afc_aiu_sb_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, SOUTH_BRIDGE_ASIO_MISC1_PADDR_S8003_A0, asio_misc1_tunable_a0, NULL, true}, + {CHIP_REVISION_A0, CP_CP_COM_PADDR_S8003_A0, cp_com_tunable_a0, NULL, true}, + + {0, 0, NULL, NULL, 0} +}; diff --git a/platform/s8000/dcs/dcs.c b/platform/s8000/dcs/dcs.c new file mode 100644 index 0000000..cdf0391 --- /dev/null +++ b/platform/s8000/dcs/dcs.c @@ -0,0 +1,921 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + dcs_boottype_t boot_type; + + // Don't perform DRAM initializion if the memory controller is already + // initialized (e.g., for SecureROM validation testing). +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + if (resume || DCS_REG_READ_CH(0, rDCS_MCU_AMCCTRL) == 0) { +#endif + clock_gate(CLK_DCS0, true); + clock_gate(CLK_DCS1, true); + clock_gate(CLK_DCS2, true); + clock_gate(CLK_DCS3, true); +#if SUB_PLATFORM_S8001 && DCS_NUM_CHANNELS > 4 + clock_gate(CLK_DCS4, true); + clock_gate(CLK_DCS5, true); + clock_gate(CLK_DCS6, true); + clock_gate(CLK_DCS7, true); +#endif + clock_gate(CLK_MCC, true); + + boot_type = (resume)? DCS_BOOT_RESUME:DCS_BOOT_COLDBOOT; + // NOTE: Boot types AOP_DDR or AOP_AWAKE do not use this Code + // For those cases, the Init sequence is executed by the AOP + + // Perform the LPDDR4 Init for this type of Boot + dcs_init(boot_type); + + // Maui A1: Samsung 25nm LP4 RBM failures - WA + // Can't do this as part of dcs_dram_workarounds because reg value gets overwritten later in the sequence + const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info(); + if(dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) + if(dev_info->rev_id == 0x3 && dev_info->rev_id2 == 0x0) + for(uint32_t channel = 0; channel < DCS_NUM_CHANNELS; channel++) + DCS_REG_ACCESS(rDCS_MCU_AREFEN_FREQ(0) + (channel * DCS_SPACING)) = 0x1010013f; +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + } +#endif + + return 0; +} + +void dcs_lock_down_mcc(void) +{ + // Don't allow MCC as RAM + rAMCC_MCCGEN &= ~AMCC_MCCGEN_MCC_RAM_EN; + rAMCC_MCCGEN |= AMCC_MCCGEN_MCC_RAM_EN_LOCK; + // Don't allow tag RAM reads + rAMCC_MCCCFG_TAG_RD_DIS |= 1; +#if NUM_AMCCS > 1 + rAMCC1_MCCGEN &= ~AMCC_MCCGEN_MCC_RAM_EN; + rAMCC1_MCCGEN |= AMCC_MCCGEN_MCC_RAM_EN_LOCK; + rAMCC1_MCCCFG_TAG_RD_DIS |= 1; +#endif +} + +void mcu_bypass_prep (int step) +{ +} + +uint64_t mcu_get_memory_size (void) +{ + return dcs_get_memory_size(); +} + +//================================================================================ +void dcs_enable_slow_boot (bool enable) +{ + if (enable) { + // switch to slow clock + clocks_set_performance(kPerformanceMemoryLow); + spin(1); + } + else { +#if !SUPPORT_FPGA + // switch back to full-speed + clocks_set_performance(kPerformanceMemoryFull); + spin(1); +#endif + } +} + +//================================================================================ +// https://seg-docs.ecs.apple.com/projects/malta//release/UserManual/Hx_LPDDR4_RevID_Workaround.pdf +void dcs_dram_workarounds(dcs_boottype_t boot_type) +{ +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + uint32_t autoref_freq1; +#endif +#if SUB_PLATFORM_S8000 + uint32_t dqvref_freq1; +#endif + + if(boot_type == DCS_BOOT_COLDBOOT) { + + const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_LPDDR4_MANUF_ID_SAMSUNG: +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + if(dev_info->rev_id == 5 && dev_info->rev_id2 == 1) { + // tRFCpbCyc_freq1 = 0x1c for Samsung + autoref_freq1 = DCS_REG_READ_CH(0, rDCS_MCU_AUTOREF_FREQ(1)); + autoref_freq1 &= 0x00ffffff; + autoref_freq1 |= (0x1c << 24); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(1), autoref_freq1); + } +#endif +#if SUB_PLATFORM_S8000 + if(dev_info->rev_id == 5) { + dqvref_freq1 = 0x00ec00ec; // Maui + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), dqvref_freq1); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), dqvref_freq1); + } +#endif + break; + + case JEDEC_LPDDR4_MANUF_ID_HYNIX: +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + if(dev_info->rev_id == 3 && dev_info->rev_id2 == 2) { + // tRFCpbCyc_freq1 = 0x1c for Hynix + autoref_freq1 = DCS_REG_READ_CH(0, rDCS_MCU_AUTOREF_FREQ(1)); + autoref_freq1 &= 0x00ffffff; + autoref_freq1 |= (0x1c << 24); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(1), autoref_freq1); + } +#endif +#if SUB_PLATFORM_S8000 + if(dev_info->rev_id == 3) { + dqvref_freq1 = 0x00df00df; // Maui + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), dqvref_freq1); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), dqvref_freq1); + } +#endif + + // Workarounds: Pull Up/Down shift for Maui Hynix 25nm + if(dev_info->rev_id == 0x3) { + // Test MRS Exit + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x0); + + // Test MRS Entry + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xb0); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xe0); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x90); + + if(dev_info->rev_id2 == 0x0) { + // Rising Slew-rate up + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x87); + + // Self-refresh OSC Min + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xd0); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x90); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x86); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x81); + } + + // For all SoCs that use this particular DRAM + if(dev_info->rev_id2 <= 0x1) { + // Pull Up RON shift + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xc4); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x90); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x8e); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x81); + + // Pull Down RON shift + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xc4); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x94); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x92); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x81); + + // ZQ calibration START MPC cmd + dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x0, 0x4f); + // wait 1us for tZQCAL + dcs_spin(1, "Workarounds -- tZQCAL"); + + // ZQ calibration LATCH MPC cmd + dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x0, 0x51); + } + } + break; + + case JEDEC_LPDDR4_MANUF_ID_MICRON: +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + if(dev_info->rev_id == 1 && dev_info->rev_id2 == 2) { + // tRFCpbCyc_freq1 = 0x20 for Micron + autoref_freq1 = DCS_REG_READ_CH(0, rDCS_MCU_AUTOREF_FREQ(1)); + autoref_freq1 &= 0x00ffffff; + autoref_freq1 |= (0x20 << 24); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(1), autoref_freq1); + } +#endif +#if SUB_PLATFORM_S8000 + if(dev_info->rev_id == 1) { + dqvref_freq1 = 0x00ea00ea; // Maui + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), dqvref_freq1); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), dqvref_freq1); + } +#endif + + if(dev_info->rev_id == 0x1) { + // Test MRS Exit + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x0); + + // Test MRS: Disable VREFDQ TAP code local latch + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xf1); + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x40); + } + break; + + default: + break; + } + } +} + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +void dcs_dram_workarounds_step12 ( void ) +{ + + const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info(); + + if ( (dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 == 1) ) + { + + if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_C0) || (dcs_cfg.chipID == 0x8003 && dcs_cfg.chipRev >= CHIP_REVISION_A1) || + (dcs_cfg.chipID == 0x8001 && dcs_cfg.chipRev >= CHIP_REVISION_B0) ) + { + dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x0b, 0x34); + dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x00, 0x4F); + dcs_spin(1, "Workaround-Samsung--step-12-tzQCAL"); + dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x00, 0x51); + dcs_spin(1, "Workaround-Samsung--step-12-tZQLAT"); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(2, 0), 0xb303340b); + + } + + } + +} +#endif +//================================================================================ +// Grab (Platform Specific) Tables with Definitions of Values for DCS Init & DCS Tunables +#include + +#if DCS_FIXUP_PARAMS +// Grab (Target Specific) Definition of Required Fixups to the Values for DCS Init +#include +#endif + +// use_dcs_params is already the same as dcs_params, unless we want to override with older chip-rev or target specific values +void dcs_init_config_params(dcs_config_params_t *use_dcs_params, dcs_target_t targtype) +{ +#if SUB_PLATFORM_S8000 + // Maui B0 DCS param table + if(platform_get_chip_revision() < CHIP_REVISION_C0) + memcpy(use_dcs_params, &dcs_params_b0, sizeof(dcs_config_params_t)); +#endif + +#if DCS_FIXUP_PARAMS + // This gives the particular target a chance to make target-specific changes + dcs_init_config_fixup_params(use_dcs_params, targtype); +#endif +} + +const dcs_tunable_t *dcs_init_tunable_table(uint32_t *table_len) +{ + const dcs_tunable_t *tunables = dcs_tunables; + uint32_t tunables_size = sizeof(dcs_tunables); + +#if SUB_PLATFORM_S8000 + // Maui B0 DCS tunables + if(platform_get_chip_revision() < CHIP_REVISION_C0) { + tunables = dcs_tunables_b0; + tunables_size = sizeof(dcs_tunables_b0); + } +#endif + + if (table_len) + *table_len = tunables_size / sizeof(tunables[0]); + + return tunables; +} + +void dcs_aop_ddr_to_awake_post_tunables_insert(void) +{ + uint32_t i, num_tunables = 0; + const dcs_tunable_t *tunables = NULL; + uintptr_t curr_reg = 0; + uint32_t reg_val = 0; + + tunables = dcs_init_tunable_table(&num_tunables); + + // At the time this function is called, tunables values are already expected to be programmed into the registers. + // Expected format of the dcs_tunables table: Each field that has a tunable value is 1 entry in the tunables table + for(i = 0; i < num_tunables; i++, tunables++) { + + // end of table + if(tunables->reg == 0) + break; + + // skip over subsequent tunables values for different fields in the same register, since we read out the entire register the first time + if(tunables->reg == curr_reg) + continue; + + curr_reg = tunables->reg; + + if(dcs_reg_is_outside_dcs_block(curr_reg)) { + reg_val = DCS_REG_ACCESS(curr_reg); + reconfig_command_write(AOP_DDR_AWAKE_POST, curr_reg, reg_val, false); + } else { + // if reg is within DCS hw block, the reg is duplicated for each instance of the hw block, just read out 1st instance + // and write that value for all instances + reg_val = DCS_REG_READ_CH(0, curr_reg); + + for(uint32_t channel = 0; channel < DCS_NUM_CHANNELS; channel++) + reconfig_command_write(AOP_DDR_AWAKE_POST, (curr_reg + (channel * DCS_SPACING)), reg_val, false); + } + } +} + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +//================================================================================ +// Save off calibration results to AOP_SRAM region (later to be stitched into mcu_aop_awake_reconfig_restore sequence) +// Order of registers to be saved matches the order in the reconfig sequence +volatile uint32_t *dcs_save_calibration_results(volatile uint32_t *save_region, uint32_t freq) +{ + uint32_t ch, n; + + // Registers to be saved off after calibration in freq 1 has completed + if (freq == DCS_FREQ(1)) { + // CASDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CASDLLCTRL(ch)); + + // CSSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CSSDLLCTRL(ch)); + + // CKSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CKSDLLCTRL(ch)); + + // AMPCAWRLVLSDLLCODE + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CAWRLVLSDLLCODE(ch)); + + // CA_DESKEW_CTRL + for(n = 0; n < CA_NUM_BITS; n++) + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CADESKEW_CTRL(ch, n)); + + // CS_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CSDESKEW_CTRL(ch)); + + // CK_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CKDESKEW_CTRL(ch)); + + // AMPWRLVLSDLLCODE0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(0, ch)); + *save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(1, ch)); + } + + // VREF_Fx + for(n = 0; n < DCS_FREQUENCY_SLOTS; n++) { + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ0, n)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ1, n)); + } + } + + // AUTOREF_FREQ1 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_AUTOREF_FREQ(1)); + + // CAMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ0)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ1)); + } + + // RDMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ0)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ1)); + } + + // WRMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ0)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ1)); + } + + // FREQCHNGCTL1_FREQ1 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(1, 1)); + + } else if (freq == DCS_FREQ(0)) { + // Registers to be saved off after calibration in freq 0 has completed + + // VREF_F0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ0, 0)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ1, 0)); + } + + // FREQCHNGCTL1_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0)); + + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0)); + } else if (freq == 0) { + // Maui/Malta: Samsung DRAM workaround: disable hw zqcal + // rGLBTIMER_ZQCTIMER + *save_region++ = DCS_REG_ACCESS(rGLBTIMER_ZQCTIMER); + } + + return save_region; +} + +//================================================================================ +// Stitch the saved calibration results into the reconfig sequence +// To be called immediately after stitching mcu_aop_awake_reconfig_pre_restore +// Uses mcu_aop_awake_reconfig_restore as reference for register order and fields +void dcs_restore_calibration_results(volatile uint32_t *save_region) +{ + uint32_t ch, n, f; + uint32_t reg_val; + + // CASDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CASDLLCTRL(ch), reg_val, false); + save_region++; + } + + // CSSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSSDLLCTRL(ch), reg_val, false); + save_region++; + } + + // CKSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKSDLLCTRL(ch), reg_val, false); + save_region++; + } + + // AMPCAWRLVLSDLLCODE + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), reg_val, false); + save_region++; + } + + // Poll for AMPCAWRLVLSDLLCODE.WRLVLRUNUPDWRRESULT to clear + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + reconfig_command_read(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), 0, WRLVLRUNUPDWRRESULT, 0, false); + + // CA_DESKEW_CTRL + for(n = 0; n < CA_NUM_BITS; n++) { + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CADESKEW_CTRL(ch, n), reg_val, false); + save_region++; + } + } + + // CS_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSDESKEW_CTRL(ch), reg_val, false); + save_region++; + } + + // CK_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKDESKEW_CTRL(ch), reg_val, false); + save_region++; + } + + // AMPWRLVLSDLLCODE0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1 + for(n = 0; n < 2; n++) { + reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_DQWRLVLSDLLCODE(n, ch), reg_val, false); + save_region++; + } + } + + // VREF_Fx + for(f = 0; f < DCS_FREQUENCY_SLOTS; f++) { + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1 + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (*save_region) & (VREFSEL_MASK | DQSVREFSEL_MASK); + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(n, f) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + } + + // AUTOREF_FREQ1 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_AUTOREF_FREQ(1) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // CAMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1: shift the status field value into the override field + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + + // RDMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1: shift the status field value into the override field + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + + // WRMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1: shift the status field value into the override field + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + + // FREQCHNGCTL1_FREQ1 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(1, 1) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // The next set of registers were saved off after freq0 calibration completed + + // VREF_F0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(AMP_DQ0, 0) + (ch * DCS_SPACING), reg_val, false); + save_region++; + + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(AMP_DQ1, 0) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // FREQCHNGCTL1_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // FREQCHNGCTL2_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // Maui/Malta: Samsung DRAM workaround: disable hw zqcal + // rGLBTIMER_ZQCTIMER + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rGLBTIMER_ZQCTIMER, reg_val, false); + save_region++; +} +#endif // #if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + +#if SUB_PLATFORM_S8001 +//================================================================================ +// Save off calibration results to AOP_SRAM region (later to be stitched into mcu_aop_awake_reconfig_restore sequence) +// Order of registers to be saved matches the order in the reconfig sequence +volatile uint32_t *dcs_save_calibration_results(volatile uint32_t *save_region, uint32_t freq) +{ + uint32_t ch, n; + + if(freq == DCS_FREQ(0)) { + // CASDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CASDLLCTRL(ch)); + + // CSSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CSSDLLCTRL(ch)); + + // CKSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CKSDLLCTRL(ch)); + + // AMPCAWRLVLSDLLCODE + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CAWRLVLSDLLCODE(ch)); + + // CA_DESKEW_CTRL + for(n = 0; n < CA_NUM_BITS; n++) + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CADESKEW_CTRL(ch, n)); + + // CS_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CSDESKEW_CTRL(ch)); + + // CK_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_ACCESS(rAMP_CKDESKEW_CTRL(ch)); + + // AMPWRLVLSDLLCODE0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(0, ch)); + *save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(1, ch)); + } + + // VREF_Fx + for(n = 0; n < DCS_FREQUENCY_SLOTS; n++) { + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ0, n)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ1, n)); + } + } + + // WRDQCALVREFCODESTATUS + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRDQCALVREFCODESTATUS); + + // RDDQCALVREFCODESTATUS + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDDQCALVREFCODESTATUS); + + // CAMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ0)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ1)); + } + + // RDMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ0)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ1)); + } + + // WRMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ0)); + *save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ1)); + } + + // FREQCHNGCTL1_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0)); + + // FREQCHNGCTL2_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0)); + + // FREQCHNGCTL2_FREQ3 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(2, 3)); + + // FREQCHNGCTL4_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + *save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(4, 0)); + + // CB_IMPCTL + *save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_CB_IMPCTL); + + // B0_ODT + *save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_B0_ODT); + + // B1_ODT + *save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_B1_ODT); + + // DQS0_ODT + *save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_DQS0_ODT); + + // DQS1_ODT + *save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_DQS1_ODT); + } else if(freq == 0) { + // Elba: Samsung DRAM workaround: disable hw zqcal + // rGLBTIMER_ZQCTIMER + *save_region++ = DCS_REG_ACCESS(rGLBTIMER_ZQCTIMER); + } + + return save_region; +} + +//================================================================================ +// Stitch the saved calibration results into the reconfig sequence +// To be called immediately after stitching mcu_aop_awake_reconfig_pre_restore +// Uses mcu_aop_awake_reconfig_restore as reference for register order and fields +void dcs_restore_calibration_results(volatile uint32_t *save_region) +{ + uint32_t ch, n, f; + uint32_t reg_val; + + // CASDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CASDLLCTRL(ch), reg_val, false); + save_region++; + } + + // CSSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSSDLLCTRL(ch), reg_val, false); + save_region++; + } + + // CKSDLLCTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKSDLLCTRL(ch), reg_val, false); + save_region++; + } + + // AMPCAWRLVLSDLLCODE + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), reg_val, false); + save_region++; + } + + // Poll for AMPCAWRLVLSDLLCODE.WRLVLRUNUPDWRRESULT to clear + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + reconfig_command_read(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), 0, WRLVLRUNUPDWRRESULT, 0, false); + + // CA_DESKEW_CTRL + for(n = 0; n < CA_NUM_BITS; n++) { + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CADESKEW_CTRL(ch, n), reg_val, false); + save_region++; + } + } + + // CS_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSDESKEW_CTRL(ch), reg_val, false); + save_region++; + } + + // CK_DESKEW_CTRL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKDESKEW_CTRL(ch), reg_val, false); + save_region++; + } + + // AMPWRLVLSDLLCODE0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1 + for(n = 0; n < 2; n++) { + reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT; + reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_DQWRLVLSDLLCODE(n, ch), reg_val, false); + save_region++; + } + } + + // VREF_Fx + for(f = 0; f < DCS_FREQUENCY_SLOTS; f++) { + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1 + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (*save_region) & (VREFSEL_MASK | DQSVREFSEL_MASK); + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(n, f) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + } + + // WRDQCALVREFCODECONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = (*save_region); + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_WRDQCALVREFCODECONTROL + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // RDDQCALVREFCODECONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = (*save_region); + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_RDDQCALVREFCODECONTROL + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // CAMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1: shift the status field value into the override field + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + + // RDMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1: shift the status field value into the override field + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + + // WRMDLLVTSCALEREFCONTROL + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + // for DQ0 and DQ1: shift the status field value into the override field + for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) { + reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + } + + // FREQCHNGCTL1_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // FREQCHNGCTL2_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // FREQCHNGCTL2_FREQ3 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(2, 3) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // Elba: Samsung DRAM workaround: disable hw zqcal + // FREQCHNGCTL4_FREQ0 + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) { + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(4, 0) + (ch * DCS_SPACING), reg_val, false); + save_region++; + } + + // CB_IMPCTL + reg_val = *save_region; + save_region++; + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_CB_IMPCTL + (ch * DCS_SPACING), reg_val, false); + + // B0_ODT + reg_val = *save_region; + save_region++; + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_B0_ODT + (ch * DCS_SPACING), reg_val, false); + + // B1_ODT + reg_val = *save_region; + save_region++; + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_B1_ODT + (ch * DCS_SPACING), reg_val, false); + + // DQS0_ODT + reg_val = *save_region; + save_region++; + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_DQS0_ODT + (ch * DCS_SPACING), reg_val, false); + + // DQS1_ODT + reg_val = *save_region; + save_region++; + for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) + reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_DQS1_ODT + (ch * DCS_SPACING), reg_val, false); + + // rGLBTIMER_ZQCTIMER + reg_val = *save_region; + reconfig_command_write(AOP_DDR_AWAKE_POST, rGLBTIMER_ZQCTIMER, reg_val, false); + save_region++; +} +#endif // #if SUB_PLATFORM_S8001 + diff --git a/platform/s8000/dcs/dcs_init_lib_s8000.c b/platform/s8000/dcs/dcs_init_lib_s8000.c new file mode 100644 index 0000000..a592805 --- /dev/null +++ b/platform/s8000/dcs/dcs_init_lib_s8000.c @@ -0,0 +1,849 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Init Sequence Library for use in: + * Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block + */ + +/* +Summary of Steps from the Spec (Spreadsheet) + + + (Aa) Steps 0,1,2,3a [need to identify parameterization] + + (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait] + + (Ac) Steps 3c,4,5 [need to identify parameterization] + + (B) Step 6 [Change Clk Speed] + + (C) Step 7 [include delay-wait from early Step 8] + + (D) Step 8a [Cal: CA 800MHz Vmin] + + (E) Step 8b [Write Regs] + + (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?) + + (G) Step 8d [Write Regs] + + (H) Step 9 [Write Regs] + + (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin] + + (J) Step 11 [Write Regs] + + (K) Step 12 [Cal: CA 1200MHz Vnom] + + (L) Step 13 [Write Regs] + + (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin] + + (N) Steps 15,16,17,18,19,20 [need to identify parameterization] + +Between these steps there is possibly a need/desire for: +- Frequency Changes (PMGR) +- PMU save/restore +- debug messages +- register dumps (DV, SiVal) +- anything else! + +CONFIG Table: + Compile-Time Known: + Type of Execution Environment CoreOS, DV, SiVal + Type of Target SoC, FPGA, Palladium + ChipID 0x8000, 0x8001, etc. + Revision A0, B0, B1, etc. + Num DCS 4, 8, etc. (Derived...!) + Variant Flags Work-arounds, RADAR Ref., et al. + + (Config Info know at Compile time can be subject to #if) + + Run-Time Known: + Type of Init ColdBoot, AOP_DDR, AOP_AWAKE + Debug Flags Low-Level, Milestone, et al. + +RegValue Table + Much like today's: various values for various registers + Sensitive to ChipID (also Target type?) + (Internal static alloc (Complete Table Fill-in within Init function): + Fill in Values (per ChipID/Rev & Target-type) + return pointer to caller + (Allows customization by caller before use) + +TODO: +- Convert to using SPDS for register names, et al + +*/ + +//================================================================================ +// API Definitions +#include +extern dcs_config_t dcs_cfg; +extern dcs_config_params_t dcs_params; + +#if izIBOOT +extern int debug_level_dcs; +#endif + +void dcs_enable_autorefresh(void) +{ + uint32_t arefen_freq0 = 0x1111013f; + uint32_t arefen_freq1 = 0x11110000; + uint32_t arefen_freq2 = 0x11000000; + uint32_t arefen_freq3 = 0x11100000; + + if(dcs_cfg.chipRev < CHIP_REVISION_C0) { + arefen_freq0 = 0x1011013f; + arefen_freq1 = 0x10110000; + arefen_freq2 = 0x10000000; + arefen_freq3 = 0x10100000; + } + + // Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last. + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), arefen_freq3); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), arefen_freq2); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), arefen_freq1); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), arefen_freq0); +} + + + +//================================================================================ +// Implementing the Various Steps of the DCS Init, per Specification +// Based on AMC Init Spec (Spreadsheet) +// - Supporting Maui: Spec (v??) +//================================================================================ +// Step 0: AMC Prolog +//================================================================================ +void dcs_init_Prolog(void) +{ + // NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds + if (izFPGA && izColdBoot) { + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + } +} + +//================================================================================ +// Step 1: AMC Initial Configuration +//================================================================================ +void dcs_init_AMC_Initial_Config(void) +{ + uint32_t i,n; + +// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman + + dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_CHARGEPUMP, 0x00000068); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_1); + + + dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_2); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_LDO, 0x00000004); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_SPLLCTRL_SPLLPWRDNCFG, 0x00000011); + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + for (n = 0; n < dcs_params.num_freqchngctl_regs; n++) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim); + } + + if (dcs_cfg.chipRev < CHIP_REVISION_C0) + dcs_reg_write_all_chan(rDCS_MCU_RWCFG, dcs_params.rwcfg); + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl); + + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat); + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch); + dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref); + dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref); + + if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg); + + } + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params); + dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn); + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate); + + // These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat); + dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000); + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000); + +} + +//================================================================================ +// Step 2: AMP Initial Configuration +//================================================================================ +void dcs_init_AMP_Initial_Config(void) +{ + int i; + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001); + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_NONDQDSPD_F(i), dcs_params.freq[i].nondqdspd); + + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_NONDQDS_F(i), dcs_params.freq[i].nondqds); + + dcs_reg_write_all_chan(rDCS_AMP_CACKCSWKDS, dcs_params.cackcswkds); + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref); + + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(0), dcs_params.freq[0].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(1), dcs_params.freq[1].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(3), dcs_params.freq[3].odt_enable); + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ0,i), dcs_params.freq[i].dqds); + dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ1,i), dcs_params.freq[i].dqds); + } + dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ0,i), dcs_params.freq[i].dqdqsds); + dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ1,i), dcs_params.freq[i].dqdqsds); + } + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref); + } + + + dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ0), dcs_params.dqspdres); + dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ1), dcs_params.dqspdres); + + + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl); + + dcs_reg_write_all_chan(rDCS_AMP_DIFFMODE_FREQ(AMP_DQ0, 3), 0x1); + dcs_reg_write_all_chan(rDCS_AMP_DIFFMODE_FREQ(AMP_DQ1, 3), 0x1); + + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000); + + if (!izFPGA) + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim); + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001); + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001); + } + + if((dcs_params.supported_freqs & DCS_FREQ(1)) != 0) + dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming); + + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming); + } + + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ0), 0x00000002); + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ1), 0x00000002); + + } + + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), dcs_params.rdwrdqcalseglen_f0); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(1), dcs_params.rdwrdqcalseglen_f1); + + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(1), dcs_params.rdwrdqcaltimingctrl1); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(2), dcs_params.rdwrdqcaltimingctrl2); + + + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i); + + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor); + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000); + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000); + } + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_CAOUTDLLSCL_FREQ(i), dcs_params.freq[i].caoutdllscl); + dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ0, i), dcs_params.freq[i].dqsindllscl); + dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ1, i), dcs_params.freq[i].dqsindllscl); + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg); + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg); + } + + if (!izFPGA) { + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1); + + dcs_reg_write_all_chan(rDCS_AMP_IMPAUTOCAL, 0x00010000); + } + + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), dcs_params.dllupdtintvl); + + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100); + + if(!izFPGA) + { + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000000); + } + + + // Workaround for Maui B0 + if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_AMP_BISTRXMODE, 0x0000001c); +// AMPH configuration + + if(dcs_cfg.chipRev >= CHIP_REVISION_B0) + dcs_reg_write_all_chan(rDCS_AMPH_SLC_REG(0), 0x0000003f); + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001); + +} + +//================================================================================ +// Step 3: Self-Refresh Exit +//================================================================================ +void dcs_init_Self_Refresh_Exit_a(void) +{ + // Wait 5 us after Impedence Calibration to avoid McPhyPending + // preventing the SRFSM from exiting SR. + dcs_spin(5, "after Imp. Cal."); + + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + + for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2); + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2); + + if(izFPGA) + if(dcs_cfg.chipRev < CHIP_REVISION_B0) + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params); + + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc); + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030007); + +} + +//======================================== +// Caller Code should: +// - Change Frequency to 50MHz +//======================================== + +void dcs_init_Self_Refresh_Exit_b(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); + + if (!izFPGA) { + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001); + dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00); + } + + if (izResume) + dcs_enable_autorefresh(); + + dcs_spin(2200, "After Enable Auto-Refresh"); + + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + dcs_spin(2, "After SoC Update"); + } + + // Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh + // Issue self-refresh exit cmd for resume boot with MPC + int n = (izColdBoot)? 0x00000000:0x00004000; + // Issue self-refresh exit cmd for resume boot with MPC + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n); + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1); + dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00); + + dcs_spin(2, NULL); + + dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1); +} + +//================================================================================ +// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only) +//================================================================================ +void dcs_init_ZQ_Cal_Cfg(void) +{ + // ZQ calibration START MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f); + // wait 1us for tZQCAL + dcs_spin(1, "tZQCAL"); + + // ZQ calibration LATCH MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51); + // wait 10ns for tZQLAT + dcs_spin(1, "tZQLAT"); + + if (izColdBoot) { + // MR2 register (read/write latency) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0); + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x59); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x59); + + // MR23 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80); + + uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff; + uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I); + + // MR15 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff); + // MR20 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff); + // MR32 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff); + // MR40 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff); + } +} + +//================================================================================ +// Step 5a: AddrConfig Configuration +//================================================================================ +void dcs_init_AddrCfg_Cfg(void) +{ + dcs_reg_write(rAMCC_ADDRCFG_ADDR, dcs_params.addrcfg); +} + +//======================================== +// Caller Code should: +// - Use MR Cmds to Query the Device +//======================================== + +//================================================================================ +// Step 5b: Total Mem Size Config +//================================================================================ +void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes) +{ + dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n", + (((uint64_t)total_size_Mbytes) * MEG * NUM_AMCCS)); + // (Units of 128 MBs in the register) + dcs_reg_write(rAMCC_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1); + dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec); + + dbgprintf(DCS_DBG_ASSESS_CONFIG, "rAMCC_DRAMACCCTRL: 0x%08x\n", rAMCC_DRAMACCCTRL); +} + +//================================================================================ +// Step 6: Switch from boot-clock speed to normal operation speed +//================================================================================ +void dcs_init_Reenable_AMC_Scheduler(void) +{ + // Wait 5 us before freq change to make sure all refreshes have been flushed + dcs_spin(5, "After Refresh"); + + // Enable (again) the AMC Scheduler + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); +} + +//================================================================================ +// Step 7: Setup registers for CA calibration for bucket 1 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq1(void) +{ + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7); + + if (izColdBoot) { + if (izFPGA) { + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00); + } else { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11); + } + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000); + } +} + +//================================================================================ +// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz +//================================================================================ +void dcs_init_CA_Cal_Freq1(void) +{ + // Nothing to be done at this step for cold boot +} + +//================================================================================ +// Step 9: Setup registers for DQ calibration for bucket 1 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq1_a(void) +{ + int i; + + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9); + } + + dcs_spin(1, NULL); + + if(izResume) { + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C); + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000); + for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000); + } +} + +// Caller code should change frequency to bucket 1 +void dcs_init_DQ_Cal_Setup_Freq1_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 10: PHY write DQ calibration +//================================================================================ +void dcs_init_wrdq_skew(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000); + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000); +} + +void dcs_init_post_wrlvl(void) +{ + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010); + } + +} + +//================================================================================ +// Step 11: Setup registers for CA calibration for bucket 0 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq0(void) +{ + if (izColdBoot) { + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000); + } + + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11); + if (!izFPGA) { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11); + } + + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11); + + if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) { + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000); + } + } +} + +//================================================================================ +// Step 12: AMP Dynamic CA Timing Calibration +//================================================================================ + +//================================================================================ +// Step 13: Setup registers for DQ calibration for bucket 0 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq0_a(void) +{ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13); + + // Wait 1 us + dcs_spin(1, NULL); + } +} + +void dcs_init_DQ_Cal_Setup_Freq0_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 14: AMP Dynamic DQ Calibration +//================================================================================ + +//================================================================================ +// Step 15: Setup Registers for Boot +//================================================================================ +void dcs_init_Reg_for_Boot(void) +{ + + if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_AMP_BISTRXMODE, 0x00000000); + + if(dcs_cfg.chipRev >= CHIP_REVISION_C0) + dcs_reg_write_all_chan(rDCS_AMPH_SLC_REG(0), 0x0000013f); + +#ifndef DCS_RUN_AT_50MHZ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15); + } +#endif + + if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1))) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50); + + // Wait 1 us + dcs_spin(1, NULL); + + if (izColdBoot) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), 0xff000008); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), 0xff000008); + +#if !DCS_DO_CALIBRATION + // skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + } +#endif + } + + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000003); + +} + +//================================================================================ +// Step 16: Enable Other Features +//================================================================================ +void dcs_init_MoreFeatures(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren_step16); + + if (izColdBoot) + dcs_enable_autorefresh(); + +} + +//================================================================================ +// Step 17: Enable Fast Critical Word Forwarding Feature +//================================================================================ +void dcs_init_Fast_Critical_Word_Forwarding(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren); + + dcs_reg_poll(rAMCC_MCCPWRONWAYCNTSTATUS_ADDR, 0x7fff7fff, 0x42104210); + dcs_reg_write(rAMCC_MCC0QPROPCTRL_ADDR, 0x300011a2); + dcs_reg_write(rAMCC_MCC1QPROPCTRL_ADDR, 0x300011a2); + dcs_reg_write(rAMCC_MCCGEN_ADDR, dcs_params.mccgen); +} + +//================================================================================ +// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers +//================================================================================ +void dcs_init_Gating_Global_Timers(void) +{ + const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info(); + + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk); + + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten); + + if(!izFPGA) { + + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTPARAM_FREQ(0), 0x01800000); + dcs_reg_write_all_chan(rDCS_MCU_PSQWQCTL1, 0x01640120); + } + + // Global Timer Setup + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev < CHIP_REVISION_B0) { + dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff); + dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000 + dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75 + dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15 + dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000 + dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001); // 300000 + dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x000001); // 300000 + dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000 + } else { + dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x01500150); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x01500150); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02a002a0); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02a002a0); + + dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(0), 0x00900090); + dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(1), 0x00900090); + dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(0), 0x01200120); + dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(1), 0x01200120); + + dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000 + dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75 + dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15 + // skip IDTTIMER setup per spec + //dcs_reg_write(rGLBTIMER_IDTTIMER, 0x007530); // 30000 + dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000 + + // Maui/Malta: Samsung DRAM workaround: disable hw zqcal + if(! ((dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 <= 1)) ) + dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000 + + dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x0493e0); // + dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x0493e0); // + dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000 + + dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(0), 0x00d800d8); + dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(1), 0x00d800d8); + dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(0), 0x00900090); + dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(1), 0x00900090); + } + + // Dynamic Clk & Power Gating + dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a0000); +} + +//================================================================================ +// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading +//================================================================================ +void dcs_init_ODTS(void) +{ + uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need + // INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank]; + + // MR4 read to bring memory out of self-refresh + dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + +} + +//================================================================================ diff --git a/platform/s8000/dcs/dcs_init_lib_s8001.c b/platform/s8000/dcs/dcs_init_lib_s8001.c new file mode 100644 index 0000000..8b4dc16 --- /dev/null +++ b/platform/s8000/dcs/dcs_init_lib_s8001.c @@ -0,0 +1,963 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Init Sequence Library for use in: + * Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block + */ + +/* +Summary of Steps from the Spec (Spreadsheet) + + + (Aa) Steps 0,1,2,3a [need to identify parameterization] + + (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait] + + (Ac) Steps 3c,4,5 [need to identify parameterization] + + (B) Step 6 [Change Clk Speed] + + (C) Step 7 [include delay-wait from early Step 8] + + (D) Step 8a [Cal: CA 800MHz Vmin] + + (E) Step 8b [Write Regs] + + (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?) + + (G) Step 8d [Write Regs] + + (H) Step 9 [Write Regs] + + (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin] + + (J) Step 11 [Write Regs] + + (K) Step 12 [Cal: CA 1200MHz Vnom] + + (L) Step 13 [Write Regs] + + (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin] + + (N) Steps 15,16,17,18,19,20 [need to identify parameterization] + +Between these steps there is possibly a need/desire for: +- Frequency Changes (PMGR) +- PMU save/restore +- debug messages +- register dumps (DV, SiVal) +- anything else! + +CONFIG Table: + Compile-Time Known: + Type of Execution Environment CoreOS, DV, SiVal + Type of Target SoC, FPGA, Palladium + ChipID 0x8000, 0x8001, etc. + Revision A0, B0, B1, etc. + Num DCS 4, 8, etc. (Derived...!) + Variant Flags Work-arounds, RADAR Ref., et al. + + (Config Info know at Compile time can be subject to #if) + + Run-Time Known: + Type of Init ColdBoot, AOP_DDR, AOP_AWAKE + Debug Flags Low-Level, Milestone, et al. + +RegValue Table + Much like today's: various values for various registers + Sensitive to ChipID (also Target type?) + (Internal static alloc (Complete Table Fill-in within Init function): + Fill in Values (per ChipID/Rev & Target-type) + return pointer to caller + (Allows customization by caller before use) + +TODO: +- Convert to using SPDS for register names, et al + +*/ + +//================================================================================ +// API Definitions +#include + +extern dcs_config_t dcs_cfg; +extern dcs_config_params_t dcs_params; + +#if izIBOOT +extern int debug_level_dcs; +#endif + +// : To track throughout the sequence whether we should apply the Samsung DRAM workarounds +static bool apply_samsung_workaround = false; + +void dcs_enable_autorefresh(void) +{ + uint32_t arefen_freq0 = 0x1011013f; + uint32_t arefen_freq1 = 0x10010000; + + // Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last. + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), 0x10100000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), 0x10000000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), arefen_freq1); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), arefen_freq0); +} + +//================================================================================ +// Implementing the Various Steps of the DCS Init, per Specification +// Based on AMC Init Spec (Spreadsheet) +// - Supporting Maui: Spec (v??) +//================================================================================ +// Step 0: AMC Prolog +//================================================================================ +void dcs_init_Prolog(void) +{ + // NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds + if (izFPGA && izColdBoot) { + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + } +} + +//================================================================================ +// Step 1: AMC Initial Configuration +//================================================================================ +void dcs_init_AMC_Initial_Config(void) +{ + uint32_t i,n; + +// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman + + dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec); +#if NUM_AMCCS == 2 + dcs_reg_write(rAMCC1_MCCCHNLDEC_ADDR, dcs_params.chnldec); +#endif + + dcs_reg_write_all_chan(rDCS_SPLLCTRL_CHARGEPUMP, 0x00000068); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_MODEREG, 0x1); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_1); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_2); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_LDO, 0x00000004); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_SPLLCTRL_SPLLPWRDNCFG, 0x00000011); + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + for (n = 0; n < dcs_params.num_freqchngctl_regs; n++) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim); + } + + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALVREFCODECONTROL, dcs_params.wrdqcalvrefcodecontrol); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALVREFCODECONTROL, dcs_params.rddqcalvrefcodecontrol); + + + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFCONTROL, 0x01d0b060); + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFOFFSETCONTROL(1), 0x06040200); + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFOFFSETCONTROL(2), 0x00fafcfe); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFCONTROL, 0x02200060); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFOFFSETCONTROL(1), 0x06040200); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFOFFSETCONTROL(2), 0x00fafcfe); + dcs_reg_write(rGLBTIMER_PERVREFCALCFG, 0x00000003); + dcs_reg_write(rGLBTIMER_VREFCNTRL, 0x00060006); + dcs_reg_write_all_chan(rDCS_MCU_MODEREG, 0x120c90b8); + + if (dcs_cfg.chipRev < CHIP_REVISION_B0) + { + dcs_reg_write_all_chan(rDCS_MCU_RWCFG, dcs_params.rwcfg); + } + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl); + + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat); + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch); + dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref); + dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref); + + if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg); + + } + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params); + dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn); + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate); + + // These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat); + dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000); + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000); + +} + +//================================================================================ +// Step 2: AMP Initial Configuration +//================================================================================ +void dcs_init_AMP_Initial_Config(void) +{ + int i; + + if (dcs_cfg.chipRev < CHIP_REVISION_B0) + { + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCK, 0x00003f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCS, 0x00003f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB0, 0x00003f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS0, 0x00003f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB1, 0x00003f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS1, 0x00003f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCA, 0x00003f3f); + + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCK, 0x00013f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCS, 0x00013f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB0, 0x00013f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS0, 0x00013f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB1, 0x00013f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS1, 0x00013f3f); + dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCA, 0x00013f3f); + } + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref); + + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(0), dcs_params.freq[0].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(1), dcs_params.freq[1].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(3), dcs_params.freq[3].odt_enable); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref); + } + + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl); + + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000); + + if (!izFPGA) + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim); + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001); + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001); + } + + if((dcs_params.supported_freqs & DCS_FREQ(1)) != 0) + dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming); + + + if (dcs_cfg.chipRev < CHIP_REVISION_B0) + { + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming); + } + } + else + { + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(1), 0x04000710); + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(2), 0x04000710); + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(3), 0x04000510); + + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 0), 0x06020704); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 1), 0x04020702); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 2), 0x04020702); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 3), 0x04020504); + + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 0), 0x06020704); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 1), 0x04020702); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 2), 0x04020702); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 3), 0x04020504); + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_RDDQCAL2, 0x00000019); + } + + + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ0), 0x00000002); + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ1), 0x00000002); + + + + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0); + + if (dcs_cfg.chipRev < CHIP_REVISION_B0) + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), dcs_params.rdwrdqcalseglen_f0); + else + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), 0x00040008); + + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(1), dcs_params.rdwrdqcalseglen_f1); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(3), dcs_params.rdwrdqcaltiming_f3); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(1), dcs_params.rdwrdqcaltimingctrl1); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(2), dcs_params.rdwrdqcaltimingctrl2); + + + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(0), 0x87654321); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(1), 0xcdedcba9); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(2), 0x456789ab); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(3), 0x5fa63123); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATINVERTMASK, 0x55550000); + + + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_MAXRDDQS_SDLL_MULFACTOR, dcs_params.maxrddqssdllmulfactor); + dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor); + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000); + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000); + } + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg); + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg); + } + + if (!izFPGA) { + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1); + } + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), dcs_params.dllupdtintvl); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100); + + dcs_reg_write_all_chan(rDCS_AMP_DCCCONTROL, dcs_params.dcccontrol); + dcs_reg_write_all_chan(rDCS_AMP_DCCTIMER, 0x00000190); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALDYNHALFCLKDLYCTRL, 0x00000001); + + +// AMPH configuration + + dcs_reg_write_all_chan(rDCS_AMPH_CB_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_CB_DRIVESTR, dcs_params.cbdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CB_IOCTL, dcs_params.cbioctl); + dcs_reg_write_all_chan(rDCS_AMPH_CK_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_CK_ZDETBIASEN, 0); + dcs_reg_write_all_chan(rDCS_AMPH_CK_DRIVESTR, dcs_params.ckdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CK_IOCTL, dcs_params.ckioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DRIVESTR, dcs_params.b0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B0_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_B0_IOCTL, dcs_params.b0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, dcs_params.b0odt); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODTCTRL, dcs_params.b0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DRIVESTR, dcs_params.b1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODTCTRL, dcs_params.b1odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_B1_IOCTL, dcs_params.b1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, dcs_params.b1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, 0x00000782); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DRIVESTR, dcs_params.dqs0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IOCTL, dcs_params.dqs0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, dcs_params.dqs0odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ZDETBIASEN, dcs_params.dqs0zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODTCTRL, dcs_params.dqs0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, 0x00000782); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DRIVESTR, dcs_params.dqs1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IOCTL, dcs_params.dqs1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, dcs_params.dqs1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ZDETBIASEN, dcs_params.dqs1zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODTCTRL, dcs_params.dqs1odtctrl); + + dcs_reg_write_all_chan(rDCS_AMPH_DBG_REG0, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(1), dcs_params.zcalfsm1); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(0), dcs_params.zcalfsm0); + + if (dcs_cfg.chipRev < CHIP_REVISION_B0) + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), dcs_params.spare0); + else + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), 0x00000816); + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001); + + if (dcs_cfg.chipRev < CHIP_REVISION_B0) + dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming); + else + { + dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, 0x06001604); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 0), 0x06021604); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 0), 0x06021604); + } + + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALTVREF, dcs_params.hwrddqcaltvref); + +} + +//================================================================================ +// Step 3: Self-Refresh Exit +//================================================================================ +void dcs_init_Self_Refresh_Exit_a(void) +{ + // Wait 5 us after Impedence Calibration to avoid McPhyPending + // preventing the SRFSM from exiting SR. + dcs_spin(5, "after Imp. Cal."); + + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + + for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2); + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2); + + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc); + // M8 Bug radar #20346417, two writes to ensure propogation + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030004); + +} + +//======================================== +// Caller Code should: +// - Change Frequency to 50MHz +//======================================== + +void dcs_init_Self_Refresh_Exit_b(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); + + + if (!izFPGA) { + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001); + dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00); + } + + if (izResume) + dcs_enable_autorefresh(); + + dcs_spin(2200, "After Enable Auto-Refresh"); + + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + dcs_spin(2, "After SoC Update"); + } + + // Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh + // Issue self-refresh exit cmd for resume boot with MPC + int n = (izColdBoot)? 0x00000000:0x00004000; + // Issue self-refresh exit cmd for resume boot with MPC + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n); + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1); + dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00); + + dcs_spin(2, NULL); + + dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1); +} + +//================================================================================ +// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only) +//================================================================================ +void dcs_init_ZQ_Cal_Cfg(void) +{ + // ZQ calibration START MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f); + // wait 1us for tZQCAL + dcs_spin(1, "tZQCAL"); + + // ZQ calibration LATCH MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51); + // wait 10ns for tZQLAT + dcs_spin(1, "tZQLAT"); + + if (izColdBoot) { + // MR2 register (read/write latency) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0); + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x59); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x59); + + // MR23 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80); + + uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff; + uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I); + + // MR15 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff); + // MR20 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff); + // MR32 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff); + // MR40 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff); + } +} + +//================================================================================ +// Step 5a: AddrConfig Configuration +//================================================================================ +void dcs_init_AddrCfg_Cfg(void) +{ + + dcs_reg_write(rAMCC_ADDRCFG_ADDR, dcs_params.addrcfg); +#if NUM_AMCCS == 2 + dcs_reg_write(rAMCC1_ADDRCFG_ADDR, dcs_params.addrcfg); +#endif +} + +//======================================== +// Caller Code should: +// - Use MR Cmds to Query the Device +//======================================== + +//================================================================================ +// Step 5b: Total Mem Size Config +//================================================================================ +void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes) +{ + dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n", + (((uint64_t)total_size_Mbytes) * MEG * NUM_AMCCS)); + // (Units of 128 MBs in the register) + dcs_reg_write(rAMCC_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1); + dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec); + +#if NUM_AMCCS == 2 + dcs_reg_write(rAMCC1_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1); + dcs_reg_write(rAMCC1_MCCCHNLDEC_ADDR, dcs_params.chnldec); +#endif + + dbgprintf(DCS_DBG_ASSESS_CONFIG, "rAMCC_DRAMACCCTRL: 0x%08x\n", rAMCC_DRAMACCCTRL); + + const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info(); + if((dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 <= 1)) + apply_samsung_workaround = true; + + if(apply_samsung_workaround) { + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 0), 0x00d800d8); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 0), 0x00d800d8); + + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), 0x00d800d8); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), 0x00d800d8); + + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, 0xf2); + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f); + + dcs_spin(1, " For tZQCAL"); + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51); + + + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(2, 0), 0xb203330b); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(4, 0), 0x00000316); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(2, 3), 0xf203000b); + + dcs_reg_write_all_chan(rDCS_AMPH_CB_IMPCTL, 0x01001c2b); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, 0x01c00339); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, 0x01c00339); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, 0x01c00339); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, 0x01c00339); + } +} + +//================================================================================ +// Step 6: Switch from boot-clock speed to normal operation speed +//================================================================================ +void dcs_init_Reenable_AMC_Scheduler(void) +{ + // Wait 5 us before freq change to make sure all refreshes have been flushed + dcs_spin(5, "After Refresh"); + + // Enable (again) the AMC Scheduler + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); +} + +//================================================================================ +// Step 7: Setup registers for CA calibration for bucket 1 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq1(void) +{ + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7); + + if (izColdBoot) { + if (izFPGA) { + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00); + } else { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11); + } + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000); + } +} + +//================================================================================ +// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz +//================================================================================ +void dcs_init_CA_Cal_Freq1(void) +{ + // Nothing to be done at this step for cold boot +} + +//================================================================================ +// Step 9: Setup registers for DQ calibration for bucket 1 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq1_a(void) +{ + int i; + + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9); + } + + dcs_spin(1, NULL); + + if(izResume) { + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C); + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000); + for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000); + } +} + +// Caller code should change frequency to bucket 1 +void dcs_init_DQ_Cal_Setup_Freq1_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 10: PHY write DQ calibration +//================================================================================ +void dcs_init_wrdq_skew(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000); + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000); +} + + + +//================================================================================ +// Step 11: Setup registers for CA calibration for bucket 0 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq0(void) +{ + if (izColdBoot) { + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000); + } + + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11); + if (!izFPGA) { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11); + // MR3 register + if(apply_samsung_workaround) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, 0xb2); + else + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11); + } + + if(apply_samsung_workaround) { + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x03); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, 0x33); + } else { + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11); + } + + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11); + + if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) { + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000); + } + } +} + +//================================================================================ +// Step 12: AMP Dynamic CA Timing Calibration +//================================================================================ + +//================================================================================ +// Step 13: Setup registers for DQ calibration for bucket 0 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq0_a(void) +{ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13); + + // Wait 1 us + dcs_spin(1, NULL); + } +} + +void dcs_init_DQ_Cal_Setup_Freq0_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 14: AMP Dynamic DQ Calibration +//================================================================================ +void dcs_init_post_wrlvl(void) +{ + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010); + } + if (!izFPGA) + { + + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, dcs_params.dqs0wkpupd); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, dcs_params.dqs1wkpupd); + } +} +//================================================================================ +// Step 15: Setup Registers for Boot +//================================================================================ +void dcs_init_Reg_for_Boot(void) +{ + if (dcs_cfg.chipRev >= CHIP_REVISION_B0) + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), 0xc16); + +#ifndef DCS_RUN_AT_50MHZ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15); + } +#endif + + if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1))) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50); + + // Wait 1 us + dcs_spin(1, NULL); + + if (izColdBoot) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), 0xff000008); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), 0xff000008); + + +#if !DCS_DO_CALIBRATION + // skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + + dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ1), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + } +#endif + } + + + if(!izFPGA) + { + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000003); + } + + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFCONTROL, 0x01D0B061); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFCONTROL, 0x02200061); + +} + +//================================================================================ +// Step 16: Enable Other Features +//================================================================================ +void dcs_init_MoreFeatures(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren_step16); + if (izColdBoot) + dcs_enable_autorefresh(); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL_ASRTIME, dcs_params.b0dyniselasrtime); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL, dcs_params.b0dynisel); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DYN_ISEL, dcs_params.b1dynisel); +} + +//================================================================================ +// Step 17: Enable Fast Critical Word Forwarding Feature +//================================================================================ +void dcs_init_Fast_Critical_Word_Forwarding(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren); + dcs_reg_write(rAMCC_MCCGEN_ADDR, dcs_params.mccgen); + dcs_reg_write(rAMCC_MCC0QPROPCTRL_ADDR, 0x300011a2); + dcs_reg_write(rAMCC_MCC1QPROPCTRL_ADDR, 0x300011a2); + +#if NUM_AMCCS == 2 + dcs_reg_write(rAMCC1_MCCGEN_ADDR, dcs_params.mccgen); + dcs_reg_write(rAMCC1_MCC0QPROPCTRL_ADDR, 0x300011a2); + dcs_reg_write(rAMCC1_MCC1QPROPCTRL_ADDR, 0x300011a2); +#endif // #if NUM_AMCCS == 2 + +} + +//================================================================================ +// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers +//================================================================================ +void dcs_init_Gating_Global_Timers(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_MDLLPWRDNCFG(0), 0x00000001); + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten); + + // Global Timer Setup + + dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0001ff); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x00f000f0); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x00f000f0); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02400240); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02400240); + + dcs_reg_write(rGLBTIMER_CALSEG2ALLBANK(0), 0x00fa0120); + dcs_reg_write(rGLBTIMER_ALLBANK2CALSEG(0), 0x00fa0120); + + dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); + dcs_reg_write(rGLBTIMER_DCCTIMER, 0x000bb8); + dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); + dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); + // Elba A0: Samsung 20nm Rev0 LPDDR4 work-around(disable IDT cal) + //dcs_reg_write(rGLBTIMER_IDTTIMER, 0x007530); // 30000 + dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x002dc6bb); + dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x002dc6c0); + + // Elba: Samsung DRAM workaround: disable hw zqcal + if(!apply_samsung_workaround) + dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); + + dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001); + dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); + + // Dynamic Clk & Power Gating + dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a0000); + +} + +//================================================================================ +// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading +//================================================================================ +void dcs_init_ODTS(void) +{ + uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need + // INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank]; + + // MR4 read to bring memory out of self-refresh + dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp); + // M8 Bug radar #20346417, two writes to ensure propogation + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + +} + +// : This function used in calibration code for Elba +bool shim_apply_samsung_workaround(void) +{ + return apply_samsung_workaround; +} + +//================================================================================ diff --git a/platform/s8000/dcs/dcs_init_lib_s8003.c b/platform/s8000/dcs/dcs_init_lib_s8003.c new file mode 100644 index 0000000..92dcbc7 --- /dev/null +++ b/platform/s8000/dcs/dcs_init_lib_s8003.c @@ -0,0 +1,889 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Init Sequence Library for use in: + * Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block + */ + +/* +Summary of Steps from the Spec (Spreadsheet) + + + (Aa) Steps 0,1,2,3a [need to identify parameterization] + + (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait] + + (Ac) Steps 3c,4,5 [need to identify parameterization] + + (B) Step 6 [Change Clk Speed] + + (C) Step 7 [include delay-wait from early Step 8] + + (D) Step 8a [Cal: CA 800MHz Vmin] + + (E) Step 8b [Write Regs] + + (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?) + + (G) Step 8d [Write Regs] + + (H) Step 9 [Write Regs] + + (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin] + + (J) Step 11 [Write Regs] + + (K) Step 12 [Cal: CA 1200MHz Vnom] + + (L) Step 13 [Write Regs] + + (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin] + + (N) Steps 15,16,17,18,19,20 [need to identify parameterization] + +Between these steps there is possibly a need/desire for: +- Frequency Changes (PMGR) +- PMU save/restore +- debug messages +- register dumps (DV, SiVal) +- anything else! + +CONFIG Table: + Compile-Time Known: + Type of Execution Environment CoreOS, DV, SiVal + Type of Target SoC, FPGA, Palladium + ChipID 0x8000, 0x8001, etc. + Revision A0, B0, B1, etc. + Num DCS 4, 8, etc. (Derived...!) + Variant Flags Work-arounds, RADAR Ref., et al. + + (Config Info know at Compile time can be subject to #if) + + Run-Time Known: + Type of Init ColdBoot, AOP_DDR, AOP_AWAKE + Debug Flags Low-Level, Milestone, et al. + +RegValue Table + Much like today's: various values for various registers + Sensitive to ChipID (also Target type?) + (Internal static alloc (Complete Table Fill-in within Init function): + Fill in Values (per ChipID/Rev & Target-type) + return pointer to caller + (Allows customization by caller before use) + +TODO: +- Convert to using SPDS for register names, et al + +*/ + +//================================================================================ +// API Definitions +#include + +extern dcs_config_t dcs_cfg; +extern dcs_config_params_t dcs_params; + +#if izIBOOT +extern int debug_level_dcs; +#endif + +void dcs_enable_autorefresh(void) +{ + // Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last. + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), 0x11100000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), 0x11000000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), 0x11110000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), 0x1111013f); +} + + + +//================================================================================ +// Implementing the Various Steps of the DCS Init, per Specification +// Based on AMC Init Spec (Spreadsheet) +// - Supporting Maui: Spec (v??) +//================================================================================ +// Step 0: AMC Prolog +//================================================================================ +void dcs_init_Prolog(void) +{ + // NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds + if (izFPGA && izColdBoot) { + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + } +} + +//================================================================================ +// Step 1: AMC Initial Configuration +//================================================================================ +void dcs_init_AMC_Initial_Config(void) +{ + uint32_t i,n; + +// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman + + dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_CHARGEPUMP, 0x00000068); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_1); + + dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_2); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_LDO, 0x00000004); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_SPLLCTRL_SPLLPWRDNCFG, 0x00000011); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + for (n = 0; n < dcs_params.num_freqchngctl_regs; n++) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim); + } + + dcs_reg_write_all_chan(rDCS_MCU_RWCFG, dcs_params.rwcfg); + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl); + + + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat); + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch); + dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref); + dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref); + + if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg); + + } + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params); + dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn); + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate); + + // These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat); + dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000); + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000); + +} + +//================================================================================ +// Step 2: AMP Initial Configuration +//================================================================================ +void dcs_init_AMP_Initial_Config(void) +{ + int i; + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_NONDQDSPD_F(i), dcs_params.freq[i].nondqdspd); + + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_NONDQDS_F(i), dcs_params.freq[i].nondqds); + + dcs_reg_write_all_chan(rDCS_AMP_CACKCSWKDS, dcs_params.cackcswkds); + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref); + + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(0), dcs_params.freq[0].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(1), dcs_params.freq[1].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(3), dcs_params.freq[3].odt_enable); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ0,i), dcs_params.freq[i].dqds); + dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ1,i), dcs_params.freq[i].dqds); + } + dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ0,i), dcs_params.freq[i].dqdqsds); + dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ1,i), dcs_params.freq[i].dqdqsds); + } + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref); + } + + dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ0), dcs_params.dqspdres); + dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ1), dcs_params.dqspdres); + + + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl); + + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000); + + if (!izFPGA) + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim); + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001); + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001); + } + + if((dcs_params.supported_freqs & DCS_FREQ(1)) != 0) + dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming); + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming); + } + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ0), 0x00000002); + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ1), 0x00000002); + + } + + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), dcs_params.rdwrdqcalseglen_f0); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(1), dcs_params.rdwrdqcalseglen_f1); + + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(1), dcs_params.rdwrdqcaltimingctrl1); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(2), dcs_params.rdwrdqcaltimingctrl2); + + + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i); + + + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_MAXRDDQS_SDLL_MULFACTOR, dcs_params.maxrddqssdllmulfactor); + dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQ_SDLL_MULFACTOR, 0x00a00a0f); + + + dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor); + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000); + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000); + } + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + + dcs_reg_write_all_chan(rDCS_AMP_CAOUTDLLSCL_FREQ(i), dcs_params.freq[i].caoutdllscl); + dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ0, i), dcs_params.freq[i].dqsindllscl); + dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ1, i), dcs_params.freq[i].dqsindllscl); + + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg); + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg); + } + + if (!izFPGA) { + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1); + + + dcs_reg_write_all_chan(rDCS_AMP_IMPAUTOCAL, 0x00010000); + + } + + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), dcs_params.dllupdtintvl); + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100); + + if(!izFPGA) { + + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000000); + } + + // Workaround for Maui B0 + if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_AMP_BISTRXMODE, 0x0000001c); + + + +// AMPH configuration + + dcs_reg_write_all_chan(rDCS_AMPH_CB_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_CB_DRIVESTR, dcs_params.cbdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CB_IOCTL, dcs_params.cbioctl); + dcs_reg_write_all_chan(rDCS_AMPH_CK_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_CK_ZDETBIASEN, 0); + dcs_reg_write_all_chan(rDCS_AMPH_CK_DRIVESTR, dcs_params.ckdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CK_IOCTL, dcs_params.ckioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DRIVESTR, dcs_params.b0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B0_IMPCTL, 0x00201c2b); + dcs_reg_write_all_chan(rDCS_AMPH_B0_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_B0_IOCTL, dcs_params.b0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, dcs_params.b0odt); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODTCTRL, dcs_params.b0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DRIVESTR, dcs_params.b1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODTCTRL, dcs_params.b1odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_IMPCTL, 0x00201c2b); + dcs_reg_write_all_chan(rDCS_AMPH_B1_WKPUPD, 0); + dcs_reg_write_all_chan(rDCS_AMPH_B1_IOCTL, dcs_params.b1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, dcs_params.b1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, 0x00000788); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DRIVESTR, dcs_params.dqs0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IMPCTL, 0x00201c2b); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IOCTL, dcs_params.dqs0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, dcs_params.dqs0odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ZDETBIASEN, dcs_params.dqs0zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODTCTRL, dcs_params.dqs0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, 0x00000788); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DRIVESTR, dcs_params.dqs1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IMPCTL, 0x00201c2b); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IOCTL, dcs_params.dqs1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, dcs_params.dqs1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ZDETBIASEN, dcs_params.dqs1zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODTCTRL, dcs_params.dqs1odtctrl); + + + + dcs_reg_write_all_chan(rDCS_AMPH_DBG_REG0, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(1), dcs_params.zcalfsm1); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(0), dcs_params.zcalfsm0); + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), dcs_params.spare0); + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001); + + +} + +//================================================================================ +// Step 3: Self-Refresh Exit +//================================================================================ +void dcs_init_Self_Refresh_Exit_a(void) +{ + // Wait 5 us after Impedence Calibration to avoid McPhyPending + // preventing the SRFSM from exiting SR. + dcs_spin(5, "after Imp. Cal."); + + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + + for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2); + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2); + + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc); + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030007); + + +} + +//======================================== +// Caller Code should: +// - Change Frequency to 50MHz +//======================================== + +void dcs_init_Self_Refresh_Exit_b(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); + + + if (!izFPGA) { + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001); + dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00); + } + + if (izResume) + dcs_enable_autorefresh(); + + dcs_spin(2200, "After Enable Auto-Refresh"); + + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + dcs_spin(2, "After SoC Update"); + } + + // Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh + // Issue self-refresh exit cmd for resume boot with MPC + int n = (izColdBoot)? 0x00000000:0x00004000; + // Issue self-refresh exit cmd for resume boot with MPC + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n); + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1); + dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00); + + dcs_spin(2, NULL); + + dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1); +} + +//================================================================================ +// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only) +//================================================================================ +void dcs_init_ZQ_Cal_Cfg(void) +{ + // ZQ calibration START MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f); + // wait 1us for tZQCAL + dcs_spin(1, "tZQCAL"); + + // ZQ calibration LATCH MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51); + // wait 10ns for tZQLAT + dcs_spin(1, "tZQLAT"); + + if (izColdBoot) { + // MR2 register (read/write latency) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0); + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x59); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x59); + + // MR23 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80); + + uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff; + uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I); + + // MR15 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff); + // MR20 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff); + // MR32 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff); + // MR40 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff); + } +} + +//================================================================================ +// Step 5a: AddrConfig Configuration +//================================================================================ +void dcs_init_AddrCfg_Cfg(void) +{ + + dcs_reg_write(rAMCC_ADDRCFG_ADDR, dcs_params.addrcfg); +} + +//======================================== +// Caller Code should: +// - Use MR Cmds to Query the Device +//======================================== + +//================================================================================ +// Step 5b: Total Mem Size Config +//================================================================================ +void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes) +{ + + dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n", + (((uint64_t)total_size_Mbytes) * MEG * NUM_AMCCS)); + + // (Units of 128 MBs in the register) + dcs_reg_write(rAMCC_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1); + dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec); + + dbgprintf(DCS_DBG_ASSESS_CONFIG, "rAMCC_DRAMACCCTRL: 0x%08x\n", rAMCC_DRAMACCCTRL); +} + +//================================================================================ +// Step 6: Switch from boot-clock speed to normal operation speed +//================================================================================ +void dcs_init_Reenable_AMC_Scheduler(void) +{ + // Wait 5 us before freq change to make sure all refreshes have been flushed + dcs_spin(5, "After Refresh"); + + // Enable (again) the AMC Scheduler + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); +} + +//================================================================================ +// Step 7: Setup registers for CA calibration for bucket 1 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq1(void) +{ + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7); + + if (izColdBoot) { + if (izFPGA) { + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00); + } else { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11); + } + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000); + } +} + +//================================================================================ +// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz +//================================================================================ +void dcs_init_CA_Cal_Freq1(void) +{ + // Nothing to be done at this step for cold boot +} + +//================================================================================ +// Step 9: Setup registers for DQ calibration for bucket 1 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq1_a(void) +{ + int i; + + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9); + } + + dcs_spin(1, NULL); + + if(izResume) { + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C); + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000); + for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000); + } +} + +// Caller code should change frequency to bucket 1 +void dcs_init_DQ_Cal_Setup_Freq1_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 10: PHY write DQ calibration +//================================================================================ +void dcs_init_wrdq_skew(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000); + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000); +} + +void dcs_init_post_wrlvl(void) +{ + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010); + } + + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, dcs_params.dqs0wkpupd); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, dcs_params.dqs1wkpupd); + +} + +//================================================================================ +// Step 11: Setup registers for CA calibration for bucket 0 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq0(void) +{ + if (izColdBoot) { + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000); + } + + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, 0x00000788); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, 0x00000788); + + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11); + if (!izFPGA) { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11); + } + + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11); + + if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) { + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000); + } + } +} + +//================================================================================ +// Step 12: AMP Dynamic CA Timing Calibration +//================================================================================ + +//================================================================================ +// Step 13: Setup registers for DQ calibration for bucket 0 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq0_a(void) +{ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13); + + // Wait 1 us + dcs_spin(1, NULL); + } +} + +void dcs_init_DQ_Cal_Setup_Freq0_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 14: AMP Dynamic DQ Calibration +//================================================================================ + +//================================================================================ +// Step 15: Setup Registers for Boot +//================================================================================ +void dcs_init_Reg_for_Boot(void) +{ + if (dcs_cfg.chipRev > CHIP_REVISION_A0) + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), 0x0000040e); + +#ifndef DCS_RUN_AT_50MHZ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15); + } +#endif + + if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1))) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50); + + // Wait 1 us + dcs_spin(1, NULL); + + if (izColdBoot) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), 0xff000008); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), 0xff000008); + + +#if !DCS_DO_CALIBRATION + // skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + } +#endif + } + + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000003); + +} + +//================================================================================ +// Step 16: Enable Other Features +//================================================================================ +void dcs_init_MoreFeatures(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren_step16); + + if (izColdBoot) + dcs_enable_autorefresh(); + + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL_ASRTIME, dcs_params.b0dyniselasrtime); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL, dcs_params.b0dynisel); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DYN_ISEL, dcs_params.b1dynisel); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DCD_IOCTL, 0x00030000); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DCD_IOCTL, 0x00030000); + + +} + +//================================================================================ +// Step 17: Enable Fast Critical Word Forwarding Feature +//================================================================================ +void dcs_init_Fast_Critical_Word_Forwarding(void) +{ + + dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren); + + dcs_reg_poll(rAMCC_MCCPWRONWAYCNTSTATUS_ADDR, 0x7fff7fff, 0x42104210); + dcs_reg_write(rAMCC_MCC0QPROPCTRL_ADDR, 0x300011a2); + dcs_reg_write(rAMCC_MCC1QPROPCTRL_ADDR, 0x300011a2); + dcs_reg_write(rAMCC_MCCGEN_ADDR, dcs_params.mccgen); +} + +//================================================================================ +// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers +//================================================================================ +void dcs_init_Gating_Global_Timers(void) +{ + const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info(); + + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk); + + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten); + + + if(!izFPGA) { + + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTPARAM_FREQ(0), 0x01800000); + dcs_reg_write_all_chan(rDCS_MCU_PSQWQCTL1, 0x01640120); + } + + // Global Timer Setup + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev < CHIP_REVISION_B0) { + dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff); + dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000 + dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75 + dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15 + dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000 + dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001); // 300000 + dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x000001); // 300000 + dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000 + } else { + dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x01500150); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x01500150); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02a002a0); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02a002a0); + + dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(0), 0x00900090); + dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(1), 0x00900090); + dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(0), 0x01200120); + dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(1), 0x01200120); + + dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000 + dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75 + dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15 + // skip IDTTIMER setup per spec + //dcs_reg_write(rGLBTIMER_IDTTIMER, 0x007530); // 30000 + dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000 + + // Maui/Malta: Samsung DRAM workaround: disable hw zqcal + if(! ((dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 <= 1)) ) + dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000 + + dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x0493e0); // + dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x0493e0); // + dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000 + + dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(0), 0x00d800d8); + dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(1), 0x00d800d8); + dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(0), 0x00900090); + dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(1), 0x00900090); + } + // Dynamic Clk & Power Gating + dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a0000); + +} + +//================================================================================ +// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading +//================================================================================ +void dcs_init_ODTS(void) +{ + uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need + // INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank]; + + // MR4 read to bring memory out of self-refresh + dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + +} + +//================================================================================ diff --git a/platform/s8000/dcs/rules.mk b/platform/s8000/dcs/rules.mk new file mode 100644 index 0000000..3098927 --- /dev/null +++ b/platform/s8000/dcs/rules.mk @@ -0,0 +1,26 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DCS=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dcs.o + +ifeq ($(SUB_PLATFORM),s8000) + ALL_OBJS += $(LOCAL_DIR)/dcs_init_lib_s8000.o +else ifeq ($(SUB_PLATFORM),s8001) + ALL_OBJS += $(LOCAL_DIR)/dcs_init_lib_s8001.o +else ifeq ($(SUB_PLATFORM),s8003) + ALL_OBJS += $(LOCAL_DIR)/dcs_init_lib_s8003.o +else +$(error "Unrecognized SUB_PLATFORM \"$(SUB_PLATFORM)\"") +endif \ No newline at end of file diff --git a/platform/s8000/error_handler/error_handler.c b/platform/s8000/error_handler/error_handler.c new file mode 100644 index 0000000..adb5531 --- /dev/null +++ b/platform/s8000/error_handler/error_handler.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(amcc) + +#define rAMCC_INTEN(n) (*(volatile uint32_t *)(AMCC_BASE_ADDR(n) + AMCC_IRERRDBG_INTEN_OFFSET)) +#define rAMCC_INTSTATUS(n) (*(volatile uint32_t *)(AMCC_BASE_ADDR(n) + AMCC_IRERRDBG_INTSTS_OFFSET)) +#define rAMCC_MCCAFERRLOG2(n) (*(volatile uint32_t *)(AMCC_BASE_ADDR(n) + AMCC_IRERRDBG_MCC_AF_ERR_LOG2_OFFSET)) + +// Enables all errors (the remaining bits are perf counters) +#define AMCC_IRERRDBG_INTEN_ALLERRORS ( AMCC_IRERRDBG_INTSTS_MCC_TP_PAR_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_DAT_ONE_BIT_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_DAT_MULTI_BITS_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_SCE_CLR_DONE_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_AF_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_TP_MULTI_PAR_ERR_UMASK ) + +#define AMCC_INTSTATUS_ALLERRORS AMCC_IRERRDBG_INTEN_ALLERRORS + +#define AMCC_IERRDBG_INTSTS_DRAM_ONE_BIT_ERR AMCC_IRERRDBG_INTSTS_MCC_DAT_ONE_BIT_ERR_UMASK +#define AMCC_IERRDBG_INTSTS_DRAM_MULTI_BIT_ERR AMCC_IRERRDBG_INTSTS_MCC_DAT_MULTI_BITS_ERR_UMASK + +#define AMCC_IRERRDBG_MCCAFERRLOG2_AGENT_IODAP (0x87) + +#define CP_COM_NORM_MSK_CLR_ALL (0xFFFFFFFF) +#define CP_COM_NORM_MSK_ILLEGAL_COH_INTS ((1<<0) | (1<<14)) + +static void amc_int_handler(void *arg) +{ + uint32_t amcc = (uint32_t)(uintptr_t)arg; + uint32_t intsts = rAMCC_INTSTATUS(amcc); + + if ((intsts & (AMCC_IERRDBG_INTSTS_DRAM_ONE_BIT_ERR | AMCC_IERRDBG_INTSTS_DRAM_ONE_BIT_ERR)) == 0) { + // Whitelist errors caused by the IODAP agent (Astris) since + // these are most likely caused by user input errors. + uint32_t agent_id = AMCC_IRERRDBG_MCC_AF_ERR_LOG2_MCC_AF_ERR_AID_LOG_XTRCT(rAMCC_MCCAFERRLOG2(amcc)); + if (agent_id == AMCC_IRERRDBG_MCCAFERRLOG2_AGENT_IODAP) { + dprintf(DEBUG_INFO, "AMC error from IODAP (ignored): 0x%x\n", rAMCC_INTSTATUS(amcc)); + + // Clear the interrupt and continue on. + rAMCC_INTSTATUS(amcc) = intsts; + return; + } + } + + panic("Received unexpected AMC error. AMC_IERRDBG_INTSTATUS = 0x%lx\n", rAMCC_INTSTATUS(amcc)); +} + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +static void cp_int_handler(void *arg __unused) { + panic("Received unexpected Coherency Point error. CP_COM_INT_NORM_REQUEST = 0x%x\n", rCP_COM_INT_NORM_REQUEST); +} +#else +static void cp_int_handler(void *arg) { + panic("Received unexpected Coherency Point %d error. CP_COM_INT_NORM_REQUEST = 0x%x\n", + (uint32_t)arg, + (((uint32_t)arg) == 0) ? rCP0_COM_INT_NORM_REQUEST : rCP1_COM_INT_NORM_REQUEST); +} +#endif + +static void enable_cp_checks() +{ +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + install_int_handler(INT_COHERENCE_PNT_ERR, cp_int_handler, NULL); + rCP_COM_INT_NORM_MASK_CLR = CP_COM_NORM_MSK_CLR_ALL; + unmask_int(INT_COHERENCE_PNT_ERR); +#elif SUB_PLATFORM_S8001 + install_int_handler(INT_COHERENCE_PNT0_ERR, cp_int_handler, (void*)0); + rCP0_COM_INT_NORM_MASK_CLR = CP_COM_NORM_MSK_CLR_ALL; + unmask_int(INT_COHERENCE_PNT0_ERR); + + install_int_handler(INT_COHERENCE_PNT1_ERR, cp_int_handler, (void*)1); + rCP1_COM_INT_NORM_MASK_CLR = CP_COM_NORM_MSK_CLR_ALL; + unmask_int(INT_COHERENCE_PNT1_ERR); +#endif +} + +static void enable_amc_checks() +{ + for (unsigned i = 0; i < NUM_AMCCS; i++) { + uint32_t vector; +#if NUM_AMCCS == 1 + vector = INT_MEM_CONTROLLER0; +#elif NUM_AMCCS == 2 + // Amusingly enough, INT_MEM_CONTROLLER1 is the 1st interrupt of the + // 2nd AMCC on Elba, but the 2nd interrupt of the first/only AMCC on Maui + if (i == 0) vector = INT_MEM_CONTROLLER0; + else vector = INT_MEM_CONTROLLER1; +#else +#error "Unsupported number of AMCCs" +#endif + install_int_handler(vector, amc_int_handler, (void *)(uintptr_t)i); + rAMCC_INTEN(i) = AMCC_IRERRDBG_INTEN_ALLERRORS; + if (rAMCC_INTSTATUS(i) & AMCC_INTSTATUS_ALLERRORS) { + // AMC Interrupts, unlike the CP ones, don't seem to stick. If an error already exists + // this early in bootup, we won't get an interrupt upon unmask. + amc_int_handler((void *)(uintptr_t)i); + } + rAMCC_INTSTATUS(i) = AMCC_INTSTATUS_ALLERRORS; + unmask_int(vector); + } +} + +void platform_enable_error_handler() { + enable_amc_checks(); + enable_cp_checks(); +} + diff --git a/platform/s8000/error_handler/rules.mk b/platform/s8000/error_handler/rules.mk new file mode 100644 index 0000000..ea5fd03 --- /dev/null +++ b/platform/s8000/error_handler/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PLATFORM_ERROR_HANDLER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/error_handler.o diff --git a/platform/s8000/include/platform/apcie.h b/platform/s8000/include/platform/apcie.h new file mode 100644 index 0000000..83d96d8 --- /dev/null +++ b/platform/s8000/include/platform/apcie.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef PLATFORM_APCIE_H +#define PLATFORM_APCIE_H + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +#define APCIE_LANE_CFG_X1_X1_X1_X1 (0) +#define APCIE_LANE_CFG_X2_X1_X1 (1) +#define APCIE_LANE_CFG_X2_X1_X2 (3) + +#define APCIE_LANE_CONFIG_NVME0_X1 APCIE_LANE_CFG_X1_X1_X1_X1 +#define APCIE_LANE_CONFIG_NVME0_X2 APCIE_LANE_CFG_X2_X1_X1 + +#elif SUB_PLATFORM_S8001 +#define APCIE_LANE_CFG_X1_X1_X1_X1_X1_X1 (0) +#define APCIE_LANE_CFG_X2_X1_X1_X1_X1 (1) +#define APCIE_LANE_CFG_X1_X1_X2_X1_X1 (2) +#define APCIE_LANE_CFG_X2_X2_X1_X1 (3) +#define APCIE_LANE_CFG_X1_X1_X1_X1_X2 (4) +#define APCIE_LANE_CFG_X2_X1_X1_X2 (5) +#define APCIE_LANE_CFG_X1_X1_X2_X2 (6) +#define APCIE_LANE_CFG_X2_X2_X2 (7) + +#define APCIE_LANE_CONFIG_NVME0_X1 APCIE_LANE_CFG_X1_X1_X1_X1_X1_X1 +#define APCIE_LANE_CONFIG_NVME0_X2 APCIE_LANE_CFG_X2_X1_X1_X1_X1 + +#endif + +#endif diff --git a/platform/s8000/include/platform/apcie_regs.h b/platform/s8000/include/platform/apcie_regs.h new file mode 100644 index 0000000..ed595b4 --- /dev/null +++ b/platform/s8000/include/platform/apcie_regs.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _APCIE_REGS_H +#define _APCIE_REGS_H + +#include + +#define APCIE_COUNTER_PORT_STRIDE (0x40) +#define APCIE_NUM_COUNTERS (8) + +#define rAPCIE_COUNTER_VALUE(port, n) (*(volatile uint32_t *)(APCIE_COUNTER_BASE_ADDR + (port) * APCIE_COUNTER_PORT_STRIDE + (n) * 4)) +#define rAPCIE_COUNTER_COMMAND(port) (*(volatile uint32_t *)(APCIE_COUNTER_BASE_ADDR + (port) * APCIE_COUNTER_PORT_STRIDE + 0x20)) + +#define APCIE_COUNTER_ENABLE (1) +#define APCIE_COUNTER_CLEAR (2) +#define APCIE_COUNTER_CAPTURE (4) + +#define APCIE_PORT_BASE_ADDR(port) (APCIE_CONFIG_BASE_ADDR + APCIE_CONFIG_PORT_STRIDE * (port)) +#define PCIE_PORT_BASE_ADDR(port) (PCI_CONFIG_BASE + ((port) << PCI_DEVICE_SHIFT)) + +#define rAPCIE_CONFIG_LINKCFG(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x080)) +#define rAPCIE_CONFIG_LINKCTRL(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x084)) +#define rAPCIE_CONFIG_LINKSTS(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x088)) +#define rAPCIE_CONFIG_PMETO(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x08c)) +#define rAPCIE_CONFIG_PMETOACK_TMOTLIM(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x090)) + +#define rAPCIE_CONFIG_INBCTRL(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x130)) +#define rAPCIE_CONFIG_OUTBCTRL(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x134)) +#define rAPCIE_CONFIG_LINKPMGRSTS(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x804)) +#define rAPCIE_CONFIG_LINKCDMSTS(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x808)) + +#define APCIE_CONFIG_LINKCFG_LTSSM_EN (1 << 0) +#define APCIE_CONFIG_LINKSTS_LINK_STATUS (1 << 0) +#define APCIE_CONFIG_LINKSTS_CORE_RST_PEND (1 << 1) +#define APCIE_CONFIG_LINKSTS_PIPE_CLK_ACTIVE (1 << 2) +#define APCIE_CONFIG_LINKSTS_CLKREQ_N (1 << 3) +#define APCIE_CONFIG_LINKSTS_L1_STATE (1 << 4) +#define APCIE_CONFIG_LINKSTS_L1_SUBSTATE (1 << 5) +#define APCIE_CONFIG_LINKSTS_L2_STATE (1 << 6) + +#define APCIE_CONFIG_INBCTRL_CPL_MUST_PUSH_EN (1 << 1) +#define APCIE_CONFIG_OUTBCTRL_EARLY_PT_RESP_EN (1 << 0) + +#define rAPCIE_CONFIG_SPACE8(port, offset) (*(volatile uint8_t *)(PCIE_PORT_BASE_ADDR(port) + (offset))) +#define rAPCIE_CONFIG_SPACE16(port, offset) (*(volatile uint16_t *)(PCIE_PORT_BASE_ADDR(port) + (offset))) +#define rAPCIE_CONFIG_SPACE32(port, offset) (*(volatile uint32_t *)(PCIE_PORT_BASE_ADDR(port) + (offset))) + +#define rAPCIE_PCIE_CAP_LINK_CONTROL2(port) rAPCIE_CONFIG_SPACE16(port, 0xa0) +#define rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(port) rAPCIE_CONFIG_SPACE32(port, 0x710) +#define rAPCIE_PORT_LOGIC_GEN2_CTRL(port) rAPCIE_CONFIG_SPACE32(port, 0x80c) + +#endif /* _APCIE_REGS_H */ diff --git a/platform/s8000/include/platform/dcsconfig.h b/platform/s8000/include/platform/dcsconfig.h new file mode 100644 index 0000000..e104f30 --- /dev/null +++ b/platform/s8000/include/platform/dcsconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCSCONFIG_H +#define __DCSCONFIG_H + +// Needful defnitions for the initializers below +#include +#include +#include +#include + +#include SUB_PLATFORM_HEADER(dcsconfig) + +#endif diff --git a/platform/s8000/include/platform/dcsconfig_s8000.h b/platform/s8000/include/platform/dcsconfig_s8000.h new file mode 100644 index 0000000..59227db --- /dev/null +++ b/platform/s8000/include/platform/dcsconfig_s8000.h @@ -0,0 +1,653 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCSCONFIG_S8000_H +#define __DCSCONFIG_S8000_H + +// Macros for tunables +#define BIT32_MASKFULL (0xFFFFFFFF) +#define BIT32_MASK(_n) (BIT32_MASKFULL >> (32 - (_n))) +#define BIT32_MASK_VAL(_h,_l,_d) (((_d) & BIT32_MASK((_h) - (_l) + 1)) << (_l)) +#define BIT32_MASK_HI_LO(_h,_l) BIT32_MASK_VAL(_h,_l,BIT32_MASKFULL) +#define DCS_MASK_VAL(_h,_l,_d) BIT32_MASK_HI_LO(_h,_l) , BIT32_MASK_VAL(_h,_l,_d) + +// Maui C0 dcs param table +dcs_config_params_t dcs_params = { + .supported_freqs = DCS_FREQ(0) | DCS_FREQ(1) | DCS_FREQ(3), + .num_freqchngctl_regs = 5, + .spllctrl_vco_1 = 0x00000076, + .spllctrl_vco_2 = 0x00000078, + .dllupdtctrl = 0x50017350, + .modereg = 0x140a90b4, + .autoref_params = 0x0015005d, + .pdn = 0x62265295, + .rnkcfg = 0x00006061, + .cackcswkds = 0x000000db, + .dqspdres = 0x00000031, + .casdllupdatectrl = 0x0303030b, + .dqsdllupdatectrl = 0x0003000b, + .rdsdllctrl_step2 = 0x00ff0004, + .wrdqdqssdllctrl_step2 = 0xff000004, + .cawrlvlsdllcode = 0x00ff02ff, + .dlllocktim = 0x012c012c, + .dficaltiming = 0x04000410, + .rdwrdqcaltiming_f0 = 0x00001426, + .rdwrdqcalseglen_f0 = 0x00010002, + .rdwrdqcaltiming_f1 = 0x00001422, + .rdwrdqcalseglen_f1 = 0x00010002, + .rdwrdqcaltimingctrl1 = 0x0000301e, + .rdwrdqcaltimingctrl2 = 0x03111004, + .rddqcalpatprbs4i = 0x55555e26, + .wrdqcalpatprbs4i = 0x55555e26, + .maxwrdqssdllmulfactor = 0xa0a0080c, + .dllupdtctrl1 = 0x50017550, + .dllupdtintvl = 0x10200020, + .arefparam = 0x08010019, + .autoref_params2 = 0x0017005d, + .odtszqc = 0x00001000, + .longsr = 0x01012008, + .freqchngctl_step3 = 0x00010000, + .mr3cmd = 0xf3, + .mr13cmd = 0x18, + .addrcfg = 0x00030201, + .chnldec = 0x00050220, + .mr13cmd_step7 = 0x58, + .mr3cmd_step7 = 0xf3, + .mr22cmd = 0x04, + .mr11cmd = 0x02, + .mr13cmd_step9 = 0xd8, + .freqchngctl_step9 = 0x00010000, + .mr13cmd_step11 = 0x98, + .mr2cmd_step11 = 0x24, + .mr1cmd_step11 = 0xce, + .mr3cmd_step11 = 0xb3, + .mr22cmd_step11 = 0x04, + .mr11cmd_step11 = 0x44, + .mr12cmd_step11 = 0x11, + .mr14cmd_step11 = 0x11, + .mr13cmd_step13 = 0x18, + .mr13cmd_step15 = 0x50, + .freqchngctl_step15 = 0x00009999, + .rdsdllctrl_step15 = 0x00150004, + .odtszqc2 = 0xc0001000, + .qbren_step16 = 0x0000000d, + .qbrparam = 0x000061a5, + .qbren = 0x0000000f, + .mccgen = 0x00000126, + .caampclk = 0x00000000, + .dqampclk = 0x00000000, + .pwrmngten = 0x00000133, + .odtszqc3 = 0xc0003320, + + .freq = { + { // 1200MHz + .clk_period = CLK_PERIOD_1200, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xb303440b, 0xce012402, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00103306, + .phyrdwrtim = 0x00050c0a, + .caspch = 0x531a060b, + .act = 0x18060d0b, + .autoref = 0x366c0078, + .selfref = 0x78071012, + .derate = 0x38c486cc, + .lat2 = 0x00113306, + .tat = 0x01312222, + .mifqmaxctrl = 0x00000100, + .nondqdspd = 0x000b316b, + .cavref = 0x00000003, + .odt_enable = 0x00000001, + .dqds = 0x000c0b08, + .dqdqsds = 0x00030b08, + .dqvref = 0x00c000c0, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00aa01d1, + .wrdqcalwindow = 0x00ca0160, + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x0100070d, + .autoref2 = 0x366c006e, + }, + { // 800MHz + .clk_period = CLK_PERIOD_800, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xf303020b, 0xae015202, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00102206, + .phyrdwrtim = 0x00050b06, + .caspch = 0x42110408, + .act = 0x10040908, + .autoref = 0x24480050, + .selfref = 0x5004b012, + .derate = 0x28835488, + .lat2 = 0x00112206, + .tat = 0x01312222, + .nondqdspd = 0x000b216b, + .nondqds = 0x00000000, + .cavref = 0x00000003, + .odt_enable = 0x00000000, + .dqds = 0x00080b00, + .dqdqsds = 0x00010b00, + .dqvref = 0x00df00df, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00aa01d1, + .wrdqcalwindow = 0x00ca0160, +#ifdef TARGET_DDR_800M + .caoutdllscl = 0x0000000c, + .dqsindllscl = 0x0000000c, +#else + .caoutdllscl = 0x0000000d, + .dqsindllscl = 0x0000000d, +#endif + .rdcapcfg = 0x2100060a, + .autoref2 = 0x24480049, + }, + { // 200MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010b01, + .caspch = 0x40c50402, + .act = 0x04020302, + .autoref = 0x09120014, + .selfref = 0x28013012, + .derate = 0x0c212142, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .nondqdspd = 0x000b3d6b, + .nondqds = 0x00083d08, + .cavref = 0x00000003, + .dqds = 0x00080b00, + .dqdqsds = 0x00080b00, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .caoutdllscl = 0x00000030, + .dqsindllscl = 0x00000030, + .rdcapcfg = 0x41000406, + .autoref2 = 0x09120013, + }, + { // 50MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010901, + .caspch = 0x40c20402, + .act = 0x02020404, + .autoref = 0x03050005, + .selfref = 0x28006012, + .derate = 0x10412082, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .mifqmaxctrl = 0x00000001, + .nondqdspd = 0x000b3d6b, + .nondqds = 0x00083d08, + .cavref = 0x00000003, + .odt_enable = 0x00000000, + .dqds = 0x00080b00, + .dqdqsds = 0x00080b00, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61000406, + .autoref2 = 0x03050005, + } + } +}; + +// DCS Tunables for s8000 C0 +// Tunables Spec versions: +// MCU: https://seg-docs.ecs.apple.com/projects/maui//release/UserManual/tunables_b0/MCU.html dated 2015/06/13 10:26:02 +// AMPSCA: https://seg-docs.ecs.apple.com/projects/maui//release/UserManual/tunables_b0/AMPSCA.html dated 2015/05/14 16:66:34 +// Notes: +// All 4 channels are tuned in exactly the same way +// Registers with all fields' tunable values matching the reset value omitted +const dcs_tunable_t dcs_tunables[] = { + // AMC Clk + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL( 8, 8, 0x1) }, + + // PSQ RQ (Part I) + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(31, 24, 0xFF) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(20, 20, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 4, 4, 0x1) }, + + // PSQ Freq 0 + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x3f4b) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0B4) }, + + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x3f4b) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0B4) }, + + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x3f4b) }, + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0B4) }, + + // PSQ Freq 1 + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x3f87) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x3f87) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x3f87) }, + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + // PSQ RQ (Part II) + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(27, 16, 0x014) }, + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(27, 16, 0x00F) }, + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + // PSQ WQ + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL( 8, 8, 0x1) }, + + // part of init sequence, so have to apply tunables even if same as reset values +#if DISPLAY_D620_TUNABLES + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x0944) }, +#else + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x0494) }, +#endif + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(15, 0, 0x0224) }, + + { rDCS_MCU_PSQWQ_CTL(2), DCS_MASK_VAL(31, 16, 0x002B) }, + { rDCS_MCU_PSQWQ_CTL(2), DCS_MASK_VAL(15, 0, 0x0158) }, + + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + // QoS + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 4, 0, 0x1F) }, + + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL(31, 31, 0x1) }, + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL( 7, 0, 0x6E) }, + + // DRAM Cfg + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL(31, 16, 0x0240) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL( 7, 0, 0x00) }, + +#if DISPLAY_D620_TUNABLES + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x0960) }, +#else + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x04b0) }, +#endif + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL(31, 16, 0x0180) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL(31, 16, 0x0030) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL(31, 16, 0x4002) }, + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL( 0, 0, 0x0) }, + + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(31, 16, 0x4a38) }, + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(15, 0, 0x22d5) }, + + { rDCS_MCU_ROWHAM_CTL(2), DCS_MASK_VAL(15, 0, 0x4a33) }, + + // AMP + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(31, 16, 0x1) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(15, 0, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(15, 0, 0x3) }, + // Alternate End Marker + // { 0, 0, 0 } +}; + +// Maui B0 dcs param table +dcs_config_params_t dcs_params_b0 = { + .supported_freqs = DCS_FREQ(0) | DCS_FREQ(1) | DCS_FREQ(3), + .num_freqchngctl_regs = 5, + .spllctrl_vco_1 = 0x00000076, + .spllctrl_vco_2 = 0x00000078, + .rwcfg = 0x000210ef, + .dllupdtctrl = 0x50017350, + .modereg = 0x140a90b4, + .autoref_params = 0x0015005d, + .pdn = 0x62265295, + .rnkcfg = 0x00006061, + .cackcswkds = 0x000000db, + .dqspdres = 0x00000031, + .casdllupdatectrl = 0x0303030b, + .dqsdllupdatectrl = 0x0003000b, + .rdsdllctrl_step2 = 0x00ff0004, + .wrdqdqssdllctrl_step2 = 0xff000004, + .cawrlvlsdllcode = 0x00ff02ff, + .dlllocktim = 0x012c012c, + .dficaltiming = 0x04000410, + .rdwrdqcaltiming_f0 = 0x00001426, + .rdwrdqcalseglen_f0 = 0x00010002, + .rdwrdqcaltiming_f1 = 0x00001422, + .rdwrdqcalseglen_f1 = 0x00010002, + .rdwrdqcaltimingctrl1 = 0x0000301e, + .rdwrdqcaltimingctrl2 = 0x03111004, + .rddqcalpatprbs4i = 0x55555e26, + .wrdqcalpatprbs4i = 0x55555e26, + .maxwrdqssdllmulfactor = 0xa0a0080c, + .dllupdtctrl1 = 0x50017550, + .dllupdtintvl = 0x10200020, + .arefparam = 0x0d010019, + .autoref_params2 = 0x0017005d, + .odtszqc = 0x00001000, + .longsr = 0x01022008, + .freqchngctl_step3 = 0x00010000, + .mr3cmd = 0xf3, + .mr13cmd = 0x18, + .addrcfg = 0x00030201, + .chnldec = 0x00050220, + .mr13cmd_step7 = 0x58, + .mr3cmd_step7 = 0xf3, + .mr22cmd = 0x04, + .mr11cmd = 0x02, + .mr13cmd_step9 = 0xd8, + .freqchngctl_step9 = 0x00010000, + .mr13cmd_step11 = 0x98, + .mr2cmd_step11 = 0x24, + .mr1cmd_step11 = 0xce, + .mr3cmd_step11 = 0xb3, + .mr22cmd_step11 = 0x04, + .mr11cmd_step11 = 0x44, + .mr12cmd_step11 = 0x11, + .mr14cmd_step11 = 0x11, + .mr13cmd_step13 = 0x18, + .mr13cmd_step15 = 0x50, + .freqchngctl_step15 = 0x00009999, + .rdsdllctrl_step15 = 0x00150004, + .odtszqc2 = 0xc0001000, + .qbren_step16 = 0x0000000d, + .qbrparam = 0x000061a5, + .qbren = 0x0000000f, + .mccgen = 0x00000126, + .caampclk = 0x00000000, + .dqampclk = 0x00000000, + .pwrmngten = 0x00000133, + .odtszqc3 = 0xc0003320, + + .freq = { + { // 1200MHz + .clk_period = CLK_PERIOD_1200, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xb303440b, 0xce012402, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00103306, + .phyrdwrtim = 0x00050c0a, + .caspch = 0x531a060b, + .act = 0x18060d0b, + .autoref = 0x366c0078, + .selfref = 0x78071012, + .derate = 0x38c486cc, + .lat2 = 0x00113306, + .tat = 0x01312222, + .mifqmaxctrl = 0x00000100, + .nondqdspd = 0x000b316b, + .cavref = 0x00000003, + .odt_enable = 0x00000001, + .dqds = 0x000c0b08, + .dqdqsds = 0x00030b08, + .dqvref = 0x00c000c0, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00aa01d1, + .wrdqcalwindow = 0x00ca0160, + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x0100070d, + .autoref2 = 0x366c006e, + }, + { // 800MHz + .clk_period = CLK_PERIOD_800, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xf303020b, 0xae015202, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00102206, + .phyrdwrtim = 0x00050b06, + .caspch = 0x42110408, + .act = 0x10040908, + .autoref = 0x24480050, + .selfref = 0x5004b012, + .derate = 0x28835488, + .lat2 = 0x00112206, + .tat = 0x01312222, + .nondqdspd = 0x000b216b, + .nondqds = 0x00000000, + .cavref = 0x00000003, + .odt_enable = 0x00000000, + .dqds = 0x00080b00, + .dqdqsds = 0x00010b00, + .dqvref = 0x00df00df, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00aa01d1, + .wrdqcalwindow = 0x00ca0160, +#ifdef TARGET_DDR_800M + .caoutdllscl = 0x0000000c, + .dqsindllscl = 0x0000000c, +#else + .caoutdllscl = 0x0000000d, + .dqsindllscl = 0x0000000d, +#endif + .rdcapcfg = 0x2100060a, + .autoref2 = 0x24480049, + }, + { // 200MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010b01, + .caspch = 0x40c50402, + .act = 0x04020302, + .autoref = 0x09120014, + .selfref = 0x28013012, + .derate = 0x0c212142, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .nondqdspd = 0x000b3d6b, + .nondqds = 0x00083d08, + .cavref = 0x00000003, + .dqds = 0x00080b00, + .dqdqsds = 0x00080b00, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .caoutdllscl = 0x00000030, + .dqsindllscl = 0x00000030, + .rdcapcfg = 0x41000406, + .autoref2 = 0x09120013, + }, + { // 50MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010901, + .caspch = 0x40c20402, + .act = 0x02020404, + .autoref = 0x03050005, + .selfref = 0x28006012, + .derate = 0x10412082, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .mifqmaxctrl = 0x00000001, + .nondqdspd = 0x000b3d6b, + .nondqds = 0x00083d08, + .cavref = 0x00000003, + .odt_enable = 0x00000000, + .dqds = 0x00080b00, + .dqdqsds = 0x00080b00, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61000406, + .autoref2 = 0x03050005, + } + } +}; + +// DCS Tunables for s8000 B0 +// Tunables Spec versions: +// MCU: https://seg-docs.ecs.apple.com/projects/maui//release/UserManual/tunables_b0/MCU.html dated 2015/06/09 22:44:29 +// AMPSCA: https://seg-docs.ecs.apple.com/projects/maui//release/UserManual/tunables_b0/AMPSCA.html dated 2014/11/07 14:45:21 +// Notes: +// All 4 channels are tuned in exactly the same way +// Registers with all fields' tunable values matching the reset value omitted +const dcs_tunable_t dcs_tunables_b0[] = { + // AMC Clk + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL( 8, 8, 0x1) }, + + // PSQ RQ (Part I) + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(31, 24, 0xFF) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(20, 20, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 8, 8, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 4, 4, 0x0) }, + + // PSQ Freq 0 + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x0) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0B4) }, + + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x0) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0B4) }, + + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x0) }, + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0B4) }, + + // PSQ Freq 1 + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x0) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x0) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x0) }, + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + // PSQ RQ (Part II) + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(27, 16, 0x014) }, + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(27, 16, 0x00F) }, + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + // PSQ WQ + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL( 8, 8, 0x1) }, + + // part of init sequence, so have to apply tunables even if same as reset values +#if DISPLAY_D620_TUNABLES + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x0944) }, +#else + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x0494) }, +#endif + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(15, 0, 0x0224) }, + + { rDCS_MCU_PSQWQ_CTL(2), DCS_MASK_VAL(31, 16, 0x002B) }, + { rDCS_MCU_PSQWQ_CTL(2), DCS_MASK_VAL(15, 0, 0x0158) }, + + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + // QoS + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 4, 0, 0x1F) }, + + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL(31, 31, 0x1) }, + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL( 7, 0, 0x6E) }, + + // DRAM Cfg + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL(31, 16, 0x0240) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL( 7, 0, 0x00) }, + +#if DISPLAY_D620_TUNABLES + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x0960) }, +#else + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x04b0) }, +#endif + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL(31, 16, 0x0180) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL(31, 16, 0x0030) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL(31, 16, 0x4002) }, + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL( 0, 0, 0x0) }, + + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(31, 16, 0x4a38) }, + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(15, 0, 0x22d4) }, + + { rDCS_MCU_ROWHAM_CTL(2), DCS_MASK_VAL(15, 0, 0x4a33) }, + + // AMP + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(15, 0, 0x3) }, + // Alternate End Marker + // { 0, 0, 0 } +}; + +#endif diff --git a/platform/s8000/include/platform/dcsconfig_s8001.h b/platform/s8000/include/platform/dcsconfig_s8001.h new file mode 100644 index 0000000..86b5ce2 --- /dev/null +++ b/platform/s8000/include/platform/dcsconfig_s8001.h @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCSCONFIG_S8001_H +#define __DCSCONFIG_S8001_H + +dcs_config_params_t dcs_params = { + .supported_freqs = DCS_FREQ(0) | DCS_FREQ(3), + .num_freqchngctl_regs = 5, + .spllctrl_vco_1 = 0x00000016, + .spllctrl_vco_2 = 0x00000015, + .wrdqcalvrefcodecontrol = 0x19191111, + .rddqcalvrefcodecontrol = 0x19191191, + .rwcfg = 0x000210ef, + .dllupdtctrl = 0x50017350, + .modereg = 0x1a0cc0f4, + .autoref_params = 0x0015005d, + .pdn = 0x722762c6, + .rnkcfg = 0x00006061, + .casdllupdatectrl = 0x03030305, + .dqsdllupdatectrl = 0x00030005, + .rdsdllctrl_step2 = 0x00ff0002, + .wrdqdqssdllctrl_step2 = 0xff000002, + .cawrlvlsdllcode = 0x00ff01ff, + .dlllocktim = 0x00c801f4, + .rdwrdqcaltiming_f0 = 0x01040508, + .rdwrdqcalseglen_f0 = 0x000c0012, + .rdwrdqcaltiming_f1 = 0x01040402, + .rdwrdqcalseglen_f1 = 0x000c0012, + .rdwrdqcaltiming_f3 = 0x01040508, + .rdwrdqcaltimingctrl1 = 0x0000381e, + .rdwrdqcaltimingctrl2 = 0x01141101, + .rddqcalpatprbs4i = 0x55553c5a, + .wrdqcalpatprbs4i = 0x00003c5a, + .maxrddqssdllmulfactor = 0x00a01414, + .maxwrdqssdllmulfactor = 0xa0a00c0d, + .dllupdtctrl1 = 0x80017580, + .dllupdtintvl = 0x10200020, + .dcccontrol = 0x10050b27, + .dcccal = 0x40401320, + .cbdrivestr = 0x33838317, + .cbioctl = 0x00020023, + .ckdrivestr = 0x33838317, + .ckioctl = 0x00000027, + .b0drivestr = 0x33838317, + .b0ioctl = 0x71500027, + .b0odt = 0x01c00333, + .b0odtctrl = 0x00000007, + .b1drivestr = 0x33838317, + .b1ioctl = 0x71500027, + .b1odt = 0x01c00333, + .b1odtctrl = 0x00000007, + .dqs0drivestr = 0x33838317, + .dqs0ioctl = 0x71500007, + .dqs0odt = 0x01c00336, + .dqs0zdetbiasen = 0x00060028, + .dqs0odtctrl = 0x00000007, + .dqs1drivestr = 0x33838317, + .dqs1ioctl = 0x71500007, + .dqs1odt = 0x01c00336, + .dqs1zdetbiasen = 0x00060028, + .dqs1odtctrl = 0x00000007, + .zcalfsm1 = 0x00887f7f, + .zcalfsm0 = 0x000f031b, + .spare0 = 0x00000016, + .dficaltiming = 0x06000504, + .hwrddqcaltvref = 0x08080808, + .arefparam = 0x0d012019, + .autoref_params2 = 0x0017005d, + .odtszqc = 0x00001000, + .longsr = 0x01022008, + .freqchngctl_step3 = 0x01010000, + .mr3cmd = 0xf3, + .mr13cmd = 0x18, + .addrcfg = 0x00030201, + .chnldec = 0x00050120, + // steps 7-10 are skipped for Elba since freq bucket 1 not used + .mr13cmd_step11 = 0x58, + .mr2cmd_step11 = 0x2d, + .mr1cmd_step11 = 0xde, + .mr3cmd_step11 = 0xb3, + .mr22cmd_step11 = 0x04, + .mr11cmd_step11 = 0x44, + .mr12cmd_step11 = 0x11, + .mr14cmd_step11 = 0x11, + .mr13cmd_step13 = 0x98, + .dqs0wkpupd = 0x00010782, + .dqs1wkpupd = 0x00010782, + .mr13cmd_step15 = 0x90, + .freqchngctl_step15 = 0x00009999, + .rdsdllctrl_step15 = 0x00140004, + .odtszqc2 = 0xc0001000, + .qbren_step16 = 0x0000000d, + .b0dyniselasrtime = 0x00000019, + .b0dynisel = 0x00000001, + .b1dynisel = 0x00000000, + .qbrparam = 0x000000a8, + .qbren = 0x0000000f, + .mccgen = 0x00000126, + .caampclk = 0x00000000, + .dqampclk = 0x00000000, + .pwrmngten = 0x00000133, + .odtszqc3 = 0xc0003320, + + .freq = { + { // 1600MHz + .clk_period = CLK_PERIOD_1600, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xb303440b, 0xde012d02, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00103387, + .phyrdwrtim = 0x00060d0c, + .caspch = 0x63e2080f, + .act = 0x2008110f, + .autoref = 0x48900078, + .selfref = 0xa0096012, + .derate = 0x4d05a910, + .lat2 = 0x00123387, + .tat = 0x01412222, + .mifqmaxctrl = 0x00000100, + .cavref = 0x00000003, + .odt_enable = 0x00000001, + .dqvref = 0x00c000c0, + .dqdficaltiming = 0x06020404, + .rddqcalwindow = 0x00ff01d1, + .wrdqcalwindow = 0x00ff0160, + .rdcapcfg = 0x01000810, + .autoref2 = 0x48900092, + }, + { // 800MHz + .freqchngctl = {0x18cd104d, 0x110c110e, 0xd303220b, 0xae015202, 0x00000216}, + .freqchngtim = 0x000c1108, + .lat = 0x00102206, + .phyrdwrtim = 0x00050b06, + .caspch = 0x42110408, + .act = 0x10040908, + .autoref = 0x24480050, + .selfref = 0x5004b012, + .derate = 0x28835488, + .lat2 = 0x00112206, + .tat = 0x01312222, + .cavref = 0x00000003, + .odt_enable = 0x00000001, + .dqvref = 0x00c000c0, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00ff01d1, + .wrdqcalwindow = 0x00ff0160, + .rdcapcfg = 0x2100060a, + .autoref2 = 0x24480049, + }, + { // 200MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010b01, + .caspch = 0x40c50402, + .act = 0x04020302, + .autoref = 0x09120014, + .selfref = 0x28013012, + .derate = 0x0c212142, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .cavref = 0x00000003, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rdcapcfg = 0x41000408, + .autoref2 = 0x09120013, + }, + { // 50MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010901, + .caspch = 0x40c20402, + .act = 0x02020404, + .autoref = 0x03050005, + .selfref = 0x28006012, + .derate = 0x10412082, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .mifqmaxctrl = 0x00000001, + .cavref = 0x00000003, + .odt_enable = 0x00000000, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020404, + .rdcapcfg = 0x61000408, + .autoref2 = 0x03050005, + } + } +}; + +#define BIT32_MASKFULL (0xFFFFFFFF) +#define BIT32_MASK(_n) (BIT32_MASKFULL >> (32 - (_n))) +#define BIT32_MASK_VAL(_h,_l,_d) (((_d) & BIT32_MASK((_h) - (_l) + 1)) << (_l)) +#define BIT32_MASK_HI_LO(_h,_l) BIT32_MASK_VAL(_h,_l,BIT32_MASKFULL) +#define DCS_MASK_VAL(_h,_l,_d) BIT32_MASK_HI_LO(_h,_l) , BIT32_MASK_VAL(_h,_l,_d) + +// DCS Tunables for s8001 B0 +// Tunables Spec versions: +// MCU: https://seg-docs.ecs.apple.com/projects/elba//release/UserManual/tunables_a0/MCU.html v14.2.0 +// AMPSCA: https://seg-docs.ecs.apple.com/projects/elba//release/UserManual/tunables_a0/AMPSCA.html dated 2014/11/10 13:03:48 +// Notes: +// All channels are tuned in exactly the same way +// Registers with all fields' tunable values matching the reset value omitted +const dcs_tunable_t dcs_tunables[] = { + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL( 8, 8, 0x1) }, + + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(31, 24, 0xFF) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(20, 20, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 4, 4, 0x1) }, + + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(27, 16, 0x014) }, + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(27, 16, 0x00F) }, + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL( 8, 8, 0x1) }, + + // part of init sequence, so have to apply tunables even if same as reset values + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x0164) }, + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(15, 0, 0x02DA) }, + + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(20, 16, 0x08) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 4, 0, 0x1F) }, + + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL(31, 31, 0x1) }, + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL(15, 8, 0x6F) }, + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL( 7, 0, 0x6E) }, + + // DRAM Cfg + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL(31, 16, 0x0300) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x0180) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL(31, 16, 0x0180) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL(31, 16, 0x0030) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL(31, 16, 0x4002) }, + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL( 0, 0, 0x0) }, + + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(31, 16, 0x4A38) }, + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(15, 0, 0x22D5) }, + + { rDCS_MCU_ROWHAM_CTL(2), DCS_MASK_VAL(15, 0, 0x4A33) }, + + // AMP + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(15, 0, 0x3) }, + // Alternate End Marker + // { 0, 0, 0 } +}; + + + +#endif diff --git a/platform/s8000/include/platform/dcsconfig_s8003.h b/platform/s8000/include/platform/dcsconfig_s8003.h new file mode 100644 index 0000000..1919fc0 --- /dev/null +++ b/platform/s8000/include/platform/dcsconfig_s8003.h @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCSCONFIG_S8003_H +#define __DCSCONFIG_S8003_H + +dcs_config_params_t dcs_params = { + .supported_freqs = DCS_FREQ(0) | DCS_FREQ(1) | DCS_FREQ(3), + .num_freqchngctl_regs = 5, + .spllctrl_vco_1 = 0x00000076, + .spllctrl_vco_2 = 0x00000078, + .rwcfg = 0x000410ef, + .dllupdtctrl = 0x50017350, + .modereg = 0x140a90b4, + .autoref_params = 0x0015005d, + .pdn = 0x62265295, + .rnkcfg = 0x00006061, + .cackcswkds = 0x000000db, + .dqspdres = 0x00000001, + .casdllupdatectrl = 0x0303030b, + .dqsdllupdatectrl = 0x0003000b, + .rdsdllctrl_step2 = 0x00ff0004, + .wrdqdqssdllctrl_step2 = 0xff000004, + .cawrlvlsdllcode = 0x00ff02ff, + .dlllocktim = 0x012c012c, + .dficaltiming = 0x04000410, + .rdwrdqcaltiming_f0 = 0x00001426, + .rdwrdqcalseglen_f0 = 0x00010002, + .rdwrdqcaltiming_f1 = 0x00001422, + .rdwrdqcalseglen_f1 = 0x00010002, + .rdwrdqcaltimingctrl1 = 0x0000301e, + .rdwrdqcaltimingctrl2 = 0x03111004, + .rddqcalpatprbs4i = 0x55555e26, + .wrdqcalpatprbs4i = 0x55555e26, + .maxrddqssdllmulfactor = 0x00a01414, + .maxwrdqssdllmulfactor = 0xa0a00c0c, + .dllupdtctrl1 = 0x50017550, + .dllupdtintvl = 0x10200020, + .cbdrivestr = 0x33831717, + .cbioctl = 0x000200a3, + .ckdrivestr = 0x33831717, + .ckioctl = 0x000000a7, + .b0drivestr = 0x33831717, + .b0ioctl = 0x715000a7, + .b0odt = 0x01c00333, + .b0odtctrl = 0x00000005, + .b1drivestr = 0x33831717, + .b1ioctl = 0x715000a7, + .b1odt = 0x01c00333, + .b1odtctrl = 0x00000005, + .dqs0drivestr = 0x33831717, + .dqs0ioctl = 0x715000a7, + .dqs0odt = 0x01c00333, + .dqs0zdetbiasen = 0x00060028, + .dqs0odtctrl = 0x00000007, + .dqs1drivestr = 0x33831717, + .dqs1ioctl = 0x715000a7, + .dqs1odt = 0x01c00333, + .dqs1zdetbiasen = 0x00060028, + .dqs1odtctrl = 0x00000007, + .zcalfsm1 = 0x00667f7f, + .zcalfsm0 = 0x000f0315, + .spare0 = 0x0000000e, + .arefparam = 0x08010019, + .autoref_params2 = 0x0017005d, + .odtszqc = 0x00001000, + .longsr = 0x01012008, + .freqchngctl_step3 = 0x00010000, + .mr3cmd = 0xf3, + .mr13cmd = 0x18, + .addrcfg = 0x00030201, + .chnldec = 0x00050220, + .mr13cmd_step7 = 0x58, + .mr3cmd_step7 = 0xf3, + .mr22cmd = 0x04, + .mr11cmd = 0x03, + .mr13cmd_step9 = 0xd8, + .freqchngctl_step9 = 0x00010000, + .dqs0wkpupd = 0x00030788, + .dqs1wkpupd = 0x00030788, + .mr13cmd_step11 = 0x98, + .mr2cmd_step11 = 0x24, + .mr1cmd_step11 = 0xce, + .mr3cmd_step11 = 0xb3, + .mr22cmd_step11 = 0x04, + .mr11cmd_step11 = 0x44, + .mr12cmd_step11 = 0x11, + .mr14cmd_step11 = 0x11, + .mr13cmd_step13 = 0x18, + .mr13cmd_step15 = 0x50, + .freqchngctl_step15 = 0x00009999, + .rdsdllctrl_step15 = 0x001a0004, + .odtszqc2 = 0xc0001000, + .qbrparam = 0x000061a5, + .qbren_step16 = 0x0000000d, + .b0dyniselasrtime = 0x00001117, + .b0dynisel = 0x00000003, + .b1dynisel = 0x00000003, + .qbren = 0x0000000f, + .mccgen = 0x00000126, + .caampclk = 0x00000000, + .dqampclk = 0x00000000, + .pwrmngten = 0x00000133, + .odtszqc3 = 0xc0003320, + + .freq = { + { // 1200MHz + .clk_period = CLK_PERIOD_1200, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xb303440b, 0xce012402, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00103306, + .phyrdwrtim = 0x00050d0a, + .caspch = 0x531a060b, + .act = 0x18060d0b, + .autoref = 0x366c0078, + .selfref = 0x78071012, + .derate = 0x38c486cc, + .lat2 = 0x00113306, + .tat = 0x01312222, + .mifqmaxctrl = 0x00000100, + .nondqdspd = 0x000b316b, + .cavref = 0x00000003, + .odt_enable = 0x00000001, + .dqds = 0x000c0b08, + .dqdqsds = 0x000c0b08, + .dqvref = 0x00c000c0, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00b101d1, + .wrdqcalwindow = 0x012f0360, + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x0100080d, + .autoref2 = 0x366c006e, + }, + { // 800MHz + .clk_period = CLK_PERIOD_800, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xf303030b, 0xae015202, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00102206, + .phyrdwrtim = 0x00050c06, + .caspch = 0x42110408, + .act = 0x10040908, + .autoref = 0x24480050, + .selfref = 0x5004b012, + .derate = 0x28835488, + .lat2 = 0x00112206, + .tat = 0x01312222, + .nondqdspd = 0x000b216b, + .nondqds = 0x00080508, + .cavref = 0x00000003, + .odt_enable = 0x00000001, + .dqds = 0x00080b00, + .dqdqsds = 0x00080b00, + .dqvref = 0x00c000c0, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00f801d1, + .wrdqcalwindow = 0x012f0360, +#ifdef TARGET_DDR_800M + .caoutdllscl = 0x0000000c, + .dqsindllscl = 0x0000000c, +#else + .caoutdllscl = 0x0000000d, + .dqsindllscl = 0x0000000d, +#endif + .rdcapcfg = 0x2100070a, + .autoref2 = 0x24480049, + }, + { // 200MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010c01, + .caspch = 0x40c50402, + .act = 0x04020302, + .autoref = 0x09120014, + .selfref = 0x28013012, + .derate = 0x0c212142, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .nondqdspd = 0x000b3d6b, + .nondqds = 0x00083d08, + .cavref = 0x00000003, + .dqds = 0x00080b00, + .dqdqsds = 0x00080b00, + .dqvref = 0x00800080, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .caoutdllscl = 0x00000030, + .dqsindllscl = 0x00000030, + .rdcapcfg = 0x41000508, + .autoref2 = 0x09120013, + }, + { // 50MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010a01, + .caspch = 0x40c20402, + .act = 0x02020404, + .autoref = 0x03050005, + .selfref = 0x28006012, + .derate = 0x10412082, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .mifqmaxctrl = 0x00000001, + .nondqdspd = 0x000b3d6b, + .nondqds = 0x00083d08, + .cavref = 0x00000003, + .odt_enable = 0x00000000, + .dqds = 0x00080b00, + .dqdqsds = 0x00080b00, + .dqvref = 0x00800080, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61000508, + .autoref2 = 0x03050005, + } + } +}; + +#define BIT32_MASKFULL (0xFFFFFFFF) +#define BIT32_MASK(_n) (BIT32_MASKFULL >> (32 - (_n))) +#define BIT32_MASK_VAL(_h,_l,_d) (((_d) & BIT32_MASK((_h) - (_l) + 1)) << (_l)) +#define BIT32_MASK_HI_LO(_h,_l) BIT32_MASK_VAL(_h,_l,BIT32_MASKFULL) +#define DCS_MASK_VAL(_h,_l,_d) BIT32_MASK_HI_LO(_h,_l) , BIT32_MASK_VAL(_h,_l,_d) + +// DCS Tunables for s8003 +// Tunables Spec versions: +// MCU: https://seg-docs.ecs.apple.com/projects/malta//release/UserManual/tunables/MCU.html dated 2015/06/09 22:36:07 +// AMPSCA: https://seg-docs.ecs.apple.com/projects/malta//release/UserManual/tunables/AMPSCA.html dated 2014/11/10 +// All 4 channels are tuned in exactly the same way +const dcs_tunable_t dcs_tunables[] = { + // AMC Clk + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL( 8, 8, 0x1) }, + + // PSQ RQ (Part I) + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(31, 24, 0xFF) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(20, 20, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 4, 4, 0x1) }, + + // PSQ Freq 0 + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x3f4b) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0b4) }, + + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x3f4b) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0b4) }, + + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL(29, 16, 0x3f4b) }, + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQSOCLLT_FREQ(0), DCS_MASK_VAL( 8, 0, 0x0b4) }, + + // PSQ Freq 1 + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x3f87) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU0LLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x3f87) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQCPU1LLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL(29, 16, 0x3f87) }, + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_PSQSOCLLT_FREQ(1), DCS_MASK_VAL( 8, 0, 0x078) }, + + // PSQ RQ (Part II) + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(27, 16, 0x014) }, + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(27, 16, 0x00f) }, + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + // PSQ WQ + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL( 8, 8, 0x1) }, + + // part of init sequence, so have to apply tunables even if same as reset values +#if DISPLAY_D620_TUNABLES + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x0944) }, +#else + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x0494) }, +#endif + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(15, 0, 0x0224) }, + + { rDCS_MCU_PSQWQ_CTL(2), DCS_MASK_VAL(31, 16, 0x002b) }, + { rDCS_MCU_PSQWQ_CTL(2), DCS_MASK_VAL(15, 0, 0x0158) }, + + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + // QoS + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 4, 0, 0x1f) }, + + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL(31, 31, 0x1) }, + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL( 7, 0, 0x6e) }, + + // DRAM Cfg + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL(31, 16, 0x0240) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL( 7, 0, 0x00) }, + +#if DISPLAY_D620_TUNABLES + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x0960) }, +#else + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x04b0) }, +#endif + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL(31, 16, 0x0180) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL(31, 16, 0x0030) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL(31, 16, 0x4002) }, + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL( 0, 0, 0x0) }, + + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(31, 16, 0x4a38) }, + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(15, 0, 0x22d5) }, + + { rDCS_MCU_ROWHAM_CTL(2), DCS_MASK_VAL(15, 0, 0x4a33) }, + + // AMP + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(15, 0, 0x3) }, + // Alternate End Marker + // { 0, 0, 0 } +}; + +#endif diff --git a/platform/s8000/include/platform/error_handler.h b/platform/s8000/include/platform/error_handler.h new file mode 100644 index 0000000..e0130ce --- /dev/null +++ b/platform/s8000/include/platform/error_handler.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_ERROR_HANDLER_H +#define __PLATFORM_ERROR_HANDLER_H + +void platform_enable_error_handler(); + +#endif // __PLATFORM_ERROR_HANDLER_H diff --git a/platform/s8000/include/platform/gpiodef.h b/platform/s8000/include/platform/gpiodef.h new file mode 100644 index 0000000..e9964b5 --- /dev/null +++ b/platform/s8000/include/platform/gpiodef.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +#include +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +#if SUB_PLATFORM_S8003 +#include +#else +#include SUB_PLATFORM_HEADER(gpiodef) +#endif + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/s8000/include/platform/gpiodef_s8000.h b/platform/s8000/include/platform/gpiodef_s8000.h new file mode 100644 index 0000000..bf5e94e --- /dev/null +++ b/platform/s8000/include/platform/gpiodef_s8000.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_S8000_H +#define __PLATFORM_GPIODEF_S8000_H + +#if !SUB_PLATFORM_S8000 && !SUB_PLATFORM_S8003 +#error "Only include for S8000 platform" +#endif + +/* S8000 specific gpio -> pin mappings - Fiji I/O Spreadsheet v9.3 */ + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_BOARD_ID0 GPIO(103) +#define GPIO_BOARD_ID1 GPIO(104) +#define GPIO_BOARD_ID2 GPIO(105) +#define GPIO_BOARD_ID3 GPIO(80) +#define GPIO_BOARD_ID4 GPIO(138) + +/* Boot configuration pins */ +#define GPIO_BOOT_CONFIG0 GPIO(82) +#define GPIO_BOOT_CONFIG1 GPIO(122) +#define GPIO_BOOT_CONFIG2 GPIO(137) + +/* Boot configuration pin encodings */ +#define BOOT_CONFIG_SPI0 (0) +#define BOOT_CONFIG_SPI0_TEST (1) +#define BOOT_CONFIG_NVME0_X2 (2) +#define BOOT_CONFIG_NVME0_X2_TEST (3) +#define BOOT_CONFIG_NVME0_X1 (4) +#define BOOT_CONFIG_NVME0_X1_TEST (5) +#define BOOT_CONFIG_SLOW_SPI0_TEST (6) +#define BOOT_CONFIG_FAST_SPI0_TEST (7) + +#define GPIO_REQUEST_DFU1 GPIO(97) // HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO(96) // MENU_KEY +#define GPIO_FORCE_DFU GPIO(123) // FORCE_DFU +#define GPIO_DFU_STATUS GPIO(136) // DFU_STATUS + +#define SPI_NOR0 (0) + +#define GPIO_SPI0_SCLK GPIO(103) +#define GPIO_SPI0_MOSI GPIO(104) +#define GPIO_SPI0_MISO GPIO(105) +#define GPIO_SPI0_SSIN GPIO(106) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#else +#define GPIO_SPI0_CS GPIO(106) // Alias of GPIO_SPI0_SSIN +#endif + +#define GPIO_IIC0_SCL GPIO(46) +#define GPIO_IIC0_SDA GPIO(45) +#define GPIO_IIC1_SCL GPIO(115) +#define GPIO_IIC1_SDA GPIO(114) +#define GPIO_IIC2_SCL GPIO(23) +#define GPIO_IIC2_SDA GPIO(22) + +#define GPIO_PCIE0_PERST GPIO(160) +#define GPIO_PCIE1_PERST GPIO(161) +#define GPIO_PCIE2_PERST GPIO(162) +#define GPIO_PCIE3_PERST GPIO(163) +#define GPIO_PCIE0_CLKREQ GPIO(164) +#define GPIO_PCIE1_CLKREQ GPIO(165) +#define GPIO_PCIE2_CLKREQ GPIO(166) +#define GPIO_PCIE3_CLKREQ GPIO(167) + +#define GPIO_NAND_SYS_CLK GPIO(196) + +#endif /* ! __PLATFORM_GPIODEF_S8000_H */ diff --git a/platform/s8000/include/platform/gpiodef_s8001.h b/platform/s8000/include/platform/gpiodef_s8001.h new file mode 100644 index 0000000..3395cb1 --- /dev/null +++ b/platform/s8000/include/platform/gpiodef_s8001.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 20124 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_S8001_H +#define __PLATFORM_GPIODEF_S8001_H + +#if !SUB_PLATFORM_S8001 +#error "Only include for S8001 platform" +#endif + +/* S8001 specific gpio -> pin mappings - Elba I/O Spreadsheet v.27 */ + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_BOARD_ID0 GPIO(94) +#define GPIO_BOARD_ID1 GPIO(95) +#define GPIO_BOARD_ID2 GPIO(96) +#define GPIO_BOARD_ID3 GPIO(16) +#define GPIO_BOARD_ID4 GPIO(203) + +/* Boot configuration pins */ +#define GPIO_BOOT_CONFIG0 GPIO(18) +#define GPIO_BOOT_CONFIG1 GPIO(185) +#define GPIO_BOOT_CONFIG2 GPIO(202) + +/* Boot configuration pin encodings */ +#define BOOT_CONFIG_SPI0 (0) +#define BOOT_CONFIG_SPI0_TEST (1) +#define BOOT_CONFIG_NVME0_X2 (2) +#define BOOT_CONFIG_NVME0_X2_TEST (3) +#define BOOT_CONFIG_NVME0_X1 (4) +#define BOOT_CONFIG_NVME0_X1_TEST (5) +#define BOOT_CONFIG_SLOW_SPI0_TEST (6) +#define BOOT_CONFIG_FAST_SPI0_TEST (7) + +#define GPIO_REQUEST_DFU1 GPIO(123) // HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO(122) // MENU_KEY +#define GPIO_FORCE_DFU GPIO(186) // FORCE_DFU +#define GPIO_DFU_STATUS GPIO(201) // DFU_STATUS + +#define SPI_NOR0 (0) + +#define GPIO_SPI0_SCLK GPIO(94) +#define GPIO_SPI0_MOSI GPIO(95) +#define GPIO_SPI0_MISO GPIO(96) +#define GPIO_SPI0_SSIN GPIO(97) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#else +#define GPIO_SPI0_CS GPIO(97) // Alias of GPIO_SPI0_SSIN +#endif + +#define GPIO_IIC0_SCL GPIO(165) +#define GPIO_IIC0_SDA GPIO(164) +#define GPIO_IIC1_SCL GPIO(178) +#define GPIO_IIC1_SDA GPIO(177) +#define GPIO_IIC2_SCL GPIO(132) +#define GPIO_IIC2_SDA GPIO(131) +#define GPIO_IIC3_SCL GPIO(115) +#define GPIO_IIC3_SDA GPIO(114) + +#define GPIO_PCIE0_PERST GPIO(98) +#define GPIO_PCIE1_PERST GPIO(99) +#define GPIO_PCIE2_PERST GPIO(100) +#define GPIO_PCIE3_PERST GPIO(101) +#define GPIO_PCIE4_PERST GPIO(102) +#define GPIO_PCIE5_PERST GPIO(103) +#define GPIO_PCIE0_CLKREQ GPIO(104) +#define GPIO_PCIE1_CLKREQ GPIO(105) +#define GPIO_PCIE2_CLKREQ GPIO(106) +#define GPIO_PCIE3_CLKREQ GPIO(107) +#define GPIO_PCIE4_CLKREQ GPIO(108) +#define GPIO_PCIE5_CLKREQ GPIO(109) + +#define GPIO_NAND_SYS_CLK GPIO(24) + +#endif /* ! __PLATFORM_GPIODEF_S8001_H */ diff --git a/platform/s8000/include/platform/image_devices.h b/platform/s8000/include/platform/image_devices.h new file mode 100644 index 0000000..6b059b2 --- /dev/null +++ b/platform/s8000/include/platform/image_devices.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_HW_ASP) + { "asp_fw", 0x00000 }, +#elif defined(WITH_ANC_FIRMWARE) + { "anc_firmware", 0x00000 }, +#endif +#if defined(WITH_NVME) + { "nvme_firmware0", 0x0000 }, +#endif +#if !defined(WITH_HW_ASP) && !defined(WITH_ANC_FIRMWARE) && !defined(WITH_NVME) + { "nor0", 0x00000 }, +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 }, +#endif +#if defined(WITH_NVME) + { "nvme_syscfg0", 0x0000 }, +#endif +#if !defined(WITH_NAND_BOOT) && !defined(WITH_NVME) + { "nor0", 0x00000 }, +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/s8000/include/platform/memconfig.h b/platform/s8000/include/platform/memconfig.h new file mode 100644 index 0000000..9dc5471 --- /dev/null +++ b/platform/s8000/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* S8000 SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/s8000/include/platform/memmap.h b/platform/s8000/include/platform/memmap.h new file mode 100644 index 0000000..170b86f --- /dev/null +++ b/platform/s8000/include/platform/memmap.h @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* S8000 specific memory map */ + +/////////////////////////////////////////////////////////////////////////////////// +// 0x800000000 + dram_size ------------------------------- +// | NVMe (12MiB) | +// | | +// |-----------------------------| +// | TZ0 (varies) | +// | | +// |-----------------------------| +// | TZ1 (512KiB) | +// | | +// |-----------------------------| +// | Consistent Debug (16KiB) | +// |-----------------------------| +// | Sleep Token Buffer (16KiB) | +// |-----------------------------| +// | DRAM Config Sequence (16KiB)| +// |-----------------------------| +// | Panic (512KiB) | +// |-----------------------------| +// | Display | +// | (Framebuffer + scratch) | +// | | +// | | +// |-----------------------------| +// | | +// | iBoot (Heap) | +// | (Variable size depending | +// (Elba) (Maui) | on DISPLAY_SIZE) | +// 0x8F0180000 / 0x870180000 --> |-----------------------------| +// | iBoot (Stacks) | +// (Elba) (Maui) | (STACKS_SIZE) | +// 0x8F017C000 / 0x87017C000 --> |-----------------------------| +// | iBoot (Page Tables) | +// (Elba) (Maui) | (PAGE_TABLES_SIZE) | +// 0x8F0100000 / 0x870100000 --> |-----------------------------| +// | iBoot (Text + Data) | +// (Elba) (Maui) | (TEXT_FOOTPRINT) | +// 0x8F0000000 / 0x870000000 --> |-----------------------------| <-- 0x800000000 + dram_size - 256MB +// | | +// | Unused | +// | | +// |-----------------------------| +// | | +// | (Ramdisk) | +// | (Kernel + DeviceTree) | +// | Secure memory | +// | | +// |-----------------------------| +// | | +// | Load region / | +// | Insecure Memory | +// | (overlaps with TZ0) | +// | | +// 0x800000000 --> ------------------------------- +// +// Note that Elba A0/B0 instead moves TZ0/TZ1 to the bottom of DRAM. See +// TZ0_BASE_A0 / TZ1_BASE_A0 below for more info +/////////////////////////////////////////////////////////////////////////////////// + +#define SDRAM_BASE (0x800000000ULL) +#define SDRAM_BANK_LEN (SDRAM_LEN) +#define SDRAM_BANK_COUNT (1) +#define SDRAM_END (SDRAM_BASE + SDRAM_LEN) + +#define VROM_BASE (0x100000000ULL) +#define VROM_BANK_LEN (0x02000000ULL) +#define VROM_LEN (0x00080000ULL) +#define SRAM_BASE (0x180000000ULL) +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + #define VROM_RSVD (0x00100000ULL) // 512 KiB reserved for SecureROM testing, remaining 512 KiB for Data and book-keeping + #define SRAM_LEN (0x00400000ULL) // 4 MiB + #define SRAM_BANK_LEN (SRAM_LEN) // Starting with Elba and Cayman, SRAM should be in a 32 MB decode region +#elif SUB_PLATFORM_S8001 + #define VROM_RSVD (0ULL) + #define SRAM_LEN (0x00080000ULL) // 512 KiB + #define SRAM_BANK_LEN (0x02000000ULL) +#endif +#define SRAM_BANK_COUNT (1) +#define SRAM_END (SRAM_BASE + SRAM_LEN) + +#define IO_BASE (0x200000000ULL) +#define IO_SIZE (0x020000000ULL) + +#define PCI_REG_BASE (0x600000000ULL) +#define PCI_REG_LEN (0x00C000000ULL) +#define PCI_CONFIG_BASE (0x610000000ULL) +#define PCI_CONFIG_LEN (0x010000000ULL) +#define PCI_32BIT_BASE (0x7C0000000ULL) +#define PCI_32BIT_LEN (0x002000000ULL) // 32 MiB fits nicely into a 32 MiB L2 MMU block + +#define SECUREROM_LOAD_ADDRESS (VROM_BASE) + +/* reserved for ASP/NVMe */ +// NOTE ASP_SIZE is now defined by the platform or target makefile. +#define ASP_BASE (SDRAM_END - ASP_SIZE) + +#define CONSISTENT_DEBUG_SIZE (0x00004000ULL) +#define TZ1_SIZE (0x00080000ULL) + +#if SUB_PLATFORM_S8001 +// Elba A0 and B0 both have SEPROM bugs that prevent TZ0/TZ1 +// from being located high in DRAM. ( Streamline Elba B0 memory map) +// +// So for these chips, we are placing TZ0/TZ1 at the base of DRAM +// before the kernel base. +// +// Actual TZ0/TZ1 reservation happens later + +#define CONSISTENT_DEBUG_BASE (ASP_BASE - CONSISTENT_DEBUG_SIZE) + +#else +// Reserved for TZ0/SEP +// TZ0_SIZE is defined by the platform or target makefile +#define TZ0_BASE (ASP_BASE - TZ0_SIZE) + +// Reserved for TZ1/AP Monitor +#define TZ1_BASE (TZ0_BASE - TZ1_SIZE) + +#define CONSISTENT_DEBUG_BASE (TZ1_BASE - CONSISTENT_DEBUG_SIZE) +#endif + +/* reserved area for sleep token info */ +#define SLEEP_TOKEN_BUFFER_SIZE (0x00004000ULL) +#define SLEEP_TOKEN_BUFFER_BASE (CONSISTENT_DEBUG_BASE - SLEEP_TOKEN_BUFFER_SIZE) + +/* reserved area for config sequence region */ +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +#define DRAM_CONFIG_SEQ_SIZE (0x00004000ULL) +#elif SUB_PLATFORM_S8001 +#define DRAM_CONFIG_SEQ_SIZE (0x00008000ULL) +#endif +#define DRAM_CONFIG_SEQ_BASE (SLEEP_TOKEN_BUFFER_BASE - DRAM_CONFIG_SEQ_SIZE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00080000ULL) +#define PANIC_BASE (DRAM_CONFIG_SEQ_BASE - PANIC_SIZE) + +/* reserved area for display */ +// DISPLAY_SIZE comes from platform's rules.mk +#define DISPLAY_BASE (PANIC_BASE - DISPLAY_SIZE) + +#if SUB_PLATFORM_S8001 +#define TZ0_BASE (SDRAM_BASE) +#define TZ1_BASE (TZ0_BASE + TZ0_SIZE) + + +// For Elba, the kernel starts at 32MB alignment above TZ0/TZ1 +#define KERNEL_BASE (((TZ1_BASE + TZ1_SIZE) + 32*1024*1024 - 1) & ~(32*1024*1024-1)) + +#else + +// For non-Elba systems, KERNEL_BASE simply starts at SDRAM_BASE +#define KERNEL_BASE (SDRAM_BASE) +#endif + +/* where to stick heap and insecure memory */ +#if APPLICATION_SECUREROM + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + +#define HEAP_BASE (SRAM_BASE + VROM_RSVD) +#define HEAP_SIZE (0x00100000ULL) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +// XXX for future platforms, include a guard page after the heap + +// DATA_BASE comes from rules.mk +#define DATA_SIZE (0x00040000ULL) + +#define PAGE_TABLES_BASE (DATA_BASE + DATA_SIZE) +#define PAGE_TABLES_SIZE (0x00008000ULL) + +#define BOOT_TRAMPOLINE_BASE (DATA_BASE + DATA_SIZE) +#define BOOT_TRAMPOLINE_SIZE (0x00004000ULL) + +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (0x00004000ULL) + +// XXX for future platforms, this should be increased to allow larger images +// to be loaded, with a guard between it and the stacks +#define INSECURE_MEMORY_SIZE (0x00080000ULL) +#define INSECURE_MEMORY_BASE (SRAM_BASE + SRAM_LEN - INSECURE_MEMORY_SIZE) + +#elif SUB_PLATFORM_S8001 + +// DFU SPACE 0x00000 - 0x40000 +// BOOT TRAMPOLINE 0x40000 - 0x44000 (read-execute, acts as write guard between load area and data area) +// DATA 0x44000 - 0x50000 +// PAGE TABLES 0x50000 - 0x58000 (not mapped, acts as guard between data area and stacks) +// STACKS 0x58000 - 0x5c000 +// HEAP 0x5c000 - 0x80000 + +#define INSECURE_MEMORY_SIZE (0x00040000ULL) +#define INSECURE_MEMORY_BASE (SRAM_BASE) + +#define BOOT_TRAMPOLINE_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define BOOT_TRAMPOLINE_SIZE (0x00004000ULL) + +// DATA_BASE comes from rules.mk +#define DATA_SIZE (0x0000C000ULL) + +#define PAGE_TABLES_BASE (DATA_BASE + DATA_SIZE) +#define PAGE_TABLES_SIZE (0x00008000ULL) + +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (0x00004000ULL) + +#define HEAP_BASE (STACKS_BASE + STACKS_SIZE) +#define HEAP_SIZE (SRAM_BASE + SRAM_LEN - HEAP_BASE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#endif + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT + +#if WITH_DFU_MODE +/* LLB, iBSS DFU */ + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x01400000ULL) +#define IBOOT_BASE (DISPLAY_BASE - IBOOT_SIZE) + +#define INSECURE_MEMORY_SIZE (IBOOT_SIZE) +#define INSECURE_MEMORY_BASE (IBOOT_BASE) + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + +// SRAM memory map +// +// ROM Testing 0x000000 - 0x0fffff (1024 KiB) +// Heap 0x100000 - 0x1fbfff (1008 KiB) +// Guard 0x1fc000 - 0x1fffff ( 16 KiB) +// Unused 0x200000 - 0x37ffff (1536 KiB) +// Code/Data 0x380000 - 0x3e7fff ( 416 KiB) +// Trampoline 0x3e8000 - 0x3ebfff ( 16 KiB) +// Page Tables 0x3ec000 - 0x3fbfff ( 64 KiB = 4 pages @ 16 KiB each) +// Stacks 0x3fc000 - 0x3fffff ( 16 KiB) + +#define HEAP_BASE (SRAM_BASE + VROM_RSVD) +#define HEAP_SIZE (0x00100000ULL - PAGE_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) + +#define BOOT_TRAMPOLINE_BASE (TEXT_BASE + TEXT_FOOTPRINT) +#define BOOT_TRAMPOLINE_SIZE (PAGE_SIZE) +#define PAGE_TABLES_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define PAGE_TABLES_SIZE (STACKS_BASE - PAGE_TABLES_BASE) +#define STACKS_BASE (SRAM_BASE + SRAM_LEN - STACKS_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) + +#elif SUB_PLATFORM_S8001 + +// Elba (S8001) offsets from SRAM_BASE +// Code/data 0x00000 - 0x4bfff ( 304 KiB) +// Boot trampoline 0x4c000 - 0x4ffff ( 16 KiB) +// Heap 0x50000 - 0x73fff ( 144 KiB) +// Page tables 0x74000 - 0x7Bfff ( 32 KiB) +// Stacks 0x7C000 - 0x7ffff ( 16 KiB) + +#define BOOT_TRAMPOLINE_BASE (SRAM_BASE + TEXT_FOOTPRINT) +#define BOOT_TRAMPOLINE_SIZE (PAGE_SIZE) + +#define HEAP_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define HEAP_SIZE (0x00024000ULL) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#define PAGE_TABLES_BASE (HEAP_BASE + HEAP_SIZE) +#define PAGE_TABLES_SIZE (0x00008000ULL) + +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (0x00004000ULL) + +#endif + +#else /* !WITH_DFU_MODE */ + +/* iBoot, iBEC */ + +// SDRAM memory map will usually look like the following for S8000/S8003: +// +// iBoot Text 0x870000000 - 0x8700FFFFF ( 1 MiB) +// Page Tables 0x870100000 - 0x870177FFF (480 KiB) +// Stacks 0x870178000 - 0x87017BFFF ( 16 KiB) +// Boot trampoline 0x87017C000 - 0x87017FFFF ( 16 KiB) +// Heap 0x870180000 - (DISPLAY_BASE - 1 page) +// Guard (DISPLAY_BASE - 1 page) - DISPLAY_BASE + +// And for S8001: +// +// iBoot Text 0x8f0000000 - 0x8f00FFFFF ( 1 MiB) +// Page Tables 0x8f0100000 - 0x8f0177FFF (480 KiB) +// Stacks 0x8f0178000 - 0x8f017BFFF ( 16 KiB) +// Boot trampoline 0x8f017C000 - 0x8f017FFFF ( 16 KiB) +// Heap 0x8f0180000 - (DISPLAY_BASE - 1 page) +// Guard (DISPLAY_BASE - 1 page) - DISPLAY_BASE + +/* reserved area for iBoot */ +#define IBOOT_BASE (TEXT_BASE) +#define IBOOT_SIZE (HEAP_END - IBOOT_BASE) + +#define PAGE_TABLES_BASE (IBOOT_BASE + TEXT_FOOTPRINT) +#define PAGE_TABLES_SIZE (0x00078000ULL) +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) +#define BOOT_TRAMPOLINE_BASE (STACKS_BASE + STACKS_SIZE) +#define BOOT_TRAMPOLINE_SIZE (PAGE_SIZE) + +#define HEAP_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define HEAP_SIZE (DISPLAY_BASE - HEAP_BASE - PAGE_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) +#if (HEAP_GUARD != (DISPLAY_BASE - PAGE_SIZE)) +#error "Memory map configuration error" +#endif + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_LOAD_SIZE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define SECURE_MEMORY_SIZE (DEFAULT_FREE_ADDRESS - SECURE_MEMORY_BASE) + +/* unused area */ +#define UNUSED_MEMORY_BASE (SECURE_MEMORY_BASE + SECURE_MEMORY_SIZE) +#define UNUSED_MEMORY_SIZE (IBOOT_BASE - UNUSED_MEMORY_BASE) + +#endif /* !WITH_DFU_MODE */ + +#endif /* APPLICATION_IBOOT */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/s8000/include/platform/pcimap.h b/platform/s8000/include/platform/pcimap.h new file mode 100644 index 0000000..3dca0d2 --- /dev/null +++ b/platform/s8000/include/platform/pcimap.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PCIMAP_H +#define __PLATFORM_PCIMAP_H + +/* S8000 specific bus/device/function and PCI base address map */ + +#include + +#define PCIE_PORT0_MEMORY_BASE (PCIE_MEMORY_BASE_ADDR) +#define PCIE_PORT0_MEMORY_LEN (0x100000ULL) + +#define NVME0_PCI_BDF (PCI_BDF(1, 0, 0)) +#define NVME0_BASE_ADDR (PCIE_PORT0_MEMORY_BASE) +#define NVME0_SIZE (0x2000) +#define NVME0_DART_ID (PCIE_PORT0_DART_ID) + + +#endif /* ! __PLATFORM_PCIMAP_H */ diff --git a/platform/s8000/include/platform/pinconfig.h b/platform/s8000/include/platform/pinconfig.h new file mode 100644 index 0000000..798c8ad --- /dev/null +++ b/platform/s8000/include/platform/pinconfig.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if SUB_PLATFORM_S8003 +#include +#else +#include SUB_PLATFORM_HEADER(pinconfig) +#endif diff --git a/platform/s8000/include/platform/pinconfig_s8000.h b/platform/s8000/include/platform/pinconfig_s8000.h new file mode 100644 index 0000000..8a53784 --- /dev/null +++ b/platform/s8000/include/platform/pinconfig_s8000.h @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : SWD_TMS2 -> + CFG_DISABLED, // 1 : SWD_TMS3 -> + CFG_DISABLED, // 2 : UART5_RTXD -> + CFG_DISABLED, // 3 : I2S4_MCK -> + CFG_DISABLED, // 4 : I2S4_BCLK -> + CFG_DISABLED, // 5 : I2S4_LRCK -> + CFG_DISABLED, // 6 : I2S4_DIN -> + CFG_DISABLED, // 7 : I2S4_DOUT -> + +/* Port 1 */ + CFG_DISABLED, // 8 : I2S2_MCK -> + CFG_DISABLED, // 9 : I2S2_BCLK -> + CFG_DISABLED, // 10 : I2S2_LRCK -> + CFG_DISABLED, // 11 : I2S2_DIN -> + CFG_DISABLED, // 12 : I2S2_DOUT -> + CFG_DISABLED, // 13 : SPI1_SCLK -> + CFG_DISABLED, // 14 : SPI1_MOSI -> + CFG_DISABLED, // 15 : SPI1_MISO -> + +/* Port 2 */ + CFG_DISABLED, // 16 : SPI1_SSIN -> + CFG_DISABLED, // 17 : I2S0_MCK -> + CFG_DISABLED, // 18 : I2S0_BCLK -> + CFG_DISABLED, // 19 : I2S0_LRCK -> + CFG_DISABLED, // 20 : I2S0_DIN -> + CFG_DISABLED, // 21 : I2S0_DOUT -> + CFG_DISABLED, // 22 : I2C2_SDA -> + CFG_DISABLED, // 23 : I2C2_SCL -> + +/* Port 3 */ + CFG_DISABLED, // 24 : UART1_TXD -> + CFG_DISABLED, // 25 : UART1_RXD -> + CFG_DISABLED, // 26 : UART1_RTSN -> + CFG_DISABLED, // 27 : UART1_CTSN -> + CFG_DISABLED, // 28 : UART4_TXD -> + CFG_DISABLED, // 29 : UART4_RXD -> + CFG_DISABLED, // 30 : UART4_RTSN -> + CFG_DISABLED, // 31 : UART4_CTSN -> + +/* Port 4 */ + CFG_DISABLED, // 32 : UART7_TXD -> + CFG_DISABLED, // 33 : UART7_RXD -> + CFG_DISABLED, // 34 : CLK32K_OUT -> + CFG_DISABLED, // 35 : DP_WAKEUP -> + CFG_DISABLED, // 36 : MIPICSI_MUXSEL -> + CFG_DISABLED, // 37 : ISP_I2C1_SDA -> + CFG_DISABLED, // 38 : ISP_I2C1_SCL -> + CFG_DISABLED, // 39 : ISP_I2C0_SDA -> + +/* Port 5 */ + CFG_DISABLED, // 40 : ISP_I2C0_SCL -> + CFG_DISABLED, // 41 : SPI2_SCLK -> + CFG_DISABLED, // 42 : SPI2_MOSI -> + CFG_DISABLED, // 43 : SPI2_MISO -> + CFG_DISABLED, // 44 : SPI2_SSIN -> + CFG_DISABLED, // 45 : I2C0_SDA -> + CFG_DISABLED, // 46 : I2C0_SCL -> + CFG_DISABLED, // 47 : SENSOR0_ISTRB -> + +/* Port 6 */ + CFG_DISABLED, // 48 : SENSOR0_RST -> + CFG_DISABLED, // 49 : SENSOR0_CLK -> + CFG_DISABLED, // 50 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 51 : SENSOR1_ISTRB -> + CFG_DISABLED, // 52 : SENSOR1_RST -> + CFG_DISABLED, // 53 : SENSOR1_CLK -> + CFG_DISABLED, // 54 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : GPIO[0] -> + CFG_DISABLED, // 65 : GPIO[1] -> + CFG_DISABLED, // 66 : GPIO[2] -> + CFG_DISABLED, // 67 : GPIO[3] -> + CFG_DISABLED, // 68 : GPIO[4] -> + CFG_DISABLED, // 69 : GPIO[5] -> + CFG_DISABLED, // 70 : GPIO[6] -> + CFG_DISABLED, // 71 : GPIO[7] -> + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[8] -> + CFG_DISABLED, // 73 : GPIO[9] -> + CFG_DISABLED, // 74 : GPIO[10] -> + CFG_DISABLED, // 75 : GPIO[11] -> + CFG_DISABLED, // 76 : GPIO[12] -> + CFG_DISABLED, // 77 : GPIO[13] -> + CFG_DISABLED, // 78 : GPIO[14] -> + CFG_DISABLED, // 79 : GPIO[15] -> + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[16] -> BOARD_ID[3] + CFG_DISABLED, // 81 : GPIO[17] -> + CFG_DISABLED, // 82 : GPIO[18] -> BOOT_CONFIG[0] + CFG_DISABLED, // 83 : I2S1_MCK -> + CFG_DISABLED, // 84 : I2S1_BCLK -> + CFG_DISABLED, // 85 : I2S1_LRCK -> + CFG_DISABLED, // 86 : I2S1_DIN -> + CFG_DISABLED, // 87 : I2S1_DOUT -> + +/* Port 11 */ + CFG_DISABLED, // 88 : UART3_TXD -> + CFG_DISABLED, // 89 : UART3_RXD -> + CFG_DISABLED, // 90 : UART3_RTSN -> + CFG_DISABLED, // 91 : UART3_CTSN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_IN, // 96 : MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // 97 : HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // 98 : SKEY_L -> + CFG_DISABLED, // 99 : SPI3_SCLK -> + CFG_DISABLED, // 100 : SPI3_MOSI -> + CFG_DISABLED, // 101 : SPI3_MISO -> + CFG_DISABLED, // 102 : SPI3_SSIN -> + CFG_DISABLED, // 103 : SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // 105 : SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // 106 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 107 : UART0_TXD -> + CFG_DISABLED, // 108 : UART0_RXD -> + CFG_DISABLED, // 109 : UART6_TXD -> + CFG_DISABLED, // 110 : UART6_RXD -> + CFG_DISABLED, // 111 : TMR32_PWM0 -> + +/* Port 14 */ + CFG_DISABLED, // 112 : TMR32_PWM1 -> + CFG_DISABLED, // 113 : TMR32_PWM2 -> + CFG_DISABLED, // 114 : I2C1_SDA -> + CFG_DISABLED, // 115 : I2C1_SCL -> + CFG_DISABLED, // 116 : GPIO[19] -> + CFG_DISABLED, // 117 : GPIO[20] -> + CFG_DISABLED, // 118 : GPIO[21] -> + CFG_DISABLED, // 119 : GPIO[22] -> + +/* Port 15 */ + CFG_DISABLED, // 120 : GPIO[23] -> + CFG_DISABLED, // 121 : GPIO[24] -> + CFG_DISABLED, // 122 : GPIO[25] -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // 123 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // 124 : PMGR_MOSI -> DFU_STATUS + CFG_DISABLED, // 125 : PMGR_MISO -> + CFG_DISABLED, // 126 : PMGR_SCLK0 -> + CFG_DISABLED, // 127 : PMGR_SSCLK1 -> + +/* Port 16 */ + CFG_DISABLED, // 128 : SOCHOT0 -> + CFG_DISABLED, // 129 : SOCHOT1 -> + CFG_DISABLED, // 130 : EDP_HPD -> + CFG_DISABLED, // 131 : I2S3_MCK -> + CFG_DISABLED, // 132 : I2S3_BCLK -> + CFG_DISABLED, // 133 : I2S3_LRCK -> + CFG_DISABLED, // 134 : I2S3_DOUT -> + CFG_DISABLED, // 135 : I2S3_DIN -> + +/* Port 17 */ + CFG_DISABLED, // 136 : GPIO[27] -> + CFG_DISABLED, // 137 : GPIO[28] -> BOOT_CONFIG[2] + CFG_DISABLED, // 138 : GPIO[29] -> BOARD_ID[4] + CFG_DISABLED, // 139 : GPIO[30] -> + CFG_DISABLED, // 140 : GPIO[31] -> + CFG_DISABLED, // 141 : GPIO[32] -> + CFG_DISABLED, // 142 : GPIO[33] -> + CFG_DISABLED, // 143 : GPIO[34] -> + +/* Port 18 */ + CFG_DISABLED, // 144 : GPIO[35] -> + CFG_DISABLED, // 145 : GPIO[36] -> + CFG_DISABLED, // 146 : GPIO[37] -> + CFG_DISABLED, // 147 : GPIO[38] -> + CFG_DISABLED, // 148 : GPIO[39] -> + CFG_DISABLED, // 149 : GPIO[40] -> + CFG_DISABLED, // 150 : GPIO[41] -> + CFG_DISABLED, // 151 : GPIO[42] -> + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : PCIE_PERST0_N -> NAND_PERST + CFG_DISABLED, // 161 : PCIE_PERST1_N -> + CFG_DISABLED, // 162 : PCIE_PERST2_N -> + CFG_DISABLED, // 163 : PCIE_PERST3_N -> + CFG_DISABLED | INPUT_SCHMITT, // 164 : PCIE_CLKREQ0_N -> NAND_CLKREQ + CFG_DISABLED, // 165 : PCIE_CLKREQ1_N -> + CFG_DISABLED, // 166 : PCIE_CLKREQ2_N -> + CFG_DISABLED, // 167 : PCIE_CLKREQ3_N -> + +/* Port 21 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_DISABLED, // 192 : UART2_TXD -> + CFG_DISABLED, // 193 : UART2_RXD -> + CFG_DISABLED, // 194 : UART2_RTSN -> + CFG_DISABLED, // 195 : UART2_CTSN -> + CFG_DISABLED, // 196 : NAND_SYS_CLK -> NAND_SYS_CLK + CFG_DISABLED, // 197 : S3E_RESETN -> NAND_RESET + CFG_DISABLED, // 198 : TST_CLKOUT -> + CFG_DISABLED, +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED, // 2 : AOP_SPI_MISO -> + CFG_DISABLED, // 3 : AOP_UART1_TXD -> + CFG_DISABLED, // 4 : AOP_UART1_RXD -> + CFG_DISABLED, // 5 : AOP_UART0_TXD -> + CFG_DISABLED, // 6 : AOP_UART0_RXD -> + CFG_DISABLED, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED, // 8 : AOP_UART2_RXD -> + CFG_DISABLED, // 9 : AOP_I2CM_SDA -> + CFG_DISABLED, // 10 : AOP_I2CM_SCL -> + CFG_DISABLED, // 11 : AOP_FUNC[0] -> + CFG_DISABLED, // 12 : AOP_FUNC[1] -> + CFG_DISABLED, // 13 : AOP_FUNC[2] -> + CFG_DISABLED, // 14 : AOP_FUNC[3] -> + CFG_DISABLED, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : AOP_FUNC[5] -> + CFG_DISABLED, // 17 : AOP_FUNC[6] -> + CFG_DISABLED, // 18 : AOP_FUNC[7] -> + CFG_DISABLED, // 19 : AOP_FUNC[8] -> + CFG_DISABLED, // 20 : AOP_FUNC[9] -> + CFG_DISABLED, // 21 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 22 : AOP_SWD_TMS0 -> + CFG_DISABLED, // 23 : AOP_SWD_TMS1 -> + +/* Port 3 */ + CFG_DISABLED, // 24 : AOP_I2S_MCK -> + CFG_DISABLED, // 25 : AOP_I2S_BCLK -> + CFG_DISABLED, // 26 : AOP_I2S_LRCK -> + CFG_DISABLED, // 27 : AOP_I2S_DIN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s8000/include/platform/pinconfig_s8001.h b/platform/s8000/include/platform/pinconfig_s8001.h new file mode 100644 index 0000000..59607ac --- /dev/null +++ b/platform/s8000/include/platform/pinconfig_s8001.h @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S4, // 0 : SPI1_SCLK -> + CFG_DISABLED | DRIVE_S4, // 1 : SPI1_MOSI -> + CFG_DISABLED | DRIVE_S4, // 2 : SPI1_MISO -> + CFG_DISABLED | DRIVE_S4, // 3 : SPI1_SSIN -> + CFG_DISABLED | DRIVE_S4, // 4 : ISP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S4, // 5 : ISP_I2C0_SCL -> + CFG_DISABLED | DRIVE_S4, // 6 : ISP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S4, // 7 : ISP_I2C0_SCL -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S4, // 8 : SENSOR0_ISTRB -> + CFG_DISABLED | DRIVE_S4, // 9 : SENSOR0_RST -> + CFG_DISABLED | DRIVE_S4, // 10 : SENSOR0_CLK -> + CFG_DISABLED | DRIVE_S4, // 11 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED | DRIVE_S4, // 12 : SENSOR1_ISTRB -> + CFG_DISABLED | DRIVE_S4, // 13 : SENSOR1_RST -> + CFG_DISABLED | DRIVE_S4, // 14 : SENSOR1_CLK -> + CFG_DISABLED | DRIVE_S4, // 15 : SENSOR1_XSHUTDOWN -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4, // 16 : GPIO[16] -> BOARD_ID[3] + CFG_DISABLED | DRIVE_S4, // 17 : GPIO[17] -> + CFG_DISABLED | DRIVE_S4, // 18 : GPIO[18] -> BOOT_CONFIG[0] + CFG_DISABLED | DRIVE_S4, // 19 : I2S1_MCK -> + CFG_DISABLED | DRIVE_S4, // 20 : I2S1_BLCK -> + CFG_DISABLED | DRIVE_S4, // 21 : I2S1_LRCK -> + CFG_DISABLED | DRIVE_S4, // 22 : I2S1_DIN -> + CFG_DISABLED | DRIVE_S4, // 23 : I2S1_DOUT -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4, // 24 : NAND_SYS_CLK -> NAND_SYS_CLK + CFG_DISABLED | DRIVE_S4, // 25 : S3E0_RESETN -> NAND_RESET + CFG_DISABLED | DRIVE_S4, // 26 : S3E1_RESETN -> + CFG_DISABLED | DRIVE_S4, // 27 : UART1_TXD -> + CFG_DISABLED | DRIVE_S4, // 28 : UART1_RXD -> + CFG_DISABLED | DRIVE_S4, // 29 : UART1_RTSN -> + CFG_DISABLED | DRIVE_S4, // 30 : UART1_CTSN -> + CFG_DISABLED | DRIVE_S4, // 31 : GPIO43 -> + +/* Port 4 */ + CFG_DISABLED | DRIVE_S4, // 32 : I2S0_BCLK -> + CFG_DISABLED | DRIVE_S4, // 33 : I2S0_LRCK -> + CFG_DISABLED | DRIVE_S4, // 34 : I2S0_DIN -> + CFG_DISABLED | DRIVE_S4, // 35 : I2S0_DOUT -> + CFG_DISABLED | DRIVE_S4, // 36 : I2S0_MCK -> + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 5 */ + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 6 */ + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 7 */ + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 8 */ + CFG_DISABLED | DRIVE_S4, // 64 : I2S4_MCK -> + CFG_DISABLED | DRIVE_S4, // 65 : I2S4_BCLK -> + CFG_DISABLED | DRIVE_S4, // 66 : I2S4_LRCK -> + CFG_DISABLED | DRIVE_S4, // 67 : I2S4_DIN -> + CFG_DISABLED | DRIVE_S4, // 68 : I2S4_DOUT -> + CFG_DISABLED | DRIVE_S4, // 69 : I2S2_MCK -> + CFG_DISABLED | DRIVE_S4, // 70 : I2S2_BCLK -> + CFG_DISABLED | DRIVE_S4, // 71 : I2S2_LRCK -> + +/* Port 9 */ + CFG_DISABLED | DRIVE_S4, // 72 : I2S2_DIN -> + CFG_DISABLED | DRIVE_S4, // 73 : I2S2_DOUT -> + CFG_DISABLED | DRIVE_S4, // 74 : GPIO[0] -> + CFG_DISABLED | DRIVE_S4, // 75 : GPIO[1] -> + CFG_DISABLED | DRIVE_S4, // 76 : GPIO[2] -> + CFG_DISABLED | DRIVE_S4, // 77 : GPIO[3] -> + CFG_DISABLED | DRIVE_S4, // 78 : GPIO[4] -> + CFG_DISABLED | DRIVE_S4, // 79 : GPIO[5] -> + +/* Port 10 */ + CFG_DISABLED | DRIVE_S4, // 80 : GPIO[6] -> + CFG_DISABLED | DRIVE_S4, // 81 : GPIO[7] -> + CFG_DISABLED | DRIVE_S4, // 82 : GPIO[8] -> + CFG_DISABLED | DRIVE_S4, // 83 : GPIO[9] -> + CFG_DISABLED | DRIVE_S4, // 84 : GPIO[10] -> + CFG_DISABLED | DRIVE_S4, // 85 : GPIO[11] -> + CFG_DISABLED | DRIVE_S4, // 86 : GPIO[12] -> + CFG_DISABLED | DRIVE_S4, // 87 : GPIO[13] -> + +/* Port 11 */ + CFG_DISABLED | DRIVE_S4, // 88 : GPIO[14] -> + CFG_DISABLED | DRIVE_S4, // 89 : GPIO[15] -> + CFG_DISABLED | DRIVE_S4, // 90 : UART3_TXD -> + CFG_DISABLED | DRIVE_S4, // 91 : UART3_RXD -> + CFG_DISABLED | DRIVE_S4, // 92 : UART3_RTSN -> + CFG_DISABLED | DRIVE_S4, // 93 : UART3_CTSN -> + CFG_FUNC0 | DRIVE_S4, // 94 : SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_FUNC0 | DRIVE_S4, // 95 : SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + +/* Port 12 */ + CFG_FUNC0 | DRIVE_S4, // 96 : SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1 | DRIVE_S4, // 97 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED | DRIVE_S4, // 98 : PCIE_PERST0_N -> NAND_PERST + CFG_DISABLED | DRIVE_S4, // 99 : PCIE_PERST1_N -> + CFG_DISABLED | DRIVE_S4, // 100 : PCIE_PERST2_N -> + CFG_DISABLED | DRIVE_S4, // 101 : PCIE_PERST3_N -> + CFG_DISABLED | DRIVE_S4, // 102 : PCIE_PERST4_N -> + CFG_DISABLED | DRIVE_S4, // 103 : PCIE_PERST5_N -> + +/* Port 13 */ + CFG_DISABLED | INPUT_SCHMITT | SLOW_SLEW | DRIVE_S4, // 104 : PCIE_CLKREQ0_N -> NAND_CLKREQ + CFG_DISABLED | DRIVE_S4, // 105 : PCIE_CLKREQ1_N -> + CFG_DISABLED | DRIVE_S4, // 106 : PCIE_CLKREQ2_N -> + CFG_DISABLED | DRIVE_S4, // 107 : PCIE_CLKREQ3_N -> + CFG_DISABLED | DRIVE_S4, // 108 : PCIE_CLKREQ4_N -> + CFG_DISABLED | DRIVE_S4, // 109 : PCIE_CLKREQ5_N -> + CFG_DISABLED | DRIVE_S4, // 110 : UART2_TXD -> + CFG_DISABLED | DRIVE_S4, // 111 : UART2_RXD -> + +/* Port 14 */ + CFG_DISABLED | DRIVE_S4, // 112 : UART2_RTSN -> + CFG_DISABLED | DRIVE_S4, // 113 : UART2_CTSN -> + CFG_DISABLED | DRIVE_S4, // 114 : I2C3_SDA -> + CFG_DISABLED | DRIVE_S4, // 115 : I2C3_SCL -> + CFG_DISABLED | DRIVE_S4, // 116 : GPIO[44] -> + CFG_DISABLED | DRIVE_S4, // 117 : GPIO[45] -> + CFG_DISABLED | DRIVE_S4, // 118 : GPIO[46] -> + CFG_DISABLED | DRIVE_S4, // 119 : GPIO[47] -> + +/* Port 15 */ + CFG_DISABLED | DRIVE_S4, // 120 : GPIO[48] -> + CFG_DISABLED | DRIVE_S4, // 121 : GPIO[49] -> + CFG_IN | DRIVE_S4, // 122 : MENU_KEY_L -> REQUEST_DFU2 + CFG_IN | DRIVE_S4, // 123 : HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED | DRIVE_S4, // 124 : SKEY_L -> + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 16 */ + CFG_DISABLED | DRIVE_S4, // 128 : SWD_TMS2 -> + CFG_DISABLED | DRIVE_S4, // 129 : SWD_TMS3 -> + CFG_DISABLED | DRIVE_S4, // 130 : UART5_RTXD -> + CFG_DISABLED | DRIVE_S4, // 131 : I2C2_SDA -> + CFG_DISABLED | DRIVE_S4, // 132 : I2C2_SCL -> + CFG_DISABLED | DRIVE_S4, // 133 : UART4_TXD -> + CFG_DISABLED | DRIVE_S4, // 134 : UART4_RXD -> + CFG_DISABLED | DRIVE_S4, // 135 : UART4_RTSN -> + +/* Port 17 */ + CFG_DISABLED | DRIVE_S4, // 136 : UART4_CTSN -> + CFG_DISABLED | DRIVE_S4, // 137 : UART7_TXD -> + CFG_DISABLED | DRIVE_S4, // 138 : UART7_RXD -> + CFG_DISABLED | DRIVE_S4, // 139 : CLK32K_OUT -> + CFG_DISABLED | DRIVE_S4, // 140 : DP_WAKEUP0 -> + CFG_DISABLED | DRIVE_S4, // 141 : DP_WAKEUP1 -> + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 18 */ + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 19 */ + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + +/* Port 20 */ + CFG_DISABLED | DRIVE_S4, // 160 : SPI2_SCLK -> + CFG_DISABLED | DRIVE_S4, // 161 : SPI2_MOSI -> + CFG_DISABLED | DRIVE_S4, // 162 : SPI2_MISO -> + CFG_DISABLED | DRIVE_S4, // 163 : SPI2_SSIN -> + CFG_DISABLED | DRIVE_S4, // 164 : I2C0_SDA -> + CFG_DISABLED | DRIVE_S4, // 165 : I2C0_SCL -> + CFG_DISABLED | DRIVE_S4, // 166 : SPI3_SCLK -> + CFG_DISABLED | DRIVE_S4, // 167 : SPI3_MOSI -> + +/* Port 21 */ + CFG_DISABLED | DRIVE_S4, // 168 : SPI3_MISO -> + CFG_DISABLED | DRIVE_S4, // 169 : SPI3_SSIN -> + CFG_DISABLED | DRIVE_S4, // 170 : UART0_TXD -> + CFG_DISABLED | DRIVE_S4, // 171 : UART0_RXD -> + CFG_DISABLED | DRIVE_S4, // 172 : UART6_TXD -> + CFG_DISABLED | DRIVE_S4, // 173 : UART6_RXD -> + CFG_DISABLED | DRIVE_S4, // 174 : TMR32_PWM0 -> + CFG_DISABLED | DRIVE_S4, // 175 : TMR32_PWM1 -> + +/* Port 22 */ + CFG_DISABLED | DRIVE_S4, // 176 : TMR32_PWM2 -> + CFG_DISABLED | DRIVE_S4, // 177 : I2C1_SDA -> + CFG_DISABLED | DRIVE_S4, // 178 : I2C1_SCL -> + CFG_DISABLED | DRIVE_S4, // 179 : GPIO[19] -> + CFG_DISABLED | DRIVE_S4, // 180 : GPIO[20] -> + CFG_DISABLED | DRIVE_S4, // 181 : GPIO[21] -> + CFG_DISABLED | DRIVE_S4, // 182 : GPIO[22] -> + CFG_DISABLED | DRIVE_S4, // 183 : GPIO[23] -> + +/* Port 23 */ + CFG_DISABLED | DRIVE_S4, // 184 : GPIO[24] -> + CFG_DISABLED | DRIVE_S4, // 185 : GPIO[25] -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN | DRIVE_S4, // 186 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | DRIVE_S4, // 187 : PSPI_MOSI -> + CFG_DISABLED | DRIVE_S4, // 188 : DWI_DO -> + CFG_DISABLED | DRIVE_S4, // 189 : PMGR_MISO -> + CFG_DISABLED | DRIVE_S4, // 190 : PMGR_SCLK0 -> + CFG_DISABLED | DRIVE_S4, // 191 : PMGR_SSCLK1 -> + +/* Port 24 */ + CFG_DISABLED | DRIVE_S4, // 192 : DROOP -> + CFG_DISABLED | DRIVE_S4, // 193 : SOCHOT1 -> + CFG_DISABLED | DRIVE_S4, // 194 : EDP_HPD0 -> + CFG_DISABLED | DRIVE_S4, // 195 : EDP_HPD1 -> + CFG_DISABLED | DRIVE_S4, // 196 : I2S3_MCK -> + CFG_DISABLED | DRIVE_S4, // 197 : I2S3_BCLK -> + CFG_DISABLED | DRIVE_S4, // 198 : I2S3_LRCK -> + CFG_DISABLED | DRIVE_S4, // 199 : I2S3_DOUT -> + +/* Port 25 */ + CFG_DISABLED | DRIVE_S4, // 200 : I2S3_DIN -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4, // 201 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | DRIVE_S4, // 202 : GPIO[28] -> BOOT_CONFIG[2] + CFG_DISABLED | DRIVE_S4, // 203 : GPIO[29] -> BOARD_ID[4] + CFG_DISABLED | DRIVE_S4, // 204 : GPIO[30] -> + CFG_DISABLED | DRIVE_S4, // 205 : GPIO[31] -> + CFG_DISABLED | DRIVE_S4, // 206 : GPIO[32] -> + CFG_DISABLED | DRIVE_S4, // 207 : GPIO[33] -> + +/* Port 26 */ + CFG_DISABLED | DRIVE_S4, // 208 : GPIO[34] -> + CFG_DISABLED | DRIVE_S4, // 209 : GPIO[35] -> + CFG_DISABLED | DRIVE_S4, // 210 : GPIO[36] -> + CFG_DISABLED | DRIVE_S4, // 211 : GPIO[37] -> + CFG_DISABLED | DRIVE_S4, // 212 : GPIO[38] -> + CFG_DISABLED | DRIVE_S4, // 213 : GPIO[39] -> + CFG_DISABLED | DRIVE_S4, // 214 : GPIO[40] -> + CFG_DISABLED | DRIVE_S4, // 215 : GPIO[41] -> + +/* Port 27 */ + CFG_DISABLED | DRIVE_S4, // 216 : GPIO[42] -> + CFG_DISABLED | DRIVE_S4, // 217 : TST_CLKOUT -> + CFG_DISABLED | DRIVE_S4, // 218 : GPU_TRIGGER1 -> + CFG_DISABLED | DRIVE_S4, // 219 : GPU_TRIGGER2 -> + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S4, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED | DRIVE_S4, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED | DRIVE_S4, // 2 : AOP_SPI_MISO -> + CFG_DISABLED | DRIVE_S4, // 3 : AOP_UART1_TXD -> + CFG_DISABLED | DRIVE_S4, // 4 : AOP_UART1_RXD -> + CFG_DISABLED | DRIVE_S4, // 5 : AOP_UART0_TXD -> + CFG_DISABLED | DRIVE_S4, // 6 : AOP_UART0_RXD -> + CFG_DISABLED | DRIVE_S4, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S4, // 8 : AOP_UART2_RXD -> + CFG_DISABLED | DRIVE_S4, // 9 : AOP_I2CM_SDA -> + CFG_DISABLED | DRIVE_S4, // 10 : AOP_I2CM_SCL -> + CFG_DISABLED | DRIVE_S4, // 11 : AOP_FUNC[0] -> + CFG_DISABLED | DRIVE_S4, // 12 : AOP_FUNC[1] -> + CFG_DISABLED | DRIVE_S4, // 13 : AOP_FUNC[2] -> + CFG_DISABLED | DRIVE_S4, // 14 : AOP_FUNC[3] -> + CFG_DISABLED | DRIVE_S4, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4, // 16 : AOP_FUNC[5] -> + CFG_DISABLED | DRIVE_S4, // 17 : AOP_FUNC[6] -> + CFG_DISABLED | DRIVE_S4, // 18 : AOP_FUNC[7] -> + CFG_DISABLED | DRIVE_S4, // 19 : AOP_FUNC[8] -> + CFG_DISABLED | DRIVE_S4, // 20 : AOP_FUNC[9] -> + CFG_DISABLED | DRIVE_S4, // 21 : AOP_SWD_TCK_OUT -> + CFG_DISABLED | DRIVE_S4, // 22 : AOP_SWD_TMS0 -> + CFG_DISABLED | DRIVE_S4, // 23 : AOP_SWD_TMS1 -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4, // 24 : AOP_I2S_MCK -> + CFG_DISABLED | DRIVE_S4, // 25 : AOP_I2S_BCLK -> + CFG_DISABLED | DRIVE_S4, // 26 : AOP_I2S_LRCK -> + CFG_DISABLED | DRIVE_S4, // 27 : AOP_I2S_DIN -> + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, + CFG_DISABLED | DRIVE_S4, +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/s8000/include/platform/soc/ccc.h b/platform/s8000/include/platform/soc/ccc.h new file mode 100644 index 0000000..f357d64 --- /dev/null +++ b/platform/s8000/include/platform/soc/ccc.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_CCC_H +#define __PLATFORM_SOC_CCC_H + +#define rCCC_CPU0_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x000)) +#define rCCC_CPU0_IMPL_CPU_IOACC_CTL_EL3 (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x008)) +#define rCCC_CPU0_IMPL_FED_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x010)) +#define rCCC_CPU0_IMPL_LSU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x018)) +#define rCCC_CPU0_IMPL_MMU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x020)) + +#define CCC0_IMPL_BASE_ADDR (CCC0_SYS_BASE_ADDR + 0x40000) +#define rCCC_CCC_IMPL_CPM_IOACC_CTL_EL3 (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x000)) +#define rCCC_CCC_IMPL_L2C_ERR_STS (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x008)) +#define rCCC_CCC_IMPL_L2C_ERR_ADR (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x010)) +#define rCCC_CCC_IMPL_L2C_ERR_INF (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x018)) + +#define rCCC_CPU1_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU1_SYS_BASE_ADDR + 0x000)) +#define rCCC_CPU2_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU2_SYS_BASE_ADDR + 0x000)) + +#endif /* __PLATFORM_SOC_CCC_H */ diff --git a/platform/s8000/include/platform/soc/chipid.h b/platform/s8000/include/platform/soc/chipid.h new file mode 100644 index 0000000..1f30df1 --- /dev/null +++ b/platform/s8000/include/platform/soc/chipid.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(minipmgr) + +#define rCFG_FUSE0 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_OFFSET)) +#define rCFG_FUSE1 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE1_OFFSET)) +#define rCFG_FUSE2 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE2_OFFSET)) +#define rCFG_FUSE3 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE3_OFFSET)) +#define rCFG_FUSE4 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE4_OFFSET)) +#define rCFG_FUSE5 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE5_OFFSET)) +#define rCFG_FUSE9 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE9_OFFSET)) + +#define CFG_FUSE9_PLL_VCO_RCTRL_SEL (0x8) // VCO_RCTRL_OW value is valid if set +#define CFG_FUSE9_PLL_VCO_RCTRL_OW_MASK (0x7) // PLL analog override value if valid + +#define rECIDLO (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE0_OFFSET)) +#define rECIDHI (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE1_OFFSET)) + +#define rSEP_SECURITY (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_SEP_SECURITY_OFFSET)) + +#define rCFG_FUSE0_RAW (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_RAW_OFFSET)) + +#define BOARD_ID_NONE (0xff) +#define J105_AP_BOARD_ID (0x04) +#define J105_DEV_BOARD_ID (0x05) +#define J98A_AP_BOARD_ID (0x10) +#define J98A_DEV_BOARD_ID (0x11) +#define J99A_AP_BOARD_ID (0x12) +#define J99A_DEV_BOARD_ID (0x13) +#define J127_AP_BOARD_ID (0x8) +#define J127_DEV_BOARD_ID (0x9) +#define J128_AP_BOARD_ID (0xA) +#define J128_DEV_BOARD_ID (0xB) +#define J111_AP_BOARD_ID (0x8) +#define J111_DEV_BOARD_ID (0x9) +#define J112_AP_BOARD_ID (0xA) +#define J112_DEV_BOARD_ID (0xB) +#define N69_AP_BOARD_ID (0x2) +#define N69_DEV_BOARD_ID (0x3) +#define N69U_AP_BOARD_ID (0x2) +#define N69U_DEV_BOARD_ID (0x3) + +enum chipid_voltage_index { + CHIPID_SOC_VOLTAGE_BYPASS = 0, + CHIPID_SOC_VOLTAGE_SECUREROM = 1, + CHIPID_SOC_VOLTAGE_VMIN = 2, + CHIPID_SOC_VOLTAGE_VNOM = 3, + + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_396, + + CHIPID_CPU_VOLTAGE_600, + CHIPID_CPU_VOLTAGE_912, + CHIPID_CPU_VOLTAGE_1200, + CHIPID_CPU_VOLTAGE_1512, + CHIPID_CPU_VOLTAGE_1800, + CHIPID_CPU_VOLTAGE_1848, + CHIPID_CPU_VOLTAGE_1896, + CHIPID_CPU_VOLTAGE_1992, + CHIPID_CPU_VOLTAGE_2112, + + CHIPID_CPU_VOLTAGE_396_WA, + CHIPID_CPU_VOLTAGE_1200_WA, + CHIPID_CPU_VOLTAGE_1512_WA, + + CHIPID_CPU_VOLTAGE_720, + CHIPID_CPU_VOLTAGE_1080, + CHIPID_CPU_VOLTAGE_1440, + CHIPID_CPU_VOLTAGE_2160, + CHIPID_CPU_VOLTAGE_2256_1core, + CHIPID_CPU_VOLTAGE_2256, + CHIPID_CPU_VOLTAGE_2352, + CHIPID_CPU_VOLTAGE_2448, + + CHIPID_GPU_VOLTAGE_OFF, + + CHIPID_GPU_VOLTAGE_340, + CHIPID_GPU_VOLTAGE_474, + CHIPID_GPU_VOLTAGE_550, + CHIPID_GPU_VOLTAGE_723, + CHIPID_GPU_VOLTAGE_616, + CHIPID_GPU_VOLTAGE_804, + CHIPID_GPU_VOLTAGE_850, + CHIPID_GPU_VOLTAGE_900, + + CHIPID_GPU_VOLTAGE_360, + CHIPID_GPU_VOLTAGE_520, + CHIPID_GPU_VOLTAGE_650, + CHIPID_GPU_VOLTAGE_800, + + CHIPID_VOLTAGE_FIXED, + + CHIPID_ALL_VOLTAGE_LAST, +}; + +enum chipid_voltage_type { + CHIPID_CPU_VOLTAGE, + CHIPID_GPU_VOLTAGE, + CHIPID_SOC_VOLTAGE, +}; + +uint32_t chipid_get_cpu_voltage(uint32_t index); + +uint32_t chipid_get_cpu_sram_voltage(uint32_t index); + +uint32_t chipid_get_soc_voltage(uint32_t index); + +uint32_t chipid_get_gpu_voltage(uint32_t index); + +uint32_t chipid_get_gpu_sram_voltage(uint32_t index); + +uint32_t chipid_get_sram_voltage(uint32_t index); + +int32_t chipid_get_cpu_temp_offset(uint32_t cpu_number); + +uint32_t chipid_get_soc_temp_sensor_trim(uint32_t sensor_index); + +uint32_t chipid_get_fuse_revision(void); + +uint32_t chipid_get_total_rails_leakage(); + +uint32_t chipid_get_lpo_trim(void); + +#if SUB_PLATFORM_S8000 +uint32_t chipid_get_pcie_txpll_vco_v2i_i_set(void); +uint32_t chipid_get_pcie_txpll_vco_v2i_pi_set(void); +uint32_t chipid_get_pcie_refpll_vco_v2i_i_set(void); +uint32_t chipid_get_pcie_refpll_vco_v2i_pi_set(void); +uint32_t chipid_get_pcie_rx_ldo(void); +#elif SUB_PLATFORM_S8001 || SUB_PLATFORM_S8003 +uint32_t chipid_get_pcie_refpll_fcal_vco_digctrl(void); +#endif + +#if SUPPORT_FPGA + +#define FPGA_HAS_ALWAYS (1 << 0) +#define FPGA_HAS_VXD (1 << 1) +#define FPGA_HAS_AVE (1 << 2) +#define FPGA_HAS_ISP (1 << 3) +#define FPGA_HAS_DISP (1 << 4) +#define FPGA_HAS_MSR (1 << 6) +#define FPGA_HAS_JPEG (1 << 7) +#define FPGA_HAS_GFX (1 << 8) +#define FPGA_HAS_MEDIA (1 << 9) + +#define rECID_FUSE3 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE3_OFFSET)) + +uint32_t chipid_get_fpga_block_instantiation(void); + +#endif // SUPPORT_FPGA + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s8000/include/platform/soc/display.h b/platform/s8000/include/platform/soc/display.h new file mode 100644 index 0000000..2e24e00 --- /dev/null +++ b/platform/s8000/include/platform/soc/display.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include SUB_PLATFORM_HEADER(soc/display) diff --git a/platform/s8000/include/platform/soc/display_s8000.h b/platform/s8000/include/platform/soc/display_s8000.h new file mode 100644 index 0000000..3684986 --- /dev/null +++ b/platform/s8000/include/platform/soc/display_s8000.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables + +// XXX - disp_dpcafclkgate is listed as TBD +// D620 is most likely something new based on the values. Update once we know more. + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ +#if DISPLAY_IPHONE_TUNABLES +#if DISPLAY_D620_TUNABLES + { + .name = "D620", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x637), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x1b1d) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x635), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x62d), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x491), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x489), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x159) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + +#endif //DISPLAY_D620_TUNABLES + +#if DISPLAY_D520_TUNABLES + { + .name = "D520", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x321), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x2d3a) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x31f), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x317), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x24d), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x245), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0xa6) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_D520_TUNABLES + +#if DISPLAY_D403_TUNABLES + { + .name = "D403", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x321), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x2d3a) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x31f), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x317), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x24d), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x245), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0xa6) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + +#endif //DISPLAY_D403_TUNABLES + +#endif //DISPLAY_IPHONE_TUNABLES + +}; + + +#endif /* ! __APPLE_DISPLAY_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/display_s8001.h b/platform/s8000/include/platform/soc/display_s8001.h new file mode 100644 index 0000000..cc42440 --- /dev/null +++ b/platform/s8000/include/platform/soc/display_s8001.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables + +// XXX - disp_dpcafclkgate is listed as TBD +// D620 is most likely something new based on the values. Update once we know more. + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ +//Tunables for targets using the the timing based on landscape ipads +#if DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_FPGA_TUNABLES || DISPLAY_APPLE_TV_TUNABLES + { + .name = "ipad4", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x547), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0xff8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x15b5) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x545), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x53d), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x3a1), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x399), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x30) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + { + .name = "ipad6", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x6c3), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0xaac) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x6c1), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x6b9), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x579), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x571), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNAGGR), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x1a9) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + { + .name = "ipad6_A1", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x7a1), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0xaac) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x797), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x78f), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x725), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x71d), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNAGGR | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x131) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + { + .name = "ipad6b", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x8ab), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x1ff0), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x3840) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x8aa), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x8a2), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x6b2), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x6aa), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x14f) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x30) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + { + .name = "ipad6d", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0xe61), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x1ff0), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x3840) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0xe60), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0xe58), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0xb1a), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0xb12), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x29d) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x30) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + { + .name = "720p", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x246), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x1ff0), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x3840) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x244), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x23c), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x1ac), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x1a4), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x59) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x30) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/s8000/include/platform/soc/display_s8003.h b/platform/s8000/include/platform/soc/display_s8003.h new file mode 100644 index 0000000..d808dd8 --- /dev/null +++ b/platform/s8000/include/platform/soc/display_s8003.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables + +// XXX - disp_dpcafclkgate is listed as TBD +// D620 is most likely something new based on the values. Update once we know more. + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ +#if DISPLAY_IPHONE_TUNABLES +#if DISPLAY_D620_TUNABLES + { + .name = "D620", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x637), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x1b1d) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x635), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x62d), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x491), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x489), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x159) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + +#endif //DISPLAY_D620_TUNABLES + +#if DISPLAY_D520_TUNABLES + { + .name = "D520", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x321), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x2d3a) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x31f), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x317), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x24d), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x245), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0xa6) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_D520_TUNABLES + +#if DISPLAY_D403_TUNABLES + { + .name = "D403", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x321), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x2d3a) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x31f), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x317), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x24d), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x245), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0xa6) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + +#endif //DISPLAY_D403_TUNABLES +#endif //DISPLAY_IPHONE_TUNABLES +}; + + +#endif /* ! __APPLE_DISPLAY_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/display_timings.h b/platform/s8000/include/platform/soc/display_timings.h new file mode 100644 index 0000000..33f3f39 --- /dev/null +++ b/platform/s8000/include/platform/soc/display_timings.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || TARGET_DISPLAY_D520 + { + .display_name = "D520", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 100000000, + .dot_pitch = 326, + .h_active = 750, + .h_pulse_width = 32, + .h_back_porch = 4, + .h_front_porch = 102, + .v_active = 1334, + .v_pulse_width = 3, + .v_back_porch = 4, + .v_front_porch = 536, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || TARGET_DISPLAY_D620 + { + .display_name = "D620", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 326, + .h_active = 1080, + .h_pulse_width = 32, + .h_back_porch = 4, + .h_front_porch = 116, + .v_active = 1920, + .v_pulse_width = 3, + .v_back_porch = 5, + .v_front_porch = 778, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || TARGET_DISPLAY_D403 + { + .display_name = "D403", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 61540000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 32, + .h_back_porch = 4, + .h_front_porch = 6, + .v_active = 1136, + .v_pulse_width = 3, + .v_back_porch = 13, + .v_front_porch = 352, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_S8000FPGA || SUB_TARGET_S8001FPGA + { + .display_name = "fpga-wsvga", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 5000000, + .dot_pitch = 243, + .h_active = 1024, + .h_pulse_width = 50, + .h_back_porch = 50, + .h_front_porch = 51, + .v_active = 600, + .v_pulse_width = 50, + .v_back_porch = 218, + .v_front_porch = 6, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 18, + .display_type = DISPLAY_TYPE_DUMB, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_S8001SIM + { + .display_name = "ipad4", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 264, + .h_active = 1536, + .h_pulse_width = 15, + .h_back_porch = 52, + .h_front_porch = 16, + .v_active = 2048, + .v_pulse_width = 1, + .v_back_porch = 3, + .v_front_porch = 7, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_J127 || SUB_TARGET_J128 + { + .display_name = "ipad6", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 240000000, + .dot_pitch = 264, + .h_active = 1536, + .h_pulse_width = 32, + .h_back_porch = 4, + .h_front_porch = 126, + .v_active = 2048, + .v_pulse_width = 2, + .v_back_porch = 4, + .v_front_porch = 302, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_J98A || SUB_TARGET_J99A + { + .display_name = "ipad6d", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 400000000, + .dot_pitch = 264, + .h_active = 2732, + .h_pulse_width = 20, + .h_back_porch = 56, + .h_front_porch = 16, + .v_active = 2048, + .v_pulse_width = 2, + .v_back_porch = 4, + .v_front_porch = 307, // No IFP + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || WITH_HW_DISPLAY_DISPLAYPORT + { + .display_name = "720p", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 110, + .h_front_porch = 220, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 5, + .v_front_porch = 20, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_DP, + .display_config = NULL, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/s8000/include/platform/soc/dvfmperf.h b/platform/s8000/include/platform/soc/dvfmperf.h new file mode 100644 index 0000000..c1b2f00 --- /dev/null +++ b/platform/s8000/include/platform/soc/dvfmperf.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_DVFMPERF_H +#define __PLATFORM_SOC_DVFMPERF_H +#include + +enum chipid_voltage_index dvfmperf_get_voltage_index(uint32_t index, enum chipid_voltage_type voltage_type); + +#endif /* __PLATFORM_SOC_DVFMPERF_H */ diff --git a/platform/s8000/include/platform/soc/hwclocks.h b/platform/s8000/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..dafa18f --- /dev/null +++ b/platform/s8000/include/platform/soc/hwclocks.h @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(pmgr) + +#if SUPPORT_FPGA +#define OSC_FREQ (5000000UL) +#define LPO_FREQ (OSC_FREQ) +#else +#define OSC_FREQ (24000000UL) +#define LPO_FREQ (192000000UL) +#endif + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +/* + * S8000 clock gate devices. + */ +enum { + // Mini-PMGR + CLK_AOP = HWCLOCK_BASE, + CLK_DEBUG, + CLK_AOP_GPIO, + CLK_AOP_UART0, + CLK_AOP_UART1, + CLK_AOP_UART2, + CLK_AOP_I2CM, + CLK_AOP_MCA0, + CLK_AOP_CPU, + CLK_AOP_FILTER, + CLK_AOP_BUSIF, + + // PMGR + CLK_SBR, + CLK_AIC, + CLK_DWI, + CLK_GPIO, + CLK_PMS, + CLK_HSIC0PHY, + CLK_HSIC1PHY, + CLK_ISPSENS0, + CLK_ISPSENS1, + CLK_PCIE_REF, + CLK_SIO_BUSIF, + CLK_SIO_P, + CLK_SIO, + CLK_MCA0, + CLK_MCA1, + CLK_MCA2, + CLK_MCA3, + CLK_MCA4, + CLK_PWM0, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_I2C3, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_UART7, + CLK_UART8, + CLK_AES0, + CLK_MCC, + CLK_DCS0, + CLK_DCS1, + CLK_DCS2, + CLK_DCS3, + CLK_USB, + CLK_USBCTLREG, + CLK_USB2HOST0, + CLK_USB2HOST0_OHCI, + CLK_USB2HOST1, + CLK_USB2HOST1_OHCI, + CLK_USB2HOST2, + CLK_USB2HOST2_OHCI, + CLK_USB_OTG, + CLK_SMX, + CLK_SF, + CLK_RTMUX, + CLK_DISP0, + CLK_MIPI_DSI, + CLK_MIPI = CLK_MIPI_DSI, + CLK_DP, + CLK_EDPLINK = CLK_DP, + CLK_DPLINK = CLK_DP, + CLK_ISP, + CLK_MEDIA, + CLK_JPG, + CLK_MSR, + CLK_PMP, + CLK_PMS_SRAM, + CLK_VDEC0, + CLK_VENC_CPU, + CLK_PCIE, + CLK_PCIE_AUX, + CLK_PCIE_LINK0, + CLK_PCIE_LINK1, + CLK_PCIE_LINK2, + CLK_PCIE_LINK3, + CLK_GFX, + + // Unmanaged + CLK_CPU0, + CLK_CPU1, + CLK_CPM, + CLK_SEP, + CLK_VENC_PIPE, + CLK_VENC_ME0, + CLK_VENC_ME1, + + CLK_LAST, +}; + +#elif SUB_PLATFORM_S8001 +/* + * S8001 clock gate devices. + */ +enum { + // Mini-PMGR + CLK_AOP = HWCLOCK_BASE, + CLK_DEBUG, + CLK_AOP_GPIO, + CLK_AOP_UART0, + CLK_AOP_UART1, + CLK_AOP_UART2, + CLK_AOP_I2CM, + CLK_AOP_MCA0, + CLK_AOP_CPU, + CLK_AOP_FILTER, + CLK_AOP_BUSIF, + + // PMGR + CLK_SBR, + CLK_AIC, + CLK_DWI, + CLK_GPIO, + CLK_PMS, + CLK_HSIC0PHY, + CLK_ISPSENS0, + CLK_ISPSENS1, + CLK_PCIE_REF, + CLK_SIO_BUSIF, + CLK_SIO_P, + CLK_SIO, + CLK_MCA0, + CLK_MCA1, + CLK_MCA2, + CLK_MCA3, + CLK_MCA4, + CLK_PWM0, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_I2C3, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_UART7, + CLK_UART8, + CLK_AES0, + CLK_DPA0, + CLK_DPA1, + CLK_MCC, + CLK_DCS0, + CLK_DCS1, + CLK_DCS2, + CLK_DCS3, + CLK_DCS4, + CLK_DCS5, + CLK_DCS6, + CLK_DCS7, + CLK_USB, + CLK_USBCTLREG, + CLK_USB2HOST0, + CLK_USB2HOST0_OHCI, + CLK_USB2HOST1, + CLK_USB2HOST1_OHCI, + CLK_USB2HOST2, + CLK_USB2HOST2_OHCI, + CLK_USB_OTG, + CLK_SMX, + CLK_SF, + CLK_RTMUX, + CLK_DISP0, + CLK_DP0, + CLK_EDPLINK = CLK_DP0, + CLK_DPLINK = CLK_DP0, + CLK_DISP1MUX, + CLK_DISP1, + CLK_DP1, + CLK_ISP, + CLK_MEDIA, + CLK_JPG, + CLK_MSR, + CLK_PMP, + CLK_PMS_SRAM, + CLK_VDEC0, + CLK_VENC_CPU, + CLK_PCIE, + CLK_PCIE_AUX, + CLK_PCIE_LINK0, + CLK_PCIE_LINK1, + CLK_PCIE_LINK2, + CLK_PCIE_LINK3, + CLK_PCIE_LINK4, + CLK_PCIE_LINK5, + CLK_GFX, + CLK_SRS, + + // Unmanaged + CLK_CPU0, + CLK_CPU1, + CLK_CPM, + CLK_SEP, + CLK_VENC_PIPE, + CLK_VENC_ME0, + CLK_VENC_ME1, + + CLK_LAST, +}; +#endif + +#define PMGR_DEVICE_INDEX(_clk) ((_clk) - HWCLOCK_BASE) +#define PMGR_DEVICE_COUNT (CLK_LAST - HWCLOCK_BASE) + +#define PMGR_FIRST_DEVICE CLK_AOP +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +#define PMGR_LAST_DEVICE CLK_GFX +#elif SUB_PLATFORM_S8001 +#define PMGR_LAST_DEVICE CLK_SRS +#else +#error Unknown Platform +#endif + +#define PMGR_VALID_DEVICE(_clk) ((_clk) >= PMGR_FIRST_DEVICE && (_clk) <= PMGR_LAST_DEVICE) + +// Legacy clocks, no associated device or PS register +enum { + CLK_FCLK = CLK_LAST, + CLK_ACLK, + CLK_HCLK, + CLK_PCLK, + CLK_VCLK0, + CLK_VCLK1, + CLK_MCLK, + CLK_NCLK, + CLK_USBPHYCLK, + CLK_NCOREF, +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/s8000/include/platform/soc/hwisr.h b/platform/s8000/include/platform/soc/hwisr.h new file mode 100644 index 0000000..463c0e6 --- /dev/null +++ b/platform/s8000/include/platform/soc/hwisr.h @@ -0,0 +1,564 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_DWI1 5 // DWI Interrupt +#define INT_DWI2 6 // DWI Interrupt +#define INT_PMGR_PERF_CNTRS 7 // PMGR Performace Counters Interrupt +#define INT_THERM_TEMP0 8 // Thermal Temp 0 Interrupt +#define INT_THERM_ALARM0 9 // Thermal Alarm 0 Interrupt +#define INT_THERM_TEMP1 10 // Thermal Temp 1 Interrupt +#define INT_THERM_ALARM1 11 // Thermal Alarm 1 Interrupt +#define INT_THERM_TEMP2 12 // Thermal Temp 2 Interrupt +#define INT_THERM_ALARM2 13 // Thermal Alarm 2 Interrupt + +// Reserved 14 - 15 + +#define INT_CPM_THERM_TEMP 16 // CPM Thermal temp Interrupt +#define INT_CPM_THERM_ALARM 17 // CPM Thermal alarm Interrupt +#define INT_CPU0_THERM_TEMP 18 // CPU0 Thermal temp Interrupt +#define INT_CPU0_THERM_ALARM 19 // CPU0 Thermal alarm Interrupt +#define INT_CPU1_THERM_TEMP 20 // CPU1 Thermal temp Interrupt +#define INT_CPU1_THERM_ALARM 21 // CPU1 Thermal alarm Interrupt + +// Reserved 21 - 26 + +#define INT_THERM_FS_ACT0 27 // Thermal Failsafe Active 0 Interrupt +#define INT_THERM_FS_ACT1 28 // Thermal Failsafe Active 1 Interrupt +#define INT_THERM_FS_EXT0 29 // Thermal Failsafe Exit 0 Interrupt +#define INT_THERM_FS_EXT1 30 // Thermal Failsafe Exit 1 Interrupt +#define INT_SOC_THERM_FS_ACT0 31 // SoC Thermal Failsafe Active 0 Interrupt +#define INT_SOC_THERM_FS_ACT1 32 // SoC Thermal Failsafe Active 1 Interrupt + +// Reserved 33 - 34 + +#define INT_CTM_TRIGGER0 35 // CTM Trigger 0 Interrupt +#define INT_CTM_TRIGGER1 36 // CTM Trigger 1 Interrupt +#define INT_CTM_TRIGGER2 37 // CTM Trigger 2 Interrupt +#define INT_CTM_TRIGGER3 38 // CTM Trigger 3 Interrupt +#define INT_COHERENCE_PNT_ERR 39 // Coherence Point Error Interrupt +#define INT_COHERENCE_PNT_PERF_CNTRS 40 // Coherence Point Performance Counters Interrupt + +// Reserved 41 + +#define INT_GPIO_CLASS0 42 // GPIO Class 0 Interrupt +#define INT_GPIO_CLASS1 43 // GPIO Class 1 Interrupt +#define INT_GPIO_CLASS2 44 // GPIO Class 2 Interrupt +#define INT_GPIO_CLASS3 45 // GPIO Class 3 Interrupt +#define INT_GPIO_CLASS4 46 // GPIO Class 4 Interrupt +#define INT_GPIO_CLASS5 47 // GPIO Class 5 Interrupt +#define INT_GPIO_CLASS6 48 // GPIO Class 6 Interrupt + +// Reserved 49-58 + +#define INT_MEM_CONTROLLER0 59 // Memory Controller MCC Interrupt +#define INT_MEM_CONTROLLER1 60 // Memory Controller MCC Interrupt +// XXX: TBD DSC interrupts + +// Reserved 73 + +#define INT_CPU0_COMM_TX 74 // CPU 0 COMM TX Interrupt +#define INT_CPU0_COMM_RX 75 // CPU 0 COMM RX Interrupt +#define INT_CPU0_PMU_IRQ 76 // CPU 0 PMU IRQ Interrupt +#define INT_CPU1_COMM_TX 77 // CPU 1 COMM TX Interrupt +#define INT_CPU1_COMM_RX 78 // CPU 1 COMM RX Interrupt +#define INT_CPU1_PMU_IRQ 79 // CPU 1 PMU IRQ Interrupt + +// Reserved 80 - 85 + +#define INT_CCC_UNIFIED_TRIGGER 86 // CCC Unified Trigger Interrupt + +// Reserved 87 + +#define INT_ISP_KF_INBOX_EMPTY 88 // ISP KF Inbox Empty Interrupt +#define INT_ISP_KF_INBOX_NOTEMPTY 89 // ISP KF Inbox Not Empty Interrupt +#define INT_ISP_KF_OUTBOX_EMPTY 90 // ISP KF Outbox Empty Interrupt +#define INT_ISP_KF_OUTBOX_NOTEMPTY 91 // ISP KF Outbox Not Empty Interrupt +#define INT_ISP0 92 // ISP 0 Interrupt +#define INT_ISP1 93 // ISP 1 Interrupt +#define INT_ISP2 94 // ISP 2 Interrupt +#define INT_ISP3 95 // ISP 3 Interrupt +#define INT_ISP_DART 96 // ISP DART Interrupt + +// Reserved 97 + +#define INT_SEP_KF_INBOX_EMPTY 98 // SEP KF Inbox Empty Interrupt +#define INT_SEP_KF_INBOX_NOTEMPTY 99 // SEP KF Inbox Not Empty Interrupt +#define INT_SEP_KF_OUTBOX_EMPTY 100 // SEP KF Outbox Empty Interrupt +#define INT_SEP_KF_OUTBOX_NOTEMPTY 101 // SEP KF Outbox Not Empty Interrupt +#define INT_SEP_AUTH_ERROR 102 // SEP Authentication Error Interrupt +#define INT_SEP_CRIT_PATH_MONITOR 103 // SEP Critical Path Monitor Interrupt + +// Reserved 104 - 105 + +// XXX JF: AOP interrupts + +// Reserved 138 - 139 + +#define INT_DISP0 140 // Display 0 Interrupt +#define INT_DISP0_DART 141 // Display 0 DART Interrupt +#define INT_DISP0_SMMU 142 // Display 0 SMMU Interrupt +#define INT_DISP0_BACK_END_BLU 143 // Display 0 Back End Back Light Update Interrupt +#define INT_DISP0_BACK_END_VBI 144 // Display 0 Back End VBI Interrupt +#define INT_DISP0_BACK_END_VFTG 145 // Display 0 Back End VFTG Idle Interrupt +#define INT_DISP0_BACK_END_VBL 146 // Display 0 Back End VBL counter Interrupt +#define INT_MIPIDSI0 147 // MIPI DSI 0 Interrupt +#define INT_MIPIDSI1 148 // MIPI DSI 1 Interrupt +#define INT_DISPLAY_PORT 149 // Display Port +#define INT_EDP0 INT_DISPLAY_PORT +#define INT_DPORT0 INT_DISPLAY_PORT + +// Reserved 151 + +// XXX: PMP + +// Reserved 156 + +#define INT_VDEC0 157 // Video Decoder 0 Interrupt + +// Reserved 158 + +#define INT_AVE_KF_INBOX_EMPTY 159 // AVE KF Inbox Empty Interrupt +#define INT_AVE_KF_INBOX_NOTEMPTY 160 // AVE KF Inbox Not Empty Interrupt +#define INT_AVE_KF_OUTBOX_EMPTY 161 // AVE KF Outbox Empty Interrupt +#define INT_AVE_KF_OUTBOX_NOTEMPTY 162 // AVE KF Outbox Not Empty Interrupt +#define INT_AVE_DART 163 // AVE DART Interrupt +#define INT_AVE_SMMU 164 // AVE SMMU Interrupt +#define INT_AVE 165 // AVE Interrupt +#define INT_SVE_SYNC 166 // SVE Driver Synchronization Interrupt + +// Reserved 167 - 169 + +#define INT_GFX 170 // GFX Interrupt +#define INT_GFX_SLEEP 171 // GFX Sleep Interrupt +#define INT_GFX_WAKE 172 // GFX Wake Interrupt +#define INT_GFX_CHG 173 // GFX Change Interrupt + +// Reserved 174 + +#define INT_JPEG 175 // JPEG Interrupt +#define INT_JPEG_DART 176 // JPEG DART Interrupt +#define INT_JPEG_DART_PERF 177 // JPEG DART Performance Interrupt + +// Reserved 178 + +#define INT_MSR 179 // MSR Interrupt +#define INT_MSR_SMMU 180 // MSR SMMU Interrupt +#define INT_MSR_DART 181 // MSR DART Interrupt +#define INT_MSR_DAR_PERF 182 // MSR DART Performance Interrupt + +// Reserved 183 + +#define INT_SIO_KF_INBOX_EMPTY 184 // SIO KF Inbox Empty Interrupt +#define INT_SIO_KF_INBOX_NOTEMPTY 185 // SIO KF Inbox Not Empty Interrupt +#define INT_SIO_KF_OUTBOX_EMPTY 186 // SIO KF Outbox Empty Interrupt +#define INT_SIO_KF_OUTBOX_NOTEMPTY 187 // SIO KF Outbox Not Empty Interrupt +#define INT_SPI0 188 // SPI 0 Interrupt +#define INT_SPI1 189 // SPI 1 Interrupt +#define INT_SPI2 190 // SPI 2 Interrupt +#define INT_SPI3 191 // SPI 3 Interrupt +#define INT_UART0 192 // UART 0 Interrupt +#define INT_UART1 193 // UART 1 Interrupt +#define INT_UART2 194 // UART 2 Interrupt +#define INT_UART3 195 // UART 3 Interrupt +#define INT_UART4 196 // UART 4 Interrupt +#define INT_UART5 197 // UART 5 Interrupt +#define INT_UART6 198 // UART 6 Interrupt +#define INT_UART7 199 // UART 7 Interrupt +#define INT_UART8 200 // UART 8 Interrupt +#define INT_MCA0 201 // Multi-Channel Audio 0 Interrupt +#define INT_MCA1 202 // Multi-Channel Audio 1 Interrupt +#define INT_MCA2 203 // Multi-Channel Audio 2 Interrupt +#define INT_MCA3 204 // Multi-Channel Audio 3 Interrupt +#define INT_MCA4 205 // Multi-Channel Audio 4 Interrupt +#define INT_IIC0 206 // I2C 0 Interrupt +#define INT_IIC1 207 // I2C 1 Interrupt +#define INT_IIC2 208 // I2C 2 Interrupt +#define INT_IIC3 209 // I2C 3 Interrupt +#define INT_PWM 210 // PWM Interrupt +#define INT_AES0 211 // AES 0 Interrupt + +// Reserved 212 - 213 + +#define INT_USB_OTG 214 // USB OTG Interrupt +#define INT_USB2HOST0_EHCI 215 // USB EHCI 0 Interrupt +#define INT_USB2HOST0_OHCI 216 // USB OHCI 0 Interrupt +#define INT_USB2HOST1_EHCI 217 // USB EHCI 1 Interrupt +#define INT_USB2HOST2_EHCI 218 // USB EHCI 2 Interrupt +#define INT_USBOTG_RESUME 219 // USB OTG Resume Interrupt +#define INT_USB_20_BATT_CHRG_DET 220 // USB 2.0 Battery Charge Detect Interrupt +#define INT_USB2HOST0_PHY_RESUME 221 // USB Host 0 Resume Interrupt +#define INT_USB2HOST1_PHY_RESUME 222 // USB Host 1 Resume Interrupt +#define INT_USB2HOST2_PHY_RESUME 223 // USB Host 2 Resume Interrupt +#define INT_OTG_IN_EP0 224 // OTG IN Endpoint 0 Interrupt +#define INT_OTG_IN_EP1 225 // OTG IN Endpoint 1 Interrupt +#define INT_OTG_IN_EP2 226 // OTG IN Endpoint 2 Interrupt +#define INT_OTG_IN_EP3 227 // OTG IN Endpoint 3 Interrupt +#define INT_OTG_IN_EP4 228 // OTG IN Endpoint 4 Interrupt +#define INT_OTG_IN_EP5 229 // OTG IN Endpoint 5 Interrupt +#define INT_OTG_IN_EP6 230 // OTG IN Endpoint 6 Interrupt +#define INT_OTG_IN_EP7 231 // OTG IN Endpoint 7 Interrupt +#define INT_OTG_IN_EP8 232 // OTG IN Endpoint 8 Interrupt +#define INT_OTG_OUT_EP0 233 // OTG OUT Endpoint 0 Interrupt +#define INT_OTG_OUT_EP1 234 // OTG OUT Endpoint 1 Interrupt +#define INT_OTG_OUT_EP2 235 // OTG OUT Endpoint 2 Interrupt +#define INT_OTG_OUT_EP3 236 // OTG OUT Endpoint 3 Interrupt +#define INT_OTG_OUT_EP4 237 // OTG OUT Endpoint 4 Interrupt +#define INT_OTG_OUT_EP5 238 // OTG OUT Endpoint 5 Interrupt +#define INT_OTG_OUT_EP6 239 // OTG OUT Endpoint 6 Interrupt +#define INT_OTG_OUT_EP7 240 // OTG OUT Endpoint 7 Interrupt +#define INT_OTG_OUT_EP8 241 // OTG OUT Endpoint 8 Interrupt + +// Reserved 242 - 243 + +#define PCIE_LINK0 244 // PCIE Link 0 Interrupt +#define PCIE_LINK0_DART 245 // PCIE Link 0 DART Interrupt +#define PCIE_LINK0_MMU 246 // PCIE Link 0 MMU Interrupt +#define PCIE_LINK1 247 // PCIE Link 1 Interrupt +#define PCIE_LINK1_DART 248 // PCIE Link 1 DART Interrupt +#define PCIE_LINK1_MMU 249 // PCIE Link 1 MMU Interrupt +#define PCIE_LINK2 250 // PCIE Link 1 Interrupt +#define PCIE_LINK2_DART 251 // PCIE Link 1 DART Interrupt +#define PCIE_LINK2_MMU 252 // PCIE Link 1 MMU Interrupt +#define PCIE_LINK3 253 // PCIE Link 1 Interrupt +#define PCIE_LINK3_DART 254 // PCIE Link 1 DART Interrupt +#define PCIE_LINK3_MMU 255 // PCIE Link 1 MMU Interrupt + +#define PCIE_MSI0 256 // PCIE MSI 0 Interrupt +#define PCIE_MSI1 257 // PCIE MSI 1 Interrupt +#define PCIE_MSI2 258 // PCIE MSI 2 Interrupt +#define PCIE_MSI3 259 // PCIE MSI 3 Interrupt +#define PCIE_MSI4 260 // PCIE MSI 4 Interrupt +#define PCIE_MSI5 261 // PCIE MSI 5 Interrupt +#define PCIE_MSI6 262 // PCIE MSI 6 Interrupt +#define PCIE_MSI7 263 // PCIE MSI 7 Interrupt +#define PCIE_MSI8 264 // PCIE MSI 8 Interrupt +#define PCIE_MSI9 265 // PCIE MSI 9 Interrupt +#define PCIE_MSI10 266 // PCIE MSI 10 Interrupt +#define PCIE_MSI11 267 // PCIE MSI 11 Interrupt +#define PCIE_MSI12 268 // PCIE MSI 12 Interrupt +#define PCIE_MSI13 269 // PCIE MSI 13 Interrupt +#define PCIE_MSI14 270 // PCIE MSI 14 Interrupt +#define PCIE_MSI15 271 // PCIE MSI 15 Interrupt +#define PCIE_MSI16 272 // PCIE MSI 16 Interrupt +#define PCIE_MSI17 273 // PCIE MSI 17 Interrupt +#define PCIE_MSI18 274 // PCIE MSI 18 Interrupt +#define PCIE_MSI19 275 // PCIE MSI 19 Interrupt +#define PCIE_MSI20 276 // PCIE MSI 20 Interrupt +#define PCIE_MSI21 277 // PCIE MSI 21 Interrupt +#define PCIE_MSI22 278 // PCIE MSI 22 Interrupt +#define PCIE_MSI23 279 // PCIE MSI 23 Interrupt +#define PCIE_MSI24 280 // PCIE MSI 24 Interrupt +#define PCIE_MSI25 281 // PCIE MSI 25 Interrupt +#define PCIE_MSI26 282 // PCIE MSI 26 Interrupt +#define PCIE_MSI27 283 // PCIE MSI 27 Interrupt +#define PCIE_MSI28 284 // PCIE MSI 28 Interrupt +#define PCIE_MSI29 285 // PCIE MSI 29 Interrupt +#define PCIE_MSI30 286 // PCIE MSI 30 Interrupt +#define PCIE_MSI31 287 // PCIE MSI 31 Interrupt + +#elif SUB_PLATFORM_S8001 + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_DWI1 5 // DWI Interrupt +#define INT_DWI2 6 // DWI Interrupt +#define INT_PMGR_PERF_CNTRS 7 // PMGR Performace Counters Interrupt +#define INT_THERM_TEMP0 8 // Thermal Temp 0 Interrupt +#define INT_THERM_ALARM0 9 // Thermal Alarm 0 Interrupt +#define INT_THERM_TEMP1 10 // Thermal Temp 1 Interrupt +#define INT_THERM_ALARM1 11 // Thermal Alarm 1 Interrupt +#define INT_THERM_TEMP2 12 // Thermal Temp 2 Interrupt +#define INT_THERM_ALARM2 13 // Thermal Alarm 2 Interrupt +#define INT_THERM_TEMP3 14 // Thermal Temp 3 Interrupt +#define INT_THERM_ALARM3 15 // Thermal Alarm 3 Interrupt +#define INT_CPM_THERM_TEMP 16 // CPM Thermal temp Interrupt +#define INT_CPM_THERM_ALARM 17 // CPM Thermal alarm Interrupt +#define INT_CPU0_THERM_TEMP 18 // CPU0 Thermal temp Interrupt +#define INT_CPU0_THERM_ALARM 19 // CPU0 Thermal alarm Interrupt +#define INT_CPU1_THERM_TEMP 20 // CPU1 Thermal temp Interrupt +#define INT_CPU1_THERM_ALARM 21 // CPU1 Thermal alarm Interrupt + +// Reserved 22 - 25 + +#define INT_THERM_FS_ACT0 26 // Thermal Failsafe Active 0 Interrupt +#define INT_THERM_FS_ACT1 27 // Thermal Failsafe Active 1 Interrupt +#define INT_THERM_FS_EXT0 28 // Thermal Failsafe Exit 0 Interrupt +#define INT_THERM_FS_EXT1 29 // Thermal Failsafe Exit 1 Interrupt +#define INT_SOC_THERM_FS_ACT0 30 // SoC Thermal Failsafe Active 0 Interrupt +#define INT_SOC_THERM_FS_ACT1 31 // SoC Thermal Failsafe Active 1 Interrupt +#define INT_PMGR_EVENT 32 // PMGR Event Interrupt +#define INT_CTM_TRIGGER0 33 // CTM Trigger 0 Interrupt +#define INT_CTM_TRIGGER1 34 // CTM Trigger 1 Interrupt +#define INT_CTM_TRIGGER2 35 // CTM Trigger 2 Interrupt +#define INT_CTM_TRIGGER3 36 // CTM Trigger 3 Interrupt +#define INT_COHERENCE_PNT0_ERR 37 // Coherence Point Error Interrupt +#define INT_COHERENCE_PNT0_PERF_CNTRS 38 // Coherence Point Performance Counters Interrupt +#define INT_COHERENCE_PNT1_ERR 39 // Coherence Point Error Interrupt +#define INT_COHERENCE_PNT1_PERF_CNTRS 40 // Coherence Point Performance Counters Interrupt + +// Reserved 41 + +#define INT_GPIO_CLASS0 42 // GPIO Class 0 Interrupt +#define INT_GPIO_CLASS1 43 // GPIO Class 1 Interrupt +#define INT_GPIO_CLASS2 44 // GPIO Class 2 Interrupt +#define INT_GPIO_CLASS3 45 // GPIO Class 3 Interrupt +#define INT_GPIO_CLASS4 46 // GPIO Class 4 Interrupt +#define INT_GPIO_CLASS5 47 // GPIO Class 5 Interrupt +#define INT_GPIO_CLASS6 48 // GPIO Class 6 Interrupt + +// Reserved 49 + +#define INT_MINI_PMGR_PERF_CNTRS 50 // MINIPMGR PerfCounter Interrupt +#define INT_GFX_PERF_CNTRS 51 // GFX Perf Counter Interrupt +#define INT_MEM_CONTROLLER0 52 // Memory Controller MCC Interrupt +#define INT_MEM_CONTROLLER0_1 53 // Memory Controller MCC Interrupt +#define INT_MEM_CONTROLLER1 54 // Memory Controller MCC Interrupt +#define INT_MEM_CONTROLLER1_1 55 // Memory Controller MCC Interrupt + +// Reserved 56 - 80 + +#define INT_CPU0_COMM_TX 57 // CPU 0 COMM TX Interrupt +#define INT_CPU0_COMM_RX 58 // CPU 0 COMM RX Interrupt +#define INT_CPU0_PMU_IRQ 59 // CPU 0 PMU IRQ Interrupt +#define INT_CPU1_COMM_TX 60 // CPU 1 COMM TX Interrupt +#define INT_CPU1_COMM_RX 61 // CPU 1 COMM RX Interrupt +#define INT_CPU1_PMU_IRQ 62 // CPU 1 PMU IRQ Interrupt + +// Reserved 87 - 92 + +#define INT_CCC_UNIFIED_TRIGGER 93 // CCC Unified Trigger Interrupt + +// Reserved 94 - 103 + +#define INT_ISP_KF_INBOX_EMPTY 104 // ISP KF Inbox Empty Interrupt +#define INT_ISP_KF_INBOX_NOTEMPTY 105 // ISP KF Inbox Not Empty Interrupt +#define INT_ISP_KF_OUTBOX_EMPTY 106 // ISP KF Outbox Empty Interrupt +#define INT_ISP_KF_OUTBOX_NOTEMPTY 107 // ISP KF Outbox Not Empty Interrupt +#define INT_ISP0 108 // ISP 0 Interrupt +#define INT_ISP1 109 // ISP 1 Interrupt +#define INT_ISP2 110 // ISP 2 Interrupt +#define INT_ISP3 111 // ISP 3 Interrupt +#define INT_ISP_DART 112 // ISP DART Interrupt + +// Reserved 113 + +#define INT_SEP_KF_INBOX_EMPTY 114 // SEP KF Inbox Empty Interrupt +#define INT_SEP_KF_INBOX_NOTEMPTY 115 // SEP KF Inbox Not Empty Interrupt +#define INT_SEP_KF_OUTBOX_EMPTY 116 // SEP KF Outbox Empty Interrupt +#define INT_SEP_KF_OUTBOX_NOTEMPTY 117 // SEP KF Outbox Not Empty Interrupt +#define INT_SEP_AUTH_ERROR 118 // SEP Authentication Error Interrupt +#define INT_SEP_CRIT_PATH_MONITOR 119 // SEP Critical Path Monitor Interrupt + +// Reserved 120 + +// XXX JF: AOP interrupts + +// Reserved 153 + +#define INT_DISP0 154 // Display 0 Interrupt +#define INT_DISP0_DART 155 // Display 0 DART Interrupt +#define INT_DISP0_SMMU 156 // Display 0 SMMU Interrupt +#define INT_DISP0_BACK_END_BLU 157 // Display 0 Back End Back Light Update Interrupt +#define INT_DISP0_BACK_END_VBI 158 // Display 0 Back End VBI Interrupt +#define INT_DISP0_BACK_END_VFTG 159 // Display 0 Back End VFTG Idle Interrupt +#define INT_DISP0_BACK_END_VBL 160 // Display 0 Back End VBL counter Interrupt +#define INT_DISPLAY_PORT0 161 // Display Port 0 +#define INT_EDP0 INT_DISPLAY_PORT0 +#define INT_DPORT0 INT_DISPLAY_PORT0 + +// Reserved 162 + +#define INT_DISP1 163 // Display 1 Interrupt +#define INT_DISP1_DART 164 // Display 1 DART Interrupt +#define INT_DISP1_SMMU 165 // Display 1 SMMU Interrupt +#define INT_DISP1_BACK_END_BLU 166 // Display 1 Back End Back Light Update Interrupt +#define INT_DISP1_BACK_END_VBI 167 // Display 1 Back End VBI Interrupt +#define INT_DISP1_BACK_END_VFTG 168 // Display 1 Back End VFTG Idle Interrupt +#define INT_DISP1_BACK_END_VBL 169 // Display 1 Back End VBL counter Interrupt +#define INT_DISPLAY_PORT1 170 // Display Port 1 + +// Reserved 171 + +// XXX: PMP + +// Reserved 176 + +#define INT_VDEC0 177 // Video Decoder 0 Interrupt + +// Reserved 178 + +#define INT_AVE_KF_INBOX_EMPTY 179 // AVE KF Inbox Empty Interrupt +#define INT_AVE_KF_INBOX_NOTEMPTY 180 // AVE KF Inbox Not Empty Interrupt +#define INT_AVE_KF_OUTBOX_EMPTY 181 // AVE KF Outbox Empty Interrupt +#define INT_AVE_KF_OUTBOX_NOTEMPTY 182 // AVE KF Outbox Not Empty Interrupt +#define INT_AVE_DART 183 // AVE DART Interrupt +#define INT_AVE_SMMU 184 // AVE SMMU Interrupt +#define INT_AVE 185 // AVE Interrupt +#define INT_SVE_SYNC 186 // SVE Driver Synchronization Interrupt + +// Reserved 187 - 189 + +#define INT_GFX 190 // GFX Interrupt +#define INT_GFX_SLEEP 191 // GFX Sleep Interrupt +#define INT_GFX_WAKE 192 // GFX Wake Interrupt +#define INT_GFX_CHG 193 // GFX Change Interrupt +#define INT_GFX_FW 194 // GFX Change Interrupt + +#define INT_SRS 195 // SRS Interrupt +#define INT_SRS_STG1 196 // SRS STG1 Interrupt +#define INT_SRS_BWM 197 // SRS BWM Interrupt +#define INT_SRS_NM 198 // SRS NM Interrupt +#define INT_SRS_DART 199 // SRS DART Interrupt +#define INT_SRS_STT 200 // SRS STT Interrupt + +#define INT_JPEG 201 // JPEG Interrupt +#define INT_JPEG_DART 202 // JPEG DART Interrupt +#define INT_JPEG_DART_PERF 203 // JPEG DART Performance Interrupt + +// Reserved 204 + +#define INT_MSR 205 // MSR Interrupt +#define INT_MSR_SMMU 206 // MSR SMMU Interrupt +#define INT_MSR_DART 207 // MSR DART Interrupt +#define INT_MSR_DAR_PERF 208 // MSR DART Performance Interrupt + +// Reserved 209 + +#define INT_SIO_KF_INBOX_EMPTY 210 // SIO KF Inbox Empty Interrupt +#define INT_SIO_KF_INBOX_NOTEMPTY 211 // SIO KF Inbox Not Empty Interrupt +#define INT_SIO_KF_OUTBOX_EMPTY 212 // SIO KF Outbox Empty Interrupt +#define INT_SIO_KF_OUTBOX_NOTEMPTY 213 // SIO KF Outbox Not Empty Interrupt +#define INT_SPI0 214 // SPI 0 Interrupt +#define INT_SPI1 215 // SPI 1 Interrupt +#define INT_SPI2 216 // SPI 2 Interrupt +#define INT_SPI3 217 // SPI 3 Interrupt +#define INT_UART0 218 // UART 0 Interrupt +#define INT_UART1 219 // UART 1 Interrupt +#define INT_UART2 220 // UART 2 Interrupt +#define INT_UART3 221 // UART 3 Interrupt +#define INT_UART4 222 // UART 4 Interrupt +#define INT_UART5 223 // UART 5 Interrupt +#define INT_UART6 224 // UART 6 Interrupt +#define INT_UART7 225 // UART 7 Interrupt +#define INT_UART8 226 // UART 8 Interrupt +#define INT_MCA0 227 // Multi-Channel Audio 0 Interrupt +#define INT_MCA1 228 // Multi-Channel Audio 1 Interrupt +#define INT_MCA2 229 // Multi-Channel Audio 2 Interrupt +#define INT_MCA3 230 // Multi-Channel Audio 3 Interrupt +#define INT_MCA4 231 // Multi-Channel Audio 4 Interrupt +#define INT_IIC0 232 // I2C 0 Interrupt +#define INT_IIC1 233 // I2C 1 Interrupt +#define INT_IIC2 234 // I2C 2 Interrupt +#define INT_IIC3 235 // I2C 3 Interrupt +#define INT_PWM 236 // PWM Interrupt +#define INT_AES0 237 // AES 0 Interrupt + +// Reserved 238 - 240 + +#define INT_USB_OTG 241 // USB OTG Interrupt +#define INT_USB2HOST0_EHCI 242 // USB EHCI 0 Interrupt +#define INT_USB2HOST0_OHCI 243 // USB OHCI 0 Interrupt +#define INT_USB2HOST1_EHCI 244 // USB EHCI 1 Interrupt +#define INT_USB2HOST2_EHCI 245 // USB EHCI 2 Interrupt +#define INT_USBOTG_RESUME 246 // USB OTG Resume Interrupt +#define INT_USB_20_BATT_CHRG_DET 247 // USB 2.0 Battery Charge Detect Interrupt +#define INT_USB2HOST0_PHY_RESUME 248 // USB Host 0 Resume Interrupt +#define INT_USB2HOST1_PHY_RESUME 249 // USB Host 1 Resume Interrupt +#define INT_USB2HOST2_PHY_RESUME 250 // USB Host 2 Resume Interrupt +#define INT_OTG_IN_EP0 251 // OTG IN Endpoint 0 Interrupt +#define INT_OTG_IN_EP1 252 // OTG IN Endpoint 1 Interrupt +#define INT_OTG_IN_EP2 253 // OTG IN Endpoint 2 Interrupt +#define INT_OTG_IN_EP3 254 // OTG IN Endpoint 3 Interrupt +#define INT_OTG_IN_EP4 255 // OTG IN Endpoint 4 Interrupt +#define INT_OTG_IN_EP5 256 // OTG IN Endpoint 5 Interrupt +#define INT_OTG_IN_EP6 257 // OTG IN Endpoint 6 Interrupt +#define INT_OTG_IN_EP7 258 // OTG IN Endpoint 7 Interrupt +#define INT_OTG_IN_EP8 259 // OTG IN Endpoint 8 Interrupt +#define INT_OTG_OUT_EP0 260 // OTG OUT Endpoint 0 Interrupt +#define INT_OTG_OUT_EP1 261 // OTG OUT Endpoint 1 Interrupt +#define INT_OTG_OUT_EP2 262 // OTG OUT Endpoint 2 Interrupt +#define INT_OTG_OUT_EP3 263 // OTG OUT Endpoint 3 Interrupt +#define INT_OTG_OUT_EP4 264 // OTG OUT Endpoint 4 Interrupt +#define INT_OTG_OUT_EP5 265 // OTG OUT Endpoint 5 Interrupt +#define INT_OTG_OUT_EP6 266 // OTG OUT Endpoint 6 Interrupt +#define INT_OTG_OUT_EP7 267 // OTG OUT Endpoint 7 Interrupt +#define INT_OTG_OUT_EP8 268 // OTG OUT Endpoint 8 Interrupt + +// Reserved 269 + +#define PCIE_LINK0 270 // PCIE Link 0 Interrupt +#define PCIE_LINK0_DART 271 // PCIE Link 0 DART Interrupt +#define PCIE_LINK0_MMU 272 // PCIE Link 0 MMU Interrupt +#define PCIE_LINK1 273 // PCIE Link 1 Interrupt +#define PCIE_LINK1_DART 274 // PCIE Link 1 DART Interrupt +#define PCIE_LINK1_MMU 275 // PCIE Link 1 MMU Interrupt +#define PCIE_LINK2 276 // PCIE Link 2 Interrupt +#define PCIE_LINK2_DART 277 // PCIE Link 2 DART Interrupt +#define PCIE_LINK2_MMU 278 // PCIE Link 2 MMU Interrupt +#define PCIE_LINK3 279 // PCIE Link 3 Interrupt +#define PCIE_LINK3_DART 280 // PCIE Link 3 DART Interrupt +#define PCIE_LINK3_MMU 281 // PCIE Link 3 MMU Interrupt +#define PCIE_LINK4 282 // PCIE Link 4 Interrupt +#define PCIE_LINK4_DART 283 // PCIE Link 4 DART Interrupt +#define PCIE_LINK4_MMU 284 // PCIE Link 4 MMU Interrupt +#define PCIE_LINK5 285 // PCIE Link 5 Interrupt +#define PCIE_LINK5_DART 286 // PCIE Link 5 DART Interrupt +#define PCIE_LINK5_MMU 287 // PCIE Link 5 MMU Interrupt +#define PCIE_MSI0 288 // PCIE MSI 0 Interrupt +#define PCIE_MSI1 289 // PCIE MSI 1 Interrupt +#define PCIE_MSI2 290 // PCIE MSI 2 Interrupt +#define PCIE_MSI3 291 // PCIE MSI 3 Interrupt +#define PCIE_MSI4 292 // PCIE MSI 4 Interrupt +#define PCIE_MSI5 293 // PCIE MSI 5 Interrupt +#define PCIE_MSI6 294 // PCIE MSI 6 Interrupt +#define PCIE_MSI7 295 // PCIE MSI 7 Interrupt +#define PCIE_MSI8 296 // PCIE MSI 8 Interrupt +#define PCIE_MSI9 297 // PCIE MSI 9 Interrupt +#define PCIE_MSI10 298 // PCIE MSI 10 Interrupt +#define PCIE_MSI11 299 // PCIE MSI 11 Interrupt +#define PCIE_MSI12 300 // PCIE MSI 12 Interrupt +#define PCIE_MSI13 301 // PCIE MSI 13 Interrupt +#define PCIE_MSI14 302 // PCIE MSI 14 Interrupt +#define PCIE_MSI15 303 // PCIE MSI 15 Interrupt +#define PCIE_MSI16 304 // PCIE MSI 16 Interrupt +#define PCIE_MSI17 305 // PCIE MSI 17 Interrupt +#define PCIE_MSI18 306 // PCIE MSI 18 Interrupt +#define PCIE_MSI19 307 // PCIE MSI 19 Interrupt +#define PCIE_MSI20 308 // PCIE MSI 20 Interrupt +#define PCIE_MSI21 309 // PCIE MSI 21 Interrupt +#define PCIE_MSI22 310 // PCIE MSI 22 Interrupt +#define PCIE_MSI23 311 // PCIE MSI 23 Interrupt +#define PCIE_MSI24 312 // PCIE MSI 24 Interrupt +#define PCIE_MSI25 313 // PCIE MSI 25 Interrupt +#define PCIE_MSI26 314 // PCIE MSI 26 Interrupt +#define PCIE_MSI27 315 // PCIE MSI 27 Interrupt +#define PCIE_MSI28 316 // PCIE MSI 28 Interrupt +#define PCIE_MSI29 317 // PCIE MSI 29 Interrupt +#define PCIE_MSI30 318 // PCIE MSI 30 Interrupt +#define PCIE_MSI31 319 // PCIE MSI 31 Interrupt + +#else +#error Unsupported Platform +#endif + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/s8000/include/platform/soc/hwregbase.h b/platform/s8000/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..4aefa61 --- /dev/null +++ b/platform/s8000/include/platform/soc/hwregbase.h @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#include + +/* + * DCS_REG_VERSION mapping used in iBoot for various platforms + * Maui: 1 + * s8003: 2 + * Elba: 3 + */ +#if SUB_PLATFORM_S8000 +#define DCS_REG_VERSION (1) +#elif SUB_PLATFORM_S8003 +#define DCS_REG_VERSION (2) +#elif SUB_PLATFORM_S8001 +#define DCS_REG_VERSION (3) +#else +#error "Unknown SUB_PLATFORM" +#endif + +/* S8000 and S8001 Reg Base Defs */ + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + +#define AMCC_BASE_ADDR(_n) (IO_BASE + ((_n) * 0x000200000)) // AMCC Config +#define NUM_AMCCS (1) + +#define DCS_BASE_ADDR (IO_BASE + 0x000200000) // DCS + +#define DCS_SPACING (0x40000) +#define SPLLCTRL_SPACING (0x00000C000) +#define AMP_CA_SPACING (0x000020000) +#define AMP_DQ_SPACING (0x000008000) +#define AMP_SPACING (DCS_SPACING) +#define AMP_BASE_ADDR (DCS_BASE_ADDR + AMP_CA_SPACING) +#define AMPH_BASE_ADDR (AMP_BASE_ADDR + 3 * AMP_DQ_SPACING) + +#define SWTCH_FAB_BASE_ADDR (IO_BASE + 0x000800000) // Switch Fabric Config + +#define CP_COM_BASE_ADDR (IO_BASE + 0x000D00000) // CP Common Registers +#define CP_COM_INT_BASE_ADDR (CP_COM_BASE_ADDR + 0x10000) // CP Common Interrupt Config Registers + +#define CP_0_DT_DBG_CA0_ADDR (IO_BASE + 0x000D40000) // Dup Tag Debug backdoor Ram Access For CP0/CA0 +#define CP_1_DT_DBG_CA0_ADDR (IO_BASE + 0x000E40000) // Dup Tag Debug backdoor Ram Access For CP1/CA0 + +#define RGX_CR_BASE_ADDR (IO_BASE + 0x001000000) // Templar4 Space + +#define GPC_BASE_ADDR (IO_BASE + 0x001e00000) // Templar4 Power Controller Space + +#define IMGV42AF_AFC_AIU_BASE_ADDR (IO_BASE + 0x001f00000) // IMGv42AF0: Local PIO Config Space of AF AIU Block +#define IMGV42AF_AFUSR_BASE_ADDR (IO_BASE + 0x001f02000) // IMGv42AF0: Bridge PIO Space + +#define ACC_BASE_ADDR (IO_BASE + 0x002000000) // Apple Compute Complex +#define CCC_CPU0_SYS_BASE_ADDR (IO_BASE + 0x002050000) // Twister CPU0 Implementation Specific Registers +#define CCC_CPU1_SYS_BASE_ADDR (IO_BASE + 0x002150000) // Twister CPU1 Implementation Specific Registers + +#define CCC0_SYS_BASE_ADDR (IO_BASE + 0x002200000) // Twister Core Complex Registers + +#define CCC_SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config +#define SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config +// XXX JF +#if SUB_PLATFORM_T7000 +#define CCC_CAM_BUSMUX_BASE_ADDR (IO_BASE + 0x005000000) // AF Camera BusMux Config +#endif + +#define ISP_AFC_AIU_0_BASE_ADDR (IO_BASE + 0x005B00000) // ISP AXI to AF Bridge +// XXX JF +#if SUB_PLATFORM_T7000 +#define ISP_AFC_AIU_1_BASE_ADDR (IO_BASE + 0x005B10000) // ISP AXI to AF Bridge +#endif +#define ISP_INTR2AXI_BASE_ADDR (IO_BASE + 0x005B20000) // ISP Interrupt to AXI Widget +#define ISP_DART_BASE_ADDR (IO_BASE + 0x005B22000) // ISP DART +#define ISP_SMMU_BASE_ADDR (IO_BASE + 0x005B24000) // ISP SMMU +#define ISP_ISPCTRL_R0_BASE_ADDR (IO_BASE + 0x005B40000) // SISP Region 0 Control +#define ISP_MIPI_CSI_0_BASE_ADDR (IO_BASE + 0x005B80000) // MIPI CSI Controller +#define ISP_MIPI_CSI_1_BASE_ADDR (IO_BASE + 0x005B81000) // MIPI CSI Controller +#define ISP_SMB_0_BASE_ADDR (IO_BASE + 0x005B82000) // SMB Controller +#define ISP_SMB_1_BASE_ADDR (IO_BASE + 0x005B83000) // SMB Controller +#define ISP_FD_BASE_ADDR (IO_BASE + 0x005B84000) // Face Detect +#define ISP_AISP_BASE_ADDR (IO_BASE + 0x005BA0000) // AISP +#define ISP_ISPCTRL_R1_BASE_ADDR (IO_BASE + 0x005BC0000) // SISP Region 1 Control +#define ISP_AKF_BASE_ADDR (IO_BASE + 0x005C00000) // SISP KF Widgets and Config + +// XXX JF +#if SUB_PLATFORM_T7000 +#define DISP_BUSMUX_BASE_ADDR (IO_BASE + 0x006000000) // AF Display BusMux Config +#endif +#define DISP0_FAB_BASE_ADDR (IO_BASE + 0x006100000) // DisplayPipe0 AF and AXI Config +#define DISP0_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 +#define DISP0_ADP_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 Configuration +#define DISP0_SMMU_BASE_ADDR (IO_BASE + 0x006300000) // DisplayPipe0 SMMU Configuration +#define DISP0_ADBE_BASE_ADDR (IO_BASE + 0x006400000) // DisplayPipe0 Backend Config +#define DISP0_AAP_BASE_ADDR (IO_BASE + 0x006440000) // DisplayPipe0 Ambient-Adaptive Pixel Config +#define DISP0_DPB_BASE_ADDR (IO_BASE + 0x006480000) // DisplayPipe0 Pixel Backlight Config +#define DISP0_DITHER_BASE_ADDR (IO_BASE + 0x0064C0000) // DisplayPipe0 Dither Config +#define DITHER_BASE_ADDR DISP0_DITHER_BASE_ADDR +#define DITHER_VERSION (3) + +#define DISP0_MIPI_DSI_BASE_ADDR (IO_BASE + 0x006600000) // DisplayPipe0 MIPI DSI Config +#define DISP0_DPTX_BASE_ADDR (IO_BASE + 0x006700000) // DisplayPipe0 DisplayPort TX Config + +#define MSR_AFC_AIU_BASE_ADDR (IO_BASE + 0x007800000) // MSR AXI2AF AFC_AIU +#define MSR_BASE_ADDR (IO_BASE + 0x007900000) // Memory Scalar Rotator +#define MSR_SMMU_BASE_ADDR (IO_BASE + 0x007904000) // MSR SMMU +#define MSR_DART_BASE_ADDR (IO_BASE + 0x007908000) // DART for MSR SMMU +#define MSR_INTR2AXI_BASE_ADDR (IO_BASE + 0x00790C000) // MSR Interrupt to AXI Widget + +#define AJPEG_AFC_AIU_BASE_ADDR (IO_BASE + 0x007A00000) // AJPEG AXI2AF AFC_AIU +#define AJPEG_BASE_ADDR (IO_BASE + 0x007B00000) // AJPEG Wrap +#define AJPEG_DART_BASE_ADDR (IO_BASE + 0x007B02000) // AJPEG DART +#define AJPEG_INTR2AXI_BASE_ADDR (IO_BASE + 0x007B04000) // AJPEG Interrupt to AXI Widget + +#define SVE_BASE_ADDR (IO_BASE + 0x007C00000) // SVE Video Encoder Subsystem +#define SVE_AVE_AXI2AF (IO_BASE + 0x007C00000) // SVE AVE AXI to Apple Fabric Bridge +#define SVE_AFC_AIU_BASE_ADDR (IO_BASE + 0x007C00000) // SVE AXI2AF AFC_AIU +#define SVE_INTR2AXI_BASE_ADDR (IO_BASE + 0x007C10000) // SVE VENC Interrupt to AXI Widget +#define SVE_SMMU_BASE_ADDR (IO_BASE + 0x007C20000) // SVE Streaming MMU for AVE +#define SVE_DART_BASE_ADDR (IO_BASE + 0x007C30000) // SVE DART for AVE SMMU +#define SVE_PL301_BASE_ADDR (IO_BASE + 0x007C40000) // SVE PL301 Config +#define SVE_AKF_BASE_ADDR (IO_BASE + 0x007C80000) // SVE Kingfisher Wrapper Configuration +// XXX #define SVE_AVE_KF_DBG_BASE_ADDR (IO_BASE + 0x007CA0000) // SVE Kingfisher Wrapper Debug APB +#define SVE_CTRL_BASE_ADDR (IO_BASE + 0x007CC0000) // SVE Control Registers + +#define VXD_AFC_AIU_BASE_ADDR (IO_BASE + 0x007E00000) // VXD AXI2AF AFC_AIU +#define VXD_INTR2AXI_BASE_ADDR (IO_BASE + 0x007E10000) // VXD Interrupt to AXI Widget +#define VXD_PL301_BASE_ADDR (IO_BASE + 0x007E20000) // VXD PL301 Config +#define VXD_CFG_BASE_ADDR (IO_BASE + 0x007F00000) // VXD Config Registers + +#define IOBUSMUX_BASE_ADDR (IO_BASE + 0x009000000) // IO BusMux Config + +#define SB_BASE_ADDR (IO_BASE + 0x00A000000) // South Bridge + +#define ASIO_MISC_0_BASE_ADDR (IO_BASE + 0x00A000000) // ASIO Shim0 Misc Registers +#define ASIO_AUD_MUX_BASE_ADDR (IO_BASE + 0x00A003000) // ASIO Audio I2S Switch Config +#define ASIO_SPI_BASE_ADDR (IO_BASE + 0x00A080000) // ASIO SPI Device +#define ASIO_SPI_TX_CFG_BASE_ADDR (IO_BASE + 0x00A081000) // ASIO SPI TX DMA Channel +#define ASIO_SPI_RX_CFG_BASE_ADDR (IO_BASE + 0x00A081800) // ASIO SPI RX DMA Channel +#define ASIO_SPI_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A082000) // ASIO SPI TX DMA Shim FIFO +#define ASIO_SPI_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A083000) // ASIO SPI RX DMA Shim FIFO +#define ASIO_MCA_BASE_ADDR (IO_BASE + 0x00A0A0000) // ASIO MCA Device +#define ASIO_MCA_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1000) // ASIO MCA TX DMA Channel +#define ASIO_MCA_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1800) // ASIO MCA RX DMA Channel +#define ASIO_MCA_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A2000) // ASIO MCA TX DMA Shim FIFO +#define ASIO_MCA_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A3000) // ASIO MCA RX DMA Shim FIFO +#define ASIO_UART_BASE_ADDR (IO_BASE + 0x00A0C0000) // ASIO UART Device +#define ASIO_UART_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1000) // ASIO UART TX DMA Channel +#define ASIO_UART_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1800) // ASIO UART RX DMA Channel +#define ASIO_UART_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C2000) // ASIO UART TX DMA Shim FIFO +#define ASIO_UART_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C3000) // ASIO UART RX DMA Shim FIFO +#define ASIO_MISC_1_BASE_ADDR (IO_BASE + 0x00A100000) // ASIO Shim1 Misc Registers +#define ASIO_AES_BASE_ADDR (IO_BASE + 0x00A108000) // ASIO AES Config and DMA Registers +#define ASIO_SMB_0_BASE_ADDR (IO_BASE + 0x00A110000) // ASIO I2C 0 Device +#define ASIO_SMB_1_BASE_ADDR (IO_BASE + 0x00A111000) // ASIO I2C 1 Device +#define ASIO_SMB_2_BASE_ADDR (IO_BASE + 0x00A112000) // ASIO I2C 2 Device +#define ASIO_SMB_3_BASE_ADDR (IO_BASE + 0x00A113000) // ASIO I2C 3 Device +#define ASIO_PWM_BASE_ADDR (IO_BASE + 0x00A118000) // ASIO PWM +#define ASIO_DNSZ_AXI_0_BASE_ADDR (IO_BASE + 0x00A141000) // ASIO Downsizer 0 Configuration Registers +#define ASIO_DNSZ_AXI_1_BASE_ADDR (IO_BASE + 0x00A142000) // ASIO Downsizer 1 Configuration Registers +#define ASIO_AKF_BASE_ADDR (IO_BASE + 0x00AE00000) // ASIO KF Wrapper +// XXX ASIO AKF DBG + +#define AUSB_CTL_REG_BASE_ADDR (IO_BASE + 0x00C000000) // USBCTL Config +#define AUSB_CTL_USB20PHY_REG_OFFSET (0x30) // USB20PHY Register offset within AUSBCTL registers +#define AUSB_OTG_BASE_ADDR (IO_BASE + 0x00C100000) // USB OTG +#define AUSB_USB2HOST0_EHCI_BASE_ADDR (IO_BASE + 0x00C200000) // EHCI0 +#define AUSB_USB2HOST0_OHCI_BASE_ADDR (IO_BASE + 0x00C300000) // OHCI0 +#define AUSB_USB2HOST1_EHCI_BASE_ADDR (IO_BASE + 0x00C400000) // EHCI1 +#define AUSB_USB2HOST1_OHCI_BASE_ADDR (IO_BASE + 0x00C500000) // OHCI1 +#define AUSB_PL301_BASE_ADDR (IO_BASE + 0x00C800000) // AUSB PL301 4-AHB Master to 1-AXI Slave +#define AUSB_PL301_WIDGET_BASE_ADDR (IO_BASE + 0x00C900000) // AUSB PL301 Widget +#define AUSB_INTR2AXI_BASE_ADDR (IO_BASE + 0x00CA00000) // AUSB Interrupt to AXI Widget +#define AUSB_AFIFO_WIDGET_BASE_ADDR (IO_BASE + 0x00CB00000) // AUSB Async FIFO + +#define ASEP_AKF_BASE_ADDR (IO_BASE + 0x00DA00000) // ASEP AKF control Registers + +#define PMGR_BASE_ADDR (IO_BASE + 0x00E000000) // PMGR + +#define AIC_BASE_ADDR (IO_BASE + 0x00E100000) // AIC +#define AIC_WIRE_VIRT_BASE_ADDR (IO_BASE + 0x00E110000) // AIC Wrapper + +#define DWI_BASE_ADDR (IO_BASE + 0x00E200000) // DWI + +#define LIO_MEM_PL301_BASE_ADDR (IO_BASE + 0x00E900000) // PL310 for pd_lio memory +#define LIO_PIO_PL310_BASE_ADDR (IO_BASE + 0x00E940000) // PL310 for pd_lio PIO +#define LIO_DNSZ_AXI_BASE_ADDR (IO_BASE + 0x00E9C8000) // PL310 for pd_lio downsizer +#define LIO_SIO_AFIFO_WIDGETS_BASE_ADDR (IO_BASE + 0x00E9C0000) // SIO Async FIFO for pd_lio +#define LIO_DAP_AFIFO_WIDGETS_BASE_ADDR (IO_BASE + 0x00E9E0000) // DAP Async FIFO for pd_lio +#define LIO_AFC_AIU_BASE_ADDR (IO_BASE + 0x00F010000) // LIO AXI to AF Bridge + +#define GPIO_BASE_ADDR (IO_BASE + 0x00F100000) // GPIO +#define GLBTIMER_BASE_ADDR (IO_BASE + 0x00F140000) // Global Timer + +#define ERR_REFLECTION_BASE_ADDR (IO_BASE + 0x00FFFC000) + +#define AOP_BASE_ADDR (IO_BASE + 0x010000000) +#define AOP_MINIPMGR_BASE_ADDR (IO_BASE + 0x010200000) +#define DBG_WRP_BASE_ADDR (IO_BASE + 0x010300000) // Debug Sub-system Config +#define AOP_GPIO_BASE_ADDR (IO_BASE + 0x0100f0000) +#define AOP_SRAM_BASE_ADDR (IO_BASE + 0x010E00000) +#define AOP_RECONFIG_REGION_BASE_ADDR (IO_BASE + 0x010E9B000) +#define AOP_RECONFIG_REGION_SIZE (IO_BASE + 0x010EA0000 - AOP_RECONFIG_REGION_BASE_ADDR) +#define AOP_RECONFIG_REGION_DIAGS_BASE_ADDR (IO_BASE + 0x010E90000) +#define AOP_RECONFIG_REGION_DIAGS_SIZE (IO_BASE + 0x010EA0000 - AOP_RECONFIG_REGION_DIAGS_BASE_ADDR) +#define MEMORY_CALIB_SAVE_BASE_ADDR AOP_SRAM_BASE_ADDR // Temporarily save cold boot memcal results in AOP_SRAM + +#define APCIE_VERSION (2) +#define APCIE_COMMON_BASE_ADDR (PCI_REG_BASE + 0x00000000) +#define APCIE_PHY_BASE_ADDR (PCI_REG_BASE + 0x00008000) +#if SUB_PLATFORM_S8000 +#define APCIE_PHY_AUSP_SHM_BASE_ADDR (PCI_REG_BASE + 0x00009a00) +#define APCIE_PHY_AUST0_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8100) +#define APCIE_PHY_AUST1_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8300) +#define APCIE_PHY_AUST2_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8500) +#define APCIE_PHY_AUST3_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8700) +#define APCIE_PHY_AUST4_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8900) +#define APCIE_PHY_AUSR0_CFG_BASE_ADDR (PCI_REG_BASE + 0x8a00) +#define APCIE_PHY_AUSR0_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8b00) +#define APCIE_PHY_AUSR1_CFG_BASE_ADDR (PCI_REG_BASE + 0x8c00) +#define APCIE_PHY_AUSR1_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8d00) +#define APCIE_PHY_AUSR2_CFG_BASE_ADDR (PCI_REG_BASE + 0x8e00) +#define APCIE_PHY_AUSR2_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x8f00) +#define APCIE_PHY_AUSR3_CFG_BASE_ADDR (PCI_REG_BASE + 0x9000) +#define APCIE_PHY_AUSR3_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x9100) +#define APCIE_PHY_AUSR4_CFG_BASE_ADDR (PCI_REG_BASE + 0x9200) +#define APCIE_PHY_AUSR4_SHM_CFG_BASE_ADDR (PCI_REG_BASE + 0x9300) +#elif SUB_PLATFORM_S8003 +#define APCIE_PHY_PMA_COMMON_BASE_ADDR (PCI_REG_BASE + 0x0a000000) +#define APCIE_PHY_PMA_TX_LANE_BASE_ADDR (PCI_REG_BASE + 0x0a010000) +#define APCIE_PHY_PMA_TX_LANE_STRIDE (0x800) +#define APCIE_PHY_PMA_RX_LANE_BASE_ADDR (PCI_REG_BASE + 0x0a020000) +#define APCIE_PHY_PMA_RX_LANE_STRIDE (0x800) +#endif +#define APCIE_COUNTER_BASE_ADDR (PCI_REG_BASE + 0x4000) +#define APCIE_CONFIG_BASE_ADDR (PCI_REG_BASE + 0x01000000) +#define APCIE_CONFIG_PORT_STRIDE (0x01000000) + +/* iBoot Specific Defs */ + +#define AKF_VERSION (2) + +#define UART0_BASE_ADDR (ASIO_UART_BASE_ADDR) +#define UART1_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x04000) +#define UART2_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x08000) +#define UART3_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x10000) +#define UART5_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x14000) +#define UART6_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x18000) +#define UART7_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x1C000) +#define UART8_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x20000) +#define UARTS_COUNT (9) +#define UART_VERSION (1) + +#define SPI0_BASE_ADDR (ASIO_SPI_BASE_ADDR) +#define SPI1_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x04000) +#define SPI2_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x08000) +#define SPI3_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x0C000) +#define SPI_VERSION (1) +#define SPIS_COUNT (4) + +#define IIC_BASE_ADDR (ASIO_SMB_0_BASE_ADDR) +#define IIC_SPACING (0x00001000) +#define IICS_COUNT (3) + +#define USBPHY_VERSION (4) + +#define DSIM_BASE_ADDR (DISP0_MIPI_DSI_BASE_ADDR) +#define DSIM_LANE_COUNT (4) +#define DSIM_VERSION (2) + +#define EDP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define DP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define LPDP_PHY_BASE_ADDR (DISP0_DPTX_BASE_ADDR + 0x080000) +#define DISPLAYPORT_VERSION (4) +#define LPDP_PHY_VERSION (1) + +#define ADBE_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define DISP_VERSION (5) +#define ADP_VERSION (2) + +#define GPIOC_COUNT (2) +#define GPIO_VERSION (4) +#define GPIO_0_GROUP_COUNT (25) +#define GPIO_1_BASE_ADDR (AOP_GPIO_BASE_ADDR) +#define GPIO_1_GROUP_COUNT (4) +#define GPIO_AP (GPIOC_0) +#define GPIO_AOP (GPIOC_1) +#define GPIO_GROUP_COUNT (GPIO_0_GROUP_COUNT) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define AIC_VERSION (1) +#define AIC_INT_COUNT (256) + +#define PMGR_WDG_VERSION (1) + +#define USBOTG_BASE_ADDR (AUSB_OTG_BASE_ADDR) + +#define APCIE_NUM_LINKS (4) + +#define DART0_BASE_ADDR (PCI_REG_BASE + 0x1008000) +#define DART0_ADDR_MASK (0x3FFFFFFF) +#define DART1_BASE_ADDR (PCI_REG_BASE + 0x2008000) +#define DART1_ADDR_MASK (0x3FFFFFFF) +#define DART2_BASE_ADDR (PCI_REG_BASE + 0x3008000) +#define DART2_ADDR_MASK (0x3FFFFFFF) +#define DART3_BASE_ADDR (PCI_REG_BASE + 0x4008000) +#define DART3_ADDR_MASK (0x3FFFFFFF) + +#define PCIE_PORT0_DART_ID (0) +#define PCIE_PORT1_DART_ID (1) +#define PCIE_PORT2_DART_ID (2) +#define PCIE_PORT3_DART_ID (3) +#define NUM_DARTS (4) + +#define AES_AP_BASE_ADDR (ASIO_AES_BASE_ADDR) +#define AES_AP_VERSION (0) + +#elif SUB_PLATFORM_S8001 + +#define AMCC_BASE_ADDR(_n) (IO_BASE + ((_n) * 0x000200000)) // AMCC Config +#define NUM_AMCCS (2) + +#define DCS_BASE_ADDR (IO_BASE + 0x000400000) // DCS + +#define DCS_SPACING (0x40000) +#define SPLLCTRL_SPACING (0x00000C000) +#define AMP_CA_SPACING (0x000020000) +#define AMP_DQ_SPACING (0x000008000) +#define AMP_SPACING (DCS_SPACING) +#define AMP_BASE_ADDR (DCS_BASE_ADDR + AMP_CA_SPACING) +#define AMPH_BASE_ADDR (AMP_BASE_ADDR + 3 * AMP_DQ_SPACING) + +#define SWTCH_FAB_BASE_ADDR (IO_BASE + 0x000800000) // Switch Fabric Config + +#define CP0_COM_BASE_ADDR (IO_BASE + 0x000A00000) // CP0 Common Registers +#define CP0_COM_INT_BASE_ADDR (CP0_COM_BASE_ADDR + 0x10000) // CP0 Common Interrupt Config Registers + +#define CP0_0_DT_DBG_CA0_ADDR (IO_BASE + 0x000A40000) // Dup Tag Debug backdoor Ram Access For CP0/CA0 +#define CP0_1_DT_DBG_CA0_ADDR (IO_BASE + 0x000B40000) // Dup Tag Debug backdoor Ram Access For CP0/CA0 + +#define CP1_COM_BASE_ADDR (IO_BASE + 0x000C00000) // CP1 Common Registers +#define CP1_COM_INT_BASE_ADDR (CP1_COM_BASE_ADDR + 0x10000) // CP1 Common Interrupt Config Registers + +#define CP1_0_DT_DBG_CA0_ADDR (IO_BASE + 0x000C40000) // Dup Tag Debug backdoor Ram Access For CP1/CA0 +#define CP1_1_DT_DBG_CA0_ADDR (IO_BASE + 0x000D40000) // Dup Tag Debug backdoor Ram Access For CP1/CA0 + +#define RGX_CR_BASE_ADDR (IO_BASE + 0x001000000) // Templar4 Space + +#define GPC_BASE_ADDR (IO_BASE + 0x001d00000) // Templar4 Power Controller Space + +#define IMGV42AF_AFC_AIU_BASE_ADDR (IO_BASE + 0x001f00000) // IMGv42AF0: Local PIO Config Space of AF AIU Block +#define IMGV42AF_AFUSR_BASE_ADDR (IO_BASE + 0x001f40000) // IMGv42AF0: Bridge PIO Space +#define IMGV42AF1_AFC_AIU_BASE_ADDR (IO_BASE + 0x001f80000) // IMGv42AF1: Local PIO Config Space of AF AIU Block +#define IMGV42AF1_AFUSR_BASE_ADDR (IO_BASE + 0x001fC0000) // IMGv42AF1: Bridge PIO Space + +#define ACC_BASE_ADDR (IO_BASE + 0x002000000) // Apple Compute Complex +#define CCC_CPU0_SYS_BASE_ADDR (IO_BASE + 0x002050000) // Twister CPU0 Implementation Specific Registers +#define CCC_CPU1_SYS_BASE_ADDR (IO_BASE + 0x002150000) // Twister CPU1 Implementation Specific Registers +#define CCC0_SYS_BASE_ADDR (IO_BASE + 0x002200000) // Twister Core Complex Registers + +#define CCC_SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config +#define SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config + +#define ISP_AFC_AIU_0_BASE_ADDR (IO_BASE + 0x005B00000) // ISP AXI to AF Bridge +#define ISP_INTR2AXI_BASE_ADDR (IO_BASE + 0x005B20000) // ISP Interrupt to AXI Widget +#define ISP_DART_BASE_ADDR (IO_BASE + 0x005B22000) // ISP DART +#define ISP_SMMU_BASE_ADDR (IO_BASE + 0x005B24000) // ISP SMMU +#define ISP_ISPCTRL_R0_BASE_ADDR (IO_BASE + 0x005B40000) // SISP Region 0 Control +#define ISP_SMB_0_BASE_ADDR (IO_BASE + 0x005B82000) // SMB Controller +#define ISP_SMB_1_BASE_ADDR (IO_BASE + 0x005B83000) // SMB Controller +#define ISP_FD_BASE_ADDR (IO_BASE + 0x005B84000) // Face Detect +#define ISP_AISP_BASE_ADDR (IO_BASE + 0x005BA0000) // AISP +#define ISP_ISPCTRL_R1_BASE_ADDR (IO_BASE + 0x005BC0000) // SISP Region 1 Control +#define ISP_AKF_BASE_ADDR (IO_BASE + 0x005C00000) // SISP KF Widgets and Config + +#define RT_BUSMUX_BASE_ADDR (IO_BASE + 0x006000000) // RT BusMux Config + +#define DISP0_FAB_BASE_ADDR (IO_BASE + 0x006100000) // DisplayPipe0 AF and AXI Config +#define DISP0_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 +#define DISP0_ADP_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 Configuration +#define DISP0_SMMU_BASE_ADDR (IO_BASE + 0x006300000) // DisplayPipe0 SMMU Configuration +#define DISP0_ADBE_BASE_ADDR (IO_BASE + 0x006400000) // DisplayPipe0 Backend Config +#define DISP0_AAP_BASE_ADDR (IO_BASE + 0x006440000) // DisplayPipe0 Ambient-Adaptive Pixel Config +#define DISP0_DPB_BASE_ADDR (IO_BASE + 0x006480000) // DisplayPipe0 Pixel Backlight Config +#define DISP0_WPC_BASE_ADDR (IO_BASE + 0x0064C0000) // DisplayPipe0 Whitepoint Correction +#define DISP0_PRC_BASE_ADDR (IO_BASE + 0x006500000) +#define DISP0_DITHER_BASE_ADDR (IO_BASE + 0x006540000) // DisplayPipe0 Dither Config +#define DITHER_BASE_ADDR DISP0_DITHER_BASE_ADDR +#define DITHER_VERSION (4) + +#define DISP0_DPTX_BASE_ADDR (IO_BASE + 0x006700000) // DisplayPipe0 DisplayPort TX Config + +#define DISP1_FAB_BASE_ADDR (IO_BASE + 0x006900000) // DisplayPipe1 AF and AXI Config +#define DISP1_BASE_ADDR (IO_BASE + 0x006A00000) // DisplayPipe1 +#define DISP1_ADP_BASE_ADDR (IO_BASE + 0x006A00000) // DisplayPipe1 Ambient-Adaptive Pixel Config +#define DISP1_SMMU_BASE_ADDR (IO_BASE + 0x006B00000) // DisplayPipe1 SMMU Configuration + +#define MEDIA_BUS_MUX (IO_BASE + 0x007000000) // Media Bus Mux +#define DISP1_MEDIA_BUSMUX_BASE_ADDR (IO_BASE + 0x008000000) // DisplayPipe1 AF Media BusMux Config + +#define MSR_AFC_AIU_BASE_ADDR (IO_BASE + 0x007800000) // MSR AXI2AF AFC_AIU +#define MSR_BASE_ADDR (IO_BASE + 0x007900000) // Memory Scalar Rotator +#define MSR_SMMU_BASE_ADDR (IO_BASE + 0x007904000) // MSR SMMU +#define MSR_DART_BASE_ADDR (IO_BASE + 0x007908000) // DART for MSR SMMU +#define MSR_INTR2AXI_BASE_ADDR (IO_BASE + 0x00790C000) // MSR Interrupt to AXI Widget + +#define AJPEG_AFC_AIU_BASE_ADDR (IO_BASE + 0x007A00000) // AJPEG AXI2AF AFC_AIU +#define AJPEG_BASE_ADDR (IO_BASE + 0x007B00000) // AJPEG Wrap +#define AJPEG_DART_BASE_ADDR (IO_BASE + 0x007B04000) // AJPEG DART +#define AJPEG_INTR2AXI_BASE_ADDR (IO_BASE + 0x007B08000) // AJPEG Interrupt to AXI Widget + +#define SVE_BASE_ADDR (IO_BASE + 0x007C00000) // SVE Video Encoder Subsystem +#define SVE_AVE_AXI2AF (IO_BASE + 0x007C00000) // SVE AVE AXI to Apple Fabric Bridge +#define SVE_AFC_AIU_BASE_ADDR (IO_BASE + 0x007C00000) // SVE AXI2AF AFC_AIU +#define SVE_INTR2AXI_BASE_ADDR (IO_BASE + 0x007C10000) // SVE VENC Interrupt to AXI Widget +#define SVE_SMMU_BASE_ADDR (IO_BASE + 0x007C20000) // SVE Streaming MMU for AVE +#define SVE_DART_BASE_ADDR (IO_BASE + 0x007C30000) // SVE DART for AVE SMMU +#define SVE_PL301_BASE_ADDR (IO_BASE + 0x007C40000) // SVE PL301 Config +#define SVE_AKF_BASE_ADDR (IO_BASE + 0x007C80000) // SVE Kingfisher Wrapper Configuration +// XXX #define SVE_AVE_KF_DBG_BASE_ADDR (IO_BASE + 0x007CA0000) // SVE Kingfisher Wrapper Debug APB +#define SVE_CTRL_BASE_ADDR (IO_BASE + 0x007CC0000) // SVE Control Registers + +#define VXD_AFC_AIU_BASE_ADDR (IO_BASE + 0x007E00000) // VXD AXI2AF AFC_AIU +#define VXD_CFG_BASE_ADDR (IO_BASE + 0x007F00000) // VXD Config Registers + +#define SB_BASE_ADDR (IO_BASE + 0x00A000000) // South Bridge + +#define ASIO_MISC_0_BASE_ADDR (IO_BASE + 0x00A000000) // ASIO Shim0 Misc Registers +#define ASIO_AUD_MUX_BASE_ADDR (IO_BASE + 0x00A003000) // ASIO Audio I2S Switch Config +#define ASIO_SPI_BASE_ADDR (IO_BASE + 0x00A080000) // ASIO SPI Device +#define ASIO_SPI_TX_CFG_BASE_ADDR (IO_BASE + 0x00A081000) // ASIO SPI TX DMA Channel +#define ASIO_SPI_RX_CFG_BASE_ADDR (IO_BASE + 0x00A081800) // ASIO SPI RX DMA Channel +#define ASIO_SPI_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A082000) // ASIO SPI TX DMA Shim FIFO +#define ASIO_SPI_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A083000) // ASIO SPI RX DMA Shim FIFO +#define ASIO_MCA_BASE_ADDR (IO_BASE + 0x00A0A0000) // ASIO MCA Device +#define ASIO_MCA_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1000) // ASIO MCA TX DMA Channel +#define ASIO_MCA_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1800) // ASIO MCA RX DMA Channel +#define ASIO_MCA_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A2000) // ASIO MCA TX DMA Shim FIFO +#define ASIO_MCA_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A3000) // ASIO MCA RX DMA Shim FIFO +#define ASIO_UART_BASE_ADDR (IO_BASE + 0x00A0C0000) // ASIO UART Device +#define ASIO_UART_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1000) // ASIO UART TX DMA Channel +#define ASIO_UART_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1800) // ASIO UART RX DMA Channel +#define ASIO_UART_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C2000) // ASIO UART TX DMA Shim FIFO +#define ASIO_UART_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C3000) // ASIO UART RX DMA Shim FIFO +#define ASIO_MISC_1_BASE_ADDR (IO_BASE + 0x00A100000) // ASIO Shim1 Misc Registers +#define ASIO_AES_BASE_ADDR (IO_BASE + 0x00A108000) // ASIO AES Config and DMA Registers +#define ASIO_SMB_0_BASE_ADDR (IO_BASE + 0x00A110000) // ASIO I2C 0 Device +#define ASIO_SMB_1_BASE_ADDR (IO_BASE + 0x00A111000) // ASIO I2C 1 Device +#define ASIO_SMB_2_BASE_ADDR (IO_BASE + 0x00A112000) // ASIO I2C 2 Device +#define ASIO_SMB_3_BASE_ADDR (IO_BASE + 0x00A113000) // ASIO I2C 3 Device +#define ASIO_PWM_BASE_ADDR (IO_BASE + 0x00A118000) // ASIO PWM +#define ASIO_DNSZ_AXI_0_BASE_ADDR (IO_BASE + 0x00A141000) // ASIO Downsizer 0 Configuration Registers +#define ASIO_DNSZ_AXI_1_BASE_ADDR (IO_BASE + 0x00A142000) // ASIO Downsizer 1 Configuration Registers +#define ASIO_AKF_BASE_ADDR (IO_BASE + 0x00AE00000) // ASIO KF Wrapper +// XXX ASIO AKF DBG + +#define AUSB_CTL_REG_BASE_ADDR (IO_BASE + 0x00C000000) // USBCTL Config +#define AUSB_CTL_USB20PHY_REG_OFFSET (0x30) // USB20PHY Register offset within AUSBCTL registers +#define AUSB_OTG_BASE_ADDR (IO_BASE + 0x00C100000) // USB OTG +#define AUSB_USB2HOST0_EHCI_BASE_ADDR (IO_BASE + 0x00C200000) // EHCI0 +#define AUSB_USB2HOST0_OHCI_BASE_ADDR (IO_BASE + 0x00C300000) // OHCI0 +#define AUSB_USB2HOST1_EHCI_BASE_ADDR (IO_BASE + 0x00C400000) // EHCI1 +#define AUSB_USB2HOST1_OHCI_BASE_ADDR (IO_BASE + 0x00C500000) // OHCI1 +#define AUSB_PL301_BASE_ADDR (IO_BASE + 0x00C800000) // AUSB PL301 4-AHB Master to 1-AXI Slave +#define AUSB_PL301_WIDGET_BASE_ADDR (IO_BASE + 0x00C900000) // AUSB PL301 Widget +#define AUSB_INTR2AXI_BASE_ADDR (IO_BASE + 0x00CA00000) // AUSB Interrupt to AXI Widget +#define AUSB_AFIFO_WIDGET_BASE_ADDR (IO_BASE + 0x00CB00000) // AUSB Async FIFO + +#define ASEP_AKF_BASE_ADDR (IO_BASE + 0x00DA00000) // ASEP AKF control Registers + +#define PMGR_BASE_ADDR (IO_BASE + 0x00E000000) // PMGR + +#define AIC_BASE_ADDR (IO_BASE + 0x00E100000) // AIC +#define AIC_WIRE_VIRT_BASE_ADDR (IO_BASE + 0x00E110000) // AIC Wrapper + +#define DWI_BASE_ADDR (IO_BASE + 0x00E200000) // DWI + +#define LIO_MEM_PL301_BASE_ADDR (IO_BASE + 0x00F160000) // PL310 for pd_lio memory +#define LIO_PIO_PL310_BASE_ADDR (IO_BASE + 0x00F180000) // PL310 for pd_lio PIO +#define LIO_NIC_PL301_BASE_ADDR (IO_BASE + 0x00F1A0000) // PL310 for pd_lio downsizer +#define LIO_PMS_AFIFO_WIDGETS_BASE_ADDR (IO_BASE + 0x00F1E0000) // PMS Async FIFO for pd_lio +#define LIO_AFC_AIU_BASE_ADDR (IO_BASE + 0x00F000000) // LIO AXI to AF Bridge +#define SBR_AFC_AIU_BASE_ADDR (LIO_AFC_AIU_BASE_ADDR) + +#define GPIO_BASE_ADDR (IO_BASE + 0x00F100000) // GPIO +#define GLBTIMER_BASE_ADDR (IO_BASE + 0x00F140000) // Global Timer + +#define ERR_REFLECTION_BASE_ADDR (IO_BASE + 0x00FFFC000) + +#define AOP_BASE_ADDR (IO_BASE + 0x010000000) +#define AOP_MINIPMGR_BASE_ADDR (IO_BASE + 0x010200000) +#define DBG_WRP_BASE_ADDR (IO_BASE + 0x010300000) // Debug Sub-system Config +#define AOP_GPIO_BASE_ADDR (IO_BASE + 0x0100f0000) +#define AOP_SRAM_BASE_ADDR (IO_BASE + 0x010E00000) +#define AOP_RECONFIG_REGION_BASE_ADDR (IO_BASE + 0x010E9B000) +#define AOP_RECONFIG_REGION_SIZE (IO_BASE + 0x010EA0000 - AOP_RECONFIG_REGION_BASE_ADDR) +#define AOP_RECONFIG_REGION_DIAGS_BASE_ADDR (IO_BASE + 0x010E90000) +#define AOP_RECONFIG_REGION_DIAGS_SIZE (IO_BASE + 0x010EA0000 - AOP_RECONFIG_REGION_DIAGS_BASE_ADDR) +#define MEMORY_CALIB_SAVE_BASE_ADDR AOP_SRAM_BASE_ADDR // Temporarily save cold boot memcal results in AOP_SRAM + +#define APCIE_VERSION (2) +#define APCIE_COMMON_BASE_ADDR (PCI_REG_BASE + 0x00000000) +#define APCIE_COUNTER_BASE_ADDR (PCI_REG_BASE + 0x4000) +#define APCIE_PHY_BASE_ADDR (PCI_REG_BASE + 0x8000) +#define APCIE_CONFIG_BASE_ADDR (PCI_REG_BASE + 0x01000000) +#define APCIE_CONFIG_PORT_STRIDE (0x01000000) +#define APCIE_PHY_PMA_COMMON_BASE_ADDR (PCI_REG_BASE + 0x0a000000) +#define APCIE_PHY_PMA_TX_LANE_BASE_ADDR (PCI_REG_BASE + 0x0a010000) +#define APCIE_PHY_PMA_TX_LANE_STRIDE (0x800) +#define APCIE_PHY_PMA_RX_LANE_BASE_ADDR (PCI_REG_BASE + 0x0a020000) +#define APCIE_PHY_PMA_RX_LANE_STRIDE (0x800) + +/* iBoot Specific Defs */ + +#define AKF_VERSION (2) + +#define UART0_BASE_ADDR (ASIO_UART_BASE_ADDR) +#define UART1_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x04000) +#define UART2_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x08000) +#define UART3_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x10000) +#define UART5_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x14000) +#define UART6_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x18000) +#define UART7_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x1C000) +#define UART8_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x20000) +#define UARTS_COUNT (9) +#define UART_VERSION (1) + +#define SPI0_BASE_ADDR (ASIO_SPI_BASE_ADDR) +#define SPI1_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x04000) +#define SPI2_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x08000) +#define SPI3_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x0C000) +#define SPI_VERSION (1) +#define SPIS_COUNT (4) + +#define IIC_BASE_ADDR (ASIO_SMB_0_BASE_ADDR) +#define IIC_SPACING (0x00001000) +#define IICS_COUNT (4) + +#define USBPHY_VERSION (4) + +#define EDP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define DP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define LPDP_PHY_BASE_ADDR (DISP0_DPTX_BASE_ADDR + 0x080000) +#define DISPLAYPORT_VERSION (5) +#define LPDP_PHY_VERSION (2) + +#define ADBE_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define DISP_VERSION (5) +#define ADP_VERSION (2) + +#define GPIOC_COUNT (2) +#define GPIO_VERSION (5) +#define GPIO_0_GROUP_COUNT (28) +#define GPIO_1_BASE_ADDR (AOP_GPIO_BASE_ADDR) +#define GPIO_1_GROUP_COUNT (4) +#define GPIO_AP (GPIOC_0) +#define GPIO_AOP (GPIOC_1) +#define GPIO_GROUP_COUNT (GPIO_0_GROUP_COUNT) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define AIC_VERSION (1) +#define AIC_INT_COUNT (256) + +#define PMGR_WDG_VERSION (1) + +#define USBOTG_BASE_ADDR (AUSB_OTG_BASE_ADDR) + +#define APCIE_NUM_LINKS (6) + +#define DART0_BASE_ADDR (PCI_REG_BASE + 0x1008000) +#define DART0_ADDR_MASK (0x3FFFFFFF) +#define DART1_BASE_ADDR (PCI_REG_BASE + 0x2008000) +#define DART1_ADDR_MASK (0x3FFFFFFF) +#define DART2_BASE_ADDR (PCI_REG_BASE + 0x3008000) +#define DART2_ADDR_MASK (0x3FFFFFFF) +#define DART3_BASE_ADDR (PCI_REG_BASE + 0x4008000) +#define DART3_ADDR_MASK (0x3FFFFFFF) +#define DART4_BASE_ADDR (PCI_REG_BASE + 0x5008000) +#define DART4_ADDR_MASK (0x3FFFFFFF) +#define DART5_BASE_ADDR (PCI_REG_BASE + 0x6008000) +#define DART5_ADDR_MASK (0x3FFFFFFF) + +#define PCIE_PORT0_DART_ID (0) +#define PCIE_PORT1_DART_ID (1) +#define PCIE_PORT2_DART_ID (2) +#define PCIE_PORT3_DART_ID (3) +#define PCIE_PORT4_DART_ID (4) +#define PCIE_PORT5_DART_ID (5) +#define NUM_DARTS (6) + +#define AES_AP_BASE_ADDR (ASIO_AES_BASE_ADDR) +#define AES_AP_VERSION (0) + +#endif + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/s8000/include/platform/soc/miu.h b/platform/s8000/include/platform/soc/miu.h new file mode 100644 index 0000000..d5240e3 --- /dev/null +++ b/platform/s8000/include/platform/soc/miu.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rSECUREROMCTRL_ROMADDRREMAP (*(volatile u_int32_t *)(AOP_MINIPMGR_BASE_ADDR + 0xd0014)) + +#define MCCLOCKREGION_TZ0BASEADDR(_n) (AMCC_BASE_ADDR(_n) + 0x480) +#define MCCLOCKREGION_TZ0ENDADDR(_n) (AMCC_BASE_ADDR(_n) + 0x484) +#define MCCLOCKREGION_TZ1BASEADDR(_n) (AMCC_BASE_ADDR(_n) + 0x488) +#define MCCLOCKREGION_TZ1ENDADDR(_n) (AMCC_BASE_ADDR(_n) + 0x48c) +#define MCCLOCKREGION_TZ0LOCK(_n) (AMCC_BASE_ADDR(_n) + 0x490) +#define MCCLOCKREGION_TZ1LOCK(_n) (AMCC_BASE_ADDR(_n) + 0x494) + +#define rMCCLOCKREGION_TZ0BASEADDR(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ0BASEADDR(_n))) +#define rMCCLOCKREGION_TZ0ENDADDR(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ0ENDADDR(_n))) +#define rMCCLOCKREGION_TZ1BASEADDR(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ1BASEADDR(_n))) +#define rMCCLOCKREGION_TZ1ENDADDR(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ1ENDADDR(_n))) +#define rMCCLOCKREGION_TZ0LOCK(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ0LOCK(_n))) +#define rMCCLOCKREGION_TZ1LOCK(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ1LOCK(_n))) + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +#define CP_COM_DYN_CLK_GATING_CTRL (0x000c) +#define rCP_COM_DYN_CLK_GATING_CTRL (*(volatile u_int32_t *)(CP_COM_BASE_ADDR + CP_COM_DYN_CLK_GATING_CTRL)) +#define CPCOM_INT_NORM_REQUEST (0x0000) +#define rCP_COM_INT_NORM_REQUEST (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_REQUEST)) +#define CPCOM_INT_NORM_MASK_SET (0x0004) +#define rCP_COM_INT_NORM_MASK_SET (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_SET)) +#define CPCOM_INT_NORM_MASK_CLR (0x0008) +#define rCP_COM_INT_NORM_MASK_CLR (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_CLR)) +#else +#define CPCOM_INT_NORM_REQUEST (0x0000) +#define rCP0_COM_INT_NORM_REQUEST (*(volatile u_int32_t *)(CP0_COM_INT_BASE_ADDR + CPCOM_INT_NORM_REQUEST)) +#define rCP1_COM_INT_NORM_REQUEST (*(volatile u_int32_t *)(CP1_COM_INT_BASE_ADDR + CPCOM_INT_NORM_REQUEST)) +#define CPCOM_INT_NORM_MASK_SET (0x0004) +#define rCP0_COM_INT_NORM_MASK_SET (*(volatile u_int32_t *)(CP0_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_SET)) +#define rCP1_COM_INT_NORM_MASK_SET (*(volatile u_int32_t *)(CP1_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_SET)) +#define CPCOM_INT_NORM_MASK_CLR (0x0008) +#define rCP0_COM_INT_NORM_MASK_CLR (*(volatile u_int32_t *)(CP0_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_CLR)) +#define rCP1_COM_INT_NORM_MASK_CLR (*(volatile u_int32_t *)(CP1_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_CLR)) +#endif + +// removed all the random registers used to set tunables +// we should grab these from the SPDS when we do Maui tunables + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/s8000/include/platform/soc/operating_point.h b/platform/s8000/include/platform/soc/operating_point.h new file mode 100644 index 0000000..d90305f --- /dev/null +++ b/platform/s8000/include/platform/soc/operating_point.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_OPERATING_POINT_H +#define __PLATFORM_SOC_OPERATING_POINT_H + +#include +struct operating_point_params { + union { + struct { + uint64_t voltage_index:9; + uint64_t bypass:1; + uint64_t clkSrc:1; + uint64_t preDivP:6; + uint64_t fbkDivM:9; + uint64_t pstDivS:6; + uint64_t biuDiv4HiVol:3; + uint64_t biuDiv4LoVol:3; + uint64_t dvmrMaxWgt:7; + uint64_t iexrfCfgWrData:2; + uint64_t iexrfCfgWrIdxa:2; + uint64_t iexrfCfgWrIdxb:2; + uint64_t exrfCfgWrIdxmuxsel:2; + uint64_t nrgAccScaleTab:8; + uint64_t lkgEstTab:8; + uint64_t dpe0DvfmTab:8; + }; + struct { + uint64_t voltage_index:9; + uint64_t bypass:1; + uint64_t clkSrc:1; + uint64_t preDivP:6; + uint64_t fbkDivM:9; + uint64_t pstDivS:6; + } gpu; + struct { + uint64_t chipid_max:9; // must contains CHIPID_MAX + uint64_t chip_id:16; + uint64_t voltage_type:3; + uint64_t chip_rev:16; + uint64_t reserved:18; + }; + }; +}; +extern const struct operating_point_params *operating_point_get_params(enum chipid_voltage_index voltage_index, enum chipid_voltage_type voltage_type); + + + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/s8000/include/platform/soc/pmgr.h b/platform/s8000/include/platform/soc/pmgr.h new file mode 100644 index 0000000..c187b4f --- /dev/null +++ b/platform/s8000/include/platform/soc/pmgr.h @@ -0,0 +1,690 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(acc) +#include SUB_PLATFORM_SPDS_HEADER(minipmgr) +#include SUB_PLATFORM_SPDS_HEADER(pmgr) + +//////////////////////////////////////////////////////////// +// +// PMGR specific +// +//////////////////////////////////////////////////////////// + +#define PMGR_BINNING_GROUP_N69 (0x1) +#define PMGR_BINNING_GROUP_J111 (0x2) + +#define PMGR_BINNING_GROUP_N69U (0x1) + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +#define PMGR_PLL_COUNT (7) +#elif SUB_PLATFORM_S8001 +#define PMGR_PLL_COUNT (9) +#endif + +#define PMGR_PLL_REG_STRIDE (PMGR_PLL1_OFFSET - PMGR_PLL0_OFFSET) + +#define rPMGR_PLL_CTL(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define PMGR_PLL_ENABLE (1 << PMGR_PLL0_CTL_ENABLE_SHIFT) +#define PMGR_PLL_LOAD (1 << PMGR_PLL0_CTL_LOAD_SHIFT) +#define PMGR_PLL_BYPASS (1 << PMGR_PLL0_CTL_BYPASS_SHIFT) +#define PMGR_PLL_PENDING (1 << PMGR_PLL0_CTL_PLL_PENDING_SHIFT) +#define PMGR_PLL_M_SHIFT PMGR_PLL0_CTL_FB_DIVN_SHIFT +#define PMGR_PLL_M_MASK PMGR_PLL0_CTL_FB_DIVN_SMASK +#define PMGR_PLL_P_SHIFT PMGR_PLL0_CTL_PRE_DIVN_SHIFT +#define PMGR_PLL_P_MASK PMGR_PLL0_CTL_PRE_DIVN_SMASK +#define PMGR_PLL_S_SHIFT PMGR_PLL0_CTL_OP_DIVN_SHIFT +#define PMGR_PLL_S_MASK PMGR_PLL0_CTL_OP_DIVN_SMASK +#define PMGR_PLL_PCIE_S_MASK PMGR_PLL_PCIE_CTL_OP_DIVN_SMASK +#define PMGR_PLL_M(_m) (((_m) & PMGR_PLL_M_MASK) << PMGR_PLL_M_SHIFT) +#define PMGR_PLL_P(_p) (((_p) & PMGR_PLL_P_MASK) << PMGR_PLL_P_SHIFT) +#define PMGR_PLL_S(_s) (((_s) & PMGR_PLL_S_MASK) << PMGR_PLL_S_SHIFT) +#define PMGR_PLL_PCIE_S(_s) (((_s) & PMGR_PLL_PCIE_S_MASK) << PMGR_PLL_S_SHIFT) +#define PMGR_PLL_FREQ(_m, _p, _s) ((((_m) * OSC_FREQ) / (_p))/((_s) + 1)) + +#define rPMGR_PLL_CFG(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0004 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define PMGR_PLL_OFF_MODE(_n) PMGR_PLL0_CFG_OFF_MODE_INSRT(_n) +#define PMGR_PLL_OFF_MODE_RESET (0) +#define PMGR_PLL_OFF_MODE_CLOCK_GATED (1) +#define PMGR_PLL_OFF_MODE_POWER_DOWN (2) +#define PMGR_PLL_LOCK_MODE(_n) PMGR_PLL0_CFG_LOCK_MODE_INSRT(_n) +#define PMGR_PLL_LOCK_MODE_COUNTER (0) +#define PMGR_PLL_LOCK_MODE_LOCK (1) +#define PMGR_PLL_AUTO_DISABLE (1 << PMGR_PLL0_CFG_AUTO_DISABLE_SHIFT) +#define PMGR_PLL_RELOCK_MODE_SHIFT PMGR_PLL0_CFG_RELOCK_MODE_SHIFT +#define PMGR_PLL_RELOCK_MODE_MASK PMGR_PLL0_CFG_RELOCK_MODE_SMASK +#define PMGR_PLL_RELOCK_MODE_STOP (0) +#define PMGR_PLL_RELOCK_MODE_BYPASS (1) +#define PMGR_PLL_FRAC_LOCK_TIME(_n) PMGR_PLL0_CFG_FRAC_LOCK_TIME_INSRT(_n) +#define PMGR_PLL_LOCK_TIME(_n) PMGR_PLL0_CFG_LOCK_TIME_INSRT(_n) + +#define rPMGR_PLL_ANA_PARAMS1(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x000c + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define rPMGR_PLL_ANA_PARAMS2(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0010 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define rPMGR_PLL_ANA_PARAMS3(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0014 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) + +#define rPMGR_PLL_DEBUG1(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0014 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define PMGR_PLL_DEBUG1_RESERVE_IN_SHIFT (20) +#define PMGR_PLL_DEBUG1_RESERVE_IN_MASK (0x3f) + +#define rPMGR_PLL_PCIE_DELAY_CTL0(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0028 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) + +#define rPMGR_CLK_CFG(_x) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_CLKCFG_##_x##_CLK_CFG_OFFSET)) + +#define PMGR_CLK_CFG_ENABLE (1 << 31) +#define PMGR_CLK_CFG_PENDING (1 << 30) +#define PMGR_CLK_CFG_PENDING_SHIFT (30) +#define PMGR_CLK_CFG_SRC_SEL_MASK (0xF) +#define PMGR_CLK_CFG_SRC_SEL_SHIFT (24) +#define PMGR_CLK_CFG_DIVISOR_MASK (0x3F) +#define PMGR_CLK_CFG_WAIT_COUNTER_UMASK (0xf00000) + +#define PMGR_SPARE_COUNT (6) + +#define rPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_CLKCFG_CLK_DIVIDER_ACG_CFG_OFFSET)) + +#define PMGR_NCO_REG_STRIDE (PMGR_NCO_1_CLK_CFG_OFFSET - PMGR_NCO_0_CLK_CFG_OFFSET) + +#define rPMGR_NCO_CLK_CFG(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_CLK_CFG_OFFSET)) +#define rPMGR_NCO_DIV_INT(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_INT_OFFSET)) +#define rPMGR_NCO_DIV_FRAC_N1(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_FRAC_N1_OFFSET)) +#define rPMGR_NCO_DIV_FRAC_N2(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_FRAC_N2_OFFSET)) +#define rPMGR_NCO_DIV_FRAC_PRIME(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_FRAC_PRIME_OFFSET)) + +#define PMGR_NCO_CLK_CFG_ENABLE (1 << PMGR_NCO_0_CLK_CFG_ENABLE_SHIFT) +#define PMGR_NCO_CLK_CFG_PENDING (1 << PMGR_NCO_0_CLK_CFG_PENDING_SHIFT) + +#define PMGR_NUM_NCO 5 + +#define kSOC_PERF_STATE_BYPASS (0) +#define kSOC_PERF_STATE_SECUREROM (kSOC_PERF_STATE_BYPASS + 1) +#define kSOC_PERF_STATE_IBOOT (kSOC_PERF_STATE_BYPASS + 2) +#define kSOC_PERF_STATE_VMIN (kSOC_PERF_STATE_IBOOT + 0) +#define kSOC_PERF_STATE_VNOM (kSOC_PERF_STATE_IBOOT + 1) + +#define kSOC_PERF_STATE_VMAX (kSOC_PERF_STATE_VNOM) + +#define kSOC_PERF_STATE_IBOOT_CNT (kSOC_PERF_STATE_VMAX + 1) +#define kSOC_PERF_STATE_MAX_CNT (14) + +#define rPMGR_SOC_PERF_STATE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_CTL_OFFSET)) +#define PMGR_SOC_PERF_STATE_CTL_PENDING_MASK (1 << PMGR_SOC_PERF_STATE_CTL_PENDING_SHIFT) + +#define PMGR_SOC_PERF_STATE_STRIDE (PMGR_SOC_PERF_STATE_ENTRY_1A_OFFSET - PMGR_SOC_PERF_STATE_ENTRY_0A_OFFSET) + +#define rPMGR_SOC_PERF_STATE_ENTRY_A(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0A_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) +#define rPMGR_SOC_PERF_STATE_ENTRY_B(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0B_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) +#define rPMGR_SOC_PERF_STATE_ENTRY_C(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0C_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) +#define rPMGR_SOC_PERF_STATE_ENTRY_D(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0D_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) + +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK (PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_UMASK | PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_UMASK) +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(_cfg, _src) (PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_INSRT(_cfg) | PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_INSRT(_src)) +#define PMGR_SOC_PERF_STATE_ENTRY_VID0(_src) (PMGR_SOC_PERF_STATE_ENTRY_0B_VID0_SRC_SEL_INSRT(_src)) +#define PMGR_SOC_PERF_STATE_ENTRY_VOLTAGE(_v) (PMGR_SOC_PERF_STATE_ENTRY_0C_VOLTAGE_INSRT(_v)) + +#define PMGR_SOC_PERF_STATE_ENTRY_COUNT (16) +// First two entries used by AOP Config Engine +#define PMGR_SOC_PERF_STATE_FIRST_ENTRY (PMGR_SOC_PERF_STATE_ENTRY_COUNT - kSOC_PERF_STATE_MAX_CNT) +#define PMGR_SOC_PERF_STATE_TO_ENTRY(_s) (PMGR_SOC_PERF_STATE_ENTRY_COUNT - (_s) - 1) + +#define kPMGR_GFX_STATE_MAX (16) +#define rPMGR_GFX_PERF_STATE_ENTRY_A(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + PMGR_GFX_PERF_STATE_ENTRY0A_OFFSET)) +#define rPMGR_GFX_PERF_STATE_ENTRY_B(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + PMGR_GFX_PERF_STATE_ENTRY0B_OFFSET)) +#define rPMGR_GFX_PERF_STATE_ENTRY_C(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + PMGR_GFX_PERF_STATE_ENTRY0C_OFFSET)) +#define rPMGR_GFX_PERF_STATE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_GFX_PERF_STATE_CTL_OFFSET)) +#define PMGR_GFX_PERF_STATE_CTL_ENABLE (1 << PMGR_GFX_PERF_STATE_CTL_ENABLE_SHIFT) +#define rPMGR_GFX_PERF_STATE_SOCHOT (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_GFX_PERF_STATE_SOCHOT_OFFSET)) + +#define rPMGR_PS(_x) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_PS_##_x##_PS_OFFSET)) + +#define PMGR_PS_RESET (1 << 31) +#define PMGR_PS_AUTO_PM_EN (1 << 28) +#define PMGR_PS_FORCE_NOACCESS (1 << 10) +#define PMGR_PS_ACTUAL_PS_SHIFT (4) +#define PMGR_PS_ACTUAL_PS_MASK (0xF) +#define PMGR_PS_MANUAL_PS_MASK (0xF) +#define PMGR_PS_RUN_MAX (0xF) +#define PMGR_PS_CLOCK_OFF (0x4) +#define PMGR_PS_POWER_OFF (0x0) + +#define rPMGR_PWRGATE_MCC_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_MCC_CFG0_OFFSET)) +#define rPMGR_PWRGATE_MCC_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_MCC_CFG1_OFFSET)) +#define rPMGR_PWRGATE_MCC_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_MCC_CFG2_OFFSET)) +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +#define rPMGR_PWRGATE_DCS01_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS01_CFG0_OFFSET)) +#define rPMGR_PWRGATE_DCS01_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS01_CFG1_OFFSET)) +#define rPMGR_PWRGATE_DCS01_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS01_CFG2_OFFSET)) +#define rPMGR_PWRGATE_DCS23_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS23_CFG0_OFFSET)) +#define rPMGR_PWRGATE_DCS23_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS23_CFG1_OFFSET)) +#define rPMGR_PWRGATE_DCS23_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS23_CFG2_OFFSET)) +#elif SUB_PLATFORM_S8001 +#define rPMGR_PWRGATE_DCS0123_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS0123_CFG0_OFFSET)) +#define rPMGR_PWRGATE_DCS0123_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS0123_CFG1_OFFSET)) +#define rPMGR_PWRGATE_DCS0123_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS0123_CFG2_OFFSET)) +#define rPMGR_PWRGATE_DCS4567_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS4567_CFG0_OFFSET)) +#define rPMGR_PWRGATE_DCS4567_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS4567_CFG1_OFFSET)) +#define rPMGR_PWRGATE_DCS4567_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_DCS4567_CFG2_OFFSET)) +#endif +#define rPMGR_PWRGATE_ACS_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_ACS_CFG0_OFFSET)) +#define rPMGR_PWRGATE_ACS_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_ACS_CFG1_OFFSET)) +#define rPMGR_PWRGATE_ACS_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PWRGATE_PWR_ACS_CFG2_OFFSET)) + +#define rPMGR_VOLMAN_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CTL_OFFSET)) +#define rPMGR_VOLMAN_BUCK_MAP (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_BUCK_MAP_OFFSET)) +#define rPMGR_VOLMAN_SOC_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_SOC_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_GFX_SRAM_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_SRAM_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_CPU_SRAM_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_SRAM_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_GFX_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_CPU_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_SOC_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_SOC_DELAY_OFFSET)) +#define rPMGR_VOLMAN_GFX_SRAM_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_SRAM_DELAY_OFFSET)) +#define rPMGR_VOLMAN_CPU_SRAM_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_SRAM_DELAY_OFFSET)) +#define rPMGR_VOLMAN_GFX_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_DELAY_OFFSET)) +#define rPMGR_VOLMAN_CPU_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_DELAY_OFFSET)) + +#define PMGR_VOLMAN_DISABLE_CPU_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_CPU_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_GFX_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_GFX_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_CPU_SRAM_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_CPU_SRAM_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_GFX_SRAM_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_GFX_SRAM_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_SOC_VOL_CHANGE_SHIFT) + +#define PMGR_VOLMAN_VOLTAGE_PENDING (1 << 31) + +#define rPMGR_EMA_FIXED_SOC0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_SOC0_OFFSET)) +#define rPMGR_EMA_FIXED_SOC1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_SOC1_OFFSET)) +#define rPMGR_EMA_GPU_SRAM_GFX (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_GPU_SRAM_GFX_OFFSET)) +#define rPMGR_EMA_FIXED_GFX (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_FIXED_GFX_OFFSET)) +#define rPMGR_EMA_FIXED_SEP0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_FIXED_SEP0_OFFSET)) + +#define rPMGR_SCRATCH(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SCRATCH_0_OFFSET + ((_n)*4))) +#define rPMGR_SCRATCH0 rPMGR_SCRATCH(0) /* Flags */ +#define rPMGR_SCRATCH1 rPMGR_SCRATCH(1) +#define rPMGR_SCRATCH2 rPMGR_SCRATCH(2) +#define rPMGR_SCRATCH3 rPMGR_SCRATCH(3) +#define rPMGR_SCRATCH4 rPMGR_SCRATCH(4) +#define rPMGR_SCRATCH5 rPMGR_SCRATCH(5) +#define rPMGR_SCRATCH6 rPMGR_SCRATCH(6) +#define rPMGR_SCRATCH7 rPMGR_SCRATCH(7) +#define rPMGR_SCRATCH8 rPMGR_SCRATCH(8) +#define rPMGR_SCRATCH9 rPMGR_SCRATCH(9) +#define rPMGR_SCRATCH10 rPMGR_SCRATCH(10) +#define rPMGR_SCRATCH11 rPMGR_SCRATCH(11) +#define rPMGR_SCRATCH12 rPMGR_SCRATCH(12) +#define rPMGR_SCRATCH13 rPMGR_SCRATCH(13) /* Memory info */ +#define rPMGR_SCRATCH14 rPMGR_SCRATCH(14) /* Boot Nonce 0 */ +#define rPMGR_SCRATCH15 rPMGR_SCRATCH(15) /* Boot Nonce 1 */ +#define rPMGR_SCRATCH16 rPMGR_SCRATCH(16) /* Boot Manifest Hash 0 */ +#define rPMGR_SCRATCH17 rPMGR_SCRATCH(17) /* Boot Manifest Hash 1 */ +#define rPMGR_SCRATCH18 rPMGR_SCRATCH(18) /* Boot Manifest Hash 2 */ +#define rPMGR_SCRATCH19 rPMGR_SCRATCH(19) /* Boot Manifest Hash 3 */ +#define rPMGR_SCRATCH20 rPMGR_SCRATCH(20) /* Boot Manifest Hash 4 */ +#define rPMGR_SCRATCH21 rPMGR_SCRATCH(21) +#define rPMGR_SCRATCH22 rPMGR_SCRATCH(22) +#define rPMGR_SCRATCH23 rPMGR_SCRATCH(23) + +#define rMINIPMGR_SCRATCH(_n) (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_SCRATCH_OFFSET + ((_n)*4))) +#define rMINIPMGR_SCRATCH0 rMINIPMGR_SCRATCH(0) +#define rMINIPMGR_SCRATCH1 rMINIPMGR_SCRATCH(1) /* Consistent debug root pointer */ +#define rMINIPMGR_SCRATCH2 rMINIPMGR_SCRATCH(2) +#define rMINIPMGR_SCRATCH3 rMINIPMGR_SCRATCH(3) +#define rMINIPMGR_SCRATCH4 rMINIPMGR_SCRATCH(4) +#define rMINIPMGR_SCRATCH5 rMINIPMGR_SCRATCH(5) +#define rMINIPMGR_SCRATCH6 rMINIPMGR_SCRATCH(6) +#define rMINIPMGR_SCRATCH7 rMINIPMGR_SCRATCH(7) +#define rMINIPMGR_SCRATCH8 rMINIPMGR_SCRATCH(8) +#define rMINIPMGR_SCRATCH9 rMINIPMGR_SCRATCH(9) +#define rMINIPMGR_SCRATCH10 rMINIPMGR_SCRATCH(10) +#define rMINIPMGR_SCRATCH11 rMINIPMGR_SCRATCH(11) /* Reconfig sequence debug */ + + +#define PMGR_THERMAL0_CTL0_SET (PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL0_SET_OFFSET) +#define PMGR_THERMAL0_CTL0_CLR (PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL0_CLR_OFFSET) +#define PMGR_THERMAL0_CTL1 (PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL1_OFFSET) +#define PMGR_THERMAL0_CTL2 (PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL2_OFFSET) +#define PMGR_THERMAL0_STATUS (PMGR_BASE_ADDR + PMGR_THERMAL_0_STATUS_OFFSET) +#define PMGR_THERMAL0_PARAM (PMGR_BASE_ADDR + PMGR_THERMAL_0_PARAM_OFFSET) +#define PMGR_THERMAL0_RDBK0 (PMGR_BASE_ADDR + PMGR_THERMAL_0_RDBK0_OFFSET) +#define PMGR_THERMAL0_RDBK1 (PMGR_BASE_ADDR + PMGR_THERMAL_0_RDBK1_OFFSET) +#define PMGR_THERMAL0_SUM (PMGR_BASE_ADDR + PMGR_THERMAL_0_SUM_OFFSET) +#define PMGR_THERMAL0_SUM_CNT (PMGR_BASE_ADDR + PMGR_THERMAL_0_SUM_CNT_OFFSET) +#define PMGR_THERMAL0_PIECE0 (PMGR_BASE_ADDR + PMGR_THERMAL_0_PIECE0_OFFSET) +#define PMGR_THERMAL0_PIECE1 (PMGR_BASE_ADDR + PMGR_THERMAL_0_PIECE1_OFFSET) +#define PMGR_THERMAL0_PIECE2 (PMGR_BASE_ADDR + PMGR_THERMAL_0_PIECE2_OFFSET) +#define PMGR_THERMAL0_ALARM0 (PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM0_OFFSET) +#define PMGR_THERMAL0_ALARM1 (PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM1_OFFSET) +#define PMGR_THERMAL0_ALARM2 (PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM2_OFFSET) +#define PMGR_THERMAL0_ALARM3 (PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM3_OFFSET) +#define PMGR_THERMAL0_FAILSAFE_TRIP_TEMP_0 (PMGR_BASE_ADDR + PMGR_THERMAL_0_FAILSAFE_TRIP_TEMP_0_OFFSET) +#define PMGR_THERMAL0_FAILSAFE_TRIP_TEMP_1 (PMGR_BASE_ADDR + PMGR_THERMAL_0_FAILSAFE_TRIP_TEMP_1_OFFSET) +#define PMGR_THERMAL1_CTL0_SET (PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL0_SET_OFFSET) +#define PMGR_THERMAL1_CTL0_CLR (PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL0_CLR_OFFSET) +#define PMGR_THERMAL1_CTL1 (PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL1_OFFSET) +#define PMGR_THERMAL1_CTL2 (PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL2_OFFSET) +#define PMGR_THERMAL1_STATUS (PMGR_BASE_ADDR + PMGR_THERMAL_1_STATUS_OFFSET) +#define PMGR_THERMAL1_PARAM (PMGR_BASE_ADDR + PMGR_THERMAL_1_PARAM_OFFSET) +#define PMGR_THERMAL1_RDBK0 (PMGR_BASE_ADDR + PMGR_THERMAL_1_RDBK0_OFFSET) +#define PMGR_THERMAL1_RDBK1 (PMGR_BASE_ADDR + PMGR_THERMAL_1_RDBK1_OFFSET) +#define PMGR_THERMAL1_SUM (PMGR_BASE_ADDR + PMGR_THERMAL_1_SUM_OFFSET) +#define PMGR_THERMAL1_SUM_CNT (PMGR_BASE_ADDR + PMGR_THERMAL_1_SUM_CNT_OFFSET) +#define PMGR_THERMAL1_PIECE0 (PMGR_BASE_ADDR + PMGR_THERMAL_1_PIECE0_OFFSET) +#define PMGR_THERMAL1_PIECE1 (PMGR_BASE_ADDR + PMGR_THERMAL_1_PIECE1_OFFSET) +#define PMGR_THERMAL1_PIECE2 (PMGR_BASE_ADDR + PMGR_THERMAL_1_PIECE2_OFFSET) +#define PMGR_THERMAL1_ALARM0 (PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM0_OFFSET) +#define PMGR_THERMAL1_ALARM1 (PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM1_OFFSET) +#define PMGR_THERMAL1_ALARM2 (PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM2_OFFSET) +#define PMGR_THERMAL1_ALARM3 (PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM3_OFFSET) +#define PMGR_THERMAL1_FAILSAFE_TRIP_TEMP_0 (PMGR_BASE_ADDR + PMGR_THERMAL_1_FAILSAFE_TRIP_TEMP_0_OFFSET) +#define PMGR_THERMAL1_FAILSAFE_TRIP_TEMP_1 (PMGR_BASE_ADDR + PMGR_THERMAL_1_FAILSAFE_TRIP_TEMP_1_OFFSET) +#define PMGR_THERMAL2_CTL0_SET (PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL0_SET_OFFSET) +#define PMGR_THERMAL2_CTL0_CLR (PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL0_CLR_OFFSET) +#define PMGR_THERMAL2_CTL1 (PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL1_OFFSET) +#define PMGR_THERMAL2_CTL2 (PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL2_OFFSET) +#define PMGR_THERMAL2_STATUS (PMGR_BASE_ADDR + PMGR_THERMAL_2_STATUS_OFFSET) +#define PMGR_THERMAL2_PARAM (PMGR_BASE_ADDR + PMGR_THERMAL_2_PARAM_OFFSET) +#define PMGR_THERMAL2_RDBK0 (PMGR_BASE_ADDR + PMGR_THERMAL_2_RDBK0_OFFSET) +#define PMGR_THERMAL2_RDBK1 (PMGR_BASE_ADDR + PMGR_THERMAL_2_RDBK1_OFFSET) +#define PMGR_THERMAL2_SUM (PMGR_BASE_ADDR + PMGR_THERMAL_2_SUM_OFFSET) +#define PMGR_THERMAL2_SUM_CNT (PMGR_BASE_ADDR + PMGR_THERMAL_2_SUM_CNT_OFFSET) +#define PMGR_THERMAL2_PIECE0 (PMGR_BASE_ADDR + PMGR_THERMAL_2_PIECE0_OFFSET) +#define PMGR_THERMAL2_PIECE1 (PMGR_BASE_ADDR + PMGR_THERMAL_2_PIECE1_OFFSET) +#define PMGR_THERMAL2_PIECE2 (PMGR_BASE_ADDR + PMGR_THERMAL_2_PIECE2_OFFSET) +#define PMGR_THERMAL2_ALARM0 (PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM0_OFFSET) +#define PMGR_THERMAL2_ALARM1 (PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM1_OFFSET) +#define PMGR_THERMAL2_ALARM2 (PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM2_OFFSET) +#define PMGR_THERMAL2_ALARM3 (PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM3_OFFSET) +#define PMGR_THERMAL2_FAILSAFE_TRIP_TEMP_0 (PMGR_BASE_ADDR + PMGR_THERMAL_2_FAILSAFE_TRIP_TEMP_0_OFFSET) +#define PMGR_THERMAL2_FAILSAFE_TRIP_TEMP_1 (PMGR_BASE_ADDR + PMGR_THERMAL_2_FAILSAFE_TRIP_TEMP_1_OFFSET) +#if SUB_PLATFORM_S8001 +#define PMGR_THERMAL3_CTL0_SET (PMGR_BASE_ADDR + PMGR_THERMAL_3_CTL0_SET_OFFSET) +#define PMGR_THERMAL3_CTL0_CLR (PMGR_BASE_ADDR + PMGR_THERMAL_3_CTL0_CLR_OFFSET) +#define PMGR_THERMAL3_CTL1 (PMGR_BASE_ADDR + PMGR_THERMAL_3_CTL1_OFFSET) +#define PMGR_THERMAL3_CTL2 (PMGR_BASE_ADDR + PMGR_THERMAL_3_CTL2_OFFSET) +#define PMGR_THERMAL3_STATUS (PMGR_BASE_ADDR + PMGR_THERMAL_3_STATUS_OFFSET) +#define PMGR_THERMAL3_PARAM (PMGR_BASE_ADDR + PMGR_THERMAL_3_PARAM_OFFSET) +#define PMGR_THERMAL3_RDBK0 (PMGR_BASE_ADDR + PMGR_THERMAL_3_RDBK0_OFFSET) +#define PMGR_THERMAL3_RDBK1 (PMGR_BASE_ADDR + PMGR_THERMAL_3_RDBK1_OFFSET) +#define PMGR_THERMAL3_SUM (PMGR_BASE_ADDR + PMGR_THERMAL_3_SUM_OFFSET) +#define PMGR_THERMAL3_SUM_CNT (PMGR_BASE_ADDR + PMGR_THERMAL_3_SUM_CNT_OFFSET) +#define PMGR_THERMAL3_PIECE0 (PMGR_BASE_ADDR + PMGR_THERMAL_3_PIECE0_OFFSET) +#define PMGR_THERMAL3_PIECE1 (PMGR_BASE_ADDR + PMGR_THERMAL_3_PIECE1_OFFSET) +#define PMGR_THERMAL3_PIECE2 (PMGR_BASE_ADDR + PMGR_THERMAL_3_PIECE2_OFFSET) +#define PMGR_THERMAL3_ALARM0 (PMGR_BASE_ADDR + PMGR_THERMAL_3_ALARM0_OFFSET) +#define PMGR_THERMAL3_ALARM1 (PMGR_BASE_ADDR + PMGR_THERMAL_3_ALARM1_OFFSET) +#define PMGR_THERMAL3_ALARM2 (PMGR_BASE_ADDR + PMGR_THERMAL_3_ALARM2_OFFSET) +#define PMGR_THERMAL3_ALARM3 (PMGR_BASE_ADDR + PMGR_THERMAL_3_ALARM3_OFFSET) +#define PMGR_THERMAL3_FAILSAFE_TRIP_TEMP_0 (PMGR_BASE_ADDR + PMGR_THERMAL_3_FAILSAFE_TRIP_TEMP_0_OFFSET) +#define PMGR_THERMAL3_FAILSAFE_TRIP_TEMP_1 (PMGR_BASE_ADDR + PMGR_THERMAL_3_FAILSAFE_TRIP_TEMP_1_OFFSET) +#endif + +#define rPMGR_THERMAL0_PARAM (*(volatile u_int32_t *)PMGR_THERMAL0_PARAM) +#define rPMGR_THERMAL1_PARAM (*(volatile u_int32_t *)PMGR_THERMAL1_PARAM) +#define rPMGR_THERMAL2_PARAM (*(volatile u_int32_t *)PMGR_THERMAL2_PARAM) +#if SUB_PLATFORM_S8001 +#define rPMGR_THERMAL3_PARAM (*(volatile u_int32_t *)PMGR_THERMAL3_PARAM) +#endif + +#define rPMGR_SOC_TVM_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_CTL_OFFSET)) +#define rPMGR_SOC_TVM_THRESH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH0_OFFSET)) +#define rPMGR_SOC_TVM_THRESH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH1_OFFSET)) +#define rPMGR_SOC_TVM_THRESH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH2_OFFSET)) +#define rPMGR_SOC_TVM_TEMP0_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP0_CFG_OFFSET)) +#define rPMGR_SOC_TVM_TEMP1_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP1_CFG_OFFSET)) +#define rPMGR_SOC_TVM_DEBUG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG0_OFFSET)) +#define rPMGR_SOC_TVM_DEBUG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG1_OFFSET)) +#define rPMGR_SOC_TVM_DEBUG2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG2_OFFSET)) + +#define rPMGR_GFX_TVM_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_CTL_OFFSET)) +#define rPMGR_GFX_TVM_THRESH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH0_OFFSET)) +#define rPMGR_GFX_TVM_THRESH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH1_OFFSET)) +#define rPMGR_GFX_TVM_THRESH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH2_OFFSET)) +#define rPMGR_GFX_TVM_TEMP0_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP0_CFG_OFFSET)) +#define rPMGR_GFX_TVM_TEMP1_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP1_CFG_OFFSET)) +#define rPMGR_GFX_TVM_DEBUG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG0_OFFSET)) +#define rPMGR_GFX_TVM_DEBUG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG1_OFFSET)) +#define rPMGR_GFX_TVM_DEBUG2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG2_OFFSET)) + +#define PMGR_TVM_THRESH(_t) ((_t) & 0x1FF) +#define PMGR_TVM_TEMP_CFG_MAX_OFFSET(_mo) (((_mo) & 0x1FF) << 16) +#define PMGR_TVM_TEMP_CFG_MIN_OFFSET(_mo) (((_mo) & 0x1FF) << 0) + +#define rPMGR_MISC_CFG_ACG (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_MISC_CFG_ACG_OFFSET)) +#define rPMGR_MISC_PCIE_PCIE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_MISC_PCIE_PCIE_CTL_OFFSET)) + +#define rPMGR_MISC_SPARE0 (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_MISC_SPARE_SPARE0_OFFSET)) + +#define rPMGR_DEBUG_PMGR_DEBUG17 (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_DEBUG_17_OFFSET)) + +#define rPMGR_CHIP_WDOG_TMR (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER_OFFSET)) +#define rPMGR_CHIP_WDOG_RST_CNT (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_RESET_COUNT_OFFSET)) +#define rPMGR_CHIP_WDOG_INTR_CNT (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_INTERRUPT_COUNT_OFFSET)) +#define rPMGR_CHIP_WDOG_CTL (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_CONTROL_OFFSET)) +#define rPMGR_SYS_WDOG_TMR (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER_OFFSET)) +#define rPMGR_SYS_WDOG_RST_CNT (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_RESET_COUNT_OFFSET)) +#define rPMGR_SYS_WDOG_CTL (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_CONTROL_OFFSET)) + +#define rMINIPMGR_LPO_CTL (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_LPO_CTL_OFFSET)) +#define MINIPMGR_LPO_CTL_ENABLE (1 << MINIPMGR_LPO_CTL_ENABLE_SHIFT) +#define MINIPMGR_LPO_CTL_PENDING (1 << MINIPMGR_LPO_CTL_PENDING_SHIFT) +#define rMINIPMGR_LPO_CFG (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_LPO_CFG_OFFSET)) + +#define rMINIPMGR_CLK_CFG(_x) (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_##_x##_CLK_CFG_OFFSET)) +#define rMINIPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_CLK_DIVIDER_ACG_CFG_OFFSET)) + +#define rMINIPMGR_PS(_x) (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_PS_##_x##_PS_OFFSET)) + +#define rMINIPMGR_MISC_CFG_ACG (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET)) + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +enum { + PMGR_CLK_OSC = 0, // 0x00 + PMGR_CLK_PLL0, // 0x01 + PMGR_CLK_PLL1, // 0x02 + PMGR_CLK_PLL2, // 0x03 + PMGR_CLK_PLL3, // 0x04 + PMGR_CLK_PLL4, // 0x05 + PMGR_CLK_PLL5, // 0x06 + PMGR_CLK_PLL_PCIE, // 0x07 + PMGR_CLK_CPU, // 0x08 + PMGR_CLK_GFX_FENDER, // 0x09 + PMGR_CLK_FIRST = PMGR_CLK_GFX_FENDER, + PMGR_CLK_MCU_REF, // 0x0A + PMGR_CLK_PMP, // 0x0B + PMGR_CLK_TEMP_MIPI_DSI, // 0x0C + PMGR_CLK_NCO_REF0, // 0x0D + PMGR_CLK_NCO_REF1, // 0x0E + PMGR_CLK_NCO_ALG0, // 0x0F + PMGR_CLK_NCO_ALG1, // 0x10 + PMGR_CLK_HSICPHY_REF_12M, // 0x11 + PMGR_CLK_USB480_0, // 0x12 + PMGR_CLK_USB480_1, // 0x13 + PMGR_CLK_USB_OHCI_48M, // 0x14 + PMGR_CLK_USB, // 0x15 + PMGR_CLK_USB_FREE_60M, // 0x16 + PMGR_CLK_SIO_C, // 0x17 + PMGR_CLK_SIO_P, // 0x18 + PMGR_CLK_ISP_C, // 0x19 + PMGR_CLK_ISP, // 0x1A + PMGR_CLK_ISP_SENSOR0_REF, // 0x1B + PMGR_CLK_ISP_SENSOR1_REF, // 0x1C + PMGR_CLK_VDEC, // 0x1D + PMGR_CLK_VENC, // 0x1E + PMGR_CLK_VID0, // 0x1F + PMGR_CLK_DISP0, // 0x20 + PMGR_CLK_AJPEG_IP, // 0x21 + PMGR_CLK_AJPEG_WRAP, // 0x22 + PMGR_CLK_MSR, // 0x23 + PMGR_CLK_AF, // 0x24 + PMGR_CLK_SBR, // 0x25 + PMGR_CLK_MCA0_M, // 0x26 + PMGR_CLK_MCA1_M, // 0x27 + PMGR_CLK_MCA2_M, // 0x28 + PMGR_CLK_MCA3_M, // 0x29 + PMGR_CLK_MCA4_M, // 0x2A + PMGR_CLK_SEP, // 0x2B + PMGR_CLK_GPIO, // 0x2C + PMGR_CLK_SPI0_N, // 0x2D + PMGR_CLK_SPI1_N, // 0x2E + PMGR_CLK_SPI2_N, // 0x2F + PMGR_CLK_SPI3_N, // 0x30 + PMGR_CLK_PCIE_APP, // 0x31 + PMGR_CLK_TMPS, // 0x32 + PMGR_CLK_UVD, // 0x33 + PMGR_CLK_LAST = PMGR_CLK_UVD, + PMGR_CLK_S0, // 0x34 + PMGR_CLK_SPARE_FIRST = PMGR_CLK_S0, + PMGR_CLK_S1, // 0x35 + PMGR_CLK_S2, // 0x36 + PMGR_CLK_S3, // 0x37 + PMGR_CLK_ISP_REF0, // 0x38 + PMGR_CLK_ISP_REF1, // 0x39 + PMGR_CLK_SPARE_LAST = PMGR_CLK_ISP_REF1, + PMGR_CLK_LPO, // 0x3A + PMGR_CLK_AOP, // 0x3B + PMGR_CLK_MINI_FIRST = PMGR_CLK_AOP, + PMGR_CLK_UART0, // 0x3C + PMGR_CLK_UART1, // 0x3D + PMGR_CLK_UART2, // 0x3E + PMGR_CLK_AOP_MCA0_M, // 0x3F + PMGR_CLK_I2CM, // 0x40 + PMGR_CLK_PROXY_FABRIC, // 0x41 + PMGR_CLK_PROXY_MCU_REF, // 0x42 + PMGR_CLK_MINI_LAST = PMGR_CLK_PROXY_MCU_REF, + PMGR_CLK_COUNT, // 0x43 + PMGR_CLK_NOT_SUPPORTED +}; + +#elif SUB_PLATFORM_S8001 + +enum { + PMGR_CLK_OSC = 0, // 0x00 + PMGR_CLK_PLL0, // 0x01 + PMGR_CLK_PLL1, // 0x02 + PMGR_CLK_PLL2, // 0x03 + PMGR_CLK_PLL3, // 0x04 + PMGR_CLK_PLL4, // 0x05 + PMGR_CLK_PLL5, // 0x06 + PMGR_CLK_PLL6, // 0x07 + PMGR_CLK_PLL7, // 0x08 + PMGR_CLK_PLL_PCIE, // 0x09 + PMGR_CLK_CPU, // 0x0A + PMGR_CLK_GFX_FENDER, // 0x0B + PMGR_CLK_FIRST = PMGR_CLK_GFX_FENDER, + PMGR_CLK_MCU_REF, // 0x0C + PMGR_CLK_PMP, // 0x0D + PMGR_CLK_NCO_REF0, // 0x0E + PMGR_CLK_NCO_REF1, // 0x0F + PMGR_CLK_NCO_ALG0, // 0x10 + PMGR_CLK_NCO_ALG1, // 0x11 + PMGR_CLK_HSICPHY_REF_12M, // 0x12 + PMGR_CLK_USB480_0, // 0x13 + PMGR_CLK_USB_OHCI_48M, // 0x14 + PMGR_CLK_USB, // 0x15 + PMGR_CLK_USB_FREE_60M, // 0x16 + PMGR_CLK_SIO_C, // 0x17 + PMGR_CLK_SIO_P, // 0x18 + PMGR_CLK_ISP_C, // 0x19 + PMGR_CLK_ISP, // 0x1A + PMGR_CLK_ISP_SENSOR0_REF, // 0x1B + PMGR_CLK_ISP_SENSOR1_REF, // 0x1C + PMGR_CLK_VDEC, // 0x1D + PMGR_CLK_VENC, // 0x1E + PMGR_CLK_VID0, // 0x1F + PMGR_CLK_DISP0, // 0x20 + PMGR_CLK_AJPEG_IP, // 0x21 + PMGR_CLK_AJPEG_WRAP, // 0x22 + PMGR_CLK_MSR, // 0x23 + PMGR_CLK_AF, // 0x24 + PMGR_CLK_SBR, // 0x25 + PMGR_CLK_MCA0_M, // 0x26 + PMGR_CLK_MCA1_M, // 0x27 + PMGR_CLK_MCA2_M, // 0x28 + PMGR_CLK_MCA3_M, // 0x29 + PMGR_CLK_MCA4_M, // 0x2A + PMGR_CLK_SEP, // 0x2B + PMGR_CLK_GPIO, // 0x2C + PMGR_CLK_SPI0_N, // 0x2D + PMGR_CLK_SPI1_N, // 0x2E + PMGR_CLK_SPI2_N, // 0x2F + PMGR_CLK_SPI3_N, // 0x30 + PMGR_CLK_PCIE_APP, // 0x31 + PMGR_CLK_TMPS, // 0x32 + PMGR_CLK_UVD, // 0x33 + PMGR_CLK_VID1, // 0x34 + PMGR_CLK_DISP1, // 0x35 + PMGR_CLK_SRS, // 0x36 + PMGR_CLK_LAST = PMGR_CLK_SRS, + PMGR_CLK_S0, // 0x37 + PMGR_CLK_SPARE_FIRST = PMGR_CLK_S0, + PMGR_CLK_S1, // 0x38 + PMGR_CLK_S2, // 0x39 + PMGR_CLK_S3, // 0x3A + PMGR_CLK_ISP_REF0, // 0x3B + PMGR_CLK_ISP_REF1, // 0x3C + PMGR_CLK_SPARE_LAST = PMGR_CLK_ISP_REF1, + PMGR_CLK_LPO, // 0x3D + PMGR_CLK_AOP, // 0x3E + PMGR_CLK_MINI_FIRST = PMGR_CLK_AOP, + PMGR_CLK_UART0, // 0x3F + PMGR_CLK_UART1, // 0x40 + PMGR_CLK_UART2, // 0x41 + PMGR_CLK_AOP_MCA0_M, // 0x42 + PMGR_CLK_I2CM, // 0x43 + PMGR_CLK_PROXY_FABRIC, // 0x44 + PMGR_CLK_PROXY_MCU_REF, // 0x45 + PMGR_CLK_MINI_LAST = PMGR_CLK_PROXY_MCU_REF, + PMGR_CLK_COUNT, // 0x46 + PMGR_CLK_NOT_SUPPORTED +}; + +#endif + +//////////////////////////////////////////////////////////// +// +// CCC specific +// +//////////////////////////////////////////////////////////// + +#define rACC_PRE_TD_TMR (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PRE_TD_TMR_OFFSET)) +#define rACC_PRE_FLUSH_TMR (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PRE_FLUSH_TMR_OFFSET)) + +#define rACC_APSC_SCR (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_APSC_SCR_OFFSET)) +#define ACC_APSC_PENDING (1 << ACC_PWRCTL_APSC_SCR_MANUAL_PENDING_SHIFT) +#define ACC_APSC_MANUAL_CHANGE(_d) ((1 << ACC_PWRCTL_APSC_SCR_MANUAL_CHANGE_SHIFT) | ACC_PWRCTL_APSC_SCR_MANUAL_ST_INSRT((uint64_t)_d)) + +#define rACC_DVFM_CFG (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_CFG_OFFSET)) + +#define rACC_DVFM_SCR (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_SCR_OFFSET)) // 64-bit +#define ACC_DVFM_SCR_TEMPSENSORMODE (ACC_PWRCTL_DVFM_MODE_INSRT((uint64_t)1)) + +#define rACC_DVFM_CFG_SEL (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_CFG_SEL_OFFSET)) + +#define rACC_DVFM_CFG1 (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_CFG1_OFFSET)) + +#define rACC_MSTR_PLLCTL (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_MSTR_PLLCTL_OFFSET)) + +#define kDVFM_STATE_BYPASS (0) +#define kDVFM_STATE_SECUREROM (kDVFM_STATE_BYPASS + 1) +#define kDVFM_STATE_IBOOT (kDVFM_STATE_BYPASS + 2) +#define kDVFM_STATE_V0 (kDVFM_STATE_IBOOT + 0) +#define kDVFM_STATE_V1 (kDVFM_STATE_IBOOT + 1) +#define kDVFM_STATE_V2 (kDVFM_STATE_IBOOT + 2) +#define kDVFM_STATE_V3 (kDVFM_STATE_IBOOT + 3) +#define kDVFM_STATE_V4 (kDVFM_STATE_IBOOT + 4) +#define kDVFM_STATE_V5 (kDVFM_STATE_IBOOT + 5) +#define kDVFM_STATE_V6 (kDVFM_STATE_IBOOT + 6) + +#define kDVFM_STATE_VMAX (kDVFM_STATE_V6) + +#define kDVFM_STATE_VNOM (kDVFM_STATE_V0) +#define kDVFM_STATE_VBOOST (kDVFM_STATE_VNOM + 1) + +#define kDVFM_STATE_IBOOT_CNT (kDVFM_STATE_VMAX + 1) + +#define kVOLTAGE_STATES1_COUNT (kDVFM_STATE_VMAX - kDVFM_STATE_V0 + 1) +#define kVOLTAGE_STATES1_SIZE (kVOLTAGE_STATES1_COUNT*2) // Minimum size of voltage-state1 property in devicetree + +#define kDVFM_STATE_MAX_CNT (16) + +#define kDVFM_STATE_IBOOT_VCO_WA (kDVFM_STATE_MAX_CNT - 1) +#define kDVFM_STATE_VCO_WA_MAX_CNT (4) + +#define rACC_DVFM_ST(_n) (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_OFFSET + ((_n) < 8 ? ((_n) * 8) : 0x300 + (((_n) - 8) * 8)))) +#define ACC_DVFM_ST_SAFE_VOL(_sv) (ACC_PWRCTL_DVFM_ST0_SAFE_VOL_INSRT((uint64_t)_sv)) +#define ACC_DVFM_ST_VOL_ADJ3(_va) (ACC_PWRCTL_DVFM_ST0_VOL_ADJ3_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_VOL_ADJ2(_va) (ACC_PWRCTL_DVFM_ST0_VOL_ADJ2_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_VOL_ADJ1(_va) (ACC_PWRCTL_DVFM_ST0_VOL_ADJ1_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_VOL_ADJ0(_va) (ACC_PWRCTL_DVFM_ST0_VOL_ADJ0_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_VOL_BYP(_vb) (ACC_PWRCTL_DVFM_ST0_VOL_BYP_INSRT((uint64_t)_vb)) +#define ACC_DVFM_ST_CLK_SRC(_s) (ACC_PWRCTL_DVFM_ST0_CLK_SRC_INSRT((uint64_t)_s)) +#define ACC_DVFM_ST_PLL_P(_p) (ACC_PWRCTL_DVFM_ST0_PRE_DIV_P_INSRT((uint64_t)_p)) +#define ACC_DVFM_ST_PLL_M(_m) (ACC_PWRCTL_DVFM_ST0_FBK_DIV_M_INSRT((uint64_t)_m)) +#define ACC_DVFM_ST_PLL_S(_s) (ACC_PWRCTL_DVFM_ST0_PST_DIV_S_INSRT((uint64_t)_s)) +#define ACC_DVFM_ST_PLL_PMS_MASK (ACC_PWRCTL_DVFM_ST0_PRE_DIV_P_UMASK | ACC_PWRCTL_DVFM_ST0_FBK_DIV_M_UMASK | ACC_PWRCTL_DVFM_ST0_PST_DIV_S_UMASK) + +#define rACC_PLL_SCR1 (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PLL_SCR1_OFFSET)) +#define rACC_PLL_CFG2 (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PLL_CFG2_OFFSET)) +#define rACC_DVMR_SCR (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVMR_SCR_OFFSET)) + +#define rACC_DVFM_ST_EXT(_n) (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_ST0_EXT_OFFSET + ((_n) * 8))) +#define ACC_DVFM_ST_BIU_DIV_HI_VOL(_d) (ACC_PWRCTL_DVFM_ST0_EXT_BIU_DIV4_HI_VOL_INSRT((uint64_t)(_d))) +#define ACC_DVFM_ST_BIU_DIV_LO_VOL(_d) (ACC_PWRCTL_DVFM_ST0_EXT_BIU_DIV4_LO_VOL_INSRT((uint64_t)(_d))) +#define ACC_DVFM_ST_DVMR_MAX_WGT(_w) (ACC_PWRCTL_DVFM_ST0_EXT_DVMR_MAX_WGT_INSRT((uint64_t)(_w))) +#define ACC_DVFM_ST_SRAM_VOL(_v) (ACC_PWRCTL_DVFM_ST0_EXT_SRAM_VOL_INSRT((uint64_t)(_v))) +#define ACC_DVFM_ST_DVFM_MAX_ADJ(_a) (ACC_PWRCTL_DVFM_ST0_EXT_DVFM_MAX_ADJ_INSRT((uint64_t)(_a))) +#define ACC_DVFM_ST_DVMR_ADJ2(_a) (ACC_PWRCTL_DVFM_ST0_EXT_DVMR_ADJ2_INSRT((uint64_t)(_a))) +#define ACC_DVFM_ST_DVMR_ADJ1(_a) (ACC_PWRCTL_DVFM_ST0_EXT_DVMR_ADJ1_INSRT((uint64_t)(_a))) +#define ACC_DVFM_ST_DVMR_ADJ0(_a) (ACC_PWRCTL_DVFM_ST0_EXT_DVMR_ADJ0_INSRT((uint64_t)(_a))) + +#define rACC_NRG_ACC_SCALE_TAB (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_NRG_ACC_SCALE_TAB_OFFSET)) +#define rACC_NRG_ACC_SCALE_TAB_EXT (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_NRG_ACC_SCALE_TAB_EXT_OFFSET)) +#define rACC_LKG_EST_TAB (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_LKG_EST_TAB_OFFSET)) +#define rACC_LKG_EST_TAB_EXT (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_LKG_EST_TAB_EXT_OFFSET)) +#define rACC_DPE0_DVFM_TAB (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DPE0_DVFM_TAB_OFFSET)) +#define rACC_DPE0_DVFM_TAB_EXT (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DPE0_DVFM_TAB_EXT_OFFSET)) + +#define rPMGR_SECURITY (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + 0xD0000)) + +#define ACC_THRM0_CTL0_SET (ACC_BASE_ADDR + ACC_THERMAL_THRM0_CTL0_SET_OFFSET) +#define ACC_THRM0_CTL0_CLR (ACC_BASE_ADDR + ACC_THERMAL_THRM0_CTL0_CLR_OFFSET) +#define ACC_THRM0_CTL1 (ACC_BASE_ADDR + ACC_THERMAL_THRM0_CTL1_OFFSET) +#define ACC_THRM0_PARAM (ACC_BASE_ADDR + ACC_THERMAL_THRM0_PARAM_OFFSET) +#define ACC_THRM0_PIECE0 (ACC_BASE_ADDR + ACC_THERMAL_THRM0_PIECE0_OFFSET) +#define ACC_THRM0_PIECE1 (ACC_BASE_ADDR + ACC_THERMAL_THRM0_PIECE1_OFFSET) +#define ACC_THRM0_PIECE2 (ACC_BASE_ADDR + ACC_THERMAL_THRM0_PIECE2_OFFSET) + +#define ACC_THRM1_CTL0_SET (ACC_BASE_ADDR + ACC_THERMAL_THRM1_CTL0_SET_OFFSET) +#define ACC_THRM1_CTL0_CLR (ACC_BASE_ADDR + ACC_THERMAL_THRM1_CTL0_CLR_OFFSET) +#define ACC_THRM1_CTL1 (ACC_BASE_ADDR + ACC_THERMAL_THRM1_CTL1_OFFSET) +#define ACC_THRM1_PARAM (ACC_BASE_ADDR + ACC_THERMAL_THRM1_PARAM_OFFSET) +#define ACC_THRM1_PIECE0 (ACC_BASE_ADDR + ACC_THERMAL_THRM1_PIECE0_OFFSET) +#define ACC_THRM1_PIECE1 (ACC_BASE_ADDR + ACC_THERMAL_THRM1_PIECE1_OFFSET) +#define ACC_THRM1_PIECE2 (ACC_BASE_ADDR + ACC_THERMAL_THRM1_PIECE2_OFFSET) + +#define ACC_THRM2_CTL0_SET (ACC_BASE_ADDR + ACC_THERMAL_THRM2_CTL0_SET_OFFSET) +#define ACC_THRM2_CTL0_CLR (ACC_BASE_ADDR + ACC_THERMAL_THRM2_CTL0_CLR_OFFSET) +#define ACC_THRM2_CTL1 (ACC_BASE_ADDR + ACC_THERMAL_THRM2_CTL1_OFFSET) +#define ACC_THRM2_PARAM (ACC_BASE_ADDR + ACC_THERMAL_THRM2_PARAM_OFFSET) +#define ACC_THRM2_PIECE0 (ACC_BASE_ADDR + ACC_THERMAL_THRM2_PIECE0_OFFSET) +#define ACC_THRM2_PIECE1 (ACC_BASE_ADDR + ACC_THERMAL_THRM2_PIECE1_OFFSET) +#define ACC_THRM2_PIECE2 (ACC_BASE_ADDR + ACC_THERMAL_THRM2_PIECE2_OFFSET) + +#define ACC_DVFM_FSHOT_IDX (ACC_BASE_ADDR + ACC_THERMAL_DVFM_FSHOT_IDX_OFFSET) + +#define ACC_THRM0_PIECE0_MAKE(_c, _o, _s) (ACC_THERMAL_THRM0_PIECE0_START_CODE_INSRT(_c) | ACC_THERMAL_THRM0_PIECE0_OFFSET_INSRT(_o) | ACC_THERMAL_THRM0_PIECE0_SLOPE_INSRT(_s)) +#define ACC_THRM0_PIECE1_MAKE(_c, _o, _s) (ACC_THERMAL_THRM0_PIECE1_START_CODE_INSRT(_c) | ACC_THERMAL_THRM0_PIECE1_OFFSET_INSRT(_o) | ACC_THERMAL_THRM0_PIECE1_SLOPE_INSRT(_s)) +#define ACC_THRM0_PIECE2_MAKE(_c, _o, _s) (ACC_THERMAL_THRM0_PIECE2_START_CODE_INSRT(_c) | ACC_THERMAL_THRM0_PIECE2_OFFSET_INSRT(_o) | ACC_THERMAL_THRM0_PIECE2_SLOPE_INSRT(_s)) +#define ACC_THRM1_PIECE0_MAKE(_c, _o, _s) (ACC_THERMAL_THRM1_PIECE0_START_CODE_INSRT(_c) | ACC_THERMAL_THRM1_PIECE0_OFFSET_INSRT(_o) | ACC_THERMAL_THRM1_PIECE0_SLOPE_INSRT(_s)) +#define ACC_THRM1_PIECE1_MAKE(_c, _o, _s) (ACC_THERMAL_THRM1_PIECE1_START_CODE_INSRT(_c) | ACC_THERMAL_THRM1_PIECE1_OFFSET_INSRT(_o) | ACC_THERMAL_THRM1_PIECE1_SLOPE_INSRT(_s)) +#define ACC_THRM1_PIECE2_MAKE(_c, _o, _s) (ACC_THERMAL_THRM1_PIECE2_START_CODE_INSRT(_c) | ACC_THERMAL_THRM1_PIECE2_OFFSET_INSRT(_o) | ACC_THERMAL_THRM1_PIECE2_SLOPE_INSRT(_s)) +#define ACC_THRM2_PIECE0_MAKE(_c, _o, _s) (ACC_THERMAL_THRM2_PIECE0_START_CODE_INSRT(_c) | ACC_THERMAL_THRM2_PIECE0_OFFSET_INSRT(_o) | ACC_THERMAL_THRM2_PIECE0_SLOPE_INSRT(_s)) +#define ACC_THRM2_PIECE1_MAKE(_c, _o, _s) (ACC_THERMAL_THRM2_PIECE1_START_CODE_INSRT(_c) | ACC_THERMAL_THRM2_PIECE1_OFFSET_INSRT(_o) | ACC_THERMAL_THRM2_PIECE1_SLOPE_INSRT(_s)) +#define ACC_THRM2_PIECE2_MAKE(_c, _o, _s) (ACC_THERMAL_THRM2_PIECE2_START_CODE_INSRT(_c) | ACC_THERMAL_THRM2_PIECE2_OFFSET_INSRT(_o) | ACC_THERMAL_THRM2_PIECE2_SLOPE_INSRT(_s)) + +//////////////////////////////////////////////////////////// +// +// Externs +// +//////////////////////////////////////////////////////////// + +extern void pmgr_update_device_tree(DTNode *pmgr_node); +extern void pmgr_gfx_update_device_tree(DTNode *gfx_node); +extern void pmgr_platform_config_uvwarn(void); + +void pmgr_awake_to_aop_ddr_pre_sequence_insert(void); +void pmgr_aop_ddr_to_awake_post_sequence_insert_pll(void); +void pmgr_aop_ddr_to_awake_post_sequence_insert(void); +void pmgr_s2r_aop_to_aop_ddr_post_sequence_insert_pwrgate(void); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/s8000/include/platform/soc/reconfig.h b/platform/s8000/include/platform/soc/reconfig.h new file mode 100644 index 0000000..b070e13 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_RECONFIG_H +#define __PLATFORM_RECONFIG_H + +#include +#include +#include + +#define rAOP_GLOBAL(_p) (*(volatile uint32_t *)(AOP_BASE_ADDR + _p)) +#define rRECONFIG_RAM_BASE(base, count) *(volatile uint32_t *)((base) + (count*4)) +#define rRECONFIG_RAM_BASE_BYTE(base, count, count_bytes) *(volatile uint32_t *)((base) + (count*4) + (count_bytes)) +#define ALIGNMENT_MASK_1KB ~(0x3FF) +#define RECONFIG_NUMBER_OF_REGS(regs) ((((regs) - 1) & 0xF) << 2) +#define AOP_CFG_TABLE (AOP_RECONFIG_REGION_BASE_ADDR) +#define AOP_CFG_TABLE_DIAGS (AOP_RECONFIG_REGION_DIAGS_BASE_ADDR) +#define WRITE_OFFSETS(addr, values) (((addr) >> 2) & 0xFF) << (((values) % 4) * 8) +#define MAX_WRITE_REGS 16 + +#define AOP_DDR_S2R_AOP_PRE_MAX_SIZE 0x200 +#define AOP_DDR_S2R_AOP_POST_MAX_SIZE 0x100 +#define S2R_AOP_AOP_DDR_PRE_MAX_SIZE 0x100 + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + #define S2R_AOP_AOP_DDR_POST_MAX_SIZE 0x4000 +#elif SUB_PLATFORM_S8001 + #define S2R_AOP_AOP_DDR_POST_MAX_SIZE 0x4b00 +#endif + +#define AWAKE_AOP_DDR_PRE_MAX_SIZE 0x200 +#define AWAKE_AOP_DDR_POST_MAX_SIZE 0x600 +#define AOP_DDR_AWAKE_PRE_MAX_SIZE 0x800 + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + #define AOP_DDR_AWAKE_POST_MAX_SIZE 0x2a00 +#elif SUB_PLATFORM_S8001 + #define AOP_DDR_AWAKE_POST_MAX_SIZE 0x4000 +#endif + +// SRAM sequences +#define AOP_DDR_S2R_AOP_PRE_BASE_ADDR (AOP_RECONFIG_REGION_BASE_ADDR + 0x100) +#define AOP_DDR_S2R_AOP_POST_BASE_ADDR (AOP_DDR_S2R_AOP_PRE_BASE_ADDR + AOP_DDR_S2R_AOP_PRE_MAX_SIZE) +#define S2R_AOP_AOP_DDR_PRE_BASE_ADDR (AOP_DDR_S2R_AOP_POST_BASE_ADDR + AOP_DDR_S2R_AOP_POST_MAX_SIZE) +#define S2R_AOP_AOP_DDR_POST_BASE_ADDR (S2R_AOP_AOP_DDR_PRE_BASE_ADDR + S2R_AOP_AOP_DDR_PRE_MAX_SIZE) + +#define AOP_RECONFIG_REGION_USED (S2R_AOP_AOP_DDR_POST_BASE_ADDR + S2R_AOP_AOP_DDR_POST_MAX_SIZE - AOP_RECONFIG_REGION_BASE_ADDR) + +#if AOP_RECONFIG_REGION_USED > AOP_RECONFIG_REGION_SIZE +#error "Reconfig engine programs overflow their SRAM allocation +#endif + +// DRAM sequences +#define AWAKE_AOP_DDR_PRE_BASE_ADDR (DRAM_CONFIG_SEQ_BASE) +#define AWAKE_AOP_DDR_POST_BASE_ADDR (AWAKE_AOP_DDR_PRE_BASE_ADDR + AWAKE_AOP_DDR_PRE_MAX_SIZE) +#define AOP_DDR_AWAKE_PRE_BASE_ADDR (AWAKE_AOP_DDR_POST_BASE_ADDR + AWAKE_AOP_DDR_POST_MAX_SIZE) +#define AOP_DDR_AWAKE_POST_BASE_ADDR (AOP_DDR_AWAKE_PRE_BASE_ADDR + AOP_DDR_AWAKE_PRE_MAX_SIZE) + +#define DRAM_CONFIG_SEQ_USED (AOP_DDR_AWAKE_POST_BASE_ADDR + AOP_DDR_AWAKE_POST_MAX_SIZE - DRAM_CONFIG_SEQ_BASE) + +#if DRAM_CONFIG_SEQ_USED > DRAM_CONFIG_SEQ_SIZE +#error "Reconfig engine programs overflow their DRAM allocation +#endif + +// For diags, all sequences go in SRAM + +#define AOP_DDR_S2R_AOP_PRE_DIAGS_BASE_ADDR (AOP_RECONFIG_REGION_DIAGS_BASE_ADDR + 0x100) +#define AOP_DDR_S2R_AOP_POST_DIAGS_BASE_ADDR (AOP_DDR_S2R_AOP_PRE_DIAGS_BASE_ADDR + AOP_DDR_S2R_AOP_PRE_MAX_SIZE) +#define S2R_AOP_AOP_DDR_PRE_DIAGS_BASE_ADDR (AOP_DDR_S2R_AOP_POST_DIAGS_BASE_ADDR + AOP_DDR_S2R_AOP_POST_MAX_SIZE) +#define S2R_AOP_AOP_DDR_POST_DIAGS_BASE_ADDR (S2R_AOP_AOP_DDR_PRE_DIAGS_BASE_ADDR + S2R_AOP_AOP_DDR_PRE_MAX_SIZE) + +#define AWAKE_AOP_DDR_PRE_DIAGS_BASE_ADDR (S2R_AOP_AOP_DDR_POST_DIAGS_BASE_ADDR + S2R_AOP_AOP_DDR_POST_MAX_SIZE) +#define AWAKE_AOP_DDR_POST_DIAGS_BASE_ADDR (AWAKE_AOP_DDR_PRE_DIAGS_BASE_ADDR + AWAKE_AOP_DDR_PRE_MAX_SIZE) +#define AOP_DDR_AWAKE_PRE_DIAGS_BASE_ADDR (AWAKE_AOP_DDR_POST_DIAGS_BASE_ADDR + AWAKE_AOP_DDR_POST_MAX_SIZE) +#define AOP_DDR_AWAKE_POST_DIAGS_BASE_ADDR (AOP_DDR_AWAKE_PRE_DIAGS_BASE_ADDR + AOP_DDR_AWAKE_PRE_MAX_SIZE) + +#define AOP_RECONFIG_REGION_DIAGS_USED (AOP_DDR_AWAKE_POST_DIAGS_BASE_ADDR + AOP_DDR_AWAKE_POST_MAX_SIZE - AOP_RECONFIG_REGION_DIAGS_BASE_ADDR) + +#if AOP_RECONFIG_REGION_DIAGS_USED > AOP_RECONFIG_REGION_DIAGS_SIZE +#error "Reconfig engine programs overflow their SRAM allocation +#endif + +#endif /* __PLATFORM_RECONFIG_H */ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000.h b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000.h new file mode 100644 index 0000000..1b426d8 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000.h @@ -0,0 +1,1474 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef AOP_CONFIG_SEQUENCES_H +#define AOP_CONFIG_SEQUENCES_H + +#include "reconfig_sequences_mcu_1200_s8000.h" + +// _ _ _ _ +// / \ _ _| |_ ___ __ _ ___ _ __ ___ _ __ __ _| |_ ___ __| | +// / _ \| | | | __/ _ \ / _` |/ _ \ '_ \ / _ \ '__/ _` | __/ _ \/ _` | +// / ___ \ |_| | || (_) | (_| | __/ | | | __/ | | (_| | || __/ (_| | +// /_/ \_\__,_|\__\___/ \__, |\___|_| |_|\___|_| \__,_|\__\___|\__,_| +// ____ |___/ _____ _ _ _ +// | _ \ ___ _ __ ___ | |_ | ____|__| (_) |_ +// | | | |/ _ \ | '_ \ / _ \| __| | _| / _` | | __| +// | |_| | (_) | | | | | (_) | |_ | |__| (_| | | |_ +// |____/ \___/ |_| |_|\___/ \__| |_____\__,_|_|\__| +// + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP SOC CONFIG SEQUENCES */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** RELEASE NOTES */ +/* Comment: // ** */ +/* Comment: // ** -- 2/23/2015 -- */ +/* Comment: // ** Removed MccLockRegion programming from SOC sequences. Added "INSERT_MCU_DDR_LOCKED" */ +/* Comment: // ** comment label to indicate where to stitch in MCU DV LockRegion subsequence. */ +/* Comment: // ** */ +/* Comment: // ** Fixed incorrect fix to radar 16219268 which left PCIE_PS on during AOP_DDR. */ +/* Comment: // ** */ +/* Comment: // ** Reset AIC during AWAKE->AOP_DDR pre-amble. */ +/* Comment: // ** */ +/* Comment: // ** -- 2/8/2015 -- */ +/* Comment: // ** Added "verbatim" command which will print the specified text verbatim in the final */ +/* Comment: // ** output file. This is used for putting #defines into the final header file for SW. */ +/* Comment: // ** */ +/* Comment: // ** Ported "ifdef" processing from Elba. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/29/2015 -- */ +/* Comment: // ** Updated sequences based on CoreOS feedback from radars 19132562 and 19148279. */ +/* Comment: // ** Added "stitch" command to stitch in sequences from external files. Intended to */ +/* Comment: // ** explicitly annotate which sequences are meant to be overridden by SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/26/2015 -- */ +/* Comment: // ** Disable DynPwrDn in AOP_DDR (see radar 19338346) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/17/2014 -- */ +/* Comment: // ** Update programming of PLL0_CTL (see radar 18899788) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/12/2014 -- */ +/* Comment: // ** Added S2R_AOP->AOP_DDR preamble which polls for proxy_osc_clk to be equal to lpo/8. */ +/* Comment: // ** Activating the S2R_AOP->AOP_DDR preamble forces the LPO to be on prior to the */ +/* Comment: // ** AOP-PMU handshake. See radar 18563566 for details. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/22/2014 -- */ +/* Comment: // ** Config engine changes the current perf state to 0 prior to polling. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/26/2014 -- */ +/* Comment: // ** Instead of implicitly stitching the 48->800 MCU sequence at the beginning of the */ +/* Comment: // ** AOP_DDR->AWAKE sequence, it is now inserted at the comment token labeled */ +/* Comment: // ** "INSERT_MCU_AWAKE_SEQ". This will make the sequence more flexible in case commands */ +/* Comment: // ** are to be inserted before the MCU sequence, e.g., changing tunables. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/20/2014 -- */ +/* Comment: // ** Added more documentation to aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/4/2014 -- */ +/* Comment: // ** In this update, we removed the need to specify reg_addr in the write/write64/poll */ +/* Comment: // ** commands. The reg_addr was prone to human error because it was manually written, */ +/* Comment: // ** so there is no guarantee that the address matches the register name. Furthermore, */ +/* Comment: // ** manually specifying the register address is not future-proof because addresses of */ +/* Comment: // ** registers may change from chip to chip. */ +/* Comment: // ** */ +/* Comment: // ** Now, the register address are calculated based on the register name and the include */ +/* Comment: // ** files. The user must ensure that all of the header files needed are specified */ +/* Comment: // ** using the "include:" command. In the DV environment, these header files were */ +/* Comment: // ** generated from SPDS. */ +/* Comment: // ** */ +/* Comment: // ** Note: For legacy reasons, we still support manually specifying the reg_addr field. */ +/* Comment: // ** If the reg_addr field is specified, the reg_name field is ignored during the */ +/* Comment: // ** generation of the .h file. */ +/* Comment: // ** */ +/* Comment: // ** We also renamed the file type of this file from .h to .seq. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ** This file contains the AOP SoC config sequences verified by DV. It is written in a */ +/* Comment: // ** pseudo-language that is parsed by the scripts described in the "Related files" section */ +/* Comment: // ** below. All commands must be contained within a single line. */ +/* Comment: // ** */ +/* Comment: // ** The supported commands are: */ +/* Comment: // ** */ +/* Comment: // ** include: */ +/* Comment: // ** Header file to include for looking up register addresses. The path to the include */ +/* Comment: // ** files is provided as an argument to the aop_func_gen.pl script described below. */ +/* Comment: // ** */ +/* Comment: // ** seq_name: */ +/* Comment: // ** Designates the start of a sequence. The supported sequences are: */ +/* Comment: // ** s2r_aop_to_aop_ddr_pre */ +/* Comment: // ** s2r_aop_to_aop_ddr_post */ +/* Comment: // ** aop_ddr_to_s2r_aop_pre */ +/* Comment: // ** aop_ddr_to_s2r_aop_post */ +/* Comment: // ** aop_ddr_to_awake_pre */ +/* Comment: // ** aop_ddr_to_awake_post */ +/* Comment: // ** awake_to_aop_ddr_pre */ +/* Comment: // ** awake_to_aop_ddr_post */ +/* Comment: // ** Note that s2r_aop_to_aop_ddr_pre and aop_ddr_to_s2r_aop_post are currently unused. */ +/* Comment: // ** */ +/* Comment: // ** endseq */ +/* Comment: // ** Designates the end of a sequence. */ +/* Comment: // ** */ +/* Comment: // ** write: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 32-bit write command to the register at 36-bit hex
with 32-bit hex . */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write64: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 64-bit write command to the 36-bit hex
with 64-bit value , */ +/* Comment: // ** where "upper" is the upper 32-bit hex value, and "lower" is the lower 32-bit hex */ +/* Comment: // ** value. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write_start */ +/* Comment: // ** Designates the start of a write command with multiple register writes. Refer to */ +/* Comment: // ** AOP spec section 6.1 "Configuration Write Command" for details. Because the */ +/* Comment: // ** annotation with "write_start" and "write_end" is manually done, it is the */ +/* Comment: // ** responsibility of the author to ensure that the combined writes are within the */ +/* Comment: // ** same 1KB block, and a max of 16 writes is included. */ +/* Comment: // ** */ +/* Comment: // ** write_end */ +/* Comment: // ** Designates the end of a multi-register write command. */ +/* Comment: // ** */ +/* Comment: // ** poll: reg_name= [reg_addr=
] reg_value= reg_mask= retry_en= retry_cnt= */ +/* Comment: // ** Reads 36-bit
until (read_data & mask == value). If is 0, the */ +/* Comment: // ** poll repeats indefinitely. If is set, the read is retried up to */ +/* Comment: // ** times. As with "write" and "write64", is not used. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** cfg_cnt: */ +/* Comment: // ** designates the number of aop_clk cycles to wait before executing the next */ +/* Comment: // ** command. */ +/* Comment: // ** */ +/* Comment: // ** cfg_end */ +/* Comment: // ** Designates the Configuration End Command. */ +/* Comment: // ** */ +/* Comment: // ** comment: */ +/* Comment: // ** Designates a comment. */ +/* Comment: // ** */ +/* Comment: // ** stitch: */ +/* Comment: // ** Stitches file.seq into the sequence inline. */ +/* Comment: // ** */ +/* Comment: // ** stitch_h: */ +/* Comment: // ** In the generated .h file, an explicit #include "file.h" will appear at this line. */ +/* Comment: // ** */ +/* Comment: // ** Related files: */ +/* Comment: // ** tb_lib/cpu/armv7/aop_lib/aop_func_gen.pl */ +/* Comment: // ** This script parses this file (aop_soc_cfg.h) and converts it into an intermediate */ +/* Comment: // ** C header format. The output file contains C arrays whose contents are in a format */ +/* Comment: // ** understood by the SOC config engine. In the DV environment, the intermediate C */ +/* Comment: // ** header file is called aop_soc_engine.h and is placed in the testgen* directory of */ +/* Comment: // ** the test results directory. The intermediate file and MCU config sequences are */ +/* Comment: // ** combined using the powgen_common.pl script, described below. */ +/* Comment: // ** */ +/* Comment: // ** tb_lib/cpu/armv8/mcu/mcu_init_aop.h */ +/* Comment: // ** Provided by the MCU team, mcu_init_aop.h contains the two sequences for configuring */ +/* Comment: // ** the DDR to operate at 48MHz and >= 800MHz. The 48MHz sequence is stitched into the */ +/* Comment: // ** S2R_AOP->AOP_DDR postamble at the comment token "INSERT_MCU_AOP_DDR_SEQ". The */ +/* Comment: // ** >= 800 MHz sequence is stitched into the AOP_DDR->AWAKE postamble at the comment */ +/* Comment: // ** token "INSERT_MCU_AWAKE_SEQ". */ +/* Comment: // ** */ +/* Comment: // ** chip/tb/cpu/bin/powgen_common.pl */ +/* Comment: // ** This script stitches together the aop_soc_engine.h file generated by aop_func_gen.pl */ +/* Comment: // ** and mcu_init_aop.h into the same AP EHEX file that is loaded into memory. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Poll for the proxy_osc clock to source LPO/8 before initiating minipmgr reset sequence */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_pre_0[] = { +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG ADDR=0x210240304 Retry_en=0 Retry_cnt=0*/ +0x000000c1, /* Offset */ +0x40300000, /* Mask */ +0x00200000, /* Data */ +/* Comment: // Do a dummy read to the AOP CPU revision register to cause a functional wakeup */ +0x21080002, /* Poll:AKF_AKFAPB_AKF_REV(GBI_AOP_AKF) ADDR=0x210800000 Retry_en=1 Retry_cnt=597*/ +0x00035500, /* Offset */ +0x00000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000004, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** This sequence is split into multiple subsequences */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_0[] = { +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000000, /* Data */ +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Security sequence */ +/* Comment: // Write mem cache data and tag enable/lock bits to prevent backdoor access as RAM attacks */ +0x20000041, /* WR:AMCC_MCCCFG_MCCGEN ADDR=0x200000780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +/* Comment: // Write lockable DRAM config regs */ +/* Comment: // INSERT_MCU_DDR_LOCKED */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // The MCU LockRegion programming must occur before the security/TZ programming (s2r_aop_to_aop_ddr_post_security) */ +#define S2D_POST_MCU_LOCKED_AFTER 0 +#define S2D_POST_MCU_LOCKED_BEFORE 1 +/* Comment: // The security/TZ programming must occur after the MCU LockRegion programming */ +#define S2D_POST_SECURITY_AFTER 0 +#define S2D_POST_SECURITY_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR security postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_security[] = { +/* Comment: // Enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20000049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR ADDR=0x200000480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR ADDR=0x200000484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // Enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20000049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR ADDR=0x200000488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR ADDR=0x20000048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_1[] = { +/* Comment: // Disable AP_GID0 */ +0x2102d001, /* WR:MINIPMGR_SECURITY_SIO_AES_DISABLE ADDR=0x2102d0000 */ +0x00000000, /* Offset */ +0x00000002, /* Data */ +/* Comment: // SRAM region that must be locked ends here. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SW: */ +/* Comment: // ** */ +/* Comment: // ** Locked region is specified in 64B granularity. If the last security entry does not */ +/* Comment: // ** land neatly at the end of a 64B boundary, some non-security entries may be locked if */ +/* Comment: // ** no additional padding is used. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // Disable voltage changes (see radar 16038537) */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SiVal/SW: */ +/* Comment: // ** */ +/* Comment: // ** Per Manu, perf state entry 0 has been reserved for use by the config engine. SW agreed */ +/* Comment: // ** to use the perf state entries starting from the higher indices. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // transition the fabric and DRAM to work off the proxy clocks */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Clear the CSYSPWRUPREQ_LOOPBACK bit. See PMGR spec section 11.4.4.1 */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000000 /* Data */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define S2D_POST_PWRGATE_AFTER 1 +#define S2D_POST_PWRGATE_BEFORE 2 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_2[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08035, /* 14-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0xba4294a4, /* Offset */ +0x00005244, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001 /* Data */ +}; + +#define S2D_POST_MCU_DDR_AFTER 2 +#define S2D_POST_MCU_DDR_BEFORE 3 +static const uint32_t s2r_aop_to_aop_ddr_post_3[] = { +/* Comment: // INSERT_MCU_AOP_DDR_SEQ */ +/* Comment: // Wait for the memcache to reach 16 ways, then set it to 0 */ +0x20000042, /* Poll:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS ADDR=0x20000079c Retry_en=0 Retry_cnt=0*/ +0x000000e7, /* Offset */ +0x03e003e0, /* Mask */ +0x02000200, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000100, /* Data */ +/* Comment: // Set the proxy fabric clock frequency back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->S2R_AOP PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_s2r_aop_pre_0[] = { +/* Comment: // Note - We do not wait for the memcache ways to reach 0 before yanking power. See radar 16051416 */ +/* Comment: // Set NO_HANDSHAKE bit prior to restoring the perf state table to its defaults, radar 16219268 */ +0x20e04081, /* WR:PMGR_CLKCTL_MCU_CLK_DEBUG ADDR=0x20e040810 */ +0x00000004, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Set all SRC_SEL for SOC clocks to 0 so there will be no clock glitches, radar 16409004 */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x00000030, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // power up PCIe/SIO/USB domain to bypass NLP:: Pcie2phy pwr clamp enable is going to X after warmboot in UPF simulations */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08025, /* 10-word write */ +0x9458a6a8, /* Offset */ +0x8e8c8ac4, /* Offset */ +0x00009290, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x0000000f, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=0 Retry_cnt=0*/ +0x000000a8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=0 Retry_cnt=0*/ +0x000000a6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=0 Retry_cnt=0*/ +0x00000058, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=0 Retry_cnt=0*/ +0x00000094, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=0 Retry_cnt=0*/ +0x000000c4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=0 Retry_cnt=0*/ +0x0000008a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=0 Retry_cnt=0*/ +0x0000008c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=0 Retry_cnt=0*/ +0x0000008e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=0 Retry_cnt=0*/ +0x00000090, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=0 Retry_cnt=0*/ +0x00000092, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // wait 100us to delay retention reset per radar 18727371 */ +0x0012c004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t aop_ddr_to_s2r_aop_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** See PMGR spec section 11.14.4 (Software Teardown for Awake Exit) */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_pre_0[] = { +/* Comment: // Restore the GPIO to its default configuration by setting GPIO_PS.RESET for 1us while setting MANUAL_PS to RUN_MAX */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x8000000f, /* Data */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x00000004, /* Data */ +/* Comment: // Disable voltage changes */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +0x20e06811, /* 5-word write */ +0x07060504, /* Offset */ +0x00000000, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0D ADDR=0x20e06801c */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Per radar 19338346, disable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +/* Comment: // Power off PLLs that software could not turn off (ENABLE == 0 and BYPASS == 1) */ +0x20e00001, /* WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x00000000, /* Offset */ +0x28190060, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x00000000, /* Offset */ +0x280b4030, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x00000000, /* Offset */ +0x2804201f, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t awake_to_aop_ddr_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.4 (Software Teardown for Awake Exit), either */ +/* Comment: // ** SW or the config engine may turn off SIO/PCIE. For DV simulations, we chose to power */ +/* Comment: // ** power down ALL of the unneeded blocks in the config engine rather than from the AP. This */ +/* Comment: // ** provided functionally equivalent behavior and allowed the AWAKE->AOP_DDR and */ +/* Comment: // ** S2R_AOP->AOP_DDR to appear symmetric. SiVal/SW may move parts of this sequence */ +/* Comment: // ** to AP software if desired. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_post_0[] = { +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define A2D_POST_PWRGATE_AFTER 0 +#define A2D_POST_PWRGATE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AWAKE->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t awake_to_aop_ddr_post_1[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08031, /* 13-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0x44ba94a4, /* Offset */ +0x00000052, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e0b83d, /* 16-word write */ +0x03020100, /* Offset */ +0x07060504, /* Offset */ +0x13121110, /* Offset */ +0x17161514, /* Offset */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH0 ADDR=0x20e0b8000 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH1 ADDR=0x20e0b8004 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH2 ADDR=0x20e0b8008 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH3 ADDR=0x20e0b800c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH4 ADDR=0x20e0b8010 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH5 ADDR=0x20e0b8014 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH6 ADDR=0x20e0b8018 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH7 ADDR=0x20e0b801c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH16 ADDR=0x20e0b8040 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH17 ADDR=0x20e0b8044 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH18 ADDR=0x20e0b8048 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH19 ADDR=0x20e0b804c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH20 ADDR=0x20e0b8050 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH21 ADDR=0x20e0b8054 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH22 ADDR=0x20e0b8058 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH23 ADDR=0x20e0b805c */ +/* Comment: // Reset and then clock gate the AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e10001, /* WR:AIC_GLOBALS_AICRST ADDR=0x20e10000c */ +0x00000003, /* Offset */ +0x00000001, /* Data */ +0x20e10002, /* Poll:AIC_GLOBALS_AICRST ADDR=0x20e10000c Retry_en=1 Retry_cnt=255*/ +0x0001ff03, /* Offset */ +0x00000001, /* Mask */ +0x00000000, /* Data */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x00000000, /* Data */ +0x2102b005, /* 2-word write */ +0x00000400, /* Offset */ +0x00000000, /* Data WR:MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER ADDR=0x2102b0000 */ +0x00000000 /* Data WR:MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER ADDR=0x2102b0010 */ +}; + +static const uint32_t awake_to_aop_ddr_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_pre_0[] = { +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000110, /* Data */ +/* Comment: // Powering up SIO partition and SIO devices */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000058, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=1 Retry_cnt=255*/ +0x0001ff58, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000056, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_P_PS ADDR=0x20e080158 Retry_en=1 Retry_cnt=255*/ +0x0001ff56, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000004, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000004, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000004, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000004, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000004, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000004, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000004, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000004, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000004, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000004, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000004, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000004, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000004, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000004, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000004, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0801d, /* 8-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000004, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000004, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000004, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000004, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000004, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000004, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000004, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +/* Comment: // It might not be required to do all of the following polls since they should take the same amount of time to power up. */ +/* Comment: // One possible optimization is to only do the poll for the last write */ +0x20e08002, /* Poll:PMGR_PS_MCA0_PS ADDR=0x20e080168 Retry_en=1 Retry_cnt=255*/ +0x0001ff5a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA1_PS ADDR=0x20e080170 Retry_en=1 Retry_cnt=255*/ +0x0001ff5c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA2_PS ADDR=0x20e080178 Retry_en=1 Retry_cnt=255*/ +0x0001ff5e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA3_PS ADDR=0x20e080180 Retry_en=1 Retry_cnt=255*/ +0x0001ff60, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA4_PS ADDR=0x20e080188 Retry_en=1 Retry_cnt=255*/ +0x0001ff62, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PWM0_PS ADDR=0x20e080190 Retry_en=1 Retry_cnt=255*/ +0x0001ff64, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C0_PS ADDR=0x20e080198 Retry_en=1 Retry_cnt=255*/ +0x0001ff66, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 Retry_en=1 Retry_cnt=255*/ +0x0001ff68, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 Retry_en=1 Retry_cnt=255*/ +0x0001ff6c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 Retry_en=1 Retry_cnt=255*/ +0x0001ff70, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 Retry_en=1 Retry_cnt=255*/ +0x0001ff72, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 Retry_en=1 Retry_cnt=255*/ +0x0001ff74, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART0_PS ADDR=0x20e0801d8 Retry_en=1 Retry_cnt=255*/ +0x0001ff76, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART1_PS ADDR=0x20e0801e0 Retry_en=1 Retry_cnt=255*/ +0x0001ff78, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART2_PS ADDR=0x20e0801e8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART3_PS ADDR=0x20e0801f0 Retry_en=1 Retry_cnt=255*/ +0x0001ff7c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART4_PS ADDR=0x20e0801f8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART5_PS ADDR=0x20e080200 Retry_en=1 Retry_cnt=255*/ +0x0001ff80, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART6_PS ADDR=0x20e080208 Retry_en=1 Retry_cnt=255*/ +0x0001ff82, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART7_PS ADDR=0x20e080210 Retry_en=1 Retry_cnt=255*/ +0x0001ff84, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART8_PS ADDR=0x20e080218 Retry_en=1 Retry_cnt=255*/ +0x0001ff86, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AES0_PS ADDR=0x20e080220 Retry_en=1 Retry_cnt=255*/ +0x0001ff88, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up PCIE partition and PCIE devices/link */ +0x20e08001, /* WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x000000c4, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=1 Retry_cnt=255*/ +0x0001ffc4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xcccac8c6, /* Offset */ +0x000000ce, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08002, /* Poll:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 Retry_en=1 Retry_cnt=255*/ +0x0001ffc6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 Retry_en=1 Retry_cnt=255*/ +0x0001ffc8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 Retry_en=1 Retry_cnt=255*/ +0x0001ffca, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 Retry_en=1 Retry_cnt=255*/ +0x0001ffcc, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 Retry_en=1 Retry_cnt=255*/ +0x0001ffce, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up USB partition and USB devices */ +0x20e08001, /* WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000094, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0x9c9896a4, /* Offset */ +0x000000a0, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000004, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x20e08002, /* Poll:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 Retry_en=1 Retry_cnt=255*/ +0x0001ffa4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 Retry_en=1 Retry_cnt=255*/ +0x0001ff96, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 Retry_en=1 Retry_cnt=255*/ +0x0001ff98, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 Retry_en=1 Retry_cnt=255*/ +0x0001ff9c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 Retry_en=1 Retry_cnt=255*/ +0x0001ffa0, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08009, /* 3-word write */ +0x00a29e9a, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 Retry_en=1 Retry_cnt=255*/ +0x0001ff9a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 Retry_en=1 Retry_cnt=255*/ +0x0001ff9e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 Retry_en=1 Retry_cnt=255*/ +0x0001ffa2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x000000ba, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PMP_PS ADDR=0x20e0802e8 Retry_en=1 Retry_cnt=255*/ +0x0001ffba, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Restore PMS, SBR, SF, SMX, MCC, and DCS* PS to reset values per CoreOS request from radar 19132562 */ +0x20e0802d, /* 12-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x52444692, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=1 Retry_cnt=255*/ +0x0001ffa8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=1 Retry_cnt=255*/ +0x0001ffa6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=1 Retry_cnt=255*/ +0x0001ff8a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80101000, /* Data */ +/* Comment: // wait 1us */ +0x00003004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_awake_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.3 (Software Init for AOP_DDR to AWAKE), the */ +/* Comment: // ** config engine restores the state of the chip in this step. The specific use cases where */ +/* Comment: // ** the config engine is the owner of state restoration are not yet defined. */ +/* Comment: // ** */ +/* Comment: // ** The sequence below contains the minimum set of commands to re-boot the AP and restore */ +/* Comment: // ** DRAM operation at bucket 1 for SOC DV simulations. AP may bring DRAM up to bucket 0. */ +/* Comment: // ** */ +/* Comment: // ** It is assumed that SW will modify this sequence extensively. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +#define D2A_POST_MCU_AWAKE_AFTER -1 +#define D2A_POST_MCU_AWAKE_BEFORE 0 +static const uint32_t aop_ddr_to_awake_post_0[] = { +/* Comment: // Wait 900us as first step of AOP_DDR->AWAKE per radar 20181763 to ensure BIRA loading is complete */ +/* Comment: // prior to powering on any non-AOP power domain */ +0x00a8c004, /* Cfg Count(Delay.Wait) */ +/* Comment: // INSERT_MCU_AWAKE_SEQ */ +/* Comment: // Restore the state of the chip */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80100000, /* Data */ +/* Comment: // wait 1us */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +#define D2A_POST_RESTORE_AFTER 0 +#define D2A_POST_RESTORE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AOP_DDR->AWAKE system restore postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_post_restore[] = { +0x20e00001, /* WR:PMGR_PLL0_ANA_PARAMS0 ADDR=0x20e000008 */ +0x00000002, /* Offset */ +0x001c8385, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_ANA_PARAMS0 ADDR=0x20e004008 */ +0x00000002, /* Offset */ +0x001c8385, /* Data */ +0x20e00005, /* 2-word write */ +0x00000100, /* Offset */ +0xa00c8030, /* Data WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x10000010, /* Data WR:PMGR_PLL0_CFG ADDR=0x20e000004 */ +0x20e00002, /* Poll:PMGR_PLL0_CTL ADDR=0x20e000000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_PLL_DELAY_CTL1 ADDR=0x20e004020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00405, /* 2-word write */ +0x00000001, /* Offset */ +0x50480030, /* Data WR:PMGR_PLL1_CFG ADDR=0x20e004004 */ +0xa003c010, /* Data WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x20e00402, /* Poll:PMGR_PLL1_CTL ADDR=0x20e004000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Bring MCU up to bucket1. Note: It is up to the AP to config MCU to bucket0 */ +0x20e06819, /* 7-word write */ +0x08060504, /* Offset */ +0x00000a09, /* Offset */ +0x55555517, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x55656666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x88878807, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1A ADDR=0x20e068020 */ +0x67a76866, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1B ADDR=0x20e068024 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1C ADDR=0x20e068028 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Tunables may be re-applied here */ +0x20e08001, /* WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000044, /* Offset */ +0x0000024f, /* Data */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +// +// The removal of the items below from this model sequence is intentional. +// +//0x00000044, /* CFG Count to aling 64 bit write to 16 bytes address:*/ +//0x20205003, /* WR:ACC_CPU0_IMPL_IO_RVBAR ADDR=0x202050000 */ +//0x00000000, /* Offset */ +//0x00000000, /* Data */ +//0x00000008 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_post_1[] = { +/* Comment: // Per radar 19338346, re-enable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +/* Comment: // Per radar 20183074, turn the following partitions on one at a time */ +0x20e08001, /* WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +0x000000aa, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 Retry_en=0 Retry_cnt=0*/ +0x000000aa, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x000000b2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_ISP_PS ADDR=0x20e0802c8 Retry_en=0 Retry_cnt=0*/ +0x000000b2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x000000b4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 Retry_en=0 Retry_cnt=0*/ +0x000000b4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x000000b8, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MSR_PS ADDR=0x20e0802e0 Retry_en=0 Retry_cnt=0*/ +0x000000b8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x000000be, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 Retry_en=0 Retry_cnt=0*/ +0x000000be, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x000000c2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 Retry_en=0 Retry_cnt=0*/ +0x000000c2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000002, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 Retry_en=0 Retry_cnt=0*/ +0x00000002, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x00000004, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 Retry_en=0 Retry_cnt=0*/ +0x00000004, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x000000d0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GFX_PS ADDR=0x20e080340 Retry_en=0 Retry_cnt=0*/ +0x000000d0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08041, /* WR:PMGR_PS_SEP_PS ADDR=0x20e080400 */ +0x00000000, /* Offset */ +0x4000000f, /* Data */ +0x20e08042, /* Poll:PMGR_PS_SEP_PS ADDR=0x20e080400 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +/* Comment: // Per CoreOS request, turn off the above PS registers (except SEP_PS, which cannot be turned off by config engine) */ +0x20e08809, /* 3-word write */ +0x00040200, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x20e08019, /* 7-word write */ +0xb8bec2d0, /* Offset */ +0x00aab2b4, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x00000000, /* Data WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x00000000, /* Data WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x00000000, /* Data WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x00000000, /* Data WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x00000000, /* Data WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x00000000, /* Data WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +/* Comment: // Set the proxy clock back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +}; + +// +// This additional stitch point is an intentional deviation from the SEG-provided +// sequence. +// +#define D2A_POST_PREBOOT_BEFORE 2 +static const uint32_t aop_ddr_to_awake_post_2[] = { +/* Comment: // Boot CPU0 by writing to the WAKE_CORES register */ +0x20e0d401, /* WR:PMGR_MISC_CORES_WAKE_CORES ADDR=0x20e0d4008 */ +0x00000002, /* Offset */ +0x00000001 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + + +typedef struct { + uint32_t *sequence; + size_t elements; +} reconfig_subsequence_t; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_pre_0, sizeof(aop_ddr_to_awake_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_pre_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_pre_0, sizeof(awake_to_aop_ddr_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_s2r_aop_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_s2r_aop_pre_0, sizeof(aop_ddr_to_s2r_aop_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_post_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_post_0, sizeof(s2r_aop_to_aop_ddr_post_0) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_1, sizeof(s2r_aop_to_aop_ddr_post_1) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_2, sizeof(s2r_aop_to_aop_ddr_post_2) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_3, sizeof(s2r_aop_to_aop_ddr_post_3) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_pre_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_pre_0, sizeof(s2r_aop_to_aop_ddr_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_post_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_post_0, sizeof(aop_ddr_to_awake_post_0) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_post_1, sizeof(aop_ddr_to_awake_post_1) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_post_2, sizeof(aop_ddr_to_awake_post_2) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_post_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_post_0, sizeof(awake_to_aop_ddr_post_0) / sizeof(uint32_t) }, + { (uint32_t *) awake_to_aop_ddr_post_1, sizeof(awake_to_aop_ddr_post_1) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +#endif // AOP_CONFIG_SEQUENCES_H diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000_b0.h b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000_b0.h new file mode 100644 index 0000000..9308a97 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8000_b0.h @@ -0,0 +1,1475 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef AOP_CONFIG_SEQUENCES_B0_H +#define AOP_CONFIG_SEQUENCES_B0_H + +#include "reconfig_sequences_mcu_1200_s8000_b0.h" + +// _ _ _ _ +// / \ _ _| |_ ___ __ _ ___ _ __ ___ _ __ __ _| |_ ___ __| | +// / _ \| | | | __/ _ \ / _` |/ _ \ '_ \ / _ \ '__/ _` | __/ _ \/ _` | +// / ___ \ |_| | || (_) | (_| | __/ | | | __/ | | (_| | || __/ (_| | +// /_/ \_\__,_|\__\___/ \__, |\___|_| |_|\___|_| \__,_|\__\___|\__,_| +// ____ |___/ _____ _ _ _ +// | _ \ ___ _ __ ___ | |_ | ____|__| (_) |_ +// | | | |/ _ \ | '_ \ / _ \| __| | _| / _` | | __| +// | |_| | (_) | | | | | (_) | |_ | |__| (_| | | |_ +// |____/ \___/ |_| |_|\___/ \__| |_____\__,_|_|\__| +// + +/* + * Generated from DV reconfig drop using the following cmd: + * $ cat aop_soc_engine_1200.h | sed -Ee 's/((s2r_aop|aop_ddr|awake)_to_(s2r_aop|aop_ddr|awake)_)/\1b0_/g' > aop_soc_engine_1200_b0.h + */ + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP SOC CONFIG SEQUENCES */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** RELEASE NOTES */ +/* Comment: // ** */ +/* Comment: // ** -- 2/23/2015 -- */ +/* Comment: // ** Removed MccLockRegion programming from SOC sequences. Added "INSERT_MCU_DDR_LOCKED" */ +/* Comment: // ** comment label to indicate where to stitch in MCU DV LockRegion subsequence. */ +/* Comment: // ** */ +/* Comment: // ** Fixed incorrect fix to radar 16219268 which left PCIE_PS on during AOP_DDR. */ +/* Comment: // ** */ +/* Comment: // ** Reset AIC during AWAKE->AOP_DDR pre-amble. */ +/* Comment: // ** */ +/* Comment: // ** -- 2/8/2015 -- */ +/* Comment: // ** Added "verbatim" command which will print the specified text verbatim in the final */ +/* Comment: // ** output file. This is used for putting #defines into the final header file for SW. */ +/* Comment: // ** */ +/* Comment: // ** Ported "ifdef" processing from Elba. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/29/2015 -- */ +/* Comment: // ** Updated sequences based on CoreOS feedback from radars 19132562 and 19148279. */ +/* Comment: // ** Added "stitch" command to stitch in sequences from external files. Intended to */ +/* Comment: // ** explicitly annotate which sequences are meant to be overridden by SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/26/2015 -- */ +/* Comment: // ** Disable DynPwrDn in AOP_DDR (see radar 19338346) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/17/2014 -- */ +/* Comment: // ** Update programming of PLL0_CTL (see radar 18899788) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/12/2014 -- */ +/* Comment: // ** Added S2R_AOP->AOP_DDR preamble which polls for proxy_osc_clk to be equal to lpo/8. */ +/* Comment: // ** Activating the S2R_AOP->AOP_DDR preamble forces the LPO to be on prior to the */ +/* Comment: // ** AOP-PMU handshake. See radar 18563566 for details. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/22/2014 -- */ +/* Comment: // ** Config engine changes the current perf state to 0 prior to polling. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/26/2014 -- */ +/* Comment: // ** Instead of implicitly stitching the 48->800 MCU sequence at the beginning of the */ +/* Comment: // ** AOP_DDR->AWAKE sequence, it is now inserted at the comment token labeled */ +/* Comment: // ** "INSERT_MCU_AWAKE_SEQ". This will make the sequence more flexible in case commands */ +/* Comment: // ** are to be inserted before the MCU sequence, e.g., changing tunables. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/20/2014 -- */ +/* Comment: // ** Added more documentation to aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/4/2014 -- */ +/* Comment: // ** In this update, we removed the need to specify reg_addr in the write/write64/poll */ +/* Comment: // ** commands. The reg_addr was prone to human error because it was manually written, */ +/* Comment: // ** so there is no guarantee that the address matches the register name. Furthermore, */ +/* Comment: // ** manually specifying the register address is not future-proof because addresses of */ +/* Comment: // ** registers may change from chip to chip. */ +/* Comment: // ** */ +/* Comment: // ** Now, the register address are calculated based on the register name and the include */ +/* Comment: // ** files. The user must ensure that all of the header files needed are specified */ +/* Comment: // ** using the "include:" command. In the DV environment, these header files were */ +/* Comment: // ** generated from SPDS. */ +/* Comment: // ** */ +/* Comment: // ** Note: For legacy reasons, we still support manually specifying the reg_addr field. */ +/* Comment: // ** If the reg_addr field is specified, the reg_name field is ignored during the */ +/* Comment: // ** generation of the .h file. */ +/* Comment: // ** */ +/* Comment: // ** We also renamed the file type of this file from .h to .seq. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ** This file contains the AOP SoC config sequences verified by DV. It is written in a */ +/* Comment: // ** pseudo-language that is parsed by the scripts described in the "Related files" section */ +/* Comment: // ** below. All commands must be contained within a single line. */ +/* Comment: // ** */ +/* Comment: // ** The supported commands are: */ +/* Comment: // ** */ +/* Comment: // ** include: */ +/* Comment: // ** Header file to include for looking up register addresses. The path to the include */ +/* Comment: // ** files is provided as an argument to the aop_func_gen.pl script described below. */ +/* Comment: // ** */ +/* Comment: // ** seq_name: */ +/* Comment: // ** Designates the start of a sequence. The supported sequences are: */ +/* Comment: // ** s2r_aop_to_aop_ddr_b0_pre */ +/* Comment: // ** s2r_aop_to_aop_ddr_b0_post */ +/* Comment: // ** aop_ddr_to_s2r_aop_b0_pre */ +/* Comment: // ** aop_ddr_to_s2r_aop_b0_post */ +/* Comment: // ** aop_ddr_to_awake_b0_pre */ +/* Comment: // ** aop_ddr_to_awake_b0_post */ +/* Comment: // ** awake_to_aop_ddr_b0_pre */ +/* Comment: // ** awake_to_aop_ddr_b0_post */ +/* Comment: // ** Note that s2r_aop_to_aop_ddr_b0_pre and aop_ddr_to_s2r_aop_b0_post are currently unused. */ +/* Comment: // ** */ +/* Comment: // ** endseq */ +/* Comment: // ** Designates the end of a sequence. */ +/* Comment: // ** */ +/* Comment: // ** write: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 32-bit write command to the register at 36-bit hex
with 32-bit hex . */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write64: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 64-bit write command to the 36-bit hex
with 64-bit value , */ +/* Comment: // ** where "upper" is the upper 32-bit hex value, and "lower" is the lower 32-bit hex */ +/* Comment: // ** value. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write_start */ +/* Comment: // ** Designates the start of a write command with multiple register writes. Refer to */ +/* Comment: // ** AOP spec section 6.1 "Configuration Write Command" for details. Because the */ +/* Comment: // ** annotation with "write_start" and "write_end" is manually done, it is the */ +/* Comment: // ** responsibility of the author to ensure that the combined writes are within the */ +/* Comment: // ** same 1KB block, and a max of 16 writes is included. */ +/* Comment: // ** */ +/* Comment: // ** write_end */ +/* Comment: // ** Designates the end of a multi-register write command. */ +/* Comment: // ** */ +/* Comment: // ** poll: reg_name= [reg_addr=
] reg_value= reg_mask= retry_en= retry_cnt= */ +/* Comment: // ** Reads 36-bit
until (read_data & mask == value). If is 0, the */ +/* Comment: // ** poll repeats indefinitely. If is set, the read is retried up to */ +/* Comment: // ** times. As with "write" and "write64", is not used. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** cfg_cnt: */ +/* Comment: // ** designates the number of aop_clk cycles to wait before executing the next */ +/* Comment: // ** command. */ +/* Comment: // ** */ +/* Comment: // ** cfg_end */ +/* Comment: // ** Designates the Configuration End Command. */ +/* Comment: // ** */ +/* Comment: // ** comment: */ +/* Comment: // ** Designates a comment. */ +/* Comment: // ** */ +/* Comment: // ** stitch: */ +/* Comment: // ** Stitches file.seq into the sequence inline. */ +/* Comment: // ** */ +/* Comment: // ** stitch_h: */ +/* Comment: // ** In the generated .h file, an explicit #include "file.h" will appear at this line. */ +/* Comment: // ** */ +/* Comment: // ** Related files: */ +/* Comment: // ** tb_lib/cpu/armv7/aop_lib/aop_func_gen.pl */ +/* Comment: // ** This script parses this file (aop_soc_cfg.h) and converts it into an intermediate */ +/* Comment: // ** C header format. The output file contains C arrays whose contents are in a format */ +/* Comment: // ** understood by the SOC config engine. In the DV environment, the intermediate C */ +/* Comment: // ** header file is called aop_soc_engine.h and is placed in the testgen* directory of */ +/* Comment: // ** the test results directory. The intermediate file and MCU config sequences are */ +/* Comment: // ** combined using the powgen_common.pl script, described below. */ +/* Comment: // ** */ +/* Comment: // ** tb_lib/cpu/armv8/mcu/mcu_init_aop.h */ +/* Comment: // ** Provided by the MCU team, mcu_init_aop.h contains the two sequences for configuring */ +/* Comment: // ** the DDR to operate at 48MHz and >= 800MHz. The 48MHz sequence is stitched into the */ +/* Comment: // ** S2R_AOP->AOP_DDR postamble at the comment token "INSERT_MCU_AOP_DDR_SEQ". The */ +/* Comment: // ** >= 800 MHz sequence is stitched into the AOP_DDR->AWAKE postamble at the comment */ +/* Comment: // ** token "INSERT_MCU_AWAKE_SEQ". */ +/* Comment: // ** */ +/* Comment: // ** chip/tb/cpu/bin/powgen_common.pl */ +/* Comment: // ** This script stitches together the aop_soc_engine.h file generated by aop_func_gen.pl */ +/* Comment: // ** and mcu_init_aop.h into the same AP EHEX file that is loaded into memory. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Poll for the proxy_osc clock to source LPO/8 before initiating minipmgr reset sequence */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_b0_pre_0[] = { +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG ADDR=0x210240304 Retry_en=0 Retry_cnt=0*/ +0x000000c1, /* Offset */ +0x40300000, /* Mask */ +0x00200000, /* Data */ +/* Comment: // Do a dummy read to the AOP CPU revision register to cause a functional wakeup */ +0x21080002, /* Poll:AKF_AKFAPB_AKF_REV(GBI_AOP_AKF) ADDR=0x210800000 Retry_en=1 Retry_cnt=597*/ +0x00035500, /* Offset */ +0x00000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000004, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_b0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** This sequence is split into multiple subsequences */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_b0_post_0[] = { +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000000, /* Data */ +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Security sequence */ +/* Comment: // Write mem cache data and tag enable/lock bits to prevent backdoor access as RAM attacks */ +0x20000041, /* WR:AMCC_MCCCFG_MCCGEN ADDR=0x200000780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +/* Comment: // Write lockable DRAM config regs */ +/* Comment: // INSERT_MCU_DDR_LOCKED */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // The MCU LockRegion programming must occur before the security/TZ programming (s2r_aop_to_aop_ddr_b0_post_security) */ +#define S2D_POST_MCU_LOCKED_AFTER 0 +#define S2D_POST_MCU_LOCKED_BEFORE 1 +/* Comment: // The security/TZ programming must occur after the MCU LockRegion programming */ +#define S2D_POST_SECURITY_AFTER 0 +#define S2D_POST_SECURITY_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR security postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_b0_post_security[] = { +/* Comment: // Enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20000049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR ADDR=0x200000480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR ADDR=0x200000484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // Enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20000049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR ADDR=0x200000488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR ADDR=0x20000048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_b0_post_1[] = { +/* Comment: // Disable AP_GID0 */ +0x2102d001, /* WR:MINIPMGR_SECURITY_SIO_AES_DISABLE ADDR=0x2102d0000 */ +0x00000000, /* Offset */ +0x00000002, /* Data */ +/* Comment: // SRAM region that must be locked ends here. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SW: */ +/* Comment: // ** */ +/* Comment: // ** Locked region is specified in 64B granularity. If the last security entry does not */ +/* Comment: // ** land neatly at the end of a 64B boundary, some non-security entries may be locked if */ +/* Comment: // ** no additional padding is used. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // Disable voltage changes (see radar 16038537) */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SiVal/SW: */ +/* Comment: // ** */ +/* Comment: // ** Per Manu, perf state entry 0 has been reserved for use by the config engine. SW agreed */ +/* Comment: // ** to use the perf state entries starting from the higher indices. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // transition the fabric and DRAM to work off the proxy clocks */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Clear the CSYSPWRUPREQ_LOOPBACK bit. See PMGR spec section 11.4.4.1 */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000000 /* Data */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define S2D_POST_PWRGATE_AFTER 1 +#define S2D_POST_PWRGATE_BEFORE 2 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_b0_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_b0_post_2[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08035, /* 14-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0xba4294a4, /* Offset */ +0x00005244, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001 /* Data */ +}; + +#define S2D_POST_MCU_DDR_AFTER 2 +#define S2D_POST_MCU_DDR_BEFORE 3 +static const uint32_t s2r_aop_to_aop_ddr_b0_post_3[] = { +/* Comment: // INSERT_MCU_AOP_DDR_SEQ */ +/* Comment: // Wait for the memcache to reach 16 ways, then set it to 0 */ +0x20000042, /* Poll:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS ADDR=0x20000079c Retry_en=0 Retry_cnt=0*/ +0x000000e7, /* Offset */ +0x03e003e0, /* Mask */ +0x02000200, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000100, /* Data */ +/* Comment: // Set the proxy fabric clock frequency back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_b0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->S2R_AOP PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_s2r_aop_b0_pre_0[] = { +/* Comment: // Note - We do not wait for the memcache ways to reach 0 before yanking power. See radar 16051416 */ +/* Comment: // Set NO_HANDSHAKE bit prior to restoring the perf state table to its defaults, radar 16219268 */ +0x20e04081, /* WR:PMGR_CLKCTL_MCU_CLK_DEBUG ADDR=0x20e040810 */ +0x00000004, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Set all SRC_SEL for SOC clocks to 0 so there will be no clock glitches, radar 16409004 */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x00000030, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // power up PCIe/SIO/USB domain to bypass NLP:: Pcie2phy pwr clamp enable is going to X after warmboot in UPF simulations */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08025, /* 10-word write */ +0x9458a6a8, /* Offset */ +0x8e8c8ac4, /* Offset */ +0x00009290, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x0000000f, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=0 Retry_cnt=0*/ +0x000000a8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=0 Retry_cnt=0*/ +0x000000a6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=0 Retry_cnt=0*/ +0x00000058, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=0 Retry_cnt=0*/ +0x00000094, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=0 Retry_cnt=0*/ +0x000000c4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=0 Retry_cnt=0*/ +0x0000008a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=0 Retry_cnt=0*/ +0x0000008c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=0 Retry_cnt=0*/ +0x0000008e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=0 Retry_cnt=0*/ +0x00000090, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=0 Retry_cnt=0*/ +0x00000092, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // wait 100us to delay retention reset per radar 18727371 */ +0x0012c004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t aop_ddr_to_s2r_aop_b0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** See PMGR spec section 11.14.4 (Software Teardown for Awake Exit) */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_b0_pre_0[] = { +/* Comment: // Restore the GPIO to its default configuration by setting GPIO_PS.RESET for 1us while setting MANUAL_PS to RUN_MAX */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x8000000f, /* Data */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x00000004, /* Data */ +/* Comment: // Disable voltage changes */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +0x20e06811, /* 5-word write */ +0x07060504, /* Offset */ +0x00000000, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0D ADDR=0x20e06801c */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Per radar 19338346, disable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +/* Comment: // Power off PLLs that software could not turn off (ENABLE == 0 and BYPASS == 1) */ +0x20e00001, /* WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x00000000, /* Offset */ +0x28190060, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x00000000, /* Offset */ +0x280b4030, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x00000000, /* Offset */ +0x2804201f, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t awake_to_aop_ddr_b0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.4 (Software Teardown for Awake Exit), either */ +/* Comment: // ** SW or the config engine may turn off SIO/PCIE. For DV simulations, we chose to power */ +/* Comment: // ** power down ALL of the unneeded blocks in the config engine rather than from the AP. This */ +/* Comment: // ** provided functionally equivalent behavior and allowed the AWAKE->AOP_DDR and */ +/* Comment: // ** S2R_AOP->AOP_DDR to appear symmetric. SiVal/SW may move parts of this sequence */ +/* Comment: // ** to AP software if desired. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_b0_post_0[] = { +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define A2D_POST_PWRGATE_AFTER 0 +#define A2D_POST_PWRGATE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AWAKE->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_b0_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t awake_to_aop_ddr_b0_post_1[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08031, /* 13-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0x44ba94a4, /* Offset */ +0x00000052, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e0b83d, /* 16-word write */ +0x03020100, /* Offset */ +0x07060504, /* Offset */ +0x13121110, /* Offset */ +0x17161514, /* Offset */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH0 ADDR=0x20e0b8000 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH1 ADDR=0x20e0b8004 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH2 ADDR=0x20e0b8008 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH3 ADDR=0x20e0b800c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH4 ADDR=0x20e0b8010 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH5 ADDR=0x20e0b8014 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH6 ADDR=0x20e0b8018 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH7 ADDR=0x20e0b801c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH16 ADDR=0x20e0b8040 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH17 ADDR=0x20e0b8044 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH18 ADDR=0x20e0b8048 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH19 ADDR=0x20e0b804c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH20 ADDR=0x20e0b8050 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH21 ADDR=0x20e0b8054 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH22 ADDR=0x20e0b8058 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH23 ADDR=0x20e0b805c */ +/* Comment: // Reset and then clock gate the AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e10001, /* WR:AIC_GLOBALS_AICRST ADDR=0x20e10000c */ +0x00000003, /* Offset */ +0x00000001, /* Data */ +0x20e10002, /* Poll:AIC_GLOBALS_AICRST ADDR=0x20e10000c Retry_en=1 Retry_cnt=255*/ +0x0001ff03, /* Offset */ +0x00000001, /* Mask */ +0x00000000, /* Data */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x00000000, /* Data */ +0x2102b005, /* 2-word write */ +0x00000400, /* Offset */ +0x00000000, /* Data WR:MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER ADDR=0x2102b0000 */ +0x00000000 /* Data WR:MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER ADDR=0x2102b0010 */ +}; + +static const uint32_t awake_to_aop_ddr_b0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_b0_pre_0[] = { +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000110, /* Data */ +/* Comment: // Powering up SIO partition and SIO devices */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000058, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=1 Retry_cnt=255*/ +0x0001ff58, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000056, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_P_PS ADDR=0x20e080158 Retry_en=1 Retry_cnt=255*/ +0x0001ff56, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000004, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000004, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000004, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000004, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000004, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000004, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000004, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000004, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000004, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000004, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000004, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000004, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000004, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000004, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000004, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0801d, /* 8-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000004, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000004, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000004, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000004, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000004, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000004, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000004, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +/* Comment: // It might not be required to do all of the following polls since they should take the same amount of time to power up. */ +/* Comment: // One possible optimization is to only do the poll for the last write */ +0x20e08002, /* Poll:PMGR_PS_MCA0_PS ADDR=0x20e080168 Retry_en=1 Retry_cnt=255*/ +0x0001ff5a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA1_PS ADDR=0x20e080170 Retry_en=1 Retry_cnt=255*/ +0x0001ff5c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA2_PS ADDR=0x20e080178 Retry_en=1 Retry_cnt=255*/ +0x0001ff5e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA3_PS ADDR=0x20e080180 Retry_en=1 Retry_cnt=255*/ +0x0001ff60, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA4_PS ADDR=0x20e080188 Retry_en=1 Retry_cnt=255*/ +0x0001ff62, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PWM0_PS ADDR=0x20e080190 Retry_en=1 Retry_cnt=255*/ +0x0001ff64, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C0_PS ADDR=0x20e080198 Retry_en=1 Retry_cnt=255*/ +0x0001ff66, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 Retry_en=1 Retry_cnt=255*/ +0x0001ff68, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 Retry_en=1 Retry_cnt=255*/ +0x0001ff6c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 Retry_en=1 Retry_cnt=255*/ +0x0001ff70, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 Retry_en=1 Retry_cnt=255*/ +0x0001ff72, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 Retry_en=1 Retry_cnt=255*/ +0x0001ff74, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART0_PS ADDR=0x20e0801d8 Retry_en=1 Retry_cnt=255*/ +0x0001ff76, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART1_PS ADDR=0x20e0801e0 Retry_en=1 Retry_cnt=255*/ +0x0001ff78, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART2_PS ADDR=0x20e0801e8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART3_PS ADDR=0x20e0801f0 Retry_en=1 Retry_cnt=255*/ +0x0001ff7c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART4_PS ADDR=0x20e0801f8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART5_PS ADDR=0x20e080200 Retry_en=1 Retry_cnt=255*/ +0x0001ff80, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART6_PS ADDR=0x20e080208 Retry_en=1 Retry_cnt=255*/ +0x0001ff82, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART7_PS ADDR=0x20e080210 Retry_en=1 Retry_cnt=255*/ +0x0001ff84, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART8_PS ADDR=0x20e080218 Retry_en=1 Retry_cnt=255*/ +0x0001ff86, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AES0_PS ADDR=0x20e080220 Retry_en=1 Retry_cnt=255*/ +0x0001ff88, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up PCIE partition and PCIE devices/link */ +0x20e08001, /* WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x000000c4, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=1 Retry_cnt=255*/ +0x0001ffc4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xcccac8c6, /* Offset */ +0x000000ce, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08002, /* Poll:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 Retry_en=1 Retry_cnt=255*/ +0x0001ffc6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 Retry_en=1 Retry_cnt=255*/ +0x0001ffc8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 Retry_en=1 Retry_cnt=255*/ +0x0001ffca, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 Retry_en=1 Retry_cnt=255*/ +0x0001ffcc, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 Retry_en=1 Retry_cnt=255*/ +0x0001ffce, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up USB partition and USB devices */ +0x20e08001, /* WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000094, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0x9c9896a4, /* Offset */ +0x000000a0, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000004, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x20e08002, /* Poll:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 Retry_en=1 Retry_cnt=255*/ +0x0001ffa4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 Retry_en=1 Retry_cnt=255*/ +0x0001ff96, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 Retry_en=1 Retry_cnt=255*/ +0x0001ff98, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 Retry_en=1 Retry_cnt=255*/ +0x0001ff9c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 Retry_en=1 Retry_cnt=255*/ +0x0001ffa0, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08009, /* 3-word write */ +0x00a29e9a, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 Retry_en=1 Retry_cnt=255*/ +0x0001ff9a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 Retry_en=1 Retry_cnt=255*/ +0x0001ff9e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 Retry_en=1 Retry_cnt=255*/ +0x0001ffa2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x000000ba, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PMP_PS ADDR=0x20e0802e8 Retry_en=1 Retry_cnt=255*/ +0x0001ffba, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Restore PMS, SBR, SF, SMX, MCC, and DCS* PS to reset values per CoreOS request from radar 19132562 */ +0x20e0802d, /* 12-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x52444692, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=1 Retry_cnt=255*/ +0x0001ffa8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=1 Retry_cnt=255*/ +0x0001ffa6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=1 Retry_cnt=255*/ +0x0001ff8a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80101000, /* Data */ +/* Comment: // wait 1us */ +0x00003004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_awake_b0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.3 (Software Init for AOP_DDR to AWAKE), the */ +/* Comment: // ** config engine restores the state of the chip in this step. The specific use cases where */ +/* Comment: // ** the config engine is the owner of state restoration are not yet defined. */ +/* Comment: // ** */ +/* Comment: // ** The sequence below contains the minimum set of commands to re-boot the AP and restore */ +/* Comment: // ** DRAM operation at bucket 1 for SOC DV simulations. AP may bring DRAM up to bucket 0. */ +/* Comment: // ** */ +/* Comment: // ** It is assumed that SW will modify this sequence extensively. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +#define D2A_POST_MCU_AWAKE_AFTER -1 +#define D2A_POST_MCU_AWAKE_BEFORE 0 +static const uint32_t aop_ddr_to_awake_b0_post_0[] = { +/* Comment: // Wait 900us as first step of AOP_DDR->AWAKE per radar 20181763 to ensure BIRA loading is complete */ +/* Comment: // prior to powering on any non-AOP power domain */ +0x00a8c004, /* Cfg Count(Delay.Wait) */ +/* Comment: // INSERT_MCU_AWAKE_SEQ */ +/* Comment: // Restore the state of the chip */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80100000, /* Data */ +/* Comment: // wait 1us */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +#define D2A_POST_RESTORE_AFTER 0 +#define D2A_POST_RESTORE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AOP_DDR->AWAKE system restore postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_b0_post_restore[] = { +0x20e00005, /* 2-word write */ +0x00000100, /* Offset */ +0xa0190060, /* Data WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x10000010, /* Data WR:PMGR_PLL0_CFG ADDR=0x20e000004 */ +0x20e00002, /* Poll:PMGR_PLL0_CTL ADDR=0x20e000000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_PLL_DELAY_CTL1 ADDR=0x20e004020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00405, /* 2-word write */ +0x00000001, /* Offset */ +0x50480030, /* Data WR:PMGR_PLL1_CFG ADDR=0x20e004004 */ +0xa00b4030, /* Data WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x20e00402, /* Poll:PMGR_PLL1_CTL ADDR=0x20e004000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Bring MCU up to bucket1. Note: It is up to the AP to config MCU to bucket0 */ +0x20e06819, /* 7-word write */ +0x08060504, /* Offset */ +0x00000a09, /* Offset */ +0x55555517, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x55656666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x88878807, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1A ADDR=0x20e068020 */ +0x67a76866, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1B ADDR=0x20e068024 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1C ADDR=0x20e068028 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Tunables may be re-applied here */ +0x20e08001, /* WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000044, /* Offset */ +0x0000024f, /* Data */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +// +// The removal of the items below from this model sequence is intentional. +// +//0x00000044, /* CFG Count to aling 64 bit write to 16 bytes address:*/ +//0x20205003, /* WR:ACC_CPU0_IMPL_IO_RVBAR ADDR=0x202050000 */ +//0x00000000, /* Offset */ +//0x00000000, /* Data */ +//0x00000008 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_b0_post_1[] = { +/* Comment: // Per radar 19338346, re-enable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +/* Comment: // Per radar 20183074, turn the following partitions on one at a time */ +0x20e08001, /* WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +0x000000aa, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 Retry_en=0 Retry_cnt=0*/ +0x000000aa, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x000000b2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_ISP_PS ADDR=0x20e0802c8 Retry_en=0 Retry_cnt=0*/ +0x000000b2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x000000b4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 Retry_en=0 Retry_cnt=0*/ +0x000000b4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x000000b8, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MSR_PS ADDR=0x20e0802e0 Retry_en=0 Retry_cnt=0*/ +0x000000b8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x000000be, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 Retry_en=0 Retry_cnt=0*/ +0x000000be, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x000000c2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 Retry_en=0 Retry_cnt=0*/ +0x000000c2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000002, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 Retry_en=0 Retry_cnt=0*/ +0x00000002, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x00000004, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 Retry_en=0 Retry_cnt=0*/ +0x00000004, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x000000d0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GFX_PS ADDR=0x20e080340 Retry_en=0 Retry_cnt=0*/ +0x000000d0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08041, /* WR:PMGR_PS_SEP_PS ADDR=0x20e080400 */ +0x00000000, /* Offset */ +0x4000000f, /* Data */ +0x20e08042, /* Poll:PMGR_PS_SEP_PS ADDR=0x20e080400 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +/* Comment: // Per CoreOS request, turn off the above PS registers (except SEP_PS, which cannot be turned off by config engine) */ +0x20e08809, /* 3-word write */ +0x00040200, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x20e08019, /* 7-word write */ +0xb8bec2d0, /* Offset */ +0x00aab2b4, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x00000000, /* Data WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x00000000, /* Data WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x00000000, /* Data WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x00000000, /* Data WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x00000000, /* Data WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x00000000, /* Data WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +/* Comment: // Set the proxy clock back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +}; + +// +// This additional stitch point is an intentional deviation from the SEG-provided +// sequence. +// +#define D2A_POST_PREBOOT_BEFORE 2 +static const uint32_t aop_ddr_to_awake_b0_post_2[] = { +/* Comment: // Boot CPU0 by writing to the WAKE_CORES register */ +0x20e0d401, /* WR:PMGR_MISC_CORES_WAKE_CORES ADDR=0x20e0d4008 */ +0x00000002, /* Offset */ +0x00000001 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_b0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +// +// Intentional removal of the following definition which would otherwise duplicate the definition from the C0 sequence +// +//typedef struct { +// uint32_t *sequence; +// size_t elements; +//} reconfig_subsequence_t; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_b0_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_b0_pre_0, sizeof(aop_ddr_to_awake_b0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_b0_pre_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_b0_pre_0, sizeof(awake_to_aop_ddr_b0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_s2r_aop_b0_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_s2r_aop_b0_pre_0, sizeof(aop_ddr_to_s2r_aop_b0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_b0_post_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_b0_post_0, sizeof(s2r_aop_to_aop_ddr_b0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_b0_post_1, sizeof(s2r_aop_to_aop_ddr_b0_post_1) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_b0_post_2, sizeof(s2r_aop_to_aop_ddr_b0_post_2) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_b0_post_3, sizeof(s2r_aop_to_aop_ddr_b0_post_3) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_b0_pre_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_b0_pre_0, sizeof(s2r_aop_to_aop_ddr_b0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_b0_post_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_b0_post_0, sizeof(aop_ddr_to_awake_b0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_b0_post_1, sizeof(aop_ddr_to_awake_b0_post_1) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_b0_post_2, sizeof(aop_ddr_to_awake_b0_post_2) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_b0_post_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_b0_post_0, sizeof(awake_to_aop_ddr_b0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) awake_to_aop_ddr_b0_post_1, sizeof(awake_to_aop_ddr_b0_post_1) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +#endif // AOP_CONFIG_SEQUENCES_B0_H diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003.h b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003.h new file mode 100644 index 0000000..821c016 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003.h @@ -0,0 +1,1468 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef AOP_CONFIG_SEQUENCES_H +#define AOP_CONFIG_SEQUENCES_H + +#include "reconfig_sequences_mcu_1200_s8003.h" + +// _ _ _ _ +// / \ _ _| |_ ___ __ _ ___ _ __ ___ _ __ __ _| |_ ___ __| | +// / _ \| | | | __/ _ \ / _` |/ _ \ '_ \ / _ \ '__/ _` | __/ _ \/ _` | +// / ___ \ |_| | || (_) | (_| | __/ | | | __/ | | (_| | || __/ (_| | +// /_/ \_\__,_|\__\___/ \__, |\___|_| |_|\___|_| \__,_|\__\___|\__,_| +// ____ |___/ _____ _ _ _ +// | _ \ ___ _ __ ___ | |_ | ____|__| (_) |_ +// | | | |/ _ \ | '_ \ / _ \| __| | _| / _` | | __| +// | |_| | (_) | | | | | (_) | |_ | |__| (_| | | |_ +// |____/ \___/ |_| |_|\___/ \__| |_____\__,_|_|\__| +// + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP SOC CONFIG SEQUENCES */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** RELEASE NOTES */ +/* Comment: // ** */ +/* Comment: // ** -- 2/23/2015 -- */ +/* Comment: // ** Removed MccLockRegion programming from SOC sequences. Added "INSERT_MCU_DDR_LOCKED" */ +/* Comment: // ** comment label to indicate where to stitch in MCU DV LockRegion subsequence. */ +/* Comment: // ** */ +/* Comment: // ** Fixed incorrect fix to radar 16219268 which left PCIE_PS on during AOP_DDR. */ +/* Comment: // ** */ +/* Comment: // ** Reset AIC during AWAKE->AOP_DDR pre-amble. */ +/* Comment: // ** */ +/* Comment: // ** -- 2/8/2015 -- */ +/* Comment: // ** Added "verbatim" command which will print the specified text verbatim in the final */ +/* Comment: // ** output file. This is used for putting #defines into the final header file for SW. */ +/* Comment: // ** */ +/* Comment: // ** Ported "ifdef" processing from Elba. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/29/2015 -- */ +/* Comment: // ** Updated sequences based on CoreOS feedback from radars 19132562 and 19148279. */ +/* Comment: // ** Added "stitch" command to stitch in sequences from external files. Intended to */ +/* Comment: // ** explicitly annotate which sequences are meant to be overridden by SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/26/2015 -- */ +/* Comment: // ** Disable DynPwrDn in AOP_DDR (see radar 19338346) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/17/2014 -- */ +/* Comment: // ** Update programming of PLL0_CTL (see radar 18899788) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/12/2014 -- */ +/* Comment: // ** Added S2R_AOP->AOP_DDR preamble which polls for proxy_osc_clk to be equal to lpo/8. */ +/* Comment: // ** Activating the S2R_AOP->AOP_DDR preamble forces the LPO to be on prior to the */ +/* Comment: // ** AOP-PMU handshake. See radar 18563566 for details. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/22/2014 -- */ +/* Comment: // ** Config engine changes the current perf state to 0 prior to polling. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/26/2014 -- */ +/* Comment: // ** Instead of implicitly stitching the 48->800 MCU sequence at the beginning of the */ +/* Comment: // ** AOP_DDR->AWAKE sequence, it is now inserted at the comment token labeled */ +/* Comment: // ** "INSERT_MCU_AWAKE_SEQ". This will make the sequence more flexible in case commands */ +/* Comment: // ** are to be inserted before the MCU sequence, e.g., changing tunables. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/20/2014 -- */ +/* Comment: // ** Added more documentation to aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/4/2014 -- */ +/* Comment: // ** In this update, we removed the need to specify reg_addr in the write/write64/poll */ +/* Comment: // ** commands. The reg_addr was prone to human error because it was manually written, */ +/* Comment: // ** so there is no guarantee that the address matches the register name. Furthermore, */ +/* Comment: // ** manually specifying the register address is not future-proof because addresses of */ +/* Comment: // ** registers may change from chip to chip. */ +/* Comment: // ** */ +/* Comment: // ** Now, the register address are calculated based on the register name and the include */ +/* Comment: // ** files. The user must ensure that all of the header files needed are specified */ +/* Comment: // ** using the "include:" command. In the DV environment, these header files were */ +/* Comment: // ** generated from SPDS. */ +/* Comment: // ** */ +/* Comment: // ** Note: For legacy reasons, we still support manually specifying the reg_addr field. */ +/* Comment: // ** If the reg_addr field is specified, the reg_name field is ignored during the */ +/* Comment: // ** generation of the .h file. */ +/* Comment: // ** */ +/* Comment: // ** We also renamed the file type of this file from .h to .seq. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ** This file contains the AOP SoC config sequences verified by DV. It is written in a */ +/* Comment: // ** pseudo-language that is parsed by the scripts described in the "Related files" section */ +/* Comment: // ** below. All commands must be contained within a single line. */ +/* Comment: // ** */ +/* Comment: // ** The supported commands are: */ +/* Comment: // ** */ +/* Comment: // ** include: */ +/* Comment: // ** Header file to include for looking up register addresses. The path to the include */ +/* Comment: // ** files is provided as an argument to the aop_func_gen.pl script described below. */ +/* Comment: // ** */ +/* Comment: // ** seq_name: */ +/* Comment: // ** Designates the start of a sequence. The supported sequences are: */ +/* Comment: // ** s2r_aop_to_aop_ddr_pre */ +/* Comment: // ** s2r_aop_to_aop_ddr_post */ +/* Comment: // ** aop_ddr_to_s2r_aop_pre */ +/* Comment: // ** aop_ddr_to_s2r_aop_post */ +/* Comment: // ** aop_ddr_to_awake_pre */ +/* Comment: // ** aop_ddr_to_awake_post */ +/* Comment: // ** awake_to_aop_ddr_pre */ +/* Comment: // ** awake_to_aop_ddr_post */ +/* Comment: // ** Note that s2r_aop_to_aop_ddr_pre and aop_ddr_to_s2r_aop_post are currently unused. */ +/* Comment: // ** */ +/* Comment: // ** endseq */ +/* Comment: // ** Designates the end of a sequence. */ +/* Comment: // ** */ +/* Comment: // ** write: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 32-bit write command to the register at 36-bit hex
with 32-bit hex . */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write64: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 64-bit write command to the 36-bit hex
with 64-bit value , */ +/* Comment: // ** where "upper" is the upper 32-bit hex value, and "lower" is the lower 32-bit hex */ +/* Comment: // ** value. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write_start */ +/* Comment: // ** Designates the start of a write command with multiple register writes. Refer to */ +/* Comment: // ** AOP spec section 6.1 "Configuration Write Command" for details. Because the */ +/* Comment: // ** annotation with "write_start" and "write_end" is manually done, it is the */ +/* Comment: // ** responsibility of the author to ensure that the combined writes are within the */ +/* Comment: // ** same 1KB block, and a max of 16 writes is included. */ +/* Comment: // ** */ +/* Comment: // ** write_end */ +/* Comment: // ** Designates the end of a multi-register write command. */ +/* Comment: // ** */ +/* Comment: // ** poll: reg_name= [reg_addr=
] reg_value= reg_mask= retry_en= retry_cnt= */ +/* Comment: // ** Reads 36-bit
until (read_data & mask == value). If is 0, the */ +/* Comment: // ** poll repeats indefinitely. If is set, the read is retried up to */ +/* Comment: // ** times. As with "write" and "write64", is not used. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** cfg_cnt: */ +/* Comment: // ** designates the number of aop_clk cycles to wait before executing the next */ +/* Comment: // ** command. */ +/* Comment: // ** */ +/* Comment: // ** cfg_end */ +/* Comment: // ** Designates the Configuration End Command. */ +/* Comment: // ** */ +/* Comment: // ** comment: */ +/* Comment: // ** Designates a comment. */ +/* Comment: // ** */ +/* Comment: // ** stitch: */ +/* Comment: // ** Stitches file.seq into the sequence inline. */ +/* Comment: // ** */ +/* Comment: // ** stitch_h: */ +/* Comment: // ** In the generated .h file, an explicit #include "file.h" will appear at this line. */ +/* Comment: // ** */ +/* Comment: // ** Related files: */ +/* Comment: // ** tb_lib/cpu/armv7/aop_lib/aop_func_gen.pl */ +/* Comment: // ** This script parses this file (aop_soc_cfg.h) and converts it into an intermediate */ +/* Comment: // ** C header format. The output file contains C arrays whose contents are in a format */ +/* Comment: // ** understood by the SOC config engine. In the DV environment, the intermediate C */ +/* Comment: // ** header file is called aop_soc_engine.h and is placed in the testgen* directory of */ +/* Comment: // ** the test results directory. The intermediate file and MCU config sequences are */ +/* Comment: // ** combined using the powgen_common.pl script, described below. */ +/* Comment: // ** */ +/* Comment: // ** tb_lib/cpu/armv8/mcu/mcu_init_aop.h */ +/* Comment: // ** Provided by the MCU team, mcu_init_aop.h contains the two sequences for configuring */ +/* Comment: // ** the DDR to operate at 48MHz and >= 800MHz. The 48MHz sequence is stitched into the */ +/* Comment: // ** S2R_AOP->AOP_DDR postamble at the comment token "INSERT_MCU_AOP_DDR_SEQ". The */ +/* Comment: // ** >= 800 MHz sequence is stitched into the AOP_DDR->AWAKE postamble at the comment */ +/* Comment: // ** token "INSERT_MCU_AWAKE_SEQ". */ +/* Comment: // ** */ +/* Comment: // ** chip/tb/cpu/bin/powgen_common.pl */ +/* Comment: // ** This script stitches together the aop_soc_engine.h file generated by aop_func_gen.pl */ +/* Comment: // ** and mcu_init_aop.h into the same AP EHEX file that is loaded into memory. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Poll for the proxy_osc clock to source LPO/8 before initiating minipmgr reset sequence */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_pre_0[] = { +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG ADDR=0x210240304 Retry_en=0 Retry_cnt=0*/ +0x000000c1, /* Offset */ +0x40300000, /* Mask */ +0x00200000, /* Data */ +/* Comment: // Do a dummy read to the AOP CPU revision register to cause a functional wakeup */ +0x21080002, /* Poll:AKF_AKFAPB_AKF_REV(GBI_AOP_AKF) ADDR=0x210800000 Retry_en=1 Retry_cnt=597*/ +0x00035500, /* Offset */ +0x00000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000004, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** This sequence is split into multiple subsequences */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_0[] = { +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000000, /* Data */ +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Security sequence */ +/* Comment: // Write mem cache data and tag enable/lock bits to prevent backdoor access as RAM attacks */ +0x20000041, /* WR:AMCC_MCCCFG_MCCGEN ADDR=0x200000780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +/* Comment: // Write lockable DRAM config regs */ +/* Comment: // INSERT_MCU_DDR_LOCKED */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // The MCU LockRegion programming must occur before the security/TZ programming (s2r_aop_to_aop_ddr_post_security) */ +#define S2D_POST_MCU_LOCKED_AFTER 0 +#define S2D_POST_MCU_LOCKED_BEFORE 1 +/* Comment: // The security/TZ programming must occur after the MCU LockRegion programming */ +#define S2D_POST_SECURITY_AFTER 0 +#define S2D_POST_SECURITY_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR security postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_security[] = { +/* Comment: // Enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20000049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR ADDR=0x200000480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR ADDR=0x200000484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // Enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20000049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR ADDR=0x200000488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR ADDR=0x20000048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_1[] = { +/* Comment: // Disable AP_GID0 */ +0x2102d001, /* WR:MINIPMGR_SECURITY_SIO_AES_DISABLE ADDR=0x2102d0000 */ +0x00000000, /* Offset */ +0x00000002, /* Data */ +/* Comment: // SRAM region that must be locked ends here. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SW: */ +/* Comment: // ** */ +/* Comment: // ** Locked region is specified in 64B granularity. If the last security entry does not */ +/* Comment: // ** land neatly at the end of a 64B boundary, some non-security entries may be locked if */ +/* Comment: // ** no additional padding is used. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // Disable voltage changes (see radar 16038537) */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SiVal/SW: */ +/* Comment: // ** */ +/* Comment: // ** Per Manu, perf state entry 0 has been reserved for use by the config engine. SW agreed */ +/* Comment: // ** to use the perf state entries starting from the higher indices. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // transition the fabric and DRAM to work off the proxy clocks */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Clear the CSYSPWRUPREQ_LOOPBACK bit. See PMGR spec section 11.4.4.1 */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000000 /* Data */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define S2D_POST_PWRGATE_AFTER 1 +#define S2D_POST_PWRGATE_BEFORE 2 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_2[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08035, /* 14-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0xba4294a4, /* Offset */ +0x00005244, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001 /* Data */ +}; + +#define S2D_POST_MCU_DDR_AFTER 2 +#define S2D_POST_MCU_DDR_BEFORE 3 +static const uint32_t s2r_aop_to_aop_ddr_post_3[] = { +/* Comment: // INSERT_MCU_AOP_DDR_SEQ */ +/* Comment: // Wait for the memcache to reach 16 ways, then set it to 0 */ +0x20000042, /* Poll:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS ADDR=0x20000079c Retry_en=0 Retry_cnt=0*/ +0x000000e7, /* Offset */ +0x03e003e0, /* Mask */ +0x02000200, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000100, /* Data */ +/* Comment: // Set the proxy fabric clock frequency back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->S2R_AOP PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_s2r_aop_pre_0[] = { +/* Comment: // Note - We do not wait for the memcache ways to reach 0 before yanking power. See radar 16051416 */ +/* Comment: // Set NO_HANDSHAKE bit prior to restoring the perf state table to its defaults, radar 16219268 */ +0x20e04081, /* WR:PMGR_CLKCTL_MCU_CLK_DEBUG ADDR=0x20e040810 */ +0x00000004, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Set all SRC_SEL for SOC clocks to 0 so there will be no clock glitches, radar 16409004 */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x00000030, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // power up PCIe/SIO/USB domain to bypass NLP:: Pcie2phy pwr clamp enable is going to X after warmboot in UPF simulations */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08025, /* 10-word write */ +0x9458a6a8, /* Offset */ +0x8e8c8ac4, /* Offset */ +0x00009290, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x0000000f, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=0 Retry_cnt=0*/ +0x000000a8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=0 Retry_cnt=0*/ +0x000000a6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=0 Retry_cnt=0*/ +0x00000058, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=0 Retry_cnt=0*/ +0x00000094, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=0 Retry_cnt=0*/ +0x000000c4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=0 Retry_cnt=0*/ +0x0000008a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=0 Retry_cnt=0*/ +0x0000008c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=0 Retry_cnt=0*/ +0x0000008e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=0 Retry_cnt=0*/ +0x00000090, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=0 Retry_cnt=0*/ +0x00000092, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // wait 100us to delay retention reset per radar 18751992 */ +0x0012c004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t aop_ddr_to_s2r_aop_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** See PMGR spec section 11.14.4 (Software Teardown for Awake Exit) */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_pre_0[] = { +/* Comment: // Restore the GPIO to its default configuration by setting GPIO_PS.RESET for 1us while setting MANUAL_PS to RUN_MAX */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x8000000f, /* Data */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x00000004, /* Data */ +/* Comment: // Disable voltage changes */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +0x20e06811, /* 5-word write */ +0x07060504, /* Offset */ +0x00000000, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0D ADDR=0x20e06801c */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Per radar 19338346, disable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +/* Comment: // Power off PLLs that software could not turn off (ENABLE == 0 and BYPASS == 1) */ +0x20e00001, /* WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x00000000, /* Offset */ +0x28190060, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x00000000, /* Offset */ +0x280b4030, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x00000000, /* Offset */ +0x2804201f, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t awake_to_aop_ddr_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.4 (Software Teardown for Awake Exit), either */ +/* Comment: // ** SW or the config engine may turn off SIO/PCIE. For DV simulations, we chose to power */ +/* Comment: // ** power down ALL of the unneeded blocks in the config engine rather than from the AP. This */ +/* Comment: // ** provided functionally equivalent behavior and allowed the AWAKE->AOP_DDR and */ +/* Comment: // ** S2R_AOP->AOP_DDR to appear symmetric. SiVal/SW may move parts of this sequence */ +/* Comment: // ** to AP software if desired. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_post_0[] = { +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define A2D_POST_PWRGATE_AFTER 0 +#define A2D_POST_PWRGATE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AWAKE->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t awake_to_aop_ddr_post_1[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08031, /* 13-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0x44ba94a4, /* Offset */ +0x00000052, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e0b83d, /* 16-word write */ +0x03020100, /* Offset */ +0x07060504, /* Offset */ +0x13121110, /* Offset */ +0x17161514, /* Offset */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH0 ADDR=0x20e0b8000 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH1 ADDR=0x20e0b8004 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH2 ADDR=0x20e0b8008 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH3 ADDR=0x20e0b800c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH4 ADDR=0x20e0b8010 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH5 ADDR=0x20e0b8014 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH6 ADDR=0x20e0b8018 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH7 ADDR=0x20e0b801c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH16 ADDR=0x20e0b8040 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH17 ADDR=0x20e0b8044 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH18 ADDR=0x20e0b8048 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH19 ADDR=0x20e0b804c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH20 ADDR=0x20e0b8050 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH21 ADDR=0x20e0b8054 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH22 ADDR=0x20e0b8058 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH23 ADDR=0x20e0b805c */ +/* Comment: // Reset and then clock gate the AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e10001, /* WR:AIC_GLOBALS_AICRST ADDR=0x20e10000c */ +0x00000003, /* Offset */ +0x00000001, /* Data */ +0x20e10002, /* Poll:AIC_GLOBALS_AICRST ADDR=0x20e10000c Retry_en=1 Retry_cnt=255*/ +0x0001ff03, /* Offset */ +0x00000001, /* Mask */ +0x00000000, /* Data */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x00000000, /* Data */ +0x2102b005, /* 2-word write */ +0x00000400, /* Offset */ +0x00000000, /* Data WR:MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER ADDR=0x2102b0000 */ +0x00000000 /* Data WR:MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER ADDR=0x2102b0010 */ +}; + +static const uint32_t awake_to_aop_ddr_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_pre_0[] = { +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000110, /* Data */ +/* Comment: // Powering up SIO partition and SIO devices */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000058, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=1 Retry_cnt=255*/ +0x0001ff58, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000056, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_P_PS ADDR=0x20e080158 Retry_en=1 Retry_cnt=255*/ +0x0001ff56, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000004, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000004, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000004, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000004, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000004, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000004, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000004, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000004, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000004, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000004, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000004, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000004, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000004, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000004, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000004, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0801d, /* 8-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000004, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000004, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000004, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000004, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000004, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000004, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000004, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +/* Comment: // It might not be required to do all of the following polls since they should take the same amount of time to power up. */ +/* Comment: // One possible optimization is to only do the poll for the last write */ +0x20e08002, /* Poll:PMGR_PS_MCA0_PS ADDR=0x20e080168 Retry_en=1 Retry_cnt=255*/ +0x0001ff5a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA1_PS ADDR=0x20e080170 Retry_en=1 Retry_cnt=255*/ +0x0001ff5c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA2_PS ADDR=0x20e080178 Retry_en=1 Retry_cnt=255*/ +0x0001ff5e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA3_PS ADDR=0x20e080180 Retry_en=1 Retry_cnt=255*/ +0x0001ff60, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA4_PS ADDR=0x20e080188 Retry_en=1 Retry_cnt=255*/ +0x0001ff62, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PWM0_PS ADDR=0x20e080190 Retry_en=1 Retry_cnt=255*/ +0x0001ff64, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C0_PS ADDR=0x20e080198 Retry_en=1 Retry_cnt=255*/ +0x0001ff66, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 Retry_en=1 Retry_cnt=255*/ +0x0001ff68, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 Retry_en=1 Retry_cnt=255*/ +0x0001ff6c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 Retry_en=1 Retry_cnt=255*/ +0x0001ff70, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 Retry_en=1 Retry_cnt=255*/ +0x0001ff72, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 Retry_en=1 Retry_cnt=255*/ +0x0001ff74, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART0_PS ADDR=0x20e0801d8 Retry_en=1 Retry_cnt=255*/ +0x0001ff76, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART1_PS ADDR=0x20e0801e0 Retry_en=1 Retry_cnt=255*/ +0x0001ff78, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART2_PS ADDR=0x20e0801e8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART3_PS ADDR=0x20e0801f0 Retry_en=1 Retry_cnt=255*/ +0x0001ff7c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART4_PS ADDR=0x20e0801f8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART5_PS ADDR=0x20e080200 Retry_en=1 Retry_cnt=255*/ +0x0001ff80, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART6_PS ADDR=0x20e080208 Retry_en=1 Retry_cnt=255*/ +0x0001ff82, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART7_PS ADDR=0x20e080210 Retry_en=1 Retry_cnt=255*/ +0x0001ff84, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART8_PS ADDR=0x20e080218 Retry_en=1 Retry_cnt=255*/ +0x0001ff86, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AES0_PS ADDR=0x20e080220 Retry_en=1 Retry_cnt=255*/ +0x0001ff88, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up PCIE partition and PCIE devices/link */ +0x20e08001, /* WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x000000c4, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=1 Retry_cnt=255*/ +0x0001ffc4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xcccac8c6, /* Offset */ +0x000000ce, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08002, /* Poll:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 Retry_en=1 Retry_cnt=255*/ +0x0001ffc6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 Retry_en=1 Retry_cnt=255*/ +0x0001ffc8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 Retry_en=1 Retry_cnt=255*/ +0x0001ffca, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 Retry_en=1 Retry_cnt=255*/ +0x0001ffcc, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 Retry_en=1 Retry_cnt=255*/ +0x0001ffce, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up USB partition and USB devices */ +0x20e08001, /* WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000094, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0x9c9896a4, /* Offset */ +0x000000a0, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000004, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x20e08002, /* Poll:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 Retry_en=1 Retry_cnt=255*/ +0x0001ffa4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 Retry_en=1 Retry_cnt=255*/ +0x0001ff96, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 Retry_en=1 Retry_cnt=255*/ +0x0001ff98, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 Retry_en=1 Retry_cnt=255*/ +0x0001ff9c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 Retry_en=1 Retry_cnt=255*/ +0x0001ffa0, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08009, /* 3-word write */ +0x00a29e9a, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 Retry_en=1 Retry_cnt=255*/ +0x0001ff9a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 Retry_en=1 Retry_cnt=255*/ +0x0001ff9e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 Retry_en=1 Retry_cnt=255*/ +0x0001ffa2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x000000ba, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PMP_PS ADDR=0x20e0802e8 Retry_en=1 Retry_cnt=255*/ +0x0001ffba, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Restore PMS, SBR, SF, SMX, MCC, and DCS* PS to reset values per CoreOS request from radar 19132562 */ +0x20e0802d, /* 12-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x52444692, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=1 Retry_cnt=255*/ +0x0001ffa8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=1 Retry_cnt=255*/ +0x0001ffa6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=1 Retry_cnt=255*/ +0x0001ff8a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80101000, /* Data */ +/* Comment: // wait 1us */ +0x00003004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_awake_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.3 (Software Init for AOP_DDR to AWAKE), the */ +/* Comment: // ** config engine restores the state of the chip in this step. The specific use cases where */ +/* Comment: // ** the config engine is the owner of state restoration are not yet defined. */ +/* Comment: // ** */ +/* Comment: // ** The sequence below contains the minimum set of commands to re-boot the AP and restore */ +/* Comment: // ** DRAM operation at bucket 1 for SOC DV simulations. AP may bring DRAM up to bucket 0. */ +/* Comment: // ** */ +/* Comment: // ** It is assumed that SW will modify this sequence extensively. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +#define D2A_POST_MCU_AWAKE_AFTER -1 +#define D2A_POST_MCU_AWAKE_BEFORE 0 +static const uint32_t aop_ddr_to_awake_post_0[] = { +/* Comment: // Wait 900us as first step of AOP_DDR->AWAKE per radar 20356875 to ensure BIRA loading is complete */ +/* Comment: // prior to powering on any non-AOP power domain */ +0x00a8c004, /* Cfg Count(Delay.Wait) */ +/* Comment: // INSERT_MCU_AWAKE_SEQ */ +/* Comment: // Restore the state of the chip */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80100000, /* Data */ +/* Comment: // wait 1us */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +#define D2A_POST_RESTORE_AFTER 0 +#define D2A_POST_RESTORE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AOP_DDR->AWAKE system restore postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_post_restore[] = { +0x20e00005, /* 2-word write */ +0x00000100, /* Offset */ +0xa0190060, /* Data WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x10000010, /* Data WR:PMGR_PLL0_CFG ADDR=0x20e000004 */ +0x20e00002, /* Poll:PMGR_PLL0_CTL ADDR=0x20e000000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_PLL_DELAY_CTL1 ADDR=0x20e004020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00405, /* 2-word write */ +0x00000001, /* Offset */ +0x50480030, /* Data WR:PMGR_PLL1_CFG ADDR=0x20e004004 */ +0xa00b4030, /* Data WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x20e00402, /* Poll:PMGR_PLL1_CTL ADDR=0x20e004000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Bring MCU up to bucket1. Note: It is up to the AP to config MCU to bucket0 */ +0x20e06819, /* 7-word write */ +0x08060504, /* Offset */ +0x00000a09, /* Offset */ +0x55555517, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x55656666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x88878807, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1A ADDR=0x20e068020 */ +0x67a76866, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1B ADDR=0x20e068024 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1C ADDR=0x20e068028 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Tunables may be re-applied here */ +0x20e08001, /* WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000044, /* Offset */ +0x0000024f, /* Data */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +// +// The removal of the items below from this model sequence is intentional. +// +//0x00000044, /* CFG Count to aling 64 bit write to 16 bytes address:*/ +//0x20205003, /* WR:ACC_CPU0_IMPL_IO_RVBAR ADDR=0x202050000 */ +//0x00000000, /* Offset */ +//0x00000000, /* Data */ +//0x00000008 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_post_1[] = { +/* Comment: // Per radar 19338346, re-enable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +/* Comment: // Per radar 20183074, turn the following partitions on one at a time */ +0x20e08001, /* WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +0x000000aa, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 Retry_en=0 Retry_cnt=0*/ +0x000000aa, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x000000b2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_ISP_PS ADDR=0x20e0802c8 Retry_en=0 Retry_cnt=0*/ +0x000000b2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x000000b4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 Retry_en=0 Retry_cnt=0*/ +0x000000b4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x000000b8, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MSR_PS ADDR=0x20e0802e0 Retry_en=0 Retry_cnt=0*/ +0x000000b8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x000000be, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 Retry_en=0 Retry_cnt=0*/ +0x000000be, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x000000c2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 Retry_en=0 Retry_cnt=0*/ +0x000000c2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000002, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 Retry_en=0 Retry_cnt=0*/ +0x00000002, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x00000004, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 Retry_en=0 Retry_cnt=0*/ +0x00000004, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x000000d0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GFX_PS ADDR=0x20e080340 Retry_en=0 Retry_cnt=0*/ +0x000000d0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08041, /* WR:PMGR_PS_SEP_PS ADDR=0x20e080400 */ +0x00000000, /* Offset */ +0x4000000f, /* Data */ +0x20e08042, /* Poll:PMGR_PS_SEP_PS ADDR=0x20e080400 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +/* Comment: // Per CoreOS request, turn off the above PS registers (except SEP_PS, which cannot be turned off by config engine) */ +0x20e08809, /* 3-word write */ +0x00040200, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x20e08019, /* 7-word write */ +0xb8bec2d0, /* Offset */ +0x00aab2b4, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x00000000, /* Data WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x00000000, /* Data WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x00000000, /* Data WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x00000000, /* Data WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x00000000, /* Data WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x00000000, /* Data WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +/* Comment: // Set the proxy clock back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +}; + +// +// This additional stitch point is an intentional deviation from the SEG-provided +// sequence. +// +#define D2A_POST_PREBOOT_BEFORE 2 +static const uint32_t aop_ddr_to_awake_post_2[] = { +/* Comment: // Boot CPU0 by writing to the WAKE_CORES register */ +0x20e0d401, /* WR:PMGR_MISC_CORES_WAKE_CORES ADDR=0x20e0d4008 */ +0x00000002, /* Offset */ +0x00000001 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + + +typedef struct { + uint32_t *sequence; + size_t elements; +} reconfig_subsequence_t; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_pre_0, sizeof(aop_ddr_to_awake_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_pre_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_pre_0, sizeof(awake_to_aop_ddr_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_s2r_aop_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_s2r_aop_pre_0, sizeof(aop_ddr_to_s2r_aop_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_post_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_post_0, sizeof(s2r_aop_to_aop_ddr_post_0) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_1, sizeof(s2r_aop_to_aop_ddr_post_1) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_2, sizeof(s2r_aop_to_aop_ddr_post_2) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_3, sizeof(s2r_aop_to_aop_ddr_post_3) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_pre_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_pre_0, sizeof(s2r_aop_to_aop_ddr_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_post_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_post_0, sizeof(aop_ddr_to_awake_post_0) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_post_1, sizeof(aop_ddr_to_awake_post_1) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_post_2, sizeof(aop_ddr_to_awake_post_2) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_post_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_post_0, sizeof(awake_to_aop_ddr_post_0) / sizeof(uint32_t) }, + { (uint32_t *) awake_to_aop_ddr_post_1, sizeof(awake_to_aop_ddr_post_1) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +#endif // AOP_CONFIG_SEQUENCES_H diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003_a0.h b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003_a0.h new file mode 100644 index 0000000..fdc42f6 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_1200_s8003_a0.h @@ -0,0 +1,1475 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef AOP_CONFIG_SEQUENCES_A0_H +#define AOP_CONFIG_SEQUENCES_A0_H + +#include "reconfig_sequences_mcu_1200_s8003_a0.h" + +// _ _ _ _ +// / \ _ _| |_ ___ __ _ ___ _ __ ___ _ __ __ _| |_ ___ __| | +// / _ \| | | | __/ _ \ / _` |/ _ \ '_ \ / _ \ '__/ _` | __/ _ \/ _` | +// / ___ \ |_| | || (_) | (_| | __/ | | | __/ | | (_| | || __/ (_| | +// /_/ \_\__,_|\__\___/ \__, |\___|_| |_|\___|_| \__,_|\__\___|\__,_| +// ____ |___/ _____ _ _ _ +// | _ \ ___ _ __ ___ | |_ | ____|__| (_) |_ +// | | | |/ _ \ | '_ \ / _ \| __| | _| / _` | | __| +// | |_| | (_) | | | | | (_) | |_ | |__| (_| | | |_ +// |____/ \___/ |_| |_|\___/ \__| |_____\__,_|_|\__| +// + +/* + * Generated from DV reconfig drop using the following cmd: + * $ cat aop_soc_engine_1200.h | sed -Ee 's/((s2r_aop|aop_ddr|awake)_to_(s2r_aop|aop_ddr|awake)_)/\1a0_/g' > aop_soc_engine_1200_a0.h + */ + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP SOC CONFIG SEQUENCES */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** RELEASE NOTES */ +/* Comment: // ** */ +/* Comment: // ** -- 2/23/2015 -- */ +/* Comment: // ** Removed MccLockRegion programming from SOC sequences. Added "INSERT_MCU_DDR_LOCKED" */ +/* Comment: // ** comment label to indicate where to stitch in MCU DV LockRegion subsequence. */ +/* Comment: // ** */ +/* Comment: // ** Fixed incorrect fix to radar 16219268 which left PCIE_PS on during AOP_DDR. */ +/* Comment: // ** */ +/* Comment: // ** Reset AIC during AWAKE->AOP_DDR pre-amble. */ +/* Comment: // ** */ +/* Comment: // ** -- 2/8/2015 -- */ +/* Comment: // ** Added "verbatim" command which will print the specified text verbatim in the final */ +/* Comment: // ** output file. This is used for putting #defines into the final header file for SW. */ +/* Comment: // ** */ +/* Comment: // ** Ported "ifdef" processing from Elba. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/29/2015 -- */ +/* Comment: // ** Updated sequences based on CoreOS feedback from radars 19132562 and 19148279. */ +/* Comment: // ** Added "stitch" command to stitch in sequences from external files. Intended to */ +/* Comment: // ** explicitly annotate which sequences are meant to be overridden by SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/26/2015 -- */ +/* Comment: // ** Disable DynPwrDn in AOP_DDR (see radar 19338346) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/17/2014 -- */ +/* Comment: // ** Update programming of PLL0_CTL (see radar 18899788) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/12/2014 -- */ +/* Comment: // ** Added S2R_AOP->AOP_DDR preamble which polls for proxy_osc_clk to be equal to lpo/8. */ +/* Comment: // ** Activating the S2R_AOP->AOP_DDR preamble forces the LPO to be on prior to the */ +/* Comment: // ** AOP-PMU handshake. See radar 18563566 for details. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/22/2014 -- */ +/* Comment: // ** Config engine changes the current perf state to 0 prior to polling. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/26/2014 -- */ +/* Comment: // ** Instead of implicitly stitching the 48->800 MCU sequence at the beginning of the */ +/* Comment: // ** AOP_DDR->AWAKE sequence, it is now inserted at the comment token labeled */ +/* Comment: // ** "INSERT_MCU_AWAKE_SEQ". This will make the sequence more flexible in case commands */ +/* Comment: // ** are to be inserted before the MCU sequence, e.g., changing tunables. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/20/2014 -- */ +/* Comment: // ** Added more documentation to aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/4/2014 -- */ +/* Comment: // ** In this update, we removed the need to specify reg_addr in the write/write64/poll */ +/* Comment: // ** commands. The reg_addr was prone to human error because it was manually written, */ +/* Comment: // ** so there is no guarantee that the address matches the register name. Furthermore, */ +/* Comment: // ** manually specifying the register address is not future-proof because addresses of */ +/* Comment: // ** registers may change from chip to chip. */ +/* Comment: // ** */ +/* Comment: // ** Now, the register address are calculated based on the register name and the include */ +/* Comment: // ** files. The user must ensure that all of the header files needed are specified */ +/* Comment: // ** using the "include:" command. In the DV environment, these header files were */ +/* Comment: // ** generated from SPDS. */ +/* Comment: // ** */ +/* Comment: // ** Note: For legacy reasons, we still support manually specifying the reg_addr field. */ +/* Comment: // ** If the reg_addr field is specified, the reg_name field is ignored during the */ +/* Comment: // ** generation of the .h file. */ +/* Comment: // ** */ +/* Comment: // ** We also renamed the file type of this file from .h to .seq. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ** This file contains the AOP SoC config sequences verified by DV. It is written in a */ +/* Comment: // ** pseudo-language that is parsed by the scripts described in the "Related files" section */ +/* Comment: // ** below. All commands must be contained within a single line. */ +/* Comment: // ** */ +/* Comment: // ** The supported commands are: */ +/* Comment: // ** */ +/* Comment: // ** include: */ +/* Comment: // ** Header file to include for looking up register addresses. The path to the include */ +/* Comment: // ** files is provided as an argument to the aop_func_gen.pl script described below. */ +/* Comment: // ** */ +/* Comment: // ** seq_name: */ +/* Comment: // ** Designates the start of a sequence. The supported sequences are: */ +/* Comment: // ** s2r_aop_to_aop_ddr_a0_pre */ +/* Comment: // ** s2r_aop_to_aop_ddr_a0_post */ +/* Comment: // ** aop_ddr_to_s2r_aop_a0_pre */ +/* Comment: // ** aop_ddr_to_s2r_aop_a0_post */ +/* Comment: // ** aop_ddr_to_awake_a0_pre */ +/* Comment: // ** aop_ddr_to_awake_a0_post */ +/* Comment: // ** awake_to_aop_ddr_a0_pre */ +/* Comment: // ** awake_to_aop_ddr_a0_post */ +/* Comment: // ** Note that s2r_aop_to_aop_ddr_a0_pre and aop_ddr_to_s2r_aop_a0_post are currently unused. */ +/* Comment: // ** */ +/* Comment: // ** endseq */ +/* Comment: // ** Designates the end of a sequence. */ +/* Comment: // ** */ +/* Comment: // ** write: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 32-bit write command to the register at 36-bit hex
with 32-bit hex . */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write64: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 64-bit write command to the 36-bit hex
with 64-bit value , */ +/* Comment: // ** where "upper" is the upper 32-bit hex value, and "lower" is the lower 32-bit hex */ +/* Comment: // ** value. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write_start */ +/* Comment: // ** Designates the start of a write command with multiple register writes. Refer to */ +/* Comment: // ** AOP spec section 6.1 "Configuration Write Command" for details. Because the */ +/* Comment: // ** annotation with "write_start" and "write_end" is manually done, it is the */ +/* Comment: // ** responsibility of the author to ensure that the combined writes are within the */ +/* Comment: // ** same 1KB block, and a max of 16 writes is included. */ +/* Comment: // ** */ +/* Comment: // ** write_end */ +/* Comment: // ** Designates the end of a multi-register write command. */ +/* Comment: // ** */ +/* Comment: // ** poll: reg_name= [reg_addr=
] reg_value= reg_mask= retry_en= retry_cnt= */ +/* Comment: // ** Reads 36-bit
until (read_data & mask == value). If is 0, the */ +/* Comment: // ** poll repeats indefinitely. If is set, the read is retried up to */ +/* Comment: // ** times. As with "write" and "write64", is not used. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** cfg_cnt: */ +/* Comment: // ** designates the number of aop_clk cycles to wait before executing the next */ +/* Comment: // ** command. */ +/* Comment: // ** */ +/* Comment: // ** cfg_end */ +/* Comment: // ** Designates the Configuration End Command. */ +/* Comment: // ** */ +/* Comment: // ** comment: */ +/* Comment: // ** Designates a comment. */ +/* Comment: // ** */ +/* Comment: // ** stitch: */ +/* Comment: // ** Stitches file.seq into the sequence inline. */ +/* Comment: // ** */ +/* Comment: // ** stitch_h: */ +/* Comment: // ** In the generated .h file, an explicit #include "file.h" will appear at this line. */ +/* Comment: // ** */ +/* Comment: // ** Related files: */ +/* Comment: // ** tb_lib/cpu/armv7/aop_lib/aop_func_gen.pl */ +/* Comment: // ** This script parses this file (aop_soc_cfg.h) and converts it into an intermediate */ +/* Comment: // ** C header format. The output file contains C arrays whose contents are in a format */ +/* Comment: // ** understood by the SOC config engine. In the DV environment, the intermediate C */ +/* Comment: // ** header file is called aop_soc_engine.h and is placed in the testgen* directory of */ +/* Comment: // ** the test results directory. The intermediate file and MCU config sequences are */ +/* Comment: // ** combined using the powgen_common.pl script, described below. */ +/* Comment: // ** */ +/* Comment: // ** tb_lib/cpu/armv8/mcu/mcu_init_aop.h */ +/* Comment: // ** Provided by the MCU team, mcu_init_aop.h contains the two sequences for configuring */ +/* Comment: // ** the DDR to operate at 48MHz and >= 800MHz. The 48MHz sequence is stitched into the */ +/* Comment: // ** S2R_AOP->AOP_DDR postamble at the comment token "INSERT_MCU_AOP_DDR_SEQ". The */ +/* Comment: // ** >= 800 MHz sequence is stitched into the AOP_DDR->AWAKE postamble at the comment */ +/* Comment: // ** token "INSERT_MCU_AWAKE_SEQ". */ +/* Comment: // ** */ +/* Comment: // ** chip/tb/cpu/bin/powgen_common.pl */ +/* Comment: // ** This script stitches together the aop_soc_engine.h file generated by aop_func_gen.pl */ +/* Comment: // ** and mcu_init_aop.h into the same AP EHEX file that is loaded into memory. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Poll for the proxy_osc clock to source LPO/8 before initiating minipmgr reset sequence */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_pre_0[] = { +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG ADDR=0x210240304 Retry_en=0 Retry_cnt=0*/ +0x000000c1, /* Offset */ +0x40300000, /* Mask */ +0x00200000, /* Data */ +/* Comment: // Do a dummy read to the AOP CPU revision register to cause a functional wakeup */ +0x21080002, /* Poll:AKF_AKFAPB_AKF_REV(GBI_AOP_AKF) ADDR=0x210800000 Retry_en=1 Retry_cnt=597*/ +0x00035500, /* Offset */ +0x00000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000004, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** This sequence is split into multiple subsequences */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_post_0[] = { +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000000, /* Data */ +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Security sequence */ +/* Comment: // Write mem cache data and tag enable/lock bits to prevent backdoor access as RAM attacks */ +0x20000041, /* WR:AMCC_MCCCFG_MCCGEN ADDR=0x200000780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +/* Comment: // Write lockable DRAM config regs */ +/* Comment: // INSERT_MCU_DDR_LOCKED */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // The MCU LockRegion programming must occur before the security/TZ programming (s2r_aop_to_aop_ddr_a0_post_security) */ +#define S2D_POST_MCU_LOCKED_AFTER 0 +#define S2D_POST_MCU_LOCKED_BEFORE 1 +/* Comment: // The security/TZ programming must occur after the MCU LockRegion programming */ +#define S2D_POST_SECURITY_AFTER 0 +#define S2D_POST_SECURITY_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR security postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_post_security[] = { +/* Comment: // Enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20000049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR ADDR=0x200000480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR ADDR=0x200000484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK ADDR=0x200000490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // Enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20000049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR ADDR=0x200000488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR ADDR=0x20000048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK ADDR=0x200000494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_1[] = { +/* Comment: // Disable AP_GID0 */ +0x2102d001, /* WR:MINIPMGR_SECURITY_SIO_AES_DISABLE ADDR=0x2102d0000 */ +0x00000000, /* Offset */ +0x00000002, /* Data */ +/* Comment: // SRAM region that must be locked ends here. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SW: */ +/* Comment: // ** */ +/* Comment: // ** Locked region is specified in 64B granularity. If the last security entry does not */ +/* Comment: // ** land neatly at the end of a 64B boundary, some non-security entries may be locked if */ +/* Comment: // ** no additional padding is used. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // Disable voltage changes (see radar 16038537) */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SiVal/SW: */ +/* Comment: // ** */ +/* Comment: // ** Per Manu, perf state entry 0 has been reserved for use by the config engine. SW agreed */ +/* Comment: // ** to use the perf state entries starting from the higher indices. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // transition the fabric and DRAM to work off the proxy clocks */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Clear the CSYSPWRUPREQ_LOOPBACK bit. See PMGR spec section 11.4.4.1 */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000000 /* Data */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define S2D_POST_PWRGATE_AFTER 1 +#define S2D_POST_PWRGATE_BEFORE 2 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_2[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08035, /* 14-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0xba4294a4, /* Offset */ +0x00005244, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001 /* Data */ +}; + +#define S2D_POST_MCU_DDR_AFTER 2 +#define S2D_POST_MCU_DDR_BEFORE 3 +static const uint32_t s2r_aop_to_aop_ddr_a0_post_3[] = { +/* Comment: // INSERT_MCU_AOP_DDR_SEQ */ +/* Comment: // Wait for the memcache to reach 16 ways, then set it to 0 */ +0x20000042, /* Poll:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS ADDR=0x20000079c Retry_en=0 Retry_cnt=0*/ +0x000000e7, /* Offset */ +0x03e003e0, /* Mask */ +0x02000200, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000100, /* Data */ +/* Comment: // Set the proxy fabric clock frequency back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->S2R_AOP PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_s2r_aop_a0_pre_0[] = { +/* Comment: // Note - We do not wait for the memcache ways to reach 0 before yanking power. See radar 16051416 */ +/* Comment: // Set NO_HANDSHAKE bit prior to restoring the perf state table to its defaults, radar 16219268 */ +0x20e04081, /* WR:PMGR_CLKCTL_MCU_CLK_DEBUG ADDR=0x20e040810 */ +0x00000004, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Set all SRC_SEL for SOC clocks to 0 so there will be no clock glitches, radar 16409004 */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x00000030, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // power up PCIe/SIO/USB domain to bypass NLP:: Pcie2phy pwr clamp enable is going to X after warmboot in UPF simulations */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08025, /* 10-word write */ +0x9458a6a8, /* Offset */ +0x8e8c8ac4, /* Offset */ +0x00009290, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x0000000f, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=0 Retry_cnt=0*/ +0x000000a8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=0 Retry_cnt=0*/ +0x000000a6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=0 Retry_cnt=0*/ +0x00000058, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=0 Retry_cnt=0*/ +0x00000094, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=0 Retry_cnt=0*/ +0x000000c4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=0 Retry_cnt=0*/ +0x0000008a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=0 Retry_cnt=0*/ +0x0000008c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=0 Retry_cnt=0*/ +0x0000008e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=0 Retry_cnt=0*/ +0x00000090, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=0 Retry_cnt=0*/ +0x00000092, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // wait 100us to delay retention reset per radar 18751992 */ +0x0012c004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t aop_ddr_to_s2r_aop_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** See PMGR spec section 11.14.4 (Software Teardown for Awake Exit) */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_a0_pre_0[] = { +/* Comment: // Restore the GPIO to its default configuration by setting GPIO_PS.RESET for 1us while setting MANUAL_PS to RUN_MAX */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x8000000f, /* Data */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x00000004, /* Data */ +/* Comment: // Disable voltage changes */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +0x20e06811, /* 5-word write */ +0x07060504, /* Offset */ +0x00000000, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0D ADDR=0x20e06801c */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Per radar 19338346, disable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +/* Comment: // Power off PLLs that software could not turn off (ENABLE == 0 and BYPASS == 1) */ +0x20e00001, /* WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x00000000, /* Offset */ +0x28190060, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x00000000, /* Offset */ +0x280b4030, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x00000000, /* Offset */ +0x2804201f, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t awake_to_aop_ddr_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.4 (Software Teardown for Awake Exit), either */ +/* Comment: // ** SW or the config engine may turn off SIO/PCIE. For DV simulations, we chose to power */ +/* Comment: // ** power down ALL of the unneeded blocks in the config engine rather than from the AP. This */ +/* Comment: // ** provided functionally equivalent behavior and allowed the AWAKE->AOP_DDR and */ +/* Comment: // ** S2R_AOP->AOP_DDR to appear symmetric. SiVal/SW may move parts of this sequence */ +/* Comment: // ** to AP software if desired. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_a0_post_0[] = { +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define A2D_POST_PWRGATE_AFTER 0 +#define A2D_POST_PWRGATE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AWAKE->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 1/20/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_a0_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x00740005, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030304, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x00210000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG0 ADDR=0x20e09c0b0 */ +0x00270003, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG1 ADDR=0x20e09c0b4 */ +0x010a0800, /* Data WR:PMGR_PWRGATE_PWR_DCS01_CFG2 ADDR=0x20e09c0b8 */ +0x80030302, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG0 ADDR=0x20e09c0c0 */ +0x002f0005, /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG1 ADDR=0x20e09c0c4 */ +0x010a0800 /* Data WR:PMGR_PWRGATE_PWR_DCS23_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t awake_to_aop_ddr_a0_post_1[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x4c5c3424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c170 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c130 */ +0x20e08021, /* 9-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x00000092, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000094 */ +0x00000025, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800074 */ +0x0000001d, /* Offset */ +0x80011c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f000014 */ +0x00000005, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0803d, /* 16-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0xc6545856, /* Offset */ +0xcecccac8, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08031, /* 13-word write */ +0xa29e9ac4, /* Offset */ +0x96a09c98, /* Offset */ +0x44ba94a4, /* Offset */ +0x00000052, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e0b83d, /* 16-word write */ +0x03020100, /* Offset */ +0x07060504, /* Offset */ +0x13121110, /* Offset */ +0x17161514, /* Offset */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH0 ADDR=0x20e0b8000 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH1 ADDR=0x20e0b8004 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH2 ADDR=0x20e0b8008 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH3 ADDR=0x20e0b800c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH4 ADDR=0x20e0b8010 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH5 ADDR=0x20e0b8014 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH6 ADDR=0x20e0b8018 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH7 ADDR=0x20e0b801c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH16 ADDR=0x20e0b8040 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH17 ADDR=0x20e0b8044 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH18 ADDR=0x20e0b8048 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH19 ADDR=0x20e0b804c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH20 ADDR=0x20e0b8050 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH21 ADDR=0x20e0b8054 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH22 ADDR=0x20e0b8058 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH23 ADDR=0x20e0b805c */ +/* Comment: // Reset and then clock gate the AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e10001, /* WR:AIC_GLOBALS_AICRST ADDR=0x20e10000c */ +0x00000003, /* Offset */ +0x00000001, /* Data */ +0x20e10002, /* Poll:AIC_GLOBALS_AICRST ADDR=0x20e10000c Retry_en=1 Retry_cnt=255*/ +0x0001ff03, /* Offset */ +0x00000001, /* Mask */ +0x00000000, /* Data */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x00000000, /* Data */ +0x2102b005, /* 2-word write */ +0x00000400, /* Offset */ +0x00000000, /* Data WR:MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER ADDR=0x2102b0000 */ +0x00000000 /* Data WR:MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER ADDR=0x2102b0010 */ +}; + +static const uint32_t awake_to_aop_ddr_a0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_a0_pre_0[] = { +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up the memcache powering up (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +0x20000041, /* WR:AMCC_MCCCFG_MCCPWRONWAYCNTCTRL ADDR=0x200000798 */ +0x000000e6, /* Offset */ +0x00000110, /* Data */ +/* Comment: // Powering up SIO partition and SIO devices */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_PS ADDR=0x20e080160 */ +0x00000058, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080160 Retry_en=1 Retry_cnt=255*/ +0x0001ff58, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_P_PS ADDR=0x20e080158 */ +0x00000056, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_P_PS ADDR=0x20e080158 Retry_en=1 Retry_cnt=255*/ +0x0001ff56, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e0803d, /* 16-word write */ +0x605e5c5a, /* Offset */ +0x68666462, /* Offset */ +0x706e6c6a, /* Offset */ +0x78767472, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080168 */ +0x00000004, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080170 */ +0x00000004, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080178 */ +0x00000004, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080180 */ +0x00000004, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080188 */ +0x00000004, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080190 */ +0x00000004, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080198 */ +0x00000004, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 */ +0x00000004, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 */ +0x00000004, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 */ +0x00000004, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 */ +0x00000004, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 */ +0x00000004, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 */ +0x00000004, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 */ +0x00000004, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d8 */ +0x00000004, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801e0 */ +0x20e0801d, /* 8-word write */ +0x807e7c7a, /* Offset */ +0x88868482, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e8 */ +0x00000004, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801f0 */ +0x00000004, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f8 */ +0x00000004, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e080200 */ +0x00000004, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080208 */ +0x00000004, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080210 */ +0x00000004, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080218 */ +0x00000004, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080220 */ +/* Comment: // It might not be required to do all of the following polls since they should take the same amount of time to power up. */ +/* Comment: // One possible optimization is to only do the poll for the last write */ +0x20e08002, /* Poll:PMGR_PS_MCA0_PS ADDR=0x20e080168 Retry_en=1 Retry_cnt=255*/ +0x0001ff5a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA1_PS ADDR=0x20e080170 Retry_en=1 Retry_cnt=255*/ +0x0001ff5c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA2_PS ADDR=0x20e080178 Retry_en=1 Retry_cnt=255*/ +0x0001ff5e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA3_PS ADDR=0x20e080180 Retry_en=1 Retry_cnt=255*/ +0x0001ff60, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA4_PS ADDR=0x20e080188 Retry_en=1 Retry_cnt=255*/ +0x0001ff62, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PWM0_PS ADDR=0x20e080190 Retry_en=1 Retry_cnt=255*/ +0x0001ff64, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C0_PS ADDR=0x20e080198 Retry_en=1 Retry_cnt=255*/ +0x0001ff66, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C1_PS ADDR=0x20e0801a0 Retry_en=1 Retry_cnt=255*/ +0x0001ff68, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C2_PS ADDR=0x20e0801a8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C3_PS ADDR=0x20e0801b0 Retry_en=1 Retry_cnt=255*/ +0x0001ff6c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI0_PS ADDR=0x20e0801b8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI1_PS ADDR=0x20e0801c0 Retry_en=1 Retry_cnt=255*/ +0x0001ff70, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI2_PS ADDR=0x20e0801c8 Retry_en=1 Retry_cnt=255*/ +0x0001ff72, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI3_PS ADDR=0x20e0801d0 Retry_en=1 Retry_cnt=255*/ +0x0001ff74, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART0_PS ADDR=0x20e0801d8 Retry_en=1 Retry_cnt=255*/ +0x0001ff76, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART1_PS ADDR=0x20e0801e0 Retry_en=1 Retry_cnt=255*/ +0x0001ff78, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART2_PS ADDR=0x20e0801e8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART3_PS ADDR=0x20e0801f0 Retry_en=1 Retry_cnt=255*/ +0x0001ff7c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART4_PS ADDR=0x20e0801f8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART5_PS ADDR=0x20e080200 Retry_en=1 Retry_cnt=255*/ +0x0001ff80, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART6_PS ADDR=0x20e080208 Retry_en=1 Retry_cnt=255*/ +0x0001ff82, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART7_PS ADDR=0x20e080210 Retry_en=1 Retry_cnt=255*/ +0x0001ff84, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART8_PS ADDR=0x20e080218 Retry_en=1 Retry_cnt=255*/ +0x0001ff86, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AES0_PS ADDR=0x20e080220 Retry_en=1 Retry_cnt=255*/ +0x0001ff88, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up PCIE partition and PCIE devices/link */ +0x20e08001, /* WR:PMGR_PS_PCIE_PS ADDR=0x20e080310 */ +0x000000c4, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080310 Retry_en=1 Retry_cnt=255*/ +0x0001ffc4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xcccac8c6, /* Offset */ +0x000000ce, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 */ +0x20e08002, /* Poll:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080318 Retry_en=1 Retry_cnt=255*/ +0x0001ffc6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080320 Retry_en=1 Retry_cnt=255*/ +0x0001ffc8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080328 Retry_en=1 Retry_cnt=255*/ +0x0001ffca, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080330 Retry_en=1 Retry_cnt=255*/ +0x0001ffcc, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080338 Retry_en=1 Retry_cnt=255*/ +0x0001ffce, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up USB partition and USB devices */ +0x20e08001, /* WR:PMGR_PS_USB_PS ADDR=0x20e080250 */ +0x00000094, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0x9c9896a4, /* Offset */ +0x000000a0, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 */ +0x00000004, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 */ +0x20e08002, /* Poll:PMGR_PS_USB_OTG_PS ADDR=0x20e080290 Retry_en=1 Retry_cnt=255*/ +0x0001ffa4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USBCTLREG_PS ADDR=0x20e080258 Retry_en=1 Retry_cnt=255*/ +0x0001ff96, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_PS ADDR=0x20e080260 Retry_en=1 Retry_cnt=255*/ +0x0001ff98, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_PS ADDR=0x20e080270 Retry_en=1 Retry_cnt=255*/ +0x0001ff9c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_PS ADDR=0x20e080280 Retry_en=1 Retry_cnt=255*/ +0x0001ffa0, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08009, /* 3-word write */ +0x00a29e9a, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080268 Retry_en=1 Retry_cnt=255*/ +0x0001ff9a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e080278 Retry_en=1 Retry_cnt=255*/ +0x0001ff9e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e080288 Retry_en=1 Retry_cnt=255*/ +0x0001ffa2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_PMP_PS ADDR=0x20e0802e8 */ +0x000000ba, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PMP_PS ADDR=0x20e0802e8 Retry_en=1 Retry_cnt=255*/ +0x0001ffba, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Restore PMS, SBR, SF, SMX, MCC, and DCS* PS to reset values per CoreOS request from radar 19132562 */ +0x20e0802d, /* 12-word write */ +0xa6a84048, /* Offset */ +0x908e8c8a, /* Offset */ +0x52444692, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802a0 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e080298 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080228 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802a0 Retry_en=1 Retry_cnt=255*/ +0x0001ffa8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e080298 Retry_en=1 Retry_cnt=255*/ +0x0001ffa6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080228 Retry_en=1 Retry_cnt=255*/ +0x0001ff8a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80101000, /* Data */ +/* Comment: // wait 1us */ +0x00003004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_awake_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.3 (Software Init for AOP_DDR to AWAKE), the */ +/* Comment: // ** config engine restores the state of the chip in this step. The specific use cases where */ +/* Comment: // ** the config engine is the owner of state restoration are not yet defined. */ +/* Comment: // ** */ +/* Comment: // ** The sequence below contains the minimum set of commands to re-boot the AP and restore */ +/* Comment: // ** DRAM operation at bucket 1 for SOC DV simulations. AP may bring DRAM up to bucket 0. */ +/* Comment: // ** */ +/* Comment: // ** It is assumed that SW will modify this sequence extensively. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +#define D2A_POST_MCU_AWAKE_AFTER -1 +#define D2A_POST_MCU_AWAKE_BEFORE 0 +static const uint32_t aop_ddr_to_awake_a0_post_0[] = { +/* Comment: // Wait 900us as first step of AOP_DDR->AWAKE per radar 20356875 to ensure BIRA loading is complete */ +/* Comment: // prior to powering on any non-AOP power domain */ +0x00a8c004, /* Cfg Count(Delay.Wait) */ +/* Comment: // INSERT_MCU_AWAKE_SEQ */ +/* Comment: // Restore the state of the chip */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a8 */ +0x0000002a, /* Offset */ +0x80100000, /* Data */ +/* Comment: // wait 1us */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +#define D2A_POST_RESTORE_AFTER 0 +#define D2A_POST_RESTORE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AOP_DDR->AWAKE system restore postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_a0_post_restore[] = { +0x20e00005, /* 2-word write */ +0x00000100, /* Offset */ +0xa0190060, /* Data WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x10000010, /* Data WR:PMGR_PLL0_CFG ADDR=0x20e000004 */ +0x20e00002, /* Poll:PMGR_PLL0_CTL ADDR=0x20e000000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_PLL_DELAY_CTL1 ADDR=0x20e004020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00405, /* 2-word write */ +0x00000001, /* Offset */ +0x50480030, /* Data WR:PMGR_PLL1_CFG ADDR=0x20e004004 */ +0xa00b4030, /* Data WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x20e00402, /* Poll:PMGR_PLL1_CTL ADDR=0x20e004000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Bring MCU up to bucket1. Note: It is up to the AP to config MCU to bucket0 */ +0x20e06819, /* 7-word write */ +0x08060504, /* Offset */ +0x00000a09, /* Offset */ +0x55555517, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x55656666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x88878807, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1A ADDR=0x20e068020 */ +0x67a76866, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1B ADDR=0x20e068024 */ +0x00000005, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_1C ADDR=0x20e068028 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Tunables may be re-applied here */ +0x20e08001, /* WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000044, /* Offset */ +0x0000024f, /* Data */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +// +// The removal of the items below from this model sequence is intentional. +// +//0x00000044, /* CFG Count to aling 64 bit write to 16 bytes address:*/ +//0x20205003, /* WR:ACC_CPU0_IMPL_IO_RVBAR ADDR=0x202050000 */ +//0x00000000, /* Offset */ +//0x00000000, /* Data */ +//0x00000008 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_1[] = { +/* Comment: // Per radar 19338346, re-enable DynPwrDnEn after switch to bucket 3 */ +0x20020041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200200424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20024041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200240424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20028041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200280424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2002c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2002c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +/* Comment: // Per radar 20183074, turn the following partitions on one at a time */ +0x20e08001, /* WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +0x000000aa, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 Retry_en=0 Retry_cnt=0*/ +0x000000aa, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x000000b2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_ISP_PS ADDR=0x20e0802c8 Retry_en=0 Retry_cnt=0*/ +0x000000b2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x000000b4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 Retry_en=0 Retry_cnt=0*/ +0x000000b4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x000000b8, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MSR_PS ADDR=0x20e0802e0 Retry_en=0 Retry_cnt=0*/ +0x000000b8, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x000000be, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 Retry_en=0 Retry_cnt=0*/ +0x000000be, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x000000c2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 Retry_en=0 Retry_cnt=0*/ +0x000000c2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000002, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 Retry_en=0 Retry_cnt=0*/ +0x00000002, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x00000004, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 Retry_en=0 Retry_cnt=0*/ +0x00000004, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x000000d0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GFX_PS ADDR=0x20e080340 Retry_en=0 Retry_cnt=0*/ +0x000000d0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08041, /* WR:PMGR_PS_SEP_PS ADDR=0x20e080400 */ +0x00000000, /* Offset */ +0x4000000f, /* Data */ +0x20e08042, /* Poll:PMGR_PS_SEP_PS ADDR=0x20e080400 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +/* Comment: // Per CoreOS request, turn off the above PS registers (except SEP_PS, which cannot be turned off by config engine) */ +0x20e08809, /* 3-word write */ +0x00040200, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x20e08019, /* 7-word write */ +0xb8bec2d0, /* Offset */ +0x00aab2b4, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_GFX_PS ADDR=0x20e080340 */ +0x00000000, /* Data WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080308 */ +0x00000000, /* Data WR:PMGR_PS_VDEC0_PS ADDR=0x20e0802f8 */ +0x00000000, /* Data WR:PMGR_PS_MSR_PS ADDR=0x20e0802e0 */ +0x00000000, /* Data WR:PMGR_PS_MEDIA_PS ADDR=0x20e0802d0 */ +0x00000000, /* Data WR:PMGR_PS_ISP_PS ADDR=0x20e0802c8 */ +0x00000000, /* Data WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802a8 */ +/* Comment: // Set the proxy clock back to 96MHz (see radar 16263183) */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +}; + +// +// This additional stitch point is an intentional deviation from the SEG-provided +// sequence. +// +#define D2A_POST_PREBOOT_BEFORE 2 +static const uint32_t aop_ddr_to_awake_a0_post_2[] = { +/* Comment: // Boot CPU0 by writing to the WAKE_CORES register */ +0x20e0d401, /* WR:PMGR_MISC_CORES_WAKE_CORES ADDR=0x20e0d4008 */ +0x00000002, /* Offset */ +0x00000001 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +// +// Intentional removal of the following definition which would otherwise duplicate the definition from the A1 sequence +// +//typedef struct { +// uint32_t *sequence; +// size_t elements; +//} reconfig_subsequence_t; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_a0_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_a0_pre_0, sizeof(aop_ddr_to_awake_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_a0_pre_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_a0_pre_0, sizeof(awake_to_aop_ddr_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_s2r_aop_a0_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_s2r_aop_a0_pre_0, sizeof(aop_ddr_to_s2r_aop_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_a0_post_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_0, sizeof(s2r_aop_to_aop_ddr_a0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_1, sizeof(s2r_aop_to_aop_ddr_a0_post_1) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_2, sizeof(s2r_aop_to_aop_ddr_a0_post_2) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_3, sizeof(s2r_aop_to_aop_ddr_a0_post_3) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_a0_pre_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_a0_pre_0, sizeof(s2r_aop_to_aop_ddr_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_a0_post_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_a0_post_0, sizeof(aop_ddr_to_awake_a0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_a0_post_1, sizeof(aop_ddr_to_awake_a0_post_1) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_a0_post_2, sizeof(aop_ddr_to_awake_a0_post_2) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_a0_post_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_a0_post_0, sizeof(awake_to_aop_ddr_a0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) awake_to_aop_ddr_a0_post_1, sizeof(awake_to_aop_ddr_a0_post_1) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +#endif // AOP_CONFIG_SEQUENCES_A0_H diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000.h new file mode 100644 index 0000000..f3557f8 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000.h @@ -0,0 +1,3100 @@ +#ifndef __MCU_INIT_AOP_H__ +#define __MCU_INIT_AOP_H__ + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_ddr[] = { + 0x20020c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20020c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20020c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20020c05c DWORD=0 NUMREGS=0 */ + 0x20024c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20024c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20024c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20024c05c DWORD=0 NUMREGS=0 */ + 0x2002cc11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2002cc01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2002cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2002cc05c DWORD=0 NUMREGS=0 */ + 0x20028c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20028c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20028c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20028c05c DWORD=0 NUMREGS=0 */ + 0x2002007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200200450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200200458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20020045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200200460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2002004c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200200468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200200470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200200474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200200478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2002004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200200480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200200484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200200488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20020048c DWORD=0 NUMREGS=0 */ + 0x2002005d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200200490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2002004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200200498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20020049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2002004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2002004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x2002407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200240450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200240458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20024045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200240460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2002404c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200240468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200240470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200240474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200240478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2002404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200240480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200240484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200240488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20024048c DWORD=0 NUMREGS=0 */ + 0x2002405d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200240490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2002404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200240498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20024049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2002404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2002404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2002404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2002404cc DWORD=0 NUMREGS=0 */ + 0x2002807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200280450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200280458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20028045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200280460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2002804c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200280468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200280470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200280474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200280478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2002804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200280480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200280484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200280488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20028048c DWORD=0 NUMREGS=0 */ + 0x2002805d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200280490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2002804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200280498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20028049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2002804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2002804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2002804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2002804cc DWORD=0 NUMREGS=0 */ + 0x2002c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2002c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2002c0458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2002c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2002c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2002c04c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2002c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2002c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2002c0474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2002c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2002c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2002c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2002c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2002c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2002c048c DWORD=0 NUMREGS=0 */ + 0x2002c05d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2002c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2002c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2002c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2002c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2002c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2002c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2002c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2002c04cc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2002c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2002c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2002c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU3) ADDR=0x2002c028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2002c0390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2002c03a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2002c03c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2002c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2002c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2002c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2002c03c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2002c0398 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2002c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2002c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2002c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2002c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2002c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2002c03d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2002c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2002c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2002c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2002c03e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2002c0388 DWORD=0 NUMREGS=0 */ + 0x2002c011, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x000000fd, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2002c038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2002c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2002c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2002c03f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU3) ADDR=0x2002c03f4 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xece8e4a3, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200200280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200200284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200200288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU0) ADDR=0x20020028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200200390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2002003a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2002003c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2002003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200200394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2002003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2002003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200200398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2002003a8 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2002003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20020039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2002003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2002003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2002003d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2002003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2002003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2002003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2002003e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200200388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20020038c DWORD=0 NUMREGS=0 */ + 0x2002000d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2002003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2002003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2002003f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU0) ADDR=0x2002003f4 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xece8e4a3, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200240280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200240284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200240288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU1) ADDR=0x20024028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200240390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2002403a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2002403c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2002403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200240394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2002403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2002403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200240398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2002403a8 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2002403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20024039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2002403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2002403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2002403d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2002403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2002403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2002403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2002403e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200240388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20024038c DWORD=0 NUMREGS=0 */ + 0x2002400d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2002403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2002403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2002403f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU1) ADDR=0x2002403f4 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xece8e4a3, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200280280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200280284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200280288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU2) ADDR=0x20028028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200280390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2002803a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2002803c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2002803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200280394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2002803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2002803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200280398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2002803a8 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2002803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20028039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2002803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2002803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2002803d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2002803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2002803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2002803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2002803e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200280388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20028038c DWORD=0 NUMREGS=0 */ + 0x2002800d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2002803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2002803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2002803f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU2) ADDR=0x2002803f4 DWORD=0 NUMREGS=0 */ + 0x20020051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200200404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20020078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200240404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200240780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20024078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200280404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200280780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20028078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2002c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2002c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2002c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200220000 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200260000 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2002a0000 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2002e0000 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200228000 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200230000 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200268000 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200270000 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2002a8000 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2002b0000 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2002e8000 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2002f0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU0) ADDR=0x20022009c DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU1) ADDR=0x20026009c DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU2) ADDR=0x2002a009c DWORD=0 NUMREGS=0 */ + 0x2002e01d, //compressed WR cmd + 0x2a292827, //compressed WR offset + 0x332e2d2c, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU3) ADDR=0x2002e009c DWORD=0 NUMREGS=0 */ + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU3) ADDR=0x2002e00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU3) ADDR=0x2002e00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU3) ADDR=0x2002e00a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU3) ADDR=0x2002e00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU3) ADDR=0x2002e00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU3) ADDR=0x2002e00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU3) ADDR=0x2002e00cc DWORD=0 NUMREGS=0 */ + 0x20022019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU0) ADDR=0x2002200a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU0) ADDR=0x2002200a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU0) ADDR=0x2002200a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU0) ADDR=0x2002200b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU0) ADDR=0x2002200b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU0) ADDR=0x2002200b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU0) ADDR=0x2002200cc DWORD=0 NUMREGS=0 */ + 0x20026019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU1) ADDR=0x2002600a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU1) ADDR=0x2002600a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU1) ADDR=0x2002600a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU1) ADDR=0x2002600b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU1) ADDR=0x2002600b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU1) ADDR=0x2002600b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU1) ADDR=0x2002600cc DWORD=0 NUMREGS=0 */ + 0x2002a019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU2) ADDR=0x2002a00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU2) ADDR=0x2002a00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU2) ADDR=0x2002a00a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU2) ADDR=0x2002a00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU2) ADDR=0x2002a00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU2) ADDR=0x2002a00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU2) ADDR=0x2002a00cc DWORD=0 NUMREGS=0 */ + 0x200220d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200220d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200220d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200220d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200220d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200220d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200220d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200220d0c DWORD=0 NUMREGS=0 */ + 0x200260d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200260d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200260d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200260d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200260d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200260d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200260d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200260d0c DWORD=0 NUMREGS=0 */ + 0x2002a0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2002a0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2002a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2002a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2002a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2002a0d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2002a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2002a0d0c DWORD=0 NUMREGS=0 */ + 0x2002e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2002e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2002e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2002e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2002e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2002e0d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2002e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2002e0d0c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ0) ADDR=0x2002280ac DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ1) ADDR=0x2002300ac DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ0) ADDR=0x2002680ac DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ1) ADDR=0x2002700ac DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ0) ADDR=0x2002a80ac DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ1) ADDR=0x2002b00ac DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ0) ADDR=0x2002e80ac DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ1) ADDR=0x2002f00ac DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ0) ADDR=0x2002280b0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ1) ADDR=0x2002300b0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ0) ADDR=0x2002680b0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ1) ADDR=0x2002700b0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ0) ADDR=0x2002a80b0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ1) ADDR=0x2002b00b0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ0) ADDR=0x2002e80b0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ1) ADDR=0x2002f00b0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ0) ADDR=0x2002280b4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ1) ADDR=0x2002300b4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ0) ADDR=0x2002680b4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ1) ADDR=0x2002700b4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ0) ADDR=0x2002a80b4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ1) ADDR=0x2002b00b4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ0) ADDR=0x2002e80b4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ1) ADDR=0x2002f00b4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ0) ADDR=0x2002280b8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ1) ADDR=0x2002300b8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ0) ADDR=0x2002680b8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ1) ADDR=0x2002700b8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ0) ADDR=0x2002a80b8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ1) ADDR=0x2002b00b8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ0) ADDR=0x2002e80b8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ1) ADDR=0x2002f00b8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ0) ADDR=0x200228084 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ1) ADDR=0x200230084 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ0) ADDR=0x200268084 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ1) ADDR=0x200270084 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ0) ADDR=0x2002a8084 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ1) ADDR=0x2002b0084 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ0) ADDR=0x2002e8084 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ1) ADDR=0x2002f0084 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ0) ADDR=0x200228088 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ1) ADDR=0x200230088 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ0) ADDR=0x200268088 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ1) ADDR=0x200270088 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ0) ADDR=0x2002a8088 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ1) ADDR=0x2002b0088 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ0) ADDR=0x2002e8088 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ1) ADDR=0x2002f0088 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ0) ADDR=0x20022808c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ1) ADDR=0x20023008c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ0) ADDR=0x20026808c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ1) ADDR=0x20027008c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ0) ADDR=0x2002a808c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ1) ADDR=0x2002b008c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ0) ADDR=0x2002e808c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ1) ADDR=0x2002f008c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ0) ADDR=0x200228090 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ1) ADDR=0x200230090 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ0) ADDR=0x200268090 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ1) ADDR=0x200270090 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ0) ADDR=0x2002a8090 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ1) ADDR=0x2002b0090 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ0) ADDR=0x2002e8090 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ1) ADDR=0x2002f0090 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ0) ADDR=0x200228114 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ1) ADDR=0x200230114 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ0) ADDR=0x200268114 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ1) ADDR=0x200270114 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ0) ADDR=0x2002a8114 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ1) ADDR=0x2002b0114 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ0) ADDR=0x2002e8114 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ1) ADDR=0x2002f0114 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200220718 DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200260718 DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2002a0718 DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2002e0718 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20022861c DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20023061c DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20026861c DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20027061c DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2002a861c DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2002b061c DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2002e861c DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2002f061c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU0, DQ0) ADDR=0x2002280a0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU0, DQ1) ADDR=0x2002300a0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU1, DQ0) ADDR=0x2002680a0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU1, DQ1) ADDR=0x2002700a0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU2, DQ0) ADDR=0x2002a80a0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU2, DQ1) ADDR=0x2002b00a0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU3, DQ0) ADDR=0x2002e80a0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU3, DQ1) ADDR=0x2002f00a0 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x20026081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x2002a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x2002e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU0, DQ0) ADDR=0x200228110 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU0, DQ1) ADDR=0x200230110 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU1, DQ0) ADDR=0x200268110 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU1, DQ1) ADDR=0x200270110 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU2, DQ0) ADDR=0x2002a8110 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU2, DQ1) ADDR=0x2002b0110 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU3, DQ0) ADDR=0x2002e8110 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU3, DQ1) ADDR=0x2002f0110 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200220e74 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200260e74 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2002a0e74 DWORD=0 NUMREGS=0 */ + 0x2002e0cd, //compressed WR cmd + 0xe2e1e09d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2002e0e74 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2002e0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2002e0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2002e0f88 DWORD=0 NUMREGS=0 */ + 0x200220c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200220f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200220f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200220f88 DWORD=0 NUMREGS=0 */ + 0x200260c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200260f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200260f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200260f88 DWORD=0 NUMREGS=0 */ + 0x2002a0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2002a0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2002a0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2002a0f88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200228d80 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200230d80 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200268d80 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200270d80 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2002a8d80 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2002b0d80 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2002e8d80 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2002f0d80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200228d84 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200230d84 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200268d84 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200270d84 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2002a8d84 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2002b0d84 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2002e8d84 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2002f0d84 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200228d88 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200230d88 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200268d88 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200270d88 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2002a8d88 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2002b0d88 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2002e8d88 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2002f0d88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200228d8c DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200230d8c DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200268d8c DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200270d8c DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2002a8d8c DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2002b0d8c DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2002e8d8c DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2002f0d8c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2002281cc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2002301cc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2002681cc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2002701cc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2002a81cc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2002b01cc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2002e81cc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2002f01cc DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200220e00 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200260e00 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2002a0e00 DWORD=0 NUMREGS=0 */ + 0x2002e0f1, //compressed WR cmd + 0x83828180, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0x91908f8e, //compressed WR offset + 0x000000a0, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2002e0e00 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2002e0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2002e0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2002e0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2002e0e80 DWORD=0 NUMREGS=0 */ + 0x200220ed, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0xa091908f, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200220e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200220e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200220e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200220e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200220e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200220e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200220e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200220e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200220e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200220e80 DWORD=0 NUMREGS=0 */ + 0x200260ed, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0xa091908f, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200260e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200260e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200260e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200260e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200260e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200260e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200260e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200260e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200260e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200260e80 DWORD=0 NUMREGS=0 */ + 0x2002a0ed, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0xa091908f, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2002a0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2002a0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2002a0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2002a0e80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200228d00 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200230d00 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200268d00 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200270d00 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2002a8d00 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2002b0d00 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2002e8d00 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2002f0d00 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU0) ADDR=0x2002201c0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU1) ADDR=0x2002601c0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU2) ADDR=0x2002a01c0 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU3) ADDR=0x2002e01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ0) ADDR=0x2002281bc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ1) ADDR=0x2002301bc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ0) ADDR=0x2002681bc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ1) ADDR=0x2002701bc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ0) ADDR=0x2002a81bc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ1) ADDR=0x2002b01bc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ0) ADDR=0x2002e81bc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ1) ADDR=0x2002f01bc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200228100 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200230100 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200268100 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200270100 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2002a8100 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2002b0100 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2002e8100 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2002f0100 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU0) ADDR=0x2002201c4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU1) ADDR=0x2002601c4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU2) ADDR=0x2002a01c4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU3) ADDR=0x2002e01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ0) ADDR=0x2002281c0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ1) ADDR=0x2002301c0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ0) ADDR=0x2002681c0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ1) ADDR=0x2002701c0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ0) ADDR=0x2002a81c0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ1) ADDR=0x2002b01c0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ0) ADDR=0x2002e81c0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ1) ADDR=0x2002f01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200228104 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200230104 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200268104 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200270104 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2002a8104 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2002b0104 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2002e8104 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2002f0104 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU0) ADDR=0x2002201c8 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU1) ADDR=0x2002601c8 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU2) ADDR=0x2002a01c8 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU3) ADDR=0x2002e01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ0) ADDR=0x2002281c4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ1) ADDR=0x2002301c4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ0) ADDR=0x2002681c4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ1) ADDR=0x2002701c4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ0) ADDR=0x2002a81c4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ1) ADDR=0x2002b01c4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ0) ADDR=0x2002e81c4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ1) ADDR=0x2002f01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200228108 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200230108 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200268108 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200270108 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2002a8108 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2002b0108 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2002e8108 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2002f0108 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU0) ADDR=0x2002201cc DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU1) ADDR=0x2002601cc DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU2) ADDR=0x2002a01cc DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU3) ADDR=0x2002e01cc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ0) ADDR=0x2002281c8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ1) ADDR=0x2002301c8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ0) ADDR=0x2002681c8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ1) ADDR=0x2002701c8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ0) ADDR=0x2002a81c8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ1) ADDR=0x2002b01c8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ0) ADDR=0x2002e81c8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ1) ADDR=0x2002f01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20022810c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20023010c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20026810c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20027010c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2002a810c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2002b010c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2002e810c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2002f010c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU0) ADDR=0x200220088 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU1) ADDR=0x200260088 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU2) ADDR=0x2002a0088 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006822, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU3) ADDR=0x2002e0088 DWORD=0 NUMREGS=0 */ + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2002e01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2002201a0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2002601a0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2002a01a0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2002281a0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2002301a0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2002681a0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2002701a0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2002a81a0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2002b01a0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2002e81a0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2002f01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU0) ADDR=0x200220180 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU1) ADDR=0x200260180 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU2) ADDR=0x2002a0180 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU3) ADDR=0x2002e0180 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200228180 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200230180 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200268180 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200270180 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2002a8180 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2002b0180 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2002e8180 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2002f0180 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00003525, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU3) ADDR=0x2002e00d4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU0) ADDR=0x2002200d4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU1) ADDR=0x2002600d4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU2) ADDR=0x2002a00d4 DWORD=0 NUMREGS=0 */ + 0x20023801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU0) ADDR=0x200238080 DWORD=0 NUMREGS=0 */ + 0x20027801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU1) ADDR=0x200278080 DWORD=0 NUMREGS=0 */ + 0x2002f801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU3) ADDR=0x2002f8080 DWORD=0 NUMREGS=0 */ + 0x2002b801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU2) ADDR=0x2002b8080 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200220008 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200260008 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2002a0008 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2002e0008 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200228008 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200230008 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200268008 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200270008 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2002a8008 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2002b0008 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2002e8008 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2002f0008 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x2002c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x2002000d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x2002400d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x2002800d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20020041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20024041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20028041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2002c041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x20022002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200200414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200200410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20020040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200200408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200240414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200240410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20024040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200240408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200280414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200280410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20028040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200280408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2002c0414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2002c0410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2002c040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2002c0408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20020045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000010, //compressed WR offset + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CHEN(MCC) ADDR=0x20f140040 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20022801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU0, DQ0) ADDR=0x2002280a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU0, DQ1) ADDR=0x2002300a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU1, DQ0) ADDR=0x2002680a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU1, DQ1) ADDR=0x2002700a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU2, DQ0) ADDR=0x2002a80a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU2, DQ1) ADDR=0x2002b00a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU3, DQ0) ADDR=0x2002e80a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU3, DQ1) ADDR=0x2002f00a4 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ0) ADDR=0x200228620 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ1) ADDR=0x200230620 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ0) ADDR=0x200268620 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ1) ADDR=0x200270620 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ0) ADDR=0x2002a8620 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ1) ADDR=0x2002b0620 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ0) ADDR=0x2002e8620 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ1) ADDR=0x2002f0620 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20022001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU0) ADDR=0x2002200d4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU1) ADDR=0x2002600d4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU2) ADDR=0x2002a00d4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU3) ADDR=0x2002e00d4 DWORD=0 NUMREGS=0 */ + 0x20023801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000013f, /* WR:AMPH_SLC_SLC_REG0(MCU0) ADDR=0x200238080 DWORD=0 NUMREGS=0 */ + 0x20027801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000013f, /* WR:AMPH_SLC_SLC_REG0(MCU1) ADDR=0x200278080 DWORD=0 NUMREGS=0 */ + 0x2002f801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000013f, /* WR:AMPH_SLC_SLC_REG0(MCU3) ADDR=0x2002f8080 DWORD=0 NUMREGS=0 */ + 0x2002b801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000013f, /* WR:AMPH_SLC_SLC_REG0(MCU2) ADDR=0x2002b8080 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200220c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20020019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x20024009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20024019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x20028009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20028019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x2002c009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2002c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x20000042, /* POLL:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS(MCC) ADDR=0x20000079c DWORD=0 */ + 0x000000e7, /* Offset */ + 0x7fff7fff, /* Mask */ + 0x42104210, /* Expected Data */ + 0x20000049, //compressed WR cmd + 0x00e09392, //compressed WR offset + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200228004 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200230004 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200268004 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200270004 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2002a8004 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2002b0004 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2002e8004 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2002f0004 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000a09, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU3) ADDR=0x2002c0428 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU0) ADDR=0x200200428 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU1) ADDR=0x200240428 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU2) ADDR=0x200280428 DWORD=0 NUMREGS=0 */ + 0x20020005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU0) ADDR=0x2002001ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200200010 DWORD=0 NUMREGS=0 */ + 0x20024005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU1) ADDR=0x2002401ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200240010 DWORD=0 NUMREGS=0 */ + 0x20f1401d, //compressed WR cmd + 0x16151413, //compressed WR offset + 0x18171211, //compressed WR offset + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(MCC) ADDR=0x20f14004c DWORD=0 NUMREGS=0 */ + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(MCC) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(MCC) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(MCC) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY0(MCC) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY1(MCC) ADDR=0x20f140048 DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY0(MCC) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY1(MCC) ADDR=0x20f140060 DWORD=0 NUMREGS=0 */ + 0x20028005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU2) ADDR=0x2002801ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200280010 DWORD=0 NUMREGS=0 */ + 0x2002c005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU3) ADDR=0x2002c01ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2002c0010 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20024042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x20028042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x2002c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_locked[] = { + 0x2000004d, //compressed WR cmd + 0x292d3229, //compressed WR offset + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC) ADDR=0x2000004c8 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC) ADDR=0x2000004b4 DWORD=0 NUMREGS=0 */ + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_before_restoration[] = { + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 NUMREGS=0 */ + 0x20022802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008381, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200220700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200260700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2002a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2002e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200220708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200260708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2002a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2002e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200220710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200260710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2002a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2002e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20022081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20026081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200220500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200260500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2002a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2002e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200220504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200260504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2002a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2002e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200220508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200260508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2002a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2002e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20022050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20026050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2002a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2002e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200220510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200260510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2002a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2002e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200220514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200260514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2002a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2002e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200220518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200260518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2002a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2002e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20022051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20026051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2002a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2002e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20022841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200228704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20023041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200230704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20026841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200268704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20027041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200270704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2002a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2002b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2002e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2002f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200228b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200230b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200268b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200270b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2002a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2002b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2002e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2002f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200228b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200230b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200268b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200270b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2002a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2002b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2002e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2002f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20020001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20024001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20028001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x2002c001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + /* FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200200458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200240458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200280458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2002c0458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20f14001, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(MCC) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x00000006, /* Offset */ + 0x00061a80, /* Data -- GLBTIMER_GLBTIMER_ZQCTIMER 0x0 ## Save the value after End of Step 18 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* END OF RESTORATION */ + 0x00000044, /* NOOP for 64bit alignment*/ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_after_restoration[] = { + 0x200220c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20f14031, //compressed WR cmd + 0x0201000e, //compressed WR offset + 0x08070504, //compressed WR offset + 0x1b1a1909, //compressed WR offset + 0x0000001c, //compressed WR offset + 0x000000ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(MCC) ADDR=0x20f140038 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(MCC) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(MCC) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(MCC) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(MCC) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(MCC) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(MCC) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_VOLTRAMPTIMER(MCC) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(MCC) ADDR=0x20f140024 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY0(MCC) ADDR=0x20f140064 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY1(MCC) ADDR=0x20f140068 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY0(MCC) ADDR=0x20f14006c DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY1(MCC) ADDR=0x20f140070 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000_b0.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000_b0.h new file mode 100644 index 0000000..3b3235e --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8000_b0.h @@ -0,0 +1,3081 @@ +#ifndef __MCU_INIT_AOP_B0_H__ +#define __MCU_INIT_AOP_B0_H__ + +static const uint32_t s2r_aop_to_aop_ddr_b0_post_mcu_ddr[] = { + 0x20020c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20020c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20020c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20020c05c DWORD=0 NUMREGS=0 */ + 0x20024c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20024c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20024c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20024c05c DWORD=0 NUMREGS=0 */ + 0x2002cc11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2002cc01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2002cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2002cc05c DWORD=0 NUMREGS=0 */ + 0x20028c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20028c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20028c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20028c05c DWORD=0 NUMREGS=0 */ + 0x2002007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200200450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200200458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20020045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200200460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2002004c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200200468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200200470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200200474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200200478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2002004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200200480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200200484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200200488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20020048c DWORD=0 NUMREGS=0 */ + 0x20020061, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000000, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200200490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2002004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200200498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20020049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2002004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2002004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU0) ADDR=0x200200400 DWORD=0 NUMREGS=0 */ + 0x2002407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200240450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200240458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20024045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200240460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2002404c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200240468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200240470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200240474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200240478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2002404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200240480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200240484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200240488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20024048c DWORD=0 NUMREGS=0 */ + 0x20024061, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000000, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200240490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2002404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200240498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20024049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2002404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2002404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2002404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2002404cc DWORD=0 NUMREGS=0 */ + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU1) ADDR=0x200240400 DWORD=0 NUMREGS=0 */ + 0x2002807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200280450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200280458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20028045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200280460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2002804c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200280468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200280470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200280474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200280478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2002804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200280480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200280484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200280488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20028048c DWORD=0 NUMREGS=0 */ + 0x20028061, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000000, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200280490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2002804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200280498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20028049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2002804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2002804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2002804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2002804cc DWORD=0 NUMREGS=0 */ + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU2) ADDR=0x200280400 DWORD=0 NUMREGS=0 */ + 0x2002c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2002c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2002c0458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2002c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2002c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2002c04c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2002c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0xf303020b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2002c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2002c0474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2002c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2002c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2002c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2002c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2002c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2002c048c DWORD=0 NUMREGS=0 */ + 0x2002c061, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000000, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2002c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2002c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2002c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2002c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2002c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2002c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2002c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2002c04cc DWORD=0 NUMREGS=0 */ + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU3) ADDR=0x2002c0400 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2002c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2002c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2002c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU3) ADDR=0x2002c028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2002c0390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2002c03a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2002c03c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2002c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2002c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2002c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2002c03c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2002c0398 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2002c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2002c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2002c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2002c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2002c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2002c03d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2002c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2002c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2002c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2002c03e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2002c0388 DWORD=0 NUMREGS=0 */ + 0x2002c011, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x000000fd, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2002c038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2002c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2002c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2002c03f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU3) ADDR=0x2002c03f4 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xece8e4a3, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200200280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200200284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200200288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU0) ADDR=0x20020028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200200390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2002003a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2002003c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2002003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200200394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2002003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2002003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200200398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2002003a8 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2002003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20020039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2002003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2002003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2002003d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2002003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2002003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2002003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2002003e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200200388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20020038c DWORD=0 NUMREGS=0 */ + 0x2002000d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2002003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2002003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2002003f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU0) ADDR=0x2002003f4 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xece8e4a3, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200240280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200240284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200240288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU1) ADDR=0x20024028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200240390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2002403a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2002403c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2002403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200240394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2002403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2002403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200240398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2002403a8 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2002403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20024039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2002403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2002403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2002403d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2002403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2002403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2002403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2002403e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200240388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20024038c DWORD=0 NUMREGS=0 */ + 0x2002400d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2002403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2002403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2002403f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU1) ADDR=0x2002403f4 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xece8e4a3, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x00050c0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200280280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200280284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200280288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU2) ADDR=0x20028028c DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200280390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2002803a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2002803c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2002803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200280394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2002803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2002803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200280398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2002803a8 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2002803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20028039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2002803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2002803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2002803d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2002803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2002803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2002803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2002803e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200280388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20028038c DWORD=0 NUMREGS=0 */ + 0x2002800d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2002803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2002803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2002803f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU2) ADDR=0x2002803f4 DWORD=0 NUMREGS=0 */ + 0x20020051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200200404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20020078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200240404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200240780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20024078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200280404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200280780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20028078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2002c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2002c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2002c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200220000 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200260000 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2002a0000 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2002e0000 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200228000 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200230000 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200268000 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200270000 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2002a8000 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2002b0000 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2002e8000 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2002f0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU0) ADDR=0x20022009c DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU1) ADDR=0x20026009c DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU2) ADDR=0x2002a009c DWORD=0 NUMREGS=0 */ + 0x2002e01d, //compressed WR cmd + 0x2a292827, //compressed WR offset + 0x332e2d2c, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU3) ADDR=0x2002e009c DWORD=0 NUMREGS=0 */ + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU3) ADDR=0x2002e00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU3) ADDR=0x2002e00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU3) ADDR=0x2002e00a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU3) ADDR=0x2002e00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU3) ADDR=0x2002e00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU3) ADDR=0x2002e00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU3) ADDR=0x2002e00cc DWORD=0 NUMREGS=0 */ + 0x20022019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU0) ADDR=0x2002200a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU0) ADDR=0x2002200a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU0) ADDR=0x2002200a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU0) ADDR=0x2002200b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU0) ADDR=0x2002200b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU0) ADDR=0x2002200b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU0) ADDR=0x2002200cc DWORD=0 NUMREGS=0 */ + 0x20026019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU1) ADDR=0x2002600a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU1) ADDR=0x2002600a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU1) ADDR=0x2002600a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU1) ADDR=0x2002600b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU1) ADDR=0x2002600b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU1) ADDR=0x2002600b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU1) ADDR=0x2002600cc DWORD=0 NUMREGS=0 */ + 0x2002a019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU2) ADDR=0x2002a00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU2) ADDR=0x2002a00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU2) ADDR=0x2002a00a8 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU2) ADDR=0x2002a00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU2) ADDR=0x2002a00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU2) ADDR=0x2002a00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU2) ADDR=0x2002a00cc DWORD=0 NUMREGS=0 */ + 0x200220d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200220d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200220d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200220d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200220d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200220d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200220d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200220d0c DWORD=0 NUMREGS=0 */ + 0x200260d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200260d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200260d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200260d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200260d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200260d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200260d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200260d0c DWORD=0 NUMREGS=0 */ + 0x2002a0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2002a0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2002a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2002a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2002a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2002a0d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2002a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2002a0d0c DWORD=0 NUMREGS=0 */ + 0x2002e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2002e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2002e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2002e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2002e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2002e0d00 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2002e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2002e0d0c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ0) ADDR=0x2002280ac DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ1) ADDR=0x2002300ac DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ0) ADDR=0x2002680ac DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ1) ADDR=0x2002700ac DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ0) ADDR=0x2002a80ac DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ1) ADDR=0x2002b00ac DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ0) ADDR=0x2002e80ac DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ1) ADDR=0x2002f00ac DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ0) ADDR=0x2002280b0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ1) ADDR=0x2002300b0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ0) ADDR=0x2002680b0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ1) ADDR=0x2002700b0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ0) ADDR=0x2002a80b0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ1) ADDR=0x2002b00b0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ0) ADDR=0x2002e80b0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ1) ADDR=0x2002f00b0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ0) ADDR=0x2002280b4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ1) ADDR=0x2002300b4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ0) ADDR=0x2002680b4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ1) ADDR=0x2002700b4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ0) ADDR=0x2002a80b4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ1) ADDR=0x2002b00b4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ0) ADDR=0x2002e80b4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ1) ADDR=0x2002f00b4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ0) ADDR=0x2002280b8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ1) ADDR=0x2002300b8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ0) ADDR=0x2002680b8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ1) ADDR=0x2002700b8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ0) ADDR=0x2002a80b8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ1) ADDR=0x2002b00b8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ0) ADDR=0x2002e80b8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ1) ADDR=0x2002f00b8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ0) ADDR=0x200228084 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ1) ADDR=0x200230084 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ0) ADDR=0x200268084 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ1) ADDR=0x200270084 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ0) ADDR=0x2002a8084 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ1) ADDR=0x2002b0084 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ0) ADDR=0x2002e8084 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x00030b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ1) ADDR=0x2002f0084 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ0) ADDR=0x200228088 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ1) ADDR=0x200230088 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ0) ADDR=0x200268088 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ1) ADDR=0x200270088 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ0) ADDR=0x2002a8088 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ1) ADDR=0x2002b0088 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ0) ADDR=0x2002e8088 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ1) ADDR=0x2002f0088 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ0) ADDR=0x20022808c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ1) ADDR=0x20023008c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ0) ADDR=0x20026808c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ1) ADDR=0x20027008c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ0) ADDR=0x2002a808c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ1) ADDR=0x2002b008c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ0) ADDR=0x2002e808c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ1) ADDR=0x2002f008c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ0) ADDR=0x200228090 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ1) ADDR=0x200230090 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ0) ADDR=0x200268090 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ1) ADDR=0x200270090 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ0) ADDR=0x2002a8090 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ1) ADDR=0x2002b0090 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ0) ADDR=0x2002e8090 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ1) ADDR=0x2002f0090 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00df00df, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ0) ADDR=0x200228114 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ1) ADDR=0x200230114 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ0) ADDR=0x200268114 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ1) ADDR=0x200270114 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ0) ADDR=0x2002a8114 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ1) ADDR=0x2002b0114 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ0) ADDR=0x2002e8114 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000031, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ1) ADDR=0x2002f0114 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200220718 DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200260718 DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2002a0718 DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2002e0718 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20022861c DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20023061c DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20026861c DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20027061c DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2002a861c DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2002b061c DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2002e861c DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2002f061c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU0, DQ0) ADDR=0x2002280a0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU0, DQ1) ADDR=0x2002300a0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU1, DQ0) ADDR=0x2002680a0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU1, DQ1) ADDR=0x2002700a0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU2, DQ0) ADDR=0x2002a80a0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU2, DQ1) ADDR=0x2002b00a0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU3, DQ0) ADDR=0x2002e80a0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000028, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQIOCFG_DIFFMODE_FREQ3(MCU3, DQ1) ADDR=0x2002f00a0 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x20026081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x2002a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x2002e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU0, DQ0) ADDR=0x200228110 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU0, DQ1) ADDR=0x200230110 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU1, DQ0) ADDR=0x200268110 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU1, DQ1) ADDR=0x200270110 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU2, DQ0) ADDR=0x2002a8110 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU2, DQ1) ADDR=0x2002b0110 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU3, DQ0) ADDR=0x2002e8110 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDENALWAYSON(MCU3, DQ1) ADDR=0x2002f0110 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200220e74 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200260e74 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2002a0e74 DWORD=0 NUMREGS=0 */ + 0x2002e0cd, //compressed WR cmd + 0xe2e1e09d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2002e0e74 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2002e0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2002e0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2002e0f88 DWORD=0 NUMREGS=0 */ + 0x200220c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200220f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200220f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200220f88 DWORD=0 NUMREGS=0 */ + 0x200260c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200260f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200260f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200260f88 DWORD=0 NUMREGS=0 */ + 0x2002a0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2002a0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2002a0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2002a0f88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200228d80 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200230d80 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200268d80 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200270d80 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2002a8d80 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2002b0d80 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2002e8d80 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2002f0d80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200228d84 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200230d84 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200268d84 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200270d84 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2002a8d84 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2002b0d84 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2002e8d84 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2002f0d84 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200228d88 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200230d88 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200268d88 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200270d88 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2002a8d88 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2002b0d88 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2002e8d88 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2002f0d88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200228d8c DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200230d8c DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200268d8c DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200270d8c DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2002a8d8c DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2002b0d8c DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2002e8d8c DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2002f0d8c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2002281cc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2002301cc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2002681cc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2002701cc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2002a81cc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2002b01cc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2002e81cc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2002f01cc DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200220e00 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200260e00 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2002a0e00 DWORD=0 NUMREGS=0 */ + 0x2002e0f1, //compressed WR cmd + 0x83828180, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0x91908f8e, //compressed WR offset + 0x000000a0, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2002e0e00 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2002e0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2002e0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2002e0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2002e0e80 DWORD=0 NUMREGS=0 */ + 0x200220ed, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0xa091908f, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200220e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200220e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200220e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200220e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200220e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200220e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200220e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200220e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200220e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200220e80 DWORD=0 NUMREGS=0 */ + 0x200260ed, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0xa091908f, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200260e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200260e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200260e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200260e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200260e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200260e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200260e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200260e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200260e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200260e80 DWORD=0 NUMREGS=0 */ + 0x2002a0ed, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0xa091908f, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2002a0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2002a0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2002a0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e30 DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e38 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e3c DWORD=0 NUMREGS=0 */ + 0x00aa01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e40 DWORD=0 NUMREGS=0 */ + 0x00ca0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e44 DWORD=0 NUMREGS=0 */ + 0xa0a0080c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2002a0e80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200228d00 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200230d00 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200268d00 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200270d00 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2002a8d00 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2002b0d00 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2002e8d00 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2002f0d00 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU0) ADDR=0x2002201c0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU1) ADDR=0x2002601c0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU2) ADDR=0x2002a01c0 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU3) ADDR=0x2002e01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ0) ADDR=0x2002281bc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ1) ADDR=0x2002301bc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ0) ADDR=0x2002681bc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ1) ADDR=0x2002701bc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ0) ADDR=0x2002a81bc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ1) ADDR=0x2002b01bc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ0) ADDR=0x2002e81bc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ1) ADDR=0x2002f01bc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200228100 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200230100 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200268100 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200270100 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2002a8100 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2002b0100 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2002e8100 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100070d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2002f0100 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU0) ADDR=0x2002201c4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU1) ADDR=0x2002601c4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU2) ADDR=0x2002a01c4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU3) ADDR=0x2002e01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ0) ADDR=0x2002281c0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ1) ADDR=0x2002301c0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ0) ADDR=0x2002681c0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ1) ADDR=0x2002701c0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ0) ADDR=0x2002a81c0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ1) ADDR=0x2002b01c0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ0) ADDR=0x2002e81c0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ1) ADDR=0x2002f01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200228104 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200230104 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200268104 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200270104 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2002a8104 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2002b0104 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2002e8104 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2002f0104 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU0) ADDR=0x2002201c8 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU1) ADDR=0x2002601c8 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU2) ADDR=0x2002a01c8 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU3) ADDR=0x2002e01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ0) ADDR=0x2002281c4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ1) ADDR=0x2002301c4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ0) ADDR=0x2002681c4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ1) ADDR=0x2002701c4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ0) ADDR=0x2002a81c4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ1) ADDR=0x2002b01c4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ0) ADDR=0x2002e81c4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ1) ADDR=0x2002f01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200228108 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200230108 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200268108 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200270108 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2002a8108 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2002b0108 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2002e8108 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2002f0108 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU0) ADDR=0x2002201cc DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU1) ADDR=0x2002601cc DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU2) ADDR=0x2002a01cc DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU3) ADDR=0x2002e01cc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ0) ADDR=0x2002281c8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ1) ADDR=0x2002301c8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ0) ADDR=0x2002681c8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ1) ADDR=0x2002701c8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ0) ADDR=0x2002a81c8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ1) ADDR=0x2002b01c8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ0) ADDR=0x2002e81c8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ1) ADDR=0x2002f01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20022810c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20023010c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20026810c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20027010c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2002a810c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2002b010c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2002e810c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000406, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2002f010c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU0) ADDR=0x200220088 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU1) ADDR=0x200260088 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU2) ADDR=0x2002a0088 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006822, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU3) ADDR=0x2002e0088 DWORD=0 NUMREGS=0 */ + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2002e01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2002201a0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2002601a0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2002a01a0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2002281a0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2002301a0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2002681a0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2002701a0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2002a81a0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2002b01a0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2002e81a0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2002f01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU0) ADDR=0x200220180 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU1) ADDR=0x200260180 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU2) ADDR=0x2002a0180 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU3) ADDR=0x2002e0180 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200228180 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200230180 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200268180 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200270180 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2002a8180 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2002b0180 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2002e8180 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2002f0180 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00003525, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU3) ADDR=0x2002e00d4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU0) ADDR=0x2002200d4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU1) ADDR=0x2002600d4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x0000001c, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU2) ADDR=0x2002a00d4 DWORD=0 NUMREGS=0 */ + 0x20023801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU0) ADDR=0x200238080 DWORD=0 NUMREGS=0 */ + 0x20027801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU1) ADDR=0x200278080 DWORD=0 NUMREGS=0 */ + 0x2002f801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU3) ADDR=0x2002f8080 DWORD=0 NUMREGS=0 */ + 0x2002b801, //compressed WR cmd + 0x00000020, //compressed WR offset + 0x0000003f, /* WR:AMPH_SLC_SLC_REG0(MCU2) ADDR=0x2002b8080 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200220008 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200260008 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2002a0008 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2002e0008 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200228008 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200230008 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200268008 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200270008 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2002a8008 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2002b0008 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2002e8008 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2002f0008 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x2002c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x2002000d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x2002400d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x2002800d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20020041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20024041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20028041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2002c041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x20022002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200200414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200200410 DWORD=0 NUMREGS=0 */ + 0x10110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20020040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200200408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200240414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200240410 DWORD=0 NUMREGS=0 */ + 0x10110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20024040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200240408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200280414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200280410 DWORD=0 NUMREGS=0 */ + 0x10110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20028040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200280408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2002c0414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2002c0410 DWORD=0 NUMREGS=0 */ + 0x10110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2002c040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2002c0408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20020045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000010, //compressed WR offset + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CHEN(MCC) ADDR=0x20f140040 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20022801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU0, DQ0) ADDR=0x2002280a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU0, DQ1) ADDR=0x2002300a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU1, DQ0) ADDR=0x2002680a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU1, DQ1) ADDR=0x2002700a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU2, DQ0) ADDR=0x2002a80a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU2, DQ1) ADDR=0x2002b00a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU3, DQ0) ADDR=0x2002e80a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000029, //compressed WR offset + 0x00000010, /* WR:AMPSDQ_AMPSDQIOCFG_DQFLTCTRL(MCU3, DQ1) ADDR=0x2002f00a4 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ0) ADDR=0x200228620 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ1) ADDR=0x200230620 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ0) ADDR=0x200268620 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ1) ADDR=0x200270620 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ0) ADDR=0x2002a8620 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ1) ADDR=0x2002b0620 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ0) ADDR=0x2002e8620 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ1) ADDR=0x2002f0620 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20022001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU0) ADDR=0x2002200d4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU1) ADDR=0x2002600d4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU2) ADDR=0x2002a00d4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000035, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_BISTRXMODE(MCU3) ADDR=0x2002e00d4 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200220c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20020019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x20024009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20024019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x20028009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20028019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x2002c009, //compressed WR cmd + 0x00666766, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2002c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x20000042, /* POLL:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS(MCC) ADDR=0x20000079c DWORD=0 */ + 0x000000e7, /* Offset */ + 0x7fff7fff, /* Mask */ + 0x42104210, /* Expected Data */ + 0x20000049, //compressed WR cmd + 0x00e09392, //compressed WR offset + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200228004 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200230004 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200268004 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200270004 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2002a8004 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2002b0004 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2002e8004 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2002f0004 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000a09, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU3) ADDR=0x2002c0428 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU0) ADDR=0x200200428 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU1) ADDR=0x200240428 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU2) ADDR=0x200280428 DWORD=0 NUMREGS=0 */ + 0x20020005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU0) ADDR=0x2002001ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200200010 DWORD=0 NUMREGS=0 */ + 0x20024005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU1) ADDR=0x2002401ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200240010 DWORD=0 NUMREGS=0 */ + 0x20f1401d, //compressed WR cmd + 0x16151413, //compressed WR offset + 0x18171211, //compressed WR offset + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(MCC) ADDR=0x20f14004c DWORD=0 NUMREGS=0 */ + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(MCC) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(MCC) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(MCC) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY0(MCC) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY1(MCC) ADDR=0x20f140048 DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY0(MCC) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY1(MCC) ADDR=0x20f140060 DWORD=0 NUMREGS=0 */ + 0x20028005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU2) ADDR=0x2002801ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200280010 DWORD=0 NUMREGS=0 */ + 0x2002c005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU3) ADDR=0x2002c01ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2002c0010 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20024042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x20028042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x2002c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_b0_post_mcu_locked[] = { + 0x2000004d, //compressed WR cmd + 0x292d3229, //compressed WR offset + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC) ADDR=0x2000004c8 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC) ADDR=0x2000004b4 DWORD=0 NUMREGS=0 */ + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_b0_post_mcu_awake_before_restoration[] = { + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 NUMREGS=0 */ + 0x20022802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008381, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_b0_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200220700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200260700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2002a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2002e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200220708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200260708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2002a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2002e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200220710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200260710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2002a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2002e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20022081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20026081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200220500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200260500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2002a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2002e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200220504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200260504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2002a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2002e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200220508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200260508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2002a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2002e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20022050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20026050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2002a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2002e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200220510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200260510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2002a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2002e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200220514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200260514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2002a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2002e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200220518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200260518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2002a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2002e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20022051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20026051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2002a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2002e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20022841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200228704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20023041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200230704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20026841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200268704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20027041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200270704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2002a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2002b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2002e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2002f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00df00df, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200228b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200230b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200268b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200270b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2002a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2002b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2002e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2002f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200228b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200230b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200268b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200270b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2002a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2002b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2002e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2002f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20020001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20024001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20028001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x2002c001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ +}; + +static const uint32_t aop_ddr_to_awake_b0_post_mcu_awake_after_restoration[] = { + 0x200220c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20f14035, //compressed WR cmd + 0x0201000e, //compressed WR offset + 0x07060504, //compressed WR offset + 0x1a190908, //compressed WR offset + 0x00001c1b, //compressed WR offset + 0x000000ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(MCC) ADDR=0x20f140038 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(MCC) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(MCC) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(MCC) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(MCC) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(MCC) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x003d0900, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(MCC) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(MCC) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_VOLTRAMPTIMER(MCC) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(MCC) ADDR=0x20f140024 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY0(MCC) ADDR=0x20f140064 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY1(MCC) ADDR=0x20f140068 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY0(MCC) ADDR=0x20f14006c DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY1(MCC) ADDR=0x20f140070 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_B0_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003.h new file mode 100644 index 0000000..2de723a --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003.h @@ -0,0 +1,3307 @@ +#ifndef __MCU_INIT_AOP_H__ +#define __MCU_INIT_AOP_H__ + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_ddr[] = { + 0x20020c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20020c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20020c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20020c05c DWORD=0 NUMREGS=0 */ + 0x20024c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20024c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20024c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20024c05c DWORD=0 NUMREGS=0 */ + 0x2002cc11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2002cc01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2002cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2002cc05c DWORD=0 NUMREGS=0 */ + 0x20028c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20028c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20028c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20028c05c DWORD=0 NUMREGS=0 */ + 0x2002007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200200450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200200458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20020045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200200460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2002004c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200200468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200200470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200200474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200200478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2002004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200200480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200200484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200200488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20020048c DWORD=0 NUMREGS=0 */ + 0x2002005d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200200490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2002004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200200498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20020049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2002004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2002004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x2002407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200240450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200240458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20024045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200240460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2002404c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200240468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200240470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200240474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200240478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2002404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200240480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200240484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200240488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20024048c DWORD=0 NUMREGS=0 */ + 0x2002405d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200240490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2002404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200240498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20024049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2002404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2002404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2002404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2002404cc DWORD=0 NUMREGS=0 */ + 0x2002807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200280450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200280458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20028045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200280460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2002804c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200280468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200280470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200280474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200280478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2002804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200280480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200280484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200280488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20028048c DWORD=0 NUMREGS=0 */ + 0x2002805d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200280490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2002804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200280498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20028049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2002804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2002804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2002804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2002804cc DWORD=0 NUMREGS=0 */ + 0x2002c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2002c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2002c0458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2002c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2002c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2002c04c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2002c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2002c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2002c0474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2002c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2002c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2002c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2002c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2002c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2002c048c DWORD=0 NUMREGS=0 */ + 0x2002c05d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2002c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2002c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2002c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2002c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2002c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2002c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2002c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2002c04cc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xece8e4a2, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2002c0280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2002c0284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2002c0288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2002c0390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2002c03a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2002c03c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2002c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2002c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2002c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2002c03c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2002c0398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2002c03a8 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2002c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2002c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2002c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2002c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2002c03d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2002c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2002c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2002c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2002c03e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2002c0388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2002c038c DWORD=0 NUMREGS=0 */ + 0x2002c00d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2002c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2002c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2002c03f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU3) ADDR=0x2002c03f4 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xf0ece8e4, //compressed WR offset + 0xede9e5f5, //compressed WR offset + 0xeeeae6f1, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200200280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200200284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200200288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200200390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2002003a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2002003c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2002003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200200394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2002003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2002003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200200398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2002003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xefebe7f2, //compressed WR offset + 0xf6f4fff3, //compressed WR offset + 0xe0f9f8f7, //compressed WR offset + 0xfae3e2e1, //compressed WR offset + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2002003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20020039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2002003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2002003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2002003d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2002003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2002003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2002003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2002003e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200200388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20020038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2002003e8 DWORD=0 NUMREGS=0 */ + 0x20020009, //compressed WR cmd + 0x00fdfcfb, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2002003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2002003f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU0) ADDR=0x2002003f4 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xf0ece8e4, //compressed WR offset + 0xede9e5f5, //compressed WR offset + 0xeeeae6f1, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200240280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200240284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200240288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200240390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2002403a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2002403c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2002403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200240394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2002403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2002403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200240398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2002403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xefebe7f2, //compressed WR offset + 0xf6f4fff3, //compressed WR offset + 0xe0f9f8f7, //compressed WR offset + 0xfae3e2e1, //compressed WR offset + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2002403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20024039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2002403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2002403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2002403d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2002403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2002403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2002403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2002403e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200240388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20024038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2002403e8 DWORD=0 NUMREGS=0 */ + 0x20024009, //compressed WR cmd + 0x00fdfcfb, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2002403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2002403f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU1) ADDR=0x2002403f4 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xf0ece8e4, //compressed WR offset + 0xede9e5f5, //compressed WR offset + 0xeeeae6f1, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200280280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200280284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200280288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200280390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2002803a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2002803c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2002803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200280394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2002803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2002803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200280398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2002803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xefebe7f2, //compressed WR offset + 0xf6f4fff3, //compressed WR offset + 0xe0f9f8f7, //compressed WR offset + 0xfae3e2e1, //compressed WR offset + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2002803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20028039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2002803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2002803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2002803d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2002803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2002803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2002803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2002803e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200280388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20028038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2002803e8 DWORD=0 NUMREGS=0 */ + 0x20028009, //compressed WR cmd + 0x00fdfcfb, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2002803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2002803f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU2) ADDR=0x2002803f4 DWORD=0 NUMREGS=0 */ + 0x20020051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200200404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20020078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200240404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200240780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20024078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200280404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200280780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20028078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2002c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2002c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2002c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200220000 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200260000 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2002a0000 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2002e0000 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200228000 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200230000 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200268000 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200270000 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2002a8000 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2002b0000 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2002e8000 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2002f0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU0) ADDR=0x20022009c DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU1) ADDR=0x20026009c DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU2) ADDR=0x2002a009c DWORD=0 NUMREGS=0 */ + 0x2002e01d, //compressed WR cmd + 0x2a292827, //compressed WR offset + 0x332e2d2c, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU3) ADDR=0x2002e009c DWORD=0 NUMREGS=0 */ + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU3) ADDR=0x2002e00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU3) ADDR=0x2002e00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU3) ADDR=0x2002e00a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU3) ADDR=0x2002e00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU3) ADDR=0x2002e00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU3) ADDR=0x2002e00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU3) ADDR=0x2002e00cc DWORD=0 NUMREGS=0 */ + 0x20022019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU0) ADDR=0x2002200a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU0) ADDR=0x2002200a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU0) ADDR=0x2002200a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU0) ADDR=0x2002200b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU0) ADDR=0x2002200b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU0) ADDR=0x2002200b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU0) ADDR=0x2002200cc DWORD=0 NUMREGS=0 */ + 0x20026019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU1) ADDR=0x2002600a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU1) ADDR=0x2002600a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU1) ADDR=0x2002600a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU1) ADDR=0x2002600b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU1) ADDR=0x2002600b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU1) ADDR=0x2002600b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU1) ADDR=0x2002600cc DWORD=0 NUMREGS=0 */ + 0x2002a019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU2) ADDR=0x2002a00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU2) ADDR=0x2002a00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU2) ADDR=0x2002a00a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU2) ADDR=0x2002a00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU2) ADDR=0x2002a00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU2) ADDR=0x2002a00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU2) ADDR=0x2002a00cc DWORD=0 NUMREGS=0 */ + 0x200220d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200220d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200220d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200220d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200220d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200220d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200220d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200220d0c DWORD=0 NUMREGS=0 */ + 0x200260d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200260d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200260d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200260d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200260d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200260d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200260d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200260d0c DWORD=0 NUMREGS=0 */ + 0x2002a0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2002a0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2002a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2002a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2002a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2002a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2002a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2002a0d0c DWORD=0 NUMREGS=0 */ + 0x2002e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2002e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2002e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2002e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2002e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2002e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2002e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2002e0d0c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ0) ADDR=0x2002280ac DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ1) ADDR=0x2002300ac DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ0) ADDR=0x2002680ac DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ1) ADDR=0x2002700ac DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ0) ADDR=0x2002a80ac DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ1) ADDR=0x2002b00ac DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ0) ADDR=0x2002e80ac DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ1) ADDR=0x2002f00ac DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ0) ADDR=0x2002280b0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ1) ADDR=0x2002300b0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ0) ADDR=0x2002680b0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ1) ADDR=0x2002700b0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ0) ADDR=0x2002a80b0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ1) ADDR=0x2002b00b0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ0) ADDR=0x2002e80b0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ1) ADDR=0x2002f00b0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ0) ADDR=0x2002280b4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ1) ADDR=0x2002300b4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ0) ADDR=0x2002680b4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ1) ADDR=0x2002700b4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ0) ADDR=0x2002a80b4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ1) ADDR=0x2002b00b4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ0) ADDR=0x2002e80b4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ1) ADDR=0x2002f00b4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ0) ADDR=0x2002280b8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ1) ADDR=0x2002300b8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ0) ADDR=0x2002680b8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ1) ADDR=0x2002700b8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ0) ADDR=0x2002a80b8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ1) ADDR=0x2002b00b8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ0) ADDR=0x2002e80b8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ1) ADDR=0x2002f00b8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ0) ADDR=0x200228084 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ1) ADDR=0x200230084 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ0) ADDR=0x200268084 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ1) ADDR=0x200270084 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ0) ADDR=0x2002a8084 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ1) ADDR=0x2002b0084 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ0) ADDR=0x2002e8084 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ1) ADDR=0x2002f0084 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ0) ADDR=0x200228088 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ1) ADDR=0x200230088 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ0) ADDR=0x200268088 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ1) ADDR=0x200270088 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ0) ADDR=0x2002a8088 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ1) ADDR=0x2002b0088 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ0) ADDR=0x2002e8088 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ1) ADDR=0x2002f0088 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ0) ADDR=0x20022808c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ1) ADDR=0x20023008c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ0) ADDR=0x20026808c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ1) ADDR=0x20027008c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ0) ADDR=0x2002a808c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ1) ADDR=0x2002b008c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ0) ADDR=0x2002e808c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ1) ADDR=0x2002f008c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ0) ADDR=0x200228090 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ1) ADDR=0x200230090 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ0) ADDR=0x200268090 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ1) ADDR=0x200270090 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ0) ADDR=0x2002a8090 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ1) ADDR=0x2002b0090 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ0) ADDR=0x2002e8090 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ1) ADDR=0x2002f0090 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200228b08 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200230b08 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200268b08 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200270b08 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2002a8b08 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2002b0b08 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2002e8b08 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2002f0b08 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200228b0c DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200230b0c DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200268b0c DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200270b0c DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2002a8b0c DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2002b0b0c DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2002e8b0c DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2002f0b0c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ0) ADDR=0x200228114 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ1) ADDR=0x200230114 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ0) ADDR=0x200268114 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ1) ADDR=0x200270114 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ0) ADDR=0x2002a8114 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ1) ADDR=0x2002b0114 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ0) ADDR=0x2002e8114 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ1) ADDR=0x2002f0114 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200220718 DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200260718 DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2002a0718 DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2002e0718 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20022861c DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20023061c DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20026861c DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20027061c DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2002a861c DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2002b061c DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2002e861c DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2002f061c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x20026081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x2002a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x2002e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200220e74 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200260e74 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2002a0e74 DWORD=0 NUMREGS=0 */ + 0x2002e0cd, //compressed WR cmd + 0xe2e1e09d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2002e0e74 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2002e0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2002e0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2002e0f88 DWORD=0 NUMREGS=0 */ + 0x200220c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200220f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200220f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200220f88 DWORD=0 NUMREGS=0 */ + 0x200260c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200260f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200260f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200260f88 DWORD=0 NUMREGS=0 */ + 0x2002a0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2002a0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2002a0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2002a0f88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200228d80 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200230d80 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200268d80 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200270d80 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2002a8d80 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2002b0d80 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2002e8d80 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2002f0d80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200228d84 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200230d84 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200268d84 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200270d84 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2002a8d84 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2002b0d84 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2002e8d84 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2002f0d84 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200228d88 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200230d88 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200268d88 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200270d88 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2002a8d88 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2002b0d88 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2002e8d88 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2002f0d88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200228d8c DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200230d8c DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200268d8c DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200270d8c DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2002a8d8c DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2002b0d8c DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2002e8d8c DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2002f0d8c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2002281cc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2002301cc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2002681cc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2002701cc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2002a81cc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2002b01cc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2002e81cc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2002f01cc DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200220e00 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200260e00 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2002a0e00 DWORD=0 NUMREGS=0 */ + 0x2002e0f9, //compressed WR cmd + 0x83828180, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0x91908f8e, //compressed WR offset + 0x00a09e9f, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2002e0e00 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2002e0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2002e0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2002e0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU3) ADDR=0x2002e0e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU3) ADDR=0x2002e0e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2002e0e80 DWORD=0 NUMREGS=0 */ + 0x200220f5, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0x9f91908f, //compressed WR offset + 0x0000a09e, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200220e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200220e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200220e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200220e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200220e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200220e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200220e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200220e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200220e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU0) ADDR=0x200220e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU0) ADDR=0x200220e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200220e80 DWORD=0 NUMREGS=0 */ + 0x200260f5, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0x9f91908f, //compressed WR offset + 0x0000a09e, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200260e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200260e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200260e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200260e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200260e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200260e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200260e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200260e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200260e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU1) ADDR=0x200260e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU1) ADDR=0x200260e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200260e80 DWORD=0 NUMREGS=0 */ + 0x2002a0f5, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0x9f91908f, //compressed WR offset + 0x0000a09e, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2002a0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2002a0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2002a0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU2) ADDR=0x2002a0e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU2) ADDR=0x2002a0e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2002a0e80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200228d00 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200230d00 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200268d00 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200270d00 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2002a8d00 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2002b0d00 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2002e8d00 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2002f0d00 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU0) ADDR=0x2002201c0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU1) ADDR=0x2002601c0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU2) ADDR=0x2002a01c0 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU3) ADDR=0x2002e01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ0) ADDR=0x2002281bc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ1) ADDR=0x2002301bc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ0) ADDR=0x2002681bc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ1) ADDR=0x2002701bc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ0) ADDR=0x2002a81bc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ1) ADDR=0x2002b01bc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ0) ADDR=0x2002e81bc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ1) ADDR=0x2002f01bc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200228100 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200230100 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200268100 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200270100 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2002a8100 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2002b0100 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2002e8100 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2002f0100 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU0) ADDR=0x2002201c4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU1) ADDR=0x2002601c4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU2) ADDR=0x2002a01c4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU3) ADDR=0x2002e01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ0) ADDR=0x2002281c0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ1) ADDR=0x2002301c0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ0) ADDR=0x2002681c0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ1) ADDR=0x2002701c0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ0) ADDR=0x2002a81c0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ1) ADDR=0x2002b01c0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ0) ADDR=0x2002e81c0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ1) ADDR=0x2002f01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200228104 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200230104 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200268104 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200270104 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2002a8104 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2002b0104 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2002e8104 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2002f0104 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU0) ADDR=0x2002201c8 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU1) ADDR=0x2002601c8 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU2) ADDR=0x2002a01c8 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU3) ADDR=0x2002e01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ0) ADDR=0x2002281c4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ1) ADDR=0x2002301c4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ0) ADDR=0x2002681c4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ1) ADDR=0x2002701c4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ0) ADDR=0x2002a81c4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ1) ADDR=0x2002b01c4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ0) ADDR=0x2002e81c4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ1) ADDR=0x2002f01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200228108 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200230108 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200268108 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200270108 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2002a8108 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2002b0108 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2002e8108 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2002f0108 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU0) ADDR=0x2002201cc DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU1) ADDR=0x2002601cc DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU2) ADDR=0x2002a01cc DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU3) ADDR=0x2002e01cc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ0) ADDR=0x2002281c8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ1) ADDR=0x2002301c8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ0) ADDR=0x2002681c8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ1) ADDR=0x2002701c8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ0) ADDR=0x2002a81c8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ1) ADDR=0x2002b01c8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ0) ADDR=0x2002e81c8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ1) ADDR=0x2002f01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20022810c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20023010c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20026810c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20027010c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2002a810c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2002b010c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2002e810c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2002f010c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU0) ADDR=0x200220088 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU1) ADDR=0x200260088 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU2) ADDR=0x2002a0088 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006822, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU3) ADDR=0x2002e0088 DWORD=0 NUMREGS=0 */ + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2002e01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2002201a0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2002601a0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2002a01a0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2002281a0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2002301a0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2002681a0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2002701a0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2002a81a0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2002b01a0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2002e81a0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2002f01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU0) ADDR=0x200220180 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU1) ADDR=0x200260180 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU2) ADDR=0x2002a0180 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU3) ADDR=0x2002e0180 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200228180 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200230180 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200268180 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200270180 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2002a8180 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2002b0180 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2002e8180 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2002f0180 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x20023801, //compressed WR cmd + 0x0000000c, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU0) ADDR=0x200238030 DWORD=0 NUMREGS=0 */ + 0x2002b801, //compressed WR cmd + 0x0000000c, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU2) ADDR=0x2002b8030 DWORD=0 NUMREGS=0 */ + 0x20027801, //compressed WR cmd + 0x0000000c, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU1) ADDR=0x200278030 DWORD=0 NUMREGS=0 */ + 0x2002f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2c28201f, //compressed WR offset + 0x3b483a2d, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU3) ADDR=0x2002f8030 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU3) ADDR=0x2002f8028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU3) ADDR=0x2002f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU3) ADDR=0x2002f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU3) ADDR=0x2002f8068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU3) ADDR=0x2002f8050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU3) ADDR=0x2002f8060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU3) ADDR=0x2002f8078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU3) ADDR=0x2002f807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU3) ADDR=0x2002f8080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU3) ADDR=0x2002f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2002f80b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU3) ADDR=0x2002f80b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU3) ADDR=0x2002f80e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU3) ADDR=0x2002f8120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU3) ADDR=0x2002f80ec DWORD=0 NUMREGS=0 */ + 0x2002f83d, //compressed WR cmd + 0x3247433c, //compressed WR offset + 0x36343130, //compressed WR offset + 0x4c4e3837, //compressed WR offset + 0x5452504d, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU3) ADDR=0x2002f80f0 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU3) ADDR=0x2002f810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2002f811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2002f80c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU3) ADDR=0x2002f80c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU3) ADDR=0x2002f80c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU3) ADDR=0x2002f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2002f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU3) ADDR=0x2002f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU3) ADDR=0x2002f80e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2002f8138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU3) ADDR=0x2002f8130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU3) ADDR=0x2002f8134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU3) ADDR=0x2002f8140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2002f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU3) ADDR=0x2002f8150 DWORD=0 NUMREGS=0 */ + 0x2002f811, //compressed WR cmd + 0x02030953, //compressed WR offset + 0x000000bf, //compressed WR offset + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU3) ADDR=0x2002f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU3) ADDR=0x2002f8024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU3) ADDR=0x2002f800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU3) ADDR=0x2002f8008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2002f82fc DWORD=0 NUMREGS=0 */ + 0x2002383d, //compressed WR cmd + 0x1a16110a, //compressed WR offset + 0x1f1e1814, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x3c3b483a, //compressed WR offset + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU0) ADDR=0x200238028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU0) ADDR=0x200238044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU0) ADDR=0x200238058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU0) ADDR=0x200238068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU0) ADDR=0x200238050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU0) ADDR=0x200238060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU0) ADDR=0x200238078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU0) ADDR=0x20023807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU0) ADDR=0x200238080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU0) ADDR=0x2002380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2002380b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU0) ADDR=0x2002380b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU0) ADDR=0x2002380e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU0) ADDR=0x200238120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU0) ADDR=0x2002380ec DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU0) ADDR=0x2002380f0 DWORD=0 NUMREGS=0 */ + 0x2002383d, //compressed WR cmd + 0x30324743, //compressed WR offset + 0x37363431, //compressed WR offset + 0x4d4c4e38, //compressed WR offset + 0x53545250, //compressed WR offset + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU0) ADDR=0x20023810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20023811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2002380c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU0) ADDR=0x2002380c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU0) ADDR=0x2002380c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU0) ADDR=0x2002380d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2002380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU0) ADDR=0x2002380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU0) ADDR=0x2002380e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200238138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU0) ADDR=0x200238130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU0) ADDR=0x200238134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU0) ADDR=0x200238140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200238148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU0) ADDR=0x200238150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU0) ADDR=0x20023814c DWORD=0 NUMREGS=0 */ + 0x2002380d, //compressed WR cmd + 0xbf020309, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU0) ADDR=0x200238024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU0) ADDR=0x20023800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU0) ADDR=0x200238008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2002382fc DWORD=0 NUMREGS=0 */ + 0x2002b83d, //compressed WR cmd + 0x1a16110a, //compressed WR offset + 0x1f1e1814, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x3c3b483a, //compressed WR offset + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU2) ADDR=0x2002b8028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU2) ADDR=0x2002b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU2) ADDR=0x2002b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU2) ADDR=0x2002b8068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU2) ADDR=0x2002b8050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU2) ADDR=0x2002b8060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU2) ADDR=0x2002b8078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU2) ADDR=0x2002b807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU2) ADDR=0x2002b8080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU2) ADDR=0x2002b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2002b80b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU2) ADDR=0x2002b80b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU2) ADDR=0x2002b80e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU2) ADDR=0x2002b8120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU2) ADDR=0x2002b80ec DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU2) ADDR=0x2002b80f0 DWORD=0 NUMREGS=0 */ + 0x2002b83d, //compressed WR cmd + 0x30324743, //compressed WR offset + 0x37363431, //compressed WR offset + 0x4d4c4e38, //compressed WR offset + 0x53545250, //compressed WR offset + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU2) ADDR=0x2002b810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2002b811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2002b80c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU2) ADDR=0x2002b80c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU2) ADDR=0x2002b80c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU2) ADDR=0x2002b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2002b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU2) ADDR=0x2002b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU2) ADDR=0x2002b80e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2002b8138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU2) ADDR=0x2002b8130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU2) ADDR=0x2002b8134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU2) ADDR=0x2002b8140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2002b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU2) ADDR=0x2002b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU2) ADDR=0x2002b814c DWORD=0 NUMREGS=0 */ + 0x2002b80d, //compressed WR cmd + 0xbf020309, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU2) ADDR=0x2002b8024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU2) ADDR=0x2002b800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU2) ADDR=0x2002b8008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2002b82fc DWORD=0 NUMREGS=0 */ + 0x2002783d, //compressed WR cmd + 0x1a16110a, //compressed WR offset + 0x1f1e1814, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x3c3b483a, //compressed WR offset + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU1) ADDR=0x200278028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU1) ADDR=0x200278044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU1) ADDR=0x200278058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU1) ADDR=0x200278068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU1) ADDR=0x200278050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU1) ADDR=0x200278060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU1) ADDR=0x200278078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU1) ADDR=0x20027807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU1) ADDR=0x200278080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU1) ADDR=0x2002780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2002780b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU1) ADDR=0x2002780b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU1) ADDR=0x2002780e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU1) ADDR=0x200278120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU1) ADDR=0x2002780ec DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU1) ADDR=0x2002780f0 DWORD=0 NUMREGS=0 */ + 0x2002783d, //compressed WR cmd + 0x30324743, //compressed WR offset + 0x37363431, //compressed WR offset + 0x4d4c4e38, //compressed WR offset + 0x53545250, //compressed WR offset + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU1) ADDR=0x20027810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20027811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2002780c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU1) ADDR=0x2002780c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU1) ADDR=0x2002780c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU1) ADDR=0x2002780d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2002780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU1) ADDR=0x2002780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU1) ADDR=0x2002780e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200278138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU1) ADDR=0x200278130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU1) ADDR=0x200278134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU1) ADDR=0x200278140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200278148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU1) ADDR=0x200278150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU1) ADDR=0x20027814c DWORD=0 NUMREGS=0 */ + 0x2002780d, //compressed WR cmd + 0xbf020309, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU1) ADDR=0x200278024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU1) ADDR=0x20027800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU1) ADDR=0x200278008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2002782fc DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200220008 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200260008 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2002a0008 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2002e0008 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200228008 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200230008 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200268008 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200270008 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2002a8008 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2002b0008 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2002e8008 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2002f0008 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x2002c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x2002000d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x2002400d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x2002800d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20020041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20024041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20028041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2002c041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x20022002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200200414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200200410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20020040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200200408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200240414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200240410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20024040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200240408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200280414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200280410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20028040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200280408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2002c0414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2002c0410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2002c040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2002c0408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20020045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000010, //compressed WR offset + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CHEN(MCC) ADDR=0x20f140040 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20023805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2002380c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200238138 DWORD=0 NUMREGS=0 */ + 0x20027805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2002780c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200278138 DWORD=0 NUMREGS=0 */ + 0x2002f805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2002f80c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2002f8138 DWORD=0 NUMREGS=0 */ + 0x2002b805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2002b80c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2002b8138 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ0) ADDR=0x200228620 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ1) ADDR=0x200230620 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ0) ADDR=0x200268620 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ1) ADDR=0x200270620 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ0) ADDR=0x2002a8620 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ1) ADDR=0x2002b0620 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ0) ADDR=0x2002e8620 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ1) ADDR=0x2002f0620 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20023801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x0000040e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2002382fc DWORD=0 NUMREGS=0 */ + 0x20027801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x0000040e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2002782fc DWORD=0 NUMREGS=0 */ + 0x2002f801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x0000040e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2002f82fc DWORD=0 NUMREGS=0 */ + 0x2002b801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x0000040e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2002b82fc DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200220c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x20023811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU0) ADDR=0x20023809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU0) ADDR=0x200238098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU0) ADDR=0x200238108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU0) ADDR=0x2002380cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU0) ADDR=0x20023813c DWORD=0 NUMREGS=0 */ + 0x20027811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU1) ADDR=0x20027809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU1) ADDR=0x200278098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU1) ADDR=0x200278108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU1) ADDR=0x2002780cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU1) ADDR=0x20027813c DWORD=0 NUMREGS=0 */ + 0x2002f811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU3) ADDR=0x2002f809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU3) ADDR=0x2002f8098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU3) ADDR=0x2002f8108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU3) ADDR=0x2002f80cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU3) ADDR=0x2002f813c DWORD=0 NUMREGS=0 */ + 0x2002b811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU2) ADDR=0x2002b809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU2) ADDR=0x2002b8098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU2) ADDR=0x2002b8108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU2) ADDR=0x2002b80cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU2) ADDR=0x2002b813c DWORD=0 NUMREGS=0 */ + 0x20020005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20020019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x20024005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20024019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x20028005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20028019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x2002c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2002c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x20000042, /* POLL:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS(MCC) ADDR=0x20000079c DWORD=0 */ + 0x000000e7, /* Offset */ + 0x7fff7fff, /* Mask */ + 0x42104210, /* Expected Data */ + 0x20000049, //compressed WR cmd + 0x00e09392, //compressed WR offset + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200228004 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200230004 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200268004 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200270004 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2002a8004 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2002b0004 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2002e8004 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2002f0004 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000a09, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU3) ADDR=0x2002c0428 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU0) ADDR=0x200200428 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU1) ADDR=0x200240428 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU2) ADDR=0x200280428 DWORD=0 NUMREGS=0 */ + 0x20020005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU0) ADDR=0x2002001ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200200010 DWORD=0 NUMREGS=0 */ + 0x20024005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU1) ADDR=0x2002401ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200240010 DWORD=0 NUMREGS=0 */ + 0x20f1401d, //compressed WR cmd + 0x16151413, //compressed WR offset + 0x18171211, //compressed WR offset + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(MCC) ADDR=0x20f14004c DWORD=0 NUMREGS=0 */ + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(MCC) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(MCC) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(MCC) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY0(MCC) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY1(MCC) ADDR=0x20f140048 DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY0(MCC) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY1(MCC) ADDR=0x20f140060 DWORD=0 NUMREGS=0 */ + 0x20028005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU2) ADDR=0x2002801ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200280010 DWORD=0 NUMREGS=0 */ + 0x2002c005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU3) ADDR=0x2002c01ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2002c0010 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20024042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x20028042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x2002c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_locked[] = { + 0x2000004d, //compressed WR cmd + 0x292d3229, //compressed WR offset + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC) ADDR=0x2000004c8 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC) ADDR=0x2000004b4 DWORD=0 NUMREGS=0 */ + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_before_restoration[] = { + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 NUMREGS=0 */ + 0x20022802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008381, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200220700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200260700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2002a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2002e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200220708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200260708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2002a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2002e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200220710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200260710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2002a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2002e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20022081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20026081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200220500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200260500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2002a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2002e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200220504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200260504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2002a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2002e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200220508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200260508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2002a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2002e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20022050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20026050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2002a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2002e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200220510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200260510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2002a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2002e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200220514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200260514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2002a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2002e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200220518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200260518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2002a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2002e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20022051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20026051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2002a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2002e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20022841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200228704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20023041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200230704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20026841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200268704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20027041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200270704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2002a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2002b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2002e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2002f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200228b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200230b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200268b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200270b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2002a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2002b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2002e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2002f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200228b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200230b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200268b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200270b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2002a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2002b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2002e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2002f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20020001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20024001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20028001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x2002c001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 ## Save the value after Bucket 1 Calibration. End of Step 10 */ + /* FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200200458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200240458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200280458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2002c0458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb303440b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20f14001, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(MCC) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x00000006, /* Offset */ + 0x00061a80, /* Data -- GLBTIMER_GLBTIMER_ZQCTIMER 0x0 ## Save the value after End of Step 18 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* END OF RESTORATION */ + 0x00000044, /* NOOP for 64bit alignment*/ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_after_restoration[] = { + 0x200220c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20f14031, //compressed WR cmd + 0x0201000e, //compressed WR offset + 0x08070504, //compressed WR offset + 0x1b1a1909, //compressed WR offset + 0x0000001c, //compressed WR offset + 0x000000ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(MCC) ADDR=0x20f140038 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(MCC) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(MCC) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(MCC) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(MCC) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(MCC) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(MCC) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_VOLTRAMPTIMER(MCC) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(MCC) ADDR=0x20f140024 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY0(MCC) ADDR=0x20f140064 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY1(MCC) ADDR=0x20f140068 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY0(MCC) ADDR=0x20f14006c DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY1(MCC) ADDR=0x20f140070 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003_a0.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003_a0.h new file mode 100644 index 0000000..c80a00c --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_1200_s8003_a0.h @@ -0,0 +1,3280 @@ +#ifndef __MCU_INIT_AOP_A0_H__ +#define __MCU_INIT_AOP_A0_H__ + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_mcu_ddr[] = { + 0x20020c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20020c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20020c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20020c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20020c05c DWORD=0 NUMREGS=0 */ + 0x20024c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20024c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20024c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20024c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20024c05c DWORD=0 NUMREGS=0 */ + 0x2002cc11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2002cc01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2002cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2002cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2002cc05c DWORD=0 NUMREGS=0 */ + 0x20028c11, //compressed WR cmd + 0x09080807, //compressed WR offset + 0x00000017, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20028c01c DWORD=0 NUMREGS=0 */ + 0x00000076, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000078, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20028c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20028c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20028c05c DWORD=0 NUMREGS=0 */ + 0x2002007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200200450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200200458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20020045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200200460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2002004c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200200468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200200470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200200474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200200478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2002004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200200480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200200484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200200488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20020048c DWORD=0 NUMREGS=0 */ + 0x2002005d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200200490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2002004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200200498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20020049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2002004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2002004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x2002407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200240450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200240458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20024045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200240460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2002404c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200240468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200240470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200240474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200240478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2002404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200240480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200240484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200240488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20024048c DWORD=0 NUMREGS=0 */ + 0x2002405d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200240490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2002404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200240498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20024049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2002404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2002404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2002404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2002404cc DWORD=0 NUMREGS=0 */ + 0x2002807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200280450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200280458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20028045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200280460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2002804c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200280468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200280470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200280474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200280478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2002804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200280480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200280484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200280488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20028048c DWORD=0 NUMREGS=0 */ + 0x2002805d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200280490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2002804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200280498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20028049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2002804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2002804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2002804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2002804cc DWORD=0 NUMREGS=0 */ + 0x2002c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3018, //compressed WR offset + 0x311e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2002c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2002c0458 DWORD=0 NUMREGS=0 */ + 0xce012402, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2002c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2002c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2002c04c0 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2002c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0xf303030b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2002c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2002c0474 DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2002c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2002c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2002c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2002c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2002c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2002c048c DWORD=0 NUMREGS=0 */ + 0x2002c05d, //compressed WR cmd + 0x27263224, //compressed WR offset + 0x332a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2002c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2002c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2002c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2002c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2002c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2002c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2002c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2002c04cc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xece8e4a2, //compressed WR offset + 0xe9e5f5f0, //compressed WR offset + 0xeae6f1ed, //compressed WR offset + 0x00103306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2002c0280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2002c0284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2002c0288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2002c0390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2002c03a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2002c03c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2002c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2002c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2002c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2002c03c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2002c0398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2002c03a8 DWORD=0 NUMREGS=0 */ + 0x2002c03d, //compressed WR cmd + 0xebe7f2ee, //compressed WR offset + 0xf4fff3ef, //compressed WR offset + 0xf9f8f7f6, //compressed WR offset + 0xe3e2e1e0, //compressed WR offset + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2002c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2002c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2002c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2002c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2002c03d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2002c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2002c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2002c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2002c03e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2002c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2002c0384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2002c0388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2002c038c DWORD=0 NUMREGS=0 */ + 0x2002c00d, //compressed WR cmd + 0xfdfcfbfa, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2002c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2002c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2002c03f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU3) ADDR=0x2002c03f4 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xf0ece8e4, //compressed WR offset + 0xede9e5f5, //compressed WR offset + 0xeeeae6f1, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200200280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200200284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200200288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200200390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2002003a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2002003c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2002003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200200394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2002003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2002003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200200398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2002003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x2002003d, //compressed WR cmd + 0xefebe7f2, //compressed WR offset + 0xf6f4fff3, //compressed WR offset + 0xe0f9f8f7, //compressed WR offset + 0xfae3e2e1, //compressed WR offset + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2002003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20020039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2002003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2002003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2002003d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2002003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2002003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2002003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2002003e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200200380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200200384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200200388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20020038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2002003e8 DWORD=0 NUMREGS=0 */ + 0x20020009, //compressed WR cmd + 0x00fdfcfb, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2002003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2002003f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU0) ADDR=0x2002003f4 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xf0ece8e4, //compressed WR offset + 0xede9e5f5, //compressed WR offset + 0xeeeae6f1, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200240280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200240284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200240288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200240390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2002403a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2002403c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2002403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200240394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2002403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2002403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200240398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2002403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x2002403d, //compressed WR cmd + 0xefebe7f2, //compressed WR offset + 0xf6f4fff3, //compressed WR offset + 0xe0f9f8f7, //compressed WR offset + 0xfae3e2e1, //compressed WR offset + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2002403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20024039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2002403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2002403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2002403d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2002403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2002403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2002403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2002403e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200240380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200240384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200240388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20024038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2002403e8 DWORD=0 NUMREGS=0 */ + 0x20024009, //compressed WR cmd + 0x00fdfcfb, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2002403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2002403f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU1) ADDR=0x2002403f4 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xa2a1a0e1, //compressed WR offset + 0xf0ece8e4, //compressed WR offset + 0xede9e5f5, //compressed WR offset + 0xeeeae6f1, //compressed WR offset + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x00050d0a, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200280280 DWORD=0 NUMREGS=0 */ + 0x00050c06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200280284 DWORD=0 NUMREGS=0 */ + 0x00010c01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200280288 DWORD=0 NUMREGS=0 */ + 0x531a060b, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200280390 DWORD=0 NUMREGS=0 */ + 0x18060d0b, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2002803a0 DWORD=0 NUMREGS=0 */ + 0x366c0078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x78071012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2002803c0 DWORD=0 NUMREGS=0 */ + 0x140a90b4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2002803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200280394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2002803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2002803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200280398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2002803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x2002803d, //compressed WR cmd + 0xefebe7f2, //compressed WR offset + 0xf6f4fff3, //compressed WR offset + 0xe0f9f8f7, //compressed WR offset + 0xfae3e2e1, //compressed WR offset + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2002803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20028039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2002803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2002803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x62265295, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2002803d0 DWORD=0 NUMREGS=0 */ + 0x38c486cc, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2002803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2002803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2002803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2002803e4 DWORD=0 NUMREGS=0 */ + 0x00113306, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200280380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200280384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200280388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20028038c DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2002803e8 DWORD=0 NUMREGS=0 */ + 0x20028009, //compressed WR cmd + 0x00fdfcfb, //compressed WR offset + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2002803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2002803f0 DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ3(MCU2) ADDR=0x2002803f4 DWORD=0 NUMREGS=0 */ + 0x20020051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200200404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20020078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200240404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200240780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20024078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200280404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200280780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20028078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2002c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2002c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2002c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000f0f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200220000 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200260000 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2002a0000 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2002e0000 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200228000 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200230000 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200268000 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200270000 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2002a8000 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2002b0000 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2002e8000 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2002f0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU0) ADDR=0x20022009c DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU1) ADDR=0x20026009c DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000027, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU2) ADDR=0x2002a009c DWORD=0 NUMREGS=0 */ + 0x2002e01d, //compressed WR cmd + 0x2a292827, //compressed WR offset + 0x332e2d2c, //compressed WR offset + 0x000b316b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F0(MCU3) ADDR=0x2002e009c DWORD=0 NUMREGS=0 */ + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU3) ADDR=0x2002e00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU3) ADDR=0x2002e00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU3) ADDR=0x2002e00a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU3) ADDR=0x2002e00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU3) ADDR=0x2002e00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU3) ADDR=0x2002e00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU3) ADDR=0x2002e00cc DWORD=0 NUMREGS=0 */ + 0x20022019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU0) ADDR=0x2002200a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU0) ADDR=0x2002200a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU0) ADDR=0x2002200a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU0) ADDR=0x2002200b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU0) ADDR=0x2002200b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU0) ADDR=0x2002200b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU0) ADDR=0x2002200cc DWORD=0 NUMREGS=0 */ + 0x20026019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU1) ADDR=0x2002600a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU1) ADDR=0x2002600a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU1) ADDR=0x2002600a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU1) ADDR=0x2002600b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU1) ADDR=0x2002600b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU1) ADDR=0x2002600b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU1) ADDR=0x2002600cc DWORD=0 NUMREGS=0 */ + 0x2002a019, //compressed WR cmd + 0x2c2a2928, //compressed WR offset + 0x00332e2d, //compressed WR offset + 0x000b216b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F1(MCU2) ADDR=0x2002a00a0 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F2(MCU2) ADDR=0x2002a00a4 DWORD=0 NUMREGS=0 */ + 0x000b3d6b, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDSPD_F3(MCU2) ADDR=0x2002a00a8 DWORD=0 NUMREGS=0 */ + 0x00080508, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F1(MCU2) ADDR=0x2002a00b0 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F2(MCU2) ADDR=0x2002a00b4 DWORD=0 NUMREGS=0 */ + 0x00083d08, /* WR:AMPSCA_AMPSCAIOCFG_NONDQDS_F3(MCU2) ADDR=0x2002a00b8 DWORD=0 NUMREGS=0 */ + 0x000000db, /* WR:AMPSCA_AMPSCAIOCFG_CACKCSWKDS(MCU2) ADDR=0x2002a00cc DWORD=0 NUMREGS=0 */ + 0x200220d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200220d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200220d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200220d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200220d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200220d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200220d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200220d0c DWORD=0 NUMREGS=0 */ + 0x200260d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200260d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200260d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200260d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200260d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200260d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200260d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200260d0c DWORD=0 NUMREGS=0 */ + 0x2002a0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2002a0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2002a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2002a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2002a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2002a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2002a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2002a0d0c DWORD=0 NUMREGS=0 */ + 0x2002e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2002e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2002e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2002e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2002e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2002e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2002e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2002e0d0c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ0) ADDR=0x2002280ac DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU0, DQ1) ADDR=0x2002300ac DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ0) ADDR=0x2002680ac DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU1, DQ1) ADDR=0x2002700ac DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ0) ADDR=0x2002a80ac DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU2, DQ1) ADDR=0x2002b00ac DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ0) ADDR=0x2002e80ac DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002b, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F0(MCU3, DQ1) ADDR=0x2002f00ac DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ0) ADDR=0x2002280b0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU0, DQ1) ADDR=0x2002300b0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ0) ADDR=0x2002680b0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU1, DQ1) ADDR=0x2002700b0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ0) ADDR=0x2002a80b0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU2, DQ1) ADDR=0x2002b00b0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ0) ADDR=0x2002e80b0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002c, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F1(MCU3, DQ1) ADDR=0x2002f00b0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ0) ADDR=0x2002280b4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU0, DQ1) ADDR=0x2002300b4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ0) ADDR=0x2002680b4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU1, DQ1) ADDR=0x2002700b4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ0) ADDR=0x2002a80b4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU2, DQ1) ADDR=0x2002b00b4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ0) ADDR=0x2002e80b4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002d, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F2(MCU3, DQ1) ADDR=0x2002f00b4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ0) ADDR=0x2002280b8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU0, DQ1) ADDR=0x2002300b8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ0) ADDR=0x2002680b8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU1, DQ1) ADDR=0x2002700b8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ0) ADDR=0x2002a80b8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU2, DQ1) ADDR=0x2002b00b8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ0) ADDR=0x2002e80b8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000002e, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDS_F3(MCU3, DQ1) ADDR=0x2002f00b8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ0) ADDR=0x200228084 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU0, DQ1) ADDR=0x200230084 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ0) ADDR=0x200268084 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU1, DQ1) ADDR=0x200270084 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ0) ADDR=0x2002a8084 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU2, DQ1) ADDR=0x2002b0084 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ0) ADDR=0x2002e8084 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000021, //compressed WR offset + 0x000c0b08, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F0(MCU3, DQ1) ADDR=0x2002f0084 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ0) ADDR=0x200228088 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU0, DQ1) ADDR=0x200230088 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ0) ADDR=0x200268088 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU1, DQ1) ADDR=0x200270088 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ0) ADDR=0x2002a8088 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU2, DQ1) ADDR=0x2002b0088 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ0) ADDR=0x2002e8088 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F1(MCU3, DQ1) ADDR=0x2002f0088 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ0) ADDR=0x20022808c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU0, DQ1) ADDR=0x20023008c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ0) ADDR=0x20026808c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU1, DQ1) ADDR=0x20027008c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ0) ADDR=0x2002a808c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU2, DQ1) ADDR=0x2002b008c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ0) ADDR=0x2002e808c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000023, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F2(MCU3, DQ1) ADDR=0x2002f008c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ0) ADDR=0x200228090 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU0, DQ1) ADDR=0x200230090 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ0) ADDR=0x200268090 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU1, DQ1) ADDR=0x200270090 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ0) ADDR=0x2002a8090 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU2, DQ1) ADDR=0x2002b0090 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ0) ADDR=0x2002e8090 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000024, //compressed WR offset + 0x00080b00, /* WR:AMPSDQ_AMPSDQIOCFG_DQDQSDS_F3(MCU3, DQ1) ADDR=0x2002f0090 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200228b08 DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200230b08 DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200268b08 DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200270b08 DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2002a8b08 DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2002b0b08 DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2002e8b08 DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c2, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2002f0b08 DWORD=0 NUMREGS=0 */ + 0x20022881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200228b0c DWORD=0 NUMREGS=0 */ + 0x20023081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200230b0c DWORD=0 NUMREGS=0 */ + 0x20026881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200268b0c DWORD=0 NUMREGS=0 */ + 0x20027081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200270b0c DWORD=0 NUMREGS=0 */ + 0x2002a881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2002a8b0c DWORD=0 NUMREGS=0 */ + 0x2002b081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2002b0b0c DWORD=0 NUMREGS=0 */ + 0x2002e881, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2002e8b0c DWORD=0 NUMREGS=0 */ + 0x2002f081, //compressed WR cmd + 0x000000c3, //compressed WR offset + 0x00800080, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2002f0b0c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ0) ADDR=0x200228114 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU0, DQ1) ADDR=0x200230114 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ0) ADDR=0x200268114 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU1, DQ1) ADDR=0x200270114 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ0) ADDR=0x2002a8114 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU2, DQ1) ADDR=0x2002b0114 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ0) ADDR=0x2002e8114 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000045, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQRDTIM_DQSPDRES(MCU3, DQ1) ADDR=0x2002f0114 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200220718 DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200260718 DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2002a0718 DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x0303030b, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2002e0718 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20022861c DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20023061c DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20026861c DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20027061c DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2002a861c DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2002b061c DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2002e861c DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x0003000b, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2002f061c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200228608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200230608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200268608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200270608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2002a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2002b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2002e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2002f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000004, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000004, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x20026081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x2002a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x2002e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff02ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200220e74 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200260e74 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2002a0e74 DWORD=0 NUMREGS=0 */ + 0x2002e0cd, //compressed WR cmd + 0xe2e1e09d, //compressed WR offset + 0x04000410, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2002e0e74 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2002e0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2002e0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2002e0f88 DWORD=0 NUMREGS=0 */ + 0x200220c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200220f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200220f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200220f88 DWORD=0 NUMREGS=0 */ + 0x200260c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200260f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200260f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200260f88 DWORD=0 NUMREGS=0 */ + 0x2002a0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2002a0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2002a0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2002a0f88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200228d80 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200230d80 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200268d80 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200270d80 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2002a8d80 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2002b0d80 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2002e8d80 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2002f0d80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200228d84 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200230d84 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200268d84 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200270d84 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2002a8d84 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2002b0d84 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2002e8d84 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2002f0d84 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200228d88 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200230d88 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200268d88 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200270d88 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2002a8d88 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2002b0d88 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2002e8d88 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2002f0d88 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200228d8c DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200230d8c DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200268d8c DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200270d8c DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2002a8d8c DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2002b0d8c DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2002e8d8c DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2002f0d8c DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2002281cc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2002301cc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2002681cc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2002701cc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2002a81cc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2002b01cc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2002e81cc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2002f01cc DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200220e00 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200260e00 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2002a0e00 DWORD=0 NUMREGS=0 */ + 0x2002e0f9, //compressed WR cmd + 0x83828180, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0x91908f8e, //compressed WR offset + 0x00a09e9f, //compressed WR offset + 0x00001426, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2002e0e00 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2002e0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2002e0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2002e0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2002e0e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2002e0e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2002e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU3) ADDR=0x2002e0e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU3) ADDR=0x2002e0e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2002e0e80 DWORD=0 NUMREGS=0 */ + 0x200220f5, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0x9f91908f, //compressed WR offset + 0x0000a09e, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200220e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200220e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200220e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200220e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200220e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200220e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200220e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200220e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200220e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU0) ADDR=0x200220e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU0) ADDR=0x200220e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200220e80 DWORD=0 NUMREGS=0 */ + 0x200260f5, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0x9f91908f, //compressed WR offset + 0x0000a09e, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200260e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200260e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200260e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200260e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200260e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200260e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200260e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200260e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200260e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU1) ADDR=0x200260e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU1) ADDR=0x200260e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200260e80 DWORD=0 NUMREGS=0 */ + 0x2002a0f5, //compressed WR cmd + 0x89838281, //compressed WR offset + 0x8e8c8b8a, //compressed WR offset + 0x9f91908f, //compressed WR offset + 0x0000a09e, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x00001422, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2002a0e08 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ + 0x0000301e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2002a0e24 DWORD=0 NUMREGS=0 */ + 0x03111004, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2002a0e28 DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e2c DWORD=0 NUMREGS=0 */ + 0x55555e26, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2002a0e30 DWORD=0 NUMREGS=0 */ + 0x00b101d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e38 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2002a0e3c DWORD=0 NUMREGS=0 */ + 0x00f801d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e40 DWORD=0 NUMREGS=0 */ + 0x012f0360, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2002a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU2) ADDR=0x2002a0e7c DWORD=0 NUMREGS=0 */ + 0x00a00a0f, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSDLLMULFACTOR(MCU2) ADDR=0x2002a0e78 DWORD=0 NUMREGS=0 */ + 0xa0a00c0c, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2002a0e80 DWORD=0 NUMREGS=0 */ + 0x200228c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200228d00 DWORD=0 NUMREGS=0 */ + 0x200230c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200230d00 DWORD=0 NUMREGS=0 */ + 0x200268c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200268d00 DWORD=0 NUMREGS=0 */ + 0x200270c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200270d00 DWORD=0 NUMREGS=0 */ + 0x2002a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2002a8d00 DWORD=0 NUMREGS=0 */ + 0x2002b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2002b0d00 DWORD=0 NUMREGS=0 */ + 0x2002e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2002e8d00 DWORD=0 NUMREGS=0 */ + 0x2002f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2002f0d00 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU0) ADDR=0x2002201c0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU1) ADDR=0x2002601c0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU2) ADDR=0x2002a01c0 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x00000008, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ0(MCU3) ADDR=0x2002e01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ0) ADDR=0x2002281bc DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU0, DQ1) ADDR=0x2002301bc DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ0) ADDR=0x2002681bc DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU1, DQ1) ADDR=0x2002701bc DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ0) ADDR=0x2002a81bc DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU2, DQ1) ADDR=0x2002b01bc DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ0) ADDR=0x2002e81bc DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x0000006f, //compressed WR offset + 0x00000008, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ0(MCU3, DQ1) ADDR=0x2002f01bc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200228100 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200230100 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200268100 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200270100 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2002a8100 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2002b0100 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2002e8100 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x0100080d, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2002f0100 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU0) ADDR=0x2002201c4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU1) ADDR=0x2002601c4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU2) ADDR=0x2002a01c4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x0000000c, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ1(MCU3) ADDR=0x2002e01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ0) ADDR=0x2002281c0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU0, DQ1) ADDR=0x2002301c0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ0) ADDR=0x2002681c0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU1, DQ1) ADDR=0x2002701c0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ0) ADDR=0x2002a81c0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU2, DQ1) ADDR=0x2002b01c0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ0) ADDR=0x2002e81c0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000070, //compressed WR offset + 0x0000000c, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ1(MCU3, DQ1) ADDR=0x2002f01c0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200228104 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200230104 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200268104 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200270104 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2002a8104 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2002b0104 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2002e8104 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100070a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2002f0104 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU0) ADDR=0x2002201c8 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU1) ADDR=0x2002601c8 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU2) ADDR=0x2002a01c8 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x00000030, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ2(MCU3) ADDR=0x2002e01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ0) ADDR=0x2002281c4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU0, DQ1) ADDR=0x2002301c4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ0) ADDR=0x2002681c4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU1, DQ1) ADDR=0x2002701c4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ0) ADDR=0x2002a81c4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU2, DQ1) ADDR=0x2002b01c4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ0) ADDR=0x2002e81c4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000071, //compressed WR offset + 0x00000030, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ2(MCU3, DQ1) ADDR=0x2002f01c4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200228108 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200230108 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200268108 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200270108 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2002a8108 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2002b0108 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2002e8108 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2002f0108 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU0) ADDR=0x2002201cc DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU1) ADDR=0x2002601cc DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU2) ADDR=0x2002a01cc DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x0000003f, /* WR:AMPSCA_AMPSCADLLCTL_CAOUTDLLSCL_FREQ3(MCU3) ADDR=0x2002e01cc DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ0) ADDR=0x2002281c8 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU0, DQ1) ADDR=0x2002301c8 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ0) ADDR=0x2002681c8 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU1, DQ1) ADDR=0x2002701c8 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ0) ADDR=0x2002a81c8 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU2, DQ1) ADDR=0x2002b01c8 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ0) ADDR=0x2002e81c8 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000072, //compressed WR offset + 0x0000003f, /* WR:AMPSDQ_AMPSDQDLLCTL_DQSINDLL0SCL_FREQ3(MCU3, DQ1) ADDR=0x2002f01c8 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20022810c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20023010c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20026810c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20027010c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2002a810c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2002b010c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2002e810c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000508, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2002f010c DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2002201a4 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2002601a4 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2002a01a4 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2002e01a4 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2002281a4 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2002301a4 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2002681a4 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2002701a4 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2002a81a4 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2002b01a4 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2002e81a4 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017550, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2002f01a4 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU0) ADDR=0x200220088 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU1) ADDR=0x200260088 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000022, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU2) ADDR=0x2002a0088 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006822, //compressed WR offset + 0x00010000, /* WR:AMPSCA_AMPSCAIOCFG_IMPAUTOCAL(MCU3) ADDR=0x2002e0088 DWORD=0 NUMREGS=0 */ + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2002e01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2002201a0 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2002601a0 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2002a01a0 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2002281a0 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2002301a0 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2002681a0 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2002701a0 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2002a81a0 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2002b01a0 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2002e81a0 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2002f01a0 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU0) ADDR=0x200220180 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU1) ADDR=0x200260180 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU2) ADDR=0x2002a0180 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSCA_AMPSCADLLCTL_DLLEN(MCU3) ADDR=0x2002e0180 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200228180 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200230180 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200268180 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200270180 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2002a8180 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2002b0180 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2002e8180 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2002f0180 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x20023801, //compressed WR cmd + 0x0000000c, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU0) ADDR=0x200238030 DWORD=0 NUMREGS=0 */ + 0x2002b801, //compressed WR cmd + 0x0000000c, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU2) ADDR=0x2002b8030 DWORD=0 NUMREGS=0 */ + 0x20027801, //compressed WR cmd + 0x0000000c, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU1) ADDR=0x200278030 DWORD=0 NUMREGS=0 */ + 0x2002f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2c28201f, //compressed WR offset + 0x3b483a2d, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU3) ADDR=0x2002f8030 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU3) ADDR=0x2002f8028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU3) ADDR=0x2002f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU3) ADDR=0x2002f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU3) ADDR=0x2002f8068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU3) ADDR=0x2002f8050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU3) ADDR=0x2002f8060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU3) ADDR=0x2002f8078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU3) ADDR=0x2002f807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU3) ADDR=0x2002f8080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU3) ADDR=0x2002f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2002f80b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU3) ADDR=0x2002f80b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU3) ADDR=0x2002f80e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU3) ADDR=0x2002f8120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU3) ADDR=0x2002f80ec DWORD=0 NUMREGS=0 */ + 0x2002f83d, //compressed WR cmd + 0x3247433c, //compressed WR offset + 0x36343130, //compressed WR offset + 0x4c4e3837, //compressed WR offset + 0x5452504d, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU3) ADDR=0x2002f80f0 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU3) ADDR=0x2002f810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2002f811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2002f80c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU3) ADDR=0x2002f80c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU3) ADDR=0x2002f80c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU3) ADDR=0x2002f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2002f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU3) ADDR=0x2002f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU3) ADDR=0x2002f80e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2002f8138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU3) ADDR=0x2002f8130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU3) ADDR=0x2002f8134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU3) ADDR=0x2002f8140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2002f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU3) ADDR=0x2002f8150 DWORD=0 NUMREGS=0 */ + 0x2002f811, //compressed WR cmd + 0x02030953, //compressed WR offset + 0x000000bf, //compressed WR offset + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU3) ADDR=0x2002f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU3) ADDR=0x2002f8024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU3) ADDR=0x2002f800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU3) ADDR=0x2002f8008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2002f82fc DWORD=0 NUMREGS=0 */ + 0x2002383d, //compressed WR cmd + 0x1a16110a, //compressed WR offset + 0x1f1e1814, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x3c3b483a, //compressed WR offset + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU0) ADDR=0x200238028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU0) ADDR=0x200238044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU0) ADDR=0x200238058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU0) ADDR=0x200238068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU0) ADDR=0x200238050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU0) ADDR=0x200238060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU0) ADDR=0x200238078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU0) ADDR=0x20023807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU0) ADDR=0x200238080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU0) ADDR=0x2002380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2002380b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU0) ADDR=0x2002380b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU0) ADDR=0x2002380e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU0) ADDR=0x200238120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU0) ADDR=0x2002380ec DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU0) ADDR=0x2002380f0 DWORD=0 NUMREGS=0 */ + 0x2002383d, //compressed WR cmd + 0x30324743, //compressed WR offset + 0x37363431, //compressed WR offset + 0x4d4c4e38, //compressed WR offset + 0x53545250, //compressed WR offset + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU0) ADDR=0x20023810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20023811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2002380c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU0) ADDR=0x2002380c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU0) ADDR=0x2002380c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU0) ADDR=0x2002380d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2002380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU0) ADDR=0x2002380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU0) ADDR=0x2002380e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200238138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU0) ADDR=0x200238130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU0) ADDR=0x200238134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU0) ADDR=0x200238140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200238148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU0) ADDR=0x200238150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU0) ADDR=0x20023814c DWORD=0 NUMREGS=0 */ + 0x2002380d, //compressed WR cmd + 0xbf020309, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU0) ADDR=0x200238024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU0) ADDR=0x20023800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU0) ADDR=0x200238008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2002382fc DWORD=0 NUMREGS=0 */ + 0x2002b83d, //compressed WR cmd + 0x1a16110a, //compressed WR offset + 0x1f1e1814, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x3c3b483a, //compressed WR offset + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU2) ADDR=0x2002b8028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU2) ADDR=0x2002b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU2) ADDR=0x2002b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU2) ADDR=0x2002b8068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU2) ADDR=0x2002b8050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU2) ADDR=0x2002b8060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU2) ADDR=0x2002b8078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU2) ADDR=0x2002b807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU2) ADDR=0x2002b8080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU2) ADDR=0x2002b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2002b80b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU2) ADDR=0x2002b80b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU2) ADDR=0x2002b80e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU2) ADDR=0x2002b8120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU2) ADDR=0x2002b80ec DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU2) ADDR=0x2002b80f0 DWORD=0 NUMREGS=0 */ + 0x2002b83d, //compressed WR cmd + 0x30324743, //compressed WR offset + 0x37363431, //compressed WR offset + 0x4d4c4e38, //compressed WR offset + 0x53545250, //compressed WR offset + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU2) ADDR=0x2002b810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2002b811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2002b80c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU2) ADDR=0x2002b80c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU2) ADDR=0x2002b80c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU2) ADDR=0x2002b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2002b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU2) ADDR=0x2002b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU2) ADDR=0x2002b80e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2002b8138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU2) ADDR=0x2002b8130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU2) ADDR=0x2002b8134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU2) ADDR=0x2002b8140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2002b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU2) ADDR=0x2002b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU2) ADDR=0x2002b814c DWORD=0 NUMREGS=0 */ + 0x2002b80d, //compressed WR cmd + 0xbf020309, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU2) ADDR=0x2002b8024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU2) ADDR=0x2002b800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU2) ADDR=0x2002b8008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2002b82fc DWORD=0 NUMREGS=0 */ + 0x2002783d, //compressed WR cmd + 0x1a16110a, //compressed WR offset + 0x1f1e1814, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x3c3b483a, //compressed WR offset + 0x33831717, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU1) ADDR=0x200278028 DWORD=0 NUMREGS=0 */ + 0x000200a3, /* WR:AMPH_CFGH_CB_IOCTL(MCU1) ADDR=0x200278044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU1) ADDR=0x200278058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU1) ADDR=0x200278068 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU1) ADDR=0x200278050 DWORD=0 NUMREGS=0 */ + 0x000000a7, /* WR:AMPH_CFGH_CK_IOCTL(MCU1) ADDR=0x200278060 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU1) ADDR=0x200278078 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B0_IMPCTL(MCU1) ADDR=0x20027807c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU1) ADDR=0x200278080 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_B0_IOCTL(MCU1) ADDR=0x2002780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2002780b0 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU1) ADDR=0x2002780b4 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU1) ADDR=0x2002780e8 DWORD=0 NUMREGS=0 */ + 0x00000005, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU1) ADDR=0x200278120 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_B1_IMPCTL(MCU1) ADDR=0x2002780ec DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU1) ADDR=0x2002780f0 DWORD=0 NUMREGS=0 */ + 0x2002783d, //compressed WR cmd + 0x30324743, //compressed WR offset + 0x37363431, //compressed WR offset + 0x4d4c4e38, //compressed WR offset + 0x53545250, //compressed WR offset + 0x715000a7, /* WR:AMPH_CFGH_B1_IOCTL(MCU1) ADDR=0x20027810c DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20027811c DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2002780c8 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU1) ADDR=0x2002780c0 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS0_IMPCTL(MCU1) ADDR=0x2002780c4 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU1) ADDR=0x2002780d0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2002780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU1) ADDR=0x2002780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU1) ADDR=0x2002780e0 DWORD=0 NUMREGS=0 */ + 0x00000788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200278138 DWORD=0 NUMREGS=0 */ + 0x33831717, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU1) ADDR=0x200278130 DWORD=0 NUMREGS=0 */ + 0x00201c2b, /* WR:AMPH_CFGH_DQS1_IMPCTL(MCU1) ADDR=0x200278134 DWORD=0 NUMREGS=0 */ + 0x715000a7, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU1) ADDR=0x200278140 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200278148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU1) ADDR=0x200278150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU1) ADDR=0x20027814c DWORD=0 NUMREGS=0 */ + 0x2002780d, //compressed WR cmd + 0xbf020309, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU1) ADDR=0x200278024 DWORD=0 NUMREGS=0 */ + 0x00667f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU1) ADDR=0x20027800c DWORD=0 NUMREGS=0 */ + 0x000f0315, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU1) ADDR=0x200278008 DWORD=0 NUMREGS=0 */ + 0x0000000e, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2002782fc DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200220008 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200260008 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2002a0008 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2002e0008 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200228008 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200230008 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200268008 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200270008 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2002a8008 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2002b0008 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2002e8008 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2002f0008 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2002003bc DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2002403bc DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2002803bc DWORD=0 NUMREGS=0 */ + 0x2002c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2002c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2002c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2002c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2002c03fc DWORD=0 NUMREGS=0 */ + 0x2002000d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2002003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2002003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2002003fc DWORD=0 NUMREGS=0 */ + 0x2002400d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2002403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2002403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2002403fc DWORD=0 NUMREGS=0 */ + 0x2002800d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2002803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x366c006e, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2002803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2002803fc DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20020041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20020043c DWORD=0 NUMREGS=0 */ + 0x20024049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20024041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20024043c DWORD=0 NUMREGS=0 */ + 0x20028049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20028041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20028043c DWORD=0 NUMREGS=0 */ + 0x2002c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x01012008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2002c041c DWORD=0 NUMREGS=0 */ + 0x15030007, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2002c043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 NUMREGS=0 */ + 0x20022002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200220094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200260094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2002a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2002e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200200414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200200410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20020040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200200408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200240414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200240410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20024040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200240408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200280414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200280410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20028040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200280408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x11100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2002c0414 DWORD=0 NUMREGS=0 */ + 0x11000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2002c0410 DWORD=0 NUMREGS=0 */ + 0x11110000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2002c040c DWORD=0 NUMREGS=0 */ + 0x1111013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2002c0408 DWORD=0 NUMREGS=0 */ + 0x00010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20020045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000010, //compressed WR offset + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CHEN(MCC) ADDR=0x20f140040 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20020001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200200000 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200240000 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200280000 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2002c0000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000002, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20023805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2002380c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200238138 DWORD=0 NUMREGS=0 */ + 0x20027805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2002780c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200278138 DWORD=0 NUMREGS=0 */ + 0x2002f805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2002f80c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2002f8138 DWORD=0 NUMREGS=0 */ + 0x2002b805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00030788, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2002b80c8 DWORD=0 NUMREGS=0 */ + 0x00030788, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2002b8138 DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ0) ADDR=0x200228620 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU0, DQ1) ADDR=0x200230620 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ0) ADDR=0x200268620 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU1, DQ1) ADDR=0x200270620 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ0) ADDR=0x2002a8620 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU2, DQ1) ADDR=0x2002b0620 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ0) ADDR=0x2002e8620 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000088, //compressed WR offset + 0x06000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRTDQSDQSKEWCONTROL(MCU3, DQ1) ADDR=0x2002f0620 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200220c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200200418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200240418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200280418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x08010019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2002c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ + 0x20020001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x20024001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x20028001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x2002c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x20023811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU0) ADDR=0x20023809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU0) ADDR=0x200238098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU0) ADDR=0x200238108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU0) ADDR=0x2002380cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU0) ADDR=0x20023813c DWORD=0 NUMREGS=0 */ + 0x20027811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU1) ADDR=0x20027809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU1) ADDR=0x200278098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU1) ADDR=0x200278108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU1) ADDR=0x2002780cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU1) ADDR=0x20027813c DWORD=0 NUMREGS=0 */ + 0x2002f811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU3) ADDR=0x2002f809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU3) ADDR=0x2002f8098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU3) ADDR=0x2002f8108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU3) ADDR=0x2002f80cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU3) ADDR=0x2002f813c DWORD=0 NUMREGS=0 */ + 0x2002b811, //compressed WR cmd + 0x33422627, //compressed WR offset + 0x0000004f, //compressed WR offset + 0x00001117, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU2) ADDR=0x2002b809c DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU2) ADDR=0x2002b8098 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPH_CFGH_B1_DYN_ISEL(MCU2) ADDR=0x2002b8108 DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS0_DCD_IOCTL(MCU2) ADDR=0x2002b80cc DWORD=0 NUMREGS=0 */ + 0x00030000, /* WR:AMPH_CFGH_DQS1_DCD_IOCTL(MCU2) ADDR=0x2002b813c DWORD=0 NUMREGS=0 */ + 0x20020005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20020019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200200198 DWORD=0 NUMREGS=0 */ + 0x20024005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20024019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200240198 DWORD=0 NUMREGS=0 */ + 0x20028005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20028019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200280198 DWORD=0 NUMREGS=0 */ + 0x2002c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000061a5, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2002c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2002c0198 DWORD=0 NUMREGS=0 */ + 0x20000042, /* POLL:AMCC_MCCCFG_MCCPWRONWAYCNTSTATUS(MCC) ADDR=0x20000079c DWORD=0 */ + 0x000000e7, /* Offset */ + 0x7fff7fff, /* Mask */ + 0x42104210, /* Expected Data */ + 0x20000049, //compressed WR cmd + 0x00e09392, //compressed WR offset + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200228004 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200230004 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200268004 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200270004 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2002a8004 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2002b0004 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2002e8004 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2002f0004 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200200424 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200240424 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200280424 DWORD=0 NUMREGS=0 */ + 0x2002c045, //compressed WR cmd + 0x00000a09, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2002c0424 DWORD=0 NUMREGS=0 */ + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU3) ADDR=0x2002c0428 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU0) ADDR=0x200200428 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU1) ADDR=0x200240428 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x0000000a, //compressed WR offset + 0x01800000, /* WR:AMCX_DRAMCFG_PWRMNGTPARAM_FREQ0(MCU2) ADDR=0x200280428 DWORD=0 NUMREGS=0 */ + 0x20020005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU0) ADDR=0x2002001ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200200010 DWORD=0 NUMREGS=0 */ + 0x20024005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU1) ADDR=0x2002401ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200240010 DWORD=0 NUMREGS=0 */ + 0x20f1401d, //compressed WR cmd + 0x16151413, //compressed WR offset + 0x18171211, //compressed WR offset + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(MCC) ADDR=0x20f14004c DWORD=0 NUMREGS=0 */ + 0x01500150, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(MCC) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(MCC) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02a002a0, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(MCC) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY0(MCC) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_CAL2PREFREQCHNGDLY1(MCC) ADDR=0x20f140048 DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY0(MCC) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x01200120, /* WR:GLBTIMER_GLBTIMER_FREQCHNG2PSTCALDLY1(MCC) ADDR=0x20f140060 DWORD=0 NUMREGS=0 */ + 0x20028005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU2) ADDR=0x2002801ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200280010 DWORD=0 NUMREGS=0 */ + 0x2002c005, //compressed WR cmd + 0x0000047b, //compressed WR offset + 0x01640120, /* WR:AMCX_MCUSCH_PSQWQCTL1(MCU3) ADDR=0x2002c01ec DWORD=0 NUMREGS=0 */ + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2002c0010 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 NUMREGS=0 */ + 0x20020042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200200500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20024041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 NUMREGS=0 */ + 0x20024042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200240500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20028041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 NUMREGS=0 */ + 0x20028042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200280500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 NUMREGS=0 */ + 0x2002c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2002c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20020041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200200420 DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200240420 DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200280420 DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2002c0420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_mcu_locked[] = { + 0x2000004d, //compressed WR cmd + 0x292d3229, //compressed WR offset + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC) ADDR=0x2000004c8 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC) ADDR=0x2000004b4 DWORD=0 NUMREGS=0 */ + 0x00050220, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_before_restoration[] = { + 0x20022001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x20022001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x20026001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x2002a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x2002e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 NUMREGS=0 */ + 0x20022802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20022818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20023002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20023018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20026818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20027002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20027018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2002a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2002b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2002e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2002f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200220004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200220198 DWORD=0 NUMREGS=0 */ + 0x20026005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200260004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200260198 DWORD=0 NUMREGS=0 */ + 0x2002a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2002a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2002a0198 DWORD=0 NUMREGS=0 */ + 0x2002e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2002e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2002e0198 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200228198 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200230198 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200268198 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200270198 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2002a8198 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2002b0198 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2002e8198 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2002f0198 DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200220e04 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200260e04 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000081, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2002a0e04 DWORD=0 NUMREGS=0 */ + 0x2002e0c5, //compressed WR cmd + 0x00008381, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2002e0e04 DWORD=0 NUMREGS=0 */ + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2002e0e0c DWORD=0 NUMREGS=0 */ + 0x200220c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200220e0c DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200260e0c DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x00000083, //compressed WR offset + 0x00010002, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2002a0e0c DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200220700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200260700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2002a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2002e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200220708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200260708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2002a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2002e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20022041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200220710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20026041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200260710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2002a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2002e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2002e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20022081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20026081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2002e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20022082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200220800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20026082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200260800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2002a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2002e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2002e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200220500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200260500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2002a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2002e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200220504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200260504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2002a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2002e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200220508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200260508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2002a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2002e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20022050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20026050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2002a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2002e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200220510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200260510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2002a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2002e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200220514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200260514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2002a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2002e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200220518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200260518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2002a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2002e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20022041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20022051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20026041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20026051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2002a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2002e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2002e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20022841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200228704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20023041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200230704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20026841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200268704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20027041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200270704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2002a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2002b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2002e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2002f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2002f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200228b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200230b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200268b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200270b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2002a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2002b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2002e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2002f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200228b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200230b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200268b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200270b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2002a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2002b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2002e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2002f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200228b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200230b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200268b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200270b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2002a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2002b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2002e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2002f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00800080, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20022881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200228b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20023081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200230b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20026881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200268b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20027081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200270b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2002a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2002b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2002e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2002f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2002f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00800080, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20020001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2002003b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20024001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2002403b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20028001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2002803b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x2002c001, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2002c03b4 DWORD=0 NUMREGS=0 */ + 0x000000ed, /* Offset */ + 0x24480049, /* Data -- AUTOREF_FREQ1 0x0 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x109c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x109c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20022801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2002281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20023001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2002301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20026801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2002681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20027001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2002701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2002a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2002b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2002e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2002f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2002f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x109c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200200454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200240454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200280454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2002c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20020041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20020046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + 0x20024041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20024046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + 0x20028041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20028046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + 0x2002c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2002c046c DWORD=0 NUMREGS=0 */ + 0x0000001b, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ1 0x0 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_after_restoration[] = { + 0x200220c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200220e34 DWORD=0 NUMREGS=0 */ + 0x200260c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200260e34 DWORD=0 NUMREGS=0 */ + 0x2002a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2002a0e34 DWORD=0 NUMREGS=0 */ + 0x2002e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2002e0e34 DWORD=0 NUMREGS=0 */ + 0x20020041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20020044c DWORD=0 NUMREGS=0 */ + 0x20024041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20024044c DWORD=0 NUMREGS=0 */ + 0x20028041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20028044c DWORD=0 NUMREGS=0 */ + 0x2002c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x00009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2002c044c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200228600 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200230600 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200268600 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200270600 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2002a8600 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2002b0600 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2002e8600 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff00000c, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2002f0600 DWORD=0 NUMREGS=0 */ + 0x20022041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20022071c DWORD=0 NUMREGS=0 */ + 0x20026041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20026071c DWORD=0 NUMREGS=0 */ + 0x2002a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2002a071c DWORD=0 NUMREGS=0 */ + 0x2002e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2002e071c DWORD=0 NUMREGS=0 */ + 0x20022841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200228628 DWORD=0 NUMREGS=0 */ + 0x20023041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200230628 DWORD=0 NUMREGS=0 */ + 0x20026841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200268628 DWORD=0 NUMREGS=0 */ + 0x20027041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200270628 DWORD=0 NUMREGS=0 */ + 0x2002a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2002a8628 DWORD=0 NUMREGS=0 */ + 0x2002b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2002b0628 DWORD=0 NUMREGS=0 */ + 0x2002e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2002e8628 DWORD=0 NUMREGS=0 */ + 0x2002f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2002f0628 DWORD=0 NUMREGS=0 */ + 0x20022801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200228190 DWORD=0 NUMREGS=0 */ + 0x20023001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200230190 DWORD=0 NUMREGS=0 */ + 0x20026801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200268190 DWORD=0 NUMREGS=0 */ + 0x20027001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200270190 DWORD=0 NUMREGS=0 */ + 0x2002a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2002a8190 DWORD=0 NUMREGS=0 */ + 0x2002b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2002b0190 DWORD=0 NUMREGS=0 */ + 0x2002e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2002e8190 DWORD=0 NUMREGS=0 */ + 0x2002f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2002f0190 DWORD=0 NUMREGS=0 */ + 0x20f14035, //compressed WR cmd + 0x0201000e, //compressed WR offset + 0x07060504, //compressed WR offset + 0x1a190908, //compressed WR offset + 0x00001c1b, //compressed WR offset + 0x000000ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(MCC) ADDR=0x20f140038 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(MCC) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(MCC) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(MCC) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(MCC) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(MCC) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x003d0900, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(MCC) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(MCC) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x000493e0, /* WR:GLBTIMER_GLBTIMER_VOLTRAMPTIMER(MCC) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(MCC) ADDR=0x20f140024 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY0(MCC) ADDR=0x20f140064 DWORD=0 NUMREGS=0 */ + 0x00d800d8, /* WR:GLBTIMER_GLBTIMER_VOLTRAMP2ALLBANKDLY1(MCC) ADDR=0x20f140068 DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY0(MCC) ADDR=0x20f14006c DWORD=0 NUMREGS=0 */ + 0x00900090, /* WR:GLBTIMER_GLBTIMER_ALLBANK2PMGRACKDLY1(MCC) ADDR=0x20f140070 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_A0_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001.h new file mode 100644 index 0000000..ebf6b4a --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001.h @@ -0,0 +1,3070 @@ +#ifndef __MCU_INIT_AOP_H__ +#define __MCU_INIT_AOP_H__ + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_ddr[] = { + 0x20040c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20040c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU0) ADDR=0x20040c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20040c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20040c05c DWORD=0 NUMREGS=0 */ + 0x20044c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20044c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU1) ADDR=0x20044c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20044c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20044c05c DWORD=0 NUMREGS=0 */ + 0x2004cc15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2004cc01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU3) ADDR=0x2004cc000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2004cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2004cc05c DWORD=0 NUMREGS=0 */ + 0x20048c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20048c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU2) ADDR=0x20048c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20048c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20048c05c DWORD=0 NUMREGS=0 */ + 0x2004007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200400450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200400458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20040045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200400460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2004004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200400468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20040046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200400470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200400474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200400478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2004004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200400480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200400484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200400488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20040048c DWORD=0 NUMREGS=0 */ + 0x2004005d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200400490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2004004cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200400498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20040049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2004004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2004004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2004004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2004004d0 DWORD=0 NUMREGS=0 */ + 0x2004407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200440450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200440458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20044045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200440460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2004404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200440468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20044046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200440470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200440474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200440478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2004404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200440480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200440484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200440488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20044048c DWORD=0 NUMREGS=0 */ + 0x2004405d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200440490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2004404cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200440498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20044049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2004404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2004404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2004404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2004404d0 DWORD=0 NUMREGS=0 */ + 0x2004c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2004c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2004c0458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2004c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2004c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2004c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2004c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2004c046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2004c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2004c0474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2004c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2004c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2004c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2004c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2004c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2004c048c DWORD=0 NUMREGS=0 */ + 0x2004c05d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2004c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2004c04cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2004c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2004c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2004c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2004c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2004c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2004c04d0 DWORD=0 NUMREGS=0 */ + 0x2004807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200480450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200480458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20048045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200480460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2004804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200480468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20048046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200480470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200480474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200480478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2004804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200480480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200480484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200480488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20048048c DWORD=0 NUMREGS=0 */ + 0x2004805d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200480490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2004804cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200480498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20048049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2004804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2004804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2004804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2004804d0 DWORD=0 NUMREGS=0 */ + 0x200420dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ef4 DWORD=0 NUMREGS=0 */ + 0x200460dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ef4 DWORD=0 NUMREGS=0 */ + 0x2004a0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ef4 DWORD=0 NUMREGS=0 */ + 0x2004e0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ef4 DWORD=0 NUMREGS=0 */ + 0x20f14005, //compressed WR cmd + 0x00002324, //compressed WR offset + 0x00000003, /* WR:GLBTIMER_GLBTIMER_PERVREFCALCFG(GLBTIMER) ADDR=0x20f140090 DWORD=0 NUMREGS=0 */ + 0x00060006, /* WR:GLBTIMER_GLBTIMER_VREFCNTRL(GLBTIMER) ADDR=0x20f14008c DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xa0e1e0f4, //compressed WR offset + 0xe4a3a2a1, //compressed WR offset + 0xf5f0ece8, //compressed WR offset + 0xf1ede9e5, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2004c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2004c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2004c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU3) ADDR=0x2004c028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2004c0390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2004c03a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2004c03c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2004c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2004c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2004c03c4 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xf2eeeae6, //compressed WR offset + 0xf3efebe7, //compressed WR offset + 0xf7f6f4ff, //compressed WR offset + 0xe1e0f9f8, //compressed WR offset + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2004c0398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2004c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2004c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2004c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2004c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2004c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2004c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2004c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2004c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2004c03e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x2004c011, //compressed WR cmd + 0xfbfae3e2, //compressed WR offset + 0x000000fc, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2004c0388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2004c038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2004c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2004c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2004c03f0 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200400280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200400284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200400288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU0) ADDR=0x20040028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200400390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2004003a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2004003c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200400394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2004003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2004003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200400398 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2004003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2004003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20040039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2004003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2004003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2004003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2004003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2004003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2004003e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200400388 DWORD=0 NUMREGS=0 */ + 0x2004000d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20040038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2004003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2004003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2004003f0 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200440280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200440284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200440288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU1) ADDR=0x20044028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200440390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2004403a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2004403c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200440394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2004403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2004403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200440398 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2004403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2004403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20044039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2004403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2004403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2004403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2004403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2004403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2004403e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200440388 DWORD=0 NUMREGS=0 */ + 0x2004400d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20044038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2004403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2004403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2004403f0 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200480280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200480284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200480288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU2) ADDR=0x20048028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200480390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2004803a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2004803c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200480394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2004803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2004803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200480398 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2004803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2004803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20048039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2004803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2004803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2004803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2004803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2004803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2004803e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200480388 DWORD=0 NUMREGS=0 */ + 0x2004800d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20048038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2004803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2004803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2004803f0 DWORD=0 NUMREGS=0 */ + 0x20040051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200400404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200400780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20040078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200440404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200440780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20044078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2004c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2004c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2004c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200480404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200480780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20048078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200420000 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200460000 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2004a0000 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2004e0000 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200428000 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200430000 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200468000 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200470000 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2004a8000 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2004b0000 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2004e8000 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2004f0000 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200420d10 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200460d10 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2004a0d10 DWORD=0 NUMREGS=0 */ + 0x2004e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2004e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2004e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2004e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2004e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2004e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2004e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2004e0d0c DWORD=0 NUMREGS=0 */ + 0x200420d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200420d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200420d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200420d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200420d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200420d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200420d0c DWORD=0 NUMREGS=0 */ + 0x200460d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200460d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200460d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200460d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200460d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200460d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200460d0c DWORD=0 NUMREGS=0 */ + 0x2004a0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2004a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2004a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2004a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2004a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2004a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2004a0d0c DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200420718 DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200460718 DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2004a0718 DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2004e0718 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20042861c DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20043061c DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20046861c DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20047061c DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2004a861c DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2004b061c DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2004e861c DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2004f061c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200420f80 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200460f80 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2004a0f80 DWORD=0 NUMREGS=0 */ + 0x2004e0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2004e0f80 DWORD=0 NUMREGS=0 */ + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2004e0f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2004e0f88 DWORD=0 NUMREGS=0 */ + 0x200420c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200420f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200420f88 DWORD=0 NUMREGS=0 */ + 0x200460c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200460f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200460f88 DWORD=0 NUMREGS=0 */ + 0x2004a0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2004a0f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2004a0f88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200428d80 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200430d80 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200468d80 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200470d80 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2004a8d80 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2004b0d80 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2004e8d80 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2004f0d80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200428d84 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200430d84 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200468d84 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200470d84 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2004a8d84 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2004b0d84 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2004e8d84 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2004f0d84 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200428d88 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200430d88 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200468d88 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200470d88 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2004a8d88 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2004b0d88 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2004e8d88 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2004f0d88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200428d8c DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200430d8c DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200468d8c DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200470d8c DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2004a8d8c DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2004b0d8c DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2004e8d8c DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2004f0d8c DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU0) ADDR=0x200420f90 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU1) ADDR=0x200460f90 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU2) ADDR=0x2004a0f90 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU3) ADDR=0x2004e0f90 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2004281cc DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2004301cc DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2004681cc DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2004701cc DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2004a81cc DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2004b01cc DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2004e81cc DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2004f01cc DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200420e00 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200460e00 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2004a0e00 DWORD=0 NUMREGS=0 */ + 0x2004e0fd, //compressed WR cmd + 0x86828180, //compressed WR offset + 0x8b8a8983, //compressed WR offset + 0xaaa9a88c, //compressed WR offset + 0x8f8eacab, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2004e0e00 DWORD=0 NUMREGS=0 */ + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2004e0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2004e0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU3) ADDR=0x2004e0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2004e0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2004e0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2004e0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU3) ADDR=0x2004e0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU3) ADDR=0x2004e0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU3) ADDR=0x2004e0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU3) ADDR=0x2004e0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU3) ADDR=0x2004e0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e3c DWORD=0 NUMREGS=0 */ + 0x2004e0cd, //compressed WR cmd + 0xa09f9190, //compressed WR offset + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e40 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e80 DWORD=0 NUMREGS=0 */ + 0x200420fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200420e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200420e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU0) ADDR=0x200420e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200420e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200420e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200420e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200420e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200420e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU0) ADDR=0x200420ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU0) ADDR=0x200420ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU0) ADDR=0x200420ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU0) ADDR=0x200420eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU0) ADDR=0x200420eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200420e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200420e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200420e40 DWORD=0 NUMREGS=0 */ + 0x200420c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200420e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e80 DWORD=0 NUMREGS=0 */ + 0x200460fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200460e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200460e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU1) ADDR=0x200460e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200460e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200460e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200460e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200460e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200460e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU1) ADDR=0x200460ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU1) ADDR=0x200460ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU1) ADDR=0x200460ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU1) ADDR=0x200460eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU1) ADDR=0x200460eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200460e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200460e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200460e40 DWORD=0 NUMREGS=0 */ + 0x200460c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200460e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e80 DWORD=0 NUMREGS=0 */ + 0x2004a0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2004a0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2004a0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU2) ADDR=0x2004a0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2004a0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2004a0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2004a0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU2) ADDR=0x2004a0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU2) ADDR=0x2004a0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU2) ADDR=0x2004a0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU2) ADDR=0x2004a0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU2) ADDR=0x2004a0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e40 DWORD=0 NUMREGS=0 */ + 0x2004a0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200428d00 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200430d00 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200468d00 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200470d00 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2004a8d00 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2004b0d00 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2004e8d00 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2004f0d00 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200428100 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200430100 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200468100 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200470100 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2004a8100 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2004b0100 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2004e8100 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2004f0100 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200428104 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200430104 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200468104 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200470104 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2004a8104 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2004b0104 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2004e8104 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2004f0104 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200428108 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200430108 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200468108 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200470108 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2004a8108 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2004b0108 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2004e8108 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2004f0108 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20042810c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20043010c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20046810c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20047010c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2004a810c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2004b010c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2004e810c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2004f010c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2004201a0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2004601a0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2004a01a0 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2004e01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2004281a0 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2004301a0 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2004681a0 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2004701a0 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2004a81a0 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2004b01a0 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2004e81a0 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2004f01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200428180 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200430180 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200468180 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200470180 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2004a8180 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2004b0180 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2004e8180 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2004f0180 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU0) ADDR=0x2004200dc DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU1) ADDR=0x2004600dc DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU2) ADDR=0x2004a00dc DWORD=0 NUMREGS=0 */ + 0x2004e005, //compressed WR cmd + 0x00003837, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU3) ADDR=0x2004e00dc DWORD=0 NUMREGS=0 */ + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU3) ADDR=0x2004e00e0 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU0) ADDR=0x2004200e0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU1) ADDR=0x2004600e0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU2) ADDR=0x2004a00e0 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU0) ADDR=0x200420ecc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU1) ADDR=0x200460ecc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU2) ADDR=0x2004a0ecc DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU3) ADDR=0x2004e0ecc DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU0) ADDR=0x200438030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU0) ADDR=0x200438028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU0) ADDR=0x200438044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU0) ADDR=0x200438058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU0) ADDR=0x200438068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU0) ADDR=0x200438050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU0) ADDR=0x200438060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU0) ADDR=0x200438078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU0) ADDR=0x200438080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU0) ADDR=0x2004380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2004380b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU0) ADDR=0x2004380b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU0) ADDR=0x2004380e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU0) ADDR=0x200438120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU0) ADDR=0x2004380f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU0) ADDR=0x20043810c DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20043811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU0) ADDR=0x2004380c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU0) ADDR=0x2004380d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2004380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU0) ADDR=0x2004380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU0) ADDR=0x2004380e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU0) ADDR=0x200438130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU0) ADDR=0x200438140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200438148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU0) ADDR=0x200438150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU0) ADDR=0x20043814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU0) ADDR=0x200438024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU0) ADDR=0x20043800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU0) ADDR=0x200438008 DWORD=0 NUMREGS=0 */ + 0x20043801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2004382fc DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU1) ADDR=0x200478030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU1) ADDR=0x200478028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU1) ADDR=0x200478044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU1) ADDR=0x200478058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU1) ADDR=0x200478068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU1) ADDR=0x200478050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU1) ADDR=0x200478060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU1) ADDR=0x200478078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU1) ADDR=0x200478080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU1) ADDR=0x2004780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2004780b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU1) ADDR=0x2004780b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU1) ADDR=0x2004780e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU1) ADDR=0x200478120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU1) ADDR=0x2004780f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU1) ADDR=0x20047810c DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20047811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU1) ADDR=0x2004780c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU1) ADDR=0x2004780d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2004780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU1) ADDR=0x2004780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU1) ADDR=0x2004780e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU1) ADDR=0x200478130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU1) ADDR=0x200478140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200478148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU1) ADDR=0x200478150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU1) ADDR=0x20047814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU1) ADDR=0x200478024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU1) ADDR=0x20047800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU1) ADDR=0x200478008 DWORD=0 NUMREGS=0 */ + 0x20047801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2004782fc DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU3) ADDR=0x2004f8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU3) ADDR=0x2004f8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU3) ADDR=0x2004f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU3) ADDR=0x2004f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU3) ADDR=0x2004f8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU3) ADDR=0x2004f8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU3) ADDR=0x2004f8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU3) ADDR=0x2004f8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU3) ADDR=0x2004f8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU3) ADDR=0x2004f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2004f80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU3) ADDR=0x2004f80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU3) ADDR=0x2004f80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU3) ADDR=0x2004f8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU3) ADDR=0x2004f80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU3) ADDR=0x2004f810c DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2004f811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU3) ADDR=0x2004f80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU3) ADDR=0x2004f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2004f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU3) ADDR=0x2004f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU3) ADDR=0x2004f80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU3) ADDR=0x2004f8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU3) ADDR=0x2004f8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2004f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU3) ADDR=0x2004f8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU3) ADDR=0x2004f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU3) ADDR=0x2004f8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU3) ADDR=0x2004f800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU3) ADDR=0x2004f8008 DWORD=0 NUMREGS=0 */ + 0x2004f801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2004f82fc DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU2) ADDR=0x2004b8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU2) ADDR=0x2004b8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU2) ADDR=0x2004b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU2) ADDR=0x2004b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU2) ADDR=0x2004b8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU2) ADDR=0x2004b8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU2) ADDR=0x2004b8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU2) ADDR=0x2004b8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU2) ADDR=0x2004b8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU2) ADDR=0x2004b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2004b80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU2) ADDR=0x2004b80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU2) ADDR=0x2004b80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU2) ADDR=0x2004b8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU2) ADDR=0x2004b80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU2) ADDR=0x2004b810c DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2004b811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU2) ADDR=0x2004b80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU2) ADDR=0x2004b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2004b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU2) ADDR=0x2004b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU2) ADDR=0x2004b80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU2) ADDR=0x2004b8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU2) ADDR=0x2004b8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2004b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU2) ADDR=0x2004b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU2) ADDR=0x2004b814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU2) ADDR=0x2004b8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU2) ADDR=0x2004b800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU2) ADDR=0x2004b8008 DWORD=0 NUMREGS=0 */ + 0x2004b801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2004b82fc DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200420008 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200460008 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2004a0008 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2004e0008 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200428008 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200430008 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200468008 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200470008 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2004a8008 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2004b0008 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2004e8008 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2004f0008 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200420e74 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200460e74 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2004a0e74 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2004e0e74 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200428d80 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200430d80 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200468d80 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200470d80 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2004a8d80 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2004b0d80 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2004e8d80 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2004f0d80 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU0) ADDR=0x200420edc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU1) ADDR=0x200460edc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU2) ADDR=0x2004a0edc DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU3) ADDR=0x2004e0edc DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x2004c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x2004000d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x2004400d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x2004800d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x20040049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20040041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20044041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2004c041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20048049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20048041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 NUMREGS=0 */ + 0x20042002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200400414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200400410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20040040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200400408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200440414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200440410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20044040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200440408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2004c0414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2004c0410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2004c040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2004c0408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200480414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200480410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20048040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200480408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20040045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000011, //compressed WR offset + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CHEN(GLBTIMER) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00051004, /* DELAY for 27 uS (5184 clock cycles) */ + 0x20043809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2004382fc DWORD=0 NUMREGS=0 */ + 0x20047809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2004782fc DWORD=0 NUMREGS=0 */ + 0x2004f809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2004f82fc DWORD=0 NUMREGS=0 */ + 0x2004b809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2004b82fc DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200420cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x200460cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x2004a0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x2004e0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x20043805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU0) ADDR=0x20043809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU0) ADDR=0x200438098 DWORD=0 NUMREGS=0 */ + 0x20047805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU1) ADDR=0x20047809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU1) ADDR=0x200478098 DWORD=0 NUMREGS=0 */ + 0x2004f805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU3) ADDR=0x2004f809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU3) ADDR=0x2004f8098 DWORD=0 NUMREGS=0 */ + 0x2004b805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU2) ADDR=0x2004b809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU2) ADDR=0x2004b8098 DWORD=0 NUMREGS=0 */ + 0x20040005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20040019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20044019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20048005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20048019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC1) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC1) ADDR=0x200200648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC1) ADDR=0x20020064c DWORD=0 NUMREGS=0 */ + 0x20000049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC0) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC0) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC0) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x2004c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2004c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200428004 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200430004 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200468004 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200470004 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2004a8004 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2004b0004 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2004e8004 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2004f0004 DWORD=0 NUMREGS=0 */ + 0x20040c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU0) ADDR=0x20040c064 DWORD=0 NUMREGS=0 */ + 0x20048c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU2) ADDR=0x20048c064 DWORD=0 NUMREGS=0 */ + 0x20044c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU1) ADDR=0x20044c064 DWORD=0 NUMREGS=0 */ + 0x2004cc01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU3) ADDR=0x2004cc064 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x20f14015, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x0000211f, //compressed WR offset + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(GLBTIMER) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(GLBTIMER) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(GLBTIMER) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(GLBTIMER) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_CALSEG2ALLBANK0(GLBTIMER) ADDR=0x20f14007c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_ALLBANK2CALSEG0(GLBTIMER) ADDR=0x20f140084 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200480010 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200400010 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200440010 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2004c0010 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20044042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20048042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x2004c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_locked[] = { + 0x20000051, //compressed WR cmd + 0x2e332929, //compressed WR offset + 0x00000029, //compressed WR offset + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC0) ADDR=0x2000004cc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC0) ADDR=0x2000004b8 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x20020051, //compressed WR cmd + 0x2e332929, //compressed WR offset + 0x00000029, //compressed WR offset + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC1) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC1) ADDR=0x2002004b8 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_before_restoration[] = { + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 NUMREGS=0 */ + 0x20042802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x2004a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2004e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200420700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200460700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2004a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2004e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200420708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200460708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2004a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2004e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200420710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200460710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2004a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2004e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20042081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20046081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200420500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200460500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2004a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2004e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200420504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200460504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2004a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2004e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200420508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200460508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2004a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2004e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20042050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20046050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2004a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2004e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200420510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200460510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2004a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2004e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200420514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200460514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2004a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2004e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200420518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200460518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2004a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2004e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20042051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20046051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2004a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2004e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20042841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200428704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20043041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200430704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20046841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200468704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20047041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200470704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2004a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2004b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2004e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2004f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200428b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200430b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200468b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200470b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2004a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2004b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2004e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2004f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200428b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200430b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200468b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200470b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2004a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2004b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2004e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2004f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* ####### IMPORTANT ##### PLEASE READ ##### */ + /* When restoring below WrDqCalVrefCodeControl and RdDqCalVrefCodeControl registers, Software first needs to read WrDQCalVrefCodeStatus and RdDqCalVrefCodeStatus registers and put the value from CodeStatus registers to CodeControl registers */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200400458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200440458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200480458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2004c0458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2004004a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2004404a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2004804a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2004c04a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200400460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200440460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200480460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2004c0460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20f14001, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(GLBTIMER) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x00000006, /* Offset */ + 0x00061a80, /* Data -- GLBTIMER_GLBTIMER_ZQCTIMER 0x0 ## Save the value after End of Step 18 */ + 0x20043801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU0) ADDR=0x20043802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU1) ADDR=0x20047802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU2) ADDR=0x2004b802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU3) ADDR=0x2004f802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2004380b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2004780b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2004b80b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2004f80b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20043811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20047811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2004b811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2004f811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2004380d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2004780d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2004b80d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2004f80d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200438148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200478148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2004b8148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2004f8148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* END OF RESTORATION */ + 0x00000044, /* NOOP for 64bit alignment*/ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_after_restoration[] = { + 0x200420c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20f14021, //compressed WR cmd + 0x0107000f, //compressed WR offset + 0x08050402, //compressed WR offset + 0x0000000a, //compressed WR offset + 0x000001ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(GLBTIMER) ADDR=0x20f14003c DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(GLBTIMER) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_DCCTIMER(GLBTIMER) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(GLBTIMER) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(GLBTIMER) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6bb, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(GLBTIMER) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(GLBTIMER) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(GLBTIMER) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(GLBTIMER) ADDR=0x20f140028 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001_a0.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001_a0.h new file mode 100644 index 0000000..97b6b60 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_4ch_s8001_a0.h @@ -0,0 +1,3009 @@ +#ifndef __MCU_INIT_AOP_A0_H__ +#define __MCU_INIT_AOP_A0_H__ + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_mcu_ddr[] = { + 0x20040c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20040c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU0) ADDR=0x20040c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20040c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20040c05c DWORD=0 NUMREGS=0 */ + 0x20044c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20044c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU1) ADDR=0x20044c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20044c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20044c05c DWORD=0 NUMREGS=0 */ + 0x2004cc15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2004cc01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU3) ADDR=0x2004cc000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2004cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2004cc05c DWORD=0 NUMREGS=0 */ + 0x20048c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20048c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU2) ADDR=0x20048c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20048c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20048c05c DWORD=0 NUMREGS=0 */ + 0x2004007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200400450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200400458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20040045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200400460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2004004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200400468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20040046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200400470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200400474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200400478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2004004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200400480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200400484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200400488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20040048c DWORD=0 NUMREGS=0 */ + 0x2004005d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200400490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2004004cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200400498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20040049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2004004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2004004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2004004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2004004d0 DWORD=0 NUMREGS=0 */ + 0x2004407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200440450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200440458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20044045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200440460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2004404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200440468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20044046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200440470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200440474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200440478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2004404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200440480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200440484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200440488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20044048c DWORD=0 NUMREGS=0 */ + 0x2004405d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200440490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2004404cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200440498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20044049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2004404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2004404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2004404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2004404d0 DWORD=0 NUMREGS=0 */ + 0x2004c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2004c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2004c0458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2004c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2004c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2004c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2004c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2004c046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2004c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2004c0474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2004c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2004c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2004c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2004c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2004c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2004c048c DWORD=0 NUMREGS=0 */ + 0x2004c05d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2004c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2004c04cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2004c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2004c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2004c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2004c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2004c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2004c04d0 DWORD=0 NUMREGS=0 */ + 0x2004807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200480450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200480458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20048045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200480460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2004804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200480468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20048046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200480470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200480474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200480478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2004804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200480480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200480484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200480488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20048048c DWORD=0 NUMREGS=0 */ + 0x2004805d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200480490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2004804cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200480498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20048049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2004804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2004804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2004804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2004804d0 DWORD=0 NUMREGS=0 */ + 0x200420dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ef4 DWORD=0 NUMREGS=0 */ + 0x200460dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ef4 DWORD=0 NUMREGS=0 */ + 0x2004a0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ef4 DWORD=0 NUMREGS=0 */ + 0x2004e0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ef4 DWORD=0 NUMREGS=0 */ + 0x20f14005, //compressed WR cmd + 0x00002324, //compressed WR offset + 0x00000003, /* WR:GLBTIMER_GLBTIMER_PERVREFCALCFG(GLBTIMER) ADDR=0x20f140090 DWORD=0 NUMREGS=0 */ + 0x00060006, /* WR:GLBTIMER_GLBTIMER_VREFCNTRL(GLBTIMER) ADDR=0x20f14008c DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU0) ADDR=0x200400400 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU1) ADDR=0x200440400 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU3) ADDR=0x2004c0400 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU2) ADDR=0x200480400 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xa0e1e0f4, //compressed WR offset + 0xe4a3a2a1, //compressed WR offset + 0xf5f0ece8, //compressed WR offset + 0xf1ede9e5, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2004c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2004c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2004c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU3) ADDR=0x2004c028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2004c0390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2004c03a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2004c03c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2004c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2004c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2004c03c4 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xf2eeeae6, //compressed WR offset + 0xf3efebe7, //compressed WR offset + 0xf7f6f4ff, //compressed WR offset + 0xe1e0f9f8, //compressed WR offset + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2004c0398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2004c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2004c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2004c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2004c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2004c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2004c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2004c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2004c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2004c03e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x2004c011, //compressed WR cmd + 0xfbfae3e2, //compressed WR offset + 0x000000fc, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2004c0388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2004c038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2004c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2004c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2004c03f0 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200400280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200400284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200400288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU0) ADDR=0x20040028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200400390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2004003a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2004003c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200400394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2004003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2004003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200400398 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2004003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2004003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20040039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2004003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2004003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2004003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2004003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2004003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2004003e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200400388 DWORD=0 NUMREGS=0 */ + 0x2004000d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20040038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2004003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2004003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2004003f0 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200440280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200440284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200440288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU1) ADDR=0x20044028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200440390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2004403a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2004403c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200440394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2004403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2004403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200440398 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2004403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2004403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20044039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2004403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2004403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2004403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2004403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2004403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2004403e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200440388 DWORD=0 NUMREGS=0 */ + 0x2004400d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20044038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2004403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2004403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2004403f0 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200480280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200480284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200480288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU2) ADDR=0x20048028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200480390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2004803a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2004803c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200480394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2004803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2004803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200480398 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2004803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2004803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20048039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2004803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2004803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2004803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2004803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2004803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2004803e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200480388 DWORD=0 NUMREGS=0 */ + 0x2004800d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20048038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2004803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2004803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2004803f0 DWORD=0 NUMREGS=0 */ + 0x20040051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200400404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200400780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20040078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200440404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200440780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20044078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2004c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2004c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2004c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200480404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200480780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20048078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x20043835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU0) ADDR=0x2004382a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU0) ADDR=0x2004382a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU0) ADDR=0x2004382a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU0) ADDR=0x2004382ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU0) ADDR=0x2004382b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU0) ADDR=0x2004382b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU0) ADDR=0x20043829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU0) ADDR=0x2004382a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU0) ADDR=0x2004382a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU0) ADDR=0x2004382a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU0) ADDR=0x2004382ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU0) ADDR=0x2004382b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU0) ADDR=0x2004382b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU0) ADDR=0x20043829c DWORD=0 NUMREGS=0 */ + 0x20047835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU1) ADDR=0x2004782a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU1) ADDR=0x2004782a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU1) ADDR=0x2004782a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU1) ADDR=0x2004782ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU1) ADDR=0x2004782b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU1) ADDR=0x2004782b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU1) ADDR=0x20047829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU1) ADDR=0x2004782a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU1) ADDR=0x2004782a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU1) ADDR=0x2004782a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU1) ADDR=0x2004782ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU1) ADDR=0x2004782b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU1) ADDR=0x2004782b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU1) ADDR=0x20047829c DWORD=0 NUMREGS=0 */ + 0x2004f835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU3) ADDR=0x2004f82a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU3) ADDR=0x2004f82a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU3) ADDR=0x2004f82a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU3) ADDR=0x2004f82ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU3) ADDR=0x2004f82b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU3) ADDR=0x2004f82b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU3) ADDR=0x2004f829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU3) ADDR=0x2004f82a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU3) ADDR=0x2004f82a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU3) ADDR=0x2004f82a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU3) ADDR=0x2004f82ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU3) ADDR=0x2004f82b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU3) ADDR=0x2004f82b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU3) ADDR=0x2004f829c DWORD=0 NUMREGS=0 */ + 0x2004b835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU2) ADDR=0x2004b82a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU2) ADDR=0x2004b82a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU2) ADDR=0x2004b82a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU2) ADDR=0x2004b82ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU2) ADDR=0x2004b82b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU2) ADDR=0x2004b82b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU2) ADDR=0x2004b829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU2) ADDR=0x2004b82a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU2) ADDR=0x2004b82a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU2) ADDR=0x2004b82a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU2) ADDR=0x2004b82ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU2) ADDR=0x2004b82b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU2) ADDR=0x2004b82b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU2) ADDR=0x2004b829c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200420000 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200460000 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2004a0000 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2004e0000 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200428000 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200430000 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200468000 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200470000 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2004a8000 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2004b0000 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2004e8000 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2004f0000 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200420d10 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200460d10 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2004a0d10 DWORD=0 NUMREGS=0 */ + 0x2004e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2004e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2004e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2004e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2004e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2004e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2004e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2004e0d0c DWORD=0 NUMREGS=0 */ + 0x200420d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200420d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200420d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200420d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200420d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200420d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200420d0c DWORD=0 NUMREGS=0 */ + 0x200460d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200460d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200460d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200460d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200460d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200460d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200460d0c DWORD=0 NUMREGS=0 */ + 0x2004a0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2004a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2004a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2004a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2004a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2004a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2004a0d0c DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200420718 DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200460718 DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2004a0718 DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2004e0718 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20042861c DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20043061c DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20046861c DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20047061c DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2004a861c DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2004b061c DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2004e861c DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2004f061c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200420f80 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200460f80 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2004a0f80 DWORD=0 NUMREGS=0 */ + 0x2004e0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2004e0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2004e0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2004e0f88 DWORD=0 NUMREGS=0 */ + 0x200420c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200420f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200420f88 DWORD=0 NUMREGS=0 */ + 0x200460c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200460f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200460f88 DWORD=0 NUMREGS=0 */ + 0x2004a0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2004a0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2004a0f88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200428d80 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200430d80 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200468d80 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200470d80 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2004a8d80 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2004b0d80 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2004e8d80 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2004f0d80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200428d84 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200430d84 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200468d84 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200470d84 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2004a8d84 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2004b0d84 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2004e8d84 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2004f0d84 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200428d88 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200430d88 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200468d88 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200470d88 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2004a8d88 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2004b0d88 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2004e8d88 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2004f0d88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200428d8c DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200430d8c DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200468d8c DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200470d8c DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2004a8d8c DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2004b0d8c DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2004e8d8c DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2004f0d8c DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2004281cc DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2004301cc DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2004681cc DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2004701cc DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2004a81cc DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2004b01cc DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2004e81cc DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2004f01cc DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200420e00 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200460e00 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2004a0e00 DWORD=0 NUMREGS=0 */ + 0x2004e0fd, //compressed WR cmd + 0x86828180, //compressed WR offset + 0x8b8a8983, //compressed WR offset + 0xaaa9a88c, //compressed WR offset + 0x8f8eacab, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2004e0e00 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2004e0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2004e0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU3) ADDR=0x2004e0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2004e0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2004e0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2004e0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU3) ADDR=0x2004e0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU3) ADDR=0x2004e0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU3) ADDR=0x2004e0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU3) ADDR=0x2004e0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU3) ADDR=0x2004e0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e3c DWORD=0 NUMREGS=0 */ + 0x2004e0cd, //compressed WR cmd + 0xa09f9190, //compressed WR offset + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e40 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e80 DWORD=0 NUMREGS=0 */ + 0x200420fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200420e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200420e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU0) ADDR=0x200420e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200420e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200420e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200420e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200420e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200420e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU0) ADDR=0x200420ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU0) ADDR=0x200420ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU0) ADDR=0x200420ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU0) ADDR=0x200420eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU0) ADDR=0x200420eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200420e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200420e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200420e40 DWORD=0 NUMREGS=0 */ + 0x200420c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200420e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e80 DWORD=0 NUMREGS=0 */ + 0x200460fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200460e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200460e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU1) ADDR=0x200460e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200460e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200460e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200460e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200460e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200460e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU1) ADDR=0x200460ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU1) ADDR=0x200460ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU1) ADDR=0x200460ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU1) ADDR=0x200460eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU1) ADDR=0x200460eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200460e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200460e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200460e40 DWORD=0 NUMREGS=0 */ + 0x200460c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200460e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e80 DWORD=0 NUMREGS=0 */ + 0x2004a0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2004a0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2004a0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU2) ADDR=0x2004a0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2004a0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2004a0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2004a0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU2) ADDR=0x2004a0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU2) ADDR=0x2004a0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU2) ADDR=0x2004a0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU2) ADDR=0x2004a0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU2) ADDR=0x2004a0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e40 DWORD=0 NUMREGS=0 */ + 0x2004a0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200428d00 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200430d00 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200468d00 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200470d00 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2004a8d00 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2004b0d00 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2004e8d00 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2004f0d00 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200428100 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200430100 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200468100 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200470100 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2004a8100 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2004b0100 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2004e8100 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2004f0100 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200428104 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200430104 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200468104 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200470104 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2004a8104 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2004b0104 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2004e8104 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2004f0104 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200428108 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200430108 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200468108 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200470108 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2004a8108 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2004b0108 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2004e8108 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2004f0108 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20042810c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20043010c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20046810c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20047010c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2004a810c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2004b010c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2004e810c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2004f010c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2004201a0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2004601a0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2004a01a0 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2004e01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2004281a0 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2004301a0 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2004681a0 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2004701a0 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2004a81a0 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2004b01a0 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2004e81a0 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2004f01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200428180 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200430180 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200468180 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200470180 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2004a8180 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2004b0180 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2004e8180 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2004f0180 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU0) ADDR=0x2004200dc DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU1) ADDR=0x2004600dc DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU2) ADDR=0x2004a00dc DWORD=0 NUMREGS=0 */ + 0x2004e005, //compressed WR cmd + 0x00003837, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU3) ADDR=0x2004e00dc DWORD=0 NUMREGS=0 */ + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU3) ADDR=0x2004e00e0 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU0) ADDR=0x2004200e0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU1) ADDR=0x2004600e0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU2) ADDR=0x2004a00e0 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU0) ADDR=0x200420ecc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU1) ADDR=0x200460ecc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU2) ADDR=0x2004a0ecc DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU3) ADDR=0x2004e0ecc DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU0) ADDR=0x200438030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU0) ADDR=0x200438028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU0) ADDR=0x200438044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU0) ADDR=0x200438058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU0) ADDR=0x200438068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU0) ADDR=0x200438050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU0) ADDR=0x200438060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU0) ADDR=0x200438078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU0) ADDR=0x200438080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU0) ADDR=0x2004380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2004380b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU0) ADDR=0x2004380b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU0) ADDR=0x2004380e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU0) ADDR=0x200438120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU0) ADDR=0x2004380f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU0) ADDR=0x20043810c DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20043811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU0) ADDR=0x2004380c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU0) ADDR=0x2004380d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2004380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU0) ADDR=0x2004380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU0) ADDR=0x2004380e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU0) ADDR=0x200438130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU0) ADDR=0x200438140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200438148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU0) ADDR=0x200438150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU0) ADDR=0x20043814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU0) ADDR=0x200438024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU0) ADDR=0x20043800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU0) ADDR=0x200438008 DWORD=0 NUMREGS=0 */ + 0x20043801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2004382fc DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU1) ADDR=0x200478030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU1) ADDR=0x200478028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU1) ADDR=0x200478044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU1) ADDR=0x200478058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU1) ADDR=0x200478068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU1) ADDR=0x200478050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU1) ADDR=0x200478060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU1) ADDR=0x200478078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU1) ADDR=0x200478080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU1) ADDR=0x2004780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2004780b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU1) ADDR=0x2004780b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU1) ADDR=0x2004780e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU1) ADDR=0x200478120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU1) ADDR=0x2004780f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU1) ADDR=0x20047810c DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20047811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU1) ADDR=0x2004780c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU1) ADDR=0x2004780d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2004780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU1) ADDR=0x2004780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU1) ADDR=0x2004780e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU1) ADDR=0x200478130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU1) ADDR=0x200478140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200478148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU1) ADDR=0x200478150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU1) ADDR=0x20047814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU1) ADDR=0x200478024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU1) ADDR=0x20047800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU1) ADDR=0x200478008 DWORD=0 NUMREGS=0 */ + 0x20047801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2004782fc DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU3) ADDR=0x2004f8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU3) ADDR=0x2004f8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU3) ADDR=0x2004f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU3) ADDR=0x2004f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU3) ADDR=0x2004f8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU3) ADDR=0x2004f8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU3) ADDR=0x2004f8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU3) ADDR=0x2004f8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU3) ADDR=0x2004f8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU3) ADDR=0x2004f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2004f80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU3) ADDR=0x2004f80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU3) ADDR=0x2004f80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU3) ADDR=0x2004f8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU3) ADDR=0x2004f80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU3) ADDR=0x2004f810c DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2004f811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU3) ADDR=0x2004f80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU3) ADDR=0x2004f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2004f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU3) ADDR=0x2004f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU3) ADDR=0x2004f80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU3) ADDR=0x2004f8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU3) ADDR=0x2004f8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2004f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU3) ADDR=0x2004f8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU3) ADDR=0x2004f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU3) ADDR=0x2004f8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU3) ADDR=0x2004f800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU3) ADDR=0x2004f8008 DWORD=0 NUMREGS=0 */ + 0x2004f801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2004f82fc DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU2) ADDR=0x2004b8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU2) ADDR=0x2004b8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU2) ADDR=0x2004b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU2) ADDR=0x2004b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU2) ADDR=0x2004b8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU2) ADDR=0x2004b8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU2) ADDR=0x2004b8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU2) ADDR=0x2004b8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU2) ADDR=0x2004b8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU2) ADDR=0x2004b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2004b80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU2) ADDR=0x2004b80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU2) ADDR=0x2004b80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU2) ADDR=0x2004b8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU2) ADDR=0x2004b80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU2) ADDR=0x2004b810c DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2004b811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU2) ADDR=0x2004b80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU2) ADDR=0x2004b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2004b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU2) ADDR=0x2004b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU2) ADDR=0x2004b80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU2) ADDR=0x2004b8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU2) ADDR=0x2004b8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2004b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU2) ADDR=0x2004b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU2) ADDR=0x2004b814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU2) ADDR=0x2004b8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU2) ADDR=0x2004b800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU2) ADDR=0x2004b8008 DWORD=0 NUMREGS=0 */ + 0x2004b801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2004b82fc DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200420008 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200460008 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2004a0008 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2004e0008 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200428008 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200430008 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200468008 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200470008 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2004a8008 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2004b0008 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2004e8008 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2004f0008 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200420e74 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200460e74 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2004a0e74 DWORD=0 NUMREGS=0 */ + 0x2004e0c5, //compressed WR cmd + 0x0000b79d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2004e0e74 DWORD=0 NUMREGS=0 */ + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU3) ADDR=0x2004e0edc DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU0) ADDR=0x200420edc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU1) ADDR=0x200460edc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU2) ADDR=0x2004a0edc DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0x20040011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x20044011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x20048011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x2004c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x20040049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20040041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20044041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2004c041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20048049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20048041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 NUMREGS=0 */ + 0x20042002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200400414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200400410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20040040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200400408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200440414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200440410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20044040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200440408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2004c0414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2004c0410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2004c040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2004c0408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200480414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200480410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20048040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200480408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20040045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000011, //compressed WR offset + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CHEN(GLBTIMER) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00051004, /* DELAY for 27 uS (5184 clock cycles) */ + 0x20043805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x20047805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x2004f805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x2004b805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200420cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x200460cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x2004a0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x2004e0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x20043805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU0) ADDR=0x20043809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU0) ADDR=0x200438098 DWORD=0 NUMREGS=0 */ + 0x20047805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU1) ADDR=0x20047809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU1) ADDR=0x200478098 DWORD=0 NUMREGS=0 */ + 0x2004f805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU3) ADDR=0x2004f809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU3) ADDR=0x2004f8098 DWORD=0 NUMREGS=0 */ + 0x2004b805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU2) ADDR=0x2004b809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU2) ADDR=0x2004b8098 DWORD=0 NUMREGS=0 */ + 0x20040005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20040019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20044019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20048005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20048019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC1) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC1) ADDR=0x200200648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC1) ADDR=0x20020064c DWORD=0 NUMREGS=0 */ + 0x20000049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC0) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC0) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC0) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x2004c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2004c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200428004 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200430004 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200468004 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200470004 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2004a8004 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2004b0004 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2004e8004 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2004f0004 DWORD=0 NUMREGS=0 */ + 0x20040c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU0) ADDR=0x20040c064 DWORD=0 NUMREGS=0 */ + 0x20048c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU2) ADDR=0x20048c064 DWORD=0 NUMREGS=0 */ + 0x20044c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU1) ADDR=0x20044c064 DWORD=0 NUMREGS=0 */ + 0x2004cc01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU3) ADDR=0x2004cc064 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x20f14015, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x0000211f, //compressed WR offset + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(GLBTIMER) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(GLBTIMER) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(GLBTIMER) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(GLBTIMER) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_CALSEG2ALLBANK0(GLBTIMER) ADDR=0x20f14007c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_ALLBANK2CALSEG0(GLBTIMER) ADDR=0x20f140084 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200480010 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200400010 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200440010 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2004c0010 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20044042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20048042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x2004c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_mcu_locked[] = { + 0x20000051, //compressed WR cmd + 0x2e332929, //compressed WR offset + 0x00000029, //compressed WR offset + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC0) ADDR=0x2000004cc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC0) ADDR=0x2000004b8 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x20020051, //compressed WR cmd + 0x2e332929, //compressed WR offset + 0x00000029, //compressed WR offset + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC1) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC1) ADDR=0x2002004b8 DWORD=0 NUMREGS=0 */ + 0x00050110, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_before_restoration[] = { + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 NUMREGS=0 */ + 0x20042802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x2004a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2004e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200420700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200460700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2004a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2004e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200420708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200460708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2004a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2004e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200420710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200460710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2004a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2004e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20042081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20046081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200420500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200460500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2004a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2004e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200420504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200460504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2004a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2004e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200420508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200460508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2004a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2004e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20042050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20046050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2004a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2004e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200420510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200460510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2004a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2004e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200420514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200460514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2004a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2004e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200420518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200460518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2004a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2004e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20042051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20046051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2004a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2004e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20042841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200428704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20043041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200430704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20046841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200468704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20047041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200470704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2004a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2004b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2004e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2004f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200428b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200430b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200468b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200470b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2004a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2004b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2004e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2004f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200428b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200430b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200468b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200470b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2004a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2004b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2004e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2004f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + /* ####### IMPORTANT ##### PLEASE READ ##### */ + /* When restoring below WrDqCalVrefCodeControl and RdDqCalVrefCodeControl registers, Software first needs to read WrDQCalVrefCodeStatus and RdDqCalVrefCodeStatus registers and put the value from CodeStatus registers to CodeControl registers */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_after_restoration[] = { + 0x200420c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20f14025, //compressed WR cmd + 0x0107000f, //compressed WR offset + 0x06050402, //compressed WR offset + 0x00000a08, //compressed WR offset + 0x000001ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(GLBTIMER) ADDR=0x20f14003c DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(GLBTIMER) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_DCCTIMER(GLBTIMER) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(GLBTIMER) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(GLBTIMER) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6bb, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(GLBTIMER) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(GLBTIMER) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x003d0900, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(GLBTIMER) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(GLBTIMER) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(GLBTIMER) ADDR=0x20f140028 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001.h new file mode 100644 index 0000000..d6d042d --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001.h @@ -0,0 +1,6042 @@ +#ifndef __MCU_INIT_AOP_H__ +#define __MCU_INIT_AOP_H__ + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_ddr[] = { + 0x20040c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20040c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU0) ADDR=0x20040c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20040c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20040c05c DWORD=0 NUMREGS=0 */ + 0x20044c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20044c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU1) ADDR=0x20044c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20044c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20044c05c DWORD=0 NUMREGS=0 */ + 0x20050c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU4) ADDR=0x20050c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU4) ADDR=0x20050c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU4) ADDR=0x20050c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU4) ADDR=0x20050c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU4) ADDR=0x20050c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU4) ADDR=0x20050c05c DWORD=0 NUMREGS=0 */ + 0x2004cc15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2004cc01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU3) ADDR=0x2004cc000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2004cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2004cc05c DWORD=0 NUMREGS=0 */ + 0x20054c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU5) ADDR=0x20054c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU5) ADDR=0x20054c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU5) ADDR=0x20054c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU5) ADDR=0x20054c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU5) ADDR=0x20054c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU5) ADDR=0x20054c05c DWORD=0 NUMREGS=0 */ + 0x20048c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20048c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU2) ADDR=0x20048c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20048c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20048c05c DWORD=0 NUMREGS=0 */ + 0x20058c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU6) ADDR=0x20058c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU6) ADDR=0x20058c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU6) ADDR=0x20058c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU6) ADDR=0x20058c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU6) ADDR=0x20058c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU6) ADDR=0x20058c05c DWORD=0 NUMREGS=0 */ + 0x2005cc15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU7) ADDR=0x2005cc01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU7) ADDR=0x2005cc000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU7) ADDR=0x2005cc020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU7) ADDR=0x2005cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU7) ADDR=0x2005cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU7) ADDR=0x2005cc05c DWORD=0 NUMREGS=0 */ + 0x2004007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200400450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200400458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20040045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200400460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2004004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200400468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20040046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200400470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200400474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200400478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2004004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200400480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200400484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200400488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20040048c DWORD=0 NUMREGS=0 */ + 0x2004005d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200400490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2004004cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200400498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20040049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2004004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2004004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2004004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2004004d0 DWORD=0 NUMREGS=0 */ + 0x2004407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200440450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200440458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20044045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200440460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2004404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200440468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20044046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200440470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200440474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200440478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2004404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200440480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200440484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200440488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20044048c DWORD=0 NUMREGS=0 */ + 0x2004405d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200440490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2004404cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200440498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20044049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2004404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2004404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2004404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2004404d0 DWORD=0 NUMREGS=0 */ + 0x2004c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2004c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2004c0458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2004c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2004c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2004c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2004c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2004c046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2004c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2004c0474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2004c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2004c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2004c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2004c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2004c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2004c048c DWORD=0 NUMREGS=0 */ + 0x2004c05d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2004c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2004c04cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2004c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2004c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2004c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2004c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2004c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2004c04d0 DWORD=0 NUMREGS=0 */ + 0x2005007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU4) ADDR=0x200500450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU4) ADDR=0x200500454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU4) ADDR=0x200500458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU4) ADDR=0x20050045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU4) ADDR=0x200500460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU4) ADDR=0x2005004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU4) ADDR=0x200500468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU4) ADDR=0x20050046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU4) ADDR=0x200500470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU4) ADDR=0x200500474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU4) ADDR=0x200500478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU4) ADDR=0x2005004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU4) ADDR=0x200500480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU4) ADDR=0x200500484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU4) ADDR=0x200500488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU4) ADDR=0x20050048c DWORD=0 NUMREGS=0 */ + 0x2005005d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU4) ADDR=0x200500490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU4) ADDR=0x2005004cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU4) ADDR=0x200500498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU4) ADDR=0x20050049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU4) ADDR=0x2005004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU4) ADDR=0x2005004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU4) ADDR=0x2005004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU4) ADDR=0x2005004d0 DWORD=0 NUMREGS=0 */ + 0x2005c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU7) ADDR=0x2005c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU7) ADDR=0x2005c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU7) ADDR=0x2005c0458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU7) ADDR=0x2005c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU7) ADDR=0x2005c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU7) ADDR=0x2005c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU7) ADDR=0x2005c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU7) ADDR=0x2005c046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU7) ADDR=0x2005c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU7) ADDR=0x2005c0474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU7) ADDR=0x2005c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU7) ADDR=0x2005c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU7) ADDR=0x2005c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU7) ADDR=0x2005c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU7) ADDR=0x2005c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU7) ADDR=0x2005c048c DWORD=0 NUMREGS=0 */ + 0x2005c05d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU7) ADDR=0x2005c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU7) ADDR=0x2005c04cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU7) ADDR=0x2005c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU7) ADDR=0x2005c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU7) ADDR=0x2005c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU7) ADDR=0x2005c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU7) ADDR=0x2005c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU7) ADDR=0x2005c04d0 DWORD=0 NUMREGS=0 */ + 0x2004807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200480450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200480458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20048045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200480460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2004804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200480468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20048046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200480470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200480474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200480478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2004804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200480480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200480484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200480488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20048048c DWORD=0 NUMREGS=0 */ + 0x2004805d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200480490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2004804cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200480498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20048049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2004804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2004804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2004804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2004804d0 DWORD=0 NUMREGS=0 */ + 0x2005407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU5) ADDR=0x200540450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU5) ADDR=0x200540454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU5) ADDR=0x200540458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU5) ADDR=0x20054045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU5) ADDR=0x200540460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU5) ADDR=0x2005404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU5) ADDR=0x200540468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU5) ADDR=0x20054046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU5) ADDR=0x200540470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU5) ADDR=0x200540474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU5) ADDR=0x200540478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU5) ADDR=0x2005404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU5) ADDR=0x200540480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU5) ADDR=0x200540484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU5) ADDR=0x200540488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU5) ADDR=0x20054048c DWORD=0 NUMREGS=0 */ + 0x2005405d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU5) ADDR=0x200540490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU5) ADDR=0x2005404cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU5) ADDR=0x200540498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU5) ADDR=0x20054049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU5) ADDR=0x2005404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU5) ADDR=0x2005404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU5) ADDR=0x2005404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU5) ADDR=0x2005404d0 DWORD=0 NUMREGS=0 */ + 0x2005807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU6) ADDR=0x200580450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU6) ADDR=0x200580454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU6) ADDR=0x200580458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU6) ADDR=0x20058045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU6) ADDR=0x200580460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU6) ADDR=0x2005804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU6) ADDR=0x200580468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU6) ADDR=0x20058046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU6) ADDR=0x200580470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU6) ADDR=0x200580474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU6) ADDR=0x200580478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU6) ADDR=0x2005804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU6) ADDR=0x200580480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU6) ADDR=0x200580484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU6) ADDR=0x200580488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU6) ADDR=0x20058048c DWORD=0 NUMREGS=0 */ + 0x2005805d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU6) ADDR=0x200580490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU6) ADDR=0x2005804cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU6) ADDR=0x200580498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU6) ADDR=0x20058049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU6) ADDR=0x2005804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU6) ADDR=0x2005804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU6) ADDR=0x2005804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU6) ADDR=0x2005804d0 DWORD=0 NUMREGS=0 */ + 0x200420dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ef4 DWORD=0 NUMREGS=0 */ + 0x200460dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ef4 DWORD=0 NUMREGS=0 */ + 0x2004a0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ef4 DWORD=0 NUMREGS=0 */ + 0x20f14005, //compressed WR cmd + 0x00002324, //compressed WR offset + 0x00000003, /* WR:GLBTIMER_GLBTIMER_PERVREFCALCFG(GLBTIMER) ADDR=0x20f140090 DWORD=0 NUMREGS=0 */ + 0x00060006, /* WR:GLBTIMER_GLBTIMER_VREFCNTRL(GLBTIMER) ADDR=0x20f14008c DWORD=0 NUMREGS=0 */ + 0x2005e0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU7) ADDR=0x2005e0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU7) ADDR=0x2005e0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU7) ADDR=0x2005e0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU7) ADDR=0x2005e0ef4 DWORD=0 NUMREGS=0 */ + 0x200520dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU4) ADDR=0x200520ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU4) ADDR=0x200520ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU4) ADDR=0x200520ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU4) ADDR=0x200520ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU4) ADDR=0x200520ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU4) ADDR=0x200520ef4 DWORD=0 NUMREGS=0 */ + 0x2004e0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ef4 DWORD=0 NUMREGS=0 */ + 0x200560dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU5) ADDR=0x200560ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU5) ADDR=0x200560ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU5) ADDR=0x200560ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU5) ADDR=0x200560ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU5) ADDR=0x200560ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU5) ADDR=0x200560ef4 DWORD=0 NUMREGS=0 */ + 0x2005a0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f18 DWORD=0 NUMREGS=0 */ + 0x01d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU6) ADDR=0x2005a0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU6) ADDR=0x2005a0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU6) ADDR=0x2005a0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU6) ADDR=0x2005a0ef4 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU4) ADDR=0x2005003d4 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU6) ADDR=0x2005803d4 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU5) ADDR=0x2005403d4 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU7) ADDR=0x2005c03d4 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ0) ADDR=0x2005281a4 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ1) ADDR=0x2005301a4 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ0) ADDR=0x2005681a4 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ1) ADDR=0x2005701a4 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ0) ADDR=0x2005a81a4 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ1) ADDR=0x2005b01a4 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ0) ADDR=0x2005e81a4 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ1) ADDR=0x2005f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU4) ADDR=0x2005201a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU6) ADDR=0x2005a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU5) ADDR=0x2005601a4 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU7) ADDR=0x2005e01a4 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU4) ADDR=0x2005003d0 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU6) ADDR=0x2005803d0 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU5) ADDR=0x2005403d0 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x2005c03d, //compressed WR cmd + 0xa0e1e0f4, //compressed WR offset + 0xe4a3a2a1, //compressed WR offset + 0xf5f0ece8, //compressed WR offset + 0xf1ede9e5, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU7) ADDR=0x2005c03d0 DWORD=0 NUMREGS=0 */ + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU7) ADDR=0x2005c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU7) ADDR=0x2005c0384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU7) ADDR=0x2005c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU7) ADDR=0x2005c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU7) ADDR=0x2005c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU7) ADDR=0x2005c028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU7) ADDR=0x2005c0390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU7) ADDR=0x2005c03a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU7) ADDR=0x2005c03b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU7) ADDR=0x2005c03c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU7) ADDR=0x2005c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU7) ADDR=0x2005c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU7) ADDR=0x2005c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU7) ADDR=0x2005c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU7) ADDR=0x2005c03c4 DWORD=0 NUMREGS=0 */ + 0x2005c03d, //compressed WR cmd + 0xf2eeeae6, //compressed WR offset + 0xf3efebe7, //compressed WR offset + 0xf7f6f4ff, //compressed WR offset + 0xe1e0f9f8, //compressed WR offset + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU7) ADDR=0x2005c0398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU7) ADDR=0x2005c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU7) ADDR=0x2005c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU7) ADDR=0x2005c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU7) ADDR=0x2005c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU7) ADDR=0x2005c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU7) ADDR=0x2005c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU7) ADDR=0x2005c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU7) ADDR=0x2005c03fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU7) ADDR=0x2005c03d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU7) ADDR=0x2005c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU7) ADDR=0x2005c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU7) ADDR=0x2005c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU7) ADDR=0x2005c03e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU7) ADDR=0x2005c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU7) ADDR=0x2005c0384 DWORD=0 NUMREGS=0 */ + 0x2005c011, //compressed WR cmd + 0xfbfae3e2, //compressed WR offset + 0x000000fc, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU7) ADDR=0x2005c0388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU7) ADDR=0x2005c038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU7) ADDR=0x2005c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU7) ADDR=0x2005c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU7) ADDR=0x2005c03f0 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200400280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200400284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200400288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU0) ADDR=0x20040028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200400390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2004003a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2004003c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200400394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2004003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2004003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200400398 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2004003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2004003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20040039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2004003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2004003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2004003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2004003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2004003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2004003e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200400388 DWORD=0 NUMREGS=0 */ + 0x2004000d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20040038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2004003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2004003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2004003f0 DWORD=0 NUMREGS=0 */ + 0x2005003d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU4) ADDR=0x200500380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU4) ADDR=0x200500384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU4) ADDR=0x200500280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU4) ADDR=0x200500284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU4) ADDR=0x200500288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU4) ADDR=0x20050028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU4) ADDR=0x200500390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU4) ADDR=0x2005003a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU4) ADDR=0x2005003b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU4) ADDR=0x2005003c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU4) ADDR=0x2005003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU4) ADDR=0x200500394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU4) ADDR=0x2005003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU4) ADDR=0x2005003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU4) ADDR=0x2005003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU4) ADDR=0x200500398 DWORD=0 NUMREGS=0 */ + 0x2005003d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU4) ADDR=0x2005003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU4) ADDR=0x2005003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU4) ADDR=0x2005003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU4) ADDR=0x20050039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU4) ADDR=0x2005003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU4) ADDR=0x2005003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU4) ADDR=0x2005003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU4) ADDR=0x2005003fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU4) ADDR=0x2005003d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU4) ADDR=0x2005003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU4) ADDR=0x2005003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU4) ADDR=0x2005003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU4) ADDR=0x2005003e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU4) ADDR=0x200500380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU4) ADDR=0x200500384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU4) ADDR=0x200500388 DWORD=0 NUMREGS=0 */ + 0x2005000d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU4) ADDR=0x20050038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU4) ADDR=0x2005003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU4) ADDR=0x2005003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU4) ADDR=0x2005003f0 DWORD=0 NUMREGS=0 */ + 0x2005803d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU6) ADDR=0x200580380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU6) ADDR=0x200580384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU6) ADDR=0x200580280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU6) ADDR=0x200580284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU6) ADDR=0x200580288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU6) ADDR=0x20058028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU6) ADDR=0x200580390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU6) ADDR=0x2005803a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU6) ADDR=0x2005803b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU6) ADDR=0x2005803c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU6) ADDR=0x2005803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU6) ADDR=0x200580394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU6) ADDR=0x2005803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU6) ADDR=0x2005803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU6) ADDR=0x2005803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU6) ADDR=0x200580398 DWORD=0 NUMREGS=0 */ + 0x2005803d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU6) ADDR=0x2005803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU6) ADDR=0x2005803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU6) ADDR=0x2005803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU6) ADDR=0x20058039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU6) ADDR=0x2005803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU6) ADDR=0x2005803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU6) ADDR=0x2005803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU6) ADDR=0x2005803fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU6) ADDR=0x2005803d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU6) ADDR=0x2005803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU6) ADDR=0x2005803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU6) ADDR=0x2005803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU6) ADDR=0x2005803e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU6) ADDR=0x200580380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU6) ADDR=0x200580384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU6) ADDR=0x200580388 DWORD=0 NUMREGS=0 */ + 0x2005800d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU6) ADDR=0x20058038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU6) ADDR=0x2005803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU6) ADDR=0x2005803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU6) ADDR=0x2005803f0 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2004c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2004c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2004c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU3) ADDR=0x2004c028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2004c0390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2004c03a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2004c03c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2004c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2004c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2004c03c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2004c0398 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2004c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2004c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2004c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2004c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2004c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2004c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2004c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2004c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2004c03e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2004c0388 DWORD=0 NUMREGS=0 */ + 0x2004c00d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2004c038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2004c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2004c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2004c03f0 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200440280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200440284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200440288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU1) ADDR=0x20044028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200440390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2004403a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2004403c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200440394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2004403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2004403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200440398 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2004403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2004403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20044039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2004403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2004403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2004403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2004403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2004403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2004403e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200440388 DWORD=0 NUMREGS=0 */ + 0x2004400d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20044038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2004403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2004403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2004403f0 DWORD=0 NUMREGS=0 */ + 0x2005403d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU5) ADDR=0x200540380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU5) ADDR=0x200540384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU5) ADDR=0x200540280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU5) ADDR=0x200540284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU5) ADDR=0x200540288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU5) ADDR=0x20054028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU5) ADDR=0x200540390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU5) ADDR=0x2005403a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU5) ADDR=0x2005403b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU5) ADDR=0x2005403c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU5) ADDR=0x2005403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU5) ADDR=0x200540394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU5) ADDR=0x2005403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU5) ADDR=0x2005403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU5) ADDR=0x2005403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU5) ADDR=0x200540398 DWORD=0 NUMREGS=0 */ + 0x2005403d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU5) ADDR=0x2005403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU5) ADDR=0x2005403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU5) ADDR=0x2005403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU5) ADDR=0x20054039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU5) ADDR=0x2005403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU5) ADDR=0x2005403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU5) ADDR=0x2005403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU5) ADDR=0x2005403fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU5) ADDR=0x2005403d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU5) ADDR=0x2005403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU5) ADDR=0x2005403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU5) ADDR=0x2005403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU5) ADDR=0x2005403e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU5) ADDR=0x200540380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU5) ADDR=0x200540384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU5) ADDR=0x200540388 DWORD=0 NUMREGS=0 */ + 0x2005400d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU5) ADDR=0x20054038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU5) ADDR=0x2005403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU5) ADDR=0x2005403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU5) ADDR=0x2005403f0 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200480280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200480284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200480288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU2) ADDR=0x20048028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200480390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2004803a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2004803c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200480394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2004803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2004803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200480398 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2004803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2004803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20048039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2004803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2004803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2004803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2004803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2004803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2004803e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200480388 DWORD=0 NUMREGS=0 */ + 0x2004800d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20048038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2004803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2004803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2004803f0 DWORD=0 NUMREGS=0 */ + 0x20040051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200400404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200400780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20040078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200440404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200440780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20044078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2004c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2004c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2004c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20050051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU4) ADDR=0x200500404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU4) ADDR=0x200500780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU4) ADDR=0x20050078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU4) ADDR=0x200500424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x2005c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU7) ADDR=0x2005c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU7) ADDR=0x2005c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU7) ADDR=0x2005c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU7) ADDR=0x2005c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200480404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200480780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20048078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20054051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU5) ADDR=0x200540404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU5) ADDR=0x200540780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU5) ADDR=0x20054078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU5) ADDR=0x200540424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x20058051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU6) ADDR=0x200580404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU6) ADDR=0x200580780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU6) ADDR=0x20058078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU6) ADDR=0x200580424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU4) ADDR=0x200500000 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU6) ADDR=0x200580000 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU5) ADDR=0x200540000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU7) ADDR=0x2005c0000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU4) ADDR=0x20050043c DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU7) ADDR=0x2005c043c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU5) ADDR=0x20054043c DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU6) ADDR=0x20058043c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200420000 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200460000 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU4) ADDR=0x200520000 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2004a0000 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU6) ADDR=0x2005a0000 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU5) ADDR=0x200560000 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2004e0000 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU7) ADDR=0x2005e0000 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200428000 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200430000 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200468000 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200470000 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2004a8000 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2004b0000 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2004e8000 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2004f0000 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU4, DQ0) ADDR=0x200528000 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU4, DQ1) ADDR=0x200530000 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU5, DQ0) ADDR=0x200568000 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU5, DQ1) ADDR=0x200570000 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU6, DQ0) ADDR=0x2005a8000 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU6, DQ1) ADDR=0x2005b0000 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU7, DQ0) ADDR=0x2005e8000 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU7, DQ1) ADDR=0x2005f0000 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200420d10 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2004a0d10 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU4) ADDR=0x200520d10 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200460d10 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU5) ADDR=0x200560d10 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2004e0d10 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU6) ADDR=0x2005a0d10 DWORD=0 NUMREGS=0 */ + 0x2005e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU7) ADDR=0x2005e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU7) ADDR=0x2005e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU7) ADDR=0x2005e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU7) ADDR=0x2005e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU7) ADDR=0x2005e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU7) ADDR=0x2005e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU7) ADDR=0x2005e0d0c DWORD=0 NUMREGS=0 */ + 0x200420d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200420d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200420d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200420d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200420d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200420d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200420d0c DWORD=0 NUMREGS=0 */ + 0x2004a0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2004a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2004a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2004a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2004a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2004a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2004a0d0c DWORD=0 NUMREGS=0 */ + 0x200520d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU4) ADDR=0x200520d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU4) ADDR=0x200520d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU4) ADDR=0x200520d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU4) ADDR=0x200520d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU4) ADDR=0x200520d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU4) ADDR=0x200520d0c DWORD=0 NUMREGS=0 */ + 0x200460d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200460d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200460d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200460d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200460d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200460d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200460d0c DWORD=0 NUMREGS=0 */ + 0x200560d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU5) ADDR=0x200560d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU5) ADDR=0x200560d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU5) ADDR=0x200560d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU5) ADDR=0x200560d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU5) ADDR=0x200560d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU5) ADDR=0x200560d0c DWORD=0 NUMREGS=0 */ + 0x2004e0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2004e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2004e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2004e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2004e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2004e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2004e0d0c DWORD=0 NUMREGS=0 */ + 0x2005a0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU6) ADDR=0x2005a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU6) ADDR=0x2005a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU6) ADDR=0x2005a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU6) ADDR=0x2005a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU6) ADDR=0x2005a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU6) ADDR=0x2005a0d0c DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x20052881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ0) ADDR=0x200528b00 DWORD=0 NUMREGS=0 */ + 0x20053081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ1) ADDR=0x200530b00 DWORD=0 NUMREGS=0 */ + 0x20056881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ0) ADDR=0x200568b00 DWORD=0 NUMREGS=0 */ + 0x20057081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ1) ADDR=0x200570b00 DWORD=0 NUMREGS=0 */ + 0x2005a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ0) ADDR=0x2005a8b00 DWORD=0 NUMREGS=0 */ + 0x2005b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ1) ADDR=0x2005b0b00 DWORD=0 NUMREGS=0 */ + 0x2005e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ0) ADDR=0x2005e8b00 DWORD=0 NUMREGS=0 */ + 0x2005f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ1) ADDR=0x2005f0b00 DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x20052881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ0) ADDR=0x200528b04 DWORD=0 NUMREGS=0 */ + 0x20053081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ1) ADDR=0x200530b04 DWORD=0 NUMREGS=0 */ + 0x20056881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ0) ADDR=0x200568b04 DWORD=0 NUMREGS=0 */ + 0x20057081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ1) ADDR=0x200570b04 DWORD=0 NUMREGS=0 */ + 0x2005a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ0) ADDR=0x2005a8b04 DWORD=0 NUMREGS=0 */ + 0x2005b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ1) ADDR=0x2005b0b04 DWORD=0 NUMREGS=0 */ + 0x2005e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ0) ADDR=0x2005e8b04 DWORD=0 NUMREGS=0 */ + 0x2005f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ1) ADDR=0x2005f0b04 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200420718 DWORD=0 NUMREGS=0 */ + 0x2005a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU6) ADDR=0x2005a0718 DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2004e0718 DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200460718 DWORD=0 NUMREGS=0 */ + 0x20056041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU5) ADDR=0x200560718 DWORD=0 NUMREGS=0 */ + 0x20052041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU4) ADDR=0x200520718 DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2004a0718 DWORD=0 NUMREGS=0 */ + 0x2005e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU7) ADDR=0x2005e0718 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20042861c DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20043061c DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20046861c DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20047061c DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2004a861c DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2004b061c DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2004e861c DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2004f061c DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU4, DQ0) ADDR=0x20052861c DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU4, DQ1) ADDR=0x20053061c DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU5, DQ0) ADDR=0x20056861c DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU5, DQ1) ADDR=0x20057061c DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU6, DQ0) ADDR=0x2005a861c DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU6, DQ1) ADDR=0x2005b061c DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU7, DQ0) ADDR=0x2005e861c DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU7, DQ1) ADDR=0x2005f061c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ0) ADDR=0x200528608 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ1) ADDR=0x200530608 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ0) ADDR=0x200568608 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ1) ADDR=0x200570608 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ0) ADDR=0x2005a8608 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ1) ADDR=0x2005b0608 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ0) ADDR=0x2005e8608 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ1) ADDR=0x2005f0608 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ0) ADDR=0x200528608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20053042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ1) ADDR=0x200530608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ0) ADDR=0x200568608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20057042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ1) ADDR=0x200570608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ0) ADDR=0x2005a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ1) ADDR=0x2005b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ0) ADDR=0x2005e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ1) ADDR=0x2005f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ0) ADDR=0x200528608 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ1) ADDR=0x200530608 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ0) ADDR=0x200568608 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ1) ADDR=0x200570608 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ0) ADDR=0x2005a8608 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ1) ADDR=0x2005b0608 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ0) ADDR=0x2005e8608 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ1) ADDR=0x2005f0608 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20053042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20057042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 NUMREGS=0 */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20056081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x20052081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 NUMREGS=0 */ + 0x2005a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2005e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 NUMREGS=0 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x20056081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 NUMREGS=0 */ + 0x2005e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x2005a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 NUMREGS=0 */ + 0x20052081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU4) ADDR=0x200520198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU6) ADDR=0x2005a0198 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU5) ADDR=0x200560198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU7) ADDR=0x2005e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ0) ADDR=0x200528198 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ1) ADDR=0x200530198 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ0) ADDR=0x200568198 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ1) ADDR=0x200570198 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ0) ADDR=0x2005a8198 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ1) ADDR=0x2005b0198 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ0) ADDR=0x2005e8198 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ1) ADDR=0x2005f0198 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200420f80 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2004a0f80 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU4) ADDR=0x200520f80 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200460f80 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU5) ADDR=0x200560f80 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2004e0f80 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU6) ADDR=0x2005a0f80 DWORD=0 NUMREGS=0 */ + 0x2005e0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU7) ADDR=0x2005e0f80 DWORD=0 NUMREGS=0 */ + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU7) ADDR=0x2005e0f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU7) ADDR=0x2005e0f88 DWORD=0 NUMREGS=0 */ + 0x200420c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200420f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200420f88 DWORD=0 NUMREGS=0 */ + 0x2004a0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2004a0f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2004a0f88 DWORD=0 NUMREGS=0 */ + 0x200520c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU4) ADDR=0x200520f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU4) ADDR=0x200520f88 DWORD=0 NUMREGS=0 */ + 0x200460c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200460f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200460f88 DWORD=0 NUMREGS=0 */ + 0x200560c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU5) ADDR=0x200560f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU5) ADDR=0x200560f88 DWORD=0 NUMREGS=0 */ + 0x2004e0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2004e0f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2004e0f88 DWORD=0 NUMREGS=0 */ + 0x2005a0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000710, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU6) ADDR=0x2005a0f84 DWORD=0 NUMREGS=0 */ + 0x04000510, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU6) ADDR=0x2005a0f88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200428d80 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200430d80 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200468d80 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200470d80 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2004a8d80 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2004b0d80 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2004e8d80 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2004f0d80 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU4, DQ0) ADDR=0x200528d80 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU4, DQ1) ADDR=0x200530d80 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU5, DQ0) ADDR=0x200568d80 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU5, DQ1) ADDR=0x200570d80 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU6, DQ0) ADDR=0x2005a8d80 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU6, DQ1) ADDR=0x2005b0d80 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU7, DQ0) ADDR=0x2005e8d80 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020704, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU7, DQ1) ADDR=0x2005f0d80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200428d84 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200430d84 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200468d84 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200470d84 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2004a8d84 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2004b0d84 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2004e8d84 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2004f0d84 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU4, DQ0) ADDR=0x200528d84 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU4, DQ1) ADDR=0x200530d84 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU5, DQ0) ADDR=0x200568d84 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU5, DQ1) ADDR=0x200570d84 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU6, DQ0) ADDR=0x2005a8d84 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU6, DQ1) ADDR=0x2005b0d84 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU7, DQ0) ADDR=0x2005e8d84 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU7, DQ1) ADDR=0x2005f0d84 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200428d88 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200430d88 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200468d88 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200470d88 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2004a8d88 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2004b0d88 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2004e8d88 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2004f0d88 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU4, DQ0) ADDR=0x200528d88 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU4, DQ1) ADDR=0x200530d88 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU5, DQ0) ADDR=0x200568d88 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU5, DQ1) ADDR=0x200570d88 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU6, DQ0) ADDR=0x2005a8d88 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU6, DQ1) ADDR=0x2005b0d88 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU7, DQ0) ADDR=0x2005e8d88 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020702, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU7, DQ1) ADDR=0x2005f0d88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200428d8c DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200430d8c DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200468d8c DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200470d8c DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2004a8d8c DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2004b0d8c DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2004e8d8c DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2004f0d8c DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU4, DQ0) ADDR=0x200528d8c DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU4, DQ1) ADDR=0x200530d8c DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU5, DQ0) ADDR=0x200568d8c DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU5, DQ1) ADDR=0x200570d8c DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU6, DQ0) ADDR=0x2005a8d8c DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU6, DQ1) ADDR=0x2005b0d8c DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU7, DQ0) ADDR=0x2005e8d8c DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020504, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU7, DQ1) ADDR=0x2005f0d8c DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU0) ADDR=0x200420f90 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU2) ADDR=0x2004a0f90 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU4) ADDR=0x200520f90 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU1) ADDR=0x200460f90 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU5) ADDR=0x200560f90 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU3) ADDR=0x2004e0f90 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU6) ADDR=0x2005a0f90 DWORD=0 NUMREGS=0 */ + 0x2005e0c1, //compressed WR cmd + 0x000000e4, //compressed WR offset + 0x00000019, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_RDDQCAL2(MCU7) ADDR=0x2005e0f90 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2004281cc DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2004301cc DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2004681cc DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2004701cc DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2004a81cc DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2004b01cc DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2004e81cc DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2004f01cc DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU4, DQ0) ADDR=0x2005281cc DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU4, DQ1) ADDR=0x2005301cc DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU5, DQ0) ADDR=0x2005681cc DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU5, DQ1) ADDR=0x2005701cc DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU6, DQ0) ADDR=0x2005a81cc DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU6, DQ1) ADDR=0x2005b01cc DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU7, DQ0) ADDR=0x2005e81cc DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU7, DQ1) ADDR=0x2005f01cc DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200420e00 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2004a0e00 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU4) ADDR=0x200520e00 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200460e00 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU5) ADDR=0x200560e00 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2004e0e00 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU6) ADDR=0x2005a0e00 DWORD=0 NUMREGS=0 */ + 0x2005e0fd, //compressed WR cmd + 0x86828180, //compressed WR offset + 0x8b8a8983, //compressed WR offset + 0xaaa9a88c, //compressed WR offset + 0x8f8eacab, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU7) ADDR=0x2005e0e00 DWORD=0 NUMREGS=0 */ + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU7) ADDR=0x2005e0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU7) ADDR=0x2005e0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU7) ADDR=0x2005e0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU7) ADDR=0x2005e0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU7) ADDR=0x2005e0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU7) ADDR=0x2005e0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU7) ADDR=0x2005e0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU7) ADDR=0x2005e0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU7) ADDR=0x2005e0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU7) ADDR=0x2005e0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU7) ADDR=0x2005e0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU7) ADDR=0x2005e0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU7) ADDR=0x2005e0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU7) ADDR=0x2005e0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU7) ADDR=0x2005e0e3c DWORD=0 NUMREGS=0 */ + 0x2005e0cd, //compressed WR cmd + 0xa09f9190, //compressed WR offset + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU7) ADDR=0x2005e0e40 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU7) ADDR=0x2005e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU7) ADDR=0x2005e0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU7) ADDR=0x2005e0e80 DWORD=0 NUMREGS=0 */ + 0x200420fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200420e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200420e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU0) ADDR=0x200420e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200420e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200420e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200420e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200420e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200420e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU0) ADDR=0x200420ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU0) ADDR=0x200420ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU0) ADDR=0x200420ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU0) ADDR=0x200420eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU0) ADDR=0x200420eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200420e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200420e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200420e40 DWORD=0 NUMREGS=0 */ + 0x200420c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200420e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e80 DWORD=0 NUMREGS=0 */ + 0x2004a0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2004a0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2004a0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU2) ADDR=0x2004a0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2004a0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2004a0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2004a0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU2) ADDR=0x2004a0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU2) ADDR=0x2004a0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU2) ADDR=0x2004a0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU2) ADDR=0x2004a0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU2) ADDR=0x2004a0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e40 DWORD=0 NUMREGS=0 */ + 0x2004a0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e80 DWORD=0 NUMREGS=0 */ + 0x200520fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU4) ADDR=0x200520e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU4) ADDR=0x200520e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU4) ADDR=0x200520e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU4) ADDR=0x200520e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU4) ADDR=0x200520e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU4) ADDR=0x200520e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU4) ADDR=0x200520e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU4) ADDR=0x200520e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU4) ADDR=0x200520ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU4) ADDR=0x200520ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU4) ADDR=0x200520ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU4) ADDR=0x200520eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU4) ADDR=0x200520eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU4) ADDR=0x200520e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU4) ADDR=0x200520e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU4) ADDR=0x200520e40 DWORD=0 NUMREGS=0 */ + 0x200520c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU4) ADDR=0x200520e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU4) ADDR=0x200520e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU4) ADDR=0x200520e80 DWORD=0 NUMREGS=0 */ + 0x200460fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200460e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200460e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU1) ADDR=0x200460e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200460e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200460e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200460e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200460e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200460e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU1) ADDR=0x200460ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU1) ADDR=0x200460ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU1) ADDR=0x200460ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU1) ADDR=0x200460eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU1) ADDR=0x200460eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200460e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200460e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200460e40 DWORD=0 NUMREGS=0 */ + 0x200460c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200460e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e80 DWORD=0 NUMREGS=0 */ + 0x200560fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU5) ADDR=0x200560e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU5) ADDR=0x200560e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU5) ADDR=0x200560e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU5) ADDR=0x200560e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU5) ADDR=0x200560e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU5) ADDR=0x200560e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU5) ADDR=0x200560e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU5) ADDR=0x200560e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU5) ADDR=0x200560ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU5) ADDR=0x200560ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU5) ADDR=0x200560ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU5) ADDR=0x200560eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU5) ADDR=0x200560eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU5) ADDR=0x200560e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU5) ADDR=0x200560e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU5) ADDR=0x200560e40 DWORD=0 NUMREGS=0 */ + 0x200560c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU5) ADDR=0x200560e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU5) ADDR=0x200560e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU5) ADDR=0x200560e80 DWORD=0 NUMREGS=0 */ + 0x2004e0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2004e0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2004e0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU3) ADDR=0x2004e0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2004e0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2004e0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2004e0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU3) ADDR=0x2004e0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU3) ADDR=0x2004e0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU3) ADDR=0x2004e0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU3) ADDR=0x2004e0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU3) ADDR=0x2004e0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e40 DWORD=0 NUMREGS=0 */ + 0x2004e0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e80 DWORD=0 NUMREGS=0 */ + 0x2005a0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x00040008, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU6) ADDR=0x2005a0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU6) ADDR=0x2005a0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU6) ADDR=0x2005a0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU6) ADDR=0x2005a0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU6) ADDR=0x2005a0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU6) ADDR=0x2005a0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU6) ADDR=0x2005a0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU6) ADDR=0x2005a0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU6) ADDR=0x2005a0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU6) ADDR=0x2005a0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU6) ADDR=0x2005a0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU6) ADDR=0x2005a0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU6) ADDR=0x2005a0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU6) ADDR=0x2005a0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU6) ADDR=0x2005a0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU6) ADDR=0x2005a0e40 DWORD=0 NUMREGS=0 */ + 0x2005a0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU6) ADDR=0x2005a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU6) ADDR=0x2005a0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU6) ADDR=0x2005a0e80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200428d00 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200430d00 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200468d00 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200470d00 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2004a8d00 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2004b0d00 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2004e8d00 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2004f0d00 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU4, DQ0) ADDR=0x200528d00 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU4, DQ1) ADDR=0x200530d00 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU5, DQ0) ADDR=0x200568d00 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU5, DQ1) ADDR=0x200570d00 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU6, DQ0) ADDR=0x2005a8d00 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU6, DQ1) ADDR=0x2005b0d00 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU7, DQ0) ADDR=0x2005e8d00 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU7, DQ1) ADDR=0x2005f0d00 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200428100 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200430100 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200468100 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200470100 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2004a8100 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2004b0100 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2004e8100 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2004f0100 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU4, DQ0) ADDR=0x200528100 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU4, DQ1) ADDR=0x200530100 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU5, DQ0) ADDR=0x200568100 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU5, DQ1) ADDR=0x200570100 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU6, DQ0) ADDR=0x2005a8100 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU6, DQ1) ADDR=0x2005b0100 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU7, DQ0) ADDR=0x2005e8100 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU7, DQ1) ADDR=0x2005f0100 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200428104 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200430104 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200468104 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200470104 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2004a8104 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2004b0104 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2004e8104 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2004f0104 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU4, DQ0) ADDR=0x200528104 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU4, DQ1) ADDR=0x200530104 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU5, DQ0) ADDR=0x200568104 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU5, DQ1) ADDR=0x200570104 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU6, DQ0) ADDR=0x2005a8104 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU6, DQ1) ADDR=0x2005b0104 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU7, DQ0) ADDR=0x2005e8104 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU7, DQ1) ADDR=0x2005f0104 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200428108 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200430108 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200468108 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200470108 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2004a8108 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2004b0108 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2004e8108 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2004f0108 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU4, DQ0) ADDR=0x200528108 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU4, DQ1) ADDR=0x200530108 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU5, DQ0) ADDR=0x200568108 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU5, DQ1) ADDR=0x200570108 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU6, DQ0) ADDR=0x2005a8108 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU6, DQ1) ADDR=0x2005b0108 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU7, DQ0) ADDR=0x2005e8108 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU7, DQ1) ADDR=0x2005f0108 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20042810c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20043010c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20046810c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20047010c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2004a810c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2004b010c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2004e810c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2004f010c DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU4, DQ0) ADDR=0x20052810c DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU4, DQ1) ADDR=0x20053010c DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU5, DQ0) ADDR=0x20056810c DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU5, DQ1) ADDR=0x20057010c DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU6, DQ0) ADDR=0x2005a810c DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU6, DQ1) ADDR=0x2005b010c DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU7, DQ0) ADDR=0x2005e810c DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU7, DQ1) ADDR=0x2005f010c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU4) ADDR=0x2005201a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU6) ADDR=0x2005a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU5) ADDR=0x2005601a4 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU7) ADDR=0x2005e01a4 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ0) ADDR=0x2005281a4 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ1) ADDR=0x2005301a4 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ0) ADDR=0x2005681a4 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ1) ADDR=0x2005701a4 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ0) ADDR=0x2005a81a4 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ1) ADDR=0x2005b01a4 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ0) ADDR=0x2005e81a4 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ1) ADDR=0x2005f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2004201a0 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU4) ADDR=0x2005201a0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2004a01a0 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU6) ADDR=0x2005a01a0 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2004e01a0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2004601a0 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU5) ADDR=0x2005601a0 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU7) ADDR=0x2005e01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2004281a0 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2004301a0 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2004681a0 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2004701a0 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2004a81a0 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2004b01a0 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2004e81a0 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2004f01a0 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU4, DQ0) ADDR=0x2005281a0 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU4, DQ1) ADDR=0x2005301a0 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU5, DQ0) ADDR=0x2005681a0 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU5, DQ1) ADDR=0x2005701a0 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU6, DQ0) ADDR=0x2005a81a0 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU6, DQ1) ADDR=0x2005b01a0 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU7, DQ0) ADDR=0x2005e81a0 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU7, DQ1) ADDR=0x2005f01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200428180 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200430180 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200468180 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200470180 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2004a8180 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2004b0180 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2004e8180 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2004f0180 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU4, DQ0) ADDR=0x200528180 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU4, DQ1) ADDR=0x200530180 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU5, DQ0) ADDR=0x200568180 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU5, DQ1) ADDR=0x200570180 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU6, DQ0) ADDR=0x2005a8180 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU6, DQ1) ADDR=0x2005b0180 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU7, DQ0) ADDR=0x2005e8180 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU7, DQ1) ADDR=0x2005f0180 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU0) ADDR=0x2004200dc DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU4) ADDR=0x2005200dc DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU2) ADDR=0x2004a00dc DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU6) ADDR=0x2005a00dc DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU3) ADDR=0x2004e00dc DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU1) ADDR=0x2004600dc DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU5) ADDR=0x2005600dc DWORD=0 NUMREGS=0 */ + 0x2005e005, //compressed WR cmd + 0x00003837, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU7) ADDR=0x2005e00dc DWORD=0 NUMREGS=0 */ + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU7) ADDR=0x2005e00e0 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU0) ADDR=0x2004200e0 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU4) ADDR=0x2005200e0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU2) ADDR=0x2004a00e0 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU6) ADDR=0x2005a00e0 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU3) ADDR=0x2004e00e0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU1) ADDR=0x2004600e0 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU5) ADDR=0x2005600e0 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU0) ADDR=0x200420ecc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU1) ADDR=0x200460ecc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU2) ADDR=0x2004a0ecc DWORD=0 NUMREGS=0 */ + 0x2005e0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU7) ADDR=0x2005e0ecc DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU4) ADDR=0x200520ecc DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU3) ADDR=0x2004e0ecc DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU5) ADDR=0x200560ecc DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU6) ADDR=0x2005a0ecc DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU0) ADDR=0x200438030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU0) ADDR=0x200438028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU0) ADDR=0x200438044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU0) ADDR=0x200438058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU0) ADDR=0x200438068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU0) ADDR=0x200438050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU0) ADDR=0x200438060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU0) ADDR=0x200438078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU0) ADDR=0x200438080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU0) ADDR=0x2004380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2004380b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU0) ADDR=0x2004380b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU0) ADDR=0x2004380e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU0) ADDR=0x200438120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU0) ADDR=0x2004380f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU0) ADDR=0x20043810c DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20043811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU0) ADDR=0x2004380c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU0) ADDR=0x2004380d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2004380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU0) ADDR=0x2004380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU0) ADDR=0x2004380e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU0) ADDR=0x200438130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU0) ADDR=0x200438140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200438148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU0) ADDR=0x200438150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU0) ADDR=0x20043814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU0) ADDR=0x200438024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU0) ADDR=0x20043800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU0) ADDR=0x200438008 DWORD=0 NUMREGS=0 */ + 0x20043801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2004382fc DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU1) ADDR=0x200478030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU1) ADDR=0x200478028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU1) ADDR=0x200478044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU1) ADDR=0x200478058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU1) ADDR=0x200478068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU1) ADDR=0x200478050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU1) ADDR=0x200478060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU1) ADDR=0x200478078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU1) ADDR=0x200478080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU1) ADDR=0x2004780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2004780b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU1) ADDR=0x2004780b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU1) ADDR=0x2004780e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU1) ADDR=0x200478120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU1) ADDR=0x2004780f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU1) ADDR=0x20047810c DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20047811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU1) ADDR=0x2004780c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU1) ADDR=0x2004780d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2004780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU1) ADDR=0x2004780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU1) ADDR=0x2004780e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU1) ADDR=0x200478130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU1) ADDR=0x200478140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200478148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU1) ADDR=0x200478150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU1) ADDR=0x20047814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU1) ADDR=0x200478024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU1) ADDR=0x20047800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU1) ADDR=0x200478008 DWORD=0 NUMREGS=0 */ + 0x20047801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2004782fc DWORD=0 NUMREGS=0 */ + 0x2005b83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU6) ADDR=0x2005b8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU6) ADDR=0x2005b8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU6) ADDR=0x2005b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU6) ADDR=0x2005b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU6) ADDR=0x2005b8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU6) ADDR=0x2005b8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU6) ADDR=0x2005b8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU6) ADDR=0x2005b8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU6) ADDR=0x2005b8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU6) ADDR=0x2005b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU6) ADDR=0x2005b80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU6) ADDR=0x2005b80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU6) ADDR=0x2005b80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU6) ADDR=0x2005b8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU6) ADDR=0x2005b80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU6) ADDR=0x2005b810c DWORD=0 NUMREGS=0 */ + 0x2005b83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU6) ADDR=0x2005b811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU6) ADDR=0x2005b80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU6) ADDR=0x2005b80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU6) ADDR=0x2005b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU6) ADDR=0x2005b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU6) ADDR=0x2005b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU6) ADDR=0x2005b80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU6) ADDR=0x2005b8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU6) ADDR=0x2005b8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU6) ADDR=0x2005b8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU6) ADDR=0x2005b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU6) ADDR=0x2005b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU6) ADDR=0x2005b814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU6) ADDR=0x2005b8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU6) ADDR=0x2005b800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU6) ADDR=0x2005b8008 DWORD=0 NUMREGS=0 */ + 0x2005b801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU6) ADDR=0x2005b82fc DWORD=0 NUMREGS=0 */ + 0x2005783d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU5) ADDR=0x200578030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU5) ADDR=0x200578028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU5) ADDR=0x200578044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU5) ADDR=0x200578058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU5) ADDR=0x200578068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU5) ADDR=0x200578050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU5) ADDR=0x200578060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU5) ADDR=0x200578078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU5) ADDR=0x200578080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU5) ADDR=0x2005780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU5) ADDR=0x2005780b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU5) ADDR=0x2005780b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU5) ADDR=0x2005780e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU5) ADDR=0x200578120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU5) ADDR=0x2005780f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU5) ADDR=0x20057810c DWORD=0 NUMREGS=0 */ + 0x2005783d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU5) ADDR=0x20057811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU5) ADDR=0x2005780c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU5) ADDR=0x2005780c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU5) ADDR=0x2005780d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU5) ADDR=0x2005780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU5) ADDR=0x2005780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU5) ADDR=0x2005780e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU5) ADDR=0x200578138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU5) ADDR=0x200578130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU5) ADDR=0x200578140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU5) ADDR=0x200578148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU5) ADDR=0x200578150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU5) ADDR=0x20057814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU5) ADDR=0x200578024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU5) ADDR=0x20057800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU5) ADDR=0x200578008 DWORD=0 NUMREGS=0 */ + 0x20057801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU5) ADDR=0x2005782fc DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU2) ADDR=0x2004b8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU2) ADDR=0x2004b8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU2) ADDR=0x2004b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU2) ADDR=0x2004b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU2) ADDR=0x2004b8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU2) ADDR=0x2004b8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU2) ADDR=0x2004b8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU2) ADDR=0x2004b8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU2) ADDR=0x2004b8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU2) ADDR=0x2004b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2004b80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU2) ADDR=0x2004b80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU2) ADDR=0x2004b80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU2) ADDR=0x2004b8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU2) ADDR=0x2004b80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU2) ADDR=0x2004b810c DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2004b811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU2) ADDR=0x2004b80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU2) ADDR=0x2004b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2004b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU2) ADDR=0x2004b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU2) ADDR=0x2004b80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU2) ADDR=0x2004b8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU2) ADDR=0x2004b8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2004b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU2) ADDR=0x2004b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU2) ADDR=0x2004b814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU2) ADDR=0x2004b8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU2) ADDR=0x2004b800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU2) ADDR=0x2004b8008 DWORD=0 NUMREGS=0 */ + 0x2004b801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2004b82fc DWORD=0 NUMREGS=0 */ + 0x2005383d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU4) ADDR=0x200538030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU4) ADDR=0x200538028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU4) ADDR=0x200538044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU4) ADDR=0x200538058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU4) ADDR=0x200538068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU4) ADDR=0x200538050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU4) ADDR=0x200538060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU4) ADDR=0x200538078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU4) ADDR=0x200538080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU4) ADDR=0x2005380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU4) ADDR=0x2005380b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU4) ADDR=0x2005380b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU4) ADDR=0x2005380e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU4) ADDR=0x200538120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU4) ADDR=0x2005380f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU4) ADDR=0x20053810c DWORD=0 NUMREGS=0 */ + 0x2005383d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU4) ADDR=0x20053811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU4) ADDR=0x2005380c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU4) ADDR=0x2005380c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU4) ADDR=0x2005380d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU4) ADDR=0x2005380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU4) ADDR=0x2005380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU4) ADDR=0x2005380e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU4) ADDR=0x200538138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU4) ADDR=0x200538130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU4) ADDR=0x200538140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU4) ADDR=0x200538148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU4) ADDR=0x200538150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU4) ADDR=0x20053814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU4) ADDR=0x200538024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU4) ADDR=0x20053800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU4) ADDR=0x200538008 DWORD=0 NUMREGS=0 */ + 0x20053801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU4) ADDR=0x2005382fc DWORD=0 NUMREGS=0 */ + 0x2005f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU7) ADDR=0x2005f8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU7) ADDR=0x2005f8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU7) ADDR=0x2005f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU7) ADDR=0x2005f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU7) ADDR=0x2005f8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU7) ADDR=0x2005f8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU7) ADDR=0x2005f8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU7) ADDR=0x2005f8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU7) ADDR=0x2005f8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU7) ADDR=0x2005f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU7) ADDR=0x2005f80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU7) ADDR=0x2005f80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU7) ADDR=0x2005f80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU7) ADDR=0x2005f8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU7) ADDR=0x2005f80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU7) ADDR=0x2005f810c DWORD=0 NUMREGS=0 */ + 0x2005f83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU7) ADDR=0x2005f811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU7) ADDR=0x2005f80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU7) ADDR=0x2005f80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU7) ADDR=0x2005f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU7) ADDR=0x2005f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU7) ADDR=0x2005f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU7) ADDR=0x2005f80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU7) ADDR=0x2005f8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU7) ADDR=0x2005f8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU7) ADDR=0x2005f8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU7) ADDR=0x2005f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU7) ADDR=0x2005f8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU7) ADDR=0x2005f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU7) ADDR=0x2005f8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU7) ADDR=0x2005f800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU7) ADDR=0x2005f8008 DWORD=0 NUMREGS=0 */ + 0x2005f801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU7) ADDR=0x2005f82fc DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU3) ADDR=0x2004f8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU3) ADDR=0x2004f8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU3) ADDR=0x2004f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU3) ADDR=0x2004f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU3) ADDR=0x2004f8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU3) ADDR=0x2004f8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU3) ADDR=0x2004f8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU3) ADDR=0x2004f8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU3) ADDR=0x2004f8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU3) ADDR=0x2004f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2004f80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU3) ADDR=0x2004f80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU3) ADDR=0x2004f80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU3) ADDR=0x2004f8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU3) ADDR=0x2004f80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU3) ADDR=0x2004f810c DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2004f811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU3) ADDR=0x2004f80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU3) ADDR=0x2004f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2004f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU3) ADDR=0x2004f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU3) ADDR=0x2004f80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU3) ADDR=0x2004f8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU3) ADDR=0x2004f8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2004f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU3) ADDR=0x2004f8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU3) ADDR=0x2004f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU3) ADDR=0x2004f8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU3) ADDR=0x2004f800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU3) ADDR=0x2004f8008 DWORD=0 NUMREGS=0 */ + 0x2004f801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000816, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2004f82fc DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200420008 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200460008 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU4) ADDR=0x200520008 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2004a0008 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU6) ADDR=0x2005a0008 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU5) ADDR=0x200560008 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2004e0008 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU7) ADDR=0x2005e0008 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200428008 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200430008 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200468008 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200470008 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2004a8008 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2004b0008 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2004e8008 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2004f0008 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU4, DQ0) ADDR=0x200528008 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU4, DQ1) ADDR=0x200530008 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU5, DQ0) ADDR=0x200568008 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU5, DQ1) ADDR=0x200570008 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU6, DQ0) ADDR=0x2005a8008 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU6, DQ1) ADDR=0x2005b0008 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU7, DQ0) ADDR=0x2005e8008 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU7, DQ1) ADDR=0x2005f0008 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200420e74 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2004a0e74 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU4) ADDR=0x200520e74 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200460e74 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU5) ADDR=0x200560e74 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2004e0e74 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU6) ADDR=0x2005a0e74 DWORD=0 NUMREGS=0 */ + 0x2005e0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06001604, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU7) ADDR=0x2005e0e74 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200428d80 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200430d80 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200468d80 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200470d80 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2004a8d80 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2004b0d80 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2004e8d80 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2004f0d80 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU4, DQ0) ADDR=0x200528d80 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU4, DQ1) ADDR=0x200530d80 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU5, DQ0) ADDR=0x200568d80 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU5, DQ1) ADDR=0x200570d80 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU6, DQ0) ADDR=0x2005a8d80 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU6, DQ1) ADDR=0x2005b0d80 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU7, DQ0) ADDR=0x2005e8d80 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06021604, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU7, DQ1) ADDR=0x2005f0d80 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU0) ADDR=0x200420edc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU2) ADDR=0x2004a0edc DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU4) ADDR=0x200520edc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU1) ADDR=0x200460edc DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU5) ADDR=0x200560edc DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU3) ADDR=0x2004e0edc DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU6) ADDR=0x2005a0edc DWORD=0 NUMREGS=0 */ + 0x2005e0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU7) ADDR=0x2005e0edc DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU6) ADDR=0x200580418 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU4) ADDR=0x200500418 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU5) ADDR=0x200540418 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU7) ADDR=0x2005c0418 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU4) ADDR=0x2005003bc DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU6) ADDR=0x2005803bc DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU5) ADDR=0x2005403bc DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000ef, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x2005c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU7) ADDR=0x2005c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU7) ADDR=0x2005c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU7) ADDR=0x2005c03b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU7) ADDR=0x2005c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU7) ADDR=0x2005c03fc DWORD=0 NUMREGS=0 */ + 0x2004000d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x2005000d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU4) ADDR=0x2005003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU4) ADDR=0x2005003b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU4) ADDR=0x2005003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU4) ADDR=0x2005003fc DWORD=0 NUMREGS=0 */ + 0x2005800d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU6) ADDR=0x2005803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU6) ADDR=0x2005803b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU6) ADDR=0x2005803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU6) ADDR=0x2005803fc DWORD=0 NUMREGS=0 */ + 0x2004c00d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x2004400d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x2005400d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU5) ADDR=0x2005403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU5) ADDR=0x2005403b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU5) ADDR=0x2005403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU5) ADDR=0x2005403fc DWORD=0 NUMREGS=0 */ + 0x2004800d, //compressed WR cmd + 0xffecedee, //compressed WR offset + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x20040049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20040041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20044041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2004c041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20050049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU4) ADDR=0x20050041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU4) ADDR=0x20050043c DWORD=0 NUMREGS=0 */ + 0x2005c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU7) ADDR=0x2005c041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU7) ADDR=0x2005c043c DWORD=0 NUMREGS=0 */ + 0x20048049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20048041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x20054049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU5) ADDR=0x20054041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU5) ADDR=0x20054043c DWORD=0 NUMREGS=0 */ + 0x20058049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU6) ADDR=0x20058041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU6) ADDR=0x20058043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU4) ADDR=0x200500000 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU6) ADDR=0x200580000 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU5) ADDR=0x200540000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU7) ADDR=0x2005c0000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU4) ADDR=0x200520094 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU6) ADDR=0x2005a0094 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU5) ADDR=0x200560094 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU7) ADDR=0x2005e0094 DWORD=0 NUMREGS=0 */ + 0x20042002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU4) ADDR=0x200520094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU5) ADDR=0x200560094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU6) ADDR=0x2005a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU7) ADDR=0x2005e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200400414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200400410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20040040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200400408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200440414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200440410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20044040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200440408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2004c0414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2004c0410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2004c040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2004c0408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20050051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU4) ADDR=0x200500414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU4) ADDR=0x200500410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU4) ADDR=0x20050040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU4) ADDR=0x200500408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 NUMREGS=0 */ + 0x2005c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU7) ADDR=0x2005c0414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU7) ADDR=0x2005c0410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU7) ADDR=0x2005c040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU7) ADDR=0x2005c0408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200480414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200480410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20048040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200480408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20054051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU5) ADDR=0x200540414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU5) ADDR=0x200540410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU5) ADDR=0x20054040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU5) ADDR=0x200540408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 NUMREGS=0 */ + 0x20058051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU6) ADDR=0x200580414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU6) ADDR=0x200580410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU6) ADDR=0x20058040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU6) ADDR=0x200580408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20050042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20054042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20058042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20040045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU4) ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU4), ISSUE COMMAND ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU7) ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU7), ISSUE COMMAND ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20054045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU5) ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU5), ISSUE COMMAND ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20058045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU6) ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU6), ISSUE COMMAND ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20050042, /* POLL:initCmdAndWait(MCU4), POLL COMMAND DONE ADDR=0x200500500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20054042, /* POLL:initCmdAndWait(MCU5), POLL COMMAND DONE ADDR=0x200540500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20058042, /* POLL:initCmdAndWait(MCU6), POLL COMMAND DONE ADDR=0x200580500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005c042, /* POLL:initCmdAndWait(MCU7), POLL COMMAND DONE ADDR=0x2005c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000011, //compressed WR offset + 0x000000ff, /* WR:GLBTIMER_GLBTIMER_CHEN(GLBTIMER) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU4) ADDR=0x200500000 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU6) ADDR=0x200580000 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU5) ADDR=0x200540000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU7) ADDR=0x2005c0000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00051004, /* DELAY for 27 uS (5184 clock cycles) */ + 0x20043809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2004382fc DWORD=0 NUMREGS=0 */ + 0x20047809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2004782fc DWORD=0 NUMREGS=0 */ + 0x2005b809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU6) ADDR=0x2005b80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU6) ADDR=0x2005b8138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU6) ADDR=0x2005b82fc DWORD=0 NUMREGS=0 */ + 0x20057809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU5) ADDR=0x2005780c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU5) ADDR=0x200578138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU5) ADDR=0x2005782fc DWORD=0 NUMREGS=0 */ + 0x2004b809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2004b82fc DWORD=0 NUMREGS=0 */ + 0x20053809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU4) ADDR=0x2005380c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU4) ADDR=0x200538138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU4) ADDR=0x2005382fc DWORD=0 NUMREGS=0 */ + 0x2005f809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU7) ADDR=0x2005f80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU7) ADDR=0x2005f8138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU7) ADDR=0x2005f82fc DWORD=0 NUMREGS=0 */ + 0x2004f809, //compressed WR cmd + 0x00bf4e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x00000c16, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2004f82fc DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200420cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x200460cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x2004a0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x2005e0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU7) ADDR=0x2005e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU7) ADDR=0x2005e0e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ee8 DWORD=0 NUMREGS=0 */ + 0x200520cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU4) ADDR=0x200520e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU4) ADDR=0x200520e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU4) ADDR=0x200520ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU4) ADDR=0x200520ee8 DWORD=0 NUMREGS=0 */ + 0x2004e0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x200560cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU5) ADDR=0x200560e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU5) ADDR=0x200560e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU5) ADDR=0x200560ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU5) ADDR=0x200560ee8 DWORD=0 NUMREGS=0 */ + 0x2005a0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU6) ADDR=0x2005a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU6) ADDR=0x2005a0e34 DWORD=0 NUMREGS=0 */ + 0x01d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ee8 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20050045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU4) ADDR=0x200500418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x2005c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU7) ADDR=0x2005c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20054045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU5) ADDR=0x200540418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x20058045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU6) ADDR=0x200580418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU4) ADDR=0x200500198 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU6) ADDR=0x200580198 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU5) ADDR=0x200540198 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU7) ADDR=0x2005c0198 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x20043805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU0) ADDR=0x20043809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU0) ADDR=0x200438098 DWORD=0 NUMREGS=0 */ + 0x20047805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU1) ADDR=0x20047809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU1) ADDR=0x200478098 DWORD=0 NUMREGS=0 */ + 0x2005b805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU6) ADDR=0x2005b809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU6) ADDR=0x2005b8098 DWORD=0 NUMREGS=0 */ + 0x20057805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU5) ADDR=0x20057809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU5) ADDR=0x200578098 DWORD=0 NUMREGS=0 */ + 0x2004b805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU2) ADDR=0x2004b809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU2) ADDR=0x2004b8098 DWORD=0 NUMREGS=0 */ + 0x20053805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU4) ADDR=0x20053809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU4) ADDR=0x200538098 DWORD=0 NUMREGS=0 */ + 0x2005f805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU7) ADDR=0x2005f809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU7) ADDR=0x2005f8098 DWORD=0 NUMREGS=0 */ + 0x2004f805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU3) ADDR=0x2004f809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU3) ADDR=0x2004f8098 DWORD=0 NUMREGS=0 */ + 0x20040005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20040019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20044019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20050005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU4) ADDR=0x20050019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU4) ADDR=0x200500198 DWORD=0 NUMREGS=0 */ + 0x20058005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU6) ADDR=0x20058019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU6) ADDR=0x200580198 DWORD=0 NUMREGS=0 */ + 0x20000049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC0) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC0) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC0) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC1) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC1) ADDR=0x200200648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC1) ADDR=0x20020064c DWORD=0 NUMREGS=0 */ + 0x20054005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU5) ADDR=0x20054019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU5) ADDR=0x200540198 DWORD=0 NUMREGS=0 */ + 0x2004c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2004c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x2005c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU7) ADDR=0x2005c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU7) ADDR=0x2005c0198 DWORD=0 NUMREGS=0 */ + 0x20048005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20048019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU4) ADDR=0x200520004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU6) ADDR=0x2005a0004 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU5) ADDR=0x200560004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU7) ADDR=0x2005e0004 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200428004 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200430004 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200468004 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200470004 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2004a8004 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2004b0004 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2004e8004 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2004f0004 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU4, DQ0) ADDR=0x200528004 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU4, DQ1) ADDR=0x200530004 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU5, DQ0) ADDR=0x200568004 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU5, DQ1) ADDR=0x200570004 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU6, DQ0) ADDR=0x2005a8004 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU6, DQ1) ADDR=0x2005b0004 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU7, DQ0) ADDR=0x2005e8004 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU7, DQ1) ADDR=0x2005f0004 DWORD=0 NUMREGS=0 */ + 0x20040c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU0) ADDR=0x20040c064 DWORD=0 NUMREGS=0 */ + 0x20050c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU4) ADDR=0x20050c064 DWORD=0 NUMREGS=0 */ + 0x20044c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU1) ADDR=0x20044c064 DWORD=0 NUMREGS=0 */ + 0x20054c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU5) ADDR=0x20054c064 DWORD=0 NUMREGS=0 */ + 0x20048c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU2) ADDR=0x20048c064 DWORD=0 NUMREGS=0 */ + 0x2004cc01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU3) ADDR=0x2004cc064 DWORD=0 NUMREGS=0 */ + 0x20058c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU6) ADDR=0x20058c064 DWORD=0 NUMREGS=0 */ + 0x2005cc01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU7) ADDR=0x2005cc064 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU6) ADDR=0x200580424 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU4) ADDR=0x200500424 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU5) ADDR=0x200540424 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU7) ADDR=0x2005c0424 DWORD=0 NUMREGS=0 */ + 0x20f14015, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x0000211f, //compressed WR offset + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(GLBTIMER) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(GLBTIMER) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(GLBTIMER) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(GLBTIMER) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_CALSEG2ALLBANK0(GLBTIMER) ADDR=0x20f14007c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_ALLBANK2CALSEG0(GLBTIMER) ADDR=0x20f140084 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200400010 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2004c0010 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU6) ADDR=0x200580010 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU4) ADDR=0x200500010 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200440010 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU5) ADDR=0x200540010 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200480010 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU7) ADDR=0x2005c0010 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20044042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20048042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x2004c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x20050042, /* POLL:MRREAD(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20054042, /* POLL:MRREAD(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x20058042, /* POLL:MRREAD(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x2005c042, /* POLL:MRREAD(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_mcu_locked[] = { + 0x2000004d, //compressed WR cmd + 0x292e3329, //compressed WR offset + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC0) ADDR=0x2000004cc DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC0) ADDR=0x2000004b8 DWORD=0 NUMREGS=0 */ + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x2002004d, //compressed WR cmd + 0x292e3329, //compressed WR offset + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC1) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC1) ADDR=0x2002004b8 DWORD=0 NUMREGS=0 */ + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_before_restoration[] = { + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU4) ADDR=0x200520198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU6) ADDR=0x2005a0198 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU5) ADDR=0x200560198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU7) ADDR=0x2005e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ0) ADDR=0x200528198 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ1) ADDR=0x200530198 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ0) ADDR=0x200568198 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ1) ADDR=0x200570198 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ0) ADDR=0x2005a8198 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ1) ADDR=0x2005b0198 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ0) ADDR=0x2005e8198 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ1) ADDR=0x2005f0198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU4) ADDR=0x200520004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU6) ADDR=0x2005a0004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU5) ADDR=0x200560004 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU7) ADDR=0x2005e0004 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x2005a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU6) ADDR=0x2005a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x20056041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU5) ADDR=0x20056071c DWORD=0 NUMREGS=0 */ + 0x20052041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU4) ADDR=0x20052071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2005e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU7) ADDR=0x2005e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ0) ADDR=0x200528628 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ1) ADDR=0x200530628 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ0) ADDR=0x200568628 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ1) ADDR=0x200570628 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ0) ADDR=0x2005a8628 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ1) ADDR=0x2005b0628 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ0) ADDR=0x2005e8628 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ1) ADDR=0x2005f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ0) ADDR=0x200528190 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ1) ADDR=0x200530190 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ0) ADDR=0x200568190 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ1) ADDR=0x200570190 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ0) ADDR=0x2005a8190 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ1) ADDR=0x2005b0190 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ0) ADDR=0x2005e8190 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ1) ADDR=0x2005f0190 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ0) ADDR=0x20052818c DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ1) ADDR=0x20053018c DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ0) ADDR=0x20056818c DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ1) ADDR=0x20057018c DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ0) ADDR=0x2005a818c DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ1) ADDR=0x2005b018c DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ0) ADDR=0x2005e818c DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ1) ADDR=0x2005f018c DWORD=0 NUMREGS=0 */ + 0x20042802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ0) ADDR=0x20052818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20053002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ1) ADDR=0x20053018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ0) ADDR=0x20056818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20057002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ1) ADDR=0x20057018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ0) ADDR=0x2005a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ1) ADDR=0x2005b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ0) ADDR=0x2005e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ1) ADDR=0x2005f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x20052005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU4) ADDR=0x200520004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU4) ADDR=0x200520198 DWORD=0 NUMREGS=0 */ + 0x2004a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2005a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU6) ADDR=0x2005a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU6) ADDR=0x2005a0198 DWORD=0 NUMREGS=0 */ + 0x20056005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU5) ADDR=0x200560004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU5) ADDR=0x200560198 DWORD=0 NUMREGS=0 */ + 0x2004e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x2005e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU7) ADDR=0x2005e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU7) ADDR=0x2005e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ0) ADDR=0x200528198 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ1) ADDR=0x200530198 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ0) ADDR=0x200568198 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ1) ADDR=0x200570198 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ0) ADDR=0x2005a8198 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ1) ADDR=0x2005b0198 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ0) ADDR=0x2005e8198 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ1) ADDR=0x2005f0198 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200420700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200460700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2004a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2004e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20052041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU4) ADDR=0x200520700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20056041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU5) ADDR=0x200560700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2005a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU6) ADDR=0x2005a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2005e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU7) ADDR=0x2005e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200420708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200460708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2004a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2004e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20052041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU4) ADDR=0x200520708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20056041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU5) ADDR=0x200560708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2005a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU6) ADDR=0x2005a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2005e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU7) ADDR=0x2005e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200420710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200460710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2004a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2004e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20052041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU4) ADDR=0x200520710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20056041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU5) ADDR=0x200560710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2005a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU6) ADDR=0x2005a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2005e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU7) ADDR=0x2005e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20042081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20046081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20052081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20056081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2005a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2005e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200420500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200460500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2004a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2004e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU4) ADDR=0x200520500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU5) ADDR=0x200560500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU6) ADDR=0x2005a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU7) ADDR=0x2005e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200420504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200460504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2004a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2004e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU4) ADDR=0x200520504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU5) ADDR=0x200560504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU6) ADDR=0x2005a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU7) ADDR=0x2005e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200420508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200460508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2004a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2004e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU4) ADDR=0x200520508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU5) ADDR=0x200560508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU6) ADDR=0x2005a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU7) ADDR=0x2005e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20042050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20046050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2004a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2004e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU4) ADDR=0x20052050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU5) ADDR=0x20056050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU6) ADDR=0x2005a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU7) ADDR=0x2005e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200420510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200460510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2004a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2004e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU4) ADDR=0x200520510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU5) ADDR=0x200560510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU6) ADDR=0x2005a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU7) ADDR=0x2005e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200420514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200460514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2004a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2004e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU4) ADDR=0x200520514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU5) ADDR=0x200560514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU6) ADDR=0x2005a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU7) ADDR=0x2005e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200420518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200460518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2004a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2004e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU4) ADDR=0x200520518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU5) ADDR=0x200560518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU6) ADDR=0x2005a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU7) ADDR=0x2005e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20042051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20046051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2004a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2004e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU4) ADDR=0x20052051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU5) ADDR=0x20056051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU6) ADDR=0x2005a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU7) ADDR=0x2005e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20042841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200428704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20043041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200430704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20046841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200468704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20047041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200470704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2004a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2004b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2004e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2004f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20052841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU4, DQ0) ADDR=0x200528704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20053041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU4, DQ1) ADDR=0x200530704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20056841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU5, DQ0) ADDR=0x200568704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20057041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU5, DQ1) ADDR=0x200570704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU6, DQ0) ADDR=0x2005a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU6, DQ1) ADDR=0x2005b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU7, DQ0) ADDR=0x2005e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU7, DQ1) ADDR=0x2005f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ0) ADDR=0x200528b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ1) ADDR=0x200530b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ0) ADDR=0x200568b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ1) ADDR=0x200570b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ0) ADDR=0x2005a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ1) ADDR=0x2005b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ0) ADDR=0x2005e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ1) ADDR=0x2005f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00d800d8, /* Data -- VREF_F0 (DQ0) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ0) ADDR=0x200528b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ1) ADDR=0x200530b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ0) ADDR=0x200568b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ1) ADDR=0x200570b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ0) ADDR=0x2005a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ1) ADDR=0x2005b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ0) ADDR=0x2005e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ1) ADDR=0x2005f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00d800d8, /* Data -- VREF_F1 (DQ1) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200428b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200430b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200468b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200470b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2004a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2004b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2004e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2004f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU4, DQ0) ADDR=0x200528b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU4, DQ1) ADDR=0x200530b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU5, DQ0) ADDR=0x200568b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU5, DQ1) ADDR=0x200570b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU6, DQ0) ADDR=0x2005a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU6, DQ1) ADDR=0x2005b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU7, DQ0) ADDR=0x2005e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU7, DQ1) ADDR=0x2005f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200428b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200430b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200468b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200470b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2004a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2004b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2004e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2004f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU4, DQ0) ADDR=0x200528b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU4, DQ1) ADDR=0x200530b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU5, DQ0) ADDR=0x200568b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU5, DQ1) ADDR=0x200570b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU6, DQ0) ADDR=0x2005a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU6, DQ1) ADDR=0x2005b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU7, DQ0) ADDR=0x2005e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU7, DQ1) ADDR=0x2005f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* ####### IMPORTANT ##### PLEASE READ ##### */ + /* When restoring below WrDqCalVrefCodeControl and RdDqCalVrefCodeControl registers, Software first needs to read WrDQCalVrefCodeStatus and RdDqCalVrefCodeStatus registers and put the value from CodeStatus registers to CodeControl registers */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200520c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200560c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2005a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2005e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200520c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200560c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2005a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2005e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20052801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU4, DQ0) ADDR=0x2005281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20053001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU4, DQ1) ADDR=0x2005301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20056801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU5, DQ0) ADDR=0x2005681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20057001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU5, DQ1) ADDR=0x2005701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU6, DQ0) ADDR=0x2005a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU6, DQ1) ADDR=0x2005b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU7, DQ0) ADDR=0x2005e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU7, DQ1) ADDR=0x2005f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20052801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU4, DQ0) ADDR=0x2005281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20053001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU4, DQ1) ADDR=0x2005301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20056801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU5, DQ0) ADDR=0x2005681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20057001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU5, DQ1) ADDR=0x2005701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU6, DQ0) ADDR=0x2005a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU6, DQ1) ADDR=0x2005b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU7, DQ0) ADDR=0x2005e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU7, DQ1) ADDR=0x2005f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20052801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU4, DQ0) ADDR=0x2005281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20053001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU4, DQ1) ADDR=0x2005301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20056801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU5, DQ0) ADDR=0x2005681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20057001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU5, DQ1) ADDR=0x2005701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU6, DQ0) ADDR=0x2005a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU6, DQ1) ADDR=0x2005b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU7, DQ0) ADDR=0x2005e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU7, DQ1) ADDR=0x2005f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20050041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU4) ADDR=0x200500454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20054041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU5) ADDR=0x200540454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20058041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU6) ADDR=0x200580454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU7) ADDR=0x2005c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200400458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200440458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200480458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2004c0458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20050041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU4) ADDR=0x200500458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20054041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU5) ADDR=0x200540458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20058041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU6) ADDR=0x200580458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU7) ADDR=0x2005c0458 DWORD=0 NUMREGS=0 */ + 0x00000016, /* Offset */ + 0xb203330b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2004004a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2004404a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2004804a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2004c04a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20050041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU4) ADDR=0x2005004a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20054041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU5) ADDR=0x2005404a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20058041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU6) ADDR=0x2005804a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU7) ADDR=0x2005c04a0 DWORD=0 NUMREGS=0 */ + 0x00000028, /* Offset */ + 0xf203000b, /* Data -- MCU_DRAMCFG_FREQCHNGCTL2_FREQ3 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200400460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200440460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200480460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2004c0460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20050041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU4) ADDR=0x200500460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20054041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU5) ADDR=0x200540460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20058041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU6) ADDR=0x200580460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU7) ADDR=0x2005c0460 DWORD=0 NUMREGS=0 */ + 0x00000018, /* Offset */ + 0x00000316, /* Data -- MCU_DRAMCFG_FREQCHNGCTL4_FREQ0 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20f14001, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(GLBTIMER) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x00000006, /* Offset */ + 0x00061a80, /* Data -- GLBTIMER_GLBTIMER_ZQCTIMER 0x0 ## Save the value after End of Step 18 */ + 0x20043801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU0) ADDR=0x20043802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU1) ADDR=0x20047802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU2) ADDR=0x2004b802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU3) ADDR=0x2004f802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU4) ADDR=0x20053802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU5) ADDR=0x20057802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU6) ADDR=0x2005b802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f801, /* WR:AMPH_CFGH_CB_IMPCTL(MCU7) ADDR=0x2005f802c DWORD=0 NUMREGS=0 */ + 0x0000000b, /* Offset */ + 0x01001c2b, /* Data -- AMPH_CFGH_CB_IMPCTL 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2004380b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2004780b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2004b80b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2004f80b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053801, /* WR:AMPH_CFGH_B0_ODT(MCU4) ADDR=0x2005380b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057801, /* WR:AMPH_CFGH_B0_ODT(MCU5) ADDR=0x2005780b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b801, /* WR:AMPH_CFGH_B0_ODT(MCU6) ADDR=0x2005b80b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f801, /* WR:AMPH_CFGH_B0_ODT(MCU7) ADDR=0x2005f80b0 DWORD=0 NUMREGS=0 */ + 0x0000002c, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20043811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20047811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2004b811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2004f811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053801, /* WR:AMPH_CFGH_B1_ODT(MCU4) ADDR=0x20053811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057801, /* WR:AMPH_CFGH_B1_ODT(MCU5) ADDR=0x20057811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b801, /* WR:AMPH_CFGH_B1_ODT(MCU6) ADDR=0x2005b811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f801, /* WR:AMPH_CFGH_B1_ODT(MCU7) ADDR=0x2005f811c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_B1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2004380d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2004780d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2004b80d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2004f80d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053801, /* WR:AMPH_CFGH_DQS0_ODT(MCU4) ADDR=0x2005380d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057801, /* WR:AMPH_CFGH_DQS0_ODT(MCU5) ADDR=0x2005780d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b801, /* WR:AMPH_CFGH_DQS0_ODT(MCU6) ADDR=0x2005b80d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f801, /* WR:AMPH_CFGH_DQS0_ODT(MCU7) ADDR=0x2005f80d8 DWORD=0 NUMREGS=0 */ + 0x00000036, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS0_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20043801, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200438148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20047801, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200478148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004b801, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2004b8148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2004f801, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2004f8148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20053801, /* WR:AMPH_CFGH_DQS1_ODT(MCU4) ADDR=0x200538148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x20057801, /* WR:AMPH_CFGH_DQS1_ODT(MCU5) ADDR=0x200578148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005b801, /* WR:AMPH_CFGH_DQS1_ODT(MCU6) ADDR=0x2005b8148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + 0x2005f801, /* WR:AMPH_CFGH_DQS1_ODT(MCU7) ADDR=0x2005f8148 DWORD=0 NUMREGS=0 */ + 0x00000052, /* Offset */ + 0x01c00339, /* Data -- AMPH_CFGH_DQS1_ODT 0x0 ## Save the value after Bucket 0 Calibration. End of Step 14 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* END OF RESTORATION */ + 0x00000044, /* NOOP for 64bit alignment*/ +}; + +static const uint32_t aop_ddr_to_awake_post_mcu_awake_after_restoration[] = { + 0x200420c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x2005e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU7) ADDR=0x2005e0e34 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU4) ADDR=0x200520e34 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU5) ADDR=0x200560e34 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU6) ADDR=0x2005a0e34 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20050045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU4) ADDR=0x200500424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 NUMREGS=0 */ + 0x2005c045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU7) ADDR=0x2005c0424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20054045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU5) ADDR=0x200540424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 NUMREGS=0 */ + 0x20058045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU6) ADDR=0x200580424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x2005a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU6) ADDR=0x2005a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x20056041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU5) ADDR=0x20056071c DWORD=0 NUMREGS=0 */ + 0x20052041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU4) ADDR=0x20052071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2005e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU7) ADDR=0x2005e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ0) ADDR=0x200528628 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ1) ADDR=0x200530628 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ0) ADDR=0x200568628 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ1) ADDR=0x200570628 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ0) ADDR=0x2005a8628 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ1) ADDR=0x2005b0628 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ0) ADDR=0x2005e8628 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ1) ADDR=0x2005f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ0) ADDR=0x200528190 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ1) ADDR=0x200530190 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ0) ADDR=0x200568190 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ1) ADDR=0x200570190 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ0) ADDR=0x2005a8190 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ1) ADDR=0x2005b0190 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ0) ADDR=0x2005e8190 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ1) ADDR=0x2005f0190 DWORD=0 NUMREGS=0 */ + 0x20f14021, //compressed WR cmd + 0x0107000f, //compressed WR offset + 0x08050402, //compressed WR offset + 0x0000000a, //compressed WR offset + 0x000001ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(GLBTIMER) ADDR=0x20f14003c DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(GLBTIMER) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_DCCTIMER(GLBTIMER) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(GLBTIMER) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(GLBTIMER) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6bb, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(GLBTIMER) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(GLBTIMER) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(GLBTIMER) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(GLBTIMER) ADDR=0x20f140028 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001_a0.h b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001_a0.h new file mode 100644 index 0000000..8409ae2 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_mcu_8ch_s8001_a0.h @@ -0,0 +1,5929 @@ +#ifndef __MCU_INIT_AOP_A0_H__ +#define __MCU_INIT_AOP_A0_H__ + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_mcu_ddr[] = { + 0x20040c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU0) ADDR=0x20040c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU0) ADDR=0x20040c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU0) ADDR=0x20040c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU0) ADDR=0x20040c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU0) ADDR=0x20040c05c DWORD=0 NUMREGS=0 */ + 0x20044c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU1) ADDR=0x20044c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU1) ADDR=0x20044c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU1) ADDR=0x20044c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU1) ADDR=0x20044c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU1) ADDR=0x20044c05c DWORD=0 NUMREGS=0 */ + 0x20050c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU4) ADDR=0x20050c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU4) ADDR=0x20050c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU4) ADDR=0x20050c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU4) ADDR=0x20050c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU4) ADDR=0x20050c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU4) ADDR=0x20050c05c DWORD=0 NUMREGS=0 */ + 0x2004cc15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU3) ADDR=0x2004cc01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU3) ADDR=0x2004cc000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU3) ADDR=0x2004cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU3) ADDR=0x2004cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU3) ADDR=0x2004cc05c DWORD=0 NUMREGS=0 */ + 0x20054c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU5) ADDR=0x20054c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU5) ADDR=0x20054c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU5) ADDR=0x20054c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU5) ADDR=0x20054c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU5) ADDR=0x20054c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU5) ADDR=0x20054c05c DWORD=0 NUMREGS=0 */ + 0x20048c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU2) ADDR=0x20048c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU2) ADDR=0x20048c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU2) ADDR=0x20048c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU2) ADDR=0x20048c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU2) ADDR=0x20048c05c DWORD=0 NUMREGS=0 */ + 0x20058c15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU6) ADDR=0x20058c01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU6) ADDR=0x20058c000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU6) ADDR=0x20058c020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU6) ADDR=0x20058c020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU6) ADDR=0x20058c024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU6) ADDR=0x20058c05c DWORD=0 NUMREGS=0 */ + 0x2005cc15, //compressed WR cmd + 0x08080007, //compressed WR offset + 0x00001709, //compressed WR offset + 0x00000068, /* WR:SPLLCTRL_SPLLCTRL_CHARGEPUMP(MCU7) ADDR=0x2005cc01c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MODEREG(MCU7) ADDR=0x2005cc000 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU7) ADDR=0x2005cc020 DWORD=0 NUMREGS=0 */ + 0x00000015, /* WR:SPLLCTRL_SPLLCTRL_VCO(MCU7) ADDR=0x2005cc020 DWORD=0 NUMREGS=0 */ + 0x00000004, /* WR:SPLLCTRL_SPLLCTRL_LDO(MCU7) ADDR=0x2005cc024 DWORD=0 NUMREGS=0 */ + 0x00000011, /* WR:SPLLCTRL_SPLLCTRL_SPLLPWRDNCFG(MCU7) ADDR=0x2005cc05c DWORD=0 NUMREGS=0 */ + 0x2004007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU0) ADDR=0x200400450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU0) ADDR=0x200400458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU0) ADDR=0x20040045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU0) ADDR=0x200400460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU0) ADDR=0x2004004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU0) ADDR=0x200400468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU0) ADDR=0x20040046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU0) ADDR=0x200400470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU0) ADDR=0x200400474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU0) ADDR=0x200400478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU0) ADDR=0x2004004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU0) ADDR=0x200400480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU0) ADDR=0x200400484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU0) ADDR=0x200400488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU0) ADDR=0x20040048c DWORD=0 NUMREGS=0 */ + 0x2004005d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU0) ADDR=0x200400490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU0) ADDR=0x2004004cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU0) ADDR=0x200400498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU0) ADDR=0x20040049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU0) ADDR=0x2004004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU0) ADDR=0x2004004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU0) ADDR=0x2004004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU0) ADDR=0x2004004d0 DWORD=0 NUMREGS=0 */ + 0x2004407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU1) ADDR=0x200440450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU1) ADDR=0x200440458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU1) ADDR=0x20044045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU1) ADDR=0x200440460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU1) ADDR=0x2004404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU1) ADDR=0x200440468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU1) ADDR=0x20044046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU1) ADDR=0x200440470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU1) ADDR=0x200440474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU1) ADDR=0x200440478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU1) ADDR=0x2004404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU1) ADDR=0x200440480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU1) ADDR=0x200440484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU1) ADDR=0x200440488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU1) ADDR=0x20044048c DWORD=0 NUMREGS=0 */ + 0x2004405d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU1) ADDR=0x200440490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU1) ADDR=0x2004404cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU1) ADDR=0x200440498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU1) ADDR=0x20044049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU1) ADDR=0x2004404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU1) ADDR=0x2004404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU1) ADDR=0x2004404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU1) ADDR=0x2004404d0 DWORD=0 NUMREGS=0 */ + 0x2004c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU3) ADDR=0x2004c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU3) ADDR=0x2004c0458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU3) ADDR=0x2004c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU3) ADDR=0x2004c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU3) ADDR=0x2004c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU3) ADDR=0x2004c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU3) ADDR=0x2004c046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU3) ADDR=0x2004c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU3) ADDR=0x2004c0474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU3) ADDR=0x2004c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU3) ADDR=0x2004c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU3) ADDR=0x2004c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU3) ADDR=0x2004c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU3) ADDR=0x2004c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU3) ADDR=0x2004c048c DWORD=0 NUMREGS=0 */ + 0x2004c05d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU3) ADDR=0x2004c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU3) ADDR=0x2004c04cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU3) ADDR=0x2004c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU3) ADDR=0x2004c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU3) ADDR=0x2004c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU3) ADDR=0x2004c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU3) ADDR=0x2004c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU3) ADDR=0x2004c04d0 DWORD=0 NUMREGS=0 */ + 0x2005007d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU4) ADDR=0x200500450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU4) ADDR=0x200500454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU4) ADDR=0x200500458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU4) ADDR=0x20050045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU4) ADDR=0x200500460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU4) ADDR=0x2005004c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU4) ADDR=0x200500468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU4) ADDR=0x20050046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU4) ADDR=0x200500470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU4) ADDR=0x200500474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU4) ADDR=0x200500478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU4) ADDR=0x2005004c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU4) ADDR=0x200500480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU4) ADDR=0x200500484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU4) ADDR=0x200500488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU4) ADDR=0x20050048c DWORD=0 NUMREGS=0 */ + 0x2005005d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU4) ADDR=0x200500490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU4) ADDR=0x2005004cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU4) ADDR=0x200500498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU4) ADDR=0x20050049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU4) ADDR=0x2005004a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU4) ADDR=0x2005004a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU4) ADDR=0x2005004a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU4) ADDR=0x2005004d0 DWORD=0 NUMREGS=0 */ + 0x2005c07d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU7) ADDR=0x2005c0450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU7) ADDR=0x2005c0454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU7) ADDR=0x2005c0458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU7) ADDR=0x2005c045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU7) ADDR=0x2005c0460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU7) ADDR=0x2005c04c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU7) ADDR=0x2005c0468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU7) ADDR=0x2005c046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU7) ADDR=0x2005c0470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU7) ADDR=0x2005c0474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU7) ADDR=0x2005c0478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU7) ADDR=0x2005c04c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU7) ADDR=0x2005c0480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU7) ADDR=0x2005c0484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU7) ADDR=0x2005c0488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU7) ADDR=0x2005c048c DWORD=0 NUMREGS=0 */ + 0x2005c05d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU7) ADDR=0x2005c0490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU7) ADDR=0x2005c04cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU7) ADDR=0x2005c0498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU7) ADDR=0x2005c049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU7) ADDR=0x2005c04a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU7) ADDR=0x2005c04a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU7) ADDR=0x2005c04a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU7) ADDR=0x2005c04d0 DWORD=0 NUMREGS=0 */ + 0x2004807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU2) ADDR=0x200480450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU2) ADDR=0x200480458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU2) ADDR=0x20048045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU2) ADDR=0x200480460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU2) ADDR=0x2004804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU2) ADDR=0x200480468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU2) ADDR=0x20048046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU2) ADDR=0x200480470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU2) ADDR=0x200480474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU2) ADDR=0x200480478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU2) ADDR=0x2004804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU2) ADDR=0x200480480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU2) ADDR=0x200480484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU2) ADDR=0x200480488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU2) ADDR=0x20048048c DWORD=0 NUMREGS=0 */ + 0x2004805d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU2) ADDR=0x200480490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU2) ADDR=0x2004804cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU2) ADDR=0x200480498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU2) ADDR=0x20048049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU2) ADDR=0x2004804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU2) ADDR=0x2004804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU2) ADDR=0x2004804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU2) ADDR=0x2004804d0 DWORD=0 NUMREGS=0 */ + 0x2005407d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU5) ADDR=0x200540450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU5) ADDR=0x200540454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU5) ADDR=0x200540458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU5) ADDR=0x20054045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU5) ADDR=0x200540460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU5) ADDR=0x2005404c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU5) ADDR=0x200540468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU5) ADDR=0x20054046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU5) ADDR=0x200540470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU5) ADDR=0x200540474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU5) ADDR=0x200540478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU5) ADDR=0x2005404c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU5) ADDR=0x200540480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU5) ADDR=0x200540484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU5) ADDR=0x200540488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU5) ADDR=0x20054048c DWORD=0 NUMREGS=0 */ + 0x2005405d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU5) ADDR=0x200540490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU5) ADDR=0x2005404cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU5) ADDR=0x200540498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU5) ADDR=0x20054049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU5) ADDR=0x2005404a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU5) ADDR=0x2005404a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU5) ADDR=0x2005404a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU5) ADDR=0x2005404d0 DWORD=0 NUMREGS=0 */ + 0x2005807d, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x1b1a3118, //compressed WR offset + 0x321e1d1c, //compressed WR offset + 0x23222120, //compressed WR offset + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ0(MCU6) ADDR=0x200580450 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU6) ADDR=0x200580454 DWORD=0 NUMREGS=0 */ + 0xb303440b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ0(MCU6) ADDR=0x200580458 DWORD=0 NUMREGS=0 */ + 0xde012d02, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ0(MCU6) ADDR=0x20058045c DWORD=0 NUMREGS=0 */ + 0x00000416, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ0(MCU6) ADDR=0x200580460 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ0(MCU6) ADDR=0x2005804c4 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ1(MCU6) ADDR=0x200580468 DWORD=0 NUMREGS=0 */ + 0x110c110e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ1(MCU6) ADDR=0x20058046c DWORD=0 NUMREGS=0 */ + 0xd303220b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ1(MCU6) ADDR=0x200580470 DWORD=0 NUMREGS=0 */ + 0xae015202, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ1(MCU6) ADDR=0x200580474 DWORD=0 NUMREGS=0 */ + 0x00000216, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ1(MCU6) ADDR=0x200580478 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ1(MCU6) ADDR=0x2005804c8 DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ2(MCU6) ADDR=0x200580480 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ2(MCU6) ADDR=0x200580484 DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ2(MCU6) ADDR=0x200580488 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ2(MCU6) ADDR=0x20058048c DWORD=0 NUMREGS=0 */ + 0x2005805d, //compressed WR cmd + 0x27263324, //compressed WR offset + 0x342a2928, //compressed WR offset + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ2(MCU6) ADDR=0x200580490 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ2(MCU6) ADDR=0x2005804cc DWORD=0 NUMREGS=0 */ + 0x18cd104d, /* WR:AMCX_DRAMCFG_FREQCHNGCTL0_FREQ3(MCU6) ADDR=0x200580498 DWORD=0 NUMREGS=0 */ + 0x590c590e, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ3(MCU6) ADDR=0x20058049c DWORD=0 NUMREGS=0 */ + 0xf303000b, /* WR:AMCX_DRAMCFG_FREQCHNGCTL2_FREQ3(MCU6) ADDR=0x2005804a0 DWORD=0 NUMREGS=0 */ + 0x8e010002, /* WR:AMCX_DRAMCFG_FREQCHNGCTL3_FREQ3(MCU6) ADDR=0x2005804a4 DWORD=0 NUMREGS=0 */ + 0x00000016, /* WR:AMCX_DRAMCFG_FREQCHNGCTL4_FREQ3(MCU6) ADDR=0x2005804a8 DWORD=0 NUMREGS=0 */ + 0x000c1108, /* WR:AMCX_DRAMCFG_FREQCHNGTIM_FREQ3(MCU6) ADDR=0x2005804d0 DWORD=0 NUMREGS=0 */ + 0x200420dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU0) ADDR=0x200420ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU0) ADDR=0x200420ef4 DWORD=0 NUMREGS=0 */ + 0x200460dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU1) ADDR=0x200460ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU1) ADDR=0x200460ef4 DWORD=0 NUMREGS=0 */ + 0x2004a0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU2) ADDR=0x2004a0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU2) ADDR=0x2004a0ef4 DWORD=0 NUMREGS=0 */ + 0x20f14005, //compressed WR cmd + 0x00002324, //compressed WR offset + 0x00000003, /* WR:GLBTIMER_GLBTIMER_PERVREFCALCFG(GLBTIMER) ADDR=0x20f140090 DWORD=0 NUMREGS=0 */ + 0x00060006, /* WR:GLBTIMER_GLBTIMER_VREFCNTRL(GLBTIMER) ADDR=0x20f14008c DWORD=0 NUMREGS=0 */ + 0x2005e0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU7) ADDR=0x2005e0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU7) ADDR=0x2005e0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU7) ADDR=0x2005e0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU7) ADDR=0x2005e0ef4 DWORD=0 NUMREGS=0 */ + 0x200520dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU4) ADDR=0x200520ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU4) ADDR=0x200520ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU4) ADDR=0x200520ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU4) ADDR=0x200520ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU4) ADDR=0x200520ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU4) ADDR=0x200520ef4 DWORD=0 NUMREGS=0 */ + 0x2004e0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU3) ADDR=0x2004e0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU3) ADDR=0x2004e0ef4 DWORD=0 NUMREGS=0 */ + 0x200560dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU5) ADDR=0x200560ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU5) ADDR=0x200560ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU5) ADDR=0x200560ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU5) ADDR=0x200560ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU5) ADDR=0x200560ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU5) ADDR=0x200560ef4 DWORD=0 NUMREGS=0 */ + 0x2005a0dd, //compressed WR cmd + 0xb8b6c6c8, //compressed WR offset + 0xbdbcbab9, //compressed WR offset + 0x19191111, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f20 DWORD=0 NUMREGS=0 */ + 0x19191191, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f18 DWORD=0 NUMREGS=0 */ + 0x02d0b060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ed8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL1(MCU6) ADDR=0x2005a0ee0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFOFFSETCONTROL2(MCU6) ADDR=0x2005a0ee4 DWORD=0 NUMREGS=0 */ + 0x02200060, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ee8 DWORD=0 NUMREGS=0 */ + 0x06040200, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL1(MCU6) ADDR=0x2005a0ef0 DWORD=0 NUMREGS=0 */ + 0x00fafcfe, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFOFFSETCONTROL2(MCU6) ADDR=0x2005a0ef4 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU4) ADDR=0x2005003d4 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU6) ADDR=0x2005803d4 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU5) ADDR=0x2005403d4 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU7) ADDR=0x2005c03d4 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f5, //compressed WR offset + 0x120c90b8, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU0) ADDR=0x200400400 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU1) ADDR=0x200440400 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU3) ADDR=0x2004c0400 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU4) ADDR=0x200500400 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU7) ADDR=0x2005c0400 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU2) ADDR=0x200480400 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU5) ADDR=0x200540400 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x000210ef, /* WR:AMCX_DRAMCFG_RWCFG(MCU6) ADDR=0x200580400 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ0) ADDR=0x2005281a4 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ1) ADDR=0x2005301a4 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ0) ADDR=0x2005681a4 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ1) ADDR=0x2005701a4 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ0) ADDR=0x2005a81a4 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ1) ADDR=0x2005b01a4 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ0) ADDR=0x2005e81a4 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ1) ADDR=0x2005f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU4) ADDR=0x2005201a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU6) ADDR=0x2005a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU5) ADDR=0x2005601a4 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x50017350, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU7) ADDR=0x2005e01a4 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU4) ADDR=0x2005003d0 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU6) ADDR=0x2005803d0 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU5) ADDR=0x2005403d0 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x000000f4, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x2005c03d, //compressed WR cmd + 0xa0e1e0f4, //compressed WR offset + 0xe4a3a2a1, //compressed WR offset + 0xf5f0ece8, //compressed WR offset + 0xf1ede9e5, //compressed WR offset + 0x72276265, /* WR:AMCX_DRAMTIM_PDN(MCU7) ADDR=0x2005c03d0 DWORD=0 NUMREGS=0 */ + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU7) ADDR=0x2005c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU7) ADDR=0x2005c0384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU7) ADDR=0x2005c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU7) ADDR=0x2005c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU7) ADDR=0x2005c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU7) ADDR=0x2005c028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU7) ADDR=0x2005c0390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU7) ADDR=0x2005c03a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU7) ADDR=0x2005c03b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU7) ADDR=0x2005c03c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU7) ADDR=0x2005c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU7) ADDR=0x2005c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU7) ADDR=0x2005c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU7) ADDR=0x2005c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU7) ADDR=0x2005c03c4 DWORD=0 NUMREGS=0 */ + 0x2005c03d, //compressed WR cmd + 0xf2eeeae6, //compressed WR offset + 0xf3efebe7, //compressed WR offset + 0xf7f6f4ff, //compressed WR offset + 0xe1e0f9f8, //compressed WR offset + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU7) ADDR=0x2005c0398 DWORD=0 NUMREGS=0 */ + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU7) ADDR=0x2005c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU7) ADDR=0x2005c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU7) ADDR=0x2005c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU7) ADDR=0x2005c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU7) ADDR=0x2005c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU7) ADDR=0x2005c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU7) ADDR=0x2005c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU7) ADDR=0x2005c03fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU7) ADDR=0x2005c03d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU7) ADDR=0x2005c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU7) ADDR=0x2005c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU7) ADDR=0x2005c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU7) ADDR=0x2005c03e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU7) ADDR=0x2005c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU7) ADDR=0x2005c0384 DWORD=0 NUMREGS=0 */ + 0x2005c011, //compressed WR cmd + 0xfbfae3e2, //compressed WR offset + 0x000000fc, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU7) ADDR=0x2005c0388 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU7) ADDR=0x2005c038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU7) ADDR=0x2005c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU7) ADDR=0x2005c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU7) ADDR=0x2005c03f0 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU0) ADDR=0x200400280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU0) ADDR=0x200400284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU0) ADDR=0x200400288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU0) ADDR=0x20040028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU0) ADDR=0x200400390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU0) ADDR=0x2004003a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU0) ADDR=0x2004003c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU0) ADDR=0x2004003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU0) ADDR=0x200400394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU0) ADDR=0x2004003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU0) ADDR=0x2004003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU0) ADDR=0x200400398 DWORD=0 NUMREGS=0 */ + 0x2004003d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU0) ADDR=0x2004003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU0) ADDR=0x2004003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU0) ADDR=0x20040039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU0) ADDR=0x2004003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU0) ADDR=0x2004003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU0) ADDR=0x2004003d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU0) ADDR=0x2004003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU0) ADDR=0x2004003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU0) ADDR=0x2004003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU0) ADDR=0x2004003e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU0) ADDR=0x200400380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU0) ADDR=0x200400384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU0) ADDR=0x200400388 DWORD=0 NUMREGS=0 */ + 0x2004000d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU0) ADDR=0x20040038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU0) ADDR=0x2004003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU0) ADDR=0x2004003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU0) ADDR=0x2004003f0 DWORD=0 NUMREGS=0 */ + 0x2005003d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU4) ADDR=0x200500380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU4) ADDR=0x200500384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU4) ADDR=0x200500280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU4) ADDR=0x200500284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU4) ADDR=0x200500288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU4) ADDR=0x20050028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU4) ADDR=0x200500390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU4) ADDR=0x2005003a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU4) ADDR=0x2005003b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU4) ADDR=0x2005003c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU4) ADDR=0x2005003d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU4) ADDR=0x200500394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU4) ADDR=0x2005003a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU4) ADDR=0x2005003b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU4) ADDR=0x2005003c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU4) ADDR=0x200500398 DWORD=0 NUMREGS=0 */ + 0x2005003d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU4) ADDR=0x2005003a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU4) ADDR=0x2005003b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU4) ADDR=0x2005003c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU4) ADDR=0x20050039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU4) ADDR=0x2005003ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU4) ADDR=0x2005003bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU4) ADDR=0x2005003cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU4) ADDR=0x2005003fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU4) ADDR=0x2005003d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU4) ADDR=0x2005003d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU4) ADDR=0x2005003dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU4) ADDR=0x2005003e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU4) ADDR=0x2005003e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU4) ADDR=0x200500380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU4) ADDR=0x200500384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU4) ADDR=0x200500388 DWORD=0 NUMREGS=0 */ + 0x2005000d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU4) ADDR=0x20050038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU4) ADDR=0x2005003e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU4) ADDR=0x2005003ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU4) ADDR=0x2005003f0 DWORD=0 NUMREGS=0 */ + 0x2005803d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU6) ADDR=0x200580380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU6) ADDR=0x200580384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU6) ADDR=0x200580280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU6) ADDR=0x200580284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU6) ADDR=0x200580288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU6) ADDR=0x20058028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU6) ADDR=0x200580390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU6) ADDR=0x2005803a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU6) ADDR=0x2005803b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU6) ADDR=0x2005803c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU6) ADDR=0x2005803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU6) ADDR=0x200580394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU6) ADDR=0x2005803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU6) ADDR=0x2005803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU6) ADDR=0x2005803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU6) ADDR=0x200580398 DWORD=0 NUMREGS=0 */ + 0x2005803d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU6) ADDR=0x2005803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU6) ADDR=0x2005803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU6) ADDR=0x2005803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU6) ADDR=0x20058039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU6) ADDR=0x2005803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU6) ADDR=0x2005803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU6) ADDR=0x2005803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU6) ADDR=0x2005803fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU6) ADDR=0x2005803d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU6) ADDR=0x2005803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU6) ADDR=0x2005803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU6) ADDR=0x2005803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU6) ADDR=0x2005803e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU6) ADDR=0x200580380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU6) ADDR=0x200580384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU6) ADDR=0x200580388 DWORD=0 NUMREGS=0 */ + 0x2005800d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU6) ADDR=0x20058038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU6) ADDR=0x2005803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU6) ADDR=0x2005803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU6) ADDR=0x2005803f0 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU3) ADDR=0x2004c0280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU3) ADDR=0x2004c0284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU3) ADDR=0x2004c0288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU3) ADDR=0x2004c028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU3) ADDR=0x2004c0390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU3) ADDR=0x2004c03a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU3) ADDR=0x2004c03c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU3) ADDR=0x2004c03d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU3) ADDR=0x2004c0394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU3) ADDR=0x2004c03a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU3) ADDR=0x2004c03c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU3) ADDR=0x2004c0398 DWORD=0 NUMREGS=0 */ + 0x2004c03d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU3) ADDR=0x2004c03a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU3) ADDR=0x2004c03c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU3) ADDR=0x2004c039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU3) ADDR=0x2004c03ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU3) ADDR=0x2004c03cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU3) ADDR=0x2004c03d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU3) ADDR=0x2004c03d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU3) ADDR=0x2004c03dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU3) ADDR=0x2004c03e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU3) ADDR=0x2004c03e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU3) ADDR=0x2004c0380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU3) ADDR=0x2004c0384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU3) ADDR=0x2004c0388 DWORD=0 NUMREGS=0 */ + 0x2004c00d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU3) ADDR=0x2004c038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU3) ADDR=0x2004c03e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU3) ADDR=0x2004c03ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU3) ADDR=0x2004c03f0 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU1) ADDR=0x200440280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU1) ADDR=0x200440284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU1) ADDR=0x200440288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU1) ADDR=0x20044028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU1) ADDR=0x200440390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU1) ADDR=0x2004403a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU1) ADDR=0x2004403c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU1) ADDR=0x2004403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU1) ADDR=0x200440394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU1) ADDR=0x2004403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU1) ADDR=0x2004403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU1) ADDR=0x200440398 DWORD=0 NUMREGS=0 */ + 0x2004403d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU1) ADDR=0x2004403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU1) ADDR=0x2004403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU1) ADDR=0x20044039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU1) ADDR=0x2004403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU1) ADDR=0x2004403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU1) ADDR=0x2004403d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU1) ADDR=0x2004403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU1) ADDR=0x2004403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU1) ADDR=0x2004403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU1) ADDR=0x2004403e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU1) ADDR=0x200440380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU1) ADDR=0x200440384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU1) ADDR=0x200440388 DWORD=0 NUMREGS=0 */ + 0x2004400d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU1) ADDR=0x20044038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU1) ADDR=0x2004403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU1) ADDR=0x2004403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU1) ADDR=0x2004403f0 DWORD=0 NUMREGS=0 */ + 0x2005403d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU5) ADDR=0x200540380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU5) ADDR=0x200540384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU5) ADDR=0x200540280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU5) ADDR=0x200540284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU5) ADDR=0x200540288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU5) ADDR=0x20054028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU5) ADDR=0x200540390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU5) ADDR=0x2005403a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU5) ADDR=0x2005403b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU5) ADDR=0x2005403c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU5) ADDR=0x2005403d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU5) ADDR=0x200540394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU5) ADDR=0x2005403a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU5) ADDR=0x2005403b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU5) ADDR=0x2005403c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU5) ADDR=0x200540398 DWORD=0 NUMREGS=0 */ + 0x2005403d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU5) ADDR=0x2005403a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU5) ADDR=0x2005403b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU5) ADDR=0x2005403c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU5) ADDR=0x20054039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU5) ADDR=0x2005403ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU5) ADDR=0x2005403bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU5) ADDR=0x2005403cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU5) ADDR=0x2005403fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU5) ADDR=0x2005403d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU5) ADDR=0x2005403d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU5) ADDR=0x2005403dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU5) ADDR=0x2005403e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU5) ADDR=0x2005403e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU5) ADDR=0x200540380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU5) ADDR=0x200540384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU5) ADDR=0x200540388 DWORD=0 NUMREGS=0 */ + 0x2005400d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU5) ADDR=0x20054038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU5) ADDR=0x2005403e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU5) ADDR=0x2005403ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU5) ADDR=0x2005403f0 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xa1a0e1e0, //compressed WR offset + 0xe8e4a3a2, //compressed WR offset + 0xe5f5f0ec, //compressed WR offset + 0xe6f1ede9, //compressed WR offset + 0x00103387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00102206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x00060d0c, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ0(MCU2) ADDR=0x200480280 DWORD=0 NUMREGS=0 */ + 0x00050b06, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ1(MCU2) ADDR=0x200480284 DWORD=0 NUMREGS=0 */ + 0x00010b01, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ2(MCU2) ADDR=0x200480288 DWORD=0 NUMREGS=0 */ + 0x00010901, /* WR:AMCX_PHYTIM_PHYRDWRTIM_FREQ3(MCU2) ADDR=0x20048028c DWORD=0 NUMREGS=0 */ + 0x63e2080f, /* WR:AMCX_DRAMTIM_CASPCH_FREQ0(MCU2) ADDR=0x200480390 DWORD=0 NUMREGS=0 */ + 0x2008110f, /* WR:AMCX_DRAMTIM_ACT_FREQ0(MCU2) ADDR=0x2004803a0 DWORD=0 NUMREGS=0 */ + 0x48900078, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0xa0096012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ0(MCU2) ADDR=0x2004803c0 DWORD=0 NUMREGS=0 */ + 0x1a0cc0f4, /* WR:AMCX_DRAMTIM_MODEREG(MCU2) ADDR=0x2004803d4 DWORD=0 NUMREGS=0 */ + 0x42110408, /* WR:AMCX_DRAMTIM_CASPCH_FREQ1(MCU2) ADDR=0x200480394 DWORD=0 NUMREGS=0 */ + 0x10040908, /* WR:AMCX_DRAMTIM_ACT_FREQ1(MCU2) ADDR=0x2004803a4 DWORD=0 NUMREGS=0 */ + 0x24480050, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x5004b012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ1(MCU2) ADDR=0x2004803c4 DWORD=0 NUMREGS=0 */ + 0x40c50402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ2(MCU2) ADDR=0x200480398 DWORD=0 NUMREGS=0 */ + 0x2004803d, //compressed WR cmd + 0xe7f2eeea, //compressed WR offset + 0xfff3efeb, //compressed WR offset + 0xf8f7f6f4, //compressed WR offset + 0xe2e1e0f9, //compressed WR offset + 0x04020302, /* WR:AMCX_DRAMTIM_ACT_FREQ2(MCU2) ADDR=0x2004803a8 DWORD=0 NUMREGS=0 */ + 0x09120014, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x28013012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ2(MCU2) ADDR=0x2004803c8 DWORD=0 NUMREGS=0 */ + 0x40c20402, /* WR:AMCX_DRAMTIM_CASPCH_FREQ3(MCU2) ADDR=0x20048039c DWORD=0 NUMREGS=0 */ + 0x02020404, /* WR:AMCX_DRAMTIM_ACT_FREQ3(MCU2) ADDR=0x2004803ac DWORD=0 NUMREGS=0 */ + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x28006012, /* WR:AMCX_DRAMTIM_SELFREF_FREQ3(MCU2) ADDR=0x2004803cc DWORD=0 NUMREGS=0 */ + 0x0015005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x722762c6, /* WR:AMCX_DRAMTIM_PDN(MCU2) ADDR=0x2004803d0 DWORD=0 NUMREGS=0 */ + 0x4d05a910, /* WR:AMCX_DRAMTIM_DERATE_FREQ0(MCU2) ADDR=0x2004803d8 DWORD=0 NUMREGS=0 */ + 0x28835488, /* WR:AMCX_DRAMTIM_DERATE_FREQ1(MCU2) ADDR=0x2004803dc DWORD=0 NUMREGS=0 */ + 0x0c212142, /* WR:AMCX_DRAMTIM_DERATE_FREQ2(MCU2) ADDR=0x2004803e0 DWORD=0 NUMREGS=0 */ + 0x10412082, /* WR:AMCX_DRAMTIM_DERATE_FREQ3(MCU2) ADDR=0x2004803e4 DWORD=0 NUMREGS=0 */ + 0x00123387, /* WR:AMCX_DRAMTIM_LAT_FREQ0(MCU2) ADDR=0x200480380 DWORD=0 NUMREGS=0 */ + 0x00112206, /* WR:AMCX_DRAMTIM_LAT_FREQ1(MCU2) ADDR=0x200480384 DWORD=0 NUMREGS=0 */ + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ2(MCU2) ADDR=0x200480388 DWORD=0 NUMREGS=0 */ + 0x2004800d, //compressed WR cmd + 0xfcfbfae3, //compressed WR offset + 0x001110c2, /* WR:AMCX_DRAMTIM_LAT_FREQ3(MCU2) ADDR=0x20048038c DWORD=0 NUMREGS=0 */ + 0x01412222, /* WR:AMCX_DRAMTIM_TAT_FREQ0(MCU2) ADDR=0x2004803e8 DWORD=0 NUMREGS=0 */ + 0x01312222, /* WR:AMCX_DRAMTIM_TAT_FREQ1(MCU2) ADDR=0x2004803ec DWORD=0 NUMREGS=0 */ + 0x01212222, /* WR:AMCX_DRAMTIM_TAT_FREQ2(MCU2) ADDR=0x2004803f0 DWORD=0 NUMREGS=0 */ + 0x20040051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU0) ADDR=0x200400404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU0) ADDR=0x200400780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU0) ADDR=0x20040078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU1) ADDR=0x200440404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU1) ADDR=0x200440780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU1) ADDR=0x20044078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU3) ADDR=0x2004c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU3) ADDR=0x2004c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU3) ADDR=0x2004c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20050051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU4) ADDR=0x200500404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU4) ADDR=0x200500780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU4) ADDR=0x20050078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU4) ADDR=0x200500424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x2005c051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU7) ADDR=0x2005c0404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU7) ADDR=0x2005c0780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU7) ADDR=0x2005c078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU7) ADDR=0x2005c0424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU2) ADDR=0x200480404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU2) ADDR=0x200480780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU2) ADDR=0x20048078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20054051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU5) ADDR=0x200540404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU5) ADDR=0x200540780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU5) ADDR=0x20054078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU5) ADDR=0x200540424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x20058051, //compressed WR cmd + 0x09e3e001, //compressed WR offset + 0x00000008, //compressed WR offset + 0x00006061, /* WR:AMCX_DRAMCFG_RNKCFG(MCU6) ADDR=0x200580404 DWORD=0 NUMREGS=0 */ + 0x00000100, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ0(MCU6) ADDR=0x200580780 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMCX_MIFQCTRL_MIFQMAXCTRL_FREQ3(MCU6) ADDR=0x20058078c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU6) ADDR=0x200580424 DWORD=0 NUMREGS=0 */ + 0x00002000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU4) ADDR=0x200500000 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU6) ADDR=0x200580000 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU5) ADDR=0x200540000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU7) ADDR=0x2005c0000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000002, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU4) ADDR=0x20050043c DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU7) ADDR=0x2005c043c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU5) ADDR=0x20054043c DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x0000000f, //compressed WR offset + 0x15030000, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU6) ADDR=0x20058043c DWORD=0 NUMREGS=0 */ + 0x20043835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU0) ADDR=0x2004382a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU0) ADDR=0x2004382a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU0) ADDR=0x2004382a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU0) ADDR=0x2004382ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU0) ADDR=0x2004382b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU0) ADDR=0x2004382b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU0) ADDR=0x20043829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU0) ADDR=0x2004382a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU0) ADDR=0x2004382a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU0) ADDR=0x2004382a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU0) ADDR=0x2004382ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU0) ADDR=0x2004382b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU0) ADDR=0x2004382b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU0) ADDR=0x20043829c DWORD=0 NUMREGS=0 */ + 0x20047835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU1) ADDR=0x2004782a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU1) ADDR=0x2004782a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU1) ADDR=0x2004782a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU1) ADDR=0x2004782ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU1) ADDR=0x2004782b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU1) ADDR=0x2004782b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU1) ADDR=0x20047829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU1) ADDR=0x2004782a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU1) ADDR=0x2004782a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU1) ADDR=0x2004782a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU1) ADDR=0x2004782ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU1) ADDR=0x2004782b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU1) ADDR=0x2004782b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU1) ADDR=0x20047829c DWORD=0 NUMREGS=0 */ + 0x2005b835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU6) ADDR=0x2005b82a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU6) ADDR=0x2005b82a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU6) ADDR=0x2005b82a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU6) ADDR=0x2005b82ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU6) ADDR=0x2005b82b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU6) ADDR=0x2005b82b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU6) ADDR=0x2005b829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU6) ADDR=0x2005b82a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU6) ADDR=0x2005b82a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU6) ADDR=0x2005b82a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU6) ADDR=0x2005b82ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU6) ADDR=0x2005b82b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU6) ADDR=0x2005b82b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU6) ADDR=0x2005b829c DWORD=0 NUMREGS=0 */ + 0x20057835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU5) ADDR=0x2005782a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU5) ADDR=0x2005782a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU5) ADDR=0x2005782a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU5) ADDR=0x2005782ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU5) ADDR=0x2005782b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU5) ADDR=0x2005782b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU5) ADDR=0x20057829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU5) ADDR=0x2005782a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU5) ADDR=0x2005782a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU5) ADDR=0x2005782a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU5) ADDR=0x2005782ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU5) ADDR=0x2005782b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU5) ADDR=0x2005782b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU5) ADDR=0x20057829c DWORD=0 NUMREGS=0 */ + 0x2004b835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU2) ADDR=0x2004b82a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU2) ADDR=0x2004b82a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU2) ADDR=0x2004b82a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU2) ADDR=0x2004b82ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU2) ADDR=0x2004b82b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU2) ADDR=0x2004b82b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU2) ADDR=0x2004b829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU2) ADDR=0x2004b82a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU2) ADDR=0x2004b82a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU2) ADDR=0x2004b82a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU2) ADDR=0x2004b82ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU2) ADDR=0x2004b82b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU2) ADDR=0x2004b82b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU2) ADDR=0x2004b829c DWORD=0 NUMREGS=0 */ + 0x20053835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU4) ADDR=0x2005382a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU4) ADDR=0x2005382a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU4) ADDR=0x2005382a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU4) ADDR=0x2005382ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU4) ADDR=0x2005382b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU4) ADDR=0x2005382b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU4) ADDR=0x20053829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU4) ADDR=0x2005382a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU4) ADDR=0x2005382a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU4) ADDR=0x2005382a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU4) ADDR=0x2005382ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU4) ADDR=0x2005382b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU4) ADDR=0x2005382b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU4) ADDR=0x20053829c DWORD=0 NUMREGS=0 */ + 0x2005f835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU7) ADDR=0x2005f82a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU7) ADDR=0x2005f82a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU7) ADDR=0x2005f82a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU7) ADDR=0x2005f82ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU7) ADDR=0x2005f82b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU7) ADDR=0x2005f82b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU7) ADDR=0x2005f829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU7) ADDR=0x2005f82a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU7) ADDR=0x2005f82a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU7) ADDR=0x2005f82a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU7) ADDR=0x2005f82ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU7) ADDR=0x2005f82b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU7) ADDR=0x2005f82b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU7) ADDR=0x2005f829c DWORD=0 NUMREGS=0 */ + 0x2004f835, //compressed WR cmd + 0xabaaa9a8, //compressed WR offset + 0xa8a7adac, //compressed WR offset + 0xacabaaa9, //compressed WR offset + 0x0000a7ad, //compressed WR offset + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU3) ADDR=0x2004f82a0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU3) ADDR=0x2004f82a4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU3) ADDR=0x2004f82a8 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU3) ADDR=0x2004f82ac DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU3) ADDR=0x2004f82b0 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU3) ADDR=0x2004f82b4 DWORD=0 NUMREGS=0 */ + 0x00003f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU3) ADDR=0x2004f829c DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCK(MCU3) ADDR=0x2004f82a0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCS(MCU3) ADDR=0x2004f82a4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB0(MCU3) ADDR=0x2004f82a8 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS0(MCU3) ADDR=0x2004f82ac DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPB1(MCU3) ADDR=0x2004f82b0 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPDQS1(MCU3) ADDR=0x2004f82b4 DWORD=0 NUMREGS=0 */ + 0x00013f3f, /* WR:AMPH_CFGH_DCC_BYPCA(MCU3) ADDR=0x2004f829c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU0) ADDR=0x200420000 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU1) ADDR=0x200460000 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU4) ADDR=0x200520000 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU2) ADDR=0x2004a0000 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU6) ADDR=0x2005a0000 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU5) ADDR=0x200560000 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU3) ADDR=0x2004e0000 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPEN(MCU7) ADDR=0x2005e0000 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ0) ADDR=0x200428000 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU0, DQ1) ADDR=0x200430000 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ0) ADDR=0x200468000 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU1, DQ1) ADDR=0x200470000 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ0) ADDR=0x2004a8000 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU2, DQ1) ADDR=0x2004b0000 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ0) ADDR=0x2004e8000 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU3, DQ1) ADDR=0x2004f0000 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU4, DQ0) ADDR=0x200528000 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU4, DQ1) ADDR=0x200530000 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU5, DQ0) ADDR=0x200568000 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU5, DQ1) ADDR=0x200570000 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU6, DQ0) ADDR=0x2005a8000 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU6, DQ1) ADDR=0x2005b0000 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU7, DQ0) ADDR=0x2005e8000 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPEN(MCU7, DQ1) ADDR=0x2005f0000 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU0) ADDR=0x200420d10 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU2) ADDR=0x2004a0d10 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU4) ADDR=0x200520d10 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU1) ADDR=0x200460d10 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU5) ADDR=0x200560d10 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU3) ADDR=0x2004e0d10 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x00000044, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU6) ADDR=0x2005a0d10 DWORD=0 NUMREGS=0 */ + 0x2005e0d9, //compressed WR cmd + 0x47464544, //compressed WR offset + 0x00434140, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F0(MCU7) ADDR=0x2005e0d10 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU7) ADDR=0x2005e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU7) ADDR=0x2005e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU7) ADDR=0x2005e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU7) ADDR=0x2005e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU7) ADDR=0x2005e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU7) ADDR=0x2005e0d0c DWORD=0 NUMREGS=0 */ + 0x200420d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU0) ADDR=0x200420d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU0) ADDR=0x200420d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU0) ADDR=0x200420d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU0) ADDR=0x200420d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU0) ADDR=0x200420d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU0) ADDR=0x200420d0c DWORD=0 NUMREGS=0 */ + 0x2004a0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU2) ADDR=0x2004a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU2) ADDR=0x2004a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU2) ADDR=0x2004a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU2) ADDR=0x2004a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU2) ADDR=0x2004a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU2) ADDR=0x2004a0d0c DWORD=0 NUMREGS=0 */ + 0x200520d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU4) ADDR=0x200520d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU4) ADDR=0x200520d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU4) ADDR=0x200520d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU4) ADDR=0x200520d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU4) ADDR=0x200520d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU4) ADDR=0x200520d0c DWORD=0 NUMREGS=0 */ + 0x200460d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU1) ADDR=0x200460d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU1) ADDR=0x200460d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU1) ADDR=0x200460d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU1) ADDR=0x200460d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU1) ADDR=0x200460d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU1) ADDR=0x200460d0c DWORD=0 NUMREGS=0 */ + 0x200560d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU5) ADDR=0x200560d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU5) ADDR=0x200560d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU5) ADDR=0x200560d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU5) ADDR=0x200560d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU5) ADDR=0x200560d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU5) ADDR=0x200560d0c DWORD=0 NUMREGS=0 */ + 0x2004e0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU3) ADDR=0x2004e0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU3) ADDR=0x2004e0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU3) ADDR=0x2004e0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU3) ADDR=0x2004e0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU3) ADDR=0x2004e0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU3) ADDR=0x2004e0d0c DWORD=0 NUMREGS=0 */ + 0x2005a0d5, //compressed WR cmd + 0x40474645, //compressed WR offset + 0x00004341, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F1(MCU6) ADDR=0x2005a0d14 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F2(MCU6) ADDR=0x2005a0d18 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCAODT_VREF_F3(MCU6) ADDR=0x2005a0d1c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F0(MCU6) ADDR=0x2005a0d00 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F1(MCU6) ADDR=0x2005a0d04 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPSCA_AMPSCAODT_ODTENABLE_F3(MCU6) ADDR=0x2005a0d0c DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x20052881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ0) ADDR=0x200528b00 DWORD=0 NUMREGS=0 */ + 0x20053081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ1) ADDR=0x200530b00 DWORD=0 NUMREGS=0 */ + 0x20056881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ0) ADDR=0x200568b00 DWORD=0 NUMREGS=0 */ + 0x20057081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ1) ADDR=0x200570b00 DWORD=0 NUMREGS=0 */ + 0x2005a881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ0) ADDR=0x2005a8b00 DWORD=0 NUMREGS=0 */ + 0x2005b081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ1) ADDR=0x2005b0b00 DWORD=0 NUMREGS=0 */ + 0x2005e881, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ0) ADDR=0x2005e8b00 DWORD=0 NUMREGS=0 */ + 0x2005f081, //compressed WR cmd + 0x000000c0, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ1) ADDR=0x2005f0b00 DWORD=0 NUMREGS=0 */ + 0x20042881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x20043081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x20046881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x20047081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x2004a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x2004b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x2004e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x2004f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x20052881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ0) ADDR=0x200528b04 DWORD=0 NUMREGS=0 */ + 0x20053081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ1) ADDR=0x200530b04 DWORD=0 NUMREGS=0 */ + 0x20056881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ0) ADDR=0x200568b04 DWORD=0 NUMREGS=0 */ + 0x20057081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ1) ADDR=0x200570b04 DWORD=0 NUMREGS=0 */ + 0x2005a881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ0) ADDR=0x2005a8b04 DWORD=0 NUMREGS=0 */ + 0x2005b081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ1) ADDR=0x2005b0b04 DWORD=0 NUMREGS=0 */ + 0x2005e881, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ0) ADDR=0x2005e8b04 DWORD=0 NUMREGS=0 */ + 0x2005f081, //compressed WR cmd + 0x000000c1, //compressed WR offset + 0x00c000c0, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ1) ADDR=0x2005f0b04 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU0) ADDR=0x200420718 DWORD=0 NUMREGS=0 */ + 0x2005a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU6) ADDR=0x2005a0718 DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU3) ADDR=0x2004e0718 DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU1) ADDR=0x200460718 DWORD=0 NUMREGS=0 */ + 0x20056041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU5) ADDR=0x200560718 DWORD=0 NUMREGS=0 */ + 0x20052041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU4) ADDR=0x200520718 DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU2) ADDR=0x2004a0718 DWORD=0 NUMREGS=0 */ + 0x2005e041, //compressed WR cmd + 0x000000c6, //compressed WR offset + 0x03030305, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATECTRL(MCU7) ADDR=0x2005e0718 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ0) ADDR=0x20042861c DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU0, DQ1) ADDR=0x20043061c DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ0) ADDR=0x20046861c DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU1, DQ1) ADDR=0x20047061c DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ0) ADDR=0x2004a861c DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU2, DQ1) ADDR=0x2004b061c DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ0) ADDR=0x2004e861c DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU3, DQ1) ADDR=0x2004f061c DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU4, DQ0) ADDR=0x20052861c DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU4, DQ1) ADDR=0x20053061c DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU5, DQ0) ADDR=0x20056861c DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU5, DQ1) ADDR=0x20057061c DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU6, DQ0) ADDR=0x2005a861c DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU6, DQ1) ADDR=0x2005b061c DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU7, DQ0) ADDR=0x2005e861c DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000087, //compressed WR offset + 0x00030005, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATECTRL(MCU7, DQ1) ADDR=0x2005f061c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ0) ADDR=0x200528608 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ1) ADDR=0x200530608 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ0) ADDR=0x200568608 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ1) ADDR=0x200570608 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ0) ADDR=0x2005a8608 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ1) ADDR=0x2005b0608 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ0) ADDR=0x2005e8608 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ1) ADDR=0x2005f0608 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ0) ADDR=0x200528608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20053042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ1) ADDR=0x200530608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ0) ADDR=0x200568608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20057042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ1) ADDR=0x200570608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ0) ADDR=0x2005a8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ1) ADDR=0x2005b0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ0) ADDR=0x2005e8608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ1) ADDR=0x2005f0608 DWORD=0 */ + 0x00000082, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ0) ADDR=0x200428608 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU0, DQ1) ADDR=0x200430608 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ0) ADDR=0x200468608 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU1, DQ1) ADDR=0x200470608 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ0) ADDR=0x2004a8608 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU2, DQ1) ADDR=0x2004b0608 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ0) ADDR=0x2004e8608 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU3, DQ1) ADDR=0x2004f0608 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ0) ADDR=0x200528608 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU4, DQ1) ADDR=0x200530608 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ0) ADDR=0x200568608 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU5, DQ1) ADDR=0x200570608 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ0) ADDR=0x2005a8608 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU6, DQ1) ADDR=0x2005b0608 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ0) ADDR=0x2005e8608 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000082, //compressed WR offset + 0x00ff0000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_RD0SDLLCTRL(MCU7, DQ1) ADDR=0x2005f0608 DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000002, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 NUMREGS=0 */ + 0x20042842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20053042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20057042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005b042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e842, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005f042, /* POLL:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 */ + 0x00000080, /* Offset */ + 0x00000002, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 NUMREGS=0 */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20056081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x20052081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 NUMREGS=0 */ + 0x2005a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2005e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff01ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 NUMREGS=0 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x20046081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x20056081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 NUMREGS=0 */ + 0x2005e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 NUMREGS=0 */ + 0x2004a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x2004e081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x2005a081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 NUMREGS=0 */ + 0x20052081, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00ff00ff, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU4) ADDR=0x200520198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU6) ADDR=0x2005a0198 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU5) ADDR=0x200560198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU7) ADDR=0x2005e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ0) ADDR=0x200528198 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ1) ADDR=0x200530198 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ0) ADDR=0x200568198 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ1) ADDR=0x200570198 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ0) ADDR=0x2005a8198 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ1) ADDR=0x2005b0198 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ0) ADDR=0x2005e8198 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00c801f4, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ1) ADDR=0x2005f0198 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU0) ADDR=0x200420f80 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU2) ADDR=0x2004a0f80 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU4) ADDR=0x200520f80 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU1) ADDR=0x200460f80 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU5) ADDR=0x200560f80 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU3) ADDR=0x2004e0f80 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x000000e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU6) ADDR=0x2005a0f80 DWORD=0 NUMREGS=0 */ + 0x2005e0c9, //compressed WR cmd + 0x00e2e1e0, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F1(MCU7) ADDR=0x2005e0f80 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU7) ADDR=0x2005e0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU7) ADDR=0x2005e0f88 DWORD=0 NUMREGS=0 */ + 0x200420c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU0) ADDR=0x200420f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU0) ADDR=0x200420f88 DWORD=0 NUMREGS=0 */ + 0x2004a0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU2) ADDR=0x2004a0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU2) ADDR=0x2004a0f88 DWORD=0 NUMREGS=0 */ + 0x200520c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU4) ADDR=0x200520f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU4) ADDR=0x200520f88 DWORD=0 NUMREGS=0 */ + 0x200460c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU1) ADDR=0x200460f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU1) ADDR=0x200460f88 DWORD=0 NUMREGS=0 */ + 0x200560c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU5) ADDR=0x200560f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU5) ADDR=0x200560f88 DWORD=0 NUMREGS=0 */ + 0x2004e0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU3) ADDR=0x2004e0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU3) ADDR=0x2004e0f88 DWORD=0 NUMREGS=0 */ + 0x2005a0c5, //compressed WR cmd + 0x0000e2e1, //compressed WR offset + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F2(MCU6) ADDR=0x2005a0f84 DWORD=0 NUMREGS=0 */ + 0x04000410, /* WR:AMPSCA_DFICALTIMING2_DFICALTIMING_F3(MCU6) ADDR=0x2005a0f88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ0) ADDR=0x200428d80 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU0, DQ1) ADDR=0x200430d80 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ0) ADDR=0x200468d80 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU1, DQ1) ADDR=0x200470d80 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ0) ADDR=0x2004a8d80 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU2, DQ1) ADDR=0x2004b0d80 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ0) ADDR=0x2004e8d80 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU3, DQ1) ADDR=0x2004f0d80 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU4, DQ0) ADDR=0x200528d80 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU4, DQ1) ADDR=0x200530d80 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU5, DQ0) ADDR=0x200568d80 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU5, DQ1) ADDR=0x200570d80 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU6, DQ0) ADDR=0x2005a8d80 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU6, DQ1) ADDR=0x2005b0d80 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU7, DQ0) ADDR=0x2005e8d80 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x06020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F0(MCU7, DQ1) ADDR=0x2005f0d80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ0) ADDR=0x200428d84 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU0, DQ1) ADDR=0x200430d84 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ0) ADDR=0x200468d84 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU1, DQ1) ADDR=0x200470d84 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ0) ADDR=0x2004a8d84 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU2, DQ1) ADDR=0x2004b0d84 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ0) ADDR=0x2004e8d84 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU3, DQ1) ADDR=0x2004f0d84 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU4, DQ0) ADDR=0x200528d84 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU4, DQ1) ADDR=0x200530d84 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU5, DQ0) ADDR=0x200568d84 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU5, DQ1) ADDR=0x200570d84 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU6, DQ0) ADDR=0x2005a8d84 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU6, DQ1) ADDR=0x2005b0d84 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU7, DQ0) ADDR=0x2005e8d84 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000061, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F1(MCU7, DQ1) ADDR=0x2005f0d84 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ0) ADDR=0x200428d88 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU0, DQ1) ADDR=0x200430d88 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ0) ADDR=0x200468d88 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU1, DQ1) ADDR=0x200470d88 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ0) ADDR=0x2004a8d88 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU2, DQ1) ADDR=0x2004b0d88 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ0) ADDR=0x2004e8d88 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU3, DQ1) ADDR=0x2004f0d88 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU4, DQ0) ADDR=0x200528d88 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU4, DQ1) ADDR=0x200530d88 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU5, DQ0) ADDR=0x200568d88 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU5, DQ1) ADDR=0x200570d88 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU6, DQ0) ADDR=0x2005a8d88 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU6, DQ1) ADDR=0x2005b0d88 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU7, DQ0) ADDR=0x2005e8d88 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000062, //compressed WR offset + 0x04020402, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F2(MCU7, DQ1) ADDR=0x2005f0d88 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ0) ADDR=0x200428d8c DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU0, DQ1) ADDR=0x200430d8c DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ0) ADDR=0x200468d8c DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU1, DQ1) ADDR=0x200470d8c DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ0) ADDR=0x2004a8d8c DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU2, DQ1) ADDR=0x2004b0d8c DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ0) ADDR=0x2004e8d8c DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU3, DQ1) ADDR=0x2004f0d8c DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU4, DQ0) ADDR=0x200528d8c DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU4, DQ1) ADDR=0x200530d8c DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU5, DQ0) ADDR=0x200568d8c DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU5, DQ1) ADDR=0x200570d8c DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU6, DQ0) ADDR=0x2005a8d8c DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU6, DQ1) ADDR=0x2005b0d8c DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU7, DQ0) ADDR=0x2005e8d8c DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x04020404, /* WR:AMPSDQ_DFICALTIMING_DFICALTIMING_F3(MCU7, DQ1) ADDR=0x2005f0d8c DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ0) ADDR=0x2004281cc DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU0, DQ1) ADDR=0x2004301cc DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ0) ADDR=0x2004681cc DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU1, DQ1) ADDR=0x2004701cc DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ0) ADDR=0x2004a81cc DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU2, DQ1) ADDR=0x2004b01cc DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ0) ADDR=0x2004e81cc DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU3, DQ1) ADDR=0x2004f01cc DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU4, DQ0) ADDR=0x2005281cc DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU4, DQ1) ADDR=0x2005301cc DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU5, DQ0) ADDR=0x2005681cc DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU5, DQ1) ADDR=0x2005701cc DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU6, DQ0) ADDR=0x2005a81cc DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU6, DQ1) ADDR=0x2005b01cc DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU7, DQ0) ADDR=0x2005e81cc DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000073, //compressed WR offset + 0x00000002, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLCODECAPTURECONTROL(MCU7, DQ1) ADDR=0x2005f01cc DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU0) ADDR=0x200420e00 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU2) ADDR=0x2004a0e00 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU4) ADDR=0x200520e00 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU1) ADDR=0x200460e00 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU5) ADDR=0x200560e00 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU3) ADDR=0x2004e0e00 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x00000080, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU6) ADDR=0x2005a0e00 DWORD=0 NUMREGS=0 */ + 0x2005e0fd, //compressed WR cmd + 0x86828180, //compressed WR offset + 0x8b8a8983, //compressed WR offset + 0xaaa9a88c, //compressed WR offset + 0x8f8eacab, //compressed WR offset + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F0(MCU7) ADDR=0x2005e0e00 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU7) ADDR=0x2005e0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU7) ADDR=0x2005e0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU7) ADDR=0x2005e0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU7) ADDR=0x2005e0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU7) ADDR=0x2005e0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU7) ADDR=0x2005e0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU7) ADDR=0x2005e0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU7) ADDR=0x2005e0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU7) ADDR=0x2005e0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU7) ADDR=0x2005e0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU7) ADDR=0x2005e0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU7) ADDR=0x2005e0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU7) ADDR=0x2005e0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU7) ADDR=0x2005e0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU7) ADDR=0x2005e0e3c DWORD=0 NUMREGS=0 */ + 0x2005e0cd, //compressed WR cmd + 0xa09f9190, //compressed WR offset + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU7) ADDR=0x2005e0e40 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU7) ADDR=0x2005e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU7) ADDR=0x2005e0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU7) ADDR=0x2005e0e80 DWORD=0 NUMREGS=0 */ + 0x200420fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU0) ADDR=0x200420e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU0) ADDR=0x200420e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU0) ADDR=0x200420e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU0) ADDR=0x200420e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU0) ADDR=0x200420e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU0) ADDR=0x200420e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU0) ADDR=0x200420e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU0) ADDR=0x200420e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU0) ADDR=0x200420ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU0) ADDR=0x200420ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU0) ADDR=0x200420ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU0) ADDR=0x200420eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU0) ADDR=0x200420eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU0) ADDR=0x200420e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU0) ADDR=0x200420e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU0) ADDR=0x200420e40 DWORD=0 NUMREGS=0 */ + 0x200420c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU0) ADDR=0x200420e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU0) ADDR=0x200420e80 DWORD=0 NUMREGS=0 */ + 0x2004a0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU2) ADDR=0x2004a0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU2) ADDR=0x2004a0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU2) ADDR=0x2004a0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU2) ADDR=0x2004a0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU2) ADDR=0x2004a0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU2) ADDR=0x2004a0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU2) ADDR=0x2004a0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU2) ADDR=0x2004a0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU2) ADDR=0x2004a0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU2) ADDR=0x2004a0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU2) ADDR=0x2004a0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU2) ADDR=0x2004a0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU2) ADDR=0x2004a0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e40 DWORD=0 NUMREGS=0 */ + 0x2004a0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU2) ADDR=0x2004a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU2) ADDR=0x2004a0e80 DWORD=0 NUMREGS=0 */ + 0x200520fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU4) ADDR=0x200520e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU4) ADDR=0x200520e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU4) ADDR=0x200520e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU4) ADDR=0x200520e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU4) ADDR=0x200520e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU4) ADDR=0x200520e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU4) ADDR=0x200520e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU4) ADDR=0x200520e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU4) ADDR=0x200520ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU4) ADDR=0x200520ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU4) ADDR=0x200520ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU4) ADDR=0x200520eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU4) ADDR=0x200520eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU4) ADDR=0x200520e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU4) ADDR=0x200520e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU4) ADDR=0x200520e40 DWORD=0 NUMREGS=0 */ + 0x200520c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU4) ADDR=0x200520e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU4) ADDR=0x200520e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU4) ADDR=0x200520e80 DWORD=0 NUMREGS=0 */ + 0x200460fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU1) ADDR=0x200460e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU1) ADDR=0x200460e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU1) ADDR=0x200460e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU1) ADDR=0x200460e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU1) ADDR=0x200460e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU1) ADDR=0x200460e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU1) ADDR=0x200460e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU1) ADDR=0x200460e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU1) ADDR=0x200460ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU1) ADDR=0x200460ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU1) ADDR=0x200460ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU1) ADDR=0x200460eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU1) ADDR=0x200460eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU1) ADDR=0x200460e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU1) ADDR=0x200460e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU1) ADDR=0x200460e40 DWORD=0 NUMREGS=0 */ + 0x200460c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU1) ADDR=0x200460e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU1) ADDR=0x200460e80 DWORD=0 NUMREGS=0 */ + 0x200560fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU5) ADDR=0x200560e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU5) ADDR=0x200560e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU5) ADDR=0x200560e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU5) ADDR=0x200560e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU5) ADDR=0x200560e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU5) ADDR=0x200560e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU5) ADDR=0x200560e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU5) ADDR=0x200560e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU5) ADDR=0x200560ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU5) ADDR=0x200560ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU5) ADDR=0x200560ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU5) ADDR=0x200560eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU5) ADDR=0x200560eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU5) ADDR=0x200560e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU5) ADDR=0x200560e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU5) ADDR=0x200560e40 DWORD=0 NUMREGS=0 */ + 0x200560c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU5) ADDR=0x200560e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU5) ADDR=0x200560e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU5) ADDR=0x200560e80 DWORD=0 NUMREGS=0 */ + 0x2004e0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU3) ADDR=0x2004e0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU3) ADDR=0x2004e0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU3) ADDR=0x2004e0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU3) ADDR=0x2004e0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU3) ADDR=0x2004e0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU3) ADDR=0x2004e0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU3) ADDR=0x2004e0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU3) ADDR=0x2004e0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU3) ADDR=0x2004e0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU3) ADDR=0x2004e0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU3) ADDR=0x2004e0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU3) ADDR=0x2004e0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU3) ADDR=0x2004e0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e40 DWORD=0 NUMREGS=0 */ + 0x2004e0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU3) ADDR=0x2004e0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU3) ADDR=0x2004e0e80 DWORD=0 NUMREGS=0 */ + 0x2005a0fd, //compressed WR cmd + 0x83868281, //compressed WR offset + 0x8c8b8a89, //compressed WR offset + 0xabaaa9a8, //compressed WR offset + 0x908f8eac, //compressed WR offset + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F0(MCU6) ADDR=0x2005a0e04 DWORD=0 NUMREGS=0 */ + 0x01040402, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F1(MCU6) ADDR=0x2005a0e08 DWORD=0 NUMREGS=0 */ + 0x01040508, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALTIMING_F3(MCU6) ADDR=0x2005a0e18 DWORD=0 NUMREGS=0 */ + 0x000c0012, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDWRDQCALSEGLEN_F1(MCU6) ADDR=0x2005a0e0c DWORD=0 NUMREGS=0 */ + 0x0000381e, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL1(MCU6) ADDR=0x2005a0e24 DWORD=0 NUMREGS=0 */ + 0x01141101, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALTIMINGCTRL2(MCU6) ADDR=0x2005a0e28 DWORD=0 NUMREGS=0 */ + 0x55553c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALPATPRBS4I(MCU6) ADDR=0x2005a0e2c DWORD=0 NUMREGS=0 */ + 0x00003c5a, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS4I(MCU6) ADDR=0x2005a0e30 DWORD=0 NUMREGS=0 */ + 0x87654321, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_0(MCU6) ADDR=0x2005a0ea0 DWORD=0 NUMREGS=0 */ + 0xcdedcba9, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_1(MCU6) ADDR=0x2005a0ea4 DWORD=0 NUMREGS=0 */ + 0x456789ab, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_2(MCU6) ADDR=0x2005a0ea8 DWORD=0 NUMREGS=0 */ + 0x5fa63123, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATPRBS7_3(MCU6) ADDR=0x2005a0eac DWORD=0 NUMREGS=0 */ + 0x55550000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALPATINVERTMASK(MCU6) ADDR=0x2005a0eb0 DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F0(MCU6) ADDR=0x2005a0e38 DWORD=0 NUMREGS=0 */ + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F0(MCU6) ADDR=0x2005a0e3c DWORD=0 NUMREGS=0 */ + 0x00ff01d1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALWINDOW_F1(MCU6) ADDR=0x2005a0e40 DWORD=0 NUMREGS=0 */ + 0x2005a0c9, //compressed WR cmd + 0x00a09f91, //compressed WR offset + 0x00ff0160, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALWINDOW_F1(MCU6) ADDR=0x2005a0e44 DWORD=0 NUMREGS=0 */ + 0x00a01414, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXRDDQSSDLLMULFACTOR(MCU6) ADDR=0x2005a0e7c DWORD=0 NUMREGS=0 */ + 0xa0a00c0d, /* WR:AMPSCA_AMPSCARDWRDQCAL_MAXWRDQSSDLLMULFACTOR(MCU6) ADDR=0x2005a0e80 DWORD=0 NUMREGS=0 */ + 0x200428c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ0) ADDR=0x200428d00 DWORD=0 NUMREGS=0 */ + 0x200430c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU0, DQ1) ADDR=0x200430d00 DWORD=0 NUMREGS=0 */ + 0x200468c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ0) ADDR=0x200468d00 DWORD=0 NUMREGS=0 */ + 0x200470c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU1, DQ1) ADDR=0x200470d00 DWORD=0 NUMREGS=0 */ + 0x2004a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ0) ADDR=0x2004a8d00 DWORD=0 NUMREGS=0 */ + 0x2004b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU2, DQ1) ADDR=0x2004b0d00 DWORD=0 NUMREGS=0 */ + 0x2004e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ0) ADDR=0x2004e8d00 DWORD=0 NUMREGS=0 */ + 0x2004f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU3, DQ1) ADDR=0x2004f0d00 DWORD=0 NUMREGS=0 */ + 0x200528c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU4, DQ0) ADDR=0x200528d00 DWORD=0 NUMREGS=0 */ + 0x200530c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU4, DQ1) ADDR=0x200530d00 DWORD=0 NUMREGS=0 */ + 0x200568c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU5, DQ0) ADDR=0x200568d00 DWORD=0 NUMREGS=0 */ + 0x200570c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU5, DQ1) ADDR=0x200570d00 DWORD=0 NUMREGS=0 */ + 0x2005a8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU6, DQ0) ADDR=0x2005a8d00 DWORD=0 NUMREGS=0 */ + 0x2005b0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU6, DQ1) ADDR=0x2005b0d00 DWORD=0 NUMREGS=0 */ + 0x2005e8c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU7, DQ0) ADDR=0x2005e8d00 DWORD=0 NUMREGS=0 */ + 0x2005f0c1, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x20181000, /* WR:AMPSDQ_AMPSDQMULFACTOR_RDDQSMULFACTOR(MCU7, DQ1) ADDR=0x2005f0d00 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ0) ADDR=0x200428100 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU0, DQ1) ADDR=0x200430100 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ0) ADDR=0x200468100 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU1, DQ1) ADDR=0x200470100 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ0) ADDR=0x2004a8100 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU2, DQ1) ADDR=0x2004b0100 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ0) ADDR=0x2004e8100 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU3, DQ1) ADDR=0x2004f0100 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU4, DQ0) ADDR=0x200528100 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU4, DQ1) ADDR=0x200530100 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU5, DQ0) ADDR=0x200568100 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU5, DQ1) ADDR=0x200570100 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU6, DQ0) ADDR=0x2005a8100 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU6, DQ1) ADDR=0x2005b0100 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU7, DQ0) ADDR=0x2005e8100 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x01000810, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ0(MCU7, DQ1) ADDR=0x2005f0100 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ0) ADDR=0x200428104 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU0, DQ1) ADDR=0x200430104 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ0) ADDR=0x200468104 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU1, DQ1) ADDR=0x200470104 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ0) ADDR=0x2004a8104 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU2, DQ1) ADDR=0x2004b0104 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ0) ADDR=0x2004e8104 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU3, DQ1) ADDR=0x2004f0104 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU4, DQ0) ADDR=0x200528104 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU4, DQ1) ADDR=0x200530104 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU5, DQ0) ADDR=0x200568104 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU5, DQ1) ADDR=0x200570104 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU6, DQ0) ADDR=0x2005a8104 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU6, DQ1) ADDR=0x2005b0104 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU7, DQ0) ADDR=0x2005e8104 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000041, //compressed WR offset + 0x2100060a, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ1(MCU7, DQ1) ADDR=0x2005f0104 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ0) ADDR=0x200428108 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU0, DQ1) ADDR=0x200430108 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ0) ADDR=0x200468108 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU1, DQ1) ADDR=0x200470108 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ0) ADDR=0x2004a8108 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU2, DQ1) ADDR=0x2004b0108 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ0) ADDR=0x2004e8108 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU3, DQ1) ADDR=0x2004f0108 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU4, DQ0) ADDR=0x200528108 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU4, DQ1) ADDR=0x200530108 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU5, DQ0) ADDR=0x200568108 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU5, DQ1) ADDR=0x200570108 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU6, DQ0) ADDR=0x2005a8108 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU6, DQ1) ADDR=0x2005b0108 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU7, DQ0) ADDR=0x2005e8108 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000042, //compressed WR offset + 0x41000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ2(MCU7, DQ1) ADDR=0x2005f0108 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ0) ADDR=0x20042810c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU0, DQ1) ADDR=0x20043010c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ0) ADDR=0x20046810c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU1, DQ1) ADDR=0x20047010c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ0) ADDR=0x2004a810c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU2, DQ1) ADDR=0x2004b010c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ0) ADDR=0x2004e810c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU3, DQ1) ADDR=0x2004f010c DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU4, DQ0) ADDR=0x20052810c DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU4, DQ1) ADDR=0x20053010c DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU5, DQ0) ADDR=0x20056810c DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU5, DQ1) ADDR=0x20057010c DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU6, DQ0) ADDR=0x2005a810c DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU6, DQ1) ADDR=0x2005b010c DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU7, DQ0) ADDR=0x2005e810c DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000043, //compressed WR offset + 0x61000408, /* WR:AMPSDQ_AMPSDQRDTIM_RDCAPCFG_FREQ3(MCU7, DQ1) ADDR=0x2005f010c DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU0) ADDR=0x2004201a4 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU4) ADDR=0x2005201a4 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU2) ADDR=0x2004a01a4 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU6) ADDR=0x2005a01a4 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU3) ADDR=0x2004e01a4 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU1) ADDR=0x2004601a4 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU5) ADDR=0x2005601a4 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTCTRL(MCU7) ADDR=0x2005e01a4 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ0) ADDR=0x2004281a4 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU0, DQ1) ADDR=0x2004301a4 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ0) ADDR=0x2004681a4 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU1, DQ1) ADDR=0x2004701a4 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ0) ADDR=0x2004a81a4 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU2, DQ1) ADDR=0x2004b01a4 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ0) ADDR=0x2004e81a4 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU3, DQ1) ADDR=0x2004f01a4 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ0) ADDR=0x2005281a4 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU4, DQ1) ADDR=0x2005301a4 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ0) ADDR=0x2005681a4 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU5, DQ1) ADDR=0x2005701a4 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ0) ADDR=0x2005a81a4 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU6, DQ1) ADDR=0x2005b01a4 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ0) ADDR=0x2005e81a4 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000069, //compressed WR offset + 0x80017580, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCTRL(MCU7, DQ1) ADDR=0x2005f01a4 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU0) ADDR=0x2004201a0 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU4) ADDR=0x2005201a0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU2) ADDR=0x2004a01a0 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU6) ADDR=0x2005a01a0 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU3) ADDR=0x2004e01a0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU1) ADDR=0x2004601a0 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU5) ADDR=0x2005601a0 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSCA_AMPSCADLLCTL_DLLUPDTINTVL(MCU7) ADDR=0x2005e01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ0) ADDR=0x2004281a0 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU0, DQ1) ADDR=0x2004301a0 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ0) ADDR=0x2004681a0 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU1, DQ1) ADDR=0x2004701a0 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ0) ADDR=0x2004a81a0 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU2, DQ1) ADDR=0x2004b01a0 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ0) ADDR=0x2004e81a0 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU3, DQ1) ADDR=0x2004f01a0 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU4, DQ0) ADDR=0x2005281a0 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU4, DQ1) ADDR=0x2005301a0 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU5, DQ0) ADDR=0x2005681a0 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU5, DQ1) ADDR=0x2005701a0 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU6, DQ0) ADDR=0x2005a81a0 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU6, DQ1) ADDR=0x2005b01a0 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU7, DQ0) ADDR=0x2005e81a0 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000068, //compressed WR offset + 0x10200020, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTINTVL(MCU7, DQ1) ADDR=0x2005f01a0 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ0) ADDR=0x200428180 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU0, DQ1) ADDR=0x200430180 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ0) ADDR=0x200468180 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU1, DQ1) ADDR=0x200470180 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ0) ADDR=0x2004a8180 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU2, DQ1) ADDR=0x2004b0180 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ0) ADDR=0x2004e8180 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU3, DQ1) ADDR=0x2004f0180 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU4, DQ0) ADDR=0x200528180 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU4, DQ1) ADDR=0x200530180 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU5, DQ0) ADDR=0x200568180 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU5, DQ1) ADDR=0x200570180 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU6, DQ0) ADDR=0x2005a8180 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU6, DQ1) ADDR=0x2005b0180 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU7, DQ0) ADDR=0x2005e8180 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000060, //compressed WR offset + 0x00000100, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLEN(MCU7, DQ1) ADDR=0x2005f0180 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU0) ADDR=0x2004200dc DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU4) ADDR=0x2005200dc DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU2) ADDR=0x2004a00dc DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU6) ADDR=0x2005a00dc DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU3) ADDR=0x2004e00dc DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU1) ADDR=0x2004600dc DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000037, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU5) ADDR=0x2005600dc DWORD=0 NUMREGS=0 */ + 0x2005e005, //compressed WR cmd + 0x00003837, //compressed WR offset + 0x10050b27, /* WR:AMPSCA_AMPSCAIOCFG_DCCCONTROL(MCU7) ADDR=0x2005e00dc DWORD=0 NUMREGS=0 */ + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU7) ADDR=0x2005e00e0 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU0) ADDR=0x2004200e0 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU4) ADDR=0x2005200e0 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU2) ADDR=0x2004a00e0 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU6) ADDR=0x2005a00e0 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU3) ADDR=0x2004e00e0 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU1) ADDR=0x2004600e0 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000038, //compressed WR offset + 0x00000190, /* WR:AMPSCA_AMPSCAIOCFG_DCCTIMER(MCU5) ADDR=0x2005600e0 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU0) ADDR=0x200420ecc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU1) ADDR=0x200460ecc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU2) ADDR=0x2004a0ecc DWORD=0 NUMREGS=0 */ + 0x2005e0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU7) ADDR=0x2005e0ecc DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU4) ADDR=0x200520ecc DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU3) ADDR=0x2004e0ecc DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU5) ADDR=0x200560ecc DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x000000b3, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALDYNAMICHALFCLKDELAYCONTROL(MCU6) ADDR=0x2005a0ecc DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU0) ADDR=0x200438030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU0) ADDR=0x200438028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU0) ADDR=0x200438044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU0) ADDR=0x200438058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU0) ADDR=0x200438068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU0) ADDR=0x200438050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU0) ADDR=0x200438060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU0) ADDR=0x200438078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU0) ADDR=0x200438080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU0) ADDR=0x2004380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU0) ADDR=0x2004380b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU0) ADDR=0x2004380b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU0) ADDR=0x2004380e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU0) ADDR=0x200438120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU0) ADDR=0x2004380f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU0) ADDR=0x20043810c DWORD=0 NUMREGS=0 */ + 0x2004383d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU0) ADDR=0x20043811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU0) ADDR=0x2004380c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU0) ADDR=0x2004380d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU0) ADDR=0x2004380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU0) ADDR=0x2004380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU0) ADDR=0x2004380e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU0) ADDR=0x200438130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU0) ADDR=0x200438140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU0) ADDR=0x200438148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU0) ADDR=0x200438150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU0) ADDR=0x20043814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU0) ADDR=0x200438024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU0) ADDR=0x20043800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU0) ADDR=0x200438008 DWORD=0 NUMREGS=0 */ + 0x20043801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU0) ADDR=0x2004382fc DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU1) ADDR=0x200478030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU1) ADDR=0x200478028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU1) ADDR=0x200478044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU1) ADDR=0x200478058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU1) ADDR=0x200478068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU1) ADDR=0x200478050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU1) ADDR=0x200478060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU1) ADDR=0x200478078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU1) ADDR=0x200478080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU1) ADDR=0x2004780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU1) ADDR=0x2004780b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU1) ADDR=0x2004780b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU1) ADDR=0x2004780e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU1) ADDR=0x200478120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU1) ADDR=0x2004780f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU1) ADDR=0x20047810c DWORD=0 NUMREGS=0 */ + 0x2004783d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU1) ADDR=0x20047811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU1) ADDR=0x2004780c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU1) ADDR=0x2004780d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU1) ADDR=0x2004780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU1) ADDR=0x2004780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU1) ADDR=0x2004780e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU1) ADDR=0x200478130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU1) ADDR=0x200478140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU1) ADDR=0x200478148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU1) ADDR=0x200478150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU1) ADDR=0x20047814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU1) ADDR=0x200478024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU1) ADDR=0x20047800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU1) ADDR=0x200478008 DWORD=0 NUMREGS=0 */ + 0x20047801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU1) ADDR=0x2004782fc DWORD=0 NUMREGS=0 */ + 0x2005b83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU6) ADDR=0x2005b8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU6) ADDR=0x2005b8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU6) ADDR=0x2005b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU6) ADDR=0x2005b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU6) ADDR=0x2005b8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU6) ADDR=0x2005b8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU6) ADDR=0x2005b8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU6) ADDR=0x2005b8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU6) ADDR=0x2005b8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU6) ADDR=0x2005b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU6) ADDR=0x2005b80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU6) ADDR=0x2005b80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU6) ADDR=0x2005b80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU6) ADDR=0x2005b8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU6) ADDR=0x2005b80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU6) ADDR=0x2005b810c DWORD=0 NUMREGS=0 */ + 0x2005b83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU6) ADDR=0x2005b811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU6) ADDR=0x2005b80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU6) ADDR=0x2005b80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU6) ADDR=0x2005b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU6) ADDR=0x2005b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU6) ADDR=0x2005b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU6) ADDR=0x2005b80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU6) ADDR=0x2005b8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU6) ADDR=0x2005b8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU6) ADDR=0x2005b8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU6) ADDR=0x2005b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU6) ADDR=0x2005b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU6) ADDR=0x2005b814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU6) ADDR=0x2005b8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU6) ADDR=0x2005b800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU6) ADDR=0x2005b8008 DWORD=0 NUMREGS=0 */ + 0x2005b801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU6) ADDR=0x2005b82fc DWORD=0 NUMREGS=0 */ + 0x2005783d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU5) ADDR=0x200578030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU5) ADDR=0x200578028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU5) ADDR=0x200578044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU5) ADDR=0x200578058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU5) ADDR=0x200578068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU5) ADDR=0x200578050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU5) ADDR=0x200578060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU5) ADDR=0x200578078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU5) ADDR=0x200578080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU5) ADDR=0x2005780a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU5) ADDR=0x2005780b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU5) ADDR=0x2005780b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU5) ADDR=0x2005780e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU5) ADDR=0x200578120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU5) ADDR=0x2005780f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU5) ADDR=0x20057810c DWORD=0 NUMREGS=0 */ + 0x2005783d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU5) ADDR=0x20057811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU5) ADDR=0x2005780c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU5) ADDR=0x2005780c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU5) ADDR=0x2005780d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU5) ADDR=0x2005780d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU5) ADDR=0x2005780dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU5) ADDR=0x2005780e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU5) ADDR=0x200578138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU5) ADDR=0x200578130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU5) ADDR=0x200578140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU5) ADDR=0x200578148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU5) ADDR=0x200578150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU5) ADDR=0x20057814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU5) ADDR=0x200578024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU5) ADDR=0x20057800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU5) ADDR=0x200578008 DWORD=0 NUMREGS=0 */ + 0x20057801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU5) ADDR=0x2005782fc DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU2) ADDR=0x2004b8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU2) ADDR=0x2004b8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU2) ADDR=0x2004b8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU2) ADDR=0x2004b8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU2) ADDR=0x2004b8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU2) ADDR=0x2004b8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU2) ADDR=0x2004b8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU2) ADDR=0x2004b8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU2) ADDR=0x2004b8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU2) ADDR=0x2004b80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU2) ADDR=0x2004b80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU2) ADDR=0x2004b80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU2) ADDR=0x2004b80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU2) ADDR=0x2004b8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU2) ADDR=0x2004b80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU2) ADDR=0x2004b810c DWORD=0 NUMREGS=0 */ + 0x2004b83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU2) ADDR=0x2004b811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU2) ADDR=0x2004b80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU2) ADDR=0x2004b80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU2) ADDR=0x2004b80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU2) ADDR=0x2004b80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU2) ADDR=0x2004b80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU2) ADDR=0x2004b8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU2) ADDR=0x2004b8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU2) ADDR=0x2004b8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU2) ADDR=0x2004b8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU2) ADDR=0x2004b814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU2) ADDR=0x2004b8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU2) ADDR=0x2004b800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU2) ADDR=0x2004b8008 DWORD=0 NUMREGS=0 */ + 0x2004b801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU2) ADDR=0x2004b82fc DWORD=0 NUMREGS=0 */ + 0x2005383d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU4) ADDR=0x200538030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU4) ADDR=0x200538028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU4) ADDR=0x200538044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU4) ADDR=0x200538058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU4) ADDR=0x200538068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU4) ADDR=0x200538050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU4) ADDR=0x200538060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU4) ADDR=0x200538078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU4) ADDR=0x200538080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU4) ADDR=0x2005380a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU4) ADDR=0x2005380b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU4) ADDR=0x2005380b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU4) ADDR=0x2005380e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU4) ADDR=0x200538120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU4) ADDR=0x2005380f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU4) ADDR=0x20053810c DWORD=0 NUMREGS=0 */ + 0x2005383d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU4) ADDR=0x20053811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU4) ADDR=0x2005380c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU4) ADDR=0x2005380c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU4) ADDR=0x2005380d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU4) ADDR=0x2005380d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU4) ADDR=0x2005380dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU4) ADDR=0x2005380e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU4) ADDR=0x200538138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU4) ADDR=0x200538130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU4) ADDR=0x200538140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU4) ADDR=0x200538148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU4) ADDR=0x200538150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU4) ADDR=0x20053814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU4) ADDR=0x200538024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU4) ADDR=0x20053800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU4) ADDR=0x200538008 DWORD=0 NUMREGS=0 */ + 0x20053801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU4) ADDR=0x2005382fc DWORD=0 NUMREGS=0 */ + 0x2005f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU7) ADDR=0x2005f8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU7) ADDR=0x2005f8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU7) ADDR=0x2005f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU7) ADDR=0x2005f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU7) ADDR=0x2005f8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU7) ADDR=0x2005f8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU7) ADDR=0x2005f8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU7) ADDR=0x2005f8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU7) ADDR=0x2005f8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU7) ADDR=0x2005f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU7) ADDR=0x2005f80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU7) ADDR=0x2005f80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU7) ADDR=0x2005f80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU7) ADDR=0x2005f8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU7) ADDR=0x2005f80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU7) ADDR=0x2005f810c DWORD=0 NUMREGS=0 */ + 0x2005f83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU7) ADDR=0x2005f811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU7) ADDR=0x2005f80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU7) ADDR=0x2005f80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU7) ADDR=0x2005f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU7) ADDR=0x2005f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU7) ADDR=0x2005f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU7) ADDR=0x2005f80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU7) ADDR=0x2005f8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU7) ADDR=0x2005f8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU7) ADDR=0x2005f8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU7) ADDR=0x2005f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU7) ADDR=0x2005f8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU7) ADDR=0x2005f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU7) ADDR=0x2005f8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU7) ADDR=0x2005f800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU7) ADDR=0x2005f8008 DWORD=0 NUMREGS=0 */ + 0x2005f801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU7) ADDR=0x2005f82fc DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x16110a0c, //compressed WR offset + 0x1e18141a, //compressed WR offset + 0x2d2c2820, //compressed WR offset + 0x433c483a, //compressed WR offset + 0x00000000, /* WR:AMPH_CFGH_CB_WKPUPD(MCU3) ADDR=0x2004f8030 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CB_DRIVE_STR(MCU3) ADDR=0x2004f8028 DWORD=0 NUMREGS=0 */ + 0x00020023, /* WR:AMPH_CFGH_CB_IOCTL(MCU3) ADDR=0x2004f8044 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_WKPUPD(MCU3) ADDR=0x2004f8058 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_CK_ZDET_BIASEN(MCU3) ADDR=0x2004f8068 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_CK_DRIVE_STR(MCU3) ADDR=0x2004f8050 DWORD=0 NUMREGS=0 */ + 0x00000027, /* WR:AMPH_CFGH_CK_IOCTL(MCU3) ADDR=0x2004f8060 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B0_DRIVE_STR(MCU3) ADDR=0x2004f8078 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B0_WKPUPD(MCU3) ADDR=0x2004f8080 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B0_IOCTL(MCU3) ADDR=0x2004f80a0 DWORD=0 NUMREGS=0 */ + 0x01c00333, /* WR:AMPH_CFGH_B0_ODT(MCU3) ADDR=0x2004f80b0 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B0_ODTCTRL(MCU3) ADDR=0x2004f80b4 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_B1_DRIVE_STR(MCU3) ADDR=0x2004f80e8 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_B1_ODTCTRL(MCU3) ADDR=0x2004f8120 DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_B1_WKPUPD(MCU3) ADDR=0x2004f80f0 DWORD=0 NUMREGS=0 */ + 0x71500027, /* WR:AMPH_CFGH_B1_IOCTL(MCU3) ADDR=0x2004f810c DWORD=0 NUMREGS=0 */ + 0x2004f83d, //compressed WR cmd + 0x34303247, //compressed WR offset + 0x4e383736, //compressed WR offset + 0x5452504c, //compressed WR offset + 0x02030953, //compressed WR offset + 0x01c00333, /* WR:AMPH_CFGH_B1_ODT(MCU3) ADDR=0x2004f811c DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS0_DRIVE_STR(MCU3) ADDR=0x2004f80c0 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS0_IOCTL(MCU3) ADDR=0x2004f80d0 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS0_ODT(MCU3) ADDR=0x2004f80d8 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS0_ZDET_BIASEN(MCU3) ADDR=0x2004f80dc DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS0_ODTCTRL(MCU3) ADDR=0x2004f80e0 DWORD=0 NUMREGS=0 */ + 0x00000782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x33838317, /* WR:AMPH_CFGH_DQS1_DRIVE_STR(MCU3) ADDR=0x2004f8130 DWORD=0 NUMREGS=0 */ + 0x71500007, /* WR:AMPH_CFGH_DQS1_IOCTL(MCU3) ADDR=0x2004f8140 DWORD=0 NUMREGS=0 */ + 0x01c00336, /* WR:AMPH_CFGH_DQS1_ODT(MCU3) ADDR=0x2004f8148 DWORD=0 NUMREGS=0 */ + 0x00060028, /* WR:AMPH_CFGH_DQS1_ZDET_BIASEN(MCU3) ADDR=0x2004f8150 DWORD=0 NUMREGS=0 */ + 0x00000007, /* WR:AMPH_CFGH_DQS1_ODTCTRL(MCU3) ADDR=0x2004f814c DWORD=0 NUMREGS=0 */ + 0x00000000, /* WR:AMPH_CFGH_DBG_DBG_REG0(MCU3) ADDR=0x2004f8024 DWORD=0 NUMREGS=0 */ + 0x00887f7f, /* WR:AMPH_CFGH_ZC_ZCAL_FSM1(MCU3) ADDR=0x2004f800c DWORD=0 NUMREGS=0 */ + 0x000f031b, /* WR:AMPH_CFGH_ZC_ZCAL_FSM0(MCU3) ADDR=0x2004f8008 DWORD=0 NUMREGS=0 */ + 0x2004f801, //compressed WR cmd + 0x000000bf, //compressed WR offset + 0x00000016, /* WR:AMPH_CFGH_DEBUG_SPARE0(MCU3) ADDR=0x2004f82fc DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU0) ADDR=0x200420008 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU1) ADDR=0x200460008 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU4) ADDR=0x200520008 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU2) ADDR=0x2004a0008 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU6) ADDR=0x2005a0008 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU5) ADDR=0x200560008 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU3) ADDR=0x2004e0008 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAGEN_AMPINIT(MCU7) ADDR=0x2005e0008 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ0) ADDR=0x200428008 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU0, DQ1) ADDR=0x200430008 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ0) ADDR=0x200468008 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU1, DQ1) ADDR=0x200470008 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ0) ADDR=0x2004a8008 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU2, DQ1) ADDR=0x2004b0008 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ0) ADDR=0x2004e8008 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU3, DQ1) ADDR=0x2004f0008 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU4, DQ0) ADDR=0x200528008 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU4, DQ1) ADDR=0x200530008 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU5, DQ0) ADDR=0x200568008 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU5, DQ1) ADDR=0x200570008 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU6, DQ0) ADDR=0x2005a8008 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU6, DQ1) ADDR=0x2005b0008 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU7, DQ0) ADDR=0x2005e8008 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000002, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQGEN_AMPINIT(MCU7, DQ1) ADDR=0x2005f0008 DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU0) ADDR=0x200420e74 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU2) ADDR=0x2004a0e74 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU4) ADDR=0x200520e74 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU1) ADDR=0x200460e74 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU5) ADDR=0x200560e74 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU3) ADDR=0x2004e0e74 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x0000009d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU6) ADDR=0x2005a0e74 DWORD=0 NUMREGS=0 */ + 0x2005e0c5, //compressed WR cmd + 0x0000b79d, //compressed WR offset + 0x06000504, /* WR:AMPSCA_AMPSCARDWRDQCAL_DFICALTIMING(MCU7) ADDR=0x2005e0e74 DWORD=0 NUMREGS=0 */ + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU7) ADDR=0x2005e0edc DWORD=0 NUMREGS=0 */ + 0x200420c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU0) ADDR=0x200420edc DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU2) ADDR=0x2004a0edc DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU4) ADDR=0x200520edc DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU1) ADDR=0x200460edc DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU5) ADDR=0x200560edc DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU3) ADDR=0x2004e0edc DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x000000b7, //compressed WR offset + 0x08080808, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALTVREF(MCU6) ADDR=0x2005a0edc DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU4) ADDR=0x200500418 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU7) ADDR=0x2005c0418 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU5) ADDR=0x200540418 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000006, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU6) ADDR=0x200580418 DWORD=0 NUMREGS=0 */ + 0x20040011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU0) ADDR=0x2004003bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU0) ADDR=0x2004003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU0) ADDR=0x2004003b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU0) ADDR=0x2004003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU0) ADDR=0x2004003fc DWORD=0 NUMREGS=0 */ + 0x20044011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU1) ADDR=0x2004403bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU1) ADDR=0x2004403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU1) ADDR=0x2004403b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU1) ADDR=0x2004403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU1) ADDR=0x2004403fc DWORD=0 NUMREGS=0 */ + 0x20050011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU4) ADDR=0x2005003bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU4) ADDR=0x2005003b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU4) ADDR=0x2005003b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU4) ADDR=0x2005003b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU4) ADDR=0x2005003fc DWORD=0 NUMREGS=0 */ + 0x20058011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU6) ADDR=0x2005803bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU6) ADDR=0x2005803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU6) ADDR=0x2005803b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU6) ADDR=0x2005803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU6) ADDR=0x2005803fc DWORD=0 NUMREGS=0 */ + 0x20054011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU5) ADDR=0x2005403bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU5) ADDR=0x2005403b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU5) ADDR=0x2005403b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU5) ADDR=0x2005403b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU5) ADDR=0x2005403fc DWORD=0 NUMREGS=0 */ + 0x2004c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU3) ADDR=0x2004c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU3) ADDR=0x2004c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU3) ADDR=0x2004c03b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU3) ADDR=0x2004c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU3) ADDR=0x2004c03fc DWORD=0 NUMREGS=0 */ + 0x2005c011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU7) ADDR=0x2005c03bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU7) ADDR=0x2005c03b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU7) ADDR=0x2005c03b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU7) ADDR=0x2005c03b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU7) ADDR=0x2005c03fc DWORD=0 NUMREGS=0 */ + 0x20048011, //compressed WR cmd + 0xecedeeef, //compressed WR offset + 0x000000ff, //compressed WR offset + 0x03050005, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ3(MCU2) ADDR=0x2004803bc DWORD=0 NUMREGS=0 */ + 0x09120013, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ2(MCU2) ADDR=0x2004803b8 DWORD=0 NUMREGS=0 */ + 0x24480049, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ1(MCU2) ADDR=0x2004803b4 DWORD=0 NUMREGS=0 */ + 0x48900092, /* WR:AMCX_DRAMTIM_AUTOREF_FREQ0(MCU2) ADDR=0x2004803b0 DWORD=0 NUMREGS=0 */ + 0x0017005d, /* WR:AMCX_DRAMTIM_AUTOREF_PARAMS(MCU2) ADDR=0x2004803fc DWORD=0 NUMREGS=0 */ + 0x20040049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU0) ADDR=0x20040041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU0) ADDR=0x20040043c DWORD=0 NUMREGS=0 */ + 0x20044049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU1) ADDR=0x20044041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU1) ADDR=0x20044043c DWORD=0 NUMREGS=0 */ + 0x2004c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU3) ADDR=0x2004c041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU3) ADDR=0x2004c043c DWORD=0 NUMREGS=0 */ + 0x20050049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU4) ADDR=0x20050041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU4) ADDR=0x20050043c DWORD=0 NUMREGS=0 */ + 0x2005c049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU7) ADDR=0x2005c041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU7) ADDR=0x2005c043c DWORD=0 NUMREGS=0 */ + 0x20048049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU2) ADDR=0x20048041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU2) ADDR=0x20048043c DWORD=0 NUMREGS=0 */ + 0x20054049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU5) ADDR=0x20054041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU5) ADDR=0x20054043c DWORD=0 NUMREGS=0 */ + 0x20058049, //compressed WR cmd + 0x000f0708, //compressed WR offset + 0x00001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ + 0x01022008, /* WR:AMCX_DRAMCFG_LONGSR(MCU6) ADDR=0x20058041c DWORD=0 NUMREGS=0 */ + 0x15030004, /* WR:AMCX_DRAMCFG_MCPHYUPDTPARAM(MCU6) ADDR=0x20058043c DWORD=0 NUMREGS=0 */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU4) ADDR=0x200500000 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU6) ADDR=0x200580000 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU5) ADDR=0x200540000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU7) ADDR=0x2005c0000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU4) ADDR=0x200520094 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU6) ADDR=0x2005a0094 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU5) ADDR=0x200560094 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000025, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU7) ADDR=0x2005e0094 DWORD=0 NUMREGS=0 */ + 0x20042002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU0) ADDR=0x200420094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU1) ADDR=0x200460094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU2) ADDR=0x2004a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU3) ADDR=0x2004e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU4) ADDR=0x200520094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU5) ADDR=0x200560094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU6) ADDR=0x2005a0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e002, /* POLL:AMPSCA_AMPSCAIOCFG_IMPCALCMD(MCU7) ADDR=0x2005e0094 DWORD=0 */ + 0x00000025, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU0) ADDR=0x200400414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU0) ADDR=0x200400410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU0) ADDR=0x20040040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU0) ADDR=0x200400408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU1) ADDR=0x200440414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU1) ADDR=0x200440410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU1) ADDR=0x20044040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU1) ADDR=0x200440408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU3) ADDR=0x2004c0414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU3) ADDR=0x2004c0410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU3) ADDR=0x2004c040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU3) ADDR=0x2004c0408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20050051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU4) ADDR=0x200500414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU4) ADDR=0x200500410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU4) ADDR=0x20050040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU4) ADDR=0x200500408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 NUMREGS=0 */ + 0x2005c051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU7) ADDR=0x2005c0414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU7) ADDR=0x2005c0410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU7) ADDR=0x2005c040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU7) ADDR=0x2005c0408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 NUMREGS=0 */ + 0x20048051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU2) ADDR=0x200480414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU2) ADDR=0x200480410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU2) ADDR=0x20048040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU2) ADDR=0x200480408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20054051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU5) ADDR=0x200540414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU5) ADDR=0x200540410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU5) ADDR=0x20054040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU5) ADDR=0x200540408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 NUMREGS=0 */ + 0x20058051, //compressed WR cmd + 0x02030405, //compressed WR offset + 0x00000013, //compressed WR offset + 0x10100000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ3(MCU6) ADDR=0x200580414 DWORD=0 NUMREGS=0 */ + 0x10000000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ2(MCU6) ADDR=0x200580410 DWORD=0 NUMREGS=0 */ + 0x10010000, /* WR:AMCX_DRAMCFG_AREFEN_FREQ1(MCU6) ADDR=0x20058040c DWORD=0 NUMREGS=0 */ + 0x1011013f, /* WR:AMCX_DRAMCFG_AREFEN_FREQ0(MCU6) ADDR=0x200580408 DWORD=0 NUMREGS=0 */ + 0x01010000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20050042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20054042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20058042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005c042, /* POLL:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 */ + 0x00000013, /* Offset */ + 0x00010000, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000013, //compressed WR offset + 0x01000000, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 NUMREGS=0 */ + 0x00004804, /* DELAY for 1.5 uS (288 clock cycles) */ + 0x20040045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU0) ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU0), ISSUE COMMAND ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU1) ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU1), ISSUE COMMAND ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU3) ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU3), ISSUE COMMAND ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU4) ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU4), ISSUE COMMAND ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU7) ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU7), ISSUE COMMAND ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU2) ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU2), ISSUE COMMAND ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20054045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU5) ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU5), ISSUE COMMAND ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20058045, //compressed WR cmd + 0x00004040, //compressed WR offset + 0x00004000, /* WR:AMCX_DRAMCMD_MRINITCMD(MCU6) ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x00004001, /* WR:initCmdAndWait(MCU6), ISSUE COMMAND ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:initCmdAndWait(MCU0), POLL COMMAND DONE ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044042, /* POLL:initCmdAndWait(MCU1), POLL COMMAND DONE ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048042, /* POLL:initCmdAndWait(MCU2), POLL COMMAND DONE ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c042, /* POLL:initCmdAndWait(MCU3), POLL COMMAND DONE ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20050042, /* POLL:initCmdAndWait(MCU4), POLL COMMAND DONE ADDR=0x200500500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20054042, /* POLL:initCmdAndWait(MCU5), POLL COMMAND DONE ADDR=0x200540500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20058042, /* POLL:initCmdAndWait(MCU6), POLL COMMAND DONE ADDR=0x200580500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005c042, /* POLL:initCmdAndWait(MCU7), POLL COMMAND DONE ADDR=0x2005c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20f14001, //compressed WR cmd + 0x00000011, //compressed WR offset + 0x000000ff, /* WR:GLBTIMER_GLBTIMER_CHEN(GLBTIMER) ADDR=0x20f140044 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x4f004100, /* WR:MRWRITEMPC(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x51004100, /* WR:MRWRITEMPC(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x0000f004, /* DELAY for 5 uS (960 clock cycles) */ + 0x20040001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU0) ADDR=0x200400000 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU1) ADDR=0x200440000 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU4) ADDR=0x200500000 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU6) ADDR=0x200580000 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU5) ADDR=0x200540000 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU3) ADDR=0x2004c0000 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU7) ADDR=0x2005c0000 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000000, //compressed WR offset + 0x00000003, /* WR:AMCX_AMCGEN_AMCCTRL(MCU2) ADDR=0x200480000 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x00051004, /* DELAY for 27 uS (5184 clock cycles) */ + 0x20043805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU0) ADDR=0x2004380c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU0) ADDR=0x200438138 DWORD=0 NUMREGS=0 */ + 0x20047805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU1) ADDR=0x2004780c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU1) ADDR=0x200478138 DWORD=0 NUMREGS=0 */ + 0x2005b805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU6) ADDR=0x2005b80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU6) ADDR=0x2005b8138 DWORD=0 NUMREGS=0 */ + 0x20057805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU5) ADDR=0x2005780c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU5) ADDR=0x200578138 DWORD=0 NUMREGS=0 */ + 0x2004b805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU2) ADDR=0x2004b80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU2) ADDR=0x2004b8138 DWORD=0 NUMREGS=0 */ + 0x20053805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU4) ADDR=0x2005380c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU4) ADDR=0x200538138 DWORD=0 NUMREGS=0 */ + 0x2005f805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU7) ADDR=0x2005f80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU7) ADDR=0x2005f8138 DWORD=0 NUMREGS=0 */ + 0x2004f805, //compressed WR cmd + 0x00004e32, //compressed WR offset + 0x00010782, /* WR:AMPH_CFGH_DQS0_WKPUPD(MCU3) ADDR=0x2004f80c8 DWORD=0 NUMREGS=0 */ + 0x00010782, /* WR:AMPH_CFGH_DQS1_WKPUPD(MCU3) ADDR=0x2004f8138 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x500d0100, /* WR:MRWRITE(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x00003004, /* DELAY for 1 uS (192 clock cycles) */ + 0x200420cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU0) ADDR=0x200420ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU0) ADDR=0x200420ee8 DWORD=0 NUMREGS=0 */ + 0x200460cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU1) ADDR=0x200460ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU1) ADDR=0x200460ee8 DWORD=0 NUMREGS=0 */ + 0x2004a0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU2) ADDR=0x2004a0ee8 DWORD=0 NUMREGS=0 */ + 0x2005e0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU7) ADDR=0x2005e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU7) ADDR=0x2005e0e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU7) ADDR=0x2005e0ee8 DWORD=0 NUMREGS=0 */ + 0x200520cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU4) ADDR=0x200520e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU4) ADDR=0x200520e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU4) ADDR=0x200520ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU4) ADDR=0x200520ee8 DWORD=0 NUMREGS=0 */ + 0x2004e0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU3) ADDR=0x2004e0ee8 DWORD=0 NUMREGS=0 */ + 0x200560cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU5) ADDR=0x200560e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU5) ADDR=0x200560e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU5) ADDR=0x200560ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU5) ADDR=0x200560ee8 DWORD=0 NUMREGS=0 */ + 0x2005a0cd, //compressed WR cmd + 0xbab68d8d, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU6) ADDR=0x2005a0e34 DWORD=0 NUMREGS=0 */ + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU6) ADDR=0x2005a0e34 DWORD=0 NUMREGS=0 */ + 0x02d0b061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ed8 DWORD=0 NUMREGS=0 */ + 0x02200061, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWWRDQCALVREFCONTROL(MCU6) ADDR=0x2005a0ee8 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU0) ADDR=0x200400418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU1) ADDR=0x200440418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU3) ADDR=0x2004c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20050045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU4) ADDR=0x200500418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x2005c045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU7) ADDR=0x2005c0418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU2) ADDR=0x200480418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20054045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU5) ADDR=0x200540418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x20058045, //compressed WR cmd + 0x00000806, //compressed WR offset + 0x0d012019, /* WR:AMCX_DRAMCFG_AREFPARAM(MCU6) ADDR=0x200580418 DWORD=0 NUMREGS=0 */ + 0xc0001000, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU4) ADDR=0x200500198 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU6) ADDR=0x200580198 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU5) ADDR=0x200540198 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU7) ADDR=0x2005c0198 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x0000000d, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x20043805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU0) ADDR=0x20043809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU0) ADDR=0x200438098 DWORD=0 NUMREGS=0 */ + 0x20047805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU1) ADDR=0x20047809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU1) ADDR=0x200478098 DWORD=0 NUMREGS=0 */ + 0x2005b805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU6) ADDR=0x2005b809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU6) ADDR=0x2005b8098 DWORD=0 NUMREGS=0 */ + 0x20057805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU5) ADDR=0x20057809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU5) ADDR=0x200578098 DWORD=0 NUMREGS=0 */ + 0x2004b805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU2) ADDR=0x2004b809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU2) ADDR=0x2004b8098 DWORD=0 NUMREGS=0 */ + 0x20053805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU4) ADDR=0x20053809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU4) ADDR=0x200538098 DWORD=0 NUMREGS=0 */ + 0x2005f805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU7) ADDR=0x2005f809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU7) ADDR=0x2005f8098 DWORD=0 NUMREGS=0 */ + 0x2004f805, //compressed WR cmd + 0x00002627, //compressed WR offset + 0x00000019, /* WR:AMPH_CFGH_B0_DYN_ISEL_ASRTIME(MCU3) ADDR=0x2004f809c DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:AMPH_CFGH_B0_DYN_ISEL(MCU3) ADDR=0x2004f8098 DWORD=0 NUMREGS=0 */ + 0x20040005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU0) ADDR=0x20040019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU0) ADDR=0x200400198 DWORD=0 NUMREGS=0 */ + 0x20044005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU1) ADDR=0x20044019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU1) ADDR=0x200440198 DWORD=0 NUMREGS=0 */ + 0x20050005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU4) ADDR=0x20050019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU4) ADDR=0x200500198 DWORD=0 NUMREGS=0 */ + 0x20058005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU6) ADDR=0x20058019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU6) ADDR=0x200580198 DWORD=0 NUMREGS=0 */ + 0x20000049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC0) ADDR=0x200000780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC0) ADDR=0x200000648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC0) ADDR=0x20000064c DWORD=0 NUMREGS=0 */ + 0x20020049, //compressed WR cmd + 0x009392e0, //compressed WR offset + 0x00000126, /* WR:AMCC_MCCCFG_MCCGEN(MCC1) ADDR=0x200200780 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC0QPROPCTRL(MCC1) ADDR=0x200200648 DWORD=0 NUMREGS=0 */ + 0x300011a2, /* WR:AMCC_AMCCPERFCNTR_MCC1QPROPCTRL(MCC1) ADDR=0x20020064c DWORD=0 NUMREGS=0 */ + 0x20054005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU5) ADDR=0x20054019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU5) ADDR=0x200540198 DWORD=0 NUMREGS=0 */ + 0x2004c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU3) ADDR=0x2004c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU3) ADDR=0x2004c0198 DWORD=0 NUMREGS=0 */ + 0x2005c005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU7) ADDR=0x2005c019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU7) ADDR=0x2005c0198 DWORD=0 NUMREGS=0 */ + 0x20048005, //compressed WR cmd + 0x00006667, //compressed WR offset + 0x000000a8, /* WR:AMCX_MCUSCH_QBRPARAM(MCU2) ADDR=0x20048019c DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCX_MCUSCH_QBREN(MCU2) ADDR=0x200480198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU4) ADDR=0x200520004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU6) ADDR=0x2005a0004 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU5) ADDR=0x200560004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU7) ADDR=0x2005e0004 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ0) ADDR=0x200428004 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU0, DQ1) ADDR=0x200430004 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ0) ADDR=0x200468004 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU1, DQ1) ADDR=0x200470004 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ0) ADDR=0x2004a8004 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU2, DQ1) ADDR=0x2004b0004 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ0) ADDR=0x2004e8004 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU3, DQ1) ADDR=0x2004f0004 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU4, DQ0) ADDR=0x200528004 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU4, DQ1) ADDR=0x200530004 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU5, DQ0) ADDR=0x200568004 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU5, DQ1) ADDR=0x200570004 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU6, DQ0) ADDR=0x2005a8004 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU6, DQ1) ADDR=0x2005b0004 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU7, DQ0) ADDR=0x2005e8004 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQGEN_AMPCLK(MCU7, DQ1) ADDR=0x2005f0004 DWORD=0 NUMREGS=0 */ + 0x20040c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU0) ADDR=0x20040c064 DWORD=0 NUMREGS=0 */ + 0x20050c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU4) ADDR=0x20050c064 DWORD=0 NUMREGS=0 */ + 0x20044c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU1) ADDR=0x20044c064 DWORD=0 NUMREGS=0 */ + 0x20054c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU5) ADDR=0x20054c064 DWORD=0 NUMREGS=0 */ + 0x20048c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU2) ADDR=0x20048c064 DWORD=0 NUMREGS=0 */ + 0x2004cc01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU3) ADDR=0x2004cc064 DWORD=0 NUMREGS=0 */ + 0x20058c01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU6) ADDR=0x20058c064 DWORD=0 NUMREGS=0 */ + 0x2005cc01, //compressed WR cmd + 0x00000019, //compressed WR offset + 0x00000001, /* WR:SPLLCTRL_SPLLCTRL_MDLLPWRDNCFG0(MCU7) ADDR=0x2005cc064 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU6) ADDR=0x200580424 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU4) ADDR=0x200500424 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU5) ADDR=0x200540424 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000009, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU7) ADDR=0x2005c0424 DWORD=0 NUMREGS=0 */ + 0x20f14015, //compressed WR cmd + 0x17161514, //compressed WR offset + 0x0000211f, //compressed WR offset + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY0(GLBTIMER) ADDR=0x20f140050 DWORD=0 NUMREGS=0 */ + 0x00f000f0, /* WR:GLBTIMER_GLBTIMER_PREFREQ2ALLBANKDLY1(GLBTIMER) ADDR=0x20f140054 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY0(GLBTIMER) ADDR=0x20f140058 DWORD=0 NUMREGS=0 */ + 0x02400240, /* WR:GLBTIMER_GLBTIMER_PREFREQCHNG2FREQCHNGDLY1(GLBTIMER) ADDR=0x20f14005c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_CALSEG2ALLBANK0(GLBTIMER) ADDR=0x20f14007c DWORD=0 NUMREGS=0 */ + 0x00fa0120, /* WR:GLBTIMER_GLBTIMER_ALLBANK2CALSEG0(GLBTIMER) ADDR=0x20f140084 DWORD=0 NUMREGS=0 */ + 0x20040001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU0) ADDR=0x200400010 DWORD=0 NUMREGS=0 */ + 0x2004c001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU3) ADDR=0x2004c0010 DWORD=0 NUMREGS=0 */ + 0x20058001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU6) ADDR=0x200580010 DWORD=0 NUMREGS=0 */ + 0x20050001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU4) ADDR=0x200500010 DWORD=0 NUMREGS=0 */ + 0x20044001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU1) ADDR=0x200440010 DWORD=0 NUMREGS=0 */ + 0x20054001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU5) ADDR=0x200540010 DWORD=0 NUMREGS=0 */ + 0x20048001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU2) ADDR=0x200480010 DWORD=0 NUMREGS=0 */ + 0x2005c001, //compressed WR cmd + 0x00000004, //compressed WR offset + 0x050a0000, /* WR:AMCX_AMCGEN_AMCCLKPWRGATE(MCU7) ADDR=0x2005c0010 DWORD=0 NUMREGS=0 */ + 0x20040041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 NUMREGS=0 */ + 0x20040042, /* POLL:MRREAD(MCU0) RANK=0 ADDR=0x200400500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20044041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 NUMREGS=0 */ + 0x20044042, /* POLL:MRREAD(MCU1) RANK=0 ADDR=0x200440500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20048041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 NUMREGS=0 */ + 0x20048042, /* POLL:MRREAD(MCU2) RANK=0 ADDR=0x200480500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 NUMREGS=0 */ + 0x2004c042, /* POLL:MRREAD(MCU3) RANK=0 ADDR=0x2004c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20050041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 NUMREGS=0 */ + 0x20050042, /* POLL:MRREAD(MCU4) RANK=0 ADDR=0x200500500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20054041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 NUMREGS=0 */ + 0x20054042, /* POLL:MRREAD(MCU5) RANK=0 ADDR=0x200540500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20058041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 NUMREGS=0 */ + 0x20058042, /* POLL:MRREAD(MCU6) RANK=0 ADDR=0x200580500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005c041, //compressed WR cmd + 0x00000040, //compressed WR offset + 0x00041100, /* WR:MRREAD(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 NUMREGS=0 */ + 0x2005c042, /* POLL:MRREAD(MCU7) RANK=0 ADDR=0x2005c0500 DWORD=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20040041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU0) ADDR=0x200400420 DWORD=0 NUMREGS=0 */ + 0x20044041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU1) ADDR=0x200440420 DWORD=0 NUMREGS=0 */ + 0x2004c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU3) ADDR=0x2004c0420 DWORD=0 NUMREGS=0 */ + 0x20050041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU4) ADDR=0x200500420 DWORD=0 NUMREGS=0 */ + 0x2005c041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU7) ADDR=0x2005c0420 DWORD=0 NUMREGS=0 */ + 0x20048041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU2) ADDR=0x200480420 DWORD=0 NUMREGS=0 */ + 0x20054041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU5) ADDR=0x200540420 DWORD=0 NUMREGS=0 */ + 0x20058041, //compressed WR cmd + 0x00000008, //compressed WR offset + 0xc0003320, /* WR:AMCX_DRAMCFG_ODTSZQC(MCU6) ADDR=0x200580420 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_mcu_locked[] = { + 0x2000004d, //compressed WR cmd + 0x292e3329, //compressed WR offset + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC0) ADDR=0x2000004cc DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC0) ADDR=0x2000004b8 DWORD=0 NUMREGS=0 */ + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC0) ADDR=0x2000004a4 DWORD=0 NUMREGS=0 */ + 0x2002004d, //compressed WR cmd + 0x292e3329, //compressed WR offset + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ + 0x00030201, /* WR:AMCC_MCCLOCKREGION_ADDRCFG(MCC1) ADDR=0x2002004cc DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:AMCC_MCCLOCKREGION_DRAMACCCTRL(MCC1) ADDR=0x2002004b8 DWORD=0 NUMREGS=0 */ + 0x00050120, /* WR:AMCC_MCCLOCKREGION_MCCCHNLDEC(MCC1) ADDR=0x2002004a4 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_before_restoration[] = { + 0x20042001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU4) ADDR=0x200520198 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU6) ADDR=0x2005a0198 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU5) ADDR=0x200560198 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU7) ADDR=0x2005e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ0) ADDR=0x200528198 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ1) ADDR=0x200530198 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ0) ADDR=0x200568198 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ1) ADDR=0x200570198 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ0) ADDR=0x2005a8198 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ1) ADDR=0x2005b0198 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ0) ADDR=0x2005e8198 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x00130013, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ1) ADDR=0x2005f0198 DWORD=0 NUMREGS=0 */ + 0x20042001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x20052001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU4) ADDR=0x200520004 DWORD=0 NUMREGS=0 */ + 0x2004a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x2005a001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU6) ADDR=0x2005a0004 DWORD=0 NUMREGS=0 */ + 0x2004e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x20046001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x20056001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU5) ADDR=0x200560004 DWORD=0 NUMREGS=0 */ + 0x2005e001, //compressed WR cmd + 0x00000001, //compressed WR offset + 0x00100001, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU7) ADDR=0x2005e0004 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x2005a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU6) ADDR=0x2005a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x20056041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU5) ADDR=0x20056071c DWORD=0 NUMREGS=0 */ + 0x20052041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU4) ADDR=0x20052071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2005e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000001, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU7) ADDR=0x2005e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ0) ADDR=0x200528628 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ1) ADDR=0x200530628 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ0) ADDR=0x200568628 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ1) ADDR=0x200570628 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ0) ADDR=0x2005a8628 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ1) ADDR=0x2005b0628 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ0) ADDR=0x2005e8628 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ1) ADDR=0x2005f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ0) ADDR=0x200528190 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ1) ADDR=0x200530190 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ0) ADDR=0x200568190 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ1) ADDR=0x200570190 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ0) ADDR=0x2005a8190 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ1) ADDR=0x2005b0190 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ0) ADDR=0x2005e8190 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00010000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ1) ADDR=0x2005f0190 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ0) ADDR=0x20052818c DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ1) ADDR=0x20053018c DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ0) ADDR=0x20056818c DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ1) ADDR=0x20057018c DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ0) ADDR=0x2005a818c DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ1) ADDR=0x2005b018c DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ0) ADDR=0x2005e818c DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000063, //compressed WR offset + 0x00000001, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ1) ADDR=0x2005f018c DWORD=0 NUMREGS=0 */ + 0x20042802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ0) ADDR=0x20042818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20043002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU0, DQ1) ADDR=0x20043018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ0) ADDR=0x20046818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20047002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU1, DQ1) ADDR=0x20047018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ0) ADDR=0x2004a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU2, DQ1) ADDR=0x2004b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ0) ADDR=0x2004e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU3, DQ1) ADDR=0x2004f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ0) ADDR=0x20052818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20053002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU4, DQ1) ADDR=0x20053018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ0) ADDR=0x20056818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20057002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU5, DQ1) ADDR=0x20057018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ0) ADDR=0x2005a818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005b002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU6, DQ1) ADDR=0x2005b018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e802, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ0) ADDR=0x2005e818c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005f002, /* POLL:AMPSDQ_AMPSDQDLLCTL_DLLUPDTCMD(MCU7, DQ1) ADDR=0x2005f018c DWORD=0 */ + 0x00000063, /* Offset */ + 0x00000001, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU0) ADDR=0x200420004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU0) ADDR=0x200420198 DWORD=0 NUMREGS=0 */ + 0x20046005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU1) ADDR=0x200460004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU1) ADDR=0x200460198 DWORD=0 NUMREGS=0 */ + 0x20052005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU4) ADDR=0x200520004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU4) ADDR=0x200520198 DWORD=0 NUMREGS=0 */ + 0x2004a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU2) ADDR=0x2004a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU2) ADDR=0x2004a0198 DWORD=0 NUMREGS=0 */ + 0x2005a005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU6) ADDR=0x2005a0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU6) ADDR=0x2005a0198 DWORD=0 NUMREGS=0 */ + 0x20056005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU5) ADDR=0x200560004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU5) ADDR=0x200560198 DWORD=0 NUMREGS=0 */ + 0x2004e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU3) ADDR=0x2004e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU3) ADDR=0x2004e0198 DWORD=0 NUMREGS=0 */ + 0x2005e005, //compressed WR cmd + 0x00006601, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCAGEN_AMPCLK(MCU7) ADDR=0x2005e0004 DWORD=0 NUMREGS=0 */ + 0x012c012c, /* WR:AMPSCA_AMPSCADLLCTL_DLLLOCKTIM(MCU7) ADDR=0x2005e0198 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ0) ADDR=0x200428198 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU0, DQ1) ADDR=0x200430198 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ0) ADDR=0x200468198 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU1, DQ1) ADDR=0x200470198 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ0) ADDR=0x2004a8198 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU2, DQ1) ADDR=0x2004b0198 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ0) ADDR=0x2004e8198 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU3, DQ1) ADDR=0x2004f0198 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ0) ADDR=0x200528198 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU4, DQ1) ADDR=0x200530198 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ0) ADDR=0x200568198 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU5, DQ1) ADDR=0x200570198 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ0) ADDR=0x2005a8198 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU6, DQ1) ADDR=0x2005b0198 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ0) ADDR=0x2005e8198 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000066, //compressed WR offset + 0x012c012c, /* WR:AMPSDQ_AMPSDQDLLCTL_DLLLOCKTIM(MCU7, DQ1) ADDR=0x2005f0198 DWORD=0 NUMREGS=0 */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_restoration[] = { + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* From this step to the next comment all the CA/CK/CS/WRLVL/VTScale/VREF registers need to be restored by SW during AOP Sequence */ + /* For Classic AP Resume Boot, SW should call the restoration function and restore these values */ + /* In Classic AP Resume Boot, Write and Read Calibration should be done by HW. This is Maui POR. */ + /* NOTE: Comment for each Data block has 2 parts: the register to read and a mask to apply the value read */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU0) ADDR=0x200420700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU1) ADDR=0x200460700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU2) ADDR=0x2004a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU3) ADDR=0x2004e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20052041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU4) ADDR=0x200520700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20056041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU5) ADDR=0x200560700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2005a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU6) ADDR=0x2005a0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x2005e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CASDLLCTRL(MCU7) ADDR=0x2005e0700 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00000004, /* Data -- CASDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU0) ADDR=0x200420708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU1) ADDR=0x200460708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU2) ADDR=0x2004a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU3) ADDR=0x2004e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20052041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU4) ADDR=0x200520708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20056041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU5) ADDR=0x200560708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2005a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU6) ADDR=0x2005a0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x2005e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CSSDLLCTRL(MCU7) ADDR=0x2005e0708 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000004, /* Data -- CSSDLLCTRL 0x4 */ + 0x20042041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU0) ADDR=0x200420710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20046041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU1) ADDR=0x200460710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU2) ADDR=0x2004a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2004e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU3) ADDR=0x2004e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20052041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU4) ADDR=0x200520710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20056041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU5) ADDR=0x200560710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2005a041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU6) ADDR=0x2005a0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x2005e041, /* WR:AMPSCA_AMPSCASDLLCTRL_CKSDLLCTRL(MCU7) ADDR=0x2005e0710 DWORD=0 NUMREGS=0 */ + 0x000000c4, /* Offset */ + 0x00000004, /* Data -- CKSDLLCTRL 0x4 */ + 0x20042081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20046081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2004e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20052081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20056081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2005a081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x2005e081, /* WR:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 NUMREGS=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Data -- AMPSCAWRLVL_AMPCAWRLVLSDLLCODE 0x200 */ + 0x20042082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU0) ADDR=0x200420800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20046082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU1) ADDR=0x200460800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU2) ADDR=0x2004a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2004e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU3) ADDR=0x2004e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20052082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU4) ADDR=0x200520800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20056082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU5) ADDR=0x200560800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005a082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU6) ADDR=0x2005a0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x2005e082, /* POLL:AMPSCA_AMPSCAWRLVL_AMPCAWRLVLSDLLCODE(MCU7) ADDR=0x2005e0800 DWORD=0 */ + 0x00000000, /* Offset */ + 0x00000200, /* Mask */ + 0x00000000, /* Expected Data */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU0) ADDR=0x200420500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU1) ADDR=0x200460500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU2) ADDR=0x2004a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU3) ADDR=0x2004e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU4) ADDR=0x200520500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU5) ADDR=0x200560500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU6) ADDR=0x2005a0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA0_DESKEW_CTRL(MCU7) ADDR=0x2005e0500 DWORD=0 NUMREGS=0 */ + 0x00000040, /* Offset */ + 0x00000100, /* Data -- CA0_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU0) ADDR=0x200420504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU1) ADDR=0x200460504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU2) ADDR=0x2004a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU3) ADDR=0x2004e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU4) ADDR=0x200520504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU5) ADDR=0x200560504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU6) ADDR=0x2005a0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA1_DESKEW_CTRL(MCU7) ADDR=0x2005e0504 DWORD=0 NUMREGS=0 */ + 0x00000041, /* Offset */ + 0x00000100, /* Data -- CA1_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU0) ADDR=0x200420508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU1) ADDR=0x200460508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU2) ADDR=0x2004a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU3) ADDR=0x2004e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU4) ADDR=0x200520508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU5) ADDR=0x200560508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU6) ADDR=0x2005a0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA2_DESKEW_CTRL(MCU7) ADDR=0x2005e0508 DWORD=0 NUMREGS=0 */ + 0x00000042, /* Offset */ + 0x00000100, /* Data -- CA2_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU0) ADDR=0x20042050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU1) ADDR=0x20046050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU2) ADDR=0x2004a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU3) ADDR=0x2004e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU4) ADDR=0x20052050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU5) ADDR=0x20056050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU6) ADDR=0x2005a050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA3_DESKEW_CTRL(MCU7) ADDR=0x2005e050c DWORD=0 NUMREGS=0 */ + 0x00000043, /* Offset */ + 0x00000100, /* Data -- CA3_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU0) ADDR=0x200420510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU1) ADDR=0x200460510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU2) ADDR=0x2004a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU3) ADDR=0x2004e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU4) ADDR=0x200520510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU5) ADDR=0x200560510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU6) ADDR=0x2005a0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA4_DESKEW_CTRL(MCU7) ADDR=0x2005e0510 DWORD=0 NUMREGS=0 */ + 0x00000044, /* Offset */ + 0x00000100, /* Data -- CA4_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU0) ADDR=0x200420514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU1) ADDR=0x200460514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU2) ADDR=0x2004a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU3) ADDR=0x2004e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU4) ADDR=0x200520514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU5) ADDR=0x200560514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU6) ADDR=0x2005a0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CA5_DESKEW_CTRL(MCU7) ADDR=0x2005e0514 DWORD=0 NUMREGS=0 */ + 0x00000045, /* Offset */ + 0x00000100, /* Data -- CA5_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU0) ADDR=0x200420518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU1) ADDR=0x200460518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU2) ADDR=0x2004a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU3) ADDR=0x2004e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU4) ADDR=0x200520518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU5) ADDR=0x200560518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU6) ADDR=0x2005a0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CS_DESKEW_CTRL(MCU7) ADDR=0x2005e0518 DWORD=0 NUMREGS=0 */ + 0x00000046, /* Offset */ + 0x00000100, /* Data -- CS_DESKEW_CTRL 0x100 */ + 0x20042041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU0) ADDR=0x20042051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20046041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU1) ADDR=0x20046051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU2) ADDR=0x2004a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2004e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU3) ADDR=0x2004e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20052041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU4) ADDR=0x20052051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20056041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU5) ADDR=0x20056051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2005a041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU6) ADDR=0x2005a051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x2005e041, /* WR:AMPSCA_AMPSCADESKEWCTRL_CK_DESKEW_CTRL(MCU7) ADDR=0x2005e051c DWORD=0 NUMREGS=0 */ + 0x00000047, /* Offset */ + 0x00000100, /* Data -- CK_DESKEW_CTRL 0x100 */ + 0x20042841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ0) ADDR=0x200428704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20043041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU0, DQ1) ADDR=0x200430704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20046841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ0) ADDR=0x200468704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20047041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU1, DQ1) ADDR=0x200470704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ0) ADDR=0x2004a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU2, DQ1) ADDR=0x2004b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ0) ADDR=0x2004e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2004f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU3, DQ1) ADDR=0x2004f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20052841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU4, DQ0) ADDR=0x200528704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20053041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU4, DQ1) ADDR=0x200530704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20056841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU5, DQ0) ADDR=0x200568704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20057041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU5, DQ1) ADDR=0x200570704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005a841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU6, DQ0) ADDR=0x2005a8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005b041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU6, DQ1) ADDR=0x2005b0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005e841, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU7, DQ0) ADDR=0x2005e8704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x2005f041, /* WR:AMPSDQ_AMPSDQWRLVL_AMPWRLVLSDLLCODE0(MCU7, DQ1) ADDR=0x2005f0704 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00000200, /* Data -- AMPSDQWRLVL_AMPWRLVLSDLLCODE0 (DQ0/1) 0x200 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ0) ADDR=0x200428b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU0, DQ1) ADDR=0x200430b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ0) ADDR=0x200468b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU1, DQ1) ADDR=0x200470b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ0) ADDR=0x2004a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU2, DQ1) ADDR=0x2004b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ0) ADDR=0x2004e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU3, DQ1) ADDR=0x2004f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ0) ADDR=0x200528b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU4, DQ1) ADDR=0x200530b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ0) ADDR=0x200568b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU5, DQ1) ADDR=0x200570b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ0) ADDR=0x2005a8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU6, DQ1) ADDR=0x2005b0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ0) ADDR=0x2005e8b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F0(MCU7, DQ1) ADDR=0x2005f0b00 DWORD=0 NUMREGS=0 */ + 0x000000c0, /* Offset */ + 0x00c000c0, /* Data -- VREF_F0 (DQ0) 0x0 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ0) ADDR=0x200428b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU0, DQ1) ADDR=0x200430b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ0) ADDR=0x200468b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU1, DQ1) ADDR=0x200470b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ0) ADDR=0x2004a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU2, DQ1) ADDR=0x2004b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ0) ADDR=0x2004e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU3, DQ1) ADDR=0x2004f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ0) ADDR=0x200528b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU4, DQ1) ADDR=0x200530b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ0) ADDR=0x200568b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU5, DQ1) ADDR=0x200570b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ0) ADDR=0x2005a8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU6, DQ1) ADDR=0x2005b0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ0) ADDR=0x2005e8b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F1(MCU7, DQ1) ADDR=0x2005f0b04 DWORD=0 NUMREGS=0 */ + 0x000000c1, /* Offset */ + 0x00c000c0, /* Data -- VREF_F1 (DQ1) 0x0 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ0) ADDR=0x200428b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU0, DQ1) ADDR=0x200430b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ0) ADDR=0x200468b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU1, DQ1) ADDR=0x200470b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ0) ADDR=0x2004a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU2, DQ1) ADDR=0x2004b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ0) ADDR=0x2004e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU3, DQ1) ADDR=0x2004f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU4, DQ0) ADDR=0x200528b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU4, DQ1) ADDR=0x200530b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU5, DQ0) ADDR=0x200568b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU5, DQ1) ADDR=0x200570b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU6, DQ0) ADDR=0x2005a8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU6, DQ1) ADDR=0x2005b0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU7, DQ0) ADDR=0x2005e8b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F2(MCU7, DQ1) ADDR=0x2005f0b08 DWORD=0 NUMREGS=0 */ + 0x000000c2, /* Offset */ + 0x00000000, /* Data -- VREF_F2 (DQ2) 0x0 */ + 0x20042881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ0) ADDR=0x200428b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20043081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU0, DQ1) ADDR=0x200430b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20046881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ0) ADDR=0x200468b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20047081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU1, DQ1) ADDR=0x200470b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ0) ADDR=0x2004a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU2, DQ1) ADDR=0x2004b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ0) ADDR=0x2004e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2004f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU3, DQ1) ADDR=0x2004f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20052881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU4, DQ0) ADDR=0x200528b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20053081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU4, DQ1) ADDR=0x200530b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20056881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU5, DQ0) ADDR=0x200568b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x20057081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU5, DQ1) ADDR=0x200570b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2005a881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU6, DQ0) ADDR=0x2005a8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2005b081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU6, DQ1) ADDR=0x2005b0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2005e881, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU7, DQ0) ADDR=0x2005e8b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + 0x2005f081, /* WR:AMPSDQ_AMPSDQODT_VREF_F3(MCU7, DQ1) ADDR=0x2005f0b0c DWORD=0 NUMREGS=0 */ + 0x000000c3, /* Offset */ + 0x00000000, /* Data -- VREF_F3 (DQ3) 0x0 */ + /* ####### IMPORTANT ##### PLEASE READ ##### */ + /* When restoring below WrDqCalVrefCodeControl and RdDqCalVrefCodeControl registers, Software first needs to read WrDQCalVrefCodeStatus and RdDqCalVrefCodeStatus registers and put the value from CodeStatus registers to CodeControl registers */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200520c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200560c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2005a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x2005e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f20 DWORD=0 NUMREGS=0 */ + 0x000000c8, /* Offset */ + 0x11111111, /* Data -- AMPSCA_AMPSCARDWRDQCAL_WRDQCALVREFCODESTATUS 0x0 */ + 0x200420c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU0) ADDR=0x200420f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200460c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU1) ADDR=0x200460f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU2) ADDR=0x2004a0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2004e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU3) ADDR=0x2004e0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200520c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU4) ADDR=0x200520f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x200560c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU5) ADDR=0x200560f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2005a0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU6) ADDR=0x2005a0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x2005e0c1, /* WR:AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODECONTROL(MCU7) ADDR=0x2005e0f18 DWORD=0 NUMREGS=0 */ + 0x000000c6, /* Offset */ + 0xc0c0c0c0, /* Data -- AMPSCA_AMPSCARDWRDQCAL_RDDQCALVREFCODESTATUS 0x0 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20052801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU4, DQ0) ADDR=0x2005281d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20053001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU4, DQ1) ADDR=0x2005301d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20056801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU5, DQ0) ADDR=0x2005681d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20057001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU5, DQ1) ADDR=0x2005701d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005a801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU6, DQ0) ADDR=0x2005a81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005b001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU6, DQ1) ADDR=0x2005b01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005e801, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU7, DQ0) ADDR=0x2005e81d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005f001, /* WR:AMPSDQ_AMPSDQDLLCTL_RDMDLLVTSCALEREFCONTROL(MCU7, DQ1) ADDR=0x2005f01d8 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000076, /* Offset */ + 0x104c0000, /* Data -- RDMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20052801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU4, DQ0) ADDR=0x2005281dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20053001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU4, DQ1) ADDR=0x2005301dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20056801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU5, DQ0) ADDR=0x2005681dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20057001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU5, DQ1) ADDR=0x2005701dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005a801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU6, DQ0) ADDR=0x2005a81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005b001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU6, DQ1) ADDR=0x2005b01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005e801, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU7, DQ0) ADDR=0x2005e81dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x2005f001, /* WR:AMPSDQ_AMPSDQDLLCTL_WRMDLLVTSCALEREFCONTROL(MCU7, DQ1) ADDR=0x2005f01dc DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000077, /* Offset */ + 0x104c0000, /* Data -- WRMDLLVTSCALEREFCONTROL (DQ0) 0x10000000 */ + 0x20042801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ0) ADDR=0x2004281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20043001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU0, DQ1) ADDR=0x2004301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20046801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ0) ADDR=0x2004681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20047001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU1, DQ1) ADDR=0x2004701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ0) ADDR=0x2004a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU2, DQ1) ADDR=0x2004b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ0) ADDR=0x2004e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2004f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU3, DQ1) ADDR=0x2004f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20052801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU4, DQ0) ADDR=0x2005281d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20053001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU4, DQ1) ADDR=0x2005301d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20056801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU5, DQ0) ADDR=0x2005681d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20057001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU5, DQ1) ADDR=0x2005701d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005a801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU6, DQ0) ADDR=0x2005a81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005b001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU6, DQ1) ADDR=0x2005b01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005e801, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU7, DQ0) ADDR=0x2005e81d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x2005f001, /* WR:AMPSDQ_AMPSDQDLLCTL_CAMDLLVTSCALEREFCONTROL(MCU7, DQ1) ADDR=0x2005f01d4 DWORD=0 NUMREGS=0 */ // NOTE: Status is 9:0 of this register. You need to write the value in 9:0 to 25:16 similar to Maui + 0x00000075, /* Offset */ + 0x104c0000, /* Data -- CAMDLLVTSCALEREFCONTROL 0x10000000 */ + 0x20040041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU0) ADDR=0x200400454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20044041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU1) ADDR=0x200440454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20048041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU2) ADDR=0x200480454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x2004c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU3) ADDR=0x2004c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20050041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU4) ADDR=0x200500454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20054041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU5) ADDR=0x200540454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x20058041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU6) ADDR=0x200580454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + 0x2005c041, /* WR:AMCX_DRAMCFG_FREQCHNGCTL1_FREQ0(MCU7) ADDR=0x2005c0454 DWORD=0 NUMREGS=0 */ + 0x00000015, /* Offset */ + 0x110c110e, /* Data -- MCU_DRAMCFG_FREQCHNGCTL1_FREQ0 0x0 */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* ################################################################################################# */ + /* End of Restoration. FreqChngCTL1 register has VrefCa and VrefDQ Values. This needs to be restored. */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_mcu_awake_after_restoration[] = { + 0x200420c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU0) ADDR=0x200420e34 DWORD=0 NUMREGS=0 */ + 0x200460c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU1) ADDR=0x200460e34 DWORD=0 NUMREGS=0 */ + 0x2004a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU2) ADDR=0x2004a0e34 DWORD=0 NUMREGS=0 */ + 0x2005e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU7) ADDR=0x2005e0e34 DWORD=0 NUMREGS=0 */ + 0x200520c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU4) ADDR=0x200520e34 DWORD=0 NUMREGS=0 */ + 0x2004e0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU3) ADDR=0x2004e0e34 DWORD=0 NUMREGS=0 */ + 0x200560c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU5) ADDR=0x200560e34 DWORD=0 NUMREGS=0 */ + 0x2005a0c1, //compressed WR cmd + 0x0000008d, //compressed WR offset + 0x00000003, /* WR:AMPSCA_AMPSCARDWRDQCAL_HWRDWRDQCALFULLSCANENABLE(MCU6) ADDR=0x2005a0e34 DWORD=0 NUMREGS=0 */ + 0x20040045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU0) ADDR=0x200400424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU0) ADDR=0x20040044c DWORD=0 NUMREGS=0 */ + 0x20044045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU1) ADDR=0x200440424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU1) ADDR=0x20044044c DWORD=0 NUMREGS=0 */ + 0x2004c045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU3) ADDR=0x2004c0424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU3) ADDR=0x2004c044c DWORD=0 NUMREGS=0 */ + 0x20050045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU4) ADDR=0x200500424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU4) ADDR=0x20050044c DWORD=0 NUMREGS=0 */ + 0x2005c045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU7) ADDR=0x2005c0424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU7) ADDR=0x2005c044c DWORD=0 NUMREGS=0 */ + 0x20048045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU2) ADDR=0x200480424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU2) ADDR=0x20048044c DWORD=0 NUMREGS=0 */ + 0x20054045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU5) ADDR=0x200540424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU5) ADDR=0x20054044c DWORD=0 NUMREGS=0 */ + 0x20058045, //compressed WR cmd + 0x00001309, //compressed WR offset + 0x00000132, /* WR:AMCX_DRAMCFG_PWRMNGTEN(MCU6) ADDR=0x200580424 DWORD=0 NUMREGS=0 */ + 0x02009999, /* WR:AMCX_DRAMCFG_FREQCHNGCTL(MCU6) ADDR=0x20058044c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ0) ADDR=0x200428600 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU0, DQ1) ADDR=0x200430600 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ0) ADDR=0x200468600 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU1, DQ1) ADDR=0x200470600 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ0) ADDR=0x2004a8600 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU2, DQ1) ADDR=0x2004b0600 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ0) ADDR=0x2004e8600 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU3, DQ1) ADDR=0x2004f0600 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ0) ADDR=0x200528600 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU4, DQ1) ADDR=0x200530600 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ0) ADDR=0x200568600 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU5, DQ1) ADDR=0x200570600 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ0) ADDR=0x2005a8600 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU6, DQ1) ADDR=0x2005b0600 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ0) ADDR=0x2005e8600 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x00000080, //compressed WR offset + 0xff000008, /* WR:AMPSDQ_AMPSDQSDLLCTRL_WRDQDQSSDLLCTRL(MCU7, DQ1) ADDR=0x2005f0600 DWORD=0 NUMREGS=0 */ + 0x20042041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU0) ADDR=0x20042071c DWORD=0 NUMREGS=0 */ + 0x2005a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU6) ADDR=0x2005a071c DWORD=0 NUMREGS=0 */ + 0x2004e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU3) ADDR=0x2004e071c DWORD=0 NUMREGS=0 */ + 0x20046041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU1) ADDR=0x20046071c DWORD=0 NUMREGS=0 */ + 0x20056041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU5) ADDR=0x20056071c DWORD=0 NUMREGS=0 */ + 0x20052041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU4) ADDR=0x20052071c DWORD=0 NUMREGS=0 */ + 0x2004a041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU2) ADDR=0x2004a071c DWORD=0 NUMREGS=0 */ + 0x2005e041, //compressed WR cmd + 0x000000c7, //compressed WR offset + 0x00000000, /* WR:AMPSCA_AMPSCASDLLCTRL_SDLLUPDATEDEFEREN(MCU7) ADDR=0x2005e071c DWORD=0 NUMREGS=0 */ + 0x20042841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ0) ADDR=0x200428628 DWORD=0 NUMREGS=0 */ + 0x20043041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU0, DQ1) ADDR=0x200430628 DWORD=0 NUMREGS=0 */ + 0x20046841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ0) ADDR=0x200468628 DWORD=0 NUMREGS=0 */ + 0x20047041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU1, DQ1) ADDR=0x200470628 DWORD=0 NUMREGS=0 */ + 0x2004a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ0) ADDR=0x2004a8628 DWORD=0 NUMREGS=0 */ + 0x2004b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU2, DQ1) ADDR=0x2004b0628 DWORD=0 NUMREGS=0 */ + 0x2004e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ0) ADDR=0x2004e8628 DWORD=0 NUMREGS=0 */ + 0x2004f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU3, DQ1) ADDR=0x2004f0628 DWORD=0 NUMREGS=0 */ + 0x20052841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ0) ADDR=0x200528628 DWORD=0 NUMREGS=0 */ + 0x20053041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU4, DQ1) ADDR=0x200530628 DWORD=0 NUMREGS=0 */ + 0x20056841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ0) ADDR=0x200568628 DWORD=0 NUMREGS=0 */ + 0x20057041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU5, DQ1) ADDR=0x200570628 DWORD=0 NUMREGS=0 */ + 0x2005a841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ0) ADDR=0x2005a8628 DWORD=0 NUMREGS=0 */ + 0x2005b041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU6, DQ1) ADDR=0x2005b0628 DWORD=0 NUMREGS=0 */ + 0x2005e841, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ0) ADDR=0x2005e8628 DWORD=0 NUMREGS=0 */ + 0x2005f041, //compressed WR cmd + 0x0000008a, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQSDLLCTRL_SDLLUPDATEDEFEREN(MCU7, DQ1) ADDR=0x2005f0628 DWORD=0 NUMREGS=0 */ + 0x20042801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ0) ADDR=0x200428190 DWORD=0 NUMREGS=0 */ + 0x20043001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU0, DQ1) ADDR=0x200430190 DWORD=0 NUMREGS=0 */ + 0x20046801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ0) ADDR=0x200468190 DWORD=0 NUMREGS=0 */ + 0x20047001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU1, DQ1) ADDR=0x200470190 DWORD=0 NUMREGS=0 */ + 0x2004a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ0) ADDR=0x2004a8190 DWORD=0 NUMREGS=0 */ + 0x2004b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU2, DQ1) ADDR=0x2004b0190 DWORD=0 NUMREGS=0 */ + 0x2004e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ0) ADDR=0x2004e8190 DWORD=0 NUMREGS=0 */ + 0x2004f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU3, DQ1) ADDR=0x2004f0190 DWORD=0 NUMREGS=0 */ + 0x20052801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ0) ADDR=0x200528190 DWORD=0 NUMREGS=0 */ + 0x20053001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU4, DQ1) ADDR=0x200530190 DWORD=0 NUMREGS=0 */ + 0x20056801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ0) ADDR=0x200568190 DWORD=0 NUMREGS=0 */ + 0x20057001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU5, DQ1) ADDR=0x200570190 DWORD=0 NUMREGS=0 */ + 0x2005a801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ0) ADDR=0x2005a8190 DWORD=0 NUMREGS=0 */ + 0x2005b001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU6, DQ1) ADDR=0x2005b0190 DWORD=0 NUMREGS=0 */ + 0x2005e801, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ0) ADDR=0x2005e8190 DWORD=0 NUMREGS=0 */ + 0x2005f001, //compressed WR cmd + 0x00000064, //compressed WR offset + 0x00000000, /* WR:AMPSDQ_AMPSDQDLLCTL_MDLLOVERRIDE(MCU7, DQ1) ADDR=0x2005f0190 DWORD=0 NUMREGS=0 */ + 0x20f14025, //compressed WR cmd + 0x0107000f, //compressed WR offset + 0x06050402, //compressed WR offset + 0x00000a08, //compressed WR offset + 0x000001ff, /* WR:GLBTIMER_GLBTIMER_PMGRWAKEUPCFG(GLBTIMER) ADDR=0x20f14003c DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_MDLLTIMER(GLBTIMER) ADDR=0x20f140000 DWORD=0 NUMREGS=0 */ + 0x00000bb8, /* WR:GLBTIMER_GLBTIMER_DCCTIMER(GLBTIMER) ADDR=0x20f14001c DWORD=0 NUMREGS=0 */ + 0x0000004b, /* WR:GLBTIMER_GLBTIMER_MDLLVOLTRAMPTIMER(GLBTIMER) ADDR=0x20f140004 DWORD=0 NUMREGS=0 */ + 0x0000000f, /* WR:GLBTIMER_GLBTIMER_CTRLUPDMASKTIMER(GLBTIMER) ADDR=0x20f140008 DWORD=0 NUMREGS=0 */ + 0x002dc6bb, /* WR:GLBTIMER_GLBTIMER_RDCALTIMER(GLBTIMER) ADDR=0x20f140010 DWORD=0 NUMREGS=0 */ + 0x002dc6c0, /* WR:GLBTIMER_GLBTIMER_WRCALTIMER(GLBTIMER) ADDR=0x20f140014 DWORD=0 NUMREGS=0 */ + 0x003d0900, /* WR:GLBTIMER_GLBTIMER_ZQCTIMER(GLBTIMER) ADDR=0x20f140018 DWORD=0 NUMREGS=0 */ + 0x00000001, /* WR:GLBTIMER_GLBTIMER_PERCAL_FREQCHNGTIMER(GLBTIMER) ADDR=0x20f140020 DWORD=0 NUMREGS=0 */ + 0x00002ee0, /* WR:GLBTIMER_GLBTIMER_IMPCALTIMER(GLBTIMER) ADDR=0x20f140028 DWORD=0 NUMREGS=0 */ +}; + +#endif // __MCU_INIT_AOP_H__ diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_s8001.h b/platform/s8000/include/platform/soc/reconfig_sequences_s8001.h new file mode 100644 index 0000000..afd7ece --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_s8001.h @@ -0,0 +1,1792 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef AOP_CONFIG_SEQUENCES_H +#define AOP_CONFIG_SEQUENCES_H + + +#if DCS_NUM_CHANNELS == 8 +#define AMC_PARAM_EIGHT_CH_ONE_RANK +#include "reconfig_sequences_mcu_8ch_s8001.h" +#else +#include "reconfig_sequences_mcu_4ch_s8001.h" +#endif + +// _ _ _ _ +// / \ _ _| |_ ___ __ _ ___ _ __ ___ _ __ __ _| |_ ___ __| | +// / _ \| | | | __/ _ \ / _` |/ _ \ '_ \ / _ \ '__/ _` | __/ _ \/ _` | +// / ___ \ |_| | || (_) | (_| | __/ | | | __/ | | (_| | || __/ (_| | +// /_/ \_\__,_|\__\___/ \__, |\___|_| |_|\___|_| \__,_|\__\___|\__,_| +// ____ |___/ _____ _ _ _ +// | _ \ ___ _ __ ___ | |_ | ____|__| (_) |_ +// | | | |/ _ \ | '_ \ / _ \| __| | _| / _` | | __| +// | |_| | (_) | | | | | (_) | |_ | |__| (_| | | |_ +// |____/ \___/ |_| |_|\___/ \__| |_____\__,_|_|\__| +// + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP SOC CONFIG SEQUENCES */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** RELEASE NOTES */ +/* Comment: // ** */ +/* Comment: // ** -- 2/8/2015 -- */ +/* Comment: // ** Added "verbatim" command which will print the specified text verbatim in the final */ +/* Comment: // ** output file. This is used for putting #defines into the final header file for SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 2/5/2015 -- */ +/* Comment: // ** Introduced ifdef command for 4ch vs 8ch mode. Moved 4ch and 8ch differences back */ +/* Comment: // ** into aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** Note: Nested ifdefs are not supported! */ +/* Comment: // ** */ +/* Comment: // ** -- 2/4/2015 -- */ +/* Comment: // ** Ported stitch sequences to Elba. Moved 4ch and 8ch differences into stitched files. */ +/* Comment: // ** Deleted 4ch version of aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/29/2015 -- */ +/* Comment: // ** Updated sequences based on CoreOS feedback from radars 19132562 and 19148279. */ +/* Comment: // ** Added "stitch" command to stitch in sequences from external files. Intended to */ +/* Comment: // ** explicitly annotate which sequences are meant to be overridden by SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/26/2015 -- */ +/* Comment: // ** Disable DynPwrDn in AOP_DDR (see radar 19338346) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/12/2014 -- */ +/* Comment: // ** Added S2R_AOP->AOP_DDR preamble which polls for proxy_osc_clk to be equal to lpo/8. */ +/* Comment: // ** Activating the S2R_AOP->AOP_DDR preamble forces the LPO to be on prior to the */ +/* Comment: // ** AOP-PMU handshake. See radar 18563566 for details. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/22/2014 -- */ +/* Comment: // ** Config engine changes the current perf state to 0 prior to polling. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/17/2014 -- */ +/* Comment: // ** Removed MCU bucket 1 transitions per radar 17699704. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/26/2014 -- */ +/* Comment: // ** Instead of implicitly stitching the 48->800 MCU sequence at the beginning of the */ +/* Comment: // ** AOP_DDR->AWAKE sequence, it is now inserted at the comment token labeled */ +/* Comment: // ** "INSERT_MCU_AWAKE_SEQ". This will make the sequence more flexible in case commands */ +/* Comment: // ** are to be inserted before the MCU sequence, e.g., changing tunables. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/20/2014 -- */ +/* Comment: // ** Added more documentation to aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/4/2014 -- */ +/* Comment: // ** In this update, we removed the need to specify reg_addr in the write/write64/poll */ +/* Comment: // ** commands. The reg_addr was prone to human error because it was manually written, */ +/* Comment: // ** so there is no guarantee that the address matches the register name. Furthermore, */ +/* Comment: // ** manually specifying the register address is not future-proof because addresses of */ +/* Comment: // ** registers may change from chip to chip. */ +/* Comment: // ** */ +/* Comment: // ** Now, the register address are calculated based on the register name and the include */ +/* Comment: // ** files. The user must ensure that all of the header files needed are specified */ +/* Comment: // ** using the "include:" command. In the DV environment, these header files were */ +/* Comment: // ** generated from SPDS. */ +/* Comment: // ** */ +/* Comment: // ** Note: For legacy reasons, we still support manually specifying the reg_addr field. */ +/* Comment: // ** If the reg_addr field is specified, the reg_name field is ignored during the */ +/* Comment: // ** generation of the .h file. */ +/* Comment: // ** */ +/* Comment: // ** We also renamed the file type of this file from .h to .seq. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ** This file contains the AOP SoC config sequences verified by DV. It is written in a */ +/* Comment: // ** pseudo-language that is parsed by the scripts described in the "Related files" section */ +/* Comment: // ** below. All commands must be contained within a single line. */ +/* Comment: // ** */ +/* Comment: // ** The supported commands are: */ +/* Comment: // ** */ +/* Comment: // ** include: */ +/* Comment: // ** Header file to include for looking up register addresses. The path to the include */ +/* Comment: // ** files is provided as an argument to the aop_func_gen.pl script described below. */ +/* Comment: // ** */ +/* Comment: // ** seq_name: */ +/* Comment: // ** Designates the start of a sequence. The supported sequences are: */ +/* Comment: // ** s2r_aop_to_aop_ddr_pre */ +/* Comment: // ** s2r_aop_to_aop_ddr_post */ +/* Comment: // ** aop_ddr_to_s2r_aop_pre */ +/* Comment: // ** aop_ddr_to_s2r_aop_post */ +/* Comment: // ** aop_ddr_to_awake_pre */ +/* Comment: // ** aop_ddr_to_awake_post */ +/* Comment: // ** awake_to_aop_ddr_pre */ +/* Comment: // ** awake_to_aop_ddr_post */ +/* Comment: // ** Note that s2r_aop_to_aop_ddr_pre and aop_ddr_to_s2r_aop_post are currently unused. */ +/* Comment: // ** */ +/* Comment: // ** endseq */ +/* Comment: // ** Designates the end of a sequence. */ +/* Comment: // ** */ +/* Comment: // ** write: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 32-bit write command to the register at 36-bit hex
with 32-bit hex . */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write64: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 64-bit write command to the 36-bit hex
with 64-bit value , */ +/* Comment: // ** where "upper" is the upper 32-bit hex value, and "lower" is the lower 32-bit hex */ +/* Comment: // ** value. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write_start */ +/* Comment: // ** Designates the start of a write command with multiple register writes. Refer to */ +/* Comment: // ** AOP spec section 6.1 "Configuration Write Command" for details. Because the */ +/* Comment: // ** annotation with "write_start" and "write_end" is manually done, it is the */ +/* Comment: // ** responsibility of the author to ensure that the combined writes are within the */ +/* Comment: // ** same 1KB block, and a max of 16 writes is included. */ +/* Comment: // ** */ +/* Comment: // ** write_end */ +/* Comment: // ** Designates the end of a multi-register write command. */ +/* Comment: // ** */ +/* Comment: // ** poll: reg_name= [reg_addr=
] reg_value= reg_mask= retry_en= retry_cnt= */ +/* Comment: // ** Reads 36-bit
until (read_data & mask == value). If is 0, the */ +/* Comment: // ** poll repeats indefinitely. If is set, the read is retried up to */ +/* Comment: // ** times. As with "write" and "write64", is not used. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** cfg_cnt: */ +/* Comment: // ** designates the number of aop_clk cycles to wait before executing the next */ +/* Comment: // ** command. */ +/* Comment: // ** */ +/* Comment: // ** cfg_end */ +/* Comment: // ** Designates the Configuration End Command. */ +/* Comment: // ** */ +/* Comment: // ** comment: */ +/* Comment: // ** Designates a comment. */ +/* Comment: // ** */ +/* Comment: // ** stitch: */ +/* Comment: // ** Stitches file.seq into the sequence inline. */ +/* Comment: // ** */ +/* Comment: // ** stitch_h: */ +/* Comment: // ** In the generated .h file, an explicit #include "file.h" will appear at this line. */ +/* Comment: // ** */ +/* Comment: // ** Related files: */ +/* Comment: // ** tb_lib/cpu/armv7/aop_lib/aop_func_gen.pl */ +/* Comment: // ** This script parses this file (aop_soc_cfg.h) and converts it into an intermediate */ +/* Comment: // ** C header format. The output file contains C arrays whose contents are in a format */ +/* Comment: // ** understood by the SOC config engine. In the DV environment, the intermediate C */ +/* Comment: // ** header file is called aop_soc_engine.h and is placed in the testgen* directory of */ +/* Comment: // ** the test results directory. The intermediate file and MCU config sequences are */ +/* Comment: // ** combined using the powgen_common.pl script, described below. */ +/* Comment: // ** */ +/* Comment: // ** tb_lib/cpu/armv8/mcu/mcu_init_aop.h */ +/* Comment: // ** Provided by the MCU team, mcu_init_aop.h contains the two sequences for configuring */ +/* Comment: // ** the DDR to operate at 48MHz and >= 800MHz. The 48MHz sequence is stitched into the */ +/* Comment: // ** S2R_AOP->AOP_DDR postamble at the comment token "INSERT_MCU_AOP_DDR_SEQ". The */ +/* Comment: // ** >= 800 MHz sequence is stitched into the AOP_DDR->AWAKE postamble at the comment */ +/* Comment: // ** token "INSERT_MCU_AWAKE_SEQ". */ +/* Comment: // ** */ +/* Comment: // ** chip/tb/cpu/bin/powgen_common.pl */ +/* Comment: // ** This script stitches together the aop_soc_engine.h file generated by aop_func_gen.pl */ +/* Comment: // ** and mcu_init_aop.h into the same AP EHEX file that is loaded into memory. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Poll for the proxy_osc clock to source LPO/8 before initiating minipmgr reset sequence */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_pre_0[] = { +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG ADDR=0x210240304 Retry_en=0 Retry_cnt=0*/ +0x000000c1, /* Offset */ +0x40300000, /* Mask */ +0x00200000, /* Data */ +/* Comment: // Do a dummy read to the AOP CPU revision register to cause a functional wakeup */ +0x21080002, /* Poll:AKF_AKFAPB_AKF_REV(GBI_AOP_AKF) ADDR=0x210800000 Retry_en=1 Retry_cnt=597*/ +0x00035500, /* Offset */ +0x00000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000004, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR POSTAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_0[] = { +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000000, /* Data */ +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up AOP_DDR transition */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Security sequence */ +/* Comment: // Write mem cache data and tag enable/lock bits to prevent backdoor access as RAM attacks */ +0x20000041, /* WR:AMCC_MCCCFG_MCCGEN(0) ADDR=0x200000780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +0x20020041, /* WR:AMCC_MCCCFG_MCCGEN(1) ADDR=0x200200780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +/* Comment: // Write lockable DRAM config regs */ +/* Comment: // INSERT_MCU_DDR_LOCKED */ +}; + +/* Comment: // The MCU LockRegion programming must occur before the security/TZ programming (s2r_aop_to_aop_ddr_post_security) */ +#define S2D_POST_MCU_LOCKED_AFTER 0 +#define S2D_POST_MCU_LOCKED_BEFORE 1 +/* Comment: // The security/TZ programming must occur after the MCU LockRegion programming */ +#define S2D_POST_SECURITY_AFTER 0 +#define S2D_POST_SECURITY_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR security postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_security[] = { +/* Comment: // Enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20000049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR(0) ADDR=0x200000480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR(0) ADDR=0x200000484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK(0) ADDR=0x200000490 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK(0) ADDR=0x200000490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20000049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR(0) ADDR=0x200000488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR(0) ADDR=0x20000048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK(0) ADDR=0x200000494 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK(0) ADDR=0x200000494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20020049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR(1) ADDR=0x200200480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR(1) ADDR=0x200200484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK(1) ADDR=0x200200490 */ +0x20020042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK(1) ADDR=0x200200490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20020049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR(1) ADDR=0x200200488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR(1) ADDR=0x20020048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK(1) ADDR=0x200200494 */ +0x20020042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK(1) ADDR=0x200200494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_1[] = { +/* Comment: // Disable AP_GID0 */ +0x2102d001, /* WR:MINIPMGR_SECURITY_SIO_AES_DISABLE ADDR=0x2102d0000 */ +0x00000000, /* Offset */ +0x00000002, /* Data */ +/* Comment: // SRAM region that must be locked ends here. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SW: */ +/* Comment: // ** */ +/* Comment: // ** Locked region is specified in 64B granularity. If the last security entry does not */ +/* Comment: // ** land neatly at the end of a 64B boundary, some non-security entries may be locked if */ +/* Comment: // ** no additional padding is used. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // Disable voltage changes (see radar 16038537) */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SiVal/SW: */ +/* Comment: // ** */ +/* Comment: // ** Per Manu, perf state entry 0 has been reserved for use by the config engine. SW agreed */ +/* Comment: // ** to use the perf state entries starting from the higher indices. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // transition the fabric and DRAM to work off the proxy clocks */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Clear the CSYSPWRUPREQ_LOOPBACK bit. See PMGR spec section 11.4.4.1 */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000000 /* Data */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define S2D_POST_PWRGATE_AFTER 1 +#define S2D_POST_PWRGATE_BEFORE 2 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 2/2/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x000f0003, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030303, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x001d0000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG0 ADDR=0x20e09c0b0 */ +0x00190003, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG1 ADDR=0x20e09c0b4 */ +0x010a0808, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG2 ADDR=0x20e09c0b8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG0 ADDR=0x20e09c0c0 */ +0x00150004, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG1 ADDR=0x20e09c0c4 */ +0x010a0808 /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_2[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x50603424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c180 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c140 */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x1000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x1000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x1000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x1000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000090 */ +0x00000024, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800094 */ +0x00000025, /* Offset */ +0x80017c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f00000c */ +0x00000003, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(0) ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +0x20020001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(1) ADDR=0x200200008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x5e5c5a58, /* Offset */ +0x66646260, /* Offset */ +0x6e6c6a68, /* Offset */ +0x76747270, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801d8 */ +0x20e0803d, /* 16-word write */ +0x7e7c7a78, /* Offset */ +0x86848280, /* Offset */ +0xd4525654, /* Offset */ +0xdcdad8d6, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e0 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 */ +0x20e08035, /* 14-word write */ +0xaca8a4d2, /* Offset */ +0xa0aaa6a2, /* Offset */ +0xc8429eae, /* Offset */ +0x00005044, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001 /* Data */ +}; + +#define S2D_POST_MCU_DDR_AFTER 2 +#define S2D_POST_MCU_DDR_BEFORE 3 +static const uint32_t s2r_aop_to_aop_ddr_post_3[] = { +/* Comment: // INSERT_MCU_AOP_DDR_SEQ */ +/* Comment: // Set the proxy fabric clock frequency back to 96MHz to save power in AOP_DDR */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->S2R_AOP PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_s2r_aop_pre_0[] = { +/* Comment: // Note - We do not wait for the memcache ways to reach 0 before yanking power. See radar 16051416 */ +/* Comment: // Set NO_HANDSHAKE bit prior to restoring the perf state table to its defaults, radar 16219268 */ +0x20e04081, /* WR:PMGR_CLKCTL_MCU_CLK_DEBUG ADDR=0x20e040810 */ +0x00000004, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Set all SRC_SEL for SOC clocks to 0 so there will be no clock glitches, radar 16409004 */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x00000030, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // power up PCIe/SIO/USB domain to bypass NLP:: Pcie2phy pwr clamp enable is going to X after warmboot in UPF simulations */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000052, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08035, /* 14-word write */ +0x9e56b0b2, /* Offset */ +0x908e8cd2, /* Offset */ +0x98969492, /* Offset */ +0x00009c9a, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x0000000f, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x0000000f, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x0000000f, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x0000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x0000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x0000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802c8 Retry_en=0 Retry_cnt=0*/ +0x000000b2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e0802c0 Retry_en=0 Retry_cnt=0*/ +0x000000b0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080158 Retry_en=0 Retry_cnt=0*/ +0x00000056, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080278 Retry_en=0 Retry_cnt=0*/ +0x0000009e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080348 Retry_en=0 Retry_cnt=0*/ +0x000000d2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080230 Retry_en=0 Retry_cnt=0*/ +0x0000008c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080238 Retry_en=0 Retry_cnt=0*/ +0x0000008e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080240 Retry_en=0 Retry_cnt=0*/ +0x00000090, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080248 Retry_en=0 Retry_cnt=0*/ +0x00000092, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080250 Retry_en=0 Retry_cnt=0*/ +0x00000094, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS4_PS ADDR=0x20e080258 Retry_en=0 Retry_cnt=0*/ +0x00000096, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS5_PS ADDR=0x20e080260 Retry_en=0 Retry_cnt=0*/ +0x00000098, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS6_PS ADDR=0x20e080268 Retry_en=0 Retry_cnt=0*/ +0x0000009a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS7_PS ADDR=0x20e080270 Retry_en=0 Retry_cnt=0*/ +0x0000009c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // wait 100us to delay retention reset per radar 18765287 */ +0x0012c004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_s2r_aop_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** See PMGR spec section 11.14.4 (Software Teardown for Awake Exit) */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_pre_0[] = { +/* Comment: // Restore the GPIO to its default configuration by setting GPIO_PS.RESET for 1us while setting MANUAL_PS to RUN_MAX */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x8000000f, /* Data */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x00000004, /* Data */ +/* Comment: // Disable voltage changes */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +0x20e06811, /* 5-word write */ +0x07060504, /* Offset */ +0x00000000, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0D ADDR=0x20e06801c */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Per radar 19338346, disable DynPwrDnEn after switch to bucket 3 */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20050041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(4) ADDR=0x200500424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20054041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(5) ADDR=0x200540424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20058041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(6) ADDR=0x200580424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2005c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(7) ADDR=0x2005c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +#endif + +/* Comment: // Power off PLLs that software could not turn off (ENABLE == 0 and BYPASS == 1) */ +0x20e00001, /* WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x00000000, /* Offset */ +0x280c8030, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x00000000, /* Offset */ +0x2803c010, /* Data */ +0x20e01801, /* WR:PMGR_PLL6_CTL ADDR=0x20e018000 */ +0x00000000, /* Offset */ +0x28032011, /* Data */ +0x20e01c01, /* WR:PMGR_PLL7_CTL ADDR=0x20e01c000 */ +0x00000000, /* Offset */ +0x2806f021, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x00000000, /* Offset */ +0x2818d06b, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t awake_to_aop_ddr_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.4 (Software Teardown for Awake Exit), either */ +/* Comment: // ** SW or the config engine may turn off SIO/PCIE. For DV simulations, we chose to power */ +/* Comment: // ** power down ALL of the unneeded blocks in the config engine rather than from the AP. This */ +/* Comment: // ** provided functionally equivalent behavior and allowed the AWAKE->AOP_DDR and */ +/* Comment: // ** S2R_AOP->AOP_DDR to appear symmetric. SiVal/SW may move parts of this sequence */ +/* Comment: // ** to AP software if desired. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_post_0[] = { +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define A2D_POST_PWRGATE_AFTER 0 +#define A2D_POST_PWRGATE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AWAKE->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 2/2/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x000f0003, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030303, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x001d0000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG0 ADDR=0x20e09c0b0 */ +0x00190003, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG1 ADDR=0x20e09c0b4 */ +0x010a0808, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG2 ADDR=0x20e09c0b8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG0 ADDR=0x20e09c0c0 */ +0x00150004, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG1 ADDR=0x20e09c0c4 */ +0x010a0808 /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t awake_to_aop_ddr_post_1[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x50603424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c180 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c140 */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x1000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x1000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x1000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x1000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000090 */ +0x00000024, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800094 */ +0x00000025, /* Offset */ +0x80017c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f00000c */ +0x00000003, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(0) ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +0x20020001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(1) ADDR=0x200200008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x5e5c5a58, /* Offset */ +0x66646260, /* Offset */ +0x6e6c6a68, /* Offset */ +0x76747270, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801d8 */ +0x20e0803d, /* 16-word write */ +0x7e7c7a78, /* Offset */ +0x86848280, /* Offset */ +0xd4525654, /* Offset */ +0xdcdad8d6, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e0 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 */ +0x20e08031, /* 13-word write */ +0xaca8a4d2, /* Offset */ +0xa0aaa6a2, /* Offset */ +0x44c89eae, /* Offset */ +0x00000050, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +0x20e0b83d, /* 16-word write */ +0x03020100, /* Offset */ +0x07060504, /* Offset */ +0x13121110, /* Offset */ +0x17161514, /* Offset */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH0 ADDR=0x20e0b8000 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH1 ADDR=0x20e0b8004 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH2 ADDR=0x20e0b8008 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH3 ADDR=0x20e0b800c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH4 ADDR=0x20e0b8010 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH5 ADDR=0x20e0b8014 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH6 ADDR=0x20e0b8018 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH7 ADDR=0x20e0b801c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH16 ADDR=0x20e0b8040 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH17 ADDR=0x20e0b8044 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH18 ADDR=0x20e0b8048 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH19 ADDR=0x20e0b804c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH20 ADDR=0x20e0b8050 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH21 ADDR=0x20e0b8054 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH22 ADDR=0x20e0b8058 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH23 ADDR=0x20e0b805c */ +/* Comment: // Reset and then clock gate the AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e10001, /* WR:AIC_GLOBALS_AICRST ADDR=0x20e10000c */ +0x00000003, /* Offset */ +0x00000001, /* Data */ +0x20e10002, /* Poll:AIC_GLOBALS_AICRST ADDR=0x20e10000c Retry_en=1 Retry_cnt=255*/ +0x0001ff03, /* Offset */ +0x00000001, /* Mask */ +0x00000000, /* Data */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x00000000, /* Data */ +0x2102b005, /* 2-word write */ +0x00000400, /* Offset */ +0x00000000, /* Data WR:MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER ADDR=0x2102b0000 */ +0x00000000 /* Data WR:MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER ADDR=0x2102b0010 */ +}; + +static const uint32_t awake_to_aop_ddr_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_pre_0[] = { +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up AOP_DDR->AWAKE transition */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Powering up SIO partition and SIO devices */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000052, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x00000056, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080158 Retry_en=1 Retry_cnt=255*/ +0x0001ff56, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_P_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_P_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e0803d, /* 16-word write */ +0x5e5c5a58, /* Offset */ +0x66646260, /* Offset */ +0x6e6c6a68, /* Offset */ +0x76747270, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080160 */ +0x00000004, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080168 */ +0x00000004, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080170 */ +0x00000004, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080178 */ +0x00000004, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080180 */ +0x00000004, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080188 */ +0x00000004, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080190 */ +0x00000004, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e080198 */ +0x00000004, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 */ +0x00000004, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 */ +0x00000004, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 */ +0x00000004, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 */ +0x00000004, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 */ +0x00000004, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 */ +0x00000004, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d0 */ +0x00000004, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801d8 */ +0x20e0801d, /* 8-word write */ +0x7e7c7a78, /* Offset */ +0x86848280, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e0 */ +0x00000004, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801e8 */ +0x00000004, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f0 */ +0x00000004, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e0801f8 */ +0x00000004, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080200 */ +0x00000004, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080208 */ +0x00000004, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080210 */ +0x00000004, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080218 */ +/* Comment: // It might not be required to do all of the following polls since they should take the same amount of time to power up. */ +/* Comment: // One possible optimization is to only do the poll for the last write */ +0x20e08002, /* Poll:PMGR_PS_MCA0_PS ADDR=0x20e080160 Retry_en=1 Retry_cnt=255*/ +0x0001ff58, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA1_PS ADDR=0x20e080168 Retry_en=1 Retry_cnt=255*/ +0x0001ff5a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA2_PS ADDR=0x20e080170 Retry_en=1 Retry_cnt=255*/ +0x0001ff5c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA3_PS ADDR=0x20e080178 Retry_en=1 Retry_cnt=255*/ +0x0001ff5e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA4_PS ADDR=0x20e080180 Retry_en=1 Retry_cnt=255*/ +0x0001ff60, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PWM0_PS ADDR=0x20e080188 Retry_en=1 Retry_cnt=255*/ +0x0001ff62, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C0_PS ADDR=0x20e080190 Retry_en=1 Retry_cnt=255*/ +0x0001ff64, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C1_PS ADDR=0x20e080198 Retry_en=1 Retry_cnt=255*/ +0x0001ff66, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 Retry_en=1 Retry_cnt=255*/ +0x0001ff68, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 Retry_en=1 Retry_cnt=255*/ +0x0001ff6c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 Retry_en=1 Retry_cnt=255*/ +0x0001ff70, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 Retry_en=1 Retry_cnt=255*/ +0x0001ff72, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART0_PS ADDR=0x20e0801d0 Retry_en=1 Retry_cnt=255*/ +0x0001ff74, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART1_PS ADDR=0x20e0801d8 Retry_en=1 Retry_cnt=255*/ +0x0001ff76, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART2_PS ADDR=0x20e0801e0 Retry_en=1 Retry_cnt=255*/ +0x0001ff78, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART3_PS ADDR=0x20e0801e8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART4_PS ADDR=0x20e0801f0 Retry_en=1 Retry_cnt=255*/ +0x0001ff7c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART5_PS ADDR=0x20e0801f8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART6_PS ADDR=0x20e080200 Retry_en=1 Retry_cnt=255*/ +0x0001ff80, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART7_PS ADDR=0x20e080208 Retry_en=1 Retry_cnt=255*/ +0x0001ff82, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART8_PS ADDR=0x20e080210 Retry_en=1 Retry_cnt=255*/ +0x0001ff84, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AES0_PS ADDR=0x20e080218 Retry_en=1 Retry_cnt=255*/ +0x0001ff86, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up PCIE partition and PCIE devices/link */ +0x20e08001, /* WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x000000d2, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080348 Retry_en=1 Retry_cnt=255*/ +0x0001ffd2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xdad8d6d4, /* Offset */ +0x000000dc, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 */ +0x20e08002, /* Poll:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 Retry_en=1 Retry_cnt=255*/ +0x0001ffd4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 Retry_en=1 Retry_cnt=255*/ +0x0001ffd6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 Retry_en=1 Retry_cnt=255*/ +0x0001ffd8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 Retry_en=1 Retry_cnt=255*/ +0x0001ffda, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 Retry_en=1 Retry_cnt=255*/ +0x0001ffdc, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up USB partition and USB devices */ +0x20e08001, /* WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x0000009e, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080278 Retry_en=1 Retry_cnt=255*/ +0x0001ff9e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xa6a2a0ae, /* Offset */ +0x000000aa, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 */ +0x00000004, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 */ +0x20e08002, /* Poll:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 Retry_en=1 Retry_cnt=255*/ +0x0001ffae, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 Retry_en=1 Retry_cnt=255*/ +0x0001ffa0, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 Retry_en=1 Retry_cnt=255*/ +0x0001ffa2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 Retry_en=1 Retry_cnt=255*/ +0x0001ffa6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 Retry_en=1 Retry_cnt=255*/ +0x0001ffaa, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08009, /* 3-word write */ +0x00aca8a4, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 Retry_en=1 Retry_cnt=255*/ +0x0001ffa4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 Retry_en=1 Retry_cnt=255*/ +0x0001ffa8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 Retry_en=1 Retry_cnt=255*/ +0x0001ffac, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_PMP_PS ADDR=0x20e080320 */ +0x000000c8, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PMP_PS ADDR=0x20e080320 Retry_en=1 Retry_cnt=255*/ +0x0001ffc8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Restore PMS, SBR, SF, SMX, MCC, and DCS* PS to reset values per CoreOS request from radar 19132562 */ +0x00000044, /* NOP to align binary to 64-bit boundary before ifdef */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20e0802d, /* 12-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x50444694, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802c8 Retry_en=1 Retry_cnt=255*/ +0x0001ffb2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e0802c0 Retry_en=1 Retry_cnt=255*/ +0x0001ffb0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 Retry_en=1 Retry_cnt=255*/ +0x0001ff50, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20e0803d, /* 16-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x5044469c, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x0000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x0000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x0000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802c8 Retry_en=1 Retry_cnt=255*/ +0x0001ffb2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e0802c0 Retry_en=1 Retry_cnt=255*/ +0x0001ffb0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS4_PS ADDR=0x20e080258 Retry_en=1 Retry_cnt=255*/ +0x0001ff96, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS5_PS ADDR=0x20e080260 Retry_en=1 Retry_cnt=255*/ +0x0001ff98, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS6_PS ADDR=0x20e080268 Retry_en=1 Retry_cnt=255*/ +0x0001ff9a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS7_PS ADDR=0x20e080270 Retry_en=1 Retry_cnt=255*/ +0x0001ff9c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 Retry_en=1 Retry_cnt=255*/ +0x0001ff50, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x00000044, /* NOP to align binary to 64-bit boundary before endif */ +#endif + +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a0 */ +0x00000028, /* Offset */ +0x80101000, /* Data */ +/* Comment: // wait 1us */ +0x00003004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_awake_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.3 (Software Init for AOP_DDR to AWAKE), the */ +/* Comment: // ** config engine restores the state of the chip in this step. The specific use cases where */ +/* Comment: // ** the config engine is the owner of state restoration are not yet defined. */ +/* Comment: // ** */ +/* Comment: // ** The sequence below contains the minimum set of commands to re-boot the AP and restore */ +/* Comment: // ** DRAM operation at bucket 1. AP may bring DRAM up to bucket 0. */ +/* Comment: // ** */ +/* Comment: // ** It is assumed that SW will add extensively to this sequence for state restoration based */ +/* Comment: // ** on future use cases. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +#define D2A_POST_MCU_AWAKE_AFTER -1 +#define D2A_POST_MCU_AWAKE_BEFORE 0 +static const uint32_t aop_ddr_to_awake_post_0[] = { +/* Comment: // Wait 900us as first step of AOP_DDR->AWAKE per radar 20181763 to ensure BIRA loading is complete */ +/* Comment: // prior to powering on any non-AOP power domain */ +0x00a8c004, /* Cfg Count(Delay.Wait) */ +/* Comment: // INSERT_MCU_AWAKE_SEQ */ +/* Comment: // Restore the state of the chip */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a0 */ +0x00000028, /* Offset */ +0x80100000, /* Data */ +/* Comment: // wait 1us */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +#define D2A_POST_RESTORE_AFTER 0 +#define D2A_POST_RESTORE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AOP_DDR->AWAKE system restore postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_post_restore[] = { +/* Comment: // DV writes small values for PLL_RESET_*TIME and LOCK_TIME to speed up simulation */ +/* Comment: // SW/SiVal should use real values here */ +0x20e00001, /* WR:PMGR_PLL0_PLL_DELAY_CTL1 ADDR=0x20e000020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00005, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL0_CFG ADDR=0x20e000004 */ +0xa00c8030, /* Data WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x20e00002, /* Poll:PMGR_PLL0_CTL ADDR=0x20e000000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_PLL_DELAY_CTL1 ADDR=0x20e004020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00405, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL1_CFG ADDR=0x20e004004 */ +0xa003c010, /* Data WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x20e00402, /* Poll:PMGR_PLL1_CTL ADDR=0x20e004000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e01801, /* WR:PMGR_PLL6_PLL_DELAY_CTL1 ADDR=0x20e018020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e01805, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL6_CFG ADDR=0x20e018004 */ +0xa0032011, /* Data WR:PMGR_PLL6_CTL ADDR=0x20e018000 */ +0x20e01802, /* Poll:PMGR_PLL6_CTL ADDR=0x20e018000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e01c01, /* WR:PMGR_PLL7_PLL_DELAY_CTL1 ADDR=0x20e01c020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e01c05, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL7_CFG ADDR=0x20e01c004 */ +0xa006f021, /* Data WR:PMGR_PLL7_CTL ADDR=0x20e01c000 */ +0x20e01c02, /* Poll:PMGR_PLL7_CTL ADDR=0x20e01c000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_PLL_DELAY_CTL1 ADDR=0x20e00c020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00c05, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL3_CFG ADDR=0x20e00c004 */ +0xa018d06b, /* Data WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x20e00c02, /* Poll:PMGR_PLL3_CTL ADDR=0x20e00c000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Bring MCU up to bucket0 */ +/* Comment: // write: reg_name=PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A reg_value=55555539 */ +0x20e06819, /* 7-word write */ +0x10060504, /* Offset */ +0x00001211, /* Offset */ +0x55555505, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x55055666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000555, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x5555bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_3A ADDR=0x20e068040 */ +0x55055666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_3B ADDR=0x20e068044 */ +0x00000555, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_3C ADDR=0x20e068048 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Tunables may be re-applied here */ +0x20e08001, /* WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000044, /* Offset */ +0x0000024f, /* Data */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044, /* CFG Count to aling 64 bit write to 16 bytes address:*/ +0x20205003, /* WR:ACC_CPU0_IMPL_IO_RVBAR ADDR=0x202050000 */ +0x00000000, /* Offset */ +0x00000000, /* Data */ +0x00000008 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_post_1[] = { + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20050041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(4) ADDR=0x200500424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20054041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(5) ADDR=0x200540424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20058041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(6) ADDR=0x200580424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2005c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(7) ADDR=0x2005c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +#endif + +/* Comment: // Per radar 20183074, turn the following partitions on one at a time */ +0x20e08001, /* WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802d0 */ +0x000000b4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_RTMUX_PS ADDR=0x20e0802d0 Retry_en=0 Retry_cnt=0*/ +0x000000b4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_ISP_PS ADDR=0x20e080300 */ +0x000000c0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_ISP_PS ADDR=0x20e080300 Retry_en=0 Retry_cnt=0*/ +0x000000c0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MEDIA_PS ADDR=0x20e080308 */ +0x000000c2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MEDIA_PS ADDR=0x20e080308 Retry_en=0 Retry_cnt=0*/ +0x000000c2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MSR_PS ADDR=0x20e080318 */ +0x000000c6, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MSR_PS ADDR=0x20e080318 Retry_en=0 Retry_cnt=0*/ +0x000000c6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VDEC0_PS ADDR=0x20e080330 */ +0x000000cc, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VDEC0_PS ADDR=0x20e080330 Retry_en=0 Retry_cnt=0*/ +0x000000cc, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080340 */ +0x000000d0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VENC_CPU_PS ADDR=0x20e080340 Retry_en=0 Retry_cnt=0*/ +0x000000d0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000002, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 Retry_en=0 Retry_cnt=0*/ +0x00000002, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x00000004, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 Retry_en=0 Retry_cnt=0*/ +0x00000004, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_GFX_PS ADDR=0x20e080388 */ +0x000000e2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GFX_PS ADDR=0x20e080388 Retry_en=0 Retry_cnt=0*/ +0x000000e2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_DISP1MUX_PS ADDR=0x20e0802e8 */ +0x000000ba, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DISP1MUX_PS ADDR=0x20e0802e8 Retry_en=0 Retry_cnt=0*/ +0x000000ba, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_SRS_PS ADDR=0x20e080390 */ +0x000000e4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SRS_PS ADDR=0x20e080390 Retry_en=0 Retry_cnt=0*/ +0x000000e4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08041, /* WR:PMGR_PS_SEP_PS ADDR=0x20e080400 */ +0x00000000, /* Offset */ +0x4000000f, /* Data */ +0x20e08042, /* Poll:PMGR_PS_SEP_PS ADDR=0x20e080400 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +/* Comment: // Per CoreOS request, turn off the above PS registers (except SEP_PS, which cannot be turned off by config engine) */ +0x20e08809, /* 3-word write */ +0x00040200, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x20e08021, /* 9-word write */ +0xd0e2bae4, /* Offset */ +0xc0c2c6cc, /* Offset */ +0x000000b4, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_SRS_PS ADDR=0x20e080390 */ +0x00000000, /* Data WR:PMGR_PS_DISP1MUX_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_GFX_PS ADDR=0x20e080388 */ +0x00000000, /* Data WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080340 */ +0x00000000, /* Data WR:PMGR_PS_VDEC0_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_MSR_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_MEDIA_PS ADDR=0x20e080308 */ +0x00000000, /* Data WR:PMGR_PS_ISP_PS ADDR=0x20e080300 */ +0x00000000, /* Data WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802d0 */ +/* Comment: // Set the proxy clock back to 96MHz to save power */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +// +// This additional stitch point is an intentional deviation from the SEG-provided +// sequence. +// +#define D2A_POST_PREBOOT_BEFORE 2 +static const uint32_t aop_ddr_to_awake_post_2[] = { +/* Comment: // Boot CPU0 by writing to the WAKE_CORES register */ +0x20e0d401, /* WR:PMGR_MISC_CORES_WAKE_CORES ADDR=0x20e0d4008 */ +0x00000002, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t aop_ddr_to_awake_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + + +typedef struct { + uint32_t *sequence; + size_t elements; +} reconfig_subsequence_t; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_pre_0, sizeof(aop_ddr_to_awake_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_pre_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_pre_0, sizeof(awake_to_aop_ddr_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_s2r_aop_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_s2r_aop_pre_0, sizeof(aop_ddr_to_s2r_aop_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_post_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_post_0, sizeof(s2r_aop_to_aop_ddr_post_0) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_1, sizeof(s2r_aop_to_aop_ddr_post_1) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_2, sizeof(s2r_aop_to_aop_ddr_post_2) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_post_3, sizeof(s2r_aop_to_aop_ddr_post_3) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_pre_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_pre_0, sizeof(s2r_aop_to_aop_ddr_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_post_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_post_0, sizeof(aop_ddr_to_awake_post_0) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_post_1, sizeof(aop_ddr_to_awake_post_1) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_post_2, sizeof(aop_ddr_to_awake_post_2) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_post_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_post_0, sizeof(awake_to_aop_ddr_post_0) / sizeof(uint32_t) }, + { (uint32_t *) awake_to_aop_ddr_post_1, sizeof(awake_to_aop_ddr_post_1) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +#endif // AOP_CONFIG_SEQUENCES_H diff --git a/platform/s8000/include/platform/soc/reconfig_sequences_s8001_a0.h b/platform/s8000/include/platform/soc/reconfig_sequences_s8001_a0.h new file mode 100644 index 0000000..93cfcf9 --- /dev/null +++ b/platform/s8000/include/platform/soc/reconfig_sequences_s8001_a0.h @@ -0,0 +1,1794 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef AOP_CONFIG_SEQUENCES_A0_H +#define AOP_CONFIG_SEQUENCES_A0_H + + +#if DCS_NUM_CHANNELS == 8 +#define AMC_PARAM_EIGHT_CH_ONE_RANK +#include "reconfig_sequences_mcu_8ch_s8001_a0.h" +#else +#include "reconfig_sequences_mcu_4ch_s8001_a0.h" +#endif + +// _ _ _ _ +// / \ _ _| |_ ___ __ _ ___ _ __ ___ _ __ __ _| |_ ___ __| | +// / _ \| | | | __/ _ \ / _` |/ _ \ '_ \ / _ \ '__/ _` | __/ _ \/ _` | +// / ___ \ |_| | || (_) | (_| | __/ | | | __/ | | (_| | || __/ (_| | +// /_/ \_\__,_|\__\___/ \__, |\___|_| |_|\___|_| \__,_|\__\___|\__,_| +// ____ |___/ _____ _ _ _ +// | _ \ ___ _ __ ___ | |_ | ____|__| (_) |_ +// | | | |/ _ \ | '_ \ / _ \| __| | _| / _` | | __| +// | |_| | (_) | | | | | (_) | |_ | |__| (_| | | |_ +// |____/ \___/ |_| |_|\___/ \__| |_____\__,_|_|\__| +// + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP SOC CONFIG SEQUENCES */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** RELEASE NOTES */ +/* Comment: // ** */ +/* Comment: // ** -- 2/8/2015 -- */ +/* Comment: // ** Added "verbatim" command which will print the specified text verbatim in the final */ +/* Comment: // ** output file. This is used for putting #defines into the final header file for SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 2/5/2015 -- */ +/* Comment: // ** Introduced ifdef command for 4ch vs 8ch mode. Moved 4ch and 8ch differences back */ +/* Comment: // ** into aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** Note: Nested ifdefs are not supported! */ +/* Comment: // ** */ +/* Comment: // ** -- 2/4/2015 -- */ +/* Comment: // ** Ported stitch sequences to Elba. Moved 4ch and 8ch differences into stitched files. */ +/* Comment: // ** Deleted 4ch version of aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/29/2015 -- */ +/* Comment: // ** Updated sequences based on CoreOS feedback from radars 19132562 and 19148279. */ +/* Comment: // ** Added "stitch" command to stitch in sequences from external files. Intended to */ +/* Comment: // ** explicitly annotate which sequences are meant to be overridden by SW. */ +/* Comment: // ** */ +/* Comment: // ** -- 1/26/2015 -- */ +/* Comment: // ** Disable DynPwrDn in AOP_DDR (see radar 19338346) */ +/* Comment: // ** */ +/* Comment: // ** -- 11/12/2014 -- */ +/* Comment: // ** Added S2R_AOP->AOP_DDR preamble which polls for proxy_osc_clk to be equal to lpo/8. */ +/* Comment: // ** Activating the S2R_AOP->AOP_DDR preamble forces the LPO to be on prior to the */ +/* Comment: // ** AOP-PMU handshake. See radar 18563566 for details. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/22/2014 -- */ +/* Comment: // ** Config engine changes the current perf state to 0 prior to polling. */ +/* Comment: // ** */ +/* Comment: // ** -- 7/17/2014 -- */ +/* Comment: // ** Removed MCU bucket 1 transitions per radar 17699704. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/26/2014 -- */ +/* Comment: // ** Instead of implicitly stitching the 48->800 MCU sequence at the beginning of the */ +/* Comment: // ** AOP_DDR->AWAKE sequence, it is now inserted at the comment token labeled */ +/* Comment: // ** "INSERT_MCU_AWAKE_SEQ". This will make the sequence more flexible in case commands */ +/* Comment: // ** are to be inserted before the MCU sequence, e.g., changing tunables. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/20/2014 -- */ +/* Comment: // ** Added more documentation to aop_soc_cfg.seq. */ +/* Comment: // ** */ +/* Comment: // ** -- 6/4/2014 -- */ +/* Comment: // ** In this update, we removed the need to specify reg_addr in the write/write64/poll */ +/* Comment: // ** commands. The reg_addr was prone to human error because it was manually written, */ +/* Comment: // ** so there is no guarantee that the address matches the register name. Furthermore, */ +/* Comment: // ** manually specifying the register address is not future-proof because addresses of */ +/* Comment: // ** registers may change from chip to chip. */ +/* Comment: // ** */ +/* Comment: // ** Now, the register address are calculated based on the register name and the include */ +/* Comment: // ** files. The user must ensure that all of the header files needed are specified */ +/* Comment: // ** using the "include:" command. In the DV environment, these header files were */ +/* Comment: // ** generated from SPDS. */ +/* Comment: // ** */ +/* Comment: // ** Note: For legacy reasons, we still support manually specifying the reg_addr field. */ +/* Comment: // ** If the reg_addr field is specified, the reg_name field is ignored during the */ +/* Comment: // ** generation of the .h file. */ +/* Comment: // ** */ +/* Comment: // ** We also renamed the file type of this file from .h to .seq. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** */ +/* Comment: // ** This file contains the AOP SoC config sequences verified by DV. It is written in a */ +/* Comment: // ** pseudo-language that is parsed by the scripts described in the "Related files" section */ +/* Comment: // ** below. All commands must be contained within a single line. */ +/* Comment: // ** */ +/* Comment: // ** The supported commands are: */ +/* Comment: // ** */ +/* Comment: // ** include: */ +/* Comment: // ** Header file to include for looking up register addresses. The path to the include */ +/* Comment: // ** files is provided as an argument to the aop_func_gen.pl script described below. */ +/* Comment: // ** */ +/* Comment: // ** seq_name: */ +/* Comment: // ** Designates the start of a sequence. The supported sequences are: */ +/* Comment: // ** s2r_aop_to_aop_ddr_a0_pre */ +/* Comment: // ** s2r_aop_to_aop_ddr_a0_post */ +/* Comment: // ** aop_ddr_to_s2r_aop_a0_pre */ +/* Comment: // ** aop_ddr_to_s2r_aop_a0_post */ +/* Comment: // ** aop_ddr_to_awake_a0_pre */ +/* Comment: // ** aop_ddr_to_awake_a0_post */ +/* Comment: // ** awake_to_aop_ddr_a0_pre */ +/* Comment: // ** awake_to_aop_ddr_a0_post */ +/* Comment: // ** Note that s2r_aop_to_aop_ddr_a0_pre and aop_ddr_to_s2r_aop_a0_post are currently unused. */ +/* Comment: // ** */ +/* Comment: // ** endseq */ +/* Comment: // ** Designates the end of a sequence. */ +/* Comment: // ** */ +/* Comment: // ** write: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 32-bit write command to the register at 36-bit hex
with 32-bit hex . */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write64: reg_name= [reg_addr=
] reg_value= */ +/* Comment: // ** 64-bit write command to the 36-bit hex
with 64-bit value , */ +/* Comment: // ** where "upper" is the upper 32-bit hex value, and "lower" is the lower 32-bit hex */ +/* Comment: // ** value. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** write_start */ +/* Comment: // ** Designates the start of a write command with multiple register writes. Refer to */ +/* Comment: // ** AOP spec section 6.1 "Configuration Write Command" for details. Because the */ +/* Comment: // ** annotation with "write_start" and "write_end" is manually done, it is the */ +/* Comment: // ** responsibility of the author to ensure that the combined writes are within the */ +/* Comment: // ** same 1KB block, and a max of 16 writes is included. */ +/* Comment: // ** */ +/* Comment: // ** write_end */ +/* Comment: // ** Designates the end of a multi-register write command. */ +/* Comment: // ** */ +/* Comment: // ** poll: reg_name= [reg_addr=
] reg_value= reg_mask= retry_en= retry_cnt= */ +/* Comment: // ** Reads 36-bit
until (read_data & mask == value). If is 0, the */ +/* Comment: // ** poll repeats indefinitely. If is set, the read is retried up to */ +/* Comment: // ** times. As with "write" and "write64", is not used. */ +/* Comment: // ** If reg_addr is specified, reg_name is ignored (except for generation of .c file). */ +/* Comment: // ** */ +/* Comment: // ** cfg_cnt: */ +/* Comment: // ** designates the number of aop_clk cycles to wait before executing the next */ +/* Comment: // ** command. */ +/* Comment: // ** */ +/* Comment: // ** cfg_end */ +/* Comment: // ** Designates the Configuration End Command. */ +/* Comment: // ** */ +/* Comment: // ** comment: */ +/* Comment: // ** Designates a comment. */ +/* Comment: // ** */ +/* Comment: // ** stitch: */ +/* Comment: // ** Stitches file.seq into the sequence inline. */ +/* Comment: // ** */ +/* Comment: // ** stitch_h: */ +/* Comment: // ** In the generated .h file, an explicit #include "file.h" will appear at this line. */ +/* Comment: // ** */ +/* Comment: // ** Related files: */ +/* Comment: // ** tb_lib/cpu/armv7/aop_lib/aop_func_gen.pl */ +/* Comment: // ** This script parses this file (aop_soc_cfg.h) and converts it into an intermediate */ +/* Comment: // ** C header format. The output file contains C arrays whose contents are in a format */ +/* Comment: // ** understood by the SOC config engine. In the DV environment, the intermediate C */ +/* Comment: // ** header file is called aop_soc_engine.h and is placed in the testgen* directory of */ +/* Comment: // ** the test results directory. The intermediate file and MCU config sequences are */ +/* Comment: // ** combined using the powgen_common.pl script, described below. */ +/* Comment: // ** */ +/* Comment: // ** tb_lib/cpu/armv8/mcu/mcu_init_aop.h */ +/* Comment: // ** Provided by the MCU team, mcu_init_aop.h contains the two sequences for configuring */ +/* Comment: // ** the DDR to operate at 48MHz and >= 800MHz. The 48MHz sequence is stitched into the */ +/* Comment: // ** S2R_AOP->AOP_DDR postamble at the comment token "INSERT_MCU_AOP_DDR_SEQ". The */ +/* Comment: // ** >= 800 MHz sequence is stitched into the AOP_DDR->AWAKE postamble at the comment */ +/* Comment: // ** token "INSERT_MCU_AWAKE_SEQ". */ +/* Comment: // ** */ +/* Comment: // ** chip/tb/cpu/bin/powgen_common.pl */ +/* Comment: // ** This script stitches together the aop_soc_engine.h file generated by aop_func_gen.pl */ +/* Comment: // ** and mcu_init_aop.h into the same AP EHEX file that is loaded into memory. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Poll for the proxy_osc clock to source LPO/8 before initiating minipmgr reset sequence */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_pre_0[] = { +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG ADDR=0x210240304 Retry_en=0 Retry_cnt=0*/ +0x000000c1, /* Offset */ +0x40300000, /* Mask */ +0x00200000, /* Data */ +/* Comment: // Do a dummy read to the AOP CPU revision register to cause a functional wakeup */ +0x21080002, /* Poll:AKF_AKFAPB_AKF_REV(GBI_AOP_AKF) ADDR=0x210800000 Retry_en=1 Retry_cnt=597*/ +0x00035500, /* Offset */ +0x00000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000004, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** S2R_AOP->AOP_DDR POSTAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_post_0[] = { +/* Comment: // for radar 20547317: AOP-CPU powering up around the time AOP-DDR partitions are undergoing BIRA repair */ +0x21029c01, /* WR:MINIPMGR_MINI_PWRGATE_PWR_AOP_CPU_DBG ADDR=0x21029c00c */ +0x00000003, /* Offset */ +0x00000000, /* Data */ +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up AOP_DDR transition */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Security sequence */ +/* Comment: // Write mem cache data and tag enable/lock bits to prevent backdoor access as RAM attacks */ +0x20000041, /* WR:AMCC_MCCCFG_MCCGEN(0) ADDR=0x200000780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +0x20020041, /* WR:AMCC_MCCCFG_MCCGEN(1) ADDR=0x200200780 */ +0x000000e0, /* Offset */ +0x00010120, /* Data */ +/* Comment: // Write lockable DRAM config regs */ +/* Comment: // INSERT_MCU_DDR_LOCKED */ +}; + +/* Comment: // The MCU LockRegion programming must occur before the security/TZ programming (s2r_aop_to_aop_ddr_a0_post_security) */ +#define S2D_POST_MCU_LOCKED_AFTER 0 +#define S2D_POST_MCU_LOCKED_BEFORE 1 +/* Comment: // The security/TZ programming must occur after the MCU LockRegion programming */ +#define S2D_POST_SECURITY_AFTER 0 +#define S2D_POST_SECURITY_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR security postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_post_security[] = { +/* Comment: // Enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20000049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR(0) ADDR=0x200000480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR(0) ADDR=0x200000484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK(0) ADDR=0x200000490 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK(0) ADDR=0x200000490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20000049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR(0) ADDR=0x200000488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR(0) ADDR=0x20000048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK(0) ADDR=0x200000494 */ +0x20000042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK(0) ADDR=0x200000494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // enable AMCC Trust Zone 0 for SEP. Lock range = 0x8_3D00_0000 => 0x8_3d01_0fff */ +0x20020049, /* 3-word write */ +0x00242120, /* Offset */ +0x0003d000, /* Data WR:AMCC_MCCLOCKREGION_TZ0BASEADDR(1) ADDR=0x200200480 */ +0x0003d010, /* Data WR:AMCC_MCCLOCKREGION_TZ0ENDADDR(1) ADDR=0x200200484 */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ0LOCK(1) ADDR=0x200200490 */ +0x20020042, /* Poll:AMCC_MCCLOCKREGION_TZ0LOCK(1) ADDR=0x200200490 Retry_en=1 Retry_cnt=255*/ +0x0001ff24, /* Offset */ +0x00000001, /* Mask */ +0x00000001, /* Data */ +/* Comment: // enable AMCC Trust Zone 1 for AP. Lock range = 0x8_3C00_0000 => 0x8_3C01_0fff */ +0x20020049, /* 3-word write */ +0x00252322, /* Offset */ +0x0003c000, /* Data WR:AMCC_MCCLOCKREGION_TZ1BASEADDR(1) ADDR=0x200200488 */ +0x0003c010, /* Data WR:AMCC_MCCLOCKREGION_TZ1ENDADDR(1) ADDR=0x20020048c */ +0x00000001, /* Data WR:AMCC_MCCLOCKREGION_TZ1LOCK(1) ADDR=0x200200494 */ +0x20020042, /* Poll:AMCC_MCCLOCKREGION_TZ1LOCK(1) ADDR=0x200200494 Retry_en=1 Retry_cnt=255*/ +0x0001ff25, /* Offset */ +0x00000001, /* Mask */ +0x00000001 /* Data */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_1[] = { +/* Comment: // Disable AP_GID0 */ +0x2102d001, /* WR:MINIPMGR_SECURITY_SIO_AES_DISABLE ADDR=0x2102d0000 */ +0x00000000, /* Offset */ +0x00000002, /* Data */ +/* Comment: // SRAM region that must be locked ends here. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SW: */ +/* Comment: // ** */ +/* Comment: // ** Locked region is specified in 64B granularity. If the last security entry does not */ +/* Comment: // ** land neatly at the end of a 64B boundary, some non-security entries may be locked if */ +/* Comment: // ** no additional padding is used. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // Disable voltage changes (see radar 16038537) */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** Note for SiVal/SW: */ +/* Comment: // ** */ +/* Comment: // ** Per Manu, perf state entry 0 has been reserved for use by the config engine. SW agreed */ +/* Comment: // ** to use the perf state entries starting from the higher indices. */ +/* Comment: // ****************************************************************************************** */ +/* Comment: // transition the fabric and DRAM to work off the proxy clocks */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Clear the CSYSPWRUPREQ_LOOPBACK bit. See PMGR spec section 11.4.4.1 */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000000 /* Data */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define S2D_POST_PWRGATE_AFTER 1 +#define S2D_POST_PWRGATE_BEFORE 2 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of S2R_AOP->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 2/2/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t s2r_aop_to_aop_ddr_a0_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x000f0003, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030303, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x001d0000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG0 ADDR=0x20e09c0b0 */ +0x00190003, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG1 ADDR=0x20e09c0b4 */ +0x010a0808, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG2 ADDR=0x20e09c0b8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG0 ADDR=0x20e09c0c0 */ +0x00150004, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG1 ADDR=0x20e09c0c4 */ +0x010a0808 /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_2[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x50603424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c180 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c140 */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x1000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x1000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x1000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x1000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000090 */ +0x00000024, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800094 */ +0x00000025, /* Offset */ +0x80017c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f00000c */ +0x00000003, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(0) ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +0x20020001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(1) ADDR=0x200200008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x5e5c5a58, /* Offset */ +0x66646260, /* Offset */ +0x6e6c6a68, /* Offset */ +0x76747270, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801d8 */ +0x20e0803d, /* 16-word write */ +0x7e7c7a78, /* Offset */ +0x86848280, /* Offset */ +0xd4525654, /* Offset */ +0xdcdad8d6, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e0 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 */ +0x20e08035, /* 14-word write */ +0xaca8a4d2, /* Offset */ +0xa0aaa6a2, /* Offset */ +0xc8429eae, /* Offset */ +0x00005044, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001 /* Data */ +}; + +#define S2D_POST_MCU_DDR_AFTER 2 +#define S2D_POST_MCU_DDR_BEFORE 3 +static const uint32_t s2r_aop_to_aop_ddr_a0_post_3[] = { +/* Comment: // INSERT_MCU_AOP_DDR_SEQ */ +/* Comment: // Set the proxy fabric clock frequency back to 96MHz to save power in AOP_DDR */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t s2r_aop_to_aop_ddr_a0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->S2R_AOP PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_s2r_aop_a0_pre_0[] = { +/* Comment: // Note - We do not wait for the memcache ways to reach 0 before yanking power. See radar 16051416 */ +/* Comment: // Set NO_HANDSHAKE bit prior to restoring the perf state table to its defaults, radar 16219268 */ +0x20e04081, /* WR:PMGR_CLKCTL_MCU_CLK_DEBUG ADDR=0x20e040810 */ +0x00000004, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Set all SRC_SEL for SOC clocks to 0 so there will be no clock glitches, radar 16409004 */ +0x20e06809, /* 3-word write */ +0x00000504, /* Offset */ +0x00000030, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // power up PCIe/SIO/USB domain to bypass NLP:: Pcie2phy pwr clamp enable is going to X after warmboot in UPF simulations */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000052, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08035, /* 14-word write */ +0x9e56b0b2, /* Offset */ +0x908e8cd2, /* Offset */ +0x98969492, /* Offset */ +0x00009c9a, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x0000000f, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x0000000f, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x0000000f, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x0000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x0000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x0000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802c8 Retry_en=0 Retry_cnt=0*/ +0x000000b2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e0802c0 Retry_en=0 Retry_cnt=0*/ +0x000000b0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080158 Retry_en=0 Retry_cnt=0*/ +0x00000056, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080278 Retry_en=0 Retry_cnt=0*/ +0x0000009e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080348 Retry_en=0 Retry_cnt=0*/ +0x000000d2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080230 Retry_en=0 Retry_cnt=0*/ +0x0000008c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080238 Retry_en=0 Retry_cnt=0*/ +0x0000008e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080240 Retry_en=0 Retry_cnt=0*/ +0x00000090, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080248 Retry_en=0 Retry_cnt=0*/ +0x00000092, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080250 Retry_en=0 Retry_cnt=0*/ +0x00000094, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS4_PS ADDR=0x20e080258 Retry_en=0 Retry_cnt=0*/ +0x00000096, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS5_PS ADDR=0x20e080260 Retry_en=0 Retry_cnt=0*/ +0x00000098, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS6_PS ADDR=0x20e080268 Retry_en=0 Retry_cnt=0*/ +0x0000009a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS7_PS ADDR=0x20e080270 Retry_en=0 Retry_cnt=0*/ +0x0000009c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x2102cc01, /* WR:MINIPMGR_MINI_PWR_STATE_TRANS_STATE_TRANS_CTL ADDR=0x2102cc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // wait 100us to delay retention reset per radar 18765287 */ +0x0012c004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_s2r_aop_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR PREAMBLE */ +/* Comment: // ** */ +/* Comment: // ** See PMGR spec section 11.14.4 (Software Teardown for Awake Exit) */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_a0_pre_0[] = { +/* Comment: // Restore the GPIO to its default configuration by setting GPIO_PS.RESET for 1us while setting MANUAL_PS to RUN_MAX */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x8000000f, /* Data */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x20e08001, /* WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000046, /* Offset */ +0x00000004, /* Data */ +/* Comment: // Disable voltage changes */ +0x20e0a001, /* WR:PMGR_VOLMAN_VOLMAN_CTL ADDR=0x20e0a0000 */ +0x00000000, /* Offset */ +0x00001f00, /* Data */ +0x20e06811, /* 5-word write */ +0x07060504, /* Offset */ +0x00000000, /* Offset */ +0x0000bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x90000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0D ADDR=0x20e06801c */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Per radar 19338346, disable DynPwrDnEn after switch to bucket 3 */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20050041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(4) ADDR=0x200500424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20054041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(5) ADDR=0x200540424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x20058041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(6) ADDR=0x200580424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +0x2005c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(7) ADDR=0x2005c0424 */ +0x00000009, /* Offset */ +0x00000132, /* Data */ +#endif + +/* Comment: // Power off PLLs that software could not turn off (ENABLE == 0 and BYPASS == 1) */ +0x20e00001, /* WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x00000000, /* Offset */ +0x280c8030, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x00000000, /* Offset */ +0x2803c010, /* Data */ +0x20e01801, /* WR:PMGR_PLL6_CTL ADDR=0x20e018000 */ +0x00000000, /* Offset */ +0x28032011, /* Data */ +0x20e01c01, /* WR:PMGR_PLL7_CTL ADDR=0x20e01c000 */ +0x00000000, /* Offset */ +0x2806f021, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x00000000, /* Offset */ +0x2818d06b, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t awake_to_aop_ddr_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.4 (Software Teardown for Awake Exit), either */ +/* Comment: // ** SW or the config engine may turn off SIO/PCIE. For DV simulations, we chose to power */ +/* Comment: // ** power down ALL of the unneeded blocks in the config engine rather than from the AP. This */ +/* Comment: // ** provided functionally equivalent behavior and allowed the AWAKE->AOP_DDR and */ +/* Comment: // ** S2R_AOP->AOP_DDR to appear symmetric. SiVal/SW may move parts of this sequence */ +/* Comment: // ** to AP software if desired. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_a0_post_0[] = { +/* Comment: // Ensure CoherencePoint DupTag ways will power off */ +0x20e09d01, /* WR:PMGR_PWRGATE_PWR_DUP_TAGS ADDR=0x20e09d000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // Enable automatic power management for the fabric and memory controller */ +#define A2D_POST_PWRGATE_AFTER 0 +#define A2D_POST_PWRGATE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AWAKE->AOP_DDR pwrgate sequence */ +/* Comment: // ** */ +/* Comment: // ** The primary purpose of this sequence is to set PWR_DOM_EN for the blocks which need */ +/* Comment: // ** to be powered down in AOP_DDR to save power. Since the same register is used for */ +/* Comment: // ** some tunable fields, the tunable values for these registers are also applied here. */ +/* Comment: // ** */ +/* Comment: // ** These values are hand-coded by the SOC DV team based on the tunable values on */ +/* Comment: // ** 2/2/2015, and should not be used directly by the CoreOS team in case tunable values */ +/* Comment: // ** change. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t awake_to_aop_ddr_a0_post_pwrgate[] = { +0x20e09c2d, /* 12-word write */ +0x382a2928, /* Offset */ +0x2d2c3a39, /* Offset */ +0x3231302e, /* Offset */ +0x80030309, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG0 ADDR=0x20e09c0a0 */ +0x000f0003, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG1 ADDR=0x20e09c0a4 */ +0x01060600, /* Data WR:PMGR_PWRGATE_PWR_MCC_CFG2 ADDR=0x20e09c0a8 */ +0x80030303, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG0 ADDR=0x20e09c0e0 */ +0x001d0000, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG1 ADDR=0x20e09c0e4 */ +0x01030301, /* Data WR:PMGR_PWRGATE_PWR_ACS_CFG2 ADDR=0x20e09c0e8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG0 ADDR=0x20e09c0b0 */ +0x00190003, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG1 ADDR=0x20e09c0b4 */ +0x010a0808, /* Data WR:PMGR_PWRGATE_PWR_DCS0123_CFG2 ADDR=0x20e09c0b8 */ +0x80030301, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG0 ADDR=0x20e09c0c0 */ +0x00150004, /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG1 ADDR=0x20e09c0c4 */ +0x010a0808 /* Data WR:PMGR_PWRGATE_PWR_DCS4567_CFG2 ADDR=0x20e09c0c8 */ +}; + +static const uint32_t awake_to_aop_ddr_a0_post_1[] = { +/* Comment: // Per , DV will set PWR_DOM_EN for SIO/USB/PCIE/PMP with default values for other fields */ +0x20e09c0d, /* 4-word write */ +0x50603424, /* Offset */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_SIO_CFG0 ADDR=0x20e09c090 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_USB_CFG0 ADDR=0x20e09c0d0 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PCIE_CFG0 ADDR=0x20e09c180 */ +0x80080860, /* Data WR:PMGR_PWRGATE_PWR_PMP_CFG0 ADDR=0x20e09c140 */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x00000000, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x00000000, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x00000000, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x00000000, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20e08031, /* 13-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x0000009c, /* Offset */ +0x1000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x1000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x1000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x1000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x1000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x1000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x1000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x1000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x1000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x1000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x1000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x1000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x1000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +#endif + +0x20e40001, /* WR:PMSCSR_PMSCSR_PMP_PMS_CPG_CTRL ADDR=0x20e40000c */ +0x00000003, /* Offset */ +0x00010100, /* Data */ +0x20400001, /* WR:SOCBUSMUX_SOCBUSMUX_REGS_CPG_CNTL ADDR=0x204000090 */ +0x00000024, /* Offset */ +0x80012c04, /* Data */ +0x20080001, /* WR:SWITCHFABRIC_SWITCHFABRIC_REGS_CPG_CNTL ADDR=0x200800094 */ +0x00000025, /* Offset */ +0x80017c04, /* Data */ +0x20f00001, /* WR:AFC_AIU_SB_AFC_AIU_SB_SELF_REGS_CPG_CNTL ADDR=0x20f00000c */ +0x00000003, /* Offset */ +0x80011004, /* Data */ +0x20f1c001, /* WR:DYNAMIC_CLK_GATING_SB_GLUE_DYNAMIC_CLK_GATING ADDR=0x20f1c0000 */ +0x00000000, /* Offset */ +0x0100001f, /* Data */ +0x20000001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(0) ADDR=0x200000008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +0x20020001, /* WR:AMCC_AMCCGEN_AMCCLKPWRGATE(1) ADDR=0x200200008 */ +0x00000002, /* Offset */ +0x10c80064, /* Data */ +/* Comment: // enable ACG for the PMGR clock tree */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +/* Comment: // Powering down SIO, PCIE, USB, AIC, PMP */ +0x20e0803d, /* 16-word write */ +0x5e5c5a58, /* Offset */ +0x66646260, /* Offset */ +0x6e6c6a68, /* Offset */ +0x76747270, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080160 */ +0x00000000, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080168 */ +0x00000000, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080170 */ +0x00000000, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080178 */ +0x00000000, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080180 */ +0x00000000, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080188 */ +0x00000000, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080190 */ +0x00000000, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e080198 */ +0x00000000, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 */ +0x00000000, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 */ +0x00000000, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 */ +0x00000000, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 */ +0x00000000, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 */ +0x00000000, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 */ +0x00000000, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d0 */ +0x00000000, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801d8 */ +0x20e0803d, /* 16-word write */ +0x7e7c7a78, /* Offset */ +0x86848280, /* Offset */ +0xd4525654, /* Offset */ +0xdcdad8d6, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e0 */ +0x00000000, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801e8 */ +0x00000000, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f0 */ +0x00000000, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e0801f8 */ +0x00000000, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080200 */ +0x00000000, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080208 */ +0x00000000, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080210 */ +0x00000000, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080218 */ +0x00000000, /* Data WR:PMGR_PS_SIO_P_PS ADDR=0x20e080150 */ +0x00000000, /* Data WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x00000000, /* Data WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 */ +0x20e08031, /* 13-word write */ +0xaca8a4d2, /* Offset */ +0xa0aaa6a2, /* Offset */ +0x44c89eae, /* Offset */ +0x00000050, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 */ +0x00000000, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 */ +0x00000000, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 */ +0x00000000, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 */ +0x00000000, /* Data WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x00000000, /* Data WR:PMGR_PS_PMP_PS ADDR=0x20e080320 */ +0x00000000, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000000, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +0x20e0b83d, /* 16-word write */ +0x03020100, /* Offset */ +0x07060504, /* Offset */ +0x13121110, /* Offset */ +0x17161514, /* Offset */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH0 ADDR=0x20e0b8000 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH1 ADDR=0x20e0b8004 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH2 ADDR=0x20e0b8008 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH3 ADDR=0x20e0b800c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH4 ADDR=0x20e0b8010 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH5 ADDR=0x20e0b8014 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH6 ADDR=0x20e0b8018 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH7 ADDR=0x20e0b801c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH16 ADDR=0x20e0b8040 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH17 ADDR=0x20e0b8044 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH18 ADDR=0x20e0b8048 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH19 ADDR=0x20e0b804c */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH20 ADDR=0x20e0b8050 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH21 ADDR=0x20e0b8054 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH22 ADDR=0x20e0b8058 */ +0x00000000, /* Data WR:PMGR_SCRATCH_SCRATCH23 ADDR=0x20e0b805c */ +/* Comment: // Reset and then clock gate the AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e10001, /* WR:AIC_GLOBALS_AICRST ADDR=0x20e10000c */ +0x00000003, /* Offset */ +0x00000001, /* Data */ +0x20e10002, /* Poll:AIC_GLOBALS_AICRST ADDR=0x20e10000c Retry_en=1 Retry_cnt=255*/ +0x0001ff03, /* Offset */ +0x00000001, /* Mask */ +0x00000000, /* Data */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x00000000, /* Data */ +0x2102b005, /* 2-word write */ +0x00000400, /* Offset */ +0x00000000, /* Data WR:MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER ADDR=0x2102b0000 */ +0x00000000 /* Data WR:MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER ADDR=0x2102b0010 */ +}; + +static const uint32_t awake_to_aop_ddr_a0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_a0_pre_0[] = { +/* Comment: // Make the proxy fabric clock run at 192MHz to speed up AOP_DDR->AWAKE transition */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x81100000, /* Data */ +/* Comment: // Powering up SIO partition and SIO devices */ +0x20e08001, /* WR:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 */ +0x00000052, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_BUSIF_PS ADDR=0x20e080148 Retry_en=1 Retry_cnt=255*/ +0x0001ff52, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_PS ADDR=0x20e080158 */ +0x00000056, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_PS ADDR=0x20e080158 Retry_en=1 Retry_cnt=255*/ +0x0001ff56, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08001, /* WR:PMGR_PS_SIO_P_PS ADDR=0x20e080150 */ +0x00000054, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SIO_P_PS ADDR=0x20e080150 Retry_en=1 Retry_cnt=255*/ +0x0001ff54, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e0803d, /* 16-word write */ +0x5e5c5a58, /* Offset */ +0x66646260, /* Offset */ +0x6e6c6a68, /* Offset */ +0x76747270, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_MCA0_PS ADDR=0x20e080160 */ +0x00000004, /* Data WR:PMGR_PS_MCA1_PS ADDR=0x20e080168 */ +0x00000004, /* Data WR:PMGR_PS_MCA2_PS ADDR=0x20e080170 */ +0x00000004, /* Data WR:PMGR_PS_MCA3_PS ADDR=0x20e080178 */ +0x00000004, /* Data WR:PMGR_PS_MCA4_PS ADDR=0x20e080180 */ +0x00000004, /* Data WR:PMGR_PS_PWM0_PS ADDR=0x20e080188 */ +0x00000004, /* Data WR:PMGR_PS_I2C0_PS ADDR=0x20e080190 */ +0x00000004, /* Data WR:PMGR_PS_I2C1_PS ADDR=0x20e080198 */ +0x00000004, /* Data WR:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 */ +0x00000004, /* Data WR:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 */ +0x00000004, /* Data WR:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 */ +0x00000004, /* Data WR:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 */ +0x00000004, /* Data WR:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 */ +0x00000004, /* Data WR:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 */ +0x00000004, /* Data WR:PMGR_PS_UART0_PS ADDR=0x20e0801d0 */ +0x00000004, /* Data WR:PMGR_PS_UART1_PS ADDR=0x20e0801d8 */ +0x20e0801d, /* 8-word write */ +0x7e7c7a78, /* Offset */ +0x86848280, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_UART2_PS ADDR=0x20e0801e0 */ +0x00000004, /* Data WR:PMGR_PS_UART3_PS ADDR=0x20e0801e8 */ +0x00000004, /* Data WR:PMGR_PS_UART4_PS ADDR=0x20e0801f0 */ +0x00000004, /* Data WR:PMGR_PS_UART5_PS ADDR=0x20e0801f8 */ +0x00000004, /* Data WR:PMGR_PS_UART6_PS ADDR=0x20e080200 */ +0x00000004, /* Data WR:PMGR_PS_UART7_PS ADDR=0x20e080208 */ +0x00000004, /* Data WR:PMGR_PS_UART8_PS ADDR=0x20e080210 */ +0x00000004, /* Data WR:PMGR_PS_AES0_PS ADDR=0x20e080218 */ +/* Comment: // It might not be required to do all of the following polls since they should take the same amount of time to power up. */ +/* Comment: // One possible optimization is to only do the poll for the last write */ +0x20e08002, /* Poll:PMGR_PS_MCA0_PS ADDR=0x20e080160 Retry_en=1 Retry_cnt=255*/ +0x0001ff58, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA1_PS ADDR=0x20e080168 Retry_en=1 Retry_cnt=255*/ +0x0001ff5a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA2_PS ADDR=0x20e080170 Retry_en=1 Retry_cnt=255*/ +0x0001ff5c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA3_PS ADDR=0x20e080178 Retry_en=1 Retry_cnt=255*/ +0x0001ff5e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCA4_PS ADDR=0x20e080180 Retry_en=1 Retry_cnt=255*/ +0x0001ff60, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PWM0_PS ADDR=0x20e080188 Retry_en=1 Retry_cnt=255*/ +0x0001ff62, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C0_PS ADDR=0x20e080190 Retry_en=1 Retry_cnt=255*/ +0x0001ff64, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C1_PS ADDR=0x20e080198 Retry_en=1 Retry_cnt=255*/ +0x0001ff66, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C2_PS ADDR=0x20e0801a0 Retry_en=1 Retry_cnt=255*/ +0x0001ff68, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_I2C3_PS ADDR=0x20e0801a8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI0_PS ADDR=0x20e0801b0 Retry_en=1 Retry_cnt=255*/ +0x0001ff6c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI1_PS ADDR=0x20e0801b8 Retry_en=1 Retry_cnt=255*/ +0x0001ff6e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI2_PS ADDR=0x20e0801c0 Retry_en=1 Retry_cnt=255*/ +0x0001ff70, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SPI3_PS ADDR=0x20e0801c8 Retry_en=1 Retry_cnt=255*/ +0x0001ff72, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART0_PS ADDR=0x20e0801d0 Retry_en=1 Retry_cnt=255*/ +0x0001ff74, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART1_PS ADDR=0x20e0801d8 Retry_en=1 Retry_cnt=255*/ +0x0001ff76, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART2_PS ADDR=0x20e0801e0 Retry_en=1 Retry_cnt=255*/ +0x0001ff78, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART3_PS ADDR=0x20e0801e8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7a, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART4_PS ADDR=0x20e0801f0 Retry_en=1 Retry_cnt=255*/ +0x0001ff7c, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART5_PS ADDR=0x20e0801f8 Retry_en=1 Retry_cnt=255*/ +0x0001ff7e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART6_PS ADDR=0x20e080200 Retry_en=1 Retry_cnt=255*/ +0x0001ff80, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART7_PS ADDR=0x20e080208 Retry_en=1 Retry_cnt=255*/ +0x0001ff82, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_UART8_PS ADDR=0x20e080210 Retry_en=1 Retry_cnt=255*/ +0x0001ff84, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AES0_PS ADDR=0x20e080218 Retry_en=1 Retry_cnt=255*/ +0x0001ff86, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up PCIE partition and PCIE devices/link */ +0x20e08001, /* WR:PMGR_PS_PCIE_PS ADDR=0x20e080348 */ +0x000000d2, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_PS ADDR=0x20e080348 Retry_en=1 Retry_cnt=255*/ +0x0001ffd2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xdad8d6d4, /* Offset */ +0x000000dc, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 */ +0x20e08002, /* Poll:PMGR_PS_PCIE_AUX_PS ADDR=0x20e080350 Retry_en=1 Retry_cnt=255*/ +0x0001ffd4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK0_PS ADDR=0x20e080358 Retry_en=1 Retry_cnt=255*/ +0x0001ffd6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK1_PS ADDR=0x20e080360 Retry_en=1 Retry_cnt=255*/ +0x0001ffd8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK2_PS ADDR=0x20e080368 Retry_en=1 Retry_cnt=255*/ +0x0001ffda, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_LINK3_PS ADDR=0x20e080370 Retry_en=1 Retry_cnt=255*/ +0x0001ffdc, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up USB partition and USB devices */ +0x20e08001, /* WR:PMGR_PS_USB_PS ADDR=0x20e080278 */ +0x0000009e, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB_PS ADDR=0x20e080278 Retry_en=1 Retry_cnt=255*/ +0x0001ff9e, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08011, /* 5-word write */ +0xa6a2a0ae, /* Offset */ +0x000000aa, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 */ +0x00000004, /* Data WR:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 */ +0x20e08002, /* Poll:PMGR_PS_USB_OTG_PS ADDR=0x20e0802b8 Retry_en=1 Retry_cnt=255*/ +0x0001ffae, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USBCTLREG_PS ADDR=0x20e080280 Retry_en=1 Retry_cnt=255*/ +0x0001ffa0, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_PS ADDR=0x20e080288 Retry_en=1 Retry_cnt=255*/ +0x0001ffa2, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_PS ADDR=0x20e080298 Retry_en=1 Retry_cnt=255*/ +0x0001ffa6, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_PS ADDR=0x20e0802a8 Retry_en=1 Retry_cnt=255*/ +0x0001ffaa, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08009, /* 3-word write */ +0x00aca8a4, /* Offset */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 */ +0x00000004, /* Data WR:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST0_OHCI_PS ADDR=0x20e080290 Retry_en=1 Retry_cnt=255*/ +0x0001ffa4, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST1_OHCI_PS ADDR=0x20e0802a0 Retry_en=1 Retry_cnt=255*/ +0x0001ffa8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_USB2HOST2_OHCI_PS ADDR=0x20e0802b0 Retry_en=1 Retry_cnt=255*/ +0x0001ffac, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Powering up AIC */ +0x20e08001, /* WR:PMGR_PS_AIC_PS ADDR=0x20e080108 */ +0x00000042, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_AIC_PS ADDR=0x20e080108 Retry_en=1 Retry_cnt=255*/ +0x0001ff42, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_PMP_PS ADDR=0x20e080320 */ +0x000000c8, /* Offset */ +0x00000004, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PMP_PS ADDR=0x20e080320 Retry_en=1 Retry_cnt=255*/ +0x0001ffc8, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +/* Comment: // Restore PMS, SBR, SF, SMX, MCC, and DCS* PS to reset values per CoreOS request from radar 19132562 */ +0x00000044, /* NOP to align binary to 64-bit boundary before ifdef */ + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20e0802d, /* 12-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x50444694, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802c8 Retry_en=1 Retry_cnt=255*/ +0x0001ffb2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e0802c0 Retry_en=1 Retry_cnt=255*/ +0x0001ffb0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 Retry_en=1 Retry_cnt=255*/ +0x0001ff50, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20e0803d, /* 16-word write */ +0xb0b24048, /* Offset */ +0x92908e8c, /* Offset */ +0x9a989694, /* Offset */ +0x5044469c, /* Offset */ +0x0000000f, /* Data WR:PMGR_PS_PMS_PS ADDR=0x20e080120 */ +0x0000000f, /* Data WR:PMGR_PS_SBR_PS ADDR=0x20e080100 */ +0x0000000f, /* Data WR:PMGR_PS_SF_PS ADDR=0x20e0802c8 */ +0x0000000f, /* Data WR:PMGR_PS_SMX_PS ADDR=0x20e0802c0 */ +0x0000000f, /* Data WR:PMGR_PS_MCC_PS ADDR=0x20e080230 */ +0x0000000f, /* Data WR:PMGR_PS_DCS0_PS ADDR=0x20e080238 */ +0x0000000f, /* Data WR:PMGR_PS_DCS1_PS ADDR=0x20e080240 */ +0x0000000f, /* Data WR:PMGR_PS_DCS2_PS ADDR=0x20e080248 */ +0x0000000f, /* Data WR:PMGR_PS_DCS3_PS ADDR=0x20e080250 */ +0x0000000f, /* Data WR:PMGR_PS_DCS4_PS ADDR=0x20e080258 */ +0x0000000f, /* Data WR:PMGR_PS_DCS5_PS ADDR=0x20e080260 */ +0x0000000f, /* Data WR:PMGR_PS_DCS6_PS ADDR=0x20e080268 */ +0x0000000f, /* Data WR:PMGR_PS_DCS7_PS ADDR=0x20e080270 */ +0x0000000f, /* Data WR:PMGR_PS_GPIO_PS ADDR=0x20e080118 */ +0x00000004, /* Data WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000004, /* Data WR:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 */ +0x20e08002, /* Poll:PMGR_PS_PMS_PS ADDR=0x20e080120 Retry_en=1 Retry_cnt=255*/ +0x0001ff48, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SBR_PS ADDR=0x20e080100 Retry_en=1 Retry_cnt=255*/ +0x0001ff40, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SF_PS ADDR=0x20e0802c8 Retry_en=1 Retry_cnt=255*/ +0x0001ffb2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SMX_PS ADDR=0x20e0802c0 Retry_en=1 Retry_cnt=255*/ +0x0001ffb0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MCC_PS ADDR=0x20e080230 Retry_en=1 Retry_cnt=255*/ +0x0001ff8c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS0_PS ADDR=0x20e080238 Retry_en=1 Retry_cnt=255*/ +0x0001ff8e, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS1_PS ADDR=0x20e080240 Retry_en=1 Retry_cnt=255*/ +0x0001ff90, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS2_PS ADDR=0x20e080248 Retry_en=1 Retry_cnt=255*/ +0x0001ff92, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS3_PS ADDR=0x20e080250 Retry_en=1 Retry_cnt=255*/ +0x0001ff94, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS4_PS ADDR=0x20e080258 Retry_en=1 Retry_cnt=255*/ +0x0001ff96, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS5_PS ADDR=0x20e080260 Retry_en=1 Retry_cnt=255*/ +0x0001ff98, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS6_PS ADDR=0x20e080268 Retry_en=1 Retry_cnt=255*/ +0x0001ff9a, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DCS7_PS ADDR=0x20e080270 Retry_en=1 Retry_cnt=255*/ +0x0001ff9c, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GPIO_PS ADDR=0x20e080118 Retry_en=1 Retry_cnt=255*/ +0x0001ff46, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DWI_PS ADDR=0x20e080110 Retry_en=1 Retry_cnt=255*/ +0x0001ff44, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x20e08002, /* Poll:PMGR_PS_PCIE_REF_PS ADDR=0x20e080140 Retry_en=1 Retry_cnt=255*/ +0x0001ff50, /* Offset */ +0x000000f0, /* Mask */ +0x00000040, /* Data */ +0x00000044, /* NOP to align binary to 64-bit boundary before endif */ +#endif + +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a0 */ +0x00000028, /* Offset */ +0x80101000, /* Data */ +/* Comment: // wait 1us */ +0x00003004 /* Cfg Count(Delay.Wait) */ +}; + +static const uint32_t aop_ddr_to_awake_a0_pre_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.3 (Software Init for AOP_DDR to AWAKE), the */ +/* Comment: // ** config engine restores the state of the chip in this step. The specific use cases where */ +/* Comment: // ** the config engine is the owner of state restoration are not yet defined. */ +/* Comment: // ** */ +/* Comment: // ** The sequence below contains the minimum set of commands to re-boot the AP and restore */ +/* Comment: // ** DRAM operation at bucket 1. AP may bring DRAM up to bucket 0. */ +/* Comment: // ** */ +/* Comment: // ** It is assumed that SW will add extensively to this sequence for state restoration based */ +/* Comment: // ** on future use cases. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +#define D2A_POST_MCU_AWAKE_AFTER -1 +#define D2A_POST_MCU_AWAKE_BEFORE 0 +static const uint32_t aop_ddr_to_awake_a0_post_0[] = { +/* Comment: // Wait 900us as first step of AOP_DDR->AWAKE per radar 20181763 to ensure BIRA loading is complete */ +/* Comment: // prior to powering on any non-AOP power domain */ +0x00a8c004, /* Cfg Count(Delay.Wait) */ +/* Comment: // INSERT_MCU_AWAKE_SEQ */ +/* Comment: // Restore the state of the chip */ +0x20e04001, /* WR:PMGR_CLKCFG_UVD_CLK_CFG ADDR=0x20e0400a0 */ +0x00000028, /* Offset */ +0x80100000, /* Data */ +/* Comment: // wait 1us */ +0x00003004, /* Cfg Count(Delay.Wait) */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +#define D2A_POST_RESTORE_AFTER 0 +#define D2A_POST_RESTORE_BEFORE 1 +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** SOC DV Version of AOP_DDR->AWAKE system restore postamble */ +/* Comment: // ** */ +/* Comment: // ** DO NOT USE THIS FILE VERBATIM -- THIS IS FOR DV TESTING PURPOSES ONLY */ +/* Comment: // ****************************************************************************************** */ +static const uint32_t aop_ddr_to_awake_a0_post_restore[] = { +/* Comment: // DV writes small values for PLL_RESET_*TIME and LOCK_TIME to speed up simulation */ +/* Comment: // SW/SiVal should use real values here */ +0x20e00001, /* WR:PMGR_PLL0_PLL_DELAY_CTL1 ADDR=0x20e000020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00005, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL0_CFG ADDR=0x20e000004 */ +0xa00c8030, /* Data WR:PMGR_PLL0_CTL ADDR=0x20e000000 */ +0x20e00002, /* Poll:PMGR_PLL0_CTL ADDR=0x20e000000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00401, /* WR:PMGR_PLL1_PLL_DELAY_CTL1 ADDR=0x20e004020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00405, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL1_CFG ADDR=0x20e004004 */ +0xa003c010, /* Data WR:PMGR_PLL1_CTL ADDR=0x20e004000 */ +0x20e00402, /* Poll:PMGR_PLL1_CTL ADDR=0x20e004000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e01801, /* WR:PMGR_PLL6_PLL_DELAY_CTL1 ADDR=0x20e018020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e01805, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL6_CFG ADDR=0x20e018004 */ +0xa0032011, /* Data WR:PMGR_PLL6_CTL ADDR=0x20e018000 */ +0x20e01802, /* Poll:PMGR_PLL6_CTL ADDR=0x20e018000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e01c01, /* WR:PMGR_PLL7_PLL_DELAY_CTL1 ADDR=0x20e01c020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e01c05, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL7_CFG ADDR=0x20e01c004 */ +0xa006f021, /* Data WR:PMGR_PLL7_CTL ADDR=0x20e01c000 */ +0x20e01c02, /* Poll:PMGR_PLL7_CTL ADDR=0x20e01c000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +0x20e00c01, /* WR:PMGR_PLL3_PLL_DELAY_CTL1 ADDR=0x20e00c020 */ +0x00000008, /* Offset */ +0x0001a019, /* Data */ +0x20e00c05, /* 2-word write */ +0x00000001, /* Offset */ +0x80480030, /* Data WR:PMGR_PLL3_CFG ADDR=0x20e00c004 */ +0xa018d06b, /* Data WR:PMGR_PLL3_CTL ADDR=0x20e00c000 */ +0x20e00c02, /* Poll:PMGR_PLL3_CTL ADDR=0x20e00c000 Retry_en=1 Retry_cnt=255*/ +0x0001ff00, /* Offset */ +0x02000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Bring MCU up to bucket0 */ +/* Comment: // write: reg_name=PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A reg_value=55555539 */ +0x20e06819, /* 7-word write */ +0x10060504, /* Offset */ +0x00001211, /* Offset */ +0x55555505, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0A ADDR=0x20e068010 */ +0x55055666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0B ADDR=0x20e068014 */ +0x00000555, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_0C ADDR=0x20e068018 */ +0x5555bb39, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_3A ADDR=0x20e068040 */ +0x55055666, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_3B ADDR=0x20e068044 */ +0x00000555, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_ENTRY_3C ADDR=0x20e068048 */ +0x00000000, /* Data WR:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 */ +0x20e06802, /* Poll:PMGR_SOC_PERF_STATE_SOC_PERF_STATE_CTL ADDR=0x20e068000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x80000000, /* Mask */ +0x00000000, /* Data */ +/* Comment: // Tunables may be re-applied here */ +0x20e08001, /* WR:PMGR_PS_DWI_PS ADDR=0x20e080110 */ +0x00000044, /* Offset */ +0x0000024f, /* Data */ +0x20e0dc01, /* WR:PMGR_MISC_CFG_ACG ADDR=0x20e0dc000 */ +0x00000000, /* Offset */ +0x00000001, /* Data */ +0x00000044, /* CFG Count to aling 64 bit write to 16 bytes address:*/ +0x20205003, /* WR:ACC_CPU0_IMPL_IO_RVBAR ADDR=0x202050000 */ +0x00000000, /* Offset */ +0x00000000, /* Data */ +0x00000008 /* Data */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_1[] = { + +#ifdef AMC_PARAM_FOUR_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +#endif + + +#ifdef AMC_PARAM_EIGHT_CH_ONE_RANK +0x20040041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(0) ADDR=0x200400424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20044041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(1) ADDR=0x200440424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20048041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(2) ADDR=0x200480424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2004c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(3) ADDR=0x2004c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20050041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(4) ADDR=0x200500424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20054041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(5) ADDR=0x200540424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x20058041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(6) ADDR=0x200580424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +0x2005c041, /* WR:AMCX_DRAMCFG_PWRMNGTEN(7) ADDR=0x2005c0424 */ +0x00000009, /* Offset */ +0x00000133, /* Data */ +#endif + +/* Comment: // Per radar 20183074, turn the following partitions on one at a time */ +0x20e08001, /* WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802d0 */ +0x000000b4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_RTMUX_PS ADDR=0x20e0802d0 Retry_en=0 Retry_cnt=0*/ +0x000000b4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_ISP_PS ADDR=0x20e080300 */ +0x000000c0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_ISP_PS ADDR=0x20e080300 Retry_en=0 Retry_cnt=0*/ +0x000000c0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MEDIA_PS ADDR=0x20e080308 */ +0x000000c2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MEDIA_PS ADDR=0x20e080308 Retry_en=0 Retry_cnt=0*/ +0x000000c2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_MSR_PS ADDR=0x20e080318 */ +0x000000c6, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_MSR_PS ADDR=0x20e080318 Retry_en=0 Retry_cnt=0*/ +0x000000c6, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VDEC0_PS ADDR=0x20e080330 */ +0x000000cc, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VDEC0_PS ADDR=0x20e080330 Retry_en=0 Retry_cnt=0*/ +0x000000cc, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080340 */ +0x000000d0, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_VENC_CPU_PS ADDR=0x20e080340 Retry_en=0 Retry_cnt=0*/ +0x000000d0, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000002, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 Retry_en=0 Retry_cnt=0*/ +0x00000002, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08801, /* WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x00000004, /* Offset */ +0x0000000f, /* Data */ +0x20e08802, /* Poll:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 Retry_en=0 Retry_cnt=0*/ +0x00000004, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_GFX_PS ADDR=0x20e080388 */ +0x000000e2, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_GFX_PS ADDR=0x20e080388 Retry_en=0 Retry_cnt=0*/ +0x000000e2, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_DISP1MUX_PS ADDR=0x20e0802e8 */ +0x000000ba, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_DISP1MUX_PS ADDR=0x20e0802e8 Retry_en=0 Retry_cnt=0*/ +0x000000ba, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08001, /* WR:PMGR_PS_SRS_PS ADDR=0x20e080390 */ +0x000000e4, /* Offset */ +0x0000000f, /* Data */ +0x20e08002, /* Poll:PMGR_PS_SRS_PS ADDR=0x20e080390 Retry_en=0 Retry_cnt=0*/ +0x000000e4, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +0x20e08041, /* WR:PMGR_PS_SEP_PS ADDR=0x20e080400 */ +0x00000000, /* Offset */ +0x4000000f, /* Data */ +0x20e08042, /* Poll:PMGR_PS_SEP_PS ADDR=0x20e080400 Retry_en=0 Retry_cnt=0*/ +0x00000000, /* Offset */ +0x000000f0, /* Mask */ +0x000000f0, /* Data */ +/* Comment: // Per CoreOS request, turn off the above PS registers (except SEP_PS, which cannot be turned off by config engine) */ +0x20e08809, /* 3-word write */ +0x00040200, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_VENC_PIPE_PS ADDR=0x20e088000 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME0_PS ADDR=0x20e088008 */ +0x00000000, /* Data WR:PMGR_PS_VENC_ME1_PS ADDR=0x20e088010 */ +0x20e08021, /* 9-word write */ +0xd0e2bae4, /* Offset */ +0xc0c2c6cc, /* Offset */ +0x000000b4, /* Offset */ +0x00000000, /* Data WR:PMGR_PS_SRS_PS ADDR=0x20e080390 */ +0x00000000, /* Data WR:PMGR_PS_DISP1MUX_PS ADDR=0x20e0802e8 */ +0x00000000, /* Data WR:PMGR_PS_GFX_PS ADDR=0x20e080388 */ +0x00000000, /* Data WR:PMGR_PS_VENC_CPU_PS ADDR=0x20e080340 */ +0x00000000, /* Data WR:PMGR_PS_VDEC0_PS ADDR=0x20e080330 */ +0x00000000, /* Data WR:PMGR_PS_MSR_PS ADDR=0x20e080318 */ +0x00000000, /* Data WR:PMGR_PS_MEDIA_PS ADDR=0x20e080308 */ +0x00000000, /* Data WR:PMGR_PS_ISP_PS ADDR=0x20e080300 */ +0x00000000, /* Data WR:PMGR_PS_RTMUX_PS ADDR=0x20e0802d0 */ +/* Comment: // Set the proxy clock back to 96MHz to save power */ +0x21024002, /* Poll:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 Retry_en=1 Retry_cnt=255*/ +0x0001ff06, /* Offset */ +0x04000000, /* Mask */ +0x00000000, /* Data */ +0x21024001, /* WR:MINIPMGR_MINI_CLKCFG_PROXY_FABRIC_CLK_CFG ADDR=0x210240018 */ +0x00000006, /* Offset */ +0x82100000, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +// +// This additional stitch point is an intentional deviation from the SEG-provided +// sequence. +// +#define D2A_POST_PREBOOT_BEFORE 2 +static const uint32_t aop_ddr_to_awake_a0_post_2[] = { +/* Comment: // Boot CPU0 by writing to the WAKE_CORES register */ +0x20e0d401, /* WR:PMGR_MISC_CORES_WAKE_CORES ADDR=0x20e0d4008 */ +0x00000002, /* Offset */ +0x00000001, /* Data */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +static const uint32_t aop_ddr_to_awake_a0_post_end[] = { +0x00000000, /*Cfg End */ +0x00000044 /* NOP to align binary to 64-bit boundary */ +}; + +#if 0 +/*Intentional removal of the following definition which would otherwise duplicate the definition from the A1 sequence*/ +typedef struct { + uint32_t *sequence; + size_t elements; +} reconfig_subsequence_t; +#endif + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_a0_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_a0_pre_0, sizeof(aop_ddr_to_awake_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_a0_pre_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_a0_pre_0, sizeof(awake_to_aop_ddr_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_s2r_aop_a0_pre_seqs[] = { + { (uint32_t *) aop_ddr_to_s2r_aop_a0_pre_0, sizeof(aop_ddr_to_s2r_aop_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_a0_post_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_0, sizeof(s2r_aop_to_aop_ddr_a0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_1, sizeof(s2r_aop_to_aop_ddr_a0_post_1) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_2, sizeof(s2r_aop_to_aop_ddr_a0_post_2) / sizeof(uint32_t) }, + { (uint32_t *) s2r_aop_to_aop_ddr_a0_post_3, sizeof(s2r_aop_to_aop_ddr_a0_post_3) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_s2r_aop_to_aop_ddr_a0_pre_seqs[] = { + { (uint32_t *) s2r_aop_to_aop_ddr_a0_pre_0, sizeof(s2r_aop_to_aop_ddr_a0_pre_0) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_aop_ddr_to_awake_a0_post_seqs[] = { + { (uint32_t *) aop_ddr_to_awake_a0_post_0, sizeof(aop_ddr_to_awake_a0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_a0_post_1, sizeof(aop_ddr_to_awake_a0_post_1) / sizeof(uint32_t) }, + { (uint32_t *) aop_ddr_to_awake_a0_post_2, sizeof(aop_ddr_to_awake_a0_post_2) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +static const reconfig_subsequence_t reconfig_awake_to_aop_ddr_a0_post_seqs[] = { + { (uint32_t *) awake_to_aop_ddr_a0_post_0, sizeof(awake_to_aop_ddr_a0_post_0) / sizeof(uint32_t) }, + { (uint32_t *) awake_to_aop_ddr_a0_post_1, sizeof(awake_to_aop_ddr_a0_post_1) / sizeof(uint32_t) }, + { NULL, 0 }, +}; + +#endif // AOP_CONFIG_SEQUENCES_H diff --git a/platform/s8000/include/platform/soc/s8000/apcie_common.h b/platform/s8000/include/platform/soc/s8000/apcie_common.h new file mode 100644 index 0000000..609d82e --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/apcie_common.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_TUNABLE_APCIE_COMMON_H +#define SPDS_S8000_TUNABLE_APCIE_COMMON_H + +#include +#include + +#endif /* SPDS_S8000_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/apcie_config.h b/platform/s8000/include/platform/soc/s8000/apcie_config.h new file mode 100644 index 0000000..da0cd85 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/apcie_config.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8000_TUNABLE_APCIE_CONFIG_H + +#include +#include + +#endif /* SPDS_S8000_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/ausr_cfg.h b/platform/s8000/include/platform/soc/s8000/ausr_cfg.h new file mode 100644 index 0000000..86b4fd9 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/ausr_cfg.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_TUNABLE_AUSR_CFG_H +#define SPDS_S8000_TUNABLE_AUSR_CFG_H + +#include +#include + +#endif /* SPDS_S8000_TUNABLE_AUSR_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/ausr_shm_cfg.h b/platform/s8000/include/platform/soc/s8000/ausr_shm_cfg.h new file mode 100644 index 0000000..78dc95d --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/ausr_shm_cfg.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_TUNABLE_AUSR_SHM_CFG_H +#define SPDS_S8000_TUNABLE_AUSR_SHM_CFG_H + +#include +#include + +#endif /* SPDS_S8000_TUNABLE_AUSR_SHM_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/aust_shm_cfg.h b/platform/s8000/include/platform/soc/s8000/aust_shm_cfg.h new file mode 100644 index 0000000..fb162f5 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/aust_shm_cfg.h @@ -0,0 +1,18 @@ +/*! + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_TUNABLE_AUST_SHM_CFG_H +#define SPDS_TUNABLE_AUST_SHM_CFG_H + +#include +#include + +#endif /*! SPDS_TUNABLE_AUST_SHM_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_common.h b/platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_common.h new file mode 100644 index 0000000..8693ea9 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_common.h @@ -0,0 +1,179 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_B0_TUNABLE_APCIE_COMMON_H +#define SPDS_S8000_B0_TUNABLE_APCIE_COMMON_H + +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f7f7f7f) +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x700) +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xc0800) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1fff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x92c) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xffffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x2001000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x9) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1000010) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_UMASK_S8000_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_VALUE_S8000_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_UMASK_S8000_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_VALUE_S8000_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_UMASK_S8000_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_VALUE_S8000_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_UMASK_S8000_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_VALUE_S8000_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_FABRIC_TLIMITS */ 0x8, sizeof(uint32_t), 0x7f7f7f7f, 0x0 }, \ +{ /* APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL */ 0xc, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_COMMON_PRIORITY */ 0x10, sizeof(uint32_t), 0x700, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING */ 0x18, sizeof(uint32_t), 0xffffff, 0xc0800 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH */ 0x1c, sizeof(uint32_t), 0x1fff, 0x92c }, \ +{ /* APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL */ 0x28, sizeof(uint32_t), 0xffffffff, 0x2001000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING */ 0x30, sizeof(uint32_t), 0xff, 0x9 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x31100010, 0x1000010 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x104, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY */ 0x108, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0 */ 0x10c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0 */ 0x110, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0 */ 0x120, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0 */ 0x128, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_0 */ 0x130, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0 */ 0x134, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1 */ 0x190, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1 */ 0x1a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1 */ 0x1a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_1 */ 0x1b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1 */ 0x1b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2 */ 0x210, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2 */ 0x220, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2 */ 0x228, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_2 */ 0x230, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2 */ 0x234, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3 */ 0x290, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3 */ 0x2a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3 */ 0x2a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_3 */ 0x2b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3 */ 0x2b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_FPGA_TUNABLES_S8000_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_B0_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_config.h b/platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_config.h new file mode 100644 index 0000000..6ed25e3 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/b0/tunable/apcie_config.h @@ -0,0 +1,133 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_B0_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8000_B0_TUNABLE_APCIE_CONFIG_H + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x5) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f7f) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x3) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x8073ffff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x403d09) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x5) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f7f) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x3) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x8073ffff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x403d09) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x5) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f7f) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x3) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x8073ffff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x403d09) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x5) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7f7f) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x3) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x8073ffff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x403d09) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_B0_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_cfg.h b/platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_cfg.h new file mode 100644 index 0000000..b732a99 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_cfg.h @@ -0,0 +1,122 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_B0_TUNABLE_AUSR_CFG_H +#define SPDS_S8000_B0_TUNABLE_AUSR_CFG_H + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xfc) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf000) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x18) + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xc0) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_PHY_AUSR0_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xfc) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf000) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x18) + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xc0) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_PHY_AUSR1_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xfc) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf000) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x18) + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xc0) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_PHY_AUSR2_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xfc) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf000) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x18) + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xc0) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_PHY_AUSR3_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xfc) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf000) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x18) + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xc0) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x40) + +#define PCIE_APCIE_PHY_AUSR4_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_B0_TUNABLE_AUSR_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_shm_cfg.h b/platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_shm_cfg.h new file mode 100644 index 0000000..16ee5f1 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/b0/tunable/ausr_shm_cfg.h @@ -0,0 +1,62 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_B0_TUNABLE_AUSR_SHM_CFG_H +#define SPDS_S8000_B0_TUNABLE_AUSR_SHM_CFG_H + +#define PCIE_APCIE_PHY_AUSR0_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR0_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR0_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR1_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR1_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR1_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR2_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR2_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR2_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR3_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR3_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR3_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR4_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR4_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_B0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR4_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_B0_TUNABLE_AUSR_SHM_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/b0/tunable/aust_shm_cfg.h b/platform/s8000/include/platform/soc/s8000/b0/tunable/aust_shm_cfg.h new file mode 100644 index 0000000..0ffa2c1 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/b0/tunable/aust_shm_cfg.h @@ -0,0 +1,82 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_B0_TUNABLE_AUST_SHM_CFG_H +#define SPDS_S8000_B0_TUNABLE_AUST_SHM_CFG_H + +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_B0 (0x1800) +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1800) + +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_B0_TUNABLE_AUST_SHM_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/b0/tunable/x1_pcie_rc.h b/platform/s8000/include/platform/soc/s8000/b0/tunable/x1_pcie_rc.h new file mode 100644 index 0000000..881f17d --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/b0/tunable/x1_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_B0_TUNABLE_X1_PCIE_RC_H +#define SPDS_S8000_B0_TUNABLE_X1_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_FPGA_TUNABLES_S8000_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_FPGA_TUNABLES_S8000_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_B0_TUNABLE_X1_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/b0/tunable/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8000/b0/tunable/x2_pcie_rc.h new file mode 100644 index 0000000..f233f2d --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/b0/tunable/x2_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_B0_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8000_B0_TUNABLE_X2_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_FPGA_TUNABLES_S8000_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_B0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8000_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_FPGA_TUNABLES_S8000_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_B0_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_common.h b/platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_common.h new file mode 100644 index 0000000..526f496 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_common.h @@ -0,0 +1,179 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_C0_TUNABLE_APCIE_COMMON_H +#define SPDS_S8000_C0_TUNABLE_APCIE_COMMON_H + +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f7f7f7f) +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x700) +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xc0800) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1fff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x92c) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xffffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x2001000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x9) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1000010) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_UMASK_S8000_C0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_VALUE_S8000_C0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_UMASK_S8000_C0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_VALUE_S8000_C0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_UMASK_S8000_C0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_VALUE_S8000_C0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_UMASK_S8000_C0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_VALUE_S8000_C0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x43f00) + +#define PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_FABRIC_TLIMITS */ 0x8, sizeof(uint32_t), 0x7f7f7f7f, 0x0 }, \ +{ /* APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL */ 0xc, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_COMMON_PRIORITY */ 0x10, sizeof(uint32_t), 0x700, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING */ 0x18, sizeof(uint32_t), 0xffffff, 0xc0800 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH */ 0x1c, sizeof(uint32_t), 0x1fff, 0x92c }, \ +{ /* APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL */ 0x28, sizeof(uint32_t), 0xffffffff, 0x2001000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING */ 0x30, sizeof(uint32_t), 0xff, 0x9 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x31100010, 0x1000010 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x104, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY */ 0x108, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0 */ 0x10c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0 */ 0x110, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0 */ 0x120, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0 */ 0x128, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_0 */ 0x130, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0 */ 0x134, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1 */ 0x190, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1 */ 0x1a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1 */ 0x1a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_1 */ 0x1b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1 */ 0x1b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2 */ 0x210, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2 */ 0x220, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2 */ 0x228, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_2 */ 0x230, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2 */ 0x234, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3 */ 0x290, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3 */ 0x2a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3 */ 0x2a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_3 */ 0x2b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3 */ 0x2b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_FPGA_TUNABLES_S8000_C0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_C0_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_config.h b/platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_config.h new file mode 100644 index 0000000..c3f1bed --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/c0/tunable/apcie_config.h @@ -0,0 +1,133 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_C0_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8000_C0_TUNABLE_APCIE_CONFIG_H + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x5) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f7f) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x3) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x8073ffff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x403d09) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x5) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f7f) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x3) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x8073ffff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x403d09) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x5) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f7f) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x3) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x8073ffff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x403d09) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x5) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7f7f) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x3) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x8073ffff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x403d09) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_C0_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_cfg.h b/platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_cfg.h new file mode 100644 index 0000000..c655327 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_cfg.h @@ -0,0 +1,122 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_C0_TUNABLE_AUSR_CFG_H +#define SPDS_S8000_C0_TUNABLE_AUSR_CFG_H + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xfc) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf000) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x18) + +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xc0) +#define PCIE_APCIE_PHY_AUSR0_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_PHY_AUSR0_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xfc) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf000) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x18) + +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xc0) +#define PCIE_APCIE_PHY_AUSR1_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_PHY_AUSR1_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xfc) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf000) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x18) + +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xc0) +#define PCIE_APCIE_PHY_AUSR2_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_PHY_AUSR2_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xfc) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf000) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x18) + +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xc0) +#define PCIE_APCIE_PHY_AUSR3_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_PHY_AUSR3_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xfc) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG1W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xa0) + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf000) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG5W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x5000) + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x7eff) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG_COM_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x18) + +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xc0) +#define PCIE_APCIE_PHY_AUSR4_CFG_BLK_CFG6W_CDR_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x40) + +#define PCIE_APCIE_PHY_AUSR4_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_CFG_BLK_CFG1W_CDR */ 0x24, sizeof(uint32_t), 0xfc, 0xa0 }, \ +{ /* AUSR_CFG_BLK_CFG5W_CDR */ 0x34, sizeof(uint32_t), 0xf000, 0x5000 }, \ +{ /* AUSR_CFG_BLK_CFG_COM */ 0x40, sizeof(uint32_t), 0x7eff, 0x18 }, \ +{ /* AUSR_CFG_BLK_CFG6W_CDR */ 0x44, sizeof(uint32_t), 0xc0, 0x40 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_C0_TUNABLE_AUSR_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_shm_cfg.h b/platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_shm_cfg.h new file mode 100644 index 0000000..08481a9 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/c0/tunable/ausr_shm_cfg.h @@ -0,0 +1,62 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_C0_TUNABLE_AUSR_SHM_CFG_H +#define SPDS_S8000_C0_TUNABLE_AUSR_SHM_CFG_H + +#define PCIE_APCIE_PHY_AUSR0_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR0_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR0_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR1_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR1_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR1_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR2_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR2_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR2_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR3_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR3_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR3_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUSR4_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1ef) +#define PCIE_APCIE_PHY_AUSR4_SHM_CFG_BLK_RXA_CFG2_DEFAULT_TUNABLE_VALUE_S8000_C0 (0xe7) + +#define PCIE_APCIE_PHY_AUSR4_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUSR_SHM_CFG_BLK_RXA_CFG2 */ 0x50, sizeof(uint32_t), 0x1ef, 0xe7 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_C0_TUNABLE_AUSR_SHM_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/c0/tunable/aust_shm_cfg.h b/platform/s8000/include/platform/soc/s8000/c0/tunable/aust_shm_cfg.h new file mode 100644 index 0000000..b574366 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/c0/tunable/aust_shm_cfg.h @@ -0,0 +1,82 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_C0_TUNABLE_AUST_SHM_CFG_H +#define SPDS_S8000_C0_TUNABLE_AUST_SHM_CFG_H + +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST0_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST1_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST2_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST3_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG6_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_UMASK_S8000_C0 (0x1800) +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_BLK_CFG7_TXA_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1800) + +#define PCIE_APCIE_PHY_AUST4_SHM_CFG_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* AUST_SHM_CFG_BLK_CFG6_TXA */ 0x18, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ /* AUST_SHM_CFG_BLK_CFG7_TXA */ 0x1c, sizeof(uint32_t), 0x1800, 0x1800 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_C0_TUNABLE_AUST_SHM_CFG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/c0/tunable/x1_pcie_rc.h b/platform/s8000/include/platform/soc/s8000/c0/tunable/x1_pcie_rc.h new file mode 100644 index 0000000..2b380ff --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/c0/tunable/x1_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_C0_TUNABLE_X1_PCIE_RC_H +#define SPDS_S8000_C0_TUNABLE_X1_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_C0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_FPGA_TUNABLES_S8000_C0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_C0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_FPGA_TUNABLES_S8000_C0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_C0_TUNABLE_X1_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/c0/tunable/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8000/c0/tunable/x2_pcie_rc.h new file mode 100644 index 0000000..e675779 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/c0/tunable/x2_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_C0_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8000_C0_TUNABLE_X2_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_C0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_FPGA_TUNABLES_S8000_C0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8000_C0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8000_C0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8000_C0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8000_C0 (0x1900) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8000_C0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x1900 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_FPGA_TUNABLES_S8000_C0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8000_C0_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/x1_pcie_rc.h b/platform/s8000/include/platform/soc/s8000/x1_pcie_rc.h new file mode 100644 index 0000000..61a7dde --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/x1_pcie_rc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_TUNABLE_X1_PCIE_RC_H +#define SPDS_S8000_TUNABLE_X1_PCIE_RC_H + +#include +#include + +#endif /* SPDS_S8000_TUNABLE_X1_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8000/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8000/x2_pcie_rc.h new file mode 100644 index 0000000..8391716 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8000/x2_pcie_rc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8000_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8000_TUNABLE_X2_PCIE_RC_H + +#include +#include + +#endif /* SPDS_S8000_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_common.h b/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_common.h new file mode 100644 index 0000000..ae0b77a --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_common.h @@ -0,0 +1,276 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_A0_TUNABLE_APCIE_COMMON_H +#define SPDS_S8001_A0_TUNABLE_APCIE_COMMON_H + +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f7f7f7f) +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x700) +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_VALUE_S8001_A0 (0xc0800) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x1fff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x92c) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xffffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x9) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_NVME_TUNABLE_UMASK_S8001_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_NVME_TUNABLE_VALUE_S8001_A0 (0x10) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_UMASK_S8001_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_VALUE_S8001_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_NVME_TUNABLE_UMASK_S8001_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_NVME_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_UMASK_S8001_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_VALUE_S8001_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_NVME_TUNABLE_UMASK_S8001_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_NVME_TUNABLE_VALUE_S8001_A0 (0x10) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_UMASK_S8001_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_VALUE_S8001_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_NVME_TUNABLE_UMASK_S8001_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_NVME_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_UMASK_S8001_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_VALUE_S8001_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_NVME_TUNABLE_UMASK_S8001_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_NVME_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_FPGA_TUNABLE_UMASK_S8001_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_FPGA_TUNABLE_VALUE_S8001_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_4_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_4_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_4_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_4_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_NVME_TUNABLE_UMASK_S8001_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_NVME_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_FPGA_TUNABLE_UMASK_S8001_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_FPGA_TUNABLE_VALUE_S8001_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_5_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_5_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_5_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_5_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_FABRIC_TLIMITS */ 0x8, sizeof(uint32_t), 0x7f7f7f7f, 0x0 }, \ +{ /* APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL */ 0xc, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_COMMON_PRIORITY */ 0x10, sizeof(uint32_t), 0x700, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING */ 0x18, sizeof(uint32_t), 0xffffff, 0xc0800 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH */ 0x1c, sizeof(uint32_t), 0x1fff, 0x92c }, \ +{ /* APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL */ 0x24, sizeof(uint32_t), 0xffffffff, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING */ 0x2c, sizeof(uint32_t), 0xff, 0x9 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x30100010, 0x10 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x108, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY_0 */ 0x10c, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0 */ 0x110, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0 */ 0x120, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0 */ 0x130, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0 */ 0x138, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_0 */ 0x140, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0 */ 0x144, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1 */ 0x1a0, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1 */ 0x1b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1 */ 0x1b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_1 */ 0x1c0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1 */ 0x1c4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_2 */ 0x208, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY_2 */ 0x20c, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_2 */ 0x210, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2 */ 0x220, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2 */ 0x230, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2 */ 0x238, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_2 */ 0x240, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2 */ 0x244, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3 */ 0x2a0, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3 */ 0x2b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3 */ 0x2b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_3 */ 0x2c0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3 */ 0x2c4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_4 */ 0x300, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_4 */ 0x320, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_4 */ 0x330, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_4 */ 0x338, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_4 */ 0x340, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_4 */ 0x344, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_5 */ 0x380, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_5 */ 0x3a0, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_5 */ 0x3b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_5 */ 0x3b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_5 */ 0x3c0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_5 */ 0x3c4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_FPGA_TUNABLES_S8001_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_4 */ 0x300, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_5 */ 0x380, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_NVME_TUNABLES_S8001_A0 \ +/* Key = nvme_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x10, 0x10 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x10, 0x10 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_4 */ 0x300, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_5 */ 0x380, sizeof(uint32_t), 0x10, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_A0_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_config.h b/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_config.h new file mode 100644 index 0000000..1a214f5 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_config.h @@ -0,0 +1,215 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_A0_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8001_A0_TUNABLE_APCIE_CONFIG_H + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x5) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x5) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f7f) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x8073ffff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x403d09) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xfff0fff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x440089) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x5) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x5) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f7f) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x8073ffff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x403d09) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xfff0fff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x440089) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x5) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x5) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f7f) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x8073ffff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x403d09) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xfff0fff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x440089) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x5) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x5) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f7f) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x8073ffff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x403d09) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xfff0fff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x440089) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x28) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x5) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x5) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x1) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f7f) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x8073ffff) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x403d09) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xfff0fff) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x440089) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xff) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x28) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x5) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x5) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x1) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x1) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x7f7f) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x3) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x8073ffff) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x403d09) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xfff0fff) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x440089) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_A0_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_phy_glue.h b/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_phy_glue.h new file mode 100644 index 0000000..b54e458 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/a0/tunable/apcie_phy_glue.h @@ -0,0 +1,30 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_A0_TUNABLE_APCIE_PHY_GLUE_H +#define SPDS_S8001_A0_TUNABLE_APCIE_PHY_GLUE_H + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_UMASK_S8001_A0 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG0 */ 0x0, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG1 */ 0x4, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_A0_TUNABLE_APCIE_PHY_GLUE_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/a0/tunable/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8001/a0/tunable/x2_pcie_rc.h new file mode 100644 index 0000000..1e404d0 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/a0/tunable/x2_pcie_rc.h @@ -0,0 +1,149 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_A0_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8001_A0_TUNABLE_X2_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_FPGA_TUNABLES_S8001_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_FPGA_TUNABLES_S8001_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_FPGA_TUNABLES_S8001_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_FPGA_TUNABLES_S8001_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC4_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC4_FPGA_TUNABLES_S8001_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC5_DEFAULT_TUNABLES_S8001_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC5_FPGA_TUNABLES_S8001_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_A0_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/apcie_common.h b/platform/s8000/include/platform/soc/s8001/apcie_common.h new file mode 100644 index 0000000..69c04df --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/apcie_common.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_TUNABLE_APCIE_COMMON_H +#define SPDS_S8001_TUNABLE_APCIE_COMMON_H + +#include +#include + +#endif /* SPDS_S8001_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/apcie_config.h b/platform/s8000/include/platform/soc/s8001/apcie_config.h new file mode 100644 index 0000000..3d4f16a --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/apcie_config.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8001_TUNABLE_APCIE_CONFIG_H + +#include +#include + +#endif /* SPDS_S8001_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/apcie_phy_glue.h b/platform/s8000/include/platform/soc/s8001/apcie_phy_glue.h new file mode 100644 index 0000000..fa804b7 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/apcie_phy_glue.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_TUNABLE_APCIE_PHY_GLUE_H +#define SPDS_S8001_TUNABLE_APCIE_PHY_GLUE_H + +#include +#include + +#endif /* SPDS_S8001_TUNABLE_APCIE_PHY_GLUE_H */ diff --git a/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_common.h b/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_common.h new file mode 100644 index 0000000..c19aaf5 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_common.h @@ -0,0 +1,276 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_B0_TUNABLE_APCIE_COMMON_H +#define SPDS_S8001_B0_TUNABLE_APCIE_COMMON_H + +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f7f7f7f) +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x700) +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_VALUE_S8001_B0 (0xc0800) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x1fff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x92c) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xffffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x9) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_NVME_TUNABLE_UMASK_S8001_B0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_NVME_TUNABLE_VALUE_S8001_B0 (0x10) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_UMASK_S8001_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_VALUE_S8001_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_NVME_TUNABLE_UMASK_S8001_B0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_NVME_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_UMASK_S8001_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_VALUE_S8001_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_B0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_NVME_TUNABLE_UMASK_S8001_B0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_NVME_TUNABLE_VALUE_S8001_B0 (0x10) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_UMASK_S8001_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_VALUE_S8001_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_NVME_TUNABLE_UMASK_S8001_B0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_NVME_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_UMASK_S8001_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_VALUE_S8001_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_B0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_NVME_TUNABLE_UMASK_S8001_B0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_NVME_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_FPGA_TUNABLE_UMASK_S8001_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_4_FPGA_TUNABLE_VALUE_S8001_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_B0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_4_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_4_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_4_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_4_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_4_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_4_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_NVME_TUNABLE_UMASK_S8001_B0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_NVME_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x30100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_FPGA_TUNABLE_UMASK_S8001_B0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_5_FPGA_TUNABLE_VALUE_S8001_B0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_B0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_5_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_5_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_5_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_5_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_5_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_5_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x43f00) + +#define PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_FABRIC_TLIMITS */ 0x8, sizeof(uint32_t), 0x7f7f7f7f, 0x0 }, \ +{ /* APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL */ 0xc, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_COMMON_PRIORITY */ 0x10, sizeof(uint32_t), 0x700, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING */ 0x18, sizeof(uint32_t), 0xffffff, 0xc0800 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH */ 0x1c, sizeof(uint32_t), 0x1fff, 0x92c }, \ +{ /* APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL */ 0x24, sizeof(uint32_t), 0xffffffff, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING */ 0x2c, sizeof(uint32_t), 0xff, 0x9 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x30100010, 0x10 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x108, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY_0 */ 0x10c, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0 */ 0x110, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0 */ 0x120, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0 */ 0x130, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0 */ 0x138, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_0 */ 0x140, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0 */ 0x144, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1 */ 0x1a0, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1 */ 0x1b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1 */ 0x1b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_1 */ 0x1c0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1 */ 0x1c4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_2 */ 0x208, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY_2 */ 0x20c, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_2 */ 0x210, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2 */ 0x220, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2 */ 0x230, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2 */ 0x238, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_2 */ 0x240, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2 */ 0x244, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3 */ 0x2a0, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3 */ 0x2b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3 */ 0x2b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_3 */ 0x2c0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3 */ 0x2c4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_4 */ 0x300, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_4 */ 0x320, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_4 */ 0x330, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_4 */ 0x338, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_4 */ 0x340, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_4 */ 0x344, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_5 */ 0x380, sizeof(uint32_t), 0x30100010, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_5 */ 0x3a0, sizeof(uint32_t), 0x3003f, 0x1000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_5 */ 0x3b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_5 */ 0x3b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_5 */ 0x3c0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_5 */ 0x3c4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_FPGA_TUNABLES_S8001_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_4 */ 0x300, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_5 */ 0x380, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_NVME_TUNABLES_S8001_B0 \ +/* Key = nvme_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x10, 0x10 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x10, 0x10 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_4 */ 0x300, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_5 */ 0x380, sizeof(uint32_t), 0x10, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_B0_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_config.h b/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_config.h new file mode 100644 index 0000000..29195a3 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_config.h @@ -0,0 +1,215 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_B0_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8001_B0_TUNABLE_APCIE_CONFIG_H + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x5) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x5) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f7f) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x8073ffff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x403d09) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xfff0fff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x440089) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x5) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x5) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f7f) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x8073ffff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x403d09) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xfff0fff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x440089) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x5) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x5) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f7f) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x8073ffff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x403d09) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xfff0fff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x440089) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x5) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x5) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f7f) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x8073ffff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x403d09) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xfff0fff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x440089) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x28) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x5) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x5) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x1) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f7f) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x8073ffff) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x403d09) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xfff0fff) +#define PCIE_APCIE_PORT4_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x440089) + +#define PCIE_APCIE_PORT4_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xff) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x28) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x5) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x5) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x1) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x1) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x7f7f) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x3) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x8073ffff) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x403d09) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xfff0fff) +#define PCIE_APCIE_PORT5_APCIE_CONFIG_BLK_REGS_AMAP_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x440089) + +#define PCIE_APCIE_PORT5_APCIE_CONFIG_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ /* APCIE_CONFIG_BLK_REGS_AMAP */ 0x144, sizeof(uint32_t), 0xfff0fff, 0x440089 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_B0_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_phy_glue.h b/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_phy_glue.h new file mode 100644 index 0000000..d723917 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/b0/tunable/apcie_phy_glue.h @@ -0,0 +1,30 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_B0_TUNABLE_APCIE_PHY_GLUE_H +#define SPDS_S8001_B0_TUNABLE_APCIE_PHY_GLUE_H + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_UMASK_S8001_B0 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG0 */ 0x0, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG1 */ 0x4, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_B0_TUNABLE_APCIE_PHY_GLUE_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/b0/tunable/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8001/b0/tunable/x2_pcie_rc.h new file mode 100644 index 0000000..3ca4672 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/b0/tunable/x2_pcie_rc.h @@ -0,0 +1,149 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_B0_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8001_B0_TUNABLE_X2_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_FPGA_TUNABLES_S8001_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_FPGA_TUNABLES_S8001_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_FPGA_TUNABLES_S8001_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_FPGA_TUNABLES_S8001_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC4_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC4_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC4_FPGA_TUNABLES_S8001_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8001_B0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8001_B0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC5_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8001_B0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC5_DEFAULT_TUNABLES_S8001_B0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC5_FPGA_TUNABLES_S8001_B0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8001_B0_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8001/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8001/x2_pcie_rc.h new file mode 100644 index 0000000..d191284 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8001/x2_pcie_rc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8001_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8001_TUNABLE_X2_PCIE_RC_H + +#include +#include + +#endif /* SPDS_S8001_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_common.h b/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_common.h new file mode 100644 index 0000000..9e46fce --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_common.h @@ -0,0 +1,179 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A0_TUNABLE_APCIE_COMMON_H +#define SPDS_S8003_A0_TUNABLE_APCIE_COMMON_H + +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f7f7f7f) +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x700) +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_VALUE_S8003_A0 (0xc0800) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x1fff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x92c) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xffffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x2001000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x9) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1000010) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_UMASK_S8003_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_VALUE_S8003_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_UMASK_S8003_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_VALUE_S8003_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_UMASK_S8003_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_VALUE_S8003_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_UMASK_S8003_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_VALUE_S8003_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_FABRIC_TLIMITS */ 0x8, sizeof(uint32_t), 0x7f7f7f7f, 0x0 }, \ +{ /* APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL */ 0xc, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_COMMON_PRIORITY */ 0x10, sizeof(uint32_t), 0x700, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING */ 0x18, sizeof(uint32_t), 0xffffff, 0xc0800 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH */ 0x1c, sizeof(uint32_t), 0x1fff, 0x92c }, \ +{ /* APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL */ 0x28, sizeof(uint32_t), 0xffffffff, 0x2001000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING */ 0x30, sizeof(uint32_t), 0xff, 0x9 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x31100010, 0x1000010 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x104, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY */ 0x108, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0 */ 0x10c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0 */ 0x110, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0 */ 0x120, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0 */ 0x128, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_0 */ 0x130, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0 */ 0x134, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1 */ 0x190, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1 */ 0x1a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1 */ 0x1a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_1 */ 0x1b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1 */ 0x1b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2 */ 0x210, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2 */ 0x220, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2 */ 0x228, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_2 */ 0x230, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2 */ 0x234, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3 */ 0x290, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3 */ 0x2a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3 */ 0x2a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_3 */ 0x2b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3 */ 0x2b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_FPGA_TUNABLES_S8003_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A0_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_config.h b/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_config.h new file mode 100644 index 0000000..c34f993 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_config.h @@ -0,0 +1,133 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A0_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8003_A0_TUNABLE_APCIE_CONFIG_H + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x5) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x5) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f7f) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x3) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x8073ffff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x403d09) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x5) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x5) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f7f) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x3) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x8073ffff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x403d09) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x5) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x5) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f7f) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x3) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x8073ffff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x403d09) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x5) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x5) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x7f7f) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x3) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x8073ffff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x403d09) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A0_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_phy_glue.h b/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_phy_glue.h new file mode 100644 index 0000000..7bc09b4 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a0/tunable/apcie_phy_glue.h @@ -0,0 +1,30 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A0_TUNABLE_APCIE_PHY_GLUE_H +#define SPDS_S8003_A0_TUNABLE_APCIE_PHY_GLUE_H + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_UMASK_S8003_A0 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG0 */ 0x0, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG1 */ 0x4, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A0_TUNABLE_APCIE_PHY_GLUE_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a0/tunable/x1_pcie_rc.h b/platform/s8000/include/platform/soc/s8003/a0/tunable/x1_pcie_rc.h new file mode 100644 index 0000000..2e8052c --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a0/tunable/x1_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A0_TUNABLE_X1_PCIE_RC_H +#define SPDS_S8003_A0_TUNABLE_X1_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_FPGA_TUNABLES_S8003_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_FPGA_TUNABLES_S8003_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A0_TUNABLE_X1_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a0/tunable/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8003/a0/tunable/x2_pcie_rc.h new file mode 100644 index 0000000..b7b5740 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a0/tunable/x2_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A0_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8003_A0_TUNABLE_X2_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_FPGA_TUNABLES_S8003_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8003_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_FPGA_TUNABLES_S8003_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A0_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_common.h b/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_common.h new file mode 100644 index 0000000..287f9ae --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_common.h @@ -0,0 +1,179 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A1_TUNABLE_APCIE_COMMON_H +#define SPDS_S8003_A1_TUNABLE_APCIE_COMMON_H + +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f7f7f7f) +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x700) +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_VALUE_S8003_A1 (0xc0800) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x1fff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x92c) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x2001000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x9) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1000010) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_UMASK_S8003_A1 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_VALUE_S8003_A1 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_UMASK_S8003_A1 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_VALUE_S8003_A1 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_UMASK_S8003_A1 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_VALUE_S8003_A1 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_UMASK_S8003_A1 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_VALUE_S8003_A1 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x40) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x43f00) + +#define PCIE_APCIE_COMMON_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_FABRIC_TLIMITS */ 0x8, sizeof(uint32_t), 0x7f7f7f7f, 0x0 }, \ +{ /* APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL */ 0xc, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_COMMON_PRIORITY */ 0x10, sizeof(uint32_t), 0x700, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING */ 0x18, sizeof(uint32_t), 0xffffff, 0xc0800 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH */ 0x1c, sizeof(uint32_t), 0x1fff, 0x92c }, \ +{ /* APCIE_COMMON_BLK_APCIE_PHY_POWERUP_CTRL */ 0x28, sizeof(uint32_t), 0xffffffff, 0x2001000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING */ 0x30, sizeof(uint32_t), 0xff, 0x9 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x31100010, 0x1000010 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x104, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY */ 0x108, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0 */ 0x10c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0 */ 0x110, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0 */ 0x120, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0 */ 0x128, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_0 */ 0x130, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0 */ 0x134, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1 */ 0x190, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1 */ 0x1a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1 */ 0x1a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_1 */ 0x1b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1 */ 0x1b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2 */ 0x210, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2 */ 0x220, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2 */ 0x228, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_2 */ 0x230, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2 */ 0x234, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3 */ 0x290, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3 */ 0x2a0, sizeof(uint32_t), 0xff, 0x40 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3 */ 0x2a8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_3 */ 0x2b0, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3 */ 0x2b4, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_FPGA_TUNABLES_S8003_A1 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A1_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_config.h b/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_config.h new file mode 100644 index 0000000..88a1225 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_config.h @@ -0,0 +1,133 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A1_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8003_A1_TUNABLE_APCIE_CONFIG_H + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x5) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x5) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f7f) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x8073ffff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x403d09) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x5) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x5) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f7f) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x8073ffff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x403d09) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x5) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x5) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f7f) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x8073ffff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x403d09) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x5) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x5) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x7f7f) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x8073ffff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x403d09) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x5, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A1_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_phy_glue.h b/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_phy_glue.h new file mode 100644 index 0000000..3a86103 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a1/tunable/apcie_phy_glue.h @@ -0,0 +1,590 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A1_TUNABLE_APCIE_PHY_GLUE_H +#define SPDS_S8003_A1_TUNABLE_APCIE_PHY_GLUE_H + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x318c) +#define PCIE_APCIE_PHY_GLUE_BLK_REFBUF_CFG1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x2108) + +#define PCIE_APCIE_PHY_GLUE_BLK_CMN_PWRON_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_CMN_PWRON_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x207) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE0_PWRON_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE0_PWRON_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x80c) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE1_PWRON_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE1_PWRON_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x817) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE2_PWRON_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE2_PWRON_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x822) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE3_PWRON_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE3_PWRON_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x82c) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE4_PWRON_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE4_PWRON_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x836) + +#define PCIE_APCIE_PHY_GLUE_BLK_CMN_PWROFF_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_CMN_PWROFF_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x200) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE0_PWROFF_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE0_PWROFF_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x102) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE1_PWROFF_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE1_PWROFF_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x103) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE2_PWROFF_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE2_PWROFF_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x104) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE3_PWROFF_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE3_PWROFF_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x105) + +#define PCIE_APCIE_PHY_GLUE_BLK_LANE4_PWROFF_CFG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0x3f3f) +#define PCIE_APCIE_PHY_GLUE_BLK_LANE4_PWROFF_CFG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x106) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x60) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x61) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4022) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4222) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR4_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR4_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4422) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR5_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR5_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4622) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR6_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR6_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4822) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR7_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR7_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x60) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR8_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR8_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x61) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR9_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR9_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR10_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR10_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR11_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR11_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR12_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR12_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8032) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR13_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR13_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8030) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR14_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR14_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x80c2) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR15_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR15_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x80d0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR16_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR16_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x80cc) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR17_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR17_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8063) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR18_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR18_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x41e1) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR19_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR19_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4022) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR20_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR20_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR21_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR21_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR22_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR22_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR23_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR23_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8232) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR24_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR24_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8230) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR25_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR25_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x82c2) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR26_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR26_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x82d0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR27_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR27_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x82cc) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR28_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR28_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8263) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR29_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR29_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x43e1) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR30_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR30_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4222) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR31_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR31_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR32_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR32_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR33_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR33_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR34_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR34_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8432) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR35_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR35_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8430) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR36_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR36_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x84c2) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR37_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR37_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x84d0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR38_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR38_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x84cc) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR39_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR39_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8463) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR40_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR40_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x45e1) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR41_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR41_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4422) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR42_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR42_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR43_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR43_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR44_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR44_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8632) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR45_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR45_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8630) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR46_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR46_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x86c2) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR47_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR47_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x86d0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR48_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR48_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x86cc) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR49_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR49_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8663) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR50_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR50_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x47e1) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR51_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR51_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4622) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR52_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR52_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR53_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR53_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR54_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR54_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8832) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR55_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR55_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8830) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR56_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR56_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x88c2) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR57_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR57_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x88d0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR58_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR58_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x88cc) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR59_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR59_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8863) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR60_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR60_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x49e1) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR61_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR61_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x4822) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR62_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR62_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR63_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR63_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA0_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA0_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA1_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA1_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA2_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA2_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA3_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA3_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA4_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA4_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA5_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA5_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA6_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA6_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA7_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA7_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8015) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA8_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA8_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8015) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA9_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA9_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA10_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA10_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA11_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA11_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA12_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA12_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x802a) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA13_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA13_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8000) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA14_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA14_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3c7) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA15_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA15_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA16_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA16_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x72) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA17_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA17_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA18_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA18_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA19_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA19_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8015) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA20_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA20_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA21_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA21_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA22_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA22_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA23_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA23_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x802a) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA24_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA24_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8000) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA25_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA25_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3c7) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA26_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA26_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA27_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA27_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x72) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA28_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA28_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA29_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA29_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA30_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA30_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8015) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA31_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA31_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA32_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA32_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA33_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA33_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA34_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA34_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x802a) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA35_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA35_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8000) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA36_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA36_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3c7) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA37_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA37_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA38_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA38_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x72) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA39_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA39_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA40_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA40_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA41_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA41_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8015) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA42_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA42_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA43_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA43_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA44_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA44_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x802a) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA45_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA45_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8000) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA46_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA46_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3c7) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA47_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA47_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA48_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA48_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x72) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA49_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA49_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA50_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA50_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA51_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA51_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8015) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA52_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA52_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA53_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA53_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA54_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA54_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x802a) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA55_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA55_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8000) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA56_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA56_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x3c7) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA57_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA57_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA58_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA58_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x72) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA59_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA59_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x15) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA60_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA60_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA61_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA61_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x8015) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA62_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA62_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA63_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xffff) +#define PCIE_APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA63_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG0 */ 0x0, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ /* APCIE_PHY_GLUE_BLK_REFBUF_CFG1 */ 0x4, sizeof(uint32_t), 0x318c, 0x2108 }, \ +{ /* APCIE_PHY_GLUE_BLK_CMN_PWRON_CFG */ 0x80, sizeof(uint32_t), 0x3f3f, 0x207 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE0_PWRON_CFG */ 0x84, sizeof(uint32_t), 0x3f3f, 0x80c }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE1_PWRON_CFG */ 0x88, sizeof(uint32_t), 0x3f3f, 0x817 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE2_PWRON_CFG */ 0x8c, sizeof(uint32_t), 0x3f3f, 0x822 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE3_PWRON_CFG */ 0x90, sizeof(uint32_t), 0x3f3f, 0x82c }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE4_PWRON_CFG */ 0x94, sizeof(uint32_t), 0x3f3f, 0x836 }, \ +{ /* APCIE_PHY_GLUE_BLK_CMN_PWROFF_CFG */ 0xa0, sizeof(uint32_t), 0x3f3f, 0x200 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE0_PWROFF_CFG */ 0xa4, sizeof(uint32_t), 0x3f3f, 0x102 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE1_PWROFF_CFG */ 0xa8, sizeof(uint32_t), 0x3f3f, 0x103 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE2_PWROFF_CFG */ 0xac, sizeof(uint32_t), 0x3f3f, 0x104 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE3_PWROFF_CFG */ 0xb0, sizeof(uint32_t), 0x3f3f, 0x105 }, \ +{ /* APCIE_PHY_GLUE_BLK_LANE4_PWROFF_CFG */ 0xb4, sizeof(uint32_t), 0x3f3f, 0x106 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR0 */ 0x400, sizeof(uint32_t), 0xffff, 0x60 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR1 */ 0x404, sizeof(uint32_t), 0xffff, 0x61 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR2 */ 0x408, sizeof(uint32_t), 0xffff, 0x4022 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR3 */ 0x40c, sizeof(uint32_t), 0xffff, 0x4222 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR4 */ 0x410, sizeof(uint32_t), 0xffff, 0x4422 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR5 */ 0x414, sizeof(uint32_t), 0xffff, 0x4622 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR6 */ 0x418, sizeof(uint32_t), 0xffff, 0x4822 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR7 */ 0x41c, sizeof(uint32_t), 0xffff, 0x60 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR8 */ 0x420, sizeof(uint32_t), 0xffff, 0x61 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR9 */ 0x424, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR10 */ 0x428, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR11 */ 0x42c, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR12 */ 0x430, sizeof(uint32_t), 0xffff, 0x8032 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR13 */ 0x434, sizeof(uint32_t), 0xffff, 0x8030 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR14 */ 0x438, sizeof(uint32_t), 0xffff, 0x80c2 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR15 */ 0x43c, sizeof(uint32_t), 0xffff, 0x80d0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR16 */ 0x440, sizeof(uint32_t), 0xffff, 0x80cc }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR17 */ 0x444, sizeof(uint32_t), 0xffff, 0x8063 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR18 */ 0x448, sizeof(uint32_t), 0xffff, 0x41e1 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR19 */ 0x44c, sizeof(uint32_t), 0xffff, 0x4022 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR20 */ 0x450, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR21 */ 0x454, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR22 */ 0x458, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR23 */ 0x45c, sizeof(uint32_t), 0xffff, 0x8232 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR24 */ 0x460, sizeof(uint32_t), 0xffff, 0x8230 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR25 */ 0x464, sizeof(uint32_t), 0xffff, 0x82c2 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR26 */ 0x468, sizeof(uint32_t), 0xffff, 0x82d0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR27 */ 0x46c, sizeof(uint32_t), 0xffff, 0x82cc }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR28 */ 0x470, sizeof(uint32_t), 0xffff, 0x8263 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR29 */ 0x474, sizeof(uint32_t), 0xffff, 0x43e1 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR30 */ 0x478, sizeof(uint32_t), 0xffff, 0x4222 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR31 */ 0x47c, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR32 */ 0x480, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR33 */ 0x484, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR34 */ 0x488, sizeof(uint32_t), 0xffff, 0x8432 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR35 */ 0x48c, sizeof(uint32_t), 0xffff, 0x8430 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR36 */ 0x490, sizeof(uint32_t), 0xffff, 0x84c2 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR37 */ 0x494, sizeof(uint32_t), 0xffff, 0x84d0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR38 */ 0x498, sizeof(uint32_t), 0xffff, 0x84cc }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR39 */ 0x49c, sizeof(uint32_t), 0xffff, 0x8463 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR40 */ 0x4a0, sizeof(uint32_t), 0xffff, 0x45e1 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR41 */ 0x4a4, sizeof(uint32_t), 0xffff, 0x4422 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR42 */ 0x4a8, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR43 */ 0x4ac, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR44 */ 0x4b0, sizeof(uint32_t), 0xffff, 0x8632 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR45 */ 0x4b4, sizeof(uint32_t), 0xffff, 0x8630 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR46 */ 0x4b8, sizeof(uint32_t), 0xffff, 0x86c2 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR47 */ 0x4bc, sizeof(uint32_t), 0xffff, 0x86d0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR48 */ 0x4c0, sizeof(uint32_t), 0xffff, 0x86cc }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR49 */ 0x4c4, sizeof(uint32_t), 0xffff, 0x8663 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR50 */ 0x4c8, sizeof(uint32_t), 0xffff, 0x47e1 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR51 */ 0x4cc, sizeof(uint32_t), 0xffff, 0x4622 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR52 */ 0x4d0, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR53 */ 0x4d4, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR54 */ 0x4d8, sizeof(uint32_t), 0xffff, 0x8832 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR55 */ 0x4dc, sizeof(uint32_t), 0xffff, 0x8830 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR56 */ 0x4e0, sizeof(uint32_t), 0xffff, 0x88c2 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR57 */ 0x4e4, sizeof(uint32_t), 0xffff, 0x88d0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR58 */ 0x4e8, sizeof(uint32_t), 0xffff, 0x88cc }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR59 */ 0x4ec, sizeof(uint32_t), 0xffff, 0x8863 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR60 */ 0x4f0, sizeof(uint32_t), 0xffff, 0x49e1 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR61 */ 0x4f4, sizeof(uint32_t), 0xffff, 0x4822 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR62 */ 0x4f8, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_ADDR63 */ 0x4fc, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA0 */ 0x600, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA1 */ 0x604, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA2 */ 0x608, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA3 */ 0x60c, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA4 */ 0x610, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA5 */ 0x614, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA6 */ 0x618, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA7 */ 0x61c, sizeof(uint32_t), 0xffff, 0x8015 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA8 */ 0x620, sizeof(uint32_t), 0xffff, 0x8015 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA9 */ 0x624, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA10 */ 0x628, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA11 */ 0x62c, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA12 */ 0x630, sizeof(uint32_t), 0xffff, 0x802a }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA13 */ 0x634, sizeof(uint32_t), 0xffff, 0x8000 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA14 */ 0x638, sizeof(uint32_t), 0xffff, 0x3c7 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA15 */ 0x63c, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA16 */ 0x640, sizeof(uint32_t), 0xffff, 0x72 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA17 */ 0x644, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA18 */ 0x648, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA19 */ 0x64c, sizeof(uint32_t), 0xffff, 0x8015 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA20 */ 0x650, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA21 */ 0x654, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA22 */ 0x658, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA23 */ 0x65c, sizeof(uint32_t), 0xffff, 0x802a }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA24 */ 0x660, sizeof(uint32_t), 0xffff, 0x8000 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA25 */ 0x664, sizeof(uint32_t), 0xffff, 0x3c7 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA26 */ 0x668, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA27 */ 0x66c, sizeof(uint32_t), 0xffff, 0x72 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA28 */ 0x670, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA29 */ 0x674, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA30 */ 0x678, sizeof(uint32_t), 0xffff, 0x8015 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA31 */ 0x67c, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA32 */ 0x680, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA33 */ 0x684, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA34 */ 0x688, sizeof(uint32_t), 0xffff, 0x802a }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA35 */ 0x68c, sizeof(uint32_t), 0xffff, 0x8000 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA36 */ 0x690, sizeof(uint32_t), 0xffff, 0x3c7 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA37 */ 0x694, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA38 */ 0x698, sizeof(uint32_t), 0xffff, 0x72 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA39 */ 0x69c, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA40 */ 0x6a0, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA41 */ 0x6a4, sizeof(uint32_t), 0xffff, 0x8015 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA42 */ 0x6a8, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA43 */ 0x6ac, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA44 */ 0x6b0, sizeof(uint32_t), 0xffff, 0x802a }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA45 */ 0x6b4, sizeof(uint32_t), 0xffff, 0x8000 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA46 */ 0x6b8, sizeof(uint32_t), 0xffff, 0x3c7 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA47 */ 0x6bc, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA48 */ 0x6c0, sizeof(uint32_t), 0xffff, 0x72 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA49 */ 0x6c4, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA50 */ 0x6c8, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA51 */ 0x6cc, sizeof(uint32_t), 0xffff, 0x8015 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA52 */ 0x6d0, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA53 */ 0x6d4, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA54 */ 0x6d8, sizeof(uint32_t), 0xffff, 0x802a }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA55 */ 0x6dc, sizeof(uint32_t), 0xffff, 0x8000 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA56 */ 0x6e0, sizeof(uint32_t), 0xffff, 0x3c7 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA57 */ 0x6e4, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA58 */ 0x6e8, sizeof(uint32_t), 0xffff, 0x72 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA59 */ 0x6ec, sizeof(uint32_t), 0xffff, 0x15 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA60 */ 0x6f0, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA61 */ 0x6f4, sizeof(uint32_t), 0xffff, 0x8015 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA62 */ 0x6f8, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ /* APCIE_PHY_GLUE_BLK_RELOAD_PMA_DATA63 */ 0x6fc, sizeof(uint32_t), 0xffff, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A1_TUNABLE_APCIE_PHY_GLUE_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a1/tunable/x1_pcie_rc.h b/platform/s8000/include/platform/soc/s8003/a1/tunable/x1_pcie_rc.h new file mode 100644 index 0000000..c3c859d --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a1/tunable/x1_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A1_TUNABLE_X1_PCIE_RC_H +#define SPDS_S8003_A1_TUNABLE_X1_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A1 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_FPGA_TUNABLES_S8003_A1 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A1 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_FPGA_TUNABLES_S8003_A1 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X1_PCIE_RC_X1_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A1_TUNABLE_X1_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/a1/tunable/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8003/a1/tunable/x2_pcie_rc.h new file mode 100644 index 0000000..6f01cba --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/a1/tunable/x2_pcie_rc.h @@ -0,0 +1,61 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_A1_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8003_A1_TUNABLE_X2_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A1 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_FPGA_TUNABLES_S8003_A1 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_S8003_A1 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_S8003_A1 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_S8003_A1 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_S8003_A1 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_FPGA_TUNABLES_S8003_A1 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x154, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_S8003_A1_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/apcie_common.h b/platform/s8000/include/platform/soc/s8003/apcie_common.h new file mode 100644 index 0000000..5f1f927 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/apcie_common.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_TUNABLE_APCIE_COMMON_H +#define SPDS_S8003_TUNABLE_APCIE_COMMON_H + +#include +#include + +#endif /* SPDS_S8003_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/apcie_config.h b/platform/s8000/include/platform/soc/s8003/apcie_config.h new file mode 100644 index 0000000..6893692 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/apcie_config.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_TUNABLE_APCIE_CONFIG_H +#define SPDS_S8003_TUNABLE_APCIE_CONFIG_H + +#include +#include + +#endif /* SPDS_S8003_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/apcie_phy_glue.h b/platform/s8000/include/platform/soc/s8003/apcie_phy_glue.h new file mode 100644 index 0000000..928aa65 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/apcie_phy_glue.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_TUNABLE_APCIE_PHY_GLUE_H +#define SPDS_S8003_TUNABLE_APCIE_PHY_GLUE_H + +#include +#include + +#endif /* SPDS_S8003_TUNABLE_APCIE_PHY_GLUE_H */ diff --git a/platform/s8000/include/platform/soc/s8003/x1_pcie_rc.h b/platform/s8000/include/platform/soc/s8003/x1_pcie_rc.h new file mode 100644 index 0000000..df292c6 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/x1_pcie_rc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_TUNABLE_X1_PCIE_RC_H +#define SPDS_S8003_TUNABLE_X1_PCIE_RC_H + +#include +#include + +#endif /* SPDS_S8003_TUNABLE_X1_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/soc/s8003/x2_pcie_rc.h b/platform/s8000/include/platform/soc/s8003/x2_pcie_rc.h new file mode 100644 index 0000000..95a0060 --- /dev/null +++ b/platform/s8000/include/platform/soc/s8003/x2_pcie_rc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_S8003_TUNABLE_X2_PCIE_RC_H +#define SPDS_S8003_TUNABLE_X2_PCIE_RC_H + +#include +#include + +#endif /* SPDS_S8003_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/s8000/include/platform/trampoline.h b/platform/s8000/include/platform/trampoline.h new file mode 100644 index 0000000..ddde922 --- /dev/null +++ b/platform/s8000/include/platform/trampoline.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include + +/* ROM related registers in AOP MINIPMGR space */ + +#define SECURITY_REG (AOP_MINIPMGR_BASE_ADDR + 0xD0010) +#define ROM_READ_DISABLE (1 << 0) + +#define REMAP_REG (AOP_MINIPMGR_BASE_ADDR + 0xD0014) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/s8000/include/platform/uartconfig.h b/platform/s8000/include/platform/uartconfig.h new file mode 100644 index 0000000..f3ba186 --- /dev/null +++ b/platform/s8000/include/platform/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_UARTCONFIG_H +#define __PLATFORM_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/platform/s8000/include/platform/usbconfig.h b/platform/s8000/include/platform/usbconfig.h new file mode 100644 index 0000000..042277f --- /dev/null +++ b/platform/s8000/include/platform/usbconfig.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#if SUB_PLATFORM_S8000 +/* + * per Maui Tunables Specification, r0.18 + */ + +#define USBPHY_OTGTUNE0 (0x37477BB3) +#define USBPHY_OTGTUNE0_AX (0x37477BF3) // Maui A0/A1 uses different tuning values than B0 +#define USBPHY_OTGTUNE1 (0x20E0C) + +#elif SUB_PLATFORM_S8001 + +/* + * per Elba Tunables Specification, r0.23 + */ + +#define USBPHY_OTGTUNE0 (0x373723F3) +#define USBPHY_OTGTUNE1 (0x20E04) + +#elif SUB_PLATFORM_S8003 + +/* + * per Malta Tunables Specification, r0.31 + */ + +#define USBPHY_OTGTUNE0 (0x37377BC3) +#define USBPHY_OTGTUNE1 (0x20C04) + +#else +#error "Unknown SUB_PLATFORM" +#endif + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +#ifdef WITH_TARGET_USB_CONFIG +#include +#endif /* WITH_TARGET_USB_CONFIG */ + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/s8000/init.c b/platform/s8000/init.c new file mode 100644 index 0000000..b0056a2 --- /dev/null +++ b/platform/s8000/init.c @@ -0,0 +1,2027 @@ +/* +* Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_CONSISTENT_DBG +#include +#endif +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#if WITH_HW_DCS +#include +#endif +#include +#include +#include +#include +#include +#include +#if WITH_HW_SEP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_PLATFORM_ERROR_HANDLER +#include +#endif +#include +#include +#include +#include +#include +#include + +static void platform_init_boot_strap(void); +static int32_t platform_bootprep_darwin(void); +static int power_convert_buck_to_rail(int buck, int *rail); +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val); +static int power_convert_dwi_to_mv_fpga(unsigned int buck, uint32_t dwival); +static void platform_relocate_securerom(void); + +void platform_reconfig_sequence_insert(enum boot_target target); + +static uint8_t boot_debug; +static bool gDisplayEnabled; + +int platform_early_init(void) +{ +#if (PRODUCT_LLB || PRODUCT_IBSS) + /* Verify that the fuses and SecureROM R/W access has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile uint32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled\n"); + } + + /* Verify that the fuses are sealed on production devices. */ + if (chipid_get_current_production_mode() && !chipid_get_fuse_seal()) { + panic("Fuses are not sealed\n"); + } +#endif + + /* Enable more Cyclone specific errors */ + ccc_enable_custom_errors(); + +#if WITH_HW_PLATFORM_POWER + /* initialize the pmgr driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); + debug_enable_uarts(3); +#endif +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8001 + if (platform_get_chip_revision() < CHIP_REVISION_B0) { + platform_not_supported(); + } +#endif + +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + return 0; +} + + +int platform_late_init(void) +{ +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); + + /* turn off DEBUG clock if debug-soc nvram is not true */ + clock_gate(CLK_DEBUG, env_get_bool("debug-soc", false)); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_HW_DCS + extern void mcu_late_init(void); + mcu_late_init(); +#endif + +#if WITH_CSI + csi_late_init(); +#endif + + return 0; +} + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { +#if WITH_HW_DISPLAY_PMU + display_pmu_init(); +#endif + + if (!displayInitOnce) { + platform_quiesce_display(); + clock_gate(CLK_RTMUX, true); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + power_backlight_enable(backlight_level); +#if WITH_HW_KSF_BACKLIGHT + // Wait 20 ms for the backlight to ramp up in color while showing black frames. + // J127 red flash when pressing sleep button with white Upgrade screen + spin(20000); +#endif +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + addr_t base_rounded = *base; + addr_t end_rounded = *base + *size; + size_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage_panic(void) +{ +#if WITH_NVME + return nvme_init_mass_storage_panic(0); +#else + return 0; +#endif + +} + +int platform_init_mass_storage(void) +{ +#if WITH_NVME + return nvme_init_mass_storage(0); +#else + return 0; +#endif +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + +#if WITH_CSI + csi_quiesce(target); +#endif + +#if WITH_NVME + nvme_quiesce_all(); +#endif + +#if WITH_HW_APCIE + apcie_disable_all(); +#endif + + switch (target) { + case BOOT_HALT: + break; + case BOOT_DARWIN_RESTORE: + panic("not supported"); + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + quiesce_clocks = true; +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ + +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + clock_gate(CLK_RTMUX, true); + + /* quiesce the panel */ + if (display_quiesce(true) == ENXIO) { + clock_gate(CLK_RTMUX, false); + } +#endif + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + uint32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT +#if WITH_BOOT_XNU + case BOOT_DARWIN: + platform_bootprep_darwin(); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; + break; + + case BOOT_DIAGS: + // Insert Reconfig sequences + reconfig_init(target); + platform_reconfig_sequence_insert(target); +#if !DEBUG_BUILD && SUB_PLATFORM_S8001 + reconfig_lock(BOOT_DIAGS); +#endif + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; +#endif // WITH_BOOT_XNU + + case BOOT_IBOOT: + platform_quiesce_display(); + break; +#endif // APPLICATION_IBOOT + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + platform_relocate_securerom(); + miu_select_remap(REMAP_SRAM); +#endif + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + panic("unknown boot target %d", target); + } + + /* make sure that fuse lock bit is set. */ + if (security_get_lock_fuses()) + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + /* Disable Cyclone specific errors enabled earlier in the boot */ + ccc_disable_custom_errors(); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + +#if APPLICATION_SECUREROM + // ROM is obviously read/execute since it's ROM + arm_mmu_map_rx(VROM_BASE, VROM_BANK_LEN); + + // everything ROM needs in SRAM is read-write, + // except the trampoline which is read-execute + arm_mmu_map_rw(INSECURE_MEMORY_BASE, INSECURE_MEMORY_SIZE); + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + arm_mmu_map_rw(DATA_BASE, DATA_SIZE); + // skip page tables here + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + +#else + // Figure out where the linker put our various bits + uintptr_t text_end_aligned = ((uintptr_t)&_text_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + size_t text_size = text_end_aligned - (uintptr_t)&_text_start; + + RELEASE_ASSERT(text_end_aligned <= (uintptr_t)&_data_start); + +#if PRODUCT_LLB || PRODUCT_IBSS + arm_mmu_map_rw(SDRAM_BASE, SDRAM_LEN); + +#if !SUB_PLATFORM_S8001 + // map SecureROM testing region read-write + arm_mmu_map_rw(SRAM_BASE, HEAP_BASE - SRAM_BASE); +#endif + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + + // __TEXT is read/execute, __DATA is read/write + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, BOOT_TRAMPOLINE_BASE - text_end_aligned); + // and then boot trampoline is read/execute + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + + // skip mapping the page tables so that they can't be modified + + // map the stacks read-write + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); +#else + // Most of DRAM gets mapped read/write + arm_mmu_map_rw(SDRAM_BASE, (uintptr_t)&_text_start - SDRAM_BASE); + + // only the text section should be executable, and it should be read only + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, PAGE_TABLES_BASE - text_end_aligned); + + // skip mapping the page tables so that they can't be modified + + // map the stacks read-write + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); + + // map the boot trampoline read/execute + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + + // map the heap read-write, leaving a hole at the end + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + RELEASE_ASSERT(HEAP_BASE + HEAP_SIZE == HEAP_GUARD); + + // and then everything up to the end of DRAM is read/write again + arm_mmu_map_rw(IBOOT_BASE + IBOOT_SIZE, SDRAM_END - (IBOOT_BASE + IBOOT_SIZE)); + +#if DEBUG_BUILD + // Create a virtual mapping for SRAM to allow SecureROM testing + arm_mmu_map_rw(SRAM_BASE, SRAM_LEN); +#endif +#endif +#endif + + // map IO + arm_mmu_map_device_rw(IO_BASE, IO_SIZE); + arm_mmu_map_device_rw(PCI_REG_BASE, PCI_REG_LEN); + arm_mmu_map_device_rw(PCI_CONFIG_BASE, PCI_CONFIG_LEN); + arm_mmu_map_device_rw(PCI_32BIT_BASE, PCI_32BIT_LEN); +} + +int platform_init(void) +{ +#if defined(UNUSED_MEMORY_BASE) && (UNUSED_MEMORY_SIZE > 0) + bzero((void *)UNUSED_MEMORY_BASE, UNUSED_MEMORY_SIZE); +#endif + +#if WITH_CONSISTENT_DBG && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + consistent_debug_init(); +#endif + +#if WITH_PLATFORM_ERROR_HANDLER + platform_enable_error_handler(); +#endif + +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_PCI + pci_init(); +#endif + +#if WITH_NVME && (PRODUCT_LLB || PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) +#if PRODUCT_IBEC + apcie_set_s3e_mode(true); +#else + apcie_set_s3e_mode(false); +#endif + if (apcie_enable_link(0)) { + nvme_init(0, apcie_get_port_bridge(0), 0); + } +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + uint32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_NVME + nvme_quiesce_all(); +#endif + +#if WITH_HW_APCIE + apcie_disable_all(); +#endif + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +uint32_t platform_set_performance(uint32_t performance_level) +{ + uint32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +void platform_setup_default_environment(void) +{ +#if WITH_ENV + env_set("boot-device", "nvme_nand0", 0); +#endif + + target_setup_default_environment(); +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Hacks and workarounds + +#if SUB_PLATFORM_S8000 + if (platform_get_chip_revision() < CHIP_REVISION_B0) { + if(FindNode(0, "defaults", &node)) { + propName = "l2-ecc-correctable-panic"; + if(FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_INFO, "defaults: Disabling L2 ECC Single Bit Error Panic\n"); + *(uint32_t *) propData = 0; + } + } + if (dt_find_node(0, "arm-io/apcie", &node)) { + dt_set_prop(node, "no-nand-sysclk-gating", NULL, 0); + } + } +#endif + +#if WITH_NVME + +#if SUB_PLATFORM_S8000 +#define MIN_CHIPREV_FOR_INVALIDATE_FIFO_EMPTY_STATUS CHIP_REVISION_C0 +#elif SUB_PLATFORM_S8001 +#define MIN_CHIPREV_FOR_INVALIDATE_FIFO_EMPTY_STATUS CHIP_REVISION_B0 +#elif SUB_PLATFORM_S8003 +#define MIN_CHIPREV_FOR_INVALIDATE_FIFO_EMPTY_STATUS CHIP_REVISION_A1 +#else +#error "Unknown SUB_PLATFORM" +#endif + + if (FindNode(0, "arm-io/nvme-mmu0", &node)) { + if (platform_get_chip_revision() < MIN_CHIPREV_FOR_INVALIDATE_FIFO_EMPTY_STATUS) { + // Must use the delay loop method for older chips. + // DELETEME when Maui B0/Elba A0/Malta A0 are deprecated + dt_set_prop_32(node, "invalidate-fifo-workaround", 2); + } else { + // Can use the MMUFIFOSTS.invalidate_fifo_empty status bit. + dt_set_prop_32(node, "invalidate-fifo-workaround", 1); + } + } +#endif + + // POR stuff below + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_CPU); + memcpy(propData, &freq, propSize); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_MEM); + memcpy(propData, &freq, propSize); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_BUS); + memcpy(propData, &freq, propSize); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_PERIPH); + memcpy(propData, &freq, propSize); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_FIXED); + memcpy(propData, &freq, propSize); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_TIMEBASE); + memcpy(propData, &freq, propSize); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(uint32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the mcc node + if (FindNode(0, "arm-io/mcc", &node)) { + propName = "dcs_num_channels"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = DCS_NUM_CHANNELS; + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the gfx node + if (FindNode(0, "arm-io/sgx", &node)) { + pmgr_gfx_update_device_tree(node); + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + + // Find the apcie node +#if WITH_HW_APCIE + if (FindNode(0, "arm-io/apcie", &node)) { + apcie_update_devicetree(node); + } +#endif + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + +#if WITH_NVME + if (FindNode(0, "arm-io/nvme-mmu0", &node)) { + uintptr_t *sart_region = NULL; + uint32_t *sart_virt_base = NULL; + uint64_t *nvme_scratch_region = NULL; + + propName = "sart-region"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == 2 * sizeof(uintptr_t)) { + sart_region = (uintptr_t *)propData; + } + + propName = "sart-virtual-base"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == sizeof(uint32_t)) { + sart_virt_base = (uint32_t *)propData; + } + + if (FindNode(0, "arm-io/apcie/pci-bridge0/s3e", &node)) { + nvme_update_devicetree(0, node); + propName = "nvme-scratch-virt-region"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == 2 * sizeof(uint64_t)) { + nvme_scratch_region = propData; + } + } + + if (sart_region != NULL && sart_virt_base != NULL && nvme_scratch_region != NULL) { + // Tell PCIe driver to point the SART at the scratch buffer + sart_region[0] = platform_get_memory_region_base(kMemoryRegion_StorageProcessor); + sart_region[1] = platform_get_memory_region_size(kMemoryRegion_StorageProcessor); + // Tell NVMe driver where the SART is putting the scratch buffer + nvme_scratch_region[0] = *sart_virt_base; + nvme_scratch_region[1] = sart_region[1]; + } + } +#endif + + if (dt_find_node(NULL, "arm-io/aop", &node)) { + addr_t aop_region_base = platform_get_memory_region_base(kMemoryRegion_AOP); + addr_t aop_region_size = platform_get_memory_region_size(kMemoryRegion_AOP); + + // Find the reg that maps the AOP SRAM and adjust it to account + // for the SRAM used by the reconfig region + bool updated = false; + if (dt_find_prop(node, "reg", &propData, &propSize)) { + uintptr_t *regs = (uintptr_t *)propData; + unsigned num_regs = propSize / (sizeof(*regs) * 2); + for (unsigned i = 0; i < num_regs; i++) { + if (regs[i * 2] == aop_region_base - IO_BASE) { + regs[i * 2 + 1] = aop_region_size; + updated = true; + break; + } + } + } + + if (!updated) panic("failed to update AOP's reg property"); + + if (dt_find_node(node, "iop-aop-nub", &node)) { + dt_set_prop_addr(node, "region-base", aop_region_base); + dt_set_prop_addr(node, "region-size", aop_region_size); + } else { + panic("failed to find AOP nub node"); + } + } + + return target_update_device_tree(); +} + +#endif + +uint32_t platform_get_board_id(void) +{ + uint32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +bool platform_get_lock_fuses_required(void) +{ + bool lock_fuses = true; + + return lock_fuses; +} + +uint32_t platform_get_boot_config(void) +{ + uint32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, uint32_t *boot_flag, uint32_t *boot_arg) +{ + uint32_t boot_config = platform_get_boot_config(); + + /* S8000 supports one boot device then USB-DFU per boot config */ + + switch (boot_config) { + case BOOT_CONFIG_SPI0: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_SPI0_TEST: + case BOOT_CONFIG_FAST_SPI0_TEST: + case BOOT_CONFIG_SLOW_SPI0_TEST: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case BOOT_CONFIG_NVME0_X1: + case BOOT_CONFIG_NVME0_X2: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_NVME0_X1_TEST: + case BOOT_CONFIG_NVME0_X2_TEST: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == -1 || (index != 0 && *boot_device != BOOT_DEVICE_TBTDFU)) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + uint32_t enable; + uint32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO_SPI0_SSIN, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO_SPI0_SSIN, GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO_SPI0_SCLK, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO_SPI0_MOSI, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO_SPI0_MISO, GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, uint32_t boot_arg) +{ + const struct boot_interface_pin *pins = 0; + uint32_t cnt, func, pin_count = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins = spi0_boot_interface_pins; + pin_count = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_ANC_BOOT + case BOOT_DEVICE_NAND : + /* NAND pins are off to ASP */ + break; +#endif /* WITH_ANC_BOOT */ + +#if WITH_NVME + case BOOT_DEVICE_NVME : + { + uint32_t dart_id = 0; + uint32_t pcie_port = 0; + if (boot_arg != 0) { + panic("invalid NVMe boot argument %u", boot_arg); + } + + if (enable) { + apcie_set_s3e_mode(false); + + // Don't try to probe for the NVMe device if the link doesn't come + // up because we shut down the root complex on link initialization + // failures + if (apcie_enable_link(pcie_port)) { + nvme_init(0, apcie_get_port_bridge(pcie_port), dart_id); + } + } + if (!enable) { + // These guys are safe no-ops if the enable above failed + nvme_quiesce(0); + + apcie_disable_link(pcie_port); + } + + break; + } +#endif + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count; cnt++) { + if (enable) { + pin = pins[pin_count - 1 - cnt].pin; + func = pins[pin_count - 1 - cnt].enable; + } else { + pin = pins[cnt].pin; + func = pins[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +uint32_t platform_get_apcie_lane_cfg(void) +{ + uint32_t boot_config = platform_get_boot_config(); + + switch (boot_config) { + case BOOT_CONFIG_NVME0_X1: + case BOOT_CONFIG_NVME0_X1_TEST: + return APCIE_LANE_CONFIG_NVME0_X1; + + case BOOT_CONFIG_NVME0_X2: + case BOOT_CONFIG_NVME0_X2_TEST: + return APCIE_LANE_CONFIG_NVME0_X2; + + default: + panic("unknown pcie boot config 0x%x", boot_config); + } +} + +// Get the expected link width (number of lanes) for the given PCIe link +// A value of 0 means to auto-negotiate (and has no effect for ports +// that only support x1 mode in the hardware) +uint32_t platform_get_pcie_link_width(uint32_t link) +{ + uint32_t boot_config = platform_get_boot_config(); + + switch (boot_config) { + case BOOT_CONFIG_NVME0_X1: + case BOOT_CONFIG_NVME0_X1_TEST: + return 1; + + default: + return 0; + } +} + +uint64_t platform_get_nonce(void) +{ + uint64_t nonce; + uint32_t *nonce_words = (uint32_t *)&nonce; + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +int32_t platform_get_sep_nonce(uint8_t *nonce) +{ +#if WITH_HW_SEP + return sep_client_get_nonce(nonce); +#else + return -1; +#endif +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return true; +} + +uint32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +uint32_t platform_get_spi_frequency(void) +{ +#if SUPPORT_FPGA + return 2500000; +#else + switch (platform_get_boot_config()) { + case BOOT_CONFIG_FAST_SPI0_TEST: + return 24000000; + + case BOOT_CONFIG_SLOW_SPI0_TEST: + return 6000000; + + default: + return 12000000; + } +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ + return gpio_read(GPIO_FORCE_DFU); +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(uint32_t key_selector, uint32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +void platform_disable_keys(uint32_t gid, uint32_t uid) +{ + uint32_t keydis = (((gid & 0x3) << 1) | ((uid & 0x1) << 0)); + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return; + + rPMGR_SECURITY = keydis; + +} + +bool platform_keys_disabled(uint32_t gid, uint32_t uid) +{ + uint32_t key_disabled; + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return true; + + key_disabled = rPMGR_SECURITY; + + return (key_disabled & (((gid & 0x3) << 1) | ((uid & 0x1) << 0))); +} + +void platform_demote_production() +{ + chipid_clear_production_mode(); +} + +#if APPLICATION_IBOOT +bool platform_is_pre_lpddr4(void) +{ + return false; +} + +uint64_t platform_get_memory_size(void) +{ + uint64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (((uint64_t)rPMGR_SCRATCH13) & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +uint8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 24) & 0xff); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info_with_revids(uint8_t manuf_id, uint64_t memory_size, uint8_t rev_id, uint8_t rev_id2) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 24) | ((rev_id2 & 0xF) << 20) | ((rev_id & 0xF) << 16) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +void platform_get_memory_rev_ids(uint8_t *rev_id, uint8_t *rev_id2) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory rev_id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) + panic("memory not yet inited\n"); + else { + if (rev_id && rev_id2) { + uint8_t rev_info = (rPMGR_SCRATCH13 >> 16) & 0xFF; + *rev_id = rev_info & 0xF; + *rev_id2 = rev_info >> 4; + } + } +} +#endif + +extern void boot_handoff_trampoline(void *entry, void *arg); + +void *platform_get_boot_trampoline(void) +{ +#ifdef BOOT_TRAMPOLINE_BASE + return (void *)BOOT_TRAMPOLINE_BASE; +#else + return (void *)boot_handoff_trampoline; +#endif +} + +int32_t platform_restore_system(void) +{ + panic("not supported"); +} + +void platform_asynchronous_exception(void) +{ + ccc_handle_asynchronous_exception(); +} + +int32_t platform_get_boot_manifest_hash(uint8_t *boot_manifest_hash) +{ + RELEASE_ASSERT(boot_manifest_hash != NULL); + + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagObjectManifestHashValid) != 0) { + ((uint32_t *)boot_manifest_hash)[0] = rPMGR_SCRATCH16; + ((uint32_t *)boot_manifest_hash)[1] = rPMGR_SCRATCH17; + ((uint32_t *)boot_manifest_hash)[2] = rPMGR_SCRATCH18; + ((uint32_t *)boot_manifest_hash)[3] = rPMGR_SCRATCH19; + ((uint32_t *)boot_manifest_hash)[4] = rPMGR_SCRATCH20; + + return 0; + } + + return -1; +} + +int32_t platform_set_boot_manifest_hash(const uint8_t *boot_manifest_hash) +{ + if(boot_manifest_hash != NULL) { + rPMGR_SCRATCH16 = ((uint32_t *)boot_manifest_hash)[0]; + rPMGR_SCRATCH17 = ((uint32_t *)boot_manifest_hash)[1]; + rPMGR_SCRATCH18 = ((uint32_t *)boot_manifest_hash)[2]; + rPMGR_SCRATCH19 = ((uint32_t *)boot_manifest_hash)[3]; + rPMGR_SCRATCH20 = ((uint32_t *)boot_manifest_hash)[4]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagObjectManifestHashValid; + } + else { + rPMGR_SCRATCH16 = 0; + rPMGR_SCRATCH17 = 0; + rPMGR_SCRATCH18 = 0; + rPMGR_SCRATCH19 = 0; + rPMGR_SCRATCH20 = 0; + + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagObjectManifestHashValid; + } + + return 0; +} + +bool platform_get_mix_n_match_prevention_status(void) +{ + return ((rPMGR_SCRATCH0 & kPlatformScratchFlagVerifyManifestHash) ? true : false); +} + +void platform_set_mix_n_match_prevention_status(bool mix_n_match_prevented) +{ + if (mix_n_match_prevented) + rPMGR_SCRATCH0 |= kPlatformScratchFlagVerifyManifestHash; + else + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagVerifyManifestHash; +} + +void platform_set_consistent_debug_root_pointer(uint32_t root) +{ + rMINIPMGR_SCRATCH1 = root; +} + +int platform_convert_voltages(int buck, uint32_t count, uint32_t *voltages) +{ +#if SUPPORT_FPGA + uint32_t index; + for (index = 0; index < count; index++) + power_get_buck_value_fpga(buck, voltages[index], &voltages[index]); + return 0; +#elif WITH_HW_POWER + int rail; + uint32_t index; + + if (voltages == 0) return -1; + + if (0 != power_convert_buck_to_rail(buck, &rail)) + return -1; + + for (index = 0; index < count; index++) { + if (voltages[index] == 0) + continue; + + if (0 != power_get_rail_value(rail, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +int platform_get_cpu_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cnt); + } + + return 0; +} + +int platform_get_soc_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_soc_voltage(cnt); + } + + return 0; +} + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = PANIC_BASE; + break; + + case kMemoryRegion_StorageProcessor: + base = ASP_BASE; + break; + + case kMemoryRegion_SecureProcessor: + base = TZ0_BASE; + break; + + case kMemoryRegion_Monitor: + base = TZ1_BASE; + break; + + case kMemoryRegion_Kernel: + base = KERNEL_BASE; + break; + + case kMemoryRegion_PageTables: + base = PAGE_TABLES_BASE; + break; + + case kMemoryRegion_Heap: + base = HEAP_BASE; + break; + + case kMemoryRegion_Stacks: + base = STACKS_BASE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + base = CONSISTENT_DEBUG_BASE; + break; + + case kMemoryRegion_SleepToken: + base = SLEEP_TOKEN_BUFFER_BASE; + break; + + case kMemoryRegion_DramConfig: + base = DRAM_CONFIG_SEQ_BASE; + break; + + case kMemoryRegion_Display: + base = PANIC_BASE - platform_get_memory_region_size(kMemoryRegion_Display); + break; + + case kMemoryRegion_iBoot: + base = IBOOT_BASE; + break; + + case kMemoryRegion_AOP: + base = AOP_SRAM_BASE_ADDR; + break; + + case kMemoryRegion_Reconfig: + base = AOP_RECONFIG_REGION_BASE_ADDR; + break; +#endif + + default: + base = (uintptr_t)-1; + break; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + + case kMemoryRegion_StorageProcessor: + size = ASP_SIZE; + break; + + case kMemoryRegion_SecureProcessor: + size = TZ0_SIZE; + break; + + case kMemoryRegion_Monitor: + size = TZ1_SIZE; + break; + + case kMemoryRegion_Kernel: + size = platform_get_memory_region_base(kMemoryRegion_Display) - platform_get_memory_region_base(kMemoryRegion_Kernel); + break; + + case kMemoryRegion_PageTables: + size = PAGE_TABLES_SIZE; + break; + + case kMemoryRegion_Heap: + size = HEAP_SIZE; + break; + + case kMemoryRegion_Stacks: + size = STACKS_SIZE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + size = CONSISTENT_DEBUG_SIZE; + break; + + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; + + case kMemoryRegion_DramConfig: + size = DRAM_CONFIG_SEQ_SIZE; + break; + + case kMemoryRegion_Display: + size = platform_get_display_memory_size(); + ASSERT(size != 0); + break; + + case kMemoryRegion_iBoot: + size = IBOOT_SIZE; + break; + + case kMemoryRegion_AOP: + size = AOP_RECONFIG_REGION_BASE_ADDR - AOP_SRAM_BASE_ADDR; + break; + + case kMemoryRegion_Reconfig: + size = AOP_RECONFIG_REGION_SIZE; + break; +#endif + + default: + size = (size_t)-1; + break; + } + + return size; +} + +#if defined(WITH_MENU) && WITH_MENU + +int do_sleep_token_test(int argc, struct cmd_arg *args) +{ + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0; + + security_create_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90); + + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0x12345678; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0xaabbccdd; + dprintf(DEBUG_INFO, "original info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + if (security_validate_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90) == false) { + dprintf(DEBUG_INFO, "failed to validate token\n"); + return 0; + } + + dprintf(DEBUG_INFO, "saved info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + return 0; +} + +MENU_COMMAND_DEBUG(sleep_token, do_sleep_token_test, "sleep token test - creates and validate it", NULL); + +#endif + +int platform_get_cpu_ram_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_sram_voltage(cnt); + } + + return 0; +} + +int platform_get_gpu_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_gpu_voltage(cnt); + } + + return 0; +} + +int platform_get_gpu_ram_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_gpu_sram_voltage(cnt); + } + + return 0; +} + +int platform_get_ram_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_sram_voltage(cnt); + } + + return 0; +} + +/* + * Gets equivalent mV for a given DWI value for a particular buck. + * PMU code should handle the special case for GPU buck. + */ +int platform_get_dwi_to_mv(int buck, uint32_t dwival) +{ +#if SUPPORT_FPGA + return power_convert_dwi_to_mv_fpga(buck, dwival); +#elif WITH_HW_POWER + int rail; + + if (0 != power_convert_buck_to_rail(buck, &rail)) + return -1; + + return power_convert_dwi_to_mv(rail, dwival); +#else + return -1; +#endif +} + +static void platform_init_boot_strap(void) +{ + volatile uint32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID4, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID4, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + // Build the board ID and boot config using the new scheme. + gpio_board_id = + (gpio_read(GPIO_BOARD_ID4) << 4) | + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID4, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 5) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +#if WITH_BOOT_XNU +static int32_t platform_bootprep_darwin(void) +{ +#if WITH_PAINT + if (paint_color_map_is_invalid()) + panic("Previous DClr errors prevent OS booting"); +#endif + +#if PRODUCT_IBEC && defined(GPIO_S3E_BOOT_FROM_HOST) + gpio_write(GPIO_S3E_BOOT_FROM_HOST, 1); +#endif + + /* 1. Setup trustzones */ + + /* clean-invalidate TZ0 & TZ1 regions */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ0_BASE, TZ0_SIZE); + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ1_BASE, TZ1_SIZE); + + /* create sleep token */ + /* already created by load_kernelcache call */ + + /* program values */ + for (uint32_t i = 0; i < NUM_AMCCS; i++) { + + rMCCLOCKREGION_TZ0BASEADDR(i) = TZ0_BASE >> 12; + rMCCLOCKREGION_TZ0ENDADDR(i) = (TZ0_BASE + TZ0_SIZE - 1) >> 12; + rMCCLOCKREGION_TZ1BASEADDR(i) = TZ1_BASE >> 12; + rMCCLOCKREGION_TZ1ENDADDR(i) = (TZ1_BASE + TZ1_SIZE - 1) >> 12; + + /* lock TZ0 & TZ1 regions */ + rMCCLOCKREGION_TZ0LOCK(i) = (1 << 0); + if ((rMCCLOCKREGION_TZ0LOCK(i) & 1) == 0) { + panic("TZ0 failed to lock\n"); + } + rMCCLOCKREGION_TZ1LOCK(i) = (1 << 0); + if ((rMCCLOCKREGION_TZ1LOCK(i) & 1) == 0) { + panic("TZ1 failed to lock\n"); + } + } + + // Don't allow access to memcache as RAM from the kernel + dcs_lock_down_mcc(); + + /* 2. Override IO_RVBAR */ + ccc_override_and_lock_iorvbar(TZ1_BASE); + + // Insert Reconfig sequences + reconfig_init(BOOT_DARWIN); + platform_reconfig_sequence_insert(BOOT_DARWIN); + reconfig_lock(BOOT_DARWIN); + + return 0; +} +#endif + +static void platform_relocate_securerom(void) +{ +#if WITH_HW_MIU && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + size_t len; + + // Get the size of the downloaded SecureROM image + len = env_get_uint("filesize", 0); + if (len == 0) + panic("filesize variable invalid or not set, aborting\n"); + + // Move the SecureROM image into place + dprintf(DEBUG_INFO, "relocating 0x%lx byte SecureROM image from SDRAM to SRAM\n", len); + memcpy((void *)SRAM_BASE, (void *)SDRAM_BASE, len); +#endif +} + +uint32_t platform_get_pcie_l1ss_ltr_threshold(void) +{ + // Per Maui tunables spec r0.15 section 6.2 + return 70; +} + +uint32_t platform_get_pcie_l1ss_t_common_mode(void) +{ +#if SUB_PLATFORM_S8001 + // Per Elba tunables spec r0.39 section 6.2 + return 0; +#else + // Per Maui tunables spec r0.69 section 6.2 + return 25; +#endif +} + +static int power_convert_buck_to_rail(int buck, int *rail) +{ + if (!rail) + return -1; + + switch (buck) { +#if APPLICATION_IBOOT +#ifndef BUCK_CPU +#error BUCK_CPU not defined for this platform +#endif + +#ifndef BUCK_CPU_RAM +#error BUCK_CPU_RAM not defined for this platform +#endif + +#ifndef BUCK_SOC +#error BUCK_SOC not defined for this platform +#endif + +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + +#ifndef BUCK_GPU_RAM +#error BUCK_GPU_RAM not defined for this platform +#endif + + case BUCK_CPU: + *rail = POWER_RAIL_CPU; + break; + case BUCK_CPU_RAM: + *rail = POWER_RAIL_CPU_RAM; + break; + case BUCK_SOC: + *rail = POWER_RAIL_SOC; + break; + case BUCK_GPU: + *rail = POWER_RAIL_GPU; + break; + case BUCK_GPU_RAM: + *rail = POWER_RAIL_GPU_RAM; + break; +#endif + default: + return -1; + } + + return 0; +} + +#if SUPPORT_FPGA +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val) +{ + if (mv == 0) { + *val = 0; + } else { + switch(buck) { +#if APPLICATION_IBOOT + case BUCK_CPU: + case BUCK_GPU: + *val = (((mv-500)*1000)+3124)/3125; + break; +#endif + + default: + *val = (((mv-600)*1000)+3124)/3125; + break; + } + } + return; +} + +static int power_convert_dwi_to_mv_fpga(unsigned int buck, uint32_t dwival) +{ + int val = 0; +#if APPLICATION_IBOOT + if (buck == BUCK_GPU) { + val = (dwival == 0) ? 0 : (500000 + (3125 * dwival))/1000; + } +#endif + return val; +} +#endif + +#if WITH_TARGET_CONFIG + +// The target's rules.mk sets the high SoC voltage point +#ifndef TARGET_BOOT_SOC_VOLTAGE +#error TARGET_BOOT_SOC_VOLTAGE not defined by the target +#endif + +uint32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} + +// The target's rules.mk sets the high CPU voltage point +#ifndef TARGET_BOOT_CPU_VOLTAGE +#error TARGET_BOOT_CPU_VOLTAGE not defined by the target +#endif + +uint32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_BOOT_CPU_VOLTAGE); +} + +// The target's rules.mk sets the high RAM voltage point +#ifndef TARGET_BOOT_RAM_VOLTAGE +#error TARGET_BOOT_RAM_VOLTAGE not defined by the target +#endif + +uint32_t platform_get_base_ram_voltage(void) +{ + return chipid_get_sram_voltage(TARGET_BOOT_RAM_VOLTAGE); +} + +#endif + +#if defined(WITH_MENU) && WITH_MENU + +static int get_total_leakage(int argc, struct cmd_arg *args) +{ + dprintf(DEBUG_INFO, "total leakage: %dmA\n", chipid_get_total_rails_leakage()); + return 0; +} +MENU_COMMAND_DEBUG(leakage, get_total_leakage, "total rails leakage read from fuse", NULL); +#endif diff --git a/platform/s8000/miu/miu.c b/platform/s8000/miu/miu.c new file mode 100644 index 0000000..a08609f --- /dev/null +++ b/platform/s8000/miu/miu.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_DEVICETREE +#if SUPPORT_FPGA + +struct bridge_list_t { + char *bridge_settings; + uint32_t fpga_enable_mask; +}; + +#define BRIDGE(b, m) { "bridge-settings-" #b, (m) } + +// ALERT: The ordering effects the device tree entries under pmgr node's reg dictionary. +// It also affects the bridge id used in the pmgr device-clock nodes. The +// bridge id must match the id on the device tree bridge-settings- properties. +// NOTE: The second parameter on the BRIDGE macro is used to dynamically determine +// which bridge settings properties should exist based upon the hardware +// blocks actually present on the device. + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +static const struct bridge_list_t bridge_list[] = { + BRIDGE(0, FPGA_HAS_MEDIA), // Media Bus Mux + BRIDGE(1, FPGA_HAS_MSR), // MSR_AXI2AF + BRIDGE(2, FPGA_HAS_JPEG), // AJPEG_AXI2AF + BRIDGE(3, FPGA_HAS_AVE), // AVE_AXI2AF + BRIDGE(4, FPGA_HAS_VXD), // VDEC0_AXI2AF + BRIDGE(5, FPGA_HAS_ISP), // ISP_DMA_AXI2AF + ISAP_KF_AXI2AF + BRIDGE(6, (FPGA_HAS_DISP)), // DISPBusMux + BRIDGE(7, FPGA_HAS_DISP), // Disp0 + BRIDGE(8, FPGA_HAS_GFX), // GFX + BRIDGE(9, FPGA_HAS_GFX), // GFX_AFUSER + BRIDGE(10, FPGA_HAS_ALWAYS), // USB + BRIDGE(11, FPGA_HAS_ALWAYS), // PCIe +}; + +#elif SUB_PLATFORM_S8001 +static const struct bridge_list_t bridge_list[] = { + BRIDGE(0, FPGA_HAS_MEDIA), // Media Bus Mux + BRIDGE(1, FPGA_HAS_MSR), // MSR_AXI2AF + BRIDGE(2, FPGA_HAS_JPEG), // AJPEG_AXI2AF + BRIDGE(3, FPGA_HAS_AVE), // AVE_AXI2AF + BRIDGE(4, FPGA_HAS_VXD), // VDEC0_AXI2AF + BRIDGE(5, FPGA_HAS_ISP), // ISP_DMA_AXI2AF + ISAP_KF_AXI2AF + BRIDGE(6, FPGA_HAS_DISP), // RTBusMux + BRIDGE(7, FPGA_HAS_DISP), // Disp0 + BRIDGE(8, FPGA_HAS_DISP), // Disp1 + BRIDGE(9, FPGA_HAS_DISP), // Disp1BusMux + BRIDGE(10, FPGA_HAS_GFX), // GFX + BRIDGE(11, FPGA_HAS_GFX), // GFX_AFUSER + BRIDGE(12, FPGA_HAS_ALWAYS), // USB + BRIDGE(13, FPGA_HAS_ALWAYS), // PCIe +}; +#endif + +#endif // SUPPORT_FPGA +#endif // WITH_DEVICETREE + +extern void ausb_setup_widgets(); + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif + ausb_setup_widgets(); + + return 0; +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT && WITH_HW_DCS + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rSECUREROMCTRL_ROMADDRREMAP = (rSECUREROMCTRL_ROMADDRREMAP & ~3) | (1 << 0); + break; + + case REMAP_SDRAM: + rSECUREROMCTRL_ROMADDRREMAP = (rSECUREROMCTRL_ROMADDRREMAP & ~3) | (2 << 0); + break; + } +} + +void miu_bypass_prep(void) +{ +} + +#if WITH_DEVICETREE + +#define DEBUG_BRIDGE DEBUG_SPEW // Debug level for bridge messages + +void miu_update_device_tree(DTNode *pmgr_node) +{ +#if SUPPORT_FPGA + DTNode *node; + char *propName; + void *propData; + uint32_t propSize; + uint32_t fpga_blocks = chipid_get_fpga_block_instantiation(); + uint32_t i; + + dprintf(DEBUG_INFO, "chipid_get_fpga_block_instantiation() = 0x%08X\n", + fpga_blocks); + + if (FindNode(0, "arm-io/pmgr", &node)) { + + // For each bridge... + for (i = 0; i < ARRAY_SIZE(bridge_list); i++) { + + // Filter out if not supported by FPGA + if (!(fpga_blocks & bridge_list[i].fpga_enable_mask)) { + + propName = bridge_list[i].bridge_settings; + + if (FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_CRITICAL, "Eliding %s\n", propName); + propName[0] = '~'; + } + } + } + } +#endif // SUPPORT_FPGA +} + +#endif // WITH_DEVICETREE diff --git a/platform/s8000/miu/rules.mk b/platform/s8000/miu/rules.mk new file mode 100644 index 0000000..a412699 --- /dev/null +++ b/platform/s8000/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/s8000/pmgr/pmgr.c b/platform/s8000/pmgr/pmgr.c new file mode 100644 index 0000000..86b20a4 --- /dev/null +++ b/platform/s8000/pmgr/pmgr.c @@ -0,0 +1,4462 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void arm_no_wfe_spin(uint32_t usecs); +extern const struct tunable_chip_struct tunables_pmgr[]; +extern const struct tunable_chip_struct tunables_pmgr_product[]; + +struct clock_config_active { + uint32_t clk; + uint32_t clock_reg_val; +}; + +struct clock_source { + uint32_t src_clk; + uint32_t factor; +}; + +#define CLOCK_SOURCES_MAX 12 + +struct clock_config { + volatile uint32_t *clock_reg; // CLKCFG Register + struct clock_source sources[CLOCK_SOURCES_MAX]; // List of sources +}; + +struct device_config { + volatile uint32_t *ps_reg; // PS Register +}; + +struct dvfm_data +{ + uint32_t dvfm_state_vmax; + uint32_t dvfm_state_iboot_cnt; + uint32_t dvfm_state_vnom; + uint32_t dvfm_state_vboost; + uint32_t voltage_states1_count; + uint32_t voltage_states1_size; +}; + +#define PLL_FREQ_TARGET(pllx) (((pllx##_O) * (pllx##_M)) / (pllx##_P) / ((pllx##_S) + (pllx != PLL_PCIE ? 1 : (pllx##_S)))) + +#if APPLICATION_SECUREROM +static uint32_t active_state = kDVFM_STATE_SECUREROM; +#endif + +#if APPLICATION_IBOOT +static uint32_t active_state = kDVFM_STATE_IBOOT; +#endif + +#if APPLICATION_SECUREROM +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_SECUREROM +#endif + +#if APPLICATION_IBOOT +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_VMIN +#endif + +struct pmgr_soc_perf_state_src_sel { + uint16_t clk_index; + uint8_t shift; + uint8_t entry; + uint32_t mask; +}; + +struct pmgr_soc_perf_state_src_sel pmgr_soc_perf_state_src_sels[] = { +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + {PMGR_CLK_VENC, PMGR_SOC_PERF_STATE_ENTRY_0A_VENC_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_VENC_SRC_SEL_UMASK}, + {PMGR_CLK_VDEC, PMGR_SOC_PERF_STATE_ENTRY_0A_VDEC_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_VDEC_SRC_SEL_UMASK}, + {PMGR_CLK_ISP, PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_SRC_SEL_UMASK}, + {PMGR_CLK_ISP_C, PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_C_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_C_SRC_SEL_UMASK}, + {PMGR_CLK_SBR, PMGR_SOC_PERF_STATE_ENTRY_0A_SBR_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_SBR_SRC_SEL_UMASK}, + {PMGR_CLK_AF, PMGR_SOC_PERF_STATE_ENTRY_0A_AF_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_AF_SRC_SEL_UMASK}, + {PMGR_CLK_MCU_REF, PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_UMASK}, + {PMGR_CLK_PMP, PMGR_SOC_PERF_STATE_ENTRY_0B_PMP_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_PMP_SRC_SEL_UMASK}, + {PMGR_CLK_DISP0, PMGR_SOC_PERF_STATE_ENTRY_0B_DISP0_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_DISP0_SRC_SEL_UMASK}, + {PMGR_CLK_VID0, PMGR_SOC_PERF_STATE_ENTRY_0B_VID0_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_VID0_SRC_SEL_UMASK}, + {PMGR_CLK_SIO_C, PMGR_SOC_PERF_STATE_ENTRY_0B_SIO_C_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_SIO_C_SRC_SEL_UMASK}, + {PMGR_CLK_GFX_FENDER, PMGR_SOC_PERF_STATE_ENTRY_0B_GFX_FENDER_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_GFX_FENDER_SRC_SEL_UMASK}, + {PMGR_CLK_MSR, PMGR_SOC_PERF_STATE_ENTRY_0B_MSR_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_MSR_SRC_SEL_UMASK}, + {PMGR_CLK_AJPEG_WRAP, PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_WRAP_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_WRAP_SRC_SEL_UMASK}, + {PMGR_CLK_AJPEG_IP, PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_IP_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_IP_SRC_SEL_UMASK}, + {PMGR_CLK_SEP, PMGR_SOC_PERF_STATE_ENTRY_0C_SEP_SRC_SEL_SHIFT, 'C', PMGR_SOC_PERF_STATE_ENTRY_0C_SEP_SRC_SEL_UMASK}, +#elif SUB_PLATFORM_S8001 + {PMGR_CLK_VENC, PMGR_SOC_PERF_STATE_ENTRY_0A_VENC_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_VENC_SRC_SEL_UMASK}, + {PMGR_CLK_VDEC, PMGR_SOC_PERF_STATE_ENTRY_0A_VDEC_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_VDEC_SRC_SEL_UMASK}, + {PMGR_CLK_ISP, PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_SRC_SEL_UMASK}, + {PMGR_CLK_ISP_C, PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_C_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_ISP_C_SRC_SEL_UMASK}, + {PMGR_CLK_SBR, PMGR_SOC_PERF_STATE_ENTRY_0A_SBR_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_SBR_SRC_SEL_UMASK}, + {PMGR_CLK_AF, PMGR_SOC_PERF_STATE_ENTRY_0A_AF_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_AF_SRC_SEL_UMASK}, + {PMGR_CLK_MCU_REF, PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_SHIFT, 'A', PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_UMASK}, + {PMGR_CLK_PMP, PMGR_SOC_PERF_STATE_ENTRY_0B_PMP_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_PMP_SRC_SEL_UMASK}, + {PMGR_CLK_DISP0, PMGR_SOC_PERF_STATE_ENTRY_0B_DISP0_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_DISP0_SRC_SEL_UMASK}, + {PMGR_CLK_SIO_C, PMGR_SOC_PERF_STATE_ENTRY_0B_SIO_C_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_SIO_C_SRC_SEL_UMASK}, + {PMGR_CLK_GFX_FENDER, PMGR_SOC_PERF_STATE_ENTRY_0B_GFX_FENDER_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_GFX_FENDER_SRC_SEL_UMASK}, + {PMGR_CLK_MSR, PMGR_SOC_PERF_STATE_ENTRY_0B_MSR_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_MSR_SRC_SEL_UMASK}, + {PMGR_CLK_AJPEG_WRAP, PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_WRAP_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_WRAP_SRC_SEL_UMASK}, + {PMGR_CLK_AJPEG_IP, PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_IP_SRC_SEL_SHIFT, 'B', PMGR_SOC_PERF_STATE_ENTRY_0B_AJPEG_IP_SRC_SEL_UMASK}, + {PMGR_CLK_SRS, PMGR_SOC_PERF_STATE_ENTRY_0C_SRS_SRC_SEL_SHIFT, 'C', PMGR_SOC_PERF_STATE_ENTRY_0C_SRS_SRC_SEL_UMASK}, + {PMGR_CLK_DISP1, PMGR_SOC_PERF_STATE_ENTRY_0C_DISP1_SRC_SEL_SHIFT, 'C', PMGR_SOC_PERF_STATE_ENTRY_0C_DISP1_SRC_SEL_UMASK}, + {PMGR_CLK_SEP, PMGR_SOC_PERF_STATE_ENTRY_0C_SEP_SRC_SEL_SHIFT, 'C', PMGR_SOC_PERF_STATE_ENTRY_0C_SEP_SRC_SEL_UMASK}, +#endif +}; + +struct pmgr_soc_perf_state { + uint32_t entry[4]; +}; + +static struct pmgr_soc_perf_state pmgr_soc_perf_states[] = { + [kSOC_PERF_STATE_BYPASS] = { + {0x00000000, + 0x00000000, + 0x00000000, + 0x00000000}}, + +#if APPLICATION_SECUREROM + [kSOC_PERF_STATE_SECUREROM] = { + { +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + // SBR = 266.66 / 2 + // AF = 360 / 2 + 0x00008800, + // PMP = 200 / 2 + // SIO_C = 400 / 2 + 0x60070000, + +#elif SUB_PLATFORM_S8001 + // SBR = 400 / 2 + // AF = 600 / 2 + 0x00005500, + // PMP = 200 / 2 + // SIO_C = 600 / 2 + 0x60050000, +#endif + + // SEP = 480 / 2 + 0x00000005, + 0x00000000}}, +#endif + +#if APPLICATION_IBOOT +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + [kSOC_PERF_STATE_VMIN] = { + // VENC = 360 + // VDEC = 266.66 + // ISP = 320 + // ISP_C = 533.33 + // SBR = 266.66 + // AF = 360 + // MCU_REF_CLK: Have to use bucket 3 and 50 MHz until dcs_init initializes SPLL, otherwise leads to a hang waiting for handshake + // MCU_REF_CFG = 0x3 + // MCU_REF_CLK = 50 + {0x88878838, + + // PMP = 200 + // DISP0 = 360 + // VID0 = TARGET_VID0_SRC_SEL / 100MHz + // SIO_C = 400 + // GFX_FENDER = 360 + // MSR = 320 + // AJPEG_WRAP = 266.66 + // AJPEG_IP = 200 +#if TARGET_VID0_SRC_SEL + 0x67078878 | PMGR_SOC_PERF_STATE_ENTRY_VID0(TARGET_VID0_SRC_SEL), +#else + 0x67A78878, +#endif + + // BIU div low + // SEP = 480 + 0x00000005, + 0x00000000}}, + + [kSOC_PERF_STATE_VNOM] = { + // VENC = 533.33 + // VDEC = 400 + // ISP = 457.14 + // ISP_C = 800 + // SBR = 400 + // AF = 533.33 + // MCU_REF_CFG = 0x0 + // MCU_REF_CLK = 100 + {0x55555507, + + // PMP = 200 + // DISP0 = 480 + // VID0 = TARGET_VID0_SRC_SEL / 100MHz + // SIO_C = 533.33 + // GFX_FENDER = 533.33 + // MSR = 480 + // AJPEG_WRAP = 360 + // AJPEG_IP = 288 +#if TARGET_VID0_SRC_SEL + 0x65055555 | PMGR_SOC_PERF_STATE_ENTRY_VID0(TARGET_VID0_SRC_SEL), +#else + 0x65A55555, +#endif + + // BIU div high + // SEP = 480 + 0x00000015, + 0x00000000}}, +#elif SUB_PLATFORM_S8001 + [kSOC_PERF_STATE_VMIN] = { + // VENC = 533.33 + // VDEC = 400 + // ISP = 457.14 + // ISP_C = 800 + // SBR = 400 + // AF = 600 + // MCU_REF_CLK: Have to use bucket 3 and 50 MHz until dcs_init initializes SPLL, otherwise leads to a hang waiting for handshake + // MCU_REF_CFG = 0x3 + // MCU_REF_CLK = 50 + {0x55555538, + + // PMP = 200 + // DISP0 = 533.33 + // SIO_C = 600 + // GFX_FENDER = 600 + // MSR = 480 + // AJPEG_WRAP = 360 + // AJPEG_IP = 288 + 0x65055555, + + // BIU div high + // SRS = 666 + // SEP = 480 + // DISP1 = 533.33 + 0x00001555, + 0x00000000}}, + // Same as kSOC_PERF_STATE_VMIN + [kSOC_PERF_STATE_VNOM] = { + {0x00000000, + 0x00000000, + 0x00000000, + 0x00000000}}, +#endif +#endif +}; + +#if APPLICATION_SECUREROM +static uint32_t perf_level = kPerformanceHigh; +#endif + +#if APPLICATION_IBOOT +static uint32_t perf_level = kPerformanceMemoryMid; +#endif + +#if APPLICATION_IBOOT + +#if SUB_PLATFORM_S8000 +/* LPO @192MHz */ +#define LPO_T LPO_FREQ + +/* PLL0 @1600MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 200 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @1440MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 60 +#define PLL1_S 0 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +/* PLL2 @1200MHz */ +#define PLL2 2 +#ifndef PLL2_T +#define PLL2_O OSC_FREQ +#define PLL2_P 1 +#define PLL2_M 50 +#define PLL2_S 0 +#define PLL2_T PLL_FREQ_TARGET(PLL2) +#endif + +/* PLL3 @99MHz */ +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 1 +#define PLL3_M 66 +#define PLL3_S 15 +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +/* PLL_PCIE 6 @100MHz */ +#define PLL_PCIE 6 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 200 +#define PLL_PCIE_S 24 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + +#elif SUB_PLATFORM_S8001 + +// Values defined in: +// https://seg-docs.ecs.apple.com/projects/elba//release/specs/Apple/PLL/asg_socpll_spec.pdf + +/* LPO @192MHz */ +#define LPO_T LPO_FREQ + +/* PLL0 @1600MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 200 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @1440MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 60 +#define PLL1_S 0 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +/* PLL2 @1200MHz */ +#define PLL2 2 +#ifndef PLL2_T +#define PLL2_O OSC_FREQ +#define PLL2_P 1 +#define PLL2_M 50 +#define PLL2_S 0 +#define PLL2_T PLL_FREQ_TARGET(PLL2) +#endif + +/* PLL3 @132.33MHz */ +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 6 +#define PLL3_M 397 +#define PLL3_S 11 +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +/* PLL6 @600Mhz */ +#define PLL6 6 +#define PLL6_O OSC_FREQ +#define PLL6_P 1 +#define PLL6_M 50 +#define PLL6_S 1 +#define PLL6_T PLL_FREQ_TARGET(PLL6) + +/* PLL7 @666Mhz */ +#define PLL7 7 +#define PLL7_O OSC_FREQ +#define PLL7_P 2 +#define PLL7_M 111 +#define PLL7_S 1 +#define PLL7_T PLL_FREQ_TARGET(PLL7) + +/* PLL_PCIE (8) @100MHz */ +/* Taken from PMGR_PLL_PCIE_CTL default */ +#define PLL_PCIE 8 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 125 +#define PLL_PCIE_S 29 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + +#elif SUB_PLATFORM_S8003 + +/* LPO @192MHz */ +#define LPO_T LPO_FREQ + +/* PLL0 @1600MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 200 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @1440MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 60 +#define PLL1_S 0 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +/* PLL2 @1200MHz */ +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 1 +#define PLL2_M 50 +#define PLL2_S 0 +#define PLL2_T PLL_FREQ_TARGET(PLL2) + +/* PLL3 @99MHz */ +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 1 +#define PLL3_M 66 +#define PLL3_S 15 +#define PLL3_T PLL_FREQ_TARGET(PLL3) + +/* PLL_PCIE (6) @100MHz */ +#define PLL_PCIE 6 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 125 +#define PLL_PCIE_S 29 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + +#else +#error "Unknown SUB_PLATFORM" +#endif + +#ifndef TARGET_SPARE0_CLK_CFG +#define TARGET_SPARE0_CLK_CFG 0x00000000 +#endif + +#ifndef TARGET_VID0_CLK_CFG +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +#define TARGET_VID0_CLK_CFG 0x88100000 +#elif SUB_PLATFORM_S8001 +#define TARGET_VID0_CLK_CFG 0x86100000 +#endif +#endif + +static const struct clock_config_active clk_configs_active[] = { + // Mini-PMGR clocks: + {PMGR_CLK_AOP, 0x81100000}, // 192 (LPO) + {PMGR_CLK_UART0, 0x84100000}, // 24 (LPO) + {PMGR_CLK_UART1, 0x84100000}, // 24 (LPO) + {PMGR_CLK_UART2, 0x84100000}, // 24 (LPO) + {PMGR_CLK_AOP_MCA0_M, 0x83100000}, // 24 (LPO) + {PMGR_CLK_I2CM, 0x83100000}, // 24 (LPO) + {PMGR_CLK_PROXY_FABRIC, 0x82100000}, // 96 (LPO) + {PMGR_CLK_PROXY_MCU_REF, 0x81100000}, // 48 (LPO) + + // Spares: + {PMGR_CLK_S0, TARGET_SPARE0_CLK_CFG}, // TARGET_SPARE0_CLK_CFG + {PMGR_CLK_S1, 0x00000000}, // 0 + {PMGR_CLK_S2, 0x00000000}, // 0 + {PMGR_CLK_S3, 0x00000000}, // 0 + {PMGR_CLK_ISP_REF0, 0x81000006}, // 48 + {PMGR_CLK_ISP_REF1, 0x81000006}, // 48 + + // PMGR clocks: +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + {PMGR_CLK_GFX_FENDER, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_MCU_REF, 0x87100000}, // SOC_PERF_STATE + {PMGR_CLK_PMP, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_TEMP_MIPI_DSI, 0x86100000}, // PLL2 + {PMGR_CLK_NCO_REF0, 0x85100000}, // 800 + {PMGR_CLK_NCO_REF1, 0x85100000}, // 800 + {PMGR_CLK_NCO_ALG0, 0x80100000}, // 24 + {PMGR_CLK_NCO_ALG1, 0x88100000}, // 100 + {PMGR_CLK_HSICPHY_REF_12M, 0x85100000}, // 12 + {PMGR_CLK_USB480_0, 0x85100000}, // 480 + {PMGR_CLK_USB480_1, 0x85100000}, // 480 + {PMGR_CLK_USB_OHCI_48M, 0x85100000}, // 48 + {PMGR_CLK_USB, 0x85100000}, // 120 + {PMGR_CLK_USB_FREE_60M, 0x85100000}, // 60 + {PMGR_CLK_SIO_C, 0x87100000}, // SOC_PERF_STATE + {PMGR_CLK_SIO_P, 0x80100000}, // 24 + {PMGR_CLK_ISP_C, 0x87100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP_SENSOR0_REF, 0x81100000}, // ISP_REF0 + {PMGR_CLK_ISP_SENSOR1_REF, 0x82100000}, // ISP_REF1 + {PMGR_CLK_VDEC, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_VENC, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_VID0, TARGET_VID0_CLK_CFG}, // SOC_PERF_STATE + {PMGR_CLK_DISP0, 0x87100000}, // SOC_PERF_STATE + {PMGR_CLK_AJPEG_IP, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_AJPEG_WRAP, 0x87100000}, // SOC_PERF_STATE + {PMGR_CLK_MSR, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_AF, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_SBR, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_MCA0_M, 0x85100000}, // NCO0 + {PMGR_CLK_MCA1_M, 0x86100000}, // NCO1 + {PMGR_CLK_MCA2_M, 0x87100000}, // NCO2 + {PMGR_CLK_MCA3_M, 0x88100000}, // NCO3 + {PMGR_CLK_MCA4_M, 0x89100000}, // NCO4 + {PMGR_CLK_SEP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_GPIO, 0x85100000}, // 50 + {PMGR_CLK_SPI0_N, 0x85100000}, // 61.54 + {PMGR_CLK_SPI1_N, 0x85100000}, // 61.54 + {PMGR_CLK_SPI2_N, 0x85100000}, // 61.54 + {PMGR_CLK_SPI3_N, 0x85100000}, // 61.54 + {PMGR_CLK_PCIE_APP, 0x87100000}, // 266.66 + {PMGR_CLK_TMPS, 0x85100000}, // 1.2 + {PMGR_CLK_UVD, 0x86100000}, // 533.33 +#elif SUB_PLATFORM_S8001 + {PMGR_CLK_GFX_FENDER, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_MCU_REF, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_PMP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_NCO_REF0, 0x85100000}, // 800 + {PMGR_CLK_NCO_REF1, 0x85100000}, // 800 + {PMGR_CLK_NCO_ALG0, 0x80100000}, // 24 + {PMGR_CLK_NCO_ALG1, 0x88100000}, // 100 + {PMGR_CLK_HSICPHY_REF_12M, 0x85100000}, // 12 + {PMGR_CLK_USB480_0, 0x85100000}, // 480 + {PMGR_CLK_USB_OHCI_48M, 0x85100000}, // 48 + {PMGR_CLK_USB, 0x88100000}, // 48 + {PMGR_CLK_USB_FREE_60M, 0x85100000}, // 60 + {PMGR_CLK_SIO_C, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_SIO_P, 0x80100000}, // 24 + {PMGR_CLK_ISP_C, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP_SENSOR0_REF, 0x81100000}, // ISP_REF0 + {PMGR_CLK_ISP_SENSOR1_REF, 0x82100000}, // ISP_REF1 + {PMGR_CLK_VDEC, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_VENC, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_VID0, TARGET_VID0_CLK_CFG}, // SOC_PERF_STATE + {PMGR_CLK_DISP0, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_AJPEG_IP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_AJPEG_WRAP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_MSR, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_AF, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_SBR, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_MCA0_M, 0x85100000}, // NCO0 + {PMGR_CLK_MCA1_M, 0x86100000}, // NCO1 + {PMGR_CLK_MCA2_M, 0x87100000}, // NCO2 + {PMGR_CLK_MCA3_M, 0x88100000}, // NCO3 + {PMGR_CLK_MCA4_M, 0x89100000}, // NCO4 + {PMGR_CLK_SEP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_GPIO, 0x85100000}, // 50 + {PMGR_CLK_SPI0_N, 0x85100000}, // 61.54 + {PMGR_CLK_SPI1_N, 0x85100000}, // 61.54 + {PMGR_CLK_SPI2_N, 0x85100000}, // 61.54 + {PMGR_CLK_SPI3_N, 0x85100000}, // 61.54 + {PMGR_CLK_PCIE_APP, 0x85100000}, // 266.66 + {PMGR_CLK_TMPS, 0x85100000}, // 1.2 + {PMGR_CLK_UVD, 0x85100000}, // 600 + {PMGR_CLK_VID1, 0x86101000}, // 600 + {PMGR_CLK_DISP1, 0x85100000}, // 533.33 + {PMGR_CLK_SRS, 0x85100000}, // 666 +#endif +}; + +static void set_gfx_perf_state(uint32_t state_num, enum chipid_voltage_index voltage_index); +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_SECUREROM + +#if SUB_PLATFORM_S8000 + +/* PLL0 @800MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 100 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @720MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 180 +#define PLL1_S 1 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +/* PLL_PCIE (6) @100MHz */ +#define PLL_PCIE 6 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 200 +#define PLL_PCIE_S 24 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + +#elif SUB_PLATFORM_S8001 + +// Values defined in: +// https://seg-docs.ecs.apple.com/projects/elba//release/specs/Apple/PLL/asg_socpll_spec.pdf + +/* PLL0 @800MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 100 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @720MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 60 +#define PLL1_S 1 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +/* PLL6 @300Mhz */ +#define PLL6 6 +#define PLL6_O OSC_FREQ +#define PLL6_P 1 +#define PLL6_M 50 +#define PLL6_S 3 +#define PLL6_T PLL_FREQ_TARGET(PLL6) + +/* PLL_PCIE (8) @100MHz */ +/* Taken from PMGR_PLL_PCIE_CTL default */ +#define PLL_PCIE 8 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 125 +#define PLL_PCIE_S 29 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + +#elif SUB_PLATFORM_S8003 + +/* PLL0 @800MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 100 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @720MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 60 +#define PLL1_S 1 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +/* PLL_PCIE (6) @100MHz */ +#define PLL_PCIE 6 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 125 +#define PLL_PCIE_S 29 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + +#endif + +static const struct clock_config_active clk_configs_active[] = { + // Mini-PMGR clocks: + + // Spares: + + // PMGR clocks: +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + {PMGR_CLK_USB, 0x86100000}, // 100 / 2 + {PMGR_CLK_SIO_C, 0x87100000}, // SOC_PERF_STATE + {PMGR_CLK_SIO_P, 0x85100000}, // 120 / 2 + {PMGR_CLK_AF, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_SBR, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_SEP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_GPIO, 0x85100000}, // 50 / 2 + {PMGR_CLK_PCIE_APP, 0x87100000}, // 266.66 / 2 +#elif SUB_PLATFORM_S8001 + {PMGR_CLK_USB, 0x86100000}, // 100 / 2 + {PMGR_CLK_SIO_C, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_SIO_P, 0x86100000}, // 120 / 2 + {PMGR_CLK_AF, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_SBR, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_SEP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_GPIO, 0x85100000}, // 50 / 2 + {PMGR_CLK_PCIE_APP, 0x85100000}, // 266.66 / 2 +#endif +}; + +#endif /* APPLICATION_SECUREROM */ + +static const struct clock_config clk_configs[PMGR_CLK_COUNT] = { +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + [PMGR_CLK_GFX_FENDER] = { + &rPMGR_CLK_CFG(GFX_FENDER), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 8 } + } + }, + + [PMGR_CLK_MCU_REF] = { + &rPMGR_CLK_CFG(MCU_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL3, 1 }, + { PMGR_CLK_PLL0, 12 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_PROXY_MCU_REF, 1 } + } + }, + + [PMGR_CLK_PMP] = { + &rPMGR_CLK_CFG(PMP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PROXY_FABRIC, 1 } + } + }, + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + [PMGR_CLK_TEMP_MIPI_DSI] = { + &rPMGR_CLK_CFG(TEMP_MIPI_DSI), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL0, 2 } + } + }, +#endif + + [PMGR_CLK_NCO_REF0] = { + &rPMGR_CLK_CFG(NCO_REF0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 4 } + } + }, + + [PMGR_CLK_NCO_REF1] = { + &rPMGR_CLK_CFG(NCO_REF1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 4 } + } + }, + + [PMGR_CLK_NCO_ALG0] = { + &rPMGR_CLK_CFG(NCO_ALG0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL1, 30 } + } + }, + + [PMGR_CLK_NCO_ALG1] = { + &rPMGR_CLK_CFG(NCO_ALG1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL1, 30 } + } + }, + + [PMGR_CLK_HSICPHY_REF_12M] = { + &rPMGR_CLK_CFG(HSICPHY_REF_12M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 2 } + } + }, + + [PMGR_CLK_USB480_0] = { + &rPMGR_CLK_CFG(USB480_0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 } + } + }, + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + [PMGR_CLK_USB480_1] = { + &rPMGR_CLK_CFG(USB480_1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 } + } + }, +#endif + + [PMGR_CLK_USB_OHCI_48M] = { + &rPMGR_CLK_CFG(USB_OHCI_48M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 30 } + } + }, + + [PMGR_CLK_USB] = { + &rPMGR_CLK_CFG(USB), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 12 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL1, 30 }, + { PMGR_CLK_PLL0, 48 }, + { PMGR_CLK_PLL1, 48 } + } + }, + + [PMGR_CLK_USB_FREE_60M] = { + &rPMGR_CLK_CFG(USB_FREE_60M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 24 } + } + }, + + [PMGR_CLK_SIO_C] = { + &rPMGR_CLK_CFG(SIO_C), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 32 } + } + }, + + [PMGR_CLK_SIO_P] = { + &rPMGR_CLK_CFG(SIO_P), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 12 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 20 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_ISP_C] = { + &rPMGR_CLK_CFG(ISP_C), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 } + } + }, + + [PMGR_CLK_ISP] = { + &rPMGR_CLK_CFG(ISP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, // 3.5 + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 } + } + }, + + [PMGR_CLK_ISP_SENSOR0_REF] = { + &rPMGR_CLK_CFG(ISP_SENSOR0_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 } + } + }, + + [PMGR_CLK_ISP_SENSOR1_REF] = { + &rPMGR_CLK_CFG(ISP_SENSOR1_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 } + } + }, + + [PMGR_CLK_VDEC] = { + &rPMGR_CLK_CFG(VDEC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 } + } + }, + + [PMGR_CLK_VENC] = { + &rPMGR_CLK_CFG(VENC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 } + } + }, + + [PMGR_CLK_VID0] = { + &rPMGR_CLK_CFG(VID0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL1, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 26 }, + } + }, + + [PMGR_CLK_DISP0] = { + &rPMGR_CLK_CFG(DISP0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 9 } + } + }, + + [PMGR_CLK_AJPEG_IP] = { + &rPMGR_CLK_CFG(AJPEG_IP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 9 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 } + } + }, + + [PMGR_CLK_AJPEG_WRAP] = { + &rPMGR_CLK_CFG(AJPEG_WRAP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 9 } + } + }, + + [PMGR_CLK_MSR] = { + &rPMGR_CLK_CFG(MSR), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 } + } + }, + + [PMGR_CLK_AF] = { + &rPMGR_CLK_CFG(AF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PROXY_FABRIC, 1 } + } + }, + + [PMGR_CLK_SBR] = { + &rPMGR_CLK_CFG(SBR), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PROXY_FABRIC, 1 } + } + }, + + [PMGR_CLK_MCA0_M] = { + &rPMGR_CLK_CFG(MCA0_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA1_M] = { + &rPMGR_CLK_CFG(MCA1_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA2_M] = { + &rPMGR_CLK_CFG(MCA2_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA3_M] = { + &rPMGR_CLK_CFG(MCA3_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA4_M] = { + &rPMGR_CLK_CFG(MCA4_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_SEP] = { + &rPMGR_CLK_CFG(SEP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 16 } + } + }, + + [PMGR_CLK_GPIO] = { + &rPMGR_CLK_CFG(GPIO), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_PLL1, 30 }, + { PMGR_CLK_OSC, 1 } + } + }, + + [PMGR_CLK_SPI0_N] = { + &rPMGR_CLK_CFG(SPI0_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 } + } + }, + + [PMGR_CLK_SPI1_N] = { + &rPMGR_CLK_CFG(SPI1_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 } + } + }, + + [PMGR_CLK_SPI2_N] = { + &rPMGR_CLK_CFG(SPI2_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 } + } + }, + + [PMGR_CLK_SPI3_N] = { + &rPMGR_CLK_CFG(SPI3_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 } + } + }, + + [PMGR_CLK_PCIE_APP] = { + &rPMGR_CLK_CFG(PCIE_APP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 16 } + } + }, + + [PMGR_CLK_TMPS] = { + &rPMGR_CLK_CFG(TMPS), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 20 }, + } + }, + + [PMGR_CLK_UVD] = { + &rPMGR_CLK_CFG(UVD), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 3 }, + } + }, + [PMGR_CLK_S0] = { + &rPMGR_CLK_CFG(S0), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_S1] = { + &rPMGR_CLK_CFG(S1), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_S2] = { + &rPMGR_CLK_CFG(S2), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_S3] = { + &rPMGR_CLK_CFG(S3), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_ISP_REF0] = { + &rPMGR_CLK_CFG(ISP_REF0), + { + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 } + } + }, + + [PMGR_CLK_ISP_REF1] = { + &rPMGR_CLK_CFG(ISP_REF1), + { + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 } + } + }, +#elif SUB_PLATFORM_S8001 + [PMGR_CLK_GFX_FENDER] = { + &rPMGR_CLK_CFG(GFX_FENDER), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_MCU_REF] = { + &rPMGR_CLK_CFG(MCU_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL3, 1 }, + { PMGR_CLK_PLL0, 12 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_PROXY_MCU_REF, 1 }, + } + }, + [PMGR_CLK_PMP] = { + &rPMGR_CLK_CFG(PMP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PROXY_FABRIC, 1 }, + } + }, + [PMGR_CLK_NCO_REF0] = { + &rPMGR_CLK_CFG(NCO_REF0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 4 }, + } + }, + [PMGR_CLK_NCO_REF1] = { + &rPMGR_CLK_CFG(NCO_REF1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 4 }, + } + }, + [PMGR_CLK_NCO_ALG0] = { + &rPMGR_CLK_CFG(NCO_ALG0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL1, 30 }, + } + }, + [PMGR_CLK_NCO_ALG1] = { + &rPMGR_CLK_CFG(NCO_ALG1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL1, 30 }, + } + }, + [PMGR_CLK_HSICPHY_REF_12M] = { + &rPMGR_CLK_CFG(HSICPHY_REF_12M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 2 }, + } + }, + [PMGR_CLK_USB480_0] = { + &rPMGR_CLK_CFG(USB480_0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + } + }, + [PMGR_CLK_USB_OHCI_48M] = { + &rPMGR_CLK_CFG(USB_OHCI_48M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 30 }, + } + }, + [PMGR_CLK_USB] = { + &rPMGR_CLK_CFG(USB), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 12 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL1, 30 }, + { PMGR_CLK_PLL0, 48 }, + { PMGR_CLK_PLL1, 48 }, + } + }, + [PMGR_CLK_USB_FREE_60M] = { + &rPMGR_CLK_CFG(USB_FREE_60M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 24 }, + } + }, + [PMGR_CLK_SIO_C] = { + &rPMGR_CLK_CFG(SIO_C), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_SIO_P] = { + &rPMGR_CLK_CFG(SIO_P), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL1, 12 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 20 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_OSC, 2 }, + } + }, + [PMGR_CLK_ISP_C] = { + &rPMGR_CLK_CFG(ISP_C), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + } + }, + [PMGR_CLK_ISP] = { + &rPMGR_CLK_CFG(ISP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_ISP_SENSOR0_REF] = { + &rPMGR_CLK_CFG(ISP_SENSOR0_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 }, + } + }, + [PMGR_CLK_ISP_SENSOR1_REF] = { + &rPMGR_CLK_CFG(ISP_SENSOR1_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 }, + } + }, + [PMGR_CLK_VDEC] = { + &rPMGR_CLK_CFG(VDEC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + } + }, + [PMGR_CLK_VENC] = { + &rPMGR_CLK_CFG(VENC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_VID0] = { + &rPMGR_CLK_CFG(VID0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 7 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_DISP0] = { + &rPMGR_CLK_CFG(DISP0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_AJPEG_IP] = { + &rPMGR_CLK_CFG(AJPEG_IP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 9 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + } + }, + [PMGR_CLK_AJPEG_WRAP] = { + &rPMGR_CLK_CFG(AJPEG_WRAP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 9 }, + } + }, + [PMGR_CLK_MSR] = { + &rPMGR_CLK_CFG(MSR), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + } + }, + [PMGR_CLK_AF] = { + &rPMGR_CLK_CFG(AF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PROXY_FABRIC, 1 }, + } + }, + [PMGR_CLK_SBR] = { + &rPMGR_CLK_CFG(SBR), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PROXY_FABRIC, 1 }, + } + }, + [PMGR_CLK_MCA0_M] = { + &rPMGR_CLK_CFG(MCA0_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA1_M] = { + &rPMGR_CLK_CFG(MCA1_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA2_M] = { + &rPMGR_CLK_CFG(MCA2_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA3_M] = { + &rPMGR_CLK_CFG(MCA3_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA4_M] = { + &rPMGR_CLK_CFG(MCA4_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_SEP] = { + &rPMGR_CLK_CFG(SEP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 16 }, + } + }, + [PMGR_CLK_GPIO] = { + &rPMGR_CLK_CFG(GPIO), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_PLL1, 30 }, + { PMGR_CLK_OSC, 1 }, + } + }, + [PMGR_CLK_SPI0_N] = { + &rPMGR_CLK_CFG(SPI0_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_SPI1_N] = { + &rPMGR_CLK_CFG(SPI1_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_SPI2_N] = { + &rPMGR_CLK_CFG(SPI2_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_SPI3_N] = { + &rPMGR_CLK_CFG(SPI3_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_PCIE_APP] = { + &rPMGR_CLK_CFG(PCIE_APP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 16 }, + } + }, + [PMGR_CLK_TMPS] = { + &rPMGR_CLK_CFG(TMPS), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 20 }, + } + }, + [PMGR_CLK_UVD] = { + &rPMGR_CLK_CFG(UVD), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 3 }, + } + }, + [PMGR_CLK_VID1] = { + &rPMGR_CLK_CFG(VID1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL1, 6 }, + { PMGR_CLK_PLL0, 7 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_DISP1] = { + &rPMGR_CLK_CFG(DISP1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_SRS] = { + &rPMGR_CLK_CFG(SRS), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL7, 1 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL0, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_S0] = { + &rPMGR_CLK_CFG(S0), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_S1] = { + &rPMGR_CLK_CFG(S1), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_S2] = { + &rPMGR_CLK_CFG(S2), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL6, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_S3] = { + &rPMGR_CLK_CFG(S3), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL7, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_ISP_REF0] = { + &rPMGR_CLK_CFG(ISP_REF0), + { + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + } + }, + [PMGR_CLK_ISP_REF1] = { + &rPMGR_CLK_CFG(ISP_REF1), + { + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL1, 5 }, + { PMGR_CLK_PLL0, 6 }, + { PMGR_CLK_PLL1, 6 }, + } + }, +#endif + [PMGR_CLK_AOP] = { + &rMINIPMGR_CLK_CFG(AOP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + + [PMGR_CLK_UART0] = { + &rMINIPMGR_CLK_CFG(UART0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + + [PMGR_CLK_UART1] = { + &rMINIPMGR_CLK_CFG(UART1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + + [PMGR_CLK_UART2] = { + &rMINIPMGR_CLK_CFG(UART2), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + + [PMGR_CLK_AOP_MCA0_M] = { + &rMINIPMGR_CLK_CFG(AOP_MCA0_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 1 } + } + }, + + [PMGR_CLK_I2CM] = { + &rMINIPMGR_CLK_CFG(I2CM), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 1 } + } + }, + + [PMGR_CLK_PROXY_FABRIC] = { + &rMINIPMGR_CLK_CFG(PROXY_FABRIC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + + [PMGR_CLK_PROXY_MCU_REF] = { + &rMINIPMGR_CLK_CFG(PROXY_MCU_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 } + } + }, +}; + +static const struct device_config device_configs[PMGR_DEVICE_COUNT] = { + // Mini PMGR + [PMGR_DEVICE_INDEX(CLK_AOP)] = {&rMINIPMGR_PS(AOP)}, + [PMGR_DEVICE_INDEX(CLK_DEBUG)] = {&rMINIPMGR_PS(DEBUG)}, + [PMGR_DEVICE_INDEX(CLK_AOP_GPIO)] = {&rMINIPMGR_PS(AOP_GPIO)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART0)] = {&rMINIPMGR_PS(AOP_UART0)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART1)] = {&rMINIPMGR_PS(AOP_UART1)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART2)] = {&rMINIPMGR_PS(AOP_UART2)}, + [PMGR_DEVICE_INDEX(CLK_AOP_I2CM)] = {&rMINIPMGR_PS(AOP_I2CM)}, + [PMGR_DEVICE_INDEX(CLK_AOP_MCA0)] = {&rMINIPMGR_PS(AOP_MCA0)}, + [PMGR_DEVICE_INDEX(CLK_AOP_CPU)] = {&rMINIPMGR_PS(AOP_CPU)}, + [PMGR_DEVICE_INDEX(CLK_AOP_FILTER)] = {&rMINIPMGR_PS(AOP_FILTER)}, + [PMGR_DEVICE_INDEX(CLK_AOP_BUSIF)] = {&rMINIPMGR_PS(AOP_BUSIF)}, + // PMGR + [PMGR_DEVICE_INDEX(CLK_SBR)] = {&rPMGR_PS(SBR)}, + [PMGR_DEVICE_INDEX(CLK_AIC)] = {&rPMGR_PS(AIC)}, + [PMGR_DEVICE_INDEX(CLK_DWI)] = {&rPMGR_PS(DWI)}, + [PMGR_DEVICE_INDEX(CLK_GPIO)] = {&rPMGR_PS(GPIO)}, + [PMGR_DEVICE_INDEX(CLK_PMS)] = {&rPMGR_PS(PMS)}, + [PMGR_DEVICE_INDEX(CLK_HSIC0PHY)] = {&rPMGR_PS(HSIC0PHY)}, +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + [PMGR_DEVICE_INDEX(CLK_HSIC1PHY)] = {&rPMGR_PS(HSIC1PHY)}, +#endif + [PMGR_DEVICE_INDEX(CLK_ISPSENS0)] = {&rPMGR_PS(ISPSENS0)}, + [PMGR_DEVICE_INDEX(CLK_ISPSENS1)] = {&rPMGR_PS(ISPSENS1)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_REF)] = {&rPMGR_PS(PCIE_REF)}, + [PMGR_DEVICE_INDEX(CLK_SIO_BUSIF)] = {&rPMGR_PS(SIO_BUSIF)}, + [PMGR_DEVICE_INDEX(CLK_SIO_P)] = {&rPMGR_PS(SIO_P)}, + [PMGR_DEVICE_INDEX(CLK_SIO)] = {&rPMGR_PS(SIO)}, + [PMGR_DEVICE_INDEX(CLK_MCA0)] = {&rPMGR_PS(MCA0)}, + [PMGR_DEVICE_INDEX(CLK_MCA1)] = {&rPMGR_PS(MCA1)}, + [PMGR_DEVICE_INDEX(CLK_MCA2)] = {&rPMGR_PS(MCA2)}, + [PMGR_DEVICE_INDEX(CLK_MCA3)] = {&rPMGR_PS(MCA3)}, + [PMGR_DEVICE_INDEX(CLK_MCA4)] = {&rPMGR_PS(MCA4)}, + [PMGR_DEVICE_INDEX(CLK_PWM0)] = {&rPMGR_PS(PWM0)}, + [PMGR_DEVICE_INDEX(CLK_I2C0)] = {&rPMGR_PS(I2C0)}, + [PMGR_DEVICE_INDEX(CLK_I2C1)] = {&rPMGR_PS(I2C1)}, + [PMGR_DEVICE_INDEX(CLK_I2C2)] = {&rPMGR_PS(I2C2)}, + [PMGR_DEVICE_INDEX(CLK_I2C3)] = {&rPMGR_PS(I2C3)}, + [PMGR_DEVICE_INDEX(CLK_SPI0)] = {&rPMGR_PS(SPI0)}, + [PMGR_DEVICE_INDEX(CLK_SPI1)] = {&rPMGR_PS(SPI1)}, + [PMGR_DEVICE_INDEX(CLK_SPI2)] = {&rPMGR_PS(SPI2)}, + [PMGR_DEVICE_INDEX(CLK_SPI3)] = {&rPMGR_PS(SPI3)}, + [PMGR_DEVICE_INDEX(CLK_UART0)] = {&rPMGR_PS(UART0)}, + [PMGR_DEVICE_INDEX(CLK_UART1)] = {&rPMGR_PS(UART1)}, + [PMGR_DEVICE_INDEX(CLK_UART2)] = {&rPMGR_PS(UART2)}, + [PMGR_DEVICE_INDEX(CLK_UART3)] = {&rPMGR_PS(UART3)}, + [PMGR_DEVICE_INDEX(CLK_UART4)] = {&rPMGR_PS(UART4)}, + [PMGR_DEVICE_INDEX(CLK_UART5)] = {&rPMGR_PS(UART5)}, + [PMGR_DEVICE_INDEX(CLK_UART6)] = {&rPMGR_PS(UART6)}, + [PMGR_DEVICE_INDEX(CLK_UART7)] = {&rPMGR_PS(UART7)}, + [PMGR_DEVICE_INDEX(CLK_UART8)] = {&rPMGR_PS(UART8)}, + [PMGR_DEVICE_INDEX(CLK_AES0)] = {&rPMGR_PS(AES0)}, +#if SUB_PLATFORM_S8001 + [PMGR_DEVICE_INDEX(CLK_DPA0)] = {&rPMGR_PS(DPA0)}, + [PMGR_DEVICE_INDEX(CLK_DPA1)] = {&rPMGR_PS(DPA1)}, +#endif + [PMGR_DEVICE_INDEX(CLK_MCC)] = {&rPMGR_PS(MCC)}, + [PMGR_DEVICE_INDEX(CLK_DCS0)] = {&rPMGR_PS(DCS0)}, + [PMGR_DEVICE_INDEX(CLK_DCS1)] = {&rPMGR_PS(DCS1)}, + [PMGR_DEVICE_INDEX(CLK_DCS2)] = {&rPMGR_PS(DCS2)}, + [PMGR_DEVICE_INDEX(CLK_DCS3)] = {&rPMGR_PS(DCS3)}, +#if SUB_PLATFORM_S8001 + [PMGR_DEVICE_INDEX(CLK_DCS4)] = {&rPMGR_PS(DCS4)}, + [PMGR_DEVICE_INDEX(CLK_DCS5)] = {&rPMGR_PS(DCS5)}, + [PMGR_DEVICE_INDEX(CLK_DCS6)] = {&rPMGR_PS(DCS6)}, + [PMGR_DEVICE_INDEX(CLK_DCS7)] = {&rPMGR_PS(DCS7)}, +#endif + [PMGR_DEVICE_INDEX(CLK_USB)] = {&rPMGR_PS(USB)}, + [PMGR_DEVICE_INDEX(CLK_USBCTLREG)] = {&rPMGR_PS(USBCTLREG)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST0)] = {&rPMGR_PS(USB2HOST0)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST0_OHCI)] = {&rPMGR_PS(USB2HOST0_OHCI)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST1)] = {&rPMGR_PS(USB2HOST1)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST1_OHCI)] = {&rPMGR_PS(USB2HOST1_OHCI)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST2)] = {&rPMGR_PS(USB2HOST2)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST2_OHCI)] = {&rPMGR_PS(USB2HOST2_OHCI)}, + [PMGR_DEVICE_INDEX(CLK_USB_OTG)] = {&rPMGR_PS(USB_OTG)}, + [PMGR_DEVICE_INDEX(CLK_SMX)] = {&rPMGR_PS(SMX)}, + [PMGR_DEVICE_INDEX(CLK_SF)] = {&rPMGR_PS(SF)}, + [PMGR_DEVICE_INDEX(CLK_RTMUX)] = {&rPMGR_PS(RTMUX)}, + [PMGR_DEVICE_INDEX(CLK_DISP0)] = {&rPMGR_PS(DISP0)}, +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + [PMGR_DEVICE_INDEX(CLK_MIPI_DSI)] = {&rPMGR_PS(MIPI_DSI)}, + [PMGR_DEVICE_INDEX(CLK_DP)] = {&rPMGR_PS(DP)}, +#endif +#if SUB_PLATFORM_S8001 + [PMGR_DEVICE_INDEX(CLK_DP0)] = {&rPMGR_PS(DP0)}, + [PMGR_DEVICE_INDEX(CLK_DISP1MUX)] = {&rPMGR_PS(DISP1MUX)}, + [PMGR_DEVICE_INDEX(CLK_DISP1)] = {&rPMGR_PS(DISP1)}, + [PMGR_DEVICE_INDEX(CLK_DP1)] = {&rPMGR_PS(DP1)}, +#endif + [PMGR_DEVICE_INDEX(CLK_ISP)] = {&rPMGR_PS(ISP)}, + [PMGR_DEVICE_INDEX(CLK_MEDIA)] = {&rPMGR_PS(MEDIA)}, + [PMGR_DEVICE_INDEX(CLK_JPG)] = {&rPMGR_PS(JPG)}, + [PMGR_DEVICE_INDEX(CLK_MSR)] = {&rPMGR_PS(MSR)}, + [PMGR_DEVICE_INDEX(CLK_PMP)] = {&rPMGR_PS(PMP)}, + [PMGR_DEVICE_INDEX(CLK_PMS_SRAM)] = {&rPMGR_PS(PMS_SRAM)}, + [PMGR_DEVICE_INDEX(CLK_VDEC0)] = {&rPMGR_PS(VDEC0)}, + [PMGR_DEVICE_INDEX(CLK_VENC_CPU)] = {&rPMGR_PS(VENC_CPU)}, + [PMGR_DEVICE_INDEX(CLK_PCIE)] = {&rPMGR_PS(PCIE)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_AUX)] = {&rPMGR_PS(PCIE_AUX)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_LINK0)] = {&rPMGR_PS(PCIE_LINK0)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_LINK1)] = {&rPMGR_PS(PCIE_LINK1)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_LINK2)] = {&rPMGR_PS(PCIE_LINK2)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_LINK3)] = {&rPMGR_PS(PCIE_LINK3)}, +#if SUB_PLATFORM_S8001 + [PMGR_DEVICE_INDEX(CLK_PCIE_LINK4)] = {&rPMGR_PS(PCIE_LINK4)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_LINK5)] = {&rPMGR_PS(PCIE_LINK5)}, +#endif + [PMGR_DEVICE_INDEX(CLK_GFX)] = {&rPMGR_PS(GFX)}, +#if SUB_PLATFORM_S8001 + [PMGR_DEVICE_INDEX(CLK_SRS)] = {&rPMGR_PS(SRS)}, +#endif + // Unmanaged + [PMGR_DEVICE_INDEX(CLK_CPU0)] = {&rPMGR_PS(CPU0)}, + [PMGR_DEVICE_INDEX(CLK_CPU1)] = {&rPMGR_PS(CPU1)}, + [PMGR_DEVICE_INDEX(CLK_CPM)] = {&rPMGR_PS(CPM)}, + [PMGR_DEVICE_INDEX(CLK_SEP)] = {&rPMGR_PS(SEP)}, + [PMGR_DEVICE_INDEX(CLK_VENC_PIPE)] = {&rPMGR_PS(VENC_PIPE)}, + [PMGR_DEVICE_INDEX(CLK_VENC_ME0)] = {&rPMGR_PS(VENC_ME0)}, + [PMGR_DEVICE_INDEX(CLK_VENC_ME1)] = {&rPMGR_PS(VENC_ME1)}, +}; + +static void config_apsc_acc_state(uint32_t state, enum chipid_voltage_index voltage_index, bool securerom); +static uint32_t get_apsc_acc_state(void); +static void set_apsc_acc_state(uint32_t target_state); +static void enable_cpu_pll_reset(bool enable); +static void config_soc_perf_state(uint32_t state, enum chipid_voltage_index voltage_index); +static void set_soc_perf_state(uint32_t target_state); +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static void init_thermal_registers(void); +#endif +static void clocks_get_frequencies(void); +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk); +static uint32_t get_pll(int32_t pll); +static uint32_t get_pll_cpu(void); +static void set_lpo(void); +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s); +static uint32_t get_spare(int32_t spare); +static void clocks_set_gates(uint64_t *devices); +static void clocks_quiesce_internal(void); +static void power_on_sep(void); + +bool pmgr_platform_set_perf_state(bool gpu, uint32_t state_num, uint32_t *voltage_indexes, uint32_t voltage_index_size) +{ + uint32_t index = 0; + uint32_t max; + uint32_t min; + if (gpu) { + max = kPMGR_GFX_STATE_MAX - 1; + min = 1; + } else { + max = kDVFM_STATE_MAX_CNT - 1; + min = 3; + } + + while (index < voltage_index_size) { + if (pmgr_platform_get_freq(gpu, voltage_indexes[index]) == 0) { + return false; // wrong voltage index; + } + if ((state_num + index < min) || (state_num + index > max)) { + return false; + } + if (gpu) { + set_gfx_perf_state(state_num + index, voltage_indexes[index]); + } else { + config_apsc_acc_state(state_num + index, voltage_indexes[index], false); + } + index++; + } + + while (state_num + index <= max) { + // Always fill following gpu/cpu with default values + if (gpu) { + set_gfx_perf_state(state_num + index, CHIPID_GPU_VOLTAGE_OFF); + } else { + config_apsc_acc_state(state_num + index, CHIPID_CPU_VOLTAGE_396, false); + } + index++; + } + return true; +} + +uint32_t pmgr_platform_get_freq(bool gpu, uint32_t voltage_index) +{ + if (gpu) { + const struct operating_point_params *params = operating_point_get_params(voltage_index, CHIPID_GPU_VOLTAGE); + if (params == NULL) { + return 0; + } + if (params->preDivP == 0) { + return 0; + } + return 24 * params->fbkDivM / params->preDivP / (1 + params->pstDivS); + } else { + const struct operating_point_params *params = operating_point_get_params(voltage_index, CHIPID_CPU_VOLTAGE); + if (params == NULL) { + return 0; + } + return 24 * params->fbkDivM / params->preDivP / (1 + params->pstDivS); + } +} + +bool pmgr_platform_get_perf_state(enum pmgr_binning_type_t type, uint32_t state, uint32_t *voltage, uint32_t *freq) +{ + switch (type) { + case PMGR_BINNING_CPU: + case PMGR_BINNING_CPU_SRAM: + if (state >= kDVFM_STATE_MAX_CNT) { + return false; + } + break; + case PMGR_BINNING_GPU: + case PMGR_BINNING_GPU_SRAM: + if (state >= kPMGR_GFX_STATE_MAX) { + return false; + } + break; + case PMGR_BINNING_SOC: + if (state >= kSOC_PERF_STATE_MAX_CNT) { + return false; + } + break; + default: + return false; + } + switch (type) { + case PMGR_BINNING_CPU: { + uint64_t state_entry = rACC_DVFM_ST(state); + *freq = OSC_FREQ; + *freq *= ((state_entry >> 4) & 0x1FF); + *freq /= ((state_entry >> 13) & 0x1F) ? ((state_entry >> 13) & 0x1F) : 1; + *freq /= (1 + ((state_entry >> 0) & 0xF)); + *voltage = platform_get_dwi_to_mv(BUCK_CPU, ACC_PWRCTL_DVFM_ST0_SAFE_VOL_XTRCT(rACC_DVFM_ST(state))); + break; + } + case PMGR_BINNING_CPU_SRAM: + *freq = 0; + *voltage = platform_get_dwi_to_mv(BUCK_CPU_RAM, ACC_PWRCTL_DVFM_ST0_EXT_SRAM_VOL_XTRCT(rACC_DVFM_ST_EXT(state))); + break; + case PMGR_BINNING_GPU: { + uint32_t state_val = rPMGR_GFX_PERF_STATE_ENTRY_A(state); + *freq = PMGR_PLL_FREQ((state_val >> 12) & 0x1FF, (state_val >> 4) & 0x1F, state_val & 0xF); + *voltage = platform_get_dwi_to_mv(BUCK_GPU, PMGR_GFX_PERF_STATE_ENTRY0A_VOLTAGE_XTRCT(rPMGR_GFX_PERF_STATE_ENTRY_A(state))); + break; + } + case PMGR_BINNING_GPU_SRAM: + *freq = 0; + *voltage = platform_get_dwi_to_mv(BUCK_GPU_RAM, PMGR_GFX_PERF_STATE_ENTRY0B_SRAM_VOLTAGE_XTRCT(rPMGR_GFX_PERF_STATE_ENTRY_B(state))); + break; + case PMGR_BINNING_SOC: + *freq = 0; + *voltage = platform_get_dwi_to_mv(BUCK_SOC, PMGR_SOC_PERF_STATE_ENTRY_0C_VOLTAGE_XTRCT(rPMGR_SOC_PERF_STATE_ENTRY_C(state))); + break; + default: + return false; + } + return true; +} + +// current clock frequencies +static uint32_t clks[PMGR_CLK_COUNT]; + +void platform_power_spin(uint32_t usecs) +{ + arm_no_wfe_spin(usecs); +} + +void pmgr_platform_config_uvwarn(void) +{ + uint32_t i, voltage, freq; + uint32_t prev_voltage = 0, overdrive_voltage = 0, arm_threshold = 0; + + for (i = 1; i < kPMGR_GFX_STATE_MAX; i++) { + pmgr_platform_get_perf_state(PMGR_BINNING_GPU, i, &voltage, &freq); + + if (freq == 0) + break; + + prev_voltage = overdrive_voltage; + overdrive_voltage = voltage; + } + + // Check voltages in mV + if (overdrive_voltage == 0 || prev_voltage == 0) + panic("Invalid binning or operating points for UV-WARN"); + + platform_convert_voltages(BUCK_GPU, 1, &prev_voltage); + platform_convert_voltages(BUCK_GPU, 1, &overdrive_voltage); + arm_threshold = overdrive_voltage - 1; + arm_threshold = platform_get_dwi_to_mv(BUCK_GPU, arm_threshold); + + // Check voltages in voltage code + if (overdrive_voltage <= prev_voltage) + panic("Invalid binning for UV-WARN"); + + // Arm threshold is 1 voltage code below overdrive voltage + pmu_uvwarn_config(0, arm_threshold); +} + +int clocks_init(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) + clocks_get_frequencies(); +#endif + + return 0; +} + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +static void set_nco_clocks(void) +{ + uint32_t i; + + // Enable this NCO with alg_ref0_clk and nco_ref0_clk. + // Note: clk_configs assumes all NCOs use nco_ref0_clk + for (i = 0; i < PMGR_NUM_NCO; i++) { + rPMGR_NCO_CLK_CFG(i) |= PMGR_NCO_CLK_CFG_ENABLE; + } +} +#endif + + +static void apply_tunables_clkcfg(uint32_t first, uint32_t last) +{ + uint32_t j; + + // Set the clocks + for (j = first; j < last; j++) { + uint64_t reg = (uint64_t)clk_configs[j].clock_reg; + if (reg == 0) { + continue; + } + if (reg >= AOP_MINIPMGR_BASE_ADDR) { + continue; // Don't touch MINIPMGR clock + } + reconfig_command_write(AOP_DDR_AWAKE_POST, reg, *((uint32_t *)reg), false); + reconfig_command_read(AOP_DDR_AWAKE_POST, reg, 0, PMGR_CLK_CFG_PENDING, 255, false); + } +} + +// apply_tunables(false) is idempotent: it doesn't write to a register if a register contains the right tunable +static void apply_tunables(bool reconfig) +{ + uint32_t i, j; + const struct tunable_chip_struct (*tunables)[]; +#if WITH_HW_RECONFIG + if (reconfig) { + volatile uint64_t *reg = (volatile uint64_t *)(PMGR_BASE_ADDR + PMGR_PWRGATE_CPM_CFG0_OFFSET); + reconfig_command_write(AOP_DDR_AWAKE_POST, + (uint64_t)reg, + *reg & ~PMGR_PWRGATE_CPM_CFG0_PWR_DOM_EN_UMASK, + 0); + } +#endif + + for (j = 0; j < 2; j++) { + if (j < 1) + tunables = &tunables_pmgr; + else + tunables = &tunables_pmgr_product; + + for (i = 0; ((*tunables)[i].tunable != NULL) || ((*tunables)[i].tunable64 != NULL); i++) { + void *tunable_base = (void *)(*tunables)[i].base_address; + uint32_t tunable_index; + + if ((*tunables)[i].chip_rev != chipid_get_chip_revision()) { + continue; + } + + if ((reconfig) && (!(*tunables)[i].reconfig)) { + continue; + } + + for (tunable_index = 0; 1 ; tunable_index++) { + uint32_t tunable_size; + uint32_t tunable_offset; + uint64_t tunable_mask; + uint64_t tunable_value; + + if ((*tunables)[i].tunable) { + tunable_size = (*tunables)[i].tunable[tunable_index].size; + tunable_offset = (*tunables)[i].tunable[tunable_index].offset; + tunable_mask = (*tunables)[i].tunable[tunable_index].mask; + tunable_value = (*tunables)[i].tunable[tunable_index].value; + } else { + tunable_size = (*tunables)[i].tunable64[tunable_index].size; + tunable_offset = (*tunables)[i].tunable64[tunable_index].offset; + tunable_mask = (*tunables)[i].tunable64[tunable_index].mask; + tunable_value = (*tunables)[i].tunable64[tunable_index].value; + } + if (tunable_offset == UINT32_MAX) { + break; + } + + uint32_t register_size = tunable_size * 8; + if ((tunable_base + tunable_offset == (void *)AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG_OFFSET) + || (tunable_base + tunable_offset == (void *)AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_XI0MUX_CLK_CFG_OFFSET) + || (tunable_base + tunable_offset == (void *)AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET)) { + // Done in the kernel driver + continue; + } + + if (tunable_base + tunable_offset == (void *)PMGR_BASE_ADDR + PMGR_MISC_CFG_ACG_OFFSET) { + // Will be done in the Kernel driver + continue; + } + + if ((tunable_base + tunable_offset >= (void *)PMGR_BASE_ADDR + PMGR_CLKCFG_OFFSET) && + (tunable_base + tunable_offset <= (void *)PMGR_BASE_ADDR + PMGR_CLKCTL_OFFSET)) { + // For CLKCFG tunables are interleaved with the clock mesh. + // Since, we don't have a read-modify-write, we let the CLKCFG reconfig restore the Clockmesh + // and the tunables at same time. + if (reconfig) { + continue; + } + } + + if ((tunable_base + tunable_offset < (void *)(ACC_BASE_ADDR + ACC_PWRCTL_OFFSET)) + && (tunable_base + tunable_offset >= (void *)(ACC_BASE_ADDR))) { + // We let xnu taking care of CPUi_IMPL_HID*, since setting ACC_cpui_IMPL_HID4 would prevent + // the end of LLB/iBSS which require set/way ops. Also, CPUi for i > 0 are off and so CPUi_IMPL_HID* + // are not accessible, but it would not be a problem here since synchronous error are masked in LLB/iBSS. + continue; + } + if ((tunable_base + tunable_offset >= (void *)(ACC_BASE_ADDR + ACC_IMPL_OFFSET)) + && (tunable_base + tunable_offset < (void *)(ACC_BASE_ADDR + ACC_CNTCTL_OFFSET))) { + // ACC_IMPL_* are lost after a cluster power gating. Let's xnu taking care of them. + continue; + } + + uint64_t val; + if (register_size == 64) { + val = *((volatile uint64_t *)(tunable_base + tunable_offset)); + } else { + val = *((volatile uint32_t *)(tunable_base + tunable_offset)); + } + + // Hack for Maui MCC EMA setting change to 3% + if (tunable_base + tunable_offset == (void *)(PMGR_BASE_ADDR + PMGR_EMA_FIXED_SOC1_OFFSET)) { + if (chipid_get_fuse_revision() >= 0x7) { + continue; + } + } + + if (!reconfig) { + if ((val & tunable_mask) == tunable_value) { + // Tunable already applied. No need to apply it again + continue; + } + + val &= ~tunable_mask; + val |= tunable_value; + if (register_size == 64) { + *((volatile uint64_t *)(tunable_base + tunable_offset)) = val; + } else { + *((volatile uint32_t *)(tunable_base + tunable_offset)) = (uint32_t)val; + } + } else { + #if WITH_HW_RECONFIG + reconfig_command_write(AOP_DDR_AWAKE_POST, + (uint64_t)(tunable_base + tunable_offset), + val, + register_size == 64); + #endif + } + } + } + } +} + +static void pmgr_reconfig_pll(void) +{ +#if WITH_HW_RECONFIG + uint32_t value; + { + uint32_t pll; + for (pll = 0; pll < PMGR_PLL_COUNT; pll++) { + if (pll == PLL_PCIE) { + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_PLL_ANA_PARAMS2(pll), rPMGR_PLL_ANA_PARAMS2(pll), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_PLL_ANA_PARAMS3(pll), rPMGR_PLL_ANA_PARAMS3(pll), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_PLL_PCIE_DELAY_CTL0(pll), rPMGR_PLL_PCIE_DELAY_CTL0(pll), false); + } + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_PLL_CTL(pll), rPMGR_PLL_CTL(pll), false); + reconfig_command_read(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_PLL_CTL(pll), 0, PMGR_PLL_PENDING, 0, false); // Infinite wait + + if (pll == PLL_PCIE) { + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_MISC_PCIE_PCIE_CTL, rPMGR_MISC_PCIE_PCIE_CTL, false); + } + } + } + + // Restore SOC STATE 0, with same state than clocks_set_performance(kPerformanceMemoryLow); + value = rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)); + value &= ~PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_UMASK; +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + value |= PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_INSRT(1); // we keep the SRC_SEL, but move to bucket 1 +#elif SUB_PLATFORM_S8001 + value |= PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_INSRT(0); // we keep the SRC_SEL, but move to bucket 0 +#else +#error "Unknown platform" +#endif + + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_A(0), value, false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_B(0), rPMGR_SOC_PERF_STATE_ENTRY_B(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_C(0), rPMGR_SOC_PERF_STATE_ENTRY_C(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_D(0), rPMGR_SOC_PERF_STATE_ENTRY_D(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)), false); + + // Switch SOC to 0 and wait for the transition + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_CTL, 0, false); + reconfig_command_read(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_CTL, 0, PMGR_SOC_PERF_STATE_CTL_PENDING_MASK, 0, false); + +#endif +} + +static void pmgr_reconfig_post(void) +{ +#if WITH_HW_RECONFIG + { + uint32_t i; + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_VOLMAN_BUCK_MAP, rPMGR_VOLMAN_BUCK_MAP, false); + + // Leakage and energy accumulator configuration + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_NRG_ACC_SCALE_TAB, rACC_NRG_ACC_SCALE_TAB, true); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_NRG_ACC_SCALE_TAB_EXT, rACC_NRG_ACC_SCALE_TAB_EXT, true); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_LKG_EST_TAB, rACC_LKG_EST_TAB, true); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_LKG_EST_TAB_EXT, rACC_LKG_EST_TAB_EXT, true); + + // In the end, DVFM/SOC/GFX states are only tunables! + + // Do not change ACC state 0, it's current state and it is different than the one we had in iBoot! + for (i = 1; i < kDVFM_STATE_MAX_CNT; i++) { + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_DVFM_ST(i), rACC_DVFM_ST(i), true); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_DVFM_ST_EXT(i), rACC_DVFM_ST_EXT(i), true); + } + + // We can change state 0, because GPU is OFF. + for (i = 0; i < kPMGR_GFX_STATE_MAX; i++) { + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_GFX_PERF_STATE_ENTRY_A(i), rPMGR_GFX_PERF_STATE_ENTRY_A(i), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_GFX_PERF_STATE_ENTRY_B(i), rPMGR_GFX_PERF_STATE_ENTRY_B(i), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_GFX_PERF_STATE_ENTRY_C(i), rPMGR_GFX_PERF_STATE_ENTRY_C(i), false); + } + // Do not change SOC state 0, it's current state and it is different than the one we had in iBoot! + for (i = 1; i < kSOC_PERF_STATE_MAX_CNT; i++) { + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_A(i), rPMGR_SOC_PERF_STATE_ENTRY_A(i), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_B(i), rPMGR_SOC_PERF_STATE_ENTRY_B(i), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_C(i), rPMGR_SOC_PERF_STATE_ENTRY_C(i), false); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_ENTRY_D(i), rPMGR_SOC_PERF_STATE_ENTRY_D(i), false); + } + + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_MSTR_PLLCTL, rACC_MSTR_PLLCTL & ~ACC_PWRCTL_MSTR_PLLCTL_SRC_SEL_UMASK, false); + reconfig_command_read(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_MSTR_PLLCTL, 0, ACC_PWRCTL_MSTR_PLLCTL_SRC_SEL_UMASK, 0, false); // Infinite wait + +#if SUB_PLATFORM_S8000 + // Switch ACC to 396MHz workaround state + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_APSC_SCR, (rACC_APSC_SCR & ~ACC_PWRCTL_APSC_SCR_MANUAL_ST_UMASK) | ACC_APSC_MANUAL_CHANGE(kDVFM_STATE_IBOOT_VCO_WA), true); + reconfig_command_read(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_APSC_SCR, 0, ACC_APSC_PENDING, 255, true); +#endif + + // Switch ACC to 396MHz. + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_APSC_SCR, (rACC_APSC_SCR & ~ACC_PWRCTL_APSC_SCR_MANUAL_ST_UMASK) | ACC_APSC_MANUAL_CHANGE(2), true); + // Wait the end of ACC change to 396MHz, we can't do after settings tunable since some of them touch ACC PLL. + reconfig_command_read(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_APSC_SCR, 0, ACC_APSC_PENDING, 255, true); + + // Restore ENABLE bit of rPMGR_GFX_PERF_STATE_CTL + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_GFX_PERF_STATE_CTL, rPMGR_GFX_PERF_STATE_CTL, false); + + // Start Si, followed by ISPi followed by normal clock. + apply_tunables_clkcfg(PMGR_CLK_S0, PMGR_CLK_ISP_REF1 + 1); + + // Restore NCO + for (i = 0; i < PMGR_NUM_NCO; i++) { + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_NCO_CLK_CFG(i), rPMGR_NCO_CLK_CFG(i), false); + } + + apply_tunables_clkcfg(0, PMGR_CLK_S0); + + // Switch SOC to SOC_PERF_STATE_ACTIVE and wait for the transition + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_CTL, rPMGR_SOC_PERF_STATE_CTL, false); + reconfig_command_read(AOP_DDR_AWAKE_POST, (uint64_t)&rPMGR_SOC_PERF_STATE_CTL, 0, PMGR_SOC_PERF_STATE_CTL_PENDING_MASK, 255, false); + + // Right time to update State 0, which is no more the current state. + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_DVFM_ST(0), rACC_DVFM_ST(0), true); + reconfig_command_write(AOP_DDR_AWAKE_POST, (uint64_t)&rACC_DVFM_ST_EXT(0), rACC_DVFM_ST_EXT(0), true); + } +#endif +} + +#if WITH_DEVICETREE +static uint64_t get_freq_from_acc_state(uint32_t state_index); + +static void pmgr_get_dvfm_data_from_vmax(struct dvfm_data *dvfm, uint32_t dvfm_state_vmax) +{ + dvfm->dvfm_state_vmax = dvfm_state_vmax; + dvfm->voltage_states1_count = dvfm_state_vmax - kDVFM_STATE_V0 + 1; + dvfm->voltage_states1_size = dvfm->voltage_states1_count * 2; + dvfm->dvfm_state_iboot_cnt = dvfm_state_vmax + 1; + dvfm->dvfm_state_vnom = kDVFM_STATE_V2; + dvfm->dvfm_state_vboost = dvfm_state_vmax; +} + +static void pmgr_get_dvfm_data(struct dvfm_data *dvfm) +{ + uint32_t dvfm_state_vmax; + // DVFM table is filled with kDVFM_STATE_IBOOT copy after the last valid state. Use it to find the last valid state. + for (dvfm_state_vmax = kDVFM_STATE_IBOOT; dvfm_state_vmax < kDVFM_STATE_MAX_CNT - 1; dvfm_state_vmax++) { + if (get_freq_from_acc_state(dvfm_state_vmax) > get_freq_from_acc_state(dvfm_state_vmax + 1)) { + break; + } + } + pmgr_get_dvfm_data_from_vmax(dvfm, dvfm_state_vmax); +} +#endif + +static void enable_bira_work_around() +{ +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + // Domain order come from + // "Functional access to memory could be corrupted when a partition is being wake up while another partition is in repair loading" + // Note: The reconfig part of this workaround is not done by pmgr driver. + static const uint32_t domain[] = { + CLK_DISP0, + CLK_ISP, + CLK_MEDIA, + CLK_MSR, + CLK_VDEC0, + CLK_VENC_CPU, + CLK_VENC_PIPE, + CLK_VENC_ME0, + CLK_VENC_ME1, + CLK_GFX, + }; +#elif SUB_PLATFORM_S8001 + static const uint32_t domain[] = { + CLK_DISP0, + CLK_ISP, + CLK_MEDIA, + CLK_MSR, + CLK_VDEC0, + CLK_VENC_CPU, + CLK_VENC_PIPE, + CLK_VENC_ME0, + CLK_VENC_ME1, + CLK_GFX, + CLK_DISP1, + CLK_SRS, + }; +#else +#error "Unknown platform" +#endif + + // Turn on the blocks + for (uint32_t i = 0; i < sizeof(domain)/sizeof(domain[0]); i++) { + clock_gate(domain[i], true); + } + // Turn off the blocks + for (uint32_t i = sizeof(domain)/sizeof(domain[0]); i > 0; i--) { + clock_gate(domain[i - 1], false); + } +} + +static uint64_t pmgr_get_offset_from_diff_uV(uint32_t buck, uint32_t uV) +{ + // power API is only able to convert absolute value + // So, we need to convert abolute value and do the diff. + uint32_t mV_prev = 0; + uint32_t mV; + uint32_t offset; + uint32_t zero_mV; + if (platform_get_dwi_to_mv(buck, 1) <= 0) // even if offset 0 is 0mV, offset 1 must be >0 mV. + return 0; // This platform doesn't have HW PMU or emulation + + zero_mV = platform_get_dwi_to_mv(buck, 0); + for (offset = 0; offset < 0xff; offset++) { + mV = platform_get_dwi_to_mv(buck, offset); + if ((mV - zero_mV) * 1000 >= uV) + { + // We look for the closest offset. + // It can be offset or offset -1 + if ((uV - (mV_prev - zero_mV) * 1000) < ((mV - zero_mV) * 1000 - uV)) + return offset - 1; + else + return offset; + } + mV_prev = mV; + } + panic("No offset for %d uV on buck %d\n", uV, buck); + return 0; +} + +static void pmgr_set_clkcfg(volatile uint32_t *clkcfg, uint32_t value) +{ + // Keep wait COUNTER tunables + uint32_t val; + val = (*clkcfg) & PMGR_CLK_CFG_WAIT_COUNTER_UMASK; + val |= value & ~PMGR_CLK_CFG_WAIT_COUNTER_UMASK; + *clkcfg = val; + while ((*clkcfg & PMGR_CLK_CFG_PENDING) != 0); +} + +/* + * clocks_set_default - called by SecureROM, LLB, iBSS main via + * platform_init_setup_clocks, so the current state of the chip is + * either POR, or whatever 'quiesce' did when leaving SecureROM. + */ + +int clocks_set_default(void) +{ + uint32_t cnt; +#if APPLICATION_SECUREROM + bool securerom = true; +#else + bool securerom = false; +#endif + volatile uint32_t *clkcfg; + +#if SUB_PLATFORM_S8001 + pmgr_soc_perf_states[kSOC_PERF_STATE_VNOM] = pmgr_soc_perf_states[kSOC_PERF_STATE_VMIN]; +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + enable_bira_work_around(); +#endif + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Setup bypass DVFM state + config_apsc_acc_state(kDVFM_STATE_BYPASS, CHIPID_CPU_VOLTAGE_BYPASS, securerom); + + // Change all clocks to something safe + clocks_quiesce_internal(); + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + apply_tunables(false); +#endif + + // Setup active DVFM and SOC PERF states for the stage of boot. +#if APPLICATION_SECUREROM + config_apsc_acc_state(kDVFM_STATE_SECUREROM, CHIPID_CPU_VOLTAGE_SECUREROM, securerom); + config_soc_perf_state(kSOC_PERF_STATE_SECUREROM, CHIPID_SOC_VOLTAGE_SECUREROM); +#endif + +#if APPLICATION_IBOOT +#ifndef BUCK_CPU +#error BUCK_CPU not defined for this platform +#endif + +#ifndef BUCK_CPU_RAM +#error BUCK_CPU_RAM not defined for this platform +#endif + +#ifndef BUCK_SOC +#error BUCK_SOC not defined for this platform +#endif + +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + +#ifndef BUCK_GPU_RAM +#error BUCK_GPU_RAM not defined for this platform +#endif + + rPMGR_VOLMAN_BUCK_MAP = + PMGR_VOLMAN_BUCK_MAP_CPU_INSRT(BUCK_CPU) | + PMGR_VOLMAN_BUCK_MAP_CPU_SRAM_INSRT(BUCK_CPU_RAM) | + PMGR_VOLMAN_BUCK_MAP_SOC_INSRT(BUCK_SOC) | + PMGR_VOLMAN_BUCK_MAP_GFX_INSRT(BUCK_GPU) | + PMGR_VOLMAN_BUCK_MAP_GFX_SRAM_INSRT(BUCK_GPU_RAM); + + // APSC sleep state will use the bypass state with V0. + config_apsc_acc_state(kDVFM_STATE_BYPASS, CHIPID_CPU_VOLTAGE_BYPASS, securerom); + + for (cnt = kDVFM_STATE_IBOOT; cnt < kDVFM_STATE_MAX_CNT; cnt++) { + enum chipid_voltage_index voltage_index = dvfmperf_get_voltage_index(cnt, CHIPID_CPU_VOLTAGE); + config_apsc_acc_state(cnt, voltage_index, securerom); + } + + for (cnt = kSOC_PERF_STATE_IBOOT; cnt < kSOC_PERF_STATE_MAX_CNT; cnt++) { + enum chipid_voltage_index voltage_index = dvfmperf_get_voltage_index(cnt, CHIPID_SOC_VOLTAGE); + config_soc_perf_state(cnt, voltage_index); + } +#if WITH_HW_DWI + extern int dwi_init(void); + dwi_init(); +#endif + +#if SUB_PLATFORM_S8000 + // Don't allow CPU PLL to reset on sleep entry (WFI) + enable_cpu_pll_reset(false); + + // Go to workaround state + set_apsc_acc_state(kDVFM_STATE_IBOOT_VCO_WA); +#endif +#endif + + // ACC clock set for this stage of boot. + set_apsc_acc_state(active_state); + +#if APPLICATION_IBOOT + for (cnt = 0; cnt <= kPMGR_GFX_STATE_MAX; cnt++) { + enum chipid_voltage_index index = dvfmperf_get_voltage_index(cnt, CHIPID_GPU_VOLTAGE); + set_gfx_perf_state(cnt, index); + } + + rPMGR_PLL_CFG(5) |= (PMGR_PLL_RELOCK_MODE_BYPASS << PMGR_PLL_RELOCK_MODE_SHIFT); + rPMGR_PLL_CTL(5) &= ~PMGR_PLL_BYPASS; + while (rPMGR_PLL_CTL(5) & PMGR_PLL_PENDING); + + rPMGR_GFX_PERF_STATE_CTL |= PMGR_GFX_PERF_STATE_CTL_ENABLE; +#endif + +#ifdef LPO_T + set_lpo(); +#endif + +#ifdef PLL0_T + set_pll(PLL0, PLL0_P, PLL0_M, PLL0_S); +#endif + +#ifdef PLL1_T + set_pll(PLL1, PLL1_P, PLL1_M, PLL1_S); +#endif + +#ifdef PLL2_T + set_pll(PLL2, PLL2_P, PLL2_M, PLL2_S); +#endif + +#ifdef PLL3_T +#ifndef TARGET_DDR_800M + if (((chipid_get_chip_id() == 0x8000) && (chipid_get_chip_revision() >= CHIP_REVISION_B0)) + || (chipid_get_chip_id() == 0x8001) || (chipid_get_chip_id() == 0x8003)) { + set_pll(PLL3, PLL3_P, PLL3_M, PLL3_S); + } +#endif +#endif + +#ifdef PLL4_T + set_pll(PLL4, PLL4_P, PLL4_M, PLL4_S); +#endif + +#ifdef PLL5_T + set_pll(PLL5, PLL5_P, PLL5_M, PLL5_S); +#endif + +#ifdef PLL6_T + set_pll(PLL6, PLL6_P, PLL6_M, PLL6_S); +#endif + +#ifdef PLL7_T + set_pll(PLL7, PLL7_P, PLL7_M, PLL7_S); +#endif + +#ifdef PLL_PCIE_T + set_pll(PLL_PCIE, PLL_PCIE_P, PLL_PCIE_M, PLL_PCIE_S); +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Turn on NCO clocks before enabling MCA clocks. + set_nco_clocks(); +#endif + + set_soc_perf_state(SOC_PERF_STATE_ACTIVE); + + // Set all clock divs to their active values + for (cnt = 0; cnt < sizeof(clk_configs_active) / sizeof(clk_configs_active[0]); cnt++) { + clkcfg = clk_configs[clk_configs_active[cnt].clk].clock_reg; + pmgr_set_clkcfg(clkcfg, clk_configs_active[cnt].clock_reg_val); + } + + power_on_sep(); + + clocks_get_frequencies(); + + return 0; +} + +static void config_apsc_acc_state(uint32_t state, enum chipid_voltage_index voltage_index, bool securerom) +{ + uint64_t value = 0; + uint64_t value_ext = 0; + + uint32_t dwi_val = 0; + uint32_t dwi_sram_val = 0; + + if (state >= kDVFM_STATE_MAX_CNT) + panic("Unsupported DVFM state"); + + dwi_val = chipid_get_cpu_voltage(voltage_index); + +#if SUB_PLATFORM_S8000 + // Workaround for N66/N71 add up to 30mV to Maui Fuse Rev 8 CPU Mode 6 due to L2C failures + // Amended in if Maui Fuse Rev 8 CPU Mode 6 bin voltage is above 1100mV, do not perform workaround + // Amended in N66/N71 add up to 25mV to Maui Fuse Rev 8 CPU Mode 6 changes in binning + // Amended in N66/N71: Maui Fuse Rev 8 and greater : set MC7 voltage to be equal to MC6 voltage + if (((voltage_index == CHIPID_CPU_VOLTAGE_1800) || (voltage_index == CHIPID_CPU_VOLTAGE_1848)) && (chipid_get_fuse_revision() == 0x8)) { + dwi_val = dwi_val + 25; + if (dwi_val > 1125) { + dwi_val = 1125; + } + } +#endif + + platform_convert_voltages(BUCK_CPU, 1, &dwi_val); + dwi_sram_val = chipid_get_cpu_sram_voltage(voltage_index); + platform_convert_voltages(BUCK_CPU_RAM, 1, &dwi_sram_val); + + const struct operating_point_params *params = operating_point_get_params(voltage_index, CHIPID_CPU_VOLTAGE); + if (params == NULL) { + return; // !!!FIXME!!! S8003: Populate chipid_voltadj_entry table + } + + value |= ACC_DVFM_ST_PLL_P(params->preDivP); + value |= ACC_DVFM_ST_PLL_M(params->fbkDivM); + value |= ACC_DVFM_ST_PLL_S(params->pstDivS); + value |= ACC_DVFM_ST_SAFE_VOL(dwi_val); + value_ext |= ACC_DVFM_ST_BIU_DIV_HI_VOL(params->biuDiv4HiVol); + value_ext |= ACC_DVFM_ST_BIU_DIV_LO_VOL(params->biuDiv4LoVol); + value_ext |= ACC_DVFM_ST_DVMR_MAX_WGT(params->dvmrMaxWgt); + value_ext |= ACC_PWRCTL_DVFM_ST0_EXT_IEXRF_CFG_WR_DATA_INSRT(params->iexrfCfgWrData); + value_ext |= ACC_PWRCTL_DVFM_ST0_EXT_IEXRF_CFG_WR_IDXA_INSRT(params->iexrfCfgWrIdxa); + value_ext |= ACC_PWRCTL_DVFM_ST0_EXT_IEXRF_CFG_WR_IDXB_INSRT(params->iexrfCfgWrIdxb); + value_ext |= ACC_PWRCTL_DVFM_ST0_EXT_IEXRF_CFG_WR_IDXMUXSEL_INSRT(params->exrfCfgWrIdxmuxsel); + value_ext |= ACC_DVFM_ST_SRAM_VOL(dwi_sram_val); + + if (securerom) { + value |= ACC_DVFM_ST_CLK_SRC(params->clkSrc); + value |= ACC_DVFM_ST_VOL_BYP(1); + value_ext |= ACC_DVFM_ST_DVFM_MAX_ADJ(0x7f); + } else { + const struct pmgr_binning_vol_adj *adj = pmgr_binning_get_vol_adj(chipid_get_chip_id(), chipid_get_chip_revision(), voltage_index); + if (adj == NULL) { + return; // !!!FIXME!!! S8003: Populate chipid_voltadj_entry table + } + value |= ACC_DVFM_ST_CLK_SRC(params->clkSrc); + value |= ACC_DVFM_ST_VOL_BYP(params->bypass); + value |= ACC_DVFM_ST_VOL_ADJ0(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj0)); + value |= ACC_DVFM_ST_VOL_ADJ1(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj1)); + value |= ACC_DVFM_ST_VOL_ADJ2(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj2)); + value |= ACC_DVFM_ST_VOL_ADJ3(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj3)); + + value_ext |= ACC_DVFM_ST_DVFM_MAX_ADJ(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvfmMaxAdj)); + value_ext |= ACC_DVFM_ST_DVMR_ADJ0(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvmrAdj0)); + value_ext |= ACC_DVFM_ST_DVMR_ADJ1(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvmrAdj1)); + value_ext |= ACC_DVFM_ST_DVMR_ADJ2(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvmrAdj2)); + + if (state < 8) { + rACC_NRG_ACC_SCALE_TAB &= ~((uint64_t)ACC_PWRCTL_NRG_ACC_SCALE_TAB_DVFM_ST0_SCALE_UMASK << (state * 8)); + rACC_NRG_ACC_SCALE_TAB |= (uint64_t)params->nrgAccScaleTab << (state * 8); + rACC_LKG_EST_TAB &= ~((uint64_t)ACC_PWRCTL_LKG_EST_TAB_DVFM_ST0_LKG_UMASK << (state * 8)); + rACC_LKG_EST_TAB |= (uint64_t)params->lkgEstTab << (state * 8); + rACC_DPE0_DVFM_TAB &= ~((uint64_t)ACC_PWRCTL_DPE0_DVFM_TAB_DVFM_ST0_THRESH_UMASK << (state * 8)); + rACC_DPE0_DVFM_TAB |= (uint64_t)params->dpe0DvfmTab << (state * 8); + } + else if (state < 16) { + rACC_NRG_ACC_SCALE_TAB_EXT &= ~((uint64_t)ACC_PWRCTL_NRG_ACC_SCALE_TAB_EXT_DVFM_ST8_SCALE_UMASK << ((state - 8) * 8)); + rACC_NRG_ACC_SCALE_TAB_EXT |= (uint64_t)params->nrgAccScaleTab << ((state - 8) * 8); + rACC_LKG_EST_TAB_EXT &= ~((uint64_t)ACC_PWRCTL_LKG_EST_TAB_EXT_DVFM_ST8_LKG_UMASK << ((state - 8) * 8)); + rACC_LKG_EST_TAB_EXT |= (uint64_t)params->lkgEstTab << ((state - 8) * 8); + rACC_DPE0_DVFM_TAB_EXT &= ~((uint64_t)ACC_PWRCTL_DPE0_DVFM_TAB_DVFM_ST0_THRESH_UMASK << ((state - 8) * 8)); + rACC_DPE0_DVFM_TAB_EXT |= (uint64_t)params->dpe0DvfmTab << ((state - 8) * 8); + } + } + + rACC_DVFM_ST(state) = value; + rACC_DVFM_ST_EXT(state) = value_ext; +} + +static uint32_t get_apsc_acc_state(void) +{ + return ACC_PWRCTL_DVFM_CFG_SEL_CUR_CFG_XTRCT(rACC_DVFM_CFG_SEL); +} + +static void set_apsc_acc_state(uint32_t target_state) +{ + // DWI clock must be enabled for any state change that has voltage control enabled. + uint64_t apsc_scr = rACC_APSC_SCR; + apsc_scr &= ~ACC_PWRCTL_APSC_SCR_MANUAL_ST_UMASK; + rACC_APSC_SCR = apsc_scr | ACC_APSC_MANUAL_CHANGE(target_state); + while ((rACC_APSC_SCR & ACC_APSC_PENDING) != 0); + + return; +} + +static void enable_cpu_pll_reset(bool enable) +{ + uint64_t apsc_scr = rACC_APSC_SCR; + + if (enable) + apsc_scr &= ~ACC_PWRCTL_APSC_SCR_DIS_RESET_PLL_IN_SLEEP_UMASK; + else + apsc_scr |= ACC_PWRCTL_APSC_SCR_DIS_RESET_PLL_IN_SLEEP_UMASK; + + rACC_APSC_SCR = apsc_scr; +} + +static void config_soc_perf_state(uint32_t state, enum chipid_voltage_index voltage_index) +{ + uint32_t dwi_val = 0; + + dwi_val = chipid_get_soc_voltage(voltage_index); + platform_convert_voltages(BUCK_SOC, 1, &dwi_val); + +#if !APPLICATION_SECUREROM && !SUB_PLATFORM_S8001 + const struct pmgr_binning_vol_adj *adj; +#endif + uint32_t vol_adj_temp = 0; + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[voltage_index].entry[0]; + rPMGR_SOC_PERF_STATE_ENTRY_B(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[voltage_index].entry[1]; + rPMGR_SOC_PERF_STATE_ENTRY_C(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[voltage_index].entry[2] | PMGR_SOC_PERF_STATE_ENTRY_VOLTAGE(dwi_val); + +#if !APPLICATION_SECUREROM && !SUB_PLATFORM_S8001 + adj = pmgr_binning_get_vol_adj(chipid_get_chip_id(), chipid_get_chip_revision(), voltage_index); + vol_adj_temp |= PMGR_SOC_PERF_STATE_ENTRY_0D_REGION0_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_SOC, adj->volAdj0)); + vol_adj_temp |= PMGR_SOC_PERF_STATE_ENTRY_0D_REGION1_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_SOC, adj->volAdj1)); + vol_adj_temp |= PMGR_SOC_PERF_STATE_ENTRY_0D_REGION2_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_SOC, adj->volAdj2)); + vol_adj_temp |= PMGR_SOC_PERF_STATE_ENTRY_0D_REGION3_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_SOC, adj->volAdj3)); +#endif + + rPMGR_SOC_PERF_STATE_ENTRY_D(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = vol_adj_temp; +} + +static void set_soc_perf_state(uint32_t target_state) +{ + rPMGR_SOC_PERF_STATE_CTL = PMGR_SOC_PERF_STATE_TO_ENTRY(target_state); + while (rPMGR_SOC_PERF_STATE_CTL & PMGR_SOC_PERF_STATE_CTL_PENDING_MASK); +} + +static void set_lpo(void) +{ + uint32_t cfg; + + cfg = rMINIPMGR_LPO_CFG; + cfg &= ~MINIPMGR_LPO_CFG_TRIM_UMASK; + cfg |= chipid_get_lpo_trim() << MINIPMGR_LPO_CFG_TRIM_SHIFT; +#if SUB_PLATFORM_S8003 + // Workaround for LPO issue - iboot + if (chipid_get_lpo_trim() == 0) { + cfg |= 0x9b << MINIPMGR_LPO_CFG_TRIM_SHIFT; + cfg &= ~MINIPMGR_LPO_CFG_LOCK_TIME_UMASK; + cfg |= 0x62 >> MINIPMGR_LPO_CFG_LOCK_TIME_SHIFT; + } +#endif + rMINIPMGR_LPO_CFG = cfg; + + rMINIPMGR_LPO_CTL = MINIPMGR_LPO_CTL_ENABLE; + + while (rMINIPMGR_LPO_CTL & MINIPMGR_LPO_CTL_PENDING); +} + +/* + * set_pll - called by SecureROM, LLB, iBSS with PLLs in default reset state. + * See restore_clock_config_state(). + */ +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s) +{ + if (pll >= PMGR_PLL_COUNT) + panic("Invalid PLL %u", pll); + + if (pll != PLL_PCIE) { + rPMGR_PLL_CTL(pll) = PMGR_PLL_ENABLE | PMGR_PLL_LOAD | PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s); + } else { + uint32_t delay_ctl; + +#if !APPLICATION_SECUREROM + uint32_t cfg_params; + + // Set PCIE_PLL Lock Mode Tunable. (Maui and Elba) + cfg_params = rPMGR_PLL_CFG(pll); + cfg_params &= ~PMGR_PLL_PCIE_CFG_LOCK_MODE_UMASK; + cfg_params |= PMGR_PLL_LOCK_MODE(PMGR_PLL_LOCK_MODE_LOCK); + rPMGR_PLL_CFG(pll) = cfg_params; +#endif + +#if SUB_PLATFORM_S8000 + uint32_t ana_params; + // The PCIe PLL needs data loaded from the fuses () + ana_params = rPMGR_PLL_ANA_PARAMS2(pll); + ana_params &= ~(PMGR_PLL_PCIE_ANA_PARAMS2_V2I_I_SET_UMASK | PMGR_PLL_PCIE_ANA_PARAMS2_V2I_PI_SET_UMASK); + ana_params |= PMGR_PLL_PCIE_ANA_PARAMS2_V2I_PI_SET_INSRT(chipid_get_pcie_refpll_vco_v2i_pi_set()); + ana_params |= PMGR_PLL_PCIE_ANA_PARAMS2_V2I_I_SET_INSRT(chipid_get_pcie_refpll_vco_v2i_i_set()); + rPMGR_PLL_ANA_PARAMS2(pll) = ana_params; + + // Maui RefPLL new default value for pll_lpf_c3 - update tunables + ana_params = rPMGR_PLL_ANA_PARAMS3(pll); + ana_params &= ~PMGR_PLL_PCIE_ANA_PARAMS3_LPF_C3_SEL_UMASK; + rPMGR_PLL_ANA_PARAMS3(pll) = ana_params; + +#elif SUB_PLATFORM_S8001 || SUB_PLATFORM_S8003 + uint32_t ana_params; + // The PCIe PLL needs data loaded from the fuses (/) + ana_params = rPMGR_PLL_ANA_PARAMS3(pll); + ana_params &= ~(PMGR_PLL_PCIE_ANA_PARAMS3_FCAL_VCODIGCTRL_UMASK | + PMGR_PLL_PCIE_ANA_PARAMS3_FCAL_BYPASS_UMASK); + ana_params |= PMGR_PLL_PCIE_ANA_PARAMS3_FCAL_VCODIGCTRL_INSRT(chipid_get_pcie_refpll_fcal_vco_digctrl()) | + PMGR_PLL_PCIE_ANA_PARAMS3_FCAL_BYPASS_INSRT(1); + rPMGR_PLL_ANA_PARAMS3(pll) = ana_params; +#endif + // Fix up PCIE PLL timing register descriptions + delay_ctl = rPMGR_PLL_PCIE_DELAY_CTL0(pll); + delay_ctl &= ~PMGR_PLL_PCIE_PLL_DELAY_CTL0_PLL_PREUPDATE_TIME_SMASK; + delay_ctl |= PMGR_PLL_PCIE_PLL_DELAY_CTL0_PLL_PREUPDATE_TIME_INSRT(0xc); + rPMGR_PLL_PCIE_DELAY_CTL0(pll) = delay_ctl; + + rPMGR_PLL_CTL(pll) = PMGR_PLL_ENABLE | PMGR_PLL_LOAD | PMGR_PLL_M(m) | PMGR_PLL_PCIE_S(s); + } + + while (rPMGR_PLL_CTL(pll) & PMGR_PLL_PENDING); + + if (pll == PLL_PCIE) { + rPMGR_MISC_PCIE_PCIE_CTL = rPMGR_MISC_PCIE_PCIE_CTL | PMGR_MISC_PCIE_PCIE_CTL_OFF_MODE_OVERRIDE_INSRT(1); + } +} + +static uint32_t get_pll_cpu(void) +{ + uint32_t freq; + uint32_t pllctl; + + pllctl = rACC_PLL_SCR1; + + // Fcpu <= ((OSC * M) / P / S+1) + freq = OSC_FREQ; + freq *= ACC_PWRCTL_PLL_SCR1_FB_DIVN_XTRCT(pllctl); + freq /= ACC_PWRCTL_PLL_SCR1_PRE_DIVN_XTRCT(pllctl); + freq /= 1 + ACC_PWRCTL_PLL_SCR1_OP_DIVN_XTRCT(pllctl); + + return freq; +} + +static uint32_t get_pll(int32_t pll) +{ + uint32_t pllctl; + uint32_t opdiv; + uint64_t freq = OSC_FREQ; + + pllctl = rPMGR_PLL_CTL(pll); + + if ((pllctl & PMGR_PLL_ENABLE) == 0) { + return 0; + } + else if (pllctl & PMGR_PLL_BYPASS) { + return freq; + } + + freq *= ((pllctl >> PMGR_PLL_M_SHIFT) & PMGR_PLL_M_MASK); + + if (pll != PLL_PCIE) { + opdiv = ((pllctl >> PMGR_PLL_S_SHIFT) & PMGR_PLL_S_MASK); + freq /= opdiv + 1; + freq /= ((pllctl >> PMGR_PLL_P_SHIFT) & PMGR_PLL_P_MASK); + } else { + opdiv = ((pllctl >> PMGR_PLL_S_SHIFT) & PMGR_PLL_PCIE_S_MASK); + if (opdiv >= 3 && opdiv <= 7) { + freq /= 16; + } else if (opdiv > 7) { + freq /= 2 * opdiv; + } + } + +#if DEBUG_BUILD + if (freq > 0xFFFFFFFF) + panic("Frequency value does not fit in uint32_t"); +#endif + + return (uint32_t)freq; +} + + +static uint32_t get_spare(int32_t spare) +{ + uint32_t reg_val, src_idx, src_clk, src_factor, div; + volatile uint32_t *spare_clkcfg = clk_configs[PMGR_CLK_S0 + spare].clock_reg; + + reg_val = *spare_clkcfg; + + div = reg_val & PMGR_CLK_CFG_DIVISOR_MASK; + + if (((reg_val & PMGR_CLK_CFG_ENABLE) == 0) || div == 0) + return 0; + + src_idx = (reg_val >> PMGR_CLK_CFG_SRC_SEL_SHIFT) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].src_clk; + src_factor = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].factor; + + return (clks[src_clk] / src_factor) / div; +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_CPU] = 5000000; + clks[PMGR_CLK_USB] = 12000000; + clks[PMGR_CLK_LPO] = LPO_FREQ; + +#elif SUB_TARGET_S8000SIM || SUB_TARGET_S8001SIM + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + +#else + uint32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + clks[PMGR_CLK_LPO] = LPO_FREQ; + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) + clks[PMGR_CLK_PLL0 + cnt] = get_pll(cnt); + + // Use get_spare() to establish the frequencies for spare clocks (unconfigured will be skipped) + for (cnt = 0; cnt < PMGR_SPARE_COUNT; cnt++) + clks[PMGR_CLK_S0 + cnt] = get_spare(cnt); + + clks[PMGR_CLK_CPU] = get_pll_cpu(); + + clocks_get_frequencies_range(PMGR_CLK_MINI_FIRST, PMGR_CLK_MINI_LAST); + clocks_get_frequencies_range(PMGR_CLK_FIRST, PMGR_CLK_LAST); +#endif +} + +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk) +{ + volatile uint32_t *reg; + uint32_t cnt, val, src_idx, src_clk, src_factor; + + if ((start_clk >= PMGR_CLK_FIRST && end_clk <= PMGR_CLK_LAST) || + (start_clk >= PMGR_CLK_MINI_FIRST && end_clk <= PMGR_CLK_MINI_LAST)) { + for (cnt = start_clk; cnt <= end_clk; cnt++) { + reg = clk_configs[cnt].clock_reg; + val = *reg; + + if ((val & PMGR_CLK_CFG_ENABLE) == 0) { + clks[cnt] = 0; + continue; + } + + src_idx = (val >> PMGR_CLK_CFG_SRC_SEL_SHIFT) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[cnt].sources[src_idx].src_clk; + src_factor = clk_configs[cnt].sources[src_idx].factor; + clks[cnt] = clks[src_clk] / src_factor; + } + } +} + +void dump_clock_frequencies() +{ + uint32_t i; + + for (i = 0; i < PMGR_CLK_COUNT; i++) { + dprintf(DEBUG_CRITICAL, "clk[%d] -> %u\n", i, clks[i]); + } +} + +static void clock_update_range(uint32_t first, uint32_t last, const uint32_t clkdata) +{ + volatile uint32_t *reg; + uint32_t cnt; + + for (cnt = first; cnt <= last; cnt++) { + reg = clk_configs[cnt].clock_reg; + pmgr_set_clkcfg(reg, clkdata); + } +} + +static void clock_update_frequency(uint32_t clk, uint32_t freq) +{ +#define ROUND_10E4(_x) ((((_x) + 5000) / 10000) * 10000) + + uint32_t src_idx, reg, i; + bool freq_supported = false; + volatile uint32_t *clkcfg = clk_configs[clk].clock_reg; + + if (freq == 0) + return; + + for (i = 0; i < CLOCK_SOURCES_MAX && clk_configs[clk].sources[i].factor != 0; i++) + { + uint32_t src_clk = clk_configs[clk].sources[i].src_clk; + uint32_t src_factor = clk_configs[clk].sources[i].factor; + + if (ROUND_10E4(clks[src_clk] / src_factor) == freq) { + freq_supported = true; + src_idx = i; // Choose latest one to pick up PLL instead of Si if available. + break; + } + } + + if (freq_supported) { + // Configure clock + uint32_t i; + uint32_t j; + uint32_t size = sizeof(pmgr_soc_perf_state_src_sels)/sizeof(pmgr_soc_perf_state_src_sels[0]); + + for (i = 0; i < size; i++) { + if (pmgr_soc_perf_state_src_sels[i].clk_index == clk) { + break; + } + } + + if (i < size) { + for (j = kSOC_PERF_STATE_IBOOT; j < kSOC_PERF_STATE_MAX_CNT; j++) { + volatile uint32_t *soc_perf_state_entry = NULL; + volatile uint32_t soc_perf_state_entry_value; + switch (pmgr_soc_perf_state_src_sels[i].entry) { + case 'A': + soc_perf_state_entry = &rPMGR_SOC_PERF_STATE_ENTRY_A(j); + break; + case 'B': + soc_perf_state_entry = &rPMGR_SOC_PERF_STATE_ENTRY_B(j); + break; + case 'C': + soc_perf_state_entry = &rPMGR_SOC_PERF_STATE_ENTRY_C(j); + break; + default: + panic("Unknwon entry\n"); + break; + } + soc_perf_state_entry_value = *soc_perf_state_entry; + soc_perf_state_entry_value &= ~pmgr_soc_perf_state_src_sels[i].mask; + soc_perf_state_entry_value |= (src_idx << pmgr_soc_perf_state_src_sels[i].shift) & pmgr_soc_perf_state_src_sels[i].mask; + *soc_perf_state_entry = soc_perf_state_entry_value; + } + } + reg = *clkcfg; + reg &= ~(PMGR_CLK_CFG_SRC_SEL_MASK << PMGR_CLK_CFG_SRC_SEL_SHIFT); + reg |= (src_idx & PMGR_CLK_CFG_SRC_SEL_MASK) << PMGR_CLK_CFG_SRC_SEL_SHIFT; + pmgr_set_clkcfg(clkcfg, reg); + } +} + +static void restore_clock_config_state(void) +{ + uint32_t cnt; + uint32_t current_select, entry_a; + + // 2. Write reset value to ACG, CLK_DIVIDER_ACG_CFG + rPMGR_MISC_CFG_ACG = 0; + rPMGR_CLK_DIVIDER_ACG_CFG = 0; + + // 3. Write the reset value to all MCAx_CLK_CFG registers + clock_update_range(PMGR_CLK_MCA0_M, PMGR_CLK_MCA4_M, 0x80100000); + + // 4. Put the NCOs in reset state + for (cnt = 0; cnt < PMGR_NUM_NCO; cnt++) + { + rPMGR_NCO_CLK_CFG(cnt) = 0; + while (rPMGR_NCO_CLK_CFG(cnt) & PMGR_NCO_CLK_CFG_PENDING); + } + + // 5a. Write reset value for all mux clock configs (excluding spares) + clock_update_range(PMGR_CLK_FIRST, PMGR_CLK_TMPS - 1, 0x80100000); + clock_update_range(PMGR_CLK_TMPS, PMGR_CLK_TMPS, 0x85100000); + clock_update_range(PMGR_CLK_TMPS + 1, PMGR_CLK_LAST, 0x80100000); + + // Since AOP config engine will use SOC perf table entries 0 and 1, we start at the other end of the table to avoid stepping on each other. + + // 5b. Write the desired DRAM clock configuration state into the SOC_PERF_STATE_ENTRY_xA register + current_select = PMGR_SOC_PERF_STATE_CTL_CURRENT_SELECT_XTRCT(rPMGR_SOC_PERF_STATE_CTL); + entry_a = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[0]; + entry_a &= ~PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + entry_a |= rPMGR_SOC_PERF_STATE_ENTRY_A(current_select) & PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = entry_a; + + // 5c. Write the reset value to all other fields in ENTRY_xA + rPMGR_SOC_PERF_STATE_ENTRY_B(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[1]; + rPMGR_SOC_PERF_STATE_ENTRY_C(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[2]; + rPMGR_SOC_PERF_STATE_ENTRY_D(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[3]; + + // 6. Write the reset value to the SOC_PERF_STATE_CTL register + set_soc_perf_state(kSOC_PERF_STATE_BYPASS); + + // 7. Write the reset values to the SOC_PERF_STATE entry registers, except for ENTRY_xA + for (cnt = PMGR_SOC_PERF_STATE_FIRST_ENTRY; cnt < PMGR_SOC_PERF_STATE_ENTRY_COUNT; cnt++) { + if (cnt == PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) + continue; + + rPMGR_SOC_PERF_STATE_ENTRY_A(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_B(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_C(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_D(cnt) = 0; + } + + // 11. Write reset value to all PLLx_CTL + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if ((cnt == 0) || (cnt == 3)) + continue; // Mem PLL + + if (cnt != PLL_PCIE) { + rPMGR_PLL_CTL(cnt) = PMGR_PLL_ENABLE | PMGR_PLL_BYPASS | PMGR_PLL_M(1) | PMGR_PLL_P(1); // fb_div = 1, pre_div = 1 + } + else { + rPMGR_PLL_CTL(cnt) = PMGR_PLL_M(0xc8) | PMGR_PLL_PCIE_S(0x18); // fb_div = 0xc8, op_div = 0x18 + } + + while (rPMGR_PLL_CTL(cnt) & PMGR_PLL_PENDING); + } + + // 12. Write reset value to all other PLL registers + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 0) + continue; // Mem PLL + + rPMGR_PLL_CFG(cnt) = PMGR_PLL_OFF_MODE(PMGR_PLL_OFF_MODE_POWER_DOWN) | + PMGR_PLL_FRAC_LOCK_TIME(0x48) | PMGR_PLL_LOCK_TIME(0x348); + } + + // 13. Write reset value to spare and ISP_REF0/1 + clock_update_range(PMGR_CLK_SPARE_FIRST, PMGR_CLK_SPARE_LAST, 0x80000001); + + // 14. Put CPU clock back into its reset default. + set_apsc_acc_state(kDVFM_STATE_BYPASS); + + // Mini-PMGR + + // 2. Write the reset value to the CLK_DIVIDER_ACG_CFG register + rMINIPMGR_CLK_DIVIDER_ACG_CFG = 0; + + // 3. Write the reset value to all mux clock config registers + clock_update_range(PMGR_CLK_MINI_FIRST, PMGR_CLK_MINI_LAST, 0x80100000); + + // 4. Write the reset value to LPO_CTL register + rMINIPMGR_LPO_CTL = PMGR_PLL_ENABLE | PMGR_PLL_BYPASS; + + // 5. Write the reset value to LPO_CFG register + rMINIPMGR_LPO_CFG = 0x40000010; + while (rMINIPMGR_LPO_CTL & PMGR_PLL_PENDING); + + // 6. Write the reset value to the MISC_CFG_ACG register + rMINIPMGR_MISC_CFG_ACG = 0; +} + + +static void power_on_sep(void) +{ + volatile uint32_t *reg; + uint32_t val; + + reg = device_configs[PMGR_DEVICE_INDEX(CLK_SEP)].ps_reg; + + val = *reg; + val &= ~(PMGR_PS_AUTO_PM_EN | PMGR_PS_FORCE_NOACCESS); + *reg = val; + while (((*reg >> 4) & 0xF) != 0xF); // Wait for SEP to turn on. + + return; +} + +static void set_device(uint64_t *devices, uint64_t device) +{ +#if DEBUG_BUILD + if (device >= 128) + panic("Invalid device clock index: %llu", device); +#endif + if (device >= 64) + devices[1] |= (0x1ULL << (device - 64)); + else + devices[0] |= (0x1ULL << device); +} + +static void clocks_quiesce_internal(void) +{ + uint64_t devices[2] = { 0, 0 }; + + // Disable all voltage changes everywhere! + rPMGR_VOLMAN_CTL |= (PMGR_VOLMAN_DISABLE_CPU_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_GFX_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_CPU_SRAM_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_GFX_SRAM_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE); + + // The following devices need to be on + set_device(devices, CLK_AOP); + set_device(devices, CLK_DEBUG); + set_device(devices, CLK_AOP_GPIO); + set_device(devices, CLK_AOP_CPU); + set_device(devices, CLK_AOP_FILTER); + set_device(devices, CLK_AOP_BUSIF); + set_device(devices, CLK_SBR); + set_device(devices, CLK_AIC); + set_device(devices, CLK_DWI); + set_device(devices, CLK_GPIO); + set_device(devices, CLK_PMS); + set_device(devices, CLK_PMS_SRAM); // Until is fixed + set_device(devices, CLK_SIO_BUSIF); + set_device(devices, CLK_SIO_P); + set_device(devices, CLK_SIO); + set_device(devices, CLK_MCC); + set_device(devices, CLK_DCS0); + set_device(devices, CLK_DCS1); + set_device(devices, CLK_DCS2); + set_device(devices, CLK_DCS3); +#if SUB_PLATFORM_S8001 && DCS_NUM_CHANNELS > 4 + set_device(devices, CLK_DCS4); + set_device(devices, CLK_DCS5); + set_device(devices, CLK_DCS6); + set_device(devices, CLK_DCS7); +#endif + set_device(devices, CLK_USB); + set_device(devices, CLK_USBCTLREG); + set_device(devices, CLK_USB_OTG); + set_device(devices, CLK_SMX); + set_device(devices, CLK_SF); + + // Turn on/off critical device clocks + clocks_set_gates(devices); + + // Disable performance state table to control PLL5 + rPMGR_GFX_PERF_STATE_CTL = 0; + + restore_clock_config_state(); +} + +void clocks_quiesce(void) +{ + clocks_quiesce_internal(); +} + +uint32_t clocks_set_performance(uint32_t performance_level) +{ + uint32_t old_perf_level = perf_level; + uint32_t acc_state = get_apsc_acc_state(); + + if (acc_state != active_state) + set_apsc_acc_state(active_state); + +#if APPLICATION_IBOOT + uint32_t entry_a; + + // Enable SOC voltage changes + rPMGR_VOLMAN_CTL &= ~PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE; + +#if SUB_PLATFORM_S8001 + if (performance_level == kPerformanceMemoryFull) { + performance_level = kPerformanceMemoryMid; + } +#endif + + switch (performance_level) { + case kPerformanceMemoryLow: + case kPerformanceMemoryMid: + entry_a = rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)); + entry_a &= ~PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + if (performance_level == kPerformanceMemoryLow) + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x3, 0x8); + else { + if (get_pll(3) > OSC_FREQ) { + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x1, 0x5); // 792 MHz MCU Clock + } else { + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x1, 0x7); // 800 MHz MCU Clock + } + } +#elif SUB_PLATFORM_S8001 + if (performance_level == kPerformanceMemoryLow) + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x3, 0x8); + else { + if (get_pll(3) > OSC_FREQ) { + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x0, 0x5); // 1588 MHz MCU CLock + } else { + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x0, 0x6); // 1588 MHz MCU CLock + } + } +#endif + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)) = entry_a; + + set_soc_perf_state(kSOC_PERF_STATE_VMIN); + perf_level = performance_level; + break; + + case kPerformanceMemoryFull: + + // VNOM: Copy MCU_REF SRC_SEL from VMIN + if ((chipid_get_chip_id() == 0x8003) || (chipid_get_chip_id() == 0x8000)) { + uint32_t mcu_src_sel; + entry_a = rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)); + mcu_src_sel = PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_XTRCT(entry_a); + + entry_a = rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VNOM)); + entry_a &= ~PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_UMASK; + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_INSRT(mcu_src_sel); + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VNOM)) = entry_a; + } + + set_soc_perf_state(kSOC_PERF_STATE_VNOM); + perf_level = performance_level; + break; + + default: + break; + } + + // Disable SOC voltage changes + rPMGR_VOLMAN_CTL |= PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE; + + clocks_get_frequencies_range(PMGR_CLK_MCU_REF, PMGR_CLK_MCU_REF); +#endif + + // At this point we should have ACC clock set for this stage of boot. + return old_perf_level; +} + +void clock_get_frequencies(uint32_t *clocks, uint32_t count) +{ + uint32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) + cnt = count; + + memcpy(clocks, clks, cnt * sizeof(uint32_t)); +} + +uint32_t clock_get_frequency(int clock) +{ + uint32_t freq = 0; + + switch (clock) { + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + freq = clks[PMGR_CLK_OSC]; + break; + case CLK_PCLK: + case CLK_PERIPH: + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + freq = clks[PMGR_CLK_SIO_P]; + break; + case CLK_MEM: +#if SUPPORT_FPGA + freq = 1000000; +#elif SUB_TARGET_S8000SIM || SUB_TARGET_S8001SIM + freq = OSC_FREQ; +#else + // XXX Frequency is a function of MCU_REF_CLK and MCU_REF_CFG_SEL + freq = clks[PMGR_CLK_MCU_REF]; +#endif + break; + case CLK_BUS: + freq = clks[PMGR_CLK_SBR]; + break; + case CLK_CPU: + freq = clks[PMGR_CLK_CPU]; + break; +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + case CLK_MIPI: + freq = clks[PMGR_CLK_TEMP_MIPI_DSI]; + break; +#endif + case CLK_VCLK0: + freq = clks[PMGR_CLK_VID0]; + break; + default: + break; + } + return freq; +} + +void clock_set_frequency(int clock, uint32_t divider, uint32_t pll_p, uint32_t pll_m, uint32_t pll_s, uint32_t pll_t) +{ + uint32_t clk = PMGR_CLK_OSC; + + switch (clock) { +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + case CLK_MIPI: + clk = PMGR_CLK_PLL2; + break; +#endif + case CLK_VCLK0: + clk = PMGR_CLK_VID0; + break; + + default: + break; + } + + if (clk >= PMGR_CLK_PLL0 && clk <= PMGR_CLK_PLL5) { + int32_t pll = clk - PMGR_CLK_PLL0; + + set_pll(pll, pll_p, pll_m, pll_s); + + clks[clk] = get_pll(pll); +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + if (clock == CLK_MIPI) { + clocks_get_frequencies_range(PMGR_CLK_TEMP_MIPI_DSI, PMGR_CLK_TEMP_MIPI_DSI); + } +#endif + } + + if (clk >= PMGR_CLK_FIRST && clk <= PMGR_CLK_LAST) { + clock_update_frequency(clk, pll_t); + clocks_get_frequencies_range(clk, clk); + } + + return; +} + +void clock_gate(int device, bool enable) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + // Set the PS field to the requested level + if (enable) { + *reg |= PMGR_PS_RUN_MAX; + } else { + *reg &= ~PMGR_PS_RUN_MAX; + } + + // Wait for the MANUAL_PS and ACTUAL_PS fields to be equal + while ((*reg & PMGR_PS_MANUAL_PS_MASK) != ((*reg >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); +} + +static void clocks_set_gates(uint64_t *devices) +{ + uint32_t i, idx; + + // For future platforms that clone from this. + if (PMGR_LAST_DEVICE >= 128) + panic("Rewrite this to deal with more than 128 clock ids"); + + // Turn on devices from lo to hi (to meet dependencies). + for (idx = 0, i = PMGR_FIRST_DEVICE; i <= PMGR_LAST_DEVICE; i++) { + if (i && ((i % 64) == 0)) + idx++; + if ((devices[idx] >> ((uint64_t)(i % 64))) & 0x1) + clock_gate(i, true); + } + + // Turn off devices hi to lo order (to meet dependencies). + for (idx = 1, i = PMGR_LAST_DEVICE; i >= PMGR_FIRST_DEVICE; i--) { + if (!((devices[idx] >> ((uint64_t)(i % 64))) & 0x1)) + clock_gate(i, false); + if (i && ((i % 64) == 0)) + idx--; + } + + return; +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_system_reset(); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + +#if APPLICATION_IBOOT + // + // Due to a silicon issue, doing a chip reset (as opposed to a system reset) on Maui/Malta + // may lead to LLB failing to initialize DRAM and panic, resulting in an infinite panic loop + // (since _panic calls this reset function, not platform_system_reset) + // + // So, for S8000 family, we will upgrade all chip resets to a system reset to prevent a panic loop. + // + // Also, this may go away after Should iBoot panic always reset via wdt_system_reset instead of wdt_chip_reset? + wdt_system_reset(); +#else + wdt_chip_reset(); +#endif + + while (1); +} + +void platform_power_init(void) +{ +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + init_thermal_registers(); +#endif +} + +void clock_reset_device(int device) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + switch (device) { + case CLK_SIO: + case CLK_EDPLINK: + *reg |= PMGR_PS_RESET; + spin(1); + *reg &= ~PMGR_PS_RESET; + break; + + default: + break; + } +} + +void clock_set_device_reset(int device, bool set) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + switch (device) { + case CLK_PCIE: + if (set) + *reg |= PMGR_PS_RESET; + else + *reg &= ~PMGR_PS_RESET; + } +} + +bool clock_get_pcie_refclk_good(void) +{ + // XXX JF: new register and bit number for S8000? + return (rPMGR_DEBUG_PMGR_DEBUG17 & (1 << 20)) != 0; +} + +#if APPLICATION_IBOOT +static void set_gfx_perf_state(uint32_t state_num, enum chipid_voltage_index voltage_index) +{ + const struct pmgr_binning_vol_adj *vol_adj = pmgr_binning_get_vol_adj(chipid_get_chip_id(), chipid_get_chip_revision(), voltage_index); + uint32_t pll_enable = 0; + const struct operating_point_params *params; + params = operating_point_get_params(voltage_index, CHIPID_GPU_VOLTAGE); + uint32_t dwi_val = 0; + uint32_t dwi_sram_val = 0; + + if (voltage_index != CHIPID_GPU_VOLTAGE_OFF) { + dwi_val = chipid_get_gpu_voltage(voltage_index); + platform_convert_voltages(BUCK_GPU, 1, &dwi_val); + dwi_sram_val = chipid_get_gpu_sram_voltage(voltage_index); + platform_convert_voltages(BUCK_GPU_RAM, 1, &dwi_sram_val); + } + + + // This is deductive. If feedback divider is 0 the PLL shouldn't output anything. + pll_enable = params->fbkDivM ? 1 : 0; + + rPMGR_GFX_PERF_STATE_ENTRY_A(state_num) = ((dwi_val & 0xFF) << 24) | + ((pll_enable & 0x1) << 21) | + ((params->fbkDivM & 0x1FF) << 12) | + ((params->preDivP & 0x1F) << 4) | + (params->pstDivS & 0xF); + + rPMGR_GFX_PERF_STATE_ENTRY_B(state_num) = dwi_sram_val & 0xFF; + + if (vol_adj != NULL) { + uint32_t entry_c = 0; + entry_c |= PMGR_GFX_PERF_STATE_ENTRY0C_REGION0_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_GPU, vol_adj->volAdj0)); + entry_c |= PMGR_GFX_PERF_STATE_ENTRY0C_REGION1_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_GPU, vol_adj->volAdj1)); + entry_c |= PMGR_GFX_PERF_STATE_ENTRY0C_REGION2_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_GPU, vol_adj->volAdj2)); + entry_c |= PMGR_GFX_PERF_STATE_ENTRY0C_REGION3_VOL_OFFSET_INSRT(pmgr_get_offset_from_diff_uV(BUCK_GPU, vol_adj->volAdj3)); + rPMGR_GFX_PERF_STATE_ENTRY_C(state_num) = entry_c; + } + + return; +} +#endif + +#if WITH_DEVICETREE +static uint64_t get_freq_from_acc_state(uint32_t state_index) +{ + uint64_t state_entry = rACC_DVFM_ST(state_index); + uint64_t freq = OSC_FREQ; + + // Fcpu <= ((OSC * M) / P / S+1) + freq *= ((state_entry >> 4) & 0x1FF); + freq /= ((state_entry >> 13) & 0x1F) ? ((state_entry >> 13) & 0x1F) : 1; + freq /= (1 + ((state_entry >> 0) & 0xF)); + + return freq; +} + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ + uint32_t num_freqs = 0; + uint32_t propSize; + uint64_t period_ns; + uint64_t freq = 0; + uint32_t volt; + + char *propName; + void *propData; + + struct dvfm_data dvfm = { + .dvfm_state_vmax = kDVFM_STATE_VMAX, + .dvfm_state_iboot_cnt = kDVFM_STATE_IBOOT_CNT, + .dvfm_state_vnom = kDVFM_STATE_VNOM, + .dvfm_state_vboost = kDVFM_STATE_VBOOST, + .voltage_states1_count = kVOLTAGE_STATES1_COUNT, + .voltage_states1_size = kVOLTAGE_STATES1_SIZE + }; + +#if SUB_PLATFORM_S8000 + uint32_t vco_hack = 0; + uint32_t index = 0; + uint32_t i, j; + +#if (APPLICATION_IBOOT && PRODUCT_IBEC) + if (rACC_DVFM_ST(kDVFM_STATE_IBOOT_VCO_WA) == rACC_DVFM_ST(kDVFM_STATE_IBOOT)) { + // VCO workaround DVFM states not configured by LLB / iBSS + for (i = kDVFM_STATE_IBOOT_VCO_WA; i > kDVFM_STATE_IBOOT_VCO_WA - kDVFM_STATE_VCO_WA_MAX_CNT; i--) { + enum chipid_voltage_index voltage_index = dvfmperf_get_voltage_index(i, CHIPID_CPU_VOLTAGE); + config_apsc_acc_state(i, voltage_index, false); + } + } +#endif + + for (i = kDVFM_STATE_IBOOT_VCO_WA; i > kDVFM_STATE_IBOOT_VCO_WA - kDVFM_STATE_VCO_WA_MAX_CNT; i--) { + uint64_t dvfm_st; + bool found = false; + + dvfm_st = rACC_DVFM_ST(i); + + if (dvfm_st == rACC_DVFM_ST(kDVFM_STATE_IBOOT)) + break; + + dvfm_st &= ~ACC_DVFM_ST_PLL_PMS_MASK; + + for (j = kDVFM_STATE_IBOOT; j <= kDVFM_STATE_IBOOT_VCO_WA - kDVFM_STATE_VCO_WA_MAX_CNT; j++) { + if ((rACC_DVFM_ST(j) & ~ACC_DVFM_ST_PLL_PMS_MASK) == dvfm_st) { + found = true; + break; + } + } + + if (!found) + break; + + vco_hack |= ((i << 4) | j) << index * 8; + + index++; + } + + propName = "vco-hack"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize == sizeof(uint32_t)) + ((uint32_t *)propData)[0] = vco_hack; + } +#endif + +#if !RELEASE_BUILD && WITH_MENU + pmgr_binning_menu_update_states(); // must be set before setting reconfig sequence +#endif + + pmgr_get_dvfm_data(&dvfm); + +#if SUPPORT_FPGA + propName = "l2c-acc-sleep"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize == sizeof(uint32_t)) + ((uint32_t *)propData)[0] = 0; + } +#endif + + // Populate the devicetree with relevant values. + propName = "nominal-performance1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property nominal-performance1 is of wrong size."); + + freq = get_freq_from_acc_state(dvfm.dvfm_state_vnom); + if (freq == 0) + panic("pmgr Fnom Operating point not defined correctly"); + + period_ns = 1000000000ULL << 16; + period_ns /= freq; + + ((uint32_t *)propData)[0] = period_ns; + } else { + panic("pmgr property nominal-performance1 not found."); + } + + propName = "boost-performance1"; + // Note: Boost is not mandatory in all platforms. + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property boost-performance1 is of wrong size"); + + freq = get_freq_from_acc_state(kDVFM_STATE_VBOOST); + if (freq == 0) + panic("pmgr Fboost Operating point not defined correctly"); + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[0] = period_ns; + } + + propName = "voltage-states1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize / sizeof(uint32_t) < dvfm.voltage_states1_size) { + panic("pmgr number of states less than required for voltage-states1"); + } + num_freqs = dvfm.voltage_states1_count; + for (int32_t i = num_freqs - 1, j = 0; i >= 0; i--, j++) { + // Getting voltage and frequencies directly from rCCC_DVFM_ST allows + // including all the changes done before launching the kernel: + // - voltage adjusting coming from converting voltage to PMU value, + // - voltage knobs from LLB, + // - astris changes done while beeing in iBoot console, + freq = get_freq_from_acc_state(dvfm.dvfm_state_vmax - j); + volt = platform_get_dwi_to_mv(BUCK_CPU, ACC_PWRCTL_DVFM_ST0_SAFE_VOL_XTRCT(rACC_DVFM_ST(dvfm.dvfm_state_vmax - j))); + + if (freq != 0) { + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[2*i] = period_ns; + ((uint32_t *)propData)[2*i+1] = volt; + } + } + } + + propName = "total-rails-leakage"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(uint32_t)) { + *(uint32_t *)propData = chipid_get_total_rails_leakage(); + } + } + + return; +} + +void pmgr_gfx_update_device_tree(DTNode *gfx_node) +{ + uint32_t count, propSize, num_states = 0, state_val; + char *propName; + void *propData; + + propName = "perf-states"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(uint32_t) * kPMGR_GFX_STATE_MAX)) { + panic("gfx property perf-state has wrong size"); + } + // Read the values programmed into the GFX perf state table + // and populate the device tree. + for (count = 0; count < kPMGR_GFX_STATE_MAX; count++) { + state_val = rPMGR_GFX_PERF_STATE_ENTRY_A(count); + + // Any but the first entry with a value of 0 marks the end of the number of valid states. + if ((count != 0) && (state_val == rPMGR_GFX_PERF_STATE_ENTRY_A(CHIPID_GPU_VOLTAGE_OFF))) { + num_states = count; + break; + } + + ((uint32_t *)propData)[count * 2 + 0] = PMGR_PLL_FREQ((state_val >> 12) & 0x1FF, (state_val >> 4) & 0x1F, state_val & 0xF); + ((uint32_t *)propData)[count * 2 + 1] = platform_get_dwi_to_mv(BUCK_GPU, (state_val >> 24) & 0xFF); + } + + // If all the entries are valid. + if (count == kPMGR_GFX_STATE_MAX) { + num_states = kPMGR_GFX_STATE_MAX; + } + + } + + propName = "perf-state-count"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = kPMGR_GFX_STATE_MAX; + } + + propName = "gpu-num-perf-states"; + /* We don't count OFF state */ + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = num_states - 1; + } + + return; +} +#endif + +struct register_config { + uint64_t addr; + uint64_t value; + uint32_t is_reg64; +}; + +#define USECS_TO_TICKS(_usecs) ((_usecs) * (OSC_FREQ / 1000000)) + +static const struct register_config thermal_registers[] = +{ + // Define sampling rate for each temperature sensor + {PMGR_THERMAL0_CTL1, USECS_TO_TICKS(2500), 0}, + {PMGR_THERMAL1_CTL1, USECS_TO_TICKS(2500), 0}, + {PMGR_THERMAL2_CTL1, USECS_TO_TICKS(2500), 0}, +#if SUB_PLATFORM_S8001 + {PMGR_THERMAL3_CTL1, USECS_TO_TICKS(2500), 0}, +#endif + {ACC_THRM0_CTL1, USECS_TO_TICKS(2500), 0}, + {ACC_THRM1_CTL1, USECS_TO_TICKS(2500), 0}, + {ACC_THRM2_CTL1, USECS_TO_TICKS(2500), 0}, + + // PMGR SOCHOT threshold temperatures have moved from the PMGR SOCHOT register block to the PMGR THERMAL block, ostensibly to provide greater + // flexibility via the ability to vary failsafe temperature threshold with PMGR location. The SOCHOT and temperature sensor drivers are separate + // entities currently, such that it would be inconvienient to coordinate how they come up (can't enable SOCHOT action until non-zero thresholds + // have been set, the SOCHOT driver doesn't really need to know how many temperature sensors are present, etc.) Accordingly, let's set the + // trip *thresholds* here and leave the drivers to do the rest, as usual. + {PMGR_THERMAL0_FAILSAFE_TRIP_TEMP_0, PMGR_THERMAL_0_FAILSAFE_TRIP_TEMP_0_TRIP_TEMP_0_INSRT(120), 0}, + {PMGR_THERMAL1_FAILSAFE_TRIP_TEMP_0, PMGR_THERMAL_1_FAILSAFE_TRIP_TEMP_0_TRIP_TEMP_0_INSRT(120), 0}, + {PMGR_THERMAL2_FAILSAFE_TRIP_TEMP_0, PMGR_THERMAL_2_FAILSAFE_TRIP_TEMP_0_TRIP_TEMP_0_INSRT(120), 0}, +#if SUB_PLATFORM_S8001 + {PMGR_THERMAL3_FAILSAFE_TRIP_TEMP_0, PMGR_THERMAL_3_FAILSAFE_TRIP_TEMP_0_TRIP_TEMP_0_INSRT(120), 0}, +#endif + {PMGR_THERMAL0_FAILSAFE_TRIP_TEMP_1, PMGR_THERMAL_0_FAILSAFE_TRIP_TEMP_1_TRIP_TEMP_1_INSRT(125), 0}, + {PMGR_THERMAL1_FAILSAFE_TRIP_TEMP_1, PMGR_THERMAL_1_FAILSAFE_TRIP_TEMP_1_TRIP_TEMP_1_INSRT(125), 0}, + {PMGR_THERMAL2_FAILSAFE_TRIP_TEMP_1, PMGR_THERMAL_2_FAILSAFE_TRIP_TEMP_1_TRIP_TEMP_1_INSRT(125), 0}, +#if SUB_PLATFORM_S8001 + {PMGR_THERMAL3_FAILSAFE_TRIP_TEMP_1, PMGR_THERMAL_3_FAILSAFE_TRIP_TEMP_1_TRIP_TEMP_1_INSRT(125), 0}, +#endif + + // Set target state for when SOCHOT0 triggers (see also [Fix S8000-family SOCHOT1 config]) + {ACC_DVFM_FSHOT_IDX, ACC_THERMAL_DVFM_FSHOT_IDX_0_ST_INSRT(kDVFM_STATE_V0) | ACC_THERMAL_DVFM_FSHOT_IDX_1_ST_INSRT(kDVFM_STATE_V0), 0}, + {PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_SOCHOT_OFFSET, 0, 0}, + {PMGR_BASE_ADDR + PMGR_GFX_PERF_STATE_SOCHOT_OFFSET, PMGR_GFX_PERF_STATE_SOCHOT_ENABLE_TRIG0_INSRT(1), 0}, + + // Enable temperature sensors (need to do this before enabling either DVTM or SOCHOT) + {PMGR_THERMAL0_CTL0_SET, PMGR_THERMAL_0_CTL0_SET_ENABLE_INSRT(1), 0}, + {PMGR_THERMAL1_CTL0_SET, PMGR_THERMAL_1_CTL0_SET_ENABLE_INSRT(1), 0}, + {PMGR_THERMAL2_CTL0_SET, PMGR_THERMAL_2_CTL0_SET_ENABLE_INSRT(1), 0}, +#if SUB_PLATFORM_S8001 + {PMGR_THERMAL3_CTL0_SET, PMGR_THERMAL_3_CTL0_SET_ENABLE_INSRT(1), 0}, +#endif + {ACC_THRM0_CTL0_SET, ACC_THERMAL_THRM0_CTL0_SET_ENABLE_INSRT(1), 0}, + {ACC_THRM1_CTL0_SET, ACC_THERMAL_THRM1_CTL0_SET_ENABLE_INSRT(1), 0}, + {ACC_THRM2_CTL0_SET, ACC_THERMAL_THRM2_CTL0_SET_ENABLE_INSRT(1), 0}, +}; + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +static void init_thermal_registers(void) +{ + // Read temperature trim values from efuse and write to corresponding registers + rPMGR_THERMAL0_PARAM = chipid_get_soc_temp_sensor_trim(0); + rPMGR_THERMAL1_PARAM = chipid_get_soc_temp_sensor_trim(1); + rPMGR_THERMAL2_PARAM = chipid_get_soc_temp_sensor_trim(2); +#if SUB_PLATFORM_S8001 + rPMGR_THERMAL3_PARAM = chipid_get_soc_temp_sensor_trim(3); +#endif + + // Apply static config items + for (size_t i = 0; i < sizeof(thermal_registers) / sizeof(thermal_registers[0]); i++) { + if (thermal_registers[i].is_reg64) { + *(volatile uint64_t*)thermal_registers[i].addr = thermal_registers[i].value; + } else { + *(volatile uint32_t*)thermal_registers[i].addr = thermal_registers[i].value; + } + } +} + +#endif + +void pmgr_awake_to_aop_ddr_pre_sequence_insert(void) +{ + // Disable temperature sensors + reconfig_command_write(AWAKE_AOP_DDR_PRE, PMGR_THERMAL0_CTL0_CLR, PMGR_THERMAL_0_CTL0_CLR_ENABLE_INSRT(1), 0); + reconfig_command_write(AWAKE_AOP_DDR_PRE, PMGR_THERMAL1_CTL0_CLR, PMGR_THERMAL_1_CTL0_CLR_ENABLE_INSRT(1), 0); + reconfig_command_write(AWAKE_AOP_DDR_PRE, PMGR_THERMAL2_CTL0_CLR, PMGR_THERMAL_2_CTL0_CLR_ENABLE_INSRT(1), 0); +#if SUB_PLATFORM_S8001 + reconfig_command_write(AWAKE_AOP_DDR_PRE, PMGR_THERMAL3_CTL0_CLR, PMGR_THERMAL_3_CTL0_CLR_ENABLE_INSRT(1), 0); +#endif + reconfig_command_write(AWAKE_AOP_DDR_PRE, ACC_THRM0_CTL0_CLR, ACC_THERMAL_THRM0_CTL0_CLR_ENABLE_INSRT(1), 0); + reconfig_command_write(AWAKE_AOP_DDR_PRE, ACC_THRM1_CTL0_CLR, ACC_THERMAL_THRM1_CTL0_CLR_ENABLE_INSRT(1), 0); + reconfig_command_write(AWAKE_AOP_DDR_PRE, ACC_THRM2_CTL0_CLR, ACC_THERMAL_THRM2_CTL0_CLR_ENABLE_INSRT(1), 0); +} + +void pmgr_aop_ddr_to_awake_post_sequence_insert_pll(void) +{ + apply_tunables(true); + pmgr_reconfig_pll(); +} + +void pmgr_aop_ddr_to_awake_post_sequence_insert(void) +{ + pmgr_reconfig_post(); + + // Read PMGR temperature trim values from efuse + reconfig_command_write(AOP_DDR_AWAKE_POST, PMGR_THERMAL0_PARAM, chipid_get_soc_temp_sensor_trim(0), 0); + reconfig_command_write(AOP_DDR_AWAKE_POST, PMGR_THERMAL1_PARAM, chipid_get_soc_temp_sensor_trim(1), 0); + reconfig_command_write(AOP_DDR_AWAKE_POST, PMGR_THERMAL2_PARAM, chipid_get_soc_temp_sensor_trim(2), 0); +#if SUB_PLATFORM_S8001 + reconfig_command_write(AOP_DDR_AWAKE_POST, PMGR_THERMAL3_PARAM, chipid_get_soc_temp_sensor_trim(3), 0); +#endif + + // Reapply temperature sensor tunables and then reenable temperature sensors + for (size_t i = 0; i < sizeof(thermal_registers) / sizeof(thermal_registers[0]); i++) { + reconfig_command_write(AOP_DDR_AWAKE_POST, thermal_registers[i].addr, thermal_registers[i].value, thermal_registers[i].is_reg64); + } +} + +void pmgr_s2r_aop_to_aop_ddr_post_sequence_insert_pwrgate(void) +{ + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_MCC_CFG0, rPMGR_PWRGATE_MCC_CFG0, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_MCC_CFG1, rPMGR_PWRGATE_MCC_CFG1, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_MCC_CFG2, rPMGR_PWRGATE_MCC_CFG2, false); +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS01_CFG0, rPMGR_PWRGATE_DCS01_CFG0, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS01_CFG1, rPMGR_PWRGATE_DCS01_CFG1, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS01_CFG2, rPMGR_PWRGATE_DCS01_CFG2, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS23_CFG0, rPMGR_PWRGATE_DCS23_CFG0, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS23_CFG1, rPMGR_PWRGATE_DCS23_CFG1, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS23_CFG2, rPMGR_PWRGATE_DCS23_CFG2, false); +#elif SUB_PLATFORM_S8001 + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS0123_CFG0, rPMGR_PWRGATE_DCS0123_CFG0, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS0123_CFG1, rPMGR_PWRGATE_DCS0123_CFG1, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS0123_CFG2, rPMGR_PWRGATE_DCS0123_CFG2, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS4567_CFG0, rPMGR_PWRGATE_DCS4567_CFG0, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS4567_CFG1, rPMGR_PWRGATE_DCS4567_CFG1, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_DCS4567_CFG2, rPMGR_PWRGATE_DCS4567_CFG2, false); +#endif + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_ACS_CFG0, rPMGR_PWRGATE_ACS_CFG0, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_ACS_CFG1, rPMGR_PWRGATE_ACS_CFG1, false); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, (uint64_t)&rPMGR_PWRGATE_ACS_CFG2, rPMGR_PWRGATE_ACS_CFG2, false); +} diff --git a/platform/s8000/pmgr/rules.mk b/platform/s8000/pmgr/rules.mk new file mode 100644 index 0000000..1fbd41d --- /dev/null +++ b/platform/s8000/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/s8000/reconfig.c b/platform/s8000/reconfig.c new file mode 100644 index 0000000..82a3f24 --- /dev/null +++ b/platform/s8000/reconfig.c @@ -0,0 +1,329 @@ +/* +* Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if SUB_PLATFORM_S8000 + +# if TARGET_DDR_800M +#include +#include +# else +#include +#include +# endif // # if TARGET_DDR_800M + +#elif SUB_PLATFORM_S8003 + +# if TARGET_DDR_800M +#include +#include +# else +#include +#include +# endif // # if TARGET_DDR_800M + +#else +#include +#include +#endif // #if SUB_PLATFORM_S8000 + +// +// For some documentation on how to update this and related files, +// see https://coreoswiki.apple.com/wiki/pages/n9b1J2R/Releasing_Reconfig_Engine_Changes.html +// + +typedef void (inserter_callback_t)(enum boot_target target, reconfig_stage_t stage, int index); + +static void add_breakpoint(reconfig_stage_t stage, int bitmask); + +static void awake_to_aop_ddr_pre_sequence_insert(enum boot_target target, reconfig_stage_t stage, int index) +{ + if (index == 0) + pmgr_awake_to_aop_ddr_pre_sequence_insert(); +} + +static void awake_to_aop_ddr_post_sequence_insert(enum boot_target target, reconfig_stage_t stage, int index) +{ + switch (index) { + case A2D_POST_PWRGATE_BEFORE: + // Nothing to do. AOP_DDR has the same MCC, DCS and ACS powergate tunables as AWAKE + break; + } +} + +static void aop_ddr_to_s2r_aop_pre_sequence_insert(enum boot_target target, reconfig_stage_t stage, int index) +{ +} + +static void s2r_aop_to_aop_ddr_pre_sequence_insert(enum boot_target target, reconfig_stage_t stage, int index) +{ +} + +static void s2r_aop_to_aop_ddr_post_sequence_insert(enum boot_target target, reconfig_stage_t stage, int index) +{ + switch (index) { + case S2D_POST_SECURITY_BEFORE: +#if SUB_PLATFORM_S8000 + if(platform_get_chip_revision() < CHIP_REVISION_C0) + reconfig_command_raw(stage, s2r_aop_to_aop_ddr_b0_post_mcu_locked, sizeof(s2r_aop_to_aop_ddr_b0_post_mcu_locked)/sizeof(uint32_t)); + else +#elif SUB_PLATFORM_S8003 + if(platform_get_chip_revision() < CHIP_REVISION_A1) + reconfig_command_raw(stage, s2r_aop_to_aop_ddr_a0_post_mcu_locked, sizeof(s2r_aop_to_aop_ddr_a0_post_mcu_locked)/sizeof(uint32_t)); + else +#endif + { + reconfig_command_raw(stage, s2r_aop_to_aop_ddr_post_mcu_locked, sizeof(s2r_aop_to_aop_ddr_post_mcu_locked)/sizeof(uint32_t)); + } + + if (target != BOOT_DIAGS) { + for (uint32_t i = 0; i < NUM_AMCCS; i++) { + reconfig_command_write(stage, MCCLOCKREGION_TZ0BASEADDR(i), TZ0_BASE>>12, 0); + reconfig_command_write(stage, MCCLOCKREGION_TZ0ENDADDR(i), (TZ0_BASE + TZ0_SIZE - 1)>>12, 0); + reconfig_command_write(stage, MCCLOCKREGION_TZ0LOCK(i), 1, 0); + reconfig_command_read(stage, MCCLOCKREGION_TZ0LOCK(i), 1, 1, 255, 0); + reconfig_command_write(stage, MCCLOCKREGION_TZ1BASEADDR(i), TZ1_BASE>>12, 0); + reconfig_command_write(stage, MCCLOCKREGION_TZ1ENDADDR(i), (TZ1_BASE + TZ1_SIZE - 1)>>12, 0); + + reconfig_command_write(stage, MCCLOCKREGION_TZ1LOCK(i), 1, 0); + reconfig_command_read(stage, MCCLOCKREGION_TZ1LOCK(i), 1, 1, 255, 0); + reconfig_command_write(stage, AMCC_MCCCFG_TAG_RD_DIS_ADDR(i), 1, 0); + } + } + break; + + case S2D_POST_PWRGATE_BEFORE: + pmgr_s2r_aop_to_aop_ddr_post_sequence_insert_pwrgate(); + break; + + case S2D_POST_MCU_DDR_BEFORE: +#if SUB_PLATFORM_S8000 + if(platform_get_chip_revision() < CHIP_REVISION_C0) + reconfig_command_raw(stage, s2r_aop_to_aop_ddr_b0_post_mcu_ddr, sizeof(s2r_aop_to_aop_ddr_b0_post_mcu_ddr)/sizeof(uint32_t)); + else +#elif SUB_PLATFORM_S8003 + if(platform_get_chip_revision() < CHIP_REVISION_A1) + reconfig_command_raw(stage, s2r_aop_to_aop_ddr_a0_post_mcu_ddr, sizeof(s2r_aop_to_aop_ddr_a0_post_mcu_ddr)/sizeof(uint32_t)); + else +#endif + { + reconfig_command_raw(stage, s2r_aop_to_aop_ddr_post_mcu_ddr, sizeof(s2r_aop_to_aop_ddr_post_mcu_ddr)/sizeof(uint32_t)); + } + break; + } +} + +static void aop_ddr_to_awake_pre_sequence_insert(enum boot_target target, reconfig_stage_t stage, int index) +{ + if (target == BOOT_DIAGS && index == 0) { + // As a first step towards supporting reconfig sequence programming for diags, we're + // simply resetting the system once we get back to AWAKE. We'll eventually support + // full-on S2R, but this is a first step to enable testing by the diags team + uint32_t end_command = 0x00000000; + reconfig_command_write(stage, 0x2102b001c, 0, false); + reconfig_command_write(stage, 0x2102b0014, 1, false); + reconfig_command_write(stage, 0x2102b0010, 0, false); + reconfig_command_write(stage, 0x2102b001c, 4, false); + reconfig_command_write(stage, 0x2102b0010, 0, false); + reconfig_command_delay(stage, 0x3FFFFFF); + reconfig_command_delay(stage, 0x3FFFFFF); + reconfig_command_raw(stage, &end_command, 1); + } +} + +extern void dcs_aop_ddr_to_awake_post_tunables_insert(void); + +static void aop_ddr_to_awake_post_sequence_insert(enum boot_target target, reconfig_stage_t stage, int index) +{ + uint32_t scratch0; + + switch (index) { + case D2A_POST_MCU_AWAKE_BEFORE: + // FPGA targets generally dont need the calibration since they run at 50 Mhz +#if !SUPPORT_FPGA + +#if SUB_PLATFORM_S8000 + if(platform_get_chip_revision() < CHIP_REVISION_C0) + reconfig_command_raw(stage, aop_ddr_to_awake_b0_post_mcu_awake_before_restoration, sizeof(aop_ddr_to_awake_b0_post_mcu_awake_before_restoration)/sizeof(uint32_t)); + else +#elif SUB_PLATFORM_S8003 + if(platform_get_chip_revision() < CHIP_REVISION_A1) + reconfig_command_raw(stage, aop_ddr_to_awake_a0_post_mcu_awake_before_restoration, sizeof(aop_ddr_to_awake_a0_post_mcu_awake_before_restoration)/sizeof(uint32_t)); + else +#endif + { + reconfig_command_raw(stage, aop_ddr_to_awake_post_mcu_awake_before_restoration, sizeof(aop_ddr_to_awake_post_mcu_awake_before_restoration)/sizeof(uint32_t)); + } + // Stitch the memory calibration values into the sequence with values that were saved to AOP_SRAM + dcs_restore_calibration_results((volatile uint32_t *) MEMORY_CALIB_SAVE_BASE_ADDR); + + // XXX DV says to not use this sequence verbatim +#if SUB_PLATFORM_S8000 + if(platform_get_chip_revision() < CHIP_REVISION_C0) + reconfig_command_raw(stage, aop_ddr_to_awake_b0_post_mcu_awake_after_restoration, sizeof(aop_ddr_to_awake_b0_post_mcu_awake_after_restoration)/sizeof(uint32_t)); + else +#elif SUB_PLATFORM_S8003 + if(platform_get_chip_revision() < CHIP_REVISION_A1) + reconfig_command_raw(stage, aop_ddr_to_awake_a0_post_mcu_awake_after_restoration, sizeof(aop_ddr_to_awake_a0_post_mcu_awake_after_restoration)/sizeof(uint32_t)); + else +#endif + { + reconfig_command_raw(stage, aop_ddr_to_awake_post_mcu_awake_after_restoration, sizeof(aop_ddr_to_awake_post_mcu_awake_after_restoration)/sizeof(uint32_t)); + } + +#endif // #if !SUPPORT_FPGA + + // AOP Boot: Maui A1: Samsung 25nm LP4 RBM failures - WA + if(platform_get_memory_manufacturer_id() == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) { + uint8_t rev_id = 0, rev_id2 = 0; + platform_get_memory_rev_ids(&rev_id, &rev_id2); + if(rev_id == 3 && rev_id2 == 0) + for(uint32_t channel = 0; channel < DCS_NUM_CHANNELS; channel++) + reconfig_command_write(stage, (rDCS_MCU_AREFEN_FREQ(0) + (channel * DCS_SPACING)), 0x1010013f, false); + } + break; + + case D2A_POST_RESTORE_BEFORE: + // + // Enabling ASIO to allows setting its tunables. + // + reconfig_command_write(stage, (uintptr_t)&rPMGR_PS(SIO_BUSIF), 0xf, false); + reconfig_command_read(stage, (uintptr_t)&rPMGR_PS(SIO_BUSIF), 0xf0, 0xf0, 255, false); + reconfig_command_write(stage, (uintptr_t)&rPMGR_PS(SIO_P), 0xf, false); + reconfig_command_read(stage, (uintptr_t)&rPMGR_PS(SIO_P), 0xf0, 0xf0, 255, false); + reconfig_command_write(stage, (uintptr_t)&rPMGR_PS(SIO), 0xf, false); + reconfig_command_read(stage, (uintptr_t)&rPMGR_PS(SIO), 0xf0, 0xf0, 255, false); + + // + // Set all MINIPMGR/ACC/PMGR and static tunables. + // Set PLL and PERF_SOC with MCU REF using bucket 1 (for DCS training) + // + pmgr_aop_ddr_to_awake_post_sequence_insert_pll(); + + // memory tunables + dcs_aop_ddr_to_awake_post_tunables_insert(); + + // Restore board ID and memory info scratch registers to help out tools that rely on them + scratch0 = rPMGR_SCRATCH0 & ~(kPlatformScratchFlagObjectManifestHashValid | kPlatformScratchFlagNonce); + reconfig_command_write(stage, (uintptr_t)&rPMGR_SCRATCH0, scratch0, false); + reconfig_command_write(stage, (uintptr_t)&rPMGR_SCRATCH13, rPMGR_SCRATCH13, false); + + // Need to enable UART0 for early resume serial logging + reconfig_command_write(stage, (uintptr_t)&rPMGR_PS(SIO_P), 0xf, false); + reconfig_command_read(stage, (uintptr_t)&rPMGR_PS(SIO_P), 0xf0, 0xf0, 255, false); + reconfig_command_write(stage, (uintptr_t)&rPMGR_PS(UART0), 0xf, false); + reconfig_command_read(stage, (uintptr_t)&rPMGR_PS(UART0), 0xf0, 0xf0, 255, false); + + // Set and lock IO RVBAR value (reset vector) + if (target != BOOT_DIAGS) { + reconfig_command_write(stage, CCC_CPU0_SYS_BASE_ADDR, TZ1_BASE | 1, 1); + reconfig_command_write(stage, CCC_CPU1_SYS_BASE_ADDR, TZ1_BASE | 1, 1); + } else { /* if (target != BOOT_DIAGS) */ + reconfig_command_write(stage, CCC_CPU0_SYS_BASE_ADDR, DEFAULT_KERNEL_ADDRESS, 1); + reconfig_command_write(stage, CCC_CPU1_SYS_BASE_ADDR, DEFAULT_KERNEL_ADDRESS, 1); + } + + // + // Move to MCU to full performance, CPU to 396MHz, SoC to VMIN and restore full clock mesh + // + pmgr_aop_ddr_to_awake_post_sequence_insert(); + break; + + case D2A_POST_PREBOOT_BEFORE: + // This stitch point is only for debug. + + // Add a breakpoint right before we wake the cores so that we can inspect the system + // after the reconfig program has run + add_breakpoint(stage, 1 << ((stage * 2) + 1)); + break; + } +} + +static void add_breakpoint(reconfig_stage_t stage, int bitmask) +{ +#if DEBUG_BUILD + // Adds a spin on a MINIPMGR scratch register to allow pausing the sequence + // at arbitrary points. To pause the sequence, set the appropriate bit in MINIPMGR_SCRATCH11 + // mem -memap 4 0x2102b802c + reconfig_command_read(stage, (uintptr_t)&rMINIPMGR_SCRATCH11, 0, bitmask, 0, 0); +#else + // Add a dummy spin so that the release sequence and debug sequence don't differ + reconfig_command_read(stage, (uintptr_t)&rMINIPMGR_SCRATCH11, 0, 0, 0, 0); +#endif +} + +// Loops through the DV-provided sections of the sequence, alternating between inserting +// a DV-provided raw sequence into the overall sequence and using the provided callback +// to stitch in software-defined portions of the sequence +static void build_sequence(enum boot_target target, reconfig_stage_t stage, const reconfig_subsequence_t *subseqs, inserter_callback_t *inserter) +{ + int i; + + add_breakpoint(stage, 1 << ((stage * 2) + 0)); + + for (i = 0; subseqs[i].sequence != NULL; i++) { + if (inserter != NULL) { + inserter(target, stage, i); + } + + reconfig_command_raw(stage, subseqs[i].sequence, subseqs[i].elements); + } + + if (inserter != NULL) { + inserter(target, stage, i); + } + + add_breakpoint(stage, 1 << ((stage * 2) + 1)); + + reconfig_commit(stage); +} + +void platform_reconfig_sequence_insert(enum boot_target target) +{ +#if SUB_PLATFORM_S8000 + if(platform_get_chip_revision() < CHIP_REVISION_C0) { + build_sequence(target, AWAKE_AOP_DDR_PRE, reconfig_awake_to_aop_ddr_b0_pre_seqs, awake_to_aop_ddr_pre_sequence_insert); + build_sequence(target, AWAKE_AOP_DDR_POST, reconfig_awake_to_aop_ddr_b0_post_seqs, awake_to_aop_ddr_post_sequence_insert); + build_sequence(target, AOP_DDR_S2R_AOP_PRE, reconfig_aop_ddr_to_s2r_aop_b0_pre_seqs, aop_ddr_to_s2r_aop_pre_sequence_insert); + build_sequence(target, S2R_AOP_AOP_DDR_PRE, reconfig_s2r_aop_to_aop_ddr_b0_pre_seqs, s2r_aop_to_aop_ddr_pre_sequence_insert); + build_sequence(target, S2R_AOP_AOP_DDR_POST, reconfig_s2r_aop_to_aop_ddr_b0_post_seqs, s2r_aop_to_aop_ddr_post_sequence_insert); + build_sequence(target, AOP_DDR_AWAKE_PRE, reconfig_aop_ddr_to_awake_b0_pre_seqs, aop_ddr_to_awake_pre_sequence_insert); + build_sequence(target, AOP_DDR_AWAKE_POST, reconfig_aop_ddr_to_awake_b0_post_seqs, aop_ddr_to_awake_post_sequence_insert); + } else +#elif SUB_PLATFORM_S8003 + if(platform_get_chip_revision() < CHIP_REVISION_A1) { + build_sequence(target, AWAKE_AOP_DDR_PRE, reconfig_awake_to_aop_ddr_a0_pre_seqs, awake_to_aop_ddr_pre_sequence_insert); + build_sequence(target, AWAKE_AOP_DDR_POST, reconfig_awake_to_aop_ddr_a0_post_seqs, awake_to_aop_ddr_post_sequence_insert); + build_sequence(target, AOP_DDR_S2R_AOP_PRE, reconfig_aop_ddr_to_s2r_aop_a0_pre_seqs, aop_ddr_to_s2r_aop_pre_sequence_insert); + build_sequence(target, S2R_AOP_AOP_DDR_PRE, reconfig_s2r_aop_to_aop_ddr_a0_pre_seqs, s2r_aop_to_aop_ddr_pre_sequence_insert); + build_sequence(target, S2R_AOP_AOP_DDR_POST, reconfig_s2r_aop_to_aop_ddr_a0_post_seqs, s2r_aop_to_aop_ddr_post_sequence_insert); + build_sequence(target, AOP_DDR_AWAKE_PRE, reconfig_aop_ddr_to_awake_a0_pre_seqs, aop_ddr_to_awake_pre_sequence_insert); + build_sequence(target, AOP_DDR_AWAKE_POST, reconfig_aop_ddr_to_awake_a0_post_seqs, aop_ddr_to_awake_post_sequence_insert); + } else +#endif + { + build_sequence(target, AWAKE_AOP_DDR_PRE, reconfig_awake_to_aop_ddr_pre_seqs, awake_to_aop_ddr_pre_sequence_insert); + build_sequence(target, AWAKE_AOP_DDR_POST, reconfig_awake_to_aop_ddr_post_seqs, awake_to_aop_ddr_post_sequence_insert); + build_sequence(target, AOP_DDR_S2R_AOP_PRE, reconfig_aop_ddr_to_s2r_aop_pre_seqs, aop_ddr_to_s2r_aop_pre_sequence_insert); + build_sequence(target, S2R_AOP_AOP_DDR_PRE, reconfig_s2r_aop_to_aop_ddr_pre_seqs, s2r_aop_to_aop_ddr_pre_sequence_insert); + build_sequence(target, S2R_AOP_AOP_DDR_POST, reconfig_s2r_aop_to_aop_ddr_post_seqs, s2r_aop_to_aop_ddr_post_sequence_insert); + build_sequence(target, AOP_DDR_AWAKE_PRE, reconfig_aop_ddr_to_awake_pre_seqs, aop_ddr_to_awake_pre_sequence_insert); + build_sequence(target, AOP_DDR_AWAKE_POST, reconfig_aop_ddr_to_awake_post_seqs, aop_ddr_to_awake_post_sequence_insert); + } +} diff --git a/platform/s8000/reconfig_s8000_a1.c b/platform/s8000/reconfig_s8000_a1.c new file mode 100644 index 0000000..29ed0b1 --- /dev/null +++ b/platform/s8000/reconfig_s8000_a1.c @@ -0,0 +1,15 @@ +/* +* Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Gross hack to get around the fact that the header files from DV don't have unique +// names for the A1 and B0 versions of the sequence +#define RECONFIG_S8000_A1 1 +#include "reconfig.c" diff --git a/platform/s8000/rules.mk b/platform/s8000/rules.mk new file mode 100644 index 0000000..323c77f --- /dev/null +++ b/platform/s8000/rules.mk @@ -0,0 +1,176 @@ +# Copyright (C) 2012-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +# Devmap chip ID, CPU, and memory default configs based on sub-platform identifier +ifeq ($(SUB_PLATFORM),s8000) + ARM_CPU := apple-twister + DEVMAP_CHIP_ID := 8000 + DISPLAY_SIZE_DEFAULT := 17*1024*1024 + MAX_DFU_SIZE := 512*1024 + SDRAM_LEN_DEFAULT := 2*1024*1024*1024 + SDRAM_TEXT_BASE := 0x870000000 + SDRAM_TEXT_FOOTPRINT := 1024*1024 + SRAM_TEXT_BASE := 0x180380000 + SRAM_TEXT_FOOTPRINT := 416*1024 + SROM_DATA_BASE := 0x180080000 + SPDS_CHIP_REV := c0 +else ifeq ($(SUB_PLATFORM),s8001) + ARM_CPU := apple-twister + DEVMAP_CHIP_ID := 8001 + DISPLAY_SIZE_DEFAULT := 64*1024*1024 + MAX_DFU_SIZE := 256*1024 + SDRAM_LEN_DEFAULT := 4*1024*1024*1024 + SDRAM_TEXT_BASE := 0x8F0000000 + SDRAM_TEXT_FOOTPRINT := 1024*1024 + SRAM_TEXT_BASE := 0x180000000 + SRAM_TEXT_FOOTPRINT := 304*1024 + SROM_DATA_BASE := 0x180044000 + SPDS_CHIP_REV := b0 +else ifeq ($(SUB_PLATFORM),s8003) + ARM_CPU := apple-twister + DEVMAP_CHIP_ID := 8003 + DISPLAY_SIZE_DEFAULT := 17*1024*1024 + MAX_DFU_SIZE := 512*1024 + SDRAM_LEN_DEFAULT := 2*1024*1024*1024 + SDRAM_TEXT_BASE := 0x870000000 + SDRAM_TEXT_FOOTPRINT := 1024*1024 + SRAM_TEXT_BASE := 0x180380000 + SRAM_TEXT_FOOTPRINT := 416*1024 + SROM_DATA_BASE := 0x180080000 + SPDS_CHIP_REV := a1 +else + $(error "Unrecognized SUB_PLATFORM \"$(SUB_PLATFORM)\"") +endif + +# SROM is always defined here +ifeq ($(TEXT_BANK),srom) + TEXT_BASE := 0x100000000 +endif + +# Overriding SRAM_LEN is not allowed. +ifeq ($(TEXT_BANK),sram) + # SRAM TEXT_BASE is fixed by SecureROM. + TEXT_BASE := $(SRAM_TEXT_BASE) + + # iBSS/LLB memory configuration + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := $(SRAM_TEXT_FOOTPRINT) + endif +endif + +# Platform target can override SDRAM config by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(SDRAM_LEN),) + SDRAM_LEN := $(SDRAM_LEN_DEFAULT) + + # iBoot/iBEC memory configuration + ifeq ($(TEXT_BANK),sdram) + # SDRAM TEXT_BASE is now set such that you don't have to do lots of math to + # calulate the correct value if you change any of the other region sizes: + # TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 256MB + TEXT_BASE := $(SDRAM_TEXT_BASE) + # Platform target can override SRAM config by specifying this in target config file (apps/iBoot/$target-config.mk) + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := $(SDRAM_TEXT_FOOTPRINT) + endif + endif +endif + +# Platform target can override any of these sizes by specifying in target config file (apps/iBoot/$target-config.mk) +ifeq ($(TZ0_SIZE),) + TZ0_SIZE := 12*1024*1024 +endif +ifeq ($(DISPLAY_SIZE),) + DISPLAY_SIZE := $(DISPLAY_SIZE_DEFAULT) +endif + +ifeq ($(TEXT_FOOTPRINT),) + $(error TEXT_FOOTPRINT has not been set) +endif + +# platform target can override ASP size by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(ASP_SIZE),) + ASP_SIZE := 12*1024*1024 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + ANC_PPNNPL_DS_DRIVE_STRENGTH=6 \ + ANC_PPNNPL_INPUT_SELECT_SCHMITT=1 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_HOLD_TIME=2 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_SETUP_TIME=3 \ + ANC_LINK_SDR_DATA_CAPTURE_DELAY=1 \ + ANC_LINK_SDR_CLE_ALE_SETUP_TIME=0 \ + ANC_BOOT_CONTROLLERS=2 \ + ANC_TOGGLE_SUPPORTED=1 \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=288 \ + PLATFORM_SPDS_CHIP_REV=$(SUB_PLATFORM)/$(SPDS_CHIP_REV) \ + PLATFORM_START_FUNCTION=_platform_start \ + SDRAM_LEN="$(SDRAM_LEN)ULL" \ + TZ0_SIZE="$(TZ0_SIZE)ULL" \ + ASP_SIZE="$(ASP_SIZE)" \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" + +# maui/elba: increase device memory carveout to 3 framebuffers + 50% +# only for maui and malta +ifeq ($(SUB_PLATFORM),s8000) + OPTIONS += DISPLAY_SIZE="((((($(DISPLAY_SIZE)ULL)*150)/100)))" + OPTIONS += TARGET_DDR_800M=1 + OPTIONS += TARGET_FB_MULT=45 + OPTIONS += LPDP_LINK_CAL_TABLE_VERSION=2 +else ifeq ($(SUB_PLATFORM),s8001) + OPTIONS += DISPLAY_SIZE="($(DISPLAY_SIZE)ULL)" + OPTIONS += LPDP_LINK_CAL_TABLE_VERSION=3 +else ifeq ($(SUB_PLATFORM),s8003) + OPTIONS += DISPLAY_SIZE="((((($(DISPLAY_SIZE)ULL)*150)/100)))" + OPTIONS += TARGET_DDR_800M=1 + OPTIONS += TARGET_FB_MULT=45 + OPTIONS += LPDP_LINK_CAL_TABLE_VERSION=3 +else + OPTIONS += DISPLAY_SIZE="($(DISPLAY_SIZE)ULL)" +endif + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) + # XXX reconsider this for future platforms to allow DFU space to increase + DATA_BASE := $(SROM_DATA_BASE) + GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) + OPTIONS += \ + WITH_ROM_TRAMPOLINE=1 \ + DATA_BASE="$(DATA_BASE)" + + ifeq ($(CONFIGS),fpga) + OPTIONS += \ + SUPPORT_FPGA=1 + endif + +else # ifeq ($(APPLICATION),SecureROM) + OPTIONS += \ + WITH_MONITOR=1 +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/reconfig.o \ + $(LOCAL_DIR)/trampoline.o diff --git a/platform/s8000/trampoline.S b/platform/s8000/trampoline.S new file mode 100644 index 0000000..6bf069f --- /dev/null +++ b/platform/s8000/trampoline.S @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2012-2014 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#include +#include +#include + +#if DEBUG_BUILD +#define VERIFY_INVALIDATION 1 +#endif + +// Clears from X0 to X1 (not including X1). +// Assumes that X0 and X1 are both 64-byte aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1 +1: + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + cmp x0, x1 + b.lo 1b +.endmacro + +// Clears from X0 to X1 (not including X1) using cacheline clear +// operations. +// Assumes that X0 and X1 are both cacheline aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1_CACHE_ON +1: + dc zva, x0 // zero cacheline + add x0, x0, #L1_CACHELINE_SIZE + cmp x0, x1 + b.lo 1b +.endmacro + + .text + .balign 16 + .globl _boot_handoff_trampoline, _boot_handoff_trampoline_end +_boot_handoff_trampoline: + // Save jump address in x27, and next stage boot info into x28. + mov x27, x0 + mov x28, x1 + + // Disable external aborts, interrupts + msr DAIFSet, #(0xf) + +#if !WITH_CLASSIC_SUSPEND_TO_RAM || !PRODUCT_LLB + // Start by clearing the heap. + ldr x0, L_heap_base + ldr x1, L_heap_end + CLEAR_X0_TO_X1_CACHE_ON + + // Clear the stacks area. + ldr x0, L_stacks_base + ldr x1, L_stacks_end + CLEAR_X0_TO_X1_CACHE_ON +#endif // !WITH_SUSPEND_TO_RAM || !PRODUCT_LLB + + // Retire all instructions executed prior to this (may include ROM). + isb sy + + // Disable caches, mmu, stack alignment fault + mov x3, #0 + msr SCTLR_EL3, x3 + dsb sy + isb sy + + // Flush the TLBs - radar 18269688 + tlbi alle3 + dsb sy + isb sy + + // Now running EL3 with MMU off. All accesses are device, secure. + +#if !WITH_CLASSIC_SUSPEND_TO_RAM || !PRODUCT_LLB + // Clear the page tables. + ldr x0, L_page_tables_base + ldr x1, L_page_tables_end + CLEAR_X0_TO_X1 + +#ifdef BOOT_TRAMPOLINE_BASE + // Clear the text area (or data area in ROM) + // This can only be done if the trampoline was copied to a safe location + ldr x0, L_text_base + ldr x1, L_text_end + CLEAR_X0_TO_X1 + + // Clear all the pointers to interesting memory areas + // that were included in the trampoline + adr x0, L_pointers_base + adr x1, L_pointers_end + CLEAR_X0_TO_X1 +#endif +#endif + +#if WITH_ROM_TRAMPOLINE + // Disable R/W access to ROM region + ldr x1, L_rom_trampoline_reg + ldr w2, L_rom_trampoline_val + ldr w3, [x1] + orr w3, w3, w2 + str w3, [x1] + dsb sy + ldr w3, [x1] + tst w3, w2 // Verify ROM access is disabled + b.eq _trampoline_spin // Oops, not disabled + + // ROM doesn't pass any info to next stage (LLB) + mov x28, #0 +#endif // WITH_ROM_TRAMPOLINE + + // Register format for "dc cisw" is: + // * 32 bit register + // * Ways in the top bits (31 downwards) + // * Sets starting at bit log2(line size) + // * Level specified near the lowest bits. + // E.g for Twister L2 with 64 byte lines, 4K lines, 12 ways: + // [31:28] = way 0..11 + // [27:18] = SBZ + // [17:6] = set 0..4095 (aka "index") + // [5:4] = SBZ + // [3:1] = level = 1 (L2) + // [0] = SBZ + mov x0, #(1 << 1) // x0 = set 0, way 0, level L2 + mov x1, #1 << L2_CACHELINE_SHIFT + mov x2, #1 << (L2_CACHELINE_SHIFT + L2_CACHEINDEX_SHIFT) + mov x3, #1 << (32 - L2_CACHEWAY_SHIFT) + mov x4, #L2_CACHEWAY_COUNT << (32 - L2_CACHEWAY_SHIFT) +1: dc cisw, x0 // Clean-invalidate with x0 + // Increment set field. + add x0, x0, x1 // Increment [16:6] + tst x0, x2 // Test for overflow in [17] + b.eq 1b + // Carry set field into way field. + bic x0, x0, x2 // Clear overflow in [17] + add x0, x0, x3 // Increment [31:29] + cmp x4, x0 // Check [31:29] < number of ways + b.hi 1b + // Carry out of way field ends the loop. + // Another dummy TLBI to act as sDsb. + mov x0, #0 + tlbi ASIDE1IS, x0 + dsb sy + isb sy + +#if VERIFY_INVALIDATION +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 + // Let's "quickly" double-check: all dup-tags should be invalid. + // WARNING: This takes 70 ms when running with quiesced clocks + ldr x0, L_ccu0_addr + bl _verify_invalidated_cp_channel + ldr x0, L_ccu1_addr + bl _verify_invalidated_cp_channel +#elif SUB_PLATFORM_S8001 + // Let's "quickly" double-check: all dup-tags should be invalid. + // WARNING: This takes 140 ms when running with quiesced clocks + ldr x0, L_ccu00_addr + bl _verify_invalidated_cp_channel + ldr x0, L_ccu01_addr + bl _verify_invalidated_cp_channel + ldr x0, L_ccu10_addr + bl _verify_invalidated_cp_channel + ldr x0, L_ccu11_addr + bl _verify_invalidated_cp_channel +#endif +#endif + +#if WITH_ROM_TRAMPOLINE + // Clear remap if enabled to boot this ROM + ldr x1, L_rom_remap_reg + str wzr, [x1] +#endif // WITH_ROM_TRAMPOLINE + + // Reset CPU state + mov x1, #0 + mov x2, #0 + mov x3, #0 + mov x4, #0 + mov x5, #0 + mov x6, #0 + mov x7, #0 + mov x8, #0 + mov x9, #0 + mov x10, #0 + mov x11, #0 + mov x12, #0 + mov x13, #0 + mov x14, #0 + mov x15, #0 + mov x16, #0 + mov x17, #0 + mov x18, #0 + mov x19, #0 + mov x20, #0 + mov x21, #0 + mov x22, #0 + mov x23, #0 + mov x24, #0 + mov x25, #0 + mov x26, #0 + mov x30, x27 // lr = next boot stage PC + mov x0, x28 // x0 = next boot stage info + mov x27, #0 + mov x28, #0 + mov x29, #0 + msr TTBR0_EL3, x1 + msr VBAR_EL3, x1 + msr ELR_EL1, x1 + msr ELR_EL2, x1 + msr ELR_EL3, x1 + msr SPSR_EL1, x1 + msr SPSR_EL2, x1 + msr SPSR_EL3, x1 + msr SP_EL1, x1 + msr SP_EL2, x1 + mov sp, x1 // SP_EL0 + msr SPSel, #1 + mov sp, x1 // SP_EL3 + + // Invalidate I-cache + ic iallu + dsb sy + isb sy + + // Jump to the next stage + ret + +#if VERIFY_INVALIDATION +_verify_invalidated_cp_channel: + // x0 = pointer to base of channel + // Loop over all sets, ways. + mov x1, #((1 << (L2_CACHEINDEX_SHIFT - 1)) * L2_CACHEWAY_COUNT) +1: ldr w2, [x0], #4 // x2 = duptag + ubfx x3, x2, #21, #2 // x3 = duptag[21:20] = state + cmp x3, #0 // Check state=0=invalid + b.ne _trampoline_spin + sub x1, x1, #1 + cmp x1, #0 + b.ne 1b + ret +#endif + +#if WITH_ROM_TRAMPOLINE || VERIFY_INVALIDATION + // Not really able to panic at this point, so let's just spin. +_trampoline_spin: + wfe + b _trampoline_spin +#endif + + .balign 8 +#if VERIFY_INVALIDATION +#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003 +L_ccu0_addr: + .8byte CP_0_DT_DBG_CA0_ADDR +L_ccu1_addr: + .8byte CP_1_DT_DBG_CA0_ADDR +#elif SUB_PLATFORM_S8001 +L_ccu00_addr: + .8byte CP0_0_DT_DBG_CA0_ADDR +L_ccu01_addr: + .8byte CP0_1_DT_DBG_CA0_ADDR +L_ccu10_addr: + .8byte CP1_0_DT_DBG_CA0_ADDR +L_ccu11_addr: + .8byte CP1_1_DT_DBG_CA0_ADDR +#endif +#endif + + +#if WITH_ROM_TRAMPOLINE +L_rom_remap_reg: + .8byte REMAP_REG +L_rom_trampoline_reg: + .8byte SECURITY_REG +L_rom_trampoline_val: + .4byte ROM_READ_DISABLE +#endif // WITH_ROM_TRAMPOLINE + + .balign 64 +L_pointers_base: +#if WITH_ROM_TRAMPOLINE + // in ROM we don't erase TEXT, but we can erase DATA +L_text_base: + .8byte DATA_BASE +L_text_end: + .8byte DATA_BASE + DATA_SIZE +#else + // In non-ROM we erase TEXT_FOOTPRINT, which includes both TEXT and DATA +L_text_base: + .8byte TEXT_BASE +L_text_end: + .8byte TEXT_BASE + TEXT_FOOTPRINT +#endif // WITH_ROM_TRAMPOLINE +L_heap_base: + .8byte HEAP_BASE +L_heap_end: + .8byte HEAP_BASE + HEAP_SIZE +L_stacks_base: + .8byte STACKS_BASE +L_stacks_end: + .8byte STACKS_BASE + STACKS_SIZE +L_page_tables_base: + .8byte PAGE_TABLES_BASE +L_page_tables_end: + .8byte PAGE_TABLES_BASE + PAGE_TABLES_SIZE + .balign 64 +L_pointers_end: + +_boot_handoff_trampoline_end: diff --git a/platform/t7000/amc/amc.c b/platform/t7000/amc/amc.c new file mode 100644 index 0000000..cbc2712 --- /dev/null +++ b/platform/t7000/amc/amc.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + // Don't perform DRAM initializion if the memory controller is already + // initialized (e.g., for SecureROM validation testing). + if (resume || rAMC_AMCEN == 0) { + clock_gate(CLK_MCU, true); + clock_gate(CLK_MCC, true); + clock_gate(CLK_AMP, true); + + amc_init(resume); + } + + return 0; +} + +void mcu_bypass_prep (int step) +{ + amc_phy_bypass_prep(step); +} + +uint64_t mcu_get_memory_size (void) +{ + return amc_get_memory_size(); +} + +void amc_configure_address_decoding_and_mapping(void) +{ + rAMC_MCSADDRBNKHASH(2) = 0x000036db; + rAMC_MCSADDRBNKHASH(1) = 0x00005b6d; + rAMC_MCSADDRBNKHASH(0) = 0x00006db6; + + rAMC_ADDRMAP_MODE = amc_get_params()->addrmapmode; +} + +void amc_enable_slow_boot (bool enable) +{ + if (enable) { + // switch to slow clock + clocks_set_performance(kPerformanceMemoryLow); + spin(1); + } + else { +#if !SUPPORT_FPGA + // switch back to full-speed + clocks_set_performance(kPerformanceMemoryFull); + spin(1); +#endif + } +} + +void amc_finalize (bool resume) +{ + // Enabling clock gating and AutoSR only after wrdqcal is done + rAMC_CLKPWRGATE = 0x050a0000; + rAMC_CLKPWRGATE2 = 0x00660300; + + // Alcatraz, Fiji, Capri: L2_TB: MCU PIO accesses to the same address and device stream getting reordered in CP + platform_memory_barrier(); + + rAMC_PWRMNGTEN &= ~0x00100000; + +#if !SUPPORT_FPGA + rAMC_PWRMNGTEN |= 0x00011011; + + // These 2 values are replaced later in the sequence when tunables are programmed + rAMC_PWRMNGTPARAM = 0x01803000; + rAMC_PSQWQCTL1 = 0x00000120; +#else + rAMC_PWRMNGTEN |= 0x00000010; +#endif +} + +void amc_dram_workarounds (bool resume) +{ + const struct amc_memory_device_info *dev_info; + + dev_info = amc_get_memory_device_info(); + + switch (dev_info->vendor_id) { + case JEDEC_MANUF_ID_HYNIX: + // No work-arounds for Hynix ... yet! + break; + + case JEDEC_MANUF_ID_ELPIDA: + /* Filter only for Elpida 25nm to apply test MRS */ + if ((dev_info->rev_id == 0x2) && (dev_info->rev_id2 <= 0x2)) { // MR6 = 2(25nm) and MR7 = 2(Rev2) + if (!resume) { + // Elpida has no TestMRS entry/exit cmd + // Fiji: Need Duty Cycle Adjust work-around to improve Fiji+Elpida 25nm DDR eye margin + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0xbb); + amc_mrcmd(MR_WRITE, AMC_NUM_CHANNELS, AMC_NUM_RANKS, 0x9, 0x27); + } + } + break; + + default: + break; + } + + return; +} diff --git a/platform/t7000/amc/rules.mk b/platform/t7000/amc/rules.mk new file mode 100644 index 0000000..b6bd0ff --- /dev/null +++ b/platform/t7000/amc/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_AMC=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/amc.o diff --git a/platform/t7000/apcie/apcie_common_regs.h b/platform/t7000/apcie/apcie_common_regs.h new file mode 100644 index 0000000..76616d0 --- /dev/null +++ b/platform/t7000/apcie/apcie_common_regs.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _APCIE_COMMON_REGS_H +#define _APCIE_COMMON_REGS_H + +#include + +#define rAPCIE_PHY_RST_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x040 + (n) * 0x010)) +#define rAPCIE_PHY_CLKREQ_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x044 + (n) * 0x010)) + +#define APCIE_PHY_RST_CTRL_phy_sw_reset (1 << 0) + +#define rAPCIE_NANDSYSCLK_CTRL (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x080)) + +#define rAPCIE_PORT_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x100 + (n) * 0x80)) +#define rAPCIE_PORT_SQUELCH_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x104 + (n) * 0x80)) +#define rAPCIE_PORT_REFCLK_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x108 + (n) * 0x80)) +#define rAPCIE_PORT_OVERRIDE_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x10c + (n) * 0x80)) +#define rAPCIE_PORT_CLKREQ_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x110 + (n) * 0x80)) +#define rAPCIE_PORT_ACG_IDLE_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x114 + (n) * 0x80)) +#define rAPCIE_PORT_RST_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x118 + (n) * 0x80)) +#define rAPCIE_PIPE_OVERRIDE_VAL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x11c + (n) * 0x80)) +#define rAPCIE_PORT_PRIORITY(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x120 + (n) * 0x80)) + +#define APCIE_PORT_CTRL_port_en (1 << 0) +#define APCIE_PORT_CTRL_appclk_auto_dis (1 << 8) +#define APCIE_PORT_CTRL_nvme_en (1 << 16) +#define APCIE_PORT_CTRL_muxed_auxclk_auto_dis (1 << 20) + +#define APCIE_PORT_REFCLK_CTRL_refclk_en (1 << 0) +#define APCIE_PORT_REFCLK_CTRL_refclk_auto_dis (1 << 8) + +#define APCIE_PORT_OVERRIDE_CTRL_pipe_ovr_en (1 << 0) + +#define APCIE_PORT_RST_CTRL_perst_n (1 << 0) + +#define APCIE_PHY_BASE_ADDR(port) (PCI_REG_BASE + 0x1000000 * ((port) + 1) + 0x5000) + +#define rAPCIE_PHY_PHY_REF_USE_PAD(port) (*(volatile uint32_t *)(APCIE_PHY_BASE_ADDR(port) + 0xc3c)) + +#endif + diff --git a/platform/t7000/apcie/apcie_v1.c b/platform/t7000/apcie/apcie_v1.c new file mode 100644 index 0000000..3888606 --- /dev/null +++ b/platform/t7000/apcie/apcie_v1.c @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "apcie_common_regs.h" + +static bool s3e_mode; +static bool s3e_reset_on_enable; +static uint32_t link_enable_count; + +struct apcie_dbi_overrides { + uint32_t offset; + uint32_t mask; + uint32_t value; +}; + +static struct apcie_dbi_overrides apcie_dbi_overrides[] = { + // Enable 64-bit addresses + { 0x024, 0x00000001, 1 }, + // Don't advertise L0s support + { 0x07c, 0x00000400, 0 }, + // Set T_POWER_OFF field in the L1_substates register to 2 () + { 0xb44, 0x00000003, 2 }, +}; + +bool external_refclk; + + +// selects internal vs external refclk. must be called before +// enabling the first link +void apcie_use_external_refclk(bool use) +{ + external_refclk = use; +} + +void apcie_set_s3e_mode(bool reset_on_enable) +{ + s3e_mode = true; + s3e_reset_on_enable = reset_on_enable; +} + +#if !SUB_PLATFORM_T7000 +static void apcie_enable_phy_clkreq(uint32_t phy) +{ + // Note, the function number might change for future platforms + if (phy == 0) { + gpio_configure(GPIO_PCIE_PHY01_CLKREQ, GPIO_CFG_FUNC1); + } else if (phy == 1) { + gpio_configure(GPIO_PCIE_PHY23_CLKREQ, GPIO_CFG_FUNC1); + } else { + panic("apcie: unknown phy %u", phy); + } + rAPCIE_PHY_CLKREQ_CTRL(phy) |= 1; +} + +static void apcie_disable_phy_clkreq(uint32_t phy) +{ + rAPCIE_PHY_CLKREQ_CTRL(phy) &= ~1; + if (phy == 0) { + gpio_configure(GPIO_PCIE_PHY01_CLKREQ, GPIO_CFG_DFLT); + } else if (phy == 1) { + gpio_configure(GPIO_PCIE_PHY23_CLKREQ, GPIO_CFG_DFLT); + } else { + panic("apcie: unknown phy %u", phy); + } +} +#endif + +static void apcie_enable_external_refclk(void) +{ + // Sequence from section 6.1.5 of Fiji/Capri APCIe spec (updated to r1.04.44) + + // 1) Set APCIE_COMMON_APCIE_RST_CTRL_{0/1}.apcie_phy_sw_reset to place the PHY in reset. + for (int i = 0; i < APCIE_NUM_LINKS; i += 2) + rAPCIE_PHY_RST_CTRL(i / 2) |= APCIE_PHY_RST_CTRL_phy_sw_reset; + // 2) To access the PHY, the link shall be enabled. + for (int i = 0; i < APCIE_NUM_LINKS; i+= 2) + rAPCIE_PORT_CTRL(i) |= APCIE_PORT_CTRL_port_en; + // 3) De-assert PERST# to the root controller + for (int i = 0; i < APCIE_NUM_LINKS; i+= 2) + rAPCIE_PORT_RST_CTRL(i) |= APCIE_PORT_RST_CTRL_perst_n; + // 4) Select the external REFCLK + for (int i = 0; i < APCIE_NUM_LINKS; i+= 2) + rAPCIE_PHY_PHY_REF_USE_PAD(i) = 1; + // c) Insert a DMB barrier instruction to insure that the external REFCLK switch occurs + // before the port is disabled. + platform_memory_barrier(); + // 5) Assert PERST# to the root controller + for (int i = 0; i < APCIE_NUM_LINKS; i+= 2) + rAPCIE_PORT_RST_CTRL(i) &= ~APCIE_PORT_RST_CTRL_perst_n; + // 6) Disable the link(s) + for (int i = 0; i < APCIE_NUM_LINKS; i+= 2) + rAPCIE_PORT_CTRL(i) &= ~APCIE_PORT_CTRL_port_en; + // 7) Release the PHY(s) from reset + for (int i = 0; i < APCIE_NUM_LINKS; i += 2) + rAPCIE_PHY_RST_CTRL(i / 2) &= ~APCIE_PHY_RST_CTRL_phy_sw_reset; +} + +static void apcie_enable_root_complex(void) +{ + clock_gate(CLK_PCIE, true); +#if SUB_PLATFORM_T7000 + // Fiji uses the clock mesh for refclk, Capri has a dedicated PLL for refclk + if (!external_refclk) + clock_gate(CLK_PCIE_REF, true); +#endif + clock_gate(CLK_PCIE_AUX, true); + spin(10); + + if (external_refclk) + apcie_enable_external_refclk(); + + if (s3e_mode) { + if (s3e_reset_on_enable) { + gpio_configure(GPIO_S3E_RESETN, GPIO_CFG_OUT_0); + } + + gpio_configure(GPIO_NAND_SYS_CLK, GPIO_CFG_FUNC0); + rAPCIE_NANDSYSCLK_CTRL = 1; + + // S3e spec requires 32 24 Mhz clock cycles from NANDSYSCLK to reset deassertion. + // The Maui spec requires 100 microseconds, so we'll follow that to match the behavior + // we'll be using in Maui + spin(100); + + gpio_configure(GPIO_S3E_RESETN, GPIO_CFG_OUT_1); + } +} + +static void apcie_disable_root_complex(void) +{ + clock_set_device_reset(CLK_PCIE, true); + spin(1); + clock_gate(CLK_PCIE, false); + + clock_set_device_reset(CLK_PCIE, false); +} + +// Implements the enable sequence from APCIe spec section 6.1 as it applies to +// APCIE_COMMON registers. The portion of the sequence that affects the APCIE_CONFIG +// registers is handled in common code +static void apcie_enable_link_hardware(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + dprintf(DEBUG_INFO, "apcie: Enabling link %d%s\n", link, external_refclk ? " with external refclk" : ""); + + // Make sure PERST# starts out as asserted + rAPCIE_PORT_RST_CTRL(link) &= ~APCIE_PORT_RST_CTRL_perst_n; + + // 2) 100Mhz REFCLK is enabled + if (!external_refclk) { + rAPCIE_PORT_REFCLK_CTRL(link) |= APCIE_PORT_REFCLK_CTRL_refclk_en; + +#if !SUB_PLATFORM_T7000 + while(!clock_get_pcie_refclk_good()) + spin(10); +#endif + } else { + // On Capri, the PHY asserts an external clkreq enable GPIO + // when it wants the external refclk to be enabled. On Fiji the + // external refclk is required to always be enabled +#if !SUB_PLATFORM_T7000 + apcie_enable_phy_clkreq(link / 2); +#endif + } + + // 3) 10 us wait + spin(10); + + // 4) Target PCIE link is enabled + rAPCIE_PORT_OVERRIDE_CTRL(link) &= ~APCIE_PORT_OVERRIDE_CTRL_pipe_ovr_en; + rAPCIE_PORT_CTRL(link) |= APCIE_PORT_CTRL_port_en; + +#if SUPPORT_FPGA + rAPCIE_PORT_CTRL(link) |= APCIE_PORT_CTRL_muxed_auxclk_auto_dis; +#endif + + // 5) De-assert PERST# for the target PCIE link. + rAPCIE_PORT_RST_CTRL(link) |= APCIE_PORT_RST_CTRL_perst_n; + + // 6b) DBI register overrides + // Unlock access to the readonly registers + rAPCIE_CONFIG_SPACE32(link, 0x8bc) |= 1; + for (unsigned i = 0; i < sizeof(apcie_dbi_overrides) / sizeof(apcie_dbi_overrides[0]); i++) { + uint32_t offset = apcie_dbi_overrides[i].offset; + uint32_t mask = apcie_dbi_overrides[i].mask; + uint32_t value = apcie_dbi_overrides[i].value; + rAPCIE_CONFIG_SPACE32(link, offset) = (rAPCIE_CONFIG_SPACE32(link, offset) & ~mask) | value; + } + // Lock access to the readonly registers + rAPCIE_CONFIG_SPACE32(link, 0x8bc) &= ~1; +} + +static void apcie_disable_link_hardware(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + rAPCIE_PORT_RST_CTRL(link) &= ~APCIE_PORT_RST_CTRL_perst_n; + rAPCIE_PORT_REFCLK_CTRL(link) &= ~APCIE_PORT_REFCLK_CTRL_refclk_en; + rAPCIE_PORT_CTRL(link) &= ~APCIE_PORT_CTRL_port_en; + rAPCIE_PORT_OVERRIDE_CTRL(link) |= APCIE_PORT_OVERRIDE_CTRL_pipe_ovr_en; +#if !SUB_PLATFORM_T7000 + if (external_refclk) { + // If the other link on this PHY is already disabled, go ahead + // and disable the external refclk settings and GPIO + if ((rAPCIE_PORT_CTRL(link ^ 1) & APCIE_PORT_CTRL_port_en) == 0) { + apcie_disable_phy_clkreq(link / 2); + } + } +#endif +} + + +bool apcie_enable_link(uint32_t link) +{ + struct apcie_link_config *config = &apcie_link_configs[link]; + struct apcie_link_status *status = &apcie_link_statuses[link]; + utime_t start; + uint32_t force_width; + + ASSERT(link < APCIE_NUM_LINKS); + + if (status->enabled) + return true; + + // Clocks to PCIe don't default to on since it isn't used in POR configurations + if (link_enable_count == 0) { + apcie_enable_root_complex(); + } + + // Make sure PERST# starts out as asserted + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + gpio_configure(config->clkreq_gpio, GPIO_CFG_IN); + + // wait for CLKREQ# to be asserted + dprintf(DEBUG_INFO, "apcie: waiting for clkreq..."); + start = system_time(); + while (gpio_read(config->clkreq_gpio) != 0) { + if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) { + dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for CLKREQ# on link %u\n", link); + goto cleanup; + } + spin(1); + } + dprintf(DEBUG_INFO, " done\n"); + + gpio_configure(config->clkreq_gpio, GPIO_CFG_FUNC0); + + // Do required initialization in APCIE_COMMON registers + apcie_enable_link_hardware(link); + + // Apply tunables + rAPCIE_CONFIG_INBCTRL(link) |= APCIE_CONFIG_INBCTRL_CPL_MUST_PUSH_EN; + rAPCIE_CONFIG_OUTBCTRL(link) |= APCIE_CONFIG_OUTBCTRL_EARLY_PT_RESP_EN; + rAPCIE_CONFIG_PMETOACK_TMOTLIM(link) = 0x28; + + // PCIe spec requires a 100 microsecond delay from REFCLK starting + // to PERST being deasserted + spin(100); + + // 5) De-assert PERST# for the target PCIE link. + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_1); + + // Limit link speed to Gen1 + rAPCIE_PCIE_CAP_LINK_CONTROL2(link) = (rAPCIE_PCIE_CAP_LINK_CONTROL2(link) & ~0xfU) | 1; + + // Limit link width if requested by the platform. If the platform returns 0, + // let the hardware autonegotiate the width using its default parameters + force_width = platform_get_pcie_link_width(link); + if (force_width != 0) { + ASSERT(force_width <= 2); + + uint32_t gen2_ctrl; + gen2_ctrl = rAPCIE_PORT_LOGIC_GEN2_CTRL(link); + gen2_ctrl &= ~(0x1ff << 8); + gen2_ctrl |= (force_width << 8); + rAPCIE_PORT_LOGIC_GEN2_CTRL(link) = gen2_ctrl; + + uint32_t port_link_ctrl; + port_link_ctrl = rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(link); + port_link_ctrl &= ~(0x3f << 16); + port_link_ctrl |= ((1 << (force_width - 1)) << 16); + rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(link) = port_link_ctrl; + } + + rAPCIE_COUNTER_COMMAND(link) = APCIE_COUNTER_CLEAR | APCIE_COUNTER_ENABLE; + + // 6c) Software sets LINKCFG.ltssm_en to start link training + rAPCIE_CONFIG_LINKCFG(link) |= APCIE_CONFIG_LINKCFG_LTSSM_EN; + + + start = system_time(); + while ((rAPCIE_CONFIG_LINKSTS(link) & APCIE_CONFIG_LINKSTS_LINK_STATUS) == 0) { + if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) { + uint32_t linkpmgrsts; + dprintf(DEBUG_CRITICAL, "apcie: Timeout waiting for LinkUp on link %u\n", link); + dprintf(DEBUG_CRITICAL, "apcie: LINKSTS 0x%08x\n", rAPCIE_CONFIG_LINKSTS(link)); + linkpmgrsts = rAPCIE_CONFIG_LINKPMGRSTS(link); + dprintf(DEBUG_CRITICAL, "apcie: LINKPMGRSTS 0x%08x (LTSSM state %d)\n", linkpmgrsts, (linkpmgrsts >> 9) & 0x1F); + + goto cleanup; + } + spin(10); + } + + status->enabled = true; + link_enable_count++; + + dart_init(config->dart_id); + + apcie_setup_root_port_bridge(link, config); + + return true; + +cleanup: + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + spin(10); + gpio_configure(config->perst_gpio, GPIO_CFG_DFLT); + gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT); + + apcie_disable_link_hardware(link); + + if (link_enable_count == 0) { + apcie_disable_root_complex(); + } + + return false; +} + +void apcie_disable_link(uint32_t link) +{ + struct apcie_link_config *config = &apcie_link_configs[link]; + struct apcie_link_status *status = &apcie_link_statuses[link]; + utime_t start; + + ASSERT(link < APCIE_NUM_LINKS); + + if (!status->enabled) + return; + + dprintf(DEBUG_INFO, "apcie: Disabling link %d\n", link); + + rAPCIE_COUNTER_COMMAND(link) = 0; + + // Request PMETO and clear the previous status indications + rAPCIE_CONFIG_PMETO(link) = 1 | (3 << 4); + + start = system_time(); + while (rAPCIE_CONFIG_PMETO(link) & 1) { + if (time_has_elapsed(start, 10000)) { + dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for PME_To_Ack, continuing\n"); + break; + } + spin(10); + } + + start = system_time(); + while ((rAPCIE_CONFIG_LINKSTS(link) & APCIE_CONFIG_LINKSTS_L2_STATE) == 0) { + if (time_has_elapsed(start, 10000)) { + dprintf(DEBUG_CRITICAL, "apcie: link did not go into L2, continuing\n"); + break; + } + spin(10); + } + + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + // delay to allow PERST# signal to settle before letting the pulldown hold it low + // and to allow the endpoint to handle PERST# before removing REFCLK + spin(25); + gpio_configure(config->perst_gpio, GPIO_CFG_DFLT); + gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT); + +#if DEBUG_BUILD + dart_assert_unmapped(config->dart_id); +#endif + + apcie_disable_link_hardware(link); + + status->enabled = false; + link_enable_count--; + + if (link_enable_count == 0) { + apcie_disable_root_complex(); + } + + apcie_free_port_bridge(link); +} + +uint32_t apcie_get_link_enable_count(void) +{ + return link_enable_count; +} + +#if WITH_DEVICETREE +void apcie_update_devicetree(DTNode *apcie_node) +{ + uint32_t propSize; + char *propName; + void *propData; + + propName = "dbi-overrides"; + if (FindProperty(apcie_node, &propName, &propData, &propSize)) { + if (propSize < sizeof(apcie_dbi_overrides)) + panic("dbi-overrides property is too small"); + memcpy(propData, apcie_dbi_overrides, sizeof(apcie_dbi_overrides)); + } +} +#endif + +struct apcie_link_config platform_apcie_link_configs[APCIE_NUM_LINKS] = { + [0] = { + .perst_gpio = GPIO_PCIE0_PERST, + .clkreq_gpio = GPIO_PCIE0_CLKREQ, + .dart_id = PCIE_PORT0_DART_ID, + }, + [1] = { + .perst_gpio = GPIO_PCIE1_PERST, + .clkreq_gpio = GPIO_PCIE1_CLKREQ, + .dart_id = PCIE_PORT1_DART_ID, + }, +#if SUB_PLATFORM_T7001 + [2] = { + .perst_gpio = GPIO_PCIE2_PERST, + .clkreq_gpio = GPIO_PCIE2_CLKREQ, + .dart_id = PCIE_PORT2_DART_ID, + }, + [3] = { + .perst_gpio = GPIO_PCIE3_PERST, + .clkreq_gpio = GPIO_PCIE3_CLKREQ, + .dart_id = PCIE_PORT3_DART_ID, + }, +#endif +}; + +void platform_register_pci_busses(void) +{ + apcie_init(); +} + +uint64_t platform_map_host_to_pci_addr(uintptr_t addr) +{ + // Right now we're only supporting 32-bit PCI addresses + // for aPCIe, so just lop off the top 32 bits + return addr & 0xFFFFFFFF; +} + +uintptr_t platform_map_pci_to_host_addr(uint64_t addr) +{ + // Right now we're only supporting 32-bit PCI addresses + // for aPCIe + ASSERT((addr & ~0xFFFFFFFFULL) == 0); + return PCI_32BIT_BASE + (addr & (PCI_32BIT_LEN - 1)); +} diff --git a/platform/t7000/apcie/rules.mk b/platform/t7000/apcie/rules.mk new file mode 100644 index 0000000..b32aed2 --- /dev/null +++ b/platform/t7000/apcie/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/apcie_v1.o \ diff --git a/platform/t7000/asm.S b/platform/t7000/asm.S new file mode 100644 index 0000000..e47c20c --- /dev/null +++ b/platform/t7000/asm.S @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + .text + .align 2 + .globl _platform_start +_platform_start: + //////////////////////////////////////////////// + // Must preserve X0 and X1 + //////////////////////////////////////////////// + + // Enable the L2 cache load/store prefetcher. + mrs x2, s3_0_c15_c5_0 // HID5 + and x2, x2, #~(3<<44) // Enable L2C load (bit 44)/store (bit 45) prefetch + msr s3_0_c15_c5_0, x2 // HID5 + isb + ret + + + .align 2 + .globl _platform_halt +_platform_halt: + + // For Typhoon, we must disable the MTLB prefetcher before doing WFI. + // iBoot: implement Cyclone/Typhoon WFI workaround + + mrs x1, s3_0_c15_c2_0 // Read HID2 + orr x0, x1, #(1 << 13) // Set HID2.DisableMTLBPrefetch + msr s3_0_c15_c2_0, x0 // Write HID2 + dsb sy + isb sy + + wfi + + // Re-enable MTLB prefetcher after WFI falls through. + msr s3_0_c15_c2_0, x1 // Restore HID2 + dsb sy + isb sy + + ret + diff --git a/platform/t7000/chipid/chipid.c b/platform/t7000/chipid/chipid.c new file mode 100644 index 0000000..5f37d76 --- /dev/null +++ b/platform/t7000/chipid/chipid.c @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include + +#define CHIPID_VOLTAGE_FIXED 0 +#define CHIPID_MODE_NONE 0 + +struct chipid_voltage_config { + uint32_t safe_voltage; + uint32_t mode; +}; + +#if SUB_PLATFORM_T7000 || SUB_PLATFORM_T7001 + +#if SUB_PLATFORM_T7000 +static struct chipid_voltage_config chipid_cpu_voltages[] = { + [CHIPID_CPU_VOLTAGE_BYPASS] = {1000, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_SECUREROM] = {1000, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_V0] = { 775, 1}, + [CHIPID_CPU_VOLTAGE_V1] = { 800, 3}, + [CHIPID_CPU_VOLTAGE_V2] = { 880, 4}, + [CHIPID_CPU_VOLTAGE_V3] = { 995, 5}, +#if !SUB_TARGET_N102 + [CHIPID_CPU_VOLTAGE_V4] = {1125, 7}, +#endif +#if SUB_TARGET_J96 || SUB_TARGET_J97 + [CHIPID_CPU_VOLTAGE_V5] = {1195, 8}, +#endif +}; + +static struct chipid_voltage_config chipid_soc_voltages[] = { + [CHIPID_SOC_VOLTAGE_BYPASS] = {950, CHIPID_MODE_NONE}, + [CHIPID_SOC_VOLTAGE_SECUREROM] = {950, CHIPID_MODE_NONE}, + [CHIPID_SOC_VOLTAGE_IBOOT_MEM_LOW_PERF] = {900, CHIPID_MODE_NONE}, + [CHIPID_SOC_VOLTAGE_VMIN] = {900, 1}, + [CHIPID_SOC_VOLTAGE_VNOM] = {950, 2}, +}; + +static struct chipid_voltage_config chipid_gpu_voltages[] = { + [CHIPID_GPU_VOLTAGE_OFF] = { 0, CHIPID_MODE_NONE}, + [CHIPID_GPU_VOLTAGE_V0] = { 900, 1}, + [CHIPID_GPU_VOLTAGE_V0_DIDT] = { 900, 1}, + [CHIPID_GPU_VOLTAGE_V1] = { 950, 2}, + [CHIPID_GPU_VOLTAGE_V1_DIDT] = { 950, 2}, + [CHIPID_GPU_VOLTAGE_V2] = {1050, 3}, + [CHIPID_GPU_VOLTAGE_V2_DIDT] = {1050, 3}, +#if SUB_TARGET_N56 || SUB_TARGET_J42 || SUB_TARGET_J42D || SUB_TARGET_J96 || SUB_TARGET_J97 + [CHIPID_GPU_VOLTAGE_V3] = {1050, 4}, + [CHIPID_GPU_VOLTAGE_V3_DIDT] = {1050, 4}, +#endif +#if SUB_TARGET_J96 || SUB_TARGET_J97 + [CHIPID_GPU_VOLTAGE_V4] = {1010, 5}, + [CHIPID_GPU_VOLTAGE_V4_DIDT] = {1010, 5}, + [CHIPID_GPU_VOLTAGE_V5] = {}, //CHIPID_GPU_VOLTAGE_V5 not used on J96/J97 + [CHIPID_GPU_VOLTAGE_V5_DIDT] = {}, +#endif +}; + +static struct chipid_voltage_config chipid_sram_voltages[] = { +#if SUB_TARGET_N56 || SUB_TARGET_J42 || SUB_TARGET_J42D + [CHIPID_VOLTAGE_FIXED] = {970, 1}, +#else + [CHIPID_VOLTAGE_FIXED] = {950, 1}, +#endif +}; + +#elif SUB_PLATFORM_T7001 +static struct chipid_voltage_config chipid_cpu_voltages[] = { + [CHIPID_CPU_VOLTAGE_BYPASS] = {1000, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_SECUREROM] = {1000, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_V0] = { 775, 1}, + [CHIPID_CPU_VOLTAGE_V1] = { 800, 3}, + [CHIPID_CPU_VOLTAGE_V2] = { 880, 4}, + [CHIPID_CPU_VOLTAGE_V3] = { 980, 5}, + [CHIPID_CPU_VOLTAGE_V4] = {1125, 7}, + [CHIPID_CPU_VOLTAGE_V5] = {1250, 8}, + [CHIPID_CPU_VOLTAGE_V6] = {1200, 9}, + [CHIPID_CPU_VOLTAGE_V6_UNBINNED] = {1200, CHIPID_MODE_NONE}, +}; + +static struct chipid_voltage_config chipid_sram_voltages[] = { + [CHIPID_CPU_VOLTAGE_BYPASS] = { 950, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_SECUREROM] = { 950, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_V0] = { 950, 1}, + [CHIPID_CPU_VOLTAGE_V1] = { 950, 1}, + [CHIPID_CPU_VOLTAGE_V2] = { 950, 1}, + [CHIPID_CPU_VOLTAGE_V3] = { 950, 1}, + [CHIPID_CPU_VOLTAGE_V4] = {1000, 1}, + [CHIPID_CPU_VOLTAGE_V5] = {1000, 2}, + [CHIPID_CPU_VOLTAGE_V6] = {1000, 2}, + [CHIPID_CPU_VOLTAGE_V6_UNBINNED] = {1000, CHIPID_MODE_NONE}, +}; + +// CHIPID_GPU_VOLTAGE_V4 / 600MHz is only used on T7000 +static struct chipid_voltage_config chipid_gpu_voltages[] = { + [CHIPID_GPU_VOLTAGE_OFF] = { 0, CHIPID_MODE_NONE}, + [CHIPID_GPU_VOLTAGE_V0] = { 900, 1}, + [CHIPID_GPU_VOLTAGE_V0_DIDT] = { 900, 1}, + [CHIPID_GPU_VOLTAGE_V1] = { 950, 2}, + [CHIPID_GPU_VOLTAGE_V1_DIDT] = { 950, 2}, + [CHIPID_GPU_VOLTAGE_V2] = {1050, 3}, + [CHIPID_GPU_VOLTAGE_V2_DIDT] = {1050, 3}, + [CHIPID_GPU_VOLTAGE_V3] = {1050, 4}, + [CHIPID_GPU_VOLTAGE_V3_DIDT] = {1050, 4}, + [CHIPID_GPU_VOLTAGE_V5] = {1100, 5}, + [CHIPID_GPU_VOLTAGE_V5_DIDT] = {1100, 5}, +}; + +static struct chipid_voltage_config chipid_gpu_sram_voltages[] = { + [CHIPID_GPU_VOLTAGE_OFF] = { 950, 1}, + [CHIPID_GPU_VOLTAGE_V0] = { 950, 1}, + [CHIPID_GPU_VOLTAGE_V0_DIDT] = { 950, 1}, + [CHIPID_GPU_VOLTAGE_V1] = { 950, 1}, + [CHIPID_GPU_VOLTAGE_V1_DIDT] = { 950, 1}, + [CHIPID_GPU_VOLTAGE_V2] = {1050, 1}, + [CHIPID_GPU_VOLTAGE_V2_DIDT] = {1050, 1}, + [CHIPID_GPU_VOLTAGE_V3] = {1050, 2}, + [CHIPID_GPU_VOLTAGE_V3_DIDT] = {1050, 2}, + [CHIPID_GPU_VOLTAGE_V5] = {1050, 2}, + [CHIPID_GPU_VOLTAGE_V5_DIDT] = {1050, 2}, +}; + +static struct chipid_voltage_config chipid_soc_voltages[] = { + [CHIPID_VOLTAGE_FIXED] = {950, CHIPID_MODE_NONE}, +}; +#endif + +#endif + +#define CHIP_REVISION_ALL 0xff +#define CHIP_ID_ALL 0x00 +struct vol_adj_struct { + uint32_t index; + uint32_t chipid; + uint32_t chiprev; + uint32_t minimum_fuserev; + struct chipid_vol_adj vol_adj; +}; + +static struct vol_adj_struct vol_adj_cpu[] = { +// T7000 b0 and T7001 a0 + {CHIPID_CPU_VOLTAGE_V0, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 31250}}}, + {CHIPID_CPU_VOLTAGE_V0, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 31250}}}, + {CHIPID_CPU_VOLTAGE_V0, 0x7001, CHIP_REVISION_A1, 0, {{ 0, 12500, 25000, 31250}}}, + {CHIPID_CPU_VOLTAGE_V1, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 25000}}}, + {CHIPID_CPU_VOLTAGE_V1, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 25000}}}, + {CHIPID_CPU_VOLTAGE_V1, 0x7001, CHIP_REVISION_A1, 0, {{ 0, 9380, 25000, 31250}}}, + {CHIPID_CPU_VOLTAGE_V2, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 25000}}}, + {CHIPID_CPU_VOLTAGE_V2, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 25000}}}, + {CHIPID_CPU_VOLTAGE_V3, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 25000}}}, + {CHIPID_CPU_VOLTAGE_V3, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 25000}}}, + {CHIPID_CPU_VOLTAGE_V4, 0x7000, CHIP_REVISION_B0, 0, {{ 12500, 12500, 12500, 0}}}, + {CHIPID_CPU_VOLTAGE_V4, 0x7001, CHIP_REVISION_A0, 0, {{ 12500, 12500, 12500, 0}}}, + {CHIPID_CPU_VOLTAGE_V5, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V5, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V6, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V6, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V6_UNBINNED, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V6_UNBINNED, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 0, 0, 0}}}, + +// If not found in previous line, the following will be used, i.e. 7001 a1 and 7000 b1 will use it. + {CHIPID_CPU_VOLTAGE_V0, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 15630, 34380, 40630}}}, + {CHIPID_CPU_VOLTAGE_V1, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 12500, 25000, 31250}}}, + {CHIPID_CPU_VOLTAGE_V2, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 9380, 18750, 18750}}}, + {CHIPID_CPU_VOLTAGE_V3, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 6250, 12500, 12500}}}, + {CHIPID_CPU_VOLTAGE_V4, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V5, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V6, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_CPU_VOLTAGE_V6_UNBINNED, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}}, +}; + +static struct vol_adj_struct vol_adj_soc[] = { + {CHIPID_SOC_VOLTAGE_IBOOT_MEM_LOW_PERF, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_SOC_VOLTAGE_VMIN, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 9400, 18800, 18800}}}, + {CHIPID_SOC_VOLTAGE_VNOM, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 9400, 15600, 9400}}}, + +//If not found in previous line, the following will be used, i.e. 7000 b1 will use it. + {CHIPID_SOC_VOLTAGE_IBOOT_MEM_LOW_PERF, 0x7000, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}}, + {CHIPID_SOC_VOLTAGE_VMIN, 0x7000, CHIP_REVISION_ALL, 0, {{ 0, 12500, 28130, 28130}}}, + {CHIPID_SOC_VOLTAGE_VNOM, 0x7000, CHIP_REVISION_ALL, 0, {{ 0, 9380, 21880, 21880}}}, + +}; + +static uint32_t chipid_get_bin_type(void) +{ + // For Capri FUSE_REV is a combination of CFG_FUSE4[5:0] and bit 287/286 for J82/J99 applications + // Chip fuse286 fuse287 + // 0x7000 0 0 N56/N61 + // 0X7000 1 0 J42 + // 0X7000 0 1 J96/J97/N102 + // 0X7000 0 0 J81/J82 + // 0x7001 1 0 J98/J99 + return (rCFG_FUSE8 >> 30) & 0x3; +} + +// Base Voltage = (Base Fuse + 1) * 25 +static uint32_t chipid_get_base_voltage(void) +{ + uint32_t voltage; + + voltage = (((rCCC_EFUSE_REV >> 24) & 0x1F) + 1) * 25; + +#if SUB_PLATFORM_T7000 + // Fiji B0: Binning information for parts with fuse revision 0x9 Fiji B0:(CoreOs) + if (chipid_get_fuse_revision() == 0x9) + voltage -= 25; +#endif + + return voltage; +} + +static uint32_t chipid_get_cpu_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse; + + switch (mode) { + case 9: + binfuse = (rCCC_EFUSE_DVFM0 >> 0) & 0x7F; + break; + case 1: + binfuse = (rCCC_EFUSE_DVFM0 >> 8) & 0x7F; + break; + case 8: +#if SUB_TARGET_J96 || SUB_TARGET_J97 || SUB_TARGET_N102 + if (chipid_get_bin_type() == 0x0) { + return 0; + } +#endif + binfuse = (rCCC_EFUSE_DVFM0 >> 16) & 0x7F; + break; + case 3: + binfuse = (rCCC_EFUSE_DVFM0 >> 24) & 0x7F; + break; + case 4: + binfuse = (rCCC_EFUSE_DVFM1 >> 0) & 0x7F; + break; + case 5: + binfuse = (rCCC_EFUSE_DVFM1 >> 8) & 0x7F; + break; + case 6: + binfuse = (rCCC_EFUSE_DVFM1 >> 16) & 0x7F; + break; + case 7: + binfuse = (rCCC_EFUSE_DVFM1 >> 24) & 0x7F; + break; + default: + panic("Unsupported CPU mode %d\n", mode); + break; + } + + return binfuse; +} + +#if SUB_PLATFORM_T7000 +static uint32_t chipid_get_soc_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse; + + switch (mode) { + case 1: + binfuse = (rCFG_FUSE7 >> 0) & 0x7F; + break; + case 2: + binfuse = (rCFG_FUSE7 >> 7) & 0x7F; + break; + default: + panic("Unsupported SOC mode %d\n", mode); + break; + } + + return binfuse; +} +#elif SUB_PLATFORM_T7001 +static uint32_t chipid_get_sram_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse; + + switch (mode) { + case 1: + binfuse = (rCFG_FUSE7 >> 0) & 0x7F; + break; + case 2: + binfuse = (rCFG_FUSE7 >> 7) & 0x7F; + break; + default: + panic("Unsupported SRAM mode %d\n", mode); + break; + } + + return binfuse; +} +#endif + +static uint32_t chipid_get_gpu_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse; + + switch (mode) { + case 1: + binfuse = (rCFG_FUSE7 >> 14) & 0x7F; + break; + case 2: + binfuse = (rCFG_FUSE7 >> 21) & 0x7F; + break; +#if SUB_PLATFORM_T7000 + case 3: // CFG[265:259] + binfuse = (rCFG_FUSE8 >> 3) & 0x7F; + break; +#elif SUB_PLATFORM_T7001 + case 3: // CFG[258:252] + binfuse = (rCFG_FUSE7 >> 28) & 0xF; + binfuse |= (rCFG_FUSE8 << 4) & 0x70; + break; +#endif + case 4: // CFG[272:266] + binfuse = (rCFG_FUSE8 >> 10) & 0x7F; + break; +#if SUB_TARGET_J96 || SUB_TARGET_J97 || SUB_TARGET_N102 + case 5: // CFG[279:273] + if (chipid_get_bin_type() == 0x0) { + return 0; + } + binfuse = (rCFG_FUSE8 >> (273 - 256)) & 0x7f; + break; +#else + case 5: // CFG[223:217] + binfuse = (rCFG_FUSE6 >> 25) & 0x7F; + break; +#endif + default: + panic("Unsupported GPU mode %d\n", mode); + break; + } + + return binfuse; +} + +#if SUB_PLATFORM_T7000 +static uint32_t chipid_get_sram_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse; + + switch (mode) { + case 1: + binfuse = (rCFG_FUSE7 >> 28) & 0xF; + binfuse |= (rCFG_FUSE8 << 4) & 0x70; + break; + default: + panic("Unsupported SRAM mode %d\n", mode); + break; + } + + return binfuse; +} +#elif SUB_PLATFORM_T7001 +static uint32_t chipid_get_soc_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse; + + switch (mode) { + case 1: + binfuse = (rCFG_FUSE8 >> 3) & 0x7F; + break; + default: + panic("Unsupported SOC mode %d\n", mode); + break; + } + + return binfuse; +} +#endif + +static uint32_t chipid_get_cpu_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_cpu_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_cpu_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_cpu_binfuse_for_mode(mode); + if (binfuse == 0) + return chipid_cpu_voltages[volt_index].safe_voltage; +#if SUB_TARGET_N102 + if (volt_index == CHIPID_CPU_VOLTAGE_V0) { + // N102: Remove CPU P7 (1392 MHz) and lower CPU P1 voltage by 15mV + return (chipid_get_base_voltage() + binfuse * 5 - 15); + } +#endif + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_soc_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_soc_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_soc_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_soc_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_gpu_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_gpu_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_gpu_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_gpu_binfuse_for_mode(mode); + if (binfuse == 0) + return chipid_gpu_voltages[volt_index].safe_voltage; + + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_sram_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_sram_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_sram_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_sram_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +#if SUB_PLATFORM_T7001 +static uint32_t chipid_get_gpu_sram_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_gpu_sram_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_gpu_sram_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_sram_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +#endif + +bool chipid_get_current_production_mode(void) +{ + return ((rCFG_FUSE0 >> 0) & 1) != 0; +} + +bool chipid_get_raw_production_mode(void) +{ + return ((rCFG_FUSE0_RAW >> 0) & 1) != 0; +} + +void chipid_clear_production_mode(void) +{ + rCFG_FUSE0 &= ~1; +} + +bool chipid_get_secure_mode(void) +{ + // demotion only applies to the SEP, so iBoot always reads + // the raw value for secure mode () + return ((rCFG_FUSE0_RAW >> 1) & 1) != 0; +} + +uint32_t chipid_get_security_domain(void) +{ + return (rCFG_FUSE0 >> 2) & 3; +} + +uint32_t chipid_get_board_id(void) +{ + return (rCFG_FUSE0 >> 4) & 7; +} + +uint32_t chipid_get_minimum_epoch(void) +{ + return (rCFG_FUSE0 >> 9) & 0x7F; +} + +uint32_t chipid_get_pid(void) +{ + return (rCFG_FUSE0 >> 16) & 0x3; +} + +uint32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_T7000 + return 0x7000; +#elif SUB_PLATFORM_T7001 + return 0x7001; +#endif +} + +uint32_t chipid_get_chip_revision(void) +{ + uint32_t chip_rev = (((rCFG_FUSE4 >> 19) & 0x7) << 4) + | (((rCFG_FUSE4 >> 16) & 0x7) << 0); + return chip_rev; +} + +uint32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +uint64_t chipid_get_ecid_id(void) +{ +#if SUPPORT_FPGA + return (0x000012345678ABCDULL); +#else + return ((uint64_t)rECIDHI << 32) | rECIDLO; +#endif +} + +uint64_t chipid_get_die_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint32_t chipid_get_soc_voltage(uint32_t index) +{ + uint32_t soc_voltage; + +#if SUB_PLATFORM_T7001 + index = CHIPID_VOLTAGE_FIXED; +#endif + + if (index >= sizeof(chipid_soc_voltages)/sizeof(chipid_soc_voltages[0])) + panic("Invalid SOC voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + soc_voltage = chipid_soc_voltages[index].safe_voltage; + else + soc_voltage = chipid_get_soc_bin_voltage(index); + + return soc_voltage; +} + +uint32_t chipid_get_cpu_voltage(uint32_t index) +{ + uint32_t cpu_voltage; + + if (index >= sizeof(chipid_cpu_voltages)/sizeof(chipid_cpu_voltages[0])) + panic("Invalid CPU voltage index %d\n", index); + +#if SUB_PLATFORM_T7000 + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + cpu_voltage = chipid_cpu_voltages[index].safe_voltage; + else + cpu_voltage = chipid_get_cpu_bin_voltage(index); +#elif SUB_PLATFORM_T7001 + if (chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION) + cpu_voltage = chipid_get_cpu_bin_voltage(index); + else + cpu_voltage = chipid_cpu_voltages[index].safe_voltage; +#endif + + return cpu_voltage; +} + +uint32_t chipid_get_ram_voltage(uint32_t index) +{ + uint32_t sram_voltage; + +#if SUB_PLATFORM_T7000 + index = CHIPID_VOLTAGE_FIXED; +#endif + + if (index >= sizeof(chipid_sram_voltages)/sizeof(chipid_sram_voltages[0])) + panic("Invalid SRAM voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + sram_voltage = chipid_sram_voltages[index].safe_voltage; + else + sram_voltage = chipid_get_sram_bin_voltage(index); + + return sram_voltage; +} + +uint32_t chipid_get_gpu_ram_voltage(uint32_t index) +{ +#if SUB_PLATFORM_T7000 + panic("GPU SRAM voltage not supported\n"); +#elif SUB_PLATFORM_T7001 + uint32_t gpu_sram_voltage; + + if (index >= sizeof(chipid_gpu_sram_voltages)/sizeof(chipid_gpu_sram_voltages[0])) + panic("Invalid GPU SRAM voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + gpu_sram_voltage = chipid_gpu_sram_voltages[index].safe_voltage; + else + gpu_sram_voltage = chipid_get_gpu_sram_bin_voltage(index); + + return gpu_sram_voltage; +#endif +} + +uint32_t chipid_get_gpu_voltage(uint32_t index) +{ + uint32_t gpu_voltage; + + if (index >= sizeof(chipid_gpu_voltages)/sizeof(chipid_gpu_voltages[0])) + panic("Invalid GPU voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + gpu_voltage = chipid_gpu_voltages[index].safe_voltage; +#if SUB_PLATFORM_T7001 + else if ((index == CHIPID_GPU_VOLTAGE_V4 || index == CHIPID_GPU_VOLTAGE_V4_DIDT) && + chipid_get_fuse_revision() < MINIMUM_BINNED_GPU_P6_REVISION) + gpu_voltage = chipid_get_gpu_bin_voltage(index - 1) + P6_VOL_OFFSET_FROM_P4_BINNING; +#endif + else + gpu_voltage = chipid_get_gpu_bin_voltage(index); + + return gpu_voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return (rCFG_FUSE1 & (1 << 31)) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) { + rCFG_FUSE1 |= (1 << 31); + asm("dsb sy"); + if ((rCFG_FUSE1 & (1 << 31)) == 0) { + panic("Failed to lock fuses\n"); + } + } +} + +uint32_t chipid_get_soc_temp_sensor_trim(uint32_t sensor_index) +{ + uint32_t trim_value = CFG_FUSE2_THERMAL_SEN(sensor_index); + return trim_value; +} + +uint32_t chipid_get_fuse_revision(void) +{ +#if SUB_PLATFORM_T7000 + // For Fiji FUSE_REV is CFG_FUSE4[5:0] +#if SUB_TARGET_J96 || SUB_TARGET_J97 || SUB_TARGET_N102 + if (chipid_get_bin_type() == 0x2) {// J96/J97/N102 binning + // Start at MINIMUM_FUSE_REVISION + 1 = 0x10, to avoid 0x9 fuse revision which has a specific workaround. + return MINIMUM_FUSE_REVISION + 1 + ((rCFG_FUSE4 >> 0) & 0x3f); + } +#endif + return (rCFG_FUSE4 >> 0) & 0x3f; +#elif SUB_PLATFORM_T7001 + // For Capri FUSE_REV is a combination of CFG_FUSE4[5:0] and bit 287 for J82/J99 applications + return (((rCFG_FUSE4 >> 0) & 0x3f) | ((rCFG_FUSE8 >> 31) & 0x1) << 6); +#endif +} + +uint32_t chipid_get_total_rails_leakage() +{ + // FIXME + return 0; +} + +#if SUPPORT_FPGA +uint32_t chipid_get_fpga_block_instantiation(void) +{ + // Hardware blocks instantiated. + uint32_t blocks = (rECID_FUSE7 >> 16) & 0xF; + uint32_t mask = FPGA_HAS_ALWAYS; + +#if SUB_PLATFORM_T7000 + switch (blocks) { + case 0x1: // INT2 + case 0x2: // old "Fiji" endcoding in pre 06_xx_yy_zz bitstream releases + break; + case 0x3: // INT2 + pcie + mask |= FPGA_HAS_PCIE; + break; + case 0x8: // INT2 + VXD + AVE + JPEG + MEDIA + mask |= FPGA_HAS_VXD | FPGA_HAS_AVE | FPGA_HAS_JPEG | FPGA_HAS_MEDIA; + break; + case 0x9: // INT2 + DISP0 + DISP1 + MSR + JPEG + MEDIA + mask |= FPGA_HAS_DISP0 | FPGA_HAS_DISP1 | FPGA_HAS_MSR | FPGA_HAS_JPEG | FPGA_HAS_MEDIA; + break; + case 0xA: // INT2 + GFX + mask |= FPGA_HAS_GFX; + break; + default: + panic("Unknown hardware block instantiation: 0x%x", blocks); + } +#elif SUB_PLATFORM_T7001 // No AVE on Capri FPGA + switch (blocks) { + case 0x1: // INT2 + break; + case 0x8: // INT3 = INT2 + VXD + DISP0 + DISP1 + MEDIA + MSR + JPEG + PCIE + mask |= FPGA_HAS_VXD | FPGA_HAS_DISP0 | FPGA_HAS_DISP1 | FPGA_HAS_MEDIA | FPGA_HAS_MSR | FPGA_HAS_JPEG; // enable PCIE later + break; + case 0xA: // INT3 + GFX + mask |= FPGA_HAS_VXD | FPGA_HAS_DISP0 | FPGA_HAS_DISP1 | FPGA_HAS_MEDIA | FPGA_HAS_MSR | FPGA_HAS_JPEG | FPGA_HAS_GFX; // enable PCIE later + break; + default: + panic("Unknown hardware block instantiation: 0x%x", blocks); + } +#endif + + return mask; +} +#endif + +void chipid_get_vol_adj(enum chipid_vol_adj_type vol_adj_type, uint32_t index, struct chipid_vol_adj * vol_adj) +{ + uint32_t i; + uint32_t chipid = chipid_get_chip_id(); + uint32_t chiprev = chipid_get_chip_revision(); + uint32_t fuserev = chipid_get_fuse_revision(); + switch (vol_adj_type) { + case CHIPID_VOL_ADJ_CPU: + for (i= 0; i < sizeof(vol_adj_cpu)/sizeof(vol_adj_cpu[0]); i++) { + if (vol_adj_cpu[i].index != index) + continue; + if ((vol_adj_cpu[i].chipid != CHIP_ID_ALL) && (vol_adj_cpu[i].chipid != chipid)) + continue; + if ((vol_adj_cpu[i].chiprev != CHIP_REVISION_ALL) && (vol_adj_cpu[i].chiprev != chiprev)) + continue; + if ((vol_adj_cpu[i]).minimum_fuserev > fuserev) + continue; + *vol_adj = vol_adj_cpu[i].vol_adj; + return; + } + panic("%s haven't found CPU index %d for chip %x rev 0x%x\n", __func__, index, chipid, chiprev); + break; + case CHIPID_VOL_ADJ_SOC: + for (i= 0; i < sizeof(vol_adj_soc)/sizeof(vol_adj_soc[0]); i++) { + if (vol_adj_soc[i].index != index) + continue; + if ((vol_adj_soc[i].chipid != CHIP_ID_ALL) && (vol_adj_soc[i].chipid != chipid)) + continue; + if ((vol_adj_soc[i].chiprev != CHIP_REVISION_ALL) && (vol_adj_soc[i].chiprev != chiprev)) + continue; + if ((vol_adj_soc[i]).minimum_fuserev > fuserev) + continue; + *vol_adj = vol_adj_soc[i].vol_adj; + return; + } + panic("%s haven't found SOC Index %d for chip %x rev 0x%x\n", __func__, index, chipid, chiprev); + break; + default: + panic("%s haven't found %d\n", __func__, index); + break; + } +} diff --git a/platform/t7000/chipid/rules.mk b/platform/t7000/chipid/rules.mk new file mode 100644 index 0000000..637efb1 --- /dev/null +++ b/platform/t7000/chipid/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o diff --git a/platform/t7000/error_handler/error_handler.c b/platform/t7000/error_handler/error_handler.c new file mode 100644 index 0000000..cf91221 --- /dev/null +++ b/platform/t7000/error_handler/error_handler.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +// Enables all errors (the remaining bits are perf counters) +#define AMCC_IRERRDBG_INTEN_ALLERRORS ((1 << 20) | (1 << 21) | (1 << 22) | \ + (1 << 23) | (1 << 24) | (1 << 25)) + +#define AMCC_INTSTATUS_ALLERRORS AMCC_IRERRDBG_INTEN_ALLERRORS + +#define AMCC_IERRDBG_INTSTS_DRAM_ONE_BIT_ERR (1 << 21) +#define AMCC_IERRDBG_INTSTS_DRAM_MULTI_BIT_ERR (1 << 22) + +#define AMCC_IRERRDBG_MCCAFERRLOG2_AGENT_MASK (0xFF) +#define AMCC_IRERRDBG_MCCAFERRLOG2_AGENT_IODAP (0x86) + +#define CP_COM_NORM_MSK_CLR_ALL (0xFFFFFFFF) +#define CP_COM_NORM_MSK_ILLEGAL_COH_INTS ((1<<0) | (1<<14)) + +static void amc_int_handler(void *arg __unused) +{ + uint32_t intsts = rAMC_INTSTATUS; + + if ((intsts & (AMCC_IERRDBG_INTSTS_DRAM_ONE_BIT_ERR | AMCC_IERRDBG_INTSTS_DRAM_ONE_BIT_ERR)) == 0) { + // Whitelist errors caused by the IODAP agent (Astris) since + // these are most likely caused by user input errors. + uint32_t agent_id = rAMC_MCCAFERRLOG2 & AMCC_IRERRDBG_MCCAFERRLOG2_AGENT_MASK; + if (agent_id == AMCC_IRERRDBG_MCCAFERRLOG2_AGENT_IODAP) { + dprintf(DEBUG_INFO, "AMC error from IODAP (ignored): 0x%x\n", rAMC_INTSTATUS); + + // Clear the interrupt and continue on. + rAMC_INTSTATUS = intsts; + return; + } + } + + panic("Received unexpected AMC error. AMC_IERRDBG_INTSTATUS = 0x%x\n", rAMC_INTSTATUS); +} + +static void cp_int_handler(void *arg __unused) { + panic("Received unexpected Coherency Point error. CP_COM_INT_NORM_REQUEST = 0x%x\n", rCP_COM_INT_NORM_REQUEST); +} + +static void enable_cp_checks() +{ + install_int_handler(INT_COHERENCE_PNT_ERR, cp_int_handler, NULL); + rCP_COM_INT_NORM_MASK_CLR = CP_COM_NORM_MSK_CLR_ALL; + unmask_int(INT_COHERENCE_PNT_ERR); +} + +static void enable_amc_checks() +{ + install_int_handler(INT_MEM_CONTROLLER, amc_int_handler, NULL); + rAMC_INTEN = AMCC_IRERRDBG_INTEN_ALLERRORS; + if (rAMC_INTSTATUS & AMCC_INTSTATUS_ALLERRORS) { + // AMC Interrupts, unlike the CP ones, don't seem to stick. If an error already exists + // this early in bootup, we won't get an interrupt upon unmask. + amc_int_handler(NULL); + } + rAMC_INTSTATUS = AMCC_INTSTATUS_ALLERRORS; + unmask_int(INT_MEM_CONTROLLER); +} + +void platform_enable_error_handler() { + enable_amc_checks(); + enable_cp_checks(); +} + diff --git a/platform/t7000/error_handler/rules.mk b/platform/t7000/error_handler/rules.mk new file mode 100644 index 0000000..ea5fd03 --- /dev/null +++ b/platform/t7000/error_handler/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PLATFORM_ERROR_HANDLER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/error_handler.o diff --git a/platform/t7000/include/platform/amcconfig.h b/platform/t7000/include/platform/amcconfig.h new file mode 100644 index 0000000..d2e2a28 --- /dev/null +++ b/platform/t7000/include/platform/amcconfig.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include SUB_PLATFORM_HEADER(amcconfig) diff --git a/platform/t7000/include/platform/amcconfig_t7000.h b/platform/t7000/include/platform/amcconfig_t7000.h new file mode 100644 index 0000000..dc0b19a --- /dev/null +++ b/platform/t7000/include/platform/amcconfig_t7000.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050010, + .mcuchnhash = 0x0ffffd54, + .mcschnldec = 0x00010200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000601, + .readleveling = 0x00000300, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, +#if DISPLAY_D600_TUNABLES + { &rAMC_PSQWQCTL1, 0x00000bd4 }, +#else + { &rAMC_PSQWQCTL1, 0x00000158 }, +#endif + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +#if DISPLAY_D600_TUNABLES + { &rAMC_PWRMNGTPARAM, 0x0c003000 }, +#else + { &rAMC_PWRMNGTPARAM, 0x01803000 }, +#endif +}; +#endif diff --git a/platform/t7000/include/platform/amcconfig_t7001.h b/platform/t7000/include/platform/amcconfig_t7001.h new file mode 100644 index 0000000..97db66e --- /dev/null +++ b/platform/t7000/include/platform/amcconfig_t7001.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if WITH_TARGET_AMC_PARAMS +#include +#else +static const struct amc_param amc_params = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x02, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050020, + .mcuchnhash = 0x0ffffd54, + .mcuchnhash2 = 0x0aaaaaa8, + .mcschnldec = 0x00020200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000501, + .readleveling = 0x00000300, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQCTL1, 0x00000336 }, + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, + { &rAMC_PWRMNGTPARAM, 0x03523000 }, +}; +#endif diff --git a/platform/t7000/include/platform/ampconfig.h b/platform/t7000/include/platform/ampconfig.h new file mode 100644 index 0000000..8f5e411 --- /dev/null +++ b/platform/t7000/include/platform/ampconfig.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_phy_params struct is defined in drivers/apple/amp_v3/amp_v3.h, and this + * file should only by included from amp_v3.c. + */ + +#if WITH_TARGET_AMP_PARAMS +#include +#else +static const struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x0101050f, + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x21010509, + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x41010506, + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61010504, + }, + }, +#if SUB_PLATFORM_T7000 + .dqdqsds = 0x00001212, + .nondqds = 0x12124a52, +#else + .dqdqsds = 0x00001414, + .nondqds = 0x14145294, +#endif + .ampclk = 0x00010000, +}; +#endif diff --git a/platform/t7000/include/platform/apcie_regs.h b/platform/t7000/include/platform/apcie_regs.h new file mode 100644 index 0000000..617ddaf --- /dev/null +++ b/platform/t7000/include/platform/apcie_regs.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _APCIE_REGS_H +#define _APCIE_REGS_H + +#include + +#define APCIE_COUNTER_PORT_STRIDE (0x40) +#define APCIE_NUM_COUNTERS (8) + +#define rAPCIE_COUNTER_VALUE(port, n) (*(volatile uint32_t *)(APCIE_COUNTER_BASE_ADDR + (port) * APCIE_COUNTER_PORT_STRIDE + (n) * 4)) +#define rAPCIE_COUNTER_COMMAND(port) (*(volatile uint32_t *)(APCIE_COUNTER_BASE_ADDR + (port) * APCIE_COUNTER_PORT_STRIDE + 0x20)) + +#define APCIE_COUNTER_ENABLE (1) +#define APCIE_COUNTER_CLEAR (2) +#define APCIE_COUNTER_CAPTURE (4) + +#define APCIE_PORT_BASE_ADDR(port) (APCIE_CONFIG_BASE_ADDR + APCIE_CONFIG_PORT_STRIDE * (port)) + +#define rAPCIE_CONFIG_LINKCFG(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x080)) +#define rAPCIE_CONFIG_LINKCTRL(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x084)) +#define rAPCIE_CONFIG_LINKSTS(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x088)) +#define rAPCIE_CONFIG_PMETO(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x08c)) +#define rAPCIE_CONFIG_PMETOACK_TMOTLIM(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x090)) +#define rAPCIE_CONFIG_LTR_THRESH(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x098)) + +#define rAPCIE_CONFIG_INBCTRL(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x130)) +#define rAPCIE_CONFIG_OUTBCTRL(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x134)) +#define rAPCIE_CONFIG_LINKPMGRSTS(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x804)) +#define rAPCIE_CONFIG_LINKCDMSTS(port) (*(volatile uint32_t *)(APCIE_PORT_BASE_ADDR(port) + 0x808)) + +#define APCIE_CONFIG_LINKCFG_LTSSM_EN (1 << 0) +#define APCIE_CONFIG_LINKSTS_LINK_STATUS (1 << 0) +#define APCIE_CONFIG_LINKSTS_CORE_RST_PEND (1 << 1) +#define APCIE_CONFIG_LINKSTS_PIPE_CLK_ACTIVE (1 << 2) +#define APCIE_CONFIG_LINKSTS_CLKREQ_N (1 << 3) +#define APCIE_CONFIG_LINKSTS_L1_STATE (1 << 4) +#define APCIE_CONFIG_LINKSTS_L1_SUBSTATE (1 << 5) +#define APCIE_CONFIG_LINKSTS_L2_STATE (1 << 6) + +#define APCIE_CONFIG_INBCTRL_CPL_MUST_PUSH_EN (1 << 1) +#define APCIE_CONFIG_OUTBCTRL_EARLY_PT_RESP_EN (1 << 0) + +#define rAPCIE_CONFIG_SPACE8(port, offset) (*(volatile uint8_t *)(PCI_CONFIG_BASE + ((port) << PCI_DEVICE_SHIFT) + (offset))) +#define rAPCIE_CONFIG_SPACE16(port, offset) (*(volatile uint16_t *)(PCI_CONFIG_BASE + ((port) << PCI_DEVICE_SHIFT) + (offset))) +#define rAPCIE_CONFIG_SPACE32(port, offset) (*(volatile uint32_t *)(PCI_CONFIG_BASE + ((port) << PCI_DEVICE_SHIFT) + (offset))) + +#define rAPCIE_PCIE_CAP_LINK_CONTROL2(port) rAPCIE_CONFIG_SPACE16(port, 0xa0) +#define rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(port) rAPCIE_CONFIG_SPACE32(port, 0x710) +#define rAPCIE_PORT_LOGIC_GEN2_CTRL(port) rAPCIE_CONFIG_SPACE32(port, 0x80c) + +#if SUB_PLATFORM_T7000 + +#define APCIE_V1_0_COMMON_BASE_ADDR (PCI_REG_BASE) + +#define rAPCIE_V1_0_PORT_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x04)) +#define rAPCIE_V1_0_APP_ACG_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x08)) +#define rAPCIE_V1_0_RST_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x0c)) +#define rAPCIE_V1_0_PORT_PERST_CTRL(n) (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x10 + 4 * n)) +#define rAPCIE_V1_0_AUXCLK_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x20)) +#define rAPCIE_V1_0_REFCLK_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x24)) +#define rAPCIE_V1_0_NANDSYSCLK_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x28)) +#define rAPCIE_V1_0_CLKREQ_OVERRIDE_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x30)) +#define rAPCIE_V1_0_PIPE_OVERRIDE_CTRL (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x34)) +#define rAPCIE_V1_0_PIPE_OVERRIDE_VAL0 (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x38)) +#define rAPCIE_V1_0_PIPE_OVERRIDE_VAL1 (*(volatile uint32_t *)(APCIE_V1_0_COMMON_BASE_ADDR + 0x3c)) + +#define APCIE_V1_0_PORT_CTRL_PORT_EN0 (1 << 0) +#define APCIE_V1_0_PORT_CTRL_PORT_EN1 (1 << 1) +#define APCIE_V1_0_PORT_CTRL_NVME_EN0 (1 << 8) +#define APCIE_V1_0_PORT_CTRL_AUTO_DIS0 (1 << 16) +#define APCIE_V1_0_PORT_CTRL_AUTO_DIS1 (1 << 17) + +#define APCIE_V1_0_RST_CTRL_PHY01_SW_RESET (1 << 0) + +#define APCIE_V1_0_PIPE_OVERRIDE_CTRL_EN0 (1 << 0) +#define APCIE_V1_0_PIPE_OVERRIDE_CTRL_EN1 (1 << 1) + +#define APCIE_V1_0_REFCLK_CTRL_REFCLK_EN0 (1 << 0) +#define APCIE_V1_0_REFCLK_CTRL_REFCLK_EN1 (1 << 1) +#define APCIE_V1_0_REFCLK_CTRL_REFCLK_AUTO_DIS0 (1 << 8) +#define APCIE_V1_0_REFCLK_CTRL_REFCLK_AUTO_DIS1 (1 << 9) + +#endif // SUB_PLATFORM_T7000 + +#endif /* _APCIE_REGS_H */ diff --git a/platform/t7000/include/platform/error_handler.h b/platform/t7000/include/platform/error_handler.h new file mode 100644 index 0000000..e0130ce --- /dev/null +++ b/platform/t7000/include/platform/error_handler.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_ERROR_HANDLER_H +#define __PLATFORM_ERROR_HANDLER_H + +void platform_enable_error_handler(); + +#endif // __PLATFORM_ERROR_HANDLER_H diff --git a/platform/t7000/include/platform/gpiodef.h b/platform/t7000/include/platform/gpiodef.h new file mode 100644 index 0000000..a378512 --- /dev/null +++ b/platform/t7000/include/platform/gpiodef.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +#include +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +#include SUB_PLATFORM_HEADER(gpiodef) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/t7000/include/platform/gpiodef_t7000.h b/platform/t7000/include/platform/gpiodef_t7000.h new file mode 100644 index 0000000..0e87fca --- /dev/null +++ b/platform/t7000/include/platform/gpiodef_t7000.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_T7000_H +#define __PLATFORM_GPIODEF_T7000_H + +#if !SUB_PLATFORM_T7000 +#error "Only include for T7000 platform" +#endif + +/* T7000 specific gpio -> pin mappings - Fiji I/O Spreadsheet v9.3 */ + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_BOARD_ID0 GPIO( 7, 4) // 60 - Alias of GPIO_SPI0_SCLK +#define GPIO_BOARD_ID1 GPIO( 7, 5) // 61 - Alias of GPIO_SPI0_MOSI +#define GPIO_BOARD_ID2 GPIO( 7, 6) // 62 - Alias of GPIO_SPI0_MISO +#define GPIO_BOARD_ID3 GPIO( 6, 4) // 52 +#define GPIO_BOARD_ID4 GPIO( 8, 6) // 70 + +/* Boot configuration pins */ +#define GPIO_BOOT_CONFIG0 GPIO( 6, 6) // 54 +#define GPIO_BOOT_CONFIG1 GPIO( 8, 4) // 68 +#define GPIO_BOOT_CONFIG2 GPIO( 8, 5) // 69 + +/* Boot configuration pin encodings */ +#define BOOT_CONFIG_SPI0 0 +#define BOOT_CONFIG_SPI0_TEST 1 +#define BOOT_CONFIG_ANS 2 +#define BOOT_CONFIG_ANS_TEST 3 +#define BOOT_CONFIG_NVME0 4 +#define BOOT_CONFIG_NVME0_TEST 5 +// #define BOOT_CONFIG_UNUSED 6 +#define BOOT_CONFIG_FAST_SPI0_TEST 7 + +#define GPIO_REQUEST_DFU1 GPIO( 4, 1) // 33 - formerly known as HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 4, 0) // 32 - formerly known as MENU_KEY +#define GPIO_FORCE_DFU GPIO(13, 4) // 108 +#define GPIO_DFU_STATUS GPIO(13, 5) // 109 + +#define SPI_NOR0 (0) + +#define GPIO_SPI0_SCLK GPIO( 7, 4) // 60 +#define GPIO_SPI0_MOSI GPIO( 7, 5) // 61 +#define GPIO_SPI0_MISO GPIO( 7, 6) // 62 +#define GPIO_SPI0_SSIN GPIO( 7, 7) // 63 + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#else +#define GPIO_SPI0_CS GPIO( 7, 7) // 63 - Alias of GPIO_SPI0_SSIN +#endif + +#define GPIO_IIC0_SCL GPIO(12, 1) // 97 +#define GPIO_IIC0_SDA GPIO(12, 0) // 96 +#define GPIO_IIC1_SCL GPIO(17, 3) // 139 +#define GPIO_IIC1_SDA GPIO(17, 2) // 138 +#define GPIO_IIC2_SCL GPIO( 8, 1) // 65 +#define GPIO_IIC2_SDA GPIO( 8, 0) // 64 +#define GPIO_IIC3_SCL GPIO(10, 7) // 87 +#define GPIO_IIC3_SDA GPIO(10, 6) // 86 + +#define GPIO_PCIE0_PERST GPIO( 9, 3) // 75 +#define GPIO_PCIE0_CLKREQ GPIO( 5, 0) // 40 +#define GPIO_PCIE1_PERST GPIO( 9, 5) // 77 +#define GPIO_PCIE1_CLKREQ GPIO( 5, 1) // 41 + +#define GPIO_S3E_RESETN GPIO( 1, 1) // 9 +#define GPIO_NAND_SYS_CLK GPIO( 5, 2) // 42 + +#endif /* ! __PLATFORM_GPIODEF_T7000_H */ diff --git a/platform/t7000/include/platform/gpiodef_t7001.h b/platform/t7000/include/platform/gpiodef_t7001.h new file mode 100644 index 0000000..0303c60 --- /dev/null +++ b/platform/t7000/include/platform/gpiodef_t7001.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_T7001_H +#define __PLATFORM_GPIODEF_T7001_H + +#if !SUB_PLATFORM_T7001 +#error "Only include for T7001 platform" +#endif + +/* T7001 specific gpio -> pin mappings - Capri I/O Spreadsheet v10.29 */ + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_BOARD_ID0 GPIO( 8, 3) // 67 - Alias of GPIO_SPI0_SCLK +#define GPIO_BOARD_ID1 GPIO( 8, 4) // 68 - Alias of GPIO_SPI0_MOSI +#define GPIO_BOARD_ID2 GPIO( 8, 5) // 69 - Alias of GPIO_SPI0_MISO +#define GPIO_BOARD_ID3 GPIO( 12, 0) // 96 +#define GPIO_BOARD_ID4 GPIO( 13, 5) // 109 + +/* Boot configuration pins */ +#define GPIO_BOOT_CONFIG0 GPIO( 12, 2) // 98 +#define GPIO_BOOT_CONFIG1 GPIO( 13, 1) // 105 +#define GPIO_BOOT_CONFIG2 GPIO( 13, 4) // 108 +#define GPIO_BOOT_CONFIG3 GPIO( 13, 7) // 111 + +/* Boot configuration pin encodings */ +#define BOOT_CONFIG_SPI0 0 +#define BOOT_CONFIG_SPI0_TEST 1 +#define BOOT_CONFIG_ANS 2 +#define BOOT_CONFIG_ANS_TEST 3 +#define BOOT_CONFIG_NVME0 4 +#define BOOT_CONFIG_NVME0_TEST 5 +#define BOOT_CONFIG_LOW_POWER_ANS 6 +#define BOOT_CONFIG_FAST_SPI0_TEST 7 +#define BOOT_CONFIG_NVME1 8 +#define BOOT_CONFIG_NVME1_TEST 9 + +#define BOOT_CONFIG_TBT0_EXTREF 10 +#define BOOT_CONFIG_TBT0_EXTREF_TEST 11 +#define BOOT_CONFIG_TBT0_INTREF 12 +#define BOOT_CONFIG_TBT0_INTREF_TEST 13 + +#define GPIO_REQUEST_DFU1 GPIO( 0, 1) // 1 - HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO( 0, 0) // 0 - MENU_KEY +#define GPIO_FORCE_DFU GPIO(13, 2) // 106 +#define GPIO_DFU_STATUS GPIO(13, 3) // 107 + +#define SPI_NOR0 (0) + +#define GPIO_SPI0_SCLK GPIO( 8, 3) // 67 +#define GPIO_SPI0_MOSI GPIO( 8, 4) // 68 +#define GPIO_SPI0_MISO GPIO( 8, 5) // 69 +#define GPIO_SPI0_SSIN GPIO( 8, 6) // 70 + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#else +#define GPIO_SPI0_CS GPIO( 8, 6) // 70 - Alias of GPIO_SPI0_SSIN +#endif + +#define GPIO_IIC0_SCL GPIO(4, 6) // 38 +#define GPIO_IIC0_SDA GPIO(4, 5) // 37 +#define GPIO_IIC1_SCL GPIO(8, 2) // 66 +#define GPIO_IIC1_SDA GPIO(8, 1) // 65 +#define GPIO_IIC2_SCL GPIO( 16, 5) // 133 +#define GPIO_IIC2_SDA GPIO( 16, 4) // 132 +#define GPIO_IIC3_SCL GPIO(16, 7) // 135 +#define GPIO_IIC3_SDA GPIO(16, 6) // 134 + +#define GPIO_PCIE0_PERST GPIO( 22, 2) // 178 +#define GPIO_PCIE0_CLKREQ GPIO( 21, 5) // 173 +#define GPIO_PCIE1_PERST GPIO( 22, 3) // 179 +#define GPIO_PCIE1_CLKREQ GPIO( 21, 6) // 174 +#define GPIO_PCIE2_PERST GPIO( 22, 4) // 180 +#define GPIO_PCIE2_CLKREQ GPIO( 21, 7) // 175 +#define GPIO_PCIE3_PERST GPIO( 22, 5) // 181 +#define GPIO_PCIE3_CLKREQ GPIO( 22, 0) // 176 + +#define GPIO_PCIE_PHY01_CLKREQ GPIO( 21, 1) // 169 +#define GPIO_PCIE_PHY23_CLKREQ GPIO( 21, 0) // 168 + +#define GPIO_S3E_RESETN GPIO( 20, 7) // 167 +#define GPIO_NAND_SYS_CLK GPIO( 22, 1) // 177 + +#endif /* ! __PLATFORM_GPIODEF_T7001_H */ diff --git a/platform/t7000/include/platform/image_devices.h b/platform/t7000/include/platform/image_devices.h new file mode 100644 index 0000000..6b059b2 --- /dev/null +++ b/platform/t7000/include/platform/image_devices.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_HW_ASP) + { "asp_fw", 0x00000 }, +#elif defined(WITH_ANC_FIRMWARE) + { "anc_firmware", 0x00000 }, +#endif +#if defined(WITH_NVME) + { "nvme_firmware0", 0x0000 }, +#endif +#if !defined(WITH_HW_ASP) && !defined(WITH_ANC_FIRMWARE) && !defined(WITH_NVME) + { "nor0", 0x00000 }, +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 }, +#endif +#if defined(WITH_NVME) + { "nvme_syscfg0", 0x0000 }, +#endif +#if !defined(WITH_NAND_BOOT) && !defined(WITH_NVME) + { "nor0", 0x00000 }, +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/t7000/include/platform/memconfig.h b/platform/t7000/include/platform/memconfig.h new file mode 100644 index 0000000..e122f59 --- /dev/null +++ b/platform/t7000/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* T7000 SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/t7000/include/platform/memmap.h b/platform/t7000/include/platform/memmap.h new file mode 100644 index 0000000..8236563 --- /dev/null +++ b/platform/t7000/include/platform/memmap.h @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* T7000 specific memory map (explicit addresses assume standard defaults) */ + +/////////////////////////////////////////////////////////////////////////////////// +// 0x800000000 + dram_size ------------------------------- +// | ASP (varies) | +// | | +// |-----------------------------| +// | TZ1 (512KiB) | +// | | +// |-----------------------------| +// | Consistent Debug (4KiB) | +// |-----------------------------| +// | Sleep Token Buffer (4KiB) | +// |-----------------------------| +// | Panic (512KiB) | +// |-----------------------------| +// | Display | +// | (Framebuffer + scratch) | +// | | +// | | +// |-----------------------------| +// | | +// | iBoot (Heap) | +// | (Variable size depending | +// (Capri) (Fiji) | on DISPLAY_SIZE) | +// 0x870180000 / 0x830180000 --> |-----------------------------| +// | iBoot (Stacks) | +// (Capri) (Fiji) | (STACKS_SIZE) | +// 0x87017C000 / 0x83017C000 --> |-----------------------------| +// | iBoot (Page Tables) | +// (Capri) (Fiji) | (PAGE_TABLES_SIZE) | +// 0x870100000 / 0x830100000 --> |-----------------------------| +// | iBoot (Text + Data) | +// (Capri) (Fiji) | (TEXT_FOOTPRINT) | +// 0x870000000 / 0x830000000 --> |-----------------------------| <-- 0x800000000 + dram_size - 256MB +// | | +// | Unused | +// | | +// |-----------------------------| +// | | +// | (Ramdisk) | +// | (Kernel + DeviceTree) | +// | Secure memory | +// | | +// |-----------------------------| +// | | +// | Load region / | +// | Insecure Memory | +// | (overlaps with TZ0) | |-----------------------------| +// | | | TZ0 (varies) | +// 0x800000000 --> ------------------------------- ------------------------------- +/////////////////////////////////////////////////////////////////////////////////// + +#define SDRAM_BASE (0x800000000ULL) +#define SDRAM_BANK_LEN (SDRAM_LEN) +#define SDRAM_BANK_COUNT (1) +#define SDRAM_END (SDRAM_BASE + SDRAM_LEN) + +// We'll map the DRAM uncached at the end of the cached mapping +#define SDRAM_BASE_UNCACHED (SDRAM_END) + +#define VROM_BASE (0x100000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00080000ULL) +#define VROM_RSVD (0x00100000ULL) // 512 KiB reserved for SecureROM testing, remaining 512 KiB for Data and book-keeping +#define SRAM_BASE (0x180000000ULL) +#if SUB_PLATFORM_T7000 && SUPPORT_FPGA +#define SRAM_LEN (0x000200000ULL) // 2 MiB +#else +#define SRAM_LEN (0x000400000ULL) // 4 MiB +#endif +#define SRAM_BANK_LEN (SRAM_LEN) +#define SRAM_BANK_COUNT (1) +#define SRAM_END (SRAM_BASE + SRAM_LEN) + +#define IO_BASE (0x200000000ULL) +#define IO_SIZE (0x10000000ULL) + +#define PCI_REG_BASE (0x600000000ULL) +#define PCI_REG_LEN (0x6000000ULL) +#define PCI_CONFIG_BASE (0x610000000ULL) +#define PCI_CONFIG_LEN (0x10000000ULL) +#define PCI_32BIT_BASE (0x7C0000000ULL) +#define PCI_32BIT_LEN (0x2000000ULL) // 32 MiB fits nicely into a 32 MiB L2 MMU block + +#define SECUREROM_LOAD_ADDRESS (VROM_BASE) + +/* reserved for ASP */ +// NOTE ASP_SIZE is now defined by the platform or target makefile. +#define ASP_BASE (SDRAM_END - (ASP_SIZE)) + +// Reserved for TZ1/AP Monitor +#define TZ1_SIZE (0x00080000ULL) +#define TZ1_BASE (ASP_BASE - TZ1_SIZE) + +#define CONSISTENT_DEBUG_SIZE (0x00004000ULL) +#define CONSISTENT_DEBUG_BASE (TZ1_BASE - CONSISTENT_DEBUG_SIZE) + +/* reserved area for sleep token info */ +#define SLEEP_TOKEN_BUFFER_SIZE (0x00001000ULL) +#define SLEEP_TOKEN_BUFFER_BASE (CONSISTENT_DEBUG_BASE - SLEEP_TOKEN_BUFFER_SIZE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00080000ULL) +#define PANIC_BASE (SLEEP_TOKEN_BUFFER_BASE - PANIC_SIZE) + +/* reserved area for display */ +// DISPLAY_SIZE comes from platform's rules.mk +#define DISPLAY_BASE (PANIC_BASE - DISPLAY_SIZE) + +// Reserved for TZ0/SEP +// TZ0_SIZE is defined by the platform or target makefile +#define TZ0_BASE (SDRAM_BASE) + +/* where to stick heap and insecure memory */ +#if APPLICATION_SECUREROM + +#define DATA_SIZE (0x00040000ULL) + +#define BOOK_KEEPING_BASE (DATA_BASE + DATA_SIZE) +#define BOOK_KEEPING_SIZE (0x00020000ULL) + +#define BOOT_TRAMPOLINE_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define BOOT_TRAMPOLINE_SIZE (0x1000ULL) + +#define HEAP_BASE (SRAM_BASE + VROM_RSVD) +#if !SUPPORT_FPGA +#define HEAP_SIZE (0x00100000ULL) +#else +#define HEAP_SIZE (0x00080000ULL) +#endif +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#define INSECURE_MEMORY_SIZE (0x00080000ULL) +#define INSECURE_MEMORY_BASE (SRAM_BASE + SRAM_LEN - INSECURE_MEMORY_SIZE) + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT + +#if WITH_DFU_MODE +/* LLB, iBSS DFU */ + +/* reserved area for iBoot */ +#define IBOOT_SIZE (0x01400000ULL) +#define IBOOT_BASE (DISPLAY_BASE - IBOOT_SIZE) + +#define INSECURE_MEMORY_SIZE (IBOOT_SIZE) +#define INSECURE_MEMORY_BASE (IBOOT_BASE) + +// SRAM memory map will usually look like the following: +// +// ROM Testing 0x000000 - 0x100000 (1024 KiB) +// Heap 0x100000 - 0x1FEFFF (1020 KiB) +// Guard 0x1FF000 - 0x1FFFFF ( 4 KiB) +// Unused 0x200000 - 0x37FFFF (1536 KiB) +// Code/Data 0x380000 - 0x3DFFFF ( 384 KiB) +// Page Tables 0x3E0000 - 0x3FBFFF ( 112 KiB) +// Stacks 0x3FC000 - 0x3FFFFF ( 16 KiB) + +#define HEAP_BASE (SRAM_BASE + VROM_RSVD) +#if !SUPPORT_FPGA +#define HEAP_SIZE (0x00100000ULL - PAGE_SIZE) +#else +#define HEAP_SIZE (0x00080000ULL - PAGE_SIZE) +#endif +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) + +#define PAGE_TABLES_BASE (TEXT_BASE + TEXT_FOOTPRINT) +#define PAGE_TABLES_SIZE (STACKS_BASE - PAGE_TABLES_BASE) +#define STACKS_BASE (SRAM_BASE + SRAM_LEN - STACKS_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) + +#else /* !WITH_DFU_MODE */ + +/* iBoot, iBEC */ + +// SDRAM memory map will usually look like the following for T7000: +// +// iBoot Text 0x830000000 - 0x8300FFFFF ( 1 MiB) +// Page Tables 0x830100000 - 0x83017AFFF (492 KiB) +// Stacks 0x83017B000 - 0x83017EFFF ( 16 KiB) +// Boot trampoline 0x83017F000 - 0x83017FFFF ( 4 KiB) +// Heap 0x830180000 - (DISPLAY_BASE - 1 page) +// Guard (DISPLAY_BASE - 1 page) - DISPLAY_BASE + +// And for T7001: +// +// iBoot Text 0x870000000 - 0x8700FFFFF ( 1 MiB) +// Page Tables 0x870100000 - 0x87017BFFF (492 KiB) +// Stacks 0x87017B000 - 0x87017EFFF ( 16 KiB) +// Boot trampoline 0x87017F000 - 0x83017FFFF ( 4 KiB) +// Heap 0x870180000 - (DISPLAY_BASE - 1 page) +// Guard (DISPLAY_BASE - 1 page) - DISPLAY_BASE + +/* reserved area for iBoot */ +#define IBOOT_BASE (TEXT_BASE) +#define IBOOT_SIZE (HEAP_END - IBOOT_BASE) + +#define PAGE_TABLES_BASE (IBOOT_BASE + TEXT_FOOTPRINT) +#define PAGE_TABLES_SIZE (0x0007B000ULL) +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) +#define BOOT_TRAMPOLINE_BASE (STACKS_BASE + STACKS_SIZE) +#define BOOT_TRAMPOLINE_SIZE (PAGE_SIZE) + +#define HEAP_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define HEAP_SIZE (DISPLAY_BASE - HEAP_BASE - PAGE_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) +#if (HEAP_GUARD != (DISPLAY_BASE - PAGE_SIZE)) +#error "Memory map configuration error" +#endif + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_LOAD_SIZE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define SECURE_MEMORY_SIZE (DEFAULT_FREE_ADDRESS - SECURE_MEMORY_BASE) + +/* unused area */ +#define UNUSED_MEMORY_BASE (SECURE_MEMORY_BASE + SECURE_MEMORY_SIZE) +#define UNUSED_MEMORY_SIZE (IBOOT_BASE - UNUSED_MEMORY_BASE) + +#endif /* !WITH_DFU_MODE */ + +#endif /* APPLICATION_IBOOT */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/t7000/include/platform/pcimap.h b/platform/t7000/include/platform/pcimap.h new file mode 100644 index 0000000..63453a0 --- /dev/null +++ b/platform/t7000/include/platform/pcimap.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PCIMAP_H +#define __PLATFORM_PCIMAP_H + +/* S5L8970X specific bus/device/function and PCI base address map */ + +#include + +#define PCIE_PORT0_MEMORY_BASE (PCIE_MEMORY_BASE) +#define PCIE_PORT0_MEMORY_LEN (0x100000ULL) + +#define NVME0_PCI_BDF (PCI_BDF(1, 0, 0)) +#define NVME0_BASE_ADDR (PCIE_PORT0_MEMORY_BASE) +#define NVME0_SIZE (0x2000) +#define NVME0_DART_ID (PCIE_PORT0_DART_ID) + + +#endif /* ! __PLATFORM_PCIMAP_H */ diff --git a/platform/t7000/include/platform/pinconfig.h b/platform/t7000/include/platform/pinconfig.h new file mode 100644 index 0000000..6446dfc --- /dev/null +++ b/platform/t7000/include/platform/pinconfig.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include SUB_PLATFORM_HEADER(pinconfig) diff --git a/platform/t7000/include/platform/pinconfig_t7000.h b/platform/t7000/include/platform/pinconfig_t7000.h new file mode 100644 index 0000000..e0d7524 --- /dev/null +++ b/platform/t7000/include/platform/pinconfig_t7000.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default T7000 SoC Pin Configuration - Fiji I/O Spreadsheet v9.3 */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // ULPI_DIR -> + CFG_DISABLED, // ULPI_STP -> + CFG_DISABLED, // ULPI_NXT -> + CFG_DISABLED, // ULPI_DATA7 -> + CFG_DISABLED, // ULPI_DATA6 -> + CFG_DISABLED, // ULPI_DATA5 -> + CFG_DISABLED, // ULPI_DATA4 -> + CFG_DISABLED, // ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // ULPI_DATA3 -> + CFG_DISABLED, // ULPI_DATA2 -> + CFG_DISABLED, // ULPI_DATA1 -> + CFG_DISABLED, // ULPI_DATA0 -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_IN, // GPIO11 -> REQUEST_DFU2 (formerly known as MENU_KEY) + CFG_IN, // GPIO12 -> REQUEST_DFU1 (formerly known as HOLD_KEY) + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // CLK32K_OUT -> + +/* Port 5 */ + CFG_DISABLED, // PCIE_CLKREQ0_N -> + CFG_DISABLED, // PCIE_CLKREQ1_N -> + CFG_DISABLED, // NAND_SYS_CLK -> + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + +/* Port 6 */ + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO20 -> + +/* Port 7 */ + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // UART5_RTXD -> + CFG_DISABLED, // UART8_TXD -> + CFG_DISABLED, // UART8_RXD -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> + +/* Port 8 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOARD_ID[4] + CFG_DISABLED, // GPIO34 -> + +/* Port 9 */ + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO39 -> + CFG_DISABLED, // GPIO42 -> + CFG_DISABLED, // GPIO43 -> + CFG_DISABLED, // DISP_VSYNC -> + CFG_DISABLED, // UART0_TXD -> + +/* Port 10 */ + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + +/* Port 11 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 12 */ + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // DWI_DO -> + +/* Port 13 */ + CFG_DISABLED, // DWI_CLK -> + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO19 -> + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + +/* Port 14 */ + CFG_DISABLED, // CPU_SLEEP_STATUS -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO15 -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + +/* Port 15 */ + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO30 -> + +/* Port 16 */ + CFG_DISABLED, // GPIO31 -> + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO40 -> + CFG_DISABLED, // GPIO41 -> + CFG_DISABLED, // I2S4_MCK -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + +/* Port 17 */ + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 18 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 19 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 20 */ + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + +/* Port 21 */ + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + +/* Port 22 */ + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // EDP_HPD -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 23 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + +/* Port 24 */ + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // ISP_UART0_TXD -> + CFG_DISABLED, // ISP_UART0_RXD -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_DISABLED, // UART7_TXD -> + CFG_DISABLED, // UART7_RXD -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/t7000/include/platform/pinconfig_t7001.h b/platform/t7000/include/platform/pinconfig_t7001.h new file mode 100644 index 0000000..1fdb776 --- /dev/null +++ b/platform/t7000/include/platform/pinconfig_t7001.h @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +/* Default T7001 SoC Pin Configuration - Capri I/O Spreadsheet v10.29 */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + +/* Port 1 */ + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RTXD -> + CFG_DISABLED, // DWI0_DO -> + CFG_DISABLED, // DWI0_CLK -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2S0_LRCK -> + +/* Port 5 */ + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + +/* Port 6 */ + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // DISP_VSYNC -> + +/* Port 7 */ + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + CFG_DISABLED, // CPU_SLEEP_STATUS -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // ISP_UART0_TXD -> + CFG_DISABLED, // ISP_UART0_RXD -> + CFG_DISABLED, // UART7_TXD -> + +/* Port 8 */ + CFG_DISABLED, // UART7_RXD -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED, // SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED, // SPI0_MISO -> BOARD_ID2 + CFG_DISABLED, // SPI0_SSIN -> + CFG_DISABLED, // I2S3_MCK -> + +/* Port 9 */ + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + +/* Port 10 */ + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 11 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 12 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID3 + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG0 + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 13 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG1 + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG2 + CFG_DISABLED, // GPIO29 -> BOARD_ID4 + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> BOOT_CONFIG3 + +/* Port 14 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 15 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // UART8_TXD -> + CFG_DISABLED, // UART8_RXD -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + +/* Port 17 */ + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + +/* Port 18 */ + CFG_DISABLED, // EDP_HPD -> + CFG_DISABLED, // I2S4_MCK -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + +/* Port 19 */ + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + CFG_DISABLED, // CLK32K_OUT -> + CFG_DISABLED, // ULPI_DIR -> + +/* Port 20 */ + CFG_DISABLED, // ULPI_STP -> + CFG_DISABLED, // ULPI_NXT -> + CFG_DISABLED, // ULPI_DATA7 -> + CFG_DISABLED, // ULPI_DATA6 -> + CFG_DISABLED, // ULPI_DATA5 -> + CFG_DISABLED, // ULPI_DATA4 -> + CFG_DISABLED, // ULPI_CLK -> + CFG_DISABLED, // ULPI_DATA3 -> + +/* Port 21 */ + CFG_DISABLED, // ULPI_DATA2 -> + CFG_DISABLED, // ULPI_DATA1 -> + CFG_DISABLED, // ULPI_DATA0 -> + CFG_DISABLED, // DWI1_DO -> + CFG_DISABLED, // DWI1_CLK -> + CFG_DISABLED, // PCIE_CLKREQ0_N -> + CFG_DISABLED, // PCIE_CLKREQ1_N -> + CFG_DISABLED, // PCIE_CLKREQ2_N -> + +/* Port 22 */ + CFG_DISABLED, // PCIE_CLKREQ3_N -> + CFG_DISABLED, // NAND_SYS_CLK -> + CFG_DISABLED, // PCIE_PERST0_N -> + CFG_DISABLED, // PCIE_PERST1_N -> + CFG_DISABLED, // PCIE_PERST2_N -> + CFG_DISABLED, // PCIE_PERST3_N -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> +}; + +#endif /* ! __PLATFORM_PINCONFIG_H */ diff --git a/platform/t7000/include/platform/soc/ccc.h b/platform/t7000/include/platform/soc/ccc.h new file mode 100644 index 0000000..f357d64 --- /dev/null +++ b/platform/t7000/include/platform/soc/ccc.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_CCC_H +#define __PLATFORM_SOC_CCC_H + +#define rCCC_CPU0_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x000)) +#define rCCC_CPU0_IMPL_CPU_IOACC_CTL_EL3 (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x008)) +#define rCCC_CPU0_IMPL_FED_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x010)) +#define rCCC_CPU0_IMPL_LSU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x018)) +#define rCCC_CPU0_IMPL_MMU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + 0x020)) + +#define CCC0_IMPL_BASE_ADDR (CCC0_SYS_BASE_ADDR + 0x40000) +#define rCCC_CCC_IMPL_CPM_IOACC_CTL_EL3 (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x000)) +#define rCCC_CCC_IMPL_L2C_ERR_STS (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x008)) +#define rCCC_CCC_IMPL_L2C_ERR_ADR (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x010)) +#define rCCC_CCC_IMPL_L2C_ERR_INF (*(volatile u_int64_t *)(CCC0_IMPL_BASE_ADDR + 0x018)) + +#define rCCC_CPU1_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU1_SYS_BASE_ADDR + 0x000)) +#define rCCC_CPU2_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU2_SYS_BASE_ADDR + 0x000)) + +#endif /* __PLATFORM_SOC_CCC_H */ diff --git a/platform/t7000/include/platform/soc/chipid.h b/platform/t7000/include/platform/soc/chipid.h new file mode 100644 index 0000000..cfd389e --- /dev/null +++ b/platform/t7000/include/platform/soc/chipid.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include +#include + +#define rCFG_FUSE0 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x00)) +#define rCFG_FUSE1 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x04)) +#define rCFG_FUSE2 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x08)) +#define rCFG_FUSE3 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x0C)) +#define rCFG_FUSE4 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x10)) +#define rCFG_FUSE5 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x14)) +#define rCFG_FUSE6 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x18)) +#define rCFG_FUSE7 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x1C)) +#define rCFG_FUSE8 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x20)) +#define rCFG_FUSE9 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x24)) +#define rCFG_FUSE15 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x3C)) + +#if SUB_PLATFORM_T7001 +#define CFG_FUSE8_PCIE_REF_PLL_VREG_ADJ_SHIFT (24) +#define CFG_FUSE8_PCIE_REF_PLL_VREG_ADJ_MASK (0x7) +#endif + +#if SUB_PLATFORM_T7000 +#define MINIMUM_FUSE_REVISION 0x9 +#elif SUB_PLATFORM_T7001 +// Fuse Rev 0x2 means Capri A1 or later. +// So all binning are against Capri A1 in "Capri Test Plan Version 1.1" +#define MINIMUM_FUSE_REVISION 0x2 +// Fuse Rev 0x41 means Capri with updated binning for J99 P5 and P6. +#define MINIMUM_BINNED_GPU_P6_REVISION 0x41 +#define P6_VOL_OFFSET_FROM_P4_BINNING 143 +#endif + +#define CFG_FUSE9_PLL_VCO_RCTRL_SEL (0x8) // VCO_RCTRL_OW value is valid if set +#define CFG_FUSE9_PLL_VCO_RCTRL_OW_MASK (0x7) // PLL analog override value if valid + +#define CFG_FUSE9_PLL_0_SHIFT (0) +#define CFG_FUSE9_PLL_1_SHIFT (4) +#define CFG_FUSE9_PLL_2_SHIFT (8) +#define CFG_FUSE9_PLL_3_SHIFT (12) +#define CFG_FUSE9_PLL_4_SHIFT (16) +#define CFG_FUSE9_PLL_5_SHIFT (20) +#define CFG_FUSE9_PLL_CPU_SHIFT (24) +#define CFG_FUSE9_PLL_LPDP_SHIFT (28) + +#define CFG_FUSE2_THERMAL_SEN_MASK (0x1f) +#define CFG_FUSE2_THERMAL_SEN_SHIFT(_idx) (5 * (_idx)) +#define CFG_FUSE2_THERMAL_SEN(_idx) ((rCFG_FUSE2 >> CFG_FUSE2_THERMAL_SEN_SHIFT(_idx)) & CFG_FUSE2_THERMAL_SEN_MASK) + +#define rECIDLO (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x80)) +#define rECIDHI (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x84)) + +#define rSEP_SECURITY (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x104)) + +#define rCFG_FUSE0_RAW (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x200)) + +#define CHIPID_SOC_VOLTAGE_BYPASS (0) +#define CHIPID_SOC_VOLTAGE_SECUREROM (1) +#define CHIPID_SOC_VOLTAGE_IBOOT_MEM_LOW_PERF (2) +#define CHIPID_SOC_VOLTAGE_VMIN (3) +#define CHIPID_SOC_VOLTAGE_VNOM (4) + +uint32_t chipid_get_soc_voltage(uint32_t index); + + +/* Wahtever is the platform CHIPID_GPU_VOLTAGE_V0_DIDT index + * will always follows immediatly the last CHIPID_GPU_VOLTAGE_V[0-9] + * So, CHIPID_GPU_VOLTAGE_V0_DIDT will also be the number of regular voltages, + * i.e. all voltages excepts DIDT ones.*/ +#if SUB_TARGET_N56 || SUB_TARGET_J42 || SUB_TARGET_J42D +#define CHIPID_GPU_VOLTAGE_OFF (0) +#define CHIPID_GPU_VOLTAGE_V0 (1) +#define CHIPID_GPU_VOLTAGE_V1 (2) +#define CHIPID_GPU_VOLTAGE_V2 (3) +#define CHIPID_GPU_VOLTAGE_V3 (4) +#define CHIPID_GPU_VOLTAGE_V0_DIDT (5) +#define CHIPID_GPU_VOLTAGE_V1_DIDT (6) +#define CHIPID_GPU_VOLTAGE_V2_DIDT (7) +#define CHIPID_GPU_VOLTAGE_V3_DIDT (8) +#elif SUB_PLATFORM_T7001 || SUB_TARGET_J96 || SUB_TARGET_J97 +#define CHIPID_GPU_VOLTAGE_OFF (0) +#define CHIPID_GPU_VOLTAGE_V0 (1) +#define CHIPID_GPU_VOLTAGE_V1 (2) +#define CHIPID_GPU_VOLTAGE_V2 (3) +#define CHIPID_GPU_VOLTAGE_V3 (4) +#define CHIPID_GPU_VOLTAGE_V4 (5) +#define CHIPID_GPU_VOLTAGE_V5 (6) +#define CHIPID_GPU_VOLTAGE_V0_DIDT (7) +#define CHIPID_GPU_VOLTAGE_V1_DIDT (8) +#define CHIPID_GPU_VOLTAGE_V2_DIDT (9) +#define CHIPID_GPU_VOLTAGE_V3_DIDT (10) +#define CHIPID_GPU_VOLTAGE_V4_DIDT (11) +#define CHIPID_GPU_VOLTAGE_V5_DIDT (12) +#define CHIPID_GPU_VOLTAGE_V_UVD CHIPID_GPU_VOLTAGE_V5 +#else +#define CHIPID_GPU_VOLTAGE_OFF (0) +#define CHIPID_GPU_VOLTAGE_V0 (1) +#define CHIPID_GPU_VOLTAGE_V1 (2) +#define CHIPID_GPU_VOLTAGE_V2 (3) +#define CHIPID_GPU_VOLTAGE_V0_DIDT (4) +#define CHIPID_GPU_VOLTAGE_V1_DIDT (5) +#define CHIPID_GPU_VOLTAGE_V2_DIDT (6) +#endif + +uint32_t chipid_get_gpu_voltage(uint32_t index); + +#define CHIPID_CPU_VOLTAGE_BYPASS (0) +#define CHIPID_CPU_VOLTAGE_SECUREROM (1) +#define CHIPID_CPU_VOLTAGE_V0 (2) +#define CHIPID_CPU_VOLTAGE_V1 (3) +#define CHIPID_CPU_VOLTAGE_V2 (4) +#define CHIPID_CPU_VOLTAGE_V3 (5) +#define CHIPID_CPU_VOLTAGE_V4 (6) +#define CHIPID_CPU_VOLTAGE_V5 (7) +// Currently pmgr expect any CHIPID_CPU_VOLTAGE_V* to be +// an index in the DVFM table. So, between 0 and 7. +// It will no more be the case for 1.6GHz +// who would be CHIPID_CPU_VOLTAGE_V6 or CHIPID_CPU_VOLTAGE_V6_UNBINNED. +#define CHIPID_CPU_VOLTAGE_V6 (8) +#define CHIPID_CPU_VOLTAGE_V6_UNBINNED (9) + + +uint32_t chipid_get_cpu_voltage(uint32_t index); + +uint32_t chipid_get_ram_voltage(uint32_t index); + +uint32_t chipid_get_gpu_ram_voltage(uint32_t index); + +int32_t chipid_get_cpu_temp_offset(uint32_t cpu_number); + +uint32_t chipid_get_soc_temp_sensor_trim(uint32_t sensor_index); + +uint32_t chipid_get_fuse_revision(void); + +uint32_t chipid_get_total_rails_leakage(void); + +enum chipid_vol_adj_type { + CHIPID_VOL_ADJ_CPU, + CHIPID_VOL_ADJ_SOC, +}; + +struct chipid_vol_adj { + uint32_t region_uV[4]; +}; +void chipid_get_vol_adj(enum chipid_vol_adj_type vol_adj_type, uint32_t index, struct chipid_vol_adj * vol_adj); + +#if SUPPORT_FPGA + +#define FPGA_HAS_ALWAYS (1 << 0) +#define FPGA_HAS_VXD (1 << 1) +#define FPGA_HAS_AVE (1 << 2) +#define FPGA_HAS_ISP (1 << 3) +#define FPGA_HAS_DISP0 (1 << 4) +#define FPGA_HAS_DISP1 (1 << 5) +#define FPGA_HAS_MSR (1 << 6) +#define FPGA_HAS_JPEG (1 << 7) +#define FPGA_HAS_GFX (1 << 8) +#define FPGA_HAS_MEDIA (1 << 9) +#define FPGA_HAS_PCIE (1 << 10) + +#define rECID_FUSE7 (*(volatile uint32_t *)(CHIPID_BASE_ADDR + 0x9c)) + +uint32_t chipid_get_fpga_block_instantiation(void); + +#endif // SUPPORT_FPGA + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/t7000/include/platform/soc/display.h b/platform/t7000/include/platform/soc/display.h new file mode 100644 index 0000000..a45c9e8 --- /dev/null +++ b/platform/t7000/include/platform/soc/display.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include SUB_PLATFORM_HEADER(soc/display) + diff --git a/platform/t7000/include/platform/soc/display_t7000.h b/platform/t7000/include/platform/soc/display_t7000.h new file mode 100644 index 0000000..d22d2e0 --- /dev/null +++ b/platform/t7000/include/platform/soc/display_t7000.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ +#if DISPLAY_IPHONE_TUNABLES +#if DISPLAY_D600_TUNABLES + { + .name = "D600", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x617), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x1082) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x61d), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x60d), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x453), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x443), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = 0, + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_D600_TUNABLES + + +#if DISPLAY_D500_TUNABLES || DISPLAY_D410_TUNABLES + { +#if DISPLAY_D500_TUNABLES + .name = "D500", +#else + .name = "D410", +#endif + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x282), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x17c5) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x280), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x278), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x1c5), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x1bd), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = 0, + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_D500_TUNABLES || DISPLAY_D410_TUNABLES + +#if DISPLAY_D403_TUNABLES + { + .name = "D403", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x1BF), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x74A) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x1C5), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x1B5), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x144), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x134), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = 0, + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif // DISPLAY_D403_TUNABLES + +#if DISPLAY_D500_2LANE_TUNABLES + { + .name = "D500_2LANE", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x282), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x17c5) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x280), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x278), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x1c5), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x1bd), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = 0, + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_D500_2LANE_TUNABLES +#endif //DISPLAY_IPHONE_TUNABLES + +//Tunables for targets using the the timing based on landscape ipads +#if DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES + { + .name = "default", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x547), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x159a) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x54d), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x53d), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x3a9), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x399), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = 0, + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + +#if DISPLAY_IPHONE_TUNABLES +#error DISPLAY_IPHONE_TUNABLES set for IPAD +#endif + +#endif //DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/t7000/include/platform/soc/display_t7001.h b/platform/t7000/include/platform/soc/display_t7001.h new file mode 100644 index 0000000..cfe8ace --- /dev/null +++ b/platform/t7000/include/platform/soc/display_t7001.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ +//Tunables for targets using the the timing based on landscape ipads +#if DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES +#if DISPLAY_X136_TUNABLES + { + .name = "default", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x904), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0xff8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x1a24) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x90e), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x8fa), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x63e), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x62a), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x30) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, + + { + // XXX - needs updated with correct values! + .name = "camelia", + .disp_dpcclkcntl = (0), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x800), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x800), + .disp_dpcqoscfg = (0), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0), + .disp_dpclinkdown = (0), + .disp_dpgpreqaggr = (0), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x18)), + .disp_dpcenab = (0), + }, +#endif + +#if !DISPLAY_X136_TUNABLES + { + .name = "default", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x547), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0xff8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x15b5) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x545), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x53d), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x3a1), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x399), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0x30) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //!DISPLAY_X136_TUNABLES + +#if DISPLAY_IPHONE_TUNABLES +#error DISPLAY_IPHONE_TUNABLES set for IPAD +#endif + +#endif //DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/t7000/include/platform/soc/display_timings.h b/platform/t7000/include/platform/soc/display_timings.h new file mode 100644 index 0000000..928a72f --- /dev/null +++ b/platform/t7000/include/platform/soc/display_timings.h @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_TYPHONIC + { + .display_name = "D403", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 61540000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 6, + .h_back_porch = 4, + .h_front_porch = 32, + .v_active = 1136, + .v_pulse_width = 3, + .v_back_porch = 13, + .v_front_porch = 352, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_N102 + { + .display_name = "D410", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 61540000, + .dot_pitch = 326, + .h_active = 640, + .h_pulse_width = 6, + .h_back_porch = 4, + .h_front_porch = 32, + .v_active = 1136, + .v_pulse_width = 3, + .v_back_porch = 13, + .v_front_porch = 352, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_N61 || SUB_TARGET_TYPHONIC + { + .display_name = "D500", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 88890000, + .dot_pitch = 326, + .h_active = 750, + .h_pulse_width = 6, + .h_back_porch = 28, + .h_front_porch = 4, + .v_active = 1334, + .v_pulse_width = 3, + .v_back_porch = 4, + .v_front_porch = 540, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_N56 + { + .display_name = "D600", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 326, + .h_active = 1080, + .h_pulse_width = 2, + .h_back_porch = 4, + .h_front_porch = 146, + .v_active = 1920, + .v_pulse_width = 3, + .v_back_porch = 5, + .v_front_porch = 778, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_T7000FPGA || SUB_TARGET_T7001FPGA + { + .display_name = "fpga-wsvga", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 5000000, + .dot_pitch = 243, + .h_active = 1024, + .h_pulse_width = 50, + .h_back_porch = 50, + .h_front_porch = 51, + .v_active = 600, + .v_pulse_width = 50, + .v_back_porch = 218, + .v_front_porch = 6, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 18, + .display_type = DISPLAY_TYPE_DUMB, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_J96 || SUB_TARGET_J97 + { + .display_name = "ipad5", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 326, + .h_active = 1536, + .h_pulse_width = 16, + .h_back_porch = 48, + .h_front_porch = 12, + .v_active = 2048, + .v_pulse_width = 4, + .v_back_porch = 8, + .v_front_porch = 8, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_J81 || SUB_TARGET_J82 || SUB_TARGET_T7001PADSIM + { + .display_name = "ipad4", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 264, + .h_active = 1536, + .h_pulse_width = 15, + .h_back_porch = 52, + .h_front_porch = 16, + .v_active = 2048, + .v_pulse_width = 1, + .v_back_porch = 3, + .v_front_porch = 7, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_J98 || SUB_TARGET_J99 + { + .display_name = "ipad5c", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 400000000, + .dot_pitch = 326, + .h_active = 2732, + .h_pulse_width = 20, + .h_back_porch = 56, + .h_front_porch = 16, + .v_active = 2048, + .v_pulse_width = 2, + .v_back_porch = 4, + .v_front_porch = 307, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, + + { + .display_name = "j99POC", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 342857142, + .dot_pitch = 326, + .h_active = 2732, + .h_pulse_width = 16, + .h_back_porch = 52, + .h_front_porch = 16, + .v_active = 2048, + .v_pulse_width = 4, + .v_back_porch = 2, + .v_front_porch = 6, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_EDP, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || WITH_HW_DISPLAY_DISPLAYPORT + { + .display_name = "720p", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 110, + .h_front_porch = 220, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 5, + .v_front_porch = 20, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_DP, + .display_config = NULL, + }, + { + .display_name = "720p-e86", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 110, + .h_front_porch = 220, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 5, + .v_front_porch = 20, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_DP, + .display_config = NULL, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/t7000/include/platform/soc/hwclocks.h b/platform/t7000/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..dc4f013 --- /dev/null +++ b/platform/t7000/include/platform/soc/hwclocks.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (5000000UL) +#else +#define OSC_FREQ (24000000UL) +#endif + +// Start from an offset of 128. So that we are safely outside the PS indexes. +#define CLK_FCLK (HWCLOCK_BASE+128) +#define CLK_ACLK (HWCLOCK_BASE+129) +#define CLK_HCLK (HWCLOCK_BASE+130) +#define CLK_PCLK (HWCLOCK_BASE+131) +#define CLK_VCLK0 (HWCLOCK_BASE+132) +#define CLK_VCLK1 (HWCLOCK_BASE+133) +#define CLK_MCLK (HWCLOCK_BASE+134) +#define CLK_NCLK (HWCLOCK_BASE+135) +#define CLK_USBPHYCLK (HWCLOCK_BASE+136) +#define CLK_NCOREF (HWCLOCK_BASE+137) +#define CLK_ANS_LINK (HWCLOCK_BASE+138) + +/* + * T7000 clock gate devices. + * Refers to the ps register offsets. + */ +enum { // enum : reg + CLK_CPU0, // 0: 0x20000 + CLK_CPU1, // 1: 0x20008 +#if SUB_PLATFORM_T7001 + CLK_CPU2, // 1: 0x20010 +#endif + CLK_CPM = 8, // 8: 0x20040 + CLK_LIO = 32, // 32: 0x20100 + CLK_IOMUX, // 33: 0x20108 + CLK_AIC, // 34: 0x20110 + CLK_DEBUG, // 35: 0x20118 + CLK_DWI, // 36: 0x20120 + CLK_GPIO, // 37: 0x20128 + CLK_MCA0, // 38: 0x20130 + CLK_MCA1, // 39: 0x20138 + CLK_MCA2, // 40: 0x20140 + CLK_MCA3, // 41: 0x20148 + CLK_MCA4, // 42: 0x20150 + CLK_PWM0, // 43: 0x20158 + CLK_I2C0, // 44: 0x20160 + CLK_I2C1, // 45: 0x20168 + CLK_I2C2, // 46: 0x20170 + CLK_I2C3, // 47: 0x20178 + CLK_SPI0, // 48: 0x20180 + CLK_SPI1, // 49: 0x20188 + CLK_SPI2, // 50: 0x20190 + CLK_SPI3, // 51: 0x20198 + CLK_UART0, // 52: 0x201a0 + CLK_UART1, // 53: 0x201a8 + CLK_UART2, // 54: 0x201b0 + CLK_UART3, // 55: 0x201b8 + CLK_UART4, // 56: 0x201c0 + CLK_UART5, // 57: 0x201c8 + CLK_UART6, // 58: 0x201d0 + CLK_UART7, // 59: 0x201d8 + CLK_UART8, // 60: 0x201e0 + CLK_AES0, // 61: 0x201e8 + CLK_SIO, // 62: 0x201f0 + CLK_SIO_P, // 63: 0x201f8 + CLK_HSIC0PHY, // 64: 0x20200 + CLK_HSIC1PHY, // 65: 0x20208 + CLK_ISPSENS0, // 66: 0x20210 + CLK_ISPSENS1, // 67: 0x20218 + CLK_PCIE_REF, // 68: 0x20220 + CLK_ANP, // 69: 0x20228 + CLK_MCC, // 70: 0x20230 + CLK_MCU, // 71: 0x20238 + CLK_AMP, // 72: 0x20240 + CLK_USB, // 73: 0x20248 + CLK_USBCTLREG, // 74: 0x20250 + CLK_USB2HOST0, // 75: 0x20258 + CLK_USB2HOST0_OHCI, // 76: 0x20260 + CLK_USB2HOST1, // 77: 0x20268 + CLK_USB2HOST1_OHCI, // 78: 0x20270 + CLK_USB2HOST2, // 79: 0x20278 + CLK_USB2HOST2_OHCI, // 80: 0x20280 + CLK_USB_OTG, // 81: 0x20288 + CLK_SMX, // 82: 0x20290 + CLK_SF, // 83: 0x20298 + CLK_CP, // 84: 0x202a0 +#if SUB_PLATFORM_T7000 + CLK_DISP_BUSMUX, // 85: 0x202a8 +#elif SUB_PLATFORM_T7001 + CLK_DISP0_BUSIF, // 85: 0x202a8 +#endif + CLK_DISP0, // 86: 0x202b0 +#if SUB_PLATFORM_T7000 + CLK_MIPI_DSI, // 87: 0x202b8 + CLK_MIPI = CLK_MIPI_DSI, + CLK_DP, // 88: 0x202c0 + CLK_EDPLINK = CLK_DP, + CLK_DPLINK = CLK_DP, +#elif SUB_PLATFORM_T7001 + CLK_DP, // 87: 0x202b8 + CLK_EDPLINK = CLK_DP, + CLK_DPLINK = CLK_DP, + CLK_DISP1_BUSIF, // 88: 0x202c0 +#endif + CLK_DISP1, // 89: 0x202c8 + CLK_ISP, // 90: 0x202d0 + CLK_MEDIA, // 91: 0x202d8 + CLK_MSR, // 92: 0x202e0 + CLK_JPG, // 93: 0x202e8 + CLK_VDEC0, // 94: 0x202f0 + CLK_UNUSED_0, // 95: 0x202f8 UNUSED + CLK_VENC_CPU, // 96: 0x20300 + CLK_PCIE, // 97: 0x20308 + CLK_PCIE_AUX, // 98: 0x20310 + CLK_ANS, // 99: 0x20318 + CLK_GFX, // 100: 0x20320 + + PMGR_LAST_DEVICE, + PMGR_FIRST_DEVICE = CLK_LIO, + CLK_SEP = 128, // 128: 0x20400 + CLK_VENC_PIPE = 512, // 512: 0x21000 + CLK_VENC_ME0, // 513: 0x21008 + CLK_VENC_ME1, // 514: 0x21010 +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/t7000/include/platform/soc/hwisr.h b/platform/t7000/include/platform/soc/hwisr.h new file mode 100644 index 0000000..0555faa --- /dev/null +++ b/platform/t7000/include/platform/soc/hwisr.h @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define INT_SW0 0 // 0x00: Software 0 Interrupt +#define INT_SW1 1 // 0x01: Software 1 Interrupt +#define INT_SW2 2 // 0x02: Software 2 Interrupt +#define INT_SW3 3 // 0x03: Software 3 Interrupt +#define INT_WDT 4 // 0x04: Watchdog Timer Interrupt +#define INT_DWI 5 // 0x05: DWI Interrupt +#define INT_PMGR_PERF_CNTRS 6 // 0x06: PMGR Performace Counters Interrupt +#define INT_THERM_TEMP0 7 // 0x07: Thermal Temp 0 Interrupt +#define INT_THERM_ALARM0 8 // 0x08: Thermal Alarm 0 Interrupt +#define INT_THERM_TEMP1 9 // 0x09: Thermal Temp 1 Interrupt +#define INT_THERM_ALARM1 10 // 0x0a: Thermal Alarm 1 Interrupt + +// Reserved 11 - 21 + +#define INT_CPM_THERM_TEMP 22 // 0x16: CPM Thermal temp Interrupt +#define INT_CPM_THERM_ALARM 23 // 0x17: CPM Thermal alarm Interrupt +#define INT_CPU0_THERM_TEMP 24 // 0x18: CPU0 Thermal temp Interrupt +#define INT_CPU0_THERM_ALARM 25 // 0x19: CPU0 Thermal alarm Interrupt +#define INT_CPU1_THERM_TEMP 26 // 0x1a: CPU1 Thermal temp Interrupt +#define INT_CPU1_THERM_ALARM 27 // 0x1b: CPU1 Thermal alarm Interrupt +#if SUB_PLATFORM_T7001 +#define INT_CPU2_THERM_TEMP 28 // 0x1c: CPU2 Thermal temp Interrupt +#define INT_CPU2_THERM_ALARM 29 // 0x1d: CPU2 Thermal alarm Interrupt +#endif + +// Reserved 28 - 35 (T7000) +// Reserved 30 - 35 (T7001) + +#define INT_ANS_KF_INBOX_EMPTY 36 // 0x24: ANS KF Inbox Empty Interrupt +#define INT_ANS_KF_INBOX_NOTEMPTY 37 // 0x25: ANS KF Inbox Not Empty Interrupt +#define INT_ANS_KF_OUTBOX_EMPTY 38 // 0x26: ANS KF Outbox Empty Interrupt +#define INT_ANS_KF_OUTBOX_NOTEMPTY 39 // 0x27: ANS KF Outbox Not Empty Interrupt +#define INT_ANS_CHNL0 40 // 0x28: ANS Channel 0 Interrupt +#define INT_ANS_CHNL1 41 // 0x29: ANS Channel 1 Interrupt + +// Reserved 42 - 46 + +#define INT_THERM_FS_ACT0 47 // 0x2f: Thermal Failsafe Active 0 Interrupt +#define INT_THERM_FS_ACT1 48 // 0x30: Thermal Failsafe Active 1 Interrupt +#define INT_THERM_FS_EXT0 49 // 0x31: Thermal Failsafe Exit 0 Interrupt +#define INT_THERM_FS_EXT1 50 // 0x32: Thermal Failsafe Exit 1 Interrupt +#define INT_SOC_THERM_FS_ACT0 51 // 0x33: SoC Thermal Failsafe Active 0 Interrupt +#define INT_SOC_THERM_FS_ACT1 52 // 0x34: SoC Thermal Failsafe Active 1 Interrupt + +// Reserved 53 - 54 + +#define INT_CTM_TRIGGER0 55 // 0x37: CTM Trigger 0 Interrupt +#define INT_CTM_TRIGGER1 56 // 0x38: CTM Trigger 1 Interrupt +#define INT_CTM_TRIGGER2 57 // 0x39: CTM Trigger 2 Interrupt +#define INT_CTM_TRIGGER3 58 // 0x3a: CTM Trigger 3 Interrupt +#define INT_COHERENCE_PNT_ERR 59 // 0x3b: Coherence Point Error Interrupt +#define INT_COHERENCE_PNT_PERF_CNTRS 60 // 0x3c: Coherence Point Performance Counters Interrupt + +// Reserved 61 + +#define INT_GPIO_CLASS0 62 // 0x3e: GPIO Class 0 Interrupt +#define INT_GPIO_CLASS1 63 // 0x3f: GPIO Class 1 Interrupt +#define INT_GPIO_CLASS2 64 // 0x40: GPIO Class 2 Interrupt +#define INT_GPIO_CLASS3 65 // 0x41: GPIO Class 3 Interrupt +#define INT_GPIO_CLASS4 66 // 0x42: GPIO Class 4 Interrupt +#define INT_GPIO_CLASS5 67 // 0x43: GPIO Class 5 Interrupt +#define INT_GPIO_CLASS6 68 // 0x44: GPIO Class 6 Interrupt + +// Reserved 61 + +#define INT_MEM_CONTROLLER 70 // 0x46: Memory Controller MCC Interrupt +#define INT_MCU 71 // 0x47: Memory Controller MCU Interrupt + +// Reserved 72 + +#define INT_CPU0_COMM_TX 73 // 0x49: CPU 0 COMM TX Interrupt +#define INT_CPU0_COMM_RX 74 // 0x4a: CPU 0 COMM RX Interrupt +#define INT_CPU0_PMU_IRQ 75 // 0x4b: CPU 0 PMU IRQ Interrupt +#define INT_CPU1_COMM_TX 76 // 0x4c: CPU 1 COMM TX Interrupt +#define INT_CPU1_COMM_RX 77 // 0x4d: CPU 1 COMM RX Interrupt +#define INT_CPU1_PMU_IRQ 78 // 0x4e: CPU 1 PMU IRQ Interrupt +#if SUB_PLATFORM_T7001 +#define INT_CPU2_COMM_TX 79 // 0x4f: CPU 2 COMM TX Interrupt +#define INT_CPU2_COMM_RX 80 // 0x50: CPU 2 COMM RX Interrupt +#define INT_CPU2_PMU_IRQ 81 // 0x51: CPU 2 PMU IRQ Interrupt +#endif + +// Reserved 79 - 84 (T7000) +// Reserved 82 - 84 (T7001) + +#define INT_CCC_UNIFIED_TRIGGER 85 // 0x55: CCC Unified Trigger Interrupt + +// Reserved 86 + +#define INT_ISP_KF_INBOX_EMPTY 87 // 0x57: ISP KF Inbox Empty Interrupt +#define INT_ISP_KF_INBOX_NOTEMPTY 88 // 0x58: ISP KF Inbox Not Empty Interrupt +#define INT_ISP_KF_OUTBOX_EMPTY 89 // 0x59: ISP KF Outbox Empty Interrupt +#define INT_ISP_KF_OUTBOX_NOTEMPTY 90 // 0x5a: ISP KF Outbox Not Empty Interrupt +#define INT_ISP0 91 // 0x5b: ISP 0 Interrupt +#define INT_ISP1 92 // 0x5c: ISP 1 Interrupt +#define INT_ISP2 93 // 0x5d: ISP 2 Interrupt +#define INT_ISP3 94 // 0x5e: ISP 3 Interrupt +#define INT_ISP_DART 95 // 0x5f: ISP DART Interrupt + +// Reserved 96 + +#define INT_SEP_KF_INBOX_EMPTY 97 // 0x61: SEP KF Inbox Empty Interrupt +#define INT_SEP_KF_INBOX_NOTEMPTY 98 // 0x62: SEP KF Inbox Not Empty Interrupt +#define INT_SEP_KF_OUTBOX_EMPTY 99 // 0x63: SEP KF Outbox Empty Interrupt +#define INT_SEP_KF_OUTBOX_NOTEMPTY 100 // 0x64: SEP KF Outbox Not Empty Interrupt +#define INT_SEP_AUTH_ERROR 101 // 0x65: SEP Authentication Error Interrupt +#define INT_SEP_CRIT_PATH_MONITOR 102 // 0x66: SEP Critical Path Monitor Interrupt +#define INT_DISP0 103 // 0x67: Display 0 Interrupt +#define INT_DISP0_PARTIAL_FRAME 104 // 0x68: Display 0 Partial Frame Interrupt +#define INT_DISP0_PERF_CNTRS 105 // 0x69: Display 0 Performace Counters Interrupt +#define INT_DISP0_DART 106 // 0x6a: Display 0 DART Interrupt +#define INT_DISP0_SMMU 107 // 0x6b: Display 0 SMMU Interrupt +#define INT_DISP0_BACK_END_BLU 108 // 0x6c: Display 0 Back End Back Light Update Interrupt +#define INT_DISP0_BACK_END_VBI 109 // 0x6d: Display 0 Back End VBI Interrupt +#define INT_DISP0_BACK_END_VFTG 110 // 0x6e: Display 0 Back End VFTG Idle Interrupt +#define INT_DISP0_BACK_END_VBL 111 // 0x6f: Display 0 Back End VBL counter Interrupt +#if SUB_PLATFORM_T7000 +#define INT_MIPIDSI0 112 // 0x70: MIPI DSI 0 Interrupt +#define INT_MIPIDSI1 113 // 0x71: MIPI DSI 1 Interrupt +#define INT_DISPLAY_PORT 114 // 0x72: Display Port +#define INT_EDP0 INT_DISPLAY_PORT +#define INT_DPORT0 INT_DISPLAY_PORT +#else +#define INT_DISPLAY_PORT 112 // 0x70: Display Port +#define INT_EDP0 INT_DISPLAY_PORT +#define INT_DPORT0 INT_DISPLAY_PORT +#endif +#define INT_DISP1 115 // 0x73: Display 1 Interrupt +#define INT_DISP1_PARTIAL_FRAME 116 // 0x74: Display 1 Partial Frame Interrupt +#define INT_DISP1_PERF_CNTRS 117 // 0x75: Display 1 Performace Counters Interrupt +#define INT_DISP1_DART 118 // 0x76: Display 1 DART Interrupt +#define INT_DISP1_SMMU 119 // 0x77: Display 1 SMMU Interrupt +#define INT_VDEC0 120 // 0x78: Video Decoder 0 Interrupt + +// Reserved 121 - 122 + +#define INT_AVE_KF_INBOX_EMPTY 123 // 0x7b: AVE KF Inbox Empty Interrupt +#define INT_AVE_KF_INBOX_NOTEMPTY 124 // 0x7c: AVE KF Inbox Not Empty Interrupt +#define INT_AVE_KF_OUTBOX_EMPTY 125 // 0x7d: AVE KF Outbox Empty Interrupt +#define INT_AVE_KF_OUTBOX_NOTEMPTY 126 // 0x7e: AVE KF Outbox Not Empty Interrupt +#define INT_AVE_DART 127 // 0x7f: AVE DART Interrupt +#define INT_AVE_SMMU 128 // 0x80: AVE SMMU Interrupt +#define INT_AVE 129 // 0x81: AVE Interrupt +#define INT_SVE_SYNC 130 // 0x82: SVE Driver Synchronization Interrupt + +// Reserved 131 - 133 + +#define INT_GFX 134 // 0x86: GFX Interrupt +#define INT_GFX_SLEEP 135 // 0x87: GFX Sleep Interrupt +#define INT_GFX_WAKE 136 // 0x88: GFX Wake Interrupt +#define INT_GFX_CHG 137 // 0x89: GFX Change Interrupt + +// Reserved 138 + +#define INT_JPEG 139 // 0x8b: JPEG Interrupt +#define INT_JPEG_DART 140 // 0x8c: JPEG DART Interrupt +#define INT_JPEG_DART_PERF 141 // 0x8d: JPEG DART Performance Interrupt + +// Reserved 142 + +#define INT_MSR 143 // 0x8f: MSR Interrupt +#define INT_MSR_SMMU 144 // 0x90: MSR SMMU Interrupt +#define INT_MSR_DART 145 // 0x91: MSR DART Interrupt +#define INT_MSR_DAR_PERF 146 // 0x92: MSR DART Performance Interrupt + +// Reserved 147 + +#define INT_SIO_KF_INBOX_EMPTY 148 // 0x94: SIO KF Inbox Empty Interrupt +#define INT_SIO_KF_INBOX_NOTEMPTY 149 // 0x95: SIO KF Inbox Not Empty Interrupt +#define INT_SIO_KF_OUTBOX_EMPTY 150 // 0x96: SIO KF Outbox Empty Interrupt +#define INT_SIO_KF_OUTBOX_NOTEMPTY 151 // 0x97: SIO KF Outbox Not Empty Interrupt +#define INT_SPI0 152 // 0x98: SPI 0 Interrupt +#define INT_SPI1 153 // 0x99: SPI 1 Interrupt +#define INT_SPI2 154 // 0x9a: SPI 2 Interrupt +#define INT_SPI3 155 // 0x9b: SPI 3 Interrupt + +// Reserved 156 - 157 + +#define INT_UART0 158 // 0x9e: UART 0 Interrupt +#define INT_UART1 159 // 0x9f: UART 1 Interrupt +#define INT_UART2 160 // 0xa0: UART 2 Interrupt +#define INT_UART3 161 // 0xa1: UART 3 Interrupt +#define INT_UART4 162 // 0xa2: UART 4 Interrupt +#define INT_UART5 163 // 0xa3: UART 5 Interrupt +#define INT_UART6 164 // 0xa4: UART 6 Interrupt +#define INT_UART7 165 // 0xa5: UART 7 Interrupt +#define INT_UART8 166 // 0xa6: UART 8 Interrupt + +// Reserved 167 - 168 + +#define INT_MCA0 169 // 0xa9: Multi-Channel Audio 0 Interrupt +#define INT_MCA1 170 // 0xab: Multi-Channel Audio 1 Interrupt +#define INT_MCA2 171 // 0xac: Multi-Channel Audio 2 Interrupt +#define INT_MCA3 172 // 0xad: Multi-Channel Audio 3 Interrupt +#define INT_MCA4 173 // 0xae: Multi-Channel Audio 4 Interrupt +#define INT_IIC0 174 // 0xaf: I2C 0 Interrupt +#define INT_IIC1 175 // 0xb0: I2C 1 Interrupt +#define INT_IIC2 176 // 0xb1: I2C 2 Interrupt +#define INT_IIC3 177 // 0xb2: I2C 3 Interrupt +#define INT_PWM 178 // 0xb3: PWM Interrupt +#define INT_AES0 179 // 0xb4: AES 0 Interrupt + +// Reserved 180 - 181 + +#define INT_USB_OTG 182 // 0xb6: USB OTG Interrupt +#define INT_USB2HOST0_EHCI 183 // 0xb7: USB EHCI 0 Interrupt +#define INT_USB2HOST0_OHCI 184 // 0xb8: USB OHCI 0 Interrupt +#define INT_USB2HOST1_EHCI 185 // 0xb9: USB EHCI 1 Interrupt +#define INT_USB2HOST2_EHCI 186 // 0xba: USB EHCI 2 Interrupt +#define INT_USBOTG_RESUME 187 // 0xbb: USB OTG Resume Interrupt +#define INT_USB_20_BATT_CHRG_DET 188 // 0xbc: USB 2.0 Battery Charge Detect Interrupt +#define INT_USB2HOST0_PHY_RESUME 189 // 0xbd: USB Host 0 Resume Interrupt +#define INT_USB2HOST1_PHY_RESUME 190 // 0xbe: USB Host 1 Resume Interrupt +#define INT_USB2HOST2_PHY_RESUME 191 // 0xbf: USB Host 2 Resume Interrupt +#define INT_OTG_IN_EP0 192 // 0xc0: OTG IN Endpoint 0 Interrupt +#define INT_OTG_IN_EP1 193 // 0xc1: OTG IN Endpoint 1 Interrupt +#define INT_OTG_IN_EP2 194 // 0xc2: OTG IN Endpoint 2 Interrupt +#define INT_OTG_IN_EP3 195 // 0xc3: OTG IN Endpoint 3 Interrupt +#define INT_OTG_IN_EP4 196 // 0xc4: OTG IN Endpoint 4 Interrupt +#define INT_OTG_IN_EP5 197 // 0xc5: OTG IN Endpoint 5 Interrupt +#define INT_OTG_IN_EP6 198 // 0xc6: OTG IN Endpoint 6 Interrupt +#define INT_OTG_IN_EP7 199 // 0xc7: OTG IN Endpoint 7 Interrupt +#define INT_OTG_IN_EP8 200 // 0xc8: OTG IN Endpoint 8 Interrupt +#define INT_OTG_OUT_EP0 201 // 0xc9: OTG OUT Endpoint 0 Interrupt +#define INT_OTG_OUT_EP1 202 // 0xca: OTG OUT Endpoint 1 Interrupt +#define INT_OTG_OUT_EP2 203 // 0xcb: OTG OUT Endpoint 2 Interrupt +#define INT_OTG_OUT_EP3 204 // 0xcc: OTG OUT Endpoint 3 Interrupt +#define INT_OTG_OUT_EP4 205 // 0xcd: OTG OUT Endpoint 4 Interrupt +#define INT_OTG_OUT_EP5 206 // 0xce: OTG OUT Endpoint 5 Interrupt +#define INT_OTG_OUT_EP6 207 // 0xcf: OTG OUT Endpoint 6 Interrupt +#define INT_OTG_OUT_EP7 208 // 0xd0: OTG OUT Endpoint 7 Interrupt +#define INT_OTG_OUT_EP8 209 // 0xd1: OTG OUT Endpoint 8 Interrupt + +// Reserved 210 - 211 + +#define PCIE_LINK0 212 // 0xd4: PCIE Link 0 Interrupt +#define PCIE_LINK0_DART 213 // 0xd5: PCIE Link 0 DART Interrupt +#define PCIE_LINK0_MMU 214 // 0xd6: PCIE Link 0 MMU Interrupt +#define PCIE_LINK1 215 // 0xd7: PCIE Link 1 Interrupt +#define PCIE_LINK1_DART 216 // 0xd8: PCIE Link 1 DART Interrupt +#define PCIE_LINK1_MMU 217 // 0xd9: PCIE Link 1 MMU Interrupt +#if SUB_PLATFORM_T7001 +#define PCIE_LINK2 218 // 0xda: PCIE Link 1 Interrupt +#define PCIE_LINK2_DART 219 // 0xdb: PCIE Link 1 DART Interrupt +#define PCIE_LINK2_MMU 220 // 0xdc: PCIE Link 1 MMU Interrupt +#define PCIE_LINK3 221 // 0xdd: PCIE Link 1 Interrupt +#define PCIE_LINK3_DART 222 // 0xde: PCIE Link 1 DART Interrupt +#define PCIE_LINK3_MMU 223 // 0xdf: PCIE Link 1 MMU Interrupt +#endif + +// Reserved 218 - 223 (T7000) + +#define PCIE_MSI0 224 // 0xe0: PCIE MSI 0 Interrupt +#define PCIE_MSI1 225 // 0xe1: PCIE MSI 1 Interrupt +#define PCIE_MSI2 226 // 0xe2: PCIE MSI 2 Interrupt +#define PCIE_MSI3 227 // 0xe3: PCIE MSI 3 Interrupt +#define PCIE_MSI4 228 // 0xe4: PCIE MSI 4 Interrupt +#define PCIE_MSI5 229 // 0xe5: PCIE MSI 5 Interrupt +#define PCIE_MSI6 230 // 0xe6: PCIE MSI 6 Interrupt +#define PCIE_MSI7 231 // 0xe7: PCIE MSI 7 Interrupt +#define PCIE_MSI8 232 // 0xe8: PCIE MSI 8 Interrupt +#define PCIE_MSI9 233 // 0xe9: PCIE MSI 9 Interrupt +#define PCIE_MSI10 234 // 0xea: PCIE MSI 10 Interrupt +#define PCIE_MSI11 235 // 0xeb: PCIE MSI 11 Interrupt +#define PCIE_MSI12 236 // 0xec: PCIE MSI 12 Interrupt +#define PCIE_MSI13 237 // 0xed: PCIE MSI 13 Interrupt +#define PCIE_MSI14 238 // 0xee: PCIE MSI 14 Interrupt +#define PCIE_MSI15 239 // 0xef: PCIE MSI 15 Interrupt +#define PCIE_MSI16 240 // 0xf0: PCIE MSI 16 Interrupt +#define PCIE_MSI17 241 // 0xf1: PCIE MSI 17 Interrupt +#define PCIE_MSI18 242 // 0xf2: PCIE MSI 18 Interrupt +#define PCIE_MSI19 243 // 0xf3: PCIE MSI 19 Interrupt +#define PCIE_MSI20 244 // 0xf4: PCIE MSI 20 Interrupt +#define PCIE_MSI21 245 // 0xf5: PCIE MSI 21 Interrupt +#define PCIE_MSI22 246 // 0xf6: PCIE MSI 22 Interrupt +#define PCIE_MSI23 247 // 0xf7: PCIE MSI 23 Interrupt +#define PCIE_MSI24 248 // 0xf8: PCIE MSI 24 Interrupt +#define PCIE_MSI25 249 // 0xf9: PCIE MSI 25 Interrupt +#define PCIE_MSI26 250 // 0xfa: PCIE MSI 26 Interrupt +#define PCIE_MSI27 251 // 0xfb: PCIE MSI 27 Interrupt +#define PCIE_MSI28 252 // 0xfc: PCIE MSI 28 Interrupt +#define PCIE_MSI29 253 // 0xfd: PCIE MSI 29 Interrupt +#define PCIE_MSI30 254 // 0xfe: PCIE MSI 30 Interrupt +#define PCIE_MSI31 255 // 0xff: PCIE MSI 31 Interrupt + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/t7000/include/platform/soc/hwregbase.h b/platform/t7000/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..661681b --- /dev/null +++ b/platform/t7000/include/platform/soc/hwregbase.h @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#include + +/* T7000 and T7001 Reg Base Defs */ + +#define AMCC_BASE_ADDR (IO_BASE + 0x000000000) // AMCC Config +#define AMCX_BASE_ADDR (IO_BASE + 0x000100000) // AMCX Config + +#define SWTCH_FAB_BASE_ADDR (IO_BASE + 0x000800000) // Switch Fabric Config + +#define CP_COM_BASE_ADDR (IO_BASE + 0x000D00000) // CP Common Registers +#define CP_COM_INT_BASE_ADDR (CP_COM_BASE_ADDR + 0x10000) // CP Common Interrupt Config Registers + +#define CP_0_DT_BASE_ADDR (IO_BASE + 0x000D20000) // Dup Tag Config and Debug +#define CP_0_DT_DBG_CA0_ADDR (IO_BASE + 0x000D30000) // Dup Tag Debug backdoor Ram Access For CP0/CA0 +#define CP_0_CCU_CSR_BASE_ADDR (IO_BASE + 0x000D90000) // CTT and MIU Config and Debug +#define CP_1_DT_BASE_ADDR (IO_BASE + 0x000E20000) // Dup Tag Config and Debug +#define CP_1_DT_DBG_CA0_ADDR (IO_BASE + 0x000E30000) // Dup Tag Debug backdoor Ram Access For CP1/CA0 +#define CP_1_CCU_CSR_BASE_ADDR (IO_BASE + 0x000E90000) // CTT and MIU Config and Debug + +#define RGX_CR_BASE_ADDR (IO_BASE + 0x001000000) // Templar4 Space +#define GPC_BASE_ADDR (IO_BASE + 0x001e00000) // Templar4 Power Controller Space + +#define IMGV42AF_AFC_AIU_BASE_ADDR (IO_BASE + 0x001f00000) // IMGv42AF: Local PIO Config Space of AF AIU Block +#define IMGV42AF_AFUSR_BASE_ADDR (IO_BASE + 0x001f02000) // IMGv42AF: Bridge PIO Space + +#define CCC_ROM_TABLE_BASE_ADDR (IO_BASE + 0x002000000) // Typhoon ROM Table +#define CCC_CPU0_DBG_BASE_ADDR (IO_BASE + 0x002010000) // Typhoon CPU0 Debug Registers +#define CCC_CPU0_CTI_BASE_ADDR (IO_BASE + 0x002020000) // Typhoon CPU0 CTI Registers +#define CCC_CPU0_PMU_BASE_ADDR (IO_BASE + 0x002030000) // Typhoon CPU0 PMU Registgers +#define CCC_CPU0_TRC_BASE_ADDR (IO_BASE + 0x002040000) // Typhoon CPU0 TRACE Registers +#define CCC_CPU0_SYS_BASE_ADDR (IO_BASE + 0x002050000) // Typhoon CPU0 Implementation Specific Registers +#define CCC_CPU1_DBG_BASE_ADDR (IO_BASE + 0x002110000) // Typhoon CPU1 Debug Registers +#define CCC_CPU1_CTI_BASE_ADDR (IO_BASE + 0x002120000) // Typhoon CPU1 CTI Registers +#define CCC_CPU1_PMU_BASE_ADDR (IO_BASE + 0x002130000) // Typhoon CPU1 PMU Registgers +#define CCC_CPU1_TRC_BASE_ADDR (IO_BASE + 0x002140000) // Typhoon CPU1 TRACE Registers +#define CCC_CPU1_SYS_BASE_ADDR (IO_BASE + 0x002150000) // Typhoon CPU1 Implementation Specific Registers +#define CCC_CCC_DBG_BASE_ADDR (IO_BASE + 0x002250000) // Typhoon CCC Debug Registers +#if SUB_PLATFORM_T7001 +#define CCC_CPU2_TRC_BASE_ADDR (IO_BASE + 0x002440000) // Typhoon CPU2 Trace Registers +#define CCC_CPU2_SYS_BASE_ADDR (IO_BASE + 0x002450000) // Typhoon CPU2 Implementation Specific Registers +#endif +#define CCC0_SYS_BASE_ADDR (IO_BASE + 0x002200000) // Typhoon Core Complex Registers +#define CCC_SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config +#define SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config +#if SUB_PLATFORM_T7000 +#define CCC_CAM_BUSMUX_BASE_ADDR (IO_BASE + 0x005000000) // AF Camera BusMux Config +#endif + +#define ISP_AFC_AIU_0_BASE_ADDR (IO_BASE + 0x005B00000) // ISP AXI to AF Bridge +#if SUB_PLATFORM_T7000 +#define ISP_AFC_AIU_1_BASE_ADDR (IO_BASE + 0x005B10000) // ISP AXI to AF Bridge +#endif +#define ISP_INTR2AXI_BASE_ADDR (IO_BASE + 0x005B20000) // ISP Interrupt to AXI Widget +#define ISP_DART_BASE_ADDR (IO_BASE + 0x005B22000) // ISP DART +#define ISP_SMMU_BASE_ADDR (IO_BASE + 0x005B24000) // ISP SMMU +#define ISP_ISPCTRL_R0_BASE_ADDR (IO_BASE + 0x005B40000) // SISP Region 0 Control +#define ISP_MIPI_CSI_0_BASE_ADDR (IO_BASE + 0x005B80000) // MIPI CSI Controller +#define ISP_MIPI_CSI_1_BASE_ADDR (IO_BASE + 0x005B81000) // MIPI CSI Controller +#define ISP_SMB_0_BASE_ADDR (IO_BASE + 0x005B82000) // SMB Controller +#define ISP_SMB_1_BASE_ADDR (IO_BASE + 0x005B83000) // SMB Controller +#define ISP_FD_BASE_ADDR (IO_BASE + 0x005B84000) // Face Detect +#define ISP_AISP_BASE_ADDR (IO_BASE + 0x005BA0000) // AISP +#define ISP_ISPCTRL_R1_BASE_ADDR (IO_BASE + 0x005BC0000) // SISP Region 1 Control +#define ISP_AKF_BASE_ADDR (IO_BASE + 0x005C00000) // SISP KF Widgets and Config + +#if SUB_PLATFORM_T7000 +#define DISP_BUSMUX_BASE_ADDR (IO_BASE + 0x006000000) // AF Display BusMux Config +#endif +#define DISP0_FAB_BASE_ADDR (IO_BASE + 0x006100000) // DisplayPipe0 AF and AXI Config +#define DISP0_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 +#define DISP0_ADP_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 Configuration +#define DISP0_SMMU_BASE_ADDR (IO_BASE + 0x006300000) // DisplayPipe0 SMMU Configuration +#define DISP0_ADBE_BASE_ADDR (IO_BASE + 0x006400000) // DisplayPipe0 Backend Config +#define DISP0_AAP_BASE_ADDR (IO_BASE + 0x006440000) // DisplayPipe0 Ambient-Adaptive Pixel Config +#define DISP0_DPB_BASE_ADDR (IO_BASE + 0x006480000) // DisplayPipe0 Pixel Backlight Config +#define DISP0_DITHER_BASE_ADDR (IO_BASE + 0x0064C0000) // DisplayPipe0 Dither Config +#define DITHER_BASE_ADDR DISP0_DITHER_BASE_ADDR +#define DITHER_VERSION (3) + +#if SUB_PLATFORM_T7000 +#define DISP0_MIPI_DSI_BASE_ADDR (IO_BASE + 0x006600000) // DisplayPipe0 MIPI DSI Config +#endif +#define DISP0_DPTX_BASE_ADDR (IO_BASE + 0x006700000) // DisplayPipe0 DisplayPort TX Config + +#define DISP1_FAB_BASE_ADDR (IO_BASE + 0x006900000) // DisplayPipe1 AF and AXI Config +#define DISP1_BASE_ADDR (IO_BASE + 0x006A00000) // DisplayPipe1 +#define DISP1_ADP_BASE_ADDR (IO_BASE + 0x006A00000) // DisplayPipe1 Ambient-Adaptive Pixel Config +#define DISP1_SMMU_BASE_ADDR (IO_BASE + 0x006B00000) // DisplayPipe1 SMMU Configuration + +#define DISP1_MEDIA_BUSMUX_BASE_ADDR (IO_BASE + 0x007000000) // DisplayPipe1 AF Media BusMux Config + +#define MSR_AFC_AIU_BASE_ADDR (IO_BASE + 0x007800000) // MSR AXI2AF AFC_AIU +#define MSR_BASE_ADDR (IO_BASE + 0x007900000) // Memory Scalar Rotator +#define MSR_SMMU_BASE_ADDR (IO_BASE + 0x007904000) // MSR SMMU +#define MSR_DART_BASE_ADDR (IO_BASE + 0x007908000) // DART for MSR SMMU +#define MSR_INTR2AXI_BASE_ADDR (IO_BASE + 0x00790C000) // MSR Interrupt to AXI Widget + +#define AJPEG_AFC_AIU_BASE_ADDR (IO_BASE + 0x007A00000) // AJPEG AXI2AF AFC_AIU +#define AJPEG_BASE_ADDR (IO_BASE + 0x007B00000) // AJPEG Wrap +#define AJPEG_DART_BASE_ADDR (IO_BASE + 0x007B02000) // AJPEG DART +#define AJPEG_INTR2AXI_BASE_ADDR (IO_BASE + 0x007B04000) // AJPEG Interrupt to AXI Widget + +#define SVE_BASE_ADDR (IO_BASE + 0x007C00000) // SVE Video Encoder Subsystem +#define SVE_AVE_AXI2AF (IO_BASE + 0x007C00000) // SVE AVE AXI to Apple Fabric Bridge +#define SVE_AFC_AIU_BASE_ADDR (IO_BASE + 0x007C00000) // SVE AXI2AF AFC_AIU +#define SVE_INTR2AXI_BASE_ADDR (IO_BASE + 0x007C10000) // SVE VENC Interrupt to AXI Widget +#define SVE_SMMU_BASE_ADDR (IO_BASE + 0x007C20000) // SVE Streaming MMU for AVE +#define SVE_DART_BASE_ADDR (IO_BASE + 0x007C30000) // SVE DART for AVE SMMU +#define SVE_PL301_BASE_ADDR (IO_BASE + 0x007C40000) // SVE PL301 Config +#define SVE_AKF_BASE_ADDR (IO_BASE + 0x007C80000) // SVE Kingfisher Wrapper Configuration +// XXX #define SVE_AVE_KF_DBG_BASE_ADDR (IO_BASE + 0x007CA0000) // SVE Kingfisher Wrapper Debug APB +#define SVE_CTRL_BASE_ADDR (IO_BASE + 0x007CC0000) // SVE Control Registers + +#define VXD_AFC_AIU_BASE_ADDR (IO_BASE + 0x007E00000) // VXD AXI2AF AFC_AIU +#define VXD_INTR2AXI_BASE_ADDR (IO_BASE + 0x007E10000) // VXD Interrupt to AXI Widget +#define VXD_PL301_BASE_ADDR (IO_BASE + 0x007E20000) // VXD PL301 Config +#define VXD_CFG_BASE_ADDR (IO_BASE + 0x007F00000) // VXD Config Registers + +#define ANS_AFC_AIU_BASE_ADDR (IO_BASE + 0x008000000) // ANS AXI2AF AFC_AIU +#define ANS_PL301_BASE_ADDR (IO_BASE + 0x008010000) // ANS PL301 Config +#define ANS_AKF_PL301_TLMT_BASE_ADDR (IO_BASE + 0x008020000) // ANS KF Transaction Limit Widget +#define ANS_AKF_INTR2AXI_BASE_ADDR (IO_BASE + 0x008021000) // ANS KF Interrupt to AXI Widget +#define ANS_ANC_PL301_TLMT_0_BASE_ADDR (IO_BASE + 0x008030000) // ANS NAND Controller Transaction Limit Widget +#define ANS_ANC_PL301_TLMT_1_BASE_ADDR (IO_BASE + 0x008031000) // ANS NAND Controller Transaction Limit Widget +#define ANS_ANC_INTR2AXI_0_BASE_ADDR (IO_BASE + 0x008038000) // ANS NAND Controller Interrupt to AXI Widget +#define ANS_ANC_INTR2AXI_1_BASE_ADDR (IO_BASE + 0x008039000) // ANS NAND Controller Interrupt to AXI Widget +#define ANS_AKF_BASE_ADDR (IO_BASE + 0x008040000) // ANS KF Wrapper +// XXX AKF DBG (IO_BASE + 0x008060000) - (IO_BASE + 0x008070000) +#define ANS_CFG_BASE_BADDR (IO_BASE + 0x008080000) // ANS Config +#define ANS_PPN_N_PL_BASE_ADDR (IO_BASE + 0x008081000) // ANS PPN-N-PL Config +#define ANS_ANC_BASE_ADDR (IO_BASE + 0x008700000) // ANC Broadcast writes to all ANCs +#define ANS_ANC_0_BASE_ADDR (IO_BASE + 0x008800000) // ANS NAND Controller 0 +#define ANS_ANC_1_BASE_ADDR (IO_BASE + 0x008900000) // ANS NAND Controller 1 +#define ANS_IO_BUSMUX_BASE_ADDR (IO_BASE + 0x009000000) // ANS AF IO BusMux Config + +#define IOBUSMUX_BASE_ADDR (IO_BASE + 0x009000000) // IO BusMux Config + +#define SB_BASE_ADDR (IO_BASE + 0x00A000000) // South Bridge + +#define ASIO_MISC_0_BASE_ADDR (IO_BASE + 0x00A000000) // ASIO Shim0 Misc Registers +#define ASIO_AUD_MUX_BASE_ADDR (IO_BASE + 0x00A003000) // ASIO Audio I2S Switch Config +#define ASIO_SPI_BASE_ADDR (IO_BASE + 0x00A080000) // ASIO SPI Device +#define ASIO_SPI_TX_CFG_BASE_ADDR (IO_BASE + 0x00A081000) // ASIO SPI TX DMA Channel +#define ASIO_SPI_RX_CFG_BASE_ADDR (IO_BASE + 0x00A081800) // ASIO SPI RX DMA Channel +#define ASIO_SPI_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A082000) // ASIO SPI TX DMA Shim FIFO +#define ASIO_SPI_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A083000) // ASIO SPI RX DMA Shim FIFO +#define ASIO_MCA_BASE_ADDR (IO_BASE + 0x00A0A0000) // ASIO MCA Device +#define ASIO_MCA_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1000) // ASIO MCA TX DMA Channel +#define ASIO_MCA_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1800) // ASIO MCA RX DMA Channel +#define ASIO_MCA_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A2000) // ASIO MCA TX DMA Shim FIFO +#define ASIO_MCA_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A3000) // ASIO MCA RX DMA Shim FIFO +#define ASIO_UART_BASE_ADDR (IO_BASE + 0x00A0C0000) // ASIO UART Device +#define ASIO_UART_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1000) // ASIO UART TX DMA Channel +#define ASIO_UART_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1800) // ASIO UART RX DMA Channel +#define ASIO_UART_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C2000) // ASIO UART TX DMA Shim FIFO +#define ASIO_UART_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C3000) // ASIO UART RX DMA Shim FIFO +#define ASIO_MISC_1_BASE_ADDR (IO_BASE + 0x00A100000) // ASIO Shim1 Misc Registers +#define ASIO_AES_BASE_ADDR (IO_BASE + 0x00A108000) // ASIO AES Config and DMA Registers +#define ASIO_SMB_0_BASE_ADDR (IO_BASE + 0x00A110000) // ASIO I2C 0 Device +#define ASIO_SMB_1_BASE_ADDR (IO_BASE + 0x00A111000) // ASIO I2C 1 Device +#define ASIO_SMB_2_BASE_ADDR (IO_BASE + 0x00A112000) // ASIO I2C 2 Device +#define ASIO_SMB_3_BASE_ADDR (IO_BASE + 0x00A113000) // ASIO I2C 3 Device +#define ASIO_PWM_BASE_ADDR (IO_BASE + 0x00A118000) // ASIO PWM +#define ASIO_DNSZ_AXI_0_BASE_ADDR (IO_BASE + 0x00A141000) // ASIO Downsizer 0 Configuration Registers +#define ASIO_DNSZ_AXI_1_BASE_ADDR (IO_BASE + 0x00A142000) // ASIO Downsizer 1 Configuration Registers +#define ASIO_AKF_BASE_ADDR (IO_BASE + 0x00AE00000) // ASIO KF Wrapper +// XXX ASIO AKF DBG + +#define AUSB_CTL_REG_BASE_ADDR (IO_BASE + 0x00C000000) // USBCTL Config +#define AUSB_CTL_USB20PHY_REG_OFFSET (0x30) // USB20PHY Register offset within AUSBCTL registers +#define AUSB_OTG_BASE_ADDR (IO_BASE + 0x00C100000) // USB OTG +#define AUSB_USB2HOST0_EHCI_BASE_ADDR (IO_BASE + 0x00C200000) // EHCI0 +#define AUSB_USB2HOST0_OHCI_BASE_ADDR (IO_BASE + 0x00C300000) // OHCI0 +#define AUSB_USB2HOST1_EHCI_BASE_ADDR (IO_BASE + 0x00C400000) // EHCI1 +#define AUSB_USB2HOST1_OHCI_BASE_ADDR (IO_BASE + 0x00C500000) // OHCI1 +#define AUSB_PL301_BASE_ADDR (IO_BASE + 0x00C800000) // AUSB PL301 4-AHB Master to 1-AXI Slave +#define AUSB_PL301_WIDGET_BASE_ADDR (IO_BASE + 0x00C900000) // AUSB PL301 Widget +#define AUSB_INTR2AXI_BASE_ADDR (IO_BASE + 0x00CA00000) // AUSB Interrupt to AXI Widget +#define AUSB_AFIFO_WIDGET_BASE_ADDR (IO_BASE + 0x00CB00000) // AUSB Async FIFO + +#define ASEP_AKF_BASE_ADDR (IO_BASE + 0x00DA00000) // ASEP AKF control Registers + +#define PMGR_BASE_ADDR (IO_BASE + 0x00E000000) // PMGR + +#define AIC_BASE_ADDR (IO_BASE + 0x00E100000) // AIC +#define AIC_WIRE_VIRT_BASE_ADDR (IO_BASE + 0x00E110000) // AIC Wrapper + +#define DWI_BASE_ADDR (IO_BASE + 0x00E200000) // DWI + +#define GPIO_BASE_ADDR (IO_BASE + 0x00E300000) // GPIO + +#define AMPS_0_DQ0_BASE_ADDR (IO_BASE + 0x00E400000) // AMP 0 DQ0 DRAM PHY +#define AMPS_0_DQ1_BASE_ADDR (IO_BASE + 0x00E410000) // AMP 0 DQ1 DRAM PHY +#define AMPS_0_CA_BASE_ADDR (IO_BASE + 0x00E420000) // AMP 0 CA DRAM PHY +#define AMPS_1_DQ0_BASE_ADDR (IO_BASE + 0x00E430000) // AMP 1 DQ0 DRAM PHY +#define AMPS_1_DQ1_BASE_ADDR (IO_BASE + 0x00E440000) // AMP 1 DQ1 DRAM PHY +#define AMPS_1_CA_BASE_ADDR (IO_BASE + 0x00E450000) // AMP 1 CA DRAM PHY +#if SUB_PLATFORM_T7001 +#define AMPS_2_DQ0_BASE_ADDR (IO_BASE + 0x00E460000) // AMP 2 DQ0 DRAM PHY +#define AMPS_2_DQ1_BASE_ADDR (IO_BASE + 0x00E470000) // AMP 2 DQ1 DRAM PHY +#define AMPS_2_CA_BASE_ADDR (IO_BASE + 0x00E480000) // AMP 2 CA DRAM PHY +#define AMPS_3_DQ0_BASE_ADDR (IO_BASE + 0x00E490000) // AMP 3 DQ0 DRAM PHY +#define AMPS_3_DQ1_BASE_ADDR (IO_BASE + 0x00E4A0000) // AMP 3 DQ1 DRAM PHY +#define AMPS_3_CA_BASE_ADDR (IO_BASE + 0x00E4B0000) // AMP 3 CA DRAM PHY +#endif + +#define LIO_MEM_PL301_BASE_ADDR (IO_BASE + 0x00E900000) // PL310 for pd_lio memory +#define LIO_PIO_PL310_BASE_ADDR (IO_BASE + 0x00E940000) // PL310 for pd_lio PIO +#define LIO_DNSZ_AXI_BASE_ADDR (IO_BASE + 0x00E9C8000) // PL310 for pd_lio downsizer +#define LIO_SIO_AFIFO_WIDGETS_BASE_ADDR (IO_BASE + 0x00E9C0000) // SIO Async FIFO for pd_lio +#define LIO_DAP_AFIFO_WIDGETS_BASE_ADDR (IO_BASE + 0x00E9E0000) // DAP Async FIFO for pd_lio +#define LIO_AFC_AIU_BASE_ADDR (IO_BASE + 0x00F010000) // LIO AXI to AF Bridge + +#define DBG_WRP_BASE_ADDR (IO_BASE + 0x00F000000) // Debug Sub-system Config +#define ERR_REFLECTION_BASE_ADDR (IO_BASE + 0x00FFFF000) + +#define APCIE_VERSION (1) +#define APCIE_COMMON_BASE_ADDR (PCI_REG_BASE + 0x000000000) +#define APCIE_CONFIG_BASE_ADDR (PCI_REG_BASE + 0x01004000) +#define APCIE_CONFIG_PORT_STRIDE (0x01000000) +#define APCIE_COUNTER_BASE_ADDR (PCI_REG_BASE + 0x800) + +/* iBoot Specific Defs */ + +#define AKF_VERSION (1) + +#define UART0_BASE_ADDR (ASIO_UART_BASE_ADDR) +#define UART1_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x04000) +#define UART2_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x08000) +#define UART3_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x10000) +#define UART5_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x14000) +#define UART6_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x18000) +#define UART7_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x1C000) +#define UART8_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x20000) +#define UARTS_COUNT (9) +#define UART_VERSION (1) + +#define SPI0_BASE_ADDR (ASIO_SPI_BASE_ADDR) +#define SPI1_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x04000) +#define SPI2_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x08000) +#define SPI3_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x0C000) +#define SPI_VERSION (1) +#define SPIS_COUNT (4) + +#define IIC_BASE_ADDR (ASIO_SMB_0_BASE_ADDR) +#define IIC_SPACING (0x00001000) +#define IICS_COUNT (4) + +#define USBPHY_VERSION (4) + +#if SUB_PLATFORM_T7000 +#define DSIM_BASE_ADDR (DISP0_MIPI_DSI_BASE_ADDR) +#define DSIM_LANE_COUNT (4) +#define DSIM_VERSION (1) +#endif + +#define EDP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define DP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define LPDP_PHY_BASE_ADDR (DISP0_DPTX_BASE_ADDR + 0x080000) +#define DISPLAYPORT_VERSION (3) + +#define ADBE_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define DISP_VERSION (5) +#if SUB_PLATFORM_T7000 +#define ADP_VERSION (1) +#elif SUB_PLATFORM_T7001 +#define ADP_VERSION (2) +#endif + +#define AMP_REG_VERSION (3) +#define AMP_BASE_ADDR (AMPS_0_DQ0_BASE_ADDR) +#define AMP_SPACING (0x00030000) +#define AMP_DQCA_SPACING (0x00010000) +#define AMP_CA_SPACING (0x00020000) + +#define CHIPID_BASE_ADDR (PMGR_BASE_ADDR + 0x2A000) + +#define GPIO_VERSION (4) +#if SUB_PLATFORM_T7000 +#define GPIO_GROUP_COUNT (26) +#elif SUB_PLATFORM_T7001 +#define GPIO_GROUP_COUNT (23) +#endif +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define AIC_VERSION (1) +#define AIC_INT_COUNT (256) + +#define PMGR_WDG_VERSION (1) + +#define USBOTG_BASE_ADDR (AUSB_OTG_BASE_ADDR) + +#if SUB_PLATFORM_T7000 +#define APCIE_NUM_LINKS (2) +#elif SUB_PLATFORM_T7001 +#define APCIE_NUM_LINKS (4) +#endif + +#define DART0_BASE_ADDR (PCI_REG_BASE + 0x1002000) +#define DART0_ADDR_MASK (0x3FFFFFFF) +#define DART1_BASE_ADDR (PCI_REG_BASE + 0x2002000) +#define DART1_ADDR_MASK (0x3FFFFFFF) +#if SUB_PLATFORM_T7001 +#define DART2_BASE_ADDR (PCI_REG_BASE + 0x3002000) +#define DART2_ADDR_MASK (0x3FFFFFFF) +#define DART3_BASE_ADDR (PCI_REG_BASE + 0x4002000) +#define DART3_ADDR_MASK (0x3FFFFFFF) +#endif + +#define PCIE_PORT0_DART_ID (0) +#define PCIE_PORT1_DART_ID (1) +#if SUB_PLATFORM_T7000 +#define NUM_DARTS (2) +#elif SUB_PLATFORM_T7001 +#define PCIE_PORT2_DART_ID (2) +#define PCIE_PORT3_DART_ID (3) +#define NUM_DARTS (4) +#endif + +#define AES_AP_BASE_ADDR (ASIO_AES_BASE_ADDR) +#define AES_AP_VERSION (0) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/t7000/include/platform/soc/miu.h b/platform/t7000/include/platform/soc/miu.h new file mode 100644 index 0000000..09ca751 --- /dev/null +++ b/platform/t7000/include/platform/soc/miu.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rSECUREROMCTRL_ROMADDRREMAP (*(volatile u_int32_t *)(AMCC_BASE_ADDR + 0x0904)) + + +#define rMCCLOCKREGION_TZ0BASEADDR (*(volatile u_int32_t *)(AMCC_BASE_ADDR + 0x480)) +#define rMCCLOCKREGION_TZ0ENDADDR (*(volatile u_int32_t *)(AMCC_BASE_ADDR + 0x484)) +#define rMCCLOCKREGION_TZ1BASEADDR (*(volatile u_int32_t *)(AMCC_BASE_ADDR + 0x488)) +#define rMCCLOCKREGION_TZ1ENDADDR (*(volatile u_int32_t *)(AMCC_BASE_ADDR + 0x48c)) +#define rMCCLOCKREGION_TZ0LOCK (*(volatile u_int32_t *)(AMCC_BASE_ADDR + 0x490)) +#define rMCCLOCKREGION_TZ1LOCK (*(volatile u_int32_t *)(AMCC_BASE_ADDR + 0x494)) + + +#define ASIO_CLK_CTRL (0x100004) +#define rASIO_CLK_CTRL (*(volatile u_int32_t *)(SB_BASE_ADDR + ASIO_CLK_CTRL)) +#define ASIO_AKF_IDLE_CTRL (0xe00024) +#define rASIO_AKF_IDLE_CTRL (*(volatile u_int32_t *)(SB_BASE_ADDR + ASIO_AKF_IDLE_CTRL)) +#define DYN_CLK_GATING (0x49a0000) +#define rDYN_CLK_GATING (*(volatile u_int32_t *)(SB_BASE_ADDR + DYN_CLK_GATING)) +#define SIO_ASYNC_FIFO_SB_RD_RATE_LIMIT (0x49c0000) +#define rSIO_ASYNC_FIFO_SB_RD_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_ASYNC_FIFO_SB_RD_RATE_LIMIT)) +#define SIO_ASYNC_FIFO_SB_WR_RATE_LIMIT (0x49c0004) +#define rSIO_ASYNC_FIFO_SB_WR_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_ASYNC_FIFO_SB_WR_RATE_LIMIT)) +#define SIO_ASYNC_FIFO_SB_WGATHER (0x49c0010) +#define rSIO_ASYNC_FIFO_SB_WGATHER (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_ASYNC_FIFO_SB_WGATHER)) +#define SIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT (0x49e0000) +#define rSIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT)) +#define SIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT (0x49e0004) +#define rSIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT)) +#define SIO_DAPASYNC_FIFO_SB_WGATHER (0x49e0010) +#define rSIO_DAPASYNC_FIFO_SB_WGATHER (*(volatile u_int32_t *)(SB_BASE_ADDR + SIO_DAPASYNC_FIFO_SB_WGATHER)) +#define AIU_SB_ARBCFG (0x5010000) +#define rAIU_SB_ARBCFG (*(volatile u_int32_t *)(SB_BASE_ADDR + AIU_SB_ARBCFG)) +#define AIU_SB_CPG_CNTL (0x5010014) +#define rAIU_SB_CPG_CNTL (*(volatile u_int32_t *)(SB_BASE_ADDR + AIU_SB_CPG_CNTL)) + + +#define SOCBUSMUX_ARBCFG (0x0000) +#define rSOCBUSMUX_ARBCFG (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + SOCBUSMUX_ARBCFG)) +#if SUB_PLATFORM_T7001 +#define DWRRCFG_DISP0_RT (0x0004) +#define rDWRRCFG_DISP0_RT (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + DWRRCFG_DISP0_RT)) +#endif +#define DWRRCFG_DISPMUX_BULK (0x0008) +#define rDWRRCFG_DISPMUX_BULK (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + DWRRCFG_DISPMUX_BULK)) +#if SUB_PLATFORM_T7001 +#define DWRRCFG_IOMUX_BULK (0x001c) +#define rDWRRCFG_IOMUX_BULK (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + DWRRCFG_IOMUX_BULK)) +#endif +#define TLIMIT_LVL0_DISP0 (0x0024) +#define rTLIMIT_LVL0_DISP0 (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL0_DISP0)) +#define TLIMIT_LVL1_DISP0 (0x0028) +#define rTLIMIT_LVL1_DISP0 (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL1_DISP0)) +#define TLIMIT_LVL2_DISP0 (0x002c) +#define rTLIMIT_LVL2_DISP0 (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL2_DISP0)) +#define TLIMIT_LVL3_DISP0 (0x0030) +#define rTLIMIT_LVL3_DISP0 (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL3_DISP0)) +#define TLIMIT_LVL0_CAMERAMUX (0x0034) +#define rTLIMIT_LVL0_CAMERAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL0_CAMERAMUX)) +#define TLIMIT_LVL1_CAMERAMUX (0x0038) +#define rTLIMIT_LVL1_CAMERAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL1_CAMERAMUX)) +#define TLIMIT_LVL1_MEDIAMUX (0x0048) +#define rTLIMIT_LVL1_MEDIAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL1_MEDIAMUX)) +#define TLIMIT_LVL2_MEDIAMUX (0x004c) +#define rTLIMIT_LVL2_MEDIAMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL2_MEDIAMUX)) +#define TLIMIT_LVL0_IOMUX (0x0054) +#define rTLIMIT_LVL0_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL0_IOMUX)) +#define TLIMIT_LVL1_IOMUX (0x0058) +#define rTLIMIT_LVL1_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL1_IOMUX)) +#define TLIMIT_LVL2_IOMUX (0x005c) +#define rTLIMIT_LVL2_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL2_IOMUX)) +#define TLIMIT_LVL3_IOMUX (0x0060) +#define rTLIMIT_LVL3_IOMUX (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + TLIMIT_LVL3_IOMUX)) +#define SOCBUSMUX_CPG_CNTL (0x0088) +#define rSOCBUSMUX_CPG_CNTL (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + SOCBUSMUX_CPG_CNTL)) + + +#define IOBUSMUX_ARBCFG (0x0000) +#define rIOBUSMUX_ARBCFG (*(volatile u_int32_t *)(IOBUSMUX_BASE_ADDR + IOBUSMUX_ARBCFG)) +#if SUB_PLATFORM_T7001 +#define IOBUSMUX_REGS_DWRRCFG_DISP1_BULK (0x0010) +#define rIOBUSMUX_REGS_DWRRCFG_DISP1_BULK (*(volatile u_int32_t *)(IOBUSMUX_BASE_ADDR + IOBUSMUX_REGS_DWRRCFG_DISP1_BULK)) +#endif +#if SUB_PLATFORM_T7000 +#define IOBUSMUX_CPG_CNTL (0x0024) +#elif SUB_PLATFORM_T7001 +#define IOBUSMUX_CPG_CNTL (0x002c) +#endif +#define rIOBUSMUX_CPG_CNTL (*(volatile u_int32_t *)(IOBUSMUX_BASE_ADDR + IOBUSMUX_CPG_CNTL)) + + +#define SWITCH_FAB_AMAP_LOCK (0x0000) +#define rSWITCH_FAB_AMAP_LOCK (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCH_FAB_AMAP_LOCK)) +#define SWITCH_FAB_ARBCFG (0x0008) +#define rSWITCH_FAB_ARBCFG (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCH_FAB_ARBCFG)) +#if SUB_PLATFORM_T7000 +#define SWITCH_FAB_PIOLIMIT (0x0028) +#elif SUB_PLATFORM_T7001 +#define SWITCH_FAB_PIOLIMIT (0x002c) +#endif +#define rSWITCH_FAB_PIOLIMIT (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCH_FAB_PIOLIMIT)) +#if SUB_PLATFORM_T7000 +#define SWITCH_FAB_CPG_CNTL (0x0070) +#elif SUB_PLATFORM_T7001 +#define SWITCH_FAB_CPG_CNTL (0x008c) +#endif +#define rSWITCH_FAB_CPG_CNTL (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCH_FAB_CPG_CNTL)) + + +#define CP_DYN_CLK_GATING_CTRL (0x000c) +#define rCP_DYN_CLK_GATING_CTRL (*(volatile u_int32_t *)(CP_COM_BASE_ADDR + CP_DYN_CLK_GATING_CTRL)) + +#define CPCOM_INT_NORM_REQUEST (0x0000) +#define rCP_COM_INT_NORM_REQUEST (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_REQUEST)) +#define CPCOM_INT_NORM_MASK_SET (0x0004) +#define rCP_COM_INT_NORM_MASK_SET (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_SET)) +#define CPCOM_INT_NORM_MASK_CLR (0x0008) +#define rCP_COM_INT_NORM_MASK_CLR (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CPCOM_INT_NORM_MASK_CLR)) + +#define LIO_MEMCACHE_DATASETID_OVERRIDE (0x001000) + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/t7000/include/platform/soc/pmgr.h b/platform/t7000/include/platform/soc/pmgr.h new file mode 100644 index 0000000..9b94e73 --- /dev/null +++ b/platform/t7000/include/platform/soc/pmgr.h @@ -0,0 +1,1003 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include + +//////////////////////////////////////////////////////////// +// +// PMGR specific +// +//////////////////////////////////////////////////////////// + +#define PMGR_PLL_COUNT (6) + +#define rPMGR_PLL_CTL(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + ((_p) * 0x1000))) +#define PMGR_PLL_ENABLE (1 << 31) +#define PMGR_PLL_LOAD (1 << 29) +#define PMGR_PLL_PENDING (1 << 25) +#define PMGR_PLL_M_SHIFT (12) +#define PMGR_PLL_M_MASK (0x1FF) +#define PMGR_PLL_P_SHIFT (4) +#define PMGR_PLL_P_MASK (0x1F) +#define PMGR_PLL_S_SHIFT (0) +#define PMGR_PLL_S_MASK (0xF) +#define PMGR_PLL_M(_m) (((_m) & PMGR_PLL_M_MASK) << PMGR_PLL_M_SHIFT) +#define PMGR_PLL_P(_p) (((_p) & PMGR_PLL_P_MASK) << PMGR_PLL_P_SHIFT) +#define PMGR_PLL_S(_s) (((_s) & PMGR_PLL_S_MASK) << PMGR_PLL_S_SHIFT) +#define PMGR_PLL_FREQ(_m, _p, _s) ((((_m) * OSC_FREQ) / (_p))/((_s) + 1)) + +#define rPMGR_PLL_EXT_BYPASS_CTL(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0004 + ((_p) * 0x1000))) +#define PMGR_PLL_BYP_ENABLED (1 << 31) +#define PMGR_PLL_ENABLED (1 << 30) +#define PMGR_PLL_EXT_BYPASS (1 << 0) // Do not change while PMGR_PLL_PENDING is high + +#define rPMGR_PLL_CFG(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0008 + ((_p) * 0x1000))) +#define PMGR_PLL_OFF_MODE_MASK (0x3) +#define PMGR_PLL_OFF_MODE(_n) (((_n) & PMGR_PLL_OFF_MODE_MASK) << 30) +#define PMGR_PLL_OFF_MODE_RESET (0) +#define PMGR_PLL_OFF_MODE_CLOCK_GATED (1) +#define PMGR_PLL_OFF_MODE_POWER_DOWN (2) +#define PMGR_PLL_LOCK_MODE_SHIFT (28) +#define PMGR_PLL_LOCK_MODE_MASK (0x3) +#define PMGR_PLL_VCO_OUT_SEL (1 << 27) +#define PMGR_PLL_AUTO_DISABLE (1 << 26) +#define PMGR_PLL_RELOCK_MODE_SHIFT (24) +#define PMGR_PLL_RELOCK_MODE_MASK (3) +#define PMGR_PLL_RELOCK_MODE_STOP (0) +#define PMGR_PLL_RELOCK_MODE_BYPASS (1) +#define PMGR_PLL_FRAC_LOCK_TIME_MASK (0xFF) +#define PMGR_PLL_FRAC_LOCK_TIME(_n) (((_n) & PMGR_PLL_FRAC_LOCK_TIME_MASK) << 16) +#define PMGR_PLL_LOCK_TIME_MASK (0xFFFF) +#define PMGR_PLL_LOCK_TIME(_n) (((_n) & PMGR_PLL_LOCK_TIME_MASK) << 0) + +#define rPMGR_PLL_ANA_PARAMS0(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x000c + ((_p) * 0x1000))) +#define PMGR_PLL_ANA_PARAMS0_VREG_ADJ_SHIFT (25) +#define PMGR_PLL_ANA_PARAMS0_VREG_ADJ_MASK (0x7) + +#define rPMGR_PLL_ANA_PARAMS1(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0010 + ((_p) * 0x1000))) +#define PMGR_PLL_ANA_PARAMS1_VCO_RCTRL_SEL (1 << 7) +#define PMGR_PLL_ANA_PARAMS1_VCO_RCTRL_OW_SHIFT (1) +#define PMGR_PLL_ANA_PARAMS1_VCO_RCTRL_OW_MASK (0x7) + +#define rPMGR_PLL_DEBUG1(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x001c + ((_p) * 0x1000))) +#define PMGR_PLL_DEBUG1_RESERVE_IN_SHIFT (20) +#define PMGR_PLL_DEBUG1_RESERVE_IN_MASK (0x3f) + +#define rPMGR_MCU_FIXED_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10000)) +#define rPMGR_MCU_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10004)) + +#if SUB_PLATFORM_T7000 + +#define rPMGR_MIPI_DSI_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10008)) +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1000c)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10010)) +#define rPMGR_NCO_ALG0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10014)) +#define rPMGR_NCO_ALG1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10018)) +#define rPMGR_HSICPHY_REF_12M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1001c)) +#define rPMGR_USB480_0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10020)) +#define rPMGR_USB480_1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10024)) +#define rPMGR_USB_OHCI_48M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10028)) +#define rPMGR_USB_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1002c)) +#define rPMGR_USB_FREE_60M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10030)) +#define rPMGR_SIO_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10034)) +#define rPMGR_SIO_P_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10038)) +#define rPMGR_ISP_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1003c)) +#define rPMGR_ISP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10040)) +#define rPMGR_ISP_SENSOR0_REF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10044)) +#define rPMGR_ISP_SENSOR1_REF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10048)) +#define rPMGR_VDEC_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1004c)) +#define rPMGR_VENC_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10050)) +#define rPMGR_VID0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10054)) +#define rPMGR_DISP0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10058)) +#define rPMGR_DISP1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1005c)) +#define rPMGR_AJPEG_IP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10060)) +#define rPMGR_AJPEG_WRAP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10064)) +#define rPMGR_MSR_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10068)) +#define rPMGR_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1006c)) +#define rPMGR_LIO_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10070)) +#define rPMGR_MCA0_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10074)) +#define rPMGR_MCA1_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10078)) +#define rPMGR_MCA2_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1007c)) +#define rPMGR_MCA3_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10080)) +#define rPMGR_MCA4_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10084)) +#define rPMGR_SEP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10088)) +#define rPMGR_GPIO_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1008c)) +#define rPMGR_SPI0_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10090)) +#define rPMGR_SPI1_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10094)) +#define rPMGR_SPI2_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10098)) +#define rPMGR_SPI3_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1009c)) +#define rPMGR_DEBUG_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100a0)) +#define rPMGR_PCIE_REF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100a4)) +#define rPMGR_PCIE_APP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100a8)) +#define rPMGR_TMPS_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100ac)) +#define rPMGR_MEDIA_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100b0)) +#define rPMGR_ISP_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100b4)) +#define rPMGR_GFX_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100b8)) +#define rPMGR_ANS_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100bc)) +#define rPMGR_ANC_LINK_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100c0)) + +#elif SUB_PLATFORM_T7001 + +#define rPMGR_NCO_REF0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10008)) +#define rPMGR_NCO_REF1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1000c)) +#define rPMGR_NCO_ALG0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10010)) +#define rPMGR_NCO_ALG1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10014)) +#define rPMGR_HSICPHY_REF_12M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10018)) +#define rPMGR_USB480_0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1001c)) +#define rPMGR_USB480_1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10020)) +#define rPMGR_USB_OHCI_48M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10024)) +#define rPMGR_USB_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10028)) +#define rPMGR_USB_FREE_60M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1002c)) +#define rPMGR_SIO_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10030)) +#define rPMGR_SIO_P_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10034)) +#define rPMGR_ISP_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10038)) +#define rPMGR_ISP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1003c)) +#define rPMGR_ISP_SENSOR0_REF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10040)) +#define rPMGR_ISP_SENSOR1_REF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10044)) +#define rPMGR_VDEC_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10048)) +#define rPMGR_VENC_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1004c)) +#define rPMGR_VID0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10050)) +#define rPMGR_DISP0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10054)) +#define rPMGR_DISP1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10058)) +#define rPMGR_AJPEG_IP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1005c)) +#define rPMGR_AJPEG_WRAP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10060)) +#define rPMGR_MSR_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10064)) +#define rPMGR_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10068)) +#define rPMGR_LIO_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1006c)) +#define rPMGR_MCA0_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10070)) +#define rPMGR_MCA1_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10074)) +#define rPMGR_MCA2_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10078)) +#define rPMGR_MCA3_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1007c)) +#define rPMGR_MCA4_M_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10080)) +#define rPMGR_SEP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10084)) +#define rPMGR_GPIO_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10088)) +#define rPMGR_SPI0_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1008c)) +#define rPMGR_SPI1_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10090)) +#define rPMGR_SPI2_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10094)) +#define rPMGR_SPI3_N_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10098)) +#define rPMGR_DEBUG_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1009c)) +#define rPMGR_PCIE_APP_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100a0)) +#define rPMGR_TMPS_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100a4)) +#define rPMGR_MEDIA_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100a8)) +#define rPMGR_ISP_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100ac)) +#define rPMGR_GFX_AF_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100b0)) +#define rPMGR_ANS_C_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100b4)) +#define rPMGR_ANC_LINK_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x100b8)) + +#endif + +#define PMGR_FIRST_CLK_CFG (&rPMGR_MCU_FIXED_CLK_CFG) +#define PMGR_LAST_CLK_CFG (&rPMGR_ANC_LINK_CLK_CFG) +#define PMGR_CLK_CFG_COUNT (((((void *)(PMGR_LAST_CLK_CFG)) - ((void *)(PMGR_FIRST_CLK_CFG))) / 4) + 1) +#define PMGR_CLK_NUM(_r) (((void *)&(rPMGR_ ## _r ## _CLK_CFG) - ((void *)(PMGR_FIRST_CLK_CFG))) / 4) + +#define rPMGR_S0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10208)) +#define rPMGR_S1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1020c)) +#define rPMGR_S2_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10210)) +#define rPMGR_S3_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10214)) +#define rPMGR_ISP_REF0_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10218)) +#define rPMGR_ISP_REF1_CLK_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1021c)) + +#define PMGR_FIRST_SPARE_CLK_CFG (&rPMGR_S0_CLK_CFG) +#define PMGR_LAST_SPARE_CLK_CFG (&rPMGR_ISP_REF1_CLK_CFG) +#define PMGR_SPARE_CLK_CFG_COUNT (((((void *)(PMGR_LAST_SPARE_CLK_CFG)) - ((void *)(PMGR_FIRST_SPARE_CLK_CFG))) / 4) + 1) + +#define rPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x10308)) + +#define PMGR_CLK_CFG_ENABLE (1 << 31) +#define PMGR_CLK_CFG_PENDING (1 << 30) +#define PMGR_CLK_CFG_PENDING_SHIFT (30) +#define PMGR_CLK_CFG_SRC_SEL_MASK (0x3F) +#define PMGR_CLK_CFG_CFG_SEL_SHIFT (16) +#define PMGR_CLK_CFG_SRC_SEL_SHIFT (24) +#define PMGR_CLK_CFG_SRC_SEL(_n) ((_n) << PMGR_CLK_CFG_SRC_SEL_SHIFT) +#define PMGR_CLK_CFG_DIVISOR_MASK (0x3F) +#define PMGR_CLK_CFG_DIVISOR(_n) ((_n) << 0) + +#define rPMGR_NCO_CLK_CFG(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x0)) +#define rPMGR_NCO_DIV_INT(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x4)) +#define rPMGR_NCO_DIV_FRAC_N1(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x8)) +#define rPMGR_NCO_DIV_FRAC_N2(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0xc)) +#define rPMGR_NCO_DIV_FRAC_PRIME(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * 0x1000 + 0x11000 + 0x10)) + +#define PMGR_NCO_CLK_CFG_PENDING (1 << 30) + +#define PMGR_NUM_NCO 5 + +#define kSOC_PERF_STATE_BYPASS (0) +#define kSOC_PERF_STATE_SECUREROM (kSOC_PERF_STATE_BYPASS + 1) +#define kSOC_PERF_STATE_IBOOT (kSOC_PERF_STATE_BYPASS + 2) +#define kSOC_PERF_STATE_IBOOT_MEM_LOW_PERF (kSOC_PERF_STATE_IBOOT + 0) +#define kSOC_PERF_STATE_IBOOT_MEM_FULL_PERF (kSOC_PERF_STATE_IBOOT + 1) +#define kSOC_PERF_STATE_VMIN (kSOC_PERF_STATE_IBOOT_MEM_FULL_PERF + 0) +#define kSOC_PERF_STATE_VNOM (kSOC_PERF_STATE_IBOOT_MEM_FULL_PERF + 1) + +#define kSOC_PERF_STATE_VMAX (kSOC_PERF_STATE_VNOM) + +#define kSOC_PERF_STATE_IBOOT_CNT (kSOC_PERF_STATE_VMAX + 1) + +#define rPMGR_SOC_PERF_STATE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1a000)) + +#define PMGR_SOC_PERF_STATE_CTL_PENDING_MASK (0xFFFF0000) +#define PMGR_SOC_PERF_STATE_CTL_CURRENT_SELECT_SHIFT (8) +#define PMGR_SOC_PERF_STATE_CTL_CURRENT_SELECT_MASK (0xF) + +#define rPMGR_SOC_PERF_STATE_SOCHOT (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1a004)) +#define PMGR_SOC_PERF_STATE_SOCHOT_ENABLE_TRIG1 (1 << 31) +#define PMGR_SOC_PERF_STATE_SOCHOT_ENABLE_TRIG0 (1 << 30) +#define PMGR_SOC_PERF_STATE_SOCHOT_TRIG1_SELECT(_n) (((_n) & 0xf) << 4) +#define PMGR_SOC_PERF_STATE_SOCHOT_TRIG0_SELECT(_n) (((_n) & 0xf) << 0) + +#define rPMGR_SOC_PERF_STATE_ENTRY_A(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + 0x1a010)) +#define rPMGR_SOC_PERF_STATE_ENTRY_B(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + 0x1a014)) +#define rPMGR_SOC_PERF_STATE_ENTRY_C(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + 0x1a018)) +#define rPMGR_SOC_PERF_STATE_ENTRY_D(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + 0x1a01c)) +#define PMGR_SOC_PERF_STATE_VOL_ADJ0(_n) ((_n & 0x3f) << (0 * 8)) +#define PMGR_SOC_PERF_STATE_VOL_ADJ1(_n) ((_n & 0x3f) << (1 * 8)) +#define PMGR_SOC_PERF_STATE_VOL_ADJ2(_n) ((_n & 0x3f) << (2 * 8)) +#define PMGR_SOC_PERF_STATE_VOL_ADJ3(_n) ((_n & 0x3f) << (3 * 8)) + + +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_CFG_SEL_MASK (0x00000300) +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_SRC_SEL_MASK (0x000000F0) +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_FIXED_SRC_SEL_MASK (0x00000001) +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_MASK (PMGR_SOC_PERF_STATE_ENTRY_MCU_CFG_SEL_MASK | \ + PMGR_SOC_PERF_STATE_ENTRY_MCU_SRC_SEL_MASK | \ + PMGR_SOC_PERF_STATE_ENTRY_MCU_FIXED_SRC_SEL_MASK) + +#define PMGR_SOC_PERF_STATE_COUNT (16) + +#define rPMGR_AGILE_CLK_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1b000)) + +#define kPMGR_GFX_STATE_MAX (16) +#define rPMGR_GFX_PERF_STATE_ENTRY(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + 0x1c000)) +#if SUB_PLATFORM_T7001 +#define rPMGR_GFX_SRAM_PERF_STATE_ENTRY(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + 0x1c004)) +#endif +#define rPMGR_GFX_PERF_STATE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1c200)) +#define rPMGR_GFX_PERF_STATE_SOCHOT (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x1c300)) +#define PMGR_GFX_PERF_STATE_SOCHOT_ENABLE_TRIG1 (1 << 31) +#define PMGR_GFX_PERF_STATE_SOCHOT_ENABLE_TRIG0 (1 << 30) +#define PMGR_GFX_PERF_STATE_SOCHOT_TRIG1_SELECT(_n) (((_n) & 0xf) << 4) +#define PMGR_GFX_PERF_STATE_SOCHOT_TRIG0_SELECT(_n) (((_n) & 0xf) << 0) + +#define rPMGR_CPU0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20000)) +#define rPMGR_CPU1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20008)) +#if SUB_PLATFORM_T7001 +#define rPMGR_CPU2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20010)) +#endif +#define rPMGR_CPM_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20040)) +#define rPMGR_LIO_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20100)) +#define rPMGR_IOMUX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20108)) +#define rPMGR_AIC_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20110)) +#define rPMGR_DEBUG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20118)) +#define rPMGR_DWI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20120)) +#define rPMGR_GPIO_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20128)) +#define rPMGR_MCA0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20130)) +#define rPMGR_MCA1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20138)) +#define rPMGR_MCA2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20140)) +#define rPMGR_MCA3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20148)) +#define rPMGR_MCA4_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20150)) +#define rPMGR_PWM0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20158)) +#define rPMGR_I2C0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20160)) +#define rPMGR_I2C1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20168)) +#define rPMGR_I2C2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20170)) +#define rPMGR_I2C3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20178)) +#define rPMGR_SPI0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20180)) +#define rPMGR_SPI1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20188)) +#define rPMGR_SPI2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20190)) +#define rPMGR_SPI3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20198)) +#define rPMGR_UART0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201a0)) +#define rPMGR_UART1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201a8)) +#define rPMGR_UART2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201b0)) +#define rPMGR_UART3_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201b8)) +#define rPMGR_UART4_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201c0)) +#define rPMGR_UART5_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201c8)) +#define rPMGR_UART6_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201d0)) +#define rPMGR_UART7_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201d8)) +#define rPMGR_UART8_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201e0)) +#define rPMGR_AES0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201e8)) +#define rPMGR_SIO_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201f0)) +#define rPMGR_SIO_P_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x201f8)) +#define rPMGR_HSIC0PHY_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20200)) +#define rPMGR_HSIC1PHY_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20208)) +#define rPMGR_ISPSENS0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20210)) +#define rPMGR_ISPSENS1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20218)) +#define rPMGR_PCIE_REF_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20220)) +#define rPMGR_ANP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20228)) +#define rPMGR_MCC_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20230)) +#define rPMGR_MCU_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20238)) +#define rPMGR_AMP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20240)) +#define rPMGR_USB_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20248)) +#define rPMGR_USBCTLREG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20250)) +#define rPMGR_USB2HOST0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20258)) +#define rPMGR_USB2HOST0_OHCI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20260)) +#define rPMGR_USB2HOST1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20268)) +#define rPMGR_USB2HOST1_OHCI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20270)) +#define rPMGR_USB2HOST2_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20278)) +#define rPMGR_USB2HOST2_OHCI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20280)) +#define rPMGR_USB_OTG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20288)) +#define rPMGR_SMX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20290)) +#define rPMGR_SF_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20298)) +#define rPMGR_CP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202a0)) +#if SUB_PLATFORM_T7000 +#define rPMGR_DISP_BUSMUX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202a8)) +#elif SUB_PLATFORM_T7001 +#define rPMGR_DISP0_BUSIF_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202a8)) +#endif +#define rPMGR_DISP0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202b0)) +#if SUB_PLATFORM_T7000 +#define rPMGR_MIPI_DSI_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202b8)) +#define rPMGR_DP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202c0)) +#elif SUB_PLATFORM_T7001 +#define rPMGR_DP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202b8)) +#define rPMGR_DISP1_BUSIF_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202c0)) +#endif +#define rPMGR_DISP1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202c8)) +#define rPMGR_ISP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202d0)) +#define rPMGR_MEDIA_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202d8)) +#define rPMGR_MSR_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202e0)) +#define rPMGR_JPG_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202e8)) +#define rPMGR_VDEC0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x202f0)) +#define rPMGR_VENC_CPU_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20300)) +#define rPMGR_PCIE_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20308)) +#define rPMGR_PCIE_AUX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20310)) +#define rPMGR_ANS_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20318)) +#define rPMGR_GFX_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20320)) +#define rPMGR_SEP_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x20400)) +#define rPMGR_VENC_PIPE_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x21000)) +#define rPMGR_VENC_ME0_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x21008)) +#define rPMGR_VENC_ME1_PS (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x21010)) + +#define PMGR_PS_RESET (1 << 31) +#define PMGR_PS_AUTO_PM_EN (1 << 28) +#define PMGR_PS_FORCE_NOACCESS (1 << 10) +#define PMGR_PS_ACTUAL_PS_SHIFT (4) +#define PMGR_PS_ACTUAL_PS_MASK (0xF) +#define PMGR_PS_MANUAL_PS_MASK (0xF) +#define PMGR_PS_RUN_MAX (0xF) +#define PMGR_PS_CLOCK_OFF (0x4) +#define PMGR_PS_POWER_OFF (0x0) + +#define PMGR_FIRST_PS (&rPMGR_CPU0_PS) +#define PMGR_LAST_PS (&rPMGR_VENC_ME1_PS) +#define PMGR_PS_COUNT (((((void *)(PMGR_LAST_PS)) - ((void *)(PMGR_FIRST_PS))) / 8) + 1) +#define PMGR_PS_NUM(_r) (((void *)&(rPMGR_ ## _r ## _PS) - ((void *)(PMGR_FIRST_PS))) / 8) + +#define rPMGR_PWRGATE_CPU0_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22000)) +#define rPMGR_PWRGATE_CPU1_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22010)) +#if SUB_PLATFORM_T7001 +#define rPMGR_PWRGATE_CPU2_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22020)) +#endif +#define rPMGR_PWRGATE_CPM_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22080)) +#define rPMGR_PWRGATE_AMC_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22090)) +#define rPMGR_PWRGATE_AMC_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22094)) +#define rPMGR_PWRGATE_AMC_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22098)) +#define rPMGR_PWRGATE_AMC_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2209c)) +#define rPMGR_PWRGATE_USB_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220a0)) +#define rPMGR_PWRGATE_USB_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220a4)) +#define rPMGR_PWRGATE_USB_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220a8)) +#define rPMGR_PWRGATE_USB_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220ac)) +#define rPMGR_PWRGATE_ACS_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220b0)) +#define rPMGR_PWRGATE_ACS_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220b4)) +#define rPMGR_PWRGATE_ACS_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220b8)) +#define rPMGR_PWRGATE_ACS_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220bc)) +#define rPMGR_PWRGATE_DISP0_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220c0)) +#define rPMGR_PWRGATE_DISP0_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220c4)) +#define rPMGR_PWRGATE_DISP0_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220c8)) +#define rPMGR_PWRGATE_DISP0_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220cc)) +#define rPMGR_PWRGATE_DISP1_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220d0)) +#define rPMGR_PWRGATE_DISP1_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220d4)) +#define rPMGR_PWRGATE_DISP1_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220d8)) +#define rPMGR_PWRGATE_DISP1_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220dc)) +#define rPMGR_PWRGATE_ISP_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220e0)) +#define rPMGR_PWRGATE_ISP_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220e4)) +#define rPMGR_PWRGATE_ISP_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220e8)) +#define rPMGR_PWRGATE_ISP_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220ec)) +#define rPMGR_PWRGATE_MEDIA_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220f0)) +#define rPMGR_PWRGATE_MEDIA_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220f4)) +#define rPMGR_PWRGATE_MEDIA_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220f8)) +#define rPMGR_PWRGATE_MEDIA_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x220fc)) +#define rPMGR_PWRGATE_VDEC0_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22100)) +#define rPMGR_PWRGATE_VDEC0_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22104)) +#define rPMGR_PWRGATE_VDEC0_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22108)) +#define rPMGR_PWRGATE_VDEC0_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2210c)) +#if SUB_PLATFORM_T7000 +#define rPMGR_PWRGATE_VENC_CPU_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22120)) +#define rPMGR_PWRGATE_VENC_CPU_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22124)) +#define rPMGR_PWRGATE_VENC_CPU_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22128)) +#define rPMGR_PWRGATE_VENC_CPU_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2212c)) +#define rPMGR_PWRGATE_PCIE_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22130)) +#define rPMGR_PWRGATE_PCIE_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22134)) +#define rPMGR_PWRGATE_PCIE_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22138)) +#define rPMGR_PWRGATE_PCIE_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2213c)) +#define rPMGR_PWRGATE_ANS_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22140)) +#define rPMGR_PWRGATE_ANS_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22144)) +#define rPMGR_PWRGATE_ANS_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22148)) +#define rPMGR_PWRGATE_ANS_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2214c)) +#define rPMGR_PWRGATE_GFX_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22150)) +#define rPMGR_PWRGATE_GFX_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22154)) +#define rPMGR_PWRGATE_GFX_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22158)) +#define rPMGR_PWRGATE_GFX_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2215c)) +#define rPMGR_PWRGATE_SEP_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22160)) +#define rPMGR_PWRGATE_SEP_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22164)) +#define rPMGR_PWRGATE_SEP_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22168)) +#define rPMGR_PWRGATE_SEP_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2216c)) +#define rPMGR_PWRGATE_VENC_PIPE_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22170)) +#define rPMGR_PWRGATE_VENC_PIPE_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22174)) +#define rPMGR_PWRGATE_VENC_PIPE_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22178)) +#define rPMGR_PWRGATE_VENC_PIPE_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2217c)) +#define rPMGR_PWRGATE_VENC_ME0_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22180)) +#define rPMGR_PWRGATE_VENC_ME0_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22184)) +#define rPMGR_PWRGATE_VENC_ME0_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22188)) +#define rPMGR_PWRGATE_VENC_ME0_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2218c)) +#define rPMGR_PWRGATE_VENC_ME1_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22190)) +#define rPMGR_PWRGATE_VENC_ME1_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22194)) +#define rPMGR_PWRGATE_VENC_ME1_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22198)) +#define rPMGR_PWRGATE_VENC_ME1_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2219c)) +#define rPMGR_PWRGATE_MCU_ASYNC_RESET (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22300)) +#elif SUB_PLATFORM_T7001 +#define rPMGR_PWRGATE_VENC_CPU_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22110)) +#define rPMGR_PWRGATE_VENC_CPU_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22114)) +#define rPMGR_PWRGATE_VENC_CPU_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22118)) +#define rPMGR_PWRGATE_VENC_CPU_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2211c)) +#define rPMGR_PWRGATE_PCIE_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22120)) +#define rPMGR_PWRGATE_PCIE_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22124)) +#define rPMGR_PWRGATE_PCIE_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22128)) +#define rPMGR_PWRGATE_PCIE_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2212c)) +#define rPMGR_PWRGATE_ANS_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22130)) +#define rPMGR_PWRGATE_ANS_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22134)) +#define rPMGR_PWRGATE_ANS_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22138)) +#define rPMGR_PWRGATE_ANS_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2213c)) +#define rPMGR_PWRGATE_GFX_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22140)) +#define rPMGR_PWRGATE_GFX_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22144)) +#define rPMGR_PWRGATE_GFX_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22148)) +#define rPMGR_PWRGATE_GFX_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2214c)) +#define rPMGR_PWRGATE_SEP_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22150)) +#define rPMGR_PWRGATE_SEP_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22154)) +#define rPMGR_PWRGATE_SEP_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22158)) +#define rPMGR_PWRGATE_SEP_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2215c)) +#define rPMGR_PWRGATE_VENC_PIPE_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22160)) +#define rPMGR_PWRGATE_VENC_PIPE_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22164)) +#define rPMGR_PWRGATE_VENC_PIPE_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22168)) +#define rPMGR_PWRGATE_VENC_PIPE_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2216c)) +#define rPMGR_PWRGATE_VENC_ME0_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22170)) +#define rPMGR_PWRGATE_VENC_ME0_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22174)) +#define rPMGR_PWRGATE_VENC_ME0_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22178)) +#define rPMGR_PWRGATE_VENC_ME0_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2217c)) +#define rPMGR_PWRGATE_VENC_ME1_CFG0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22180)) +#define rPMGR_PWRGATE_VENC_ME1_CFG1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22184)) +#define rPMGR_PWRGATE_VENC_ME1_CFG2 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22188)) +#define rPMGR_PWRGATE_VENC_ME1_DBG (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2218c)) +#endif +#define rPMGR_PWRGATE_MCU_ASYNC_RESET (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x22300)) + +#define rPMGR_VOLMAN_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x23000)) +#define rPMGR_VOLMAN_VAR_SOC_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x23004)) +#define rPMGR_VOLMAN_FIXED_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x23008)) +#define rPMGR_VOLMAN_GFX_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2300c)) +#define rPMGR_VOLMAN_CPU_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x23010)) +#define rPMGR_VOLMAN_VAR_SOC_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x23014)) +#define rPMGR_VOLMAN_FIXED_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x23018)) +#define rPMGR_VOLMAN_GFX_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2301c)) +#define rPMGR_VOLMAN_CPU_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x23020)) +#define PMGR_VOLMAN_DISABLE_CPU_VOL_CHANGE (1 << 11) +#define PMGR_VOLMAN_DISABLE_GFX_VOL_CHANGE (1 << 10) +#define PMGR_VOLMAN_DISABLE_FIXED_VOL_CHANGE (1 << 9) +#define PMGR_VOLMAN_DISABLE_VAR_SOC_VOL_CHANGE (1 << 8) + +#define rPMGR_EMA_FIXED_GFX0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x26010)) +#define rPMGR_EMA_FIXED_GFX1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x26014)) + +#define rPMGR_CHIP_WDOG_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27000)) +#define rPMGR_CHIP_WDOG_RST_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27004)) +#define rPMGR_CHIP_WDOG_INTR_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27008)) +#define rPMGR_CHIP_WDOG_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2700c)) +#define rPMGR_SYS_WDOG_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27010)) +#define rPMGR_SYS_WDOG_RST_CNT (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x27014)) +#define rPMGR_SYS_WDOG_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + 0x2701c)) + +#define rPMGR_SCRATCH(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x29000 + ((_n)*4))) +#define rPMGR_SCRATCH0 rPMGR_SCRATCH(0) /* Flags */ +#define rPMGR_SCRATCH1 rPMGR_SCRATCH(1) +#define rPMGR_SCRATCH2 rPMGR_SCRATCH(2) +#define rPMGR_SCRATCH3 rPMGR_SCRATCH(3) +#define rPMGR_SCRATCH4 rPMGR_SCRATCH(4) +#define rPMGR_SCRATCH5 rPMGR_SCRATCH(5) +#define rPMGR_SCRATCH6 rPMGR_SCRATCH(6) +#define rPMGR_SCRATCH7 rPMGR_SCRATCH(7) /* Consistent debug root pointer */ +#define rPMGR_SCRATCH8 rPMGR_SCRATCH(8) +#define rPMGR_SCRATCH9 rPMGR_SCRATCH(9) +#define rPMGR_SCRATCH10 rPMGR_SCRATCH(10) +#define rPMGR_SCRATCH11 rPMGR_SCRATCH(11) +#define rPMGR_SCRATCH12 rPMGR_SCRATCH(12) +#define rPMGR_SCRATCH13 rPMGR_SCRATCH(13) /* Memory info */ +#define rPMGR_SCRATCH14 rPMGR_SCRATCH(14) /* Boot Nonce 0 */ +#define rPMGR_SCRATCH15 rPMGR_SCRATCH(15) /* Boot Nonce 1 */ +#define rPMGR_SCRATCH16 rPMGR_SCRATCH(16) /* Boot Manifest Hash 0 */ +#define rPMGR_SCRATCH17 rPMGR_SCRATCH(17) /* Boot Manifest Hash 1 */ +#define rPMGR_SCRATCH18 rPMGR_SCRATCH(18) /* Boot Manifest Hash 2 */ +#define rPMGR_SCRATCH19 rPMGR_SCRATCH(19) /* Boot Manifest Hash 3 */ +#define rPMGR_SCRATCH20 rPMGR_SCRATCH(20) /* Boot Manifest Hash 4 */ +#define rPMGR_SCRATCH21 rPMGR_SCRATCH(21) +#define rPMGR_SCRATCH22 rPMGR_SCRATCH(22) +#define rPMGR_SCRATCH23 rPMGR_SCRATCH(23) + +#define rPMGR_THERMAL0_CTL0_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b000)) +#define rPMGR_THERMAL0_CTL0_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b004)) +#define rPMGR_THERMAL0_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b008)) +#define rPMGR_THERMAL0_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b00c)) +#define rPMGR_THERMAL0_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b010)) +#define rPMGR_THERMAL0_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b014)) +#define rPMGR_THERMAL0_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b018)) +#define rPMGR_THERMAL0_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b01c)) +#define rPMGR_THERMAL0_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b020)) +#define rPMGR_THERMAL0_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b024)) +#define rPMGR_THERMAL0_PIECE0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b028)) +#define rPMGR_THERMAL0_PIECE1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b02c)) +#define rPMGR_THERMAL0_PIECE2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b030)) +#define rPMGR_THERMAL0_ALARM0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b034)) +#define rPMGR_THERMAL0_ALARM1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b038)) +#define rPMGR_THERMAL0_ALARM2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b03c)) +#define rPMGR_THERMAL0_ALARM3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b040)) +#define rPMGR_THERMAL1_CTL0_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b044)) +#define rPMGR_THERMAL1_CTL0_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b048)) +#define rPMGR_THERMAL1_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b04c)) +#define rPMGR_THERMAL1_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b050)) +#define rPMGR_THERMAL1_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b054)) +#define rPMGR_THERMAL1_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b058)) +#define rPMGR_THERMAL1_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b05c)) +#define rPMGR_THERMAL1_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b060)) +#define rPMGR_THERMAL1_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b064)) +#define rPMGR_THERMAL1_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b068)) +#define rPMGR_THERMAL1_PIECE0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b06c)) +#define rPMGR_THERMAL1_PIECE1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b070)) +#define rPMGR_THERMAL1_PIECE2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b074)) +#define rPMGR_THERMAL1_ALARM0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b078)) +#define rPMGR_THERMAL1_ALARM1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b07c)) +#define rPMGR_THERMAL1_ALARM2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b080)) +#define rPMGR_THERMAL1_ALARM3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2b084)) + +#define PMGR_THERMAL_CTL0_ENABLE (1 << 0) +#define PMGR_THERMAL_PARAM_TRIM_MASK (0x1F) +#define PMGR_THERMAL_PARAM_TRIM_SHIFT (0) +#define PMGR_THERMAL_PARAM_TRIM(_t) (((_t) & PMGR_THERMAL_PARAM_TRIM_MASK) << PMGR_THERMAL_PARAM_TRIM_SHIFT) +#define PMGR_THERMAL_PARAM_SET_TRIM(_reg, _t) (((_reg) & ~PMGR_THERMAL_PARAM_TRIM(PMGR_THERMAL_PARAM_TRIM_MASK)) | PMGR_THERMAL_PARAM_TRIM(_t)) +#define PMGR_THERMAL_PIECE_START_CODE_MASK (0x3FF) +#define PMGR_THERMAL_PIECE_OFFSET_MASK (0x1FF) +#define PMGR_THERMAL_PIECE_SLOPE_MASK (0x3FF) +#define PMGR_THERMAL_PIECE_START_CODE_SHIFT (22) +#define PMGR_THERMAL_PIECE_OFFSET_SHIFT (10) +#define PMGR_THERMAL_PIECE_SLOPE_SHIFT (0) +#define PMGR_THERMAL_PIECE_START_CODE(_c) (((_c) & PMGR_THERMAL_PIECE_START_CODE_MASK) << PMGR_THERMAL_PIECE_START_CODE_SHIFT) +#define PMGR_THERMAL_PIECE_OFFSET(_o) (((_o) & PMGR_THERMAL_PIECE_OFFSET_MASK) << PMGR_THERMAL_PIECE_OFFSET_SHIFT) +#define PMGR_THERMAL_PIECE_SLOPE(_s) (((_s) & PMGR_THERMAL_PIECE_SLOPE_MASK) << PMGR_THERMAL_PIECE_SLOPE_SHIFT) +#define PMGR_THERMAL_PIECE(_c, _o, _s) (PMGR_THERMAL_PIECE_START_CODE(_c) | PMGR_THERMAL_PIECE_OFFSET(_o) | PMGR_THERMAL_PIECE_SLOPE(_s)) + +#define rPMGR_SOCHOT_FAILSAFE_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C000)) +#define rPMGR_SOCHOT_FAILSAFE_TRIP_TEMP_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C010)) +#define rPMGR_SOCHOT_FAILSAFE_TRIP_TEMP_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C014)) +#define rPMGR_SOCHOT_FAILSAFE_ASSERT_COUNT_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C018)) +#define rPMGR_SOCHOT_FAILSAFE_ASSERT_COUNT_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C01C)) +#define rPMGR_SOCHOT_FAILSAFE_DEASSERT_COUNT_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C020)) +#define rPMGR_SOCHOT_FAILSAFE_DEASSERT_COUNT_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C024)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT0_COUNT_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C080)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT0_COUNT_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C084)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT1_COUNT_LO (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C088)) +#define rPMGR_SOCHOT_FAILSAFE_SOCHOT1_COUNT_HI (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2C08C)) + +#define rPMGR_TVM_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D000)) +#define rPMGR_TVM_THRESH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D004)) +#define rPMGR_TVM_THRESH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D008)) +#define rPMGR_TVM_THRESH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D00C)) +#define rPMGR_TVM_TEMP0_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D010)) +#define rPMGR_TVM_TEMP1_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D014)) +#define rPMGR_TVM_DEBUG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D100)) +#define rPMGR_TVM_DEBUG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D104)) +#define rPMGR_TVM_DEBUG2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + 0x2D108)) +#define PMGR_TVM_THRESH(_t) ((_t) & 0x1FF) +#define PMGR_TVM_TEMP_CFG_MAX_OFFSET(_mo) (((_mo) & 0x1FF) << 16) +#define PMGR_TVM_TEMP_CFG_MIN_OFFSET(_mo) (((_mo) & 0x1FF) << 0) + +#define rPMGR_MISC_ACG (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x32000)) + +#define rPMGR_MISC_SPARE0 (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x33000)) + +#if SUB_PLATFORM_T7001 +#define rPMGR_DEBUG_PMGR_DEBUG18 (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x40048)) +#endif + +#if SUB_PLATFORM_T7000 +enum { // clock-id + PMGR_CLK_OSC = 0, // 0x00 + PMGR_CLK_PLL0, // 0x01 + PMGR_CLK_PLL1, // 0x02 + PMGR_CLK_PLL2, // 0x03 + PMGR_CLK_PLL3, // 0x04 + PMGR_CLK_PLL4, // 0x05 + PMGR_CLK_PLL5, // 0x06 + PMGR_CLK_CPU, // 0x07 + PMGR_CLK_MCU_FIXED, // 0x08 + PMGR_CLK_SOURCE_FIRST = PMGR_CLK_MCU_FIXED, + PMGR_CLK_MCU, // 0x09 + PMGR_CLK_MIPI_DSI, // 0x0A + PMGR_CLK_NCO_REF0, // 0x0B + PMGR_CLK_NCO_REF1, // 0x0C + PMGR_CLK_NCO_ALG0, // 0x0D + PMGR_CLK_NCO_ALG1, // 0x0E + PMGR_CLK_HSICPHY_REF_12M, // 0x0F + PMGR_CLK_USB480_0, // 0x10 + PMGR_CLK_USB480_1, // 0x11 + PMGR_CLK_USB_OHCI_48M, // 0x12 + PMGR_CLK_USB, // 0x13 + PMGR_CLK_USB_FREE_60M, // 0x14 + PMGR_CLK_SIO_C, // 0x15 + PMGR_CLK_SIO_P, // 0x16 + PMGR_CLK_ISP_C, // 0x17 + PMGR_CLK_ISP, // 0x18 + PMGR_CLK_ISP_SENSOR0_REF, // 0x19 + PMGR_CLK_ISP_SENSOR1_REF, // 0x1A + PMGR_CLK_VDEC, // 0x1B + PMGR_CLK_VENC, // 0x1C + PMGR_CLK_VID0, // 0x1D + PMGR_CLK_DISP0, // 0x1E + PMGR_CLK_DISP1, // 0x1F + PMGR_CLK_AJPEG_IP, // 0x20 + PMGR_CLK_AJPEG_WRAP, // 0x21 + PMGR_CLK_MSR, // 0x22 + PMGR_CLK_AF, // 0x23 + PMGR_CLK_LIO, // 0x24 + PMGR_CLK_MCA0_M, // 0x25 + PMGR_CLK_MCA1_M, // 0x26 + PMGR_CLK_MCA2_M, // 0x27 + PMGR_CLK_MCA3_M, // 0x28 + PMGR_CLK_MCA4_M, // 0x29 + PMGR_CLK_SEP, // 0x2A + PMGR_CLK_GPIO, // 0x2B + PMGR_CLK_SPI0_N, // 0x2C + PMGR_CLK_SPI1_N, // 0x2D + PMGR_CLK_SPI2_N, // 0x2E + PMGR_CLK_SPI3_N, // 0x2F + PMGR_CLK_DEBUG, // 0x30 + PMGR_CLK_PCIE_REF, // 0x31 + PMGR_CLK_PCIE_APP, // 0x32 + PMGR_CLK_TMPS, // 0x33 + PMGR_CLK_MEDIA_AF, // 0x34 + PMGR_CLK_ISP_AF, // 0x35 + PMGR_CLK_GFX_AF, // 0x36 + PMGR_CLK_ANS_C, // 0x37 + PMGR_CLK_ANC_LINK, // 0x38 + PMGR_CLK_SOURCE_LAST = PMGR_CLK_ANC_LINK, + PMGR_CLK_S0, // 0x39 + PMGR_CLK_S1, // 0x3A + PMGR_CLK_S2, // 0x3B + PMGR_CLK_S3, // 0x3C + PMGR_CLK_ISP_REF0, // 0x3D + PMGR_CLK_ISP_REF1, // 0x3E + PMGR_CLK_COUNT, // 0x3F + PMGR_CLK_NOT_SUPPORTED +}; + +#elif SUB_PLATFORM_T7001 +enum { // clock-id + PMGR_CLK_OSC = 0, // 0x00 + PMGR_CLK_PLL0, // 0x01 + PMGR_CLK_PLL1, // 0x02 + PMGR_CLK_PLL2, // 0x03 + PMGR_CLK_PLL3, // 0x04 + PMGR_CLK_PLL4, // 0x05 + PMGR_CLK_PLL5, // 0x06 + PMGR_CLK_CPU, // 0x07 + PMGR_CLK_MCU_FIXED, // 0x08 + PMGR_CLK_SOURCE_FIRST = PMGR_CLK_MCU_FIXED, + PMGR_CLK_MCU, // 0x09 + PMGR_CLK_NCO_REF0, // 0x0A + PMGR_CLK_NCO_REF1, // 0x0B + PMGR_CLK_NCO_ALG0, // 0x0C + PMGR_CLK_NCO_ALG1, // 0x0D + PMGR_CLK_HSICPHY_REF_12M, // 0x0E + PMGR_CLK_USB480_0, // 0x0F + PMGR_CLK_USB480_1, // 0x10 + PMGR_CLK_USB_OHCI_48M, // 0x11 + PMGR_CLK_USB, // 0x12 + PMGR_CLK_USB_FREE_60M, // 0x13 + PMGR_CLK_SIO_C, // 0x14 + PMGR_CLK_SIO_P, // 0x15 + PMGR_CLK_ISP_C, // 0x16 + PMGR_CLK_ISP, // 0x17 + PMGR_CLK_ISP_SENSOR0_REF, // 0x18 + PMGR_CLK_ISP_SENSOR1_REF, // 0x19 + PMGR_CLK_VDEC, // 0x1A + PMGR_CLK_VENC, // 0x1B + PMGR_CLK_VID0, // 0x1C + PMGR_CLK_DISP0, // 0x1D + PMGR_CLK_DISP1, // 0x1E + PMGR_CLK_AJPEG_IP, // 0x1F + PMGR_CLK_AJPEG_WRAP, // 0x20 + PMGR_CLK_MSR, // 0x21 + PMGR_CLK_AF, // 0x22 + PMGR_CLK_LIO, // 0x23 + PMGR_CLK_MCA0_M, // 0x24 + PMGR_CLK_MCA1_M, // 0x25 + PMGR_CLK_MCA2_M, // 0x26 + PMGR_CLK_MCA3_M, // 0x27 + PMGR_CLK_MCA4_M, // 0x28 + PMGR_CLK_SEP, // 0x29 + PMGR_CLK_GPIO, // 0x2A + PMGR_CLK_SPI0_N, // 0x2B + PMGR_CLK_SPI1_N, // 0x2C + PMGR_CLK_SPI2_N, // 0x2D + PMGR_CLK_SPI3_N, // 0x2E + PMGR_CLK_DEBUG, // 0x2F + PMGR_CLK_PCIE_APP, // 0x30 + PMGR_CLK_TMPS, // 0x31 + PMGR_CLK_MEDIA_AF, // 0x32 + PMGR_CLK_ISP_AF, // 0x33 + PMGR_CLK_GFX_AF, // 0x34 + PMGR_CLK_ANS_C, // 0x35 + PMGR_CLK_ANC_LINK, // 0x36 + PMGR_CLK_SOURCE_LAST = PMGR_CLK_ANC_LINK, + PMGR_CLK_S0, // 0x37 + PMGR_CLK_S1, // 0x38 + PMGR_CLK_S2, // 0x39 + PMGR_CLK_S3, // 0x3A + PMGR_CLK_ISP_REF0, // 0x3B + PMGR_CLK_ISP_REF1, // 0x3C + PMGR_CLK_COUNT, // 0x3D + PMGR_CLK_NOT_SUPPORTED +}; + +#endif + +#define PMGR_CLK_CFG_INDEX(_clk) ((_clk) - PMGR_CLK_MCU_FIXED) +//////////////////////////////////////////////////////////// +// +// CCC specific +// +//////////////////////////////////////////////////////////// + +#define CCC_PWRCTL_BASE (CCC_ROM_TABLE_BASE_ADDR + 0x220000) +#define CCC_CPM_THERMAL_BASE (CCC_ROM_TABLE_BASE_ADDR + 0x230000) + +#define rCCC_PSW_DLY (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x000)) + +#define rCCC_PRE_TD_TMR (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x008)) +#define rCCC_PRE_FLUSH_TMR (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x010)) + +#define rCCC_APSC_SCR (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x020)) +#define CCC_APSC_PENDING (1 << 31) +#define CCC_APSC_MANUAL_CHANGE(_d) ((1 << 25) | (((_d) & 0x7) << 22)) + +#define rCCC_DVFM_CFG (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x040)) +#define CCC_DVFM_CFG_TEMPOFFSET1(_to) (((_to) & 0x7F) << 21) +#define CCC_DVFM_CFG_TEMPOFFSET0(_to) (((_to) & 0x7F) << 14) +#define CCC_DVFM_CFG_TEMPTHRESH1(_tt) (((_tt) & 0x7F) << 7) +#define CCC_DVFM_CFG_TEMPTHRESH0(_tt) (((_tt) & 0x7F) << 0) + +#define rCCC_DVFM_SCR (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x048)) // 64-bit +#define CCC_DVFM_SCR_TEMPSENSORMODE (1) + +#define rCCC_DVFM_CFG_SEL (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x050)) + +#define rCCC_DVFM_CFG1 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x058)) +#define CCC_DVFM_CFG1_TEMPOFFSET2(_to) (((_to) & 0x7F) << 7) +#define CCC_DVFM_CFG1_TEMPTHRESH2(_tt) (((_tt) & 0x7F) << 0) + +#define rCCC_EFUSE_DVFM0 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0A8)) +#define rCCC_EFUSE_REV (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0B0)) + +#define rCCC_PLL_DLY_CFG0 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0E0)) +#define rCCC_PLL_DLY_CFG1 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0E8)) +#define rCCC_PLL_CFG0 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0D0)) + +#define rCCC_PLL_CFG1 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0D8)) +#define CCC_PLL_CFG1_PLL_VCO_RCTRL_SEL (1 << 11) +#define CCC_PLL_CFG1_PLL_VCO_RCTRL_OW_SHIFT (14) +#define CCC_PLL_CFG1_PLL_VCO_RCTRL_OW_MASK (0x7) + +#define rCCC_PLL_CFG2 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0F8)) +#define CCC_PLL_CFG2_RELOCKBYS2_S4_MASK (0x6) +#define CCC_PLL_CFG2_RELOCKBYS2_S4_DIV2 (0x6) + +#define rCCC_EFUSE_DVFM1 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x100)) + +#define kDVFM_STATE_BYPASS (0) +#define kDVFM_STATE_SECUREROM (kDVFM_STATE_BYPASS + 1) +#define kDVFM_STATE_IBOOT (kDVFM_STATE_BYPASS + 2) +#define kDVFM_STATE_V0 (kDVFM_STATE_IBOOT + 0) +#define kDVFM_STATE_V1 (kDVFM_STATE_IBOOT + 1) +#define kDVFM_STATE_V2 (kDVFM_STATE_IBOOT + 2) +#define kDVFM_STATE_V3 (kDVFM_STATE_IBOOT + 3) +#if !SUB_TARGET_N102 +#define kDVFM_STATE_V4 (kDVFM_STATE_IBOOT + 4) +#endif +#if SUB_TARGET_N102 +#define kDVFM_STATE_VMAX (kDVFM_STATE_V3) +#elif SUB_PLATFORM_T7000 && !SUB_TARGET_J96 && !SUB_TARGET_J97 +#define kDVFM_STATE_VMAX (kDVFM_STATE_V4) +#else +#define kDVFM_STATE_V5 (kDVFM_STATE_IBOOT + 5) +#define kDVFM_STATE_V6 (kDVFM_STATE_IBOOT + 6) +#define kDVFM_STATE_V6_UNBINNED (kDVFM_STATE_IBOOT + 7) +#define kDVFM_STATE_VMAX (kDVFM_STATE_V5) +#endif + +#define kDVFM_STATE_VNOM (kDVFM_STATE_V2) + +#define kDVFM_STATE_VBOOST (kDVFM_STATE_VMAX) + +#define kDVFM_STATE_IBOOT_CNT (kDVFM_STATE_VMAX + 1) + +#define kVOLTAGE_STATES1_COUNT (kDVFM_STATE_VMAX - kDVFM_STATE_V0 + 1) +#define kVOLTAGE_STATES1_SIZE (kVOLTAGE_STATES1_COUNT*2) // Minimum size of voltage-state1 property in devicetree + +#define CCC_DVFM_STATE_COUNT (8) +#define rCCC_DVFM_ST(_n) (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x068 + ((_n) * 8))) +#if SUB_PLATFORM_T7001 +#define CCC_DVFM_SRAM_STATE(_int,_state,_vid) (_int | (_vid & 0xffULL) << (8 * _state)) +#define rCCC_DVFM_SRAM (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x110)) +#endif + +#define CCC_DVFM_ST_TO_SAFEVOL(_st) (((uint64_t)(_st) >> 56) & 0xff) +#define CCC_DVFM_ST_SAFEVOL(_sv) (((uint64_t)(_sv) & 0xFF) << 56) +#define CCC_DVFM_ST_VOLADJ3(_va) (((uint64_t)(_va) & 0x3F) << 48) +#define CCC_DVFM_ST_VOLADJ2(_va) (((uint64_t)(_va) & 0x3F) << 42) +#define CCC_DVFM_ST_VOLADJ1(_va) (((uint64_t)(_va) & 0x3F) << 36) +#define CCC_DVFM_ST_VOLADJ0(_va) (((uint64_t)(_va) & 0x3F) << 30) +#define CCC_DVFM_ST_PLL_P(_p) (((_p) & 0x1F) << 13) +#define CCC_DVFM_ST_PLL_M(_m) (((_m) & 0x1FF) << 4) +#define CCC_DVFM_ST_PLL_S(_s) (((_s) & 0xF) << 0) + +#define rCCC_PWRCTRL_MSTR_PLLCTL (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0B8)) + +#define rCCC_PWRCTRL_PLL_SCR0 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0C0)) + +#define rCCC_PWRCTRL_PLL_SCR1 (*(volatile uint32_t *)(CCC_PWRCTL_BASE + 0x0C8)) + +#define rCCC_IEX_NRG_WGHT (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x240)) +#define rCCC_LSU_NRG_WGHT (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x250)) +#define rCCC_DCD_NRG_WGHT (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x258)) +#define rCCC_NEX_NRG_WGHT0 (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x260)) +#define rCCC_NEX_NRG_WGHT1 (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x268)) +#define rCCC_NEX_NRG_WGHT2 (*(volatile uint64_t *)(CCC_PWRCTL_BASE + 0x270)) + +#define rCCC_THRM0_CTL0_SET (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x000)) +#define rCCC_THRM0_CTL1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x008)) +#define rCCC_THRM0_CTL2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x010)) +#define rCCC_THRM0_PARAM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x018)) +#define rCCC_THRM0_RD_BK0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x020)) +#define rCCC_THRM0_RD_BK1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x028)) +#define rCCC_THRM0_SUM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x030)) +#define rCCC_THRM0_SUM_CNT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x038)) +#define rCCC_THRM1_CTL0_SET (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x040)) +#define rCCC_THRM1_CTL1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x048)) +#define rCCC_THRM1_CTL2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x050)) +#define rCCC_THRM1_PARAM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x058)) +#define rCCC_THRM1_RD_BK0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x060)) +#define rCCC_THRM1_RD_BK1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x068)) +#define rCCC_THRM1_SUM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x070)) +#define rCCC_THRM1_SUM_CNT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x078)) +#define rCCC_THRM_FSCTL (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x080)) +#define rCCC_THRM_FSTRIP_T0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x090)) +#define rCCC_THRM_FSTRIP_T1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x098)) +#define rCCC_THRM_FSASRT_CNT0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x0a0)) +#define rCCC_THRM_FSASRT_CNT1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x0a8)) +#define rCCC_THRM_FSDE_ASRT_CNT0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x0b0)) +#define rCCC_THRM_FSDE_ASRT_CNT1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x0b8)) +#define rCCC_THRM_FSHOT0_TSTAMP (*(volatile uint64_t*)(CCC_CPM_THERMAL_BASE + 0x0c0)) // 64-bit +#define rCCC_THRM_FSHOT1_TSTAMP (*(volatile uint64_t*)(CCC_CPM_THERMAL_BASE + 0x0c8)) // 64-bit +#define rCCC_DVFM_FSHOT_IDX (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x0f0)) +#define rCCC_THRM0_PIECE0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x100)) +#define rCCC_THRM0_PIECE1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x108)) +#define rCCC_THRM0_PIECE2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x110)) +#define rCCC_THRM1_PIECE0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x118)) +#define rCCC_THRM1_PIECE1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x120)) +#define rCCC_THRM1_PIECE2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x128)) +#define rCCC_THRM2_PIECE0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x130)) +#define rCCC_THRM2_PIECE1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x138)) +#define rCCC_THRM2_PIECE2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x140)) +#if SUB_PLATFORM_T7001 +#define rCCC_THRM3_PIECE0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x150)) +#define rCCC_THRM3_PIECE1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x158)) +#define rCCC_THRM3_PIECE2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x160)) +#endif +#define rCCC_THRM2_CTL0_SET (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x200)) +#define rCCC_THRM2_CTL1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x208)) +#define rCCC_THRM2_CTL2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x210)) +#define rCCC_THRM2_PARAM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x218)) +#define rCCC_THRM2_RD_BK0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x220)) +#define rCCC_THRM2_RD_BK1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x228)) +#define rCCC_THRM2_SUM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x230)) +#define rCCC_THRM2_SUM_CNT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x238)) +#define rCCC_THRM0_CTL0_STAT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x400)) +#define rCCC_THRM0_CTL0_CLR (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x408)) +#define rCCC_THRM0_ALARM0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x410)) +#define rCCC_THRM0_ALARM1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x418)) +#define rCCC_THRM0_ALARM2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x420)) +#define rCCC_THRM0_ALARM3 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x428)) +#define rCCC_THRM1_CTL0_STAT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x430)) +#define rCCC_THRM1_CTL0_CLR (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x438)) +#define rCCC_THRM1_ALARM0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x440)) +#define rCCC_THRM1_ALARM1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x448)) +#define rCCC_THRM1_ALARM2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x450)) +#define rCCC_THRM1_ALARM3 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x458)) +#define rCCC_THRM2_CTL0_STAT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x460)) +#define rCCC_THRM2_CTL0_CLR (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x468)) +#define rCCC_THRM2_ALARM0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x470)) +#define rCCC_THRM2_ALARM1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x478)) +#define rCCC_THRM2_ALARM2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x480)) +#define rCCC_THRM2_ALARM3 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x488)) +#if SUB_PLATFORM_T7001 +#define rCCC_THRM3_CTL0_SET (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x500)) +#define rCCC_THRM3_CTL1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x508)) +#define rCCC_THRM3_CTL2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x510)) +#define rCCC_THRM3_PARAM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x518)) +#define rCCC_THRM3_RD_BK0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x520)) +#define rCCC_THRM3_RD_BK1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x528)) +#define rCCC_THRM3_SUM (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x530)) +#define rCCC_THRM3_SUM_CNT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x538)) +#define rCCC_THRM3_CTL0_STAT (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x760)) +#define rCCC_THRM3_CTL0_CLR (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x768)) +#define rCCC_THRM3_ALARM0 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x770)) +#define rCCC_THRM3_ALARM1 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x778)) +#define rCCC_THRM3_ALARM2 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x780)) +#define rCCC_THRM3_ALARM3 (*(volatile uint32_t*)(CCC_CPM_THERMAL_BASE + 0x788)) +#endif + +#define CCC_THRM_CTL0_ENABLE (1 << 0) +#define CCC_THRM_PIECE_START_CODE_MASK PMGR_THERMAL_PIECE_START_CODE_MASK +#define CCC_THRM_PIECE_OFFSET_MASK (0x0FF) +#define CCC_THRM_PIECE_SLOPE_MASK PMGR_THERMAL_PIECE_SLOPE_MASK +#define CCC_THRM_PIECE_START_CODE_SHIFT PMGR_THERMAL_PIECE_START_CODE_SHIFT +#define CCC_THRM_PIECE_OFFSET_SHIFT PMGR_THERMAL_PIECE_OFFSET_SHIFT +#define CCC_THRM_PIECE_SLOPE_SHIFT PMGR_THERMAL_PIECE_SLOPE_SHIFT +#define CCC_THRM_PIECE_START_CODE(_c) (((_c) & CCC_THRM_PIECE_START_CODE_MASK) << CCC_THRM_PIECE_START_CODE_SHIFT) +#define CCC_THRM_PIECE_OFFSET(_o) (((_o) & CCC_THRM_PIECE_OFFSET_MASK) << CCC_THRM_PIECE_OFFSET_SHIFT) +#define CCC_THRM_PIECE_SLOPE(_s) (((_s) & CCC_THRM_PIECE_SLOPE_MASK) << CCC_THRM_PIECE_SLOPE_SHIFT) +#define CCC_THRM_PIECE(_c, _o, _s) (CCC_THRM_PIECE_START_CODE(_c) | CCC_THRM_PIECE_OFFSET(_o) | CCC_THRM_PIECE_SLOPE(_s)) +#define CCC_DFVM_FSHOT_IDX_THERMAL1(_n) (((_n) & 0x7) << 16) +#define CCC_DFVM_FSHOT_IDX_THERMAL0(_n) (((_n) & 0x7) << 0) +#define CCC_DFVM_FSHOT_IDX_THERMAL1_STATE ((rCCC_DVFM_FSHOT_IDX >> 16) & 0x7) +#define CCC_DFVM_FSHOT_IDX_THERMAL0_STATE ((rCCC_DVFM_FSHOT_IDX >> 0) & 0x7) + +#define CCC_PLL_P_SHIFT (9) +#define CCC_PLL_P_MASK (0x1F) +#define CCC_PLL_M_SHIFT (18) +#define CCC_PLL_M_MASK (0x1FF) +#define CCC_PLL_S_SHIFT (0) +#define CCC_PLL_S_MASK (0xF) +#define CCC_PLL_M(_m) (((_m) & CCC_PLL_M_MASK) << CCC_PLL_M_SHIFT) +#define CCC_PLL_P(_p) (((_p) & CCC_PLL_P_MASK) << CCC_PLL_P_SHIFT) +#define CCC_PLL_S(_s) (((_s) & CCC_PLL_S_MASK) << CCC_PLL_S_SHIFT) +#define CCC_PLL_ENABLE (1 << 31) +#define CCC_PLL_LOCKED (1 << 29) +#define CCC_PLL_LOAD (1 << 27) + + +//////////////////////////////////////////////////////////// +// +// Externs +// +//////////////////////////////////////////////////////////// + +extern void pmgr_update_device_tree(DTNode *pmgr_node); +extern void pmgr_gfx_update_device_tree(DTNode *gfx_node); +void sochot_pmgr_update_device_tree(DTNode *node); + +void pmgr_update_dvfm(uint32_t board_id, uint32_t board_rev); +void pmgr_update_gfx_states(uint32_t board_id, uint32_t board_rev); +bool pmgr_check_gpu_use650MHz_binned(uint32_t board_id, uint32_t board_rev); +bool pmgr_check_gpu_use650MHz_unbinned(uint32_t board_id, uint32_t board_rev); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/t7000/include/platform/trampoline.h b/platform/t7000/include/platform/trampoline.h new file mode 100644 index 0000000..0f19e03 --- /dev/null +++ b/platform/t7000/include/platform/trampoline.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include + +/* ROM related registers in AMC space */ + +#define SECURITY_REG (AMCC_BASE_ADDR + 0x900) +#define ROM_READ_DISABLE (1 << 0) + +#define REMAP_REG (AMCC_BASE_ADDR + 0x904) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/t7000/include/platform/usbconfig.h b/platform/t7000/include/platform/usbconfig.h new file mode 100644 index 0000000..3917129 --- /dev/null +++ b/platform/t7000/include/platform/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +/* + * per Fiji Tunables Specification, Revision 1.18, August 13, 2013 + */ +#define USBPHY_OTGTUNE0 (0x37477BF3) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/t7000/init.c b/platform/t7000/init.c new file mode 100644 index 0000000..1a4d460 --- /dev/null +++ b/platform/t7000/init.c @@ -0,0 +1,2104 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_CONSISTENT_DBG +#include +#endif +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#if WITH_HW_SEP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_PLATFORM_ERROR_HANDLER +#include +#endif +#include +#include +#include +#include +#include +#include + +static void platform_init_boot_strap(void); +static int32_t platform_bootprep_darwin(bool resume); +static bool platform_get_boot_from_nvme(uint32_t *port, uint32_t *dart_id); +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val); +static int power_convert_dwi_to_mv_fpga(unsigned int buck, u_int32_t dwival); +static void platform_relocate_securerom(void); +#if SUB_PLATFORM_T7001 && (PRODUCT_LLB || PRODUCT_IBSS) +static void t7001_ram_repair_init(void); +#endif + +static uint8_t boot_debug; +static bool gDisplayEnabled; + +int platform_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + /* Verify that the fuses and SecureROM R/W access has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile u_int32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled\n"); + } + +#if SUB_PLATFORM_T7001 + // Capri: Core-2 repair register loading fails if Core-1 is booted before Core-2 + t7001_ram_repair_init(); +#endif +#endif + + /* Enable more Cyclone specific errors */ + ccc_enable_custom_errors(); + +#if WITH_HW_PLATFORM_POWER + /* initialize the pmgr driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); + debug_enable_uarts(3); +#endif +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif + +#if SUB_PLATFORM_T7000 + // Note: This can't be postposned until platform_late_init() because + // Fiji A0 chips will hang before we can get there. + if (platform_get_chip_revision() < CHIP_REVISION_B1) { + platform_not_supported(); + } +#elif SUB_PLATFORM_T7001 + if (platform_get_chip_revision() < CHIP_REVISION_A1) { + platform_not_supported(); + } +#endif + +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + return 0; +} + + +int platform_late_init(void) +{ +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); + + /* turn off DEBUG clock if debug-soc nvram is not true */ + clock_gate(CLK_DEBUG, env_get_bool("debug-soc", false)); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_HW_AMC + extern void mcu_late_init(void); + mcu_late_init(); +#endif + +#if WITH_CSI + csi_late_init(); +#endif + + return 0; +} + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { +#if WITH_HW_DISPLAY_PMU + display_pmu_init(); +#endif + + if (!displayInitOnce) { + platform_quiesce_display(); +#if SUB_PLATFORM_T7000 + clock_gate(CLK_DISP_BUSMUX, true); +#elif SUB_PLATFORM_T7001 + clock_gate(CLK_DISP0_BUSIF, true); +#endif + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + + power_backlight_enable(backlight_level); +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + addr_t base_rounded = *base; + addr_t end_rounded = *base + *size; + size_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_HW_ASP + if (!platform_get_boot_from_nvme(NULL, NULL)) + return (asp_nand_open()); +#endif +#if WITH_NVME + if (platform_get_boot_from_nvme(NULL, NULL)) + return nvme_init_mass_storage(0); +#endif + return 0; +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + +#if WITH_CSI + csi_quiesce(target); +#endif + +#if WITH_NVME + nvme_quiesce_all(); +#endif + +#if WITH_THUNDERBOOT + thunderboot_quiesce_and_free(NULL); +#endif + +#if WITH_HW_APCIE + apcie_disable_all(); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + quiesce_clocks = true; +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + +#if SUB_PLATFORM_T7000 + clock_gate(CLK_DISP_BUSMUX, true); +#elif SUB_PLATFORM_T7001 + clock_gate(CLK_DISP0_BUSIF, true); +#endif + /* quiesce the panel */ + if (display_quiesce(true) == ENXIO) { +#if SUB_PLATFORM_T7000 + clock_gate(CLK_DISP_BUSMUX, false); +#elif SUB_PLATFORM_T7001 + clock_gate(CLK_DISP0_BUSIF, false); +#endif + } + +#endif + + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + uint32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: +#if WITH_PAINT + if (paint_color_map_is_invalid()) + panic("Previous DClr errors prevent OS booting"); +#endif + platform_quiesce_display(); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; + break; + + case BOOT_DARWIN: +#if WITH_PAINT + if (paint_color_map_is_invalid()) + panic("Previous DClr errors prevent OS booting"); +#endif + platform_bootprep_darwin(false); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: + platform_quiesce_display(); + break; +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + platform_relocate_securerom(); + miu_select_remap(REMAP_SRAM); +#endif + break; + + case BOOT_MONITOR: + /* clean-invalidate TZ0 & TZ1 regions */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ1_BASE, TZ1_SIZE); + + /* program values */ + rMCCLOCKREGION_TZ1BASEADDR = TZ1_BASE >> 12; + rMCCLOCKREGION_TZ1ENDADDR = (TZ1_BASE + TZ1_SIZE - 1) >> 12; + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + ; // do nothing + } + + /* make sure that fuse lock bit is set. */ + if (security_get_lock_fuses()) + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + /* Disable Cyclone specific errors enabled earlier in the boot */ + ccc_disable_custom_errors(); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + +#if APPLICATION_SECUREROM + arm_mmu_map_rx(VROM_BASE, VROM_LEN); + arm_mmu_map_rw(SRAM_BASE, SRAM_LEN); + + // for future ROMS add heap guard and RO pagetables +#else + // Figure out where the linker put our various bits + uintptr_t text_end_aligned = ((uintptr_t)&_text_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + size_t text_size = text_end_aligned - (uintptr_t)&_text_start; + + RELEASE_ASSERT(text_end_aligned <= (uintptr_t)&_data_start); + +#if PRODUCT_LLB || PRODUCT_IBSS + arm_mmu_map_rw(SDRAM_BASE, SDRAM_LEN); + // Make an uncached mapping to DRAM (used during memory calibration) + arm_mmu_map_range(SDRAM_BASE_UNCACHED, SDRAM_BASE, SDRAM_LEN, kARMMMUDeviceRW); + + // map through to end of heap read/write + arm_mmu_map_rw(SRAM_BASE, HEAP_END - SRAM_BASE); + + // __TEXT is read/execute, __DATA is read/write + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, PAGE_TABLES_BASE - text_end_aligned); + + // skip mapping the page tables so that they can't be modified + + // map the stacks read-write + arm_mmu_map_rw(STACKS_BASE, SRAM_BASE + SRAM_LEN - STACKS_BASE); +#else + // Most of DRAM gets mapped read/write + arm_mmu_map_rw(SDRAM_BASE, (uintptr_t)&_text_start - SDRAM_BASE); + + // only the text section should be executable, and it should be read only + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, PAGE_TABLES_BASE - text_end_aligned); + + // skip mapping the page tables so that they can't be modified + + // map the stacks read-write + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); + + // map the boot trampoline read/execute + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + + // map the heap read-write, leaving a hole at the end + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + RELEASE_ASSERT(HEAP_BASE + HEAP_SIZE == HEAP_GUARD); + + // and then everything up to the end of DRAM is read/write again + arm_mmu_map_rw(IBOOT_BASE + IBOOT_SIZE, SDRAM_END - (IBOOT_BASE + IBOOT_SIZE)); + +#if DEBUG_BUILD + // Create a virtual mapping for SRAM to allow SecureROM testing + arm_mmu_map_rw(SRAM_BASE, SRAM_LEN); +#endif +#endif +#endif + + // map IO + arm_mmu_map_device_rw(IO_BASE, IO_SIZE); + arm_mmu_map_device_rw(PCI_REG_BASE, PCI_REG_LEN); + arm_mmu_map_device_rw(PCI_CONFIG_BASE, PCI_CONFIG_LEN); + arm_mmu_map_device_rw(PCI_32BIT_BASE, PCI_32BIT_LEN); +} + +int platform_init(void) +{ + uint32_t nvme_port = 0; + uint32_t nvme_dart_id = 0; + bool boot_from_nvme; + +#if defined(UNUSED_MEMORY_BASE) && (UNUSED_MEMORY_SIZE > 0) + bzero((void *)UNUSED_MEMORY_BASE, UNUSED_MEMORY_SIZE); +#endif + +#if WITH_PLATFORM_ERROR_HANDLER + platform_enable_error_handler(); +#endif + +#if WITH_CONSISTENT_DBG && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + consistent_debug_init(); +#endif + +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_PCI + pci_init(); +#endif + + boot_from_nvme = platform_get_boot_from_nvme(&nvme_port, &nvme_dart_id); + +#if WITH_ANC_FIRMWARE + if (!boot_from_nvme) + anc_firmware_init(); +#endif + +#if WITH_HW_ASP && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + if (!boot_from_nvme) { + csi_init(CSI_COPROC_ANS); /* coproc switchboard used by nand driver to communicate with ans iop */ + asp_init(); + } +#endif + +#if WITH_NVME && (PRODUCT_LLB || PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + if (boot_from_nvme) { +#if SUB_PLATFORM_T7000 + apcie_use_external_refclk(true); +#endif +#if PRODUCT_IBEC + apcie_set_s3e_mode(true); +#else + apcie_set_s3e_mode(false); +#endif + if (apcie_enable_link(nvme_port)) { + nvme_init(0, apcie_get_port_bridge(nvme_port), nvme_dart_id); + } + } +#endif + +#if WITH_THUNDERBOOT && (PRODUCT_IBSS || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + if (apcie_enable_link(0)) { + thunderboot_init(apcie_get_port_bridge(0), PCIE_PORT0_DART_ID); + } +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + uint32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_NVME + nvme_quiesce_all(); +#endif + +#if WITH_HW_APCIE + apcie_disable_all(); +#endif + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +uint32_t platform_set_performance(uint32_t performance_level) +{ + uint32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +void platform_setup_default_environment(void) +{ +#if WITH_ENV + if (!platform_get_boot_from_nvme(NULL, NULL)) + env_set("boot-device", "asp_nand", 0); + else + env_set("boot-device", "nvme_nand0", 0); +#endif + + target_setup_default_environment(); +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; +#if SUB_PLATFORM_T7001 + char *propNamePOR; +#endif + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_CPU); + memcpy(propData, &freq, propSize); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_MEM); + memcpy(propData, &freq, propSize); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_BUS); + memcpy(propData, &freq, propSize); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_PERIPH); + memcpy(propData, &freq, propSize); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_FIXED); + memcpy(propData, &freq, propSize); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_TIMEBASE); + memcpy(propData, &freq, propSize); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(uint32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the gfx node + if (FindNode(0, "arm-io/sgx", &node)) { + pmgr_gfx_update_device_tree(node); + +#if SUB_PLATFORM_T7001 + if (chipid_get_fuse_revision() < 0x1) { + propName = "gpu-device-max-power-fuserev0"; + propNamePOR = "gpu-device-max-power"; + + if (FindProperty(node, &propName, &propData, &propSize) && + FindProperty(node, &propNamePOR, &propData, &propSize)) { + strlcpy(propName, "gpu-device-max-power", kPropNameLength); + propNamePOR[0] = '~'; + } + + propName = "gpu-pwr-perf-scale4"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + } +#endif + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + + // Find the sochot0 and 1 nodes and override/augment EDT as needed + if (FindNode(0, "arm-io/sochot0", &node)) { + sochot_pmgr_update_device_tree(node); + } + + // Find the apcie node + if (FindNode(0, "arm-io/apcie", &node)) { + apcie_update_devicetree(node); + } + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + + if (platform_get_boot_from_nvme(NULL, NULL)) { + if (FindNode(0, "arm-io/ans", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + +#if SUB_PLATFORM_T7000 + // Automatically select external refclk in OS on Fiji when booting from NVMe + if (FindNode(0, "arm-io/apcie", &node)) { + propName = "phy0-external-refclk-nvme"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "phy0-external-refclk", kPropNameLength); + } + } +#endif + + if (FindNode(0, "arm-io/apcie/pci-bridge0/device0", &node)) { + propName = "nvme-scratch-region"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == 2 * sizeof(uintptr_t)) { + ((uintptr_t *)propData)[0] = platform_get_memory_region_base(kMemoryRegion_StorageProcessor); + ((uintptr_t *)propData)[1] = platform_get_memory_region_size(kMemoryRegion_StorageProcessor); + } + } else if (FindNode(0, "arm-io/apcie/pci-bridge2/device2", &node)) { + propName = "nvme-scratch-region"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == 2 * sizeof(uintptr_t)) { + ((uintptr_t *)propData)[0] = platform_get_memory_region_base(kMemoryRegion_StorageProcessor); + ((uintptr_t *)propData)[1] = platform_get_memory_region_size(kMemoryRegion_StorageProcessor); + } + } + } + + return target_update_device_tree(); +} + +#endif + +uint32_t platform_get_board_id(void) +{ + uint32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +bool platform_get_lock_fuses_required(void) +{ + bool lock_fuses = true; + +#if APPLICATION_SECUREROM && SUB_PLATFORM_T7001 + if (chipid_get_board_id() == 0x6) + lock_fuses = false; +#endif + + return lock_fuses; +} + +uint32_t platform_get_boot_config(void) +{ + uint32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, uint32_t *boot_flag, uint32_t *boot_arg) +{ + uint32_t boot_config = platform_get_boot_config(); + + /* T7000 supports one boot device then USB-DFU per boot config */ + /* T7001 supports the same, with the special case of TBT. The rules there are: + - If FORCE_DFU is asserted and USB is connected, do USB DFU on all tries + - If FORCE_DFU is not asserted, do TBT DFU on all tries */ + + switch (boot_config) { + case BOOT_CONFIG_SPI0: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_SPI0_TEST: + case BOOT_CONFIG_FAST_SPI0_TEST: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case BOOT_CONFIG_ANS: + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_ANS_TEST: + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case BOOT_CONFIG_NVME0: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_NVME0_TEST: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + +#if SUB_PLATFORM_T7001 + case BOOT_CONFIG_NVME1: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = 0; + *boot_arg = 1; + break; + + case BOOT_CONFIG_NVME1_TEST: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 1; + break; +#endif + +#ifndef SUB_PLATFORM_T7000 + case BOOT_CONFIG_LOW_POWER_ANS: + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = ANC_BOOT_MODE_RESET_ONE_CONTROLLER; + break; +#endif + +#if SUB_PLATFORM_T7001 + case BOOT_CONFIG_TBT0_EXTREF: + *boot_device = BOOT_DEVICE_TBTDFU; + *boot_flag = 0; + *boot_arg = 1; + break; + + case BOOT_CONFIG_TBT0_EXTREF_TEST: + *boot_device = BOOT_DEVICE_TBTDFU; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 1; + break; + + case BOOT_CONFIG_TBT0_INTREF: + *boot_device = BOOT_DEVICE_TBTDFU; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_TBT0_INTREF_TEST: + *boot_device = BOOT_DEVICE_TBTDFU; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; +#endif + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == -1 || (index != 0 && *boot_device != BOOT_DEVICE_TBTDFU)) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + uint32_t enable; + uint32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO_SPI0_SSIN, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO_SPI0_SSIN, GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO_SPI0_SCLK, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO_SPI0_MOSI, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO_SPI0_MISO, GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, uint32_t boot_arg) +{ + const struct boot_interface_pin *pins = 0; + uint32_t cnt, func, pin_count = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins = spi0_boot_interface_pins; + pin_count = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_ANC_BOOT + case BOOT_DEVICE_NAND : + /* NAND pins are off to ASP */ + break; +#endif /* WITH_ANC_BOOT */ + +#if WITH_NVME + case BOOT_DEVICE_NVME : + { + uint32_t dart_id = 0; + uint32_t pcie_port = 0; + if (boot_arg == 0) { + dart_id = PCIE_PORT0_DART_ID; + pcie_port = 0; +#if SUB_PLATFORM_T7001 + } else if (boot_arg == 1) { + dart_id = PCIE_PORT2_DART_ID; + pcie_port = 2; +#endif + } else { + panic("invalid NVMe boot argument %u", boot_arg); + } + + if (enable) { +#if SUB_PLATFORM_T7000 + // Fiji uses external refclk, Capri uses the internal one + apcie_use_external_refclk(true); +#endif + apcie_set_s3e_mode(false); + + // Don't try to probe for the NVMe device if the link doesn't come + // up because we shut down the root complex on link initialization + // failures + if (apcie_enable_link(pcie_port)) { + nvme_init(0, apcie_get_port_bridge(pcie_port), dart_id); + } + } + if (!enable) { + // These guys are safe no-ops if the enable above failed + nvme_quiesce(0); + + apcie_disable_link(pcie_port); + } + + break; + } +#endif + +#if WITH_TBT_BOOT + case BOOT_DEVICE_TBTDFU : + { + bool ext_refclk = (boot_arg & 1) != 0; + + if (enable) { + apcie_use_external_refclk(ext_refclk); + + // Don't try to probe for the TBT device if the link doesn't come + // up because we shut down the root complex on link initialization + // failures + if (apcie_enable_link(0)) { + thunderboot_init(apcie_get_port_bridge(0), PCIE_PORT0_DART_ID); + } + } + if (!enable) { + // These guys are safe no-ops if the enable above failed + thunderboot_quiesce_and_free(NULL); + + apcie_disable_link(0); + } + + break; + } +#endif + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count; cnt++) { + if (enable) { + pin = pins[pin_count - 1 - cnt].pin; + func = pins[pin_count - 1 - cnt].enable; + } else { + pin = pins[cnt].pin; + func = pins[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +uint64_t platform_get_nonce(void) +{ + uint64_t nonce; + uint32_t *nonce_words = (uint32_t *)&nonce; + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH14 = nonce_words[0]; + rPMGR_SCRATCH15 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH14; + nonce_words[1] = rPMGR_SCRATCH15; + } + + return nonce; +} + +int32_t platform_get_sep_nonce(uint8_t *nonce) +{ +#if WITH_HW_SEP + return sep_client_get_nonce(nonce); +#else + return -1; +#endif +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return true; +} + +uint32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +uint32_t platform_get_spi_frequency(void) +{ +#if SUPPORT_FPGA + return 2500000; +#else + if (platform_get_boot_config() == BOOT_CONFIG_FAST_SPI0_TEST) + return 24000000; + else + return 12000000; +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ + return gpio_read(GPIO_FORCE_DFU); +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(uint32_t key_selector, uint32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +void platform_disable_keys(uint32_t gid, uint32_t uid) +{ + // Disable requested GID and UID in SIO-AES + extern void aes_ap_disable_keys(uint32_t gid, uint32_t uid); + aes_ap_disable_keys(gid, uid); + +#if APPLICATION_SECUREROM + // Disable UID1 in ANS, if UID1 disable is requested + extern void anc_disable_uid_key(); + if (uid & 1) + anc_disable_uid_key(); +#endif + + // XXX TODO: Revisit for LLB, iBoot, iBSS, iBEC +} + +void platform_demote_production() +{ + chipid_clear_production_mode(); +} + +#if APPLICATION_IBOOT +uint64_t platform_get_memory_size(void) +{ + uint64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (rPMGR_SCRATCH13 & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +uint8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH13 >> 28) & 0xf); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info(uint8_t manuf_id, uint64_t memory_size) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH13 = 0; + } + + rPMGR_SCRATCH13 = (manuf_id << 28) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +#endif + +extern void boot_handoff_trampoline(void *entry, void *arg); + +void *platform_get_boot_trampoline(void) +{ +#ifdef BOOT_TRAMPOLINE_BASE + return (void *)BOOT_TRAMPOLINE_BASE; +#else + return (void *)boot_handoff_trampoline; +#endif +} + +int32_t platform_restore_system(void) +{ + // XXX kSleepTokenKernelOffset = 0 + uint32_t *signature = (uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0); + +#if WITH_CONSISTENT_DBG + consistent_debug_resume(); +#endif + + power_will_resume(); + + dprintf(DEBUG_INFO, "restore_system: signature[0]: 0x%08x, signature[1]: 0x%08x\n", + signature[0], signature[1]); + + if ((signature[0] != 'MOSX') || (signature[1] != 'SUSP')) return -1; + + signature[0] = 0; + signature[1] = 0; + + platform_bootprep_darwin(true); + +#if PRODUCT_LLB + // Workaround per rdar://problem/18049697 - Zero out Host S3-E DRAM on Wake from Suspsend to RAM + if (platform_get_boot_from_nvme(NULL, NULL)) + { + bzero((void *)ASP_BASE, (size_t)ASP_SIZE); + dprintf(DEBUG_INFO, "NVMe: Zero'd out scratch buffer\n"); + } +#endif + + /* Jump to reset vector (first address of physical page of l4 or kernel). Our memory layout expects TZ0 -> TZ1 -> Kernel memory */ + dprintf(DEBUG_INFO, "restoring kernel\n"); + + prepare_and_jump(BOOT_DARWIN_RESTORE, (void *)TZ1_BASE, NULL); + + /* shouldn't get here */ + panic("returned from restore_system\n"); +} + +void platform_asynchronous_exception(void) +{ + ccc_handle_asynchronous_exception(); +} + +int32_t platform_get_boot_manifest_hash(uint8_t *boot_manifest_hash) +{ + RELEASE_ASSERT(boot_manifest_hash != NULL); + + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagObjectManifestHashValid) != 0) { + ((uint32_t *)boot_manifest_hash)[0] = rPMGR_SCRATCH16; + ((uint32_t *)boot_manifest_hash)[1] = rPMGR_SCRATCH17; + ((uint32_t *)boot_manifest_hash)[2] = rPMGR_SCRATCH18; + ((uint32_t *)boot_manifest_hash)[3] = rPMGR_SCRATCH19; + ((uint32_t *)boot_manifest_hash)[4] = rPMGR_SCRATCH20; + + return 0; + } + + return -1; +} + +int32_t platform_set_boot_manifest_hash(const uint8_t *boot_manifest_hash) +{ + if(boot_manifest_hash != NULL) { + rPMGR_SCRATCH16 = ((uint32_t *)boot_manifest_hash)[0]; + rPMGR_SCRATCH17 = ((uint32_t *)boot_manifest_hash)[1]; + rPMGR_SCRATCH18 = ((uint32_t *)boot_manifest_hash)[2]; + rPMGR_SCRATCH19 = ((uint32_t *)boot_manifest_hash)[3]; + rPMGR_SCRATCH20 = ((uint32_t *)boot_manifest_hash)[4]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagObjectManifestHashValid; + } + else { + rPMGR_SCRATCH16 = 0; + rPMGR_SCRATCH17 = 0; + rPMGR_SCRATCH18 = 0; + rPMGR_SCRATCH19 = 0; + rPMGR_SCRATCH20 = 0; + + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagObjectManifestHashValid; + } + + return 0; +} + +bool platform_get_mix_n_match_prevention_status(void) +{ + return ((rPMGR_SCRATCH0 & kPlatformScratchFlagVerifyManifestHash) ? true : false); +} + +void platform_set_mix_n_match_prevention_status(bool mix_n_match_prevented) +{ + if (mix_n_match_prevented) + rPMGR_SCRATCH0 |= kPlatformScratchFlagVerifyManifestHash; + else + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagVerifyManifestHash; +} + +void platform_set_consistent_debug_root_pointer(uint32_t root) +{ + rPMGR_SCRATCH7 = root; +} + +int platform_convert_voltages(int buck, u_int32_t count, u_int32_t *voltages) +{ +#if SUPPORT_FPGA + u_int32_t index; + for (index = 0; index < count; index++) + power_get_buck_value_fpga(buck, voltages[index], &voltages[index]); + return 0; +#elif WITH_HW_POWER + u_int32_t index; + + if (voltages == 0) return -1; + + for (index = 0; index < count; index++) { + if (0 != power_get_buck_value(buck, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +int platform_get_cpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cnt); + } + + return 0; +} + +int platform_get_soc_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_soc_voltage(cnt); + } + + return 0; +} + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = PANIC_BASE; + break; + + case kMemoryRegion_StorageProcessor: + base = ASP_BASE; + break; + + case kMemoryRegion_SecureProcessor: + base = TZ0_BASE; + break; + + case kMemoryRegion_Monitor: + base = TZ1_BASE; + break; + + case kMemoryRegion_Kernel: + base = TZ0_BASE + TZ0_SIZE; + break; + + case kMemoryRegion_PageTables: + base = PAGE_TABLES_BASE; + break; + + case kMemoryRegion_Heap: + base = HEAP_BASE; + break; + + case kMemoryRegion_Stacks: + base = STACKS_BASE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + base = CONSISTENT_DEBUG_BASE; + break; + + case kMemoryRegion_SleepToken: + base = SLEEP_TOKEN_BUFFER_BASE; + break; + + case kMemoryRegion_Display: + base = PANIC_BASE - platform_get_memory_region_size(kMemoryRegion_Display); + break; + + case kMemoryRegion_iBoot: + base = IBOOT_BASE; + break; +#endif + + default: + base = (uintptr_t)-1; + break; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + + case kMemoryRegion_StorageProcessor: + size = ASP_SIZE; + break; + + case kMemoryRegion_SecureProcessor: + size = TZ0_SIZE; + break; + + case kMemoryRegion_Monitor: + size = TZ1_SIZE; + break; + + case kMemoryRegion_Kernel: + size = platform_get_memory_region_base(kMemoryRegion_Display) - platform_get_memory_region_base(kMemoryRegion_Kernel); + break; + + case kMemoryRegion_PageTables: + size = PAGE_TABLES_SIZE; + break; + + case kMemoryRegion_Heap: + size = HEAP_SIZE; + break; + + case kMemoryRegion_Stacks: + size = STACKS_SIZE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + size = CONSISTENT_DEBUG_SIZE; + break; + + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; + + case kMemoryRegion_Display: + size = platform_get_display_memory_size(); + ASSERT(size != 0); + break; + + case kMemoryRegion_iBoot: + size = IBOOT_SIZE; + break; +#endif + + default: + size = (size_t)-1; + break; + } + + return size; +} + +#if defined(WITH_MENU) && WITH_MENU + +int do_sleep_token_test(int argc, struct cmd_arg *args) +{ + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0; + + security_create_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90); + + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0x12345678; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0xaabbccdd; + dprintf(DEBUG_INFO, "original info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + if (security_validate_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90) == false) { + dprintf(DEBUG_INFO, "failed to validate token\n"); + return 0; + } + + dprintf(DEBUG_INFO, "saved info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + return 0; +} + +MENU_COMMAND_DEBUG(sleep_token, do_sleep_token_test, "sleep token test - creates and validate it", NULL); + +#endif + +uint32_t platform_get_pcie_l1ss_ltr_threshold(void) +{ + // Per Fiji Tunables r1.44 section 8.2 + return 93; +} + +uint32_t platform_get_pcie_l1ss_t_common_mode(void) +{ + // Per Fiji Tunables r1.44 section 8.2 + return 55; +} + +int platform_get_gpu_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_gpu_voltage(cnt); + } + + return 0; +} + +int platform_get_gpu_ram_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_gpu_ram_voltage(cnt); + } + + return 0; +} + +int platform_get_ram_voltages(u_int32_t count, u_int32_t *voltages) +{ + u_int32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_ram_voltage(cnt); + } + + return 0; +} + +/* + * Gets equivalent mV for a given DWI value for a particular buck. + * PMU code should handle the special case for GPU buck. + */ +int platform_get_dwi_to_mv(int buck, u_int32_t dwival) +{ +#if SUPPORT_FPGA + return power_convert_dwi_to_mv_fpga(buck, dwival); +#elif WITH_HW_POWER + return power_convert_dwi_to_mv(buck, dwival); +#else + return -1; +#endif +} + +static void platform_init_boot_strap(void) +{ + uint32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID4, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID4, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); +#if SUB_PLATFORM_T7001 + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_IN); +#endif + + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); +#if SUB_PLATFORM_T7001 + gpio_configure_pupdn(GPIO_BOOT_CONFIG3, GPIO_PDN); +#endif + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + // Build the board ID and boot config using the new scheme. + gpio_board_id = + (gpio_read(GPIO_BOARD_ID4) << 4) | + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = +#if SUB_PLATFORM_T7001 + (gpio_read(GPIO_BOOT_CONFIG3) << 3) | +#endif + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID4, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); +#if SUB_PLATFORM_T7001 + gpio_configure(GPIO_BOOT_CONFIG3, GPIO_CFG_DFLT); +#endif + + boot_strap = (((chip_board_id << 5) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +static int32_t platform_bootprep_darwin(bool resume) +{ + /* 1. Setup trustzones */ + + if (!resume) { + /* clean-invalidate TZ0 & TZ1 regions */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ0_BASE, TZ0_SIZE); + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ1_BASE, TZ1_SIZE); + } + else { + /* validate sleep token */ + if (!security_validate_sleep_token(SLEEP_TOKEN_BUFFER_BASE + kSleepTokeniBootOffset)) return -1; + } + + /* program values */ + rMCCLOCKREGION_TZ0BASEADDR = TZ0_BASE >> 12; + rMCCLOCKREGION_TZ0ENDADDR = (TZ0_BASE + TZ0_SIZE - 1) >> 12; + rMCCLOCKREGION_TZ1BASEADDR = TZ1_BASE >> 12; + rMCCLOCKREGION_TZ1ENDADDR = (TZ1_BASE + TZ1_SIZE - 1) >> 12; + + /* lock TZ0 & TZ1 regions */ + rMCCLOCKREGION_TZ0LOCK = (1 << 0); + if ((rMCCLOCKREGION_TZ0LOCK & 1) == 0) { + panic("TZ0 failed to lock\n"); + } + rMCCLOCKREGION_TZ1LOCK = (1 << 0); + if ((rMCCLOCKREGION_TZ1LOCK & 1) == 0) { + panic("TZ1 failed to lock\n"); + } + + /* 2. Override IO_RVBAR */ + + ccc_override_and_lock_iorvbar(TZ1_BASE); + + return 0; +} + +static void platform_relocate_securerom(void) +{ +#if WITH_HW_MIU && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + size_t len; + + // Get the size of the downloaded SecureROM image + len = env_get_uint("filesize", 0); + if (len == 0) + panic("filesize variable invalid or not set, aborting\n"); + + // Move the SecureROM image into place + dprintf(DEBUG_INFO, "relocating 0x%lx byte SecureROM image from SDRAM to SRAM\n", len); + memcpy((void *)SRAM_BASE, (void *)SDRAM_BASE, len); +#endif +} + +static bool platform_get_boot_from_nvme(uint32_t *port, uint32_t *dart_id) +{ + bool result = false; +#if WITH_NVME + enum boot_device boot_device; + uint32_t boot_flag; + uint32_t boot_arg; + + if (platform_get_boot_device(0, &boot_device, &boot_flag, &boot_arg) && boot_device == BOOT_DEVICE_NVME) { + result = true; + if (port != NULL) +#if SUB_PLATFORM_T7000 + *port = 0; +#elif SUB_PLATFORM_T7001 + *port = boot_arg == 0 ? 0 : 2; +#endif + if (dart_id != NULL) +#if SUB_PLATFORM_T7000 + *dart_id = PCIE_PORT0_DART_ID; +#elif SUB_PLATFORM_T7001 + *dart_id = boot_arg == 0 ? PCIE_PORT0_DART_ID : PCIE_PORT2_DART_ID; +#endif + } +#endif + return result; +} + +#if SUPPORT_FPGA +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val) +{ + if (mv == 0) { + *val = 0; + } else { + *val = (((mv-600)*1000)+3124)/3125; + } + return; +} + +static int power_convert_dwi_to_mv_fpga(unsigned int buck, u_int32_t dwival) +{ + int val = 0; +#if APPLICATION_IBOOT +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + if (buck == BUCK_GPU) { + val = (dwival == 0) ? 0 : (600000 + (3125 * dwival))/1000; + } +#endif + return val; +} +#endif + +#if WITH_TARGET_CONFIG + +// The target's rules.mk sets the high SoC voltage point +#ifndef TARGET_BOOT_SOC_VOLTAGE +#error TARGET_BOOT_SOC_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} + +// The target's rules.mk sets the high CPU voltage point +#ifndef TARGET_BOOT_CPU_VOLTAGE +#error TARGET_BOOT_CPU_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_BOOT_CPU_VOLTAGE); +} + +// The target's rules.mk sets the high RAM voltage point +#ifndef TARGET_BOOT_RAM_VOLTAGE +#error TARGET_BOOT_RAM_VOLTAGE not defined by the target +#endif + +u_int32_t platform_get_base_ram_voltage(void) +{ + return chipid_get_ram_voltage(TARGET_BOOT_RAM_VOLTAGE); +} + +#endif + +static int get_total_leakage(int argc, struct cmd_arg *args) +{ + dprintf(DEBUG_INFO, "total leakage: %dmA\n", chipid_get_total_rails_leakage()); + return 0; +} +MENU_COMMAND_DEBUG(leakage, get_total_leakage, "total rails leakage read from fuse", NULL); + +#if SUB_PLATFORM_T7001 && (PRODUCT_LLB || PRODUCT_IBSS) + +// Capri CPU2 RAM repair does not happen if CPU1 powers up before CPU2. +// Therefore, when coming up from a powered off state, power up CPU2 then CPU1. +// It is not necessary for the CPU1/CPU2 to execut any instructions for the +// RAM repair to be triggered. All they have to do is power up. Therefore, +// use the CPU's debug interface to hold CPU1/CPU2 in reset so that they +// don't execute any instructions, then power them down again. +// +// Capri: Core-2 repair register loading fails if Core-1 is booted before Core-2 + +#define rCCC_CCC_CCC_OVRD (*(volatile u_int32_t *)(CCC_CCC_DBG_BASE_ADDR + 0x000)) +# define CCC_CCC_CCC_OVRD_SPIDEN_FORCE_DBG_EN (0x3ul << 20) + +#define rCCC_CCC_CCC_STS (*(volatile u_int32_t *)(CCC_CCC_DBG_BASE_ADDR + 0x090)) +# define CCC_CCC_CCC_STS_cc2St_MASK (0xFul << 25) + +#define rCCC_CPU1_CYC_OVRD (*(volatile u_int32_t *)(CCC_CPU1_SYS_BASE_ADDR + 0x110)) +#define rCCC_CPU2_CYC_OVRD (*(volatile u_int32_t *)(CCC_CPU2_SYS_BASE_ADDR + 0x110)) +# define CCC_CPUx_CYC_OVRD_reqBoot_MASK (0x3ul << 28) +# define CCC_CPUx_CYC_OVRD_reqBoot_OVERRIDE (0x2ul << 28) +# define CCC_CPUx_CYC_OVRD_reqBoot_BOOT (0x3ul << 28) +# define CCC_CPUx_CYC_OVRD_ok2pwrdn_MASK (0x3ul << 24) +# define CCC_CPUx_CYC_OVRD_ok2pwrdn_POWERDN (0x3ul << 24) + +#define rCCC_CPU1_DGB_WRAP (*(volatile u_int32_t *)(CCC_CPU1_TRC_BASE_ADDR + 0x000)) +#define rCCC_CPU2_DGB_WRAP (*(volatile u_int32_t *)(CCC_CPU2_TRC_BASE_ADDR + 0x000)) +# define CCC_CPUx_DGB_WRAP_dbgHaltOnRst (0x1ul << 29) +# define CCC_CPUx_DGB_WRAP_dbgAck (0x1ul << 28) +# define CCC_CPUx_DGB_WRAP_frcPwrDn (0x1ul << 27) + +#define RAM_REPAIR_TIMEOUT_COUNT (10000000) + +void t7001_ram_repair_init(void) +{ + uint32_t ccc_ovrd; // CCC override control + uint32_t cyc_ovrd1; // CPU1 core override control + uint32_t cyc_ovrd2; // CPU2 core override control + uint32_t dbg_wrap1; // CPU1 debug wrapper control + uint32_t dbg_wrap2; // CPU2 debug wrapper control + uint32_t reg; + int i; + + // Save the state of all the register that will get modified below. + ccc_ovrd = rCCC_CCC_CCC_OVRD; + cyc_ovrd1 = rCCC_CPU1_CYC_OVRD; + cyc_ovrd2 = rCCC_CPU2_CYC_OVRD; + dbg_wrap1 = rCCC_CPU1_DGB_WRAP; + dbg_wrap2 = rCCC_CPU2_DGB_WRAP; + + // Override SPIDEN so that we can modify registers in the debug wrapper. + reg = ccc_ovrd | CCC_CCC_CCC_OVRD_SPIDEN_FORCE_DBG_EN; + rCCC_CCC_CCC_OVRD = reg; + + // Power up CPU2 and drop in to debug mode on reset. + reg = dbg_wrap2 | CCC_CPUx_DGB_WRAP_dbgHaltOnRst; + rCCC_CPU2_DGB_WRAP = reg; + reg = (cyc_ovrd2 & ~CCC_CPUx_CYC_OVRD_reqBoot_MASK) | CCC_CPUx_CYC_OVRD_reqBoot_BOOT; + rCCC_CPU2_CYC_OVRD = reg; + + // Power up CPU1 and drop in to debug mode on reset. + reg = dbg_wrap1 | CCC_CPUx_DGB_WRAP_dbgHaltOnRst; + rCCC_CPU1_DGB_WRAP = reg; + reg = (cyc_ovrd1 & ~CCC_CPUx_CYC_OVRD_reqBoot_MASK) | CCC_CPUx_CYC_OVRD_reqBoot_BOOT; + rCCC_CPU1_CYC_OVRD = reg; + + // Wait for CPU1 to power up. + for (i = 0; i < RAM_REPAIR_TIMEOUT_COUNT; i++) { + if (rCCC_CPU1_DGB_WRAP & CCC_CPUx_DGB_WRAP_dbgAck) { + break; + } + } + + // Failure of CPU1 to power up means death. + if (!(rCCC_CPU1_DGB_WRAP & CCC_CPUx_DGB_WRAP_dbgAck)) { + panic("CPU1 failed to power up"); + } + + // Power down CPU1. + reg = rCCC_CPU1_CYC_OVRD & ~CCC_CPUx_CYC_OVRD_reqBoot_MASK; + reg |= CCC_CPUx_CYC_OVRD_reqBoot_OVERRIDE; + reg |= CCC_CPUx_CYC_OVRD_ok2pwrdn_POWERDN; + rCCC_CPU1_CYC_OVRD = reg; + + reg = rCCC_CPU1_DGB_WRAP | CCC_CPUx_DGB_WRAP_frcPwrDn; + rCCC_CPU1_DGB_WRAP = reg; + + // Power down CPU2. + reg = rCCC_CPU2_CYC_OVRD & ~CCC_CPUx_CYC_OVRD_reqBoot_MASK; + reg |= CCC_CPUx_CYC_OVRD_reqBoot_OVERRIDE; + reg |= CCC_CPUx_CYC_OVRD_ok2pwrdn_POWERDN; + rCCC_CPU2_CYC_OVRD = reg; + + reg = rCCC_CPU2_DGB_WRAP | CCC_CPUx_DGB_WRAP_frcPwrDn; + rCCC_CPU2_DGB_WRAP = reg; + + // Wait for CPU1/CPU2 to power down. + for (i = 0; i < RAM_REPAIR_TIMEOUT_COUNT; i++) { + if ((rCCC_CCC_CCC_STS & CCC_CCC_CCC_STS_cc2St_MASK) == 0) { + break; + } + } + + // Failure of CPU1/CPU2 to power down up means death. + if ((rCCC_CCC_CCC_STS & CCC_CCC_CCC_STS_cc2St_MASK) != 0) { + panic("CPU1 and/or CPU2 failed to power down"); + } + + // Restore the state of all the registers modified above. + rCCC_CPU2_DGB_WRAP = dbg_wrap2; + rCCC_CPU1_DGB_WRAP = dbg_wrap1; + rCCC_CPU2_CYC_OVRD = cyc_ovrd2; + rCCC_CPU1_CYC_OVRD = cyc_ovrd1; + rCCC_CCC_CCC_OVRD = ccc_ovrd; +} +#endif // SUB_PLATFORM_T7001 && (PRODUCT_LLB || PRODUCT_IBSS) + diff --git a/platform/t7000/miu/miu.c b/platform/t7000/miu/miu.c new file mode 100644 index 0000000..f543ad9 --- /dev/null +++ b/platform/t7000/miu/miu.c @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void miu_configure_bridge(const u_int32_t *bridge_settings); + +#define STATIC_BRIDGE_SHIFT (28) +#define STATIC_BRIDGE_MASK ((1 << STATIC_BRIDGE_SHIFT) - 1) +#define SB_WIDGETS (0 << STATIC_BRIDGE_SHIFT) +#define SOCBUSMUX_WIDGETS (1 << STATIC_BRIDGE_SHIFT) +#define IOBUSMUX_WIDGETS (2 << STATIC_BRIDGE_SHIFT) +#define SWITCH_FAB_WIDGETS (3 << STATIC_BRIDGE_SHIFT) +#define CP_WIDGETS (4 << STATIC_BRIDGE_SHIFT) +#define ANS_WIDGETS (5 << STATIC_BRIDGE_SHIFT) +#define LIO_WIDGETS (6 << STATIC_BRIDGE_SHIFT) + +static const u_int64_t bridge_registers[] = { + SB_BASE_ADDR, + SOC_BUSMUX_BASE_ADDR, + IOBUSMUX_BASE_ADDR, + SWTCH_FAB_BASE_ADDR, + CP_COM_BASE_ADDR, + ANS_AFC_AIU_BASE_ADDR, + LIO_AFC_AIU_BASE_ADDR +}; + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +#if SUB_PLATFORM_T7000 + +static const u_int32_t bridge_settings_static[] = { + + SB_WIDGETS | ASIO_CLK_CTRL, 0x03000102, + + SB_WIDGETS | DYN_CLK_GATING, (0x30 << 16) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 0), + SB_WIDGETS | SIO_ASYNC_FIFO_SB_RD_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_ASYNC_FIFO_SB_WR_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_ASYNC_FIFO_SB_WGATHER, (0x1 << 8), + + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_WGATHER, (0x1 << 8), + + SB_WIDGETS | AIU_SB_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 12) | 0x4, + 0,0, + + SOCBUSMUX_WIDGETS | DWRRCFG_DISPMUX_BULK, (0x51 << 8) | (0x41 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL0_CAMERAMUX, (0x40 << 8) | (0xff << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_CAMERAMUX, (0x20 << 8) | (0x80 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_MEDIAMUX, (0x60 << 8) | (0x20 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL2_MEDIAMUX, (0x40 << 8) | (0x10 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL0_IOMUX, 0xa2, + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_IOMUX, 0xa2, + SOCBUSMUX_WIDGETS | TLIMIT_LVL2_IOMUX, 0xa2, + SOCBUSMUX_WIDGETS | TLIMIT_LVL3_IOMUX, 0xa2, + SOCBUSMUX_WIDGETS | SOCBUSMUX_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 12) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + IOBUSMUX_WIDGETS | IOBUSMUX_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 13) | (0x1 << 12) | (0x1 << 10) | (0x4 << 0), + 0,0, + + SWITCH_FAB_WIDGETS | SWITCH_FAB_AMAP_LOCK, (0x1 << 0), + SWITCH_FAB_WIDGETS | SWITCH_FAB_ARBCFG, (0x1 << 10) | (0x1 << 8) | (0x1 << 5) | (0x1 << 4) | (0x4 << 0), + SWITCH_FAB_WIDGETS | SWITCH_FAB_CPG_CNTL, (0x1 << 31) | (0x1 << 30) | (0x1 << 16) | (0x1 << 12) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + CP_WIDGETS | CP_DYN_CLK_GATING_CTRL, (0x1 << 4) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1) | (0x1 << 0), + 0,0, + + LIO_WIDGETS | LIO_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + 0,0 +}; + +#elif SUB_PLATFORM_T7001 + +static const u_int32_t bridge_settings_static[] = { + + SB_WIDGETS | ASIO_CLK_CTRL, 0x03000102, + + SB_WIDGETS | DYN_CLK_GATING, (0x30 << 16) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 0), + SB_WIDGETS | SIO_ASYNC_FIFO_SB_RD_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_ASYNC_FIFO_SB_WR_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_ASYNC_FIFO_SB_WGATHER, (0x1 << 8), + + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_RD_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_WR_RATE_LIMIT, 0x0, + SB_WIDGETS | SIO_DAPASYNC_FIFO_SB_WGATHER, (0x1 << 8), + + SB_WIDGETS | AIU_SB_CPG_CNTL, (0x1 << 31) | (0x1 << 30) | (0x1 << 16) | (0x1 << 12) | 0x4, + 0,0, + + SOCBUSMUX_WIDGETS | DWRRCFG_DISP0_RT, (0x28 << 8) | (0x20 << 0), + SOCBUSMUX_WIDGETS | DWRRCFG_IOMUX_BULK, (0x51 << 8) | (0x41 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL0_DISP0, (0x60 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL0_CAMERAMUX, (0x40 << 8) | (0xff << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_CAMERAMUX, (0x20 << 8) | (0x80 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_MEDIAMUX, (0x60 << 8) | (0x20 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL2_MEDIAMUX, (0x40 << 8) | (0x10 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL0_IOMUX, (0x40 << 8) | (0xa4 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL1_IOMUX, (0x40 << 8) | (0x40 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL2_IOMUX, (0x30 << 8) | (0x30 << 0), + SOCBUSMUX_WIDGETS | TLIMIT_LVL3_IOMUX, (0x20 << 8) | (0x20 << 0), + SOCBUSMUX_WIDGETS | SOCBUSMUX_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 12) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + IOBUSMUX_WIDGETS | IOBUSMUX_REGS_DWRRCFG_DISP1_BULK, (0x1e << 8) | (0x18 << 0), + IOBUSMUX_WIDGETS | IOBUSMUX_CPG_CNTL, (0x1 << 31) | (0x1 << 16) | (0x1 << 14) | (0x1 << 13) | (0x1 << 12) | (0x1 << 10) | (0x4 << 0), + 0,0, + + SWITCH_FAB_WIDGETS | SWITCH_FAB_AMAP_LOCK, (0x1 << 0), + SWITCH_FAB_WIDGETS | SWITCH_FAB_CPG_CNTL, (0x1 << 31) | (0x1 << 30) | (0x1 << 16) | (0x1 << 13) | (0x1 << 12) | (0x1 << 11) | (0x1 << 10) | (0x4 << 0), + 0,0, + + CP_WIDGETS | CP_DYN_CLK_GATING_CTRL, (0x1 << 4) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1) | (0x1 << 0), + 0,0, + + LIO_WIDGETS | LIO_MEMCACHE_DATASETID_OVERRIDE, (0xC00F000F), + 0,0, + + 0,0, +}; +#endif +#endif // (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +#if WITH_DEVICETREE +#if SUPPORT_FPGA + +struct bridge_list_t { + char *bridge_settings; + uint32_t fpga_enable_mask; +}; + +#define BRIDGE(b, m) { "bridge-settings-" #b, (m) } + +// ALERT: The ordering effects the device tree entries under pmgr node's reg dictionary. +// It also affects the bridge id used in the pmgr device-clock nodes. The +// bridge id must match the id on the device tree bridge-settings- properties. +// NOTE: The second parameter on the BRIDGE macro is used to dynamically determine +// which bridge settings properties should exist based upon the hardware +// blocks actually present on the device. +static const struct bridge_list_t bridge_list[] = { + BRIDGE(0, FPGA_HAS_ALWAYS), + BRIDGE(1, FPGA_HAS_MEDIA), + BRIDGE(2, FPGA_HAS_MSR), + BRIDGE(3, FPGA_HAS_JPEG), + BRIDGE(4, FPGA_HAS_AVE), + BRIDGE(5, FPGA_HAS_VXD), + BRIDGE(6, FPGA_HAS_ISP), +#if SUB_PLATFORM_T7000 + BRIDGE(7, (FPGA_HAS_DISP0 | FPGA_HAS_DISP1)), + BRIDGE(8, FPGA_HAS_DISP0), + BRIDGE(9, FPGA_HAS_DISP1), + BRIDGE(10, FPGA_HAS_GFX), + BRIDGE(11, FPGA_HAS_GFX), + BRIDGE(12, FPGA_HAS_ALWAYS), + BRIDGE(13, FPGA_HAS_PCIE), +#elif SUB_PLATFORM_T7001 + BRIDGE(7, FPGA_HAS_DISP0), + BRIDGE(8, FPGA_HAS_DISP1), + BRIDGE(9, FPGA_HAS_GFX), + BRIDGE(10, FPGA_HAS_GFX), + BRIDGE(11, FPGA_HAS_ALWAYS), + BRIDGE(12, FPGA_HAS_PCIE), +#endif +}; +#endif // SUPPORT_FPGA +#endif // WITH_DEVICETREE + +extern void ausb_setup_widgets(); + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + miu_configure_bridge(bridge_settings_static); +#endif + ausb_setup_widgets(); + + return 0; +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT && WITH_HW_AMC + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rSECUREROMCTRL_ROMADDRREMAP = (rSECUREROMCTRL_ROMADDRREMAP & ~3) | (1 << 0); + break; + + case REMAP_SDRAM: + rSECUREROMCTRL_ROMADDRREMAP = (rSECUREROMCTRL_ROMADDRREMAP & ~3) | (2 << 0); + break; + } +} + +void miu_bypass_prep(void) +{ +} + +static void miu_configure_bridge(const u_int32_t *bridge_settings) +{ + volatile u_int32_t *reg; + u_int32_t cnt = 0, bridge, offset, data; + + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + bridge = bridge_settings[cnt] >> STATIC_BRIDGE_SHIFT; + offset = bridge_settings[cnt] & STATIC_BRIDGE_MASK; + data = bridge_settings[cnt + 1]; + reg = (volatile u_int32_t *)(bridge_registers[bridge] + offset); + *reg = data; + cnt += 2; + } + cnt += 2; + } +} + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ +#if SUPPORT_FPGA + DTNode *node; + char *propName; + void *propData; + uint32_t propSize; + uint32_t fpga_blocks = chipid_get_fpga_block_instantiation(); + uint32_t i; + + dprintf(DEBUG_INFO, "chipid_get_fpga_block_instantiation() = 0x%08X\n", + fpga_blocks); + + if (FindNode(0, "arm-io/pmgr", &node)) { + + // For each bridge... + for (i = 0; i < ARRAY_SIZE(bridge_list); i++) { + + // Filter out if not supported by FPGA + if (!(fpga_blocks & bridge_list[i].fpga_enable_mask)) { + + propName = bridge_list[i].bridge_settings; + + if (FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_CRITICAL, "Eliding %s\n", propName); + propName[0] = '~'; + } + } + } + } +#endif // SUPPORT_FPGA +} + +#endif // WITH_DEVICETREE + diff --git a/platform/t7000/miu/rules.mk b/platform/t7000/miu/rules.mk new file mode 100644 index 0000000..a412699 --- /dev/null +++ b/platform/t7000/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/t7000/pmgr/pmgr.c b/platform/t7000/pmgr/pmgr.c new file mode 100644 index 0000000..3bfe251 --- /dev/null +++ b/platform/t7000/pmgr/pmgr.c @@ -0,0 +1,3329 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if SUB_TARGET_J81 || SUB_TARGET_J82 || SUB_TARGET_J96 || SUB_TARGET_J97 || SUB_TARGET_J98 || SUB_TARGET_J99 +#include +#endif + +extern void arm_no_wfe_spin(uint32_t usecs); + +struct clock_source { + uint32_t src_clk; + uint32_t factor; +}; + +#define CLOCK_SOURCES_MAX 12 + +struct clock_config { + volatile uint32_t *clock_reg; // CLK_CFG Register + struct clock_source sources[CLOCK_SOURCES_MAX]; // List of sources +}; + +#define PLL_VCO_TARGET(pllx) ((2ULL * (pllx##_O) * (pllx##_M)) / (pllx##_P)) +#define PLL_FREQ_TARGET(pllx) (((pllx##_O) * (pllx##_M)) / (pllx##_P) / ((pllx##_S) + 1)) + +#if APPLICATION_SECUREROM +static uint32_t active_state = kDVFM_STATE_SECUREROM; +#endif + +#if APPLICATION_IBOOT +static uint32_t active_state = kDVFM_STATE_IBOOT; +#endif + +static uint64_t ccc_dvfm_states[] = { + +#if APPLICATION_SECUREROM + // BIU div = 1, disable voltage change sequence, Clk src = Ref clk. + [kDVFM_STATE_BYPASS] = (2ULL << 18)|(1ULL << 22), + + // CCC @ 300 MHz, disable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_SECUREROM] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(50) | + CCC_DVFM_ST_PLL_S(3) |(1ULL << 22)| + (1ULL << 21)|(2ULL << 18), +#else + // BIU div = 1, Clk src = Ref clk. + [kDVFM_STATE_BYPASS] = (2ULL << 18), +#endif + +#if APPLICATION_IBOOT + // CCC V0 + // CCC @ 396 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_IBOOT] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(33) | + CCC_DVFM_ST_PLL_S(1) | (1ULL << 21) | (2ULL << 18), + + // CCC V1 + // CCC @ 600 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 1. + [kDVFM_STATE_V1] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(25) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (2ULL << 18), + + // CCC V2 + // CCC @ 840 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2. + [kDVFM_STATE_V2] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(35) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18), + + // CCC V3 + // CCC @ 1128 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 2 + [kDVFM_STATE_V3] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(47) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (4ULL << 18), + +#if !SUB_TARGET_N102 + // CCC V4 + // CCC @ 1392 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 3.0 + [kDVFM_STATE_V4] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(58) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (6ULL << 18) +#endif +#if SUB_PLATFORM_T7001 || SUB_TARGET_J96 || SUB_TARGET_J97 + // CCC V5 + // CCC @ 1512 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 3.0 + ,[kDVFM_STATE_V5] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(63) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (6ULL << 18) + + // CCC V6 (pseudo-state) + // CCC @ 1608 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 3.0 + ,[kDVFM_STATE_V6] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(67) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (6ULL << 18) + + // CCC V6 Unbinned (pseudo-state) + // CCC @ 1608 MHz, enable voltage change sequence, Clk src = PLL, BIU div = 3.0 + ,[kDVFM_STATE_V6_UNBINNED] = CCC_DVFM_ST_PLL_P(1) | CCC_DVFM_ST_PLL_M(67) | + CCC_DVFM_ST_PLL_S(0) | (1ULL << 21) | (6ULL << 18) +#endif +#endif +}; + +#if APPLICATION_SECUREROM +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_SECUREROM +#endif + +#if APPLICATION_IBOOT +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_IBOOT_MEM_FULL_PERF +#endif + +struct pmgr_soc_perf_state { + uint32_t entry[3]; +}; + +static struct pmgr_soc_perf_state pmgr_soc_perf_states[] = { + [kSOC_PERF_STATE_BYPASS] = { + {0x00000000, + 0x00000000, +#if SUB_PLATFORM_T7000 + 0x00000070}}, +#elif SUB_PLATFORM_T7001 + 0x00000000}}, +#endif + +#if APPLICATION_SECUREROM + [kSOC_PERF_STATE_SECUREROM] = { + // af = pll4 div 5 + // lio = pll4 div 10 + {0x00055000, + 0x00000000, +#if SUB_PLATFORM_T7000 + 0x00000070}}, +#elif SUB_PLATFORM_T7001 + 0x00000000}}, +#endif +#endif + +#if APPLICATION_IBOOT + // Memory Low Performance: + [kSOC_PERF_STATE_IBOOT_MEM_LOW_PERF] = { + // mcu_fixed = pll1 + // mcu = pll1 div 16 + // mcu_cfg = 0x3 + // af = pll4 div 5 + // lio = pll4 div 10 + // media_af = pll4 div 6 + // isp_af = pll4 div 6 + {0x06655361, + // isp_c = pll4 div 6 + // isp = pll4 div 8 + // vdec = pll4 div 10 + // venc = pll4 div 7 + // ajpeg_ip = pll4 div 14 + // ajpeg_wrap = pll4 div 11 + // msr = pll4 div 8 + 0x07887876, + 0x00000000}}, + + // Memory Full Performance / VMIN: + [kSOC_PERF_STATE_IBOOT_MEM_FULL_PERF] = { +#if !SUPPORT_FPGA + // mcu_fixed = pll1 + // mcu = pll1 + // mcu_cfg = 0x0 + // af = pll4 div 5 + // lio = pll4 div 10 + // media_af = pll4 div 6 + // isp_af = pll4 div 6 + {0x06655081, +#else + // mcu_fixed = pll1 + // mcu = pll1 div 16 + // mcu_cfg = 0x3 + // af = pll4 div 5 + // lio = pll4 div 10 + // media_af = pll4 div 6 + // isp_af = pll4 div 6 + {0x06655361, +#endif + // isp_c = pll4 div 6 + // isp = pll4 div 8 + // vdec = pll4 div 10 + // venc = pll4 div 7 + // ajpeg_ip = pll4 div 14 + // ajpeg_wrap = pll4 div 11 + // msr = pll4 div 8 + 0x07887876, + 0x00000000}}, + + // VNOM: + [kSOC_PERF_STATE_VNOM] = { +#if !SUPPORT_FPGA + // mcu_fixed = pll1 + // mcu = pll1 + // mcu_cfg = 0x0 + // af = pll4 div 5 + // lio = pll4 div 10 + // media_af = pll4 div 5 + // isp_af = pll4 div 5 + {0x05555081, +#else + // mcu_fixed = pll1 + // mcu = pll1 div 16 + // mcu_cfg = 0x3 + // af = pll4 div 5 + // lio = pll4 div 10 + // media_af = pll4 div 5 + // isp_af = pll4 div 5 + {0x05555361, +#endif + // isp_c = pll4 div 5 + // isp = pll4 div 7 + // vdec = pll4 div 7 + // venc = pll4 div 5 + // ajpeg_ip = pll4 div 10 + // ajpeg_wrap = pll4 div 8 + // msr = pll4 div 6 + 0x05555565, + 0x00000000}}, +#endif +}; + +#if APPLICATION_SECUREROM +static uint32_t perf_level = kPerformanceHigh; +#endif + +#if APPLICATION_IBOOT +static uint32_t perf_level = kPerformanceMemoryFull; +#endif + + +#if APPLICATION_IBOOT + +#if SUB_PLATFORM_T7000 && WITH_HW_MIPI +/* MIPI: PLL0 @900MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 2 +#define PLL0_M 150 +#define PLL0_S 1 +#define PLL0_V PLL_VCO_TARGET(PLL0) +#define PLL0_T PLL_FREQ_TARGET(PLL0) +#endif + +#if TARGET_DDR_740M + +/* PLL1 @740MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 6 +#define PLL1_M 185 +#define PLL1_S 0 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#elif TARGET_DDR_798M + +/* PLL1 @798MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 4 +#define PLL1_M 133 +#define PLL1_S 0 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#elif TARGET_DDR_792M + +/* PLL1 @792MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 66 +#define PLL1_S 1 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#else + +/* PLL1 @800MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 3 +#define PLL1_M 100 +#define PLL1_S 0 +#define PLL1_V PLL_VCO_TARGET(PLL1) +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +#endif + +// Support 100 MHz PLL3 on Capri for PCIe +#if SUB_PLATFORM_T7001 +/* PLL3 @100MHz */ +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 1 +#define PLL3_M 50 +#define PLL3_S 11 +#define PLL3_V PLL_VCO_TARGET(PLL3) +#define PLL3_T PLL_FREQ_TARGET(PLL3) +#endif + +/* PLL4 @2400MHz (VCO output) */ +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 1 +#define PLL4_M 50 +#define PLL4_S 0 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) +#define PLL4_VCO_ENABLED 1 + +#ifndef TARGET_SPARE0_CLK_CFG +#define TARGET_SPARE0_CLK_CFG 0x00000000 +#endif + +#define VID0_CLKD TARGET_VID0_CLK_CFG + +#if SUB_PLATFORM_T7000 +#if WITH_HW_MIPI +#define MIPI_CLKD 0x88100000 +#else +#define MIPI_CLKD 0x80100000 +#endif + +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x81100000, 0x88100000, MIPI_CLKD, 0x86100000, // 0x10000: mcu_fixed, mcu, mipi_dsi, nco_ref0, + 0x85100000, 0x80100000, 0x88100000, 0x85100000, // 0x10010: nco_ref1, nco_alg0, nco_alg1, hsciphy_ref_12m, + 0x85100000, 0x85100000, 0x85100000, 0x85100000, // 0x10020: usb480_0, usb480_1, usb_ohci_48m, usb, + 0x85100000, 0x85100000, 0x80100000, 0x85100000, // 0x10030: usb_free_60m, sio_c, sio_p, isp_c, + 0x86100000, 0x81100000, 0x82100000, 0x85100000, // 0x10040: isp, isp_sensor0_ref, isp_sensor1_ref, vdec, + 0x85100000, VID0_CLKD, 0x86100000, 0x86100000, // 0x10050: venc, vid0, disp0, disp1, + 0x85100000, 0x85100000, 0x85100000, 0x85100000, // 0x10060: ajpeg_ip, ajpeg_wrap, msr, af, + 0x85100000, 0x85100000, 0x86100000, 0x87100000, // 0x10070: lio, mca0_m, mca1_m, mca2_m + 0x88100000, 0x89100000, 0x85100000, 0x86100000, // 0x10080: mca3_m, mca4_m, sep, gpio, + 0x85100000, 0x85100000, 0x85100000, 0x85100000, // 0x10090: spi0_n, spi1_n, spi2_n, spi3_n + 0x80100000, 0x80100000, 0x85100000, 0x85100000, // 0x100A0: debug, pcie_ref, pcie_app, tmps, + 0x85100000, 0x85100000, 0x86100000, 0x85100000, // 0x100B0: media_af, isp_af, gfx_af, ans_c + 0x85100000 // 0x100C0: anc_link +}; +#elif SUB_PLATFORM_T7001 +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x81100000, 0x88100000, 0x86100000, 0x85100000, // 0x10000: mcu_fixed, mcu, nco_ref0, nco_ref1, + 0x80100000, 0x88100000, 0x85100000, 0x85100000, // 0x10010: nco_alg0, nco_alg1, hsciphy_ref_12m, usb480_0, + 0x85100000, 0x85100000, 0x85100000, 0x85100000, // 0x10020: usb480_1, usb_ohci_48m, usb, usb_free_60m, + 0x85100000, 0x80100000, 0x85100000, 0x86100000, // 0x10030: sio_c, sio_p, isp_c, isp, + 0x81100000, 0x82100000, 0x85100000, 0x85100000, // 0x10040: isp_sensor0_ref, isp_sensor1_ref, vdec, venc, + VID0_CLKD, 0x85100000, 0x86100000, 0x85100000, // 0x10050: vid0, disp0, disp1, ajpeg_ip, + 0x85100000, 0x85100000, 0x85100000, 0x85100000, // 0x10060: ajpeg_wrap, msr, af, lio, + 0x85100000, 0x86100000, 0x87100000, 0x88100000, // 0x10070: mca0_m, mca1_m, mca2_m, mca3_m, + 0x89100000, 0x85100000, 0x86100000, 0x85100000, // 0x10080: mca4_m, sep, gpio, spi0_n, + 0x85100000, 0x85100000, 0x85100000, 0x80100000, // 0x10090: spi1_n, spi2_n, spi3_n, debug, + 0x85100000, 0x85100000, 0x85100000, 0x85100000, // 0x100A0: pcie_app, tmps, media_af, isp_af, + 0x86100000, 0x85100000, 0x85100000 // 0x100B0: gfx_af, ans_c, anc_link +}; +#endif + +static const uint32_t spare_divs_active[PMGR_SPARE_CLK_CFG_COUNT] = { + TARGET_SPARE0_CLK_CFG, // 0x10208: spare0 + 0x00000000, // 0x1020C: spare1 + 0x00000000, // 0x10210: spare2 + 0x00000000, // 0x10214: spare3 + 0x80100028, // 0x10218: isp_ref0 + 0x80100028 // 0x1021C: isp_ref1 +}; + +/* GFX table. The voltage information is maintained in chipid.c */ +struct gfx_state_info { + uint32_t dwi_val; /* will be populated by determining the binning info */ + uint32_t fb_div; + uint32_t pre_div; + uint32_t op_div; + uint32_t dwi_sram_val; /* Only meaningfull for SUB_PLATFORM_T7001 */ + +}; + +static struct gfx_state_info gfx_states[] = { + [CHIPID_GPU_VOLTAGE_OFF] = { 0, 0, 0, 0, 0 }, /* Power off Templar4 state.*/ + [CHIPID_GPU_VOLTAGE_V0] = { 0, 365, 6, 3, 0 }, /* 365 MHz */ + [CHIPID_GPU_VOLTAGE_V1] = { 0, 75, 2, 1, 0 }, /* 450 MHz */ + [CHIPID_GPU_VOLTAGE_V2] = { 0, 125, 3, 1, 0 }, /* 500 MHz */ +#if SUB_TARGET_N56 || SUB_TARGET_J42 || SUB_TARGET_J42D || SUB_PLATFORM_T7001 || SUB_TARGET_J96 || SUB_TARGET_J97 + [CHIPID_GPU_VOLTAGE_V3] = { 0, 275, 6, 1, 0 }, /* 550 MHz */ +#endif +#if SUB_PLATFORM_T7001 || SUB_TARGET_J96 || SUB_TARGET_J97 + [CHIPID_GPU_VOLTAGE_V4] = { 0, 50, 1, 1, 0 }, /* 600 MHz */ + [CHIPID_GPU_VOLTAGE_V5] = { 0, 325, 6, 1, 0 }, /* 650 MHz */ +#endif + [CHIPID_GPU_VOLTAGE_V0_DIDT] = { 0, 365, 6, 7, 0 }, /* 182.5 MHz */ + [CHIPID_GPU_VOLTAGE_V1_DIDT] = { 0, 75, 2, 3, 0 }, /* 225 MHz */ + [CHIPID_GPU_VOLTAGE_V2_DIDT] = { 0, 125, 3, 3, 0 }, /* 250 MHz */ +#if SUB_TARGET_N56 || SUB_TARGET_J42 || SUB_TARGET_J42D || SUB_PLATFORM_T7001 || SUB_TARGET_J96 || SUB_TARGET_J97 + [CHIPID_GPU_VOLTAGE_V3_DIDT] = { 0, 275, 6, 3, 0 }, /* 275 MHz */ +#endif +#if SUB_PLATFORM_T7001 || SUB_TARGET_J96 || SUB_TARGET_J97 + [CHIPID_GPU_VOLTAGE_V4_DIDT] = { 0, 50, 1, 3, 0 }, /* 300 MHz */ + [CHIPID_GPU_VOLTAGE_V5_DIDT] = { 0, 325, 6, 3, 0 }, /* 325 MHz */ +#endif +#if 0 + [5] = {0, 0, 0, 0}, /* Debug state. chipid.c has a valid voltage for this state. */ +#endif +}; + +static void set_gfx_perf_state(uint32_t state_num, struct gfx_state_info *gfx_state); +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_SECUREROM + +#if SUB_PLATFORM_T7001 && !SUPPORT_FPGA +/* PLL3 @100MHz */ +#define PLL3 3 +#define PLL3_O OSC_FREQ +#define PLL3_P 1 +#define PLL3_M 50 +#define PLL3_S 11 +#define PLL3_V PLL_VCO_TARGET(PLL3) +#define PLL3_T PLL_FREQ_TARGET(PLL3) +#endif + +/* PLL4 @1200MHz */ +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 1 +#define PLL4_M 50 +#define PLL4_S 0 +#define PLL4_V PLL_VCO_TARGET(PLL4) +#define PLL4_T PLL_FREQ_TARGET(PLL4) +#define PLL4_VCO_ENABLED 0 + + +// We won't touch the clk gen's that aren't necessary during SecureROM. +#if SUB_PLATFORM_T7000 +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10000: mcu_fixed, mcu, mipi_dsi, nco_ref0, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10010: nco_ref1, nco_alg0, nco_alg1, hsciphy_ref_12m, + 0x80100000, 0x80100000, 0x80100000, 0x86100000, // 0x10020: usb480_0, usb480_1, usb_ohci_48m, usb, + 0x80100000, 0x85100000, 0x85100000, 0x80100000, // 0x10030: usb_free_60m, sio_c, sio_p, isp_c + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10040: isp, isp_sensor0_ref, isp_sensor1_ref, vdec + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10050: venc, vid0, disp0, disp1 + 0x80100000, 0x80100000, 0x80100000, 0x85100000, // 0x10060: ajpeg_ip, ajpeg_wrap, msr, af + 0x85100000, 0x80100000, 0x80100000, 0x80100000, // 0x10070: lio, mca0_m, mca1_m, mca2_m + 0x80100000, 0x80100000, 0x85100000, 0x86100000, // 0x10080: mca3_m, mca4_m, sep, gpio + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10090: spi0_n, spi1_n, spi2_n, spi3_n + 0x80100000, 0x80100000, 0x85100000, 0x80100000, // 0x100a0: debug, pcie_ref, pcie_app, tmps + 0x80100000, 0x80100000, 0x80100000, 0x85100000, // 0x100b0: media, isp_af, gfx, ans_c + 0x85100000 // 0x100c0: anc_link +}; +#elif SUB_PLATFORM_T7001 +static const uint32_t clk_divs_active[PMGR_CLK_CFG_COUNT] = { + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10000: mcu_fixed, mcu, nco_ref0, nco_ref1, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10010: nco_alg0, nco_alg1, hsciphy_ref_12m, usb480_0, + 0x80100000, 0x80100000, 0x86100000, 0x80100000, // 0x10020: usb480_1, usb_ohci_48m, usb, usb_free_60m, + 0x85100000, 0x85100000, 0x80100000, 0x80100000, // 0x10030: sio_c, sio_p, isp_c, isp, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10040: isp_sensor0_ref, isp_sensor1_ref, vdec, venc, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10050: vid0, disp0, disp1, ajpeg_ip, + 0x80100000, 0x80100000, 0x85100000, 0x85100000, // 0x10060: ajpeg_wrap, msr, af, lio, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10070: mca0_m, mca1_m, mca2_m, mca3_m, + 0x80100000, 0x85100000, 0x86100000, 0x80100000, // 0x10080: mca4_m, sep, gpio, spi0_n, + 0x80100000, 0x80100000, 0x80100000, 0x80100000, // 0x10090: spi1_n, spi2_n, spi3_n, debug, + 0x85100000, 0x80100000, 0x80100000, 0x80100000, // 0x100a0: pcie_app, tmps, media, isp_af, + 0x80100000, 0x85100000, 0x85100000 // 0x100b0: gfx, ans_c, anc_link +}; +#endif + +static const uint32_t spare_divs_active[PMGR_SPARE_CLK_CFG_COUNT] = { + 0x80000001, // 0x10208: s0 + 0x80000001, // 0x1020C: s1 + 0x80000001, // 0x10210: s2 + 0x80000001, // 0x10214: s3, + 0x80000001, // 0x10218: isp_ref0 + 0x80000001 // 0x1021c: isp_ref1 +}; + +#endif /* APPLICATION_SECUREROM */ + + +static const struct clock_config clk_configs[PMGR_CLK_COUNT] = { + [PMGR_CLK_MCU_FIXED] = { + &rPMGR_MCU_FIXED_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_PLL1, 1 } + } + }, + + [PMGR_CLK_MCU] = { + &rPMGR_MCU_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL1, 8 }, + { PMGR_CLK_PLL1, 16 }, + { PMGR_CLK_PLL4, 48 }, + { PMGR_CLK_PLL1, 1 } + } + }, +#if SUB_PLATFORM_T7000 + [PMGR_CLK_MIPI_DSI] = { + &rPMGR_MIPI_DSI_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL0, 1 } + } + }, +#endif + + [PMGR_CLK_NCO_REF0] = { + &rPMGR_NCO_REF0_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL4, 7 } + } + }, + + [PMGR_CLK_NCO_REF1] = { + &rPMGR_NCO_REF1_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL4, 7 } + } + }, + + [PMGR_CLK_NCO_ALG0] = { + &rPMGR_NCO_ALG0_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 16 }, + { PMGR_CLK_PLL4, 24 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_NCO_ALG1] = { + &rPMGR_NCO_ALG1_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 16 }, + { PMGR_CLK_PLL4, 24 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_HSICPHY_REF_12M] = { + &rPMGR_HSICPHY_REF_12M_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 2 } + } + }, + + [PMGR_CLK_USB480_0] = { + &rPMGR_USB480_0_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 } + } + }, + + [PMGR_CLK_USB480_1] = { + &rPMGR_USB480_1_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 } + } + }, + + [PMGR_CLK_USB_OHCI_48M] = { + &rPMGR_USB_OHCI_48M_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_USB] = { + &rPMGR_USB_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 20 }, + { PMGR_CLK_PLL4, 24 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 50 }, + { PMGR_CLK_PLL4, 72 }, + { PMGR_CLK_PLL4, 80 } + } + }, + + [PMGR_CLK_USB_FREE_60M] = { + &rPMGR_USB_FREE_60M_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 40 } + } + }, + + [PMGR_CLK_SIO_C] = { + &rPMGR_SIO_C_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 48 } + } + }, + + [PMGR_CLK_SIO_P] = { + &rPMGR_SIO_P_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 20 }, + { PMGR_CLK_PLL4, 24 }, + { PMGR_CLK_PLL4, 30 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 48 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_ISP_C] = { + &rPMGR_ISP_C_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 48 } + } + }, + + [PMGR_CLK_ISP] = { + &rPMGR_ISP_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 12 } + } + }, + + [PMGR_CLK_ISP_SENSOR0_REF] = { + &rPMGR_ISP_SENSOR0_REF_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 } + } + }, + + [PMGR_CLK_ISP_SENSOR1_REF] = { + &rPMGR_ISP_SENSOR1_REF_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 } + } + }, + + [PMGR_CLK_VDEC] = { + &rPMGR_VDEC_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 16 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_VENC] = { + &rPMGR_VENC_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_VID0] = { + &rPMGR_VID0_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 11 }, + { PMGR_CLK_PLL4, 39 } +#if SUB_PLATFORM_T7001 + ,{ PMGR_CLK_PLL4, 30 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 7 } +#endif + } + }, + +#if SUB_PLATFORM_T7000 + [PMGR_CLK_DISP0] = { + &rPMGR_DISP0_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 14 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_DISP1] = { + &rPMGR_DISP1_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 14 }, + { PMGR_CLK_PLL4, 24 } + } + }, +#elif SUB_PLATFORM_T7001 + [PMGR_CLK_DISP0] = { + &rPMGR_DISP0_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 14 } + } + }, + + [PMGR_CLK_DISP1] = { + &rPMGR_DISP1_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 14 } + } + }, +#endif + + [PMGR_CLK_AJPEG_IP] = { + &rPMGR_AJPEG_IP_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 11 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 14 }, + { PMGR_CLK_PLL4, 16 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_AJPEG_WRAP] = { + &rPMGR_AJPEG_WRAP_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 11 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 14 }, + { PMGR_CLK_PLL4, 16 } + } + }, + + [PMGR_CLK_MSR] = { + &rPMGR_MSR_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 16 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_AF] = { + &rPMGR_AF_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_LIO] = { + &rPMGR_LIO_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 14 }, + { PMGR_CLK_PLL4, 16 }, + { PMGR_CLK_PLL4, 18 }, + { PMGR_CLK_PLL4, 20 }, + { PMGR_CLK_PLL4, 48 } + } + }, + + [PMGR_CLK_MCA0_M] = { + &rPMGR_NCO_CLK_CFG(0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA1_M] = { + &rPMGR_NCO_CLK_CFG(1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA2_M] = { + &rPMGR_NCO_CLK_CFG(2), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA3_M] = { + &rPMGR_NCO_CLK_CFG(3), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_MCA4_M] = { + &rPMGR_NCO_CLK_CFG(4), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_NOT_SUPPORTED, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 } + } + }, + + [PMGR_CLK_SEP] = { + &rPMGR_SEP_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_GPIO] = { + &rPMGR_GPIO_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 100 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_SPI0_N] = { + &rPMGR_SPI0_N_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 48 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_SPI1_N] = { + &rPMGR_SPI1_N_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 48 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_SPI2_N] = { + &rPMGR_SPI2_N_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 48 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_SPI3_N] = { + &rPMGR_SPI3_N_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 48 }, + { PMGR_CLK_PLL4, 50 } + } + }, + + [PMGR_CLK_DEBUG] = { + &rPMGR_DEBUG_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 20 }, + { PMGR_CLK_PLL4, 24 }, + { PMGR_CLK_PLL4, 30 }, + { PMGR_CLK_PLL4, 40 }, + { PMGR_CLK_PLL4, 48 } + } + }, + +#if SUB_PLATFORM_T7000 + [PMGR_CLK_PCIE_REF] = { + &rPMGR_PCIE_REF_CLK_CFG, + { + { PMGR_CLK_PLL4, 24 }, + { PMGR_CLK_PLL3, 1 }, + } + }, +#endif + + [PMGR_CLK_PCIE_APP] = { + &rPMGR_PCIE_APP_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_TMPS] = { + &rPMGR_TMPS_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 20 }, + } + }, + + [PMGR_CLK_MEDIA_AF] = { + &rPMGR_MEDIA_AF_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 24 }, + } + }, + + [PMGR_CLK_ISP_AF] = { + &rPMGR_ISP_AF_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 24 }, + } + }, + + [PMGR_CLK_GFX_AF] = { + &rPMGR_GFX_AF_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 24 }, + } + }, + + [PMGR_CLK_ANS_C] = { + &rPMGR_ANS_C_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 6 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 10 }, + { PMGR_CLK_PLL4, 48 } + } + }, + + [PMGR_CLK_ANC_LINK] = { + &rPMGR_ANC_LINK_CLK_CFG, + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 12 }, + { PMGR_CLK_PLL4, 18 }, + { PMGR_CLK_PLL4, 24 } + } + }, + + [PMGR_CLK_S0] = { + &rPMGR_S0_CLK_CFG, + { + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL2, 1 }, +#if SUB_PLATFORM_T7000 + { PMGR_CLK_PLL3, 1 }, +#elif SUB_PLATFORM_T7001 + { PMGR_CLK_PLL0, 1 }, +#endif + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_S1] = { + &rPMGR_S1_CLK_CFG, + { + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL2, 1 }, +#if SUB_PLATFORM_T7000 + { PMGR_CLK_PLL3, 1 }, +#elif SUB_PLATFORM_T7001 + { PMGR_CLK_PLL0, 1 }, +#endif + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_S2] = { + &rPMGR_S2_CLK_CFG, + { + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL2, 1 }, +#if SUB_PLATFORM_T7000 + { PMGR_CLK_PLL3, 1 }, +#elif SUB_PLATFORM_T7001 + { PMGR_CLK_PLL0, 1 }, +#endif + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_S3] = { + &rPMGR_S3_CLK_CFG, + { + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL2, 1 }, +#if SUB_PLATFORM_T7000 + { PMGR_CLK_PLL3, 1 }, +#elif SUB_PLATFORM_T7001 + { PMGR_CLK_PLL0, 1 }, +#endif + { PMGR_CLK_PLL4, 2 } + } + }, + + [PMGR_CLK_ISP_REF0] = { + &rPMGR_ISP_REF0_CLK_CFG, + { + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 } + } + }, + + [PMGR_CLK_ISP_REF1] = { + &rPMGR_ISP_REF1_CLK_CFG, + { + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL4, 7 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL4, 9 } + } + }, +}; + +static uint32_t get_apsc_ccc_state(void); +static void set_apsc_ccc_state(uint32_t target_state); +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static void init_soc_thermal_sensors(void); +static void init_soc_sochot(void); +static void init_cpu_thermal_sensors(void); +static void init_cpu_sochot(void); +static void init_soc_tvm_tunables(void); +#endif +static void clocks_get_frequencies(void); +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk); +static uint32_t get_pll(int32_t pll); +static uint32_t get_pll_cpu(void); +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s, bool vco_output); +static uint32_t is_pll_running(int32_t pll); +static void set_running_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s); +static uint64_t pmgr_get_offset_from_diff_uV(uint32_t buck, uint32_t uV); +static uint32_t get_spare(int32_t spare); +static void clocks_set_gates(uint64_t *devices); +static void clocks_quiesce_internal(void); +static void power_on_sep(void); + +// current clock frequencies +static uint32_t clks[PMGR_CLK_COUNT + 1]; + +void platform_power_spin(uint32_t usecs) +{ + arm_no_wfe_spin(usecs); +} + +int clocks_init(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) + clks[PMGR_CLK_OSC] = OSC_FREQ; + + clocks_get_frequencies(); + +#endif /* (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) */ + + return 0; +} + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +/* + * To avoid di/dt voltage drop at the end of PLL relock. rdar://problem/13112194. + */ +static void set_ccc_pll_relock_div2(void) +{ + uint32_t reg; + + reg = rCCC_PLL_CFG2; + reg &= ~CCC_PLL_CFG2_RELOCKBYS2_S4_MASK; + reg |= CCC_PLL_CFG2_RELOCKBYS2_S4_DIV2; + rCCC_PLL_CFG2 = reg; +} + +static void set_nco_clocks(void) +{ + uint32_t i; + + // Enable this NCO with alg_ref0_clk and nco_ref0_clk. + for (i = 0; i < 5; i++) + rPMGR_NCO_CLK_CFG(i) |= (1 << 31); +} + +static void apply_pmgr_tunables() +{ +#define CLAMP_TIME_MASK (((1 << 8) - 1) << 8) +#define CLK_EN_TIME_MASK (((1 << 8) - 1) << 16) +#define RETN_SAVE_TIME_MASK (((1 << 3) - 1) << 24) +#define RETN_RESTORE_TIME_MASK (((1 << 3) - 1) << 27) +#define _PWRGATE_CFG0(rCFG0, RETN_RESTORE_TIME, RETN_SAVE_TIME, CLK_EN_TIME, CLAMP_TIME) \ + regTemp = rCFG0; \ + regTemp &= ~CLAMP_TIME_MASK; \ + regTemp |= (CLAMP_TIME << 8); \ + regTemp &= ~CLK_EN_TIME_MASK; \ + regTemp |= (CLK_EN_TIME << 16); \ + regTemp &= ~RETN_SAVE_TIME_MASK; \ + regTemp |= (RETN_SAVE_TIME << 24); \ + regTemp &= ~RETN_RESTORE_TIME_MASK; \ + regTemp |= (RETN_RESTORE_TIME << 27); \ + rCFG0 = regTemp; + +#define RAMP_PRE_TIME_MASK (((1 << 12) - 1) << 0) +#define RAMP_ALL_TIME_MASK (((1 << 12) - 1) << 16) + +#define _PWRGATE_CFG1(rCFG1, RAMP_ALL_TIME, RAMP_PRE_TIME) \ + regTemp = rCFG1; \ + regTemp &= ~RAMP_PRE_TIME_MASK; \ + regTemp |= (RAMP_PRE_TIME << 0); \ + regTemp &= ~RAMP_ALL_TIME_MASK; \ + regTemp |= (RAMP_ALL_TIME << 16); \ + rCFG1 = regTemp; + +#define RESET_DOWN_TIME_MASK (((1 << 8) - 1) << 0) +#define RESET_UP_TIME_MASK (((1 << 8) - 1) << 8) +#define RESET_OFF_TIME_MASK (((1 << 8) - 1) << 16) + +#define _PWRGATE_CFG2(rCFG2, RESET_OFF_TIME, RESET_UP_TIME, RESET_DOWN_TIME) \ + regTemp = rCFG2; \ + regTemp &= ~RESET_DOWN_TIME_MASK; \ + regTemp |= (RESET_DOWN_TIME << 0); \ + regTemp &= ~RESET_UP_TIME_MASK; \ + regTemp |= (RESET_UP_TIME << 8); \ + regTemp &= ~RESET_OFF_TIME_MASK; \ + regTemp |= (RESET_OFF_TIME << 16); \ + rCFG2 = regTemp; + +#define DBG_CLK_ON_RAMP_MASK (1 << 4) + +#define _PWRGATE_DBG(rDBG, DBG_CLK_ON_RAMP) \ + regTemp = rDBG; \ + regTemp &= ~DBG_CLK_ON_RAMP_MASK; \ + regTemp |= (DBG_CLK_ON_RAMP << 4); \ + rDBG = regTemp; + + uint32_t regTemp; + + // A0 tunables. + + _PWRGATE_CFG0(rPMGR_PWRGATE_AMC_CFG0, 0x1, 0x1, 0x7, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_AMC_CFG1, 0x13, 0x1); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_AMC_CFG1, 0x12, 0x1); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_AMC_CFG2, 0x7, 0x7, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_USB_CFG0, 0x1, 0x1, 0x4, 0x3); + _PWRGATE_CFG1(rPMGR_PWRGATE_USB_CFG1, 0xe, 0x1); + _PWRGATE_CFG2(rPMGR_PWRGATE_USB_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ACS_CFG0, 0x1, 0x1, 0x6, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_ACS_CFG1, 0xe, 0x1); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_ACS_CFG1, 0x12, 0x1); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_ACS_CFG2, 0x6, 0x6, 0x0); + + _PWRGATE_CFG0(rPMGR_PWRGATE_DISP0_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_DISP0_CFG1, 0x33, 0x2); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_DISP0_CFG1, 0x3b, 0x3); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_DISP0_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_DISP1_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_DISP1_CFG1, 0x31, 0x3); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_DISP1_CFG1, 0x38, 0x3); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_DISP1_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ISP_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_ISP_CFG1, 0x78, 0x3); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_ISP_CFG1, 0x5c, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_ISP_CFG2, 0x8, 0x8, 0x8); + _PWRGATE_DBG(rPMGR_PWRGATE_ISP_DBG, 0x1); + + _PWRGATE_CFG0(rPMGR_PWRGATE_MEDIA_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_MEDIA_CFG1, 0x95, 0x4); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_MEDIA_CFG1, 0x72, 0x3); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_MEDIA_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_VDEC0_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_VDEC0_CFG1, 0x53, 0x2); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_VDEC0_CFG1, 0x36, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_VDEC0_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_VENC_CPU_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_CPU_CFG1, 0x65, 0x3); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_CPU_CFG1, 0x58, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_VENC_CPU_CFG2, 0x8, 0x8, 0x8); + _PWRGATE_DBG(rPMGR_PWRGATE_VENC_CPU_DBG, 0x1); + + _PWRGATE_CFG0(rPMGR_PWRGATE_PCIE_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_PCIE_CFG1, 0x2b, 0x2); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_PCIE_CFG1, 0x56, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_PCIE_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_ANS_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_ANS_CFG1, 0x3a, 0x2); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_ANS_CFG1, 0x2a, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_ANS_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_GFX_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_GFX_CFG1, 0x13, 0x1); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_GFX_CFG1, 0x1f, 0x1); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_GFX_CFG2, 0x8, 0x8, 0x8); + + _PWRGATE_CFG0(rPMGR_PWRGATE_VENC_PIPE_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_PIPE_CFG1, 0x7c, 0x2); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_PIPE_CFG1, 0x5e, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_VENC_PIPE_CFG2, 0x8, 0x8, 0x8); + _PWRGATE_DBG(rPMGR_PWRGATE_VENC_PIPE_DBG, 0x1); + + _PWRGATE_CFG0(rPMGR_PWRGATE_VENC_ME0_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_ME0_CFG1, 0x55, 0x2); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_ME0_CFG1, 0x40, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_VENC_ME0_CFG2, 0x8, 0x8, 0x8); + _PWRGATE_DBG(rPMGR_PWRGATE_VENC_ME0_DBG, 0x1); + + _PWRGATE_CFG0(rPMGR_PWRGATE_VENC_ME1_CFG0, 0x1, 0x1, 0x4, 0x3); +#if SUB_PLATFORM_T7000 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_ME1_CFG1, 0x55, 0x2); +#elif SUB_PLATFORM_T7001 + _PWRGATE_CFG1(rPMGR_PWRGATE_VENC_ME1_CFG1, 0x40, 0x2); +#endif + _PWRGATE_CFG2(rPMGR_PWRGATE_VENC_ME1_CFG2, 0x8, 0x8, 0x8); + _PWRGATE_DBG(rPMGR_PWRGATE_VENC_ME1_DBG, 0x1); + + // 2. Apply MCU Async reset timing. + + rPMGR_PWRGATE_MCU_ASYNC_RESET = (0x1 << 0) | (0x1 << 4) | (0x1 << 8); + + // 3. Apply VolMan tunables + + rPMGR_VOLMAN_VAR_SOC_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + rPMGR_VOLMAN_FIXED_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + rPMGR_VOLMAN_GFX_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + rPMGR_VOLMAN_CPU_DELAY = (0x5 << 0) | (0x6b << 10) | (0xbb8 << 20); + + // 4. Apply Misc Spare tunable + + rPMGR_MISC_SPARE0 = 0x100; + + // 5. Apply PLL4 tunable +#if SUB_PLATFORM_T7000 + regTemp = rPMGR_PLL_DEBUG1(4); + regTemp &= ~(PMGR_PLL_DEBUG1_RESERVE_IN_MASK << PMGR_PLL_DEBUG1_RESERVE_IN_SHIFT); + regTemp |= (0x10 << PMGR_PLL_DEBUG1_RESERVE_IN_SHIFT); + rPMGR_PLL_DEBUG1(4) = regTemp; +#endif + + return; +} + +static void apply_ccc_tunables(void) +{ + rCCC_PRE_TD_TMR = 0x4; + rCCC_PRE_FLUSH_TMR = 0x1000; +#if SUB_PLATFORM_T7000 + rCCC_PLL_DLY_CFG0 = (0x0 << 10) | 0x5; +#else + rCCC_PLL_DLY_CFG0 = (0x0 << 10) | 0x5; + rCCC_PSW_DLY = (0x7f << 22) | (0x1 << 16) | 0x60; +#endif + rCCC_DCD_NRG_WGHT = 0x0c803ce24838c28aULL; + rCCC_IEX_NRG_WGHT = 0x018a00a90046c597ULL; + rCCC_LSU_NRG_WGHT = 0x62d37934a9854c2aULL; + rCCC_NEX_NRG_WGHT0 = 0x6666574475795557ULL; + rCCC_NEX_NRG_WGHT1 = 0xc6b7b54676896658ULL; + rCCC_NEX_NRG_WGHT2 = 0x000000ba787a7aabULL; + +} +#endif + +struct dvfm_data +{ + uint32_t dvfm_state_vmax; + uint32_t dvfm_state_iboot_cnt; + uint32_t dvfm_state_vnom; + uint32_t dvfm_state_vboost; + uint32_t voltage_states1_count; + uint32_t voltage_states1_size; +}; + +#if SUB_PLATFORM_T7001 || SUB_TARGET_J96 || SUB_TARGET_J97 +#if APPLICATION_IBOOT + +#if SUB_TARGET_J98 || SUB_TARGET_J99 +static bool pmgr_check_use1608MHz_unbinned(uint32_t board_id, uint32_t board_rev) +{ + bool use1608MHz_unbinned = false; + switch (board_id & 0xf) { + case TARGET_BOARD_ID_J98DEV: + case TARGET_BOARD_ID_J99DEV: + break; + case TARGET_BOARD_ID_J98AP: + case TARGET_BOARD_ID_J99AP: + if ((board_rev & 0xf) == J99_PROTO3_BOARD_REV) + use1608MHz_unbinned = true; + break; + default: + panic("Unknown board id %d\n", board_id); + } + return use1608MHz_unbinned; +} + +static bool pmgr_check_use1608MHz_binned(uint32_t board_id, uint32_t board_rev) +{ + bool use1608MHz_binned = false; + switch (board_id & 0xf) { + case TARGET_BOARD_ID_J98DEV: + case TARGET_BOARD_ID_J99DEV: + break; + case TARGET_BOARD_ID_J98AP: + case TARGET_BOARD_ID_J99AP: + if ((board_rev & 0xf) <= J99_PROTO3_P9_BOARD_REV) + use1608MHz_binned = true; + break; + default: + panic("Unknown board id %d\n", board_id); + } + return use1608MHz_binned; +} +#endif + +bool pmgr_check_gpu_use650MHz_unbinned(uint32_t board_id, uint32_t board_rev) +{ + bool use_gpu_650MHz_unbinned = false; + switch (board_id & 0xf) { +#if SUB_TARGET_J98 || SUB_TARGET_J99 + case TARGET_BOARD_ID_J98AP: + case TARGET_BOARD_ID_J99AP: + if ((board_rev & 0xf) <= J99_EVT_BOARD_REV && chipid_get_fuse_revision() < MINIMUM_BINNED_GPU_P6_REVISION) + use_gpu_650MHz_unbinned = true; + break; +#endif + default: + break; + } + return use_gpu_650MHz_unbinned; +} + +bool pmgr_check_gpu_use650MHz_binned(uint32_t board_id, uint32_t board_rev) +{ + bool use_gpu_650MHz_binned = false; + switch (board_id & 0xf) { +#if SUB_TARGET_J98 || SUB_TARGET_J99 + case TARGET_BOARD_ID_J98AP: + case TARGET_BOARD_ID_J99AP: + if ((board_rev & 0xf) <= J99_EVT_BOARD_REV && chipid_get_fuse_revision() >= MINIMUM_BINNED_GPU_P6_REVISION) + use_gpu_650MHz_binned = true; + break; +#endif + default: + break; + } + return use_gpu_650MHz_binned; +} + +bool pmgr_check_gpu_use600MHz_unbinned(uint32_t board_id, uint32_t board_rev) +{ + bool use_gpu_600MHz_unbinned = false; +#if SUB_TARGET_J96 || SUB_TARGET_J97 + use_gpu_600MHz_unbinned = true; +#endif + return use_gpu_600MHz_unbinned; +} + +bool pmgr_check_gpu_use600MHz_binned(uint32_t board_id, uint32_t board_rev) +{ + bool use_gpu_600MHz_binned = false; +#if SUB_TARGET_J96 || SUB_TARGET_J97 + use_gpu_600MHz_binned = false; +#endif + return use_gpu_600MHz_binned; +} + +static bool pmgr_check_use1512MHz(uint32_t board_id, uint32_t board_rev) +{ + bool use1512MHz = false; + switch (board_id & 0xf) { +#if SUB_TARGET_J98 || SUB_TARGET_J99 + case TARGET_BOARD_ID_J98DEV: + case TARGET_BOARD_ID_J99DEV: + break; + case TARGET_BOARD_ID_J98AP: + case TARGET_BOARD_ID_J99AP: + if ((board_rev & 0xf) <= J99_PROTO1_BOARD_REV_LOCAL) + use1512MHz = true; + break; +#endif +#if SUB_TARGET_J81 || SUB_TARGET_J82 + case TARGET_BOARD_ID_J81DEV: + case TARGET_BOARD_ID_J82DEV: + if ((board_rev & 0xf) == 0x3) + use1512MHz = true; + case TARGET_BOARD_ID_J81AP: + case TARGET_BOARD_ID_J82AP: + if ((board_rev & 0xf) >= 0x4) + use1512MHz = true; + break; +#endif +#if SUB_TARGET_J96 || SUB_TARGET_J97 + case TARGET_BOARD_ID_J96AP: + case TARGET_BOARD_ID_J97AP: + case TARGET_BOARD_ID_J96DEV: + case TARGET_BOARD_ID_J97DEV: + use1512MHz = true; + break; +#endif + default: + panic("Unknown board id %d\n", board_id); + } + return use1512MHz; +} + +static void pmgr_get_dvfm_data_from_vmax(struct dvfm_data *dvfm, uint32_t dvfm_state_vmax) +{ + dvfm->dvfm_state_vmax = dvfm_state_vmax; + dvfm->voltage_states1_count = dvfm_state_vmax - kDVFM_STATE_V0 + 1; + dvfm->voltage_states1_size = dvfm->voltage_states1_count * 2; + dvfm->dvfm_state_iboot_cnt = dvfm_state_vmax + 1; + dvfm->dvfm_state_vnom = kDVFM_STATE_V2; + dvfm->dvfm_state_vboost = dvfm_state_vmax; +} + +static void pmgr_get_dvfm_data(struct dvfm_data *dvfm) +{ + uint32_t dvfm_state_vmax; + // DVFM table is filled with kDVFM_STATE_IBOOT copy after the last valid state. Use it to find the last valid state. + for (dvfm_state_vmax = CCC_DVFM_STATE_COUNT - 1; dvfm_state_vmax > kDVFM_STATE_IBOOT; dvfm_state_vmax--) + if (rCCC_DVFM_ST(dvfm_state_vmax) != rCCC_DVFM_ST(kDVFM_STATE_IBOOT)) + break; + pmgr_get_dvfm_data_from_vmax(dvfm, dvfm_state_vmax); +} + +void pmgr_update_gfx_states(uint32_t board_id, uint32_t board_rev) +{ + uint32_t states = sizeof(gfx_states) / sizeof(gfx_states[0]); + uint32_t cnt, invalid_cnt = 0; + + bool gpu_use650MHz = pmgr_check_gpu_use650MHz_binned(board_id, board_rev) || + pmgr_check_gpu_use650MHz_unbinned(board_id, board_rev); + bool gpu_use600MHz = pmgr_check_gpu_use600MHz_binned(board_id, board_rev) || + pmgr_check_gpu_use600MHz_unbinned(board_id, board_rev); + + // Default 365MHz 450MHz 500MHz 550MHz + bool states_enable[] = {true, true, true, true, true, false, false, true, true, true, true, false, false}; + if (gpu_use650MHz) { + // 365MHz 450MHz 550MHz 650MHz + states_enable[CHIPID_GPU_VOLTAGE_V2] = false; // 500MHz + states_enable[CHIPID_GPU_VOLTAGE_V2_DIDT] = false; + states_enable[CHIPID_GPU_VOLTAGE_V5] = true; // 650MHz + states_enable[CHIPID_GPU_VOLTAGE_V5_DIDT] = true; + } else if (gpu_use600MHz) { + // 365MHz 450MHz 550MHz 600MHz + states_enable[CHIPID_GPU_VOLTAGE_V2] = false; // 500MHz + states_enable[CHIPID_GPU_VOLTAGE_V2_DIDT] = false; + states_enable[CHIPID_GPU_VOLTAGE_V4] = true; // 600MHz + states_enable[CHIPID_GPU_VOLTAGE_V4_DIDT] = true; + } else if ((chipid_get_fuse_revision() < 0x1) && (chipid_get_chip_id() == 0x7001)) { // Capri A0 + // 365MHz 450MHz 500MMHz + states_enable[CHIPID_GPU_VOLTAGE_V3] = false; // 550MHz + states_enable[CHIPID_GPU_VOLTAGE_V3_DIDT] = false; + } + + for (cnt = 1; cnt < states; cnt++) { + // The states are in this order: off,V0,V1,..,Vi,V0_DIDT,V1_DIDT,...,Vi_DIDT + if (!states_enable[cnt]) + invalid_cnt++; + else + gfx_states[cnt - invalid_cnt] = gfx_states[cnt]; + } + + for (cnt = 1; cnt < states; cnt++) { + // Invalidate the GFX states that are now duplicates from the shifting by setting them to 0 + if (cnt >= states - invalid_cnt) + gfx_states[cnt] = gfx_states[CHIPID_GPU_VOLTAGE_OFF]; + + set_gfx_perf_state(cnt, &gfx_states[cnt]); + } + + dprintf(DEBUG_CRITICAL, "board_id=0x%x board_rev=0x%x gpu_use650MHz_binned=%d gpu_use650MHz_unbinned=%d gpu_use600MHz_binned=%d gpu_use600MHz_unbinned=%d\n", + board_id, board_rev, (int)pmgr_check_gpu_use650MHz_binned(board_id, board_rev), + (int)pmgr_check_gpu_use650MHz_unbinned(board_id, board_rev), + (int)pmgr_check_gpu_use600MHz_binned(board_id, board_rev), + (int)pmgr_check_gpu_use600MHz_unbinned(board_id, board_rev)); +} + +/* + * Set-up DVFM table with new states. This will override all previous states. + */ +void pmgr_update_dvfm(uint32_t board_id, uint32_t board_rev) +{ + bool use1608MHz_binned = false; + bool use1608MHz_unbinned = false; + bool use1512MHz = pmgr_check_use1512MHz(board_id, board_rev); + + u_int32_t cpu_vid; +#if SUB_PLATFORM_T7001 + u_int32_t cpu_sram_vid; + u_int64_t cpu_dvfm_sram = 0; +#endif + u_int32_t dvfm_state; + struct chipid_vol_adj adj; + uint64_t vol_adj_temp = 0; + +#if SUB_TARGET_J98 || SUB_TARGET_J99 + use1608MHz_binned = pmgr_check_use1608MHz_binned(board_id, board_rev); + use1608MHz_unbinned = pmgr_check_use1608MHz_unbinned(board_id, board_rev); +#endif + + dprintf(DEBUG_CRITICAL, "board_id=0x%x board_rev=0x%x fuse_rev=%d use1512MHz=%d use1608MHz_binned=%d use1608MHz_unbinned=%d \n", + board_id, board_rev, chipid_get_fuse_revision(), (int)use1512MHz, (int)use1608MHz_binned, (int)use1608MHz_unbinned); + + if (use1608MHz_unbinned) + dvfm_state = kDVFM_STATE_V6_UNBINNED; + else if (use1608MHz_binned) + dvfm_state = kDVFM_STATE_V6; + else if (use1512MHz) + return; + else { + // kDVFM_STATE_V5 and kDVFM_STATE_V0 are the same, so pmgr_get_dvfm_data() will detect that the max state is kDVFM_STATE_V4 + rCCC_DVFM_ST(kDVFM_STATE_V5) = rCCC_DVFM_ST(kDVFM_STATE_V0); + return; + } + + cpu_vid = chipid_get_cpu_voltage(dvfm_state); + platform_convert_voltages(BUCK_CPU, 1, &cpu_vid); + + chipid_get_vol_adj(CHIPID_VOL_ADJ_CPU, dvfm_state, &adj); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ0(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[0])); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ1(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[1])); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ2(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[2])); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ3(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[3])); + rCCC_DVFM_ST(kDVFM_STATE_V5) = ccc_dvfm_states[dvfm_state] | CCC_DVFM_ST_SAFEVOL(cpu_vid) | vol_adj_temp; + +#if SUB_PLATFORM_T7001 + cpu_sram_vid = chipid_get_ram_voltage(dvfm_state); + platform_convert_voltages(BUCK_RAM, 1, &cpu_sram_vid); + cpu_dvfm_sram = CCC_DVFM_SRAM_STATE(cpu_dvfm_sram, kDVFM_STATE_V5, cpu_sram_vid); + + rCCC_DVFM_SRAM &= ~CCC_DVFM_SRAM_STATE(0ULL, kDVFM_STATE_V5, ~0ULL); + rCCC_DVFM_SRAM |= cpu_dvfm_sram; +#endif +} +#endif +#endif + +static uint64_t pmgr_get_offset_from_diff_uV(uint32_t buck, uint32_t uV) +{ +// power API is only able to convert absolute value +// So, we need to convert abolute value and do the diff. + uint32_t mV_prev = 0; + uint32_t mV; + uint32_t offset; + uint32_t zero_mV; + if (platform_get_dwi_to_mv(buck, 1) <= 0) // even if offset 0 is 0mV, offset 1 must be >0 mV. + return 0; // This platform doesn't have HW PMU or emulation + + zero_mV = platform_get_dwi_to_mv(buck, 0); + for (offset = 0; offset < 0xff; offset++) { + mV = platform_get_dwi_to_mv(buck, offset); + if ((mV - zero_mV) * 1000 >= uV) + { + // We look for the closest offset. + // It can be offset or offset -1 + if ((uV - (mV_prev - zero_mV) * 1000) < ((mV - zero_mV) * 1000 - uV)) + return offset - 1; + else + return offset; + } + mV_prev = mV; + } + panic("No offset for %d uV on buck %d\n", uV, buck); + return 0; +} + +/* + * clocks_set_default - called by SecureROM, LLB, iBSS main via + * platform_init_setup_clocks, so the current state of the chip is + * either POR, or whatever 'quiesce' did when leaving SecureROM. + */ + +int clocks_set_default(void) +{ + uint32_t cnt; +#if APPLICATION_IBOOT + u_int32_t cpu_vid[kDVFM_STATE_IBOOT_CNT]; +#if SUB_PLATFORM_T7000 + u_int32_t soc_vid[kSOC_PERF_STATE_IBOOT_CNT]; +#elif SUB_PLATFORM_T7001 + u_int32_t gpu_sram_vid[kPMGR_GFX_STATE_MAX]; + u_int32_t cpu_sram_vid[kDVFM_STATE_IBOOT_CNT]; + u_int64_t cpu_dvfm_sram = 0; +#endif + u_int32_t gpu_vid[kPMGR_GFX_STATE_MAX]; +#endif + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + volatile uint32_t *spare_clkcfgs = PMGR_FIRST_SPARE_CLK_CFG; + + // Setup bypass DVFM state + rCCC_DVFM_ST(kDVFM_STATE_BYPASS) = ccc_dvfm_states[kDVFM_STATE_BYPASS]; + + // Begin: Secure ROM PLL calibration sequence changes + { + uint32_t vco_override = rCFG_FUSE9; + + // Shift the override value for the CPU PLL to the LSB position. + vco_override >>= CFG_FUSE9_PLL_CPU_SHIFT; + + // Is the override data for this PLL valid? + if (vco_override & CFG_FUSE9_PLL_VCO_RCTRL_SEL) { + uint32_t reg = rCCC_PLL_CFG1; + reg &= ~(CCC_PLL_CFG1_PLL_VCO_RCTRL_OW_MASK + << CCC_PLL_CFG1_PLL_VCO_RCTRL_OW_SHIFT); + reg |= (vco_override & CFG_FUSE9_PLL_VCO_RCTRL_OW_MASK) + << CCC_PLL_CFG1_PLL_VCO_RCTRL_OW_SHIFT; + reg |= CCC_PLL_CFG1_PLL_VCO_RCTRL_SEL; + rCCC_PLL_CFG1 = reg; + } + } + // End: Secure ROM PLL calibration sequence changes + + // Change all clocks to something safe + clocks_quiesce_internal(); + + // Setup active DVFM and SOC PERF states for the stage of boot. +#if SUB_PLATFORM_T7001 +#if APPLICATION_IBOOT + /* T7001 doesn't have kSOC_PERF_STATE_VMIN */ + pmgr_soc_perf_states[kSOC_PERF_STATE_VMIN] = pmgr_soc_perf_states[kSOC_PERF_STATE_VNOM]; +#endif +#endif +#if APPLICATION_SECUREROM + rCCC_DVFM_ST(kDVFM_STATE_SECUREROM) = ccc_dvfm_states[kDVFM_STATE_SECUREROM]; + + rPMGR_SOC_PERF_STATE_ENTRY_A(kSOC_PERF_STATE_SECUREROM) = pmgr_soc_perf_states[kSOC_PERF_STATE_SECUREROM].entry[0]; + rPMGR_SOC_PERF_STATE_ENTRY_B(kSOC_PERF_STATE_SECUREROM) = pmgr_soc_perf_states[kSOC_PERF_STATE_SECUREROM].entry[1]; + rPMGR_SOC_PERF_STATE_ENTRY_C(kSOC_PERF_STATE_SECUREROM) = pmgr_soc_perf_states[kSOC_PERF_STATE_SECUREROM].entry[2]; + rPMGR_SOC_PERF_STATE_ENTRY_D(kSOC_PERF_STATE_SECUREROM) = 0; +#endif + +#if APPLICATION_IBOOT +#ifndef BUCK_CPU +#error BUCK_CPU not defined for this platform +#endif + // Get the binned voltages and update the CCC DVFM state registers. + platform_get_cpu_voltages(kDVFM_STATE_IBOOT_CNT, cpu_vid); + platform_convert_voltages(BUCK_CPU, kDVFM_STATE_IBOOT_CNT, cpu_vid); +#if SUB_PLATFORM_T7001 +#ifndef BUCK_RAM +#error BUCK_RAM not defined for this platform +#endif + platform_get_ram_voltages(kDVFM_STATE_IBOOT_CNT, cpu_sram_vid); + platform_convert_voltages(BUCK_RAM, kDVFM_STATE_IBOOT_CNT, cpu_sram_vid); +#endif + + for (cnt = kDVFM_STATE_IBOOT; cnt < kDVFM_STATE_IBOOT_CNT; cnt++) { + struct chipid_vol_adj adj; + uint64_t vol_adj_temp = 0; + chipid_get_vol_adj(CHIPID_VOL_ADJ_CPU, cnt, &adj); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ0(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[0])); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ1(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[1])); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ2(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[2])); + vol_adj_temp |= CCC_DVFM_ST_VOLADJ3(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[3])); + rCCC_DVFM_ST(cnt) = ccc_dvfm_states[cnt] | CCC_DVFM_ST_SAFEVOL(cpu_vid[cnt]) | vol_adj_temp; + } +#if SUB_PLATFORM_T7001 + cpu_dvfm_sram = CCC_DVFM_SRAM_STATE(cpu_dvfm_sram, kDVFM_STATE_BYPASS, cpu_sram_vid[kDVFM_STATE_BYPASS]); + for (cnt = kDVFM_STATE_IBOOT; cnt < kDVFM_STATE_IBOOT_CNT; cnt++) { + cpu_dvfm_sram = CCC_DVFM_SRAM_STATE(cpu_dvfm_sram, cnt, cpu_sram_vid[cnt]); + } +#endif + // APSC sleep state will use the bypass state with V0. + + rCCC_DVFM_ST(kDVFM_STATE_BYPASS) = ccc_dvfm_states[kDVFM_STATE_BYPASS] | CCC_DVFM_ST_SAFEVOL(cpu_vid[kDVFM_STATE_V0]); + + // To prevent crashes/hangs during update install due to + // mismatch of CCC clock config info between an old LLB and a new EDT+OS + // we can populate the unused entries of the DVFM table with that of + // Vmin, Fmin. That way we will always have a workable entry in the DVFM + // table. + // Assumptions: + // There is always a valid state for iBoot and we will use that to populate the + // empty table entries. + + for (cnt = kDVFM_STATE_IBOOT_CNT; cnt < CCC_DVFM_STATE_COUNT; cnt++) { + rCCC_DVFM_ST(cnt) = rCCC_DVFM_ST(kDVFM_STATE_IBOOT); + } +#if SUB_PLATFORM_T7001 + for (cnt = kDVFM_STATE_IBOOT_CNT; cnt < CCC_DVFM_STATE_COUNT; cnt++) { + cpu_dvfm_sram = CCC_DVFM_SRAM_STATE(cpu_dvfm_sram, cnt, cpu_sram_vid[kDVFM_STATE_IBOOT]); + } + + rCCC_DVFM_SRAM = cpu_dvfm_sram; +#endif + + // Configure temperature ranges and measurement offsets for DVFM/DVTM + rCCC_DVFM_CFG = CCC_DVFM_CFG_TEMPTHRESH0(0x8) | CCC_DVFM_CFG_TEMPTHRESH1(0x21) | CCC_DVFM_CFG_TEMPOFFSET0(0) | CCC_DVFM_CFG_TEMPOFFSET1(0); + rCCC_DVFM_CFG1 = CCC_DVFM_CFG1_TEMPTHRESH2(0x3A) | CCC_DVFM_CFG1_TEMPOFFSET2(0); +#endif + +#if APPLICATION_IBOOT + for (cnt = kSOC_PERF_STATE_IBOOT; cnt < kSOC_PERF_STATE_IBOOT_CNT; cnt++) { + uint32_t vol_adj_temp = 0; +#if SUB_PLATFORM_T7000 + struct chipid_vol_adj adj; + chipid_get_vol_adj(CHIPID_VOL_ADJ_SOC, cnt, &adj); + vol_adj_temp |= PMGR_SOC_PERF_STATE_VOL_ADJ0(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[0])); + vol_adj_temp |= PMGR_SOC_PERF_STATE_VOL_ADJ1(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[1])); + vol_adj_temp |= PMGR_SOC_PERF_STATE_VOL_ADJ2(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[2])); + vol_adj_temp |= PMGR_SOC_PERF_STATE_VOL_ADJ3(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj.region_uV[3])); +#endif + + rPMGR_SOC_PERF_STATE_ENTRY_A(cnt) = pmgr_soc_perf_states[cnt].entry[0]; + rPMGR_SOC_PERF_STATE_ENTRY_B(cnt) = pmgr_soc_perf_states[cnt].entry[1]; + rPMGR_SOC_PERF_STATE_ENTRY_C(cnt) = pmgr_soc_perf_states[cnt].entry[2]; + rPMGR_SOC_PERF_STATE_ENTRY_D(cnt) = vol_adj_temp; + } + + for (cnt = kSOC_PERF_STATE_IBOOT_CNT; cnt < PMGR_SOC_PERF_STATE_COUNT; cnt++) { + rPMGR_SOC_PERF_STATE_ENTRY_A(cnt) = rPMGR_SOC_PERF_STATE_ENTRY_A(kSOC_PERF_STATE_VMIN); + rPMGR_SOC_PERF_STATE_ENTRY_B(cnt) = rPMGR_SOC_PERF_STATE_ENTRY_B(kSOC_PERF_STATE_VMIN); + rPMGR_SOC_PERF_STATE_ENTRY_C(cnt) = rPMGR_SOC_PERF_STATE_ENTRY_C(kSOC_PERF_STATE_VMIN); + rPMGR_SOC_PERF_STATE_ENTRY_D(cnt) = rPMGR_SOC_PERF_STATE_ENTRY_D(kSOC_PERF_STATE_VMIN); + } + +#if SUB_PLATFORM_T7000 +#ifndef BUCK_SOC +#error BUCK_SOC not defined for this platform +#endif + platform_get_soc_voltages(kSOC_PERF_STATE_IBOOT_CNT, soc_vid); + platform_convert_voltages(BUCK_SOC, kSOC_PERF_STATE_IBOOT_CNT, soc_vid); + + for (cnt = kSOC_PERF_STATE_IBOOT; cnt < kSOC_PERF_STATE_IBOOT_CNT; cnt++) { + rPMGR_SOC_PERF_STATE_ENTRY_C(cnt) = soc_vid[cnt]; + } + + for (cnt = kSOC_PERF_STATE_IBOOT_CNT; cnt < PMGR_SOC_PERF_STATE_COUNT; cnt++) { + rPMGR_SOC_PERF_STATE_ENTRY_C(cnt) = soc_vid[kSOC_PERF_STATE_VMIN]; + } +#endif +#endif + +#if APPLICATION_IBOOT +#if WITH_HW_DWI + extern int dwi_init(void); + dwi_init(); +#endif +#endif + + set_apsc_ccc_state(active_state); // CCC clock set for this stage of boot. + +#if APPLICATION_IBOOT +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + + platform_get_gpu_voltages(sizeof(gfx_states) / sizeof(gfx_states[0]), gpu_vid); +#if SUB_PLATFORM_T7000 + // Workaround T7000 start + for (cnt = 2; cnt < sizeof(gfx_states) / sizeof(gfx_states[0]); cnt++) { + if (gpu_vid[cnt] < gpu_vid[1]) { + gpu_vid[cnt] = gpu_vid[1]; + } + } + // Workaround T7000 end +#endif + platform_convert_voltages(BUCK_GPU, sizeof(gfx_states) / sizeof(gfx_states[0]), gpu_vid); + + for (cnt = 0; cnt < sizeof(gfx_states) / sizeof(gfx_states[0]); cnt++) { + if (cnt == 0) + gfx_states[cnt].dwi_val = 0; + else + gfx_states[cnt].dwi_val = gpu_vid[cnt]; + } +#if SUB_PLATFORM_T7001 +#ifndef BUCK_RAM +#error BUCK_RAM not defined for this platform +#endif + platform_get_gpu_ram_voltages(sizeof(gfx_states) / sizeof(gfx_states[0]), gpu_sram_vid); + platform_convert_voltages(BUCK_RAM, sizeof(gfx_states) / sizeof(gfx_states[0]), gpu_sram_vid); + + for (cnt = 0; cnt < sizeof(gfx_states) / sizeof(gfx_states[0]); cnt++) { + if (cnt == 0) + gfx_states[cnt].dwi_sram_val = 0; + else + gfx_states[cnt].dwi_sram_val = gpu_sram_vid[cnt]; + } +#endif + for (cnt = 0; cnt < sizeof(gfx_states) / sizeof(gfx_states[0]); cnt++) { + set_gfx_perf_state(cnt, &gfx_states[cnt]); + } + // Complete the PERF table with GPU_VOLTAGE_OFF value + for (cnt = sizeof(gfx_states) / sizeof(gfx_states[0]); cnt < kPMGR_GFX_STATE_MAX; cnt++) { + set_gfx_perf_state(cnt, &gfx_states[CHIPID_GPU_VOLTAGE_OFF]); + } + // As per GFX Performance state software Sequence + // Clear the bypass bit in PLL5 + while (rPMGR_PLL_CTL(5) & PMGR_PLL_PENDING); + rPMGR_PLL_EXT_BYPASS_CTL(5) &= ~PMGR_PLL_EXT_BYPASS; + // PLL5 relock mode is set to 1 to switch to bypass mode while re-locking. + rPMGR_PLL_CFG(5) |= (PMGR_PLL_RELOCK_MODE_BYPASS << PMGR_PLL_RELOCK_MODE_SHIFT); + // Enable performance state table to control PLL5 + rPMGR_GFX_PERF_STATE_CTL |= (1 << 31); + + // The initial SRAM, SOC, CPU voltages are set by IIC writes to the PMU (in the pmu driver). +#endif + +#ifdef PLL0_T +#if WITH_HW_AGC_MIPI + rPMGR_AGILE_CLK_CTL &= ~(1 << 29); +#endif + set_pll(0, PLL0_P, PLL0_M, PLL0_S, 0); +#endif + +#ifdef PLL1_T + set_pll(1, PLL1_P, PLL1_M, PLL1_S, 0); +#endif + +#ifdef PLL2_T + set_pll(2, PLL2_P, PLL2_M, PLL2_S, 0); +#endif + +#ifdef PLL3_T + set_pll(3, PLL3_P, PLL3_M, PLL3_S, 0); +#if SUB_PLATFORM_T7001 + uint32_t pll_vreg_adj = (rCFG_FUSE8 >> CFG_FUSE8_PCIE_REF_PLL_VREG_ADJ_SHIFT) & CFG_FUSE8_PCIE_REF_PLL_VREG_ADJ_MASK; + if (pll_vreg_adj == 5) { + uint32_t reg = rPMGR_PLL_ANA_PARAMS0(3); + reg &= ~(PMGR_PLL_ANA_PARAMS0_VREG_ADJ_MASK << PMGR_PLL_ANA_PARAMS0_VREG_ADJ_SHIFT); + reg |= pll_vreg_adj << PMGR_PLL_ANA_PARAMS0_VREG_ADJ_SHIFT; + rPMGR_PLL_ANA_PARAMS0(3) = reg; + } +#endif +#endif + +#ifdef PLL4_T + set_pll(4, PLL4_P, PLL4_M, PLL4_S, PLL4_VCO_ENABLED); +#endif + +#ifdef PLL5_T + set_pll(5, PLL5_P, PLL5_M, PLL5_S, 0); +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Turn on NCO clocks before enabling MCA clocks. + set_nco_clocks(); +#endif + + rPMGR_SOC_PERF_STATE_CTL = SOC_PERF_STATE_ACTIVE; + while (rPMGR_SOC_PERF_STATE_CTL & PMGR_SOC_PERF_STATE_CTL_PENDING_MASK); + + // Set all spare clock divs to their active values + for (cnt = 0; cnt < PMGR_SPARE_CLK_CFG_COUNT; cnt++) { + spare_clkcfgs[cnt] = spare_divs_active[cnt]; + while ((spare_clkcfgs[cnt] & PMGR_CLK_CFG_PENDING) != 0); + } + + // Set all but the spare clock divs to their active values + for (cnt = 0; cnt < PMGR_CLK_CFG_COUNT; cnt++) { + clkcfgs[cnt] = clk_divs_active[cnt]; + while ((clkcfgs[cnt] & PMGR_CLK_CFG_PENDING) != 0); + } + + power_on_sep(); + + clocks_get_frequencies(); + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + apply_pmgr_tunables(); + apply_ccc_tunables(); +#endif + + return 0; +} + +static uint32_t get_apsc_ccc_state(void) +{ + return ((rCCC_DVFM_CFG_SEL >> 3) & 0x7); +} + +static void set_apsc_ccc_state(uint32_t target_state) +{ + // DWI clock must be enabled for any state change that has voltage control enabled. + rCCC_APSC_SCR = CCC_APSC_MANUAL_CHANGE(target_state); + while ((rCCC_APSC_SCR & CCC_APSC_PENDING) != 0); + + return; +} + +/* + * set_pll - called by SecureROM, LLB, iBSS with PLLs in default reset state. + * See restore_clock_config_state(). PLL1 is not enabled on entry to LLB or + * or iBSS, since not configured by SecureROM. + */ +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s, bool vco_output) +{ + if (pll >= PMGR_PLL_COUNT) + return; + + // Secure ROM PLL calibration sequence changes + { + uint32_t vco_override = rCFG_FUSE9; + + // Each PMGR PLL's override values occupy contiguous 4-bit fields. + // Shift the override value for this PLL to the LSB position. + vco_override >>= (pll * 4); + + // Is the override data for this PLL valid? + if (vco_override & CFG_FUSE9_PLL_VCO_RCTRL_SEL) { + uint32_t reg = rPMGR_PLL_ANA_PARAMS1(pll); + reg &= ~(PMGR_PLL_ANA_PARAMS1_VCO_RCTRL_OW_MASK + << PMGR_PLL_ANA_PARAMS1_VCO_RCTRL_OW_SHIFT); + reg |= (vco_override & CFG_FUSE9_PLL_VCO_RCTRL_OW_MASK) + << PMGR_PLL_ANA_PARAMS1_VCO_RCTRL_OW_SHIFT; + reg |= PMGR_PLL_ANA_PARAMS1_VCO_RCTRL_SEL; + rPMGR_PLL_ANA_PARAMS1(pll) = reg; + } + } + + if (vco_output) + rPMGR_PLL_CFG(pll) |= PMGR_PLL_VCO_OUT_SEL; + + if (p == 0) // not a PLL setting + return; + + rPMGR_PLL_CTL(pll) = (PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s) | + PMGR_PLL_LOAD); + while (rPMGR_PLL_CTL(pll) & PMGR_PLL_PENDING); + + rPMGR_PLL_EXT_BYPASS_CTL(pll) &= ~PMGR_PLL_EXT_BYPASS; + while ((rPMGR_PLL_EXT_BYPASS_CTL(pll) & PMGR_PLL_BYP_ENABLED) != 0); + + rPMGR_PLL_CTL(pll) |= PMGR_PLL_ENABLE; + while (rPMGR_PLL_CTL(pll) & PMGR_PLL_PENDING); +} + +static uint32_t is_pll_running(int32_t pll) +{ + if (pll >= PMGR_PLL_COUNT) + return 0; + + if ((rPMGR_PLL_CTL(pll) & PMGR_PLL_ENABLE) == 0) + return 0; + else + return 1; +} + +/* + * set_running_pll - program PLL that is already running. + */ +static void set_running_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s) +{ + if (pll >= PMGR_PLL_COUNT) + return; + + if (!is_pll_running(pll)) + return; + + rPMGR_PLL_CTL(pll) = (PMGR_PLL_ENABLE | PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s) | PMGR_PLL_LOAD); + while (rPMGR_PLL_CTL(pll) & PMGR_PLL_PENDING); +} + +static uint32_t get_pll_cpu(void) +{ + uint32_t freq; + uint32_t pllctl; + + pllctl = rCCC_PWRCTRL_PLL_SCR1; + + // Fcpu <= ((OSC * M) / P / S+1) + freq = OSC_FREQ; + freq *= (pllctl >> CCC_PLL_M_SHIFT) & CCC_PLL_M_MASK; + freq /= (pllctl >> CCC_PLL_P_SHIFT) & CCC_PLL_P_MASK; + freq /= 1 + ((pllctl >> CCC_PLL_S_SHIFT) & CCC_PLL_S_MASK); + + return freq; +} + +static uint32_t get_pll(int32_t pll) +{ + uint32_t pllctl; + uint32_t pllbyp; + uint64_t freq = 0; + + pllctl = rPMGR_PLL_CTL(pll); + pllbyp = rPMGR_PLL_EXT_BYPASS_CTL(pll); + + // If PLL is not enabled, check for External Bypass + if ((pllctl & PMGR_PLL_ENABLE) == 0) { + if ((pllbyp & PMGR_PLL_EXT_BYPASS) == 0) + return 0; + else + return OSC_FREQ; + } + + freq = OSC_FREQ; + + freq *= ((pllctl >> PMGR_PLL_M_SHIFT) & PMGR_PLL_M_MASK); + + if ((rPMGR_PLL_CFG(pll) & PMGR_PLL_VCO_OUT_SEL) == 0) { + freq /= (1 + ((pllctl >> PMGR_PLL_S_SHIFT) & PMGR_PLL_S_MASK)); + } else { + freq *= 2; + } + + freq /= ((pllctl >> PMGR_PLL_P_SHIFT) & PMGR_PLL_P_MASK); + +#if DEBUG_BUILD + if (freq > 0xFFFFFFFF) + panic("Frequency value does not fit in uint32_t"); +#endif + + return (uint32_t)freq; +} + + +static uint32_t get_spare(int32_t spare) +{ + uint32_t reg_val, src_idx, src_clk, src_factor, div; + volatile uint32_t *spare_clkcfg = clk_configs[PMGR_CLK_S0 + spare].clock_reg; + + reg_val = *spare_clkcfg; + + div = reg_val & 0x3F; + + if (((reg_val & PMGR_CLK_CFG_ENABLE) == 0) || div == 0) + return 0; + + src_idx = (reg_val >> PMGR_CLK_CFG_SRC_SEL_SHIFT) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].src_clk; + src_factor = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].factor; + + return (clks[src_clk] / src_factor) / div; +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_CPU] = 5000000; + clks[PMGR_CLK_MCU] = 10000000; + clks[PMGR_CLK_MCU_FIXED] = 10000000; + clks[PMGR_CLK_USB] = 12000000; + +#elif SUB_TARGET_TYPHONIC + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + +#else + uint32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) + clks[PMGR_CLK_PLL0 + cnt] = get_pll(cnt); + + // Use get_spare() to establish the frequencies for spare clocks (unconfigured will be skipped) + for (cnt = 0; cnt < PMGR_SPARE_CLK_CFG_COUNT; cnt++) + clks[PMGR_CLK_S0 + cnt] = get_spare(cnt); + + clks[PMGR_CLK_CPU] = get_pll_cpu(); + + clocks_get_frequencies_range(PMGR_CLK_MCU_FIXED, PMGR_CLK_ANC_LINK); +#endif +} + +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk) +{ + volatile uint32_t *reg; + uint32_t cnt, val, src_idx, src_clk, src_factor; + + if (start_clk < PMGR_CLK_SOURCE_FIRST || end_clk > PMGR_CLK_SOURCE_LAST) + return; + + for (cnt = start_clk; cnt <= end_clk; cnt++) { + reg = clk_configs[cnt].clock_reg; + val = *reg; + + if ((val & PMGR_CLK_CFG_ENABLE) == 0) { + clks[cnt] = 0; + continue; + } + + src_idx = (val >> PMGR_CLK_CFG_SRC_SEL_SHIFT) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[cnt].sources[src_idx].src_clk; + src_factor = clk_configs[cnt].sources[src_idx].factor; + clks[cnt] = clks[src_clk] / src_factor; + } +} + +void dump_clock_frequencies() +{ + uint32_t i; + + for (i = 0; i < PMGR_CLK_COUNT; i++) { + dprintf(DEBUG_CRITICAL, "clk[%d] -> %u\n", i, clks[i]); + } +} + +static void clock_update_range(uint32_t first, uint32_t last, const uint32_t clkdata) +{ + volatile uint32_t *clkcfgs = PMGR_FIRST_CLK_CFG; + uint32_t reg; + + reg = first; + while (reg <= last) { + clkcfgs[reg] = clkdata; + while (clkcfgs[reg] & PMGR_CLK_CFG_PENDING); + reg++; + } +} + +static void clock_update_frequency(uint32_t clk, uint32_t freq) +{ +#define ROUND_10E4(_x) ((((_x) + 5000) / 10000) * 10000) + + uint32_t src_idx, src_clk, src_factor, reg; + bool freq_supported = false; + volatile uint32_t *clkcfg = clk_configs[clk].clock_reg; + + if (freq == 0) + return; + + for (src_idx = 0; src_idx < CLOCK_SOURCES_MAX && clk_configs[clk].sources[src_idx].factor != 0; src_idx++) + { + src_clk = clk_configs[clk].sources[src_idx].src_clk; + src_factor = clk_configs[clk].sources[src_idx].factor; + + if (ROUND_10E4(clks[src_clk] / src_factor) == freq) { + freq_supported = true; + break; + } + } + + if (!freq_supported) { + // Frequency not supported by CLK_CFG register, try spare + uint32_t spare, spare_src_idx, spare_src_freq, spare_div; + const struct clock_source *spare_clk_src; + volatile uint32_t *spare_clkcfgs = PMGR_FIRST_SPARE_CLK_CFG; + + switch (clk) + { + case PMGR_CLK_VID0: + // Use spare 0 with PLL4 div 3 as source clock + spare = 0; + spare_src_idx = 0; + + // Set VID0 clock source to spare 0 + src_idx = 1; + + break; + + default: + return; + } + + spare_clk_src = &clk_configs[PMGR_CLK_S0 + spare].sources[spare_src_idx]; + spare_src_freq = clks[spare_clk_src->src_clk] / spare_clk_src->factor; + + for (spare_div = 1; spare_div < 16; spare_div++) { + if (ROUND_10E4(spare_src_freq / spare_div) == freq) { + freq_supported = true; + break; + } +} + + if (freq_supported) { + // Configure spare + spare_clkcfgs[spare] = PMGR_CLK_CFG_ENABLE | (spare_src_idx << PMGR_CLK_CFG_SRC_SEL_SHIFT) | PMGR_CLK_CFG_DIVISOR(spare_div); + while ((spare_clkcfgs[spare] & PMGR_CLK_CFG_PENDING) != 0); + + clks[PMGR_CLK_S0 + spare] = get_spare(spare); + } + } + + if (freq_supported) { + // Configure clock + reg = *clkcfg; + reg &= ~(PMGR_CLK_CFG_SRC_SEL_MASK << PMGR_CLK_CFG_SRC_SEL_SHIFT); + reg |= (src_idx & PMGR_CLK_CFG_SRC_SEL_MASK) << PMGR_CLK_CFG_SRC_SEL_SHIFT; + *clkcfg = reg; + while (*clkcfg & PMGR_CLK_CFG_PENDING); + } +} + +static void restore_clock_config_state(void) +{ + uint32_t cnt; + uint32_t soc_perf_state; + + // 3. Write reset value to ACG, CLK_DIVIDER_ACG_CFG + rPMGR_MISC_ACG = 0; + rPMGR_CLK_DIVIDER_ACG_CFG = 0; + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // 4. Write the reset value to all MCAx_CLK_CFG registers + clock_update_range(PMGR_CLK_NUM(MCA0_M), PMGR_CLK_NUM(MCA4_M), 0x80100000); + + // 5. Put the NCOs in reset state + for (cnt = 0; cnt < PMGR_NUM_NCO; cnt++) + { + rPMGR_NCO_CLK_CFG(cnt) = 0; + while (rPMGR_NCO_CLK_CFG(cnt) & PMGR_NCO_CLK_CFG_PENDING); + } +#endif + + // 6. Write reset value for all mux clock configs (excluding spares) + clock_update_range(PMGR_CLK_NUM(MCU_FIXED), PMGR_CLK_NUM(ANC_LINK), 0x80100000); + + soc_perf_state = (rPMGR_SOC_PERF_STATE_CTL >> PMGR_SOC_PERF_STATE_CTL_CURRENT_SELECT_SHIFT) & + PMGR_SOC_PERF_STATE_CTL_CURRENT_SELECT_MASK; + + if (soc_perf_state != kSOC_PERF_STATE_BYPASS) { + // 7a. Write the desired DRAM clock configuration state into the SOC_PERF_STATE_ENTRY_0A register + rPMGR_SOC_PERF_STATE_ENTRY_A(kSOC_PERF_STATE_BYPASS) = + (pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[0] & ~PMGR_SOC_PERF_STATE_ENTRY_MCU_MASK) | + (rPMGR_SOC_PERF_STATE_ENTRY_A(soc_perf_state) & PMGR_SOC_PERF_STATE_ENTRY_MCU_MASK); + // 7b. Write the reset value to all other fields in ENTRY_0A + rPMGR_SOC_PERF_STATE_ENTRY_B(kSOC_PERF_STATE_BYPASS) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[1]; + rPMGR_SOC_PERF_STATE_ENTRY_C(kSOC_PERF_STATE_BYPASS) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[2]; + rPMGR_SOC_PERF_STATE_ENTRY_D(kSOC_PERF_STATE_BYPASS) = 0; + + // 8. Write the reset value to the SOC_PERF_STATE_CTL register + rPMGR_SOC_PERF_STATE_CTL = kSOC_PERF_STATE_BYPASS; + while (rPMGR_SOC_PERF_STATE_CTL & PMGR_SOC_PERF_STATE_CTL_PENDING_MASK); + + // 9. Write the reset values to the SOC_PERF_STATE entry registers + for (cnt = 0; cnt < PMGR_SOC_PERF_STATE_COUNT; cnt++) { + if (cnt == kSOC_PERF_STATE_BYPASS) + continue; + + rPMGR_SOC_PERF_STATE_ENTRY_A(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_B(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_C(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_D(cnt) = 0; + } + } + + // 11. Write all PLLx_EXT_BYPASS_CTL.EXT_BYPASS to 1 + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 1) + continue; // Mem PLL + + // Make sure the PLL can accept a bypass state change. + while (rPMGR_PLL_CTL(cnt) & PMGR_PLL_PENDING); + + // Switch to bypass mode. + rPMGR_PLL_EXT_BYPASS_CTL(cnt) |= PMGR_PLL_EXT_BYPASS; + while ((rPMGR_PLL_EXT_BYPASS_CTL(cnt) & PMGR_PLL_BYP_ENABLED) == 0); + } + + // 14. Write reset value to all PLLx_CTL + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 1) + continue; // Mem PLL + + rPMGR_PLL_CTL(cnt) = PMGR_PLL_M(1) | PMGR_PLL_P(1); // fb_div = 1, pre_div = 1 + while (rPMGR_PLL_CTL(cnt) & PMGR_PLL_PENDING); + } + + // 15. Write reset value to all other PLL registers + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 1) + continue; // Mem PLL + + rPMGR_PLL_CFG(cnt) = PMGR_PLL_OFF_MODE(PMGR_PLL_OFF_MODE_POWER_DOWN) | + PMGR_PLL_FRAC_LOCK_TIME(0x48) | PMGR_PLL_LOCK_TIME(0x348); + } + + // 16. Write reset value to spare and ISP_REF0/1 + clock_update_range(PMGR_CLK_NUM(S0), PMGR_CLK_NUM(ISP_REF1), 0x80000001); + + // 17. Put CPU clock back into its reset default. + set_apsc_ccc_state(kDVFM_STATE_BYPASS); +} + + +static void power_on_sep(void) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + CLK_SEP); + uint32_t val = *reg; + + val &= ~(PMGR_PS_AUTO_PM_EN | PMGR_PS_FORCE_NOACCESS); + *reg = val; + while (((*reg >> 4) & 0xF) != 0xF); // Wait for SEP to turn on. + + return; +} + +static void set_device(uint64_t *devices, uint64_t device) +{ +#if DEBUG_BUILD + if (device >= 128) + panic("Invalid device clock index: %llu", device); +#endif + if (device >= 64) + devices[1] |= (0x1ULL << (device - 64)); + else + devices[0] |= (0x1ULL << device); +} + +static void clocks_quiesce_internal(void) +{ + uint64_t devices[2] = { 0, 0 }; + + // Disable all voltage changes everywhere! + rPMGR_VOLMAN_CTL |= (PMGR_VOLMAN_DISABLE_CPU_VOL_CHANGE | PMGR_VOLMAN_DISABLE_GFX_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_FIXED_VOL_CHANGE | PMGR_VOLMAN_DISABLE_VAR_SOC_VOL_CHANGE); + + // We don't touch CPU0, CPU1, CPM but the following devices need to be on. + set_device(devices, CLK_LIO); + set_device(devices, CLK_IOMUX); + set_device(devices, CLK_AIC); + set_device(devices, CLK_DEBUG); + set_device(devices, CLK_DWI); + set_device(devices, CLK_GPIO); + set_device(devices, CLK_SIO); + set_device(devices, CLK_SIO_P); + set_device(devices, CLK_ANS); + set_device(devices, CLK_MCC); + set_device(devices, CLK_MCU); + set_device(devices, CLK_AMP); + set_device(devices, CLK_USB); + set_device(devices, CLK_USBCTLREG); + set_device(devices, CLK_USB_OTG); + set_device(devices, CLK_SMX); + set_device(devices, CLK_SF); + set_device(devices, CLK_CP); + set_device(devices, CLK_PCIE_AUX); + + // Turn on/off critical device clocks + clocks_set_gates(devices); + + // Disable performance state table to control PLL5 + rPMGR_GFX_PERF_STATE_CTL = 0; + + restore_clock_config_state(); +} + +void clocks_quiesce(void) +{ + clocks_quiesce_internal(); +} + +uint32_t clocks_set_performance(uint32_t performance_level) +{ + uint32_t old_perf_level = perf_level; + uint32_t ccc_state = get_apsc_ccc_state(); + + if (ccc_state != active_state) + set_apsc_ccc_state(active_state); + +#if APPLICATION_IBOOT + if (performance_level == kPerformanceMemoryLow || performance_level == kPerformanceMemoryFull) { + + rPMGR_SOC_PERF_STATE_CTL = (performance_level == kPerformanceMemoryLow) ? kSOC_PERF_STATE_IBOOT_MEM_LOW_PERF : kSOC_PERF_STATE_IBOOT_MEM_FULL_PERF; + // Wait for Pending bits to clear. + while (rPMGR_SOC_PERF_STATE_CTL & PMGR_SOC_PERF_STATE_CTL_PENDING_MASK); + + perf_level = performance_level; + + clocks_get_frequencies_range(PMGR_CLK_MCU_FIXED, PMGR_CLK_MCU); + } +#endif + // At this point we should have CCC clock set for this stage of boot. + return old_perf_level; +} + +void clock_get_frequencies(uint32_t *clocks, uint32_t count) +{ + uint32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) + cnt = count; + + memcpy(clocks, clks, cnt * sizeof(uint32_t)); +} + +uint32_t clock_get_frequency(int clock) +{ + uint32_t freq = 0; + + // XXX TODO + + switch (clock) { + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + freq = clks[PMGR_CLK_OSC]; + break; + case CLK_PCLK: + case CLK_PERIPH: + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + freq = clks[PMGR_CLK_SIO_P]; + break; + case CLK_MEM: + freq = clks[PMGR_CLK_MCU]; + break; + case CLK_ANS_LINK: + freq = clks[PMGR_CLK_ANC_LINK]; + break; + case CLK_BUS: + freq = clks[PMGR_CLK_LIO]; + break; + case CLK_CPU: + freq = clks[PMGR_CLK_CPU]; + break; +#if SUB_PLATFORM_T7000 + case CLK_MIPI: + freq = clks[PMGR_CLK_MIPI_DSI]; + break; +#endif + case CLK_VCLK0: + freq = clks[PMGR_CLK_VID0]; + break; + default: + break; + } + return freq; +} + +void clock_set_frequency(int clock, uint32_t divider, uint32_t pll_p, uint32_t pll_m, uint32_t pll_s, uint32_t pll_t) +{ + uint32_t clk = PMGR_CLK_OSC; + + switch (clock) { + case CLK_VCLK0: + clk = PMGR_CLK_VID0; + break; +#if SUB_PLATFORM_T7000 + case CLK_MIPI: + clk = PMGR_CLK_PLL0; + break; +#endif + default: + break; + } + + if (clk >= PMGR_CLK_PLL0 && clk <= PMGR_CLK_PLL5) { + int32_t pll = clk - PMGR_CLK_PLL0; + + if (!is_pll_running(pll)) + set_pll(pll, pll_p, pll_m, pll_s, false); + else + set_running_pll(pll, pll_p, pll_m, pll_s); + + clks[clk] = get_pll(pll); + +#if SUB_PLATFORM_T7000 + if (clock == CLK_MIPI) { + clocks_get_frequencies_range(PMGR_CLK_MIPI_DSI, PMGR_CLK_MIPI_DSI); + } +#endif + } + + if (clk >= PMGR_CLK_SOURCE_FIRST && clk <= PMGR_CLK_SOURCE_LAST) { + clock_update_frequency(clk, pll_t); + clocks_get_frequencies_range(clk, clk); + } + + return; +} + +void clock_gate(int device, bool enable) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device); + + // Make sure we are within limits. + if (reg > PMGR_LAST_PS) + return; + +#if APPLICATION_IBOOT && SUPPORT_FPGA + // Old versions of FPGA Secure ROM set FORCE_NOACCESS bit when powering off a block. Make sure bit is cleared. + *reg &= ~PMGR_PS_FORCE_NOACCESS; +#endif + + // Set the PS field to the requested level + if (enable) { + *reg |= PMGR_PS_RUN_MAX; + } else { + *reg &= ~PMGR_PS_RUN_MAX; + } + + // Wait for the MANUAL_PS and ACTUAL_PS fields to be equal + while ((*reg & PMGR_PS_MANUAL_PS_MASK) != ((*reg >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); +} + +static void clocks_set_gates(uint64_t *devices) +{ + uint32_t i, idx; + + // For future platforms that clone from this. + if (PMGR_LAST_DEVICE >= 128) + panic("Rewrite this to deal with more than 128 clock ids"); + + // Make sure SIO_P is on before SIO. + clock_gate(CLK_SIO_P, true); + + // Turn on devices from lo to hi (to meet dependencies). + for (idx = 0, i = PMGR_FIRST_DEVICE; i < PMGR_LAST_DEVICE; i++) { + if (i && ((i % 64) == 0)) + idx++; + if ((devices[idx] >> ((uint64_t)(i % 64))) & 0x1) + clock_gate(i, true); + } + + // Turn off devices hi to lo order (to meet dependencies). + for (idx = 1, i = PMGR_LAST_DEVICE - 1; i >= PMGR_FIRST_DEVICE; i--) { + if (!((devices[idx] >> ((uint64_t)(i % 64))) & 0x1)) + clock_gate(i, false); + if (i && ((i % 64) == 0)) + idx--; + } + + return; +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_system_reset(); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_power_init(void) +{ + /* Disable Power gating for CPU0, this is needed to avoid WFI from powering down the core */ + /* Remove this once following is addressed: Core 0 power gating enabled by default */ + rPMGR_PWRGATE_CPU0_CFG0 &= ~(1UL << 31); + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + + // Initialize temperature sensors, thermal failsafe blocks, and TVM tunables + init_soc_thermal_sensors(); + init_cpu_thermal_sensors(); + init_soc_sochot(); + init_cpu_sochot(); + init_soc_tvm_tunables(); +#endif +} + +void platform_watchdog_tickle(void) +{ + // Varies by target. This layer between is necessary so that + // we don't go straight from generic code to target. + target_watchdog_tickle(); +} + +void clock_reset_device(int device) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device); + uint32_t lpdp_override = 4; + bool lpdp_fuse_ow_enable = false; + + // Make sure we are within limits. + if (device >= PMGR_LAST_DEVICE) + return; + + // XXX TODO + switch (device) { + case CLK_MCU: + case CLK_ANS: + case CLK_SIO: + case CLK_EDPLINK: +#if SUB_PLATFORM_T7000 + case CLK_MIPI: +#endif + *reg |= PMGR_PS_FORCE_NOACCESS; + spin(1); + *reg |= PMGR_PS_RESET; + spin(1); + *reg &= ~(PMGR_PS_RESET | PMGR_PS_FORCE_NOACCESS); + + if (device == CLK_EDPLINK) { + //Begin : SecureROM PLL calibration sequence changes + + lpdp_override = rCFG_FUSE9; + lpdp_override >>= CFG_FUSE9_PLL_LPDP_SHIFT; + lpdp_fuse_ow_enable = lpdp_override & CFG_FUSE9_PLL_VCO_RCTRL_SEL; + + // Is the override data for this PLL valid? + if (lpdp_fuse_ow_enable) { + #define rLPDP_PLL_CLK (*(volatile u_int32_t *)(LPDP_PHY_BASE_ADDR + 0x00084)) + #define LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT 2 + #define LPDP_PLL_CLK_VCO_RCTRL_OW_MASK 0x7 + #define LPDP_PLL_CLK_VCO_RCTRL_SEL_ENABLE 0x1 + #define LPDP_PLL_CLK_VCO_RCTRL_SEL_SHIFT 0x5 + uint32_t reg = rLPDP_PLL_CLK; + reg &= ~(LPDP_PLL_CLK_VCO_RCTRL_OW_MASK << LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT); + reg |= (lpdp_override & LPDP_PLL_CLK_VCO_RCTRL_OW_MASK) << LPDP_PLL_CLK_VCO_RCTRL_OW_SHIFT; + reg |= (LPDP_PLL_CLK_VCO_RCTRL_SEL_ENABLE << LPDP_PLL_CLK_VCO_RCTRL_SEL_SHIFT); + rLPDP_PLL_CLK = reg; + } + // End : SecureROM PLL calibration sequence changes + } + break; + + default: + break; + } +} + +void clock_set_device_reset(int device, bool set) +{ + volatile uint32_t *reg = (volatile uint32_t *)((uint64_t *)PMGR_FIRST_PS + device); + + switch (device) { + case CLK_PCIE: + if (set) { + *reg |= PMGR_PS_FORCE_NOACCESS; + spin(1); + *reg |= PMGR_PS_RESET; + } + else { + *reg &= ~(PMGR_PS_RESET | PMGR_PS_FORCE_NOACCESS); + } + } +} + +bool clock_get_pcie_refclk_good(void) +{ +#if SUB_PLATFORM_T7000 + return true; +#elif SUB_PLATFORM_T7001 + return (rPMGR_DEBUG_PMGR_DEBUG18 & (1 << 18)) != 0; +#endif +} + +#if APPLICATION_IBOOT +static void set_gfx_perf_state(uint32_t state_num, struct gfx_state_info *gfx_state) +{ + uint32_t pll_enable = 0; + + // This is deductive. If feedback divider is 0 the PLL shouldn't output anything. + pll_enable = gfx_state->fb_div ? 1 : 0; + + rPMGR_GFX_PERF_STATE_ENTRY(state_num) = ((gfx_state->dwi_val & 0xFF) << 24) | + ((pll_enable & 0x1) << 21) | + ((gfx_state->fb_div & 0x1FF) << 12) | + ((gfx_state->pre_div & 0x1F) << 4) | + (gfx_state->op_div & 0xF); +#if SUB_PLATFORM_T7001 + rPMGR_GFX_SRAM_PERF_STATE_ENTRY(state_num) = gfx_state->dwi_sram_val & 0xff; +#endif +} +#endif + +#if WITH_DEVICETREE +static uint64_t get_freq_from_ccc_state(uint64_t state_entry) +{ + // Fcpu <= ((OSC * M) / P / S+1) + uint64_t freq = OSC_FREQ; + freq *= ((state_entry >> 4) & 0x1FF); + freq /= ((state_entry >> 13) & 0x1F) ? ((state_entry >> 13) & 0x1F) : 1; + freq /= (1 + ((state_entry >> 0) & 0xF)); + + return freq; +} + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ + uint32_t num_freqs = 0; + uint32_t propSize; + uint64_t period_ns; + uint64_t freq = 0; + uint32_t volt; + + char *propName; + void *propData; + + struct dvfm_data dvfm = { + .dvfm_state_vmax = kDVFM_STATE_VMAX, + .dvfm_state_iboot_cnt = kDVFM_STATE_IBOOT_CNT, + .dvfm_state_vnom = kDVFM_STATE_VNOM, + .dvfm_state_vboost = kDVFM_STATE_VBOOST, + .voltage_states1_count = kVOLTAGE_STATES1_COUNT, + }; + +#if SUB_PLATFORM_T7001 + pmgr_get_dvfm_data(&dvfm); +#endif + + // Populate the devicetree with relevant values. + propName = "nominal-performance1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property nominal-performance1 is of wrong size."); + + freq = get_freq_from_ccc_state(rCCC_DVFM_ST(dvfm.dvfm_state_vnom)); + if (freq == 0) + panic("pmgr Fnom Operating point not defined correctly"); + + period_ns = 1000000000ULL << 16; + period_ns /= freq; + + ((uint32_t *)propData)[0] = period_ns; + } else { + panic("pmgr property nominal-performance1 not found."); + } + + propName = "boost-performance1"; + // Note: Boost is not mandatory in all platforms. + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property boost-performance1 is of wrong size"); + + freq = get_freq_from_ccc_state(rCCC_DVFM_ST(dvfm.dvfm_state_vboost)); + if (freq == 0) + panic("pmgr Fboost Operating point not defined correctly"); + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[0] = period_ns; + } + + propName = "voltage-states1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize / sizeof(uint32_t) < dvfm.voltage_states1_size) { + panic("pmgr number of states less than required for voltage-states1"); + } + + num_freqs = dvfm.voltage_states1_count; + for (int32_t i = num_freqs - 1, j = 0; i >= 0; i--, j++) { + // Getting voltage and frequencies directly from rCCC_DVFM_ST allows + // including all the changes done before launching the kernel: + // - voltage adjusting coming from converting voltage to PMU value, + // - voltage knobs from LLB, + // - astris changes done while beeing in iBoot console, + freq = get_freq_from_ccc_state(rCCC_DVFM_ST(dvfm.dvfm_state_vmax - j)); + volt = platform_get_dwi_to_mv(BUCK_CPU, CCC_DVFM_ST_TO_SAFEVOL(rCCC_DVFM_ST(dvfm.dvfm_state_vmax - j))); + if (freq != 0) { + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[2*i] = period_ns; + ((uint32_t *)propData)[2*i+1] = volt; + } + } + } + + propName = "total-rails-leakage"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(uint32_t)) { + *(uint32_t *)propData = chipid_get_total_rails_leakage(); + } + } + + return; +} + +void pmgr_gfx_update_device_tree(DTNode *gfx_node) +{ + u_int32_t count, propSize, num_states = 0, state_val; + char *propName; + void *propData; + + propName = "perf-states"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(u_int32_t) * kPMGR_GFX_STATE_MAX)) { + panic("gfx property perf-state has wrong size"); + } + // Read the values programmed into the GFX perf state table + // and populate the device tree. + for (count = 0; count < kPMGR_GFX_STATE_MAX; count++) { + state_val = rPMGR_GFX_PERF_STATE_ENTRY(count); + + // Any but the first entry with a value of 0 marks the end of the number of valid states. + if ((count != 0) && (state_val == rPMGR_GFX_PERF_STATE_ENTRY(CHIPID_GPU_VOLTAGE_OFF))) { + num_states = count; + break; + } + + ((u_int32_t *)propData)[count * 2 + 0] = PMGR_PLL_FREQ((state_val >> 12) & 0x1FF, (state_val >> 4) & 0x1F, state_val & 0xF); + ((u_int32_t *)propData)[count * 2 + 1] = platform_get_dwi_to_mv(BUCK_GPU, (state_val >> 24) & 0xFF); + } + + // If all the entries are valid. + if (count == kPMGR_GFX_STATE_MAX) { + num_states = kPMGR_GFX_STATE_MAX; + } + + } + + propName = "perf-state-count"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + *(u_int32_t *)propData = kPMGR_GFX_STATE_MAX; // This is the value given before + } + + propName = "gpu-num-perf-states"; + /* We don't count DIDT states and OFF state */ + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + *(u_int32_t *)propData = num_states / 2; + } + return; +} + +void sochot_pmgr_update_device_tree(DTNode *node) +{ + uint32_t propSize; + char *propName; + void *propData; + + propName = "target-dvfm-state-0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(uint32_t)) { + *(uint32_t *)propData = CCC_DFVM_FSHOT_IDX_THERMAL0_STATE; + } + } + + propName = "target-dvfm-state-1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(uint32_t)) { + *(uint32_t *)propData = CCC_DFVM_FSHOT_IDX_THERMAL1_STATE; + } + } +} +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +static void init_soc_thermal_sensors(void) +{ + // Keep sampling rate at default 1 kHz (pending Tune temperature sensor sampling rates for Fiji/Capri) + + // Define piecewise-linear relationship (start_codes, offsets, slopes) between output and temperature for SOC/PMGR sensors + rPMGR_THERMAL0_PIECE0 = PMGR_THERMAL_PIECE(0x000, 0x1d4, 0x036); + rPMGR_THERMAL0_PIECE1 = PMGR_THERMAL_PIECE(0x1aa, 0x1e3, 0x02d); + rPMGR_THERMAL0_PIECE2 = PMGR_THERMAL_PIECE(0x270, 0x1f9, 0x024); + + rPMGR_THERMAL1_PIECE0 = PMGR_THERMAL_PIECE(0x000, 0x1d4, 0x036); + rPMGR_THERMAL1_PIECE1 = PMGR_THERMAL_PIECE(0x1aa, 0x1e3, 0x02d); + rPMGR_THERMAL1_PIECE2 = PMGR_THERMAL_PIECE(0x270, 0x1f9, 0x024); + + // Read temperature trim values from efuse and write to corresponding registers (CPU sensors handle this step in hardware) + rPMGR_THERMAL0_PARAM = PMGR_THERMAL_PARAM_SET_TRIM(rPMGR_THERMAL0_PARAM, chipid_get_soc_temp_sensor_trim(0)); + rPMGR_THERMAL1_PARAM = PMGR_THERMAL_PARAM_SET_TRIM(rPMGR_THERMAL1_PARAM, chipid_get_soc_temp_sensor_trim(1)); + + rPMGR_THERMAL0_CTL1 = 0xea60; + rPMGR_THERMAL1_CTL1 = 0xea60; + + // Enable temperature sensors (need to do this before enabling either DVTM or thermal failsafe) + rPMGR_THERMAL0_CTL0_SET = PMGR_THERMAL_CTL0_ENABLE; + rPMGR_THERMAL1_CTL0_SET = PMGR_THERMAL_CTL0_ENABLE; +} + +static void init_soc_sochot(void) +{ + // Set target state for when SOCHOT triggers + rPMGR_GFX_PERF_STATE_SOCHOT = PMGR_GFX_PERF_STATE_SOCHOT_ENABLE_TRIG0 | PMGR_GFX_PERF_STATE_SOCHOT_TRIG0_SELECT(1); + + // SOC SOCHOT not supported due to certain media use cases having hard clock requirements +} + +static void init_cpu_thermal_sensors(void) +{ + // Keep sampling rate at default 1 kHz (pending Tune temperature sensor sampling rates for Fiji/Capri) + + // Define piecewise-linear relationship (start_codes, offsets, slopes) between output and temperature for CPU sensors + rCCC_THRM0_PIECE0 = CCC_THRM_PIECE(0x000, 0x0d4, 0x036); + rCCC_THRM0_PIECE1 = CCC_THRM_PIECE(0x1aa, 0x0e3, 0x02d); + rCCC_THRM0_PIECE2 = CCC_THRM_PIECE(0x270, 0x0f9, 0x024); + + rCCC_THRM1_PIECE0 = CCC_THRM_PIECE(0x000, 0x0d4, 0x036); + rCCC_THRM1_PIECE1 = CCC_THRM_PIECE(0x1aa, 0x0e3, 0x02d); + rCCC_THRM1_PIECE2 = CCC_THRM_PIECE(0x270, 0x0f9, 0x024); + + rCCC_THRM2_PIECE0 = CCC_THRM_PIECE(0x000, 0x0d4, 0x036); + rCCC_THRM2_PIECE1 = CCC_THRM_PIECE(0x1aa, 0x0e3, 0x02d); + rCCC_THRM2_PIECE2 = CCC_THRM_PIECE(0x270, 0x0f9, 0x024); + +#if SUB_PLATFORM_T7001 + rCCC_THRM3_PIECE0 = CCC_THRM_PIECE(0x000, 0x0d4, 0x036); + rCCC_THRM3_PIECE1 = CCC_THRM_PIECE(0x1aa, 0x0e3, 0x02d); + rCCC_THRM3_PIECE2 = CCC_THRM_PIECE(0x270, 0x0f9, 0x024); +#endif + + // Per , although the CPU sensors handle the step of reading temperature trim from efuse and writing + // this to THRMn_PARAM in hardware, the value doesn't actually take effect until an explicit register write is done -- so the + // workaround for this errata is to read out and then write back the contents of each CCC_THRMn_PARAM register, unchanged. + rCCC_THRM0_PARAM = rCCC_THRM0_PARAM; + rCCC_THRM1_PARAM = rCCC_THRM1_PARAM; + rCCC_THRM2_PARAM = rCCC_THRM2_PARAM; +#if SUB_PLATFORM_T7001 + rCCC_THRM3_PARAM = rCCC_THRM3_PARAM; +#endif + + rCCC_THRM0_CTL1 = 0xea60; + rCCC_THRM1_CTL1 = 0xea60; + rCCC_THRM2_CTL1 = 0xea60; +#if SUB_PLATFORM_T7001 + rCCC_THRM3_CTL1 = 0xea60; +#endif + + // Enable temperature sensors (need to do this before enabling either DVTM or thermal failsafe) + rCCC_THRM0_CTL0_SET = CCC_THRM_CTL0_ENABLE; + rCCC_THRM1_CTL0_SET = CCC_THRM_CTL0_ENABLE; + rCCC_THRM2_CTL0_SET = CCC_THRM_CTL0_ENABLE; +#if SUB_PLATFORM_T7001 + rCCC_THRM3_CTL0_SET = CCC_THRM_CTL0_ENABLE; +#endif +} + +static void init_cpu_sochot(void) +{ + // Set target state for when SOCHOT triggers + rCCC_DVFM_FSHOT_IDX = CCC_DFVM_FSHOT_IDX_THERMAL0(kDVFM_STATE_V0); +} + +static void init_soc_tvm_tunables(void) +{ + rPMGR_TVM_THRESH0 = PMGR_TVM_THRESH(0x00); + rPMGR_TVM_THRESH1 = PMGR_TVM_THRESH(0x19); + rPMGR_TVM_THRESH2 = PMGR_TVM_THRESH(0x32); + rPMGR_TVM_TEMP0_CFG = PMGR_TVM_TEMP_CFG_MAX_OFFSET(0x5) | PMGR_TVM_TEMP_CFG_MIN_OFFSET(0x1F6); + rPMGR_TVM_TEMP1_CFG = PMGR_TVM_TEMP_CFG_MAX_OFFSET(0x5) | PMGR_TVM_TEMP_CFG_MIN_OFFSET(0x1FB); +} + +#endif diff --git a/platform/t7000/pmgr/rules.mk b/platform/t7000/pmgr/rules.mk new file mode 100644 index 0000000..1fbd41d --- /dev/null +++ b/platform/t7000/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/t7000/rules.mk b/platform/t7000/rules.mk new file mode 100644 index 0000000..f092fb1 --- /dev/null +++ b/platform/t7000/rules.mk @@ -0,0 +1,146 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +# Devmap chip ID and cpu based on sub-platform identifier +ifeq ($(SUB_PLATFORM),t7000) + ARM_CPU := apple-typhoon + DEVMAP_CHIP_ID := 7000 + SDRAM_LEN_DEFAULT := 1*1024*1024*1024 + SDRAM_TEXT_BASE := 0x830000000 + SDRAM_TEXT_FOOTPRINT := 1024*1024 + ifeq ($(SUPPORT_FPGA),) + SRAM_TEXT_BASE := 0x180380000 + SRAM_TEXT_FOOTPRINT := 384*1024 + else + SRAM_TEXT_BASE := 0x180180000 + SRAM_TEXT_FOOTPRINT := 256*1024 + endif +else ifeq ($(SUB_PLATFORM),t7001) + ARM_CPU := apple-typhoon-capri + DEVMAP_CHIP_ID := 7001 + SDRAM_LEN_DEFAULT := 2*1024*1024*1024 + SDRAM_TEXT_BASE := 0x870000000 + SDRAM_TEXT_FOOTPRINT := 1024*1024 + SRAM_TEXT_BASE := 0x180380000 + SRAM_TEXT_FOOTPRINT := 384*1024 +else + $(error "Unrecognized SUB_PLATFORM \"$(SUB_PLATFORM)\"") +endif + +MAX_DFU_SIZE := 524288 + +# srom is always defined in here +ifeq ($(TEXT_BANK),srom) + TEXT_BASE := 0x100000000 +endif + +# Overriding SRAM_LEN is not allowed. +ifeq ($(TEXT_BANK),sram) + # SRAM TEXT_BASE is fixed by SecureROM. + TEXT_BASE := $(SRAM_TEXT_BASE) + + # iBSS/LLB memory configuration + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := $(SRAM_TEXT_FOOTPRINT) + endif +endif + +# Platform target can override SDRAM config by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(SDRAM_LEN),) + SDRAM_LEN := $(SDRAM_LEN_DEFAULT) + + # iBoot/iBEC memory configuration + ifeq ($(TEXT_BANK),sdram) + # SDRAM TEXT_BASE is now set such that you don't have to do lots of math to + # calulate the correct value if you change any of the other region sizes: + # TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 256MB + TEXT_BASE := $(SDRAM_TEXT_BASE) + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := $(SDRAM_TEXT_FOOTPRINT) + endif + endif +endif + +# Platform target can override any of these sizes by specifying in target config file (apps/iBoot/$target-config.mk) +ifeq ($(ASP_SIZE),) + ASP_SIZE := 8*1024*1024 +endif +ifeq ($(TZ0_SIZE),) + TZ0_SIZE := 2*1024*1024 +endif +ifeq ($(DISPLAY_SIZE),) + DISPLAY_SIZE := 16*1024*1024 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + ANC_PPNNPL_DS_DRIVE_STRENGTH=6 \ + ANC_PPNNPL_INPUT_SELECT_SCHMITT=1 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_HOLD_TIME=2 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_SETUP_TIME=3 \ + ANC_LINK_SDR_REN_HOLD_TIME=2 \ + ANC_LINK_SDR_REN_SETUP_TIME=3 \ + ANC_LINK_SDR_WEN_HOLD_TIME=2 \ + ANC_LINK_SDR_WEN_SETUP_TIME=3 \ + ANC_LINK_SDR_DATA_CAPTURE_DELAY=1 \ + ANC_LINK_SDR_CLE_ALE_SETUP_TIME=0 \ + ANC_BOOT_CONTROLLERS=2 \ + ANC_TOGGLE_SUPPORTED=1 \ + DISPLAY_SIZE="($(DISPLAY_SIZE)ULL)" \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=256 \ + PLATFORM_START_FUNCTION=_platform_start \ + SDRAM_LEN="$(SDRAM_LEN)ULL" \ + ASP_SIZE="$(ASP_SIZE)" \ + TZ0_SIZE="$(TZ0_SIZE)ULL" \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" \ + WITH_CLASSIC_SUSPEND_TO_RAM=1 \ + WITH_NO_RANDOM_HEAP_COOKIE=1 \ + WITH_NO_RANDOM_STACK_COOKIE=1 \ + LPDP_LINK_CAL_TABLE_VERSION=1 + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) + DATA_BASE := 0x180080000 + + GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) + + OPTIONS += \ + WITH_ROM_TRAMPOLINE=1 \ + DATA_BASE="$(DATA_BASE)" + + ifeq ($(CONFIGS),fpga) + OPTIONS += \ + SUPPORT_FPGA=1 + endif + +else # ifeq ($(APPLICATION),SecureROM) + + OPTIONS += \ + WITH_MONITOR=1 +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/trampoline.o diff --git a/platform/t7000/trampoline.S b/platform/t7000/trampoline.S new file mode 100644 index 0000000..418a1ce --- /dev/null +++ b/platform/t7000/trampoline.S @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2012-2014 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ + +#include +#if WITH_ROM_TRAMPOLINE +#include +#endif // WITH_ROM_TRAMPOLINE +#include +#include + +// Clears from X0 to X1 (not including X1). +// Assumes that X0 and X1 are both 64-byte aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1 +1: + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + cmp x0, x1 + b.lo 1b +.endmacro + +// Clears from X0 to X1 (not including X1) using cacheline clear +// operations. +// Assumes that X0 and X1 are both cacheline aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1_CACHE_ON +1: + dc zva, x0 // zero cacheline + add x0, x0, #L1_CACHELINE_SIZE + cmp x0, x1 + b.lo 1b +.endmacro + + .text + .balign 16 + .globl _boot_handoff_trampoline, _boot_handoff_trampoline_end +_boot_handoff_trampoline: + // Save jump address in x27, and next stage boot info into x28. + mov x27, x0 + mov x28, x1 + + // Disable external aborts, interrupts + msr DAIFSet, #(0xf) + +#if !WITH_CLASSIC_SUSPEND_TO_RAM || !PRODUCT_LLB + // Start by clearing the heap. + ldr x0, L_heap_base + ldr x1, L_heap_end + CLEAR_X0_TO_X1_CACHE_ON + + // Clear the stacks area. + ldr x0, L_stacks_base + ldr x1, L_stacks_end + CLEAR_X0_TO_X1_CACHE_ON +#endif // !WITH_SUSPEND_TO_RAM || !PRODUCT_LLB + + // Retire all instructions executed prior to this (may include ROM). + isb sy + + // Disable caches, mmu, stack alignment fault + mov x3, #0 + msr SCTLR_EL3, x3 + dsb sy + isb sy + + // Flush the TLBs - radar 18269688 + tlbi alle3 + dsb sy + isb sy + + // Now running EL3 with MMU off. All accesses are device, secure. + +#if !WITH_CLASSIC_SUSPEND_TO_RAM || !PRODUCT_LLB + // Clear the page tables. + ldr x0, L_page_tables_base + ldr x1, L_page_tables_end + CLEAR_X0_TO_X1 + +#ifdef BOOT_TRAMPOLINE_BASE + // Clear the text area (or data area in ROM) + // This can only be done if the trampoline was copied to a safe location + ldr x0, L_text_base + ldr x1, L_text_end + CLEAR_X0_TO_X1 + + // Clear all the pointers to interesting memory areas + // that were included in the trampoline + adr x0, L_pointers_base + adr x1, L_pointers_end + CLEAR_X0_TO_X1 +#endif +#endif + +#if WITH_ROM_TRAMPOLINE + // Disable R/W access to ROM region + ldr x1, L_rom_trampoline_reg + ldr w2, L_rom_trampoline_val + ldr w3, [x1] + orr w3, w3, w2 + str w3, [x1] + dsb sy + ldr w3, [x1] + tst w3, w2 // Verify ROM access is disabled + b.eq _trampoline_spin // Oops, not disabled + + // ROM doesn't pass any info to next stage (LLB) + mov x28, #0 +#endif // WITH_ROM_TRAMPOLINE + + // Register format for "dc cisw" is: + // * 32 bit register + // * Ways in the top bits (31 downwards) + // * Sets starting at bit log2(line size) + // * Level specified near the lowest bits. + // E.g for Cyclone L2 with 64 byte lines, 2K lines, 8 ways: + // [31:29] = way 0..7 + // [28:17] = SBZ + // [16:6] = set 0..2047 (aka "index") + // [5:4] = SBZ + // [3:1] = level = 3'h1 (L2) + // [0] = SBZ + mov x0, #(1 << 1) // x0 = set 0, way 0, level L2 + mov x1, #1 << L2_CACHELINE_SHIFT + mov x2, #1 << (L2_CACHELINE_SHIFT + L2_CACHEINDEX_SHIFT) + mov x3, #1 << (32 - L2_CACHEWAY_SHIFT) + mov x4, #1 << 32 +1: dc cisw, x0 // Clean-invalidate with x0 + // Increment set field. + add x0, x0, x1 // Increment [16:6] + tst x0, x2 // Test for overflow in [17] + b.eq 1b + // Carry set field into way field. + bic x0, x0, x2 // Clear overflow in [17] + add x0, x0, x3 // Increment [31:29] + tst x0, x4 // Test for overflow in [32] + b.eq 1b + // Carry out of way field ends the loop. + // Another dummy TLBI to act as sDsb. + mov x0, #0 + tlbi ASIDE1IS, x0 + dsb sy + isb sy + +#if VERIFY_INVALIDATION + // Let's "quickly" double-check: all dup-tags should be invalid. + // WARNING: This takes 70 ms when running with quiesced clocks + ldr x0, L_ccu0_addr + bl _verify_invalidated_cp_channel + ldr x0, L_ccu1_addr + bl _verify_invalidated_cp_channel +#endif + +#if WITH_ROM_TRAMPOLINE + // Clear remap if enabled to boot this ROM + ldr x1, L_rom_remap_reg + str wzr, [x1] +#endif // WITH_ROM_TRAMPOLINE + + // Reset CPU state + mov x1, #0 + mov x2, #0 + mov x3, #0 + mov x4, #0 + mov x5, #0 + mov x6, #0 + mov x7, #0 + mov x8, #0 + mov x9, #0 + mov x10, #0 + mov x11, #0 + mov x12, #0 + mov x13, #0 + mov x14, #0 + mov x15, #0 + mov x16, #0 + mov x17, #0 + mov x18, #0 + mov x19, #0 + mov x20, #0 + mov x21, #0 + mov x22, #0 + mov x23, #0 + mov x24, #0 + mov x25, #0 + mov x26, #0 + mov x30, x27 // lr = next boot stage PC + mov x0, x28 // x0 = next boot stage info + mov x27, #0 + mov x28, #0 + mov x29, #0 + msr TTBR0_EL3, x1 + msr VBAR_EL3, x1 + msr ELR_EL1, x1 + msr ELR_EL2, x1 + msr ELR_EL3, x1 + msr SPSR_EL1, x1 + msr SPSR_EL2, x1 + msr SPSR_EL3, x1 + msr SP_EL1, x1 + msr SP_EL2, x1 + mov sp, x1 // SP_EL0 + msr SPSel, #1 + mov sp, x1 // SP_EL3 + + // Invalidate I-cache + ic iallu + dsb sy + isb sy + + // Jump to the next stage + ret + +#if VERIFY_INVALIDATION +_verify_invalidated_cp_channel: + // x0 = pointer to base of channel + mov x1, #1024 * 8 // Loop over all sets, ways. +1: ldr w2, [x0], #4 // x4 = duptag + ubfx x3, x2, #21, #2 // x5 = duptag[21:20] = state + cmp x3, #0 // Check state=0=invalid + b.ne _trampoline_spin + sub x1, x1, #1 + cmp x1, #0 + b.ne 1b + ret +#endif + +#if WITH_ROM_TRAMPOLINE || VERIFY_INVALIDATION + // Not really able to panic at this point, so let's just spin. +_trampoline_spin: + wfe + b _trampoline_spin +#endif + + .balign 8 +#if VERIFY_INVALIDATION +L_ccu0_addr: + .8byte CP_0_DT_DBG_CA0_ADDR +L_ccu1_addr: + .8byte CP_1_DT_DBG_CA0_ADDR +#endif + +#if WITH_ROM_TRAMPOLINE +L_rom_remap_reg: + .8byte REMAP_REG +L_rom_trampoline_reg: + .8byte SECURITY_REG +L_rom_trampoline_val: + .4byte ROM_READ_DISABLE +#endif // WITH_ROM_TRAMPOLINE + + .balign 64 +L_pointers_base: +#if WITH_ROM_TRAMPOLINE + // in ROM we don't erase TEXT, but we can erase DATA +L_text_base: + .8byte DATA_BASE +L_text_end: + .8byte DATA_BASE + DATA_SIZE +#else + // In non-ROM we erase TEXT_FOOTPRINT, which includes both TEXT and DATA +L_text_base: + .8byte TEXT_BASE +L_text_end: + .8byte TEXT_BASE + TEXT_FOOTPRINT +#endif // WITH_ROM_TRAMPOLINE +L_heap_base: + .8byte HEAP_BASE +L_heap_end: + .8byte HEAP_BASE + HEAP_SIZE +L_stacks_base: + .8byte STACKS_BASE +L_stacks_end: + .8byte STACKS_BASE + STACKS_SIZE +L_page_tables_base: + .8byte PAGE_TABLES_BASE +L_page_tables_end: + .8byte PAGE_TABLES_BASE + PAGE_TABLES_SIZE + .balign 64 +L_pointers_end: + +_boot_handoff_trampoline_end: diff --git a/platform/t8002/asm.S b/platform/t8002/asm.S new file mode 100644 index 0000000..ffa1774 --- /dev/null +++ b/platform/t8002/asm.S @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + +#if APPLICATION_IBOOT && (PRODUCT_IBSS || PRODUCT_LLB) + .text + .arm + .align 12 + .globl _platform_start +_platform_start: + // Use VBAR to relocate exception vectors to binary linked address + mcr p15, 0, r0, c12, c0, 0 + isb + bx lr +#endif diff --git a/platform/t8002/chipid/chipid.c b/platform/t8002/chipid/chipid.c new file mode 100644 index 0000000..d8e8a6c --- /dev/null +++ b/platform/t8002/chipid/chipid.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +bool chipid_get_current_production_mode(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_XTRCT(rCFG_FUSE0) != 0; +} + +bool chipid_get_raw_production_mode(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_XTRCT(rCFG_FUSE0_RAW) != 0; +} + +void chipid_clear_production_mode(void) +{ + rCFG_FUSE0 &= ~MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_UMASK; +} + +bool chipid_get_secure_mode(void) +{ + // demotion only applies to the SEP, so iBoot always reads + // the raw value for secure mode () + return MINIPMGR_FUSE_CFG_FUSE0_SECURE_MODE_XTRCT(rCFG_FUSE0_RAW); +} + +uint32_t chipid_get_security_domain(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_SECURITY_DOMAIN_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_board_id(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_BID_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_minimum_epoch(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_MINIMUM_EPOCH_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_chip_id(void) +{ + return 0x8002; +} + +uint32_t chipid_get_chip_revision(void) +{ + uint32_t fuse_val = MINIPMGR_FUSE_CFG_FUSE4_DEV_VERSION_XTRCT(rCFG_FUSE4); + + // we use 4 bits for base layer and 4 bits for metal, + // the fuses use 3 for each + return (fuse_val & 0x7) | (((fuse_val >> 3) & 0x7) << 4); +} + +uint32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +uint64_t chipid_get_ecid_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint64_t chipid_get_die_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint32_t chipid_get_soc_voltage(uint32_t index) +{ + uint32_t soc_voltage = 0; + + return soc_voltage; +} + +uint32_t chipid_get_cpu_voltage(uint32_t index) +{ + uint32_t cpu_voltage = 0; + + return cpu_voltage; +} + + +uint32_t chipid_get_ram_voltage(uint32_t index) +{ + uint32_t sram_voltage = 0; + + return sram_voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return MINIPMGR_FUSE_CFG_FUSE1_AP_LOCK_XTRCT(rCFG_FUSE1) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) { + rCFG_FUSE1 |= MINIPMGR_FUSE_CFG_FUSE1_AP_LOCK_INSRT(1); + asm("dsb sy"); + if (!chipid_get_fuse_lock()) { + panic("Failed to lock fuses\n"); + } + } +} + +bool chipid_get_fuse_seal(void) +{ + return MINIPMGR_FUSE_CFG_FUSE1_SEAL_FUSES_XTRCT(rCFG_FUSE1) != 0; +} + +uint32_t chipid_get_fuse_revision(void) +{ + return MINIPMGR_FUSE_CFG_FUSE4_REV_XTRCT(rCFG_FUSE4); +} + +uint32_t chipid_get_total_rails_leakage() +{ + uint32_t total_leakage; + uint32_t leakage_data0; + uint8_t leakage_data1; + + leakage_data0 = rCFG_FUSE5; + leakage_data1 = (rCFG_FUSE4 >> 31) & 1; + + total_leakage = ((leakage_data0 >> 28) & 0xf) + 1; // soc_sram: cfg_fuse4[31:28] + total_leakage += ((leakage_data0 >> 24) & 0xf) + 1; // cpu_sram: cfg_fuse4[27:24] + total_leakage += ((leakage_data0 >> 16) & 0xff) + 1; // gpu: cfg_fuse4[23:16] + total_leakage += ((leakage_data0 >> 8) & 0xff) + 1; // soc: cfg_fuse4[15:8] + total_leakage += ((((leakage_data0 >> 0) & 0xff) << 1) | leakage_data1) + 1; // cpu: cfg_fuse4[7:0], cfg_fuse4[31] + + return total_leakage; +} diff --git a/platform/t8002/chipid/rules.mk b/platform/t8002/chipid/rules.mk new file mode 100644 index 0000000..8f01518 --- /dev/null +++ b/platform/t8002/chipid/rules.mk @@ -0,0 +1,20 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += $(LOCAL_DIR)/chipid.o + +ifeq ($(SUB_PLATFORM),t8002) +ALL_OBJS += \ + $(LOCAL_DIR)/tunables_pmgr_t8002.o +endif diff --git a/platform/t8002/chipid/tunables_pmgr_t8002.c b/platform/t8002/chipid/tunables_pmgr_t8002.c new file mode 100644 index 0000000..86fe469 --- /dev/null +++ b/platform/t8002/chipid/tunables_pmgr_t8002.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* This file contains Tunables for t8002 */ + +#include +#include +#include +#include + +/**************************************** BEGIN CHIP_REVISION_B0 ****************************************/ +#include +#include +#include +#include +#include +#include + +static const struct tunable_struct pmgr_tunable_t8002_b0[] = { + PMS_PMGR_DEFAULT_TUNABLES_T8002_B0 +}; + +static const struct tunable_struct minipmgr_tunable_t8002_b0[] = { + AOP_MINIPMGR_DEFAULT_TUNABLES_T8002_B0 +}; + +static const struct tunable_struct cpu_fabric_tunable_t8002_b0[] = { + PIO_CPU_FABRIC_DEFAULT_TUNABLES_T8002_B0 +}; + +static const struct tunable_struct nrt_fabric_tunable_t8002_b0[] = { + PIO_NRT_FABRIC_DEFAULT_TUNABLES_T8002_B0 +}; + +static const struct tunable_struct uvdc_tunable_t8002_b0[] = { + PMS_UVDC_DEFAULT_TUNABLES_T8002_B0 +}; + +static const struct tunable_struct pio_wrap_tunable_t8002_b0[] = { + PIO_PIO_WRAP_DEFAULT_TUNABLES_T8002_B0 +}; +/***************************************** END CHIP_REVISION_B0 *****************************************/ + +/**************************************** BEGIN CHIP_REVISION_A0 ****************************************/ +#include +#include +#include +#include +#include +#include + +static const struct tunable_struct pmgr_tunable_t8002_a0[] = { + PMS_PMGR_DEFAULT_TUNABLES_T8002_A0 +}; + +static const struct tunable_struct minipmgr_tunable_t8002_a0[] = { + AOP_MINIPMGR_DEFAULT_TUNABLES_T8002_A0 +}; + +static const struct tunable_struct cpu_fabric_tunable_t8002_a0[] = { + PIO_CPU_FABRIC_DEFAULT_TUNABLES_T8002_A0 +}; + +static const struct tunable_struct nrt_fabric_tunable_t8002_a0[] = { + PIO_NRT_FABRIC_DEFAULT_TUNABLES_T8002_A0 +}; + +static const struct tunable_struct uvdc_tunable_t8002_a0[] = { + PMS_UVDC_DEFAULT_TUNABLES_T8002_A0 +}; + +static const struct tunable_struct pio_wrap_tunable_t8002_a0[] = { + PIO_PIO_WRAP_DEFAULT_TUNABLES_T8002_A0 +}; +/***************************************** END CHIP_REVISION_A0 *****************************************/ + +const struct tunable_chip_struct tunables_pmgr[] = { + // B0 + {CHIP_REVISION_B0, PMS_PMGR_PADDR_T8002_B0, pmgr_tunable_t8002_b0, NULL, true}, + {CHIP_REVISION_B0, AOP_MINIPMGR_PADDR_T8002_B0, minipmgr_tunable_t8002_b0, NULL, false}, + {CHIP_REVISION_B0, PIO_CPU_FABRIC_PADDR_T8002_B0, cpu_fabric_tunable_t8002_b0, NULL, true}, + {CHIP_REVISION_B0, PIO_NRT_FABRIC_PADDR_T8002_B0, nrt_fabric_tunable_t8002_b0, NULL, true}, + {CHIP_REVISION_B0, PMS_UVDC_PADDR_T8002_B0, uvdc_tunable_t8002_b0, NULL, true}, + {CHIP_REVISION_B0, PIO_PIO_WRAP_PADDR_T8002_B0, pio_wrap_tunable_t8002_b0, NULL, true}, + + // A0 + {CHIP_REVISION_A0, PMS_PMGR_PADDR_T8002_A0, pmgr_tunable_t8002_a0, NULL, true}, + {CHIP_REVISION_A0, AOP_MINIPMGR_PADDR_T8002_A0, minipmgr_tunable_t8002_a0, NULL, false}, + {CHIP_REVISION_A0, PIO_CPU_FABRIC_PADDR_T8002_A0, cpu_fabric_tunable_t8002_a0, NULL, true}, + {CHIP_REVISION_A0, PIO_NRT_FABRIC_PADDR_T8002_A0, nrt_fabric_tunable_t8002_a0, NULL, true}, + {CHIP_REVISION_A0, PMS_UVDC_PADDR_T8002_A0, uvdc_tunable_t8002_a0, NULL, true}, + {CHIP_REVISION_A0, PIO_PIO_WRAP_PADDR_T8002_A0, pio_wrap_tunable_t8002_a0, NULL, true}, + + {-1, -1, NULL, NULL, false}, +}; + +const struct tunable_filtered_chip_struct tunables_filtered_pmgr[] = { + // B0 + // Applied in OS + {CHIP_REVISION_B0, AOP_MINIPMGR_PADDR_T8002_B0 + MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG_OFFSET, AOP_MINIPMGR_PADDR_T8002_B0 + MINIPMGR_MINI_CLKCFG_XI0MUX_CLK_CFG_OFFSET, true, true}, + {CHIP_REVISION_B0, AOP_MINIPMGR_PADDR_T8002_B0 + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET, AOP_MINIPMGR_PADDR_T8002_B0 + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET, true, true}, + {CHIP_REVISION_B0, PMS_PMGR_PADDR_T8002_B0 + PMGR_MISC_CFG_ACG_OFFSET, PMS_PMGR_PADDR_T8002_B0 + PMGR_MISC_CFG_ACG_OFFSET, true, true}, + + // A0 + // Applied in OS + {CHIP_REVISION_A0, AOP_MINIPMGR_PADDR_T8002_A0 + MINIPMGR_MINI_CLKCFG_PROXY_OSC_CLK_CFG_OFFSET, AOP_MINIPMGR_PADDR_T8002_A0 + MINIPMGR_MINI_CLKCFG_XI0MUX_CLK_CFG_OFFSET, true, true}, + {CHIP_REVISION_A0, AOP_MINIPMGR_PADDR_T8002_A0 + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET, AOP_MINIPMGR_PADDR_T8002_A0 + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET, true, true}, + {CHIP_REVISION_A0, PMS_PMGR_PADDR_T8002_A0 + PMGR_MISC_CFG_ACG_OFFSET, PMS_PMGR_PADDR_T8002_A0 + PMGR_MISC_CFG_ACG_OFFSET, true, true}, + + {-1, -1, -1, NULL, false}, +}; diff --git a/platform/t8002/dcs/dcs.c b/platform/t8002/dcs/dcs.c new file mode 100644 index 0000000..4975714 --- /dev/null +++ b/platform/t8002/dcs/dcs.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + dcs_boottype_t boot_type; + + // Don't perform DRAM initializion if the memory controller is already + // initialized (e.g., for SecureROM validation testing). + if (resume || DCS_REG_READ_CH(0, rDCS_MCU_AMCCTRL) == 0) { + clock_gate(CLK_AMC, true); + + boot_type = (resume)? DCS_BOOT_RESUME:DCS_BOOT_COLDBOOT; + // NOTE: Boot types AOP_DDR or AOP_AWAKE do not use this Code + // For those cases, the Init sequence is executed by the AOP + + // Perform the LPDDR4 Init for this type of Boot + dcs_init(boot_type); + } + + return 0; +} + +void mcu_bypass_prep (int step) +{ +} + +uint64_t mcu_get_memory_size (void) +{ + return dcs_get_memory_size(); +} + +//================================================================================ +void dcs_enable_slow_boot (bool enable) +{ + if (enable) { + // switch to slow clock + clocks_set_performance(kPerformanceMemoryLow); + spin(1); + } + else { +#if !SUPPORT_FPGA + // switch back to full-speed + clocks_set_performance(kPerformanceMemoryFull); + spin(1); +#endif + } +} + +//================================================================================ +void dcs_dram_workarounds(dcs_boottype_t boot_type) +{ + /* No workarounds yet */ +} + +//================================================================================ +// Grab (Platform Specific) Tables with Definitions of Values for DCS Init & DCS Tunables +#include + +#if DCS_FIXUP_PARAMS +// Grab (Target Specific) Definition of Required Fixups to the Values for DCS Init +#include +#endif +//================================================================================ +void dcs_init_config_params(dcs_config_params_t *use_dcs_params, dcs_target_t targtype) +{ + memcpy(use_dcs_params, &dcs_params, sizeof(dcs_config_params_t)); + +#if DCS_FIXUP_PARAMS + // This gives the particular target a chance to make target-specific changes + dcs_init_config_fixup_params(use_dcs_params, targtype); +#endif +} + +//================================================================================ +const dcs_tunable_t *dcs_init_tunable_table(uint32_t *table_len) +{ + if (table_len) + *table_len = sizeof(dcs_tunables) / sizeof(dcs_tunables[0]); + + return dcs_tunables; +} + +//================================================================================ +// Save off calibration results to AOP_SRAM region (later to be stitched into reconfig sequence) +// Order of registers to be saved must match the order to be restored +volatile uint32_t *dcs_save_calibration_results(volatile uint32_t *save_region, uint32_t freq) +{ + /* TBD */ + return NULL; +} + +//================================================================================ +// Stitch the saved calibration results into the reconfig sequence +// To be called immediately after stitching mcu_aop_awake_reconfig_pre_restore +// Order of registers to be restored matches the order in the reconfig sequence +void dcs_restore_calibration_results(volatile uint32_t *save_region) +{ + /* TBD */ +} + + +//================================================================================ diff --git a/platform/t8002/dcs/dcs_init_lib_t8002.c b/platform/t8002/dcs/dcs_init_lib_t8002.c new file mode 100644 index 0000000..0f0dc06 --- /dev/null +++ b/platform/t8002/dcs/dcs_init_lib_t8002.c @@ -0,0 +1,832 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Init Sequence Library for use in: + * Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block + */ + +/* +Summary of Steps from the Spec (Spreadsheet) + + + (Aa) Steps 0,1,2,3a [need to identify parameterization] + + (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait] + + (Ac) Steps 3c,4,5 [need to identify parameterization] + + (B) Step 6 [Change Clk Speed] + + (C) Step 7 [include delay-wait from early Step 8] + + (D) Step 8a [Cal: CA 800MHz Vmin] + + (E) Step 8b [Write Regs] + + (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?) + + (G) Step 8d [Write Regs] + + (H) Step 9 [Write Regs] + + (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin] + + (J) Step 11 [Write Regs] + + (K) Step 12 [Cal: CA 1200MHz Vnom] + + (L) Step 13 [Write Regs] + + (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin] + + (N) Steps 15,16,17,18,19,20 [need to identify parameterization] + +Between these steps there is possibly a need/desire for: +- Frequency Changes (PMGR) +- PMU save/restore +- debug messages +- register dumps (DV, SiVal) +- anything else! + +CONFIG Table: + Compile-Time Known: + Type of Execution Environment CoreOS, DV, SiVal + Type of Target SoC, FPGA, Palladium + ChipID 0x8000, 0x8001, etc. + Revision A0, B0, B1, etc. + Num DCS 4, 8, etc. (Derived...!) + Variant Flags Work-arounds, RADAR Ref., et al. + + (Config Info know at Compile time can be subject to #if) + + Run-Time Known: + Type of Init ColdBoot, AOP_DDR, AOP_AWAKE + Debug Flags Low-Level, Milestone, et al. + +RegValue Table + Much like today's: various values for various registers + Sensitive to ChipID (also Target type?) + (Internal static alloc (Complete Table Fill-in within Init function): + Fill in Values (per ChipID/Rev & Target-type) + return pointer to caller + (Allows customization by caller before use) + +TODO: +- Convert to using SPDS for register names, et al + +*/ + +//================================================================================ +// API Definitions +#include + +extern dcs_config_t dcs_cfg; +extern dcs_config_params_t dcs_params; + +#if izIBOOT +extern int debug_level_dcs; +#endif + + + +void dcs_enable_autorefresh(void) +{ + uint32_t arefen_freq0 = 0x1011013f; + uint32_t arefen_freq1 = 0x10010000; + + arefen_freq0 = 0x101101ff; + + // Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last. + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), 0x10100000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), 0x10000000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), arefen_freq1); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), arefen_freq0); +} + + + +//================================================================================ +// Implementing the Various Steps of the DCS Init, per Specification +// Based on AMC Init Spec (Spreadsheet) +// - Supporting Maui: Spec (v??) +//================================================================================ +// Step 0: AMC Prolog +//================================================================================ +void dcs_init_Prolog(void) +{ + // NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds + if (izFPGA && izColdBoot) { + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + } +} + +//================================================================================ +// Step 1: AMC Initial Configuration +//================================================================================ +void dcs_init_AMC_Initial_Config(void) +{ + uint32_t i,n; + +// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman + + dcs_reg_write_all_chan(rDCS_SPLLCTRL_CHARGEPUMP, 0x00000068); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_LDO, 0x00000004); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_SPLLPWRDNCFG, 0x00000011); + + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + for (n = 0; n < dcs_params.num_freqchngctl_regs; n++) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim); + } + + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALVREFCODECONTROL, dcs_params.wrdqcalvrefcodecontrol); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALVREFCODECONTROL, dcs_params.rddqcalvrefcodecontrol); + dcs_reg_write_all_chan(rDCS_MCU_MODEREG, 0x120c90b8); + + + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl); + + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat); + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch); + dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref); + dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref); + + if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg); + + } + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params); + dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn); + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate); + + // These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat); + dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000); + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000); + + dcs_reg_write(rAMC_AMCEN, 0x80010001); + dcs_reg_write(rAMC_AIUADDRBANKHASH(2), 0x000036db); + dcs_reg_write(rAMC_AIUADDRBANKHASH(1), 0x00005b6d); + dcs_reg_write(rAMC_AIUADDRBANKHASH(0), 0x00006db6); + dcs_reg_write(rAMC_ADDRMAPMODE, 0x00000002); + dcs_reg_write(rAMC_ADDRCFG, 0x00030201); + +} + +//================================================================================ +// Step 2: AMP Initial Configuration +//================================================================================ +void dcs_init_AMP_Initial_Config(void) +{ + int i; + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref); + + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(0), dcs_params.freq[0].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(1), dcs_params.freq[1].odt_enable); + dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(3), dcs_params.freq[3].odt_enable); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref); + } + + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000); + + if (!izFPGA) + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim); + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001); + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001); + } + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming); + } + + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ0), 0x00000002); + dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ1), 0x00000002); + } + + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(1), dcs_params.rdwrdqcaltimingctrl1); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(2), dcs_params.rdwrdqcaltimingctrl2); + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(0), 0x87654321); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(1), 0xcdedcba9); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(2), 0x456789ab); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(3), 0x5fa63123); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATINVERTMASK, 0x55550000); + + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_MAXRDDQS_SDLL_MULFACTOR, dcs_params.maxrddqssdllmulfactor); + dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQ_SDLL_MULFACTOR, 0x00a00f0f); + dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor); + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000); + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000); + } + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg); + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg); + } + + if (!izFPGA) { + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1); + } + + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), dcs_params.dllupdtintvl); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), dcs_params.dllupdtintvl); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100); + + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCONTROL3, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_DCCCONTROL, dcs_params.dcccontrol); + dcs_reg_write_all_chan(rDCS_AMP_DCCTIMER, 0x00000190); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALDYNHALFCLKDLYCTRL, 0x00000001); + + +// AMPH configuration + + dcs_reg_write_all_chan(rDCS_AMPH_CB_DRIVESTR, dcs_params.cbdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CB_IMPCTL, 0x0f001c2b); + dcs_reg_write_all_chan(rDCS_AMPH_CK_WKPUPD, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMPH_CB_IOCTL, dcs_params.cbioctl); + dcs_reg_write_all_chan(rDCS_AMPH_CK_DRIVESTR, dcs_params.ckdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CK_IOCTL, dcs_params.ckioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DRIVESTR, dcs_params.b0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B0_IOCTL, dcs_params.b0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, dcs_params.b0odt); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODTCTRL, dcs_params.b0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DRIVESTR, dcs_params.b1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODTCTRL, dcs_params.b1odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_IOCTL, dcs_params.b1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, dcs_params.b1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DRIVESTR, dcs_params.dqs0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IOCTL, dcs_params.dqs0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, dcs_params.dqs0odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ZDETBIASEN, dcs_params.dqs0zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODTCTRL, dcs_params.dqs0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DRIVESTR, dcs_params.dqs1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IOCTL, dcs_params.dqs1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, dcs_params.dqs1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ZDETBIASEN, dcs_params.dqs1zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODTCTRL, dcs_params.dqs1odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_DBG_REG0, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(1), dcs_params.zcalfsm1); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(0), dcs_params.zcalfsm0); + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), dcs_params.spare0); + + + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001); + + dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming); + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALTVREF, dcs_params.hwrddqcaltvref); + +} + +//================================================================================ +// Step 3: Self-Refresh Exit +//================================================================================ +void dcs_init_Self_Refresh_Exit_a(void) +{ + // Wait 5 us after Impedence Calibration to avoid McPhyPending + // preventing the SRFSM from exiting SR. + dcs_spin(5, "after Imp. Cal."); + + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + + for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2); + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2); + + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc); + // M8 Bug radar #20346417, two writes to ensure propogation + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030004); + + dcs_reg_write_all_chan(rDCS_MCU_DIV_CLK_SELECT, 0x00000000); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_RECONFIGSWRESETCONTROL, 0x0000003c); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_RECONFIGSWRESETTRIGGER, 0x00000001); + // Wait 20ns + dcs_spin(1, NULL); + dcs_reg_poll(rAMC_PIO_ACCESS_CFG, 0x1, 0x1); + +} + +//======================================== +// Caller Code should: +// - Change Frequency to 50MHz +//======================================== + +void dcs_init_Self_Refresh_Exit_b(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); + + + if (!izFPGA) { + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001); + dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00); + } + + if (izResume) + dcs_enable_autorefresh(); + + dcs_spin(2200, "After Enable Auto-Refresh"); + + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + dcs_spin(2, "After SoC Update"); + } + + // Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh + // Issue self-refresh exit cmd for resume boot with MPC + int n = (izColdBoot)? 0x00000000:0x00004000; + // Issue self-refresh exit cmd for resume boot with MPC + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n); + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1); + dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00); + + dcs_spin(2, NULL); + + dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1); +} + +//================================================================================ +// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only) +//================================================================================ +void dcs_init_ZQ_Cal_Cfg(void) +{ + // ZQ calibration START MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f); + // wait 1us for tZQCAL + dcs_spin(1, "tZQCAL"); + + // ZQ calibration LATCH MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51); + // wait 10ns for tZQLAT + dcs_spin(1, "tZQLAT"); + + if (izColdBoot) { + // MR2 register (read/write latency) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0); + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd); + +// MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x4d); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x4d); + // MR23 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80); + + uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff; + uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I); + + // MR15 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff); + // MR20 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff); + // MR32 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff); + // MR40 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff); + } +} + +//================================================================================ +// Step 5a: AddrConfig Configuration +//================================================================================ +void dcs_init_AddrCfg_Cfg(void) +{ + dcs_reg_write(rAMC_ADDRCFG, dcs_params.addrcfg); + +} + +//======================================== +// Caller Code should: +// - Use MR Cmds to Query the Device +//======================================== + +//================================================================================ +// Step 5b: Total Mem Size Config +//================================================================================ +void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes) +{ + + dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n", + (((uint64_t)total_size_Mbytes) * MEG)); + dcs_reg_write(rAMC_AIUPRTBADDR, dcs_params.aiuprtbaddr); + dcs_reg_write(rAMC_AIUCHNLDEC, dcs_params.chnldec); + +} + +//================================================================================ +// Step 6: Switch from boot-clock speed to normal operation speed +//================================================================================ +void dcs_init_Reenable_AMC_Scheduler(void) +{ + // Wait 5 us before freq change to make sure all refreshes have been flushed + dcs_spin(5, "After Refresh"); + + // Enable (again) the AMC Scheduler + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); +} + +//================================================================================ +// Step 7: Setup registers for CA calibration for bucket 1 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq1(void) +{ + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7); + + if (izColdBoot) { + if (izFPGA) { + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00); + } else { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11); + } + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000); + } +} + +//================================================================================ +// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz +//================================================================================ +void dcs_init_CA_Cal_Freq1(void) +{ + // Nothing to be done at this step for cold boot +} + +//================================================================================ +// Step 9: Setup registers for DQ calibration for bucket 1 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq1_a(void) +{ + int i; + + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9); + } + + dcs_spin(1, NULL); + + if(izResume) { + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C); + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000); + for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000); + } +} + +// Caller code should change frequency to bucket 1 +void dcs_init_DQ_Cal_Setup_Freq1_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 10: PHY write DQ calibration +//================================================================================ +void dcs_init_wrdq_skew(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000); + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000); +} + +void dcs_init_post_wrlvl(void) +{ + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010); + } + +} + +//================================================================================ +// Step 11: Setup registers for CA calibration for bucket 0 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq0(void) +{ + if (izColdBoot) { + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000); + } + + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11); + if (!izFPGA) { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11); + } + + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11); + + if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) { + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000); + } + } +} + +//================================================================================ +// Step 12: AMP Dynamic CA Timing Calibration +//================================================================================ + +//================================================================================ +// Step 13: Setup registers for DQ calibration for bucket 0 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq0_a(void) +{ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13); + + // Wait 1 us + dcs_spin(1, NULL); + } +} + +void dcs_init_DQ_Cal_Setup_Freq0_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 14: AMP Dynamic DQ Calibration +//================================================================================ + +//================================================================================ +// Step 15: Setup Registers for Boot +//================================================================================ +void dcs_init_Reg_for_Boot(void) +{ + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), 0x0000040b); + +#ifndef DCS_RUN_AT_50MHZ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15); + } +#endif + + if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1))) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50); + + // Wait 1 us + dcs_spin(1, NULL); + + if (izColdBoot) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), 0xff000008); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), 0xff000008); + + +#if !DCS_DO_CALIBRATION + // skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + + dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ1), 0x00000000); + + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + } +#endif + } + +} + +//================================================================================ +// Step 16: Enable Other Features +//================================================================================ +void dcs_init_MoreFeatures(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2); + + dcs_reg_write(rAMC_QBREN, 0x00110000); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, 0x00000001); + + if (izColdBoot) + dcs_enable_autorefresh(); + + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL_ASRTIME, dcs_params.b0dyniselasrtime); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL, dcs_params.b0dynisel); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DYN_ISEL, dcs_params.b1dynisel); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DCD_IOCTL, 0x00010000); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DCD_IOCTL, 0x00090000); + + +} + +//================================================================================ +// Step 17: Enable Fast Critical Word Forwarding Feature +//================================================================================ +void dcs_init_Fast_Critical_Word_Forwarding(void) +{ + + uint32_t aiuprt_rd_cwf = 0x00121200; + uint32_t qbrparam2 = 0x00004555; + + if(izFPGA) { + aiuprt_rd_cwf = 0x00000000; + qbrparam2 = 0x00000555; + } + + dcs_reg_write(rAMC_AIUPRT_RD_CWF, aiuprt_rd_cwf); + dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM2, qbrparam2); + dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren); + +} + +//================================================================================ +// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers +//================================================================================ +void dcs_init_Gating_Global_Timers(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk); + + dcs_reg_write_all_chan(rDCS_SPLLCTRL_MDLLPWRDNCFG(0), 0x00000001); + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten); + + if(!izFPGA) { + dcs_reg_write(rAMC_IDLE2BCG_CONTROL, 0x00000001); + dcs_reg_write_all_chan(rDCS_AON_IDLE2BCG_CONTROL, 0x00000001); + dcs_reg_write_all_chan(rDCS_MCU_IDLE_EXTEND_CONTROL, 0x00000001); + dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a1100); + dcs_reg_write(rAMC_PWRMNGTPARAM, 0x001d0140); + dcs_reg_write(rAMC_PSQWQCTL1, 0x00240100); + } + dcs_reg_write_all_chan(rDCS_AMP_DQCALBURSTLENMODE, 0x00000011); + + + // Global Timer Setup + dcs_reg_poll(rGLBTIMER_FREQCHNG_ACTIVE, 0x1, 0x0); + dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0001ff); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x00f000f0); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x00f000f0); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02400240); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02400240); + dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000 + dcs_reg_write(rGLBTIMER_DCCTIMER, 0x000bb8); + dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75 + dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15 + dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6bb); // + dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000 + dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001); // 300000 + dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000 + +} + +//================================================================================ +// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading +//================================================================================ +void dcs_init_ODTS(void) +{ + uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need + // INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank]; + + // MR4 read to bring memory out of self-refresh + dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp); + // M8 Bug radar #20346417, two writes to ensure propogation + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + + // disable full scan calibrations + if(!izFPGA) + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000); +} + +//================================================================================ diff --git a/platform/t8002/dcs/rules.mk b/platform/t8002/dcs/rules.mk new file mode 100644 index 0000000..78bb5bf --- /dev/null +++ b/platform/t8002/dcs/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DCS=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dcs.o \ + $(LOCAL_DIR)/dcs_init_lib_t8002.o diff --git a/platform/t8002/include/platform/dcsconfig.h b/platform/t8002/include/platform/dcsconfig.h new file mode 100644 index 0000000..0e9e63a --- /dev/null +++ b/platform/t8002/include/platform/dcsconfig.h @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCSCONFIG_H +#define __DCSCONFIG_H + +// Needful defnitions for the initializers below +#include +#include +#include +#include + +dcs_config_params_t dcs_params = { + .supported_freqs = DCS_FREQ(0) | DCS_FREQ(3), + .num_freqchngctl_regs = 5, + .spllctrl_vco_1 = 0x00000018, + .spllctrl_vco_2 = 0x00000015, + .wrdqcalvrefcodecontrol = 0x0d000019, + .rddqcalvrefcodecontrol = 0x0d000099, + .dllupdtctrl = 0x50017350, + .modereg = 0x120c80a4, + .autoref_params = 0x0015005d, + .pdn = 0x72274284, + .rnkcfg = 0x00006061, + .casdllupdatectrl = 0x03030305, + .dqsdllupdatectrl = 0x00030005, + .rdsdllctrl_step2 = 0x00ff0002, + .wrdqdqssdllctrl_step2 = 0xff000002, + .cawrlvlsdllcode = 0x00ff01ff, + .dlllocktim = 0x00c801f4, + .rdwrdqcaltiming_f0 = 0x01040304, + .rdwrdqcaltiming_f1 = 0x01040402, + .rdwrdqcaltimingctrl1 = 0x0000381e, + .rdwrdqcaltimingctrl2 = 0x01100e01, + .rddqcalpatprbs4i = 0x55553c5a, + .wrdqcalpatprbs4i = 0x00003c5a, + .maxrddqssdllmulfactor = 0x00a00c0c, + .maxwrdqssdllmulfactor = 0xa0a00c0d, + .dllupdtctrl1 = 0x80017580, + .dllupdtintvl = 0x10200020, + .dcccontrol = 0x10050b27, + .cbdrivestr = 0x33838317, + .cbioctl = 0x00020021, + .ckdrivestr = 0x33838317, + .ckioctl = 0x00000021, + .b0drivestr = 0x33838317, + .b0ioctl = 0x71500021, + .b0odt = 0x01c00339, + .b0odtctrl = 0x00000007, + .b1drivestr = 0x33838317, + .b1ioctl = 0x71500021, + .b1odt = 0x01c00339, + .b1odtctrl = 0x00000007, + .dqs0drivestr = 0x33838317, + .dqs0ioctl = 0x71500021, + .dqs0odt = 0x01c00339, + .dqs0zdetbiasen = 0x00060928, + .dqs0odtctrl = 0x00000007, + .dqs1drivestr = 0x33838317, + .dqs1ioctl = 0x71500021, + .dqs1odt = 0x01c00339, + .dqs1zdetbiasen = 0x00060928, + .dqs1odtctrl = 0x00000007, + .zcalfsm1 = 0x005b7f7f, + .zcalfsm0 = 0x000f0333, + .spare0 = 0x0000000b, + .dficaltiming = 0x05000504, + .hwrddqcaltvref = 0x08080808, + .arefparam = 0x0d012019, + .autoref_params2 = 0x0015005d, + .odtszqc = 0x00003000, + .longsr = 0x01022008, + .freqchngctl_step3 = 0x01010000, + .mr3cmd = 0xf2, + .mr13cmd = 0x18, + .addrcfg = 0x00030201, + .aiuprtbaddr = 0x00000010, + .chnldec = 0x00050101, + // steps 7-10 are skipped for M8 since freq bucket 1 not used + .mr13cmd_step11 = 0x58, + .mr2cmd_step11 = 0x1b, + .mr1cmd_step11 = 0xbe, + .mr3cmd_step11 = 0xb2, + .mr22cmd_step11 = 0x03, + .mr11cmd_step11 = 0x33, + .mr12cmd_step11 = 0x19, + .mr14cmd_step11 = 0x19, + .mr13cmd_step13 = 0x98, + .mr13cmd_step15 = 0x90, + .freqchngctl_step15 = 0x00009009, + .rdsdllctrl_step15 = 0x001d0004, + .odtszqc2 = 0xc0003000, + .b0dyniselasrtime = 0x00000014, + .b0dynisel = 0x00000001, + .b1dynisel = 0x00000009, + .qbrparam = 0x00000000, + .qbren = 0x00000003, + .caampclk = 0x11000000, + .dqampclk = 0x11000000, + .pwrmngten = 0x00000133, + .odtszqc3 = 0xc0003320, + + .freq = { + { // 1066MHz + .clk_period = CLK_PERIOD_1600, + .freqchngctl = {0x18cd104d, 0x190c190e, 0xb203330b, 0xbe011b02, 0x00000316}, + .freqchngtim = 0x000c1108, + .lat = 0x00103285, + .phyrdwrtim = 0x00040c08, + .caspch = 0x43d7060a, + .act = 0x16060c0a, + .autoref = 0x30600078, + .selfref = 0x6b064012, + .derate = 0x34b3760b, + .lat2 = 0x00112285, + .tat = 0x01312222, + .mifqmaxctrl = 0x00000100, + .cavref = 0x00000003, + .odt_enable = 0x00000001, + .dqvref = 0x00cb00cb, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00ff01d1, + .wrdqcalwindow = 0x00ff0160, + .rdcapcfg = 0x0100070c, + .autoref2 = 0x30600070, + }, + { // 800MHz + .freqchngctl = {0x18cd104d, 0x110c110e, 0xd303220b, 0xae015202, 0x00000216}, + .freqchngtim = 0x000c1108, + .lat = 0x00112206, + .phyrdwrtim = 0x00050b06, + .caspch = 0x42110408, + .act = 0x10040908, + .autoref = 0x24480050, + .selfref = 0x5004b012, + .derate = 0x28835488, + .lat2 = 0x00112206, + .tat = 0x01312222, + .cavref = 0x00000000, + .odt_enable = 0x00000001, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rddqcalwindow = 0x00ff01d1, + .wrdqcalwindow = 0x00ff0160, + .rdcapcfg = 0x2100060a, + .autoref2 = 0x24480054, + }, + { // 200MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010b01, + .caspch = 0x40c50402, + .act = 0x04020302, + .autoref = 0x09120014, + .selfref = 0x28013012, + .derate = 0x0c212142, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .cavref = 0x00000000, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rdcapcfg = 0x41000406, + .autoref2 = 0x09120015, + }, + { // 50MHz + .freqchngctl = {0x18cd104d, 0x4d0c4d0e, 0xf203000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010901, + .caspch = 0x40c20402, + .act = 0x01020404, + .autoref = 0x03050005, + .selfref = 0x28005012, + .derate = 0x10412082, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .mifqmaxctrl = 0x00000001, + .cavref = 0x00000003, + .odt_enable = 0x00000000, + .dqvref = 0x00000000, + .cadficaltiming = 0x04000410, + .dqdficaltiming = 0x04020402, + .rdcapcfg = 0x61000406, + .autoref2 = 0x03050005, + } + } +}; + +#define BIT32_MASKFULL (0xFFFFFFFF) +#define BIT32_MASK(_n) (BIT32_MASKFULL >> (32 - (_n))) +#define BIT32_MASK_VAL(_h,_l,_d) (((_d) & BIT32_MASK((_h) - (_l) + 1)) << (_l)) +#define BIT32_MASK_HI_LO(_h,_l) BIT32_MASK_VAL(_h,_l,BIT32_MASKFULL) +#define DCS_MASK_VAL(_h,_l,_d) BIT32_MASK_HI_LO(_h,_l) , BIT32_MASK_VAL(_h,_l,_d) + +// M8 A0 Tunables Specs: +// https://seg-docs.ecs.apple.com/projects/m8//release/UserManual/tunables/amc.html dated 1/16/2015 20:07:00 +// https://seg-docs.ecs.apple.com/projects/m8//release/UserManual/tunables/amcsys_aon.html dated 1/16/2015 20:06:27 +// https://seg-docs.ecs.apple.com/projects/m8//release/UserManual/tunables/amcx.html dated 1/16/2015 11:49:17 +// https://seg-docs.ecs.apple.com/projects/m8//release/UserManual/tunables/dcsh_aon.html dated 1/2/2015 00:30:12 +// https://seg-docs.ecs.apple.com/projects/m8//release/UserManual/tunables/ampsca.html dated 1/14/2015 19:42:28 +// https://seg-docs.ecs.apple.com/projects/m8//release/UserManual/tunables/AMPSDQ0.html dated 1/14/2015 19:44:46 +// https://seg-docs.ecs.apple.com/projects/m8//release/UserManual/tunables/AMPSDQ1.html dated 1/14/2015 19:44:46 +const dcs_tunable_t dcs_tunables[] = { + + // AMCSYS + { rAMC_AIUPRT_RD_GEN, DCS_MASK_VAL(3, 3, 0x1) }, + { rAMC_AIUADDRBANKHASH(0), DCS_MASK_VAL(14, 0, 0x6db6) }, + { rAMC_AIUADDRBANKHASH(1), DCS_MASK_VAL(14, 0, 0x5b6d) }, + { rAMC_AIUADDRBANKHASH(2), DCS_MASK_VAL(14, 0, 0x36db) }, + + { rAMC_AIUCHNLTM, DCS_MASK_VAL(24, 20, 0x10) }, + { rAMC_AIUCHNLTM, DCS_MASK_VAL(16, 16, 0x1) }, + { rAMC_AIUCHNLTM, DCS_MASK_VAL(14, 14, 0x0) }, + { rAMC_AIUCHNLTM, DCS_MASK_VAL(13, 13, 0x1) }, + { rAMC_AIUCHNLTM, DCS_MASK_VAL(12, 12, 0x1) }, + { rAMC_AIUCHNLTM, DCS_MASK_VAL(8, 4, 0x10) }, + { rAMC_AIUCHNLTM, DCS_MASK_VAL(0, 0, 0x1) }, + + { rAMC_AIURDBRSTLEN, DCS_MASK_VAL(30, 28, 0x1) }, + { rAMC_AIURDBRSTLEN, DCS_MASK_VAL(26, 24, 0x1) }, + { rAMC_AIURDBRSTLEN, DCS_MASK_VAL(18, 16, 0x1) }, + { rAMC_AIURDBRSTLEN, DCS_MASK_VAL(10, 8, 0x1) }, + { rAMC_AIURDBRSTLEN, DCS_MASK_VAL(2, 0, 0x1) }, + + { rAMC_AIURDMAXCRD, DCS_MASK_VAL(30, 24, 0x30) }, + { rAMC_AIURDMAXCRD, DCS_MASK_VAL(22, 16, 0x8) }, + { rAMC_AIURDMAXCRD, DCS_MASK_VAL(14, 8, 0xc) }, + { rAMC_AIURDMAXCRD, DCS_MASK_VAL(6, 0, 0x7f) }, + + { rAMC_AIURDREFL, DCS_MASK_VAL(30, 24, 0x28) }, + { rAMC_AIURDREFL, DCS_MASK_VAL(22, 16, 0x7) }, + { rAMC_AIURDREFL, DCS_MASK_VAL(14, 8, 0xa) }, + { rAMC_AIURDREFL, DCS_MASK_VAL(6, 0, 0x7f) }, + + { rAMC_AIUWRBRSTLEN, DCS_MASK_VAL(30, 28, 0x1) }, + { rAMC_AIUWRBRSTLEN, DCS_MASK_VAL(26, 24, 0x1) }, + { rAMC_AIUWRBRSTLEN, DCS_MASK_VAL(18, 16, 0x1) }, + { rAMC_AIUWRBRSTLEN, DCS_MASK_VAL(10, 8, 0x1) }, + { rAMC_AIUWRBRSTLEN, DCS_MASK_VAL(2, 0, 0x1) }, + + { rAMC_AIUWRMAXCRD, DCS_MASK_VAL(30, 24, 0x30) }, + { rAMC_AIUWRMAXCRD, DCS_MASK_VAL(22, 16, 0x8) }, + { rAMC_AIUWRMAXCRD, DCS_MASK_VAL(14, 8, 0xc) }, + { rAMC_AIUWRMAXCRD, DCS_MASK_VAL(6, 0, 0x7f) }, + + { rAMC_AIUWRREFL, DCS_MASK_VAL(30, 24, 0x28) }, + { rAMC_AIUWRREFL, DCS_MASK_VAL(22, 16, 0x7) }, + { rAMC_AIUWRREFL, DCS_MASK_VAL(14, 8, 0xa) }, + { rAMC_AIUWRREFL, DCS_MASK_VAL(6, 0, 0x7f) }, + + { rAMC_AIUCPUSPCREQ, DCS_MASK_VAL(9, 0, 0x13) }, + { rAMC_AIUGRXSPCREQ, DCS_MASK_VAL(9, 0, 0x19) }, + { rAMC_AIUNRTSPCREQ, DCS_MASK_VAL(9, 0, 0x19) }, + { rAMC_AIURLTSPCREQ, DCS_MASK_VAL(9, 0, 0x13) }, + + { rAMC_AIUWPQSCH, DCS_MASK_VAL(30, 24, 0x8) }, + { rAMC_AIUWPQSCH, DCS_MASK_VAL(14, 8, 0x8) }, + + { rAMC_AIUTHOTLEN, DCS_MASK_VAL(5, 5, 0x1) }, + { rAMC_AIUTHOTLEN, DCS_MASK_VAL(4, 4, 0x1) }, + + { rAMC_AIUTHOTLCPUPARAM, DCS_MASK_VAL(10, 4, 0x8) }, + { rAMC_AIUTHOTLCPUPARAM, DCS_MASK_VAL(2, 2, 0x1) }, + + { rAMC_AIUTHOTLRLTPARAM, DCS_MASK_VAL(10, 4, 0x8) }, + { rAMC_AIUTHOTLRLTPARAM, DCS_MASK_VAL(2, 2, 0x1) }, + + { rAMC_AIUTHOTLNRTPARAM, DCS_MASK_VAL(10, 4, 0x8) }, + { rAMC_AIUTHOTLGRXPARAM, DCS_MASK_VAL(10, 4, 0x8) }, + + { rAMC_AIUPUSHEN, DCS_MASK_VAL(12, 12, 0x1) }, + { rAMC_AIUPUSHEN, DCS_MASK_VAL(8, 8, 0x1) }, + + { rAMC_AIUTHOTLCPUPARAM2, DCS_MASK_VAL(23, 23, 0x1) }, + { rAMC_AIUTHOTLCPUPARAM2, DCS_MASK_VAL(22, 22, 0x1) }, + { rAMC_AIUTHOTLCPUPARAM2, DCS_MASK_VAL(10, 4, 0x4) }, + + { rAMC_AIUTHOTLRLTPARAM2, DCS_MASK_VAL(23, 23, 0x1) }, + { rAMC_AIUTHOTLRLTPARAM2, DCS_MASK_VAL(22, 22, 0x1) }, + { rAMC_AIUTHOTLRLTPARAM2, DCS_MASK_VAL(10, 4, 0x4) }, + + { rAMC_AIUTHOTLNRTPARAM2, DCS_MASK_VAL(10, 4, 0x4) }, + { rAMC_AIUTHOTLGRXPARAM2, DCS_MASK_VAL(10, 4, 0x4) }, + + { rAMC_AIULLTSCHCTL, DCS_MASK_VAL(0, 0, 0x1) }, + { rAMC_AIURDMAXCRD2, DCS_MASK_VAL(6, 0, 0x12) }, + { rAMC_AIURDREFL2, DCS_MASK_VAL(6, 0, 0xf) }, + { rAMC_AIUWRMAXCRD2, DCS_MASK_VAL(6, 0, 0x12) }, + { rAMC_AIUWRMAXCRD2, DCS_MASK_VAL(6, 0, 0x12) }, + { rAMC_AIUWRREFL2, DCS_MASK_VAL(6, 0, 0xf) }, + { rAMC_AIUMEDSPCREQ, DCS_MASK_VAL(9, 0, 0x19) }, + { rAMC_AIUTHOTLMEDPARAM, DCS_MASK_VAL(10, 4, 0x8) }, + { rAMC_AIUTHOTLMEDPARAM2, DCS_MASK_VAL(10, 4, 0x4) }, + { rAMC_PSQRQCTL0, DCS_MASK_VAL(31, 24, 0x1) }, + + { rAMC_PSQRQCTL1, DCS_MASK_VAL(9, 9, 0x1) }, + { rAMC_PSQRQCTL1, DCS_MASK_VAL(5, 5, 0x1) }, + { rAMC_PSQRQCTL1, DCS_MASK_VAL(3, 3, 0x1) }, + { rAMC_PSQRQCTL1, DCS_MASK_VAL(1, 1, 0x1) }, + + { rAMC_PSQRQTIMER(0), DCS_MASK_VAL(11, 0, 0xa) }, + { rAMC_PSQRQTIMER(1), DCS_MASK_VAL(11, 0, 0x5) }, + { rAMC_PSQRQTIMER(2), DCS_MASK_VAL(11, 0, 0x20) }, + + { rAMC_PSQRQBRST, DCS_MASK_VAL(28, 24, 0x4) }, + { rAMC_PSQRQBRST, DCS_MASK_VAL(12, 8, 0x4) }, + + { rAMC_PSQRQSCHCRD, DCS_MASK_VAL(23, 16, 0x20) }, + { rAMC_PSQRQSCHCRD, DCS_MASK_VAL(15, 8, 0x28) }, + + { rAMC_PSQWQCTL1, DCS_MASK_VAL(31, 16, 0x24) }, + { rAMC_PSQWQCTL1, DCS_MASK_VAL(15, 0, 0xbb) }, + + { rAMC_PSQWQBRST, DCS_MASK_VAL(28, 24, 0x2) }, + { rAMC_PSQWQBRST, DCS_MASK_VAL(20, 16, 0x2) }, + { rAMC_PSQWQBRST, DCS_MASK_VAL(12, 8, 0x2) }, + { rAMC_PSQWQBRST, DCS_MASK_VAL(4, 0, 0x8) }, + + { rAMC_PSQWQSCHCRD, DCS_MASK_VAL(23, 16, 0x4) }, + { rAMC_PSQWQSCHCRD, DCS_MASK_VAL(15, 8, 0x5) }, + + { rAMC_MCUQOS, DCS_MASK_VAL(16, 16, 0x1) }, + + { rAMC_MCUQOSLLT, DCS_MASK_VAL(16, 16, 0x1) }, + { rAMC_MCUQOSLLT, DCS_MASK_VAL(4, 0, 0x8) }, + + { rAMC_ADDRMAPMODE, DCS_MASK_VAL(2, 0, 0x2) }, + + { rAMC_PWRMNGTPARAM, DCS_MASK_VAL(31, 16, 0x30) }, + { rAMC_PWRMNGTPARAM, DCS_MASK_VAL(15, 0, 0xfa) }, + + { rAMC_IDLE2BCG_CONTROL, DCS_MASK_VAL(0, 0, 0x1) }, + + // AMCX + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL(8, 8, 0x1) }, + + { rDCS_MCU_IDLE_EXTEND_CONTROL, DCS_MASK_VAL(0, 0, 0x1) }, + + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL(31, 16, 0x4002) }, + { rDCS_MCU_ROWHAM_CTL(0), DCS_MASK_VAL(0, 0, 0x1) }, + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(31, 16, 0x4a38) }, + { rDCS_MCU_ROWHAM_CTL(1), DCS_MASK_VAL(15, 0, 0x22d4) }, + { rDCS_MCU_ROWHAM_CTL(2), DCS_MASK_VAL(15, 0, 0x4a33) }, + + // DCSH_AON + { rDCS_AON_IDLE2BCG_CONTROL, DCS_MASK_VAL(0, 0, 0x1) }, + + // AMSPCA + { rDCS_AMP_AMPCLK(AMP_CA), DCS_MASK_VAL(28, 28, 0x0) }, + { rDCS_AMP_AMPCLK(AMP_CA), DCS_MASK_VAL(24, 24, 0x0) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(0), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(1), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(2), DCS_MASK_VAL(15, 0, 0x3) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(31, 16, 0x2) }, + { rDCS_AMP_RDWRDQCALSEGLEN_F(3), DCS_MASK_VAL(15, 0, 0x3) }, + + // AMPSDQ + { rDCS_AMP_AMPCLK(AMP_DQ0), DCS_MASK_VAL(28, 28, 0x0) }, + { rDCS_AMP_AMPCLK(AMP_DQ0), DCS_MASK_VAL(24, 24, 0x0) }, + { rDCS_AMP_AMPCLK(AMP_DQ1), DCS_MASK_VAL(28, 28, 0x0) }, + { rDCS_AMP_AMPCLK(AMP_DQ1), DCS_MASK_VAL(24, 24, 0x0) }, +}; + +#endif diff --git a/platform/t8002/include/platform/dmin.h b/platform/t8002/include/platform/dmin.h new file mode 100644 index 0000000..1495889 --- /dev/null +++ b/platform/t8002/include/platform/dmin.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + /* + * Dmin.h is provided by the diags team, defining the 'DMin' key's format + * The contents below are copy-pasted verbatim from header files supplied by Diags. + */ + + +#ifndef _DMin_h_ +#define _DMin_h_ + +/* vim: set ts=4 sw=4 softtabstop=4 noexpandtab */ + +#include + +#ifndef MULTICHARACTER_LITERAL +# define MULTICHARACTER_LITERAL(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) +#endif + +enum { + kEnclosureNone = 0, + kEnclosureAlumLight6063 = 1, + kEnclosureAlumDark6063 = 2, + kEnclosureAlumLight7003 = 3, + kEnclosureAlumDark7003 = 4, + kEnclosureSUSMirror = 5, + kEnclosureSUSBrushed = 6, + kEnclosureSUSBlackPVD = 7, + kEnclosureMaverickYellow = 8, + kEnclosureMaverickRose = 9, + kEnclosureZirconiaWhite = 10, + kEnclosureGlass = 11, +}; +typedef uint32_t EnclosureType_t; // goes with above enum + +enum { + kFCMTypeNone = 0, + kFCMTypeOnyx = 1, + kFCMTypeGlass = 2, +}; +typedef uint32_t FCMType_t; // goes with above + +enum { + kBCMWindowTypeNone = 0, + kBCMWindowTypeOnyx = 1, + kBCMWindowTypeGlass = 2, +}; +typedef uint32_t BCMWindowType_t; + +enum { + kBCMLensTypeNone = 0, + kBCMLensTypeNormal = 1, + kBCMLensTypeFresnel = 2, +}; +typedef uint32_t BCMLensType_t; + +enum { + kBCMLEDTypeNone = 0, + kBCMLEDTypeNormal = 1, + kBCMLEDTypeNew = 2, +}; +typedef uint32_t BCMPTLEDType_t; + +enum { + kBCMPlatinumTypeNone = 0, + kBCMPlatinumTypeProtoN_34 = 1, + kBCMPlatinumTypeProtoC = 2, +}; +typedef uint32_t BCMPTSensorType_t; + +/* Version 2 information - added Lisa Bits */ + +enum { + kLisaOpAmpNone = 0, + kLisaOpAmpMAX4321 = 1, + kLisaOpAmpLMV693 = 2, + kLisaOpAmpLMV881 = 3, +}; +typedef uint32_t LisaOpAmpType_t; + +enum { + kLisaSensorICNone = 0, + kLisaSensorICA0 = 1, + kLisaSensorICB0 = 2, +}; +typedef uint32_t LisaSensorICType_t; + +enum { + kLisaWheelNone = 0, + kLisaWheelLF31 = 1, + kLisaWheelLF31LowDiffusion = 2, + kLisaWheelLF31HighStripeVar = 3, + kLisaWheelLF31pSLaser = 4, + kLisaWheelLF45 = 5, + kLisaWheelSantek = 6, + kLisaWheelNisseiBlack = 7, + kLisaWheelNissei = 8, + kLisaWheelHeptagonGrind = 9, + kLisaWheelHeptagonFormed = 10 +}; +typedef uint32_t LisaWheelType_t; + +enum { + kLisaKnurlNone = 0, + kLisaKnurlProtoN = 1, +}; +typedef uint32_t LisaKnurlType_t; + +/* Pack the structure, do not allow compiler padding */ +typedef struct __attribute__((packed)) { + EnclosureType_t topEnclosure; // See enum at the top + EnclosureType_t botEnclosure; // Same values here + FCMType_t fcmType; // Onyx or Glass + uint32_t fcmARCoated; // 0x00000000 = no AR coating, 0x00000001 = AR coating + uint32_t fcmInkColor; // 0x00RRGGBB (little endian, 32-bit word, just like DClr) + BCMWindowType_t bcmWindow; // Onyx or Glass + BCMLensType_t bcmLens; // Normal or Fresnel + BCMPTSensorType_t bcmPTSensorType; // 3 or 4 + BCMPTLEDType_t bcmPTLEDType; // Normal or "New" +} DMin_v1_t; + +typedef struct __attribute__((packed)) { + EnclosureType_t topEnclosure; // See enum at the top + EnclosureType_t botEnclosure; // Same values here + FCMType_t fcmType; // Onyx or Glass + uint32_t fcmARCoated; // 0x00000000 = no AR coating, 0x00000001 = AR coating + uint32_t fcmInkColor; // 0x00RRGGBB (little endian, 32-bit word, just like DClr) + BCMWindowType_t bcmWindow; // Onyx or Glass + BCMLensType_t bcmLens; // Normal or Fresnel + BCMPTSensorType_t bcmPTSensorType; // 3 or 4 + BCMPTLEDType_t bcmPTLEDType; // Normal or "New" + + // v2 bits + LisaOpAmpType_t lisaOAType; + LisaSensorICType_t lisaSensorIC; + LisaWheelType_t lisaEncoderWheel; + LisaKnurlType_t lisaKnurl; +} DMin_v2_t; + +#define DMIN_VERSION_1 0x00000001 +#define DMIN_VERSION_2 0x00000002 + +typedef struct { + uint32_t version; // Set to DMIN_VERSION_2 + union { + DMin_v1_t v1; // if version == DMIN_VERSION_1, use this struct + DMin_v2_t v2; // if version == DMIN_VERSION_2, use this struct + }; // Anonymous union to bridge between v1 and any later version +}DMin_t; + +#define SYSCFG_DEVICE_MATERIAL_INFO_SIZE (sizeof(DMin_t)) /* v1 = 40 bytes, v2 = 56 bytes */ +#define SYSCFG_DEVICE_MATERIAL_INFO MULTICHARACTER_LITERAL('D','M','i','n') + +#endif /* _DMin_h_ */ diff --git a/platform/t8002/include/platform/dockchannel_config.h b/platform/t8002/include/platform/dockchannel_config.h new file mode 100644 index 0000000..cadc0ae --- /dev/null +++ b/platform/t8002/include/platform/dockchannel_config.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __DOCKCHANNEL_CONFIG_H +#define __DOCKCHANNEL_CONFIG_H + +#include +#include + +// These values can also be read out from DC_HWCFG register but is fixed for a particular Dockchannel instance +#define DOCKCHANNEL_MAX_AGENTS (4) +#define DOCKCHANNEL_MAX_CHANNELS (5) + +// Allocation of agents as per AOP Spec +// https://seg-docs.ecs.apple.com/projects/m8//release/specs/Apple/AOP/M8%20AOP%20Microarchitecture%20Specification.pdf +#define DOCKCHANNEL_DOCK_AGENT_ID (0) +#define DOCKCHANNEL_AP_AGENT_ID (1) +#define DOCKCHANNEL_AOP_AGENT_ID (2) +#define DOCKCHANNEL_RTP_AGENT_ID (3) + +// Software allocation of channels. UART channel is 0 and needs to be the same as what kanzi firmware +// uses. Kanzi firmware separates out SWD communication and UART data, and presents a virtual uart device +// to users. +// The channels are decided by us and we need to make sure the consumers, in this case kanzi or OS driver +// for DockChannel is setup as per these assignments +#define DOCKCHANNEL_UART (0) +#define DOCKCHANNEL_DIAGS (1) +#define DOCKCHANNEL_UNUSED_1 (2) +#define DOCKCHANNEL_UNUSED_2 (3) +#define DOCKCHANNEL_RTP (4) + +#endif /* __DOCKCHANNEL_CONFIG_H */ diff --git a/platform/t8002/include/platform/gpiodef.h b/platform/t8002/include/platform/gpiodef.h new file mode 100644 index 0000000..a7fc575 --- /dev/null +++ b/platform/t8002/include/platform/gpiodef.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +/* T8002 specific gpio -> pin mappings */ + +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +/* define platform-specific gpios in a generic fashion here. */ +#define GPIO_BOARD_ID0 GPIOC(GPIO_AP, 8, 1) +#define GPIO_BOARD_ID1 GPIOC(GPIO_AP, 8, 2) +#define GPIO_BOARD_ID2 GPIOC(GPIO_AP, 8, 3) +#define GPIO_BOARD_ID3 GPIOC(GPIO_AP, 0, 6) + +#define GPIO_BOOT_CONFIG0 GPIOC(GPIO_AP, 0, 2) +#define GPIO_BOOT_CONFIG1 GPIOC(GPIO_AP, 0, 3) +#define GPIO_BOOT_CONFIG2 GPIOC(GPIO_AP, 0, 4) + +#define BOOT_CONFIG_SPI0 (0) +#define BOOT_CONFIG_SPI0_TEST (1) +#define BOOT_CONFIG_ANS (2) +#define BOOT_CONFIG_ANS_TEST (3) +#define BOOT_CONFIG_SLOW_SPI0_TEST (6) + +#define GPIO_BOARD_REV0 GPIOC(GPIO_AP, 0, 7) +#define GPIO_BOARD_REV1 GPIOC(GPIO_AP, 1, 0) +#define GPIO_BOARD_REV2 GPIOC(GPIO_AP, 1, 1) +#define GPIO_BOARD_REV3 GPIOC(GPIO_AP, 1, 2) + +#define GPIO_REQUEST_DFU1 GPIOC(GPIO_AP, 12, 4) +#define GPIO_REQUEST_DFU2 GPIOC(GPIO_AP, 12, 5) +#define GPIO_FORCE_DFU GPIOC(GPIO_AP, 12, 6) +#define GPIO_DFU_STATUS GPIOC(GPIO_AP, 17, 0) +#define GPIO_DOCK_CONNECT GPIOC(GPIO_AOP, 0, 6) +#define GPIO_DOCK_ATTENTION GPIOC(GPIO_AOP, 0, 7) + +#define SPI_NOR0 (0) + +#define GPIO_SPI0_CS GPIOC(GPIO_AP, 8, 4) +#define GPIO_SPI0_SSIN GPIO_SPI0_CS +#define GPIO_SPI0_SCLK GPIOC(GPIO_AP, 8, 1) +#define GPIO_SPI0_MOSI GPIOC(GPIO_AP, 8, 2) +#define GPIO_SPI0_MISO GPIOC(GPIO_AP, 8, 3) + +#define GPIO_NAND_CEN0 GPIOC(GPIO_AP, 2, 5) +#define GPIO_NAND_CEN1 GPIOC(GPIO_AP, 2, 6) +#define GPIO_NAND_CLE GPIOC(GPIO_AP, 4, 1) +#define GPIO_NAND_ALE GPIOC(GPIO_AP, 4, 2) +#define GPIO_NAND_REN GPIOC(GPIO_AP, 3, 3) +#define GPIO_NAND_WEN GPIOC(GPIO_AP, 4, 0) +#define GPIO_NAND_IO0 GPIOC(GPIO_AP, 3, 7) +#define GPIO_NAND_IO1 GPIOC(GPIO_AP, 3, 6) +#define GPIO_NAND_IO2 GPIOC(GPIO_AP, 3, 5) +#define GPIO_NAND_IO3 GPIOC(GPIO_AP, 3, 4) +#define GPIO_NAND_IO4 GPIOC(GPIO_AP, 3, 2) +#define GPIO_NAND_IO5 GPIOC(GPIO_AP, 3, 1) +#define GPIO_NAND_IO6 GPIOC(GPIO_AP, 3, 0) +#define GPIO_NAND_IO7 GPIOC(GPIO_AP, 2, 7) + +#define GPIO_IIC0_SCL GPIOC(GPIO_AP, 9, 2) +#define GPIO_IIC0_SDA GPIOC(GPIO_AP, 9, 1) +#define GPIO_IIC1_SCL GPIOC(GPIO_AP, 9, 4) +#define GPIO_IIC1_SDA GPIOC(GPIO_AP, 9, 3) +#define GPIO_IIC2_SCL GPIOC(GPIO_AP, 9, 6) +#define GPIO_IIC2_SDA GPIOC(GPIO_AP, 9, 5) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/t8002/include/platform/image_devices.h b/platform/t8002/include/platform/image_devices.h new file mode 100644 index 0000000..d9c5c2d --- /dev/null +++ b/platform/t8002/include/platform/image_devices.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_HW_ASP) + { "asp_fw", 0x00000 } +#elif defined(WITH_ANC_FIRMWARE) + { "anc_firmware", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 } +#else + { "nor0", 0x00000 } +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/t8002/include/platform/memconfig.h b/platform/t8002/include/platform/memconfig.h new file mode 100644 index 0000000..53cf08a --- /dev/null +++ b/platform/t8002/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* Stub */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/t8002/include/platform/memmap.h b/platform/t8002/include/platform/memmap.h new file mode 100644 index 0000000..7e8dbcc --- /dev/null +++ b/platform/t8002/include/platform/memmap.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +#include + +/* T8002 specific memory map */ + +/////////////////////////////////////////////////////////////////////////////////// +// 0x80000000 + dram_size --> ------------------------------- +// | TZ0 (varies) | +// |-----------------------------| +// | ASP (5 MiB) | +// |-----------------------------| +// | Consistent Debug (16KiB) | +// |-----------------------------| +// | Sleep Token Buffer (4KiB) | +// |-----------------------------| +// | DRAM Config Sequence (16KiB)| +// |-----------------------------| +// | Panic (512KiB) | +// |-----------------------------| +// | Display (16MiB) | +// | (Framebuffer + scratch) | +// | | +// | | +// | | +// |-----------------------------| +// | iBoot (32MiB) | +// | (Text + Data + Stacks ) | +// | (Page Tables + Heap) | +// | | +// |-----------------------------| <-- 0x80000000 + dram_size - 64MB +// | Unused | +// | | +// | | +// | | +// | | +// |-----------------------------| +// | | +// | (Ramdisk) | +// | (Kernel + DeviceTree) | +// | Secure memory | +// |-----------------------------| +// | | +// | | +// | Load region / | +// | Insecure Memory | +// | (overlaps with TZ0) | +// | | |-----------------------| +// | | | TZ0 (varies | +// 0x80000000 --> ------------------------------- ------------------------- +/////////////////////////////////////////////////////////////////////////////////// + +#define SDRAM_BASE (0x80000000ULL) +#define SDRAM_BANK_LEN (SDRAM_LEN) +#define SDRAM_BANK_COUNT (1) +#define SDRAM_END (SDRAM_BASE + SDRAM_LEN) + +#define VROM_BASE (0x40000000ULL) +#define VROM_BANK_LEN (0x00100000ULL) +#define VROM_LEN (0x00040000ULL) + +#define SRAM_BASE (0x48800000ULL) +#define SRAM_LEN (0x00120000ULL) +#define SRAM_BANK_LEN (SRAM_LEN) +#define SRAM_BANK_COUNT (1) +#define SRAM_END (SRAM_BASE + SRAM_LEN) + +#define IO_BASE (0x40000000ULL) +#define IO_SIZE (0x20000000ULL) + +/* custom ROM is stored at first physical page DRAM, and booted by enabling remap */ +#define SECUREROM_LOAD_ADDRESS (SDRAM_BASE) + +// Reserved for TZ0/SEP +// TZ0_SIZE is defined by the platform or target makefile +#define TZ0_BASE (SDRAM_END - TZ0_SIZE) + +/* reserved area for ASP */ +#define ASP_SIZE (0x00500000ULL) +#define ASP_BASE (TZ0_BASE - ASP_SIZE) + +#define CONSISTENT_DEBUG_SIZE (0x00004000ULL) +#define CONSISTENT_DEBUG_BASE (ASP_BASE - CONSISTENT_DEBUG_SIZE) + +/* reserved area for sleep token info */ +#define SLEEP_TOKEN_BUFFER_SIZE (0x00001000ULL) +#define SLEEP_TOKEN_BUFFER_BASE (CONSISTENT_DEBUG_BASE - SLEEP_TOKEN_BUFFER_SIZE) + +/* reserved area for config sequence region */ +#define DRAM_CONFIG_SEQ_SIZE (0x00004000ULL) +#define DRAM_CONFIG_SEQ_BASE (SLEEP_TOKEN_BUFFER_BASE - DRAM_CONFIG_SEQ_SIZE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00080000ULL) +#define PANIC_BASE (DRAM_CONFIG_SEQ_BASE - PANIC_SIZE) + +/* reserved area for display + * DISPLAY_SIZE comes from platform's rules.mk + */ +#define DISPLAY_BASE (PANIC_BASE - DISPLAY_SIZE) + + +/* where to stick heap and insecure memory */ +#if APPLICATION_SECUREROM + +// SecureROM SRAM memory map +// +// Data 0x000000 - 0x007000 ( 28 KiB) +// Boot Trampoline 0x007000 - 0x008000 ( 4 KiB) +// Page Tables 0x008000 - 0x00C000 ( 16 KiB) +// Stacks 0x00C000 - 0x010000 ( 16 KiB) +// Heaps 0x010000 - 0x018000 ( 32 KiB) +// DFU Region 0x018000 - 0x120000 (1056 KiB) + +#define INSECURE_MEMORY_SIZE (SRAM_END - HEAP_END) +#define INSECURE_MEMORY_BASE (HEAP_END) + +// DATA_BASE comes from rules.mk +#define DATA_SIZE (0x00007000ULL) + +#define BOOK_KEEPING_BASE (DATA_BASE + DATA_SIZE) +#define BOOT_TRAMPOLINE_BASE (BOOK_KEEPING_BASE) +#define BOOT_TRAMPOLINE_SIZE (0x00001000ULL) +#define MMU_TT_BASE (BOOK_KEEPING_BASE + BOOT_TRAMPOLINE_SIZE) +#define MMU_TT_SIZE (0x00004000ULL) +#define STACK_BASE (BOOK_KEEPING_BASE + BOOT_TRAMPOLINE_SIZE + MMU_TT_SIZE) +#define STACK_SIZE (0x00004000ULL) +#define BOOK_KEEPING_SIZE (BOOT_TRAMPOLINE_SIZE + STACK_SIZE + MMU_TT_SIZE) + +#define HEAP_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define HEAP_SIZE (0x00008000ULL) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT + +#if WITH_DFU_MODE +/* LLB, iBSS DFU */ + +/* reserved area for iBoot (aligned to 1MB boundary) */ +#define IBOOT_SIZE (0x02000000ULL + 0x100000ULL - (PANIC_SIZE + DISPLAY_SIZE)) +#define IBOOT_BASE (DISPLAY_BASE - IBOOT_SIZE) + +#define INSECURE_MEMORY_SIZE (IBOOT_SIZE) +#define INSECURE_MEMORY_BASE (IBOOT_BASE) + +#define STACK_SIZE (0x00004000ULL) +#define MMU_TT_SIZE (0x00004000ULL) +#define BOOK_KEEPING_SIZE (STACK_SIZE + MMU_TT_SIZE) +#define BOOK_KEEPING_BASE (SRAM_BASE) +#define MMU_TT_BASE (BOOK_KEEPING_BASE) +#define STACK_BASE (BOOK_KEEPING_BASE + MMU_TT_SIZE) + +#define HEAP_SIZE (TEXT_BASE - HEAP_BASE) +#define HEAP_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) + +#else /* !WITH_DFU_MODE */ +/* iBoot, iBEC */ + +#define IBOOT_BASE (TEXT_BASE) +#define IBOOT_SIZE (HEAP_END - IBOOT_BASE) + +#define BOOK_KEEPING_BASE (IBOOT_BASE + TEXT_FOOTPRINT) +#define MMU_TT_BASE (BOOK_KEEPING_BASE) +#define MMU_TT_SIZE (0x00004000ULL) +#define STACK_BASE (BOOK_KEEPING_BASE + MMU_TT_SIZE) +#define STACK_SIZE (0x00004000ULL) +#define BOOK_KEEPING_SIZE (STACK_SIZE + MMU_TT_SIZE) + +#define HEAP_BASE (BOOK_KEEPING_BASE + BOOK_KEEPING_SIZE) +#define HEAP_SIZE (DISPLAY_BASE - HEAP_BASE - PAGE_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_LOAD_SIZE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define SECURE_MEMORY_SIZE (DEFAULT_FREE_ADDRESS - SECURE_MEMORY_BASE) + +/* unused area */ +#define UNUSED_MEMORY_BASE (SECURE_MEMORY_BASE + SECURE_MEMORY_SIZE) +#define UNUSED_MEMORY_SIZE (IBOOT_BASE - UNUSED_MEMORY_BASE) + +#endif /* !WITH_DFU_MODE */ + +#endif /* APPLICATION_IBOOT */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/t8002/include/platform/pinconfig.h b/platform/t8002/include/platform/pinconfig.h new file mode 100644 index 0000000..7ca8f43 --- /dev/null +++ b/platform/t8002/include/platform/pinconfig.h @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: m8 io list. version 148 + I/O Spreadsheet tracker: 20260553 + Conversion command: csvtopinconfig.py --rom --header --soc m8 --config-column 'SecureROM config' --pupd-column PU/PD --copyright 2015 --radar 20260553 --netname-column 'ROM Config' +*/ + +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +static const uint32_t gpio_default_cfg_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : GPIO[0] -> + CFG_DISABLED, // 1 : GPIO[1] -> + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 2 : GPIO[2] -> Boot_config[0] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 3 : GPIO[3] -> Boot_config[1] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 4 : GPIO[4] -> Boot_config[2] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 5 : GPIO[5] -> Boot_config[3] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 6 : GPIO[6] -> Board_ID[3] + CFG_DISABLED, // 7 : GPIO[7] -> + +/* Port 1 */ + CFG_DISABLED, // 8 : GPIO[8] -> + CFG_DISABLED, // 9 : GPIO[9] -> + CFG_DISABLED, // 10 : GPIO[10] -> + CFG_DISABLED, // 11 : GPIO[11] -> + CFG_DISABLED, // 12 : GPIO[12] -> + CFG_DISABLED, // 13 : GPIO[13] -> + CFG_DISABLED, // 14 : GPIO[14] -> + CFG_DISABLED, // 15 : GPIO[15] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[16] -> + CFG_DISABLED, // 17 : GPIO[17] -> + CFG_DISABLED, // 18 : TMR32_PWM1 -> + CFG_DISABLED, // 19 : TMR32_PWM2 -> + CFG_DISABLED, // 20 : TMR32_PWM0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : NAND_CEN[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : NAND_CEN[1] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 23 : NAND_IO[7] -> + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 24 : NAND_IO[6] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 25 : NAND_IO[5] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 26 : NAND_IO[4] -> + CFG_DISABLED | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 27 : NAND_REN -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 28 : NAND_IO[3] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 29 : NAND_IO[2] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 30 : NAND_IO[1] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 31 : NAND_IO[0] -> + +/* Port 4 */ + CFG_DISABLED | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 32 : NAND_WEN -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 33 : NAND_CLE -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 34 : NAND_ALE -> + CFG_DISABLED, // 35 : I2S0_LRCK -> + CFG_DISABLED, // 36 : I2S0_BCLK -> + CFG_DISABLED, // 37 : I2S0_DOUT -> + CFG_DISABLED, // 38 : I2S0_DIN -> + CFG_DISABLED, // 39 : I2S1_LRCK -> + +/* Port 5 */ + CFG_DISABLED, // 40 : I2S1_BCLK -> + CFG_DISABLED, // 41 : I2S1_DOUT -> + CFG_DISABLED, // 42 : I2S1_DIN -> + CFG_DISABLED, // 43 : I2S2_LRCK -> + CFG_DISABLED, // 44 : I2S2_BCLK -> + CFG_DISABLED, // 45 : I2S2_DOUT -> + CFG_DISABLED, // 46 : I2S2_DIN -> + CFG_DISABLED, // 47 : SD_CLKOUT -> + +/* Port 6 */ + CFG_DISABLED, // 48 : sDIO_IRQ -> + CFG_DISABLED, // 49 : SD_DATA_IO[0] -> + CFG_DISABLED, // 50 : SD_DATA_IO[1] -> + CFG_DISABLED, // 51 : SD_DATA_IO[2] -> + CFG_DISABLED, // 52 : SD_DATA_IO[3] -> + CFG_DISABLED, // 53 : SDIO_IRQ -> + CFG_DISABLED, // 54 : WL_HOST_WAKE -> + CFG_DISABLED, // 55 : ENET_MDC -> + +/* Port 7 */ + CFG_DISABLED, // 56 : ENET_MDIO -> + CFG_DISABLED, // 57 : RMII_RXER -> + CFG_DISABLED, // 58 : RMII_TXEN -> + CFG_DISABLED, // 59 : RMII_CLK -> + CFG_DISABLED, // 60 : RMII_TXD[0] -> + CFG_DISABLED, // 61 : RMII_TXD[1] -> + CFG_DISABLED, // 62 : RMII_RXD[0] -> + CFG_DISABLED, // 63 : RMII_RXD[1] -> + +/* Port 8 */ + CFG_DISABLED, // 64 : RMII_CRSDV -> + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 65 : SPI0_SCLK -> SPI0_SCLK/Board_ID[0] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 66 : SPI0_MOSI -> SPI0_MOSI/Board_ID[1] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 67 : SPI0_MISO -> SPI0_MISO/Board_ID[2] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 68 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 69 : SPI1_SCLK -> + CFG_DISABLED, // 70 : SPI1_MOSI -> + CFG_DISABLED, // 71 : SPI1_MISO -> + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI1_SSIN -> + CFG_DISABLED, // 73 : I2C0_SDA -> + CFG_DISABLED, // 74 : I2C0_SCL -> + CFG_DISABLED, // 75 : I2C1_SDA -> + CFG_DISABLED, // 76 : I2C1_SCL -> + CFG_DISABLED, // 77 : I2C2_0_SDA -> + CFG_DISABLED, // 78 : I2C2_0_SCL -> + CFG_DISABLED, // 79 : I2C2_1_SDA -> + +/* Port 10 */ + CFG_DISABLED, // 80 : I2C2_1_SCL -> + CFG_DISABLED, // 81 : UART0_TXD -> + CFG_DISABLED, // 82 : UART0_RXD -> + CFG_DISABLED, // 83 : UART3_RTXD -> + CFG_DISABLED, // 84 : UART4_TXD -> + CFG_DISABLED, // 85 : UART4_RXD -> + CFG_DISABLED, // 86 : UART5_TXD -> + CFG_DISABLED, // 87 : UART5_RXD -> + +/* Port 11 */ + CFG_DISABLED, // 88 : UART2_TXD -> + CFG_DISABLED, // 89 : UART2_RXD -> + CFG_DISABLED, // 90 : UART2_RTSN -> + CFG_DISABLED, // 91 : UART2_CTSN -> + CFG_DISABLED, // 92 : UART1_TXD -> + CFG_DISABLED, // 93 : UART1_RXD -> + CFG_DISABLED, // 94 : UART1_RTSN -> + CFG_DISABLED, // 95 : UART1_CTSN -> + +/* Port 12 */ + CFG_DISABLED, // 96 : ISP0_SDA -> + CFG_DISABLED, // 97 : ISP0_SCL -> + CFG_DISABLED, // 98 : DISP_TE -> + CFG_DISABLED, // 99 : DISP_VSYNC -> + CFG_IN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 100 : REQUEST_DFU1 -> REQUEST_DFU1 + CFG_IN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 101 : REQUEST_DFU2 -> REQUEST_DFU2 + CFG_IN | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 102 : FORCE_DFU -> FORCE_DFU + CFG_DISABLED, // 103 : SWD_TMS2 -> + +/* Port 13 */ + CFG_DISABLED, // 104 : SWD_TMS3 -> + CFG_DISABLED, // 105 : CLK32K_OUT -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 14 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 15 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED, // 128 : MON[0] -> + CFG_DISABLED, // 129 : MON[1] -> + CFG_DISABLED, // 130 : MON[2] -> + CFG_DISABLED, // 131 : MON[3] -> + CFG_DISABLED, // 132 : MON[4] -> + CFG_DISABLED, // 133 : MON[5] -> + CFG_DISABLED, // 134 : MON[6] -> + CFG_DISABLED, // 135 : MON[7] -> + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW, // 136 : DFU_STATUS -> DFU_STATUS + CFG_DISABLED, // 137 : DROOP_N -> + CFG_DISABLED, // 138 : TST_CLKOUT -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t gpio_default_cfg_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_I2S1_MCK -> + CFG_DISABLED, // 1 : AOP_I2S0_MCK -> + CFG_DISABLED, // 2 : AOP_PDM_CLK -> + CFG_DISABLED, // 3 : AOP_PDM_DAT -> + CFG_DISABLED, // 4 : AOP_PLED[0] -> + CFG_DISABLED, // 5 : AOP_PLED[1] -> + CFG_FUNC0 | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 6 : AOP_DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW, // 7 : AOP_DOCK_ATTENTION -> + +/* Port 1 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : AOP_PLED[2] -> + CFG_DISABLED, // 33 : AOP_PLED[3] -> + CFG_DISABLED, // 34 : AOP_PLED[4] -> + CFG_DISABLED, // 35 : AOP_PLED[5] -> + CFG_DISABLED, // 36 : AOP_PLED[6] -> + CFG_DISABLED, // 37 : AOP_PLED[7] -> + CFG_DISABLED, // 38 : AOP_MON[0] -> + CFG_DISABLED, // 39 : AOP_MON[1] -> + +/* Port 5 */ + CFG_DISABLED, // 40 : AOP_MON[2] -> + CFG_DISABLED, // 41 : AOP_MON[3] -> + CFG_DISABLED, // 42 : AOP_MON[4] -> + CFG_DISABLED, // 43 : AOP_MON[5] -> + CFG_DISABLED, // 44 : AOP_MON[6] -> + CFG_DISABLED, // 45 : AOP_MON[7] -> + CFG_DISABLED, // 46 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 47 : AOP_SWD_TMS0 -> + +/* Port 6 */ + CFG_DISABLED, // 48 : AOP_SWD_TMS1 -> + CFG_DISABLED, // 49 : AOP_UART0_TXD -> + CFG_DISABLED, // 50 : AOP_UART0_RXD -> + CFG_DISABLED, // 51 : AOP_UART0_RTSN -> + CFG_DISABLED, // 52 : AOP_UART0_CTSN -> + CFG_DISABLED, // 53 : AOP_UART1_TXD -> + CFG_DISABLED, // 54 : AOP_UART1_RXD -> + CFG_DISABLED, // 55 : AOP_UART1_RTSN -> + +/* Port 7 */ + CFG_DISABLED, // 56 : AOP_UART1_CTSN -> + CFG_DISABLED, // 57 : AOP_UART2_TXD -> + CFG_DISABLED, // 58 : AOP_UART2_RXD -> + CFG_DISABLED, // 59 : AOP_SPI_CS_TRIG[0] -> + CFG_DISABLED, // 60 : AOP_SPI_CS_TRIG[1] -> + CFG_DISABLED, // 61 : AOP_SPI_CS_TRIG[2] -> + CFG_DISABLED, // 62 : AOP_SPI_CS_TRIG[3] -> + CFG_DISABLED, // 63 : AOP_SPI_CS_TRIG[4] -> + +/* Port 8 */ + CFG_DISABLED, // 64 : AOP_SPI_CS_TRIG[5] -> + CFG_DISABLED, // 65 : AOP_SPI_CS_TRIG[6] -> + CFG_DISABLED, // 66 : AOP_SPI_CS_TRIG[7] -> + CFG_DISABLED, // 67 : AOP_SPI_CS_TRIG[8] -> + CFG_DISABLED, // 68 : AOP_SPI_CS_TRIG[9] -> + CFG_DISABLED, // 69 : AOP_SPI_CS_TRIG[10] -> + CFG_DISABLED, // 70 : AOP_SPI_CS_TRIG[11] -> + CFG_DISABLED, // 71 : AOP_SPI_CS_TRIG[12] -> + +/* Port 9 */ + CFG_DISABLED, // 72 : AOP_SPI_CS_TRIG[13] -> + CFG_DISABLED, // 73 : AOP_SPI_CS_TRIG[14] -> + CFG_DISABLED, // 74 : AOP_SPI_CS_TRIG[15] -> + CFG_DISABLED, // 75 : AOP_I2C0_SDA -> + CFG_DISABLED, // 76 : AOP_I2C0_SCL -> + CFG_DISABLED, // 77 : AOP_I2C1_SDA -> + CFG_DISABLED, // 78 : AOP_I2C1_SCL -> + CFG_DISABLED, // 79 : AOP_SPI0_SCLK -> + +/* Port 10 */ + CFG_DISABLED, // 80 : AOP_SPI0_MOSI -> + CFG_DISABLED, // 81 : AOP_SPI0_MISO -> + CFG_DISABLED, // 82 : AOP_PSPI_CS_TRIG[3] -> + CFG_DISABLED, // 83 : AOP_PSPI_CS_TRIG[4] -> + CFG_DISABLED, // 84 : AOP_PSPI_SCLK -> + CFG_DISABLED, // 85 : AOP_PSPI_MOSI -> + CFG_DISABLED, // 86 : AOP_PSPI_MISO -> + CFG_DISABLED, // 87 : AOP_LSPI_SCLK -> + +/* Port 11 */ + CFG_DISABLED, // 88 : AOP_LSPI_MOSI -> + CFG_DISABLED, // 89 : AOP_LSPI_MISO -> + CFG_DISABLED, // 90 : AOP_DETECT[0] -> + CFG_DISABLED, // 91 : AOP_DETECT[1] -> + CFG_DISABLED, // 92 : AOP_PSENSE_CTRL[4] -> + CFG_DISABLED, // 93 : AOP_PSENSE_CTRL[5] -> + CFG_DISABLED, // 94 : AOP_PSENSE_CTRL[6] -> + CFG_DISABLED, // 95 : AOP_PSENSE_CTRL[7] -> +}; + + +#endif /* __PLATFORM_PINCONFIG_H */ diff --git a/platform/t8002/include/platform/soc/aop_dma.h b/platform/t8002/include/platform/soc/aop_dma.h new file mode 100644 index 0000000..cc2bb7c --- /dev/null +++ b/platform/t8002/include/platform/soc/aop_dma.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __APPLE_AOP_DMA_H +#define __APPLE_AOP_DMA_H + +#include +#include + +/* AOP PL080 registers */ + +#define rAOP_PL080_INTTCCLEAR (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_INTTCCLEAR_OFFSET)) +#define rAOP_PL080_INTERRCLR (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_INTERRCLR_OFFSET)) +#define rAOP_PL080_CONFIGURATION (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_CONFIGURATION_OFFSET)) +#define rAOP_PL080_SYNC (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_SYNC_OFFSET)) +#define rAOP_PL080_C0_SRCADDR (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_C0_SRCADDR_OFFSET)) +#define rAOP_PL080_C0_DESTADDR (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_C0_DESTADDR_OFFSET)) +#define rAOP_PL080_C0_LLI (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_C0_LLI_OFFSET)) +#define rAOP_PL080_C0_CONTROL (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_C0_CONTROL_OFFSET)) +#define rAOP_PL080_C0_CONFIGURATION (*(volatile uint32_t *)(AOP_PL080_BASE_ADDR + AOP_PL080_BLK_DMAC_C0_CONFIGURATION_OFFSET)) + +#endif /* __APPLE_AOP_DMA_H */ \ No newline at end of file diff --git a/platform/t8002/include/platform/soc/chipid.h b/platform/t8002/include/platform/soc/chipid.h new file mode 100644 index 0000000..f53fd4e --- /dev/null +++ b/platform/t8002/include/platform/soc/chipid.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 - 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include +#include + +#define rCFG_FUSE0 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_OFFSET)) +#define rCFG_FUSE1 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE1_OFFSET)) +#define rCFG_FUSE2 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE2_OFFSET)) +#define rCFG_FUSE3 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE3_OFFSET)) +#define rCFG_FUSE4 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE4_OFFSET)) +#define rCFG_FUSE5 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE5_OFFSET)) +#define rCFG_FUSE9 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE9_OFFSET)) + +#define rECIDLO (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE0_OFFSET)) +#define rECIDHI (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE1_OFFSET)) + +#define rSEP_SECURITY (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_SEP_SECURITY_OFFSET)) + +#define rCFG_FUSE0_RAW (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_RAW_OFFSET)) + +uint32_t chipid_get_total_rails_leakage(); +uint32_t chipid_get_soc_voltage(uint32_t index); +uint32_t chipid_get_fuse_revision(void); + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/t8002/include/platform/soc/display.h b/platform/t8002/include/platform/soc/display.h new file mode 100644 index 0000000..bacae2e --- /dev/null +++ b/platform/t8002/include/platform/soc/display.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ + { + .name = "default", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x20) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x130), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x1f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x7d0) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x130), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x128), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x118), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x114), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x24) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcenab = ADPCENAB_IDEAL_ARB_ENAB, + }, +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/t8002/include/platform/soc/display_timings.h b/platform/t8002/include/platform/soc/display_timings.h new file mode 100644 index 0000000..738e230 --- /dev/null +++ b/platform/t8002/include/platform/soc/display_timings.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_N27 || SUB_TARGET_N28 || SUB_TARGET_N27A || SUB_TARGET_N28A + { + .display_name = "C1", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 6412500, + .dot_pitch = 326, + .h_active = 232, + .h_pulse_width = 2, + .h_back_porch = 44, + .h_front_porch = 42, + .v_active = 288, + .v_pulse_width = 1, + .v_back_porch = 23, + .v_front_porch = 22, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = {0x00000971}, + }, // 533MHz, 1-lane + + { + .display_name = "POR_DISP_S", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 22200000, + .dot_pitch = 326, + .h_active = 272, + .h_pulse_width = 8, + .h_back_porch = 8, + .h_front_porch = 16, + .v_active = 340, + .v_pulse_width = 1, + .v_back_porch = 1, + .v_front_porch = 43, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = {0x00000951}, + }, // 533MHz, 1-lane + + { + .display_name = "POR_DISP_B", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 22200000, + .dot_pitch = 326, + .h_active = 312, + .h_pulse_width = 8, + .h_back_porch = 8, + .h_front_porch = 16, + .v_active = 390, + .v_pulse_width = 1, + .v_back_porch = 1, + .v_front_porch = 38, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = {0x00000951}, + }, // 533MHz, 1-lane + + { + .display_name = "POR_DISP_B_VID", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 12000000, + .dot_pitch = 326, + .h_active = 312, + .h_pulse_width = 4, + .h_back_porch = 102, + .h_front_porch = 42, + .v_active = 390, + .v_pulse_width = 1, + .v_back_porch = 23, + .v_front_porch = 22, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_SUMMIT, + .display_config = {0x00000951}, + }, // 533MHz, 1-lane +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/t8002/include/platform/soc/hwclocks.h b/platform/t8002/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..53f842c --- /dev/null +++ b/platform/t8002/include/platform/soc/hwclocks.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (5000000UL) +#define LPPLL_FREQ (OSC_FREQ) +#else +#define OSC_FREQ (24000000UL) +#define LPPLL_FREQ (96000000UL) +#endif + +// Start from an offset of 128. So that we are safely outside the PS indexes. +#define CLK_FCLK (HWCLOCK_BASE+128) +#define CLK_ACLK (HWCLOCK_BASE+129) +#define CLK_HCLK (HWCLOCK_BASE+130) +#define CLK_PCLK (HWCLOCK_BASE+131) +#define CLK_VCLK0 (HWCLOCK_BASE+132) +#define CLK_VCLK1 (HWCLOCK_BASE+133) +#define CLK_MCLK (HWCLOCK_BASE+134) +#define CLK_NCLK (HWCLOCK_BASE+135) +#define CLK_USBPHYCLK (HWCLOCK_BASE+136) +#define CLK_NCOREF (HWCLOCK_BASE+137) +#define CLK_ANS_LINK (HWCLOCK_BASE+138) + +#define PMGR_DEVICE_INDEX(_clk) ((_clk) - HWCLOCK_BASE) +#define PMGR_DEVICE_COUNT (CLK_LAST - HWCLOCK_BASE) + +#define PMGR_FIRST_DEVICE CLK_AOP +#define PMGR_LAST_DEVICE CLK_USB2HOST1 + +#define PMGR_VALID_DEVICE(_clk) ((_clk) >= PMGR_FIRST_DEVICE && (_clk) <= PMGR_LAST_DEVICE) + +/* + * T8002 clock gate devices. + */ +enum { + // Mini-PMGR + CLK_AOP = HWCLOCK_BASE, + CLK_DEBUG, + CLK_AOP_GPIO, + CLK_AOP_I2CM1, + CLK_AOP_CPU, + CLK_AOP_RTCPU, + CLK_AOP_FILTER, + CLK_AOP_UART0, + CLK_AOP_UART1, + CLK_AOP_UART2, + CLK_AOP_I2CM, + CLK_AOP_FILTER_DMA, + CLK_AOP_LPD0, + CLK_AOP_HPDS, + CLK_AOP_HPDSC, + CLK_AOP_HPDD, + CLK_MARCONI, + + // PMGR + CLK_SCU, + CLK_CPU0, + CLK_CPU1, + CLK_PIO, + CLK_CPU_FAB, + CLK_NRT_FAB, + CLK_RT_FAB, + CLK_AIC, + CLK_GPIO, + CLK_ISPSENS0, + CLK_UVD, + CLK_HSIC0PHY, + CLK_AMC, + CLK_LIO_FAB, + CLK_LIO_LOGIC, + CLK_LIO, + CLK_AES0, + CLK_MCA0, + CLK_MCA1, + CLK_MCA2, + CLK_HFD, + CLK_SPI0, + CLK_SPI1, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_UART7, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_PWM0, + CLK_USB, + CLK_USBCTLREG = CLK_USB, + CLK_USB_OTG = CLK_USB, + CLK_ETH, + CLK_ANS, + CLK_SDIO, + CLK_DISP, + CLK_DISP0 = CLK_DISP, + CLK_MIPI_DSI, + CLK_MIPI = CLK_MIPI_DSI, + CLK_ISP, + CLK_GFX, + CLK_MEDIA_FAB, + CLK_MSR, + CLK_VDEC, + CLK_RESERVED, + CLK_JPG, + CLK_VENC_CPU, + CLK_USB2HOST1, + CLK_SEP, + CLK_VENC_PIPE, + CLK_VENC_ME, + + CLK_LAST, +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/t8002/include/platform/soc/hwisr.h b/platform/t8002/include/platform/soc/hwisr.h new file mode 100644 index 0000000..dcb78dd --- /dev/null +++ b/platform/t8002/include/platform/soc/hwisr.h @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2013 - 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt + +// Reserved 4 + +#define INT_PMGR_PERF_CNTRS 5 // PMGR Performace Counters Interrupt +#define INT_THERM_TEMP0 6 // Thermal Temp 0 Interrupt +#define INT_THERM_ALARM0 7 // Thermal Alarm 0 Interrupt +#define INT_UVDC 8 // UVDC Interrupt +#define INT_UVDC_TH 9 // UVDC TH interrupt +#define INT_DROOP 10 // Droop Interrupt +#define INT_DROOP_TH 11 // Droop TH interrupt + +// Reserved 12 - 13 + +#define INT_MIPIDPHY 14 // MIPID PHY Interrupt +#define INT_CTM_TRIGGER0 15 // CTM Trigger 0 Interrupt +#define INT_CTM_TRIGGER1 16 // CTM Trigger 1 Interrupt +#define INT_CTM_TRIGGER2 17 // CTM Trigger 2 Interrupt +#define INT_CTM_TRIGGER3 18 // CTM Trigger 3 Interrupt + +// Reserved 19 + +#define INT_MINI_PMGR_PERF_CNTRS 20 // MINIPMGR PerfCounter Interrupt +#define INT_MINI_PMGR_WDT 21 // MINIPMGR Watchdog Interrupt + +// Reserved 22 + +#define INT_CPU0_AXI_ERR_IRQ 23 // CPU 0 AXI Error IRQ Interrupt +#define INT_CPU0_CX_ETB_FUKK 24 // CPU 0 CXETB Full Interrupt + +// Reserved 25 + +#define INT_CPU0_PMU_IRQ 26 // CPU 0 PMU IRQ Interrupt +#define INT_CPU0_CTI_IRQ 27 // CPU 0 CTI Interrupt +#define INT_CPU0_COMM_RX 28 // CPU 0 COMM RX Interrupt +#define INT_CPU0_COMM_TX 29 // CPU 0 COMM TX Interrupt + +// Reserved 30 + +#define INT_CPU1_PMU_IRQ 31 // CPU 1 PMU IRQ Interrupt +#define INT_CPU1_CTI_IRQ 32 // CPU 1 CTI Interrupt +#define INT_CPU1_COMM_RX 33 // CPU 1 COMM RX Interrupt +#define INT_CPU1_COMM_TX 34 // CPU 1 COMM TX Interrupt + +// Reserved 35 + +#define INT_GPIO_CLASS0 36 // GPIO Class 0 Interrupt +#define INT_GPIO_CLASS1 37 // GPIO Class 1 Interrupt +#define INT_GPIO_CLASS2 38 // GPIO Class 2 Interrupt +#define INT_GPIO_CLASS3 39 // GPIO Class 3 Interrupt +#define INT_GPIO_CLASS4 40 // GPIO Class 4 Interrupt +#define INT_GPIO_CLASS5 41 // GPIO Class 5 Interrupt +#define INT_GPIO_CLASS6 42 // GPIO Class 6 Interrupt + +// Reserved 43 + +#define INT_MEM_MCU 44 // Memory Controller MCU Interrupt +#define INT_DCS_AMCX0 45 // Memory Controller DCS AMCX0 Interrupt +#define INT_DCS_AMCX1 46 // Memory Controller DCS AMCX1 Interrupt +#define INT_DCS_AMP_CAL_ERR 47 // Memory Controller DCS AMP Cal Error Interrupt + +// Reserved 48 + +#define INT_GFX 49 // GFX Interrupt + +// Reserved 50 + +#define INT_ENET 51 // Ethernet IP Interrupt +#define INT_USB_OTG 52 // USB OTG Interrupt +#define INT_USB_20_BATT_CHRG_DET 53 // USB 2.0 Battery Charge Detect Interrupt +#define INT_USBOTG_RESUME 54 // USB OTG Resume Interrupt +#define INT_USB_HOST 55 // USB Host Interrupt +#define INT_SDIO_KF_INBOX_EMPTY 56 // SDIO KF Inbox Empty Interrupt +#define INT_SDIO_KF_INBOX_NOTEMPTY 57 // SDIO KF Inbox Not Empty Interrupt +#define INT_SDIO_KF_OUTBOX_EMPTY 58 // SDIO KF Outbox Empty Interrupt +#define INT_SDIO_KF_OUTBOX_NOTEMPTY 59 // SDIO KF Outbox Not Empty Interrupt +#define INT_SDIO_SDHC_WAKEUP 60 // SDIO SDHC Wakeup +#define INT_SDIO_SDHC_INT 61 // SDIO SDHC Tnterrupt +#define INT_SDIO_CARD_INT 62 // SDIO SDHC Interrupt +#define INT_SDIO_IRQ 63 // SDIO IRQ +#define INT_SDIO_WL_HOST_WAKE_INT 64 // SDIO Host Wake Interrupt + +// Reserved 65 + +#define INT_ANS_KF_INBOX_EMPTY 66 // ANS KF Inbox Empty Interrupt +#define INT_ANS_KF_INBOX_NOTEMPTY 67 // ANS KF Inbox Not Empty Interrupt +#define INT_ANS_KF_OUTBOX_EMPTY 68 // ANS KF Outbox Empty Interrupt +#define INT_ANS_KF_OUTBOX_NOTEMPTY 69 // ANS KF Outbox Not Empty Interrupt +#define INT_ANS_CHNL0 70 // ANS Channel 0 Interrupt + +// Reserved 71 + +#define INT_PIO 72 // PIO IRQ + +// Reserved 73 + +#define INT_DMA_RX_TC 74 // DMA Rx Transfer Complete Interrupt +#define INT_DMA_RX_ERR 75 // DMA Rx Error Interrupt +#define INT_DMA_TX_TC 76 // DMA Tx Transfer Complete Interrupt +#define INT_DMA_TX_ERR 77 // DMA Tx Error Interrupt + +// Reserved 78 + +#define INT_SPI0 79 // SPI 0 Interrupt +#define INT_SPI1 80 // SPI 1 Interrupt +#define INT_UART0 81 // UART 0 Interrupt +#define INT_UART1 82 // UART 1 Interrupt +#define INT_UART2 83 // UART 2 Interrupt +#define INT_UART3 84 // UART 3 Interrupt +#define INT_UART4 85 // UART 4 Interrupt +#define INT_UART5 86 // UART 5 Interrupt +#define INT_UART6 87 // UART 6 Interrupt +#define INT_UART7 88 // UART 7 Interrupt +#define INT_PWM0 89 // PWM0 Interrupt +#define INT_MCA0 90 // Multi-Channel Audio 0 Interrupt +#define INT_MCA1 91 // Multi-Channel Audio 1 Interrupt +#define INT_MCA2 92 // Multi-Channel Audio 2 Interrupt +#define INT_IIC0 93 // I2C 0 Interrupt +#define INT_IIC1 94 // I2C 1 Interrupt +#define INT_IIC2 95 // I2C 2 Interrupt +#define INT_AES 96 // AES Interrupt + +// Reserved 97 + +#define INT_MSR 98 // MSR Interrupt +#define INT_MSR_SMMU 99 // MSR SMMU Interrupt +#define INT_MSR_DART 100 // MSR DART Interrupt +#define INT_MSR_SMMU_PERF 101 // MSR SMMU Performance Interrupt +#define INT_MSR_DART_PERF 102 // MSR DART Performance Interrupt + +// Reserved 103 + +#define INT_ADP 104 // Display All ADP +#define INT_DISP_DART 105 // Display DART Interrupt +#define INT_DISP_SMMU 106 // Display SMMU Interrupt +#define INT_DISP_BACK_END_VBI 107 // Display Back End VBI Interrupt +#define INT_DISP_BACK_END_VFTG_IDLE 108 // Display Back End VFTG Idle Interrupt +#define INT_DISP_BACK_END_VBL_CNTR 109 // Display Back End VBL Counter Interrupt +#define INT_PIO_DMA 110 // PIO DMA Interrupt + +// Reserved 111 + +#define INT_VDEC 112 // Video Decoder + +// Reserved 113 + +#define INT_JPEG 114 // MSR Interrupt +#define INT_JPEG_DART 115 // MSR SMMU Interrupt +#define INT_JPEG_DART_PERF 116 // MSR DART Interrupt + +// Reserved 117 + +#define INT_AVE_KF_INBOX_EMPTY 118 // AVE KF Inbox Empty Interrupt +#define INT_AVE_KF_INBOX_NOTEMPTY 119 // AVE KF Inbox Not Empty Interrupt +#define INT_AVE_KF_OUTBOX_EMPTY 120 // AVE KF Outbox Empty Interrupt +#define INT_AVE_KF_OUTBOX_NOTEMPTY 121 // AVE KF Outbox Not Empty Interrupt +#define INT_AVE_SMMU 122 // AVE SMMU Interrupt +#define INT_AVE_DART 123 // AVE DART Interrupt +#define INT_AVE 124 // AVE Interrupt +#define INT_SVE 125 // SVE Driver Synchronization Interrupt + +// AVE Reserved 126-127 + +// Reserved 128 + +#define INT_ISP_KF_INBOX_EMPTY 129 // ISP KF Inbox Empty Interrupt +#define INT_ISP_KF_INBOX_NOTEMPTY 130 // ISP KF Inbox Not Empty Interrupt +#define INT_ISP_KF_OUTBOX_EMPTY 131 // ISP KF Outbox Empty Interrupt +#define INT_ISP_KF_OUTBOX_NOTEMPTY 132 // ISP KF Outbox Not Empty Interrupt +#define INT_ISP0 133 // ISP 0 Interrupt +#define INT_ISP1 134 // ISP 1 Interrupt +#define INT_ISP2 135 // ISP 2 Interrupt +#define INT_ISP3 136 // ISP 3 Interrupt +#define INT_ISP_DART 137 // ISP DART Interrupt + +// Reserved 138 + +#define INT_SEP_KF_INBOX_EMPTY 139 // SEP KF Inbox Empty Interrupt +#define INT_SEP_KF_INBOX_NOTEMPTY 140 // SEP KF Inbox Not Empty Interrupt +#define INT_SEP_KF_OUTBOX_EMPTY 141 // SEP KF Outbox Empty Interrupt +#define INT_SEP_KF_OUTBOX_NOTEMPTY 142 // SEP KF Outbox Not Empty Interrupt +#define INT_SEP_CRIT_PATH_MONITOR 143 // SEP Critical Path Monitor Interrupt +#define INT_SEP_AUTH_ERROR 144 // SEP Authentication Error Interrupt + +// Reserved 145 - 147 + +#define INT_DOCKCHANNELS_AP 148 // DOCKCHANNELS Interrupt:q + +// AOP Interrupts 146 - 211 + +// Reserved 221 + +#define INT_PDMC 222 // PDMC Interrupt + +// Reserved 223 - 224 + +// Marconi Interrupts 225 - 248 + +// Reserved 249 - 255 + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/t8002/include/platform/soc/hwregbase.h b/platform/t8002/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..2239005 --- /dev/null +++ b/platform/t8002/include/platform/soc/hwregbase.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#include + +/* T8002 Reg Base Defs */ + +// Memory Subsystem +#define SECUREROM_BASE_ADDR (IO_BASE + 0x00000000) // SecureROM access through PIO +#define PIO_BASE_ADDR (IO_BASE + 0x00100000) // PIO Config +#define CPU_FABRIC_BASE_ADDR (IO_BASE + 0x00101000) // CPU Fabric Config +#define NRT_FABRIC_BASE_ADDR (IO_BASE + 0x00102000) // NRT Fabric Config +#define RT_FABRIC_BASE_ADDR (IO_BASE + 0x00103000) // RT Fabric Config + +#define DCS_REG_VERSION (0x10) + +// AMCSYS Config +#define AMC_BASE_ADDR (IO_BASE + 0x00200000) // AMC Config +#define NUM_AMCCS (0) + +#define DCS_BASE_ADDR (IO_BASE + 0x00300000) // DCS + +#define DCS_SPACING (0x40000) +#define SPLLCTRL_SPACING (0x0000C000) +#define DCSH_AON_SPACING (0x00010000) +#define AMP_CA_SPACING (0x00020000) +#define AMP_DQ_SPACING (0x00008000) +#define AMP_SPACING (DCS_SPACING) +#define AMP_BASE_ADDR (DCS_BASE_ADDR + AMP_CA_SPACING) +#define AMPH_BASE_ADDR (AMP_BASE_ADDR + 3 * AMP_DQ_SPACING) + +// MSR Subsystem +#define MSR_BASE_ADDR (IO_BASE + 0x01100000) // MSR Config +#define MSR_SMMU_BASE_ADDR (IO_BASE + 0x01104000) // MSR SMMU +#define MSR_DART_BASE_ADDR (IO_BASE + 0x01108000) // MSR DART +#define VDEC_BASE_ADDR (IO_BASE + 0x01200000) // VXD394 Video Decoder +//XXX +//#define SGX544_SC_BASE_ADDR (IO_BASE + 0x02800000) // SGX544-SC Space + +// Display Subsystem +#define DISP_ADP_BASE_ADDR (IO_BASE + 0x03200000) // Display pipe configuration +#define DISP0_BASE_ADDR DISP_ADP_BASE_ADDR +#define DISP_ADP_SMMU_BASE_ADDR (IO_BASE + 0x03300000) // Display pipe SMMU configuration +#define DISP_ADE_BASE_ADDR (IO_BASE + 0x03400000) // DBE Timing controller +#define DISP0_ADBE_BASE_ADDR DISP_ADE_BASE_ADDR +//XXX +//#define DISP_AAP_BASE_ADDR (IO_BASE + 0x03440000) // DBE Ambient-Adaptive Pixel +#define DISP_DITHER_BASE_ADDR (IO_BASE + 0x03540000) // DBE Dither +#define DISP_MIPI_DSI_BASE_ADDR (IO_BASE + 0x03800000) // MIPI DSI Core configuration + +// ANS Subsystem +#define ANS_PL301_BASE_ADDR (IO_BASE + 0x05010000) // ANS PL301 Configuration +#define ANS_PL301_TLIMIT0_BASE_ADDR (IO_BASE + 0x05020000) // ANS Cortex-A7 Transaction Limit +#define ANS_PL301_TLIMIT1_BASE_ADDR (IO_BASE + 0x05030000) // ANS NAND controoler Transaction Limit +#define ANS_AKF_BASE_ADDR (IO_BASE + 0x05040000) // ANS Cortex-A7 and wrapper +// ANS KF Debug registers +#define ANS_CFG_BASE_ADDR (IO_BASE + 0x05080000) // ANS Config +#define ANS_PPN_N_PL_BASE_ADDR (IO_BASE + 0x05081000) +#define ANS_ANC_BASE_ADDR (IO_BASE + 0x05800000) // NAND Controller + +// SDIO Subsystem +#define SDIO_PL301_BASE_ADDR (IO_BASE + 0x06010000) // SDIO PL301 Configuration +#define SDIO_PL301_TLIMIT0_BASE_ADDR (IO_BASE + 0x06020000) // SDIO Cortex-A7 Transaction Limit +#define SDIO_PL301_TLIMIT1_BASE_ADDR (IO_BASE + 0x06030000) // SDIO controller Transaction Limit +#define SDIO_AKF_BASE_ADDR (IO_BASE + 0x06080000) // SDIO Cortex-A7 and wrapper +// SDIO KF Debug registers +#define SDIO_CFG_BASE_ADDR (IO_BASE + 0x060C0000) // SDIO Config + +// LIO Subsystem +#define LIO_MISC_BASE_ADDR (IO_BASE + 0x07000000) // Miscellaneous registers +#define LIO_AUD_MUX_BASE_ADDR (IO_BASE + 0x07004000) // Audio I2S Switch registers +#define LIO_PWM_BASE_ADDR (IO_BASE + 0x07010000) // PWM Device registers +#define LIO_SMB_0_BASE_ADDR (IO_BASE + 0x07020000) // I2C Device registers +#define LIO_SPI_BASE_ADDR (IO_BASE + 0x07200000) // SPI Device registers +#define LIO_UART_BASE_ADDR (IO_BASE + 0x07230000) // UART Device registers +#define LIO_MCA_BASE_ADDR (IO_BASE + 0x07260000) // MCA Device registers +#define LIO_AES_BASE_ADDR (IO_BASE + 0x07280000) // AES +#define LIO_DMAC_BASE_ADDR (IO_BASE + 0x07300000) // PL080 DMAC registers + +// PMS Subsystem +#define GPIO_BASE_ADDR (IO_BASE + 0x07500000) // GPIO Device Registers +#define PMGR_BASE_ADDR (IO_BASE + 0x07600000) // Power Manager +#define AIC_BASE_ADDR (IO_BASE + 0x07700000) // Apple Interrupt Controller +#define GLBTIMER_BASE_ADDR (IO_BASE + 0x07710000) // Global Timer + +#define rAIC_TMR_CNT (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2014)) +#define rAIC_TMR_ISR (*(volatile u_int32_t *)(AIC_BASE_ADDR + 0x2018)) +#define AIC_TMRISR_PCT (1 << 0) +#define AIC_TMRISR_ETS (1 << 1) +#define AIC_TMRISR_STS (1 << 2) + +// AOP Subsystem +// SPU KF Debug registers +#define AOP_GPIO_BASE_ADDR (IO_BASE + 0x08088000) // AOP GPIO +#define AOP_MINIPMGR_BASE_ADDR (IO_BASE + 0x08100000) +// XXX Need to be fixed +#define AOP_SRAM (IO_BASE + 0x88000000) +#define MEMORY_CALIB_SAVE_BASE_ADDR AOP_SRAM // Temporarily save cold boot memcal results in AOP_SRAM + + // Dockchannels +#define DOCKCHANNELS_BASE_ADDR (IO_BASE + 0x08380000) // Dock channel registers + +// AOP PL080 DMA +#define AOP_PL080_BASE_ADDR (IO_BASE + 0x08650000) + +// AUE Subsystem +#define AUE_USBCONT_BASE_ADDR (IO_BASE + 0x09000000) // USB Control +#define AUE_USBOTG_BASE_ADDR (IO_BASE + 0x09100000) // USBOTG + +/* iBoot Specific Defs */ + +#define AKF_VERSION (2) + +#define UART0_BASE_ADDR (LIO_UART_BASE_ADDR) +#define UART1_BASE_ADDR (LIO_UART_BASE_ADDR + 0x04000) +#define UART2_BASE_ADDR (LIO_UART_BASE_ADDR + 0x08000) +#define UART3_BASE_ADDR (LIO_UART_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (LIO_UART_BASE_ADDR + 0x10000) +#define UARTS_COUNT (5) +#define UART_VERSION (1) + +#define SPI0_BASE_ADDR (LIO_SPI_BASE_ADDR) +#define SPI1_BASE_ADDR (LIO_SPI_BASE_ADDR + 0x04000) +#define SPI_VERSION (1) +#define SPIS_COUNT (2) + +#define IIC_BASE_ADDR (LIO_SMB_0_BASE_ADDR) +#define IIC_SPACING (0x00004000) +#define IICS_COUNT (3) + +#define AES_AP_BASE_ADDR (LIO_AES_BASE_ADDR) + +#define DSIM_BASE_ADDR (DISP_MIPI_DSI_BASE_ADDR) +#define DSIM_LANE_COUNT (1) +#define DSIM_VERSION (3) + +#define ADBE_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define DISP_VERSION (5) +#define ADP_VERSION (1) + +#define PMGR_WDG_VERSION (1) + +#define GPIOC_COUNT (2) +#define GPIO_VERSION (5) +#define GPIO_0_GROUP_COUNT (18) +#define GPIO_GROUP_COUNT (GPIO_0_GROUP_COUNT) +#define GPIO_1_BASE_ADDR (AOP_GPIO_BASE_ADDR) +#define GPIO_1_GROUP_COUNT (12) +#define GPIO_AP (GPIOC_0) +#define GPIO_AOP (GPIOC_1) + +#define AIC_VERSION 2 +#define AIC_INT_COUNT (256) + +#define USBOTG_BASE_ADDR (AUE_USBOTG_BASE_ADDR) +#define AUSB_CTL_REG_BASE_ADDR (AUE_USBCONT_BASE_ADDR) +#define AUSB_CTL_USB20PHY_REG_OFFSET (0x30) +#define AUSB_USB20PHY_ONLY_VERSION (1) + +#define ASEP_AKF_BASE_ADDR (IO_BASE + 0x0AA00000) // ASEP AKF control Registers + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/t8002/include/platform/soc/miu.h b/platform/t8002/include/platform/soc/miu.h new file mode 100644 index 0000000..02da7c1 --- /dev/null +++ b/platform/t8002/include/platform/soc/miu.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include + +#define rMCCLOCKREGION_TZ0BASEADDR *(volatile uint32_t *)(AMC_BASE_ADDR + 0x40) +#define rMCCLOCKREGION_TZ0ENDADDR *(volatile uint32_t *)(AMC_BASE_ADDR + 0x44) +#define rMCCLOCKREGION_TZ0LOCK *(volatile uint32_t *)(AMC_BASE_ADDR + 0x48) + +// CPU Fabric Widget Registers (base address @ CPU_FABRIC_BASE_ADDR) +#define CPU_Fabric_pl301Wrap0_AMCRDRATELIMIT (0x0000) // AMC Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AMCWRALIMIT (0x0004) // AMC Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AMCRTRLIMIT (0x0008) // AMC Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_AMCWTRLIMIT (0x000c) // AMC Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_SPURDRATELIMIT (0x0040) // SPU Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_SPUWRALIMIT (0x0044) // SPU Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_SPURTRLIMIT (0x0048) // SPU Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_SPUWTRLIMIT (0x004c) // SPU Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_SPUWGATHER (0x0050) // SPU Write Gather Register +#define CPU_Fabric_pl301Wrap0_LIOWGATHER (0x0090) // LIO Write Gather Register +#define CPU_Fabric_pl301Wrap0_AUERDRATELIMIT (0x00c0) // AUE Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AUEWRALIMIT (0x00c4) // AUE Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_AUERTRLIMIT (0x00c8) // AUE Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_AUEWTRLIMIT (0x00cc) // AUE Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_AUEWGATHER (0x00d0) // AUE Write Gather Register +#define CPU_Fabric_pl301Wrap0_ANSRDRATELIMIT (0x0100) // ANS Read Rate Limit Register +#define CPU_Fabric_pl301Wrap0_ANSWRALIMIT (0x0104) // ANS Write Rate Limit Register +#define CPU_Fabric_pl301Wrap0_ANSRTRLIMIT (0x0108) // ANS Read Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_ANSWTRLIMIT (0x010c) // ANS Write Transactions Limit Register +#define CPU_Fabric_pl301Wrap0_ANSWGATHER (0x0110) // ANS Write Gather Register +#define CPU_Fabric_pl301Wrap0_AXI0_ARCHANARBMI0 (0x0408) // Configured AR channel arbitration value for MI 0 + +// NRT Fabric Widget Registers (base address @ NRT_FABRIC_BASE_ADDR) +#define NRT_Fabric_pl301Wrap1_AMCRDRATELIMIT (0x0000) // AMC Read Rate Limit Register +#define NRT_Fabric_pl301Wrap1_AMCWRALIMIT (0x0004) // AMC Write Rate Limit Register +#define NRT_Fabric_pl301Wrap1_AMCRTRLIMIT (0x0008) // AMC Read Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_AMCWTRLIMIT (0x000c) // AMC Write Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_MSRRDRATELIMIT (0x0040) // MSR Read Rate Limit Register +#define NRT_Fabric_pl301Wrap1_MSRWRALIMIT (0x0044) // MSR Write Rate Limit Register +#define NRT_Fabric_pl301Wrap1_MSRRTRLIMIT (0x0048) // MSR Read Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_MSRWTRLIMIT (0x004c) // MSR Write Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_SDIORDRATELIMIT (0x0080) // SDIO Read Rate Limit Register +#define NRT_Fabric_pl301Wrap1_SDIOWRALIMIT (0x0084) // SDIO Write Rate Limit Register +#define NRT_Fabric_pl301Wrap1_SDIORTRLIMIT (0x0088) // SDIO Read Transactions Limit Register +#define NRT_Fabric_pl301Wrap1_SDIOWTRLIMIT (0x008c) // SDIO Write Transactions Limit Register + +#define rPIO_REMAP_CTL *(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_PIOSYS_ROMADDRREMAP_OFFSET) + +enum remap_select { + REMAP_SRAM = 1, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/t8002/include/platform/soc/pmgr.h b/platform/t8002/include/platform/soc/pmgr.h new file mode 100644 index 0000000..c83fa42 --- /dev/null +++ b/platform/t8002/include/platform/soc/pmgr.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(minipmgr) +#include SUB_PLATFORM_SPDS_HEADER(pmgr) + +enum { + PMGR_CLK_OSC = 0, + PMGR_CLK_PLL0, + PMGR_CLK_PLL1, + PMGR_CLK_GPIO, + PMGR_CLK_SOURCE_FIRST = PMGR_CLK_GPIO, + PMGR_CLK_CPU, + PMGR_CLK_MCU_REF, + PMGR_CLK_GFX, + PMGR_CLK_MEDIA_FAB, + PMGR_CLK_PIO, + PMGR_CLK_SDIO, + PMGR_CLK_LIO, // 0xa + PMGR_CLK_AES, + PMGR_CLK_AUE, + PMGR_CLK_SPI0_N, + PMGR_CLK_SPI1_N, + PMGR_CLK_NCO_REF0, + PMGR_CLK_NCO_REF1, // 0x10 + PMGR_CLK_NCO_ALG0, + PMGR_CLK_NCO_ALG1, + PMGR_CLK_MCA0_M, + PMGR_CLK_MCA1_M, + PMGR_CLK_MCA2_M, + PMGR_CLK_TMPS, + PMGR_CLK_UVD, + PMGR_CLK_ISP_C, + PMGR_CLK_ISP, + PMGR_CLK_RT_FAB, // 0x1a + PMGR_CLK_ISP_SENSOR0, + PMGR_CLK_VENC, + PMGR_CLK_SEP, + PMGR_CLK_SEP_FAB, + PMGR_CLK_ANS, + PMGR_CLK_ANC_LINK, // 0x20 + PMGR_CLK_VDEC, + PMGR_CLK_MSR, + PMGR_CLK_AJPEG_IP, + PMGR_CLK_AJPEG_WRAP, + PMGR_CLK_DISP, + PMGR_CLK_MIPI_DSI, + PMGR_CLK_VID, + PMGR_CLK_HFD, + PMGR_CLK_HSICPHY_REF_12M, + PMGR_CLK_USB480_0, // 0x2a + PMGR_CLK_USB_EHCI, + PMGR_CLK_SOURCE_LAST = PMGR_CLK_USB_EHCI, + PMGR_CLK_S0, + PMGR_CLK_SPARE_FIRST = PMGR_CLK_S0, + PMGR_CLK_S1, + PMGR_CLK_ISP_REF0, + PMGR_CLK_SPARE_LAST = PMGR_CLK_ISP_REF0, + PMGR_CLK_LPPLL, + PMGR_CLK_AOP, // 0x30 + PMGR_CLK_MINI_FIRST = PMGR_CLK_AOP, + PMGR_CLK_UART0, + PMGR_CLK_UART1, + PMGR_CLK_UART2, + PMGR_CLK_SENSE_X2, + PMGR_CLK_DETECT, + PMGR_CLK_I2CM, + PMGR_CLK_I2CM1, + PMGR_CLK_PROXY_FABRIC, + PMGR_CLK_PROXY_MCU_REF, // 0x3a + PMGR_CLK_MINI_LAST = PMGR_CLK_PROXY_MCU_REF, + PMGR_CLK_COUNT, + PMGR_CLK_NOT_SUPPORTED, +}; + +// PLL +static const int PMGR_PLL_COUNT = 2; +#define PMGR_PLL_REG_STRIDE (PMGR_PLL1_OFFSET - PMGR_PLL0_OFFSET) +#define rPMGR_PLL_CTL(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + ((_p) * PMGR_PLL_REG_STRIDE))) +#define rPMGR_PLL_CFG(_p) (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_PLL0_CFG_OFFSET + ((_p) * PMGR_PLL_REG_STRIDE))) + +#define PMGR_PLL_CTL_PRE_DIVN_INSRT(_f) PMGR_PLL0_CTL_PRE_DIVN_INSRT(_f) +#define PMGR_PLL_CTL_FB_DIVN_INSRT(_f) PMGR_PLL0_CTL_FB_DIVN_INSRT(_f) +#define PMGR_PLL_CTL_OP_DIVN_INSRT(_f) PMGR_PLL0_CTL_OP_DIVN_INSRT(_f) +#define PMGR_PLL_CTL_ENABLE_INSRT(_f) PMGR_PLL0_CTL_ENABLE_INSRT(_f) +#define PMGR_PLL_CTL_LOAD_INSRT(_f) PMGR_PLL0_CTL_LOAD_INSRT(_f) +#define PMGR_PLL_CTL_BYPASS_INSRT(_f) PMGR_PLL0_CTL_BYPASS_INSRT(_f) +#define PMGR_PLL_CFG_VCO_OUT_SEL_INSRT(_f) PMGR_PLL0_CFG_VCO_OUT_SEL_INSRT(_f) +#define PMGR_PLL_CFG_OFF_MODE_INSRT(_f) PMGR_PLL0_CFG_OFF_MODE_INSRT(_f) +#define PMGR_PLL_CFG_FRAC_LOCK_TIME_INSRT(_f) PMGR_PLL0_CFG_FRAC_LOCK_TIME_INSRT(_f) +#define PMGR_PLL_CFG_LOCK_TIME_INSRT(_f) PMGR_PLL0_CFG_LOCK_TIME_INSRT(_f) + +#define PMGR_PLL_CTL_PENDING_XTRCT(_f) PMGR_PLL0_CTL_PLL_PENDING_XTRCT(_f) +#define PMGR_PLL_CTL_ENABLE_XTRCT(_f) PMGR_PLL0_CTL_ENABLE_XTRCT(_f) +#define PMGR_PLL_CTL_BYPASS_XTRCT(_f) PMGR_PLL0_CTL_BYPASS_XTRCT(_f) +#define PMGR_PLL_CTL_PRE_DIVN_XTRCT(_f) PMGR_PLL0_CTL_PRE_DIVN_XTRCT(_f) +#define PMGR_PLL_CTL_FB_DIVN_XTRCT(_f) PMGR_PLL0_CTL_FB_DIVN_XTRCT(_f) +#define PMGR_PLL_CTL_OP_DIVN_XTRCT(_f) PMGR_PLL0_CTL_OP_DIVN_XTRCT(_f) +#define PMGR_PLL_CFG_VCO_OUT_SEL_XTRCT(_f) PMGR_PLL0_CFG_VCO_OUT_SEL_XTRCT(_f) + +enum pmgr_pll_off_mode { + PMGR_PLL_OFF_MODE_RESET = 0, + PMGR_PLL_OFF_MODE_CLOCK_GATED, + PMGR_PLL_OFF_MODE_POWER_DOWN +}; + +enum pmgr_pll_lock_mode { + PMGR_PLL_LOCK_MODE_COUNTER = 0, + PMGR_PLL_LOCK_MODE_LOCK +}; + +enum pmgr_pll_relock_mode { + PMGR_PLL_RELOCK_MODE_STOP = 0, + PMGR_PLL_RELOCK_MODE_BYPASS +}; + +// PS +#define rPMGR_PS(_x) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_PS_##_x##_PS_OFFSET)) + +#define PMGR_PS_MANUAL_PS_XTRCT(_f) PMGR_PS_DISP_PS_MANUAL_PS_XTRCT(_f) +#define PMGR_PS_ACTUAL_PS_XTRCT(_f) PMGR_PS_DISP_PS_ACTUAL_PS_XTRCT(_f) +#define PMGR_PS_MANUAL_PS_INSRT(_f) PMGR_PS_DISP_PS_MANUAL_PS_INSRT(_f) +#define PMGR_PS_RESET_INSRT(_f) PMGR_PS_DISP_PS_RESET_INSRT(_f) + +enum pmgr_ps_state { + PMGR_PS_RUN_MAX = 0xF, + PMGR_PS_CLOCK_OFF = 0x4, + PMGR_PS_POWER_OFF = 0x0 +}; + +#define rPMGR_CLK_CFG(_x) (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_CLKCFG_##_x##_CLK_CFG_OFFSET)) +#define PMGR_FIRST_CLK_CFG (&rPMGR_CLK_CFG(GPIO)) +#define PMGR_LAST_CLK_CFG (&rPMGR_CLK_CFG(USB_EHCI)) +#define PMGR_FIRST_SPARE_CLK_CFG (&rPMGR_CLK_CFG(S0)) +#define PMGR_LAST_SPARE_CLK_CFG (&rPMGR_CLK_CFG(ISP_REF0)) + +#define PMGR_CLKCFG_ENABLE_UMASK PMGR_CLKCFG_S0_CLK_CFG_ENABLE_UMASK +#define PMGR_CLKCFG_SRC_SEL_UMASK PMGR_CLKCFG_MCU_REF_CLK_CFG_SRC_SEL_UMASK // Must have the max width of any CLKCFG SRC_SEL field +#define PMGR_CLKCFG_DIVISOR_UMASK PMGR_CLKCFG_S0_CLK_CFG_DIVISOR_UMASK +#define PMGR_CLKCFG_WAIT_COUNTER_UMASK PMGR_CLKCFG_MCU_REF_CLK_CFG_WAIT_COUNTER_UMASK +#define PMGR_CLKCFG_PENDING_XTRCT(_f) PMGR_CLKCFG_S0_CLK_CFG_PENDING_XTRCT(_f) +#define PMGR_CLKCFG_SRC_SEL_XTRCT(_f) PMGR_CLKCFG_MCU_REF_CLK_CFG_SRC_SEL_XTRCT(_f) // Must have the max width of any CLKCFG SRC_SEL field +#define PMGR_CLKCFG_ENABLE_XTRCT(_f) PMGR_CLKCFG_MCU_REF_CLK_CFG_ENABLE_XTRCT(_f) +#define PMGR_CLKCFG_DIVISOR_XTRCT(_f) PMGR_CLKCFG_S0_CLK_CFG_DIVISOR_XTRCT(_f) +#define PMGR_CLKCFG_SRC_SEL_INSRT(_f) PMGR_CLKCFG_MCU_REF_CLK_CFG_SRC_SEL_INSRT(_f) // Must have the max width of any CLKCFG SRC_SEL field + +#define rPMGR_MISC_CFG_ACG (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_MISC_CFG_ACG_OFFSET)) +#define rPMGR_MISC_CFG_ASYNC_XOVER_ACG (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_MISC_CFG_ASYNC_XOVER_ACG_OFFSET)) + +// MiniPMGR PS +#define rMINIPMGR_PS(_x) (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_PS_##_x##_PS_OFFSET)) + +#define rMINIPMGR_CLK_CFG(_x) (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_##_x##_CLK_CFG_OFFSET)) +#define rMINIPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_CLK_DIVIDER_ACG_CFG_OFFSET)) + +#define rMINIPMGR_MISC_CFG_ACG (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET)) + +#define rMINIPMGR_LPPLL_CTL (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_LPPLL_CTL_OFFSET)) +#define rMINIPMGR_LPPLL_CFG (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_LPPLL_CFG_OFFSET)) + +// MiniPMGR Watchdog +#define rPMGR_CHIP_WDOG_TMR (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER_OFFSET)) +#define rPMGR_CHIP_WDOG_RST_CNT (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_RESET_COUNT_OFFSET)) +#define rPMGR_CHIP_WDOG_INTR_CNT (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_INTERRUPT_COUNT_OFFSET)) +#define rPMGR_CHIP_WDOG_CTL (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_CONTROL_OFFSET)) +#define rPMGR_SYS_WDOG_TMR (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER_OFFSET)) +#define rPMGR_SYS_WDOG_RST_CNT (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_RESET_COUNT_OFFSET)) +#define rPMGR_SYS_WDOG_CTL (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_CONTROL_OFFSET)) + +// PMGR Event Timer +#define rPMGR_EVENT_TMR (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_TIMERS_EVENT_TIMER_OFFSET)) +#define rPMGR_EVENT_TMR_PERIOD (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_TIMERS_EVENT_TIMER_PERIOD_OFFSET)) +#define rPMGR_EVENT_TMR_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_TIMERS_EVENT_TIMER_CTL_OFFSET)) + +// NCO Config block +#define rPMGR_NCO_CLK_CFG(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_NCO_##_n##_CLK_CFG_OFFSET)) + +// Misc Clock Tree Power Saving Regs +#define rPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_CLKCFG_CLK_DIVIDER_ACG_CFG_OFFSET)) +#define rPMGR_CLK_POWER_CONFIG (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_CLKCFG_CLK_POWER_CONFIG_OFFSET)) + +// SOC Perf State +static const int PMGR_SOC_PERF_STATE_ENTRY_COUNT = 8; +static const int PMGR_SOC_PERF_STATE_STRIDE = (PMGR_SOC_PERF_STATE_ENTRY_1A_OFFSET - PMGR_SOC_PERF_STATE_ENTRY_0A_OFFSET); +static const int kSOC_PERF_STATE_MAX_CNT = 6; +#define rPMGR_SOC_PERF_STATE_ENTRY_A(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0A_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) +#define rPMGR_SOC_PERF_STATE_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_CTL_OFFSET)) + +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK (PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_UMASK | PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_UMASK) +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(_cfg, _src) (PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_INSRT(_cfg) | PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_INSRT(_src)) + +// First two entries used by AOP Config Engine +#define PMGR_SOC_PERF_STATE_FIRST_ENTRY (PMGR_SOC_PERF_STATE_ENTRY_COUNT - kSOC_PERF_STATE_MAX_CNT) +#define PMGR_SOC_PERF_STATE_TO_ENTRY(_s) (PMGR_SOC_PERF_STATE_ENTRY_COUNT - (_s) - 1) + +enum pmgr_soc_perf_state_index { + kSOC_PERF_STATE_BYPASS = 0, + kSOC_PERF_STATE_SECUREROM, + kSOC_PERF_STATE_IBOOT, + kSOC_PERF_STATE_VMIN = kSOC_PERF_STATE_IBOOT, + kSOC_PERF_STATE_IBOOT_CNT +}; + +static const int PMGR_SCRATCH_REG_STRIDE = (PMGR_SCRATCH_1_OFFSET - PMGR_SCRATCH_0_OFFSET); +#define rPMGR_SCRATCH(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_SCRATCH_0_OFFSET + ((_n) * PMGR_SCRATCH_REG_STRIDE))) +#define rPMGR_SCRATCH0 rPMGR_SCRATCH(0) /* Flags */ +#define rPMGR_SCRATCH1 rPMGR_SCRATCH(1) +#define rPMGR_SCRATCH2 rPMGR_SCRATCH(2) +#define rPMGR_SCRATCH3 rPMGR_SCRATCH(3) +#define rPMGR_SCRATCH4 rPMGR_SCRATCH(4) +#define rPMGR_SCRATCH5 rPMGR_SCRATCH(5) +#define rPMGR_SCRATCH6 rPMGR_SCRATCH(6) +#define rPMGR_SCRATCH7 rPMGR_SCRATCH(7) /* Consistent debug root pointer */ +#define rPMGR_SCRATCH8 rPMGR_SCRATCH(8) + +#define rPMGR_SCRATCH_MEM_INFO rPMGR_SCRATCH(9) +#define rPMGR_SCRATCH_BOOT_NONCE_0 rPMGR_SCRATCH(10) +#define rPMGR_SCRATCH_BOOT_NONCE_1 rPMGR_SCRATCH(11) +#define rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST rPMGR_SCRATCH(12) +#define rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST rPMGR_SCRATCH(23) +#define PMGR_SCRATCH_BOOT_MANIFEST_REGISTERS (384 / 32) + +static const int MINIPMGR_SCRATCH_REG_STRIDE = (MINIPMGR_MINI_SCRATCH_SCRATCH1_OFFSET - MINIPMGR_MINI_SCRATCH_SCRATCH0_OFFSET); +#define rMINIPMGR_SCRATCH(_n) (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_SCRATCH_OFFSET + ((_n) * MINIPMGR_SCRATCH_REG_STRIDE))) +#define rMINIPMGR_SCRATCH0 rMINIPMGR_SCRATCH(0) +#define rMINIPMGR_SCRATCH1 rMINIPMGR_SCRATCH(1) /* Consistent debug root pointer */ +#define rMINIPMGR_SCRATCH2 rMINIPMGR_SCRATCH(2) +#define rMINIPMGR_SCRATCH3 rMINIPMGR_SCRATCH(3) +#define rMINIPMGR_SCRATCH4 rMINIPMGR_SCRATCH(4) +#define rMINIPMGR_SCRATCH5 rMINIPMGR_SCRATCH(5) +#define rMINIPMGR_SCRATCH6 rMINIPMGR_SCRATCH(6) +#define rMINIPMGR_SCRATCH7 rMINIPMGR_SCRATCH(7) +#define rMINIPMGR_SCRATCH8 rMINIPMGR_SCRATCH(8) +#define rMINIPMGR_SCRATCH9 rMINIPMGR_SCRATCH(9) +#define rMINIPMGR_SCRATCH10 rMINIPMGR_SCRATCH(10) +#define rMINIPMGR_SCRATCH11 rMINIPMGR_SCRATCH(11) + +#define rPMGR_SECURITY (*(volatile uint32_t *) (AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_OFFSET)) + +extern void pmgr_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/t8002/include/platform/soc/spds/aes.h b/platform/t8002/include/platform/soc/spds/aes.h new file mode 100644 index 0000000..bf263d2 --- /dev/null +++ b/platform/t8002/include/platform/soc/spds/aes.h @@ -0,0 +1,22587 @@ +/*! + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_AES_H +#define SPDS_AES_H + +/* Chips s5l8960x_a0, s5l8960x_b0, s5l8960x_b1, t7000_a0, t7000_b0, t7000_b1, t7001_a0, t7001_a1 */ +/* Reported Version 1.1.2 */ +#define SPDS_AES_V1 1 + +/* Chips s7002_a1, s7002_a1 */ +/* Reported Version 1.1.0 */ +#define SPDS_AES_V2 2 + +/* Chips s8000_a1, s8000_a1 */ +/* Reported Version 0.0.1 */ +#define SPDS_AES_V3 3 + +/* Chips s8000_b0 */ +/* Reported Version 0.0.1 */ +#define SPDS_AES_V4 4 + +/* Chips s8001_a0 */ +/* Reported Version 0.0.1 */ +#define SPDS_AES_V5 5 + +/* Chips t8002_a0 */ +/* Reported Version 0.0.1 */ +#define SPDS_AES_V6 6 + +/* Chips t8010_a0 */ +/* Reported Version 0.0.1 */ +#define SPDS_AES_V7 7 + +#if (defined(SPDS_AES_VERSION) && (SPDS_AES_VERSION < 1 || SPDS_AES_VERSION > 7)) +#error 'SPDS_AES_VERSION': value is invalid. +#endif + +/*! @ingroup group873046 */ + +/*! + * @addtogroup group995868 aes + * @brief Address = 0x20a108000 + * @details Version = 0.0.1 @n + * AES Registers + * @{ + */ + +/*! + * @addtogroup group995869 blk (AES) + * @brief Offset = 0x0 + * @details General Control registers + * @see @ref SAIAddressBlock + * @{ + */ + +#define AES_BLK_OFFSET (0x0) + +/*! + * @addtogroup group995870 version + * @brief Offset = 0x0 + * @details IP Implementation Version + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_VERSION_OFFSET_V3 (0x0 + 0x0) +#define AES_BLK_VERSION_OFFSET_V4 (0x0 + 0x0) +#define AES_BLK_VERSION_OFFSET_V5 (0x0 + 0x0) +#define AES_BLK_VERSION_OFFSET_V6 (0x0 + 0x0) +#define AES_BLK_VERSION_OFFSET_V7 (0x0 + 0x0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_OFFSET AES_BLK_VERSION_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_OFFSET AES_BLK_VERSION_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_OFFSET AES_BLK_VERSION_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_OFFSET AES_BLK_VERSION_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_OFFSET AES_BLK_VERSION_OFFSET_V7 +#endif + +/*! + * @addtogroup group995871 minor_release + * @brief Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 + * @details Minor Release Number + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V3 (0) +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V4 (0) +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V5 (0) +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V6 (0) +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MINOR_RELEASE_SHIFT AES_BLK_VERSION_MINOR_RELEASE_SHIFT_V7 +#endif + +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V3 (8) +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V4 (8) +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V5 (8) +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V6 (8) +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MINOR_RELEASE_WIDTH AES_BLK_VERSION_MINOR_RELEASE_WIDTH_V7 +#endif + +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK_V3 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK_V4 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK_V5 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK_V6 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK AES_BLK_VERSION_MINOR_RELEASE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK AES_BLK_VERSION_MINOR_RELEASE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK AES_BLK_VERSION_MINOR_RELEASE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK AES_BLK_VERSION_MINOR_RELEASE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MINOR_RELEASE_UMASK AES_BLK_VERSION_MINOR_RELEASE_UMASK_V7 +#endif + +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK_V3 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK_V4 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK_V5 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK_V6 (0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK AES_BLK_VERSION_MINOR_RELEASE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK AES_BLK_VERSION_MINOR_RELEASE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK AES_BLK_VERSION_MINOR_RELEASE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK AES_BLK_VERSION_MINOR_RELEASE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MINOR_RELEASE_SMASK AES_BLK_VERSION_MINOR_RELEASE_SMASK_V7 +#endif + +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MINOR_RELEASE_XTRCT AES_BLK_VERSION_MINOR_RELEASE_XTRCT_V7 +#endif + +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT_V3(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT_V4(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT_V5(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT_V6(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT_V7(f) ((((uint32_t)f) & 0xff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT AES_BLK_VERSION_MINOR_RELEASE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT AES_BLK_VERSION_MINOR_RELEASE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT AES_BLK_VERSION_MINOR_RELEASE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT AES_BLK_VERSION_MINOR_RELEASE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MINOR_RELEASE_INSRT AES_BLK_VERSION_MINOR_RELEASE_INSRT_V7 +#endif + +/*! @} minor_release */ + +/*! + * @addtogroup group995872 major_release + * @brief Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 + * @details Major Release Number + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V3 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V4 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V5 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V6 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MAJOR_RELEASE_SHIFT AES_BLK_VERSION_MAJOR_RELEASE_SHIFT_V7 +#endif + +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V3 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V4 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V5 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V6 (8) +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MAJOR_RELEASE_WIDTH AES_BLK_VERSION_MAJOR_RELEASE_WIDTH_V7 +#endif + +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V3 (0xff00) +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V4 (0xff00) +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V5 (0xff00) +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V6 (0xff00) +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V7 (0xff00) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MAJOR_RELEASE_UMASK AES_BLK_VERSION_MAJOR_RELEASE_UMASK_V7 +#endif + +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V3 (0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V4 (0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V5 (0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V6 (0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MAJOR_RELEASE_SMASK AES_BLK_VERSION_MAJOR_RELEASE_SMASK_V7 +#endif + +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V3(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V4(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V5(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MAJOR_RELEASE_XTRCT AES_BLK_VERSION_MAJOR_RELEASE_XTRCT_V7 +#endif + +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V3(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V4(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V5(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V6(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V7(f) ((((uint32_t)f) & 0xff) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_MAJOR_RELEASE_INSRT AES_BLK_VERSION_MAJOR_RELEASE_INSRT_V7 +#endif + +/*! @} major_release */ + +/*! + * @addtogroup group995873 fld (VERSION) + * @brief Range = 23:16 | Width = 8 | Access = read-only | Default = 0x0 + * @details Version Number + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_VERSION_FLD_SHIFT_V3 (16) +#define AES_BLK_VERSION_FLD_SHIFT_V4 (16) +#define AES_BLK_VERSION_FLD_SHIFT_V5 (16) +#define AES_BLK_VERSION_FLD_SHIFT_V6 (16) +#define AES_BLK_VERSION_FLD_SHIFT_V7 (16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_FLD_SHIFT AES_BLK_VERSION_FLD_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_FLD_SHIFT AES_BLK_VERSION_FLD_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_FLD_SHIFT AES_BLK_VERSION_FLD_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_FLD_SHIFT AES_BLK_VERSION_FLD_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_FLD_SHIFT AES_BLK_VERSION_FLD_SHIFT_V7 +#endif + +#define AES_BLK_VERSION_FLD_WIDTH_V3 (8) +#define AES_BLK_VERSION_FLD_WIDTH_V4 (8) +#define AES_BLK_VERSION_FLD_WIDTH_V5 (8) +#define AES_BLK_VERSION_FLD_WIDTH_V6 (8) +#define AES_BLK_VERSION_FLD_WIDTH_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_FLD_WIDTH AES_BLK_VERSION_FLD_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_FLD_WIDTH AES_BLK_VERSION_FLD_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_FLD_WIDTH AES_BLK_VERSION_FLD_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_FLD_WIDTH AES_BLK_VERSION_FLD_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_FLD_WIDTH AES_BLK_VERSION_FLD_WIDTH_V7 +#endif + +#define AES_BLK_VERSION_FLD_UMASK_V3 (0xff0000) +#define AES_BLK_VERSION_FLD_UMASK_V4 (0xff0000) +#define AES_BLK_VERSION_FLD_UMASK_V5 (0xff0000) +#define AES_BLK_VERSION_FLD_UMASK_V6 (0xff0000) +#define AES_BLK_VERSION_FLD_UMASK_V7 (0xff0000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_FLD_UMASK AES_BLK_VERSION_FLD_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_FLD_UMASK AES_BLK_VERSION_FLD_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_FLD_UMASK AES_BLK_VERSION_FLD_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_FLD_UMASK AES_BLK_VERSION_FLD_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_FLD_UMASK AES_BLK_VERSION_FLD_UMASK_V7 +#endif + +#define AES_BLK_VERSION_FLD_SMASK_V3 (0xff) +#define AES_BLK_VERSION_FLD_SMASK_V4 (0xff) +#define AES_BLK_VERSION_FLD_SMASK_V5 (0xff) +#define AES_BLK_VERSION_FLD_SMASK_V6 (0xff) +#define AES_BLK_VERSION_FLD_SMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_FLD_SMASK AES_BLK_VERSION_FLD_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_FLD_SMASK AES_BLK_VERSION_FLD_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_FLD_SMASK AES_BLK_VERSION_FLD_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_FLD_SMASK AES_BLK_VERSION_FLD_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_FLD_SMASK AES_BLK_VERSION_FLD_SMASK_V7 +#endif + +#define AES_BLK_VERSION_FLD_XTRCT_V3(r) ((((uint32_t)r) >> 16) & 0xff) +#define AES_BLK_VERSION_FLD_XTRCT_V4(r) ((((uint32_t)r) >> 16) & 0xff) +#define AES_BLK_VERSION_FLD_XTRCT_V5(r) ((((uint32_t)r) >> 16) & 0xff) +#define AES_BLK_VERSION_FLD_XTRCT_V6(r) ((((uint32_t)r) >> 16) & 0xff) +#define AES_BLK_VERSION_FLD_XTRCT_V7(r) ((((uint32_t)r) >> 16) & 0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_FLD_XTRCT AES_BLK_VERSION_FLD_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_FLD_XTRCT AES_BLK_VERSION_FLD_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_FLD_XTRCT AES_BLK_VERSION_FLD_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_FLD_XTRCT AES_BLK_VERSION_FLD_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_FLD_XTRCT AES_BLK_VERSION_FLD_XTRCT_V7 +#endif + +#define AES_BLK_VERSION_FLD_INSRT_V3(f) ((((uint32_t)f) & 0xff) << 16) +#define AES_BLK_VERSION_FLD_INSRT_V4(f) ((((uint32_t)f) & 0xff) << 16) +#define AES_BLK_VERSION_FLD_INSRT_V5(f) ((((uint32_t)f) & 0xff) << 16) +#define AES_BLK_VERSION_FLD_INSRT_V6(f) ((((uint32_t)f) & 0xff) << 16) +#define AES_BLK_VERSION_FLD_INSRT_V7(f) ((((uint32_t)f) & 0xff) << 16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_VERSION_FLD_INSRT AES_BLK_VERSION_FLD_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_VERSION_FLD_INSRT AES_BLK_VERSION_FLD_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_VERSION_FLD_INSRT AES_BLK_VERSION_FLD_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_VERSION_FLD_INSRT AES_BLK_VERSION_FLD_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_VERSION_FLD_INSRT AES_BLK_VERSION_FLD_INSRT_V7 +#endif + +/*! @} fld (VERSION) */ + +/*! + * @addtogroup group995875 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_VERSION_TNBLE_RESET_UMASK_S8000_A1 (0xffffff) +#define AES_BLK_VERSION_TNBLE_RESET_UMASK_S8000_B0 (0xffffff) +#define AES_BLK_VERSION_TNBLE_RESET_UMASK_S8001_A0 (0xffffff) +#define AES_BLK_VERSION_TNBLE_RESET_UMASK_T8002_A0 (0xffffff) +#define AES_BLK_VERSION_TNBLE_RESET_UMASK_T8010_A0 (0xffffff) + +#define AES_BLK_VERSION_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_VERSION_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_VERSION_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_VERSION_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_VERSION_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} version */ + +/*! + * @addtogroup group995876 config + * @brief Offset = 0x4 + * @details Configuration register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_CONFIG_OFFSET_V3 (0x0 + 0x4) +#define AES_BLK_CONFIG_OFFSET_V4 (0x0 + 0x4) +#define AES_BLK_CONFIG_OFFSET_V5 (0x0 + 0x4) +#define AES_BLK_CONFIG_OFFSET_V6 (0x0 + 0x4) +#define AES_BLK_CONFIG_OFFSET_V7 (0x0 + 0x4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_OFFSET AES_BLK_CONFIG_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_OFFSET AES_BLK_CONFIG_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_OFFSET AES_BLK_CONFIG_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_OFFSET AES_BLK_CONFIG_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_OFFSET AES_BLK_CONFIG_OFFSET_V7 +#endif + +/*! + * @addtogroup group995877 axi_aruser + * @brief Range = 3:0 | Width = 4 | Access = read-write | Default = 0x0 + * @details USER ID for AXI Address Read transactions + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V3 (0) +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V4 (0) +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V5 (0) +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V6 (0) +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARUSER_SHIFT AES_BLK_CONFIG_AXI_ARUSER_SHIFT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V3 (4) +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V4 (4) +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V5 (4) +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V6 (4) +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARUSER_WIDTH AES_BLK_CONFIG_AXI_ARUSER_WIDTH_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK_V3 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK_V4 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK_V5 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK_V6 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK_V7 (0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK AES_BLK_CONFIG_AXI_ARUSER_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK AES_BLK_CONFIG_AXI_ARUSER_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK AES_BLK_CONFIG_AXI_ARUSER_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK AES_BLK_CONFIG_AXI_ARUSER_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARUSER_UMASK AES_BLK_CONFIG_AXI_ARUSER_UMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK_V3 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK_V4 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK_V5 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK_V6 (0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK_V7 (0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK AES_BLK_CONFIG_AXI_ARUSER_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK AES_BLK_CONFIG_AXI_ARUSER_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK AES_BLK_CONFIG_AXI_ARUSER_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK AES_BLK_CONFIG_AXI_ARUSER_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARUSER_SMASK AES_BLK_CONFIG_AXI_ARUSER_SMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xf) +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARUSER_XTRCT AES_BLK_CONFIG_AXI_ARUSER_XTRCT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT_V3(f) ((((uint32_t)f) & 0xf) << 0) +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT_V4(f) ((((uint32_t)f) & 0xf) << 0) +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT_V5(f) ((((uint32_t)f) & 0xf) << 0) +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT_V6(f) ((((uint32_t)f) & 0xf) << 0) +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT_V7(f) ((((uint32_t)f) & 0xf) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT AES_BLK_CONFIG_AXI_ARUSER_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT AES_BLK_CONFIG_AXI_ARUSER_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT AES_BLK_CONFIG_AXI_ARUSER_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT AES_BLK_CONFIG_AXI_ARUSER_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARUSER_INSRT AES_BLK_CONFIG_AXI_ARUSER_INSRT_V7 +#endif + +/*! @} axi_aruser */ + +/*! + * @addtogroup group995878 axi_arcache + * @brief Range = 7:4 | Width = 4 | Access = read-write | Default = 0x0 + * @details ARCACHE for AXI Address Read transactions + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V3 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V4 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V5 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V6 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARCACHE_SHIFT AES_BLK_CONFIG_AXI_ARCACHE_SHIFT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V3 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V4 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V5 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V6 (4) +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARCACHE_WIDTH AES_BLK_CONFIG_AXI_ARCACHE_WIDTH_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V3 (0xf0) +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V4 (0xf0) +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V5 (0xf0) +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V6 (0xf0) +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V7 (0xf0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARCACHE_UMASK AES_BLK_CONFIG_AXI_ARCACHE_UMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V3 (0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V4 (0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V5 (0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V6 (0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V7 (0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARCACHE_SMASK AES_BLK_CONFIG_AXI_ARCACHE_SMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V3(r) ((((uint32_t)r) >> 4) & 0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V4(r) ((((uint32_t)r) >> 4) & 0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V5(r) ((((uint32_t)r) >> 4) & 0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V6(r) ((((uint32_t)r) >> 4) & 0xf) +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V7(r) ((((uint32_t)r) >> 4) & 0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARCACHE_XTRCT AES_BLK_CONFIG_AXI_ARCACHE_XTRCT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V3(f) ((((uint32_t)f) & 0xf) << 4) +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V4(f) ((((uint32_t)f) & 0xf) << 4) +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V5(f) ((((uint32_t)f) & 0xf) << 4) +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V6(f) ((((uint32_t)f) & 0xf) << 4) +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V7(f) ((((uint32_t)f) & 0xf) << 4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_ARCACHE_INSRT AES_BLK_CONFIG_AXI_ARCACHE_INSRT_V7 +#endif + +/*! @} axi_arcache */ + +/*! + * @addtogroup group995879 axi_awuser + * @brief Range = 11:8 | Width = 4 | Access = read-write | Default = 0x0 + * @details USER ID for AXI Address Write transactions + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V3 (8) +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V4 (8) +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V5 (8) +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V6 (8) +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWUSER_SHIFT AES_BLK_CONFIG_AXI_AWUSER_SHIFT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V3 (4) +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V4 (4) +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V5 (4) +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V6 (4) +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWUSER_WIDTH AES_BLK_CONFIG_AXI_AWUSER_WIDTH_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK_V3 (0xf00) +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK_V4 (0xf00) +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK_V5 (0xf00) +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK_V6 (0xf00) +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK_V7 (0xf00) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK AES_BLK_CONFIG_AXI_AWUSER_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK AES_BLK_CONFIG_AXI_AWUSER_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK AES_BLK_CONFIG_AXI_AWUSER_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK AES_BLK_CONFIG_AXI_AWUSER_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWUSER_UMASK AES_BLK_CONFIG_AXI_AWUSER_UMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK_V3 (0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK_V4 (0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK_V5 (0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK_V6 (0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK_V7 (0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK AES_BLK_CONFIG_AXI_AWUSER_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK AES_BLK_CONFIG_AXI_AWUSER_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK AES_BLK_CONFIG_AXI_AWUSER_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK AES_BLK_CONFIG_AXI_AWUSER_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWUSER_SMASK AES_BLK_CONFIG_AXI_AWUSER_SMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V3(r) ((((uint32_t)r) >> 8) & 0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V4(r) ((((uint32_t)r) >> 8) & 0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V5(r) ((((uint32_t)r) >> 8) & 0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0xf) +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWUSER_XTRCT AES_BLK_CONFIG_AXI_AWUSER_XTRCT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT_V3(f) ((((uint32_t)f) & 0xf) << 8) +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT_V4(f) ((((uint32_t)f) & 0xf) << 8) +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT_V5(f) ((((uint32_t)f) & 0xf) << 8) +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT_V6(f) ((((uint32_t)f) & 0xf) << 8) +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT_V7(f) ((((uint32_t)f) & 0xf) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT AES_BLK_CONFIG_AXI_AWUSER_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT AES_BLK_CONFIG_AXI_AWUSER_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT AES_BLK_CONFIG_AXI_AWUSER_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT AES_BLK_CONFIG_AXI_AWUSER_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWUSER_INSRT AES_BLK_CONFIG_AXI_AWUSER_INSRT_V7 +#endif + +/*! @} axi_awuser */ + +/*! + * @addtogroup group995880 axi_awcache + * @brief Range = 15:12 | Width = 4 | Access = read-write | Default = 0x0 + * @details AWCACHE for AXI Address Write transactions + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V3 (12) +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V4 (12) +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V5 (12) +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V6 (12) +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V7 (12) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWCACHE_SHIFT AES_BLK_CONFIG_AXI_AWCACHE_SHIFT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V3 (4) +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V4 (4) +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V5 (4) +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V6 (4) +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWCACHE_WIDTH AES_BLK_CONFIG_AXI_AWCACHE_WIDTH_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V3 (0xf000) +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V4 (0xf000) +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V5 (0xf000) +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V6 (0xf000) +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V7 (0xf000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWCACHE_UMASK AES_BLK_CONFIG_AXI_AWCACHE_UMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V3 (0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V4 (0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V5 (0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V6 (0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V7 (0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWCACHE_SMASK AES_BLK_CONFIG_AXI_AWCACHE_SMASK_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V3(r) ((((uint32_t)r) >> 12) & 0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V4(r) ((((uint32_t)r) >> 12) & 0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V5(r) ((((uint32_t)r) >> 12) & 0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V6(r) ((((uint32_t)r) >> 12) & 0xf) +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V7(r) ((((uint32_t)r) >> 12) & 0xf) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWCACHE_XTRCT AES_BLK_CONFIG_AXI_AWCACHE_XTRCT_V7 +#endif + +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V3(f) ((((uint32_t)f) & 0xf) << 12) +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V4(f) ((((uint32_t)f) & 0xf) << 12) +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V5(f) ((((uint32_t)f) & 0xf) << 12) +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V6(f) ((((uint32_t)f) & 0xf) << 12) +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V7(f) ((((uint32_t)f) & 0xf) << 12) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_AXI_AWCACHE_INSRT AES_BLK_CONFIG_AXI_AWCACHE_INSRT_V7 +#endif + +/*! @} axi_awcache */ + +/*! + * @addtogroup group995881 burst_size + * @brief Range = 17:16 | Width = 2 | Access = read-write | Default = 0x0 + * @details 0 = Full Size (default) 64 bytes, 1 = Half Size 32 bytes, 2 = + * Quarter Size 16 bytes, 3 = N/A + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT_V3 (16) +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT_V4 (16) +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT_V5 (16) +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT_V6 (16) +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT_V7 (16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT AES_BLK_CONFIG_BURST_SIZE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT AES_BLK_CONFIG_BURST_SIZE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT AES_BLK_CONFIG_BURST_SIZE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT AES_BLK_CONFIG_BURST_SIZE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_BURST_SIZE_SHIFT AES_BLK_CONFIG_BURST_SIZE_SHIFT_V7 +#endif + +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH_V3 (2) +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH_V4 (2) +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH_V5 (2) +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH_V6 (2) +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH AES_BLK_CONFIG_BURST_SIZE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH AES_BLK_CONFIG_BURST_SIZE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH AES_BLK_CONFIG_BURST_SIZE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH AES_BLK_CONFIG_BURST_SIZE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_BURST_SIZE_WIDTH AES_BLK_CONFIG_BURST_SIZE_WIDTH_V7 +#endif + +#define AES_BLK_CONFIG_BURST_SIZE_UMASK_V3 (0x30000) +#define AES_BLK_CONFIG_BURST_SIZE_UMASK_V4 (0x30000) +#define AES_BLK_CONFIG_BURST_SIZE_UMASK_V5 (0x30000) +#define AES_BLK_CONFIG_BURST_SIZE_UMASK_V6 (0x30000) +#define AES_BLK_CONFIG_BURST_SIZE_UMASK_V7 (0x30000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_BURST_SIZE_UMASK AES_BLK_CONFIG_BURST_SIZE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_BURST_SIZE_UMASK AES_BLK_CONFIG_BURST_SIZE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_BURST_SIZE_UMASK AES_BLK_CONFIG_BURST_SIZE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_BURST_SIZE_UMASK AES_BLK_CONFIG_BURST_SIZE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_BURST_SIZE_UMASK AES_BLK_CONFIG_BURST_SIZE_UMASK_V7 +#endif + +#define AES_BLK_CONFIG_BURST_SIZE_SMASK_V3 (0x3) +#define AES_BLK_CONFIG_BURST_SIZE_SMASK_V4 (0x3) +#define AES_BLK_CONFIG_BURST_SIZE_SMASK_V5 (0x3) +#define AES_BLK_CONFIG_BURST_SIZE_SMASK_V6 (0x3) +#define AES_BLK_CONFIG_BURST_SIZE_SMASK_V7 (0x3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_BURST_SIZE_SMASK AES_BLK_CONFIG_BURST_SIZE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_BURST_SIZE_SMASK AES_BLK_CONFIG_BURST_SIZE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_BURST_SIZE_SMASK AES_BLK_CONFIG_BURST_SIZE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_BURST_SIZE_SMASK AES_BLK_CONFIG_BURST_SIZE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_BURST_SIZE_SMASK AES_BLK_CONFIG_BURST_SIZE_SMASK_V7 +#endif + +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT_V3(r) ((((uint32_t)r) >> 16) & 0x3) +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT_V4(r) ((((uint32_t)r) >> 16) & 0x3) +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT_V5(r) ((((uint32_t)r) >> 16) & 0x3) +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT_V6(r) ((((uint32_t)r) >> 16) & 0x3) +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT_V7(r) ((((uint32_t)r) >> 16) & 0x3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT AES_BLK_CONFIG_BURST_SIZE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT AES_BLK_CONFIG_BURST_SIZE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT AES_BLK_CONFIG_BURST_SIZE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT AES_BLK_CONFIG_BURST_SIZE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_BURST_SIZE_XTRCT AES_BLK_CONFIG_BURST_SIZE_XTRCT_V7 +#endif + +#define AES_BLK_CONFIG_BURST_SIZE_INSRT_V3(f) ((((uint32_t)f) & 0x3) << 16) +#define AES_BLK_CONFIG_BURST_SIZE_INSRT_V4(f) ((((uint32_t)f) & 0x3) << 16) +#define AES_BLK_CONFIG_BURST_SIZE_INSRT_V5(f) ((((uint32_t)f) & 0x3) << 16) +#define AES_BLK_CONFIG_BURST_SIZE_INSRT_V6(f) ((((uint32_t)f) & 0x3) << 16) +#define AES_BLK_CONFIG_BURST_SIZE_INSRT_V7(f) ((((uint32_t)f) & 0x3) << 16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONFIG_BURST_SIZE_INSRT AES_BLK_CONFIG_BURST_SIZE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONFIG_BURST_SIZE_INSRT AES_BLK_CONFIG_BURST_SIZE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONFIG_BURST_SIZE_INSRT AES_BLK_CONFIG_BURST_SIZE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONFIG_BURST_SIZE_INSRT AES_BLK_CONFIG_BURST_SIZE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONFIG_BURST_SIZE_INSRT AES_BLK_CONFIG_BURST_SIZE_INSRT_V7 +#endif + +/*! @} burst_size */ + +/*! + * @addtogroup group995883 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_CONFIG_TNBLE_RESET_UMASK_S8000_A1 (0x3ffff) +#define AES_BLK_CONFIG_TNBLE_RESET_UMASK_S8000_B0 (0x3ffff) +#define AES_BLK_CONFIG_TNBLE_RESET_UMASK_S8001_A0 (0x3ffff) +#define AES_BLK_CONFIG_TNBLE_RESET_UMASK_T8002_A0 (0x3ffff) +#define AES_BLK_CONFIG_TNBLE_RESET_UMASK_T8010_A0 (0x3ffff) + +#define AES_BLK_CONFIG_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_CONFIG_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_CONFIG_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_CONFIG_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_CONFIG_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! + * @addtogroup group995884 _default (default) + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_CONFIG_TNBLE_DEFAULT_UMASK_S8000_A1 (0x30000) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_UMASK_S8000_B0 (0x30000) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_UMASK_S8001_A0 (0x30000) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_UMASK_T8002_A0 (0x30000) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_UMASK_T8010_A0 (0x30000) + +#define AES_BLK_CONFIG_TNBLE_DEFAULT_VALUE_S8000_A1 (0x0) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_VALUE_S8000_B0 (0x0) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_VALUE_S8001_A0 (0x0) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_VALUE_T8002_A0 (0x0) +#define AES_BLK_CONFIG_TNBLE_DEFAULT_VALUE_T8010_A0 (0x0) + +/*! @} _default (default) */ + +/*! @} config */ + +/*! + * @addtogroup group995885 control + * @brief Offset = 0x8 + * @details Control Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_CONTROL_OFFSET_V3 (0x0 + 0x8) +#define AES_BLK_CONTROL_OFFSET_V4 (0x0 + 0x8) +#define AES_BLK_CONTROL_OFFSET_V5 (0x0 + 0x8) +#define AES_BLK_CONTROL_OFFSET_V6 (0x0 + 0x8) +#define AES_BLK_CONTROL_OFFSET_V7 (0x0 + 0x8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_OFFSET AES_BLK_CONTROL_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_OFFSET AES_BLK_CONTROL_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_OFFSET AES_BLK_CONTROL_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_OFFSET AES_BLK_CONTROL_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_OFFSET AES_BLK_CONTROL_OFFSET_V7 +#endif + +/*! + * @addtogroup group995886 start + * @brief Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Start executing commands in Command FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONTROL_START_SHIFT_V3 (0) +#define AES_BLK_CONTROL_START_SHIFT_V4 (0) +#define AES_BLK_CONTROL_START_SHIFT_V5 (0) +#define AES_BLK_CONTROL_START_SHIFT_V6 (0) +#define AES_BLK_CONTROL_START_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_START_SHIFT AES_BLK_CONTROL_START_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_START_SHIFT AES_BLK_CONTROL_START_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_START_SHIFT AES_BLK_CONTROL_START_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_START_SHIFT AES_BLK_CONTROL_START_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_START_SHIFT AES_BLK_CONTROL_START_SHIFT_V7 +#endif + +#define AES_BLK_CONTROL_START_WIDTH_V3 (1) +#define AES_BLK_CONTROL_START_WIDTH_V4 (1) +#define AES_BLK_CONTROL_START_WIDTH_V5 (1) +#define AES_BLK_CONTROL_START_WIDTH_V6 (1) +#define AES_BLK_CONTROL_START_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_START_WIDTH AES_BLK_CONTROL_START_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_START_WIDTH AES_BLK_CONTROL_START_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_START_WIDTH AES_BLK_CONTROL_START_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_START_WIDTH AES_BLK_CONTROL_START_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_START_WIDTH AES_BLK_CONTROL_START_WIDTH_V7 +#endif + +#define AES_BLK_CONTROL_START_UMASK_V3 (0x1) +#define AES_BLK_CONTROL_START_UMASK_V4 (0x1) +#define AES_BLK_CONTROL_START_UMASK_V5 (0x1) +#define AES_BLK_CONTROL_START_UMASK_V6 (0x1) +#define AES_BLK_CONTROL_START_UMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_START_UMASK AES_BLK_CONTROL_START_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_START_UMASK AES_BLK_CONTROL_START_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_START_UMASK AES_BLK_CONTROL_START_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_START_UMASK AES_BLK_CONTROL_START_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_START_UMASK AES_BLK_CONTROL_START_UMASK_V7 +#endif + +#define AES_BLK_CONTROL_START_SMASK_V3 (0x1) +#define AES_BLK_CONTROL_START_SMASK_V4 (0x1) +#define AES_BLK_CONTROL_START_SMASK_V5 (0x1) +#define AES_BLK_CONTROL_START_SMASK_V6 (0x1) +#define AES_BLK_CONTROL_START_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_START_SMASK AES_BLK_CONTROL_START_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_START_SMASK AES_BLK_CONTROL_START_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_START_SMASK AES_BLK_CONTROL_START_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_START_SMASK AES_BLK_CONTROL_START_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_START_SMASK AES_BLK_CONTROL_START_SMASK_V7 +#endif + +#define AES_BLK_CONTROL_START_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_CONTROL_START_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_CONTROL_START_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_CONTROL_START_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_CONTROL_START_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_START_XTRCT AES_BLK_CONTROL_START_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_START_XTRCT AES_BLK_CONTROL_START_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_START_XTRCT AES_BLK_CONTROL_START_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_START_XTRCT AES_BLK_CONTROL_START_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_START_XTRCT AES_BLK_CONTROL_START_XTRCT_V7 +#endif + +#define AES_BLK_CONTROL_START_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_CONTROL_START_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_CONTROL_START_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_CONTROL_START_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_CONTROL_START_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_START_INSRT AES_BLK_CONTROL_START_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_START_INSRT AES_BLK_CONTROL_START_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_START_INSRT AES_BLK_CONTROL_START_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_START_INSRT AES_BLK_CONTROL_START_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_START_INSRT AES_BLK_CONTROL_START_INSRT_V7 +#endif + +/*! @} start */ + +/*! + * @addtogroup group995887 stop + * @brief Range = 1 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Stop executing commands in Command FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONTROL_STOP_SHIFT_V3 (1) +#define AES_BLK_CONTROL_STOP_SHIFT_V4 (1) +#define AES_BLK_CONTROL_STOP_SHIFT_V5 (1) +#define AES_BLK_CONTROL_STOP_SHIFT_V6 (1) +#define AES_BLK_CONTROL_STOP_SHIFT_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_STOP_SHIFT AES_BLK_CONTROL_STOP_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_STOP_SHIFT AES_BLK_CONTROL_STOP_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_STOP_SHIFT AES_BLK_CONTROL_STOP_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_STOP_SHIFT AES_BLK_CONTROL_STOP_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_STOP_SHIFT AES_BLK_CONTROL_STOP_SHIFT_V7 +#endif + +#define AES_BLK_CONTROL_STOP_WIDTH_V3 (1) +#define AES_BLK_CONTROL_STOP_WIDTH_V4 (1) +#define AES_BLK_CONTROL_STOP_WIDTH_V5 (1) +#define AES_BLK_CONTROL_STOP_WIDTH_V6 (1) +#define AES_BLK_CONTROL_STOP_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_STOP_WIDTH AES_BLK_CONTROL_STOP_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_STOP_WIDTH AES_BLK_CONTROL_STOP_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_STOP_WIDTH AES_BLK_CONTROL_STOP_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_STOP_WIDTH AES_BLK_CONTROL_STOP_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_STOP_WIDTH AES_BLK_CONTROL_STOP_WIDTH_V7 +#endif + +#define AES_BLK_CONTROL_STOP_UMASK_V3 (0x2) +#define AES_BLK_CONTROL_STOP_UMASK_V4 (0x2) +#define AES_BLK_CONTROL_STOP_UMASK_V5 (0x2) +#define AES_BLK_CONTROL_STOP_UMASK_V6 (0x2) +#define AES_BLK_CONTROL_STOP_UMASK_V7 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_STOP_UMASK AES_BLK_CONTROL_STOP_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_STOP_UMASK AES_BLK_CONTROL_STOP_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_STOP_UMASK AES_BLK_CONTROL_STOP_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_STOP_UMASK AES_BLK_CONTROL_STOP_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_STOP_UMASK AES_BLK_CONTROL_STOP_UMASK_V7 +#endif + +#define AES_BLK_CONTROL_STOP_SMASK_V3 (0x1) +#define AES_BLK_CONTROL_STOP_SMASK_V4 (0x1) +#define AES_BLK_CONTROL_STOP_SMASK_V5 (0x1) +#define AES_BLK_CONTROL_STOP_SMASK_V6 (0x1) +#define AES_BLK_CONTROL_STOP_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_STOP_SMASK AES_BLK_CONTROL_STOP_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_STOP_SMASK AES_BLK_CONTROL_STOP_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_STOP_SMASK AES_BLK_CONTROL_STOP_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_STOP_SMASK AES_BLK_CONTROL_STOP_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_STOP_SMASK AES_BLK_CONTROL_STOP_SMASK_V7 +#endif + +#define AES_BLK_CONTROL_STOP_XTRCT_V3(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_CONTROL_STOP_XTRCT_V4(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_CONTROL_STOP_XTRCT_V5(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_CONTROL_STOP_XTRCT_V6(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_CONTROL_STOP_XTRCT_V7(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_STOP_XTRCT AES_BLK_CONTROL_STOP_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_STOP_XTRCT AES_BLK_CONTROL_STOP_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_STOP_XTRCT AES_BLK_CONTROL_STOP_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_STOP_XTRCT AES_BLK_CONTROL_STOP_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_STOP_XTRCT AES_BLK_CONTROL_STOP_XTRCT_V7 +#endif + +#define AES_BLK_CONTROL_STOP_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_CONTROL_STOP_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_CONTROL_STOP_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_CONTROL_STOP_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_CONTROL_STOP_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_STOP_INSRT AES_BLK_CONTROL_STOP_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_STOP_INSRT AES_BLK_CONTROL_STOP_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_STOP_INSRT AES_BLK_CONTROL_STOP_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_STOP_INSRT AES_BLK_CONTROL_STOP_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_STOP_INSRT AES_BLK_CONTROL_STOP_INSRT_V7 +#endif + +/*! @} stop */ + +/*! + * @addtogroup group995888 reset + * @brief Range = 2 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Empty Command FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONTROL_RESET_SHIFT_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_SHIFT AES_BLK_CONTROL_RESET_SHIFT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_WIDTH AES_BLK_CONTROL_RESET_WIDTH_V7 +#endif + +#define AES_BLK_CONTROL_RESET_UMASK_V7 (0x4) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_UMASK AES_BLK_CONTROL_RESET_UMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_SMASK AES_BLK_CONTROL_RESET_SMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_XTRCT_V7(r) ((((uint32_t)r) >> 2) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_XTRCT AES_BLK_CONTROL_RESET_XTRCT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_INSRT AES_BLK_CONTROL_RESET_INSRT_V7 +#endif + +/*! @} reset */ + +/*! + * @addtogroup group995889 reset_aes + * @brief Range = 3 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Reset the AES Engine + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONTROL_RESET_AES_SHIFT_V3 (3) +#define AES_BLK_CONTROL_RESET_AES_SHIFT_V4 (3) +#define AES_BLK_CONTROL_RESET_AES_SHIFT_V5 (3) +#define AES_BLK_CONTROL_RESET_AES_SHIFT_V6 (3) +#define AES_BLK_CONTROL_RESET_AES_SHIFT_V7 (3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_AES_SHIFT AES_BLK_CONTROL_RESET_AES_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_AES_SHIFT AES_BLK_CONTROL_RESET_AES_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_AES_SHIFT AES_BLK_CONTROL_RESET_AES_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_AES_SHIFT AES_BLK_CONTROL_RESET_AES_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_AES_SHIFT AES_BLK_CONTROL_RESET_AES_SHIFT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_AES_WIDTH_V3 (1) +#define AES_BLK_CONTROL_RESET_AES_WIDTH_V4 (1) +#define AES_BLK_CONTROL_RESET_AES_WIDTH_V5 (1) +#define AES_BLK_CONTROL_RESET_AES_WIDTH_V6 (1) +#define AES_BLK_CONTROL_RESET_AES_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_AES_WIDTH AES_BLK_CONTROL_RESET_AES_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_AES_WIDTH AES_BLK_CONTROL_RESET_AES_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_AES_WIDTH AES_BLK_CONTROL_RESET_AES_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_AES_WIDTH AES_BLK_CONTROL_RESET_AES_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_AES_WIDTH AES_BLK_CONTROL_RESET_AES_WIDTH_V7 +#endif + +#define AES_BLK_CONTROL_RESET_AES_UMASK_V3 (0x8) +#define AES_BLK_CONTROL_RESET_AES_UMASK_V4 (0x8) +#define AES_BLK_CONTROL_RESET_AES_UMASK_V5 (0x8) +#define AES_BLK_CONTROL_RESET_AES_UMASK_V6 (0x8) +#define AES_BLK_CONTROL_RESET_AES_UMASK_V7 (0x8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_AES_UMASK AES_BLK_CONTROL_RESET_AES_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_AES_UMASK AES_BLK_CONTROL_RESET_AES_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_AES_UMASK AES_BLK_CONTROL_RESET_AES_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_AES_UMASK AES_BLK_CONTROL_RESET_AES_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_AES_UMASK AES_BLK_CONTROL_RESET_AES_UMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_AES_SMASK_V3 (0x1) +#define AES_BLK_CONTROL_RESET_AES_SMASK_V4 (0x1) +#define AES_BLK_CONTROL_RESET_AES_SMASK_V5 (0x1) +#define AES_BLK_CONTROL_RESET_AES_SMASK_V6 (0x1) +#define AES_BLK_CONTROL_RESET_AES_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_AES_SMASK AES_BLK_CONTROL_RESET_AES_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_AES_SMASK AES_BLK_CONTROL_RESET_AES_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_AES_SMASK AES_BLK_CONTROL_RESET_AES_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_AES_SMASK AES_BLK_CONTROL_RESET_AES_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_AES_SMASK AES_BLK_CONTROL_RESET_AES_SMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_AES_XTRCT_V3(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_CONTROL_RESET_AES_XTRCT_V4(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_CONTROL_RESET_AES_XTRCT_V5(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_CONTROL_RESET_AES_XTRCT_V6(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_CONTROL_RESET_AES_XTRCT_V7(r) ((((uint32_t)r) >> 3) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_AES_XTRCT AES_BLK_CONTROL_RESET_AES_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_AES_XTRCT AES_BLK_CONTROL_RESET_AES_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_AES_XTRCT AES_BLK_CONTROL_RESET_AES_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_AES_XTRCT AES_BLK_CONTROL_RESET_AES_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_AES_XTRCT AES_BLK_CONTROL_RESET_AES_XTRCT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_AES_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_CONTROL_RESET_AES_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_CONTROL_RESET_AES_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_CONTROL_RESET_AES_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_CONTROL_RESET_AES_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_AES_INSRT AES_BLK_CONTROL_RESET_AES_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_AES_INSRT AES_BLK_CONTROL_RESET_AES_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_AES_INSRT AES_BLK_CONTROL_RESET_AES_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_AES_INSRT AES_BLK_CONTROL_RESET_AES_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_AES_INSRT AES_BLK_CONTROL_RESET_AES_INSRT_V7 +#endif + +/*! @} reset_aes */ + +/*! + * @addtogroup group995890 reset_read_channel + * @brief Range = 4 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Unused. May be used in future chips. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V3 (4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V4 (4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V5 (4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V6 (4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_READ_CHANNEL_SHIFT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V3 (1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V4 (1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V5 (1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V6 (1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_READ_CHANNEL_WIDTH_V7 +#endif + +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V3 (0x10) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V4 (0x10) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V5 (0x10) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V6 (0x10) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V7 (0x10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_UMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V3 (0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V4 (0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V5 (0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V6 (0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK AES_BLK_CONTROL_RESET_READ_CHANNEL_SMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V3(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V4(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V5(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V6(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V7(r) ((((uint32_t)r) >> 4) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_READ_CHANNEL_XTRCT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT AES_BLK_CONTROL_RESET_READ_CHANNEL_INSRT_V7 +#endif + +/*! @} reset_read_channel */ + +/*! + * @addtogroup group995891 reset_write_channel + * @brief Range = 5 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Unused. May be used in future chips. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V3 (5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V4 (5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V5 (5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V6 (5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V7 (5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SHIFT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V3 (1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V4 (1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V5 (1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V6 (1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH AES_BLK_CONTROL_RESET_WRITE_CHANNEL_WIDTH_V7 +#endif + +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V3 (0x20) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V4 (0x20) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V5 (0x20) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V6 (0x20) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V7 (0x20) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_UMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V3 (0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V4 (0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V5 (0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V6 (0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK AES_BLK_CONTROL_RESET_WRITE_CHANNEL_SMASK_V7 +#endif + +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V3(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V4(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V5(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V6(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V7(r) ((((uint32_t)r) >> 5) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_XTRCT_V7 +#endif + +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT AES_BLK_CONTROL_RESET_WRITE_CHANNEL_INSRT_V7 +#endif + +/*! @} reset_write_channel */ + +/*! + * @addtogroup group995893 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_CONTROL_TNBLE_RESET_UMASK_T8010_A0 (0x3f) + +#define AES_BLK_CONTROL_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} control */ + +/*! + * @addtogroup group995894 status + * @brief Offset = 0xc + * @details Channel status register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_STATUS_OFFSET_V1 (0x0 + 0x0) +#define AES_BLK_STATUS_OFFSET_V2 (0x0 + 0x0) +#define AES_BLK_STATUS_OFFSET_V3 (0x0 + 0xc) +#define AES_BLK_STATUS_OFFSET_V4 (0x0 + 0xc) +#define AES_BLK_STATUS_OFFSET_V5 (0x0 + 0xc) +#define AES_BLK_STATUS_OFFSET_V6 (0x0 + 0xc) +#define AES_BLK_STATUS_OFFSET_V7 (0x0 + 0xc) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_STATUS_OFFSET AES_BLK_STATUS_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_STATUS_OFFSET AES_BLK_STATUS_OFFSET_V2 +#elif SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_OFFSET AES_BLK_STATUS_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_OFFSET AES_BLK_STATUS_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_OFFSET AES_BLK_STATUS_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_OFFSET AES_BLK_STATUS_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_OFFSET AES_BLK_STATUS_OFFSET_V7 +#endif + +/*! + * @addtogroup group995895 dma_read_active + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x0 + * @details The DMA is reading data from System Memory + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V3 (0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V4 (0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V5 (0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V6 (0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT AES_BLK_STATUS_DMA_READ_ACTIVE_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V3 (1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V4 (1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V5 (1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V6 (1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH AES_BLK_STATUS_DMA_READ_ACTIVE_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V3 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V4 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V5 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V6 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK AES_BLK_STATUS_DMA_READ_ACTIVE_UMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V3 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V4 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V5 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V6 (0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK AES_BLK_STATUS_DMA_READ_ACTIVE_SMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT AES_BLK_STATUS_DMA_READ_ACTIVE_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT AES_BLK_STATUS_DMA_READ_ACTIVE_INSRT_V7 +#endif + +/*! @} dma_read_active */ + +/*! + * @addtogroup group995896 dma_read_incomplete + * @brief Range = 1 | Width = 1 | Access = read-only | Default = 0x0 + * @details The DMA is done reading data from System Memory but not all data + * has been pushed into the AES engine + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V3 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V4 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V5 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V6 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_READ_INCOMPLETE_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V3 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V4 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V5 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V6 (1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_READ_INCOMPLETE_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V3 (0x2) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V4 (0x2) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V5 (0x2) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V6 (0x2) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V7 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_UMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V3 (0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V4 (0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V5 (0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V6 (0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_READ_INCOMPLETE_SMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V3(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V4(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V5(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V6(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V7(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_READ_INCOMPLETE_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_READ_INCOMPLETE_INSRT_V7 +#endif + +/*! @} dma_read_incomplete */ + +/*! + * @addtogroup group995897 dma_write_active + * @brief Range = 2 | Width = 1 | Access = read-only | Default = 0x0 + * @details The DMA is writing data to System Memory + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V3 (2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V4 (2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V5 (2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V6 (2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT AES_BLK_STATUS_DMA_WRITE_ACTIVE_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V3 (1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V4 (1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V5 (1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V6 (1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH AES_BLK_STATUS_DMA_WRITE_ACTIVE_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V3 (0x4) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V4 (0x4) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V5 (0x4) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V6 (0x4) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V7 (0x4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_UMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V3 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V4 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V5 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V6 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK AES_BLK_STATUS_DMA_WRITE_ACTIVE_SMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V3(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V4(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V5(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V6(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V7(r) ((((uint32_t)r) >> 2) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT AES_BLK_STATUS_DMA_WRITE_ACTIVE_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT AES_BLK_STATUS_DMA_WRITE_ACTIVE_INSRT_V7 +#endif + +/*! @} dma_write_active */ + +/*! + * @addtogroup group995898 dma_write_incomplete + * @brief Range = 3 | Width = 1 | Access = read-only | Default = 0x0 + * @details The DMA is done writing data to System Memory but not all data has + * been written + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V3 (3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V4 (3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V5 (3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V6 (3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V7 (3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V3 (1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V4 (1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V5 (1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V6 (1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V3 (0x8) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V4 (0x8) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V5 (0x8) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V6 (0x8) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V7 (0x8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_UMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V3 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V4 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V5 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V6 (0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_SMASK_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V3(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V4(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V5(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V6(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V7(r) ((((uint32_t)r) >> 3) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT AES_BLK_STATUS_DMA_WRITE_INCOMPLETE_INSRT_V7 +#endif + +/*! @} dma_write_incomplete */ + +/*! + * @addtogroup group995899 active (AES_ACTIVE) + * @brief Range = 4 | Width = 1 | Access = read-only | Default = 0x0 + * @details AES module is busy + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_ACTIVE_SHIFT_V3 (4) +#define AES_BLK_STATUS_ACTIVE_SHIFT_V4 (4) +#define AES_BLK_STATUS_ACTIVE_SHIFT_V5 (4) +#define AES_BLK_STATUS_ACTIVE_SHIFT_V6 (4) +#define AES_BLK_STATUS_ACTIVE_SHIFT_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_ACTIVE_SHIFT AES_BLK_STATUS_ACTIVE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_ACTIVE_SHIFT AES_BLK_STATUS_ACTIVE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_ACTIVE_SHIFT AES_BLK_STATUS_ACTIVE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_ACTIVE_SHIFT AES_BLK_STATUS_ACTIVE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_ACTIVE_SHIFT AES_BLK_STATUS_ACTIVE_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_ACTIVE_WIDTH_V3 (1) +#define AES_BLK_STATUS_ACTIVE_WIDTH_V4 (1) +#define AES_BLK_STATUS_ACTIVE_WIDTH_V5 (1) +#define AES_BLK_STATUS_ACTIVE_WIDTH_V6 (1) +#define AES_BLK_STATUS_ACTIVE_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_ACTIVE_WIDTH AES_BLK_STATUS_ACTIVE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_ACTIVE_WIDTH AES_BLK_STATUS_ACTIVE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_ACTIVE_WIDTH AES_BLK_STATUS_ACTIVE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_ACTIVE_WIDTH AES_BLK_STATUS_ACTIVE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_ACTIVE_WIDTH AES_BLK_STATUS_ACTIVE_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_ACTIVE_UMASK_V3 (0x10) +#define AES_BLK_STATUS_ACTIVE_UMASK_V4 (0x10) +#define AES_BLK_STATUS_ACTIVE_UMASK_V5 (0x10) +#define AES_BLK_STATUS_ACTIVE_UMASK_V6 (0x10) +#define AES_BLK_STATUS_ACTIVE_UMASK_V7 (0x10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_ACTIVE_UMASK AES_BLK_STATUS_ACTIVE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_ACTIVE_UMASK AES_BLK_STATUS_ACTIVE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_ACTIVE_UMASK AES_BLK_STATUS_ACTIVE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_ACTIVE_UMASK AES_BLK_STATUS_ACTIVE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_ACTIVE_UMASK AES_BLK_STATUS_ACTIVE_UMASK_V7 +#endif + +#define AES_BLK_STATUS_ACTIVE_SMASK_V3 (0x1) +#define AES_BLK_STATUS_ACTIVE_SMASK_V4 (0x1) +#define AES_BLK_STATUS_ACTIVE_SMASK_V5 (0x1) +#define AES_BLK_STATUS_ACTIVE_SMASK_V6 (0x1) +#define AES_BLK_STATUS_ACTIVE_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_ACTIVE_SMASK AES_BLK_STATUS_ACTIVE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_ACTIVE_SMASK AES_BLK_STATUS_ACTIVE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_ACTIVE_SMASK AES_BLK_STATUS_ACTIVE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_ACTIVE_SMASK AES_BLK_STATUS_ACTIVE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_ACTIVE_SMASK AES_BLK_STATUS_ACTIVE_SMASK_V7 +#endif + +#define AES_BLK_STATUS_ACTIVE_XTRCT_V3(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_STATUS_ACTIVE_XTRCT_V4(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_STATUS_ACTIVE_XTRCT_V5(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_STATUS_ACTIVE_XTRCT_V6(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_STATUS_ACTIVE_XTRCT_V7(r) ((((uint32_t)r) >> 4) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_ACTIVE_XTRCT AES_BLK_STATUS_ACTIVE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_ACTIVE_XTRCT AES_BLK_STATUS_ACTIVE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_ACTIVE_XTRCT AES_BLK_STATUS_ACTIVE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_ACTIVE_XTRCT AES_BLK_STATUS_ACTIVE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_ACTIVE_XTRCT AES_BLK_STATUS_ACTIVE_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_ACTIVE_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_STATUS_ACTIVE_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_STATUS_ACTIVE_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_STATUS_ACTIVE_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_STATUS_ACTIVE_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_ACTIVE_INSRT AES_BLK_STATUS_ACTIVE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_ACTIVE_INSRT AES_BLK_STATUS_ACTIVE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_ACTIVE_INSRT AES_BLK_STATUS_ACTIVE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_ACTIVE_INSRT AES_BLK_STATUS_ACTIVE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_ACTIVE_INSRT AES_BLK_STATUS_ACTIVE_INSRT_V7 +#endif + +/*! @} active (AES_ACTIVE) */ + +/*! + * @addtogroup group995900 command_fifo_active + * @brief Range = 5 | Width = 1 | Access = read-only | Default = 0x0 + * @details A command is being executed from the Command FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V3 (5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V4 (5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V5 (5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V6 (5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V7 (5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V3 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V4 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V5 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V6 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V3 (0x20) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V4 (0x20) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V5 (0x20) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V6 (0x20) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V7 (0x20) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_UMASK_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V3 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V4 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V5 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V6 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_SMASK_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V3(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V4(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V5(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V6(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V7(r) ((((uint32_t)r) >> 5) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT AES_BLK_STATUS_COMMAND_FIFO_ACTIVE_INSRT_V7 +#endif + +/*! @} command_fifo_active */ + +/*! + * @addtogroup group995901 command_fifo_enabled + * @brief Range = 6 | Width = 1 | Access = read-only | Default = 0x0 + * @details Indicates the Command FIFO has been enabled and ready to execute + * commands + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V3 (6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V4 (6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V5 (6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V6 (6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V7 (6) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V3 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V4 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V5 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V6 (1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH AES_BLK_STATUS_COMMAND_FIFO_ENABLED_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V3 (0x40) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V4 (0x40) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V5 (0x40) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V6 (0x40) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V7 (0x40) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_UMASK_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V3 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V4 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V5 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V6 (0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK AES_BLK_STATUS_COMMAND_FIFO_ENABLED_SMASK_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V3(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V4(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V5(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V6(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V7(r) ((((uint32_t)r) >> 6) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 6) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT AES_BLK_STATUS_COMMAND_FIFO_ENABLED_INSRT_V7 +#endif + +/*! @} command_fifo_enabled */ + +/*! + * @addtogroup group995902 text_dpa_random_seeded + * @brief Range = 7 | Width = 1 | Access = read-only | Default = 0x0 + * @details The random number generator for text DPA has been seeded + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SHIFT_V6 (7) +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SHIFT_V7 (7) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SHIFT AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SHIFT AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_WIDTH_V6 (1) +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_WIDTH AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_WIDTH AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_UMASK_V6 (0x80) +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_UMASK_V7 (0x80) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_UMASK AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_UMASK AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_UMASK_V7 +#endif + +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SMASK_V6 (0x1) +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SMASK AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SMASK AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_SMASK_V7 +#endif + +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_XTRCT_V6(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_XTRCT_V7(r) ((((uint32_t)r) >> 7) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_XTRCT AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_XTRCT AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 7) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_INSRT AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_INSRT AES_BLK_STATUS_TEXT_DPA_RANDOM_SEEDED_INSRT_V7 +#endif + +/*! @} text_dpa_random_seeded */ + +/*! + * @addtogroup group995903 key_unwrap_dpa_random_seeded + * @brief Range = 8 | Width = 1 | Access = read-only | Default = 0x0 + * @details The random number generator for key unwrap DPA has been seeded + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SHIFT_V6 (8) +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SHIFT AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SHIFT AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SHIFT_V7 +#endif + +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_WIDTH_V6 (1) +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_WIDTH AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_WIDTH AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_WIDTH_V7 +#endif + +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_UMASK_V6 (0x100) +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_UMASK_V7 (0x100) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_UMASK AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_UMASK AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_UMASK_V7 +#endif + +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SMASK_V6 (0x1) +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SMASK AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SMASK AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_SMASK_V7 +#endif + +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_XTRCT AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_XTRCT AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_XTRCT_V7 +#endif + +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_INSRT AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_INSRT AES_BLK_STATUS_KEY_UNWRAP_DPA_RANDOM_SEEDED_INSRT_V7 +#endif + +/*! @} key_unwrap_dpa_random_seeded */ + +/*! + * @addtogroup group995905 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_S5L8960X_A0 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_S5L8960X_B0 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_S5L8960X_B1 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_T7000_A0 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_T7000_B0 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_T7000_B1 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_T7001_A0 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_T7001_A1 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_S7002_A1 (0x1) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_S8000_A1 (0x7f) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_S8000_B0 (0x7f) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_S8001_A0 (0x7f) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_T8002_A0 (0x1ff) +#define AES_BLK_STATUS_TNBLE_RESET_UMASK_T8010_A0 (0x1ff) + +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_S7002_A1 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_STATUS_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! + * @addtogroup group120223 busy (aes_busy) + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x0 + * @details Asserted when either the key configurator, IV setup, or AES cipher + * engines are busy + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_STATUS_BUSY_SHIFT_V1 (0) +#define AES_BLK_STATUS_BUSY_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_STATUS_BUSY_SHIFT AES_BLK_STATUS_BUSY_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_STATUS_BUSY_SHIFT AES_BLK_STATUS_BUSY_SHIFT_V2 +#endif + +#define AES_BLK_STATUS_BUSY_WIDTH_V1 (1) +#define AES_BLK_STATUS_BUSY_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_STATUS_BUSY_WIDTH AES_BLK_STATUS_BUSY_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_STATUS_BUSY_WIDTH AES_BLK_STATUS_BUSY_WIDTH_V2 +#endif + +#define AES_BLK_STATUS_BUSY_UMASK_V1 (0x1) +#define AES_BLK_STATUS_BUSY_UMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_STATUS_BUSY_UMASK AES_BLK_STATUS_BUSY_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_STATUS_BUSY_UMASK AES_BLK_STATUS_BUSY_UMASK_V2 +#endif + +#define AES_BLK_STATUS_BUSY_SMASK_V1 (0x1) +#define AES_BLK_STATUS_BUSY_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_STATUS_BUSY_SMASK AES_BLK_STATUS_BUSY_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_STATUS_BUSY_SMASK AES_BLK_STATUS_BUSY_SMASK_V2 +#endif + +#define AES_BLK_STATUS_BUSY_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_STATUS_BUSY_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_STATUS_BUSY_XTRCT AES_BLK_STATUS_BUSY_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_STATUS_BUSY_XTRCT AES_BLK_STATUS_BUSY_XTRCT_V2 +#endif + +#define AES_BLK_STATUS_BUSY_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_STATUS_BUSY_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_STATUS_BUSY_INSRT AES_BLK_STATUS_BUSY_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_STATUS_BUSY_INSRT AES_BLK_STATUS_BUSY_INSRT_V2 +#endif + +/*! @} busy (aes_busy) */ + +/*! @} status */ + +/*! + * @addtogroup group995906 key_id + * @brief Offset = 0x10 + * @details Current Key IDs + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_ID_OFFSET_V3 (0x0 + 0x10) +#define AES_BLK_KEY_ID_OFFSET_V4 (0x0 + 0x10) +#define AES_BLK_KEY_ID_OFFSET_V5 (0x0 + 0x10) +#define AES_BLK_KEY_ID_OFFSET_V6 (0x0 + 0x10) +#define AES_BLK_KEY_ID_OFFSET_V7 (0x0 + 0x10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_OFFSET AES_BLK_KEY_ID_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_OFFSET AES_BLK_KEY_ID_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_OFFSET AES_BLK_KEY_ID_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_OFFSET AES_BLK_KEY_ID_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_OFFSET AES_BLK_KEY_ID_OFFSET_V7 +#endif + +/*! + * @addtogroup group995907 context_0 + * @brief Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 + * @details ID for Key in context 0 + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V3 (0) +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V4 (0) +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V5 (0) +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V6 (0) +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_0_SHIFT AES_BLK_KEY_ID_CONTEXT_0_SHIFT_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V3 (8) +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V4 (8) +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V5 (8) +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V6 (8) +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_0_WIDTH AES_BLK_KEY_ID_CONTEXT_0_WIDTH_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK_V3 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK_V4 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK_V5 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK_V6 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK AES_BLK_KEY_ID_CONTEXT_0_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK AES_BLK_KEY_ID_CONTEXT_0_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK AES_BLK_KEY_ID_CONTEXT_0_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK AES_BLK_KEY_ID_CONTEXT_0_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_0_UMASK AES_BLK_KEY_ID_CONTEXT_0_UMASK_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK_V3 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK_V4 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK_V5 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK_V6 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK AES_BLK_KEY_ID_CONTEXT_0_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK AES_BLK_KEY_ID_CONTEXT_0_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK AES_BLK_KEY_ID_CONTEXT_0_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK AES_BLK_KEY_ID_CONTEXT_0_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_0_SMASK AES_BLK_KEY_ID_CONTEXT_0_SMASK_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_0_XTRCT AES_BLK_KEY_ID_CONTEXT_0_XTRCT_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT_V3(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT_V4(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT_V5(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT_V6(f) ((((uint32_t)f) & 0xff) << 0) +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT_V7(f) ((((uint32_t)f) & 0xff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT AES_BLK_KEY_ID_CONTEXT_0_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT AES_BLK_KEY_ID_CONTEXT_0_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT AES_BLK_KEY_ID_CONTEXT_0_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT AES_BLK_KEY_ID_CONTEXT_0_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_0_INSRT AES_BLK_KEY_ID_CONTEXT_0_INSRT_V7 +#endif + +/*! @} context_0 */ + +/*! + * @addtogroup group995908 context_1 + * @brief Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 + * @details ID for Key in context 1 + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V3 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V4 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V5 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V6 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_1_SHIFT AES_BLK_KEY_ID_CONTEXT_1_SHIFT_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V3 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V4 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V5 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V6 (8) +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_1_WIDTH AES_BLK_KEY_ID_CONTEXT_1_WIDTH_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK_V3 (0xff00) +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK_V4 (0xff00) +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK_V5 (0xff00) +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK_V6 (0xff00) +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK_V7 (0xff00) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK AES_BLK_KEY_ID_CONTEXT_1_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK AES_BLK_KEY_ID_CONTEXT_1_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK AES_BLK_KEY_ID_CONTEXT_1_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK AES_BLK_KEY_ID_CONTEXT_1_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_1_UMASK AES_BLK_KEY_ID_CONTEXT_1_UMASK_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK_V3 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK_V4 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK_V5 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK_V6 (0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK AES_BLK_KEY_ID_CONTEXT_1_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK AES_BLK_KEY_ID_CONTEXT_1_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK AES_BLK_KEY_ID_CONTEXT_1_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK AES_BLK_KEY_ID_CONTEXT_1_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_1_SMASK AES_BLK_KEY_ID_CONTEXT_1_SMASK_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V3(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V4(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V5(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_1_XTRCT AES_BLK_KEY_ID_CONTEXT_1_XTRCT_V7 +#endif + +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT_V3(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT_V4(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT_V5(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT_V6(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT_V7(f) ((((uint32_t)f) & 0xff) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT AES_BLK_KEY_ID_CONTEXT_1_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT AES_BLK_KEY_ID_CONTEXT_1_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT AES_BLK_KEY_ID_CONTEXT_1_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT AES_BLK_KEY_ID_CONTEXT_1_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_KEY_ID_CONTEXT_1_INSRT AES_BLK_KEY_ID_CONTEXT_1_INSRT_V7 +#endif + +/*! @} context_1 */ + +/*! + * @addtogroup group995910 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_ID_TNBLE_RESET_UMASK_S8000_A1 (0xffff) +#define AES_BLK_KEY_ID_TNBLE_RESET_UMASK_S8000_B0 (0xffff) +#define AES_BLK_KEY_ID_TNBLE_RESET_UMASK_S8001_A0 (0xffff) +#define AES_BLK_KEY_ID_TNBLE_RESET_UMASK_T8002_A0 (0xffff) +#define AES_BLK_KEY_ID_TNBLE_RESET_UMASK_T8010_A0 (0xffff) + +#define AES_BLK_KEY_ID_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_KEY_ID_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_KEY_ID_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_KEY_ID_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_KEY_ID_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} key_id */ + +/*! + * @addtogroup group995911 axi_status + * @brief Offset = 0x14 + * @details AXI status register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_AXI_STATUS_OFFSET_V3 (0x0 + 0x14) +#define AES_BLK_AXI_STATUS_OFFSET_V4 (0x0 + 0x14) +#define AES_BLK_AXI_STATUS_OFFSET_V5 (0x0 + 0x14) +#define AES_BLK_AXI_STATUS_OFFSET_V6 (0x0 + 0x14) +#define AES_BLK_AXI_STATUS_OFFSET_V7 (0x0 + 0x14) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_OFFSET AES_BLK_AXI_STATUS_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_OFFSET AES_BLK_AXI_STATUS_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_OFFSET AES_BLK_AXI_STATUS_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_OFFSET AES_BLK_AXI_STATUS_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_OFFSET AES_BLK_AXI_STATUS_OFFSET_V7 +#endif + +/*! + * @addtogroup group995912 read_response + * @brief Range = 1:0 | Width = 2 | Access = read-only | Default = 0x0 + * @details AXI response to read request + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V3 (0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V4 (0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V5 (0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V6 (0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT AES_BLK_AXI_STATUS_READ_RESPONSE_SHIFT_V7 +#endif + +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V3 (2) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V4 (2) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V5 (2) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V6 (2) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH AES_BLK_AXI_STATUS_READ_RESPONSE_WIDTH_V7 +#endif + +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V3 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V4 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V5 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V6 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V7 (0x3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK AES_BLK_AXI_STATUS_READ_RESPONSE_UMASK_V7 +#endif + +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V3 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V4 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V5 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V6 (0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V7 (0x3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK AES_BLK_AXI_STATUS_READ_RESPONSE_SMASK_V7 +#endif + +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x3) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT AES_BLK_AXI_STATUS_READ_RESPONSE_XTRCT_V7 +#endif + +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V3(f) ((((uint32_t)f) & 0x3) << 0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V4(f) ((((uint32_t)f) & 0x3) << 0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V5(f) ((((uint32_t)f) & 0x3) << 0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V6(f) ((((uint32_t)f) & 0x3) << 0) +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V7(f) ((((uint32_t)f) & 0x3) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT AES_BLK_AXI_STATUS_READ_RESPONSE_INSRT_V7 +#endif + +/*! @} read_response */ + +/*! + * @addtogroup group995913 write_response + * @brief Range = 3:2 | Width = 2 | Access = read-only | Default = 0x0 + * @details AXI response to write request + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V3 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V4 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V5 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V6 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT AES_BLK_AXI_STATUS_WRITE_RESPONSE_SHIFT_V7 +#endif + +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V3 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V4 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V5 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V6 (2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH AES_BLK_AXI_STATUS_WRITE_RESPONSE_WIDTH_V7 +#endif + +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V3 (0xc) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V4 (0xc) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V5 (0xc) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V6 (0xc) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V7 (0xc) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_UMASK_V7 +#endif + +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V3 (0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V4 (0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V5 (0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V6 (0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V7 (0x3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK AES_BLK_AXI_STATUS_WRITE_RESPONSE_SMASK_V7 +#endif + +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V3(r) ((((uint32_t)r) >> 2) & 0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V4(r) ((((uint32_t)r) >> 2) & 0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V5(r) ((((uint32_t)r) >> 2) & 0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V6(r) ((((uint32_t)r) >> 2) & 0x3) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V7(r) ((((uint32_t)r) >> 2) & 0x3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT AES_BLK_AXI_STATUS_WRITE_RESPONSE_XTRCT_V7 +#endif + +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V3(f) ((((uint32_t)f) & 0x3) << 2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V4(f) ((((uint32_t)f) & 0x3) << 2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V5(f) ((((uint32_t)f) & 0x3) << 2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V6(f) ((((uint32_t)f) & 0x3) << 2) +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V7(f) ((((uint32_t)f) & 0x3) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT AES_BLK_AXI_STATUS_WRITE_RESPONSE_INSRT_V7 +#endif + +/*! @} write_response */ + +/*! + * @addtogroup group995915 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_AXI_STATUS_TNBLE_RESET_UMASK_S8000_A1 (0xf) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_UMASK_S8000_B0 (0xf) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_UMASK_S8001_A0 (0xf) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_UMASK_T8002_A0 (0xf) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_UMASK_T8010_A0 (0xf) + +#define AES_BLK_AXI_STATUS_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_AXI_STATUS_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} axi_status */ + +/*! + * @addtogroup group995916 int_status + * @brief Offset = 0x18 + * @details Channel interrupt status register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_INT_STATUS_OFFSET_V3 (0x0 + 0x18) +#define AES_BLK_INT_STATUS_OFFSET_V4 (0x0 + 0x18) +#define AES_BLK_INT_STATUS_OFFSET_V5 (0x0 + 0x18) +#define AES_BLK_INT_STATUS_OFFSET_V6 (0x0 + 0x18) +#define AES_BLK_INT_STATUS_OFFSET_V7 (0x0 + 0x18) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_OFFSET AES_BLK_INT_STATUS_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_OFFSET AES_BLK_INT_STATUS_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_OFFSET AES_BLK_INT_STATUS_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_OFFSET AES_BLK_INT_STATUS_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_OFFSET AES_BLK_INT_STATUS_OFFSET_V7 +#endif + +/*! + * @addtogroup group995917 command_fifo_low + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x0 + * @details The number of entries in the Command FIFO has gone below + * CHAN.DMA_WATERMARKS.COMMAND_FIFO_LOW (not sticky) + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V3 (0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V4 (0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V5 (0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V6 (0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_LOW_INSRT_V7 +#endif + +/*! @} command_fifo_low */ + +/*! + * @addtogroup group995918 command_fifo_overflow + * @brief Range = 1 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details SW pushed (wrote) too many entries into the Command FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V3 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V4 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V5 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V6 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V3 (0x2) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V4 (0x2) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V5 (0x2) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V6 (0x2) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V7 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V3(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V4(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V5(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V6(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V7(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_STATUS_COMMAND_FIFO_OVERFLOW_INSRT_V7 +#endif + +/*! @} command_fifo_overflow */ + +/*! + * @addtogroup group995919 invalid_command + * @brief Range = 2 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details An invalid opcode detected. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V3 (2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V4 (2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V5 (2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V6 (2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT AES_BLK_INT_STATUS_INVALID_COMMAND_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH AES_BLK_INT_STATUS_INVALID_COMMAND_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V3 (0x4) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V4 (0x4) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V5 (0x4) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V6 (0x4) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V7 (0x4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK AES_BLK_INT_STATUS_INVALID_COMMAND_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK AES_BLK_INT_STATUS_INVALID_COMMAND_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V3(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V4(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V5(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V6(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V7(r) ((((uint32_t)r) >> 2) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT AES_BLK_INT_STATUS_INVALID_COMMAND_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT AES_BLK_INT_STATUS_INVALID_COMMAND_INSRT_V7 +#endif + +/*! @} invalid_command */ + +/*! + * @addtogroup group995920 axi_read_response_not_okay + * @brief Range = 3 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details AXI responded with an "error", "retry" or "split" + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V3 (3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V4 (3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V5 (3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V6 (3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V7 (3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V3 (0x8) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V4 (0x8) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V5 (0x8) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V6 (0x8) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V7 (0x8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V3(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V4(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V5(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V6(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V7(r) ((((uint32_t)r) >> 3) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V7 +#endif + +/*! @} axi_read_response_not_okay */ + +/*! + * @addtogroup group995921 axi_write_response_not_okay + * @brief Range = 4 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details AXI responded with an "error", "retry" or "split" + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V3 (4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V4 (4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V5 (4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V6 (4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V3 (0x10) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V4 (0x10) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V5 (0x10) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V6 (0x10) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V7 (0x10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V3(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V4(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V5(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V6(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V7(r) ((((uint32_t)r) >> 4) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_STATUS_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V7 +#endif + +/*! @} axi_write_response_not_okay */ + +/*! + * @addtogroup group995922 flag_command + * @brief Range = 5 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details A "flag" command has been executed. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V3 (5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V4 (5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V5 (5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V6 (5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V7 (5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT AES_BLK_INT_STATUS_FLAG_COMMAND_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH AES_BLK_INT_STATUS_FLAG_COMMAND_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V3 (0x20) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V4 (0x20) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V5 (0x20) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V6 (0x20) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V7 (0x20) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK AES_BLK_INT_STATUS_FLAG_COMMAND_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK AES_BLK_INT_STATUS_FLAG_COMMAND_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V3(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V4(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V5(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V6(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V7(r) ((((uint32_t)r) >> 5) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT AES_BLK_INT_STATUS_FLAG_COMMAND_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT AES_BLK_INT_STATUS_FLAG_COMMAND_INSRT_V7 +#endif + +/*! @} flag_command */ + +/*! + * @addtogroup group995923 invalid_data_length + * @brief Range = 6 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details Non-multiple of 16B data length. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V3 (6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V4 (6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V5 (6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V6 (6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V7 (6) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V3 (0x40) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V4 (0x40) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V5 (0x40) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V6 (0x40) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V7 (0x40) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V3(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V4(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V5(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V6(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V7(r) ((((uint32_t)r) >> 6) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 6) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_STATUS_INVALID_DATA_LENGTH_INSRT_V7 +#endif + +/*! @} invalid_data_length */ + +/*! + * @addtogroup group995924 key_0_disabled + * @brief Range = 7 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details Keys are disabled + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V3 (7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V4 (7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V5 (7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V6 (7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V7 (7) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_0_DISABLED_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_0_DISABLED_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V3 (0x80) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V4 (0x80) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V5 (0x80) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V6 (0x80) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V7 (0x80) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_0_DISABLED_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V3(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V4(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V5(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V6(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V7(r) ((((uint32_t)r) >> 7) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_0_DISABLED_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 7) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_0_DISABLED_INSRT_V7 +#endif + +/*! @} key_0_disabled */ + +/*! + * @addtogroup group995925 key_0_cmac_tag_mismatch + * @brief Range = 8 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details CMAC Tag mismatch detected + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V3 (8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V4 (8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V5 (8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V6 (8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V3 (0x100) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V4 (0x100) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V5 (0x100) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V6 (0x100) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V7 (0x100) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_CMAC_TAG_MISMATCH_INSRT_V7 +#endif + +/*! @} key_0_cmac_tag_mismatch */ + +/*! + * @addtogroup group995926 key_0_policy_mismatch + * @brief Range = 9 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details Key policy mismatch at load time + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V3 (9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V4 (9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V5 (9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V6 (9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V7 (9) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V3 (0x200) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V4 (0x200) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V5 (0x200) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V6 (0x200) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V7 (0x200) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 9) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 9) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_0_POLICY_MISMATCH_INSRT_V7 +#endif + +/*! @} key_0_policy_mismatch */ + +/*! + * @addtogroup group995927 key_0_invalid_at_use_time + * @brief Range = 10 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details Keys have expired + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V3 (10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V4 (10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V5 (10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V6 (10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V7 (10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V3 (0x400) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V4 (0x400) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V5 (0x400) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V6 (0x400) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V7 (0x400) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V3(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V4(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V5(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V6(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V7(r) ((((uint32_t)r) >> 10) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_0_INVALID_AT_USE_TIME_INSRT_V7 +#endif + +/*! @} key_0_invalid_at_use_time */ + +/*! + * @addtogroup group995928 key_0_hdcp_err + * @brief Range = 11 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details HDCP error detected + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V3 (11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V4 (11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V5 (11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V6 (11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V7 (11) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V3 (0x800) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V4 (0x800) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V5 (0x800) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V6 (0x800) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V7 (0x800) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V3(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V4(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V5(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V6(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V7(r) ((((uint32_t)r) >> 11) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 11) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_0_HDCP_ERR_INSRT_V7 +#endif + +/*! @} key_0_hdcp_err */ + +/*! + * @addtogroup group995929 key_0_dpa_random_unseeded + * @brief Range = 12 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details DAP random number generator has not been seeded + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V6 (12) +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V7 (12) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V6 (0x1000) +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V7 (0x1000) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V6(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V7(r) ((((uint32_t)r) >> 12) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 12) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_STATUS_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V7 +#endif + +/*! @} key_0_dpa_random_unseeded */ + +/*! + * @addtogroup group995930 key_1_disabled + * @brief Range = 13 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details Keys are disabled + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V3 (12) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V4 (12) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V5 (12) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V6 (13) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V7 (13) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT AES_BLK_INT_STATUS_KEY_1_DISABLED_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH AES_BLK_INT_STATUS_KEY_1_DISABLED_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V3 (0x1000) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V4 (0x1000) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V5 (0x1000) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V6 (0x2000) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V7 (0x2000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK AES_BLK_INT_STATUS_KEY_1_DISABLED_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V3(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V4(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V5(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V6(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V7(r) ((((uint32_t)r) >> 13) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT AES_BLK_INT_STATUS_KEY_1_DISABLED_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 13) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT AES_BLK_INT_STATUS_KEY_1_DISABLED_INSRT_V7 +#endif + +/*! @} key_1_disabled */ + +/*! + * @addtogroup group995931 key_1_cmac_tag_mismatch + * @brief Range = 14 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details CMAC Tag mismatch detected + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V3 (13) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V4 (13) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V5 (13) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V6 (14) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V7 (14) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V3 (0x2000) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V4 (0x2000) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V5 (0x2000) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V6 (0x4000) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V7 (0x4000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 14) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 14) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_CMAC_TAG_MISMATCH_INSRT_V7 +#endif + +/*! @} key_1_cmac_tag_mismatch */ + +/*! + * @addtogroup group995932 key_1_policy_mismatch + * @brief Range = 15 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details Key policy mismatch at load time + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V3 (14) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V4 (14) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V5 (14) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V6 (15) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V7 (15) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V3 (0x4000) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V4 (0x4000) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V5 (0x4000) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V6 (0x8000) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V7 (0x8000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 15) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 15) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_STATUS_KEY_1_POLICY_MISMATCH_INSRT_V7 +#endif + +/*! @} key_1_policy_mismatch */ + +/*! + * @addtogroup group995933 key_1_invalid_at_use_time + * @brief Range = 16 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details Keys have expired + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V3 (15) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V4 (15) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V5 (15) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V6 (16) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V7 (16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V3 (0x8000) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V4 (0x8000) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V5 (0x8000) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V6 (0x10000) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V7 (0x10000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V3(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V4(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V5(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V6(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V7(r) ((((uint32_t)r) >> 16) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_STATUS_KEY_1_INVALID_AT_USE_TIME_INSRT_V7 +#endif + +/*! @} key_1_invalid_at_use_time */ + +/*! + * @addtogroup group995934 key_1_hdcp_err + * @brief Range = 17 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details HDCP error detected + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V3 (16) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V4 (16) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V5 (16) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V6 (17) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V7 (17) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V3 (1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V4 (1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V5 (1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V3 (0x10000) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V4 (0x10000) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V5 (0x10000) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V6 (0x20000) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V7 (0x20000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V3 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V4 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V5 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V3(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V4(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V5(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V6(r) ((((uint32_t)r) >> 17) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V7(r) ((((uint32_t)r) >> 17) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 17) +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 17) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_STATUS_KEY_1_HDCP_ERR_INSRT_V7 +#endif + +/*! @} key_1_hdcp_err */ + +/*! + * @addtogroup group995935 key_1_dpa_random_unseeded + * @brief Range = 18 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @details DAP random number generator has not been seeded + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V6 (18) +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V7 (18) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V6 (1) +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V6 (0x40000) +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V7 (0x40000) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V6 (0x1) +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V6(r) ((((uint32_t)r) >> 18) & 0x1) +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V7(r) ((((uint32_t)r) >> 18) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V7 +#endif + +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 18) +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 18) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_STATUS_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V7 +#endif + +/*! @} key_1_dpa_random_unseeded */ + +/*! + * @addtogroup group995937 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_INT_STATUS_TNBLE_RESET_UMASK_S8000_A1 (0x1ffff) +#define AES_BLK_INT_STATUS_TNBLE_RESET_UMASK_S8000_B0 (0x1ffff) +#define AES_BLK_INT_STATUS_TNBLE_RESET_UMASK_S8001_A0 (0x1ffff) +#define AES_BLK_INT_STATUS_TNBLE_RESET_UMASK_T8002_A0 (0x7ffff) +#define AES_BLK_INT_STATUS_TNBLE_RESET_UMASK_T8010_A0 (0x7ffff) + +#define AES_BLK_INT_STATUS_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_INT_STATUS_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_INT_STATUS_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_INT_STATUS_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_INT_STATUS_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} int_status */ + +/*! + * @addtogroup group995938 int_enable + * @brief Offset = 0x1c + * @details Channel interrupt enable register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_INT_ENABLE_OFFSET_V3 (0x0 + 0x1c) +#define AES_BLK_INT_ENABLE_OFFSET_V4 (0x0 + 0x1c) +#define AES_BLK_INT_ENABLE_OFFSET_V5 (0x0 + 0x1c) +#define AES_BLK_INT_ENABLE_OFFSET_V6 (0x0 + 0x1c) +#define AES_BLK_INT_ENABLE_OFFSET_V7 (0x0 + 0x1c) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_OFFSET AES_BLK_INT_ENABLE_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_OFFSET AES_BLK_INT_ENABLE_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_OFFSET AES_BLK_INT_ENABLE_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_OFFSET AES_BLK_INT_ENABLE_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_OFFSET AES_BLK_INT_ENABLE_OFFSET_V7 +#endif + +/*! + * @addtogroup group995939 command_fifo_low + * @brief Range = 0 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable COMMAND_FIFO_LOW Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V3 (0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V4 (0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V5 (0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V6 (0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_LOW_INSRT_V7 +#endif + +/*! @} command_fifo_low */ + +/*! + * @addtogroup group995940 command_fifo_overflow + * @brief Range = 1 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable COMMAND_FIFO_OVERFLOW Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V3 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V4 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V5 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V6 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V3 (0x2) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V4 (0x2) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V5 (0x2) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V6 (0x2) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V7 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V3(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V4(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V5(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V6(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V7(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT AES_BLK_INT_ENABLE_COMMAND_FIFO_OVERFLOW_INSRT_V7 +#endif + +/*! @} command_fifo_overflow */ + +/*! + * @addtogroup group995941 invalid_command + * @brief Range = 2 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable INVALID_COMMAND Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V3 (2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V4 (2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V5 (2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V6 (2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT AES_BLK_INT_ENABLE_INVALID_COMMAND_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH AES_BLK_INT_ENABLE_INVALID_COMMAND_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V3 (0x4) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V4 (0x4) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V5 (0x4) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V6 (0x4) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V7 (0x4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK AES_BLK_INT_ENABLE_INVALID_COMMAND_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V3(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V4(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V5(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V6(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V7(r) ((((uint32_t)r) >> 2) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT AES_BLK_INT_ENABLE_INVALID_COMMAND_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT AES_BLK_INT_ENABLE_INVALID_COMMAND_INSRT_V7 +#endif + +/*! @} invalid_command */ + +/*! + * @addtogroup group995942 axi_read_response_not_okay + * @brief Range = 3 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable AXI_READ_RESPONSE_NOT_OKAY Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V3 (3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V4 (3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V5 (3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V6 (3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V7 (3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V3 (0x8) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V4 (0x8) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V5 (0x8) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V6 (0x8) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V7 (0x8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V3(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V4(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V5(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V6(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V7(r) ((((uint32_t)r) >> 3) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_READ_RESPONSE_NOT_OKAY_INSRT_V7 +#endif + +/*! @} axi_read_response_not_okay */ + +/*! + * @addtogroup group995943 axi_write_response_not_okay + * @brief Range = 4 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable AXI_WRITE_RESPONSE_NOT_OKAY Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V3 (4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V4 (4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V5 (4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V6 (4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V7 (4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V3 (0x10) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V4 (0x10) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V5 (0x10) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V6 (0x10) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V7 (0x10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V3(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V4(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V5(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V6(r) ((((uint32_t)r) >> 4) & 0x1) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V7(r) ((((uint32_t)r) >> 4) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 4) +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT AES_BLK_INT_ENABLE_AXI_WRITE_RESPONSE_NOT_OKAY_INSRT_V7 +#endif + +/*! @} axi_write_response_not_okay */ + +/*! + * @addtogroup group995944 flag_command + * @brief Range = 5 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable FLAG_COMMAND Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V3 (5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V4 (5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V5 (5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V6 (5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V7 (5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT AES_BLK_INT_ENABLE_FLAG_COMMAND_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH AES_BLK_INT_ENABLE_FLAG_COMMAND_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V3 (0x20) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V4 (0x20) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V5 (0x20) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V6 (0x20) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V7 (0x20) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK AES_BLK_INT_ENABLE_FLAG_COMMAND_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V3(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V4(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V5(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V6(r) ((((uint32_t)r) >> 5) & 0x1) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V7(r) ((((uint32_t)r) >> 5) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT AES_BLK_INT_ENABLE_FLAG_COMMAND_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 5) +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT AES_BLK_INT_ENABLE_FLAG_COMMAND_INSRT_V7 +#endif + +/*! @} flag_command */ + +/*! + * @addtogroup group995945 invalid_data_length + * @brief Range = 6 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable INVALID_DATA_LENGTH Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V3 (6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V4 (6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V5 (6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V6 (6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V7 (6) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V3 (0x40) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V4 (0x40) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V5 (0x40) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V6 (0x40) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V7 (0x40) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V3(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V4(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V5(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V6(r) ((((uint32_t)r) >> 6) & 0x1) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V7(r) ((((uint32_t)r) >> 6) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 6) +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 6) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT AES_BLK_INT_ENABLE_INVALID_DATA_LENGTH_INSRT_V7 +#endif + +/*! @} invalid_data_length */ + +/*! + * @addtogroup group995946 key_0_disabled + * @brief Range = 7 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_0_DISABLED Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V3 (7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V4 (7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V5 (7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V6 (7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V7 (7) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_0_DISABLED_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_0_DISABLED_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V3 (0x80) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V4 (0x80) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V5 (0x80) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V6 (0x80) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V7 (0x80) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_0_DISABLED_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V3(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V4(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V5(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V6(r) ((((uint32_t)r) >> 7) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V7(r) ((((uint32_t)r) >> 7) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_0_DISABLED_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 7) +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 7) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_0_DISABLED_INSRT_V7 +#endif + +/*! @} key_0_disabled */ + +/*! + * @addtogroup group995947 key_0_cmac_tag_mismatch + * @brief Range = 8 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_0_CMAC_TAG_MISMATCH Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V3 (8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V4 (8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V5 (8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V6 (8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V3 (0x100) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V4 (0x100) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V5 (0x100) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V6 (0x100) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V7 (0x100) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 8) +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_CMAC_TAG_MISMATCH_INSRT_V7 +#endif + +/*! @} key_0_cmac_tag_mismatch */ + +/*! + * @addtogroup group995948 key_0_policy_mismatch + * @brief Range = 9 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_0_POLICY_MISMATCH Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V3 (9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V4 (9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V5 (9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V6 (9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V7 (9) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V3 (0x200) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V4 (0x200) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V5 (0x200) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V6 (0x200) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V7 (0x200) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 9) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 9) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 9) +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 9) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_0_POLICY_MISMATCH_INSRT_V7 +#endif + +/*! @} key_0_policy_mismatch */ + +/*! + * @addtogroup group995949 key_0_invalid_at_use_time + * @brief Range = 10 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_0_INVALID_AT_USE_TIME Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V3 (10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V4 (10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V5 (10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V6 (10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V7 (10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V3 (0x400) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V4 (0x400) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V5 (0x400) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V6 (0x400) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V7 (0x400) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V3(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V4(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V5(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V6(r) ((((uint32_t)r) >> 10) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V7(r) ((((uint32_t)r) >> 10) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 10) +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 10) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_0_INVALID_AT_USE_TIME_INSRT_V7 +#endif + +/*! @} key_0_invalid_at_use_time */ + +/*! + * @addtogroup group995950 key_0_hdcp_err + * @brief Range = 11 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_0_HDCP_ERR Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V3 (11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V4 (11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V5 (11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V6 (11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V7 (11) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V3 (0x800) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V4 (0x800) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V5 (0x800) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V6 (0x800) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V7 (0x800) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V3(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V4(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V5(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V6(r) ((((uint32_t)r) >> 11) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V7(r) ((((uint32_t)r) >> 11) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 11) +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 11) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_0_HDCP_ERR_INSRT_V7 +#endif + +/*! @} key_0_hdcp_err */ + +/*! + * @addtogroup group995951 key_0_dpa_random_unseeded + * @brief Range = 12 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_0_DPA_RANDOM_UNSEEDED Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V6 (12) +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V7 (12) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V6 (0x1000) +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V7 (0x1000) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V6(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V7(r) ((((uint32_t)r) >> 12) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 12) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_ENABLE_KEY_0_DPA_RANDOM_UNSEEDED_INSRT_V7 +#endif + +/*! @} key_0_dpa_random_unseeded */ + +/*! + * @addtogroup group995952 key_1_disabled + * @brief Range = 13 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_1_DISABLED Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V3 (12) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V4 (12) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V5 (12) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V6 (13) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V7 (13) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT AES_BLK_INT_ENABLE_KEY_1_DISABLED_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH AES_BLK_INT_ENABLE_KEY_1_DISABLED_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V3 (0x1000) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V4 (0x1000) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V5 (0x1000) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V6 (0x2000) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V7 (0x2000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK AES_BLK_INT_ENABLE_KEY_1_DISABLED_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V3(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V4(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V5(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V6(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V7(r) ((((uint32_t)r) >> 13) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT AES_BLK_INT_ENABLE_KEY_1_DISABLED_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 13) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT AES_BLK_INT_ENABLE_KEY_1_DISABLED_INSRT_V7 +#endif + +/*! @} key_1_disabled */ + +/*! + * @addtogroup group995953 key_1_cmac_tag_mismatch + * @brief Range = 14 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_1_CMAC_TAG_MISMATCH Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V3 (13) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V4 (13) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V5 (13) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V6 (14) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V7 (14) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V3 (0x2000) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V4 (0x2000) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V5 (0x2000) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V6 (0x4000) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V7 (0x4000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 14) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 14) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_CMAC_TAG_MISMATCH_INSRT_V7 +#endif + +/*! @} key_1_cmac_tag_mismatch */ + +/*! + * @addtogroup group995954 key_1_policy_mismatch + * @brief Range = 15 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_1_POLICY_MISMATCH Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V3 (14) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V4 (14) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V5 (14) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V6 (15) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V7 (15) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V3 (0x4000) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V4 (0x4000) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V5 (0x4000) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V6 (0x8000) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V7 (0x8000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V3(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V4(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V5(r) ((((uint32_t)r) >> 14) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V6(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V7(r) ((((uint32_t)r) >> 15) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 14) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 15) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT AES_BLK_INT_ENABLE_KEY_1_POLICY_MISMATCH_INSRT_V7 +#endif + +/*! @} key_1_policy_mismatch */ + +/*! + * @addtogroup group995955 key_1_invalid_at_use_time + * @brief Range = 16 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_1_INVALID_AT_USE_TIME Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V3 (15) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V4 (15) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V5 (15) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V6 (16) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V7 (16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V3 (0x8000) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V4 (0x8000) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V5 (0x8000) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V6 (0x10000) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V7 (0x10000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V3(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V4(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V5(r) ((((uint32_t)r) >> 15) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V6(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V7(r) ((((uint32_t)r) >> 16) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 15) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT AES_BLK_INT_ENABLE_KEY_1_INVALID_AT_USE_TIME_INSRT_V7 +#endif + +/*! @} key_1_invalid_at_use_time */ + +/*! + * @addtogroup group995956 key_1_hdcp_err + * @brief Range = 17 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_1_HDCP_ERR Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V3 (16) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V4 (16) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V5 (16) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V6 (17) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V7 (17) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V3 (1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V4 (1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V5 (1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V3 (0x10000) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V4 (0x10000) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V5 (0x10000) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V6 (0x20000) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V7 (0x20000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V3 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V4 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V5 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V3(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V4(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V5(r) ((((uint32_t)r) >> 16) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V6(r) ((((uint32_t)r) >> 17) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V7(r) ((((uint32_t)r) >> 17) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 16) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 17) +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 17) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT AES_BLK_INT_ENABLE_KEY_1_HDCP_ERR_INSRT_V7 +#endif + +/*! @} key_1_hdcp_err */ + +/*! + * @addtogroup group995957 key_1_dpa_random_unseeded + * @brief Range = 18 | Width = 1 | Access = read-write | Default = 0x0 + * @details Enable KEY_1_DPA_RANDOM_UNSEEDED Interrupt. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V6 (18) +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V7 (18) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SHIFT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V6 (1) +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_WIDTH_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V6 (0x40000) +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V7 (0x40000) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_UMASK AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_UMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V6 (0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SMASK AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_SMASK_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V6(r) ((((uint32_t)r) >> 18) & 0x1) +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V7(r) ((((uint32_t)r) >> 18) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_XTRCT_V7 +#endif + +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 18) +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 18) +#if SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_INSRT AES_BLK_INT_ENABLE_KEY_1_DPA_RANDOM_UNSEEDED_INSRT_V7 +#endif + +/*! @} key_1_dpa_random_unseeded */ + +/*! + * @addtogroup group995959 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_INT_ENABLE_TNBLE_RESET_UMASK_S8000_A1 (0x1ffff) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_UMASK_S8000_B0 (0x1ffff) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_UMASK_S8001_A0 (0x1ffff) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_UMASK_T8002_A0 (0x7ffff) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_UMASK_T8010_A0 (0x7ffff) + +#define AES_BLK_INT_ENABLE_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_INT_ENABLE_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} int_enable */ + +/*! + * @addtogroup group995960 watermarks + * @brief Offset = 0x20 + * @details Watermarks for FIFO interrupts. + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_WATERMARKS_OFFSET_V3 (0x0 + 0x20) +#define AES_BLK_WATERMARKS_OFFSET_V4 (0x0 + 0x20) +#define AES_BLK_WATERMARKS_OFFSET_V5 (0x0 + 0x20) +#define AES_BLK_WATERMARKS_OFFSET_V6 (0x0 + 0x20) +#define AES_BLK_WATERMARKS_OFFSET_V7 (0x0 + 0x20) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_WATERMARKS_OFFSET AES_BLK_WATERMARKS_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_WATERMARKS_OFFSET AES_BLK_WATERMARKS_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_WATERMARKS_OFFSET AES_BLK_WATERMARKS_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_WATERMARKS_OFFSET AES_BLK_WATERMARKS_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_WATERMARKS_OFFSET AES_BLK_WATERMARKS_OFFSET_V7 +#endif + +/*! + * @addtogroup group995961 command_fifo_low + * @brief Range = 6:0 | Width = 7 | Access = read-write | Default = 0x0 + * @details Command FIFO Level below which the COMMAND_FIFO_LOW interrupt will + * be asserted + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V3 (0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V4 (0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V5 (0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V6 (0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SHIFT_V7 +#endif + +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V3 (7) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V4 (7) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V5 (7) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V6 (7) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V7 (7) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_WIDTH_V7 +#endif + +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V3 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V4 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V5 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V6 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V7 (0x7f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_UMASK_V7 +#endif + +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V3 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V4 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V5 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V6 (0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V7 (0x7f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_SMASK_V7 +#endif + +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x7f) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x7f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_XTRCT_V7 +#endif + +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V3(f) ((((uint32_t)f) & 0x7f) << 0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V4(f) ((((uint32_t)f) & 0x7f) << 0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V5(f) ((((uint32_t)f) & 0x7f) << 0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V6(f) ((((uint32_t)f) & 0x7f) << 0) +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V7(f) ((((uint32_t)f) & 0x7f) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT AES_BLK_WATERMARKS_COMMAND_FIFO_LOW_INSRT_V7 +#endif + +/*! @} command_fifo_low */ + +/*! + * @addtogroup group995963 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_WATERMARKS_TNBLE_RESET_UMASK_S8000_A1 (0x7f) +#define AES_BLK_WATERMARKS_TNBLE_RESET_UMASK_S8000_B0 (0x7f) +#define AES_BLK_WATERMARKS_TNBLE_RESET_UMASK_S8001_A0 (0x7f) +#define AES_BLK_WATERMARKS_TNBLE_RESET_UMASK_T8002_A0 (0x7f) +#define AES_BLK_WATERMARKS_TNBLE_RESET_UMASK_T8010_A0 (0x7f) + +#define AES_BLK_WATERMARKS_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_WATERMARKS_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_WATERMARKS_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_WATERMARKS_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_WATERMARKS_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} watermarks */ + +/*! + * @addtogroup group995964 command_fifo_status + * @brief Offset = 0x24 + * @details Status information for the Command Queue + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V3 (0x0 + 0x24) +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V4 (0x0 + 0x24) +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V5 (0x0 + 0x24) +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V6 (0x0 + 0x24) +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V7 (0x0 + 0x24) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_OFFSET AES_BLK_COMMAND_FIFO_STATUS_OFFSET_V7 +#endif + +/*! + * @addtogroup group995965 low + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x0 + * @details Command FIFO has gone below Low Watermark + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V3 (0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V4 (0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V5 (0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V6 (0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LOW_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V3 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V4 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V5 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V6 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LOW_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V3 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V4 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V5 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V6 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V3 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V4 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V5 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V6 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_LOW_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LOW_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_LOW_INSRT_V7 +#endif + +/*! @} low */ + +/*! + * @addtogroup group995966 empty + * @brief Range = 1 | Width = 1 | Access = read-only | Default = 0x1 + * @details Command FIFO is empty + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V3 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V4 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V5 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V6 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V3 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V4 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V5 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V6 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH AES_BLK_COMMAND_FIFO_STATUS_EMPTY_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V3 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V4 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V5 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V6 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V7 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V3 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V4 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V5 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V6 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK AES_BLK_COMMAND_FIFO_STATUS_EMPTY_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V3(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V4(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V5(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V6(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V7(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT AES_BLK_COMMAND_FIFO_STATUS_EMPTY_INSRT_V7 +#endif + +/*! @} empty */ + +/*! + * @addtogroup group995967 full + * @brief Range = 2 | Width = 1 | Access = read-only | Default = 0x0 + * @details Command FIFO is full + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V3 (2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V4 (2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V5 (2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V6 (2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V7 (2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_FULL_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V3 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V4 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V5 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V6 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_FULL_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V3 (0x4) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V4 (0x4) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V5 (0x4) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V6 (0x4) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V7 (0x4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V3 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V4 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V5 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V6 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK AES_BLK_COMMAND_FIFO_STATUS_FULL_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V3(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V4(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V5(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V6(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V7(r) ((((uint32_t)r) >> 2) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_FULL_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT AES_BLK_COMMAND_FIFO_STATUS_FULL_INSRT_V7 +#endif + +/*! @} full */ + +/*! + * @addtogroup group995968 overflow + * @brief Range = 3 | Width = 1 | Access = read-only | Default = 0x0 + * @details Software overflowed Command FIFO. This bit is not sticky + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V3 (3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V4 (3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V5 (3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V6 (3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V7 (3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V3 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V4 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V5 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V6 (1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V3 (0x8) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V4 (0x8) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V5 (0x8) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V6 (0x8) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V7 (0x8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V3 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V4 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V5 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V6 (0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V3(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V4(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V5(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V6(r) ((((uint32_t)r) >> 3) & 0x1) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V7(r) ((((uint32_t)r) >> 3) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 3) +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 3) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT AES_BLK_COMMAND_FIFO_STATUS_OVERFLOW_INSRT_V7 +#endif + +/*! @} overflow */ + +/*! + * @addtogroup group995970 level + * @brief Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 + * @details Number of 4 byte words in the Command FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V3 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V4 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V5 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V6 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V3 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V4 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V5 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V6 (8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH AES_BLK_COMMAND_FIFO_STATUS_LEVEL_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V3 (0xff00) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V4 (0xff00) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V5 (0xff00) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V6 (0xff00) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V7 (0xff00) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V3 (0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V4 (0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V5 (0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V6 (0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V7 (0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK AES_BLK_COMMAND_FIFO_STATUS_LEVEL_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V3(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V4(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V5(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0xff) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0xff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V3(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V4(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V5(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V6(f) ((((uint32_t)f) & 0xff) << 8) +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V7(f) ((((uint32_t)f) & 0xff) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT AES_BLK_COMMAND_FIFO_STATUS_LEVEL_INSRT_V7 +#endif + +/*! @} level */ + +/*! + * @addtogroup group995971 read_pointer + * @brief Range = 22:16 | Width = 7 | Access = read-only | Default = 0x0 + * @details Pointer to next command + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V3 (16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V4 (16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V5 (16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V6 (16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V7 (16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V3 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V4 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V5 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V6 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V7 (7) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V3 (0x7f0000) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V4 (0x7f0000) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V5 (0x7f0000) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V6 (0x7f0000) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V7 (0x7f0000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V3 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V4 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V5 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V6 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V7 (0x7f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V3(r) ((((uint32_t)r) >> 16) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V4(r) ((((uint32_t)r) >> 16) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V5(r) ((((uint32_t)r) >> 16) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V6(r) ((((uint32_t)r) >> 16) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V7(r) ((((uint32_t)r) >> 16) & 0x7f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V3(f) ((((uint32_t)f) & 0x7f) << 16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V4(f) ((((uint32_t)f) & 0x7f) << 16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V5(f) ((((uint32_t)f) & 0x7f) << 16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V6(f) ((((uint32_t)f) & 0x7f) << 16) +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V7(f) ((((uint32_t)f) & 0x7f) << 16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_READ_POINTER_INSRT_V7 +#endif + +/*! @} read_pointer */ + +/*! + * @addtogroup group995973 write_pointer + * @brief Range = 30:24 | Width = 7 | Access = read-only | Default = 0x0 + * @details Pointer to next empty location + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V3 (24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V4 (24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V5 (24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V6 (24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V7 (24) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V3 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V4 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V5 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V6 (7) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V7 (7) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V3 (0x7f000000) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V4 (0x7f000000) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V5 (0x7f000000) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V6 (0x7f000000) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V7 (0x7f000000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V3 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V4 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V5 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V6 (0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V7 (0x7f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V3(r) ((((uint32_t)r) >> 24) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V4(r) ((((uint32_t)r) >> 24) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V5(r) ((((uint32_t)r) >> 24) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V6(r) ((((uint32_t)r) >> 24) & 0x7f) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V7(r) ((((uint32_t)r) >> 24) & 0x7f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V3(f) ((((uint32_t)f) & 0x7f) << 24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V4(f) ((((uint32_t)f) & 0x7f) << 24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V5(f) ((((uint32_t)f) & 0x7f) << 24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V6(f) ((((uint32_t)f) & 0x7f) << 24) +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V7(f) ((((uint32_t)f) & 0x7f) << 24) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_COMMAND_FIFO_STATUS_WRITE_POINTER_INSRT_V7 +#endif + +/*! @} write_pointer */ + +/*! + * @addtogroup group995975 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_UMASK_S8000_A1 (0x7f7fff0f) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_UMASK_S8000_B0 (0x7f7fff0f) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_UMASK_S8001_A0 (0x7f7fff0f) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_UMASK_T8002_A0 (0x7f7fff0f) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_UMASK_T8010_A0 (0x7f7fff0f) + +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_VALUE_S8000_A1 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_VALUE_S8000_B0 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_VALUE_S8001_A0 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_VALUE_T8002_A0 (0x2) +#define AES_BLK_COMMAND_FIFO_STATUS_TNBLE_RESET_VALUE_T8010_A0 (0x2) + +/*! @} reset */ + +/*! @} command_fifo_status */ + +/*! + * @addtogroup group995976 history_fifo_status + * @brief Offset = 0x28 + * @details Status information for the DMA Debug FIFO + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V3 (0x0 + 0x28) +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V4 (0x0 + 0x28) +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V5 (0x0 + 0x28) +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V6 (0x0 + 0x28) +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V7 (0x0 + 0x28) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_OFFSET AES_BLK_HISTORY_FIFO_STATUS_OFFSET_V7 +#endif + +/*! + * @addtogroup group995977 empty + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x1 + * @details History FIFO is empty + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V3 (0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V4 (0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V5 (0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V6 (0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SHIFT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V3 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V4 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V5 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V6 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH AES_BLK_HISTORY_FIFO_STATUS_EMPTY_WIDTH_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V3 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V4 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V5 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V6 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_UMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V3 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V4 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V5 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V6 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK AES_BLK_HISTORY_FIFO_STATUS_EMPTY_SMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_XTRCT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT AES_BLK_HISTORY_FIFO_STATUS_EMPTY_INSRT_V7 +#endif + +/*! @} empty */ + +/*! + * @addtogroup group995978 full + * @brief Range = 1 | Width = 1 | Access = read-only | Default = 0x0 + * @details History FIFO is full + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V3 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V4 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V5 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V6 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_FULL_SHIFT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V3 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V4 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V5 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V6 (1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_FULL_WIDTH_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V3 (0x2) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V4 (0x2) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V5 (0x2) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V6 (0x2) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V7 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_UMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V3 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V4 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V5 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V6 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK AES_BLK_HISTORY_FIFO_STATUS_FULL_SMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V3(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V4(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V5(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V6(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V7(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_FULL_XTRCT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V3(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V4(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V5(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V6(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT AES_BLK_HISTORY_FIFO_STATUS_FULL_INSRT_V7 +#endif + +/*! @} full */ + +/*! + * @addtogroup group995980 level + * @brief Range = 13:8 | Width = 6 | Access = read-only | Default = 0x0 + * @details Number of 4 byte words in the History FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V3 (8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V4 (8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V5 (8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V6 (8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V7 (8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SHIFT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V3 (6) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V4 (6) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V5 (6) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V6 (6) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V7 (6) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH AES_BLK_HISTORY_FIFO_STATUS_LEVEL_WIDTH_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V3 (0x3f00) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V4 (0x3f00) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V5 (0x3f00) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V6 (0x3f00) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V7 (0x3f00) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_UMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V3 (0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V4 (0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V5 (0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V6 (0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V7 (0x3f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK AES_BLK_HISTORY_FIFO_STATUS_LEVEL_SMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V3(r) ((((uint32_t)r) >> 8) & 0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V4(r) ((((uint32_t)r) >> 8) & 0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V5(r) ((((uint32_t)r) >> 8) & 0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V6(r) ((((uint32_t)r) >> 8) & 0x3f) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V7(r) ((((uint32_t)r) >> 8) & 0x3f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_XTRCT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V3(f) ((((uint32_t)f) & 0x3f) << 8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V4(f) ((((uint32_t)f) & 0x3f) << 8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V5(f) ((((uint32_t)f) & 0x3f) << 8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V6(f) ((((uint32_t)f) & 0x3f) << 8) +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V7(f) ((((uint32_t)f) & 0x3f) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT AES_BLK_HISTORY_FIFO_STATUS_LEVEL_INSRT_V7 +#endif + +/*! @} level */ + +/*! + * @addtogroup group995982 write_pointer + * @brief Range = 20:16 | Width = 5 | Access = read-only | Default = 0x0 + * @details Pointer to next write location + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V3 (16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V4 (16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V5 (16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V6 (16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V7 (16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SHIFT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V3 (5) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V4 (5) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V5 (5) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V6 (5) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V7 (5) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_WIDTH_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V3 (0x1f0000) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V4 (0x1f0000) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V5 (0x1f0000) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V6 (0x1f0000) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V7 (0x1f0000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_UMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V3 (0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V4 (0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V5 (0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V6 (0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V7 (0x1f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_SMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V3(r) ((((uint32_t)r) >> 16) & 0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V4(r) ((((uint32_t)r) >> 16) & 0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V5(r) ((((uint32_t)r) >> 16) & 0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V6(r) ((((uint32_t)r) >> 16) & 0x1f) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V7(r) ((((uint32_t)r) >> 16) & 0x1f) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_XTRCT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V3(f) ((((uint32_t)f) & 0x1f) << 16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V4(f) ((((uint32_t)f) & 0x1f) << 16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V5(f) ((((uint32_t)f) & 0x1f) << 16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V6(f) ((((uint32_t)f) & 0x1f) << 16) +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V7(f) ((((uint32_t)f) & 0x1f) << 16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT AES_BLK_HISTORY_FIFO_STATUS_WRITE_POINTER_INSRT_V7 +#endif + +/*! @} write_pointer */ + +/*! + * @addtogroup group995984 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_UMASK_S8000_A1 (0x1f3f03) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_UMASK_S8000_B0 (0x1f3f03) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_UMASK_S8001_A0 (0x1f3f03) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_UMASK_T8002_A0 (0x1f3f03) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_UMASK_T8010_A0 (0x1f3f03) + +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_VALUE_S8000_A1 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_VALUE_S8000_B0 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_VALUE_S8001_A0 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_VALUE_T8002_A0 (0x1) +#define AES_BLK_HISTORY_FIFO_STATUS_TNBLE_RESET_VALUE_T8010_A0 (0x1) + +/*! @} reset */ + +/*! @} history_fifo_status */ + +/*! + * @addtogroup group995985 command_fifo_count + * @brief Offset = 0x2c + * @details Total count of commands since the Command FIFO was last enabled + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V3 (0x0 + 0x2c) +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V4 (0x0 + 0x2c) +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V5 (0x0 + 0x2c) +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V6 (0x0 + 0x2c) +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V7 (0x0 + 0x2c) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_COUNT_OFFSET AES_BLK_COMMAND_FIFO_COUNT_OFFSET_V7 +#endif + +/*! + * @addtogroup group995986 total + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details Number of commands popped from the Command FIFO since it was last + * turned on. (saturates at max) + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V3 (0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V4 (0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V5 (0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V6 (0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V3 (32) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V4 (32) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V5 (32) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V6 (32) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V7 (32) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH AES_BLK_COMMAND_FIFO_COUNT_TOTAL_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V3 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V4 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V5 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V6 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V3 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V4 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V5 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V6 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK AES_BLK_COMMAND_FIFO_COUNT_TOTAL_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V3(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V4(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V5(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V6(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V7(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT AES_BLK_COMMAND_FIFO_COUNT_TOTAL_INSRT_V7 +#endif + +/*! @} total */ + +/*! + * @addtogroup group995987 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_UMASK_S8000_A1 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_UMASK_S8000_B0 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_UMASK_S8001_A0 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_UMASK_T8002_A0 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_UMASK_T8010_A0 (0xffffffff) + +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_COMMAND_FIFO_COUNT_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} command_fifo_count */ + +/*! + * @addtogroup group995988 flag_command + * @brief Offset = 0x30 + * @details Interrupt code that provides information about the flag interrupt + * that occurred. + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_FLAG_COMMAND_OFFSET_V3 (0x0 + 0x30) +#define AES_BLK_FLAG_COMMAND_OFFSET_V4 (0x0 + 0x30) +#define AES_BLK_FLAG_COMMAND_OFFSET_V5 (0x0 + 0x30) +#define AES_BLK_FLAG_COMMAND_OFFSET_V6 (0x0 + 0x30) +#define AES_BLK_FLAG_COMMAND_OFFSET_V7 (0x0 + 0x30) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_FLAG_COMMAND_OFFSET AES_BLK_FLAG_COMMAND_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_FLAG_COMMAND_OFFSET AES_BLK_FLAG_COMMAND_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_FLAG_COMMAND_OFFSET AES_BLK_FLAG_COMMAND_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_FLAG_COMMAND_OFFSET AES_BLK_FLAG_COMMAND_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_FLAG_COMMAND_OFFSET AES_BLK_FLAG_COMMAND_OFFSET_V7 +#endif + +/*! + * @addtogroup group995989 code + * @brief Range = 15:0 | Width = 16 | Access = read-only | Default = 0x0 + * @details Interrupt code from the last flag command executed in the Command + * FIFO + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT_V3 (0) +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT_V4 (0) +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT_V5 (0) +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT_V6 (0) +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT AES_BLK_FLAG_COMMAND_CODE_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT AES_BLK_FLAG_COMMAND_CODE_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT AES_BLK_FLAG_COMMAND_CODE_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT AES_BLK_FLAG_COMMAND_CODE_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_FLAG_COMMAND_CODE_SHIFT AES_BLK_FLAG_COMMAND_CODE_SHIFT_V7 +#endif + +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH_V3 (16) +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH_V4 (16) +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH_V5 (16) +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH_V6 (16) +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH_V7 (16) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH AES_BLK_FLAG_COMMAND_CODE_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH AES_BLK_FLAG_COMMAND_CODE_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH AES_BLK_FLAG_COMMAND_CODE_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH AES_BLK_FLAG_COMMAND_CODE_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_FLAG_COMMAND_CODE_WIDTH AES_BLK_FLAG_COMMAND_CODE_WIDTH_V7 +#endif + +#define AES_BLK_FLAG_COMMAND_CODE_UMASK_V3 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_UMASK_V4 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_UMASK_V5 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_UMASK_V6 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_UMASK_V7 (0xffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_FLAG_COMMAND_CODE_UMASK AES_BLK_FLAG_COMMAND_CODE_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_FLAG_COMMAND_CODE_UMASK AES_BLK_FLAG_COMMAND_CODE_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_FLAG_COMMAND_CODE_UMASK AES_BLK_FLAG_COMMAND_CODE_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_FLAG_COMMAND_CODE_UMASK AES_BLK_FLAG_COMMAND_CODE_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_FLAG_COMMAND_CODE_UMASK AES_BLK_FLAG_COMMAND_CODE_UMASK_V7 +#endif + +#define AES_BLK_FLAG_COMMAND_CODE_SMASK_V3 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_SMASK_V4 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_SMASK_V5 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_SMASK_V6 (0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_SMASK_V7 (0xffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_FLAG_COMMAND_CODE_SMASK AES_BLK_FLAG_COMMAND_CODE_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_FLAG_COMMAND_CODE_SMASK AES_BLK_FLAG_COMMAND_CODE_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_FLAG_COMMAND_CODE_SMASK AES_BLK_FLAG_COMMAND_CODE_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_FLAG_COMMAND_CODE_SMASK AES_BLK_FLAG_COMMAND_CODE_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_FLAG_COMMAND_CODE_SMASK AES_BLK_FLAG_COMMAND_CODE_SMASK_V7 +#endif + +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xffff) +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT AES_BLK_FLAG_COMMAND_CODE_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT AES_BLK_FLAG_COMMAND_CODE_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT AES_BLK_FLAG_COMMAND_CODE_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT AES_BLK_FLAG_COMMAND_CODE_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_FLAG_COMMAND_CODE_XTRCT AES_BLK_FLAG_COMMAND_CODE_XTRCT_V7 +#endif + +#define AES_BLK_FLAG_COMMAND_CODE_INSRT_V3(f) ((((uint32_t)f) & 0xffff) << 0) +#define AES_BLK_FLAG_COMMAND_CODE_INSRT_V4(f) ((((uint32_t)f) & 0xffff) << 0) +#define AES_BLK_FLAG_COMMAND_CODE_INSRT_V5(f) ((((uint32_t)f) & 0xffff) << 0) +#define AES_BLK_FLAG_COMMAND_CODE_INSRT_V6(f) ((((uint32_t)f) & 0xffff) << 0) +#define AES_BLK_FLAG_COMMAND_CODE_INSRT_V7(f) ((((uint32_t)f) & 0xffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_FLAG_COMMAND_CODE_INSRT AES_BLK_FLAG_COMMAND_CODE_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_FLAG_COMMAND_CODE_INSRT AES_BLK_FLAG_COMMAND_CODE_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_FLAG_COMMAND_CODE_INSRT AES_BLK_FLAG_COMMAND_CODE_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_FLAG_COMMAND_CODE_INSRT AES_BLK_FLAG_COMMAND_CODE_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_FLAG_COMMAND_CODE_INSRT AES_BLK_FLAG_COMMAND_CODE_INSRT_V7 +#endif + +/*! @} code */ + +/*! + * @addtogroup group995991 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_UMASK_S8000_A1 (0xffff) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_UMASK_S8000_B0 (0xffff) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_UMASK_S8001_A0 (0xffff) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_UMASK_T8002_A0 (0xffff) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_UMASK_T8010_A0 (0xffff) + +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_FLAG_COMMAND_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} flag_command */ + +/*! + * @addtogroup group995992 skg_key + * @brief Offset = 0x34 + * @details Secure Key Generation Key + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_SKG_KEY_OFFSET_V3 (0x0 + 0x34) +#define AES_BLK_SKG_KEY_OFFSET_V4 (0x0 + 0x34) +#define AES_BLK_SKG_KEY_OFFSET_V5 (0x0 + 0x34) +#define AES_BLK_SKG_KEY_OFFSET_V6 (0x0 + 0x34) +#define AES_BLK_SKG_KEY_OFFSET_V7 (0x0 + 0x34) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_SKG_KEY_OFFSET AES_BLK_SKG_KEY_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_SKG_KEY_OFFSET AES_BLK_SKG_KEY_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_SKG_KEY_OFFSET AES_BLK_SKG_KEY_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_SKG_KEY_OFFSET AES_BLK_SKG_KEY_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_SKG_KEY_OFFSET AES_BLK_SKG_KEY_OFFSET_V7 +#endif + +/*! + * @addtogroup group995993 count + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details Count + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_SKG_KEY_COUNT_SHIFT_V3 (0) +#define AES_BLK_SKG_KEY_COUNT_SHIFT_V4 (0) +#define AES_BLK_SKG_KEY_COUNT_SHIFT_V5 (0) +#define AES_BLK_SKG_KEY_COUNT_SHIFT_V6 (0) +#define AES_BLK_SKG_KEY_COUNT_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_SKG_KEY_COUNT_SHIFT AES_BLK_SKG_KEY_COUNT_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_SKG_KEY_COUNT_SHIFT AES_BLK_SKG_KEY_COUNT_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_SKG_KEY_COUNT_SHIFT AES_BLK_SKG_KEY_COUNT_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_SKG_KEY_COUNT_SHIFT AES_BLK_SKG_KEY_COUNT_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_SKG_KEY_COUNT_SHIFT AES_BLK_SKG_KEY_COUNT_SHIFT_V7 +#endif + +#define AES_BLK_SKG_KEY_COUNT_WIDTH_V3 (32) +#define AES_BLK_SKG_KEY_COUNT_WIDTH_V4 (32) +#define AES_BLK_SKG_KEY_COUNT_WIDTH_V5 (32) +#define AES_BLK_SKG_KEY_COUNT_WIDTH_V6 (32) +#define AES_BLK_SKG_KEY_COUNT_WIDTH_V7 (32) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_SKG_KEY_COUNT_WIDTH AES_BLK_SKG_KEY_COUNT_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_SKG_KEY_COUNT_WIDTH AES_BLK_SKG_KEY_COUNT_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_SKG_KEY_COUNT_WIDTH AES_BLK_SKG_KEY_COUNT_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_SKG_KEY_COUNT_WIDTH AES_BLK_SKG_KEY_COUNT_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_SKG_KEY_COUNT_WIDTH AES_BLK_SKG_KEY_COUNT_WIDTH_V7 +#endif + +#define AES_BLK_SKG_KEY_COUNT_UMASK_V3 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_UMASK_V4 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_UMASK_V5 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_UMASK_V6 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_UMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_SKG_KEY_COUNT_UMASK AES_BLK_SKG_KEY_COUNT_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_SKG_KEY_COUNT_UMASK AES_BLK_SKG_KEY_COUNT_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_SKG_KEY_COUNT_UMASK AES_BLK_SKG_KEY_COUNT_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_SKG_KEY_COUNT_UMASK AES_BLK_SKG_KEY_COUNT_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_SKG_KEY_COUNT_UMASK AES_BLK_SKG_KEY_COUNT_UMASK_V7 +#endif + +#define AES_BLK_SKG_KEY_COUNT_SMASK_V3 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_SMASK_V4 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_SMASK_V5 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_SMASK_V6 (0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_SMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_SKG_KEY_COUNT_SMASK AES_BLK_SKG_KEY_COUNT_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_SKG_KEY_COUNT_SMASK AES_BLK_SKG_KEY_COUNT_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_SKG_KEY_COUNT_SMASK AES_BLK_SKG_KEY_COUNT_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_SKG_KEY_COUNT_SMASK AES_BLK_SKG_KEY_COUNT_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_SKG_KEY_COUNT_SMASK AES_BLK_SKG_KEY_COUNT_SMASK_V7 +#endif + +#define AES_BLK_SKG_KEY_COUNT_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_SKG_KEY_COUNT_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_SKG_KEY_COUNT_XTRCT AES_BLK_SKG_KEY_COUNT_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_SKG_KEY_COUNT_XTRCT AES_BLK_SKG_KEY_COUNT_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_SKG_KEY_COUNT_XTRCT AES_BLK_SKG_KEY_COUNT_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_SKG_KEY_COUNT_XTRCT AES_BLK_SKG_KEY_COUNT_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_SKG_KEY_COUNT_XTRCT AES_BLK_SKG_KEY_COUNT_XTRCT_V7 +#endif + +#define AES_BLK_SKG_KEY_COUNT_INSRT_V3(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_SKG_KEY_COUNT_INSRT_V4(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_SKG_KEY_COUNT_INSRT_V5(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_SKG_KEY_COUNT_INSRT_V6(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_SKG_KEY_COUNT_INSRT_V7(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_SKG_KEY_COUNT_INSRT AES_BLK_SKG_KEY_COUNT_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_SKG_KEY_COUNT_INSRT AES_BLK_SKG_KEY_COUNT_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_SKG_KEY_COUNT_INSRT AES_BLK_SKG_KEY_COUNT_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_SKG_KEY_COUNT_INSRT AES_BLK_SKG_KEY_COUNT_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_SKG_KEY_COUNT_INSRT AES_BLK_SKG_KEY_COUNT_INSRT_V7 +#endif + +/*! @} count */ + +/*! + * @addtogroup group995994 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_SKG_KEY_TNBLE_RESET_UMASK_S8000_A1 (0xffffffff) +#define AES_BLK_SKG_KEY_TNBLE_RESET_UMASK_S8000_B0 (0xffffffff) +#define AES_BLK_SKG_KEY_TNBLE_RESET_UMASK_S8001_A0 (0xffffffff) +#define AES_BLK_SKG_KEY_TNBLE_RESET_UMASK_T8002_A0 (0xffffffff) +#define AES_BLK_SKG_KEY_TNBLE_RESET_UMASK_T8010_A0 (0xffffffff) + +#define AES_BLK_SKG_KEY_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_SKG_KEY_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_SKG_KEY_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_SKG_KEY_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_SKG_KEY_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} skg_key */ + +/*! + * @addtogroup group995995 clear_fifos + * @brief Offset = 0x38 + * @details Clear COMMAND and HISTORY FIFOs + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_CLEAR_FIFOS_OFFSET_V5 (0x0 + 0x38) +#define AES_BLK_CLEAR_FIFOS_OFFSET_V6 (0x0 + 0x38) +#define AES_BLK_CLEAR_FIFOS_OFFSET_V7 (0x0 + 0x38) +#if SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_CLEAR_FIFOS_OFFSET AES_BLK_CLEAR_FIFOS_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_CLEAR_FIFOS_OFFSET AES_BLK_CLEAR_FIFOS_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CLEAR_FIFOS_OFFSET AES_BLK_CLEAR_FIFOS_OFFSET_V7 +#endif + +/*! + * @addtogroup group995996 reset + * @brief Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Write 1 to this field to reset the contents of the Command and + * History FIFOs to zero. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_CLEAR_FIFOS_RESET_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CLEAR_FIFOS_RESET_SHIFT AES_BLK_CLEAR_FIFOS_RESET_SHIFT_V7 +#endif + +#define AES_BLK_CLEAR_FIFOS_RESET_WIDTH_V7 (1) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CLEAR_FIFOS_RESET_WIDTH AES_BLK_CLEAR_FIFOS_RESET_WIDTH_V7 +#endif + +#define AES_BLK_CLEAR_FIFOS_RESET_UMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CLEAR_FIFOS_RESET_UMASK AES_BLK_CLEAR_FIFOS_RESET_UMASK_V7 +#endif + +#define AES_BLK_CLEAR_FIFOS_RESET_SMASK_V7 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CLEAR_FIFOS_RESET_SMASK AES_BLK_CLEAR_FIFOS_RESET_SMASK_V7 +#endif + +#define AES_BLK_CLEAR_FIFOS_RESET_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CLEAR_FIFOS_RESET_XTRCT AES_BLK_CLEAR_FIFOS_RESET_XTRCT_V7 +#endif + +#define AES_BLK_CLEAR_FIFOS_RESET_INSRT_V7(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_CLEAR_FIFOS_RESET_INSRT AES_BLK_CLEAR_FIFOS_RESET_INSRT_V7 +#endif + +/*! @} reset */ + +/*! + * @addtogroup group995998 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_CLEAR_FIFOS_TNBLE_RESET_UMASK_T8010_A0 (0x1) + +#define AES_BLK_CLEAR_FIFOS_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} clear_fifos */ + +/*! + * @addtogroup group995999 command_fifo + * @brief Offset = 0x200 + * @details Command FIFO. FIFO Depth is (128) Words + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_OFFSET_V3 (0x0 + 0x100) +#define AES_BLK_COMMAND_FIFO_OFFSET_V4 (0x0 + 0x100) +#define AES_BLK_COMMAND_FIFO_OFFSET_V5 (0x0 + 0x200) +#define AES_BLK_COMMAND_FIFO_OFFSET_V6 (0x0 + 0x200) +#define AES_BLK_COMMAND_FIFO_OFFSET_V7 (0x0 + 0x200) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_OFFSET AES_BLK_COMMAND_FIFO_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_OFFSET AES_BLK_COMMAND_FIFO_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_OFFSET AES_BLK_COMMAND_FIFO_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_OFFSET AES_BLK_COMMAND_FIFO_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_OFFSET AES_BLK_COMMAND_FIFO_OFFSET_V7 +#endif + +/*! + * @addtogroup group996000 push_word + * @brief Range = 31:0 | Width = 32 | Access = write-only | Default = 0x0 + * @details Command Word + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V3 (0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V4 (0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V5 (0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V6 (0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT AES_BLK_COMMAND_FIFO_PUSH_WORD_SHIFT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V3 (32) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V4 (32) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V5 (32) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V6 (32) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V7 (32) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH AES_BLK_COMMAND_FIFO_PUSH_WORD_WIDTH_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V3 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V4 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V5 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V6 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_UMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V3 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V4 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V5 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V6 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK AES_BLK_COMMAND_FIFO_PUSH_WORD_SMASK_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT AES_BLK_COMMAND_FIFO_PUSH_WORD_XTRCT_V7 +#endif + +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V3(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V4(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V5(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V6(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V7(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT AES_BLK_COMMAND_FIFO_PUSH_WORD_INSRT_V7 +#endif + +/*! @} push_word */ + +/*! + * @addtogroup group996001 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_UMASK_S8000_A1 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_UMASK_S8000_B0 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_UMASK_S8001_A0 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_UMASK_T8002_A0 (0xffffffff) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_UMASK_T8010_A0 (0xffffffff) + +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_COMMAND_FIFO_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} command_fifo */ + +/*! + * @addtogroup group996003 history_fifo + * @brief Offset = 0x400 + * @details Last (32) Commands words + * @see @ref SAIRegister + * @{ + */ + +/*! + * Compute the offset for an element in array 'history_fifo'. The base offset + * of 'history_fifo' is 0x400. The size of each element in 'history_fifo' is 4 + * bytes. + * @param i Index for an element in 'history_fifo'. Legal values include [0...31]. + */ +#define AES_BLK_HISTORY_FIFO_OFFSET_V3 (0x0 + 0x200) +#define AES_BLK_HISTORY_FIFO_OFFSET_V4 (0x0 + 0x200) +#define AES_BLK_HISTORY_FIFO_OFFSET_V5(i) (0x0 + 0x400 + (i) * 4) +#define AES_BLK_HISTORY_FIFO_OFFSET_V6 (0x0 + 0x400) +#define AES_BLK_HISTORY_FIFO_OFFSET_V7(i) (0x0 + 0x400 + (i) * 4) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_OFFSET AES_BLK_HISTORY_FIFO_OFFSET_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_OFFSET AES_BLK_HISTORY_FIFO_OFFSET_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_OFFSET AES_BLK_HISTORY_FIFO_OFFSET_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_OFFSET AES_BLK_HISTORY_FIFO_OFFSET_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_OFFSET AES_BLK_HISTORY_FIFO_OFFSET_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_COUNT_V3 (1) +#define AES_BLK_HISTORY_FIFO_COUNT_V4 (1) +#define AES_BLK_HISTORY_FIFO_COUNT_V5 (32) +#define AES_BLK_HISTORY_FIFO_COUNT_V6 (1) +#define AES_BLK_HISTORY_FIFO_COUNT_V7 (32) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_COUNT AES_BLK_HISTORY_FIFO_COUNT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_COUNT AES_BLK_HISTORY_FIFO_COUNT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_COUNT AES_BLK_HISTORY_FIFO_COUNT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_COUNT AES_BLK_HISTORY_FIFO_COUNT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_COUNT AES_BLK_HISTORY_FIFO_COUNT_V7 +#endif + +/*! + * @addtogroup group996004 pop_word + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details Unconnected FIFO output. Command words should be read from + * HISTORY_FIFO - 0x3600 + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V3 (0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V4 (0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V5 (0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V6 (0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V7 (0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT AES_BLK_HISTORY_FIFO_POP_WORD_SHIFT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V3 (32) +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V4 (32) +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V5 (32) +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V6 (32) +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V7 (32) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH AES_BLK_HISTORY_FIFO_POP_WORD_WIDTH_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V3 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V4 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V5 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V6 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_POP_WORD_UMASK AES_BLK_HISTORY_FIFO_POP_WORD_UMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V3 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V4 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V5 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V6 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V7 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_POP_WORD_SMASK AES_BLK_HISTORY_FIFO_POP_WORD_SMASK_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V3(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V4(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V5(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V6(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V7(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT AES_BLK_HISTORY_FIFO_POP_WORD_XTRCT_V7 +#endif + +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V3(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V4(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V5(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V6(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V7(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V3 +#elif SPDS_AES_VERSION == SPDS_AES_V4 +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V4 +#elif SPDS_AES_VERSION == SPDS_AES_V5 +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V5 +#elif SPDS_AES_VERSION == SPDS_AES_V6 +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V6 +#elif SPDS_AES_VERSION == SPDS_AES_V7 +#define AES_BLK_HISTORY_FIFO_POP_WORD_INSRT AES_BLK_HISTORY_FIFO_POP_WORD_INSRT_V7 +#endif + +/*! @} pop_word */ + +/*! + * @addtogroup group996005 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_UMASK_S8000_A1 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_UMASK_S8000_B0 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_UMASK_S8001_A0 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_UMASK_T8002_A0 (0xffffffff) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_UMASK_T8010_A0 (0xffffffff) + +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_VALUE_S8000_A1 (0x0) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_VALUE_S8000_B0 (0x0) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_VALUE_S8001_A0 (0x0) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_VALUE_T8002_A0 (0x0) +#define AES_BLK_HISTORY_FIFO_TNBLE_RESET_VALUE_T8010_A0 (0x0) + +/*! @} reset */ + +/*! @} history_fifo */ + +/*! + * @addtogroup group570682 disable (AES_DISABLE) + * @brief Offset = 0x4 + * @details AES GID0, GID1, UID1 and Fairplay Descrambler Disable register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DISABLE_OFFSET_V1 (0x0 + 0x4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_OFFSET AES_BLK_DISABLE_OFFSET_V1 +#endif + +/*! + * @addtogroup group570683 id (disable_id) + * @brief Range = 2:0 | Width = 3 | Access = write-only | Default = 0x0 + * @details Write to the disable_id field to disable use of GID0, GID1, and + * UID1 keys until the next chip reset. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DISABLE_ID_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_SHIFT AES_BLK_DISABLE_ID_SHIFT_V1 +#endif + +#define AES_BLK_DISABLE_ID_WIDTH_V1 (3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_WIDTH AES_BLK_DISABLE_ID_WIDTH_V1 +#endif + +#define AES_BLK_DISABLE_ID_UMASK_V1 (0x7) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_UMASK AES_BLK_DISABLE_ID_UMASK_V1 +#endif + +#define AES_BLK_DISABLE_ID_SMASK_V1 (0x7) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_SMASK AES_BLK_DISABLE_ID_SMASK_V1 +#endif + +#define AES_BLK_DISABLE_ID_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x7) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_XTRCT AES_BLK_DISABLE_ID_XTRCT_V1 +#endif + +#define AES_BLK_DISABLE_ID_INSRT_V1(f) ((((uint32_t)f) & 0x7) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_INSRT AES_BLK_DISABLE_ID_INSRT_V1 +#endif + +/*! @} id (disable_id) */ + +/*! + * @addtogroup group570687 dsb (disable_dsb) + * @brief Range = 3 | Width = 1 | Access = write-only | Default = 0x0 + * @details Write to the disable_dsb field to disable use of the Fairplay + * descrambler until the next chip reset. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DISABLE_DSB_SHIFT_V1 (3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_SHIFT AES_BLK_DISABLE_DSB_SHIFT_V1 +#endif + +#define AES_BLK_DISABLE_DSB_WIDTH_V1 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_WIDTH AES_BLK_DISABLE_DSB_WIDTH_V1 +#endif + +#define AES_BLK_DISABLE_DSB_UMASK_V1 (0x8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_UMASK AES_BLK_DISABLE_DSB_UMASK_V1 +#endif + +#define AES_BLK_DISABLE_DSB_SMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_SMASK AES_BLK_DISABLE_DSB_SMASK_V1 +#endif + +#define AES_BLK_DISABLE_DSB_XTRCT_V1(r) ((((uint32_t)r) >> 3) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_XTRCT AES_BLK_DISABLE_DSB_XTRCT_V1 +#endif + +#define AES_BLK_DISABLE_DSB_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_INSRT AES_BLK_DISABLE_DSB_INSRT_V1 +#endif + +/*! @} dsb (disable_dsb) */ + +/*! + * @addtogroup group570689 id_disabled + * @brief Range = 10:8 | Width = 3 | Access = read-only | Default = 0x0 + * @details The id_disabled field indicates which keys are disabled. If the + * GID0, GID1, or UID1 keys are selected for use when disabled, then the key + * used in the AES operation is zero and an error interrupt is generated. + * This field is only cleared on a chip reset. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DISABLE_ID_DISABLED_SHIFT_V1 (8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_DISABLED_SHIFT AES_BLK_DISABLE_ID_DISABLED_SHIFT_V1 +#endif + +#define AES_BLK_DISABLE_ID_DISABLED_WIDTH_V1 (3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_DISABLED_WIDTH AES_BLK_DISABLE_ID_DISABLED_WIDTH_V1 +#endif + +#define AES_BLK_DISABLE_ID_DISABLED_UMASK_V1 (0x700) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_DISABLED_UMASK AES_BLK_DISABLE_ID_DISABLED_UMASK_V1 +#endif + +#define AES_BLK_DISABLE_ID_DISABLED_SMASK_V1 (0x7) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_DISABLED_SMASK AES_BLK_DISABLE_ID_DISABLED_SMASK_V1 +#endif + +#define AES_BLK_DISABLE_ID_DISABLED_XTRCT_V1(r) ((((uint32_t)r) >> 8) & 0x7) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_DISABLED_XTRCT AES_BLK_DISABLE_ID_DISABLED_XTRCT_V1 +#endif + +#define AES_BLK_DISABLE_ID_DISABLED_INSRT_V1(f) ((((uint32_t)f) & 0x7) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_ID_DISABLED_INSRT AES_BLK_DISABLE_ID_DISABLED_INSRT_V1 +#endif + +/*! @} id_disabled */ + +/*! + * @addtogroup group570693 dsb_disabled + * @brief Range = 11 | Width = 1 | Access = read-only | Default = 0x0 + * @details When set, the dsb_disabled field indicates that the Fairplay key + * descrambler is disabled. If the Fairplay key descrambler is selected for + * use when disabled, then the scrambling operation is bypassed and an error + * interrupt is generated. This field is only cleared on a chip reset. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DISABLE_DSB_DISABLED_SHIFT_V1 (11) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_DISABLED_SHIFT AES_BLK_DISABLE_DSB_DISABLED_SHIFT_V1 +#endif + +#define AES_BLK_DISABLE_DSB_DISABLED_WIDTH_V1 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_DISABLED_WIDTH AES_BLK_DISABLE_DSB_DISABLED_WIDTH_V1 +#endif + +#define AES_BLK_DISABLE_DSB_DISABLED_UMASK_V1 (0x800) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_DISABLED_UMASK AES_BLK_DISABLE_DSB_DISABLED_UMASK_V1 +#endif + +#define AES_BLK_DISABLE_DSB_DISABLED_SMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_DISABLED_SMASK AES_BLK_DISABLE_DSB_DISABLED_SMASK_V1 +#endif + +#define AES_BLK_DISABLE_DSB_DISABLED_XTRCT_V1(r) ((((uint32_t)r) >> 11) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_DISABLED_XTRCT AES_BLK_DISABLE_DSB_DISABLED_XTRCT_V1 +#endif + +#define AES_BLK_DISABLE_DSB_DISABLED_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 11) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DISABLE_DSB_DISABLED_INSRT AES_BLK_DISABLE_DSB_DISABLED_INSRT_V1 +#endif + +/*! @} dsb_disabled */ + +/*! + * @addtogroup group570695 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_S5L8960X_A0 (0xf0f) +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_S5L8960X_B0 (0xf0f) +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_S5L8960X_B1 (0xf0f) +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_T7000_A0 (0xf0f) +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_T7000_B0 (0xf0f) +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_T7000_B1 (0xf0f) +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_T7001_A0 (0xf0f) +#define AES_BLK_DISABLE_TNBLE_RESET_UMASK_T7001_A1 (0xf0f) + +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_DISABLE_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} disable (AES_DISABLE) */ + +/*! + * @addtogroup group120226 txt_in_control (AES_TXT_IN_CONTROL) + * @brief Offset = 0x8 + * @details AES Cipher TXT_IN Control Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_IN_CONTROL_OFFSET_V1 (0x0 + 0x8) +#define AES_BLK_TXT_IN_CONTROL_OFFSET_V2 (0x0 + 0x8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_OFFSET AES_BLK_TXT_IN_CONTROL_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_OFFSET AES_BLK_TXT_IN_CONTROL_OFFSET_V2 +#endif + +/*! + * @addtogroup group120228 txt_in_key_ctx + * @brief Range = 1 | Width = 1 | Access = read-write | Default = 0x0 + * @details Select the key to use for the AES cipher operation. Software is + * responsible for ensuring that the keys are configured and ready for use + * through the AES_KEY_IN registers. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SHIFT_V1 (1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SHIFT_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SHIFT AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SHIFT AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SHIFT_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_WIDTH_V1 (1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_WIDTH AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_WIDTH AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_WIDTH_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_UMASK_V1 (0x2) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_UMASK_V2 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_UMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_UMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_UMASK_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SMASK_V1 (0x1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_SMASK_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_XTRCT_V1(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_XTRCT_V2(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_XTRCT AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_XTRCT AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_XTRCT_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_INSRT AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_INSRT AES_BLK_TXT_IN_CONTROL_TXT_IN_KEY_CTX_INSRT_V2 +#endif + +/*! @} txt_in_key_ctx */ + +/*! + * @addtogroup group120229 txt_in_iv_ctx + * @brief Range = 2 | Width = 1 | Access = read-write | Default = 0x0 + * @details Select the IV to use for the AES CBC cipher operation. Software + * is responsible for specifying the IV through the AES_IV_IN registers when + * starting a new operation. When continuing an AES CBC cipher operation from + * the previous block, hardware updates the IV. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SHIFT_V1 (2) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SHIFT_V2 (2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SHIFT AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SHIFT AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SHIFT_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_WIDTH_V1 (1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_WIDTH AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_WIDTH AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_WIDTH_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_UMASK_V1 (0x4) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_UMASK_V2 (0x4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_UMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_UMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_UMASK_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SMASK_V1 (0x1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_SMASK_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_XTRCT_V1(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_XTRCT_V2(r) ((((uint32_t)r) >> 2) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_XTRCT AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_XTRCT AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_XTRCT_V2 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_INSRT AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_INSRT AES_BLK_TXT_IN_CONTROL_TXT_IN_IV_CTX_INSRT_V2 +#endif + +/*! @} txt_in_iv_ctx */ + +/*! + * @addtogroup group120231 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_IN_CONTROL_TNBLE_RESET_UMASK_T7001_A1 (0x7) +#define AES_BLK_TXT_IN_CONTROL_TNBLE_RESET_UMASK_S7002_A1 (0x6) + +#define AES_BLK_TXT_IN_CONTROL_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_TXT_IN_CONTROL_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! + * @addtogroup group570697 txt_in_val + * @brief Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Set this field to start an AES cipher operation on the 16B block + * stored in the AES_TXT_IN0/1/2/3 registers. Before starting an AES cipher + * operation, software must check that the AES cipher engine is ready by + * checking the AES_TXT_IN_STATUS register. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_SHIFT AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_SHIFT_V1 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_WIDTH_V1 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_WIDTH AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_WIDTH_V1 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_UMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_UMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_UMASK_V1 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_SMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_SMASK AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_SMASK_V1 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_XTRCT AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_XTRCT_V1 +#endif + +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_INSRT AES_BLK_TXT_IN_CONTROL_TXT_IN_VAL_INSRT_V1 +#endif + +/*! @} txt_in_val */ + +/*! @} txt_in_control (AES_TXT_IN_CONTROL) */ + +/*! + * @addtogroup group120232 txt_in_status (AES_TXT_IN_STATUS) + * @brief Offset = 0xc + * @details AES Cipher TXT_IN Status register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_IN_STATUS_OFFSET_V1 (0x0 + 0xc) +#define AES_BLK_TXT_IN_STATUS_OFFSET_V2 (0x0 + 0xc) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_STATUS_OFFSET AES_BLK_TXT_IN_STATUS_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_STATUS_OFFSET AES_BLK_TXT_IN_STATUS_OFFSET_V2 +#endif + +/*! + * @addtogroup group120233 tx_fifo_space_available + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x1 + * @details There are at least 16 bytes of space in the Tx fifo which can be + * written into. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_SHIFT AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_SHIFT_V2 +#endif + +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_WIDTH AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_WIDTH_V2 +#endif + +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_UMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_UMASK AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_UMASK_V2 +#endif + +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_SMASK AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_SMASK_V2 +#endif + +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_XTRCT AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_XTRCT_V2 +#endif + +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_INSRT AES_BLK_TXT_IN_STATUS_TX_FIFO_SPACE_AVAILABLE_INSRT_V2 +#endif + +/*! @} tx_fifo_space_available */ + +/*! + * @addtogroup group120235 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_IN_STATUS_TNBLE_RESET_UMASK_T7001_A1 (0x1) +#define AES_BLK_TXT_IN_STATUS_TNBLE_RESET_UMASK_S7002_A1 (0x1) + +#define AES_BLK_TXT_IN_STATUS_TNBLE_RESET_VALUE_T7001_A1 (0x1) +#define AES_BLK_TXT_IN_STATUS_TNBLE_RESET_VALUE_S7002_A1 (0x1) + +/*! @} reset */ + +/*! + * @addtogroup group570703 txt_in_rdy + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x1 + * @details Check that the txt_in_rdy bit is set before writing to the + * AES_TXT_IN_CONTROL register to start an AES operation. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_SHIFT AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_SHIFT_V1 +#endif + +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_WIDTH_V1 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_WIDTH AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_WIDTH_V1 +#endif + +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_UMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_UMASK AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_UMASK_V1 +#endif + +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_SMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_SMASK AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_SMASK_V1 +#endif + +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_XTRCT AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_XTRCT_V1 +#endif + +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_INSRT AES_BLK_TXT_IN_STATUS_TXT_IN_RDY_INSRT_V1 +#endif + +/*! @} txt_in_rdy */ + +/*! @} txt_in_status (AES_TXT_IN_STATUS) */ + +/*! + * @addtogroup group570706 txt_in0 (AES_TXT_IN0) + * @brief Offset = 0x40 + * @details AES Cipher TXT_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_IN0_OFFSET_V1 (0x0 + 0x40) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN0_OFFSET AES_BLK_TXT_IN0_OFFSET_V1 +#endif + +/*! + * @addtogroup group570707 fld (txt_in0) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details txt_in[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN0_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN0_FLD_SHIFT AES_BLK_TXT_IN0_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_IN0_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN0_FLD_WIDTH AES_BLK_TXT_IN0_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_IN0_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN0_FLD_UMASK AES_BLK_TXT_IN0_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_IN0_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN0_FLD_SMASK AES_BLK_TXT_IN0_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_IN0_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN0_FLD_XTRCT AES_BLK_TXT_IN0_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_IN0_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN0_FLD_INSRT AES_BLK_TXT_IN0_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_in0) */ + +/*! + * @addtogroup group570708 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_IN0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_IN0_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_in0 (AES_TXT_IN0) */ + +/*! + * @addtogroup group570709 txt_in1 (AES_TXT_IN1) + * @brief Offset = 0x44 + * @details AES Cipher TXT_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_IN1_OFFSET_V1 (0x0 + 0x44) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN1_OFFSET AES_BLK_TXT_IN1_OFFSET_V1 +#endif + +/*! + * @addtogroup group570710 fld (txt_in1) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details txt_in[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN1_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN1_FLD_SHIFT AES_BLK_TXT_IN1_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_IN1_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN1_FLD_WIDTH AES_BLK_TXT_IN1_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_IN1_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN1_FLD_UMASK AES_BLK_TXT_IN1_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_IN1_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN1_FLD_SMASK AES_BLK_TXT_IN1_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_IN1_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN1_FLD_XTRCT AES_BLK_TXT_IN1_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_IN1_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN1_FLD_INSRT AES_BLK_TXT_IN1_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_in1) */ + +/*! + * @addtogroup group570711 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_IN1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_IN1_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_in1 (AES_TXT_IN1) */ + +/*! + * @addtogroup group570712 txt_in2 (AES_TXT_IN2) + * @brief Offset = 0x48 + * @details AES Cipher TXT_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_IN2_OFFSET_V1 (0x0 + 0x48) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN2_OFFSET AES_BLK_TXT_IN2_OFFSET_V1 +#endif + +/*! + * @addtogroup group570713 fld (txt_in2) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details txt_in[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN2_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN2_FLD_SHIFT AES_BLK_TXT_IN2_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_IN2_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN2_FLD_WIDTH AES_BLK_TXT_IN2_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_IN2_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN2_FLD_UMASK AES_BLK_TXT_IN2_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_IN2_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN2_FLD_SMASK AES_BLK_TXT_IN2_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_IN2_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN2_FLD_XTRCT AES_BLK_TXT_IN2_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_IN2_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN2_FLD_INSRT AES_BLK_TXT_IN2_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_in2) */ + +/*! + * @addtogroup group570714 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_IN2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_IN2_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_in2 (AES_TXT_IN2) */ + +/*! + * @addtogroup group570715 txt_in3 (AES_TXT_IN3) + * @brief Offset = 0x4c + * @details AES Cipher TXT_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_IN3_OFFSET_V1 (0x0 + 0x4c) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN3_OFFSET AES_BLK_TXT_IN3_OFFSET_V1 +#endif + +/*! + * @addtogroup group570716 fld (txt_in3) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details txt_in[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN3_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN3_FLD_SHIFT AES_BLK_TXT_IN3_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_IN3_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN3_FLD_WIDTH AES_BLK_TXT_IN3_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_IN3_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN3_FLD_UMASK AES_BLK_TXT_IN3_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_IN3_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN3_FLD_SMASK AES_BLK_TXT_IN3_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_IN3_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN3_FLD_XTRCT AES_BLK_TXT_IN3_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_IN3_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_IN3_FLD_INSRT AES_BLK_TXT_IN3_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_in3) */ + +/*! + * @addtogroup group570717 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_IN3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_IN3_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_in3 (AES_TXT_IN3) */ + +/*! + * @addtogroup group120239 txt_out_status (AES_TXT_OUT_STATUS) + * @brief Offset = 0x50 + * @details AES Cipher TXT_OUT Status Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_OUT_STATUS_OFFSET_V1 (0x0 + 0x50) +#define AES_BLK_TXT_OUT_STATUS_OFFSET_V2 (0x0 + 0x50) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_OFFSET AES_BLK_TXT_OUT_STATUS_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_OFFSET AES_BLK_TXT_OUT_STATUS_OFFSET_V2 +#endif + +/*! + * @addtogroup group120240 rx_fifo_data_available + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x0 + * @details There are at least 16 bytes in the Rx fifo available for reading. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_SHIFT AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_SHIFT_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_WIDTH AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_WIDTH_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_UMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_UMASK AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_UMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_SMASK AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_SMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_XTRCT AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_XTRCT_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_INSRT AES_BLK_TXT_OUT_STATUS_RX_FIFO_DATA_AVAILABLE_INSRT_V2 +#endif + +/*! @} rx_fifo_data_available */ + +/*! + * @addtogroup group120241 txt_out_key_ctx + * @brief Range = 1 | Width = 1 | Access = read-only | Default = 0x0 + * @details Identifies which key was used for the AES cipher operation. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SHIFT_V1 (1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SHIFT_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SHIFT AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SHIFT AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SHIFT_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_WIDTH_V1 (1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_WIDTH AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_WIDTH AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_WIDTH_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_UMASK_V1 (0x2) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_UMASK_V2 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_UMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_UMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_UMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SMASK_V1 (0x1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_SMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_XTRCT_V1(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_XTRCT_V2(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_XTRCT AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_XTRCT AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_XTRCT_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_INSRT AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_INSRT AES_BLK_TXT_OUT_STATUS_TXT_OUT_KEY_CTX_INSRT_V2 +#endif + +/*! @} txt_out_key_ctx */ + +/*! + * @addtogroup group120242 txt_out_iv_ctx + * @brief Range = 2 | Width = 1 | Access = read-only | Default = 0x0 + * @details Identifies which IV was used for the AES cipher operation. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SHIFT_V1 (2) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SHIFT_V2 (2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SHIFT AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SHIFT AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SHIFT_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_WIDTH_V1 (1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_WIDTH AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_WIDTH AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_WIDTH_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_UMASK_V1 (0x4) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_UMASK_V2 (0x4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_UMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_UMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_UMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SMASK_V1 (0x1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_SMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_XTRCT_V1(r) ((((uint32_t)r) >> 2) & 0x1) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_XTRCT_V2(r) ((((uint32_t)r) >> 2) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_XTRCT AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_XTRCT AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_XTRCT_V2 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 2) +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_INSRT AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_INSRT AES_BLK_TXT_OUT_STATUS_TXT_OUT_IV_CTX_INSRT_V2 +#endif + +/*! @} txt_out_iv_ctx */ + +/*! + * @addtogroup group120244 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_OUT_STATUS_TNBLE_RESET_UMASK_T7001_A1 (0x7) +#define AES_BLK_TXT_OUT_STATUS_TNBLE_RESET_UMASK_S7002_A1 (0x7) + +#define AES_BLK_TXT_OUT_STATUS_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_TXT_OUT_STATUS_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! + * @addtogroup group570719 txt_out_val + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x0 + * @details When set, AES Cipher data may be read from the TXT_OUT and IV_OUT + * registers. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_SHIFT AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_SHIFT_V1 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_WIDTH_V1 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_WIDTH AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_WIDTH_V1 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_UMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_UMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_UMASK_V1 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_SMASK_V1 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_SMASK AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_SMASK_V1 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_XTRCT AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_XTRCT_V1 +#endif + +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_INSRT AES_BLK_TXT_OUT_STATUS_TXT_OUT_VAL_INSRT_V1 +#endif + +/*! @} txt_out_val */ + +/*! @} txt_out_status (AES_TXT_OUT_STATUS) */ + +/*! + * @addtogroup group570724 txt_out0 (AES_TXT_OUT0) + * @brief Offset = 0x80 + * @details AES Cipher TXT_OUT[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_OUT0_OFFSET_V1 (0x0 + 0x80) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT0_OFFSET AES_BLK_TXT_OUT0_OFFSET_V1 +#endif + +/*! + * @addtogroup group570725 fld (txt_out0) + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details txt_out[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT0_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT0_FLD_SHIFT AES_BLK_TXT_OUT0_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_OUT0_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT0_FLD_WIDTH AES_BLK_TXT_OUT0_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_OUT0_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT0_FLD_UMASK AES_BLK_TXT_OUT0_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_OUT0_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT0_FLD_SMASK AES_BLK_TXT_OUT0_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_OUT0_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT0_FLD_XTRCT AES_BLK_TXT_OUT0_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_OUT0_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT0_FLD_INSRT AES_BLK_TXT_OUT0_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_out0) */ + +/*! + * @addtogroup group570726 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_OUT0_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_out0 (AES_TXT_OUT0) */ + +/*! + * @addtogroup group570727 txt_out1 (AES_TXT_OUT1) + * @brief Offset = 0x84 + * @details AES Cipher TXT_OUT[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_OUT1_OFFSET_V1 (0x0 + 0x84) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT1_OFFSET AES_BLK_TXT_OUT1_OFFSET_V1 +#endif + +/*! + * @addtogroup group570728 fld (txt_out1) + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details txt_out[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT1_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT1_FLD_SHIFT AES_BLK_TXT_OUT1_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_OUT1_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT1_FLD_WIDTH AES_BLK_TXT_OUT1_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_OUT1_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT1_FLD_UMASK AES_BLK_TXT_OUT1_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_OUT1_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT1_FLD_SMASK AES_BLK_TXT_OUT1_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_OUT1_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT1_FLD_XTRCT AES_BLK_TXT_OUT1_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_OUT1_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT1_FLD_INSRT AES_BLK_TXT_OUT1_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_out1) */ + +/*! + * @addtogroup group570729 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_OUT1_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_out1 (AES_TXT_OUT1) */ + +/*! + * @addtogroup group570730 txt_out2 (AES_TXT_OUT2) + * @brief Offset = 0x88 + * @details AES Cipher TXT_OUT[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_OUT2_OFFSET_V1 (0x0 + 0x88) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT2_OFFSET AES_BLK_TXT_OUT2_OFFSET_V1 +#endif + +/*! + * @addtogroup group570731 fld (txt_out2) + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details txt_out[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT2_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT2_FLD_SHIFT AES_BLK_TXT_OUT2_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_OUT2_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT2_FLD_WIDTH AES_BLK_TXT_OUT2_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_OUT2_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT2_FLD_UMASK AES_BLK_TXT_OUT2_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_OUT2_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT2_FLD_SMASK AES_BLK_TXT_OUT2_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_OUT2_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT2_FLD_XTRCT AES_BLK_TXT_OUT2_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_OUT2_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT2_FLD_INSRT AES_BLK_TXT_OUT2_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_out2) */ + +/*! + * @addtogroup group570732 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_OUT2_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_out2 (AES_TXT_OUT2) */ + +/*! + * @addtogroup group570733 txt_out3 (AES_TXT_OUT3) + * @brief Offset = 0x8c + * @details AES Cipher TXT_OUT[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_OUT3_OFFSET_V1 (0x0 + 0x8c) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT3_OFFSET AES_BLK_TXT_OUT3_OFFSET_V1 +#endif + +/*! + * @addtogroup group570734 fld (txt_out3) + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details txt_out[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT3_FLD_SHIFT_V1 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT3_FLD_SHIFT AES_BLK_TXT_OUT3_FLD_SHIFT_V1 +#endif + +#define AES_BLK_TXT_OUT3_FLD_WIDTH_V1 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT3_FLD_WIDTH AES_BLK_TXT_OUT3_FLD_WIDTH_V1 +#endif + +#define AES_BLK_TXT_OUT3_FLD_UMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT3_FLD_UMASK AES_BLK_TXT_OUT3_FLD_UMASK_V1 +#endif + +#define AES_BLK_TXT_OUT3_FLD_SMASK_V1 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT3_FLD_SMASK AES_BLK_TXT_OUT3_FLD_SMASK_V1 +#endif + +#define AES_BLK_TXT_OUT3_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT3_FLD_XTRCT AES_BLK_TXT_OUT3_FLD_XTRCT_V1 +#endif + +#define AES_BLK_TXT_OUT3_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_TXT_OUT3_FLD_INSRT AES_BLK_TXT_OUT3_FLD_INSRT_V1 +#endif + +/*! @} fld (txt_out3) */ + +/*! + * @addtogroup group570735 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_S5L8960X_A0 (0xffffffff) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_S5L8960X_B0 (0xffffffff) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_S5L8960X_B1 (0xffffffff) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_T7000_A0 (0xffffffff) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_T7000_B0 (0xffffffff) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_T7000_B1 (0xffffffff) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_T7001_A0 (0xffffffff) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) + +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_S5L8960X_A0 (0x0) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_S5L8960X_B0 (0x0) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_S5L8960X_B1 (0x0) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_T7000_A0 (0x0) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_T7000_B0 (0x0) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_T7000_B1 (0x0) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_T7001_A0 (0x0) +#define AES_BLK_TXT_OUT3_TNBLE_RESET_VALUE_T7001_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_out3 (AES_TXT_OUT3) */ + +/*! + * @addtogroup group120248 key_in_control (AES_KEY_IN_CONTROL) + * @brief Offset = 0x90 + * @details AES KEY_IN Control Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_OFFSET_V1 (0x0 + 0x90) +#define AES_BLK_KEY_IN_CONTROL_OFFSET_V2 (0x0 + 0x90) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_OFFSET AES_BLK_KEY_IN_CONTROL_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_OFFSET AES_BLK_KEY_IN_CONTROL_OFFSET_V2 +#endif + +/*! + * @addtogroup group120249 key_in_val + * @brief Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Set this field to start an AES key configurator operation. Before + * starting an AES key configurator operation, software must check that the + * AES key configurator engine is ready by checking the AES_KEY_IN_STATUS + * register. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SHIFT_V1 (0) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_WIDTH_V1 (1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_UMASK_V1 (0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_UMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SMASK_V1 (0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_VAL_INSRT_V2 +#endif + +/*! @} key_in_val */ + +/*! + * @addtogroup group120250 key_in_ctx + * @brief Range = 1 | Width = 1 | Access = read-write | Default = 0x0 + * @details Selects the key context that will be updated with the results of + * the AES key configurator operation. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SHIFT_V1 (1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SHIFT_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_WIDTH_V1 (1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_UMASK_V1 (0x2) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_UMASK_V2 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SMASK_V1 (0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_XTRCT_V1(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_XTRCT_V2(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_CTX_INSRT_V2 +#endif + +/*! @} key_in_ctx */ + +/*! + * @addtogroup group120252 key_in_sel + * @brief Range = 5:4 | Width = 2 | Access = read-write | Default = 0x0 + * @details Selects which key to use as an input to the AES key configurator. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SHIFT_V1 (4) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SHIFT_V2 (4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_WIDTH_V1 (2) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_WIDTH_V2 (2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_UMASK_V1 (0x30) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_UMASK_V2 (0x30) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SMASK_V1 (0x3) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SMASK_V2 (0x3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_XTRCT_V1(r) ((((uint32_t)r) >> 4) & 0x3) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_XTRCT_V2(r) ((((uint32_t)r) >> 4) & 0x3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_INSRT_V1(f) ((((uint32_t)f) & 0x3) << 4) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_INSRT_V2(f) ((((uint32_t)f) & 0x3) << 4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_SEL_INSRT_V2 +#endif + +/*! @} key_in_sel */ + +/*! + * @addtogroup group120257 key_in_len + * @brief Range = 7:6 | Width = 2 | Access = read-write | Default = 0x0 + * @details Key context length + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SHIFT_V1 (6) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SHIFT_V2 (6) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_WIDTH_V1 (2) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_WIDTH_V2 (2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_UMASK_V1 (0xc0) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_UMASK_V2 (0xc0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SMASK_V1 (0x3) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SMASK_V2 (0x3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_XTRCT_V1(r) ((((uint32_t)r) >> 6) & 0x3) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_XTRCT_V2(r) ((((uint32_t)r) >> 6) & 0x3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_INSRT_V1(f) ((((uint32_t)f) & 0x3) << 6) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_INSRT_V2(f) ((((uint32_t)f) & 0x3) << 6) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_LEN_INSRT_V2 +#endif + +/*! @} key_in_len */ + +/*! + * @addtogroup group120261 key_in_fun + * @brief Range = 10:8 | Width = 3 | Access = read-write | Default = 0x0 + * @details Key function + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SHIFT_V1 (8) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SHIFT_V2 (8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_WIDTH_V1 (3) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_WIDTH_V2 (3) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_UMASK_V1 (0x700) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_UMASK_V2 (0x700) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SMASK_V1 (0x7) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SMASK_V2 (0x7) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_XTRCT_V1(r) ((((uint32_t)r) >> 8) & 0x7) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_XTRCT_V2(r) ((((uint32_t)r) >> 8) & 0x7) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_INSRT_V1(f) ((((uint32_t)f) & 0x7) << 8) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_INSRT_V2(f) ((((uint32_t)f) & 0x7) << 8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_FUN_INSRT_V2 +#endif + +/*! @} key_in_fun */ + +/*! + * @addtogroup group120266 key_in_enc + * @brief Range = 12 | Width = 1 | Access = read-write | Default = 0x0 + * @details When set, the key will be used for encryption. When cleared, the + * key will be used for decryption. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SHIFT_V1 (12) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SHIFT_V2 (12) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_WIDTH_V1 (1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_UMASK_V1 (0x1000) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_UMASK_V2 (0x1000) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SMASK_V1 (0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_XTRCT_V1(r) ((((uint32_t)r) >> 12) & 0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_XTRCT_V2(r) ((((uint32_t)r) >> 12) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 12) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 12) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_ENC_INSRT_V2 +#endif + +/*! @} key_in_enc */ + +/*! + * @addtogroup group120267 key_in_mod + * @brief Range = 13 | Width = 1 | Access = read-write | Default = 0x0 + * @details Block Cipher Mode: When set, the AES cipher is configured to + * support CBC mode. When cleared, the AES Cipher supports ECB mode. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SHIFT_V1 (13) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SHIFT_V2 (13) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SHIFT AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_WIDTH_V1 (1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_WIDTH AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_UMASK_V1 (0x2000) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_UMASK_V2 (0x2000) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_UMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SMASK_V1 (0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SMASK AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_XTRCT_V1(r) ((((uint32_t)r) >> 13) & 0x1) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_XTRCT_V2(r) ((((uint32_t)r) >> 13) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_XTRCT AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 13) +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 13) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_INSRT AES_BLK_KEY_IN_CONTROL_KEY_IN_MOD_INSRT_V2 +#endif + +/*! @} key_in_mod */ + +/*! + * @addtogroup group120269 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN_CONTROL_TNBLE_RESET_UMASK_T7001_A1 (0x37f3) +#define AES_BLK_KEY_IN_CONTROL_TNBLE_RESET_UMASK_S7002_A1 (0x37f3) + +#define AES_BLK_KEY_IN_CONTROL_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN_CONTROL_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in_control (AES_KEY_IN_CONTROL) */ + +/*! + * @addtogroup group120270 key_in_status (AES_KEY_IN_STATUS) + * @brief Offset = 0x94 + * @details AES KEY_IN Status Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN_STATUS_OFFSET_V1 (0x0 + 0x94) +#define AES_BLK_KEY_IN_STATUS_OFFSET_V2 (0x0 + 0x94) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_STATUS_OFFSET AES_BLK_KEY_IN_STATUS_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_STATUS_OFFSET AES_BLK_KEY_IN_STATUS_OFFSET_V2 +#endif + +/*! + * @addtogroup group120271 key_in_rdy + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x1 + * @details When set, the AES Key configurator operation is complete and the + * key may be used by the AES Cipher engine. After starting a key + * configurator operation, software checks this register to determine that the + * key context is ready for use. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SHIFT_V1 (0) +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SHIFT AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SHIFT AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_WIDTH_V1 (1) +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_WIDTH AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_WIDTH AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_UMASK_V1 (0x1) +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_UMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_UMASK AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_UMASK AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SMASK_V1 (0x1) +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SMASK AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SMASK AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_XTRCT AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_XTRCT AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_INSRT AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_INSRT AES_BLK_KEY_IN_STATUS_KEY_IN_RDY_INSRT_V2 +#endif + +/*! @} key_in_rdy */ + +/*! + * @addtogroup group120273 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN_STATUS_TNBLE_RESET_UMASK_T7001_A1 (0x1) +#define AES_BLK_KEY_IN_STATUS_TNBLE_RESET_UMASK_S7002_A1 (0x1) + +#define AES_BLK_KEY_IN_STATUS_TNBLE_RESET_VALUE_T7001_A1 (0x1) +#define AES_BLK_KEY_IN_STATUS_TNBLE_RESET_VALUE_S7002_A1 (0x1) + +/*! @} reset */ + +/*! @} key_in_status (AES_KEY_IN_STATUS) */ + +/*! + * @addtogroup group120274 key_in0 (AES_KEY_IN0) + * @brief Offset = 0xc0 + * @details AES KEY_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN0_OFFSET_V1 (0x0 + 0xc0) +#define AES_BLK_KEY_IN0_OFFSET_V2 (0x0 + 0xc0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN0_OFFSET AES_BLK_KEY_IN0_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN0_OFFSET AES_BLK_KEY_IN0_OFFSET_V2 +#endif + +/*! + * @addtogroup group120275 fld (key_in0) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN0_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN0_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN0_FLD_SHIFT AES_BLK_KEY_IN0_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN0_FLD_SHIFT AES_BLK_KEY_IN0_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN0_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN0_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN0_FLD_WIDTH AES_BLK_KEY_IN0_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN0_FLD_WIDTH AES_BLK_KEY_IN0_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN0_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN0_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN0_FLD_UMASK AES_BLK_KEY_IN0_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN0_FLD_UMASK AES_BLK_KEY_IN0_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN0_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN0_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN0_FLD_SMASK AES_BLK_KEY_IN0_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN0_FLD_SMASK AES_BLK_KEY_IN0_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN0_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN0_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN0_FLD_XTRCT AES_BLK_KEY_IN0_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN0_FLD_XTRCT AES_BLK_KEY_IN0_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN0_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN0_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN0_FLD_INSRT AES_BLK_KEY_IN0_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN0_FLD_INSRT AES_BLK_KEY_IN0_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in0) */ + +/*! + * @addtogroup group120276 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN0_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN0_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN0_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in0 (AES_KEY_IN0) */ + +/*! + * @addtogroup group120277 key_in1 (AES_KEY_IN1) + * @brief Offset = 0xc4 + * @details AES KEY_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN1_OFFSET_V1 (0x0 + 0xc4) +#define AES_BLK_KEY_IN1_OFFSET_V2 (0x0 + 0xc4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN1_OFFSET AES_BLK_KEY_IN1_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN1_OFFSET AES_BLK_KEY_IN1_OFFSET_V2 +#endif + +/*! + * @addtogroup group120278 fld (key_in1) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN1_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN1_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN1_FLD_SHIFT AES_BLK_KEY_IN1_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN1_FLD_SHIFT AES_BLK_KEY_IN1_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN1_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN1_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN1_FLD_WIDTH AES_BLK_KEY_IN1_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN1_FLD_WIDTH AES_BLK_KEY_IN1_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN1_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN1_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN1_FLD_UMASK AES_BLK_KEY_IN1_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN1_FLD_UMASK AES_BLK_KEY_IN1_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN1_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN1_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN1_FLD_SMASK AES_BLK_KEY_IN1_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN1_FLD_SMASK AES_BLK_KEY_IN1_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN1_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN1_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN1_FLD_XTRCT AES_BLK_KEY_IN1_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN1_FLD_XTRCT AES_BLK_KEY_IN1_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN1_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN1_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN1_FLD_INSRT AES_BLK_KEY_IN1_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN1_FLD_INSRT AES_BLK_KEY_IN1_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in1) */ + +/*! + * @addtogroup group120279 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN1_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN1_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN1_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in1 (AES_KEY_IN1) */ + +/*! + * @addtogroup group120280 key_in2 (AES_KEY_IN2) + * @brief Offset = 0xc8 + * @details AES KEY_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN2_OFFSET_V1 (0x0 + 0xc8) +#define AES_BLK_KEY_IN2_OFFSET_V2 (0x0 + 0xc8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN2_OFFSET AES_BLK_KEY_IN2_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN2_OFFSET AES_BLK_KEY_IN2_OFFSET_V2 +#endif + +/*! + * @addtogroup group120281 fld (key_in2) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN2_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN2_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN2_FLD_SHIFT AES_BLK_KEY_IN2_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN2_FLD_SHIFT AES_BLK_KEY_IN2_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN2_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN2_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN2_FLD_WIDTH AES_BLK_KEY_IN2_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN2_FLD_WIDTH AES_BLK_KEY_IN2_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN2_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN2_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN2_FLD_UMASK AES_BLK_KEY_IN2_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN2_FLD_UMASK AES_BLK_KEY_IN2_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN2_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN2_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN2_FLD_SMASK AES_BLK_KEY_IN2_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN2_FLD_SMASK AES_BLK_KEY_IN2_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN2_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN2_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN2_FLD_XTRCT AES_BLK_KEY_IN2_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN2_FLD_XTRCT AES_BLK_KEY_IN2_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN2_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN2_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN2_FLD_INSRT AES_BLK_KEY_IN2_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN2_FLD_INSRT AES_BLK_KEY_IN2_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in2) */ + +/*! + * @addtogroup group120282 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN2_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN2_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN2_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in2 (AES_KEY_IN2) */ + +/*! + * @addtogroup group120283 key_in3 (AES_KEY_IN3) + * @brief Offset = 0xcc + * @details AES KEY_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN3_OFFSET_V1 (0x0 + 0xcc) +#define AES_BLK_KEY_IN3_OFFSET_V2 (0x0 + 0xcc) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN3_OFFSET AES_BLK_KEY_IN3_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN3_OFFSET AES_BLK_KEY_IN3_OFFSET_V2 +#endif + +/*! + * @addtogroup group120284 fld (key_in3) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN3_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN3_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN3_FLD_SHIFT AES_BLK_KEY_IN3_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN3_FLD_SHIFT AES_BLK_KEY_IN3_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN3_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN3_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN3_FLD_WIDTH AES_BLK_KEY_IN3_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN3_FLD_WIDTH AES_BLK_KEY_IN3_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN3_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN3_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN3_FLD_UMASK AES_BLK_KEY_IN3_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN3_FLD_UMASK AES_BLK_KEY_IN3_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN3_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN3_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN3_FLD_SMASK AES_BLK_KEY_IN3_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN3_FLD_SMASK AES_BLK_KEY_IN3_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN3_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN3_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN3_FLD_XTRCT AES_BLK_KEY_IN3_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN3_FLD_XTRCT AES_BLK_KEY_IN3_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN3_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN3_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN3_FLD_INSRT AES_BLK_KEY_IN3_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN3_FLD_INSRT AES_BLK_KEY_IN3_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in3) */ + +/*! + * @addtogroup group120285 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN3_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN3_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN3_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in3 (AES_KEY_IN3) */ + +/*! + * @addtogroup group120286 key_in4 (AES_KEY_IN4) + * @brief Offset = 0xd0 + * @details AES KEY_IN[159:128] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN4_OFFSET_V1 (0x0 + 0xd0) +#define AES_BLK_KEY_IN4_OFFSET_V2 (0x0 + 0xd0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN4_OFFSET AES_BLK_KEY_IN4_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN4_OFFSET AES_BLK_KEY_IN4_OFFSET_V2 +#endif + +/*! + * @addtogroup group120287 fld (key_in4) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[159:128] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN4_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN4_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN4_FLD_SHIFT AES_BLK_KEY_IN4_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN4_FLD_SHIFT AES_BLK_KEY_IN4_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN4_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN4_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN4_FLD_WIDTH AES_BLK_KEY_IN4_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN4_FLD_WIDTH AES_BLK_KEY_IN4_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN4_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN4_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN4_FLD_UMASK AES_BLK_KEY_IN4_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN4_FLD_UMASK AES_BLK_KEY_IN4_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN4_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN4_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN4_FLD_SMASK AES_BLK_KEY_IN4_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN4_FLD_SMASK AES_BLK_KEY_IN4_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN4_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN4_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN4_FLD_XTRCT AES_BLK_KEY_IN4_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN4_FLD_XTRCT AES_BLK_KEY_IN4_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN4_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN4_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN4_FLD_INSRT AES_BLK_KEY_IN4_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN4_FLD_INSRT AES_BLK_KEY_IN4_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in4) */ + +/*! + * @addtogroup group120288 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN4_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN4_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN4_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN4_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in4 (AES_KEY_IN4) */ + +/*! + * @addtogroup group120289 key_in5 (AES_KEY_IN5) + * @brief Offset = 0xd4 + * @details AES KEY_IN[191:160] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN5_OFFSET_V1 (0x0 + 0xd4) +#define AES_BLK_KEY_IN5_OFFSET_V2 (0x0 + 0xd4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN5_OFFSET AES_BLK_KEY_IN5_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN5_OFFSET AES_BLK_KEY_IN5_OFFSET_V2 +#endif + +/*! + * @addtogroup group120290 fld (key_in5) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[191:160] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN5_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN5_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN5_FLD_SHIFT AES_BLK_KEY_IN5_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN5_FLD_SHIFT AES_BLK_KEY_IN5_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN5_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN5_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN5_FLD_WIDTH AES_BLK_KEY_IN5_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN5_FLD_WIDTH AES_BLK_KEY_IN5_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN5_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN5_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN5_FLD_UMASK AES_BLK_KEY_IN5_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN5_FLD_UMASK AES_BLK_KEY_IN5_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN5_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN5_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN5_FLD_SMASK AES_BLK_KEY_IN5_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN5_FLD_SMASK AES_BLK_KEY_IN5_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN5_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN5_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN5_FLD_XTRCT AES_BLK_KEY_IN5_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN5_FLD_XTRCT AES_BLK_KEY_IN5_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN5_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN5_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN5_FLD_INSRT AES_BLK_KEY_IN5_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN5_FLD_INSRT AES_BLK_KEY_IN5_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in5) */ + +/*! + * @addtogroup group120291 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN5_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN5_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN5_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN5_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in5 (AES_KEY_IN5) */ + +/*! + * @addtogroup group120292 key_in6 (AES_KEY_IN6) + * @brief Offset = 0xd8 + * @details AES KEY_IN[223:192] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN6_OFFSET_V1 (0x0 + 0xd8) +#define AES_BLK_KEY_IN6_OFFSET_V2 (0x0 + 0xd8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN6_OFFSET AES_BLK_KEY_IN6_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN6_OFFSET AES_BLK_KEY_IN6_OFFSET_V2 +#endif + +/*! + * @addtogroup group120293 fld (key_in6) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[223:192] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN6_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN6_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN6_FLD_SHIFT AES_BLK_KEY_IN6_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN6_FLD_SHIFT AES_BLK_KEY_IN6_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN6_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN6_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN6_FLD_WIDTH AES_BLK_KEY_IN6_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN6_FLD_WIDTH AES_BLK_KEY_IN6_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN6_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN6_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN6_FLD_UMASK AES_BLK_KEY_IN6_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN6_FLD_UMASK AES_BLK_KEY_IN6_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN6_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN6_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN6_FLD_SMASK AES_BLK_KEY_IN6_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN6_FLD_SMASK AES_BLK_KEY_IN6_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN6_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN6_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN6_FLD_XTRCT AES_BLK_KEY_IN6_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN6_FLD_XTRCT AES_BLK_KEY_IN6_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN6_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN6_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN6_FLD_INSRT AES_BLK_KEY_IN6_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN6_FLD_INSRT AES_BLK_KEY_IN6_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in6) */ + +/*! + * @addtogroup group120294 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN6_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN6_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN6_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN6_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in6 (AES_KEY_IN6) */ + +/*! + * @addtogroup group120295 key_in7 (AES_KEY_IN7) + * @brief Offset = 0xdc + * @details AES KEY_IN[255:224] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_KEY_IN7_OFFSET_V1 (0x0 + 0xdc) +#define AES_BLK_KEY_IN7_OFFSET_V2 (0x0 + 0xdc) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN7_OFFSET AES_BLK_KEY_IN7_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN7_OFFSET AES_BLK_KEY_IN7_OFFSET_V2 +#endif + +/*! + * @addtogroup group120296 fld (key_in7) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details key_in[255:224] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_KEY_IN7_FLD_SHIFT_V1 (0) +#define AES_BLK_KEY_IN7_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN7_FLD_SHIFT AES_BLK_KEY_IN7_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN7_FLD_SHIFT AES_BLK_KEY_IN7_FLD_SHIFT_V2 +#endif + +#define AES_BLK_KEY_IN7_FLD_WIDTH_V1 (32) +#define AES_BLK_KEY_IN7_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN7_FLD_WIDTH AES_BLK_KEY_IN7_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN7_FLD_WIDTH AES_BLK_KEY_IN7_FLD_WIDTH_V2 +#endif + +#define AES_BLK_KEY_IN7_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN7_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN7_FLD_UMASK AES_BLK_KEY_IN7_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN7_FLD_UMASK AES_BLK_KEY_IN7_FLD_UMASK_V2 +#endif + +#define AES_BLK_KEY_IN7_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_KEY_IN7_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN7_FLD_SMASK AES_BLK_KEY_IN7_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN7_FLD_SMASK AES_BLK_KEY_IN7_FLD_SMASK_V2 +#endif + +#define AES_BLK_KEY_IN7_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_KEY_IN7_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN7_FLD_XTRCT AES_BLK_KEY_IN7_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN7_FLD_XTRCT AES_BLK_KEY_IN7_FLD_XTRCT_V2 +#endif + +#define AES_BLK_KEY_IN7_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_KEY_IN7_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_KEY_IN7_FLD_INSRT AES_BLK_KEY_IN7_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_KEY_IN7_FLD_INSRT AES_BLK_KEY_IN7_FLD_INSRT_V2 +#endif + +/*! @} fld (key_in7) */ + +/*! + * @addtogroup group120297 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_KEY_IN7_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_KEY_IN7_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_KEY_IN7_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_KEY_IN7_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} key_in7 (AES_KEY_IN7) */ + +/*! + * @addtogroup group120298 iv_in_control (AES_IV_IN_CONTROL) + * @brief Offset = 0xe0 + * @details AES IV_IN Control Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV_IN_CONTROL_OFFSET_V1 (0x0 + 0xe0) +#define AES_BLK_IV_IN_CONTROL_OFFSET_V2 (0x0 + 0xe0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_OFFSET AES_BLK_IV_IN_CONTROL_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_OFFSET AES_BLK_IV_IN_CONTROL_OFFSET_V2 +#endif + +/*! + * @addtogroup group120299 iv_in_val + * @brief Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 + * @details Set this field to load the IV stored in the AES_IV_IN registers to + * the IV context specified by the iv_in_ctx field. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SHIFT_V1 (0) +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SHIFT AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SHIFT AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SHIFT_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_WIDTH_V1 (1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_WIDTH AES_BLK_IV_IN_CONTROL_IV_IN_VAL_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_WIDTH AES_BLK_IV_IN_CONTROL_IV_IN_VAL_WIDTH_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_UMASK_V1 (0x1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_UMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_UMASK AES_BLK_IV_IN_CONTROL_IV_IN_VAL_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_UMASK AES_BLK_IV_IN_CONTROL_IV_IN_VAL_UMASK_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SMASK_V1 (0x1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SMASK AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SMASK AES_BLK_IV_IN_CONTROL_IV_IN_VAL_SMASK_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_XTRCT AES_BLK_IV_IN_CONTROL_IV_IN_VAL_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_XTRCT AES_BLK_IV_IN_CONTROL_IV_IN_VAL_XTRCT_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_INSRT AES_BLK_IV_IN_CONTROL_IV_IN_VAL_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_VAL_INSRT AES_BLK_IV_IN_CONTROL_IV_IN_VAL_INSRT_V2 +#endif + +/*! @} iv_in_val */ + +/*! + * @addtogroup group120300 iv_in_ctx + * @brief Range = 1 | Width = 1 | Access = read-write | Default = 0x0 + * @details Selects which IV context is updated + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SHIFT_V1 (1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SHIFT_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SHIFT AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SHIFT AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SHIFT_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_WIDTH_V1 (1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_WIDTH AES_BLK_IV_IN_CONTROL_IV_IN_CTX_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_WIDTH AES_BLK_IV_IN_CONTROL_IV_IN_CTX_WIDTH_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_UMASK_V1 (0x2) +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_UMASK_V2 (0x2) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_UMASK AES_BLK_IV_IN_CONTROL_IV_IN_CTX_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_UMASK AES_BLK_IV_IN_CONTROL_IV_IN_CTX_UMASK_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SMASK_V1 (0x1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SMASK AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SMASK AES_BLK_IV_IN_CONTROL_IV_IN_CTX_SMASK_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_XTRCT_V1(r) ((((uint32_t)r) >> 1) & 0x1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_XTRCT_V2(r) ((((uint32_t)r) >> 1) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_XTRCT AES_BLK_IV_IN_CONTROL_IV_IN_CTX_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_XTRCT AES_BLK_IV_IN_CONTROL_IV_IN_CTX_XTRCT_V2 +#endif + +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 1) +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_INSRT AES_BLK_IV_IN_CONTROL_IV_IN_CTX_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN_CONTROL_IV_IN_CTX_INSRT AES_BLK_IV_IN_CONTROL_IV_IN_CTX_INSRT_V2 +#endif + +/*! @} iv_in_ctx */ + +/*! + * @addtogroup group120302 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV_IN_CONTROL_TNBLE_RESET_UMASK_T7001_A1 (0x3) +#define AES_BLK_IV_IN_CONTROL_TNBLE_RESET_UMASK_S7002_A1 (0x3) + +#define AES_BLK_IV_IN_CONTROL_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV_IN_CONTROL_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv_in_control (AES_IV_IN_CONTROL) */ + +/*! + * @addtogroup group120303 iv_in0 (AES_IV_IN0) + * @brief Offset = 0x100 + * @details AES IV_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV_IN0_OFFSET_V1 (0x0 + 0x100) +#define AES_BLK_IV_IN0_OFFSET_V2 (0x0 + 0x100) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN0_OFFSET AES_BLK_IV_IN0_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN0_OFFSET AES_BLK_IV_IN0_OFFSET_V2 +#endif + +/*! + * @addtogroup group120304 fld (iv_in0) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details iv_in[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV_IN0_FLD_SHIFT_V1 (0) +#define AES_BLK_IV_IN0_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN0_FLD_SHIFT AES_BLK_IV_IN0_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN0_FLD_SHIFT AES_BLK_IV_IN0_FLD_SHIFT_V2 +#endif + +#define AES_BLK_IV_IN0_FLD_WIDTH_V1 (32) +#define AES_BLK_IV_IN0_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN0_FLD_WIDTH AES_BLK_IV_IN0_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN0_FLD_WIDTH AES_BLK_IV_IN0_FLD_WIDTH_V2 +#endif + +#define AES_BLK_IV_IN0_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN0_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN0_FLD_UMASK AES_BLK_IV_IN0_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN0_FLD_UMASK AES_BLK_IV_IN0_FLD_UMASK_V2 +#endif + +#define AES_BLK_IV_IN0_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN0_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN0_FLD_SMASK AES_BLK_IV_IN0_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN0_FLD_SMASK AES_BLK_IV_IN0_FLD_SMASK_V2 +#endif + +#define AES_BLK_IV_IN0_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV_IN0_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN0_FLD_XTRCT AES_BLK_IV_IN0_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN0_FLD_XTRCT AES_BLK_IV_IN0_FLD_XTRCT_V2 +#endif + +#define AES_BLK_IV_IN0_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV_IN0_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN0_FLD_INSRT AES_BLK_IV_IN0_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN0_FLD_INSRT AES_BLK_IV_IN0_FLD_INSRT_V2 +#endif + +/*! @} fld (iv_in0) */ + +/*! + * @addtogroup group120305 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV_IN0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV_IN0_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV_IN0_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV_IN0_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv_in0 (AES_IV_IN0) */ + +/*! + * @addtogroup group120306 iv_in1 (AES_IV_IN1) + * @brief Offset = 0x104 + * @details AES IV_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV_IN1_OFFSET_V1 (0x0 + 0x104) +#define AES_BLK_IV_IN1_OFFSET_V2 (0x0 + 0x104) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN1_OFFSET AES_BLK_IV_IN1_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN1_OFFSET AES_BLK_IV_IN1_OFFSET_V2 +#endif + +/*! + * @addtogroup group120307 fld (iv_in1) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details iv_in[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV_IN1_FLD_SHIFT_V1 (0) +#define AES_BLK_IV_IN1_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN1_FLD_SHIFT AES_BLK_IV_IN1_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN1_FLD_SHIFT AES_BLK_IV_IN1_FLD_SHIFT_V2 +#endif + +#define AES_BLK_IV_IN1_FLD_WIDTH_V1 (32) +#define AES_BLK_IV_IN1_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN1_FLD_WIDTH AES_BLK_IV_IN1_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN1_FLD_WIDTH AES_BLK_IV_IN1_FLD_WIDTH_V2 +#endif + +#define AES_BLK_IV_IN1_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN1_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN1_FLD_UMASK AES_BLK_IV_IN1_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN1_FLD_UMASK AES_BLK_IV_IN1_FLD_UMASK_V2 +#endif + +#define AES_BLK_IV_IN1_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN1_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN1_FLD_SMASK AES_BLK_IV_IN1_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN1_FLD_SMASK AES_BLK_IV_IN1_FLD_SMASK_V2 +#endif + +#define AES_BLK_IV_IN1_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV_IN1_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN1_FLD_XTRCT AES_BLK_IV_IN1_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN1_FLD_XTRCT AES_BLK_IV_IN1_FLD_XTRCT_V2 +#endif + +#define AES_BLK_IV_IN1_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV_IN1_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN1_FLD_INSRT AES_BLK_IV_IN1_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN1_FLD_INSRT AES_BLK_IV_IN1_FLD_INSRT_V2 +#endif + +/*! @} fld (iv_in1) */ + +/*! + * @addtogroup group120308 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV_IN1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV_IN1_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV_IN1_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV_IN1_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv_in1 (AES_IV_IN1) */ + +/*! + * @addtogroup group120309 iv_in2 (AES_IV_IN2) + * @brief Offset = 0x108 + * @details AES IV_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV_IN2_OFFSET_V1 (0x0 + 0x108) +#define AES_BLK_IV_IN2_OFFSET_V2 (0x0 + 0x108) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN2_OFFSET AES_BLK_IV_IN2_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN2_OFFSET AES_BLK_IV_IN2_OFFSET_V2 +#endif + +/*! + * @addtogroup group120310 fld (iv_in2) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details iv_in[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV_IN2_FLD_SHIFT_V1 (0) +#define AES_BLK_IV_IN2_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN2_FLD_SHIFT AES_BLK_IV_IN2_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN2_FLD_SHIFT AES_BLK_IV_IN2_FLD_SHIFT_V2 +#endif + +#define AES_BLK_IV_IN2_FLD_WIDTH_V1 (32) +#define AES_BLK_IV_IN2_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN2_FLD_WIDTH AES_BLK_IV_IN2_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN2_FLD_WIDTH AES_BLK_IV_IN2_FLD_WIDTH_V2 +#endif + +#define AES_BLK_IV_IN2_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN2_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN2_FLD_UMASK AES_BLK_IV_IN2_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN2_FLD_UMASK AES_BLK_IV_IN2_FLD_UMASK_V2 +#endif + +#define AES_BLK_IV_IN2_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN2_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN2_FLD_SMASK AES_BLK_IV_IN2_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN2_FLD_SMASK AES_BLK_IV_IN2_FLD_SMASK_V2 +#endif + +#define AES_BLK_IV_IN2_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV_IN2_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN2_FLD_XTRCT AES_BLK_IV_IN2_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN2_FLD_XTRCT AES_BLK_IV_IN2_FLD_XTRCT_V2 +#endif + +#define AES_BLK_IV_IN2_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV_IN2_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN2_FLD_INSRT AES_BLK_IV_IN2_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN2_FLD_INSRT AES_BLK_IV_IN2_FLD_INSRT_V2 +#endif + +/*! @} fld (iv_in2) */ + +/*! + * @addtogroup group120311 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV_IN2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV_IN2_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV_IN2_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV_IN2_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv_in2 (AES_IV_IN2) */ + +/*! + * @addtogroup group120312 iv_in3 (AES_IV_IN3) + * @brief Offset = 0x10c + * @details AES IV_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV_IN3_OFFSET_V1 (0x0 + 0x10c) +#define AES_BLK_IV_IN3_OFFSET_V2 (0x0 + 0x10c) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN3_OFFSET AES_BLK_IV_IN3_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN3_OFFSET AES_BLK_IV_IN3_OFFSET_V2 +#endif + +/*! + * @addtogroup group120313 fld (iv_in3) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details iv_in[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV_IN3_FLD_SHIFT_V1 (0) +#define AES_BLK_IV_IN3_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN3_FLD_SHIFT AES_BLK_IV_IN3_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN3_FLD_SHIFT AES_BLK_IV_IN3_FLD_SHIFT_V2 +#endif + +#define AES_BLK_IV_IN3_FLD_WIDTH_V1 (32) +#define AES_BLK_IV_IN3_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN3_FLD_WIDTH AES_BLK_IV_IN3_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN3_FLD_WIDTH AES_BLK_IV_IN3_FLD_WIDTH_V2 +#endif + +#define AES_BLK_IV_IN3_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN3_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN3_FLD_UMASK AES_BLK_IV_IN3_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN3_FLD_UMASK AES_BLK_IV_IN3_FLD_UMASK_V2 +#endif + +#define AES_BLK_IV_IN3_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_IV_IN3_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN3_FLD_SMASK AES_BLK_IV_IN3_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN3_FLD_SMASK AES_BLK_IV_IN3_FLD_SMASK_V2 +#endif + +#define AES_BLK_IV_IN3_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV_IN3_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN3_FLD_XTRCT AES_BLK_IV_IN3_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN3_FLD_XTRCT AES_BLK_IV_IN3_FLD_XTRCT_V2 +#endif + +#define AES_BLK_IV_IN3_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV_IN3_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV_IN3_FLD_INSRT AES_BLK_IV_IN3_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV_IN3_FLD_INSRT AES_BLK_IV_IN3_FLD_INSRT_V2 +#endif + +/*! @} fld (iv_in3) */ + +/*! + * @addtogroup group120314 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV_IN3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV_IN3_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV_IN3_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV_IN3_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv_in3 (AES_IV_IN3) */ + +/*! + * @addtogroup group120315 iv0_out0 (AES_IV0_OUT0) + * @brief Offset = 0x140 + * @details AES IV0_OUT[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV0_OUT0_OFFSET_V1 (0x0 + 0x140) +#define AES_BLK_IV0_OUT0_OFFSET_V2 (0x0 + 0x140) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT0_OFFSET AES_BLK_IV0_OUT0_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT0_OFFSET AES_BLK_IV0_OUT0_OFFSET_V2 +#endif + +/*! + * @addtogroup group120316 iv_out0 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV0_OUT[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV0_OUT0_IV_OUT0_SHIFT_V1 (0) +#define AES_BLK_IV0_OUT0_IV_OUT0_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT0_IV_OUT0_SHIFT AES_BLK_IV0_OUT0_IV_OUT0_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT0_IV_OUT0_SHIFT AES_BLK_IV0_OUT0_IV_OUT0_SHIFT_V2 +#endif + +#define AES_BLK_IV0_OUT0_IV_OUT0_WIDTH_V1 (32) +#define AES_BLK_IV0_OUT0_IV_OUT0_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT0_IV_OUT0_WIDTH AES_BLK_IV0_OUT0_IV_OUT0_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT0_IV_OUT0_WIDTH AES_BLK_IV0_OUT0_IV_OUT0_WIDTH_V2 +#endif + +#define AES_BLK_IV0_OUT0_IV_OUT0_UMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT0_IV_OUT0_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT0_IV_OUT0_UMASK AES_BLK_IV0_OUT0_IV_OUT0_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT0_IV_OUT0_UMASK AES_BLK_IV0_OUT0_IV_OUT0_UMASK_V2 +#endif + +#define AES_BLK_IV0_OUT0_IV_OUT0_SMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT0_IV_OUT0_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT0_IV_OUT0_SMASK AES_BLK_IV0_OUT0_IV_OUT0_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT0_IV_OUT0_SMASK AES_BLK_IV0_OUT0_IV_OUT0_SMASK_V2 +#endif + +#define AES_BLK_IV0_OUT0_IV_OUT0_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV0_OUT0_IV_OUT0_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT0_IV_OUT0_XTRCT AES_BLK_IV0_OUT0_IV_OUT0_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT0_IV_OUT0_XTRCT AES_BLK_IV0_OUT0_IV_OUT0_XTRCT_V2 +#endif + +#define AES_BLK_IV0_OUT0_IV_OUT0_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV0_OUT0_IV_OUT0_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT0_IV_OUT0_INSRT AES_BLK_IV0_OUT0_IV_OUT0_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT0_IV_OUT0_INSRT AES_BLK_IV0_OUT0_IV_OUT0_INSRT_V2 +#endif + +/*! @} iv_out0 */ + +/*! + * @addtogroup group120317 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV0_OUT0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV0_OUT0_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV0_OUT0_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV0_OUT0_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv0_out0 (AES_IV0_OUT0) */ + +/*! + * @addtogroup group120318 iv0_out1 (AES_IV0_OUT1) + * @brief Offset = 0x144 + * @details AES IV0_OUT[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV0_OUT1_OFFSET_V1 (0x0 + 0x144) +#define AES_BLK_IV0_OUT1_OFFSET_V2 (0x0 + 0x144) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT1_OFFSET AES_BLK_IV0_OUT1_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT1_OFFSET AES_BLK_IV0_OUT1_OFFSET_V2 +#endif + +/*! + * @addtogroup group120319 iv_out1 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV0_OUT[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV0_OUT1_IV_OUT1_SHIFT_V1 (0) +#define AES_BLK_IV0_OUT1_IV_OUT1_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT1_IV_OUT1_SHIFT AES_BLK_IV0_OUT1_IV_OUT1_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT1_IV_OUT1_SHIFT AES_BLK_IV0_OUT1_IV_OUT1_SHIFT_V2 +#endif + +#define AES_BLK_IV0_OUT1_IV_OUT1_WIDTH_V1 (32) +#define AES_BLK_IV0_OUT1_IV_OUT1_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT1_IV_OUT1_WIDTH AES_BLK_IV0_OUT1_IV_OUT1_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT1_IV_OUT1_WIDTH AES_BLK_IV0_OUT1_IV_OUT1_WIDTH_V2 +#endif + +#define AES_BLK_IV0_OUT1_IV_OUT1_UMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT1_IV_OUT1_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT1_IV_OUT1_UMASK AES_BLK_IV0_OUT1_IV_OUT1_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT1_IV_OUT1_UMASK AES_BLK_IV0_OUT1_IV_OUT1_UMASK_V2 +#endif + +#define AES_BLK_IV0_OUT1_IV_OUT1_SMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT1_IV_OUT1_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT1_IV_OUT1_SMASK AES_BLK_IV0_OUT1_IV_OUT1_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT1_IV_OUT1_SMASK AES_BLK_IV0_OUT1_IV_OUT1_SMASK_V2 +#endif + +#define AES_BLK_IV0_OUT1_IV_OUT1_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV0_OUT1_IV_OUT1_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT1_IV_OUT1_XTRCT AES_BLK_IV0_OUT1_IV_OUT1_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT1_IV_OUT1_XTRCT AES_BLK_IV0_OUT1_IV_OUT1_XTRCT_V2 +#endif + +#define AES_BLK_IV0_OUT1_IV_OUT1_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV0_OUT1_IV_OUT1_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT1_IV_OUT1_INSRT AES_BLK_IV0_OUT1_IV_OUT1_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT1_IV_OUT1_INSRT AES_BLK_IV0_OUT1_IV_OUT1_INSRT_V2 +#endif + +/*! @} iv_out1 */ + +/*! + * @addtogroup group120320 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV0_OUT1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV0_OUT1_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV0_OUT1_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV0_OUT1_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv0_out1 (AES_IV0_OUT1) */ + +/*! + * @addtogroup group120321 iv0_out2 (AES_IV0_OUT2) + * @brief Offset = 0x148 + * @details AES IV0_OUT[96:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV0_OUT2_OFFSET_V1 (0x0 + 0x148) +#define AES_BLK_IV0_OUT2_OFFSET_V2 (0x0 + 0x148) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT2_OFFSET AES_BLK_IV0_OUT2_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT2_OFFSET AES_BLK_IV0_OUT2_OFFSET_V2 +#endif + +/*! + * @addtogroup group120322 iv_out2 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV0_OUT[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV0_OUT2_IV_OUT2_SHIFT_V1 (0) +#define AES_BLK_IV0_OUT2_IV_OUT2_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT2_IV_OUT2_SHIFT AES_BLK_IV0_OUT2_IV_OUT2_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT2_IV_OUT2_SHIFT AES_BLK_IV0_OUT2_IV_OUT2_SHIFT_V2 +#endif + +#define AES_BLK_IV0_OUT2_IV_OUT2_WIDTH_V1 (32) +#define AES_BLK_IV0_OUT2_IV_OUT2_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT2_IV_OUT2_WIDTH AES_BLK_IV0_OUT2_IV_OUT2_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT2_IV_OUT2_WIDTH AES_BLK_IV0_OUT2_IV_OUT2_WIDTH_V2 +#endif + +#define AES_BLK_IV0_OUT2_IV_OUT2_UMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT2_IV_OUT2_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT2_IV_OUT2_UMASK AES_BLK_IV0_OUT2_IV_OUT2_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT2_IV_OUT2_UMASK AES_BLK_IV0_OUT2_IV_OUT2_UMASK_V2 +#endif + +#define AES_BLK_IV0_OUT2_IV_OUT2_SMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT2_IV_OUT2_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT2_IV_OUT2_SMASK AES_BLK_IV0_OUT2_IV_OUT2_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT2_IV_OUT2_SMASK AES_BLK_IV0_OUT2_IV_OUT2_SMASK_V2 +#endif + +#define AES_BLK_IV0_OUT2_IV_OUT2_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV0_OUT2_IV_OUT2_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT2_IV_OUT2_XTRCT AES_BLK_IV0_OUT2_IV_OUT2_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT2_IV_OUT2_XTRCT AES_BLK_IV0_OUT2_IV_OUT2_XTRCT_V2 +#endif + +#define AES_BLK_IV0_OUT2_IV_OUT2_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV0_OUT2_IV_OUT2_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT2_IV_OUT2_INSRT AES_BLK_IV0_OUT2_IV_OUT2_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT2_IV_OUT2_INSRT AES_BLK_IV0_OUT2_IV_OUT2_INSRT_V2 +#endif + +/*! @} iv_out2 */ + +/*! + * @addtogroup group120323 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV0_OUT2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV0_OUT2_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV0_OUT2_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV0_OUT2_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv0_out2 (AES_IV0_OUT2) */ + +/*! + * @addtogroup group120324 iv0_out3 (AES_IV0_OUT3) + * @brief Offset = 0x14c + * @details AES IV0_OUT[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV0_OUT3_OFFSET_V1 (0x0 + 0x14c) +#define AES_BLK_IV0_OUT3_OFFSET_V2 (0x0 + 0x14c) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT3_OFFSET AES_BLK_IV0_OUT3_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT3_OFFSET AES_BLK_IV0_OUT3_OFFSET_V2 +#endif + +/*! + * @addtogroup group120325 iv_out3 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV0_OUT[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV0_OUT3_IV_OUT3_SHIFT_V1 (0) +#define AES_BLK_IV0_OUT3_IV_OUT3_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT3_IV_OUT3_SHIFT AES_BLK_IV0_OUT3_IV_OUT3_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT3_IV_OUT3_SHIFT AES_BLK_IV0_OUT3_IV_OUT3_SHIFT_V2 +#endif + +#define AES_BLK_IV0_OUT3_IV_OUT3_WIDTH_V1 (32) +#define AES_BLK_IV0_OUT3_IV_OUT3_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT3_IV_OUT3_WIDTH AES_BLK_IV0_OUT3_IV_OUT3_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT3_IV_OUT3_WIDTH AES_BLK_IV0_OUT3_IV_OUT3_WIDTH_V2 +#endif + +#define AES_BLK_IV0_OUT3_IV_OUT3_UMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT3_IV_OUT3_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT3_IV_OUT3_UMASK AES_BLK_IV0_OUT3_IV_OUT3_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT3_IV_OUT3_UMASK AES_BLK_IV0_OUT3_IV_OUT3_UMASK_V2 +#endif + +#define AES_BLK_IV0_OUT3_IV_OUT3_SMASK_V1 (0xffffffff) +#define AES_BLK_IV0_OUT3_IV_OUT3_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT3_IV_OUT3_SMASK AES_BLK_IV0_OUT3_IV_OUT3_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT3_IV_OUT3_SMASK AES_BLK_IV0_OUT3_IV_OUT3_SMASK_V2 +#endif + +#define AES_BLK_IV0_OUT3_IV_OUT3_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV0_OUT3_IV_OUT3_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT3_IV_OUT3_XTRCT AES_BLK_IV0_OUT3_IV_OUT3_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT3_IV_OUT3_XTRCT AES_BLK_IV0_OUT3_IV_OUT3_XTRCT_V2 +#endif + +#define AES_BLK_IV0_OUT3_IV_OUT3_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV0_OUT3_IV_OUT3_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV0_OUT3_IV_OUT3_INSRT AES_BLK_IV0_OUT3_IV_OUT3_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV0_OUT3_IV_OUT3_INSRT AES_BLK_IV0_OUT3_IV_OUT3_INSRT_V2 +#endif + +/*! @} iv_out3 */ + +/*! + * @addtogroup group120326 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV0_OUT3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV0_OUT3_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV0_OUT3_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV0_OUT3_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv0_out3 (AES_IV0_OUT3) */ + +/*! + * @addtogroup group120327 iv1_out0 (AES_IV1_OUT0) + * @brief Offset = 0x150 + * @details AES IV1_OUT[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV1_OUT0_OFFSET_V1 (0x0 + 0x150) +#define AES_BLK_IV1_OUT0_OFFSET_V2 (0x0 + 0x150) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT0_OFFSET AES_BLK_IV1_OUT0_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT0_OFFSET AES_BLK_IV1_OUT0_OFFSET_V2 +#endif + +/*! + * @addtogroup group120328 iv_out0 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV1_OUT[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV1_OUT0_IV_OUT0_SHIFT_V1 (0) +#define AES_BLK_IV1_OUT0_IV_OUT0_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT0_IV_OUT0_SHIFT AES_BLK_IV1_OUT0_IV_OUT0_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT0_IV_OUT0_SHIFT AES_BLK_IV1_OUT0_IV_OUT0_SHIFT_V2 +#endif + +#define AES_BLK_IV1_OUT0_IV_OUT0_WIDTH_V1 (32) +#define AES_BLK_IV1_OUT0_IV_OUT0_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT0_IV_OUT0_WIDTH AES_BLK_IV1_OUT0_IV_OUT0_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT0_IV_OUT0_WIDTH AES_BLK_IV1_OUT0_IV_OUT0_WIDTH_V2 +#endif + +#define AES_BLK_IV1_OUT0_IV_OUT0_UMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT0_IV_OUT0_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT0_IV_OUT0_UMASK AES_BLK_IV1_OUT0_IV_OUT0_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT0_IV_OUT0_UMASK AES_BLK_IV1_OUT0_IV_OUT0_UMASK_V2 +#endif + +#define AES_BLK_IV1_OUT0_IV_OUT0_SMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT0_IV_OUT0_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT0_IV_OUT0_SMASK AES_BLK_IV1_OUT0_IV_OUT0_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT0_IV_OUT0_SMASK AES_BLK_IV1_OUT0_IV_OUT0_SMASK_V2 +#endif + +#define AES_BLK_IV1_OUT0_IV_OUT0_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV1_OUT0_IV_OUT0_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT0_IV_OUT0_XTRCT AES_BLK_IV1_OUT0_IV_OUT0_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT0_IV_OUT0_XTRCT AES_BLK_IV1_OUT0_IV_OUT0_XTRCT_V2 +#endif + +#define AES_BLK_IV1_OUT0_IV_OUT0_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV1_OUT0_IV_OUT0_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT0_IV_OUT0_INSRT AES_BLK_IV1_OUT0_IV_OUT0_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT0_IV_OUT0_INSRT AES_BLK_IV1_OUT0_IV_OUT0_INSRT_V2 +#endif + +/*! @} iv_out0 */ + +/*! + * @addtogroup group120329 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV1_OUT0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV1_OUT0_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV1_OUT0_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV1_OUT0_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv1_out0 (AES_IV1_OUT0) */ + +/*! + * @addtogroup group120330 iv1_out1 (AES_IV1_OUT1) + * @brief Offset = 0x154 + * @details AES IV1_OUT[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV1_OUT1_OFFSET_V1 (0x0 + 0x154) +#define AES_BLK_IV1_OUT1_OFFSET_V2 (0x0 + 0x154) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT1_OFFSET AES_BLK_IV1_OUT1_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT1_OFFSET AES_BLK_IV1_OUT1_OFFSET_V2 +#endif + +/*! + * @addtogroup group120331 iv_out1 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV1_OUT[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV1_OUT1_IV_OUT1_SHIFT_V1 (0) +#define AES_BLK_IV1_OUT1_IV_OUT1_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT1_IV_OUT1_SHIFT AES_BLK_IV1_OUT1_IV_OUT1_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT1_IV_OUT1_SHIFT AES_BLK_IV1_OUT1_IV_OUT1_SHIFT_V2 +#endif + +#define AES_BLK_IV1_OUT1_IV_OUT1_WIDTH_V1 (32) +#define AES_BLK_IV1_OUT1_IV_OUT1_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT1_IV_OUT1_WIDTH AES_BLK_IV1_OUT1_IV_OUT1_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT1_IV_OUT1_WIDTH AES_BLK_IV1_OUT1_IV_OUT1_WIDTH_V2 +#endif + +#define AES_BLK_IV1_OUT1_IV_OUT1_UMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT1_IV_OUT1_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT1_IV_OUT1_UMASK AES_BLK_IV1_OUT1_IV_OUT1_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT1_IV_OUT1_UMASK AES_BLK_IV1_OUT1_IV_OUT1_UMASK_V2 +#endif + +#define AES_BLK_IV1_OUT1_IV_OUT1_SMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT1_IV_OUT1_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT1_IV_OUT1_SMASK AES_BLK_IV1_OUT1_IV_OUT1_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT1_IV_OUT1_SMASK AES_BLK_IV1_OUT1_IV_OUT1_SMASK_V2 +#endif + +#define AES_BLK_IV1_OUT1_IV_OUT1_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV1_OUT1_IV_OUT1_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT1_IV_OUT1_XTRCT AES_BLK_IV1_OUT1_IV_OUT1_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT1_IV_OUT1_XTRCT AES_BLK_IV1_OUT1_IV_OUT1_XTRCT_V2 +#endif + +#define AES_BLK_IV1_OUT1_IV_OUT1_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV1_OUT1_IV_OUT1_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT1_IV_OUT1_INSRT AES_BLK_IV1_OUT1_IV_OUT1_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT1_IV_OUT1_INSRT AES_BLK_IV1_OUT1_IV_OUT1_INSRT_V2 +#endif + +/*! @} iv_out1 */ + +/*! + * @addtogroup group120332 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV1_OUT1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV1_OUT1_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV1_OUT1_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV1_OUT1_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv1_out1 (AES_IV1_OUT1) */ + +/*! + * @addtogroup group120333 iv1_out2 (AES_IV1_OUT2) + * @brief Offset = 0x158 + * @details AES IV1_OUT[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV1_OUT2_OFFSET_V1 (0x0 + 0x158) +#define AES_BLK_IV1_OUT2_OFFSET_V2 (0x0 + 0x158) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT2_OFFSET AES_BLK_IV1_OUT2_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT2_OFFSET AES_BLK_IV1_OUT2_OFFSET_V2 +#endif + +/*! + * @addtogroup group120334 iv_out2 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV1_OUT[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV1_OUT2_IV_OUT2_SHIFT_V1 (0) +#define AES_BLK_IV1_OUT2_IV_OUT2_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT2_IV_OUT2_SHIFT AES_BLK_IV1_OUT2_IV_OUT2_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT2_IV_OUT2_SHIFT AES_BLK_IV1_OUT2_IV_OUT2_SHIFT_V2 +#endif + +#define AES_BLK_IV1_OUT2_IV_OUT2_WIDTH_V1 (32) +#define AES_BLK_IV1_OUT2_IV_OUT2_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT2_IV_OUT2_WIDTH AES_BLK_IV1_OUT2_IV_OUT2_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT2_IV_OUT2_WIDTH AES_BLK_IV1_OUT2_IV_OUT2_WIDTH_V2 +#endif + +#define AES_BLK_IV1_OUT2_IV_OUT2_UMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT2_IV_OUT2_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT2_IV_OUT2_UMASK AES_BLK_IV1_OUT2_IV_OUT2_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT2_IV_OUT2_UMASK AES_BLK_IV1_OUT2_IV_OUT2_UMASK_V2 +#endif + +#define AES_BLK_IV1_OUT2_IV_OUT2_SMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT2_IV_OUT2_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT2_IV_OUT2_SMASK AES_BLK_IV1_OUT2_IV_OUT2_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT2_IV_OUT2_SMASK AES_BLK_IV1_OUT2_IV_OUT2_SMASK_V2 +#endif + +#define AES_BLK_IV1_OUT2_IV_OUT2_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV1_OUT2_IV_OUT2_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT2_IV_OUT2_XTRCT AES_BLK_IV1_OUT2_IV_OUT2_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT2_IV_OUT2_XTRCT AES_BLK_IV1_OUT2_IV_OUT2_XTRCT_V2 +#endif + +#define AES_BLK_IV1_OUT2_IV_OUT2_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV1_OUT2_IV_OUT2_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT2_IV_OUT2_INSRT AES_BLK_IV1_OUT2_IV_OUT2_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT2_IV_OUT2_INSRT AES_BLK_IV1_OUT2_IV_OUT2_INSRT_V2 +#endif + +/*! @} iv_out2 */ + +/*! + * @addtogroup group120335 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV1_OUT2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV1_OUT2_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV1_OUT2_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV1_OUT2_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv1_out2 (AES_IV1_OUT2) */ + +/*! + * @addtogroup group120336 iv1_out3 (AES_IV1_OUT3) + * @brief Offset = 0x15c + * @details AES IV1_OUT[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_IV1_OUT3_OFFSET_V1 (0x0 + 0x15c) +#define AES_BLK_IV1_OUT3_OFFSET_V2 (0x0 + 0x15c) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT3_OFFSET AES_BLK_IV1_OUT3_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT3_OFFSET AES_BLK_IV1_OUT3_OFFSET_V2 +#endif + +/*! + * @addtogroup group120337 iv_out3 + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details IV1_OUT[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_IV1_OUT3_IV_OUT3_SHIFT_V1 (0) +#define AES_BLK_IV1_OUT3_IV_OUT3_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT3_IV_OUT3_SHIFT AES_BLK_IV1_OUT3_IV_OUT3_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT3_IV_OUT3_SHIFT AES_BLK_IV1_OUT3_IV_OUT3_SHIFT_V2 +#endif + +#define AES_BLK_IV1_OUT3_IV_OUT3_WIDTH_V1 (32) +#define AES_BLK_IV1_OUT3_IV_OUT3_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT3_IV_OUT3_WIDTH AES_BLK_IV1_OUT3_IV_OUT3_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT3_IV_OUT3_WIDTH AES_BLK_IV1_OUT3_IV_OUT3_WIDTH_V2 +#endif + +#define AES_BLK_IV1_OUT3_IV_OUT3_UMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT3_IV_OUT3_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT3_IV_OUT3_UMASK AES_BLK_IV1_OUT3_IV_OUT3_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT3_IV_OUT3_UMASK AES_BLK_IV1_OUT3_IV_OUT3_UMASK_V2 +#endif + +#define AES_BLK_IV1_OUT3_IV_OUT3_SMASK_V1 (0xffffffff) +#define AES_BLK_IV1_OUT3_IV_OUT3_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT3_IV_OUT3_SMASK AES_BLK_IV1_OUT3_IV_OUT3_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT3_IV_OUT3_SMASK AES_BLK_IV1_OUT3_IV_OUT3_SMASK_V2 +#endif + +#define AES_BLK_IV1_OUT3_IV_OUT3_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_IV1_OUT3_IV_OUT3_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT3_IV_OUT3_XTRCT AES_BLK_IV1_OUT3_IV_OUT3_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT3_IV_OUT3_XTRCT AES_BLK_IV1_OUT3_IV_OUT3_XTRCT_V2 +#endif + +#define AES_BLK_IV1_OUT3_IV_OUT3_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_IV1_OUT3_IV_OUT3_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_IV1_OUT3_IV_OUT3_INSRT AES_BLK_IV1_OUT3_IV_OUT3_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_IV1_OUT3_IV_OUT3_INSRT AES_BLK_IV1_OUT3_IV_OUT3_INSRT_V2 +#endif + +/*! @} iv_out3 */ + +/*! + * @addtogroup group120338 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_IV1_OUT3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_IV1_OUT3_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_IV1_OUT3_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_IV1_OUT3_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} iv1_out3 (AES_IV1_OUT3) */ + +/*! + * @addtogroup group120339 skg_key_cnt_in (AES_SKG_KEY_CNT_IN) + * @brief Offset = 0x160 + * @details AES SKG_KEY_CNT_IN Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_SKG_KEY_CNT_IN_OFFSET_V1 (0x0 + 0x160) +#define AES_BLK_SKG_KEY_CNT_IN_OFFSET_V2 (0x0 + 0x160) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_IN_OFFSET AES_BLK_SKG_KEY_CNT_IN_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_IN_OFFSET AES_BLK_SKG_KEY_CNT_IN_OFFSET_V2 +#endif + +/*! + * @addtogroup group120340 fld (skg_key_cnt_in) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details This register specifies the number of AES operations + * (skg_key_cnt_in+1) that are performed by legacy SKG unwrap logic. This + * field can also be used to abort SKG operations by writing 0 to this register + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SHIFT_V1 (0) +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SHIFT AES_BLK_SKG_KEY_CNT_IN_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SHIFT AES_BLK_SKG_KEY_CNT_IN_FLD_SHIFT_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_IN_FLD_WIDTH_V1 (32) +#define AES_BLK_SKG_KEY_CNT_IN_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_WIDTH AES_BLK_SKG_KEY_CNT_IN_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_WIDTH AES_BLK_SKG_KEY_CNT_IN_FLD_WIDTH_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_IN_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_SKG_KEY_CNT_IN_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_UMASK AES_BLK_SKG_KEY_CNT_IN_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_UMASK AES_BLK_SKG_KEY_CNT_IN_FLD_UMASK_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SMASK AES_BLK_SKG_KEY_CNT_IN_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_SMASK AES_BLK_SKG_KEY_CNT_IN_FLD_SMASK_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_IN_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_SKG_KEY_CNT_IN_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_XTRCT AES_BLK_SKG_KEY_CNT_IN_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_XTRCT AES_BLK_SKG_KEY_CNT_IN_FLD_XTRCT_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_IN_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_SKG_KEY_CNT_IN_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_INSRT AES_BLK_SKG_KEY_CNT_IN_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_IN_FLD_INSRT AES_BLK_SKG_KEY_CNT_IN_FLD_INSRT_V2 +#endif + +/*! @} fld (skg_key_cnt_in) */ + +/*! + * @addtogroup group120341 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_SKG_KEY_CNT_IN_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_SKG_KEY_CNT_IN_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_SKG_KEY_CNT_IN_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_SKG_KEY_CNT_IN_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} skg_key_cnt_in (AES_SKG_KEY_CNT_IN) */ + +/*! + * @addtogroup group120342 skg_key_cnt_out (AES_SKG_KEY_CNT_OUT) + * @brief Offset = 0x164 + * @details AES SKG_KEY_CNT_OUT Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_SKG_KEY_CNT_OUT_OFFSET_V1 (0x0 + 0x164) +#define AES_BLK_SKG_KEY_CNT_OUT_OFFSET_V2 (0x0 + 0x164) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_OUT_OFFSET AES_BLK_SKG_KEY_CNT_OUT_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_OUT_OFFSET AES_BLK_SKG_KEY_CNT_OUT_OFFSET_V2 +#endif + +/*! + * @addtogroup group120343 skg_key_cnt + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details This register specifies the number of AES operations that have + * been performed during legacy SKG unwrap. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SHIFT_V1 (0) +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SHIFT AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SHIFT AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SHIFT_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_WIDTH_V1 (32) +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_WIDTH AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_WIDTH AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_WIDTH_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_UMASK_V1 (0xffffffff) +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_UMASK AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_UMASK AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_UMASK_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SMASK_V1 (0xffffffff) +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SMASK AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SMASK AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_SMASK_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_XTRCT AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_XTRCT AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_XTRCT_V2 +#endif + +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_INSRT AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_INSRT AES_BLK_SKG_KEY_CNT_OUT_SKG_KEY_CNT_INSRT_V2 +#endif + +/*! @} skg_key_cnt */ + +/*! + * @addtogroup group120344 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_SKG_KEY_CNT_OUT_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_SKG_KEY_CNT_OUT_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_SKG_KEY_CNT_OUT_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_SKG_KEY_CNT_OUT_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} skg_key_cnt_out (AES_SKG_KEY_CNT_OUT) */ + +/*! + * @addtogroup group120345 dsb_r1_in0 (AES_DSB_R1_IN0) + * @brief Offset = 0x180 + * @details AES DSB_R1_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R1_IN0_OFFSET_V1 (0x0 + 0x180) +#define AES_BLK_DSB_R1_IN0_OFFSET_V2 (0x0 + 0x180) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN0_OFFSET AES_BLK_DSB_R1_IN0_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN0_OFFSET AES_BLK_DSB_R1_IN0_OFFSET_V2 +#endif + +/*! + * @addtogroup group120346 fld (dsb_r1_in0) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R1_IN[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R1_IN0_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R1_IN0_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN0_FLD_SHIFT AES_BLK_DSB_R1_IN0_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN0_FLD_SHIFT AES_BLK_DSB_R1_IN0_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R1_IN0_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R1_IN0_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN0_FLD_WIDTH AES_BLK_DSB_R1_IN0_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN0_FLD_WIDTH AES_BLK_DSB_R1_IN0_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R1_IN0_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN0_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN0_FLD_UMASK AES_BLK_DSB_R1_IN0_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN0_FLD_UMASK AES_BLK_DSB_R1_IN0_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN0_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN0_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN0_FLD_SMASK AES_BLK_DSB_R1_IN0_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN0_FLD_SMASK AES_BLK_DSB_R1_IN0_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN0_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R1_IN0_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN0_FLD_XTRCT AES_BLK_DSB_R1_IN0_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN0_FLD_XTRCT AES_BLK_DSB_R1_IN0_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R1_IN0_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R1_IN0_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN0_FLD_INSRT AES_BLK_DSB_R1_IN0_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN0_FLD_INSRT AES_BLK_DSB_R1_IN0_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r1_in0) */ + +/*! + * @addtogroup group120347 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R1_IN0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R1_IN0_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R1_IN0_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R1_IN0_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r1_in0 (AES_DSB_R1_IN0) */ + +/*! + * @addtogroup group120348 dsb_r1_in1 (AES_DSB_R1_IN1) + * @brief Offset = 0x184 + * @details AES DSB_R1_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R1_IN1_OFFSET_V1 (0x0 + 0x184) +#define AES_BLK_DSB_R1_IN1_OFFSET_V2 (0x0 + 0x184) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN1_OFFSET AES_BLK_DSB_R1_IN1_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN1_OFFSET AES_BLK_DSB_R1_IN1_OFFSET_V2 +#endif + +/*! + * @addtogroup group120349 fld (dsb_r1_in1) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R1_IN[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R1_IN1_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R1_IN1_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN1_FLD_SHIFT AES_BLK_DSB_R1_IN1_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN1_FLD_SHIFT AES_BLK_DSB_R1_IN1_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R1_IN1_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R1_IN1_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN1_FLD_WIDTH AES_BLK_DSB_R1_IN1_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN1_FLD_WIDTH AES_BLK_DSB_R1_IN1_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R1_IN1_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN1_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN1_FLD_UMASK AES_BLK_DSB_R1_IN1_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN1_FLD_UMASK AES_BLK_DSB_R1_IN1_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN1_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN1_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN1_FLD_SMASK AES_BLK_DSB_R1_IN1_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN1_FLD_SMASK AES_BLK_DSB_R1_IN1_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN1_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R1_IN1_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN1_FLD_XTRCT AES_BLK_DSB_R1_IN1_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN1_FLD_XTRCT AES_BLK_DSB_R1_IN1_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R1_IN1_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R1_IN1_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN1_FLD_INSRT AES_BLK_DSB_R1_IN1_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN1_FLD_INSRT AES_BLK_DSB_R1_IN1_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r1_in1) */ + +/*! + * @addtogroup group120350 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R1_IN1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R1_IN1_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R1_IN1_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R1_IN1_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r1_in1 (AES_DSB_R1_IN1) */ + +/*! + * @addtogroup group120351 dsb_r1_in2 (AES_DSB_R1_IN2) + * @brief Offset = 0x188 + * @details AES DSB_R1_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R1_IN2_OFFSET_V1 (0x0 + 0x188) +#define AES_BLK_DSB_R1_IN2_OFFSET_V2 (0x0 + 0x188) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN2_OFFSET AES_BLK_DSB_R1_IN2_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN2_OFFSET AES_BLK_DSB_R1_IN2_OFFSET_V2 +#endif + +/*! + * @addtogroup group120352 fld (dsb_r1_in2) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R1_IN[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R1_IN2_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R1_IN2_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN2_FLD_SHIFT AES_BLK_DSB_R1_IN2_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN2_FLD_SHIFT AES_BLK_DSB_R1_IN2_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R1_IN2_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R1_IN2_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN2_FLD_WIDTH AES_BLK_DSB_R1_IN2_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN2_FLD_WIDTH AES_BLK_DSB_R1_IN2_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R1_IN2_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN2_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN2_FLD_UMASK AES_BLK_DSB_R1_IN2_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN2_FLD_UMASK AES_BLK_DSB_R1_IN2_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN2_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN2_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN2_FLD_SMASK AES_BLK_DSB_R1_IN2_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN2_FLD_SMASK AES_BLK_DSB_R1_IN2_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN2_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R1_IN2_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN2_FLD_XTRCT AES_BLK_DSB_R1_IN2_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN2_FLD_XTRCT AES_BLK_DSB_R1_IN2_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R1_IN2_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R1_IN2_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN2_FLD_INSRT AES_BLK_DSB_R1_IN2_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN2_FLD_INSRT AES_BLK_DSB_R1_IN2_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r1_in2) */ + +/*! + * @addtogroup group120353 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R1_IN2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R1_IN2_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R1_IN2_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R1_IN2_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r1_in2 (AES_DSB_R1_IN2) */ + +/*! + * @addtogroup group120354 dsb_r1_in3 (AES_DSB_R1_IN3) + * @brief Offset = 0x18c + * @details AES DSB_R1_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R1_IN3_OFFSET_V1 (0x0 + 0x18c) +#define AES_BLK_DSB_R1_IN3_OFFSET_V2 (0x0 + 0x18c) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN3_OFFSET AES_BLK_DSB_R1_IN3_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN3_OFFSET AES_BLK_DSB_R1_IN3_OFFSET_V2 +#endif + +/*! + * @addtogroup group120355 fld (dsb_r1_in3) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R1_IN[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R1_IN3_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R1_IN3_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN3_FLD_SHIFT AES_BLK_DSB_R1_IN3_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN3_FLD_SHIFT AES_BLK_DSB_R1_IN3_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R1_IN3_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R1_IN3_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN3_FLD_WIDTH AES_BLK_DSB_R1_IN3_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN3_FLD_WIDTH AES_BLK_DSB_R1_IN3_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R1_IN3_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN3_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN3_FLD_UMASK AES_BLK_DSB_R1_IN3_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN3_FLD_UMASK AES_BLK_DSB_R1_IN3_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN3_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R1_IN3_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN3_FLD_SMASK AES_BLK_DSB_R1_IN3_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN3_FLD_SMASK AES_BLK_DSB_R1_IN3_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R1_IN3_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R1_IN3_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN3_FLD_XTRCT AES_BLK_DSB_R1_IN3_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN3_FLD_XTRCT AES_BLK_DSB_R1_IN3_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R1_IN3_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R1_IN3_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R1_IN3_FLD_INSRT AES_BLK_DSB_R1_IN3_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R1_IN3_FLD_INSRT AES_BLK_DSB_R1_IN3_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r1_in3) */ + +/*! + * @addtogroup group120356 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R1_IN3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R1_IN3_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R1_IN3_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R1_IN3_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r1_in3 (AES_DSB_R1_IN3) */ + +/*! + * @addtogroup group120357 dsb_r2_in0 (AES_DSB_R2_IN0) + * @brief Offset = 0x1c0 + * @details AES DSB_R2_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R2_IN0_OFFSET_V1 (0x0 + 0x1c0) +#define AES_BLK_DSB_R2_IN0_OFFSET_V2 (0x0 + 0x1c0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN0_OFFSET AES_BLK_DSB_R2_IN0_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN0_OFFSET AES_BLK_DSB_R2_IN0_OFFSET_V2 +#endif + +/*! + * @addtogroup group120358 fld (dsb_r2_in0) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R2_IN[31:0] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R2_IN0_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R2_IN0_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN0_FLD_SHIFT AES_BLK_DSB_R2_IN0_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN0_FLD_SHIFT AES_BLK_DSB_R2_IN0_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R2_IN0_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R2_IN0_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN0_FLD_WIDTH AES_BLK_DSB_R2_IN0_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN0_FLD_WIDTH AES_BLK_DSB_R2_IN0_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R2_IN0_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN0_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN0_FLD_UMASK AES_BLK_DSB_R2_IN0_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN0_FLD_UMASK AES_BLK_DSB_R2_IN0_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN0_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN0_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN0_FLD_SMASK AES_BLK_DSB_R2_IN0_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN0_FLD_SMASK AES_BLK_DSB_R2_IN0_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN0_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R2_IN0_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN0_FLD_XTRCT AES_BLK_DSB_R2_IN0_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN0_FLD_XTRCT AES_BLK_DSB_R2_IN0_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R2_IN0_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R2_IN0_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN0_FLD_INSRT AES_BLK_DSB_R2_IN0_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN0_FLD_INSRT AES_BLK_DSB_R2_IN0_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r2_in0) */ + +/*! + * @addtogroup group120359 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R2_IN0_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R2_IN0_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R2_IN0_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R2_IN0_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r2_in0 (AES_DSB_R2_IN0) */ + +/*! + * @addtogroup group120360 dsb_r2_in1 (AES_DSB_R2_IN1) + * @brief Offset = 0x1c4 + * @details AES DSB_R2_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R2_IN1_OFFSET_V1 (0x0 + 0x1c4) +#define AES_BLK_DSB_R2_IN1_OFFSET_V2 (0x0 + 0x1c4) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN1_OFFSET AES_BLK_DSB_R2_IN1_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN1_OFFSET AES_BLK_DSB_R2_IN1_OFFSET_V2 +#endif + +/*! + * @addtogroup group120361 fld (dsb_r2_in1) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R2_IN[63:32] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R2_IN1_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R2_IN1_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN1_FLD_SHIFT AES_BLK_DSB_R2_IN1_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN1_FLD_SHIFT AES_BLK_DSB_R2_IN1_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R2_IN1_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R2_IN1_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN1_FLD_WIDTH AES_BLK_DSB_R2_IN1_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN1_FLD_WIDTH AES_BLK_DSB_R2_IN1_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R2_IN1_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN1_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN1_FLD_UMASK AES_BLK_DSB_R2_IN1_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN1_FLD_UMASK AES_BLK_DSB_R2_IN1_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN1_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN1_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN1_FLD_SMASK AES_BLK_DSB_R2_IN1_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN1_FLD_SMASK AES_BLK_DSB_R2_IN1_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN1_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R2_IN1_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN1_FLD_XTRCT AES_BLK_DSB_R2_IN1_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN1_FLD_XTRCT AES_BLK_DSB_R2_IN1_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R2_IN1_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R2_IN1_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN1_FLD_INSRT AES_BLK_DSB_R2_IN1_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN1_FLD_INSRT AES_BLK_DSB_R2_IN1_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r2_in1) */ + +/*! + * @addtogroup group120362 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R2_IN1_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R2_IN1_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R2_IN1_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R2_IN1_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r2_in1 (AES_DSB_R2_IN1) */ + +/*! + * @addtogroup group120363 dsb_r2_in2 (AES_DSB_R2_IN2) + * @brief Offset = 0x1c8 + * @details AES DSB_R2_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R2_IN2_OFFSET_V1 (0x0 + 0x1c8) +#define AES_BLK_DSB_R2_IN2_OFFSET_V2 (0x0 + 0x1c8) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN2_OFFSET AES_BLK_DSB_R2_IN2_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN2_OFFSET AES_BLK_DSB_R2_IN2_OFFSET_V2 +#endif + +/*! + * @addtogroup group120364 fld (dsb_r2_in2) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R2_IN[95:64] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R2_IN2_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R2_IN2_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN2_FLD_SHIFT AES_BLK_DSB_R2_IN2_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN2_FLD_SHIFT AES_BLK_DSB_R2_IN2_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R2_IN2_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R2_IN2_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN2_FLD_WIDTH AES_BLK_DSB_R2_IN2_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN2_FLD_WIDTH AES_BLK_DSB_R2_IN2_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R2_IN2_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN2_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN2_FLD_UMASK AES_BLK_DSB_R2_IN2_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN2_FLD_UMASK AES_BLK_DSB_R2_IN2_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN2_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN2_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN2_FLD_SMASK AES_BLK_DSB_R2_IN2_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN2_FLD_SMASK AES_BLK_DSB_R2_IN2_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN2_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R2_IN2_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN2_FLD_XTRCT AES_BLK_DSB_R2_IN2_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN2_FLD_XTRCT AES_BLK_DSB_R2_IN2_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R2_IN2_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R2_IN2_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN2_FLD_INSRT AES_BLK_DSB_R2_IN2_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN2_FLD_INSRT AES_BLK_DSB_R2_IN2_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r2_in2) */ + +/*! + * @addtogroup group120365 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R2_IN2_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R2_IN2_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R2_IN2_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R2_IN2_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r2_in2 (AES_DSB_R2_IN2) */ + +/*! + * @addtogroup group120366 dsb_r2_in3 (AES_DSB_R2_IN3) + * @brief Offset = 0x1cc + * @details AES DSB_R2_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_DSB_R2_IN3_OFFSET_V1 (0x0 + 0x1cc) +#define AES_BLK_DSB_R2_IN3_OFFSET_V2 (0x0 + 0x1cc) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN3_OFFSET AES_BLK_DSB_R2_IN3_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN3_OFFSET AES_BLK_DSB_R2_IN3_OFFSET_V2 +#endif + +/*! + * @addtogroup group120367 fld (dsb_r2_in3) + * @brief Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 + * @details DSB_R2_IN[127:96] + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_DSB_R2_IN3_FLD_SHIFT_V1 (0) +#define AES_BLK_DSB_R2_IN3_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN3_FLD_SHIFT AES_BLK_DSB_R2_IN3_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN3_FLD_SHIFT AES_BLK_DSB_R2_IN3_FLD_SHIFT_V2 +#endif + +#define AES_BLK_DSB_R2_IN3_FLD_WIDTH_V1 (32) +#define AES_BLK_DSB_R2_IN3_FLD_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN3_FLD_WIDTH AES_BLK_DSB_R2_IN3_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN3_FLD_WIDTH AES_BLK_DSB_R2_IN3_FLD_WIDTH_V2 +#endif + +#define AES_BLK_DSB_R2_IN3_FLD_UMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN3_FLD_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN3_FLD_UMASK AES_BLK_DSB_R2_IN3_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN3_FLD_UMASK AES_BLK_DSB_R2_IN3_FLD_UMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN3_FLD_SMASK_V1 (0xffffffff) +#define AES_BLK_DSB_R2_IN3_FLD_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN3_FLD_SMASK AES_BLK_DSB_R2_IN3_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN3_FLD_SMASK AES_BLK_DSB_R2_IN3_FLD_SMASK_V2 +#endif + +#define AES_BLK_DSB_R2_IN3_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#define AES_BLK_DSB_R2_IN3_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN3_FLD_XTRCT AES_BLK_DSB_R2_IN3_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN3_FLD_XTRCT AES_BLK_DSB_R2_IN3_FLD_XTRCT_V2 +#endif + +#define AES_BLK_DSB_R2_IN3_FLD_INSRT_V1(f) ((((uint32_t)f) & 0xffffffff) << 0) +#define AES_BLK_DSB_R2_IN3_FLD_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_DSB_R2_IN3_FLD_INSRT AES_BLK_DSB_R2_IN3_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_DSB_R2_IN3_FLD_INSRT AES_BLK_DSB_R2_IN3_FLD_INSRT_V2 +#endif + +/*! @} fld (dsb_r2_in3) */ + +/*! + * @addtogroup group120368 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_DSB_R2_IN3_TNBLE_RESET_UMASK_T7001_A1 (0xffffffff) +#define AES_BLK_DSB_R2_IN3_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_DSB_R2_IN3_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_DSB_R2_IN3_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} dsb_r2_in3 (AES_DSB_R2_IN3) */ + +/*! + * @addtogroup group120369 err (AES_ERR) + * @brief Offset = 0x1d0 + * @details AES Error Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_ERR_OFFSET_V1 (0x0 + 0x1d0) +#define AES_BLK_ERR_OFFSET_V2 (0x0 + 0x1d0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_ERR_OFFSET AES_BLK_ERR_OFFSET_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_ERR_OFFSET AES_BLK_ERR_OFFSET_V2 +#endif + +/*! + * @addtogroup group120370 fld (aes_err) + * @brief Range = 0 | Width = 1 | Access = read-only | Default = 0x0 + * @details If the GID0, GID1, UID1, UID2, or Fairplay key descrambler is + * selected for use when disabled, then the error bit is set. The error bit + * is sticky and is only cleared on a reset. + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_ERR_FLD_SHIFT_V1 (0) +#define AES_BLK_ERR_FLD_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_ERR_FLD_SHIFT AES_BLK_ERR_FLD_SHIFT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_ERR_FLD_SHIFT AES_BLK_ERR_FLD_SHIFT_V2 +#endif + +#define AES_BLK_ERR_FLD_WIDTH_V1 (1) +#define AES_BLK_ERR_FLD_WIDTH_V2 (1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_ERR_FLD_WIDTH AES_BLK_ERR_FLD_WIDTH_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_ERR_FLD_WIDTH AES_BLK_ERR_FLD_WIDTH_V2 +#endif + +#define AES_BLK_ERR_FLD_UMASK_V1 (0x1) +#define AES_BLK_ERR_FLD_UMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_ERR_FLD_UMASK AES_BLK_ERR_FLD_UMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_ERR_FLD_UMASK AES_BLK_ERR_FLD_UMASK_V2 +#endif + +#define AES_BLK_ERR_FLD_SMASK_V1 (0x1) +#define AES_BLK_ERR_FLD_SMASK_V2 (0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_ERR_FLD_SMASK AES_BLK_ERR_FLD_SMASK_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_ERR_FLD_SMASK AES_BLK_ERR_FLD_SMASK_V2 +#endif + +#define AES_BLK_ERR_FLD_XTRCT_V1(r) ((((uint32_t)r) >> 0) & 0x1) +#define AES_BLK_ERR_FLD_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0x1) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_ERR_FLD_XTRCT AES_BLK_ERR_FLD_XTRCT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_ERR_FLD_XTRCT AES_BLK_ERR_FLD_XTRCT_V2 +#endif + +#define AES_BLK_ERR_FLD_INSRT_V1(f) ((((uint32_t)f) & 0x1) << 0) +#define AES_BLK_ERR_FLD_INSRT_V2(f) ((((uint32_t)f) & 0x1) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V1 +#define AES_BLK_ERR_FLD_INSRT AES_BLK_ERR_FLD_INSRT_V1 +#elif SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_ERR_FLD_INSRT AES_BLK_ERR_FLD_INSRT_V2 +#endif + +/*! @} fld (aes_err) */ + +/*! + * @addtogroup group120372 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_ERR_TNBLE_RESET_UMASK_T7001_A1 (0x1) +#define AES_BLK_ERR_TNBLE_RESET_UMASK_S7002_A1 (0x1) + +#define AES_BLK_ERR_TNBLE_RESET_VALUE_T7001_A1 (0x0) +#define AES_BLK_ERR_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} err (AES_ERR) */ + +/*! + * @addtogroup group120236 txt_in_data (AES_TXT_IN_DATA) + * @brief Offset = 0x40 + * @details AES Cipher TXT_IN Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_IN_DATA_OFFSET_V2 (0x0 + 0x40) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_DATA_OFFSET AES_BLK_TXT_IN_DATA_OFFSET_V2 +#endif + +/*! + * @addtogroup group120237 txt_in + * @brief Range = 31:0 | Width = 32 | Access = write_only | Default = 0x0 + * @details txt_in to fifo + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_IN_DATA_TXT_IN_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_DATA_TXT_IN_SHIFT AES_BLK_TXT_IN_DATA_TXT_IN_SHIFT_V2 +#endif + +#define AES_BLK_TXT_IN_DATA_TXT_IN_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_DATA_TXT_IN_WIDTH AES_BLK_TXT_IN_DATA_TXT_IN_WIDTH_V2 +#endif + +#define AES_BLK_TXT_IN_DATA_TXT_IN_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_DATA_TXT_IN_UMASK AES_BLK_TXT_IN_DATA_TXT_IN_UMASK_V2 +#endif + +#define AES_BLK_TXT_IN_DATA_TXT_IN_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_DATA_TXT_IN_SMASK AES_BLK_TXT_IN_DATA_TXT_IN_SMASK_V2 +#endif + +#define AES_BLK_TXT_IN_DATA_TXT_IN_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_DATA_TXT_IN_XTRCT AES_BLK_TXT_IN_DATA_TXT_IN_XTRCT_V2 +#endif + +#define AES_BLK_TXT_IN_DATA_TXT_IN_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_IN_DATA_TXT_IN_INSRT AES_BLK_TXT_IN_DATA_TXT_IN_INSRT_V2 +#endif + +/*! @} txt_in */ + +/*! + * @addtogroup group120238 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_IN_DATA_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_TXT_IN_DATA_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_in_data (AES_TXT_IN_DATA) */ + +/*! + * @addtogroup group120245 txt_out_data (AES_TXT_OUT_DATA) + * @brief Offset = 0x80 + * @details AES Cipher TXT_OUT Register + * @see @ref SAIRegister + * @{ + */ + +#define AES_BLK_TXT_OUT_DATA_OFFSET_V2 (0x0 + 0x80) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_DATA_OFFSET AES_BLK_TXT_OUT_DATA_OFFSET_V2 +#endif + +/*! + * @addtogroup group120246 txt_out + * @brief Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 + * @details txt_out from fifo + * @see @ref SAIField + * @{ + */ + +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_SHIFT_V2 (0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_SHIFT AES_BLK_TXT_OUT_DATA_TXT_OUT_SHIFT_V2 +#endif + +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_WIDTH_V2 (32) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_WIDTH AES_BLK_TXT_OUT_DATA_TXT_OUT_WIDTH_V2 +#endif + +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_UMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_UMASK AES_BLK_TXT_OUT_DATA_TXT_OUT_UMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_SMASK_V2 (0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_SMASK AES_BLK_TXT_OUT_DATA_TXT_OUT_SMASK_V2 +#endif + +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_XTRCT_V2(r) ((((uint32_t)r) >> 0) & 0xffffffff) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_XTRCT AES_BLK_TXT_OUT_DATA_TXT_OUT_XTRCT_V2 +#endif + +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_INSRT_V2(f) ((((uint32_t)f) & 0xffffffff) << 0) +#if SPDS_AES_VERSION == SPDS_AES_V2 +#define AES_BLK_TXT_OUT_DATA_TXT_OUT_INSRT AES_BLK_TXT_OUT_DATA_TXT_OUT_INSRT_V2 +#endif + +/*! @} txt_out */ + +/*! + * @addtogroup group120247 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_BLK_TXT_OUT_DATA_TNBLE_RESET_UMASK_S7002_A1 (0xffffffff) + +#define AES_BLK_TXT_OUT_DATA_TNBLE_RESET_VALUE_S7002_A1 (0x0) + +/*! @} reset */ + +/*! @} txt_out_data (AES_TXT_OUT_DATA) */ + +/*! @} blk (AES) */ + +/*! + * @addtogroup group581457 command_fifo_direct_access + * @brief Offset = 0x4000 + * @details Direct read access to 128 X 32 Command FIFO + * @see @ref SAIAddressBlock + * @{ + */ + +#define AES_COMMAND_FIFO_DIRECT_ACCESS_OFFSET_V3 (0x4000) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_COMMAND_FIFO_DIRECT_ACCESS_OFFSET AES_COMMAND_FIFO_DIRECT_ACCESS_OFFSET_V3 +#endif + +/*! + * @addtogroup group581458 word + * @brief Offset = 0x0 + * @see @ref SAIRegister + * @{ + */ + +#define AES_COMMAND_FIFO_DIRECT_ACCESS_WORD_OFFSET_V3 (0x4000 + 0x0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_COMMAND_FIFO_DIRECT_ACCESS_WORD_OFFSET AES_COMMAND_FIFO_DIRECT_ACCESS_WORD_OFFSET_V3 +#endif + +/*! + * @addtogroup group581459 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_COMMAND_FIFO_DIRECT_ACCESS_WORD_TNBLE_RESET_UMASK_S8000_A1 (0x0) + +#define AES_COMMAND_FIFO_DIRECT_ACCESS_WORD_TNBLE_RESET_VALUE_S8000_A1 (0x0) + +/*! @} reset */ + +/*! @} word */ + +/*! @} command_fifo_direct_access */ + +/*! + * @addtogroup group581460 history_fifo_direct_access + * @brief Offset = 0x4600 + * @details Direct read access to 32 word History FIFO + * @see @ref SAIAddressBlock + * @{ + */ + +#define AES_HISTORY_FIFO_DIRECT_ACCESS_OFFSET_V3 (0x4600) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_HISTORY_FIFO_DIRECT_ACCESS_OFFSET AES_HISTORY_FIFO_DIRECT_ACCESS_OFFSET_V3 +#endif + +/*! + * @addtogroup group581461 command + * @brief Offset = 0x0 + * @details Command Word Data + * @see @ref SAIRegister + * @{ + */ + +#define AES_HISTORY_FIFO_DIRECT_ACCESS_COMMAND_OFFSET_V3 (0x4600 + 0x0) +#if SPDS_AES_VERSION == SPDS_AES_V3 +#define AES_HISTORY_FIFO_DIRECT_ACCESS_COMMAND_OFFSET AES_HISTORY_FIFO_DIRECT_ACCESS_COMMAND_OFFSET_V3 +#endif + +/*! + * @addtogroup group581462 reset + * @see @ref SAITunable + * @{ + */ + +#define AES_HISTORY_FIFO_DIRECT_ACCESS_COMMAND_TNBLE_RESET_UMASK_S8000_A1 (0x0) + +#define AES_HISTORY_FIFO_DIRECT_ACCESS_COMMAND_TNBLE_RESET_VALUE_S8000_A1 (0x0) + +/*! @} reset */ + +/*! @} command */ + +/*! @} history_fifo_direct_access */ + +#define AES_TNBLES_DEFAULT_S8000_A1 \ +/* Key = spds_tunable_default */ \ +/* Register Macro Identifier Register Offset Tunable Mask Tunable Value */ \ +{ /*! AES_BLK_CONFIG */ 0x4, 0x30000, 0x0 }, \ +{ -1, -1, -1 } + +#define AES_TNBLES_DEFAULT_S8000_B0 \ +/* Key = spds_tunable_default */ \ +/* Register Macro Identifier Register Offset Tunable Mask Tunable Value */ \ +{ /*! AES_BLK_CONFIG */ 0x4, 0x30000, 0x0 }, \ +{ -1, -1, -1 } + +#define AES_TNBLES_DEFAULT_S8001_A0 \ +/* Key = spds_tunable_default */ \ +/* Register Macro Identifier Register Offset Tunable Mask Tunable Value */ \ +{ /*! AES_BLK_CONFIG */ 0x4, 0x30000, 0x0 }, \ +{ -1, -1, -1 } + +#define AES_TNBLES_DEFAULT_T8010_A0 \ +/* Key = spds_tunable_default */ \ +/* Register Macro Identifier Register Offset Tunable Mask Tunable Value */ \ +{ /*! AES_BLK_CONFIG */ 0x4, 0x30000, 0x0 }, \ +{ -1, -1, -1 } + +/*! @} aes */ + +#ifdef __ASSEMBLY__ +#undef SPDS_ENABLE_ENUMS +#undef SPDS_ENABLE_STRUCTS +#endif /*! __ASSEMBLY__ */ + +#ifdef SPDS_ENABLE_STRUCTS +#include +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! + * @addtogroup group995868 aes + * @brief Address = 0x20a108000 + * @details Version = 0.0.1 @n + * AES Registers + * @{ + */ + +/*! + * @addtogroup group995869 blk (AES) + * @brief Offset = 0x0 + * @details General Control registers + * @see @ref SAIAddressBlock + * @{ + */ + +/*! + * @addtogroup group995870 version + * @brief Offset = 0x0 + * @details IP Implementation Version + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * Minor Release Number + */ + uint32_t minor_release : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Major Release Number + */ + uint32_t major_release : 8; + + /*! + * Range = 23:16 | Width = 8 | Access = read-only | Default = 0x0 @n + * Version Number + */ + uint32_t fld : 8; + + /*! + * Range = 31:24 | Width = 8 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 8; + }; +} aes_blk_version_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * Minor Release Number + */ + uint32_t minor_release : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Major Release Number + */ + uint32_t major_release : 8; + + /*! + * Range = 23:16 | Width = 8 | Access = read-only | Default = 0x0 @n + * Version Number + */ + uint32_t fld : 8; + + /*! + * Range = 31:24 | Width = 8 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 8; + }; +} aes_blk_version_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * Minor Release Number + */ + uint32_t minor_release : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Major Release Number + */ + uint32_t major_release : 8; + + /*! + * Range = 23:16 | Width = 8 | Access = read-only | Default = 0x0 @n + * Version Number + */ + uint32_t fld : 8; + + /*! + * Range = 31:24 | Width = 8 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 8; + }; +} aes_blk_version_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * Minor Release Number + */ + uint32_t minor_release : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Major Release Number + */ + uint32_t major_release : 8; + + /*! + * Range = 23:16 | Width = 8 | Access = read-only | Default = 0x0 @n + * Version Number + */ + uint32_t fld : 8; + + /*! + * Range = 31:24 | Width = 8 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 8; + }; +} aes_blk_version_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * Minor Release Number + */ + uint32_t minor_release : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Major Release Number + */ + uint32_t major_release : 8; + + /*! + * Range = 23:16 | Width = 8 | Access = read-only | Default = 0x0 @n + * Version Number + */ + uint32_t fld : 8; + + /*! + * Range = 31:24 | Width = 8 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 8; + }; +} aes_blk_version_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_version_v3_t aes_blk_version_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_version_v4_t aes_blk_version_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_version_v5_t aes_blk_version_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_version_v6_t aes_blk_version_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_version_v7_t aes_blk_version_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} version */ + +/*! + * @addtogroup group995876 config + * @brief Offset = 0x4 + * @details Configuration register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 3:0 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Read transactions + */ + uint32_t axi_aruser : 4; + + /*! + * Range = 7:4 | Width = 4 | Access = read-write | Default = 0x0 @n + * ARCACHE for AXI Address Read transactions + */ + uint32_t axi_arcache : 4; + + /*! + * Range = 11:8 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Write transactions + */ + uint32_t axi_awuser : 4; + + /*! + * Range = 15:12 | Width = 4 | Access = read-write | Default = 0x0 @n + * AWCACHE for AXI Address Write transactions + */ + uint32_t axi_awcache : 4; + + /*! + * Range = 17:16 | Width = 2 | Access = read-write | Default = 0x0 @n + * 0 = Full Size (default) 64 bytes, 1 = Half Size 32 bytes, 2 = + * Quarter Size 16 bytes, 3 = N/A + */ + uint32_t burst_size : 2; + + /*! + * Range = 31:18 | Width = 14 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 14; + }; +} aes_blk_config_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 3:0 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Read transactions + */ + uint32_t axi_aruser : 4; + + /*! + * Range = 7:4 | Width = 4 | Access = read-write | Default = 0x0 @n + * ARCACHE for AXI Address Read transactions + */ + uint32_t axi_arcache : 4; + + /*! + * Range = 11:8 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Write transactions + */ + uint32_t axi_awuser : 4; + + /*! + * Range = 15:12 | Width = 4 | Access = read-write | Default = 0x0 @n + * AWCACHE for AXI Address Write transactions + */ + uint32_t axi_awcache : 4; + + /*! + * Range = 17:16 | Width = 2 | Access = read-write | Default = 0x0 @n + * 0 = Full Size (default) 64 bytes, 1 = Half Size 32 bytes, 2 = + * Quarter Size 16 bytes, 3 = N/A + */ + uint32_t burst_size : 2; + + /*! + * Range = 31:18 | Width = 14 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 14; + }; +} aes_blk_config_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 3:0 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Read transactions + */ + uint32_t axi_aruser : 4; + + /*! + * Range = 7:4 | Width = 4 | Access = read-write | Default = 0x0 @n + * ARCACHE for AXI Address Read transactions + */ + uint32_t axi_arcache : 4; + + /*! + * Range = 11:8 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Write transactions + */ + uint32_t axi_awuser : 4; + + /*! + * Range = 15:12 | Width = 4 | Access = read-write | Default = 0x0 @n + * AWCACHE for AXI Address Write transactions + */ + uint32_t axi_awcache : 4; + + /*! + * Range = 17:16 | Width = 2 | Access = read-write | Default = 0x0 @n + * 0 = Full Size (default) 64 bytes, 1 = Half Size 32 bytes, 2 = + * Quarter Size 16 bytes, 3 = N/A + */ + uint32_t burst_size : 2; + + /*! + * Range = 31:18 | Width = 14 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 14; + }; +} aes_blk_config_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 3:0 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Read transactions + */ + uint32_t axi_aruser : 4; + + /*! + * Range = 7:4 | Width = 4 | Access = read-write | Default = 0x0 @n + * ARCACHE for AXI Address Read transactions + */ + uint32_t axi_arcache : 4; + + /*! + * Range = 11:8 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Write transactions + */ + uint32_t axi_awuser : 4; + + /*! + * Range = 15:12 | Width = 4 | Access = read-write | Default = 0x0 @n + * AWCACHE for AXI Address Write transactions + */ + uint32_t axi_awcache : 4; + + /*! + * Range = 17:16 | Width = 2 | Access = read-write | Default = 0x0 @n + * 0 = Full Size (default) 64 bytes, 1 = Half Size 32 bytes, 2 = + * Quarter Size 16 bytes, 3 = N/A + */ + uint32_t burst_size : 2; + + /*! + * Range = 31:18 | Width = 14 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 14; + }; +} aes_blk_config_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 3:0 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Read transactions + */ + uint32_t axi_aruser : 4; + + /*! + * Range = 7:4 | Width = 4 | Access = read-write | Default = 0x0 @n + * ARCACHE for AXI Address Read transactions + */ + uint32_t axi_arcache : 4; + + /*! + * Range = 11:8 | Width = 4 | Access = read-write | Default = 0x0 @n + * USER ID for AXI Address Write transactions + */ + uint32_t axi_awuser : 4; + + /*! + * Range = 15:12 | Width = 4 | Access = read-write | Default = 0x0 @n + * AWCACHE for AXI Address Write transactions + */ + uint32_t axi_awcache : 4; + + /*! + * Range = 17:16 | Width = 2 | Access = read-write | Default = 0x0 @n + * 0 = Full Size (default) 64 bytes, 1 = Half Size 32 bytes, 2 = + * Quarter Size 16 bytes, 3 = N/A + */ + uint32_t burst_size : 2; + + /*! + * Range = 31:18 | Width = 14 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 14; + }; +} aes_blk_config_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_config_v3_t aes_blk_config_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_config_v4_t aes_blk_config_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_config_v5_t aes_blk_config_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_config_v6_t aes_blk_config_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_config_v7_t aes_blk_config_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} config */ + +/*! + * @addtogroup group995885 control + * @brief Offset = 0x8 + * @details Control Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Start executing commands in Command FIFO + */ + uint32_t start : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Stop executing commands in Command FIFO + */ + uint32_t stop : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Empty Command FIFO + */ + uint32_t reset : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Reset the AES Engine + */ + uint32_t reset_aes : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_read_channel : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_write_channel : 1; + + /*! + * Range = 31:6 | Width = 26 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 26; + }; +} aes_blk_control_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Start executing commands in Command FIFO + */ + uint32_t start : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Stop executing commands in Command FIFO + */ + uint32_t stop : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Empty Command FIFO + */ + uint32_t reset : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Reset the AES Engine + */ + uint32_t reset_aes : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_read_channel : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_write_channel : 1; + + /*! + * Range = 31:6 | Width = 26 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 26; + }; +} aes_blk_control_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Start executing commands in Command FIFO + */ + uint32_t start : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Stop executing commands in Command FIFO + */ + uint32_t stop : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Empty Command FIFO + */ + uint32_t reset : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Reset the AES Engine + */ + uint32_t reset_aes : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_read_channel : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_write_channel : 1; + + /*! + * Range = 31:6 | Width = 26 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 26; + }; +} aes_blk_control_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Start executing commands in Command FIFO + */ + uint32_t start : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Stop executing commands in Command FIFO + */ + uint32_t stop : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Empty Command FIFO + */ + uint32_t reset : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Reset the AES Engine + */ + uint32_t reset_aes : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_read_channel : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_write_channel : 1; + + /*! + * Range = 31:6 | Width = 26 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 26; + }; +} aes_blk_control_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Start executing commands in Command FIFO + */ + uint32_t start : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Stop executing commands in Command FIFO + */ + uint32_t stop : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Empty Command FIFO + */ + uint32_t reset : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Reset the AES Engine + */ + uint32_t reset_aes : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_read_channel : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Unused. May be used in future chips. + */ + uint32_t reset_write_channel : 1; + + /*! + * Range = 31:6 | Width = 26 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 26; + }; +} aes_blk_control_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_control_v3_t aes_blk_control_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_control_v4_t aes_blk_control_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_control_v5_t aes_blk_control_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_control_v6_t aes_blk_control_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_control_v7_t aes_blk_control_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} control */ + +/*! + * @addtogroup group995894 status + * @brief Offset = 0xc + * @details Channel status register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * Asserted when either the key configurator, IV setup, or AES cipher + * engines are busy + */ + uint32_t busy : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_status_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * Asserted when either the key configurator, IV setup, or AES cipher + * engines are busy + */ + uint32_t busy : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_status_v2_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is reading data from System Memory + */ + uint32_t dma_read_active : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done reading data from System Memory but not all data + * has been pushed into the AES engine + */ + uint32_t dma_read_incomplete : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is writing data to System Memory + */ + uint32_t dma_write_active : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done writing data to System Memory but not all data has + * been written + */ + uint32_t dma_write_incomplete : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-only | Default = 0x0 @n + * AES module is busy + */ + uint32_t active : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-only | Default = 0x0 @n + * A command is being executed from the Command FIFO + */ + uint32_t command_fifo_active : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-only | Default = 0x0 @n + * Indicates the Command FIFO has been enabled and ready to execute + * commands + */ + uint32_t command_fifo_enabled : 1; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_status_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is reading data from System Memory + */ + uint32_t dma_read_active : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done reading data from System Memory but not all data + * has been pushed into the AES engine + */ + uint32_t dma_read_incomplete : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is writing data to System Memory + */ + uint32_t dma_write_active : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done writing data to System Memory but not all data has + * been written + */ + uint32_t dma_write_incomplete : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-only | Default = 0x0 @n + * AES module is busy + */ + uint32_t active : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-only | Default = 0x0 @n + * A command is being executed from the Command FIFO + */ + uint32_t command_fifo_active : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-only | Default = 0x0 @n + * Indicates the Command FIFO has been enabled and ready to execute + * commands + */ + uint32_t command_fifo_enabled : 1; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_status_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is reading data from System Memory + */ + uint32_t dma_read_active : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done reading data from System Memory but not all data + * has been pushed into the AES engine + */ + uint32_t dma_read_incomplete : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is writing data to System Memory + */ + uint32_t dma_write_active : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done writing data to System Memory but not all data has + * been written + */ + uint32_t dma_write_incomplete : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-only | Default = 0x0 @n + * AES module is busy + */ + uint32_t active : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-only | Default = 0x0 @n + * A command is being executed from the Command FIFO + */ + uint32_t command_fifo_active : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-only | Default = 0x0 @n + * Indicates the Command FIFO has been enabled and ready to execute + * commands + */ + uint32_t command_fifo_enabled : 1; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_status_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is reading data from System Memory + */ + uint32_t dma_read_active : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done reading data from System Memory but not all data + * has been pushed into the AES engine + */ + uint32_t dma_read_incomplete : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is writing data to System Memory + */ + uint32_t dma_write_active : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done writing data to System Memory but not all data has + * been written + */ + uint32_t dma_write_incomplete : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-only | Default = 0x0 @n + * AES module is busy + */ + uint32_t active : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-only | Default = 0x0 @n + * A command is being executed from the Command FIFO + */ + uint32_t command_fifo_active : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-only | Default = 0x0 @n + * Indicates the Command FIFO has been enabled and ready to execute + * commands + */ + uint32_t command_fifo_enabled : 1; + + /*! + * Range = 7 | Width = 1 | Access = read-only | Default = 0x0 @n + * The random number generator for text DPA has been seeded + */ + uint32_t text_dpa_random_seeded : 1; + + /*! + * Range = 8 | Width = 1 | Access = read-only | Default = 0x0 @n + * The random number generator for key unwrap DPA has been seeded + */ + uint32_t key_unwrap_dpa_random_seeded : 1; + + /*! + * Range = 31:9 | Width = 23 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 23; + }; +} aes_blk_status_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is reading data from System Memory + */ + uint32_t dma_read_active : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done reading data from System Memory but not all data + * has been pushed into the AES engine + */ + uint32_t dma_read_incomplete : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is writing data to System Memory + */ + uint32_t dma_write_active : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * The DMA is done writing data to System Memory but not all data has + * been written + */ + uint32_t dma_write_incomplete : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-only | Default = 0x0 @n + * AES module is busy + */ + uint32_t active : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-only | Default = 0x0 @n + * A command is being executed from the Command FIFO + */ + uint32_t command_fifo_active : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-only | Default = 0x0 @n + * Indicates the Command FIFO has been enabled and ready to execute + * commands + */ + uint32_t command_fifo_enabled : 1; + + /*! + * Range = 7 | Width = 1 | Access = read-only | Default = 0x0 @n + * The random number generator for text DPA has been seeded + */ + uint32_t text_dpa_random_seeded : 1; + + /*! + * Range = 8 | Width = 1 | Access = read-only | Default = 0x0 @n + * The random number generator for key unwrap DPA has been seeded + */ + uint32_t key_unwrap_dpa_random_seeded : 1; + + /*! + * Range = 31:9 | Width = 23 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 23; + }; +} aes_blk_status_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_status_v1_t aes_blk_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_status_v2_t aes_blk_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_status_v3_t aes_blk_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_status_v4_t aes_blk_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_status_v5_t aes_blk_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_status_v6_t aes_blk_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_status_v7_t aes_blk_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} status */ + +/*! + * @addtogroup group995906 key_id + * @brief Offset = 0x10 + * @details Current Key IDs + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 0 + */ + uint32_t context_0 : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 1 + */ + uint32_t context_1 : 8; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_key_id_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 0 + */ + uint32_t context_0 : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 1 + */ + uint32_t context_1 : 8; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_key_id_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 0 + */ + uint32_t context_0 : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 1 + */ + uint32_t context_1 : 8; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_key_id_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 0 + */ + uint32_t context_0 : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 1 + */ + uint32_t context_1 : 8; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_key_id_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 7:0 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 0 + */ + uint32_t context_0 : 8; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * ID for Key in context 1 + */ + uint32_t context_1 : 8; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_key_id_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_key_id_v3_t aes_blk_key_id_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_key_id_v4_t aes_blk_key_id_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_key_id_v5_t aes_blk_key_id_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_key_id_v6_t aes_blk_key_id_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_key_id_v7_t aes_blk_key_id_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_id */ + +/*! + * @addtogroup group995911 axi_status + * @brief Offset = 0x14 + * @details AXI status register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 1:0 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to read request + */ + uint32_t read_response : 2; + + /*! + * Range = 3:2 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to write request + */ + uint32_t write_response : 2; + + /*! + * Range = 31:4 | Width = 28 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 28; + }; +} aes_blk_axi_status_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 1:0 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to read request + */ + uint32_t read_response : 2; + + /*! + * Range = 3:2 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to write request + */ + uint32_t write_response : 2; + + /*! + * Range = 31:4 | Width = 28 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 28; + }; +} aes_blk_axi_status_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 1:0 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to read request + */ + uint32_t read_response : 2; + + /*! + * Range = 3:2 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to write request + */ + uint32_t write_response : 2; + + /*! + * Range = 31:4 | Width = 28 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 28; + }; +} aes_blk_axi_status_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 1:0 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to read request + */ + uint32_t read_response : 2; + + /*! + * Range = 3:2 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to write request + */ + uint32_t write_response : 2; + + /*! + * Range = 31:4 | Width = 28 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 28; + }; +} aes_blk_axi_status_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 1:0 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to read request + */ + uint32_t read_response : 2; + + /*! + * Range = 3:2 | Width = 2 | Access = read-only | Default = 0x0 @n + * AXI response to write request + */ + uint32_t write_response : 2; + + /*! + * Range = 31:4 | Width = 28 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 28; + }; +} aes_blk_axi_status_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_axi_status_v3_t aes_blk_axi_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_axi_status_v4_t aes_blk_axi_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_axi_status_v5_t aes_blk_axi_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_axi_status_v6_t aes_blk_axi_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_axi_status_v7_t aes_blk_axi_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} axi_status */ + +/*! + * @addtogroup group995916 int_status + * @brief Offset = 0x18 + * @details Channel interrupt status register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The number of entries in the Command FIFO has gone below + * CHAN.DMA_WATERMARKS.COMMAND_FIFO_LOW (not sticky) + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * SW pushed (wrote) too many entries into the Command FIFO + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * An invalid opcode detected. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * A "flag" command has been executed. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Non-multiple of 16B data length. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Keys are disabled + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * CMAC Tag mismatch detected + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Key policy mismatch at load time + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys are disabled + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 13 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * CMAC Tag mismatch detected + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 14 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Key policy mismatch at load time + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 16 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 31:17 | Width = 15 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 15; + }; +} aes_blk_int_status_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The number of entries in the Command FIFO has gone below + * CHAN.DMA_WATERMARKS.COMMAND_FIFO_LOW (not sticky) + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * SW pushed (wrote) too many entries into the Command FIFO + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * An invalid opcode detected. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * A "flag" command has been executed. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Non-multiple of 16B data length. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Keys are disabled + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * CMAC Tag mismatch detected + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Key policy mismatch at load time + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys are disabled + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 13 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * CMAC Tag mismatch detected + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 14 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Key policy mismatch at load time + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 16 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 31:17 | Width = 15 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 15; + }; +} aes_blk_int_status_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The number of entries in the Command FIFO has gone below + * CHAN.DMA_WATERMARKS.COMMAND_FIFO_LOW (not sticky) + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * SW pushed (wrote) too many entries into the Command FIFO + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * An invalid opcode detected. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * A "flag" command has been executed. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Non-multiple of 16B data length. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Keys are disabled + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * CMAC Tag mismatch detected + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Key policy mismatch at load time + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys are disabled + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 13 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * CMAC Tag mismatch detected + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 14 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Key policy mismatch at load time + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 16 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 31:17 | Width = 15 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 15; + }; +} aes_blk_int_status_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The number of entries in the Command FIFO has gone below + * CHAN.DMA_WATERMARKS.COMMAND_FIFO_LOW (not sticky) + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * SW pushed (wrote) too many entries into the Command FIFO + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * An invalid opcode detected. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * A "flag" command has been executed. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Non-multiple of 16B data length. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Keys are disabled + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * CMAC Tag mismatch detected + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Key policy mismatch at load time + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * DAP random number generator has not been seeded + */ + uint32_t key_0_dpa_random_unseeded : 1; + + /*! + * Range = 13 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys are disabled + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 14 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * CMAC Tag mismatch detected + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Key policy mismatch at load time + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 16 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 17 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 18 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * DAP random number generator has not been seeded + */ + uint32_t key_1_dpa_random_unseeded : 1; + + /*! + * Range = 31:19 | Width = 13 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 13; + }; +} aes_blk_int_status_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * The number of entries in the Command FIFO has gone below + * CHAN.DMA_WATERMARKS.COMMAND_FIFO_LOW (not sticky) + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * SW pushed (wrote) too many entries into the Command FIFO + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * An invalid opcode detected. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * AXI responded with an "error", "retry" or "split" + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * A "flag" command has been executed. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Non-multiple of 16B data length. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Keys are disabled + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * CMAC Tag mismatch detected + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = write-once-clear | Default = 0x0 @n + * Key policy mismatch at load time + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * DAP random number generator has not been seeded + */ + uint32_t key_0_dpa_random_unseeded : 1; + + /*! + * Range = 13 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys are disabled + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 14 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * CMAC Tag mismatch detected + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Key policy mismatch at load time + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 16 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * Keys have expired + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 17 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * HDCP error detected + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 18 | Width = 1 | Access = write-once-clear | Default = 0x0 + * @n + * DAP random number generator has not been seeded + */ + uint32_t key_1_dpa_random_unseeded : 1; + + /*! + * Range = 31:19 | Width = 13 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 13; + }; +} aes_blk_int_status_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_int_status_v3_t aes_blk_int_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_int_status_v4_t aes_blk_int_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_int_status_v5_t aes_blk_int_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_int_status_v6_t aes_blk_int_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_int_status_v7_t aes_blk_int_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} int_status */ + +/*! + * @addtogroup group995938 int_enable + * @brief Offset = 0x1c + * @details Channel interrupt enable register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_LOW Interrupt. + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_OVERFLOW Interrupt. + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_COMMAND Interrupt. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_READ_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_WRITE_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable FLAG_COMMAND Interrupt. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_DATA_LENGTH Interrupt. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_DISABLED Interrupt. + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_POLICY_MISMATCH Interrupt. + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_HDCP_ERR Interrupt. + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_DISABLED Interrupt. + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 13 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 14 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_POLICY_MISMATCH Interrupt. + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 16 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_HDCP_ERR Interrupt. + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 31:17 | Width = 15 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 15; + }; +} aes_blk_int_enable_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_LOW Interrupt. + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_OVERFLOW Interrupt. + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_COMMAND Interrupt. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_READ_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_WRITE_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable FLAG_COMMAND Interrupt. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_DATA_LENGTH Interrupt. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_DISABLED Interrupt. + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_POLICY_MISMATCH Interrupt. + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_HDCP_ERR Interrupt. + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_DISABLED Interrupt. + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 13 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 14 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_POLICY_MISMATCH Interrupt. + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 16 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_HDCP_ERR Interrupt. + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 31:17 | Width = 15 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 15; + }; +} aes_blk_int_enable_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_LOW Interrupt. + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_OVERFLOW Interrupt. + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_COMMAND Interrupt. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_READ_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_WRITE_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable FLAG_COMMAND Interrupt. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_DATA_LENGTH Interrupt. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_DISABLED Interrupt. + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_POLICY_MISMATCH Interrupt. + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_HDCP_ERR Interrupt. + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_DISABLED Interrupt. + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 13 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 14 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_POLICY_MISMATCH Interrupt. + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 16 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_HDCP_ERR Interrupt. + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 31:17 | Width = 15 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 15; + }; +} aes_blk_int_enable_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_LOW Interrupt. + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_OVERFLOW Interrupt. + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_COMMAND Interrupt. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_READ_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_WRITE_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable FLAG_COMMAND Interrupt. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_DATA_LENGTH Interrupt. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_DISABLED Interrupt. + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_POLICY_MISMATCH Interrupt. + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_HDCP_ERR Interrupt. + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_DPA_RANDOM_UNSEEDED Interrupt. + */ + uint32_t key_0_dpa_random_unseeded : 1; + + /*! + * Range = 13 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_DISABLED Interrupt. + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 14 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_POLICY_MISMATCH Interrupt. + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 16 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 17 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_HDCP_ERR Interrupt. + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 18 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_DPA_RANDOM_UNSEEDED Interrupt. + */ + uint32_t key_1_dpa_random_unseeded : 1; + + /*! + * Range = 31:19 | Width = 13 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 13; + }; +} aes_blk_int_enable_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_LOW Interrupt. + */ + uint32_t command_fifo_low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable COMMAND_FIFO_OVERFLOW Interrupt. + */ + uint32_t command_fifo_overflow : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_COMMAND Interrupt. + */ + uint32_t invalid_command : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_READ_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_read_response_not_okay : 1; + + /*! + * Range = 4 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable AXI_WRITE_RESPONSE_NOT_OKAY Interrupt. + */ + uint32_t axi_write_response_not_okay : 1; + + /*! + * Range = 5 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable FLAG_COMMAND Interrupt. + */ + uint32_t flag_command : 1; + + /*! + * Range = 6 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable INVALID_DATA_LENGTH Interrupt. + */ + uint32_t invalid_data_length : 1; + + /*! + * Range = 7 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_DISABLED Interrupt. + */ + uint32_t key_0_disabled : 1; + + /*! + * Range = 8 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_0_cmac_tag_mismatch : 1; + + /*! + * Range = 9 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_POLICY_MISMATCH Interrupt. + */ + uint32_t key_0_policy_mismatch : 1; + + /*! + * Range = 10 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_0_invalid_at_use_time : 1; + + /*! + * Range = 11 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_HDCP_ERR Interrupt. + */ + uint32_t key_0_hdcp_err : 1; + + /*! + * Range = 12 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_0_DPA_RANDOM_UNSEEDED Interrupt. + */ + uint32_t key_0_dpa_random_unseeded : 1; + + /*! + * Range = 13 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_DISABLED Interrupt. + */ + uint32_t key_1_disabled : 1; + + /*! + * Range = 14 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_CMAC_TAG_MISMATCH Interrupt. + */ + uint32_t key_1_cmac_tag_mismatch : 1; + + /*! + * Range = 15 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_POLICY_MISMATCH Interrupt. + */ + uint32_t key_1_policy_mismatch : 1; + + /*! + * Range = 16 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_INVALID_AT_USE_TIME Interrupt. + */ + uint32_t key_1_invalid_at_use_time : 1; + + /*! + * Range = 17 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_HDCP_ERR Interrupt. + */ + uint32_t key_1_hdcp_err : 1; + + /*! + * Range = 18 | Width = 1 | Access = read-write | Default = 0x0 @n + * Enable KEY_1_DPA_RANDOM_UNSEEDED Interrupt. + */ + uint32_t key_1_dpa_random_unseeded : 1; + + /*! + * Range = 31:19 | Width = 13 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 13; + }; +} aes_blk_int_enable_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_int_enable_v3_t aes_blk_int_enable_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_int_enable_v4_t aes_blk_int_enable_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_int_enable_v5_t aes_blk_int_enable_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_int_enable_v6_t aes_blk_int_enable_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_int_enable_v7_t aes_blk_int_enable_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} int_enable */ + +/*! + * @addtogroup group995960 watermarks + * @brief Offset = 0x20 + * @details Watermarks for FIFO interrupts. + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 6:0 | Width = 7 | Access = read-write | Default = 0x0 @n + * Command FIFO Level below which the COMMAND_FIFO_LOW interrupt will + * be asserted + */ + uint32_t command_fifo_low : 7; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_watermarks_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 6:0 | Width = 7 | Access = read-write | Default = 0x0 @n + * Command FIFO Level below which the COMMAND_FIFO_LOW interrupt will + * be asserted + */ + uint32_t command_fifo_low : 7; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_watermarks_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 6:0 | Width = 7 | Access = read-write | Default = 0x0 @n + * Command FIFO Level below which the COMMAND_FIFO_LOW interrupt will + * be asserted + */ + uint32_t command_fifo_low : 7; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_watermarks_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 6:0 | Width = 7 | Access = read-write | Default = 0x0 @n + * Command FIFO Level below which the COMMAND_FIFO_LOW interrupt will + * be asserted + */ + uint32_t command_fifo_low : 7; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_watermarks_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 6:0 | Width = 7 | Access = read-write | Default = 0x0 @n + * Command FIFO Level below which the COMMAND_FIFO_LOW interrupt will + * be asserted + */ + uint32_t command_fifo_low : 7; + + /*! + * Range = 31:7 | Width = 25 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 25; + }; +} aes_blk_watermarks_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_watermarks_v3_t aes_blk_watermarks_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_watermarks_v4_t aes_blk_watermarks_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_watermarks_v5_t aes_blk_watermarks_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_watermarks_v6_t aes_blk_watermarks_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_watermarks_v7_t aes_blk_watermarks_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} watermarks */ + +/*! + * @addtogroup group995964 command_fifo_status + * @brief Offset = 0x24 + * @details Status information for the Command Queue + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO has gone below Low Watermark + */ + uint32_t low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x1 @n + * Command FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * Software overflowed Command FIFO. This bit is not sticky + */ + uint32_t overflow : 1; + + /*! + * Range = 7:4 | Width = 4 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 4; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the Command FIFO + */ + uint32_t level : 8; + + /*! + * Range = 22:16 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next command + */ + uint32_t read_pointer : 7; + + /*! + * Range = 23 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 1; + + /*! + * Range = 30:24 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next empty location + */ + uint32_t write_pointer : 7; + + /*! + * Range = 31 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd2 : 1; + }; +} aes_blk_command_fifo_status_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO has gone below Low Watermark + */ + uint32_t low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x1 @n + * Command FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * Software overflowed Command FIFO. This bit is not sticky + */ + uint32_t overflow : 1; + + /*! + * Range = 7:4 | Width = 4 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 4; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the Command FIFO + */ + uint32_t level : 8; + + /*! + * Range = 22:16 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next command + */ + uint32_t read_pointer : 7; + + /*! + * Range = 23 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 1; + + /*! + * Range = 30:24 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next empty location + */ + uint32_t write_pointer : 7; + + /*! + * Range = 31 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd2 : 1; + }; +} aes_blk_command_fifo_status_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO has gone below Low Watermark + */ + uint32_t low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x1 @n + * Command FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * Software overflowed Command FIFO. This bit is not sticky + */ + uint32_t overflow : 1; + + /*! + * Range = 7:4 | Width = 4 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 4; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the Command FIFO + */ + uint32_t level : 8; + + /*! + * Range = 22:16 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next command + */ + uint32_t read_pointer : 7; + + /*! + * Range = 23 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 1; + + /*! + * Range = 30:24 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next empty location + */ + uint32_t write_pointer : 7; + + /*! + * Range = 31 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd2 : 1; + }; +} aes_blk_command_fifo_status_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO has gone below Low Watermark + */ + uint32_t low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x1 @n + * Command FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * Software overflowed Command FIFO. This bit is not sticky + */ + uint32_t overflow : 1; + + /*! + * Range = 7:4 | Width = 4 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 4; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the Command FIFO + */ + uint32_t level : 8; + + /*! + * Range = 22:16 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next command + */ + uint32_t read_pointer : 7; + + /*! + * Range = 23 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 1; + + /*! + * Range = 30:24 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next empty location + */ + uint32_t write_pointer : 7; + + /*! + * Range = 31 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd2 : 1; + }; +} aes_blk_command_fifo_status_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO has gone below Low Watermark + */ + uint32_t low : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x1 @n + * Command FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * Command FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 3 | Width = 1 | Access = read-only | Default = 0x0 @n + * Software overflowed Command FIFO. This bit is not sticky + */ + uint32_t overflow : 1; + + /*! + * Range = 7:4 | Width = 4 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 4; + + /*! + * Range = 15:8 | Width = 8 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the Command FIFO + */ + uint32_t level : 8; + + /*! + * Range = 22:16 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next command + */ + uint32_t read_pointer : 7; + + /*! + * Range = 23 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 1; + + /*! + * Range = 30:24 | Width = 7 | Access = read-only | Default = 0x0 @n + * Pointer to next empty location + */ + uint32_t write_pointer : 7; + + /*! + * Range = 31 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd2 : 1; + }; +} aes_blk_command_fifo_status_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_command_fifo_status_v3_t aes_blk_command_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_command_fifo_status_v4_t aes_blk_command_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_command_fifo_status_v5_t aes_blk_command_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_command_fifo_status_v6_t aes_blk_command_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_command_fifo_status_v7_t aes_blk_command_fifo_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} command_fifo_status */ + +/*! + * @addtogroup group995976 history_fifo_status + * @brief Offset = 0x28 + * @details Status information for the DMA Debug FIFO + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * History FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * History FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 7:2 | Width = 6 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 6; + + /*! + * Range = 13:8 | Width = 6 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the History FIFO + */ + uint32_t level : 6; + + /*! + * Range = 15:14 | Width = 2 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 2; + + /*! + * Range = 20:16 | Width = 5 | Access = read-only | Default = 0x0 @n + * Pointer to next write location + */ + uint32_t write_pointer : 5; + + /*! + * Range = 31:21 | Width = 11 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd2 : 11; + }; +} aes_blk_history_fifo_status_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * History FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * History FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 7:2 | Width = 6 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 6; + + /*! + * Range = 13:8 | Width = 6 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the History FIFO + */ + uint32_t level : 6; + + /*! + * Range = 15:14 | Width = 2 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 2; + + /*! + * Range = 20:16 | Width = 5 | Access = read-only | Default = 0x0 @n + * Pointer to next write location + */ + uint32_t write_pointer : 5; + + /*! + * Range = 31:21 | Width = 11 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd2 : 11; + }; +} aes_blk_history_fifo_status_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * History FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * History FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 7:2 | Width = 6 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 6; + + /*! + * Range = 13:8 | Width = 6 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the History FIFO + */ + uint32_t level : 6; + + /*! + * Range = 15:14 | Width = 2 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 2; + + /*! + * Range = 20:16 | Width = 5 | Access = read-only | Default = 0x0 @n + * Pointer to next write location + */ + uint32_t write_pointer : 5; + + /*! + * Range = 31:21 | Width = 11 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd2 : 11; + }; +} aes_blk_history_fifo_status_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * History FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * History FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 7:2 | Width = 6 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 6; + + /*! + * Range = 13:8 | Width = 6 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the History FIFO + */ + uint32_t level : 6; + + /*! + * Range = 15:14 | Width = 2 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 2; + + /*! + * Range = 20:16 | Width = 5 | Access = read-only | Default = 0x0 @n + * Pointer to next write location + */ + uint32_t write_pointer : 5; + + /*! + * Range = 31:21 | Width = 11 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd2 : 11; + }; +} aes_blk_history_fifo_status_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * History FIFO is empty + */ + uint32_t empty : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * History FIFO is full + */ + uint32_t full : 1; + + /*! + * Range = 7:2 | Width = 6 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 6; + + /*! + * Range = 13:8 | Width = 6 | Access = read-only | Default = 0x0 @n + * Number of 4 byte words in the History FIFO + */ + uint32_t level : 6; + + /*! + * Range = 15:14 | Width = 2 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 2; + + /*! + * Range = 20:16 | Width = 5 | Access = read-only | Default = 0x0 @n + * Pointer to next write location + */ + uint32_t write_pointer : 5; + + /*! + * Range = 31:21 | Width = 11 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd2 : 11; + }; +} aes_blk_history_fifo_status_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_history_fifo_status_v3_t aes_blk_history_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_history_fifo_status_v4_t aes_blk_history_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_history_fifo_status_v5_t aes_blk_history_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_history_fifo_status_v6_t aes_blk_history_fifo_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_history_fifo_status_v7_t aes_blk_history_fifo_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} history_fifo_status */ + +/*! + * @addtogroup group995985 command_fifo_count + * @brief Offset = 0x2c + * @details Total count of commands since the Command FIFO was last enabled + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Number of commands popped from the Command FIFO since it was last + * turned on. (saturates at max) + */ + uint32_t total : 32; + }; +} aes_blk_command_fifo_count_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Number of commands popped from the Command FIFO since it was last + * turned on. (saturates at max) + */ + uint32_t total : 32; + }; +} aes_blk_command_fifo_count_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Number of commands popped from the Command FIFO since it was last + * turned on. (saturates at max) + */ + uint32_t total : 32; + }; +} aes_blk_command_fifo_count_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Number of commands popped from the Command FIFO since it was last + * turned on. (saturates at max) + */ + uint32_t total : 32; + }; +} aes_blk_command_fifo_count_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Number of commands popped from the Command FIFO since it was last + * turned on. (saturates at max) + */ + uint32_t total : 32; + }; +} aes_blk_command_fifo_count_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_command_fifo_count_v3_t aes_blk_command_fifo_count_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_command_fifo_count_v4_t aes_blk_command_fifo_count_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_command_fifo_count_v5_t aes_blk_command_fifo_count_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_command_fifo_count_v6_t aes_blk_command_fifo_count_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_command_fifo_count_v7_t aes_blk_command_fifo_count_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} command_fifo_count */ + +/*! + * @addtogroup group995988 flag_command + * @brief Offset = 0x30 + * @details Interrupt code that provides information about the flag interrupt + * that occurred. + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 15:0 | Width = 16 | Access = read-only | Default = 0x0 @n + * Interrupt code from the last flag command executed in the Command + * FIFO + */ + uint32_t code : 16; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_flag_command_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 15:0 | Width = 16 | Access = read-only | Default = 0x0 @n + * Interrupt code from the last flag command executed in the Command + * FIFO + */ + uint32_t code : 16; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_flag_command_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 15:0 | Width = 16 | Access = read-only | Default = 0x0 @n + * Interrupt code from the last flag command executed in the Command + * FIFO + */ + uint32_t code : 16; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_flag_command_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 15:0 | Width = 16 | Access = read-only | Default = 0x0 @n + * Interrupt code from the last flag command executed in the Command + * FIFO + */ + uint32_t code : 16; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_flag_command_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 15:0 | Width = 16 | Access = read-only | Default = 0x0 @n + * Interrupt code from the last flag command executed in the Command + * FIFO + */ + uint32_t code : 16; + + /*! + * Range = 31:16 | Width = 16 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd0 : 16; + }; +} aes_blk_flag_command_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_flag_command_v3_t aes_blk_flag_command_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_flag_command_v4_t aes_blk_flag_command_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_flag_command_v5_t aes_blk_flag_command_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_flag_command_v6_t aes_blk_flag_command_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_flag_command_v7_t aes_blk_flag_command_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} flag_command */ + +/*! + * @addtogroup group995992 skg_key + * @brief Offset = 0x34 + * @details Secure Key Generation Key + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Count + */ + uint32_t count : 32; + }; +} aes_blk_skg_key_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Count + */ + uint32_t count : 32; + }; +} aes_blk_skg_key_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Count + */ + uint32_t count : 32; + }; +} aes_blk_skg_key_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Count + */ + uint32_t count : 32; + }; +} aes_blk_skg_key_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Count + */ + uint32_t count : 32; + }; +} aes_blk_skg_key_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_skg_key_v3_t aes_blk_skg_key_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_skg_key_v4_t aes_blk_skg_key_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_skg_key_v5_t aes_blk_skg_key_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_skg_key_v6_t aes_blk_skg_key_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_skg_key_v7_t aes_blk_skg_key_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} skg_key */ + +/*! + * @addtogroup group995995 clear_fifos + * @brief Offset = 0x38 + * @details Clear COMMAND and HISTORY FIFOs + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Write 1 to this field to reset the contents of the Command and + * History FIFOs to zero. + */ + uint32_t reset : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_clear_fifos_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Write 1 to this field to reset the contents of the Command and + * History FIFOs to zero. + */ + uint32_t reset : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_clear_fifos_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Write 1 to this field to reset the contents of the Command and + * History FIFOs to zero. + */ + uint32_t reset : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_clear_fifos_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_clear_fifos_v5_t aes_blk_clear_fifos_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_clear_fifos_v6_t aes_blk_clear_fifos_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_clear_fifos_v7_t aes_blk_clear_fifos_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} clear_fifos */ + +/*! + * @addtogroup group995999 command_fifo + * @brief Offset = 0x200 + * @details Command FIFO. FIFO Depth is (128) Words + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = write-only | Default = 0x0 @n + * Command Word + */ + uint32_t push_word : 32; + }; +} aes_blk_command_fifo_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = write-only | Default = 0x0 @n + * Command Word + */ + uint32_t push_word : 32; + }; +} aes_blk_command_fifo_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = write-only | Default = 0x0 @n + * Command Word + */ + uint32_t push_word : 32; + }; +} aes_blk_command_fifo_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = write-only | Default = 0x0 @n + * Command Word + */ + uint32_t push_word : 32; + }; +} aes_blk_command_fifo_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = write-only | Default = 0x0 @n + * Command Word + */ + uint32_t push_word : 32; + }; +} aes_blk_command_fifo_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_command_fifo_v3_t aes_blk_command_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_command_fifo_v4_t aes_blk_command_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_command_fifo_v5_t aes_blk_command_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_command_fifo_v6_t aes_blk_command_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_command_fifo_v7_t aes_blk_command_fifo_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} command_fifo */ + +/*! + * @addtogroup group996003 history_fifo + * @brief Offset = 0x400 + * @details Last (32) Commands words + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Unconnected FIFO output. Command words should be read from + * HISTORY_FIFO - 0x3600 + */ + uint32_t pop_word : 32; + }; +} aes_blk_history_fifo_v3_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Unconnected FIFO output. Command words should be read from + * HISTORY_FIFO - 0x3600 + */ + uint32_t pop_word : 32; + }; +} aes_blk_history_fifo_v4_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Unconnected FIFO output. Command words should be read from + * HISTORY_FIFO - 0x3600 + */ + uint32_t pop_word : 32; + }; +} aes_blk_history_fifo_v5_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Unconnected FIFO output. Command words should be read from + * HISTORY_FIFO - 0x3600 + */ + uint32_t pop_word : 32; + }; +} aes_blk_history_fifo_v6_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * Unconnected FIFO output. Command words should be read from + * HISTORY_FIFO - 0x3600 + */ + uint32_t pop_word : 32; + }; +} aes_blk_history_fifo_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_blk_history_fifo_v3_t aes_blk_history_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_blk_history_fifo_v4_t aes_blk_history_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_blk_history_fifo_v5_t aes_blk_history_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_blk_history_fifo_v6_t aes_blk_history_fifo_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_blk_history_fifo_v7_t aes_blk_history_fifo_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} history_fifo */ + +/*! + * @addtogroup group570682 disable (AES_DISABLE) + * @brief Offset = 0x4 + * @details AES GID0, GID1, UID1 and Fairplay Descrambler Disable register + * @see @ref SAIRegister + * @{ + */ + +/*! + * @addtogroup group570683 id (disable_id) + * @brief Range = 2:0 | Width = 3 | Access = write-only | Default = 0x0 + * @details Write to the disable_id field to disable use of GID0, GID1, and + * UID1 keys until the next chip reset. + * @see @ref SAIField + * @{ + */ + +#ifdef SPDS_ENABLE_ENUMS +typedef enum +{ + /*! Write high to disable use of the GID1 key. */ + aes_blk_disable_id_gid1 = 4, + + /*! Write high to disable use of the GID0 key. */ + aes_blk_disable_id_gid0 = 2, + + /*! Write high to disable use of the UID1 key. */ + aes_blk_disable_id_uid1 = 1 +} aes_blk_disable_id_v1_t; +#endif /*! SPDS_ENABLE_ENUMS */ + +/*! @} id (disable_id) */ + +/*! + * @addtogroup group570689 id_disabled + * @brief Range = 10:8 | Width = 3 | Access = read-only | Default = 0x0 + * @details The id_disabled field indicates which keys are disabled. If the + * GID0, GID1, or UID1 keys are selected for use when disabled, then the key + * used in the AES operation is zero and an error interrupt is generated. + * This field is only cleared on a chip reset. + * @see @ref SAIField + * @{ + */ + +#ifdef SPDS_ENABLE_ENUMS +typedef enum +{ + /*! When set, the GID1 key is disabled. */ + aes_blk_disable_id_disabled_gid1_disabled = 4, + + /*! When set, the GID0 key is disabled. */ + aes_blk_disable_id_disabled_gid0_disabled = 2, + + /*! When set, the UID1 key is disabled. */ + aes_blk_disable_id_disabled_uid1_disabled = 1 +} aes_blk_disable_id_disabled_v1_t; +#endif /*! SPDS_ENABLE_ENUMS */ + +/*! @} id_disabled */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 2:0 | Width = 3 | Access = write-only | Default = 0x0 @n + * Write to the disable_id field to disable use of GID0, GID1, and + * UID1 keys until the next chip reset. + */ + uint32_t id : 3; + + /*! + * Range = 3 | Width = 1 | Access = write-only | Default = 0x0 @n + * Write to the disable_dsb field to disable use of the Fairplay + * descrambler until the next chip reset. + */ + uint32_t dsb : 1; + + /*! + * Range = 7:4 | Width = 4 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 4; + + /*! + * Range = 10:8 | Width = 3 | Access = read-only | Default = 0x0 @n + * The id_disabled field indicates which keys are disabled. If the + * GID0, GID1, or UID1 keys are selected for use when disabled, then + * the key used in the AES operation is zero and an error interrupt is + * generated. This field is only cleared on a chip reset. + */ + uint32_t id_disabled : 3; + + /*! + * Range = 11 | Width = 1 | Access = read-only | Default = 0x0 @n + * When set, the dsb_disabled field indicates that the Fairplay key + * descrambler is disabled. If the Fairplay key descrambler is + * selected for use when disabled, then the scrambling operation is + * bypassed and an error interrupt is generated. This field is only + * cleared on a chip reset. + */ + uint32_t dsb_disabled : 1; + + /*! + * Range = 31:12 | Width = 20 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd1 : 20; + }; +} aes_blk_disable_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_disable_v1_t aes_blk_disable_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} disable (AES_DISABLE) */ + +/*! + * @addtogroup group120226 txt_in_control (AES_TXT_IN_CONTROL) + * @brief Offset = 0x8 + * @details AES Cipher TXT_IN Control Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Set this field to start an AES cipher operation on the 16B block + * stored in the AES_TXT_IN0/1/2/3 registers. Before starting an AES + * cipher operation, software must check that the AES cipher engine is + * ready by checking the AES_TXT_IN_STATUS register. + */ + uint32_t txt_in_val : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Select the key to use for the AES cipher operation. Software is + * responsible for ensuring that the keys are configured and ready for + * use through the AES_KEY_IN registers. + */ + uint32_t txt_in_key_ctx : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-write | Default = 0x0 @n + * Select the IV to use for the AES CBC cipher operation. Software is + * responsible for specifying the IV through the AES_IV_IN registers + * when starting a new operation. When continuing an AES CBC cipher + * operation from the previous block, hardware updates the IV. + */ + uint32_t txt_in_iv_ctx : 1; + + /*! + * Range = 31:3 | Width = 29 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 29; + }; +} aes_blk_txt_in_control_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Select the key to use for the AES cipher operation. Software is + * responsible for ensuring that the keys are configured and ready for + * use through the AES_KEY_IN registers. + */ + uint32_t txt_in_key_ctx : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-write | Default = 0x0 @n + * Select the IV to use for the AES CBC cipher operation. Software is + * responsible for specifying the IV through the AES_IV_IN registers + * when starting a new operation. When continuing an AES CBC cipher + * operation from the previous block, hardware updates the IV. + */ + uint32_t txt_in_iv_ctx : 1; + + /*! + * Range = 31:3 | Width = 29 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 29; + }; +} aes_blk_txt_in_control_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_in_control_v1_t aes_blk_txt_in_control_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_txt_in_control_v2_t aes_blk_txt_in_control_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_in_control (AES_TXT_IN_CONTROL) */ + +/*! + * @addtogroup group120232 txt_in_status (AES_TXT_IN_STATUS) + * @brief Offset = 0xc + * @details AES Cipher TXT_IN Status register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * Check that the txt_in_rdy bit is set before writing to the + * AES_TXT_IN_CONTROL register to start an AES operation. + */ + uint32_t txt_in_rdy : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_txt_in_status_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * There are at least 16 bytes of space in the Tx fifo which can be + * written into. + */ + uint32_t tx_fifo_space_available : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_txt_in_status_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_in_status_v1_t aes_blk_txt_in_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_txt_in_status_v2_t aes_blk_txt_in_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_in_status (AES_TXT_IN_STATUS) */ + +/*! + * @addtogroup group570706 txt_in0 (AES_TXT_IN0) + * @brief Offset = 0x40 + * @details AES Cipher TXT_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * txt_in[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_in0_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_in0_v1_t aes_blk_txt_in0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_in0 (AES_TXT_IN0) */ + +/*! + * @addtogroup group570709 txt_in1 (AES_TXT_IN1) + * @brief Offset = 0x44 + * @details AES Cipher TXT_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * txt_in[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_in1_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_in1_v1_t aes_blk_txt_in1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_in1 (AES_TXT_IN1) */ + +/*! + * @addtogroup group570712 txt_in2 (AES_TXT_IN2) + * @brief Offset = 0x48 + * @details AES Cipher TXT_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * txt_in[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_in2_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_in2_v1_t aes_blk_txt_in2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_in2 (AES_TXT_IN2) */ + +/*! + * @addtogroup group570715 txt_in3 (AES_TXT_IN3) + * @brief Offset = 0x4c + * @details AES Cipher TXT_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * txt_in[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_in3_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_in3_v1_t aes_blk_txt_in3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_in3 (AES_TXT_IN3) */ + +/*! + * @addtogroup group120239 txt_out_status (AES_TXT_OUT_STATUS) + * @brief Offset = 0x50 + * @details AES Cipher TXT_OUT Status Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * When set, AES Cipher data may be read from the TXT_OUT and IV_OUT + * registers. + */ + uint32_t txt_out_val : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * Identifies which key was used for the AES cipher operation. + */ + uint32_t txt_out_key_ctx : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * Identifies which IV was used for the AES cipher operation. + */ + uint32_t txt_out_iv_ctx : 1; + + /*! + * Range = 31:3 | Width = 29 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 29; + }; +} aes_blk_txt_out_status_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * There are at least 16 bytes in the Rx fifo available for reading. + */ + uint32_t rx_fifo_data_available : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-only | Default = 0x0 @n + * Identifies which key was used for the AES cipher operation. + */ + uint32_t txt_out_key_ctx : 1; + + /*! + * Range = 2 | Width = 1 | Access = read-only | Default = 0x0 @n + * Identifies which IV was used for the AES cipher operation. + */ + uint32_t txt_out_iv_ctx : 1; + + /*! + * Range = 31:3 | Width = 29 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 29; + }; +} aes_blk_txt_out_status_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_out_status_v1_t aes_blk_txt_out_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_txt_out_status_v2_t aes_blk_txt_out_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_out_status (AES_TXT_OUT_STATUS) */ + +/*! + * @addtogroup group570724 txt_out0 (AES_TXT_OUT0) + * @brief Offset = 0x80 + * @details AES Cipher TXT_OUT[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * txt_out[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_out0_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_out0_v1_t aes_blk_txt_out0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_out0 (AES_TXT_OUT0) */ + +/*! + * @addtogroup group570727 txt_out1 (AES_TXT_OUT1) + * @brief Offset = 0x84 + * @details AES Cipher TXT_OUT[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * txt_out[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_out1_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_out1_v1_t aes_blk_txt_out1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_out1 (AES_TXT_OUT1) */ + +/*! + * @addtogroup group570730 txt_out2 (AES_TXT_OUT2) + * @brief Offset = 0x88 + * @details AES Cipher TXT_OUT[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * txt_out[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_out2_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_out2_v1_t aes_blk_txt_out2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_out2 (AES_TXT_OUT2) */ + +/*! + * @addtogroup group570733 txt_out3 (AES_TXT_OUT3) + * @brief Offset = 0x8c + * @details AES Cipher TXT_OUT[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * txt_out[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_txt_out3_v1_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_txt_out3_v1_t aes_blk_txt_out3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_out3 (AES_TXT_OUT3) */ + +/*! + * @addtogroup group120248 key_in_control (AES_KEY_IN_CONTROL) + * @brief Offset = 0x90 + * @details AES KEY_IN Control Register + * @see @ref SAIRegister + * @{ + */ + +/*! + * @addtogroup group120252 key_in_sel + * @brief Range = 5:4 | Width = 2 | Access = read-write | Default = 0x0 + * @details Selects which key to use as an input to the AES key configurator. + * @see @ref SAIField + * @{ + */ + +#ifdef SPDS_ENABLE_ENUMS +typedef enum +{ + /*! GID1 */ + aes_blk_key_in_control_key_in_sel_gid1 = 3, + + /*! GID0 */ + aes_blk_key_in_control_key_in_sel_gid0 = 2, + + /*! UID1 */ + aes_blk_key_in_control_key_in_sel_uid1 = 1, + + /*! Software key. Selects the key described by the AES_KEY_IN0-7 registers. */ + aes_blk_key_in_control_key_in_sel_soft = 0 +} aes_blk_key_in_control_key_in_sel_v2_t; +#endif /*! SPDS_ENABLE_ENUMS */ + +/*! @} key_in_sel */ + +/*! + * @addtogroup group120257 key_in_len + * @brief Range = 7:6 | Width = 2 | Access = read-write | Default = 0x0 + * @details Key context length + * @see @ref SAIField + * @{ + */ + +#ifdef SPDS_ENABLE_ENUMS +typedef enum +{ + /*! 256-bit */ + aes_blk_key_in_control_key_in_len_key256 = 2, + + /*! 192-bit */ + aes_blk_key_in_control_key_in_len_key192 = 1, + + /*! 128-bit */ + aes_blk_key_in_control_key_in_len_key128 = 0 +} aes_blk_key_in_control_key_in_len_v2_t; +#endif /*! SPDS_ENABLE_ENUMS */ + +/*! @} key_in_len */ + +/*! + * @addtogroup group120261 key_in_fun + * @brief Range = 10:8 | Width = 3 | Access = read-write | Default = 0x0 + * @details Key function + * @see @ref SAIField + * @{ + */ + +#ifdef SPDS_ENABLE_ENUMS +typedef enum +{ + /*! + * Legacy SKG mode. Under legacy SKG mode, the key unwrapper uses UID2 as + * a key and repeats AES operations on the input key for the number of + * iterations that is specified in the AES_SKG_KEY_CNT_IN register. When + * legacy SKG mode is selected, bit 0 is ignored. + */ + aes_blk_key_in_control_key_in_fun_skg = 4, + + /*! + * Fairplay key descrambler enabled. The Fairplay descrambler uses the + * 128b values stored in the AES_DSB_R1 and AES_DSB_R2 registers. + */ + aes_blk_key_in_control_key_in_fun_fairplay = 2, + + /*! Key unwrap enabled. */ + aes_blk_key_in_control_key_in_fun_unwrap = 1 +} aes_blk_key_in_control_key_in_fun_v2_t; +#endif /*! SPDS_ENABLE_ENUMS */ + +/*! @} key_in_fun */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Set this field to start an AES key configurator operation. Before + * starting an AES key configurator operation, software must check + * that the AES key configurator engine is ready by checking the + * AES_KEY_IN_STATUS register. + */ + uint32_t key_in_val : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Selects the key context that will be updated with the results of + * the AES key configurator operation. + */ + uint32_t key_in_ctx : 1; + + /*! + * Range = 3:2 | Width = 2 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 2; + + /*! + * Range = 5:4 | Width = 2 | Access = read-write | Default = 0x0 @n + * Selects which key to use as an input to the AES key configurator. + */ + uint32_t key_in_sel : 2; + + /*! + * Range = 7:6 | Width = 2 | Access = read-write | Default = 0x0 @n + * Key context length + */ + uint32_t key_in_len : 2; + + /*! + * Range = 10:8 | Width = 3 | Access = read-write | Default = 0x0 @n + * Key function + */ + uint32_t key_in_fun : 3; + + /*! + * Range = 11 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 1; + + /*! + * Range = 12 | Width = 1 | Access = read-write | Default = 0x0 @n + * When set, the key will be used for encryption. When cleared, the + * key will be used for decryption. + */ + uint32_t key_in_enc : 1; + + /*! + * Range = 13 | Width = 1 | Access = read-write | Default = 0x0 @n + * Block Cipher Mode: When set, the AES cipher is configured to + * support CBC mode. When cleared, the AES Cipher supports ECB mode. + */ + uint32_t key_in_mod : 1; + + /*! + * Range = 31:14 | Width = 18 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd2 : 18; + }; +} aes_blk_key_in_control_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Set this field to start an AES key configurator operation. Before + * starting an AES key configurator operation, software must check + * that the AES key configurator engine is ready by checking the + * AES_KEY_IN_STATUS register. + */ + uint32_t key_in_val : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Selects the key context that will be updated with the results of + * the AES key configurator operation. + */ + uint32_t key_in_ctx : 1; + + /*! + * Range = 3:2 | Width = 2 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 2; + + /*! + * Range = 5:4 | Width = 2 | Access = read-write | Default = 0x0 @n + * Selects which key to use as an input to the AES key configurator. + */ + uint32_t key_in_sel : 2; + + /*! + * Range = 7:6 | Width = 2 | Access = read-write | Default = 0x0 @n + * Key context length + */ + uint32_t key_in_len : 2; + + /*! + * Range = 10:8 | Width = 3 | Access = read-write | Default = 0x0 @n + * Key function + */ + uint32_t key_in_fun : 3; + + /*! + * Range = 11 | Width = 1 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd1 : 1; + + /*! + * Range = 12 | Width = 1 | Access = read-write | Default = 0x0 @n + * When set, the key will be used for encryption. When cleared, the + * key will be used for decryption. + */ + uint32_t key_in_enc : 1; + + /*! + * Range = 13 | Width = 1 | Access = read-write | Default = 0x0 @n + * Block Cipher Mode: When set, the AES cipher is configured to + * support CBC mode. When cleared, the AES Cipher supports ECB mode. + */ + uint32_t key_in_mod : 1; + + /*! + * Range = 31:14 | Width = 18 | Access = read-as-zero | Default = 0x0 + * @n + * Reserved + */ + uint32_t rsvd2 : 18; + }; +} aes_blk_key_in_control_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in_control_v1_t aes_blk_key_in_control_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in_control_v2_t aes_blk_key_in_control_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in_control (AES_KEY_IN_CONTROL) */ + +/*! + * @addtogroup group120270 key_in_status (AES_KEY_IN_STATUS) + * @brief Offset = 0x94 + * @details AES KEY_IN Status Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * When set, the AES Key configurator operation is complete and the + * key may be used by the AES Cipher engine. After starting a key + * configurator operation, software checks this register to determine + * that the key context is ready for use. + */ + uint32_t key_in_rdy : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_key_in_status_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x1 @n + * When set, the AES Key configurator operation is complete and the + * key may be used by the AES Cipher engine. After starting a key + * configurator operation, software checks this register to determine + * that the key context is ready for use. + */ + uint32_t key_in_rdy : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_key_in_status_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in_status_v1_t aes_blk_key_in_status_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in_status_v2_t aes_blk_key_in_status_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in_status (AES_KEY_IN_STATUS) */ + +/*! + * @addtogroup group120274 key_in0 (AES_KEY_IN0) + * @brief Offset = 0xc0 + * @details AES KEY_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in0_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in0_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in0_v1_t aes_blk_key_in0_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in0_v2_t aes_blk_key_in0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in0 (AES_KEY_IN0) */ + +/*! + * @addtogroup group120277 key_in1 (AES_KEY_IN1) + * @brief Offset = 0xc4 + * @details AES KEY_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in1_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in1_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in1_v1_t aes_blk_key_in1_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in1_v2_t aes_blk_key_in1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in1 (AES_KEY_IN1) */ + +/*! + * @addtogroup group120280 key_in2 (AES_KEY_IN2) + * @brief Offset = 0xc8 + * @details AES KEY_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in2_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in2_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in2_v1_t aes_blk_key_in2_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in2_v2_t aes_blk_key_in2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in2 (AES_KEY_IN2) */ + +/*! + * @addtogroup group120283 key_in3 (AES_KEY_IN3) + * @brief Offset = 0xcc + * @details AES KEY_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in3_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in3_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in3_v1_t aes_blk_key_in3_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in3_v2_t aes_blk_key_in3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in3 (AES_KEY_IN3) */ + +/*! + * @addtogroup group120286 key_in4 (AES_KEY_IN4) + * @brief Offset = 0xd0 + * @details AES KEY_IN[159:128] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[159:128] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in4_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[159:128] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in4_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in4_v1_t aes_blk_key_in4_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in4_v2_t aes_blk_key_in4_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in4 (AES_KEY_IN4) */ + +/*! + * @addtogroup group120289 key_in5 (AES_KEY_IN5) + * @brief Offset = 0xd4 + * @details AES KEY_IN[191:160] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[191:160] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in5_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[191:160] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in5_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in5_v1_t aes_blk_key_in5_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in5_v2_t aes_blk_key_in5_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in5 (AES_KEY_IN5) */ + +/*! + * @addtogroup group120292 key_in6 (AES_KEY_IN6) + * @brief Offset = 0xd8 + * @details AES KEY_IN[223:192] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[223:192] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in6_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[223:192] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in6_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in6_v1_t aes_blk_key_in6_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in6_v2_t aes_blk_key_in6_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in6 (AES_KEY_IN6) */ + +/*! + * @addtogroup group120295 key_in7 (AES_KEY_IN7) + * @brief Offset = 0xdc + * @details AES KEY_IN[255:224] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[255:224] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in7_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * key_in[255:224] + */ + uint32_t fld : 32; + }; +} aes_blk_key_in7_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_key_in7_v1_t aes_blk_key_in7_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_key_in7_v2_t aes_blk_key_in7_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} key_in7 (AES_KEY_IN7) */ + +/*! + * @addtogroup group120298 iv_in_control (AES_IV_IN_CONTROL) + * @brief Offset = 0xe0 + * @details AES IV_IN Control Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Set this field to load the IV stored in the AES_IV_IN registers to + * the IV context specified by the iv_in_ctx field. + */ + uint32_t iv_in_val : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Selects which IV context is updated + */ + uint32_t iv_in_ctx : 1; + + /*! + * Range = 31:2 | Width = 30 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 30; + }; +} aes_blk_iv_in_control_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = write-auto-clear | Default = 0x0 @n + * Set this field to load the IV stored in the AES_IV_IN registers to + * the IV context specified by the iv_in_ctx field. + */ + uint32_t iv_in_val : 1; + + /*! + * Range = 1 | Width = 1 | Access = read-write | Default = 0x0 @n + * Selects which IV context is updated + */ + uint32_t iv_in_ctx : 1; + + /*! + * Range = 31:2 | Width = 30 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 30; + }; +} aes_blk_iv_in_control_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv_in_control_v1_t aes_blk_iv_in_control_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv_in_control_v2_t aes_blk_iv_in_control_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv_in_control (AES_IV_IN_CONTROL) */ + +/*! + * @addtogroup group120303 iv_in0 (AES_IV_IN0) + * @brief Offset = 0x100 + * @details AES IV_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in0_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in0_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv_in0_v1_t aes_blk_iv_in0_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv_in0_v2_t aes_blk_iv_in0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv_in0 (AES_IV_IN0) */ + +/*! + * @addtogroup group120306 iv_in1 (AES_IV_IN1) + * @brief Offset = 0x104 + * @details AES IV_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in1_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in1_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv_in1_v1_t aes_blk_iv_in1_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv_in1_v2_t aes_blk_iv_in1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv_in1 (AES_IV_IN1) */ + +/*! + * @addtogroup group120309 iv_in2 (AES_IV_IN2) + * @brief Offset = 0x108 + * @details AES IV_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in2_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in2_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv_in2_v1_t aes_blk_iv_in2_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv_in2_v2_t aes_blk_iv_in2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv_in2 (AES_IV_IN2) */ + +/*! + * @addtogroup group120312 iv_in3 (AES_IV_IN3) + * @brief Offset = 0x10c + * @details AES IV_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in3_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * iv_in[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_iv_in3_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv_in3_v1_t aes_blk_iv_in3_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv_in3_v2_t aes_blk_iv_in3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv_in3 (AES_IV_IN3) */ + +/*! + * @addtogroup group120315 iv0_out0 (AES_IV0_OUT0) + * @brief Offset = 0x140 + * @details AES IV0_OUT[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[31:0] + */ + uint32_t iv_out0 : 32; + }; +} aes_blk_iv0_out0_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[31:0] + */ + uint32_t iv_out0 : 32; + }; +} aes_blk_iv0_out0_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv0_out0_v1_t aes_blk_iv0_out0_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv0_out0_v2_t aes_blk_iv0_out0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv0_out0 (AES_IV0_OUT0) */ + +/*! + * @addtogroup group120318 iv0_out1 (AES_IV0_OUT1) + * @brief Offset = 0x144 + * @details AES IV0_OUT[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[63:32] + */ + uint32_t iv_out1 : 32; + }; +} aes_blk_iv0_out1_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[63:32] + */ + uint32_t iv_out1 : 32; + }; +} aes_blk_iv0_out1_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv0_out1_v1_t aes_blk_iv0_out1_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv0_out1_v2_t aes_blk_iv0_out1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv0_out1 (AES_IV0_OUT1) */ + +/*! + * @addtogroup group120321 iv0_out2 (AES_IV0_OUT2) + * @brief Offset = 0x148 + * @details AES IV0_OUT[96:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[95:64] + */ + uint32_t iv_out2 : 32; + }; +} aes_blk_iv0_out2_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[95:64] + */ + uint32_t iv_out2 : 32; + }; +} aes_blk_iv0_out2_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv0_out2_v1_t aes_blk_iv0_out2_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv0_out2_v2_t aes_blk_iv0_out2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv0_out2 (AES_IV0_OUT2) */ + +/*! + * @addtogroup group120324 iv0_out3 (AES_IV0_OUT3) + * @brief Offset = 0x14c + * @details AES IV0_OUT[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[127:96] + */ + uint32_t iv_out3 : 32; + }; +} aes_blk_iv0_out3_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV0_OUT[127:96] + */ + uint32_t iv_out3 : 32; + }; +} aes_blk_iv0_out3_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv0_out3_v1_t aes_blk_iv0_out3_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv0_out3_v2_t aes_blk_iv0_out3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv0_out3 (AES_IV0_OUT3) */ + +/*! + * @addtogroup group120327 iv1_out0 (AES_IV1_OUT0) + * @brief Offset = 0x150 + * @details AES IV1_OUT[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[31:0] + */ + uint32_t iv_out0 : 32; + }; +} aes_blk_iv1_out0_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[31:0] + */ + uint32_t iv_out0 : 32; + }; +} aes_blk_iv1_out0_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv1_out0_v1_t aes_blk_iv1_out0_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv1_out0_v2_t aes_blk_iv1_out0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv1_out0 (AES_IV1_OUT0) */ + +/*! + * @addtogroup group120330 iv1_out1 (AES_IV1_OUT1) + * @brief Offset = 0x154 + * @details AES IV1_OUT[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[63:32] + */ + uint32_t iv_out1 : 32; + }; +} aes_blk_iv1_out1_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[63:32] + */ + uint32_t iv_out1 : 32; + }; +} aes_blk_iv1_out1_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv1_out1_v1_t aes_blk_iv1_out1_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv1_out1_v2_t aes_blk_iv1_out1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv1_out1 (AES_IV1_OUT1) */ + +/*! + * @addtogroup group120333 iv1_out2 (AES_IV1_OUT2) + * @brief Offset = 0x158 + * @details AES IV1_OUT[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[95:64] + */ + uint32_t iv_out2 : 32; + }; +} aes_blk_iv1_out2_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[95:64] + */ + uint32_t iv_out2 : 32; + }; +} aes_blk_iv1_out2_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv1_out2_v1_t aes_blk_iv1_out2_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv1_out2_v2_t aes_blk_iv1_out2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv1_out2 (AES_IV1_OUT2) */ + +/*! + * @addtogroup group120336 iv1_out3 (AES_IV1_OUT3) + * @brief Offset = 0x15c + * @details AES IV1_OUT[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[127:96] + */ + uint32_t iv_out3 : 32; + }; +} aes_blk_iv1_out3_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * IV1_OUT[127:96] + */ + uint32_t iv_out3 : 32; + }; +} aes_blk_iv1_out3_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_iv1_out3_v1_t aes_blk_iv1_out3_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_iv1_out3_v2_t aes_blk_iv1_out3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} iv1_out3 (AES_IV1_OUT3) */ + +/*! + * @addtogroup group120339 skg_key_cnt_in (AES_SKG_KEY_CNT_IN) + * @brief Offset = 0x160 + * @details AES SKG_KEY_CNT_IN Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * This register specifies the number of AES operations + * (skg_key_cnt_in+1) that are performed by legacy SKG unwrap logic. + * This field can also be used to abort SKG operations by writing 0 to + * this register + */ + uint32_t fld : 32; + }; +} aes_blk_skg_key_cnt_in_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * This register specifies the number of AES operations + * (skg_key_cnt_in+1) that are performed by legacy SKG unwrap logic. + * This field can also be used to abort SKG operations by writing 0 to + * this register + */ + uint32_t fld : 32; + }; +} aes_blk_skg_key_cnt_in_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_skg_key_cnt_in_v1_t aes_blk_skg_key_cnt_in_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_skg_key_cnt_in_v2_t aes_blk_skg_key_cnt_in_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} skg_key_cnt_in (AES_SKG_KEY_CNT_IN) */ + +/*! + * @addtogroup group120342 skg_key_cnt_out (AES_SKG_KEY_CNT_OUT) + * @brief Offset = 0x164 + * @details AES SKG_KEY_CNT_OUT Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * This register specifies the number of AES operations that have been + * performed during legacy SKG unwrap. + */ + uint32_t skg_key_cnt : 32; + }; +} aes_blk_skg_key_cnt_out_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * This register specifies the number of AES operations that have been + * performed during legacy SKG unwrap. + */ + uint32_t skg_key_cnt : 32; + }; +} aes_blk_skg_key_cnt_out_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_skg_key_cnt_out_v1_t aes_blk_skg_key_cnt_out_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_skg_key_cnt_out_v2_t aes_blk_skg_key_cnt_out_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} skg_key_cnt_out (AES_SKG_KEY_CNT_OUT) */ + +/*! + * @addtogroup group120345 dsb_r1_in0 (AES_DSB_R1_IN0) + * @brief Offset = 0x180 + * @details AES DSB_R1_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in0_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in0_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r1_in0_v1_t aes_blk_dsb_r1_in0_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r1_in0_v2_t aes_blk_dsb_r1_in0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r1_in0 (AES_DSB_R1_IN0) */ + +/*! + * @addtogroup group120348 dsb_r1_in1 (AES_DSB_R1_IN1) + * @brief Offset = 0x184 + * @details AES DSB_R1_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in1_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in1_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r1_in1_v1_t aes_blk_dsb_r1_in1_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r1_in1_v2_t aes_blk_dsb_r1_in1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r1_in1 (AES_DSB_R1_IN1) */ + +/*! + * @addtogroup group120351 dsb_r1_in2 (AES_DSB_R1_IN2) + * @brief Offset = 0x188 + * @details AES DSB_R1_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in2_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in2_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r1_in2_v1_t aes_blk_dsb_r1_in2_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r1_in2_v2_t aes_blk_dsb_r1_in2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r1_in2 (AES_DSB_R1_IN2) */ + +/*! + * @addtogroup group120354 dsb_r1_in3 (AES_DSB_R1_IN3) + * @brief Offset = 0x18c + * @details AES DSB_R1_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in3_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R1_IN[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r1_in3_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r1_in3_v1_t aes_blk_dsb_r1_in3_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r1_in3_v2_t aes_blk_dsb_r1_in3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r1_in3 (AES_DSB_R1_IN3) */ + +/*! + * @addtogroup group120357 dsb_r2_in0 (AES_DSB_R2_IN0) + * @brief Offset = 0x1c0 + * @details AES DSB_R2_IN[31:0] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in0_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[31:0] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in0_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r2_in0_v1_t aes_blk_dsb_r2_in0_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r2_in0_v2_t aes_blk_dsb_r2_in0_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r2_in0 (AES_DSB_R2_IN0) */ + +/*! + * @addtogroup group120360 dsb_r2_in1 (AES_DSB_R2_IN1) + * @brief Offset = 0x1c4 + * @details AES DSB_R2_IN[63:32] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in1_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[63:32] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in1_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r2_in1_v1_t aes_blk_dsb_r2_in1_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r2_in1_v2_t aes_blk_dsb_r2_in1_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r2_in1 (AES_DSB_R2_IN1) */ + +/*! + * @addtogroup group120363 dsb_r2_in2 (AES_DSB_R2_IN2) + * @brief Offset = 0x1c8 + * @details AES DSB_R2_IN[95:64] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in2_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[95:64] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in2_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r2_in2_v1_t aes_blk_dsb_r2_in2_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r2_in2_v2_t aes_blk_dsb_r2_in2_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r2_in2 (AES_DSB_R2_IN2) */ + +/*! + * @addtogroup group120366 dsb_r2_in3 (AES_DSB_R2_IN3) + * @brief Offset = 0x1cc + * @details AES DSB_R2_IN[127:96] Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in3_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-write | Default = 0x0 @n + * DSB_R2_IN[127:96] + */ + uint32_t fld : 32; + }; +} aes_blk_dsb_r2_in3_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_dsb_r2_in3_v1_t aes_blk_dsb_r2_in3_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_dsb_r2_in3_v2_t aes_blk_dsb_r2_in3_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} dsb_r2_in3 (AES_DSB_R2_IN3) */ + +/*! + * @addtogroup group120369 err (AES_ERR) + * @brief Offset = 0x1d0 + * @details AES Error Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * If the GID0, GID1, UID1, or Fairplay key descrambler is selected + * for use when disabled, then the error bit is set. The error bit is + * sticky and is only cleared on a chip reset. + */ + uint32_t fld : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_err_v1_t; + +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 0 | Width = 1 | Access = read-only | Default = 0x0 @n + * If the GID0, GID1, UID1, UID2, or Fairplay key descrambler is + * selected for use when disabled, then the error bit is set. The + * error bit is sticky and is only cleared on a reset. + */ + uint32_t fld : 1; + + /*! + * Range = 31:1 | Width = 31 | Access = read-as-zero | Default = 0x0 @n + * Reserved + */ + uint32_t rsvd0 : 31; + }; +} aes_blk_err_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_blk_err_v1_t aes_blk_err_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_err_v2_t aes_blk_err_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} err (AES_ERR) */ + +/*! + * @addtogroup group120236 txt_in_data (AES_TXT_IN_DATA) + * @brief Offset = 0x40 + * @details AES Cipher TXT_IN Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = write_only | Default = 0x0 @n + * txt_in to fifo + */ + uint32_t txt_in : 32; + }; +} aes_blk_txt_in_data_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_txt_in_data_v2_t aes_blk_txt_in_data_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_in_data (AES_TXT_IN_DATA) */ + +/*! + * @addtogroup group120245 txt_out_data (AES_TXT_OUT_DATA) + * @brief Offset = 0x80 + * @details AES Cipher TXT_OUT Register + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; + struct + { + /*! + * Range = 31:0 | Width = 32 | Access = read-only | Default = 0x0 @n + * txt_out from fifo + */ + uint32_t txt_out : 32; + }; +} aes_blk_txt_out_data_v2_t; + +#if SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_blk_txt_out_data_v2_t aes_blk_txt_out_data_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} txt_out_data (AES_TXT_OUT_DATA) */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef struct +{ + /*! + * Offset = 0x0 @n + * IP Implementation Version + */ + aes_blk_version_v3_t version; + + /*! + * Offset = 0x4 @n + * Configuration register + */ + aes_blk_config_v3_t config; + + /*! + * Offset = 0x8 @n + * Control Register + */ + aes_blk_control_v3_t control; + + /*! + * Offset = 0xc @n + * Channel status register + */ + aes_blk_status_v3_t status; + + /*! + * Offset = 0x10 @n + * Current Key IDs + */ + aes_blk_key_id_v3_t key_id; + + /*! + * Offset = 0x14 @n + * AXI status register + */ + aes_blk_axi_status_v3_t axi_status; + + /*! + * Offset = 0x18 @n + * Channel interrupt status register + */ + aes_blk_int_status_v3_t int_status; + + /*! + * Offset = 0x1c @n + * Channel interrupt enable register + */ + aes_blk_int_enable_v3_t int_enable; + + /*! + * Offset = 0x20 @n + * Watermarks for FIFO interrupts. + */ + aes_blk_watermarks_v3_t watermarks; + + /*! + * Offset = 0x24 @n + * Status information for the Command Queue + */ + aes_blk_command_fifo_status_v3_t command_fifo_status; + + /*! + * Offset = 0x28 @n + * Status information for the DMA Debug FIFO + */ + aes_blk_history_fifo_status_v3_t history_fifo_status; + + /*! + * Offset = 0x2c @n + * Total count of commands since the Command FIFO was last enabled + */ + aes_blk_command_fifo_count_v3_t command_fifo_count; + + /*! + * Offset = 0x30 @n + * Interrupt code that provides information about the flag interrupt that + * occurred. + */ + aes_blk_flag_command_v3_t flag_command; + + /*! + * Offset = 0x34 @n + * Secure Key Generation Key + */ + aes_blk_skg_key_v3_t skg_key; + uint8_t rsvd0[200]; + + /*! + * Offset = 0x100 @n + * Command FIFO. FIFO Depth is (128) Words + */ + aes_blk_command_fifo_v3_t command_fifo; + uint8_t rsvd1[252]; + + /*! + * Offset = 0x200 @n + * Last (32) Commands words + */ + aes_blk_history_fifo_v3_t history_fifo; +} aes_blk_v3_t; +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} blk (AES) */ + +/*! + * @addtogroup group581457 command_fifo_direct_access + * @brief Offset = 0x4000 + * @details Direct read access to 128 X 32 Command FIFO + * @see @ref SAIAddressBlock + * @{ + */ + +/*! + * @addtogroup group581458 word + * @brief Offset = 0x0 + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint64_t raw[2]; +} aes_command_fifo_direct_access_word_v3_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_command_fifo_direct_access_word_v3_t aes_command_fifo_direct_access_word_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} word */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef struct +{ + /*! Offset = 0x0 */ + aes_command_fifo_direct_access_word_v3_t word; +} aes_command_fifo_direct_access_v3_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_command_fifo_direct_access_v3_t aes_command_fifo_direct_access_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} command_fifo_direct_access */ + +/*! + * @addtogroup group581460 history_fifo_direct_access + * @brief Offset = 0x4600 + * @details Direct read access to 32 word History FIFO + * @see @ref SAIAddressBlock + * @{ + */ + +/*! + * @addtogroup group581461 command + * @brief Offset = 0x0 + * @details Command Word Data + * @see @ref SAIRegister + * @{ + */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef union +{ + uint32_t raw; +} aes_history_fifo_direct_access_command_v3_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_history_fifo_direct_access_command_v3_t aes_history_fifo_direct_access_command_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} command */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef struct +{ + /*! + * Offset = 0x0 @n + * Command Word Data + */ + aes_history_fifo_direct_access_command_v3_t command; +} aes_history_fifo_direct_access_v3_t; + +#if SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_history_fifo_direct_access_v3_t aes_history_fifo_direct_access_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} history_fifo_direct_access */ + +#ifdef SPDS_ENABLE_STRUCTS +typedef struct +{ + /*! + * Offset = 0x0 @n + * AES Status Register + */ + aes_blk_status_v1_t status; + + /*! + * Offset = 0x4 @n + * AES GID0, GID1, UID1 and Fairplay Descrambler Disable register + */ + aes_blk_disable_v1_t disable; + + /*! + * Offset = 0x8 @n + * AES Cipher TXT_IN Control Register + */ + aes_blk_txt_in_control_v1_t txt_in_control; + + /*! + * Offset = 0xc @n + * AES Cipher TXT_IN Status register + */ + aes_blk_txt_in_status_v1_t txt_in_status; + uint8_t rsvd0[48]; + + /*! + * Offset = 0x40 @n + * AES Cipher TXT_IN[31:0] Register + */ + aes_blk_txt_in0_v1_t txt_in0; + + /*! + * Offset = 0x44 @n + * AES Cipher TXT_IN[63:32] Register + */ + aes_blk_txt_in1_v1_t txt_in1; + + /*! + * Offset = 0x48 @n + * AES Cipher TXT_IN[95:64] Register + */ + aes_blk_txt_in2_v1_t txt_in2; + + /*! + * Offset = 0x4c @n + * AES Cipher TXT_IN[127:96] Register + */ + aes_blk_txt_in3_v1_t txt_in3; + + /*! + * Offset = 0x50 @n + * AES Cipher TXT_OUT Status Register + */ + aes_blk_txt_out_status_v1_t txt_out_status; + uint8_t rsvd1[44]; + + /*! + * Offset = 0x80 @n + * AES Cipher TXT_OUT[31:0] Register + */ + aes_blk_txt_out0_v1_t txt_out0; + + /*! + * Offset = 0x84 @n + * AES Cipher TXT_OUT[63:32] Register + */ + aes_blk_txt_out1_v1_t txt_out1; + + /*! + * Offset = 0x88 @n + * AES Cipher TXT_OUT[95:64] Register + */ + aes_blk_txt_out2_v1_t txt_out2; + + /*! + * Offset = 0x8c @n + * AES Cipher TXT_OUT[127:96] Register + */ + aes_blk_txt_out3_v1_t txt_out3; + + /*! + * Offset = 0x90 @n + * AES KEY_IN Control Register + */ + aes_blk_key_in_control_v1_t key_in_control; + + /*! + * Offset = 0x94 @n + * AES KEY_IN Status Register + */ + aes_blk_key_in_status_v1_t key_in_status; + uint8_t rsvd2[40]; + + /*! + * Offset = 0xc0 @n + * AES KEY_IN[31:0] Register + */ + aes_blk_key_in0_v1_t key_in0; + + /*! + * Offset = 0xc4 @n + * AES KEY_IN[63:32] Register + */ + aes_blk_key_in1_v1_t key_in1; + + /*! + * Offset = 0xc8 @n + * AES KEY_IN[95:64] Register + */ + aes_blk_key_in2_v1_t key_in2; + + /*! + * Offset = 0xcc @n + * AES KEY_IN[127:96] Register + */ + aes_blk_key_in3_v1_t key_in3; + + /*! + * Offset = 0xd0 @n + * AES KEY_IN[159:128] Register + */ + aes_blk_key_in4_v1_t key_in4; + + /*! + * Offset = 0xd4 @n + * AES KEY_IN[191:160] Register + */ + aes_blk_key_in5_v1_t key_in5; + + /*! + * Offset = 0xd8 @n + * AES KEY_IN[223:192] Register + */ + aes_blk_key_in6_v1_t key_in6; + + /*! + * Offset = 0xdc @n + * AES KEY_IN[255:224] Register + */ + aes_blk_key_in7_v1_t key_in7; + + /*! + * Offset = 0xe0 @n + * AES IV_IN Control Register + */ + aes_blk_iv_in_control_v1_t iv_in_control; + uint8_t rsvd3[28]; + + /*! + * Offset = 0x100 @n + * AES IV_IN[31:0] Register + */ + aes_blk_iv_in0_v1_t iv_in0; + + /*! + * Offset = 0x104 @n + * AES IV_IN[63:32] Register + */ + aes_blk_iv_in1_v1_t iv_in1; + + /*! + * Offset = 0x108 @n + * AES IV_IN[95:64] Register + */ + aes_blk_iv_in2_v1_t iv_in2; + + /*! + * Offset = 0x10c @n + * AES IV_IN[127:96] Register + */ + aes_blk_iv_in3_v1_t iv_in3; + uint8_t rsvd4[48]; + + /*! + * Offset = 0x140 @n + * AES IV0_OUT[31:0] Register + */ + aes_blk_iv0_out0_v1_t iv0_out0; + + /*! + * Offset = 0x144 @n + * AES IV0_OUT[63:32] Register + */ + aes_blk_iv0_out1_v1_t iv0_out1; + + /*! + * Offset = 0x148 @n + * AES IV0_OUT[96:64] Register + */ + aes_blk_iv0_out2_v1_t iv0_out2; + + /*! + * Offset = 0x14c @n + * AES IV0_OUT[127:96] Register + */ + aes_blk_iv0_out3_v1_t iv0_out3; + + /*! + * Offset = 0x150 @n + * AES IV1_OUT[31:0] Register + */ + aes_blk_iv1_out0_v1_t iv1_out0; + + /*! + * Offset = 0x154 @n + * AES IV1_OUT[63:32] Register + */ + aes_blk_iv1_out1_v1_t iv1_out1; + + /*! + * Offset = 0x158 @n + * AES IV1_OUT[95:64] Register + */ + aes_blk_iv1_out2_v1_t iv1_out2; + + /*! + * Offset = 0x15c @n + * AES IV1_OUT[127:96] Register + */ + aes_blk_iv1_out3_v1_t iv1_out3; + + /*! + * Offset = 0x160 @n + * AES SKG_KEY_CNT_IN Register + */ + aes_blk_skg_key_cnt_in_v1_t skg_key_cnt_in; + + /*! + * Offset = 0x164 @n + * AES SKG_KEY_CNT_OUT Register + */ + aes_blk_skg_key_cnt_out_v1_t skg_key_cnt_out; + uint8_t rsvd5[24]; + + /*! + * Offset = 0x180 @n + * AES DSB_R1_IN[31:0] Register + */ + aes_blk_dsb_r1_in0_v1_t dsb_r1_in0; + + /*! + * Offset = 0x184 @n + * AES DSB_R1_IN[63:32] Register + */ + aes_blk_dsb_r1_in1_v1_t dsb_r1_in1; + + /*! + * Offset = 0x188 @n + * AES DSB_R1_IN[95:64] Register + */ + aes_blk_dsb_r1_in2_v1_t dsb_r1_in2; + + /*! + * Offset = 0x18c @n + * AES DSB_R1_IN[127:96] Register + */ + aes_blk_dsb_r1_in3_v1_t dsb_r1_in3; + uint8_t rsvd6[48]; + + /*! + * Offset = 0x1c0 @n + * AES DSB_R2_IN[31:0] Register + */ + aes_blk_dsb_r2_in0_v1_t dsb_r2_in0; + + /*! + * Offset = 0x1c4 @n + * AES DSB_R2_IN[63:32] Register + */ + aes_blk_dsb_r2_in1_v1_t dsb_r2_in1; + + /*! + * Offset = 0x1c8 @n + * AES DSB_R2_IN[95:64] Register + */ + aes_blk_dsb_r2_in2_v1_t dsb_r2_in2; + + /*! + * Offset = 0x1cc @n + * AES DSB_R2_IN[127:96] Register + */ + aes_blk_dsb_r2_in3_v1_t dsb_r2_in3; + + /*! + * Offset = 0x1d0 @n + * AES Error Register + */ + aes_blk_err_v1_t err; +} aes_v1_t; + +typedef struct +{ + /*! + * Offset = 0x0 @n + * AES Status Register + */ + aes_blk_status_v2_t status; + uint8_t rsvd0[4]; + + /*! + * Offset = 0x8 @n + * AES Cipher TXT_IN Control Register + */ + aes_blk_txt_in_control_v2_t txt_in_control; + + /*! + * Offset = 0xc @n + * AES Cipher TXT_IN Status register + */ + aes_blk_txt_in_status_v2_t txt_in_status; + uint8_t rsvd1[48]; + + /*! + * Offset = 0x40 @n + * AES Cipher TXT_IN Register + */ + aes_blk_txt_in_data_v2_t txt_in_data; + uint8_t rsvd2[12]; + + /*! + * Offset = 0x50 @n + * AES Cipher TXT_OUT Status Register + */ + aes_blk_txt_out_status_v2_t txt_out_status; + uint8_t rsvd3[44]; + + /*! + * Offset = 0x80 @n + * AES Cipher TXT_OUT Register + */ + aes_blk_txt_out_data_v2_t txt_out_data; + uint8_t rsvd4[12]; + + /*! + * Offset = 0x90 @n + * AES KEY_IN Control Register + */ + aes_blk_key_in_control_v2_t key_in_control; + + /*! + * Offset = 0x94 @n + * AES KEY_IN Status Register + */ + aes_blk_key_in_status_v2_t key_in_status; + uint8_t rsvd5[40]; + + /*! + * Offset = 0xc0 @n + * AES KEY_IN[31:0] Register + */ + aes_blk_key_in0_v2_t key_in0; + + /*! + * Offset = 0xc4 @n + * AES KEY_IN[63:32] Register + */ + aes_blk_key_in1_v2_t key_in1; + + /*! + * Offset = 0xc8 @n + * AES KEY_IN[95:64] Register + */ + aes_blk_key_in2_v2_t key_in2; + + /*! + * Offset = 0xcc @n + * AES KEY_IN[127:96] Register + */ + aes_blk_key_in3_v2_t key_in3; + + /*! + * Offset = 0xd0 @n + * AES KEY_IN[159:128] Register + */ + aes_blk_key_in4_v2_t key_in4; + + /*! + * Offset = 0xd4 @n + * AES KEY_IN[191:160] Register + */ + aes_blk_key_in5_v2_t key_in5; + + /*! + * Offset = 0xd8 @n + * AES KEY_IN[223:192] Register + */ + aes_blk_key_in6_v2_t key_in6; + + /*! + * Offset = 0xdc @n + * AES KEY_IN[255:224] Register + */ + aes_blk_key_in7_v2_t key_in7; + + /*! + * Offset = 0xe0 @n + * AES IV_IN Control Register + */ + aes_blk_iv_in_control_v2_t iv_in_control; + uint8_t rsvd6[28]; + + /*! + * Offset = 0x100 @n + * AES IV_IN[31:0] Register + */ + aes_blk_iv_in0_v2_t iv_in0; + + /*! + * Offset = 0x104 @n + * AES IV_IN[63:32] Register + */ + aes_blk_iv_in1_v2_t iv_in1; + + /*! + * Offset = 0x108 @n + * AES IV_IN[95:64] Register + */ + aes_blk_iv_in2_v2_t iv_in2; + + /*! + * Offset = 0x10c @n + * AES IV_IN[127:96] Register + */ + aes_blk_iv_in3_v2_t iv_in3; + uint8_t rsvd7[48]; + + /*! + * Offset = 0x140 @n + * AES IV0_OUT[31:0] Register + */ + aes_blk_iv0_out0_v2_t iv0_out0; + + /*! + * Offset = 0x144 @n + * AES IV0_OUT[63:32] Register + */ + aes_blk_iv0_out1_v2_t iv0_out1; + + /*! + * Offset = 0x148 @n + * AES IV0_OUT[96:64] Register + */ + aes_blk_iv0_out2_v2_t iv0_out2; + + /*! + * Offset = 0x14c @n + * AES IV0_OUT[127:96] Register + */ + aes_blk_iv0_out3_v2_t iv0_out3; + + /*! + * Offset = 0x150 @n + * AES IV1_OUT[31:0] Register + */ + aes_blk_iv1_out0_v2_t iv1_out0; + + /*! + * Offset = 0x154 @n + * AES IV1_OUT[63:32] Register + */ + aes_blk_iv1_out1_v2_t iv1_out1; + + /*! + * Offset = 0x158 @n + * AES IV1_OUT[95:64] Register + */ + aes_blk_iv1_out2_v2_t iv1_out2; + + /*! + * Offset = 0x15c @n + * AES IV1_OUT[127:96] Register + */ + aes_blk_iv1_out3_v2_t iv1_out3; + + /*! + * Offset = 0x160 @n + * AES SKG_KEY_CNT_IN Register + */ + aes_blk_skg_key_cnt_in_v2_t skg_key_cnt_in; + + /*! + * Offset = 0x164 @n + * AES SKG_KEY_CNT_OUT Register + */ + aes_blk_skg_key_cnt_out_v2_t skg_key_cnt_out; + uint8_t rsvd8[24]; + + /*! + * Offset = 0x180 @n + * AES DSB_R1_IN[31:0] Register + */ + aes_blk_dsb_r1_in0_v2_t dsb_r1_in0; + + /*! + * Offset = 0x184 @n + * AES DSB_R1_IN[63:32] Register + */ + aes_blk_dsb_r1_in1_v2_t dsb_r1_in1; + + /*! + * Offset = 0x188 @n + * AES DSB_R1_IN[95:64] Register + */ + aes_blk_dsb_r1_in2_v2_t dsb_r1_in2; + + /*! + * Offset = 0x18c @n + * AES DSB_R1_IN[127:96] Register + */ + aes_blk_dsb_r1_in3_v2_t dsb_r1_in3; + uint8_t rsvd9[48]; + + /*! + * Offset = 0x1c0 @n + * AES DSB_R2_IN[31:0] Register + */ + aes_blk_dsb_r2_in0_v2_t dsb_r2_in0; + + /*! + * Offset = 0x1c4 @n + * AES DSB_R2_IN[63:32] Register + */ + aes_blk_dsb_r2_in1_v2_t dsb_r2_in1; + + /*! + * Offset = 0x1c8 @n + * AES DSB_R2_IN[95:64] Register + */ + aes_blk_dsb_r2_in2_v2_t dsb_r2_in2; + + /*! + * Offset = 0x1cc @n + * AES DSB_R2_IN[127:96] Register + */ + aes_blk_dsb_r2_in3_v2_t dsb_r2_in3; + + /*! + * Offset = 0x1d0 @n + * AES Error Register + */ + aes_blk_err_v2_t err; +} aes_v2_t; + +typedef struct +{ + /*! + * Offset = 0x0 @n + * General Control registers + */ + aes_blk_v3_t blk; + uint8_t rsvd0[15868]; + + /*! + * Offset = 0x4000 @n + * Direct read access to 128 X 32 Command FIFO + */ + aes_command_fifo_direct_access_v3_t command_fifo_direct_access; + uint8_t rsvd1[1520]; + + /*! + * Offset = 0x4600 @n + * Direct read access to 32 word History FIFO + */ + aes_history_fifo_direct_access_v3_t history_fifo_direct_access; +} aes_v3_t; + +typedef struct +{ + /*! + * Offset = 0x0 @n + * IP Implementation Version + */ + aes_blk_version_v4_t version; + + /*! + * Offset = 0x4 @n + * Configuration register + */ + aes_blk_config_v4_t config; + + /*! + * Offset = 0x8 @n + * Control Register + */ + aes_blk_control_v4_t control; + + /*! + * Offset = 0xc @n + * Channel status register + */ + aes_blk_status_v4_t status; + + /*! + * Offset = 0x10 @n + * Current Key IDs + */ + aes_blk_key_id_v4_t key_id; + + /*! + * Offset = 0x14 @n + * AXI status register + */ + aes_blk_axi_status_v4_t axi_status; + + /*! + * Offset = 0x18 @n + * Channel interrupt status register + */ + aes_blk_int_status_v4_t int_status; + + /*! + * Offset = 0x1c @n + * Channel interrupt enable register + */ + aes_blk_int_enable_v4_t int_enable; + + /*! + * Offset = 0x20 @n + * Watermarks for FIFO interrupts. + */ + aes_blk_watermarks_v4_t watermarks; + + /*! + * Offset = 0x24 @n + * Status information for the Command Queue + */ + aes_blk_command_fifo_status_v4_t command_fifo_status; + + /*! + * Offset = 0x28 @n + * Status information for the DMA Debug FIFO + */ + aes_blk_history_fifo_status_v4_t history_fifo_status; + + /*! + * Offset = 0x2c @n + * Total count of commands since the Command FIFO was last enabled + */ + aes_blk_command_fifo_count_v4_t command_fifo_count; + + /*! + * Offset = 0x30 @n + * Interrupt code that provides information about the flag interrupt that + * occurred. + */ + aes_blk_flag_command_v4_t flag_command; + + /*! + * Offset = 0x34 @n + * Secure Key Generation Key + */ + aes_blk_skg_key_v4_t skg_key; + uint8_t rsvd0[200]; + + /*! + * Offset = 0x100 @n + * Command FIFO. FIFO Depth is (128) Words + */ + aes_blk_command_fifo_v4_t command_fifo; + uint8_t rsvd1[252]; + + /*! + * Offset = 0x200 @n + * Last (32) Commands words + */ + aes_blk_history_fifo_v4_t history_fifo; +} aes_v4_t; + +typedef struct +{ + /*! + * Offset = 0x0 @n + * IP Implementation Version + */ + aes_blk_version_v5_t version; + + /*! + * Offset = 0x4 @n + * Configuration register + */ + aes_blk_config_v5_t config; + + /*! + * Offset = 0x8 @n + * Control Register + */ + aes_blk_control_v5_t control; + + /*! + * Offset = 0xc @n + * Channel status register + */ + aes_blk_status_v5_t status; + + /*! + * Offset = 0x10 @n + * Current Key IDs + */ + aes_blk_key_id_v5_t key_id; + + /*! + * Offset = 0x14 @n + * AXI status register + */ + aes_blk_axi_status_v5_t axi_status; + + /*! + * Offset = 0x18 @n + * Channel interrupt status register + */ + aes_blk_int_status_v5_t int_status; + + /*! + * Offset = 0x1c @n + * Channel interrupt enable register + */ + aes_blk_int_enable_v5_t int_enable; + + /*! + * Offset = 0x20 @n + * Watermarks for FIFO interrupts. + */ + aes_blk_watermarks_v5_t watermarks; + + /*! + * Offset = 0x24 @n + * Status information for the Command Queue + */ + aes_blk_command_fifo_status_v5_t command_fifo_status; + + /*! + * Offset = 0x28 @n + * Status information for the DMA Debug FIFO + */ + aes_blk_history_fifo_status_v5_t history_fifo_status; + + /*! + * Offset = 0x2c @n + * Total count of commands since the Command FIFO was last enabled + */ + aes_blk_command_fifo_count_v5_t command_fifo_count; + + /*! + * Offset = 0x30 @n + * Interrupt code that provides information about the flag interrupt that + * occurred. + */ + aes_blk_flag_command_v5_t flag_command; + + /*! + * Offset = 0x34 @n + * Secure Key Generation Key + */ + aes_blk_skg_key_v5_t skg_key; + + /*! + * Offset = 0x38 @n + * Clear COMMAND and HISTORY FIFOs + */ + aes_blk_clear_fifos_v5_t clear_fifos; + uint8_t rsvd0[452]; + + /*! + * Offset = 0x200 @n + * Command FIFO. FIFO Depth is (128) Words + */ + aes_blk_command_fifo_v5_t command_fifo; + uint8_t rsvd1[508]; + + /*! Last (32) Commands words */ + aes_blk_history_fifo_v5_t history_fifo[32]; +} aes_v5_t; + +typedef struct +{ + /*! + * Offset = 0x0 @n + * IP Implementation Version + */ + aes_blk_version_v6_t version; + + /*! + * Offset = 0x4 @n + * Configuration register + */ + aes_blk_config_v6_t config; + + /*! + * Offset = 0x8 @n + * Control Register + */ + aes_blk_control_v6_t control; + + /*! + * Offset = 0xc @n + * Channel status register + */ + aes_blk_status_v6_t status; + + /*! + * Offset = 0x10 @n + * Current Key IDs + */ + aes_blk_key_id_v6_t key_id; + + /*! + * Offset = 0x14 @n + * AXI status register + */ + aes_blk_axi_status_v6_t axi_status; + + /*! + * Offset = 0x18 @n + * Channel interrupt status register + */ + aes_blk_int_status_v6_t int_status; + + /*! + * Offset = 0x1c @n + * Channel interrupt enable register + */ + aes_blk_int_enable_v6_t int_enable; + + /*! + * Offset = 0x20 @n + * Watermarks for FIFO interrupts. + */ + aes_blk_watermarks_v6_t watermarks; + + /*! + * Offset = 0x24 @n + * Status information for the Command Queue + */ + aes_blk_command_fifo_status_v6_t command_fifo_status; + + /*! + * Offset = 0x28 @n + * Status information for the DMA Debug FIFO + */ + aes_blk_history_fifo_status_v6_t history_fifo_status; + + /*! + * Offset = 0x2c @n + * Total count of commands since the Command FIFO was last enabled + */ + aes_blk_command_fifo_count_v6_t command_fifo_count; + + /*! + * Offset = 0x30 @n + * Interrupt code that provides information about the flag interrupt that + * occurred. + */ + aes_blk_flag_command_v6_t flag_command; + + /*! + * Offset = 0x34 @n + * Secure Key Generation Key + */ + aes_blk_skg_key_v6_t skg_key; + + /*! + * Offset = 0x38 @n + * Clear COMMAND and HISTORY FIFOs + */ + aes_blk_clear_fifos_v6_t clear_fifos; + uint8_t rsvd0[452]; + + /*! + * Offset = 0x200 @n + * Command FIFO. FIFO Depth is (128) Words + */ + aes_blk_command_fifo_v6_t command_fifo; + uint8_t rsvd1[508]; + + /*! + * Offset = 0x400 @n + * Last (32) Commands words + */ + aes_blk_history_fifo_v6_t history_fifo; +} aes_v6_t; + +typedef struct +{ + /*! + * Offset = 0x0 @n + * IP Implementation Version + */ + aes_blk_version_v7_t version; + + /*! + * Offset = 0x4 @n + * Configuration register + */ + aes_blk_config_v7_t config; + + /*! + * Offset = 0x8 @n + * Control Register + */ + aes_blk_control_v7_t control; + + /*! + * Offset = 0xc @n + * Channel status register + */ + aes_blk_status_v7_t status; + + /*! + * Offset = 0x10 @n + * Current Key IDs + */ + aes_blk_key_id_v7_t key_id; + + /*! + * Offset = 0x14 @n + * AXI status register + */ + aes_blk_axi_status_v7_t axi_status; + + /*! + * Offset = 0x18 @n + * Channel interrupt status register + */ + aes_blk_int_status_v7_t int_status; + + /*! + * Offset = 0x1c @n + * Channel interrupt enable register + */ + aes_blk_int_enable_v7_t int_enable; + + /*! + * Offset = 0x20 @n + * Watermarks for FIFO interrupts. + */ + aes_blk_watermarks_v7_t watermarks; + + /*! + * Offset = 0x24 @n + * Status information for the Command Queue + */ + aes_blk_command_fifo_status_v7_t command_fifo_status; + + /*! + * Offset = 0x28 @n + * Status information for the DMA Debug FIFO + */ + aes_blk_history_fifo_status_v7_t history_fifo_status; + + /*! + * Offset = 0x2c @n + * Total count of commands since the Command FIFO was last enabled + */ + aes_blk_command_fifo_count_v7_t command_fifo_count; + + /*! + * Offset = 0x30 @n + * Interrupt code that provides information about the flag interrupt that + * occurred. + */ + aes_blk_flag_command_v7_t flag_command; + + /*! + * Offset = 0x34 @n + * Secure Key Generation Key + */ + aes_blk_skg_key_v7_t skg_key; + + /*! + * Offset = 0x38 @n + * Clear COMMAND and HISTORY FIFOs + */ + aes_blk_clear_fifos_v7_t clear_fifos; + uint8_t rsvd0[452]; + + /*! + * Offset = 0x200 @n + * Command FIFO. FIFO Depth is (128) Words + */ + aes_blk_command_fifo_v7_t command_fifo; + uint8_t rsvd1[508]; + + /*! Last (32) Commands words */ + aes_blk_history_fifo_v7_t history_fifo[32]; +} aes_v7_t; + +#if SPDS_AES_VERSION == SPDS_AES_V1 +typedef aes_v1_t aes_t; +#elif SPDS_AES_VERSION == SPDS_AES_V2 +typedef aes_v2_t aes_t; +#elif SPDS_AES_VERSION == SPDS_AES_V3 +typedef aes_v3_t aes_t; +#elif SPDS_AES_VERSION == SPDS_AES_V4 +typedef aes_v4_t aes_t; +#elif SPDS_AES_VERSION == SPDS_AES_V5 +typedef aes_v5_t aes_t; +#elif SPDS_AES_VERSION == SPDS_AES_V6 +typedef aes_v6_t aes_t; +#elif SPDS_AES_VERSION == SPDS_AES_V7 +typedef aes_v7_t aes_t; +#endif +#endif /*! SPDS_ENABLE_STRUCTS */ + +/*! @} aes */ + +#endif /*! SPDS_AES_H */ \ No newline at end of file diff --git a/platform/t8002/include/platform/trampoline.h b/platform/t8002/include/platform/trampoline.h new file mode 100644 index 0000000..efbf0db --- /dev/null +++ b/platform/t8002/include/platform/trampoline.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include + +/* ROM related registers in PMGR space */ + +#define SECURITY_REG (AOP_MINIPMGR_BASE_ADDR + 0xD0010) +#define ROM_READ_DISABLE (1 << 0) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/t8002/include/platform/uartconfig.h b/platform/t8002/include/platform/uartconfig.h new file mode 100644 index 0000000..f3ba186 --- /dev/null +++ b/platform/t8002/include/platform/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_UARTCONFIG_H +#define __PLATFORM_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/platform/t8002/include/platform/usbconfig.h b/platform/t8002/include/platform/usbconfig.h new file mode 100644 index 0000000..cfddc8b --- /dev/null +++ b/platform/t8002/include/platform/usbconfig.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#ifdef WITH_TARGET_USB_CONFIG +#include +#endif /* WITH_TARGET_USB_CONFIG */ + +#define USBPHY_OTGTUNE0 (0x37377bc3) +#define USBPHY_OTGTUNE1 (0x20c04) + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +#define USBCFG_TURNAROUND_TIME (9) + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/t8002/init.c b/platform/t8002/init.c new file mode 100644 index 0000000..3986cb2 --- /dev/null +++ b/platform/t8002/init.c @@ -0,0 +1,1435 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#if WITH_HW_DOCKCHANNEL_UART +#include +#endif +#if WITH_CONSISTENT_DBG +#include +#endif +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#if WITH_HW_SEP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uint8_t boot_debug; +static bool gDisplayEnabled; + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + uint32_t enable; + uint32_t disable; +}; + +#if WITH_ANC_BOOT +/* Note: The code below expects this table to begin with CS1 through CS0 */ +static const struct boot_interface_pin nand_boot_interface_pins[] = +{ + { GPIO_NAND_CEN0, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_CEN0 + { GPIO_NAND_CEN1, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_CEN1 + { GPIO_NAND_CLE, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_CLE + { GPIO_NAND_ALE, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_ALE + { GPIO_NAND_REN, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_REN + { GPIO_NAND_WEN, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_WEN + { GPIO_NAND_IO0, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO0 + { GPIO_NAND_IO1, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO1 + { GPIO_NAND_IO2, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO2 + { GPIO_NAND_IO3, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO3 + { GPIO_NAND_IO4, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO4 + { GPIO_NAND_IO5, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO5 + { GPIO_NAND_IO6, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // NAND_IO6 + { GPIO_NAND_IO7, GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // NAND_IO7 +}; +#endif /* WITH_ANC_BOOT */ + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ + { GPIO_SPI0_SSIN, GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN + { GPIO_SPI0_SCLK, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO_SPI0_MOSI, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO_SPI0_MISO, GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +static void platform_init_boot_strap(void); +static void platform_bootprep_darwin(void); + +int platform_early_init(void) +{ +#if APPLICATION_IBOOT && (PRODUCT_LLB || PRODUCT_IBSS) + /* Verify that the fuses and SecureROM R/W access has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile uint32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled\n"); + } + + /* Verify that the fuses are sealed on production devices. */ + if (chipid_get_current_production_mode() && !chipid_get_fuse_seal()) { + panic("Fuses are not sealed\n"); + } +#endif + +#if WITH_HW_PLATFORM_POWER + /* initialize the s5l8960x pmgr driver */ + platform_power_init(); +#endif + +#if WITH_CONSISTENT_DBG && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + consistent_debug_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif + +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif + +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif + +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); + debug_enable_uarts(3); +#endif + +#if WITH_HW_DOCKCHANNEL_UART + /* do whatever uart initialization we need to get a simple console */ + dockchannel_uart_init(); + debug_enable_uarts(3); +#endif + +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif + +#if WITH_IIC + iic_init(); +#endif + +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_HW_DMA + /* initialize the dma engine */ + dma_init(); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + + return 0; +} + +int platform_late_init(void) +{ +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_CSI + csi_late_init(); +#endif + + return 0; +} + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if (PRODUCT_LLB || PRODUCT_IBSS) && WITH_HW_DOCKCHANNEL_UART + // Enable all DockFIFO's used by platform in LLB () + dockchannel_access_enable((1) | (1 << 4)); +#endif + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); + + /* always remap the memory region at this point, regardless of resume, + * because the early MMU init always runs and we have to fix up. */ + platform_init_mainmem_map(); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { + if (!displayInitOnce) { + platform_quiesce_display(); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } else { +#if PRODUCT_IBSS + /* + * WARNING: With move to DFU-mode iBSS, this will never be + * reached. Thus, it should either be eliminated or + * refactored to make sense, perhaps by changing + * condition from PRODUCT_IBSS to WITH_RESTORE_BOOT. + */ + debug_enable_uarts(3); +#endif + } + if (env_get_uint("display-rotation", 0) == 1) + { + display_set_rotation(true); + } +#endif + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + addr_t base_rounded = *base; + addr_t end_rounded = *base + *size; + size_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + arm_mmu_map_section_range(base_rounded, base_rounded, size_rounded/MB, kARMMMUWriteCombined, false, true); + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + +int platform_init_mass_storage(void) +{ +#if WITH_HW_ASP + return (asp_nand_open()); +#else + return 0; +#endif +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + +#if WITH_CSI + csi_quiesce(target); +#endif + + switch (target) { + case BOOT_HALT: + case BOOT_DARWIN_RESTORE: + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + case BOOT_SECUREROM: + quiesce_clocks = true; + // fall through to default + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ + +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + /* quiesce the clcd panel */ + display_quiesce(true); +#endif + + gDisplayEnabled = false; + + return 0; +} + +int platform_bootprep(enum boot_target target) +{ + uint32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + platform_quiesce_display(); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* Darwin only gets the UID on resume */ + uids = 1; + gids = 0; + break; + + case BOOT_DARWIN: + /* setup Reconfig block, program MEM and SOC configs */ + platform_bootprep_darwin(); + + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; + break; + + case BOOT_DIAGS: + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: + platform_quiesce_display(); + break; +#endif + + case BOOT_SECUREROM: + platform_quiesce_display(); +#if WITH_HW_MIU + miu_select_remap(REMAP_SDRAM); +#endif + break; + + case BOOT_MONITOR: + panic("Monitor not supported"); + break; + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + default: + ; // do nothing + } + + /* make sure that fuse lock bit is set. */ + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(false == resume); + + /* mark usable ram as cached/buffered, shared */ + arm_mmu_map_section_range(SRAM_BASE, SRAM_BASE, ROUNDUP(SRAM_BANK_LEN, MB)/MB, kARMMMUNormal, true, false); +#if APPLICATION_SECUREROM + arm_mmu_map_section_range(VROM_BASE, VROM_BASE, ROUNDUP(VROM_BANK_LEN, MB)/MB, kARMMMUNormal, true, false); +#endif + +#if !(PRODUCT_IBSS || PRODUCT_LLB) + arm_mmu_map_section(0, TEXT_BASE, kARMMMUNormalRX, true); +#endif + + /* in cases where we are running from DRAM, remap it now */ +#if APPLICATION_IBOOT + arm_mmu_map_section_range(SDRAM_BASE, SDRAM_BASE, ROUNDUP(SDRAM_BANK_LEN * SDRAM_BANK_COUNT, MB)/MB, kARMMMUNormal, true, false); +#endif +} + +int platform_init(void) +{ +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_HW_ASP && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + csi_init(CSI_COPROC_ANS); /* coproc switchboard used by nand driver to communicate with ans iop */ + asp_init(); +#endif + +#if WITH_ANC_FIRMWARE + anc_firmware_init(); +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + uint32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +uint32_t platform_set_performance(uint32_t performance_level) +{ + uint32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_CPU); + memcpy(propData, &freq, propSize); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_MEM); + memcpy(propData, &freq, propSize); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_BUS); + memcpy(propData, &freq, propSize); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_PERIPH); + memcpy(propData, &freq, propSize); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_FIXED); + memcpy(propData, &freq, propSize); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_TIMEBASE); + memcpy(propData, &freq, propSize); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(uint32_t)); + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + //miu_update_device_tree(node); + } + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + + return target_update_device_tree(); +} + +#endif + +uint32_t platform_get_board_id(void) +{ + uint32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +uint32_t platform_get_boot_config(void) +{ + uint32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, uint32_t *boot_flag, uint32_t *boot_arg) +{ + uint32_t boot_config = platform_get_boot_config(); + + /* T8002 supports one boot device then USB-DFU per boot config */ + + /* If the index is not zero force DFU mode */ + if (index != 0) index = 1; + + switch (boot_config) { + case BOOT_CONFIG_SPI0: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_SPI0_TEST: + case BOOT_CONFIG_SLOW_SPI0_TEST: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case BOOT_CONFIG_ANS: + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_ANS_TEST: + *boot_device = BOOT_DEVICE_NAND; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == 1) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +#if WITH_HW_POWER +uint32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} +#endif + +int platform_get_soc_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = platform_get_base_soc_voltage(); + } + + return 0; +} + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, uint32_t boot_arg) +{ + const struct boot_interface_pin *pins = 0; + uint32_t cnt, func, pin_count = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins = spi0_boot_interface_pins; + pin_count = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_ANC_BOOT + case BOOT_DEVICE_NAND : + pins = nand_boot_interface_pins; + pin_count = (sizeof(nand_boot_interface_pins) / sizeof(nand_boot_interface_pins[0])); + + break; +#endif /* WITH_ANC_BOOT */ + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count; cnt++) { + if (enable) { + pin = pins[pin_count - 1 - cnt].pin; + func = pins[pin_count - 1 - cnt].enable; + } else { + pin = pins[cnt].pin; + func = pins[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +uint64_t platform_get_nonce(void) +{ + uint64_t nonce; + uint32_t *nonce_words = (uint32_t *)&nonce; + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH_BOOT_NONCE_0 = nonce_words[0]; + rPMGR_SCRATCH_BOOT_NONCE_1 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH_BOOT_NONCE_0; + nonce_words[1] = rPMGR_SCRATCH_BOOT_NONCE_1; + } + + return nonce; +} + +int32_t platform_get_sep_nonce(uint8_t *nonce) +{ +#if WITH_HW_SEP + return sep_client_get_nonce(nonce); +#else + return -1; +#endif +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return true; +} + +uint32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +uint32_t platform_get_spi_frequency(void) +{ +#if SUPPORT_FPGA + return 2500000; +#else + switch (platform_get_boot_config()) { + case BOOT_CONFIG_SLOW_SPI0_TEST: + return 6000000; + + default: + return 12000000; + } +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ + return gpio_read(GPIO_FORCE_DFU); +} + +bool platform_get_request_dfu1(void) +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +bool platform_get_dock_connect(void) +{ +#if CONFIG_FPGA || CONFIG_SIM + return true; +#else + return gpio_read(GPIO_DOCK_CONNECT); +#endif +} + +void platform_set_dock_attention(bool value) +{ + gpio_write(GPIO_DOCK_ATTENTION, value); +} + +int platform_translate_key_selector(uint32_t key_selector, uint32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +void platform_disable_keys(uint32_t gid, uint32_t uid) +{ + uint32_t key_disable = (((gid & 0x3) << 1) | ((uid & 0x1) << 0)); + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return; + + rPMGR_SECURITY = key_disable; +} + +bool platform_keys_disabled(uint32_t gid, uint32_t uid) +{ + uint32_t key_disabled; + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return true; + + key_disabled = rPMGR_SECURITY; + + return (key_disabled & (((gid & 0x3) << 1) | ((uid & 0x1) << 0))); +} + +void platform_demote_production() +{ + chipid_clear_production_mode(); +} + +#if APPLICATION_IBOOT +bool platform_is_pre_lpddr4(void) +{ + return false; +} + +uint64_t platform_get_memory_size(void) +{ + uint64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (((uint64_t)rPMGR_SCRATCH_MEM_INFO) & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +uint8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH_MEM_INFO >> 24) & 0xff); + } + else { + panic("memory not yet inited\n"); + } +} + + +void platform_set_memory_info_with_revids(uint8_t manuf_id, uint64_t memory_size, uint8_t rev_id, uint8_t rev_id2) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH_MEM_INFO = 0; + } + + rPMGR_SCRATCH_MEM_INFO = (manuf_id << 24) | ((rev_id2 & 0xF) << 20) | ((rev_id & 0xF) << 16) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +void platform_get_memory_rev_ids(uint8_t *rev_id, uint8_t *rev_id2) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory rev_id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) + panic("memory not yet inited\n"); + else { + if (rev_id && rev_id2) { + uint8_t rev_info = (rPMGR_SCRATCH_MEM_INFO >> 16) & 0xFF; + *rev_id = rev_info & 0xF; + *rev_id2 = rev_info >> 4; + } + } +} +#endif + +int32_t platform_get_boot_manifest_hash(uint8_t *boot_manifest_hash) +{ + volatile uint32_t *pScratch; + uint32_t *pHash; + + RELEASE_ASSERT(boot_manifest_hash != NULL); + ASSERT((&rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST - &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST + 1) + == PMGR_SCRATCH_BOOT_MANIFEST_REGISTERS); + + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagObjectManifestHashValid) != 0) { + pHash = &((uint32_t *)boot_manifest_hash)[0]; + pScratch = &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST; + + // Copy the boot manifest hash from the scratch registers. + while (pScratch <= &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST) { + *pHash++ = *pScratch++; + } + return 0; + } + + return -1; +} + +int32_t platform_set_boot_manifest_hash(const uint8_t *boot_manifest_hash) +{ + volatile uint32_t *pScratch = &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST; + uint32_t *pHash; + + ASSERT((&rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST - &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST + 1) + == PMGR_SCRATCH_BOOT_MANIFEST_REGISTERS); + + if (boot_manifest_hash != NULL) { + pHash = &((uint32_t *)boot_manifest_hash)[0]; + + // Copy the boot manifest hash to the scratch registers. + while (pScratch <= &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST) { + *pScratch++ = *pHash++; + } + + rPMGR_SCRATCH0 |= kPlatformScratchFlagObjectManifestHashValid; + } else { + // Clear the boot manifest hash in the scratch registers. + while (pScratch <= &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST) { + *pScratch++ = 0; + } + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagObjectManifestHashValid; + } + return 0; +} + +bool platform_get_mix_n_match_prevention_status(void) +{ + return ((rPMGR_SCRATCH0 & kPlatformScratchFlagVerifyManifestHash) ? true : false); +} + +void platform_set_mix_n_match_prevention_status(bool mix_n_match_prevented) +{ + if (mix_n_match_prevented) + rPMGR_SCRATCH0 |= kPlatformScratchFlagVerifyManifestHash; + else + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagVerifyManifestHash; +} + +void platform_set_consistent_debug_root_pointer(uint32_t root) +{ + rPMGR_SCRATCH7 = root; +} + +#define MAX_DMA_TRANSFER_SIZE 0xFF0 + +// Use AOP PL080 DMA to clear out insecure memory. We use this instead +// of bzero to improve boot time. The AOP PL080 avoids PIO from AP and +// saves us time on PIO latency. The DMA source address is fixed and +// destination address is incremented a word at a time. +// rdar://problem/19986351 +void platform_clear_mem_with_dma(char *dst, size_t count) +{ + uint32_t src = 0; + uint32_t transfer_size = 0; + uint32_t increment = 0; + // increasing burst size further doesnt improve speed due to pl080's poor utilization of the bus + // use bufferable attribute + const uint32_t control_c0 = AOP_PL080_BLK_DMAC_C0_CONTROL_SRC_BURST_SIZE_INSRT(0x1) | + AOP_PL080_BLK_DMAC_C0_CONTROL_DST_BURST_SIZE_INSRT(0x1) | + AOP_PL080_BLK_DMAC_C0_CONTROL_SRC_XFER_WIDTH_INSRT(2) | + AOP_PL080_BLK_DMAC_C0_CONTROL_DST_XFER_WIDTH_INSRT(2) | + AOP_PL080_BLK_DMAC_C0_CONTROL_SRC_MST_SEL_INSRT(0) | + AOP_PL080_BLK_DMAC_C0_CONTROL_DST_MST_SEL_INSRT(1) | + AOP_PL080_BLK_DMAC_C0_CONTROL_SRC_INCR_INSRT(0) | + AOP_PL080_BLK_DMAC_C0_CONTROL_DST_INCR_INSRT(1) | + AOP_PL080_BLK_DMAC_C0_CONTROL_PROTECTION_INSRT(2); + + // clean by mva the src location + platform_cache_operation(CACHE_CLEAN, (void *)((uint32_t)&src & ~(CPU_CACHELINE_SIZE-1)), CPU_CACHELINE_SIZE); + + // Enable DMAC + rAOP_PL080_CONFIGURATION = AOP_PL080_BLK_DMAC_CONFIGURATION_DMAC_ENABLE_INSRT(1); + + // Clear interrupts + rAOP_PL080_INTTCCLEAR = AOP_PL080_BLK_DMAC_INTTCCLEAR_INT_TC_CLEAR_INSRT(0xff); + rAOP_PL080_INTERRCLR = AOP_PL080_BLK_DMAC_INTERRCLR_INT_ERR_CLR_INSRT(0xff); + + // Set source and destination address + rAOP_PL080_C0_SRCADDR = (uint32_t)&src; + rAOP_PL080_C0_DESTADDR = (uint32_t)dst; + + // Dont use segments + rAOP_PL080_C0_LLI = 0; + + while (count) { + // DMA size limited to 0xFFF * transfer width * burst size + // In this case each transfer is of 4 bytes and burst size 1 + transfer_size = ((count/4) <= MAX_DMA_TRANSFER_SIZE) ? (count/4) : MAX_DMA_TRANSFER_SIZE; + count -= (transfer_size * 4); + + // transfer width - 4 bytes, burst size - 1, source no increment, destination increment + // transfer_size + rAOP_PL080_C0_CONTROL = control_c0 | AOP_PL080_BLK_DMAC_C0_CONTROL_XFER_SIZE_INSRT(transfer_size); + + // Enable the DMA channel. It gets disabled once the DMA completes. + rAOP_PL080_C0_CONFIGURATION |= AOP_PL080_BLK_DMAC_C0_CONFIGURATION_CHANNEL_ENABLE_INSRT(0x1); + + while(AOP_PL080_BLK_DMAC_C0_CONFIGURATION_ACTIVE_XTRCT(rAOP_PL080_C0_CONFIGURATION)) { + } + + // Once the DMA completes destination address is the last byte + // read. So we need to move it forward to dst + transfer_size + // for the next DMA transfer + increment += (transfer_size * 4); + rAOP_PL080_C0_DESTADDR = (uint32_t)dst + increment; + } + + arm_clean_invalidate_dcache(); +} + + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = PANIC_BASE; + break; + + case kMemoryRegion_StorageProcessor: + base = ASP_BASE; + break; + + case kMemoryRegion_SecureProcessor: + base = TZ0_BASE; + break; + + case kMemoryRegion_Kernel: + base = SDRAM_BASE; + break; + + case kMemoryRegion_PageTables: + base = MMU_TT_BASE; + break; + + case kMemoryRegion_Heap: + base = HEAP_BASE; + break; + + case kMemoryRegion_Stacks: + base = STACK_BASE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + base = CONSISTENT_DEBUG_BASE; + break; + + case kMemoryRegion_SleepToken: + base = SLEEP_TOKEN_BUFFER_BASE; + break; + + case kMemoryRegion_DramConfig: + base = DRAM_CONFIG_SEQ_BASE; + break; + + case kMemoryRegion_Display: + base = PANIC_BASE - DISPLAY_SIZE; + break; + + case kMemoryRegion_iBoot: + base = IBOOT_BASE; + break; +#endif + + default: + base = (uintptr_t)-1; + break; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + + case kMemoryRegion_StorageProcessor: + size = ASP_SIZE; + break; + + case kMemoryRegion_SecureProcessor: + size = TZ0_SIZE; + break; + + case kMemoryRegion_Kernel: + size = DISPLAY_BASE - platform_get_memory_region_base(kMemoryRegion_Kernel); + break; + + case kMemoryRegion_PageTables: + size = MMU_TT_SIZE; + break; + + case kMemoryRegion_Heap: + size = (size_t)HEAP_SIZE; + break; + + case kMemoryRegion_Stacks: + size = STACK_SIZE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + size = CONSISTENT_DEBUG_SIZE; + break; + + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; + + case kMemoryRegion_DramConfig: + size = DRAM_CONFIG_SEQ_SIZE; + break; + + case kMemoryRegion_Display: + size = DISPLAY_SIZE; + break; + + case kMemoryRegion_iBoot: + size = (size_t)IBOOT_SIZE; + break; +#endif + + default: + size = (size_t)-1; + break; + } + + return size; +} + +#if APPLICATION_IBOOT && (PRODUCT_LLB || PRODUCT_IBSS) +extern uintptr_t boot_handoff_trampoline; + +void *platform_get_boot_trampoline(void) +{ + return (void *)&boot_handoff_trampoline; +} + +#elif WITH_ROM_TRAMPOLINE + +extern uint8_t boot_handoff_trampoline, boot_handoff_trampoline_end; + +void *platform_get_boot_trampoline(void) +{ + size_t len = &boot_handoff_trampoline_end - &boot_handoff_trampoline; + + /* copy trampoline code */ + memcpy((void *)BOOT_TRAMPOLINE_BASE, &boot_handoff_trampoline, len); + + /* clean-invalidate TZ0 & TZ1 regions */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + + return (void *)BOOT_TRAMPOLINE_BASE; +} +#endif + +static void platform_init_boot_strap(void) +{ + volatile uint32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_BOARD_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_ID3, GPIO_PDN); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + + gpio_board_id = + (gpio_read(GPIO_BOARD_ID3) << 3) | + (gpio_read(GPIO_BOARD_ID2) << 2) | + (gpio_read(GPIO_BOARD_ID1) << 1) | + (gpio_read(GPIO_BOARD_ID0) << 0); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOARD_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_ID3, GPIO_CFG_DFLT); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 4) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +static void platform_bootprep_darwin() +{ +#if PRODUCT_IBOOT || PRODUCT_IBEC + /* clean-invalidate TZ0 region */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ0_BASE, TZ0_SIZE); + + /* program values + Tz{base,end}addr are relative addresses from DRAM base + */ + + rMCCLOCKREGION_TZ0BASEADDR = (TZ0_BASE - SDRAM_BASE) >> 12; + rMCCLOCKREGION_TZ0ENDADDR = (TZ0_BASE + TZ0_SIZE - SDRAM_BASE - 1) >> 12; + + /* Lock TZ0 region. */ + rMCCLOCKREGION_TZ0LOCK = (1 << 0); + if ((rMCCLOCKREGION_TZ0LOCK & 1) == 0) { + panic("TZ0 failed to lock\n"); + } +#endif +} + diff --git a/platform/t8002/miu/miu.c b/platform/t8002/miu/miu.c new file mode 100644 index 0000000..450ec16 --- /dev/null +++ b/platform/t8002/miu/miu.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif + + return 0; +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ +#if APPLICATION_IBOOT && WITH_HW_DCS + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + /* + The ROMADDRREMAP[1:0] is responsible for the remap + + 1. ROMADDRREMAP[1] = 1’b0 - ROM mapped to PIO + 1.1. ROMADDRREMAP[0] = 1’b0 - ROM mapped to SECURE ROM + 1.2. ROMADDRREMAP[0] = 1’b1 - ROM mapped to AOP-SRAM + 2. ROMADDRREMAP[1] = 1’b1 - ROM mapped to DRAM + + in other words + ROMADDRREMAP[1:0] + 2’b00 - SECURE ROM + 2’b01 - AOP-SRAM + 2’b1x - DDR + */ + + switch (sel) { + case REMAP_SRAM: + rPIO_REMAP_CTL = (rPIO_REMAP_CTL & ~3) | (1 << 0); + break; + + case REMAP_SDRAM: + rPIO_REMAP_CTL = (rPIO_REMAP_CTL & ~3) | (2 << 0); + break; + + // reset back to default behavior + default: + rPIO_REMAP_CTL = 0; + break; + } +} + +void miu_bypass_prep(void) +{ +} + +#if WITH_DEVICETREE + +void miu_update_device_tree(DTNode *pmgr_node) +{ + // Nothing to do here +} + +#endif diff --git a/platform/t8002/miu/rules.mk b/platform/t8002/miu/rules.mk new file mode 100644 index 0000000..77b88cb --- /dev/null +++ b/platform/t8002/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/t8002/pmgr/pmgr.c b/platform/t8002/pmgr/pmgr.c new file mode 100644 index 0000000..ef439b7 --- /dev/null +++ b/platform/t8002/pmgr/pmgr.c @@ -0,0 +1,1675 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern const struct tunable_chip_struct tunables_pmgr[]; +extern const struct tunable_filtered_chip_struct tunables_filtered_pmgr[]; + +#define PLL_VCO_TARGET(pllx) ((2ULL * (pllx##_O) * (pllx##_M)) / (pllx##_P)) +#define PLL_FREQ_TARGET(pllx) (((pllx##_O) * (pllx##_M)) / (pllx##_P) / ((pllx##_S) + 1)) + +static uint32_t perf_level = kPerformanceMemoryLow; + +#if APPLICATION_SECUREROM +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_SECUREROM +#endif + +#if APPLICATION_IBOOT +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_VMIN +#endif + +struct clock_source { + uint32_t src_clk; + uint32_t factor; +}; + +struct clock_config { + volatile uint32_t *clock_reg; // CLK_CFG Register + struct clock_source sources[8]; // List of sources +}; + +struct clock_config_active { + uint32_t clk; + uint32_t clock_reg_val; +}; + +struct device_config { + volatile uint32_t *ps_reg; // PS Register +}; + +/* ******************************************************************************** */ +#if APPLICATION_IBOOT + +/* LPO @192MHz */ +#define LPPLL_T LPPLL_FREQ + +/* PLL0 @1065.6MHz */ +#define PLL0 0 +#define PLL0_P 5 +#define PLL0_M 111 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) +#define PLL0_VCO_OUT true + +/* PLL1 @480MHz */ +#define PLL1 1 +#define PLL1_P 1 +#define PLL1_M 40 +#define PLL1_S 1 +#define PLL1_T PLL_FREQ_TARGET(PLL1) +#define PLL1_VCO_OUT false + +static const struct clock_config_active clk_configs_active[] = { + {PMGR_CLK_AOP, 0x81100000}, // minipmgr_aop on 96MHz + {PMGR_CLK_UART0, 0x83100000}, // minipmgr_uart0 on 24MHz + {PMGR_CLK_UART1, 0x83100000}, // minipmgr_uart1 on 24MHz + {PMGR_CLK_UART2, 0x83100000}, // minipmgr_uart2 on 24MHz + {PMGR_CLK_SENSE_X2, 0x81100000}, // minipmgr_sense_x2 on 48MHz + {PMGR_CLK_DETECT, 0x81100000}, // minipmgr_detect on 96MHz + {PMGR_CLK_I2CM, 0x81100000}, // minipmgr_i2cm on 24MHz + {PMGR_CLK_I2CM1, 0x81100000}, // minipmgr_i2cm1 on 24MHz + {PMGR_CLK_PROXY_FABRIC, 0x81100000}, // minipmgr_proxy_fabric on 96MHz + {PMGR_CLK_PROXY_MCU_REF, 0x81100000}, // minipmgr_proxy_mcu_ref on 96MHz + {PMGR_CLK_GPIO, 0x80100000}, // gpio on 24MHz + {PMGR_CLK_MCU_REF, 0x83100000}, // mcu_ref on SOC_PERF_STATE + {PMGR_CLK_CPU, 0x83100000}, // cpu on SOC_PERF_STATE + {PMGR_CLK_GFX, 0x83100000}, // gfx on 133.25MHz + {PMGR_CLK_MEDIA_FAB, 0x83100000}, // media_fab on SOC_PERF_STATE + {PMGR_CLK_PIO, 0x83100000}, // pio on SOC_PERF_STATE + {PMGR_CLK_SDIO, 0x83100000}, // sdio on SOC_PERF_STATE + {PMGR_CLK_LIO, 0x83100000}, // lio on SOC_PERF_STATE + {PMGR_CLK_AES, 0x83100000}, // aes on SOC_PERF_STATE + {PMGR_CLK_AUE, 0x83100000}, // aue on 53.3MHz + {PMGR_CLK_SPI0_N, 0x83100000}, // spi0_n on 53.3MHz + {PMGR_CLK_SPI1_N, 0x83100000}, // spi1_n on 53.3MHz + {PMGR_CLK_NCO_REF0, 0x83100000}, // nco_ref0 on 266.5MHz + {PMGR_CLK_NCO_REF1, 0x83100000}, // nco_ref1 on 266.5MHz + {PMGR_CLK_NCO_ALG0, 0x83100000}, // nco_alg0 on 133.25MHz + {PMGR_CLK_NCO_ALG1, 0x83100000}, // nco_alg1 on 133.25MHz + {PMGR_CLK_MCA0_M, 0x83100000}, // mca0_m on 133.25MHz + {PMGR_CLK_MCA1_M, 0x84100000}, // mca1_m on 133.25MHz + {PMGR_CLK_MCA2_M, 0x84100000}, // mca2_m on 133.25MHz + {PMGR_CLK_TMPS, 0x83100000}, // tmps on 1.2MHz + {PMGR_CLK_UVD, 0x83100000}, // uvd on 266.5MHz + {PMGR_CLK_ISP_C, 0x83100000}, // isp_c on 480MHz + {PMGR_CLK_ISP, 0x83100000}, // isp on 160MHz + {PMGR_CLK_RT_FAB, 0x83100000}, // rt_fab on 266.5MHz + {PMGR_CLK_ISP_SENSOR0, 0x81100000}, // isp_sensor0_ref on 48MHz + {PMGR_CLK_VENC, 0x83100000}, // venc_clk on 160MHz + {PMGR_CLK_SEP, 0x83100000}, // sep_clk on 355.33MHz + {PMGR_CLK_SEP_FAB, 0x83100000}, // sep_fab_clk on 177.7MHz + {PMGR_CLK_ANS, 0x83100000}, // ans_c_clk on 106.6MHz + {PMGR_CLK_ANC_LINK, 0x83100000}, // anc_link_clk on 106.6MHz + {PMGR_CLK_VDEC, 0x83100000}, // vdec_clk on 266.5MHz + {PMGR_CLK_MSR, 0x83100000}, // msr_clk on 133.25MHz + {PMGR_CLK_AJPEG_IP, 0x83100000}, // ajpeg_ip_clk on 106.6MHz + {PMGR_CLK_AJPEG_WRAP, 0x83100000}, // ajpeg_wrap_clk on 133.25MHz + {PMGR_CLK_DISP, 0x83100000}, // disp_clk on 106.6MHz + {PMGR_CLK_MIPI_DSI, 0x83100000}, // mipi_dsi_clk on 533MHz + {PMGR_CLK_VID, 0x80100000}, // vid_clk on 24MHz + {PMGR_CLK_HFD, 0x83100000}, // hfd_clk on 106.6MHz + {PMGR_CLK_HSICPHY_REF_12M, 0x83100000}, // hsicphy_ref_12M_clk on 12MHz + {PMGR_CLK_USB480_0, 0x83100000}, // usb480_0_clk on 480MHz + {PMGR_CLK_USB_EHCI, 0x83100000}, // usb_ehci_clk on 106.6MHz +}; + +static const struct clock_config_active spare_clock_configs_active[] = { + {PMGR_CLK_S0, 0x00000000}, // s0 off + {PMGR_CLK_S1, 0x00000000}, // s1 off + {PMGR_CLK_ISP_REF0, 0x83000005}, // isp_ref0 on 48MHz +}; + +#endif /* APPLICATION_IBOOT */ + +struct pmgr_soc_perf_state { + uint32_t entry[1]; +}; + +static struct pmgr_soc_perf_state pmgr_soc_perf_states[] = { + [kSOC_PERF_STATE_BYPASS] = {{ 0x00000000 }}, + +#if APPLICATION_SECUREROM + [kSOC_PERF_STATE_SECUREROM] = { + // PIO = 106.6 / 2 + // SDIO = 24 + // MEDIA_FAB = 24 + // CPU = 533 / 2 + // AES = 24 + // LIO = 24 + // MCU_REF_CFG_SEL = 0 + // MCU_REF = 24 + { 0x30030000 } + }, +#endif + +#if APPLICATION_IBOOT + [kSOC_PERF_STATE_VMIN] = { + // PIO = 106.6 + // SDIO = 106.6 + // MEDIA_FAB = 266.5 + // CPU = 533 + // AES = 266.5 + // LIO = 106.6 + // MCU_REF_CFG_SEL = 48 + // MCU_REF = 48 + { 0x33333334 } + }, +#endif +}; + +/* ******************************************************************************** */ +#if APPLICATION_SECUREROM + +/* PLL0 @532.8MHz */ +#define PLL0 0 +#define PLL0_P 5 +#define PLL0_M 222 +#define PLL0_S 1 +#define PLL0_T PLL_FREQ_TARGET(PLL0) +#define PLL0_VCO_OUT false + +// TODO: Figure out which ones aren't necessary during SecureROM +// We won't touch the clk gen's that aren't necessary during SecureROM. +static const struct clock_config_active clk_configs_active[] = { + {PMGR_CLK_AOP, 0x80100000}, // minipmgr_aop on 24MHz + {PMGR_CLK_UART0, 0x80100000}, // minipmgr_uart0 on 24MHz + {PMGR_CLK_UART1, 0x80100000}, // minipmgr_uart1 on 24MHz + {PMGR_CLK_UART2, 0x80100000}, // minipmgr_uart2 on 24MHz + {PMGR_CLK_SENSE_X2, 0x80100000}, // minipmgr_sense_x2 on 24MHz + {PMGR_CLK_DETECT, 0x80100000}, // minipmgr_detect on 24MHz + {PMGR_CLK_I2CM, 0x80100000}, // minipmgr_i2cm on 24MHz + {PMGR_CLK_I2CM1, 0x80100000}, // minipmgr_i2cm1 on 24MHz + {PMGR_CLK_PROXY_FABRIC, 0x80100000}, // minipmgr_proxy_fabric on 24MHz + {PMGR_CLK_PROXY_MCU_REF, 0x80100000}, // minipmgr_proxy_mcu_ref on 24MHz + {PMGR_CLK_GPIO, 0x80100000}, // gpio on 24MHz + {PMGR_CLK_MCU_REF, 0x83100000}, // mcu_ref on SOC_PERF_STATE + {PMGR_CLK_CPU, 0x83100000}, // cpu on SOC_PERF_STATE + {PMGR_CLK_GFX, 0x80100000}, // gfx on 24MHz + {PMGR_CLK_MEDIA_FAB, 0x80100000}, // media_fab on SOC_PERF_STATE + {PMGR_CLK_PIO, 0x83100000}, // pio on SOC_PERF_STATE + {PMGR_CLK_SDIO, 0x80100000}, // sdio on SOC_PERF_STATE + {PMGR_CLK_LIO, 0x80100000}, // lio on SOC_PERF_STATE + {PMGR_CLK_AES, 0x80100000}, // aes on SOC_PERF_STATE + {PMGR_CLK_AUE, 0x80100000}, // aue on 24MHz + {PMGR_CLK_SPI0_N, 0x80100000}, // spi0_n on 24MHz + {PMGR_CLK_SPI1_N, 0x80100000}, // spi1_n on 24MHz + {PMGR_CLK_NCO_REF0, 0x80100000}, // nco_ref0 on 24MHz + {PMGR_CLK_NCO_REF1, 0x80100000}, // nco_ref1 on 24MHz + {PMGR_CLK_NCO_ALG0, 0x80100000}, // nco_alg0 on 24MHz + {PMGR_CLK_NCO_ALG1, 0x80100000}, // nco_alg1 on 24MHz + {PMGR_CLK_MCA0_M, 0x80100000}, // mca0_m on 24MHz + {PMGR_CLK_MCA1_M, 0x80100000}, // mca1_m on 24MHz + {PMGR_CLK_MCA2_M, 0x80100000}, // mca2_m on 24MHz + {PMGR_CLK_TMPS, 0x83100000}, // tmps on 1.2MHz + {PMGR_CLK_UVD, 0x80100000}, // uvd on 24MHz + {PMGR_CLK_ISP_C, 0x80100000}, // isp_c on 24MHz + {PMGR_CLK_ISP, 0x80100000}, // isp on 24MHz + {PMGR_CLK_RT_FAB, 0x80100000}, // rt_fab on 24MHz + {PMGR_CLK_ISP_SENSOR0, 0x80100000}, // isp_sensor0_ref on 24MHz + {PMGR_CLK_VENC, 0x80100000}, // venc_clk on 24MHz + {PMGR_CLK_SEP, 0x83100000}, // sep_clk on 177.67MHz + {PMGR_CLK_SEP_FAB, 0x83100000}, // sep_fab_clk on 88.85MHz + {PMGR_CLK_ANS, 0x83100000}, // ans_c_clk on 53.3MHz + {PMGR_CLK_ANC_LINK, 0x83100000}, // anc_link_clk on 53.3MHz + {PMGR_CLK_VDEC, 0x80100000}, // vdec_clk on 24MHz + {PMGR_CLK_MSR, 0x80100000}, // msr_clk on 24MHz + {PMGR_CLK_AJPEG_IP, 0x80100000}, // ajpeg_ip_clk on 24MHz + {PMGR_CLK_AJPEG_WRAP, 0x80100000}, // ajpeg_wrap_clk on 24MHz + {PMGR_CLK_DISP, 0x80100000}, // disp_clk on 24MHz + {PMGR_CLK_MIPI_DSI, 0x80100000}, // mipi_dsi_clk on 24MHz + {PMGR_CLK_VID, 0x80100000}, // vid_clk on 24MHz + {PMGR_CLK_HFD, 0x80100000}, // hfd_clk on 24MHz + {PMGR_CLK_HSICPHY_REF_12M, 0x80100000}, // hsicphy_ref_12M_clk on 24MHz + {PMGR_CLK_USB480_0, 0x80100000}, // usb480_0_clk on 24MHz + {PMGR_CLK_USB_EHCI, 0x80100000}, // usb_ehci_clk on 24MHz +}; + +static const struct clock_config_active spare_clock_configs_active[] = { + {PMGR_CLK_S0, 0x80000001}, // s0 on 266.4MHz + {PMGR_CLK_S1, 0x80000001}, // s1 on 266.4MHz + {PMGR_CLK_ISP_REF0, 0x81000006}, // isp_ref0 on 22.2MHz // Should be less than 24 MHz +}; + +#endif /* APPLICATION_SECUREROM */ +/* ******************************************************************************** */ +#define CLOCK_SOURCES_MAX 8 + +static const struct clock_config clk_configs[PMGR_CLK_COUNT] = { + [PMGR_CLK_GPIO] = { + &rPMGR_CLK_CFG(GPIO), + { + {PMGR_CLK_OSC, 1} + } + }, + [PMGR_CLK_MCU_REF] = { + &rPMGR_CLK_CFG(MCU_REF), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL1, 10}, + {PMGR_CLK_PROXY_MCU_REF, 1}, + } + }, + [PMGR_CLK_CPU] = { + &rPMGR_CLK_CFG(CPU), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + } + }, + [PMGR_CLK_GFX] = { + &rPMGR_CLK_CFG(GFX), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + } + }, + [PMGR_CLK_MEDIA_FAB] = { + &rPMGR_CLK_CFG(MEDIA_FAB), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL1, 3}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + } + }, + [PMGR_CLK_PIO] = { + &rPMGR_CLK_CFG(PIO), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PROXY_FABRIC, 1}, + {PMGR_CLK_PLL1, 5}, + } + }, + [PMGR_CLK_SDIO] = { + &rPMGR_CLK_CFG(SDIO), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_LIO] = { + &rPMGR_CLK_CFG(LIO), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 20}, + {PMGR_CLK_OSC, 4}, + } + }, + [PMGR_CLK_AES] = { + &rPMGR_CLK_CFG(AES), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + } + }, + [PMGR_CLK_AUE] = { + &rPMGR_CLK_CFG(AUE), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 20}, + {PMGR_CLK_PLL1, 8}, + } + }, + [PMGR_CLK_SPI0_N] = { + &rPMGR_CLK_CFG(SPI0_N), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 20}, + {PMGR_CLK_PLL0, 40}, + } + }, + [PMGR_CLK_SPI1_N] = { + &rPMGR_CLK_CFG(SPI1_N), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 20}, + {PMGR_CLK_PLL0, 40}, + } + }, + [PMGR_CLK_NCO_REF0] = { + &rPMGR_CLK_CFG(NCO_REF0), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 8}, + } + }, + [PMGR_CLK_NCO_REF1] = { + &rPMGR_CLK_CFG(NCO_REF1), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 8}, + } + }, + [PMGR_CLK_NCO_ALG0] = { + &rPMGR_CLK_CFG(NCO_ALG0), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_NCO_ALG1] = { + &rPMGR_CLK_CFG(NCO_ALG1), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_MCA0_M] = { + &rPMGR_CLK_CFG(MCA0_M), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_NCO_REF0, 1}, + {PMGR_CLK_NCO_REF1, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4}, + } + }, + [PMGR_CLK_MCA1_M] = { + &rPMGR_CLK_CFG(MCA1_M), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_NCO_REF0, 1}, + {PMGR_CLK_NCO_REF1, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4}, + } + }, + [PMGR_CLK_MCA2_M] = { + &rPMGR_CLK_CFG(MCA2_M), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_NCO_REF0, 1}, + {PMGR_CLK_NCO_REF1, 1}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 4}, + } + }, + [PMGR_CLK_TMPS] = { + &rPMGR_CLK_CFG(TMPS), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_OSC, 20}, + } + }, + [PMGR_CLK_UVD] = { + &rPMGR_CLK_CFG(UVD), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + } + }, + [PMGR_CLK_ISP_C] = { + &rPMGR_CLK_CFG(ISP_C), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL1, 2}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL1, 4}, + } + }, + [PMGR_CLK_ISP] = { + &rPMGR_CLK_CFG(ISP), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL1, 3}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 16}, + } + }, + [PMGR_CLK_RT_FAB] = { + &rPMGR_CLK_CFG(RT_FAB), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL1, 3}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 16}, + } + }, + [PMGR_CLK_ISP_SENSOR0] = { + &rPMGR_CLK_CFG(ISP_SENSOR0_REF), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_ISP_REF0, 1}, + } + }, + [PMGR_CLK_VENC] = { + &rPMGR_CLK_CFG(VENC), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL1, 3}, + {PMGR_CLK_PLL0, 8}, + } + }, + [PMGR_CLK_SEP] = { + &rPMGR_CLK_CFG(SEP), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 3}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + } + }, + [PMGR_CLK_SEP_FAB] = { + &rPMGR_CLK_CFG(SEP_FAB), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 6}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + } + }, + [PMGR_CLK_ANS] = { + &rPMGR_CLK_CFG(ANS_C), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_ANC_LINK] = { + &rPMGR_CLK_CFG(ANC_LINK), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_VDEC] = { + &rPMGR_CLK_CFG(VDEC), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + } + }, + [PMGR_CLK_MSR] = { + &rPMGR_CLK_CFG(MSR), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_AJPEG_IP] = { + &rPMGR_CLK_CFG(AJPEG_IP), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_AJPEG_WRAP] = { + &rPMGR_CLK_CFG(AJPEG_WRAP), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 8}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_DISP] = { + &rPMGR_CLK_CFG(DISP), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + {PMGR_CLK_PLL0, 16}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_MIPI_DSI] = { + &rPMGR_CLK_CFG(MIPI_DSI), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 12}, + } + }, + [PMGR_CLK_VID] = { + &rPMGR_CLK_CFG(VID), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 48}, + {PMGR_CLK_OSC, 2}, + {PMGR_CLK_OSC, 3}, + {PMGR_CLK_OSC, 4}, + } + }, + [PMGR_CLK_HFD] = { + &rPMGR_CLK_CFG(HFD), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 20}, + {PMGR_CLK_PLL0, 32}, + {PMGR_CLK_OSC, 1}, + } + }, + [PMGR_CLK_HSICPHY_REF_12M] = { + &rPMGR_CLK_CFG(HSICPHY_REF_12M), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_OSC, 2}, + } + }, + [PMGR_CLK_USB_EHCI] = { + &rPMGR_CLK_CFG(USB_EHCI), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL0, 10}, + {PMGR_CLK_PLL0, 20}, + } + }, + [PMGR_CLK_USB480_0] = { + &rPMGR_CLK_CFG(USB480_0), + { + {PMGR_CLK_OSC, 1}, + {PMGR_CLK_S0, 1}, + {PMGR_CLK_S1, 1}, + {PMGR_CLK_PLL1, 1}, + } + }, + [PMGR_CLK_S0] = { + &rPMGR_CLK_CFG(S0), + { + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL1, 2}, + } + }, + [PMGR_CLK_S1] = { + &rPMGR_CLK_CFG(S1), + { + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL1, 2}, + } + }, + [PMGR_CLK_ISP_REF0] = { + &rPMGR_CLK_CFG(ISP_REF0), + { + {PMGR_CLK_PLL0, 2}, + {PMGR_CLK_PLL0, 4}, + {PMGR_CLK_PLL1, 1}, + {PMGR_CLK_PLL1, 2}, + } + }, + [PMGR_CLK_AOP] = { + &rMINIPMGR_CLK_CFG(AOP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + } + }, + [PMGR_CLK_UART0] = { + &rMINIPMGR_CLK_CFG(UART0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + } + }, + [PMGR_CLK_UART1] = { + &rMINIPMGR_CLK_CFG(UART1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + } + }, + [PMGR_CLK_UART2] = { + &rMINIPMGR_CLK_CFG(UART2), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + } + }, + [PMGR_CLK_SENSE_X2] = { + &rMINIPMGR_CLK_CFG(SENSE_X2), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + { PMGR_CLK_LPPLL, 7 }, + { PMGR_CLK_LPPLL, 14 }, + } + }, + [PMGR_CLK_DETECT] = { + &rMINIPMGR_CLK_CFG(DETECT), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + } + }, + [PMGR_CLK_I2CM] = { + &rMINIPMGR_CLK_CFG(I2CM), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 4 }, + { PMGR_CLK_LPPLL, 8 }, + } + }, + [PMGR_CLK_I2CM1] = { + &rMINIPMGR_CLK_CFG(I2CM1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 4 }, + { PMGR_CLK_LPPLL, 8 }, + } + }, + [PMGR_CLK_PROXY_FABRIC] = { + &rMINIPMGR_CLK_CFG(PROXY_FABRIC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + } + }, + [PMGR_CLK_PROXY_MCU_REF] = { + &rMINIPMGR_CLK_CFG(PROXY_MCU_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPPLL, 1 }, + { PMGR_CLK_LPPLL, 2 }, + { PMGR_CLK_LPPLL, 4 }, + } + }, +}; + +static const struct device_config device_configs[PMGR_DEVICE_COUNT] = { + // Mini PMGR + [PMGR_DEVICE_INDEX(CLK_AOP)] = {&rMINIPMGR_PS(AOP)}, + [PMGR_DEVICE_INDEX(CLK_DEBUG)] = {&rMINIPMGR_PS(DEBUG)}, + [PMGR_DEVICE_INDEX(CLK_AOP_GPIO)] = {&rMINIPMGR_PS(AOP_GPIO)}, + [PMGR_DEVICE_INDEX(CLK_AOP_I2CM1)] = {&rMINIPMGR_PS(AOP_I2CM1)}, + [PMGR_DEVICE_INDEX(CLK_AOP_CPU)] = {&rMINIPMGR_PS(AOP_CPU)}, + [PMGR_DEVICE_INDEX(CLK_AOP_RTCPU)] = {&rMINIPMGR_PS(AOP_RTCPU)}, + [PMGR_DEVICE_INDEX(CLK_AOP_FILTER)] = {&rMINIPMGR_PS(AOP_FILTER)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART0)] = {&rMINIPMGR_PS(AOP_UART0)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART1)] = {&rMINIPMGR_PS(AOP_UART1)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART2)] = {&rMINIPMGR_PS(AOP_UART2)}, + [PMGR_DEVICE_INDEX(CLK_AOP_I2CM)] = {&rMINIPMGR_PS(AOP_I2CM)}, + [PMGR_DEVICE_INDEX(CLK_AOP_FILTER_DMA)] = {&rMINIPMGR_PS(AOP_FILTER_DMA)}, + [PMGR_DEVICE_INDEX(CLK_AOP_LPD0)] = {&rMINIPMGR_PS(AOP_LPD0)}, + [PMGR_DEVICE_INDEX(CLK_AOP_HPDS)] = {&rMINIPMGR_PS(AOP_HPDS)}, + [PMGR_DEVICE_INDEX(CLK_AOP_HPDSC)] = {&rMINIPMGR_PS(AOP_HPDSC)}, + [PMGR_DEVICE_INDEX(CLK_AOP_HPDD)] = {&rMINIPMGR_PS(AOP_HPDD)}, + [PMGR_DEVICE_INDEX(CLK_MARCONI)] = {&rMINIPMGR_PS(MARCONI)}, + + // PMGR + [PMGR_DEVICE_INDEX(CLK_SCU)] = {&rPMGR_PS(SCU)}, + [PMGR_DEVICE_INDEX(CLK_CPU0)] = {&rPMGR_PS(CPU0)}, + [PMGR_DEVICE_INDEX(CLK_CPU1)] = {&rPMGR_PS(CPU1)}, + [PMGR_DEVICE_INDEX(CLK_PIO)] = {&rPMGR_PS(PIO)}, + [PMGR_DEVICE_INDEX(CLK_CPU_FAB)] = {&rPMGR_PS(CPU_FAB)}, + [PMGR_DEVICE_INDEX(CLK_NRT_FAB)] = {&rPMGR_PS(NRT_FAB)}, + [PMGR_DEVICE_INDEX(CLK_RT_FAB)] = {&rPMGR_PS(RT_FAB)}, + [PMGR_DEVICE_INDEX(CLK_AIC)] = {&rPMGR_PS(AIC)}, + [PMGR_DEVICE_INDEX(CLK_GPIO)] = {&rPMGR_PS(GPIO)}, + [PMGR_DEVICE_INDEX(CLK_ISPSENS0)] = {&rPMGR_PS(ISPSENS0)}, + [PMGR_DEVICE_INDEX(CLK_UVD)] = {&rPMGR_PS(UVD)}, + [PMGR_DEVICE_INDEX(CLK_HSIC0PHY)] = {&rPMGR_PS(HSIC0PHY)}, + [PMGR_DEVICE_INDEX(CLK_AMC)] = {&rPMGR_PS(AMC)}, + [PMGR_DEVICE_INDEX(CLK_LIO_FAB)] = {&rPMGR_PS(LIO_FAB)}, + [PMGR_DEVICE_INDEX(CLK_LIO_LOGIC)] = {&rPMGR_PS(LIO_LOGIC)}, + [PMGR_DEVICE_INDEX(CLK_LIO)] = {&rPMGR_PS(LIO)}, + [PMGR_DEVICE_INDEX(CLK_AES0)] = {&rPMGR_PS(AES)}, + [PMGR_DEVICE_INDEX(CLK_MCA0)] = {&rPMGR_PS(MCA0)}, + [PMGR_DEVICE_INDEX(CLK_MCA1)] = {&rPMGR_PS(MCA1)}, + [PMGR_DEVICE_INDEX(CLK_MCA2)] = {&rPMGR_PS(MCA2)}, + [PMGR_DEVICE_INDEX(CLK_HFD)] = {&rPMGR_PS(HFD)}, + [PMGR_DEVICE_INDEX(CLK_SPI0)] = {&rPMGR_PS(SPI0)}, + [PMGR_DEVICE_INDEX(CLK_SPI1)] = {&rPMGR_PS(SPI1)}, + [PMGR_DEVICE_INDEX(CLK_UART0)] = {&rPMGR_PS(UART0)}, + [PMGR_DEVICE_INDEX(CLK_UART1)] = {&rPMGR_PS(UART1)}, + [PMGR_DEVICE_INDEX(CLK_UART2)] = {&rPMGR_PS(UART2)}, + [PMGR_DEVICE_INDEX(CLK_UART3)] = {&rPMGR_PS(UART3)}, + [PMGR_DEVICE_INDEX(CLK_UART4)] = {&rPMGR_PS(UART4)}, + [PMGR_DEVICE_INDEX(CLK_UART5)] = {&rPMGR_PS(UART5)}, + [PMGR_DEVICE_INDEX(CLK_UART6)] = {&rPMGR_PS(UART6)}, + [PMGR_DEVICE_INDEX(CLK_UART7)] = {&rPMGR_PS(UART7)}, + [PMGR_DEVICE_INDEX(CLK_I2C0)] = {&rPMGR_PS(I2C0)}, + [PMGR_DEVICE_INDEX(CLK_I2C1)] = {&rPMGR_PS(I2C1)}, + [PMGR_DEVICE_INDEX(CLK_I2C2)] = {&rPMGR_PS(I2C2)}, + [PMGR_DEVICE_INDEX(CLK_PWM0)] = {&rPMGR_PS(PWM0)}, + [PMGR_DEVICE_INDEX(CLK_USB)] = {&rPMGR_PS(USB)}, + [PMGR_DEVICE_INDEX(CLK_ETH)] = {&rPMGR_PS(ETH)}, + [PMGR_DEVICE_INDEX(CLK_ANS)] = {&rPMGR_PS(ANS)}, + [PMGR_DEVICE_INDEX(CLK_SDIO)] = {&rPMGR_PS(SDIO)}, + [PMGR_DEVICE_INDEX(CLK_DISP)] = {&rPMGR_PS(DISP)}, + [PMGR_DEVICE_INDEX(CLK_MIPI_DSI)] = {&rPMGR_PS(MIPI_DSI)}, + [PMGR_DEVICE_INDEX(CLK_ISP)] = {&rPMGR_PS(ISP)}, + [PMGR_DEVICE_INDEX(CLK_GFX)] = {&rPMGR_PS(GFX)}, + [PMGR_DEVICE_INDEX(CLK_MEDIA_FAB)] = {&rPMGR_PS(MEDIA_FAB)}, + [PMGR_DEVICE_INDEX(CLK_MSR)] = {&rPMGR_PS(MSR)}, + [PMGR_DEVICE_INDEX(CLK_VDEC)] = {&rPMGR_PS(VDEC)}, + [PMGR_DEVICE_INDEX(CLK_JPG)] = {&rPMGR_PS(JPG)}, + [PMGR_DEVICE_INDEX(CLK_VENC_CPU)] = {&rPMGR_PS(VENC_CPU)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST1)] = {&rPMGR_PS(USB2HOST1)}, + [PMGR_DEVICE_INDEX(CLK_SEP)] = {&rPMGR_PS(SEP)}, + [PMGR_DEVICE_INDEX(CLK_VENC_PIPE)] = {&rPMGR_PS(VENC_PIPE)}, + [PMGR_DEVICE_INDEX(CLK_VENC_ME)] = {&rPMGR_PS(VENC_ME)}, +}; + +/* ******************************************************************************** */ + +static void set_pll(uint32_t pll, uint32_t p, uint32_t m, uint32_t s, bool vco_out); +static uint32_t get_pll_frequency(uint32_t pll); +static uint32_t get_spare_frequency(uint32_t cnt); + +static void clocks_get_frequencies(void); +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk); +static void clocks_quiesce_internal(void); +static void apply_tunables(void); +static void power_on_sep(void); + +static void update_memory_clk_config(uint32_t performance_level); + +static void config_soc_perf_state(uint32_t state); +static void set_soc_perf_state(uint32_t target_state); +static void set_lppll(void); + +static void clock_update_range(uint32_t first, uint32_t last, const uint32_t clkdata); + +// current clock frequencies +static uint32_t clks[PMGR_CLK_COUNT + 1]; + +/* ******************************************************************************** */ + +static void set_pll(uint32_t pll, uint32_t p, uint32_t m, uint32_t s, bool vco_out) +{ + if (pll >= PMGR_PLL_COUNT) + panic("Invalid PLL %u", pll); + + rPMGR_PLL_CFG(pll) |= PMGR_PLL_CFG_VCO_OUT_SEL_INSRT(vco_out ? 1 : 0); + rPMGR_PLL_CTL(pll) = (PMGR_PLL_CTL_PRE_DIVN_INSRT(p) | PMGR_PLL_CTL_FB_DIVN_INSRT(m) | PMGR_PLL_CTL_OP_DIVN_INSRT(s) | PMGR_PLL_CTL_LOAD_INSRT(1)); + while (PMGR_PLL_CTL_PENDING_XTRCT(rPMGR_PLL_CTL(pll))); + + rPMGR_PLL_CTL(pll) |= PMGR_PLL_CTL_ENABLE_INSRT(1); + while (PMGR_PLL_CTL_PENDING_XTRCT(rPMGR_PLL_CTL(pll))); +} + +static uint32_t get_pll_frequency(uint32_t pll) +{ + uint32_t pllctl, pllcfg; + uint64_t freq = OSC_FREQ; + + if (pll >= PMGR_PLL_COUNT) + panic("Invalid PLL %u", pll); + + pllctl = rPMGR_PLL_CTL(pll); + pllcfg = rPMGR_PLL_CFG(pll); + + if (PMGR_PLL_CTL_ENABLE_XTRCT(pllctl) == 0) { + return 0; + } + else if (PMGR_PLL_CTL_BYPASS_XTRCT(pllctl)) { + return freq; + } + + if (PMGR_PLL_CFG_VCO_OUT_SEL_XTRCT(pllcfg)) { + // F_out = F_vco = ((24 / P) * M) * 2 + freq /= PMGR_PLL_CTL_PRE_DIVN_XTRCT(pllctl); + freq *= PMGR_PLL_CTL_FB_DIVN_XTRCT(pllctl); + freq *= 2; + } + else { + // F_out = ((24 / P) * M) / (S + 1) + freq /= PMGR_PLL_CTL_PRE_DIVN_XTRCT(pllctl); + freq *= PMGR_PLL_CTL_FB_DIVN_XTRCT(pllctl); + freq /= (1 + PMGR_PLL_CTL_OP_DIVN_XTRCT(pllctl)); + } + +#if DEBUG_BUILD + if (freq > 0xFFFFFFFF) + panic("Frequency value does not fit in uint32_t"); +#endif + + return (uint32_t)freq; +} + +static uint32_t get_spare_frequency(uint32_t spare) +{ + uint32_t reg_val, src_idx, src_clk, src_factor, div; + volatile uint32_t *spare_clkcfg = clk_configs[PMGR_CLK_S0 + spare].clock_reg; + + reg_val = *spare_clkcfg; + + div = PMGR_CLKCFG_DIVISOR_XTRCT(reg_val); + + if ((PMGR_CLKCFG_ENABLE_XTRCT(reg_val) == 0) || div == 0) + return 0; + + src_idx = PMGR_CLKCFG_SRC_SEL_XTRCT(reg_val); + src_clk = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].src_clk; + src_factor = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].factor; + + return (clks[src_clk] / src_factor) / div; +} + +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk) +{ + volatile uint32_t *reg; + uint32_t cnt, val, src_idx, src_clk, src_factor; + + if ((start_clk >= PMGR_CLK_SOURCE_FIRST && end_clk <= PMGR_CLK_SOURCE_LAST) || + (start_clk >= PMGR_CLK_MINI_FIRST && end_clk <= PMGR_CLK_MINI_LAST)) { + for (cnt = start_clk; cnt <= end_clk; cnt++) { + reg = clk_configs[cnt].clock_reg; + val = *reg; + + if (PMGR_CLKCFG_ENABLE_XTRCT(val) == 0) { + clks[cnt] = 0; + continue; + } + + src_idx = PMGR_CLKCFG_SRC_SEL_XTRCT(val); + src_clk = clk_configs[cnt].sources[src_idx].src_clk; + src_factor = clk_configs[cnt].sources[src_idx].factor; + clks[cnt] = clks[src_clk] / src_factor; + } + } +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_MCU_REF] = 10000000; + //clks[PMGR_CLK_MCU_FIXED]= 10000000; + //clks[PMGR_CLK_USB] = 12000000; + +#elif CONFIG_SIM + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + +#else + uint32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Use get_pll_frequency() to establish the frequency (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) + clks[PMGR_CLK_PLL0 + cnt] = get_pll_frequency(cnt); + + // Use get_spare_frequencies() to establish the frequencies for spare clocks (unconfigured will be skipped) + for (cnt = 0; cnt < sizeof(spare_clock_configs_active) / sizeof(spare_clock_configs_active[0]); cnt++) + clks[PMGR_CLK_S0 + cnt] = get_spare_frequency(cnt); + + clocks_get_frequencies_range(PMGR_CLK_MINI_FIRST, PMGR_CLK_MINI_LAST); + clocks_get_frequencies_range(PMGR_CLK_SOURCE_FIRST, PMGR_CLK_SOURCE_LAST); +#endif +} + +int clocks_init(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) + clocks_get_frequencies(); +#endif + + return 0; +} + +void clock_gate(int device, bool enable) +{ + volatile uint32_t *reg; + + // Make sure we are within limits + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + // Set the PS field to the requested level + if (enable) { + *reg |= PMGR_PS_MANUAL_PS_INSRT(PMGR_PS_RUN_MAX); + } else { + *reg &= ~PMGR_PS_MANUAL_PS_INSRT(PMGR_PS_RUN_MAX); + } + + // Wait for the MANUAL_PS and ACTUAL_PS fields to be equal + while (PMGR_PS_MANUAL_PS_XTRCT(*reg) != PMGR_PS_ACTUAL_PS_XTRCT(*reg)); +} + +static void restore_clock_config_reset_state(void) +{ + uint32_t current_select, entry_a; + uint32_t cnt; + + // 1. Restore PWR_*_CFG* registers to their reset defaults + rPMGR_CLK_POWER_CONFIG = 0; + + // 2. Write reset value to ACG, CLK_DIVIDER_ACG_CFG, CLK_DIVIDER_ACG_CFG1, and PLL_ACG_CFG + rPMGR_MISC_CFG_ACG = 0; + rPMGR_CLK_DIVIDER_ACG_CFG = 0; + + // 5a. Write reset value for all mux clock configs (excluding spares) + clock_update_range(PMGR_CLK_SOURCE_FIRST, PMGR_CLK_TMPS - 1, 0x80100000); + clock_update_range(PMGR_CLK_TMPS, PMGR_CLK_TMPS, 0x83100000); + clock_update_range(PMGR_CLK_TMPS + 1, PMGR_CLK_SOURCE_LAST, 0x80100000); + + // 5b. Write the desired DRAM clock configuration state into the SOC_PERF_STATE ENTRY_0A register, MCU_REF_CFG_SEL, + // MCU_REF_SRC_SEL fields; Write the reset value to all other fields in ENTRY_0 + current_select = PMGR_SOC_PERF_STATE_CTL_CURRENT_SELECT_XTRCT(rPMGR_SOC_PERF_STATE_CTL); + entry_a = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[0]; + entry_a &= ~PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + entry_a |= rPMGR_SOC_PERF_STATE_ENTRY_A(current_select) & PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = entry_a; + + // 6. Write the reset value to the SOC_PERF_STATE_CTL register + rPMGR_SOC_PERF_STATE_CTL = 0; + while (PMGR_SOC_PERF_STATE_CTL_PENDING_XTRCT(rPMGR_SOC_PERF_STATE_CTL)); + + // 7. Write the reset values to the SOC_PERF_STATE entry registers, except for BYPASS ENTRY_A + for (cnt = PMGR_SOC_PERF_STATE_FIRST_ENTRY; cnt < PMGR_SOC_PERF_STATE_ENTRY_COUNT; cnt++) { + if (cnt == PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) + continue; + + rPMGR_SOC_PERF_STATE_ENTRY_A(cnt) = 0; + } + + // 11. Write reset value to all PLLx_CTL, except for PLL0 + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 0) + continue; + + rPMGR_PLL_CTL(cnt) = PMGR_PLL_CTL_ENABLE_INSRT(1) | PMGR_PLL_CTL_BYPASS_INSRT(1) | PMGR_PLL_CTL_FB_DIVN_INSRT(1) | PMGR_PLL_CTL_PRE_DIVN_INSRT(1); + + while (PMGR_PLL_CTL_PENDING_XTRCT(rPMGR_PLL_CTL(cnt))); + } + + // 12. Write reset value to all other PLL registers, except for PLL0 + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 0) + continue; + + rPMGR_PLL_CFG(cnt) = PMGR_PLL_CFG_OFF_MODE_INSRT(PMGR_PLL_OFF_MODE_POWER_DOWN) | + PMGR_PLL_CFG_FRAC_LOCK_TIME_INSRT(0x48) | PMGR_PLL_CFG_LOCK_TIME_INSRT(0x348); + } + + // 13. Write reset value to spare and ISP_REF0 + clock_update_range(PMGR_CLK_SPARE_FIRST, PMGR_CLK_SPARE_LAST, 0x80000001); + + // Mini-PMGR + + // 2. Write the reset value to the CLK_DIVIDER_ACG_CFG register + rMINIPMGR_CLK_DIVIDER_ACG_CFG = 0; + + // 3. Write the reset value to all mux clock config registers + clock_update_range(PMGR_CLK_MINI_FIRST, PMGR_CLK_MINI_LAST, 0x80100000); + + // 4. Write the reset value to LPPLL_CTL register + rMINIPMGR_LPPLL_CTL = MINIPMGR_LPPLL_CTL_ENABLE_INSRT(1) | MINIPMGR_LPPLL_CTL_BYPASS_INSRT(1); + while (MINIPMGR_LPPLL_CTL_PENDING_XTRCT(rMINIPMGR_LPPLL_CTL)); + + // 5. Write the reset value to LPPLL_CFG register + rMINIPMGR_LPPLL_CFG = 0x00000010; + + // 6. Write the reset value to the MISC_CFG_ACG register + rMINIPMGR_MISC_CFG_ACG = 0; +} + +static void clocks_quiesce_internal(void) +{ +#if APPLICATION_SECUREROM + // Workaround for M8: Set ASYNC_XOVER_ACG.GLOBAL_ENABLE at boot before other PS registers + rPMGR_MISC_CFG_ASYNC_XOVER_ACG = PMGR_MISC_CFG_ASYNC_XOVER_ACG_GLOBAL_ENABLE_INSRT(1); +#endif + + // Turn on these domains + clock_gate(CLK_AOP, 1); + clock_gate(CLK_DEBUG, 1); + clock_gate(CLK_AOP_GPIO, 1); + clock_gate(CLK_AOP_CPU, 1); + clock_gate(CLK_AOP_FILTER, 1); + clock_gate(CLK_AOP_FILTER_DMA, 1); // PL080 DMA to zero out memory - rdar://problem/19986351 + + clock_gate(CLK_SCU, 1); + clock_gate(CLK_CPU0, 1); + clock_gate(CLK_PIO, 1); + clock_gate(CLK_CPU_FAB, 1); + clock_gate(CLK_NRT_FAB, 1); + + clock_gate(CLK_AIC, 1); + clock_gate(CLK_AMC, 1); + clock_gate(CLK_LIO_FAB, 1); + clock_gate(CLK_LIO_LOGIC, 1); + clock_gate(CLK_LIO, 1); + clock_gate(CLK_GPIO, 1); + clock_gate(CLK_AES0, 1); + clock_gate(CLK_USB, 1); + clock_gate(CLK_ETH, 1); + clock_gate(CLK_ANS, 1); + + // Turn off these domains + clock_gate(CLK_AOP_I2CM1, 0); + clock_gate(CLK_AOP_RTCPU, 0); + clock_gate(CLK_AOP_UART0, 0); + clock_gate(CLK_AOP_UART1, 0); + clock_gate(CLK_AOP_UART2, 0); + clock_gate(CLK_AOP_I2CM, 0); + clock_gate(CLK_AOP_LPD0, 0); + clock_gate(CLK_AOP_HPDS, 0); + clock_gate(CLK_AOP_HPDSC, 0); + clock_gate(CLK_AOP_HPDD, 0); + + clock_gate(CLK_CPU1, 0); + clock_gate(CLK_RT_FAB, 0); + clock_gate(CLK_ISPSENS0, 0); + clock_gate(CLK_UVD, 0); + clock_gate(CLK_HSIC0PHY, 0); + clock_gate(CLK_MCA0, 0); + clock_gate(CLK_MCA1, 0); + clock_gate(CLK_MCA2, 0); + clock_gate(CLK_HFD, 0); + clock_gate(CLK_SPI0, 0); + clock_gate(CLK_SPI1, 0); + clock_gate(CLK_UART0, 0); + clock_gate(CLK_UART1, 0); + clock_gate(CLK_UART2, 0); + clock_gate(CLK_UART3, 0); + clock_gate(CLK_UART4, 0); + clock_gate(CLK_UART5, 0); + clock_gate(CLK_UART6, 0); + clock_gate(CLK_UART7, 0); + clock_gate(CLK_I2C0, 0); + clock_gate(CLK_I2C1, 0); + clock_gate(CLK_I2C2, 0); + clock_gate(CLK_PWM0, 0); + clock_gate(CLK_SDIO, 0); + clock_gate(CLK_DISP, 0); + clock_gate(CLK_MIPI_DSI, 0); + clock_gate(CLK_ISP, 0); + clock_gate(CLK_GFX, 0); + clock_gate(CLK_MEDIA_FAB, 0); + clock_gate(CLK_MSR, 0); + clock_gate(CLK_VDEC, 0); + clock_gate(CLK_JPG, 0); + clock_gate(CLK_VENC_CPU, 0); + clock_gate(CLK_USB2HOST1, 0); + + restore_clock_config_reset_state(); +} + +static void enable_bira_work_around(void) +{ + // Workaround for M8: DFT logic isn't reset when a partition powers up while another one is repaired + // Note: The reconfig part of this workaround is not done by pmgr driver. + static const uint32_t domain[] = { + CLK_SDIO, + CLK_DISP, + CLK_MIPI_DSI, + CLK_ISP, + CLK_GFX, + CLK_MSR, + CLK_VDEC, + CLK_JPG, + CLK_VENC_CPU, + CLK_VENC_PIPE, + CLK_VENC_ME, + }; + + // Turn on the blocks + for (uint32_t i = 0; i < sizeof(domain)/sizeof(domain[0]); i++) { + clock_gate(domain[i], true); + } + + // Turn off the blocks + for (uint32_t i = sizeof(domain)/sizeof(domain[0]); i > 0; i--) { + clock_gate(domain[i - 1], false); + } +} + +static void apply_tunables(void) +{ + uint32_t i, j; + for (i = 0; tunables_pmgr[i].chip_rev < UINT32_MAX; i++) { + const struct tunable_struct *tunable_chip = tunables_pmgr[i].tunable; + void *tunable_base = (void *)tunables_pmgr[i].base_address; + uint32_t tunable_index; + + if (tunables_pmgr[i].chip_rev > chipid_get_chip_revision()) { + continue; + } + + for (tunable_index = 0; tunable_chip[tunable_index].offset != -1; tunable_index++) { + uint32_t val; + bool filtered = false; + + // Skip filtered cold boot tunables + for (j = 0; tunables_filtered_pmgr[j].chip_rev < UINT32_MAX; j++) { + if (tunables_pmgr[i].chip_rev == tunables_filtered_pmgr[j].chip_rev && + tunables_pmgr[i].base_address + tunable_chip[tunable_index].offset >= tunables_filtered_pmgr[j].starting_address && + tunables_pmgr[i].base_address + tunable_chip[tunable_index].offset <= tunables_filtered_pmgr[j].ending_address && + tunables_filtered_pmgr[j].cold_boot) { + filtered = true; + break; + } + } + + if (filtered) + continue; + + // TODO: Handle reconfig tunables and filtered reconfig tunables + + val = *((volatile uint32_t *)(tunable_base + tunable_chip[tunable_index].offset)); + + if ((val & tunable_chip[tunable_index].mask) == tunable_chip[tunable_index].value) { + // Tunable already applied. No need to apply it again + continue; + } + + val &= ~tunable_chip[tunable_index].mask; + val |= tunable_chip[tunable_index].value; + + *((volatile uint32_t *)(tunable_base + tunable_chip[tunable_index].offset)) = (uint32_t)val; + } + } +} + +static void set_nco_clocks(void) +{ + // Enable this NCO with alg_ref0_clk and nco_ref0_clk. + // Note: clk_configs assumes all NCOs use nco_ref0_clk + rPMGR_NCO_CLK_CFG(0) |= (PMGR_CLKCFG_NCO_REF0_CLK_CFG_ENABLE_INSRT(1)); + rPMGR_NCO_CLK_CFG(1) |= (PMGR_CLKCFG_NCO_REF1_CLK_CFG_ENABLE_INSRT(1)); +} + +static void set_clkcfg(volatile uint32_t *clkcfg, uint32_t value) +{ + uint32_t val; + // Modify only the fields in mask + uint32_t mask = PMGR_CLKCFG_ENABLE_UMASK | PMGR_CLKCFG_SRC_SEL_UMASK | + PMGR_CLKCFG_DIVISOR_UMASK | PMGR_CLKCFG_WAIT_COUNTER_UMASK; + + if (value & ~mask) + panic("Fields mismatch with mask for value %#u in CLK_CFG %#u", value, (uint32_t) clkcfg); + + val = (*clkcfg) & ~mask; + val |= value & mask; + + *clkcfg = val; + + while (PMGR_CLKCFG_PENDING_XTRCT(*clkcfg)); +} + +/* + * clocks_set_default - called by SecureROM, LLB, iBSS main via + * platform_init_setup_clocks, so the current state of the chip is + * either POR, or whatever 'quiesce' did when leaving SecureROM. + */ +int clocks_set_default(void) +{ + uint32_t cnt; + volatile uint32_t *clkcfg; + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) || APPLICATION_OSV + enable_bira_work_around(); +#endif + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Change all clocks to something safe + clocks_quiesce_internal(); + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) || APPLICATION_OSV + apply_tunables(); +#endif + +// Setup active DVFM and SOC PERF states for the stage of boot. +#if APPLICATION_SECUREROM + config_soc_perf_state(kSOC_PERF_STATE_SECUREROM); +#endif + + config_soc_perf_state(kSOC_PERF_STATE_VMIN); + +#ifdef LPPLL_T + set_lppll(); +#endif +#ifdef PLL0_T + set_pll(PLL0, PLL0_P, PLL0_M, PLL0_S, PLL0_VCO_OUT); +#endif +#ifdef PLL1_T + set_pll(PLL1, PLL1_P, PLL1_M, PLL1_S, PLL1_VCO_OUT); +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Turn on NCO clocks before enabling MCA clocks. + set_nco_clocks(); +#endif + + set_soc_perf_state(SOC_PERF_STATE_ACTIVE); + + // Set all spare clock divs to their active values + for (cnt = 0; cnt < sizeof(spare_clock_configs_active) / sizeof(spare_clock_configs_active[0]); cnt++) { + clkcfg = clk_configs[spare_clock_configs_active[cnt].clk].clock_reg; + + set_clkcfg(clkcfg, spare_clock_configs_active[cnt].clock_reg_val); + } + + // Set all non-spare clock divs to their active values + for (cnt = 0; cnt < sizeof(clk_configs_active) / sizeof(clk_configs_active[0]); cnt++) { + clkcfg = clk_configs[clk_configs_active[cnt].clk].clock_reg; + + set_clkcfg(clkcfg, clk_configs_active[cnt].clock_reg_val); + } + + power_on_sep(); + + clocks_get_frequencies(); + + return 0; +} + +void clocks_quiesce(void) +{ + clocks_quiesce_internal(); +} + +uint32_t clocks_set_performance(uint32_t performance_level) +{ + uint32_t old_perf_level = perf_level; + +#if APPLICATION_IBOOT + uint32_t entry_a; + + switch (performance_level) { + case kPerformanceMemoryLow: + case kPerformanceMemoryMid: + case kPerformanceMemoryFull: + entry_a = rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)); + entry_a &= ~PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + + if (performance_level == kPerformanceMemoryLow) + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x3, 0x4); // 48 MHz MCU_REF_CLK, 48 MHz bin + else + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x0, 0x3); // 88.8 MHz MCU_REF_CLK, 1600 MHz bin + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)) = entry_a; + + set_soc_perf_state(kSOC_PERF_STATE_VMIN); + perf_level = performance_level; + break; + default: + break; + } + + clocks_get_frequencies_range(PMGR_CLK_MCU_REF, PMGR_CLK_MCU_REF); +#endif + + return old_perf_level; +} + +void clock_get_frequencies(uint32_t *clocks, uint32_t count) +{ + uint32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) cnt = count; + + memcpy(clocks, clks, cnt * sizeof(uint32_t)); +} + +uint32_t clock_get_frequency(int clock) +{ + uint32_t freq = OSC_FREQ; + + switch (clock) { + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + freq = clks[PMGR_CLK_OSC]; + break; + case CLK_ANS_LINK: + freq = clks[PMGR_CLK_ANS]; + break; + case CLK_BUS: + case CLK_PCLK: + case CLK_PERIPH: + freq = clks[PMGR_CLK_LIO]; + break; + case CLK_MEM: + freq = clks[PMGR_CLK_MCU_REF]; + break; + case CLK_CPU: + freq = clks[PMGR_CLK_MCU_REF]; + break; + case CLK_AOP: + freq = clks[PMGR_CLK_AOP]; + break; + default: + break; + } + + return freq; +} + +static void clock_update_frequency(uint32_t clk, uint32_t freq) +{ + uint32_t src_idx, src_clk, src_factor, reg; + bool freq_supported = false; + volatile uint32_t *clkcfg = clk_configs[clk].clock_reg; + + if (freq == 0) + { + return; + } + + for (src_idx = 0; src_idx < CLOCK_SOURCES_MAX && clk_configs[clk].sources[src_idx].factor != 0; src_idx++) + { + src_clk = clk_configs[clk].sources[src_idx].src_clk; + src_factor = clk_configs[clk].sources[src_idx].factor; + + // Round the requested frequency to closest MHz value and check if we have a match + if ((freq / 1000000) == ((clks[src_clk] / src_factor) / 1000000)) + { + freq_supported = true; + break; + } + } + + if (freq_supported) + { + // Configure clock + reg = *clkcfg; + reg &= ~(PMGR_CLKCFG_SRC_SEL_UMASK); + reg |= PMGR_CLKCFG_SRC_SEL_INSRT(src_idx); + set_clkcfg(clkcfg, reg); + } +} + +void clock_set_frequency(int clock, uint32_t divider, uint32_t pll_p, uint32_t pll_m, uint32_t pll_s, uint32_t pll_t) +{ + uint32_t clk = PMGR_CLK_OSC; + + switch (clock) { + + case CLK_VCLK0: + clk = PMGR_CLK_VID; + break; + + default: + break; + } + + if (clk >= PMGR_CLK_SOURCE_FIRST && clk <= PMGR_CLK_SOURCE_LAST) { + clock_update_frequency(clk, pll_t); + clocks_get_frequencies_range(clk, clk); + } +} + +void clock_reset_device(int device) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + switch (device) { + case CLK_AMC: + default: + *reg |= PMGR_PS_RESET_INSRT(1); + spin(1); + *reg &= ~PMGR_PS_RESET_INSRT(1); + break; + } +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_system_reset(); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_power_init(void) +{ +} + +void platform_power_spin(uint32_t usecs) +{ + extern void aic_spin(uint32_t usecs); + aic_spin(usecs); +} + +#if WITH_DEVICETREE +void pmgr_update_device_tree(DTNode *pmgr_node) +{ +} +#endif + +static void config_soc_perf_state(uint32_t state) +{ + uint32_t index = state; + +#if APPLICATION_IBOOT + if (index >= kSOC_PERF_STATE_IBOOT_CNT) + index = kSOC_PERF_STATE_VMIN; +#endif + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[index].entry[0]; +} + +static void set_soc_perf_state(uint32_t target_state) +{ + rPMGR_SOC_PERF_STATE_CTL = PMGR_SOC_PERF_STATE_TO_ENTRY(target_state); + + while (PMGR_SOC_PERF_STATE_CTL_PENDING_XTRCT(rPMGR_SOC_PERF_STATE_CTL)); +} + +static void set_lppll(void) +{ + rMINIPMGR_LPPLL_CTL = MINIPMGR_LPPLL_CTL_ENABLE_INSRT(1); + + while (MINIPMGR_LPPLL_CTL_PENDING_XTRCT(rMINIPMGR_LPPLL_CTL)); +} + +static void clock_update_range(uint32_t first, uint32_t last, const uint32_t clkdata) +{ + volatile uint32_t *reg; + uint32_t cnt; + + for (cnt = first; cnt <= last; cnt++) { + reg = clk_configs[cnt].clock_reg; + set_clkcfg(reg, clkdata); + } +} + +static void power_on_sep(void) +{ + volatile uint32_t *reg; + uint32_t val; + + reg = device_configs[PMGR_DEVICE_INDEX(CLK_SEP)].ps_reg; + + val = *reg; + val &= ~(PMGR_PS_SEP_PS_AUTO_PM_EN_INSRT(1) | PMGR_PS_SEP_PS_FORCE_NOACCESS_INSRT(1)); + *reg = val; + while (PMGR_PS_SEP_PS_ACTUAL_PS_XTRCT(*reg) != PMGR_PS_RUN_MAX); // Wait for SEP to turn on. + + return; +} diff --git a/platform/t8002/pmgr/rules.mk b/platform/t8002/pmgr/rules.mk new file mode 100644 index 0000000..f64871a --- /dev/null +++ b/platform/t8002/pmgr/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_TIMER=1 \ + WITH_FIQ_TIMER=1 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/t8002/rules.mk b/platform/t8002/rules.mk new file mode 100644 index 0000000..8497939 --- /dev/null +++ b/platform/t8002/rules.mk @@ -0,0 +1,139 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +ARM_CPU := cortex-a7 + +# Devmap chip ID +DEVMAP_CHIP_ID := 8002 + +SPDS_CHIP_REV := b0 + +IRQ_STACK_SIZE := 4096 + +# srom is always defined in here +ifeq ($(TEXT_BANK),srom) + TEXT_BASE := 0x00000000 +endif + +# Overriding SRAM_LEN is not allowed. +ifeq ($(TEXT_BANK),sram) + # SRAM TEXT_BASE is fixed by SecureROM. + TEXT_BASE := 0x48818000 + + # iBSS/LLB memory configuration + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT:= 1024*1024 + endif +endif + +# platform target can override sdram config by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(SDRAM_LEN),) + SDRAM_LEN := 512*1024*1024 + + # iBoot/iBEC memory configuration + ifeq ($(TEXT_BANK),sdram) + # SDRAM TEXT_BASE is now set such that you don't have to do lots of math to + # calulate the correct value if you change any of the other region sizes: + # TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 64MB + TEXT_BASE := 0x9C000000 + + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := 1024*1024 + endif + endif +endif + +ifeq ($(TEXT_BANK),srom) + MAX_DFU_SIZE := 128*1024 +endif +ifeq ($(TEXT_BANK),sram) + MAX_DFU_SIZE := 1056*1024 +endif + +# Platform target can override any of these sizes by specifying in target config file (apps/iBoot/$target-config.mk) +ifeq ($(TZ0_SIZE),) + TZ0_SIZE := 8*1024*1024 +endif +ifeq ($(DISPLAY_SIZE),) + DISPLAY_SIZE := 4*1024*1024 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + L2_CACHE_SIZE=512*1024 \ + L2_CACHE_SETS=10 \ + WITH_NON_COHERENT_DMA=1 \ + ANC_PPNNPL_DS_DRIVE_STRENGTH=6 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_HOLD_TIME=1 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_SETUP_TIME=1 \ + ANC_LINK_SDR_REN_HOLD_TIME=0 \ + ANC_LINK_SDR_REN_SETUP_TIME=1 \ + ANC_LINK_SDR_WEN_HOLD_TIME=0 \ + ANC_LINK_SDR_WEN_SETUP_TIME=1 \ + ANC_LINK_SDR_DATA_CAPTURE_DELAY=0 \ + ANC_LINK_SDR_CLE_ALE_SETUP_TIME=1 \ + ANC_BOOT_CONTROLLERS=1 \ + ANC_TOGGLE_SUPPORTED=0 \ + DISPLAY_SIZE="$(DISPLAY_SIZE)ULL" \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=256 \ + PLATFORM_SPDS_CHIP_REV=$(PLATFORM)/$(SPDS_CHIP_REV) \ + SDRAM_LEN="$(SDRAM_LEN)ULL" \ + TZ0_SIZE="$(TZ0_SIZE)ULL" \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" \ + WITH_DPA=1 \ + WITH_DMA_CLEAR=1 + +# This platform contains corecrypto, needs large idle task stack for DFU stages. +ifeq ($(PRODUCT),iBSS) + OPTIONS += \ + IDLE_TASK_SIZE=0x3000 \ + PLATFORM_START_FUNCTION=_platform_start +endif + +ifeq ($(PRODUCT),LLB) + OPTIONS += \ + IDLE_TASK_SIZE=0x3000 \ + PLATFORM_START_FUNCTION=_platform_start +endif + +ifeq ($(APPLICATION),SecureROM) + DATA_BASE := 0x48800000 + OPTIONS += \ + IDLE_TASK_SIZE=0x3000 \ + WITH_ROM_TRAMPOLINE=1 \ + DATA_BASE="$(DATA_BASE)" + + GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) + ifeq ($(CONFIGS),fpga) + OPTIONS += \ + SUPPORT_FPGA=1 + endif +endif + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/trampoline.o \ + $(LOCAL_DIR)/init.o diff --git a/platform/t8002/trampoline.S b/platform/t8002/trampoline.S new file mode 100644 index 0000000..6dcf21e --- /dev/null +++ b/platform/t8002/trampoline.S @@ -0,0 +1,64 @@ + +/* + * Copyright (c) 2014 - 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include + +// iBSS & LLB trampoline +#if APPLICATION_IBOOT && (PRODUCT_IBSS || PRODUCT_LLB) + .text + .arm + .align 12 + .globl _boot_handoff_trampoline, _boot_handoff_trampoline_end +_boot_handoff_trampoline: + // Reset VBAR to 0 + mov r1, #0 // iBSS and LLB doesn't pass forward anything to next stage. + mcr p15, 0, r1, c12, c0, 0 + isb + bx r0 +_boot_handoff_trampoline_end: +#endif + +// SecureROM trampoline +#if WITH_ROM_TRAMPOLINE + .text + .arm + .align 12 + .globl _boot_handoff_trampoline, _boot_handoff_trampoline_end +_boot_handoff_trampoline: + ldr r1, _trampoline_reg + ldr r2, _trampoline_val + ldr r3, [r1] + orr r3, r2 + str r3, [r1] + dsb sy + ldr r3, [r1] + tst r3, r2 // Verify ROM access is disabled + beq 1f + + mov r4, r0 + mov r0, #0 + mov r1, #0 + mov r2, #0 + mov r3, #0 + bx r4 + +1: // trampoline spin function + wfi + b . + +_trampoline_reg: + .word SECURITY_REG +_trampoline_val: + .word ROM_READ_DISABLE + .align CPU_CACHELINE_SHIFT +_boot_handoff_trampoline_end: +#endif diff --git a/platform/t8010/apcie/apcie.c b/platform/t8010/apcie/apcie.c new file mode 100644 index 0000000..50ea9da --- /dev/null +++ b/platform/t8010/apcie/apcie.c @@ -0,0 +1,896 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifdef APCIE_DEBUG_LEVEL +#define DEBUG_LEVEL APCIE_DEBUG_LEVEL +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include SUB_PLATFORM_SPDS_HEADER(apcie_common) +#include SUB_PLATFORM_SPDS_HEADER(apcie_phy_glue) +#include SUB_PLATFORM_SPDS_HEADER(pma_cmn_registers) +#include SUB_PLATFORM_SPDS_HEADER(pma_rx_lane_registers) +#include SUB_PLATFORM_SPDS_HEADER(pma_tx_lane_registers) +#include SUB_PLATFORM_SPDS_HEADER(x2_pcie_rc) + +#include SUB_PLATFORM_TUNABLE_HEADER(apcie_common) +#include SUB_PLATFORM_TUNABLE_HEADER(apcie_config) +#include SUB_PLATFORM_TUNABLE_HEADER(x2_pcie_rc) + +#define MAX_DT_PROPERTY_SIZE 4096 + +//////////////////////////////////////////////////////////////////////////////// + +// APCIe common tunables + +#if APPLICATION_SECUREROM + +// T8010 A0 +static const struct tunable_struct common_tunables_a0 [] = { + PCIE_APCIE_COMMON_SECURE_ROM_TUNABLES_T8010_A0 +}; + +#else // !APPLICATION_SECUREROM + +// T8010 A0 +static const struct tunable_struct common_tunables_a0 [] = { + PCIE_APCIE_COMMON_DEFAULT_TUNABLES_T8010_A0 +}; + +// APCIe common NVMe tunables + +// T8010 A0 +static const struct tunable_struct common_nvme_tunables_a0 [] = { + PCIE_APCIE_COMMON_NVME_TUNABLES_T8010_A0 +}; + +// T8010 chip revision table +static const struct tunable_chip_struct tunables_nvme_common [] = { + {CHIP_REVISION_A0, APCIE_COMMON_BASE_ADDR, common_nvme_tunables_a0 , NULL, false}, +}; + +#endif // APPLICATION_SECUREROM + +// T8010 chip revision table +static const struct tunable_chip_struct tunables_pcie_common [] = { + {CHIP_REVISION_A0, APCIE_COMMON_BASE_ADDR, common_tunables_a0 , NULL, false}, +}; + +//////////////////////////////////////////////////////////////////////////////// + +// APCIe config tunables + +#if APPLICATION_SECUREROM + +// T8010 A0 +static const struct tunable_struct port0_config_tunable_a0[] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct port1_config_tunable_a0[] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct port2_config_tunable_a0[] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct port3_config_tunable_a0[] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 +}; + +#else // !APPLICATION_SECUREROM + +// T8010 A0 +static const struct tunable_struct port0_config_tunable_a0[] = { + PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct port1_config_tunable_a0[] = { + PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct port2_config_tunable_a0[] = { + PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct port3_config_tunable_a0[] = { + PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 +}; + +#endif // !APPLICATION_SECUREROM + +// T8010 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_port_0[] = { + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(0), port0_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_1[] = { + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(1), port1_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_2[] = { + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(2), port2_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_port_3[] = { + {CHIP_REVISION_A0, APCIE_PORT_BASE_ADDR(3), port3_config_tunable_a0, NULL, false}, +}; + +// T8010 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_ports[APCIE_NUM_LINKS] = { + { tunables_pcie_config_port_0, ARRAY_SIZE(tunables_pcie_config_port_0), 0 }, + { tunables_pcie_config_port_1, ARRAY_SIZE(tunables_pcie_config_port_1), 0 }, + { tunables_pcie_config_port_2, ARRAY_SIZE(tunables_pcie_config_port_2), 0 }, + { tunables_pcie_config_port_3, ARRAY_SIZE(tunables_pcie_config_port_3), 0 }, +}; + +//////////////////////////////////////////////////////////////////////////////// + +// PCIe root complex tunables + +#if APPLICATION_SECUREROM + +// T8010 A0 +static const struct tunable_struct rc0_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC0_SECURE_ROM_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct rc1_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC1_SECURE_ROM_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct rc2_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC2_SECURE_ROM_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct rc3_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC3_SECURE_ROM_TUNABLES_T8010_A0 +}; + +#else // !APPLICATION_SECUREROM + +// T8010 A0 +static const struct tunable_struct rc0_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct rc1_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct rc2_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_T8010_A0 +}; + +static const struct tunable_struct rc3_config_tunable_a0[] = { + PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_T8010_A0 +}; + +#endif // !APPLICATION_SECUREROM + +// T8010 chip revision table +static const struct tunable_chip_struct tunables_pcie_config_rc_0[] = { + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(0), rc0_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_1[] = { + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(1), rc1_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_2[] = { + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(2), rc2_config_tunable_a0, NULL, false}, +}; + +static const struct tunable_chip_struct tunables_pcie_config_rc_3[] = { + {CHIP_REVISION_A0, PCIE_PORT_BASE_ADDR(3), rc3_config_tunable_a0, NULL, false}, +}; + +// T8010 port chip revision table +static const struct tunable_chip_array tunables_pcie_config_rc[APCIE_NUM_LINKS] = { + { tunables_pcie_config_rc_0, ARRAY_SIZE(tunables_pcie_config_rc_0), 0 }, + { tunables_pcie_config_rc_1, ARRAY_SIZE(tunables_pcie_config_rc_1), 0 }, + { tunables_pcie_config_rc_2, ARRAY_SIZE(tunables_pcie_config_rc_2), 0 }, + { tunables_pcie_config_rc_3, ARRAY_SIZE(tunables_pcie_config_rc_3), 0 }, +}; + +//////////////////////////////////////////////////////////////////////////////// + +// PHY tunables + +// T8010 A0 +static const struct tunable_struct phy_glue_tunable_a0[] = { +#ifdef PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_T8010_A0 + PCIE_APCIE_PHY_GLUE_DEFAULT_TUNABLES_T8010_A0 +#else + // Temporary until tunables are actually defined. + TUNABLE_TABLE_END_MARKER +#endif +}; + +const struct tunable_chip_struct tunables_pcie_phy[] = { + {CHIP_REVISION_A0, APCIE_PHY_BASE_ADDR, phy_glue_tunable_a0, NULL, false}, +}; + +//////////////////////////////////////////////////////////////////////////////// + +static bool s3e_mode; +static bool s3e_reset_on_enable_disable; +static uint32_t link_enable_count; + + +#define SET_REG(reg, value) set_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET, (value)) +#define GET_REG(reg) get_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET) +#define OR_REG(reg, value) or_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET, (value)) +#define AND_REG(reg, value) and_reg(APCIE_COMMON_BASE_ADDR, APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET, (value)) + +#define PORT_STRIDE (APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_OFFSET - APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_OFFSET) +#define PORT_REG(reg, port) (APCIE_COMMON_BLK_APCIE_ ## reg ## _OFFSET) + (PORT_STRIDE * (port)) +#define SET_PORT_REG(reg, port, value) set_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), value) +#define GET_PORT_REG(reg, port) get_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port)) +#define OR_PORT_REG(reg, port, value) or_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), value) +#define AND_PORT_REG(reg, port, value) and_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), value) + +#define PORT_REG_BIT_SHIFT(reg, bit) (APCIE_COMMON_BLK_APCIE_ ## reg ## _ ## bit ## _SHIFT) +#define SET_PORT_REG_BIT(reg, port, b) or_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), 1 << PORT_REG_BIT_SHIFT(reg, b)) +#define CLR_PORT_REG_BIT(reg, port, b) and_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port), ~(1 << PORT_REG_BIT_SHIFT(reg, b))) +#define GET_PORT_REG_BIT(reg, port, b) ((get_reg(APCIE_COMMON_BASE_ADDR, PORT_REG(reg, port)) >> PORT_REG_BIT_SHIFT(reg, b)) & 1) + +#define SET_APCIE_CONFIG_REG(reg, port, value) set_reg(APCIE_PORT_BASE_ADDR(port), (reg), (value)) +#define GET_APCIE_CONFIG_REG(reg, port) get_reg(APCIE_PORT_BASE_ADDR(port), (reg)) +#define OR_APCIE_CONFIG_REG(reg, port, value) or_reg(APCIE_PORT_BASE_ADDR(port), (reg), (value)) +#define AND_APCIE_CONFIG_REG(reg, port, value) and_reg(APCIE_PORT_BASE_ADDR(port), (reg), (value)) + +#define PHY_SET_REG(reg, value) set_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET, (value)) +#define PHY_GET_REG(reg) get_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET) +#define PHY_OR_REG(reg, value) or_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET, (value)) +#define PHY_AND_REG(reg, value) and_reg(APCIE_PHY_BASE_ADDR, APCIE_PHY_GLUE_BLK_ ## reg ## _OFFSET, (value)) + +#define SET_PMA_CMN_REG(reg, value) set_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET, (value)) +#define GET_PMA_CMN_REG(reg) get_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET) +#define OR_PMA_CMN_REG(reg, value) or_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET, (value)) +#define AND_PMA_CMN_REG(reg, value) and_reg(APCIE_PHY_PMA_COMMON_BASE_ADDR, PMA_CMN_REGISTERS_BLK_ ## reg ## _OFFSET, (value)) + +#define PMA_RX_REG(reg, lane) (PMA_RX_LANE_REGISTERS_BLK_ ## reg ## _OFFSET) + (APCIE_PHY_PMA_RX_LANE_STRIDE * (lane)) +#define SET_PMA_RX_REG(reg, lane, value) set_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane), value) +#define GET_PMA_RX_REG(reg, lane) get_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane)) +#define OR_PMA_RX_REG(reg, lane, value) or_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane), value) +#define AND_PMA_RX_REG(reg, lane, value) and_reg(APCIE_PHY_PMA_RX_LANE_BASE_ADDR, PMA_RX_REG(reg, lane), value) + +#define PMA_TX_REG(reg, lane) (PMA_TX_LANE_REGISTERS_BLK_ ## reg ## _OFFSET) + (APCIE_PHY_PMA_TX_LANE_STRIDE * (lane)) +#define SET_PMA_TX_REG(reg, lane, value) set_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane), value) +#define GET_PMA_TX_REG(reg, lane) get_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane)) +#define OR_PMA_TX_REG(reg, lane, value) or_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane), value) +#define AND_PMA_TX_REG(reg, lane, value) and_reg(APCIE_PHY_PMA_TX_LANE_BASE_ADDR, PMA_TX_REG(reg, lane), value) + + +static void set_reg(uintptr_t base, uint32_t offset, uint32_t value) +{ + dprintf(DEBUG_SPEW, "apcie: set_reg[0x%lx] = 0x%x\n", base + offset, value); + *(volatile uint32_t *)(base + offset) = value; +} + +static uint32_t get_reg(uintptr_t base, uint32_t offset) +{ + uint32_t value; + + dprintf(DEBUG_SPEW, "acpie: get_reg[0x%lx]", base + offset); + value = *(volatile uint32_t *)(base + offset); + + dprintf(DEBUG_SPEW, " = 0x%x\n", value); + return value; +} + +static void or_reg(uintptr_t base, uint32_t offset, uint32_t value) +{ + uint32_t orig; + + orig = get_reg(base, offset); + set_reg(base, offset, orig | value); +} + +static void and_reg(uintptr_t base, uint32_t offset, uint32_t value) +{ + uint32_t orig; + + orig = get_reg(base, offset); + set_reg(base, offset, orig & value); +} + +void apcie_set_s3e_mode(bool reset_on_enable) +{ + s3e_mode = true; + s3e_reset_on_enable_disable = reset_on_enable; +} + +static void apcie_enable_root_complex(void) +{ + // PCIe Initialization Sequence v1.12.02, section 6.1.2: + // 1. Program PCIE PLL parameters from PMGR fuses done in pmgr.c set_pll(). + + // 2. Turn on PCIE in PCIE_PS register + clock_gate(CLK_PCIE, true); + + // 3. Enable the 24Mhz clock + clock_gate(CLK_PCIE_AUX, true); + + // 4. Enable the ref clock + clock_gate(CLK_PCIE_REF, true); + + // Apply common tunables. + platform_apply_tunables(tunables_pcie_common , ARRAY_SIZE(tunables_pcie_common ), "PCIe common"); +#if !APPLICATION_SECUREROM + platform_apply_tunables(tunables_nvme_common , ARRAY_SIZE(tunables_nvme_common ), "NVMe common"); +#endif + + // 5. Enable clock auto clock management for the "common" clock domain -- not doing this in iBoot. + + // 6. Enable dynamic clock gating of per-link aux_xlk -- not doing this in iBoot. + + // 7. NAND_SYS_CLK/S3E_RESET_N reset sequence defined in Section 5.5. + if (s3e_mode) { + + if (s3e_reset_on_enable_disable) { + AND_REG(NANDRST_CTRL, ~APCIE_COMMON_BLK_APCIE_NANDRST_CTRL_NANDRST_UMASK); + } + + gpio_configure(GPIO_NAND_SYS_CLK, GPIO_CFG_FUNC0); + OR_REG(NANDSYSCLK_CTRL, APCIE_COMMON_BLK_APCIE_NANDSYSCLK_CTRL_NANDSYSCLK_EN_UMASK); + // S3e spec requires 32 24 Mhz clock cycles from NANDSYSCLK to reset deassertion. + // But, APCIe spec requires we wait 100 microseconds (Cayman PCIe spec section 5.5) + spin(100); + + // De-assert S3E_RESET_N if it's already asserted. Except when platform specified + // s3e_reset_on_enable_disable (for example, in iBEC), we only de-assert the reset, + // and then leave it de-asserted + OR_REG(NANDRST_CTRL, APCIE_COMMON_BLK_APCIE_NANDRST_CTRL_NANDRST_UMASK); + } + + // 8. Select APCIE lane configuration + SET_REG(LANE_CFG, APCIE_COMMON_BLK_APCIE_LANE_CFG_VALID_UMASK | platform_get_apcie_lane_cfg()); + + // 9. PCIe Phy is powered up: + // APCIE_PHY_POWERUP_STS.powerup_done is set by the HW when Phy power-up sequence is completed + while((GET_REG(PHY_POWERUP_STS) & APCIE_COMMON_BLK_APCIE_PHY_POWERUP_STS_POWERUP_DONE_UMASK) == 0) + spin(1); + + // 10. Software de-asserts phy_apb_reset_n + OR_REG(PHY_CONFIG_RST_CTRL, APCIE_COMMON_BLK_APCIE_PHY_CONFIG_RST_CTRL_PHY_CFG_RST_N_UMASK); + + // Apply SPDS-generated PHY tunable values + platform_apply_tunables(tunables_pcie_phy, ARRAY_SIZE(tunables_pcie_phy), "PCIe PHY"); + + // 11. Select external REFCLK if desired -- not desired. + + // The following is from Section 6.1.3 PCIe link bring-up sequence, step + // 1.a.(iii). When internal REFCLK is selected, SW must ensure that REFCLK + // provided by PCIe REFCLK PLL is stable before proceeding to link bring-up + while ((GET_REG(PHY_POWERUP_STS) & APCIE_COMMON_BLK_APCIE_PHY_POWERUP_STS_PMGR_REFCLK_GOOD_UMASK) == 0) + spin(1); +} + +static void apcie_disable_root_complex(void) +{ + if (s3e_reset_on_enable_disable) { + AND_REG(NANDRST_CTRL, ~APCIE_COMMON_BLK_APCIE_NANDRST_CTRL_NANDRST_UMASK); + } + + clock_set_device_reset(CLK_PCIE, true); + + spin(10); + + // WARNING: DO NOT power off PCIe CLK_PCIE_AUX, CLK_PCIE_REF, and CLK_PCIE + // here. The SEP and AES blocks will be unhappy if you do that. + // Just turn the clock off but leave the power on. + power_on(CLK_PCIE_AUX); + power_on(CLK_PCIE_REF); + power_on(CLK_PCIE); + + clock_set_device_reset(CLK_PCIE, false); +} + +// Implements the enable sequence from APCIe spec section 6.1.3 as it applies to +// APCIE_COMMON registers. The portion of the sequence that affects the APCIE_CONFIG +// registers is handled in common code +static void apcie_enable_link_hardware(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + dprintf(DEBUG_INFO, "apcie: Enabling link %d\n", link); + + // Make sure PERST# starts out as asserted + CLR_PORT_REG_BIT(PORT_RST_CTRL_0, link, APCIE_PERST_N); + + // 1(i). 100Mhz REFCLK to the link partners is enabled + SET_PORT_REG_BIT(PORT_REFCLK_CTRL_0, link, REFCLK_EN); + + // 1(iii). SW must ensure that REFCLK provided by PCIe REFCLK PLL is stable + // before proceeding to the next step + while (GET_PORT_REG_BIT(PHY_POWERUP_STS, link, PMGR_REFCLK_GOOD) == 0) + spin(10); + + // 2. Configure CLKREQ# GPIO for the target link -- done in the common + // code before calling this function + + // 3. Wait until the endpoint asserts CLKREQ# -- done in the common + // code before calling this function + + // 4. Update link configuration -- skip this step in SecureROM/iBoot + + // 5. Enable target PCIE link by setting APCIE_PORT_CTRL_{0/1/2/3}.port_en + SET_PORT_REG_BIT(PORT_CTRL_0, link, PORT_EN); + +#if SUPPORT_FPGA + SET_PORT_REG_BIT(PORT_CTRL_0, link, MUXED_AUXCLK_AUTO_DIS); +#endif + + // 6. De-assert PERST# for the target PCIE link. + SET_PORT_REG_BIT(PORT_RST_CTRL_0, link, APCIE_PERST_N); + while (GET_PORT_REG_BIT(PORT_STS_0, link, PORT_STS) == 0) + spin(10); + + // 7. Enable dynamic REFCLK clock gating -- skip this step in SecureROM/iBoot +} + +static void apcie_disable_link_hardware(uint32_t link) +{ + ASSERT(link < APCIE_NUM_LINKS); + + CLR_PORT_REG_BIT(PORT_RST_CTRL_0, link, APCIE_PERST_N); + CLR_PORT_REG_BIT(PORT_REFCLK_CTRL_0, link, REFCLK_EN); + CLR_PORT_REG_BIT(PORT_CTRL_0, link, PORT_EN); + + while (GET_PORT_REG_BIT(PORT_STS_0, link, PORT_STS) != 0) + spin(10); +} + +bool apcie_enable_link(uint32_t link) +{ + struct apcie_link_config *config = &apcie_link_configs[link]; + struct apcie_link_status *status = &apcie_link_statuses[link]; + utime_t start; + uint32_t counter_command; + uint32_t force_width; + uint32_t l1sub_cap; + uint16_t link_control2; + + ASSERT(link < APCIE_NUM_LINKS); + + if (status->enabled) + return true; + + // Clocks to PCIe don't default to on since it isn't used in POR configurations + if (link_enable_count == 0) { + apcie_enable_root_complex(); + } + + // Make sure PERST# starts out as asserted + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + gpio_configure(config->clkreq_gpio, GPIO_CFG_IN); + + // wait for CLKREQ# to be asserted + dprintf(DEBUG_INFO, "apcie: waiting for clkreq..."); + start = system_time(); + while (gpio_read(config->clkreq_gpio) != 0) { + if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) { + dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for CLKREQ# on link %u\n", link); + goto cleanup; + } + spin(1); + } + dprintf(DEBUG_INFO, " done\n"); + + gpio_configure(config->clkreq_gpio, GPIO_CFG_FUNC0); + + // Do required initialization in APCIE_COMMON registers + apcie_enable_link_hardware(link); + + // Apply root complex config tunables + platform_apply_tunables(tunables_pcie_config_rc[link].tunable_chip, + tunables_pcie_config_rc[link].num_tunable_chips, + "PCIe config"); + + // Apply APCIe config port tunables + platform_apply_tunables(tunables_pcie_config_ports[link].tunable_chip, + tunables_pcie_config_ports[link].num_tunable_chips, + "APCIe config"); + + // Enable fabric timeout. + OR_APCIE_CONFIG_REG(APCIE_CONFIG_BLK_AF_TMOT_CTRL_OFFSET, link, APCIE_CONFIG_BLK_AF_TMOT_CTRL_AF_TMOT_EN_UMASK); + + // PCIe spec requires a 100 microsecond delay from REFCLK starting + // to PERST being deasserted + spin(100); + + // 5) De-assert PERST# for the target PCIE link. + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_1); + + // Limit link speed to Gen1 + apcie_config_read_raw(&link_control2, PCIE_RC_CAP_LINK_CONTROL2_OFFSET(link), sizeof(link_control2)); + link_control2 &= ~PCIE_RC_CAP_LINK_CONTROL2_PCIE_TARGET_LINK_SPEED_UMASK; + link_control2 |= 1; + apcie_config_write_raw(&link_control2, PCIE_RC_CAP_LINK_CONTROL2_OFFSET(link), sizeof(link_control2)); + + // Limit link width if requested by the platform. If the platform returns 0, + // let the hardware autonegotiate the width using its default parameters + force_width = platform_get_pcie_link_width(link); + if (force_width != 0) { + ASSERT(force_width <= 2); + + uint32_t gen2_ctrl; + apcie_config_read_raw(&gen2_ctrl, PCIE_RC_PORT_LOGIC_GEN2_CTRL_OFFSET(link), sizeof(gen2_ctrl)); + gen2_ctrl &= ~PCIE_RC_PORT_LOGIC_GEN2_CTRL_NUM_OF_LANES_UMASK; + gen2_ctrl |= (force_width << PCIE_RC_PORT_LOGIC_GEN2_CTRL_NUM_OF_LANES_SHIFT); + apcie_config_write_raw(&gen2_ctrl, PCIE_RC_PORT_LOGIC_GEN2_CTRL_OFFSET(link), sizeof(gen2_ctrl)); + + uint32_t port_link_ctrl; + apcie_config_read_raw(&port_link_ctrl, PCIE_RC_PORT_LOGIC_PORT_LINK_CTRL_OFFSET(link), sizeof(port_link_ctrl)); + port_link_ctrl &= ~PCIE_RC_PORT_LOGIC_PORT_LINK_CTRL_LINK_CAPABLE_UMASK; + port_link_ctrl |= ((1 << (force_width - 1)) << PCIE_RC_PORT_LOGIC_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT); + apcie_config_write_raw(&port_link_ctrl, PCIE_RC_PORT_LOGIC_PORT_LINK_CTRL_OFFSET(link), sizeof(port_link_ctrl)); + } + + // Update L1 substate capabilites register to indicate the root complex + // has the capability of supporting T_POWER_ON=0us. + apcie_config_read_raw(&l1sub_cap, PCIE_RC_PORT_LOGIC_L1SUB_CAPABILITY_REG_OFFSET(link), sizeof(l1sub_cap)); + l1sub_cap &= ~PCIE_RC_PORT_LOGIC_L1SUB_CAPABILITY_REG_PWR_ON_VALUE_SUPPORT_UMASK; + l1sub_cap &= ~PCIE_RC_PORT_LOGIC_L1SUB_CAPABILITY_REG_COMM_MODE_SUPPORT_UMASK; + apcie_config_write_raw(&l1sub_cap, PCIE_RC_PORT_LOGIC_L1SUB_CAPABILITY_REG_OFFSET(link), sizeof(l1sub_cap)); + + // Clear the link counters + counter_command = get_reg(APCIE_PORT_COUNTER_BASE_ADDR(link), APCIE_LCOUNT_BLK_LCOUNT_COMMAND_0_OFFSET); + counter_command |= APCIE_COUNTER_CLEAR | APCIE_COUNTER_ENABLE; + set_reg(APCIE_PORT_COUNTER_BASE_ADDR(link), APCIE_LCOUNT_BLK_LCOUNT_COMMAND_0_OFFSET, counter_command); + + // Disable PHY powergating: H9: PCIe Sequence with Disable PHY power gating and disable txboost + uint32_t lane_cfg = platform_get_apcie_lane_cfg(); + uint32_t phy_sig_mask; + + uint32_t link_widths[][4] = { + [APCIE_LANE_CFG_X1_X1_X1_X1] = { 1, 1, 1, 1 }, + [APCIE_LANE_CFG_X2_X1_X1] = { 2, 0, 1, 1 }, + [APCIE_LANE_CFG_X1_X1_X2] = { 1, 1, 2, 0 }, + [APCIE_LANE_CFG_X2_X2] = { 2, 0, 2, 0 }, + }; + + ASSERT(lane_cfg < ARRAY_SIZE(link_widths)); + ASSERT(link < ARRAY_SIZE(link_widths[0])); + + uint32_t link_width = link_widths[lane_cfg][link]; + ASSERT(link_width != 0); + + phy_sig_mask = ((1 << link_width) - 1) << link; + + // Wait for the phy lanes to power up. + while ((PHY_GET_REG(PCIE_PHY_SIG) & phy_sig_mask) != phy_sig_mask) { + spin(10); + } + +#if APPLICATION_SECUREROM + + // 6) Always enable DFW adapatation for SecureROM. + + // For each lane... + for (uint32_t lane = 0; phy_sig_mask != 0; lane++, phy_sig_mask >>= 1) { + // ... if we're enabling this lane ... + if (phy_sig_mask & 1) { + // ... set DFE adapation to always enabled. + OR_PMA_RX_REG(RX_REE_GEN_CTRL_EN, lane, PMA_RX_LANE_REGISTERS_BLK_RX_REE_GEN_CTRL_EN_15_UMASK); + OR_PMA_RX_REG(RX_REE_FREE0_CFGD, lane, PMA_RX_LANE_REGISTERS_BLK_RX_REE_FREE0_CFGD_6_UMASK); + OR_PMA_TX_REG(XCVR_DIAG_DCYA, lane, PMA_TX_LANE_REGISTERS_BLK_XCVR_DIAG_DCYA_0_UMASK); + } + } + +#else // !APPLICATION_SECUREROM + + // 5) Disable PCIE PHY common block power gating. + + // Disable PCIE PHY power gating. + OR_PMA_CMN_REG(CMN_CDIAG_FUNC_PWR_CTRL, PMA_CMN_REGISTERS_BLK_CMN_CDIAG_FUNC_PWR_CTRL_14_UMASK); + OR_PMA_CMN_REG(CMN_CDIAG_XCTRL_PWR_CTRL, PMA_CMN_REGISTERS_BLK_CMN_CDIAG_XCTRL_PWR_CTRL_14_UMASK); + + // Update common PHY PLL timers. + uint32_t phy_reg; + phy_reg = GET_PMA_CMN_REG(CMN_SSM_PLLPRE_TMR); + phy_reg &= ~PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLPRE_TMR_11_0_UMASK; + phy_reg |= PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLPRE_TMR_11_0_INSRT(0x64); + SET_PMA_CMN_REG(CMN_SSM_PLLPRE_TMR, phy_reg); + phy_reg = GET_PMA_CMN_REG(CMN_SSM_PLLLOCK_TMR); + phy_reg &= ~PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLLOCK_TMR_11_0_UMASK; + phy_reg |= PMA_CMN_REGISTERS_BLK_CMN_SSM_PLLLOCK_TMR_11_0_INSRT(0x19); + SET_PMA_CMN_REG(CMN_SSM_PLLLOCK_TMR, phy_reg); + + // For each lane... + for (uint32_t lane = 0; phy_sig_mask != 0; lane++, phy_sig_mask >>= 1) { + // ... if we're enabling this lane ... + if (phy_sig_mask & 1) { + // ... disable power gating ... + OR_PMA_TX_REG(XCVR_DIAG_FUNC_PWR_CTRL, lane, PMA_TX_LANE_REGISTERS_BLK_XCVR_DIAG_FUNC_PWR_CTRL_14_UMASK); + + // ... and disable transmitter boost ... + SET_PMA_TX_REG(TX_DIAG_TX_BOOST, lane, 0); + + // ... and update the lane calibration timer ... + phy_reg = GET_PMA_TX_REG(XCVR_PSM_LANECAL_TMR, lane); + phy_reg &= ~PMA_TX_LANE_REGISTERS_BLK_XCVR_PSM_LANECAL_TMR_11_0_UMASK; + phy_reg |= PMA_TX_LANE_REGISTERS_BLK_XCVR_PSM_LANECAL_TMR_11_0_INSRT(0x600); + SET_PMA_TX_REG(XCVR_PSM_LANECAL_TMR, lane, phy_reg); + + // ... and improve SIG DET performance ... + SET_PMA_RX_REG(RX_DIAG_SIGDET_TUNE, lane, 0x3105); + + // ... and improve PI stability ... + phy_reg = GET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM3, lane); + phy_reg &= ~PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM3_7_0_UMASK; + phy_reg |= PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM3_7_0_INSRT(0x9f); + SET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM3, lane, phy_reg); + + phy_reg = GET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM5, lane); + phy_reg &= ~PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM5_7_0_UMASK; + phy_reg |= PMA_RX_LANE_REGISTERS_BLK_RX_DIAG_ILL_IQE_TRIM5_7_0_INSRT(0x01); + SET_PMA_RX_REG(RX_DIAG_ILL_IQE_TRIM5, lane, phy_reg); + + // ... and improve CDR performace. + phy_reg = GET_PMA_RX_REG(RX_CDRLF_CNFG, lane); + phy_reg &= ~PMA_RX_LANE_REGISTERS_BLK_RX_CDRLF_CNFG_4_0_UMASK; + phy_reg |= PMA_RX_LANE_REGISTERS_BLK_RX_CDRLF_CNFG_4_0_INSRT(0xa); + SET_PMA_RX_REG(RX_CDRLF_CNFG, lane, phy_reg); + + // NOTE: Because iBoot always forces links to Gen1 speed, + // the steps for non-Gen1 speeds have been omitted. + } + } +#endif // APPLICATION_SECUREROM + + // 7) Software sets LINKCFG.ltssm_en to start link training + OR_APCIE_CONFIG_REG(APCIE_CONFIG_BLK_LINKCFG_OFFSET, link, APCIE_CONFIG_BLK_LINKCFG_LTSSM_EN_UMASK); + + start = system_time(); + while ((GET_APCIE_CONFIG_REG(APCIE_CONFIG_BLK_LINKSTS_OFFSET, link) & APCIE_CONFIG_BLK_LINKSTS_LINK_STATUS_UMASK) == 0) { + if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) { + uint32_t linksts = GET_APCIE_CONFIG_REG(APCIE_CONFIG_BLK_LINKSTS_OFFSET, link); + dprintf(DEBUG_CRITICAL, "apcie: Timeout waiting for LinkUp on link %u\n", link); + dprintf(DEBUG_CRITICAL, "apcie: LINKSTS 0x%08x (LTSSM state %d)\n", + linksts, APCIE_CONFIG_BLK_LINKSTS_LTSSM_STATE_XTRCT(linksts)); + goto cleanup; + } + spin(10); + } + + status->enabled = true; + link_enable_count++; + + dart_init(config->dart_id); + + apcie_setup_root_port_bridge(link, config); + + return true; + +cleanup: + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + spin(10); + gpio_configure(config->perst_gpio, GPIO_CFG_DFLT); + gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT); + + apcie_disable_link_hardware(link); + + if (link_enable_count == 0) { + apcie_disable_root_complex(); + } + + return false; +} + +void apcie_disable_link(uint32_t link) +{ + struct apcie_link_config *config = &apcie_link_configs[link]; + struct apcie_link_status *status = &apcie_link_statuses[link]; + utime_t start; + + ASSERT(link < APCIE_NUM_LINKS); + + if (!status->enabled) + return; + + dprintf(DEBUG_INFO, "apcie: Disabling link %d\n", link); + + set_reg(APCIE_PORT_COUNTER_BASE_ADDR(link), APCIE_LCOUNT_BLK_LCOUNT_COMMAND_0_OFFSET, 0); + + // Request PMETO and clear the previous status indications + SET_APCIE_CONFIG_REG(APCIE_CONFIG_BLK_PMETO_OFFSET, link, + APCIE_CONFIG_BLK_PMETO_FLD_UMASK + | APCIE_CONFIG_BLK_PMETO_PME_TO_ACK_MSG_UMASK + | APCIE_CONFIG_BLK_PMETO_TIMEOUT_UMASK); + start = system_time(); + while (GET_APCIE_CONFIG_REG(APCIE_CONFIG_BLK_PMETO_OFFSET, link) & APCIE_CONFIG_BLK_PMETO_FLD_UMASK) { + if (time_has_elapsed(start, 10000)) { + dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for PME_To_Ack, continuing\n"); + break; + } + spin(10); + } + + start = system_time(); + while ((GET_APCIE_CONFIG_REG(APCIE_CONFIG_BLK_LINKSTS_OFFSET, link) & APCIE_CONFIG_BLK_LINKSTS_L2_STATE_UMASK) == 0) { + if (time_has_elapsed(start, 10000)) { + dprintf(DEBUG_CRITICAL, "apcie: link did not go into L2, continuing\n"); + break; + } + spin(10); + } + + gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0); + // delay to allow PERST# signal to settle before letting the pulldown hold it low + // and to allow the endpoint to handle PERST# before removing REFCLK + spin(25); + gpio_configure(config->perst_gpio, GPIO_CFG_DFLT); + gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT); + +#if DEBUG_BUILD + dart_assert_unmapped(config->dart_id); +#endif + + apcie_disable_link_hardware(link); + + status->enabled = false; + link_enable_count--; + + if (link_enable_count == 0) { + apcie_disable_root_complex(); + } + + apcie_free_port_bridge(link); +} + +uint32_t apcie_get_link_enable_count(void) +{ + return link_enable_count; +} + +#if WITH_DEVICETREE +void apcie_update_devicetree(DTNode *apcie_node) +{ + DTNode *node; + uint32_t propSize; + uint8_t *dt_prop = (uint8_t *)malloc(MAX_DT_PROPERTY_SIZE); + uint8_t *next_dt_prop = dt_prop; + char bridge[16]; + + // Apply common tunables. + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_common, + ARRAY_SIZE(tunables_pcie_common), + next_dt_prop, + 0, // Already at the correct offset + "apcie common"); + + next_dt_prop = platform_apply_dt_tunables(tunables_nvme_common , + ARRAY_SIZE(tunables_nvme_common ), + next_dt_prop, + 0, // Already at the correct offset + "apcie common"); + + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + dt_set_prop(apcie_node, "apcie-common-tunables", dt_prop, propSize); + + // Apply port-specific config tunables. + for (uint32_t i = 0; i < APCIE_NUM_LINKS; i++) { + snprintf(bridge, sizeof(bridge), "pci-bridge%d", i); + if (dt_find_node(apcie_node, bridge, &node)) { + // APCIe port config tunables. + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_config_ports[i].tunable_chip, + tunables_pcie_config_ports[i].num_tunable_chips, + next_dt_prop, + tunables_pcie_config_ports[i].dt_base, + bridge); + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + dt_set_prop(node, "apcie-config-tunables", dt_prop, propSize); + + // PCIe root complex config tunables. + snprintf(bridge, sizeof(bridge), "pcie-rc%d", i); + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_config_rc[i].tunable_chip, + tunables_pcie_config_rc[i].num_tunable_chips, + next_dt_prop, + tunables_pcie_config_rc[i].dt_base, + bridge); + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + dt_set_prop(node, "pcie-rc-tunables", dt_prop, propSize); + } else { + dprintf(DEBUG_INFO,"PCIe bridge node %s not found -- skipping tunable update\n", bridge); + } + } + + // Apply SPDS PHY tunables. + bzero(dt_prop, MAX_DT_PROPERTY_SIZE); + next_dt_prop = dt_prop; + next_dt_prop = platform_apply_dt_tunables(tunables_pcie_phy, + ARRAY_SIZE(tunables_pcie_phy), + next_dt_prop, + APCIE_PHY_BASE_ADDR, + "PCIe PHY"); + + propSize = next_dt_prop - dt_prop; + RELEASE_ASSERT(propSize < MAX_DT_PROPERTY_SIZE); + + dt_set_prop(apcie_node, "phy-params", dt_prop, propSize); + free(dt_prop); + dt_prop = next_dt_prop = NULL; +} +#endif + +struct apcie_link_config platform_apcie_link_configs[APCIE_NUM_LINKS] = { + [0] = { + .perst_gpio = GPIO_PCIE0_PERST, + .clkreq_gpio = GPIO_PCIE0_CLKREQ, + .dart_id = PCIE_PORT0_DART_ID, + }, + [1] = { + .perst_gpio = GPIO_PCIE1_PERST, + .clkreq_gpio = GPIO_PCIE1_CLKREQ, + .dart_id = PCIE_PORT1_DART_ID, + }, + [2] = { + .perst_gpio = GPIO_PCIE2_PERST, + .clkreq_gpio = GPIO_PCIE2_CLKREQ, + .dart_id = PCIE_PORT2_DART_ID, + }, + [3] = { + .perst_gpio = GPIO_PCIE3_PERST, + .clkreq_gpio = GPIO_PCIE3_CLKREQ, + .dart_id = PCIE_PORT3_DART_ID, + }, +}; + +void platform_register_pci_busses(void) +{ + apcie_init(); +} + +uint64_t platform_map_host_to_pci_addr(uintptr_t addr) +{ + // Right now we're only supporting 32-bit PCI addresses + // for aPCIe, so just lop off the top 32 bits + return addr & 0xFFFFFFFF; +} + +uintptr_t platform_map_pci_to_host_addr(uint64_t addr) +{ + // Right now we're only supporting 32-bit PCI addresses + // for aPCIe + ASSERT((addr & ~0xFFFFFFFFULL) == 0); + return PCI_32BIT_BASE + (addr & (PCI_32BIT_LEN - 1)); +} diff --git a/platform/t8010/apcie/rules.mk b/platform/t8010/apcie/rules.mk new file mode 100644 index 0000000..1ee6b68 --- /dev/null +++ b/platform/t8010/apcie/rules.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Computer, Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Computer, Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ALL_OBJS += \ + $(LOCAL_DIR)/apcie.o \ diff --git a/platform/t8010/asm.S b/platform/t8010/asm.S new file mode 100644 index 0000000..7a17647 --- /dev/null +++ b/platform/t8010/asm.S @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include + + .text + .balign 4 + .globl _platform_start +_platform_start: + //////////////////////////////////////////////// + // Must preserve X0 and X1 + //////////////////////////////////////////////// + +#if !APPLICATION_SECUREROM + // Enable the L2 cache load/store prefetcher. + mrs x2, s3_0_c15_c5_0 // HID5 + and x2, x2, #~(3<<44) // Enable L2C load (bit 44)/store (bit 45) prefetch + msr s3_0_c15_c5_0, x2 // HID5 + isb +#endif + +#if WITH_L2_AS_RAM +#if APPLICATION_SECUREROM + // Enable L2 as RAM + mrs x2, s3_3_c15_c7_0 // L2_CRAMCONFIG + orr x2, x2, #2 // L2_CRAMCONFIG.EnableSize (2 MiB SRAM) + msr s3_3_c15_c7_0, x2 // L2_CRAMCONFIG +1: + // Poll for RAM ready + mrs x2, s3_3_c15_c7_0 // L2_CRAMCONFIG + and x2, x2, #(1<<63) // L2_CRAMCONFIG.Ready + cbz x2, 1b // Not ready +#endif +#if PRODUCT_IBOOT || PRODUCT_IBEC + // Disable L2 as RAM + mrs x2, s3_3_c15_c7_0 // L2_CRAMCONFIG + and x2, x2, #~0x3F // L2_CRAMCONFIG.EnableSize (disable SRAM) + msr s3_3_c15_c7_0, x2 // L2_CRAMCONFIG +1: + // Poll for RAM not ready + mrs x2, s3_3_c15_c7_0 // L2_CRAMCONFIG + and x2, x2, #(1<<63) // L2_CRAMCONFIG.Ready + cbnz x2, 1b // Still ready +#endif +#endif + ret + diff --git a/platform/t8010/chipid/chipid.c b/platform/t8010/chipid/chipid.c new file mode 100644 index 0000000..7202f62 --- /dev/null +++ b/platform/t8010/chipid/chipid.c @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include + +#define MINIMUM_FUSE_REVISION 0x0 + +#define CHIPID_VOLTAGE_FIXED 0 +#define CHIPID_MODE_NONE 0 + +struct chipid_voltage_config { + uint32_t safe_voltage; + uint32_t mode; +}; + +static struct chipid_voltage_config chipid_cpu_voltages[] = { + [CHIPID_CPU_VOLTAGE_BYPASS] = { 610, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_SECUREROM] = { 610, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_396] = { 610, CHIPID_MODE_NONE}, +}; + +static struct chipid_voltage_config chipid_cpu_sram_voltages[] = { + [CHIPID_CPU_VOLTAGE_BYPASS] = { 800, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_SECUREROM] = { 800, CHIPID_MODE_NONE}, + [CHIPID_CPU_VOLTAGE_396] = { 800, CHIPID_MODE_NONE}, +}; + +static struct chipid_voltage_config chipid_soc_voltages[] = { + [CHIPID_SOC_VOLTAGE_BYPASS] = {725, CHIPID_MODE_NONE}, + [CHIPID_SOC_VOLTAGE_SECUREROM] = {725, CHIPID_MODE_NONE}, + [CHIPID_SOC_VOLTAGE_VMIN] = {725, CHIPID_MODE_NONE}, + [CHIPID_SOC_VOLTAGE_VNOM] = {825, CHIPID_MODE_NONE}, +}; + +static struct chipid_voltage_config chipid_gpu_voltages[] = { + [CHIPID_GPU_VOLTAGE_OFF] = { 0, CHIPID_MODE_NONE}, +}; + +static struct chipid_voltage_config chipid_gpu_sram_voltages[] = { + [CHIPID_GPU_VOLTAGE_OFF] = { 0, CHIPID_MODE_NONE}, +}; + +static struct chipid_voltage_config chipid_sram_voltages[] = { + [CHIPID_VOLTAGE_FIXED] = {850, CHIPID_MODE_NONE}, +}; + +struct chipid_voltadj_entry { + uint64_t voltage_index:8; + uint64_t chipid:32; + uint64_t chip_rev_min:8; + uint64_t fuse_rev_min:8; + struct chipid_vol_adj voltages; +}; + +#define CHIPID_ALL 0x0 + +// .voltages = {volAdj0, volAdj1, volAdj2, volAdj3, dvfmMaxAdj, dvmrAdj0, dvmrAdj1, dvmrAdj2} + +static const struct chipid_voltadj_entry chipid_voltadj_entry[] = { + {CHIPID_CPU_VOLTAGE_BYPASS, CHIPID_ALL, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 0, 0, 0, 0}}, + {CHIPID_SOC_VOLTAGE_SECUREROM, CHIPID_ALL, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 0, 0, 0, 0}}, + {CHIPID_CPU_VOLTAGE_396, 0x8010, CHIP_REVISION_A0, 0, .voltages = {0, 0, 0, 0, 0, 0, 0, 0}}, +}; + +const struct chipid_vol_adj *chipid_get_vol_adj(enum chipid_voltage_index voltage_index) +{ + uint32_t chipid = chipid_get_chip_id(); + uint32_t chip_rev = chipid_get_chip_revision(); + uint32_t fuse_rev = chipid_get_fuse_revision(); + + for (size_t i = 0; i < sizeof(chipid_voltadj_entry)/sizeof(chipid_voltadj_entry[0]); i++) { + if (voltage_index != chipid_voltadj_entry[i].voltage_index) { + continue; + } + if ((chipid != chipid_voltadj_entry[i].chipid) && (chipid_voltadj_entry[i].chipid != CHIPID_ALL)) { + continue; + } + if ((chip_rev < chipid_voltadj_entry[i].chip_rev_min)) { + continue; + } + if ((fuse_rev < chipid_voltadj_entry[i].fuse_rev_min)) { + continue; + } + return &chipid_voltadj_entry[i].voltages; + } + return NULL; +} + +static uint32_t chipid_get_base_voltage(void) +{ + uint32_t voltage = 0; + + // TODO + + return voltage; +} + +static uint32_t chipid_get_cpu_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse = 0; + + // TODO + + return binfuse; +} + +static uint32_t chipid_get_cpu_sram_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse = 0; + + // TODO + + return binfuse; +} + +static uint32_t chipid_get_soc_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse = 0; + + // TODO + + return binfuse; +} + +static uint32_t chipid_get_gpu_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse = 0; + + // TODO + + return binfuse; +} + +static uint32_t chipid_get_gpu_sram_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse = 0; + + // TODO + + return binfuse; +} + +static uint32_t chipid_get_sram_binfuse_for_mode(uint32_t mode) +{ + uint32_t binfuse = 0; + + // TODO + + return binfuse; +} + +static uint32_t chipid_get_cpu_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_cpu_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_cpu_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_cpu_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_cpu_sram_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_cpu_sram_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_cpu_sram_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_cpu_sram_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_soc_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_soc_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_soc_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_soc_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_gpu_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_gpu_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_gpu_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_gpu_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_gpu_sram_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_gpu_sram_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_gpu_sram_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_gpu_sram_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +static uint32_t chipid_get_sram_bin_voltage(uint32_t volt_index) +{ + uint32_t mode, binfuse; + + mode = chipid_sram_voltages[volt_index].mode; + + // Return safe voltage if no binned voltage + if (mode == CHIPID_MODE_NONE) + return chipid_sram_voltages[volt_index].safe_voltage; + + binfuse = chipid_get_sram_binfuse_for_mode(mode); + + return (chipid_get_base_voltage() + binfuse * 5); +} + +bool chipid_get_current_production_mode(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_XTRCT(rCFG_FUSE0) != 0; +} + +bool chipid_get_raw_production_mode(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_XTRCT(rCFG_FUSE0_RAW) != 0; +} + +void chipid_clear_production_mode(void) +{ + rCFG_FUSE0 &= ~MINIPMGR_FUSE_CFG_FUSE0_PRODUCTION_MODE_UMASK; +} + +bool chipid_get_secure_mode(void) +{ + // demotion only applies to the SEP, so iBoot always reads + // the raw value for secure mode () + return MINIPMGR_FUSE_CFG_FUSE0_SECURE_MODE_XTRCT(rCFG_FUSE0_RAW); +} + +uint32_t chipid_get_security_domain(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_SECURITY_DOMAIN_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_board_id(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_BID_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_minimum_epoch(void) +{ + return MINIPMGR_FUSE_CFG_FUSE0_MINIMUM_EPOCH_XTRCT(rCFG_FUSE0); +} + +uint32_t chipid_get_chip_id(void) +{ +#if SUB_PLATFORM_T8010 + return 0x8010; +#else +#error "Unknown platform" +#endif +} + +uint32_t chipid_get_chip_revision(void) +{ + uint32_t fuse_val = rCFG_FUSE4; + + return (MINIPMGR_FUSE_CFG_FUSE4_CHIP_REV_MAJOR_XTRCT(fuse_val) << 4) | + (MINIPMGR_FUSE_CFG_FUSE4_CHIP_REV_MINOR_XTRCT(fuse_val)); +} + +uint32_t chipid_get_osc_frequency(void) +{ + return OSC_FREQ; +} + +uint64_t chipid_get_ecid_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint64_t chipid_get_die_id(void) +{ + return ((uint64_t)rECIDHI << 32) | rECIDLO; +} + +uint32_t chipid_get_cpu_voltage(uint32_t index) +{ + uint32_t cpu_voltage; + + if (index >= sizeof(chipid_cpu_voltages)/sizeof(chipid_cpu_voltages[0])) + panic("Invalid CPU voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + cpu_voltage = chipid_cpu_voltages[index].safe_voltage; + else + cpu_voltage = chipid_get_cpu_bin_voltage(index); + + return cpu_voltage; +} + +uint32_t chipid_get_cpu_sram_voltage(uint32_t index) +{ + uint32_t cpu_sram_voltage; + + if (index >= sizeof(chipid_cpu_sram_voltages)/sizeof(chipid_cpu_sram_voltages[0])) + panic("Invalid CPU SRAM voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + cpu_sram_voltage = chipid_cpu_sram_voltages[index].safe_voltage; + else + cpu_sram_voltage = chipid_get_cpu_sram_bin_voltage(index); + + return cpu_sram_voltage; +} + +uint32_t chipid_get_soc_voltage(uint32_t index) +{ + uint32_t soc_voltage; + + if (index >= sizeof(chipid_soc_voltages)/sizeof(chipid_soc_voltages[0])) + panic("Invalid SOC voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + soc_voltage = chipid_soc_voltages[index].safe_voltage; + else + soc_voltage = chipid_get_soc_bin_voltage(index); + + return soc_voltage; +} + +uint32_t chipid_get_gpu_voltage(uint32_t index) +{ + uint32_t gpu_voltage; + + if (index >= sizeof(chipid_gpu_voltages)/sizeof(chipid_gpu_voltages[0])) + panic("Invalid GPU voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + gpu_voltage = chipid_gpu_voltages[index].safe_voltage; + else + gpu_voltage = chipid_get_gpu_bin_voltage(index); + + return gpu_voltage; +} + +uint32_t chipid_get_gpu_sram_voltage(uint32_t index) +{ + uint32_t gpu_sram_voltage; + + if (index >= sizeof(chipid_gpu_sram_voltages)/sizeof(chipid_gpu_sram_voltages[0])) + panic("Invalid GPU SRAM voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + gpu_sram_voltage = chipid_gpu_sram_voltages[index].safe_voltage; + else + gpu_sram_voltage = chipid_get_gpu_sram_bin_voltage(index); + + return gpu_sram_voltage; +} + +uint32_t chipid_get_sram_voltage(uint32_t index) +{ + uint32_t sram_voltage; + + index = CHIPID_VOLTAGE_FIXED; + + if (index >= sizeof(chipid_sram_voltages)/sizeof(chipid_sram_voltages[0])) + panic("Invalid SRAM voltage index %d\n", index); + + if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION) + sram_voltage = chipid_sram_voltages[index].safe_voltage; + else + sram_voltage = chipid_get_sram_bin_voltage(index); + + return sram_voltage; +} + +bool chipid_get_fuse_lock(void) +{ + return MINIPMGR_FUSE_CFG_FUSE1_AP_LOCK_XTRCT(rCFG_FUSE1) != 0; +} + +void chipid_set_fuse_lock(bool locked) +{ + if (locked) { + rCFG_FUSE1 |= MINIPMGR_FUSE_CFG_FUSE1_AP_LOCK_INSRT(1); + asm("dsb sy"); + if (!chipid_get_fuse_lock()) { + panic("Failed to lock fuses\n"); + } + } +} + +bool chipid_get_fuse_seal(void) +{ + return MINIPMGR_FUSE_CFG_FUSE1_SEAL_FUSES_XTRCT(rCFG_FUSE1) != 0; +} + +uint32_t chipid_get_lpo_trim(void) +{ + // Workaround for Maui LPO issue + // return MINIPMGR_FUSE_CFG_FUSE2_LPO_TRIM_XTRCT(rCFG_FUSE2); + return 0x20; +} + +uint32_t chipid_get_pcie_refpll_fcal_vco_digctrl(void) +{ + return MINIPMGR_FUSE_CFG_FUSE4_PCIE_REFPLL_FCAL_VCO_DIGCTRL_XTRCT(rCFG_FUSE4); +} + +uint32_t chipid_get_soc_temp_sensor_trim(uint32_t sensor_index) +{ + uint32_t sensor_trim; + + switch (sensor_index) { + case 0: + sensor_trim = rCFG_FUSE2; + sensor_trim &= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_TRIMG_UMASK | MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_TRIMO_UMASK; + sensor_trim >>= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN0_TRIMG_SHIFT; + break; + case 1: + sensor_trim = rCFG_FUSE2; + sensor_trim &= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN1_TRIMG_UMASK | MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN1_TRIMO_UMASK; + sensor_trim >>= MINIPMGR_FUSE_CFG_FUSE2_THERMAL_SEN1_TRIMG_SHIFT; + break; + case 2: + sensor_trim = rCFG_FUSE3; + sensor_trim &= MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN2_TRIMG_UMASK | MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN2_TRIMO_UMASK; + sensor_trim >>= MINIPMGR_FUSE_CFG_FUSE3_THERMAL_SEN2_TRIMG_SHIFT; + break; + default: + panic("invalid thermal sensor %u", sensor_index); + } + return sensor_trim; +} + +uint32_t chipid_get_fuse_revision(void) +{ + return MINIPMGR_FUSE_CFG_FUSE4_REV_XTRCT(rCFG_FUSE4); +} + +uint32_t chipid_get_total_rails_leakage() +{ + // FIXME + return 0; +} + +#if SUPPORT_FPGA + +#define FPGA_HAS_INT3 (FPGA_HAS_MEDIA | FPGA_HAS_MSR | FPGA_HAS_JPEG | FPGA_HAS_VXD | FPGA_HAS_DISP) + +uint32_t chipid_get_fpga_block_instantiation(void) +{ + // Hardware blocks instantiated. + uint32_t blocks = (rECID_FUSE3 >> 18) & 0xF; + uint32_t mask = FPGA_HAS_ALWAYS; + + switch (blocks) { + // INT2 := ACC + AF + AMC + SouthBridge + PCIE + case 0x1: + break; + + // INT2GFX := INT2 + GFX + case 0x2: + mask |= FPGA_HAS_GFX; + break; + + // INT3 := INT2 + DISP + MEDIA + JPEG + MSR + VXD + case 0x8: + mask |= FPGA_HAS_INT3; + break; + + // INT3GFX := INT3 + GFX + case 0xA: + mask |= (FPGA_HAS_INT3 | FPGA_HAS_GFX); + break; + + default: + panic("Unknown hardware block instantiation: 0x%x", blocks); + } + + return mask; +} +#endif diff --git a/platform/t8010/chipid/dvfmperf.c b/platform/t8010/chipid/dvfmperf.c new file mode 100644 index 0000000..7960dc2 --- /dev/null +++ b/platform/t8010/chipid/dvfmperf.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * This file is only a database of the performance sate for CPU and GPU, regarding the kind of chip + * or board, it has no access to the chip. + */ +#include +#include + +// These array are the first iteration, the next part will include reference to board id, board rev, fuse rev. + +static const enum chipid_voltage_index t8010_cpu[] = { + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_396, +}; + +static const enum chipid_voltage_index t8010_gpu[] = { + CHIPID_GPU_VOLTAGE_OFF, +}; + +static const struct { + uint32_t chip_id; + uint32_t chip_rev; + enum chipid_voltage_type voltage_type; + const enum chipid_voltage_index *voltage_indexes; + uint32_t size; +} dvfmperfs[] = { // Entry with highest chip revision must come first + {0x8010, CHIP_REVISION_A0, CHIPID_CPU_VOLTAGE, t8010_cpu, sizeof(t8010_cpu)/sizeof(t8010_cpu[0])}, + {0x8010, CHIP_REVISION_A0, CHIPID_GPU_VOLTAGE, t8010_gpu, sizeof(t8010_gpu)/sizeof(t8010_gpu[0])}, +}; + +enum chipid_voltage_index dvfmperf_get_voltage_index(uint32_t index, enum chipid_voltage_type voltage_type) +{ + uint32_t chip_id = chipid_get_chip_id(); + uint32_t chip_rev = chipid_get_chip_revision(); + uint32_t i; + + for (i = 0; i < sizeof(dvfmperfs)/sizeof(dvfmperfs[0]); i++) { + if (chip_id != dvfmperfs[i].chip_id) { + continue; + } + if (chip_rev < dvfmperfs[i].chip_rev) { + continue; + } + if (voltage_type != dvfmperfs[i].voltage_type) { + continue; + } + if (index >= dvfmperfs[i].size) { + switch (voltage_type) { + case CHIPID_CPU_VOLTAGE: + return dvfmperfs[i].voltage_indexes[2]; // Default to lowest frequency + case CHIPID_GPU_VOLTAGE: + return dvfmperfs[i].voltage_indexes[0]; + default: + panic("Unknwon voltage type\n"); + } + } + return dvfmperfs[i].voltage_indexes[index]; + } + panic("Unknown voltage for current chip\n"); + return CHIPID_GPU_VOLTAGE_OFF; // Never reach this code +} diff --git a/platform/t8010/chipid/operating_point.c b/platform/t8010/chipid/operating_point.c new file mode 100644 index 0000000..f73eb96 --- /dev/null +++ b/platform/t8010/chipid/operating_point.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * This file is only a database of the frequencies used by CPU and GPU, it has no access + * To the chip. + */ +#include +#include + +#define CHIP_ID_ALL 0 +#define DELIMITER CHIPID_ALL_VOLTAGE_LAST + +static const struct operating_point_params operating_point_params[] = { + // T8010 + {.voltage_index = DELIMITER, .chip_id = 0x8010, .voltage_type = CHIPID_GPU_VOLTAGE}, + // voltage_index P M S + {.gpu = {CHIPID_GPU_VOLTAGE_OFF, 0, 0, 0}}, + + // T8010 + {.voltage_index = DELIMITER, .chip_id = 0x8010, .voltage_type = CHIPID_CPU_VOLTAGE}, + // bypass + // | clkSrc + // | | fcwInt + // | | | fcwFrac + // | | | | pstDivS + // | | | | | migDivS + // | | | | | | coreTyp + // | | | | | | | biuDiv4HiVol + // | | | | | | | | biuDiv4LoVol + // | | | | | | | | | dvmrMaxWgt + // | | | | | | | | | | iexrfCfgWrData + // | | | | | | | | | | | iexrfCfgWrIdxa + // | | | | | | | | | | | | iexrfCfgWrIdxb + // | | | | | | | | | | | | | exrfCfgWrIdxmuxsel + // | | | | | | | | | | | | | | + {.cpu = {CHIPID_CPU_VOLTAGE_BYPASS, 1, 0, 125, 0, 7, 7, kACC_CORETYP_FUSED, 2, 2, 0xf, 0, 0, 0, 0}}, // 24 MHz + {.cpu = {CHIPID_CPU_VOLTAGE_SECUREROM,1, 1, 125, 0, 4, 7, kACC_CORETYP_FUSED, 2, 2, 0xf, 0, 0, 0, 0}}, // 300 MHz + {.cpu = {CHIPID_CPU_VOLTAGE_396, 0, 0, 0, 0, 0, 0, kACC_CORETYP_ECORE, 2, 2, 0xf, 0, 0, 0, 0}}, // 396 MHz !!!FIXME!!! Get correct settings +}; + +const struct operating_point_params *operating_point_get_params(enum chipid_voltage_index voltage_index, enum chipid_voltage_type voltage_type) +{ + uint64_t chip_id = chipid_get_chip_id(); + uint64_t chip_id_in_array = 0; + size_t size = sizeof(operating_point_params)/sizeof(operating_point_params[0]); + enum chipid_voltage_type voltage_type_in_array = CHIPID_CPU_VOLTAGE; + + size_t found = size; + for (size_t i = 0; i < size; i++) { + if (operating_point_params[i].voltage_index == DELIMITER) { + chip_id_in_array = operating_point_params[i].chip_id; + voltage_type_in_array = operating_point_params[i].voltage_type; + continue; + } + if ((voltage_type_in_array != voltage_type)) { + continue; + } + if ((operating_point_params[i].voltage_index == voltage_index) && ((chip_id_in_array == CHIP_ID_ALL) || (chip_id_in_array == chip_id))) { + found = i; + } + } + if (found == size) { + panic("%s Index %d not found for chipId 0x%llx\n", + __func__, voltage_index, chip_id); + } + return &operating_point_params[found]; +} diff --git a/platform/t8010/chipid/rules.mk b/platform/t8010/chipid/rules.mk new file mode 100644 index 0000000..e893c2d --- /dev/null +++ b/platform/t8010/chipid/rules.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_PLATFORM_CHIPID=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/chipid.o \ + $(LOCAL_DIR)/operating_point.o \ + $(LOCAL_DIR)/dvfmperf.o diff --git a/platform/t8010/dcs/dcs.c b/platform/t8010/dcs/dcs.c new file mode 100644 index 0000000..062d00e --- /dev/null +++ b/platform/t8010/dcs/dcs.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +int mcu_initialize_dram (bool resume) +{ + RELEASE_ASSERT(!resume); + + // Don't perform DRAM initializion if the memory controller is already + // initialized (e.g., for SecureROM validation testing). + if (DCS_REG_READ_CH(0, rDCS_MCU_AMCCTRL) == 0) { + clock_gate(CLK_DCS0, true); + clock_gate(CLK_DCS1, true); + clock_gate(CLK_DCS2, true); + clock_gate(CLK_DCS3, true); + clock_gate(CLK_MCC, true); + + dcs_init(DCS_BOOT_COLDBOOT); + } + + return 0; +} + +void mcu_bypass_prep (int step) +{ +} + +uint64_t mcu_get_memory_size (void) +{ + return dcs_get_memory_size(); +} + +//================================================================================ +void dcs_enable_slow_boot (bool enable) +{ + if (enable) { + // switch to slow clock + clocks_set_performance(kPerformanceMemoryLow); + spin(1); + } + else { +#if !SUPPORT_FPGA + // switch back to full-speed + clocks_set_performance(kPerformanceMemoryFull); + spin(1); +#endif + } +} + +//================================================================================ +void dcs_dram_workarounds(dcs_boottype_t boot_type) +{ + /* Nothing yet */ +} + +//================================================================================ +// Grab (Platform Specific) Tables with Definitions of Values for DCS Init & DCS Tunables +#include + +#if DCS_FIXUP_PARAMS +// Grab (Target Specific) Definition of Required Fixups to the Values for DCS Init +#include +#endif +//================================================================================ +void dcs_init_config_params(dcs_config_params_t *use_dcs_params, dcs_target_t targtype) +{ + memcpy(use_dcs_params, &dcs_params, sizeof(dcs_config_params_t)); + +#if DCS_FIXUP_PARAMS + // This gives the particular target a chance to make target-specific changes + dcs_init_config_fixup_params(use_dcs_params, targtype); +#endif +} + +//================================================================================ +const dcs_tunable_t *dcs_init_tunable_table(uint32_t *table_len) +{ + if (table_len) + *table_len = sizeof(dcs_tunables) / sizeof(dcs_tunables[0]); + + return dcs_tunables; +} + +//================================================================================ +// Save off calibration results to AOP_SRAM region (later to be stitched into reconfig sequence) +// Order of registers to be saved must match the order to be restored +volatile uint32_t *dcs_save_calibration_results(volatile uint32_t *save_region, uint32_t freq) +{ + /* TBD */ + return NULL; +} + +//================================================================================ +// Stitch the saved calibration results into the reconfig sequence +// To be called immediately after stitching mcu_aop_awake_reconfig_pre_restore +// Order of registers to be restored matches the order in the reconfig sequence +void dcs_restore_calibration_results(volatile uint32_t *save_region) +{ + /* TBD */ +} + +//================================================================================ diff --git a/platform/t8010/dcs/dcs_init_lib_t8010.c b/platform/t8010/dcs/dcs_init_lib_t8010.c new file mode 100644 index 0000000..17f8d82 --- /dev/null +++ b/platform/t8010/dcs/dcs_init_lib_t8010.c @@ -0,0 +1,812 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * Init Sequence Library for use in: + * Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block + */ + +/* +Summary of Steps from the Spec (Spreadsheet) + + + (Aa) Steps 0,1,2,3a [need to identify parameterization] + + (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait] + + (Ac) Steps 3c,4,5 [need to identify parameterization] + + (B) Step 6 [Change Clk Speed] + + (C) Step 7 [include delay-wait from early Step 8] + + (D) Step 8a [Cal: CA 800MHz Vmin] + + (E) Step 8b [Write Regs] + + (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?) + + (G) Step 8d [Write Regs] + + (H) Step 9 [Write Regs] + + (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin] + + (J) Step 11 [Write Regs] + + (K) Step 12 [Cal: CA 1200MHz Vnom] + + (L) Step 13 [Write Regs] + + (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin] + + (N) Steps 15,16,17,18,19,20 [need to identify parameterization] + +Between these steps there is possibly a need/desire for: +- Frequency Changes (PMGR) +- PMU save/restore +- debug messages +- register dumps (DV, SiVal) +- anything else! + +CONFIG Table: + Compile-Time Known: + Type of Execution Environment CoreOS, DV, SiVal + Type of Target SoC, FPGA, Palladium + ChipID 0x8000, 0x8001, etc. + Revision A0, B0, B1, etc. + Num DCS 4, 8, etc. (Derived...!) + Variant Flags Work-arounds, RADAR Ref., et al. + + (Config Info know at Compile time can be subject to #if) + + Run-Time Known: + Type of Init ColdBoot, AOP_DDR, AOP_AWAKE + Debug Flags Low-Level, Milestone, et al. + +RegValue Table + Much like today's: various values for various registers + Sensitive to ChipID (also Target type?) + (Internal static alloc (Complete Table Fill-in within Init function): + Fill in Values (per ChipID/Rev & Target-type) + return pointer to caller + (Allows customization by caller before use) + +TODO: +- Convert to using SPDS for register names, et al + +*/ + +//================================================================================ +// API Definitions +#include + +extern dcs_config_t dcs_cfg; +extern dcs_config_params_t dcs_params; + +#if izIBOOT +extern int debug_level_dcs; +#endif + +void dcs_enable_autorefresh(void) +{ + uint32_t arefen_freq0 = 0x1011013f; + uint32_t arefen_freq1 = 0x10010000; + + arefen_freq1 = 0x10110000; + + // Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last. + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), 0x10100000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), 0x10000000); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), arefen_freq1); + dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), arefen_freq0); +} + + +//================================================================================ +// Implementing the Various Steps of the DCS Init, per Specification +// Based on AMC Init Spec (Spreadsheet) +// - Supporting Maui: Spec (v??) +//================================================================================ +// Step 0: AMC Prolog +//================================================================================ +void dcs_init_Prolog(void) +{ + // NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds + if (izFPGA && izColdBoot) { + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0); + delay_for_us(200); + dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1); + delay_for_us(200); + } +} + +//================================================================================ +// Step 1: AMC Initial Configuration +//================================================================================ +void dcs_init_AMC_Initial_Config(void) +{ + uint32_t i,n; + +// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman + + dcs_reg_write_all_chan(rDCS_SPLLCTRL_MODEREG, 0x1); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_1); + + + + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + for (n = 0; n < dcs_params.num_freqchngctl_regs; n++) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]); + + // This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim); + } + + + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALVREFCODECONTROL, dcs_params.wrdqcalvrefcodecontrol); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALVREFCODECONTROL, dcs_params.rddqcalvrefcodecontrol); + dcs_reg_write_all_chan(rDCS_MCU_MODEREG, 0x120c90b8); + + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat); + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch); + dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act); + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref); + dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref); + + if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg); + + dcs_reg_write_all_chan(rDCS_MCU_PDN_FREQ(i), dcs_params.freq[i].pdn); + if (i == 0) { + dcs_reg_write_all_chan(rDCS_MCU_PDN1, dcs_params.pdn1); + dcs_reg_write_all_chan(rDCS_MCU_MODEREG1, dcs_params.modereg1); + } + } + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params); + dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn); + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate); + + // These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2); + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat); + dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl); + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000); + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002); + + dcs_reg_write_all_chan(rDCS_MCU_LS3B_QUIES_CTRL, 0x00000015); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000); + +} + +//================================================================================ +// Step 2: AMP Initial Configuration +//================================================================================ +void dcs_init_AMP_Initial_Config(void) +{ + int i; + + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref); + dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref); + } + + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0); + + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000); + + if (!izFPGA) + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim); + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001); + dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001); + } + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + for(i = 1; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming); + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming); + dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming); + } + } + + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), dcs_params.rdwrdqcalseglen_f0); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(1), dcs_params.rdwrdqcalseglen_f1); + dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(3), dcs_params.rdwrdqcaltiming_f3); + + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i); + + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(0), 0x87654321); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(1), 0xcdedcba9); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(2), 0x456789ab); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(3), 0x5fa63123); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATINVERTMASK, 0x55550000); + + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow); + dcs_reg_write_all_chan(rDCS_AMP_MAXRDDQS_SDLL_MULFACTOR, dcs_params.maxrddqssdllmulfactor); + + dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor); + + // These register writes to be skipped for Maui A0/A1 + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000); + dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000); + } + + for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) { + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg); + dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg); + } + + if (!izFPGA) { + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1); + } + + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl); + + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), 0); + dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), 0); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100); + + dcs_reg_write_all_chan(rDCS_AMP_DCCCONTROL, dcs_params.dcccontrol); + dcs_reg_write_all_chan(rDCS_AMP_DCCTIMER, 0x00000190); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALDYNHALFCLKDLYCTRL, 0x00000001); + + +// AMPH configuration + + + dcs_reg_write_all_chan(rDCS_AMPH_CB_DRIVESTR, dcs_params.cbdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CB_IOCTL, dcs_params.cbioctl); + dcs_reg_write_all_chan(rDCS_AMPH_CK_DRIVESTR, dcs_params.ckdrivestr); + dcs_reg_write_all_chan(rDCS_AMPH_CK_IOCTL, dcs_params.ckioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DRIVESTR, dcs_params.b0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B0_IOCTL, dcs_params.b0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, dcs_params.b0odt); + dcs_reg_write_all_chan(rDCS_AMPH_B0_ODTCTRL, dcs_params.b0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DRIVESTR, dcs_params.b1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODTCTRL, dcs_params.b1odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_IOCTL, dcs_params.b1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, dcs_params.b1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DRIVESTR, dcs_params.dqs0drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IOCTL, dcs_params.dqs0ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, dcs_params.dqs0odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ZDETBIASEN, dcs_params.dqs0zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODTCTRL, dcs_params.dqs0odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DRIVESTR, dcs_params.dqs1drivestr); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IOCTL, dcs_params.dqs1ioctl); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, dcs_params.dqs1odt); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ZDETBIASEN, dcs_params.dqs1zdetbiasen); + dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODTCTRL, dcs_params.dqs1odtctrl); + dcs_reg_write_all_chan(rDCS_AMPH_DBG_REG0, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(1), dcs_params.zcalfsm1); + dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(0), dcs_params.zcalfsm0); + dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), dcs_params.spare0); + dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALTVREF, dcs_params.hwrddqcaltvref); + dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALTVREF, dcs_params.hwwrdqcaltvref); + +} + +//================================================================================ +// Step 3: Self-Refresh Exit +//================================================================================ +void dcs_init_Self_Refresh_Exit_a(void) +{ + // Wait 5 us after Impedence Calibration to avoid McPhyPending + // preventing the SRFSM from exiting SR. + dcs_spin(5, "after Imp. Cal."); + + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + + for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++) + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2); + + dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2); + + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc); + // M8 Bug radar #20346417, two writes to ensure propogation + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr); + dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030004); + +} + +//======================================== +// Caller Code should: +// - Change Frequency to 50MHz +//======================================== + +void dcs_init_Self_Refresh_Exit_b(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); + + for(uint32_t i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001); + + if (!izFPGA) { + dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001); + dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00); + } + + if (izResume) + dcs_enable_autorefresh(); + + dcs_spin(2200, "After Enable Auto-Refresh"); + + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + dcs_spin(2, "After SoC Update"); + } + + // Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh + // Issue self-refresh exit cmd for resume boot with MPC + int n = (izColdBoot)? 0x00000000:0x00004000; + // Issue self-refresh exit cmd for resume boot with MPC + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n); + dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1); + dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00); + + dcs_spin(2, NULL); + + dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1); +} + +//================================================================================ +// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only) +//================================================================================ +void dcs_init_ZQ_Cal_Cfg(void) +{ + // ZQ calibration START MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f); + // wait 1us for tZQCAL + dcs_spin(1, "tZQCAL"); + + // ZQ calibration LATCH MPC cmd + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51); + // wait 10ns for tZQLAT + dcs_spin(1, "tZQLAT"); + + if (izColdBoot) { + // MR2 register (read/write latency) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0); + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x59); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x59); + // MR23 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80); + + uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff; + uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I); + + // MR15 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff); + // MR20 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff); + // MR32 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff); + // MR40 register + dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff); + } +} + +//================================================================================ +// Step 5a: AddrConfig Configuration +//================================================================================ +void dcs_init_AddrCfg_Cfg(void) +{ + + dcs_reg_write(rAMCC_ADDRCFG_ADDR, dcs_params.addrcfg); +#if NUM_AMCCS == 2 + dcs_reg_write(rAMCC1_ADDRCFG_ADDR, dcs_params.addrcfg); +#endif + +} + +//======================================== +// Caller Code should: +// - Use MR Cmds to Query the Device +//======================================== + +//================================================================================ +// Step 5b: Total Mem Size Config +//================================================================================ +void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes) +{ + + dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n", + (((uint64_t)total_size_Mbytes) * MEG * NUM_AMCCS)); + // (Units of 128 MBs in the register) + dcs_reg_write(rAMCC_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1); + dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec); + +#if NUM_AMCCS == 2 + dcs_reg_write(rAMCC1_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1); + dcs_reg_write(rAMCC1_MCCCHNLDEC_ADDR, dcs_params.chnldec); +#endif + dbgprintf(DCS_DBG_ASSESS_CONFIG, "rAMCC_DRAMACCCTRL: 0x%08x\n", rAMCC_DRAMACCCTRL); +} + +//================================================================================ +// Step 6: Switch from boot-clock speed to normal operation speed +//================================================================================ +void dcs_init_Reenable_AMC_Scheduler(void) +{ + // Wait 5 us before freq change to make sure all refreshes have been flushed + dcs_spin(5, "After Refresh"); + + // Enable (again) the AMC Scheduler + dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003); +} + +//================================================================================ +// Step 7: Setup registers for CA calibration for bucket 1 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq1(void) +{ + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7); + + if (izColdBoot) { + if (izFPGA) { + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00); + } else { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7); + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11); + } + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000); + } +} + +//================================================================================ +// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz +//================================================================================ +void dcs_init_CA_Cal_Freq1(void) +{ + // Nothing to be done at this step for cold boot +} + +//================================================================================ +// Step 9: Setup registers for DQ calibration for bucket 1 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq1_a(void) +{ + int i; + + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9); + } + + dcs_spin(1, NULL); + + if(izResume) { + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002); + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888); + + for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C); + for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000); + for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++) + dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000); + } +} + +// Caller code should change frequency to bucket 1 +void dcs_init_DQ_Cal_Setup_Freq1_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 10: PHY write DQ calibration +//================================================================================ +void dcs_init_wrdq_skew(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000); + dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000); +} + +void dcs_init_post_wrlvl(void) +{ + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010); + } + +} + +//================================================================================ +// Step 11: Setup registers for CA calibration for bucket 0 +//================================================================================ +void dcs_init_CA_Cal_Setup_Freq0(void) +{ + if (izColdBoot) { + + if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) { + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000); + } + + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11); + if (!izFPGA) { + // MR2 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11); + // MR1 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11); + // MR3 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11); + } + + // MR22 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11); + // MR11 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11); + // MR12 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11); + // MR14 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11); + + if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) { + dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200); + dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000); + } + } +} + +//================================================================================ +// Step 12: AMP Dynamic CA Timing Calibration +//================================================================================ + +//================================================================================ +// Step 13: Setup registers for DQ calibration for bucket 0 +//================================================================================ +void dcs_init_DQ_Cal_Setup_Freq0_a(void) +{ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13); + + // Wait 1 us + dcs_spin(1, NULL); + } +} + +void dcs_init_DQ_Cal_Setup_Freq0_b(void) +{ + if (izColdBoot) { + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000); + dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000); + + // Wait 2us for the soc update to finish + dcs_spin(2, NULL); + } + } +} + +//================================================================================ +// Step 14: AMP Dynamic DQ Calibration +//================================================================================ + +//================================================================================ +// Step 15: Setup Registers for Boot +//================================================================================ +void dcs_init_Reg_for_Boot(void) +{ + +#ifndef DCS_RUN_AT_50MHZ + if (izColdBoot) { + // MR13 register + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15); + } +#endif + if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1))) + dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50); + + // Wait 1 us + dcs_spin(1, NULL); + + if (izColdBoot) { + dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15); + +#if !DCS_DO_CALIBRATION + // skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target + if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) { + + dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ0), 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ1), 0x00000000); + + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15); + dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0); + } +#endif + } + + + if(!izFPGA) + { + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000); + dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000003); + } + +} + +//================================================================================ +// Step 16: Enable Other Features +//================================================================================ +void dcs_init_MoreFeatures(void) +{ + dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2); + + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren_step16); + dcs_reg_write_all_chan(rDCS_MCU_PSQWQCTL0, 0x00000100); + + if (izColdBoot) + dcs_enable_autorefresh(); + + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL_ASRTIME, dcs_params.b0dyniselasrtime); + dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL, dcs_params.b0dynisel); + dcs_reg_write_all_chan(rDCS_AMPH_B1_DYN_ISEL, dcs_params.b1dynisel); + +} + +//================================================================================ +// Step 17: Enable Fast Critical Word Forwarding Feature +//================================================================================ +void dcs_init_Fast_Critical_Word_Forwarding(void) +{ + + dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam); + dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren); + dcs_reg_write(rAMCC_MCCGEN_ADDR, dcs_params.mccgen); + + +#if NUM_AMCCS == 2 + dcs_reg_write(rAMCC1_MCCGEN_ADDR, dcs_params.mccgen); + +#endif // #if NUM_AMCCS == 2 + +} + +//================================================================================ +// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers +//================================================================================ +void dcs_init_Gating_Global_Timers(void) +{ + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk); + dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk); + dcs_reg_write_all_chan(rDCS_SPLLCTRL_MDLLPWRDNCFG(0), 0x00000001); + + + dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten); + dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x000001ff); + + + if(!izFPGA) { + + dcs_reg_write_all_chan(rDCS_MCU_PSQWQCTL1, 0x01e60120); + } + + + // Global Timer Setup + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x00f000f0); + dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x00f000f0); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02400240); + dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02400240); + dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000 + dcs_reg_write(rGLBTIMER_DCCTIMER, 0x000bb8); + dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75 + dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15 + dcs_reg_write(rGLBTIMER_IDTTIMER, 0x007530); // 30000 + dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000 + dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000 + dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001); // 300000 + dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000 + dcs_reg_write(rGLBTIMER_PERVREFCALCFG, 0x0000000b); + dcs_reg_write(rGLBTIMER_FREQCHNGCFG, 0x000000ff); + + // Dynamic Clk & Power Gating + dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a0000); + +} + +//================================================================================ +// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading +//================================================================================ +void dcs_init_ODTS(void) +{ + uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need + // INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank]; + + // MR4 read to bring memory out of self-refresh + dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp); + // M8 Bug radar #20346417, two writes to ensure propogation + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3); + +} + +//================================================================================ diff --git a/platform/t8010/dcs/rules.mk b/platform/t8010/dcs/rules.mk new file mode 100644 index 0000000..9a82c89 --- /dev/null +++ b/platform/t8010/dcs/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_DCS=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/dcs.o \ + $(LOCAL_DIR)/dcs_init_lib_t8010.o diff --git a/platform/t8010/error_handler/error_handler.c b/platform/t8010/error_handler/error_handler.c new file mode 100644 index 0000000..b150345 --- /dev/null +++ b/platform/t8010/error_handler/error_handler.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +// All errors (the remaining bits are perf counters) +#define AMCC_IRERRDBG_INTEN_ALLERRORS ( \ + AMCC_IRERRDBG_INTSTS_MCC_TP_PAR_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_DAT_ONE_BIT_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_DAT_MULTI_BITS_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_AF_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCC_TP_MULTI_PAR_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCS_LS3_B_ALLOC_PAR_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCS_LS3_B_RESP_PAR_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCS_LS3_B_TOKEN_PAR_ERR_UMASK \ + | AMCC_IRERRDBG_INTSTS_MCS_LS3_B_DATA_PULL_PAR_ERR_UMASK \ + ) + +#define AMCC_IRERRDBG_INTSTS_ALLERRORS AMCC_IRERRDBG_INTEN_ALLERRORS + +#define AMCC_IRERRDBG_MCC_AF_ERR_LOG2_AGENT_IODAP (0x88) + +#define CP_COM_NORM_MSK_CLR_ALL (~0) +#define CP_COM_NORM_MSK_ILLEGAL_COH_INTS ( \ + CP_COM_INT_NORM_MASK_SET_CCU0_ILLEGAL_PIO_ACCESS_INT_MSK_SET_UMASK \ + | CP_COM_INT_NORM_MASK_SET_CCU1_ILLEGAL_PIO_ACCESS_INT_MSK_SET_UMASK \ + ) + +#if NUM_AMCCS > 1 +#error "amc_int_handler() must be recoded for NUM_AMCCS > 1" +#endif + +static void amc_int_handler(void *arg __unused) +{ + uint32_t intsts = rAMCC_IRERRDBG_INTSTS(0); + + if ((intsts & (AMCC_IRERRDBG_INTEN_ALLERRORS & ~AMCC_IRERRDBG_INTSTS_MCC_AF_ERR_UMASK)) == 0) { + // Whitelist errors caused by the IODAP agent (Astris) since + // these are most likely caused by user input errors. + uint32_t agent_id = AMCC_IRERRDBG_MCC_AF_ERR_LOG2_MCC_AF_ERR_AID_LOG_XTRCT(rAMCC_IRERRDBG_MCC_AF_ERR_LOG2(0)); + if (agent_id == AMCC_IRERRDBG_MCC_AF_ERR_LOG2_AGENT_IODAP) { + dprintf(DEBUG_INFO, "AMC error from IODAP (ignored): 0x%x\n", intsts); + + // Clear the interrupt and continue on. + rAMCC_IRERRDBG_INTSTS(0) = intsts; + return; + } + } + + panic("Received unexpected AMC error. AMCC_IRERRDBG_INTSTS = 0x%x\n", intsts); +} + +static void cp_int_handler(void *arg __unused) { + panic("Received unexpected Coherency Point error. CP_COM_INT_NORM_REQUEST = 0x%x\n", rCP_COM_INT_NORM_REQUEST); +} + +static void enable_cp_checks() +{ + install_int_handler(INT_COHERENCE_PNT_ERR, cp_int_handler, NULL); + rCP_COM_INT_NORM_MASK_CLR = CP_COM_NORM_MSK_CLR_ALL; + unmask_int(INT_COHERENCE_PNT_ERR); +} + +static void enable_amc_checks() +{ + install_int_handler(INT_MEM_CONTROLLER0, amc_int_handler, NULL); + rAMCC_IRERRDBG_INTEN(0) = AMCC_IRERRDBG_INTEN_ALLERRORS; + if (rAMCC_IRERRDBG_INTSTS(0) & AMCC_IRERRDBG_INTSTS_ALLERRORS) { + // AMC Interrupts, unlike the CP ones, don't seem to stick. If an error already exists + // this early in bootup, we won't get an interrupt upon unmask. + amc_int_handler(NULL); + } + rAMCC_IRERRDBG_INTSTS(0) = AMCC_IRERRDBG_INTSTS_ALLERRORS; + unmask_int(INT_MEM_CONTROLLER0); +} + +void platform_enable_error_handler() { + enable_amc_checks(); + enable_cp_checks(); +} + diff --git a/platform/t8010/error_handler/rules.mk b/platform/t8010/error_handler/rules.mk new file mode 100644 index 0000000..b61e8a1 --- /dev/null +++ b/platform/t8010/error_handler/rules.mk @@ -0,0 +1,16 @@ +# Copyright (C) 2011-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_PLATFORM_ERROR_HANDLER=1 + +ALL_OBJS += \ + $(LOCAL_DIR)/error_handler.o diff --git a/platform/t8010/include/platform/apcie.h b/platform/t8010/include/platform/apcie.h new file mode 100644 index 0000000..085270b --- /dev/null +++ b/platform/t8010/include/platform/apcie.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef PLATFORM_APCIE_H +#define PLATFORM_APCIE_H + +#define APCIE_LANE_CFG_X1_X1_X1_X1 (0) +#define APCIE_LANE_CFG_X2_X1_X1 (1) +#define APCIE_LANE_CFG_X1_X1_X2 (2) +#define APCIE_LANE_CFG_X2_X2 (3) + +#define APCIE_LANE_CONFIG_NVME0_X1 APCIE_LANE_CFG_X1_X1_X1_X1 +#define APCIE_LANE_CONFIG_NVME0_X2 APCIE_LANE_CFG_X2_X1_X1 + +#endif diff --git a/platform/t8010/include/platform/apcie_regs.h b/platform/t8010/include/platform/apcie_regs.h new file mode 100644 index 0000000..d593167 --- /dev/null +++ b/platform/t8010/include/platform/apcie_regs.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _APCIE_REGS_H +#define _APCIE_REGS_H + +#include +#include +#include +#include + +#define APCIE_COUNTER_PORT_STRIDE (APCIE_LCOUNT_BLK_TIME_L0_1_OFFSET - APCIE_LCOUNT_BLK_TIME_L0_0_OFFSET) +#define APCIE_NUM_COUNTERS (8) + +#define APCIE_PORT_COUNTER_BASE_ADDR(port) (APCIE_COUNTER_BASE_ADDR + (port) * APCIE_COUNTER_PORT_STRIDE) +#define APCIE_PORT_BASE_ADDR(port) (APCIE_CONFIG_BASE_ADDR + APCIE_CONFIG_PORT_STRIDE * (port)) +#define PCIE_PORT_BASE_ADDR(port) (PCI_CONFIG_BASE + ((port) << PCI_DEVICE_SHIFT)) + +#define rAPCIE_COUNTER_VALUE(port, n) (*(volatile uint32_t *)(APCIE_PORT_COUNTER_BASE_ADDR(port) + (n) * 4)) +#define rAPCIE_COUNTER_COMMAND(port) (*(volatile uint32_t *)(APCIE_PORT_COUNTER_BASE_ADDR(port) + APCIE_LCOUNT_BLK_LCOUNT_COMMAND_0_OFFSET)) + +#define APCIE_COUNTER_ENABLE APCIE_LCOUNT_BLK_LCOUNT_COMMAND_0_ENABLE_UMASK +#define APCIE_COUNTER_CLEAR APCIE_LCOUNT_BLK_LCOUNT_COMMAND_0_CLEAR_UMASK +#define APCIE_COUNTER_CAPTURE APCIE_LCOUNT_BLK_LCOUNT_COMMAND_0_CAPTURE_UMASK + +#define PCIE_RC_CAP_LINK_CONTROL2_OFFSET(link) (PCIE_PORT_BASE_ADDR(link) + X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_LINK_CONTROL2_LINK_STATUS2_REG_OFFSET) +#define PCIE_RC_CAP_LINK_CONTROL2_PCIE_TARGET_LINK_SPEED_UMASK X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_LINK_CONTROL2_LINK_STATUS2_REG_PCIE_CAP_TARGET_LINK_SPEED_UMASK + +#define PCIE_RC_PORT_LOGIC_GEN2_CTRL_OFFSET(link) (PCIE_PORT_BASE_ADDR(link) + X2_PCIE_RC_X2_PCIE_DSP_PF0_PORT_LOGIC_GEN2_CTRL_OFF_OFFSET) +#define PCIE_RC_PORT_LOGIC_GEN2_CTRL_NUM_OF_LANES_SHIFT X2_PCIE_RC_X2_PCIE_DSP_PF0_PORT_LOGIC_GEN2_CTRL_OFF_NUM_OF_LANES_SHIFT +#define PCIE_RC_PORT_LOGIC_GEN2_CTRL_NUM_OF_LANES_UMASK X2_PCIE_RC_X2_PCIE_DSP_PF0_PORT_LOGIC_GEN2_CTRL_OFF_NUM_OF_LANES_UMASK + +#define PCIE_RC_PORT_LOGIC_PORT_LINK_CTRL_OFFSET(link) (PCIE_PORT_BASE_ADDR(link) + X2_PCIE_RC_X2_PCIE_DSP_PF0_PORT_LOGIC_PORT_LINK_CTRL_OFF_OFFSET) +#define PCIE_RC_PORT_LOGIC_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT X2_PCIE_RC_X2_PCIE_DSP_PF0_PORT_LOGIC_PORT_LINK_CTRL_OFF_LINK_CAPABLE_SHIFT +#define PCIE_RC_PORT_LOGIC_PORT_LINK_CTRL_LINK_CAPABLE_UMASK X2_PCIE_RC_X2_PCIE_DSP_PF0_PORT_LOGIC_PORT_LINK_CTRL_OFF_LINK_CAPABLE_UMASK + +#define PCIE_RC_PORT_LOGIC_L1SUB_CAPABILITY_REG_OFFSET(link) (PCIE_PORT_BASE_ADDR(link) + X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_OFFSET) +#define PCIE_RC_PORT_LOGIC_L1SUB_CAPABILITY_REG_PWR_ON_VALUE_SUPPORT_UMASK X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_PWR_ON_VALUE_SUPPORT_UMASK +#define PCIE_RC_PORT_LOGIC_L1SUB_CAPABILITY_REG_COMM_MODE_SUPPORT_UMASK X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_COMM_MODE_SUPPORT_UMASK + +#define rAPCIE_PMA_LANE_TX_XCVR_DIAG_FUNC_PWR_CTRL(lane) (*(volatile uint32_t *)(APCIE_PHY_PMA_TX_LANE_BASE_ADDR + (PMA_TX_LANE_REGISTERS_BLK_XCVR_DIAG_FUNC_PWR_CTRL_OFFSET + ((lane) * APCIE_PHY_PMA_TX_LANE_STRIDE)))) +#define rAPCIE_PMA_LANE_TX_XCVR_DIAG_DCYA(lane) (*(volatile uint32_t *)(APCIE_PHY_PMA_TX_LANE_BASE_ADDR + (PMA_TX_LANE_REGISTERS_BLK_XCVR_DIAG_DCYA_OFFSET + ((lane) * APCIE_PHY_PMA_TX_LANE_STRIDE)))) +#define rAPCIE_PMA_LANE_TX_DIAG_TX_BOOST(lane) (*(volatile uint32_t *)(APCIE_PHY_PMA_TX_LANE_BASE_ADDR + (PMA_TX_LANE_REGISTERS_BLK_TX_DIAG_TX_BOOST_OFFSET + ((lane) * APCIE_PHY_PMA_TX_LANE_STRIDE)))) + +#define rAPCIE_PMA_LANE_RX_REE_GEN_CTRL_EN(lane) (*(volatile uint32_t *)(APCIE_PHY_PMA_RX_LANE_BASE_ADDR + (PMA_RX_LANE_REGISTERS_BLK_RX_REE_GEN_CTRL_EN_OFFSET + ((lane) * APCIE_PHY_PMA_RX_LANE_STRIDE)))) +#define rAPCIE_PMA_LANE_RX_REE_FREE0_CFGD(lane) (*(volatile uint32_t *)(APCIE_PHY_PMA_RX_LANE_BASE_ADDR + (PMA_RX_LANE_REGISTERS_BLK_RX_REE_FREE0_CFGD_OFFSET + ((lane) * APCIE_PHY_PMA_RX_LANE_STRIDE)))) + +#endif /* _APCIE_REGS_H */ diff --git a/platform/t8010/include/platform/dcsconfig.h b/platform/t8010/include/platform/dcsconfig.h new file mode 100644 index 0000000..e104f30 --- /dev/null +++ b/platform/t8010/include/platform/dcsconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCSCONFIG_H +#define __DCSCONFIG_H + +// Needful defnitions for the initializers below +#include +#include +#include +#include + +#include SUB_PLATFORM_HEADER(dcsconfig) + +#endif diff --git a/platform/t8010/include/platform/dcsconfig_t8010.h b/platform/t8010/include/platform/dcsconfig_t8010.h new file mode 100644 index 0000000..a373708 --- /dev/null +++ b/platform/t8010/include/platform/dcsconfig_t8010.h @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __DCSCONFIG_T8010_H +#define __DCSCONFIG_T8010_H + +dcs_config_params_t dcs_params = { + .supported_freqs = DCS_FREQ(0) | DCS_FREQ(1) | DCS_FREQ(3), + .num_freqchngctl_regs = 5, + .spllctrl_vco_1 = 0x00000015, + .wrdqcalvrefcodecontrol = 0x19191111, + .rddqcalvrefcodecontrol = 0x19199191, + .pdn1 = 0x0, + .modereg = 0x1a0c80f4, + .modereg1 = 0x0000000c, + .autoref_params = 0x0015005d, + .pdn = 0x722762c6, + .rnkcfg = 0x00006061, + .casdllupdatectrl = 0x03030305, + .dqsdllupdatectrl = 0x00030005, + .rdsdllctrl_step2 = 0x00ff0002, + .wrdqdqssdllctrl_step2 = 0xff000002, + .cawrlvlsdllcode = 0x00ff01ff, + .dlllocktim = 0x00c801f4, + .rdwrdqcaltiming_f0 = 0x01060508, + .rdwrdqcalseglen_f0 = 0x0d0b1313, + .rdwrdqcaltiming_f1 = 0x01060305, + .rdwrdqcalseglen_f1 = 0x09070d0d, + .rdwrdqcaltiming_f3 = 0x01060308, + .rddqcalpatprbs4i = 0x55553c5a, + .wrdqcalpatprbs4i = 0x00003c5a, + .maxrddqssdllmulfactor = 0x00a00d14, + .maxwrdqssdllmulfactor = 0xa0a00d0d, + .dllupdtctrl1 = 0x80000080, + .dllupdtintvl = 0x10200020, + .dcccontrol = 0x10050b27, + .cbdrivestr = 0x77838317, + .cbioctl = 0x0002000b, + .ckdrivestr = 0x77838317, + .ckioctl = 0x0000000f, + .b0drivestr = 0x77838317, + .b0ioctl = 0x7160000f, + .b0odt = 0x01c00333, + .b0odtctrl = 0x00000007, + .b1drivestr = 0x77838317, + .b1odtctrl = 0x00000007, + .b1ioctl = 0x7160000f, + .b1odt = 0x01c00333, + .dqs0drivestr = 0x77838317, + .dqs0ioctl = 0x7160000f, + .dqs0odt = 0x01c00333, + .dqs0zdetbiasen = 0x0007082a, + .dqs0odtctrl = 0x00000007, + .dqs1drivestr = 0x77838317, + .dqs1ioctl = 0x7160000f, + .dqs1odt = 0x01c00333, + .dqs1zdetbiasen = 0x0007082a, + .dqs1odtctrl = 0x00000007, + .zcalfsm1 = 0x00887f7f, + .zcalfsm0 = 0x000f031b, + .spare0 = 0x00000016, + .hwrddqcaltvref = 0x08080808, + .hwwrdqcaltvref = 0x323286c8, + .arefparam = 0x08012019, + .autoref_params2 = 0x0017005d, + .odtszqc = 0x00001000, + .longsr = 0x01012008, + .freqchngctl_step3 = 0x00010000, + .mr3cmd = 0xf3, + .mr13cmd = 0x18, + .addrcfg = 0x00030201, + .chnldec = 0x00050220, +// steps 7-14 are skipped for FPGA since only freq used is 50 MHz +// Cayman: Implement stesp 7-14 of the memory init sequence (only used on silicon) +// .mr3cmd_step11 = 0xb2, + .mr13cmd_step15 = 0x50, + .freqchngctl_step15 = 0x00009999, + .rdsdllctrl_step15 = 0x00140004, + .odtszqc2 = 0xc0001000, + .qbren_step16 = 0x0000000f, + .b0dyniselasrtime = 0x00001c25, + .b0dynisel = 0x00000003, + .b1dynisel = 0x00000003, + .qbrparam = 0x00001070, + .qbren = 0x0000000f, + .mccgen = 0x00100124, + .caampclk = 0x8a000000, + .dqampclk = 0x80000000, + .pwrmngten = 0x00000033, + .odtszqc3 = 0xc0003320, + + .freq = { + { // 1600MHz + .clk_period = CLK_PERIOD_1600, + .freqchngctl = {0x18cd104d, 0x110c110e, 0xa303440b, 0xde012d02, 0x00000416}, + .freqchngtim = 0x000c1108, + .lat = 0x00113387, + .phyrdwrtim = 0x00060d0c, + .caspch = 0x63e2080f, + .act = 0x2008110f, + .autoref = 0x489000a0, + .selfref = 0xa0096012, + .pdn = 0x00000076, + .derate = 0x4d05a910, + .lat2 = 0x00123387, + .tat = 0x01412222, + .mifqmaxctrl = 0x00000100, + .cavref = 0x00000003, + .dqvref = 0x00c00000, + .dqdficaltiming = 0x04060604, + .rddqcalwindow = 0x00f801d1, + .wrdqcalwindow = 0x012f0360, + .rdcapcfg = 0x00000810, + .autoref2 = 0x48900092, + }, + { // 1066MHz + .freqchngctl = {0x18cd104d, 0x110c110e, 0xd303220b, 0xbe011b02, 0x00000216}, + .freqchngtim = 0x000c1108, + .lat = 0x001022c5, + .phyrdwrtim = 0x00040c09, + .caspch = 0x4297060a, + .act = 0x16060c0a, + .autoref = 0x3060006b, + .selfref = 0x6b064012, + .pdn = 0x00000054, + .derate = 0x34b3760b, + .lat2 = 0x001122c5, + .tat = 0x01312222, + .cavref = 0x00000003, + .dqvref = 0x00c00000, + .cadficaltiming = 0x04060604, + .dqdficaltiming = 0x04060604, + .rddqcalwindow = 0x00f801d1, + .wrdqcalwindow = 0x012f0360, + .rdcapcfg = 0x2000070c, + .autoref2 = 0x30600061, + }, + { // 200MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010b01, + .caspch = 0x40c50402, + .act = 0x04020302, + .autoref = 0x09120014, + .selfref = 0x28013012, + .pdn = 0x00000033, + .derate = 0x0c212142, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .cavref = 0x00000003, + .dqvref = 0x00000000, + .cadficaltiming = 0x04060604, + .dqdficaltiming = 0x04060604, + .rdcapcfg = 0x40000406, + .autoref2 = 0x09120013, + }, + { // 50MHz + .freqchngctl = {0x18cd104d, 0x590c590e, 0xf303000b, 0x8e010002, 0x00000016}, + .freqchngtim = 0x000c1108, + .phyrdwrtim = 0x00010901, + .caspch = 0x40c20402, + .act = 0x02020404, + .autoref = 0x03050005, + .selfref = 0x28006012, + .pdn = 0x00000033, + .derate = 0x10412082, + .lat2 = 0x001110c2, + .tat = 0x01212222, + .mifqmaxctrl = 0x00000001, + .cavref = 0x00000003, + .dqvref = 0x00000000, + .cadficaltiming = 0x02060602, + .dqdficaltiming = 0x02060602, + .rdcapcfg = 0x60000406, + .autoref2 = 0x03050005, + } + } +}; + +#define BIT32_MASKFULL (0xFFFFFFFF) +#define BIT32_MASK(_n) (BIT32_MASKFULL >> (32 - (_n))) +#define BIT32_MASK_VAL(_h,_l,_d) (((_d) & BIT32_MASK((_h) - (_l) + 1)) << (_l)) +#define BIT32_MASK_HI_LO(_h,_l) BIT32_MASK_VAL(_h,_l,BIT32_MASKFULL) +#define DCS_MASK_VAL(_h,_l,_d) BIT32_MASK_HI_LO(_h,_l) , BIT32_MASK_VAL(_h,_l,_d) + +// DCS Tunables for t8010 +// Tunables Spec versions: +// MCU: https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/tunables/MCU.html dated 2015/02/09 +// Notes: +// All channels are tuned in exactly the same way +// Registers with all fields' tunable values matching the reset value omitted +const dcs_tunable_t dcs_tunables[] = { + + { rDCS_MCU_CLKGATE, DCS_MASK_VAL(19, 16, 0x1) }, + { rDCS_MCU_CLKGATE, DCS_MASK_VAL(15, 12, 0x3) }, + { rDCS_MCU_CLKGATE, DCS_MASK_VAL( 8, 7, 0x2) }, + { rDCS_MCU_CLKGATE, DCS_MASK_VAL( 6, 4, 0x1) }, + + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL(12, 12, 0x1) }, + { rDCS_MCU_AMCCLKPWRGATE, DCS_MASK_VAL( 8, 8, 0x1) }, + + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(31, 24, 0xff) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(20, 20, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL(12, 12, 0x0) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_PSQRQCTL0, DCS_MASK_VAL( 4, 4, 0x1) }, + + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(27, 16, 0x014) }, + { rDCS_MCU_PSQRQTIMER0, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(27, 16, 0x00f) }, + { rDCS_MCU_PSQRQTIMER1, DCS_MASK_VAL(11, 0, 0x040) }, + + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(20, 16, 0x10) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQRQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQRQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL(16, 16, 0x1) }, + { rDCS_MCU_PSQWQ_CTL(0), DCS_MASK_VAL( 8, 8, 0x1) }, + + // part of init sequence, so have to apply tunables even if same as reset values + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(31, 16, 0x01e6) }, + { rDCS_MCU_PSQWQ_CTL(1), DCS_MASK_VAL(15, 0, 0x02da) }, + + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(28, 24, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(20, 16, 0x08) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL(12, 8, 0x04) }, + { rDCS_MCU_PSQWQBRST, DCS_MASK_VAL( 4, 0, 0x10) }, + + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(23, 16, 0x10) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL(15, 8, 0x14) }, + { rDCS_MCU_PSQWQSCHCRD, DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 8, 8, 0x1) }, + { rDCS_MCU_QOSLLT, DCS_MASK_VAL( 4, 0, 0x1f) }, + + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL(31, 31, 0x1) }, + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL(15, 8, 0x6f) }, + { rDCS_MCU_SBQOSUPGCTL, DCS_MASK_VAL( 7, 0, 0x6e) }, + + // DRAM Cfg + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL(31, 16, 0x0300) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(0), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL(31, 16, 0x0200) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(1), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL(31, 16, 0x0180) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(2), DCS_MASK_VAL( 7, 0, 0x00) }, + + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL(31, 16, 0x0017) }, + { rDCS_MCU_PWRMNGTPARAM_FREQ(3), DCS_MASK_VAL( 7, 0, 0x00) }, + + // Alternate End Marker + // { 0, 0, 0 } +}; + +#endif diff --git a/platform/t8010/include/platform/error_handler.h b/platform/t8010/include/platform/error_handler.h new file mode 100644 index 0000000..8c2889f --- /dev/null +++ b/platform/t8010/include/platform/error_handler.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_ERROR_HANDLER_H +#define __PLATFORM_ERROR_HANDLER_H + +void platform_enable_error_handler(); + +#endif // __PLATFORM_ERROR_HANDLER_H diff --git a/platform/t8010/include/platform/gpiodef.h b/platform/t8010/include/platform/gpiodef.h new file mode 100644 index 0000000..04f25de --- /dev/null +++ b/platform/t8010/include/platform/gpiodef.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_H +#define __PLATFORM_GPIODEF_H + +#include +#include +#include + +#if WITH_TARGET_CONFIG +# include +#endif + +#include SUB_PLATFORM_HEADER(gpiodef) + +#endif /* ! __PLATFORM_GPIODEF_H */ diff --git a/platform/t8010/include/platform/gpiodef_t8010.h b/platform/t8010/include/platform/gpiodef_t8010.h new file mode 100644 index 0000000..2000adf --- /dev/null +++ b/platform/t8010/include/platform/gpiodef_t8010.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_GPIODEF_t8010_H +#define __PLATFORM_GPIODEF_t8010_H + +#if !SUB_PLATFORM_T8010 +#error "Only include for t8010 platform" +#endif + +/* t8010 specific gpio -> pin mappings - Cayman I/O Spreadsheet v2.05 */ + +/* Boot configuration pins */ +#define GPIO_BOOT_CONFIG0 GPIO(167) +#define GPIO_BOOT_CONFIG1 GPIO(204) +#define GPIO_BOOT_CONFIG2 GPIO(207) + +/* Boot configuration pin encodings */ +#define BOOT_CONFIG_SPI0 (0) +#define BOOT_CONFIG_SPI0_TEST (1) +#define BOOT_CONFIG_NVME0_X2 (2) +#define BOOT_CONFIG_NVME0_X2_TEST (3) +#define BOOT_CONFIG_NVME0_X1 (4) +#define BOOT_CONFIG_NVME0_X1_TEST (5) +#define BOOT_CONFIG_SLOW_SPI0_TEST (6) +#define BOOT_CONFIG_FAST_SPI0_TEST (7) + +#define GPIO_REQUEST_DFU1 GPIO(179) // Formerly HOLD_KEY +#define GPIO_REQUEST_DFU2 GPIO(180) // Formerly MENU_KEY +#define GPIO_FORCE_DFU GPIO(205) // FORCE_DFU +#define GPIO_DFU_STATUS GPIO(206) // DFU_STATUS + +#define SPI_NOR0 (0) + +#define GPIO_SPI0_SCLK GPIO(184) +#define GPIO_SPI0_MOSI GPIO(185) +#define GPIO_SPI0_MISO GPIO(186) +#define GPIO_SPI0_SSIN GPIO(187) + +#if SUPPORT_FPGA +#define GPIO_SPI0_CS GPIO(GPIO_PAD_SPI, 0) +#else +#define GPIO_SPI0_CS GPIO(187) // Alias of GPIO_SPI0_SSIN +#endif + +#define GPIO_IIC0_SCL GPIO(197) +#define GPIO_IIC0_SDA GPIO(196) +#define GPIO_IIC1_SCL GPIO(40) +#define GPIO_IIC1_SDA GPIO(39) +#define GPIO_IIC2_SCL GPIO(133) +#define GPIO_IIC2_SDA GPIO(132) +#define GPIO_IIC3_SCL GPIO(42) +#define GPIO_IIC3_SDA GPIO(41) + +#define GPIO_PCIE0_PERST GPIO(12) +#define GPIO_PCIE1_PERST GPIO(13) +#define GPIO_PCIE2_PERST GPIO(14) +#define GPIO_PCIE3_PERST GPIO(15) +#define GPIO_PCIE0_CLKREQ GPIO(16) +#define GPIO_PCIE1_CLKREQ GPIO(17) +#define GPIO_PCIE2_CLKREQ GPIO(18) +#define GPIO_PCIE3_CLKREQ GPIO(19) + +#define GPIO_NAND_SYS_CLK GPIO(10) + +#endif /* ! __PLATFORM_GPIODEF_t8010_H */ diff --git a/platform/t8010/include/platform/image_devices.h b/platform/t8010/include/platform/image_devices.h new file mode 100644 index 0000000..6cad8c9 --- /dev/null +++ b/platform/t8010/include/platform/image_devices.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_IMAGE_DEVICES_H +#define __PLATFORM_IMAGE_DEVICES_H + +static const struct image_device platform_image_devices[] = { +#if defined(WITH_HW_ASP) + { "asp_fw", 0x00000 }, +#elif defined(WITH_ANC_FIRMWARE) + { "anc_firmware", 0x00000 }, +#endif +#if defined(WITH_NVME) + { "nvme_firmware0", 0x0000 }, +#endif +#if !defined(WITH_HW_ASP) && !defined(WITH_ANC_FIRMWARE) && !defined(WITH_NVME) + { "nor0", 0x00000 }, +#endif +}; + +#if WITH_SYSCFG +static const struct image_device platform_syscfg_devices[] = { +#if defined(WITH_NAND_BOOT) + { "nand_syscfg", 0x00000 }, +#endif +#if defined(WITH_NVME) + { "nvme_syscfg0", 0x0000 }, +#endif +#if !defined(WITH_NAND_BOOT) && !defined(WITH_NVME) + { "nor0", 0x00000 }, +#endif +}; +#endif /* WITH_SYSCFG */ + +#endif /* ! __PLATFORM_IMAGE_DEVICES_H */ diff --git a/platform/t8010/include/platform/memconfig.h b/platform/t8010/include/platform/memconfig.h new file mode 100644 index 0000000..3eeace1 --- /dev/null +++ b/platform/t8010/include/platform/memconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMCONFIG_H +#define __PLATFORM_MEMCONFIG_H + +/* T8010 SoC Mem Pin Configuration */ + +static const gpio_t memory_interface_gpios[] = { + /* Not needed */ +}; +#endif /* ! __PLATFORM_MEMCONFIG_H */ diff --git a/platform/t8010/include/platform/memmap.h b/platform/t8010/include/platform/memmap.h new file mode 100644 index 0000000..6c95981 --- /dev/null +++ b/platform/t8010/include/platform/memmap.h @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_MEMMAP_H +#define __PLATFORM_MEMMAP_H + +// Remove memory map hack in s8000's memmap.h +//#include +#define DEFAULT_LOAD_ADDRESS (INSECURE_MEMORY_BASE) +#define DEFAULT_LOAD_SIZE (0x08000000ULL) // 128 MB instead of 64 MB in memmap_defaults.h +#define DEFAULT_KERNEL_ADDRESS (DEFAULT_LOAD_ADDRESS + DEFAULT_LOAD_SIZE) +#define DEFAULT_KERNEL_SIZE (0x03F00000ULL) +#define DEFAULT_DEVICETREE_ADDRESS (DEFAULT_KERNEL_ADDRESS + DEFAULT_KERNEL_SIZE) +#define DEFAULT_DEVICETREE_SIZE (0x00100000ULL) +#define DEFAULT_RAMDISK_ADDRESS (DEFAULT_DEVICETREE_ADDRESS + DEFAULT_DEVICETREE_SIZE) +#define DEFAULT_RAMDISK_SIZE (0x04000000ULL) +#define DEFAULT_FREE_ADDRESS (DEFAULT_RAMDISK_ADDRESS + DEFAULT_RAMDISK_SIZE) + +/* T8010 specific memory map */ + +/////////////////////////////////////////////////////////////////////////////////// +// 0x800000000 + dram_size ------------------------------- +// | NVMe (12MiB) | +// | | +// |-----------------------------| +// | Consistent Debug (16KiB) | +// |-----------------------------| +// | Sleep Token Buffer (16KiB) | +// |-----------------------------| +// | DRAM Config Sequence (16KiB)| +// |-----------------------------| +// | Panic (512KiB) | +// |-----------------------------| +// | Display | +// | (Framebuffer + scratch) | +// | | +// | | +// |-----------------------------| +// | | +// | iBoot (Heap) | +// | (Variable size depending | +// (Cayman) | on DISPLAY_SIZE) | +// 0x870180000 --> |-----------------------------| +// | iBoot (Trampoline) | +// (Cayman) | (BOOT_TRAMPOLINE_SIZE) | +// 0x87017C000 --> |-----------------------------| +// | iBoot (Stacks) | +// (Cayman) | (STACKS_SIZE) | +// 0x870178000 --> |-----------------------------| +// | iBoot (Page Tables) | +// (Cayman) | (PAGE_TABLES_SIZE) | +// 0x870100000 --> |-----------------------------| +// | iBoot (Text + Data) | +// (Cayman) | (TEXT_FOOTPRINT) | +// 0x870000000 --> |-----------------------------| <-- 0x800000000 + dram_size - 256MB +// | | +// | Unused | +// | | +// |-----------------------------| +// | | +// | (Ramdisk) | +// | (Kernel + DeviceTree) | +// | Secure memory | +// | | +// |-----------------------------| +// | | +// | Load region / | +// | Insecure Memory | +// | (overlaps with TZ0) | |-----------------------------| +// | | | TZ0 (varies) | +// 0x800000000 --> ------------------------------- ------------------------------- +/////////////////////////////////////////////////////////////////////////////////// + +#define SDRAM_BASE (0x800000000ULL) +#define SDRAM_BANK_LEN (SDRAM_LEN) +#define SDRAM_BANK_COUNT (1) +#define SDRAM_END (SDRAM_BASE + SDRAM_LEN) + +#define VROM_BASE (0x100000000ULL) +#define VROM_BANK_LEN (0x002000000ULL) +#define VROM_RSVD (0x00080000ULL) // 512 KiB reserved for SecureROM testing +#define SRAM_BASE (0x180000000ULL) +#define SRAM_LEN (0x000200000ULL) // 2 MiB +#define SRAM_BANK_LEN (SRAM_LEN) // SRAM should be in a 32 MB decode region +#define SRAM_BANK_COUNT (1) +#define SRAM_END (SRAM_BASE + SRAM_LEN) + +#define IO_BASE (0x200000000ULL) +#define IO_SIZE (0x020000000ULL) + +#define PCI_REG_BASE (0x600000000ULL) +#define PCI_REG_LEN (0x00C000000ULL) +#define PCI_CONFIG_BASE (0x610000000ULL) +#define PCI_CONFIG_LEN (0x10000000ULL) +#define PCI_32BIT_BASE (0x7C0000000ULL) +#define PCI_32BIT_LEN (0x002000000ULL) // 32 MiB fits nicely into a 32 MiB L2 MMU block + +#define SECUREROM_LOAD_ADDRESS (VROM_BASE) + +/* reserved for ASP/NVMe */ +// NOTE ASP_SIZE is now defined by the platform or target makefile. +#define ASP_BASE (SDRAM_END - ASP_SIZE) + +#define CONSISTENT_DEBUG_SIZE (0x00004000ULL) +#define CONSISTENT_DEBUG_BASE (ASP_BASE - CONSISTENT_DEBUG_SIZE) + +/* reserved area for sleep token info */ +#define SLEEP_TOKEN_BUFFER_SIZE (0x00004000ULL) +#define SLEEP_TOKEN_BUFFER_BASE (CONSISTENT_DEBUG_BASE - SLEEP_TOKEN_BUFFER_SIZE) + +/* reserved area for config sequence region */ +#define DRAM_CONFIG_SEQ_SIZE (0x00004000ULL) +#define DRAM_CONFIG_SEQ_BASE (SLEEP_TOKEN_BUFFER_BASE - DRAM_CONFIG_SEQ_SIZE) + +/* reserved area for panic info */ +#define PANIC_SIZE (0x00080000ULL) +#define PANIC_BASE (DRAM_CONFIG_SEQ_BASE - PANIC_SIZE) + +/* reserved area for display */ +// DISPLAY_SIZE comes from platform's rules.mk +#define DISPLAY_BASE (PANIC_BASE - DISPLAY_SIZE) + +// Reserved for TZ0/SEP +// TZ0_SIZE is defined by the platform or target makefile +#define TZ0_BASE (SDRAM_BASE) + +/* where to stick heap and insecure memory */ +#if APPLICATION_SECUREROM + +// SecureROM SRAM memory map +// +// ROM Testing 0x000000 - 0x07FFFF ( 512 KiB) +// Data 0x080000 - 0x09FFFF ( 128 KiB) +// Page Tables 0x0A0000 - 0x0A7FFF ( 32 KiB) +// Stacks 0x0A8000 - 0x0ABFFF ( 16 KiB) +// Boot Trampoline 0x0AC000 - 0x0AFFFF ( 16 KiB) +// DFU Region 0x0B0000 - 0x1AFFFF (1024 KiB) +// Heap 0x1B0000 - 0x1FFFFF ( 320 KiB) + +// DATA_BASE comes from platform/t8010/rules.mk +#define DATA_SIZE (0x00020000ULL) + +#define PAGE_TABLES_BASE (DATA_BASE + DATA_SIZE) +#define PAGE_TABLES_SIZE (0x00008000ULL) + +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (0x00004000ULL) + +#define BOOT_TRAMPOLINE_BASE (STACKS_BASE + STACKS_SIZE) +#define BOOT_TRAMPOLINE_SIZE (0x00004000ULL) + +#define INSECURE_MEMORY_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define INSECURE_MEMORY_SIZE (0x00100000ULL) + +#define HEAP_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define HEAP_END (SRAM_END) +#define HEAP_SIZE (HEAP_END - HEAP_BASE) +#define HEAP_GUARD (HEAP_END) + +#endif /* APPLICATION_SECUREROM */ + +#if APPLICATION_IBOOT + +#if WITH_DFU_MODE + +// iBSS/LLB SRAM memory map +// +// ROM Testing 0x000000 - 0x07FFFF ( 512 KiB) +// Page Tables 0x080000 - 0x097FFF ( 96 KiB) +// Stacks 0x098000 - 0x09BFFF ( 16 KiB) +// 0x09C000 - 0x0AFFFF ( 96 KiB) +// Code/Data 0x0B0000 - 0x1AFFFF (1024 KiB) +// Boot Trampoline 0x1B0000 - 0x1B3FFF ( 16 KiB) +// Heap 0x1B4000 - 0x1FFFFF ( 304 KiB) + +#define PAGE_TABLES_BASE (SRAM_BASE + VROM_RSVD) +#define PAGE_TABLES_SIZE (0x0018000ULL) + +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) + +#define CODE_DATA_END (TEXT_BASE + TEXT_FOOTPRINT) + +#define BOOT_TRAMPOLINE_BASE (CODE_DATA_END) +#define BOOT_TRAMPOLINE_SIZE (PAGE_SIZE) + +#define HEAP_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define HEAP_END (SRAM_END) +#define HEAP_SIZE (HEAP_END - HEAP_BASE) +#define HEAP_GUARD (HEAP_END) + +// Reserved area for iBoot +#define IBOOT_BASE (SDRAM_END - SDRAM_LOAD_OFFSET) +#define IBOOT_SIZE (0x01400000ULL) + +#define INSECURE_MEMORY_BASE (IBOOT_BASE) +#define INSECURE_MEMORY_SIZE (IBOOT_SIZE) + +#else /* !WITH_DFU_MODE */ + +// iBoot/iBEC SDRAM memory map + +// SDRAM memory map will usually look like the following for T8010: +// +// iBoot Text 0x870000000 - 0x8700FFFFF ( 1 MiB) +// Page Tables 0x870100000 - 0x870177FFF (480 KiB) +// Stacks 0x870178000 - 0x87017BFFF ( 16 KiB) +// Boot trampoline 0x87017C000 - 0x87017FFFF ( 16 KiB) +// Heap 0x870180000 - (DISPLAY_BASE - 1 page) +// Guard (DISPLAY_BASE - 1 page) - DISPLAY_BASE + +/* reserved area for iBoot */ +#define IBOOT_BASE (TEXT_BASE) +#define IBOOT_SIZE (HEAP_END - IBOOT_BASE) + +#define CODE_DATA_END (IBOOT_BASE + IBOOT_SIZE) + +#if (IBOOT_BASE != (SDRAM_END - SDRAM_LOAD_OFFSET)) +#error "Memory map configuration error" +#endif + +#define PAGE_TABLES_BASE (IBOOT_BASE + TEXT_FOOTPRINT) +#define PAGE_TABLES_SIZE (0x00078000ULL) +#define STACKS_BASE (PAGE_TABLES_BASE + PAGE_TABLES_SIZE) +#define STACKS_SIZE (EXCEPTION_STACK_SIZE + BOOTSTRAP_STACK_SIZE + INTERRUPT_STACK_SIZE) +#define BOOT_TRAMPOLINE_BASE (STACKS_BASE + STACKS_SIZE) +#define BOOT_TRAMPOLINE_SIZE (PAGE_SIZE) + +#define HEAP_BASE (BOOT_TRAMPOLINE_BASE + BOOT_TRAMPOLINE_SIZE) +#define HEAP_SIZE (DISPLAY_BASE - HEAP_BASE - PAGE_SIZE) +#define HEAP_END (HEAP_BASE + HEAP_SIZE) +#define HEAP_GUARD (HEAP_END) +#if (HEAP_GUARD != (DISPLAY_BASE - PAGE_SIZE)) +#error "Memory map configuration error" +#endif + +#define INSECURE_MEMORY_BASE (SDRAM_BASE) +#define INSECURE_MEMORY_SIZE (DEFAULT_LOAD_SIZE) + +#define SECURE_MEMORY_BASE (INSECURE_MEMORY_BASE + INSECURE_MEMORY_SIZE) +#define SECURE_MEMORY_SIZE (DEFAULT_FREE_ADDRESS - SECURE_MEMORY_BASE) + +/* unused area */ +#define UNUSED_MEMORY_BASE (SECURE_MEMORY_BASE + SECURE_MEMORY_SIZE) +#define UNUSED_MEMORY_SIZE (IBOOT_BASE - UNUSED_MEMORY_BASE) + +#endif /* !WITH_DFU_MODE */ + +#endif /* APPLICATION_IBOOT */ + +#endif /* ! __PLATFORM_MEMMAP_H */ diff --git a/platform/t8010/include/platform/pcimap.h b/platform/t8010/include/platform/pcimap.h new file mode 100644 index 0000000..2be3a7e --- /dev/null +++ b/platform/t8010/include/platform/pcimap.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_PCIMAP_H +#define __PLATFORM_PCIMAP_H + +/* T8010 specific bus/device/function and PCI base address map */ + +#include + +#define PCIE_PORT0_MEMORY_BASE (PCIE_MEMORY_BASE_ADDR) +#define PCIE_PORT0_MEMORY_LEN (0x00100000ULL) + +#define NVME0_PCI_BDF (PCI_BDF(1, 0, 0)) +#define NVME0_BASE_ADDR (PCIE_PORT0_MEMORY_BASE) +#define NVME0_SIZE (0x00002000) +#define NVME0_DART_ID (PCIE_PORT0_DART_ID) + + +#endif /* ! __PLATFORM_PCIMAP_H */ diff --git a/platform/t8010/include/platform/pinconfig.h b/platform/t8010/include/platform/pinconfig.h new file mode 100644 index 0000000..cded206 --- /dev/null +++ b/platform/t8010/include/platform/pinconfig.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include SUB_PLATFORM_HEADER(pinconfig) + diff --git a/platform/t8010/include/platform/pinconfig_t8010.h b/platform/t8010/include/platform/pinconfig_t8010.h new file mode 100644 index 0000000..489d3ad --- /dev/null +++ b/platform/t8010/include/platform/pinconfig_t8010.h @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: cayman io list. ver 3.13 + I/O Spreadsheet tracker: H9: Update SecureROM pin configuration to I/O spreadsheet v3.13 + Conversion command: csvtopinconfig.py --rom --header --soc h9p --pupd-column 'Default pull-up/pull-down' --netname-column D1x_Net --copyright 2015 --radar ' H9: Update SecureROM pin configuration to I/O spreadsheet v3.13' +*/ + +#ifndef __PLATFORM_PINCONFIG_H +#define __PLATFORM_PINCONFIG_H + +static const uint32_t gpio_default_cfg_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 0 : I2S0_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 1 : I2S0_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 2 : I2S0_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 3 : I2S0_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 4 : I2S0_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 5 : I2S2_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 6 : I2S2_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 7 : I2S2_LRCK -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 8 : I2S2_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 9 : I2S2_DOUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 10 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 11 : S3E_RESETN -> AP_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 12 : PCIE_PERST0_N -> PCIE_AP_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 13 : PCIE_PERST1_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 14 : PCIE_PERST2_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 15 : PCIE_PERST3_N -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 16 : PCIE_CLKREQ0_N -> PCIE_NAND_BI_AP_CLKREQ_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 17 : PCIE_CLKREQ1_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 18 : PCIE_CLKREQ2_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 19 : PCIE_CLKREQ3_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 20 : GPIO[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : GPIO[1] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : GPIO[2] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 23 : GPIO[3] -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 24 : GPIO[4] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 25 : GPIO[5] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 26 : GPIO[6] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 27 : GPIO[7] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 28 : GPIO[8] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 29 : GPIO[9] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 30 : GPIO[10] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 31 : GPIO[11] -> + +/* Port 4 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 32 : CLK32K_OUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 33 : DWI_DO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 34 : DWI_CLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 35 : PMU_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 36 : PMU_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 37 : PMU_SCLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 38 : GPIO[12] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 39 : I2C1_SDA -> + +/* Port 5 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 40 : I2C1_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 41 : I2C3_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 42 : I2C3_SCL -> + CFG_DISABLED, // 43 : SENSOR2_RST -> + CFG_DISABLED, // 44 : SENSOR3_RST -> + CFG_DISABLED, // 45 : SENSOR4_RST -> + CFG_DISABLED, // 46 : SENSOR_INT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 47 : ISP_I2C3_SDA -> + +/* Port 6 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 48 : ISP_I2C3_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 49 : ISP_I2C2_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 50 : ISP_I2C2_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 51 : ISP_I2C1_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 52 : ISP_I2C1_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 53 : ISP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 54 : ISP_I2C0_SCL -> + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 64 : SENSOR0_ISTRB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 65 : SENSOR0_RST -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 66 : SENSOR0_CLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 67 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 68 : SENSOR1_ISTRB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 69 : SENSOR1_RST -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 70 : SENSOR1_CLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 71 : SENSOR1_XSHUTDOWN -> + +/* Port 9 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 72 : SENSOR2_CLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 73 : I2S1_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 74 : I2S1_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 75 : I2S1_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 76 : I2S1_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 77 : I2S1_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 78 : SPI2_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 79 : SPI2_MOSI -> + +/* Port 10 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 80 : SPI2_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 81 : SPI2_SSIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 82 : SPI3_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 83 : SPI3_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 84 : SPI3_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 85 : SPI3_SSIN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 86 : GPIO[31] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 87 : GPIO[32] -> + +/* Port 11 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 88 : GPIO[33] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 89 : GPIO[34] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 90 : GPIO[35] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 91 : GPIO[36] -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 96 : UART1_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 97 : UART1_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 98 : UART1_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 99 : UART1_CTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 100 : UART4_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 101 : UART4_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 102 : UART4_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 103 : UART4_CTSN -> + +/* Port 13 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 14 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 15 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 128 : SPI1_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 129 : SPI1_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 130 : SPI1_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 131 : SPI1_SSIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 132 : I2C2_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 133 : I2C2_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 134 : UART3_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 135 : UART3_RXD -> + +/* Port 17 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 136 : UART3_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 137 : UART3_CTSN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 139 : GPIO[30] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 140 : GPIO[13] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 141 : GPIO[14] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 142 : GPIO[15] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 143 : DROOP -> + +/* Port 18 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 144 : SOCHOT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 145 : TMR32_PWM0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 146 : TMR32_PWM1 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 147 : TMR32_PWM2 -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 148 : UART2_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 149 : UART2_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 150 : UART2_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 151 : UART2_CTSN -> + +/* Port 19 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 152 : UART7_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 153 : UART7_RXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 154 : DP_WAKEUP -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 160 : GPIO[37] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 161 : GPIO[38] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 162 : GPIO[39] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 163 : GPIO[40] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 164 : GPIO[41] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 165 : GPIO[16] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 166 : GPIO[17] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 167 : GPIO[18] -> BOOT_CONFIG0 + +/* Port 21 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 168 : GPIO[19] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 169 : GPIO[20] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 170 : GPIO[21] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 171 : GPIO[22] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 172 : GPIO[23] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 173 : UART5_RTXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 174 : TST_CLKOUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 175 : EDP_HPD -> + +/* Port 22 */ + CFG_DISABLED, // 176 : DISP_TOUCH_BSYNC0 -> + CFG_DISABLED, // 177 : DISP_TOUCH_BSYNC1 -> + CFG_DISABLED, // 178 : DISP_TOUCH_EB -> + CFG_IN, // 179 : REQUEST_DFU1 -> PMU_TO_AP_BUF_BUTTON1 + CFG_IN, // 180 : REQUEST_DFU2 -> PMU_TO_AP_BUF_BUTTON2 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 181 : SWD_TMS2 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 182 : SWD_TMS3 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 183 : GPU_TRIGGER -> + +/* Port 23 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 184 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 185 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 186 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 187 : SPI0_SSIN -> BOARD_ID3 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 192 : UART0_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 193 : UART0_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 194 : UART6_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 195 : UART6_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 196 : I2C0_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 197 : I2C0_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 198 : I2S3_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 199 : I2S3_BCLK -> + +/* Port 25 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 200 : I2S3_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 201 : I2S3_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 202 : I2S3_DIN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 203 : GPIO[24] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 204 : GPIO[25] -> BOOT_CONFIG1 + CFG_IN | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 205 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 206 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 207 : GPIO[28] -> BOOT_CONFIG2 +}; + +static const uint32_t gpio_default_cfg_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 2 : AOP_SPI_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 3 : AOP_UART0_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 4 : AOP_UART0_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 5 : AOP_UART1_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 6 : AOP_UART1_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 8 : AOP_UART2_RXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 9 : AOP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 10 : AOP_I2C0_SCL -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 11 : AOP_FUNC[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 12 : AOP_FUNC[1] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 13 : AOP_FUNC[2] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 14 : AOP_FUNC[3] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 16 : AOP_FUNC[5] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 17 : AOP_FUNC[6] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 18 : AOP_FUNC[7] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 19 : AOP_FUNC[8] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 20 : AOP_FUNC[9] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : AOP_FUNC[10] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : AOP_FUNC[11] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 23 : AOP_FUNC[12] -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 24 : AOP_FUNC[13] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 25 : AOP_FUNC[14] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 26 : AOP_FUNC[15] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 27 : AOP_SWD_TCK_OUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 28 : AOP_SWD_TMS0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 29 : AOP_SWD_TMS1 -> + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 32 : AOP_I2S_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 33 : AOP_I2S_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 34 : AOP_I2S_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 35 : AOP_I2S_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 36 : AOP_I2S_MCK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 37 : DOCK_CONNECT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 38 : DOCK_ATTENTION -> + CFG_DISABLED, // 39 : AOP_PDM_CLK0 -> + +/* Port 5 */ + CFG_DISABLED, // 40 : AOP_PDM_DATA0 -> + CFG_DISABLED, // 41 : AOP_PDM_DATA1 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : XI0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 65 : XO0 -> + CFG_DISABLED, // 66 : ANALOGMUX_OUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 67 : CFSB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 68 : HOLD_RESET -> + CFG_DISABLED, // 69 : TESTMODE -> + CFG_DISABLED, // 70 : PACKAGED_N -> + CFG_DISABLED, // 71 : CFSB_AOP -> + +/* Port 9 */ + CFG_DISABLED, // 72 : COLD_RESETN -> + CFG_DISABLED, // 73 : JTAG_TRSTN -> + CFG_DISABLED, // 74 : JTAG_SEL -> + CFG_DISABLED, // 75 : JTAG_TMS -> + CFG_DISABLED, // 76 : JTAG_TDI -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 77 : JTAG_TDO -> + CFG_DISABLED, // 78 : JTAG_TCK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 79 : AOP_DDR_REQ -> + +/* Port 10 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 80 : AOP_DDR_RESETN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 81 : AWAKE_REQ -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 82 : AWAKE_RESETN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 83 : WDOG -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 84 : RT_CLK32768 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + + +#endif /* __PLATFORM_PINCONFIG_H */ diff --git a/platform/t8010/include/platform/soc/aop_config_sequences.h b/platform/t8010/include/platform/soc/aop_config_sequences.h new file mode 100644 index 0000000..793113b --- /dev/null +++ b/platform/t8010/include/platform/soc/aop_config_sequences.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __AOP_CONFIG_SEQUENCES_H__ +#define __AOP_CONFIG_SEQUENCES_H__ + +// These structures are valid reconfig commands. They are stitched together in +// the platform init.c. For example look at the platform_s2r_aop_to_aop_ddr_post_sequence_insert() +// to figure out how the reconfig sequences are stitched together for the transition +// from s2r_aop to aop_ddr postamble + +uint32_t s2r_aop_to_aop_ddr_post[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +uint32_t s2r_aop_to_aop_ddr_post_2[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +uint32_t s2r_aop_to_aop_ddr_post_3[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->S2R_AOP PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +uint32_t aop_ddr_to_s2r_aop_pre[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +uint32_t awake_to_aop_ddr_pre[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AWAKE->AOP_DDR POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.4 (Software Teardown for Awake Exit), either */ +/* Comment: // ** SW or the config engine may turn off SIO/PCIE. For DV simulations, we chose to power */ +/* Comment: // ** power down ALL of the unneeded blocks in the config engine rather than from the AP. This */ +/* Comment: // ** provided functionally equivalent behavior and allowed the AWAKE->AOP_DDR and */ +/* Comment: // ** S2R_AOP->AOP_DDR to appear symmetric. SiVal/SW may move parts of this sequence */ +/* Comment: // ** to AP software if desired. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +uint32_t awake_to_aop_ddr_post[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE PREAMBLE */ +/* Comment: // ****************************************************************************************** */ +uint32_t aop_ddr_to_awake_pre[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +/* Comment: // ****************************************************************************************** */ +/* Comment: // ** AOP_DDR->AWAKE POSTAMBLE */ +/* Comment: // ** */ +/* Comment: // ** Note: */ +/* Comment: // ** According to the PMGR spec section 11.14.3 (Software Init for AOP_DDR to AWAKE), the */ +/* Comment: // ** config engine restores the state of the chip in this step. The specific use cases where */ +/* Comment: // ** the config engine is the owner of state restoration are not yet defined. */ +/* Comment: // ** */ +/* Comment: // ** The sequence below contains the minimum set of commands to re-boot the AP and restore */ +/* Comment: // ** DRAM operation at bucket 1. AP may bring DRAM up to bucket 0. */ +/* Comment: // ** */ +/* Comment: // ** It is assumed that SW will add extensively to this sequence for state restoration based */ +/* Comment: // ** on future use cases. */ +/* Comment: // ** */ +/* Comment: // ****************************************************************************************** */ +uint32_t aop_ddr_to_awake_post[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +uint32_t aop_ddr_to_awake_post_2[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +uint32_t mcu_aop_ddr_reconfig[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +uint32_t mcu_aop_awake_reconfig_pre_restore[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +// Calibrated values will be added to this sequence, thus needs to be aligned. +// The order of registers in this sequence impacts dcs_save_calibration_results and dcs_restore_calibration_results +uint32_t mcu_aop_awake_reconfig_restore[]__aligned(32) = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +uint32_t mcu_aop_awake_reconfig_post_restore[] = { + /* Comment: !!!FIXME!!! */ + 0x00000000, /*Cfg End */ + 0x00000000 /* END COMMAND */ +}; + +#endif // __AOP_CONFIG_SEQUENCES_H__ diff --git a/platform/t8010/include/platform/soc/ccc.h b/platform/t8010/include/platform/soc/ccc.h new file mode 100644 index 0000000..85e064b --- /dev/null +++ b/platform/t8010/include/platform/soc/ccc.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __PLATFORM_SOC_CCC_H +#define __PLATFORM_SOC_CCC_H + +#include +#include SUB_PLATFORM_SPDS_HEADER(acc) + +// CPU0 Regsiters +#define rCCC_CPU0_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_IO_RVBAR_OFFSET)) +#define rCCC_CPU0_IMPL_MMU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_MMU_ERR_STS_OFFSET)) +#define rCCC_CPU0_IMPL_MIGSTS_EL1 (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_MIGSTS_EL1_OFFSET)) + +// CPU0 Hurricane Regsiters +#define rCCC_CPU0_IMPL_FED_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_FED_ERR_STS_OFFSET)) +#define rCCC_CPU0_IMPL_LSU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_LSU_ERR_STS_OFFSET)) + +// CPU0 Zephyr Regsiters +#define rCCC_CPU0_IMPL_E_FED_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_E_FED_ERR_STS_OFFSET)) +#define rCCC_CPU0_IMPL_E_LSU_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_E_LSU_ERR_STS_OFFSET)) + +// CPU1 Registers +#define rCCC_CPU1_IMPL_IORVBAR (*(volatile u_int64_t *)(CCC_CPU1_SYS_BASE_ADDR + ACC_CPU0_IMPL_IO_RVBAR_OFFSET)) + +// Registers shared between all CPUs +#define rCCC_CCC_IMPL_L2C_ERR_STS (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_IMPL_L2C_ERR_STS_OFFSET)) +#define rCCC_CCC_IMPL_L2C_ERR_ADR (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_IMPL_L2C_ERR_ADR_OFFSET)) +#define rCCC_CCC_IMPL_L2C_ERR_INF (*(volatile u_int64_t *)(CCC_CPU0_SYS_BASE_ADDR + ACC_IMPL_L2C_ERR_INF_OFFSET)) + +#endif /* __PLATFORM_SOC_CCC_H */ diff --git a/platform/t8010/include/platform/soc/chipid.h b/platform/t8010/include/platform/soc/chipid.h new file mode 100644 index 0000000..0ed538a --- /dev/null +++ b/platform/t8010/include/platform/soc/chipid.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_CHIPID_H +#define __PLATFORM_SOC_CHIPID_H + +#include +#include +#include +#include + +#define rCFG_FUSE0 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_OFFSET)) +#define rCFG_FUSE1 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE1_OFFSET)) +#define rCFG_FUSE2 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE2_OFFSET)) +#define rCFG_FUSE3 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE3_OFFSET)) +#define rCFG_FUSE4 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE4_OFFSET)) +#define rCFG_FUSE5 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE5_OFFSET)) +#define rCFG_FUSE9 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE9_OFFSET)) + +#define rECIDLO (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE0_OFFSET)) +#define rECIDHI (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE1_OFFSET)) + +#define rSEP_SECURITY (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_SEP_SECURITY_OFFSET)) + +#define rCFG_FUSE0_RAW (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_CFG_FUSE0_RAW_OFFSET)) + + enum chipid_voltage_index { + CHIPID_CPU_VOLTAGE_BYPASS, + CHIPID_CPU_VOLTAGE_SECUREROM, + CHIPID_CPU_VOLTAGE_396, + + CHIPID_GPU_VOLTAGE_OFF, + + CHIPID_ALL_VOLTAGE_LAST, +}; + +enum chipid_voltage_type { + CHIPID_CPU_VOLTAGE, + CHIPID_GPU_VOLTAGE, +}; + +struct chipid_vol_adj { + uint64_t volAdj0:20; + uint64_t volAdj1:20; + uint64_t volAdj2:20; + uint64_t volAdj3:20; + uint64_t dvfmMaxAdj:20; + uint64_t dvmrAdj0:20; + uint64_t dvmrAdj1:20; + uint64_t dvmrAdj2:20; +}; + +#define CHIPID_SOC_VOLTAGE_BYPASS (0) +#define CHIPID_SOC_VOLTAGE_SECUREROM (1) +#define CHIPID_SOC_VOLTAGE_VMIN (2) +#define CHIPID_SOC_VOLTAGE_VNOM (3) + +extern const struct chipid_vol_adj *chipid_get_vol_adj(enum chipid_voltage_index voltage_index); + +uint32_t chipid_get_cpu_voltage(uint32_t index); + +uint32_t chipid_get_cpu_sram_voltage(uint32_t index); + +uint32_t chipid_get_soc_voltage(uint32_t index); + +uint32_t chipid_get_gpu_voltage(uint32_t index); + +uint32_t chipid_get_gpu_sram_voltage(uint32_t index); + +uint32_t chipid_get_sram_voltage(uint32_t index); + +int32_t chipid_get_cpu_temp_offset(uint32_t cpu_number); + +uint32_t chipid_get_soc_temp_sensor_trim(uint32_t sensor_index); + +uint32_t chipid_get_fuse_revision(void); + +uint32_t chipid_get_total_rails_leakage(); + +uint32_t chipid_get_lpo_trim(void); + +uint32_t chipid_get_pcie_refpll_fcal_vco_digctrl(void); + +#if SUPPORT_FPGA + +#define FPGA_HAS_ALWAYS (1 << 31) +#define FPGA_HAS_MEDIA (1 << 0) +#define FPGA_HAS_MSR (1 << 1) +#define FPGA_HAS_JPEG (1 << 2) +#define FPGA_HAS_AVE (1 << 3) +#define FPGA_HAS_VXD (1 << 4) +#define FPGA_HAS_ISP (1 << 5) +#define FPGA_HAS_RTBUSMUX (1 << 6) +#define FPGA_HAS_DISP (1 << 7) +#define FPGA_HAS_GFX (1 << 8) + +#define rECID_FUSE3 (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_FUSE_ECID_FUSE3_OFFSET)) + +uint32_t chipid_get_fpga_block_instantiation(void); + +#endif // SUPPORT_FPGA + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/t8010/include/platform/soc/display.h b/platform/t8010/include/platform/soc/display.h new file mode 100644 index 0000000..2021da5 --- /dev/null +++ b/platform/t8010/include/platform/soc/display.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_H +#define __APPLE_DISPLAY_H + +// Platform-specific displaypipe tunables + +// XXX - disp_dpcafclkgate is listed as TBD +// D620 is most likely something new based on the values. Update once we know more. + +static struct adfe_v2_tuneable adfe_tuneables[] = +{ +#if DISPLAY_IPHONE_TUNABLES +#if DISPLAY_D620_TUNABLES + { + .name = "D620", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x709), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0xffff) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x6ff), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x6f7), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x5f6), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x5ee), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0xe1) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_D620_TUNABLES + +#if DISPLAY_D520_TUNABLES + { + .name = "D520", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_PIPE_ENABLE | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x3db), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x7a7) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x3d1), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x3c9), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x2ff), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x2f7), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x6b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#endif //DISPLAY_D520_TUNABLES +#endif //DISPLAY_IPHONE_TUNABLES + +//Tunables for targets using the the timing based on landscape ipads +#if DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES + { + .name = "default", + .disp_dpcclkcntl = (ADPCCLKCNTL_FLOOR(0x60) | \ + ADPCCLKCNTL_LB_ENABLE | \ + ADPCCLKCNTL_PIO_GATE_ENABLE | \ + ADPCCLKCNTL_STAT_GATE_ENABLE | \ + ADPCCLKCNTL_EXT_GATE_ENABLE | \ + ADPCCLKCNTL_DYN_GATE_ENABLE), + .disp_dpcclklvl_clock_on_level = ADPCCLKLVL_ONLVL(0x547), + .disp_dpcclklvl_clock_off_level = ADPCCLKLVL_OFFLVL(0x7f8), + .disp_dpcqoscfg = (ADPCQOSCFG_QOS_TIMER(0x3a2c) | \ + ADPCQOSCFG_PIPE_ENABLE | \ + ADPCQOSCFG_QOS_ENABLE), + .disp_dpcqosylvl_yellow_off = ADPCQOSYLVL_YELLOW_OFF(0x545), + .disp_dpcqosylvl_yellow_on = ADPCQOSYLVL_YELLOW_ON(0x53d), + .disp_dpcqosrlvl_red_off = ADPCQOSRLVL_RED_OFF(0x3a1), + .disp_dpcqosrlvl_red_on = ADPCQOSRLVL_RED_ON(0x399), + .disp_dpclinkdown = (ADPCLINKDOWN_TEARDOWNNOSCL | \ + ADPCLINKDOWN_TEARDOWNEN), + .disp_dpgpreqaggr = (ADPGPREQAGGR_REQAGGRTHRESH(0x4b) | \ + ADPGPREQAGGR_CACHEHINT(0x3) | \ + ADPGPREQARRG_OPPORTUNISMENAB | \ + ADPGPREQAGGR_REQAGGRENAB), + .disp_dpcafclkgate = (ADPAFIDLECOUNT(0) | \ + ADPAFDYNCLKGATEEN), + .disp_dpcenab = (ADPCENAB_IDEAL_ARB_ENAB), + }, +#if DISPLAY_IPHONE_TUNABLES +#error DISPLAY_IPHONE_TUNABLES set for IPAD +#endif + +#endif //DISPLAY_LANDSCAPE_IPAD_TUNABLES || DISPLAY_APPLE_TV_TUNABLES || DISPLAY_FPGA_TUNABLES +}; + +#endif /* ! __APPLE_DISPLAY_H */ diff --git a/platform/t8010/include/platform/soc/display_timings.h b/platform/t8010/include/platform/soc/display_timings.h new file mode 100644 index 0000000..9dda693 --- /dev/null +++ b/platform/t8010/include/platform/soc/display_timings.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __APPLE_DISPLAY_TIMINGS_H +#define __APPLE_DISPLAY_TIMINGS_H + +//Supported timings by this platform +static struct display_timing timing_list[] = +{ +#if DEBUG_BUILD || SUB_TARGET_T8010SIM + { + .display_name = "D520", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 100000000, + .dot_pitch = 326, + .h_active = 750, + .h_pulse_width = 32, + .h_back_porch = 4, + .h_front_porch = 102, + .v_active = 1334, + .v_pulse_width = 3, + .v_back_porch = 4, + .v_front_porch = 536, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD + { + .display_name = "D620", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 200000000, + .dot_pitch = 326, + .h_active = 1080, + .h_pulse_width = 32, + .h_back_porch = 4, + .h_front_porch = 116, + .v_active = 1920, + .v_pulse_width = 3, + .v_back_porch = 5, + .v_front_porch = 778, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_PINOT, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || SUB_TARGET_T8010FPGA + { + .display_name = "fpga-wsvga", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 5000000, + .dot_pitch = 243, + .h_active = 1024, + .h_pulse_width = 50, + .h_back_porch = 50, + .h_front_porch = 51, + .v_active = 600, + .v_pulse_width = 50, + .v_back_porch = 218, + .v_front_porch = 6, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 18, + .display_type = DISPLAY_TYPE_DUMB, + .display_config = NULL, + }, +#endif +#if DEBUG_BUILD || WITH_HW_DISPLAY_DISPLAYPORT + { + .display_name = "720p", + .host_clock_id = CLK_VCLK0, + .pixel_clock = 74250000, + .dot_pitch = 243, + .h_active = 1280, + .h_pulse_width = 40, + .h_back_porch = 110, + .h_front_porch = 220, + .v_active = 720, + .v_pulse_width = 5, + .v_back_porch = 5, + .v_front_porch = 20, + .neg_vclk = 0, + .neg_hsync = 0, + .neg_vsync = 0, + .neg_vden = 0, + .display_depth = 24, + .display_type = DISPLAY_TYPE_DP, + .display_config.dp.mode = 0x0, + .display_config.dp.type = 0x1, + .display_config.dp.min_link_rate = 0x6, + .display_config.dp.max_link_rate = 0x6, + .display_config.dp.lanes = 0x2, + .display_config.dp.ssc = 0x0, + .display_config.dp.alpm = 0x0, + .display_config.dp.vrr_enable = 0x0, + .display_config.dp.vrr_on = 0x0, + }, +#endif +}; +#endif /* ! __APPLE_DISPLAY_TIMINGS_H */ diff --git a/platform/t8010/include/platform/soc/dvfmperf.h b/platform/t8010/include/platform/soc/dvfmperf.h new file mode 100644 index 0000000..c1b2f00 --- /dev/null +++ b/platform/t8010/include/platform/soc/dvfmperf.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_DVFMPERF_H +#define __PLATFORM_SOC_DVFMPERF_H +#include + +enum chipid_voltage_index dvfmperf_get_voltage_index(uint32_t index, enum chipid_voltage_type voltage_type); + +#endif /* __PLATFORM_SOC_DVFMPERF_H */ diff --git a/platform/t8010/include/platform/soc/hwclocks.h b/platform/t8010/include/platform/soc/hwclocks.h new file mode 100644 index 0000000..dff498c --- /dev/null +++ b/platform/t8010/include/platform/soc/hwclocks.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWCLOCKS_H +#define __PLATFORM_SOC_HWCLOCKS_H + +#include +#include + +#if SUPPORT_FPGA +#define OSC_FREQ (5000000UL) +#define LPPLL_FREQ (OSC_FREQ) +#else +#define OSC_FREQ (24000000UL) +#define LPPLL_FREQ (192000000UL) +#endif + +#if SUB_PLATFORM_T8010 +/* + * T8010 clock gate devices. + */ +enum { + // Mini-PMGR + CLK_AOP = HWCLOCK_BASE, + CLK_DEBUG, + CLK_AOP_GPIO, + CLK_AOP_UART0, + CLK_AOP_UART1, + CLK_AOP_UART2, + CLK_AOP_I2CM, + CLK_AOP_MCA0, + CLK_AOP_PDM_REF, + CLK_AOP_CPU, + CLK_AOP_FILTER, + CLK_AOP_BUSIF, + CLK_AOP_LPD0, + CLK_AOP_LPD1, + CLK_AOP_HPDS, + CLK_AOP_HPDSC, + CLK_AOP_HPDD, + + // PMGR + CLK_SBR, + CLK_AIC, + CLK_DWI, + CLK_GPIO, + CLK_PMS, + CLK_HSIC0PHY, + CLK_ISPSENS0, + CLK_ISPSENS1, + CLK_ISPSENS2, + CLK_PCIE_REF, + CLK_SOCUVD, + CLK_SIO_BUSIF, + CLK_SIO_P, + CLK_SIO, + CLK_MCA0, + CLK_MCA1, + CLK_MCA2, + CLK_MCA3, + CLK_MCA4, + CLK_PWM0, + CLK_I2C0, + CLK_I2C1, + CLK_I2C2, + CLK_I2C3, + CLK_SPI0, + CLK_SPI1, + CLK_SPI2, + CLK_SPI3, + CLK_UART0, + CLK_UART1, + CLK_UART2, + CLK_UART3, + CLK_UART4, + CLK_UART5, + CLK_UART6, + CLK_UART7, + CLK_UART8, + CLK_AES0, + CLK_HFD0, + CLK_MCC, + CLK_DCS0, + CLK_DCS1, + CLK_DCS2, + CLK_DCS3, + CLK_USB, + CLK_USBCTLREG, + CLK_USB2HOST0, + CLK_USB2HOST0_OHCI, + CLK_USB2HOST1, + CLK_USB_OTG, + CLK_SMX, + CLK_SF, + CLK_RTMUX, + CLK_DISP0_FE, + CLK_DISP0_BE, + CLK_MIPI_DSI, + CLK_MIPI = CLK_MIPI_DSI, + CLK_DP, + CLK_EDPLINK = CLK_DP, + CLK_DPLINK = CLK_DP, + CLK_ISP_SYS, + CLK_MEDIA, + CLK_JPG, + CLK_MSR, + CLK_PMP, + CLK_PMS_SRAM, + CLK_VDEC0, + CLK_VENC, + CLK_PCIE, + CLK_PCIE_AUX, + CLK_GFX, + + // Unmanaged + CLK_CPU0, + CLK_CPU1, + CLK_CPM, + CLK_SEP, + CLK_ISP_RSTS0, + CLK_ISP_RSTS1, + CLK_ISP_VIS, + CLK_ISP_BE, + CLK_ISP_PEARL, + CLK_DPRX, + CLK_VENC_PIPE4, + CLK_VENC_PIPE5, + CLK_VENC_ME0, + CLK_VENC_ME1, + + CLK_LAST, +}; + +#define PMGR_FIRST_DEVICE CLK_AOP +#define PMGR_LAST_DEVICE CLK_GFX + +#else +#error "Unknown Platform" +#endif + +#define PMGR_DEVICE_INDEX(_clk) ((_clk) - HWCLOCK_BASE) +#define PMGR_DEVICE_COUNT (CLK_LAST - HWCLOCK_BASE) + +#define PMGR_VALID_DEVICE(_clk) ((_clk) >= PMGR_FIRST_DEVICE && (_clk) <= PMGR_LAST_DEVICE) + +// Legacy clocks, no associated device or PS register +enum { + CLK_FCLK = CLK_LAST, + CLK_ACLK, + CLK_HCLK, + CLK_PCLK, + CLK_VCLK0, + CLK_VCLK1, + CLK_MCLK, + CLK_NCLK, + CLK_USBPHYCLK, + CLK_NCOREF, +}; + +#endif /* ! __PLATFORM_SOC_HWCLOCKS_H */ diff --git a/platform/t8010/include/platform/soc/hwisr.h b/platform/t8010/include/platform/soc/hwisr.h new file mode 100644 index 0000000..abac82d --- /dev/null +++ b/platform/t8010/include/platform/soc/hwisr.h @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWISR_H +#define __PLATFORM_SOC_HWISR_H + +#if SUB_PLATFORM_T8010 + +#define INT_SW0 0 // Software 0 Interrupt +#define INT_SW1 1 // Software 1 Interrupt +#define INT_SW2 2 // Software 2 Interrupt +#define INT_SW3 3 // Software 3 Interrupt +#define INT_WDT 4 // Watchdog Timer Interrupt +#define INT_DWI1 5 // DWI Interrupt +#define INT_DWI2 6 // DWI Interrupt +#define INT_PMGR_PERF_CNTRS 7 // PMGR Performace Counters Interrupt +#define INT_THERM_TEMP0 8 // Thermal Temp 0 Interrupt +#define INT_THERM_ALARM0 9 // Thermal Alarm 0 Interrupt +#define INT_THERM_TEMP1 10 // Thermal Temp 1 Interrupt +#define INT_THERM_ALARM1 11 // Thermal Alarm 1 Interrupt +#define INT_THERM_TEMP2 12 // Thermal Temp 2 Interrupt +#define INT_THERM_ALARM2 13 // Thermal Alarm 2 Interrupt + +// Reserved 14 - 15 + +#define INT_CPM_THERM_TEMP 16 // CPM Thermal temp Interrupt +#define INT_CPM_THERM_ALARM 17 // CPM Thermal alarm Interrupt +#define INT_CPU0_THERM_TEMP 18 // CPU0 Thermal temp Interrupt +#define INT_CPU0_THERM_ALARM 19 // CPU0 Thermal alarm Interrupt +#define INT_CPU1_THERM_TEMP 20 // CPU1 Thermal temp Interrupt +#define INT_CPU1_THERM_ALARM 21 // CPU1 Thermal alarm Interrupt + +// Reserved 21 - 25 + +#define INT_THERM_FS_ACT0 26 // Thermal Failsafe Active 0 Interrupt +#define INT_THERM_FS_ACT1 27 // Thermal Failsafe Active 1 Interrupt +#define INT_THERM_FS_EXT0 28 // Thermal Failsafe Exit 0 Interrupt +#define INT_THERM_FS_EXT1 29 // Thermal Failsafe Exit 1 Interrupt +#define INT_SOC_THERM_FS_ACT0 30 // SoC Thermal Failsafe Active 0 Interrupt +#define INT_SOC_THERM_FS_ACT1 31 // SoC Thermal Failsafe Active 1 Interrupt +#define INT_PMGR_EVENT 32 // PMGR Event Interrupt +#define INT_CTM_TRIGGER0 33 // CTM Trigger 0 Interrupt +#define INT_CTM_TRIGGER1 34 // CTM Trigger 1 Interrupt +#define INT_CTM_TRIGGER2 35 // CTM Trigger 2 Interrupt +#define INT_CTM_TRIGGER3 36 // CTM Trigger 3 Interrupt +#define INT_COHERENCE_PNT_ERR 37 // Coherence Point Error Interrupt +#define INT_COHERENCE_PNT_PERF_CNTRS 38 // Coherence Point Performance Counter Interrupt + +// Reserved 39-41 + +#define INT_GPIO_CLASS0 42 // GPIO Class 0 Interrupt +#define INT_GPIO_CLASS1 43 // GPIO Class 1 Interrupt +#define INT_GPIO_CLASS2 44 // GPIO Class 2 Interrupt +#define INT_GPIO_CLASS3 45 // GPIO Class 3 Interrupt +#define INT_GPIO_CLASS4 46 // GPIO Class 4 Interrupt +#define INT_GPIO_CLASS5 47 // GPIO Class 5 Interrupt +#define INT_GPIO_CLASS6 48 // GPIO Class 6 Interrupt + +// Reserved 49 + +#define INT_MINIMPGR_PERF_CTR 50 // MINIPMGR Performance Counter Interrupt +#define INT_GFX_PERF_CTR 51 // GFX Performance Counter Interrupt +#define INT_MEM_CONTROLLER0 52 // Memory Controller MCC0 Interrupt +#define INT_MEM_CONTROLLER1 53 // Memory Controller MCC1 Interrupt + +// Reserved 54-55 + +#define INT_MEM_CTLR_DCS0_AMCX0 56 // Memory Controller DCS0 AMCX 0 Interrupt +#define INT_MEM_CTLR_DCS0_AMCX1 57 // Memory Controller DCS0 AMCX 1 Interrupt +#define INT_MEM_CTLR_DCS0_AMP_CAL_ERR 58 // Memory Controller DCS0 AMP Cal Error 1 Interrupt +#define INT_MEM_CTLR_DCS1_AMCX0 59 // Memory Controller DCS1 AMCX 0 Interrupt +#define INT_MEM_CTLR_DCS1_AMCX1 60 // Memory Controller DCS1 AMCX 1 Interrupt +#define INT_MEM_CTLR_DCS1_AMP_CAL_ERR 61 // Memory Controller DCS1 AMP Cal Error 1 Interrupt +#define INT_MEM_CTLR_DCS2_AMCX0 62 // Memory Controller DCS2 AMCX 0 Interrupt +#define INT_MEM_CTLR_DCS2_AMCX1 63 // Memory Controller DCS2 AMCX 1 Interrupt +#define INT_MEM_CTLR_DCS2_AMP_CAL_ERR 64 // Memory Controller DCS2 AMP Cal Error 1 Interrupt +#define INT_MEM_CTLR_DCS3_AMCX0 65 // Memory Controller DCS3 AMCX 0 Interrupt +#define INT_MEM_CTLR_DCS3_AMCX1 66 // Memory Controller DCS3 AMCX 1 Interrupt +#define INT_MEM_CTLR_DCS3_AMP_CAL_ERR 67 // Memory Controller DCS3 AMP Cal Error 1 Interrupt + +// Reserved 68-80 + +#define INT_CPU0_COMM_TX 81 // CPU 0 COMM TX Interrupt +#define INT_CPU0_COMM_RX 82 // CPU 0 COMM RX Interrupt +#define INT_CPU0_PMU_IRQ 83 // CPU 0 PMU IRQ Interrupt +#define INT_CPU1_COMM_TX 84 // CPU 1 COMM TX Interrupt +#define INT_CPU1_COMM_RX 85 // CPU 1 COMM RX Interrupt +#define INT_CPU1_PMU_IRQ 86 // CPU 1 PMU IRQ Interrupt + +// Reserved 87 - 92 + +#define INT_CCC_UNIFIED_TRIGGER 93 // CCC Unified Trigger Interrupt + +// Reserved 94 + +#define INT_GFX_THROTTLING_TRIGGER 95 // GFX Throttling Trigger Interrupt + +// Reserved 96 - 103 + +#define INT_ISP_KF_INBOX_EMPTY 104 // ISP KF Inbox Empty Interrupt +#define INT_ISP_KF_INBOX_NOTEMPTY 105 // ISP KF Inbox Not Empty Interrupt +#define INT_ISP_KF_OUTBOX_EMPTY 106 // ISP KF Outbox Empty Interrupt +#define INT_ISP_KF_OUTBOX_NOTEMPTY 107 // ISP KF Outbox Not Empty Interrupt +#define INT_ISP0 108 // ISP 0 Interrupt +#define INT_ISP1 109 // ISP 1 Interrupt +#define INT_ISP2 110 // ISP 2 Interrupt +#define INT_ISP3 111 // ISP 3 Interrupt +#define INT_ISP_DART 112 // ISP DART Interrupt + +// Reserved 113 + +#define INT_SEP_KF_INBOX_EMPTY 114 // SEP KF Inbox Empty Interrupt +#define INT_SEP_KF_INBOX_NOTEMPTY 115 // SEP KF Inbox Not Empty Interrupt +#define INT_SEP_KF_OUTBOX_EMPTY 116 // SEP KF Outbox Empty Interrupt +#define INT_SEP_KF_OUTBOX_NOTEMPTY 117 // SEP KF Outbox Not Empty Interrupt +#define INT_SEP_AUTH_ERROR 118 // SEP Authentication Error Interrupt +#define INT_SEP_CRIT_PATH_MONITOR 119 // SEP Critical Path Monitor Interrupt + +// Reserved 120 - 122 + +#define INT_DOCK_CHANNELS 123 // Dock Channels Interrupt +#define INT_SCM_SPI 124 // SCM SPI Interrupt +#define INT_AOP_UART0 125 // AOP UART0 Interrupt +#define INT_AOP_UART1 126 // AOP UART1 Interrupt +#define INT_AOP_I2CM 127 // AOP I2CM Interrupt +#define INT_AOP_GPIO_IRQ0 128 // AOP GPIO IRQ0 Interrupt +#define INT_AOP_GPIO_IRQ1 129 // AOP GPIO IRQ1 Interrupt +#define INT_AOP_GPIO_IRQ2 130 // AOP GPIO IRQ2 Interrupt +#define INT_AOP_GPIO_IRQ3 131 // AOP GPIO IRQ3 Interrupt +#define INT_AOP_GPIO_IRQ4 132 // AOP GPIO IRQ4 Interrupt +#define INT_AOP_GPIO_IRQ5 133 // AOP GPIO IRQ5 Interrupt +#define INT_AOP_GPIO_IRQ6 134 // AOP GPIO IRQ6 Interrupt +#define INT_WAKEUP_AP 135 // AOP Wakeup AP Interrupt +#define INT_CPU_WAKEUP_AP 136 // AOP CPU Wakeup AP Interrupt +#define INT_SCM_RX_BUFFER_FULL0 137 // AOP SCM Buffer Full 0 Interrupt +#define INT_SCM_RX_BUFFER_FULL1 138 // AOP SCM Buffer Full 1 Interrupt +#define INT_SCM_MAX_COUNT0 139 // AOP SCM Max Count 0 Interrupt +#define INT_SCM_MAX_COUNT1 140 // AOP SCM Max Count 1 Interrupt +#define INT_SCM_SLAVE_ERROR 141 // AOP SCM Slave Error Interrupt +#define INT_AOP_UART2 142 // AOP UART2 Interrupt +#define INT_AOP_MCA0 143 // AOP MCA0 Interrupt +#define INT_AOP_HPD_DETECT 144 // AOP HPD Detect Interrupt +#define INT_AOP_KF_INBOX_EMPTY 145 // AOP KF Inbox Empty Interrupt +#define INT_AOP_KF_INBOX_NOTEMPTY 146 // AOP KF Inbox Not Empty Interrupt +#define INT_AOP_KF_OUTBOX_EMPTY 147 // AOP KF Outbox Empty Interrupt +#define INT_AOP_KF_OUTBOX_NOTEMPTY 148 // AOP KF Outbox Not Empty Interrupt +#define INT_AOP_AP_WATCHDOG 149 // AOP MCA0 Interrupt +#define INT_AOP_AP_WAKEUP_TIME 150 // AOP MCA0 Interrupt +#define INT_AOP_CDBGPWRUPREQ 151 // AOP CDBGPWRUPREQ Interrupt +#define INT_AOP_HPD_ERROR 152 // AOP HPD Error Interrupt + +// Reserved 153 + +#define INT_DISP0 154 // Display 0 Interrupt +#define INT_DISP0_PIO_DMA 155 // Display 0 PIO DMA Interrupt +#define INT_DISP0_DART 156 // Display 0 DART Interrupt +#define INT_DISP0_SMMU 157 // Display 0 SMMU Interrupt +#define INT_DISP0_BACK_END_BLU 158 // Display 0 Back End Back Light Update Interrupt +#define INT_DISP0_BACK_END_VBI 159 // Display 0 Back End VBI Interrupt +#define INT_DISP0_BACK_END_VFTG 160 // Display 0 Back End VFTG Idle Interrupt +#define INT_DISP0_BACK_END_VBL 161 // Display 0 Back End VBL counter Interrupt +#define INT_DISPLAY_PORT_TX0 162 // Display Port TX 0 Interrupt +#define INT_MIPIDSI0 163 // MIPI DSI 0 Interrupt +#define INT_EDP0 INT_DISPLAY_PORT +#define INT_DPORT0 INT_DISPLAY_PORT +#define INT_DISP0_BACK_END_VBI2 164 // Display 0 Back End - VBI2 Interrupt +#define INT_DISP0_SUBFRAME_TIMESTAMP 165 // Display 0 Sub Frame Line Count TimeStamp Interrupt +#define INT_DISP0_BACK_END_PARAM_FIFO 166 // Display 0 Back End - Param FIFO completion Interrupt +#define INT_PMP_KF_INBOX_EMPTY 167 // PMP KF Inbox Empty Interrupt +#define INT_PMP_KF_INBOX_NOTEMPTY 168 // PMP KF Inbox Not Empty Interrupt +#define INT_PMP_KF_OUTBOX_EMPTY 169 // PMP KF Outbox Empty Interrupt +#define INT_PMP_KF_OUTBOX_NOTEMPTY 170 // PMP KF Outbox Not Empty Interrupt + +// Reserved 171 + +#define INT_VDEC0 172 // Video Decoder 0 Interrupt + +// Reserved 173 + +#define INT_AVE_KF_INBOX_EMPTY 174 // AVE KF Inbox Empty Interrupt +#define INT_AVE_KF_INBOX_NOTEMPTY 175 // AVE KF Inbox Not Empty Interrupt +#define INT_AVE_KF_OUTBOX_EMPTY 176 // AVE KF Outbox Empty Interrupt +#define INT_AVE_KF_OUTBOX_NOTEMPTY 177 // AVE KF Outbox Not Empty Interrupt +#define INT_AVE_SMMU 178 // AVE SMMU Interrupt +#define INT_AVE_DART 179 // AVE DART Interrupt +#define INT_AVE 180 // AVE Interrupt +#define INT_SVE_SYNC 181 // SVE Driver Synchronization Interrupt + +// Reserved 182 - 184 + +#define INT_GFX 185 // GFX Interrupt +#define INT_GFX_SLEEP 186 // GFX Sleep Interrupt +#define INT_GFX_WAKE 187 // GFX Wake Interrupt +#define INT_GFX_CHG 188 // GFX Change Interrupt +#define INT_GHX_KF_INBOX_EMPTY 189 // GHX KF Inbox Empty Interrupt +#define INT_GHX_KF_INBOX_NOTEMPTY 190 // GHX KF Inbox Not Empty Interrupt +#define INT_GHX_KF_OUTBOX_EMPTY 191 // GHX KF Outbox Empty Interrupt +#define INT_GHX_KF_OUTBOX_NOTEMPTY 192 // GHX KF Outbox Not Empty Interrupt +#define INT_GHX_FIRMWARE 193 // GHX Firmware Only Interrupt + +// Reserved 194 + +#define INT_GPU_TIMER 195 // GPU Timer Interrupt +#define INT_JPEG0 196 // JPEG0 Interrupt +#define INT_JPEG0_DART 197 // JPEG0 DART Interrupt +#define INT_JPEG0_DART_PERF 198 // JPEG0 DART Performance Interrupt +#define INT_JPEG1 199 // JPEG1 Interrupt +#define INT_JPEG1_DART 200 // JPEG1 DART Interrupt +#define INT_JPEG1_DART_PERF 201 // JPEG1 DART Performance Interrupt + +// Reserved 202 - 203 + +#define INT_MSR 204 // MSR Interrupt +#define INT_MSR_PIO_DMA 205 // MSR PIO DMA Interrupt +#define INT_MSR_SMMU 206 // MSR SMMU Interrupt +#define INT_MSR_DART 207 // MSR DART Interrupt +#define INT_MSR_DART_PERF 208 // MSR DART Performance Interrupt + +// Reserved 209 + +#define INT_SIO_KF_INBOX_EMPTY 210 // SIO KF Inbox Empty Interrupt +#define INT_SIO_KF_INBOX_NOTEMPTY 211 // SIO KF Inbox Not Empty Interrupt +#define INT_SIO_KF_OUTBOX_EMPTY 212 // SIO KF Outbox Empty Interrupt +#define INT_SIO_KF_OUTBOX_NOTEMPTY 213 // SIO KF Outbox Not Empty Interrupt +#define INT_SPI0 214 // SPI 0 Interrupt +#define INT_SPI1 215 // SPI 1 Interrupt +#define INT_SPI2 216 // SPI 2 Interrupt +#define INT_SPI3 217 // SPI 3 Interrupt +#define INT_UART0 218 // UART 0 Interrupt +#define INT_UART1 219 // UART 1 Interrupt +#define INT_UART2 220 // UART 2 Interrupt +#define INT_UART3 221 // UART 3 Interrupt +#define INT_UART4 222 // UART 4 Interrupt +#define INT_UART5 223 // UART 5 Interrupt +#define INT_UART6 224 // UART 6 Interrupt +#define INT_UART7 225 // UART 7 Interrupt +#define INT_UART8 226 // UART 8 Interrupt +#define INT_MCA0 227 // Multi-Channel Audio 0 Interrupt +#define INT_MCA1 228 // Multi-Channel Audio 1 Interrupt +#define INT_MCA2 229 // Multi-Channel Audio 2 Interrupt +#define INT_MCA3 230 // Multi-Channel Audio 3 Interrupt +#define INT_MCA4 231 // Multi-Channel Audio 4 Interrupt +#define INT_IIC0 232 // I2C 0 Interrupt +#define INT_IIC1 233 // I2C 1 Interrupt +#define INT_IIC2 234 // I2C 2 Interrupt +#define INT_IIC3 235 // I2C 3 Interrupt +#define INT_PWM 236 // PWM Interrupt +#define INT_AES0 237 // AES 0 Interrupt +#define INT_HFD 238 // HFD Interrupt + +// Reserved 239 - 240 + +#define INT_USB_OTG 241 // USB OTG Interrupt +#define INT_USB2HOST0_EHCI 242 // USB EHCI 0 Interrupt +#define INT_USB2HOST0_OHCI 243 // USB OHCI 0 Interrupt +#define INT_USB2HOST1_EHCI 244 // USB EHCI 1 Interrupt + +// Reserved 245 + +#define INT_USBOTG_RESUME 246 // USB OTG Resume Interrupt +#define INT_USB_20_BATT_CHRG_DET 247 // USB 2.0 Battery Charge Detect Interrupt +#define INT_USB2HOST0_PHY_RESUME 248 // USB Host 0 Resume Interrupt +#define INT_USB2HOST1_PHY_RESUME 249 // USB Host 1 Resume Interrupt + +// Reserved 250 + +#define INT_OTG_IN_EP0 251 // OTG IN Endpoint 0 Interrupt +#define INT_OTG_IN_EP1 252 // OTG IN Endpoint 1 Interrupt +#define INT_OTG_IN_EP2 253 // OTG IN Endpoint 2 Interrupt +#define INT_OTG_IN_EP3 254 // OTG IN Endpoint 3 Interrupt +#define INT_OTG_IN_EP4 255 // OTG IN Endpoint 4 Interrupt +#define INT_OTG_IN_EP5 256 // OTG IN Endpoint 5 Interrupt +#define INT_OTG_IN_EP6 257 // OTG IN Endpoint 6 Interrupt +#define INT_OTG_IN_EP7 258 // OTG IN Endpoint 7 Interrupt +#define INT_OTG_IN_EP8 259 // OTG IN Endpoint 8 Interrupt +#define INT_OTG_OUT_EP0 260 // OTG OUT Endpoint 0 Interrupt +#define INT_OTG_OUT_EP1 261 // OTG OUT Endpoint 1 Interrupt +#define INT_OTG_OUT_EP2 262 // OTG OUT Endpoint 2 Interrupt +#define INT_OTG_OUT_EP3 263 // OTG OUT Endpoint 3 Interrupt +#define INT_OTG_OUT_EP4 264 // OTG OUT Endpoint 4 Interrupt +#define INT_OTG_OUT_EP5 265 // OTG OUT Endpoint 5 Interrupt +#define INT_OTG_OUT_EP6 266 // OTG OUT Endpoint 6 Interrupt +#define INT_OTG_OUT_EP7 267 // OTG OUT Endpoint 7 Interrupt +#define INT_OTG_OUT_EP8 268 // OTG OUT Endpoint 8 Interrupt + +// Reserved 269 + +#define PCIE_LINK0 270 // PCIE Link 0 Interrupt +#define PCIE_LINK0_DART 271 // PCIE Link 0 DART Interrupt +#define PCIE_LINK0_MMU 272 // PCIE Link 0 MMU Interrupt +#define PCIE_LINK1 273 // PCIE Link 1 Interrupt +#define PCIE_LINK1_DART 274 // PCIE Link 1 DART Interrupt +#define PCIE_LINK1_MMU 275 // PCIE Link 1 MMU Interrupt +#define PCIE_LINK2 276 // PCIE Link 1 Interrupt +#define PCIE_LINK2_DART 277 // PCIE Link 1 DART Interrupt +#define PCIE_LINK2_MMU 278 // PCIE Link 1 MMU Interrupt +#define PCIE_LINK3 279 // PCIE Link 1 Interrupt +#define PCIE_LINK3_DART 280 // PCIE Link 1 DART Interrupt +#define PCIE_LINK3_MMU 281 // PCIE Link 1 MMU Interrupt + +// Reserved 282 - 287 + +#define PCIE_MSI0 288 // PCIE MSI 0 Interrupt +#define PCIE_MSI1 289 // PCIE MSI 1 Interrupt +#define PCIE_MSI2 290 // PCIE MSI 2 Interrupt +#define PCIE_MSI3 291 // PCIE MSI 3 Interrupt +#define PCIE_MSI4 292 // PCIE MSI 4 Interrupt +#define PCIE_MSI5 293 // PCIE MSI 5 Interrupt +#define PCIE_MSI6 294 // PCIE MSI 6 Interrupt +#define PCIE_MSI7 295 // PCIE MSI 7 Interrupt +#define PCIE_MSI8 296 // PCIE MSI 8 Interrupt +#define PCIE_MSI9 297 // PCIE MSI 9 Interrupt +#define PCIE_MSI10 298 // PCIE MSI 10 Interrupt +#define PCIE_MSI11 299 // PCIE MSI 11 Interrupt +#define PCIE_MSI12 300 // PCIE MSI 12 Interrupt +#define PCIE_MSI13 301 // PCIE MSI 13 Interrupt +#define PCIE_MSI14 302 // PCIE MSI 14 Interrupt +#define PCIE_MSI15 303 // PCIE MSI 15 Interrupt +#define PCIE_MSI16 304 // PCIE MSI 16 Interrupt +#define PCIE_MSI17 305 // PCIE MSI 17 Interrupt +#define PCIE_MSI18 306 // PCIE MSI 18 Interrupt +#define PCIE_MSI19 307 // PCIE MSI 19 Interrupt +#define PCIE_MSI20 308 // PCIE MSI 20 Interrupt +#define PCIE_MSI21 309 // PCIE MSI 21 Interrupt +#define PCIE_MSI22 310 // PCIE MSI 22 Interrupt +#define PCIE_MSI23 311 // PCIE MSI 23 Interrupt +#define PCIE_MSI24 312 // PCIE MSI 24 Interrupt +#define PCIE_MSI25 313 // PCIE MSI 25 Interrupt +#define PCIE_MSI26 314 // PCIE MSI 26 Interrupt +#define PCIE_MSI27 315 // PCIE MSI 27 Interrupt +#define PCIE_MSI28 316 // PCIE MSI 28 Interrupt +#define PCIE_MSI29 317 // PCIE MSI 29 Interrupt +#define PCIE_MSI30 318 // PCIE MSI 30 Interrupt +#define PCIE_MSI31 319 // PCIE MSI 31 Interrupt + +#else +#error Unsupported Platform +#endif + +#endif /* ! __PLATFORM_SOC_HWISR_H */ diff --git a/platform/t8010/include/platform/soc/hwregbase.h b/platform/t8010/include/platform/soc/hwregbase.h new file mode 100644 index 0000000..34af833 --- /dev/null +++ b/platform/t8010/include/platform/soc/hwregbase.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_H +#define __PLATFORM_SOC_HWREGBASE_H + +#include +#include + +// Common definitions for T801x SoCs go here. Put everything into the +// SoC-specific header until there is another chip in the family. + +#include SUB_PLATFORM_SOC_HEADER(hwregbase) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_H */ diff --git a/platform/t8010/include/platform/soc/hwregbase_t8010.h b/platform/t8010/include/platform/soc/hwregbase_t8010.h new file mode 100644 index 0000000..9c78445 --- /dev/null +++ b/platform/t8010/include/platform/soc/hwregbase_t8010.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_HWREGBASE_T8010_H +#define __PLATFORM_SOC_HWREGBASE_T8010_H + +#include + +#if !SUB_PLATFORM_T8010 +#error "Include only for T8010" +#endif + +#define DCS_REG_VERSION (4) + +/* T8010 Reg Base Definitions */ + +#define AMCC_BASE_ADDR(_n) (IO_BASE + ((_n) * 0x000200000)) // AMCC Config +#define NUM_AMCCS (1) + +#define DCS_BASE_ADDR (IO_BASE + 0x000200000) // DCS + +#define DCS_SPACING (0x40000) +#define SPLLCTRL_SPACING (0x00000C000) +#define AMP_CA_SPACING (0x000020000) +#define AMP_DQ_SPACING (0x000008000) +#define AMP_SPACING (DCS_SPACING) +#define AMP_BASE_ADDR (DCS_BASE_ADDR + AMP_CA_SPACING) +#define AMPH_BASE_ADDR (AMP_BASE_ADDR + 3 * AMP_DQ_SPACING) + +#define SWTCH_FAB_BASE_ADDR (IO_BASE + 0x000800000) // Switch Fabric Config + +#define CP_COM_BASE_ADDR (IO_BASE + 0x000D00000) // CP Common Registers +#define CP_COM_INT_BASE_ADDR (CP_COM_BASE_ADDR + 0x10000) // CP Common Interrupt Config Registers + +#define CP_0_DT_DBG_CA0_ADDR (IO_BASE + 0x000D40000) // Dup Tag Debug backdoor Ram Access For CP0/CA0 +#define CP_1_DT_DBG_CA0_ADDR (IO_BASE + 0x000E40000) // Dup Tag Debug backdoor Ram Access For CP1/CA0 + +#define ACC_BASE_ADDR (IO_BASE + 0x002000000) // Apple Compute Complex +#define CCC_CPU0_SYS_BASE_ADDR (IO_BASE + 0x002000000) // Hurricane/Zephyr CPU0 Implementation Specific Registers +#define CCC_CPU1_SYS_BASE_ADDR (IO_BASE + 0x002100000) // Hurricane/Zephyr CPU1 Implementation Specific Registers + +#define SOC_BUSMUX_BASE_ADDR (IO_BASE + 0x004000000) // AF SoC BusMux Config + +#define DISP0_FAB_BASE_ADDR (IO_BASE + 0x006100000) // DisplayPipe0 AF and AXI Config +#define DISP0_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 +#define DISP0_ADP_BASE_ADDR (IO_BASE + 0x006200000) // DisplayPipe0 Configuration +#define DISP0_SMMU_BASE_ADDR (IO_BASE + 0x006300000) // DisplayPipe0 SMMU Configuration +#define DISP0_DART_BASE_ADDR (IO_BASE + 0x006304000) // DisplayPipe0 DART Configuration +#define DISP0_ADBE_BASE_ADDR (IO_BASE + 0x006400000) // DisplayPipe0 Backend Config +#define DISP0_AAP_BASE_ADDR (IO_BASE + 0x006440000) // DisplayPipe0 Ambient-Adaptive Pixel Config +#define DISP0_DPB_BASE_ADDR (IO_BASE + 0x006480000) // DisplayPipe0 Dynamic Pixel Backlight Config +#define DISP0_WPC_BASE_ADDR (IO_BASE + 0x0064C0000) // DisplayPipe0 White Point Correction Config +#define DISP0_PRC_BASE_ADDR (IO_BASE + 0x006500000) // DisplayPipe0 Panel Regamma Correction Config +#define DISP0_DITHER_BASE_ADDR (IO_BASE + 0x006540000) // DisplayPipe0 Dither Config +#define DISP0_CDRR_BASE_ADDR (IO_BASE + 0x0065C0000) // DisplayPipe0 Content Dependent Refresh Rate Statistics Config +#define DISP0_ADP_PARAM_FIFO_BASE_ADDR (IO_BASE + 0x006600000) // DisplayPipe0 Backend Parameter Buffer Config +#define DITHER_BASE_ADDR DISP0_DITHER_BASE_ADDR +#define DITHER_VERSION (3) + +#define DISP0_DPTX_BASE_ADDR (IO_BASE + 0x006780000) // DisplayPipe0 DisplayPort TX Config +#define DISP0_MIPI_DSI_BASE_ADDR (IO_BASE + 0x006800000) // DisplayPipe0 MIPI DSI Config + +#define ASIO_MISC_0_BASE_ADDR (IO_BASE + 0x00A000000) // ASIO Shim0 Misc Registers +#define ASIO_AUD_MUX_BASE_ADDR (IO_BASE + 0x00A003000) // ASIO Audio I2S Switch Config +#define ASIO_SPI_BASE_ADDR (IO_BASE + 0x00A080000) // ASIO SPI Device +#define ASIO_SPI_TX_CFG_BASE_ADDR (IO_BASE + 0x00A081000) // ASIO SPI TX DMA Channel +#define ASIO_SPI_RX_CFG_BASE_ADDR (IO_BASE + 0x00A081800) // ASIO SPI RX DMA Channel +#define ASIO_SPI_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A082000) // ASIO SPI TX DMA Shim FIFO +#define ASIO_SPI_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A083000) // ASIO SPI RX DMA Shim FIFO +#define ASIO_MCA_BASE_ADDR (IO_BASE + 0x00A0A0000) // ASIO MCA Device +#define ASIO_MCA_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1000) // ASIO MCA TX DMA Channel +#define ASIO_MCA_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0A1800) // ASIO MCA RX DMA Channel +#define ASIO_MCA_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A2000) // ASIO MCA TX DMA Shim FIFO +#define ASIO_MCA_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0A3000) // ASIO MCA RX DMA Shim FIFO +#define ASIO_PDM_BASE_ADDR (IO_BASE + 0x00A0B4000) // ASIO PDM Device +#define ASIO_PDM_DEMOD_BASE_ADDR (IO_BASE + 0x00A0B4000) +#define ASIO_PDM_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0B5000) +#define ASIO_PDM_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0B5800) +#define ASIO_PDM_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0BC000) +#define ASIO_PDM_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0B7000) +#define ASIO_UART_BASE_ADDR (IO_BASE + 0x00A0C0000) // ASIO UART Device +#define ASIO_UART_TX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1000) // ASIO UART TX DMA Channel +#define ASIO_UART_RX_CFG_BASE_ADDR (IO_BASE + 0x00A0C1800) // ASIO UART RX DMA Channel +#define ASIO_UART_TX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C2000) // ASIO UART TX DMA Shim FIFO +#define ASIO_UART_RX_FIFO_BASE_ADDR (IO_BASE + 0x00A0C3000) // ASIO UART RX DMA Shim FIFO +#define ASIO_MISC_1_BASE_ADDR (IO_BASE + 0x00A100000) // ASIO Shim1 Misc Registers +#define ASIO_AES_BASE_ADDR (IO_BASE + 0x00A108000) // ASIO AES Config and DMA Registers +#define ASIO_SMB_0_BASE_ADDR (IO_BASE + 0x00A110000) // ASIO I2C 0 Device +#define ASIO_SMB_1_BASE_ADDR (IO_BASE + 0x00A111000) // ASIO I2C 1 Device +#define ASIO_SMB_2_BASE_ADDR (IO_BASE + 0x00A112000) // ASIO I2C 2 Device +#define ASIO_SMB_3_BASE_ADDR (IO_BASE + 0x00A113000) // ASIO I2C 3 Device +#define ASIO_PWM_BASE_ADDR (IO_BASE + 0x00A118000) // ASIO PWM +#define ASIO_PL301_BASE_ADDR (IO_BASE + 0x00A140000) // ASIO PL301 +#define ASIO_PL301_AES_BASE_ADDR (IO_BASE + 0x00A141000) // ASIO PL301 AES +#define ASIO_DNSZ_AXI_0_BASE_ADDR (IO_BASE + 0x00A142000) // ASIO Downsizer 0 Configuration Registers +#define ASIO_DNSZ_AXI_1_BASE_ADDR (IO_BASE + 0x00A143000) // ASIO Downsizer 1 Configuration Registers +#define ASIO_AKF_BASE_ADDR (IO_BASE + 0x00AE00000) // ASIO KF Wrapper +#define ASIO_AKF_DEBUG_BASE_ADDR (IO_BASE + 0x00AE20000) // ASIO KF Debug Wrapper + +#define AUSB_CTL_REG_BASE_ADDR (IO_BASE + 0x00C000000) // USBCTL Config +#define AUSB_CTL_USB20PHY_REG_OFFSET (0x30) // USB20PHY Register offset within AUSBCTL registers +#define AUSB_OTG_BASE_ADDR (IO_BASE + 0x00C100000) // USB OTG +#define AUSB_USB2HOST0_EHCI_BASE_ADDR (IO_BASE + 0x00C200000) // EHCI0 +#define AUSB_USB2HOST0_OHCI_BASE_ADDR (IO_BASE + 0x00C300000) // OHCI0 +#define AUSB_PL301_BASE_ADDR (IO_BASE + 0x00C800000) // AUSB PL301 4-AHB Master to 1-AXI Slave +#define AUSB_PL301_WIDGET_BASE_ADDR (IO_BASE + 0x00C900000) // AUSB PL301 Widget +#define AUSB_INTR2AXI_BASE_ADDR (IO_BASE + 0x00CA00000) // AUSB Interrupt to AXI Widget +#define AUSB_AFIFO_WIDGET_BASE_ADDR (IO_BASE + 0x00CB00000) // AUSB Async FIFO + +#define ASEP_AKF_BASE_ADDR (IO_BASE + 0x00DA00000) // ASEP AKF control Registers + +#define PMGR_BASE_ADDR (IO_BASE + 0x00E000000) // PMGR +#define PMS_CRS_BASE_ADDR (IO_BASE + 0x00E400000) // PMS control registers + +#define AIC_BASE_ADDR (IO_BASE + 0x00E100000) // AIC +#define AIC_WIRE_VIRT_BASE_ADDR (IO_BASE + 0x00E110000) // AIC Wrapper + +#define DWI_BASE_ADDR (IO_BASE + 0x00E200000) // DWI + +#define AFC_AIU_SB_BASE_ADDR (IO_BASE + 0x00F000000) // AFC_AIU_SB + +#define GPIO_BASE_ADDR (IO_BASE + 0x00F100000) // GPIO +#define GLBTIMER_BASE_ADDR (IO_BASE + 0x00F140000) // Global Timer + +#define LIO_MEM_PL301_BASE_ADDR (IO_BASE + 0x00F160000) // PL310 for pd_lio memory +#define LIO_PIO_PL310_BASE_ADDR (IO_BASE + 0x00F180000) // PL310 for pd_lio PIO +#define LIO_DNSZ_AXI_BASE_ADDR (IO_BASE + 0x00F1A0000) // PL310 for pd_lio downsizer + +#define SB_GLUE_REG_BASE (IO_BASE + 0x00f1c0000) // Local registers for south bridge + +#define ERR_REFLECTION_BASE_ADDR (IO_BASE + 0x00FFFC000) + +#define AOP_BASE_ADDR (IO_BASE + 0x010000000) +#define AOP_MINIPMGR_BASE_ADDR (IO_BASE + 0x010200000) +#define DBG_WRP_BASE_ADDR (IO_BASE + 0x010300000) // Debug Sub-system Config +#define AOP_GPIO_BASE_ADDR (IO_BASE + 0x0100f0000) +#define AOP_SRAM_BASE_ADDR (IO_BASE + 0x010E00000) +#define AOP_RECONFIG_REGION_BASE_ADDR (IO_BASE + 0x010E9B000) +#define AOP_RECONFIG_REGION_SIZE (IO_BASE + 0x010EA0000 - AOP_RECONFIG_REGION_BASE_ADDR) +#define MEMORY_CALIB_SAVE_BASE_ADDR AOP_SRAM_BASE_ADDR // Temporarily save cold boot memcal results in AOP_SRAM + +#define APCIE_VERSION (2) +#define APCIE_COMMON_BASE_ADDR (PCI_REG_BASE + 0x00000000) +#define APCIE_COUNTER_BASE_ADDR (PCI_REG_BASE + 0x00004000) +#define APCIE_PHY_BASE_ADDR (PCI_REG_BASE + 0x00008000) +#define APCIE_CONFIG_BASE_ADDR (PCI_REG_BASE + 0x01000000) +#define APCIE_CONFIG_PORT_STRIDE (0x01000000) +#define APCIE_PHY_PMA_COMMON_BASE_ADDR (PCI_REG_BASE + 0x0a000000) +#define APCIE_PHY_PMA_TX_LANE_BASE_ADDR (PCI_REG_BASE + 0x0a010000) +#define APCIE_PHY_PMA_TX_LANE_STRIDE (0x800) +#define APCIE_PHY_PMA_RX_LANE_BASE_ADDR (PCI_REG_BASE + 0x0a020000) +#define APCIE_PHY_PMA_RX_LANE_STRIDE (0x800) + +/* iBoot Specific Defs */ + +#define AKF_VERSION (2) + +#define UART0_BASE_ADDR (ASIO_UART_BASE_ADDR) +#define UART1_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x04000) +#define UART2_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x08000) +#define UART3_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x10000) +#define UART5_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x14000) +#define UART6_BASE_ADDR (ASIO_UART_BASE_ADDR + 0x18000) +#define UARTS_COUNT (7) +#define UART_VERSION (1) + +#define SPI0_BASE_ADDR (ASIO_SPI_BASE_ADDR) +#define SPI1_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x04000) +#define SPI2_BASE_ADDR (ASIO_SPI_BASE_ADDR + 0x08000) +#define SPI_VERSION (1) +#define SPIS_COUNT (3) + +#define IIC_BASE_ADDR (ASIO_SMB_0_BASE_ADDR) +#define IIC_SPACING (0x00001000) +#define IICS_COUNT (4) + +#define USBPHY_VERSION (4) + +#define DSIM_BASE_ADDR (DISP0_MIPI_DSI_BASE_ADDR) +#define DSIM_LANE_COUNT (4) +#define DSIM_VERSION (2) + +#define EDP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define DP_BASE_ADDR (DISP0_DPTX_BASE_ADDR) +#define LPDP_PHY_BASE_ADDR (DISP0_DPTX_BASE_ADDR + 0x080000) +#define DISPLAYPORT_VERSION (3) + +#define ADBE_DISPLAYPIPE_BASE_ADDR (DISP0_BASE_ADDR) +#define DISP_VERSION (5) +#define ADP_VERSION (2) + +#define GPIOC_COUNT (2) +#define GPIO_VERSION (6) +#define GPIO_0_GROUP_COUNT (26) +#define GPIO_1_BASE_ADDR (AOP_GPIO_BASE_ADDR) +#define GPIO_1_GROUP_COUNT (11) +#define GPIO_AP (GPIOC_0) +#define GPIO_AOP (GPIOC_1) +#define GPIO_GROUP_COUNT (GPIO_0_GROUP_COUNT) +#define GPIO_PAD_SPI (GPIO_GROUP_COUNT) + +#define AIC_VERSION (3) +#define AIC_INT_COUNT (320) + +#define PMGR_WDG_VERSION (1) + +#define USBOTG_BASE_ADDR (AUSB_OTG_BASE_ADDR) + +#define APCIE_NUM_LINKS (4) + +#define DART0_BASE_ADDR (PCI_REG_BASE + 0x1008000) +#define DART0_ADDR_MASK (0x3FFFFFFF) +#define DART1_BASE_ADDR (PCI_REG_BASE + 0x2008000) +#define DART1_ADDR_MASK (0x3FFFFFFF) +#define DART2_BASE_ADDR (PCI_REG_BASE + 0x3008000) +#define DART2_ADDR_MASK (0x3FFFFFFF) +#define DART3_BASE_ADDR (PCI_REG_BASE + 0x4008000) +#define DART3_ADDR_MASK (0x3FFFFFFF) + +#define PCIE_PORT0_DART_ID (0) +#define PCIE_PORT1_DART_ID (1) +#define PCIE_PORT2_DART_ID (2) +#define PCIE_PORT3_DART_ID (3) +#define NUM_DARTS (4) + +#define AES_AP_BASE_ADDR (ASIO_AES_BASE_ADDR) +#define AES_AP_VERSION (0) + +#endif /* ! __PLATFORM_SOC_HWREGBASE_T8010_H */ diff --git a/platform/t8010/include/platform/soc/miu.h b/platform/t8010/include/platform/soc/miu.h new file mode 100644 index 0000000..b0e6db5 --- /dev/null +++ b/platform/t8010/include/platform/soc/miu.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_MIU_H +#define __PLATFORM_SOC_MIU_H + +#include +#include +#include SUB_PLATFORM_SPDS_HEADER(afc_aiu_sb) +#include SUB_PLATFORM_SPDS_HEADER(amcc) +#include SUB_PLATFORM_SPDS_HEADER(cp_com) +#include SUB_PLATFORM_SPDS_HEADER(minipmgr) +#include SUB_PLATFORM_SPDS_HEADER(misc1) +#include SUB_PLATFORM_SPDS_HEADER(pms_csr) +#include SUB_PLATFORM_SPDS_HEADER(sb_glue) +#include SUB_PLATFORM_SPDS_HEADER(socbusmux) +#include SUB_PLATFORM_SPDS_HEADER(switchfabric) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/MINIPMGR.html?baseaddr=0x210200000#MINIPMGR_SECURITY +#define rSECUREROMCTRL_ROMADDRREMAP (*(volatile u_int32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_MCC_ROMADDRREMAP_OFFSET)) +#define SECUREROMCTRL_ROMADDRREMAP_SRAM (1 << 0) +#define SECUREROMCTRL_ROMADDRREMAP_SDRAM (1 << 1) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/amcc.html?baseaddr=0x200000000 +#define MCCLOCKREGION_TZ0BASEADDR(_n) (AMCC_BASE_ADDR(_n) + AMCC_MCC_LOCK_REGION_TZ0_BASE_ADDR_OFFSET) +#define MCCLOCKREGION_TZ0ENDADDR(_n) (AMCC_BASE_ADDR(_n) + AMCC_MCC_LOCK_REGION_TZ0_END_ADDR_OFFSET) +#define MCCLOCKREGION_TZ0LOCK(_n) (AMCC_BASE_ADDR(_n) + AMCC_MCC_LOCK_REGION_TZ0_LOCK_OFFSET) + +#define rMCCLOCKREGION_TZ0BASEADDR(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ0BASEADDR(_n))) +#define rMCCLOCKREGION_TZ0ENDADDR(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ0ENDADDR(_n))) +#define rMCCLOCKREGION_TZ0LOCK(_n) (*(volatile u_int32_t *)(MCCLOCKREGION_TZ0LOCK(_n))) + +#define rAMCC_IRERRDBG_INTEN(_n) (*(volatile uint32_t *)(AMCC_BASE_ADDR(_n) + AMCC_IRERRDBG_INTEN_OFFSET)) +#define rAMCC_IRERRDBG_INTSTS(_n) (*(volatile uint32_t *)(AMCC_BASE_ADDR(_n) + AMCC_IRERRDBG_INTSTS_OFFSET)) +#define rAMCC_IRERRDBG_MCC_AF_ERR_LOG2(_n) (*(volatile uint32_t *)(AMCC_BASE_ADDR(_n) + AMCC_IRERRDBG_MCC_AF_ERR_LOG2_OFFSET)) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/SWITCHFABRIC.html?baseaddr=0x200800000 +#define rSWITCH_FAB_CPG_CNTL (*(volatile u_int32_t *)(SWTCH_FAB_BASE_ADDR + SWITCHFABRIC_BLK_REGS_CPG_CNTL_OFFSET)) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/CP_COM.html?baseaddr=0x200d00000 +#define rCP_COM_DYN_CLK_GATING_CTRL (*(volatile u_int32_t *)(CP_COM_BASE_ADDR + CP_COM_CFG_DYN_CLK_GATE_CTRL_OFFSET)) +#define rCP_COM_INT_NORM_REQUEST (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CP_COM_INT_NORM_REQUEST_OFFSET)) +#define rCP_COM_INT_NORM_MASK_SET (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CP_COM_INT_NORM_MASK_SET_OFFSET)) +#define rCP_COM_INT_NORM_MASK_CLR (*(volatile u_int32_t *)(CP_COM_INT_BASE_ADDR + CP_COM_INT_NORM_MASK_CLR_OFFSET)) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/SOCBUSMUX.html?baseaddr=0x204000000 +#define rSOCBUSMUX_CPG_CNTL (*(volatile u_int32_t *)(SOC_BUSMUX_BASE_ADDR + SOCBUSMUX_BLK_REGS_CPG_CNTL_OFFSET)) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/Misc1.html?baseaddr=0x20a100000 +#define rASIO_CLK_CTRL (*(volatile u_int32_t *)(ASIO_MISC_1_BASE_ADDR + MISC1_BLK_CLOCK_CONTROL_OFFSET)) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/pmsCSR.html?baseaddr=0x20e400000 +#define rPMS_SRAM_CPG_CTRL (*(volatile u_int32_t *)(PMS_CRS_BASE_ADDR + PMS_CSR_PMSCSR_PMP_PMS_SRAM_CPG_CTRL_OFFSET)) +#define rPMP_CPG_CTRL (*(volatile u_int32_t *)(PMS_CRS_BASE_ADDR + PMS_CSR_PMSCSR_PMP_PMP_CPG_CTRL_OFFSET)) +#define rPMS_CPG_CTRL (*(volatile u_int32_t *)(PMS_CRS_BASE_ADDR + PMS_CSR_PMSCSR_PMP_PMS_CPG_CTRL_OFFSET)) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/afc_aiu_sb.html?baseaddr=0x20f000000 +#define rAIU_SB_CPG_CNTL (*(volatile u_int32_t *)(AFC_AIU_SB_BASE_ADDR + AFC_AIU_SB_SELF_OFFSET)) + +// https://seg-docs.ecs.apple.com/projects/cayman//release/UserManual/regs/DYNAMIC_CLK_GATING.html?baseaddr=0x20f1c0000 +#define rDYN_CLK_GATING (*(volatile u_int32_t *)(SB_GLUE_REG_BASE + SB_GLUE_BLK_DYNAMIC_CLK_GATING_OFFSET)) +#define rDYN_CLK_GATING2 (*(volatile u_int32_t *)(SB_GLUE_REG_BASE + SB_GLUE_BLK_DYNAMIC_CLK_GATING2_OFFSET)) + +enum remap_select { + REMAP_SRAM = 0, + REMAP_SDRAM +}; + +extern void miu_select_remap(enum remap_select sel); +extern void miu_bypass_prep(void); +extern void miu_update_device_tree(DTNode *pmgr_node); + +#endif /* ! __PLATFORM_SOC_MIU_H */ diff --git a/platform/t8010/include/platform/soc/operating_point.h b/platform/t8010/include/platform/soc/operating_point.h new file mode 100644 index 0000000..aed3bee --- /dev/null +++ b/platform/t8010/include/platform/soc/operating_point.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_OPERATING_POINT_H +#define __PLATFORM_SOC_OPERATING_POINT_H + +#include +struct operating_point_params { + union { + struct { + uint64_t voltage_index:9; + uint64_t bypass:1; + uint64_t clkSrc:1; + uint64_t fcwInt:8; + uint64_t fcwFrac:3; + uint64_t pstDivS:4; + uint64_t migDivS:4; + uint64_t coreTyp:2; + uint64_t biuDiv4HiVol:3; + uint64_t biuDiv4LoVol:3; + uint64_t dvmrMaxWgt:7; + uint64_t iexrfCfgWrData:2; + uint64_t iexrfCfgWrIdxa:2; + uint64_t iexrfCfgWrIdxb:2; + uint64_t exrfCfgWrIdxmuxsel:2; + } cpu; + struct { + uint64_t voltage_index:9; + uint64_t preDivP:6; + uint64_t fbkDivM:9; + uint64_t pstDivS:4; + } gpu; + struct { + uint64_t voltage_index:9; // must contains CHIPID_MAX + uint64_t chip_id:16; + uint64_t voltage_type:3; + uint64_t reserved:34; + }; + }; +}; +extern const struct operating_point_params *operating_point_get_params(enum chipid_voltage_index voltage_index, enum chipid_voltage_type voltage_type); + + + +#endif /* __PLATFORM_SOC_CHIPID_H */ diff --git a/platform/t8010/include/platform/soc/pmgr.h b/platform/t8010/include/platform/soc/pmgr.h new file mode 100644 index 0000000..7a4c24c --- /dev/null +++ b/platform/t8010/include/platform/soc/pmgr.h @@ -0,0 +1,581 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_SOC_PMGR_H +#define __PLATFORM_SOC_PMGR_H + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////// +// +// PMGR specific +// +//////////////////////////////////////////////////////////// + +enum coreTyp { + kACC_CORETYP_ECORE, + kACC_CORETYP_PCORE, + kACC_CORETYP_FUSED +}; + +#define PMGR_PLL_COUNT (7) + +#define PMGR_PLL_REG_STRIDE (PMGR_PLL1_OFFSET - PMGR_PLL0_OFFSET) + +#define rPMGR_PLL_CTL(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define PMGR_PLL_ENABLE (1 << PMGR_PLL0_CTL_ENABLE_SHIFT) +#define PMGR_PLL_LOAD (1 << PMGR_PLL0_CTL_LOAD_SHIFT) +#define PMGR_PLL_BYPASS (1 << PMGR_PLL0_CTL_BYPASS_SHIFT) +#define PMGR_PLL_PENDING (1 << PMGR_PLL0_CTL_PLL_PENDING_SHIFT) +#define PMGR_PLL_M_SHIFT PMGR_PLL0_CTL_FB_DIVN_SHIFT +#define PMGR_PLL_M_MASK PMGR_PLL0_CTL_FB_DIVN_SMASK +#define PMGR_PLL_P_SHIFT PMGR_PLL0_CTL_PRE_DIVN_SHIFT +#define PMGR_PLL_P_MASK PMGR_PLL0_CTL_PRE_DIVN_SMASK +#define PMGR_PLL_S_SHIFT PMGR_PLL0_CTL_OP_DIVN_SHIFT +#define PMGR_PLL_S_MASK PMGR_PLL0_CTL_OP_DIVN_SMASK +#define PMGR_PLL_PCIE_S_MASK PMGR_PLL_PCIE_CTL_OP_DIVN_SMASK +#define PMGR_PLL_M(_m) (((_m) & PMGR_PLL_M_MASK) << PMGR_PLL_M_SHIFT) +#define PMGR_PLL_P(_p) (((_p) & PMGR_PLL_P_MASK) << PMGR_PLL_P_SHIFT) +#define PMGR_PLL_S(_s) (((_s) & PMGR_PLL_S_MASK) << PMGR_PLL_S_SHIFT) +#define PMGR_PLL_PCIE_S(_s) (((_s) & PMGR_PLL_PCIE_S_MASK) << PMGR_PLL_S_SHIFT) +#define PMGR_PLL_FREQ(_m, _p, _s) ((((_m) * OSC_FREQ) / (_p))/((_s) + 1)) + +#define rPMGR_PLL_CFG(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0004 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define PMGR_PLL_OFF_MODE(_n) PMGR_PLL0_CFG_OFF_MODE_INSRT(_n) +#define PMGR_PLL_OFF_MODE_RESET (0) +#define PMGR_PLL_OFF_MODE_CLOCK_GATED (1) +#define PMGR_PLL_OFF_MODE_POWER_DOWN (2) +#define PMGR_PLL_LOCK_MODE(_n) PMGR_PLL0_CFG_LOCK_MODE_INSRT(_n) +#define PMGR_PLL_LOCK_MODE_COUNTER (0) +#define PMGR_PLL_LOCK_MODE_LOCK (1) +#define PMGR_PLL_AUTO_DISABLE (1 << PMGR_PLL0_CFG_AUTO_DISABLE_SHIFT) +#define PMGR_PLL_RELOCK_MODE_SHIFT PMGR_PLL0_CFG_RELOCK_MODE_SHIFT +#define PMGR_PLL_RELOCK_MODE_MASK PMGR_PLL0_CFG_RELOCK_MODE_SMASK +#define PMGR_PLL_RELOCK_MODE_STOP (0) +#define PMGR_PLL_RELOCK_MODE_BYPASS (1) +#define PMGR_PLL_FRAC_LOCK_TIME(_n) PMGR_PLL0_CFG_FRAC_LOCK_TIME_INSRT(_n) +#define PMGR_PLL_LOCK_TIME(_n) PMGR_PLL0_CFG_LOCK_TIME_INSRT(_n) + +#define rPMGR_PLL_ANA_PARAMS1(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x000c + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define rPMGR_PLL_ANA_PARAMS2(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0010 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define rPMGR_PLL_ANA_PARAMS3(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0014 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) + +#define rPMGR_PLL_DEBUG1(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0014 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) +#define PMGR_PLL_DEBUG1_RESERVE_IN_SHIFT (20) +#define PMGR_PLL_DEBUG1_RESERVE_IN_MASK (0x3f) + +#define rPMGR_PLL_PCIE_DELAY_CTL0(_p) (*(volatile uint32_t *)(PMGR_BASE_ADDR + 0x0028 + ((_p == PLL_PCIE) ? PMGR_PLL_PCIE_OFFSET : ((_p) * PMGR_PLL_REG_STRIDE)))) + +#define rPMGR_CLK_CFG(_x) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_CLKCFG_##_x##_CLK_CFG_OFFSET)) + +#define PMGR_CLK_CFG_ENABLE (1 << 31) +#define PMGR_CLK_CFG_PENDING (1 << 30) +#define PMGR_CLK_CFG_PENDING_SHIFT (30) +#define PMGR_CLK_CFG_SRC_SEL_MASK (0xF) +#define PMGR_CLK_CFG_SRC_SEL_SHIFT (24) +#define PMGR_CLK_CFG_DIVISOR_MASK (0x3F) + +#define PMGR_SPARE_COUNT (7) + +#define rPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_CLKCFG_CLK_DIVIDER_ACG_CFG_OFFSET)) + +#define PMGR_NCO_REG_STRIDE (PMGR_NCO_1_CLK_CFG_OFFSET - PMGR_NCO_0_CLK_CFG_OFFSET) + +#define rPMGR_NCO_CLK_CFG(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_CLK_CFG_OFFSET)) +#define rPMGR_NCO_DIV_INT(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_INT_OFFSET)) +#define rPMGR_NCO_DIV_FRAC_N1(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_FRAC_N1_OFFSET)) +#define rPMGR_NCO_DIV_FRAC_N2(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_FRAC_N2_OFFSET)) +#define rPMGR_NCO_DIV_FRAC_PRIME(_n) (*(volatile uint32_t *) (PMGR_BASE_ADDR + (_n) * PMGR_NCO_REG_STRIDE + PMGR_NCO_0_DIV_FRAC_PRIME_OFFSET)) + +#define PMGR_NCO_CLK_CFG_ENABLE (1 << PMGR_NCO_0_CLK_CFG_ENABLE_SHIFT) +#define PMGR_NCO_CLK_CFG_PENDING (1 << PMGR_NCO_0_CLK_CFG_PENDING_SHIFT) + +#define PMGR_NUM_NCO (5) + +#define kSOC_PERF_STATE_BYPASS (0) +#define kSOC_PERF_STATE_SECUREROM (kSOC_PERF_STATE_BYPASS + 1) +#define kSOC_PERF_STATE_IBOOT (kSOC_PERF_STATE_BYPASS + 2) +#define kSOC_PERF_STATE_VMIN (kSOC_PERF_STATE_IBOOT + 0) +#define kSOC_PERF_STATE_VNOM (kSOC_PERF_STATE_IBOOT + 1) + +#define kSOC_PERF_STATE_VMAX (kSOC_PERF_STATE_VNOM) + +#define kSOC_PERF_STATE_IBOOT_CNT (kSOC_PERF_STATE_VMAX + 1) +#define kSOC_PERF_STATE_MAX_CNT (14) + +#define rPMGR_SOC_PERF_STATE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_CTL_OFFSET)) +#define PMGR_SOC_PERF_STATE_CTL_PENDING_MASK (1 << PMGR_SOC_PERF_STATE_CTL_PENDING_SHIFT) + +#define PMGR_SOC_PERF_STATE_STRIDE (PMGR_SOC_PERF_STATE_ENTRY_1A_OFFSET - PMGR_SOC_PERF_STATE_ENTRY_0A_OFFSET) + +#define rPMGR_SOC_PERF_STATE_ENTRY_A(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0A_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) +#define rPMGR_SOC_PERF_STATE_ENTRY_B(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0B_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) +#define rPMGR_SOC_PERF_STATE_ENTRY_C(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0C_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) +#define rPMGR_SOC_PERF_STATE_ENTRY_D(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SOC_PERF_STATE_ENTRY_0D_OFFSET + (_n) * PMGR_SOC_PERF_STATE_STRIDE)) + +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK (PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_UMASK | PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_UMASK) +#define PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(_cfg, _src) (PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_SRC_SEL_INSRT(_src) | PMGR_SOC_PERF_STATE_ENTRY_0A_MCU_REF_CFG_SEL_INSRT(_cfg)) +#define PMGR_SOC_PERF_STATE_ENTRY_VID0(_src) (PMGR_SOC_PERF_STATE_ENTRY_0B_VID0_SRC_SEL_INSRT(_src)) +#define PMGR_SOC_PERF_STATE_ENTRY_VOLTAGE(_v) (PMGR_SOC_PERF_STATE_ENTRY_0C_VOLTAGE_INSRT(_v)) + +#define PMGR_SOC_PERF_STATE_ENTRY_COUNT (16) +// First two entries used by AOP Config Engine +#define PMGR_SOC_PERF_STATE_FIRST_ENTRY (PMGR_SOC_PERF_STATE_ENTRY_COUNT - kSOC_PERF_STATE_MAX_CNT) +#define PMGR_SOC_PERF_STATE_TO_ENTRY(_s) (PMGR_SOC_PERF_STATE_ENTRY_COUNT - (_s) - 1) + +#define kPMGR_GFX_STATE_MAX (16) +#define rPMGR_GFX_PERF_STATE_ENTRY_A(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + PMGR_GFX_PERF_STATE_ENTRY0A_OFFSET)) +#define rPMGR_GFX_PERF_STATE_ENTRY_B(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + PMGR_GFX_PERF_STATE_ENTRY0B_OFFSET)) +#define rPMGR_GFX_PERF_STATE_ENTRY_C(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + (_n) * 0x10 + PMGR_GFX_PERF_STATE_ENTRY0C_OFFSET)) +#define rPMGR_GFX_PERF_STATE_CTL (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_GFX_PERF_STATE_CTL_OFFSET)) +#define PMGR_GFX_PERF_STATE_CTL_ENABLE (1 << PMGR_GFX_PERF_STATE_CTL_ENABLE_SHIFT) +#define rPMGR_GFX_PERF_STATE_SOCHOT (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_GFX_PERF_STATE_SOCHOT_OFFSET)) + +#define rPMGR_PS(_x) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_PS_##_x##_PS_OFFSET)) + +#define PMGR_PS_RESET (1 << 31) +#define PMGR_PS_AUTO_PM_EN (1 << 28) +#define PMGR_PS_FORCE_NOACCESS (1 << 10) +#define PMGR_PS_ACTUAL_PS_SHIFT (4) +#define PMGR_PS_ACTUAL_PS_MASK (0xF) +#define PMGR_PS_MANUAL_PS_MASK (0xF) +#define PMGR_PS_RUN_MAX (0xF) +#define PMGR_PS_CLOCK_OFF (0x4) +#define PMGR_PS_POWER_OFF (0x0) + +#define rPMGR_VOLMAN_CTL (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CTL_OFFSET)) +#define rPMGR_VOLMAN_BUCK_MAP (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_BUCK_MAP_OFFSET)) +#define rPMGR_VOLMAN_SOC_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_SOC_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_GFX_SRAM_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_SRAM_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_CPU_SRAM_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_SRAM_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_GFX_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_CPU_VOLTAGE (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_VOLTAGE_OFFSET)) +#define rPMGR_VOLMAN_SOC_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_SOC_DELAY_OFFSET)) +#define rPMGR_VOLMAN_GFX_SRAM_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_SRAM_DELAY_OFFSET)) +#define rPMGR_VOLMAN_CPU_SRAM_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_SRAM_DELAY_OFFSET)) +#define rPMGR_VOLMAN_GFX_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_GFX_DELAY_OFFSET)) +#define rPMGR_VOLMAN_CPU_DELAY (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_VOLMAN_CPU_DELAY_OFFSET)) + +#define PMGR_VOLMAN_DISABLE_CPU_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_CPU_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_GFX_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_GFX_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_CPU_SRAM_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_CPU_SRAM_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_GFX_SRAM_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_GFX_SRAM_VOL_CHANGE_SHIFT) +#define PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE (1 << PMGR_VOLMAN_CTL_DISABLE_SOC_VOL_CHANGE_SHIFT) + +#define PMGR_VOLMAN_VOLTAGE_PENDING (1 << 31) + +#define rPMGR_EMA_FIXED_SOC0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_SOC0_OFFSET) +#define rPMGR_EMA_FIXED_SOC1 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_SOC1_OFFSET) +#define rPMGR_EMA_GPU_SRAM_GFX (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_GPU_SRAM_GFX_OFFSET) +#define rPMGR_EMA_FIXED_GFX (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_FIXED_GFX_OFFSET) +#define rPMGR_EMA_FIXED_SEP0 (*(volatile uint32_t *) (PMGR_BASE_ADDR + PMGR_EMA_FIXED_FIXED_SEP0_OFFSET) + +#define rPMGR_SCRATCH(_n) (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_SCRATCH_0_OFFSET + ((_n)*4))) +#define rPMGR_SCRATCH0 rPMGR_SCRATCH(0) /* Flags */ +#define rPMGR_SCRATCH1 rPMGR_SCRATCH(1) +#define rPMGR_SCRATCH2 rPMGR_SCRATCH(2) +#define rPMGR_SCRATCH3 rPMGR_SCRATCH(3) +#define rPMGR_SCRATCH4 rPMGR_SCRATCH(4) +#define rPMGR_SCRATCH5 rPMGR_SCRATCH(5) +#define rPMGR_SCRATCH6 rPMGR_SCRATCH(6) +#define rPMGR_SCRATCH7 rPMGR_SCRATCH(7) +#define rPMGR_SCRATCH8 rPMGR_SCRATCH(8) +// Use the symbolic functional name assignments below for these scratch registers +//#define rPMGR_SCRATCH9 rPMGR_SCRATCH(9) /* Memory info */ +//#define rPMGR_SCRATCH10 rPMGR_SCRATCH(10) /* Boot Nonce 0 */ +//#define rPMGR_SCRATCH11 rPMGR_SCRATCH(11) /* Boot Nonce 1 */ +//#define rPMGR_SCRATCH12 rPMGR_SCRATCH(12) /* Boot Manifest Hash 0 */ +//#define rPMGR_SCRATCH13 rPMGR_SCRATCH(13) /* Boot Manifest Hash 1 */ +//#define rPMGR_SCRATCH14 rPMGR_SCRATCH(14) /* Boot Manifest Hash 2 */ +//#define rPMGR_SCRATCH15 rPMGR_SCRATCH(15) /* Boot Manifest Hash 3 */ +//#define rPMGR_SCRATCH16 rPMGR_SCRATCH(16) /* Boot Manifest Hash 4 */ +//#define rPMGR_SCRATCH17 rPMGR_SCRATCH(17) /* Boot Manifest Hash 5 */ +//#define rPMGR_SCRATCH18 rPMGR_SCRATCH(18) /* Boot Manifest Hash 6 */ +//#define rPMGR_SCRATCH19 rPMGR_SCRATCH(19) /* Boot Manifest Hash 7 */ +//#define rPMGR_SCRATCH20 rPMGR_SCRATCH(20) /* Boot Manifest Hash 8 */ +//#define rPMGR_SCRATCH21 rPMGR_SCRATCH(21) /* Boot Manifest Hash 9 */ +//#define rPMGR_SCRATCH22 rPMGR_SCRATCH(22) /* Boot Manifest Hash 10 */ +//#define rPMGR_SCRATCH23 rPMGR_SCRATCH(23) /* Boot Manifest Hash 11 */ + +#define rPMGR_SCRATCH_MEM_INFO rPMGR_SCRATCH(9) +#define rPMGR_SCRATCH_BOOT_NONCE_0 rPMGR_SCRATCH(10) +#define rPMGR_SCRATCH_BOOT_NONCE_1 rPMGR_SCRATCH(11) +#define rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST rPMGR_SCRATCH(12) +#define rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST rPMGR_SCRATCH(23) +#define PMGR_SCRATCH_BOOT_MANIFEST_REGISTERS (384 / 32) + +#define rMINIPMGR_SCRATCH(_n) (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_SCRATCH_OFFSET + ((_n)*4))) +#define rMINIPMGR_SCRATCH0 rMINIPMGR_SCRATCH(0) +#define rMINIPMGR_SCRATCH1 rMINIPMGR_SCRATCH(1) /* Consistent debug root pointer */ +#define rMINIPMGR_SCRATCH2 rMINIPMGR_SCRATCH(2) +#define rMINIPMGR_SCRATCH3 rMINIPMGR_SCRATCH(3) +#define rMINIPMGR_SCRATCH4 rMINIPMGR_SCRATCH(4) +#define rMINIPMGR_SCRATCH5 rMINIPMGR_SCRATCH(5) +#define rMINIPMGR_SCRATCH6 rMINIPMGR_SCRATCH(6) +#define rMINIPMGR_SCRATCH7 rMINIPMGR_SCRATCH(7) +#define rMINIPMGR_SCRATCH8 rMINIPMGR_SCRATCH(8) +#define rMINIPMGR_SCRATCH9 rMINIPMGR_SCRATCH(9) +#define rMINIPMGR_SCRATCH10 rMINIPMGR_SCRATCH(10) +#define rMINIPMGR_SCRATCH11 rMINIPMGR_SCRATCH(11) + +#define rPMGR_THERMAL0_CTL0_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL0_SET_OFFSET)) +#define rPMGR_THERMAL0_CTL0_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL0_CLR_OFFSET)) +#define rPMGR_THERMAL0_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL1_OFFSET)) +#define rPMGR_THERMAL0_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_CTL2_OFFSET)) +#define rPMGR_THERMAL0_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_STATUS_OFFSET)) +#define rPMGR_THERMAL0_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_PARAM_OFFSET)) +#define rPMGR_THERMAL0_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_RDBK0_OFFSET)) +#define rPMGR_THERMAL0_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_RDBK1_OFFSET)) +#define rPMGR_THERMAL0_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_SUM_OFFSET)) +#define rPMGR_THERMAL0_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_SUM_CNT_OFFSET)) +#define rPMGR_THERMAL0_PIECE0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_PIECE0_OFFSET)) +#define rPMGR_THERMAL0_PIECE1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_PIECE1_OFFSET)) +#define rPMGR_THERMAL0_PIECE2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_PIECE2_OFFSET)) +#define rPMGR_THERMAL0_ALARM0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM0_OFFSET)) +#define rPMGR_THERMAL0_ALARM1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM1_OFFSET)) +#define rPMGR_THERMAL0_ALARM2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM2_OFFSET)) +#define rPMGR_THERMAL0_ALARM3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_ALARM3_OFFSET)) +#define rPMGR_THERMAL0_FAILSAFE_TRIP_TEMP_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_FAILSAFE_TRIP_TEMP_0_OFFSET)) +#define rPMGR_THERMAL0_FAILSAFE_TRIP_TEMP_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_0_FAILSAFE_TRIP_TEMP_1_OFFSET)) +#define rPMGR_THERMAL1_CTL0_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL0_SET_OFFSET)) +#define rPMGR_THERMAL1_CTL0_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL0_CLR_OFFSET)) +#define rPMGR_THERMAL1_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL1_OFFSET)) +#define rPMGR_THERMAL1_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_CTL2_OFFSET)) +#define rPMGR_THERMAL1_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_STATUS_OFFSET)) +#define rPMGR_THERMAL1_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_PARAM_OFFSET)) +#define rPMGR_THERMAL1_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_RDBK0_OFFSET)) +#define rPMGR_THERMAL1_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_RDBK1_OFFSET)) +#define rPMGR_THERMAL1_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_SUM_OFFSET)) +#define rPMGR_THERMAL1_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_SUM_CNT_OFFSET)) +#define rPMGR_THERMAL1_PIECE0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_PIECE0_OFFSET)) +#define rPMGR_THERMAL1_PIECE1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_PIECE1_OFFSET)) +#define rPMGR_THERMAL1_PIECE2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_PIECE2_OFFSET)) +#define rPMGR_THERMAL1_ALARM0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM0_OFFSET)) +#define rPMGR_THERMAL1_ALARM1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM1_OFFSET)) +#define rPMGR_THERMAL1_ALARM2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM2_OFFSET)) +#define rPMGR_THERMAL1_ALARM3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_ALARM3_OFFSET)) +#define rPMGR_THERMAL1_FAILSAFE_TRIP_TEMP_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_FAILSAFE_TRIP_TEMP_0_OFFSET)) +#define rPMGR_THERMAL1_FAILSAFE_TRIP_TEMP_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_1_FAILSAFE_TRIP_TEMP_1_OFFSET)) +#define rPMGR_THERMAL2_CTL0_SET (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL0_SET_OFFSET)) +#define rPMGR_THERMAL2_CTL0_CLR (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL0_CLR_OFFSET)) +#define rPMGR_THERMAL2_CTL1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL1_OFFSET)) +#define rPMGR_THERMAL2_CTL2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_CTL2_OFFSET)) +#define rPMGR_THERMAL2_STATUS (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_STATUS_OFFSET)) +#define rPMGR_THERMAL2_PARAM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_PARAM_OFFSET)) +#define rPMGR_THERMAL2_RDBK0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_RDBK0_OFFSET)) +#define rPMGR_THERMAL2_RDBK1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_RDBK1_OFFSET)) +#define rPMGR_THERMAL2_SUM (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_SUM_OFFSET)) +#define rPMGR_THERMAL2_SUM_CNT (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_SUM_CNT_OFFSET)) +#define rPMGR_THERMAL2_PIECE0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_PIECE0_OFFSET)) +#define rPMGR_THERMAL2_PIECE1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_PIECE1_OFFSET)) +#define rPMGR_THERMAL2_PIECE2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_PIECE2_OFFSET)) +#define rPMGR_THERMAL2_ALARM0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM0_OFFSET)) +#define rPMGR_THERMAL2_ALARM1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM1_OFFSET)) +#define rPMGR_THERMAL2_ALARM2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM2_OFFSET)) +#define rPMGR_THERMAL2_ALARM3 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_ALARM3_OFFSET)) +#define rPMGR_THERMAL2_FAILSAFE_TRIP_TEMP_0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_FAILSAFE_TRIP_TEMP_0_OFFSET)) +#define rPMGR_THERMAL2_FAILSAFE_TRIP_TEMP_1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_THERMAL_2_FAILSAFE_TRIP_TEMP_1_OFFSET)) + +#define PMGR_THERMAL0_PIECE0(_c, _o, _s) (PMGR_THERMAL_0_PIECE0_START_CODE_INSRT(_c) | PMGR_THERMAL_0_PIECE0_OFFSET_INSRT(_o) | PMGR_THERMAL_0_PIECE0_SLOPE_INSRT(_s)) +#define PMGR_THERMAL0_PIECE1(_c, _o, _s) (PMGR_THERMAL_0_PIECE1_START_CODE_INSRT(_c) | PMGR_THERMAL_0_PIECE1_OFFSET_INSRT(_o) | PMGR_THERMAL_0_PIECE1_SLOPE_INSRT(_s)) +#define PMGR_THERMAL0_PIECE2(_c, _o, _s) (PMGR_THERMAL_0_PIECE2_START_CODE_INSRT(_c) | PMGR_THERMAL_0_PIECE2_OFFSET_INSRT(_o) | PMGR_THERMAL_0_PIECE2_SLOPE_INSRT(_s)) +#define PMGR_THERMAL1_PIECE0(_c, _o, _s) (PMGR_THERMAL_1_PIECE0_START_CODE_INSRT(_c) | PMGR_THERMAL_1_PIECE0_OFFSET_INSRT(_o) | PMGR_THERMAL_1_PIECE0_SLOPE_INSRT(_s)) +#define PMGR_THERMAL1_PIECE1(_c, _o, _s) (PMGR_THERMAL_1_PIECE1_START_CODE_INSRT(_c) | PMGR_THERMAL_1_PIECE1_OFFSET_INSRT(_o) | PMGR_THERMAL_1_PIECE1_SLOPE_INSRT(_s)) +#define PMGR_THERMAL1_PIECE2(_c, _o, _s) (PMGR_THERMAL_1_PIECE2_START_CODE_INSRT(_c) | PMGR_THERMAL_1_PIECE2_OFFSET_INSRT(_o) | PMGR_THERMAL_1_PIECE2_SLOPE_INSRT(_s)) +#define PMGR_THERMAL2_PIECE0(_c, _o, _s) (PMGR_THERMAL_2_PIECE0_START_CODE_INSRT(_c) | PMGR_THERMAL_2_PIECE0_OFFSET_INSRT(_o) | PMGR_THERMAL_2_PIECE0_SLOPE_INSRT(_s)) +#define PMGR_THERMAL2_PIECE1(_c, _o, _s) (PMGR_THERMAL_2_PIECE1_START_CODE_INSRT(_c) | PMGR_THERMAL_2_PIECE1_OFFSET_INSRT(_o) | PMGR_THERMAL_2_PIECE1_SLOPE_INSRT(_s)) +#define PMGR_THERMAL2_PIECE2(_c, _o, _s) (PMGR_THERMAL_2_PIECE2_START_CODE_INSRT(_c) | PMGR_THERMAL_2_PIECE2_OFFSET_INSRT(_o) | PMGR_THERMAL_2_PIECE2_SLOPE_INSRT(_s)) + +#define rPMGR_SOC_TVM_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_CTL_OFFSET)) +#define rPMGR_SOC_TVM_THRESH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH0_OFFSET)) +#define rPMGR_SOC_TVM_THRESH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH1_OFFSET)) +#define rPMGR_SOC_TVM_THRESH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH2_OFFSET)) +#define rPMGR_SOC_TVM_TEMP0_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP0_CFG_OFFSET)) +#define rPMGR_SOC_TVM_TEMP1_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP1_CFG_OFFSET)) +#define rPMGR_SOC_TVM_DEBUG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG0_OFFSET)) +#define rPMGR_SOC_TVM_DEBUG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG1_OFFSET)) +#define rPMGR_SOC_TVM_DEBUG2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG2_OFFSET)) + +#define rPMGR_GFX_TVM_CTL (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_CTL_OFFSET)) +#define rPMGR_GFX_TVM_THRESH0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH0_OFFSET)) +#define rPMGR_GFX_TVM_THRESH1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH1_OFFSET)) +#define rPMGR_GFX_TVM_THRESH2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_THRESH2_OFFSET)) +#define rPMGR_GFX_TVM_TEMP0_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP0_CFG_OFFSET)) +#define rPMGR_GFX_TVM_TEMP1_CFG (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_TEMP1_CFG_OFFSET)) +#define rPMGR_GFX_TVM_DEBUG0 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG0_OFFSET)) +#define rPMGR_GFX_TVM_DEBUG1 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG1_OFFSET)) +#define rPMGR_GFX_TVM_DEBUG2 (*(volatile u_int32_t *)(PMGR_BASE_ADDR + PMGR_TVM_DEBUG2_OFFSET)) + +#define PMGR_TVM_THRESH(_t) ((_t) & 0x1FF) +#define PMGR_TVM_TEMP_CFG_MAX_OFFSET(_mo) (((_mo) & 0x1FF) << 16) +#define PMGR_TVM_TEMP_CFG_MIN_OFFSET(_mo) (((_mo) & 0x1FF) << 0) + +#define rPMGR_MISC_CFG_ACG (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_MISC_CFG_ACG_OFFSET)) + +#define rPMGR_MISC_SPARE0 (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_MISC_SPARE_SPARE0_OFFSET)) + +#define rPMGR_DEBUG_PMGR_DEBUG20 (*(volatile uint32_t *)(PMGR_BASE_ADDR + PMGR_DEBUG_20_OFFSET)) +#define rPMGR_PCIE_REFCLK_GOOD rPMGR_DEBUG_PMGR_DEBUG20 +#define PMGR_PCIE_REFCLK_GOOD_UMASK (PMGR_DEBUG_20_CLKGEN_PMGR_PCIE_REF_CLK_GOOD_UMASK) + +#define rPMGR_CHIP_WDOG_TMR (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_TIMER_OFFSET)) +#define rPMGR_CHIP_WDOG_RST_CNT (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_RESET_COUNT_OFFSET)) +#define rPMGR_CHIP_WDOG_INTR_CNT (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_INTERRUPT_COUNT_OFFSET)) +#define rPMGR_CHIP_WDOG_CTL (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_CHIP_WATCHDOG_CONTROL_OFFSET)) +#define rPMGR_SYS_WDOG_TMR (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_TIMER_OFFSET)) +#define rPMGR_SYS_WDOG_RST_CNT (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_RESET_COUNT_OFFSET)) +#define rPMGR_SYS_WDOG_CTL (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_WATCHDOG_SYS_WATCHDOG_CONTROL_OFFSET)) + +#define rMINIPMGR_LPPLL_CTL (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_LPPLL_CTL_OFFSET)) +#define MINIPMGR_LPPLL_CTL_ENABLE (1 << MINIPMGR_LPPLL_CTL_ENABLE_SHIFT) +#define MINIPMGR_LPPLL_CTL_PENDING (1 << MINIPMGR_LPPLL_CTL_PENDING_SHIFT) +#define rMINIPMGR_LPPLL_CFG (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_LPPLL_CFG_OFFSET)) + +#define rMINIPMGR_CLK_CFG(_x) (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_##_x##_CLK_CFG_OFFSET)) +#define rMINIPMGR_CLK_DIVIDER_ACG_CFG (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_CLKCFG_CLK_DIVIDER_ACG_CFG_OFFSET)) + +#define rMINIPMGR_PS(_x) (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_PS_##_x##_PS_OFFSET)) + +#define rMINIPMGR_MISC_CFG_ACG (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_MISC_CFG_ACG_OFFSET)) +#define rMINIPMGR_MISC_CFG_CPU (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_MINI_MISC_CFG_CPU_CFG_OFFSET)) + +#if SUB_PLATFORM_T8010 +enum { + PMGR_CLK_OSC = 0, // 0x00 + PMGR_CLK_PLL0, // 0x01 + PMGR_CLK_PLL1, // 0x02 + PMGR_CLK_PLL2, // 0x03 + PMGR_CLK_PLL3, // 0x04 + PMGR_CLK_PLL4, // 0x05 + PMGR_CLK_PLL5, // 0x06 + PMGR_CLK_PLL_PCIE, // 0x07 + PMGR_CLK_CPU, // 0x08 + PMGR_CLK_GFX_FENDER, // 0x09 + PMGR_CLK_FIRST = PMGR_CLK_GFX_FENDER, + PMGR_CLK_MCU_REF, // 0x0A + PMGR_CLK_PMP, // 0x0B + PMGR_CLK_TEMP_MIPI_DSI, // 0x0C + PMGR_CLK_NCO_REF0, // 0x0D + PMGR_CLK_NCO_REF1, // 0x0E + PMGR_CLK_NCO_ALG0, // 0x0F + PMGR_CLK_NCO_ALG1, // 0x10 + PMGR_CLK_HSICPHY_REF_12M, // 0x11 + PMGR_CLK_USB480_0, // 0x12 + PMGR_CLK_USB_OHCI_48M, // 0x13 + PMGR_CLK_USB, // 0x14 + PMGR_CLK_USB_FREE_60M, // 0x15 + PMGR_CLK_SIO_C, // 0x16 + PMGR_CLK_SIO_P, // 0x17 + PMGR_CLK_SIO_AES, // 0x18 + PMGR_CLK_HFD, // 0x19 + PMGR_CLK_ISP_C, // 0x1A + PMGR_CLK_ISP_AHFD, // 0x1B + PMGR_CLK_ISP_PEARL, // 0x1C + PMGR_CLK_ISP, // 0x1D + PMGR_CLK_ISP_SENSOR0_REF, // 0x1E + PMGR_CLK_ISP_SENSOR1_REF, // 0x1F + PMGR_CLK_ISP_SENSOR2_REF, // 0x20 + PMGR_CLK_VDEC, // 0x21 + PMGR_CLK_VENC, // 0x22 + PMGR_CLK_VID0, // 0x23 + PMGR_CLK_DISP0, // 0x24 + PMGR_CLK_AJPEG_IP, // 0x25 + PMGR_CLK_AJPEG_WRAP, // 0x26 + PMGR_CLK_MSR, // 0x27 + PMGR_CLK_FAST_AF, // 0x28 + PMGR_CLK_SLOW_AF, // 0x29 + PMGR_CLK_SBR, // 0x2A + PMGR_CLK_MCA0_M, // 0x2B + PMGR_CLK_MCA1_M, // 0x2C + PMGR_CLK_MCA2_M, // 0x2D + PMGR_CLK_MCA3_M, // 0x2E + PMGR_CLK_MCA4_M, // 0x2F + PMGR_CLK_SEP, // 0x30 + PMGR_CLK_GPIO, // 0x31 + PMGR_CLK_SPI0_N, // 0x32 + PMGR_CLK_SPI1_N, // 0x33 + PMGR_CLK_SPI2_N, // 0x34 + PMGR_CLK_SPI3_N, // 0x35 + PMGR_CLK_TMPS, // 0x36 + PMGR_CLK_CPU_UVD, // 0x37 + PMGR_CLK_GFX_UVD, // 0x38 + PMGR_CLK_SOC_UVD, // 0x39 + PMGR_CLK_LPDP_RX_REF, // 0x3A + PMGR_CLK_LAST = PMGR_CLK_LPDP_RX_REF, + PMGR_CLK_S0, // 0x3B + PMGR_CLK_SPARE_FIRST = PMGR_CLK_S0, + PMGR_CLK_S1, // 0x3C + PMGR_CLK_S2, // 0x3D + PMGR_CLK_S3, // 0x3E + PMGR_CLK_ISP_REF0, // 0x3F + PMGR_CLK_ISP_REF1, // 0x40 + PMGR_CLK_ISP_REF2, // 0x41 + PMGR_CLK_SPARE_LAST = PMGR_CLK_ISP_REF2, + PMGR_CLK_LPO, // 0x42 + PMGR_CLK_AOP, // 0x43 + PMGR_CLK_MINI_FIRST = PMGR_CLK_AOP, + PMGR_CLK_UART0, // 0x44 + PMGR_CLK_UART1, // 0x45 + PMGR_CLK_UART2, // 0x46 + PMGR_CLK_AOP_MCA0_M, // 0x47 + PMGR_CLK_I2CM, // 0x48 + PMGR_CLK_PDM_REF, // 0x49 + PMGR_CLK_SENSE_2X, // 0x4A + PMGR_CLK_DETECT, // 0x4B + PMGR_CLK_PROXY_FABRIC, // 0x4C + PMGR_CLK_PROXY_MCU_REF, // 0x4D + PMGR_CLK_MINI_LAST = PMGR_CLK_PROXY_MCU_REF, + PMGR_CLK_COUNT, // 0x4E + PMGR_CLK_NOT_SUPPORTED +}; + +#else +#error "Unknown platform" +#endif + +//////////////////////////////////////////////////////////// +// +// CCC specific +// +//////////////////////////////////////////////////////////// + +#define rACC_PRE_TD_TMR (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PRE_TD_TMR_OFFSET)) +#define rACC_PRE_FLUSH_TMR (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PRE_FLUSH_TMR_OFFSET)) + +#define rACC_APSC_SCR (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_APSC_SCR_OFFSET)) +#define ACC_APSC_PENDING (1 << ACC_PWRCTL_APSC_SCR_MANUAL_PENDING_SHIFT) +#define ACC_APSC_MANUAL_CHANGE(_d) ((1 << ACC_PWRCTL_APSC_SCR_MANUAL_CHANGE_SHIFT) | ACC_PWRCTL_APSC_SCR_MANUAL_ST_INSRT((uint64_t)_d)) + +#define rACC_DVFM_CFG (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_CFG_OFFSET)) + +#define rACC_DVFM_SCR (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_SCR_OFFSET)) // 64-bit +#define ACC_DVFM_SCR_TEMPSENSORMODE (ACC_PWRCTL_DVFM_MODE_INSRT((uint64_t)1)) + +#define rACC_DVFM_CFG_SEL (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_CFG_SEL_OFFSET)) + +#define rACC_DVFM_CFG1 (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_DVFM_CFG1_OFFSET)) + +#define kDVFM_STATE_BYPASS (0) +#define kDVFM_STATE_SECUREROM (kDVFM_STATE_BYPASS + 1) +#define kDVFM_STATE_IBOOT (kDVFM_STATE_BYPASS + 2) +#define kDVFM_STATE_V0 (kDVFM_STATE_IBOOT + 0) + +#define kDVFM_STATE_VMAX (kDVFM_STATE_IBOOT) // !!! FIXME !!! (kDVFM_STATE_V5) + +#define kDVFM_STATE_VNOM (kDVFM_STATE_V0) +#define kDVFM_STATE_VBOOST (kDVFM_STATE_VNOM + 1) + +#define kDVFM_STATE_IBOOT_CNT (kDVFM_STATE_VMAX + 1) + +#define kVOLTAGE_STATES1_COUNT (kDVFM_STATE_VMAX - kDVFM_STATE_V0 + 1) +#define kVOLTAGE_STATES1_SIZE (kVOLTAGE_STATES1_COUNT*2) // Minimum size of voltage-state1 property in devicetree + +#define kDVFM_STATE_MAX_CNT (16) + +// TODO: Remove these when added to EmbeddedHeaders +#define ACC_PWRCTL_DVFM_ST0_PRE_DIV_P_INSRT(f) ((((uint64_t)f) & 0x1f) << 13) +#define ACC_PWRCTL_DVFM_ST0_FBK_DIV_M_INSRT(f) ((((uint64_t)f) & 0x1ff) << 4) +#define ACC_PWRCTL_DVFM_ST0_PST_DIV_S_INSRT(f) ((((uint64_t)f) & 0xf) << 0) + +#define ACC_DVFM_ST_STRIDE (ACC_DVFM_ST1_OFFSET - ACC_DVFM_ST0_OFFSET) + +#define rACC_DVFM_ST(_n) (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_DVFM_ST0_OFFSET + ((_n) * ACC_DVFM_ST_STRIDE))) +#define ACC_DVFM_ST_SAFE_VOL_INSRT(_sv) (ACC_DVFM_ST0_SAFE_VOL_INSRT((uint64_t)_sv)) +#define ACC_DVFM_ST_SAFE_VOL_XTRCT(_sv) (ACC_DVFM_ST0_SAFE_VOL_XTRCT((uint64_t)_sv)) +#define ACC_DVFM_ST_VOL_ADJ3(_va) (ACC_DVFM_ST0_VOL_ADJ3_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_VOL_ADJ2(_va) (ACC_DVFM_ST0_VOL_ADJ2_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_VOL_ADJ1(_va) (ACC_DVFM_ST0_VOL_ADJ1_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_VOL_ADJ0(_va) (ACC_DVFM_ST0_VOL_ADJ0_INSRT((uint64_t)_va)) +#define ACC_DVFM_ST_CORE_TYP(_ct) (ACC_DVFM_ST0_CORE_TYP_INSRT((uint64_t)_ct)) +#define ACC_DVFM_ST_VOL_BYP(_vb) (ACC_DVFM_ST0_VOL_BYP_INSRT((uint64_t)_vb)) +#define ACC_DVFM_ST_CLK_SRC(_s) (ACC_DVFM_ST0_CLK_SRC_INSRT((uint64_t)_s)) +#define ACC_DVFM_ST_MIG_DIV_S(_s) (ACC_DVFM_ST0_MIG_DIV_S_INSRT((uint64_t)_s)) +#define ACC_DVFM_ST_FCW_FRAC_INSRT(_f) (ACC_DVFM_ST0_FCW_FRAC_INSRT((uint64_t)_f)) +#define ACC_DVFM_ST_FCW_INT_INSRT(_i) (ACC_DVFM_ST0_FCW_INT_INSRT((uint64_t)_i)) +#define ACC_DVFM_ST_PST_DIV_S_INSRT(_s) (ACC_DVFM_ST0_PST_DIV_S_INSRT((uint64_t)_s)) +#define ACC_DVFM_ST_FCW_FRAC_XTRCT(_f) (ACC_DVFM_ST0_FCW_FRAC_XTRCT((uint64_t)_f)) +#define ACC_DVFM_ST_FCW_INT_XTRCT(_i) (ACC_DVFM_ST0_FCW_INT_XTRCT((uint64_t)_i)) +#define ACC_DVFM_ST_PST_DIV_S_XTRCT(_s) (ACC_DVFM_ST0_PST_DIV_S_XTRCT((uint64_t)_s)) + +#define rACC_DVFM_ST_EXT(_n) (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_DVFM_ST0_EXT_OFFSET + ((_n) * ACC_DVFM_ST_STRIDE))) +#define ACC_DVFM_ST_BIU_DIV_HI_VOL(_d) (ACC_DVFM_ST0_EXT_BIU_DIV4_HI_VOL_INSRT((uint64_t)(_d))) +#define ACC_DVFM_ST_BIU_DIV_LO_VOL(_d) (ACC_DVFM_ST0_EXT_BIU_DIV4_LO_VOL_INSRT((uint64_t)(_d))) +#define ACC_DVFM_ST_DVMR_MAX_WGT(_w) (ACC_DVFM_ST0_EXT_DVMR_MAX_WGT_INSRT((uint64_t)(_w))) +#define ACC_DVFM_ST_SRAM_VOL(_v) (ACC_DVFM_ST0_EXT_SRAM_VOL_INSRT((uint64_t)(_v))) +#define ACC_DVFM_ST_DVFM_MAX_ADJ(_a) (ACC_DVFM_ST0_EXT_MAX_ADJ_INSRT((uint64_t)(_a))) +#define ACC_DVFM_ST_DVMR_ADJ2(_a) (ACC_DVFM_ST0_EXT_DVMR_ADJ2_INSRT((uint64_t)(_a))) +#define ACC_DVFM_ST_DVMR_ADJ1(_a) (ACC_DVFM_ST0_EXT_DVMR_ADJ1_INSRT((uint64_t)(_a))) +#define ACC_DVFM_ST_DVMR_ADJ0(_a) (ACC_DVFM_ST0_EXT_DVMR_ADJ0_INSRT((uint64_t)(_a))) + +#define rACC_DVFM_ST_EXT2(_n) (*(volatile uint64_t *)(ACC_BASE_ADDR + ACC_DVFM_ST0_EXT2_OFFSET + ((_n) * ACC_DVFM_ST_STRIDE))) +#define ACC_DVFM_ST_ADCLK_EN(_a) (ACC_DVFM_ST0_EXT2_ADCLK_EN_INSRT((uint64_t)(_a))) + +#define rACC_PLL_SCR1 (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PLL_SCR1_OFFSET)) +#define rACC_PLL_CFG2 (*(volatile uint32_t *)(ACC_BASE_ADDR + ACC_PWRCTL_PLL_CFG2_OFFSET)) +#define rACC_DVMR_SCR (*(volatile uint64_t *)(ACC_BASE_ADDR + DVMR_SCR_OFFSET)) + +#define rMINIPMGR_SIO_AES_DISABLE (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SIO_AES_DISABLE_OFFSET)) +#define rMINIPMGR_SECURITY_GPIO_STRAPS (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_GPIO_STRAPS_OFFSET)) +#define rMINIPMGR_SET_ONLY (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SET_ONLY_OFFSET)) +#define MINIPMGR_SET_ONLY_MIX_N_MATCH (1 << 31) +#define rMINIPMGR_SEAL_DATA_A_FIRST (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SEAL_DATA_A0_OFFSET)) +#define rMINIPMGR_SEAL_DATA_A_LAST (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SEAL_DATA_A7_OFFSET)) +#define rMINIPMGR_SEAL_CTL_A (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SEAL_CTL_A_OFFSET)) +#define rMINIPMGR_SEAL_DATA_B_FIRST (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SEAL_DATA_B0_OFFSET)) +#define rMINIPMGR_SEAL_DATA_B_LAST (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SEAL_DATA_B7_OFFSET)) +#define rMINIPMGR_SEAL_CTL_B (*(volatile uint32_t *)(AOP_MINIPMGR_BASE_ADDR + MINIPMGR_SECURITY_SEAL_CTL_B_OFFSET)) + +#define rACC_THRM0_CTL0_SET (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM0_CTL0_SET_OFFSET)) +#define rACC_THRM0_CTL1 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM0_CTL1_OFFSET)) +#define rACC_THRM0_PARAM (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM0_PARAM_OFFSET)) +#define rACC_THRM0_PIECE0 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM0_PIECE0_OFFSET)) +#define rACC_THRM0_PIECE1 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM0_PIECE1_OFFSET)) +#define rACC_THRM0_PIECE2 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM0_PIECE2_OFFSET)) + +#define rACC_THRM1_CTL0_SET (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM1_CTL0_SET_OFFSET)) +#define rACC_THRM1_CTL1 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM1_CTL1_OFFSET)) +#define rACC_THRM1_PARAM (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM1_PARAM_OFFSET)) +#define rACC_THRM1_PIECE0 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM1_PIECE0_OFFSET)) +#define rACC_THRM1_PIECE1 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM1_PIECE1_OFFSET)) +#define rACC_THRM1_PIECE2 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM1_PIECE2_OFFSET)) + +#define rACC_THRM2_CTL0_SET (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM2_CTL0_SET_OFFSET)) +#define rACC_THRM2_CTL1 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM2_CTL1_OFFSET)) +#define rACC_THRM2_PARAM (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM2_PARAM_OFFSET)) +#define rACC_THRM2_PIECE0 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM2_PIECE0_OFFSET)) +#define rACC_THRM2_PIECE1 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM2_PIECE1_OFFSET)) +#define rACC_THRM2_PIECE2 (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_THRM2_PIECE2_OFFSET)) + +#define rACC_DVFM_FSHOT_IDX (*(volatile uint64_t*)(ACC_BASE_ADDR + ACC_THERMAL_DVFM_FSHOT_IDX_OFFSET)) + +#define ACC_THRM0_PIECE0(_c, _o, _s) (ACC_THERMAL_THRM0_PIECE0_START_CODE_INSRT(_c) | ACC_THERMAL_THRM0_PIECE0_OFFSET_INSRT(_o) | ACC_THERMAL_THRM0_PIECE0_SLOPE_INSRT(_s)) +#define ACC_THRM0_PIECE1(_c, _o, _s) (ACC_THERMAL_THRM0_PIECE1_START_CODE_INSRT(_c) | ACC_THERMAL_THRM0_PIECE1_OFFSET_INSRT(_o) | ACC_THERMAL_THRM0_PIECE1_SLOPE_INSRT(_s)) +#define ACC_THRM0_PIECE2(_c, _o, _s) (ACC_THERMAL_THRM0_PIECE2_START_CODE_INSRT(_c) | ACC_THERMAL_THRM0_PIECE2_OFFSET_INSRT(_o) | ACC_THERMAL_THRM0_PIECE2_SLOPE_INSRT(_s)) +#define ACC_THRM1_PIECE0(_c, _o, _s) (ACC_THERMAL_THRM1_PIECE0_START_CODE_INSRT(_c) | ACC_THERMAL_THRM1_PIECE0_OFFSET_INSRT(_o) | ACC_THERMAL_THRM1_PIECE0_SLOPE_INSRT(_s)) +#define ACC_THRM1_PIECE1(_c, _o, _s) (ACC_THERMAL_THRM1_PIECE1_START_CODE_INSRT(_c) | ACC_THERMAL_THRM1_PIECE1_OFFSET_INSRT(_o) | ACC_THERMAL_THRM1_PIECE1_SLOPE_INSRT(_s)) +#define ACC_THRM1_PIECE2(_c, _o, _s) (ACC_THERMAL_THRM1_PIECE2_START_CODE_INSRT(_c) | ACC_THERMAL_THRM1_PIECE2_OFFSET_INSRT(_o) | ACC_THERMAL_THRM1_PIECE2_SLOPE_INSRT(_s)) +#define ACC_THRM2_PIECE0(_c, _o, _s) (ACC_THERMAL_THRM2_PIECE0_START_CODE_INSRT(_c) | ACC_THERMAL_THRM2_PIECE0_OFFSET_INSRT(_o) | ACC_THERMAL_THRM2_PIECE0_SLOPE_INSRT(_s)) +#define ACC_THRM2_PIECE1(_c, _o, _s) (ACC_THERMAL_THRM2_PIECE1_START_CODE_INSRT(_c) | ACC_THERMAL_THRM2_PIECE1_OFFSET_INSRT(_o) | ACC_THERMAL_THRM2_PIECE1_SLOPE_INSRT(_s)) +#define ACC_THRM2_PIECE2(_c, _o, _s) (ACC_THERMAL_THRM2_PIECE2_START_CODE_INSRT(_c) | ACC_THERMAL_THRM2_PIECE2_OFFSET_INSRT(_o) | ACC_THERMAL_THRM2_PIECE2_SLOPE_INSRT(_s)) + +//////////////////////////////////////////////////////////// +// +// Externs +// +//////////////////////////////////////////////////////////// + +extern void pmgr_update_device_tree(DTNode *pmgr_node); +extern void pmgr_gfx_update_device_tree(DTNode *gfx_node); + +#endif /* ! __PLATFORM_SOC_PMGR_H */ diff --git a/platform/t8010/include/platform/soc/reconfig.h b/platform/t8010/include/platform/soc/reconfig.h new file mode 100644 index 0000000..14692fd --- /dev/null +++ b/platform/t8010/include/platform/soc/reconfig.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_RECONFIG_H +#define __PLATFORM_RECONFIG_H + +#include +#include +#include + +#define rAOP_GLOBAL(_p) (*(volatile uint32_t *)(AOP_BASE_ADDR + (_p))) +#define rRECONFIG_RAM_BASE(base, count) *(volatile uint32_t *)((base) + ((count) * 4)) +#define rRECONFIG_RAM_BASE_BYTE(base, count, count_bytes) *(volatile uint32_t *)((base) + ((count) * 4) + (count_bytes)) + +#define ALIGNMENT_MASK_1KB ~(0x3FF) +#define RECONFIG_NUMBER_OF_REGS(regs) ((((regs) - 1) & 0xF) << 2) +#define AOP_CFG_TABLE (AOP_RECONFIG_REGION_BASE_ADDR) +#define WRITE_OFFSETS(addr, values) (((addr) >> 2) & 0xFF) << (((values) % 4) * 8) +#define MAX_WRITE_REGS 16 + +// SRAM sequences +#define AOP_DDR_S2R_AOP_PRE_BASE_ADDR (AOP_RECONFIG_REGION_BASE_ADDR + 0x100) +#define AOP_DDR_S2R_AOP_PRE_MAX_SIZE 0x200 + +#define AOP_DDR_S2R_AOP_POST_BASE_ADDR (AOP_DDR_S2R_AOP_PRE_BASE_ADDR + AOP_DDR_S2R_AOP_PRE_MAX_SIZE) +#define AOP_DDR_S2R_AOP_POST_MAX_SIZE 0x100 + +#define S2R_AOP_AOP_DDR_PRE_BASE_ADDR (AOP_DDR_S2R_AOP_POST_BASE_ADDR + AOP_DDR_S2R_AOP_POST_MAX_SIZE) +#define S2R_AOP_AOP_DDR_PRE_MAX_SIZE 0x100 + +#define S2R_AOP_AOP_DDR_POST_BASE_ADDR (S2R_AOP_AOP_DDR_PRE_BASE_ADDR + S2R_AOP_AOP_DDR_PRE_MAX_SIZE) +#define S2R_AOP_AOP_DDR_POST_MAX_SIZE 0x3000 + +#define AOP_RECONFIG_REGION_USED (AOP_RECONFIG_REGION_BASE_ADDR - S2R_AOP_AOP_DDR_PRE_BASE_ADDR + S2R_AOP_AOP_DDR_POST_MAX_SIZE) + +#if AOP_RECONFIG_REGION_USED > AOP_RECONFIG_REGION_SIZE +#error "Reconfig engine programs overflow their SRAM allocation +#endif + +// DRAM sequences +#define AWAKE_AOP_DDR_PRE_BASE_ADDR (DRAM_CONFIG_SEQ_BASE) +#define AWAKE_AOP_DDR_PRE_MAX_SIZE 0x200 + +#define AWAKE_AOP_DDR_POST_BASE_ADDR (AWAKE_AOP_DDR_PRE_BASE_ADDR + AWAKE_AOP_DDR_PRE_MAX_SIZE) +#define AWAKE_AOP_DDR_POST_MAX_SIZE 0x600 + +#define AOP_DDR_AWAKE_PRE_BASE_ADDR (AWAKE_AOP_DDR_POST_BASE_ADDR + AWAKE_AOP_DDR_POST_MAX_SIZE) +#define AOP_DDR_AWAKE_PRE_MAX_SIZE 0x800 + +#define AOP_DDR_AWAKE_POST_BASE_ADDR (AOP_DDR_AWAKE_PRE_BASE_ADDR + AOP_DDR_AWAKE_PRE_MAX_SIZE) +#define AOP_DDR_AWAKE_POST_MAX_SIZE 0x2400 + +#define DRAM_CONFIG_SEQ_USED (AOP_DDR_AWAKE_POST_BASE_ADDR + AOP_DDR_AWAKE_POST_MAX_SIZE - DRAM_CONFIG_SEQ_BASE) + +#if DRAM_CONFIG_SEQ_USED > DRAM_CONFIG_SEQ_SIZE +#error "Reconfig engine programs overflow their DRAM allocation +#endif + +#endif /* __PLATFORM_RECONFIG_H */ diff --git a/platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_common.h b/platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_common.h new file mode 100644 index 0000000..e7a91b0 --- /dev/null +++ b/platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_common.h @@ -0,0 +1,221 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_T8010_A0_TUNABLE_APCIE_COMMON_H +#define SPDS_T8010_A0_TUNABLE_APCIE_COMMON_H + +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f7f7f7f) +#define PCIE_APCIE_COMMON_BLK_FABRIC_TLIMITS_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x700) +#define PCIE_APCIE_COMMON_BLK_COMMON_PRIORITY_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xffffff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING_DEFAULT_TUNABLE_VALUE_T8010_A0 (0xc0800) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x1fff) +#define PCIE_APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x92c) + +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x9) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_NVME_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_NVME_TUNABLE_VALUE_T8010_A0 (0x10) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_UMASK_T8010_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_0_FPGA_TUNABLE_VALUE_T8010_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x11) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_COMMON_BLK_APCIE_NVME_CTRL_0_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7) +#define PCIE_APCIE_COMMON_BLK_NVME_PRIORITY_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_NVME_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_NVME_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_UMASK_T8010_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_1_FPGA_TUNABLE_VALUE_T8010_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_1_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1_DEFAULT_TUNABLE_VALUE_T8010_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_NVME_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_NVME_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_UMASK_T8010_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_2_FPGA_TUNABLE_VALUE_T8010_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_2_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2_DEFAULT_TUNABLE_VALUE_T8010_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x3e) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_NVME_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_NVME_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x31100010) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1000000) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x10) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_UMASK_T8010_A0 (0x100000) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_CTRL_3_FPGA_TUNABLE_VALUE_T8010_A0 (0x100000) + +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x707) +#define PCIE_APCIE_COMMON_BLK_PORT_PRIORITY_3_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x73f3f) +#define PCIE_APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x43f00) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x333003f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x111000f) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3_DEFAULT_TUNABLE_VALUE_T8010_A0 (0xf) + +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f) +#define PCIE_APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x3e) + +#define PCIE_APCIE_COMMON_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_FABRIC_TLIMITS */ 0x8, sizeof(uint32_t), 0x7f7f7f7f, 0x0 }, \ +{ /* APCIE_COMMON_BLK_LLT_RATE_LIMITER_CTRL */ 0xc, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_COMMON_PRIORITY */ 0x10, sizeof(uint32_t), 0x700, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NANDSYSCLK_TIMING */ 0x18, sizeof(uint32_t), 0xffffff, 0xc0800 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NAND_LTR_THRESH */ 0x1c, sizeof(uint32_t), 0x1fff, 0x92c }, \ +{ /* APCIE_COMMON_BLK_APCIE_REFCLKBUF_TIMING */ 0x2c, sizeof(uint32_t), 0xff, 0x9 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_0 */ 0x108, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_0 */ 0x10c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x110, sizeof(uint32_t), 0x11, 0x1 }, \ +{ /* APCIE_COMMON_BLK_NVME_PRIORITY_0 */ 0x114, sizeof(uint32_t), 0x7, 0x0 }, \ +{ /* APCIE_COMMON_BLK_NVME_RATE_LIMITER_CTRL_0 */ 0x118, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_0 */ 0x120, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_0 */ 0x130, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_0 */ 0x138, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_1 */ 0x188, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_1 */ 0x18c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_1 */ 0x1a0, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_1 */ 0x1b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_1 */ 0x1b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_2 */ 0x208, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_2 */ 0x20c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_2 */ 0x220, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_2 */ 0x230, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_2 */ 0x238, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x31100010, 0x1000000 }, \ +{ /* APCIE_COMMON_BLK_PORT_PRIORITY_3 */ 0x288, sizeof(uint32_t), 0x707, 0x0 }, \ +{ /* APCIE_COMMON_BLK_PORT_RATE_LIMITER_CTRL_3 */ 0x28c, sizeof(uint32_t), 0x73f3f, 0x43f00 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_SQUELCH_CTRL_3 */ 0x2a0, sizeof(uint32_t), 0x333003f, 0x111000f }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_ACG_IDLE_CTRL_3 */ 0x2b0, sizeof(uint32_t), 0xff, 0xf }, \ +{ /* APCIE_COMMON_BLK_APCIE_PIPE_OVERRIDE_VAL_3 */ 0x2b8, sizeof(uint32_t), 0x7f, 0x3e }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_FPGA_TUNABLES_T8010_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x100000, 0x100000 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_NVME_TUNABLES_T8010_A0 \ +/* Key = nvme_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x10, 0x10 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x10, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_COMMON_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_0 */ 0x100, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_NVME_CTRL_0 */ 0x110, sizeof(uint32_t), 0x1, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_1 */ 0x180, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_2 */ 0x200, sizeof(uint32_t), 0x10, 0x0 }, \ +{ /* APCIE_COMMON_BLK_APCIE_PORT_CTRL_3 */ 0x280, sizeof(uint32_t), 0x10, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_T8010_A0_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_config.h b/platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_config.h new file mode 100644 index 0000000..747ac4d --- /dev/null +++ b/platform/t8010/include/platform/soc/t8010/a0/tunable/apcie_config.h @@ -0,0 +1,201 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_T8010_A0_TUNABLE_APCIE_CONFIG_H +#define SPDS_T8010_A0_TUNABLE_APCIE_CONFIG_H + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xd) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x5) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x2) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f7f) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x3) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x8073ffff) +#define PCIE_APCIE_PORT0_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x403d09) + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0xd, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT0_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x2, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xd) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x5) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x2) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f7f) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x3) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x8073ffff) +#define PCIE_APCIE_PORT1_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x403d09) + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0xd, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT1_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x2, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xd) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x5) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x2) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f7f) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x3) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x8073ffff) +#define PCIE_APCIE_PORT2_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x403d09) + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0xd, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT2_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x2, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_PMETOACK_TMOTLIM_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x28) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xd) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x5) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x2) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_INBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0x1) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_OUTBCTRL_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x1) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x7f7f) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_MCACHE_HINT_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x3) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_L1_SUBCTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x2) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_UMASK_T8010_A0 (0x8073ffff) +#define PCIE_APCIE_PORT3_APCIE_CONFIG_BLK_AF_TMOT_CTRL_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x403d09) + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0xd, 0x5 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ /* APCIE_CONFIG_BLK_MCACHE_HINT */ 0x138, sizeof(uint32_t), 0x7f7f, 0x0 }, \ +{ /* APCIE_CONFIG_BLK_L1_SUBCTRL */ 0x13c, sizeof(uint32_t), 0x3, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_AF_TMOT_CTRL */ 0x140, sizeof(uint32_t), 0x8073ffff, 0x403d09 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_APCIE_PORT3_APCIE_CONFIG_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* APCIE_CONFIG_BLK_PMETOACK_TMOTLIM */ 0x90, sizeof(uint32_t), 0xff, 0x28 }, \ +{ /* APCIE_CONFIG_BLK_INBCTRL */ 0x130, sizeof(uint32_t), 0x2, 0x2 }, \ +{ /* APCIE_CONFIG_BLK_OUTBCTRL */ 0x134, sizeof(uint32_t), 0x1, 0x1 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_T8010_A0_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/t8010/include/platform/soc/t8010/a0/tunable/x2_pcie_rc.h b/platform/t8010/include/platform/soc/t8010/a0/tunable/x2_pcie_rc.h new file mode 100644 index 0000000..995bce9 --- /dev/null +++ b/platform/t8010/include/platform/soc/t8010/a0/tunable/x2_pcie_rc.h @@ -0,0 +1,141 @@ +/* + * Automatically generated by socgen. DO NOT EDIT! + * + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_T8010_A0_TUNABLE_X2_PCIE_RC_H +#define SPDS_T8010_A0_TUNABLE_X2_PCIE_RC_H + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_T8010_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC0_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC0_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_FPGA_TUNABLES_T8010_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC0_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_T8010_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC1_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC1_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_FPGA_TUNABLES_T8010_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC1_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_T8010_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC2_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC2_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_FPGA_TUNABLES_T8010_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC2_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_UMASK_T8010_A0 (0x1f) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_FPGA_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_DEFAULT_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_UMASK_T8010_A0 (0xf8ff00) +#define PCIE_PCIE_CONFIG_PCIE_RC3_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG_SECURE_ROM_TUNABLE_VALUE_T8010_A0 (0x0) + +#define PCIE_PCIE_CONFIG_PCIE_RC3_DEFAULT_TUNABLES_T8010_A0 \ +/* Key = default_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_PCIE_CAP_DEVICE_CONTROL2_DEVICE_STATUS2_REG */ 0x98, sizeof(uint32_t), 0xf, 0x0 }, \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_FPGA_TUNABLES_T8010_A0 \ +/* Key = fpga_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0x1f, 0x0 }, \ +{ -1, -1, -1, -1 } + +#define PCIE_PCIE_CONFIG_PCIE_RC3_SECURE_ROM_TUNABLES_T8010_A0 \ +/* Key = secure_rom_tunable_key */ \ +/* Register Macro Identifier Register Offset Register Size Tunable Mask Tunable Value */ \ +{ /* X2_PCIE_RC_X2_PCIE_DSP_PF0_L1SUB_CAP_L1SUB_CAPABILITY_REG */ 0x164, sizeof(uint32_t), 0xf8ff00, 0x0 }, \ +{ -1, -1, -1, -1 } + +#endif /* SPDS_T8010_A0_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/t8010/include/platform/soc/t8010/apcie_common.h b/platform/t8010/include/platform/soc/t8010/apcie_common.h new file mode 100644 index 0000000..450e8d7 --- /dev/null +++ b/platform/t8010/include/platform/soc/t8010/apcie_common.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_T8010_TUNABLE_APCIE_COMMON_H +#define SPDS_T8010_TUNABLE_APCIE_COMMON_H + +#include + +#endif /* SPDS_T8010_TUNABLE_APCIE_COMMON_H */ \ No newline at end of file diff --git a/platform/t8010/include/platform/soc/t8010/apcie_config.h b/platform/t8010/include/platform/soc/t8010/apcie_config.h new file mode 100644 index 0000000..ad58d72 --- /dev/null +++ b/platform/t8010/include/platform/soc/t8010/apcie_config.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_T8010_TUNABLE_APCIE_CONFIG_H +#define SPDS_T8010_TUNABLE_APCIE_CONFIG_H + +#include + +#endif /* SPDS_T8010_TUNABLE_APCIE_CONFIG_H */ \ No newline at end of file diff --git a/platform/t8010/include/platform/soc/t8010/x2_pcie_rc.h b/platform/t8010/include/platform/soc/t8010/x2_pcie_rc.h new file mode 100644 index 0000000..3868aed --- /dev/null +++ b/platform/t8010/include/platform/soc/t8010/x2_pcie_rc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form + * in whole or in part, without the express written permission of + * Apple inc. + */ + +#ifndef SPDS_T8010_TUNABLE_X2_PCIE_RC_H +#define SPDS_T8010_TUNABLE_X2_PCIE_RC_H + +#include + +#endif /* SPDS_T8010_TUNABLE_X2_PCIE_RC_H */ \ No newline at end of file diff --git a/platform/t8010/include/platform/trampoline.h b/platform/t8010/include/platform/trampoline.h new file mode 100644 index 0000000..fff8bd2 --- /dev/null +++ b/platform/t8010/include/platform/trampoline.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_TRAMPOLINE_H +#define __PLATFORM_TRAMPOLINE_H + +#include + +/* ROM related registers in AOP MINIPMGR space */ + +#define SECURITY_REG (AOP_MINIPMGR_BASE_ADDR + 0xD0010) +#define ROM_READ_DISABLE (1 << 0) + +#define REMAP_REG (AOP_MINIPMGR_BASE_ADDR + 0xD0014) + +#endif /* ! __PLATFORM_TRAMPOLINE_H */ diff --git a/platform/t8010/include/platform/uartconfig.h b/platform/t8010/include/platform/uartconfig.h new file mode 100644 index 0000000..f3ba186 --- /dev/null +++ b/platform/t8010/include/platform/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_UARTCONFIG_H +#define __PLATFORM_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/platform/t8010/include/platform/usbconfig.h b/platform/t8010/include/platform/usbconfig.h new file mode 100644 index 0000000..a43ccdc --- /dev/null +++ b/platform/t8010/include/platform/usbconfig.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __PLATFORM_USBCONFIG_H +#define __PLATFORM_USBCONFIG_H + +#if SUB_PLATFORM_T8010 +/* + * per Cayman Tunables Specification, SPDS version 0.0.1 + */ + +#define USBPHY_OTGTUNE0 (0x37377BC3) +#define USBPHY_OTGTUNE1 (0x00020C04) + +#else +#error "Unknown SUB_PLATFORM" +#endif + +#define USBOTG_AHB_DMA_BURST (DWCUSB_GAHBCFG_HBST_INCR16) + +#endif /* ! __PLATFORM_USBCONFIG_H */ diff --git a/platform/t8010/init.c b/platform/t8010/init.c new file mode 100644 index 0000000..61bf6d2 --- /dev/null +++ b/platform/t8010/init.c @@ -0,0 +1,2161 @@ +/* +* Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_CONSISTENT_DBG +#include +#endif +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#if WITH_HW_SEP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_PLATFORM_ERROR_HANDLER +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +static void platform_init_boot_strap(void); +static void platform_bootprep_darwin(void); +static int power_convert_buck_to_rail(int buck, int *rail); +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val); +static int power_convert_dwi_to_mv_fpga(unsigned int buck, uint32_t dwival); + +static void platform_awake_to_aop_ddr_pre_sequence_insert(); +static void platform_awake_to_aop_ddr_post_sequence_insert(); +static void platform_aop_ddr_to_s2r_aop_pre_sequence_insert(); +static void platform_s2r_aop_to_aop_ddr_post_sequence_insert(); +static void platform_aop_ddr_to_awake_pre_sequence_insert(); +static void platform_aop_ddr_to_awake_post_sequence_insert(); + +static uint8_t boot_debug; +static bool gDisplayEnabled; + +int platform_early_init(void) +{ +#if (PRODUCT_LLB || PRODUCT_IBSS) + /* Verify that the fuses and SecureROM R/W access has been disabled */ + if (!chipid_get_fuse_lock() || (((*(volatile uint32_t *)SECURITY_REG) & ROM_READ_DISABLE) == 0)) { + panic("Fuses are unlocked or SecureROM is enabled\n"); + } + + /* Verify that the fuses are sealed on production devices. */ + if (chipid_get_current_production_mode() && !chipid_get_fuse_seal()) { + panic("Fuses are not sealed\n"); + } +#endif + + /* Enable more Cyclone specific errors */ + ccc_enable_custom_errors(); + +#if WITH_HW_PLATFORM_POWER + /* initialize the pmgr driver */ + platform_power_init(); +#endif + +#if WITH_HW_MIU + /* CIF, SCU, remap setup */ + miu_init(); +#endif +#if WITH_HW_CLOCKS + /* initialize the clock driver */ + clocks_init(); +#endif + +#if WITH_HW_AIC + /* initialize the AIC, mask all interrupts */ + interrupt_init(); +#endif + +#if WITH_HW_TIMER + timer_init(0); +#endif +#if WITH_HW_USBPHY + usbphy_power_down(); +#endif +#if WITH_HW_UART + /* do whatever uart initialization we need to get a simple console */ + uart_init(); + debug_enable_uarts(3); +#endif +#if WITH_SHM_CONSOLE + shmcon_init(); +#endif + +#if WITH_IIC + iic_init(); +#endif +#if !PRODUCT_IBOOT && !PRODUCT_IBEC + platform_init_power(); + +#if WITH_BOOT_STAGE + boot_check_stage(); +#endif +#endif + +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductStart); +#endif + +#if WITH_HW_POWER + power_get_nvram(kPowerNVRAMiBootDebugKey, &boot_debug); + debug_enable_uarts(boot_debug); +#endif + +#if WITH_TARGET_CONFIG + target_early_init(); +#endif + return 0; +} + + +int platform_late_init(void) +{ +#if WITH_ENV + /* publish secure-boot flag for restore mode */ + env_set_uint("secure-boot", 1, 0); + + /* turn off DEBUG clock if debug-soc nvram is not true */ + clock_gate(CLK_DEBUG, env_get_bool("debug-soc", false)); +#endif + +#if WITH_HW_USB && WITH_USB_MODE_RECOVERY + usb_early_init(); +#endif + +#if WITH_HW_POWER + power_late_init(); +#endif + +#if WITH_TARGET_CONFIG + target_late_init(); +#endif + +#if WITH_HW_DCS + extern void mcu_late_init(void); + mcu_late_init(); +#endif + +#if WITH_CSI + csi_late_init(); +#endif + + return 0; +} + +int platform_init_setup_clocks(void) +{ +#if WITH_HW_CLOCKS + clocks_set_default(); +#endif + return 0; +} + +int platform_init_hwpins(void) +{ + // need board id to select default pinconfig + platform_init_boot_strap(); + +#if WITH_HW_GPIO + /* finish initializing the gpio driver */ + gpio_init_pinconfig(); +#endif + + return 0; +} + +int platform_init_internal_mem(void) +{ +#if WITH_HW_MIU + /* initialize sram bus */ + miu_initialize_internal_ram(); +#endif + + return 0; +} + +int platform_init_mainmem(bool resume) +{ + RELEASE_ASSERT(!resume); + +#if WITH_HW_MIU && APPLICATION_IBOOT + /* initialize sdram */ + miu_initialize_dram(resume); +#endif + + return 0; +} + +void platform_init_mainmem_map(void) +{ +} + +int platform_init_power(void) +{ +#if WITH_HW_POWER + power_init(); +#endif + + return 0; +} + +int platform_init_display(void) +{ +#if WITH_HW_DISPLAYPIPE + static bool displayInitOnce; + uint32_t backlight_level = 0; + int result = 0; + + /* initialize the display if not already enabled */ + if (!gDisplayEnabled) { +#if WITH_HW_DISPLAY_PMU + display_pmu_init(); +#endif + + if (!displayInitOnce) { + platform_quiesce_display(); + clock_gate(CLK_RTMUX, true); + result = display_init(); + } else result = -1; + + /* if initialization fails, make sure we never try again. On success, gDisplayEnabled will be set, + * ensuring no reinitialization unless platform_quiesce_display is called first. + */ + if (result != 0) { + displayInitOnce = true; + } + } + + if (result == 0) { + gDisplayEnabled = true; + backlight_level = env_get_uint("backlight-level", 0xffffffff); + } + + power_backlight_enable(backlight_level); +#endif + + return 0; +} + +int platform_init_display_mem(addr_t *base, size_t *size) +{ +#if WITH_HW_DISPLAYPIPE + addr_t base_rounded = *base; + addr_t end_rounded = *base + *size; + size_t size_rounded = *size; + + /* Map the framebuffer as device memory and + * round the base and size to the mapping granule. + */ + base_rounded = ROUNDDOWN(base_rounded, MB); + end_rounded = ROUNDUP(end_rounded, MB); + size_rounded = end_rounded - base_rounded; + *base = base_rounded; + *size = size_rounded; +#endif + + return 0; +} + + +int platform_init_mass_storage_panic(void) +{ +#if WITH_NVME + return nvme_init_mass_storage_panic(0); +#else + return 0; +#endif +} + +int platform_init_mass_storage(void) +{ +#if WITH_NVME + return nvme_init_mass_storage(0); +#else + return 0; +#endif +} + +int platform_quiesce_hardware(enum boot_target target) +{ + bool quiesce_clocks = false; + +#if APPLICATION_SECUREROM + quiesce_clocks = true; +#endif + +#if WITH_TARGET_CONFIG + target_quiesce_hardware(); +#endif + +#if WITH_HW_USB + usb_quiesce(); +#endif + +#if WITH_CSI + csi_quiesce(target); +#endif + +#if WITH_NVME + nvme_quiesce_all(); +#endif + +#if WITH_HW_APCIE + apcie_disable_all(); +#endif + + switch (target) { + case BOOT_HALT: + break; + case BOOT_SECUREROM: + case BOOT_DARWIN_RESTORE: + panic("not supported"); + break; + case BOOT_IBOOT: + case BOOT_DARWIN: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + case BOOT_DIAGS: + quiesce_clocks = true; +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageProductEnd); +#endif + break; + default: +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + break; + } + +#if WITH_HW_TIMER + timer_stop_all(); +#endif +#if WITH_HW_AIC + interrupt_mask_all(); +#endif + + if (quiesce_clocks) { +#if WITH_HW_CLOCKS + clocks_quiesce(); +#endif + } + +#if APPLICATION_IBOOT + switch (target) { + case BOOT_IBOOT : + break; + + default: + break; + } +#endif + + return 0; +} + +int platform_quiesce_display(void) +{ +#if WITH_HW_DISPLAYPIPE + // Turn off the back light + power_backlight_enable(0); + + clock_gate(CLK_RTMUX, true); + + /* quiesce the panel */ + if (display_quiesce(true) == ENXIO) { + clock_gate(CLK_RTMUX, false); + } +#endif + gDisplayEnabled = false; + + return 0; +} + +static bool need_l2_ram_disabled(void) +{ +#if PRODUCT_IBSS || PRODUCT_LLB + // If the current product is iBSS or LLB we're currently running out + // of L2-as-RAM and therefore can't disable it. + return false; +#else + return true; +#endif +} + +int platform_bootprep(enum boot_target target) +{ + uint32_t gids = ~0, uids = ~0; /* leave crypto keys alone by default */ + bool l2_ram_disable = false; + + /* prepare hardware for booting into various targets */ + +#if WITH_HW_CLOCKS + if (target != BOOT_IBOOT) clocks_set_performance(kPerformanceHigh); +#endif + +#if WITH_TARGET_CONFIG + target_bootprep(target); +#endif + + /* If we're not restoring, reset the watchdog-on-wake until enabled */ + if ((boot_debug & kPowerNVRAMiBootDebugWDTWake) && (target == BOOT_DARWIN)) + { + boot_debug &= ~kPowerNVRAMiBootDebugWDTWake; +#if WITH_HW_POWER + power_set_nvram(kPowerNVRAMiBootDebugKey, boot_debug); +#endif + } + + switch (target) { +#if APPLICATION_IBOOT + case BOOT_DARWIN_RESTORE: + panic("not supported"); + break; + +#if WITH_BOOT_XNU + case BOOT_DARWIN: + platform_bootprep_darwin(); + if (boot_debug & kPowerNVRAMiBootDebugWDTWake) + wdt_enable(); + /* even when trusted, Darwin only gets the UID / GID1 */ + uids = 1; + gids = 2; + l2_ram_disable = true; + break; +#endif // WITH_BOOT_XNU + + case BOOT_DIAGS: +#if WITH_SIDP + /* Seal the manifest that authorizes diags. */ + security_sidp_seal_boot_manifest(false); +#endif + l2_ram_disable = need_l2_ram_disabled(); + platform_quiesce_display(); +#if WITH_BOOT_STAGE + boot_clear_error_count(); +#endif + break; + + case BOOT_IBOOT: + l2_ram_disable = need_l2_ram_disabled(); + platform_quiesce_display(); + break; +#endif // APPLICATION_IBOOT + + case BOOT_UNKNOWN: + platform_quiesce_display(); + break; + + case BOOT_SECUREROM: + case BOOT_MONITOR: + default: + panic("unknown boot target %d", target); + } + + // Make sure L2-as-RAM is disabled if required. + if (l2_ram_disable) { + uint64_t l2_cramconfig = arm_read_l2_cramconfig(); + if ((l2_cramconfig & 0x3F) != 0) { + panic("SRAM is still enabled"); + } + } + + /* make sure that fuse lock bit is set. */ + if (security_get_lock_fuses()) + chipid_set_fuse_lock(true); + + /* Let security override keys */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + gids = 0; + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + uids = 0; + + /* disable all keys not requested */ + platform_disable_keys(~gids, ~uids); + +#if WITH_SIDP + + /* The Silicon Data Protection ROM manifest must be locked. */ + if (!platform_sidp_rom_manifest_locked()) { + panic("SiDP ROM manifest not locked"); + } + +#if !APPLICATION_SECUREROM + + /* The Silicon Data Protection boot manifest must be locked. */ + if ((target != BOOT_IBOOT) && !platform_sidp_boot_manifest_locked()) { + panic("SiDP boot manifest not locked"); + } + +#endif // !APPLICATION_SECUREROM +#endif // WITH_SIDP + + /* Disable Cyclone specific errors enabled earlier in the boot */ + ccc_disable_custom_errors(); + + return 0; +} + +void platform_mmu_setup(bool resume) +{ + RELEASE_ASSERT(!resume); + +#if APPLICATION_SECUREROM + // ROM is obviously read/execute since it's ROM + arm_mmu_map_rx(VROM_BASE, VROM_BANK_LEN); + + // everything ROM needs in SRAM is read-write, + // except the trampoline which is read-execute + arm_mmu_map_rw(INSECURE_MEMORY_BASE, INSECURE_MEMORY_SIZE); + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + arm_mmu_map_rw(DATA_BASE, DATA_SIZE); + // skip page tables here + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + +#else // APPLICATION_IBOOT + // Figure out where the linker put our various bits + uintptr_t text_end_aligned = ((uintptr_t)&_text_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + size_t text_size = text_end_aligned - (uintptr_t)&_text_start; + + RELEASE_ASSERT(text_end_aligned <= (uintptr_t)&_data_start); + +#if PRODUCT_LLB || PRODUCT_IBSS + arm_mmu_map_rw(SDRAM_BASE, SDRAM_LEN); + + // Map read/write SRAM regions + // Don't map the page tables so that they can't be modified + arm_mmu_map_rw(SRAM_BASE, VROM_RSVD); + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + + // __TEXT is read/execute, __DATA is read/write + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, CODE_DATA_END - text_end_aligned); +#else // PRODUCT_IBEC || PRODUCT_IBOOT + // Most of DRAM gets mapped read/write + arm_mmu_map_rw(SDRAM_BASE, (uintptr_t)&_text_start - SDRAM_BASE); + + // only the text section should be executable, and it should be read only + arm_mmu_map_rx((uintptr_t)&_text_start, text_size); + arm_mmu_map_rw(text_end_aligned, PAGE_TABLES_BASE - text_end_aligned); + + // skip mapping the page tables so that they can't be modified + + // map the stacks read-write + arm_mmu_map_rw(STACKS_BASE, STACKS_SIZE); + + // map the boot trampoline read/execute + arm_mmu_map_rx(BOOT_TRAMPOLINE_BASE, BOOT_TRAMPOLINE_SIZE); + + // map the heap read-write, leaving a hole at the end + arm_mmu_map_rw(HEAP_BASE, HEAP_SIZE); + RELEASE_ASSERT(HEAP_BASE + HEAP_SIZE == HEAP_GUARD); + + // and then everything up to the end of DRAM is read/write again + arm_mmu_map_rw(CODE_DATA_END, SDRAM_END - (CODE_DATA_END)); +#endif // PRODUCT_LLB || PRODUCT_IBSS +#endif // APPLICATION_SECUREROM + + // map IO + arm_mmu_map_device_rw(IO_BASE, IO_SIZE); + arm_mmu_map_device_rw(PCI_REG_BASE, PCI_REG_LEN); + arm_mmu_map_device_rw(PCI_CONFIG_BASE, PCI_CONFIG_LEN); + arm_mmu_map_device_rw(PCI_32BIT_BASE, PCI_32BIT_LEN); +} + +int platform_init(void) +{ +#if defined(UNUSED_MEMORY_BASE) && (UNUSED_MEMORY_SIZE > 0) + bzero((void *)UNUSED_MEMORY_BASE, UNUSED_MEMORY_SIZE); +#endif + +#if WITH_CONSISTENT_DBG && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) + consistent_debug_init(); +#endif + +#if WITH_PLATFORM_ERROR_HANDLER + platform_enable_error_handler(); +#endif + +#if PRODUCT_IBEC && WITH_SIDP + // The code that authorized iBEC must have locked the boot manifest. + RELEASE_ASSERT(platform_sidp_boot_manifest_locked()); +#endif + +#if WITH_HW_SPI + spi_init(); +#endif + +#if WITH_PCI + pci_init(); +#endif + +#if WITH_NVME && (PRODUCT_LLB || PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS) +#if PRODUCT_IBEC + apcie_set_s3e_mode(true); +#else + apcie_set_s3e_mode(false); +#endif + if (apcie_enable_link(0)) { + nvme_init(0, apcie_get_port_bridge(0), 0); + } +#endif + +#if WITH_TARGET_CONFIG + target_init(); +#endif + + return 0; +} + +int platform_debug_init(void) +{ +#if WITH_HW_USB + uint32_t usb_enabled = 1; +#if WITH_ENV && SUPPORT_FPGA + usb_enabled = env_get_uint("usb-enabled", 1); +#endif + if (usb_enabled) usb_init(); +#endif + +#if WITH_TARGET_CONFIG + target_debug_init(); +#endif + + return 0; +} + +void platform_poweroff(void) +{ + platform_quiesce_display(); + +#if WITH_NVME + nvme_quiesce_all(); +#endif + +#if WITH_HW_APCIE + apcie_disable_all(); +#endif + +#if WITH_TARGET_CONFIG + target_poweroff(); +#endif + +#if WITH_HW_POWER +#if WITH_BOOT_STAGE + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + power_shutdown(); +#endif + for(;;); +} + +uint32_t platform_set_performance(uint32_t performance_level) +{ + uint32_t old_performance_level = kPerformanceHigh; + +#if WITH_HW_CLOCKS + old_performance_level = clocks_set_performance(performance_level); +#endif + + return old_performance_level; +} + +void platform_setup_default_environment(void) +{ +#if WITH_ENV + env_set("boot-device", "nvme_nand0", 0); +#endif + + target_setup_default_environment(); +} + +#if WITH_DEVICETREE + +int platform_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Find the cpu0 node. + if (FindNode(0, "cpus/cpu0", &node)) { + + // Fill in the cpu frequency + propName = "clock-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_CPU); + memcpy(propData, &freq, propSize); + } + + // Fill in the memory frequency + propName = "memory-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_MEM); + memcpy(propData, &freq, propSize); + } + + // Fill in the bus frequency + propName = "bus-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_BUS); + memcpy(propData, &freq, propSize); + } + + // Fill in the peripheral frequency + propName = "peripheral-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_PERIPH); + memcpy(propData, &freq, propSize); + } + + // Fill in the fixed frequency + propName = "fixed-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_FIXED); + memcpy(propData, &freq, propSize); + } + + // Fill in the time base frequency + propName = "timebase-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint64_t freq = clock_get_frequency(CLK_TIMEBASE); + memcpy(propData, &freq, propSize); + } + } + + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the clock-frequencies table + propName = "clock-frequencies"; + if (FindProperty(node, &propName, &propData, &propSize)) { + clock_get_frequencies(propData, propSize / sizeof(uint32_t)); + } + + // Fill in the usb-phy frequency + propName = "usbphy-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_USBPHYCLK); + } + } + + // Find the mcc node + if (FindNode(0, "arm-io/mcc", &node)) { + propName = "dcs_num_channels"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = DCS_NUM_CHANNELS; + } + } + + // Find the pmgr node + if (FindNode(0, "arm-io/pmgr", &node)) { + pmgr_update_device_tree(node); + miu_update_device_tree(node); + } + + // Find the gfx node + if (FindNode(0, "arm-io/sgx", &node)) { + pmgr_gfx_update_device_tree(node); + } + + // Find the audio-complex node + if (FindNode(0, "arm-io/audio-complex", &node)) { + // Fill in the ncoref-frequency frequency + propName = "ncoref-frequency"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = clock_get_frequency(CLK_NCOREF); + } + } + + // Find the apcie node +#if WITH_HW_APCIE + if (FindNode(0, "arm-io/apcie", &node)) { + apcie_update_devicetree(node); + } +#endif + +#if WITH_HW_PLATFORM_CHIPID + // Find the arm-io node + if (FindNode(0, "arm-io", &node)) { + // Fill in the chip-revision property + propName = "chip-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = platform_get_chip_revision(); + } + } +#endif + +#if WITH_HW_USBPHY + // Find the otgphyctrl node + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + usbphy_update_device_tree(node); + } +#endif + +#if WITH_NVME + if (FindNode(0, "arm-io/nvme-mmu0", &node)) { + uintptr_t *sart_region = NULL; + uint32_t *sart_virt_base = NULL; + uint64_t *nvme_scratch_region = NULL; + + propName = "sart-region"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == 2 * sizeof(uintptr_t)) { + sart_region = (uintptr_t *)propData; + } + + propName = "sart-virtual-base"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == sizeof(uint32_t)) { + sart_virt_base = (uint32_t *)propData; + } + + if (FindNode(0, "arm-io/apcie/pci-bridge0/s3e", &node)) { + propName = "nvme-scratch-virt-region"; + if (FindProperty(node, &propName, &propData, &propSize) && propSize == 2 * sizeof(uint64_t)) { + nvme_scratch_region = propData; + } + } + + if (sart_region != NULL && sart_virt_base != NULL && nvme_scratch_region != NULL) { + // Tell PCIe driver to point the SART at the scratch buffer + sart_region[0] = platform_get_memory_region_base(kMemoryRegion_StorageProcessor); + sart_region[1] = platform_get_memory_region_size(kMemoryRegion_StorageProcessor); + // Tell NVMe driver where the SART is putting the scratch buffer + nvme_scratch_region[0] = *sart_virt_base; + nvme_scratch_region[1] = sart_region[1]; + } + } +#endif + + if (dt_find_node(NULL, "arm-io/aop", &node)) { + addr_t aop_region_base = platform_get_memory_region_base(kMemoryRegion_AOP); + addr_t aop_region_size = platform_get_memory_region_size(kMemoryRegion_AOP); + + // Find the reg that maps the AOP SRAM and adjust it to account + // for the SRAM used by the reconfig region + bool updated = false; + if (dt_find_prop(node, "reg", &propData, &propSize)) { + uintptr_t *regs = (uintptr_t *)propData; + unsigned num_regs = propSize / (sizeof(*regs) * 2); + for (unsigned i = 0; i < num_regs; i++) { + if (regs[i * 2] == aop_region_base - IO_BASE) { + regs[i * 2 + 1] = aop_region_size; + updated = true; + break; + } + } + } + + if (!updated) panic("failed to update AOP's reg property"); + + if (dt_find_node(node, "iop-aop-nub", &node)) { + dt_set_prop_addr(node, "region-base", aop_region_base); + dt_set_prop_addr(node, "region-size", aop_region_size); + } else { + panic("failed to find AOP nub node"); + } + } + + return target_update_device_tree(); +} + +#endif + +uint32_t platform_get_board_id(void) +{ + uint32_t board_id; + + ASSERT((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0); + + board_id = (rPMGR_SCRATCH0 >> 16) & 0xFF; + + return board_id; +} + +bool platform_get_lock_fuses_required(void) +{ + bool lock_fuses = true; + + return lock_fuses; +} + +uint32_t platform_get_boot_config(void) +{ + uint32_t boot_config; + + boot_config = (rPMGR_SCRATCH0 >> 8) & 0xFF; + + return boot_config; +} + +bool platform_get_boot_device(int32_t index, enum boot_device *boot_device, uint32_t *boot_flag, uint32_t *boot_arg) +{ + uint32_t boot_config = platform_get_boot_config(); + + /* T8010 supports one boot device then USB-DFU per boot config */ + + switch (boot_config) { + case BOOT_CONFIG_SPI0: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_SPI0_TEST: + case BOOT_CONFIG_FAST_SPI0_TEST: + case BOOT_CONFIG_SLOW_SPI0_TEST: + *boot_device = BOOT_DEVICE_SPI; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + case BOOT_CONFIG_NVME0_X1: + case BOOT_CONFIG_NVME0_X2: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = 0; + *boot_arg = 0; + break; + + case BOOT_CONFIG_NVME0_X1_TEST: + case BOOT_CONFIG_NVME0_X2_TEST: + *boot_device = BOOT_DEVICE_NVME; + *boot_flag = BOOT_FLAG_TEST_MODE; + *boot_arg = 0; + break; + + default: + return false; + } + + /* Change boot_device and boot_arg for DFU Mode */ + /* Don't change flags */ + if (index == -1 || (index != 0 && *boot_device != BOOT_DEVICE_TBTDFU)) { + *boot_device = BOOT_DEVICE_USBDFU; + *boot_arg = 0; + } + + return true; +} + +/* + * boot_interface_pin tables + * tables are executed in order for disable and reverse order for enable + * + */ + +struct boot_interface_pin { + gpio_t pin; + uint32_t enable; + uint32_t disable; +}; + +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI +static const struct boot_interface_pin spi0_boot_interface_pins[] = +{ +#if SUPPORT_FPGA + { GPIO_SPI0_SSIN, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SSIN +#else + { GPIO_SPI0_SSIN, GPIO_CFG_OUT_1, GPIO_CFG_DFLT }, // SPI0_SSIN +#endif + { GPIO_SPI0_SCLK, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_SCLK + { GPIO_SPI0_MOSI, GPIO_CFG_FUNC0, GPIO_CFG_DFLT }, // SPI0_MOSI + { GPIO_SPI0_MISO, GPIO_CFG_FUNC0, GPIO_CFG_DFLT } // SPI0_MISO +}; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +void platform_enable_boot_interface(bool enable, enum boot_device boot_device, uint32_t boot_arg) +{ + const struct boot_interface_pin *pins = 0; + uint32_t cnt, func, pin_count = 0; + gpio_t pin; + + switch (boot_device) { +#if WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI + case BOOT_DEVICE_SPI : + if (boot_arg == 0) { + pins = spi0_boot_interface_pins; + pin_count = (sizeof(spi0_boot_interface_pins) / sizeof(spi0_boot_interface_pins[0])); + } + break; +#endif /* WITH_HW_FLASH_NOR && WITH_HW_FLASH_NOR_SPI */ + +#if WITH_ANC_BOOT + case BOOT_DEVICE_NAND : + /* NAND pins are off to ASP */ + break; +#endif /* WITH_ANC_BOOT */ + +#if WITH_NVME + case BOOT_DEVICE_NVME : + { + uint32_t dart_id = 0; + uint32_t pcie_port = 0; + if (boot_arg != 0) { + panic("invalid NVMe boot argument %u", boot_arg); + } + + if (enable) { + apcie_set_s3e_mode(false); + + // Don't try to probe for the NVMe device if the link doesn't come + // up because we shut down the root complex on link initialization + // failures + if (apcie_enable_link(pcie_port)) { + nvme_init(0, apcie_get_port_bridge(pcie_port), dart_id); + } + } + if (!enable) { + // These guys are safe no-ops if the enable above failed + nvme_quiesce(0); + + apcie_disable_link(pcie_port); + } + + break; + } +#endif + +#if WITH_USB_DFU + case BOOT_DEVICE_USBDFU : + /* USB is always configured */ + break; +#endif /* WITH_USB_DFU */ + + default : + break; + } + + for (cnt = 0; cnt < pin_count; cnt++) { + if (enable) { + pin = pins[pin_count - 1 - cnt].pin; + func = pins[pin_count - 1 - cnt].enable; + } else { + pin = pins[cnt].pin; + func = pins[cnt].disable; + } + + dprintf(DEBUG_INFO, "platform_enable_boot_interface: 0 %x, %x\n", pin, func); + gpio_configure(pin, func); + } +} + +uint32_t platform_get_apcie_lane_cfg(void) +{ + uint32_t boot_config = platform_get_boot_config(); + + switch (boot_config) { + case BOOT_CONFIG_NVME0_X1: + case BOOT_CONFIG_NVME0_X1_TEST: + return APCIE_LANE_CONFIG_NVME0_X1; + + case BOOT_CONFIG_NVME0_X2: + case BOOT_CONFIG_NVME0_X2_TEST: + return APCIE_LANE_CONFIG_NVME0_X2; + + default: + panic("unknown pcie boot config 0x%x", boot_config); + } +} + +// Get the expected link width (number of lanes) for the given PCIe link +// A value of 0 means to auto-negotiate (and has no effect for ports +// that only support x1 mode in the hardware) +uint32_t platform_get_pcie_link_width(uint32_t link) +{ + uint32_t boot_config = platform_get_boot_config(); + + switch (boot_config) { + case BOOT_CONFIG_NVME0_X1: + case BOOT_CONFIG_NVME0_X1_TEST: + return 1; + + default: + return 0; + } +} + +uint64_t platform_get_nonce(void) +{ + uint64_t nonce; + uint32_t *nonce_words = (uint32_t *)&nonce; + + // If rPMGR_SCRATCH0[1] set then the nonce has already been generated + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagNonce) == 0) { + + nonce = platform_consume_nonce(); + + rPMGR_SCRATCH_BOOT_NONCE_0 = nonce_words[0]; + rPMGR_SCRATCH_BOOT_NONCE_1 = nonce_words[1]; + + rPMGR_SCRATCH0 |= kPlatformScratchFlagNonce; + } else { + nonce_words[0] = rPMGR_SCRATCH_BOOT_NONCE_0; + nonce_words[1] = rPMGR_SCRATCH_BOOT_NONCE_1; + } + + return nonce; +} + +int32_t platform_get_sep_nonce(uint8_t *nonce) +{ +#if WITH_HW_SEP + return sep_client_get_nonce(nonce); +#else + return -1; +#endif +} + +bool platform_get_ecid_image_personalization_required(void) +{ + return true; +} + +uint32_t platform_get_osc_frequency(void) +{ + return chipid_get_osc_frequency(); +} + +uint32_t platform_get_spi_frequency(void) +{ +#if SUPPORT_FPGA + return 2500000; +#else + switch (platform_get_boot_config()) { + case BOOT_CONFIG_FAST_SPI0_TEST: + return 24000000; + + case BOOT_CONFIG_SLOW_SPI0_TEST: + return 6000000; + + default: + return 12000000; + } +#endif +} + +bool platform_get_usb_cable_connected(void) +{ +#if WITH_HW_USBPHY + return usbphy_is_cable_connected(); +#else + return false; +#endif +} + +void platform_set_dfu_status(bool dfu) +{ + gpio_write(GPIO_DFU_STATUS, dfu); +} + +bool platform_get_force_dfu(void) +{ + return gpio_read(GPIO_FORCE_DFU); +} + +bool platform_get_request_dfu1(void) // Formerly platform_get_hold_key() +{ + return !gpio_read(GPIO_REQUEST_DFU1); +} + +bool platform_get_request_dfu2(void) // Formerly platform_get_menu_key() +{ + return !gpio_read(GPIO_REQUEST_DFU2); +} + +int platform_translate_key_selector(uint32_t key_selector, uint32_t *key_opts) +{ + bool production = platform_get_current_production_mode(); + + switch (key_selector) { + case IMAGE_KEYBAG_SELECTOR_PROD : + if (!production) return -1; + break; + + case IMAGE_KEYBAG_SELECTOR_DEV : + if (production) return -1; + break; + + default : + return -1; + } + + *key_opts = AES_KEY_TYPE_GID0 | AES_KEY_SIZE_256; + + return 0; +} + +bool platform_set_usb_brick_detect(int select) +{ +#if WITH_HW_USBPHY + return usbphy_set_dpdm_monitor(select); +#else + return false; +#endif +} + +void platform_disable_keys(uint32_t gid, uint32_t uid) +{ + uint32_t keydis = (((gid & 0x3) << 1) | ((uid & 0x1) << 0)); + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return; + + rMINIPMGR_SIO_AES_DISABLE = keydis; + +} + +bool platform_keys_disabled(uint32_t gid, uint32_t uid) +{ + uint32_t key_disabled; + + dprintf(DEBUG_SPEW, "gid:0x%08x uid:0x%08x\n", gid, uid); + + if (!gid && !uid) return true; + + key_disabled = rMINIPMGR_SIO_AES_DISABLE; + + return (key_disabled & (((gid & 0x3) << 1) | ((uid & 0x1) << 0))); +} + +void platform_demote_production() +{ + chipid_clear_production_mode(); +} + +#if APPLICATION_IBOOT +bool platform_is_pre_lpddr4(void) +{ + return false; +} + +uint64_t platform_get_memory_size(void) +{ + uint64_t memory_size; + + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory size info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + memory_size = (((uint64_t)rPMGR_SCRATCH_MEM_INFO) & 0xffff) * 1024 * 1024; + } + else { + panic("memory not yet inited\n"); + } + + return memory_size; +} + +uint8_t platform_get_memory_manufacturer_id(void) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory vendor-id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) != 0) { + return ((rPMGR_SCRATCH_MEM_INFO >> 24) & 0xff); + } + else { + panic("memory not yet inited\n"); + } +} + +void platform_set_memory_info_with_revids(uint8_t manuf_id, uint64_t memory_size, uint8_t rev_id, uint8_t rev_id2) +{ + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) { + rPMGR_SCRATCH_MEM_INFO = 0; + } + + rPMGR_SCRATCH_MEM_INFO = (manuf_id << 24) | ((rev_id2 & 0xF) << 20) | ((rev_id & 0xF) << 16) | (memory_size & 0xffff); + rPMGR_SCRATCH0 |= kPlatformScratchFlagMemoryInfo; +} + +void platform_get_memory_rev_ids(uint8_t *rev_id, uint8_t *rev_id2) +{ + // If rPMGR_SCRATCH0[2] set then the memory was inited, we have memory rev_id info + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagMemoryInfo) == 0) + panic("memory not yet inited\n"); + else { + if (rev_id && rev_id2) { + uint8_t rev_info = (rPMGR_SCRATCH_MEM_INFO >> 16) & 0xFF; + *rev_id = rev_info & 0xF; + *rev_id2 = rev_info >> 4; + } + } +} +#endif + +extern void boot_handoff_trampoline(void *entry, void *arg); + +void *platform_get_boot_trampoline(void) +{ +#ifdef BOOT_TRAMPOLINE_BASE + return (void *)BOOT_TRAMPOLINE_BASE; +#else + return (void *)boot_handoff_trampoline; +#endif +} + +int32_t platform_restore_system(void) +{ + panic("not supported"); +} + +void platform_asynchronous_exception(void) +{ + ccc_handle_asynchronous_exception(); +} + +int32_t platform_get_boot_manifest_hash(uint8_t *boot_manifest_hash) +{ + volatile uint32_t *pScratch; + uint32_t *pHash; + + RELEASE_ASSERT(boot_manifest_hash != NULL); + ASSERT((&rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST - &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST + 1) + == PMGR_SCRATCH_BOOT_MANIFEST_REGISTERS); + + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagObjectManifestHashValid) != 0) { + pHash = &((uint32_t *)boot_manifest_hash)[0]; + pScratch = &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST; + + // Copy the boot manifest hash from the scratch registers. + while (pScratch <= &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST) { + *pHash++ = *pScratch++; + } + return 0; + } + + return -1; +} + +int32_t platform_set_boot_manifest_hash(const uint8_t *boot_manifest_hash) +{ + volatile uint32_t *pScratch = &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST; + uint32_t *pHash; + + ASSERT((&rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST - &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_FIRST + 1) + == PMGR_SCRATCH_BOOT_MANIFEST_REGISTERS); + + if (boot_manifest_hash != NULL) { + pHash = &((uint32_t *)boot_manifest_hash)[0]; + + // Copy the boot manifest hash to the scratch registers. + while (pScratch <= &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST) { + *pScratch++ = *pHash++; + } + + rPMGR_SCRATCH0 |= kPlatformScratchFlagObjectManifestHashValid; + } else { + // Clear the boot manifest hash in the scratch registers. + while (pScratch <= &rPMGR_SCRATCH_BOOT_MANIFEST_HASH_LAST) { + *pScratch++ = 0; + } + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagObjectManifestHashValid; + } + return 0; +} + +#if WITH_SIDP + +// Returns true if Silicon Data Protection ROM manifest is locked. +bool platform_sidp_rom_manifest_locked(void) +{ + return (rMINIPMGR_SEAL_CTL_A & MINIPMGR_SECURITY_SEAL_CTL_A_LOCK_UMASK) != 0; +} + +// Returns true if Silicon Data Protection boot manifest is locked. +bool platform_sidp_boot_manifest_locked(void) +{ + return (rMINIPMGR_SEAL_CTL_B & MINIPMGR_SECURITY_SEAL_CTL_B_LOCK_UMASK) != 0; +} + +#if APPLICATION_SECUREROM + +// Lock the Silicon Data Protection ROM manifest +void platform_sidp_lock_rom_manifest(void) +{ + // Can't already be locked. + RELEASE_ASSERT(!platform_sidp_rom_manifest_locked()); + rMINIPMGR_SEAL_CTL_A |= MINIPMGR_SECURITY_SEAL_CTL_A_LOCK_UMASK; +} + +// Set the Silicon Data Protection ROM manifest +void platform_sidp_set_rom_manifest(const uint32_t *manifest_hash, size_t manifest_hash_size) +{ + // Can't already be locked. + RELEASE_ASSERT(!platform_sidp_rom_manifest_locked()); + + volatile uint32_t *seal_reg = &rMINIPMGR_SEAL_DATA_A_FIRST; + + if (manifest_hash == NULL) { + // Clear the seal data A registers + while (seal_reg <= &rMINIPMGR_SEAL_DATA_A_LAST) { + *seal_reg++ = 0; + } + + // Mark the seal as invalid. + rMINIPMGR_SEAL_CTL_A &= ~MINIPMGR_SECURITY_SEAL_CTL_A_VALID_UMASK; + + } else { + const uint32_t *manifest_end = manifest_hash + (manifest_hash_size / sizeof(uint32_t)); + + // Copy the manifest hash to seal data A registers. + do { + // Copy the manifest to seal A registers. If we run out of + // manifest before we run out of seal regsiters, store zero. + if (manifest_hash < manifest_end) { + *seal_reg++ = *manifest_hash++; + } else { + *seal_reg++ = 0; + } + } while (seal_reg <= &rMINIPMGR_SEAL_DATA_A_LAST); + + // Mark the seal data as valid. + rMINIPMGR_SEAL_CTL_A |= MINIPMGR_SECURITY_SEAL_CTL_A_VALID_UMASK; + } +} + +#else // !APPLICATION_SECUREROM + +// Lock the Silicon Data Protection boot manifest +void platform_sidp_lock_boot_manifest(void) +{ + // Can't already be locked. + RELEASE_ASSERT(!platform_sidp_boot_manifest_locked()); + rMINIPMGR_SEAL_CTL_B |= MINIPMGR_SECURITY_SEAL_CTL_B_LOCK_UMASK; + + dprintf(DEBUG_SPEW, "SiDP boot manifest locked\n"); +} + +// Set the Silicon Data Protection boot manifest +void platform_sidp_set_boot_manifest(const uint32_t *manifest_hash, size_t manifest_hash_size) +{ + // Can't already be locked. + RELEASE_ASSERT(!platform_sidp_boot_manifest_locked()); + + volatile uint32_t *seal_reg = &rMINIPMGR_SEAL_DATA_B_FIRST; + + if (manifest_hash == NULL) { + // Clear the seal data B registers + while (seal_reg <= &rMINIPMGR_SEAL_DATA_B_LAST) { + *seal_reg++ = 0; + } + + // Mark the seal as invalid. + rMINIPMGR_SEAL_CTL_B &= ~MINIPMGR_SECURITY_SEAL_CTL_B_VALID_UMASK; + + dprintf(DEBUG_SPEW, "SiDP boot manifest marked invalid\n"); + + } else { + const uint32_t *manifest_end = manifest_hash + (manifest_hash_size / sizeof(uint32_t)); + + // Copy the manifest hash to seal data B registers. + do { + // Copy the manifest to seal B registers. If we run out of + // manifest before we run out of seal regsiters, store zero. + if (manifest_hash < manifest_end) { + *seal_reg++ = *manifest_hash++; + } else { + *seal_reg++ = 0; + } + } while (seal_reg <= &rMINIPMGR_SEAL_DATA_B_LAST); + + // Mark the seal data as valid. + rMINIPMGR_SEAL_CTL_B |= MINIPMGR_SECURITY_SEAL_CTL_B_VALID_UMASK; + + dprintf(DEBUG_SPEW, "SiDP boot manifest marked valid\n"); + } +} + +// Set the Silicon Data Protection mix-n-match attribute +void platform_sidp_set_mix_n_match(void) +{ + rMINIPMGR_SET_ONLY |= MINIPMGR_SET_ONLY_MIX_N_MATCH; + + dprintf(DEBUG_SPEW, "SiDP boot manifest min-n-match state set\n"); +} + +#endif // APPLICATION_IBOOT +#endif // WITH_SIDP + +bool platform_get_mix_n_match_prevention_status(void) +{ + return ((rPMGR_SCRATCH0 & kPlatformScratchFlagVerifyManifestHash) ? true : false); +} + +void platform_set_mix_n_match_prevention_status(bool mix_n_match_prevented) +{ + if (mix_n_match_prevented) + rPMGR_SCRATCH0 |= kPlatformScratchFlagVerifyManifestHash; + else + rPMGR_SCRATCH0 &= ~kPlatformScratchFlagVerifyManifestHash; +} + +void platform_set_consistent_debug_root_pointer(uint32_t root) +{ + rMINIPMGR_SCRATCH1 = root; +} + +int platform_convert_voltages(int buck, uint32_t count, uint32_t *voltages) +{ +#if SUPPORT_FPGA + uint32_t index; + for (index = 0; index < count; index++) + power_get_buck_value_fpga(buck, voltages[index], &voltages[index]); + return 0; +#elif WITH_HW_POWER + int rail; + uint32_t index; + + if (voltages == 0) return -1; + + if (0 != power_convert_buck_to_rail(buck, &rail)) + return -1; + + for (index = 0; index < count; index++) { + if (voltages[index] == 0) + continue; + + if (0 != power_get_rail_value(rail, voltages[index], &voltages[index])) + return -1; + } + + return 0; +#else + return -1; +#endif +} + +int platform_get_cpu_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_voltage(cnt); + } + + return 0; +} + +int platform_get_soc_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_soc_voltage(cnt); + } + + return 0; +} + +uintptr_t platform_get_memory_region_base_optional(memory_region_type_t region) +{ + uintptr_t base; + + switch (region) { + case kMemoryRegion_Panic: + base = PANIC_BASE; + break; + + case kMemoryRegion_StorageProcessor: + base = ASP_BASE; + break; + + case kMemoryRegion_SecureProcessor: + base = TZ0_BASE; + break; + + case kMemoryRegion_Kernel: + base = TZ0_BASE + TZ0_SIZE; + // XXX: kernel must be loaded at a 32 MB aligned address. We'll want to reclaim this + // memory, but for now, just throw it away + // Maui: Align kernel to 32 MB without wasting memory + base += 0x2000000-1; + base &= ~(0x2000000ULL - 1); + break; + + case kMemoryRegion_PageTables: + base = PAGE_TABLES_BASE; + break; + + case kMemoryRegion_Heap: + base = HEAP_BASE; + break; + + case kMemoryRegion_Stacks: + base = STACKS_BASE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + base = CONSISTENT_DEBUG_BASE; + break; + + case kMemoryRegion_SleepToken: + base = SLEEP_TOKEN_BUFFER_BASE; + break; + + case kMemoryRegion_DramConfig: + base = DRAM_CONFIG_SEQ_BASE; + break; + + case kMemoryRegion_Display: + base = PANIC_BASE - DISPLAY_SIZE; + break; + + case kMemoryRegion_iBoot: + base = IBOOT_BASE; + break; + + case kMemoryRegion_AOP: + base = AOP_SRAM_BASE_ADDR; + break; + + case kMemoryRegion_Reconfig: + base = AOP_RECONFIG_REGION_BASE_ADDR; + break; +#endif + + default: + base = (uintptr_t)-1; + break; + } + + return base; +} + +size_t platform_get_memory_region_size_optional(memory_region_type_t region) +{ + size_t size; + + switch (region) { + case kMemoryRegion_Panic: + size = PANIC_SIZE; + break; + + case kMemoryRegion_StorageProcessor: + size = ASP_SIZE; + break; + + case kMemoryRegion_SecureProcessor: + size = TZ0_SIZE; + break; + + case kMemoryRegion_Kernel: + size = DISPLAY_BASE - platform_get_memory_region_base(kMemoryRegion_Kernel); + break; + + case kMemoryRegion_PageTables: + size = PAGE_TABLES_SIZE; + break; + + case kMemoryRegion_Heap: + size = HEAP_SIZE; + break; + + case kMemoryRegion_Stacks: + size = STACKS_SIZE; + break; + +#if APPLICATION_IBOOT + case kMemoryRegion_ConsistentDebug: + size = CONSISTENT_DEBUG_SIZE; + break; + + case kMemoryRegion_SleepToken: + size = SLEEP_TOKEN_BUFFER_SIZE; + break; + + case kMemoryRegion_DramConfig: + size = DRAM_CONFIG_SEQ_SIZE; + break; + + case kMemoryRegion_Display: + size = DISPLAY_SIZE; + break; + + case kMemoryRegion_iBoot: + size = IBOOT_SIZE; + break; + + case kMemoryRegion_AOP: + size = AOP_RECONFIG_REGION_BASE_ADDR - AOP_SRAM_BASE_ADDR; + break; + + case kMemoryRegion_Reconfig: + size = AOP_RECONFIG_REGION_SIZE; + break; +#endif + + default: + size = (size_t)-1; + break; + } + + return size; +} + +#if defined(WITH_MENU) && WITH_MENU + +int do_sleep_token_test(int argc, struct cmd_arg *args) +{ + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0; + + security_create_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90); + + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0) = 0x12345678; + *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4) = 0xaabbccdd; + dprintf(DEBUG_INFO, "original info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + if (security_validate_sleep_token(SLEEP_TOKEN_BUFFER_BASE + 0x90) == false) { + dprintf(DEBUG_INFO, "failed to validate token\n"); + return 0; + } + + dprintf(DEBUG_INFO, "saved info buffer: %#x %#x\n", *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA0), *(uint32_t *)(SLEEP_TOKEN_BUFFER_BASE + 0xA4)); + + return 0; +} + +MENU_COMMAND_DEBUG(sleep_token, do_sleep_token_test, "sleep token test - creates and validate it", NULL); + +#endif + +int platform_get_cpu_ram_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_cpu_sram_voltage(cnt); + } + + return 0; +} + +int platform_get_gpu_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_gpu_voltage(cnt); + } + + return 0; +} + +int platform_get_gpu_ram_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_gpu_sram_voltage(cnt); + } + + return 0; +} + +int platform_get_ram_voltages(uint32_t count, uint32_t *voltages) +{ + uint32_t cnt; + + if (voltages == 0) return -1; + + for (cnt = 0; cnt < count; cnt++) { + voltages[cnt] = chipid_get_sram_voltage(cnt); + } + + return 0; +} + +/* + * Gets equivalent mV for a given DWI value for a particular buck. + * PMU code should handle the special case for GPU buck. + */ +int platform_get_dwi_to_mv(int buck, uint32_t dwival) +{ +#if SUPPORT_FPGA + return power_convert_dwi_to_mv_fpga(buck, dwival); +#elif WITH_HW_POWER + int rail; + + if (0 != power_convert_buck_to_rail(buck, &rail)) + return -1; + + return power_convert_dwi_to_mv(rail, dwival); +#else + return -1; +#endif +} + +static void platform_init_boot_strap(void) +{ + volatile uint32_t boot_strap, chip_board_id, gpio_board_id, boot_config; + + // If rPMGR_SCRATCH0[0] set then boot strap already valid + if ((rPMGR_SCRATCH0 & kPlatformScratchFlagBootStrap) != 0) return; + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_IN); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOOT_CONFIG0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOOT_CONFIG2, GPIO_PDN); + + platform_power_spin(100); // Wait 100us + + chip_board_id = chipid_get_board_id(); + gpio_board_id = gpio_get_board_id(); + + boot_config = + (gpio_read(GPIO_BOOT_CONFIG2) << 2) | + (gpio_read(GPIO_BOOT_CONFIG1) << 1) | + (gpio_read(GPIO_BOOT_CONFIG0) << 0); + + gpio_configure(GPIO_BOOT_CONFIG0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOOT_CONFIG2, GPIO_CFG_DFLT); + + boot_strap = (((chip_board_id << 5) | gpio_board_id) << 16) | + (boot_config << 8) | + (0x01 << 0); + + rPMGR_SCRATCH0 = (rPMGR_SCRATCH0 & 0xFF000000) | (boot_strap & 0x00FFFFFF); +} + +#if WITH_BOOT_XNU +static void platform_bootprep_darwin(void) +{ +#if PRODUCT_IBOOT || PRODUCT_IBEC + extern addr_t gKernelEntry; // Kernel entry point + +#if WITH_PAINT + if (paint_color_map_is_invalid()) + panic("Previous DClr errors prevent OS booting"); +#endif + +/* 1. Setup trustzones */ + + /* clean-invalidate TZ0 region */ + platform_cache_operation((CACHE_CLEAN | CACHE_INVALIDATE), (void *)TZ0_BASE, TZ0_SIZE); + + /* create sleep token */ + /* already created by load_kernelcache call */ + + /* program values */ + for (uint32_t i = 0; i < NUM_AMCCS; i++) { + rMCCLOCKREGION_TZ0BASEADDR(i) = TZ0_BASE >> 12; + rMCCLOCKREGION_TZ0ENDADDR(i) = (TZ0_BASE + TZ0_SIZE - 1) >> 12; + + /* Lock TZ0 region. */ + rMCCLOCKREGION_TZ0LOCK(i) = AMCC_MCC_LOCK_REGION_TZ0_LOCK_FLD_UMASK; + if ((rMCCLOCKREGION_TZ0LOCK(i) & AMCC_MCC_LOCK_REGION_TZ0_LOCK_FLD_UMASK) == 0) { + panic("TZ0 failed to lock\n"); + } + } + + /* 2. Override IO_RVBAR - the kernel guarantees that it's reset vector + is at the beginning of the 4KB (yes, I really mean 4KB) page + containing the kernel entry point. */ + ccc_override_and_lock_iorvbar(gKernelEntry & ~0xfff); + +#if WITH_SIDP + /* Seal the manifest that authorizes the kernelcache. */ + security_sidp_seal_boot_manifest(false); +#endif + +#if 0 // !!!FIXME!!! H9: Implement AOP_S2R suspend/resume + // Update the calibration values in the sequence with values that were saved to AOP_SRAM + extern void dcs_restore_calibration_results(volatile uint32_t *save_region, uint32_t *sequence); + dcs_restore_calibration_results((volatile uint32_t *) MEMORY_CALIB_SAVE_BASE_ADDR, mcu_aop_awake_reconfig_restore); + // Insert Reconfig sequences + reconfig_init(); + platform_awake_to_aop_ddr_pre_sequence_insert(); + platform_awake_to_aop_ddr_post_sequence_insert(); + platform_aop_ddr_to_s2r_aop_pre_sequence_insert(); + platform_s2r_aop_to_aop_ddr_post_sequence_insert(); + platform_aop_ddr_to_awake_pre_sequence_insert(); + platform_aop_ddr_to_awake_post_sequence_insert(); + + /* XXX + - tunable values + - timeouts during state transitions + - lockdown regions + */ +#endif // !!!FIXME!!! +#else // !(PRODUCT_IBOOT || PRODUCT_IBEC) + // Booting the kernel is not supported from anything except iBoot and iBEC. + panic("Kernel booting not supported"); +#endif // PRODUCT_IBOOT || PRODUCT_IBEC +} +#endif // WITH_BOOT_XNU + +uint32_t platform_get_pcie_l1ss_ltr_threshold(void) +{ + // Per Cayman tunables spec r0.11 (16 Apr 2015), section 7.2 3(a). + return 85; +} + +uint32_t platform_get_pcie_l1ss_t_common_mode(void) +{ + // Per Cayman tunables spec r0.11 (16 Apr 2015), section 7.2 2(b). + return 0; +} + +static int power_convert_buck_to_rail(int buck, int *rail) +{ + if (!rail) + return -1; + + switch (buck) { +#if APPLICATION_IBOOT +#ifndef BUCK_CPU +#error BUCK_CPU not defined for this platform +#endif + +#ifndef BUCK_CPU_RAM +#error BUCK_CPU_RAM not defined for this platform +#endif + +#ifndef BUCK_SOC +#error BUCK_SOC not defined for this platform +#endif + +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + +#ifndef BUCK_GPU_RAM +#error BUCK_GPU_RAM not defined for this platform +#endif + + case BUCK_CPU: + *rail = POWER_RAIL_CPU; + break; + case BUCK_CPU_RAM: + *rail = POWER_RAIL_CPU_RAM; + break; + case BUCK_SOC: + *rail = POWER_RAIL_SOC; + break; + case BUCK_GPU: + *rail = POWER_RAIL_GPU; + break; + case BUCK_GPU_RAM: + *rail = POWER_RAIL_GPU_RAM; + break; +#endif + default: + return -1; + } + + return 0; +} + +#if SUPPORT_FPGA +static void power_get_buck_value_fpga(int buck, uint32_t mv, uint32_t *val) +{ + if (mv == 0) { + *val = 0; + } else { + switch(buck) { +#if APPLICATION_IBOOT + case BUCK_CPU: + case BUCK_GPU: + *val = (((mv-500)*1000)+3124)/3125; + break; +#endif + + default: + *val = (((mv-600)*1000)+3124)/3125; + break; + } + } + return; +} + +static int power_convert_dwi_to_mv_fpga(unsigned int buck, uint32_t dwival) +{ + int val = 0; +#if APPLICATION_IBOOT + if (buck == BUCK_GPU) { + val = (dwival == 0) ? 0 : (500000 + (3125 * dwival))/1000; + } +#endif + return val; +} +#endif + +#if WITH_BOOT_XNU +static void platform_awake_to_aop_ddr_pre_sequence_insert() +{ + reconfig_command_raw(AWAKE_AOP_DDR_PRE, awake_to_aop_ddr_pre, sizeof(awake_to_aop_ddr_pre)/sizeof(uint32_t)); + reconfig_commit(AWAKE_AOP_DDR_PRE); +} + +static void platform_awake_to_aop_ddr_post_sequence_insert() +{ + reconfig_command_raw(AWAKE_AOP_DDR_POST, awake_to_aop_ddr_post, sizeof(awake_to_aop_ddr_post)/sizeof(uint32_t)); + reconfig_commit(AWAKE_AOP_DDR_POST); + +} + +static void platform_aop_ddr_to_s2r_aop_pre_sequence_insert() +{ + reconfig_command_raw(AOP_DDR_S2R_AOP_PRE, aop_ddr_to_s2r_aop_pre, sizeof(aop_ddr_to_s2r_aop_pre)/sizeof(uint32_t)); + reconfig_commit(AOP_DDR_S2R_AOP_PRE); + +} + +static void platform_s2r_aop_to_aop_ddr_post_sequence_insert() +{ + reconfig_command_raw(S2R_AOP_AOP_DDR_POST, s2r_aop_to_aop_ddr_post, sizeof(s2r_aop_to_aop_ddr_post)/sizeof(uint32_t)); + + // TZ lock region inserted here + for (uint32_t i = 0; i < NUM_AMCCS; i++) { + reconfig_command_write(S2R_AOP_AOP_DDR_POST, MCCLOCKREGION_TZ0BASEADDR(i), TZ0_BASE>>12, 0); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, MCCLOCKREGION_TZ0ENDADDR(i), (TZ0_BASE + TZ0_SIZE - 1)>>12, 0); + reconfig_command_write(S2R_AOP_AOP_DDR_POST, MCCLOCKREGION_TZ0LOCK(i), 1, 0); + reconfig_command_read(S2R_AOP_AOP_DDR_POST, MCCLOCKREGION_TZ0LOCK(i), 1, 1, 255, 0); + } + + reconfig_command_raw(S2R_AOP_AOP_DDR_POST, s2r_aop_to_aop_ddr_post_2, sizeof(s2r_aop_to_aop_ddr_post_2)/sizeof(uint32_t)); + reconfig_command_raw(S2R_AOP_AOP_DDR_POST, mcu_aop_ddr_reconfig, sizeof(mcu_aop_ddr_reconfig)/sizeof(uint32_t)); + reconfig_command_raw(S2R_AOP_AOP_DDR_POST, s2r_aop_to_aop_ddr_post_3, sizeof(s2r_aop_to_aop_ddr_post_3)/sizeof(uint32_t)); + reconfig_commit(S2R_AOP_AOP_DDR_POST); + +} + +static void platform_aop_ddr_to_awake_pre_sequence_insert() +{ + reconfig_command_raw(AOP_DDR_AWAKE_PRE, aop_ddr_to_awake_pre, sizeof(aop_ddr_to_awake_pre)/sizeof(uint32_t)); + reconfig_commit(AOP_DDR_AWAKE_PRE); + +} + +static void platform_aop_ddr_to_awake_post_sequence_insert() +{ +#if !SUPPORT_FPGA + reconfig_command_raw(AOP_DDR_AWAKE_POST, mcu_aop_awake_reconfig_pre_restore, sizeof(mcu_aop_awake_reconfig_pre_restore)/sizeof(uint32_t)); + reconfig_command_raw(AOP_DDR_AWAKE_POST, mcu_aop_awake_reconfig_restore, sizeof(mcu_aop_awake_reconfig_restore)/sizeof(uint32_t)); + reconfig_command_raw(AOP_DDR_AWAKE_POST, mcu_aop_awake_reconfig_post_restore, sizeof(mcu_aop_awake_reconfig_post_restore)/sizeof(uint32_t)); +#endif + reconfig_command_raw(AOP_DDR_AWAKE_POST, aop_ddr_to_awake_post, sizeof(aop_ddr_to_awake_post)/sizeof(uint32_t)); + + reconfig_command_write(AOP_DDR_AWAKE_POST, CCC_CPU0_SYS_BASE_ADDR + ACC_CPU0_IMPL_IO_RVBAR_OFFSET, (TZ0_BASE + TZ0_SIZE), 1); + + reconfig_command_raw(AOP_DDR_AWAKE_POST, aop_ddr_to_awake_post_2, sizeof(aop_ddr_to_awake_post_2)/sizeof(uint32_t)); + reconfig_commit(AOP_DDR_AWAKE_POST); + +} +#endif // WITH_BOOT_XNU + +#if WITH_TARGET_CONFIG + +// The target's rules.mk sets the high SoC voltage point +#ifndef TARGET_BOOT_SOC_VOLTAGE +#error TARGET_BOOT_SOC_VOLTAGE not defined by the target +#endif + +uint32_t platform_get_base_soc_voltage(void) +{ + return chipid_get_soc_voltage(TARGET_BOOT_SOC_VOLTAGE); +} + +// The target's rules.mk sets the high CPU voltage point +#ifndef TARGET_BOOT_CPU_VOLTAGE +#error TARGET_BOOT_CPU_VOLTAGE not defined by the target +#endif + +uint32_t platform_get_base_cpu_voltage(void) +{ + return chipid_get_cpu_voltage(TARGET_BOOT_CPU_VOLTAGE); +} + +// The target's rules.mk sets the high RAM voltage point +#ifndef TARGET_BOOT_RAM_VOLTAGE +#error TARGET_BOOT_RAM_VOLTAGE not defined by the target +#endif + +uint32_t platform_get_base_ram_voltage(void) +{ + return chipid_get_sram_voltage(TARGET_BOOT_RAM_VOLTAGE); +} + +#endif + +#if defined(WITH_MENU) && WITH_MENU + +static int get_total_leakage(int argc, struct cmd_arg *args) +{ + dprintf(DEBUG_INFO, "total leakage: %dmA\n", chipid_get_total_rails_leakage()); + return 0; +} +MENU_COMMAND_DEBUG(leakage, get_total_leakage, "total rails leakage read from fuse", NULL); +#endif + diff --git a/platform/t8010/miu/miu.c b/platform/t8010/miu/miu.c new file mode 100644 index 0000000..a4f24cf --- /dev/null +++ b/platform/t8010/miu/miu.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void miu_configure_bridge(const uint32_t *bridge_settings); + +#define STATIC_BRIDGE_SHIFT (28) +#define STATIC_BRIDGE_MASK ((1 << STATIC_BRIDGE_SHIFT) - 1) + +// !!!FIXME!!! H9: Implement static MIU bridge setting +#define SB_WIDGETS (0 << STATIC_BRIDGE_SHIFT) +#define SOCBUSMUX_WIDGETS (1 << STATIC_BRIDGE_SHIFT) +#define SWITCH_FAB_WIDGETS (2 << STATIC_BRIDGE_SHIFT) +#define CP_WIDGETS (3 << STATIC_BRIDGE_SHIFT) + +static const uint64_t bridge_registers[] = { +#if 0 // H9: Implement static MIU bridge setting + SB_BASE_ADDR, + SOC_BUSMUX_BASE_ADDR, + SWTCH_FAB_BASE_ADDR, + CP_COM_BASE_ADDR, +#endif + 0 +}; + + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +static const uint32_t bridge_settings_static[] = { + 0,0 +}; + +#endif // (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +#if WITH_DEVICETREE +#if SUPPORT_FPGA + +struct bridge_list_t { + char *bridge_settings; + uint32_t fpga_enable_mask; +}; + +#define BRIDGE(b, m) { "bridge-settings-" #b, (m) } + +// ALERT: The ordering effects the device tree entries under pmgr node's reg dictionary. +// It also affects the bridge id used in the pmgr device-clock nodes. The +// bridge id must match the id on the device tree bridge-settings- properties. +// NOTE: The second parameter on the BRIDGE macro is used to dynamically determine +// which bridge settings properties should exist based upon the hardware +// blocks actually present on the device. + +static const struct bridge_list_t bridge_list[] = { + BRIDGE(0, FPGA_HAS_MEDIA), // Media Bus Mux + BRIDGE(1, FPGA_HAS_MSR), // MSR_AXI2AF + BRIDGE(2, FPGA_HAS_JPEG), // AJPEG_AXI2AF + BRIDGE(3, FPGA_HAS_AVE), // AVE_AXI2AF + BRIDGE(4, FPGA_HAS_VXD), // VDEC0_AXI2AF + BRIDGE(5, FPGA_HAS_ISP), // ISP_DMA_AXI2AF + ISAP_KF_AXI2AF + BRIDGE(6, FPGA_HAS_RTBUSMUX), // RTBusMux + BRIDGE(7, FPGA_HAS_DISP), // Disp0 + BRIDGE(8, FPGA_HAS_GFX), // GFX + BRIDGE(9, FPGA_HAS_GFX), // GFX_AFUSER + BRIDGE(10, FPGA_HAS_ALWAYS), // USB + BRIDGE(11, FPGA_HAS_ALWAYS), // PCIe +}; + +#endif // SUPPORT_FPGA +#endif // WITH_DEVICETREE + +extern void ausb_setup_widgets(); + +int miu_initialize_internal_ram(void) +{ +#if APPLICATION_SECUREROM + // Ensure that rPMGR_SCRATCH0-3 get cleared + rPMGR_SCRATCH0 = 0; + rPMGR_SCRATCH1 = 0; + rPMGR_SCRATCH2 = 0; + rPMGR_SCRATCH3 = 0; +#endif /* APPLICATION_SECUREROM */ + + // Save the Security Epoch in the top byte of PMGR_SCRATCH0 + rPMGR_SCRATCH0 &= ~0xFF000000; + rPMGR_SCRATCH0 |= (platform_get_security_epoch()) << 24; + + return 0; +} + +int miu_init(void) +{ +#if APPLICATION_IBOOT && !PRODUCT_IBEC + // Verify that the Security Epoch in PMGR_SCRATCH0 matches + if ((rPMGR_SCRATCH0 >> 24) != platform_get_security_epoch()) { + panic("miu_init: Epoch Mismatch\n"); + } +#endif +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + miu_configure_bridge(bridge_settings_static); +#endif + ausb_setup_widgets(); + + return 0; +} + +void miu_suspend(void) +{ + /* nothing required for suspend */ +} + +int miu_initialize_dram(bool resume) +{ + RELEASE_ASSERT(!resume); + +#if APPLICATION_IBOOT && WITH_HW_DCS + mcu_initialize_dram(resume); +#endif + return 0; +} + +void miu_select_remap(enum remap_select sel) +{ + switch (sel) { + case REMAP_SRAM: + rSECUREROMCTRL_ROMADDRREMAP = (rSECUREROMCTRL_ROMADDRREMAP & ~MINIPMGR_SECURITY_MCC_ROMADDRREMAP_ROMADDRRREMAP_UMASK) | SECUREROMCTRL_ROMADDRREMAP_SRAM; + break; + + case REMAP_SDRAM: + rSECUREROMCTRL_ROMADDRREMAP = (rSECUREROMCTRL_ROMADDRREMAP & ~MINIPMGR_SECURITY_MCC_ROMADDRREMAP_ROMADDRRREMAP_UMASK) | SECUREROMCTRL_ROMADDRREMAP_SDRAM; + break; + } +} + +void miu_bypass_prep(void) +{ +} + +static void miu_configure_bridge(const uint32_t *bridge_settings) +{ + volatile uint32_t *reg; + uint32_t cnt = 0, bridge, offset, data; + + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + while ((bridge_settings[cnt] != 0) || (bridge_settings[cnt + 1] != 0)) { + bridge = bridge_settings[cnt] >> STATIC_BRIDGE_SHIFT; + offset = bridge_settings[cnt] & STATIC_BRIDGE_MASK; + data = bridge_settings[cnt + 1]; + reg = (volatile uint32_t *)(bridge_registers[bridge] + offset); + *reg = data; + cnt += 2; + } + cnt += 2; + } +} + +#if WITH_DEVICETREE + +#define DEBUG_BRIDGE DEBUG_SPEW // Debug level for bridge messages + +void miu_update_device_tree(DTNode *pmgr_node) +{ +#if SUPPORT_FPGA + DTNode *node; + char *propName; + void *propData; + uint32_t propSize; + uint32_t fpga_blocks = chipid_get_fpga_block_instantiation(); + uint32_t i; + + dprintf(DEBUG_INFO, "chipid_get_fpga_block_instantiation() = 0x%08X\n", + fpga_blocks); + + if (FindNode(0, "arm-io/pmgr", &node)) { + + // For each bridge... + for (i = 0; i < ARRAY_SIZE(bridge_list); i++) { + + // Filter out if not supported by FPGA + if (!(fpga_blocks & bridge_list[i].fpga_enable_mask)) { + + propName = bridge_list[i].bridge_settings; + + if (FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_CRITICAL, "Eliding %s\n", propName); + propName[0] = '~'; + } + } + } + } +#endif // SUPPORT_FPGA +} + +#endif // WITH_DEVICETREE diff --git a/platform/t8010/miu/rules.mk b/platform/t8010/miu/rules.mk new file mode 100644 index 0000000..9582e87 --- /dev/null +++ b/platform/t8010/miu/rules.mk @@ -0,0 +1,15 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_MIU=1 + +ALL_OBJS += $(LOCAL_DIR)/miu.o diff --git a/platform/t8010/pmgr/pmgr.c b/platform/t8010/pmgr/pmgr.c new file mode 100644 index 0000000..55a9d0a --- /dev/null +++ b/platform/t8010/pmgr/pmgr.c @@ -0,0 +1,2697 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void arm_no_wfe_spin(uint32_t usecs); + +struct clock_config_active { + uint32_t clk; + uint32_t clock_reg_val; +}; + +struct clock_source { + uint32_t src_clk; + uint32_t factor; +}; + +#define CLOCK_SOURCES_MAX 12 + +struct clock_config { + volatile uint32_t *clock_reg; // CLKCFG Register + struct clock_source sources[CLOCK_SOURCES_MAX]; // List of sources +}; + +struct device_config { + volatile uint32_t *ps_reg; // PS Register +}; + +struct dvfm_data +{ + uint32_t dvfm_state_vmax; + uint32_t dvfm_state_iboot_cnt; + uint32_t dvfm_state_vnom; + uint32_t dvfm_state_vboost; + uint32_t voltage_states1_count; + uint32_t voltage_states1_size; +}; + +#define PLL_FREQ_TARGET(pllx) (((pllx##_O) * (pllx##_M)) / (pllx##_P) / ((pllx##_S) + 1)) + +#if APPLICATION_SECUREROM +static uint32_t active_state = kDVFM_STATE_SECUREROM; +#endif + +#if APPLICATION_IBOOT +static uint32_t active_state = kDVFM_STATE_IBOOT; +#endif + +#if APPLICATION_SECUREROM +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_SECUREROM +#endif + +#if APPLICATION_IBOOT +#define SOC_PERF_STATE_ACTIVE kSOC_PERF_STATE_VMIN +#endif + +struct pmgr_soc_perf_state { + uint32_t entry[4]; +}; + +static struct pmgr_soc_perf_state pmgr_soc_perf_states[] = { + [kSOC_PERF_STATE_BYPASS] = { + { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + } + }, + +#if APPLICATION_SECUREROM + [kSOC_PERF_STATE_SECUREROM] = { + { + // SBR = 266.66 / 2 + // SLOW_AF = 355.56 / 2 + // FAST_AF = 533.33 / 2 + 0x00066600, + // SIO_C = 400 / 2 + 0x60000000, + // PMP = 200 / 2 + 0x00000050, + 0x00000000 + } + }, +#endif + +#if APPLICATION_IBOOT + [kSOC_PERF_STATE_VMIN] = { + // ISP_PEARL = 320 + // ISP_AHFD = 400 + // ISP_C = 800 + // SBR = 266.66 + // SLOW_AF = 355.56 + // FAST_AF = 533.33 + // AMCC_CFG_SEL = 0x0 // !!!FIXME!!! Finalize value + // MCU_REF_CFG = 0x3 + // MCU_REF_CLK = 133 + { + 0x66566637, + + // SIO_C = 400 + // GFX_FENDER = 533.33 + // MSR = 355.56 + // AJPEG_WRAP = 320 + // AJPEG_IP = 266.67 + // VENC = 533.33 + // VDEC = 266.66 + // ISP = 355.56 + 0x66666666, + + // AMCC_AUX_BUCKET_SEL = 0x0 // !!!FIXME!!! Finalize value + // BIU div low + // PMP = 200 + // DISP0 = 355.56 + 0x00000056, + 0x00000000 + } + }, + + [kSOC_PERF_STATE_VNOM] = { + // ISP_PEARL = 400 + // ISP_AHFD = 533.33 + // ISP_C = 800 + // SBR = 400 + // SLOW_AF = 533.33 + // FAST_AF = 800 + // AMCC_CFG_SEL = 0x0 // !!!FIXME!!! Finalize value + // MCU_REF_CFG = 0x0 + // MCU_REF_CLK = 133 + { + 0x55555505, + + // SIO_C = 533.33 + // GFX_FENDER = 800 + // MSR = 533.33 + // AJPEG_WRAP = 480 + // AJPEG_IP = 360 + // VENC = 720 + // VDEC = 400 + // ISP = 480 + 0x55555555, + + // AMCC_AUX_BUCKET_SEL = 0x0 // !!!FIXME!!! Finalize value + // BIU div high + // PMP = 200 + // DISP0 = 480 + 0x00000155, + 0x00000000 + } + }, +#endif // APPLICATION_IBOOT +}; + +#if APPLICATION_SECUREROM +static uint32_t perf_level = kPerformanceHigh; +#endif + +#if APPLICATION_IBOOT +static uint32_t perf_level = kPerformanceMemoryMid; + +/* LPPLL @192MHz */ +#define LPPLL_T LPPLL_FREQ + +/* PLL0 @1600MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 200 +#define PLL0_S 0 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @1440MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 60 +#define PLL1_S 0 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + + +/* PLL2 @1200MHz */ +#define PLL2 2 +#define PLL2_O OSC_FREQ +#define PLL2_P 1 +#define PLL2_M 50 +#define PLL2_S 0 +#define PLL2_T PLL_FREQ_TARGET(PLL2) + +// Spare +// /* PLL3 @101MHz */ +// #define PLL3 3 +// #define PLL3_O OSC_FREQ +// #define PLL3_P 2 +// #define PLL3_M 101 +// #define PLL3_S 11 +// #define PLL3_T PLL_FREQ_TARGET(PLL3) + +/* PLL4 @1066MHz */ +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 9 +#define PLL4_M 400 +#define PLL4_S 0 +#define PLL4_T PLL_FREQ_TARGET(PLL4) + +/* PLL5 managed by GFX */ + +/* PLL_PCIE 6 @100MHz */ +#define PLL_PCIE 6 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 125 +#define PLL_PCIE_S 29 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + + +static const struct clock_config_active clk_configs_active[] = { + // Mini-PMGR clocks: + {PMGR_CLK_AOP, 0x81100000}, // 192 (LPO) + {PMGR_CLK_UART0, 0x84100000}, // 24 (LPO / 8) + {PMGR_CLK_UART1, 0x84100000}, // 24 (LPO / 8) + {PMGR_CLK_UART2, 0x84100000}, // 24 (LPO / 8) + {PMGR_CLK_AOP_MCA0_M, 0x83100000}, // 24 (LPO / 8) + {PMGR_CLK_I2CM, 0x83100000}, // 24 (LPO / 8) + {PMGR_CLK_PDM_REF, 0x81100000}, // 192 (LPO) + {PMGR_CLK_SENSE_2X, 0x83100000}, // 13.714 (LPO / 14) + {PMGR_CLK_DETECT, 0x81100000}, // 96 (LPO / 2) + {PMGR_CLK_PROXY_FABRIC, 0x82100000}, // 96 (LPO / 2) + {PMGR_CLK_PROXY_MCU_REF, 0x81100000}, // 48 (LPO / 4) + + // Spares: + {PMGR_CLK_S0, 0x00000000}, // 0 + {PMGR_CLK_S1, 0x00000000}, // 0 + {PMGR_CLK_S2, 0x00000000}, // 0 + {PMGR_CLK_S3, 0x00000000}, // 0 + {PMGR_CLK_ISP_REF0, 0x83000004}, // 50 (PLL0 / 8 / 4) + {PMGR_CLK_ISP_REF1, 0x83000004}, // 50 (PLL0 / 8 / 4) + {PMGR_CLK_ISP_REF2, 0x83000004}, // 50 (PLL0 / 8 / 4) + + // PMGR clocks: + {PMGR_CLK_GFX_FENDER, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_MCU_REF, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_PMP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_TEMP_MIPI_DSI, 0x03100000}, // 800 (PLL2) -- disabled + {PMGR_CLK_NCO_REF0, 0x85100000}, // 800 (PLL0 / 2) + {PMGR_CLK_NCO_REF1, 0x85100000}, // 800 (PLL0 / 2) + {PMGR_CLK_NCO_ALG0, 0x80100000}, // 24 (OSC) + {PMGR_CLK_NCO_ALG1, 0x85100000}, // 100 (PLL0 / 16) + {PMGR_CLK_HSICPHY_REF_12M, 0x85100000}, // 12 (OSC / 2) + {PMGR_CLK_USB480_0, 0x85100000}, // 480 (PLL1 / 3) + {PMGR_CLK_USB_OHCI_48M, 0x85100000}, // 48 (PLL1 / 30) + {PMGR_CLK_USB, 0x85100000}, // 120 (PLL1 / 12) + {PMGR_CLK_USB_FREE_60M, 0x85100000}, // 60 (PLL1 / 24) + {PMGR_CLK_SIO_C, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_SIO_P, 0x80100000}, // 24 (OSC) + {PMGR_CLK_SIO_AES, 0x85100000}, // 533 (PLL4 / 2) + {PMGR_CLK_HFD, 0x85100000}, // 97 (PLL4 / 11) + {PMGR_CLK_ISP_C, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP_AHFD, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP_PEARL, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_ISP_SENSOR0_REF, 0x81100000}, // ISP_REF0 + {PMGR_CLK_ISP_SENSOR1_REF, 0x82100000}, // ISP_REF1 + {PMGR_CLK_ISP_SENSOR2_REF, 0x83100000}, // ISP_REF2 + {PMGR_CLK_VDEC, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_VENC, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_VID0, 0x85100000}, // 320 (PLL0 / 5) + {PMGR_CLK_DISP0, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_AJPEG_IP, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_AJPEG_WRAP, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_MSR, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_FAST_AF, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_SLOW_AF, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_SBR, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_MCA0_M, 0x85100000}, // NCO0 + {PMGR_CLK_MCA1_M, 0x86100000}, // NCO1 + {PMGR_CLK_MCA2_M, 0x87100000}, // NCO2 + {PMGR_CLK_MCA3_M, 0x88100000}, // NCO3 + {PMGR_CLK_MCA4_M, 0x89100000}, // NCO4 + {PMGR_CLK_SEP, 0x85100000}, // 800 (PLL0 / 2) + {PMGR_CLK_GPIO, 0x85100000}, // 50 (PLL0 / 32) + {PMGR_CLK_SPI0_N, 0x85100000}, // 61.54 (PLL0 / 26) + {PMGR_CLK_SPI1_N, 0x85100000}, // 61.54 (PLL0 / 26) + {PMGR_CLK_SPI2_N, 0x85100000}, // 61.54 (PLL0 / 26) + {PMGR_CLK_SPI3_N, 0x85100000}, // 61.54 (PLL0 / 26) + {PMGR_CLK_TMPS, 0x85100000}, // 1.2 (OSC / 20) + {PMGR_CLK_CPU_UVD, 0x85100000}, // 533 (PLL4 / 2) + {PMGR_CLK_GFX_UVD, 0x85100000}, // 533 (PLL4 / 2) + {PMGR_CLK_SOC_UVD, 0x85100000}, // 533 (PLL4 / 2) + {PMGR_CLK_LPDP_RX_REF, 0x85100000}, // 533 (PLL4 / 2) +}; + +static void set_gfx_perf_state(uint32_t state_num, enum chipid_voltage_index voltage_index); + +#endif /* APPLICATION_IBOOT */ + +#if APPLICATION_SECUREROM + +/* PLL0 @800MHz */ +#define PLL0 0 +#define PLL0_O OSC_FREQ +#define PLL0_P 3 +#define PLL0_M 200 +#define PLL0_S 1 +#define PLL0_T PLL_FREQ_TARGET(PLL0) + +/* PLL1 @720MHz */ +#define PLL1 1 +#define PLL1_O OSC_FREQ +#define PLL1_P 1 +#define PLL1_M 60 +#define PLL1_S 1 +#define PLL1_T PLL_FREQ_TARGET(PLL1) + +/* PLL4 @533.33MHz */ +#define PLL4 4 +#define PLL4_O OSC_FREQ +#define PLL4_P 9 +#define PLL4_M 400 +#define PLL4_S 1 +#define PLL4_T PLL_FREQ_TARGET(PLL4) + +/* PLL_PCIE (6) @100MHz */ +#define PLL_PCIE 6 +#define PLL_PCIE_O OSC_FREQ +#define PLL_PCIE_P 1 +#define PLL_PCIE_M 125 +#define PLL_PCIE_S 29 +#define PLL_PCIE_T PLL_FREQ_TARGET(PLL_PCIE) + +static const struct clock_config_active clk_configs_active[] = { + // Mini-PMGR clocks: + + // Spares: + + // PMGR clocks: + {PMGR_CLK_PMP, 0x85100000}, // SOC_PERF_STATE + {PMGR_CLK_USB, 0x87100000}, // 50 ((PLL0 / 16) / 2 + {PMGR_CLK_SIO_C, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_SIO_P, 0x88100000}, // 40 (PLL0 / 20) / 2 + {PMGR_CLK_FAST_AF, 0x88100000}, // SOC_PERF_STATE + {PMGR_CLK_SLOW_AF, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_SBR, 0x86100000}, // SOC_PERF_STATE + {PMGR_CLK_SEP, 0x85100000}, // 400 ((PLL0 / 2) / 2) + {PMGR_CLK_GPIO, 0x85100000}, // 25 ((PLL0 / 32) / 2) + {PMGR_CLK_TMPS, 0x85100000}, // 1.2 (OSC / 20) +}; + +#endif /* APPLICATION_SECUREROM */ + +static const struct clock_config clk_configs[PMGR_CLK_COUNT] = { +[PMGR_CLK_GFX_FENDER] = { + &rPMGR_CLK_CFG(GFX_FENDER), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 3 }, + } + }, + [PMGR_CLK_MCU_REF] = { + &rPMGR_CLK_CFG(MCU_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 8 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_PLL3, 1 }, + { PMGR_CLK_PROXY_MCU_REF, 1 }, + } + }, + [PMGR_CLK_PMP] = { + &rPMGR_CLK_CFG(PMP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PROXY_FABRIC, 1 }, + } + }, + [PMGR_CLK_TEMP_MIPI_DSI] = { + &rPMGR_CLK_CFG(TEMP_MIPI_DSI), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_PLL2, 1 }, + } + }, + [PMGR_CLK_NCO_REF0] = { + &rPMGR_CLK_CFG(NCO_REF0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL4, 3 }, + } + }, + [PMGR_CLK_NCO_REF1] = { + &rPMGR_CLK_CFG(NCO_REF1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL4, 3 }, + } + }, + [PMGR_CLK_NCO_ALG0] = { + &rPMGR_CLK_CFG(NCO_ALG0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL1, 24 }, + } + }, + [PMGR_CLK_NCO_ALG1] = { + &rPMGR_CLK_CFG(NCO_ALG1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + { PMGR_CLK_PLL1, 24 }, + } + }, + [PMGR_CLK_HSICPHY_REF_12M] = { + &rPMGR_CLK_CFG(HSICPHY_REF_12M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 2 }, + } + }, + [PMGR_CLK_USB480_0] = { + &rPMGR_CLK_CFG(USB480_0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + } + }, + [PMGR_CLK_USB_OHCI_48M] = { + &rPMGR_CLK_CFG(USB_OHCI_48M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 30 }, + } + }, + [PMGR_CLK_USB] = { + &rPMGR_CLK_CFG(USB), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 12 }, + { PMGR_CLK_PLL1, 30 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL1, 24 }, + { PMGR_CLK_PLL4, 32 }, + } + }, + [PMGR_CLK_USB_FREE_60M] = { + &rPMGR_CLK_CFG(USB_FREE_60M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 24 }, + } + }, + [PMGR_CLK_SIO_C] = { + &rPMGR_CLK_CFG(SIO_C), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL4, 4 }, + } + }, + [PMGR_CLK_SIO_P] = { + &rPMGR_CLK_CFG(SIO_P), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL4, 9 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 20 }, + { PMGR_CLK_OSC, 2 }, + } + }, + [PMGR_CLK_SIO_AES] = { + &rPMGR_CLK_CFG(SIO_AES), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 4 }, + } + }, + [PMGR_CLK_HFD] = { + &rPMGR_CLK_CFG(HFD), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 11 }, + { PMGR_CLK_PLL4, 22 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_ISP_C] = { + &rPMGR_CLK_CFG(ISP_C), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 3 }, + } + }, + [PMGR_CLK_ISP_AHFD] = { + &rPMGR_CLK_CFG(ISP_AHFD), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL4, 4 }, + } + }, + [PMGR_CLK_ISP_PEARL] = { + &rPMGR_CLK_CFG(ISP_PEARL), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 10 }, + } + }, + [PMGR_CLK_ISP] = { + &rPMGR_CLK_CFG(ISP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL4, 4 }, + } + }, + [PMGR_CLK_ISP_SENSOR0_REF] = { + &rPMGR_CLK_CFG(ISP_SENSOR0_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 }, + { PMGR_CLK_ISP_REF2, 1 }, + } + }, + [PMGR_CLK_ISP_SENSOR1_REF] = { + &rPMGR_CLK_CFG(ISP_SENSOR1_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 }, + { PMGR_CLK_ISP_REF2, 1 }, + } + }, + [PMGR_CLK_ISP_SENSOR2_REF] = { + &rPMGR_CLK_CFG(ISP_SENSOR2_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_ISP_REF0, 1 }, + { PMGR_CLK_ISP_REF1, 1 }, + { PMGR_CLK_ISP_REF2, 1 }, + } + }, + [PMGR_CLK_VDEC] = { + &rPMGR_CLK_CFG(VDEC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL0, 10 }, + } + }, + [PMGR_CLK_VENC] = { + &rPMGR_CLK_CFG(VENC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL4, 4 }, + } + }, + [PMGR_CLK_VID0] = { + &rPMGR_CLK_CFG(VID0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL0, 7 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 16 }, + { PMGR_CLK_PLL2, 1 }, + } + }, + [PMGR_CLK_DISP0] = { + &rPMGR_CLK_CFG(DISP0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_AJPEG_IP] = { + &rPMGR_CLK_CFG(AJPEG_IP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 4 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PLL0, 16 }, + } + }, + [PMGR_CLK_AJPEG_WRAP] = { + &rPMGR_CLK_CFG(AJPEG_WRAP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_MSR] = { + &rPMGR_CLK_CFG(MSR), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL4, 4 }, + } + }, + [PMGR_CLK_FAST_AF] = { + &rPMGR_CLK_CFG(FAST_AF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PROXY_FABRIC, 1 }, + } + }, + [PMGR_CLK_SLOW_AF] = { + &rPMGR_CLK_CFG(SLOW_AF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL1, 3 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PROXY_FABRIC, 1 }, + } + }, + [PMGR_CLK_SBR] = { + &rPMGR_CLK_CFG(SBR), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL4, 3 }, + { PMGR_CLK_PLL0, 8 }, + { PMGR_CLK_PROXY_FABRIC, 1 }, + } + }, + [PMGR_CLK_MCA0_M] = { + &rPMGR_CLK_CFG(MCA0_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA1_M] = { + &rPMGR_CLK_CFG(MCA1_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA2_M] = { + &rPMGR_CLK_CFG(MCA2_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA3_M] = { + &rPMGR_CLK_CFG(MCA3_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_MCA4_M] = { + &rPMGR_CLK_CFG(MCA4_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_NCO_REF0, 1 }, + { PMGR_CLK_OSC, 2 }, + { PMGR_CLK_OSC, 4 }, + } + }, + [PMGR_CLK_SEP] = { + &rPMGR_CLK_CFG(SEP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL0, 4 }, + { PMGR_CLK_PLL4, 3 }, + } + }, + [PMGR_CLK_GPIO] = { + &rPMGR_CLK_CFG(GPIO), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 32 }, + { PMGR_CLK_PLL4, 32 }, + { PMGR_CLK_OSC, 1 }, + } + }, + [PMGR_CLK_SPI0_N] = { + &rPMGR_CLK_CFG(SPI0_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_SPI1_N] = { + &rPMGR_CLK_CFG(SPI1_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_SPI2_N] = { + &rPMGR_CLK_CFG(SPI2_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_SPI3_N] = { + &rPMGR_CLK_CFG(SPI3_N), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL0, 26 }, + { PMGR_CLK_PLL0, 32 }, + } + }, + [PMGR_CLK_TMPS] = { + &rPMGR_CLK_CFG(TMPS), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_OSC, 20 }, + } + }, + [PMGR_CLK_CPU_UVD] = { + &rPMGR_CLK_CFG(CPU_UVD), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_GFX_UVD] = { + &rPMGR_CLK_CFG(GFX_UVD), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_SOC_UVD] = { + &rPMGR_CLK_CFG(SOC_UVD), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_LPDP_RX_REF] = { + &rPMGR_CLK_CFG(LPDP_RX_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_S0, 1 }, + { PMGR_CLK_S1, 1 }, + { PMGR_CLK_S2, 1 }, + { PMGR_CLK_S3, 1 }, + { PMGR_CLK_PLL4, 2 }, + { PMGR_CLK_PLL0, 4 }, + } + }, + [PMGR_CLK_S0] = { + &rPMGR_CLK_CFG(S0), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_S1] = { + &rPMGR_CLK_CFG(S1), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_S2] = { + &rPMGR_CLK_CFG(S2), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_S3] = { + &rPMGR_CLK_CFG(S3), + { + { PMGR_CLK_PLL0, 2 }, + { PMGR_CLK_PLL1, 2 }, + { PMGR_CLK_PLL2, 1 }, + { PMGR_CLK_PLL4, 1 }, + } + }, + [PMGR_CLK_ISP_REF0] = { + &rPMGR_CLK_CFG(ISP_REF0), + { + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_ISP_REF1] = { + &rPMGR_CLK_CFG(ISP_REF1), + { + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_ISP_REF2] = { + &rPMGR_CLK_CFG(ISP_REF2), + { + { PMGR_CLK_PLL0, 5 }, + { PMGR_CLK_PLL4, 4 }, + { PMGR_CLK_PLL4, 5 }, + { PMGR_CLK_PLL0, 8 }, + } + }, + [PMGR_CLK_AOP] = { + &rMINIPMGR_CLK_CFG(AOP), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + [PMGR_CLK_UART0] = { + &rMINIPMGR_CLK_CFG(UART0), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + [PMGR_CLK_UART1] = { + &rMINIPMGR_CLK_CFG(UART1), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + [PMGR_CLK_UART2] = { + &rMINIPMGR_CLK_CFG(UART2), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + [PMGR_CLK_AOP_MCA0_M] = { + &rMINIPMGR_CLK_CFG(AOP_MCA0_M), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 1 } + } + }, + [PMGR_CLK_I2CM] = { + &rMINIPMGR_CLK_CFG(I2CM), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 1 } + } + }, + [PMGR_CLK_PDM_REF] = { + &rMINIPMGR_CLK_CFG(PDM_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 } + } + }, + [PMGR_CLK_SENSE_2X] = { + &rMINIPMGR_CLK_CFG(PDM_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 14 }, + { PMGR_CLK_LPO, 28 }, + { PMGR_CLK_LPO, 40 }, + { PMGR_CLK_LPO, 56 } + } + }, + [PMGR_CLK_DETECT] = { + &rMINIPMGR_CLK_CFG(I2CM), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 1 } + } + }, + [PMGR_CLK_PROXY_FABRIC] = { + &rMINIPMGR_CLK_CFG(PROXY_FABRIC), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 } + } + }, + [PMGR_CLK_PROXY_MCU_REF] = { + &rMINIPMGR_CLK_CFG(PROXY_MCU_REF), + { + { PMGR_CLK_OSC, 1 }, + { PMGR_CLK_LPO, 4 }, + { PMGR_CLK_LPO, 8 }, + { PMGR_CLK_LPO, 1 }, + { PMGR_CLK_LPO, 2 } + } + }, +}; + +static const struct device_config device_configs[PMGR_DEVICE_COUNT] = { + // Mini PMGR + [PMGR_DEVICE_INDEX(CLK_AOP)] = {&rMINIPMGR_PS(AOP)}, + [PMGR_DEVICE_INDEX(CLK_DEBUG)] = {&rMINIPMGR_PS(DEBUG)}, + [PMGR_DEVICE_INDEX(CLK_AOP_GPIO)] = {&rMINIPMGR_PS(AOP_GPIO)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART0)] = {&rMINIPMGR_PS(AOP_UART0)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART1)] = {&rMINIPMGR_PS(AOP_UART1)}, + [PMGR_DEVICE_INDEX(CLK_AOP_UART2)] = {&rMINIPMGR_PS(AOP_UART2)}, + [PMGR_DEVICE_INDEX(CLK_AOP_I2CM)] = {&rMINIPMGR_PS(AOP_I2CM)}, + [PMGR_DEVICE_INDEX(CLK_AOP_MCA0)] = {&rMINIPMGR_PS(AOP_MCA0)}, + [PMGR_DEVICE_INDEX(CLK_AOP_PDM_REF)] = {&rMINIPMGR_PS(AOP_PDM_REF)}, + [PMGR_DEVICE_INDEX(CLK_AOP_CPU)] = {&rMINIPMGR_PS(AOP_CPU)}, + [PMGR_DEVICE_INDEX(CLK_AOP_FILTER)] = {&rMINIPMGR_PS(AOP_FILTER)}, + [PMGR_DEVICE_INDEX(CLK_AOP_BUSIF)] = {&rMINIPMGR_PS(AOP_BUSIF)}, + [PMGR_DEVICE_INDEX(CLK_AOP_LPD0)] = {&rMINIPMGR_PS(AOP_LPD0)}, + [PMGR_DEVICE_INDEX(CLK_AOP_LPD1)] = {&rMINIPMGR_PS(AOP_LPD1)}, + [PMGR_DEVICE_INDEX(CLK_AOP_HPDS)] = {&rMINIPMGR_PS(AOP_HPDS)}, + [PMGR_DEVICE_INDEX(CLK_AOP_HPDSC)] = {&rMINIPMGR_PS(AOP_HPDSC)}, + [PMGR_DEVICE_INDEX(CLK_AOP_HPDD)] = {&rMINIPMGR_PS(AOP_HPDD)}, + // PMGR + [PMGR_DEVICE_INDEX(CLK_SBR)] = {&rPMGR_PS(SBR)}, + [PMGR_DEVICE_INDEX(CLK_AIC)] = {&rPMGR_PS(AIC)}, + [PMGR_DEVICE_INDEX(CLK_DWI)] = {&rPMGR_PS(DWI)}, + [PMGR_DEVICE_INDEX(CLK_GPIO)] = {&rPMGR_PS(GPIO)}, + [PMGR_DEVICE_INDEX(CLK_PMS)] = {&rPMGR_PS(PMS)}, + [PMGR_DEVICE_INDEX(CLK_HSIC0PHY)] = {&rPMGR_PS(HSIC0PHY)}, + [PMGR_DEVICE_INDEX(CLK_ISPSENS0)] = {&rPMGR_PS(ISPSENS0)}, + [PMGR_DEVICE_INDEX(CLK_ISPSENS1)] = {&rPMGR_PS(ISPSENS1)}, + [PMGR_DEVICE_INDEX(CLK_ISPSENS2)] = {&rPMGR_PS(ISPSENS2)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_REF)] = {&rPMGR_PS(PCIE_REF)}, + [PMGR_DEVICE_INDEX(CLK_SOCUVD)] = {&rPMGR_PS(SOCUVD)}, + [PMGR_DEVICE_INDEX(CLK_SIO_BUSIF)] = {&rPMGR_PS(SIO_BUSIF)}, + [PMGR_DEVICE_INDEX(CLK_SIO_P)] = {&rPMGR_PS(SIO_P)}, + [PMGR_DEVICE_INDEX(CLK_SIO)] = {&rPMGR_PS(SIO)}, + [PMGR_DEVICE_INDEX(CLK_MCA0)] = {&rPMGR_PS(MCA0)}, + [PMGR_DEVICE_INDEX(CLK_MCA1)] = {&rPMGR_PS(MCA1)}, + [PMGR_DEVICE_INDEX(CLK_MCA2)] = {&rPMGR_PS(MCA2)}, + [PMGR_DEVICE_INDEX(CLK_MCA3)] = {&rPMGR_PS(MCA3)}, + [PMGR_DEVICE_INDEX(CLK_MCA4)] = {&rPMGR_PS(MCA4)}, + [PMGR_DEVICE_INDEX(CLK_PWM0)] = {&rPMGR_PS(PWM0)}, + [PMGR_DEVICE_INDEX(CLK_I2C0)] = {&rPMGR_PS(I2C0)}, + [PMGR_DEVICE_INDEX(CLK_I2C1)] = {&rPMGR_PS(I2C1)}, + [PMGR_DEVICE_INDEX(CLK_I2C2)] = {&rPMGR_PS(I2C2)}, + [PMGR_DEVICE_INDEX(CLK_I2C3)] = {&rPMGR_PS(I2C3)}, + [PMGR_DEVICE_INDEX(CLK_SPI0)] = {&rPMGR_PS(SPI0)}, + [PMGR_DEVICE_INDEX(CLK_SPI1)] = {&rPMGR_PS(SPI1)}, + [PMGR_DEVICE_INDEX(CLK_SPI2)] = {&rPMGR_PS(SPI2)}, + [PMGR_DEVICE_INDEX(CLK_SPI3)] = {&rPMGR_PS(SPI3)}, + [PMGR_DEVICE_INDEX(CLK_UART0)] = {&rPMGR_PS(UART0)}, + [PMGR_DEVICE_INDEX(CLK_UART1)] = {&rPMGR_PS(UART1)}, + [PMGR_DEVICE_INDEX(CLK_UART2)] = {&rPMGR_PS(UART2)}, + [PMGR_DEVICE_INDEX(CLK_UART3)] = {&rPMGR_PS(UART3)}, + [PMGR_DEVICE_INDEX(CLK_UART4)] = {&rPMGR_PS(UART4)}, + [PMGR_DEVICE_INDEX(CLK_UART5)] = {&rPMGR_PS(UART5)}, + [PMGR_DEVICE_INDEX(CLK_UART6)] = {&rPMGR_PS(UART6)}, + [PMGR_DEVICE_INDEX(CLK_UART7)] = {&rPMGR_PS(UART7)}, + [PMGR_DEVICE_INDEX(CLK_UART8)] = {&rPMGR_PS(UART8)}, + [PMGR_DEVICE_INDEX(CLK_AES0)] = {&rPMGR_PS(AES0)}, + [PMGR_DEVICE_INDEX(CLK_HFD0)] = {&rPMGR_PS(HFD0)}, + [PMGR_DEVICE_INDEX(CLK_MCC)] = {&rPMGR_PS(MCC)}, + [PMGR_DEVICE_INDEX(CLK_DCS0)] = {&rPMGR_PS(DCS0)}, + [PMGR_DEVICE_INDEX(CLK_DCS1)] = {&rPMGR_PS(DCS1)}, + [PMGR_DEVICE_INDEX(CLK_DCS2)] = {&rPMGR_PS(DCS2)}, + [PMGR_DEVICE_INDEX(CLK_DCS3)] = {&rPMGR_PS(DCS3)}, + [PMGR_DEVICE_INDEX(CLK_USB)] = {&rPMGR_PS(USB)}, + [PMGR_DEVICE_INDEX(CLK_USBCTLREG)] = {&rPMGR_PS(USBCTLREG)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST0)] = {&rPMGR_PS(USB2HOST0)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST0_OHCI)] = {&rPMGR_PS(USB2HOST0_OHCI)}, + [PMGR_DEVICE_INDEX(CLK_USB2HOST1)] = {&rPMGR_PS(USB2HOST1)}, + [PMGR_DEVICE_INDEX(CLK_USB_OTG)] = {&rPMGR_PS(USB_OTG)}, + [PMGR_DEVICE_INDEX(CLK_SMX)] = {&rPMGR_PS(SMX)}, + [PMGR_DEVICE_INDEX(CLK_SF)] = {&rPMGR_PS(SF)}, + [PMGR_DEVICE_INDEX(CLK_RTMUX)] = {&rPMGR_PS(RTMUX)}, + [PMGR_DEVICE_INDEX(CLK_DISP0_FE)] = {&rPMGR_PS(DISP0_FE)}, + [PMGR_DEVICE_INDEX(CLK_DISP0_BE)] = {&rPMGR_PS(DISP0_BE)}, + [PMGR_DEVICE_INDEX(CLK_MIPI_DSI)] = {&rPMGR_PS(MIPI_DSI)}, + [PMGR_DEVICE_INDEX(CLK_DP)] = {&rPMGR_PS(DP)}, + [PMGR_DEVICE_INDEX(CLK_ISP_SYS)] = {&rPMGR_PS(ISP_SYS)}, + [PMGR_DEVICE_INDEX(CLK_MEDIA)] = {&rPMGR_PS(MEDIA)}, + [PMGR_DEVICE_INDEX(CLK_JPG)] = {&rPMGR_PS(JPG)}, + [PMGR_DEVICE_INDEX(CLK_MSR)] = {&rPMGR_PS(MSR)}, + [PMGR_DEVICE_INDEX(CLK_PMP)] = {&rPMGR_PS(PMP)}, + [PMGR_DEVICE_INDEX(CLK_PMS_SRAM)] = {&rPMGR_PS(PMS_SRAM)}, + [PMGR_DEVICE_INDEX(CLK_VDEC0)] = {&rPMGR_PS(VDEC0)}, + [PMGR_DEVICE_INDEX(CLK_VENC)] = {&rPMGR_PS(VENC_SYS)}, // NOTE: Name discrepancy between _CLK_CFG and _PS register + [PMGR_DEVICE_INDEX(CLK_PCIE)] = {&rPMGR_PS(PCIE)}, + [PMGR_DEVICE_INDEX(CLK_PCIE_AUX)] = {&rPMGR_PS(PCIE_AUX)}, + [PMGR_DEVICE_INDEX(CLK_GFX)] = {&rPMGR_PS(GFX)}, + // Unmanaged + [PMGR_DEVICE_INDEX(CLK_CPU0)] = {&rPMGR_PS(CPU0)}, + [PMGR_DEVICE_INDEX(CLK_CPU1)] = {&rPMGR_PS(CPU1)}, + [PMGR_DEVICE_INDEX(CLK_CPM)] = {&rPMGR_PS(CPM)}, + [PMGR_DEVICE_INDEX(CLK_SEP)] = {&rPMGR_PS(SEP)}, + [PMGR_DEVICE_INDEX(CLK_ISP_RSTS0)] = {&rPMGR_PS(ISP_RSTS0)}, + [PMGR_DEVICE_INDEX(CLK_ISP_RSTS1)] = {&rPMGR_PS(ISP_RSTS1)}, + [PMGR_DEVICE_INDEX(CLK_ISP_VIS)] = {&rPMGR_PS(ISP_VIS)}, + [PMGR_DEVICE_INDEX(CLK_ISP_BE)] = {&rPMGR_PS(ISP_BE)}, + [PMGR_DEVICE_INDEX(CLK_ISP_PEARL)] = {&rPMGR_PS(ISP_PEARL)}, + [PMGR_DEVICE_INDEX(CLK_DPRX)] = {&rPMGR_PS(DPRX)}, + [PMGR_DEVICE_INDEX(CLK_VENC_PIPE4)] = {&rPMGR_PS(VENC_PIPE5)}, + [PMGR_DEVICE_INDEX(CLK_VENC_PIPE5)] = {&rPMGR_PS(VENC_PIPE5)}, + [PMGR_DEVICE_INDEX(CLK_VENC_ME0)] = {&rPMGR_PS(VENC_ME0)}, + [PMGR_DEVICE_INDEX(CLK_VENC_ME1)] = {&rPMGR_PS(VENC_ME1)}, +}; + +static void config_apsc_acc_state(uint32_t state, enum chipid_voltage_index voltage_index); +static uint32_t get_apsc_acc_state(void); +static void set_apsc_acc_state(uint32_t target_state); +static void config_soc_perf_state(uint32_t state, uint32_t safevol); +static void set_soc_perf_state(uint32_t target_state); +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) +static void init_soc_thermal_sensors(void); +static void init_soc_sochot(void); +static void init_cpu_thermal_sensors(void); +static void init_cpu_sochot(void); +static void init_soc_tvm_tunables(void); +#endif +static void clocks_get_frequencies(void); +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk); +static uint32_t get_pll(int32_t pll); +static uint32_t get_pll_cpu(void); +static void set_lppll(void); +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s); +static uint32_t get_spare(int32_t spare); +static void clocks_set_gates(uint64_t *devices, uint64_t *power); +static void clocks_quiesce_internal(void); +static void power_on_sep(void); + +// current clock frequencies +static uint32_t clks[PMGR_CLK_COUNT]; + +void platform_power_spin(uint32_t usecs) +{ + arm_no_wfe_spin(usecs); +} + +int clocks_init(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC || WITH_RECOVERY_MODE_IBSS)) + clocks_get_frequencies(); +#endif + + return 0; +} + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +static void set_nco_clocks(void) +{ + uint32_t i; + + // Enable this NCO with alg_ref0_clk and nco_ref0_clk. + // Note: clk_configs assumes all NCOs use nco_ref0_clk + for (i = 0; i < PMGR_NUM_NCO; i++) { + rPMGR_NCO_CLK_CFG(i) |= PMGR_NCO_CLK_CFG_ENABLE; + } +} + +static void apply_pmgr_tunables() +{ + rPMGR_VOLMAN_SOC_DELAY = (0x5 << 0) | (0x1e << 10) | (0xbb8 << 20); + + return; +} +#endif + +#if WITH_DEVICETREE +static uint64_t get_freq_from_acc_state(uint32_t state_index); + +static void pmgr_get_dvfm_data_from_vmax(struct dvfm_data *dvfm, uint32_t dvfm_state_vmax) +{ + dvfm->dvfm_state_vmax = dvfm_state_vmax; + dvfm->voltage_states1_count = dvfm_state_vmax - kDVFM_STATE_V0 + 1; + dvfm->voltage_states1_size = dvfm->voltage_states1_count * 2; + dvfm->dvfm_state_iboot_cnt = dvfm_state_vmax + 1; + dvfm->dvfm_state_vnom = kDVFM_STATE_VNOM; + dvfm->dvfm_state_vboost = dvfm_state_vmax; +} + +static void pmgr_get_dvfm_data(struct dvfm_data *dvfm) +{ + uint32_t dvfm_state_vmax; + // DVFM table is filled with kDVFM_STATE_IBOOT copy after the last valid state. Use it to find the last valid state. + for (dvfm_state_vmax = kDVFM_STATE_IBOOT; dvfm_state_vmax < kDVFM_STATE_MAX_CNT - 1; dvfm_state_vmax++) { + if (get_freq_from_acc_state(dvfm_state_vmax) > get_freq_from_acc_state(dvfm_state_vmax + 1)) { + break; + } + } + pmgr_get_dvfm_data_from_vmax(dvfm, dvfm_state_vmax); +} +#endif + +static uint64_t pmgr_get_offset_from_diff_uV(uint32_t buck, uint32_t uV) +{ + // power API is only able to convert absolute value + // So, we need to convert abolute value and do the diff. + uint32_t mV_prev = 0; + uint32_t mV; + uint32_t offset; + uint32_t zero_mV; + if (platform_get_dwi_to_mv(buck, 1) <= 0) // even if offset 0 is 0mV, offset 1 must be >0 mV. + return 0; // This platform doesn't have HW PMU or emulation + + zero_mV = platform_get_dwi_to_mv(buck, 0); + for (offset = 0; offset < 0xff; offset++) { + mV = platform_get_dwi_to_mv(buck, offset); + if ((mV - zero_mV) * 1000 >= uV) + { + // We look for the closest offset. + // It can be offset or offset -1 + if ((uV - (mV_prev - zero_mV) * 1000) < ((mV - zero_mV) * 1000 - uV)) + return offset - 1; + else + return offset; + } + mV_prev = mV; + } + panic("No offset for %d uV on buck %d\n", uV, buck); + return 0; +} + +/* + * clocks_set_default - called by SecureROM, LLB, iBSS main via + * platform_init_setup_clocks, so the current state of the chip is + * either POR, or whatever 'quiesce' did when leaving SecureROM. + */ + +int clocks_set_default(void) +{ + uint32_t cnt; + +#if APPLICATION_IBOOT + uint32_t soc_vid[kSOC_PERF_STATE_MAX_CNT]; +#endif + volatile uint32_t *clkcfg; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + + // Setup bypass DVFM state + config_apsc_acc_state(kDVFM_STATE_BYPASS, CHIPID_CPU_VOLTAGE_BYPASS); + + // Change all clocks to something safe + clocks_quiesce_internal(); + + // Setup active DVFM and SOC PERF states for the stage of boot. +#if APPLICATION_SECUREROM + config_apsc_acc_state(kDVFM_STATE_SECUREROM, CHIPID_CPU_VOLTAGE_SECUREROM); + config_soc_perf_state(kSOC_PERF_STATE_SECUREROM, 0); +#endif + +#if APPLICATION_IBOOT +#ifndef BUCK_CPU +#error BUCK_CPU not defined for this platform +#endif + +#ifndef BUCK_CPU_RAM +#error BUCK_CPU_RAM not defined for this platform +#endif + +#ifndef BUCK_SOC +#error BUCK_SOC not defined for this platform +#endif + +#ifndef BUCK_GPU +#error BUCK_GPU not defined for this platform +#endif + +#ifndef BUCK_GPU_RAM +#error BUCK_GPU_RAM not defined for this platform +#endif + + rPMGR_VOLMAN_BUCK_MAP = + PMGR_VOLMAN_BUCK_MAP_CPU_INSRT(BUCK_CPU) | + PMGR_VOLMAN_BUCK_MAP_CPU_SRAM_INSRT(BUCK_CPU_RAM) | + PMGR_VOLMAN_BUCK_MAP_SOC_INSRT(BUCK_SOC) | + PMGR_VOLMAN_BUCK_MAP_GFX_INSRT(BUCK_GPU) | + PMGR_VOLMAN_BUCK_MAP_GFX_SRAM_INSRT(BUCK_GPU_RAM); + + // APSC sleep state will use the bypass state with V0. + config_apsc_acc_state(kDVFM_STATE_BYPASS, CHIPID_CPU_VOLTAGE_BYPASS); + + for (cnt = kDVFM_STATE_IBOOT; cnt < kDVFM_STATE_MAX_CNT; cnt++) { + enum chipid_voltage_index voltage_index = dvfmperf_get_voltage_index(cnt, CHIPID_CPU_VOLTAGE); + config_apsc_acc_state(cnt, voltage_index); + } + + platform_get_soc_voltages(kSOC_PERF_STATE_IBOOT_CNT, soc_vid); + platform_convert_voltages(BUCK_SOC, kSOC_PERF_STATE_IBOOT_CNT, soc_vid); + + for (cnt = kSOC_PERF_STATE_IBOOT; cnt < kSOC_PERF_STATE_IBOOT_CNT; cnt++) { + config_soc_perf_state(cnt, soc_vid[cnt]); + } + + // Populate unused states with something safe + for (cnt = kSOC_PERF_STATE_IBOOT_CNT; cnt < kSOC_PERF_STATE_MAX_CNT; cnt++) { + config_soc_perf_state(cnt, soc_vid[kSOC_PERF_STATE_VMIN]); + } + + // TODO: Finalize DVFM/DVTM settings. This is a placeholder from Maui. + // Configure temperature ranges and measurement offsets for DVFM/DVTM + // Cayman FPGA: iBSS encounters abort when accessing DWI_PS register +#if 0 + rACC_DVFM_CFG = ACC_PWRCTL_DVFM_CFG_TEMP_THRES0_INSRT(0x8) | ACC_PWRCTL_DVFM_CFG_TEMP_THRES1_INSRT(0x21) | + ACC_PWRCTL_DVFM_CFG_TEMP_OFFST0_INSRT(0) | ACC_PWRCTL_DVFM_CFG_TEMP_OFFST1_INSRT(0); + rACC_DVFM_CFG1 = ACC_PWRCTL_DVFM_CFG1_TEMP_THRES2_INSRT(0x3A) | ACC_PWRCTL_DVFM_CFG1_TEMP_THRES2_INSRT(0); +#endif + +#if WITH_HW_DWI + extern int dwi_init(void); + dwi_init(); +#endif +#endif // APPLICATION_IBOOT + + // ACC clock set for this stage of boot. + set_apsc_acc_state(active_state); + +#if APPLICATION_IBOOT + for (cnt = 0; cnt <= kPMGR_GFX_STATE_MAX; cnt++) { + enum chipid_voltage_index index = dvfmperf_get_voltage_index(cnt, CHIPID_GPU_VOLTAGE); + set_gfx_perf_state(cnt, index); + } + + rPMGR_PLL_CFG(5) |= (PMGR_PLL_RELOCK_MODE_BYPASS << PMGR_PLL_RELOCK_MODE_SHIFT); + rPMGR_PLL_CTL(5) &= ~PMGR_PLL_BYPASS; + while (rPMGR_PLL_CTL(5) & PMGR_PLL_PENDING); + + rPMGR_GFX_PERF_STATE_CTL |= PMGR_GFX_PERF_STATE_CTL_ENABLE; +#endif + +#ifdef LPPLL_T + set_lppll(); +#endif + +#ifdef PLL0_T + set_pll(PLL0, PLL0_P, PLL0_M, PLL0_S); +#endif + +#ifdef PLL1_T + set_pll(PLL1, PLL1_P, PLL1_M, PLL1_S); +#endif + +#ifdef PLL2_T + set_pll(PLL2, PLL2_P, PLL2_M, PLL2_S); +#endif + +#ifdef PLL3_T + set_pll(PLL3, PLL3_P, PLL3_M, PLL3_S); +#endif + +#ifdef PLL4_T + set_pll(PLL4, PLL4_P, PLL4_M, PLL4_S); +#endif + +#ifdef PLL5_T + set_pll(PLL5, PLL5_P, PLL5_M, PLL5_S); +#endif + +#ifdef PLL_PCIE_T + set_pll(PLL_PCIE, PLL_PCIE_P, PLL_PCIE_M, PLL_PCIE_S); +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Turn on NCO clocks before enabling MCA clocks. + set_nco_clocks(); +#endif + + set_soc_perf_state(SOC_PERF_STATE_ACTIVE); + + // Set all clock divs to their active values + for (cnt = 0; cnt < sizeof(clk_configs_active) / sizeof(clk_configs_active[0]); cnt++) { + clkcfg = clk_configs[clk_configs_active[cnt].clk].clock_reg; + + *clkcfg = clk_configs_active[cnt].clock_reg_val; + while ((*clkcfg & PMGR_CLK_CFG_PENDING) != 0); + } + + power_on_sep(); + + clocks_get_frequencies(); + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + apply_pmgr_tunables(); +#endif + + return 0; +} + +static void config_apsc_acc_state(uint32_t state, enum chipid_voltage_index voltage_index) +{ + uint64_t value = 0; + uint64_t value_ext = 0; + uint32_t dwi_val = 0; + uint32_t dwi_sram_val = 0; + uint32_t fused_core_typ = 0; + +#if APPLICATION_IBOOT + dwi_val = chipid_get_cpu_voltage(voltage_index); + platform_convert_voltages(BUCK_CPU, 1, &dwi_val); + dwi_sram_val = chipid_get_cpu_sram_voltage(voltage_index); + platform_convert_voltages(BUCK_CPU_RAM, 1, &dwi_sram_val); +#endif + + const struct operating_point_params *params = operating_point_get_params(voltage_index, CHIPID_CPU_VOLTAGE); + if (params == NULL) { + return; + } + + value |= ACC_DVFM_ST_FCW_FRAC_INSRT(params->cpu.fcwFrac); + value |= ACC_DVFM_ST_FCW_INT_INSRT(params->cpu.fcwInt); + value |= ACC_DVFM_ST_PST_DIV_S_INSRT(params->cpu.pstDivS); + value |= ACC_DVFM_ST_MIG_DIV_S(params->cpu.migDivS); + value |= ACC_DVFM_ST_CLK_SRC(params->cpu.clkSrc); + value |= ACC_DVFM_ST_VOL_BYP(params->cpu.bypass); + value |= ACC_DVFM_ST_SAFE_VOL_INSRT(dwi_val); + value_ext |= ACC_DVFM_ST_BIU_DIV_HI_VOL(params->cpu.biuDiv4HiVol); + value_ext |= ACC_DVFM_ST_BIU_DIV_LO_VOL(params->cpu.biuDiv4LoVol); + value_ext |= ACC_DVFM_ST_DVMR_MAX_WGT(params->cpu.dvmrMaxWgt); + value_ext |= ACC_DVFM_ST_SRAM_VOL(dwi_sram_val); + + // Get the core we're booting on (0 == eCore, 1 == pCore) + fused_core_typ = MINIPMGR_MINI_MISC_CFG_CPU_CFG_BOOT_PCORE_XTRCT(rMINIPMGR_MISC_CFG_CPU); + + if (params->cpu.coreTyp == kACC_CORETYP_FUSED) + value |= ACC_DVFM_ST_CORE_TYP(fused_core_typ); + else + value |= ACC_DVFM_ST_CORE_TYP(params->cpu.coreTyp); + +#if APPLICATION_IBOOT + const struct chipid_vol_adj *adj = chipid_get_vol_adj(voltage_index); + if (adj == NULL) { + return; + } + + value |= ACC_DVFM_ST_VOL_ADJ0(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj0)); + value |= ACC_DVFM_ST_VOL_ADJ1(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj1)); + value |= ACC_DVFM_ST_VOL_ADJ2(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj2)); + value |= ACC_DVFM_ST_VOL_ADJ3(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->volAdj3)); + + value_ext |= ACC_DVFM_ST_DVFM_MAX_ADJ(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvfmMaxAdj)); + value_ext |= ACC_DVFM_ST_DVMR_ADJ0(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvmrAdj0)); + value_ext |= ACC_DVFM_ST_DVMR_ADJ1(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvmrAdj1)); + value_ext |= ACC_DVFM_ST_DVMR_ADJ2(pmgr_get_offset_from_diff_uV(BUCK_CPU, adj->dvmrAdj2)); +#endif + + rACC_DVFM_ST(state) = value; + rACC_DVFM_ST_EXT(state) = value_ext; +} + +static uint32_t get_apsc_acc_state(void) +{ + return ACC_PWRCTL_DVFM_CFG_SEL_CUR_CFG_XTRCT(rACC_DVFM_CFG_SEL); +} + +static void set_apsc_acc_state(uint32_t target_state) +{ + // DWI clock must be enabled for any state change that has voltage control enabled. + rACC_APSC_SCR = ACC_APSC_MANUAL_CHANGE(target_state); + while ((rACC_APSC_SCR & ACC_APSC_PENDING) != 0); + + return; +} + +static void config_soc_perf_state(uint32_t state, uint32_t safevol) +{ + uint32_t index = state; + +#if APPLICATION_IBOOT + if (index >= kSOC_PERF_STATE_IBOOT_CNT) + index = kSOC_PERF_STATE_VMIN; +#endif + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[index].entry[0]; + rPMGR_SOC_PERF_STATE_ENTRY_B(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[index].entry[1]; + rPMGR_SOC_PERF_STATE_ENTRY_C(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[index].entry[2] | PMGR_SOC_PERF_STATE_ENTRY_VOLTAGE(safevol); + rPMGR_SOC_PERF_STATE_ENTRY_D(PMGR_SOC_PERF_STATE_TO_ENTRY(state)) = pmgr_soc_perf_states[index].entry[3]; +} + +static void set_soc_perf_state(uint32_t target_state) +{ + rPMGR_SOC_PERF_STATE_CTL = PMGR_SOC_PERF_STATE_TO_ENTRY(target_state); + while (rPMGR_SOC_PERF_STATE_CTL & PMGR_SOC_PERF_STATE_CTL_PENDING_MASK); +} + +static void set_lppll(void) +{ + rMINIPMGR_LPPLL_CTL = MINIPMGR_LPPLL_CTL_ENABLE; + + while (rMINIPMGR_LPPLL_CTL & MINIPMGR_LPPLL_CTL_PENDING); +} + +/* + * set_pll - called by SecureROM, LLB, iBSS with PLLs in default reset state. + * See restore_clock_config_state(). + */ +static void set_pll(int32_t pll, uint32_t p, uint32_t m, uint32_t s) +{ + if (pll >= PMGR_PLL_COUNT) + panic("Invalid PLL %u", pll); + + if (pll == PLL_PCIE) { + uint32_t ana_params; + uint32_t cfg_params; + + // Set PCIE_PLL Lock Mode Tunable. + cfg_params = rPMGR_PLL_CFG(pll); + cfg_params &= ~PMGR_PLL_PCIE_CFG_LOCK_MODE_UMASK; + +#if APPLICATION_IBOOT + cfg_params |= PMGR_PLL_LOCK_MODE(PMGR_PLL_LOCK_MODE_LOCK); +#endif + rPMGR_PLL_CFG(pll) = cfg_params; + + // The PCIe PLL needs data loaded from the fuses () + ana_params = rPMGR_PLL_ANA_PARAMS3(pll); + ana_params &= ~PMGR_PLL_PCIE_ANA_PARAMS3_FCAL_VCODIGCTRL_UMASK; + ana_params |= PMGR_PLL_PCIE_ANA_PARAMS3_FCAL_VCODIGCTRL_INSRT(chipid_get_pcie_refpll_fcal_vco_digctrl()) | + PMGR_PLL_PCIE_ANA_PARAMS3_FCAL_BYPASS_UMASK; + rPMGR_PLL_ANA_PARAMS3(pll) = ana_params; + + rPMGR_PLL_CTL(pll) = PMGR_PLL_ENABLE | PMGR_PLL_LOAD | PMGR_PLL_M(m) | PMGR_PLL_PCIE_S(s); + } else { + rPMGR_PLL_CTL(pll) = PMGR_PLL_ENABLE | PMGR_PLL_LOAD | PMGR_PLL_P(p) | PMGR_PLL_M(m) | PMGR_PLL_S(s); + } + + while (rPMGR_PLL_CTL(pll) & PMGR_PLL_PENDING); +} + +static uint32_t get_pll_cpu(void) +{ + uint32_t freq; + uint32_t pllctl; + + pllctl = rACC_PLL_SCR1; + + // Fcpu <= (OSC * (PLL_FCW_INT + PLL_FCW_FRAC / 5)) / (2 * (S + 1)) + freq = OSC_FREQ; + freq *= (ACC_PWRCTL_PLL_SCR1_FCW_INT_XTRCT(pllctl) + (ACC_PWRCTL_PLL_SCR1_FCW_FRAC_XTRCT(pllctl) / 5.0)); + freq /= (2 * (1 + ACC_PWRCTL_PLL_SCR1_OP_DIVN_XTRCT(pllctl))); + + return freq; +} + +static uint32_t get_pll(int32_t pll) +{ + uint32_t pllctl; + uint32_t opdiv; + uint64_t freq = OSC_FREQ; + + pllctl = rPMGR_PLL_CTL(pll); + + if ((pllctl & PMGR_PLL_ENABLE) == 0) { + return 0; + } + else if (pllctl & PMGR_PLL_BYPASS) { + return freq; + } + + freq *= ((pllctl >> PMGR_PLL_M_SHIFT) & PMGR_PLL_M_MASK); + + if (pll == PLL_PCIE) { + opdiv = ((pllctl >> PMGR_PLL_S_SHIFT) & PMGR_PLL_PCIE_S_MASK); + if (opdiv >= 3 && opdiv <= 7) { + freq /= 16; + } else if (opdiv > 7) { + freq /= 2 * opdiv; + } + } else { + opdiv = ((pllctl >> PMGR_PLL_S_SHIFT) & PMGR_PLL_S_MASK); + freq /= opdiv + 1; + freq /= ((pllctl >> PMGR_PLL_P_SHIFT) & PMGR_PLL_P_MASK); + } + +#if DEBUG_BUILD + if (freq > 0xFFFFFFFF) + panic("Frequency value does not fit in uint32_t"); +#endif + + return (uint32_t)freq; +} + + +static uint32_t get_spare(int32_t spare) +{ + uint32_t reg_val, src_idx, src_clk, src_factor, div; + volatile uint32_t *spare_clkcfg = clk_configs[PMGR_CLK_S0 + spare].clock_reg; + + reg_val = *spare_clkcfg; + + div = reg_val & PMGR_CLK_CFG_DIVISOR_MASK; + + if (((reg_val & PMGR_CLK_CFG_ENABLE) == 0) || div == 0) + return 0; + + src_idx = (reg_val >> PMGR_CLK_CFG_SRC_SEL_SHIFT) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].src_clk; + src_factor = clk_configs[PMGR_CLK_S0 + spare].sources[src_idx].factor; + + return (clks[src_clk] / src_factor) / div; +} + +static void clocks_get_frequencies(void) +{ +#if SUPPORT_FPGA + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + + clks[PMGR_CLK_CPU] = 5000000; + clks[PMGR_CLK_USB] = 12000000; + clks[PMGR_CLK_LPO] = LPPLL_FREQ; + +#elif SUB_TARGET_T8010SIM + uint32_t cnt; + uint32_t freq = OSC_FREQ; + + for (cnt = 0; cnt < PMGR_CLK_COUNT; cnt++) + clks[cnt] = freq; + +#else + uint32_t cnt; + + clks[PMGR_CLK_OSC] = OSC_FREQ; + clks[PMGR_CLK_LPO] = LPPLL_FREQ; + + // Use get_pll() to establish the frequencies (unconfigured PLLs will bypass OSC) + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) + clks[PMGR_CLK_PLL0 + cnt] = get_pll(cnt); + + // Use get_spare() to establish the frequencies for spare clocks (unconfigured will be skipped) + for (cnt = 0; cnt < PMGR_SPARE_COUNT; cnt++) + clks[PMGR_CLK_S0 + cnt] = get_spare(cnt); + + clks[PMGR_CLK_CPU] = get_pll_cpu(); + + clocks_get_frequencies_range(PMGR_CLK_MINI_FIRST, PMGR_CLK_MINI_LAST); + clocks_get_frequencies_range(PMGR_CLK_FIRST, PMGR_CLK_LAST); +#endif +} + +static void clocks_get_frequencies_range(uint32_t start_clk, uint32_t end_clk) +{ + volatile uint32_t *reg; + uint32_t cnt, val, src_idx, src_clk, src_factor; + + if ((start_clk >= PMGR_CLK_FIRST && end_clk <= PMGR_CLK_LAST) || + (start_clk >= PMGR_CLK_MINI_FIRST && end_clk <= PMGR_CLK_MINI_LAST)) { + for (cnt = start_clk; cnt <= end_clk; cnt++) { + reg = clk_configs[cnt].clock_reg; + val = *reg; + + if ((val & PMGR_CLK_CFG_ENABLE) == 0) { + clks[cnt] = 0; + continue; + } + + src_idx = (val >> PMGR_CLK_CFG_SRC_SEL_SHIFT) & PMGR_CLK_CFG_SRC_SEL_MASK; + src_clk = clk_configs[cnt].sources[src_idx].src_clk; + src_factor = clk_configs[cnt].sources[src_idx].factor; + clks[cnt] = clks[src_clk] / src_factor; + } + } +} + +void dump_clock_frequencies() +{ + uint32_t i; + + for (i = 0; i < PMGR_CLK_COUNT; i++) { + dprintf(DEBUG_CRITICAL, "clk[%d] -> %u\n", i, clks[i]); + } +} + +static void clock_update_range(uint32_t first, uint32_t last, const uint32_t clkdata) +{ + volatile uint32_t *reg; + uint32_t cnt; + + for (cnt = first; cnt <= last; cnt++) { + reg = clk_configs[cnt].clock_reg; + *reg = clkdata; + while (*reg & PMGR_CLK_CFG_PENDING); + } +} + +static void clock_update_frequency(uint32_t clk, uint32_t freq) +{ +#define ROUND_10E4(_x) ((((_x) + 5000) / 10000) * 10000) + + uint32_t src_idx, src_clk, src_factor, reg; + bool freq_supported = false; + volatile uint32_t *clkcfg = clk_configs[clk].clock_reg; + + if (freq == 0) + return; + + for (src_idx = 0; src_idx < CLOCK_SOURCES_MAX && clk_configs[clk].sources[src_idx].factor != 0; src_idx++) + { + src_clk = clk_configs[clk].sources[src_idx].src_clk; + src_factor = clk_configs[clk].sources[src_idx].factor; + + if (ROUND_10E4(clks[src_clk] / src_factor) == freq) { + freq_supported = true; + break; + } + } + + if (freq_supported) { + // Configure clock + reg = *clkcfg; + reg &= ~(PMGR_CLK_CFG_SRC_SEL_MASK << PMGR_CLK_CFG_SRC_SEL_SHIFT); + reg |= (src_idx & PMGR_CLK_CFG_SRC_SEL_MASK) << PMGR_CLK_CFG_SRC_SEL_SHIFT; + *clkcfg = reg; + while (*clkcfg & PMGR_CLK_CFG_PENDING); + } +} + +static void restore_clock_config_state(void) +{ + uint32_t cnt; + uint32_t current_select, entry_a; + + // 2. Write reset value to ACG, CLK_DIVIDER_ACG_CFG + rPMGR_MISC_CFG_ACG = 0; + rPMGR_CLK_DIVIDER_ACG_CFG = 0; + + // 3. Write the reset value to all MCAx_CLK_CFG registers + clock_update_range(PMGR_CLK_MCA0_M, PMGR_CLK_MCA4_M, 0x80100000); + + // 4. Put the NCOs in reset state + for (cnt = 0; cnt < PMGR_NUM_NCO; cnt++) + { + rPMGR_NCO_CLK_CFG(cnt) = 0; + while (rPMGR_NCO_CLK_CFG(cnt) & PMGR_NCO_CLK_CFG_PENDING); + } + + // 5a. Write reset value for all mux clock configs (excluding spares) + clock_update_range(PMGR_CLK_FIRST, PMGR_CLK_TMPS - 1, 0x80100000); + clock_update_range(PMGR_CLK_TMPS, PMGR_CLK_TMPS, 0x85100000); + clock_update_range(PMGR_CLK_TMPS + 1, PMGR_CLK_LAST, 0x80100000); + + // Since AOP config engine will use SOC perf table entries 0 and 1, we start at the other end of the table to avoid stepping on each other. + + // 5b. Write the desired DRAM clock configuration state into the SOC_PERF_STATE_ENTRY_xA register + current_select = PMGR_SOC_PERF_STATE_CTL_CURRENT_SELECT_XTRCT(rPMGR_SOC_PERF_STATE_CTL); + entry_a = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[0]; + entry_a &= ~PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + entry_a |= rPMGR_SOC_PERF_STATE_ENTRY_A(current_select) & PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = entry_a; + + // 5c. Write the reset value to all other fields in ENTRY_xA + rPMGR_SOC_PERF_STATE_ENTRY_B(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[1]; + rPMGR_SOC_PERF_STATE_ENTRY_C(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[2]; + rPMGR_SOC_PERF_STATE_ENTRY_D(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) = pmgr_soc_perf_states[kSOC_PERF_STATE_BYPASS].entry[3]; + + // 6. Write the reset value to the SOC_PERF_STATE_CTL register + set_soc_perf_state(kSOC_PERF_STATE_BYPASS); + + // 7. Write the reset values to the SOC_PERF_STATE entry registers, except for ENTRY_xA + for (cnt = PMGR_SOC_PERF_STATE_FIRST_ENTRY; cnt < PMGR_SOC_PERF_STATE_ENTRY_COUNT; cnt++) { + if (cnt == PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_BYPASS)) + continue; + + rPMGR_SOC_PERF_STATE_ENTRY_A(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_B(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_C(cnt) = 0; + rPMGR_SOC_PERF_STATE_ENTRY_D(cnt) = 0; + } + + // 11. Write reset value to all PLLx_CTL + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 0) + continue; // Mem PLL + + if (cnt == PLL_PCIE) { + rPMGR_PLL_CTL(cnt) = PMGR_PLL_M(0x7d) | PMGR_PLL_PCIE_S(0x1d); // fb_div = 0x7d, op_div = 0x1d + } + else { + rPMGR_PLL_CTL(cnt) = PMGR_PLL_ENABLE | PMGR_PLL_BYPASS | PMGR_PLL_M(1) | PMGR_PLL_P(1); // fb_div = 1, pre_div = 1 + } + + while (rPMGR_PLL_CTL(cnt) & PMGR_PLL_PENDING); + } + + // 12. Write reset value to all other PLL registers + for (cnt = 0; cnt < PMGR_PLL_COUNT; cnt++) { + if (cnt == 0) + continue; // Mem PLL + + rPMGR_PLL_CFG(cnt) = PMGR_PLL_OFF_MODE(PMGR_PLL_OFF_MODE_POWER_DOWN) | + PMGR_PLL_FRAC_LOCK_TIME(0x48) | PMGR_PLL_LOCK_TIME(0x348); + } + + // 13. Write reset value to spare and ISP_REF0/1 + clock_update_range(PMGR_CLK_SPARE_FIRST, PMGR_CLK_SPARE_LAST, 0x80000001); + + // 14. Put CPU clock back into its reset default. + set_apsc_acc_state(kDVFM_STATE_BYPASS); + + // Mini-PMGR + + // 2. Write the reset value to the CLK_DIVIDER_ACG_CFG register + rMINIPMGR_CLK_DIVIDER_ACG_CFG = 0; + + // 3. Write the reset value to all mux clock config registers + clock_update_range(PMGR_CLK_MINI_FIRST, PMGR_CLK_MINI_LAST, 0x80100000); + + // 4. Write the reset value to LPPLL_CTL register + rMINIPMGR_LPPLL_CTL = PMGR_PLL_ENABLE | PMGR_PLL_BYPASS; + + // 5. Write the reset value to LPPLL_CFG register + rMINIPMGR_LPPLL_CFG = 0x1f; + while (rMINIPMGR_LPPLL_CTL & PMGR_PLL_PENDING); + + // 6. Write the reset value to the MISC_CFG_ACG register + rMINIPMGR_MISC_CFG_ACG = 0; +} + + +static void power_on_sep(void) +{ + volatile uint32_t *reg; + uint32_t val; + + reg = device_configs[PMGR_DEVICE_INDEX(CLK_SEP)].ps_reg; + + val = *reg; + val &= ~(PMGR_PS_AUTO_PM_EN | PMGR_PS_FORCE_NOACCESS); + *reg = val; + while (((*reg >> 4) & 0xF) != 0xF); // Wait for SEP to turn on. + + return; +} + +static void set_device(uint64_t *devices, uint64_t device) +{ +#if DEBUG_BUILD + if (device >= 128) + panic("Invalid device clock index: %llu", device); +#endif + if (device >= 64) + devices[1] |= (0x1ULL << (device - 64)); + else + devices[0] |= (0x1ULL << device); +} + +static void clocks_quiesce_internal(void) +{ + uint64_t devices[2] = { 0, 0 }; + uint64_t power[2] = { 0, 0 }; + + // Disable all voltage changes everywhere! + rPMGR_VOLMAN_CTL |= (PMGR_VOLMAN_DISABLE_CPU_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_GFX_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_CPU_SRAM_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_GFX_SRAM_VOL_CHANGE | + PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE); + + // The following devices need to be on + set_device(devices, CLK_AOP); + set_device(devices, CLK_DEBUG); + set_device(devices, CLK_AOP_GPIO); + set_device(devices, CLK_AOP_CPU); + set_device(devices, CLK_AOP_FILTER); + set_device(devices, CLK_AOP_BUSIF); + set_device(devices, CLK_SBR); + set_device(devices, CLK_AIC); + set_device(devices, CLK_DWI); + set_device(devices, CLK_GPIO); + set_device(devices, CLK_PMS); + set_device(devices, CLK_SIO_BUSIF); + set_device(devices, CLK_SIO_P); + set_device(devices, CLK_SIO); + set_device(devices, CLK_MCC); + set_device(devices, CLK_DCS0); + set_device(devices, CLK_DCS1); + set_device(devices, CLK_DCS2); + set_device(devices, CLK_DCS3); + set_device(devices, CLK_USB); + set_device(devices, CLK_USBCTLREG); + set_device(devices, CLK_USB_OTG); + set_device(devices, CLK_SMX); + set_device(devices, CLK_SF); + +#if APPLICATION_SECUREROM + // These devices need power but their clocks don't need to be on. + set_device(power, CLK_PCIE); + set_device(power, CLK_PCIE_REF); + set_device(power, CLK_PCIE_AUX); +#endif + + // Turn on/off critical device clocks + clocks_set_gates(devices, power); + + // Disable performance state table to control PLL5 + rPMGR_GFX_PERF_STATE_CTL = 0; + + restore_clock_config_state(); +} + +void clocks_quiesce(void) +{ + clocks_quiesce_internal(); +} + +uint32_t clocks_set_performance(uint32_t performance_level) +{ + uint32_t old_perf_level = perf_level; + uint32_t acc_state = get_apsc_acc_state(); + + if (acc_state != active_state) + set_apsc_acc_state(active_state); + +#if APPLICATION_IBOOT + uint32_t entry_a; + + // Enable SOC voltage changes + rPMGR_VOLMAN_CTL &= ~PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE; + + switch (performance_level) { + case kPerformanceMemoryLow: + case kPerformanceMemoryMid: + entry_a = rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)); + entry_a &= ~PMGR_SOC_PERF_STATE_ENTRY_MCU_REF_MASK; + + if (performance_level == kPerformanceMemoryLow) + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x3, 0x7); + else + entry_a |= PMGR_SOC_PERF_STATE_ENTRY_MCU_REF(0x1, 0x6); + + rPMGR_SOC_PERF_STATE_ENTRY_A(PMGR_SOC_PERF_STATE_TO_ENTRY(kSOC_PERF_STATE_VMIN)) = entry_a; + + set_soc_perf_state(kSOC_PERF_STATE_VMIN); + perf_level = performance_level; + break; + + case kPerformanceMemoryFull: + set_soc_perf_state(kSOC_PERF_STATE_VNOM); + perf_level = performance_level; + break; + + default: + break; + } + + // Disable SOC voltage changes + rPMGR_VOLMAN_CTL |= PMGR_VOLMAN_DISABLE_SOC_VOL_CHANGE; + + clocks_get_frequencies_range(PMGR_CLK_MCU_REF, PMGR_CLK_MCU_REF); +#endif + + // At this point we should have ACC clock set for this stage of boot. + return old_perf_level; +} + +void clock_get_frequencies(uint32_t *clocks, uint32_t count) +{ + uint32_t cnt = PMGR_CLK_COUNT; + + if (cnt > count) + cnt = count; + + memcpy(clocks, clks, cnt * sizeof(uint32_t)); +} + +uint32_t clock_get_frequency(int clock) +{ + uint32_t freq = 0; + + switch (clock) { + case CLK_NCLK: + case CLK_FIXED: + case CLK_TIMEBASE: + freq = clks[PMGR_CLK_OSC]; + break; + case CLK_PCLK: + case CLK_PERIPH: + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + freq = clks[PMGR_CLK_SIO_P]; + break; + case CLK_MEM: +#if SUPPORT_FPGA + freq = 1000000; +#elif SUB_TARGET_T8010SIM + freq = OSC_FREQ; +#else + // XXX Frequency is a function of MCU_REF_CLK and MCU_REF_CFG_SEL + freq = clks[PMGR_CLK_MCU_REF]; +#endif + break; + case CLK_BUS: + freq = clks[PMGR_CLK_SBR]; + break; + case CLK_CPU: + freq = clks[PMGR_CLK_CPU]; + break; + case CLK_MIPI: + freq = clks[PMGR_CLK_TEMP_MIPI_DSI]; + break; + case CLK_VCLK0: + freq = clks[PMGR_CLK_VID0]; + break; + default: + break; + } + return freq; +} + +void clock_set_frequency(int clock, uint32_t divider, uint32_t pll_p, uint32_t pll_m, uint32_t pll_s, uint32_t pll_t) +{ + uint32_t clk = PMGR_CLK_OSC; + + switch (clock) { + case CLK_MIPI: + clk = PMGR_CLK_PLL2; + break; + default: + break; + } + + if (clk >= PMGR_CLK_PLL0 && clk <= PMGR_CLK_PLL5) { + int32_t pll = clk - PMGR_CLK_PLL0; + + set_pll(pll, pll_p, pll_m, pll_s); + + clks[clk] = get_pll(pll); + if (clock == CLK_MIPI) { + clocks_get_frequencies_range(PMGR_CLK_TEMP_MIPI_DSI, PMGR_CLK_TEMP_MIPI_DSI); + } + } + + if (clk >= PMGR_CLK_FIRST && clk <= PMGR_CLK_LAST) { + clock_update_frequency(clk, pll_t); + clocks_get_frequencies_range(clk, clk); + } + + return; +} + +void clock_gate(int device, bool enable) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + // Set the PS field to the requested level + if (enable) { + *reg |= PMGR_PS_RUN_MAX; + } else { + *reg &= ~PMGR_PS_RUN_MAX; + } + + // Wait for the MANUAL_PS and ACTUAL_PS fields to be equal + while ((*reg & PMGR_PS_MANUAL_PS_MASK) != ((*reg >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); +} + +void power_on(int device) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + *reg = (*reg & ~PMGR_PS_RUN_MAX) | PMGR_PS_CLOCK_OFF; + + // Wait for the MANUAL_PS and ACTUAL_PS fields to be equal + while ((*reg & PMGR_PS_MANUAL_PS_MASK) != ((*reg >> PMGR_PS_ACTUAL_PS_SHIFT) & PMGR_PS_ACTUAL_PS_MASK)); +} + +static void clocks_set_gates(uint64_t *devices, uint64_t *power) +{ + uint32_t i, idx; + + // For future platforms that clone from this. + if (PMGR_LAST_DEVICE >= 128) + panic("Rewrite this to deal with more than 128 clock ids"); + + // Turn on devices from lo to hi (to meet dependencies). + for (idx = 0, i = PMGR_FIRST_DEVICE; i <= PMGR_LAST_DEVICE; i++) { + if (i && ((i % 64) == 0)) + idx++; + if ((devices[idx] >> ((uint64_t)(i % 64))) & 0x1) + clock_gate(i, true); + } + + // Turn off devices hi to lo order (to meet dependencies). + for (idx = 1, i = PMGR_LAST_DEVICE; i >= PMGR_FIRST_DEVICE; i--) { + if (!((devices[idx] >> ((uint64_t)(i % 64))) & 0x1)) { + if ((power[idx] >> ((uint64_t)(i % 64))) & 0x1) + power_on(i); + else + clock_gate(i, false); + } + if (i && ((i % 64) == 0)) + idx--; + } + + return; +} + +void platform_system_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_system_reset(); + + while (1); +} + +void platform_reset(bool panic) +{ +#if WITH_BOOT_STAGE + if (!panic) + boot_set_stage(kPowerNVRAMiBootStageOff); +#endif + + wdt_chip_reset(); + + while (1); +} + +void platform_power_init(void) +{ +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + // Initialize temperature sensors, thermal failsafe blocks, and TVM tunables + init_soc_thermal_sensors(); + init_cpu_thermal_sensors(); + init_soc_sochot(); + init_cpu_sochot(); + init_soc_tvm_tunables(); +#endif +} + +void clock_reset_device(int device) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + switch (device) { + case CLK_SIO: + *reg |= PMGR_PS_RESET; + spin(1); + *reg &= ~PMGR_PS_RESET; + break; + + default: + break; + } +} + +void clock_set_device_reset(int device, bool set) +{ + volatile uint32_t *reg; + + // Make sure we are within limits. + if (!PMGR_VALID_DEVICE(device)) + return; + + reg = device_configs[PMGR_DEVICE_INDEX(device)].ps_reg; + + switch (device) { + case CLK_PCIE: + if (set) + *reg |= PMGR_PS_RESET; + else + *reg &= ~PMGR_PS_RESET; + } +} + +bool clock_get_pcie_refclk_good(void) +{ + return (rPMGR_PCIE_REFCLK_GOOD & PMGR_PCIE_REFCLK_GOOD_UMASK) != 0; +} + +#if APPLICATION_IBOOT +static void set_gfx_perf_state(uint32_t state_num, enum chipid_voltage_index voltage_index) +{ + uint32_t pll_enable = 0; + const struct operating_point_params *params; + params = operating_point_get_params(voltage_index, CHIPID_GPU_VOLTAGE); + uint32_t dwi_val = 0; + uint32_t dwi_sram_val = 0; + + if (voltage_index != CHIPID_GPU_VOLTAGE_OFF) { + dwi_val = chipid_get_gpu_voltage(voltage_index); + platform_convert_voltages(BUCK_GPU, 1, &dwi_val); + dwi_sram_val = chipid_get_gpu_sram_voltage(voltage_index); + platform_convert_voltages(BUCK_GPU_RAM, 1, &dwi_sram_val); + } + + + // This is deductive. If feedback divider is 0 the PLL shouldn't output anything. + pll_enable = params->gpu.fbkDivM ? 1 : 0; + + rPMGR_GFX_PERF_STATE_ENTRY_A(state_num) = ((dwi_val & 0xFF) << 24) | + ((pll_enable & 0x1) << 21) | + ((params->gpu.fbkDivM & 0x1FF) << 12) | + ((params->gpu.preDivP & 0x1F) << 4) | + (params->gpu.pstDivS & 0xF); + + rPMGR_GFX_PERF_STATE_ENTRY_B(state_num) = dwi_sram_val & 0xFF; + + return; +} +#endif + +#if WITH_DEVICETREE +static uint64_t get_freq_from_acc_state(uint32_t state_index) +{ + uint64_t state_entry = rACC_DVFM_ST(state_index); + uint64_t freq = OSC_FREQ; + + // Fcpu <= (OSC * (PLL_FCW_INT + PLL_FCW_FRAC / 5)) / (2 * (S + 1)) + freq *= (ACC_DVFM_ST_FCW_INT_XTRCT(state_entry) + (ACC_DVFM_ST_FCW_FRAC_XTRCT(state_entry) / 5.0)); + freq /= (2 * (1 + ACC_DVFM_ST_PST_DIV_S_XTRCT(state_entry))); + + return freq; +} + +void pmgr_update_device_tree(DTNode *pmgr_node) +{ +#if 0 // !!!FIXME!!! T8010FPGA: panic: chipid_get_cpu_voltage: Invalid CPU voltage index 1880788768 + uint32_t num_freqs = 0; + uint32_t propSize; + uint64_t period_ns; + uint64_t freq = 0; + uint32_t volt; + + char *propName; + void *propData; + + struct dvfm_data dvfm; + + pmgr_get_dvfm_data(&dvfm); + + // Populate the devicetree with relevant values. + propName = "nominal-performance1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property nominal-performance1 is of wrong size."); + + freq = get_freq_from_acc_state(dvfm.dvfm_state_vnom); + if (freq == 0) + panic("pmgr Fnom Operating point not defined correctly"); + + period_ns = 1000000000ULL << 16; + period_ns /= freq; + + ((uint32_t *)propData)[0] = period_ns; + } else { + panic("pmgr property nominal-performance1 not found."); + } + + propName = "boost-performance1"; + // Note: Boost is not mandatory in all platforms. + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize != sizeof(uint32_t)) + panic("pmgr property boost-performance1 is of wrong size"); + + freq = get_freq_from_acc_state(dvfm.dvfm_state_vboost); + if (freq == 0) + panic("pmgr Fboost Operating point not defined correctly"); + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[0] = period_ns; + } + + propName = "voltage-states1"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize / sizeof(uint32_t) < dvfm.voltage_states1_size) { + panic("pmgr number of states less than required for voltage-states1"); + } + + num_freqs = dvfm.voltage_states1_count; + for (int32_t i = num_freqs - 1, j = 0; i >= 0; i--, j++) { + // Getting voltage and frequencies directly from rCCC_DVFM_ST allows + // including all the changes done before launching the kernel: + // - voltage adjusting coming from converting voltage to PMU value, + // - voltage knobs from LLB, + // - astris changes done while beeing in iBoot console, + freq = get_freq_from_acc_state(dvfm.dvfm_state_vmax - j); + volt = platform_get_dwi_to_mv(BUCK_CPU, ACC_PWRCTL_DVFM_ST0_SAFE_VOL_XTRCT(rACC_DVFM_ST(dvfm.dvfm_state_vmax - j))); + + if (freq != 0) { + period_ns = 1000000000ULL << 16; + period_ns /= freq; + ((uint32_t *)propData)[2*i] = period_ns; + ((uint32_t *)propData)[2*i+1] = volt; + } + } + } + + propName = "total-rails-leakage"; + if (FindProperty(pmgr_node, &propName, &propData, &propSize)) { + if (propSize >= sizeof(uint32_t)) { + *(uint32_t *)propData = chipid_get_total_rails_leakage(); + } + } +#endif +} + +void pmgr_gfx_update_device_tree(DTNode *gfx_node) +{ + uint32_t count, propSize, num_states = 0, state_val; + char *propName; + void *propData; + + propName = "perf-states"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + if (propSize != (2 * sizeof(uint32_t) * kPMGR_GFX_STATE_MAX)) { + panic("gfx property perf-state has wrong size"); + } + // Read the values programmed into the GFX perf state table + // and populate the device tree. + for (count = 0; count < kPMGR_GFX_STATE_MAX; count++) { + state_val = rPMGR_GFX_PERF_STATE_ENTRY_A(count); + + // Any but the first entry with a value of 0 marks the end of the number of valid states. + if ((count != 0) && (state_val == rPMGR_GFX_PERF_STATE_ENTRY_A(CHIPID_GPU_VOLTAGE_OFF))) { + num_states = count; + break; + } + + ((uint32_t *)propData)[count * 2 + 0] = PMGR_PLL_FREQ((state_val >> 12) & 0x1FF, (state_val >> 4) & 0x1F, state_val & 0xF); + ((uint32_t *)propData)[count * 2 + 1] = platform_get_dwi_to_mv(BUCK_GPU, (state_val >> 24) & 0xFF); + } + + // If all the entries are valid. + if (count == kPMGR_GFX_STATE_MAX) { + num_states = kPMGR_GFX_STATE_MAX; + } + + } + + propName = "perf-state-count"; + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = kPMGR_GFX_STATE_MAX; + } + + propName = "gpu-num-perf-states"; + /* We don't count OFF state */ + if (FindProperty(gfx_node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = num_states - 1; + } +} +#endif + +#if (APPLICATION_IBOOT && !PRODUCT_IBOOT && !PRODUCT_IBEC) + +static void init_soc_thermal_sensors(void) +{ + // Define piecewise-linear relationship (start_codes, offsets, slopes) between output and temperature for SOC/PMGR sensors + rPMGR_THERMAL0_PIECE0 = PMGR_THERMAL0_PIECE0(0x000, 0x1e5, 0x03b); + rPMGR_THERMAL0_PIECE1 = PMGR_THERMAL0_PIECE1(0x140, 0x1f4, 0x02f); + rPMGR_THERMAL0_PIECE2 = PMGR_THERMAL0_PIECE2(0x257, 0x009, 0x026); + + rPMGR_THERMAL1_PIECE0 = PMGR_THERMAL1_PIECE0(0x000, 0x1e5, 0x03b); + rPMGR_THERMAL1_PIECE1 = PMGR_THERMAL1_PIECE1(0x140, 0x1f4, 0x02f); + rPMGR_THERMAL1_PIECE2 = PMGR_THERMAL1_PIECE2(0x257, 0x009, 0x026); + + rPMGR_THERMAL2_PIECE0 = PMGR_THERMAL2_PIECE0(0x000, 0x1e5, 0x03b); + rPMGR_THERMAL2_PIECE1 = PMGR_THERMAL2_PIECE1(0x140, 0x1f4, 0x02f); + rPMGR_THERMAL2_PIECE2 = PMGR_THERMAL2_PIECE2(0x257, 0x009, 0x026); + + // Read temperature trim values from efuse and write to corresponding registers +#if 0 + rPMGR_THERMAL0_PARAM = chipid_get_soc_temp_sensor_trim(0); + rPMGR_THERMAL1_PARAM = chipid_get_soc_temp_sensor_trim(1); + rPMGR_THERMAL2_PARAM = chipid_get_soc_temp_sensor_trim(2); +#else + // Fix up ACC temp sensor gain/offset values--see 18151623 + rPMGR_THERMAL0_PARAM = PMGR_THERMAL_0_PARAM_TRIMO_INSRT(0x00) | PMGR_THERMAL_0_PARAM_TRIMG_INSRT(0x0F); + rPMGR_THERMAL1_PARAM = PMGR_THERMAL_1_PARAM_TRIMO_INSRT(0x00) | PMGR_THERMAL_1_PARAM_TRIMG_INSRT(0x0F); + rPMGR_THERMAL2_PARAM = PMGR_THERMAL_2_PARAM_TRIMO_INSRT(0x00) | PMGR_THERMAL_2_PARAM_TRIMG_INSRT(0x0F); +#endif + + // Define sampling rate for each sensor + rPMGR_THERMAL0_CTL1 = 0xea60; + rPMGR_THERMAL1_CTL1 = 0xea60; + rPMGR_THERMAL2_CTL1 = 0xea60; + + // Enable temperature sensors (need to do this before enabling either DVTM or SOCHOT) + rPMGR_THERMAL0_CTL0_SET = PMGR_THERMAL_0_CTL0_SET_ENABLE_INSRT(1); + rPMGR_THERMAL1_CTL0_SET = PMGR_THERMAL_1_CTL0_SET_ENABLE_INSRT(1); + rPMGR_THERMAL2_CTL0_SET = PMGR_THERMAL_2_CTL0_SET_ENABLE_INSRT(1); +} + +static void init_soc_sochot(void) +{ + // PMGR SOCHOT threshold temperatures have moved from the PMGR SOCHOT register block to the PMGR THERMAL block, ostensibly to provide greater + // flexibility via the ability to vary failsafe temperature threshold with PMGR location. The SOCHOT and temperature sensor drivers are separate + // entities currently, such that it would be inconvienient to coordinate how they come up (can't enable SOCHOT action until non-zero thresholds + // have been set, the SOCHOT driver doesn't really need to know how many temperature sensors are present, etc.) Accordingly, let's set the + // trip *thresholds* here and leave the drivers to do the rest, as usual. + rPMGR_THERMAL0_FAILSAFE_TRIP_TEMP_0 = 120; + rPMGR_THERMAL1_FAILSAFE_TRIP_TEMP_0 = 120; + rPMGR_THERMAL2_FAILSAFE_TRIP_TEMP_0 = 120; + + rPMGR_THERMAL0_FAILSAFE_TRIP_TEMP_1 = 125; + rPMGR_THERMAL1_FAILSAFE_TRIP_TEMP_1 = 125; + rPMGR_THERMAL2_FAILSAFE_TRIP_TEMP_1 = 125; +} + +static void init_cpu_thermal_sensors(void) +{ + // Define piecewise-linear relationship (start_codes, offsets, slopes) between output and temperature for CPU sensors + rACC_THRM0_PIECE0 = ACC_THRM0_PIECE0(0x000, 0x0e5, 0x03b); + rACC_THRM0_PIECE1 = ACC_THRM0_PIECE1(0x140, 0x0f4, 0x02f); + rACC_THRM0_PIECE2 = ACC_THRM0_PIECE2(0x257, 0x009, 0x026); + + rACC_THRM1_PIECE0 = ACC_THRM1_PIECE0(0x000, 0x0e5, 0x03b); + rACC_THRM1_PIECE1 = ACC_THRM1_PIECE1(0x140, 0x0f4, 0x02f); + rACC_THRM1_PIECE2 = ACC_THRM1_PIECE2(0x257, 0x009, 0x026); + + rACC_THRM2_PIECE0 = ACC_THRM2_PIECE0(0x000, 0x0e5, 0x03b); + rACC_THRM2_PIECE1 = ACC_THRM2_PIECE1(0x140, 0x0f4, 0x02f); + rACC_THRM2_PIECE2 = ACC_THRM2_PIECE2(0x257, 0x009, 0x026); + + // Fix up ACC temp sensor gain/offset values--see 18151623 + rACC_THRM0_PARAM = ACC_THERMAL_THRM0_PARAM_TRIMO_INSRT(0x00) | ACC_THERMAL_THRM0_PARAM_TRIMG_INSRT(0x0F); + rACC_THRM1_PARAM = ACC_THERMAL_THRM1_PARAM_TRIMO_INSRT(0x00) | ACC_THERMAL_THRM1_PARAM_TRIMG_INSRT(0x0F); + rACC_THRM2_PARAM = ACC_THERMAL_THRM2_PARAM_TRIMO_INSRT(0x00) | ACC_THERMAL_THRM2_PARAM_TRIMG_INSRT(0x0F); + + // Define sampling rate for each sensor + rACC_THRM0_CTL1 = 0xea60; + rACC_THRM1_CTL1 = 0xea60; + rACC_THRM2_CTL1 = 0xea60; + + // Enable temperature sensors (need to do this before enabling either DVTM or SOCHOT) + rACC_THRM0_CTL0_SET = ACC_THERMAL_THRM0_CTL0_SET_ENABLE_INSRT(1); + rACC_THRM1_CTL0_SET = ACC_THERMAL_THRM1_CTL0_SET_ENABLE_INSRT(1); + rACC_THRM2_CTL0_SET = ACC_THERMAL_THRM2_CTL0_SET_ENABLE_INSRT(1); +} + +static void init_cpu_sochot(void) +{ + // Set target state for when SOCHOT0 triggers + rACC_DVFM_FSHOT_IDX = ACC_THERMAL_DVFM_FSHOT_IDX_0_ST_INSRT(kDVFM_STATE_V0); +} + +static void init_soc_tvm_tunables(void) +{ +} + +#endif diff --git a/platform/t8010/pmgr/rules.mk b/platform/t8010/pmgr/rules.mk new file mode 100644 index 0000000..0dd9878 --- /dev/null +++ b/platform/t8010/pmgr/rules.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +OPTIONS += \ + WITH_HW_CLOCKS=1 \ + WITH_HW_PLATFORM_POWER=1 \ + WITH_HW_POWER_GATING=0 + +ALL_OBJS += $(LOCAL_DIR)/pmgr.o diff --git a/platform/t8010/rules.mk b/platform/t8010/rules.mk new file mode 100644 index 0000000..358dd6c --- /dev/null +++ b/platform/t8010/rules.mk @@ -0,0 +1,136 @@ +# Copyright (C) 2012-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +# modules implied by this platform +MODULES += \ + platform/defaults \ + platform/generic \ + arch/$(ARCH) + +# Devmap chip ID, CPU, and memory default configs based on sub-platform identifier +ifeq ($(SUB_PLATFORM),t8010) + ARM_CPU := apple-hurricane-zephyr + DEVMAP_CHIP_ID := 8010 + DISPLAY_SIZE_DEFAULT := 34*1024*1024 + MAX_DFU_SIZE := 512*1024 + SDRAM_LEN_DEFAULT := 2*1024*1024*1024 + SDRAM_LOAD_OFFSET := 256*1024*1024 + SDRAM_TEXT_BASE := 0x870000000 + SDRAM_TEXT_FOOTPRINT := 1024*1024 + SRAM_TEXT_BASE := 0x1800B0000 + SRAM_TEXT_FOOTPRINT := 1024*1024 + SROM_DATA_BASE := 0x180080000 + SPDS_CHIP_REV := a0 +else + $(error "Unrecognized SUB_PLATFORM \"$(SUB_PLATFORM)\"") +endif + +# SROM is always defined here +ifeq ($(TEXT_BANK),srom) + TEXT_BASE := 0x100000000 +endif + +# Overriding SRAM_LEN is not allowed. +ifeq ($(TEXT_BANK),sram) + # SRAM TEXT_BASE is fixed by SecureROM. + TEXT_BASE := $(SRAM_TEXT_BASE) + + # iBSS/LLB memory configuration + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := $(SRAM_TEXT_FOOTPRINT) + endif +endif + +# Platform target can override SDRAM config by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(SDRAM_LEN),) + SDRAM_LEN := $(SDRAM_LEN_DEFAULT) + + # iBoot/iBEC memory configuration + ifeq ($(TEXT_BANK),sdram) + # SDRAM TEXT_BASE is now set such that you don't have to do lots of math to + # calulate the correct value if you change any of the other region sizes: + # TEXT_BASE = SDRAM_BASE + SDRAM_LEN - 256MB + TEXT_BASE := $(SDRAM_TEXT_BASE) + # Platform target can override SRAM config by specifying this in target config file (apps/iBoot/$target-config.mk) + ifeq ($(TEXT_FOOTPRINT),) + TEXT_FOOTPRINT := $(SDRAM_TEXT_FOOTPRINT) + endif + endif +endif + +# Platform target can override any of these sizes by specifying in target config file (apps/iBoot/$target-config.mk) +ifeq ($(TZ0_SIZE),) + TZ0_SIZE := 12*1024*1024 +endif +ifeq ($(DISPLAY_SIZE),) + DISPLAY_SIZE := $(DISPLAY_SIZE_DEFAULT) +endif + +ifeq ($(TEXT_FOOTPRINT),) + $(error TEXT_FOOTPRINT has not been set) +endif + +# platform target can override ASP size by specifying this in target config file (apps/iBoot/$target-config.mk) +ifeq ($(ASP_SIZE),) + ASP_SIZE := 12*1024*1024 +endif + +OPTIONS += \ + AIC_CPU_ID=0 \ + ANC_PPNNPL_DS_DRIVE_STRENGTH=6 \ + ANC_PPNNPL_INPUT_SELECT_SCHMITT=1 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_HOLD_TIME=2 \ + ANC_LINK_CMD_ADDR_PULSE_TIMING_CA_SETUP_TIME=3 \ + ANC_LINK_SDR_REN_HOLD_TIME=2 \ + ANC_LINK_SDR_REN_SETUP_TIME=3 \ + ANC_LINK_SDR_WEN_HOLD_TIME=2 \ + ANC_LINK_SDR_WEN_SETUP_TIME=3 \ + ANC_LINK_SDR_DATA_CAPTURE_DELAY=1 \ + ANC_LINK_SDR_CLE_ALE_SETUP_TIME=0 \ + ANC_BOOT_CONTROLLERS=2 \ + ANC_TOGGLE_SUPPORTED=1 \ + DISPLAY_SIZE="($(DISPLAY_SIZE)ULL)" \ + PLATFORM_ENTROPY_RATIO=200 \ + PLATFORM_IRQ_COUNT=288 \ + PLATFORM_START_FUNCTION=_platform_start \ + SDRAM_LEN="$(SDRAM_LEN)ULL" \ + TZ0_SIZE="$(TZ0_SIZE)ULL" \ + ASP_SIZE="$(ASP_SIZE)" \ + SDRAM_LOAD_OFFSET="$(SDRAM_LOAD_OFFSET)ULL" \ + PLATFORM_SPDS_CHIP_REV=$(SUB_PLATFORM)/$(SPDS_CHIP_REV) \ + TEXT_BASE="$(TEXT_BASE)" \ + TEXT_FOOTPRINT="$(TEXT_FOOTPRINT)" \ + WITH_DPA=1 \ + WITH_SIDP=1 + +GLOBAL_LDFLAGS += \ + -seg1addr $(TEXT_BASE) + +ifeq ($(APPLICATION),SecureROM) + DATA_BASE := $(SROM_DATA_BASE) + GLOBAL_LDFLAGS += \ + -segaddr __DATA $(DATA_BASE) + OPTIONS += \ + WITH_ROM_TRAMPOLINE=1 \ + DATA_BASE="$(DATA_BASE)" + + ifeq ($(CONFIGS),fpga) + OPTIONS += \ + SUPPORT_FPGA=1 + endif +endif + +ALL_OBJS += \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/trampoline.o diff --git a/platform/t8010/trampoline.S b/platform/t8010/trampoline.S new file mode 100644 index 0000000..84bb728 --- /dev/null +++ b/platform/t8010/trampoline.S @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2012-2015 Apple, Inc. All rights reserved. + * + * This document is the property of Apple, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple, Inc. + */ + +#include +#include +#include +#include + +// Clears from X0 to X1 (not including X1). +// Assumes that X0 and X1 are both 64-byte aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1 +1: + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + stp xzr, xzr, [x0], #16 + cmp x0, x1 + b.lo 1b +.endmacro + +// Clears from X0 to X1 (not including X1) using cacheline clear +// operations. +// Assumes that X0 and X1 are both cacheline aligned as this +// will normally be used to clear a whole page. +.macro CLEAR_X0_TO_X1_CACHE_ON +1: + dc zva, x0 // zero cacheline + add x0, x0, #L1_CACHELINE_SIZE + cmp x0, x1 + b.lo 1b +.endmacro + + .text + .balign 16 + .globl _boot_handoff_trampoline, _boot_handoff_trampoline_end +_boot_handoff_trampoline: + + // Disable external aborts, interrupts + msr DAIFSet, #(0xf) + + // Save jump address in x29, and next stage boot info into x28. + mov x29, x0 + mov x28, x1 + + // Start by clearing the heap. + ldr x0, L_heap_base + ldr x1, L_heap_end + CLEAR_X0_TO_X1_CACHE_ON + + // Clear the stacks area. + ldr x0, L_stacks_base + ldr x1, L_stacks_end + CLEAR_X0_TO_X1_CACHE_ON + + // Retire all data accesses prior to this + // H9: L2 as RAM request RO and DO alias result in prb hang + dsb sy + // Retire all instructions executed prior to this (may include ROM). + isb sy + + // Disable caches, mmu, stack alignment fault + mov x3, #0 + msr SCTLR_EL1, x3 + dsb sy + isb sy + + // Flush the TLBs + tlbi vmalle1 + dsb sy + isb sy + + // Now running EL1 with MMU off. All accesses are device. + + // Clear the page tables. + ldr x0, L_page_tables_base + ldr x1, L_page_tables_end + CLEAR_X0_TO_X1 + + // Clear the text area (or data area in ROM) + // This can only be done if the trampoline was copied to a safe location + ldr x0, L_text_base + ldr x1, L_text_end + CLEAR_X0_TO_X1 + + // Clear all the pointers to interesting memory areas + // that were included in the trampoline + adr x0, L_pointers_base + adr x1, L_pointers_end + CLEAR_X0_TO_X1 + +#if WITH_ROM_TRAMPOLINE + // Disable R/W access to ROM region + ldr x1, L_rom_trampoline_reg + ldr w2, L_rom_trampoline_val + ldr w3, [x1] + orr w3, w3, w2 + str w3, [x1] + dsb sy + ldr w3, [x1] + tst w3, w2 // Verify ROM access is disabled + b.eq _trampoline_spin // Oops, not disabled + + // ROM doesn't pass any info to next stage (LLB) + mov x28, #0 + + // Clear remap if enabled to boot this ROM + ldr x1, L_rom_remap_reg + str wzr, [x1] +#endif // WITH_ROM_TRAMPOLINE + + // Reset CPU state + mov x1, #0 + mov x2, #0 + mov x3, #0 + mov x4, #0 + mov x5, #0 + mov x6, #0 + mov x7, #0 + mov x8, #0 + mov x9, #0 + mov x10, #0 + mov x11, #0 + mov x12, #0 + mov x13, #0 + mov x14, #0 + mov x15, #0 + mov x16, #0 + mov x17, #0 + mov x18, #0 + mov x19, #0 + mov x20, #0 + mov x21, #0 + mov x22, #0 + mov x23, #0 + mov x24, #0 + mov x25, #0 + mov x26, #0 + mov x27, #0 + mov x30, x29 // lr = next boot stage PC + mov x0, x28 // x0 = next boot stage info + mov x28, #0 + mov x29, #0 + msr TTBR0_EL1, x1 + msr VBAR_EL1, x1 + msr ELR_EL1, x1 + msr SPSR_EL1, x1 + msr SPSel, #0 + mov sp, x1 // SP_EL0 + msr SPSel, #1 + mov sp, x1 // SP_EL1 + + // Invalidate I-cache + ic iallu + dsb sy + isb sy + + ret + +#if WITH_ROM_TRAMPOLINE + // Not really able to panic at this point, so let's just spin. +_trampoline_spin: + wfe + b _trampoline_spin + + .balign 8 +L_rom_remap_reg: + .8byte REMAP_REG +L_rom_trampoline_reg: + .8byte SECURITY_REG +L_rom_trampoline_val: + .4byte ROM_READ_DISABLE +#endif // WITH_ROM_TRAMPOLINE + + .balign 64 +L_pointers_base: +#if WITH_ROM_TRAMPOLINE + // in ROM we don't erase TEXT, but we can erase DATA +L_text_base: + .8byte DATA_BASE +L_text_end: + .8byte DATA_BASE + DATA_SIZE +#else + // In non-ROM we erase TEXT_FOOTPRINT, which includes both TEXT and DATA +L_text_base: + .8byte TEXT_BASE +L_text_end: + .8byte TEXT_BASE + TEXT_FOOTPRINT +#endif // WITH_ROM_TRAMPOLINE +L_heap_base: + .8byte HEAP_BASE +L_heap_end: + .8byte HEAP_BASE + HEAP_SIZE +L_stacks_base: + .8byte STACKS_BASE +L_stacks_end: + .8byte STACKS_BASE + STACKS_SIZE +L_page_tables_base: + .8byte PAGE_TABLES_BASE +L_page_tables_end: + .8byte PAGE_TABLES_BASE + PAGE_TABLES_SIZE + .balign 64 +L_pointers_end: + +_boot_handoff_trampoline_end: + + .balign 16 diff --git a/sys/boot.c b/sys/boot.c new file mode 100644 index 0000000..e07cddf --- /dev/null +++ b/sys/boot.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +typedef void (* entry_func_t)(void *, int, int, int); +typedef void (* trampoline_func_t)(entry_func_t, void *); + +/* quiesce hardware and jump into a new image */ +void prepare_and_jump(enum boot_target boot, void *ptr, void *arg) +{ + entry_func_t entry = (entry_func_t)(uintptr_t)ptr; + trampoline_func_t trampoline = (trampoline_func_t)platform_get_boot_trampoline(); + + /* keep alive a little longer */ + platform_watchdog_tickle(); + + /* do whatever prep needs to happen before jumping into something */ + platform_bootprep(boot); + + /* make sure timers and whatnot aren't running */ + platform_quiesce_hardware(boot); + + /* verify we haven't had any heap corruption */ + heap_verify(); + + /* make sure interrupts are disabled */ + enter_critical_section(); + + /* Copy profile buffer from SRAM into panic RAM */ + PROFILE_HANDOFF(); + + /* quiesce the cpu, disabling the mmu and caches */ + arch_cpu_quiesce(); + + if (trampoline != NULL) + trampoline(entry, arg); + else + entry(arg, 0, 0, 0); + + /* should not get here */ + for(;;) ; +} diff --git a/sys/callout.c b/sys/callout.c new file mode 100644 index 0000000..97df8ad --- /dev/null +++ b/sys/callout.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +static struct list_node callout_queue; + +static int callout_init(void); +static int _callout_dequeue(struct callout *c); +static void _callout_reset_deadline(void); +static void callout_deadline(void); + +static bool ready; + +/* + * Initialise the callout system. + */ +static int callout_init(void) +{ + list_initialize(&callout_queue); + + ready = true; + + return 0; +} + +/* + * Enqueue (func) to be called after at least (delay) microseconds. + */ +void callout_enqueue(struct callout *c, utime_t delay, callout_func func, void *arg) +{ + struct callout *entry; + uint64_t now; + + /* if we have not been initialised, do so now */ + if (unlikely(!ready)) + callout_init(); + + enter_critical_section(); + + /* remove it if it's already in a list */ + _callout_dequeue(c); + + /* convert utime_t delay to absolute clock deadline */ + now = timer_get_ticks(); + c->sched_ticks = now + timer_usecs_to_ticks(delay); +// printf("callout %p: %lluus at %llu ticks (now %llu)\n", c, delay, c->sched_ticks, now); + c->delay = delay; + c->callback = func; + c->arg = arg; + + list_for_every_entry(&callout_queue, entry, struct callout, list) { + /* search through the callout queue, finding the right sorted slot */ + if (c->sched_ticks < entry->sched_ticks) { + list_add_before(&entry->list, &c->list); + goto done; + } + } + + /* either the queue was empty or our entry is the last */ + list_add_tail(&callout_queue, &c->list); + +done: + _callout_reset_deadline(); + + exit_critical_section(); +} + +/* + * Dequeue the callout (c) + */ +int callout_dequeue(struct callout *c) +{ + int err; + + enter_critical_section(); + err = _callout_dequeue(c); + exit_critical_section(); + return err; +} + +/* + * Reset the callout (c) to be called after (newdelay) microseconds. + */ +int callout_reset(struct callout *c, utime_t newdelay) +{ + int err = 0; + + enter_critical_section(); + + /* remove it if it's already in a list */ + _callout_dequeue(c); + + if (newdelay != 0) + c->delay = newdelay; + + if (c->delay == 0) { + err = -1; + } else { + callout_enqueue(c, c->delay, c->callback, c->arg); + } + + exit_critical_section(); + + return err; +} + +/* + * Reset the timer deadline as the queue may have changed. + */ +static void _callout_reset_deadline(void) +{ + struct callout *c; + + c = list_peek_head_type(&callout_queue, struct callout, list); + + if (c == NULL) { + timer_deadline_enter(0, NULL); + } else { + timer_deadline_enter(c->sched_ticks, callout_deadline); + } +} + +void callout_reset_deadline(void) +{ + enter_critical_section(); + _callout_reset_deadline(); + exit_critical_section(); +} + +/* + * Pull callout (c) from the queue (while locked) + */ +static int _callout_dequeue(struct callout *c) +{ + + if (list_in_list(&c->list)) { + list_delete(&c->list); + _callout_reset_deadline(); + return 1; + } + + return 0; +} + +/* + * Callback from the timer when the deadline expires; call all of the + * pending callouts and reschedule the deadline accordingly. + * + * Note that the timer is allowed to call us early; if we have set a + * deadline beyond its ability to handle we will do no work and just re-schedule. + */ +static void callout_deadline(void) +{ + struct callout *c; + uint64_t t; + + while ((c = list_peek_head_type(&callout_queue, struct callout, list)) != NULL) { + t = timer_get_ticks(); + + /* if the event has expired */ + if (c->sched_ticks <= t) { +// printf("callout %p: invoked, scheduled %llu now %llu\n", c, c->sched_ticks, t); + + /* remove from the list and call out */ + list_delete(&c->list); + c->callback(c, c->arg); + } else { + + /* callout in the future, schedule callback and we're done */ + timer_deadline_enter(c->sched_ticks, callout_deadline); + break; + } + } +} diff --git a/sys/debug.c b/sys/debug.c new file mode 100644 index 0000000..6707c8b --- /dev/null +++ b/sys/debug.c @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include + +#if WITH_HW_UART +# include +# if WITH_TARGET_CONFIG +# include +# elif WITH_PLATFORM_UARTCONFIG +# include +# endif +#endif + +#if APPLICATION_SECUREROM +# define DEBUG_QUEUE_LEN 256 +#else +# define DEBUG_QUEUE_LEN 4096 +#endif +static struct task_event debug_event; +static struct cbuf *debug_cbuf; + +#if WITH_USB_MODE_RECOVERY + +// Use USB serial debug, unless there's a dockfifo, because spew from that +// driver will deadlock us. +#if !defined(USE_USB_DEBUG) && !defined(WITH_HW_DOCKFIFO_BULK) +#define USE_USB_DEBUG 1 +#endif + +#include + +#endif // WITH_USB_MODE_RECOVERY + +#if WITH_TBT_MODE_RECOVERY + +#ifndef USE_TBT_DEBUG +#define USE_TBT_DEBUG 1 +#endif + +#include + +#endif // WITH_TBT_MODE_RECOVERY + +#if WITH_ARM_DCC +# include +#endif + +#if WITH_SHM_CONSOLE +# include +#endif + +#if WITH_HW_DOCKFIFO_UART +# include +#endif + +#if WITH_HW_DOCKCHANNEL_UART +# include +#endif + +int debug_getchar(void) +{ + ssize_t ret; + char c; + + ASSERT(NULL != debug_cbuf); + + event_wait(&debug_event); + ret = cbuf_read_char(debug_cbuf, &c); + ASSERT(ret >= 0); + + return c; +} + +int debug_getchar_nowait(void) +{ + ssize_t ret; + char c; + + ASSERT(NULL != debug_cbuf); + + ret = cbuf_read_char(debug_cbuf, &c); + if (ret < 1) { + return -1; + } + + return c; +} + +int debug_pushchar(int c) +{ + ASSERT(NULL != debug_cbuf); + return cbuf_write_char(debug_cbuf, c); +} + +void debug_init(void) +{ + debug_cbuf = cbuf_create(DEBUG_QUEUE_LEN, &debug_event); +} + + +int DebugUartReady = 0; + +void debug_enable_uarts(int debug_uarts) +{ + DebugUartReady |= debug_uarts; +} + +void debug_putchar(int c) +{ +#if USE_USB_DEBUG + usb_serial_putchar(c); +#endif + +#if USE_TBT_DEBUG + thunderboot_putchar(c); +#endif + +#if defined(DEBUG_SERIAL_PORT) + if ((DebugUartReady & kPowerNVRAMiBootDebugIAPSerial) != 0) { + if (c == '\n') + uart_putc(DEBUG_SERIAL_PORT, '\r'); + uart_putc(DEBUG_SERIAL_PORT, c); + } +#endif + +#if defined(DEBUG_SERIAL_PORT2) + if ((DebugUartReady & kPowerNVRAMiBootDebugAltSerial) != 0) { + if (c == '\n') + uart_putc(DEBUG_SERIAL_PORT2, '\r'); + uart_putc(DEBUG_SERIAL_PORT2, c); + } +#endif + +#if WITH_ARM_DCC + // always output dcc + arm_write_dcc_char(c); +#endif + +#if WITH_SHM_CONSOLE + if ((DebugUartReady & kPowerNVRAMiBootDebugJtag) != 0) { + if (c == '\n') + shmcon_putc(0, '\r'); + shmcon_putc(0, c); + } +#endif + +#if WITH_HW_DOCKFIFO_UART + if ((DebugUartReady & kPowerNVRAMiBootDebugIAPSerial) != 0) { + if (c == '\n') + dockfifo_uart_putc('\r'); + dockfifo_uart_putc(c); + } +#endif + +#if WITH_HW_DOCKCHANNEL_UART + if ((DebugUartReady & kPowerNVRAMiBootDebugIAPSerial) != 0) { + if (c == '\n') + dockchannel_uart_putc('\r'); + dockchannel_uart_putc(c); + } +#endif + +#if WITH_APPLICATION_PUTCHAR + application_putchar(c); +#endif + +} + +int debug_run_script(const char *addr) +{ + char lastchar; + +// printf("running script at %p\n", addr); + + /* start stuffing data into the input queue at the specified address until we hit an EOF char */ + lastchar = 0; + while ((*addr != 0x04) && (*addr != 0)) { + debug_pushchar(*addr); + lastchar = *addr; + addr++; + } + if (lastchar != '\n') + debug_pushchar('\n'); + +// printf("finished running script (EOF at %p)\n", addr); + return 0; +} + diff --git a/sys/halt.c b/sys/halt.c new file mode 100644 index 0000000..5ecb2c9 --- /dev/null +++ b/sys/halt.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#if WITH_CONSISTENT_DBG +#include +#endif + +#if WITH_HW_TIMER +#include +#endif + +/* + * Make the panic info easy to find. + */ +char * gPanicStr; /* pointer to current panic string or NULL if not doing panic */ +const char * gPanicFunc; /* pointer to function calling panic */ +#if defined(__LP64__) +static char panicBuf[1024]; /* buffer for constructed panic message */ +#else +static char panicBuf[512]; /* buffer for constructed panic message */ +#endif +static unsigned panicDepth = 0; +static u_int64_t panicStamp; + +static const char doublePanic[] = "double panic in "; + +void _panic(const char *func, const char *str, ...) +{ + va_list ap; +#if WITH_PANIC_HOOKS + void ** cursor; + struct panic_hook * hook; +#endif + + /* There are cases where panic can spiral out of control if the task structure + * was demolished. Detect recursion here before doing anything else, and STOP + * (with interrupts known to have been masked). */ + if (++panicDepth > 2) + arch_spin(); + + /* make sure that interrupts are masked and don't get enabled during panic */ + enter_critical_section(); + + if (NULL != gPanicStr) { + /* + * We are already trying to panic, so this is very bad. + * Do our very best to get the 'double panic' string into + * the panic buffer. + */ + memcpy(panicBuf, doublePanic, sizeof(doublePanic)); + gPanicFunc = func; + strlcat(panicBuf, func, sizeof(panicBuf)); + + /* clean the cache so that the panic string is in memory */ + platform_cache_operation(CACHE_PANIC | CACHE_CLEAN, 0, 0); + + /* and try to print it */ + puts("\n\n"); + puts(panicBuf); + puts("\n\n"); + + /* spin here - not safe to do anything else */ + arch_spin(); + } + +#if WITH_HW_TIMER + panicStamp = timer_get_ticks(); +#endif + + /* + * First pass through the panic path + */ + + /* gPanicFunc can be compared with NULL to test whether we are panicking */ + gPanicFunc = func; + + /* construct the panic string */ + gPanicStr = panicBuf; + va_start(ap, str); + vsnprintf(panicBuf, sizeof(panicBuf), str, ap); + va_end(ap); + + /* clean the cache so that the panic string is in memory */ + platform_cache_operation(CACHE_PANIC | CACHE_CLEAN, 0, 0); + + /* emit it */ + puts("\npanic: "); + puts(func); + puts(": "); + puts(panicBuf); + puts("\n\n"); + +#if WITH_CONSISTENT_DBG && (PRODUCT_IBEC || PRODUCT_IBOOT) + consistent_debug_update_ap_cpr(DBG_CPR_STATE_CRASHED, DBG_CPR_AP_PANICKED_IN_IBOOT); + // Register location of panic string + dbg_record_header_t dbghdr; + dbghdr.physaddr = (uintptr_t)(mem_static_map_physical((uintptr_t)panicBuf)); + dbghdr.length = sizeof(panicBuf); + dbghdr.record_id = kDbgIdPanicHeaderAP; + consistent_debug_register_header(dbghdr); +#endif + +#if WITH_PANIC_HOOKS + /* run the set of panic handlers */ + LINKER_SET_FOREACH(cursor, panic_hooks) { + hook = (struct panic_hook *)*cursor; + hook->func(hook->arg); + } + +#endif + /* XXX try to drain the console here */ + + /* clean the cache again to get console output out in case the application is saving it */ + platform_cache_operation(CACHE_PANIC | CACHE_CLEAN, 0, 0); + + +#if !DEBUG_BUILD + platform_reset(true); +#else + halt(); +#endif +} + +void abort(void) +{ + panic("abort"); +} + +void halt() +{ + printf("\nsystem halted, spinning forever...\n"); + + /* try to quiesce hardware to make JTAG easier */ + //prepare_and_jump(BOOT_HALT, (void *)(uintptr_t)&arch_spin, NULL); + arch_spin(); +} + +#if defined(__SSP_ALL__) +#error "Can't compile stack.c with -fstack-protector-all. That'd emit a stack check fault on sys_init_stack!" +#endif + +/* + * Stack overflow testing. + */ +#ifdef __arm64__ +#define DEFAULT_STACK_COOKIE 0x4752400444303631ull // 'GRD\0D061' +uint64_t __stack_chk_guard __used = DEFAULT_STACK_COOKIE; +#else +#define DEFAULT_STACK_COOKIE 'GRD\0' +uint32_t __stack_chk_guard __used = DEFAULT_STACK_COOKIE; +#endif + +#if WITH_RANDOM +// this needs to be outside of sys_init_stack_cookie to stop -fstack-protector-strong from tripping +static uint8_t stack_chk_guard_zero_byte = 0; +#endif + +// WARNING: This function cannot be called by anything that returns "normally" +// without risking a false stack overflow panic. +void sys_init_stack_cookie(void) +{ +#if WITH_RANDOM + uint8_t *guard = (uint8_t*)&__stack_chk_guard; + + // This is tricky. You can't do anything in this function that would + // cause the compiler to insert its stack validation cookie into + // the stack frame because we're changing the value of the cookie + // that the stack check code checks. + + if (random_get_bytes((u_int8_t *)&__stack_chk_guard, sizeof(__stack_chk_guard)) != 0) { + // In case of failure, put back the static cookie just in case. + __stack_chk_guard = DEFAULT_STACK_COOKIE; + } + + // Grab a byte of entropy and use that value as an index to stuff a + // zero byte into the cookie to block string functions from reading + // past the cookie. + random_get_bytes(&stack_chk_guard_zero_byte, sizeof(stack_chk_guard_zero_byte)); + + guard[stack_chk_guard_zero_byte & (sizeof(__stack_chk_guard) - 1)] = 0; +#endif +} + +void __noreturn __used +__stack_chk_fail(void) +{ + panic("stack corrupted"); +} diff --git a/sys/hash.c b/sys/hash.c new file mode 100644 index 0000000..6fbef86 --- /dev/null +++ b/sys/hash.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_SHA2_384 +void sha384_calculate(const void *buffer, size_t length, void *result, size_t out_len) +{ + RELEASE_ASSERT(out_len >= CCSHA384_OUTPUT_SIZE); + ccdigest(ccsha384_di(), length, buffer, result); +} +#endif + +#if !HOST_TEST + +void hash_calculate(const void *in_ptr, size_t in_len, void *out_ptr, size_t out_len) +{ + RELEASE_ASSERT(out_len >= HASH_OUTPUT_SIZE); +#if WITH_SHA2_384 + sha384_calculate(in_ptr, in_len, out_ptr, out_len); +#else // SHA1 + sha1_calculate(in_ptr, in_len, out_ptr); +#endif +} + + +#if WITH_SHA2_384 && WITH_MENU + +int do_sha384(int argc, struct cmd_arg *args) +{ + u_int8_t hash[CCSHA384_OUTPUT_SIZE]; + u_int32_t cnt; + + if (argc < 3) { + printf("not enough arguments.\n"); + printf("%s
\n", args[0].str); + return -1; + } + + if (!security_allow_memory((void *)args[1].u, args[2].u)) { + printf("Permission Denied\n"); + return -1; + } + + sha384_calculate((void *)args[1].u, args[2].u, hash, sizeof(hash)); + printf("sha384 of 0x%08lx for 0x%08lx bytes: ", args[1].u, args[2].u); + for (cnt = 0; cnt < CCSHA384_OUTPUT_SIZE; cnt++) + printf("%02x%s", hash[cnt], (cnt != CCSHA384_OUTPUT_SIZE-1) ? ":" : "\n"); + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(sha384, do_sha384, "SHA_384 hash of specified memory address range.", NULL); + +#endif // WITH_SHA2_384 && WITH_MENU +#endif // !HOST_TEST */ + diff --git a/sys/init.c b/sys/init.c new file mode 100644 index 0000000..a1e8b7c --- /dev/null +++ b/sys/init.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2006-2011 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* these need to be non-static and initialised for applications that patch them */ +#define HEAP_SIZE_UNPATCHED ((size_t)-1) +void *heap_base = (void *)-1; +size_t heap_size = HEAP_SIZE_UNPATCHED; + +MIB_CONSTANT_PTR(kMIBBuildBanner, kOIDTypeString|kOIDDataIndirect, (void *)&build_banner_string); +MIB_CONSTANT_PTR(kMIBBuildStyle, kOIDTypeString|kOIDDataIndirect, (void *)&build_style_string); +MIB_CONSTANT_PTR(kMIBBuildTag, kOIDTypeString|kOIDDataIndirect, (void *)&build_tag_string); + +/* called from each binary's main() routine to initialize basic system services */ +void sys_init(void) +{ + /* + * Initialise the heap. + * + * If HEAP_END is defined, we assume that we are going to + * configure the heap size using it. + * + * If HEAP_BASE is defined, we respect the definition. Otherwise + * we start the heap at the end of the __DATA segment. + * + * If HEAP_END is not defined, someone may have patched heap_base/ + * heap_end, so we check and create a heap with their values if they + * have. + */ +#ifdef HEAP_END +# ifdef HEAP_BASE + /* we have a defined base for the heap */ + heap_base = (void *)HEAP_BASE; +# else + /* create the heap at the end of the __DATA segment */ + heap_base = __segment_end(__DATA); +# endif + /* compute the heap size*/ + heap_size = HEAP_END - (uintptr_t)heap_base; +#endif + /* if we have computed (or had patched in) a heap size, create the heap */ + if (heap_size != HEAP_SIZE_UNPATCHED) { +#if WITH_RANDOM + bool random_heap_cookie = mib_get_bool(kMIBTargetRandomHeapCookie); + + if (random_heap_cookie) { + uint8_t heap_cookie[HEAP_COOKIE_SIZE]; + + random_get_bytes_noheap(heap_cookie, sizeof(heap_cookie), heap_base, heap_size); + heap_set_cookie(heap_cookie); + } +#endif + + heap_add_chunk(heap_base, heap_size, true); + } + + /* initialize security */ +#if !WITH_NO_SECURITY + security_init(false); +#endif + +#if WITH_ENV + /* populate the environment with some default values */ + sys_setup_default_environment(); +#endif + + /* initialize the tasking system */ + task_init(); + + /* after tasks are initialized, do some more cpu init (if needed) */ + arch_cpu_init_posttasks(); + + /* initialize the debug i/o queue */ + debug_init(); +} + diff --git a/sys/lock.c b/sys/lock.c new file mode 100644 index 0000000..bb7a90c --- /dev/null +++ b/sys/lock.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2006,2009 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include + +#if DEBUG_CRITICAL_SECTIONS +void _enter_critical_section(const char *from) +{ + dprintf(DEBUG_SPEW, "enter_critical_section: %s %p %d\n", from, current_task, current_task->irq_disable_count); +#else +void enter_critical_section(void) +{ +#endif + RELEASE_ASSERT(current_task->irq_disable_count >= 0); + RELEASE_ASSERT(current_task->irq_disable_count < 1000); + current_task->irq_disable_count++; + if (current_task->irq_disable_count == 1) { + arch_disable_ints(); + } +} + +#if DEBUG_CRITICAL_SECTIONS +void _exit_critical_section(const char *from) +{ + dprintf(DEBUG_SPEW, "exit_critical_section: %s %p %d\n", from, current_task, current_task->irq_disable_count); +#else +void exit_critical_section(void) +{ +#endif + RELEASE_ASSERT(current_task->irq_disable_count > 0); + current_task->irq_disable_count--; + if (current_task->irq_disable_count == 0) { + arch_enable_ints(); + } +} + +/* the following are only used in interrupt handler glue */ +void _irq_enter_critical_section(void) +{ + RELEASE_ASSERT(current_task->irq_disable_count >= 0); + RELEASE_ASSERT(current_task->irq_disable_count < 1000); + current_task->irq_disable_count += 100; +} + +void _irq_exit_critical_section(void) +{ + RELEASE_ASSERT(current_task->irq_disable_count >= 100); + current_task->irq_disable_count -= 100; +} + diff --git a/sys/mem.c b/sys/mem.c new file mode 100644 index 0000000..4de24ea --- /dev/null +++ b/sys/mem.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +/* + * Generic memory mapping functions. + */ + +#include +#include + +static struct mem_static_map_entry * +mem_static_find_virtual(uintptr_t addr, ptrdiff_t *offset) +{ + struct mem_static_map_entry *mp; + + for (mp = mem_static_map_entries; mp->size != 0; mp++) { + /* is this an entry in a cached mapping? */ + if ((MAP_NO_ENTRY != mp->cached_base) && + (addr >= mp->cached_base) && + (addr <= (mp->cached_base + mp->size - 1))) { + *offset = addr - mp->cached_base; + return(mp); + } + + /* is this an entry in an uncached mapping? */ + if ((mp->uncached_base != MAP_NO_ENTRY) && + (addr >= mp->uncached_base) && + (addr <= (mp->uncached_base + mp->size - 1))) { + *offset = addr - mp->uncached_base; + return(mp); + } + } + return(NULL); +} + +static struct mem_static_map_entry * +mem_static_find_physical(uintptr_t addr) +{ + struct mem_static_map_entry *mp; + + for (mp = mem_static_map_entries; mp->size != 0; mp++) { + /* is this an entry in a physical mapping? */ + if ((MAP_NO_ENTRY != mp->physical_base) && + (addr >= mp->physical_base) && + (addr <= (mp->physical_base + mp->size - 1))) + return(mp); + } + return(NULL); +} + +void * +mem_static_map_cached(uintptr_t ptr) +{ + struct mem_static_map_entry *mp; + ptrdiff_t offset; + + mp = mem_static_find_virtual(ptr, &offset); + if (NULL != mp) + return((void *)(mp->cached_base + offset)); + return(MAP_FAILED); +} + +void * +mem_static_map_uncached(uintptr_t ptr) +{ + struct mem_static_map_entry *mp; + ptrdiff_t offset; + + mp = mem_static_find_virtual(ptr, &offset); + if (NULL != mp) + return((void *)(mp->uncached_base + offset)); + return(MAP_FAILED); +} + +uintptr_t +mem_static_map_physical(uintptr_t ptr) +{ + struct mem_static_map_entry *mp; + ptrdiff_t offset; + + mp = mem_static_find_virtual(ptr, &offset); + if (NULL != mp) + return(mp->physical_base + offset); + return(MAP_NO_ENTRY); +} diff --git a/sys/menu.c b/sys/menu.c new file mode 100644 index 0000000..ea53f37 --- /dev/null +++ b/sys/menu.c @@ -0,0 +1,502 @@ +/* + * Copyright (C) 2007-2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_MENU +#if !WITH_SIMPLE_MENU + +// 0x1b 0x5b 0x41 uparrow +// 0x1b 0x5b 0x42 downarrow +// 0x1b 0x5b 0x43 rightarrow +// 0x1b 0x5b 0x44 leftarrow + +#define HISTORY_SIZE 16 +static char (*history)[256]; +static uint32_t curr_history_pos = 0; + +#define kTokenBufSize (1024) +#define kMaxMenuArgs 64 + +utime_t gMenuLastActivityTime; +static char *token_buf; +static char *console_prompt; + +struct task_event gMenuTaskReadyEvent = EVENT_STATIC_INIT(gMenuTaskReadyEvent, false, 0); + +static char *get_line(const char *prompt, char *buf, int buf_size) +{ + int i; + int escape; + uint32_t history_pos = curr_history_pos; + uint32_t saved_history_pos = curr_history_pos; + +do_prompt: + puts(prompt); + + history[curr_history_pos][0] = 0; + + i = 0; + escape = 0; + for (;;) { + char c = getchar(); + +// printf("c = 0x%x (%c)\n", c, c); + + /* Update activity time on any new input. */ + gMenuLastActivityTime = system_time(); + + switch (c) { + case '\n': + escape = 0; + putchar('\n'); + if (i != 0) { + buf[i] = 0; + + /* save the history, if it's different from the last command */ + if (strcmp(buf, history[(curr_history_pos - 1) % HISTORY_SIZE]) != 0) { + strlcpy(history[curr_history_pos], buf, sizeof(history[curr_history_pos])); + curr_history_pos = (curr_history_pos + 1) % HISTORY_SIZE; + } + return buf; + } else { + goto do_prompt; + } + break; + case 0x8: // backspace + case 0x7f: // del + escape = 0; + if (i > 0) { + i--; + putchar(0x8); + putchar(0x20); + putchar(0x8); + } + break; + case 0x1b: + escape = 1; + break; + case 0x5b: + if (escape > 0) + escape = 2; + break; + case 0x41: case 0x42: + if (escape < 2) { + goto regchar; + } else { + // up/down arrow + char *new_history; + + if (c == 0x41) { + int temp = history_pos; + history_pos = (history_pos - 1) % HISTORY_SIZE; + if (history_pos == saved_history_pos) { +// printf("%d %d\n", history_pos, saved_history_pos); + // we've wrapped around + history_pos = temp; + break; + } + if (strlen(history[history_pos]) == 0) { +// printf("%p %d, len 0\n", history[history_pos], history_pos); + // we've walked before the start of history + history_pos = temp; + break; + } + } else { + if (history_pos == saved_history_pos) + break; // can't go forward past top of the history + history_pos = (history_pos + 1) % HISTORY_SIZE; + } + new_history = history[history_pos]; + + /* wipe out the line */ + while(i > 0) { + putchar(0x8); + putchar(' '); + putchar(0x8); + i--; + } + + /* output the new line */ + for (i=0; new_history[i] != 0; i++) { + buf[i] = new_history[i]; + putchar(new_history[i]); + } + } + escape = 0; + break; + case 0x43: case 0x44: + if (escape < 2) { + goto regchar; + } else { + // left & right arrow + escape = 0; + } + break; + default: +regchar: + escape = 0; + if (i < (buf_size - 1)) { + buf[i++] = c; + putchar(c); + } + } + } +} + +/* + * chop a string into multiple tokens, each pointed to by the tokens array. + * if an unescaped ';' is hit, stop tokenizing and return the remainder of + * the line in *line_remainder. If no ';' is hit, return null in *line_remainder. + */ +static int tokenize(const char *buf, char **tokens, int token_count, const char **line_remainder) +{ + bool done; + bool done_after; + int inpos = 0; + int outpos = 0; + int outpos_token_start = 0; + int token = 0; + char last_char = 0; + enum { + INITIAL, + CONSUME_WHITESPACE, + TOKEN_START, + TOKEN, + QUOTED_TOKEN, + FINISH_TOKEN, + +#if WITH_ENV + ENV_TOKEN, + FINISH_ENV_TOKEN, +#endif + } state = INITIAL; + + *line_remainder = NULL; + + done = done_after = false; + while (!done) { + /* end of input buffer, finish off whatever token we're in the middle of and exit */ + if ((buf[inpos] == 0) || (outpos >= (kTokenBufSize - 1))) { + done = true; + if (state == TOKEN || state == QUOTED_TOKEN || state == FINISH_TOKEN) + state = FINISH_TOKEN; +#if WITH_ENV + else if (state == ENV_TOKEN) + state = FINISH_ENV_TOKEN; +#endif + else + break; + } + if (done_after) + done = true; + +// printf("tok: in %d (%c) out %d tok %d state %d\n", +// inpos, buf[inpos], outpos, token, state); + switch (state) { + case INITIAL: + case CONSUME_WHITESPACE: + /* eat whitespace until we see the start of a token */ + if (isspace(buf[inpos])) { + last_char = buf[inpos]; + inpos++; + continue; + } + + state = TOKEN_START; + break; + case TOKEN_START: + /* start of a token, examine the first character to see if we need to do anything special */ + outpos_token_start = outpos; + if (buf[inpos] == '#') { + /* comment, ignore the rest of the line */ + last_char = buf[inpos]; + done = true; + break; +#if WITH_ENV + } else if (buf[inpos] == '$') { + /* environment variable */ + last_char = buf[inpos]; + inpos++; + state = ENV_TOKEN; + tokens[token] = &token_buf[outpos]; +#endif + } else if (buf[inpos] == ';') { + /* if we hit a unescaped ';', it's the end of the line */ + *line_remainder = &buf[inpos+1]; + done = true; + break; + } else if (buf[inpos] == '"') { + /* quoted token */ + last_char = buf[inpos]; + inpos++; + state = QUOTED_TOKEN; + tokens[token] = &token_buf[outpos]; + } else { + state = TOKEN; + tokens[token] = &token_buf[outpos]; + } + break; + case TOKEN: + /* consume characters until we hit whitespace */ + if (isspace(buf[inpos])) { + /* whitespace, null terminate current token and switch to whitespace consume state */ + last_char = buf[inpos]; + state = FINISH_TOKEN; + break; + } else if (buf[inpos] == ';') { + /* if we hit a unescaped ';', it's the end of the line */ + if (last_char != '\\') { + *line_remainder = &buf[inpos+1]; + state = FINISH_TOKEN; + done_after = true; + break; + } + } + + last_char = buf[inpos]; + if (buf[inpos] != '\\') + token_buf[outpos++] = buf[inpos]; + inpos++; + break; + case QUOTED_TOKEN: + /* consume characters until we hit terminating quote */ + if (buf[inpos] == '"') { + /* terminating quote, null terminate current token and switch to whitespace consume state */ + inpos++; // consume the quote + state = FINISH_TOKEN; + break; + } + + last_char = buf[inpos]; + token_buf[outpos++] = buf[inpos++]; + break; + case FINISH_TOKEN: + /* finish whatever token we're dealing with */ + token_buf[outpos++] = 0; + if (++token < token_count) + state = CONSUME_WHITESPACE; + else { + *line_remainder = &buf[inpos]; + done = true; + } + break; +#if WITH_ENV + case ENV_TOKEN: + /* consume characters until we hit whitespace */ + if (isspace(buf[inpos])) { + /* whitespace, we've now got the environment variable we want to read */ + last_char = buf[inpos]; + state = FINISH_ENV_TOKEN; + break; + } + + last_char = buf[inpos]; + token_buf[outpos++] = buf[inpos++]; + break; + case FINISH_ENV_TOKEN: { + /* the current token now holds the environment variable we want to read */ + const char *env; + + token_buf[outpos++] = 0; + + /* read in the environment variable */ + env = env_get(tokens[token]); + if (!env) { + printf("\ncould not read environment var '%s'\n", tokens[token]); + return -1; + } + + /* copy the value of the environment variable on top of the current token */ + strlcpy(&token_buf[outpos_token_start], env, kTokenBufSize - outpos_token_start); + outpos = outpos_token_start + strlen(token_buf + outpos_token_start) + 1; + + if (++token < token_count) + state = CONSUME_WHITESPACE; + else { + *line_remainder = &buf[inpos]; + done = true; + } + break; + } +#endif + default: + panic("tokenize: got into an invalid state\n"); + } + } + + return token; +} + +bool process_command_line(char *line, int* ret_val) +{ + char *tokens[kMaxMenuArgs]; + struct cmd_arg args[kMaxMenuArgs]; + int token_count; + int ret = 0; + const struct cmd_menu_item *menu_entry = NULL; + void **menu_cursor; + int argnum; + + /* don't allow ourselves to be called before the menu task has started */ + if (NULL == token_buf) + return(false); + + /* Update activity; we might have come from outside the get_line() loop */ + gMenuLastActivityTime = system_time(); + + while(line) { + memset(tokens, 0, sizeof(tokens)); + memset(args, 0, sizeof(args)); + token_count = tokenize(line, tokens, sizeof(tokens)/sizeof(char *), (const char **)&line); + if (token_count <= 0) + continue; + +// printf("buf %p, line %p\n", buf, line); +// for(i=0; i < token_count; i++) +// printf("\t%d: '%s'\n", i, tokens[i]); + + /* if the command starts with '?', only execute it if the last command returned a positive error */ + if (tokens[0][0] == '?') { + tokens[0]++; + if (ret < 0) + continue; + } + + menu_entry = NULL; + LINKER_SET_FOREACH(menu_cursor, menu) { + menu_entry = (const struct cmd_menu_item *)*menu_cursor; + if (!strcmp(menu_entry->cmd, tokens[0])) { + + /* parse the arglist */ + for (argnum = 0; argnum < kMaxMenuArgs; argnum++) { + /* are we done? */ + if (argnum >= token_count) + break; + + args[argnum].n = strtol(tokens[argnum], NULL, 0); + args[argnum].u = strtoul(tokens[argnum], NULL, 0); + args[argnum].h = strtol(tokens[argnum], NULL, 16); + if (!strcmp(tokens[argnum], "true")) + args[argnum].b = true; + else if (!strcmp(tokens[argnum], "false")) + args[argnum].b = false; + else + args[argnum].b = args[argnum].n ? true : false; + args[argnum].str = tokens[argnum]; + } + + /* call the routine */ + ret = menu_entry->func(argnum, args); + if (ret_val) + *ret_val = ret; +#if WITH_ENV + /* stick the result in an environment variable */ + env_set_uint("?", ret, 0); +#endif + break; + } else { + menu_entry = NULL; + } + } + } + + return (menu_entry == NULL); +} + +int menu_task(void *arg) +{ + char *buf; + + /* allocate the history buffer */ + history = calloc(1, HISTORY_SIZE * sizeof(*history)); + + /* allocate the line buffer */ + buf = malloc(512); + + /* allocate the token buffer */ + token_buf = malloc(kTokenBufSize); + + /* signal others waiting for us */ + event_signal(&gMenuTaskReadyEvent); + + menu_prompt(NULL); + + for (;;) { + /* prompt */ + puts("\x1b[m"); + get_line(console_prompt, buf, 512); + + if (process_command_line(buf, NULL)) { + printf("\x1b[1m?SYNTAX ERROR\n"); + } + } + + return 0; +} + +char *menu_prompt(char *new_prompt) +{ + char *ret; + + ret = console_prompt; + if (NULL != new_prompt) { + console_prompt = new_prompt; + } else { + console_prompt = "] "; + } + return(ret); +} + +static int do_help(int argc, struct cmd_arg *args) +{ + const struct cmd_menu_item *menu_entry; + void **menu_cursor; + + printf("command list:\n"); + LINKER_SET_FOREACH(menu_cursor, menu) { + menu_entry = (const struct cmd_menu_item *)*menu_cursor; + if (menu_entry->help) + printf(" %-16.16s %s\n", menu_entry->cmd, menu_entry->help); + } + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(help, do_help, NULL, NULL); + +#if 0 +static int do_argtest(int argc, struct cmd_arg *args) +{ + int i; + + printf("argtest, %d args:\n", argc); + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include + +#define RELEASE_SECURITY_MODE (kSecurityModeGIDKeyAccess | kSecurityModeUIDKeyAccess | kSecurityModeProdCertAccess | kSecurityStatusSystemTrusted) +#define SECRET_SECURITY_MODE (RELEASE_SECURITY_MODE | kSecurityModeKDPEnabled) + +// XXX Remove this once image4 transition for older platforms/targets is complete. +#if !WITH_IMAGE4 +#define DEVELOPMENT_SECURITY_MODE (RELEASE_SECURITY_MODE | kSecurityModeExUntrust) +#else +#define DEVELOPMENT_SECURITY_MODE (RELEASE_SECURITY_MODE) +#endif +#define DEBUG_SECURITY_MODE (DEVELOPMENT_SECURITY_MODE | kSecurityModeKDPEnabled | kSecurityModeDebugCmd | kSecurityModeMemAccess | kSecurityModeHWAccess) + +#if RELEASE_BUILD +#define DEFAULT_SECURITY_MODE RELEASE_SECURITY_MODE +#endif +#if SECRET_BUILD +#define DEFAULT_SECURITY_MODE SECRET_SECURITY_MODE +#endif +#if DEVELOPMENT_BUILD +#define DEFAULT_SECURITY_MODE DEVELOPMENT_SECURITY_MODE +#endif +#if DEBUG_BUILD +#define DEFAULT_SECURITY_MODE DEBUG_SECURITY_MODE +#endif + +#ifndef DEFAULT_SECURITY_MODE +#error Security: Unknown build style +#endif + +#define CLEAR_MEM_CHUNK_SIZE (256 * 1024 * 1024) + +static security_mode_t security_mode; + +static addr_t insecure_memory_start; +static addr_t insecure_memory_end; + +#if !DISABLE_CLEAR_MEMORY +static bool secure_memory_cleared; +#endif + +#if WITH_IMAGE4 +static u_int8_t security_boot_manifest_hash[HASH_OUTPUT_SIZE]; +static bool security_environment_consolidated; +#endif // WITH_IMAGE4 + +static void security_clear_mem_in_chunks(char *dst, size_t count); + +int security_init(bool clear_memory) +{ + security_mode = DEFAULT_SECURITY_MODE; + + if (platform_get_secure_mode()) { + security_mode |= kSecurityStatusSecureBoot; + } else { +#if APPLICATION_SECUREROM + // SecureROM allows untrusted execution if secure_mode is false + security_mode |= kSecurityModeExUntrust; +#endif + } + + if (!platform_get_current_production_mode()) { + security_mode |= kSecurityModeDevCertAccess; + security_mode |= kSecurityModeKDPEnabled; + } + + if (platform_get_lock_fuses_required()) { + security_mode |= kSecurityOptionLockFuses; + } + + insecure_memory_start = -1; + insecure_memory_end = 0; + +#if !DISABLE_CLEAR_MEMORY + if (clear_memory) { + /* Break up the memory region into chunks to keep watchdog alive in between the clearings */ + security_clear_mem_in_chunks((char *)INSECURE_MEMORY_BASE, INSECURE_MEMORY_SIZE); + +#ifdef SECURE_MEMORY_SIZE + if ((SECURE_MEMORY_SIZE != 0) && !secure_memory_cleared) { + /* Break up the memory region into chunks to keep watchdog alive in between the clearings */ + security_clear_mem_in_chunks((char *)SECURE_MEMORY_BASE, SECURE_MEMORY_SIZE); + } +#endif + + secure_memory_cleared = true; + } +#endif + + security_protect_memory((void *)INSECURE_MEMORY_BASE, INSECURE_MEMORY_SIZE, false); + +#if WITH_RAMDISK + ramdisk_init(); +#endif + +#if WITH_DEVICETREE + dt_init(); +#endif + + return 0; +} + +bool security_allow_modes(security_mode_t modes) +{ + bool result = (modes & security_mode) == modes; + + if (result && ((modes & kSecurityModeExUntrust) != 0)) + security_set_untrusted(); + + return result; +} + +bool security_validate_image(security_image_t image_validity) +{ + // Check if untrusted is allowed. + if ((image_validity == kSecurityImageUntrusted) && !security_allow_modes(kSecurityModeExUntrust)) { + image_validity = kSecurityImageInvalid; + } + + return image_validity != kSecurityImageInvalid; +} + +bool security_allow_memory(const void *address, size_t length) +{ + addr_t addr = (addr_t)address, last = addr + length; + bool allow = false; + + if (security_allow_modes(kSecurityModeMemAccess)) + return true; + + // Disallow wrap-around + if (last <= addr) + return false; + + if ((insecure_memory_start <= addr) && (last <= insecure_memory_end)) + allow = true; + + return allow; +} + +void security_protect_memory(const void *address, size_t length, bool protect) +{ + addr_t addr = (addr_t)address, last = addr + length; + + if (security_allow_modes(kSecurityModeMemAccess)) + return; + + if (protect) { + insecure_memory_start = -1; + insecure_memory_end = 0; + } else { + if (addr < insecure_memory_start) + insecure_memory_start = addr; + if (insecure_memory_end < last) + insecure_memory_end = last; + } +} + +void security_enable_kdp(void) +{ + if ((security_mode & kSecurityModeKDPEnabled) != 0) + return; + + security_allow_modes(kSecurityModeExUntrust); +} + +void security_set_untrusted(void) +{ + security_mode &= ~(kSecurityModeGIDKeyAccess | kSecurityModeUIDKeyAccess | kSecurityStatusSystemTrusted); + security_mode |= kSecurityModeKDPEnabled; +} + +void security_set_production_override(bool override) +{ + security_mode &= ~kSecurityOptionClearProduction; + if (override)security_mode |= kSecurityOptionClearProduction; +} + +bool security_get_production_override(void) +{ + return (security_mode & kSecurityOptionClearProduction) != 0; +} + +#if WITH_IMAGE4 + +bool security_get_effective_production_status(bool with_demotion) +{ + bool device_production_status = platform_get_current_production_mode(); + + return (device_production_status ? (device_production_status ^ with_demotion) : false); +} + +void security_set_boot_manifest_hash(u_int8_t *boot_manifest_hash) +{ + security_mode &= ~kSecurityOptionBootManifestHashValid; + + if (boot_manifest_hash == NULL) { + security_mode &= ~kSecurityOptionBootManifestHashValid; + } else { + security_mode |= kSecurityOptionBootManifestHashValid; + memcpy((void *)security_boot_manifest_hash, (const void *)boot_manifest_hash, sizeof(security_boot_manifest_hash)); + } +} + +bool security_get_boot_manifest_hash(u_int8_t *boot_manifest_hash, u_int32_t hash_length) +{ + if (security_mode & kSecurityOptionBootManifestHashValid) { + RELEASE_ASSERT(boot_manifest_hash != NULL); + RELEASE_ASSERT(hash_length == sizeof(security_boot_manifest_hash)); + memcpy((void *)boot_manifest_hash, (const void *)security_boot_manifest_hash, hash_length); + return true; + } else { + return false; + } +} + +void security_set_mix_n_match_prevention_status(bool mix_n_match_enforced) +{ + security_mode &= ~kSecurityOptionMixNMatchPrevented; + if (mix_n_match_enforced) + security_mode |= kSecurityOptionMixNMatchPrevented; +} + +bool security_get_mix_n_match_prevention_status(void) +{ + return (security_mode & kSecurityOptionMixNMatchPrevented); +} + +void security_set_lock_fuses(void) +{ + security_mode |= kSecurityOptionLockFuses; +} + +bool security_get_lock_fuses(void) +{ + return (security_mode & kSecurityOptionLockFuses); +} + +bool security_restore_environment(void) +{ + uint8_t boot_manifest_hash[HASH_OUTPUT_SIZE]; + + if (security_environment_consolidated) + return false; + + security_set_mix_n_match_prevention_status(platform_get_mix_n_match_prevention_status()); + + if (platform_get_boot_manifest_hash((u_int8_t *)boot_manifest_hash) == 0) + security_set_boot_manifest_hash((u_int8_t *)boot_manifest_hash); + else + security_set_boot_manifest_hash(NULL); + + if (security_get_production_override()) + security_set_production_override(false); + + if ((security_mode & (kSecurityModeGIDKeyAccess | kSecurityModeUIDKeyAccess | kSecurityStatusSystemTrusted)) == 0) + security_mode |= (kSecurityModeGIDKeyAccess | kSecurityModeUIDKeyAccess | kSecurityStatusSystemTrusted); + + return true; +} + +bool security_consolidate_environment(void) +{ + /* demote production status if requested */ + if (security_get_production_override()) + platform_demote_production(); + + /* disable all keys not requested */ + if (!security_allow_modes(kSecurityModeGIDKeyAccess)) + platform_disable_keys(~0, 0); + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + platform_disable_keys(0, ~0); + + /* update next stage boot-manifest-hash, and related flags */ + if (security_mode & kSecurityOptionBootManifestHashValid) + platform_set_boot_manifest_hash((u_int8_t *)security_boot_manifest_hash); + else + platform_set_boot_manifest_hash(NULL); + + platform_set_mix_n_match_prevention_status(((security_mode & kSecurityOptionMixNMatchPrevented) == kSecurityOptionMixNMatchPrevented)); + + /* record environment was consolidated atleast once */ + security_environment_consolidated = true; + + return true; +} + +#else // WITH_IMAGE4 + +bool security_consolidate_environment(void) +{ + return false; +} + +#endif // WITH_IMAGE4 + +static const char gSleepToken[] = "iBootSleepValid"; + +void security_create_sleep_token(addr_t address) +{ + uint8_t key_buffer[16]; + + memcpy((void *)address, gSleepToken, sizeof(gSleepToken)); + +#if WITH_AES + if (!security_allow_modes(kSecurityModeUIDKeyAccess)) + return; + + memcpy(key_buffer, gSleepToken, sizeof(gSleepToken)); + + /* note that we ignore any errors from AES here */ + aes_cbc_encrypt(key_buffer, key_buffer, sizeof(key_buffer), AES_KEY_TYPE_UID0, NULL, NULL); + aes_cbc_encrypt((u_int8_t *)address, (u_int8_t *)address, sizeof(gSleepToken), AES_KEY_TYPE_USER, key_buffer, NULL); +#endif + memset(key_buffer, 0, sizeof(key_buffer)); +} + +bool security_validate_sleep_token(addr_t address) +{ + uint8_t key_buffer[16]; + uint8_t token_buffer[16]; + bool result = false; + +#if WITH_AES + if (security_allow_modes(kSecurityModeUIDKeyAccess)) { + memcpy(token_buffer, gSleepToken, sizeof(token_buffer)); + + memcpy(key_buffer, gSleepToken, sizeof(key_buffer)); + + /* note that we ignore any errors from AES here */ + aes_cbc_encrypt(key_buffer, key_buffer, sizeof(key_buffer), AES_KEY_TYPE_UID0, NULL, NULL); + aes_cbc_encrypt(token_buffer, token_buffer, sizeof(token_buffer), AES_KEY_TYPE_USER, key_buffer, NULL); + + if (!memcmp_secure((void *)address, token_buffer, sizeof(token_buffer))) { + result = true; + goto out; + } + } +#endif + + if (!memcmp_secure((void *)address, gSleepToken, sizeof(gSleepToken)) && security_allow_modes(kSecurityModeExUntrust)) { + result = true; + goto out; + } + +out: + memset(key_buffer, 0, sizeof(key_buffer)); + memset(token_buffer, 0, sizeof(token_buffer)); + + return result; +} + +/* + * This function avoids clearing memory in one bzero call, since that might + * take too long such that watchdog fires (if enabled) and causes a full system reset + */ +static void security_clear_mem_in_chunks(char *dst, size_t count) +{ +#if APPLICATION_SECUREROM && WITH_DMA_CLEAR + extern void platform_clear_mem_with_dma(char *dst, size_t count); + platform_clear_mem_with_dma(dst, count); +#else // !WITH_DMA_CLEAR || !APPLICATION_SECUREROM + size_t chunk_len; + do { + /* reset watchdog timer in case it's enabled */ + platform_watchdog_tickle(); + + /* Only clear CLEAR_MEM_CHUNK_SIZE bytes at a time */ + chunk_len = (count > CLEAR_MEM_CHUNK_SIZE) ? CLEAR_MEM_CHUNK_SIZE : count; + bzero((void *)dst, chunk_len); + dst += chunk_len; + count -= chunk_len; + }while (count > 0); +#endif // WITH_DMA_CLEAR && APPLICATION_SECUREROM +} + +#if WITH_SIDP +#if APPLICATION_SECUREROM + +void security_sidp_seal_rom_manifest(void) +{ + // Is the boot manifest hash valid? + if (security_mode & kSecurityOptionBootManifestHashValid) { + // Copy the manifest hash to a word aligned buffer. + uint32_t manifest_buffer[HASH_OUTPUT_SIZE / sizeof(uint32_t)]; + memcpy(manifest_buffer, security_boot_manifest_hash, HASH_OUTPUT_SIZE); + + // Copy the manifest hash to ROM seal registers. + platform_sidp_set_rom_manifest(manifest_buffer, HASH_OUTPUT_SIZE); + } else { + // Clear the ROM seal registers. + platform_sidp_set_rom_manifest(NULL, 0); + } + + // Lock the ROM seal. + platform_sidp_lock_rom_manifest(); +} + +#else // !APPLICATION_SECUREROM + +void security_sidp_seal_boot_manifest(bool require_unlocked) +{ + // The caller must have consolidated the security environment before + // calling this function. + RELEASE_ASSERT(security_environment_consolidated); + + // Did a prior boot stage lock the manifest? + if (platform_sidp_boot_manifest_locked()) { + if (require_unlocked) { + panic("Boot manifest already locked"); + } + + // Yep, nothing to do. + dprintf(DEBUG_INFO, "SiDP boot manifest already locked\n"); + return; + } + + // Is the boot manifest hash valid? + if (security_mode & kSecurityOptionBootManifestHashValid) { + // Copy the manifest hash to a word aligned buffer. + uint32_t manifest_buffer[HASH_OUTPUT_SIZE / sizeof(uint32_t)]; + memcpy(manifest_buffer, security_boot_manifest_hash, HASH_OUTPUT_SIZE); + + // Copy the manifest hash to the bootloader seal registers. + platform_sidp_set_boot_manifest(manifest_buffer, HASH_OUTPUT_SIZE); + } else { + // Clear the bootloader seal registers. + platform_sidp_set_boot_manifest(NULL, 0); + } + + // Mix-n-match allowed? + if (!security_get_mix_n_match_prevention_status()) { + platform_sidp_set_mix_n_match(); + } + + // Lock the boot manifest. + platform_sidp_lock_boot_manifest(); +} + +#endif // APPLICATION_SECUREROM +#endif // WITH_SIDP + diff --git a/sys/simple_menu.c b/sys/simple_menu.c new file mode 100644 index 0000000..a961cfc --- /dev/null +++ b/sys/simple_menu.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Computer, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_MENU +#if WITH_SIMPLE_MENU + +#define kTokenBufSize 128 +#define kMaxTokens 8 + +utime_t gMenuLastActivityTime; +static char *token_buf; + +struct task_event gMenuTaskReadyEvent = EVENT_STATIC_INIT(gMenuTaskReadyEvent, false, 0); + +/* + * Parse tokens from (buf). + */ +static int +tokenize(const char *buf, char **tokens, int token_count) +{ + const char *in; + char *out, *out_limit; + int token; + enum { + WHITESPACE, + TOKEN, + DONE + } state; + + in = buf; + out = token_buf; + out_limit = out + kTokenBufSize - 1; + token = 0; + state = WHITESPACE; + + for (;;) { + /* state machine */ + switch(state) { + case WHITESPACE: + /* if we hit the end of the input, bail now */ + if ('\0' == *in) { + state = DONE; + break; + } + + /* found a token starting? */ + if (!isspace(*in)) { + tokens[token] = out; + state = TOKEN; + break; + } + /* discard and move on */ + in++; + break; + + case TOKEN: + /* output cursor has reached or exceeded the last safe character */ + if (out >= out_limit) { + /* terminate at the last safe character */ + *out_limit = '\0'; + /* update the token count */ + token++; + /* and we are done */ + state = DONE; + break; + } + + /* input cursor has reached the end of the input or whitespace */ + if (('\0' == *in) || isspace(*in)) { + *out++ = '\0'; + token++; + + /* if the input is exhausted or we have run out of token space */ + if (('\0' == *in) || (token >= token_count)) { + state = DONE; + } else { + /* return to discarding whitespace */ + state = WHITESPACE; + } + break; + } + + /* copy another character */ + *out++ = *in++; + break; + + case DONE: + return(token); + } + } +} + + +bool +process_command_line(char *line, int *ret_val) +{ + char *tokens[kMaxTokens]; + struct cmd_arg args[kMaxTokens]; + const struct cmd_menu_item *menu_entry; + void **menu_cursor; + int argnum; + int token_count; + int ret; + + /* don't allow ourselves to be called before the menu task has started */ + if (NULL == token_buf) + return(true); + + /* Update activity; we might have come from outside the get_line() loop */ + gMenuLastActivityTime = system_time(); + + /* tokenize, will never return > kMaxTokens */ + token_count = tokenize(line, tokens, kMaxTokens); + + if (token_count > 0) { + LINKER_SET_FOREACH(menu_cursor, menu) { + menu_entry = (const struct cmd_menu_item *)*menu_cursor; + if (!strcmp(menu_entry->cmd, tokens[0])) { + + /* parse the arglist */ + for (argnum = 0; argnum < token_count; argnum++) { + /* are we done? */ + if (argnum >= token_count) + break; + + args[argnum].n = strtol(tokens[argnum], NULL, 0); + args[argnum].u = strtoul(tokens[argnum], NULL, 0); + args[argnum].h = strtol(tokens[argnum], NULL, 16); + if (!strcmp(tokens[argnum], "true")) + args[argnum].b = true; + else if (!strcmp(tokens[argnum], "false")) + args[argnum].b = false; + else + args[argnum].b = args[argnum].n ? true : false; + args[argnum].str = tokens[argnum]; + } + + /* call the routine */ + ret = menu_entry->func(argnum, args); + if (ret_val) + *ret_val = ret; +#if WITH_ENV + /* stick the result in an environment variable */ + env_set_uint("?", ret, 0); +#endif + return(false); + } + } + } + return(true); +} + + +int menu_task(void *arg) +{ + + /* allocate the token buffer */ + token_buf = malloc(kTokenBufSize); + + /* signal others waiting for us */ + event_signal(&gMenuTaskReadyEvent); + + /* spin throwing away console input */ + for (;;) { + + /* get an input character */ + (void)getchar(); + + /* Update activity time on any new input. */ + gMenuLastActivityTime = system_time(); + } + + return 0; +} + +#endif /* WITH_SIMPLE_MENU */ +#endif /* WITH_MENU */ diff --git a/sys/task.c b/sys/task.c new file mode 100644 index 0000000..5b0ff22 --- /dev/null +++ b/sys/task.c @@ -0,0 +1,774 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !WITH_HW_TIMER +# error Cannot build task subsystem without timer support +#endif + +#define DEFAULT_TASK_STACK_MAGIC 'stak' + +/* list of all tasks */ +static struct list_node task_list = LIST_INITIAL_VALUE(task_list); +static int task_count; + +static int max_task_id; + +/* global run queue */ +static struct list_node run_q = LIST_INITIAL_VALUE(run_q); +static volatile int run_q_len; + +/* initial bootstrapping task, partially constructed */ +static struct task bootstrap_task = { + .magic = TASK_MAGIC, + .state = TASK_RUNNING, + .irq_disable_count = 1, + .routine = NULL, + .arg = NULL, + .stack_base = NULL, + .stack_len = 0, + + .name = "bootstrap", + .magic2 = TASK_MAGIC2, + .task_id = 0, +}; + +/* idle task */ +static int idle_task_routine(void *); + +#ifndef IDLE_TASK_SIZE + #define IDLE_TASK_SIZE TASK_STACK_MIN +#endif + +static uint8_t idle_task_stack[IDLE_TASK_SIZE] __attribute__ ((aligned(16))); +static struct task idle_task; +static uint64_t idle_ticks = 0ULL; +static uint64_t deep_idle_ticks = 0ULL; +static uint64_t boot_time_ticks; +static uint64_t shallow_idle_cnt = 0ULL; +static uint64_t deep_idle_cnt = 0ULL; +static uint64_t last_yield; +static uint64_t last_switch; +static uint32_t task_stack_magic = DEFAULT_TASK_STACK_MAGIC; + +MIB_VARIABLE(kMIBSystemBootTime, kOIDTypeUInt64, boot_time_ticks); +MIB_VARIABLE(kMIBSystemIdleTime, kOIDTypeUInt64, idle_ticks); + +static void +uptime_handler(u_int32_t oid __unused, void *arg __unused, void *data) +{ + u_int64_t *resptr = (u_int64_t *)data; + u_int64_t now; + + now = timer_get_ticks(); + *resptr = now - boot_time_ticks; +} + +MIB_FUNCTION(kMIBSystemUptime, kOIDTypeUInt64, uptime_handler, NULL); + +/* currently running task */ +struct task *current_task = &bootstrap_task; + +#if defined(__arm__) +static uint32_t nullptr_value; +#endif +static bool deep_idle; + +#ifndef DEEP_IDLE_THRESHOLD_US +#define DEEP_IDLE_THRESHOLD_US 1000 +#endif + +static volatile uint32_t deep_idle_threshold_us = 0; // + +static struct task *task_create_etc(struct task *t, const char *name, task_routine routine, void *arg, void *stack, size_t stack_len); +static void insert_run_q_head(struct task *t); +static void insert_run_q_tail(struct task *t); + +struct callout deep_idle_callout; +static void deep_idle_timeout(struct callout *co, void *arg) +{ + deep_idle = true; +} + +static int idle_task_routine(void *arg) +{ + u_int64_t idle_enter, idle_leave; + u_int64_t *ticks_accumulator; + + for(;;) { + task_yield(); + idle_enter = timer_get_ticks(); + + enter_critical_section(); + ticks_accumulator = & idle_ticks; + if (likely(run_q_len == 0)) { + if (deep_idle) { + ticks_accumulator = & deep_idle_ticks; + deep_idle_cnt++; + platform_deep_idle(); + deep_idle = false; + } else { + /* Setup the "deep idle" callout and halt ("shallow idle") */ + if (deep_idle_threshold_us) + callout_enqueue(&deep_idle_callout, deep_idle_threshold_us, deep_idle_timeout, NULL); + ticks_accumulator = & idle_ticks; + shallow_idle_cnt++; + platform_halt(); + } + } + exit_critical_section(); + + /* We should never be here with interrupts disabled */ + RELEASE_ASSERT(0 == current_task->irq_disable_count); + + idle_leave = timer_get_ticks(); + *ticks_accumulator += idle_leave - idle_enter; + } + + return 0; +} + +static void task_init_stack_magic_cookie(void) +{ +#if WITH_RANDOM + uint8_t *guard = (uint8_t*)&task_stack_magic; + + if (random_get_bytes((u_int8_t *)&task_stack_magic, sizeof(task_stack_magic)) != 0) { + // In case of failure, put back the static cookie just in case. + task_stack_magic = DEFAULT_TASK_STACK_MAGIC; + } + + guard[task_stack_magic & (sizeof(task_stack_magic) - 1)] = 0; +#endif +} + + +void task_init(void) +{ + + dprintf(DEBUG_INFO, "initializing task system\n"); + + boot_time_ticks = timer_get_ticks(); + +#if !WITH_NO_RANDOM_STACK_COOKIE + /* initialize the random cookie used for overflow detection */ + task_init_stack_magic_cookie(); +#endif + + /* go back and fill in some more details of the bootstrap task */ + wait_queue_init(&bootstrap_task.return_waiters); + + /* construct an idle task */ + task_create_etc(&idle_task, "idle task", &idle_task_routine, NULL, idle_task_stack, sizeof(idle_task_stack)); + idle_task.state = TASK_READY; /* it never gets started properly */ + + task_count = 2; /* bootstrap task, idle task */ + +#if defined(__arm__) && !defined(__clang_analyzer__) + nullptr_value = *(volatile uint32_t *)NULL; +#endif +} + +struct task *task_get_current_task(void) +{ + return(current_task); +} + +static struct task *task_create_etc(struct task *t, const char *name, task_routine routine, void *arg, void *stack, size_t stack_len) +{ + uint32_t i; + + /* clear the storage for the task */ + memset(t, 0, sizeof(struct task)); + + /* set up the new task */ + t->magic = TASK_MAGIC; + t->magic2 = TASK_MAGIC2; + t->stack_base = stack; + t->stack_len = stack_len; + strlcpy(t->name, name, sizeof(t->name)); + t->routine = routine; + t->arg = arg; + + enter_critical_section(); + t->task_id = ++max_task_id; + exit_critical_section(); + + list_clear_node(&t->queue_node); + wait_queue_init(&t->return_waiters); + + t->state = TASK_INITIAL; + t->irq_disable_count = 1; /* start off as if we were inside a critical section */ + + /* fill the stack with 'magic' */ + for (i = 0; i < (stack_len / sizeof(uint32_t)); i++) + *((uint32_t *)t->stack_base + i) = task_stack_magic; + + arch_task_create(t); + + /* add ourselves to the global task list */ + list_add_head(&task_list, &t->task_list_node); + + task_count++; + + return t; +} + +struct task *task_create(const char *name, task_routine routine, void *arg, size_t stack_len) +{ + struct task *t; + void *stack; + + /* stacks must be at least TASK_STACK_MIN bytes */ + if (stack_len < TASK_STACK_MIN) + stack_len = TASK_STACK_MIN; + + /* it will panic if not to be able to allocate stack */ + t = malloc(sizeof(struct task)); + /* assumption: malloc always returns cache-line size aligned buffer */ + stack = malloc(stack_len); + + return task_create_etc(t, name, routine, arg, stack, stack_len); +} + +void task_destroy(struct task *t) +{ + list_delete(&t->task_list_node); + free(t->stack_base); + free(t); +} + +static void insert_run_q_head(struct task *t) +{ + ASSERT(t != &idle_task); + ASSERT(run_q_len < task_count); + + list_add_head(&run_q, &t->queue_node); + run_q_len++; +} + +static void insert_run_q_tail(struct task *t) +{ + ASSERT(t != &idle_task); + ASSERT(run_q_len < task_count); + + list_add_tail(&run_q, &t->queue_node); + run_q_len++; +} + +static struct task *pop_run_q_head(void) +{ + struct task *t = list_remove_head_type(&run_q, struct task, queue_node); + if (t) { + ASSERT(run_q_len > 0); + run_q_len--; + } + return t; +} + +void task_yield(void) +{ + struct task *old_task; + struct task *new_task; + + last_yield = timer_get_ticks(); + + /* + * If the current task is still ready to run and there's no other tasks ready, just + * continue. + * Note that this is simply an optimisation to avoid entering the critical section; + * we will later check again whether the current task is runnable to avoid racing + * with wakeups. + */ + if (likely(run_q_len == 0) && likely(current_task->state == TASK_RUNNING)) + return; + + /* + * It's not safe to yield in panic context. + */ + ASSERT(NULL == gPanicStr); + + /* + * Sanity check the world before we yield from this task. + * + * XXX we could avoid this for the idle task to improve latency for + * tasks made runnable in interrupt context. + */ + if (likely(&bootstrap_task != current_task)) { +#if defined(__arm__) && !defined(__clang_analyzer__) + /* the bootstrap task might yield before calling task_init() */ + /* XXX really? */ + if (unlikely(nullptr_value != *(volatile uint32_t *)NULL)) + panic("reset vector overwritten while executing task '%s' (0x%08x)", + current_task->name, *(volatile uint32_t *)NULL); +#endif + + /* we don't know the base of the bootstrap stack, so it has no magic */ + if (unlikely(task_stack_magic != *(uint32_t *)current_task->stack_base)) + panic("task '%s' has overflowed its stack", current_task->name); + } + + enter_critical_section(); + + /* + * We're headed to another task, so cancel the deep idle callout. Clear the + * flag too, just in case. + */ + callout_dequeue(&deep_idle_callout); + deep_idle = false; + + /* if it's blocked or finished, it shouldn't go back to the run queue */ + old_task = current_task; + if (old_task->state == TASK_RUNNING) { + old_task->state = TASK_READY; + /* the idle task gets scheduled when the run_q is empty; don't put it in there */ + if (old_task != &idle_task) + insert_run_q_tail(old_task); + } + + /* find the next task */ + new_task = pop_run_q_head(); + if (new_task == NULL) + new_task = &idle_task; + +#if 0 + dprintf(DEBUG_SPEW, "task_yield: switching from task %p (%s) %d %p to task %p (%s) %d %p\n", + old_task, old_task->name, old_task->irq_disable_count, old_task->stack_base, + new_task, new_task->name, new_task->irq_disable_count, new_task->stack_base); +#endif + + ASSERT(new_task != old_task); + + new_task->state = TASK_RUNNING; + current_task = new_task; + + /* XXX we could sanity-check the new task here before switching to it */ + arch_task_context_switch(&old_task->arch, &new_task->arch); + + last_switch = timer_get_ticks(); + + exit_critical_section(); +} + +void task_start(struct task *t) +{ + ASSERT(NULL != t); + + if (t->state == TASK_INITIAL) { + /* stick it in the run queue */ + t->state = TASK_READY; + enter_critical_section(); + insert_run_q_tail(t); + exit_critical_section(); + } +} + +void task_exit(int return_code) +{ + /* set our return code and wake anyone waiting on us */ + current_task->return_code = return_code; + current_task->state = TASK_FINISHED; + wait_queue_wake_all(¤t_task->return_waiters); + + task_count--; + task_yield(); + + /* should never reach here */ + panic("task_exit: should not be here\n"); +} + +int task_wait_on(struct task *t) +{ + ASSERT(NULL != t); + + if (t->state == TASK_FINISHED) + return t->return_code; + + /* block on the task's wait queue and return with it's return code */ + // XXX race condition here for someone deleting the finished task before a + // waiter gets to read it's return code + task_block(&t->return_waiters); + ASSERT(t->state == TASK_FINISHED); + + return t->return_code; +} + +void task_block(struct task_wait_queue *q) +{ + /* stick ourselves into the wait queue, set our state to BLOCKED, and yield */ + enter_critical_section(); + current_task->state = TASK_BLOCKED; + list_add_tail(&q->task_list, ¤t_task->queue_node); + + task_yield(); + exit_critical_section(); +} + +/* happens at interrupt context */ +static void task_sleep_callback(struct callout *c, void *_task) +{ + struct task *t = (struct task *)_task; + + ASSERT(c == &t->sleep_callout); + ASSERT(t->state == TASK_SLEEPING); + + t->state = TASK_READY; + insert_run_q_tail(t); +} + +void task_sleep(utime_t delay) +{ + /* queue our sleep callout and reschedule */ + enter_critical_section(); + current_task->state = TASK_SLEEPING; + callout_enqueue(¤t_task->sleep_callout, delay, &task_sleep_callback, current_task); + + task_yield(); + exit_critical_section(); +} + +/* wait queue stuff */ + +void wait_queue_init(struct task_wait_queue *q) +{ + ASSERT(NULL != q); + + list_initialize(&q->task_list); +} + +void wait_queue_destroy(struct task_wait_queue *q) +{ + wait_queue_wake_all(q); +} + +int wait_queue_wake_all(struct task_wait_queue *q) +{ + struct task *t; + struct task *temp; + int ret = 0; + + /* iterate through the wait queue, sticking each of the waiting threads in the run queue */ + enter_critical_section(); + list_for_every_entry_safe(&q->task_list, t, temp, struct task, queue_node) { + list_delete(&t->queue_node); + + ASSERT(t->state == TASK_BLOCKED); + t->state = TASK_READY; + insert_run_q_tail(t); + ret++; + } + exit_critical_section(); + return ret; +} + +int wait_queue_wake_one(struct task_wait_queue *q) +{ + struct task *t; + int ret = 0; + + /* pop the head of the wait queue and stick in the run queue */ + enter_critical_section(); + t = list_remove_head_type(&q->task_list, struct task, queue_node); + + if (t) { + ASSERT(t->state == TASK_BLOCKED); + t->state = TASK_READY; + insert_run_q_tail(t); + ret = 1; + } + exit_critical_section(); + + return ret; +} + +/* profile the task manager */ +void task_get_statistics(struct idle_statistics *s) +{ + u_int64_t now; + + enter_critical_section(); + now = timer_get_ticks(); + s->uptime_ticks = now - boot_time_ticks; + s->ticksHz = timer_get_tick_rate(); + s->idle_ticks = idle_ticks; + s->idles = shallow_idle_cnt; + s->deep_idle_ticks = deep_idle_ticks; + s->deep_idles = deep_idle_cnt; + s->threshold_us = deep_idle_threshold_us; + exit_critical_section(); +} + + +void task_set_idle_threshold(u_int32_t us) +{ + deep_idle_threshold_us = us; +} + +/* event stuff */ + +void event_init(struct task_event *event, uint32_t flags, bool initial_state) +{ + ASSERT(NULL != event); + + wait_queue_init(&event->wait); + event->signalled = initial_state; + event->flags = flags; +} + +void event_signal(struct task_event *event) +{ + enter_critical_section(); + event->signalled = true; + + if (event->flags & EVENT_FLAG_AUTO_UNSIGNAL) { + /* only allow one task to get through and unsignal */ + if (wait_queue_wake_one(&event->wait) > 0) { + event->signalled = false; + } + } else { + wait_queue_wake_all(&event->wait); + } + + exit_critical_section(); +} + +void event_unsignal(struct task_event *event) +{ + event->signalled = false; +} + +void event_wait(struct task_event *event) +{ + enter_critical_section(); + if (event->signalled == false) { + /* block on the wait queue */ + task_block(&event->wait); + } else { + /* we're the first task here, unsignal the lock */ + if (event->flags & EVENT_FLAG_AUTO_UNSIGNAL) + event->signalled = false; + } + exit_critical_section(); +} + +/* happens at interrupt context */ +struct event_wait_callback_info { + struct task_event *event; + struct task *task; + bool timed_out; +}; + +static void event_wait_callback(struct callout *c, void *_info) +{ + struct event_wait_callback_info *info = (struct event_wait_callback_info *)_info; + struct task_wait_queue *q = &info->event->wait; + struct task *task = info->task; + struct task *t, *temp; + + /* we may be racing with a legitimate wakeup, in which case we have not timed out */ + if (TASK_BLOCKED != task->state) + return; + + /* verify that we are blocked on the queue we think we're blocked on */ + list_for_every_entry_safe(&q->task_list, t, temp, struct task, queue_node) { + if (t == task) { + list_delete(&t->queue_node); + + ASSERT(t->state == TASK_BLOCKED); + t->state = TASK_READY; + insert_run_q_tail(t); + + info->timed_out = true; + } + } +} + +bool event_wait_timeout(struct task_event *event, utime_t delay) +{ + bool ret; + + enter_critical_section(); + ret = event->signalled; + if (false == ret) { + + /* are we allowed to wait? */ + if (delay > 0) { + struct event_wait_callback_info info; + info.event = event; + info.task = current_task; + info.timed_out = false; + + /* block on the wait queue */ + callout_enqueue(¤t_task->sleep_callout, delay, event_wait_callback, &info); + task_block(&event->wait); + callout_dequeue(¤t_task->sleep_callout); + + /* if we didn't time out, the event was signalled and we woke because of it */ + if (false == info.timed_out) + ret = true; + } + } else { + /* we're the first task here, unsignal the lock */ + if (event->flags & EVENT_FLAG_AUTO_UNSIGNAL) + event->signalled = false; + } + + exit_critical_section(); + + return ret; +} + +/* debug stuff */ +static const char *task_state_to_string(enum task_state state) +{ + switch (state) { + case TASK_INITIAL: + return "initial"; + case TASK_READY: + return "ready"; + case TASK_RUNNING: + return "running"; + case TASK_BLOCKED: + return "blocked"; + case TASK_SLEEPING: + return "sleeping"; + case TASK_FINISHED: + return "finished"; + default: + return "unknown"; + } +} + +static void dump_task(struct task *t) +{ + uint32_t i; + + dprintf(DEBUG_CRITICAL, "task %p (%s):\n", t, t->name); + dprintf(DEBUG_CRITICAL, " state %d (%s) interrupts %sabled (%d)\n", + t->state, + task_state_to_string(t->state), + (t->irq_disable_count == 0) ? "en" : "dis", + t->irq_disable_count); + dprintf(DEBUG_CRITICAL, " stack base %p, len 0x%zx, ", t->stack_base, t->stack_len); + + if (task_stack_magic != *(uint32_t *)t->stack_base) { + dprintf(DEBUG_CRITICAL, "overflowed\n"); + } else { + for (i = 0; i < (t->stack_len / sizeof(uint32_t)); i++) + if (task_stack_magic != *((uint32_t *)t->stack_base + i)) + break; + dprintf(DEBUG_CRITICAL, "used 0x%lx\n", t->stack_len - (i * sizeof(uint32_t))); + } + printf(" start routine %p, args %p\n", t->routine, t->arg); +} + +static int do_task(int argc, struct cmd_arg *args) +{ + if (argc < 2) { + printf("not enough arguments\n"); +usage: + printf("usage: \n"); + printf("%s list\n", args[0].str); + printf("%s uptime\n", args[0].str); + return -1; + } + + if (!strcmp(args[1].str, "list")) { + struct task *t; + + list_for_every_entry(&task_list, t, struct task, task_list_node) { + dump_task(t); + } + } else if (!strcmp(args[1].str, "uptime")) { + uint64_t now; + utime_t elapsed, idle, active; + + now = timer_get_ticks(); + + /* convert to microseconds */ + elapsed = timer_ticks_to_usecs(now - boot_time_ticks); + idle = timer_ticks_to_usecs(idle_ticks); + active = elapsed - idle; + printf("up %u.%06u idle %u.%06u active %u.%06u\n", + (unsigned)(elapsed / (1000 * 1000)), (unsigned)(elapsed % (1000 * 1000)), + (unsigned)(idle / (1000 * 1000)), (unsigned)(idle % (1000 * 1000)), + (unsigned)(active / (1000 * 1000)), (unsigned)(active % (1000 * 1000))); + } else { + printf("unrecognized subcommand\n"); + goto usage; + } + + return 0; +} + +MENU_COMMAND_DEVELOPMENT(task, do_task, "examine system tasks", NULL); + +/* + * Validate that a task pointer points to something that looks like a task. + */ +static bool task_ptr_sanity(struct task *t) +{ + if ((u_int32_t)t % 4) { + dprintf(DEBUG_CRITICAL, "task pointer %p bad, task list corrupt\n", t); + return(false); + } + /* add extra bad-address checks here */ + + if ((TASK_MAGIC != t->magic) || (TASK_MAGIC2 != t->magic2)) { + dprintf(DEBUG_CRITICAL, "task %p (corrupt)\n", t); + return(false); + } + return(true); +} + +static void do_task_panic(void *junk) +{ + struct task *t; + int tcount; + + dprintf(DEBUG_CRITICAL, "current "); + if (task_ptr_sanity(current_task)) { + dump_task(current_task); + arch_backtrace_current_task(current_task->stack_base, current_task->stack_len); + } + tcount = 0; + list_for_every_entry(&task_list, t, struct task, task_list_node) { + if (current_task != t) { + if (!task_ptr_sanity(t)) + break; + + /* paranoia */ + t->name[TASK_NAME_MAX] = 0; + dump_task(t); + arch_backtrace_task(&t->arch, t->stack_base, t->stack_len); + } + /* XXX tasks aren't properly reaped so many tasks exiting will confuse this */ + if (tcount++ > (task_count + 2)) { + dprintf(DEBUG_CRITICAL, "too many tasks, task list probably corrupt\n"); + break; + } + } +} + +PANIC_HOOK(task, do_task_panic, NULL); diff --git a/sys/tests-list.c b/sys/tests-list.c new file mode 100644 index 0000000..1a0398d --- /dev/null +++ b/sys/tests-list.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +void test_list_is_empty(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + struct list_node list2; + + struct list_node item; + struct list_node item2; + + TEST_ASSERT(list_is_empty(&list)); + + list_add_head(&list, &item); + + TEST_ASSERT(!list_is_empty(&list)); + + list_initialize(&list2); + + TEST_ASSERT(list_is_empty(&list2)); + + list_add_head(&list2, &item2); + + TEST_ASSERT(!list_is_empty(&list2)); +} + +void test_list_add_head(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + struct list_node *iter; + + struct list_node item1; + struct list_node item2; + struct list_node item3; + + struct list_node* items[] = {&item1, &item2, &item3}; + int i; + + list_add_head(&list, &item1); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 1); + TEST_ASSERT_PTR_EQ(items[1 - (i + 1)], iter); + i++; + } + + list_add_head(&list, &item2); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 2); + TEST_ASSERT_PTR_EQ(items[2 - (i + 1)], iter); + i++; + } + + list_add_head(&list, &item3); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 3); + TEST_ASSERT_PTR_EQ(items[3 - (i + 1)], iter); + i++; + } +} + +void test_list_add_tail(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + struct list_node *iter; + + struct list_node item1; + struct list_node item2; + struct list_node item3; + + struct list_node* items[] = {&item1, &item2, &item3}; + int i; + + list_add_tail(&list, &item1); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 1); + TEST_ASSERT_PTR_EQ(items[i], iter); + i++; + } + + list_add_tail(&list, &item2); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 2); + TEST_ASSERT_PTR_EQ(items[i], iter); + i++; + } + + list_add_tail(&list, &item3); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 3); + TEST_ASSERT_PTR_EQ(items[i], iter); + i++; + } +} + +void test_list_remove_head(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + struct list_node *iter; + struct list_node *removed; + + struct list_node item1; + struct list_node item2; + struct list_node item3; + + struct list_node* items[] = {&item1, &item2, &item3}; + int i; + + list_add_tail(&list, &item1); + list_add_tail(&list, &item2); + list_add_tail(&list, &item3); + + removed = list_remove_head(&list); + TEST_ASSERT_PTR_EQ(removed, &item1); + TEST_ASSERT(!list_in_list(removed)); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 2); + TEST_ASSERT_PTR_EQ(items[i + 1], iter); + i++; + } + + removed = list_remove_head(&list); + TEST_ASSERT_PTR_EQ(removed, &item2); + TEST_ASSERT(!list_in_list(removed)); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 1); + TEST_ASSERT_PTR_EQ(items[i + 2], iter); + i++; + } + + removed = list_remove_head(&list); + TEST_ASSERT_PTR_EQ(removed, &item3); + TEST_ASSERT(!list_in_list(removed)); + TEST_ASSERT(list_is_empty(&list)); + + removed = list_remove_head(&list); + TEST_ASSERT_NULL(removed); + TEST_ASSERT(list_is_empty(&list)); +} + +void test_list_remove_tail(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + struct list_node *iter; + struct list_node *removed; + + struct list_node item1; + struct list_node item2; + struct list_node item3; + + struct list_node* items[] = {&item1, &item2, &item3}; + int i; + + list_add_tail(&list, &item1); + list_add_tail(&list, &item2); + list_add_tail(&list, &item3); + + removed = list_remove_tail(&list); + TEST_ASSERT_PTR_EQ(removed, &item3); + TEST_ASSERT(!list_in_list(removed)); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 2); + TEST_ASSERT_PTR_EQ(items[i], iter); + i++; + } + + removed = list_remove_tail(&list); + TEST_ASSERT_PTR_EQ(removed, &item2); + TEST_ASSERT(!list_in_list(removed)); + + i = 0; + list_for_every(&list, iter) { + TEST_ASSERT_LT(i, 1); + TEST_ASSERT_PTR_EQ(items[i], iter); + i++; + } + + removed = list_remove_tail(&list); + TEST_ASSERT_PTR_EQ(removed, &item1); + TEST_ASSERT(!list_in_list(removed)); + TEST_ASSERT(list_is_empty(&list)); + + removed = list_remove_head(&list); + TEST_ASSERT_NULL(removed); + TEST_ASSERT(list_is_empty(&list)); +} + +void test_safe_unlink_double_free(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + + struct list_node item1; + struct list_node item2; + + list_add_tail(&list, &item1); + list_add_tail(&list, &item2); + + list_delete(&item1); + + TEST_EXPECT_PANIC(); + list_delete(&item1); + TEST_EXPECT_PANICKED(); +} + +void test_safe_unlink_next_corrupt(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + + struct list_node item1; + struct list_node item2; + + list_add_tail(&list, &item1); + list_add_tail(&list, &item2); + + item1.next = item1.next->next; + + TEST_EXPECT_PANIC(); + list_delete(&item1); + TEST_EXPECT_PANICKED(); +} + +void test_safe_unlink_prev_corrupt(uintptr_t param) +{ + struct list_node list = LIST_INITIAL_VALUE(list); + + struct list_node item1; + struct list_node item2; + + list_add_tail(&list, &item1); + list_add_tail(&list, &item2); + + item1.prev = item1.prev->prev; + + TEST_EXPECT_PANIC(); + list_delete(&item1); + TEST_EXPECT_PANICKED(); +} + +struct test_suite linked_list_suite = { + .name = "linked_list", + .test_cases = { + { "list_is_empty", test_list_is_empty, 0, "Tests list_is_empty" }, + { "list_add_head", test_list_add_head, 0, "Tests list_add_head" }, + { "list_add_tail", test_list_add_tail, 0, "Tests list_add_tail" }, + { "list_remove_head", test_list_remove_head, 0, "Tests list_remove_head" }, + { "list_remove_tail", test_list_remove_tail, 0, "Tests list_remove_tail" }, + { "safe_unlink_double_free", test_safe_unlink_double_free, 0, "Tests removing an item twice is detected" }, + { "safe_unlink_next_corrupt", test_safe_unlink_next_corrupt, 0, "Tests corrupting the next pointer is detected" }, + { "safe_unlink_prev_corrupt", test_safe_unlink_prev_corrupt, 0, "Tests corrupting the next pointer is detected" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(linked_list_suite); diff --git a/sys/tests-sha384.c b/sys/tests-sha384.c new file mode 100644 index 0000000..5b1acf3 --- /dev/null +++ b/sys/tests-sha384.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include + +void sha384_calculate(const void *in_ptr, size_t in_len, void *out_ptr, size_t out_len); + +struct sha384_test { + const char *data; + uint32_t len; + uint8_t expected[CCSHA384_OUTPUT_SIZE]; +}; + +static struct sha384_test sha384_tests[] = { + { "", 0, + { 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b} }, + + { "abc", 3, + { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } }, + + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39, 0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39, 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab, 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6, 0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f, 0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b } }, + +}; + +void test_sha384(uintptr_t param) +{ + for (unsigned i = 0; i < sizeof sha384_tests / sizeof(sha384_tests[0]); i++) { + struct sha384_test *test = &sha384_tests[i]; + + uint8_t calculated[CCSHA384_OUTPUT_SIZE]; + + sha384_calculate((void *)test->data, test->len, (void *)calculated, sizeof(calculated)); + + TEST_ASSERT_MEM_EQ(calculated, test->expected, sizeof(test->expected)); + } +} + +struct test_suite sha384_suite = { + .name = "sha384", + .test_cases = { + { "sha384", test_sha384, 0, "Tests the sha384_calculate function" }, + TEST_CASE_LAST + } +}; + +TEST_SUITE(sha384_suite); diff --git a/sys/tests.mk b/sys/tests.mk new file mode 100644 index 0000000..cd56d7c --- /dev/null +++ b/sys/tests.mk @@ -0,0 +1,28 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := iboot-sys + +TEST_OBJS := \ + $(LOCAL_DIR)/hash.o + +TEST_SUPPORT_OBJS := \ + tests/unittest-main.o \ + $(LOCAL_DIR)/tests-sha384.o \ + $(LOCAL_DIR)/tests-list.o + +HOST_SDKROOT_PATH := $(shell xcodebuild -version -sdk macosx.internal Path) + +TEST_CFLAGS := \ + -DWITH_SHA2_384=1 \ + -I$(HOST_SDKROOT_PATH)/usr/local/include + diff --git a/sys/time.c b/sys/time.c new file mode 100644 index 0000000..46de2b5 --- /dev/null +++ b/sys/time.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007-2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include /* for __unused */ +#include +#include +#include + +#if WITH_HW_TIMER +utime_t system_time(void) +{ + return timer_ticks_to_usecs(timer_get_ticks()); +} + +bool time_has_elapsed(utime_t start_time, utime_t timeout) +{ + return ((system_time() - start_time) >= timeout) ? true : false; +} + +void spin(utime_t usecs) +{ + utime_t t; + + t = system_time(); + while (system_time() - t < usecs) + ; +} +#else +utime_t system_time(void) +{ + return 0; +} + +bool time_has_elapsed(utime_t start_time __unused, utime_t timeout __unused) +{ + return true; +} + +void spin(utime_t usecs __unused) +{ +} + +#endif + +#if WITH_HW_POWER + +utime_t calendar_time(void) +{ + return power_get_calendar_time(); +} + +#else + +utime_t calendar_time(void) +{ + return 0; +} + +#endif \ No newline at end of file diff --git a/target/alcatrazref/include/target/adbe_settings.h b/target/alcatrazref/include/target/adbe_settings.h new file mode 100644 index 0000000..7aa1a06 --- /dev/null +++ b/target/alcatrazref/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_AFC_TEARDOWN_ENABLE | DBEMODECNTL_PMGR_CLK_GATE_ENABL| DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/alcatrazref/include/target/aspnandconfig.h b/target/alcatrazref/include/target/aspnandconfig.h new file mode 100644 index 0000000..0800563 --- /dev/null +++ b/target/alcatrazref/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/alcatrazref/include/target/gpiodef.h b/target/alcatrazref/include/target/gpiodef.h new file mode 100644 index 0000000..9e78dbb --- /dev/null +++ b/target/alcatrazref/include/target/gpiodef.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iRef,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_RINGER_AB GPIO( 2, 0) + +#define GPIO_WDOG GPIO( 0, 1) // WDOG + +/* D2094 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 5) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/alcatrazref/include/target/powerconfig.h b/target/alcatrazref/include/target/powerconfig.h new file mode 100644 index 0000000..f47c446 --- /dev/null +++ b/target/alcatrazref/include/target/powerconfig.h @@ -0,0 +1,88 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2045_LDO9_VSEL, 0x5A}, // LDO9 (PP2V8_CAM) to 2.85V + + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xAE }, // Current OTP enables LDO{1,2,3,4,5,7}, disable LDO4. + { PMU_IIC_BUS, kD2045_ACTIVE6, 0x37 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1, BUCK4_SW2 + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + + { PMU_IIC_BUS, kD2045_HIBERNATE1, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE3, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE6, 0x24 }, +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup_a0[] = +{ + { PMU_IIC_BUS, kD2045_LDO9_VSEL, 0x42}, // LDO9 (PP2V8_CAM) to 2.85V + + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xAE }, // Current OTP enables LDO{1,2,3,4,5,7}, disable LDO4. + { PMU_IIC_BUS, kD2045_ACTIVE6, 0x37 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1, BUCK4_SW2 + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + + // N51: Workaround needed for hibernate on PROTO2 Amber OTP + { PMU_IIC_BUS, 0x7000, 0x1d }, // Enable test mode + { PMU_IIC_BUS, kD2045_BUTTON4_CONF, 0x94 }, // Set BUTTON4 config to be pulled up to VBUCK3 instead of VBUCK3_SW + { PMU_IIC_BUS, 0x7000, 0x00 }, // Disable test mode + + { PMU_IIC_BUS, kD2045_HIBERNATE1, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE3, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE6, 0x24 }, +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2045_GPIO_DEB2, 0x12 }, + { PMU_IIC_BUS, kD2045_GPIO_DEB5, 0x12 }, + { PMU_IIC_BUS, kD2045_GPIO_DEB6, 0x12 }, + + { PMU_IIC_BUS, kD2045_BUCK_DWI_CTRL0, 0x03 }, // enable DWI for BUCK0, BUCK1 + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + + { PMU_IIC_BUS, kD2045_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/alcatrazref/include/target/uartconfig.h b/target/alcatrazref/include/target/uartconfig.h new file mode 100644 index 0000000..6d43057 --- /dev/null +++ b/target/alcatrazref/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/alcatrazref/init.c b/target/alcatrazref/init.c new file mode 100644 index 0000000..341e440 --- /dev/null +++ b/target/alcatrazref/init.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +uint32_t display_config; + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000da2; + return ((void *)(&display_config)); +} +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "n51", 0); +} + +#endif // WITH_ENV + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + return 0; +} + +#endif // WITH_DEVICETREE diff --git a/target/alcatrazref/pinconfig.c b/target/alcatrazref/pinconfig.c new file mode 100644 index 0000000..135b78b --- /dev/null +++ b/target/alcatrazref/pinconfig.c @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* N51/N53 (iPhone6,x) Pin Configuration */ + +/* + * N51 pinlist v0.13 + * N51 HW ERS | System | Pinlist + */ + +#define CFG_DISABLED_SS_X4 (CFG_DISABLED | SLOW_SLEW | DRIVE_X4 ) +#define CFG_DISABLED_SS_X4_PD (CFG_DISABLED | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_DISABLED_SS_X1_PD (CFG_DISABLED | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_DISABLED_SS_X4_PU (CFG_DISABLED | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_DISABLED_SS_X1_PU (CFG_DISABLED | SLOW_SLEW | DRIVE_X1 | PULL_UP ) +#define CFG_IN_SS_X1 (CFG_IN | SLOW_SLEW | DRIVE_X1 ) +#define CFG_IN_SS_X2 (CFG_IN | SLOW_SLEW | DRIVE_X2 ) +#define CFG_IN_SS_X4 (CFG_IN | SLOW_SLEW | DRIVE_X4 ) +#define CFG_IN_SS_X4_PD (CFG_IN | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_IN_SS_X1_PD (CFG_IN | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_IN_SS_X4_PU (CFG_IN | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_IN_SS_X1_PU (CFG_IN | SLOW_SLEW | DRIVE_X1 | PULL_UP ) +#define CFG_OUT_0_SS_X4 (CFG_OUT_0 | SLOW_SLEW | DRIVE_X4 ) +#define CFG_OUT_0_SS_X4_PD (CFG_OUT_0 | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_OUT_0_SS_X1_PD (CFG_OUT_0 | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_OUT_0_SS_X4_PU (CFG_OUT_0 | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_OUT_0_SS_X1_PU (CFG_OUT_0 | SLOW_SLEW | DRIVE_X1 | PULL_UP ) +#define CFG_OUT_1_SS_X4 (CFG_OUT_1 | SLOW_SLEW | DRIVE_X4 ) +#define CFG_OUT_1_SS_X4_PD (CFG_OUT_1 | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_OUT_1_SS_X1_PD (CFG_OUT_1 | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_OUT_1_SS_X4_PU (CFG_OUT_1 | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_OUT_1_SS_X1_PU (CFG_OUT_1 | SLOW_SLEW | DRIVE_X1 | PULL_UP ) +#define CFG_FUNC0_SS_X1 (CFG_FUNC0 | SLOW_SLEW | DRIVE_X1 ) +#define CFG_FUNC0_SS_X2 (CFG_FUNC0 | SLOW_SLEW | DRIVE_X2 ) +#define CFG_FUNC0_SS_X4 (CFG_FUNC0 | SLOW_SLEW | DRIVE_X4 ) +#define CFG_FUNC0_SS_X4_PD (CFG_FUNC0 | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_FUNC0_SS_X2_PD (CFG_FUNC0 | SLOW_SLEW | DRIVE_X2 | PULL_DOWN) +#define CFG_FUNC0_SS_X1_PD (CFG_FUNC0 | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_FUNC0_SS_X4_PU (CFG_FUNC0 | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_FUNC0_SS_X1_PU (CFG_FUNC0 | SLOW_SLEW | DRIVE_X1 | PULL_UP ) + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED_SS_X4_PD, // TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED_SS_X4_PD, // WDOG -> AP_TO_PMU_RESET_IN + CFG_IN_SS_X1, // GPIO0 -> BUTTON_TO_AP_MENU_KEY_BUFF_L + CFG_IN_SS_X1, // GPIO1 -> BUTTON_TO_AP_HOLD_KEY_BUFF_L + CFG_IN_SS_X1_PU, // GPIO2 -> BUTTON_TO_AP_VOL_UP_L + CFG_IN_SS_X1_PU, // GPIO3 -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN_SS_X1_PU, // GPIO4 -> PMU_NIRQ [PMU_TO_AP_IRQ_L in N51] + CFG_OUT_0_SS_X4_PD, // GPIO5 -> AP_TO_SPKAMP_BEE_GEES + +/* Port 1 */ + CFG_OUT_0_SS_X4_PD, // GPIO6 -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0_SS_X4_PD, // GPIO7 -> AP_TO_BT_WAKE + CFG_IN_SS_X4, // GPIO8 -> AP_TO_BB_RST_L + CFG_DISABLED_SS_X4, // GPIO9 -> AP_TO_BB_JTAG_TDI + CFG_DISABLED_SS_X4_PD, // GPIO10 -> AP_TO_BB_JTAG_TDO + CFG_DISABLED_SS_X4_PD, // GPIO11 -> AP_TO_HEADSET_HS3_CTRL + CFG_DISABLED_SS_X4_PD, // GPIO12 -> AP_TO_HEADSET_HS4_CTRL + CFG_DISABLED, // GPIO13 -> NULL + +/* Port 2 */ + CFG_IN_SS_X1, // GPIO14 -> BUTTON_TO_AP_RINGER_A + CFG_OUT_0_SS_X4, // GPIO15 -> AP_TO_BB_WAKE_MODEM + CFG_DISABLED_SS_X1_PU, // GPIO16 -> N/C -> BOARD_ID[3] + CFG_IN_SS_X1, // GPIO17 -> AP_TO_OSCAR_DBGEN + CFG_DISABLED_SS_X1_PU, // GPIO18 -> BOARD_INFO -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> NULL + CFG_DISABLED, // GPIO20 -> NULL + CFG_DISABLED, // GPIO21 -> NULL + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_FUNC0_SS_X4_PU, // UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0_SS_X1_PU, // UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_FUNC0_SS_X4_PU, // UART1_RTSN -> AP_TO_BT_UART1_RTS_L + CFG_FUNC0_SS_X1_PU, // UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_FUNC0_SS_X4_PU, // UART2_TXD -> AP_TO_OSCAR_UART2_TXD + CFG_FUNC0_SS_X1_PU, // UART2_RXD -> OSCAR_TO_AP_UART2_RXD + CFG_OUT_1_SS_X4_PU, // UART2_RTSN -> AP_TO_OSCAR_RESET_L + CFG_IN_SS_X1_PD, // UART2_CTSN -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 5 */ + CFG_FUNC0_SS_X4, // UART3_TXD -> AP_TO_WLAN_UART3_TXD + CFG_FUNC0_SS_X1, // UART3_RXD -> WLAN_TO_AP_UART3_RXD + CFG_DISABLED_SS_X1_PD, // UART3_RTSN -> BB_TO_AP_PP_SYNC + CFG_OUT_0_SS_X4_PD, // UART3_CTSN -> AP_TO_RCAM_VDDCORE_EN + CFG_FUNC0_SS_X2, // UART5_RXD -> AP_BI_BATTERY_SWI + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 6 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 7 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 8 */ + CFG_OUT_0_SS_X4, // UART4_TXD -> AP_TO_BB_UART4_TXD + CFG_FUNC0_SS_X1, // UART4_RXD -> BB_TO_AP_UART4_RXD + CFG_OUT_0_SS_X4, // UART4_RTSN -> AP_TO_BB_UART4_RTS_L + CFG_FUNC0_SS_X1, // UART4_CTSN -> BB_TO_AP_UART4_CTS_L + CFG_FUNC0_SS_X4_PD, // SPI1_SCLK -> AP_TO_TOUCH_SPI1_CLK + CFG_FUNC0_SS_X4_PD, // SPI1_MOSI -> AP_TO_TOUCH_SPI1_MOSI + CFG_FUNC0_SS_X1_PD, // SPI1_MISO -> TOUCH_TO_AP_SPI1_MISO + CFG_FUNC0_SS_X4_PU, // SPI1_SSIN -> AP_TO_TOUCH_SPI1_CS_L + +/* Port 9 */ + CFG_DISABLED_SS_X1_PU, // SPI0_SCLK -> N/C -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED_SS_X1_PU, // SPI0_MOSI -> N/C -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED_SS_X1_PU, // SPI0_MISO -> N/C -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED_SS_X1_PD, // SPI0_SSIN -> LCM_TO_AP_PIFA + CFG_FUNC0_SS_X2, // SPI2_SCLK -> AP_TO_NAVAJO_SPI2_CLK + CFG_FUNC0_SS_X2, // SPI2_MOSI -> AP_TO_NAVAJO_SPI2_MOSI + CFG_FUNC0_SS_X2_PD, // SPI2_MISO -> NAVAJO_TO_AP_SPI2_MISO + CFG_FUNC0_SS_X2, // SPI2_SSIN -> NAVAJO_TO_PMU_INT_H + +/* Port 10 */ + CFG_FUNC0_SS_X4, // I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0_SS_X4, // I2C0_SCL -> AP_TO_I2C0_SDA + CFG_FUNC0_SS_X4, // I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0_SS_X4, // I2C1_SCL -> AP_TO_ISC1_SCL + CFG_FUNC0_SS_X4, // ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0_SS_X4, // ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0_SS_X4, // ISP1_SDA -> AP_TO_FCAM_I2C_SCL + CFG_FUNC0_SS_X4, // ISP1_SCL -> AP_TO_FCAM_I2C_SCL + +/* Port 11 */ + CFG_OUT_0_SS_X4_PD, // SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED_SS_X4_PD, // SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + CFG_IN_SS_X1_PU, // SENSOR0_XSHUTDOWN -> FCAM_TO_AP_ALS_INT_L + CFG_DISABLED_SS_X1_PD, // SENSOR0_ISTRB -> BB_TO_AP_IPC_GPIO + CFG_OUT_0_SS_X4_PD, // SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED_SS_X4_PD, // SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_DISABLED_SS_X1_PD, // SENSOR1_XSHUTDOWN -> N/C + CFG_OUT_0_SS_X4_PD, // SENSOR1_ISTRB -> AP_TO_LEDDRV_EN + +/* Port 12 */ + CFG_FUNC0_SS_X4_PD, // SPI3_MOSI -> AP_TO_CODEC_SPI3_MOSI + CFG_FUNC0_SS_X1_PD, // SPI3_MISO -> CODEC_TO_AP_SPI3_MISO + CFG_FUNC0_SS_X4_PD, // SPI3_SCLK -> AP_TO_CODEC_SPI3_CLK + CFG_FUNC0_SS_X4_PD, // SPI3_SSIN -> AP_TO_CODEC_SPI3_CS_L + CFG_DISABLED_SS_X1_PD, // I2C2_SDA -> N/C + CFG_DISABLED_SS_X1_PD, // I2C2_SCL -> N/C + CFG_DISABLED_SS_X4_PD, // GPIO22 -> AP_TO_PMU_KEEPACT + CFG_DISABLED_SS_X1_PD, // GPIO23 -> LCM_TO_AP_HIFA_BSYNC + +/* Port 13 */ + CFG_DISABLED_SS_X1_PD, // GPIO24 -> BB_TO_AP_RESET_DET_L + CFG_DISABLED_SS_X1_PU, // GPIO25 -> BOARD_INFO -> BOOT_CONFIG[1] + CFG_DISABLED_SS_X1_PD, // GPIO26 -> FORCE_DFU + CFG_DISABLED_SS_X1_PD, // GPIO27 -> DFU_STATUS + CFG_DISABLED_SS_X1_PU, // GPIO28 -> N/C -> BOOT_CONFIG[2] + CFG_DISABLED_SS_X1_PU, // GPIO29 -> N/C -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> NULL + CFG_IN_SS_X4, // GPIO31 -> AP_TO_RADIO_ON_L + +/* Port 14 */ + CFG_DISABLED_SS_X4, // GPIO32 -> AP_TO_BB_JTAG_TCK + CFG_DISABLED_SS_X4, // GPIO33 -> AP_TO_BB_JTAG_TMS + CFG_DISABLED_SS_X1_PU, // GPIO34 -> BOARD_INFO -> BOARD_REV3 + CFG_DISABLED_SS_X1_PU, // GPIO35 -> BOARD_INFO -> BOARD_REV2 + CFG_DISABLED_SS_X1_PU, // GPIO36 -> BOARD_INFO -> BOARD_REV1 + CFG_DISABLED_SS_X1_PU, // GPIO37 -> BOARD_INFO -> BOARD_REV0 + CFG_DISABLED_SS_X1_PU, // GPIO38 -> AP_TO_NAVAJO_DAISY_CHAIN + CFG_DISABLED_SS_X1_PD, // DISPLAY_SYNC -> N/C + +/* Port 15 */ + CFG_DISABLED_SS_X1_PU, // SOCHOT0 -> BB_TO_AP_SOCHOT0 + CFG_FUNC0_SS_X4, // SOCHOT1 -> AP_TO_PMU_SOCHOT1 + CFG_FUNC0_SS_X4_PU, // UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + CFG_FUNC0_SS_X1_PU, // UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_DISABLED_SS_X1_PD, // DWI_DI -> N/C + CFG_FUNC0_SS_X4_PD, // DWI_D0 -> 45_AP_TO_PMU_DWI_DO + CFG_FUNC0_SS_X4_PD, // DWI_CLK -> 45_AP_TO_PMU_DWI_CLK + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_FUNC0_SS_X4_PD, // I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0_SS_X4_PD, // I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0_SS_X1_PD, // I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED_SS_X4, // I2S1_MCK -> AP_TO_BB_JTAG_TRST_L + CFG_FUNC0_SS_X4_PD, // I2S1_LRCK -> AP_TO_BB_I2S1_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S1_BCLK -> 45_AP_TO_BB_I2S1_BCLK + CFG_FUNC0_SS_X4_PD, // I2S1_DOUT -> AP_TO_BB_I2S1_DOUT + +/* Port 17 */ + CFG_FUNC0_SS_X1_PD, // I2S1_DIN -> BB_TO_AP_I2S1_DIN + CFG_FUNC0_SS_X4_PD, // I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0_SS_X4_PD, // I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0_SS_X1_PD, // I2S2_DIN -> CODEC_TO_AP_XSP_I2S2_DIN + CFG_IN_SS_X1_PU, // I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0_SS_X4_PD, // I2S3_LRCK -> AP_TO_BT_I2S3_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S3_BCLK -> 45_AP_TO_BT_I2S3_BCLK + +/* Port 18 */ + CFG_FUNC0_SS_X4_PD, // I2S3_DOUT -> AP_TO_BT_I2S3_DOUT + CFG_FUNC0_SS_X1_PD, // I2S3_DIN -> BT_TO_AP_I2S3_DIN + CFG_IN_SS_X1_PD, // I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0_SS_X4_PD, // I2S4_LRCK -> AP_TO_CODEC_VSP_I2S4_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S4_BCLK + CFG_FUNC0_SS_X4_PD, // I2S4_DOUT -> AP_TO_CODEC_VSP_I2S4_DOUT + CFG_FUNC0_SS_X1_PD, // I2S4_DIN -> CODEC_TO_AP_VSP_I2S4_DIN + CFG_DISABLED, // NULL -> + +/* Port 19 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 20 */ + CFG_OUT_0_SS_X4_PD, // TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_DISABLED_SS_X4_PD, // TMR32_PWM1 -> AP_TO_PMU_VIBE_PWM_EN + CFG_FUNC0_SS_X4, // TMR32_PWM2 -> 45_AP_TO_TOUCH_CLK32K_RESET_L + CFG_OUT_0_SS_X4, // SIO_7816UART0_SDA -> AP_TO_BB_HSIC1_RDY + CFG_DISABLED_SS_X1_PD, // SIO_7816UART0_SCL -> BB_TO_AP_HSIC1_RDY + CFG_DISABLED_SS_X1_PD, // SIO_7816UART0_RST -> BB_TO_AP_HSIC1_REMOTE_WAKE + CFG_OUT_0_SS_X4, // SIO_7816UART1_SDA -> AP_TO_WLAN_HSIC2_RDY + CFG_IN_SS_X1_PD, // SIO_7816UART1_SCL -> WLAN_TO_AP_HSIC2_RDY + +/* Port 21 */ + CFG_IN_SS_X1_PD, // SIO_7816UART0_RST -> WLAN_TO_AP_HSIC2_REMOTE_WAKE + CFG_FUNC0_SS_X4_PU, // UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0_SS_X1_PU, // UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED_SS_X4_PD, // I2C3_SDA -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED_SS_X4_PD, // I2C3_SCL -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 22 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 23 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 24 */ + CFG_DISABLED_SS_X1_PD, // EPD_HPD -> N/C + CFG_FUNC0_SS_X4_PD, // I2S0_MCK -> 45_AP_TO_CODEC_I2S_MCLK_R + CFG_FUNC0_SS_X4_PD, // I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/alcatrazref/rules.mk b/target/alcatrazref/rules.mk new file mode 100644 index 0000000..923d346 --- /dev/null +++ b/target/alcatrazref/rules.mk @@ -0,0 +1,40 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2045=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_VID0_CLK_CFG=0x86100000 \ + DISPLAY_IPHONE_TUNABLES=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_DPHYCTL=0x30 \ + TARGET_DSIM_UP_CODE=0x1 \ + TARGET_DSIM_DOWN_CODE=0x1 \ + TARGET_DSIM_SUPPRESS=0x1 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_CPU_APSC=1 + +# this board may have no PMU installed, so AMP should not panic because of that +OPTIONS += \ + AMP_NO_PMU_PANIC=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/b184/include/target/adbe_settings.h b/target/b184/include/target/adbe_settings.h new file mode 100644 index 0000000..3c15c04 --- /dev/null +++ b/target/b184/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_AFC_TEARDOWN_ENABLE | DBEMODECNTL_PMGR_CLK_GATE_ENABL| DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/b184/include/target/amcconfig.h b/target/b184/include/target/amcconfig.h new file mode 100644 index 0000000..e224683 --- /dev/null +++ b/target/b184/include/target/amcconfig.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_ZQCL), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00020000, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 10, + .phywrlat = 2, + .pdn = 0x22000403, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .derate = 0x2483135b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x00000021, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00050000, + .aref_freq0 = 0x00000110, + .schen_default = 0x00000110, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x01, + .pwrmngten_default = 0x00100100, + .mcphyupdate1 = 0x00000001, + .odts = 0x190, + .readleveling = 0x00000300, + .offset_shift_hynix = 0, + .offset_shift_elpida = 1, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + .mifcassch = 0x00000110, + .arefparam = 0x0c022131, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 50MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001728 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQBRST, 0x04100410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOS, 0x00001919 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +}; diff --git a/target/b184/include/target/aspnandconfig.h b/target/b184/include/target/aspnandconfig.h new file mode 100644 index 0000000..cba8f88 --- /dev/null +++ b/target/b184/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_DIES_IN_PARALLEL 2 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/b184/include/target/gpiodef.h b/target/b184/include/target/gpiodef.h new file mode 100644 index 0000000..f607d58 --- /dev/null +++ b/target/b184/include/target/gpiodef.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPad4,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_PWR_EN GPIO( 2, 7) + +#define GPIO_RINGER_AB GPIO(13, 6) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 6) +#define GPIO_BOARD_REV1 GPIO(14, 5) +#define GPIO_BOARD_REV2 GPIO(14, 4) +#define GPIO_BOARD_REV3 GPIO(14, 3) + +/* which IICs to initialize */ +#define IICS_MASK (0x5) + +#define TRISTAR_IIC_BUS (0) + +/* D2089 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(12, 6) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/b184/include/target/powerconfig.h b/target/b184/include/target/powerconfig.h new file mode 100644 index 0000000..68c818b --- /dev/null +++ b/target/b184/include/target/powerconfig.h @@ -0,0 +1,90 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xAE }, // Current OTP enables LDO{1,2,3,4,5,7}, disable LDO4. + { PMU_IIC_BUS, kD2045_ACTIVE6, 0x37 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1, BUCK4_SW2 + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + + { PMU_IIC_BUS, kD2045_HIBERNATE1, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE3, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE6, 0x24 }, +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2045_GPIO1, 0xBB }, // AUD_ARRAY_HOST_WAKE In, R Edge, No PU, Wake, PD + { PMU_IIC_BUS, kD2045_GPIO2, 0xBB }, // WLAN2_HOST_WAKE IN, R Edge, No PU, Wake, PD + { PMU_IIC_BUS, kD2045_GPIO3, 0x0B }, // WLAN2_REG_ON Out 1, Buck 3, push-pull + { PMU_IIC_BUS, kD2045_GPIO4, 0xB9 }, // TRI_INT In, R Edge, No PU, no wake, PD + { PMU_IIC_BUS, kD2045_GPIO5, 0x09 }, // BT1_REG_ON + { PMU_IIC_BUS, kD2045_GPIO6, 0xBB }, // BT1_HOST_WAKE In, R Edge, No PU, wake, PD + { PMU_IIC_BUS, kD2045_GPIO7, 0xBB }, // WLAN1_HOST_WAKE In, R Edge, No PU, wake, PD + { PMU_IIC_BUS, kD2045_GPIO8, 0xBB }, // ENET_PHY_HOST_WAKE In, R Edge, No PU, wake, PD + { PMU_IIC_BUS, kD2045_GPIO9, 0x09 }, // BT2_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO10, 0xBB }, // BT2_HOST_WAKE In, R Edge, No PU, wake, PD + { PMU_IIC_BUS, kD2045_GPIO11, 0x0B }, // WLAN1_REG_ON Out 1, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO12, 0xBB }, // ENET_PME_1V8 In, R Edge, No PU, wake, PD + { PMU_IIC_BUS, kD2045_GPIO13, 0xBB }, // MCU_HOST_WAKE In, R Edge, No PU, wake, PD + { PMU_IIC_BUS, kD2045_GPIO14, 0x0B }, // PS_ON (16V) Out 1, VBUCK3, open drain + { PMU_IIC_BUS, kD2045_GPIO15, 0x7A }, // PMU_WAKE_ON_VCC + { PMU_IIC_BUS, kD2045_GPIO16, 0xBB }, // ACCEL_HOST_WAKE1 In, R Edge, No PU, wake, PD + { PMU_IIC_BUS, kD2045_OUT_32K, 0x49 }, // OUT_32K (WLAN_CLK32K) Out 32K, Push-Pull, VBUCK3 + + { PMU_IIC_BUS, kD2045_BUCK_DWI_CTRL0, 0x03 }, // enable DWI for BUCK0, BUCK1 + + { PMU_IIC_BUS, kD2045_BUTTON1_CONF, 0x84 }, // PMU_BUTTTON1 + { PMU_IIC_BUS, kD2045_BUTTON2_CONF, 0x84 }, // PMU_BUTTTON2 + { PMU_IIC_BUS, kD2045_BUTTON3_CONF, 0xD4 }, // PMU_BUTTTON3 + { PMU_IIC_BUS, kD2045_BUTTON4_CONF, 0x94 }, // PMU_BUTTTON4 + + // Special function + { PMU_IIC_BUS, kDIALOG_BUTTON_DBL, 0x00 }, // + { PMU_IIC_BUS, kD2045_BUTTON_WAKE, 0x00 }, // AUD_ARRAY_HOST_WAKE + { PMU_IIC_BUS, kD2045_RESET_IN1_CONF,0x02}, // PMU_RESET_IN1_WDOG + { PMU_IIC_BUS, kD2045_RESET_IN2_CONF,0x00}, // PMU_RESET_IN2_TRISTAR + { PMU_IIC_BUS, kD2045_RESET_IN3_CONF,0x14}, // SOCHOT1_L + +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_POWER_NO_BATTERY 1 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (3000) +#define PRECHARGE_BACKLIGHT_LEVEL 103 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/b184/include/target/uartconfig.h b/target/b184/include/target/uartconfig.h new file mode 100644 index 0000000..6d43057 --- /dev/null +++ b/target/b184/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/b184/include/target/usbconfig.h b/target/b184/include/target/usbconfig.h new file mode 100644 index 0000000..ac2ef76 --- /dev/null +++ b/target/b184/include/target/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_OTGTUNE0 + +#undef USBPHY_OTGTUNE0 +#define USBPHY_OTGTUNE0 (0x3644D3F3) + +#endif /* USBPHY_OTGTUNE0 */ + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/b184/init.c b/target/b184/init.c new file mode 100644 index 0000000..ccb8caf --- /dev/null +++ b/target/b184/init.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static u_int32_t b184_get_board_rev(void) +{ + + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + + +void target_early_init(void) +{ + +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); +} + +#endif // WITH_ENV + +bool target_has_tristar2(void) +{ + return true; // TODO: Does it have tristar2? +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; +#endif + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Store secondary mac addresses into products node + if (FindNode(0, "product", &node)) { + propName = "mac-address-wifi1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("wifi1addr")) { + env_get_ethaddr("wifi1addr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_WIFI1_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + + propName = "mac-address-ethernet1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("eth1addr")) { + env_get_ethaddr("eth1addr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_ETH1_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + + propName = "mac-address-bluetooth1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("bt1addr")) { + env_get_ethaddr("bt1addr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_BT1_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + // Store second wlan mac address into wlan1 node + if (FindNode(0, "arm-io/usb-complex/usb-ehci1/wlan1", &node)) { + propName = "local-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("wifi1addr")) { + env_get_ethaddr("wifi1addr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_WIFI1_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + // Add bluetooth, ethernet second mac address when node is available + // B184 /12A43 : bluetooth not responding + + // TriStar 1 on older systems + if (!target_has_tristar2()) { + if (FindNode(0, "arm-io/i2c2/tristar", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "tristar,cbtl1608", kPropNameLength); + } + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CBAT', propData, propSize); + } + } + + return 0; +} + +#endif // WITH_DEVICETREE diff --git a/target/b184/pinconfig.c b/target/b184/pinconfig.c new file mode 100644 index 0000000..f683005 --- /dev/null +++ b/target/b184/pinconfig.c @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: version 1.16 + I/O Spreadsheet tracker: 12739020&15521285 +*/ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> SOC_WDOG + CFG_IN, // 2 : GPIO[0] -> PMU_BUTTON1 + CFG_IN, // 3 : GPIO[1] -> PMU_BUTTON2 + CFG_IN, // 4 : GPIO[2] -> PMU_BUTTON3 + CFG_IN, // 5 : GPIO[3] -> PMU_BUTTON4 + CFG_IN, // 6 : GPIO[4] -> ACCEL_HOST_WAKE1 + CFG_IN, // 7 : GPIO[5] -> PS_ON_SOC + +/* Port 1 */ + CFG_IN, // 8 : GPIO[6] -> AUD_ARRAY_HOST_WAKE + CFG_IN, // 9 : GPIO[7] -> BT2_BTWAKE + CFG_IN, // 10 : GPIO[8] -> ENET_PHY_HOST_WAKE + CFG_IN, // 11 : GPIO[9] -> MCU_HOST_WAKE + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 12 : GPIO[10] -> SOC_TO_ENET_PME_MODE_SEL + CFG_IN, // 13 : GPIO[11] -> SOC_TO_MCU_RESET_L + CFG_IN, // 14 : GPIO[12] -> SOC_TO_MCU_BOOTLOAD + CFG_IN | PULL_UP, // 15 : GPIO[13] -> PMU_IRQ_L + +/* Port 2 */ + CFG_IN, // 16 : GPIO[14] -> SOC_WLAN_ASTP_SEL + CFG_IN, // 17 : GPIO[15] -> ENET_HSIC_DEVICE_READY + CFG_IN | PULL_DOWN, // 18 : GPIO[16] -> BOARDID_3 + CFG_IN, // 19 : GPIO[17] -> TRI_INT + CFG_IN | PULL_DOWN, // 20 : GPIO[18] -> BOOTCONFIG_0 + CFG_OUT_0 | SLOW_SLEW, // 21 : GPIO[19] -> PMU_KEEPACT + CFG_DISABLED, // 22 : GPIO[20] -> NC_SPDIF_LOCK_L + CFG_DISABLED, // 23 : GPIO[21] -> NC_SPDIF_INT_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | SLOW_SLEW, // 32 : UART1_TXD -> SOC_UART1_TO_MCU_TXD + CFG_FUNC0, // 33 : UART1_RXD -> MCU_TO_SOC_UART1_RXD + CFG_OUT_0, // 34 : UART1_RTSN -> MCU_SWCLK + CFG_IN | SLOW_SLEW, // 35 : UART1_CTSN -> MCU_SWDIO + CFG_FUNC0 | SLOW_SLEW, // 36 : UART2_TXD -> SOC_UART2_TO_BT_TXD + CFG_FUNC0, // 37 : UART2_RXD -> BT_TO_SOC_UART2_RXD + CFG_FUNC0, // 38 : UART2_RTSN -> SOC_UART2_TO_BT_RTSB + CFG_FUNC0, // 39 : UART2_CTSN -> BT_TO_SOC_UART2_CTSB + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : UART3_TXD -> WLAN1_TO_SOC_UART3_RXD + CFG_FUNC0, // 41 : UART3_RXD -> SOC_UART3_TO_WLAN1_TXD + CFG_DISABLED, // 42 : UART3_RTSN -> NC_UART3_RTSN + CFG_DISABLED, // 43 : UART3_CTSN -> NC_UART3_CTSN + CFG_DISABLED, // 44 : UART5_RTXD -> UART5_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_FUNC0 | SLOW_SLEW, // 64 : UART4_TXD -> SOC_UART4_TO_WLAN2_TXD + CFG_FUNC0, // 65 : UART4_RXD -> WLAN2_TO_SOC_UART4_RXD + CFG_DISABLED, // 66 : UART4_RTSN -> NC_UART4_RTSN + CFG_DISABLED, // 67 : UART4_CTSN -> NC_UART4_CTSN + CFG_DISABLED, // 68 : SPI1_SCLK -> NC_SPI1_SCLK + CFG_DISABLED, // 69 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 70 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 71 : SPI1_SSIN -> NC_SPI1_SSIN + +/* Port 9 */ + CFG_IN | PULL_DOWN, // 72 : SPI0_SCLK -> BOARDID_0 + CFG_IN | PULL_DOWN, // 73 : SPI0_MOSI -> BOARDID_1 + CFG_IN | PULL_DOWN, // 74 : SPI0_MISO -> BOARDID_2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_DISABLED, // 76 : SPI2_SCLK -> NC_SPI2_SCLK + CFG_DISABLED, // 77 : SPI2_MOSI -> NC_SPI2_MOSI + CFG_DISABLED, // 78 : SPI2_MISO -> NC_SPI2_MISO + CFG_DISABLED, // 79 : SPI2_SSIN -> NC_SPI2_SSIN + +/* Port 10 */ + CFG_FUNC0 | SLOW_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 82 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 83 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 84 : ISP0_SDA -> (NC) + CFG_DISABLED, // 85 : ISP0_SCL -> (NC) + CFG_DISABLED, // 86 : ISP1_SDA -> (NC) + CFG_DISABLED, // 87 : ISP1_SCL -> (NC) + +/* Port 11 */ + CFG_DISABLED, // 88 : SENSOR0_RST -> + CFG_DISABLED, // 89 : SENSOR0_CLK -> + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> + CFG_DISABLED, // 92 : SENSOR1_RST -> + CFG_DISABLED, // 93 : SENSOR1_CLK -> + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> + +/* Port 12 */ + CFG_DISABLED, // 96 : SPI3_MOSI -> NC_SPI3_MOSI + CFG_DISABLED, // 97 : SPI3_MISO -> NC_SPI3_MISO + CFG_DISABLED, // 98 : SPI3_SCLK -> NC_SPI3_SCLK + CFG_DISABLED, // 99 : SPI3_SSIN -> NC_SPI3_SSIN + CFG_DISABLED, // 100 : I2C2_SDA -> I2C2_SPDIF_SDA_1V8 + CFG_DISABLED, // 101 : I2C2_SCL -> I2C2_SPDIF_SCL_1V8 + CFG_DISABLED, // 102 : GPIO[22] -> NC_SPDIF_RESET_L + CFG_OUT_0 | PULL_UP | SLOW_SLEW, // 103 : GPIO[23] -> ENET_RESET_L + +/* Port 13 */ + CFG_IN, // 104 : GPIO[24] -> ENET_PME_1V8 + CFG_IN | PULL_DOWN, // 105 : GPIO[25] -> BOOTCONFIG_1 + CFG_IN, // 106 : GPIO[26] -> FORCE_DFU + CFG_OUT_0 | SLOW_SLEW, // 107 : GPIO[27] -> DFU_STATUS + CFG_IN | PULL_DOWN, // 108 : GPIO[28] -> BOOTCONFIG_2 + CFG_IN | PULL_DOWN, // 109 : GPIO[29] -> BOOTCONFIG_3 + CFG_IN, // 110 : GPIO[30] -> BT1_BTWAKE + CFG_DISABLED, // 111 : GPIO[31] -> SOC_ANALOG_SEL + +/* Port 14 */ + CFG_DISABLED, // 112 : GPIO[32] -> SOC_SPDIF_SEL + CFG_DISABLED, // 113 : GPIO[33] -> SOC_ANALOG_PWR_EN + CFG_IN | PULL_DOWN, // 114 : GPIO[34] -> BOARDREV_3 + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> BOARDREV_2 + CFG_IN | PULL_DOWN, // 116 : GPIO[36] -> BOARDREV_1 + CFG_IN | PULL_DOWN, // 117 : GPIO[37] -> BOARDREV_0 + CFG_OUT_0 | SLOW_SLEW, // 118 : GPIO[38] -> SOC_BT_SEL + CFG_DISABLED, // 119 : DISP_VSYNC -> SOC_DISP_VSYNC + +/* Port 15 */ + CFG_FUNC0, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | FAST_SLEW, // 122 : UART0_TXD -> UART0_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 125 : DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0, // 128 : I2S0_LRCK -> MCA_FSYNC_1V8 + CFG_FUNC0, // 129 : I2S0_BCLK -> MCA_BCLK_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> MCA0_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> MIC_DATA_1V8 + CFG_DISABLED, // 132 : I2S1_MCK -> I2S0_MCK + CFG_FUNC0, // 133 : I2S1_LRCK -> MCA_FSYNC_1V8 + CFG_FUNC0, // 134 : I2S1_BCLK -> MCA_BCLK_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> MCA1_DOUT + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S1_DIN -> MCA1_DIN + CFG_FUNC0, // 137 : I2S2_LRCK -> MCA_FSYNC_1V8 + CFG_FUNC0, // 138 : I2S2_BCLK -> MCA_BCLK_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> MCA2_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> MCU_MISO_1V8 + CFG_DISABLED, // 141 : I2S3_MCK -> NC_I2S2_MCK + CFG_FUNC0, // 142 : I2S3_LRCK -> MCA_FSYNC_1V8 + CFG_FUNC0, // 143 : I2S3_BCLK -> MCA_BCLK_1V8 + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> MCA3_DOUT + CFG_FUNC0, // 145 : I2S3_DIN -> MCA3_DIN + CFG_DISABLED, // 146 : I2S4_MCK -> NC_I2S4_MCK + CFG_DISABLED, // 147 : I2S4_LRCK -> NC_I2S4_LRCLK + CFG_DISABLED, // 148 : I2S4_BCLK -> NC_I2S4_BCLK + CFG_DISABLED, // 149 : I2S4_DOUT -> NC_I2S4_DOUT + CFG_DISABLED, // 150 : I2S4_DIN -> NC_I2S4_DIN + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : TMR32_PWM0 -> NC_TMR32_PWM0 + CFG_DISABLED, // 161 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 162 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_OUT_0 | FAST_SLEW, // 163 : SIO_7816UART0_SDA -> WLAN2_HOST_READY + CFG_IN, // 164 : SIO_7816UART0_SCL -> WLAN2_DEVICE_READY + CFG_IN, // 165 : SIO_7816UART0_RST -> WLAN2_HSIC_RESUME + CFG_OUT_0, // 166 : SIO_7816UART1_SDA -> WLAN1_HOST_READY + CFG_IN, // 167 : SIO_7816UART1_SCL -> WLAN1_DEVICE_READY + +/* Port 21 */ + CFG_IN, // 168 : SIO_7816UART1_RST -> WLAN1_HSIC_RESUME + CFG_FUNC0 | FAST_SLEW, // 169 : UART6_TXD -> UART6_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_RXD + CFG_DISABLED, // 171 : I2C3_SDA -> I2C_ARRAY_SCL_1V8 + CFG_DISABLED, // 172 : I2C3_SCL -> I2C_ARRAY_SDA_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_DISABLED, // 192 : EDP_HPD -> (NC) + CFG_DISABLED, // 193 : I2S0_MCK -> I2S0_MCK + CFG_DISABLED, // 194 : I2S2_MCK -> NC_I2S2_MCK +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/b184/properties.c b/target/b184/properties.c new file mode 100644 index 0000000..3129d11 --- /dev/null +++ b/target/b184/properties.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/b184/rules.mk b/target/b184/rules.mk new file mode 100644 index 0000000..586c37e --- /dev/null +++ b/target/b184/rules.mk @@ -0,0 +1,45 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2045=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_SPARE0_CLK_CFG=0x83000006 \ + TARGET_VID0_CLK_CFG=0x81000000 \ + TARGET_DDR_798M=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + WITH_TARGET_AMC_PARAMS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_CPU_APSC=1 \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci0/wlan0\" \ + WITH_TARGET_USB_CONFIG=1 \ + ETHERNET_DTPATH=\"arm-io/usb-complex/usb-ehci0/lan0\" + +# TODO: Wifi and BT config are almost certainly wrong here. + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/b238/include/target/aspnandconfig.h b/target/b238/include/target/aspnandconfig.h new file mode 100644 index 0000000..80dd0ed --- /dev/null +++ b/target/b238/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/b238/include/target/gpiodef.h b/target/b238/include/target/gpiodef.h new file mode 100644 index 0000000..80e10a6 --- /dev/null +++ b/target/b238/include/target/gpiodef.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* B238 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#define GPIO_BOARD_REV0 GPIO( 9, 2) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO( 9, 1) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO( 9, 0) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO( 8, 7) // 71 : GPIO[37] + +/* D2186 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(13, 3) // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + +/* which IICs to initialize */ +// for t7000/fiji IICS_COUNT is 4. +// if IICS_MASK is not defined it is set to 0xF +// iic0 - ADI PMU +// iic1 - Accel +// iic2 - Mic Codec +// iic3 - Nitrogen +#define IICS_MASK (0xF) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/b238/include/target/powerconfig.h b/target/b238/include/target/powerconfig.h new file mode 100644 index 0000000..11a2d15 --- /dev/null +++ b/target/b238/include/target/powerconfig.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// XXX: review setup for each GPIO and add back decoded description of each config +// rdar://problem/19654165 B238: IO Spreadsheet Tracker + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2186_BUCK_DWI_CTRL0, 0x07 }, // B238: Multiple panics when entering single user mode - need to enable DWI comm between PMU and bucks + { PMU_IIC_BUS, kD2186_GPIO9_CONF1, 0x93 }, // B238: GPIO17 wake on rising edge +}; + + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK5_VSEL } +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK2_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_POWER_NO_BATTERY 1 +//#define TARGET_POWER_USB_MASK STATUS_FLAG_MAKE(0, kD1815_STATUS_A_VBUS_EXT) +#define ALWAYS_BOOT_BATTERY_VOLTAGE (3000) +#define PRECHARGE_BACKLIGHT_LEVEL 103 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/b238/include/target/uartconfig.h b/target/b238/include/target/uartconfig.h new file mode 100644 index 0000000..96168f7 --- /dev/null +++ b/target/b238/include/target/uartconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/b238/init.c b/target/b238/init.c new file mode 100644 index 0000000..b1dbc84 --- /dev/null +++ b/target/b238/init.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2009-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +//#include +//#include +#include +//#include +//#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +//#include + +// Do not delay iBoot by more than this amount from power on (microseconds). +// Give up waiting for a boot logo and carry on at this point. +#define kDPDeviceStartTimeout (8 * 1000 * 1000) + +static u_int32_t b238_get_board_rev(void); +extern utime_t gPowerOnTime; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS +// dprintf(DEBUG_INFO, "%s: chip rev: %d, fuse: %d\n", __func__, +// chipid_get_chip_revision(), chipid_get_fuse_revision()); +#endif +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); + +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_debug_init(void) +{ + return 0; +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DIAGS: + break; + case BOOT_DARWIN_RESTORE: + break; + default: + // do nothing + break; + } + + return 0; +} + +bool target_should_recover(void) +{ + // trigger recovery mode whenever USB is attached, unless + // environment variable says otherwise. + + return power_has_usb() && !env_get_bool("auto-boot-usb", true); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + // always powers on + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + // never power off + return false; +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ +// u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); +// gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("idle-off", "false", 0); // do not idle off; there is no battery and this will just reboot (8035422) +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if 0 + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Update the pmu node with the actual vcore values + if (FindNode(0, "arm-io/i2c0/pmu", &node)) { + propName = "swi-vcores"; + if (FindProperty(node, &propName, &propData, &propSize)) { + platform_get_soc_voltages(propSize / sizeof(u_int32_t), propData); + } + } +#endif + return 0; +} + +#endif + + +static u_int32_t b238_get_board_rev(void) +{ + u_int32_t gpio_board_rev=0; + +#if 0 + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); +#endif + return (gpio_board_rev &0xF); +} diff --git a/target/b238/pinconfig.c b/target/b238/pinconfig.c new file mode 100644 index 0000000..a047906 --- /dev/null +++ b/target/b238/pinconfig.c @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 1v1 + I/O Spreadsheet tracker: + Conversion command: ./tools/csvtopinconfig.py --soc fiji --copyright 2015 --config-column Dir --radar '' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_OUT_0 | SLOW_SLEW, // 0 : ULPI_DIR -> LAN_PME_MODE_1V8 + CFG_DISABLED | SLOW_SLEW, // 1 : ULPI_STP -> + CFG_OUT_0 | SLOW_SLEW, // 2 : ULPI_NXT -> LAN_RESET_1V8_L + CFG_DISABLED | SLOW_SLEW, // 3 : ULPI_DATA[7] -> + CFG_IN | SLOW_SLEW, // 4 : ULPI_DATA[6] -> LAN_PHY_IRQ_1V8 + CFG_IN | SLOW_SLEW, // 5 : ULPI_DATA[5] -> LAN_PME_1V8 + CFG_IN | SLOW_SLEW, // 6 : ULPI_DATA[4] -> LAN_HSIC_DEV_RDY + CFG_DISABLED | SLOW_SLEW, // 7 : ULPI_CLK -> + +/* Port 1 */ + CFG_OUT_0 | SLOW_SLEW, // 8 : ULPI_DATA[3] -> SOC2WLB_DEVICE_WAKE_R + CFG_OUT_0 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> SOC2WLB_THROTTLE_R + CFG_IN | SLOW_SLEW, // 10 : ULPI_DATA[1] -> WLB2PMU_HOST_WAKE_R + CFG_OUT_0 | SLOW_SLEW, // 11 : ULPI_DATA[0] -> SOC2BTB_BTWAKE_R + CFG_DISABLED | SLOW_SLEW, // 12 : SPI1_SCLK -> + CFG_DISABLED | SLOW_SLEW, // 13 : SPI1_MOSI -> + CFG_DISABLED | SLOW_SLEW, // 14 : SPI1_MISO -> + CFG_DISABLED | SLOW_SLEW, // 15 : SPI1_SSIN -> + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> AP_BUTTON1_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> AP_BUTTON2_L + CFG_FUNC0 | SLOW_SLEW, // 34 : I2S3_MCK -> AP_TDM3_MCLK + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> AP_TDM3_FSYNC + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> AP_TDM3_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 37 : I2S3_DOUT -> AP_TDM3_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> AP_TDM3_DIN + CFG_DISABLED | SLOW_SLEW, // 39 : CLK32K_OUT -> + +/* Port 5 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 40 : PCIE_CLKREQ0_N -> PCIE0_WLA2SOC_CLKREQ_R_L + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> PCIE1_WLB2SOC_CLKREQ_R_L + CFG_DISABLED | SLOW_SLEW, // 42 : NAND_SYS_CLK -> + CFG_OUT_0 | SLOW_SLEW, // 43 : GPIO[0] -> SOC2WLA_DEVICE_WAKE_R + CFG_OUT_0 | SLOW_SLEW | INPUT_SCHMITT, // 44 : GPIO[1] -> SOC2WLA_THROTTLE_R + CFG_DISABLED | SLOW_SLEW, // 45 : GPIO[2] -> + CFG_DISABLED | SLOW_SLEW, // 46 : GPIO[3] -> + CFG_OUT_1 | SLOW_SLEW, // 47 : GPIO[4] -> CODEC_RESET_L + +/* Port 6 */ + CFG_OUT_1 | SLOW_SLEW, // 48 : GPIO[5] -> DEV_TUX_AUX_EN + CFG_OUT_1 | SLOW_SLEW, // 49 : GPIO[6] -> DEV_TUX_SYNC_L + CFG_OUT_0 | SLOW_SLEW, // 50 : GPIO[7] -> DEV_TUX_EN + CFG_DISABLED | SLOW_SLEW, // 51 : GPIO[14] -> + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 52 : GPIO[16] -> AP_BOARD_ID_3 + CFG_DISABLED | SLOW_SLEW, // 53 : GPIO[17] -> + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 54 : GPIO[18] -> AP_BOARD_CFG_0 + CFG_DISABLED | SLOW_SLEW | INPUT_SCHMITT, // 55 : GPIO[20] -> + +/* Port 7 */ + CFG_OUT_1 | SLOW_SLEW, // 56 : GPIO[21] -> AP_TS_RST_L + CFG_DISABLED | SLOW_SLEW | INPUT_SCHMITT, // 57 : UART5_RTXD -> + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 58 : UART8_TXD -> AP_UART8_SOC2MCU + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> AP_UART8_MCU2SOC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 60 : SPI0_SCLK -> AP_BOARD_ID_0 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 61 : SPI0_MOSI -> AP_BOARD_ID_1 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 62 : SPI0_MISO -> AP_BOARD_ID_2 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 63 : SPI0_SSIN -> + +/* Port 8 */ + CFG_FUNC0 | FAST_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> I2C2_SDA + CFG_FUNC0 | FAST_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> I2C2_SCL + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 66 : GPIO[22] -> AP_TRIG_MYSELF + CFG_OUT_1 | SLOW_SLEW | INPUT_SCHMITT, // 67 : GPIO[23] -> NITRO_MCA_BUF_EN_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> AP_BOARD_CFG_1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> AP_BOARD_CFG_2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> AP_BOARD_ID_4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> AP_BOARD_REV_3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> AP_BOARD_REV_2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> AP_BOARD_REV_1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> AP_BOARD_REV_0 + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 75 : GPIO[39] -> PCIE0_SOC2WLA_RESET_R_L + CFG_OUT_0 | SLOW_SLEW, // 76 : GPIO[42] -> AP_LED_SEL + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 77 : GPIO[43] -> PCIE1_SOC2WLB_RESET_R_L + CFG_DISABLED | SLOW_SLEW, // 78 : DISP_VSYNC -> + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 79 : UART0_TXD -> AP_UART0_SOC2USR + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> AP_UART0_USR2SOC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 81 : TMR32_PWM0 -> WLA2SOC_TIME_SYNC_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 82 : TMR32_PWM1 -> WLB2SOC_TIME_SYNC_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 83 : TMR32_PWM2 -> AP_LED_PWM + CFG_OUT_0 | SLOW_SLEW, // 84 : UART6_TXD -> PLL_S0 + CFG_OUT_0 | SLOW_SLEW, // 85 : UART6_RXD -> PLL_S1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 86 : I2C3_SDA -> I2C3_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : I2C3_SCL -> I2C3_SCL + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> I2C0_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> I2C0_SCL + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 98 : GPIO[38] -> + CFG_FUNC0 | PULL_UP | FAST_SLEW, // 99 : UART2_TXD -> AP_UART2_SOC2BTB + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 100 : UART2_RXD -> AP_UART2_BTB2SOC + CFG_FUNC0 | SLOW_SLEW, // 101 : UART2_RTSN -> AP_UART2_SOC2BTB_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 102 : UART2_CTSN -> AP_UART2_BTB2SOC_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | FAST_SLEW, // 103 : DWI_DO -> AP_DWI_DAT + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | FAST_SLEW, // 104 : DWI_CLK -> AP_DWI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 105 : WDOG -> AP_WDOG + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 106 : GPIO[13] -> PMU_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 107 : GPIO[19] -> SOC2PMU_KEEPACT + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 108 : GPIO[26] -> FORCE_DFU + CFG_OUT_0 | SLOW_SLEW, // 109 : GPIO[27] -> DFU_STATUS + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 110 : SOCHOT0 -> AP_SOCHOT0_L + CFG_FUNC0 | PULL_UP | FAST_SLEW | INPUT_SCHMITT, // 111 : SOCHOT1 -> SOC2PMU_SOCHOT1_L + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 113 : TST_CLKOUT -> + CFG_DISABLED | SLOW_SLEW, // 114 : GPIO[8] -> + CFG_DISABLED | SLOW_SLEW, // 115 : GPIO[9] -> + CFG_DISABLED | SLOW_SLEW, // 116 : GPIO[10] -> + CFG_DISABLED | SLOW_SLEW, // 117 : GPIO[15] -> + CFG_FUNC0 | PULL_UP | FAST_SLEW, // 118 : UART4_TXD -> AP_UART4_SOC2WLB + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> AP_UART4_WLB2SOC + +/* Port 15 */ + CFG_FUNC0 | SLOW_SLEW, // 120 : UART4_RTSN -> AP_UART4_SOC2WLB_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> AP_UART4_WLB2SOC_CTS_L + CFG_DISABLED | SLOW_SLEW, // 122 : SPI3_MOSI -> + CFG_DISABLED | SLOW_SLEW, // 123 : SPI3_MISO -> + CFG_DISABLED | SLOW_SLEW, // 124 : SPI3_SCLK -> + CFG_DISABLED | SLOW_SLEW, // 125 : SPI3_SSIN -> + CFG_DISABLED | SLOW_SLEW, // 126 : GPIO[24] -> + CFG_DISABLED | SLOW_SLEW, // 127 : GPIO[30] -> + +/* Port 16 */ + CFG_DISABLED | SLOW_SLEW, // 128 : GPIO[31] -> + CFG_DISABLED | SLOW_SLEW, // 129 : GPIO[32] -> + CFG_DISABLED | SLOW_SLEW, // 130 : GPIO[33] -> + CFG_DISABLED | SLOW_SLEW, // 131 : GPIO[40] -> + CFG_DISABLED | SLOW_SLEW, // 132 : GPIO[41] -> + CFG_FUNC0 | SLOW_SLEW, // 133 : I2S4_MCK -> AP_I2S4_MCLK + CFG_FUNC0 | SLOW_SLEW, // 134 : I2S4_LRCK -> AP_I2S4_LRCLK + CFG_FUNC0 | SLOW_SLEW, // 135 : I2S4_BCLK -> AP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_I2S4_DOUT + CFG_FUNC0 | SLOW_SLEW, // 137 : I2S4_DIN -> AP_I2S4_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2C1_SDA -> I2C1_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2C1_SCL -> I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | SLOW_SLEW, // 160 : I2S0_LRCK -> AP_TDM0_FSYNC + CFG_FUNC0 | SLOW_SLEW, // 161 : I2S0_BCLK -> AP_TDM0_BCLK + CFG_FUNC0 | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TDM0_DOUT + CFG_FUNC0 | SLOW_SLEW, // 163 : I2S0_DIN -> AP_TDM0_DIN + CFG_FUNC0 | SLOW_SLEW, // 164 : I2S1_MCK -> AP_TDM1_MCLK + CFG_FUNC0 | SLOW_SLEW, // 165 : I2S1_LRCK -> AP_TDM1_FSYNC + CFG_FUNC0 | SLOW_SLEW, // 166 : I2S1_BCLK -> AP_TDM1_BCLK + CFG_FUNC0 | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TDM1_DOUT + +/* Port 21 */ + CFG_FUNC0 | SLOW_SLEW, // 168 : I2S1_DIN -> AP_TDM1_DIN + CFG_FUNC0 | SLOW_SLEW, // 169 : I2S2_LRCK -> AP_TDM2_FSYNC + CFG_FUNC0 | SLOW_SLEW, // 170 : I2S2_BCLK -> AP_TDM2_BCLK + CFG_FUNC0 | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TDM2_DOUT + CFG_FUNC0 | SLOW_SLEW, // 172 : I2S2_DIN -> AP_TDM2_DIN + CFG_FUNC0 | PULL_UP | FAST_SLEW, // 173 : UART1_TXD -> AP_UART1_SOC2BTA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> AP_UART1_BTA2SOC + CFG_FUNC0 | SLOW_SLEW, // 175 : UART1_RTSN -> AP_UART1_SOC2BTA_RTS_L + +/* Port 22 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 176 : UART1_CTSN -> AP_UART1_BTA2SOC_CTS_L + CFG_DISABLED | SLOW_SLEW, // 177 : EDP_HPD -> + CFG_FUNC0 | PULL_UP | FAST_SLEW, // 178 : UART3_TXD -> AP_UART3_SOC2WLA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 179 : UART3_RXD -> AP_UART3_WLA2SOC + CFG_FUNC0 | SLOW_SLEW, // 180 : UART3_RTSN -> AP_UART3_SOC2WLA_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 181 : UART3_CTSN -> AP_UART3_WLA2SOC_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 182 : SPI2_SCLK -> MCU_SPI2_SCLK + CFG_FUNC0 | SLOW_SLEW, // 183 : SPI2_MOSI -> MCU_SPI2_MOSI + +/* Port 23 */ + CFG_FUNC0 | SLOW_SLEW, // 184 : SPI2_MISO -> MCU_SPI2_MISO + CFG_FUNC0 | SLOW_SLEW, // 185 : SPI2_SSIN -> MCU_SPI2_CS_L + CFG_DISABLED | SLOW_SLEW, // 186 : ISP0_SDA -> + CFG_DISABLED | SLOW_SLEW, // 187 : ISP0_SCL -> + CFG_DISABLED | SLOW_SLEW, // 188 : ISP1_SDA -> + CFG_DISABLED | SLOW_SLEW, // 189 : ISP1_SCL -> + CFG_DISABLED | SLOW_SLEW, // 190 : SENSOR0_RST -> + CFG_DISABLED | SLOW_SLEW, // 191 : SENSOR0_CLK -> + +/* Port 24 */ + CFG_DISABLED | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> + CFG_DISABLED | SLOW_SLEW, // 194 : ISP_UART0_TXD -> + CFG_DISABLED | SLOW_SLEW, // 195 : ISP_UART0_RXD -> + CFG_DISABLED | SLOW_SLEW, // 196 : SENSOR1_RST -> + CFG_DISABLED | SLOW_SLEW, // 197 : SENSOR1_CLK -> + CFG_DISABLED | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_OUT_0 | FAST_SLEW, // 200 : UART7_TXD -> SOC2BTA_BTWAKE_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 201 : UART7_RXD -> WLA2PMU_HOST_WAKE_R + CFG_FUNC0 | FAST_SLEW, // 202 : I2S0_MCK -> AP_TDM0_MCLK + CFG_FUNC0 | FAST_SLEW, // 203 : I2S2_MCK -> AP_TDM2_MCLK + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_OUT_0 | SLOW_SLEW, // 0 : ULPI_DIR -> LAN_PME_MODE_1V8 + CFG_DISABLED | SLOW_SLEW, // 1 : ULPI_STP -> + CFG_OUT_0 | SLOW_SLEW, // 2 : ULPI_NXT -> LAN_RESET_1V8_L + CFG_DISABLED | SLOW_SLEW, // 3 : ULPI_DATA[7] -> + CFG_IN | SLOW_SLEW, // 4 : ULPI_DATA[6] -> LAN_PHY_IRQ_1V8 + CFG_IN | SLOW_SLEW, // 5 : ULPI_DATA[5] -> LAN_PME_1V8 + CFG_IN | SLOW_SLEW, // 6 : ULPI_DATA[4] -> LAN_HSIC_DEV_RDY + CFG_DISABLED | SLOW_SLEW, // 7 : ULPI_CLK -> + +/* Port 1 */ + CFG_OUT_0 | SLOW_SLEW, // 8 : ULPI_DATA[3] -> SOC2WLB_DEVICE_WAKE_R + CFG_OUT_0 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> SOC2WLB_THROTTLE_R + CFG_IN | SLOW_SLEW, // 10 : ULPI_DATA[1] -> WLB2PMU_HOST_WAKE_R + CFG_OUT_0 | SLOW_SLEW, // 11 : ULPI_DATA[0] -> SOC2BTB_BTWAKE_R + CFG_DISABLED | SLOW_SLEW, // 12 : SPI1_SCLK -> + CFG_DISABLED | SLOW_SLEW, // 13 : SPI1_MOSI -> + CFG_DISABLED | SLOW_SLEW, // 14 : SPI1_MISO -> + CFG_DISABLED | SLOW_SLEW, // 15 : SPI1_SSIN -> + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> AP_BUTTON1_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> AP_BUTTON2_L + CFG_FUNC0 | SLOW_SLEW, // 34 : I2S3_MCK -> AP_TDM3_MCLK + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> AP_TDM3_FSYNC + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> AP_TDM3_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 37 : I2S3_DOUT -> AP_TDM3_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> AP_TDM3_DIN + CFG_DISABLED | SLOW_SLEW, // 39 : CLK32K_OUT -> + +/* Port 5 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 40 : PCIE_CLKREQ0_N -> PCIE0_WLA2SOC_CLKREQ_R_L + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> PCIE1_WLB2SOC_CLKREQ_R_L + CFG_DISABLED | SLOW_SLEW, // 42 : NAND_SYS_CLK -> + CFG_OUT_0 | SLOW_SLEW, // 43 : GPIO[0] -> SOC2WLA_DEVICE_WAKE_R + CFG_OUT_0 | SLOW_SLEW | INPUT_SCHMITT, // 44 : GPIO[1] -> SOC2WLA_THROTTLE_R + CFG_DISABLED | SLOW_SLEW, // 45 : GPIO[2] -> + CFG_DISABLED | SLOW_SLEW, // 46 : GPIO[3] -> + CFG_OUT_1 | SLOW_SLEW, // 47 : GPIO[4] -> CODEC_RESET_L + +/* Port 6 */ + CFG_OUT_1 | SLOW_SLEW, // 48 : GPIO[5] -> DEV_TUX_AUX_EN + CFG_OUT_1 | SLOW_SLEW, // 49 : GPIO[6] -> DEV_TUX_SYNC_L + CFG_OUT_0 | SLOW_SLEW, // 50 : GPIO[7] -> DEV_TUX_EN + CFG_DISABLED | SLOW_SLEW, // 51 : GPIO[14] -> + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 52 : GPIO[16] -> AP_BOARD_ID_3 + CFG_DISABLED | SLOW_SLEW, // 53 : GPIO[17] -> + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 54 : GPIO[18] -> AP_BOARD_CFG_0 + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 55 : GPIO[20] -> + +/* Port 7 */ + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 56 : GPIO[21] -> AP_TS_RST_L + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 57 : UART5_RTXD -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 58 : UART8_TXD -> AP_UART8_SOC2MCU + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> AP_UART8_MCU2SOC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 60 : SPI0_SCLK -> AP_BOARD_ID_0 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 61 : SPI0_MOSI -> AP_BOARD_ID_1 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 62 : SPI0_MISO -> AP_BOARD_ID_2 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 63 : SPI0_SSIN -> + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> I2C2_SDA + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> I2C2_SCL + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 66 : GPIO[22] -> AP_TRIG_MYSELF + CFG_OUT_1 | SLOW_SLEW | INPUT_SCHMITT, // 67 : GPIO[23] -> NITRO_MCA_BUF_EN_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> AP_BOARD_CFG_1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> AP_BOARD_CFG_2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> AP_BOARD_ID_4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> AP_BOARD_REV_3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> AP_BOARD_REV_2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> AP_BOARD_REV_1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> AP_BOARD_REV_0 + CFG_IN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 75 : GPIO[39] -> PCIE0_SOC2WLA_RESET_R_L + CFG_OUT_0 | SLOW_SLEW, // 76 : GPIO[42] -> AP_LED_SEL + CFG_IN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 77 : GPIO[43] -> PCIE1_SOC2WLB_RESET_R_L + CFG_DISABLED | SLOW_SLEW, // 78 : DISP_VSYNC -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 79 : UART0_TXD -> AP_UART0_SOC2USR + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> AP_UART0_USR2SOC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 81 : TMR32_PWM0 -> WLA2SOC_TIME_SYNC_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 82 : TMR32_PWM1 -> WLB2SOC_TIME_SYNC_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : TMR32_PWM2 -> AP_LED_PWM + CFG_OUT_0 | SLOW_SLEW, // 84 : UART6_TXD -> PLL_S0 + CFG_OUT_0 | SLOW_SLEW, // 85 : UART6_RXD -> PLL_S1 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 86 : I2C3_SDA -> I2C3_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 87 : I2C3_SCL -> I2C3_SCL + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> I2C0_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> I2C0_SCL + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 98 : GPIO[38] -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | FAST_SLEW, // 99 : UART2_TXD -> AP_UART2_SOC2BTB + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 100 : UART2_RXD -> AP_UART2_BTB2SOC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 101 : UART2_RTSN -> AP_UART2_SOC2BTB_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 102 : UART2_CTSN -> AP_UART2_BTB2SOC_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | FAST_SLEW, // 103 : DWI_DO -> AP_DWI_DAT + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | FAST_SLEW, // 104 : DWI_CLK -> AP_DWI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 105 : WDOG -> AP_WDOG + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 106 : GPIO[13] -> PMU_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 107 : GPIO[19] -> SOC2PMU_KEEPACT + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 108 : GPIO[26] -> FORCE_DFU + CFG_OUT_0 | SLOW_SLEW, // 109 : GPIO[27] -> DFU_STATUS + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 110 : SOCHOT0 -> AP_SOCHOT0_L + CFG_FUNC0 | PULL_UP | DRIVE_X4 | FAST_SLEW | INPUT_SCHMITT, // 111 : SOCHOT1 -> SOC2PMU_SOCHOT1_L + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 113 : TST_CLKOUT -> + CFG_DISABLED | SLOW_SLEW, // 114 : GPIO[8] -> + CFG_DISABLED | SLOW_SLEW, // 115 : GPIO[9] -> + CFG_DISABLED | SLOW_SLEW, // 116 : GPIO[10] -> + CFG_DISABLED | SLOW_SLEW, // 117 : GPIO[15] -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | FAST_SLEW, // 118 : UART4_TXD -> AP_UART4_SOC2WLB + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> AP_UART4_WLB2SOC + +/* Port 15 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 120 : UART4_RTSN -> AP_UART4_SOC2WLB_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> AP_UART4_WLB2SOC_CTS_L + CFG_DISABLED | SLOW_SLEW, // 122 : SPI3_MOSI -> + CFG_DISABLED | SLOW_SLEW, // 123 : SPI3_MISO -> + CFG_DISABLED | SLOW_SLEW, // 124 : SPI3_SCLK -> + CFG_DISABLED | SLOW_SLEW, // 125 : SPI3_SSIN -> + CFG_DISABLED | SLOW_SLEW, // 126 : GPIO[24] -> + CFG_DISABLED | SLOW_SLEW, // 127 : GPIO[30] -> + +/* Port 16 */ + CFG_DISABLED | SLOW_SLEW, // 128 : GPIO[31] -> + CFG_DISABLED | SLOW_SLEW, // 129 : GPIO[32] -> + CFG_DISABLED | SLOW_SLEW, // 130 : GPIO[33] -> + CFG_DISABLED | SLOW_SLEW, // 131 : GPIO[40] -> + CFG_DISABLED | SLOW_SLEW, // 132 : GPIO[41] -> + CFG_FUNC0 | SLOW_SLEW, // 133 : I2S4_MCK -> AP_I2S4_MCLK + CFG_FUNC0 | SLOW_SLEW, // 134 : I2S4_LRCK -> AP_I2S4_LRCLK + CFG_FUNC0 | SLOW_SLEW, // 135 : I2S4_BCLK -> AP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_I2S4_DOUT + CFG_FUNC0 | SLOW_SLEW, // 137 : I2S4_DIN -> AP_I2S4_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 138 : I2C1_SDA -> I2C1_SDA + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 139 : I2C1_SCL -> I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | SLOW_SLEW, // 160 : I2S0_LRCK -> AP_TDM0_FSYNC + CFG_FUNC0 | SLOW_SLEW, // 161 : I2S0_BCLK -> AP_TDM0_BCLK + CFG_FUNC0 | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TDM0_DOUT + CFG_FUNC0 | SLOW_SLEW, // 163 : I2S0_DIN -> AP_TDM0_DIN + CFG_FUNC0 | SLOW_SLEW, // 164 : I2S1_MCK -> AP_TDM1_MCLK + CFG_FUNC0 | SLOW_SLEW, // 165 : I2S1_LRCK -> AP_TDM1_FSYNC + CFG_FUNC0 | SLOW_SLEW, // 166 : I2S1_BCLK -> AP_TDM1_BCLK + CFG_FUNC0 | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TDM1_DOUT + +/* Port 21 */ + CFG_FUNC0 | SLOW_SLEW, // 168 : I2S1_DIN -> AP_TDM1_DIN + CFG_FUNC0 | SLOW_SLEW, // 169 : I2S2_LRCK -> AP_TDM2_FSYNC + CFG_FUNC0 | SLOW_SLEW, // 170 : I2S2_BCLK -> AP_TDM2_BCLK + CFG_FUNC0 | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TDM2_DOUT + CFG_FUNC0 | SLOW_SLEW, // 172 : I2S2_DIN -> AP_TDM2_DIN + CFG_FUNC0 | PULL_UP | DRIVE_X4 | FAST_SLEW, // 173 : UART1_TXD -> AP_UART1_SOC2BTA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> AP_UART1_BTA2SOC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 175 : UART1_RTSN -> AP_UART1_SOC2BTA_RTS_L + +/* Port 22 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 176 : UART1_CTSN -> AP_UART1_BTA2SOC_CTS_L + CFG_DISABLED | SLOW_SLEW, // 177 : EDP_HPD -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | FAST_SLEW, // 178 : UART3_TXD -> AP_UART3_SOC2WLA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 179 : UART3_RXD -> AP_UART3_WLA2SOC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 180 : UART3_RTSN -> AP_UART3_SOC2WLA_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 181 : UART3_CTSN -> AP_UART3_WLA2SOC_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 182 : SPI2_SCLK -> MCU_SPI2_SCLK + CFG_FUNC0 | SLOW_SLEW, // 183 : SPI2_MOSI -> MCU_SPI2_MOSI + +/* Port 23 */ + CFG_FUNC0 | SLOW_SLEW, // 184 : SPI2_MISO -> MCU_SPI2_MISO + CFG_FUNC0 | SLOW_SLEW, // 185 : SPI2_SSIN -> MCU_SPI2_CS_L + CFG_DISABLED | SLOW_SLEW, // 186 : ISP0_SDA -> + CFG_DISABLED | SLOW_SLEW, // 187 : ISP0_SCL -> + CFG_DISABLED | SLOW_SLEW, // 188 : ISP1_SDA -> + CFG_DISABLED | SLOW_SLEW, // 189 : ISP1_SCL -> + CFG_DISABLED | SLOW_SLEW, // 190 : SENSOR0_RST -> + CFG_DISABLED | SLOW_SLEW, // 191 : SENSOR0_CLK -> + +/* Port 24 */ + CFG_DISABLED | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> + CFG_DISABLED | SLOW_SLEW, // 194 : ISP_UART0_TXD -> + CFG_DISABLED | SLOW_SLEW, // 195 : ISP_UART0_RXD -> + CFG_DISABLED | SLOW_SLEW, // 196 : SENSOR1_RST -> + CFG_DISABLED | SLOW_SLEW, // 197 : SENSOR1_CLK -> + CFG_DISABLED | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 200 : UART7_TXD -> SOC2BTA_BTWAKE_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 201 : UART7_RXD -> WLA2PMU_HOST_WAKE_R + CFG_FUNC0 | FAST_SLEW, // 202 : I2S0_MCK -> AP_TDM0_MCLK + CFG_FUNC0 | FAST_SLEW, // 203 : I2S2_MCK -> AP_TDM2_MCLK + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0 } }, + { 1, 1, { pinconfig_dev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/b238/rules.mk b/target/b238/rules.mk new file mode 100644 index 0000000..0bfcf62 --- /dev/null +++ b/target/b238/rules.mk @@ -0,0 +1,36 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2186=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + WIFI_DTPATH=\"arm-io/uart3/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + TARGET_HS_2_LP_DATA_TIME=24 \ + TARGET_LP_2_HS_DATA_TIME=63 \ + TARGET_HS_2_LP_CLOCK_TIME=36 \ + TARGET_LP_2_HS_CLOCK_TIME=79 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o $(LOCAL_DIR)/pinconfig.o diff --git a/target/capriref/include/target/adbe_settings.h b/target/capriref/include/target/adbe_settings.h new file mode 100644 index 0000000..9ed18c9 --- /dev/null +++ b/target/capriref/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_PMGR_CLK_GATE_ENABLE | DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/capriref/include/target/amcconfig.h b/target/capriref/include/target/amcconfig.h new file mode 100644 index 0000000..b786f10 --- /dev/null +++ b/target/capriref/include/target/amcconfig.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amc/amc.h, and this + * file should only by included from amc.c. + */ + +static const struct amc_param amc_params = { + .lat = 0x00040200, + .phyrdwrtim = 0x00010802, + .tREFi = 0x11, + .pdn = 0x22000203, + .derate = 0x04110111, + .read = 0x00000101, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000001, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x84, + .mr2 = 0x06, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050020, + .mcuchnhash = 0x0ffffd54, + .mcuchnhash2 = 0x0aaaaaa8, + .mcschnldec = 0x00020200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000501, + + .freq = { + { // 800MHz + .cas = 0x00000203, + .pch = 0x00020303, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002030, + .modereg = 0x20010732, + }, + { // 400MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + }, + { // 50MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQCTL1, 0x00000336 }, + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, + { &rAMC_PWRMNGTPARAM, 0x03521000 }, +}; diff --git a/target/capriref/include/target/ampconfig.h b/target/capriref/include/target/ampconfig.h new file mode 100644 index 0000000..7a90673 --- /dev/null +++ b/target/capriref/include/target/ampconfig.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_phy_params struct is defined in drivers/apple/amp_v3/amp_v3.h, and this + * file should only by included from amp_v3.c. + */ + +static const struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x01010304, + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x21010309, + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x41010306, + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61010304, + }, + }, +}; diff --git a/target/capriref/include/target/aspnandconfig.h b/target/capriref/include/target/aspnandconfig.h new file mode 100644 index 0000000..99d4bfd --- /dev/null +++ b/target/capriref/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 8 +#define ASPNAND_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/capriref/include/target/gpiodef.h b/target/capriref/include/target/gpiodef.h new file mode 100644 index 0000000..dfc47c6 --- /dev/null +++ b/target/capriref/include/target/gpiodef.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* CapriRef specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 20, 1) // 161 : ULPI_NXT +#define GPIO_BOARD_REV1 GPIO( 19, 7) // 159 : ULPI_DIR +#define GPIO_BOARD_REV2 GPIO( 21, 0) // 168 : ULPI_DATA[2] +#define GPIO_BOARD_REV3 GPIO( 20, 3) // 163 : ULPI_DATA[6] + +/* D2207 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO( 10, 7) // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/capriref/include/target/powerconfig.h b/target/capriref/include/target/powerconfig.h new file mode 100644 index 0000000..fcfcfd0 --- /dev/null +++ b/target/capriref/include/target/powerconfig.h @@ -0,0 +1,97 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2207_HIBERNATE3, 0x90 }, // enable LDO7+LDO4 in hibernate +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* J82 IO Spreadsheet */ +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO5, 0x09}, // PMU_GPIO_PMU2BBPMU_RST_L Out 0, Push-Pull, VBUCK3 +#else + { PMU_IIC_BUS, kD2207_GPIO5, 0xB9}, // PMU_GPIO_PMU2BBPMU_RST_L In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO6, 0xDA}, // UART5_BATT_TRXD In, F Edge, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO7, 0xBA}, // PMU_GPIO_BT_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO8, 0xBA}, // PMU_GPIO_WLAN_HOST_WAKE In, R Edge, Wake, PD +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO9, 0xBA}, // PMU_GPIO_BB2PMU_HOST_WAKE In, R Edge, Wake, PU, VBUCK3 +#else + { PMU_IIC_BUS, kD2207_GPIO9, 0xB9}, // PMU_GPIO_BB2PMU_HOST_WAKE In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO10, 0xCA}, // PMU_GPIO_CODEC_HS_INT_L In, F Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD2207_GPIO11, 0xFA}, // PMU_GPIO_MB_HALL1_IRQ In, Any Edge, Wake, No PU + { PMU_IIC_BUS, kD2207_GPIO12, 0x7B}, // GPIO_TS2SOC2PMU_INT In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO14, 0xB8}, // PMU_GPIO_WLAN2PMU_PCIE_WAKE_L In, R Edge, PU + { PMU_IIC_BUS, kD2207_GPIO16, 0x7B}, // PMU_GPIO_OSCAR2PMU_HOST_WAKE In, Hi level, Wake, PD + + { PMU_IIC_BUS, kD2207_BUCK_DWI_CTRL0, 0x07 }, // enable DWI for BUCK0, BUCK1, BUCK2 +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_OPTIONS, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/capriref/include/target/uartconfig.h b/target/capriref/include/target/uartconfig.h new file mode 100644 index 0000000..09ae44b --- /dev/null +++ b/target/capriref/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/capriref/init.c b/target/capriref/init.c new file mode 100644 index 0000000..5d821d5 --- /dev/null +++ b/target/capriref/init.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = false; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +#if WITH_ENV +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("wifiaddr", "7E:77:77:77:77:77", 0); +} +#endif + +#if WITH_DEVICETREE +int target_update_device_tree(void) +{ + return 0; +} +#endif // WITH_DEVICETREE diff --git a/target/capriref/pinconfig.c b/target/capriref/pinconfig.c new file mode 100644 index 0000000..2389fa6 --- /dev/null +++ b/target/capriref/pinconfig.c @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* FIXME: just pulled these direction from ipad5b, may need to update */ + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.2 + I/O Spreadsheet tracker: J82 IO Spreadsheet +*/ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2OSLO_EN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2OSLO_DWLD_REQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BT2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BT2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_GRAPE_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_GRAPE_SCLK_R + CFG_OUT_1, // 51 : SPI3_SSIN -> SPI_GRAPE_CS_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_DISABLED, // 53 : TMR32_PWM1 -> GPIO_SOC2GRAPE_HV_BOOST_EN + CFG_DISABLED, // 54 : TMR32_PWM2 -> JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_DISABLED, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_DISABLED, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_DISABLED, // 63 : UART7_TXD -> GPIO_TT2SOC_SMI_L + +/* Port 8 */ + CFG_DISABLED, // 64 : UART7_RXD -> GPIO_TT2SOC_WAKE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_DISABLED, // 70 : SPI0_SSIN -> JTAG_BB_TMS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2OSLO_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_OSLO2SOC_TX + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2OSLO_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_OSLO2SOC_RTS_L + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_DISABLED, // 81 : GPIO[1] -> GPIO_SOC2TT_PWR_SW_EN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN | PULL_UP, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_DISABLED, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_SW_EN + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[8] -> GPIO_GANGES2SOC_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_ALS2SOC_DEVBRD_IRQ_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2SPKRAMP_RESET_L + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_DISABLED, // 94 : GPIO[14] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_DISABLED, // 99 : GPIO[19] -> GPIO_SOC2TT_POR_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> NC_BOARD_ID4 + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_BTN_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2OSCAR_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_OSCAR2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BB2SOC_TX + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BB2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_DISABLED, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_DISABLED, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + +/* Port 19 */ + CFG_DISABLED, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_DISABLED, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_CODEC_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 156 : SPI1_MISO -> SPI_CODEC_MISO + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_CODEC_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_32K + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_DISABLED, // 160 : ULPI_STP -> GPIO_SOC2DEVBRD_S3E_WAKE + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_DISABLED, // 167 : ULPI_DATA[3] -> GPIO_SOC2DEVBRD_S3E_RESET2_L + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_DISABLED, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_DISABLED, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED, // 175 : PCIE_CLKREQ2_N -> PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> CLK_SOC2DEVBRD_PCIE_24MHZ + CFG_DISABLED, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> NC_PERST3 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_DISABLED, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/capriref/rules.mk b/target/capriref/rules.mk new file mode 100644 index 0000000..fcc80e9 --- /dev/null +++ b/target/capriref/rules.mk @@ -0,0 +1,32 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2207=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_DDR_798M=1 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + AMC_NUM_CHANNELS=4 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_GPU=2 \ + BUCK_RAM=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/cyclonic/include/target/adbe_settings.h b/target/cyclonic/include/target/adbe_settings.h new file mode 100644 index 0000000..3c15c04 --- /dev/null +++ b/target/cyclonic/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_AFC_TEARDOWN_ENABLE | DBEMODECNTL_PMGR_CLK_GATE_ENABL| DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/cyclonic/include/target/amcconfig.h b/target/cyclonic/include/target/amcconfig.h new file mode 100644 index 0000000..49b7085 --- /dev/null +++ b/target/cyclonic/include/target/amcconfig.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amc/amc.h, and this + * file should only by included from amc.c. + */ + +#define AMC_PARAMS_AP_DEV (1) + +static const struct amc_param amc_params_dev = { + .flags = (FLAG_AMC_PARAM_BUSTAT23), + + .tREFi = 0x11, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00020000, + .rdlat = 4, + .wrlat = 2, + .phyrdlat = 10, + .phywrlat = 1, + .pdn = 0x22000203, + .read = 0x00000101, + .bustat = 0x0022221b, + .bustat2 = 0x0022221b, + .derate = 0x04110111, + .mcphyupdate = 0x05030000, + .autoref_params = 0x00000021, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00050000, + .arefparam = 0x0c00a000, + .aref_freq0 = 0x00000110, + .schen_default = 0x00000110, + .mr1 = 0x44, + .mr2 = 0x1a, + .pwrmngten_default = 0x00100000, + + .freq = { + { // 522MHz + .cas = 0x00000203, + .pch = 0x00020303, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002030, + .modereg = 0x00010772, + .mifcassch = 0x001f0110, + }, + { // 400MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + .mifcassch = 0x00000000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + .mifcassch = 0x00000000, + }, + { // 50 & 24MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + .mifcassch = 0x00000000, + } + } +}; + +static const struct amc_param amc_params_ap = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00020000, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 10, + .phywrlat = 2, + .pdn = 0x22000403, + .read = 0x00000203, + .bustat = 0x0022221b, + .bustat2 = 0x0022221b, + .derate = 0x2483135b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x00000021, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00050000, + .arefparam = 0x0c00a000, + .aref_freq0 = 0x00000110, + .schen_default = 0x00000110, + .mr1 = 0x44, + .mr2 = 0x1a, + .pwrmngten_default = 0x00100000, + + .freq = { + { // 522MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x14040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x40250772, + .mifcassch = 0x001f0110, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x0a020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + .mifcassch = 0x00000000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + .mifcassch = 0x00000000, + }, + { // 50 + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + .mifcassch = 0x00000000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { 0, 0 } +}; diff --git a/target/cyclonic/include/target/ampconfig.h b/target/cyclonic/include/target/ampconfig.h new file mode 100644 index 0000000..e464e37 --- /dev/null +++ b/target/cyclonic/include/target/ampconfig.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amp/amp.h, and this + * file should only by included from that amp.c. + */ + +static struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x0002040a + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x20020308 + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x40020308 + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x60020308 + } + } +}; diff --git a/target/cyclonic/include/target/aspnandconfig.h b/target/cyclonic/include/target/aspnandconfig.h new file mode 100644 index 0000000..18774a9 --- /dev/null +++ b/target/cyclonic/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/cyclonic/include/target/gpiodef.h b/target/cyclonic/include/target/gpiodef.h new file mode 100644 index 0000000..a9b914d --- /dev/null +++ b/target/cyclonic/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* Cyclonic specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/cyclonic/include/target/nand_spec_tables.h b/target/cyclonic/include/target/nand_spec_tables.h new file mode 100644 index 0000000..029be11 --- /dev/null +++ b/target/cyclonic/include/target/nand_spec_tables.h @@ -0,0 +1,153 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* blocksPerCS */ 4100, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_TOSHIBA_MLC, + /* diesPerCS */ 1 + } +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + } +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Toshiba" + } +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ + { + /* packageId */ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + }, + /* appleName */ "335S0700", + /* vendor_part_num */ "TH58NVG6D2FLA49", + /* package_type */ "DDP", + /* package_size */ "1.00mm LGA" + } +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + } +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000303 + }, + + /* useToggleMode */ 0, + /* useDiffDQSMode */ 0, + /* useDiffREMode */ 0, + /* useVref */ 0 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 0 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/cyclonic/include/target/powerconfig.h b/target/cyclonic/include/target/powerconfig.h new file mode 100644 index 0000000..e258978 --- /dev/null +++ b/target/cyclonic/include/target/powerconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +// Minimal definitions to make lib/power.c happy +#define TARGET_POWER_NO_BATTERY 1 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (5000) + +// This fake SoC block takes the place of the external PMU in Fastsim +#define SWIFTER_PMU_BASE 0x20F050000 + +#endif diff --git a/target/cyclonic/include/target/uartconfig.h b/target/cyclonic/include/target/uartconfig.h new file mode 100644 index 0000000..8dbadc2 --- /dev/null +++ b/target/cyclonic/include/target/uartconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#endif diff --git a/target/cyclonic/init.c b/target/cyclonic/init.c new file mode 100644 index 0000000..241d306 --- /dev/null +++ b/target/cyclonic/init.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +uint32_t display_config; + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +void * target_get_display_configuration(void) +{ + + display_config = 0x00000da2; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", "debug=0x14e serial=3 amfi=0x83 cs_enforcement_disable=1 fips_mode=0 -disable_aslr", ENV_PERSISTENT); + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "n51", 0); + env_set("idle-off", "false", 0); + env_set("kaslr-slide", "0x10000000", 0); + env_set("wifiaddr", "12:22:33:44:55:66", 0); + env_set("ethaddr", "12:22:33:44:55:77", 0); + env_set("btaddr", "00:00:00:00:00:00", 0); +} + +#endif + +#if WITH_DEVICETREE + +#define ROOT_DTPATH "" +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Overwrite the serial-number with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "serial-number property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *serial = (uint64_t *)propData; + serial[0] = *(volatile uint64_t *)0x20f050040; + serial[1] = *(volatile uint64_t *)0x20f050048; + serial[2] = *(volatile uint64_t *)0x20f050050; + serial[3] = *(volatile uint64_t *)0x20f050058; + } + } + + // Overwrite the region-info with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "region-info"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "region-info property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *region = (uint64_t *)propData; + region[0] = *(volatile uint64_t *)0x20f050060; + region[1] = *(volatile uint64_t *)0x20f050068; + region[2] = *(volatile uint64_t *)0x20f050070; + region[3] = *(volatile uint64_t *)0x20f050078; + } + } + + return 0; +} + +#endif + + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/cyclonic/pinconfig.c b/target/cyclonic/pinconfig.c new file mode 100644 index 0000000..53c690e --- /dev/null +++ b/target/cyclonic/pinconfig.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* Pin configuration for FPGA */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // WDOG -> + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + +/* Port 1 */ + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + +/* Port 2 */ + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + +/* Port 5 */ + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RXD -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 6 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 7 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 8 */ + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 9 */ + CFG_FUNC0, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_FUNC0, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_FUNC0, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1, // SPI0_SSIN -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + +/* Port 10 */ + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + +/* Port 11 */ + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + +/* Port 12 */ + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 13 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN, // GPIO26 -> FORCE_DFU + CFG_DISABLED, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + +/* Port 14 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // GPIO39 -> + +/* Port 15 */ + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + CFG_FUNC0, // UART0_TXD -> + CFG_FUNC0, // UART0_RXD -> + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_D0 -> + CFG_DISABLED, // DWI_CLK -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + +/* Port 17 */ + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + +/* Port 18 */ + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 19 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 20 */ + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // SIO_7816UART0_SDA -> + CFG_DISABLED, // SIO_7816UART0_SCL -> + CFG_DISABLED, // SIO_7816UART0_RST -> + CFG_DISABLED, // SIO_7816UART1_SDA -> + CFG_DISABLED, // SIO_7816UART1_SCL -> + +/* Port 21 */ + CFG_DISABLED, // SIO_7816UART0_RST -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 22 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 23 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 24 */ + CFG_DISABLED, // EPD_HPD -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/cyclonic/rules.mk b/target/cyclonic/rules.mk new file mode 100644 index 0000000..93724bd --- /dev/null +++ b/target/cyclonic/rules.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_VID0_CLK_CFG=0x86100000 \ + DISPLAY_IPHONE_TUNABLES=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMP_CALIBRATION_SKIP=1 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_TARGET_AMC_PARAMS=1 \ + WITH_TARGET_AMP_PARAMS=1 \ + WIFI_DTPATH=\"arm-io/wlan\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/e86/include/target/adbe_settings.h b/target/e86/include/target/adbe_settings.h new file mode 100644 index 0000000..a7cf569 --- /dev/null +++ b/target/e86/include/target/adbe_settings.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = +{ + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x000e, + .adbe0_vblank_clk_gate_wakeup = 0x000e, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/e86/include/target/aspnandconfig.h b/target/e86/include/target/aspnandconfig.h new file mode 100644 index 0000000..e6ec918 --- /dev/null +++ b/target/e86/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/e86/include/target/gpiodef.h b/target/e86/include/target/gpiodef.h new file mode 100644 index 0000000..b33714c --- /dev/null +++ b/target/e86/include/target/gpiodef.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iphone7,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 9, 2) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO( 9, 1) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO( 9, 0) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO( 8, 7) // 71 : GPIO[37] + +/* Display reset */ +#define GPIO_LCD_RST GPIO(0, 1) // 1 : ULPI_STP -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + +/* D2186 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(13, 3) // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + +/* which IICs to initialize */ +#define IICS_MASK (1) + +#define TRISTAR_IIC_BUS (0) +#define DISPLAY_PMU_IIC_BUS (0) + +#define POWER_GPIO_HVR_RESET_L (5) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/e86/include/target/powerconfig.h b/target/e86/include/target/powerconfig.h new file mode 100644 index 0000000..0486c89 --- /dev/null +++ b/target/e86/include/target/powerconfig.h @@ -0,0 +1,115 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2186_ACTIVE3, 0xAE }, // Current OTP enables LDO{1,2,3,4,5,7}, disable LDO4. + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x37 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1, BUCK4_SW2 + { PMU_IIC_BUS, kD2186_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + + { PMU_IIC_BUS, kD2186_BUCK1_VSEL, 0x80 }, // rdar://14689066 TODO: remove when not necessary + + { PMU_IIC_BUS, kD2186_OUT_32K, 0x49 }, // enable OUT32 clock + + { PMU_IIC_BUS, kD2186_BUCK6_VSEL, 0x26 }, // N56/T133 Adi PMU: Change default voltage on BUCK6 to 2.0375 V + + { PMU_IIC_BUS, kD2186_LDO9_VSEL, 0x44 }, // N56/T133/N61 Front Camera AVDD Voltage setting from PMU +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2186_GPIO1_CONF1, 0x88 }, // CHG_TO_PMU_INT_L In, L Low, No Wake, PU + { PMU_IIC_BUS, kD2186_GPIO1_CONF2, 0x72 }, // CHG_TO_PMU_INT_L POR + { PMU_IIC_BUS, kD2186_GPIO2_CONF1, 0x8a }, // BB_TO_PMU_HOST_WAKE_L In, L Low, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO2_CONF2, 0x72 }, // BB_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO3_CONF1, 0x01 }, // PMU_TO_BB_RST_R_L Out 0, Low , Push-Pull + { PMU_IIC_BUS, kD2186_GPIO3_CONF2, 0x12 }, // PMU_TO_BB_RST_R_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO4_CONF1, 0x82 }, // TRISTAR_TO_AP_INT In, L High, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO4_CONF2, 0x72 }, // TRISTAR_TO_AP_INT POR + { PMU_IIC_BUS, kD2186_GPIO5_CONF1, 0x83 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO5_CONF2, 0x72 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO6_CONF1, 0x01 }, // PMU_TO_OSCAR_RESET_CLK_32K_L Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO6_CONF2, 0x12 }, // PMU_TO_OSCAR_RESET_CLK_32K_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO7_CONF1, 0x83 }, // WLAN_TO_PMU_HOST_WAKE In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO7_CONF2, 0x72 }, // WLAN_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO8_CONF1, 0xA2 }, // CODEC_TO_PMU_MIKEY_INT_L In, Any Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO8_CONF2, 0x12 }, // CODEC_TO_PMU_MIKEY_INT_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO9_CONF1, 0x01 }, // PMU_TO_BT_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO9_CONF2, 0x12 }, // PMU_TO_BT_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO10_CONF1, 0x92 }, // BT_TO_PMU_HOST_WAKE In, R Edge, Wake, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO10_CONF2, 0x72 }, // BT_TO_PMU_HOST_WAKE Disabled +// { PMU_IIC_BUS, kD2186_GPIO11_CONF1, 0x01 }, // PMU_TO_WLAN_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO11_CONF1, 0x03 }, // PMU_TO_WLAN_REG_ON_R Out 1, Push-Pull (FIXME! rdar://14957372) + { PMU_IIC_BUS, kD2186_GPIO11_CONF2, 0x12 }, // PMU_TO_WLAN_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO12_CONF1, 0x08}, // AP_TO_I2C0_SCL Out, nReset, PU + { PMU_IIC_BUS, kD2186_GPIO12_CONF2, 0x72 }, // AP_TO_I2C0_SCL POR + { PMU_IIC_BUS, kD2186_GPIO13_CONF1, 0x83 }, // OSCAR_TO_PMU_HOST_WAKE In, In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO13_CONF2, 0x72 }, // OSCAR_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO14_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO14_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO15_CONF1, 0x01 }, // PMU_TO_BB_VBUS_DET Out 0, Low, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO15_CONF2, 0x02 }, // PMU_TO_BB_VBUS_DET VCC_MAIN + { PMU_IIC_BUS, kD2186_GPIO16_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO16_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO17_CONF1, 0x9A }, // WLAN_TO_PMU_PCIE_WAKE_L In, F Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO17_CONF2, 0x12 }, // WLAN_TO_PMU_PCIE_WAKE_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO18_CONF1, 0x01 }, // PMU_TO_ACC_SW_ON Out 0, Low, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO18_CONF2, 0x12 }, // PMU_TO_ACC_SW_ON VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO19_CONF1, 0x93 }, // NC_HALL1_TO_PMU_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO19_CONF2, 0x12 }, // NC_HALL1_TO_PMU_WAKE VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO20_CONF1, 0x93 }, // NC_HALL2_TO_PMU_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO20_CONF2, 0x12 }, // NC_HALL2_TO_PMU_WAKE VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO21_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO21_CONF2, 0x72 }, // POR + +// TODO: configure debounce for WAS kD2045_GPIO_DEB2,kD2045_GPIO_DEB5,kD2045_GPIO_DEB6? + + { PMU_IIC_BUS, kD2186_BUCK_DWI_CTRL0, 0x07 }, // enable DWI for BUCK0, BUCK1, BUCK2 + { PMU_IIC_BUS, kD2186_SYS_CTRL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + +// TODO: verify + { PMU_IIC_BUS, kD2186_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/e86/include/target/uartconfig.h b/target/e86/include/target/uartconfig.h new file mode 100644 index 0000000..09ae44b --- /dev/null +++ b/target/e86/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/e86/init.c b/target/e86/init.c new file mode 100644 index 0000000..0e1d2a6 --- /dev/null +++ b/target/e86/init.c @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if (APPLICATION_IBOOT && PRODUCT_IBOOT) +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define E86_AP_BOARD_ID (0xE) // AP board ID +#define E86_DEV_BOARD_ID (0xF) // DEV board ID + +#define E86_BOARD_REV (0xF) //(0xF) + +// Combined Board Id/Board Revision +typedef enum { + BOARD_TYPE_UNKNOWN = 0, + BOARD_TYPE_E86_PROTO1 = 1 +} board_type; + +static uint32_t gpio_board_rev; +static bool gpio_board_rev_valid; + +static uint32_t e86_get_board_rev(void); +static board_type e86_get_board_type(void); + +#if WITH_HW_DISPLAY_DISPLAYPORT +static dp_t dp_link_config = { + .mode = 1, + .type = 0, + .min_link_rate = 0xa, + .max_link_rate = 0xa, + .lanes = 4, + .ssc = 0, + .alpm = 0, + .vrr_enable = 0, + .vrr_on = 0, + .fast_link_training = false, +}; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static uint32_t e86_get_board_rev (void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; + } + +static board_type e86_get_board_type (void) +{ + static board_type board_type = BOARD_TYPE_UNKNOWN; + + if (board_type != BOARD_TYPE_UNKNOWN) { + dprintf(DEBUG_INFO, "%s: board type: %d\n", __func__, board_type); + return board_type; + } + + uint32_t board_id = platform_get_board_id(); + uint32_t board_rev = e86_get_board_rev(); + + dprintf(DEBUG_INFO, "%s: board id: %d, rev: %d\n", + __func__, board_id, board_rev); + + if (target_config_ap()) { + if (E86_AP_BOARD_ID == board_id) { + if (E86_BOARD_REV == board_rev) { + return (BOARD_TYPE_E86_PROTO1); + } + } + } + + panic("Unknown/unsupported board id/rev combination: 0x%x/0x%x", + board_id, board_rev); + + return (BOARD_TYPE_UNKNOWN); +} + +static void e86_reset_hoover (bool reset) +{ + power_set_gpio(POWER_GPIO_HVR_RESET_L, 1, !reset); +} + +static void target_fixup_pmu(void) +{ +#if WITH_HW_POWER + int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); + + int rc; + uint8_t val; + bool fix_ana_trim = false; + + rc = pmu_get_data(0, 0x1, &val); // read PMU.OTP version + + if (rc < 0) { + dprintf(DEBUG_CRITICAL, "PMU: cannot read OTP Version (%d)\n", rc); + } else { + dprintf(DEBUG_INFO, "%s: PMU OTP ver: %x\n", __func__, val); + + if (val < 0x0d) { + rc = pmu_get_data(0, 0x01d7, &val); // read kD2186_BUCK6_ANA_TRIM4 + + if (rc < 0) { + dprintf(DEBUG_INFO, "PMU: cannot read " + "kD2186_BUCK6_ANA_TRIM4 (%d)\n", rc); + } else { + fix_ana_trim = true; + } + } + } + + dprintf(DEBUG_INFO, "%s: fix_ana_trim: %d\n", __func__, fix_ana_trim); + + rc = pmu_set_data(0, 0x7000, 0x1d, 0); // test mode + + if (rc < 0) { + dprintf(DEBUG_INFO, "PMU: cannot enter test mode (%d)\n", rc); + } else { + // Remove N56 EVT iBoot Overwrites for PMU + // to set high gain mode for kD2186_BUCK6_ANA_TRIM4 0x02 has to be + // OR'd in to preserve exiting bits + if (fix_ana_trim) { + // merge in high gain mode + rc = pmu_set_data(0, 0x01d7, ( val | 0x02 ), 1); + + if (rc < 0) { + dprintf(DEBUG_INFO, "cannot change " + "kD2186_BUCK6_ANA_TRIM4 (%d)\n", rc); + } + } + + // N61/12A265: All wakes appended with + // "button4" + rc = pmu_set_data(0, 0x0443, 0x35, 1); + + if (rc < 0) { + dprintf(DEBUG_INFO, "cannot change button4 (%d)\n", rc); + } + + rc = pmu_set_data(0, 0x7000, 0x00, 0); + + if (rc < 0) { + panic("PMU: cannot exit test mode (%d)", rc); + } + } +#endif +} + +void target_early_init (void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + dprintf(DEBUG_INFO, "%s: chip rev: %d, fuse: %d\n", __func__, + chipid_get_chip_revision(), chipid_get_fuse_revision()); + + target_fixup_pmu(); +#endif +} + +void target_late_init (void) +{ + clock_gate(CLK_UART7, 0); + +#if WITH_HW_DISPLAY_DISPLAYPORT + displayport_init(&dp_link_config); + e86_reset_hoover(false); +#endif +} + +void target_init (void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware (void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); +} + +void target_poweroff (void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); +} + +int target_bootprep (enum boot_target target) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); + return 0; +} + +bool target_should_recover (void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron (bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) { + *cold_button_boot = true; + } +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return (!*cold_button_boot || platform_get_request_dfu1()); +} + +bool target_should_poweroff (bool at_boot) +{ + return (platform_get_request_dfu1() && (!at_boot || !power_has_usb())); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle (void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); + dprintf(DEBUG_INFO, "%s ...\n", __func__); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if WITH_HW_DISPLAY_DISPLAYPORT + return ((void *)(&dp_link_config)); +#else + return (NULL); +#endif +} + +#if WITH_ENV +void target_setup_default_environment (void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); + + // boot-device is set in platform's init.c + env_set("wifiaddr", "7E:77:77:77:77:77", 0); + env_set("display-timing", "720p-e86", 0); + env_set("adbe-tunables", "default", 0); +} +#endif + +#if WITH_DEVICETREE +int target_update_device_tree (void) +{ + + dprintf(DEBUG_INFO, "%s ...\n", __func__); + + return 0; +} +#endif // WITH_DEVICETREE diff --git a/target/e86/pinconfig.c b/target/e86/pinconfig.c new file mode 100644 index 0000000..fc262e0 --- /dev/null +++ b/target/e86/pinconfig.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 1v0 + I/O Spreadsheet tracker: E86: IO Spreadsheet Tracker + Conversion command: csvtopinconfig.py --soc fiji --copyright 2014 --radar ' E86: IO Spreadsheet Tracker' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : ULPI_DIR -> + CFG_DISABLED, // 1 : ULPI_STP -> + CFG_DISABLED, // 2 : ULPI_NXT -> + CFG_DISABLED, // 3 : ULPI_DATA[7] -> + CFG_DISABLED, // 4 : ULPI_DATA[6] -> + CFG_DISABLED, // 5 : ULPI_DATA[5] -> + CFG_DISABLED, // 6 : ULPI_DATA[4] -> + CFG_DISABLED, // 7 : ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // 8 : ULPI_DATA[3] -> + CFG_DISABLED, // 9 : ULPI_DATA[2] -> + CFG_DISABLED, // 10 : ULPI_DATA[1] -> + CFG_DISABLED, // 11 : ULPI_DATA[0] -> + CFG_DISABLED, // 12 : SPI1_SCLK -> + CFG_DISABLED, // 13 : SPI1_MOSI -> + CFG_DISABLED, // 14 : SPI1_MISO -> + CFG_DISABLED, // 15 : SPI1_SSIN -> + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | PULL_UP, // 32 : GPIO[11] -> SYS_BTN_MENU_L + CFG_IN | PULL_UP, // 33 : GPIO[12] -> SYS_BTN_HOLD_L + CFG_DISABLED, // 34 : I2S3_MCK -> + CFG_DISABLED, // 35 : I2S3_LRCK -> + CFG_DISABLED, // 36 : I2S3_BCLK -> + CFG_DISABLED, // 37 : I2S3_DOUT -> + CFG_DISABLED, // 38 : I2S3_DIN -> + CFG_DISABLED, // 39 : CLK32K_OUT -> + +/* Port 5 */ + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 40 : PCIE_CLKREQ0_N -> GMAC_CLKREQ_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> WLAN_PCIE_CLKREQ_L + CFG_DISABLED, // 42 : NAND_SYS_CLK -> + CFG_DISABLED, // 43 : GPIO[0] -> + CFG_DISABLED, // 44 : GPIO[1] -> + CFG_IN | PULL_UP, // 45 : GPIO[2] -> SYS_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 46 : GPIO[3] -> SYS_BTN_VOL_DN_L + CFG_DISABLED, // 47 : GPIO[4] -> + +/* Port 6 */ + CFG_DISABLED, // 48 : GPIO[5] -> + CFG_DISABLED, // 49 : GPIO[6] -> + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 50 : GPIO[7] -> WLAN_BT_DEV_WAKE + CFG_DISABLED, // 51 : GPIO[14] -> + CFG_DISABLED, // 52 : GPIO[16] -> DUT_BOARD_ID3 + CFG_DISABLED, // 53 : GPIO[17] -> + CFG_DISABLED, // 54 : GPIO[18] -> DUT_BOOT_CFG0 + CFG_DISABLED, // 55 : GPIO[20] -> + +/* Port 7 */ + CFG_IN | PULL_DOWN, // 56 : GPIO[21] -> HOOVER_IRQ + CFG_DISABLED, // 57 : UART5_RTXD -> + CFG_DISABLED, // 58 : UART8_TXD -> + CFG_DISABLED, // 59 : UART8_RXD -> + CFG_DISABLED, // 60 : SPI0_SCLK -> DUT_BOARD_ID0 + CFG_DISABLED, // 61 : SPI0_MOSI -> DUT_BOARD_ID1 + CFG_DISABLED, // 62 : SPI0_MISO -> DUT_BOARD_ID2 + CFG_DISABLED, // 63 : SPI0_SSIN -> + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> GMAC_SMB_DATA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> GMAC_SMB_CLK + CFG_DISABLED, // 66 : GPIO[22] -> + CFG_DISABLED, // 67 : GPIO[23] -> + CFG_DISABLED, // 68 : GPIO[25] -> DUT_BOOT_CFG1 + CFG_DISABLED, // 69 : GPIO[28] -> DUT_BOOT_CFG2 + CFG_DISABLED, // 70 : GPIO[29] -> DUT_BOARD_ID4 + CFG_DISABLED, // 71 : GPIO[34] -> DUT_BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[35] -> DUT_BOARD_REV2 + CFG_DISABLED, // 73 : GPIO[36] -> DUT_BOARD_REV1 + CFG_DISABLED, // 74 : GPIO[37] -> DUT_BOARD_REV0 + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39]/ PCIE_PERST0_N -> GMAC_PERST_L + CFG_DISABLED, // 76 : GPIO[42] -> + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 77 : GPIO[43]/PCIE_PERST1_N -> WLAN_PCIE_RST_L + CFG_DISABLED, // 78 : DISP_VSYNC -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 79 : UART0_TXD -> TRISTAR_UART1_TX + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> TRISTAR_UART1_RX + CFG_DISABLED, // 81 : TMR32_PWM0 -> + CFG_DISABLED, // 82 : TMR32_PWM1 -> + CFG_DISABLED, // 83 : TMR32_PWM2 -> + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 84 : UART6_TXD -> TRISTAR_UART0_TX + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 85 : UART6_RXD -> TRISTAR_UART0_RX + CFG_DISABLED, // 86 : I2C3_SDA -> HUB0_NON_REM1_SDA + CFG_DISABLED, // 87 : I2C3_SCL -> HUB0_CFG_SEL0_SCL + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> PMU_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> PMU_SCL + CFG_DISABLED, // 98 : GPIO[38] -> + CFG_DISABLED, // 99 : UART2_TXD -> << CPLD MUX >> + CFG_DISABLED, // 100 : UART2_RXD -> << CPLD MUX >> + CFG_DISABLED, // 101 : UART2_RTSN -> << CPLD MUX >> + CFG_DISABLED, // 102 : UART2_CTSN -> << CPLD MUX >> + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 103 : DWI_DO -> PMU_DWI_DI + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 104 : DWI_CLK -> PMU_DWI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 105 : WDOG -> PMU_RESET_IN1 + CFG_IN | PULL_UP, // 106 : GPIO[13] -> PMU_IRQ_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 107 : GPIO[19] -> PMU_KEEPACT + CFG_DISABLED, // 108 : GPIO[26] -> DUT_FORCE_DFU + CFG_DISABLED, // 109 : GPIO[27] -> DUT_DFU_STATUS + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_PRE_UVLO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 111 : SOCHOT1 -> PMU_RESET_IN3 + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 113 : TST_CLKOUT -> << SMA CONN >> + CFG_DISABLED, // 114 : GPIO[8] -> + CFG_DISABLED, // 115 : GPIO[9] -> WLAN_JTAG_SWCLK + CFG_DISABLED, // 116 : GPIO[10] -> WLAN_JTAG_SWDIO + CFG_DISABLED, // 117 : GPIO[15] -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 118 : UART4_TXD -> WLAN_UART_RXD + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> WLAN_UART_TXD + +/* Port 15 */ + CFG_OUT_1 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 120 : UART4_RTSN -> WLAN_UART_CTS_L + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 121 : UART4_CTSN -> WLAN_UART_RTS_L + CFG_DISABLED, // 122 : SPI3_MOSI -> + CFG_DISABLED, // 123 : SPI3_MISO -> + CFG_DISABLED, // 124 : SPI3_SCLK -> + CFG_DISABLED, // 125 : SPI3_SSIN -> + CFG_DISABLED, // 126 : GPIO[24] -> + CFG_DISABLED, // 127 : GPIO[30] -> << CPLD SPARE >> + +/* Port 16 */ + CFG_DISABLED, // 128 : GPIO[31] -> << CPLD SPARE >> + CFG_DISABLED, // 129 : GPIO[32] -> << CPLD SPARE >> + CFG_DISABLED, // 130 : GPIO[33] -> << CPLD SPARE >> + CFG_IN, // 131 : GPIO[40] -> SYS_BTN_RING_L + CFG_DISABLED, // 132 : GPIO[41] -> + CFG_IN | PULL_DOWN, // 133 : I2S4_MCK -> TRISTAR_INT + CFG_DISABLED, // 134 : I2S4_LRCK -> + CFG_DISABLED, // 135 : I2S4_BCLK -> + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S4_DOUT -> + CFG_DISABLED, // 137 : I2S4_DIN -> + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 138 : I2C1_SDA -> HOOVER_I2C_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 139 : I2C1_SCL -> HOOVER_I2C_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 160 : I2S0_LRCK -> HOOVER_MCA_LRCK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 161 : I2S0_BCLK -> HOOVER_MCA_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 162 : I2S0_DOUT -> HOOVER_MCA_D0 + CFG_DISABLED, // 163 : I2S0_DIN -> + CFG_DISABLED, // 164 : I2S1_MCK -> + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 165 : I2S1_LRCK -> WLAN_BT_I2S_LRCK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 166 : I2S1_BCLK -> WLAN_BT_I2S_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 167 : I2S1_DOUT -> WLAN_BT_I2S_DIN + +/* Port 21 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 168 : I2S1_DIN -> WLAN_B2_I2S_DOUT + CFG_DISABLED, // 169 : I2S2_LRCK -> + CFG_DISABLED, // 170 : I2S2_BCLK -> + CFG_DISABLED, // 171 : I2S2_DOUT -> + CFG_DISABLED, // 172 : I2S2_DIN -> + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 173 : UART1_TXD -> WLAN_BT_UART_RXD + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> WLAN_BT_UART_TXD + CFG_OUT_1 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 175 : UART1_RTSN -> WLAN_BT_UART_CTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 176 : UART1_CTSN -> WLAN_BT_UART_RTS_L + CFG_FUNC0 | PULL_DOWN, // 177 : EDP_HPD -> HOOVER_HPD_OUT + CFG_DISABLED, // 178 : UART3_TXD -> + CFG_DISABLED, // 179 : UART3_RXD -> + CFG_DISABLED, // 180 : UART3_RTSN -> + CFG_DISABLED, // 181 : UART3_CTSN -> + CFG_DISABLED, // 182 : SPI2_SCLK -> + CFG_DISABLED, // 183 : SPI2_MOSI -> + +/* Port 23 */ + CFG_DISABLED, // 184 : SPI2_MISO -> + CFG_DISABLED, // 185 : SPI2_SSIN -> + CFG_DISABLED, // 186 : ISP0_SDA -> + CFG_DISABLED, // 187 : ISP0_SCL -> + CFG_DISABLED, // 188 : ISP1_SDA -> + CFG_DISABLED, // 189 : ISP1_SCL -> + CFG_DISABLED, // 190 : SENSOR0_RST -> + CFG_DISABLED, // 191 : SENSOR0_CLK -> + +/* Port 24 */ + CFG_DISABLED, // 192 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 193 : SENSOR0_ISTRB -> + CFG_DISABLED, // 194 : ISP_UART0_TXD -> + CFG_DISABLED, // 195 : ISP_UART0_RXD -> + CFG_DISABLED, // 196 : SENSOR1_RST -> + CFG_DISABLED, // 197 : SENSOR1_CLK -> + CFG_DISABLED, // 198 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // 199 : SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 200 : UART7_TXD -> WLAN_GPIO_1_WLAN_DEV_WAKE + CFG_DISABLED, // 201 : UART7_RXD -> + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 202 : I2S0_MCK -> HOOVER_MCA_MCK + CFG_DISABLED, // 203 : I2S2_MCK -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 0, { pinconfig_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/e86/rules.mk b/target/e86/rules.mk new file mode 100644 index 0000000..90cddfd --- /dev/null +++ b/target/e86/rules.mk @@ -0,0 +1,44 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2186=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + WITH_HW_HOOVER=1 \ + DISPLAY_APPLE_TV_TUNABLES=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + DP_DTPATH=\"arm-io/displayport\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy\" \ + WIFI_DTPATH=\"arm-io/uart4/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" + +ifeq ($(PRODUCT),iBoot) +OPTIONS += \ + WITH_HW_DISPLAY_DISPLAYPORT=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/e88/include/target/gpiodef.h b/target/e88/include/target/gpiodef.h new file mode 100644 index 0000000..e14f429 --- /dev/null +++ b/target/e88/include/target/gpiodef.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* E88 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_RINGER_AB GPIO( 0, 4) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 4, 5) // EHCI_PORT_PWR0 +#define GPIO_BOARD_REV1 GPIO( 4, 6) // EHCI_PORT_PWR1 +#define GPIO_BOARD_REV2 GPIO( 4, 7) // EHCI_PORT_PWR2 +#define GPIO_BOARD_REV3 GPIO( 2, 1) // GPIO17 + +/* which IICs to initialize */ +#define IICS_MASK (5) + +#define TRISTAR_IIC_BUS (0) + +/* D1881 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/e88/include/target/nand_spec_tables.h b/target/e88/include/target/nand_spec_tables.h new file mode 100644 index 0000000..e7e91ae --- /dev/null +++ b/target/e88/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000101 + }, + + /* useToggleMode */ TRUE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ TRUE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ TRUE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/e88/include/target/powerconfig.h b/target/e88/include/target/powerconfig.h new file mode 100644 index 0000000..b231746 --- /dev/null +++ b/target/e88/include/target/powerconfig.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +/* Matched to D1881B1-OTP-CD-v5 */ + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kD1881_LDO1, 0x0D }, // PP3V0_USB 3.15V + { PMU_IIC_BUS, kD1881_LDO2, 0x0A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1881_LDO3, 0x0A }, // PP3V0_IMU 3.00V + { PMU_IIC_BUS, kD1881_LDO4, 0x16 }, // PP3V0_OPTICAL 2.90V + { PMU_IIC_BUS, kD1881_LDO5, 0x0A }, // PP3V0_NAND 3.00V + { PMU_IIC_BUS, kD1881_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1881_LDO7, 0x0F }, // PP3V3_VIDEO 3.00V + { PMU_IIC_BUS, kD1881_LDO8, 0x14 }, // PP3V0_USBMUX 3.00V + { PMU_IIC_BUS, kD1881_LDO9, 0x01 }, // PP1V5_CAM_AVDD 1.30V + { PMU_IIC_BUS, kD1881_LDO10, 0x01 }, // PP2V8_CAM_AVDD 2.55V + { PMU_IIC_BUS, kD1881_LDO11, 0x02 }, // 1.80V + { PMU_IIC_BUS, kD1881_LDO12, 0x10 }, // PP1V1 1.00V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // no bypass +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1881_ACTIVE1, 0xBD }, // Everything except VBUCK1, LDO2 + { PMU_IIC_BUS, kD1881_ACTIVE2, 0xBB }, // LDO4, LDO5, LDO7, LDO8, LDO9, LDO11 enabled + { PMU_IIC_BUS, kD1881_ACTIVE3, 0x2F }, // LDO12 + { PMU_IIC_BUS, kD1881_ACTIVE4, 0xE0 }, // CPU1V8 & CPU1V2 on, WDIG off + { PMU_IIC_BUS, kD1881_LCM_CONTROL1, 0x02 }, // PP5V1_GRAPE_VDDH 5.10V + { PMU_IIC_BUS, kD1881_LCM_CONTROL2, 0x0E }, // PP5V7_LCD_AVDDH 5.70V + { PMU_IIC_BUS, kD1881_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1881_LCM_BST_CONTROL, 0x1A }, // PP6V3_LCM_VBOOST 6.30V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* Note: the following differences from OTP are intentional: + - GPIO 5: Enable CLK32k + - GPIO 8: Enable Codec (Mikey) Wake + - GPIO 7: Enable WiFi Wake + - GPIO 10: Enable Wake amd Pull-Up + */ + { PMU_IIC_BUS, kD1881_SYS_GPIO_1, 0xB9 }, // CLK32K_GRAPE In, R Edge, No Wake, No PU + // Clock is enabled by AppleARMFunction default + { PMU_IIC_BUS, kD1881_SYS_GPIO_2, 0x09 }, // BB_WAKE_AP -- NC + { PMU_IIC_BUS, kD1881_SYS_GPIO_3, 0x09 }, // BB_PMU_FET_ON -- NC + { PMU_IIC_BUS, kD1881_SYS_GPIO_4, 0xBA }, // TRISTAR_INT In, R Edge, Wake, No PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_5, 0x49 }, // CLK32K_WIFI Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_6, 0x09 }, // BATTERY_SWI -- NC + { PMU_IIC_BUS, kD1881_SYS_GPIO_7, 0xBB }, // WLAN_HOST_WAKE In, R Edge, Wake, PD, No PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_8, 0xEA }, // CODEC_HOST_WAKE_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_9, 0x09 }, // BT_REG_ON Out 1, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_10, 0xBA }, // BT_HOST_WAKE In, R Edge, Wake, PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_11, 0x09 }, // WIFI_REG_ON Out 0, Push-Pull, VBUCK3 + + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB1, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB2, 0x02 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB3, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB4, 0x00 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB5, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB6, 0x02 }, + + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // enable HIB_32kHz (for WIFI/BT); DWI disabled + + // turn off buck4 negative current limit + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, // set bank1 + { PMU_IIC_BUS, kD1881_TEST_MODE, 0x01 }, // enter test mode + { PMU_IIC_BUS, 0xCB, 0x23 }, // turn off negative current limit + { PMU_IIC_BUS, kD1881_TEST_MODE, 0x00 }, // exit test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, // set bank0 +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xC8 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x01 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable LED Power + (kDIALOG_WLED_CONTROL_WLED_ENABLE2 | kDIALOG_WLED_CONTROL_WLED_ENABLE1 | kDIALOG_WLED_CONTROL_WLED_RAMP_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/e88/include/target/uartconfig.h b/target/e88/include/target/uartconfig.h new file mode 100644 index 0000000..606b3bb --- /dev/null +++ b/target/e88/include/target/uartconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (1) + +#endif diff --git a/target/e88/include/target/usbconfig.h b/target/e88/include/target/usbconfig.h new file mode 100644 index 0000000..e3fcbcf --- /dev/null +++ b/target/e88/include/target/usbconfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_UOTGTUNE1 + +#undef USBPHY_UOTGTUNE1 +#define USBPHY_UOTGTUNE1 (0x749) + +#endif /* USBPHY_UOTGTUNE1 */ + +#ifdef USBPHY_UOTGTUNE2 + +#undef USBPHY_UOTGTUNE2 +#define USBPHY_UOTGTUNE2 (0x2FF3) + +#endif /* USBPHY_UOTGTUNE2 */ + + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/e88/init.c b/target/e88/init.c new file mode 100644 index 0000000..a2d3c08 --- /dev/null +++ b/target/e88/init.c @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static u_int32_t e88_get_board_rev(void); + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("boot-partition", "0", 0); + env_set("boot-path", "/System/Library/Caches/com.apple.kernelcaches/kernelcache", 0); +} + +#endif + +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; + +static u_int32_t e88_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + uint32_t brd_rev3_inverted = (gpio_read(GPIO_BOARD_REV3) ? 0UL : 1UL); + gpio_board_rev = + (brd_rev3_inverted << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize, propCnt; + char *propName; + void *propData; + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + } + + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Updte the speaker calibration data + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + return 0; +} + +#endif diff --git a/target/e88/pinconfig.c b/target/e88/pinconfig.c new file mode 100644 index 0000000..932f4ce --- /dev/null +++ b/target/e88/pinconfig.c @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v4 + I/O Spreadsheet tracker: E88: IO Spreadsheet Tracker + Conversion command: csvtopinconfig.py --soc h4a --radar ' E88: IO Spreadsheet Tracker' --copyright 2014 +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | PULL_UP, // 0 : GPIO[0] -> MENU_KEY_L + CFG_IN | PULL_UP, // 1 : GPIO[1] -> HOLD_KEY_L + CFG_IN | PULL_UP, // 2 : GPIO[2] -> VOL_UP_L + CFG_IN | PULL_UP, // 3 : GPIO[3] -> VOL_DWN_L + CFG_OUT_1, // 4 : GPIO[4] -> ACC_UHPM_EN + CFG_DISABLED | PULL_DOWN, // 5 : GPIO[5] -> NC + CFG_DISABLED | PULL_DOWN, // 6 : GPIO[6] -> NC + CFG_OUT_0 | PULL_DOWN, // 7 : GPIO[7] -> BT_WAKE + +/* Port 1 */ + CFG_OUT_0, // 8 : GPIO[8] -> WLAN_HSIC_AP_RDY + CFG_IN | PULL_DOWN, // 9 : GPIO[9] -> WLAN_HSIC_DEV_RDY + CFG_DISABLED, // 10 : GPIO[10] -> NC + CFG_DISABLED, // 11 : GPIO[11] -> NC + CFG_OUT_0, // 12 : GPIO[12] -> EN_8VBOOST + CFG_IN | PULL_UP, // 13 : GPIO[13] -> PMU_IRQ_L + CFG_OUT_0, // 14 : GPIO[14] -> WLAN_HSIC_RESUME + CFG_OUT_1, // 15 : GPIO[15] -> SNAP_MCU_RESET_L + +/* Port 2 */ + CFG_IN, // 16 : GPIO[16] -> BRD_ID3 + CFG_IN, // 17 : GPIO[17] -> BRD_REV3 + CFG_IN | PULL_DOWN, // 18 : GPIO[18] -> BOOT_CFG0 + CFG_OUT_0, // 19 : GPIO[19] -> KEEPACTIVE + CFG_IN, // 20 : GPIO[20] -> TRISTAR_INT + CFG_IN | PULL_UP, // 21 : GPIO[21] -> SNAP_INT_L + CFG_OUT_0 | PULL_DOWN, // 22 : GPIO[22] -> SNAP_ID0 + CFG_IN | PULL_DOWN, // 23 : GPIO[23] -> SNAP_ID1 + +/* Port 3 */ + CFG_OUT_0 | PULL_DOWN, // 24 : GPIO[24] -> PS_5VBOOST_L + CFG_IN | PULL_DOWN, // 25 : GPIO[25] -> BOOT_CFG1 + CFG_IN | PULL_DOWN, // 26 : GPIO[26] -> FORCE_DFU + CFG_OUT_0, // 27 : GPIO[27] -> DUT_DFU_STATUS + CFG_IN, // 28 : GPIO[28] -> BOOT_CFG2 + CFG_IN, // 29 : GPIO[29] -> BOOT_CFG3 + CFG_OUT_0 | PULL_DOWN, // 30 : GPIO[30] -> CODEC_RESET_L + CFG_IN, // 31 : GPIO[31] -> VBUS_FAULT_L + +/* Port 4 */ + CFG_OUT_0, // 32 : GPIO[32] -> USB_SW_EN + CFG_IN | PULL_DOWN, // 33 : GPIO[33] -> GYRO_INT1 + CFG_IN, // 34 : GPIO[34] -> ACC_UHPM_POK + CFG_OUT_1, // 35 : GPIO[35] -> EN_5VBOOST + CFG_IN, // 36 : GPIO[36] -> ACCEL_INT2_L + CFG_IN, // 37 : EHCI_PORT_PWR[0] -> BRD_REV[0] + CFG_IN, // 38 : EHCI_PORT_PWR[1] -> BRD_REV[1] + CFG_IN, // 39 : EHCI_PORT_PWR[2] -> BRD_REV[2] + +/* Port 5 */ + CFG_FUNC0, // 40 : UART1_TXD -> AP_DBG_UART_TXD + CFG_FUNC0, // 41 : UART1_RXD -> AP_DBG_UART_RXD + CFG_DISABLED | PULL_DOWN, // 42 : UART1_RTSN -> NC + CFG_IN, // 43 : UART1_CTSN -> SNAP_DET_L + CFG_FUNC0, // 44 : UART2_TXD -> ACC_UART_TXD + CFG_FUNC0, // 45 : UART2_RXD -> ACC_UART_RXD + CFG_DISABLED | PULL_DOWN, // 46 : UART2_RTSN -> NC + CFG_OUT_1, // 47 : UART2_CTSN -> USB_HUB_RST_L + +/* Port 6 */ + CFG_FUNC0, // 48 : UART3_TXD -> BT_UART_RXD + CFG_FUNC0, // 49 : UART3_RXD -> BT_UART_TXD + CFG_FUNC0, // 50 : UART3_RTSN -> BT_UART_CTS_L + CFG_FUNC0, // 51 : UART3_CTSN -> BT_UART_RTS_L + CFG_FUNC0, // 52 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0, // 53 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0, // 54 : I2C1_SDA -> SNAP_I2C_SDA + CFG_FUNC0, // 55 : I2C1_SCL -> SNAP_I2C_SCL + +/* Port 7 */ + CFG_FUNC0, // 56 : ISP0_SDA -> I2C_CAM_REAR_SDA_1V8 + CFG_FUNC0, // 57 : ISP0_SCL -> I2C_CAM_REAR_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 58 : ISP1_SDA -> NC + CFG_DISABLED | PULL_DOWN, // 59 : ISP1_SCL -> NC + CFG_FUNC0 | PULL_DOWN, // 60 : MIPI_VSYNC -> SNAP_MIPI_VSYNC + CFG_FUNC0 | PULL_DOWN, // 61 : TMR32_PWM0 -> GYRO_INT2 + CFG_FUNC0 | PULL_DOWN, // 62 : TMR32_PWM1 -> ACCEL_INT1_L + CFG_FUNC0, // 63 : TMR32_PWM2 -> WLAN_TIMESYNC + +/* Port 8 */ + CFG_DISABLED, // 64 : SWI_DATA -> NC + CFG_FUNC0, // 65 : DWI_DI -> DWI_AP_DI + CFG_FUNC0, // 66 : DWI_DO -> DWI_AP_DO + CFG_FUNC0, // 67 : DWI_CLK -> DWI_AP_CLK + CFG_OUT_0, // 68 : SENSOR0_RST -> CAM_REAR_SHUTDOWN_L + CFG_FUNC0, // 69 : SENSOR0_CLK -> CAM_REAR_CLK + CFG_DISABLED | PULL_DOWN, // 70 : SENSOR1_RST -> NC + CFG_DISABLED | PULL_DOWN, // 71 : SENSOR1_CLK -> NC + +/* Port 9 */ + CFG_DISABLED | PULL_DOWN, // 72 : ISP0_PRE_FLASH -> NC + CFG_DISABLED | PULL_DOWN, // 73 : ISP0_FLASH -> NC + CFG_DISABLED, // 74 : ISP1_PRE_FLASH -> NC + CFG_DISABLED, // 75 : ISP1_FLASH -> NC + CFG_FUNC0, // 76 : I2S0_MCK -> CODEC_MCLK + CFG_FUNC0, // 77 : I2S0_LRCK -> CODEC_LRCLK + CFG_FUNC0, // 78 : I2S0_BCLK -> CODEC_BCLK + CFG_DISABLED | PULL_DOWN, // 79 : I2S0_DOUT -> NC + +/* Port 10 */ + CFG_FUNC0, // 80 : I2S0_DIN -> CODEC_TO_DUT_DIN + CFG_DISABLED, // 81 : I2S1_MCK -> NC + CFG_FUNC0, // 82 : I2S1_LRCK -> BT_PCM_SYNC + CFG_FUNC0, // 83 : I2S1_BCLK -> BT_PCM_CLK + CFG_FUNC0, // 84 : I2S1_DOUT -> BT_PCM_IN + CFG_FUNC0, // 85 : I2S1_DIN -> BT_PCM_OUT + CFG_DISABLED, // 86 : I2S2_MCK -> NC + CFG_FUNC0, // 87 : I2S2_LRCK -> SPKR_AMP_MCA_FSYNC + +/* Port 11 */ + CFG_FUNC0, // 88 : I2S2_BCLK -> SPKR_AMP_MCA_BCLK + CFG_FUNC0 | PULL_DOWN, // 89 : I2S2_DOUT -> SPKR_AMP_MCA_SDATA + CFG_DISABLED, // 90 : I2S2_DIN -> NC + CFG_FUNC0, // 91 : I2S3_MCK -> SNAP_I2S_MCLK_H4A + CFG_FUNC0, // 92 : I2S3_LRCK -> SNAP_I2S_LRCK + CFG_FUNC0, // 93 : I2S3_BCLK -> SNAP_I2S_BCLK + CFG_FUNC0, // 94 : I2S3_DOUT -> DUT_DOUT_TO_SNAP_I2S + CFG_FUNC0, // 95 : I2S3_DIN -> SNAP_TO_DUT_I2S_DIN + +/* Port 12 */ + CFG_IN, // 96 : SPI0_SCLK -> BRD_ID0 + CFG_IN, // 97 : SPI0_MOSI -> BRD_ID1 + CFG_IN, // 98 : SPI0_MISO -> BRD_ID2 + CFG_DISABLED, // 99 : SPI0_SSIN -> NC + CFG_FUNC0, // 100 : SPI1_SCLK -> SNAP_SPI_CLK + CFG_FUNC0, // 101 : SPI1_MOSI -> SNAP_SPI_MOSI + CFG_FUNC0, // 102 : SPI1_MISO -> SNAP_SPI_MISO + CFG_FUNC0, // 103 : SPI1_SSIN -> SNAP_MCU_SPI_CS_L + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI2_SCLK -> NC + CFG_DISABLED, // 105 : SPI2_MOSI -> NC + CFG_DISABLED, // 106 : SPI2_MISO -> NC + CFG_DISABLED, // 107 : SPI2_SSIN -> NC + CFG_DISABLED, // 108 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 109 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 110 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 111 : UNSPECIFIED -> UNSPECIFIED + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0, // 128 : UART4_TXD -> WLAN_DBG_UART_RXD + CFG_FUNC0, // 129 : UART4_RXD -> WLAN_DBG_UART_TXD + CFG_DISABLED | PULL_DOWN, // 130 : UART4_RTSN -> NC + CFG_IN, // 131 : UART4_CTSN -> PMU_AMUX_AY_CTRL + CFG_DISABLED | PULL_DOWN, // 132 : SDIO0_DATA[3] -> SDIO0_DATA[3] + CFG_DISABLED | PULL_DOWN, // 133 : SDIO0_DATA[2] -> SDIO0_DATA[2] + CFG_DISABLED | PULL_DOWN, // 134 : SDIO0_DATA[1] -> SDIO0_DATA[1] + CFG_DISABLED | PULL_DOWN, // 135 : SDIO0_DATA[0] -> SDIO0_DATA[0] + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN, // 136 : SDIO0_CMD -> SDIO0_CMD + CFG_DISABLED | PULL_DOWN, // 137 : SDIO0_CLK -> SDIO0_CLK + CFG_DISABLED | PULL_DOWN, // 138 : FMI0_CEN[3] -> NC + CFG_DISABLED | PULL_DOWN, // 139 : FMI0_CEN[2] -> NC + CFG_DISABLED | PULL_DOWN, // 140 : FMI0_CEN[1] -> NC + CFG_FUNC0 | DRIVE_X2, // 141 : FMI0_CEN[0] -> F0CE0_L + CFG_FUNC0 | DRIVE_X2, // 142 : FMI0_CLE -> F0CLE + CFG_FUNC0 | DRIVE_X2, // 143 : FMI0_ALE -> F0ALE + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2, // 144 : FMI0_REN -> F0RE_L + CFG_FUNC0 | DRIVE_X2, // 145 : FMI0_WEN -> F0WE_L + CFG_FUNC0 | DRIVE_X2, // 146 : FMI0_IO[7] -> F0AD<7> + CFG_FUNC0 | DRIVE_X2, // 147 : FMI0_IO[6] -> F0AD<6> + CFG_FUNC0 | DRIVE_X2, // 148 : FMI0_IO[5] -> F0AD<5> + CFG_FUNC0 | DRIVE_X2, // 149 : FMI0_IO[4] -> F0AD<4> + CFG_DISABLED, // 150 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 151 : UNSPECIFIED -> UNSPECIFIED + +/* Port 19 */ + CFG_DISABLED, // 152 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 153 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 154 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 155 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 156 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 157 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 158 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 159 : UNSPECIFIED -> UNSPECIFIED + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X2, // 160 : FMI0_DQS -> F0DQS + CFG_FUNC0 | DRIVE_X2, // 161 : FMI0_IO[3] -> F0AD<3> + CFG_FUNC0 | DRIVE_X2, // 162 : FMI0_IO[2] -> F0AD<2> + CFG_FUNC0 | DRIVE_X2, // 163 : FMI0_IO[1] -> F0AD<1> + CFG_FUNC0 | DRIVE_X2, // 164 : FMI0_IO[0] -> F0AD<0> + CFG_DISABLED | PULL_DOWN, // 165 : FMI1_CEN[3] -> + CFG_DISABLED | PULL_DOWN, // 166 : FMI1_CEN[2] -> + CFG_DISABLED | PULL_DOWN, // 167 : FMI1_CEN[1] -> + +/* Port 21 */ + CFG_FUNC0 | DRIVE_X2, // 168 : FMI1_CEN[0] -> F1CE0_L + CFG_FUNC0 | DRIVE_X2, // 169 : FMI1_CLE -> F1CLE + CFG_FUNC0 | DRIVE_X2, // 170 : FMI1_ALE -> F1ALE + CFG_FUNC0 | DRIVE_X2, // 171 : FMI1_REN -> F1RE_L + CFG_FUNC0 | DRIVE_X2, // 172 : FMI1_WEN -> F1WE_L + CFG_FUNC0 | DRIVE_X2, // 173 : FMI1_IO[7] -> F1AD<7> + CFG_FUNC0 | DRIVE_X2, // 174 : FMI1_IO[6] -> F1AD<6> + CFG_FUNC0 | DRIVE_X2, // 175 : FMI1_IO[5] -> F1AD<5> + +/* Port 22 */ + CFG_FUNC0 | DRIVE_X2, // 176 : FMI1_IO[4] -> F1AD<4> + CFG_FUNC0 | DRIVE_X2, // 177 : FMI1_DQS -> F1DQS + CFG_FUNC0 | DRIVE_X2, // 178 : FMI1_IO[3] -> F1AD<3> + CFG_FUNC0 | DRIVE_X2, // 179 : FMI1_IO[2] -> F1AD<2> + CFG_FUNC0 | DRIVE_X2, // 180 : FMI1_IO[1] -> F1AD<1> + CFG_FUNC0 | DRIVE_X2, // 181 : FMI1_IO[0] -> F1AD<0> + CFG_DISABLED, // 182 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 183 : UNSPECIFIED -> UNSPECIFIED + +/* Port 23 */ + CFG_DISABLED, // 184 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 185 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 186 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 187 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 188 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 189 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 190 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 191 : UNSPECIFIED -> UNSPECIFIED + +/* Port 24 */ + CFG_FUNC0, // 192 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0, // 193 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0, // 194 : UART0_TXD -> DUT_TXD + CFG_FUNC0 | PULL_DOWN, // 195 : UART0_RXD -> DUT_RXD + CFG_DISABLED | PULL_DOWN, // 196 : UART5_RTXD -> NC + CFG_DISABLED | PULL_DOWN, // 197 : DP_HPD -> GND + CFG_FUNC0 | PULL_DOWN, // 198 : TST_CLKOUT -> TST_CLKOUT + CFG_DISABLED | PULL_DOWN, // 199 : TST_STPCLK -> GND + +/* Port 25 */ + CFG_FUNC0, // 200 : WDOG -> H4A_WDOG + CFG_DISABLED, // 201 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 202 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 203 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 204 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 205 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 206 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 207 : UNSPECIFIED -> UNSPECIFIED +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | PULL_UP, // 0 : GPIO[0] -> MENU_KEY_L + CFG_IN | PULL_UP, // 1 : GPIO[1] -> HOLD_KEY_L + CFG_IN | PULL_UP, // 2 : GPIO[2] -> VOL_UP_L + CFG_IN | PULL_UP, // 3 : GPIO[3] -> VOL_DWN_L + CFG_OUT_1, // 4 : GPIO[4] -> ACC_UHPM_EN + CFG_DISABLED | PULL_DOWN, // 5 : GPIO[5] -> NC + CFG_DISABLED | PULL_DOWN, // 6 : GPIO[6] -> NC + CFG_OUT_0 | PULL_DOWN, // 7 : GPIO[7] -> BT_WAKE + +/* Port 1 */ + CFG_OUT_0, // 8 : GPIO[8] -> WLAN_HSIC_AP_RDY + CFG_IN | PULL_DOWN, // 9 : GPIO[9] -> WLAN_HSIC_DEV_RDY + CFG_DISABLED, // 10 : GPIO[10] -> NC + CFG_DISABLED, // 11 : GPIO[11] -> NC + CFG_OUT_0, // 12 : GPIO[12] -> EN_8VBOOST + CFG_IN | PULL_UP, // 13 : GPIO[13] -> PMU_IRQ_L + CFG_OUT_0, // 14 : GPIO[14] -> WLAN_HSIC_RESUME + CFG_OUT_1, // 15 : GPIO[15] -> SNAP_MCU_RESET_L + +/* Port 2 */ + CFG_IN, // 16 : GPIO[16] -> BRD_ID3 + CFG_IN, // 17 : GPIO[17] -> BRD_REV3 + CFG_IN | PULL_DOWN, // 18 : GPIO[18] -> BOOT_CFG0 + CFG_OUT_0, // 19 : GPIO[19] -> KEEPACTIVE + CFG_IN, // 20 : GPIO[20] -> TRISTAR_INT + CFG_IN | PULL_UP, // 21 : GPIO[21] -> SNAP_INT_L + CFG_OUT_0 | PULL_DOWN, // 22 : GPIO[22] -> SNAP_ID0 + CFG_IN | PULL_DOWN, // 23 : GPIO[23] -> SNAP_ID1 + +/* Port 3 */ + CFG_OUT_0 | PULL_DOWN, // 24 : GPIO[24] -> PS_5VBOOST_L + CFG_IN | PULL_DOWN, // 25 : GPIO[25] -> BOOT_CFG1 + CFG_IN | PULL_DOWN, // 26 : GPIO[26] -> FORCE_DFU + CFG_OUT_0, // 27 : GPIO[27] -> DUT_DFU_STATUS + CFG_IN, // 28 : GPIO[28] -> BOOT_CFG2 + CFG_IN, // 29 : GPIO[29] -> BOOT_CFG3 + CFG_OUT_0 | PULL_DOWN, // 30 : GPIO[30] -> CODEC_RESET_L + CFG_IN, // 31 : GPIO[31] -> VBUS_FAULT_L + +/* Port 4 */ + CFG_OUT_0, // 32 : GPIO[32] -> USB_SW_EN + CFG_IN | PULL_DOWN, // 33 : GPIO[33] -> GYRO_INT1 + CFG_IN, // 34 : GPIO[34] -> ACC_UHPM_POK + CFG_OUT_1, // 35 : GPIO[35] -> EN_5VBOOST + CFG_IN, // 36 : GPIO[36] -> ACCEL_INT2_L + CFG_IN, // 37 : EHCI_PORT_PWR[0] -> BRD_REV[0] + CFG_IN, // 38 : EHCI_PORT_PWR[1] -> BRD_REV[1] + CFG_IN, // 39 : EHCI_PORT_PWR[2] -> BRD_REV[2] + +/* Port 5 */ + CFG_FUNC0, // 40 : UART1_TXD -> AP_DBG_UART_TXD + CFG_FUNC0, // 41 : UART1_RXD -> AP_DBG_UART_RXD + CFG_DISABLED | PULL_DOWN, // 42 : UART1_RTSN -> NC + CFG_IN, // 43 : UART1_CTSN -> SNAP_DET_L + CFG_FUNC0, // 44 : UART2_TXD -> ACC_UART_TXD + CFG_FUNC0, // 45 : UART2_RXD -> ACC_UART_RXD + CFG_DISABLED | PULL_DOWN, // 46 : UART2_RTSN -> NC + CFG_OUT_1, // 47 : UART2_CTSN -> USB_HUB_RST_L + +/* Port 6 */ + CFG_FUNC0, // 48 : UART3_TXD -> BT_UART_RXD + CFG_FUNC0, // 49 : UART3_RXD -> BT_UART_TXD + CFG_FUNC0, // 50 : UART3_RTSN -> BT_UART_CTS_L + CFG_FUNC0, // 51 : UART3_CTSN -> BT_UART_RTS_L + CFG_FUNC0, // 52 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0, // 53 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0, // 54 : I2C1_SDA -> SNAP_I2C_SDA + CFG_FUNC0, // 55 : I2C1_SCL -> SNAP_I2C_SCL + +/* Port 7 */ + CFG_FUNC0, // 56 : ISP0_SDA -> I2C_CAM_REAR_SDA_1V8 + CFG_FUNC0, // 57 : ISP0_SCL -> I2C_CAM_REAR_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 58 : ISP1_SDA -> NC + CFG_DISABLED | PULL_DOWN, // 59 : ISP1_SCL -> NC + CFG_FUNC0 | PULL_DOWN, // 60 : MIPI_VSYNC -> SNAP_MIPI_VSYNC + CFG_FUNC0 | PULL_DOWN, // 61 : TMR32_PWM0 -> GYRO_INT2 + CFG_FUNC0 | PULL_DOWN, // 62 : TMR32_PWM1 -> ACCEL_INT1_L + CFG_FUNC0, // 63 : TMR32_PWM2 -> WLAN_TIMESYNC + +/* Port 8 */ + CFG_DISABLED, // 64 : SWI_DATA -> NC + CFG_FUNC0, // 65 : DWI_DI -> DWI_AP_DI + CFG_FUNC0, // 66 : DWI_DO -> DWI_AP_DO + CFG_FUNC0, // 67 : DWI_CLK -> DWI_AP_CLK + CFG_OUT_0, // 68 : SENSOR0_RST -> CAM_REAR_SHUTDOWN_L + CFG_FUNC0, // 69 : SENSOR0_CLK -> CAM_REAR_CLK + CFG_DISABLED | PULL_DOWN, // 70 : SENSOR1_RST -> NC + CFG_DISABLED | PULL_DOWN, // 71 : SENSOR1_CLK -> NC + +/* Port 9 */ + CFG_DISABLED | PULL_DOWN, // 72 : ISP0_PRE_FLASH -> NC + CFG_DISABLED | PULL_DOWN, // 73 : ISP0_FLASH -> NC + CFG_DISABLED, // 74 : ISP1_PRE_FLASH -> NC + CFG_DISABLED, // 75 : ISP1_FLASH -> NC + CFG_FUNC0, // 76 : I2S0_MCK -> CODEC_MCLK + CFG_FUNC0, // 77 : I2S0_LRCK -> CODEC_LRCLK + CFG_FUNC0, // 78 : I2S0_BCLK -> CODEC_BCLK + CFG_DISABLED | PULL_DOWN, // 79 : I2S0_DOUT -> NC + +/* Port 10 */ + CFG_FUNC0, // 80 : I2S0_DIN -> CODEC_TO_DUT_DIN + CFG_DISABLED, // 81 : I2S1_MCK -> NC + CFG_FUNC0, // 82 : I2S1_LRCK -> BT_PCM_SYNC + CFG_FUNC0, // 83 : I2S1_BCLK -> BT_PCM_CLK + CFG_FUNC0, // 84 : I2S1_DOUT -> BT_PCM_IN + CFG_FUNC0, // 85 : I2S1_DIN -> BT_PCM_OUT + CFG_DISABLED, // 86 : I2S2_MCK -> NC + CFG_FUNC0, // 87 : I2S2_LRCK -> SPKR_AMP_MCA_FSYNC + +/* Port 11 */ + CFG_FUNC0, // 88 : I2S2_BCLK -> SPKR_AMP_MCA_BCLK + CFG_FUNC0 | PULL_DOWN, // 89 : I2S2_DOUT -> SPKR_AMP_MCA_SDATA + CFG_DISABLED, // 90 : I2S2_DIN -> NC + CFG_FUNC0, // 91 : I2S3_MCK -> SNAP_I2S_MCLK_H4A + CFG_FUNC0, // 92 : I2S3_LRCK -> SNAP_I2S_LRCK + CFG_FUNC0, // 93 : I2S3_BCLK -> SNAP_I2S_BCLK + CFG_FUNC0, // 94 : I2S3_DOUT -> DUT_DOUT_TO_SNAP_I2S + CFG_FUNC0, // 95 : I2S3_DIN -> SNAP_TO_DUT_I2S_DIN + +/* Port 12 */ + CFG_IN, // 96 : SPI0_SCLK -> BRD_ID0 + CFG_IN, // 97 : SPI0_MOSI -> BRD_ID1 + CFG_IN, // 98 : SPI0_MISO -> BRD_ID2 + CFG_DISABLED, // 99 : SPI0_SSIN -> NC + CFG_FUNC0, // 100 : SPI1_SCLK -> SNAP_SPI_CLK + CFG_FUNC0, // 101 : SPI1_MOSI -> SNAP_SPI_MOSI + CFG_FUNC0, // 102 : SPI1_MISO -> SNAP_SPI_MISO + CFG_FUNC0, // 103 : SPI1_SSIN -> SNAP_MCU_SPI_CS_L + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI2_SCLK -> NC + CFG_DISABLED, // 105 : SPI2_MOSI -> NC + CFG_DISABLED, // 106 : SPI2_MISO -> NC + CFG_DISABLED, // 107 : SPI2_SSIN -> NC + CFG_DISABLED, // 108 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 109 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 110 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 111 : UNSPECIFIED -> UNSPECIFIED + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0, // 128 : UART4_TXD -> WLAN_DBG_UART_RXD + CFG_FUNC0, // 129 : UART4_RXD -> WLAN_DBG_UART_TXD + CFG_DISABLED | PULL_DOWN, // 130 : UART4_RTSN -> NC + CFG_IN, // 131 : UART4_CTSN -> PMU_AMUX_AY_CTRL + CFG_DISABLED | PULL_DOWN, // 132 : SDIO0_DATA[3] -> SDIO0_DATA[3] + CFG_DISABLED | PULL_DOWN, // 133 : SDIO0_DATA[2] -> SDIO0_DATA[2] + CFG_DISABLED | PULL_DOWN, // 134 : SDIO0_DATA[1] -> SDIO0_DATA[1] + CFG_DISABLED | PULL_DOWN, // 135 : SDIO0_DATA[0] -> SDIO0_DATA[0] + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN, // 136 : SDIO0_CMD -> SDIO0_CMD + CFG_DISABLED | PULL_DOWN, // 137 : SDIO0_CLK -> SDIO0_CLK + CFG_DISABLED | PULL_DOWN, // 138 : FMI0_CEN[3] -> NC + CFG_DISABLED | PULL_DOWN, // 139 : FMI0_CEN[2] -> NC + CFG_DISABLED | PULL_DOWN, // 140 : FMI0_CEN[1] -> NC + CFG_FUNC0, // 141 : FMI0_CEN[0] -> F0CE0_L + CFG_FUNC0, // 142 : FMI0_CLE -> F0CLE + CFG_FUNC0, // 143 : FMI0_ALE -> F0ALE + +/* Port 18 */ + CFG_FUNC0, // 144 : FMI0_REN -> F0RE_L + CFG_FUNC0, // 145 : FMI0_WEN -> F0WE_L + CFG_FUNC0, // 146 : FMI0_IO[7] -> F0AD<7> + CFG_FUNC0, // 147 : FMI0_IO[6] -> F0AD<6> + CFG_FUNC0, // 148 : FMI0_IO[5] -> F0AD<5> + CFG_FUNC0, // 149 : FMI0_IO[4] -> F0AD<4> + CFG_DISABLED, // 150 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 151 : UNSPECIFIED -> UNSPECIFIED + +/* Port 19 */ + CFG_DISABLED, // 152 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 153 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 154 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 155 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 156 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 157 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 158 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 159 : UNSPECIFIED -> UNSPECIFIED + +/* Port 20 */ + CFG_FUNC0, // 160 : FMI0_DQS -> F0DQS + CFG_FUNC0, // 161 : FMI0_IO[3] -> F0AD<3> + CFG_FUNC0, // 162 : FMI0_IO[2] -> F0AD<2> + CFG_FUNC0, // 163 : FMI0_IO[1] -> F0AD<1> + CFG_FUNC0, // 164 : FMI0_IO[0] -> F0AD<0> + CFG_DISABLED | PULL_DOWN, // 165 : FMI1_CEN[3] -> + CFG_DISABLED | PULL_DOWN, // 166 : FMI1_CEN[2] -> + CFG_DISABLED | PULL_DOWN, // 167 : FMI1_CEN[1] -> + +/* Port 21 */ + CFG_FUNC0, // 168 : FMI1_CEN[0] -> F1CE0_L + CFG_FUNC0, // 169 : FMI1_CLE -> F1CLE + CFG_FUNC0, // 170 : FMI1_ALE -> F1ALE + CFG_FUNC0, // 171 : FMI1_REN -> F1RE_L + CFG_FUNC0, // 172 : FMI1_WEN -> F1WE_L + CFG_FUNC0, // 173 : FMI1_IO[7] -> F1AD<7> + CFG_FUNC0, // 174 : FMI1_IO[6] -> F1AD<6> + CFG_FUNC0, // 175 : FMI1_IO[5] -> F1AD<5> + +/* Port 22 */ + CFG_FUNC0, // 176 : FMI1_IO[4] -> F1AD<4> + CFG_FUNC0, // 177 : FMI1_DQS -> F1DQS + CFG_FUNC0, // 178 : FMI1_IO[3] -> F1AD<3> + CFG_FUNC0, // 179 : FMI1_IO[2] -> F1AD<2> + CFG_FUNC0, // 180 : FMI1_IO[1] -> F1AD<1> + CFG_FUNC0, // 181 : FMI1_IO[0] -> F1AD<0> + CFG_DISABLED, // 182 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 183 : UNSPECIFIED -> UNSPECIFIED + +/* Port 23 */ + CFG_DISABLED, // 184 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 185 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 186 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 187 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 188 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 189 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 190 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 191 : UNSPECIFIED -> UNSPECIFIED + +/* Port 24 */ + CFG_FUNC0, // 192 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0, // 193 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0, // 194 : UART0_TXD -> DUT_TXD + CFG_FUNC0 | PULL_DOWN, // 195 : UART0_RXD -> DUT_RXD + CFG_DISABLED | PULL_DOWN, // 196 : UART5_RTXD -> NC + CFG_DISABLED | PULL_DOWN, // 197 : DP_HPD -> GND + CFG_FUNC0 | PULL_DOWN, // 198 : TST_CLKOUT -> TST_CLKOUT + CFG_DISABLED | PULL_DOWN, // 199 : TST_STPCLK -> GND + +/* Port 25 */ + CFG_FUNC0, // 200 : WDOG -> H4A_WDOG + CFG_DISABLED, // 201 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 202 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 203 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 204 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 205 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 206 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 207 : UNSPECIFIED -> UNSPECIFIED +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0 } }, + { 1, 1, { pinconfig_dev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/e88/rules.mk b/target/e88/rules.mk new file mode 100644 index 0000000..f2d4dd8 --- /dev/null +++ b/target/e88/rules.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1881=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_MED \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_CPU_SOURCE=2 \ + TARGET_MIPI_DSI_SOURCE=1 \ + TARGET_MANAGED2H_SOURCE=0 \ + TARGET_MANAGED2L_SOURCE=0 \ + TARGET_MANAGED2H_DIV=1 \ + TARGET_MANAGED2L_DIV=2 \ + TARGET_PCLK1_SOURCE=1 \ + TARGET_PCLK1_DIV=4 \ + TARGET_GFX_SOURCE=2 \ + TARGET_GFX_SLC_SOURCE=3 \ + TARGET_IOP_SOURCE=3 \ + TARGET_LPERFS_SOURCE=3 \ + TARGET_HPERFNRT_SOURCE=0 \ + TARGET_USE_HSIC=1 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_DPHYCTL=0x30 \ + TARGET_DSIM_SUPPRESS=0x1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci/wlan\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/elbaref/include/target/adbe_settings.h b/target/elbaref/include/target/adbe_settings.h new file mode 100644 index 0000000..f05d2a5 --- /dev/null +++ b/target/elbaref/include/target/adbe_settings.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "ipad6d", + .adbe0_vblank_pos_vbi_pulse = 0x0132, + .adbe0_vblank_clk_gate_wakeup = 0x07, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_PMGR_CLK_GATE_ENABLE | + DBEMODECNTL_DYN_CLK_GATE_ENABLE | + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | + AAP_FORMAT_CONTROL_REG1_FCMODE(2) | + AAP_FORMAT_CONTROL_REG1_RSVD(0) | + AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/elbaref/include/target/boardid.h b/target/elbaref/include/target/boardid.h new file mode 100644 index 0000000..6145e77 --- /dev/null +++ b/target/elbaref/include/target/boardid.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TARGET_BOARDID_H +#define TARGET_BOARDID_H + +// Board ids +#define TARGET_BOARD_ID_J98aAP (0x10) +#define TARGET_BOARD_ID_J98aDEV (0x11) + +#define TARGET_BOARD_ID_J99aAP (0x12) +#define TARGET_BOARD_ID_J99aDEV (0x13) + +// Board revs +#define J99a_DEV0_BOARD_REV (0x0) +#define J99a_DEV1_BOARD_REV (0x1) + +#endif diff --git a/target/elbaref/include/target/dcsfixup.h b/target/elbaref/include/target/dcsfixup.h new file mode 100644 index 0000000..b977bbd --- /dev/null +++ b/target/elbaref/include/target/dcsfixup.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +// Revert applicable Elba targets to 4 GB when kernel supports 4 GB +// will require removing chnldec from the table below, as well as +// setting DCS_NUM_CHANNELS to 8. In addition, the SDRAM_LEN and TEXT_BASE will have to be increased +static inline +void dcs_init_config_fixup_params(dcs_config_params_t *dcs_params, dcs_target_t targtype) +{ + dcs_params->chnldec = 0x00050110; + +#if DCS_DRAM_800MHZ + dcs_params->freq[0].clk_period = CLK_PERIOD_800; + dcs_params->freq[0].freqchngctl[3] = 0xae015202; + dcs_params->freq[1].freqchngctl[3] = 0xae011202; + dcs_params->freq[0].lat = 0x001031c6; + dcs_params->freq[0].phyrdwrtim = 0x00050c05; + dcs_params->freq[0].caspch = 0x43d10408; + dcs_params->freq[0].act = 0x10040908; + dcs_params->freq[0].autoref = 0x24480078; + dcs_params->freq[0].selfref = 0x5004b012; + dcs_params->modereg = 0x0e0c6084; + dcs_params->pdn = 0x72273263; + dcs_params->freq[0].derate = 0x28835488; + dcs_params->freq[0].lat2 = 0x001121c6; + dcs_params->freq[0].tat = 0x01312222; + dcs_params->rdwrdqcaltiming_f0 = 0x01040401; + dcs_params->rdwrdqcaltiming_f3 = 0x01040408; + dcs_params->rdwrdqcaltimingctrl2 = 0x010f0a01; + dcs_params->maxrddqssdllmulfactor = 0x00a00b0b; + dcs_params->maxwrdqssdllmulfactor = 0xa0a00808; + dcs_params->freq[0].rdcapcfg = 0x0100070a; + dcs_params->freq[0].autoref2 = 0x24480049; + dcs_params->mr2cmd_step11 = 0x52; + dcs_params->mr1cmd_step11 = 0xae; + dcs_params->rdsdllctrl_step15 = 0x00280004; + dcs_params->qbrparam = 0x00000000; +#endif +}; diff --git a/target/elbaref/include/target/gpiodef.h b/target/elbaref/include/target/gpiodef.h new file mode 100644 index 0000000..11af680 --- /dev/null +++ b/target/elbaref/include/target/gpiodef.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* ipad6,x specific gpio -> pin mappings */ + +#include + +// XXX: Update all of this + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 4) // 116 : GPIO[44] +#define GPIO_BOARD_REV1 GPIO(14, 5) // 117 : GPIO[45] +#define GPIO_BOARD_REV2 GPIO(14, 6) // 118 : GPIO[46] +#define GPIO_BOARD_REV3 GPIO(15, 1) // 121 : GPIO[49] + +/* Miscellaneous Pins */ +#define GPIO_DISPLAY_HPD GPIO(24, 2) // 194: EPD_HPD0 -> LPDP_TCON_TO_SOC_HPD + +#define GPIO_S3E_BOOT_FROM_HOST GPIO_ID(76) // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP (formerly AP_TO_NAND_FW_STRAP) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +/* Switch to this when i2c3 is enabled */ +//#define IICS_MASK (0xF) + +#define TRISTAR_IIC_BUS (0) +#define BACKLIGHT_IIC_BUS (0) +#define DISPLAY_PMU_IIC_BUS (0) + +#define GPIO_PMU_LCD_PWR_EN (17) // PMU GPIO 18 - GPIO_PMU_TO_LCD_PWREN +#define GPIO_PMU_NAND_LOW_POWER_MODE (15) // PMU GPIO 16 - GPIO_PMU_TO_NAND_LOW_BATT_L + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/elbaref/include/target/lpdp_settings.h b/target/elbaref/include/target/lpdp_settings.h new file mode 100644 index 0000000..70231bf --- /dev/null +++ b/target/elbaref/include/target/lpdp_settings.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef LPDP_SETTINGS_H +#define LPDP_SETTINGS_H + +static struct lpdp_port_calibration lpdp_port_calibration_table[1][1] = { + { {LPDP_PHY_LANE_VREG_ADJ_450_mV, 0}, }, +}; + +#define LPDP_PORT_CALIBRATION_TABLE_FIXED (true) + +#endif diff --git a/target/elbaref/include/target/powerconfig.h b/target/elbaref/include/target/powerconfig.h new file mode 100644 index 0000000..2b2ef0c --- /dev/null +++ b/target/elbaref/include/target/powerconfig.h @@ -0,0 +1,140 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +// Configuration per target + +#define PMU_IIC_BUS 0 + +// This configuration is very PMU specific and must be included exactly +// once in power.c +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2257_EN_CMD0, (1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0) }, + { PMU_IIC_BUS, kD2257_EN_CMD1, (1<<0) }, // buck8 + { PMU_IIC_BUS, kD2257_EN_CMD2, 1 }, // enable WLED SPI access + { PMU_IIC_BUS, kD2257_SPI_CTRL, 1 } // enable SPI access +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + // TODO :This is a Bringup Hack, remove + { PMU_IIC_BUS, kD2257_BUCK0_VSEL, 0xc0}, // CPU rail + { PMU_IIC_BUS, kD2257_BUCK1_VSEL, 0xc0}, // GPU rail + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK1_EN, 0xf}, // GPU power rail (see ) + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK8_EN, 0xf}, // GPU RAM power rail (see ) + // TODO :This is a Bringup Hack, remove + + { PMU_IIC_BUS, kD2257_PWRONOFF_LDO4_EN, 0x1}, // Enable PP3V0_ALS + { PMU_IIC_BUS, kD2257_PWRONOFF_LDO7_EN, 0x1}, // Enable PP3V3_USB3 + + { PMU_IIC_BUS, kD2257_LDO2_BYPASS, 0x1}, // bypass when Active rdar://19773152 + + // Drive GPIO_PMU_TO_1V1_EXT_SW_ON (PMU GPIO 20) to enable PP1V1_S1_EXT_SW + // which inturn is SNSI_PP1V1_S1_DDR_VDDQ_x. + // + // Should be ON by default via OTP. + + // Drive GPIO_PMU_TO_1V8_EXT_SW2_ON (PMU GPIO 21) to enable PP1V8_S2_EXT_SW2 + // which inturn is PP1V8_S2_IO_EXPANDER. + // + // Should be ON by default via OTP. + + { PMU_IIC_BUS, 0x7000, 0x1D }, // Enable Test Mode + { PMU_IIC_BUS, kD2257_EN_CMD3, 0}, // Enable SPI access for BUCKx (x=3) + { PMU_IIC_BUS, 0x7000, 0x0 }, // Disable Test Mode + +#if SUB_TARGET_J98a + { PMU_IIC_BUS, kD2257_GPIO5_CONF1, 0x14}, + { PMU_IIC_BUS, kD2257_GPIO5_CONF2, 0x0F}, + { PMU_IIC_BUS, kD2257_GPIO9_CONF1, 0x14}, + { PMU_IIC_BUS, kD2257_GPIO9_CONF2, 0x0F} +#endif + + // ElbaRefUI uses PMU_GPIO19 as GPIO_BEACON_EN_R (J99a uses UART7_RXD as GPIO_SOC_TO_BEACON_EN) + { PMU_IIC_BUS, kD2257_GPIO19_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x80 Output(Push-Pull), Level, no PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO19_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xff }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x7f }, + { PMU_IIC_BUS, kD2257_WLED_CTRL1, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kD2257_WLED_CTRL2, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDA_EN, 0x1f }, // enable LED Power + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDB_EN, 0x1f }, // enable LED Power +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDA_EN, 0x0 }, // disable LED Power + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDB_EN, 0x0 }, // disable LED Power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK0_VSEL } +}; + +// It's VDD FIXED! used for RAM inside the SOC +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK5_VSEL } +}; + +// This is indexed with POWER_RAIL_*, I really just need to use the +// index in LDO[] +target_rails_t target_rails = { + { 0x10, 450, 1250, 3125 }, // POWER_RAIL_CPU, BUCK0 + { 0x15, 600, 1400, 3125 }, // POWER_RAIL_VDD_FIXED BUCK5 + { 0x12, 600, 1400, 3125 }, // POWER_RAIL_SOC, BUCK2 + + { 0x17, 600, 1400, 3125 }, // POWER_RAIL_CPU_RAM, BUCK7 + { 0x11, 450, 1250, 3125 }, // POWER_RAIL_GPU, BUCK1 + { 0x18, 600, 1400, 3125 }, // POWER_RAIL_GPU_RAM, BUCK8 +}; + +#endif // POWERCONFIG_PMU_SETUP + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 + +#define ACC_PWR_LDO (6) + +#define GASGAUGE_BATTERYID_BLOCK 1 + +#endif diff --git a/target/elbaref/include/target/uartconfig.h b/target/elbaref/include/target/uartconfig.h new file mode 100644 index 0000000..ca81b1e --- /dev/null +++ b/target/elbaref/include/target/uartconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#endif diff --git a/target/elbaref/init.c b/target/elbaref/init.c new file mode 100644 index 0000000..ec8ed94 --- /dev/null +++ b/target/elbaref/init.c @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#if (ELBAUIREF && APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#include +dp_t dp; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, -90); + +void +target_early_init (void) +{ +} + +void +target_late_init (void) +{ + power_set_gpio(GPIO_PMU_NAND_LOW_POWER_MODE, 1, 1); +} + +void +target_init (void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void +target_quiesce_hardware (void) +{ +} + +void +target_poweroff (void) +{ +} + +int +target_bootprep (enum boot_target target) +{ + return 0; +} + +bool +target_should_recover (void) +{ + return (platform_get_request_dfu2() && power_has_usb()); +} + +bool +target_should_poweron (bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) { + *cold_button_boot = true; + } +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return (!*cold_button_boot || platform_get_request_dfu1()); +} + +bool +target_should_poweroff (bool at_boot) +{ + return (platform_get_request_dfu1() && (!at_boot || !power_has_usb())); +} + +void * target_get_display_configuration(void) +{ +#if (ELBAUIREF && APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = kDPControllerMode_Slave; + dp.type = kDPControllerType_EDP; + dp.min_link_rate = kLinkRate324Gbps; + dp.max_link_rate = kLinkRate324Gbps; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x1; + dp.vrr_enable = 0x1; + dp.vrr_on = 0x1; + dp.rx_n1= 25; + dp.rx_n2= 2; + dp.rx_n3= 16030; + dp.rx_n5= 0x2; + dp.fast_link_training = true; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void +target_setup_default_environment (void) +{ + env_set("boot-args", " debug=0x14e serial=3 amfi=3 amfi_get_out_of_my_way=1 cs_enforcement_disable=1 fips_mode=0", 0); + // boot-device is set in platform's init.c + env_set("boot-partition", "0", 0); + env_set("boot-path", "/System/Library/Caches/com.apple.kernelcaches/kernelcache", 0); + + env_set("display-color-space","RGB888", 0); + + env_set("display-timing", "ipad6d", 0); + env_set("adbe-tunables", "ipad6d", 0); + env_set("adfe-tunables", "ipad6d", 0); +} + +#endif + +#if WITH_DEVICETREE + +int +target_update_device_tree (void) +{ + DTNode *node; + +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; + DTNode *lpdp_node = NULL; +#endif + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + + extern int lpdp_phy_update_device_tree(DTNode *lpdp_node); + FindNode(0, DPPHY_DTPATH, &lpdp_node); + lpdp_phy_update_device_tree(lpdp_node); + + } +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries +// (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t * +target_color_map_init (enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + + fail: + return NULL; +} +#endif // WITH_PAINT + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +uint32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(uint8_t key, uint8_t *data) +{ + return -1; +} + +int power_set_nvram(uint8_t key, uint8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/elbaref/pinconfig.c b/target/elbaref/pinconfig.c new file mode 100644 index 0000000..c042308 --- /dev/null +++ b/target/elbaref/pinconfig.c @@ -0,0 +1,706 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.1 + I/O Spreadsheet tracker: rdar://problem/18695359 + Conversion command: csvtopinconfig.py --soc elba --config-column 'J99A Config' --radar rdar://problem/18695359 --copyright 2015 +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_CODEC_SCLK_R + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 2 : SPI1_MISO -> SPI_CODEC_MISO + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_CODEC_CS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 8 : SENSOR0_ISTRB -> NC_GPIO_SOC_TO_AUDIO_FH_KEEPALIVE + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 19 : I2S1_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC2CODEC_ASP_BCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC2CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 22 : I2S1_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC2CODEC_ASP_DOUT + +/* Port 3 */ + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 24 : NAND_SYS_CLK -> NAND_SYS_CLK_24MHZ + CFG_FUNC0 | PULL_UP | DRIVE_S3 | SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 27 : UART1_TXD -> UART_SOC2BB_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 28 : UART1_RXD -> UART_BB2SOC_TX + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 29 : UART1_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 30 : UART1_CTSN -> UART_BB2SOC_RTS_L + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 31 : GPIO[43] -> GPIO_SOC2AJ_HS3_SHUNT_EN + +/* Port 4 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC2CODEC_XSP_BCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC2SOC_XSP_DOUT + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S0_MCK -> I2S_AOP_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 5 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 64 : I2S4_MCK -> SWD_KONA_CLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 69 : I2S2_MCK -> I2S_SOC_TO_SPKRAMP_FH_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_SPKRAMP_FH_LRCK + +/* Port 9 */ + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 72 : I2S2_DIN -> I2S_SPKRAMP_FH_TO_SOC_DOUT + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_SPKRAMP_FH_DOUT + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 78 : GPIO[4] -> GPIO_TOUCH_TO_SOC_IRQ_L + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_FH_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + CFG_DISABLED, // 81 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 83 : GPIO[9] -> GPIO_CN_ALS_TO_SOC_IRQ_L + CFG_FUNC1 | DRIVE_S3 | SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 85 : GPIO[11] -> GPIO_SPKAMP_FH_RIGHT_TO_SOC_IRQ_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 86 : GPIO[12] -> NC_DISPLAY_ID0 + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 87 : GPIO[13] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 11 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 88 : GPIO[14] -> NC_DISPLAY_ID0 + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 97 : SPI0_SSIN -> GPIO_USBPD_TO_SOC_IRQ + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 101 : PCIE_PERST3_N -> GPIO_SOC_TO_BB_WAKE_MODEM + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 102 : PCIE_PERST4_N -> PCIE_SOC_TO_USB3_RESET_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 108 : PCIE_CLKREQ4_N -> PCIE_USB3_TO_SOC_CLKREQ_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 119 : GPIO[47] -> GPIO_BRD_REV2 + +/* Port 15 */ + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + CFG_IN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 124 : SKEY_L -> NC_SKEY_ID + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 137 : UART7_TXD -> NC_GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 138 : UART7_RXD -> 1v25_CAM_LDO_EN + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 139 : CLK32K_OUT -> NC_CLK32K_OUT_24MHZ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 140 : DP_WAKEUP0 -> SWD_ORION_SWCLK + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 141 : DP_WAKEUP1 -> SWD_ORION_SWDIO + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_S3 | SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 175 : TMR32_PWM1 -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + +/* Port 22 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_CN_RIGHT_TO_SOC_IRQ_L + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_USB3_XBAR_EN_PULSE_L + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 181 : GPIO[21] -> GPIO_SOC_TO_USB3_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 182 : GPIO[22] -> GPIO_SPKAMP_CN_LEFT_TO_SOC_IRQ_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 183 : GPIO[23] -> GPIO_USB3_TO_SOC_SMI_L + +/* Port 23 */ + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 184 : GPIO[24] -> GPIO_SOC_TO_AUDIO_KEEPALIVE_FH + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 188 : DWI_DO -> DWI_SOC_TO_BEACON_DO + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 191 : PMGR_SSCLK1 -> DWI_SOC_TO_BEACON_CLK + +/* Port 24 */ + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + CFG_FUNC0 | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 196 : I2S3_MCK -> I2S_SOC_TO_SPKRAMP_CN_MCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_SPKRAMP_CN_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_SPKRAMP_CN_LRCK + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_SPKRAMP_CN_DOUT + +/* Port 25 */ + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 200 : I2S3_DIN -> I2S_SPKRAMP_CN_TO_SOC_DOUT + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 203 : GPIO[29] -> GPIO_BRD_ID4 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 204 : GPIO[30] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 205 : GPIO[31] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 206 : GPIO[32] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 207 : GPIO[33] -> NC_EDP_HPD1 + +/* Port 26 */ + CFG_DISABLED, // 208 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V85_CAM_LDO_EN + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 211 : GPIO[37] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 212 : GPIO[38] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 213 : GPIO[39] -> NC_EDP_HPD1 + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE_CN + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 215 : GPIO[41] -> NC_EDP_HPD1 + +/* Port 27 */ + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + CFG_IN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + CFG_IN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + CFG_IN | DRIVE_S3 | SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_UART_AOP_TO_TOUCH_TX + +/* Port 1 */ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_GPIO_TOUCH_TO_AOP_DATA_REQUEST + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_COMPASS_CS_L + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_COMPASS_TO_AOP_IRQ + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 13 : AOP_FUNC[2] -> NC_GPIO_PHOSPHORUS_TO_AOP_IRQ + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_GPIO_SOC_TO_TCON_DISPLAY_SYNC + CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 20 : AOP_FUNC[9] -> NC_GPIO_AOP_TO_LPOSC_EN + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_USBPD_SWDIO + CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> NC_SWD_BB_SWDIO + +/* Port 3 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 24 : AOP_I2S_MCK -> I2S_AOP_MCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> I2S_SOC2CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, // 27 : AOP_I2S_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_CODEC_SCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 2 : SPI1_MISO -> SPI_CODEC_MISO + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_CODEC_CS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 8 : SENSOR0_ISTRB -> NC_GPIO_SOC_TO_AUDIO_FH_KEEPALIVE + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 19 : I2S1_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC2CODEC_ASP_BCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC2CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 22 : I2S1_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC2CODEC_ASP_DOUT + +/* Port 3 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 24 : NAND_SYS_CLK -> NAND_SYS_CLK_24MHZ + CFG_FUNC0 | PULL_UP | DRIVE_S7 | SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + CFG_IN | DRIVE_S7 | SLOW_SLEW, // 27 : UART1_TXD -> UART_SOC2BB_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 28 : UART1_RXD -> UART_BB2SOC_TX + CFG_IN | DRIVE_S7 | SLOW_SLEW, // 29 : UART1_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 30 : UART1_CTSN -> UART_BB2SOC_RTS_L + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 31 : GPIO[43] -> GPIO_SOC2AJ_HS3_SHUNT_EN + +/* Port 4 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC2CODEC_XSP_BCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC2SOC_XSP_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S0_MCK -> I2S_AOP_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 5 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 64 : I2S4_MCK -> SWD_KONA_CLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 69 : I2S2_MCK -> I2S_SOC_TO_SPKRAMP_FH_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_SPKRAMP_FH_LRCK + +/* Port 9 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 72 : I2S2_DIN -> I2S_SPKRAMP_FH_TO_SOC_DOUT + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_SPKRAMP_FH_DOUT + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + CFG_IN | DRIVE_S4 | SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 78 : GPIO[4] -> GPIO_TOUCH_TO_SOC_IRQ_L + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_FH_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + CFG_DISABLED, // 81 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 83 : GPIO[9] -> GPIO_CN_ALS_TO_SOC_IRQ_L + CFG_FUNC1 | DRIVE_S7 | SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 85 : GPIO[11] -> GPIO_SPKAMP_FH_RIGHT_TO_SOC_IRQ_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 86 : GPIO[12] -> NC_DISPLAY_ID0 + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 87 : GPIO[13] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 11 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 88 : GPIO[14] -> NC_DISPLAY_ID0 + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 97 : SPI0_SSIN -> GPIO_USBPD_TO_SOC_IRQ + CFG_IN | DRIVE_S7 | SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + CFG_IN | DRIVE_S4 | SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + CFG_IN | DRIVE_S7 | SLOW_SLEW, // 101 : PCIE_PERST3_N -> GPIO_SOC_TO_BB_WAKE_MODEM + CFG_IN | DRIVE_S7 | SLOW_SLEW, // 102 : PCIE_PERST4_N -> PCIE_SOC_TO_USB3_RESET_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 108 : PCIE_CLKREQ4_N -> PCIE_USB3_TO_SOC_CLKREQ_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 119 : GPIO[47] -> GPIO_BRD_REV2 + +/* Port 15 */ + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + CFG_IN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 124 : SKEY_L -> NC_SKEY_ID + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 137 : UART7_TXD -> NC_GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 138 : UART7_RXD -> 1v25_CAM_LDO_EN + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 139 : CLK32K_OUT -> NC_CLK32K_OUT_24MHZ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 140 : DP_WAKEUP0 -> SWD_ORION_SWCLK + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 141 : DP_WAKEUP1 -> SWD_ORION_SWDIO + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 175 : TMR32_PWM1 -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + +/* Port 22 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_CN_RIGHT_TO_SOC_IRQ_L + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_USB3_XBAR_EN_PULSE_L + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 181 : GPIO[21] -> GPIO_SOC_TO_USB3_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 182 : GPIO[22] -> GPIO_SPKAMP_CN_LEFT_TO_SOC_IRQ_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 183 : GPIO[23] -> GPIO_USB3_TO_SOC_SMI_L + +/* Port 23 */ + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 184 : GPIO[24] -> GPIO_SOC_TO_AUDIO_KEEPALIVE_FH + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN | DRIVE_S7 | SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 188 : DWI_DO -> DWI_SOC_TO_BEACON_DO + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 191 : PMGR_SSCLK1 -> DWI_SOC_TO_BEACON_CLK + +/* Port 24 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 196 : I2S3_MCK -> I2S_SOC_TO_SPKRAMP_CN_MCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_SPKRAMP_CN_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_SPKRAMP_CN_LRCK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_SPKRAMP_CN_DOUT + +/* Port 25 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 200 : I2S3_DIN -> I2S_SPKRAMP_CN_TO_SOC_DOUT + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 203 : GPIO[29] -> GPIO_BRD_ID4 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 204 : GPIO[30] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 205 : GPIO[31] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 206 : GPIO[32] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 207 : GPIO[33] -> NC_EDP_HPD1 + +/* Port 26 */ + CFG_DISABLED, // 208 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V85_CAM_LDO_EN + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 211 : GPIO[37] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 212 : GPIO[38] -> NC_EDP_HPD1 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 213 : GPIO[39] -> NC_EDP_HPD1 + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE_CN + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 215 : GPIO[41] -> NC_EDP_HPD1 + +/* Port 27 */ + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + CFG_IN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + CFG_IN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + CFG_IN | DRIVE_S7 | SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_UART_AOP_TO_TOUCH_TX + +/* Port 1 */ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_GPIO_TOUCH_TO_AOP_DATA_REQUEST + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_COMPASS_CS_L + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_COMPASS_TO_AOP_IRQ + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 13 : AOP_FUNC[2] -> NC_GPIO_PHOSPHORUS_TO_AOP_IRQ + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_GPIO_SOC_TO_TCON_DISPLAY_SYNC + CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 20 : AOP_FUNC[9] -> NC_GPIO_AOP_TO_LPOSC_EN + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_USBPD_SWDIO + CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> NC_SWD_BB_SWDIO + +/* Port 3 */ + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 24 : AOP_I2S_MCK -> I2S_AOP_MCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> I2S_SOC2CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 27 : AOP_I2S_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0, pinconfig_ap_1 } }, + { 1, 1, { pinconfig_dev_0, pinconfig_dev_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/elbaref/rules.mk b/target/elbaref/rules.mk new file mode 100644 index 0000000..ffa513c --- /dev/null +++ b/target/elbaref/rules.mk @@ -0,0 +1,46 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2257=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_PLL_VCO_CAP=0 \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=8 \ + TARGET_ICP_CTR=15 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + PMU_LCD_PWR_EN=1 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + DCS_NUM_RANKS=1 \ + DCS_NUM_CHANNELS=8 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi3/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart2/wlan\" \ + DP_DTPATH=\"arm-io/displayport0\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy0\" \ + BT_DTPATH=\"arm-io/uart3/bluetooth\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o $(LOCAL_DIR)/pinconfig.o diff --git a/target/fijiref/include/target/adbe_settings.h b/target/fijiref/include/target/adbe_settings.h new file mode 100644 index 0000000..132b062 --- /dev/null +++ b/target/fijiref/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0, + .adbe0_tunable_mode_ctrl = 0, + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/fijiref/include/target/aspnandconfig.h b/target/fijiref/include/target/aspnandconfig.h new file mode 100644 index 0000000..4c8e4c2 --- /dev/null +++ b/target/fijiref/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/fijiref/include/target/gpiodef.h b/target/fijiref/include/target/gpiodef.h new file mode 100644 index 0000000..1492904 --- /dev/null +++ b/target/fijiref/include/target/gpiodef.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iphone7,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 9, 2) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO( 9, 1) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO( 9, 0) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO( 8, 7) // 71 : GPIO[37] + +/* Miscellaneous Pins */ + +/* Display reset */ +#define GPIO_LCD_RST GPIO( 0, 1) // 1 : ULPI_STP -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + +/* Ringer Switch */ +#define GPIO_RINGER_AB GPIO(16, 3) // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + +/* D2186 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(13, 3) // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (0) + +#define DISPLAY_PMU_IIC_BUS (0) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/fijiref/include/target/powerconfig.h b/target/fijiref/include/target/powerconfig.h new file mode 100644 index 0000000..0486c89 --- /dev/null +++ b/target/fijiref/include/target/powerconfig.h @@ -0,0 +1,115 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2186_ACTIVE3, 0xAE }, // Current OTP enables LDO{1,2,3,4,5,7}, disable LDO4. + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x37 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1, BUCK4_SW2 + { PMU_IIC_BUS, kD2186_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + + { PMU_IIC_BUS, kD2186_BUCK1_VSEL, 0x80 }, // rdar://14689066 TODO: remove when not necessary + + { PMU_IIC_BUS, kD2186_OUT_32K, 0x49 }, // enable OUT32 clock + + { PMU_IIC_BUS, kD2186_BUCK6_VSEL, 0x26 }, // N56/T133 Adi PMU: Change default voltage on BUCK6 to 2.0375 V + + { PMU_IIC_BUS, kD2186_LDO9_VSEL, 0x44 }, // N56/T133/N61 Front Camera AVDD Voltage setting from PMU +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2186_GPIO1_CONF1, 0x88 }, // CHG_TO_PMU_INT_L In, L Low, No Wake, PU + { PMU_IIC_BUS, kD2186_GPIO1_CONF2, 0x72 }, // CHG_TO_PMU_INT_L POR + { PMU_IIC_BUS, kD2186_GPIO2_CONF1, 0x8a }, // BB_TO_PMU_HOST_WAKE_L In, L Low, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO2_CONF2, 0x72 }, // BB_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO3_CONF1, 0x01 }, // PMU_TO_BB_RST_R_L Out 0, Low , Push-Pull + { PMU_IIC_BUS, kD2186_GPIO3_CONF2, 0x12 }, // PMU_TO_BB_RST_R_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO4_CONF1, 0x82 }, // TRISTAR_TO_AP_INT In, L High, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO4_CONF2, 0x72 }, // TRISTAR_TO_AP_INT POR + { PMU_IIC_BUS, kD2186_GPIO5_CONF1, 0x83 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO5_CONF2, 0x72 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO6_CONF1, 0x01 }, // PMU_TO_OSCAR_RESET_CLK_32K_L Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO6_CONF2, 0x12 }, // PMU_TO_OSCAR_RESET_CLK_32K_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO7_CONF1, 0x83 }, // WLAN_TO_PMU_HOST_WAKE In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO7_CONF2, 0x72 }, // WLAN_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO8_CONF1, 0xA2 }, // CODEC_TO_PMU_MIKEY_INT_L In, Any Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO8_CONF2, 0x12 }, // CODEC_TO_PMU_MIKEY_INT_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO9_CONF1, 0x01 }, // PMU_TO_BT_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO9_CONF2, 0x12 }, // PMU_TO_BT_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO10_CONF1, 0x92 }, // BT_TO_PMU_HOST_WAKE In, R Edge, Wake, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO10_CONF2, 0x72 }, // BT_TO_PMU_HOST_WAKE Disabled +// { PMU_IIC_BUS, kD2186_GPIO11_CONF1, 0x01 }, // PMU_TO_WLAN_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO11_CONF1, 0x03 }, // PMU_TO_WLAN_REG_ON_R Out 1, Push-Pull (FIXME! rdar://14957372) + { PMU_IIC_BUS, kD2186_GPIO11_CONF2, 0x12 }, // PMU_TO_WLAN_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO12_CONF1, 0x08}, // AP_TO_I2C0_SCL Out, nReset, PU + { PMU_IIC_BUS, kD2186_GPIO12_CONF2, 0x72 }, // AP_TO_I2C0_SCL POR + { PMU_IIC_BUS, kD2186_GPIO13_CONF1, 0x83 }, // OSCAR_TO_PMU_HOST_WAKE In, In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO13_CONF2, 0x72 }, // OSCAR_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO14_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO14_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO15_CONF1, 0x01 }, // PMU_TO_BB_VBUS_DET Out 0, Low, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO15_CONF2, 0x02 }, // PMU_TO_BB_VBUS_DET VCC_MAIN + { PMU_IIC_BUS, kD2186_GPIO16_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO16_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO17_CONF1, 0x9A }, // WLAN_TO_PMU_PCIE_WAKE_L In, F Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO17_CONF2, 0x12 }, // WLAN_TO_PMU_PCIE_WAKE_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO18_CONF1, 0x01 }, // PMU_TO_ACC_SW_ON Out 0, Low, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO18_CONF2, 0x12 }, // PMU_TO_ACC_SW_ON VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO19_CONF1, 0x93 }, // NC_HALL1_TO_PMU_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO19_CONF2, 0x12 }, // NC_HALL1_TO_PMU_WAKE VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO20_CONF1, 0x93 }, // NC_HALL2_TO_PMU_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO20_CONF2, 0x12 }, // NC_HALL2_TO_PMU_WAKE VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO21_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO21_CONF2, 0x72 }, // POR + +// TODO: configure debounce for WAS kD2045_GPIO_DEB2,kD2045_GPIO_DEB5,kD2045_GPIO_DEB6? + + { PMU_IIC_BUS, kD2186_BUCK_DWI_CTRL0, 0x07 }, // enable DWI for BUCK0, BUCK1, BUCK2 + { PMU_IIC_BUS, kD2186_SYS_CTRL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + +// TODO: verify + { PMU_IIC_BUS, kD2186_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/fijiref/include/target/uartconfig.h b/target/fijiref/include/target/uartconfig.h new file mode 100644 index 0000000..f81b712 --- /dev/null +++ b/target/fijiref/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/fijiref/init.c b/target/fijiref/init.c new file mode 100644 index 0000000..d6cac76 --- /dev/null +++ b/target/fijiref/init.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + clock_gate(CLK_UART7, 0); +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + if (power_get_boot_flag() == kPowerBootFlagColdButton) + *cold_button_boot = true; + + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +#if WITH_ENV +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("wifiaddr", "7E:77:77:77:77:77", 0); +} +#endif + +#if WITH_DEVICETREE +int target_update_device_tree(void) +{ + return 0; +} +#endif // WITH_DEVICETREE diff --git a/target/fijiref/pinconfig.c b/target/fijiref/pinconfig.c new file mode 100644 index 0000000..5db2853 --- /dev/null +++ b/target/fijiref/pinconfig.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v7 + I/O Spreadsheet tracker: N56 | IOSpreadsheet +*/ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 0 : ULPI_DIR -> LCM_TO_AP_HIFA_BSYNC + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 1 : ULPI_STP -> AP_TO_LCM_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 2 : ULPI_NXT -> AP_TO_TOUCH_AND_MAMBA_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 3 : ULPI_DATA[7] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_DOWN, // 4 : ULPI_DATA[6] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> DISPLAY_TO_AP_ID1 + CFG_IN | PULL_DOWN | SLOW_SLEW, // 7 : ULPI_CLK -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 1 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 8 : ULPI_DATA[3] -> AP_TO_LEDDRV_EN + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> DISPLAY_TO_AP_ID0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 10 : ULPI_DATA[1] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 11 : ULPI_DATA[0] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 12 : SPI1_SCLK -> AP_TO_CODEC_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_MOSI -> AP_TO_CODEC_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 14 : SPI1_MISO -> CODEC_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 15 : SPI1_SSIN -> AP_TO_CODEC_SPI_CS_L + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> BUTTON_TO_AP_MENU_KEY_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> BUTTON_TO_AP_HOLD_KEY_L + CFG_IN | PULL_UP | SLOW_SLEW, // 34 : I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 35 : I2S3_LRCK -> AP_TO_BB_I2S3_LRCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 36 : I2S3_BCLK -> 45_AP_TO_BB_I2S3_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 37 : I2S3_DOUT -> AP_TO_BB_I2S3_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 38 : I2S3_DIN -> BB_TO_AP_I2S3_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 39 : CLK32K_OUT -> 45_AP_TO_TOUCH_CLK32K_RESET_L + +/* Port 5 */ + CFG_IN | SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC + CFG_FUNC0 | PULL_UP, // 41 : PCIE_CLKREQ1_N -> WLAN_TO_AP_PCIE1_CLKREQ_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 43 : GPIO[0] -> AP_TO_HEADSET_HS3_CTRL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 44 : GPIO[1] -> AP_TO_HEADSET_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW, // 45 : GPIO[2] -> BUTTON_TO_AP_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 46 : GPIO[3] -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 47 : GPIO[4] -> SPKAMP_TO_AP_INT_L + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 48 : GPIO[5] -> AP_TO_SPKAMP_BEE_GEES + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 49 : GPIO[6] -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_BT_WAKE + CFG_IN | SLOW_SLEW, // 51 : GPIO[14] -> HALL_TO_PMU_AP_WAKE + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 52 : GPIO[16] -> BOARD_ID3 + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 53 : GPIO[17] -> AP_TO_STOCKHOLM_SIM_SEL + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 54 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN, // 55 : GPIO[20] -> NC + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 56 : GPIO[21] -> BB_TO_AP_DEVICE_RDY + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 57 : UART5_RTXD -> AP_TO_TIGRIS_SWI + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 58 : UART8_TXD -> AP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW, // 59 : UART8_RXD -> OSCAR_TO_AP_UART_RXD + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 60 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 61 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 62 : SPI0_MISO -> BOARD_ID2 + CFG_OUT_1 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 63 : SPI0_SSIN -> NC + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 64 : I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 65 : I2C2_SCL -> AP_TO_I2C2_SCL + CFG_DISABLED | SLOW_SLEW, // 66 : GPIO[22] -> BB_TO_AP_HSIC1_WAKE + CFG_OUT_0 | SLOW_SLEW, // 67 : GPIO[23] -> AP_TO_BB_HOST_RDY + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39] -> NC + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 76 : GPIO[42] -> AP_TO_VIBE_EN + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 77 : GPIO[43] -> AP_TO_WLAN_PCIE1_RST_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 78 : DISP_VSYNC -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 79 : UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 80 : UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 81 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 82 : TMR32_PWM1 -> AP_TO_VIBE_TRIG + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 83 : TMR32_PWM2 -> HALL_TO_AP_GPIO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 84 : UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 85 : UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 86 : I2C3_SDA -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2C3_SCL -> NC + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 96 : I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 97 : I2C0_SCL -> AP_TO_I2C0_SCL + CFG_OUT_0 | SLOW_SLEW, // 98 : GPIO[38] -> AP_TO_BB_COREDUMP + CFG_OUT_0 | SLOW_SLEW, // 99 : UART2_TXD -> AP_TO_BB_UART2_TXD + CFG_FUNC0 | SLOW_SLEW, // 100 : UART2_RXD -> BB_TO_AP_UART2_RXD + CFG_OUT_0 | SLOW_SLEW, // 101 : UART2_RTSN -> AP_TO_BB_UART2_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 102 : UART2_CTSN -> BB_TO_AP_UART2_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 103 : DWI_DO -> 45_AP_TO_PMU_AND_BL_DWI_DO + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 104 : DWI_CLK -> 45_AP_TO_PMU_AND_BL_DWI_CLK_H7P + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 105 : WDOG -> AP_TO_PMU_RESET_IN + CFG_IN | PULL_UP | SLOW_SLEW, // 106 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 108 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 109 : GPIO[27] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_TO_AP_PRE_UVLO_L_R + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 111 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L_R + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED | SLOW_SLEW, // 114 : GPIO[8] -> AP_TO_BB_RST_L + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 115 : GPIO[9] -> AP_TO_WLAN_JTAG_SWCLK + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 116 : GPIO[10] -> AP_TO_WLAN_JTAG_SWDIO + CFG_OUT_0 | SLOW_SLEW, // 117 : GPIO[15] -> AP_TO_BB_WAKE_MODEM + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 118 : UART4_TXD -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0 | SLOW_SLEW, // 119 : UART4_RXD -> WLAN_TO_AP_UART4_RXD + +/* Port 15 */ + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 120 : UART4_RTSN -> AP_TO_WLAN_UART4_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> WLAN_TO_AP_UART4_CTS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 122 : SPI3_MOSI -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 123 : SPI3_MISO -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 124 : SPI3_SCLK -> NC + CFG_IN | SLOW_SLEW, // 125 : SPI3_SSIN -> BB_TO_AP_GPS_SYNC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 126 : GPIO[24] -> BB_TO_AP_RESET_DET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 127 : GPIO[30] -> CODEC_TO_AP_INT_L + +/* Port 16 */ + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 128 : GPIO[31] -> AP_TO_RADIO_ON_L + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 129 : GPIO[32] -> AP_TO_BB_JTAG_SWCLK + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 130 : GPIO[33] -> AP_TO_BB_JTAG_SWDIO + CFG_IN | SLOW_SLEW, // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + CFG_DISABLED | SLOW_SLEW, // 132 : GPIO[41] -> BB_TO_AP_IPC_GPIO + CFG_IN | PULL_DOWN | SLOW_SLEW, // 133 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 134 : I2S4_LRCK -> AP_TO_CODEC_VSP_I2S4_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 135 : I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_TO_CODEC_VSP_I2S4_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 137 : I2S4_DIN -> CODEC_TO_AP_VSP_I2S4_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 138 : I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 139 : I2C1_SCL -> AP_TO_I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 160 : I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 161 : I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 163 : I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED | PULL_DOWN, // 164 : I2S1_MCK -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 165 : I2S1_LRCK -> AP_TO_BT_I2S1_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 166 : I2S1_BCLK -> 45_AP_TO_BT_I2S1_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TO_BT_I2S1_DOUT + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 168 : I2S1_DIN -> BT_TO_AP_I2S1_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 169 : I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 170 : I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 172 : I2S2_DIN -> CODEC_TO_AP_XSP_I2S2_DIN + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 173 : UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 174 : UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 175 : UART1_RTSN -> AP_TO_BT_UART1_RTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 176 : UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 177 : EDP_HPD -> AP_TO_STOCKHOLM_EN + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 178 : UART3_TXD -> AP_TO_STOCKHOLM_UART3_TXD + CFG_FUNC0 | SLOW_SLEW, // 179 : UART3_RXD -> STOCKHOLM_TO_AP_UART3_RXD + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 180 : UART3_RTSN -> AP_TO_STOCKHOLM_UART3_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 181 : UART3_CTSN -> STOCKHOLM_TO_AP_UART3_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 182 : SPI2_SCLK -> AP_TO_TOUCH_SPI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 183 : SPI2_MOSI -> AP_TO_TOUCH_SPI_MOSI + +/* Port 23 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 184 : SPI2_MISO -> TOUCH_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 185 : SPI2_SSIN -> AP_TO_TOUCH_SPI_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 186 : ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 187 : ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 188 : ISP1_SDA -> AP_BI_FCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 189 : ISP1_SCL -> AP_TO_FCAM_I2C_SCL + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 190 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + +/* Port 24 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQ + CFG_IN | PULL_UP | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> BUTTON_TO_AP_SKEY_L + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 194 : ISP_UART0_TXD -> NC_AP_ISP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW, // 195 : ISP_UART0_RXD -> NC_OSCAR_TO_AP_ISP_UART_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 196 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> STOCKHOLM_TO_PMU_HOST_WAKE + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 200 : UART7_TXD -> AP_TO_WLAN_DEVICE_WAKE + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 201 : UART7_RXD -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 202 : I2S0_MCK -> 45_AP_TO_CODEC_I2S0_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 203 : I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/fijiref/rules.mk b/target/fijiref/rules.mk new file mode 100644 index 0000000..815f863 --- /dev/null +++ b/target/fijiref/rules.mk @@ -0,0 +1,38 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2186=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_IPHONE_TUNABLES=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + TARGET_HS_2_LP_DATA_TIME=0 \ + TARGET_LP_2_HS_DATA_TIME=0 \ + TARGET_HS_2_LP_CLOCK_TIME=0 \ + TARGET_LP_2_HS_CLOCK_TIME=0 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/iaccy1/display_get_info.c b/target/iaccy1/display_get_info.c new file mode 100644 index 0000000..f6829ae --- /dev/null +++ b/target/iaccy1/display_get_info.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +int display_get_info(struct display_info *info) +{ + // Relatively sane defaults of 1136x640 @2x + info->stride = 640 * 4; + info->width = 640; + info->height = 1136; + + // 32bpp and @2x scale + info->depth = 32 | 1 << 16; + info->framebuffer = (uintptr_t)PANIC_BASE - (((info->stride * info->height + 0xFFFUL) & ~0xFFFUL) * 3); + + return 0; +} diff --git a/target/iaccy1/include/target/gpiodef.h b/target/iaccy1/include/target/gpiodef.h new file mode 100644 index 0000000..c92b0be --- /dev/null +++ b/target/iaccy1/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iaccy1 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/iaccy1/include/target/pinconfig.h b/target/iaccy1/include/target/pinconfig.h new file mode 100644 index 0000000..1439626 --- /dev/null +++ b/target/iaccy1/include/target/pinconfig.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_PINCONFIG_H +#define __TARGET_PINCONFIG_H + +/* Default iAccy1 Hardware Pin Configuration */ + +/* Updated to match B137B165_io_pinlist_013.xls */ + +#if SUB_TARGET_B137 +#define PCON_B137_B165(x, y) (PCON_##x) +#elif SUB_TARGET_B165 +#define PCON_B137_B165(x, y) (PCON_##y) +#else +#error "Unknown subtarget" +#endif + +static const struct gpio_default_config gpio_default_config[GPIO_GROUP_COUNT] = { +/* P0 */ PINCONFIG( + PCON_OUT_0, NO_PUPDN, // I2S0_MCK -> FORCE_PWM_3V3_L + PCON_OUT_1, NO_PUPDN, // I2S0_LRCK -> 5V_EN + PCON_IN, NO_PUPDN, // I2S0_BCK -> TRI_INT + PCON_B137_B165(DISABLE, OUT_1), NO_PUPDN, // I2S0_DOUT -> FORCE_PWM_1V8 + PCON_OUT_1, NO_PUPDN, // I2S0_DIN -> FORCE_PWM_1V2 + PCON_FUNC2, NO_PUPDN, // UART0_RXD -> + PCON_FUNC2, NO_PUPDN, // UART0_TXD -> + PCON_B137_B165(DISABLE, IN), NO_PUPDN // UART0_NRTS -> DAC_SENSE_STS + ), +/* P1 */ PINCONFIG( + PCON_B137_B165(DISABLE, IN), NO_PUPDN, // UART0_NCTS -> DAC_HEARTBEAT + PCON_FUNC2, NO_PUPDN, // I2C0_SCL -> I2C0_SCL + PCON_FUNC2, NO_PUPDN, // I2C0_SDA -> I2C0_SCL + PCON_DISABLE, NO_PUPDN, // SPI0_CEN -> SPI0_CS + PCON_DISABLE, NO_PUPDN, // SPI0_CLK -> SPI0_CLK + PCON_DISABLE, NO_PUPDN, // SPI0_MOSI -> SPI0_MOSI + PCON_DISABLE, NO_PUPDN, // SPI0_MISO -> SPI0_MISO + PCON_DISABLE, NO_PUPDN // - -> + ), +/* P2 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // GPIO0 -> BOARD_REV[0] + PCON_DISABLE, NO_PUPDN, // GPIO1 -> BOOT_CONFIG[0] + PCON_DISABLE, NO_PUPDN, // GPIO2 -> BOOT_CONFIG[1] + PCON_DISABLE, NO_PUPDN, // GPIO3 -> BOARD_ID[1] + PCON_DISABLE, NO_PUPDN, // GPIO4 -> BOARD_ID[2] + PCON_DISABLE, NO_PUPDN, // GPIO5 -> BOARD_ID[3] + PCON_DISABLE, NO_PUPDN, // GPIO6 -> BOARD_ID[4] + PCON_DISABLE, NO_PUPDN // GPIO7 -> BOARD_REV[1] + ), +/* P3 */ PINCONFIG( + PCON_DISABLE, NO_PUPDN, // CLK0_OUT -> G1_CLK0 + PCON_DISABLE, NO_PUPDN, // CLK1_OUT -> + PCON_B137_B165(FUNC2, DISABLE), NO_PUPDN, // HDMI_HPD -> G1_HPD + PCON_DISABLE, NO_PUPDN, // HDMI_CEC -> G1_HDMI_CEC + PCON_DISABLE, NO_PUPDN, // FORCE_DFU -> FORCE_DFU + PCON_DISABLE, NO_PUPDN, // DFU_STATUS -> DFU_STATUS + PCON_FUNC2, NO_PUPDN, // I2C1_SCL -> G1_I2C1_SCL + PCON_FUNC2, NO_PUPDN // I2C1_SDA -> G1_I2C1_SDA + ), +/* P4 */ PINCONFIG( + PCON_FUNC2, NO_PUPDN, // UART2_RXD -> G1_UART_RXFROMPOD + PCON_FUNC2, NO_PUPDN, // UART2_TXD -> G1_UART_TXTOPOD + PCON_DISABLE, NO_PUPDN, // UART2_NRTS -> + PCON_DISABLE, NO_PUPDN, // UART2_NCTS -> + PCON_DISABLE, NO_PUPDN, // SPI1_CEN -> + PCON_DISABLE, NO_PUPDN, // SPI1_CLK -> + PCON_DISABLE, NO_PUPDN, // SPI1_MOSI -> + PCON_DISABLE, NO_PUPDN // SPI1_MISO -> BOARD_REV[2] + ), +/* P5 */ PINCONFIG( + PCON_FUNC2, NO_PUPDN, // UART1_RXD -> G1_UART_RXFROMACC + PCON_FUNC2, NO_PUPDN, // UART1_TXD -> G1_UART_TXTOACC + PCON_DISABLE, NO_PUPDN, // UART1_NRTS -> + PCON_B137_B165(DISABLE, OUT_1), NO_PUPDN, // UART1_NCTS -> DAC_RESETN + PCON_DISABLE, NO_PUPDN, // VGA_VDEN -> + PCON_DISABLE, NO_PUPDN, // VGA_HSYNC -> + PCON_DISABLE, NO_PUPDN, // VGA_VSYNC -> + PCON_DISABLE, NO_PUPDN // - -> + ), +}; + +/* default push-pull/open-drain configuration */ +#define DEFAULT_ODEN (0x00000007) // PoR Defaults + +/* default drive strength */ +#define DEFAULT_DSTR0 (0x00000555) // PoR Defaults + +#define DEFAULT_OSC_DSTR (0x00000004) + +#endif /* ! __TARGET_PINCONFIG_H */ diff --git a/target/iaccy1/include/target/uartconfig.h b/target/iaccy1/include/target/uartconfig.h new file mode 100644 index 0000000..8dbadc2 --- /dev/null +++ b/target/iaccy1/include/target/uartconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#endif diff --git a/target/iaccy1/init.c b/target/iaccy1/init.c new file mode 100644 index 0000000..35a28bd --- /dev/null +++ b/target/iaccy1/init.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2011-2012, 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetAcceptGlobalTicket, kOIDTypeBoolean, true); + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + +#if !RELEASE_BUILD + // API for B137 test harness to control G1 CLK0_OUT state + gpio_configure(GPIO_CLK0_OUT, GPIO_CFG_FUNC0); +#endif +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: { + break; + } + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + return 1; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +#if WITH_ENV + +void target_setup_default_environment(void) +{ +#if DEVELOPMENT_BUILD || DEBUG_BUILD + env_set("boot-args", "debug=0x14e serial=3 rd=md0", 0); + env_set("debug-uarts", "3", 0); +#else + env_set("boot-args", "rd=md0", 0); +#endif + env_set("auto-boot", "false", 0); + env_set("idle-off", "false", 0); +} + +#endif // WITH_ENV + +// Dummy function to make LIBENV happy. +int syscfgCopyDataForTag(u_int32_t tag, u_int8_t *buffer, size_t size) { +#pragma unused ( tag, buffer, size ) + return -1; +} + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/iaccy1/rules.mk b/target/iaccy1/rules.mk new file mode 100644 index 0000000..7d1f516 --- /dev/null +++ b/target/iaccy1/rules.mk @@ -0,0 +1,32 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + TARGET_DREX_CLK_RATIO=2 \ + TARGET_DREX_TIMING_AREF=0x0000005D \ + TARGET_DREX_TIMING_ROW=0x34488611 \ + TARGET_DREX_TIMING_DATA=0x36330306 \ + TARGET_DREX_TIMING_POWER=0x50380335 \ + TARGET_DREX_QOS_TIDEMARK=9 \ + TARGET_DREX_QOS_ACCESS=12 \ + TARGET_USB_DEVICE_SELF_POWERED=1 \ + WITH_BRIEF_BOOT_BANNER=1 + +ifeq ($(APPLICATION),iBoot) +OPTIONS += \ + DISABLE_CLEAR_MEMORY=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/display_get_info.o diff --git a/target/ipad2/include/target/amgconfig.h b/target/ipad2/include/target/amgconfig.h new file mode 100644 index 0000000..9ecc2fd --- /dev/null +++ b/target/ipad2/include/target/amgconfig.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amg_param struct is defined in drivers/apple/amg/amg.h, and this + * file should only by included from amg.c. + */ + +static const struct amg_params amc_phy_params = { + .flags = FLAG_AMG_PARAM_CAL_STATIC, + .core_config = 0x00001053, + .read_latency = 0x0000669b, + .gate_offset = 0x08080808, +}; diff --git a/target/ipad2/include/target/display_gamma_tables.h b/target/ipad2/include/target/display_gamma_tables.h new file mode 100644 index 0000000..57f241d --- /dev/null +++ b/target/ipad2/include/target/display_gamma_tables.h @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2010,2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_DISPLAY_GAMMA_TABLES_H +#define __TARGET_DISPLAY_GAMMA_TABLES_H + +/* K9x display gamma tables */ + +static const display_gamma_table ipad2_display_gamma_tables[] = +{ + { + 0x00960C49, 0x00FFFF7F, // LGD P5 table V0 + { + 0x62, 0xca, 0x1d, 0xd0, 0x1d, 0x00, 0x00, 0x0d, + 0x0d, 0x00, 0xc0, 0x1d, 0x77, 0xd3, 0x1d, 0x1c, + 0xc7, 0x71, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0x40, 0x03, 0x0d, 0x34, 0x34, + 0x0d, 0x0d, 0x00, 0x1c, 0x77, 0xdc, 0x71, 0x1c, + 0xc7, 0x71, 0xc7, 0xc1, 0x01, 0x70, 0xc0, 0x01, + 0x07, 0xc0, 0x01, 0x40, 0x00, 0x1c, 0x00, 0x1c, + 0x1c, 0xc7, 0xdd, 0x4d, 0xd3, 0x4d, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0xc7, 0x01, 0xd0, 0xd0, + 0x00, 0x00, 0x70, 0x77, 0x37, 0xdd, 0x74, 0xdc, + 0x71, 0xdc, 0x1d, 0x07, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x40, 0x03, 0x0d, + 0x4d, 0x43, 0x03, 0x1c, 0xc7, 0x1d, 0x77, 0x1c, + 0x07, 0xc7, 0xc1, 0x71, 0x00, 0x70, 0x00, 0x70, + 0x00, 0x00, 0x1c, 0xd0, 0x01, 0x00, 0x00, 0xc0, + 0x01, 0x07, 0x77, 0x77, 0x77, 0x13, 0x07, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0x77, 0x00, 0x40, 0x43, + 0x03, 0x0d, 0x07, 0x07, 0xc7, 0x1d, 0x07, 0x07, + 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, + 0x00, 0x0d, 0xd0, 0x34, 0x34, 0x0d, 0x4d, 0xd3, + 0x0d, 0x0d, 0xc0, 0x71, 0x1c, 0xc7, 0x71, 0x70, + 0x70, 0x1c, 0x1c, 0x00, 0x07, 0xc0, 0x01, 0x70, + 0x00, 0x1c, 0x00, 0x01, 0x1c, 0x00, 0x1c, 0x77, + 0xdc, 0x4d, 0x03, 0x0d, 0x00, 0x34, 0x4d, 0xd3, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00950C49, 0x00FFFF7F, // LGD P6 table V0 (same as P5) + { + 0x62, 0xca, 0x1d, 0xd0, 0x1d, 0x00, 0x00, 0x0d, + 0x0d, 0x00, 0xc0, 0x1d, 0x77, 0xd3, 0x1d, 0x1c, + 0xc7, 0x71, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0x40, 0x03, 0x0d, 0x34, 0x34, + 0x0d, 0x0d, 0x00, 0x1c, 0x77, 0xdc, 0x71, 0x1c, + 0xc7, 0x71, 0xc7, 0xc1, 0x01, 0x70, 0xc0, 0x01, + 0x07, 0xc0, 0x01, 0x40, 0x00, 0x1c, 0x00, 0x1c, + 0x1c, 0xc7, 0xdd, 0x4d, 0xd3, 0x4d, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0xc7, 0x01, 0xd0, 0xd0, + 0x00, 0x00, 0x70, 0x77, 0x37, 0xdd, 0x74, 0xdc, + 0x71, 0xdc, 0x1d, 0x07, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x40, 0x03, 0x0d, + 0x4d, 0x43, 0x03, 0x1c, 0xc7, 0x1d, 0x77, 0x1c, + 0x07, 0xc7, 0xc1, 0x71, 0x00, 0x70, 0x00, 0x70, + 0x00, 0x00, 0x1c, 0xd0, 0x01, 0x00, 0x00, 0xc0, + 0x01, 0x07, 0x77, 0x77, 0x77, 0x13, 0x07, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0x77, 0x00, 0x40, 0x43, + 0x03, 0x0d, 0x07, 0x07, 0xc7, 0x1d, 0x07, 0x07, + 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, + 0x00, 0x0d, 0xd0, 0x34, 0x34, 0x0d, 0x4d, 0xd3, + 0x0d, 0x0d, 0xc0, 0x71, 0x1c, 0xc7, 0x71, 0x70, + 0x70, 0x1c, 0x1c, 0x00, 0x07, 0xc0, 0x01, 0x70, + 0x00, 0x1c, 0x00, 0x01, 0x1c, 0x00, 0x1c, 0x77, + 0xdc, 0x4d, 0x03, 0x0d, 0x00, 0x34, 0x4d, 0xd3, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00970C49, 0x00FFFF7F, // LGD P3 table V0 + { + 0x62, 0xca, 0x04, 0x00, 0x71, 0x00, 0x40, 0x03, + 0x0d, 0x00, 0x70, 0xdc, 0xdd, 0xdd, 0x1d, 0x07, + 0x07, 0xc7, 0x01, 0xd7, 0x00, 0x00, 0x00, 0xd0, + 0xd0, 0x40, 0x43, 0x37, 0xdd, 0x34, 0xdd, 0x74, + 0x37, 0x0d, 0x00, 0xc7, 0x1d, 0x77, 0x1c, 0x1c, + 0x1c, 0xc7, 0xc1, 0x01, 0x70, 0xc0, 0x01, 0x07, + 0xc0, 0x01, 0x47, 0x07, 0x00, 0x1c, 0xc0, 0x1d, + 0xc7, 0xdd, 0x40, 0x03, 0xd0, 0x40, 0x77, 0x77, + 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x74, 0xd0, 0x04, 0x07, 0x00, 0x0d, + 0x00, 0x00, 0x70, 0x77, 0x77, 0xd3, 0xdd, 0x71, + 0x70, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x03, 0x0d, 0x34, 0x74, 0xd3, 0x34, 0xdd, 0x74, + 0x77, 0xd3, 0x00, 0xc7, 0x71, 0xc7, 0x71, 0x70, + 0x70, 0x1c, 0x1c, 0x70, 0x00, 0x70, 0x00, 0x70, + 0x00, 0x70, 0x00, 0x04, 0x00, 0x00, 0x70, 0x70, + 0x1c, 0x77, 0x37, 0x34, 0xd0, 0xd0, 0xdd, 0xdd, + 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x74, 0x0d, 0x1d, 0x07, 0xd0, 0x40, + 0x03, 0x00, 0x00, 0x07, 0x1c, 0xc7, 0x01, 0xc0, + 0x01, 0xc0, 0x01, 0x0d, 0x34, 0x00, 0x34, 0x4d, + 0x37, 0x4d, 0xd3, 0xdd, 0xdd, 0xdd, 0x1d, 0x77, + 0x37, 0x7d, 0x70, 0x1c, 0x1c, 0xc7, 0x01, 0x07, + 0x1c, 0x1c, 0x00, 0x1c, 0xc0, 0x01, 0x1c, 0xc0, + 0x01, 0x1c, 0x1d, 0x00, 0x70, 0x70, 0xdc, 0x4d, + 0x37, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00E40C49, 0x00FFFF7F, // Samsung 6mask table V0 + { + 0x62, 0xca, 0x74, 0xd0, 0x04, 0x07, 0x00, 0x0d, + 0xd0, 0x00, 0x1c, 0x1c, 0x1c, 0x77, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0x43, 0x43, 0x43, 0xd3, + 0x40, 0x03, 0x0d, 0x34, 0x00, 0x0d, 0x00, 0x34, + 0x00, 0x00, 0x34, 0x00, 0x34, 0x00, 0x1c, 0x70, + 0x70, 0x1c, 0x1c, 0x07, 0xc7, 0x71, 0x77, 0x77, + 0xd3, 0x74, 0xd3, 0x01, 0x00, 0x00, 0x40, 0x43, + 0x77, 0x77, 0x77, 0x07, 0xc7, 0xc1, 0x41, 0x43, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x00, 0x1d, 0xb0, 0x32, 0x00, + 0x0d, 0x40, 0x1f, 0x70, 0xdc, 0x71, 0xc7, 0x01, + 0x1c, 0x00, 0x07, 0x40, 0x43, 0x03, 0x34, 0x40, + 0x03, 0x0d, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x70, + 0x70, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x77, + 0x77, 0xd3, 0x4d, 0x77, 0x07, 0x00, 0x00, 0xd0, + 0x74, 0x77, 0x1c, 0x07, 0x1c, 0x00, 0xd0, 0xdd, + 0x71, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x74, 0x00, 0xdd, 0x01, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x34, + 0x40, 0x03, 0x74, 0x37, 0xdd, 0x74, 0x37, 0xdd, + 0x34, 0x4d, 0xd3, 0xd0, 0x40, 0x43, 0x03, 0x0d, + 0xd0, 0x40, 0x03, 0x0d, 0x34, 0x1c, 0xc0, 0x01, + 0x07, 0x1c, 0x1c, 0x1c, 0x1c, 0x77, 0x37, 0xdd, + 0x4d, 0x77, 0x07, 0x00, 0x00, 0x00, 0x40, 0xd3, + 0x34, 0x34, 0xdd, 0x34, 0x4d, 0xd3, 0x34, 0xdd, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00E30C49, 0x00FFFF7F, // Samsung 5mask table V0 + { + 0x22, 0xce, 0x4d, 0x07, 0xd0, 0x74, 0x1c, 0x1c, + 0x1c, 0x1c, 0xd3, 0xdd, 0xdd, 0x34, 0xdd, 0x74, + 0x07, 0x1c, 0x1c, 0x1c, 0x00, 0x0d, 0xd0, 0x00, + 0x34, 0x0d, 0x0d, 0x34, 0xd0, 0x40, 0x03, 0x34, + 0xd0, 0x40, 0x03, 0x34, 0x34, 0x0d, 0x0d, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0xc0, 0x71, + 0x1c, 0x77, 0xc7, 0x1d, 0x00, 0xd0, 0x00, 0x4d, + 0x07, 0x07, 0x1c, 0x00, 0x00, 0x00, 0xd0, 0x1d, + 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0xce, 0x4d, 0x07, 0x40, 0x77, 0x07, 0x07, + 0xc7, 0x71, 0x37, 0xdd, 0x74, 0xd3, 0x34, 0x74, + 0xc7, 0xc1, 0x71, 0x07, 0x07, 0x0d, 0x00, 0x40, + 0x03, 0x34, 0x40, 0x03, 0xd0, 0x00, 0x0d, 0x00, + 0x0d, 0xd0, 0x00, 0x34, 0xd0, 0xd0, 0x40, 0x03, + 0x00, 0x07, 0xc0, 0x01, 0x00, 0x1c, 0x00, 0x07, + 0xc7, 0x1d, 0x77, 0xdc, 0x41, 0x43, 0x43, 0xd3, + 0x71, 0x00, 0x1c, 0x00, 0x0d, 0xd0, 0xc4, 0x01, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0xce, 0x0d, 0x01, 0x40, 0x13, 0x77, 0x70, + 0xc0, 0xc1, 0x1d, 0xc7, 0x71, 0xc7, 0xdd, 0x71, + 0x00, 0x00, 0x07, 0x00, 0x4d, 0xd3, 0xd0, 0x34, + 0x4d, 0x37, 0x4d, 0xd3, 0x34, 0x34, 0x34, 0x4d, + 0x43, 0xd3, 0xd0, 0x74, 0xd3, 0x34, 0x00, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x07, 0x70, 0xdc, + 0x1d, 0x77, 0x07, 0x00, 0x00, 0x0d, 0xd0, 0x74, + 0xdc, 0xdd, 0x1d, 0x77, 0xdc, 0x71, 0x1c, 0x77, + 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00890C49, 0x00FFFF7F, // CMI T1 table V0 + { + 0x62, 0xca, 0x01, 0x74, 0x00, 0xd0, 0xdd, 0x1d, + 0x77, 0x4c, 0x43, 0x03, 0x40, 0xd3, 0xdd, 0xdd, + 0x1d, 0xc7, 0xc1, 0x1d, 0xc7, 0x71, 0x77, 0x77, + 0x77, 0xd3, 0x34, 0x0d, 0x0d, 0x0d, 0x34, 0xd0, + 0x00, 0x34, 0x00, 0x70, 0x70, 0xc7, 0x71, 0xdc, + 0x1d, 0x77, 0x77, 0x77, 0x43, 0x03, 0xd0, 0x00, + 0xd0, 0x74, 0x1c, 0x77, 0xdc, 0xc1, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x4d, 0xd3, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x01, 0x74, 0x00, 0xd0, 0x74, 0xdc, + 0x71, 0xd3, 0x34, 0x00, 0xd0, 0xd0, 0xdd, 0xdd, + 0xdd, 0x1d, 0x1c, 0xc7, 0x1d, 0xc7, 0xdd, 0xdd, + 0xdd, 0x74, 0x43, 0xd3, 0x34, 0x34, 0x34, 0x40, + 0x03, 0x34, 0x00, 0xc0, 0x71, 0x1c, 0xc7, 0x71, + 0xc7, 0xdd, 0x1d, 0x37, 0x0d, 0x34, 0x40, 0x03, + 0xd0, 0x74, 0x1c, 0x77, 0x1c, 0x07, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x40, 0xd3, 0x34, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x01, 0x74, 0x00, 0xd0, 0x74, 0xdc, + 0x71, 0x77, 0xd3, 0xd0, 0xd0, 0x74, 0xdc, 0x1d, + 0x77, 0x70, 0x70, 0x70, 0x1c, 0x1c, 0x77, 0xdc, + 0xdd, 0x4d, 0x37, 0x4d, 0xd3, 0x34, 0x34, 0x0d, + 0x0d, 0x34, 0x00, 0x70, 0x1c, 0x07, 0xc7, 0x1d, + 0xc7, 0x1d, 0x77, 0x37, 0x34, 0xd0, 0x00, 0x0d, + 0x74, 0xc7, 0x71, 0xc7, 0x71, 0x00, 0x07, 0x00, + 0x1c, 0x00, 0x70, 0x00, 0x1c, 0x00, 0xc0, 0x01, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00900C49, 0x00FFFF7F, // CMI T1x table V0 + { + 0x26, 0x11, 0x07, 0xd0, 0x1d, 0x00, 0x00, 0xdd, + 0xdd, 0xc1, 0x01, 0x07, 0x1c, 0x1c, 0xc7, 0xdd, + 0x34, 0x34, 0xd0, 0x00, 0x0d, 0x34, 0x00, 0x0d, + 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x70, 0xc0, 0xc1, 0xc1, 0xc1, + 0xc1, 0x71, 0x1c, 0x77, 0xdc, 0x71, 0x1c, 0x07, + 0xc7, 0x71, 0x70, 0x1c, 0x1c, 0x40, 0x1c, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0xd1, 0x1d, 0xd0, 0x74, 0x1c, 0x00, 0x34, + 0x4d, 0xc7, 0x1d, 0xc7, 0x1d, 0x77, 0x77, 0xd3, + 0xd0, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x07, 0x70, + 0xc0, 0x01, 0x00, 0x07, 0x70, 0x00, 0x07, 0xc0, + 0x01, 0x1c, 0xc0, 0x01, 0x07, 0x1c, 0xc7, 0x71, + 0x1c, 0x77, 0xdc, 0x1d, 0x77, 0x77, 0x77, 0xc7, + 0xdd, 0x71, 0x77, 0xdc, 0x71, 0xc7, 0x1d, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x41, 0x77, 0x00, 0x74, 0x77, 0x00, 0x00, + 0x40, 0xd3, 0x4d, 0x77, 0x37, 0xdd, 0x34, 0x0d, + 0x40, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xc0, + 0x01, 0x70, 0x00, 0x1c, 0x70, 0xc0, 0xc1, 0x71, + 0x1c, 0xc7, 0xc1, 0xc1, 0x71, 0x1c, 0xc7, 0xc1, + 0x71, 0x1c, 0x1c, 0x77, 0x1c, 0x77, 0xdc, 0xdd, + 0x31, 0xdd, 0xdd, 0x4d, 0x37, 0x4d, 0x43, 0xd3, + 0x34, 0x4d, 0xd3, 0xd0, 0x34, 0x34, 0x34, 0x34, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, +}; + +#endif diff --git a/target/ipad2/include/target/gpiodef.h b/target/ipad2/include/target/gpiodef.h new file mode 100644 index 0000000..77fc662 --- /dev/null +++ b/target/ipad2/include/target/gpiodef.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* K93 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_RST GPIO(17, 7) +#define GPIO_LCD_RST_POLARITY (0) +#define GPIO_LCD_PWR_EN GPIO(18, 1) + +#define GPIO_RINGER_AB GPIO( 6, 2) + +#define POWER_GPIO_BATTERY_SWI (5) +#define POWER_GPIO_BATTERY_SWI_CONFIG_OUTPUT 0x03 +#define POWER_GPIO_BATTERY_SWI_CONFIG_INPUT 0xD8 + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 5, 0) +#define GPIO_BOARD_REV1 GPIO( 5, 1) +#define GPIO_BOARD_REV2 GPIO( 5, 2) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +/* D1946 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad2/include/target/nand_spec_tables.h b/target/ipad2/include/target/nand_spec_tables.h new file mode 100644 index 0000000..d12c230 --- /dev/null +++ b/target/ipad2/include/target/nand_spec_tables.h @@ -0,0 +1,1464 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* blocksPerCS */ 4152, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 640, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_SAMSUNG_MLC_8K, + /* diesPerCS */ 1 + }, + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x7A }, + /* blocksPerCS */ 8304, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 640, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_SAMSUNG_MLC_8K, + /* diesPerCS */ 2 + }, + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* blocksPerCS */ 4152, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 436, + /* eccPer512Bytes */ 12, + /* initialBBType */ INIT_BBT_SAMSUNG_MLC_8K, + /* diesPerCS */ 1 + }, + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* blocksPerCS */ 8304, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 436, + /* eccPer512Bytes */ 12, + /* initialBBType */ INIT_BBT_SAMSUNG_MLC_8K, + /* diesPerCS */ 2 + }, + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* blocksPerCS */ 4100, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_TOSHIBA_MLC, + /* diesPerCS */ 1 + }, + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* blocksPerCS */ 8200, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 24, + /* initialBBType */ INIT_BBT_TOSHIBA_MLC, + /* diesPerCS */ 2 + }, + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* blocksPerCS */ 4096, + /* pagesPerBlock */ 256, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 24, + /* initialBBType */ INIT_BBT_MICRON_ONFI, + /* diesPerCS */ 1 + }, + { + /* chipId */ { 0x45, 0x48, 0x94, 0x32 }, + /* blocksPerCS */ 4096, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 8, + /* initialBBType */ INIT_BBT_SANDISK_MLC, + /* diesPerCS */ 1 + }, + { + /* chipId */ { 0x45, 0x68, 0x95, 0x32 }, + /* blocksPerCS */ 8192, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 8, + /* initialBBType */ INIT_BBT_SANDISK_MLC, + /* diesPerCS */ 2 + }, + { + /* chipId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* blocksPerCS */ 4096, + /* pagesPerBlock */ 256, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 640, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_SANDISK_MLC, + /* diesPerCS */ 1 + }, + { + /* chipId */ { 0x45, 0x4D, 0x94, 0x82 }, + /* blocksPerCS */ 4096, + /* pagesPerBlock */ 256, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 640, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_SANDISK_MLC, + /* diesPerCS */ 1 + }, + { + /* chipId */ { 0x45, 0x29, 0x94, 0x32 }, + /* blocksPerCS */ 4096, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 640, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_SANDISK_MLC, + /* diesPerCS */ 1 + } +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x7A }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x7A }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 30, + /* writeSetupNanosecs */ 15, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 30, + /* readSetupNanosecs */ 15, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 25, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 30, + /* writeSetupNanosecs */ 15, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 30, + /* readSetupNanosecs */ 15, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 25, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 30, + /* writeSetupNanosecs */ 15, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 30, + /* readSetupNanosecs */ 15, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 25, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 30, + /* writeSetupNanosecs */ 15, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 30, + /* readSetupNanosecs */ 15, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 25, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 8 + } + } + }, + /* writeCycleNanosecs */ 30, + /* writeSetupNanosecs */ 15, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 30, + /* readSetupNanosecs */ 15, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 25, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 8 + }, + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 8 + } + } + }, + /* writeCycleNanosecs */ 30, + /* writeSetupNanosecs */ 15, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 30, + /* readSetupNanosecs */ 15, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 25, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 8 + }, + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 8 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 20, + /* writeSetupNanosecs */ 10, + /* writeHoldNanosecs */ 7, + /* readCycleNanosecs */ 20, + /* readSetupNanosecs */ 10, + /* readHoldNanosecs */ 7, + /* readDelayNanosecs */ 16, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 2 + }, + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 20, + /* writeSetupNanosecs */ 10, + /* writeHoldNanosecs */ 7, + /* readCycleNanosecs */ 20, + /* readSetupNanosecs */ 10, + /* readHoldNanosecs */ 7, + /* readDelayNanosecs */ 16, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 20, + /* writeSetupNanosecs */ 10, + /* writeHoldNanosecs */ 7, + /* readCycleNanosecs */ 20, + /* readSetupNanosecs */ 10, + /* readHoldNanosecs */ 7, + /* readDelayNanosecs */ 16, + /* readValidNanosecs */ 15 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* ceCnt */ 2 + }, + { + /* chipId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x48, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x68, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x4D, 0x94, 0x82 }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0x45, 0x4D, 0x94, 0x82 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x29, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 20, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 20, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x48, 0x94, 0x32 }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0x45, 0x48, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x68, 0x95, 0x32 }, + /* ceCnt */ 4 + }, + { + /* chipId */ { 0x45, 0x68, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + } +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* die */ "27nm", + /* vendor_name */ "Samsung" + }, + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x7A }, + /* die */ "27nm", + /* vendor_name */ "Samsung" + }, + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* die */ "35nm", + /* vendor_name */ "Samsung" + }, + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* die */ "35nm", + /* vendor_name */ "Samsung" + }, + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Toshiba" + }, + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Toshiba" + }, + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* die */ "25nm", + /* vendor_name */ "Micron" + }, + { + /* chipId */ { 0x45, 0x48, 0x94, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Sandisk" + }, + { + /* chipId */ { 0x45, 0x68, 0x95, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Sandisk" + }, + { + /* chipId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* die */ "24nm", + /* vendor_name */ "Sandisk" + }, + { + /* chipId */ { 0x45, 0x4D, 0x94, 0x82 }, + /* die */ "24nm", + /* vendor_name */ "Sandisk" + }, + { + /* chipId */ { 0x45, 0x29, 0x94, 0x32 }, + /* die */ "24nm", + /* vendor_name */ "Sandisk" + } +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ + { + /* packageId */ + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* ceCnt */ 4 + }, + /* appleName */ "TBD", + /* vendor_part_num */ "K9HDG08U5A-L", + /* package_type */ "QDP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x7A }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0791", + /* vendor_part_num */ "K9PFG08U5A-L", + /* package_type */ "ODP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0682", + /* vendor_part_num */ "K9HDG08U5M-LCB0", + /* package_type */ "QDP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0665", + /* vendor_part_num */ "K9PEG08U5M-LCB0", + /* package_type */ "ODP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 8 + }, + /* appleName */ "335S0707", + /* vendor_part_num */ "K9UHG08U8M-LCB0", + /* package_type */ "16DP", + /* package_size */ "1.40mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0701", + /* vendor_part_num */ "TH58NVG7D2FLA89", + /* package_type */ "QDP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0702", + /* vendor_part_num */ "TH58NVG8D2FLA89", + /* package_type */ "ODP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 8 + }, + /* appleName */ "335S0708", + /* vendor_part_num */ "TH58NVG9D2FLAB7", + /* package_type */ "16DP", + /* package_size */ "1.40mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 2 + }, + /* appleName */ "335S0766", + /* vendor_part_num */ "MT29F128G08CEAAAC5", + /* package_type */ "DDP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0767", + /* vendor_part_num */ "MT29F256G08CMAAAC5", + /* package_type */ "QDP", + /* package_size */ "1.00mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x45, 0x48, 0x94, 0x32 }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0721", + /* vendor_part_num */ "SDZNNMCHER-016G", + /* package_type */ "QDP", + /* package_size */ "1mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x45, 0x68, 0x95, 0x32 }, + /* ceCnt */ 4 + }, + /* appleName */ "335S0722", + /* vendor_part_num */ "SDZNNMDHER-032G", + /* package_type */ "ODP", + /* package_size */ "1mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* ceCnt */ 2 + }, + /* appleName */ "TBD", + /* vendor_part_num */ "SDZNOQBHER-016G", + /* package_type */ "DDP", + /* package_size */ "1mm LGA" + }, + { + /* packageId */ + { + /* chipId */ { 0x45, 0x4D, 0x94, 0x82 }, + /* ceCnt */ 4 + }, + /* appleName */ "TBD", + /* vendor_part_num */ "SDZNOQCHER-032G", + /* package_type */ "QDP", + /* package_size */ "1mm LGA" + } +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0xEC, 0xD7, 0x94, 0x7A }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x7A }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x7A }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xD7, 0x94, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 8 + }, + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 8 + } + } + }, + /* vsType */ FIL_VS_SIMPLE + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0xEC, 0xDE, 0xD5, 0x72 }, + /* ceCnt */ 8 + } + } + }, + /* vsType */ FIL_VS_HYNIX_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 8 + }, + { + /* deviceId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 8 + } + } + }, + /* vsType */ FIL_VS_SIMPLE + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0x98, 0xEE, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_ONFI_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 2 + }, + { + /* deviceId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_ONFI_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0x2C, 0x88, 0x04, 0x4B }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_ONFI_2P + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x4D, 0x94, 0x82 }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0x45, 0x4D, 0x94, 0x82 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x29, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x48, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* ceCnt */ 2 + }, + { + /* deviceId */ { 0x45, 0x2D, 0x94, 0x82 }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x48, 0x94, 0x32 }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0x45, 0x48, 0x94, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x68, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + }, + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 2, + /* packageIds[] */ + { + { + /* deviceId */ { 0x45, 0x68, 0x95, 0x32 }, + /* ceCnt */ 4 + }, + { + /* deviceId */ { 0x45, 0x68, 0x95, 0x32 }, + /* ceCnt */ 4 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + } +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 3, + /* socToNandFallNanosecs */ 3, + /* nandToSocRiseNanosecs */ 5, + /* nandToSocFallNanosecs */ 5, + + /* landing map */ + { + 0x00003333, + 0x0000CCCC + }, + + /* useToggleMode */ FALSE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ FALSE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ FALSE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 0 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/ipad2/include/target/pinconfig.h b/target/ipad2/include/target/pinconfig.h new file mode 100644 index 0000000..75d041f --- /dev/null +++ b/target/ipad2/include/target/pinconfig.h @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default K93/K94 SoC Pin Configuration, v1.2 */ + +#if PIN_CFG_AP +#define HI_DRIVE_STR DRIVE_X3 +#define GPIO_DRIVE_STR DRIVE_X2 +#elif PIN_CFG_DEV +#define HI_DRIVE_STR DRIVE_X4 +#define GPIO_DRIVE_STR DRIVE_X2 +#endif + +#define BB_DRIVE_STR HI_DRIVE_STR +#define BT_DRIVE_STR HI_DRIVE_STR +#define SWI_DRIVE_STR HI_DRIVE_STR +#define GPS_DRIVE_STR HI_DRIVE_STR +#define FMI_DRIVE_STR HI_DRIVE_STR +#define SPI_DRIVE_STR HI_DRIVE_STR +#define SPI_CS_DRIVE_STR GPIO_DRIVE_STR +#define I2C_DRIVE_STR HI_DRIVE_STR +#define DWI_DRIVE_STR HI_DRIVE_STR +#define I2S_DRIVE_STR HI_DRIVE_STR +#define SDIO_DRIVE_STR HI_DRIVE_STR +#define CAM_DRIVE_STR HI_DRIVE_STR +#define UART_DRIVE_STR HI_DRIVE_STR + +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO7 -> PM_BT_WAKE + +/* Port 1 */ + CFG_DISABLED, // GPIO8 -> +#if SUB_TARGET_K93 + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> +#else +#if SUB_TARGET_K94 + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO9 -> PM_RADIO_ON +#else + CFG_IN, // GPIO9 -> PM_RADIO_ON +#endif + CFG_DISABLED, // GPIO10 -> + CFG_IN, // GPIO11 -> RST_DET_L + CFG_IN, // GPIO12 -> SPI_IPC_SRDY +#endif + CFG_IN | PULL_UP, // GPIO13 -> IRQ_PMU_L + CFG_DISABLED, // GPIO14 -> + CFG_IN | PULL_UP, // GPIO15 -> IRQ_CODEC_L + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_IN | PULL_DOWN, // GPIO17 -> IRQ_GYRO_INT2 + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO19 -> PM_KEEPACT + CFG_DISABLED, // GPIO20 -> + CFG_IN | PULL_UP, // GPIO21 -> IRQ_GRAPE_HOST_INT_L + CFG_DISABLED, // GPIO22 -> +#if SUB_TARGET_K93 + CFG_DISABLED, // GPIO23 -> +#else + CFG_IN, // GPIO23 -> GPS_SYNC +#endif + +/* Port 3 */ + CFG_DISABLED, // GPIO24 -> GSM_TXBURST_IND + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN, // GPIO26 -> FORCE_DFU + CFG_OUT_0, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] +#if SUB_TARGET_K93 + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> +#else + CFG_OUT_1 | GPIO_DRIVE_STR, // GPIO30 -> RST_GPS_L + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO31 -> PM_GPS_STANDBY +#endif + +/* Port 4 */ +#if SUB_TARGET_K93 + CFG_DISABLED, // GPIO32 -> +#else + CFG_IN, // GPIO32 -> IRQ_PROX_INT_L +#endif + CFG_IN | PULL_DOWN, // GPIO33 -> IRQ_GYRO_INT1 + CFG_DISABLED, // GPIO34 -> IRQ_GPS_INT_L + CFG_DISABLED, // GPIO35 -> + CFG_IN | PULL_UP, // GPIO36 -> IRQ_ACCEL_INT1_L + CFG_IN | PULL_UP, // GPIO37 -> IRQ_ALS_INT_L + CFG_IN | PULL_UP, // GPIO38 -> IRQ_ACCEL_INT2_L + CFG_OUT_0, // GPIO39 -> AUD_SPKRAMP_MUTE_L + +/* Port 5 */ + CFG_DISABLED, // EHCI_PORT_PWR[0] -> BOARD_REV0 + CFG_DISABLED, // EHCI_PORT_PWR[1] -> BOARD_REV1 + CFG_DISABLED, // EHCI_PORT_PWR[2] -> BOARD_REV2 +#if SUB_TARGET_K93 + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> +#else +#if SUB_TARGET_K94 + CFG_FUNC0 | BB_DRIVE_STR, // UART1_TXD -> UART_AP_1_TXD (BB USART) + // Add pullup to BB UART RX pin to work around glitch during baseband updates (Sundance) + CFG_FUNC0 | PULL_UP, // UART1_RXD -> UART_AP_1_RXD +#else + CFG_OUT_0 | BB_DRIVE_STR, // UART1_TXD -> UART_AP_1_TXD (BB USART) + CFG_FUNC0, // UART1_RXD -> UART_AP_1_RXD +#endif + CFG_FUNC0 | BB_DRIVE_STR, // UART1_RTSN -> UART_AP_1_RTS_L + CFG_FUNC0, // UART1_CTSN -> UART_AP_1_CTS_L + CFG_FUNC0 | BB_DRIVE_STR, // UART2_TXD -> UART_AP_2_TXD (BB UMTS) +#endif + +/* Port 6 */ +#if SUB_TARGET_K93 + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> +#else + CFG_FUNC0, // UART2_RXD -> UART_AP_2_RXD +#if SUB_TARGET_K94 + CFG_OUT_1 | GPIO_DRIVE_STR, // UART2_RTSN -> RST_BB_L +#else + CFG_IN, // UART2_RTSN -> RST_BB_L +#endif +#endif + CFG_IN, // UART2_CTSN -> SRL_L + CFG_FUNC0 | BT_DRIVE_STR, // UART3_TXD -> UART_AP_3_TXD (BT) + CFG_FUNC0, // UART3_RXD -> UART_AP_3_RXD + CFG_OUT_1 | BT_DRIVE_STR, // UART3_RTSN -> UART_AP_3_RTS_L + CFG_FUNC0, // UART3_CTSN -> UART_AP_3_CTS_L + CFG_FUNC0 | SWI_DRIVE_STR, // UART5_RTXD -> BATTERY_SWI + +/* Port 7 */ + CFG_DISABLED, // UART6_TXD -> + CFG_IN | PULL_UP, // UART6_RXD -> AUD_VOL_UP_L +#if SUB_TARGET_K95 + CFG_OUT_0, // UART6_RTSN -> IPC_GPIO +#else + CFG_DISABLED, // UART6_RTSN -> +#endif + CFG_IN | PULL_UP, // UART6_CTSN -> AUD_VOL_DOWN_L +#if SUB_TARGET_K93 + CFG_DISABLED, // UART4_TXD -> UART_AP_4_TXD (GPS) + CFG_DISABLED, // UART4_RXD -> UART_AP_4_RXD + CFG_DISABLED, // UART4_RTSN -> UART_AP_4_RTS_L + CFG_DISABLED, // UART4_CTSN -> UART_AP_4_CTS_L +#else + CFG_FUNC0 | GPS_DRIVE_STR, // UART4_TXD -> UART_AP_4_TXD (GPS) + CFG_FUNC0, // UART4_RXD -> UART_AP_4_RXD + CFG_FUNC0 | GPS_DRIVE_STR, // UART4_RTSN -> UART_AP_4_RTS_L + CFG_FUNC0, // UART4_CTSN -> UART_AP_4_CTS_L +#endif + +/* Port 8 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_REN -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_WEN -> + +/* Port 9 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED, // FMI0_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO1 -> + +/* Port 10 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_REN -> + +/* Port 11 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED, // FMI1_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO2 -> + +/* Port 12 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED, // FMI2_CEN3 -> + CFG_DISABLED, // FMI2_CEN2 -> + CFG_DISABLED, // FMI2_CEN1 -> + CFG_DISABLED, // FMI2_CEN0 -> + CFG_DISABLED, // FMI2_CLE -> + CFG_DISABLED, // FMI2_ALE -> + +/* Port 13 */ + CFG_DISABLED, // FMI2_REN -> + CFG_DISABLED, // FMI2_WEN -> + CFG_DISABLED, // FMI2_IO7 -> + CFG_DISABLED, // FMI2_IO6 -> + CFG_DISABLED, // FMI2_IO5 -> + CFG_DISABLED, // FMI2_IO4 -> + CFG_DISABLED, // FMI2_DQS -> + CFG_DISABLED, // FMI2_IO3 -> + +/* Port 14 */ + CFG_DISABLED, // FMI2_IO2 -> + CFG_DISABLED, // FMI2_IO1 -> + CFG_DISABLED, // FMI2_IO0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN7 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN6 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN5 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN4 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN7 -> + +/* Port 15 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN6 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN5 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN4 -> + CFG_DISABLED, // FMI3_CEN3 -> + CFG_DISABLED, // FMI3_CEN2 -> + CFG_DISABLED, // FMI3_CEN1 -> + CFG_DISABLED, // FMI3_CEN0 -> + CFG_DISABLED, // FMI3_CLE -> + +/* Port 16 */ + CFG_DISABLED, // FMI3_ALE -> + CFG_DISABLED, // FMI3_REN -> + CFG_DISABLED, // FMI3_WEN -> + CFG_DISABLED, // FMI3_IO7 -> + CFG_DISABLED, // FMI3_IO6 -> + CFG_DISABLED, // FMI3_IO5 -> + CFG_DISABLED, // FMI3_IO4 -> + CFG_DISABLED, // FMI3_DQS -> + +/* Port 17 */ + CFG_DISABLED, // FMI3_IO3 -> + CFG_DISABLED, // FMI3_IO2 -> + CFG_DISABLED, // FMI3_IO1 -> + CFG_DISABLED, // FMI3_IO0 -> + CFG_OUT_1 | GPIO_DRIVE_STR, // FMI2_CEN7 -> GRAPE_FW_DNLD_EN_L + CFG_DISABLED, // FMI2_CEN6 -> RST_GRAPE_L + CFG_DISABLED, // FMI2_CEN5 -> + CFG_OUT_0 | GPIO_DRIVE_STR, // FMI2_CEN4 -> RST_MLC_L + +/* Port 18 */ + CFG_DISABLED, // FMI3_CEN7 -> + CFG_OUT_0 | GPIO_DRIVE_STR, // FMI3_CEN6 -> PM_MLC_PWR_EN + CFG_OUT_0, // FMI3_CEN5 -> SD_RESET_L + CFG_DISABLED, // FMI3_CEN4 -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + +/* Port 19 */ + CFG_FUNC0, // ISP0_PRE_FLASH -> + CFG_FUNC0, // ISP0_FLASH -> + CFG_FUNC0, // ISP1_PRE_FLASH -> + CFG_FUNC0, // ISP1_FLASH -> + CFG_FUNC0 | SPI_DRIVE_STR, // SPI1_SCLK -> SPI_GRAPE_SCLK + CFG_FUNC0 | SPI_DRIVE_STR, // SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SPI_CS_DRIVE_STR, // SPI1_SSIN -> SPI_GRAPE_CS_L + +/* Port 20 */ + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SDA -> I2C2_SDA_3V0 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SCL -> I2C2_SCL_3V0 + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> SPI0_SSIN +#if SUB_TARGET_K93 + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> +#else + CFG_FUNC0 | SPI_DRIVE_STR, // SPI2_SCLK -> SPI_IPC_SCLK + CFG_FUNC0 | SPI_DRIVE_STR, // SPI2_MOSI -> SPI_IPC_MOSI +#endif + +/* Port 21 */ +#if SUB_TARGET_K93 + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> +#else + CFG_FUNC0, // SPI2_MISO -> SPI_IPC_MISO + CFG_OUT_0 | SPI_CS_DRIVE_STR, // SPI2_SSIN -> SPI_IPC_MRDY +#endif + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // ISP0_SDA -> ISP_AP_0_SDA + CFG_FUNC0 | I2C_DRIVE_STR, // ISP0_SCL -> ISP_AP_0_SCL + +/* Port 22 */ + CFG_FUNC0 | I2C_DRIVE_STR, // ISP1_SDA -> ISP_AP_1_SDA + CFG_FUNC0 | I2C_DRIVE_STR, // ISP1_SCL -> ISP_AP_1_SCL + CFG_FUNC0 | SDIO_DRIVE_STR, // SDIO_CLK -> + CFG_FUNC0 | PULL_UP | SDIO_DRIVE_STR, // SDIO_CMD -> + CFG_FUNC0 | PULL_UP | SDIO_DRIVE_STR, // SDIO_DATA0 -> + CFG_FUNC0 | PULL_UP | SDIO_DRIVE_STR, // SDIO_DATA1 -> + CFG_FUNC0 | PULL_UP | SDIO_DRIVE_STR, // SDIO_DATA2 -> + CFG_FUNC0 | PULL_UP | SDIO_DRIVE_STR, // SDIO_DATA3 -> + +/* Port 23 */ + CFG_DISABLED, // MIPI_VSYNC -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // SWI_DATA -> + CFG_FUNC0 | PULL_DOWN, // DWI_DI -> + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> + +/* Port 24 */ + CFG_OUT_0 | GPIO_DRIVE_STR, // SENSOR0_RST -> PM_REAR_CAM_SHUTDOWN + CFG_OUT_0 | CAM_DRIVE_STR, // SENSOR0_CLK -> CLK_CAM_RF + CFG_OUT_1 | GPIO_DRIVE_STR, // SENSOR1_RST -> PM_FRONT_CAM_SHUTDOWN + CFG_OUT_0 | CAM_DRIVE_STR, // SENSOR1_CLK -> CLK_CAM_FF + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_MCK -> I2S_AP_0_MCL (codec ASP) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> I2S_AP_0_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_BCLK -> I2S_AP_0_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> I2S_AP_0_DOUT + +/* Port 25 */ + CFG_FUNC0, // I2S0_DIN -> I2S_AP_0_DIN + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_MCK -> I2S_AP_2_MCK (codec VSP) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> I2S_AP_2_LRCK + +/* Port 26 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> I2S_AP_2_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> I2S_AP_2_DOUT + CFG_FUNC0, // I2S2_DIN -> I2S_AP_2_DIN + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_MCK -> I2S_AP_3_MCK (codec XSP) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> I2S_AP_3_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> I2S_AP_3_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> I2S_AP_3_DOUT + CFG_FUNC0, // I2S3_DIN -> I2S_AP_3_DIN + +/* Port 27 */ + CFG_DISABLED, // SPDIF -> + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO217 -> PORT_DOCK_VIDEO_AMP_EN + CFG_DISABLED, // GPIO218 -> + CFG_FUNC0, // DP_HPD -> DP_AP_HPD + CFG_FUNC0 | UART_DRIVE_STR, // UART0_TXD -> UART_AP_0_TXD + CFG_FUNC0, // UART0_RXD -> UART_AP_0_RXD + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 28 */ + CFG_FUNC0, // WDOG -> AP_WDOG + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#undef BB_DRIVE_STR +#undef BT_DRIVE_STR +#undef SWI_DRIVE_STR +#undef GPS_DRIVE_STR +#undef FMI_DRIVE_STR +#undef SPI_DRIVE_STR +#undef SPI_CS_DRIVE_STR +#undef I2C_DRIVE_STR +#undef DWI_DRIVE_STR +#undef I2S_DRIVE_STR +#undef SDIO_DRIVE_STR +#undef CAM_DRIVE_STR +#undef UART_DRIVE_STR +#undef HI_DRIVE_STR +#undef GPIO_DRIVE_STR diff --git a/target/ipad2/include/target/powerconfig.h b/target/ipad2/include/target/powerconfig.h new file mode 100644 index 0000000..e45bfbc --- /dev/null +++ b/target/ipad2/include/target/powerconfig.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Force bypass off + { PMU_IIC_BUS, kD1946_LDO1, 0x0A }, // PP3V0_GRAPE 3.00V + { PMU_IIC_BUS, kD1946_LDO2, 0x0A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1946_LDO3, 0x0A }, // PP3V0_VIDEO 3.00V + { PMU_IIC_BUS, kD1946_LDO4, 0x18 }, // PP3V0_OPTICAL 3.00V + { PMU_IIC_BUS, kD1946_LDO5, 0x0E }, // PP3V2_SD 3.20V + { PMU_IIC_BUS, kD1946_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1946_LDO7, 0x0F }, // PP3V0_VIDEO_BUF 3.00V + { PMU_IIC_BUS, kD1946_LDO8, 0x18 }, // PP3V2_S2R_USBMUX 3.20V + { PMU_IIC_BUS, kD1946_LDO9, 0x12 }, // PP3V0_IO 3.00V + { PMU_IIC_BUS, kD1946_LDO10, 0x0A }, // PP3V2_SD_CTRL 3.00V + { PMU_IIC_BUS, kD1946_LDO11, 0x17 }, // PP2V85_CAM 2.85V + { PMU_IIC_BUS, kD1946_LDO12, 0x14 }, // PP1V1 1.10V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Leave bypass off +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1946_ACTIVE1, 0xDD }, // Everything but BUCK1 and LDO1 + { PMU_IIC_BUS, kD1946_ACTIVE2, 0xF9 }, // Everything but SD and ACC + { PMU_IIC_BUS, kD1946_ACTIVE3, 0x61 }, // BUCK5, VBOOST_LCM, PP1V1 + { PMU_IIC_BUS, kD1946_ACTIVE4, 0xA0 }, // CPU1V8_SW and CPU1V2_SW + { PMU_IIC_BUS, kD1946_LCM_CONTROL1, 0x02 }, // unused 5.10V + { PMU_IIC_BUS, kD1946_LCM_CONTROL2, 0x0E }, // unused 5.70V + { PMU_IIC_BUS, kD1946_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1946_LCM_BST_CONTROL, 0x14 }, // VBOOST_LCM 6.00V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // HIB_32K on, DWI off + + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_A, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_B, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_C, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_D, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_E, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_F, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_G, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_H, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_K, 0x00 }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD1946_BUCK4, 0x9B }, // BUCK4 1.21V + { PMU_IIC_BUS, kD1946_BUCK4_HIB, 0x9B }, // BUCK4_HIB 1.21V + + { PMU_IIC_BUS, kD1946_SYS_GPIO_1, 0x11 }, // CLK_32K_PMU Out 0, Push-Pull, CPU_1V8 + { PMU_IIC_BUS, kD1946_SYS_GPIO_2, 0x49 }, // CLK_32K_WLAN CLK32K, Pull Down, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_3, 0x09 }, // RST_BT_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_4, 0x09 }, // RST_WLAN_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_5, 0x09 }, // RST_BB_PMU_L Out 0, Push-pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_6, 0xDA }, // BATTERY_SWI In, F Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_7, 0xBB }, // PM_BT_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_8, 0xBB }, // PM_WLAN_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_9, 0xBB }, // PM_BB_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_10, 0xEA }, // AUD_MIK_HS1_INT_L In, Change, Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_11, 0x09 }, // DOCK_BB_EN Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_12, 0x49 }, // CLK_32K_GPS CLK32K, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_13, 0xB9 }, // SD_CON_CD In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_14, 0xC8 }, // RST_L63_L In, F Edge, No Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_15, 0xFA }, // HALL_IRQ In, E Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_16, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_17, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_18, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB1, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB2, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB3, 0x02 }, // no debounce on GPIO6 + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB4, 0x10 }, // no debounce on GPIO7 + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB5, 0x02 }, // no debounce on GPIO10 + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB6, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB7, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB8, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB9, 0x12 }, // 10ms debounce + + // + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x02 }, + { PMU_IIC_BUS, kD1946_TEST_MODE, 0x01 }, // Enable test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, + { PMU_IIC_BUS, kD1946_WLED_CONTROL5, 0x00 }, // set WLED to IDAC always + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x02 }, + { PMU_IIC_BUS, kD1946_TEST_MODE, 0x00 }, // Disable test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, + + // + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, // Select Bank 1 + { PMU_IIC_BUS, kD1946_BUCK_CONTROL1, 0x0e }, // Force Buck0 into PWM Mode + { PMU_IIC_BUS, kD1946_BUCK_CONTROL3, 0x0e }, // Force Buck2 into PWM Mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, // Select Bank 0 +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL2, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { // gas gauge can have up to 16 entries + { 4000, 1000, 1600, 3000 }, // 10 - 16C 0.44C + { 4100, 1000, 1600, 1375 }, // 0.2C + { USHRT_MAX, 1000, 1600, 750 }, // 0.11C + { 4000, 1500, 2100, 3000 }, // 15 - 21C 0.44C + { 4100, 1500, 2100, 2000 }, // 0.29C + { USHRT_MAX, 1500, 2100, 1375 }, // 0.2C + { 4000, 2000, 3500, 3000 }, // 20 - 35C 0.44C + { 4100, 2000, 3500, 3000 }, // 0.44C + { USHRT_MAX, 2000, 3500, 2000 }, // 0.29C + { 4000, 3400, 4500, 3000 }, // 34 - 45C 0.44C + { 4100, 3400, 4500, 3000 }, // 0.44C + { USHRT_MAX, 3400, 4500, 3000 }, // 0.44C +}; + +// matches OTP for ICHG_TBAT_x +#define TARGET_ICHG_TBAT_MAX { 0x00, 0x00, 0x3f, 0x3f, 0x3f } + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 1287 /* 10% brightness */ +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2100 + +#define GASGAUGE_BATTERYID_BLOCK 1 +#define GASGAUGE_CHARGETABLE_BLOCK 3 +static const unsigned int atv_voltage_limit[16] = { 3600, 3650, 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350 }; +static const unsigned int atv_current_limit[16] = { 0, 0, 625, 750, 875, 1000, 1125, 1250, 1375, 1500, 1750, 2000, 2250, 2500, 2750, 3000 }; + +#endif diff --git a/target/ipad2/include/target/radioconfig.h b/target/ipad2/include/target/radioconfig.h new file mode 100644 index 0000000..b156c31 --- /dev/null +++ b/target/ipad2/include/target/radioconfig.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_RADIOCONFIG_H +#define __TARGET_RADIOCONFIG_H + +/* configuration per target */ + +#define RADIO_VERIFY_BASEBAND_EXISTS 1 + +static const gpio_t target_radio_quiesce_pins[] = +{ + GPIO_UART1_TXD +}; + +#define RADIO_ENABLE_IMEI_OVERRIDE 0 + +#endif /* ! __TARGET_RADIOCONFIG_H */ diff --git a/target/ipad2/include/target/uartconfig.h b/target/ipad2/include/target/uartconfig.h new file mode 100644 index 0000000..4b29946 --- /dev/null +++ b/target/ipad2/include/target/uartconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +/* define radio serial port */ +#define RADIO_SERIAL_PORT (1) +#define RADIO_MAX_READ_ERRORS (10) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/ipad2/init.c b/target/ipad2/init.c new file mode 100644 index 0000000..7fc74a8 --- /dev/null +++ b/target/ipad2/init.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2010-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define K93_PROTO1_BOARD (0) // And DEV1 +#define K93_PROTO2_BOARD (1) +#define K93_EVT_BOARD (2) // And DEV3 +#define K93_EVT2_BOARD (3) +#define K93_DVT_BOARD (4) + +static u_int32_t k93_get_board_rev(void); +static uint32_t display_config; + +MIB_CONSTANT_PTR(kMIBTargetDisplayGammaTablePtr,kOIDTypeStruct, (void *)ipad2_display_gamma_tables); +MIB_CONSTANT(kMIBTargetDisplayGammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(ipad2_display_gamma_tables)); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 90); + + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000644; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "k48", 0); +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node, *clcd_node, *backlight_node; + uint32_t propSize, propCnt; + char *propName; + void *propData; + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + } + + // Find the CLCD node + FindNode(0, "arm-io/clcd", &clcd_node); + +#if WITH_HW_DISPLAY_PINOT + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, clcd_node, backlight_node); + } +#endif + + // Update the bottom prox calibration data + if (FindNode(0, "arm-io/i2c1/prox", &node)) { + propName = "prox-bottom-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBCl', propData, propSize); + } + propName = "prox-temp-base"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBTb', propData, propSize); + } + propName = "prox-centerpoint-base"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBCb', propData, propSize); + } + propName = "prox-calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPCl', propData, propSize); + } + } + + // Update als node with calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "backlight-leakage-channel0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC0', propData, propSize); + } + propName = "backlight-leakage-channel1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC1', propData, propSize); + } + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + } + + // Update camera calibration data + if (FindNode(0, "arm-io/isp", &node)) { + propName = "camera-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CmCl', propData, propSize); + } + } + + // Update USB input current limit + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-max"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = TARGET_MAX_USB_INPUT_CURRENT; + } + } + + // K94 EVT does not support Charleston slow-ramp + if (k93_get_board_rev() < K93_DVT_BOARD) { + if (FindNode(0, "arm-io/i2c0/headset-switch", &node)) { + propName = "slow-ramp-delay"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = 0; + } + } + } + + return 0; +} + +#endif + +static u_int32_t k93_get_board_rev(void) +{ + u_int32_t gpio_board_rev; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + + return (gpio_board_rev & 0x7); +} diff --git a/target/ipad2/pinconfig.c b/target/ipad2/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/ipad2/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/ipad2/properties.c b/target/ipad2/properties.c new file mode 100644 index 0000000..98a6b3e --- /dev/null +++ b/target/ipad2/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad2/rules.mk b/target/ipad2/rules.mk new file mode 100644 index 0000000..7d5aee4 --- /dev/null +++ b/target/ipad2/rules.mk @@ -0,0 +1,49 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1946=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_HIGH \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_HIGH \ + TARGET_CPU_VOLTAGE_MASK=5 \ + TARGET_CPU_SOURCE=1 \ + TARGET_MIPI_DSI_SOURCE=2 \ + TARGET_MANAGED2H_SOURCE=1 \ + TARGET_MANAGED2L_SOURCE=2 \ + TARGET_MANAGED2H_DIV=2 \ + TARGET_MANAGED2L_DIV=3 \ + TARGET_PCLK1_SOURCE=2 \ + TARGET_PCLK1_DIV=6 \ + TARGET_GFX_SOURCE=2 \ + TARGET_GFX_SLC_SOURCE=2 \ + TARGET_SPI2_SOURCE=0 \ + TARGET_IOP_SOURCE=3 \ + TARGET_LPERFS_SOURCE=3 \ + TARGET_HPERFNRT_SOURCE=0 \ + TARGET_CLCD_VSPP=0 \ + TARGET_DSIM_CONFIG=0x00800000 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + BASEBAND_DTPATH=\"baseband\" \ + WITH_TARGET_AMG_PARAMS=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad2b/include/target/display_gamma_tables.h b/target/ipad2b/include/target/display_gamma_tables.h new file mode 100644 index 0000000..2adc1b9 --- /dev/null +++ b/target/ipad2b/include/target/display_gamma_tables.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010, 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_DISPLAY_GAMMA_TABLES_H +#define __TARGET_DISPLAY_GAMMA_TABLES_H + +/* K9x display gamma tables */ + +static const display_gamma_table ipad2b_display_gamma_tables[] = +{ + { + 0x00951149, 0x00FFFF7F, // LGD table 8/19/2012 + { + 0x62, 0x0a, 0x4d, 0x40, 0x07, 0x2b, 0x03, 0x34, + 0x34, 0xc0, 0x31, 0xc0, 0xdd, 0xdd, 0x34, 0x4d, + 0xd3, 0xd0, 0x74, 0xd3, 0xd0, 0x34, 0x34, 0xdd, + 0x34, 0x4d, 0xd3, 0x74, 0xc7, 0xdd, 0xdd, 0xc4, + 0x71, 0x70, 0x1c, 0xc7, 0x01, 0xc0, 0x01, 0x70, + 0x00, 0xd0, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x0d, + 0xd0, 0xd0, 0x40, 0x13, 0xd0, 0x1d, 0xd3, 0x00, + 0xc0, 0x01, 0x37, 0x34, 0x34, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0x0a, 0x4d, 0x40, 0x07, 0x2b, 0x03, 0x34, + 0x34, 0xc0, 0x31, 0xc0, 0xdd, 0xdd, 0x34, 0x4d, + 0xd3, 0xd0, 0x74, 0xd3, 0xd0, 0x34, 0x34, 0xdd, + 0x34, 0x4d, 0xd3, 0x74, 0xc7, 0xdd, 0xdd, 0xc4, + 0x71, 0x70, 0x1c, 0xc7, 0x01, 0xc0, 0x01, 0x70, + 0x00, 0xd0, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x0d, + 0xd0, 0xd0, 0x40, 0x13, 0xd0, 0x1d, 0xd3, 0x00, + 0xc0, 0x01, 0x37, 0x34, 0x34, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0x0a, 0x4d, 0x40, 0x07, 0x2b, 0x03, 0x34, + 0x34, 0xc0, 0x31, 0xc0, 0xdd, 0xdd, 0x34, 0x4d, + 0xd3, 0xd0, 0x74, 0xd3, 0xd0, 0x34, 0x34, 0xdd, + 0x34, 0x4d, 0xd3, 0x74, 0xc7, 0xdd, 0xdd, 0xc4, + 0x71, 0x70, 0x1c, 0xc7, 0x01, 0xc0, 0x01, 0x70, + 0x00, 0xd0, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x0d, + 0xd0, 0xd0, 0x40, 0x13, 0xd0, 0x1d, 0xd3, 0x00, + 0xc0, 0x01, 0x37, 0x34, 0x34, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } + }, + { + 0x00A41149, 0x00FFFF7F, // AUO table 8/20/2012 + { + 0x62, 0x0a, 0x0d, 0x01, 0xdd, 0x01, 0x00, 0x00, + 0x00, 0xc7, 0x0d, 0x1c, 0x07, 0x07, 0xc7, 0x71, + 0x70, 0x1c, 0x1c, 0x77, 0xdc, 0xc1, 0x71, 0x70, + 0xc7, 0x71, 0x70, 0xc0, 0x01, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x70, 0x70, 0x70, 0x00, 0x07, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x74, 0xc7, 0x1d, 0x77, 0x37, 0x4d, + 0x43, 0x03, 0x70, 0xc0, 0x01, 0x00, 0x34, 0xdd, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0x0a, 0x40, 0x77, 0x34, 0x1d, 0x07, 0x70, + 0x70, 0xdc, 0x00, 0x00, 0xc7, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x71, + 0xdc, 0x71, 0x07, 0xc7, 0xc1, 0x71, 0x1c, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x07, 0x1c, 0x1c, 0x00, + 0x00, 0x00, 0x70, 0x0d, 0x40, 0x03, 0xd0, 0x00, + 0x0d, 0x34, 0xd0, 0x1d, 0x1c, 0x70, 0xdc, 0xdd, + 0xdd, 0xdd, 0x34, 0x40, 0x03, 0x34, 0x1d, 0x77, + 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0x0a, 0x4d, 0x40, 0x13, 0x00, 0x40, 0xd3, + 0x00, 0xc0, 0x4d, 0x73, 0x00, 0x00, 0xc0, 0x01, + 0x70, 0x00, 0x07, 0x07, 0x07, 0x1c, 0xc0, 0x01, + 0x07, 0x00, 0x70, 0x00, 0x07, 0x40, 0x03, 0x00, + 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0d, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, + 0x40, 0xd3, 0xdd, 0xdd, 0x0d, 0x0d, 0x00, 0x00, + 0xc0, 0x71, 0x77, 0x77, 0x77, 0x77, 0x1c, 0xc7, + 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + } +}; + +#endif diff --git a/target/ipad2b/include/target/gpiodef.h b/target/ipad2b/include/target/gpiodef.h new file mode 100644 index 0000000..506b6f4 --- /dev/null +++ b/target/ipad2b/include/target/gpiodef.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* K93a specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_RST GPIO( 4, 4) +#define GPIO_LCD_RST_POLARITY (0) +#define GPIO_LCD_PWR_EN GPIO( 4, 3) + +#define GPIO_RINGER_AB GPIO( 0, 4) + +#define POWER_GPIO_BATTERY_SWI (5) +#define POWER_GPIO_BATTERY_SWI_CONFIG_OUTPUT 0x0B +#define POWER_GPIO_BATTERY_SWI_CONFIG_INPUT 0xD8 + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 4, 5) +#define GPIO_BOARD_REV1 GPIO( 4, 6) +#define GPIO_BOARD_REV2 GPIO( 4, 7) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (0) + +/* D1946 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad2b/include/target/nand_spec_tables.h b/target/ipad2b/include/target/nand_spec_tables.h new file mode 100644 index 0000000..e7e91ae --- /dev/null +++ b/target/ipad2b/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000101 + }, + + /* useToggleMode */ TRUE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ TRUE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ TRUE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/ipad2b/include/target/pinconfig.h b/target/ipad2b/include/target/pinconfig.h new file mode 100644 index 0000000..193fdc0 --- /dev/null +++ b/target/ipad2b/include/target/pinconfig.h @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default P105/6/7 SoC Pin Configuration from rev 2.1 */ + +/* Different drive strength for AP and DEV. */ +#if PIN_CFG_AP +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##ap +#elif PIN_CFG_DEV +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##dev +#endif + +#if TARGET_HAS_BASEBAND +#define IF_BB(x, y) (x) +#else +#define IF_BB(x, y) (y) +#endif + +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_IN | PULL_UP, // GPIO2 -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // GPIO3 -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // GPIO4 -> GPIO_BTN_SRL_L + CFG_OUT_0 | DRIVE_X1, // GPIO5 -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | DRIVE_X1, // GPIO6 -> GPIO_SPKAMP_KEEPALIVE + CFG_IN | PULL_UP, // GPIO7 -> GPIO_SPKAMP_LEFT_IRQ_L + +/* Port 1 */ + CFG_IN | PULL_UP, // GPIO8 -> GPIO_CODEC_IRQ_L + CFG_OUT_0 | DRIVE_X1, // GPIO9 -> GPIO_BT_WAKE + IF_BB(CFG_IN, CFG_DISABLED | PULL_DOWN), // GPIO10 -> GPIO_BB_RST_L + CFG_DISABLED | PULL_DOWN, // GPIO11 -> GPIO_BB_GSM_TXBURST + IF_BB(CFG_OUT_0, CFG_DISABLED | PULL_DOWN) | DRIVE_X1, // GPIO12 -> GPIO_BB_IPC_GPIO + IF_BB(CFG_IN, CFG_DISABLED) | PULL_DOWN, // GPIO13 -> GPIO_BB_HSIC1_REMOTE_WAKE + CFG_DISABLED | PULL_DOWN, // GPIO14 -> GPIO_BB_GPS_SYNC + IF_BB(CFG_IN, CFG_DISABLED) | PULL_DOWN, // GPIO15 -> GPIO_BB_RST_DET_L + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> GPIO_BOARD_ID3 + IF_BB(CFG_OUT_0, CFG_DISABLED | PULL_DOWN) | DRIVE_X1, // GPIO17 -> GPIO_BB_HSIC_HOST_RDY + CFG_DISABLED, // GPIO18 -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // GPIO19 -> GPIO_PMU_IRQ_L + CFG_OUT_0 | DRIVE_X1, // GPIO20 -> GPIO_PMU_KEEPACT + CFG_OUT_0 | DRIVE_X1, // GPIO21 -> GPIO_GRAPE_RST_L + CFG_IN | PULL_UP, // GPIO22 -> GPIO_GRAPE_IRQ_L + IF_BB(CFG_IN, CFG_DISABLED | PULL_DOWN) | DRIVE_X1, // GPIO23 -> GPIO_BB_RADIO_ON_L + +/* Port 3 */ + IF_BB(CFG_IN, CFG_DISABLED) | PULL_DOWN, // GPIO24 -> GPIO_BB_HSIC_DEV_RDY + CFG_DISABLED, // GPIO25 -> GPIO_BOOT_CONFIG1 + CFG_IN | PULL_DOWN, // GPIO26 -> GPIO_FORCE_DFU + CFG_OUT_0 | PULL_DOWN | DRIVE_X1, // GPIO27 -> GPIO_DFU_STATUS + CFG_DISABLED, // GPIO28 -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // GPIO29 -> GPIO_BOOT_CONFIG3 + IF_BB(CFG_IN, CFG_DISABLED | PULL_DOWN), // GPIO30 -> GPIO_PROX_IRQ_L + CFG_DISABLED, // GPIO31 -> + +/* Port 4 */ + CFG_IN | PULL_DOWN, // GPIO32 -> GPIO_ACCEL_IRQ2_L + CFG_IN | PULL_DOWN, // GPIO33 -> GPIO_GYRO_IRQ1 + CFG_IN | PULL_DOWN, // GPIO34 -> GPIO_WLAN_HSIC_RESUME + CFG_OUT_0 | DRIVE_X1, // GPIO35 -> GPIO_MLC_PWR_EN + CFG_OUT_0 | DRIVE_X1, // GPIO36 -> GPIO_MLC_RST_1V8_L + CFG_DISABLED, // EHCI_PORT_PWR[0] -> GPIO_BOARD_REV0 + CFG_DISABLED, // EHCI_PORT_PWR[1] -> GPIO_BOARD_REV1 + CFG_DISABLED, // EHCI_PORT_PWR[2] -> GPIO_BOARD_REV2 + +/* Port 5 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X3), // UART1_TXD -> UART1_BT_TXD + CFG_FUNC0, // UART1_RXD -> UART1_BT_RXD + CFG_OUT_1 | AP_DEV_DRIVE_STR(X1, X3), // UART1_RTSN -> UART1_BT_RTS_L + CFG_FUNC0, // UART1_CTSN -> UART1_BT_CTS_L + CFG_FUNC0 | DRIVE_X1, // UART2_TXD -> UART2_ACC_TXD + CFG_FUNC0, // UART2_RXD -> UART2_ACC_RXD + CFG_IN | PULL_UP, // UART2_RTSN -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_IN | PULL_UP, // UART2_CTSN -> GPIO_ALS_IRQ_L + +/* Port 6 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X3), // UART3_TXD -> UART3_WLAN_TXD + CFG_FUNC0, // UART3_RXD -> UART3_WLAN_RXD + CFG_OUT_0 | DRIVE_X1, // UART3_RTSN -> GPIO_WLAN_HSIC_HOST_RDY + CFG_IN | PULL_DOWN, // UART3_CTSN -> GPIO_WLAN_HSIC_DEV_RDY + CFG_FUNC0 | DRIVE_X2, // I2C0_SDA -> I2C0_SDA + CFG_FUNC0 | DRIVE_X2, // I2C0_SCL -> I2C0_SCL + CFG_FUNC0 | DRIVE_X2, // I2C1_SDA -> I2C1_SDA + CFG_FUNC0 | DRIVE_X2, // I2C1_SCL -> I2C1_SCL + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2, // ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2, // ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2, // ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2, // ISP1_SCL -> ISP1_CAM_FRONT_SCL + CFG_DISABLED | PULL_DOWN, // MIPI_VSYNC -> DISPLAY_SYNC + CFG_FUNC0 | PULL_DOWN, // TMR32_PWM0 -> GPIO_GYRO_IRQ2 + CFG_FUNC0 | PULL_DOWN, // TMR32_PWM1 -> GPIO_ACCEL_IRQ1_L + CFG_FUNC0 | DRIVE_X2, // TMR32_PWM2 -> AP_CLK_32K_CUMULUS + +/* Port 8 */ + CFG_DISABLED, // SWI_DATA -> + CFG_FUNC0 | PULL_DOWN, // DWI_DI -> DWI_DI + CFG_FUNC0 | DRIVE_X2, // DWI_DO -> DWI_DO + CFG_FUNC0 | DRIVE_X2, // DWI_CLK -> DWI_CLK + CFG_OUT_1 | DRIVE_X1, // SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN + CFG_OUT_0 | DRIVE_X3, // SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_OUT_1 | DRIVE_X1, // SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN + CFG_OUT_0 | DRIVE_X3, // SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + +/* Port 9 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_FUNC0 | DRIVE_X3, // I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2, // I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2, // I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2, // I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + +/* Port 10 */ + CFG_FUNC0, // I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X3, // I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2, // I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2, // I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2, // I2S1_DOUT -> I2S1_SPKAMP_DOUT + CFG_FUNC0, // I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_IN, // I2S2_MCK -> PMU_GPIO_TRISTAR_IRQ + CFG_FUNC0 | DRIVE_X2, // I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2, // I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2, // I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN, // I2S3_MCK -> GPIO_ACC_SW_POK_L + CFG_FUNC0 | DRIVE_X2, // I2S3_LRCK -> I2S3_BT_LRCK + CFG_FUNC0 | DRIVE_X2, // I2S3_BCLK -> I2S3_BT_BCLK + CFG_FUNC0 | DRIVE_X2, // I2S3_DOUT -> I2S3_BT_DOUT + CFG_FUNC0, // I2S3_DIN -> I2S3_BT_DIN + +/* Port 12 */ + CFG_DISABLED, // SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> + CFG_FUNC0 | DRIVE_X2, // SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2, // SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | DRIVE_X1, // SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 13 */ + CFG_FUNC0 | DRIVE_X2, // SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2, // SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | DRIVE_X1, // SPI2_SSIN -> SPI2_CODEC_CS_L + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + IF_BB(CFG_IN, CFG_DISABLED | PULL_DOWN) | AP_DEV_DRIVE_STR(X1, X3), // UART4_TXD -> UART4_BB_TXD + IF_BB(CFG_FUNC0, CFG_DISABLED | PULL_DOWN), // UART4_RXD -> UART4_BB_RXD + IF_BB(CFG_IN, CFG_DISABLED | PULL_DOWN) | AP_DEV_DRIVE_STR(X1, X3), // UART4_RTSN -> UART4_BB_RTS_L + IF_BB(CFG_FUNC0, CFG_DISABLED | PULL_DOWN), // UART4_CTSN -> UART4_BB_CTS_L + CFG_OUT_0 | DRIVE_X1, // SDIO0_DATA3 -> GPIO_ACC_SW_EN + IF_BB(CFG_DISABLED, CFG_DISABLED | PULL_DOWN), // SDIO0_DATA2 -> BB_JTAG_TRST_L + IF_BB(CFG_DISABLED, CFG_DISABLED | PULL_DOWN), // SDIO0_DATA1 -> BB_JTAG_TDO + IF_BB(CFG_DISABLED, CFG_DISABLED | PULL_DOWN), // SDIO0_DATA0 -> BB_JTAG_TDI + +/* Port 17 */ + IF_BB(CFG_DISABLED, CFG_DISABLED | PULL_DOWN), // SDIO0_CMD -> BB_JTAG_TMS + IF_BB(CFG_DISABLED, CFG_DISABLED | PULL_DOWN), // SDIO0_CLK -> BB_JTAG_TCK + CFG_DISABLED, // FMI0_CEN3 -> + CFG_DISABLED, // FMI0_CEN2 -> + CFG_DISABLED, // FMI0_CEN1 -> + CFG_FUNC0 | DRIVE_X1, // FMI0_CEN0 -> FMI0_CE0_L + CFG_FUNC0 | DRIVE_X1, // FMI0_CLE -> FMI0_CLE + CFG_FUNC0 | DRIVE_X1, // FMI0_ALE -> FMI0_ALE + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X1, // FMI0_REN -> FMI0_RE_N + CFG_FUNC0 | DRIVE_X1, // FMI0_WEN -> FMI0_WE_L + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO7 -> FMI0_AD<7> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO6 -> FMI0_AD<6> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO5 -> FMI0_AD<5> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO4 -> FMI0_AD<4> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 19 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 20 */ + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_DQS -> FMI0_DQS_P + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO3 -> FMI0_AD<3> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO2 -> FMI0_AD<2> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO1 -> FMI0_AD<1> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI0_IO0 -> FMI0_AD<0> + CFG_DISABLED, // FMI1_CEN3 -> + CFG_DISABLED, // FMI1_CEN2 -> + CFG_DISABLED, // FMI1_CEN1 -> + +/* Port 21 */ + CFG_FUNC0 | DRIVE_X1, // FMI1_CEN0 -> FMI1_CE0_L + CFG_FUNC0 | DRIVE_X1, // FMI1_CLE -> FMI1_CLE + CFG_FUNC0 | DRIVE_X1, // FMI1_ALE -> FMI1_ALE + CFG_FUNC0 | DRIVE_X1, // FMI1_REN -> FMI1_RE_N + CFG_FUNC0 | DRIVE_X1, // FMI1_WEN -> FMI1_WE_L + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO7 -> FMI1_AD<7> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO6 -> FMI1_AD<6> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO5 -> FMI1_AD<5> + +/* Port 22 */ + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO4 -> FMI1_AD<4> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_DQS -> FMI1_DQS_P + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO3 -> FMI1_AD<3> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO2 -> FMI1_AD<2> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO1 -> FMI1_AD<1> + CFG_FUNC0 | BUS_HOLD | DRIVE_X1, // FMI1_IO0 -> FMI1_AD<0> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 23 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 24 */ + CFG_FUNC0 | DRIVE_X2, // I2C2_SDA -> I2C2_SDA + CFG_FUNC0 | DRIVE_X2, // I2C2_SCL -> I2C2_SCL + CFG_FUNC0 | DRIVE_X1, // UART0_TXD -> UART0_DEBUG_TXD + CFG_FUNC0, // UART0_RXD -> UART0_DEBUG_RXD + CFG_FUNC0 | DRIVE_X2, // UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, // DP_HPD -> + CFG_DISABLED, // TST_CLKOUT -> TP_SOC_TST_CLKOUT + CFG_DISABLED, // TST_STPCLK -> SOC_TST_STPCLK + +/* Port 25 */ + CFG_FUNC0 | DRIVE_X1, // WDOG -> SOC_WDOG + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#undef AP_DEV_DRIVE_STR +#undef IF_BB diff --git a/target/ipad2b/include/target/powerconfig.h b/target/ipad2b/include/target/powerconfig.h new file mode 100644 index 0000000..1a94238 --- /dev/null +++ b/target/ipad2b/include/target/powerconfig.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Force bypass off + { PMU_IIC_BUS, kD1946_LDO1, 0x0A }, // PP3V0_SPARE1 3.00V + { PMU_IIC_BUS, kD1946_LDO2, 0x0A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1946_LDO3, 0x0A }, // PP3V0_S2R_TRISTAR 3.00V + { PMU_IIC_BUS, kD1946_LDO4, 0x18 }, // PP3V0_SENSOR 3.00V + { PMU_IIC_BUS, kD1946_LDO5, 0x0E }, // PP3V2_SPARE2 3.20V + { PMU_IIC_BUS, kD1946_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1946_LDO7, 0x03 }, // PP1V8_CAM 1.80V + { PMU_IIC_BUS, kD1946_LDO8, 0x14 }, // PP3V0_S2R_HALL 3.00V + { PMU_IIC_BUS, kD1946_LDO9, 0x01 }, // PP1V2_CAM 1.30V + { PMU_IIC_BUS, kD1946_LDO10, 0x02 }, // PP2V8_CAM_AF 2.60V + { PMU_IIC_BUS, kD1946_LDO11, 0x16 }, // PP2V8_CAM 2.80V + { PMU_IIC_BUS, kD1946_LDO12, 0x10 }, // PP1V0 1.00V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Leave bypass off +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1946_ACTIVE1, 0xDD }, // Everything but BUCK1 and LDO1 + { PMU_IIC_BUS, kD1946_ACTIVE2, 0xB9 }, // LDO5, 6, and 10 are off + { PMU_IIC_BUS, kD1946_ACTIVE3, 0x61 }, // LDO12, Buck5, and WLED Boost + { PMU_IIC_BUS, kD1946_ACTIVE4, 0xA0 }, // CPU1V8_SW and CPU1V2_SW + { PMU_IIC_BUS, kD1946_LCM_CONTROL1, 0x05 }, // unused 5.25V + { PMU_IIC_BUS, kD1946_LCM_CONTROL2, 0x0E }, // unused 5.70V + { PMU_IIC_BUS, kD1946_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1946_LCM_BST_CONTROL, 0x14 }, // VBOOST_LCM 6.00V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // HIB_32K on, DWI off + + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_A, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_B, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_C, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_D, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_E, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_F, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_G, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_H, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_K, 0x00 }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD1946_BUCK4, 0x9B }, // BUCK4 1.21V + { PMU_IIC_BUS, kD1946_BUCK4_HIB, 0x9B }, // BUCK4_HIB 1.21V + + { PMU_IIC_BUS, kD1946_SYS_GPIO_1, 0x11 }, // PMU_CLK_32K_CUMULUS Out 0, Push-Pull, CPU_1V8 + { PMU_IIC_BUS, kD1946_SYS_GPIO_2, 0x49 }, // PMU_CLK_32K_WLAN CLK32K, Pull Down, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_3, 0x09 }, // PMU_GPIO_BT_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_4, 0x09 }, // PMU_GPIO_WLAN_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_5, 0x18 }, // PMU_GPIO_BB_RST_L Out 0, OD/PU, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_6, 0xDA }, // UART5_BATT_RTXD In, F Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_7, 0xBA }, // PMU_GPIO_BT_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_8, 0xBA }, // PMU_GPIO_WLAN_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD1946_SYS_GPIO_9, 0xBA }, // PMU_GPIO_BB_WAKE In, R Edge, Wake, No Pull Down, Disable Pull-Up +#else + { PMU_IIC_BUS, kD1946_SYS_GPIO_9, 0xB9 }, // PMU_GPIO_BB_WAKE In, R Edge, No Wake, Pull Down, Disable Pull-Up +#endif + { PMU_IIC_BUS, kD1946_SYS_GPIO_10, 0xEA }, // PMU_GPIO_CODEC_HS_IRQ_L In, Any Edge, Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_11, 0xC8 }, // PMU_GPIO_CODEC_RST_L In, F Edge, No Wake, VBUCK3 (for internal PU) + { PMU_IIC_BUS, kD1946_SYS_GPIO_12, 0xB9 }, // PMU_GPIO_TRISTAR_IRQ In, R Edge, No Wake, Pull Down + { PMU_IIC_BUS, kD1946_SYS_GPIO_13, 0xFA }, // PMU_GPIO_HALL_IRQ_1 In, Change, Wake, Pull Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_14, 0xFA }, // PMU_GPIO_HALL_IRQ_2 In, Change, Wake, Pull Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_15, 0xB9 }, // PMU_GPIO_HALL_IRQ_3 In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_16, 0xF8 }, // PMU_GPIO_HALL_IRQ_4 In, Change, No Wake, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_17, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_18, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB1, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB2, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB3, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB4, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB5, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB6, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB7, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB8, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB9, 0x12 }, // 10ms debounce + + // + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x02 }, + { PMU_IIC_BUS, kD1946_TEST_MODE, 0x01 }, // Enable test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, + { PMU_IIC_BUS, kD1946_WLED_CONTROL5, 0x00 }, // set WLED to IDAC always + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x02 }, + { PMU_IIC_BUS, kD1946_TEST_MODE, 0x00 }, // Disable test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL2, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { // gas gauge can have up to 16 entries + { 4000, 1000, 1600, 2520 }, // 10 - 16C + { 4100, 1000, 1600, 2240 }, + { USHRT_MAX, 1000, 1600, 1320 }, + { 4000, 1500, 2100, 2520 }, // 15 - 21C + { 4100, 1500, 2100, 2520 }, + { USHRT_MAX, 1500, 2100, 1320 }, + { 4000, 2000, 3500, 2520 }, // 20 - 35C + { 4100, 2000, 3500, 2520 }, + { USHRT_MAX, 2000, 3500, 2240 }, + { 4000, 3400, 4500, 2520 }, // 34 - 45C + { 4100, 3400, 4500, 2520 }, + { USHRT_MAX, 3400, 4500, 2240 }, +}; + +// matches OTP for ICHG_TBAT_x +#define TARGET_ICHG_TBAT_MAX { 0x00, 0x00, 0x3f, 0x3f, 0x3f } + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 1287 /* 10% brightness */ +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2100 + +#define GASGAUGE_BATTERYID_BLOCK 1 +#define GASGAUGE_CHARGETABLE_BLOCK 3 +static const unsigned int atv_voltage_limit[16] = { 3600, 3650, 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350 }; +static const unsigned int atv_current_limit[16] = { 0, 200, 440, 640, 880, 1120, 1320, 1560, 1760, 2000, 2240, 2440, 2520, 2520, 2520, 2520 }; + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/ipad2b/include/target/uartconfig.h b/target/ipad2b/include/target/uartconfig.h new file mode 100644 index 0000000..b48b06b --- /dev/null +++ b/target/ipad2b/include/target/uartconfig.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/ipad2b/include/target/usbconfig.h b/target/ipad2b/include/target/usbconfig.h new file mode 100644 index 0000000..87af85e --- /dev/null +++ b/target/ipad2b/include/target/usbconfig.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_UOTGTUNE1 + +#undef USBPHY_UOTGTUNE1 +#define USBPHY_UOTGTUNE1 (0x549) + +#endif /* USBPHY_UOTGTUNE1 */ + +#ifdef USBPHY_UOTGTUNE2 + +#undef USBPHY_UOTGTUNE2 +#define USBPHY_UOTGTUNE2 (0x2FF3) + +#endif /* USBPHY_UOTGTUNE2 */ + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/ipad2b/init.c b/target/ipad2b/init.c new file mode 100644 index 0000000..f532761 --- /dev/null +++ b/target/ipad2b/init.c @@ -0,0 +1,431 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IPAD2B_PROTO0_DEV1_BOARD (0x0) +#define IPAD2B_PROTO1_BOARD (0x1) +#define IPAD2B_PROTO2_BOARD (0x2) +#define IPAD2B_EVT1_BOARD (0x3) + +static uint32_t ipad2b_get_board_rev(void); + +MIB_CONSTANT_PTR(kMIBTargetDisplayGammaTablePtr,kOIDTypeStruct, (void *)ipad2b_display_gamma_tables); +MIB_CONSTANT(kMIBTargetDisplayGammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(ipad2b_display_gamma_tables)); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +static uint32_t display_config; + + +void target_early_init(void) +{ + unsigned int i; + + // For proto0, go back to 2.8 V: P105 LDO10 needs to be set to 2.5v for Proto1 + if (ipad2b_get_board_rev() == IPAD2B_PROTO0_DEV1_BOARD) { + const uint8_t pmu_data[] = { + 0x38, 0x06, + }; + + for (i = 0; i < sizeof(pmu_data); i += 2) + iic_write(0, 0x78, &pmu_data[i], 2); + + } +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + // P105 EVT: Disable Alison LCM boost soft start to fix some grape fallouts + // P105's LCM Boost: SW to disable OC every time boot + if (ipad2b_get_board_rev() <= IPAD2B_EVT1_BOARD) { + + unsigned int i; + + const uint8_t pmu_data[] = { + 0x1e, 0x02, // bank 2 + 0xd0, 0x01, // enable test mode + 0xef, 0x10, // disable OC for LCM boost + 0x1e, 0x01, // bank 1 + 0xee, 0x0c, // trim_conf15 = 0x0c ; disable soft-start + 0x1e, 0x02, // bank 2 + 0xd0, 0x00, // disable test mode + 0x1e, 0x00, // bank 0 + }; + + for (i = 0; i < sizeof(pmu_data); i += 2) + iic_write(0, 0x78, &pmu_data[i], 2); + + } +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000944; + // X124 LVDS panel timing parameters workaround for proto0 + if (ipad2b_get_board_rev() == IPAD2B_PROTO0_DEV1_BOARD) { + display_config = 0x00000644; + } + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "ipad2b", 0); + + // X124 LVDS panel timing parameters workaround for proto0 + if (ipad2b_get_board_rev() == IPAD2B_PROTO0_DEV1_BOARD) { + env_set("display-timing", "ipad2b-p0", 0); + } +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node, *clcd_node, *backlight_node; + uint32_t propSize, propCnt; + char *propName; + void *propData; + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + } + + // Find the CLCD node + FindNode(0, "arm-io/clcd", &clcd_node); + +#if WITH_HW_DISPLAY_PINOT + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, clcd_node, backlight_node); + } +#endif + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the bottom prox calibration data + if (FindNode(0, "arm-io/i2c1/prox", &node)) { + propName = "prox-bottom-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBCl', propData, propSize); + } + propName = "prox-temp-base"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBTb', propData, propSize); + } + propName = "prox-centerpoint-base"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBCb', propData, propSize); + } + propName = "prox-calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update als node with calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "backlight-leakage-channel0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC0', propData, propSize); + } + propName = "backlight-leakage-channel1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC1', propData, propSize); + } + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update camera calibration data + if (FindNode(0, "arm-io/isp", &node)) { + propName = "camera-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CmCl', propData, propSize); + } + } + + // Updte the speaker calibration data + if (FindNode(0, "arm-io/i2c0/audio-speaker0", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr[2]; + if (syscfgCopyDataForTag('VPBR', vpbr, sizeof(vpbr)) == 2) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr[0] & 0x1f); + ((uint8_t *)propData)[32] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr[1] & 0x1f); + } + uint8_t vbst[2]; + if (syscfgCopyDataForTag('VBST', vbst, sizeof(vbst)) == 2) { + ((uint8_t *)propData)[16] = vbst[0]; + ((uint8_t *)propData)[36] = vbst[1]; + } + } + } + + // Update USB input current limit + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-max"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = TARGET_MAX_USB_INPUT_CURRENT; + } + } + + + // pre-Proto2 Grape clock config + if (ipad2b_get_board_rev() <= IPAD2B_PROTO1_BOARD) { + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "function-clock_enable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-clock_enable-pmu"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[21] = '\0'; + } + } + + // configure PMU GPIO1 to be Grape clock (off until enabled) + // configure SoC PWM2 to be disabled ( + power_gpio_configure(0, 0x11); + gpio_configure(GPIO(7, 7), GPIO_CFG_IN); + } + + // pre-EVT Grape LDO config + if (ipad2b_get_board_rev() <= IPAD2B_PROTO2_BOARD) { + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "function-power_ana"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-power_ldo"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-power_ldo-pre-evt"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[18] = '\0'; + } + } + } + + // pre-EVT speaker amp interrupt assignments + if (ipad2b_get_board_rev() <= IPAD2B_PROTO2_BOARD) { + if (FindNode(0, "arm-io/i2c0/audio-speaker0", &node)) { + propName = "interrupts"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = 0x07; + } + } + if (FindNode(0, "arm-io/i2c0/audio-speaker1", &node)) { + propName = "interrupts"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = 0x2e; + } + } + } + + return 0; +} + +#endif + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; + +static uint32_t ipad2b_get_board_rev(void) +{ + if(!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + diff --git a/target/ipad2b/pinconfig.c b/target/ipad2b/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/ipad2b/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/ipad2b/properties.c b/target/ipad2b/properties.c new file mode 100644 index 0000000..27452af --- /dev/null +++ b/target/ipad2b/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad2b/rules.mk b/target/ipad2b/rules.mk new file mode 100644 index 0000000..c218181 --- /dev/null +++ b/target/ipad2b/rules.mk @@ -0,0 +1,54 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1946=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_HIGH \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_HIGH \ + TARGET_CPU_VOLTAGE_MASK=5 \ + TARGET_EMA_CTL_CPU_SEL=2 \ + TARGET_CPU_SOURCE=1 \ + TARGET_MIPI_DSI_SOURCE=1 \ + TARGET_MANAGED2H_SOURCE=1 \ + TARGET_MANAGED2L_SOURCE=2 \ + TARGET_MANAGED2H_DIV=2 \ + TARGET_MANAGED2L_DIV=3 \ + TARGET_PCLK1_SOURCE=1 \ + TARGET_PCLK1_DIV=4 \ + TARGET_GFX_SOURCE=2 \ + TARGET_GFX_SLC_SOURCE=2 \ + TARGET_SPI2_SOURCE=0 \ + TARGET_IOP_SOURCE=3 \ + TARGET_LPERFS_SOURCE=3 \ + TARGET_HPERFNRT_SOURCE=0 \ + TARGET_USE_HSIC=1 \ + TARGET_CLCD_VSPP=0 \ + TARGET_DSIM_CONFIG=0x00800000 \ + TARGET_DSIM_SUPPRESS=0x1 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad3/include/target/gpiodef.h b/target/ipad3/include/target/gpiodef.h new file mode 100644 index 0000000..a78be78 --- /dev/null +++ b/target/ipad3/include/target/gpiodef.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* K93 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_PWR_EN GPIO(21, 1) + +#define GPIO_RINGER_AB GPIO( 0, 3) + +#define POWER_GPIO_BATTERY_SWI (5) +#define POWER_GPIO_BATTERY_SWI_CONFIG_OUTPUT 0x03 +#define POWER_GPIO_BATTERY_SWI_CONFIG_INPUT 0xD8 + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(17, 3) +#define GPIO_BOARD_REV1 GPIO(17, 4) +#define GPIO_BOARD_REV2 GPIO(17, 5) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +/* D1974 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(7, 2) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad3/include/target/nand_spec_tables.h b/target/ipad3/include/target/nand_spec_tables.h new file mode 100644 index 0000000..45105e1 --- /dev/null +++ b/target/ipad3/include/target/nand_spec_tables.h @@ -0,0 +1,93 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00003333, + 0x0000CCCC + }, + + /* useToggleMode */ FALSE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ FALSE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ FALSE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/ipad3/include/target/pinconfig.h b/target/ipad3/include/target/pinconfig.h new file mode 100644 index 0000000..788be69 --- /dev/null +++ b/target/ipad3/include/target/pinconfig.h @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default J1/J2/J2A SoC Pin Configuration, IO spreadsheet v0.11 */ + +#if PIN_CFG_AP + +#define GPIO_DRIVE_STR DRIVE_X2 + +#define FMI_DRIVE_STR DRIVE_X3 +#define SPI_DRIVE_STR DRIVE_X3 +#define SPI_CS_DRIVE_STR DRIVE_X2 +#define I2C_DRIVE_STR DRIVE_X3 +#define I2S_DRIVE_STR DRIVE_X3 +#define CAM_DRIVE_STR DRIVE_X3 +#define CAM_RF_DRIVE_STR DRIVE_X4 +#define UART_DRIVE_STR DRIVE_X3 +#define DWI_DRIVE_STR DRIVE_X3 +#define BATTERY_SWI_DRIVE_STR DRIVE_X3 +#define ISP_DRIVE_STR DRIVE_X3 + +#elif PIN_CFG_DEV + +#define GPIO_DRIVE_STR DRIVE_X2 + +#define FMI_DRIVE_STR DRIVE_X4 +#define SPI_DRIVE_STR DRIVE_X4 +#define SPI_CS_DRIVE_STR DRIVE_X3 +#define I2C_DRIVE_STR DRIVE_X4 +#define I2S_DRIVE_STR DRIVE_X4 +#define CAM_DRIVE_STR DRIVE_X3 +#define CAM_RF_DRIVE_STR DRIVE_X4 +#define UART_DRIVE_STR DRIVE_X4 +#define DWI_DRIVE_STR DRIVE_X4 +#define BATTERY_SWI_DRIVE_STR DRIVE_X4 +#define ISP_DRIVE_STR DRIVE_X3 + +#endif + +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif +/* Port 0 */ + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_IN | GPIO_DRIVE_STR, // UART2_RTSN -> RST_BB_L + CFG_IN, // UART2_CTSN -> SRL_L + CFG_FUNC0 | UART_DRIVE_STR, // UART6_TXD -> UART6_WLAN_TXD + CFG_FUNC0, // UART6_RXD -> UART6_WLAN_RXD + CFG_DISABLED, // UART6_RTSN -> + CFG_DISABLED, // UART6_CTSN -> + +/* Port 1 */ + CFG_DISABLED, // SPI0_SCLK -> BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + +/* Port 2 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 3 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 4 */ + CFG_FUNC0, // DP_HPD -> DP_AP_HPD + CFG_FUNC0, // EDP_HPD -> EDP_AP_HPD + CFG_FUNC0 | UART_DRIVE_STR, // UART0_TXD -> UART0_MUX_TXD + CFG_FUNC0, // UART0_RXD -> UART0_MUX_RXD + CFG_IN, // GPIO0 -> HOME_L + CFG_IN, // GPIO1 -> ONOFF_L +#if SUB_TARGET_J2 || SUB_TARGET_J2A + CFG_IN | PULL_DOWN, // GPIO2 -> HSIC_BB_RDY +#elif SUB_TARGET_J1 + CFG_DISABLED, // GPIO2 -> HSIC_BB_RDY +#endif + CFG_DISABLED, // GPIO3 -> + +/* Port 5 */ + CFG_IN | PULL_UP, // GPIO4 -> IRQ_PMU_L + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO5 -> PM_BT_WAKE + CFG_IN | PULL_UP, // GPIO6 -> IRQ_CODEC_L + CFG_DISABLED, // GPIO7 -> + CFG_DISABLED, // GPIO8 -> + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO9 -> PM_RADIO_ON +#if SUB_TARGET_J2 || SUB_TARGET_J2A + CFG_IN | PULL_DOWN, // GPIO10 -> RST_DET_L +#elif SUB_TARGET_J1 + CFG_DISABLED, // GPIO10 -> RST_DET_L +#endif + CFG_DISABLED, // GPIO11 -> + +/* Port 6 */ +#if SUB_TARGET_J2 || SUB_TARGET_J2A + CFG_IN, // GPIO12 -> SPI2_IPC_SRDY +#elif SUB_TARGET_J1 + CFG_DISABLED, // GPIO12 -> SPI2_IPC_SRDY +#endif + CFG_DISABLED, // GPIO13 -> + CFG_IN | PULL_UP, // GPIO14 -> AUD_VOL_DOWN_L + CFG_IN | PULL_DOWN, // GPIO15 -> GSM_TXBURST_IND + CFG_DISABLED | PULL_DOWN, // GPIO16 -> BOARD_ID[3] + CFG_IN, // GPIO17 -> IRQ_GYRO_INT2 + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO19 -> + +/* Port 7 */ + CFG_IN | PULL_UP, // GPIO20 -> AUD_VOL_UP_L + CFG_IN | PULL_UP, // GPIO21 -> IRQ_GRAPE_HOST_INT_L + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO22 -> PM_KEEPACT + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO23 -> BB_EMERGENCY_DWLD + CFG_OUT_0, // GPIO24 -> IPC_GPIO_X26 + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN, // GPIO26 -> FORCE_DFU + CFG_OUT_0 | DRIVE_X1, // GPIO27 -> DFU_STATUS + +/* Port 8 */ + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_IN, // GPIO30 -> HSIC_WLAN_RDY + CFG_DISABLED, // GPIO31 -> + CFG_IN, // GPIO32 -> IRQ_PROX_INT_L + CFG_IN | PULL_DOWN, // GPIO33 -> IRQ_GYRO_INT1 + CFG_OUT_0, // GPIO34 -> HSIC_HOST_READY_WL + CFG_DISABLED, // GPIO35 -> + +/* Port 9 */ + CFG_IN | PULL_UP, // GPIO36 -> IRQ_ACCEL_INT1_L + CFG_IN | PULL_UP, // GPIO37 -> IRQ_ALS_INT_L + CFG_IN | PULL_UP, // GPIO38 -> IRQ_ACCEL_INT2_L + CFG_OUT_0 | GPIO_DRIVE_STR, // GPIO39 -> AUD_SPKRAMP_MUTE_L + CFG_FUNC0 | SPI_DRIVE_STR, // SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | SPI_DRIVE_STR, // SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | SPI_CS_DRIVE_STR, // SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 10 */ + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SDA -> I2C2_SDA_3V0 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SCL -> I2C2_SCL_3V0 + CFG_IN | UART_DRIVE_STR, // UART1_TXD -> UART1_BB_TXD + CFG_FUNC0, // UART1_RXD -> UART1_BB_RXD + CFG_FUNC0 | UART_DRIVE_STR, // UART1_RTSN -> UART1_BB_RTS_L + CFG_FUNC0, // UART1_CTSN -> UART1_BB_CTS_L + CFG_FUNC0 | UART_DRIVE_STR, // UART3_TXD -> UART3_BT_TXD + CFG_FUNC0, // UART3_RXD -> UART3_BT_RXD + +/* Port 11 */ + CFG_OUT_1 | UART_DRIVE_STR, // UART3_RTSN -> UART3_BT_RTS_L + CFG_FUNC0, // UART3_CTSN -> UART3_BT_CTS_L + CFG_FUNC0 | BATTERY_SWI_DRIVE_STR, // UART5_RTXD -> BATTERY_SWI + CFG_FUNC0 | ISP_DRIVE_STR, // ISP0_SDA -> ISP_AP_0_SDA + CFG_FUNC0 | ISP_DRIVE_STR, // ISP0_SCL -> ISP_AP_0_SCL + CFG_FUNC0 | ISP_DRIVE_STR, // ISP1_SDA -> ISP_AP_1_SDA + CFG_FUNC0 | ISP_DRIVE_STR, // ISP1_SCL -> ISP_AP_1_SCL + CFG_DISABLED, // SPI2_SCLK -> + +/* Port 12 */ + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, +#if SUB_TARGET_J2 || SUB_TARGET_J2A + CFG_OUT_0 | SPI_CS_DRIVE_STR, // SPI2_SSIN -> HSIC_HOST_RDY +#elif SUB_TARGET_J1 + CFG_DISABLED | SPI_CS_DRIVE_STR, // SPI2_SSIN -> HSIC_HOST_RDY +#endif + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // MIPI_VSYNC -> + +/* Port 13 */ + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED | GPIO_DRIVE_STR, // TMR32_PWM2 -> LED_STROBE_EN + CFG_DISABLED, // SWI_DATA -> + CFG_FUNC0 | PULL_DOWN, // DWI_DI -> DWI_AP_DI + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> DWI_AP_CLK + CFG_OUT_1 | GPIO_DRIVE_STR, // SENSOR0_RST -> PM_REAR_CAM_SHUTDOWN + +/* Port 14 */ + CFG_OUT_0 | CAM_RF_DRIVE_STR, // SENSOR0_CLK -> CLK_CAM_RF_R + CFG_OUT_1 | GPIO_DRIVE_STR, // SENSOR1_RST -> PM_FRONT_CAM_SHUTDOWN + CFG_OUT_0 | CAM_DRIVE_STR, // SENSOR1_CLK -> CLK_CAM_FF_R + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_MCK -> I2S0_ASP_MCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> I2S0_ASP_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_BCLK -> I2S0_ASP_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> I2S0_ASP_DOUT + CFG_FUNC0, // I2S0_DIN -> I2S0_ASP_DIN + +/* Port 15 */ + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> I2S2_VSP_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> I2S2_VSP_BCLK + +/* Port 16 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> I2S2_VSP_DOUT + CFG_FUNC0, // I2S2_DIN -> I2S2_VSP_DIN + CFG_DISABLED, // I2S3_MCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> I2S3_XSP_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> I2S3_XSP_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> I2S3_XSP_DOUT + CFG_FUNC0, // I2S3_DIN -> I2S3_XSP_DIN + CFG_DISABLED, // SPDIF -> + +/* Port 17 */ + CFG_FUNC0, // TST_CLKOUT -> TP_AP_TST_CLKOUT + CFG_FUNC0, // TST_STPCLK -> AP_TST_STPCLK + CFG_FUNC0 | DRIVE_X3, // WDOG -> AP_WDOG + CFG_DISABLED, // EHCI_PORT_PWR[0] -> GPIO40_BRD_REV0 + CFG_DISABLED, // EHCI_PORT_PWR[1] -> GPIO41_BRD_REV1 + CFG_DISABLED, // EHCI_PORT_PWR[2] -> GPIO42_BRD_REV2 + CFG_DISABLED, // SDIO_CLK -> + CFG_DISABLED, // SDIO_CMD -> + +/* Port 18 */ + CFG_DISABLED, // SDIO_DATA0 -> + CFG_DISABLED, // SDIO_DATA1 -> + CFG_DISABLED, // SDIO_DATA2 -> + CFG_DISABLED, // SDIO_DATA3 -> + CFG_OUT_0 | DRIVE_X3, // GPIO_3V_0 -> PORT_DOCK_VIDEO_AMP_EN + CFG_DISABLED, // GPIO_3V_1 -> + CFG_OUT_0 | CAM_DRIVE_STR, // ISP0_PRE_FLASH -> CAM0_1V2_VDDCORE_EN + CFG_OUT_0 | CAM_DRIVE_STR, // ISP0_FLASH -> CAM0_RESET_L + +/* Port 19 */ + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN7 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN6 -> + +/* Port 20 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN5 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN4 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN7 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN6 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN5 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN4 -> + CFG_OUT_1 | GPIO_DRIVE_STR, // FMI2_CEN7 -> GRAPE_FW_DNLD_EN_L + CFG_OUT_0 | GPIO_DRIVE_STR, // FMI2_CEN6 -> RST_GRAPE_L + +/* Port 21 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_CEN5 -> + CFG_OUT_0 | DRIVE_X3, // FMI2_CEN4 -> PM_LCDVDD_PWR_EN + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN7 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN6 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN5 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN4 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO6 -> + +/* Port 22 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED | PULL_DOWN, // FMI0_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO1 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_REN -> + +/* Port 23 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_WEN -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO7 -> + +/* Port 24 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_DOWN, // FMI1_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO2 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO0 -> + +/* Port 25 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_REN -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN0 -> + +/* Port 26 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO7 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO6 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO5 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO4 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_DQS -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO1 -> + +/* Port 27 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_REN -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_WEN -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_ALE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_CLE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_CEN2 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI2_CEN1 -> + +/* Port 28 */ + CFG_IN, // FMI2_CEN0 -> SPK_ID + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO7 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO6 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO5 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO4 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_DQS -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO2 -> + +/* Port 29 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_IO0 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_REN -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_WEN -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_ALE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CLE -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN3 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN2 -> + +/* Port 30 */ + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN1 -> + CFG_DISABLED | FMI_DRIVE_STR, // FMI3_CEN0 -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#undef GPIO_DRIVE_STR +#undef FMI_DRIVE_STR +#undef SPI_DRIVE_STR +#undef SPI_CS_DRIVE_STR +#undef I2C_DRIVE_STR +#undef I2S_DRIVE_STR +#undef CAM_DRIVE_STR +#undef CAM_RF_DRIVE_STR +#undef UART_DRIVE_STR +#undef DWI_DRIVE_STR +#undef BATTERY_SWI_DRIVE_STR +#undef ISP_DRIVE_STR diff --git a/target/ipad3/include/target/powerconfig.h b/target/ipad3/include/target/powerconfig.h new file mode 100644 index 0000000..4f9bf1a --- /dev/null +++ b/target/ipad3/include/target/powerconfig.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Force bypass off + { PMU_IIC_BUS, kD1974_LDO1, 0x0A }, // PP3V0_GRAPE 3.00V + { PMU_IIC_BUS, kD1974_LDO2, 0x0A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1974_LDO3, 0x0A }, // PP3V0_VIDEO 3.00V + { PMU_IIC_BUS, kD1974_LDO4, 0x18 }, // PP3V0_OPTICAL 3.00V + { PMU_IIC_BUS, kD1974_LDO5, 0x0E }, // PP3V2_LDO5 3.20V + { PMU_IIC_BUS, kD1974_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1974_LDO7, 0x12 }, // PP3V0_VIDEO_BUF 3.00V + { PMU_IIC_BUS, kD1974_LDO8, 0x18 }, // PP3V2_S2R_USBMUX 3.20V + { PMU_IIC_BUS, kD1974_LDO9, 0x12 }, // PP3V0_IO 3.00V + { PMU_IIC_BUS, kD1974_LDO10, 0x0A }, // PP3V0_S2R_HALL 3.00V + { PMU_IIC_BUS, kD1974_LDO11, 0x17 }, // PP2V85_CAM 2.85V + { PMU_IIC_BUS, kD1974_LDO12, 0x14 }, // PP1V1 1.10V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Leave bypass off +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1974_ACTIVE1, 0xDF }, // Everything but LDO1 + { PMU_IIC_BUS, kD1974_ACTIVE2, 0xF9 }, // Everything but LDO5 and LDO6 + { PMU_IIC_BUS, kD1974_ACTIVE3, 0x61 }, // LDO12 ON, WLEDA/B BST + { PMU_IIC_BUS, kD1974_ACTIVE4, 0xA0 }, // CPU1V8 and CPU1V2 ON + { PMU_IIC_BUS, kD1974_LCM_CONTROL1, 0x02 }, // unused 5.10V + { PMU_IIC_BUS, kD1974_LCM_CONTROL2, 0x05 }, // unused 5.25V + { PMU_IIC_BUS, kD1974_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1974_LCM_BST_CONTROL, 0x14 }, // VBOOST_LCM 6.00V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // HIB_32K on, DWI off + + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_A, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_B, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_C, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_D, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_E, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_F, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_G, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_H, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_I, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_J, 0x00 }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD1974_BUCK4, 0x98 }, // BUCK4 1.2V + { PMU_IIC_BUS, kD1974_BUCK4_HIB, 0x98 }, // BUCK4_HIB 1.2V + + { PMU_IIC_BUS, kD1974_SYS_GPIO_1, 0x11 }, // CLK_32K_PMU Out 0, Push-Pull, CPU_1V8 + { PMU_IIC_BUS, kD1974_SYS_GPIO_2, 0x49 }, // CLK_32K_WLAN CLK32K, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1974_SYS_GPIO_3, 0x09 }, // RST_BT_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1974_SYS_GPIO_4, 0x09 }, // RST_WLAN_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1974_SYS_GPIO_5, 0x09 }, // RST_BB_PMU_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1974_SYS_GPIO_6, 0xDA }, // BATTERY_SWI In, F Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_7, 0xBB }, // PM_BT_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_8, 0xBB }, // PM_WLAN_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_9, 0xBB }, // PM_BB_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_10, 0xEA }, // AUD_MIK_HS1_INT_L In, Change, Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD1974_SYS_GPIO_11, 0x09 }, // DOCK_BB_EN Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1974_SYS_GPIO_12, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_13, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_14, 0xC8 }, // RST_L63_L In, F Edge, No Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD1974_SYS_GPIO_15, 0xFA }, // HALL_IRQ Both Edges, No Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_16, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1974_SYS_GPIO_17, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB1, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB2, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB3, 0x02 }, // no debounce on GPIO6 + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB4, 0x10 }, // no debounce on GPIO7 + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB5, 0x02 }, // no debounce on GPIO8 + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB6, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB7, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB8, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1974_SYS_GPIO_DEB9, 0x12 }, // 10ms debounce +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL2, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { // gas gauge can have up to 16 entries + { 4000, 1000, 1600, 3150 }, // 10 - 16C 0.27C + { 4100, 1000, 1600, 2350 }, // 0.27C + { USHRT_MAX, 1000, 1600, 1350 }, // 0.11C + { 4000, 1500, 2100, 3150 }, // 15 - 21C 0.27C + { 4100, 1500, 2100, 3150 }, // 0.27C + { USHRT_MAX, 1500, 2100, 2350 }, // 0.2C + { 4000, 2000, 3500, 3150 }, // 20 - 35C 0.27C + { 4100, 2000, 3500, 3150 }, // 0.27C + { USHRT_MAX, 2000, 3500, 3150 }, // 0.27C + { 4000, 3400, 4500, 3150 }, // 34 - 45C 0.27C + { 4100, 3400, 4500, 3150 }, // 0.27C + { USHRT_MAX, 3400, 4500, 3150 }, // 0.27C +}; + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 1287 /* 10% brightness */ +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define GASGAUGE_BATTERYID_BLOCK 1 +#define GASGAUGE_CHARGETABLE_BLOCK 3 +static const unsigned int atv_voltage_limit[16] = { 3600, 3650, 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350 }; +static const unsigned int atv_current_limit[16] = { 150, 350, 550, 750, 950, 1150, 1350, 1550, 1750, 1950, 2150, 2350, 2550, 2750, 2950, 3150 }; + +#endif diff --git a/target/ipad3/include/target/radioconfig.h b/target/ipad3/include/target/radioconfig.h new file mode 100644 index 0000000..0c383b2 --- /dev/null +++ b/target/ipad3/include/target/radioconfig.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_RADIOCONFIG_H +#define __TARGET_RADIOCONFIG_H + +/* configuration per target */ + +#define RADIO_VERIFY_BASEBAND_EXISTS 1 + +static const gpio_t target_radio_quiesce_pins[] = +{ + GPIO_UART1_TXD +}; + +#define RADIO_ENABLE_IMEI_OVERRIDE 0 + +#endif /* ! __TARGET_RADIOCONFIG_H */ diff --git a/target/ipad3/include/target/uartconfig.h b/target/ipad3/include/target/uartconfig.h new file mode 100644 index 0000000..6e2b0f0 --- /dev/null +++ b/target/ipad3/include/target/uartconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +/* define radio serial port */ +#define RADIO_SERIAL_PORT (1) +#define RADIO_MAX_READ_ERRORS (10) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/ipad3/init.c b/target/ipad3/init.c new file mode 100644 index 0000000..1ac4202 --- /dev/null +++ b/target/ipad3/init.c @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define J2_PROTO0_BOARD (0) // same as REV1 Dev Board +#define J2_PROTO1_LOCAL_BOARD (1) +#define J2_PROTO1_CHINA_BOARD (2) +#define J2_PROTO2_BOARD (3) // DEV2 board also +#define J2_PRE_EVT_BOARD (4) + +static u_int32_t ipad3_get_board_rev(void); +static void amelia_init(); + +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +static dp_t dp; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 90); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + if (target_config_ap()) { + // Deprecate Proto0/1/2 boards + // Since board revs are shared between dev boards and enclosures, + // depreate only enclosures + if (ipad3_get_board_rev() < J2_PRE_EVT_BOARD) + platform_not_supported(); + } +} + +void target_init(void) +{ + // Cold-boot defaults for GPIOs where pinconfig.h differs, + // and it can't wait for the AppleARMFunction creation. + +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + amelia_init(); +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0x6; + dp.max_link_rate = 0x6; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x0; + dp.vrr_enable = 0x0; + dp.vrr_on = 0x0; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "ipad3", 0); +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; +#endif + uint32_t propSize, propCnt; + char *propName; + void *propData; + + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + } + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/clcd", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + } +#endif + + if (target_config_dev()) { + // Below is needed for DEV1 boards + + // Support for A0 Amelia + if (ipad3_get_board_rev() <= J2_PROTO1_CHINA_BOARD) { + // + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "dwi-version"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((u_int32_t *)propData)[0] = 0; + } + } + + // Proto0 and Proto1-Local support + if (ipad3_get_board_rev() <= J2_PROTO1_LOCAL_BOARD) { + // update wlan node, HSIC_WLAN_READY pin is different + if (FindNode(0, WIFI_DTPATH, &node)) { + propName = "function-device_ready"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // structure looks like this: + // UInt32 gpioPHandle; + // UInt32 gpioSignature; + // UInt32 gpioIndex; + // UInt8 gpioDirection; + // UInt8 gpioPolarity; + // UInt8 gpioDefault; + // UInt8 gpioAltFunction; + ((u_int32_t *)propData)[2] = 0x00001205; // GPIO_3V_1 -> HSIC_WLAN_RDY + } + propName = "interrupts"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // structure looks like this: + // UInt32 vectorNumber; + // UInt32 vectorType; + ((u_int32_t *)propData)[0] = 0x00000095; // GPIO_3V_1 -> HSIC_WLAN_RDY + } + } + } + } + + // Update the bottom prox calibration data + if (FindNode(0, "arm-io/i2c1/prox", &node)) { + propName = "prox-calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update als node with calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "backlight-leakage-channel0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC0', propData, propSize); + } + propName = "backlight-leakage-channel1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC1', propData, propSize); + } + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-sens-matrix-inverse"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCi', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update the gyro1 calibration data + if (FindNode(0, "arm-io/i2c2/gyro1", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-sens-matrix-inverse"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCi', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + } + + // Update camera calibration data + if (FindNode(0, "arm-io/isp", &node)) { + propName = "camera-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CmCl', propData, propSize); + } + } + + return 0; +} + +#endif + +static u_int32_t ipad3_get_board_rev(void) +{ + u_int32_t gpio_board_rev; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + + return (gpio_board_rev & 0x7); +} + +static void amelia_init() +{ + uint32_t board_rev; + + struct pmu_iic_data { + uint8_t addr; + uint8_t data; + }; + struct pmu_iic_data amelia_a0_data[] = { + { 0x22, 0x02 }, // BANKSEL: select bank 2 + { 0xd0, 0x01 }, // TESTMODE: enable test mode + { 0x22, 0x01 }, // BANKSEL: select bank 1 + { 0xa9, 0x00 }, // WLED_CONTROL4: set WLED to IDAC always, WLED_IRATE to 17.5mA + { 0x22, 0x02 }, // BANKSEL: select bank 2 + { 0xd0, 0x00 }, // TESTMODE: disable test mode + { 0x22, 0x00 }, // BANKSEL: select bank 1 + }; + + struct pmu_iic_data amelia_a1_data[] = { + { 0x22, 0x02 }, // BANKSEL: select bank 2 + { 0xd0, 0x01 }, // TESTMODE: enable test mode + { 0x22, 0x01 }, // BANKSEL: select bank 1 + { 0xa9, 0x79 }, // WLED_CONTROL4: set WLED to IDAC always, WLED_IRATE to 18.5mA + { 0xaa, 0x86 }, // WLED_CONTROL5: set ALT_MIN_IDAC_CODE + { 0xab, 0x00 }, // WLED_CONTROL6: set ALT_PWM_START_CODE + { 0xac, 0x18 }, // WLED_CONTROL7: set ALT_DITHER_EN and ALT_DITHER_ALLOW + { 0xb2, 0xee }, // BUCK_CTRL0: operate into Synchronous mode (forced PWM mode) + { 0xb4, 0xee }, // BUCK_CTRL2: operate into Synchronous mode (forced PWM mode) + { 0x22, 0x02 }, // BANKSEL: select bank 2 + { 0xd0, 0x00 }, // TESTMODE: disable test mode + { 0x22, 0x00 }, // BANKSEL: select bank 1 + }; + struct pmu_iic_data *data; + uint8_t entries; + uint8_t i; + + board_rev = ipad3_get_board_rev(); + + // J1/J2 default display brightness too high + // J1/J2 Pre-Proto MLBs and Dev Board Rev.1 Brightness Too High + // Switch J1/J2 backlight over to enhanced hybrid mode + if (target_config_dev() && (board_rev == J2_PROTO0_BOARD || board_rev == J2_PROTO1_LOCAL_BOARD)) { + data = amelia_a0_data; + entries = sizeof(amelia_a0_data)/sizeof(amelia_a0_data[0]); + } else { + data = amelia_a1_data; + entries = sizeof(amelia_a1_data)/sizeof(amelia_a1_data[0]); + } + + // Amelia I2C bus: 0, Amelia Write address: 0x78 + for (i = 0; i < entries; i++) + iic_write(0, 0x78, (const void *)&data[i], 2); +} diff --git a/target/ipad3/pinconfig.c b/target/ipad3/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/ipad3/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/ipad3/properties.c b/target/ipad3/properties.c new file mode 100644 index 0000000..27452af --- /dev/null +++ b/target/ipad3/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad3/rules.mk b/target/ipad3/rules.mk new file mode 100644 index 0000000..0578257 --- /dev/null +++ b/target/ipad3/rules.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1974=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_HIGH \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_HIGH \ + TARGET_USE_HSIC=1 \ + AMC_NUM_CHANNELS=4 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + DP_DTPATH=\"arm-io/edp\" \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + WIFI_DTPATH=\"arm-io/usb1-complex/usb1-ehci/wlan\" \ + USBDEVICE_DTPATH=\"arm-io/usb0-complex/usb0-device\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad3b/include/target/gpiodef.h b/target/ipad3b/include/target/gpiodef.h new file mode 100644 index 0000000..3b519c8 --- /dev/null +++ b/target/ipad3b/include/target/gpiodef.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* P101/P102/P103 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#define GPIO_LCD_PWR_EN GPIO(26, 0) + +#define GPIO_RINGER_AB GPIO(25, 2) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 4, 2) +#define GPIO_BOARD_REV1 GPIO( 4, 3) +#define GPIO_BOARD_REV2 GPIO( 4, 4) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (0) + +/* PMU watchdog tickle; connected to GPIO_PMU_KEEPACT */ +#define GPIO_WDOG_TICKLE GPIO(24, 2) + +// Configure both FMI0 & FMI1 to use differential DQS with DQ set to DQVREF +#define FMI_DIFF_SEL (0x36) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad3b/include/target/nand_spec_tables.h b/target/ipad3b/include/target/nand_spec_tables.h new file mode 100644 index 0000000..aaf6a12 --- /dev/null +++ b/target/ipad3b/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2011 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000101 + }, + + /* useToggleMode */ TRUE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ TRUE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ FALSE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/ipad3b/include/target/pinconfig.h b/target/ipad3b/include/target/pinconfig.h new file mode 100644 index 0000000..3074c03 --- /dev/null +++ b/target/ipad3b/include/target/pinconfig.h @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default P101/P102/P103 SoC Pin Configuration + + Based on I/O spreadsheet rev2p3 + X140 IO Spreadsheet tracker + + Do not modify without first requesting an update to the I/O spreadsheet + */ + +#define CFG_RESERVED CFG_DISABLED + + +/* Different drive strength for AP and DEV. */ +#if PIN_CFG_AP +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##ap +#elif PIN_CFG_DEV +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##dev +#endif + +#if TARGET_HAS_BASEBAND +# define _IFF_BB(cfg) cfg +#else +# define _IFF_BB(cfg) CFG_DISABLED +#endif + +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif + +/* + * config idx pad net notes + * ======== === ======== ================ ======================== + */ + +/* Port 0 */ + CFG_IN, // 0: GPIO0 -> GPIO_BTN_HOME_L also connected to PMU + CFG_IN, // 1: GPIO1 -> GPIO_BTN_ONOFF_L also connected to PMU + _IFF_BB(CFG_IN | PULL_DOWN), // 2: GPIO2 -> GPIO_BB_HSIC_DEV_RDY baseband models only + CFG_IN | PULL_UP, // 3: GPIO3 -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 4: GPIO4 -> GPIO_ALS_IRQ_L + CFG_OUT_0 | AP_DEV_DRIVE_STR(X2, X4), // 5: GPIO5 -> GPIO_BT_WAKE + _IFF_BB(CFG_OUT_0 | AP_DEV_DRIVE_STR(X2, X4)), // 6: GPIO6 -> GPIO_AP_MODEM_WAKE baseband models only + CFG_DISABLED | DRIVE_X2, // 7: GPIO7 -> BB_JTAG_TMS_RF + +/* Port 1 */ + _IFF_BB(CFG_IN | PULL_DOWN), // 8: GPIO10 -> GPIO_BB_RESET_DET_L baseband models only + CFG_IN | PULL_UP, // 9: GPIO11 -> GPIO_ACCEL_IRQ2_L + _IFF_BB(CFG_IN | PULL_DOWN), // 10: GPIO12 -> GPIO_BB_HSIC_RESUME baseband models only + CFG_OUT_0 | AP_DEV_DRIVE_STR(X2, X4), // 11: GPIO13 -> GPIO_WLAN_HSIC_HOST_RDY + CFG_IN | PULL_UP, // 12: GPIO14 -> GPIO_BTN_VOL_DOWN_L + _IFF_BB(CFG_IN), // 13: GPIO15 -> GPIO_BB_GSM_TXBURST baseband models only + CFG_RESERVED, // 14: (reserved) + CFG_RESERVED, // 15: (reserved) + +/* Port 2 */ + CFG_RESERVED, // 16: (reserved) + CFG_RESERVED, // 17: (reserved) + CFG_RESERVED, // 18: (reserved) + CFG_RESERVED, // 19: (reserved) + CFG_RESERVED, // 20: (reserved) + CFG_RESERVED, // 21: (reserved) + CFG_RESERVED, // 22: (reserved) + CFG_RESERVED, // 23: (reserved) + +/* Port 3 */ + CFG_RESERVED, // 24: (reserved) + CFG_RESERVED, // 25: (reserved) + CFG_RESERVED, // 26: (reserved) + CFG_RESERVED, // 27: (reserved) + CFG_RESERVED, // 28: (reserved) + CFG_RESERVED, // 29: (reserved) + CFG_RESERVED, // 30: (reserved) + CFG_RESERVED, // 31: (reserved) + +/* Port 4 */ + _IFF_BB(CFG_IN | DRIVE_X2), // 32: GPIO8 -> GPIO_BB_RST_L baseband models only + _IFF_BB(CFG_IN | AP_DEV_DRIVE_STR(X2, X4)), // 33: GPIO9 -> GPIO_BB_RADIO_ON baseband models only + CFG_DISABLED, // 34: EHCI_PORT_PWR0 -> GPIO_BRD_REV0 + CFG_DISABLED, // 35: EHCI_PORT_PWR1 -> GPIO_BRD_REV1 + CFG_DISABLED, // 36: EHCI_PORT_PWR2 -> GPIO_BRD_REV2 + CFG_DISABLED, // 37: EHCI_PORT_PWR3 -> NC_EHCI_PORT_PWR3_AP + CFG_DISABLED, // 38: GPIO16 -> NC_GPIO_BOARD_ID_3 + CFG_IN, // 39: GPIO17 -> PMU_GPIO_TS_INT + +/* Port 5 */ + CFG_DISABLED, // 40: GPIO18 -> GPIO_BOOT_CONFIG_0 + _IFF_BB(CFG_IN | DRIVE_X2), // 41: GPIO19 -> GPIO_BB_GPS_SYNC baseband models only + _IFF_BB(CFG_IN | AP_DEV_DRIVE_STR(X2, X6)), // 42: UART1_TXD -> UART1_BB_TXD baseband models only + _IFF_BB(CFG_FUNC0), // 43: UART1_RXD -> UART1_BB_RXD baseband models only + _IFF_BB(CFG_IN | AP_DEV_DRIVE_STR(X2, X6)), // 44: UART1_RTSN -> UART1_BB_RTS_L baseband models only + _IFF_BB(CFG_FUNC0), // 45: UART1_CTSN -> UART1_BB_CTS_L baseband models only + CFG_DISABLED, // 46: FMI0_CEN3 -> NC_FMI0_CE3_L + CFG_DISABLED, // 47: FMI0_CEN2 -> NC_FMI0_CE2_L + +/* Port 6 */ + CFG_DISABLED, // 48: FMI0_CEN1 -> NC_FMI0_CE1_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 49: FMI0_CEN0 -> FMI0_CE0_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 50: FMI0_CLE -> FMI0_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 51: FMI0_ALE -> FMI0_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 52: FMI0_REN -> FMI0_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 53: FMI0_WEN -> FMI0_WE_L + CFG_DISABLED, // 54: FMI0_WENN -> NC_FMI0_RE + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 55: FMI0_IO7 -> FMI0_AD<7> + +/* Port 7 */ + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 56: FMI0_IO6 -> FMI0_AD<6> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 57: FMI0_IO5 -> FMI0_AD<5> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 58: FMI0_IO4 -> FMI0_AD<4> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 59: FMI0_DQS -> FMI0_DQS + CFG_DISABLED, // 60: FMI0_DQSN -> NC_FMI0_DQSN + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 61: FMI0_IO3 -> FMI0_AD<3> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 62: FMI0_IO2 -> FMI0_AD<2> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 63: FMI0_IO1 -> FMI0_AD<1> + +/* Port 8 */ + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 64: FMI0_IO0 -> FMI0_AD<0> + CFG_DISABLED, // 65: FMI0_CEN7 -> NC_FMI0_CE7_L + CFG_DISABLED, // 66: FMI0_CEN6 -> NC_FMI0_CE6_L + CFG_DISABLED, // 67: FMI0_CEN5 -> NC_FMI0_CE5_L + CFG_DISABLED, // 68: FMI0_CEN4 -> NC_FMI0_CE4_L + CFG_DISABLED, // 69: FMI1_CEN3 -> NC_FMI1_CE3_L + CFG_DISABLED, // 70: FMI1_CEN2 -> NC_FMI1_CE2_L + CFG_DISABLED, // 71: FMI1_CEN1 -> NC_FMI1_CE1_L + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72: FMI1_CEN0 -> FMI1_CE0_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 73: FMI1_CLE -> FMI1_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74: FMI1_ALE -> FMI1_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 75: FMI1_REN -> FMI1_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 76: FMI1_WEN -> FMI1_WE_L + CFG_DISABLED, // 77: FMI1_WENN -> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 78: FMI1_IO7 -> FMI1_AD<7> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 79: FMI1_IO6 -> FMI1_AD<6> + +/* Port 10 */ + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 80: FMI1_IO5 -> FMI1_AD<5> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 81: FMI1_IO4 -> FMI1_AD<4> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 82: FMI1_DQS -> FMI1_DQS + CFG_DISABLED, // 83: FMI1_DQSN -> FMI1_DQSN + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 84: FMI1_IO3 -> FMI1_AD<3> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 85: FMI1_IO2 -> FMI1_AD<2> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 86: FMI1_IO1 -> FMI1_AD<1> + CFG_FUNC0 | BUS_HOLD | DRIVE_X2 | SLOW_SLEW, // 87: FMI1_IO0 -> FMI1_AD<0> + +/* Port 11 */ + CFG_DISABLED, // 88: FMI1_CEN7 -> NC_FMI1_CE7_L + CFG_DISABLED, // 89: FMI1_CEN6 -> NC_FMI1_CE6_L + CFG_DISABLED, // 90: FMI1_CEN5 -> NC_FMI1_CE5_L + CFG_DISABLED, // 91: FMI1_CEN4 -> NC_FMI1_CE4_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X2, X6), // 92: UART2_TXD -> UART2_TS_ACC_TXD + CFG_FUNC0 | PULL_UP, // 93: UART2_RXD -> UART2_TS_ACC_RXD + CFG_DISABLED, // 94: UART2_RTSN -> NC_UART2_RTSN + CFG_DISABLED | DRIVE_X2, // 95: UART2_CTSN -> BB_JTAG_TCK_RF + +/* Port 12 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X2, X6), // 96: UART3_TXD -> UART3_BT_TXD + CFG_FUNC0 | PULL_UP, // 97: UART3_RXD -> UART3_BT_RXD + CFG_OUT_1 | AP_DEV_DRIVE_STR(X2, X6), // 98: UART3_RTSN -> UART3_BT_RTS_L + CFG_FUNC0 | PULL_UP, // 99: UART3_CTSN -> UART3_BT_CTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X2, X6), // 100: UART4_TXD -> UART4_WLAN_TXD + CFG_FUNC0 | PULL_UP, // 101: UART4_RXD -> UART4_WLAN_RXD + CFG_DISABLED, // 102: UART4_RTSN -> NC_UART4_RTS_L + CFG_DISABLED, // 103: UART4_CTSN -> NC_UART4_CTS_L + +/* Port 13 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X2, X6), // 104: UART6_TXD -> UART6_AP_TXD + CFG_FUNC0 | PULL_UP, // 105: UART6_RXD -> UART6_AP_RXD + CFG_DISABLED, // 106: UART6_RTSN -> NC_UART6_RTSN + CFG_DISABLED, // 107: UART6_CTSN -> NC_UART6_CTSN + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 108: SPI1_SCLK -> SPI1_CODEC_SCLK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 109: SPI1_MOSI -> SPI1_CODEC_MOSI + CFG_FUNC0, // 110: SPI1_MISO -> SPI1_CODEC_MISO + CFG_OUT_1 | AP_DEV_DRIVE_STR(X4, X6), // 111: SPI1_SSIN -> SPI1_CODEC_CS_L + +/* Port 14 */ + CFG_DISABLED, // 112: SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_DISABLED, // 113: SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 114: SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 115: SPI0_SSIN -> TP_SPI0_SSIN + CFG_DISABLED, // 116: SPI2_SCLK -> BB_JTAG_TDO_RF + CFG_DISABLED | DRIVE_X2, // 117: SPI2_MOSI -> BB_JTAG_TDI_RF + CFG_DISABLED | DRIVE_X2, // 118: SPI2_MISO -> BB_JTAG_TRST_RF_L + _IFF_BB(CFG_OUT_0 | AP_DEV_DRIVE_STR(X2, X4)), // 119: SPI2_SSIN -> GPIO_BB_HSIC_HOST_RDY baseband models only + +/* Port 15 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 120: I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 121: I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X2, X6), // 122: I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X2, X6), // 123: I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 124: ISP0_SDA -> ISP0_CAM_RF_I2C_SDA + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 125: ISP0_SCL -> ISP0_CAM_RF_I2C_SCL + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 126: ISP1_SDA -> ISP1_CAM_FF_I2C_SDA + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 127: ISP1_SCL -> ISP1_CAM_FF_I2C_SCL + +/* Port 16 */ + CFG_DISABLED, // 128: MIPI_VSYNC -> NC_MIPI_VSYNC_H5 + CFG_FUNC0 | PULL_DOWN, // 129: TMR32_PWM0 -> GPIO_GYRO_IRQ2 + CFG_FUNC0 | PULL_UP, // 130: TMR32_PWM1 -> GPIO_ACCEL_IRQ1_L + CFG_DISABLED, // 131: TMR32_PWM2 -> NC_TMR32_PWM2_AP + CFG_DISABLED, // 132: SWI_DATA -> NC_SWI_AP + CFG_FUNC0 | PULL_DOWN, // 133: DWI_DI -> DWI_AP_DI + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 134: DWI_DO -> DWI_AP_DO + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 135: DWI_CLK -> DWI_AP_CLK + +/* Port 17 */ + CFG_OUT_1 | DRIVE_X2, // 136: SENSOR0_RST -> ISP0_CAM_RF_SHUTDOWN + CFG_OUT_0 | AP_DEV_DRIVE_STR(X4, X6), // 137: SENSOR0_CLK -> ISP0_CAM_RF_CLK_R + CFG_OUT_0 | PULL_DOWN | DRIVE_X2, // 138: SENSOR1_RST -> ISP1_CAM_FF_SHUTDOWN_L + CFG_OUT_0 | AP_DEV_DRIVE_STR(X4, X6), // 139: SENSOR1_CLK -> ISP1_CAM_FF_CLK_R + CFG_RESERVED, // 140: (reserved) + CFG_RESERVED, // 141: (reserved) + CFG_RESERVED, // 142: (reserved) + CFG_RESERVED, // 143: (reserved) + +/* Port 18 */ + CFG_RESERVED, // 144: (reserved) + CFG_RESERVED, // 145: (reserved) + CFG_RESERVED, // 146: (reserved) + CFG_RESERVED, // 147: (reserved) + CFG_RESERVED, // 148: (reserved) + CFG_RESERVED, // 149: (reserved) + CFG_RESERVED, // 150: (reserved) + CFG_RESERVED, // 151: (reserved) + +/* Port 19 */ + CFG_RESERVED, // 152: (reserved) + CFG_RESERVED, // 153: (reserved) + CFG_RESERVED, // 154: (reserved) + CFG_RESERVED, // 155: (reserved) + CFG_RESERVED, // 156: (reserved) + CFG_RESERVED, // 157: (reserved) + CFG_RESERVED, // 158: (reserved) + CFG_RESERVED, // 159: (reserved) + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X4, // 160: CPU0_SWITCH -> CPU0_SWITCH + CFG_FUNC0 | DRIVE_X4, // 161: CPU1_SWITCH -> CPU1_SWITCH + CFG_DISABLED, // 162: ISP0_PRE_FLASH -> NC_ISP0_CAM_RF_FLASH + CFG_OUT_0 | DRIVE_X4, // 163: ISP0_FLASH -> ISP0_CAM_RF_RST_L + CFG_DISABLED | DRIVE_X4, // 164: ISP1_PRE_FLASH -> SOCHOT0_L + CFG_FUNC1 | DRIVE_X4, // 165: ISP1_FLASH -> SOCHOT1_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 166: I2S0_MCK -> I2S0_CODEC_ASP_MCK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 167: I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + +/* Port 21 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 168: I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 169: I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 170: I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X2, // 171: I2S1_MCK -> I2S1_SPKAMP_MCK + CFG_FUNC0 | DRIVE_X2, // 172: I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2, // 173: I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2, // 174: I2S1_DOUT -> I2S1_SPKAMP_DOUT + CFG_FUNC0, // 175: I2S1_DIN -> I2S1_SPKAMP_DIN + +/* Port 22 */ + CFG_DISABLED, // 176: I2S2_MCK -> NC_I2S2_MCK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 177: I2S2_LRCK -> I2S2_BT_LRCK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 178: I2S2_BCLK -> I2S2_BT_BCLK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 179: I2S2_DOUT -> I2S2_BT_DOUT + CFG_FUNC0, // 180: I2S2_DIN -> I2S2_BT_DIN + CFG_DISABLED, // 181: I2S3_MCK -> NC_I2S3_MCK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 182: I2S3_LRCK -> I2S3_CODEC_XSP_LRCK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 183: I2S3_BCLK -> I2S3_CODEC_XSP_BCLK + +/* Port 23 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 184: I2S3_DOUT -> I2S3_CODEC_XSP_DOUT + CFG_FUNC0, // 185: I2S3_DIN -> I2S3_CODEC_XSP_DIN + CFG_DISABLED, // 186: I2S4_MCK -> NC_I2S4_MCK + CFG_DISABLED, // 187: I2S4_LRCK -> NC_I2S4_LRCK + CFG_DISABLED, // 188: I2S4_BCLK -> NC_I2S4_BCLK + CFG_DISABLED, // 189: I2S4_DOUT -> NC_I2S4_DOUT + CFG_DISABLED, // 190: I2S4_DIN -> NC_I2S4_DIN + CFG_DISABLED, // 191: SPDIF -> NC_AP_GPIO216 + +/* Port 24 */ + CFG_IN, // 192: GPIO20 -> GPIO_PROX_IRQ_L + CFG_IN | PULL_DOWN, // 193: GPIO21 -> GPIO_GYRO_IRQ1 + CFG_OUT_0 | DRIVE_X2, // 194: GPIO22 -> GPIO_PMU_KEEPACT + CFG_IN | PULL_UP, // 195: GPIO23 -> GPIO_PMU_IRQ_L + CFG_IN | PULL_DOWN, // 196: GPIO24 -> GPIO_WLAN_HSIC_DEV_RDY + CFG_DISABLED, // 197: GPIO25 -> GPIO_BOOT_CONFIG_1 + CFG_IN | PULL_DOWN, // 198: GPIO26 -> GPIO_FORCE_DFU + CFG_OUT_0 | PULL_DOWN | DRIVE_X1, // 199: GPIO27 -> GPIO_DFU_STATUS + +/* Port 25 */ + CFG_DISABLED, // 200: GPIO28 -> GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 201: GPIO29 -> GPIO_BOOT_CONFIG_3 + CFG_IN, // 202: GPIO30 -> GPIO_BTN_SRL_L a.k.a. ringer switch + CFG_IN | PULL_UP, // 203: GPIO31 -> GPIO_GRAPE_IRQ_L + CFG_IN | PULL_DOWN, // 204: GPIO32 -> GPIO_WL_HSIC_RESUME + CFG_OUT_0 | DRIVE_X2, // 205: GPIO33 -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | DRIVE_X2, // 206: GPIO34 -> GPIO_SPKAMP_KEEPALIVE + CFG_IN | PULL_UP, // 207: GPIO35 -> GPIO_SPKAMP_RIGHT_IRQ_L + +/* Port 26 */ + CFG_OUT_0 | DRIVE_X2, // 208: GPIO36 -> PM_LCDVDD_PWREN + CFG_IN | PULL_UP, // 209: GPIO37 -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_IN | PULL_UP, // 210: GPIO38 -> SPK_ID + CFG_IN | PULL_UP, // 211: GPIO39 -> GPIO_CODEC_IRQ_L + CFG_RESERVED, // 212: (reserved) + CFG_RESERVED, // 213: (reserved) + CFG_RESERVED, // 214: (reserved) + CFG_RESERVED, // 215: (reserved) + +/* Port 27 */ + CFG_RESERVED, // 216: (reserved) + CFG_RESERVED, // 217: (reserved) + CFG_RESERVED, // 218: (reserved) + CFG_RESERVED, // 219: (reserved) + CFG_RESERVED, // 220: (reserved) + CFG_RESERVED, // 221: (reserved) + CFG_RESERVED, // 222: (reserved) + CFG_RESERVED, // 223: (reserved) + +/* Port 28 */ + CFG_FUNC0 | DRIVE_X4, // 224: SPI3_MOSI -> SPI3_GRAPE_MOSI + CFG_FUNC0, // 225: SPI3_MISO -> SPI3_GRAPE_MISO + CFG_FUNC0 | DRIVE_X4, // 226: SPI3_SCLK -> SPI3_GRAPE_SCLK + CFG_OUT_1 | AP_DEV_DRIVE_STR(X4, X6), // 227: SPI3_SSIN -> SPI3_GRAPE_CS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 228: I2C2_SDA -> I2C2_SDA_3V0 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X4, X6), // 229: I2C2_SCL -> I2C2_SCL_3V0 + CFG_OUT_1 | DRIVE_X2, // 230: GPIO_3V0 -> GPIO_GRAPE_FW_DNLD_EN_L + CFG_OUT_0 | DRIVE_X2, // 231: GPIO_3V1 -> GPIO_GRAPE_RST_L + +/* Port 29 */ + CFG_DISABLED, // 232: DP_HPD -> NC_DP_HPD + CFG_FUNC0, // 233: EDP_HPD -> EDP_HPD + CFG_DISABLED, // 234: UART0_TXD -> NC_UART0_TXD + CFG_DISABLED, // 235: UART0_RXD -> NC_UART0_RXD + CFG_FUNC1 | AP_DEV_DRIVE_STR(X1, X6), // 236: UART5_RXD -> UART5_BATTERY_TRXD + CFG_DISABLED, // 237: UART5_TXD -> NC_UART5_TXD + CFG_DISABLED, // 238: TST_CLKOUT -> TP_AP_TST_CLKOUT + CFG_IN, // 239: TST_STPCLK -> AP_TST_STPCLK + +/* Port 30 */ + CFG_FUNC0 | DRIVE_X2, // 240: WDOG -> AP_WDOG + CFG_RESERVED, // 241: (reserved) + CFG_RESERVED, // 242: (reserved) + CFG_RESERVED, // 243: (reserved) + CFG_RESERVED, // 244: (reserved) + CFG_RESERVED, // 245: (reserved) + CFG_RESERVED, // 246: (reserved) + CFG_RESERVED, // 247: (reserved) +}; + +#undef AP_DEV_DRIVE_STR +#undef _IFF_BB diff --git a/target/ipad3b/include/target/powerconfig.h b/target/ipad3b/include/target/powerconfig.h new file mode 100644 index 0000000..48bb5f6 --- /dev/null +++ b/target/ipad3b/include/target/powerconfig.h @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Force bypass off + { PMU_IIC_BUS, kD2018_LDO1, 0x24 }, // PP3V0_GRAPE 3.00V + { PMU_IIC_BUS, kD2018_LDO2, 0x2A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD2018_LDO3, 0x0E }, // PP3V2_S2R_USBMUX 3.20V + { PMU_IIC_BUS, kD2018_LDO4, 0x18 }, // PP3V0_SENSOR 3.00V + { PMU_IIC_BUS, kD2018_LDO5, 0x1A }, // LDO5 3.00V + { PMU_IIC_BUS, kD2018_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD2018_LDO7, 0x12 }, // PP3V0_S2R_TRISTAR 3.00V + { PMU_IIC_BUS, kD2018_LDO8, 0x14 }, // PP3V0_S2R_HALL 3.00V + { PMU_IIC_BUS, kD2018_LDO9, 0x12 }, // PP3V0_IO 3.00V + { PMU_IIC_BUS, kD2018_LDO10, 0x0A }, // LDO10 3.00V + { PMU_IIC_BUS, kD2018_LDO11, 0x16 }, // PP2V8_CAM 2.80V + { PMU_IIC_BUS, kD2018_LDO12, 0x10 }, // PP1V0 1.00V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Leave bypass off +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2018_ACTIVE1, 0x7F }, // Everything but LDO1 + { PMU_IIC_BUS, kD2018_ACTIVE2, 0xE7 }, // Everything but LDO5 and LDO6 + { PMU_IIC_BUS, kD2018_ACTIVE3, 0xC6 }, // LDO11, LDO12, LDO16, and CP + { PMU_IIC_BUS, kD2018_ACTIVE4, 0xAC }, // CPU1V2 and CPU1V8, CPUA&CPUB switches + { PMU_IIC_BUS, kD2018_ACTIVE5, 0x03 }, // WLEDA/B BST + { PMU_IIC_BUS, kD2018_LCM_CONTROL1, 0x05 }, // unused 5.25 + { PMU_IIC_BUS, kD2018_LCM_CONTROL2, 0x05 }, // unused 5.25V + { PMU_IIC_BUS, kD2018_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD2018_LCM_BST_CONTROL, 0x14 }, // VBOOST_LCM 6.00V + + { PMU_IIC_BUS, kDIALOG_BANKSEL, 1 }, + { PMU_IIC_BUS, kD2018_TRIM_CONF68, 0x1A }, // BUCK0-A, BUCK0-B = Forced Sync mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0 }, +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // HIB_32K on, DWI off + + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_A, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_B, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_C, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_D, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_E, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_F, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_G, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_H, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_I, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_J, 0x00 }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* GPIO configuration from I/O spreadsheet. + Request spreadsheet update before modifying + X140 IO Spreadsheet tracker + + The following differences from OTP are intentional: + - GPIO6: Enable wake + - GPIO7: Enable wake + - GPIO8: Enable wake + - GPIO9: Enable wake + - GPIO10: Enable wake, any edge trigger + */ + { PMU_IIC_BUS, kD2018_BUCK4, 0x98 }, // BUCK4 1.2V + { PMU_IIC_BUS, kD2018_BUCK4_HIB, 0x98 }, // BUCK4_HIB 1.2V + + { PMU_IIC_BUS, kD2018_SYS_GPIO_1, 0x11 }, // PMU_GPIO_CLK_32K_GRAPE Out 0, Push-Pull, CPU_1V8 + { PMU_IIC_BUS, kD2018_SYS_GPIO_2, 0x49 }, // PMU_GPIO_CLK_32K_WLAN CLK32K, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2018_SYS_GPIO_3, 0x09 }, // PMU_GPIO_BT_RST_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2018_SYS_GPIO_4, 0x09 }, // PMU_GPIO_WLAN_RST_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2018_SYS_GPIO_5, 0x09 }, // PMU_GPIO_BB_RST_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2018_SYS_GPIO_6, 0xDA }, // PMU_GPIO_BATTERY_SWI In, F Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_7, 0xBA }, // PMU_GPIO_BT_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_8, 0xBA }, // PMU_GPIO_WLAN_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2018_SYS_GPIO_9, 0xBA }, // PMU_GPIO_BB_HOST_WAKE In, R Edge, Wake, No Pull Down, Disable Pull-Up +#else + { PMU_IIC_BUS, kD2018_SYS_GPIO_9, 0xB9 }, // PMU_GPIO_BB_HOST_WAKE In, R Edge, No Wake, Pull Down, Disable Pull-Up +#endif + { PMU_IIC_BUS, kD2018_SYS_GPIO_10, 0xEA }, // PMU_GPIO_CODEC_HS_INT_L In, Any Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_11, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_12, 0x7B }, // PMU_GPIO_TS_INT In, Hi level, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_13, 0xFA }, // PMU_GPIO_HALL_IRQ_1 In, Any Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_14, 0xC8 }, // PMU_GPIO_CODEC_RST_L In, F Edge, No Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD2018_SYS_GPIO_15, 0xFA }, // PMU_GPIO_HALL_IRQ_2 In, Any Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_16, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD2018_SYS_GPIO_17, 0x01 }, // PMU_GPIO_BB_VBUS_DET Out 0, Push-Pull, VCC_MAIN + + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB1, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB2, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB3, 0x02 }, // no debounce on GPIO6 + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB4, 0x10 }, // no debounce on GPIO7 + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB5, 0x02 }, // no debounce on GPIO10 + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB6, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB7, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB8, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD2018_SYS_GPIO_DEB9, 0x12 }, // 10ms debounce + + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) & DWI + + { PMU_IIC_BUS, kD2018_TDEV1_RISE, 0x04 }, // PMU support for SOCHOT1 + { PMU_IIC_BUS, kD2018_TDEV2_RISE, 0x04 } // PMU support for SOCHOT1 +}; + + +static const struct pmu_setup_struct pmu_cold_init_a0_samples[] = +{ + // P102: WLED boost frequency incorrectly set to 2MHz in the initial A0 samples + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x03 }, // bank 3 + { PMU_IIC_BUS, 0xd2, 0x01 }, // testmode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, // bank 1 + { PMU_IIC_BUS, 0xf1, 0x88 }, // WLED boost frequency 1 MHz + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x03 }, // bank 3 + { PMU_IIC_BUS, 0xd2, 0x00 }, // disable testmode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, // bank 0 +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL2, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2018_LDO16 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { // gas gauge can have up to 16 entries + { 4000, 1000, 1600, 3150 }, // 10 - 16C 0.27C + { 4100, 1000, 1600, 2350 }, // 0.27C + { USHRT_MAX, 1000, 1600, 1350 }, // 0.11C + { 4000, 1500, 2100, 3150 }, // 15 - 21C 0.27C + { 4100, 1500, 2100, 3150 }, // 0.27C + { USHRT_MAX, 1500, 2100, 2350 }, // 0.2C + { 4000, 2000, 3500, 3150 }, // 20 - 35C 0.27C + { 4100, 2000, 3500, 3150 }, // 0.27C + { USHRT_MAX, 2000, 3500, 3150 }, // 0.27C + { 4000, 3400, 4500, 3150 }, // 34 - 45C 0.27C + { 4100, 3400, 4500, 3150 }, // 0.27C + { USHRT_MAX, 3400, 4500, 3150 }, // 0.27C +}; + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 1287 /* 10% brightness */ +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define GASGAUGE_BATTERYID_BLOCK 1 +#define GASGAUGE_CHARGETABLE_BLOCK 3 +static const unsigned int atv_voltage_limit[16] = { 3600, 3650, 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350 }; +static const unsigned int atv_current_limit[16] = { 150, 350, 550, 750, 950, 1150, 1350, 1550, 1750, 1950, 2150, 2350, 2550, 2750, 2950, 3150 }; + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/ipad3b/include/target/radioconfig.h b/target/ipad3b/include/target/radioconfig.h new file mode 100644 index 0000000..4b3272a --- /dev/null +++ b/target/ipad3b/include/target/radioconfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_RADIOCONFIG_H +#define __TARGET_RADIOCONFIG_H + +/* configuration per target */ + +// XXX config below remains as copied from +// '.../targets/ipad3/include/target/radioconfig'; +// confirm settings remain appropriate for P101/P102/P103 + +#define RADIO_VERIFY_BASEBAND_EXISTS 1 + +static const gpio_t target_radio_quiesce_pins[] = +{ + GPIO_UART1_TXD +}; + +#define RADIO_ENABLE_IMEI_OVERRIDE 0 + +#endif /* ! __TARGET_RADIOCONFIG_H */ diff --git a/target/ipad3b/include/target/uartconfig.h b/target/ipad3b/include/target/uartconfig.h new file mode 100644 index 0000000..84dd2d1 --- /dev/null +++ b/target/ipad3b/include/target/uartconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (6) + +/* define radio serial port */ +#define RADIO_SERIAL_PORT (1) +#define RADIO_MAX_READ_ERRORS (10) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/ipad3b/init.c b/target/ipad3b/init.c new file mode 100644 index 0000000..f4f773d --- /dev/null +++ b/target/ipad3b/init.c @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define P101_PROTO0_BOARD (0) +#define P101_PROTO2_BOARD (1) +#define P101_EVT_BOARD (2) + +static u_int32_t ipad3b_get_board_rev(void); +static void amelia_init(); + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 90); +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +static dp_t dp; +#endif + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + if (target_config_ap()) { + // Deprecate Proto0/1 + // Since board revs are shared between dev boards and enclosures, + // depreate only enclosures + if (ipad3b_get_board_rev() < P101_PROTO2_BOARD) + platform_not_supported(); + } +} + +void target_init(void) +{ + // Cold-boot defaults for GPIOs where pinconfig.h differs, + // and it can't wait for the AppleARMFunction creation. + + unsigned int i; + + // P102 use 18.5mA for IRATE setting, not OTP value of 21mA + if (ipad3b_get_board_rev() <= P101_EVT_BOARD) { + const uint8_t pmu_data[] = { + 0x23,0x03, // bank 3 + 0xd2,0x01, // enter test mode + 0x23,0x01, // bank 1 + 0x89,0x21, // WLED_CTRL4 16kHz, 18.5mA + 0x23,0x03, // bank 3 + 0xd2,0x00, // exit test mode + 0x23,0x00 // bank 0 + }; + + for (i = 0; i < sizeof(pmu_data); i += 2) + iic_write(0, 0x78, &pmu_data[i], 2); + } + + // lower VDD_UNDER to 2.9V + { + uint8_t pmu_data[] = { + 0x23,0x03, // bank 3 + 0xd2,0x01, // enter test mode + 0x23,0x01, // bank 1 + 0xd5,0x00, // TRIM/CONF73 + 0x23,0x03, // bank 3 + 0xd2,0x00, // exit test mode + 0x23,0x00 // bank 0 + }; + + + for (i = 0; i < sizeof(pmu_data); i += 2) { + if (i == 6) { + iic_read(0, 0x78, &pmu_data[i], 1, &pmu_data[i+1], 1, IIC_NORMAL); + pmu_data[i+1] = (pmu_data[i+1] & ~7) | 2; // VDD_FAULT = 2.9V + } + iic_write(0, 0x78, &pmu_data[i], 2); + } + } + +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0x6; + dp.max_link_rate = 0x6; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x0; + dp.vrr_enable = 0x0; + dp.vrr_on = 0x0; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + // XXX follow up on 'display-timing' below setting below + + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "ipad3", 0); +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; +#endif + uint32_t propSize, propCnt; + char *propName; + void *propData; + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + } + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/clcd", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + } +#endif + + // Update the bottom prox calibration data + if (FindNode(0, "arm-io/i2c1/prox", &node)) { + propName = "prox-calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPCl', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update als node with calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "backlight-leakage-channel0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC0', propData, propSize); + } + propName = "backlight-leakage-channel1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC1', propData, propSize); + } + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-sens-matrix-inverse"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCi', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update the gyro1 calibration data + if (FindNode(0, "arm-io/i2c2/gyro1", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-sens-matrix-inverse"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCi', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + } + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c0/audio-speaker0", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr[2]; + if (syscfgCopyDataForTag('VPBR', vpbr, sizeof(vpbr)) == 2) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | ((vpbr[0] - 6) & 0x1f); + ((uint8_t *)propData)[32] = (((uint8_t *)propData)[12] & ~0x1f) | ((vpbr[1] - 6) & 0x1f); + } + uint8_t vbst[2]; + if (syscfgCopyDataForTag('VBST', vbst, sizeof(vbst)) == 2) { + ((uint8_t *)propData)[16] = vbst[0]; + ((uint8_t *)propData)[36] = vbst[1]; + } + } + } + + // Update camera calibration data + if (FindNode(0, "arm-io/isp", &node)) { + propName = "camera-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CmCl', propData, propSize); + } + } + + // Dev1 audio config + if (target_config_dev()) { + if (ipad3b_get_board_rev() < P101_PROTO2_BOARD) { + // disable speaker nodes + if (FindNode(0, "arm-io/i2c0/audio-speaker0", &node)) { + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "AAPL,ignore", kPropNameLength); + } + } + if (FindNode(0, "arm-io/i2c0/audio-speaker1", &node)) { + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "AAPL,ignore", kPropNameLength); + } + } + + // restore built-in speaker + if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { + propName = "function-spkr_mute_xxx"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-spkr_mute", kPropNameLength); + } + propName = "aout1-speaker_xxx"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "aout1-speaker", kPropNameLength); + } + propName = "aout2-speaker_xxx"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "aout2-speaker", kPropNameLength); + } + } + } + } + + return 0; +} + +#endif + +static u_int32_t ipad3b_get_board_rev(void) +{ + u_int32_t gpio_board_rev; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + + return (gpio_board_rev & 0x7); +} diff --git a/target/ipad3b/pinconfig.c b/target/ipad3b/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/ipad3b/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/ipad3b/properties.c b/target/ipad3b/properties.c new file mode 100644 index 0000000..27452af --- /dev/null +++ b/target/ipad3b/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad3b/rules.mk b/target/ipad3b/rules.mk new file mode 100644 index 0000000..acd1abc --- /dev/null +++ b/target/ipad3b/rules.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2018=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=CHIPID_RAM_VOLTAGE_LOW \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_MED \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=5 \ + TARGET_USE_HSIC=1 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + AMC_NUM_CHANNELS=4 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + DP_DTPATH=\"arm-io/edp\" \ + MULTITOUCH_DTPATH=\"arm-io/spi3/multi-touch\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci0/wlan\" \ + USBDEVICE_DTPATH=\"arm-io/usb0-complex/usb0-device\" \ + DPTX_PLL_CTL_VALUE=0x14 \ + DPTX_ANALOG_CTL_2_VALUE=0x0d \ + DPTX_ANALOG_CTL_3_VALUE=0x60 \ + DPTX_FINE_PRE_EMPHASIS_VOLTAGE_VALUE=2 + + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad4/include/target/adbe_settings.h b/target/ipad4/include/target/adbe_settings.h new file mode 100644 index 0000000..3c15c04 --- /dev/null +++ b/target/ipad4/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_AFC_TEARDOWN_ENABLE | DBEMODECNTL_PMGR_CLK_GATE_ENABL| DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/ipad4/include/target/amcconfig.h b/target/ipad4/include/target/amcconfig.h new file mode 100644 index 0000000..535f615 --- /dev/null +++ b/target/ipad4/include/target/amcconfig.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_ZQCL), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00020000, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 10, + .phywrlat = 2, + .pdn = 0x22000403, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .derate = 0x2483135b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x00000021, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00050000, + .aref_freq0 = 0x00000110, + .schen_default = 0x00000110, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x01, + .pwrmngten_default = 0x00100100, + .mcphyupdate1 = 0x00000001, + .odts = 0x190, + .readleveling = 0x00000300, + .offset_shift_hynix = 0, + .offset_shift_elpida = 1, + .offset_shift_elpida25nm = -2, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + .mifcassch = 0x00000110, + .arefparam = 0x0c022131, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 50MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001728 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQBRST, 0x04100410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOS, 0x00001919 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +}; diff --git a/target/ipad4/include/target/aspnandconfig.h b/target/ipad4/include/target/aspnandconfig.h new file mode 100644 index 0000000..bed46e8 --- /dev/null +++ b/target/ipad4/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 8 +#define ASPNAND_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/ipad4/include/target/gpiodef.h b/target/ipad4/include/target/gpiodef.h new file mode 100644 index 0000000..1609684 --- /dev/null +++ b/target/ipad4/include/target/gpiodef.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPad4,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_PWR_EN GPIO( 2, 7) + +#define GPIO_RINGER_AB GPIO(13, 6) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 6) +#define GPIO_BOARD_REV1 GPIO(14, 5) +#define GPIO_BOARD_REV2 GPIO(14, 4) +#define GPIO_BOARD_REV3 GPIO(14, 3) + +/* which IICs to initialize */ +#define IICS_MASK (0x5) + +#define TRISTAR_IIC_BUS (2) + +/* D2089 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(12, 6) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad4/include/target/pinconfig.h b/target/ipad4/include/target/pinconfig.h new file mode 100644 index 0000000..846804d --- /dev/null +++ b/target/ipad4/include/target/pinconfig.h @@ -0,0 +1,787 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 1.10 + I/O Spreadsheet tracker: J72 IO Spreadsheet +*/ + +/* Different drive strength for AP and DEV. */ +#if PIN_CFG_AP +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##ap +#elif PIN_CFG_DEV +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##dev +#endif + +#ifdef SUB_TARGET_J71 +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_DOWN_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 6 : GPIO[4] -> GPIO_CAM_ALS2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : GPIO[5] -> GPIO_BT_WAKE + +/* Port 1 */ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 8 : GPIO[6] -> GPIO_SOC2BB_WAKE_MODEM + CFG_DISABLED, // 9 : GPIO[7] -> NC_GPIO7 + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 10 : GPIO[8] -> GPIO_SOC2BB_RST_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 11 : GPIO[9] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED | PULL_DOWN, // 12 : GPIO[10] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 13 : GPIO[11] -> NC_GPIO11 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 14 : GPIO[12] -> GPIO_SOC2OSCAR_DBGEN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 15 : GPIO[13] -> GPIO_SOC2GRAPE_RESET_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> NC_GPIO14 + CFG_DISABLED, // 17 : GPIO[15] -> GPIO_BB2SOC_GSM_TXBURST + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID_3 + CFG_IN, // 19 : GPIO[17] -> GPIO_TS2SOC2PMU_INT + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 21 : GPIO[19] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN, // 22 : GPIO[20] -> GPIO_PROX2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 23 : GPIO[21] -> GPIO_SOC2LCD_PWREN + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2WLAN_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : UART2_RXD -> UART2_WLAN2SOC_TX + CFG_DISABLED, // 38 : UART2_RTSN -> NC_GPIO_UART2_RTSN + CFG_DISABLED, // 39 : UART2_CTSN -> NC_GPIO_UART2_CTSN + +/* Port 5 */ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX + CFG_DISABLED | SLOW_SLEW, // 41 : UART3_RXD -> UART3_BB2SOC_TX + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_DISABLED | SLOW_SLEW, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 44 : UART5_RTXD -> UART5_BATT_TRXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED, // 68 : SPI1_SCLK -> NC_SPI1_SCLK + CFG_DISABLED, // 69 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 70 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 71 : SPI1_SSIN -> NC_SPI1_SSIN + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 76 : SPI2_SCLK -> SPI2_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 77 : SPI2_MOSI -> SPI2_GRAPE_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 78 : SPI2_MISO -> SPI2_GRAPE_MISO + CFG_OUT_1 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 79 : SPI2_SSIN -> SPI2_GRAPE_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED, // 82 : I2C1_SDA -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 83 : I2C1_SCL -> I2C1_SOC2OSCAR_SWDCLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> BB_IPC_GPIO + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 94 : SENSOR1_XSHUTDOWN -> AUD_SPKRAMP_MUTE_L + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> NC_SENSOR1_ISTRB + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI3_CODEC_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 97 : SPI3_MISO -> SPI3_CODEC_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI3_CODEC_SCLK + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 99 : SPI3_SSIN -> SPI3_CODEC_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 102 : GPIO[22] -> GPIO_SOC2PMU_KEEPACT + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_PMU2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | PULL_UP, // 104 : GPIO[24] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG_1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_OUT_0 | SLOW_SLEW, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG_3 + CFG_IN, // 110 : GPIO[30] -> GPIO_BTN_SRL_L + CFG_IN | PULL_UP, // 111 : GPIO[31] -> GPIO_GRAPE2SOC_IRQ_L + +/* Port 14 */ + CFG_DISABLED, // 112 : GPIO[32] -> NC_GPIO32 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 113 : GPIO[33] -> GPIO_HS3_SHUNT_EN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 114 : GPIO[34] -> GPIO_HS4_SHUNT_EN + CFG_DISABLED, // 115 : GPIO[35] -> GPIO_BRD_REV3 + CFG_DISABLED, // 116 : GPIO[36] -> GPIO_BRD_REV2 + CFG_DISABLED, // 117 : GPIO[37] -> GPIO_BRD_REV1 + CFG_DISABLED, // 118 : GPIO[38] -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X2, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_FUNC0 | SLOW_SLEW, // 124 : DWI_DI -> SOC_TST_CPUSWITCH_OUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 125 : DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_DISABLED, // 132 : I2S1_MCK -> NC_I2S1_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2S1_LRCK -> I2S1_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2S1_BCLK -> I2S1_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2S1_DOUT -> I2S1_CODEC_XSP_DOUT + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : I2S1_DIN -> I2S1_CODEC_XSP_DIN + CFG_DISABLED, // 137 : I2S2_LRCK -> NC_I2S2_LRCK + CFG_DISABLED, // 138 : I2S2_BCLK -> NC_I2S2_BCLK + CFG_DISABLED, // 139 : I2S2_DOUT -> NC_I2S2_DOUT + CFG_DISABLED, // 140 : I2S2_DIN -> NC_I2S2_DIN + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 141 : I2S3_MCK -> BB_JTAG_TRST_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 142 : I2S3_LRCK -> BB_JTAG_TDO + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 143 : I2S3_BCLK -> BB_JTAG_TDI + +/* Port 18 */ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 144 : I2S3_DOUT -> BB_JTAG_TMS + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S3_DIN -> BB_JTAG_TCK + CFG_DISABLED, // 146 : I2S4_MCK -> NC_I2S4_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_LRCK -> I2S4_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_BCLK -> I2S4_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 149 : I2S4_DOUT -> I2S4_SOC2BT_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S4_DIN -> I2S4_BT2SOC_DATA + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | SLOW_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_DISABLED, // 161 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_DISABLED | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | FAST_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | FAST_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | SLOW_SLEW, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK + CFG_DISABLED, // 194 : I2S2_MCK -> NC_I2S2_MCK +}; +#endif /* SUB_TARGET_J71 */ + +#ifdef SUB_TARGET_J72 +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_DOWN_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 6 : GPIO[4] -> GPIO_CAM_ALS2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : GPIO[5] -> GPIO_BT_WAKE + +/* Port 1 */ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 8 : GPIO[6] -> GPIO_SOC2BB_WAKE_MODEM + CFG_DISABLED, // 9 : GPIO[7] -> NC_GPIO7 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 10 : GPIO[8] -> GPIO_SOC2BB_RST_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 11 : GPIO[9] -> GPIO_SOC2BB_RADIO_ON_L + CFG_IN | PULL_DOWN, // 12 : GPIO[10] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 13 : GPIO[11] -> NC_GPIO11 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 14 : GPIO[12] -> GPIO_SOC2OSCAR_DBGEN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 15 : GPIO[13] -> GPIO_SOC2GRAPE_RESET_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> NC_GPIO14 + CFG_IN, // 17 : GPIO[15] -> GPIO_BB2SOC_GSM_TXBURST + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID_3 + CFG_IN, // 19 : GPIO[17] -> GPIO_TS2SOC2PMU_INT + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG_0 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 21 : GPIO[19] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN, // 22 : GPIO[20] -> GPIO_PROX2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 23 : GPIO[21] -> GPIO_SOC2LCD_PWREN + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2WLAN_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : UART2_RXD -> UART2_WLAN2SOC_TX + CFG_DISABLED, // 38 : UART2_RTSN -> NC_GPIO_UART2_RTSN + CFG_DISABLED, // 39 : UART2_CTSN -> NC_GPIO_UART2_CTSN + +/* Port 5 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX + CFG_FUNC0 | SLOW_SLEW, // 41 : UART3_RXD -> UART3_BB2SOC_TX + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 44 : UART5_RTXD -> UART5_BATT_TRXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED, // 68 : SPI1_SCLK -> NC_SPI1_SCLK + CFG_DISABLED, // 69 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 70 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 71 : SPI1_SSIN -> NC_SPI1_SSIN + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 76 : SPI2_SCLK -> SPI2_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 77 : SPI2_MOSI -> SPI2_GRAPE_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 78 : SPI2_MISO -> SPI2_GRAPE_MISO + CFG_OUT_1 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 79 : SPI2_SSIN -> SPI2_GRAPE_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED, // 82 : I2C1_SDA -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 83 : I2C1_SCL -> I2C1_SOC2OSCAR_SWDCLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> BB_IPC_GPIO + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 94 : SENSOR1_XSHUTDOWN -> AUD_SPKRAMP_MUTE_L + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> NC_SENSOR1_ISTRB + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI3_CODEC_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 97 : SPI3_MISO -> SPI3_CODEC_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI3_CODEC_SCLK + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 99 : SPI3_SSIN -> SPI3_CODEC_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 102 : GPIO[22] -> GPIO_SOC2PMU_KEEPACT + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_PMU2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | PULL_UP, // 104 : GPIO[24] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG_1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_OUT_0 | SLOW_SLEW, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG_3 + CFG_IN, // 110 : GPIO[30] -> GPIO_BTN_SRL_L + CFG_IN | PULL_UP, // 111 : GPIO[31] -> GPIO_GRAPE2SOC_IRQ_L + +/* Port 14 */ + CFG_DISABLED, // 112 : GPIO[32] -> NC_GPIO32 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 113 : GPIO[33] -> GPIO_HS3_SHUNT_EN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 114 : GPIO[34] -> GPIO_HS4_SHUNT_EN + CFG_DISABLED, // 115 : GPIO[35] -> GPIO_BRD_REV3 + CFG_DISABLED, // 116 : GPIO[36] -> GPIO_BRD_REV2 + CFG_DISABLED, // 117 : GPIO[37] -> GPIO_BRD_REV1 + CFG_DISABLED, // 118 : GPIO[38] -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X2, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_FUNC0 | SLOW_SLEW, // 124 : DWI_DI -> SOC_TST_CPUSWITCH_OUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 125 : DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_DISABLED, // 132 : I2S1_MCK -> NC_I2S1_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2S1_LRCK -> I2S1_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2S1_BCLK -> I2S1_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2S1_DOUT -> I2S1_CODEC_XSP_DOUT + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : I2S1_DIN -> I2S1_CODEC_XSP_DIN + CFG_DISABLED, // 137 : I2S2_LRCK -> NC_I2S2_LRCK + CFG_DISABLED, // 138 : I2S2_BCLK -> NC_I2S2_BCLK + CFG_DISABLED, // 139 : I2S2_DOUT -> NC_I2S2_DOUT + CFG_DISABLED, // 140 : I2S2_DIN -> NC_I2S2_DIN + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 141 : I2S3_MCK -> BB_JTAG_TRST_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 142 : I2S3_LRCK -> BB_JTAG_TDO + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 143 : I2S3_BCLK -> BB_JTAG_TDI + +/* Port 18 */ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 144 : I2S3_DOUT -> BB_JTAG_TMS + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S3_DIN -> BB_JTAG_TCK + CFG_DISABLED, // 146 : I2S4_MCK -> NC_I2S4_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_LRCK -> I2S4_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_BCLK -> I2S4_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 149 : I2S4_DOUT -> I2S4_SOC2BT_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S4_DIN -> I2S4_BT2SOC_DATA + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | SLOW_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_DISABLED, // 161 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_IN | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | FAST_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | FAST_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | SLOW_SLEW, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK + CFG_DISABLED, // 194 : I2S2_MCK -> NC_I2S2_MCK +}; +#endif /* SUB_TARGET_J72 */ + +#ifdef SUB_TARGET_J73 +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_DOWN_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 6 : GPIO[4] -> GPIO_CAM_ALS2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : GPIO[5] -> GPIO_BT_WAKE + +/* Port 1 */ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 8 : GPIO[6] -> GPIO_SOC2BB_WAKE_MODEM + CFG_DISABLED, // 9 : GPIO[7] -> NC_GPIO7 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 10 : GPIO[8] -> GPIO_SOC2BB_RST_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 11 : GPIO[9] -> GPIO_SOC2BB_RADIO_ON_L + CFG_IN | PULL_DOWN, // 12 : GPIO[10] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 13 : GPIO[11] -> NC_GPIO11 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 14 : GPIO[12] -> GPIO_SOC2OSCAR_DBGEN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 15 : GPIO[13] -> GPIO_SOC2GRAPE_RESET_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> NC_GPIO14 + CFG_IN, // 17 : GPIO[15] -> GPIO_BB2SOC_GSM_TXBURST + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID_3 + CFG_IN, // 19 : GPIO[17] -> GPIO_TS2SOC2PMU_INT + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG_0 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 21 : GPIO[19] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN, // 22 : GPIO[20] -> GPIO_PROX2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 23 : GPIO[21] -> GPIO_SOC2LCD_PWREN + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2WLAN_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : UART2_RXD -> UART2_WLAN2SOC_TX + CFG_DISABLED, // 38 : UART2_RTSN -> NC_GPIO_UART2_RTSN + CFG_DISABLED, // 39 : UART2_CTSN -> NC_GPIO_UART2_CTSN + +/* Port 5 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX + CFG_FUNC0 | SLOW_SLEW, // 41 : UART3_RXD -> UART3_BB2SOC_TX + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 44 : UART5_RTXD -> UART5_BATT_TRXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED, // 68 : SPI1_SCLK -> NC_SPI1_SCLK + CFG_DISABLED, // 69 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 70 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 71 : SPI1_SSIN -> NC_SPI1_SSIN + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 76 : SPI2_SCLK -> SPI2_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 77 : SPI2_MOSI -> SPI2_GRAPE_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 78 : SPI2_MISO -> SPI2_GRAPE_MISO + CFG_OUT_1 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 79 : SPI2_SSIN -> SPI2_GRAPE_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED, // 82 : I2C1_SDA -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 83 : I2C1_SCL -> I2C1_SOC2OSCAR_SWDCLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> BB_IPC_GPIO + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 94 : SENSOR1_XSHUTDOWN -> AUD_SPKRAMP_MUTE_L + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> NC_SENSOR1_ISTRB + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI3_CODEC_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 97 : SPI3_MISO -> SPI3_CODEC_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI3_CODEC_SCLK + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 99 : SPI3_SSIN -> SPI3_CODEC_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 102 : GPIO[22] -> GPIO_SOC2PMU_KEEPACT + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_PMU2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | PULL_UP, // 104 : GPIO[24] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG_1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_OUT_0 | SLOW_SLEW, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG_3 + CFG_IN, // 110 : GPIO[30] -> GPIO_BTN_SRL_L + CFG_IN | PULL_UP, // 111 : GPIO[31] -> GPIO_GRAPE2SOC_IRQ_L + +/* Port 14 */ + CFG_DISABLED, // 112 : GPIO[32] -> NC_GPIO32 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 113 : GPIO[33] -> GPIO_HS3_SHUNT_EN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 114 : GPIO[34] -> GPIO_HS4_SHUNT_EN + CFG_DISABLED, // 115 : GPIO[35] -> GPIO_BRD_REV3 + CFG_DISABLED, // 116 : GPIO[36] -> GPIO_BRD_REV2 + CFG_DISABLED, // 117 : GPIO[37] -> GPIO_BRD_REV1 + CFG_DISABLED, // 118 : GPIO[38] -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X2, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_FUNC0 | SLOW_SLEW, // 124 : DWI_DI -> SOC_TST_CPUSWITCH_OUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 125 : DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_DISABLED, // 132 : I2S1_MCK -> NC_I2S1_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2S1_LRCK -> I2S1_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2S1_BCLK -> I2S1_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2S1_DOUT -> I2S1_CODEC_XSP_DOUT + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : I2S1_DIN -> I2S1_CODEC_XSP_DIN + CFG_DISABLED, // 137 : I2S2_LRCK -> NC_I2S2_LRCK + CFG_DISABLED, // 138 : I2S2_BCLK -> NC_I2S2_BCLK + CFG_DISABLED, // 139 : I2S2_DOUT -> NC_I2S2_DOUT + CFG_DISABLED, // 140 : I2S2_DIN -> NC_I2S2_DIN + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 141 : I2S3_MCK -> BB_JTAG_TRST_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 142 : I2S3_LRCK -> BB_JTAG_TDO + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 143 : I2S3_BCLK -> BB_JTAG_TDI + +/* Port 18 */ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 144 : I2S3_DOUT -> BB_JTAG_TMS + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S3_DIN -> BB_JTAG_TCK + CFG_DISABLED, // 146 : I2S4_MCK -> NC_I2S4_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_LRCK -> I2S4_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_BCLK -> I2S4_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 149 : I2S4_DOUT -> I2S4_SOC2BT_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S4_DIN -> I2S4_BT2SOC_DATA + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | SLOW_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_DISABLED, // 161 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_IN | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | FAST_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | FAST_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | SLOW_SLEW, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK + CFG_DISABLED, // 194 : I2S2_MCK -> NC_I2S2_MCK +}; +#endif /* SUB_TARGET_J73 */ + +#undef AP_DEV_DRIVE_STR diff --git a/target/ipad4/include/target/powerconfig.h b/target/ipad4/include/target/powerconfig.h new file mode 100644 index 0000000..e7dc8dd --- /dev/null +++ b/target/ipad4/include/target/powerconfig.h @@ -0,0 +1,146 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2089_ACTIVE2, 0x03 }, // WLEDA/B BST + { PMU_IIC_BUS, kD2089_HIBERNATE3, 0x88 }, // pp3v0_s2r_sensor (LDO3) + { PMU_IIC_BUS, kD2089_HIBERNATE6, 0x24 }, // pp1v8_s2r_sw3 (buck3_sw3) and pp1v2_s2r_sw2 (buck4_sw2) +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* GPIO configuration from I/O spreadsheet. + J72 IO Spreadsheet + Request spreadsheet update before modifying + + The following differences from OTP are intentional: + - GPIO6: Enable wake + - GPIO7: Enable wake + - GPIO8: Enable wake + - GPIO9: Enable wake (baseband targets) + - GPIO10: Enable wake + - GPIO11: Enable wake + - GPIO12: Hi level interrupt, enable wake + - GPIO16: Enable wake + */ + { PMU_IIC_BUS, kD2089_GPIO1, 0x49 }, // PMU_GPIO_CLK_32K_OSCAR 32k, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO2, 0x49 }, // PMU_GPIO_CLK_32K_WLAN 32k, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO3, 0x09 }, // PMU_GPIO_BT_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO4, 0x09 }, // PMU_GPIO_WLAN_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO5, 0x09 }, // PMU_GPIO_PMU2BB_RST_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO6, 0xDA }, // UART5_BATT_TRXD In, F Edge, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO7, 0xBA }, // PMU_GPIO_BT2PMU_HOST_WAKE In, R Edge, Wake, No PU + { PMU_IIC_BUS, kD2089_GPIO8, 0xBA }, // PMU_GPIO_WLAN2PMU_HOST_WAKE In, R Edge, Wake, No PU +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2089_GPIO9, 0x7A }, // PMU_GPIO_BB2PMU_HOST_WAKE In, L High, Wake, No PU +#else + { PMU_IIC_BUS, kD2089_GPIO9, 0xB9 }, // PMU_GPIO_BB2PMU_HOST_WAKE In, R Edge, No Wake, PD, No PU +#endif + { PMU_IIC_BUS, kD2089_GPIO10, 0xEA }, // PMU_GPIO_CODEC_HS_INT_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO11, 0xFA }, // PMU_GPIO_MB_HALL1_IRQ In, Any Edge, Wake, No PU + { PMU_IIC_BUS, kD2089_GPIO12, 0x7B }, // GPIO_TS2SOC2PMU_INT In, L High, Wake, PD, No PU + { PMU_IIC_BUS, kD2089_GPIO13, 0xF8 }, // PMU_GPIO_MB_HALL2_IRQ In, Any Edge, No PU + { PMU_IIC_BUS, kD2089_GPIO14, 0xC8 }, // PMU_GPIO_CODEC_RST_L In, F Edge, PU, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO15, 0xB9 }, // GPIO_NAVAJO2SOC_INT In, R Edge, No Wake, PD, No PU + { PMU_IIC_BUS, kD2089_GPIO16, 0x7B }, // PMU_GPIO_OSCAR2PMU_HOST_WAKE In, L High, Wake, PD, No PU + { PMU_IIC_BUS, kD2089_GPIO17, 0x01 }, // PMU_GPIO_BB_VBUS_DET Out 0, Push-Pull, VCC_MAIN + + { PMU_IIC_BUS, kD2089_BUCK_DWI_CTRL0, 0x03 }, // enable DWI for BUCK0, BUCK1 + { PMU_IIC_BUS, kD2089_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_OPTIONS, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { + { 4000, 1000, 1600, 3150 }, // 10 - 16C + { 4100, 1000, 1600, 3150 }, + { 4200, 1000, 1600, 3150 }, + { USHRT_MAX, 1000, 1600, 2550 }, + { 4000, 1500, 2100, 3150 }, // 15 - 21C + { 4100, 1500, 2100, 3150 }, + { 4200, 1500, 2100, 3150 }, + { USHRT_MAX, 1500, 2100, 2550 }, + { 4000, 2000, 3500, 3150 }, // 20 - 35C + { 4100, 2000, 3500, 3150 }, + { 4200, 2000, 3500, 3150 }, + { USHRT_MAX, 2000, 3500, 3150 }, + { 4000, 3400, 4500, 3150 }, // 34 - 45C + { 4100, 3400, 4500, 3150 }, + { 4200, 3400, 4500, 3150 }, + { USHRT_MAX, 3400, 4500, 3150 } +}; + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 1287 /* 10% brightness */ +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define GASGAUGE_BATTERYID_BLOCK 1 +#define GASGAUGE_CHARGETABLE_BLOCK 3 + +static const unsigned int atv_voltage_limit[16] = { 3600, 3650, 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350 }; +static const unsigned int atv_current_limit[16] = { 150, 350, 550, 750, 950, 1150, 1350, 1550, 1750, 1950, 2150, 2350, 2550, 2750, 2950, 3150 }; + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/ipad4/include/target/uartconfig.h b/target/ipad4/include/target/uartconfig.h new file mode 100644 index 0000000..8134624 --- /dev/null +++ b/target/ipad4/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/ipad4/include/target/usbconfig.h b/target/ipad4/include/target/usbconfig.h new file mode 100644 index 0000000..ac2ef76 --- /dev/null +++ b/target/ipad4/include/target/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_OTGTUNE0 + +#undef USBPHY_OTGTUNE0 +#define USBPHY_OTGTUNE0 (0x3644D3F3) + +#endif /* USBPHY_OTGTUNE0 */ + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/ipad4/init.c b/target/ipad4/init.c new file mode 100644 index 0000000..26f3e23 --- /dev/null +++ b/target/ipad4/init.c @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IPAD4_DEV1_PROTO0_BOARD (0x0) +#define IPAD4_PROTO0_TS2_BOARD (0x1) +#define IPAD4_PROTO1_TS2_BOARD (0x2) +#define IPAD4_PROTO1_TS1_BOARD (0x3) +#define IPAD4_PROTO2_BOARD (0x5) +#define IPAD4_EVT1_BOARD (0x6) +#define IPAD4_DVT_BOARD (0x7) + +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +MIB_CONSTANT(kMIBTargetDisplayCMEngammaTablePtr, kOIDTypeStruct, (void *)linear_rgb_engamma_tables); +MIB_CONSTANT(kMIBTargetDisplayCMEngammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_rgb_engamma_tables)); +MIB_CONSTANT(kMIBTargetDisplayCMDegammaTablePtr, kOIDTypeStruct, (void *)linear_rgb_degamma_tables); +MIB_CONSTANT(kMIBTargetDisplayCMDegammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_rgb_degamma_tables)); +MIB_CONSTANT(kMIBTargetDisplayCMMatrixTablePtr, kOIDTypeStruct, (void *)linear_identity_matrix_tables); +MIB_CONSTANT(kMIBTargetDisplayCMMatrixTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_identity_matrix_tables)); + +// Don't panic for these targets because of . +MIB_CONSTANT(kMIBTargetPanicOnUnknownDclrVersion, kOIDTypeBoolean, false); +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +static dp_t dp; +#endif + +static u_int32_t ipad4_get_board_rev(void) +{ + + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + + +void target_early_init(void) +{ + unsigned i; + + // and J72 : Change LDO5 voltage for EVT build + if (ipad4_get_board_rev() == IPAD4_EVT1_BOARD) { + const uint8_t pmu_data[] = { + 0x03, 0x28, 0x47, + }; + + for (i = 0; i < sizeof(pmu_data); i += 3) + iic_write(0, 0x78, &pmu_data[i], 3); + } +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0x6; + dp.max_link_rate = 0x6; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x0; + dp.vrr_enable = 0x0; + dp.vrr_on = 0x0; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "ipad4", 0); +} + +#endif // WITH_ENV + +bool target_has_tristar2(void) +{ + return ipad4_get_board_rev() != IPAD4_DEV1_PROTO0_BOARD && ipad4_get_board_rev() != IPAD4_PROTO1_TS1_BOARD; +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; +#endif + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + } +#endif + + // Update the codec node with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi3/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + } + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart4/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart4/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart4/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + { + char *prox_node_name = "arm-io/i2c3/prox-i2c3"; + char *als_node_name = "arm-io/i2c3/als-i2c3"; + + if (ipad4_get_board_rev() < IPAD4_DVT_BOARD) { + prox_node_name = "arm-io/i2c0/prox-i2c0"; + als_node_name = "arm-io/i2c0/als-i2c0"; + } + + // Update the bottom prox calibration data + if (FindNode(0, prox_node_name, &node)) { + propName = "AAPL,ignore"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + + propName = "prox-calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPCl', propData, propSize); + } + } + + // Update the als calibration data + if (FindNode(0, als_node_name, &node)) { + propName = "AAPL,ignore"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + } + + // TriStar 1 on older systems + if (!target_has_tristar2()) { + if (FindNode(0, "arm-io/i2c2/tristar", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "tristar,cbtl1608", kPropNameLength); + } + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CBAT', propData, propSize); + } + } + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT + diff --git a/target/ipad4/pinconfig.c b/target/ipad4/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/ipad4/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/ipad4/properties.c b/target/ipad4/properties.c new file mode 100644 index 0000000..1ac9897 --- /dev/null +++ b/target/ipad4/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad4/rules.mk b/target/ipad4/rules.mk new file mode 100644 index 0000000..5680c9a --- /dev/null +++ b/target/ipad4/rules.mk @@ -0,0 +1,47 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2089=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_SPARE0_CLK_CFG=0x83000006 \ + TARGET_VID0_CLK_CFG=0x81000000 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + TARGET_ENABLE_CM=1 \ + TARGET_DDR_798M=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + WITH_TARGET_AMC_PARAMS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_ADBE0_VBLANK_POSITION=0xF0000 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_CPU_APSC=1 \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + DP_DTPATH=\"arm-io/displayport\" \ + MULTITOUCH_DTPATH=\"arm-io/spi2/multi-touch\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci0/wlan\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad4b/include/target/adbe_settings.h b/target/ipad4b/include/target/adbe_settings.h new file mode 100644 index 0000000..3c15c04 --- /dev/null +++ b/target/ipad4b/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_AFC_TEARDOWN_ENABLE | DBEMODECNTL_PMGR_CLK_GATE_ENABL| DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/ipad4b/include/target/aspnandconfig.h b/target/ipad4b/include/target/aspnandconfig.h new file mode 100644 index 0000000..cbf1b08 --- /dev/null +++ b/target/ipad4b/include/target/aspnandconfig.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#if SUB_TARGET_J85M +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#else +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 8 +#endif +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 8 +#if SUB_TARGET_J85M +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#else +#define ASPNAND_READ_DIES_IN_PARALLEL 8 +#endif +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - ASPNAND_INDIRECTION_MEMORY and ASPNAND_LEGACY_INDIRECTION_MEMORY +// should be the same for all post-OkemoTaos targets +#if SUB_TARGET_J85 +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) +#elif SUB_TARGET_J86 +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) +#elif SUB_TARGET_J87 +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) +#elif SUB_TARGET_J85M +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (4*1024*1024) +#elif SUB_TARGET_J86M +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (4*1024*1024) +#elif SUB_TARGET_J87M +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (4*1024*1024) +#else +#error // need to add a value for any new subtarget +#endif + +#endif diff --git a/target/ipad4b/include/target/boardid.h b/target/ipad4b/include/target/boardid.h new file mode 100644 index 0000000..b191f5a --- /dev/null +++ b/target/ipad4b/include/target/boardid.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TARGET_BOARDID_H +#define TARGET_BOARDID_H + +#define TARGET_BOARD_ID_J85MAP (0x32) +#define TARGET_BOARD_ID_J85MDEV (0x33) +#define TARGET_BOARD_ID_J86MAP (0x34) +#define TARGET_BOARD_ID_J86MDEV (0x35) +#define TARGET_BOARD_ID_J87MAP (0x36) +#define TARGET_BOARD_ID_J87MDEV (0x37) + +#endif diff --git a/target/ipad4b/include/target/gpiodef.h b/target/ipad4b/include/target/gpiodef.h new file mode 100644 index 0000000..9837a2f --- /dev/null +++ b/target/ipad4b/include/target/gpiodef.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 - 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPad4,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_PWR_EN GPIO(14, 6) +#define GPIO_RINGER_AB GPIO(0, 6) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(1, 2) +#define GPIO_BOARD_REV1 GPIO(1, 3) +#define GPIO_BOARD_REV2 GPIO(1, 4) + +/* which IICs to initialize */ +#if SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M +#define IICS_MASK (0xF) +#else +#define IICS_MASK (0xD) +#endif + +#define TRISTAR_IIC_BUS (0) + +/* D2089 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 6) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad4b/include/target/pinconfig-nomesa.h b/target/ipad4b/include/target/pinconfig-nomesa.h new file mode 100644 index 0000000..1be5581 --- /dev/null +++ b/target/ipad4b/include/target/pinconfig-nomesa.h @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2012 - 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default iPad4,x SoC Pin Configuration from I/O spreadsheet rev 0.17 + The pin configuration is tracked in the I/O spreadsheet: + J85: IOSpreadsheet + + The I/O spreadsheet should be updated before updating the pin configuration */ + +/* Different drive strength for AP and DEV. */ +#if PIN_CFG_AP +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##ap +#elif PIN_CFG_DEV +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##dev +#endif + +/* Different slew rate for AP and DEV. */ +#if PIN_CFG_AP +#define AP_DEV_SLEW(ap, dev) ap##_SLEW +#elif PIN_CFG_DEV +#define AP_DEV_SLEW(ap, dev) dev##_SLEW +#endif + +#if TARGET_HAS_BASEBAND +# define IFF_BB(cfg) cfg +#else +# define IFF_BB(cfg) CFG_DISABLED | PULL_DOWN +#endif + + +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | DRIVE_X1 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 6 : GPIO[4] -> GPIO_BTN_SRL_L + CFG_DISABLED, // 7 : GPIO[5] -> GPIO_SOC2BEACON_EN + +/* Port 1 */ + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 8 : GPIO[6] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 9 : GPIO[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 10 : GPIO[8] -> GPIO_BOARD_REV0 + CFG_DISABLED, // 11 : GPIO[9] -> GPIO_BOARD_REV1 + CFG_DISABLED, // 12 : GPIO[10] -> GPIO_BOARD_REV2 + CFG_IN | PULL_UP, // 13 : GPIO[11] -> GPIO_CODEC_IRQ_L + IFF_BB(CFG_OUT_0) | DRIVE_X1 | FAST_SLEW, // 14 : GPIO[12] -> GPIO_SOC2BB_WAKE_MODEM + CFG_IN | PULL_UP, // 15 : GPIO[13] -> GPIO_GRAPE_IRQ_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> BB_IPC_GPIO + CFG_IN | PULL_UP, // 17 : GPIO[15] -> GPIO_ALS_IRQ_L + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID3 + IFF_BB(CFG_IN | PULL_DOWN), // 19 : GPIO[17] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // 21 : GPIO[19] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 22 : GPIO[20] -> GPIO_SOC2PMU_KEEPACT + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 23 : GPIO[21] -> GPIO_GRAPE_RST_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X4) | AP_DEV_SLEW(SLOW, FAST), // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | AP_DEV_DRIVE_STR(X1, X4) | AP_DEV_SLEW(SLOW, FAST), // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X4) | AP_DEV_SLEW(SLOW, FAST), // 36 : UART2_TXD -> UART2_SOC2WLAN_TX + CFG_FUNC0, // 37 : UART2_RXD -> UART2_WLAN2SOC_TX + CFG_DISABLED, + CFG_DISABLED, + +/* Port 5 */ + IFF_BB(CFG_IN) | AP_DEV_DRIVE_STR(X1, X4) | AP_DEV_SLEW(SLOW, FAST), // 40 : UART3_TXD -> UART3_SOC2BB_TX + IFF_BB(CFG_FUNC0), // 41 : UART3_RXD -> UART3_BB2SOC_TX + IFF_BB(CFG_IN) | AP_DEV_DRIVE_STR(X1, X4) | AP_DEV_SLEW(SLOW, FAST), // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + IFF_BB(CFG_FUNC0), // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | FAST_SLEW, // 44 : UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_OUT_1 | DRIVE_X1 | FAST_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | DRIVE_X1 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED, + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 76 : SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 77 : SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // 78 : SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | DRIVE_X1 | FAST_SLEW, // 79 : SPI2_SSIN -> SPI2_CODEC_CS_L + +/* Port 10 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | AP_DEV_SLEW(SLOW, FAST), // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | AP_DEV_SLEW(SLOW, FAST), // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED, // 82 : I2C1_SDA -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 83 : I2C1_SCL -> I2C1_SOC2OSCAR_SWDCLK_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_OUT_0 | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + IFF_BB(CFG_IN) | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 103 : GPIO[23] -> GPIO_SOC2BB_RADIO_ON_L + +/* Port 13 */ + CFG_DISABLED, + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG3 + CFG_IN | DRIVE_X1 | FAST_SLEW, // 110 : GPIO[30] -> GPIO_SOC2OSCAR_DBGEN + IFF_BB(CFG_IN) | AP_DEV_SLEW(SLOW, FAST), // 111 : GPIO[31] -> GPIO_SOC2BB_RST_L + + +/* Port 14 */ + IFF_BB(CFG_IN), // 112 : GPIO[32] -> GPIO_PROX_IRQ_L + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> GPIO_BB2SOC_GSM_TXBURST + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 114 : GPIO[34] -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 115 : GPIO[35] -> GPIO_BT_WAKE + CFG_IN, // 116 : GPIO[36] -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_UP, // 117 : GPIO[37] -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 118 : GPIO[38] -> GPIO_SOC2LCD_PWREN + CFG_OUT_0 | PULL_DOWN, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | DRIVE_X1 | FAST_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X1 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_DISABLED, + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 125 : DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK + CFG_DISABLED, + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 132 : I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 133 : I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 134 : I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> I2S1_SPKAMP_DOUT + +/* Port 17 */ + CFG_FUNC0, // 136 : I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN | PULL_UP, // 141 : I2S3_MCK -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 142 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 143 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_SOC2BT_DATA + CFG_FUNC0, // 145 : I2S3_DIN -> I2S3_BT2SOC_DATA + IFF_BB(CFG_DISABLED), // 146 : I2S4_MCK -> BB_JTAG_TCK + IFF_BB(CFG_DISABLED), // 147 : I2S4_LRCK -> BB_JTAG_TDI + IFF_BB(CFG_DISABLED), // 148 : I2S4_BCLK -> BB_JTAG_TMS + IFF_BB(CFG_DISABLED), // 149 : I2S4_DOUT -> BB_JTAG_TRST_L + IFF_BB(CFG_DISABLED), // 150 : I2S4_DIN -> BB_JTAG_TDO + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_OUT_0 | DRIVE_X1 | FAST_SLEW, // 161 : TMR32_PWM1 -> GPIO_SPKAMP_KEEPALIVE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + IFF_BB(CFG_OUT_0) | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + IFF_BB(CFG_IN | PULL_DOWN), // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + IFF_BB(CFG_IN | PULL_DOWN), // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | DRIVE_X1 | AP_DEV_SLEW(SLOW, FAST), // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | AP_DEV_SLEW(SLOW, FAST), // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | AP_DEV_SLEW(SLOW, FAST), // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_DISABLED, +}; + +#undef AP_DEV_DRIVE_STR +#undef AP_DEV_SLEW +#undef IFF_BB diff --git a/target/ipad4b/include/target/powerconfig.h b/target/ipad4b/include/target/powerconfig.h new file mode 100644 index 0000000..c657a79 --- /dev/null +++ b/target/ipad4b/include/target/powerconfig.h @@ -0,0 +1,148 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2089_ACTIVE2, 0x03 }, // WLEDA/B BST +#if SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + { PMU_IIC_BUS, kD2089_ACTIVE3, 0xB6 }, // pp3v0_s2r_mesa (LDO5) + { PMU_IIC_BUS, kD2089_HIBERNATE3, 0xA8 }, // TriStar(LDO7) Mesa(LDO5) pp3v0_s2r_sensor (LDO3) + { PMU_IIC_BUS, kD2089_LDO5_VSEL, 0x4C }, // J85M - change PMU LDO5 to 3.1V +#else + { PMU_IIC_BUS, kD2089_HIBERNATE3, 0x88 }, // pp3v0_s2r_sensor (LDO3) +#endif + { PMU_IIC_BUS, kD2089_HIBERNATE6, 0x24 }, // pp1v8_s2r_sw3 (buck3_sw3) and pp1v2_s2r_sw2 (buck4_sw2) +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* GPIO configuration from I/O spreadsheet. + J85 IOSpreadsheet Tracker + Request spreadsheet update before modifying + + The following differences from OTP are intentional: + - GPIO6: Enable wake + - GPIO7: Enable wake + - GPIO8: Enable wake + - GPIO9: Enable wake (baseband targets) + - GPIO10: Enable wake + - GPIO11: Enable wake + - GPIO12: Hi level interrupt, enable wake + - GPIO13: Enable wake + - GPIO14: Disable wake + - GPIO16: Enable wake + */ +#if SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + { PMU_IIC_BUS, kD2089_GPIO1, 0x79 }, // PMU_GPIO_CLK_32K_OSCAR in hi, disable PU, no wake, PD +#else + { PMU_IIC_BUS, kD2089_GPIO1, 0x49 }, // PMU_GPIO_CLK_32K_OSCAR 32k, Push-Pull, VBUCK3 +#endif + { PMU_IIC_BUS, kD2089_GPIO2, 0x49 }, // PMU_GPIO_CLK_32K_WLAN 32k, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO3, 0x09 }, // PMU_GPIO_BT_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO4, 0x09 }, // PMU_GPIO_WLAN_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO5, 0x09 }, // PMU_GPIO_PMU2BB_RST_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO6, 0xDA }, // UART5_BATT_TRXD In, F Edge, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO7, 0xBA }, // PMU_GPIO_BT2PMU_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO8, 0xBA }, // PMU_GPIO_WLAN2PMU_HOST_WAKE In, R Edge, Wake, PD +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2089_GPIO9, 0x7A }, // PMU_GPIO_BB2PMU_HOST_WAKE In, L High, Wake, PD +#else + { PMU_IIC_BUS, kD2089_GPIO9, 0xB9 }, // PMU_GPIO_BB2PMU_HOST_WAKE In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2089_GPIO10, 0xEA }, // PMU_GPIO_CODEC_HS_INT_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO11, 0xFA }, // PMU_GPIO_MB_HALL1_IRQ In, Any Edge, Wake, No PU + { PMU_IIC_BUS, kD2089_GPIO12, 0x7B }, // GPIO_TS2SOC2PMU_INT In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO13, 0xF8 }, // PMU_GPIO_MB_HALL2_IRQ In, Any Edge, No PU + { PMU_IIC_BUS, kD2089_GPIO14, 0xF8 }, // PMU_GPIO_MB_HALL3_IRQ In, Any Edge, No PU + { PMU_IIC_BUS, kD2089_GPIO15, 0xC8 }, // PMU_GPIO_CODEC_RST_L In, F Edge, PU, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO16, 0x7B }, // PMU_GPIO_OSCAR2PMU_HOST_WAKE In, L High, Wake, PD, No PU + { PMU_IIC_BUS, kD2089_GPIO17, 0x01 }, // PMU_GPIO_BB_VBUS_DET Out 0, Push-Pull, VCC_MAIN + + { PMU_IIC_BUS, kD2089_BUCK_DWI_CTRL0, 0x03 }, // enable DWI for BUCK0, BUCK1 + { PMU_IIC_BUS, kD2089_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_OPTIONS, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { + { 4200, 1000, 2100, 2600 }, + { USHRT_MAX, 1000, 2100, 1950 }, + { 4200, 2000, 4500, 2600 }, + { USHRT_MAX, 2000, 4500, 2600 } +}; + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 1287 /* 10% brightness */ +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define GASGAUGE_BATTERYID_BLOCK 1 +#define GASGAUGE_CHARGETABLE_BLOCK 3 + +// NEEDS TO BE REPLACED WITH PROPER INFO +static const unsigned int atv_voltage_limit[16] = { 3650, 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350, 4400 }; +static const unsigned int atv_current_limit[16] = { 0, 200, 400, 650, 850, 1100, 1350, 1550, 1700, 1950, 2200, 2400, 2600, 2600, 2600, 2600 }; + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/ipad4b/include/target/uartconfig.h b/target/ipad4b/include/target/uartconfig.h new file mode 100644 index 0000000..8134624 --- /dev/null +++ b/target/ipad4b/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/ipad4b/include/target/usbconfig.h b/target/ipad4b/include/target/usbconfig.h new file mode 100644 index 0000000..305ab58 --- /dev/null +++ b/target/ipad4b/include/target/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_OTGTUNE0 + +#undef USBPHY_OTGTUNE0 +#define USBPHY_OTGTUNE0 (0x354493B3) + +#endif /* USBPHY_OTGTUNE0 */ + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/ipad4b/init.c b/target/ipad4b/init.c new file mode 100644 index 0000000..73fc711 --- /dev/null +++ b/target/ipad4b/init.c @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2012 - 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 +#define IPAD4B_DEV1_PROTO0_REV (0x7) +#define IPAD4B_DEV2_PROTO1_REV (0x6) // with Beacon backlight controller +#define IPAD4B_EVT_REV (0x5) // removed Beacon +#endif + +#if SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M +#define IPAD4BM_DEV1_PROTO0_REV (0x7) +#endif + +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +static dp_t dp; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +MIB_CONSTANT(kMIBTargetDisplayCMEngammaTablePtr, kOIDTypeStruct, (void *)linear_rgb_engamma_tables); +MIB_CONSTANT(kMIBTargetDisplayCMEngammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_rgb_engamma_tables)); +MIB_CONSTANT(kMIBTargetDisplayCMDegammaTablePtr, kOIDTypeStruct, (void *)linear_rgb_degamma_tables); +MIB_CONSTANT(kMIBTargetDisplayCMDegammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_rgb_degamma_tables)); +MIB_CONSTANT(kMIBTargetDisplayCMMatrixTablePtr, kOIDTypeStruct, (void *)linear_identity_matrix_tables); +MIB_CONSTANT(kMIBTargetDisplayCMMatrixTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_identity_matrix_tables)); + +// Don't panic for these targets because of . +MIB_CONSTANT(kMIBTargetPanicOnUnknownDclrVersion, kOIDTypeBoolean, false); + +static u_int32_t ipad4b_get_board_rev(void) +{ + + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + // IRATE needs to be 25 mA on J85 + // WLED IRATE is in the low 3 bits, and 0x3 corresponds to 25mA. If OTP is + // not properly programmed, use test mode to change to 25mA. + uint8_t value; + iic_read(0, 0x78, (uint8_t[]){0x06,0x07}, 2, &value, 1, IIC_NORMAL); + if ((value & 0x7) != 3) { + iic_write(0, 0x78, (uint8_t[]){0x70,0x00,0x1d},3); + iic_write(0, 0x78, (uint8_t[]){0x06,0x07,(value & 0xf8) | 0x3}, 3); + iic_write(0, 0x78, (uint8_t[]){0x70,0x00,0x00},3); + } +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +bool beacon_supported() +{ + bool supported = false; +#if SUB_TARGET_J85 || SUB_TARGET_J86 || SUB_TARGET_J87 + supported = (ipad4b_get_board_rev() == IPAD4B_DEV2_PROTO1_REV) ? true:false; +#endif + return supported; +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0x6; + dp.max_link_rate = 0x6; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x0; + dp.vrr_enable = 0x0; + dp.vrr_on = 0x0; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "ipad4b", 0); +} + +#endif // WITH_ENV + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; +#endif + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + if (beacon_supported()) { + panic("Unsupported board revision"); + } + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + } +#endif + + // Update the codec node with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi2/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + } + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart4/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart4/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart4/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + + // Update the bottom prox calibration data + if (FindNode(0, "arm-io/i2c3/prox", &node)) { + propName = "prox-calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPCl', propData, propSize); + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c3/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if ( syscfgCopyDataForTag('CBAT', propData, propSize)==20 ) { + ((uint32_t*)propData)[4]=0; + } + } + } + + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c2/audio-speaker0", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr[2]; // calibrated @ 3.1V + if (syscfgCopyDataForTag('VPBR', vpbr, sizeof(vpbr)) == 2) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | ( (vpbr[0]-1) & 0x1f); + ((uint8_t *)propData)[32] = (((uint8_t *)propData)[32] & ~0x1f) | ( (vpbr[1]-1) & 0x1f); + } + uint8_t vbst[2]; + if (syscfgCopyDataForTag('VBST', vbst, sizeof(vbst)) == 2) { + ((uint8_t *)propData)[16] = vbst[0]; + ((uint8_t *)propData)[36] = vbst[1]; + } + } + } + +#if SUB_TARGET_J85M || SUB_TARGET_J86M || SUB_TARGET_J87M + + // Update the X162 calibration data + if (FindNode(0, "arm-io/spi3/mesa", &node)) { + propName = "calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FSCl', propData, propSize); + } + propName = "modulation-ratio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('NvMR', propData, propSize); + } + } +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT + diff --git a/target/ipad4b/pinconfig-mesa.c b/target/ipad4b/pinconfig-mesa.c new file mode 100644 index 0000000..2e55ce4 --- /dev/null +++ b/target/ipad4b/pinconfig-mesa.c @@ -0,0 +1,1577 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.4 + I/O Spreadsheet tracker: 16055666 + Conversion command: csvtopinconfig.py --soc h6p --copyright 2014 --config-column 'J85M:J85 Config' --config-column 'J86M:J86 Config' --config-column 'J87M:J87 Config' --pupd-column 'J85M:J85 PU/PD' --pupd-column 'J86M:J86 PU/PD' --pupd-column 'J87M:J87 PU/PD' --radar 16055666 +*/ + +#include +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_j85map_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 6 : GPIO[4] -> GPIO_BTN_SRL_L + CFG_DISABLED, // 7 : GPIO[5] -> GPIO_SOC2BEACON_EN + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO[6] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_OUT_0 | FAST_SLEW, // 9 : GPIO[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 10 : GPIO[8] -> GPIO_BOARD_REV0 + CFG_DISABLED, // 11 : GPIO[9] -> GPIO_BOARD_REV1 + CFG_DISABLED, // 12 : GPIO[10] -> GPIO_BOARD_REV2 + CFG_IN | PULL_UP, // 13 : GPIO[11] -> GPIO_CODEC_IRQ_L + CFG_DISABLED | PULL_DOWN | FAST_SLEW, // 14 : GPIO[12] -> GPIO_SOC2BB_WAKE_MODEM + CFG_IN | PULL_UP, // 15 : GPIO[13] -> GPIO_GRAPE_IRQ_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> BB_IPC_GPIO + CFG_IN | PULL_UP, // 17 : GPIO[15] -> GPIO_ALS_IRQ_L + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID3 + CFG_DISABLED | PULL_DOWN, // 19 : GPIO[17] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // 21 : GPIO[19] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 22 : GPIO[20] -> GPIO_SOC2PMU_KEEPACT + CFG_OUT_0 | FAST_SLEW, // 23 : GPIO[21] -> GPIO_GRAPE_RST_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | SLOW_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2OSLO_TX + CFG_FUNC0, // 37 : UART2_RXD -> UART2_OSLO2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 38 : UART2_RTSN -> UART2_SOC2OSLO_RTS_L + CFG_FUNC0, // 39 : UART2_CTSN -> UART2_OSLO2SOC_RTS_L + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX / UART2_SOC2WLAN_TX + CFG_FUNC0, // 41 : UART3_RXD -> UART3_BB2SOC_TX / UART2_WLAN2SOC_TX + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | FAST_SLEW, // 44 : UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_IN | FAST_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 76 : SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 77 : SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // 78 : SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | FAST_SLEW, // 79 : SPI2_SSIN -> SPI2_CODEC_CS_L + +/* Port 10 */ + CFG_FUNC0 | SLOW_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 82 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 83 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | SLOW_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC + CFG_OUT_0 | SLOW_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> I2C1_SOC2OSCAR_SWDCLK_1V8 + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI_MESA_MOSI + CFG_FUNC0, // 97 : SPI3_MISO -> SPI_MESA_MISO + CFG_FUNC0 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI_MESA_SCLK_R + CFG_IN | PULL_DOWN, // 99 : SPI3_SSIN -> GPIO_MESA2SOC_INT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 103 : GPIO[23] -> GPIO_SOC2BB_RADIO_ON_L + +/* Port 13 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2OSLO_FW_DWL_REQ + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG3 + CFG_IN | FAST_SLEW, // 110 : GPIO[30] -> GPIO_SOC2OSCAR_DBGEN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 111 : GPIO[31] -> GPIO_SOC2BB_RST_L + +/* Port 14 */ + CFG_DISABLED | PULL_DOWN, // 112 : GPIO[32] -> GPIO_PROX_IRQ_L + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> GPIO_BB2SOC_GSM_TXBURST + CFG_OUT_0 | FAST_SLEW, // 114 : GPIO[34] -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | SLOW_SLEW, // 115 : GPIO[35] -> GPIO_BT_WAKE + CFG_IN, // 116 : GPIO[36] -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_UP, // 117 : GPIO[37] -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 118 : GPIO[38] -> GPIO_SOC2LCD_PWREN + CFG_OUT_0 | PULL_DOWN, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | FAST_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | SLOW_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 125 : DWI_DO -> DWI_AP_DO - to be checked again + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK - to be checked again + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 132 : I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 133 : I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 134 : I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> I2S1_SPKAMP_DOUT + +/* Port 17 */ + CFG_FUNC0, // 136 : I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN | PULL_UP, // 141 : I2S3_MCK -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 142 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 143 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_SOC2BT_DATA + CFG_FUNC0, // 145 : I2S3_DIN -> I2S3_BT2SOC_DATA + CFG_DISABLED | PULL_DOWN, // 146 : I2S4_MCK -> BB_JTAG_TCK + CFG_DISABLED | PULL_DOWN, // 147 : I2S4_LRCK -> BB_JTAG_TDI + CFG_DISABLED | PULL_DOWN, // 148 : I2S4_BCLK -> BB_JTAG_TMS + CFG_DISABLED | PULL_DOWN, // 149 : I2S4_DOUT -> BB_JTAG_TRST_L + CFG_DISABLED | PULL_DOWN, // 150 : I2S4_DIN -> BB_JTAG_TDO + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | FAST_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_OUT_0 | FAST_SLEW, // 161 : TMR32_PWM1 -> GPIO_SPKAMP_KEEPALIVE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | SLOW_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_DISABLED | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | SLOW_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | SLOW_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : I2S2_MCK -> GPIO_SOC2OSLO_EN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j85mdev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 6 : GPIO[4] -> GPIO_BTN_SRL_L + CFG_DISABLED, // 7 : GPIO[5] -> GPIO_SOC2BEACON_EN + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO[6] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_OUT_0 | FAST_SLEW, // 9 : GPIO[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 10 : GPIO[8] -> GPIO_BOARD_REV0 + CFG_DISABLED, // 11 : GPIO[9] -> GPIO_BOARD_REV1 + CFG_DISABLED, // 12 : GPIO[10] -> GPIO_BOARD_REV2 + CFG_IN | PULL_UP, // 13 : GPIO[11] -> GPIO_CODEC_IRQ_L + CFG_DISABLED | PULL_DOWN | FAST_SLEW, // 14 : GPIO[12] -> GPIO_SOC2BB_WAKE_MODEM + CFG_IN | PULL_UP, // 15 : GPIO[13] -> GPIO_GRAPE_IRQ_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> BB_IPC_GPIO + CFG_IN | PULL_UP, // 17 : GPIO[15] -> GPIO_ALS_IRQ_L + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID3 + CFG_DISABLED | PULL_DOWN, // 19 : GPIO[17] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // 21 : GPIO[19] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 22 : GPIO[20] -> GPIO_SOC2PMU_KEEPACT + CFG_OUT_0 | FAST_SLEW, // 23 : GPIO[21] -> GPIO_GRAPE_RST_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | DRIVE_X4 | FAST_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2OSLO_TX + CFG_FUNC0, // 37 : UART2_RXD -> UART2_OSLO2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 38 : UART2_RTSN -> UART2_SOC2OSLO_RTS_L + CFG_FUNC0, // 39 : UART2_CTSN -> UART2_OSLO2SOC_RTS_L + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX / UART2_SOC2WLAN_TX + CFG_FUNC0, // 41 : UART3_RXD -> UART3_BB2SOC_TX / UART2_WLAN2SOC_TX + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | FAST_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 44 : UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_IN | PULL_DOWN | FAST_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_IN | FAST_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 76 : SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 77 : SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // 78 : SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | FAST_SLEW, // 79 : SPI2_SSIN -> SPI2_CODEC_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 82 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 83 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | FAST_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC + CFG_OUT_0 | FAST_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> I2C1_SOC2OSCAR_SWDCLK_1V8 + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI_MESA_MOSI + CFG_FUNC0, // 97 : SPI3_MISO -> SPI_MESA_MISO + CFG_FUNC0 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI_MESA_SCLK_R + CFG_IN | PULL_DOWN, // 99 : SPI3_SSIN -> GPIO_MESA2SOC_INT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_DISABLED | PULL_DOWN | FAST_SLEW, // 103 : GPIO[23] -> GPIO_SOC2BB_RADIO_ON_L + +/* Port 13 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2OSLO_FW_DWL_REQ + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG3 + CFG_IN | FAST_SLEW, // 110 : GPIO[30] -> GPIO_SOC2OSCAR_DBGEN + CFG_DISABLED | PULL_DOWN | FAST_SLEW, // 111 : GPIO[31] -> GPIO_SOC2BB_RST_L + +/* Port 14 */ + CFG_DISABLED | PULL_DOWN, // 112 : GPIO[32] -> GPIO_PROX_IRQ_L + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> GPIO_BB2SOC_GSM_TXBURST + CFG_OUT_0 | FAST_SLEW, // 114 : GPIO[34] -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | FAST_SLEW, // 115 : GPIO[35] -> GPIO_BT_WAKE + CFG_IN, // 116 : GPIO[36] -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_UP, // 117 : GPIO[37] -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 118 : GPIO[38] -> GPIO_SOC2LCD_PWREN + CFG_OUT_0 | PULL_DOWN, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | FAST_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | FAST_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 125 : DWI_DO -> DWI_AP_DO - to be checked again + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK - to be checked again + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 132 : I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 133 : I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 134 : I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> I2S1_SPKAMP_DOUT + +/* Port 17 */ + CFG_FUNC0, // 136 : I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN | PULL_UP, // 141 : I2S3_MCK -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 142 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 143 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_SOC2BT_DATA + CFG_FUNC0, // 145 : I2S3_DIN -> I2S3_BT2SOC_DATA + CFG_DISABLED | PULL_DOWN, // 146 : I2S4_MCK -> BB_JTAG_TCK + CFG_DISABLED | PULL_DOWN, // 147 : I2S4_LRCK -> BB_JTAG_TDI + CFG_DISABLED | PULL_DOWN, // 148 : I2S4_BCLK -> BB_JTAG_TMS + CFG_DISABLED | PULL_DOWN, // 149 : I2S4_DOUT -> BB_JTAG_TRST_L + CFG_DISABLED | PULL_DOWN, // 150 : I2S4_DIN -> BB_JTAG_TDO + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | FAST_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_OUT_0 | FAST_SLEW, // 161 : TMR32_PWM1 -> GPIO_SPKAMP_KEEPALIVE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | FAST_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_DISABLED | PULL_DOWN | FAST_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_DISABLED | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | FAST_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : I2S2_MCK -> GPIO_SOC2OSLO_EN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j86map_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 6 : GPIO[4] -> GPIO_BTN_SRL_L + CFG_DISABLED, // 7 : GPIO[5] -> GPIO_SOC2BEACON_EN + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO[6] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_OUT_0 | FAST_SLEW, // 9 : GPIO[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 10 : GPIO[8] -> GPIO_BOARD_REV0 + CFG_DISABLED, // 11 : GPIO[9] -> GPIO_BOARD_REV1 + CFG_DISABLED, // 12 : GPIO[10] -> GPIO_BOARD_REV2 + CFG_IN | PULL_UP, // 13 : GPIO[11] -> GPIO_CODEC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 14 : GPIO[12] -> GPIO_SOC2BB_WAKE_MODEM + CFG_IN | PULL_UP, // 15 : GPIO[13] -> GPIO_GRAPE_IRQ_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> BB_IPC_GPIO + CFG_IN | PULL_UP, // 17 : GPIO[15] -> GPIO_ALS_IRQ_L + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID3 + CFG_IN | PULL_DOWN, // 19 : GPIO[17] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // 21 : GPIO[19] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 22 : GPIO[20] -> GPIO_SOC2PMU_KEEPACT + CFG_OUT_0 | FAST_SLEW, // 23 : GPIO[21] -> GPIO_GRAPE_RST_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | SLOW_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2OSLO_TX + CFG_FUNC0, // 37 : UART2_RXD -> UART2_OSLO2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 38 : UART2_RTSN -> UART2_SOC2OSLO_RTS_L + CFG_FUNC0, // 39 : UART2_CTSN -> UART2_OSLO2SOC_RTS_L + +/* Port 5 */ + CFG_IN | SLOW_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX / UART2_SOC2WLAN_TX + CFG_FUNC0, // 41 : UART3_RXD -> UART3_BB2SOC_TX / UART2_WLAN2SOC_TX + CFG_IN | SLOW_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_FUNC0, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | FAST_SLEW, // 44 : UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_IN | FAST_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 76 : SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 77 : SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // 78 : SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | FAST_SLEW, // 79 : SPI2_SSIN -> SPI2_CODEC_CS_L + +/* Port 10 */ + CFG_FUNC0 | SLOW_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 82 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 83 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | SLOW_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC + CFG_OUT_0 | SLOW_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> I2C1_SOC2OSCAR_SWDCLK_1V8 + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI_MESA_MOSI + CFG_FUNC0, // 97 : SPI3_MISO -> SPI_MESA_MISO + CFG_FUNC0 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI_MESA_SCLK_R + CFG_IN | PULL_DOWN, // 99 : SPI3_SSIN -> GPIO_MESA2SOC_INT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | SLOW_SLEW, // 103 : GPIO[23] -> GPIO_SOC2BB_RADIO_ON_L + +/* Port 13 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2OSLO_FW_DWL_REQ + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG3 + CFG_IN | FAST_SLEW, // 110 : GPIO[30] -> GPIO_SOC2OSCAR_DBGEN + CFG_IN | SLOW_SLEW, // 111 : GPIO[31] -> GPIO_SOC2BB_RST_L + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_PROX_IRQ_L + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> GPIO_BB2SOC_GSM_TXBURST + CFG_OUT_0 | FAST_SLEW, // 114 : GPIO[34] -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | SLOW_SLEW, // 115 : GPIO[35] -> GPIO_BT_WAKE + CFG_IN, // 116 : GPIO[36] -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_UP, // 117 : GPIO[37] -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 118 : GPIO[38] -> GPIO_SOC2LCD_PWREN + CFG_OUT_0 | PULL_DOWN, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | FAST_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | SLOW_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 125 : DWI_DO -> DWI_AP_DO - to be checked again + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK - to be checked again + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 132 : I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 133 : I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 134 : I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> I2S1_SPKAMP_DOUT + +/* Port 17 */ + CFG_FUNC0, // 136 : I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN | PULL_UP, // 141 : I2S3_MCK -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 142 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 143 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_SOC2BT_DATA + CFG_FUNC0, // 145 : I2S3_DIN -> I2S3_BT2SOC_DATA + CFG_DISABLED, // 146 : I2S4_MCK -> BB_JTAG_TCK + CFG_DISABLED, // 147 : I2S4_LRCK -> BB_JTAG_TDI + CFG_DISABLED, // 148 : I2S4_BCLK -> BB_JTAG_TMS + CFG_DISABLED, // 149 : I2S4_DOUT -> BB_JTAG_TRST_L + CFG_DISABLED, // 150 : I2S4_DIN -> BB_JTAG_TDO + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | FAST_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_OUT_0 | FAST_SLEW, // 161 : TMR32_PWM1 -> GPIO_SPKAMP_KEEPALIVE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | SLOW_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_IN | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | SLOW_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | SLOW_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : I2S2_MCK -> GPIO_SOC2OSLO_EN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j86mdev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 6 : GPIO[4] -> GPIO_BTN_SRL_L + CFG_DISABLED, // 7 : GPIO[5] -> GPIO_SOC2BEACON_EN + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO[6] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_OUT_0 | FAST_SLEW, // 9 : GPIO[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 10 : GPIO[8] -> GPIO_BOARD_REV0 + CFG_DISABLED, // 11 : GPIO[9] -> GPIO_BOARD_REV1 + CFG_DISABLED, // 12 : GPIO[10] -> GPIO_BOARD_REV2 + CFG_IN | PULL_UP, // 13 : GPIO[11] -> GPIO_CODEC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 14 : GPIO[12] -> GPIO_SOC2BB_WAKE_MODEM + CFG_IN | PULL_UP, // 15 : GPIO[13] -> GPIO_GRAPE_IRQ_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> BB_IPC_GPIO + CFG_IN | PULL_UP, // 17 : GPIO[15] -> GPIO_ALS_IRQ_L + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID3 + CFG_IN | PULL_DOWN, // 19 : GPIO[17] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // 21 : GPIO[19] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 22 : GPIO[20] -> GPIO_SOC2PMU_KEEPACT + CFG_OUT_0 | FAST_SLEW, // 23 : GPIO[21] -> GPIO_GRAPE_RST_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | DRIVE_X4 | FAST_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2OSLO_TX + CFG_FUNC0, // 37 : UART2_RXD -> UART2_OSLO2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 38 : UART2_RTSN -> UART2_SOC2OSLO_RTS_L + CFG_FUNC0, // 39 : UART2_CTSN -> UART2_OSLO2SOC_RTS_L + +/* Port 5 */ + CFG_IN | DRIVE_X4 | FAST_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX / UART2_SOC2WLAN_TX + CFG_FUNC0, // 41 : UART3_RXD -> UART3_BB2SOC_TX / UART2_WLAN2SOC_TX + CFG_IN | DRIVE_X4 | FAST_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_FUNC0, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 44 : UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_IN | PULL_DOWN | FAST_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_IN | FAST_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 76 : SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 77 : SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // 78 : SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | FAST_SLEW, // 79 : SPI2_SSIN -> SPI2_CODEC_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 82 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 83 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | FAST_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC + CFG_OUT_0 | FAST_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> I2C1_SOC2OSCAR_SWDCLK_1V8 + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI_MESA_MOSI + CFG_FUNC0, // 97 : SPI3_MISO -> SPI_MESA_MISO + CFG_FUNC0 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI_MESA_SCLK_R + CFG_IN | PULL_DOWN, // 99 : SPI3_SSIN -> GPIO_MESA2SOC_INT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | FAST_SLEW, // 103 : GPIO[23] -> GPIO_SOC2BB_RADIO_ON_L + +/* Port 13 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2OSLO_FW_DWL_REQ + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG3 + CFG_IN | FAST_SLEW, // 110 : GPIO[30] -> GPIO_SOC2OSCAR_DBGEN + CFG_IN | FAST_SLEW, // 111 : GPIO[31] -> GPIO_SOC2BB_RST_L + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_PROX_IRQ_L + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> GPIO_BB2SOC_GSM_TXBURST + CFG_OUT_0 | FAST_SLEW, // 114 : GPIO[34] -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | FAST_SLEW, // 115 : GPIO[35] -> GPIO_BT_WAKE + CFG_IN, // 116 : GPIO[36] -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_UP, // 117 : GPIO[37] -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 118 : GPIO[38] -> GPIO_SOC2LCD_PWREN + CFG_OUT_0 | PULL_DOWN, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | FAST_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | FAST_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 125 : DWI_DO -> DWI_AP_DO - to be checked again + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK - to be checked again + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 132 : I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 133 : I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 134 : I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> I2S1_SPKAMP_DOUT + +/* Port 17 */ + CFG_FUNC0, // 136 : I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN | PULL_UP, // 141 : I2S3_MCK -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 142 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 143 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_SOC2BT_DATA + CFG_FUNC0, // 145 : I2S3_DIN -> I2S3_BT2SOC_DATA + CFG_DISABLED, // 146 : I2S4_MCK -> BB_JTAG_TCK + CFG_DISABLED, // 147 : I2S4_LRCK -> BB_JTAG_TDI + CFG_DISABLED, // 148 : I2S4_BCLK -> BB_JTAG_TMS + CFG_DISABLED, // 149 : I2S4_DOUT -> BB_JTAG_TRST_L + CFG_DISABLED, // 150 : I2S4_DIN -> BB_JTAG_TDO + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | FAST_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_OUT_0 | FAST_SLEW, // 161 : TMR32_PWM1 -> GPIO_SPKAMP_KEEPALIVE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | FAST_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_OUT_0 | FAST_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_IN | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | FAST_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : I2S2_MCK -> GPIO_SOC2OSLO_EN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j87map_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 6 : GPIO[4] -> GPIO_BTN_SRL_L + CFG_DISABLED, // 7 : GPIO[5] -> GPIO_SOC2BEACON_EN + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO[6] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_OUT_0 | FAST_SLEW, // 9 : GPIO[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 10 : GPIO[8] -> GPIO_BOARD_REV0 + CFG_DISABLED, // 11 : GPIO[9] -> GPIO_BOARD_REV1 + CFG_DISABLED, // 12 : GPIO[10] -> GPIO_BOARD_REV2 + CFG_IN | PULL_UP, // 13 : GPIO[11] -> GPIO_CODEC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 14 : GPIO[12] -> GPIO_SOC2BB_WAKE_MODEM + CFG_IN | PULL_UP, // 15 : GPIO[13] -> GPIO_GRAPE_IRQ_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> BB_IPC_GPIO + CFG_IN | PULL_UP, // 17 : GPIO[15] -> GPIO_ALS_IRQ_L + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID3 + CFG_IN | PULL_DOWN, // 19 : GPIO[17] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // 21 : GPIO[19] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 22 : GPIO[20] -> GPIO_SOC2PMU_KEEPACT + CFG_OUT_0 | FAST_SLEW, // 23 : GPIO[21] -> GPIO_GRAPE_RST_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | SLOW_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2OSLO_TX + CFG_FUNC0, // 37 : UART2_RXD -> UART2_OSLO2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 38 : UART2_RTSN -> UART2_SOC2OSLO_RTS_L + CFG_FUNC0, // 39 : UART2_CTSN -> UART2_OSLO2SOC_RTS_L + +/* Port 5 */ + CFG_IN | SLOW_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX / UART2_SOC2WLAN_TX + CFG_FUNC0, // 41 : UART3_RXD -> UART3_BB2SOC_TX / UART2_WLAN2SOC_TX + CFG_IN | SLOW_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_FUNC0, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | FAST_SLEW, // 44 : UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_IN | FAST_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 76 : SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 77 : SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // 78 : SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | FAST_SLEW, // 79 : SPI2_SSIN -> SPI2_CODEC_CS_L + +/* Port 10 */ + CFG_FUNC0 | SLOW_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 82 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 83 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | SLOW_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC + CFG_OUT_0 | SLOW_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> I2C1_SOC2OSCAR_SWDCLK_1V8 + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI_MESA_MOSI + CFG_FUNC0, // 97 : SPI3_MISO -> SPI_MESA_MISO + CFG_FUNC0 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI_MESA_SCLK_R + CFG_IN | PULL_DOWN, // 99 : SPI3_SSIN -> GPIO_MESA2SOC_INT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | SLOW_SLEW, // 103 : GPIO[23] -> GPIO_SOC2BB_RADIO_ON_L + +/* Port 13 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2OSLO_FW_DWL_REQ + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG3 + CFG_IN | FAST_SLEW, // 110 : GPIO[30] -> GPIO_SOC2OSCAR_DBGEN + CFG_IN | SLOW_SLEW, // 111 : GPIO[31] -> GPIO_SOC2BB_RST_L + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_PROX_IRQ_L + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> GPIO_BB2SOC_GSM_TXBURST + CFG_OUT_0 | FAST_SLEW, // 114 : GPIO[34] -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | SLOW_SLEW, // 115 : GPIO[35] -> GPIO_BT_WAKE + CFG_IN, // 116 : GPIO[36] -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_UP, // 117 : GPIO[37] -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 118 : GPIO[38] -> GPIO_SOC2LCD_PWREN + CFG_OUT_0 | PULL_DOWN, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | FAST_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | SLOW_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 125 : DWI_DO -> DWI_AP_DO - to be checked again + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK - to be checked again + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 132 : I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 133 : I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 134 : I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> I2S1_SPKAMP_DOUT + +/* Port 17 */ + CFG_FUNC0, // 136 : I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN | PULL_UP, // 141 : I2S3_MCK -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 142 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 143 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_SOC2BT_DATA + CFG_FUNC0, // 145 : I2S3_DIN -> I2S3_BT2SOC_DATA + CFG_DISABLED, // 146 : I2S4_MCK -> BB_JTAG_TCK + CFG_DISABLED, // 147 : I2S4_LRCK -> BB_JTAG_TDI + CFG_DISABLED, // 148 : I2S4_BCLK -> BB_JTAG_TMS + CFG_DISABLED, // 149 : I2S4_DOUT -> BB_JTAG_TRST_L + CFG_DISABLED, // 150 : I2S4_DIN -> BB_JTAG_TDO + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | FAST_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_OUT_0 | FAST_SLEW, // 161 : TMR32_PWM1 -> GPIO_SPKAMP_KEEPALIVE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | SLOW_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_IN | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | SLOW_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | SLOW_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : I2S2_MCK -> GPIO_SOC2OSLO_EN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j87mdev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO[0] -> GPIO_BTN_HOME_L + CFG_IN, // 3 : GPIO[1] -> GPIO_BTN_ONOFF_L + CFG_IN | PULL_UP, // 4 : GPIO[2] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 5 : GPIO[3] -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 6 : GPIO[4] -> GPIO_BTN_SRL_L + CFG_DISABLED, // 7 : GPIO[5] -> GPIO_SOC2BEACON_EN + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO[6] -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_OUT_0 | FAST_SLEW, // 9 : GPIO[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 10 : GPIO[8] -> GPIO_BOARD_REV0 + CFG_DISABLED, // 11 : GPIO[9] -> GPIO_BOARD_REV1 + CFG_DISABLED, // 12 : GPIO[10] -> GPIO_BOARD_REV2 + CFG_IN | PULL_UP, // 13 : GPIO[11] -> GPIO_CODEC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 14 : GPIO[12] -> GPIO_SOC2BB_WAKE_MODEM + CFG_IN | PULL_UP, // 15 : GPIO[13] -> GPIO_GRAPE_IRQ_L + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[14] -> BB_IPC_GPIO + CFG_IN | PULL_UP, // 17 : GPIO[15] -> GPIO_ALS_IRQ_L + CFG_DISABLED, // 18 : GPIO[16] -> GPIO_BOARD_ID3 + CFG_IN | PULL_DOWN, // 19 : GPIO[17] -> GPIO_BB2SOC_RESET_DET_L + CFG_DISABLED, // 20 : GPIO[18] -> GPIO_BOOT_CONFIG0 + CFG_IN | PULL_UP, // 21 : GPIO[19] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 22 : GPIO[20] -> GPIO_SOC2PMU_KEEPACT + CFG_OUT_0 | FAST_SLEW, // 23 : GPIO[21] -> GPIO_GRAPE_RST_L + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 32 : UART1_TXD -> UART1_SOC2BT_TX + CFG_FUNC0, // 33 : UART1_RXD -> UART1_BT2SOC_TX + CFG_OUT_1 | DRIVE_X4 | FAST_SLEW, // 34 : UART1_RTSN -> UART1_SOC2BT_RTS_L + CFG_FUNC0, // 35 : UART1_CTSN -> UART1_BT2SOC_RTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 36 : UART2_TXD -> UART2_SOC2OSLO_TX + CFG_FUNC0, // 37 : UART2_RXD -> UART2_OSLO2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 38 : UART2_RTSN -> UART2_SOC2OSLO_RTS_L + CFG_FUNC0, // 39 : UART2_CTSN -> UART2_OSLO2SOC_RTS_L + +/* Port 5 */ + CFG_IN | DRIVE_X4 | FAST_SLEW, // 40 : UART3_TXD -> UART3_SOC2BB_TX / UART2_SOC2WLAN_TX + CFG_FUNC0, // 41 : UART3_RXD -> UART3_BB2SOC_TX / UART2_WLAN2SOC_TX + CFG_IN | DRIVE_X4 | FAST_SLEW, // 42 : UART3_RTSN -> UART3_SOC2BB_RTS_L + CFG_FUNC0, // 43 : UART3_CTSN -> UART3_BB2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 44 : UART5_RTXD -> UART5_BATT_RTXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_IN | PULL_DOWN | FAST_SLEW, // 64 : UART4_TXD -> UART4_SOC2OSCAR_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_OSCAR2SOC_RXD + CFG_IN | FAST_SLEW, // 66 : UART4_RTSN -> GPIO_OSCAR_RESET_L + CFG_IN, // 67 : UART4_CTSN -> PMU_GPIO_OSCAR2PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_GRAPE_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_GRAPE_MOSI + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_GRAPE_MISO + CFG_OUT_1 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_GRAPE_CS_L + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI0_SCLK -> GPIO_BOARD_ID0 + CFG_DISABLED, // 73 : SPI0_MOSI -> GPIO_BOARD_ID1 + CFG_DISABLED, // 74 : SPI0_MISO -> GPIO_BOARD_ID2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 76 : SPI2_SCLK -> SPI2_CODEC_SCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 77 : SPI2_MOSI -> SPI2_CODEC_MOSI + CFG_FUNC0, // 78 : SPI2_MISO -> SPI2_CODEC_MISO + CFG_OUT_1 | FAST_SLEW, // 79 : SPI2_SSIN -> SPI2_CODEC_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 82 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 83 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 84 : ISP0_SDA -> ISP0_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 85 : ISP0_SCL -> ISP0_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 86 : ISP1_SDA -> ISP1_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 87 : ISP1_SCL -> ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_OUT_0 | FAST_SLEW, // 88 : SENSOR0_RST -> ISP0_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 89 : SENSOR0_CLK -> ISP0_CAM_REAR_CLK_R + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC + CFG_OUT_0 | FAST_SLEW, // 92 : SENSOR1_RST -> ISP1_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | FAST_SLEW, // 93 : SENSOR1_CLK -> ISP1_CAM_FRONT_CLK_R + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> I2C1_SOC2OSCAR_SWDIO_1V8 + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> I2C1_SOC2OSCAR_SWDCLK_1V8 + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : SPI3_MOSI -> SPI_MESA_MOSI + CFG_FUNC0, // 97 : SPI3_MISO -> SPI_MESA_MISO + CFG_FUNC0 | SLOW_SLEW, // 98 : SPI3_SCLK -> SPI_MESA_SCLK_R + CFG_IN | PULL_DOWN, // 99 : SPI3_SSIN -> GPIO_MESA2SOC_INT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | FAST_SLEW, // 103 : GPIO[23] -> GPIO_SOC2BB_RADIO_ON_L + +/* Port 13 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2OSLO_FW_DWL_REQ + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CONFIG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CONFIG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_BOOT_CONFIG3 + CFG_IN | FAST_SLEW, // 110 : GPIO[30] -> GPIO_SOC2OSCAR_DBGEN + CFG_IN | FAST_SLEW, // 111 : GPIO[31] -> GPIO_SOC2BB_RST_L + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_PROX_IRQ_L + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> GPIO_BB2SOC_GSM_TXBURST + CFG_OUT_0 | FAST_SLEW, // 114 : GPIO[34] -> GPIO_SPKAMP_RST_L + CFG_OUT_0 | FAST_SLEW, // 115 : GPIO[35] -> GPIO_BT_WAKE + CFG_IN, // 116 : GPIO[36] -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_UP, // 117 : GPIO[37] -> GPIO_SPKAMP_LEFT_IRQ_L + CFG_OUT_0 | FAST_SLEW, // 118 : GPIO[38] -> GPIO_SOC2LCD_PWREN + CFG_OUT_0 | PULL_DOWN, // 119 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0 | FAST_SLEW, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0 | FAST_SLEW, // 122 : UART0_TXD -> UART0_SOC_TXD + CFG_FUNC0, // 123 : UART0_RXD -> UART0_SOC_RXD + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 125 : DWI_DO -> DWI_AP_DO - to be checked again + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK - to be checked again + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_CODEC_ASP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_CODEC_ASP_DOUT + CFG_FUNC0, // 131 : I2S0_DIN -> I2S0_CODEC_ASP_DIN + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 132 : I2S1_MCK -> I2S1_SPKAMP_MCK_R + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 133 : I2S1_LRCK -> I2S1_SPKAMP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 134 : I2S1_BCLK -> I2S1_SPKAMP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 135 : I2S1_DOUT -> I2S1_SPKAMP_DOUT + +/* Port 17 */ + CFG_FUNC0, // 136 : I2S1_DIN -> I2S1_SPKAMP_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> I2S2_CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> I2S2_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> I2S2_CODEC_XSP_DOUT + CFG_FUNC0, // 140 : I2S2_DIN -> I2S2_CODEC_XSP_DIN + CFG_IN | PULL_UP, // 141 : I2S3_MCK -> GPIO_SPKAMP_RIGHT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 142 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 143 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + +/* Port 18 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_SOC2BT_DATA + CFG_FUNC0, // 145 : I2S3_DIN -> I2S3_BT2SOC_DATA + CFG_DISABLED, // 146 : I2S4_MCK -> BB_JTAG_TCK + CFG_DISABLED, // 147 : I2S4_LRCK -> BB_JTAG_TDI + CFG_DISABLED, // 148 : I2S4_BCLK -> BB_JTAG_TMS + CFG_DISABLED, // 149 : I2S4_DOUT -> BB_JTAG_TRST_L + CFG_DISABLED, // 150 : I2S4_DIN -> BB_JTAG_TDO + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_OUT_0 | FAST_SLEW, // 160 : TMR32_PWM0 -> OSCAR_TIME_SYNC_HOST_INT + CFG_OUT_0 | FAST_SLEW, // 161 : TMR32_PWM1 -> GPIO_SPKAMP_KEEPALIVE + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 162 : TMR32_PWM2 -> CLK_32K_SOC2CUMULUS + CFG_OUT_0 | FAST_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN | PULL_DOWN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_OUT_0 | FAST_SLEW, // 166 : SIO_7816UART1_SDA -> HSIC2_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 167 : SIO_7816UART1_SCL -> HSIC2_BB2SOC_DEVICE_RDY + +/* Port 21 */ + CFG_IN | PULL_DOWN, // 168 : SIO_7816UART1_RST -> HSIC2_BB2SOC_REMOTE_WAKE + CFG_FUNC0 | FAST_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 171 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 172 : I2C3_SCL -> I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_CODEC_ASP_MCK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : I2S2_MCK -> GPIO_SOC2OSLO_EN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J85MAP, ~0, { pinconfig_j85map_0 } }, + { TARGET_BOARD_ID_J85MDEV, ~0, { pinconfig_j85mdev_0 } }, + { TARGET_BOARD_ID_J86MAP, ~0, { pinconfig_j86map_0 } }, + { TARGET_BOARD_ID_J86MDEV, ~0, { pinconfig_j86mdev_0 } }, + { TARGET_BOARD_ID_J87MAP, ~0, { pinconfig_j87map_0 } }, + { TARGET_BOARD_ID_J87MDEV, ~0, { pinconfig_j87mdev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipad4b/pinconfig-nomesa.c b/target/ipad4b/pinconfig-nomesa.c new file mode 100644 index 0000000..650e4dc --- /dev/null +++ b/target/ipad4b/pinconfig-nomesa.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/ipad4b/properties.c b/target/ipad4b/properties.c new file mode 100644 index 0000000..1ac9897 --- /dev/null +++ b/target/ipad4b/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad4b/rules.mk b/target/ipad4b/rules.mk new file mode 100644 index 0000000..4af9c39 --- /dev/null +++ b/target/ipad4b/rules.mk @@ -0,0 +1,47 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2089=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_SPARE0_CLK_CFG=0x83000006 \ + TARGET_VID0_CLK_CFG=0x81000000 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + TARGET_ENABLE_CM=1 \ + TARGET_HPD_TO_BL_TIMEOUT=92000 \ + TARGET_DDR_798M=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_ADBE0_VBLANK_POSITION=0xF0000 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_CPU_APSC=1 \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + DP_DTPATH=\"arm-io/displayport\" \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci1/wlan\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/$(PINCONFIG_OBJ) + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad5/include/target/adbe_settings.h b/target/ipad5/include/target/adbe_settings.h new file mode 100644 index 0000000..fdfcbde --- /dev/null +++ b/target/ipad5/include/target/adbe_settings.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x000e, + .adbe0_vblank_clk_gate_wakeup = 0x000e, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/ipad5/include/target/amcconfig.h b/target/ipad5/include/target/amcconfig.h new file mode 100644 index 0000000..f1a6e0f --- /dev/null +++ b/target/ipad5/include/target/amcconfig.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014,2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Memory settings taken from j42d (2 GB), SEG signed off that they are the same (800MHz vs 792MHz) */ +static const struct amc_param amc_params = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x03, + .addrcfg = 0x00030201, + .mccchnldec = 0x00060010, + .mcuchnhash = 0x0ffffd54, + .mcschnldec = 0x00010200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000601, + .readleveling = 0x00000300, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x25550000, + .selfref = 0x00059060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x132b0000, + .selfref = 0x0002d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x0a160000, + .selfref = 0x00017000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x03050000, + .selfref = 0x00006000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, +#if DISPLAY_D600_TUNABLES + { &rAMC_PSQWQCTL1, 0x00000bd4 }, +#else + { &rAMC_PSQWQCTL1, 0x00000158 }, +#endif + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +#if DISPLAY_D600_TUNABLES + { &rAMC_PWRMNGTPARAM, 0x0c003000 }, +#else + { &rAMC_PWRMNGTPARAM, 0x01803000 }, +#endif +}; diff --git a/target/ipad5/include/target/aspnandconfig.h b/target/ipad5/include/target/aspnandconfig.h new file mode 100644 index 0000000..a410432 --- /dev/null +++ b/target/ipad5/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 8 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (4*1024*1024) + +#endif diff --git a/target/ipad5/include/target/boardid.h b/target/ipad5/include/target/boardid.h new file mode 100644 index 0000000..c8b684b --- /dev/null +++ b/target/ipad5/include/target/boardid.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TARGET_BOARDID_H +#define TARGET_BOARDID_H + +#define TARGET_BOARD_ID_J96AP (8) +#define TARGET_BOARD_ID_J96DEV (9) +#define TARGET_BOARD_ID_J97AP (10) +#define TARGET_BOARD_ID_J97DEV (11) + +#endif diff --git a/target/ipad5/include/target/gpiodef.h b/target/ipad5/include/target/gpiodef.h new file mode 100644 index 0000000..a29977d --- /dev/null +++ b/target/ipad5/include/target/gpiodef.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* ipad5,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 14, 2) // 118 : GPIO[8] +#define GPIO_BOARD_REV1 GPIO( 14, 3) // 117 : GPIO[9] +#define GPIO_BOARD_REV2 GPIO( 14, 4) // 116 : GPIO[10] + +/* Miscellaneous Pins */ +#define GPIO_PMU_LCD_PWR_EN (17) + +/* Ringer Switch */ +#define GPIO_RINGER_AB GPIO( 5 , 7) // 131 : GPIO[4] -> gpio_btn_srl_l + +/* D2207 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO( 6, 7) // 55 : GPIO[20] -> gpio_soc2pmu_keepact + +/* which IICs to initialize */ +#define IICS_MASK (0xD) + +#define TRISTAR_IIC_BUS (0) + +#define BACKLIGHT_IIC_BUS (0) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad5/include/target/lpdp_settings.h b/target/ipad5/include/target/lpdp_settings.h new file mode 100644 index 0000000..384b699 --- /dev/null +++ b/target/ipad5/include/target/lpdp_settings.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef LPDP_SETTINGS_H +#define LPDP_SETTINGS_H + +static struct lpdp_port_calibration lpdp_port_calibration_table[1][1] = { + { {LPDP_PHY_LANE_VREG_ADJ_280_mV, 0}, }, +}; + +#define LPDP_PORT_CALIBRATION_TABLE_FIXED (true) + +#endif diff --git a/target/ipad5/include/target/powerconfig.h b/target/ipad5/include/target/powerconfig.h new file mode 100644 index 0000000..689e6df --- /dev/null +++ b/target/ipad5/include/target/powerconfig.h @@ -0,0 +1,121 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2207_HIBERNATE6, 0x22 }, // DVDD must be on +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* J96-J97 IO spreadsheet tracker */ +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO5, 0x09}, // PMU_GPIO_PMU2BBPMU_RST_L Out 0, Push-Pull, VBUCK3 +#else + { PMU_IIC_BUS, kD2207_GPIO5, 0xB9}, // PMU_GPIO_PMU2BBPMU_RST_L In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO6, 0xDA}, // UART5_BATT_TRXD In, F Edge, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO7, 0xBA}, // PMU_GPIO_BT_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO8, 0x7B}, // PMU_GPIO_WLAN_HOST_WAKE In, Hi level, Wake, PD +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO9, 0x8A}, // PMU_GPIO_BB2PMU_HOST_WAKE In, Active low, Wake, PU, VBUCK3 +#else + { PMU_IIC_BUS, kD2207_GPIO9, 0xB9}, // PMU_GPIO_BB2PMU_HOST_WAKE In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO10, 0xEA}, // PMU_GPIO_CODEC_HS_INT_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD2207_GPIO11, 0xFA}, // PMU_GPIO_MB_HALL0_IRQ In, Any Edge, Wake, No PU + { PMU_IIC_BUS, kD2207_GPIO12, 0x7B}, // GPIO_TS2SOC2PMU_INT In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO13, 0xF8}, // PMU_GPIO_MB_HALL1_IRQ In, Any Edge, NoWake, No PU + { PMU_IIC_BUS, kD2207_GPIO14, 0xB8}, // PMU_GPIO_WLAN2PMU_PCIE_WAKE_L In, R Edge, PU + { PMU_IIC_BUS, kD2207_GPIO16, 0x7B}, // PMU_GPIO_OSCAR2PMU_HOST_WAKE In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO21, 0xF8}, // PMU_GPIO_MB_HALL2_IRQ In, Any Edge, NoWake, No PU + { PMU_IIC_BUS, kD2207_BUCK_DWI_CTRL0, 0x23}, // enable DWI for BUCK0, BUCK1, BUCK5 + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11}, // DWI_EN HIB_32K (for WiFi/BT) + + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA}, // enable TEST Access + { PMU_IIC_BUS, kD2207_PRE_UVLO_CONF, 0x06}, // SOCHOT0 save power in sleep, disable pull-up + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS}, // disable TEST Access +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_OPTIONS, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK5_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK2_VSEL } +}; + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { + { 4100, 1000, 1500, 1004 }, // 10 - 15C + { 4200, 1000, 1500, 1004 }, + { USHRT_MAX, 1000, 1500, 1004 }, + { 4100, 1500, 2000, 2509 }, // 15 - 20C + { 4200, 1500, 2000, 2007 }, + { USHRT_MAX, 1500, 2000, 1004 }, + { 4100, 2000, 4500, 2509 }, // 20 - 45C + { 4200, 2000, 4500, 2509 }, + { USHRT_MAX, 2000, 4500, 2007 }, +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 60 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define ACC_PWR_LDO (6) + +#define GASGAUGE_BATTERYID_BLOCK 1 +// no charge table + +#endif diff --git a/target/ipad5/include/target/uartconfig.h b/target/ipad5/include/target/uartconfig.h new file mode 100644 index 0000000..f81b712 --- /dev/null +++ b/target/ipad5/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/ipad5/init.c b/target/ipad5/init.c new file mode 100644 index 0000000..c56bb6a --- /dev/null +++ b/target/ipad5/init.c @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#endif + +#include +// Board ids +// pick up these defines from boardid.h +#define J96_AP_BOARD_ID TARGET_BOARD_ID_J96AP +#define J96_DEV_BOARD_ID TARGET_BOARD_ID_J96DEV + +#define J97_AP_BOARD_ID TARGET_BOARD_ID_J97AP +#define J97_DEV_BOARD_ID TARGET_BOARD_ID_J97DEV + +// Board revs +// the following apply to both j96 and j97 +#define J96_DEV1_BOARD_REV (0x7) +#define J96_DEV2_BOARD_REV (0x5) +#define J96_DEV3_BOARD_REV (0x4) +#define J96_DEV3a_BOARD_REV (0x3) +#define J96_DEV4_BOARD_REV (0x2) // 1GB -> 2GB migration + +#define J96_PROTO0_BOARD_REV (0x7) +#define J96_PROTO0b_BOARD_REV (0x6) +#define J96_PROTO1_BOARD_REV (0x5) +#define J96_PROTO1a_BOARD_REV (0x4) +#define J96_PROTO2_BOARD_REV (0x3) +#define J96_EVT_BOARD_REV (0x2) +#define J96_DVT_BOARD_REV (0x1) +#define J96_DVT_2GB_BOARD_REV (0x0) + +#define T7000_2GB_SOC_PID (0x2) + +static uint32_t ipad5_get_board_rev(void); + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +static dp_t dp; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static uint32_t ipad5_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +static bool board_type_preproto(void) { + bool preproto = false; + const uint32_t rev = ipad5_get_board_rev(); + + if (target_config_dev()) { + if (rev > J96_DEV2_BOARD_REV) + preproto = true; + } else if (target_config_ap()) { + if (rev > J96_PROTO0b_BOARD_REV) + preproto = true; + } + + return preproto; + +} + +static bool board_type_proto(void) { + bool proto = false; + const uint32_t rev = ipad5_get_board_rev(); + + if (target_config_dev()) { + if (rev > J96_DEV3_BOARD_REV) + proto = true; + } else if (target_config_ap()) { + if (rev > J96_PROTO1_BOARD_REV) + proto = true; + } + + return proto; +} + +static bool board_type_proto1(void) { + bool proto1 = false; + const uint32_t rev = ipad5_get_board_rev(); + + if (target_config_dev()) { + if (rev > J96_DEV3a_BOARD_REV) + proto1 = true; + } else if (target_config_ap()) { + if (rev > J96_PROTO1a_BOARD_REV) + proto1 = true; + } + + return proto1; +} + +static bool support_hall0(void){ + bool support = true; + const uint32_t rev = ipad5_get_board_rev(); + + if (target_config_ap()) { + if ((rev == J96_PROTO1_BOARD_REV) || (rev == J96_PROTO1a_BOARD_REV)) + support = false; + } + + return support; +} + +static void check_board_supported(void) +{ + bool supported = true; + + // as of june 2015, j96/j97 is moving to 2GB RAM...obsolete the rest + // differentiated by the fues0 PID values of 2 + if ( chipid_get_pid() != T7000_2GB_SOC_PID ) + { + supported = false; + dprintf(DEBUG_INFO, "%s-%d (chipid_get_pid()=0x%x, T7000_2GB_SOC_PID=0xx%x) \n", + __FUNCTION__, __LINE__ ,chipid_get_pid(), T7000_2GB_SOC_PID ); + } + + if ( !supported) + platform_not_supported(); +} + + +void target_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + pmgr_update_dvfm(platform_get_board_id(),ipad5_get_board_rev()); + pmgr_update_gfx_states(platform_get_board_id(),ipad5_get_board_rev()); +#endif + + check_board_supported(); + +} + +void target_late_init(void) +{ + if(board_type_preproto() || board_type_proto()) + platform_not_supported(); + +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0x6; + dp.max_link_rate = 0x6; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x0; + dp.vrr_enable = 0x0; + dp.vrr_on = 0x0; + dp.rx_n1= 0x0; + dp.rx_n2= 0x0; + dp.rx_n3= 0x0; + dp.rx_n5= 0x0; + dp.fast_link_training = true; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "ipad5", 0); +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; + DTNode *lpdp_node = NULL; + DTNode *node; +#endif + + uint32_t propSize; + char *propName, *propNamePOR; + void *propData; + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + + extern int lpdp_phy_update_device_tree(DTNode *lpdp_node); + FindNode(0, DPPHY_DTPATH, &lpdp_node); + lpdp_phy_update_device_tree(lpdp_node); + } +#endif + + // Update the codec node with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi2/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + } + } + } + + if (board_type_proto1()) { + if (FindNode(0, "arm-io/uart7/oscar", &node)) { + propName = "function-oscar_power1_proto1"; + propNamePOR = "function-oscar_power1"; + if (FindProperty(node, &propName, &propData, &propSize) && + FindProperty(node, &propNamePOR, &propData, &propSize)) { + strlcpy(propName, "function-oscar_power1", kPropNameLength); + propNamePOR[0] = '~'; + } + + } + } + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c2/audio-speaker0", &node)) { + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + } + + // Update the als calibration data for all nodes that may be present + if (FindNode(0, "arm-io/i2c3/als1", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + if (FindNode(0, "arm-io/i2c3/als2", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart7/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + propName = "compass-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CRot', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart7/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart7/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (FindNode(0, "arm-io/uart7/oscar/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT diff --git a/target/ipad5/pinconfig.c b/target/ipad5/pinconfig.c new file mode 100644 index 0000000..b4dfe78 --- /dev/null +++ b/target/ipad5/pinconfig.c @@ -0,0 +1,1109 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 3.0.0 + I/O Spreadsheet tracker: J96-J97 IO spreadsheet tracker + Conversion command: csvtopinconfig.py --soc fiji --radar ' J96-J97 IO spreadsheet tracker' --copyright 2013-2014 --config-column 'j96:j96 config' --config-column 'j97:j97 config' --pupd-column 'j96:j96 pu/pd' --pupd-column 'j97:j97 pu/pd' +*/ + +#include +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_j96ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : ULPI_DIR -> nc_soc_gpio_0 + CFG_DISABLED, // 1 : ULPI_STP -> + CFG_IN | PULL_UP, // 2 : ULPI_NXT -> gpio_spkamp_left_irq_l + CFG_DISABLED, // 3 : ULPI_DATA[7] -> + CFG_IN | PULL_UP, // 4 : ULPI_DATA[6] -> gpio_spkamp_right_irq_l + CFG_DISABLED, // 5 : ULPI_DATA[5] -> + CFG_OUT_0 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> gpio_spkamp_keepalive + CFG_DISABLED, // 7 : ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // 8 : ULPI_DATA[3] -> + CFG_DISABLED, // 9 : ULPI_DATA[2] -> + CFG_DISABLED, // 10 : ULPI_DATA[1] -> i2c1_soc2oscar_swdio_1v8 + CFG_DISABLED, // 11 : ULPI_DATA[0] -> i2c1_soc2oscar_swdclk_1v8 + CFG_FUNC0 | SLOW_SLEW, // 12 : SPI1_SCLK -> spi1_grape_sclk + CFG_FUNC0 | SLOW_SLEW, // 13 : SPI1_MOSI -> spi1_grape_mosi + CFG_FUNC0, // 14 : SPI1_MISO -> spi1_grape_miso + CFG_OUT_1 | SLOW_SLEW, // 15 : SPI1_SSIN -> spi1_grape_cs_l + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN, // 32 : GPIO[11] -> gpio_btn_home_l + CFG_IN, // 33 : GPIO[12] -> gpio_btn_onoff_l + CFG_DISABLED, // 34 : I2S3_MCK -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : I2S3_LRCK -> i2s3_soc2bt_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 36 : I2S3_BCLK -> i2s3_soc2bt_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2S3_DOUT -> i2s3_soc2bt_data + CFG_FUNC0, // 38 : I2S3_DIN -> i2s3_bt2soc_data + CFG_FUNC0 | SLOW_SLEW, // 39 : CLK32K_OUT -> clk_32k_soc2cumulus + +/* Port 5 */ + CFG_DISABLED, // 40 : PCIE_CLKREQ0_N -> + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> pcie1_wlan2soc_clkreq_l + CFG_DISABLED, // 42 : NAND_SYS_CLK -> + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 43 : GPIO[0] -> gpio_soc2bb_wake_modem + CFG_IN | PULL_UP, // 44 : GPIO[1] -> gpio_codec_irq_l + CFG_IN | PULL_UP, // 45 : GPIO[2] -> gpio_btn_vol_up_l + CFG_IN | PULL_UP, // 46 : GPIO[3] -> gpio_btn_vol_down_l + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[4] -> gpio_soc2grape_1v8_en + +/* Port 6 */ + CFG_DISABLED, // 48 : GPIO[5] -> GPIO_SOC2CODEC_RST_L + CFG_OUT_0 | SLOW_SLEW, // 49 : GPIO[6] -> gpio_soc2aj_hs4_shunt_en + CFG_OUT_0 | SLOW_SLEW, // 50 : GPIO[7] -> gpio_soc2aj_hs3_shunt_en + CFG_DISABLED | PULL_DOWN, // 51 : GPIO[14] -> bb_ipc_gpio + CFG_DISABLED, // 52 : GPIO[16] -> gpio_board_id3 + CFG_DISABLED | PULL_DOWN, // 53 : GPIO[17] -> gpio_bb2soc_reset_det_l + CFG_DISABLED, // 54 : GPIO[18] -> gpio_boot_config0 + CFG_OUT_0 | SLOW_SLEW, // 55 : GPIO[20] -> gpio_soc2pmu_keepact + +/* Port 7 */ + CFG_OUT_0 | SLOW_SLEW, // 56 : GPIO[21] -> gpio_grape_rst_l + CFG_FUNC0 | SLOW_SLEW, // 57 : UART5_RTXD -> uart5_batt_rtxd + CFG_DISABLED, // 58 : UART8_TXD -> + CFG_IN, // 59 : UART8_RXD -> pmu_gpio_oscar2pmu_host_wake + CFG_DISABLED, // 60 : SPI0_SCLK -> gpio_board_id0 + CFG_DISABLED, // 61 : SPI0_MOSI -> gpio_board_id1 + CFG_DISABLED, // 62 : SPI0_MISO -> gpio_board_id2 + CFG_OUT_0 | SLOW_SLEW, // 63 : SPI0_SSIN -> gpio_soc2wlan_pcie_dev_wake + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : I2C2_SDA -> i2c2_sda_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C2_SCL -> i2c2_scl_1v8 + CFG_DISABLED | PULL_DOWN, // 66 : GPIO[22] -> gpio_bb2soc_gps_sync + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 67 : GPIO[23] -> gpio_soc2bb_radio_on_l + CFG_DISABLED, // 68 : GPIO[25] -> gpio_boot_config1 + CFG_DISABLED, // 69 : GPIO[28] -> gpio_boot_config2 + CFG_DISABLED, // 70 : GPIO[29] -> + CFG_DISABLED, // 71 : GPIO[34] -> + +/* Port 9 */ + CFG_OUT_0 | SLOW_SLEW, // 72 : GPIO[35] -> gpio_soc2bt_wake + CFG_IN, // 73 : GPIO[36] -> gpio_ts2soc2pmu_int + CFG_DISABLED, // 74 : GPIO[37] -> + CFG_DISABLED, // 75 : GPIO[39]/PCIE_PERST0_N -> + CFG_DISABLED, // 76 : GPIO[42] -> + CFG_IN | SLOW_SLEW, // 77 : GPIO[43]/PCIE_PERST1_N -> pcie1_soc2wlan_rst_l + CFG_OUT_0 | PULL_DOWN, // 78 : DISP_VSYNC -> display_sync + CFG_FUNC0 | SLOW_SLEW, // 79 : UART0_TXD -> uart0_soc_txd + +/* Port 10 */ + CFG_FUNC0, // 80 : UART0_RXD -> uart0_soc_rxd + CFG_OUT_0 | SLOW_SLEW, // 81 : TMR32_PWM0 -> oscar_time_sync_host_int + CFG_DISABLED, // 82 : TMR32_PWM1 -> + CFG_DISABLED, // 83 : TMR32_PWM2 -> + CFG_FUNC0 | SLOW_SLEW, // 84 : UART6_TXD -> uart6_ts_acc_txd + CFG_FUNC0, // 85 : UART6_RXD -> uart6_ts_acc_rxd + CFG_FUNC0 | SLOW_SLEW, // 86 : I2C3_SDA -> i2c3_sda_1v8 + CFG_FUNC0 | SLOW_SLEW, // 87 : I2C3_SCL -> i2c3_scl_1v8 + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : I2C0_SDA -> i2c0_sda_1v8 + CFG_FUNC0 | SLOW_SLEW, // 97 : I2C0_SCL -> i2c0_scl_1v8 + CFG_DISABLED, // 98 : GPIO[38] -> + CFG_FUNC0 | SLOW_SLEW, // 99 : UART2_TXD -> uart2_soc2wlan_tx + CFG_FUNC0, // 100 : UART2_RXD -> uart2_wlan2soc_tx + CFG_OUT_1 | SLOW_SLEW, // 101 : UART2_RTSN -> uart2_soc2wlan_rts_l + CFG_FUNC0, // 102 : UART2_CTSN -> uart2_wlan2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 103 : DWI_DO -> dwi_ap_do + +/* Port 13 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 104 : DWI_CLK -> dwi_ap_clk + CFG_FUNC0 | SLOW_SLEW, // 105 : WDOG -> wdog_soc + CFG_IN | PULL_UP, // 106 : GPIO[13] -> gpio_grape_irq_l + CFG_IN | PULL_UP, // 107 : GPIO[19] -> gpio_pmu2soc_irq_l + CFG_IN, // 108 : GPIO[26] -> gpio_force_dfu + CFG_DISABLED, // 109 : GPIO[27] -> tp_gpio_dfu_status + CFG_FUNC0 | SLOW_SLEW, // 110 : SOCHOT0 -> sochot0_l + CFG_FUNC0 | SLOW_SLEW, // 111 : SOCHOT1 -> sochot1_l + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : GPIO[8] -> gpio_board_rev0 + CFG_DISABLED, // 115 : GPIO[9] -> gpio_board_rev1 + CFG_DISABLED, // 116 : GPIO[10] -> gpio_board_rev2 + CFG_IN | PULL_UP, // 117 : GPIO[15] -> gpio_als1_irq_l + CFG_IN | PULL_UP | SLOW_SLEW, // 118 : UART4_TXD -> uart4_soc2oslo_tx + CFG_FUNC0, // 119 : UART4_RXD -> uart4_oslo2soc_tx + +/* Port 15 */ + CFG_IN | PULL_UP | SLOW_SLEW, // 120 : UART4_RTSN -> uart4_soc2oslo_rts_l + CFG_FUNC0, // 121 : UART4_CTSN -> uart4_oslo2soc_rts_l + CFG_FUNC0 | SLOW_SLEW, // 122 : SPI3_MOSI -> spi_mesa_mosi + CFG_FUNC0, // 123 : SPI3_MISO -> spi_mesa_miso + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> spi_mesa_sclk_r + CFG_IN | PULL_DOWN, // 125 : SPI3_SSIN -> gpio_mesa2soc_int + CFG_DISABLED, // 126 : GPIO[24] -> bb_jtag_tms + CFG_DISABLED | PULL_DOWN, // 127 : GPIO[30] -> hsic1_bb2soc_device_rdy + +/* Port 16 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 128 : GPIO[31] -> gpio_soc2bb_rst_l + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 129 : GPIO[32] -> hsic1_soc2bb_host_rdy + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 130 : GPIO[33] -> gpio_soc2bb_coredump + CFG_IN | PULL_UP, // 131 : GPIO[40] -> gpio_als2_irq_l + CFG_IN | PULL_DOWN | SLOW_SLEW, // 132 : GPIO[41] -> gpio_soc2oslo_fw_dwl_req + CFG_DISABLED, // 133 : I2S4_MCK -> bb_jtag_tck + CFG_DISABLED, // 134 : I2S4_LRCK -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 135 : I2S4_BCLK -> gpio_soc2oslo_en + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S4_DOUT -> + CFG_DISABLED, // 137 : I2S4_DIN -> + CFG_DISABLED, // 138 : I2C1_SDA -> + CFG_DISABLED, // 139 : I2C1_SCL -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 160 : I2S0_LRCK -> i2s0_codec_asp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 161 : I2S0_BCLK -> i2s0_codec_asp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : I2S0_DOUT -> i2s0_codec_asp_dout + CFG_FUNC0, // 163 : I2S0_DIN -> i2s0_codec_asp_din + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> i2s1_spkamp_mck_r + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 165 : I2S1_LRCK -> i2s1_spkamp_lrck + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 166 : I2S1_BCLK -> i2s1_spkamp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 167 : I2S1_DOUT -> i2s1_spkamp_dout + +/* Port 21 */ + CFG_FUNC0, // 168 : I2S1_DIN -> i2s1_spkamp_din + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 169 : I2S2_LRCK -> i2s2_codec_xsp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 170 : I2S2_BCLK -> i2s2_codec_xsp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : I2S2_DOUT -> i2s2_codec_xsp_dout + CFG_FUNC0, // 172 : I2S2_DIN -> i2s2_codec_xsp_din + CFG_FUNC0 | SLOW_SLEW, // 173 : UART1_TXD -> uart1_soc2bt_tx + CFG_FUNC0, // 174 : UART1_RXD -> uart1_bt2soc_tx + CFG_OUT_1 | SLOW_SLEW, // 175 : UART1_RTSN -> uart1_soc2bt_rts_l + +/* Port 22 */ + CFG_FUNC0, // 176 : UART1_CTSN -> uart1_bt2soc_rts_l + CFG_FUNC0, // 177 : EDP_HPD -> edp_hpd + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 178 : UART3_TXD -> uart3_soc2bb_tx + CFG_DISABLED | PULL_DOWN, // 179 : UART3_RXD -> uart3_bb2soc_tx + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 180 : UART3_RTSN -> uart3_soc2bb_rts_l + CFG_DISABLED | PULL_DOWN, // 181 : UART3_CTSN -> uart3_bb2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 182 : SPI2_SCLK -> spi2_codec_sclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : SPI2_MOSI -> spi2_codec_mosi + +/* Port 23 */ + CFG_FUNC0, // 184 : SPI2_MISO -> spi2_codec_miso + CFG_OUT_1 | SLOW_SLEW, // 185 : SPI2_SSIN -> spi2_codec_cs_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 186 : ISP0_SDA -> isp0_cam_rear_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 187 : ISP0_SCL -> isp0_cam_rear_scl + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 188 : ISP1_SDA -> isp1_cam_front_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 189 : ISP1_SCL -> isp1_cam_front_scl + CFG_OUT_0 | SLOW_SLEW, // 190 : SENSOR0_RST -> isp0_cam_rear_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> isp0_cam_rear_clk_r + +/* Port 24 */ + CFG_DISABLED, // 192 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 193 : SENSOR0_ISTRB -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : ISP_UART0_TXD -> soc2oscar_isp_uart_txd + CFG_FUNC0, // 195 : ISP_UART0_RXD -> oscar2soc_isp_uart_rxd + CFG_OUT_0 | SLOW_SLEW, // 196 : SENSOR1_RST -> isp1_cam_front_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> isp1_cam_front_clk_r + CFG_DISABLED, // 198 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // 199 : SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 200 : UART7_TXD -> uart7_soc2oscar_txd + CFG_FUNC0, // 201 : UART7_RXD -> uart7_oscar2soc_rxd + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 202 : I2S0_MCK -> i2s0_codec_asp_mck_r + CFG_DISABLED, // 203 : I2S2_MCK -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j96dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : ULPI_DIR -> nc_soc_gpio_0 + CFG_DISABLED, // 1 : ULPI_STP -> + CFG_IN | PULL_UP, // 2 : ULPI_NXT -> gpio_spkamp_left_irq_l + CFG_DISABLED, // 3 : ULPI_DATA[7] -> + CFG_IN | PULL_UP, // 4 : ULPI_DATA[6] -> gpio_spkamp_right_irq_l + CFG_DISABLED, // 5 : ULPI_DATA[5] -> + CFG_OUT_0 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> gpio_spkamp_keepalive + CFG_DISABLED, // 7 : ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // 8 : ULPI_DATA[3] -> + CFG_DISABLED, // 9 : ULPI_DATA[2] -> + CFG_DISABLED, // 10 : ULPI_DATA[1] -> i2c1_soc2oscar_swdio_1v8 + CFG_DISABLED, // 11 : ULPI_DATA[0] -> i2c1_soc2oscar_swdclk_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 12 : SPI1_SCLK -> spi1_grape_sclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 13 : SPI1_MOSI -> spi1_grape_mosi + CFG_FUNC0, // 14 : SPI1_MISO -> spi1_grape_miso + CFG_OUT_1 | SLOW_SLEW, // 15 : SPI1_SSIN -> spi1_grape_cs_l + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN, // 32 : GPIO[11] -> gpio_btn_home_l + CFG_IN, // 33 : GPIO[12] -> gpio_btn_onoff_l + CFG_DISABLED, // 34 : I2S3_MCK -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : I2S3_LRCK -> i2s3_soc2bt_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 36 : I2S3_BCLK -> i2s3_soc2bt_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2S3_DOUT -> i2s3_soc2bt_data + CFG_FUNC0, // 38 : I2S3_DIN -> i2s3_bt2soc_data + CFG_FUNC0 | SLOW_SLEW, // 39 : CLK32K_OUT -> clk_32k_soc2cumulus + +/* Port 5 */ + CFG_DISABLED, // 40 : PCIE_CLKREQ0_N -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> pcie1_wlan2soc_clkreq_l + CFG_DISABLED, // 42 : NAND_SYS_CLK -> + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 43 : GPIO[0] -> gpio_soc2bb_wake_modem + CFG_IN | PULL_UP, // 44 : GPIO[1] -> gpio_codec_irq_l + CFG_IN | PULL_UP, // 45 : GPIO[2] -> gpio_btn_vol_up_l + CFG_IN | PULL_UP, // 46 : GPIO[3] -> gpio_btn_vol_down_l + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[4] -> gpio_soc2grape_1v8_en + +/* Port 6 */ + CFG_DISABLED, // 48 : GPIO[5] -> GPIO_SOC2CODEC_RST_L + CFG_OUT_0 | SLOW_SLEW, // 49 : GPIO[6] -> gpio_soc2aj_hs4_shunt_en + CFG_OUT_0 | SLOW_SLEW, // 50 : GPIO[7] -> gpio_soc2aj_hs3_shunt_en + CFG_DISABLED | PULL_DOWN, // 51 : GPIO[14] -> bb_ipc_gpio + CFG_DISABLED, // 52 : GPIO[16] -> gpio_board_id3 + CFG_DISABLED | PULL_DOWN, // 53 : GPIO[17] -> gpio_bb2soc_reset_det_l + CFG_DISABLED, // 54 : GPIO[18] -> gpio_boot_config0 + CFG_OUT_0 | SLOW_SLEW, // 55 : GPIO[20] -> gpio_soc2pmu_keepact + +/* Port 7 */ + CFG_OUT_0 | SLOW_SLEW, // 56 : GPIO[21] -> gpio_grape_rst_l + CFG_FUNC0 | SLOW_SLEW, // 57 : UART5_RTXD -> uart5_batt_rtxd + CFG_DISABLED, // 58 : UART8_TXD -> + CFG_IN, // 59 : UART8_RXD -> pmu_gpio_oscar2pmu_host_wake + CFG_DISABLED, // 60 : SPI0_SCLK -> gpio_board_id0 + CFG_DISABLED, // 61 : SPI0_MOSI -> gpio_board_id1 + CFG_DISABLED, // 62 : SPI0_MISO -> gpio_board_id2 + CFG_OUT_0 | SLOW_SLEW, // 63 : SPI0_SSIN -> gpio_soc2wlan_pcie_dev_wake + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : I2C2_SDA -> i2c2_sda_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C2_SCL -> i2c2_scl_1v8 + CFG_DISABLED | PULL_DOWN, // 66 : GPIO[22] -> gpio_bb2soc_gps_sync + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 67 : GPIO[23] -> gpio_soc2bb_radio_on_l + CFG_DISABLED, // 68 : GPIO[25] -> gpio_boot_config1 + CFG_DISABLED, // 69 : GPIO[28] -> gpio_boot_config2 + CFG_DISABLED, // 70 : GPIO[29] -> + CFG_DISABLED, // 71 : GPIO[34] -> + +/* Port 9 */ + CFG_OUT_0 | SLOW_SLEW, // 72 : GPIO[35] -> gpio_soc2bt_wake + CFG_IN, // 73 : GPIO[36] -> gpio_ts2soc2pmu_int + CFG_DISABLED, // 74 : GPIO[37] -> + CFG_DISABLED, // 75 : GPIO[39]/PCIE_PERST0_N -> + CFG_DISABLED, // 76 : GPIO[42] -> + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 77 : GPIO[43]/PCIE_PERST1_N -> pcie1_soc2wlan_rst_l + CFG_OUT_0 | PULL_DOWN, // 78 : DISP_VSYNC -> display_sync + CFG_FUNC0 | SLOW_SLEW, // 79 : UART0_TXD -> uart0_soc_txd + +/* Port 10 */ + CFG_FUNC0, // 80 : UART0_RXD -> uart0_soc_rxd + CFG_OUT_0 | SLOW_SLEW, // 81 : TMR32_PWM0 -> oscar_time_sync_host_int + CFG_DISABLED, // 82 : TMR32_PWM1 -> + CFG_DISABLED, // 83 : TMR32_PWM2 -> + CFG_FUNC0 | SLOW_SLEW, // 84 : UART6_TXD -> uart6_ts_acc_txd + CFG_FUNC0, // 85 : UART6_RXD -> uart6_ts_acc_rxd + CFG_FUNC0 | SLOW_SLEW, // 86 : I2C3_SDA -> i2c3_sda_1v8 + CFG_FUNC0 | SLOW_SLEW, // 87 : I2C3_SCL -> i2c3_scl_1v8 + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 96 : I2C0_SDA -> i2c0_sda_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 97 : I2C0_SCL -> i2c0_scl_1v8 + CFG_DISABLED, // 98 : GPIO[38] -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 99 : UART2_TXD -> uart2_soc2wlan_tx + CFG_FUNC0, // 100 : UART2_RXD -> uart2_wlan2soc_tx + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 101 : UART2_RTSN -> uart2_soc2wlan_rts_l + CFG_FUNC0, // 102 : UART2_CTSN -> uart2_wlan2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 103 : DWI_DO -> dwi_ap_do + +/* Port 13 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 104 : DWI_CLK -> dwi_ap_clk + CFG_FUNC0 | SLOW_SLEW, // 105 : WDOG -> wdog_soc + CFG_IN | PULL_UP, // 106 : GPIO[13] -> gpio_grape_irq_l + CFG_IN | PULL_UP, // 107 : GPIO[19] -> gpio_pmu2soc_irq_l + CFG_IN, // 108 : GPIO[26] -> gpio_force_dfu + CFG_DISABLED, // 109 : GPIO[27] -> tp_gpio_dfu_status + CFG_FUNC0 | SLOW_SLEW, // 110 : SOCHOT0 -> sochot0_l + CFG_FUNC0 | SLOW_SLEW, // 111 : SOCHOT1 -> sochot1_l + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : GPIO[8] -> gpio_board_rev0 + CFG_DISABLED, // 115 : GPIO[9] -> gpio_board_rev1 + CFG_DISABLED, // 116 : GPIO[10] -> gpio_board_rev2 + CFG_IN | PULL_UP, // 117 : GPIO[15] -> gpio_als1_irq_l + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 118 : UART4_TXD -> uart4_soc2oslo_tx + CFG_FUNC0, // 119 : UART4_RXD -> uart4_oslo2soc_tx + +/* Port 15 */ + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 120 : UART4_RTSN -> uart4_soc2oslo_rts_l + CFG_FUNC0, // 121 : UART4_CTSN -> uart4_oslo2soc_rts_l + CFG_FUNC0 | SLOW_SLEW, // 122 : SPI3_MOSI -> spi_mesa_mosi + CFG_FUNC0, // 123 : SPI3_MISO -> spi_mesa_miso + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> spi_mesa_sclk_r + CFG_IN | PULL_DOWN, // 125 : SPI3_SSIN -> gpio_mesa2soc_int + CFG_DISABLED, // 126 : GPIO[24] -> bb_jtag_tms + CFG_DISABLED | PULL_DOWN, // 127 : GPIO[30] -> hsic1_bb2soc_device_rdy + +/* Port 16 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 128 : GPIO[31] -> gpio_soc2bb_rst_l + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 129 : GPIO[32] -> hsic1_soc2bb_host_rdy + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 130 : GPIO[33] -> gpio_soc2bb_coredump + CFG_IN | PULL_UP, // 131 : GPIO[40] -> gpio_als2_irq_l + CFG_IN | PULL_DOWN | SLOW_SLEW, // 132 : GPIO[41] -> gpio_soc2oslo_fw_dwl_req + CFG_DISABLED, // 133 : I2S4_MCK -> bb_jtag_tck + CFG_DISABLED, // 134 : I2S4_LRCK -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 135 : I2S4_BCLK -> gpio_soc2oslo_en + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S4_DOUT -> + CFG_DISABLED, // 137 : I2S4_DIN -> + CFG_DISABLED, // 138 : I2C1_SDA -> + CFG_DISABLED, // 139 : I2C1_SCL -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 160 : I2S0_LRCK -> i2s0_codec_asp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 161 : I2S0_BCLK -> i2s0_codec_asp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : I2S0_DOUT -> i2s0_codec_asp_dout + CFG_FUNC0, // 163 : I2S0_DIN -> i2s0_codec_asp_din + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> i2s1_spkamp_mck_r + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 165 : I2S1_LRCK -> i2s1_spkamp_lrck + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 166 : I2S1_BCLK -> i2s1_spkamp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 167 : I2S1_DOUT -> i2s1_spkamp_dout + +/* Port 21 */ + CFG_FUNC0, // 168 : I2S1_DIN -> i2s1_spkamp_din + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 169 : I2S2_LRCK -> i2s2_codec_xsp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 170 : I2S2_BCLK -> i2s2_codec_xsp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : I2S2_DOUT -> i2s2_codec_xsp_dout + CFG_FUNC0, // 172 : I2S2_DIN -> i2s2_codec_xsp_din + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 173 : UART1_TXD -> uart1_soc2bt_tx + CFG_FUNC0, // 174 : UART1_RXD -> uart1_bt2soc_tx + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 175 : UART1_RTSN -> uart1_soc2bt_rts_l + +/* Port 22 */ + CFG_FUNC0, // 176 : UART1_CTSN -> uart1_bt2soc_rts_l + CFG_FUNC0, // 177 : EDP_HPD -> edp_hpd + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 178 : UART3_TXD -> uart3_soc2bb_tx + CFG_DISABLED | PULL_DOWN, // 179 : UART3_RXD -> uart3_bb2soc_tx + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 180 : UART3_RTSN -> uart3_soc2bb_rts_l + CFG_DISABLED | PULL_DOWN, // 181 : UART3_CTSN -> uart3_bb2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 182 : SPI2_SCLK -> spi2_codec_sclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : SPI2_MOSI -> spi2_codec_mosi + +/* Port 23 */ + CFG_FUNC0, // 184 : SPI2_MISO -> spi2_codec_miso + CFG_OUT_1 | SLOW_SLEW, // 185 : SPI2_SSIN -> spi2_codec_cs_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 186 : ISP0_SDA -> isp0_cam_rear_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 187 : ISP0_SCL -> isp0_cam_rear_scl + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 188 : ISP1_SDA -> isp1_cam_front_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 189 : ISP1_SCL -> isp1_cam_front_scl + CFG_OUT_0 | SLOW_SLEW, // 190 : SENSOR0_RST -> isp0_cam_rear_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> isp0_cam_rear_clk_r + +/* Port 24 */ + CFG_DISABLED, // 192 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 193 : SENSOR0_ISTRB -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : ISP_UART0_TXD -> soc2oscar_isp_uart_txd + CFG_FUNC0, // 195 : ISP_UART0_RXD -> oscar2soc_isp_uart_rxd + CFG_OUT_0 | SLOW_SLEW, // 196 : SENSOR1_RST -> isp1_cam_front_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> isp1_cam_front_clk_r + CFG_DISABLED, // 198 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // 199 : SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 200 : UART7_TXD -> uart7_soc2oscar_txd + CFG_FUNC0, // 201 : UART7_RXD -> uart7_oscar2soc_rxd + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 202 : I2S0_MCK -> i2s0_codec_asp_mck_r + CFG_DISABLED, // 203 : I2S2_MCK -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j97ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : ULPI_DIR -> nc_soc_gpio_0 + CFG_DISABLED, // 1 : ULPI_STP -> + CFG_IN | PULL_UP, // 2 : ULPI_NXT -> gpio_spkamp_left_irq_l + CFG_DISABLED, // 3 : ULPI_DATA[7] -> + CFG_IN | PULL_UP, // 4 : ULPI_DATA[6] -> gpio_spkamp_right_irq_l + CFG_DISABLED, // 5 : ULPI_DATA[5] -> + CFG_OUT_0 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> gpio_spkamp_keepalive + CFG_DISABLED, // 7 : ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // 8 : ULPI_DATA[3] -> + CFG_DISABLED, // 9 : ULPI_DATA[2] -> + CFG_DISABLED, // 10 : ULPI_DATA[1] -> i2c1_soc2oscar_swdio_1v8 + CFG_DISABLED, // 11 : ULPI_DATA[0] -> i2c1_soc2oscar_swdclk_1v8 + CFG_FUNC0 | SLOW_SLEW, // 12 : SPI1_SCLK -> spi1_grape_sclk + CFG_FUNC0 | SLOW_SLEW, // 13 : SPI1_MOSI -> spi1_grape_mosi + CFG_FUNC0, // 14 : SPI1_MISO -> spi1_grape_miso + CFG_OUT_1 | SLOW_SLEW, // 15 : SPI1_SSIN -> spi1_grape_cs_l + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN, // 32 : GPIO[11] -> gpio_btn_home_l + CFG_IN, // 33 : GPIO[12] -> gpio_btn_onoff_l + CFG_DISABLED, // 34 : I2S3_MCK -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : I2S3_LRCK -> i2s3_soc2bt_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 36 : I2S3_BCLK -> i2s3_soc2bt_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2S3_DOUT -> i2s3_soc2bt_data + CFG_FUNC0, // 38 : I2S3_DIN -> i2s3_bt2soc_data + CFG_FUNC0 | SLOW_SLEW, // 39 : CLK32K_OUT -> clk_32k_soc2cumulus + +/* Port 5 */ + CFG_DISABLED, // 40 : PCIE_CLKREQ0_N -> + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> pcie1_wlan2soc_clkreq_l + CFG_DISABLED, // 42 : NAND_SYS_CLK -> + CFG_OUT_0 | SLOW_SLEW, // 43 : GPIO[0] -> gpio_soc2bb_wake_modem + CFG_IN | PULL_UP, // 44 : GPIO[1] -> gpio_codec_irq_l + CFG_IN | PULL_UP, // 45 : GPIO[2] -> gpio_btn_vol_up_l + CFG_IN | PULL_UP, // 46 : GPIO[3] -> gpio_btn_vol_down_l + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[4] -> gpio_soc2grape_1v8_en + +/* Port 6 */ + CFG_DISABLED, // 48 : GPIO[5] -> GPIO_SOC2CODEC_RST_L + CFG_OUT_0 | SLOW_SLEW, // 49 : GPIO[6] -> gpio_soc2aj_hs4_shunt_en + CFG_OUT_0 | SLOW_SLEW, // 50 : GPIO[7] -> gpio_soc2aj_hs3_shunt_en + CFG_DISABLED, // 51 : GPIO[14] -> bb_ipc_gpio + CFG_DISABLED, // 52 : GPIO[16] -> gpio_board_id3 + CFG_IN | PULL_DOWN, // 53 : GPIO[17] -> gpio_bb2soc_reset_det_l + CFG_DISABLED, // 54 : GPIO[18] -> gpio_boot_config0 + CFG_OUT_0 | SLOW_SLEW, // 55 : GPIO[20] -> gpio_soc2pmu_keepact + +/* Port 7 */ + CFG_OUT_0 | SLOW_SLEW, // 56 : GPIO[21] -> gpio_grape_rst_l + CFG_FUNC0 | SLOW_SLEW, // 57 : UART5_RTXD -> uart5_batt_rtxd + CFG_DISABLED, // 58 : UART8_TXD -> + CFG_IN, // 59 : UART8_RXD -> pmu_gpio_oscar2pmu_host_wake + CFG_DISABLED, // 60 : SPI0_SCLK -> gpio_board_id0 + CFG_DISABLED, // 61 : SPI0_MOSI -> gpio_board_id1 + CFG_DISABLED, // 62 : SPI0_MISO -> gpio_board_id2 + CFG_OUT_0 | SLOW_SLEW, // 63 : SPI0_SSIN -> gpio_soc2wlan_pcie_dev_wake + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : I2C2_SDA -> i2c2_sda_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C2_SCL -> i2c2_scl_1v8 + CFG_DISABLED, // 66 : GPIO[22] -> gpio_bb2soc_gps_sync + CFG_IN | SLOW_SLEW, // 67 : GPIO[23] -> gpio_soc2bb_radio_on_l + CFG_DISABLED, // 68 : GPIO[25] -> gpio_boot_config1 + CFG_DISABLED, // 69 : GPIO[28] -> gpio_boot_config2 + CFG_DISABLED, // 70 : GPIO[29] -> + CFG_DISABLED, // 71 : GPIO[34] -> + +/* Port 9 */ + CFG_OUT_0 | SLOW_SLEW, // 72 : GPIO[35] -> gpio_soc2bt_wake + CFG_IN, // 73 : GPIO[36] -> gpio_ts2soc2pmu_int + CFG_DISABLED, // 74 : GPIO[37] -> + CFG_DISABLED, // 75 : GPIO[39]/PCIE_PERST0_N -> + CFG_DISABLED, // 76 : GPIO[42] -> + CFG_IN | SLOW_SLEW, // 77 : GPIO[43]/PCIE_PERST1_N -> pcie1_soc2wlan_rst_l + CFG_OUT_0 | PULL_DOWN, // 78 : DISP_VSYNC -> display_sync + CFG_FUNC0 | SLOW_SLEW, // 79 : UART0_TXD -> uart0_soc_txd + +/* Port 10 */ + CFG_FUNC0, // 80 : UART0_RXD -> uart0_soc_rxd + CFG_OUT_0 | SLOW_SLEW, // 81 : TMR32_PWM0 -> oscar_time_sync_host_int + CFG_DISABLED, // 82 : TMR32_PWM1 -> + CFG_DISABLED, // 83 : TMR32_PWM2 -> + CFG_FUNC0 | SLOW_SLEW, // 84 : UART6_TXD -> uart6_ts_acc_txd + CFG_FUNC0, // 85 : UART6_RXD -> uart6_ts_acc_rxd + CFG_FUNC0 | SLOW_SLEW, // 86 : I2C3_SDA -> i2c3_sda_1v8 + CFG_FUNC0 | SLOW_SLEW, // 87 : I2C3_SCL -> i2c3_scl_1v8 + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : I2C0_SDA -> i2c0_sda_1v8 + CFG_FUNC0 | SLOW_SLEW, // 97 : I2C0_SCL -> i2c0_scl_1v8 + CFG_DISABLED, // 98 : GPIO[38] -> + CFG_FUNC0 | SLOW_SLEW, // 99 : UART2_TXD -> uart2_soc2wlan_tx + CFG_FUNC0, // 100 : UART2_RXD -> uart2_wlan2soc_tx + CFG_OUT_1 | SLOW_SLEW, // 101 : UART2_RTSN -> uart2_soc2wlan_rts_l + CFG_FUNC0, // 102 : UART2_CTSN -> uart2_wlan2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 103 : DWI_DO -> dwi_ap_do + +/* Port 13 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 104 : DWI_CLK -> dwi_ap_clk + CFG_FUNC0 | SLOW_SLEW, // 105 : WDOG -> wdog_soc + CFG_IN | PULL_UP, // 106 : GPIO[13] -> gpio_grape_irq_l + CFG_IN | PULL_UP, // 107 : GPIO[19] -> gpio_pmu2soc_irq_l + CFG_IN, // 108 : GPIO[26] -> gpio_force_dfu + CFG_DISABLED, // 109 : GPIO[27] -> tp_gpio_dfu_status + CFG_FUNC0 | SLOW_SLEW, // 110 : SOCHOT0 -> sochot0_l + CFG_FUNC0 | SLOW_SLEW, // 111 : SOCHOT1 -> sochot1_l + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : GPIO[8] -> gpio_board_rev0 + CFG_DISABLED, // 115 : GPIO[9] -> gpio_board_rev1 + CFG_DISABLED, // 116 : GPIO[10] -> gpio_board_rev2 + CFG_IN | PULL_UP, // 117 : GPIO[15] -> gpio_als1_irq_l + CFG_IN | PULL_UP | SLOW_SLEW, // 118 : UART4_TXD -> uart4_soc2oslo_tx + CFG_FUNC0, // 119 : UART4_RXD -> uart4_oslo2soc_tx + +/* Port 15 */ + CFG_IN | PULL_UP | SLOW_SLEW, // 120 : UART4_RTSN -> uart4_soc2oslo_rts_l + CFG_FUNC0, // 121 : UART4_CTSN -> uart4_oslo2soc_rts_l + CFG_FUNC0 | SLOW_SLEW, // 122 : SPI3_MOSI -> spi_mesa_mosi + CFG_FUNC0, // 123 : SPI3_MISO -> spi_mesa_miso + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> spi_mesa_sclk_r + CFG_IN | PULL_DOWN, // 125 : SPI3_SSIN -> gpio_mesa2soc_int + CFG_DISABLED, // 126 : GPIO[24] -> bb_jtag_tms + CFG_IN | PULL_DOWN, // 127 : GPIO[30] -> hsic1_bb2soc_device_rdy + +/* Port 16 */ + CFG_IN | SLOW_SLEW, // 128 : GPIO[31] -> gpio_soc2bb_rst_l + CFG_OUT_0 | SLOW_SLEW, // 129 : GPIO[32] -> hsic1_soc2bb_host_rdy + CFG_OUT_0 | SLOW_SLEW, // 130 : GPIO[33] -> gpio_soc2bb_coredump + CFG_IN | PULL_UP, // 131 : GPIO[40] -> gpio_als2_irq_l + CFG_IN | PULL_DOWN | SLOW_SLEW, // 132 : GPIO[41] -> gpio_soc2oslo_fw_dwl_req + CFG_DISABLED, // 133 : I2S4_MCK -> bb_jtag_tck + CFG_DISABLED, // 134 : I2S4_LRCK -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 135 : I2S4_BCLK -> gpio_soc2oslo_en + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S4_DOUT -> + CFG_DISABLED, // 137 : I2S4_DIN -> + CFG_DISABLED, // 138 : I2C1_SDA -> + CFG_DISABLED, // 139 : I2C1_SCL -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 160 : I2S0_LRCK -> i2s0_codec_asp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 161 : I2S0_BCLK -> i2s0_codec_asp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : I2S0_DOUT -> i2s0_codec_asp_dout + CFG_FUNC0, // 163 : I2S0_DIN -> i2s0_codec_asp_din + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> i2s1_spkamp_mck_r + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 165 : I2S1_LRCK -> i2s1_spkamp_lrck + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 166 : I2S1_BCLK -> i2s1_spkamp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 167 : I2S1_DOUT -> i2s1_spkamp_dout + +/* Port 21 */ + CFG_FUNC0, // 168 : I2S1_DIN -> i2s1_spkamp_din + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 169 : I2S2_LRCK -> i2s2_codec_xsp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 170 : I2S2_BCLK -> i2s2_codec_xsp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : I2S2_DOUT -> i2s2_codec_xsp_dout + CFG_FUNC0, // 172 : I2S2_DIN -> i2s2_codec_xsp_din + CFG_FUNC0 | SLOW_SLEW, // 173 : UART1_TXD -> uart1_soc2bt_tx + CFG_FUNC0, // 174 : UART1_RXD -> uart1_bt2soc_tx + CFG_OUT_1 | SLOW_SLEW, // 175 : UART1_RTSN -> uart1_soc2bt_rts_l + +/* Port 22 */ + CFG_FUNC0, // 176 : UART1_CTSN -> uart1_bt2soc_rts_l + CFG_FUNC0, // 177 : EDP_HPD -> edp_hpd + CFG_IN | SLOW_SLEW, // 178 : UART3_TXD -> uart3_soc2bb_tx + CFG_FUNC0, // 179 : UART3_RXD -> uart3_bb2soc_tx + CFG_IN | SLOW_SLEW, // 180 : UART3_RTSN -> uart3_soc2bb_rts_l + CFG_FUNC0, // 181 : UART3_CTSN -> uart3_bb2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 182 : SPI2_SCLK -> spi2_codec_sclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : SPI2_MOSI -> spi2_codec_mosi + +/* Port 23 */ + CFG_FUNC0, // 184 : SPI2_MISO -> spi2_codec_miso + CFG_OUT_1 | SLOW_SLEW, // 185 : SPI2_SSIN -> spi2_codec_cs_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 186 : ISP0_SDA -> isp0_cam_rear_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 187 : ISP0_SCL -> isp0_cam_rear_scl + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 188 : ISP1_SDA -> isp1_cam_front_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 189 : ISP1_SCL -> isp1_cam_front_scl + CFG_OUT_0 | SLOW_SLEW, // 190 : SENSOR0_RST -> isp0_cam_rear_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> isp0_cam_rear_clk_r + +/* Port 24 */ + CFG_DISABLED, // 192 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 193 : SENSOR0_ISTRB -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : ISP_UART0_TXD -> soc2oscar_isp_uart_txd + CFG_FUNC0, // 195 : ISP_UART0_RXD -> oscar2soc_isp_uart_rxd + CFG_OUT_0 | SLOW_SLEW, // 196 : SENSOR1_RST -> isp1_cam_front_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> isp1_cam_front_clk_r + CFG_DISABLED, // 198 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // 199 : SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 200 : UART7_TXD -> uart7_soc2oscar_txd + CFG_FUNC0, // 201 : UART7_RXD -> uart7_oscar2soc_rxd + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 202 : I2S0_MCK -> i2s0_codec_asp_mck_r + CFG_DISABLED, // 203 : I2S2_MCK -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_j97dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : ULPI_DIR -> nc_soc_gpio_0 + CFG_DISABLED, // 1 : ULPI_STP -> + CFG_IN | PULL_UP, // 2 : ULPI_NXT -> gpio_spkamp_left_irq_l + CFG_DISABLED, // 3 : ULPI_DATA[7] -> + CFG_IN | PULL_UP, // 4 : ULPI_DATA[6] -> gpio_spkamp_right_irq_l + CFG_DISABLED, // 5 : ULPI_DATA[5] -> + CFG_OUT_0 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> gpio_spkamp_keepalive + CFG_DISABLED, // 7 : ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // 8 : ULPI_DATA[3] -> + CFG_DISABLED, // 9 : ULPI_DATA[2] -> + CFG_DISABLED, // 10 : ULPI_DATA[1] -> i2c1_soc2oscar_swdio_1v8 + CFG_DISABLED, // 11 : ULPI_DATA[0] -> i2c1_soc2oscar_swdclk_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 12 : SPI1_SCLK -> spi1_grape_sclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 13 : SPI1_MOSI -> spi1_grape_mosi + CFG_FUNC0, // 14 : SPI1_MISO -> spi1_grape_miso + CFG_OUT_1 | SLOW_SLEW, // 15 : SPI1_SSIN -> spi1_grape_cs_l + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN, // 32 : GPIO[11] -> gpio_btn_home_l + CFG_IN, // 33 : GPIO[12] -> gpio_btn_onoff_l + CFG_DISABLED, // 34 : I2S3_MCK -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : I2S3_LRCK -> i2s3_soc2bt_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 36 : I2S3_BCLK -> i2s3_soc2bt_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2S3_DOUT -> i2s3_soc2bt_data + CFG_FUNC0, // 38 : I2S3_DIN -> i2s3_bt2soc_data + CFG_FUNC0 | SLOW_SLEW, // 39 : CLK32K_OUT -> clk_32k_soc2cumulus + +/* Port 5 */ + CFG_DISABLED, // 40 : PCIE_CLKREQ0_N -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> pcie1_wlan2soc_clkreq_l + CFG_DISABLED, // 42 : NAND_SYS_CLK -> + CFG_OUT_0 | SLOW_SLEW, // 43 : GPIO[0] -> gpio_soc2bb_wake_modem + CFG_IN | PULL_UP, // 44 : GPIO[1] -> gpio_codec_irq_l + CFG_IN | PULL_UP, // 45 : GPIO[2] -> gpio_btn_vol_up_l + CFG_IN | PULL_UP, // 46 : GPIO[3] -> gpio_btn_vol_down_l + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[4] -> gpio_soc2grape_1v8_en + +/* Port 6 */ + CFG_DISABLED, // 48 : GPIO[5] -> GPIO_SOC2CODEC_RST_L + CFG_OUT_0 | SLOW_SLEW, // 49 : GPIO[6] -> gpio_soc2aj_hs4_shunt_en + CFG_OUT_0 | SLOW_SLEW, // 50 : GPIO[7] -> gpio_soc2aj_hs3_shunt_en + CFG_DISABLED, // 51 : GPIO[14] -> bb_ipc_gpio + CFG_DISABLED, // 52 : GPIO[16] -> gpio_board_id3 + CFG_IN | PULL_DOWN, // 53 : GPIO[17] -> gpio_bb2soc_reset_det_l + CFG_DISABLED, // 54 : GPIO[18] -> gpio_boot_config0 + CFG_OUT_0 | SLOW_SLEW, // 55 : GPIO[20] -> gpio_soc2pmu_keepact + +/* Port 7 */ + CFG_OUT_0 | SLOW_SLEW, // 56 : GPIO[21] -> gpio_grape_rst_l + CFG_FUNC0 | SLOW_SLEW, // 57 : UART5_RTXD -> uart5_batt_rtxd + CFG_DISABLED, // 58 : UART8_TXD -> + CFG_IN, // 59 : UART8_RXD -> pmu_gpio_oscar2pmu_host_wake + CFG_DISABLED, // 60 : SPI0_SCLK -> gpio_board_id0 + CFG_DISABLED, // 61 : SPI0_MOSI -> gpio_board_id1 + CFG_DISABLED, // 62 : SPI0_MISO -> gpio_board_id2 + CFG_OUT_0 | SLOW_SLEW, // 63 : SPI0_SSIN -> gpio_soc2wlan_pcie_dev_wake + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : I2C2_SDA -> i2c2_sda_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C2_SCL -> i2c2_scl_1v8 + CFG_DISABLED, // 66 : GPIO[22] -> gpio_bb2soc_gps_sync + CFG_IN | SLOW_SLEW, // 67 : GPIO[23] -> gpio_soc2bb_radio_on_l + CFG_DISABLED, // 68 : GPIO[25] -> gpio_boot_config1 + CFG_DISABLED, // 69 : GPIO[28] -> gpio_boot_config2 + CFG_DISABLED, // 70 : GPIO[29] -> + CFG_DISABLED, // 71 : GPIO[34] -> + +/* Port 9 */ + CFG_OUT_0 | SLOW_SLEW, // 72 : GPIO[35] -> gpio_soc2bt_wake + CFG_IN, // 73 : GPIO[36] -> gpio_ts2soc2pmu_int + CFG_DISABLED, // 74 : GPIO[37] -> + CFG_DISABLED, // 75 : GPIO[39]/PCIE_PERST0_N -> + CFG_DISABLED, // 76 : GPIO[42] -> + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 77 : GPIO[43]/PCIE_PERST1_N -> pcie1_soc2wlan_rst_l + CFG_OUT_0 | PULL_DOWN, // 78 : DISP_VSYNC -> display_sync + CFG_FUNC0 | SLOW_SLEW, // 79 : UART0_TXD -> uart0_soc_txd + +/* Port 10 */ + CFG_FUNC0, // 80 : UART0_RXD -> uart0_soc_rxd + CFG_OUT_0 | SLOW_SLEW, // 81 : TMR32_PWM0 -> oscar_time_sync_host_int + CFG_DISABLED, // 82 : TMR32_PWM1 -> + CFG_DISABLED, // 83 : TMR32_PWM2 -> + CFG_FUNC0 | SLOW_SLEW, // 84 : UART6_TXD -> uart6_ts_acc_txd + CFG_FUNC0, // 85 : UART6_RXD -> uart6_ts_acc_rxd + CFG_FUNC0 | SLOW_SLEW, // 86 : I2C3_SDA -> i2c3_sda_1v8 + CFG_FUNC0 | SLOW_SLEW, // 87 : I2C3_SCL -> i2c3_scl_1v8 + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 96 : I2C0_SDA -> i2c0_sda_1v8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 97 : I2C0_SCL -> i2c0_scl_1v8 + CFG_DISABLED, // 98 : GPIO[38] -> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 99 : UART2_TXD -> uart2_soc2wlan_tx + CFG_FUNC0, // 100 : UART2_RXD -> uart2_wlan2soc_tx + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 101 : UART2_RTSN -> uart2_soc2wlan_rts_l + CFG_FUNC0, // 102 : UART2_CTSN -> uart2_wlan2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 103 : DWI_DO -> dwi_ap_do + +/* Port 13 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 104 : DWI_CLK -> dwi_ap_clk + CFG_FUNC0 | SLOW_SLEW, // 105 : WDOG -> wdog_soc + CFG_IN | PULL_UP, // 106 : GPIO[13] -> gpio_grape_irq_l + CFG_IN | PULL_UP, // 107 : GPIO[19] -> gpio_pmu2soc_irq_l + CFG_IN, // 108 : GPIO[26] -> gpio_force_dfu + CFG_DISABLED, // 109 : GPIO[27] -> tp_gpio_dfu_status + CFG_FUNC0 | SLOW_SLEW, // 110 : SOCHOT0 -> sochot0_l + CFG_FUNC0 | SLOW_SLEW, // 111 : SOCHOT1 -> sochot1_l + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : GPIO[8] -> gpio_board_rev0 + CFG_DISABLED, // 115 : GPIO[9] -> gpio_board_rev1 + CFG_DISABLED, // 116 : GPIO[10] -> gpio_board_rev2 + CFG_IN | PULL_UP, // 117 : GPIO[15] -> gpio_als1_irq_l + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 118 : UART4_TXD -> uart4_soc2oslo_tx + CFG_FUNC0, // 119 : UART4_RXD -> uart4_oslo2soc_tx + +/* Port 15 */ + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 120 : UART4_RTSN -> uart4_soc2oslo_rts_l + CFG_FUNC0, // 121 : UART4_CTSN -> uart4_oslo2soc_rts_l + CFG_FUNC0 | SLOW_SLEW, // 122 : SPI3_MOSI -> spi_mesa_mosi + CFG_FUNC0, // 123 : SPI3_MISO -> spi_mesa_miso + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> spi_mesa_sclk_r + CFG_IN | PULL_DOWN, // 125 : SPI3_SSIN -> gpio_mesa2soc_int + CFG_DISABLED, // 126 : GPIO[24] -> bb_jtag_tms + CFG_IN | PULL_DOWN, // 127 : GPIO[30] -> hsic1_bb2soc_device_rdy + +/* Port 16 */ + CFG_IN | SLOW_SLEW, // 128 : GPIO[31] -> gpio_soc2bb_rst_l + CFG_OUT_0 | SLOW_SLEW, // 129 : GPIO[32] -> hsic1_soc2bb_host_rdy + CFG_OUT_0 | SLOW_SLEW, // 130 : GPIO[33] -> gpio_soc2bb_coredump + CFG_IN | PULL_UP, // 131 : GPIO[40] -> gpio_als2_irq_l + CFG_IN | PULL_DOWN | SLOW_SLEW, // 132 : GPIO[41] -> gpio_soc2oslo_fw_dwl_req + CFG_DISABLED, // 133 : I2S4_MCK -> bb_jtag_tck + CFG_DISABLED, // 134 : I2S4_LRCK -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 135 : I2S4_BCLK -> gpio_soc2oslo_en + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S4_DOUT -> + CFG_DISABLED, // 137 : I2S4_DIN -> + CFG_DISABLED, // 138 : I2C1_SDA -> + CFG_DISABLED, // 139 : I2C1_SCL -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 160 : I2S0_LRCK -> i2s0_codec_asp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 161 : I2S0_BCLK -> i2s0_codec_asp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : I2S0_DOUT -> i2s0_codec_asp_dout + CFG_FUNC0, // 163 : I2S0_DIN -> i2s0_codec_asp_din + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> i2s1_spkamp_mck_r + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 165 : I2S1_LRCK -> i2s1_spkamp_lrck + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 166 : I2S1_BCLK -> i2s1_spkamp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 167 : I2S1_DOUT -> i2s1_spkamp_dout + +/* Port 21 */ + CFG_FUNC0, // 168 : I2S1_DIN -> i2s1_spkamp_din + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 169 : I2S2_LRCK -> i2s2_codec_xsp_lrck + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 170 : I2S2_BCLK -> i2s2_codec_xsp_bclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : I2S2_DOUT -> i2s2_codec_xsp_dout + CFG_FUNC0, // 172 : I2S2_DIN -> i2s2_codec_xsp_din + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 173 : UART1_TXD -> uart1_soc2bt_tx + CFG_FUNC0, // 174 : UART1_RXD -> uart1_bt2soc_tx + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 175 : UART1_RTSN -> uart1_soc2bt_rts_l + +/* Port 22 */ + CFG_FUNC0, // 176 : UART1_CTSN -> uart1_bt2soc_rts_l + CFG_FUNC0, // 177 : EDP_HPD -> edp_hpd + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 178 : UART3_TXD -> uart3_soc2bb_tx + CFG_FUNC0, // 179 : UART3_RXD -> uart3_bb2soc_tx + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 180 : UART3_RTSN -> uart3_soc2bb_rts_l + CFG_FUNC0, // 181 : UART3_CTSN -> uart3_bb2soc_rts_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 182 : SPI2_SCLK -> spi2_codec_sclk + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : SPI2_MOSI -> spi2_codec_mosi + +/* Port 23 */ + CFG_FUNC0, // 184 : SPI2_MISO -> spi2_codec_miso + CFG_OUT_1 | SLOW_SLEW, // 185 : SPI2_SSIN -> spi2_codec_cs_l + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 186 : ISP0_SDA -> isp0_cam_rear_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 187 : ISP0_SCL -> isp0_cam_rear_scl + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 188 : ISP1_SDA -> isp1_cam_front_sda + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 189 : ISP1_SCL -> isp1_cam_front_scl + CFG_OUT_0 | SLOW_SLEW, // 190 : SENSOR0_RST -> isp0_cam_rear_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> isp0_cam_rear_clk_r + +/* Port 24 */ + CFG_DISABLED, // 192 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 193 : SENSOR0_ISTRB -> + CFG_IN | PULL_DOWN | SLOW_SLEW, // 194 : ISP_UART0_TXD -> soc2oscar_isp_uart_txd + CFG_FUNC0, // 195 : ISP_UART0_RXD -> oscar2soc_isp_uart_rxd + CFG_OUT_0 | SLOW_SLEW, // 196 : SENSOR1_RST -> isp1_cam_front_shutdown_l + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> isp1_cam_front_clk_r + CFG_DISABLED, // 198 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // 199 : SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 200 : UART7_TXD -> uart7_soc2oscar_txd + CFG_FUNC0, // 201 : UART7_RXD -> uart7_oscar2soc_rxd + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 202 : I2S0_MCK -> i2s0_codec_asp_mck_r + CFG_DISABLED, // 203 : I2S2_MCK -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J96AP, ~0, { pinconfig_j96ap_0 } }, + { TARGET_BOARD_ID_J96DEV, ~0, { pinconfig_j96dev_0 } }, + { TARGET_BOARD_ID_J97AP, ~0, { pinconfig_j97ap_0 } }, + { TARGET_BOARD_ID_J97DEV, ~0, { pinconfig_j97dev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipad5/properties.c b/target/ipad5/properties.c new file mode 100644 index 0000000..1ac9897 --- /dev/null +++ b/target/ipad5/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad5/rules.mk b/target/ipad5/rules.mk new file mode 100644 index 0000000..3f9ebf1 --- /dev/null +++ b/target/ipad5/rules.mk @@ -0,0 +1,49 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2207=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_SPARE0_CLK_CFG=0x80000004 \ + TARGET_VID0_CLK_CFG=0x81100000 \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + PMU_LCD_PWR_EN=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart2/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy\" \ + DP_DTPATH=\"arm-io/displayport\" \ + TARGET_DDR_792M=1 \ + WITH_TARGET_AMC_PARAMS=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad5b/include/target/adbe_settings.h b/target/ipad5b/include/target/adbe_settings.h new file mode 100644 index 0000000..8a885ea --- /dev/null +++ b/target/ipad5b/include/target/adbe_settings.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013-2104 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0005, + .adbe0_vblank_clk_gate_wakeup = 0x0005, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/ipad5b/include/target/aspnandconfig.h b/target/ipad5b/include/target/aspnandconfig.h new file mode 100644 index 0000000..a410432 --- /dev/null +++ b/target/ipad5b/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 8 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (4*1024*1024) + +#endif diff --git a/target/ipad5b/include/target/boardid.h b/target/ipad5b/include/target/boardid.h new file mode 100644 index 0000000..69f3205 --- /dev/null +++ b/target/ipad5b/include/target/boardid.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TARGET_BOARDID_H +#define TARGET_BOARDID_H + +#define TARGET_BOARD_ID_J81AP (6) +#define TARGET_BOARD_ID_J81DEV (7) +#define TARGET_BOARD_ID_J82AP (2) +#define TARGET_BOARD_ID_J82DEV (3) + +#endif diff --git a/target/ipad5b/include/target/gpiodef.h b/target/ipad5b/include/target/gpiodef.h new file mode 100644 index 0000000..dc47ebe --- /dev/null +++ b/target/ipad5b/include/target/gpiodef.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* ipad5,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 20, 1) // 161 : ULPI_NXT +#define GPIO_BOARD_REV1 GPIO( 19, 7) // 159 : ULPI_DIR +#define GPIO_BOARD_REV2 GPIO( 21, 0) // 168 : ULPI_DATA[2] +#define GPIO_BOARD_REV3 GPIO( 20, 3) // 163 : ULPI_DATA[6] + +/* Miscellaneous Pins */ +#define GPIO_PMU_LCD_PWR_EN (17) + +/* D2207 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO( 10, 7) // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* which IICs to initialize */ +#define IICS_MASK (0xF) + +#define TRISTAR_IIC_BUS (0) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad5b/include/target/lpdp_settings.h b/target/ipad5b/include/target/lpdp_settings.h new file mode 100644 index 0000000..619b591 --- /dev/null +++ b/target/ipad5b/include/target/lpdp_settings.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef LPDP_SETTINGS_H +#define LPDP_SETTINGS_H + +static struct lpdp_port_calibration lpdp_port_calibration_table[1][1] = { + { {LPDP_PHY_LANE_VREG_ADJ_360_mV, 0}, }, +}; + +#define LPDP_PORT_CALIBRATION_TABLE_FIXED (true) + +#endif diff --git a/target/ipad5b/include/target/powerconfig.h b/target/ipad5b/include/target/powerconfig.h new file mode 100644 index 0000000..ba206ce --- /dev/null +++ b/target/ipad5b/include/target/powerconfig.h @@ -0,0 +1,113 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2207_HIBERNATE3, 0xAA }, // enable LDO7 (Tristar), LDO5(Mesa) and LDO3(Sensors), LDO1(Hall) + { PMU_IIC_BUS, kD2207_HIBERNATE6, 0x26 }, // enable BUCK4_SW2+BUCK3_SW3+BUCK3_SW2 (Oscar Rails, DVDD) in hibernate + { PMU_IIC_BUS, kD2207_ACTIVE2, 0x03 }, // WLEDA/WLEDB enable +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* J82 IO Spreadsheet */ +#ifndef TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO5, 0xB9}, // GPIO_PMU2BBPMU_RESET_R_L In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO6, 0xDA}, // UART_BATT_HDQ In, F Edge, Wake, No PU + { PMU_IIC_BUS, kD2207_GPIO7, 0xBA}, // GPIO_BT2PMU_HOST_WAKE In, R Edge, Wake, No PU + { PMU_IIC_BUS, kD2207_GPIO8, 0x7B}, // GPIO_WLAN2PMU_HOST_WAKE In, Hi level, Wake, PD +#ifdef TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO9, 0x8A}, // GPIO_BB2PMU_HOST_WAKE_L In, Active low, Wake, PU, VBUCK3 +#else + { PMU_IIC_BUS, kD2207_GPIO9, 0xB9}, // GPIO_BB2PMU_HOST_WAKE_L In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO10, 0xEA}, // GPIO_CODEC2PMU_HS_IRQ_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD2207_GPIO11, 0xFA}, // GPIO_HALL2PMU_IRQ0 In, Any Edge, Wake, No PU + { PMU_IIC_BUS, kD2207_GPIO12, 0x7B}, // GPIO_TS2SOC2PMU_IRQ In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO16, 0x7B}, // GPIO_OSCAR2PMU_HOST_WAKE In, Hi level, Wake, PD + + { PMU_IIC_BUS, kD2207_BUCK_DWI_CTRL0, 0x23 }, // enable DWI for BUCK0, BUCK1, BUCK5 + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // DWI_EN HIB_32K (for WiFi/BT) +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_OPTIONS, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 + +// Need this only once in lib/power/power.c +#if POWERCONFIG_CHARGE_TABLE +static const struct power_charge_limits pmu_charge_table[16] = { + { 4200, 1000, 1500, 1511 }, { USHRT_MAX, 1000, 1500, 756 }, // 10°C < T ≤ 15°C + { 4200, 1500, 2000, 3021 }, { USHRT_MAX, 1500, 2000, 2266 }, // 15°C < T ≤ 20°C + { 4200, 2000, 4500, 3021 }, { USHRT_MAX, 2000, 4500, 3021 }, // 20°C < T ≤ 45°C +}; +#endif + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define ACC_PWR_LDO (6) + +#define GASGAUGE_BATTERYID_BLOCK 1 +// NOTE: this product doesn't have a charge table + +#endif diff --git a/target/ipad5b/include/target/uartconfig.h b/target/ipad5b/include/target/uartconfig.h new file mode 100644 index 0000000..f81b712 --- /dev/null +++ b/target/ipad5b/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/ipad5b/init.c b/target/ipad5b/init.c new file mode 100644 index 0000000..0f88724 --- /dev/null +++ b/target/ipad5b/init.c @@ -0,0 +1,522 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#endif + +// Board ids +#define J81_AP_BOARD_ID (0x6) +#define J81_DEV_BOARD_ID (0x7) + +#define J82_AP_BOARD_ID (0x2) +#define J82_DEV_BOARD_ID (0x3) + +// Board revs +#define J81_DEV1_BOARD_REV (0x2) +#define J81_PROTO2_BOARD_REV (0x4) +#define J81_PREEVT_BOARD_REV (0x5) + +static uint32_t ipad5b_get_board_rev(void); + +typedef enum { + DISPLAY_UNKNOWN = 0, + DISPLAY_J72 = 2, + DISPLAY_POR = 3, +} ipad5b_display_t; + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; +static bool gpio_display_id_valid; +static ipad5b_display_t display_panel; + +// Display panel id sense pins +#define GPIO_DISPLAY_ID0 GPIO( 18, 1) // 145: I2S4_MCK -> GPIO_DISPLAY_ID0 (JA118) +#define GPIO_DISPLAY_ID1 GPIO( 5, 3) // 43 : I2S1_MCK -> GPIO_DISPLAY_ID1 (JA119) + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +static dp_t dp; +#endif + +void ipad5b_detect_display(void) +{ + /*----------------------------- + Display ID [1:0] = [GPIO43: GPIO145] + + Display ID [1:0] + POR 0b11 (no jumpers stuffed) + J72 0b10 (JA118 stuffed) + Unused 0b01 (JA119 stuffed) + Unused 0b00 (both JA118 and JA119 stuffed) + + S/W Read Flow + 1. Set GPIO as input + 2. Enable PU and disable PD + 3. Read + ------------------------------*/ + + static const char *display_panel_name[] = { + [DISPLAY_UNKNOWN] = "Unknown", + [DISPLAY_J72] = "J72", + [DISPLAY_POR] = "POR", + }; + + gpio_configure(GPIO_DISPLAY_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_DISPLAY_ID1, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_DISPLAY_ID0, GPIO_PUP); + gpio_configure_pupdn(GPIO_DISPLAY_ID1, GPIO_PUP); + + spin(100); // Wait 100us + + display_panel = (gpio_read(GPIO_DISPLAY_ID1) << 1) | gpio_read(GPIO_DISPLAY_ID0); + + dprintf(DEBUG_INFO, "Display panel = %s\n", + display_panel_name[display_panel]); + + gpio_configure(GPIO_DISPLAY_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_DISPLAY_ID1, GPIO_CFG_DFLT); + gpio_display_id_valid = true; +} + +static uint32_t ipad5b_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +uint32_t target_get_display_panel_type(void) +{ + if (!gpio_display_id_valid) { + ipad5b_detect_display(); + } + return display_panel; +} + +static void target_fixup_pmu(void) +{ +#if WITH_HW_POWER +int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + int rc; + uint8_t trc; + + rc=pmu_get_data(0, 0x0001, &trc); + if ( rc<0 ) { + dprintf(DEBUG_CRITICAL, "PMU: cannot read TRC (%d)\n", rc); + } else if ( trc==0x6 || trc==0x7 ) { + rc=pmu_set_data(0, 0x7000, 0x1d, 0); // test mode + if ( rc<0 ) { + dprintf(DEBUG_INFO, "PMU: cannot enter test mode (%d)\n", rc); + } else { + rc=pmu_set_data(0, 0x002A, 0x0B, 0); + if ( rc<0 ) dprintf(DEBUG_INFO, "PMU: cannot change PRE_UVLO_ADJ (%d)\n", rc); + + rc=pmu_set_data(0, 0x7000, 0x00, 0); + if ( rc<0 ) panic("PMU: cannot exit test mode (%d)", rc); + } + } +#endif +} + + +void target_early_init(void) +{ + if (target_config_dev()) { + // Read the panel id early + target_get_display_panel_type(); + } else { + if (ipad5b_get_board_rev() < J81_PROTO2_BOARD_REV) { + platform_not_supported(); + } + } +#if PRODUCT_LLB || PRODUCT_IBSS + pmgr_update_dvfm(platform_get_board_id(),ipad5b_get_board_rev()); + pmgr_update_gfx_states(platform_get_board_id(),ipad5b_get_board_rev()); + target_fixup_pmu(); +#endif +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0x6; + dp.max_link_rate = 0x6; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x0; + dp.vrr_enable = 0x0; + dp.vrr_on = 0x0; + dp.rx_n1= 0x0; + dp.rx_n2= 0x0; + dp.rx_n3= 0x0; + dp.rx_n5= 0x0; + dp.fast_link_training = true; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "ipad4", 0); +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; + DTNode *lpdp_node = NULL; + DTNode *node; +#endif + + uint32_t propSize; + char *propName, *propNamePOR; + void *propData; + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + + extern int lpdp_phy_update_device_tree(DTNode *lpdp_node); + FindNode(0, DPPHY_DTPATH, &lpdp_node); + lpdp_phy_update_device_tree(lpdp_node); + } +#endif + + if (target_config_dev()) { + // multi-touch compatibilty to j72 + if (FindNode(0, MULTITOUCH_DTPATH, &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + if (DISPLAY_J72 == target_get_display_panel_type()) { + strlcpy(propData, "multi-touch,j72", propSize); + } else { + strlcpy(propData, "multi-touch,j82", propSize); + } + } + } + + if (ipad5b_get_board_rev() == J81_DEV1_BOARD_REV) { + // mesa pwr hooked up differently on boards with revs earlier than 3 + if (FindNode(0, "arm-io/spi2/mesa", &node)) { + propName = "function-mesa_pwr_preprotorev3"; + propNamePOR = "function-mesa_pwr"; + if (FindProperty(node, &propName, &propData, &propSize) && + FindProperty(node, &propNamePOR, &propData, &propSize)) { + strlcpy(propName, "function-mesa_pwr", kPropNameLength); + propNamePOR[0] = '~'; + } + } + } + } + + // Update the codec node with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + } + } + } + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c1/audio-speaker0", &node)) { + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + } + + // Update the als calibration data for all nodes that may be present on the dev board + if (FindNode(0, "arm-io/i2c2/als1", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + if (FindNode(0, "arm-io/i2c2/als2", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart8/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart8/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart8/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (FindNode(0, "arm-io/uart8/oscar/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CBAT', propData, propSize); + } + } + + // Update halleffect button -- remove when pre-EVT hardware deprecated + if (FindNode(0, "buttons", &node)) { + if (ipad5b_get_board_rev() < J81_PREEVT_BOARD_REV) { + propName = "function-button_halleffect-preevt"; + propNamePOR = "function-button_halleffect"; + if (FindProperty(node, &propName, &propData, &propSize) && + FindProperty(node, &propNamePOR, &propData, &propSize)) { + strlcpy(propName, "function-button_halleffect", kPropNameLength); + propNamePOR[0] = '~'; + } + } + } + + // WLAN Capri A0 workarounds -- !!!FIXME!!! Remove this when Capri A0 is deprecated + // Remove Capri A0 PCIe hacks + if (FindNode(0, "arm-io/apcie/pci-bridge1/wlan", &node)) { + if (chipid_get_chip_revision() > CHIP_REVISION_A0) { + // Disable workarounds for Capri A1 and later. + propName = "acpie-l1ss-workaround"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "pci-wake-l1pm-disable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } else { + // Fix up the hacks for Capri A0 + propName = "pci-l1pm-control"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "pci-l1pm-control-a0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[16] = '\0'; + } + } + } + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT diff --git a/target/ipad5b/pinconfig.c b/target/ipad5b/pinconfig.c new file mode 100644 index 0000000..4cc4d69 --- /dev/null +++ b/target/ipad5b/pinconfig.c @@ -0,0 +1,989 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 1.2 + I/O Spreadsheet tracker: J82 IO Spreadsheet + Conversion command: csvtopinconfig.py --soc capri --config-column j81:J81 --config-column j82:J82 --copyright 2013-2014 --radar ' J82 IO Spreadsheet' +*/ + +#include +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_j81ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BT2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BT2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED, // 43 : I2S1_MCK -> GPIO_DISPLAY_ID1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_GRAPE_MISO + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_GRAPE_SCLK_R + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_GRAPE_CS_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_DISABLED, // 53 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC_CPU_SLEEP_STATUS + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_DISABLED, // 61 : ISP_UART0_TXD -> NC_ISP_UART0_TXD + CFG_DISABLED, // 62 : ISP_UART0_RXD -> NC_ISP_UART0_RXD + CFG_DISABLED, // 63 : UART7_TXD -> NC_UART7_TXD + +/* Port 8 */ + CFG_DISABLED, // 64 : UART7_RXD -> NC_UART7_RXD + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_DISABLED, // 70 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_FUNC0 | DRIVE_X6 | SLOW_SLEW | INPUT_SCHMITT, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[0] -> NC_SOC_GPIO00 + CFG_DISABLED, // 81 : GPIO[1] -> NC_SOC_GPIO01 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_DISABLED, // 85 : GPIO[5] -> NC_SOC_GPIO05 + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[8] -> NC_SOC_GPIO08 + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_ALS2SOC_DEVBRD_IRQ_L + CFG_DISABLED, // 90 : GPIO[10] -> NC_SOC_GPIO10 + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_DISABLED, // 94 : GPIO[14] -> NC_SOC_GPIO14 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_DISABLED, // 99 : GPIO[19] -> NC_SOC_GPIO19 + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> NC_BOARD_ID4 + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_MIC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2OSCAR_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_OSCAR2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_DISABLED | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BB_TX + CFG_DISABLED, // 141 : UART1_RXD -> UART_BB2SOC_TX + CFG_DISABLED | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED, // 143 : UART1_CTSN -> UART_BB2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED, // 145 : I2S4_MCK -> GPIO_DISPLAY_ID0 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_DISABLED, // 150 : I2S2_LRCK -> NC_I2S2_LRCK + CFG_DISABLED, // 151 : I2S2_BCLK -> NC_I2S2_BCLK + +/* Port 19 */ + CFG_DISABLED, // 152 : I2S2_DOUT -> NC_I2S2_DOUT + CFG_DISABLED, // 153 : I2S2_DIN -> NC_I2S2_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_CODEC_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 156 : SPI1_MISO -> SPI_CODEC_MISO + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_CODEC_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_32K + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_DISABLED, // 160 : ULPI_STP -> GPIO_SOC2DEVBRD_S3E_WAKE + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_DISABLED, // 167 : ULPI_DATA[3] -> GPIO_SOC2DEVBRD_S3E_RESET2_L + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_DISABLED, // 171 : DWI1_DO -> NC_DWI1_DO + CFG_DISABLED, // 172 : DWI1_CLK -> NC_DWI1_CLK + CFG_DISABLED, // 173 : PCIE_CLKREQ0_N -> NC_PCIE_CLKREQ0_N + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED, // 175 : PCIE_CLKREQ2_N -> PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED, // 176 : PCIE_CLKREQ3_N -> NC_PCIE_CLKREQ3_N + CFG_DISABLED, // 177 : NAND_SYS_CLK -> CLK_SOC2DEVBRD_PCIE_24MHZ + CFG_DISABLED, // 178 : PCIE_PERST0_N -> NC_PERST0 + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> NC_PERST3 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_DISABLED, // 183 : I2S2_MCK -> NC_I2S2_MCLK +}; + +static const uint32_t pinconfig_j81dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_RIGHT_IRQ_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BT2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BT2SOC_RTS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED, // 43 : I2S1_MCK -> GPIO_DISPLAY_ID1 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_GRAPE_MISO + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_GRAPE_SCLK_R + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_GRAPE_CS_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_DISABLED, // 53 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC_CPU_SLEEP_STATUS + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_DISABLED, // 61 : ISP_UART0_TXD -> NC_ISP_UART0_TXD + CFG_DISABLED, // 62 : ISP_UART0_RXD -> NC_ISP_UART0_RXD + CFG_DISABLED, // 63 : UART7_TXD -> NC_UART7_TXD + +/* Port 8 */ + CFG_DISABLED, // 64 : UART7_RXD -> NC_UART7_RXD + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_DISABLED, // 70 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_DOUT + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[0] -> NC_SOC_GPIO00 + CFG_DISABLED, // 81 : GPIO[1] -> NC_SOC_GPIO01 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_DISABLED, // 85 : GPIO[5] -> NC_SOC_GPIO05 + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[8] -> NC_SOC_GPIO08 + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_ALS2SOC_DEVBRD_IRQ_L + CFG_DISABLED, // 90 : GPIO[10] -> NC_SOC_GPIO10 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_DISABLED, // 94 : GPIO[14] -> NC_SOC_GPIO14 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_DISABLED, // 99 : GPIO[19] -> NC_SOC_GPIO19 + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> NC_BOARD_ID4 + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_MIC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2OSCAR_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_OSCAR2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BB_TX + CFG_DISABLED, // 141 : UART1_RXD -> UART_BB2SOC_TX + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED, // 143 : UART1_CTSN -> UART_BB2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED, // 145 : I2S4_MCK -> GPIO_DISPLAY_ID0 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_DISABLED, // 150 : I2S2_LRCK -> NC_I2S2_LRCK + CFG_DISABLED, // 151 : I2S2_BCLK -> NC_I2S2_BCLK + +/* Port 19 */ + CFG_DISABLED, // 152 : I2S2_DOUT -> NC_I2S2_DOUT + CFG_DISABLED, // 153 : I2S2_DIN -> NC_I2S2_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_CODEC_SCLK_R + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 156 : SPI1_MISO -> SPI_CODEC_MISO + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_CODEC_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_32K + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_DISABLED, // 160 : ULPI_STP -> GPIO_SOC2DEVBRD_S3E_WAKE + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_DISABLED, // 167 : ULPI_DATA[3] -> GPIO_SOC2DEVBRD_S3E_RESET2_L + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_DISABLED, // 171 : DWI1_DO -> NC_DWI1_DO + CFG_DISABLED, // 172 : DWI1_CLK -> NC_DWI1_CLK + CFG_DISABLED, // 173 : PCIE_CLKREQ0_N -> NC_PCIE_CLKREQ0_N + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED, // 175 : PCIE_CLKREQ2_N -> PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED, // 176 : PCIE_CLKREQ3_N -> NC_PCIE_CLKREQ3_N + CFG_DISABLED, // 177 : NAND_SYS_CLK -> CLK_SOC2DEVBRD_PCIE_24MHZ + CFG_DISABLED, // 178 : PCIE_PERST0_N -> NC_PERST0 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> NC_PERST3 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_DISABLED, // 183 : I2S2_MCK -> NC_I2S2_MCLK +}; + +static const uint32_t pinconfig_j82ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BT2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BT2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED, // 43 : I2S1_MCK -> GPIO_DISPLAY_ID1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_GRAPE_MISO + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_GRAPE_SCLK_R + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_GRAPE_CS_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_DISABLED, // 53 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC_CPU_SLEEP_STATUS + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_DISABLED, // 61 : ISP_UART0_TXD -> NC_ISP_UART0_TXD + CFG_DISABLED, // 62 : ISP_UART0_RXD -> NC_ISP_UART0_RXD + CFG_DISABLED, // 63 : UART7_TXD -> NC_UART7_TXD + +/* Port 8 */ + CFG_DISABLED, // 64 : UART7_RXD -> NC_UART7_RXD + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_DISABLED, // 70 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_FUNC0 | DRIVE_X6 | SLOW_SLEW | INPUT_SCHMITT, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[0] -> NC_SOC_GPIO00 + CFG_DISABLED, // 81 : GPIO[1] -> NC_SOC_GPIO01 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_DISABLED, // 85 : GPIO[5] -> NC_SOC_GPIO05 + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[8] -> NC_SOC_GPIO08 + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_ALS2SOC_DEVBRD_IRQ_L + CFG_DISABLED, // 90 : GPIO[10] -> NC_SOC_GPIO10 + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_DISABLED, // 94 : GPIO[14] -> NC_SOC_GPIO14 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_DISABLED, // 99 : GPIO[19] -> NC_SOC_GPIO19 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> NC_BOARD_ID4 + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_MIC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2OSCAR_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_OSCAR2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_IN | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BB2SOC_TX + CFG_IN | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BB2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED, // 145 : I2S4_MCK -> GPIO_DISPLAY_ID0 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_DISABLED, // 150 : I2S2_LRCK -> NC_I2S2_LRCK + CFG_DISABLED, // 151 : I2S2_BCLK -> NC_I2S2_BCLK + +/* Port 19 */ + CFG_DISABLED, // 152 : I2S2_DOUT -> NC_I2S2_DOUT + CFG_DISABLED, // 153 : I2S2_DIN -> NC_I2S2_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_CODEC_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 156 : SPI1_MISO -> SPI_CODEC_MISO + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_CODEC_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_32K + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_DISABLED, // 160 : ULPI_STP -> GPIO_SOC2DEVBRD_S3E_WAKE + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_DISABLED, // 167 : ULPI_DATA[3] -> GPIO_SOC2DEVBRD_S3E_RESET2_L + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_DISABLED, // 171 : DWI1_DO -> NC_DWI1_DO + CFG_DISABLED, // 172 : DWI1_CLK -> NC_DWI1_CLK + CFG_DISABLED, // 173 : PCIE_CLKREQ0_N -> NC_PCIE_CLKREQ0_N + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED, // 175 : PCIE_CLKREQ2_N -> PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED, // 176 : PCIE_CLKREQ3_N -> NC_PCIE_CLKREQ3_N + CFG_DISABLED, // 177 : NAND_SYS_CLK -> CLK_SOC2DEVBRD_PCIE_24MHZ + CFG_DISABLED, // 178 : PCIE_PERST0_N -> NC_PERST0 + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> NC_PERST3 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_DISABLED, // 183 : I2S2_MCK -> NC_I2S2_MCLK +}; + +static const uint32_t pinconfig_j82dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_RIGHT_IRQ_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BT2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BT2SOC_RTS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED, // 43 : I2S1_MCK -> GPIO_DISPLAY_ID1 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_GRAPE_MISO + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_GRAPE_SCLK_R + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_GRAPE_CS_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_DISABLED, // 53 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC_CPU_SLEEP_STATUS + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_DISABLED, // 61 : ISP_UART0_TXD -> NC_ISP_UART0_TXD + CFG_DISABLED, // 62 : ISP_UART0_RXD -> NC_ISP_UART0_RXD + CFG_DISABLED, // 63 : UART7_TXD -> NC_UART7_TXD + +/* Port 8 */ + CFG_DISABLED, // 64 : UART7_RXD -> NC_UART7_RXD + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_DISABLED, // 70 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_DOUT + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[0] -> NC_SOC_GPIO00 + CFG_DISABLED, // 81 : GPIO[1] -> NC_SOC_GPIO01 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_DISABLED, // 85 : GPIO[5] -> NC_SOC_GPIO05 + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[8] -> NC_SOC_GPIO08 + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_ALS2SOC_DEVBRD_IRQ_L + CFG_DISABLED, // 90 : GPIO[10] -> NC_SOC_GPIO10 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_DISABLED, // 94 : GPIO[14] -> NC_SOC_GPIO14 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_DISABLED, // 99 : GPIO[19] -> NC_SOC_GPIO19 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> NC_BOARD_ID4 + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_MIC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2OSCAR_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_OSCAR2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BB2SOC_TX + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BB2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED, // 145 : I2S4_MCK -> GPIO_DISPLAY_ID0 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_DISABLED, // 150 : I2S2_LRCK -> NC_I2S2_LRCK + CFG_DISABLED, // 151 : I2S2_BCLK -> NC_I2S2_BCLK + +/* Port 19 */ + CFG_DISABLED, // 152 : I2S2_DOUT -> NC_I2S2_DOUT + CFG_DISABLED, // 153 : I2S2_DIN -> NC_I2S2_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_CODEC_SCLK_R + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 156 : SPI1_MISO -> SPI_CODEC_MISO + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_CODEC_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_32K + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_DISABLED, // 160 : ULPI_STP -> GPIO_SOC2DEVBRD_S3E_WAKE + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_DISABLED, // 167 : ULPI_DATA[3] -> GPIO_SOC2DEVBRD_S3E_RESET2_L + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_DISABLED, // 171 : DWI1_DO -> NC_DWI1_DO + CFG_DISABLED, // 172 : DWI1_CLK -> NC_DWI1_CLK + CFG_DISABLED, // 173 : PCIE_CLKREQ0_N -> NC_PCIE_CLKREQ0_N + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED, // 175 : PCIE_CLKREQ2_N -> PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED, // 176 : PCIE_CLKREQ3_N -> NC_PCIE_CLKREQ3_N + CFG_DISABLED, // 177 : NAND_SYS_CLK -> CLK_SOC2DEVBRD_PCIE_24MHZ + CFG_DISABLED, // 178 : PCIE_PERST0_N -> NC_PERST0 + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> NC_PERST3 + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_DISABLED, // 183 : I2S2_MCK -> NC_I2S2_MCLK +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J81AP, ~0, { pinconfig_j81ap_0 } }, + { TARGET_BOARD_ID_J81DEV, ~0, { pinconfig_j81dev_0 } }, + { TARGET_BOARD_ID_J82AP, ~0, { pinconfig_j82ap_0 } }, + { TARGET_BOARD_ID_J82DEV, ~0, { pinconfig_j82dev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipad5b/properties.c b/target/ipad5b/properties.c new file mode 100644 index 0000000..1ac9897 --- /dev/null +++ b/target/ipad5b/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad5b/rules.mk b/target/ipad5b/rules.mk new file mode 100644 index 0000000..639e0f0 --- /dev/null +++ b/target/ipad5b/rules.mk @@ -0,0 +1,50 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +# BUCK_CPU, BUCK_GPU and BUCK_RAM should be reviewed +# if any changed happen in drivers/dialog/pmu/power.c:power_get_buck_value() + +OPTIONS += \ + DIALOG_D2207=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + TARGET_DDR_798M=1 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + PMU_LCD_PWR_EN=1 \ + AMC_NUM_CHANNELS=4 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_GPU=2 \ + BUCK_RAM=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi3/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart2/wlan\" \ + DP_DTPATH=\"arm-io/displayport\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy\" \ + BT_DTPATH=\"arm-io/uart3/bluetooth\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad5c/include/target/adbe_settings.h b/target/ipad5c/include/target/adbe_settings.h new file mode 100644 index 0000000..70ac9e1 --- /dev/null +++ b/target/ipad5c/include/target/adbe_settings.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0132, + .adbe0_vblank_clk_gate_wakeup = 0x0132, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, + + { + .name = "camelia", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/ipad5c/include/target/aspnandconfig.h b/target/ipad5c/include/target/aspnandconfig.h new file mode 100644 index 0000000..a9c1b69 --- /dev/null +++ b/target/ipad5c/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 8 +#define ASPNAND_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (8*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/ipad5c/include/target/boardid.h b/target/ipad5c/include/target/boardid.h new file mode 100644 index 0000000..432c012 --- /dev/null +++ b/target/ipad5c/include/target/boardid.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TARGET_BOARDID_H +#define TARGET_BOARDID_H + +#define TARGET_BOARD_ID_J98AP (12) +#define TARGET_BOARD_ID_J98DEV (13) +#define TARGET_BOARD_ID_J99AP (4) +#define TARGET_BOARD_ID_J99DEV (5) + +// Board revs +#define J98_DEV1_BOARD_REV (0x0) +#define J98_DEV2_BOARD_REV (0x1) +// board revs on AP are reversed +// J99: Display timing selection on Form Factor is incorrect +#define J99_PROTO0_BOARD_REV_LOCAL (0xE) +#define J99_PROTO0_BOARD_REV_CHINA (0xD) +#define J99_PROTO1_BOARD_REV_LOCAL (0xC) +#define J99_PROTO1_BOARD_REV_CHINA (0xB) +#define J99_PROTO2_BOARD_REV (0xA) +#define J99_PROTO3_BOARD_REV (0x9) +#define J99_PROTO3_P9_BOARD_REV (0x8) +#define J99_EVT_BOARD_REV (0x7) +#define J99_EVT_PLUS_BOARD_REV (0x6) +#define J99_EVT2_BOARD_REV (0x5) + +#endif diff --git a/target/ipad5c/include/target/gpiodef.h b/target/ipad5c/include/target/gpiodef.h new file mode 100644 index 0000000..b09b925 --- /dev/null +++ b/target/ipad5c/include/target/gpiodef.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* ipad5,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 20, 1) // 161 : ULPI_NXT +#define GPIO_BOARD_REV1 GPIO( 19, 7) // 159 : ULPI_DIR +#define GPIO_BOARD_REV2 GPIO( 21, 0) // 168 : ULPI_DATA[2] +#define GPIO_BOARD_REV3 GPIO( 20, 3) // 163 : ULPI_DATA[6] + +/* Miscellaneous Pins */ +#define GPIO_PMU_LCD_PWR_EN (17) + +/* D2207 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO( 10, 7) // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Enable for GPU UVD */ +#define GPIO_SOC2GPUUVD_EN GPIO( 10, 0) + +/* which IICs to initialize */ +#define IICS_MASK (0xF) + +#define TRISTAR_IIC_BUS (0) + +#define BACKLIGHT_IIC_BUS (0) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad5c/include/target/lpdp_settings.h b/target/ipad5c/include/target/lpdp_settings.h new file mode 100644 index 0000000..619b591 --- /dev/null +++ b/target/ipad5c/include/target/lpdp_settings.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef LPDP_SETTINGS_H +#define LPDP_SETTINGS_H + +static struct lpdp_port_calibration lpdp_port_calibration_table[1][1] = { + { {LPDP_PHY_LANE_VREG_ADJ_360_mV, 0}, }, +}; + +#define LPDP_PORT_CALIBRATION_TABLE_FIXED (true) + +#endif diff --git a/target/ipad5c/include/target/powerconfig.h b/target/ipad5c/include/target/powerconfig.h new file mode 100644 index 0000000..49d64e4 --- /dev/null +++ b/target/ipad5c/include/target/powerconfig.h @@ -0,0 +1,120 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 3 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2207_HIBERNATE6, 0x24 }, // enable BUCK4_SW2+BUCK3_SW3 (Oscar Rails) in hibernate +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2207_GPIO3, 0xDA}, // GPIO_IOXPNDR_INT_L In, F Edge, No Push-Pull, No Wake, PU + { PMU_IIC_BUS, kD2207_GPIO4, 0x7B}, // GPIO_TS2ORIONSOC2PMU_IRQ In, R Edge, No Push-Pull, No Wake, PU +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO5, 0x09}, // GPIO_PMU2BBPMU_RESET_L Out 0, Push-Pull, VBUCK3 +#else + { PMU_IIC_BUS, kD2207_GPIO5, 0xB9}, // GPIO_PMU2BBPMU_RESET_L In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO6, 0xDA}, // UART_BATT_HDQ In, F Edge, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO7, 0xBA}, // GPIO_BT2PMU_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO8, 0x7B}, // GPIO_WLAN2PMU_HOST_WAKE In, R Edge, No Pull-Up, No Wake, PD +#if TARGET_HAS_BASEBAND + { PMU_IIC_BUS, kD2207_GPIO9, 0x8A}, // GPIO_BB2PMU_HOST_WAKE_L In, Active low, Wake, PU, VBUCK3 +#else + { PMU_IIC_BUS, kD2207_GPIO9, 0xB9}, // GPIO_BB2PMU_HOST_WAKE_L In, R Edge, PD +#endif + { PMU_IIC_BUS, kD2207_GPIO10, 0xEA}, // GPIO_CODEC2PMU_HS_IRQ_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD2207_GPIO11, 0xFB}, // GPIO_HALL2PMU_IRQ0 Both Edges, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO12, 0x7B}, // GPIO_TS2SOC2PMU_IRQ In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO13, 0xEA}, // GPIO_HALL2PMU_IRQ1 Both Edges, VBUCK3, Wake, PU + { PMU_IIC_BUS, kD2207_GPIO14, 0xB8}, // PCIE_WLAN2PMU_WAKE_L In, F Edge, VBUCK3, No Wake, PU + { PMU_IIC_BUS, kD2207_GPIO15, 0xDA}, // GPIO_GANGES2SOC2PMU_IRQ_L In, F Edge, Wake, PD + { PMU_IIC_BUS, kD2207_GPIO16, 0x7B}, // GPIO_OSCAR2PMU_HOST_WAKE In, Hi level, Wake, PD + + { PMU_IIC_BUS, kD2207_BUCK_DWI_CTRL0, 0x23 }, // enable DWI for BUCK0, BUCK1, BUCK5 + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // HIB_32K (for WiFi/BT) + DWI_EN +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_OPTIONS, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2207_BUCK5_VSEL } +}; + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { + { 4100, 1000, 1500, 2018 }, // 10 - 15C + { 4200, 1000, 1500, 2018 }, + { USHRT_MAX, 1000, 1500, 2018 }, + { 4100, 1500, 2000, 6053 }, // 15 - 20C + { 4200, 1500, 2000, 4035 }, + { USHRT_MAX, 1500, 2000, 2018 }, + { 4100, 2000, 4500, 6053 }, // 20 - 45C + { 4200, 2000, 4500, 5044 }, + { USHRT_MAX, 2000, 4500, 4035 }, +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_MAX_USB_INPUT_CURRENT 2400 +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 + + +#define ACC_PWR_LDO (6) + +#define GASGAUGE_BATTERYID_BLOCK 1 + +#endif diff --git a/target/ipad5c/include/target/uartconfig.h b/target/ipad5c/include/target/uartconfig.h new file mode 100644 index 0000000..a1f3e65 --- /dev/null +++ b/target/ipad5c/include/target/uartconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#endif diff --git a/target/ipad5c/init.c b/target/ipad5c/init.c new file mode 100644 index 0000000..20a4186 --- /dev/null +++ b/target/ipad5c/init.c @@ -0,0 +1,995 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#endif + +// Display panel type +typedef enum { + DISPLAY_PANEL_TYPE_UNKNOWN = 0, + DISPLAY_PANEL_TYPE_CAMELIA, + DISPLAY_PANEL_TYPE_TULIP, + // Metadata + DISPLAY_PANEL_TYPE_COUNT +} display_panel_type; + +static const char *display_panel_types[] = { + "UNKNOWN", + "j99POC", + "ipad5c", +}; + +typedef enum { + DISPLAY_SWITCH_TYPE_UNKNOWN = 0, + DISPLAY_SWITCH_TYPE_TEMP_KONA, + DISPLAY_SWITCH_TYPE_KONA, + // Metadata + DISPLAY_SWITCH_TYPE_COUNT +} display_switch_type; + +static const char *display_switch_types[] = { + "UNKNOWN", + "multi-touch,j99-st", + "multi-touch,j99", +}; + +// Display panel id sense pins +#define DISPLAY_TO_AP_ID0 GPIO(22, 5) // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + +uint32_t ipad5c_get_board_rev(void); +static void ipad5c_get_display_info(void); +uint32_t target_get_display_panel_type(void); +uint32_t target_get_display_switch_type(void); + +static bool gpio_board_rev_valid; +static bool gpio_display_id_valid; +static uint32_t gpio_board_rev; +static display_panel_type display_panel; +static display_switch_type display_switch; +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +static dp_t dp; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, -90); + +bool check_is_board_deprecated = false; + +uint32_t ipad5c_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} +// The panel id pin mappings are described by the following id pin states: + +// ID0 Panel Switch +// ---- ----- ----- +// PD Camelia Temp_kona +// PU Tulip Temp_kona +// Open Tulip Kona + +static void ipad5c_get_display_info(void) +{ + if (target_config_ap()) { + uint32_t get_board_rev; + get_board_rev = ipad5c_get_board_rev(); + switch(get_board_rev) { + case J99_PROTO0_BOARD_REV_LOCAL: + case J99_PROTO0_BOARD_REV_CHINA: + display_panel = DISPLAY_PANEL_TYPE_CAMELIA; + display_switch = DISPLAY_SWITCH_TYPE_TEMP_KONA; + break; + case J99_PROTO1_BOARD_REV_LOCAL: + case J99_PROTO1_BOARD_REV_CHINA: + case J99_PROTO2_BOARD_REV: + display_panel = DISPLAY_PANEL_TYPE_TULIP; + display_switch = DISPLAY_SWITCH_TYPE_TEMP_KONA; + break; + default: + display_panel = DISPLAY_PANEL_TYPE_TULIP; + display_switch = DISPLAY_SWITCH_TYPE_KONA; + break; + } + dprintf(DEBUG_INFO, "get_board_rev %d Display panel = %s\nDisplay switch = %s\n", + get_board_rev, + display_panel_types[display_panel], + display_switch_types[display_switch]); + } else { + const char *id0; + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_IN); + + gpio_configure_pupdn(DISPLAY_TO_AP_ID0, GPIO_PUP); + + spin(100); // Wait 100us + + if (gpio_read(DISPLAY_TO_AP_ID0)) { + // ID0 could be externally pulled low or it could be + // floating. Change the polarity of the internal pull. + gpio_configure_pupdn(DISPLAY_TO_AP_ID0, GPIO_PDN); + spin(100); // Wait 100us + + if (!gpio_read(DISPLAY_TO_AP_ID0)) { + // ID0 is open. + id0 = "open"; + display_panel = DISPLAY_PANEL_TYPE_TULIP; + display_switch = DISPLAY_SWITCH_TYPE_KONA; + gpio_display_id_valid = true; + } else { + // ID0 has an external pull up. + id0 = "pu"; + display_panel = DISPLAY_PANEL_TYPE_TULIP; + display_switch = DISPLAY_SWITCH_TYPE_TEMP_KONA; + gpio_display_id_valid = true; + } + + } else { + // ID1 has an external pull down. + id0 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_CAMELIA; + display_switch = DISPLAY_SWITCH_TYPE_TEMP_KONA; + gpio_display_id_valid = true; + } + + dprintf(DEBUG_INFO, "%spanel id pin state: id0=%s\n", + gpio_display_id_valid ? "" : "Unknown", id0); + + ASSERT(display_panel < DISPLAY_PANEL_TYPE_COUNT); + ASSERT(display_switch < DISPLAY_SWITCH_TYPE_COUNT); + + dprintf(DEBUG_INFO, "Display panel = %s\nDisplay switch = %s\n", + display_panel_types[display_panel], + display_switch_types[display_switch]); + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_DFLT); + gpio_display_id_valid = true; + } +} + +uint32_t target_get_display_panel_type(void) +{ + if (!gpio_display_id_valid) { + ipad5c_get_display_info(); + } + return display_panel; +} + +uint32_t target_get_display_switch_type(void) +{ + if (!gpio_display_id_valid) { + ipad5c_get_display_info(); + } + return display_switch; +} + +bool is_board_deprecated(void) { + uint32_t board_id; + uint32_t board_rev; + + board_id = platform_get_board_id(); + board_rev = ipad5c_get_board_rev(); + + //Check Dev boards first. + if (( board_id == TARGET_BOARD_ID_J98DEV || board_id == TARGET_BOARD_ID_J99DEV) && (board_rev == J98_DEV1_BOARD_REV)) { + return true; + } + + //Check AP boards + switch(board_rev) { + case J99_PROTO0_BOARD_REV_LOCAL: + case J99_PROTO0_BOARD_REV_CHINA: + case J99_PROTO1_BOARD_REV_LOCAL: + case J99_PROTO1_BOARD_REV_CHINA: + return true; + } + + return false; +} + +#if WITH_HW_POWER +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); +int charger_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); +#endif + +// TODO: Abstract DPOT code in a DPOT driver +// Begin DPOT code +#define GPU_UVD_DPOT_IIC_BUS (3) + +#define GPU_UVD_DPOT_IIC_ADDRESS (0xA0) + +/* Register addresses for GPU UVD DPOT */ +#define GPU_UVD_DPOT_IVRA (0x00) +#define GPU_UVD_DPOT_IVRB (0x01) +#define GPU_UVD_DPOT_ACR (0x10) + +#define GPU_UVD_DPOT_READ_MISMATCH_ERROR (-2) +#define GPU_UVD_DPOT_INVALID_WIPER_ERROR (-3) + +typedef enum { + GPU_UVD_DPOT_WIPER_A, + GPU_UVD_DPOT_WIPER_B +} gpu_uvd_dpot_wiper; + +#if PRODUCT_LLB || PRODUCT_IBSS +static void gpu_uvd_dpot_error(int error_code) +{ + panic("GPU UVD: Error communicating with DPOT (%d)\n", error_code); +} + +static void gpu_uvd_dpot_poll_busy_bit(void) +{ + int rc = 0; + uint8_t read_data[2] = { 0 }; + uint8_t busy; + + do { + read_data[0] = GPU_UVD_DPOT_ACR; + if ((rc = iic_read(GPU_UVD_DPOT_IIC_BUS, GPU_UVD_DPOT_IIC_ADDRESS, &read_data[0], 1, &read_data[1], 1, IIC_COMBINED))) + gpu_uvd_dpot_error(rc); + + busy = (read_data[1] >> 5) & 0x1; + } while (busy); +} + +static uint8_t gpu_uvd_dpot_get_wiper_voltage(gpu_uvd_dpot_wiper wiper) +{ + int rc = 0; + uint8_t read_data[2] = { 0 }; + + switch (wiper) { + case GPU_UVD_DPOT_WIPER_A: + read_data[0] = GPU_UVD_DPOT_IVRA; + break; + case GPU_UVD_DPOT_WIPER_B: + read_data[0] = GPU_UVD_DPOT_IVRB; + break; + default: + gpu_uvd_dpot_error(GPU_UVD_DPOT_INVALID_WIPER_ERROR); + } + + if ((rc = iic_read(GPU_UVD_DPOT_IIC_BUS, GPU_UVD_DPOT_IIC_ADDRESS, &read_data[0], 1, &read_data[1], 1, IIC_COMBINED))) + gpu_uvd_dpot_error(rc); + + return read_data[1]; +} + +static void gpu_uvd_dpot_set_wiper_voltage(gpu_uvd_dpot_wiper wiper, uint8_t wiper_voltage) +{ + int rc = 0; + uint8_t write_data[2]; + uint8_t written_wiper_voltage; + + switch (wiper) { + case GPU_UVD_DPOT_WIPER_A: + write_data[0] = GPU_UVD_DPOT_IVRA; + break; + case GPU_UVD_DPOT_WIPER_B: + write_data[0] = GPU_UVD_DPOT_IVRB; + break; + default: + gpu_uvd_dpot_error(GPU_UVD_DPOT_INVALID_WIPER_ERROR); + } + + write_data[1] = wiper_voltage; + + if ((rc = iic_write(GPU_UVD_DPOT_IIC_BUS, GPU_UVD_DPOT_IIC_ADDRESS, write_data, 2))) + gpu_uvd_dpot_error(rc); + + gpu_uvd_dpot_poll_busy_bit(); + + written_wiper_voltage = gpu_uvd_dpot_get_wiper_voltage(wiper); + + if (written_wiper_voltage != write_data[1]) { + dprintf(DEBUG_CRITICAL, "GPU UVD: Error writing to GPU_UVD_DPOT_WIPER%s. Expected (0x%x) but read (0x%x).\n", + ((wiper == GPU_UVD_DPOT_WIPER_A) ? "A" : "B"), write_data[1], written_wiper_voltage); + gpu_uvd_dpot_error(GPU_UVD_DPOT_READ_MISMATCH_ERROR); + } +} + +static bool gpu_uvd_dpot_is_nvmem_writable(void) +{ + int rc = 0; + uint8_t read_data[2] = { 0 }; + + read_data[0] = GPU_UVD_DPOT_ACR; + + if ((rc = iic_read(GPU_UVD_DPOT_IIC_BUS, GPU_UVD_DPOT_IIC_ADDRESS, &read_data[0], 1, &read_data[1], 1, IIC_COMBINED))) + gpu_uvd_dpot_error(rc); + + return read_data[1] != 0xc0; +} + +static void gpu_uvd_dpot_set_nvmem_writable(bool enable) +{ + // Clearing ACR[7] bit enables NV writes; ACR[6] always set to disable shutdown mode + uint8_t acr_config = (enable) ? 0x40 : 0xc0; + uint8_t write_data[2]; + uint8_t read_data[2]; + int rc = 0; + + write_data[0] = GPU_UVD_DPOT_ACR; + write_data[1] = acr_config; + + if ((rc = iic_write(GPU_UVD_DPOT_IIC_BUS, GPU_UVD_DPOT_IIC_ADDRESS, write_data, 2))) + gpu_uvd_dpot_error(rc); + + gpu_uvd_dpot_poll_busy_bit(); + + read_data[0] = GPU_UVD_DPOT_ACR; + if ((rc = iic_read(GPU_UVD_DPOT_IIC_BUS, GPU_UVD_DPOT_IIC_ADDRESS, &read_data[0], 1, &read_data[1], 1, IIC_COMBINED))) + gpu_uvd_dpot_error(rc); + + if (read_data[1] != write_data[1]) { + dprintf(DEBUG_CRITICAL, "GPU UVD: Error writing to GPU_UVD_DPOT_ACR. Expected (0x%x) but read (0x%x).\n", + write_data[1], read_data[1]); + gpu_uvd_dpot_error(GPU_UVD_DPOT_READ_MISMATCH_ERROR); + } +} + +static void gpu_uvd_dpot_init(void) +{ + uint32_t wiper_voltage_a, wiper_voltage_b; + uint32_t pmu_v_uvd_voltage; + + // Get V4 voltage, convert to PMU VSEL, and convert back to mV to get actual PMU output for wiper equations + pmu_v_uvd_voltage = chipid_get_gpu_voltage(CHIPID_GPU_VOLTAGE_V_UVD); + platform_convert_voltages(BUCK_GPU, 1, &pmu_v_uvd_voltage); + pmu_v_uvd_voltage = platform_get_dwi_to_mv(BUCK_GPU, pmu_v_uvd_voltage); + + // Use 32-bit fixed point arithmetic with a scaling factor of 1e4 to determine wiper voltage codes + // Take ceiling of integer division using ceiling(x/y) = truncate[(x + y - 1) / y] + // Code_UVD,det = Code_WiperA = 1280.06 * (VSEL_P6,volts - 0.08) - 1216.51 + wiper_voltage_a = (128006 * pmu_v_uvd_voltage - 10240480 - 121651000 + 100000 - 1) / 100000; + // Code_ARM,th = Code_WiperB = 1280.06 * (VSEL_P6,volts - 0.045) - 1216.51 + wiper_voltage_b = (128006 * pmu_v_uvd_voltage - 5760270 - 121651000 + 100000 - 1) / 100000; + + gpio_write(GPIO_SOC2GPUUVD_EN, 1); // Enable GPU UVD system + + spin(10000); // Wait 10 ms for GPU UVD setup + + gpu_uvd_dpot_poll_busy_bit(); + + // Check to configure Wiper A (minimize EEPROM writes to maximize on 100k write cycle endurance) + if (gpu_uvd_dpot_get_wiper_voltage(GPU_UVD_DPOT_WIPER_A) != wiper_voltage_a) { + if (!gpu_uvd_dpot_is_nvmem_writable()) + gpu_uvd_dpot_set_nvmem_writable(true); + + gpu_uvd_dpot_set_wiper_voltage(GPU_UVD_DPOT_WIPER_A, wiper_voltage_a); + } + + // Check to configure Wiper B + if (gpu_uvd_dpot_get_wiper_voltage(GPU_UVD_DPOT_WIPER_B) != wiper_voltage_b) { + if (!gpu_uvd_dpot_is_nvmem_writable()) + gpu_uvd_dpot_set_nvmem_writable(true); + + gpu_uvd_dpot_set_wiper_voltage(GPU_UVD_DPOT_WIPER_B, wiper_voltage_b); + } + + // Check to disable non-volatile writes + if (gpu_uvd_dpot_is_nvmem_writable()) + gpu_uvd_dpot_set_nvmem_writable(false); + + gpio_write(GPIO_SOC2GPUUVD_EN, 0); // Disable GPU UVD system +} +#endif +// End DPOT code + +void target_early_init(void) +{ + // Get the display panel type. + ipad5c_get_display_info(); + +#if WITH_HW_POWER + int rc; + const uint32_t bid=platform_get_board_id(); + if ( bid == TARGET_BOARD_ID_J98DEV || bid == TARGET_BOARD_ID_J99DEV ) { + rc = pmu_set_data(0, 0x040e, 0xc8, true); + if ( rc!=0 ) dprintf(DEBUG_INFO, "pmu: write failed (%d)\n", rc); + } +#if PRODUCT_LLB || PRODUCT_IBSS + // J99 EVT+ Hall-Effect Sensor IRQs change + if (!target_config_ap() || (ipad5c_get_board_rev() > J99_EVT_PLUS_BOARD_REV)) { + // GPIO11 + rc = pmu_set_data(0, 0x040a, 0xea, true); + if (rc != 0) dprintf(DEBUG_INFO, "pmu: write failed (%d)\n", rc); + + // GPIO13 + rc = pmu_set_data(0, 0x040c, 0xe8, true); + if (rc != 0) dprintf(DEBUG_INFO, "pmu: write failed (%d)\n", rc); + } +#if 0 + // this change is making charge to not charge , disabling ... + // for detecting VCENTER on Ganges rdar://18532953 + // set VSET to 3.73V allowing VCenter to 3.83 :: Vset + 100mV + charger_set_data(3, 0x1f8, 0x00, true); + charger_set_data(3, 0x1f9, 0x80, true); +#endif +#endif +#endif +#if PRODUCT_LLB || PRODUCT_IBSS + pmgr_update_dvfm(platform_get_board_id(),ipad5c_get_board_rev()); + pmgr_update_gfx_states(platform_get_board_id(),ipad5c_get_board_rev()); + + if (pmgr_check_gpu_use650MHz_binned(platform_get_board_id(), ipad5c_get_board_rev()) || + pmgr_check_gpu_use650MHz_unbinned(platform_get_board_id(), ipad5c_get_board_rev())) { + gpu_uvd_dpot_init(); + } +#endif +} + +void target_late_init(void) +{ + //Check if board is deprecated + if (check_is_board_deprecated && is_board_deprecated()) { + platform_not_supported(); + } + +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_CAMELIA: + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0xa; + dp.max_link_rate = 0xa; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x0; + dp.vrr_enable = 0x1; + dp.vrr_on = 0x0; + dp.rx_n1= 0x0; + dp.rx_n2= 0x0; + dp.rx_n3= 0x0; + dp.rx_n5= 0x0; + dp.fast_link_training = true; + break; + case DISPLAY_PANEL_TYPE_TULIP: + dp.mode = 0x1; + dp.type = 0x1; + dp.min_link_rate = 0xc; + dp.max_link_rate = 0xc; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x1; + dp.vrr_enable = 0x1; + dp.vrr_on = 0x1; + dp.rx_n1= 25; + dp.rx_n2= 2; + dp.rx_n3= 16030; + dp.rx_n5= 0x0; + dp.fast_link_training = true; + break; + } + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + uint32_t panel_type_index; + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + panel_type_index = target_get_display_panel_type(); + env_set("display-timing", display_panel_types[panel_type_index], 0); + + if (panel_type_index == DISPLAY_PANEL_TYPE_CAMELIA) { + env_set("adfe-tunables", "camelia", 0); + env_set("adbe-tunables", "camelia", 0); + } +} + +#endif + +#if WITH_DEVICETREE + +// J99 Proto2: Update Device Tree to move BT & WiFi Enable Controls to the IOExpander +void target_ipad5c_use_pmu_gpios_wlan_bt(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + if (FindNode(0, WIFI_DTPATH, &node)) { + //Fix reg on property + propName = "function-reg_on_p1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propName, 0, kPropNameLength); + strlcpy(propName, "function-reg_on", kPropNameLength); + } + propName = "function-reg_on"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // Disable the proto2 and greater property + propName[0] = '~'; + } + } + + //Fix bluetooth + if (FindNode(0, BT_DTPATH, &node)) { + //Fix reg on property + propName = "function-power_enable_p1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propName, 0, kPropNameLength); + strlcpy(propName, "function-power_enable", kPropNameLength); + } + propName = "function-power_enable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // Disable the proto2 and greater property + propName[0] = '~'; + } + } + //disable the gpio expander driver + if (FindNode(0, "arm-io/i2c3/tca7408", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // Disable the proto2 and greater property + propName[0] = '~'; + } + } +} + +void hid_update_device_tree() +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + strlcpy(propData, display_switch_types[display_switch], propSize); + } + if (display_switch != DISPLAY_SWITCH_TYPE_KONA) { + //Fix up the device tree to support pre Kona touch + propName = "function-clock_enable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-clock_enPre3"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-clock_enable", strlen(propName)+1); + } + propName = "function-power_ana"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-power_pp3"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-power_ana", strlen(propName)+1); + } + } else { + propName = "swd-flash-update"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + propName = "multitouch-to-display-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('MtDO', propData, propSize); + } + propName = "firefly-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FfCl', propData, propSize); + } + } +} + +//Remove when all HW prior to EVT is deprecated +static void ipad5c_set_old_backlight_values(DTNode *node) +{ + uint32_t propSize; + char *propName; + void *propData; + + propName = "milliAmps2DACPart1MaxCurrent"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x00030000; + } + propName = "milliAmps2DACPart2MaxCurrent"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x00140000; + } + propName = "calibratedMaxCurrent"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x0011E3D7; + } + propName = "calibratedMidCurrent"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x00068000; + } + propName = "mA2Nits2ndOrderCoef"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0xFFFFFFF9; + } + propName = "mA2Nits1stOrderCoef"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x00000ED1; + } + propName = "mA2Nits0thOrderCoef"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0xFFFFFFDC; + } + propName = "nits2mAmps2ndOrderCoef"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x0000A100; + } + propName = "nits2mAmps1stOrderCoef"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x00114042; + } + propName = "nits2mAmps0thOrderCoef"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x000002B7; + } +} + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; + DTNode *lpdp_node = NULL; + DTNode *node; +#endif + + uint32_t propSize; + char *propName; + void *propData; + dt_node_t *dtnode; + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + + extern int lpdp_phy_update_device_tree(DTNode *lpdp_node); + FindNode(0, DPPHY_DTPATH, &lpdp_node); + lpdp_phy_update_device_tree(lpdp_node); + + } +#endif + + // Update the codec node with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi3/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + } + } + } + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c1/audio-speaker0", &node)) { + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + } + + // Update the als calibration data for all nodes that may be present on the dev board + if (FindNode(0, "arm-io/i2c2/als1", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + if (FindNode(0, "arm-io/i2c2/als2", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + + // J99: Update screen brightness settings for EVT systems + //Default is evt. Fix preevt + if (ipad5c_get_board_rev() > J99_EVT_BOARD_REV) { + ipad5c_set_old_backlight_values(node); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart7/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart7/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart7/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (FindNode(0, "arm-io/uart7/oscar/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + // WLAN Capri A0 workarounds -- !!!FIXME!!! Remove this when Capri A0 is deprecated + // Remove Capri A0 PCIe hacks + if (FindNode(0, "arm-io/apcie/pci-bridge1/wlan", &node)) { + if (chipid_get_chip_revision() > CHIP_REVISION_A0) { + // Disable workarounds for Capri A1 and later. + propName = "acpie-l1ss-workaround"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "pci-wake-l1pm-disable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } else { + // Fix up the hacks for Capri A0 + propName = "pci-l1pm-control"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "pci-l1pm-control-a0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[16] = '\0'; + } + } + } + + const uint32_t board_id = platform_get_board_id(); + // IO expander GPIO 4 is not used on EVT2, so disable function-acc_sw_en. + if ((board_id == TARGET_BOARD_ID_J98AP || board_id == TARGET_BOARD_ID_J99AP) && (ipad5c_get_board_rev() <= J99_EVT2_BOARD_REV)) { + if (FindNode(0, "dock-orion", &node)) { + propName = "function-acc_sw_en"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + } else { + // Undo IO expander otp-data values in device tree, which were set for EVT2. + if (FindNode(0, "arm-io/i2c3/tca7408", &node)) { + propName = "otp-data"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0xff000000; + ((uint32_t *)propData)[1] = 0x00000000; + } + } + } + /* + * Need to support HW which does not have the GPIO Expander. + * HW before Proto2 do not have the expander + * HW before Dev2 do not have the expander + */ + if (((board_id == TARGET_BOARD_ID_J98AP || board_id == TARGET_BOARD_ID_J99AP) && (ipad5c_get_board_rev() >= J99_PROTO1_BOARD_REV_CHINA)) || + ((board_id == TARGET_BOARD_ID_J98DEV || board_id == TARGET_BOARD_ID_J99DEV) && (ipad5c_get_board_rev() < J98_DEV2_BOARD_REV))) { + target_ipad5c_use_pmu_gpios_wlan_bt(); + } + + // EVT2 (or dev boards with dip switches set to EVT2) will use the micro based Orion + // Older revs will continue to support TriStar based Orion for bring-up + if (ipad5c_get_board_rev() == J99_EVT2_BOARD_REV) { + // Enable Micro Orion + if (dt_find_node(0, "arm-io/i2c1/orion-ic", &dtnode)) { + propName = "AAPL,ignore"; + if (dt_get_prop(dtnode, &propName, &propData, &propSize)) { + dt_remove_prop(dtnode, propName); + } + } + // Enable aod flashing of Orion's FW + if (dt_find_node(0, "arm-io/aod4", &dtnode)) { + propName = "AAPL,ignore"; + if (dt_get_prop(dtnode, &propName, &propData, &propSize)) { + dt_remove_prop(dtnode, propName); + } + } + } else { + // Enable TriStar Orion + if (dt_find_node(0, "arm-io/i2c1/tristar-orion", &dtnode)) { + propName = "AAPL,ignore"; + if (dt_get_prop(dtnode, &propName, &propData, &propSize)) { + dt_remove_prop(dtnode, propName); + } + } + } + + hid_update_device_tree(); + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT diff --git a/target/ipad5c/pinconfig.c b/target/ipad5c/pinconfig.c new file mode 100644 index 0000000..56fc600 --- /dev/null +++ b/target/ipad5c/pinconfig.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include + +extern uint32_t ipad5c_get_board_rev(void); +extern const uint32_t* target_get_proto2_gpio_cfg(uint32_t gpioc); +extern const uint32_t* target_get_proto3_gpio_cfg(uint32_t gpioc); +extern const uint32_t* target_get_evt_gpio_cfg(uint32_t gpioc); +extern const uint32_t* target_get_evt2_gpio_cfg(uint32_t gpioc); + +extern bool check_is_board_deprecated; + +static bool board_rev_determined; +static bool use_dummy_pinconfig; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + // HACK: -- the first call into target_get_default_gpio_cfg() reads + // and attempts to restore BOARD_REV[3:0] to GPIO_CFG_DEFAULT. + // + // This will result in a recursive call back into target_get_default_gpio_cfg. + // To break the recursion, while determining board rev we can reply with any pinconfig + // since it's only being used for BOARD_REV[3:0] and it's CFG_DISABLED in all pinconfigs + // + // Remove this after we no longer have BOARD_REV-dependent pinconfigs. + if (use_dummy_pinconfig) + { + return target_get_evt_gpio_cfg(gpioc); + } + if (!board_rev_determined) + { + use_dummy_pinconfig = true; + (void)ipad5c_get_board_rev(); + use_dummy_pinconfig = false; + + board_rev_determined = true; + } + + if (!target_config_ap()) { + //For dev boards, just use the current settings for proto 1 until it changes + switch (ipad5c_get_board_rev()) { + case J98_DEV2_BOARD_REV: + return target_get_proto3_gpio_cfg(gpioc); + + default: + goto fail; + } + } else { + // Current AP products have several pinconfigs depending on board revision. + switch (ipad5c_get_board_rev()) { + case J99_PROTO2_BOARD_REV: + return target_get_proto2_gpio_cfg(gpioc); + + case J99_PROTO3_BOARD_REV: + case J99_PROTO3_P9_BOARD_REV: + return target_get_proto3_gpio_cfg(gpioc); + case J99_EVT_BOARD_REV: + return target_get_evt_gpio_cfg(gpioc); + case J99_EVT2_BOARD_REV: + return target_get_evt2_gpio_cfg(gpioc); + default: + goto fail; + } + } +fail: + //Allow more of the HW to get far enough to detect a deprecated board + check_is_board_deprecated = true; + + return target_get_evt_gpio_cfg(gpioc); +} diff --git a/target/ipad5c/pinconfig_evt.c b/target/ipad5c/pinconfig_evt.c new file mode 100644 index 0000000..eda2018 --- /dev/null +++ b/target/ipad5c/pinconfig_evt.c @@ -0,0 +1,989 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 3.5.0 + I/O Spreadsheet tracker: 19787800 + Conversion command: csvtopinconfig.py --soc capri --prefix evt --config-column 'j99:J99 Config' --config-column 'j98:J98 Config' --pupd-column 'j99:J99 PU/PD' --pupd-column 'j98:J98 PU/PD' --copyright 2013-2015 --radar 19787800 +*/ + +#include +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_evt_j98ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_DISABLED, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_evt_j98dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_DISABLED, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_evt_j99ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_FUNC0 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_evt_j99dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J98AP, ~0, { pinconfig_evt_j98ap_0 } }, + { TARGET_BOARD_ID_J98DEV, ~0, { pinconfig_evt_j98dev_0 } }, + { TARGET_BOARD_ID_J99AP, ~0, { pinconfig_evt_j99ap_0 } }, + { TARGET_BOARD_ID_J99DEV, ~0, { pinconfig_evt_j99dev_0 } }, +}; + +const uint32_t * target_get_evt_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipad5c/pinconfig_evt2.c b/target/ipad5c/pinconfig_evt2.c new file mode 100644 index 0000000..3e0600e --- /dev/null +++ b/target/ipad5c/pinconfig_evt2.c @@ -0,0 +1,989 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 4.3.0 + I/O Spreadsheet tracker: 19473089 + Conversion command: csvtopinconfig.py --soc capri --prefix evt2 --config-column 'j99:J99 Config' --config-column 'j98:J98 Config' --pupd-column 'j99:J99 PU/PD' --pupd-column 'j98:J98 PU/PD' --copyright 2015 --radar 19473089 +*/ + +#include +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_evt2_j98ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> ORIONMCU_SWDIO_1V8 + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 122 : UART8_TXD -> SOC2USBPDMCU_SWCLK + CFG_DISABLED, // 123 : UART8_RXD -> SOC2USBPDMCU_SWDIO + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> ORIONMCU_SWCLK_1V8 + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_evt2_j98dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> ORIONMCU_SWDIO_1V8 + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> SOC2USBPDMCU_SWCLK + CFG_DISABLED, // 123 : UART8_RXD -> SOC2USBPDMCU_SWDIO + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> ORIONMCU_SWCLK_1V8 + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_evt2_j99ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> ORIONMCU_SWDIO_1V8 + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 122 : UART8_TXD -> SOC2USBPDMCU_SWCLK + CFG_DISABLED, // 123 : UART8_RXD -> SOC2USBPDMCU_SWDIO + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> ORIONMCU_SWCLK_1V8 + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_evt2_j99dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_IN, // 54 : TMR32_PWM2 -> GPUUVD2SOC_OUT_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> ORIONMCU_SWDIO_1V8 + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2GPUUVD_EN + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> SOC2USBPDMCU_SWCLK + CFG_DISABLED, // 123 : UART8_RXD -> SOC2USBPDMCU_SWDIO + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 158 : CLK32K_OUT -> ORIONMCU_SWCLK_1V8 + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_IN, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J98AP, ~0, { pinconfig_evt2_j98ap_0 } }, + { TARGET_BOARD_ID_J98DEV, ~0, { pinconfig_evt2_j98dev_0 } }, + { TARGET_BOARD_ID_J99AP, ~0, { pinconfig_evt2_j99ap_0 } }, + { TARGET_BOARD_ID_J99DEV, ~0, { pinconfig_evt2_j99dev_0 } }, +}; + +const uint32_t * target_get_evt2_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipad5c/pinconfig_proto2.c b/target/ipad5c/pinconfig_proto2.c new file mode 100644 index 0000000..40854c6 --- /dev/null +++ b/target/ipad5c/pinconfig_proto2.c @@ -0,0 +1,989 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 1.14.0 + I/O Spreadsheet tracker: None + Conversion command: csvtopinconfig.py --soc capri --prefix proto2 --config-column 'j99:J99 Config' --config-column 'j98:J98 Config' --pupd-column 'j99:J99 PU/PD' --pupd-column 'j98:J98 PU/PD' --copyright 2013-2014 +*/ + +#include +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_proto2_j98ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED | PULL_DOWN, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_DISABLED, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN | PULL_DOWN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_proto2_j98dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED | PULL_DOWN, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_DISABLED, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN | PULL_DOWN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_proto2_j99ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_FUNC0 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN | PULL_DOWN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_proto2_j99dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_DISABLED, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN | PULL_DOWN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J98AP, ~0, { pinconfig_proto2_j98ap_0 } }, + { TARGET_BOARD_ID_J98DEV, ~0, { pinconfig_proto2_j98dev_0 } }, + { TARGET_BOARD_ID_J99AP, ~0, { pinconfig_proto2_j99ap_0 } }, + { TARGET_BOARD_ID_J99DEV, ~0, { pinconfig_proto2_j99dev_0 } }, +}; + +const uint32_t * target_get_proto2_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipad5c/pinconfig_proto3.c b/target/ipad5c/pinconfig_proto3.c new file mode 100644 index 0000000..00c2d39 --- /dev/null +++ b/target/ipad5c/pinconfig_proto3.c @@ -0,0 +1,989 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 2.1.0 + I/O Spreadsheet tracker: 17851336 + Conversion command: csvtopinconfig.py --soc capri --prefix proto3 --config-column 'j99:J99 Config' --config-column 'j98:J98 Config' --pupd-column 'j99:J99 PU/PD' --pupd-column 'j98:J98 PU/PD' --copyright 2013-2014 --radar 17851336 +*/ + +#include +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_proto3_j98ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED | PULL_DOWN, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_DISABLED, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_proto3_j98dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_DISABLED | PULL_DOWN, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_DISABLED | PULL_DOWN, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED | PULL_DOWN, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED | PULL_DOWN, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_DISABLED | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_DISABLED | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_DISABLED, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_proto3_j99ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_FUNC0 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +static const uint32_t pinconfig_proto3_j99dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // 0 : MENU_KEY_L -> GPIO_BTN_HOME_L + CFG_IN, // 1 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : ISP0_SDA -> ISP_CAM_REAR_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 3 : ISP0_SCL -> ISP_CAM_REAR_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 4 : ISP1_SDA -> ISP_CAM_FRONT_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 5 : ISP1_SCL -> ISP_CAM_FRONT_SCL + CFG_OUT_0 | SLOW_SLEW, // 6 : SENSOR0_RST -> ISP_CAM_REAR_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 7 : SENSOR0_CLK -> ISP_CAM_REAR_CLK_R + +/* Port 1 */ + CFG_IN | PULL_UP, // 8 : SENSOR0_XSHUTDOWN -> GPIO_SPKRAMP2SOC_CN_LEFT_IRQ_L + CFG_IN | PULL_UP, // 9 : SENSOR0_ISTRB -> GPIO_SPKRAMP2SOC_CN_RIGHT_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 10 : SENSOR1_RST -> ISP_CAM_FRONT_SHUTDOWN_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 11 : SENSOR1_CLK -> ISP_CAM_FRONT_CLK_R + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : SENSOR1_XSHUTDOWN -> GPIO_SOC2ROTTERDAM_EN + CFG_IN | PULL_DOWN | SLOW_SLEW, // 13 : SENSOR1_ISTRB -> GPIO_SOC2ROTTERDAM_DWLD_REQ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 14 : UART3_TXD -> UART_SOC2BB_TX + CFG_FUNC0, // 15 : UART3_RXD -> UART_BB2SOC_TX + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 32 : UART3_RTSN -> UART_SOC2BB_RTS_L + CFG_FUNC0, // 33 : UART3_CTSN -> UART_BB2SOC_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 34 : UART5_RTXD -> UART_BATT_HDQ + CFG_FUNC0 | SLOW_SLEW, // 35 : DWI0_DO -> DWI_SOC2PMU_DO + CFG_FUNC0 | SLOW_SLEW, // 36 : DWI0_CLK -> DWI_SOC2PMU_CLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | SLOW_SLEW, // 39 : I2S0_LRCK -> I2S_SOC2CODEC_ASP_LRCK + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : I2S0_BCLK -> I2S_SOC2CODEC_ASP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 41 : I2S0_DOUT -> I2S_SOC2CODEC_ASP_DOUT + CFG_FUNC0, // 42 : I2S0_DIN -> I2S_CODEC2SOC_ASP_DOUT + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 43 : I2S1_MCK -> SWD_KONA_CLK + CFG_FUNC0 | SLOW_SLEW, // 44 : I2S1_LRCK -> I2S_SOC2CODEC_XSP_LRCK + CFG_FUNC0 | SLOW_SLEW, // 45 : I2S1_BCLK -> I2S_SOC2CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW, // 46 : I2S1_DOUT -> I2S_SOC2CODEC_XSP_DOUT + CFG_FUNC0, // 47 : I2S1_DIN -> I2S_CODEC2SOC_XSP_DOUT + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW, // 48 : SPI3_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // 49 : SPI3_MISO -> SPI_CODEC_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 50 : SPI3_SCLK -> SPI_CODEC_SCLK_R + CFG_OUT_1 | SLOW_SLEW, // 51 : SPI3_SSIN -> SPI_CODEC_CS_L + CFG_OUT_0 | SLOW_SLEW, // 52 : TMR32_PWM0 -> OSCAR_BIDIR_TIME_SYNC_HOST_IRQ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 53 : TMR32_PWM1 -> GPIO_SOC2BT2GRAPE_TIMESTAMP_SYNC + CFG_DISABLED, // 54 : TMR32_PWM2 -> NC_JTAG_BB_TCK + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 55 : DISP_VSYNC -> DISPLAY_SYNC + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : WDOG -> WDOG_SOC + CFG_FUNC0, // 57 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | SLOW_SLEW, // 58 : SOCHOT1 -> SOCHOT1_L + CFG_DISABLED, // 59 : CPU_SLEEP_STATUS -> NC + CFG_DISABLED | SLOW_SLEW, // 60 : TST_CLKOUT -> SOC_TST_CLKOUT + CFG_IN | PULL_UP, // 61 : ISP_UART0_TXD -> GPIO_SPKRAMP2SOC_FH_RIGHT_IRQ_L + CFG_IN | PULL_UP, // 62 : ISP_UART0_RXD -> GPIO_SPKRAMP2SOC_FH_LEFT_IRQ_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 63 : UART7_TXD -> UART_SOC2OSCAR_TX + +/* Port 8 */ + CFG_FUNC0, // 64 : UART7_RXD -> UART_OSCAR2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 65 : I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : I2C1_SCL -> I2C1_SCL_1V8 + CFG_DISABLED, // 67 : SPI0_SCLK -> GPIO_BRD_ID0 + CFG_DISABLED, // 68 : SPI0_MOSI -> GPIO_BRD_ID1 + CFG_DISABLED, // 69 : SPI0_MISO -> GPIO_BRD_ID2 + CFG_IN, // 70 : SPI0_SSIN -> GPIO_TS2ORIONSOC2PMU_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 71 : I2S3_MCK -> I2S_SOC2SPKRAMP_FH_MCK_R + +/* Port 9 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 72 : I2S3_LRCK -> I2S_SOC2SPKRAMP_FH_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 73 : I2S3_BCLK -> I2S_SOC2SPKRAMP_FH_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 74 : I2S3_DOUT -> I2S_SOC2SPKRAMP_FH_DOUT + CFG_FUNC0, // 75 : I2S3_DIN -> I2S_SPKRAMP2SOC_FH_DOUT + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 76 : UART4_TXD -> UART_SOC2ROTTERDAM_TX + CFG_FUNC0, // 77 : UART4_RXD -> UART_ROTTERDAM2SOC_TX + CFG_IN | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 78 : UART4_RTSN -> UART_SOC2ROTTERDAM_RTS_L + CFG_FUNC0, // 79 : UART4_CTSN -> UART_ROTTERDAM2SOC_RTS_L + +/* Port 10 */ + CFG_OUT_0 | SLOW_SLEW, // 80 : GPIO[0] -> GPIO_SOC2TT_MUX_SEL + CFG_OUT_1 | SLOW_SLEW, // 81 : GPIO[1] -> GPIO_SOC2TT_XBAR_EN_PULSE_L + CFG_OUT_0 | SLOW_SLEW, // 82 : GPIO[2] -> GPIO_SOC2GRAPE_RESET_L + CFG_IN, // 83 : GPIO[3] -> GPIO_TS2SOC2PMU_IRQ + CFG_IN | PULL_UP, // 84 : GPIO[4] -> GPIO_GRAPE2SOC_IRQ_L + CFG_OUT_1 | SLOW_SLEW, // 85 : GPIO[5] -> GPIO_SOC2TT_XBAR_DIS_PULSE_L + CFG_IN | PULL_UP, // 86 : GPIO[6] -> GPIO_PMU2SOC_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 87 : GPIO[7] -> GPIO_SOC2PMU_KEEPACT + +/* Port 11 */ + CFG_IN, // 88 : GPIO[8] -> GPIO_GANGES2SOC2PMU_IRQ_L + CFG_DISABLED, // 89 : GPIO[9] -> GPIO_TT2SOC_WAKE_L + CFG_DISABLED, // 90 : GPIO[10] -> GPIO_SOC2CODEC_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 91 : GPIO[11] -> GPIO_BB_IPC + CFG_IN | PULL_UP, // 92 : GPIO[12] -> GPIO_BTN_VOL_UP_L + CFG_IN | PULL_UP, // 93 : GPIO[13] -> GPIO_BTN_VOL_DOWN_L + CFG_OUT_0 | SLOW_SLEW, // 94 : GPIO[14] -> GPIO_SOC2TT_SW_EN + CFG_OUT_0 | SLOW_SLEW, // 95 : GPIO[15] -> GPIO_SOC2GRAPE_EXT_SW_ON + +/* Port 12 */ + CFG_DISABLED, // 96 : GPIO[16] -> GPIO_BRD_ID3 + CFG_OUT_0 | SLOW_SLEW, // 97 : GPIO[17] -> GPIO_SOC2BB_COREDUMP + CFG_DISABLED, // 98 : GPIO[18] -> GPIO_BOOT_CFG0 + CFG_OUT_0 | SLOW_SLEW, // 99 : GPIO[19] -> GPIO_SOC2TT_LDO_EN + CFG_OUT_0 | SLOW_SLEW, // 100 : GPIO[20] -> GPIO_SOC2BB_WAKE_MODEM + CFG_OUT_0 | SLOW_SLEW, // 101 : GPIO[21] -> GPIO_SOC2SPKRAMP_KEEPALIVE + CFG_DISABLED, // 102 : GPIO[22] -> GPIO_BB2SOC_GPS_SYNC + CFG_IN | PULL_UP, // 103 : GPIO[23] -> GPIO_HP_ALS2SOC_IRQ_L + +/* Port 13 */ + CFG_IN | SLOW_SLEW, // 104 : GPIO[24] -> GPIO_SOC2BB_RADIO_ON_L + CFG_DISABLED, // 105 : GPIO[25] -> GPIO_BOOT_CFG1 + CFG_IN, // 106 : GPIO[26] -> GPIO_FORCE_DFU + CFG_DISABLED, // 107 : GPIO[27] -> TP_GPIO_DFU_STATUS + CFG_DISABLED, // 108 : GPIO[28] -> GPIO_BOOT_CFG2 + CFG_DISABLED, // 109 : GPIO[29] -> GPIO_TT2SOC_SMI_L + CFG_IN | PULL_UP, // 110 : GPIO[30] -> GPIO_RC_ALS2SOC_IRQ_L + CFG_DISABLED, // 111 : GPIO[31] -> GPIO_BOOT_CFG3 + +/* Port 14 */ + CFG_IN, // 112 : GPIO[32] -> GPIO_OSCAR2PMU_HOST_WAKE + CFG_IN | PULL_DOWN, // 113 : GPIO[33] -> HSIC_BB2SOC_DEVICE_RDY + CFG_OUT_0 | SLOW_SLEW, // 114 : GPIO[34] -> HSIC_SOC2BB_HOST_RDY + CFG_IN | PULL_DOWN, // 115 : GPIO[35] -> GPIO_BB2SOC_RESET_DET_L + CFG_IN | PULL_UP, // 116 : GPIO[36] -> GPIO_CODEC2SOC_IRQ_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[37] -> GPIO_SOC2BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 118 : SPI2_SCLK -> SPI_MESA_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 119 : SPI2_MOSI -> SPI_MESA_MOSI + +/* Port 15 */ + CFG_FUNC0, // 120 : SPI2_MISO -> SPI_MESA_MISO + CFG_IN | PULL_DOWN, // 121 : SPI2_SSIN -> GPIO_MESA2SOC_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 122 : UART8_TXD -> UART_SOC2USBPDMCU_TX + CFG_FUNC0, // 123 : UART8_RXD -> UART_USBPDMCU2SOC_TX + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 128 : UART0_TXD -> UART_SOC2DEBUG_TX + CFG_FUNC0, // 129 : UART0_RXD -> UART_DEBUG2SOC_TX + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 130 : UART6_TXD -> UART_SOC2ACC_TX + CFG_FUNC0, // 131 : UART6_RXD -> UART_ACC2SOC_TX + CFG_FUNC0 | SLOW_SLEW, // 132 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | SLOW_SLEW, // 133 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 134 : I2C3_SDA -> I2C3_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 135 : I2C3_SCL -> I2C3_SCL_1V8 + +/* Port 17 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 136 : UART2_TXD -> UART_SOC2WLAN_TX + CFG_FUNC0, // 137 : UART2_RXD -> UART_WLAN2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 138 : UART2_RTSN -> UART_SOC2WLAN_RTS_L + CFG_FUNC0, // 139 : UART2_CTSN -> UART_WLAN2SOC_RTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 140 : UART1_TXD -> UART_SOC2BT_TX + CFG_FUNC0, // 141 : UART1_RXD -> UART_BT2SOC_TX + CFG_OUT_1 | DRIVE_X2 | SLOW_SLEW, // 142 : UART1_RTSN -> UART_SOC2BT_RTS_L + CFG_FUNC0, // 143 : UART1_CTSN -> UART_BT2SOC_RTS_L + +/* Port 18 */ + CFG_FUNC0, // 144 : EDP_HPD -> EDP_HPD + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 145 : I2S4_MCK -> SWD_KONA_IO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 146 : I2S4_LRCK -> I2S_SOC2BT_LRCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 147 : I2S4_BCLK -> I2S_SOC2BT_BCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 148 : I2S4_DOUT -> I2S_SOC2BT_DOUT + CFG_FUNC0, // 149 : I2S4_DIN -> I2S_BT2SOC_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 150 : I2S2_LRCK -> I2S_SOC2SPKRAMP_CN_LRCK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 151 : I2S2_BCLK -> I2S_SOC2SPKRAMP_CN_BCLK + +/* Port 19 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 152 : I2S2_DOUT -> I2S_SOC2SPKRAMP_CN_DOUT + CFG_FUNC0, // 153 : I2S2_DIN -> I2S_SPKRAMP2SOC_CN_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 154 : SPI1_SCLK -> SPI_GRAPE_SCLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 155 : SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // 156 : SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SLOW_SLEW, // 157 : SPI1_SSIN -> SPI_GRAPE_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 158 : CLK32K_OUT -> CLK_SOC2GRAPE_24M + CFG_DISABLED, // 159 : ULPI_DIR -> GPIO_BRD_REV1 + +/* Port 20 */ + CFG_OUT_0, // 160 : ULPI_STP -> SOC2USBPDMCU_RESET_L + CFG_DISABLED, // 161 : ULPI_NXT -> GPIO_BRD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 162 : ULPI_DATA[7] -> GPIO_SOC2AJ_HS3_SHUNT_EN + CFG_DISABLED, // 163 : ULPI_DATA[6] -> GPIO_BRD_REV3 + CFG_OUT_0 | SLOW_SLEW, // 164 : ULPI_DATA[5] -> GPIO_SOC2BT_WAKE + CFG_OUT_0 | SLOW_SLEW, // 165 : ULPI_DATA[4] -> GPIO_SOC2WLAN_WAKE + CFG_OUT_0 | SLOW_SLEW, // 166 : ULPI_CLK -> GPIO_SOC2AJ_HS4_SHUNT_EN + CFG_IN, // 167 : ULPI_DATA[3] -> USBPDMCU2SOC_IRQ + +/* Port 21 */ + CFG_DISABLED, // 168 : ULPI_DATA[2] -> GPIO_BRD_REV2 + CFG_DISABLED, // 169 : ULPI_DATA[1] -> SWD_OSCAR_IO_1V8 + CFG_DISABLED, // 170 : ULPI_DATA[0] -> SWD_OSCAR_CLK_1V8 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 171 : DWI1_DO -> DWI_SOC2BEACON_DO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 172 : DWI1_CLK -> DWI_SOC2BEACON_CLK + CFG_DISABLED | INPUT_SCHMITT, // 173 : PCIE_CLKREQ0_N -> PCIE_TT2SOC_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 174 : PCIE_CLKREQ1_N -> PCIE_WLAN2SOC_CLKREQ_L + CFG_DISABLED | INPUT_SCHMITT, // 175 : PCIE_CLKREQ2_N -> NC_PCIE_DEVBRD2SOC_CLKREQ_L + +/* Port 22 */ + CFG_DISABLED | INPUT_SCHMITT, // 176 : PCIE_CLKREQ3_N -> GPIO_TT2SOC_PWR_SW_OC + CFG_DISABLED, // 177 : NAND_SYS_CLK -> NC + CFG_OUT_0 | SLOW_SLEW, // 178 : PCIE_PERST0_N -> PCIE_SOC2TT_RESET_L + CFG_IN | SLOW_SLEW, // 179 : PCIE_PERST1_N -> PCIE_SOC2WLAN_RESET_L + CFG_DISABLED, // 180 : PCIE_PERST2_N -> NC_PCIE_SOC2DEVBRD_RESET_L + CFG_DISABLED, // 181 : PCIE_PERST3_N -> GPIO_DEVDOG_DETECT + CFG_FUNC0 | SLOW_SLEW, // 182 : I2S0_MCK -> I2S_SOC2CODEC_ASP_MCK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 183 : I2S2_MCK -> I2S_SOC2SPKRAMP_CN_MCK_R +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J98AP, ~0, { pinconfig_proto3_j98ap_0 } }, + { TARGET_BOARD_ID_J98DEV, ~0, { pinconfig_proto3_j98dev_0 } }, + { TARGET_BOARD_ID_J99AP, ~0, { pinconfig_proto3_j99ap_0 } }, + { TARGET_BOARD_ID_J99DEV, ~0, { pinconfig_proto3_j99dev_0 } }, +}; + +const uint32_t * target_get_proto3_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipad5c/properties.c b/target/ipad5c/properties.c new file mode 100644 index 0000000..1ac9897 --- /dev/null +++ b/target/ipad5c/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipad5c/rules.mk b/target/ipad5c/rules.mk new file mode 100644 index 0000000..3942f62 --- /dev/null +++ b/target/ipad5c/rules.mk @@ -0,0 +1,56 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +# BUCK_CPU, BUCK_GPU and BUCK_RAM should be reviewed +# if any changed happen in drivers/dialog/pmu/power.c:power_get_buck_value() + +OPTIONS += \ + DIALOG_D2207=1 \ + DIALOG_D2231=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_VID0_CLK_CFG=0x89100000 \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + TARGET_DDR_798M=1 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + TARGET_DITHER_TYPE=DITHER_BLUE_NOISE \ + PMU_LCD_PWR_EN=1 \ + AMC_NUM_CHANNELS=4 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_GPU=2 \ + BUCK_RAM=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart2/wlan\" \ + DP_DTPATH=\"arm-io/displayport\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o \ + $(LOCAL_DIR)/pinconfig_proto2.o \ + $(LOCAL_DIR)/pinconfig_proto3.o \ + $(LOCAL_DIR)/pinconfig_evt.o \ + $(LOCAL_DIR)/pinconfig_evt2.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/ipad6b/include/target/adbe_settings.h b/target/ipad6b/include/target/adbe_settings.h new file mode 100644 index 0000000..92212a1 --- /dev/null +++ b/target/ipad6b/include/target/adbe_settings.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "ipad6b", + .adbe0_vftgctl_idle_frame_vblank_enable = 1, + .adbe0_vblank_pos_vbi_pulse = 0x012d, + .adbe0_vblank_clk_gate_wakeup = 0x0007, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | + AAP_FORMAT_CONTROL_REG1_FCMODE(2) | + AAP_FORMAT_CONTROL_REG1_RSVD(0) | + AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/ipad6b/include/target/boardid.h b/target/ipad6b/include/target/boardid.h new file mode 100644 index 0000000..5e355fc --- /dev/null +++ b/target/ipad6b/include/target/boardid.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TARGET_BOARDID_H +#define TARGET_BOARDID_H + +// Board ids +#define TARGET_BOARD_ID_J127AP (0x8) +#define TARGET_BOARD_ID_J127DEV (0x9) + +#define TARGET_BOARD_ID_J128AP (0xA) +#define TARGET_BOARD_ID_J128DEV (0xB) + +// Board revs - for info purposes +/* +J127_DEV1_BOARD_REV (0x0) // DEPRECIATED +J127_DEV2_BOARD_REV (0x4) + +J127_PROTO0_BOARD_REV (0x0) // DEPRECIATED +J127_PROTO0_A_BOARD_REV (0x1) // DEPRECIATED +J127_PROTO0_B_BOARD_REV (0x2) // DEPRECIATED +J127_PROTO1_BOARD_REV (0x3) // DEPRECIATED +J127_PRE_PROTO2_BOARD_REV (0x4) // DEPRECIATED +J127_PROTO2_MOHAVE_A1_BOARD_REV (0x5) +J127_PROTO2_MOHAVE_A0_POR_BOARD_REV (0x6) +*/ + +#endif diff --git a/target/ipad6b/include/target/dcsfixup.h b/target/ipad6b/include/target/dcsfixup.h new file mode 100644 index 0000000..4acb766 --- /dev/null +++ b/target/ipad6b/include/target/dcsfixup.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static inline +void dcs_init_config_fixup_params(dcs_config_params_t *dcs_params, dcs_target_t targtype) +{ + dcs_params->chnldec = 0x00050110; +}; diff --git a/target/ipad6b/include/target/display_gamma_tables.h b/target/ipad6b/include/target/display_gamma_tables.h new file mode 100644 index 0000000..8bae983 --- /dev/null +++ b/target/ipad6b/include/target/display_gamma_tables.h @@ -0,0 +1,604 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_DISPLAY_GAMMA_TABLES_H +#define __TARGET_DISPLAY_GAMMA_TABLES_H + +/* display gamma tables */ + +#define ADP_CM_DEGAMMA_PAIRED_LUT_COUNT 65 +#define ADP_CM_DEGAMMA_PAIRED_LUT_SIZE (ADP_CM_DEGAMMA_PAIRED_LUT_COUNT - 1) +static const uint32_t target_blend_degamma_tables[ADP_CM_DEGAMMA_PAIRED_LUT_COUNT] = { + 0x00050000, + 0x000F000A, + 0x00190014, + 0x0024001E, + 0x0031002A, + 0x00410039, + 0x0054004A, + 0x006A005F, + 0x00820076, + 0x009E0090, + 0x00BD00AD, + 0x00DF00CD, + 0x010400F1, + 0x012C0118, + 0x01590142, + 0x01880170, + 0x01BC01A2, + 0x01F301D7, + 0x022E0210, + 0x026C024C, + 0x02AF028D, + 0x02F602D2, + 0x0340031A, + 0x038F0367, + 0x03E203B8, + 0x043A040D, + 0x04950467, + 0x04F504C5, + 0x055A0527, + 0x05C3058E, + 0x063005F9, + 0x06A20669, + 0x071906DD, + 0x07940756, + 0x081407D4, + 0x08990856, + 0x092308DE, + 0x09B2096A, + 0x0A4609FB, + 0x0ADF0A92, + 0x0B7C0B2D, + 0x0C1F0BCD, + 0x0CC70C73, + 0x0D740D1D, + 0x0E270DCD, + 0x0EDF0E82, + 0x0F9C0F3C, + 0x105E0FFC, + 0x112610C1, + 0x11F3118C, + 0x12C6125C, + 0x139E1331, + 0x147C140D, + 0x156014ED, + 0x164915D4, + 0x173816C0, + 0x182C17B1, + 0x192718A9, + 0x1A2719A6, + 0x1B2D1AA9, + 0x1C391BB2, + 0x1D4B1CC1, + 0x1E621DD6, + 0x1F801EF0, + 0x29F42011, +}; + +#define ADP_CM_ENGAMMA_PAIRED_LUT_COUNT 513 +#define ADP_CM_ENGAMMA_PAIRED_LUT_SIZE (ADP_CM_ENGAMMA_PAIRED_LUT_COUNT - 1) +static const uint32_t target_blend_engamma_tables[ADP_CM_ENGAMMA_PAIRED_LUT_COUNT] = { + 0x000D0000, + 0x0026001A, + 0x003D0033, + 0x004F0047, + 0x005E0057, + 0x006B0065, + 0x00770071, + 0x0081007C, + 0x008B0087, + 0x00950090, + 0x009D0099, + 0x00A500A2, + 0x00AD00AA, + 0x00B500B1, + 0x00BC00B8, + 0x00C300C0, + 0x00CA00C6, + 0x00D000CD, + 0x00D600D3, + 0x00DC00D9, + 0x00E200DF, + 0x00E800E5, + 0x00ED00EB, + 0x00F300F0, + 0x00F800F5, + 0x00FD00FA, + 0x01020100, + 0x01070104, + 0x010C0109, + 0x0110010E, + 0x01150113, + 0x01190117, + 0x011E011C, + 0x01220120, + 0x01270124, + 0x012B0129, + 0x012F012D, + 0x01330131, + 0x01370135, + 0x013B0139, + 0x013F013D, + 0x01430141, + 0x01460144, + 0x014A0148, + 0x014E014C, + 0x01510150, + 0x01550153, + 0x01590157, + 0x015C015A, + 0x015F015E, + 0x01630161, + 0x01660165, + 0x016A0168, + 0x016D016B, + 0x0170016F, + 0x01730172, + 0x01770175, + 0x017A0178, + 0x017D017B, + 0x0180017E, + 0x01830181, + 0x01860185, + 0x01890188, + 0x018C018B, + 0x018F018E, + 0x01920190, + 0x01950193, + 0x01980196, + 0x019B0199, + 0x019D019C, + 0x01A0019F, + 0x01A301A2, + 0x01A601A4, + 0x01A801A7, + 0x01AB01AA, + 0x01AE01AD, + 0x01B101AF, + 0x01B301B2, + 0x01B601B5, + 0x01B801B7, + 0x01BB01BA, + 0x01BE01BC, + 0x01C001BF, + 0x01C301C1, + 0x01C501C4, + 0x01C801C6, + 0x01CA01C9, + 0x01CD01CB, + 0x01CF01CE, + 0x01D201D0, + 0x01D401D3, + 0x01D601D5, + 0x01D901D8, + 0x01DB01DA, + 0x01DE01DC, + 0x01E001DF, + 0x01E201E1, + 0x01E501E3, + 0x01E701E6, + 0x01E901E8, + 0x01EB01EA, + 0x01EE01ED, + 0x01F001EF, + 0x01F201F1, + 0x01F401F3, + 0x01F701F5, + 0x01F901F8, + 0x01FB01FA, + 0x01FD01FC, + 0x01FF01FE, + 0x02010200, + 0x02040203, + 0x02060205, + 0x02080207, + 0x020A0209, + 0x020C020B, + 0x020E020D, + 0x0210020F, + 0x02120211, + 0x02140213, + 0x02160215, + 0x02180217, + 0x021A0219, + 0x021D021C, + 0x021E021E, + 0x02210220, + 0x02220222, + 0x02240224, + 0x02260225, + 0x02280227, + 0x022A0229, + 0x022C022B, + 0x022E022D, + 0x0230022F, + 0x02320231, + 0x02340233, + 0x02360235, + 0x02380237, + 0x023A0239, + 0x023C023B, + 0x023D023D, + 0x023F023E, + 0x02410240, + 0x02430242, + 0x02450244, + 0x02470246, + 0x02490248, + 0x024A0249, + 0x024C024B, + 0x024E024D, + 0x0250024F, + 0x02520251, + 0x02530252, + 0x02550254, + 0x02570256, + 0x02590258, + 0x025A025A, + 0x025C025B, + 0x025E025D, + 0x0260025F, + 0x02610261, + 0x02630262, + 0x02650264, + 0x02670266, + 0x02680267, + 0x026A0269, + 0x026C026B, + 0x026D026C, + 0x026F026E, + 0x02710270, + 0x02720272, + 0x02740273, + 0x02760275, + 0x02770276, + 0x02790278, + 0x027B027A, + 0x027C027B, + 0x027E027D, + 0x0280027F, + 0x02810280, + 0x02830282, + 0x02840284, + 0x02860285, + 0x02880287, + 0x02890288, + 0x028B028A, + 0x028C028C, + 0x028E028D, + 0x028F028F, + 0x02910290, + 0x02930292, + 0x02940293, + 0x02960295, + 0x02970297, + 0x02990298, + 0x029A029A, + 0x029C029B, + 0x029D029D, + 0x029F029E, + 0x02A102A0, + 0x02A202A1, + 0x02A402A3, + 0x02A502A4, + 0x02A702A6, + 0x02A802A7, + 0x02AA02A9, + 0x02AB02AA, + 0x02AD02AC, + 0x02AE02AD, + 0x02B002AF, + 0x02B102B0, + 0x02B202B2, + 0x02B402B3, + 0x02B502B5, + 0x02B702B6, + 0x02B802B8, + 0x02BA02B9, + 0x02BB02BB, + 0x02BD02BC, + 0x02BE02BD, + 0x02C002BF, + 0x02C102C0, + 0x02C202C2, + 0x02C402C3, + 0x02C502C5, + 0x02C702C6, + 0x02C802C7, + 0x02CA02C9, + 0x02CB02CA, + 0x02CC02CC, + 0x02CE02CD, + 0x02CF02CE, + 0x02D102D0, + 0x02D202D1, + 0x02D302D3, + 0x02D502D4, + 0x02D602D5, + 0x02D702D7, + 0x02D902D8, + 0x02DA02D9, + 0x02DC02DB, + 0x02DD02DC, + 0x02DE02DE, + 0x02E002DF, + 0x02E102E0, + 0x02E202E2, + 0x02E402E3, + 0x02E502E4, + 0x02E602E6, + 0x02E802E7, + 0x02E902E8, + 0x02EA02EA, + 0x02EC02EB, + 0x02ED02EC, + 0x02EE02EE, + 0x02F002EF, + 0x02F102F0, + 0x02F202F2, + 0x02F402F3, + 0x02F502F4, + 0x02F602F6, + 0x02F802F7, + 0x02F902F8, + 0x02FA02F9, + 0x02FB02FB, + 0x02FD02FC, + 0x02FE02FD, + 0x02FF02FF, + 0x03010300, + 0x03020301, + 0x03030302, + 0x03040304, + 0x03060305, + 0x03070306, + 0x03080308, + 0x03090309, + 0x030B030A, + 0x030C030B, + 0x030D030D, + 0x030E030E, + 0x0310030F, + 0x03110310, + 0x03120312, + 0x03130313, + 0x03150314, + 0x03160315, + 0x03170317, + 0x03180318, + 0x031A0319, + 0x031B031A, + 0x031C031B, + 0x031D031D, + 0x031E031E, + 0x0320031F, + 0x03210320, + 0x03220322, + 0x03230323, + 0x03250324, + 0x03260325, + 0x03270326, + 0x03280328, + 0x03290329, + 0x032B032A, + 0x032C032B, + 0x032D032C, + 0x032E032E, + 0x032F032F, + 0x03300330, + 0x03320331, + 0x03330332, + 0x03340333, + 0x03350335, + 0x03360336, + 0x03380337, + 0x03390338, + 0x033A0339, + 0x033B033A, + 0x033C033C, + 0x033D033D, + 0x033F033E, + 0x0340033F, + 0x03410340, + 0x03420341, + 0x03430343, + 0x03440344, + 0x03450345, + 0x03470346, + 0x03480347, + 0x03490348, + 0x034A0349, + 0x034B034B, + 0x034C034C, + 0x034D034D, + 0x034F034E, + 0x0350034F, + 0x03510350, + 0x03520351, + 0x03530352, + 0x03540354, + 0x03550355, + 0x03560356, + 0x03570357, + 0x03590358, + 0x035A0359, + 0x035B035A, + 0x035C035B, + 0x035D035C, + 0x035E035E, + 0x035F035F, + 0x03600360, + 0x03610361, + 0x03620362, + 0x03640363, + 0x03650364, + 0x03660365, + 0x03670366, + 0x03680367, + 0x03690368, + 0x036A036A, + 0x036B036B, + 0x036C036C, + 0x036D036D, + 0x036E036E, + 0x036F036F, + 0x03710370, + 0x03720371, + 0x03730372, + 0x03740373, + 0x03750374, + 0x03760375, + 0x03770376, + 0x03780377, + 0x03790379, + 0x037A037A, + 0x037B037B, + 0x037C037C, + 0x037D037D, + 0x037E037E, + 0x037F037F, + 0x03800380, + 0x03810381, + 0x03830382, + 0x03840383, + 0x03850384, + 0x03860385, + 0x03870386, + 0x03880387, + 0x03890388, + 0x038A0389, + 0x038B038A, + 0x038C038B, + 0x038D038C, + 0x038E038D, + 0x038F038E, + 0x0390038F, + 0x03910390, + 0x03920391, + 0x03930393, + 0x03940394, + 0x03950395, + 0x03960396, + 0x03970397, + 0x03980398, + 0x03990399, + 0x039A039A, + 0x039B039B, + 0x039C039C, + 0x039D039D, + 0x039E039E, + 0x039F039F, + 0x03A003A0, + 0x03A103A1, + 0x03A203A2, + 0x03A303A3, + 0x03A403A4, + 0x03A503A5, + 0x03A603A6, + 0x03A703A7, + 0x03A803A8, + 0x03A903A9, + 0x03AA03AA, + 0x03AB03AB, + 0x03AC03AC, + 0x03AD03AD, + 0x03AE03AD, + 0x03AF03AE, + 0x03B003AF, + 0x03B103B0, + 0x03B203B1, + 0x03B303B2, + 0x03B403B3, + 0x03B503B4, + 0x03B603B5, + 0x03B703B6, + 0x03B803B7, + 0x03B903B8, + 0x03BA03B9, + 0x03BB03BA, + 0x03BC03BB, + 0x03BD03BC, + 0x03BD03BD, + 0x03BE03BE, + 0x03BF03BF, + 0x03C003C0, + 0x03C103C1, + 0x03C203C2, + 0x03C303C3, + 0x03C403C4, + 0x03C503C5, + 0x03C603C6, + 0x03C703C7, + 0x03C803C7, + 0x03C903C8, + 0x03CA03C9, + 0x03CB03CA, + 0x03CC03CB, + 0x03CD03CC, + 0x03CE03CD, + 0x03CF03CE, + 0x03CF03CF, + 0x03D003D0, + 0x03D103D1, + 0x03D203D2, + 0x03D303D3, + 0x03D403D4, + 0x03D503D5, + 0x03D603D6, + 0x03D703D6, + 0x03D803D7, + 0x03D903D8, + 0x03DA03D9, + 0x03DB03DA, + 0x03DC03DB, + 0x03DC03DC, + 0x03DD03DD, + 0x03DE03DE, + 0x03DF03DF, + 0x03E003E0, + 0x03E103E1, + 0x03E203E2, + 0x03E303E2, + 0x03E403E3, + 0x03E503E4, + 0x03E603E5, + 0x03E703E6, + 0x03E703E7, + 0x03E803E8, + 0x03E903E9, + 0x03EA03EA, + 0x03EB03EB, + 0x03EC03EB, + 0x03ED03EC, + 0x03EE03ED, + 0x03EF03EE, + 0x03F003EF, + 0x03F003F0, + 0x03F103F1, + 0x03F203F2, + 0x03F303F3, + 0x03F403F4, + 0x03F503F4, + 0x03F603F5, + 0x03F703F6, + 0x03F803F7, + 0x03F803F8, + 0x03F903F9, + 0x03FA03FA, + 0x03FB03FB, + 0x03FC03FC, + 0x03FD03FC, + 0x03FE03FD, + 0x03FF03FE, + 0x043503FF +}; + +#endif diff --git a/target/ipad6b/include/target/gpiodef.h b/target/ipad6b/include/target/gpiodef.h new file mode 100644 index 0000000..e2a327d --- /dev/null +++ b/target/ipad6b/include/target/gpiodef.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* ipad6,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 4) // 116 : GPIO[44] +#define GPIO_BOARD_REV1 GPIO(14, 5) // 117 : GPIO[45] +#define GPIO_BOARD_REV2 GPIO(14, 6) // 118 : GPIO[46] +#define GPIO_BOARD_REV3 GPIO(15, 1) // 121 : GPIO[49] + +/* Miscellaneous Pins */ +#define GPIO_DISPLAY_HPD GPIO(24, 2) // 194: EPD_HPD0 -> LPDP_TCON_TO_SOC_HPD + +#define GPIO_S3E_BOOT_FROM_HOST GPIO_ID(76) // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + +#define GPIO_TOUCH_SENSOR_ID GPIO(10, 5) // 85 : GPIO[11] -> TOUCH_SENSOR_ID0 + +/* which IICs to initialize */ +#define IICS_MASK (0xF) + +#define TRISTAR_IIC_BUS (0) +#define BACKLIGHT_IIC_BUS (0) +#define DISPLAY_PMU_IIC_BUS (0) + +#define GPIO_PMU_LCD_PWR_EN (17) // PMU GPIO 18 - GPIO_PMU_TO_LCD_PWREN +#define GPIO_PMU_NAND_LOW_POWER_MODE (15) // PMU GPIO 16 - GPIO_PMU_TO_NAND_LOW_BATT_L + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad6b/include/target/lpdp_settings.h b/target/ipad6b/include/target/lpdp_settings.h new file mode 100644 index 0000000..70231bf --- /dev/null +++ b/target/ipad6b/include/target/lpdp_settings.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef LPDP_SETTINGS_H +#define LPDP_SETTINGS_H + +static struct lpdp_port_calibration lpdp_port_calibration_table[1][1] = { + { {LPDP_PHY_LANE_VREG_ADJ_450_mV, 0}, }, +}; + +#define LPDP_PORT_CALIBRATION_TABLE_FIXED (true) + +#endif diff --git a/target/ipad6b/include/target/powerconfig.h b/target/ipad6b/include/target/powerconfig.h new file mode 100644 index 0000000..7616d8b --- /dev/null +++ b/target/ipad6b/include/target/powerconfig.h @@ -0,0 +1,256 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +// Configuration per target + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 0 + + +// This configuration is very PMU specific and must be included exactly +// once in power.c +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2257_EN_CMD0, (1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0) }, + { PMU_IIC_BUS, kD2257_EN_CMD1, (1<<0) }, // buck8 + { PMU_IIC_BUS, kD2257_EN_CMD2, 1 }, // enable WLED SPI access + { PMU_IIC_BUS, kD2257_SPI_CTRL, 1 } // enable SPI access +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// IO_CONFIG[7:6] 0=I 1=O_OD 2=O_PP 3=SS +// IO_TYPE[5:3] O 0=L 1=32K 2=nR 3=TI 4=L +// PUPD[2:1] O 0=NP 1=PU 2=NP 3=<0> +// WAKE_LVL[0] O 0=low 1=high +// IO_TYPE[5:3] I 0=L_AH 1=L_AL 2=RE 3=FE 4=AE +// PUPD[2:1] I 0=NP 1=PU 2=PD_GND 3=<0> +// WAKE_LVL[0] I 0=NW 1=W +// +// J127 GPIO Spreadsheet (master) +// J127_IO_spreadsheet_v26 (EVT).xlsx +static const struct pmu_setup_struct pmu_cold_init[] = +{ + // TODO :This is a Bringup Hack, remove + { PMU_IIC_BUS, kD2257_BUCK0_VSEL, 0xc0 }, // CPU rail + { PMU_IIC_BUS, kD2257_BUCK1_VSEL, 0xc0 }, // GPU rail + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK1_EN, 0xf }, // GPU power rail (see ) + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK8_EN, 0xf }, // GPU RAM power rail (see ) + // TODO :This is a Bringup Hack, remove + + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK3_SW2_EN, 0xf}, // J99A/J127: Keep DVDD power rail on to avoid speaker pops (work around HW issue) + { PMU_IIC_BUS, kD2257_PWRONOFF_LDO4_EN, 0x1 }, // Enable PP3V0_ALS + { PMU_IIC_BUS, kD2257_PWRONOFF_LDO7_EN, 0x1 }, // Enable PP3V3_USB_SOC + + { PMU_IIC_BUS, kD2257_LDO2_BYPASS, 0x1}, // bypass when Active rdar://19773152 + + // Drive GPIO_PMU_TO_1V1_EXT_SW_ON (PMU GPIO 20) to enable PP1V1_S1_EXT_SW + // which inturn is SNSI_PP1V1_S1_DDR_VDDQ_x. + // + // Should be ON by default via OTP. + + // Drive GPIO_PMU_TO_1V8_EXT_SW2_ON (PMU GPIO 21) to enable PP1V8_S2_EXT_SW2 + // which inturn is PP1V8_S2_IO_EXPANDER. + // + // Should be ON by default via OTP. + + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA }, // Enable Test Mode + { PMU_IIC_BUS, kD2257_EN_CMD3, 0}, // Enable SPI access for BUCKx (x=3) + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS }, // Disable Test Mode + + // GPIO1: GPIO_AJ_HALL_TO_PMU_IRQ_L + { PMU_IIC_BUS, kD2257_GPIO1_CONF1, (0<<6)|(4<<3)|(1<<1)|(1<<0) }, // 0x23 Input, AnyE, PU, WakeUp + { PMU_IIC_BUS, kD2257_GPIO1_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO2: GPIO_ACC_TO_PMU_PWR_SW_OC_L + { PMU_IIC_BUS, kD2257_GPIO2_CONF1, (0<<6)|(3<<3)|(0<<1)|(0<<0) }, // 0x18 Input, AnyE, No PU/PD + { PMU_IIC_BUS, kD2257_GPIO2_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO3: GPIO_ORION_TO_SOC_TO_PMU_IRQ + { PMU_IIC_BUS, kD2257_GPIO3_CONF1, (0<<6)|(0<<3)|(2<<1)|(1<<0) }, // 0x25 Input, AH, PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO3_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO4: GPIO_PMU_TO_ACC_PWR_SW (was GPIO_PMU_TO_ACC_PWR_SEL) + { PMU_IIC_BUS, kD2257_GPIO4_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO4_CONF2, (0<<3)|(0<<0) }, // 0x00 VCC_MAIN, no DEB + + // GPIO6: UART_BATT_HDQ + { PMU_IIC_BUS, kD2257_GPIO6_CONF1, (0<<6)|(3<<3)|(0<<1)|(1<<0) }, // 0x19 Input, FE, No PU/PD + { PMU_IIC_BUS, kD2257_GPIO6_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO7: GPIO_BT_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2257_GPIO7_CONF1, (0<<6)|(2<<3)|(0<<1)|(1<<0) }, // 0x11 Input, RE, No PU/PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO7_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO8: GPIO_WLAN_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2257_GPIO8_CONF1, (0<<6)|(2<<3)|(2<<1)|(1<<0) }, // 0x15 Input, RE, PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO8_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO10: GPIO_CODEC_TO_PMU_WAKE_L + { PMU_IIC_BUS, kD2257_GPIO10_CONF1, (0<<6)|(4<<3)|(1<<1)|(1<<0) }, // 0x23 Input, AnyE, PU, Wakeup + { PMU_IIC_BUS, kD2257_GPIO10_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO11: GPIO_STB_HALL_TO_PMU_IRQ_L + { PMU_IIC_BUS, kD2257_GPIO11_CONF1, (0<<6)|(4<<3)|(1<<1)|(1<<0) }, // 0x23 Input, AnyE, PU, WakeUp + { PMU_IIC_BUS, kD2257_GPIO11_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO12: GPIO_TS_TO_SOC_TO_PMU_IRQ + { PMU_IIC_BUS, kD2257_GPIO12_CONF1, (0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input, AH, No PU/PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO12_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO13: GPIO_BELFIELD_TO_PMU_WAKE_L (was GPIO_IO_EXP_TO_PMU_IRQ) + { PMU_IIC_BUS, kD2257_GPIO13_CONF1, (0<<6)|(4<<3)|(1<<1)|(1<<0) }, // 0x23 Input, AnyE, PU, WakeUp + { PMU_IIC_BUS, kD2257_GPIO13_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO14: GPIO_EUPHRATES_TO_PMU_WAKE (was PCIE_WLAN_TO_PMU_WAKE_L) + { PMU_IIC_BUS, kD2257_GPIO14_CONF1, (0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input, AH, No PU/PD, WakeUp + { PMU_IIC_BUS, kD2257_GPIO14_CONF2, (3<<3)|(1<<0) }, // 0x19 PP1V8_ALWAYS, 5ms + + // GPIO15: GPIO_EUPHRATES_TO_SOC_TO_PMU_IRQ_L (was GPIO_PMU_TO_CODEC_RESET_L) + { PMU_IIC_BUS, kD2257_GPIO15_CONF1, (0<<6)|(3<<3)|(1<<1)|(1<<0) }, // 0x1B Input, FE, PU, WakeUp + { PMU_IIC_BUS, kD2257_GPIO15_CONF2, (3<<3)|(2<<0) }, // 0x1A PP1V8_ALWAYS, 10ms + + // GPIO16: GPIO_PMU_TO_NAND_LOW_BATT_L + // kD2257_GPIO16_CONF1 gets set in target_late_init() + { PMU_IIC_BUS, kD2257_GPIO16_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO18: Enable GPIO_PMU_TO_LCD_PWREN + { PMU_IIC_BUS, kD2257_GPIO18_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO18_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO9: GPIO_BB_TO_PMU_HOST_WAKE_L + { PMU_IIC_BUS, kD2257_GPIO9_CONF1, (0<<6)|(1<<3)|(2<<1)|(0<<0) }, // 0x0C Input, AL, PD + { PMU_IIC_BUS, kD2257_GPIO9_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + +#if TARGET_HAS_BASEBAND + // GPIO5: GPIO_PMU_TO_BBPMU_RESET_R_L (rdar://20064772, rdar://20110706, rdar://21211826) + { PMU_IIC_BUS, kD2257_GPIO5_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, no PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO5_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO17: GPIO_PMU_TO_BB_VBUS_DET + { PMU_IIC_BUS, kD2257_GPIO17_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO17_CONF2, (0<<3)|(0<<0) }, // 0x00 VCC_MAIN, no DEB +#else + // GPIO5: GPIO_PMU_TO_BBPMU_RESET_R_L + { PMU_IIC_BUS, kD2257_GPIO5_CONF1, (0<<6)|(0<<3)|(2<<1)|(0<<0) }, // 0x40 Input, AH, PD + { PMU_IIC_BUS, kD2257_GPIO5_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO17: GPIO_PMU_TO_BB_VBUS_DET + { PMU_IIC_BUS, kD2257_GPIO17_CONF1, (0<<6)|(0<<3)|(2<<1)|(0<<0) }, // 0x40 Input, AH, PD + { PMU_IIC_BUS, kD2257_GPIO17_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB +#endif + + // GPIO19: GPIO_PMU_TO_EUPHRATES_LINCH_EN (was GPIO_GANGES_TO_PMU_WAKE) + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_SLP1,(1<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x41 Output(Open Drain), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_SLP2,(1<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x41 Output(Open Drain), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_SLP3,(1<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x41 Output(Open Drain), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_OFF, (1<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x40 Output(Open Drain), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO19_CONF1, (1<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x41 Output(Open Drain), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO19_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO20: GPIO_PMU_TO_1V1_EXT_SW_ON + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_SLP1,(2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_SLP2,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_SLP3,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_OFF, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO20_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO20_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO21: GPIO_PMU_TO_1V8_EXT_SW2_ON + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_SLP1,(2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_SLP2,(2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_SLP3,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_OFF, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO21_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO21_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO22: GPIO_PMU_TO_3V3_EXT_SW_ON (was GPIO_GANGES_TO_SOC_TO_PMU_IRQ_L) + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_SLP1,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_SLP2,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_SLP3,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_OFF, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU/PD, High + { PMU_IIC_BUS, kD2257_GPIO22_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0x06 }, // 75% of max 0x7FF + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kD2257_WLED_CTRL1, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kD2257_WLED_CTRL2, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDA_EN, 0x1 }, // enable LED Power + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDB_EN, 0x1 }, // enable LED Power +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDA_EN, 0x0 }, // disable LED Power + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDB_EN, 0x0 }, // disable LED Power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK0_VSEL } +}; + +// It's VDD FIXED! used for RAM inside the SOC +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK5_VSEL } +}; + +// This is indexed with POWER_RAIL_*, I really just need to use the +// index in LDO[] +target_rails_t target_rails = { + { 0x10, 450, 1250, 3125 }, // POWER_RAIL_CPU, BUCK0 + { 0x15, 600, 1400, 3125 }, // POWER_RAIL_VDD_FIXED BUCK5 + { 0x12, 600, 1400, 3125 }, // POWER_RAIL_SOC, BUCK2 + + { 0x17, 600, 1400, 3125 }, // POWER_RAIL_CPU_RAM, BUCK7 + { 0x11, 450, 1250, 3125 }, // POWER_RAIL_GPU, BUCK1 + { 0x18, 600, 1400, 3125 }, // POWER_RAIL_GPU_RAM, BUCK8 +}; + +#endif // POWERCONFIG_PMU_SETUP + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 + +#define ACC_PWR_LDO (6) + +#define GASGAUGE_BATTERYID_BLOCK 1 + +#endif diff --git a/target/ipad6b/include/target/uartconfig.h b/target/ipad6b/include/target/uartconfig.h new file mode 100644 index 0000000..ca81b1e --- /dev/null +++ b/target/ipad6b/include/target/uartconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#endif diff --git a/target/ipad6b/include/target/usbconfig.h b/target/ipad6b/include/target/usbconfig.h new file mode 100644 index 0000000..5c5a6e8 --- /dev/null +++ b/target/ipad6b/include/target/usbconfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_OTGTUNE0 + +#undef USBPHY_OTGTUNE0 +#define USBPHY_OTGTUNE0 (0x37377B93) + +#endif /* USBPHY_OTGTUNE0 */ + +#ifdef USBPHY_OTGTUNE1 + +#undef USBPHY_OTGTUNE1 +#define USBPHY_OTGTUNE1 (0x20C04) + +#endif /* USBPHY_OTGTUNE1 */ + + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/ipad6b/init.c b/target/ipad6b/init.c new file mode 100644 index 0000000..e68c42f --- /dev/null +++ b/target/ipad6b/init.c @@ -0,0 +1,617 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#include +#endif +#if TARGET_USES_BLEND_CM +#include +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +static dp_t dp; +#endif + +// DEV settings for: +// +// IO GPIO 298: AOP_I2CM_SCL (AOP GPIO 10) -> SPI_ACCEL_CS_L +// IO GPIO 299: AOP_FUNC[0] (AOP GPIO 11) -> SPI_MAGNESIUM_CS_L +// IO GPIO 303: AOP_FUNC[4] (AOP GPIO 15) -> SPI_CARBON_CS_L +// IO GPIO 305: AOP_FUNC[6] (AOP GPIO 17) -> SPI_PHOSPHORUS_CS_L +static const uint32_t fixup_list_dev[] = { + GPIOC(GPIOC_1, (10 / 8), (10 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + GPIOC(GPIOC_1, (11 / 8), (11 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + GPIOC(GPIOC_1, (15 / 8), (15 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + GPIOC(GPIOC_1, (17 / 8), (17 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + UINT32_MAX, UINT32_MAX +}; + +// AP settings for: +// +// IO GPIO 298: AOP_I2CM_SCL (AOP GPIO 10) -> SPI_ACCEL_CS_L +// IO GPIO 299: AOP_FUNC[0] (AOP GPIO 11) -> SPI_MAGNESIUM_CS_L +// IO GPIO 303: AOP_FUNC[4] (AOP GPIO 15) -> SPI_CARBON_CS_L +// IO GPIO 305: AOP_FUNC[6] (AOP GPIO 17) -> SPI_PHOSPHORUS_CS_L +static const uint32_t fixup_list_ap[] = { + GPIOC(GPIOC_1, (10 / 8), (10 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S4 | SLOW_SLEW), + + GPIOC(GPIOC_1, (11 / 8), (11 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S4 | SLOW_SLEW), + + GPIOC(GPIOC_1, (15 / 8), (15 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S4 | SLOW_SLEW), + + GPIOC(GPIOC_1, (17 / 8), (17 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S4 | SLOW_SLEW), + + UINT32_MAX, UINT32_MAX +}; + +static uint32_t gpio_board_rev; +static bool gpio_board_rev_valid; + +#if WITH_HW_POWER + int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); +#endif + +uint32_t +ipad6b_get_board_rev (void) +{ + /* + * Sequence: + * - Set GPIO as input. + * - Enable PU and disable PD. + * - Read + */ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return (gpio_board_rev); +} + +int +target_get_boot_battery_capacity (void) +{ + int temp = 0; +#if WITH_HW_GASGAUGE + if (gasgauge_read_temperature(&temp) != 0) { + temp = 0; // defensive + } +#endif + + if (temp > 500) { + return (0); // rely on SOC1 clear only + } + + return (50); // @see rdar://16587240 +} + +uint32_t +target_get_board_rev (void) +{ + if (!gpio_board_rev_valid) { + ipad6b_get_board_rev(); + } + + return (gpio_board_rev); +} + +static +void target_fixup_power (uint32_t board_rev) +{ +#if WITH_HW_POWER +int charger_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + + int rc; + + // Update PMU UV comparator settings for J127 units prior to EVT + // NOTE: kD2257_IPK_UV_BUCK1_UV_EN_THR, kD2257_IPK_UV_BUCK1_UV_DIG_CONF_1 (0xf8c,0x0f8a) set in pmu_uvwarn_config() + uint8_t data=0xff; + pmu_get_data(0, 0x0201, &data); + if ( data < 0x09 ) { // 0x09 = BJ + rc = pmu_set_data(0, 0x7000, 0x1d, false); + if ( rc<0 ) { + dprintf(DEBUG_CRITICAL, "pmu: cannot enter test mode (%d)\n", rc); + } else { + rc = pmu_set_data(0, 0x0f8e, 0x0f, true); // was 0xa + if ( rc==0 ) rc = pmu_set_data(0, 0x0f87, 0x00, true); // required + if ( rc==0 ) rc = pmu_set_data(0, 0x0f8d, 0x0f, true); // ok + if ( rc==0 ) rc = pmu_set_data(0, 0x1108, 0xff, true); + + if ( rc!=0 ) dprintf(DEBUG_INFO, "pmu: failed UV_WARN reconfig(%d)\n", rc); + + int temp=pmu_set_data(0, 0x700, 0x1d, false); + if ( temp<0 ) panic("pmu: cannot exit test mode\n"); + } + } + + rc=charger_set_data(0, 0x04d7, 0x04, true); + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "chg: cannot update ATV table (%d)\n", rc); +#endif +} + +void +target_early_init (void) +{ + uint32_t board_rev = target_get_board_rev(); + uint32_t board_id = platform_get_board_id(); + + dprintf(DEBUG_INFO, "%s: board id: 0x%02x, board rev: 0x%02x\n", + __func__, board_id, board_rev); + +#if PRODUCT_LLB || PRODUCT_IBSS + // Refer rdar://18848645 + target_fixup_power(board_rev); + pmgr_platform_config_uvwarn(); +#endif +} + +void +target_late_init (void) +{ + power_set_gpio(GPIO_PMU_NAND_LOW_POWER_MODE, 1, 1); +} + +void +target_init (void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + if (target_config_dev()) { + gpio_fixup_pinconfig(fixup_list_dev); + } else { + gpio_fixup_pinconfig(fixup_list_ap); + } +} + +void +target_quiesce_hardware (void) +{ +} + +void +target_poweroff (void) +{ +} + +int +target_bootprep (enum boot_target target) +{ + return 0; +} + +bool +target_should_recover (void) +{ + return (platform_get_request_dfu2() && power_has_usb()); +} + +bool +target_should_poweron (bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) { + *cold_button_boot = true; + } +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return (!*cold_button_boot || platform_get_request_dfu1()); +} + +bool +target_should_poweroff (bool at_boot) +{ + return (platform_get_request_dfu1() && (!at_boot || !power_has_usb())); +} + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = kDPControllerMode_Slave; + dp.type = kDPControllerType_EDP; + dp.min_link_rate = kLinkRate270Gbps; + dp.max_link_rate = kLinkRate270Gbps; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x1; + dp.vrr_enable = 0x1; + dp.vrr_on = 0x1; + dp.rx_n1= 25; + dp.rx_n2= 2; + dp.rx_n3= 13380; + dp.rx_n5= 0x2; + dp.fast_link_training = true; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void +target_setup_default_environment (void) +{ + // boot-device is set in platform's init.c + env_set("display-color-space","ARGB8101010", 0); + + env_set("display-timing", "ipad6", 0); + env_set("adbe-tunables", "ipad6b", 0); + env_set("adfe-tunables", "ipad6b", 0); +} + +#endif + +#if WITH_DEVICETREE + +int +target_update_device_tree (void) +{ +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; + DTNode *lpdp_node = NULL; +#endif + + DTNode *node; + void *propData; + uint32_t propSize; + char *propName; + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, + DTNode *lcd_node, + DTNode *clcd_node, + DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + + extern int lpdp_phy_update_device_tree(DTNode *lpdp_node); + FindNode(0, DPPHY_DTPATH, &lpdp_node); + lpdp_phy_update_device_tree(lpdp_node); + + } +#endif +#if TARGET_USES_BLEND_CM + if (dt_find_node(0, "arm-io/disp0", &node)) { + dt_set_prop(node, "cm-post-blend-degamma", target_blend_degamma_tables, sizeof(target_blend_degamma_tables)); + dt_set_prop(node, "cm-post-blend-engamma", target_blend_engamma_tables, sizeof(target_blend_engamma_tables)); + } +#endif + + // Update the als calibration data for all nodes that may be present on the dev board + if (dt_find_node(0, "arm-io/i2c3/als-1-fh", &node)) { + propName = "alsCalibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + //First, copy the CSCI key is present + if(syscfgCopyDataForTag('CSCI', propData, propSize) == -1) { + //Otherwise try to copy the CTMP key + syscfgCopyDataForTag('CTMP', propData, propSize); + } + } + } + + if (dt_find_node(0, "arm-io/i2c3/als-2-cn", &node)) { + propName = "alsCalibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + //First, copy the CSCI key is present + if(syscfgCopyDataForTag('CSCI', propData, propSize) == -1) { + //Otherwise try to copy the CTMP key + syscfgCopyDataForTag('CTMP', propData, propSize); + } + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + if (dt_find_node(0, "arm-io/spi3/multi-touch", &node)) { + propName = "multitouch-to-display-offset"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('MtDO', propData, propSize); + } + + propName = "firefly-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FfCl', propData, propSize); + } + + // + // rdar://problem/20508636 - Orb Cal Sys Cfg Keys + // + propName = "orb-afe-cal"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('OrbF', propData, propSize); + } + + propName = "orb-sum-cal"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('OrbS', propData, propSize); + } + + propName = "orb-dhybrid-cal"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('OrbD', propData, propSize); + } + + propName = "orb-plmf-cal"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('OrbP', propData, propSize); + } + } + + // Update the compass calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/compass", &node)) { + propName = "compass-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + propName = "compass-orientation"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CRot', propData, propSize); + } + } + + // Update the gyro calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/gyro", &node)) { + propName = "gyro-orientation"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/accel", &node)) { + propName = "accel-orientation"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + // + // J127: Unexpected speaker calibration values + // + if (FindNode(0, "arm-io/i2c1/audio-speaker-cn-left", &node)) { + propName = "speaker-calib"; + + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + } + + return (0); +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries +// (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899002827270000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E4E7E80000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 39, 39, 40), false }, // Blacker - black background, white logo + { RGB(228, 231, 232), true }, // Whiter - white background, black logo + // !!!FIXME!!! Remove the colors below when proto devices have been deprecated + // Remove old J127/J128 DClr values after Proto 2 units are deprecated + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t * +target_color_map_init (enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + if ((cs != CS_RGB888) && (cs != CS_ARGB8101010)) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + + fail: + return NULL; +} +#endif // WITH_PAINT + +#if !WITH_HW_POWER + +bool +power_needs_precharge (void) +{ + return false; +} + +void +power_cancel_buttonwait (void) +{ +} + +bool +power_do_chargetrap (void) +{ + return false; +} + +bool +power_is_suspended (void) +{ + return false; +} + +void +power_will_resume (void) +{ +} + +bool +power_has_usb (void) +{ + return false; +} + +int +power_read_dock_id (unsigned *id) +{ + return -1; +} + +bool +power_get_diags_dock (void) +{ + return false; +} + +uint32_t +power_get_boot_battery_level (void) +{ + return 0; +} + +int +power_get_nvram (uint8_t key, uint8_t *data) +{ + return -1; +} + +int +power_set_nvram (uint8_t key, uint8_t data) +{ + return -1; +} + +int +power_set_soc_voltage (unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void +power_set_usb_state (bool configured, bool suspended) +{ +} + +int +power_backlight_enable (uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/ipad6b/pinconfig.c b/target/ipad6b/pinconfig.c new file mode 100644 index 0000000..2249898 --- /dev/null +++ b/target/ipad6b/pinconfig.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +extern uint32_t ipad6b_get_board_rev(void); +extern const uint32_t* target_get_proto2_gpio_cfg(uint32_t gpioc); + +static bool use_proto2_pinconfig; +static bool board_rev_determined; + +const uint32_t * +target_get_default_gpio_cfg (uint32_t gpioc) +{ + uint32_t brev; + + // HACK: The first call into target_get_default_gpio_cfg() reads + // and attempts to restore BOARD_REV[3:0] to GPIO_CFG_DEFAULT. + // + // This will result in a recursive call back into + // target_get_default_gpio_cfg. To break the recursion, while determining + // board rev we can reply with any pinconfig since it's only being used + // for BOARD_REV[3:0] and it's CFG_DISABLED in all pinconfigs. + // + // Remove this after we no longer have BOARD_REV-dependent pinconfigs. + + if (use_proto2_pinconfig) { + return (target_get_proto2_gpio_cfg(gpioc)); + } + + if (!board_rev_determined) { + use_proto2_pinconfig = true; + + (void)ipad6b_get_board_rev(); + + use_proto2_pinconfig = false; + board_rev_determined = true; + } + + switch ((brev = ipad6b_get_board_rev())) { + + default: + return (target_get_proto2_gpio_cfg(gpioc)); + } +} diff --git a/target/ipad6b/pinconfig_proto2.c b/target/ipad6b/pinconfig_proto2.c new file mode 100644 index 0000000..36cae07 --- /dev/null +++ b/target/ipad6b/pinconfig_proto2.c @@ -0,0 +1,1470 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.30 + I/O Spreadsheet tracker: IO Spreadsheet for Rotterdam Experiment + Conversion command: ./tools/csvtopinconfig.py --soc elba --prefix proto2 --radar ' IO Spreadsheet for Rotterdam Experiment' --config-column j127:J127 --config-column j128:J128 --sheet SOC --copyright 2015 +*/ + +#include +#include +#include +#include +#include +#include + +enum { + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S8_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S7_SLOW_SLEW, +}; + + +static const uint32_t enum_map[] = { + [GPIOCFG_CFG_DISABLED] = CFG_DISABLED, + [GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW] = CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW] = CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW] = CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW] = CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW] = CFG_FUNC0 | DRIVE_S8 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_S8 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW] = CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S8_SLOW_SLEW] = CFG_FUNC0 | PULL_DOWN | DRIVE_S8 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S4_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW] = CFG_IN | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW] = CFG_IN | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW] = CFG_IN | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW] = CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW] = CFG_IN | PULL_UP | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_UP | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW] = CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW] = CFG_OUT_0 | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW] = CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW] = CFG_OUT_1 | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW] = CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S4_SLOW_SLEW] = CFG_OUT_1 | PULL_UP | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S7_SLOW_SLEW] = CFG_OUT_1 | PULL_UP | DRIVE_S7 | SLOW_SLEW, +}; + + +static const uint8_t pinconfig_proto2_j127ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_BELFIELD_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_BELFIELD_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_BELFIELD_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_BELFIELD_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> GPIO_SOC_TO_CODEC_RESET_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> GPIO_SOC_TO_BELFIELD_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC_TO_LED_DRIVER_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 19 : I2S1_MCK -> I2S_SOC_TO_AUDIO_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC_TO_BELFIELD_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC_TO_BELFIELD_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_BELFIELD_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC_TO_BELFIELD_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : NAND_SYS_CLK -> CLK_NAND_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S4_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 27 : UART1_TXD -> NC_UART1_TXD + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 28 : UART1_RXD -> NC_UART1_RXD + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 29 : UART1_RTSN -> NC_UART1_RTS + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 30 : UART1_CTSN -> NC_UART1_CTS + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_BELFIELD_TO_SOC_IRQ_L + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC_TO_CODEC_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC_TO_CODEC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC_TO_CODEC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 36 : I2S0_MCK -> TP_I2S0_MCK + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 64 : I2S4_MCK -> GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 69 : I2S2_MCK -> I2S_SOC_TO_BELFIELD_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_AUDIO_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_AUDIO_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_AUDIO_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_AUDIO_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_AJ_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_STB_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> TOUCH_SENSOR_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 86 : GPIO[12] -> NC_GPIO12 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 87 : GPIO[13] -> GPIO_SOC_TO_BB_WAKE_MODEM + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V28_CAM_LDO_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S4_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S4_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 97 : SPI0_SSIN -> NC_SPI0_SSIN + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 101 : PCIE_PERST3_N -> PCIE_SOC_TO_BB_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 102 : PCIE_PERST4_N -> NC_PCIE_PERST4 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 108 : PCIE_CLKREQ4_N -> NC_PCIE_CLKREQ4 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 119 : GPIO[47] -> NC_GPIO47 + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 137 : UART7_TXD -> GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_ORION_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 139 : CLK32K_OUT -> CLK_TOUCH_24MHZ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S8_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 175 : TMR32_PWM1 -> NC_TMR32_PWM1 + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_ROTTERDAM_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 181 : GPIO[21] -> NC_GPIO21 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 182 : GPIO[22] -> NC_GPIO22 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 183 : GPIO[23] -> NC_GPIO23 + +/* Port 23 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 184 : GPIO[24] -> NC_GPIO24 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 188 : DWI_DO -> NC_DWI_DO + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 191 : PMGR_SSCLK1 -> NC_PMGR_SSCLK1 + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 196 : I2S3_MCK -> TP_I2S3_MCK + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_BB_BCLK + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_BB_LRCK + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_BB_DOUT + +/* Port 25 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_BB_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 203 : GPIO[29] -> NC_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 205 : GPIO[31] -> NC_GPIO31 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V85_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_EUPHRATES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 213 : GPIO[39] -> GPIO_SOC_TO_ROTTERDAM_DEV_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_proto2_j127ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_AOP_UART2_TXD + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_AOP_UART2_RXD + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_MAGNESIUM_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_MAGNESIUM_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 13 : AOP_FUNC[2] -> GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_AOP_FUNC_7 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 20 : AOP_FUNC[9] -> GPIO_AOP_TO_LPOSC_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : AOP_I2S_MCK -> I2S_AOP_MCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> I2S_AOP_TO_MIC_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> I2S_AOP_TO_MIC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 27 : AOP_I2S_DIN -> I2S_MIC_TO_AOP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_proto2_j127dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_BELFIELD_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_BELFIELD_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_BELFIELD_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_BELFIELD_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> GPIO_SOC_TO_CODEC_RESET_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> GPIO_SOC_TO_BELFIELD_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC_TO_LED_DRIVER_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 19 : I2S1_MCK -> I2S_SOC_TO_AUDIO_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC_TO_BELFIELD_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC_TO_BELFIELD_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_BELFIELD_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC_TO_BELFIELD_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : NAND_SYS_CLK -> CLK_NAND_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 27 : UART1_TXD -> NC_UART1_TXD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 28 : UART1_RXD -> NC_UART1_RXD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 29 : UART1_RTSN -> NC_UART1_RTS + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 30 : UART1_CTSN -> NC_UART1_CTS + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_BELFIELD_TO_SOC_IRQ_L + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC_TO_CODEC_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC_TO_CODEC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC_TO_CODEC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 36 : I2S0_MCK -> TP_I2S0_MCK + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 64 : I2S4_MCK -> GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 69 : I2S2_MCK -> I2S_SOC_TO_BELFIELD_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_AUDIO_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_AUDIO_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_AUDIO_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_AUDIO_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_AJ_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_STB_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> TOUCH_SENSOR_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 86 : GPIO[12] -> NC_GPIO12 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 87 : GPIO[13] -> GPIO_SOC_TO_BB_WAKE_MODEM + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V28_CAM_LDO_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S7_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 97 : SPI0_SSIN -> NC_SPI0_SSIN + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 101 : PCIE_PERST3_N -> PCIE_SOC_TO_BB_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 102 : PCIE_PERST4_N -> NC_PCIE_PERST4 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 108 : PCIE_CLKREQ4_N -> NC_PCIE_CLKREQ4 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 119 : GPIO[47] -> NC_GPIO47 + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 137 : UART7_TXD -> GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_ORION_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 139 : CLK32K_OUT -> CLK_TOUCH_24MHZ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 175 : TMR32_PWM1 -> NC_TMR32_PWM1 + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_ROTTERDAM_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 181 : GPIO[21] -> NC_GPIO21 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 182 : GPIO[22] -> NC_GPIO22 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 183 : GPIO[23] -> NC_GPIO23 + +/* Port 23 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 184 : GPIO[24] -> NC_GPIO24 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 188 : DWI_DO -> NC_DWI_DO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 191 : PMGR_SSCLK1 -> NC_PMGR_SSCLK1 + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 196 : I2S3_MCK -> TP_I2S3_MCK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_BB_BCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_BB_LRCK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_BB_DOUT + +/* Port 25 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_BB_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 203 : GPIO[29] -> NC_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 205 : GPIO[31] -> NC_GPIO31 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V85_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_EUPHRATES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 213 : GPIO[39] -> GPIO_SOC_TO_ROTTERDAM_DEV_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_proto2_j127dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_AOP_UART2_TXD + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_AOP_UART2_RXD + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_MAGNESIUM_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_MAGNESIUM_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 13 : AOP_FUNC[2] -> GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_AOP_FUNC_7 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 20 : AOP_FUNC[9] -> GPIO_AOP_TO_LPOSC_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 24 : AOP_I2S_MCK -> I2S_AOP_MCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> I2S_AOP_TO_MIC_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> I2S_AOP_TO_MIC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 27 : AOP_I2S_DIN -> I2S_MIC_TO_AOP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_proto2_j128ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_BELFIELD_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_BELFIELD_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_BELFIELD_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_BELFIELD_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> GPIO_SOC_TO_CODEC_RESET_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> GPIO_SOC_TO_BELFIELD_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC_TO_LED_DRIVER_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 19 : I2S1_MCK -> I2S_SOC_TO_AUDIO_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC_TO_BELFIELD_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC_TO_BELFIELD_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_BELFIELD_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC_TO_BELFIELD_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : NAND_SYS_CLK -> CLK_NAND_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S4_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 27 : UART1_TXD -> NC_UART1_TXD + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 28 : UART1_RXD -> NC_UART1_RXD + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 29 : UART1_RTSN -> NC_UART1_RTS + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 30 : UART1_CTSN -> NC_UART1_CTS + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_BELFIELD_TO_SOC_IRQ_L + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC_TO_CODEC_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC_TO_CODEC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC_TO_CODEC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 36 : I2S0_MCK -> TP_I2S0_MCK + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 64 : I2S4_MCK -> GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 69 : I2S2_MCK -> I2S_SOC_TO_BELFIELD_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_AUDIO_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_AUDIO_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_AUDIO_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_AUDIO_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_AJ_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_STB_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> TOUCH_SENSOR_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 86 : GPIO[12] -> NC_GPIO12 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 87 : GPIO[13] -> GPIO_SOC_TO_BB_WAKE_MODEM + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V28_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S4_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S4_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 97 : SPI0_SSIN -> NC_SPI0_SSIN + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 101 : PCIE_PERST3_N -> PCIE_SOC_TO_BB_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 102 : PCIE_PERST4_N -> NC_PCIE_PERST4 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 108 : PCIE_CLKREQ4_N -> NC_PCIE_CLKREQ4 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 119 : GPIO[47] -> NC_GPIO47 + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 137 : UART7_TXD -> GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_ORION_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 139 : CLK32K_OUT -> CLK_TOUCH_24MHZ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S8_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 175 : TMR32_PWM1 -> NC_TMR32_PWM1 + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_ROTTERDAM_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 181 : GPIO[21] -> NC_GPIO21 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 182 : GPIO[22] -> NC_GPIO22 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 183 : GPIO[23] -> NC_GPIO23 + +/* Port 23 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 184 : GPIO[24] -> NC_GPIO24 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 188 : DWI_DO -> NC_DWI_DO + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 191 : PMGR_SSCLK1 -> NC_PMGR_SSCLK1 + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 196 : I2S3_MCK -> TP_I2S3_MCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_BB_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_BB_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_BB_DOUT + +/* Port 25 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_BB_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 203 : GPIO[29] -> NC_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 205 : GPIO[31] -> NC_GPIO31 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V85_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_EUPHRATES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW, // 213 : GPIO[39] -> GPIO_SOC_TO_ROTTERDAM_DEV_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_proto2_j128ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_AOP_UART2_TXD + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_AOP_UART2_RXD + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_MAGNESIUM_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_MAGNESIUM_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 13 : AOP_FUNC[2] -> GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S4_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_AOP_FUNC_7 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 20 : AOP_FUNC[9] -> GPIO_AOP_TO_LPOSC_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : AOP_I2S_MCK -> I2S_AOP_MCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> I2S_AOP_TO_MIC_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> I2S_AOP_TO_MIC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 27 : AOP_I2S_DIN -> I2S_MIC_TO_AOP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_proto2_j128dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_BELFIELD_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_BELFIELD_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_BELFIELD_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_BELFIELD_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> GPIO_SOC_TO_CODEC_RESET_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> GPIO_SOC_TO_BELFIELD_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC_TO_LED_DRIVER_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 19 : I2S1_MCK -> I2S_SOC_TO_AUDIO_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC_TO_BELFIELD_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC_TO_BELFIELD_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_BELFIELD_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC_TO_BELFIELD_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : NAND_SYS_CLK -> CLK_NAND_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 27 : UART1_TXD -> NC_UART1_TXD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 28 : UART1_RXD -> NC_UART1_RXD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 29 : UART1_RTSN -> NC_UART1_RTS + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 30 : UART1_CTSN -> NC_UART1_CTS + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_BELFIELD_TO_SOC_IRQ_L + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC_TO_CODEC_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC_TO_CODEC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC_TO_CODEC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 36 : I2S0_MCK -> TP_I2S0_MCK + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 64 : I2S4_MCK -> GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 69 : I2S2_MCK -> I2S_SOC_TO_BELFIELD_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_AUDIO_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_AUDIO_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_AUDIO_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_AUDIO_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_AJ_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_STB_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> TOUCH_SENSOR_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 86 : GPIO[12] -> NC_GPIO12 + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 87 : GPIO[13] -> GPIO_SOC_TO_BB_WAKE_MODEM + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V28_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_PULL_UP_DRIVE_S7_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 97 : SPI0_SSIN -> NC_SPI0_SSIN + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 101 : PCIE_PERST3_N -> PCIE_SOC_TO_BB_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 102 : PCIE_PERST4_N -> NC_PCIE_PERST4 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 108 : PCIE_CLKREQ4_N -> NC_PCIE_CLKREQ4 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 119 : GPIO[47] -> NC_GPIO47 + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 137 : UART7_TXD -> GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_ORION_RESET_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 139 : CLK32K_OUT -> CLK_TOUCH_24MHZ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S8_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 175 : TMR32_PWM1 -> NC_TMR32_PWM1 + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_ROTTERDAM_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 181 : GPIO[21] -> NC_GPIO21 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 182 : GPIO[22] -> NC_GPIO22 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 183 : GPIO[23] -> NC_GPIO23 + +/* Port 23 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 184 : GPIO[24] -> NC_GPIO24 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 188 : DWI_DO -> NC_DWI_DO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 191 : PMGR_SSCLK1 -> NC_PMGR_SSCLK1 + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 196 : I2S3_MCK -> TP_I2S3_MCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_BB_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_BB_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_BB_DOUT + +/* Port 25 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_BB_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 203 : GPIO[29] -> NC_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 205 : GPIO[31] -> NC_GPIO31 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V85_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_EUPHRATES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 213 : GPIO[39] -> GPIO_SOC_TO_ROTTERDAM_DEV_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_proto2_j128dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_AOP_UART2_TXD + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_AOP_UART2_RXD + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_MAGNESIUM_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_MAGNESIUM_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 13 : AOP_FUNC[2] -> GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_AOP_FUNC_7 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 20 : AOP_FUNC[9] -> GPIO_AOP_TO_LPOSC_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 24 : AOP_I2S_MCK -> I2S_AOP_MCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> I2S_AOP_TO_MIC_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> I2S_AOP_TO_MIC_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 27 : AOP_I2S_DIN -> I2S_MIC_TO_AOP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint8_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J127AP, ~0, { pinconfig_proto2_j127ap_0, pinconfig_proto2_j127ap_1 } }, + { TARGET_BOARD_ID_J127DEV, ~0, { pinconfig_proto2_j127dev_0, pinconfig_proto2_j127dev_1 } }, + { TARGET_BOARD_ID_J128AP, ~0, { pinconfig_proto2_j128ap_0, pinconfig_proto2_j128ap_1 } }, + { TARGET_BOARD_ID_J128DEV, ~0, { pinconfig_proto2_j128dev_0, pinconfig_proto2_j128dev_1 } }, +}; + +static uint32_t *expanded_pinconfigs[GPIOC_COUNT]; + +static const uint32_t controller_pins[GPIOC_COUNT] = { + GPIO_GROUP_COUNT * GPIOPADPINS, + GPIO_1_GROUP_COUNT * GPIOPADPINS, +}; + +const uint32_t * target_get_proto2_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + /* Cannot use malloc as chunk manager is yet to be intialized */ + static uint32_t pinconfig_buf[GPIO_GROUP_COUNT * GPIOPADPINS]; + expanded_pinconfigs[0] = pinconfig_buf; + static uint32_t pinconfig_buf_1[GPIO_1_GROUP_COUNT * GPIOPADPINS]; + expanded_pinconfigs[1] = pinconfig_buf_1; + + ASSERT(gpioc < GPIOC_COUNT); + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + + for (unsigned i = 0; i < GPIOC_COUNT; i++) { + uint32_t num_pins = controller_pins[i]; + + for (uint32_t j = 0; j < num_pins; j++) { + uint8_t enum_key = selected_map->pinconfigs[i][j]; + expanded_pinconfigs[i][j] = enum_map[enum_key]; + } + } + } + + return expanded_pinconfigs[gpioc]; +} diff --git a/target/ipad6b/rules.mk b/target/ipad6b/rules.mk new file mode 100644 index 0000000..5b8fbc2 --- /dev/null +++ b/target/ipad6b/rules.mk @@ -0,0 +1,75 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2257=1 \ + DIALOG_D2355=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_PLL_VCO_CAP=0 \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=8 \ + TARGET_ICP_CTR=15 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + PMU_LCD_PWR_EN=1 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + DCS_NUM_RANKS=1 \ + DCS_NUM_CHANNELS=4 \ + DCS_FIXUP_PARAMS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_DITHER_TYPE=DITHER_SPATIO_TEMPORAL \ + TARGET_DITHER_INBITSREDUCTION=0 \ + TARGET_DITHER_EDOUTTOSTINWIDTH=0 \ + TARGET_DITHER_DITHEROUTWIDTH=3 \ + TARGET_DITHER_ST_METHOD_MAX=3 \ + TARGET_DITHER_ST_METHOD_POP=4 \ + TARGET_DITHER_ST_PHASE=0x1a00 \ + TARGET_DITHER_ST_SKEWLOC0=0 \ + TARGET_DITHER_ST_SKEWLOC1=1 \ + TARGET_DITHER_ST_SKEWLOC2=100 \ + TARGET_DITHER_ST_SKEWLOC3=1023 \ + TARGET_DITHER_ST_SKEWLOC4=1023 \ + TARGET_DITHER_ST_SKEWLOC5=1023 \ + TARGET_DITHER_ST_SKEWLOC6=1023 \ + TARGET_DITHER_ST_SKEWLOC7=1023 \ + TARGET_DITHER_ST_SKEWLOC8=1023 \ + TARGET_DITHER_ST_SKEWLOC9=1023 \ + TARGET_DITHER_ST_SKEWLOC10=1023 \ + TARGET_DITHER_ST_SKEWLOC11=1023 \ + TARGET_DITHER_ST_SKEWLOC12=1023 \ + TARGET_DITHER_ST_SKEWLOC13=1023 \ + TARGET_DITHER_ST_SKEWLOC14=1023 \ + TARGET_USES_BLEND_CM=1 \ + WITH_HW_KSF_BACKLIGHT=1 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + PMU_LCD_PWR_EN=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi3/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart2/wlan\" \ + DP_DTPATH=\"arm-io/displayport0\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy0\" \ + BT_DTPATH=\"arm-io/uart3/bluetooth\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o $(LOCAL_DIR)/pinconfig.o \ + $(LOCAL_DIR)/pinconfig_proto2.o diff --git a/target/ipad6d/include/target/adbe_settings.h b/target/ipad6d/include/target/adbe_settings.h new file mode 100644 index 0000000..d89c642 --- /dev/null +++ b/target/ipad6d/include/target/adbe_settings.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +// see adbe_v2.c for structure definition +// +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "ipad6d", + .adbe0_vftgctl_idle_frame_vblank_enable = 1, + .adbe0_vblank_pos_vbi_pulse = 0x0132, + .adbe0_vblank_clk_gate_wakeup = 0x07, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_PMGR_CLK_GATE_ENABLE | + DBEMODECNTL_DYN_CLK_GATE_ENABLE | + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | + AAP_FORMAT_CONTROL_REG1_FCMODE(2) | + AAP_FORMAT_CONTROL_REG1_RSVD(0) | + AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/ipad6d/include/target/boardid.h b/target/ipad6d/include/target/boardid.h new file mode 100644 index 0000000..b89ec46 --- /dev/null +++ b/target/ipad6d/include/target/boardid.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef TARGET_BOARDID_H +#define TARGET_BOARDID_H + +// Board ids +#define TARGET_BOARD_ID_J98AAP (0x10) +#define TARGET_BOARD_ID_J98ADEV (0x11) + +#define TARGET_BOARD_ID_J99AAP (0x12) +#define TARGET_BOARD_ID_J99ADEV (0x13) + +// Board revs +#define J99a_DEV0_BOARD_REV (0x0) +#define J99a_DEV1_BOARD_REV (0x1) +#define J99a_DEV2_BOARD_REV (0x2) + +#define J99a_AP_BOARD_REV (0x0) +#define J99a_AP_EVT_BOARD_REV_1 (0x1) +#define J99a_AP_EVT_BOARD_REV_2 (0x2) +#define J99a_AP_DVT_BOARD_REV_1 (0x3) + +#endif diff --git a/target/ipad6d/include/target/display_gamma_tables.h b/target/ipad6d/include/target/display_gamma_tables.h new file mode 100644 index 0000000..8bae983 --- /dev/null +++ b/target/ipad6d/include/target/display_gamma_tables.h @@ -0,0 +1,604 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_DISPLAY_GAMMA_TABLES_H +#define __TARGET_DISPLAY_GAMMA_TABLES_H + +/* display gamma tables */ + +#define ADP_CM_DEGAMMA_PAIRED_LUT_COUNT 65 +#define ADP_CM_DEGAMMA_PAIRED_LUT_SIZE (ADP_CM_DEGAMMA_PAIRED_LUT_COUNT - 1) +static const uint32_t target_blend_degamma_tables[ADP_CM_DEGAMMA_PAIRED_LUT_COUNT] = { + 0x00050000, + 0x000F000A, + 0x00190014, + 0x0024001E, + 0x0031002A, + 0x00410039, + 0x0054004A, + 0x006A005F, + 0x00820076, + 0x009E0090, + 0x00BD00AD, + 0x00DF00CD, + 0x010400F1, + 0x012C0118, + 0x01590142, + 0x01880170, + 0x01BC01A2, + 0x01F301D7, + 0x022E0210, + 0x026C024C, + 0x02AF028D, + 0x02F602D2, + 0x0340031A, + 0x038F0367, + 0x03E203B8, + 0x043A040D, + 0x04950467, + 0x04F504C5, + 0x055A0527, + 0x05C3058E, + 0x063005F9, + 0x06A20669, + 0x071906DD, + 0x07940756, + 0x081407D4, + 0x08990856, + 0x092308DE, + 0x09B2096A, + 0x0A4609FB, + 0x0ADF0A92, + 0x0B7C0B2D, + 0x0C1F0BCD, + 0x0CC70C73, + 0x0D740D1D, + 0x0E270DCD, + 0x0EDF0E82, + 0x0F9C0F3C, + 0x105E0FFC, + 0x112610C1, + 0x11F3118C, + 0x12C6125C, + 0x139E1331, + 0x147C140D, + 0x156014ED, + 0x164915D4, + 0x173816C0, + 0x182C17B1, + 0x192718A9, + 0x1A2719A6, + 0x1B2D1AA9, + 0x1C391BB2, + 0x1D4B1CC1, + 0x1E621DD6, + 0x1F801EF0, + 0x29F42011, +}; + +#define ADP_CM_ENGAMMA_PAIRED_LUT_COUNT 513 +#define ADP_CM_ENGAMMA_PAIRED_LUT_SIZE (ADP_CM_ENGAMMA_PAIRED_LUT_COUNT - 1) +static const uint32_t target_blend_engamma_tables[ADP_CM_ENGAMMA_PAIRED_LUT_COUNT] = { + 0x000D0000, + 0x0026001A, + 0x003D0033, + 0x004F0047, + 0x005E0057, + 0x006B0065, + 0x00770071, + 0x0081007C, + 0x008B0087, + 0x00950090, + 0x009D0099, + 0x00A500A2, + 0x00AD00AA, + 0x00B500B1, + 0x00BC00B8, + 0x00C300C0, + 0x00CA00C6, + 0x00D000CD, + 0x00D600D3, + 0x00DC00D9, + 0x00E200DF, + 0x00E800E5, + 0x00ED00EB, + 0x00F300F0, + 0x00F800F5, + 0x00FD00FA, + 0x01020100, + 0x01070104, + 0x010C0109, + 0x0110010E, + 0x01150113, + 0x01190117, + 0x011E011C, + 0x01220120, + 0x01270124, + 0x012B0129, + 0x012F012D, + 0x01330131, + 0x01370135, + 0x013B0139, + 0x013F013D, + 0x01430141, + 0x01460144, + 0x014A0148, + 0x014E014C, + 0x01510150, + 0x01550153, + 0x01590157, + 0x015C015A, + 0x015F015E, + 0x01630161, + 0x01660165, + 0x016A0168, + 0x016D016B, + 0x0170016F, + 0x01730172, + 0x01770175, + 0x017A0178, + 0x017D017B, + 0x0180017E, + 0x01830181, + 0x01860185, + 0x01890188, + 0x018C018B, + 0x018F018E, + 0x01920190, + 0x01950193, + 0x01980196, + 0x019B0199, + 0x019D019C, + 0x01A0019F, + 0x01A301A2, + 0x01A601A4, + 0x01A801A7, + 0x01AB01AA, + 0x01AE01AD, + 0x01B101AF, + 0x01B301B2, + 0x01B601B5, + 0x01B801B7, + 0x01BB01BA, + 0x01BE01BC, + 0x01C001BF, + 0x01C301C1, + 0x01C501C4, + 0x01C801C6, + 0x01CA01C9, + 0x01CD01CB, + 0x01CF01CE, + 0x01D201D0, + 0x01D401D3, + 0x01D601D5, + 0x01D901D8, + 0x01DB01DA, + 0x01DE01DC, + 0x01E001DF, + 0x01E201E1, + 0x01E501E3, + 0x01E701E6, + 0x01E901E8, + 0x01EB01EA, + 0x01EE01ED, + 0x01F001EF, + 0x01F201F1, + 0x01F401F3, + 0x01F701F5, + 0x01F901F8, + 0x01FB01FA, + 0x01FD01FC, + 0x01FF01FE, + 0x02010200, + 0x02040203, + 0x02060205, + 0x02080207, + 0x020A0209, + 0x020C020B, + 0x020E020D, + 0x0210020F, + 0x02120211, + 0x02140213, + 0x02160215, + 0x02180217, + 0x021A0219, + 0x021D021C, + 0x021E021E, + 0x02210220, + 0x02220222, + 0x02240224, + 0x02260225, + 0x02280227, + 0x022A0229, + 0x022C022B, + 0x022E022D, + 0x0230022F, + 0x02320231, + 0x02340233, + 0x02360235, + 0x02380237, + 0x023A0239, + 0x023C023B, + 0x023D023D, + 0x023F023E, + 0x02410240, + 0x02430242, + 0x02450244, + 0x02470246, + 0x02490248, + 0x024A0249, + 0x024C024B, + 0x024E024D, + 0x0250024F, + 0x02520251, + 0x02530252, + 0x02550254, + 0x02570256, + 0x02590258, + 0x025A025A, + 0x025C025B, + 0x025E025D, + 0x0260025F, + 0x02610261, + 0x02630262, + 0x02650264, + 0x02670266, + 0x02680267, + 0x026A0269, + 0x026C026B, + 0x026D026C, + 0x026F026E, + 0x02710270, + 0x02720272, + 0x02740273, + 0x02760275, + 0x02770276, + 0x02790278, + 0x027B027A, + 0x027C027B, + 0x027E027D, + 0x0280027F, + 0x02810280, + 0x02830282, + 0x02840284, + 0x02860285, + 0x02880287, + 0x02890288, + 0x028B028A, + 0x028C028C, + 0x028E028D, + 0x028F028F, + 0x02910290, + 0x02930292, + 0x02940293, + 0x02960295, + 0x02970297, + 0x02990298, + 0x029A029A, + 0x029C029B, + 0x029D029D, + 0x029F029E, + 0x02A102A0, + 0x02A202A1, + 0x02A402A3, + 0x02A502A4, + 0x02A702A6, + 0x02A802A7, + 0x02AA02A9, + 0x02AB02AA, + 0x02AD02AC, + 0x02AE02AD, + 0x02B002AF, + 0x02B102B0, + 0x02B202B2, + 0x02B402B3, + 0x02B502B5, + 0x02B702B6, + 0x02B802B8, + 0x02BA02B9, + 0x02BB02BB, + 0x02BD02BC, + 0x02BE02BD, + 0x02C002BF, + 0x02C102C0, + 0x02C202C2, + 0x02C402C3, + 0x02C502C5, + 0x02C702C6, + 0x02C802C7, + 0x02CA02C9, + 0x02CB02CA, + 0x02CC02CC, + 0x02CE02CD, + 0x02CF02CE, + 0x02D102D0, + 0x02D202D1, + 0x02D302D3, + 0x02D502D4, + 0x02D602D5, + 0x02D702D7, + 0x02D902D8, + 0x02DA02D9, + 0x02DC02DB, + 0x02DD02DC, + 0x02DE02DE, + 0x02E002DF, + 0x02E102E0, + 0x02E202E2, + 0x02E402E3, + 0x02E502E4, + 0x02E602E6, + 0x02E802E7, + 0x02E902E8, + 0x02EA02EA, + 0x02EC02EB, + 0x02ED02EC, + 0x02EE02EE, + 0x02F002EF, + 0x02F102F0, + 0x02F202F2, + 0x02F402F3, + 0x02F502F4, + 0x02F602F6, + 0x02F802F7, + 0x02F902F8, + 0x02FA02F9, + 0x02FB02FB, + 0x02FD02FC, + 0x02FE02FD, + 0x02FF02FF, + 0x03010300, + 0x03020301, + 0x03030302, + 0x03040304, + 0x03060305, + 0x03070306, + 0x03080308, + 0x03090309, + 0x030B030A, + 0x030C030B, + 0x030D030D, + 0x030E030E, + 0x0310030F, + 0x03110310, + 0x03120312, + 0x03130313, + 0x03150314, + 0x03160315, + 0x03170317, + 0x03180318, + 0x031A0319, + 0x031B031A, + 0x031C031B, + 0x031D031D, + 0x031E031E, + 0x0320031F, + 0x03210320, + 0x03220322, + 0x03230323, + 0x03250324, + 0x03260325, + 0x03270326, + 0x03280328, + 0x03290329, + 0x032B032A, + 0x032C032B, + 0x032D032C, + 0x032E032E, + 0x032F032F, + 0x03300330, + 0x03320331, + 0x03330332, + 0x03340333, + 0x03350335, + 0x03360336, + 0x03380337, + 0x03390338, + 0x033A0339, + 0x033B033A, + 0x033C033C, + 0x033D033D, + 0x033F033E, + 0x0340033F, + 0x03410340, + 0x03420341, + 0x03430343, + 0x03440344, + 0x03450345, + 0x03470346, + 0x03480347, + 0x03490348, + 0x034A0349, + 0x034B034B, + 0x034C034C, + 0x034D034D, + 0x034F034E, + 0x0350034F, + 0x03510350, + 0x03520351, + 0x03530352, + 0x03540354, + 0x03550355, + 0x03560356, + 0x03570357, + 0x03590358, + 0x035A0359, + 0x035B035A, + 0x035C035B, + 0x035D035C, + 0x035E035E, + 0x035F035F, + 0x03600360, + 0x03610361, + 0x03620362, + 0x03640363, + 0x03650364, + 0x03660365, + 0x03670366, + 0x03680367, + 0x03690368, + 0x036A036A, + 0x036B036B, + 0x036C036C, + 0x036D036D, + 0x036E036E, + 0x036F036F, + 0x03710370, + 0x03720371, + 0x03730372, + 0x03740373, + 0x03750374, + 0x03760375, + 0x03770376, + 0x03780377, + 0x03790379, + 0x037A037A, + 0x037B037B, + 0x037C037C, + 0x037D037D, + 0x037E037E, + 0x037F037F, + 0x03800380, + 0x03810381, + 0x03830382, + 0x03840383, + 0x03850384, + 0x03860385, + 0x03870386, + 0x03880387, + 0x03890388, + 0x038A0389, + 0x038B038A, + 0x038C038B, + 0x038D038C, + 0x038E038D, + 0x038F038E, + 0x0390038F, + 0x03910390, + 0x03920391, + 0x03930393, + 0x03940394, + 0x03950395, + 0x03960396, + 0x03970397, + 0x03980398, + 0x03990399, + 0x039A039A, + 0x039B039B, + 0x039C039C, + 0x039D039D, + 0x039E039E, + 0x039F039F, + 0x03A003A0, + 0x03A103A1, + 0x03A203A2, + 0x03A303A3, + 0x03A403A4, + 0x03A503A5, + 0x03A603A6, + 0x03A703A7, + 0x03A803A8, + 0x03A903A9, + 0x03AA03AA, + 0x03AB03AB, + 0x03AC03AC, + 0x03AD03AD, + 0x03AE03AD, + 0x03AF03AE, + 0x03B003AF, + 0x03B103B0, + 0x03B203B1, + 0x03B303B2, + 0x03B403B3, + 0x03B503B4, + 0x03B603B5, + 0x03B703B6, + 0x03B803B7, + 0x03B903B8, + 0x03BA03B9, + 0x03BB03BA, + 0x03BC03BB, + 0x03BD03BC, + 0x03BD03BD, + 0x03BE03BE, + 0x03BF03BF, + 0x03C003C0, + 0x03C103C1, + 0x03C203C2, + 0x03C303C3, + 0x03C403C4, + 0x03C503C5, + 0x03C603C6, + 0x03C703C7, + 0x03C803C7, + 0x03C903C8, + 0x03CA03C9, + 0x03CB03CA, + 0x03CC03CB, + 0x03CD03CC, + 0x03CE03CD, + 0x03CF03CE, + 0x03CF03CF, + 0x03D003D0, + 0x03D103D1, + 0x03D203D2, + 0x03D303D3, + 0x03D403D4, + 0x03D503D5, + 0x03D603D6, + 0x03D703D6, + 0x03D803D7, + 0x03D903D8, + 0x03DA03D9, + 0x03DB03DA, + 0x03DC03DB, + 0x03DC03DC, + 0x03DD03DD, + 0x03DE03DE, + 0x03DF03DF, + 0x03E003E0, + 0x03E103E1, + 0x03E203E2, + 0x03E303E2, + 0x03E403E3, + 0x03E503E4, + 0x03E603E5, + 0x03E703E6, + 0x03E703E7, + 0x03E803E8, + 0x03E903E9, + 0x03EA03EA, + 0x03EB03EB, + 0x03EC03EB, + 0x03ED03EC, + 0x03EE03ED, + 0x03EF03EE, + 0x03F003EF, + 0x03F003F0, + 0x03F103F1, + 0x03F203F2, + 0x03F303F3, + 0x03F403F4, + 0x03F503F4, + 0x03F603F5, + 0x03F703F6, + 0x03F803F7, + 0x03F803F8, + 0x03F903F9, + 0x03FA03FA, + 0x03FB03FB, + 0x03FC03FC, + 0x03FD03FC, + 0x03FE03FD, + 0x03FF03FE, + 0x043503FF +}; + +#endif diff --git a/target/ipad6d/include/target/gpiodef.h b/target/ipad6d/include/target/gpiodef.h new file mode 100644 index 0000000..151f0da --- /dev/null +++ b/target/ipad6d/include/target/gpiodef.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* ipad6,x specific gpio -> pin mappings */ + +#include + +// XXX: Update all of this + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 4) // 116 : GPIO[44] +#define GPIO_BOARD_REV1 GPIO(14, 5) // 117 : GPIO[45] +#define GPIO_BOARD_REV2 GPIO(14, 6) // 118 : GPIO[46] +#define GPIO_BOARD_REV3 GPIO(15, 1) // 121 : GPIO[49] + +/* Miscellaneous Pins */ +#define GPIO_DISPLAY_HPD GPIO(24, 2) // 194: EPD_HPD0 -> LPDP_TCON_TO_SOC_HPD + +#define GPIO_S3E_BOOT_FROM_HOST GPIO_ID(76) // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP (formerly AP_TO_NAND_FW_STRAP) + + +/* which IICs to initialize */ +#define IICS_MASK (0xF) + +#define TRISTAR_IIC_BUS (0) +#define BACKLIGHT_IIC_BUS (0) +#define DISPLAY_PMU_IIC_BUS (0) + +#define GPIO_PMU_LCD_PWR_EN (17) // PMU GPIO 18 - GPIO_PMU_TO_LCD_PWREN +#define GPIO_PMU_NAND_LOW_POWER_MODE (15) // PMU GPIO 16 - GPIO_PMU_TO_NAND_LOW_BATT_L + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipad6d/include/target/lpdp_settings.h b/target/ipad6d/include/target/lpdp_settings.h new file mode 100644 index 0000000..1c73a39 --- /dev/null +++ b/target/ipad6d/include/target/lpdp_settings.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef LPDP_SETTINGS_H +#define LPDP_SETTINGS_H + +static struct lpdp_port_calibration lpdp_port_calibration_table[1][1] = { + { {LPDP_PHY_LANE_VREG_ADJ_390_mV, 0}, }, +}; + +#define LPDP_PORT_CALIBRATION_TABLE_FIXED (true) + +#endif diff --git a/target/ipad6d/include/target/powerconfig.h b/target/ipad6d/include/target/powerconfig.h new file mode 100644 index 0000000..5603b05 --- /dev/null +++ b/target/ipad6d/include/target/powerconfig.h @@ -0,0 +1,252 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +// Configuration per target + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 0 + +// This configuration is very PMU specific and must be included exactly +// once in power.c +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2257_EN_CMD0, (1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0) }, + { PMU_IIC_BUS, kD2257_EN_CMD1, (1<<0) }, // buck8 + { PMU_IIC_BUS, kD2257_EN_CMD2, 1 }, // enable WLED SPI access + { PMU_IIC_BUS, kD2257_SPI_CTRL, 1 } // enable SPI access +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// IO_CONFIG[7:6] 0=I 1=O_OD 2=O_PP 3=SS +// IO_TYPE[5:3] O 0=L 1=32K 2=nR 3=TI 4=L +// PUPD[2:1] O 0=NP 1=PU 2=NP 3=<0> +// WAKE_LVL[0] O 0=low 1=high +// IO_TYPE[5:3] I 0=L_AH 1=L_AL 2=RE 3=FE 4=AE +// PUPD[2:1] I 0=NP 1=PU 2=PD_GND 3=<0> +// WAKE_LVL[0] I 0=NW 1=W +// +// J99A Dev0 IO Spreadsheet +// J99A MLB-DEV1 IO Spreadsheet +// J99A IO Spreadsheet (J99A_IO_EVT_1p0.xlsx) +static const struct pmu_setup_struct pmu_cold_init[] = +{ + // TODO :This is a Bringup Hack, remove + { PMU_IIC_BUS, kD2257_BUCK0_VSEL, 0xc0}, // CPU rail + { PMU_IIC_BUS, kD2257_BUCK1_VSEL, 0xc0}, // GPU rail + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK1_EN, 0xf}, // GPU power rail (see ) + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK8_EN, 0xf}, // GPU RAM power rail (see ) + // TODO :This is a Bringup Hack, remove + + { PMU_IIC_BUS, kD2257_PWRONOFF_BUCK3_SW2_EN, 0xf}, // J99A/J127: Keep DVDD power rail on to avoid speaker pops (work around HW issue) + { PMU_IIC_BUS, kD2257_PWRONOFF_LDO4_EN, 0x1}, // Enable PP3V0_ALS + + { PMU_IIC_BUS, kD2257_LDO2_BYPASS, 0x1}, // bypass when Active rdar://19773152 + + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA }, // Enable Test Mode + { PMU_IIC_BUS, kD2257_EN_CMD3, 0}, // Enable SPI access for BUCKx (x=3) + { PMU_IIC_BUS, kD2257_IPK_UV_BUCK1_IPEAK_ANA_CONF_2, 0x1 }, // 0xf87 + { PMU_IIC_BUS, kD2257_IPK_UV_BUCK1_UV_OFFSET, 0x0a }, // 0xf8e + { PMU_IIC_BUS, kD2257_IPK_UV_BUCK1_UV_EN_THR, 0x90 }, // 0xf8c = 900mV + { PMU_IIC_BUS, kD2257_IPK_UV_BUCK1_UV_ANA_CONF_1, 0x0f }, // 0xf8d + { PMU_IIC_BUS, kD2257_LDO7_SOFT_STARTUP, 0x1}, // J99a: LDO7 soft startup should be disabled + { PMU_IIC_BUS, kD2257_SYSCTL_PRE_UVLO_CONF, 0x16}, // rdar://22196011 + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS }, // Disable Test Mode + + { PMU_IIC_BUS, kD2257_IPK_UV_BUCK1_UV_DIG_CONF_1, 0x01 }, // 0x0f8a + + // GPIO1 - GPIO_FH_HALL_TO_PMU_IRQ_L + { PMU_IIC_BUS, kD2257_GPIO1_CONF1, (0<<6)|(4<<3)|(1<<1)|(1<<0) }, // 0x23 Input, AnyE, PU, Wakeup + { PMU_IIC_BUS, kD2257_GPIO1_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO_ACC_TO_PMU_PWR_SW_OC_L + { PMU_IIC_BUS, kD2257_GPIO2_CONF1, (0<<6)|(3<<3)|(1<<1)|(0<<0) }, // 0x1A Input, FE, PU, No Wakeup + { PMU_IIC_BUS, kD2257_GPIO2_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO_ORION_TO_SOC_TO_PMU_IRQ + { PMU_IIC_BUS, kD2257_GPIO3_CONF1, (0<<6)|(0<<3)|(2<<1)|(1<<0) }, // 0x25 Input, AH, PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO3_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO_PMU_TO_ACC_PWR_SEL + { PMU_IIC_BUS, kD2257_GPIO4_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO4_CONF2, (0<<3)|(0<<0) }, // 0x00 VBUCK3, no DEB + + // UART_BATT_HDQ + { PMU_IIC_BUS, kD2257_GPIO6_CONF1, (0<<6)|(3<<3)|(0<<1)|(1<<0) }, // 0x19 Input, FE, No PU/PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO6_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO_BT_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2257_GPIO7_CONF1, (0<<6)|(2<<3)|(0<<1)|(1<<0) }, // 0x11 Input, RE, No PU/PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO7_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO_WLAN_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2257_GPIO8_CONF1, (0<<6)|(2<<3)|(2<<1)|(1<<0) }, // 0x15 Input, RE, PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO8_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + +#if TARGET_HAS_BASEBAND + // GPIO_PMU_TO_BBPMU_RESET_R_L rdar://20064772 + { PMU_IIC_BUS, kD2257_GPIO5_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, no PU/PD, Low + { PMU_IIC_BUS, kD2257_GPIO5_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + // GPIO_BB_TO_PMU_HOST_WAKE_L + { PMU_IIC_BUS, kD2257_GPIO9_CONF1, (0<<6)|(1<<3)|(2<<1)|(0<<0) }, // 0x0C Input, AL, PD, + { PMU_IIC_BUS, kD2257_GPIO9_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms +#else + // GPIO_PMU_TO_BBPMU_RESET_R_L rdar://20064772 + { PMU_IIC_BUS, kD2257_GPIO5_CONF1, (0<<6)|(2<<3)|(2<<1)|(0<<0) }, // 0x14 Input, RE, PD, Low + { PMU_IIC_BUS, kD2257_GPIO5_CONF2, (1<<3)|(7<<0) }, // 0x0F VBUCK3, 1000ms + // GPIO_BB_TO_PMU_HOST_WAKE_L + { PMU_IIC_BUS, kD2257_GPIO9_CONF1, (0<<6)|(2<<3)|(2<<1)|(0<<0) }, // 0x14 Input, RE, PD, Low + { PMU_IIC_BUS, kD2257_GPIO9_CONF2, (1<<3)|(7<<0) }, // 0x0F VBUCK3, 1000ms +#endif + + // GPIO_CODEC_TO_PMU_HS_IRQ_L + { PMU_IIC_BUS, kD2257_GPIO10_CONF1, (0<<6)|(4<<3)|(1<<1)|(1<<0) }, // 0x23 Input, AE, PU, Wakeup + { PMU_IIC_BUS, kD2257_GPIO10_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // GPIO_CN_HALL_TO_PMU_IRQ_L + { PMU_IIC_BUS, kD2257_GPIO11_CONF1, (0<<6)|(4<<3)|(1<<1)|(0<<0) }, // 0x22 Input, AnyE, PU + { PMU_IIC_BUS, kD2257_GPIO11_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO_TS_TO_SOC_TO_PMU_IRQ + { PMU_IIC_BUS, kD2257_GPIO12_CONF1, (0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input, AH, No PU/PD, Wakeup + { PMU_IIC_BUS, kD2257_GPIO12_CONF2, (1<<3)|(1<<0) }, // 0x09 VBUCK3, 5ms + + // GPIO_GANGES_TO_SOC_TO_PMU_IRQ_L + { PMU_IIC_BUS, kD2257_GPIO13_CONF1, (0<<6)|(3<<3)|(0<<1)|(0<<0) }, // 0x18 Input, FE, No PU/PD + { PMU_IIC_BUS, kD2257_GPIO13_CONF2, (1<<3)|(2<<0) }, // 0x0A VBUCK3, 10ms + + // PCIE_WLAN_TO_PMU_WAKE_L + { PMU_IIC_BUS, kD2257_GPIO14_CONF1, (0<<6)|(2<<3)|(2<<1)|(0<<0) }, // 0x14 Input, RE, PD + { PMU_IIC_BUS, kD2257_GPIO14_CONF2, (1<<3)|(7<<0) }, // 0x0F VBUCK3, 1000ms + + // GPIO_PMU_TO_CODEC_RESET_L rdar://20218237 J99A Aria need to enable GPIO15 to take Codec out of reset + { PMU_IIC_BUS, kD2257_GPIO15_CONF1, (0<<6)|(3<<3)|(1<<1)|(0<<0) }, // 0x1A Input FE, PU, Low + { PMU_IIC_BUS, kD2257_GPIO15_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // J98a/J99a: Remove OTP override for GPIO_PMU_NAND_LOW_POWER_MODE + // We are diverting from IO spreadsheet and removing the OTP override from here because this GPIO + // is driven high later in target_late_init() which is the right place to do it. + + // GPIO_PMU_TO_BB_VBUS_DET + { PMU_IIC_BUS, kD2257_GPIO17_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO17_CONF2, (0<<3)|(0<<0) }, // 0x00 VCC_MAIN, no DEB + + // GPIO_PMU_TO_LCD_PWREN + { PMU_IIC_BUS, kD2257_GPIO18_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO18_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO_GANGES_TO_PMU_WAKE + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_SLP1,(0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input AH, No PU/PD, WakeUp + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_SLP2,(0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input AH, No PU/PD, WakeUp + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_SLP3,(0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input AH, No PU/PD, WakeUp + { PMU_IIC_BUS, kD2257_GPIO19_CONF1_OFF, (0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input AH, No PU/PD, WakeUp + { PMU_IIC_BUS, kD2257_GPIO19_CONF1, (0<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x01 Input AH, No PU/PD, WakeUp + { PMU_IIC_BUS, kD2257_GPIO19_CONF2, (3<<3)|(1<<0) }, // 0x19 PP1V8, 5ms + + // GPIO_PMU_TO_1V1_EXT_SW_ON + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_SLP1,(2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU, High + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_SLP2,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_SLP3,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO20_CONF1_OFF, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO20_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU, High + { PMU_IIC_BUS, kD2257_GPIO20_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO_PMU_TO_1V8_EXT_SW2_ON + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_SLP1,(2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU, High + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_SLP2,(2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU, High + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_SLP3,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO21_CONF1_OFF, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO21_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU, High + { PMU_IIC_BUS, kD2257_GPIO21_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB + + // GPIO_PMU_TO_3V3_EXT_SW_ON + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_SLP1,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_SLP2,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_SLP3,(2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1_OFF, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // 0x80 Output(Push-Pull), Level, No PU, Low + { PMU_IIC_BUS, kD2257_GPIO22_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // 0x81 Output(Push-Pull), Level, No PU, High + { PMU_IIC_BUS, kD2257_GPIO22_CONF2, (1<<3)|(0<<0) }, // 0x08 VBUCK3, no DEB +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xff }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x7f }, + { PMU_IIC_BUS, kD2257_WLED_CTRL1, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kD2257_WLED_CTRL2, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDA_EN, 0x1f }, // enable LED Power + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDB_EN, 0x1f }, // enable LED Power +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDA_EN, 0x0 }, // disable LED Power + { PMU_IIC_BUS, kD2257_PWRONOFF_WLEDB_EN, 0x0 }, // disable LED Power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK0_VSEL } +}; + +// It's VDD FIXED! used for RAM inside the SOC +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2257_BUCK5_VSEL } +}; + +// This is indexed with POWER_RAIL_*, I really just need to use the +// index in LDO[] +target_rails_t target_rails = { + { 0x10, 450, 1250, 3125 }, // POWER_RAIL_CPU, BUCK0 + { 0x15, 600, 1400, 3125 }, // POWER_RAIL_VDD_FIXED BUCK5 + { 0x12, 600, 1400, 3125 }, // POWER_RAIL_SOC, BUCK2 + + { 0x17, 600, 1400, 3125 }, // POWER_RAIL_CPU_RAM, BUCK7 + { 0x11, 450, 1250, 3125 }, // POWER_RAIL_GPU, BUCK1 + { 0x18, 600, 1400, 3125 }, // POWER_RAIL_GPU_RAM, BUCK8 +}; + +#endif // POWERCONFIG_PMU_SETUP + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_MAX_USB_INPUT_CURRENT 2400 +#define TARGET_HAS_SMARTPORT 1 + +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 + +#define ACC_PWR_LDO (6) + +#define GASGAUGE_BATTERYID_BLOCK 1 + +#endif diff --git a/target/ipad6d/include/target/uartconfig.h b/target/ipad6d/include/target/uartconfig.h new file mode 100644 index 0000000..ca81b1e --- /dev/null +++ b/target/ipad6d/include/target/uartconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#endif diff --git a/target/ipad6d/include/target/usbconfig.h b/target/ipad6d/include/target/usbconfig.h new file mode 100644 index 0000000..1920f01 --- /dev/null +++ b/target/ipad6d/include/target/usbconfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_OTGTUNE0 + +#undef USBPHY_OTGTUNE0 +#define USBPHY_OTGTUNE0 (0x37377BA3) + +#endif /* USBPHY_OTGTUNE0 */ + +#ifdef USBPHY_OTGTUNE1 + +#undef USBPHY_OTGTUNE1 +#define USBPHY_OTGTUNE1 (0x20C04) + +#endif /* USBPHY_OTGTUNE1 */ + + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/ipad6d/init.c b/target/ipad6d/init.c new file mode 100644 index 0000000..1b87447 --- /dev/null +++ b/target/ipad6d/init.c @@ -0,0 +1,586 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#include +#endif +#if TARGET_USES_BLEND_CM +#include +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, -90); + +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +dp_t dp; +#endif + +typedef enum { + DISPLAY_PANEL_TYPE_TULIP = 0, + DISPLAY_PANEL_TYPE_COUNT +} ipad6d_display_t; + +#if WITH_ENV +static const char *display_panel_name[] = { + [DISPLAY_PANEL_TYPE_TULIP] = "ipad6d", +}; +#endif + +// AP settings for: +// +// IO GPIO 298: AOP_I2CM_SCL (AOP GPIO 10 ) -> SPI_ACCEL_CS_L +// IO GPIO 299: AOP_FUNC[0] (AOP GPIO 11) -> SPI_MAGNESIUM_CS_L +// IO GPIO 303: AOP_FUNC[4] (AOP GPIO 15) -> SPI_CARBON_CS_L +// IO GPIO 305: AOP_FUNC[6] (AOP GPIO 17) -> SPI_PHOSPHORUS_CS_L +static const uint32_t fixup_list_ap[] = { + GPIOC(GPIOC_1, (10 / 8), (10 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + GPIOC(GPIOC_1, (11 / 8), (11 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + GPIOC(GPIOC_1, (15 / 8), (15 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + GPIOC(GPIOC_1, (17 / 8), (17 % 8)), + (FUNC_ALT0 | PULL_UP | DRIVE_S7 | SLOW_SLEW), + + UINT32_MAX, UINT32_MAX +}; + +static uint32_t gpio_board_rev; +static bool gpio_board_rev_valid = false; + +static uint32_t ipad6d_get_board_rev(void); +static void ipad6d_assert_display_type(void); + +#if WITH_HW_POWER + int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); +#endif + +static uint32_t +ipad6d_get_board_rev (void) +{ + /* + * Sequence: + * - Set GPIO as input. + * - Enable PU and disable PD. + * - Read + */ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return (gpio_board_rev); +} + +static uint32_t +ipad6d_get_display_type (void) +{ + return (DISPLAY_PANEL_TYPE_TULIP); +} + +int +target_get_boot_battery_capacity (void) +{ + int temp = 0; +#if WITH_HW_GASGAUGE + if (gasgauge_read_temperature(&temp) != 0) { + temp = 0; // defensive + } +#endif + + if (temp > 500) { + return (0); // rely on SOC1 clear only + } + + return (50); // @see rdar://16587240 +} + +uint32_t +target_get_display_panel_type (void) +{ + return (ipad6d_get_display_type()); +} + +uint32_t +target_get_board_rev (void) +{ + if (!gpio_board_rev_valid) { + ipad6d_get_board_rev(); + } + + return (gpio_board_rev); +} + +void +target_early_init (void) +{ + uint32_t board_rev = target_get_board_rev(); + uint32_t board_id = platform_get_board_id(); + + dprintf(DEBUG_INFO, "%s: board id: %x, board rev: %x\n", + __func__, board_id, board_rev); +} + +void +target_late_init (void) +{ + if (target_config_ap() && target_get_board_rev() < J99a_AP_DVT_BOARD_REV_1) { + dprintf(DEBUG_INFO, "PRE-DVT MLBs are deprecated\n"); + platform_not_supported(); + } + else if (target_config_dev() && target_get_board_rev() < J99a_DEV2_BOARD_REV) { + dprintf(DEBUG_INFO, "PRE-DEV2 boards are deprecated\n"); + platform_not_supported(); + } + power_set_gpio(GPIO_PMU_NAND_LOW_POWER_MODE, 1, 1); +} + +void +target_init (void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + // apply AOP fixups after the above are done + gpio_fixup_pinconfig(fixup_list_ap); +} + +void +target_quiesce_hardware (void) +{ +} + +void +target_poweroff (void) +{ +} + +int +target_bootprep (enum boot_target target) +{ + return 0; +} + +bool +target_should_recover (void) +{ + return (platform_get_request_dfu2() && power_has_usb()); +} + +bool +target_should_poweron (bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) { + *cold_button_boot = true; + } +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return (!*cold_button_boot || platform_get_request_dfu1()); +} + +bool +target_should_poweroff (bool at_boot) +{ + return (platform_get_request_dfu1() && (!at_boot || !power_has_usb())); +} + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + dp.mode = kDPControllerMode_Slave; + dp.type = kDPControllerType_EDP; + dp.min_link_rate = kLinkRate324Gbps; + dp.max_link_rate = kLinkRate324Gbps; + dp.lanes = 0x4; + dp.ssc = 0x0; + dp.alpm = 0x1; + dp.vrr_enable = 0x1; + dp.vrr_on = 0x1; + dp.rx_n1= 25; + dp.rx_n2= 2; + dp.rx_n3= 16030; + dp.rx_n5= 0x2; + dp.fast_link_training = true; + return ((void *)(&dp)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void +target_setup_default_environment (void) +{ + uint32_t display_id = ipad6d_get_display_type(); + + // boot-device is set in platform's init.c + env_set("boot-partition", "0", 0); + + env_set("boot-path", + "/System/Library/Caches/com.apple.kernelcaches/kernelcache", 0); + + env_set("display-color-space","RGB888", 0); + + env_set("display-timing", display_panel_name[display_id], 0); + env_set("adbe-tunables", display_panel_name[display_id], 0); + env_set("adfe-tunables", display_panel_name[display_id], 0); +} + +#endif + +#if WITH_HW_LM3534 +uint8_t +target_lm3534_gpr (uint32_t ctlr) +{ + uint8_t gpr = (1 << 1) | (1 << 0); // (ramp disable) | (chip enable) + +#if TARGET_DISPLAY_D520 + gpr |= (1 << 4); // (ovp_select_21v) +#elif TARGET_DISPLAY_D620 + if (ctlr == 1) + gpr |= (1 << 4); // (ovp_select_21v) +#else +#error "unknown display type" +#endif + + return gpr; +} +#endif + +#if WITH_DEVICETREE + +void +hid_update_device_tree(void) +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (dt_find_node(0, "arm-io/spi3/multi-touch", &node)) { + propName = "multitouch-to-display-offset"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('MtDO', propData, propSize); + } + + propName = "firefly-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FfCl', propData, propSize); + } + } +} + +int +target_update_device_tree (void) +{ + uint32_t propSize; + char *propName; + void *propData; + DTNode *node; + +#if WITH_HW_DISPLAY_EDP + DTNode *clcd_node = NULL, *backlight_node = NULL, *lcd_node = NULL; + DTNode *lpdp_node = NULL; +#endif + +#if WITH_HW_DISPLAY_EDP + if (FindNode(0, DP_DTPATH, &node)) { + extern int edp_update_device_tree(DTNode *edp_node, DTNode *lcd_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "arm-io/disp0", &clcd_node); + FindNode(0, DP_DTPATH "/lcd", &lcd_node); + FindNode(0, "backlight", &backlight_node); + edp_update_device_tree(node, lcd_node, clcd_node, backlight_node); + + extern int lpdp_phy_update_device_tree(DTNode *lpdp_node); + FindNode(0, DPPHY_DTPATH, &lpdp_node); + lpdp_phy_update_device_tree(lpdp_node); + + } +#endif +#if TARGET_USES_BLEND_CM + if (dt_find_node(0, "arm-io/disp0", &node)) { + dt_set_prop(node, "cm-post-blend-degamma", target_blend_degamma_tables, sizeof(target_blend_degamma_tables)); + dt_set_prop(node, "cm-post-blend-engamma", target_blend_engamma_tables, sizeof(target_blend_engamma_tables)); + } +#endif + + // Update the als calibration data for all nodes that may be present on the dev board + if (dt_find_node(0, "arm-io/i2c3/als1", &node)) { + propName = "alsCalibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + if (dt_find_node(0, "arm-io/i2c3/als2", &node)) { + propName = "alsCalibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/compass", &node)) { + propName = "compass-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + propName = "compass-orientation"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CRot', propData, propSize); + } + } + + // Update the gyro calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/gyro", &node)) { + propName = "gyro-orientation"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/accel", &node)) { + propName = "accel-orientation"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (dt_find_node(0, "arm-io/aop/iop-aop-nub/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (dt_get_prop(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + + + if (FindNode(0, "arm-io/i2c1/audio-speaker-cn-left", &node)) { + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + } + + hid_update_device_tree(); + + return (0); +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries +// (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t * +target_color_map_init (enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + + fail: + return NULL; +} +#endif // WITH_PAINT + +#if !WITH_HW_POWER + +bool +power_needs_precharge (void) +{ + return false; +} + +void +power_cancel_buttonwait (void) +{ +} + +bool +power_do_chargetrap (void) +{ + return false; +} + +bool +power_is_suspended (void) +{ + return false; +} + +void +power_will_resume (void) +{ +} + +bool +power_has_usb (void) +{ + return false; +} + +int +power_read_dock_id (unsigned *id) +{ + return -1; +} + +bool +power_get_diags_dock (void) +{ + return false; +} + +uint32_t +power_get_boot_battery_level (void) +{ + return 0; +} + +int +power_get_nvram (uint8_t key, uint8_t *data) +{ + return -1; +} + +int +power_set_nvram (uint8_t key, uint8_t data) +{ + return -1; +} + +int +power_set_soc_voltage (unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void +power_set_usb_state (bool configured, bool suspended) +{ +} + +int +power_backlight_enable (uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/ipad6d/pinconfig.c b/target/ipad6d/pinconfig.c new file mode 100644 index 0000000..c491203 --- /dev/null +++ b/target/ipad6d/pinconfig.c @@ -0,0 +1,1476 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 1.7 + I/O Spreadsheet tracker: + Conversion command: ./tools/csvtopinconfig.py --sheet SOC --soc elba --config-column 'j99a:J99A Config' --config-column 'j98a:J98A Config' --radar '' --copyright 2015 +*/ + +#include +#include +#include +#include +#include +#include + +enum { + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_FUNC1_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_FUNC1_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, +}; + + +static const uint32_t enum_map[] = { + [GPIOCFG_CFG_DISABLED] = CFG_DISABLED, + [GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW] = CFG_DISABLED | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW] = CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW] = CFG_DISABLED | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_S3_SLOW_SLEW] = CFG_DISABLED | PULL_UP | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_S4_SLOW_SLEW] = CFG_DISABLED | PULL_UP | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW] = CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW] = CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW] = CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S3_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC1_DRIVE_S3_SLOW_SLEW] = CFG_FUNC1 | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC1_DRIVE_S7_SLOW_SLEW] = CFG_FUNC1 | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW] = CFG_IN | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW] = CFG_IN | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW] = CFG_IN | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW] = CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_DOWN | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW] = CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_DOWN | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW] = CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_UP | DRIVE_S3 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW] = CFG_IN | PULL_UP | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW] = CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_UP | DRIVE_S7 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW] = CFG_OUT_0 | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW] = CFG_OUT_0 | DRIVE_S4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW] = CFG_OUT_0 | DRIVE_S7 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW] = CFG_OUT_1 | DRIVE_S3 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW] = CFG_OUT_1 | DRIVE_S7 | SLOW_SLEW, +}; + + +static const uint8_t pinconfig_j98aap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_CODEC_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_CODEC_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_CODEC_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_CODEC_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> NC_GPIO_SOC_TO_AUDIO_FH_KEEPALIVE + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC2AJ_HS4_SHUNT_EN + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 19 : I2S1_MCK -> NC_I2S1_MCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC2CODEC_ASP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC2CODEC_ASP_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : NAND_SYS_CLK -> NAND_SYS_CLK_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S3_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 27 : UART1_TXD -> UART_SOC2BB_TX + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 28 : UART1_RXD -> UART_BB2SOC_TX + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 29 : UART1_RTSN -> UART_SOC2BB_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 30 : UART1_CTSN -> UART_BB2SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_SOC2AJ_HS3_SHUNT_EN + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC2CODEC_XSP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC2CODEC_XSP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC2SOC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC2CODEC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 36 : I2S0_MCK -> I2S_SOC_TO_CODEC_MCLK_R + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 64 : I2S4_MCK -> NC_GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 69 : I2S2_MCK -> I2S_SOC_TO_SPKRAMP_FH_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_SPKRAMP_FH_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_SPKRAMP_FH_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_SPKRAMP_FH_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_SPKRAMP_FH_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_S3_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_FH_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_CN_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC1_DRIVE_S3_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> GPIO_SPKAMP_FH_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 86 : GPIO[12] -> GPIO_SPKAMP_FH_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 87 : GPIO[13] -> PCIE_SOC_TO_BB_RESET_L + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V25_CAM_LDO_EN + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 97 : SPI0_SSIN -> GPIO_USBPD_TO_SOC_IRQ + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 101 : PCIE_PERST3_N -> GPIO_SOC_TO_BB_WAKE_MODEM + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 102 : PCIE_PERST4_N -> PCIE_SOC_TO_USB3_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 108 : PCIE_CLKREQ4_N -> PCIE_USB3_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 119 : GPIO[47] -> GPIO_SOC_TO_1V05_USB3_LDO_EN + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 124 : SKEY_L -> NC_SKEY_ID + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 137 : UART7_TXD -> NC_GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_BEACON_EN + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 139 : CLK32K_OUT -> NC_CLK32K_OUT_24MHZ + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 175 : TMR32_PWM1 -> SWD_USBPD_SWCLK + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_CN_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_USB3_XBAR_EN_PULSE_L + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 181 : GPIO[21] -> GPIO_SOC_TO_USB3_XBAR_DIS_PULSE_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 182 : GPIO[22] -> GPIO_SPKAMP_CN_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 183 : GPIO[23] -> GPIO_USB3_TO_SOC_SMI_L + +/* Port 23 */ + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 184 : GPIO[24] -> GPIO_SOC_TO_ORION_RESET_H_EDGE + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 188 : DWI_DO -> DWI_SOC_TO_BEACON_DO + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 191 : PMGR_SSCLK1 -> DWI_SOC_TO_BEACON_CLK + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 196 : I2S3_MCK -> I2S_SOC_TO_SPKRAMP_CN_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_SPKRAMP_CN_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_SPKRAMP_CN_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_SPKRAMP_CN_DOUT + +/* Port 25 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_SPKRAMP_CN_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 203 : GPIO[29] -> GPIO_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 205 : GPIO[31] -> GPIO_USB3_TO_SOC_WAKE_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V9_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_GANGES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 213 : GPIO[39] -> SWD_USBPD_SWDIO + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_j98aap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_UART_AOP_TO_TOUCH_TX + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_GPIO_TOUCH_TO_AOP_DATA_REQUEST + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_COMPASS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_COMPASS_TO_AOP_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 13 : AOP_FUNC[2] -> NC_GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_SWD_USBPD_SWCLK + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 20 : AOP_FUNC[9] -> NC_SWD_USBPD_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> NC_SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 24 : AOP_I2S_MCK -> NC_I2S_AOP_MCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> NC_I2S_SOC2CODEC_ASP_BCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> NC_I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 27 : AOP_I2S_DIN -> NC_I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_j98adev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_CODEC_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_CODEC_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_CODEC_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_CODEC_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> NC_GPIO_SOC_TO_AUDIO_FH_KEEPALIVE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC2AJ_HS4_SHUNT_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 19 : I2S1_MCK -> NC_I2S1_MCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC2CODEC_ASP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC2CODEC_ASP_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 24 : NAND_SYS_CLK -> NAND_SYS_CLK_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 27 : UART1_TXD -> UART_SOC2BB_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 28 : UART1_RXD -> UART_BB2SOC_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 29 : UART1_RTSN -> UART_SOC2BB_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 30 : UART1_CTSN -> UART_BB2SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_SOC2AJ_HS3_SHUNT_EN + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC2CODEC_XSP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC2CODEC_XSP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC2SOC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC2CODEC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 36 : I2S0_MCK -> I2S_SOC_TO_CODEC_MCLK_R + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 64 : I2S4_MCK -> NC_GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 69 : I2S2_MCK -> I2S_SOC_TO_SPKRAMP_FH_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_SPKRAMP_FH_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_SPKRAMP_FH_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_SPKRAMP_FH_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_SPKRAMP_FH_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_S4_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_FH_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_CN_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC1_DRIVE_S7_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> GPIO_SPKAMP_FH_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 86 : GPIO[12] -> GPIO_SPKAMP_FH_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 87 : GPIO[13] -> PCIE_SOC_TO_BB_RESET_L + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V25_CAM_LDO_EN + GPIOCFG_CFG_DISABLED_DRIVE_S4_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 97 : SPI0_SSIN -> GPIO_USBPD_TO_SOC_IRQ + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 101 : PCIE_PERST3_N -> GPIO_SOC_TO_BB_WAKE_MODEM + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 102 : PCIE_PERST4_N -> PCIE_SOC_TO_USB3_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 108 : PCIE_CLKREQ4_N -> PCIE_USB3_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 119 : GPIO[47] -> GPIO_SOC_TO_1V05_USB3_LDO_EN + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 124 : SKEY_L -> NC_SKEY_ID + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 137 : UART7_TXD -> NC_GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_BEACON_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 139 : CLK32K_OUT -> NC_CLK32K_OUT_24MHZ + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 175 : TMR32_PWM1 -> SWD_USBPD_SWCLK + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_CN_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_USB3_XBAR_EN_PULSE_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 181 : GPIO[21] -> GPIO_SOC_TO_USB3_XBAR_DIS_PULSE_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 182 : GPIO[22] -> GPIO_SPKAMP_CN_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 183 : GPIO[23] -> GPIO_USB3_TO_SOC_SMI_L + +/* Port 23 */ + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 184 : GPIO[24] -> GPIO_SOC_TO_ORION_RESET_H_EDGE + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 188 : DWI_DO -> DWI_SOC_TO_BEACON_DO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 191 : PMGR_SSCLK1 -> DWI_SOC_TO_BEACON_CLK + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 196 : I2S3_MCK -> I2S_SOC_TO_SPKRAMP_CN_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_SPKRAMP_CN_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_SPKRAMP_CN_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_SPKRAMP_CN_DOUT + +/* Port 25 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_SPKRAMP_CN_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 203 : GPIO[29] -> GPIO_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 205 : GPIO[31] -> GPIO_USB3_TO_SOC_WAKE_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V9_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_GANGES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 213 : GPIO[39] -> SWD_USBPD_SWDIO + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_j98adev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_UART_AOP_TO_TOUCH_TX + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_GPIO_TOUCH_TO_AOP_DATA_REQUEST + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_COMPASS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_COMPASS_TO_AOP_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 13 : AOP_FUNC[2] -> NC_GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_SWD_USBPD_SWCLK + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 20 : AOP_FUNC[9] -> NC_SWD_USBPD_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> NC_SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 24 : AOP_I2S_MCK -> NC_I2S_AOP_MCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> NC_I2S_SOC2CODEC_ASP_BCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> NC_I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 27 : AOP_I2S_DIN -> NC_I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_j99aap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_CODEC_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_CODEC_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_CODEC_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_CODEC_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> NC_GPIO_SOC_TO_AUDIO_FH_KEEPALIVE + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC2AJ_HS4_SHUNT_EN + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 19 : I2S1_MCK -> NC_I2S1_MCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC2CODEC_ASP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC2CODEC_ASP_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S4_SLOW_SLEW, // 24 : NAND_SYS_CLK -> NAND_SYS_CLK_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S3_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 27 : UART1_TXD -> UART_SOC2BB_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 28 : UART1_RXD -> UART_BB2SOC_TX + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 29 : UART1_RTSN -> UART_SOC2BB_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 30 : UART1_CTSN -> UART_BB2SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_SOC2AJ_HS3_SHUNT_EN + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC2CODEC_XSP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC2CODEC_XSP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC2SOC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC2CODEC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 36 : I2S0_MCK -> I2S_SOC_TO_CODEC_MCLK_R + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 64 : I2S4_MCK -> NC_GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 69 : I2S2_MCK -> I2S_SOC_TO_SPKRAMP_FH_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_SPKRAMP_FH_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_SPKRAMP_FH_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_SPKRAMP_FH_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_SPKRAMP_FH_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_FH_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_CN_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC1_DRIVE_S3_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> GPIO_SPKAMP_FH_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 86 : GPIO[12] -> GPIO_SPKAMP_FH_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 87 : GPIO[13] -> PCIE_SOC_TO_BB_RESET_L + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V25_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 97 : SPI0_SSIN -> GPIO_USBPD_TO_SOC_IRQ + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 101 : PCIE_PERST3_N -> GPIO_SOC_TO_BB_WAKE_MODEM + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 102 : PCIE_PERST4_N -> PCIE_SOC_TO_USB3_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 108 : PCIE_CLKREQ4_N -> PCIE_USB3_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 119 : GPIO[47] -> GPIO_SOC_TO_1V05_USB3_LDO_EN + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 124 : SKEY_L -> NC_SKEY_ID + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 137 : UART7_TXD -> NC_GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_BEACON_EN + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 139 : CLK32K_OUT -> NC_CLK32K_OUT_24MHZ + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 175 : TMR32_PWM1 -> SWD_USBPD_SWCLK + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_CN_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_USB3_XBAR_EN_PULSE_L + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 181 : GPIO[21] -> GPIO_SOC_TO_USB3_XBAR_DIS_PULSE_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 182 : GPIO[22] -> GPIO_SPKAMP_CN_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 183 : GPIO[23] -> GPIO_USB3_TO_SOC_SMI_L + +/* Port 23 */ + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 184 : GPIO[24] -> GPIO_SOC_TO_ORION_RESET_H_EDGE + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 188 : DWI_DO -> DWI_SOC_TO_BEACON_DO + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 191 : PMGR_SSCLK1 -> DWI_SOC_TO_BEACON_CLK + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 196 : I2S3_MCK -> I2S_SOC_TO_SPKRAMP_CN_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_SPKRAMP_CN_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_SPKRAMP_CN_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_SPKRAMP_CN_DOUT + +/* Port 25 */ + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_SPKRAMP_CN_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 203 : GPIO[29] -> GPIO_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 205 : GPIO[31] -> GPIO_USB3_TO_SOC_WAKE_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V9_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_GANGES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 213 : GPIO[39] -> SWD_USBPD_SWDIO + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_j99aap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S3_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_IN_DRIVE_S3_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_FUNC0_DRIVE_S3_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_UART_AOP_TO_TOUCH_TX + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_GPIO_TOUCH_TO_AOP_DATA_REQUEST + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_COMPASS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_COMPASS_TO_AOP_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 13 : AOP_FUNC[2] -> NC_GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S3_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_SWD_USBPD_SWCLK + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S3_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 20 : AOP_FUNC[9] -> NC_SWD_USBPD_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> NC_SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 24 : AOP_I2S_MCK -> NC_I2S_AOP_MCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> NC_I2S_SOC2CODEC_ASP_BCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> NC_I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_DISABLED_DRIVE_S3_SLOW_SLEW, // 27 : AOP_I2S_DIN -> NC_I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_j99adev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : SPI1_SCLK -> SPI_CODEC_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : SPI1_MOSI -> SPI_CODEC_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : SPI1_MISO -> SPI_CODEC_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 3 : SPI1_SSIN -> SPI_CODEC_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 4 : ISP_I2C1_SDA -> ISP_FRONT_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 5 : ISP_I2C1_SCL -> ISP_FRONT_CAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 6 : ISP_I2C0_SDA -> ISP_REAR_CAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 7 : ISP_I2C0_SCL -> ISP_REAR_CAM_SCL + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 8 : SENSOR0_ISTRB -> NC_GPIO_SOC_TO_AUDIO_FH_KEEPALIVE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 9 : SENSOR0_RST -> GPIO_SOC_TO_REAR_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 10 : SENSOR0_CLK -> CLK_SOC_TO_REAR_CAM_12MHZ_R + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 11 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : SENSOR1_ISTRB -> GPIO_BTN_VOL_UP_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 13 : SENSOR1_RST -> GPIO_SOC_TO_FRONT_CAM_SHTDWN_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 14 : SENSOR1_CLK -> CLK_SOC_TO_FRONT_CAM_12MHZ_R + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 15 : SENSOR1_XSHUTDOWN -> GPIO_BTN_VOL_DOWN_L + +/* Port 2 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 16 : GPIO[16] -> GPIO_BRD_ID3 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 17 : GPIO[17] -> GPIO_SOC2AJ_HS4_SHUNT_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : GPIO[18] -> GPIO_BOOT_CFG0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 19 : I2S1_MCK -> NC_I2S1_MCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S1_BCLK -> I2S_SOC2CODEC_ASP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 21 : I2S1_LRCK -> I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 22 : I2S1_DIN -> I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 23 : I2S1_DOUT -> I2S_SOC2CODEC_ASP_DOUT + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 24 : NAND_SYS_CLK -> NAND_SYS_CLK_24MHZ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_S7_SLOW_SLEW, // 25 : S3E0_RESETN -> GPIO_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 26 : S3E1_RESETN -> NC_PCIE_S3E1_RESET + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 27 : UART1_TXD -> UART_SOC2BB_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 28 : UART1_RXD -> UART_BB2SOC_TX + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 29 : UART1_RTSN -> UART_SOC2BB_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 30 : UART1_CTSN -> UART_BB2SOC_RTS_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 31 : GPIO[43] -> GPIO_SOC2AJ_HS3_SHUNT_EN + +/* Port 4 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 32 : I2S0_BCLK -> I2S_SOC2CODEC_XSP_BCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 33 : I2S0_LRCK -> I2S_SOC2CODEC_XSP_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 34 : I2S0_DIN -> I2S_CODEC2SOC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 35 : I2S0_DOUT -> I2S_SOC2CODEC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 36 : I2S0_MCK -> I2S_SOC_TO_CODEC_MCLK_R + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 5 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 6 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 64 : I2S4_MCK -> NC_GPIO_SOC_TO_BB_MESA_ON + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 65 : I2S4_BCLK -> I2S_SOC_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 66 : I2S4_LRCK -> I2S_SOC_TO_BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 67 : I2S4_DIN -> I2S_BT_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 68 : I2S4_DOUT -> I2S_SOC_TO_BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 69 : I2S2_MCK -> I2S_SOC_TO_SPKRAMP_FH_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 70 : I2S2_BCLK -> I2S_SOC_TO_SPKRAMP_FH_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 71 : I2S2_LRCK -> I2S_SOC_TO_SPKRAMP_FH_LRCK + +/* Port 9 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 72 : I2S2_DIN -> I2S_SPKRAMP_FH_TO_SOC_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 73 : I2S2_DOUT -> I2S_SOC_TO_SPKRAMP_FH_DOUT + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 74 : GPIO[0] -> GPIO_CODEC_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S4_SLOW_SLEW, // 75 : GPIO[1] -> GPIO_SOC_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 76 : GPIO[2] -> GPIO_SOC_TO_NAND_FW_STRAP + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 77 : GPIO[3] -> GPIO_BB_TO_SOC_RESET_DET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 78 : GPIO[4] -> GPIO_BB_IPC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 79 : GPIO[5] -> GPIO_FH_ALS_TO_SOC_IRQ_L + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 80 : GPIO[6] -> NC_DISPLAY_ID0 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 81 : GPIO[7] -> GPIO_CN_ALS_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 82 : GPIO[8] -> GPIO_BB_TO_SOC_GPS_SYNC + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 83 : GPIO[9] -> GPIO_SOC_TO_BB_RESET_L + GPIOCFG_CFG_FUNC1_DRIVE_S7_SLOW_SLEW, // 84 : GPIO[10] -> GPIO_SOC_TO_KONA_DISPLAY_SYNC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 85 : GPIO[11] -> GPIO_SPKAMP_FH_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 86 : GPIO[12] -> GPIO_SPKAMP_FH_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 87 : GPIO[13] -> PCIE_SOC_TO_BB_RESET_L + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 88 : GPIO[14] -> GPIO_SOC_TO_1V25_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S4_SLOW_SLEW, // 89 : GPIO[15] -> GPIO_SOC_TO_BB_COREDUMP + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 90 : UART3_TXD -> UART_SOC_TO_BT_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 91 : UART3_RXD -> UART_BT_TO_SOC_TX + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 92 : UART3_RTSN -> UART_SOC_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 93 : UART3_CTSN -> UART_BT_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 94 : SPI0_SCLK -> GPIO_BRD_ID0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 95 : SPI0_MOSI -> GPIO_BRD_ID1 + +/* Port 12 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 96 : SPI0_MISO -> GPIO_BRD_ID2 + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 97 : SPI0_SSIN -> GPIO_USBPD_TO_SOC_IRQ + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 98 : PCIE_PERST0_N -> PCIE_SOC_TO_NAND_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 99 : PCIE_PERST1_N -> NC_PCIE_PERST1 + GPIOCFG_CFG_IN_DRIVE_S4_SLOW_SLEW, // 100 : PCIE_PERST2_N -> PCIE_SOC_TO_WLAN_RESET_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 101 : PCIE_PERST3_N -> GPIO_SOC_TO_BB_WAKE_MODEM + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 102 : PCIE_PERST4_N -> PCIE_SOC_TO_USB3_RESET_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 103 : PCIE_PERST5_N -> NC_PCIE_PERST5 + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 104 : PCIE_CLKREQ0_N -> PCIE_NAND_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> NC_PCIE_CLKREQ1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 106 : PCIE_CLKREQ2_N -> PCIE_WLAN_TO_SOC_CLKREQ_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 107 : PCIE_CLKREQ3_N -> PCIE_BB_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 108 : PCIE_CLKREQ4_N -> PCIE_USB3_TO_SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 109 : PCIE_CLKREQ5_N -> NC_PCIE_CLKREQ5 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 110 : UART2_TXD -> UART_SOC_TO_WLAN_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 111 : UART2_RXD -> UART_WLAN_TO_SOC_TX + +/* Port 14 */ + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 112 : UART2_RTSN -> UART_SOC_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 113 : UART2_CTSN -> UART_WLAN_TO_SOC_RTS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C3_SDA -> I2C3_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C3_SCL -> I2C3_SCL_1V8 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 116 : GPIO[44] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 117 : GPIO[45] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 118 : GPIO[46] -> GPIO_BRD_REV2 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 119 : GPIO[47] -> GPIO_SOC_TO_1V05_USB3_LDO_EN + +/* Port 15 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 120 : GPIO[48] -> GPIO_TS_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 121 : GPIO[49] -> GPIO_BRD_REV3 + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 122 : MENU_KEY_L -> GPIO_BTN_HOME_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 123 : HOLD_KEY_L -> GPIO_BTN_ONOFF_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 124 : SKEY_L -> NC_SKEY_ID + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 128 : SWD_TMS2 -> SWD_NAND_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 129 : SWD_TMS3 -> SWD_KONA_SWDIO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 130 : UART5_RTXD -> UART_BATT_HDQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2C2_SDA -> I2C2_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2C2_SCL -> I2C2_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 133 : UART4_TXD -> UART_SOC_TO_ROTTERDAM_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 134 : UART4_RXD -> UART_ROTTERDAM_TO_SOC_TX + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW, // 135 : UART4_RTSN -> UART_SOC_TO_ROTTERDAM_RTS_L + +/* Port 17 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 136 : UART4_CTSN -> UART_ROTTERDAM_TO_SOC_RTS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 137 : UART7_TXD -> NC_GPIO_SOC_TO_3V3_TOUCH_EXT_SW_ON + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 138 : UART7_RXD -> GPIO_SOC_TO_BEACON_EN + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 139 : CLK32K_OUT -> NC_CLK32K_OUT_24MHZ + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 140 : DP_WAKEUP0 -> NC_DP_WAKEUP0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 141 : DP_WAKEUP1 -> NC_DP_WAKEUP1 + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 160 : SPI2_SCLK -> SPI_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 161 : SPI2_MOSI -> SPI_MESA_MOSI + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 162 : SPI2_MISO -> SPI_MESA_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 163 : SPI2_SSIN -> GPIO_MESA_TO_SOC_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 164 : I2C0_SDA -> I2C0_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 165 : I2C0_SCL -> I2C0_SCL_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 166 : SPI3_SCLK -> SPI_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 167 : SPI3_MOSI -> SPI_TOUCH_MOSI + +/* Port 21 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 168 : SPI3_MISO -> SPI_TOUCH_MISO + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 169 : SPI3_SSIN -> SPI_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 170 : UART0_TXD -> UART_SOC_TO_DEBUG_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 171 : UART0_RXD -> UART_DEBUG_TO_SOC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 172 : UART6_TXD -> UART_SOC_TO_ACC_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 173 : UART6_RXD -> UART_ACC_TO_SOC_TX + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 174 : TMR32_PWM0 -> GPIO_SOC_TO_WLAN_DEVICE_WAKE + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 175 : TMR32_PWM1 -> SWD_USBPD_SWCLK + +/* Port 22 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 176 : TMR32_PWM2 -> NC_TMR32_PWM2 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 177 : I2C1_SDA -> I2C1_SDA_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 178 : I2C1_SCL -> I2C1_SCL_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 179 : GPIO[19] -> GPIO_SPKAMP_CN_RIGHT_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 180 : GPIO[20] -> GPIO_SOC_TO_USB3_XBAR_EN_PULSE_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 181 : GPIO[21] -> GPIO_SOC_TO_USB3_XBAR_DIS_PULSE_L + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 182 : GPIO[22] -> GPIO_SPKAMP_CN_LEFT_TO_SOC_IRQ_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 183 : GPIO[23] -> GPIO_USB3_TO_SOC_SMI_L + +/* Port 23 */ + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 184 : GPIO[24] -> GPIO_SOC_TO_ORION_RESET_H_EDGE + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 185 : GPIO[25] -> GPIO_BOOT_CFG1 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 186 : GPIO[26] -> GPIO_FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 187 : PSPI_MOSI -> SPI_SOC_TO_PMU_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 188 : DWI_DO -> DWI_SOC_TO_BEACON_DO + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 189 : PMGR_MISO -> SPI_PMU_TO_SOC_DATA + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 190 : PMGR_SCLK0 -> SPI_SOC_TO_PMU_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 191 : PMGR_SSCLK1 -> DWI_SOC_TO_BEACON_CLK + +/* Port 24 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 192 : DROOP -> SOCHOT0_PMU_TO_SOC_L + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 193 : SOCHOT1 -> SOCHOT1_SOC_TO_PMU_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 194 : EDP_HPD0 -> LPDP_TCON_TO_SOC_HPD + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 195 : EDP_HPD1 -> NC_EDP_HPD1 + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 196 : I2S3_MCK -> I2S_SOC_TO_SPKRAMP_CN_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 197 : I2S3_BCLK -> I2S_SOC_TO_SPKRAMP_CN_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 198 : I2S3_LRCK -> I2S_SOC_TO_SPKRAMP_CN_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 199 : I2S3_DOUT -> I2S_SOC_TO_SPKRAMP_CN_DOUT + +/* Port 25 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 200 : I2S3_DIN -> I2S_SPKRAMP_CN_TO_SOC_DOUT + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 201 : GPIO[27] -> TP_GPIO_DFU_STATUS + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 202 : GPIO[28] -> GPIO_BOOT_CFG2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 203 : GPIO[29] -> GPIO_BRD_ID4 + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 204 : GPIO[30] -> GPIO_SOC_TO_BT_TO_TOUCH_TS_SYNC + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 205 : GPIO[31] -> GPIO_USB3_TO_SOC_WAKE_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 206 : GPIO[32] -> GPIO_SOC_TO_BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 207 : GPIO[33] -> GPIO_SOC_TO_1V8_TOUCH_EXT_SW_ON + +/* Port 26 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 208 : GPIO[34] -> GPIO_TOUCH_TO_SOC_IRQ_L + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 209 : GPIO[35] -> GPIO_SOC_TO_2V9_CAM_LDO_EN + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 210 : GPIO[36] -> GPIO_SOC_TO_TOUCH_RESET_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 211 : GPIO[37] -> GPIO_GANGES_TO_SOC_TO_PMU_IRQ_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW, // 212 : GPIO[38] -> GPIO_SOC_TO_ROTTERDAM_DWLD_REQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 213 : GPIO[39] -> SWD_USBPD_SWDIO + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 214 : GPIO[40] -> GPIO_SOC_TO_AUDIO_KEEPALIVE + GPIOCFG_CFG_IN_PULL_UP_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 215 : GPIO[41] -> GPIO_PMU_TO_SOC_IRQ_L + +/* Port 27 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 216 : GPIO[42] -> GPIO_ORION_TO_SOC_TO_PMU_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 217 : TST_CLKOUT -> TP_TST_CLKOUT + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 218 : GPU_TRIGGER1 -> GPIO_PMU_TO_SOC_UV_WARN_L + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 219 : GPU_TRIGGER2 -> GPIO_PMU_TO_SOC_UV_PEAKI_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_j99adev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 0 : AOP_SPI_SCLK -> SPI_SENSORS_SCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 1 : AOP_SPI_MOSI -> SPI_SENSORS_MOSI_R + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 2 : AOP_SPI_MISO -> SPI_SENSORS_MISO + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 3 : AOP_UART1_TXD -> GPIO_AOP_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_S7_SLOW_SLEW, // 4 : AOP_UART1_RXD -> GPIO_AOP_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_IN_DRIVE_S7_SLOW_SLEW, // 5 : AOP_UART0_TXD -> UART_AOP_TO_BB_TX + GPIOCFG_CFG_FUNC0_DRIVE_S7_SLOW_SLEW, // 6 : AOP_UART0_RXD -> UART_BB_TO_AOP_TX + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 7 : AOP_UART2_TXD -> NC_UART_AOP_TO_TOUCH_TX + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 8 : AOP_UART2_RXD -> NC_GPIO_TOUCH_TO_AOP_DATA_REQUEST + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 9 : AOP_I2CM_SDA -> GPIO_ACCEL_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 10 : AOP_I2CM_SCL -> SPI_ACCEL_CS_L + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 11 : AOP_FUNC[0] -> SPI_COMPASS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 12 : AOP_FUNC[1] -> GPIO_COMPASS_TO_AOP_IRQ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 13 : AOP_FUNC[2] -> NC_GPIO_PHOSPHORUS_TO_AOP_IRQ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 14 : AOP_FUNC[3] -> GPIO_CARBON_TO_AOP_IRQ1 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 15 : AOP_FUNC[4] -> SPI_CARBON_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 16 : AOP_FUNC[5] -> GPIO_CARBON_TO_AOP_IRQ2 + GPIOCFG_CFG_OUT_1_DRIVE_S7_SLOW_SLEW, // 17 : AOP_FUNC[6] -> SPI_PHOSPHORUS_CS_L + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 18 : AOP_FUNC[7] -> NC_SWD_USBPD_SWCLK + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 19 : AOP_FUNC[8] -> GPIO_ACCEL_TO_AOP_IRQ2 + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 20 : AOP_FUNC[9] -> NC_SWD_USBPD_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 21 : AOP_SWD_TCK_OUT -> SWD_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 22 : AOP_SWD_TMS0 -> SWD_ORION_SWDIO + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 23 : AOP_SWD_TMS1 -> NC_SWD_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 24 : AOP_I2S_MCK -> NC_I2S_AOP_MCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 25 : AOP_I2S_BCLK -> NC_I2S_SOC2CODEC_ASP_BCLK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW_INPUT_SCHMITT, // 26 : AOP_I2S_LRCK -> NC_I2S_SOC2CODEC_ASP_LRCK + GPIOCFG_CFG_DISABLED_DRIVE_S7_SLOW_SLEW, // 27 : AOP_I2S_DIN -> NC_I2S_CODEC2SOC_ASP_DOUT + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint8_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { TARGET_BOARD_ID_J98AAP, ~0, { pinconfig_j98aap_0, pinconfig_j98aap_1 } }, + { TARGET_BOARD_ID_J98ADEV, ~0, { pinconfig_j98adev_0, pinconfig_j98adev_1 } }, + { TARGET_BOARD_ID_J99AAP, ~0, { pinconfig_j99aap_0, pinconfig_j99aap_1 } }, + { TARGET_BOARD_ID_J99ADEV, ~0, { pinconfig_j99adev_0, pinconfig_j99adev_1 } }, +}; + +static uint32_t *expanded_pinconfigs[GPIOC_COUNT]; + +static const uint32_t controller_pins[GPIOC_COUNT] = { + GPIO_GROUP_COUNT * GPIOPADPINS, + GPIO_1_GROUP_COUNT * GPIOPADPINS, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + /* Cannot use malloc as chunk manager is yet to be intialized */ + static uint32_t pinconfig_buf[GPIO_GROUP_COUNT * GPIOPADPINS]; + expanded_pinconfigs[0] = pinconfig_buf; + static uint32_t pinconfig_buf_1[GPIO_1_GROUP_COUNT * GPIOPADPINS]; + expanded_pinconfigs[1] = pinconfig_buf_1; + + ASSERT(gpioc < GPIOC_COUNT); + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + + for (unsigned i = 0; i < GPIOC_COUNT; i++) { + uint32_t num_pins = controller_pins[i]; + + for (uint32_t j = 0; j < num_pins; j++) { + uint8_t enum_key = selected_map->pinconfigs[i][j]; + expanded_pinconfigs[i][j] = enum_map[enum_key]; + } + } + } + + return expanded_pinconfigs[gpioc]; +} diff --git a/target/ipad6d/rules.mk b/target/ipad6d/rules.mk new file mode 100644 index 0000000..b4b71f5 --- /dev/null +++ b/target/ipad6d/rules.mk @@ -0,0 +1,50 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2257=1 \ + DIALOG_D2231=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_PLL_VCO_CAP=0 \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=8 \ + TARGET_ICP_CTR=15 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 \ + PMU_LCD_PWR_EN=1 \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + DCS_NUM_RANKS=1 \ + DCS_NUM_CHANNELS=8 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_DITHER_TYPE=DITHER_ERROR_DIFFUSION \ + TARGET_USES_BLEND_CM=1 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi3/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart2/wlan\" \ + DP_DTPATH=\"arm-io/displayport0\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy0\" \ + BT_DTPATH=\"arm-io/uart3/bluetooth\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o $(LOCAL_DIR)/pinconfig.o diff --git a/target/iphone5/include/target/gpiodef.h b/target/iphone5/include/target/gpiodef.h new file mode 100644 index 0000000..64c9233 --- /dev/null +++ b/target/iphone5/include/target/gpiodef.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPhone5,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#define GPIO_LCD_RST GPIO(25, 2) +#define GPIO_LCD_RST_POLARITY (0) +#define GPIO_LCD_CHKSUM GPIO( 4, 7) + +#define GPIO_RINGER_AB GPIO( 0, 4) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 2, 4) +#define GPIO_BOARD_REV1 GPIO( 2, 5) +#define GPIO_BOARD_REV2 GPIO( 2, 6) +#define GPIO_BOARD_REV3 GPIO( 2, 7) + +/* Grape ID */ +#define GPIO_GRAPE_ID0 GPIO( 1, 5) +#define GPIO_GRAPE_ID1 GPIO( 1, 4) +#define GPIO_GRAPE_ID2 GPIO( 1, 3) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (0) + +/* D1972 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +// Configure both FMI0 & FMI1 to use differential DQS with DQ set to DQVREF +#define FMI_DIFF_SEL (0x36) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/iphone5/include/target/nand_spec_tables.h b/target/iphone5/include/target/nand_spec_tables.h new file mode 100644 index 0000000..e7e91ae --- /dev/null +++ b/target/iphone5/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000101 + }, + + /* useToggleMode */ TRUE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ TRUE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ TRUE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/iphone5/include/target/pinconfig.h b/target/iphone5/include/target/pinconfig.h new file mode 100644 index 0000000..12f683f --- /dev/null +++ b/target/iphone5/include/target/pinconfig.h @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default iPhone5,x SoC Pin Configuration */ + +#if PIN_CFG_AP +#define HI_DRIVE_STR DRIVE_X4 +#elif PIN_CFG_DEV +#define HI_DRIVE_STR DRIVE_X6 +#endif + +#define BB_UART_DRIVE_STR DRIVE_X2 +#define BT_UART_DRIVE_STR DRIVE_X2 +#define DOCK_UART_DRIVE_STR DRIVE_X2 +#define SWI_UART_DRIVE_STR DRIVE_X1 +#define WIFI_UART_DRIVE_STR DRIVE_X2 +#define FMI_LO_SPEED_DRIVE_STR (DRIVE_X2 | SLOW_SLEW) +#define FMI_HI_SPEED_DRIVE_STR (DRIVE_X2 | SLOW_SLEW) +#define GRAPE_IO_DRIVE_STR DRIVE_X1 +#define GRAPE_CLK_DRIVE_STR DRIVE_X2 +#define DWI_DRIVE_STR DRIVE_X2 +#define I2C_DRIVE_STR DRIVE_X1 +#define I2S_DRIVE_STR DRIVE_X2 +#define CAM_I2C_DRIVE_STR DRIVE_X1 +#define CAM_STROBE_DRIVE_STR DRIVE_X1 +#define CAM_CLK_DRIVE_STR DRIVE_X2 + +#define DISABLE_OPTIONAL_SIGNALS (1) + +#if PIN_CFG_AP +static const uint32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const uint32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY_BUFF_L (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY_BUFF_L (REQUEST_DFU1) + CFG_IN | PULL_UP, // GPIO2 -> VOL_UP_L + CFG_IN | PULL_UP, // GPIO3 -> VOL_DWN_L + CFG_IN, // GPIO4 -> RINGER_A + CFG_IN | PULL_UP, // GPIO5 -> SPKAMP_INT_L + CFG_IN | PULL_UP, // GPIO6 -> PMU_IRQ_L + CFG_OUT_0, // GPIO7 -> BT_WAKE + +/* Port 1 */ + CFG_IN, // GPIO8 -> BB_PMU_FET_ON + CFG_OUT_0, // GPIO9 -> BEE_GEES + CFG_IN, // GPIO10 -> BB_HSIC1_REMOTE_WAKE + CFG_IN | PULL_UP, // GPIO11 -> WLAN_SDIO_DATA[2] + CFG_IN | PULL_UP, // GPIO12 -> WLAN_SDIO_DATA[1] + CFG_IN | PULL_UP, // GPIO13 -> WLAN_SDIO_DATA[0] + CFG_IN, // GPIO14 -> WLAN_SDIO_CMP + CFG_IN, // GPIO15 -> WLAN_SDIO_CLK + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_OUT_0, // GPIO17 -> AP_HSIC1_RDY + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_OUT_0, // GPIO19 -> KEEPACT + CFG_DISABLED, // EHCI_PORT_PWR[0] -> BOARD_REV0 + CFG_DISABLED, // EHCI_PORT_PWR[1] -> BOARD_REV1 + CFG_DISABLED, // EHCI_PORT_PWR[2] -> BOARD_REV2 + CFG_DISABLED, // EHCI_PORT_PWR[3] -> BOARD_REV3 + +/* Port 3 */ + CFG_IN | BB_UART_DRIVE_STR, // UART1_TXD -> UART1_TXD + CFG_FUNC0, // UART1_RXD -> UART1_RXD + CFG_FUNC0 | BB_UART_DRIVE_STR, // UART1_RTSN -> UART1_RTS_L + CFG_FUNC0, // UART1_CTSN -> UART1_CTS_L + CFG_FUNC0 | DOCK_UART_DRIVE_STR, // UART2_TXD -> UART2_TXD + CFG_FUNC0, // UART2_RXD -> UART2_RXD + CFG_IN | PULL_DOWN, // UART2_RTSN -> ACCEL_INT1 + CFG_IN, // UART2_CTSN -> TRISTAR_INT + +/* Port 4 */ + CFG_FUNC0 | BT_UART_DRIVE_STR, // UART3_TXD -> UART3_TXD + CFG_FUNC0, // UART3_RXD -> UART3_RXD + CFG_OUT_1 | BT_UART_DRIVE_STR, // UART3_RTSN -> UART3_RTS_L + CFG_FUNC0, // UART3_CTSN -> UART3_CTS_L + CFG_FUNC0 | WIFI_UART_DRIVE_STR, // UART4_TXD/SPI4_MOSI -> UART4_TXD + CFG_FUNC0, // UART4_RXD/SPI4_MISO -> UART4_RXD + CFG_OUT_0, // UART4_RTSN/SPI4_SCLK -> CAM0_VDDCORE_EN +#if PIN_CFG_AP + CFG_OUT_0, // UART4_CTSN/SPI4_SSIN -> BB_JTAG_TRST_L +#elif PIN_CFG_DEV + CFG_IN, // UART4_CTSN/SPI4_SSIN -> LCD_ERSTB_L +#else +#error "unknown config" +#endif + +/* Port 5 */ + CFG_FUNC0 | DOCK_UART_DRIVE_STR, // UART6_TXD -> UART6_TXD + CFG_FUNC0, // UART6_RXD -> UART6_RXD + CFG_OUT_0, // UART6_RTSN -> SPKAMP_RESET_L + CFG_IN | PULL_DOWN, // UART6_CTSN -> BB_PP_SYNC + CFG_FUNC1 | SWI_UART_DRIVE_STR, // UART5_RXD/UART5_RTXD -> UART5_RXD + CFG_IN | PULL_DOWN, // UART5_TXD -> BB_RESET_DET_L + CFG_FUNC0 | GRAPE_CLK_DRIVE_STR, // SPI1_SCLK -> SPI1_SCLK + CFG_FUNC0 | GRAPE_IO_DRIVE_STR, // SPI1_MOSI -> SPI1_MOSI + +/* Port 6 */ + CFG_FUNC0, // SPI1_MISO -> SPI1_MISO + CFG_OUT_0 | GRAPE_IO_DRIVE_STR, // SPI1_SSIN -> SPI1_CS_L + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> SPI0_SSIN + CFG_OUT_0, // SPI2_SCLK -> AP_HSIC3_RDY + CFG_OUT_0, // SPI2_MOSI -> PMU_AMUX_BY_CTRL + +/* Port 7 */ + CFG_OUT_0, // SPI2_MISO -> PMU_AMUX_AY_CTRL + CFG_IN | PULL_UP, // SPI2_SSIN -> DEV_HSIC3_RDY + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SDA -> CAM0_I2C_SDA + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SCL -> CAM0_I2C_SCL + +/* Port 8 */ + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SDA -> CAM1_I2C_SDA + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SCL -> CAM1_I2C_SCL + CFG_DISABLED, // MIPI_VSYNC -> MIPI_VSYNC + CFG_FUNC0 | PULL_DOWN, // TMR32_PWM0 -> GYRO_INT2 + CFG_FUNC0, // TMR32_PWM1 -> VIB_PWM + CFG_FUNC0 | GRAPE_IO_DRIVE_STR, // TMR32_PWM2 -> CLK32K_GRAPE_RESET_SOC_L + CFG_DISABLED | PULL_DOWN, // SWI_DATA -> SWI_BLCTL + CFG_FUNC0, // DWI_DI -> DWI_AP_DI + +/* Port 9 */ + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> DWI_AP_CLK + CFG_OUT_0, // SENSOR0_RST -> CAM0_SHUTDOWN + CFG_FUNC0 | CAM_CLK_DRIVE_STR, // SENSOR0_CLK -> CAM0_CLK + CFG_OUT_0, // SENSOR1_RST -> CAM1_SHUTDOWN + CFG_FUNC0 | CAM_CLK_DRIVE_STR, // SENSOR1_CLK -> CAM1_CLK + CFG_FUNC0, // CPU0_SWITCH -> CPU0_SWITCH + CFG_FUNC0, // CPU1_SWITCH -> CPU1_SWITCH + +/* Port 10 */ + CFG_OUT_0, // ISP0_PRE_FLASH -> CAM0_TORCH + CFG_DISABLED, // ISP0_FLASH -> CLK32K_GRAPE_RESET_L + CFG_DISABLED | PULL_DOWN, // ISP1_PRE_FLASH -> ISP1_PRE_FLASH + CFG_DISABLED, // ISP1_FLASH -> + CFG_FUNC0, // SPI3_MOSI -> CODEC_SPI_DIN + CFG_FUNC0, // SPI3_MISO -> CODEC_SPI_DOUT + CFG_FUNC0, // SPI3_SCLK -> CODEC_SPI_CLK + CFG_OUT_1, // SPI3_SSIN -> CODEC_SPI_CS + +/* Port 11 */ + CFG_FUNC0, // I2C2_SDA -> I2C2_SDA_3V0 + CFG_FUNC0, // I2C2_SCL -> I2C2_SCL_3V0 + CFG_OUT_0, // GPIO_3V0 -> HS3_CONTROL + CFG_OUT_0, // GPIO_3V1 -> HS4_CONTROL + CFG_FUNC0 | PULL_DOWN, // DP_HPD -> DP_HPD + CFG_DISABLED | PULL_DOWN, // LPDP_HPD -> LPDP_HPD + CFG_OUT_1, // UART0_TXD -> FLASH_ENABLE + CFG_OUT_0, // UART0_RXD -> VIB_PWM_EN + +/* Port 12 */ + CFG_DISABLED, // TST_CLKOUT -> TST_CLKOUT + CFG_DISABLED, // TST_STPCLK -> TST_STPCLK + CFG_FUNC0, // WDOG -> PMU_RESET_IN + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 13 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_MCK -> I2S0_MCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> I2S0_LRCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_BCLK -> I2S0_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> I2S0_DOUT + CFG_FUNC0, // I2S0_DIN -> I2S0_DIN + CFG_DISABLED, // I2S1_MCK -> I2S1_MCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_LRCK -> I2S1_LRCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_BCLK -> I2S1_BCLK + +/* Port 17 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_DOUT -> I2S1_DOUT + CFG_FUNC0, // I2S1_DIN -> I2S1_DIN + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_MCK -> I2S_MCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> I2S2_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> I2S2_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> I2S2_DOUT + CFG_FUNC0, // I2S2_DIN -> I2S2_DIN + CFG_DISABLED, // I2S3_MCK -> I2S3_MCLK + +/* Port 18 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> I2S3_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> I2S3_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> I2S3_DOUT + CFG_FUNC0, // I2S3_DIN -> I2S3_DIN + CFG_DISABLED, // I2S4_MCK -> I2S4_MCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S4_LRCK -> I2S4_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S4_BCLK -> I2S4_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S4_DOUT -> I2S4_DOUT + +/* Port 19 */ + CFG_FUNC0, // I2S4_DIN -> I2S4_DIN +#if PIN_CFG_DEV + CFG_FUNC0, // SPDIF -> SPDIF +#else + CFG_DISABLED, // SPDIF -> SPDIF +#endif + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN3 -> FMI0_CEN3_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN2 -> FMI0_CEN2_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN1 -> FMI0_CEN1_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN0 -> FMI0_CEN0_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CLE -> FMI0_CLE + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_ALE -> FMI0_ALE + +/* Port 20 */ + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI0_REN -> FMI0_RE_N + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI0_WEN -> FMI0_WE_L +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_DOWN | FMI_HI_SPEED_DRIVE_STR, // FMI0_WENN -> FMI0_RE_P +#else + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI0_WENN -> FMI0_RE_P +#endif + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO7 -> FMI0_IO[7] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO6 -> FMI0_IO[6] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO5 -> FMI0_IO[5] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO4 -> FMI0_IO[4] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_DQS -> FMI0_DQS_P + +/* Port 21 */ +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_UP | FMI_HI_SPEED_DRIVE_STR, // FMI0_DQSN -> FMI0_DQS_N +#else + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_DQSN -> FMI0_DQS_N +#endif + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO3 -> FMI0_IO[3] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO2 -> FMI0_IO[2] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO1 -> FMI0_IO[1] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO0 -> FMI0_IO[0] + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN7 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN6 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN5 -> + +/* Port 22 */ + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN4 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN3 -> FMI1_CEN3_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN2 -> FMI1_CEN2_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN1 -> FMI1_CEN1_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN0 -> FMI1_CEN0_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CLE -> FMI1_CLE + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_ALE -> FMI1_ALE + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI1_REN -> FMI1_RE_N + +/* Port 23 */ + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI1_WEN -> FMI1_WE_L +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_DOWN | FMI_HI_SPEED_DRIVE_STR, // FMI1_WENN -> FMI1_RE_P +#else + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI1_WENN -> FMI1_RE_P +#endif + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO7 -> FMI1_IO[7] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO6 -> FMI1_IO[6] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO5 -> FMI1_IO[5] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO4 -> FMI1_IO[4] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_DQS -> FMI1_DQS_P +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_UP | FMI_HI_SPEED_DRIVE_STR, // FMI1_DQSN -> FMI1_DQS_N +#else + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_DQSN -> FMI1_DQS_N +#endif + +/* Port 24 */ + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO3 -> FMI1_IO[3] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO2 -> FMI1_IO[2] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO1 -> FMI1_IO[1] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO0 -> FMI1_IO[0] + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN7 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN6 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN5 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN4 -> + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN, // GPIO20 -> WLAN_HSIC3_RESUME + CFG_IN | PULL_DOWN, // GPIO21 -> GRAPE_INT_L + CFG_OUT_0, // GPIO22 -> LCD_RESET_L + CFG_IN, // GPIO23 -> LCD_HIFA_BSYNC + CFG_IN, // GPIO24 -> BB_RST_L + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + +/* Port 26 */ + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_IN | PULL_UP, // GPIO30 -> CODEC_INT_L + CFG_IN | PULL_DOWN, // GPIO31 -> DEV_HSIC1_RDY + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 27 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 28 */ + CFG_IN, // GPIO32 -> RADIO_ON_L + CFG_IN | PULL_DOWN, // GPIO33 -> GYRO_INT1 + CFG_IN | PULL_UP, // GPIO34 -> COMPASS_BRD_INT + CFG_OUT_0, // GPIO35 -> AP_WAKE_MODEM + CFG_IN | PULL_DOWN, // GPIO36 -> ACCEL_INT2_L + CFG_OUT_0, // GPIO37 -> THS7380_SEL + CFG_IN | PULL_UP, // GPIO38 -> ALS_INT_L + CFG_OUT_0, // GPIO39 -> GRAPE_RESET_L +}; + +#undef HI_DRIVE_STR +#undef BB_UART_DRIVE_STR +#undef BT_UART_DRIVE_STR +#undef DOCK_UART_DRIVE_STR +#undef SWI_UART_DRIVE_STR +#undef WIFI_UART_DRIVE_STR +#undef FMI_LO_SPEED_DRIVE_STR +#undef FMI_HI_SPEED_DRIVE_STR +#undef GRAPE_IO_DRIVE_STR +#undef GRAPE_CLK_DRIVE_STR +#undef DWI_DRIVE_STR +#undef I2C_DRIVE_STR +#undef I2S_DRIVE_STR +#undef CAM_I2C_DRIVE_STR +#undef CAM_STROBE_DRIVE_STR +#undef CAM_CLK_DRIVE_STR +#undef DISABLE_OPTIONAL_SIGNALS diff --git a/target/iphone5/include/target/powerconfig.h b/target/iphone5/include/target/powerconfig.h new file mode 100644 index 0000000..0983fea --- /dev/null +++ b/target/iphone5/include/target/powerconfig.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +/* Matched to D1972A2-OTP-AE-v2 */ + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kD1972_LDO1, 0x0A }, // PP3V0_USB 3.00V + { PMU_IIC_BUS, kD1972_LDO2, 0x2A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1972_LDO3, 0x0A }, // PP3V0_VIDEO 3.00V + { PMU_IIC_BUS, kD1972_LDO4, 0x0F }, // PP2V8_CAM0_AF 2.55V + { PMU_IIC_BUS, kD1972_LDO5, 0x0A }, // PP3V0_NAND 3.00V + { PMU_IIC_BUS, kD1972_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1972_LDO7, 0x0F }, // P3V0_IMU 3.00V + { PMU_IIC_BUS, kD1972_LDO8, 0x14 }, // PP3V0_USBMUX 3.00V + + // + { PMU_IIC_BUS, kD1972_TEST_MODE, 0x1D }, + { PMU_IIC_BUS, 0xF5, 0x01 }, + { PMU_IIC_BUS, kD1972_LDO9, 0x13 }, // PP3V0_IO 3.10V + { PMU_IIC_BUS, 0xF5, 0x00 }, + { PMU_IIC_BUS, kD1972_TEST_MODE, 0x00 }, + + { PMU_IIC_BUS, kD1972_LDO10, 0x0A }, // PP3V0_OPTICAL 3.00V + { PMU_IIC_BUS, kD1972_LDO11, 0x17 }, // PP2V8_CAM_AVDD 2.85V + { PMU_IIC_BUS, kD1972_LDO12, 0x10 }, // PP1V0 1.00V + { PMU_IIC_BUS, kD1972_LDO16, 0xA0 }, // PP1V0_SRAM_PMU 1.00V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // no bypass + { PMU_IIC_BUS, kD1972_BUCK_CTRL5, 0xD3 }, // Enable x_DWI_EN and CPUx_EN_CTRL +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1972_ACTIVE1, 0xFF }, // Everything on + { PMU_IIC_BUS, kD1972_ACTIVE2, 0xF4 }, // Everything but LDO3, LDO4, LDO6 on + { PMU_IIC_BUS, kD1972_ACTIVE3, 0xEB }, // WLED_BST, LCM_BST, LDO16, LDO_LCM2, LDO12, LDO11 on + { PMU_IIC_BUS, kD1972_ACTIVE4, 0xAD }, // CPU1V8, CPU1V2, CPUA_SW on + { PMU_IIC_BUS, kD1972_HIBERNATE1, 0x70 }, // BUCK3, BUCK4, LDO1 on + { PMU_IIC_BUS, kD1972_HIBERNATE2, 0x00 }, // Everything off + { PMU_IIC_BUS, kD1972_LCM_CONTROL1, 0x02 }, // PP5V1_GRAPE_VDDH_PMU 5.10V + { PMU_IIC_BUS, kD1972_LCM_CONTROL2, 0x0E }, // PP5V7_LCD_AVDDH_PMU 5.70V + { PMU_IIC_BUS, kD1972_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1972_LCM_BST_CONTROL, 0x14 }, // LCM_VBOOST 6.00V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* Note: the following differences from OTP are intentional: + - GPIO2,6,7,10 enable wake + - GPIO5 enables CLK32 + - GPIO8 enables wake up and state change + - GPIO10 pullup + */ + { PMU_IIC_BUS, kD1972_SYS_GPIO_1, 0xB9 }, // CLK32K_GRAPE_RESET_L In, R Edge, No Wake, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_2, 0xBA }, // BB_WAKE_AP In, R Edge, Wake, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_3, 0x09 }, // BB_PMU_ON_R_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_4, 0x7A }, // TRISTAR_INT In, L High, Wake, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_5, 0x49 }, // CLK32K_WIFI Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_6, 0xDA }, // BATTERY_SWI In, F Edge, Out Hib, Wake, PD, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_7, 0xBB }, // HOST_WAKE_WLAN In, R Edge, Wake, PD, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_8, 0xEA }, // MIKEY_INT_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_9, 0x09 }, // BT_REG_ON_R Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_10, 0xAA }, // HOST_WAKE_BT In, R Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_11, 0x09 }, // WIFI_REG_ON_R Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_12, 0xB9 }, // PMU_DBG_GPIO12 In, R Edge, No Wake, No PU + + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB1, 0x12 }, + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB2, 0x12 }, + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB3, 0x02 }, // no debounce on GPIO6 [OTP: 0x12] + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB4, 0x02 }, // no debounce on GPIO8 [OTP: 0x12] + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB5, 0x12 }, + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB6, 0x12 }, + + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) & DWI +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD1972_LDO16 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 + +#define TARGET_DISPLAY_VOLTAGE_BASE 6000 +#define TARGET_DISPLAY_VOLTAGE_SCALE 50 +#define TARGET_DISPLAY_BOOST_LDO kD1972_LCM_CONTROL2 +#define TARGET_DISPLAY_BOOST_OFFSET 300 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/iphone5/include/target/radioconfig.h b/target/iphone5/include/target/radioconfig.h new file mode 100644 index 0000000..32c21ff --- /dev/null +++ b/target/iphone5/include/target/radioconfig.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_RADIOCONFIG_H +#define __TARGET_RADIOCONFIG_H + +/* configuration per target */ + +#define RADIO_VERIFY_BASEBAND_EXISTS 1 + +static const gpio_t target_radio_quiesce_pins[] = +{ + GPIO_UART1_TXD +}; + +#define RADIO_ENABLE_IMEI_OVERRIDE 0 + +#endif /* ! __TARGET_RADIOCONFIG_H */ diff --git a/target/iphone5/include/target/uartconfig.h b/target/iphone5/include/target/uartconfig.h new file mode 100644 index 0000000..84dd2d1 --- /dev/null +++ b/target/iphone5/include/target/uartconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (6) + +/* define radio serial port */ +#define RADIO_SERIAL_PORT (1) +#define RADIO_MAX_READ_ERRORS (10) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/iphone5/init.c b/target/iphone5/init.c new file mode 100644 index 0000000..5133e69 --- /dev/null +++ b/target/iphone5/init.c @@ -0,0 +1,661 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IPHONE5_DEV3_BOARD (0xF) +#define IPHONE5_DEV5_PROTO0_BOARD (0xE) +#define IPHONE5_DEV6_PROTO1_BOARD (0xD) +#define IPHONE5_PROTO2A_BOARD (0xC) +#define IPHONE5_PROTO2B_PROTO2C_BOARD (0xB) +#define IPHONE5_DEV7_PROTO3_BOARD (0xA) +#define IPHONE5_EVT1_BOARD (0x9) +#define IPHONE5_DOE1_BOARD (0x8) +#define IPHONE5_EVT3_BOARD (0x6) + +static u_int32_t iphone5_get_board_rev(void); +static u_int32_t display_config; + +#define IPHONE5_GRAPE_ID_N94 (0x0) +#define IPHONE5_GRAPE_ID_DS401 (0x1) +#define IPHONE5_GRAPE_ID_DS402 (0x2) +#define IPHONE5_GRAPE_ID_PROTO0 (0x8) + +static u_int32_t iphone5_get_grape_id(void); + +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xC6); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + if (iphone5_get_board_rev() > IPHONE5_DEV7_PROTO3_BOARD) { + platform_not_supported(); + } +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + // All AP and PMU GPIOS for the radios are set by pinconfig.h + // and powerconfig.h. While the AP settings are compatible with wake, + // the BB PMU will be in reset thanks to powerconfig.h providing + // dedicated cold boot settings. The AppleARMFunctions in the device + // tree will take care of the rest for a cold boot. +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000964; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "n41", 0); +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *clcd_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize; + char *propName, *propStr; + void *propData; + +#if WITH_HW_DISPLAY_PINOT + // Find the CLCD node + FindNode(0, "arm-io/clcd", &clcd_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, clcd_node, backlight_node); + } +#endif + + // Update the highland-park node with acoustic transducer scale data + if (FindNode(0, "arm-io/highland-park", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ATSc', propData, propSize); + } + } + + // Update the codec and speaker nodes with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi3/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + propName = "at-scale-fmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[8], sizeof(uint32_t)); + } + propName = "at-scale-rcvr"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[12], sizeof(uint32_t)); + } + } + // Update speaker + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[16], sizeof(uint32_t)); + } + } + } + } + + // Updte the speaker calibration data + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass1", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the als calibration data + // XXX The I2C1 als node can be removed once we deprecate proto HW + if (FindNode(0, "arm-io/i2c1/als_i2c1", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c0/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c1/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PxCl', propData, propSize); + } + } + + // HACKs for multi-touch support + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propStr = NULL; + + switch (iphone5_get_grape_id()) { + case IPHONE5_GRAPE_ID_N94 : + propStr = "multi-touch,n94"; + break; + + case IPHONE5_GRAPE_ID_PROTO0 : + propStr = "multi-touch,n41-proto0"; + break; + + case IPHONE5_GRAPE_ID_DS401 : + propStr = "multi-touch,n41-d401"; + break; + + default : + break; + } + + // Replace the data if an override was found + if (propStr != NULL) { + memset(propData, 0, propSize); + strlcpy(propData, propStr, propSize); + } + } + } + + // pre-EVT1 Grape clock config + if (iphone5_get_board_rev() > IPHONE5_EVT1_BOARD) { + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "function-clock_enable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-clock_enable-pmu"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[21] = '\0'; + } + } + + // configure PMU GPIO1 to be Grape clock (off until enabled) + // configure SoC PWM2 to be disabled ( + power_gpio_configure(0, 0x11); + gpio_configure(GPIO(8, 5), GPIO_CFG_IN); + } + + // pre-DOE1 and pre-DEV8 don't use I2C2 + // I2C2 Hardware configuration for N41&N42 + if (iphone5_get_board_rev() > IPHONE5_DOE1_BOARD) { + if (FindNode(0, "arm-io/i2c2", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + strlcpy(propData, "none", propSize); + } + } + } + + // pre-DOE1 vibrator and accelerometer config + if (iphone5_get_board_rev() > IPHONE5_DOE1_BOARD) { + if (FindNode(0, "arm-io/i2c1/accelerometer", &node)) { + propName = "interrupts"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0x44; + } + } + + // add pull-down to TMR32_PWM1 (now accel int.) + gpio_configure_pupdn(GPIO(8, 4), GPIO_PDN); + + // remove PWM vibrator control + if (FindNode(0, "arm-io/pwm/vibrator", &node)) { + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "AAPL,ignore", kPropNameLength); + } + } + + // enable PMU vibrator control + if (FindNode(0, "arm-io/i2c0/pmu/vib-pwm", &node)) { + propName = "AAPL,ignore"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + + // transform vibrator node back to PMU control + if (FindNode(0, "arm-io/i2c0/pmu/vib-pwm/vibrator", &node)) { + uint32_t strong_vset = 0x35; + uint32_t weak_vset = 0xFF; + + syscfgCopyDataForTag('VLSg', (void *)&strong_vset, sizeof(strong_vset)); + syscfgCopyDataForTag('VLWk', (void *)&weak_vset, sizeof(strong_vset)); + + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = strong_vset; + } + propName = "default-hz"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "duty-cycle"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "enable-ms"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-enable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "intensity-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 'ampl'; + ((uint32_t *)propData)[1] = (((uint64_t)weak_vset << 32) + (strong_vset-1)) / strong_vset; // round up + } + } + } + + // vibrator calibration (DOE1 and newer only) + if (iphone5_get_board_rev() <= IPHONE5_DOE1_BOARD) { + if (FindNode(0, "arm-io/pwm/vibrator", &node)) { + propName = "duty-cycle"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint32_t pct; + if (syscfgCopyDataForTag('VLSg', (void *)&pct, sizeof(pct)) > 0) { + ((uint32_t *)propData)[0] = ((uint64_t)pct << 32) / 100; + } + } + propName = "intensity-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint32_t pct; + if (syscfgCopyDataForTag('VLWk', (void *)&pct, sizeof(pct)) > 0) { + ((uint32_t *)propData)[1] = ((uint64_t)pct << 32) / 100; + } + } + } + } + + // Hack for EVT2 and older + if (iphone5_get_board_rev() <= IPHONE5_EVT3_BOARD) { + // Update codec's mic 4 inversion + if (FindNode(0, "arm-io/spi3/audio-codec", &node)) { + propName = "mic4a-invpol"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CBAT', propData, propSize); + } + } + + return 0; +} + +#endif + +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; + +static u_int32_t iphone5_get_board_rev(void) +{ + + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +static bool gpio_grape_id_valid; +static u_int32_t gpio_grape_id; + +static u_int32_t iphone5_get_grape_id(void) +{ + if (!gpio_grape_id_valid) { + if (target_config_ap()) { + gpio_grape_id = IPHONE5_GRAPE_ID_DS402; + } else { + gpio_configure(GPIO_GRAPE_ID0, GPIO_CFG_IN); + gpio_configure(GPIO_GRAPE_ID1, GPIO_CFG_IN); + gpio_configure(GPIO_GRAPE_ID2, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_GRAPE_ID0, GPIO_PDN); + gpio_configure_pupdn(GPIO_GRAPE_ID1, GPIO_PDN); + gpio_configure_pupdn(GPIO_GRAPE_ID2, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_grape_id = + (gpio_read(GPIO_GRAPE_ID2) << 0) | + (gpio_read(GPIO_GRAPE_ID1) << 1) | + (gpio_read(GPIO_GRAPE_ID0) << 2); + + gpio_configure(GPIO_GRAPE_ID0, GPIO_CFG_DFLT); + gpio_configure(GPIO_GRAPE_ID1, GPIO_CFG_DFLT); + gpio_configure(GPIO_GRAPE_ID2, GPIO_CFG_DFLT); + } + gpio_grape_id_valid = true; + } + + return gpio_grape_id; +} + +#if WITH_PAINT + +// N41 & N42 don't support the DClr syscfg key necessary for varying the iBoot +// logo and background color. Therefore we will synthesize a DClr from the +// the information contained in the ClrC syscfg key along with the knowledge +// than N41s and N42s only come in black or white. +// +// Note: The device enclosure colors are not currently used for anything and +// the values below are taken from N51. If at some point the enclosure +// color starts being using for something, then these values will need +// to be set to the actual alues corresponding to the N41/N42 enclosures. + +static const syscfg_DClr_t iphone5_DClr[] = { + [clrcColorBlack] = { + .minor_version = 0, + .major_version = 2, + .device_enclosure.rgb = RGB(153, 152, 155), // Value taken from n51 + .cover_glass.rgb = RGB( 59, 59, 60) + }, + [clrcColorWhite] = { + .minor_version = 0, + .major_version = 2, + .device_enclosure.rgb = RGB(215, 217, 216), // Value taken from n51 + .cover_glass.rgb = RGB(225, 228, 227) + }, +}; + +int target_dclr_from_clrc(uint8_t *buffer, size_t size) +{ + int result; + syscfg_ClrC_t ClrC; + + if ((buffer == NULL) || (size != sizeof(syscfg_DClr_t))) { + return -1; + } + + // Look up the 'ClrC' tag from syscfg. + result = syscfgCopyDataForTag('ClrC', (uint8_t *)&ClrC, sizeof(ClrC)); + if (result < 0) { + dprintf(DEBUG_INFO, + "DClr: ClrC syscfg entry not found -- color remapping disabled\n"); + return result; + } + + if (ClrC.clrcColor < ARRAY_SIZE(iphone5_DClr)) { + dprintf(DEBUG_INFO, + "DClr: Synthesizing values from ClrC (%d)\n", ClrC.clrcColor); + memcpy(buffer, &iphone5_DClr[ClrC.clrcColor], size); + return size; + } else { + dprintf(DEBUG_INFO, + "DClr: Unsupported ClrC value (%d) -- color remapping disabled\n", + ClrC.clrcColor); + return -1; + } +} + + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} + +#endif // WITH_PAINT diff --git a/target/iphone5/pinconfig.c b/target/iphone5/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/iphone5/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/iphone5/rules.mk b/target/iphone5/rules.mk new file mode 100644 index 0000000..737bc8d --- /dev/null +++ b/target/iphone5/rules.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2011-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1972=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=CHIPID_RAM_VOLTAGE_LOW \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_MED \ + TARGET_RAM_VOLTAGE_OFFSET=17 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=5 \ + TARGET_USE_HSIC=1 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_DPHYCTL=0x30 \ + TARGET_DSIM_UP_CODE=0x5 \ + TARGET_DSIM_DOWN_CODE=0x1 \ + TARGET_DSIM_SUPPRESS=0x1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + BASEBAND_DTPATH=\"baseband\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci/wlan\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/iphone5b/include/target/gpiodef.h b/target/iphone5b/include/target/gpiodef.h new file mode 100644 index 0000000..d709a60 --- /dev/null +++ b/target/iphone5b/include/target/gpiodef.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPhone5,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#define GPIO_LCD_RST GPIO(25, 2) +#define GPIO_LCD_RST_POLARITY (0) + +#define GPIO_RINGER_AB GPIO( 0, 4) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 2, 4) +#define GPIO_BOARD_REV1 GPIO( 2, 5) +#define GPIO_BOARD_REV2 GPIO( 2, 6) +#define GPIO_BOARD_REV3 GPIO( 2, 7) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (0) + +#define DISPLAY_PMU_IIC_BUS (0) + +/* D1972 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +// Configure both FMI0 & FMI1 to use differential DQS with DQ set to DQVREF +#define FMI_DIFF_SEL (0x36) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/iphone5b/include/target/nand_spec_tables.h b/target/iphone5b/include/target/nand_spec_tables.h new file mode 100644 index 0000000..e7e91ae --- /dev/null +++ b/target/iphone5b/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000101 + }, + + /* useToggleMode */ TRUE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ TRUE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ TRUE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/iphone5b/include/target/pinconfig.h b/target/iphone5b/include/target/pinconfig.h new file mode 100644 index 0000000..1d07235 --- /dev/null +++ b/target/iphone5b/include/target/pinconfig.h @@ -0,0 +1,366 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default iPhone5b (iPhone5,3/4) SoC Pin Configuration */ + +#if PIN_CFG_AP +#define HI_DRIVE_STR DRIVE_X4 +#elif PIN_CFG_DEV +#define HI_DRIVE_STR DRIVE_X6 +#endif + +#define BB_UART_DRIVE_STR DRIVE_X2 +#define BT_UART_DRIVE_STR DRIVE_X2 +#define DOCK_UART_DRIVE_STR DRIVE_X2 +#define SWI_UART_DRIVE_STR DRIVE_X1 +#define WIFI_UART_DRIVE_STR DRIVE_X2 +#define FMI_LO_SPEED_DRIVE_STR (DRIVE_X2 | SLOW_SLEW) +#define FMI_HI_SPEED_DRIVE_STR (DRIVE_X2 | SLOW_SLEW) +#define GRAPE_IO_DRIVE_STR DRIVE_X1 +#define GRAPE_CLK_DRIVE_STR DRIVE_X2 +#define DWI_DRIVE_STR DRIVE_X2 +#define I2C_DRIVE_STR DRIVE_X1 +#define I2S_DRIVE_STR DRIVE_X2 +#define CAM_I2C_DRIVE_STR DRIVE_X1 +#define CAM_STROBE_DRIVE_STR DRIVE_X1 +#define CAM_CLK_DRIVE_STR DRIVE_X2 + +#define DISABLE_OPTIONAL_SIGNALS (1) + +#if PIN_CFG_AP +static const uint32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const uint32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif +/* Port 0 */ + CFG_IN, // GPIO0 -> BUTTON_TO_AP_MENU_KEY_BUFF_L (REQUEST_DFU2) + CFG_IN, // GPIO1 -> BUTTON_TO_AP_HOLD_KEY_BUFF_L (REQUEST_DFU1) + CFG_IN | PULL_UP, // GPIO2 -> BUTTON_TO_AP_VOL_UP_L + CFG_IN | PULL_UP, // GPIO3 -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN, // GPIO4 -> BUTTON_TO_AP_RINGER_A + CFG_IN | PULL_UP, // GPIO5 -> SPKAMP_TO_AP_INT_L + CFG_IN | PULL_UP, // GPIO6 -> PMU_IRQ_L + CFG_OUT_0, // GPIO7 -> AP_TO_BT_WAKE + +/* Port 1 */ + CFG_DISABLED | PULL_DOWN, // GPIO8 -> N/C + CFG_OUT_0, // GPIO9 -> AP_TO_APKAMP_BEE_GEES + CFG_DISABLED | PULL_DOWN, // GPIO10 -> BB_TO_AP_HSIC1_REMOTE_WAKE + CFG_DISABLED, // GPIO11 -> AP_TO_BB_JTAG_TCK + CFG_DISABLED, // GPIO12 -> AP_TO_BB_BB_JTAG_TDI + CFG_IN | PULL_UP, // GPIO13 -> AP_TO_BB_JTAG_TMS + CFG_DISABLED | PULL_DOWN, // GPIO14 -> BB_TO_AP_JTAG_TDO + CFG_DISABLED | PULL_DOWN, // GPIO15 -> N/C + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_OUT_0, // GPIO17 -> AP_TO_BB_HSIC1_RDY + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_OUT_0, // GPIO19 -> KEEPACT + CFG_DISABLED, // EHCI_PORT_PWR[0] -> BOARD_REV[0] + CFG_DISABLED, // EHCI_PORT_PWR[1] -> BOARD_REV[1] + CFG_DISABLED, // EHCI_PORT_PWR[2] -> BOARD_REV[2] + CFG_DISABLED, // EHCI_PORT_PWR[3] -> BOARD_REV[3] + +/* Port 3 */ + CFG_OUT_0 | BB_UART_DRIVE_STR, // UART1_TXD -> AP_TO_BB_UART1_TXD + CFG_FUNC0, // UART1_RXD -> AP_TO_BB_UART1_RXD + CFG_OUT_0 | BB_UART_DRIVE_STR, // UART1_RTSN -> AP_TO_BB_UART1_RTS_L + CFG_FUNC0, // UART1_CTSN -> AP_TO_BB_UART1_CTS_L + CFG_FUNC0 | DOCK_UART_DRIVE_STR, // UART2_TXD -> AP_TO_TRISTAR_ACC_UART2_TXD + CFG_FUNC0, // UART2_RXD -> AP_TO_TRISTAR_ACC_UART2_RXD + CFG_IN | PULL_DOWN, // UART2_RTSN -> AP_TO_ACCEL_INT1 + CFG_IN, // UART2_CTSN -> AP_TO_TRISTAR_INT + +/* Port 4 */ + CFG_FUNC0 | BT_UART_DRIVE_STR, // UART3_TXD -> AP_TO_BT_UART3_TXD + CFG_FUNC0, // UART3_RXD -> BT_TO_AP_UART3_RXD + CFG_OUT_1 | BT_UART_DRIVE_STR, // UART3_RTSN -> AP_TO_BT_UART3_RTS_L + CFG_FUNC0, // UART3_CTSN -> BT_TO_AP_UART3_CTS_L + CFG_FUNC0 | WIFI_UART_DRIVE_STR, // UART4_TXD/SPI4_MOSI -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0, // UART4_RXD/SPI4_MISO -> AP_TO_WLAN_UART4_RXD + CFG_OUT_0, // UART4_RTSN/SPI4_SCLK -> AP_TO_CAM0_VDDCORE_EN + CFG_DISABLED, // UART4_CTSN/SPI4_SSIN -> AP_TO_BB_JTAG_TRST_L + +/* Port 5 */ + CFG_FUNC0 | DOCK_UART_DRIVE_STR, // UART6_TXD -> AP_TO_TRISTAR_DEBUG_UART6_TXD + CFG_FUNC0, // UART6_RXD -> AP_TO_TRISTAR_DEBUG_UART6_RXD + CFG_OUT_0, // UART6_RTSN -> AP_TO_SPKAMP_RESET_L + CFG_IN | PULL_DOWN, // UART6_CTSN -> BB_TO_AP_PP_SYNC + CFG_FUNC1 | SWI_UART_DRIVE_STR, // UART5_RXD/UART5_RTXD -> AP_BI_BATTERY_SWI + CFG_IN | PULL_DOWN, // UART5_TXD -> BB_TO_AP_RESET_DET_L + CFG_FUNC0 | GRAPE_CLK_DRIVE_STR, // SPI1_SCLK -> AP_TO_TOUCH_SPI1_CLK + CFG_FUNC0 | GRAPE_IO_DRIVE_STR, // SPI1_MOSI -> AP_TO_TOUCH_SPI1_MOSI + +/* Port 6 */ + CFG_FUNC0, // SPI1_MISO -> AP_TO_TOUCH_SPI1_MISO + CFG_OUT_0 | GRAPE_IO_DRIVE_STR, // SPI1_SSIN -> AP_TO_TOUCH_API1_CS_L + CFG_DISABLED, // SPI0_SCLK -> BOARD_ID[0]/SPI0_SCLK + CFG_DISABLED, // SPI0_MOSI -> BOARD_ID[1]/SPI0_MOSI + CFG_DISABLED, // SPI0_MISO -> BOARD_ID[2]/SPI0_MISO + CFG_DISABLED, // SPI0_SSIN -> LCD_TO_AP_PIFA + CFG_OUT_0, // SPI2_SCLK -> AP_TO_WLAN_HSIC2_RDY + CFG_DISABLED, // SPI2_MOSI -> BB_TO_AP_IPC_GPIO + +/* Port 7 */ + CFG_OUT_0, // SPI2_MISO -> FCAM_TO_AP_ALS_INT_L + CFG_IN | PULL_DOWN, // SPI2_SSIN -> WLAN_TO_AP_HSIC2_RDY + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> AP_TO_I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> AP_BI_I2C0_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SDA -> AP_TO_I2C1_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SCL -> AP_BI_I2C1_SCL_1V8 + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SDA -> AP_BI_CAM_RF_SDA + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SCL -> AP_TO_CAM_RF_SCL + +/* Port 8 */ + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SDA -> AP_BI_CAM_FF_SDA + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SCL -> AP_TO_CAM_FF_SCL + CFG_DISABLED | PULL_DOWN, // MIPI_VSYNC -> MIPI_VSYNC + CFG_FUNC0 | PULL_DOWN, // TMR32_PWM0 -> GYRO_TO_AP_INT2 + CFG_FUNC0, // TMR32_PWM1 -> VIB_PWM + CFG_FUNC0, // TMR32_PWM2 -> 45_AP_TO_TOUCH_CLK32K_RESET_L + CFG_DISABLED | PULL_DOWN, // SWI_DATA -> N/C + CFG_FUNC0, // DWI_DI -> 45_AP_TO_PMU_DWI_DI + +/* Port 9 */ + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> 45_AP_TO_PMU_DWI_DO + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> 45_AP_TO_PMU_DWI_CLK + CFG_OUT_0, // SENSOR0_RST -> AP_TO_CAM_RF_SHUTDOWN + CFG_FUNC0 | CAM_CLK_DRIVE_STR, // SENSOR0_CLK -> 45_CAM0_CLK_R + CFG_OUT_0, // SENSOR1_RST -> AP_TO_CAM_FF_SHUTDOWN + CFG_FUNC0 | CAM_CLK_DRIVE_STR, // SENSOR1_CLK -> 45_CAM1_CLK_R + CFG_FUNC0, // CPU0_SWITCH -> CPU0_SWITCH + CFG_FUNC0, // CPU1_SWITCH -> CPU1_SWITCH + +/* Port 10 */ + CFG_OUT_0, // ISP0_PRE_FLASH -> CAM0_TORCH + CFG_DISABLED | PULL_DOWN, // ISP0_FLASH -> N/C + CFG_DISABLED | PULL_DOWN, // ISP1_PRE_FLASH -> N/C + CFG_DISABLED | PULL_DOWN, // ISP1_FLASH -> N/C + CFG_FUNC0, // SPI3_MOSI -> AP_TO_CODEC_SPI3_MOSI + CFG_FUNC0, // SPI3_MISO -> AP_TO_CODEC_SPI3_MISO + CFG_FUNC0, // SPI3_SCLK -> AP_TO_CODEC_SPI3_CLK + CFG_OUT_1, // SPI3_SSIN -> AP_TO_CODEC_SPI3_CS_L + +/* Port 11 */ + CFG_FUNC0, // I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0, // I2C2_SCL -> AP_TO_I2C2_SCL + CFG_OUT_0, // GPIO_3V0 -> AP_TO_HEADSET_HS3_CONTROL + CFG_OUT_0, // GPIO_3V1 -> AP_TO_HEADSET_HS4_CONTROL + CFG_DISABLED | PULL_DOWN, // DP_HPD -> N/C + CFG_DISABLED | PULL_DOWN, // LPDP_HPD -> N/C + CFG_OUT_1, // UART0_TXD -> AP_TO_LEDDRV_EN + CFG_OUT_0, // UART0_RXD -> VIB_LDO_EN + +/* Port 12 */ + CFG_DISABLED, // TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED, // TST_STPCLK -> GND + CFG_FUNC0, // WDOG -> WDOG + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 13 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // I2S0_MCK -> AP_TO_CODEC_I2S0_MCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> AP_TO_CODEC_I2S0_LRCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_BCLK -> AP_TO_CODEC_I2S0_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> AP_TO_CODEC_I2S0_DOUT + CFG_FUNC0, // I2S0_DIN -> AP_TO_CODEC_I2S0_DIN + CFG_DISABLED | PULL_DOWN, // I2S1_MCK -> N/C + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_LRCK -> AP_TO_BB_I2S1_LRCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_BCLK -> AP_TO_BB_I2S1_BCLK + +/* Port 17 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_DOUT -> AP_TO_BB_I2S1_DOUT + CFG_FUNC0, // I2S1_DIN -> AP_TO_BB_I2S1_DIN + CFG_FUNC0 | SLOW_SLEW, // I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0, // I2S2_DIN -> AP_TO_CODEC_XSP_I2S2_DIN + CFG_DISABLED | PULL_DOWN, // I2S3_MCK -> N/C + +/* Port 18 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> AP_TO_BT_I2S3_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> 45_AP_TO_BT_I2S3_LRCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> AP_TO_BT_I2S3_DOUT + CFG_FUNC0, // I2S3_DIN -> AP_TO_BT_I2S3_DIN + CFG_DISABLED | PULL_DOWN, // I2S4_MCK -> N/C + CFG_FUNC0 | I2S_DRIVE_STR, // I2S4_LRCK -> AP_TO_CODEC_VSP_I2S2_LRCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S2_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S4_DOUT -> AP_TO_CODEC_VSP_I2S2_DOUT + +/* Port 19 */ + CFG_FUNC0, // I2S4_DIN -> AP_TO_CODEC_VSP_I2S2_DIN + CFG_DISABLED | PULL_DOWN, // SPDIF -> N/C + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN3 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN2 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN1 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN0 -> FMI0_CEN0_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_CLE -> FMI0_CLE + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI0_ALE -> FMI0_ALE + +/* Port 20 */ + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI0_REN -> FMI0_RE_N + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI0_WEN -> FMI0_WE_L +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_DOWN | FMI_HI_SPEED_DRIVE_STR, // FMI0_WENN -> FMI0_RE_P +#else + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI0_WENN -> FMI0_RE_P +#endif + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO7 -> FMI0_IO[7] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO6 -> FMI0_IO[6] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO5 -> FMI0_IO[5] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO4 -> FMI0_IO[4] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_DQS -> FMI0_DQS_P + +/* Port 21 */ +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_UP | FMI_HI_SPEED_DRIVE_STR, // FMI0_DQSN -> FMI0_DQS_N +#else + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_DQSN -> FMI0_DQS_N +#endif + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO3 -> FMI0_IO[3] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO2 -> FMI0_IO[2] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO1 -> FMI0_IO[1] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI0_IO0 -> FMI0_IO[0] + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN7 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN6 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN5 -> + +/* Port 22 */ + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI0_CEN4 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN3 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN2 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN1 -> + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN0 -> FMI1_CEN0_L + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_CLE -> FMI1_CLE + CFG_FUNC0 | FMI_LO_SPEED_DRIVE_STR, // FMI1_ALE -> FMI1_ALE + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI1_REN -> FMI1_RE_N + +/* Port 23 */ + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI1_WEN -> FMI1_WE_L +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_DOWN | FMI_HI_SPEED_DRIVE_STR, // FMI1_WENN -> FMI1_RE_P +#else + CFG_FUNC0 | FMI_HI_SPEED_DRIVE_STR, // FMI1_WENN -> FMI1_RE_P +#endif + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO7 -> FMI1_IO[7] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO6 -> FMI1_IO[6] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO5 -> FMI1_IO[5] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO4 -> FMI1_IO[4] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_DQS -> FMI1_DQS_P +#if DISABLE_OPTIONAL_SIGNALS + CFG_DISABLED | PULL_UP | FMI_HI_SPEED_DRIVE_STR, // FMI1_DQSN -> FMI1_DQS_N +#else + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_DQSN -> FMI1_DQS_N +#endif + +/* Port 24 */ + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO3 -> FMI1_IO[3] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO2 -> FMI1_IO[2] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO1 -> FMI1_IO[1] + CFG_FUNC0 | BUS_HOLD | FMI_HI_SPEED_DRIVE_STR, // FMI1_IO0 -> FMI1_IO[0] + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN7 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN6 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN5 -> + CFG_DISABLED | FMI_LO_SPEED_DRIVE_STR, // FMI1_CEN4 -> + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN, // GPIO20 -> WLAN_HSIC3_RESUME + CFG_IN | PULL_DOWN, // GPIO21 -> TOUCH_TO_AP_INT_L + CFG_OUT_0, // GPIO22 -> LCD_RESET_L + CFG_IN, // GPIO23 -> LCD_HIFA_BSYNC + CFG_IN, // GPIO24 -> BB_RESET_L + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + +/* Port 26 */ + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_IN | PULL_UP, // GPIO30 -> CODEC_INT_L + CFG_IN | PULL_DOWN, // GPIO31 -> PBL_RUN_BB_HSIC1_RDY + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 27 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 28 */ + CFG_IN, // GPIO32 -> AP_TO_RADIO_ON_L + CFG_IN | PULL_DOWN, // GPIO33 -> GYRO_TO_AP_INT1 + CFG_IN | PULL_UP, // GPIO34 -> COMPASS_INT_2 + CFG_OUT_0, // GPIO35 -> AP_TO_BB_WAKE_MODEM + CFG_IN | PULL_DOWN, // GPIO36 -> AP_TO_ACCEL_INT2_L + CFG_DISABLED | PULL_DOWN, // GPIO37 -> N/C + CFG_IN | PULL_UP, // GPIO38 -> ALS_TO_AP_INT_L + CFG_OUT_0, // GPIO39 -> AP_TO_TOUCH_GRAPE_RESET +}; + +#undef HI_DRIVE_STR +#undef BB_UART_DRIVE_STR +#undef BT_UART_DRIVE_STR +#undef DOCK_UART_DRIVE_STR +#undef SWI_UART_DRIVE_STR +#undef WIFI_UART_DRIVE_STR +#undef FMI_LO_SPEED_DRIVE_STR +#undef FMI_HI_SPEED_DRIVE_STR +#undef GRAPE_IO_DRIVE_STR +#undef GRAPE_CLK_DRIVE_STR +#undef DWI_DRIVE_STR +#undef I2C_DRIVE_STR +#undef I2S_DRIVE_STR +#undef CAM_I2C_DRIVE_STR +#undef CAM_STROBE_DRIVE_STR +#undef CAM_CLK_DRIVE_STR +#undef DISABLE_OPTIONAL_SIGNALS diff --git a/target/iphone5b/include/target/powerconfig.h b/target/iphone5b/include/target/powerconfig.h new file mode 100644 index 0000000..2585d94 --- /dev/null +++ b/target/iphone5b/include/target/powerconfig.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2010-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +/* Matched to D1972A2-OTP-AE-v2 */ + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kD1972_LDO1, 0x0A }, // PP3V0_ALWAYS 3.00V + { PMU_IIC_BUS, kD1972_LDO2, 0x2A }, // PP1V7_VA_L19 1.70V + { PMU_IIC_BUS, kD1972_LDO3, 0x10 }, // PP3V3_USB 3.30V + { PMU_IIC_BUS, kD1972_LDO4, 0x0F }, // PP2V8_CAM0_AF 2.55V + { PMU_IIC_BUS, kD1972_LDO5, 0x0A }, // PP3V0_NAND 3.00V + { PMU_IIC_BUS, kD1972_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1972_LDO7, 0x0F }, // P3V0_IMU 3.00V + { PMU_IIC_BUS, kD1972_LDO8, 0x14 }, // PP3V0_PROX_ALS 3.00V + + // + { PMU_IIC_BUS, kD1972_TEST_MODE, 0x1D }, + { PMU_IIC_BUS, 0xF5, 0x01 }, + { PMU_IIC_BUS, kD1972_LDO9, 0x13 }, // PP3V0_VIB 3.10V + { PMU_IIC_BUS, 0xF5, 0x00 }, + { PMU_IIC_BUS, kD1972_TEST_MODE, 0x00 }, + + { PMU_IIC_BUS, kD1972_LDO10, 0x0A }, // PP3V0_PROX_IRLED 3.00V + { PMU_IIC_BUS, kD1972_LDO11, 0x17 }, // PP2V8_CAM_AVDD 2.85V + { PMU_IIC_BUS, kD1972_LDO12, 0x10 }, // PP1V0 1.00V + { PMU_IIC_BUS, kD1972_LDO16, 0xA0 }, // PP1V0_SRAM_PMU 1.00V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // no bypass + { PMU_IIC_BUS, kD1972_BUCK_CTRL5, 0xD3 }, // Enable x_DWI_EN and CPUx_EN_CTRL +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1972_ACTIVE1, 0xFF }, // Everything on + { PMU_IIC_BUS, kD1972_ACTIVE2, 0xF5 }, // Everything but LDO4, LDO6 on + { PMU_IIC_BUS, kD1972_ACTIVE3, 0x23 }, // LDO16, LDO12, LDO11 on + { PMU_IIC_BUS, kD1972_ACTIVE4, 0xAD }, // CPU1V8, CPU1V2, CPUA_SW on + { PMU_IIC_BUS, kD1972_HIBERNATE1, 0x70 }, // BUCK3, BUCK4, LDO1 on + { PMU_IIC_BUS, kD1972_HIBERNATE2, 0x00 }, // Everything off + { PMU_IIC_BUS, kD1972_LCM_CONTROL1, 0x02 }, // PP5V1_GRAPE_VDDH_PMU 5.10V + { PMU_IIC_BUS, kD1972_LCM_CONTROL2, 0x0E }, // PP5V7_LCD_AVDDH_PMU 5.70V + { PMU_IIC_BUS, kD1972_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1972_LCM_BST_CONTROL, 0x14 }, // LCM_VBOOST 6.00V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* Note: the following differences from OTP are intentional: + - GPIO2,6,7,10 enable wake + - GPIO5 enables CLK32 + - GPIO8 enables wake up and state change + - GPIO10 pullup + */ + { PMU_IIC_BUS, kD1972_SYS_GPIO_2, 0x7A }, // BB_WAKE_AP In, L High, Wake, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_3, 0x09 }, // BB_PMU_ON_R_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_4, 0x7A }, // TRISTAR_INT In, L High, Wake, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_5, 0x49 }, // CLK32K_WIFI Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_6, 0xDA }, // BATTERY_SWI In, F Edge, Out Hib, Wake, PD, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_7, 0xBB }, // HOST_WAKE_WLAN In, R Edge, Wake, PD, No PU + { PMU_IIC_BUS, kD1972_SYS_GPIO_8, 0xEA }, // MIKEY_INT_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_9, 0x09 }, // BT_REG_ON_R Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_10, 0xAA }, // HOST_WAKE_BT In, R Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_11, 0x09 }, // WIFI_REG_ON_R Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1972_SYS_GPIO_12, 0x01 }, // PMU_TO_BB_VBUS_DET Out 0, Push-Pull, VCC_MAIN + + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB1, 0x12 }, + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB2, 0x12 }, + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB3, 0x02 }, // no debounce on GPIO6 [OTP: 0x12] + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB4, 0x02 }, // no debounce on GPIO8 [OTP: 0x12] + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB5, 0x12 }, + { PMU_IIC_BUS, kD1972_SYS_GPIO_DEB6, 0x12 }, + + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) & DWI +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD1972_LDO16 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 + +#define TARGET_DISPLAY_VOLTAGE_BASE 6000 +#define TARGET_DISPLAY_VOLTAGE_SCALE 50 +#define TARGET_DISPLAY_BOOST_LDO kD1972_LCM_CONTROL2 +#define TARGET_DISPLAY_BOOST_OFFSET 300 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/iphone5b/include/target/radioconfig.h b/target/iphone5b/include/target/radioconfig.h new file mode 100644 index 0000000..32c21ff --- /dev/null +++ b/target/iphone5b/include/target/radioconfig.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_RADIOCONFIG_H +#define __TARGET_RADIOCONFIG_H + +/* configuration per target */ + +#define RADIO_VERIFY_BASEBAND_EXISTS 1 + +static const gpio_t target_radio_quiesce_pins[] = +{ + GPIO_UART1_TXD +}; + +#define RADIO_ENABLE_IMEI_OVERRIDE 0 + +#endif /* ! __TARGET_RADIOCONFIG_H */ diff --git a/target/iphone5b/include/target/uartconfig.h b/target/iphone5b/include/target/uartconfig.h new file mode 100644 index 0000000..84dd2d1 --- /dev/null +++ b/target/iphone5b/include/target/uartconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (6) + +/* define radio serial port */ +#define RADIO_SERIAL_PORT (1) +#define RADIO_MAX_READ_ERRORS (10) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/iphone5b/init.c b/target/iphone5b/init.c new file mode 100644 index 0000000..13232e2 --- /dev/null +++ b/target/iphone5b/init.c @@ -0,0 +1,686 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Board ID/Board Rev matrix: + +// Board ID: N48 MLB: 1010, N49 MLB: 1110 +// Board Rev 1111: PreProto+Tristar1+Chestnut Combined Rail (Not supported by SW) +// Board Rev 1101: Proto1+Tristar1+Chestnut Split Rail+d404 display panel +// Board Rev 1100: Proto1+Tristar2+Chestnut Split Rail+d404 display panel +// Board Rev 1011: EVT1+Tristar2+Chestnut Split Rail+d404 display panel+L81 audio +// Board Rev 1010: EVT2+Tristar2+Chestnut Split Rail+d404 display panel+L81 audio +// Board Rev 1001: DVT+Tristar2+Chestnut Split Rail+d404 display panel+L81 audio + +// Board ID: N48 Dev: 1011, N49 DEV: 1111 +// Board Rev 1111: Dev1+Tristar1+Chestnut Combined Rail+d401 display panel +// Board Rev 1101: Proto1+Tristar1+Chestnut Split Rail+d404 display panel +// Board Rev 1100: Proto1+Tristar2+Chestnut Split Rail+d404 display panel +// Board Rev 1011: EVT1+Tristar2+Chestnut Split Rail+d404 display panel+L81 audio +// Board Rev 1010: EVT2+Tristar2+Chestnut Split Rail+d404 display panel+L81 audio +// Board Rev 1001: DVT+Tristar2+Chestnut Split Rail+d404 display panel+L81 audio + +#define N48_AP_BOARD_ID (0xA) // AP board ID +#define N48_DEV_BOARD_ID (0xB) // DEV board ID + +#define N49_AP_BOARD_ID (0xE) // AP board ID +#define N49_DEV_BOARD_ID (0xF) // DEV board ID + +#define DEV1_BOARD (0xF) // Dev1 + Tristar1 + Chestnut Combined Rail +#define DEV1A_BOARD (0xE) // Dev1 + Tristar2 + Chestnut Combined Rail +#define DEV1B_BOARD (0xC) // Dev1 + Tristar2 + Chestnut Split Rail +#define DEV1C_BOARD (0xB) // Dev1 + Tristar2 + Chestnut Split Rail + L81 audio +#define PROTO1A_BOARD (0xD) // Proto1 + Tristar1 + Chestnut Split Rail +#define PROTO1B_BOARD (0xC) // Proto1 + Tristar2 + Chestnut Split Rail +#define EVT1_BOARD (0xB) // EVT1 + Tristar2 + Chestnut Split Rail + L81 audio +#define EVT2_BOARD (0xA) // EVT2 + Tristar2 + Chestnut Split Rail + L81 audio +#define DVT_BOARD (0x9) // DVT + Tristar2 + Chestnut Split Rail + L81 audio + +static u_int32_t iphone5b_get_board_rev(void); +static bool iphone5b_with_chestnut_split_rail(void); +static uint32_t display_config; + +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xC6); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +// Don't panic for these targets because of . +MIB_CONSTANT(kMIBTargetPanicOnUnknownDclrVersion, kOIDTypeBoolean, false); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + if (iphone5b_get_board_rev() > DEV1_BOARD) { + platform_not_supported(); + } +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + // All AP and PMU GPIOS for the radios are set by pinconfig.h + // and powerconfig.h. While the AP settings are compatible with wake, + // the BB PMU will be in reset thanks to powerconfig.h providing + // dedicated cold boot settings. The AppleARMFunctions in the device + // tree will take care of the rest for a cold boot. + + if (iphone5b_get_board_rev() == EVT1_BOARD) { + // Switch Tristar to Pulsing Con Detect mode for n5x and n48/n49 + iic_write(0, 0x35, (uint8_t[]){ 0x1e, 0x30 }, 2); + } +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000964; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "n41", 0); +} + +#endif + +bool target_has_tristar2(void) +{ + u_int32_t board_rev = iphone5b_get_board_rev(); + return board_rev != DEV1_BOARD && board_rev != PROTO1A_BOARD; +} + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ +// N48 dev and ap boards have different display PMU rail topologes: + +// Split rail topology (ap boards with D404 display module) +// LDO1: PP5V7_SAGE_AVDDH +// LDO2: PP5V7_TO_LCD_AVDDH +// LDO3: PP5V1_GRAPE_VDDH + +// Combined rail topology (dev boards with D401 display module) +// LDO1: PP5V7_SAGE_AND_LCM_AVDDH +// LDO2: PP5V1_GRAPE_VDDH +// LDO3: Unused + + if (iphone5b_with_chestnut_split_rail()) { + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); + } + // The combined rail topology requires only LDO1 to be enabled. + return DISPLAY_PMU_LDO(0); +} +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *clcd_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize; + char *propName, *propStr; + void *propData; + +#if WITH_HW_DISPLAY_PINOT + // Find the CLCD node + FindNode(0, "arm-io/clcd", &clcd_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, clcd_node, backlight_node); + + // Set Chestnut LDO based upon split/combined rail topology. + propName = "function-lcd_ldo"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (iphone5b_with_chestnut_split_rail()) + ((uint8_t *)propData)[8] = 1; // V02 -> PP5V7_CHESTNUT_LDO2 + else + ((uint8_t *)propData)[8] = 0; // V01 -> PP5V7_CHESTNUT_LDO1 + } + } +#endif + + // Update the highland-park node with acoustic transducer scale data + if (FindNode(0, "arm-io/highland-park", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ATSc', propData, propSize); + } + } + + // Update the codec and speaker nodes with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi3/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + propName = "at-scale-fmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[8], sizeof(uint32_t)); + } + propName = "at-scale-rcvr"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[12], sizeof(uint32_t)); + } + } + // Update speaker + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[16], sizeof(uint32_t)); + } + } + } + } + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + switch ( iphone5b_get_board_rev() ) { + case DEV1_BOARD: + case DEV1A_BOARD: + case PROTO1A_BOARD: + case PROTO1B_BOARD: // DEV1B_BOARD same as PROTO1B_BOARD + { + static const uint8_t l20cfg[]={0x90,0x00,0x01,0x90,0x62,0x03,0x12,0x1e,0x02,0x04,0x0A,0x05,0x6b,0x63,0x06,0x32,0x74,0x03,0x00,0x00 }; + + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "audio-control,cs35l20", kPropNameLength); + } + + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, (void*)l20cfg, sizeof(l20cfg)); + } + + propName = "l67_func-ext_active"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-ext_active", kPropNameLength); + } + + propName = "l67_func-ext_master"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-ext_master", kPropNameLength); + } + } + + // MCLK provides 6MHz for L20 on I2S2_MCLK pin + if (FindNode(0, "arm-io/i2s2/audio-bluetooth", &node)) { + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t*)propData)[2] = 0x005b8d80; + } + } + + if (FindNode(0, "arm-io/spi3/audio-codec", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "audio-control,cs42l67", propSize); + } + propName = "function-xsp_active"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-vsp_active", kPropNameLength); + } + propName = "function-xsp_master"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-vsp_master", kPropNameLength); + } + propName = "function-l67_xsp_active"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-xsp_active", kPropNameLength); + } + propName = "function-l67_xsp_master"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-xsp_master", kPropNameLength); + } + propName = "function-xsp_sidetone_active"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "l67_aout2-hac"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "aout2-hac", kPropNameLength); + } + propName = "mic3-intmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "ain1-intmic", kPropNameLength); + } + propName = "mic2-extmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "ain2-extmic", kPropNameLength); + } + propName = "mic1-intmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "ain5-intmic", kPropNameLength); + } + propName = "mic4-intmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "ain6-intmic", kPropNameLength); + } + } + if (FindNode(0, "arm-io/i2s0/audio-codec", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "audio-data,cs42l67", propSize); + } + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint8_t *)propData)[0] = 0x11; + } + propName = "l67_func-clock_src_system"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-clock_src_system", kPropNameLength); + } + propName = "l67_func-clock_src_baseband"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-clock_src_baseband", kPropNameLength); + } + } + if (FindNode(0, "arm-io/mca0/audio-codec-reference", &node)) { + propName = "AAPL,ignore"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + if (FindNode(0, "arm-io/mca0/audio-codec-sidetone", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "AAPL,ignore", kPropNameLength); + } + } + if (FindNode(0, "arm-io/mca1/audio-codec-voice", &node)) { + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint8_t *)propData)[0] = 0x01; + } + propName = "l67_clock-sources"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "clock-sources", kPropNameLength); + } + propName = "l67_func-clock_src_route_i2sM"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-clock_src_route_i2sM", kPropNameLength); + } + propName = "l67_func-clock_src_route_bb2w"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-clock_src_route_bb2w", kPropNameLength); + } + } + + } break; + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass1", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c0/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c1/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c1/accelerometer1", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + // Set multi-touch compatibility based upon split/combined rail topology. + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (iphone5b_with_chestnut_split_rail()) + propStr = "multi-touch,n48"; + else + propStr = "multi-touch,n41"; + + memset(propData, 0, propSize); + strlcpy(propData, propStr, propSize); + } + + // Set Chestnut LDO based upon split/combined rail topology. + propName = "function-power_ana"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (iphone5b_with_chestnut_split_rail()) + ((uint8_t *)propData)[8] = 2; // V03 -> PP5V1_CHESTNUT_LDO3 + else + ((uint8_t *)propData)[8] = 1; // V02 -> PP5V1_CHESTNUT_LDO2 + } + + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PxCl', propData, propSize); + } + } + + // vibrator calibration + if (FindNode(0, "arm-io/pwm/vibrator", &node)) { + propName = "duty-cycle"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint32_t pct; + if (syscfgCopyDataForTag('VLSg', (void *)&pct, sizeof(pct)) > 0) { + ((uint32_t *)propData)[0] = ((uint64_t)pct << 32) / 100; + } + } + propName = "intensity-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint32_t pct; + if (syscfgCopyDataForTag('VLWk', (void *)&pct, sizeof(pct)) > 0) { + ((uint32_t *)propData)[1] = ((uint64_t)pct << 32) / 100; + } + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CBAT', propData, propSize); + } + } + + // TriStar 1 on older systems + if (!target_has_tristar2()) { + if (FindNode(0, "arm-io/i2c0/tristar", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "tristar,cbtl1608", kPropNameLength); + } + } + } + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} + +#endif + +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; + +static u_int32_t iphone5b_get_board_rev(void) +{ + + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +static bool iphone5b_with_chestnut_split_rail(void) +{ + if ((platform_get_board_id() == N48_DEV_BOARD_ID) + || (platform_get_board_id() == N49_DEV_BOARD_ID)) { + u_int32_t board_rev = iphone5b_get_board_rev(); + if ((board_rev == DEV1_BOARD) || (board_rev == DEV1A_BOARD)) { + return false; + } + } + + return true; +} + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// white/black: setenv DClr_override 00020000F7F4F5003C3B3B0000000000 +// yellow/black: setenv DClr_override 0002000089F1FA003C3B3B0000000000 +// pink/black: setenv DClr_override 000200007A76FE003C3B3B0000000000 +// blue/black: setenv DClr_override 00020000E0AB46003C3B3B0000000000 +// green/black: setenv DClr_override 0002000077E8A1003C3B3B0000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT + diff --git a/target/iphone5b/pinconfig.c b/target/iphone5b/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/iphone5b/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/iphone5b/rules.mk b/target/iphone5b/rules.mk new file mode 100644 index 0000000..737bc8d --- /dev/null +++ b/target/iphone5b/rules.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2011-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1972=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=CHIPID_RAM_VOLTAGE_LOW \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_MED \ + TARGET_RAM_VOLTAGE_OFFSET=17 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=5 \ + TARGET_USE_HSIC=1 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_DPHYCTL=0x30 \ + TARGET_DSIM_UP_CODE=0x5 \ + TARGET_DSIM_DOWN_CODE=0x1 \ + TARGET_DSIM_SUPPRESS=0x1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + BASEBAND_DTPATH=\"baseband\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci/wlan\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/iphone6/include/target/adbe_settings.h b/target/iphone6/include/target/adbe_settings.h new file mode 100644 index 0000000..3c15c04 --- /dev/null +++ b/target/iphone6/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_AFC_TEARDOWN_ENABLE | DBEMODECNTL_PMGR_CLK_GATE_ENABL| DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/iphone6/include/target/aspnandconfig.h b/target/iphone6/include/target/aspnandconfig.h new file mode 100644 index 0000000..1690248 --- /dev/null +++ b/target/iphone6/include/target/aspnandconfig.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + + +#endif diff --git a/target/iphone6/include/target/gpiodef.h b/target/iphone6/include/target/gpiodef.h new file mode 100644 index 0000000..057d672 --- /dev/null +++ b/target/iphone6/include/target/gpiodef.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPhone6,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_SOCHOT0_IN GPIO(15, 0) // BB_TO_AP_SOCHOT0 + +#define GPIO_LCD_RST GPIO(12, 6) // AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) + +#define GPIO_X162_INT GPIO( 9, 7) // NAVAJO_TO_PMU_INT_H + +#define GPIO_RINGER_AB GPIO( 2, 0) + +#define GPIO_WDOG GPIO( 0, 1) // WDOG + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 5) +#define GPIO_BOARD_REV1 GPIO(14, 4) +#define GPIO_BOARD_REV2 GPIO(14, 3) +#define GPIO_BOARD_REV3 GPIO(14, 2) + +/* which IICs to initialize */ +#define IICS_MASK (3) + +#define TRISTAR_IIC_BUS (0) + +#define DISPLAY_PMU_IIC_BUS (0) + +/* D2094 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 5) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/iphone6/include/target/powerconfig.h b/target/iphone6/include/target/powerconfig.h new file mode 100644 index 0000000..b7f86f1 --- /dev/null +++ b/target/iphone6/include/target/powerconfig.h @@ -0,0 +1,91 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xAE }, // Current OTP enables LDO{1,2,3,4,5,7}, disable LDO4. + { PMU_IIC_BUS, kD2045_ACTIVE6, 0x37 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1, BUCK4_SW2 + { PMU_IIC_BUS, kD2045_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + + { PMU_IIC_BUS, kD2045_HIBERNATE1, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE3, 0x18 }, + { PMU_IIC_BUS, kD2045_HIBERNATE6, 0x24 }, +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// NOTE: N51 PMU continuously reboots when VBatt is near UVLO +// ** GPIO4,GPIO8, and GPIO12 are enabled using the gpio-activate-defaults property in the device tree. + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2045_GPIO2, 0x7A }, // BB_TO_PMU_HOST_WAKE In, L High, Wake, No PU + { PMU_IIC_BUS, kD2045_GPIO3, 0x09 }, // PMU_TO_BB_RST_R_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO4, 0x78 }, // TRISTAR_TO_AP_INT In, L High, Wake**, No PU + { PMU_IIC_BUS, kD2045_GPIO6, 0xDA }, // AP_BI_BATTERY_SWI In, F Edge, Out Hib, Wake, PD, No PU + { PMU_IIC_BUS, kD2045_GPIO7, 0xBB }, // WLAN_TO_PMU_HOST_WAKE In, R Edge, Wake, PD, No PU + { PMU_IIC_BUS, kD2045_GPIO8, 0xE8 }, // CODEC_TO_PMU_MIKEY_INT_L In, Any Edge, Wake**, PU, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO9, 0x09 }, // PMU_TO_BT_REG_ON_R Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO10, 0xAA }, // BT_TO_PMU_HOST_WAKE In, R Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO11, 0x09 }, // PMU_TO_WLAN_REG_ON_R Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO12, 0xB9 }, // NAVAJO_TO_PMU_INT_L In, R Edge, Wake**, No PU + { PMU_IIC_BUS, kD2045_GPIO13, 0x7B }, // OSCAR_TO_PMU_HOST_WAKE In, L High, Wake, PD, No PU + { PMU_IIC_BUS, kD2045_GPIO14, 0x49 }, // PMU_TO_OSCAR_CLK_32K Out 32K, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2045_GPIO15, 0x01 }, // PMU_TO_BB_VBUS_DET Out 0, Push-Pull, VCC_MAIN + { PMU_IIC_BUS, kD2045_GPIO16, 0x38 }, // N5x PMU | Set GPIO16 to 0x38 to better support OTP-AQ on DVT boards + { PMU_IIC_BUS, kD2045_OUT_32K, 0x49 }, // OUT_32K (WLAN_CLK32K) Out 32K, Push-Pull, VBUCK3 + + { PMU_IIC_BUS, kD2045_GPIO_DEB2, 0x12 }, + { PMU_IIC_BUS, kD2045_GPIO_DEB5, 0x12 }, + { PMU_IIC_BUS, kD2045_GPIO_DEB6, 0x12 }, + + { PMU_IIC_BUS, kD2045_BUCK_DWI_CTRL0, 0x03 }, // enable DWI for BUCK0, BUCK1 + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + + { PMU_IIC_BUS, kD2045_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) + + { PMU_IIC_BUS, 0x7000, 0x1D }, // Enable Test Mode + { PMU_IIC_BUS, kD2045_ADC_FSM_TRIM2, 0x00 }, // Enable offset correction on Amber IBUS ADC + { PMU_IIC_BUS, 0x7000, 0x00 }, // Disable Test Mode +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2045_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/iphone6/include/target/uartconfig.h b/target/iphone6/include/target/uartconfig.h new file mode 100644 index 0000000..8134624 --- /dev/null +++ b/target/iphone6/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/iphone6/init.c b/target/iphone6/init.c new file mode 100644 index 0000000..c483153 --- /dev/null +++ b/target/iphone6/init.c @@ -0,0 +1,571 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////// +// CHESTNUT LDO assignment +// +// LCM SAGE GRAPE +// +// DEV1 1 2 3 +// N51-PROTO2 1 1 2 +// N53-PROTO2/2A 2 1 3 +// DEV2/EVT1 2 1 3 +// +/////////////////////////////////////////////////////////// + +#define N51_N53_DEV1_PROTO2_BOARD (0xF) +#define N53_PROTO2A_BOARD (0xE) +#define N51_N53_DEV2_BOARD (0xE) +#define N51_EVT1_MAIN_BOARD (0xE) +#define N51_EVT1_MESA_BOARD (0xD) +#define N53_EVT1_MAIN_BOARD N51_EVT1_MESA_BOARD +#define N51_N53_DEV3_BOARD (0xD) // XXX we got this wrong, should have matched EVT1C. +#define N51_N53_EVT1A_BOARD (0xC) +#define N51_N53_EVT1B_BOARD (0xB) // presumably +#define N51_N53_EVT1C_BOARD (0xA) +#define N51_N53_EVT2_BOARD (0x9) + +static uint32_t iphone6_get_board_rev(void); + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; + +static uint32_t display_config; + +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xC6); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +MIB_CONSTANT(kMIBTargetDisplayCMEngammaTablePtr, kOIDTypeStruct, (void *)linear_rgb_engamma_tables); +MIB_CONSTANT(kMIBTargetDisplayCMEngammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_rgb_engamma_tables)); +MIB_CONSTANT(kMIBTargetDisplayCMDegammaTablePtr, kOIDTypeStruct, (void *)linear_rgb_degamma_tables); +MIB_CONSTANT(kMIBTargetDisplayCMDegammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_rgb_degamma_tables)); +MIB_CONSTANT(kMIBTargetDisplayCMMatrixTablePtr, kOIDTypeStruct, (void *)linear_identity_matrix_tables); +MIB_CONSTANT(kMIBTargetDisplayCMMatrixTableCount, kOIDTypeUInt32, ARRAY_SIZE(linear_identity_matrix_tables)); + +static uint32_t iphone6_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +static bool is_dev1_board() +{ + // DEV config: board-id == 1 + // DEV1 board-rev == 0xF + if (((rPMGR_SCRATCH0 >> 16) & 0xf) == 1) + return (iphone6_get_board_rev() == N51_N53_DEV1_PROTO2_BOARD); + + return false; +} + +static bool is_n51_proto2_board() +{ + // N51 board-id == 0 + // Proto2 board-rev == 0xF + if (((rPMGR_SCRATCH0 >> 16) & 0xf) == 0) + return (iphone6_get_board_rev() == N51_N53_DEV1_PROTO2_BOARD); + + return false; +} + +static bool is_n53_proto2_board() +{ + // N53 board-id == 2 + // Proto2a board-rev == 0xF + if (((rPMGR_SCRATCH0 >> 16) & 0xf) == 2) + return (iphone6_get_board_rev() == N51_N53_DEV1_PROTO2_BOARD); + + return false; +} + +static bool is_mesa_supported() +{ + // X162 INT line needs to be configured active high only on supported boards + // Any DEV board and N51_EVT1_MESA_BOARD and all EVT2 boards and forward. + + // Return true if DEV board. + if ( (((rPMGR_SCRATCH0 >> 16) & 0xf) == 1) || (iphone6_get_board_rev() <= N51_EVT1_MESA_BOARD) ) + return true; + else + return false; +} + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + if(is_mesa_supported()) { + // Configure the X162 INT line to be active high. + // Currently doing this for all DEV boards and EVT1 MESA board + gpio_configure(GPIO_X162_INT, GPIO_CFG_IN); + gpio_configure_pupdn(GPIO_X162_INT, GPIO_PDN); + } + if (iphone6_get_board_rev() == N51_N53_EVT1A_BOARD) { + // Switch Tristar to Pulsing Con Detect mode for n5x and n48/n49 + iic_write(0, 0x35, (uint8_t[]){ 0x1e, 0x30 }, 2); + } + if ((iphone6_get_board_rev() <= N51_N53_EVT1A_BOARD) && (iphone6_get_board_rev() > N51_N53_EVT1C_BOARD)) { + // LDO9 (PP2V8_CAM) to 2.85V (Amber >= A1 version) + // NOTE: Boards with Amber A0 version is handled via power_init pmu_ldo_cold_setup_a0 + iic_write(0, 0xe8, (uint8_t[]){ 0x03, 0x48, 0x5A }, 3); + } + if (iphone6_get_board_rev() <= N51_N53_EVT1C_BOARD) { + // Override pin config to support SOCHOT0 throttler circuit on N5x E1C+ + gpio_configure_pupdn(GPIO_SOCHOT0_IN, GPIO_NO_PUPDN); + + // N5x | Set LDO9 to 2.80V for power throttler circuit + // LDO9_VSEL = 2.8V (0.6V + 25mV*LDO9_VSEL) + iic_write(0, 0xe8, (uint8_t[]){ 0x03, 0x48, 0x58 }, 3); + + // N5x EVT2 | Change LDO3 and LDO13 voltages for Amber OTP-AP and older + // For OTP-AP and older, which is determined by PMU register 0x0001 containing a value 0x16 or lower + // - We need to overwrite LDO3 with 0x60 (used to be 0x64) + // - And we need to overwrite LDO13 with 0x64 (used to be 0x60) + + uint8_t addr[2] = {0x00,0x01}; + uint8_t data; + if (iic_read(0, 0xe8, &addr, sizeof(addr), &data, sizeof(data), IIC_NORMAL) == 0) { + if (data <= 0x16) { + iic_write(0, 0xe8, (uint8_t[]){ 0x03, 0x18, 0x60 }, 3); + iic_write(0, 0xe8, (uint8_t[]){ 0x03, 0x68, 0x64 }, 3); + } + } + } + else { // pre-EVT2 HW + // Hack to support Mesa on older HW + // // N5x EVT2 and beyond - increase drive strength of Mesa SPI_CLK to 8mA (x4), slow slew + { + uintptr_t mesa_spi_clk_gpio; + uint32_t mesa_spi_clk_gpio_val; + + mesa_spi_clk_gpio = (uintptr_t)(GPIO_BASE_ADDR + 0x130); // SPI2_SCLK -> AP_TO_NAVAJO_SPI2_CLK + mesa_spi_clk_gpio_val = *(volatile uint32_t *)mesa_spi_clk_gpio; + mesa_spi_clk_gpio_val &= ~(3 << 10); // reset drive strength + mesa_spi_clk_gpio_val |= (1 << 10); // set drive strength to X2 + *(volatile uint32_t *)mesa_spi_clk_gpio = mesa_spi_clk_gpio_val; + } + } + + // N5x AP_DEV: Enable GPIO5 for WLAN_CLK32K instead of CLK32K_OUT + if (((rPMGR_SCRATCH0 >> 16) & 0xf) == 1) { + iic_write(0, 0xe8, (uint8_t[]){ 0x04, 0x04, 0x49 }, 3); // GPIO5 Out 32K, Push-Pull, VBUCK3 + } + +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000da2; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "n51", 0); +} + +#endif // WITH_ENV + +bool target_has_tristar2(void) +{ + return iphone6_get_board_rev() != N51_N53_DEV1_PROTO2_BOARD; +} + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ + if (is_n51_proto2_board()) + return DISPLAY_PMU_LDO(0); + + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); +} +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *disp0_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize; + char *propName, *propStr; + void *propData; + +#if WITH_HW_DISPLAY_PINOT + // Find the DISP0 (display-subsystem 0) node + FindNode(0, "arm-io/disp0", &disp0_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, disp0_node, backlight_node); + + // Fix up LCM LDO for dev1 and n51proto2 + if (is_dev1_board() || is_n51_proto2_board()) { + propName = "function-lcd_ldo"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((uint8_t *)propData)[8] = 0; // V01 -> PP5V7_LCM_AVDDH_CHESTNUT + } + } +#endif + + // Update the codec and speaker nodes with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi3/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + propName = "at-scale-fmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[8], sizeof(uint32_t)); + } + propName = "at-scale-rcvr"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[12], sizeof(uint32_t)); + } + } + // Update speaker + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[16], sizeof(uint32_t)); + } + } + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c1/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('BLCl', propData, propSize); + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart2/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the X162 calibration data + if (FindNode(0, "arm-io/spi2/mesa", &node)) { + propName = "calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FSCl', propData, propSize); + } + propName = "modulation-ratio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('NvMR', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart2/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart2/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('PxCl', propData, propSize); + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('CBAT', propData, propSize); + } + + // Update vibrator calibration data + if (FindNode(0, "arm-io/i2c0/pmu/vib-pwm/vibrator", &node)) { + uint32_t strong_vset; + uint32_t weak_vset; + + propName = "reg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (syscfgCopyDataForTag('VLSg', (void *)&strong_vset, sizeof(strong_vset)) > 0) + ((uint32_t *)propData)[0] = strong_vset; + } + propName = "intensity-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (syscfgCopyDataForTag('VLWk', (void *)&weak_vset, sizeof(strong_vset)) > 0) + ((uint32_t *)propData)[1] = (((uint64_t)weak_vset << 32) + (strong_vset-1)) / strong_vset; // round up + } + } + + // Multi-touch support + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propStr = NULL; + + if (is_dev1_board()) + propStr = "multi-touch,n41"; + else if (is_n51_proto2_board()) + propStr = "multi-touch,n51-p251"; + + if (propStr != NULL) { + memset(propData, 0, propSize); + strlcpy(propData, propStr, propSize); + } + } + + // Set Grape LDOs for proto2 board + if (is_n51_proto2_board()) { + propName = "function-power_ana"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((uint8_t *)propData)[8] = 0x01; // V02 -> PP5V1_GRAPE_VDDH + } + } + + // Display-pmu Sage LDO + if (is_dev1_board()) { + if (FindNode(0, "arm-io/i2c0/display-pmu", &node)) { + propName = "sage-ldo"; + if (FindProperty(node, &propName, &propData, &propSize)) + *(uint32_t *)propData = 0x01; // V02 -> PP5V7_SAGE_AVDDH_CHESTNUT + } + } + + // TriStar 1 on older systems + if (!target_has_tristar2()) { + if (FindNode(0, "arm-io/i2c0/tristar", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "tristar,cbtl1608", kPropNameLength); + } + } + } + + // Pre-E1C Camera AVDD LDO is coming from PMU LDO9 + if ((target_config_ap() && iphone6_get_board_rev() > N51_N53_EVT1C_BOARD) || + (!target_config_ap() && iphone6_get_board_rev() > N51_N53_DEV3_BOARD)) { + if (FindNode(0, "arm-io/isp", &node)) { + propName = "function-cam_avdd_ldo"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + } + } + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 000200009B9899003C3B3B0000000000 +// gold/white: setenv DClr_override 00020000B3C5D400E3E4E10000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT diff --git a/target/iphone6/pinconfig.c b/target/iphone6/pinconfig.c new file mode 100644 index 0000000..1280d17 --- /dev/null +++ b/target/iphone6/pinconfig.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* N51/N53 (iPhone6,x) Pin Configuration */ + +/* + * N51 pinlist v0.21 + * N51 HW ERS | System | Pinlist + */ + +#define CFG_DISABLED_SS_X4 (CFG_DISABLED | SLOW_SLEW | DRIVE_X4 ) +#define CFG_DISABLED_SS_X1 (CFG_DISABLED | SLOW_SLEW | DRIVE_X1 ) +#define CFG_DISABLED_SS_X4_PD (CFG_DISABLED | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_DISABLED_SS_X1_PD (CFG_DISABLED | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_DISABLED_SS_X4_PU (CFG_DISABLED | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_DISABLED_SS_X1_PU (CFG_DISABLED | SLOW_SLEW | DRIVE_X1 | PULL_UP ) +#define CFG_IN_SS_X1 (CFG_IN | SLOW_SLEW | DRIVE_X1 ) +#define CFG_IN_SS_X2 (CFG_IN | SLOW_SLEW | DRIVE_X2 ) +#define CFG_IN_SS_X4 (CFG_IN | SLOW_SLEW | DRIVE_X4 ) +#define CFG_IN_SS_X4_PD (CFG_IN | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_IN_SS_X1_PD (CFG_IN | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_IN_SS_X4_PU (CFG_IN | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_IN_SS_X1_PU (CFG_IN | SLOW_SLEW | DRIVE_X1 | PULL_UP ) +#define CFG_OUT_0_SS_X4 (CFG_OUT_0 | SLOW_SLEW | DRIVE_X4 ) +#define CFG_OUT_0_SS_X4_PD (CFG_OUT_0 | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_OUT_0_SS_X2_PD (CFG_OUT_0 | SLOW_SLEW | DRIVE_X2 | PULL_DOWN) +#define CFG_OUT_0_SS_X1_PD (CFG_OUT_0 | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_OUT_1_SS_X4 (CFG_OUT_1 | SLOW_SLEW | DRIVE_X4 ) +#define CFG_OUT_1_SS_X4_PU (CFG_OUT_1 | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_OUT_1_SS_X1_PU (CFG_OUT_1 | SLOW_SLEW | DRIVE_X1 | PULL_UP ) +#define CFG_FUNC0_SS_X1 (CFG_FUNC0 | SLOW_SLEW | DRIVE_X1 ) +#define CFG_FUNC0_SS_X2 (CFG_FUNC0 | SLOW_SLEW | DRIVE_X2 ) +#define CFG_FUNC0_SS_X4 (CFG_FUNC0 | SLOW_SLEW | DRIVE_X4 ) +#define CFG_FUNC0_SS_X4_PD (CFG_FUNC0 | SLOW_SLEW | DRIVE_X4 | PULL_DOWN) +#define CFG_FUNC0_SS_X2_PD (CFG_FUNC0 | SLOW_SLEW | DRIVE_X2 | PULL_DOWN) +#define CFG_FUNC0_SS_X1_PD (CFG_FUNC0 | SLOW_SLEW | DRIVE_X1 | PULL_DOWN) +#define CFG_FUNC0_SS_X4_PU (CFG_FUNC0 | SLOW_SLEW | DRIVE_X4 | PULL_UP ) +#define CFG_FUNC0_SS_X1_PU (CFG_FUNC0 | SLOW_SLEW | DRIVE_X1 | PULL_UP ) + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED_SS_X4_PD, // TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_FUNC0_SS_X4_PD, // WDOG -> WDOG_SOC + CFG_IN_SS_X1, // GPIO0 -> BUTTON_TO_AP_MENU_KEY_BUFF_L (REQUEST_DFU2) + CFG_IN_SS_X1, // GPIO1 -> BUTTON_TO_AP_HOLD_KEY_BUFF_L (REQUEST_DFU1) + CFG_IN_SS_X1_PU, // GPIO2 -> BUTTON_TO_AP_VOL_UP_L + CFG_IN_SS_X1_PU, // GPIO3 -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN_SS_X1_PU, // GPIO4 -> SPKAMP_TO_AP_INT_L + CFG_OUT_0_SS_X4_PD, // GPIO5 -> AP_TO_SPKAMP_BEE_GEES + +/* Port 1 */ + CFG_OUT_0_SS_X4_PD, // GPIO6 -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0_SS_X4_PD, // GPIO7 -> AP_TO_BT_WAKE + CFG_IN_SS_X4, // GPIO8 -> AP_TO_BB_RST_L + CFG_DISABLED_SS_X4, // GPIO9 -> AP_TO_BB_JTAG_TDI + CFG_DISABLED_SS_X4_PD, // GPIO10 -> AP_TO_BB_JTAG_TDO + CFG_DISABLED_SS_X4_PD, // GPIO11 -> AP_TO_HEADSET_HS3_CTRL + CFG_DISABLED_SS_X4_PD, // GPIO12 -> AP_TO_HEADSET_HS4_CTRL + CFG_IN_SS_X1_PU, // GPIO13 -> PMU_TO_AP_IRQ_L + +/* Port 2 */ + CFG_IN_SS_X1, // GPIO14 -> BUTTON_TO_AP_RINGER_A + CFG_OUT_0_SS_X4, // GPIO15 -> AP_TO_BB_WAKE_MODEM + CFG_DISABLED_SS_X1_PU, // GPIO16 -> N/C -> BOARD_ID[3] + CFG_IN_SS_X1, // GPIO17 -> AP_TO_OSCAR_DBGEN + CFG_DISABLED_SS_X1_PU, // GPIO18 -> BOARD_INFO -> BOOT_CONFIG[0] + CFG_DISABLED_SS_X4_PD, // GPIO19 -> AP_TO_PMU_KEEPACT + CFG_IN_SS_X1_PU, // GPIO20 -> TOUCH_TO_AP_INT_L + CFG_OUT_0_SS_X4_PD, // GPIO21 -> AP_TO_TOUCH_GRAPE_RESET_L + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_FUNC0_SS_X4_PU, // UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0_SS_X1_PU, // UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1_SS_X4_PU, // UART1_RTSN -> AP_TO_BT_UART1_RTS_L + CFG_FUNC0_SS_X1_PU, // UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_FUNC0_SS_X4_PU, // UART2_TXD -> AP_TO_OSCAR_UART2_TXD + CFG_FUNC0_SS_X1_PU, // UART2_RXD -> OSCAR_TO_AP_UART2_RXD + CFG_OUT_1_SS_X4_PU, // UART2_RTSN -> AP_TO_OSCAR_RESET_L + CFG_IN_SS_X1_PD, // UART2_CTSN -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 5 */ + CFG_FUNC0_SS_X4, // UART3_TXD -> AP_TO_WLAN_UART3_TXD + CFG_FUNC0_SS_X1, // UART3_RXD -> WLAN_TO_AP_UART3_RXD + CFG_DISABLED_SS_X1_PD, // UART3_RTSN -> BB_TO_AP_PP_SYNC + CFG_OUT_0_SS_X4_PD, // UART3_CTSN -> AP_TO_RCAM_VDDCORE_EN + CFG_FUNC0_SS_X2, // UART5_RXD -> AP_BI_BATTERY_SWI + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 6 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 7 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 8 */ + CFG_OUT_0_SS_X4, // UART4_TXD -> AP_TO_BB_UART4_TXD + CFG_FUNC0_SS_X1, // UART4_RXD -> BB_TO_AP_UART4_RXD + CFG_OUT_0_SS_X4, // UART4_RTSN -> AP_TO_BB_UART4_RTS_L + CFG_FUNC0_SS_X1, // UART4_CTSN -> BB_TO_AP_UART4_CTS_L + CFG_FUNC0_SS_X4_PD, // SPI1_SCLK -> AP_TO_TOUCH_SPI1_CLK + CFG_FUNC0_SS_X4_PD, // SPI1_MOSI -> AP_TO_TOUCH_SPI1_MOSI + CFG_FUNC0_SS_X1_PD, // SPI1_MISO -> TOUCH_TO_AP_SPI1_MISO + CFG_FUNC0_SS_X4_PU, // SPI1_SSIN -> AP_TO_TOUCH_SPI1_CS_L + +/* Port 9 */ + CFG_DISABLED_SS_X1_PU, // SPI0_SCLK -> N/C -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED_SS_X1_PU, // SPI0_MOSI -> N/C -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED_SS_X1_PU, // SPI0_MISO -> N/C -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED_SS_X1_PD, // SPI0_SSIN -> N/C + CFG_FUNC0_SS_X4, // SPI2_SCLK -> AP_TO_NAVAJO_SPI2_CLK + CFG_FUNC0_SS_X2, // SPI2_MOSI -> AP_TO_NAVAJO_SPI2_MOSI + CFG_FUNC0_SS_X2_PD, // SPI2_MISO -> NAVAJO_TO_AP_SPI2_MISO + CFG_IN_SS_X1_PD, // SPI2_SSIN -> NAVAJO_TO_PMU_INT_H + +/* Port 10 */ + CFG_FUNC0_SS_X4, // I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0_SS_X4, // I2C0_SCL -> AP_TO_I2C0_SDA + CFG_FUNC0_SS_X4, // I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0_SS_X4, // I2C1_SCL -> AP_TO_ISC1_SCL + CFG_FUNC0_SS_X2, // ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0_SS_X2, // ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0_SS_X2, // ISP1_SDA -> AP_TO_FCAM_I2C_SCL + CFG_FUNC0_SS_X2, // ISP1_SCL -> AP_TO_FCAM_I2C_SCL + +/* Port 11 */ + CFG_OUT_0_SS_X2_PD, // SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED_SS_X4_PD, // SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + CFG_DISABLED_SS_X1_PD, // SENSOR0_XSHUTDOWN -> N/C + CFG_DISABLED_SS_X1, // SENSOR0_ISTRB -> BB_TO_AP_IPC_GPIO + CFG_OUT_0_SS_X2_PD, // SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED_SS_X4_PD, // SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0_SS_X4_PD, // SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_OUT_0_SS_X4_PD, // SENSOR1_ISTRB -> AP_TO_LEDDRV_EN + +/* Port 12 */ + CFG_FUNC0_SS_X4_PD, // SPI3_MOSI -> AP_TO_CODEC_SPI3_MOSI + CFG_FUNC0_SS_X1_PD, // SPI3_MISO -> CODEC_TO_AP_SPI3_MISO + CFG_FUNC0_SS_X4_PD, // SPI3_SCLK -> AP_TO_CODEC_SPI3_CLK + CFG_FUNC0_SS_X4_PD, // SPI3_SSIN -> AP_TO_CODEC_SPI3_CS_L + CFG_DISABLED_SS_X1_PD, // I2C2_SDA -> N/C + CFG_DISABLED_SS_X1_PD, // I2C2_SCL -> N/C + CFG_OUT_0_SS_X4_PD, // GPIO22 -> AP_TO_LCM_RESET_L + CFG_DISABLED_SS_X1_PD, // GPIO23 -> LCM_TO_AP_HIFA_BSYNC + +/* Port 13 */ + CFG_DISABLED_SS_X1_PD, // GPIO24 -> BB_TO_AP_RESET_DET_L + CFG_DISABLED_SS_X1_PU, // GPIO25 -> BOARD_INFO -> BOOT_CONFIG[1] + CFG_DISABLED_SS_X1_PD, // GPIO26 -> FORCE_DFU + CFG_DISABLED_SS_X1_PD, // GPIO27 -> DFU_STATUS + CFG_DISABLED_SS_X1_PU, // GPIO28 -> N/C -> BOOT_CONFIG[2] + CFG_DISABLED_SS_X1_PU, // GPIO29 -> N/C -> BOOT_CONFIG[3] + CFG_IN_SS_X1_PU, // GPIO30 -> CODEC_TO_AP_INT_L + CFG_IN_SS_X4, // GPIO31 -> AP_TO_RADIO_ON_L + +/* Port 14 */ + CFG_DISABLED_SS_X4, // GPIO32 -> AP_TO_BB_JTAG_TCK + CFG_DISABLED_SS_X4, // GPIO33 -> AP_TO_BB_JTAG_TMS + CFG_DISABLED_SS_X1_PU, // GPIO34 -> BOARD_INFO -> BOARD_REV3 + CFG_DISABLED_SS_X1_PU, // GPIO35 -> BOARD_INFO -> BOARD_REV2 + CFG_DISABLED_SS_X1_PU, // GPIO36 -> BOARD_INFO -> BOARD_REV1 + CFG_DISABLED_SS_X1_PU, // GPIO37 -> BOARD_INFO -> BOARD_REV0 + CFG_DISABLED_SS_X1_PD, // GPIO38 -> N/C + CFG_DISABLED_SS_X1_PD, // DISPLAY_SYNC -> N/C + +/* Port 15 */ + CFG_FUNC0_SS_X1_PU, // SOCHOT0 -> BB_TO_AP_SOCHOT0 + CFG_FUNC0_SS_X4, // SOCHOT1 -> AP_TO_PMU_SOCHOT1 + CFG_FUNC0_SS_X4_PU, // UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + CFG_FUNC0_SS_X1_PU, // UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_DISABLED_SS_X1_PD, // DWI_DI -> N/C + CFG_FUNC0_SS_X1_PD, // DWI_D0 -> 45_AP_TO_PMU_DWI_DO + CFG_FUNC0_SS_X1_PD, // DWI_CLK -> 45_AP_TO_PMU_DWI_CLK + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_FUNC0_SS_X4_PD, // I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0_SS_X4_PD, // I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0_SS_X1_PD, // I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED_SS_X4, // I2S1_MCK -> AP_TO_BB_JTAG_TRST_L + CFG_FUNC0_SS_X4_PD, // I2S1_LRCK -> AP_TO_BB_I2S1_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S1_BCLK -> 45_AP_TO_BB_I2S1_BCLK + CFG_FUNC0_SS_X4_PD, // I2S1_DOUT -> AP_TO_BB_I2S1_DOUT + +/* Port 17 */ + CFG_FUNC0_SS_X1_PD, // I2S1_DIN -> BB_TO_AP_I2S1_DIN + CFG_FUNC0_SS_X4_PD, // I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0_SS_X4_PD, // I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0_SS_X1_PD, // I2S2_DIN -> CODEC_TO_AP_XSP_I2S2_DIN + CFG_IN_SS_X1_PU, // I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0_SS_X4_PD, // I2S3_LRCK -> AP_TO_BT_I2S3_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S3_BCLK -> 45_AP_TO_BT_I2S3_BCLK + +/* Port 18 */ + CFG_FUNC0_SS_X4_PD, // I2S3_DOUT -> AP_TO_BT_I2S3_DOUT + CFG_FUNC0_SS_X1_PD, // I2S3_DIN -> BT_TO_AP_I2S3_DIN + CFG_IN_SS_X1_PD, // I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0_SS_X4_PD, // I2S4_LRCK -> AP_TO_CODEC_VSP_I2S4_LRCLK + CFG_FUNC0_SS_X4_PD, // I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S4_BCLK + CFG_FUNC0_SS_X4_PD, // I2S4_DOUT -> AP_TO_CODEC_VSP_I2S4_DOUT + CFG_FUNC0_SS_X1_PD, // I2S4_DIN -> CODEC_TO_AP_VSP_I2S4_DIN + CFG_DISABLED, // NULL -> + +/* Port 19 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 20 */ + CFG_OUT_0_SS_X4_PD, // TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_DISABLED_SS_X4_PD, // TMR32_PWM1 -> AP_TO_PMU_VIBE_PWM_EN + CFG_FUNC0_SS_X4, // TMR32_PWM2 -> 45_AP_TO_TOUCH_CLK32K_RESET_L + CFG_OUT_0_SS_X4, // SIO_7816UART0_SDA -> AP_TO_BB_HSIC1_RDY + CFG_DISABLED_SS_X1_PD, // SIO_7816UART0_SCL -> BB_TO_AP_HSIC1_RDY + CFG_DISABLED_SS_X1_PD, // SIO_7816UART0_RST -> BB_TO_AP_HSIC1_REMOTE_WAKE + CFG_OUT_0_SS_X4, // SIO_7816UART1_SDA -> AP_TO_WLAN_HSIC2_RDY + CFG_IN_SS_X1_PD, // SIO_7816UART1_SCL -> WLAN_TO_AP_HSIC2_RDY + +/* Port 21 */ + CFG_IN_SS_X1_PD, // SIO_7816UART0_RST -> WLAN_TO_AP_HSIC2_REMOTE_WAKE + CFG_FUNC0_SS_X4_PU, // UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0_SS_X1_PU, // UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED_SS_X4_PD, // I2C3_SDA -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED_SS_X4_PD, // I2C3_SCL -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_DISABLED_SS_X1_PD, // EDP_HPD -> N/C + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 22 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 23 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 24 */ + CFG_DISABLED_SS_X1_PD, // EPD_HPD -> N/C + CFG_FUNC0_SS_X4_PD, // I2S0_MCK -> 45_AP_TO_CODEC_I2S_MCLK_R + CFG_FUNC0_SS_X4_PD, // I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED_SS_X1_PD, // TESTMODE -> N/C + CFG_DISABLED_SS_X1_PD, // FAST_SCAN_CLK -> N/C + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/iphone6/rules.mk b/target/iphone6/rules.mk new file mode 100644 index 0000000..560288f --- /dev/null +++ b/target/iphone6/rules.mk @@ -0,0 +1,44 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2045=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_VID0_CLK_CFG=0x86100000 \ + DISPLAY_IPHONE_TUNABLES=1 \ + TARGET_ENABLE_CM=1 \ + TARGET_DDR_798M=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_CHESTNUT_USE_LOW_RIPPLE_MODE=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_DPHYCTL=0x30 \ + TARGET_DSIM_UP_CODE=0x1 \ + TARGET_DSIM_DOWN_CODE=0x1 \ + TARGET_DSIM_SUPPRESS=0x1 \ + WITH_HW_AGC_MIPI=1 \ + TARGET_ADBE0_VBLANK_POSITION=0xF0000 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_CPU_APSC=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci1/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/iphone7/include/target/adbe_settings.h b/target/iphone7/include/target/adbe_settings.h new file mode 100644 index 0000000..1cecd99 --- /dev/null +++ b/target/iphone7/include/target/adbe_settings.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = +{ + { + .name = "D600", + .adbe0_vblank_pos_vbi_pulse = 0x030b, + .adbe0_vblank_clk_gate_wakeup = 0x030b, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, + + { + .name = "D500", + .adbe0_vblank_pos_vbi_pulse = 0x021d, + .adbe0_vblank_clk_gate_wakeup = 0x021d, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, + + { + .name = "D403", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, + + { + .name = "D500_2LANE", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x021d, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, + +}; + +#endif diff --git a/target/iphone7/include/target/aspnandconfig.h b/target/iphone7/include/target/aspnandconfig.h new file mode 100644 index 0000000..aac601b --- /dev/null +++ b/target/iphone7/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (4*1024*1024) + +#endif diff --git a/target/iphone7/include/target/gpiodef.h b/target/iphone7/include/target/gpiodef.h new file mode 100644 index 0000000..1492904 --- /dev/null +++ b/target/iphone7/include/target/gpiodef.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iphone7,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 9, 2) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO( 9, 1) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO( 9, 0) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO( 8, 7) // 71 : GPIO[37] + +/* Miscellaneous Pins */ + +/* Display reset */ +#define GPIO_LCD_RST GPIO( 0, 1) // 1 : ULPI_STP -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + +/* Ringer Switch */ +#define GPIO_RINGER_AB GPIO(16, 3) // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + +/* D2186 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(13, 3) // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (0) + +#define DISPLAY_PMU_IIC_BUS (0) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/iphone7/include/target/powerconfig.h b/target/iphone7/include/target/powerconfig.h new file mode 100644 index 0000000..ff12e62 --- /dev/null +++ b/target/iphone7/include/target/powerconfig.h @@ -0,0 +1,150 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 1 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2186_ACTIVE3, 0xAE }, // Current OTP enables LDO{1,2,3,4,5,7}, disable LDO4. + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x17 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1 + { PMU_IIC_BUS, kD2186_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x37 }, // enable BUCK4_SW2 N56 and N61: PP1V2_Oscar and PP1V8_Oscar brought up in wrong order during iBoot + { PMU_IIC_BUS, kD2186_ACTIVE4, 0x2C }, // POR OTP enables LDO{13,11,10} disable LDO{9,8} see target_early_init() to workaround pre-EVT boards + + { PMU_IIC_BUS, kD2186_HIBERNATE3, 0x18 }, // enable LDO3+LDO4 in hibernate + + { PMU_IIC_BUS, kD2186_OUT_32K, 0x49 }, // enable OUT32 clock + + { PMU_IIC_BUS, kD2186_BUCK6_VSEL, 0x26 }, // N56/T133 Adi PMU: Change default voltage on BUCK6 to 2.0375 V + + { PMU_IIC_BUS, kD2186_LDO13_VSEL, 0x49 }, // 3.025v = (1.2+.025*0x49) Change LDO13 to output 3.025V + + { PMU_IIC_BUS, kD2186_LDO1_VSEL, 0x51 }, // N61 EVT: PP3V3_USB Voltage reduction (PMU LDO1), set LDO1 to 3.225v (1.2+.025*0x51) + + { PMU_IIC_BUS, kD2186_BUCK6_MODE, 0x72 }, // N56 - BUCK6 mode for Sphere + // for N61 this is NC, so will never be enabled, rdar://16383138 + { PMU_IIC_BUS, kD2186_UOV_CONTROL, 0x1 }, // Disabling Adi PMU OV/UV Comparators for N61 & N56 DVT + { PMU_IIC_BUS, kD2186_UOV_CONTROL, 0x0 }, + + // begin TEST_MODE PMU Buck1 settings need to change to fix GPU hang + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA }, // enable test register access + { PMU_IIC_BUS, kD2186_BUCK1_START_ILIMIT, 0x0F }, // increase current limit to 718 mAh + { PMU_IIC_BUS, kD2186_BUCK1_FSM_TRIM2, 0x27 }, // change startup timer value to 150us + + // N61/N56: PMU power sequence update in iBoot + { PMU_IIC_BUS, kD2186_LDO1_SLOT, 0x66 }, // LDO1 from slot +3/-4 to +6/-7 + + // OTP-AL values rdar://16383138 iBoot PMU overwrites for part shortage (N56 EVT build) + { PMU_IIC_BUS, kD2186_VDD_FAULT, 0x23 }, // update PRE_UVLO and VDD_FAULT_LOWER + { PMU_IIC_BUS, kD2186_BUCK0_FSM_TRIM2, 0x77 }, // increase BUCK0 startup delay + { PMU_IIC_BUS, kD2186_BUCK1_SYNC_ILIMIT, 0x3F }, // increase BUCK1 PWM ILIM + { PMU_IIC_BUS, kD2186_BUCK2_FSM_TRIM2, 0x77 }, // increase BUCK2 startup delay + { PMU_IIC_BUS, kD2186_BUCK3_FSM_TRIM2, 0x76 }, // increase BUCK3 startup delay + { PMU_IIC_BUS, kD2186_BUCK4_FSM_TRIM2, 0x77 }, // increase BUCK4 startup delay + { PMU_IIC_BUS, kD2186_BUCK5_FSM_TRIM2, 0x77 }, // increase BUCK5 startup delay + { PMU_IIC_BUS, kD2186_BUTTON3_CONF, 0xF6 }, // disable internal pull-up on BUTTON3 (rocker switch), 50ms debounce + { PMU_IIC_BUS, kD2186_BUTTON4_CONF, 0x14 }, // spurious interrupts + + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS }, // disabled test register access + // end TEST_MODE NOTE: do NOT insert any lines between this begin-end TEST_MODE block +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// Settings as of N56 | IOSpreadsheet, version 0v9 +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2186_GPIO1_CONF1, 0x8a }, // CHG_TO_PMU_INT_L In, L Low, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO1_CONF2, 0x72 }, // CHG_TO_PMU_INT_L POR + { PMU_IIC_BUS, kD2186_GPIO2_CONF1, 0x8a }, // BB_TO_PMU_HOST_WAKE_L In, L Low, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO2_CONF2, 0x72 }, // BB_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO3_CONF1, 0x01 }, // PMU_TO_BB_RST_R_L Out 0, Low , Push-Pull + { PMU_IIC_BUS, kD2186_GPIO3_CONF2, 0x12 }, // PMU_TO_BB_RST_R_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO4_CONF1, 0x83 }, // TRISTAR_TO_AP_INT In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO4_CONF2, 0x72 }, // TRISTAR_TO_AP_INT POR + { PMU_IIC_BUS, kD2186_GPIO5_CONF1, 0x83 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO5_CONF2, 0x72 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO6_CONF1, 0x01 }, // PMU_TO_OSCAR_RESET_CLK_32K_L Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO6_CONF2, 0x12 }, // PMU_TO_OSCAR_RESET_CLK_32K_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO7_CONF1, 0x83 }, // WLAN_TO_PMU_HOST_WAKE In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO7_CONF2, 0x72 }, // WLAN_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO8_CONF1, 0xA2 }, // CODEC_TO_PMU_MIKEY_INT_L In, Any Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO8_CONF2, 0x12 }, // CODEC_TO_PMU_MIKEY_INT_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO9_CONF1, 0x01 }, // PMU_TO_BT_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO9_CONF2, 0x12 }, // PMU_TO_BT_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO10_CONF1, 0x92 }, // BT_TO_PMU_HOST_WAKE In, R Edge, Wake, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO10_CONF2, 0x72 }, // BT_TO_PMU_HOST_WAKE Disabled + { PMU_IIC_BUS, kD2186_GPIO11_CONF1, 0x01 }, // PMU_TO_WLAN_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO11_CONF2, 0x12 }, // PMU_TO_WLAN_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO12_CONF1, 0x08 }, // AP_TO_I2C0_SCL Out, nReset, PU + { PMU_IIC_BUS, kD2186_GPIO12_CONF2, 0x72 }, // AP_TO_I2C0_SCL POR + { PMU_IIC_BUS, kD2186_GPIO13_CONF1, 0x83 }, // OSCAR_TO_PMU_HOST_WAKE In, In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO13_CONF2, 0x72 }, // OSCAR_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO14_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO14_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO15_CONF1, 0x01 }, // PMU_TO_BB_VBUS_DET Out 0, Low, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO15_CONF2, 0x02 }, // PMU_TO_BB_VBUS_DET VCC_MAIN + { PMU_IIC_BUS, kD2186_GPIO16_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO16_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO17_CONF1, 0x88 }, // WLAN_TO_PMU_PCIE_WAKE_L In, L Low, PU + { PMU_IIC_BUS, kD2186_GPIO17_CONF2, 0x72 }, // WLAN_TO_PMU_PCIE_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO18_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO18_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO19_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO19_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO20_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO20_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO21_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO21_CONF2, 0x72 }, // POR + +// TODO: configure debounce for WAS kD2045_GPIO_DEB2,kD2045_GPIO_DEB5,kD2045_GPIO_DEB6? + + { PMU_IIC_BUS, kD2186_BUCK_DWI_CTRL0, 0x07 }, // enable DWI for BUCK0, BUCK1, BUCK2 + { PMU_IIC_BUS, kD2186_SYS_CTRL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + { PMU_IIC_BUS, kD2186_SYS_CTRL1, 0x24 }, // disable PROT_FET_DIS, BAT_PWR_SUSP rdar://15680815 + +// TODO: verify + { PMU_IIC_BUS, kD2186_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 + +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define TARGET_POWER_NEEDS_BATTERY_PROTECTION_RESET 1 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/iphone7/include/target/uartconfig.h b/target/iphone7/include/target/uartconfig.h new file mode 100644 index 0000000..f81b712 --- /dev/null +++ b/target/iphone7/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/iphone7/init.c b/target/iphone7/init.c new file mode 100644 index 0000000..5d392d8 --- /dev/null +++ b/target/iphone7/init.c @@ -0,0 +1,1105 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#endif + +#define N56_AP_BOARD_ID (0x4) // AP board ID +#define N56_DEV_BOARD_ID (0x5) // DEV board ID + +#define N61_AP_BOARD_ID (0x6) // AP board ID +#define N61_DEV_BOARD_ID (0x7) // DEV board ID + +#define N56_DEV2_BOARD_REV (0xD) +#define N61_DEV2_BOARD_REV (0xD) + +#define N56_DEV3_BOARD_REV (0xB) +#define N61_DEV3_BOARD_REV (0xB) + +#define N56_PROTO2_BOARD_REV (0xC) +#define N61_PROTO2_BOARD_REV (0xC) + +#define N56_EVT1_BOARD_REV (0xB) +#define N61_EVT1_BOARD_REV (0xB) + +#define N56_EVT1_DOE_BOARD_REV (0xA) +#define N61_EVT1_DOE_BOARD_REV (0xA) + +#define N56_EVT1_CARRIER_BOARD_REV (0x9) +#define N61_EVT1_CARRIER_BOARD_REV (0x9) + +// Combined Board Id/Board Revision +// IMPORTANT: IF YOU CHANGE THE ORDER OF THESE ENUMERATORS YOU MUST CHECK +// FOR ANY > or < RELATIONSHIPS THAT MAY NEED TO ALSO CHANGE. +typedef enum { + BOARD_TYPE_UNKNOWN = 0, +// BOARD_TYPE_N56_DEV1 = 1, // Deprecated +// BOARD_TYPE_N56_PROTO1 = 2, // Deprecated +// BOARD_TYPE_T133_PROTO1 = 3, // Deprecated +// BOARD_TYPE_N56_DEV2 = 4, // Deprecated +// BOARD_TYPE_N61_DEV2 = 5, // Deprecated +// BOARD_TYPE_N61_DEV1 = 6, // Deprecated + BOARD_TYPE_N61_PROTO2 = 7, + BOARD_TYPE_N56_PROTO2 = 8, + BOARD_TYPE_N61_EVT1 = 9, + BOARD_TYPE_N56_EVT1 = 10, + BOARD_TYPE_N61_DEV3 = 11, + BOARD_TYPE_N56_DEV3 = 12, +} board_type; + +// Display panel type +typedef enum { + DISPLAY_PANEL_TYPE_UNKNOWN = 0, + DISPLAY_PANEL_TYPE_D500, + DISPLAY_PANEL_TYPE_D600, + DISPLAY_PANEL_TYPE_D500_2LANE, + // Metadata + DISPLAY_PANEL_TYPE_COUNT +} display_panel_type; + +#if SUB_TARGET_N56 +#define DEFAULT_DISPLAY_PANEL DISPLAY_PANEL_TYPE_D600 +#endif +#if SUB_TARGET_N61 +#define DEFAULT_DISPLAY_PANEL DISPLAY_PANEL_TYPE_D500 +#endif + +static const char *display_panel_types[] = { + "UNKNOWN", + "D500", + "D600", + "D500_2LANE" +}; + +static board_type iphone7_get_board_type(void); +static uint32_t iphone7_get_board_rev(void); +static void iphone7_get_display_info(void); +uint32_t target_get_display_panel_type(void); + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; +static display_panel_type display_panel; +static bool display_panel_missing; +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +static mipi_t display_panel_configurations[] = { + { + .lanes = 0, + .esc_div = 0, + .pll_n = 0, + .pll_m = 0, + .pll_p = 0, + .hsfreq = 0, + .target_phy_settings = { 0, {}}, //0 Mhz + + }, + { + .lanes = 3, + .esc_div = 6, + .pll_n = 0, + .pll_m = 0, + .pll_p = 0, + .hsfreq = 0, + .target_phy_settings = { 4, {{0x44, 1, {0x52}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //843 Mhz + + }, + { + .lanes = 4, + .esc_div = 8, + .pll_n = 0, + .pll_m = 0, + .pll_p = 0, + .hsfreq = 0, + .target_phy_settings = { 4, {{0x44, 1, {0x36}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //1200 Mhz + }, + { + .lanes = 2, + .esc_div = 8, + .pll_n = 0, + .pll_m = 0, + .pll_p = 0, + .hsfreq = 0, + .target_phy_settings = { 4, {{0x44, 1, {0x36}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //1200 Mhz + }, +}; +#endif + +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xC6); +#if SUB_TARGET_N56 +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 3); +MIB_CONSTANT(kMIBTargetBacklight1I2CBus, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetBacklight1I2CAddress, kOIDTypeUInt32, 0xC6); +#else +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +#endif +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static uint32_t iphone7_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +static board_type iphone7_get_board_type(void) +{ + static board_type board_type = BOARD_TYPE_UNKNOWN; + + if (board_type != BOARD_TYPE_UNKNOWN) { + return board_type; + } + + uint32_t board_id = platform_get_board_id(); + uint32_t board_rev = iphone7_get_board_rev(); + + switch (board_id) { +#if SUB_TARGET_N56 + case N56_AP_BOARD_ID: + switch (board_rev) { + case N56_PROTO2_BOARD_REV: + board_type = BOARD_TYPE_N56_PROTO2; + return board_type; + + default: + if (board_rev > N56_EVT1_BOARD_REV) { + // Deprecated or unsupported board revision + goto fail; + } + + /* FALL THROUGH */ + + case N56_EVT1_BOARD_REV: + board_type = BOARD_TYPE_N56_EVT1; + return board_type; + } +#endif // SUB_TARGET_N56 +#if SUB_TARGET_N61 + case N61_AP_BOARD_ID: { + switch (board_rev) { + case N61_PROTO2_BOARD_REV: + board_type = BOARD_TYPE_N61_PROTO2; + return board_type; + + default: + if (board_rev > N61_EVT1_BOARD_REV) { + // Deprecated or unsupported board revision + goto fail; + } + + /* FALL THROUGH */ + + case N61_EVT1_BOARD_REV: + board_type = BOARD_TYPE_N61_EVT1; + return board_type; + } + } +#endif // SUB_TARGET_N61 +#if SUB_TARGET_N56 + case N56_DEV_BOARD_ID: { + switch (board_rev) { + case N56_DEV3_BOARD_REV: + board_type = BOARD_TYPE_N56_DEV3; + return board_type; + default: + goto fail; + } + } +#endif // SUB_TARGET_N56 +#if SUB_TARGET_N61 + case N61_DEV_BOARD_ID: { + switch (board_rev) { + case N61_DEV3_BOARD_REV: + board_type = BOARD_TYPE_N61_DEV3; + return board_type; + default: + goto fail; + } + } +#endif // SUB_TARGET_N61 + default: + goto fail; + } + +fail: + platform_not_supported(); + return BOARD_TYPE_UNKNOWN; +} + + +// The panel id pin mappings for development boards are described by the +// following id pin states: + +// ID1 ID0 Panel Switch Board Status +// ---- ---- ----- ------ ----- ------------- +// Open Open D403 Sage2 N56/N61 Deprecated +// PU PD D500 Sage2 N61 Deprecated +// Open PD D500 Meson N61 Valid for N61 +// PD PU D600 Sage2 N56 Deprecated +// PD Open D600 Meson N56 Valid for N56 + +static void iphone7_get_display_info(void) +{ +// Display types for form-factor devices are determined by the board id. + if (target_config_ap()) { + display_panel = DEFAULT_DISPLAY_PANEL; + return; + } + +// For development boards we have to sense which type of display daughter card +// is plugged in. However, for boards with the boot configuration set to NVMe +// we can't do this because one of the display sense pins serves double duty +// as the S3E reset pin (AP_TO_S3E_RESET_L). Therefore, for boards that boot +// from NVMe, force the display type to correspond to the board id. + + uint32_t boot_config = platform_get_boot_config(); + if ((boot_config == BOOT_CONFIG_NVME0) + || (boot_config == BOOT_CONFIG_NVME0_TEST)) { + display_panel = DEFAULT_DISPLAY_PANEL; + return; + } + +// Display panel id sense pins +#define DISPLAY_TO_AP_ID0 GPIO( 1, 1) // 9: ULPI_DATA[2] -> DISPLAY_TO_AP_ID0 +#define DISPLAY_TO_AP_ID1 GPIO( 0, 6) // 6: ULPI_DATA[4] -> DISPLAY_TO_AP_ID1 + + const char *id0; + const char *id1; + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_IN); + gpio_configure(DISPLAY_TO_AP_ID1, GPIO_CFG_IN); + + gpio_configure_pupdn(DISPLAY_TO_AP_ID0, GPIO_PUP); + gpio_configure_pupdn(DISPLAY_TO_AP_ID1, GPIO_PUP); + + display_panel_missing = false; + + spin(100); // Wait 100us + + if (!gpio_read(DISPLAY_TO_AP_ID1)) { + // ID1 has an external pull down. + id1 = "pd"; + + if (!gpio_read(DISPLAY_TO_AP_ID0)) { + // ID0 has an external pull down which is an + // invalid configuration. + id0 = "pd"; + } else { + // ID0 could be externally pulled up or it could be + // floating. Change the polarity of the internal pull. + gpio_configure_pupdn(DISPLAY_TO_AP_ID0, GPIO_PDN); + spin(100); // Wait 100us + + if (gpio_read(DISPLAY_TO_AP_ID0)) { + // ID0 has an external pull up which is an + // invalid configuration. + id0 = "pu"; + } else { + // ID0 is open. + id0 = "open"; + display_panel = DISPLAY_PANEL_TYPE_D600; + } + } + } else { + // ID1 could be externally pulled high or it could be + // floating. Change the polarity of the internal pull. + gpio_configure_pupdn(DISPLAY_TO_AP_ID1, GPIO_PDN); + spin(100); // Wait 100us + + if (gpio_read(DISPLAY_TO_AP_ID1)) { + // ID1 has an external pull up which is an + // an invalid configuration. + id1 = "pu"; + id0 = "any"; + } else { + // ID1 is open. + id1 = "open"; + + if (!gpio_read(DISPLAY_TO_AP_ID0)) { + // ID0 has an external pull down. + id0 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_D500; + } else { + // ID0 could be externally pulled up or it could be + // floating. Change the polarity of the internal pull. + gpio_configure_pupdn(DISPLAY_TO_AP_ID0, GPIO_PDN); + spin(100); // Wait 100us + + if (gpio_read(DISPLAY_TO_AP_ID0)) { + // ID0 has an external pull up which is an + // invalid configuration. + id0 = "pu"; + } else { + // ID0 is open. + id0 = "open"; + + // Both ID1 and ID0 are open. That means + // no panel is installed or an unsupported + // panel that doesn't have id sense pins + // is installed. We can't tell which at + // this point. + display_panel_missing = true; + } + } + } + } + + dprintf(DEBUG_INFO, "%spanel id pin state: id1=%s, id0=%s\n", + (display_panel !=DISPLAY_PANEL_TYPE_UNKNOWN) ? "" : "Unknown", id1, id0); + + ASSERT(display_panel < DISPLAY_PANEL_TYPE_COUNT); + + dprintf(DEBUG_INFO, "Display panel = %s\n", display_panel_types[display_panel]); + +#if SUB_TARGET_N56 + ASSERT(display_panel_missing || (display_panel == DISPLAY_PANEL_TYPE_D600)); +#endif +#if SUB_TARGET_N61 + ASSERT(display_panel_missing || (display_panel == DISPLAY_PANEL_TYPE_D500)); +#endif + + // If no panel was found, assume the default panel for now. + // If any panel id is actually read from the display, we'll panic + // when updating the device tree. + if (display_panel_missing) { + display_panel = DEFAULT_DISPLAY_PANEL; + } + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_DFLT); + gpio_configure(DISPLAY_TO_AP_ID1, GPIO_CFG_DFLT); +} + +int target_get_boot_battery_capacity(void) { + + if ( iphone7_get_board_rev() <= N56_EVT1_CARRIER_BOARD_REV ) { // XXX: also N56 carrier, etc. + int temp=0; +#if WITH_HW_GASGAUGE + if ( gasgauge_read_temperature(&temp) != 0 ) temp=0; // defensive +#endif + + const uint32_t charge_current=power_get_available_charge_current(); + if ( temp>500 && charge_current>500 ) return 0; // rely on SOC1 clear only + + return 50; // @see rdar://16587240, rdar://18649980 + } + + return 50; // old limit +} + +uint32_t target_get_display_panel_type(void) +{ + if (display_panel == DISPLAY_PANEL_TYPE_UNKNOWN) { + iphone7_get_display_info(); + } + return display_panel; +} + +static void target_fixup_power(void) +{ +#if WITH_HW_POWER +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); +int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); + + int rc; + uint8_t val; + + bool fix_ana_trim=false; + rc = pmu_get_data(0, 0x1, &val); // read PMU.OTP version + if ( rc < 0 ) { + dprintf(DEBUG_INFO, "PMU: cannot read OTP Version (%d)\n", rc); + } else if ( val < 0x0d ) { + rc = pmu_get_data(0, 0x01d7, &val); // read kD2186_BUCK6_ANA_TRIM4 + if ( rc<0 ) { + dprintf(DEBUG_INFO, "PMU: cannot read kD2186_BUCK6_ANA_TRIM4 (%d)\n", rc); + } else { + fix_ana_trim=true; + } + } + + rc=pmu_set_data(0, 0x7000, 0x1d, 0); // test mode + if ( rc<0 ) { + dprintf(DEBUG_INFO, "PMU: cannot enter test mode (%d)\n", rc); + } else { + + // for N61 EVT, N56 Proto 2 and earlier + if ( iphone7_get_board_type() <= BOARD_TYPE_N61_EVT1 ) { + rc=pmu_set_data(0, 0x0028, 0x23, 1); + if ( rc<0 ) dprintf(DEBUG_INFO, "cannot change VDD_FAULT (%d)\n", rc); + } + + // Remove N56 EVT iBoot Overwrites for PMU + // to set high gain mode for kD2186_BUCK6_ANA_TRIM4 0x02 has to be OR'd in to preserve exiting bits + if ( fix_ana_trim ) { + rc=pmu_set_data(0, 0x01d7, ( val | 0x02 ), 1); // merge in high gain mode + if ( rc<0 ) dprintf(DEBUG_INFO, "cannot change kD2186_BUCK6_ANA_TRIM4 (%d)\n", rc); + } + + rc=pmu_set_data(0, 0x7000, 0x00, 0); + if ( rc<0 ) panic("PMU: cannot exit test mode (%d)", rc); + } + + + uint8_t data[2] = { 0xa, 0 }; + rc=iic_read(1, 0xea, data, 1, &data[1], 1, IIC_NORMAL); + if ( rc<0 ) { + dprintf(DEBUG_INFO, "tigris: cannot read VBUS_ILIM (%d)\n", rc); + } else if ( data[1]!=0x23 ) { + data[1]=0x23; + + rc=iic_write(1, 0xea, data, sizeof(data)); + if ( rc<0 ) dprintf(DEBUG_INFO, "tigris: cannot set VBUS_ILIM (%d)\n", rc); + } +#endif +} + +void target_early_init(void) +{ + // Get the display panel type. + iphone7_get_display_info(); + + uint32_t panel_type_index; + uint32_t target_mipi_p, target_mipi_m, target_mipi_s; + //Horrible hack to support suspend to ram. Should remove when supporting only one display per target + uint32_t pixel_clock = 0; + + panel_type_index = target_get_display_panel_type(); + + if (panel_type_index == DISPLAY_PANEL_TYPE_D500) { + // D500 @ 843 Mhz + target_mipi_p = 4; + target_mipi_m = 281; + target_mipi_s = 1; + pixel_clock = 88890000; + } else { + // D600 @ 1200 MHz + target_mipi_p = 2; + target_mipi_m = 100; + target_mipi_s = 0; + pixel_clock = 200000000; + } + +#if PRODUCT_LLB || PRODUCT_IBSS + clock_set_frequency(CLK_MIPI, 0, target_mipi_p, target_mipi_m, target_mipi_s, 0); +#endif + //Remove when only 1 display panel is supported + clock_set_frequency(CLK_VCLK0, 0, 0, 0, 0, pixel_clock); + +// Fuse Rev { 0x4 or 0x5} then USB Operating condition 3.0V +// Fuse Rev is NOT {0x4} or NOT { 0x5} and CFG Bit 492=0 then USB Operating condition is 3.3V +// Fuse Rev is NOT {0x4} or NOT {0x5} and CFG Bit 492=1 then USB Operating condition is 3.0V +#if PRODUCT_LLB || PRODUCT_IBSS + if ( chipid_get_chip_revision() == CHIP_REVISION_B0 ) { + const uint32_t fuse=chipid_get_fuse_revision(); + + // LDO1, kD2186_LDO1_VSEL=0x0308 + if ( fuse==0x4 || fuse==0x5 || (rCFG_FUSE15&(1<<12))!=0 ) { + printf("*** setting PP33_USB t0 3.0V ***\n"); + power_set_ldo(1, 3000); // USB 3.0V, + } else { + // has set LDO1 to 3.225 i pmu_ldo_cold_setup + printf("*** setting PP33_USB t0 3.225V ***\n"); + } + } + + target_fixup_power(); + +#endif +#if APPLICATION_IBOOT + // revs of N61/N56 boards before EVT builds (ie. < BOARD_TYPE_N61_EVT) + // turn on LDO9 for rear and front camera + if (iphone7_get_board_type() < BOARD_TYPE_N61_EVT1) + power_enable_ldo(9, true); // LDO9, kD2186_ACTIVE4:(1<<1) +#endif + +} + +void target_late_init(void) +{ + clock_gate(CLK_UART7, 0); +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +#if PRODUCT_IBSS || PRODUCT_LLB + if (iphone7_get_board_type() < BOARD_TYPE_N61_EVT1) { + static const uint32_t fixup_list[] = { + GPIO_ID(51), CFG_IN | SLOW_SLEW, // 51 : GPIO[14] -> BB_TO_AP_GPS_SYNC + GPIO_ID(66), CFG_DISABLED | SLOW_SLEW, // 66 : GPIO[22] -> BB_TO_AP_HSIC1_WAKE + UINT32_MAX, UINT32_MAX + }; + + dprintf(DEBUG_INFO, "Fixing up GPIOs for pre-EVT devices\n"); + + gpio_fixup_pinconfig(fixup_list); + } +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + + return ((void *)(&(display_panel_configurations[target_get_display_panel_type()]))); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + uint32_t panel_type_index; + + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + panel_type_index = target_get_display_panel_type(); + env_set("display-timing", display_panel_types[panel_type_index], 0); + env_set("adbe-tunables", display_panel_types[panel_type_index], 0); + env_set("adfe-tunables", display_panel_types[panel_type_index], 0); +} + +#endif + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); +} +#endif + +#if WITH_HW_LM3534 +uint8_t target_lm3534_gpr(uint32_t ctlr) +{ + uint8_t gpr = (1 << 1) | (1 << 0); // (ramp disable) | (chip enable) + + switch (target_get_display_panel_type()) { + case DISPLAY_PANEL_TYPE_D500: + gpr |= (1 << 4); // (ovp_select_21v) + break; + + case DISPLAY_PANEL_TYPE_D600: + if (ctlr == 1) + gpr |= (1 << 4); // (ovp_select_21v) + break; + + case DISPLAY_PANEL_TYPE_D500_2LANE: + gpr |= (1 << 4); // (ovp_select_21v) + break; + + default: + break; + } + + return gpr; +} +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *disp0_node, *backlight_node; +#endif + board_type board = iphone7_get_board_type(); + DTNode *node; + uint32_t propSize; + char *propName; + char *propStr; + void *propData; + const char *nodeName; + +#if WITH_HW_DISPLAY_PINOT + // Find the DISP0 (display-subsystem 0) node + FindNode(0, "arm-io/disp0", &disp0_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, disp0_node, backlight_node); + + if (target_config_dev() && display_panel_missing) { + // Get the panel id that was actually read (if any). + propName = "lcd-panel-id"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // If we really read a panel id then an + // unsupported panel is plugged into the board. + if (((u_int32_t *)propData)[0] != 0) { + panic("Unsupported lcd-panel-id: 0x%08x", + ((u_int32_t *)propData)[0]); + } + } + } + } +#endif + +#if WITH_HW_MIPI_DSIM + // Find the mipi node + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + extern int mipi_update_device_tree(DTNode *mipi_node); + mipi_update_device_tree(node); + } +#endif + + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propStr = NULL; + if (target_config_ap()) { + // AP Boards are assigned a display + switch (board) { + case BOARD_TYPE_N61_PROTO2: + case BOARD_TYPE_N61_EVT1: + propStr = "multi-touch,n61"; + break; + case BOARD_TYPE_N56_PROTO2: + case BOARD_TYPE_N56_EVT1: + propStr = "multi-touch,n56"; + break; + default: + panic("Unknown display for board type: %d", board); + break; + } + } else { + // Dev boards have to figure out the display type + if (target_get_display_panel_type() == DISPLAY_PANEL_TYPE_D500) { + // D500: N61 + propStr = "multi-touch,n61"; + } else { + // D600: N56 + propStr = "multi-touch,n56"; + } + } + if (propStr != NULL) { + memset(propData, 0, propSize); + strlcpy(propData, propStr, propSize); + } + } + } + + // Move mesa I2C to 12C1 + // N61/N56 Mesa EEPROM moved from i2c2 to i2c1 + if (board < BOARD_TYPE_N56_PROTO2) { + // Mesa EEPROM is on I2C2 so delete arm-io/i2c1/mesa-eeprom. + nodeName = "arm-io/i2c1/mesa-eeprom"; + if (FindNode(0, nodeName, &node)) { + propName = "name"; + if (FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_INFO,"Mesa EEPROM on I2C2 - deleting DT node %s\n", + nodeName); + propName[0] = '~'; + } else { + panic("%s has no 'name' property", nodeName); + } + } else { + panic("Unable to find device tree node %s", nodeName); + } + } else { + // Mesa EEPROM is on I2C1 so delete arm-io/i2c2/mesa-eeprom. + nodeName = "arm-io/i2c2/mesa-eeprom"; + if (FindNode(0, nodeName, &node)) { + propName = "name"; + if (FindProperty(node, &propName, &propData, &propSize)) { + dprintf(DEBUG_INFO,"Mesa EEPROM on I2C1 - deleting DT node %s\n", + nodeName); + propName[0] = '~'; + } else { + panic("%s has no 'name' property", nodeName); + } + } else { + panic("Unable to find device tree node %s", nodeName); + } + } + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + // Update the codec and speaker nodes with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + propName = "at-scale-fmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[8], sizeof(uint32_t)); + } + propName = "at-scale-rcvr"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[12], sizeof(uint32_t)); + } + } + // Update speaker + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[16], sizeof(uint32_t)); + } + } + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + + // Remove the properties for the second backlight controller + // if we have anything other than a D600 display panel. + if (target_get_display_panel_type() != DISPLAY_PANEL_TYPE_D600) { + propName = "dual-backlight-controllers"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-backlight_enable1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-backlight_enable1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart8/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + propName = "compass-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CRot', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart8/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart8/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (FindNode(0, "arm-io/uart8/oscar/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('PxCl', propData, propSize); + } + + // Stockholm calibration + if (FindNode(0, "arm-io/uart3/stockholm", &node)) { + propName = "calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('NFCl', propData, propSize); + } + + // Update the X162 calibration data + if (FindNode(0, "arm-io/spi3/mesa", &node)) { + propName = "calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FSCl', propData, propSize); + } + propName = "modulation-ratio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('NvMR', propData, propSize); + } + } + +#if SUB_TARGET_N56 + // Update rear camera tilt and rotation data + if (FindNode(0, "arm-io/isp", &node)) { + propName = "back-camera-tilt-and-rotation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BCTR', propData, propSize); + } + } +#endif + + // Update cover glass type + if (FindNode(0, "product", &node)) { + propName = "cover-glass"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CGSp', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('CBAT', propData, propSize); + } + + // Update Vibe calibration data + if (FindNode(0, "arm-io/i2c1/vib-pwm", &node)) { + propName = "calibration-data"; + if (FindProperty(node, &propName, &propData, &propSize)) { + const uint32_t count=syscfgCopyDataForTag('VbCl', propData, propSize); + if ( count!=propSize ) *((uint32_t*)propData)=0x00a46d0d; + } + } + + // Update the baseband time sync GPIO. + // This signal is on GPIO14 (pin 51) for pre-EVT devices. + if (board < BOARD_TYPE_N61_EVT1) { + if (FindNode(0, "baseband", &node)) { + propName = "function-bb_ap_time_sync"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize == (4 * sizeof(uint32_t))) { + ((uint32_t*)propData)[2] = 51; + } + } + } + } + + // WLAN Fiji B0 workarounds -- !!!FIXME!!! Remove this when Fiji B0 is deprecated + // Remove Fiji B0 PCIe hacks + if (FindNode(0, "arm-io/apcie/pci-bridge1/wlan", &node)) { + if (chipid_get_chip_revision() > CHIP_REVISION_B0) { + // Disable workarounds for Fiji B1 and later. + propName = "acpie-l1ss-workaround"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "pci-wake-l1pm-disable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } else { + // Fix up the hacks for Fiji B0 and earlier + propName = "pci-l1pm-control"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "pci-l1pm-control-b0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[16] = '\0'; + } + } + } + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 00020000B9B5B4003C3B3B0000000000 +// gold/white: setenv DClr_override 00020000B5CCE100E3E4E10000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT diff --git a/target/iphone7/pinconfig.c b/target/iphone7/pinconfig.c new file mode 100644 index 0000000..d6886ed --- /dev/null +++ b/target/iphone7/pinconfig.c @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v17 + I/O Spreadsheet tracker: N56 | IOSpreadsheet + Conversion command: csvtopinconfig.py --soc fiji --copyright 2013-2014 --radar ' N56 | IOSpreadsheet' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 0 : ULPI_DIR -> LCM_TO_AP_HIFA_BSYNC + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 1 : ULPI_STP -> AP_TO_LCM_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 2 : ULPI_NXT -> AP_TO_TOUCH_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 3 : ULPI_DATA[7] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + CFG_IN | PULL_DOWN | SLOW_SLEW, // 7 : ULPI_CLK -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 1 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 8 : ULPI_DATA[3] -> AP_TO_LEDDRV_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 10 : ULPI_DATA[1] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 11 : ULPI_DATA[0] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 12 : SPI1_SCLK -> AP_TO_CODEC_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_MOSI -> AP_TO_CODEC_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 14 : SPI1_MISO -> CODEC_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 15 : SPI1_SSIN -> AP_TO_CODEC_SPI_CS_L + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> BUTTON_TO_AP_MENU_KEY_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> BUTTON_TO_AP_HOLD_KEY_L + CFG_IN | PULL_UP | SLOW_SLEW, // 34 : I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> AP_TO_BB_I2S3_LRCLK + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> 45_AP_TO_BB_I2S3_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 37 : I2S3_DOUT -> AP_TO_BB_I2S3_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> BB_TO_AP_I2S3_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 39 : CLK32K_OUT -> 45_AP_TO_TOUCH_CLK32K_RESET_L + +/* Port 5 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> WLAN_TO_AP_PCIE1_CLKREQ_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 43 : GPIO[0] -> AP_TO_HEADSET_HS3_CTRL + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 44 : GPIO[1] -> AP_TO_HEADSET_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW, // 45 : GPIO[2] -> BUTTON_TO_AP_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 46 : GPIO[3] -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 47 : GPIO[4] -> SPKAMP_TO_AP_INT_L + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 48 : GPIO[5] -> AP_TO_SPKAMP_BEE_GEES + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 49 : GPIO[6] -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_BT_WAKE + CFG_DISABLED | SLOW_SLEW, // 51 : GPIO[14] -> BB_TO_AP_IPC_GPIO1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 52 : GPIO[16] -> BOARD_ID3 + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 53 : GPIO[17] -> AP_TO_STOCKHOLM_SIM_SEL + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 54 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : GPIO[20] -> NC + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 56 : GPIO[21] -> BB_TO_AP_DEVICE_RDY + CFG_FUNC0 | SLOW_SLEW, // 57 : UART5_RTXD -> AP_TO_TIGRIS_SWI + CFG_IN | PULL_UP | SLOW_SLEW, // 58 : UART8_TXD -> AP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> OSCAR_TO_AP_UART_RXD + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 60 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 61 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 62 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 63 : SPI0_SSIN -> NC + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> AP_TO_I2C2_SCL + CFG_IN | SLOW_SLEW, // 66 : GPIO[22] -> BB_TO_AP_GPS_SYNC + CFG_OUT_0 | SLOW_SLEW, // 67 : GPIO[23] -> AP_TO_BB_HOST_RDY + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39] -> NC + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 76 : GPIO[42] -> AP_TO_VIBE_EN + CFG_IN | SLOW_SLEW, // 77 : GPIO[43] -> AP_TO_WLAN_PCIE1_RST_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 78 : DISP_VSYNC -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 79 : UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 81 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_IN | PULL_DOWN | SLOW_SLEW, // 82 : TMR32_PWM1 -> AP_TO_VIBE_TRIG + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 84 : UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 85 : UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 86 : I2C3_SDA -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2C3_SCL -> NC + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> AP_TO_I2C0_SCL + CFG_OUT_0 | SLOW_SLEW, // 98 : GPIO[38] -> AP_TO_BB_COREDUMP + CFG_OUT_0 | SLOW_SLEW, // 99 : UART2_TXD -> AP_TO_BB_UART2_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 100 : UART2_RXD -> BB_TO_AP_UART2_RXD + CFG_OUT_0 | SLOW_SLEW, // 101 : UART2_RTSN -> AP_TO_BB_UART2_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 102 : UART2_CTSN -> BB_TO_AP_UART2_CTS_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 103 : DWI_DO -> 45_AP_TO_PMU_AND_BL_DWI_DO + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 104 : DWI_CLK -> 45_AP_TO_PMU_AND_BL_DWI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 105 : WDOG -> AP_TO_PMU_RESET_IN + CFG_IN | PULL_UP | SLOW_SLEW, // 106 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 108 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 109 : GPIO[27] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_TO_AP_PRE_UVLO_L_R + CFG_FUNC0 | SLOW_SLEW, // 111 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L_R + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_IN | SLOW_SLEW, // 114 : GPIO[8] -> AP_TO_BB_RST_L + CFG_DISABLED | SLOW_SLEW, // 115 : GPIO[9] -> AP_TO_WLAN_JTAG_SWCLK + CFG_DISABLED | SLOW_SLEW, // 116 : GPIO[10] -> AP_TO_WLAN_JTAG_SWDIO + CFG_OUT_0 | SLOW_SLEW, // 117 : GPIO[15] -> AP_TO_BB_WAKE_MODEM + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 118 : UART4_TXD -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> WLAN_TO_AP_UART4_RXD + +/* Port 15 */ + CFG_OUT_1 | PULL_DOWN | SLOW_SLEW, // 120 : UART4_RTSN -> AP_TO_WLAN_UART4_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> WLAN_TO_AP_UART4_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 122 : SPI3_MOSI -> AP_TO_MESA_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 123 : SPI3_MISO -> MESA_TO_AP_SPI_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> AP_TO_MESA_SPI_CLK_R + CFG_IN | SLOW_SLEW, // 125 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 126 : GPIO[24] -> BB_TO_AP_RESET_DET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 127 : GPIO[30] -> CODEC_TO_AP_INT_L + +/* Port 16 */ + CFG_IN | SLOW_SLEW, // 128 : GPIO[31] -> AP_TO_RADIO_ON_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 129 : GPIO[32] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 130 : GPIO[33] -> NC + CFG_IN | SLOW_SLEW, // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + CFG_DISABLED | SLOW_SLEW, // 132 : GPIO[41] -> BB_TO_AP_IPC_GPIO + CFG_IN | SLOW_SLEW, // 133 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2S4_LRCK -> AP_TO_CODEC_VSP_I2S4_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_TO_CODEC_VSP_I2S4_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 137 : I2S4_DIN -> CODEC_TO_AP_VSP_I2S4_DIN + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 138 : I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 139 : I2C1_SCL -> AP_TO_I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 160 : I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 161 : I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 163 : I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2S1_LRCK -> AP_TO_BT_I2S1_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 166 : I2S1_BCLK -> 45_AP_TO_BT_I2S1_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TO_BT_I2S1_DOUT + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 168 : I2S1_DIN -> BT_TO_AP_I2S1_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 169 : I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 170 : I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 172 : I2S2_DIN -> CODEC_TO_AP_XSP_I2S2_DIN + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 173 : UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1 | PULL_DOWN | SLOW_SLEW, // 175 : UART1_RTSN -> AP_TO_BT_UART1_RTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 176 : UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 177 : EDP_HPD -> AP_TO_STOCKHOLM_EN + CFG_IN | PULL_UP | SLOW_SLEW, // 178 : UART3_TXD -> AP_TO_STOCKHOLM_UART3_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 179 : UART3_RXD -> STOCKHOLM_TO_AP_UART3_RXD + CFG_IN | PULL_UP | SLOW_SLEW, // 180 : UART3_RTSN -> AP_TO_STOCKHOLM_UART3_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 181 : UART3_CTSN -> STOCKHOLM_TO_AP_UART3_CTS_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 182 : SPI2_SCLK -> AP_TO_TOUCH_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 183 : SPI2_MOSI -> AP_TO_TOUCH_SPI_MOSI + +/* Port 23 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 184 : SPI2_MISO -> TOUCH_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 185 : SPI2_SSIN -> AP_TO_TOUCH_SPI_CS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 186 : ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 187 : ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 188 : ISP1_SDA -> AP_BI_FCAM_I2C_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 189 : ISP1_SCL -> AP_TO_FCAM_I2C_SCL + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 190 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 191 : SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + +/* Port 24 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 194 : ISP_UART0_TXD -> AP_ISP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 195 : ISP_UART0_RXD -> OSCAR_TO_AP_ISP_UART_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 196 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 197 : SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 200 : UART7_TXD -> AP_TO_WLAN_DEVICE_WAKE + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 201 : UART7_RXD -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 202 : I2S0_MCK -> 45_AP_TO_CODEC_I2S0_MCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 203 : I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 0 : ULPI_DIR -> LCM_TO_AP_HIFA_BSYNC + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 1 : ULPI_STP -> AP_TO_LCM_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 2 : ULPI_NXT -> AP_TO_TOUCH_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 3 : ULPI_DATA[7] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + CFG_IN | PULL_DOWN | SLOW_SLEW, // 7 : ULPI_CLK -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 1 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 8 : ULPI_DATA[3] -> AP_TO_LEDDRV_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 10 : ULPI_DATA[1] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 11 : ULPI_DATA[0] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 12 : SPI1_SCLK -> AP_TO_CODEC_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_MOSI -> AP_TO_CODEC_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 14 : SPI1_MISO -> CODEC_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 15 : SPI1_SSIN -> AP_TO_CODEC_SPI_CS_L + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> BUTTON_TO_AP_MENU_KEY_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> BUTTON_TO_AP_HOLD_KEY_L + CFG_IN | PULL_UP | SLOW_SLEW, // 34 : I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> AP_TO_BB_I2S3_LRCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> 45_AP_TO_BB_I2S3_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 37 : I2S3_DOUT -> AP_TO_BB_I2S3_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> BB_TO_AP_I2S3_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 39 : CLK32K_OUT -> 45_AP_TO_TOUCH_CLK32K_RESET_L + +/* Port 5 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> WLAN_TO_AP_PCIE1_CLKREQ_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 43 : GPIO[0] -> AP_TO_HEADSET_HS3_CTRL + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 44 : GPIO[1] -> AP_TO_HEADSET_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW, // 45 : GPIO[2] -> BUTTON_TO_AP_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 46 : GPIO[3] -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 47 : GPIO[4] -> SPKAMP_TO_AP_INT_L + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 48 : GPIO[5] -> AP_TO_SPKAMP_BEE_GEES + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 49 : GPIO[6] -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_BT_WAKE + CFG_DISABLED | SLOW_SLEW, // 51 : GPIO[14] -> BB_TO_AP_IPC_GPIO1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 52 : GPIO[16] -> BOARD_ID3 + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 53 : GPIO[17] -> AP_TO_STOCKHOLM_SIM_SEL + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 54 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : GPIO[20] -> NC + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 56 : GPIO[21] -> BB_TO_AP_DEVICE_RDY + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 57 : UART5_RTXD -> AP_TO_TIGRIS_SWI + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 58 : UART8_TXD -> AP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> OSCAR_TO_AP_UART_RXD + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 60 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 61 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 62 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 63 : SPI0_SSIN -> NC + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> AP_TO_I2C2_SCL + CFG_IN | SLOW_SLEW, // 66 : GPIO[22] -> BB_TO_AP_GPS_SYNC + CFG_OUT_0 | SLOW_SLEW, // 67 : GPIO[23] -> AP_TO_BB_HOST_RDY + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39] -> NC + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 76 : GPIO[42] -> AP_TO_VIBE_EN + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 77 : GPIO[43] -> AP_TO_WLAN_PCIE1_RST_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 78 : DISP_VSYNC -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 79 : UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 81 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 82 : TMR32_PWM1 -> AP_TO_VIBE_TRIG + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 84 : UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 85 : UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 86 : I2C3_SDA -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2C3_SCL -> NC + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> AP_TO_I2C0_SCL + CFG_OUT_0 | SLOW_SLEW, // 98 : GPIO[38] -> AP_TO_BB_COREDUMP + CFG_OUT_0 | SLOW_SLEW, // 99 : UART2_TXD -> AP_TO_BB_UART2_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 100 : UART2_RXD -> BB_TO_AP_UART2_RXD + CFG_OUT_0 | SLOW_SLEW, // 101 : UART2_RTSN -> AP_TO_BB_UART2_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 102 : UART2_CTSN -> BB_TO_AP_UART2_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 103 : DWI_DO -> 45_AP_TO_PMU_AND_BL_DWI_DO + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 104 : DWI_CLK -> 45_AP_TO_PMU_AND_BL_DWI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 105 : WDOG -> AP_TO_PMU_RESET_IN + CFG_IN | PULL_UP | SLOW_SLEW, // 106 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 108 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 109 : GPIO[27] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_TO_AP_PRE_UVLO_L_R + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 111 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L_R + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_IN | SLOW_SLEW, // 114 : GPIO[8] -> AP_TO_BB_RST_L + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 115 : GPIO[9] -> AP_TO_WLAN_JTAG_SWCLK + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 116 : GPIO[10] -> AP_TO_WLAN_JTAG_SWDIO + CFG_OUT_0 | SLOW_SLEW, // 117 : GPIO[15] -> AP_TO_BB_WAKE_MODEM + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 118 : UART4_TXD -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> WLAN_TO_AP_UART4_RXD + +/* Port 15 */ + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 120 : UART4_RTSN -> AP_TO_WLAN_UART4_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> WLAN_TO_AP_UART4_CTS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 122 : SPI3_MOSI -> AP_TO_MESA_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 123 : SPI3_MISO -> MESA_TO_AP_SPI_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> AP_TO_MESA_SPI_CLK_R + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 125 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 126 : GPIO[24] -> BB_TO_AP_RESET_DET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 127 : GPIO[30] -> CODEC_TO_AP_INT_L + +/* Port 16 */ + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 128 : GPIO[31] -> AP_TO_RADIO_ON_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 129 : GPIO[32] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 130 : GPIO[33] -> NC + CFG_IN | SLOW_SLEW, // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + CFG_DISABLED | SLOW_SLEW, // 132 : GPIO[41] -> BB_TO_AP_IPC_GPIO + CFG_IN | SLOW_SLEW, // 133 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2S4_LRCK -> AP_TO_CODEC_VSP_I2S4_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_TO_CODEC_VSP_I2S4_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 137 : I2S4_DIN -> CODEC_TO_AP_VSP_I2S4_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 138 : I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 139 : I2C1_SCL -> AP_TO_I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 160 : I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 161 : I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 163 : I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2S1_LRCK -> AP_TO_BT_I2S1_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 166 : I2S1_BCLK -> 45_AP_TO_BT_I2S1_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TO_BT_I2S1_DOUT + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 168 : I2S1_DIN -> BT_TO_AP_I2S1_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 169 : I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 170 : I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 172 : I2S2_DIN -> CODEC_TO_AP_XSP_I2S2_DIN + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 173 : UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 175 : UART1_RTSN -> AP_TO_BT_UART1_RTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 176 : UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 177 : EDP_HPD -> AP_TO_STOCKHOLM_EN + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 178 : UART3_TXD -> AP_TO_STOCKHOLM_UART3_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 179 : UART3_RXD -> STOCKHOLM_TO_AP_UART3_RXD + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 180 : UART3_RTSN -> AP_TO_STOCKHOLM_UART3_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 181 : UART3_CTSN -> STOCKHOLM_TO_AP_UART3_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 182 : SPI2_SCLK -> AP_TO_TOUCH_SPI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 183 : SPI2_MOSI -> AP_TO_TOUCH_SPI_MOSI + +/* Port 23 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 184 : SPI2_MISO -> TOUCH_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 185 : SPI2_SSIN -> AP_TO_TOUCH_SPI_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 186 : ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 187 : ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 188 : ISP1_SDA -> AP_BI_FCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 189 : ISP1_SCL -> AP_TO_FCAM_I2C_SCL + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 190 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + +/* Port 24 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 194 : ISP_UART0_TXD -> AP_ISP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 195 : ISP_UART0_RXD -> OSCAR_TO_AP_ISP_UART_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 196 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 200 : UART7_TXD -> AP_TO_WLAN_DEVICE_WAKE + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 201 : UART7_RXD -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 202 : I2S0_MCK -> 45_AP_TO_CODEC_I2S0_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 203 : I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0 } }, + { 1, 1, { pinconfig_dev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/iphone7/rules.mk b/target/iphone7/rules.mk new file mode 100644 index 0000000..055966f --- /dev/null +++ b/target/iphone7/rules.mk @@ -0,0 +1,57 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2186=1 \ + TARGET_CHESTNUT_USE_LOW_RIPPLE_MODE=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_IPHONE_TUNABLES=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi2/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart4/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" + +ifeq ($(SUB_TARGET),n56) +OPTIONS += \ + WITH_HW_MIPI=1 \ + WITH_HW_AGC_MIPI=1 \ + TARGET_HS_2_LP_DATA_TIME=41 \ + TARGET_LP_2_HS_DATA_TIME=125 \ + TARGET_HS_2_LP_CLOCK_TIME=57 \ + TARGET_LP_2_HS_CLOCK_TIME=153 +else ifeq ($(SUB_TARGET),n61) +OPTIONS += \ + WITH_HW_MIPI=1 \ + WITH_HW_AGC_MIPI=1 \ + TARGET_HS_2_LP_DATA_TIME=31 \ + TARGET_LP_2_HS_DATA_TIME=93 \ + TARGET_HS_2_LP_CLOCK_TIME=44 \ + TARGET_LP_2_HS_CLOCK_TIME=113 +else +$(error Unsupported subtarget: $(SUB_TARGET)) +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o + +ALL_OBJS += $(LOCAL_DIR)/pinconfig.o diff --git a/target/iphone8/include/target/adbe_settings.h b/target/iphone8/include/target/adbe_settings.h new file mode 100644 index 0000000..bbfec24 --- /dev/null +++ b/target/iphone8/include/target/adbe_settings.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = +{ + { + .name = "D620", + .adbe0_vblank_pos_vbi_pulse = 0x30b, + .adbe0_vblank_clk_gate_wakeup = 0x0007, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(9) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, + + { + .name = "D520", + .adbe0_vblank_pos_vbi_pulse = 0x218, + .adbe0_vblank_clk_gate_wakeup = 0x0007, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(9) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/iphone8/include/target/aspnandconfig.h b/target/iphone8/include/target/aspnandconfig.h new file mode 100644 index 0000000..2b5ca83 --- /dev/null +++ b/target/iphone8/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/iphone8/include/target/gpiodef.h b/target/iphone8/include/target/gpiodef.h new file mode 100644 index 0000000..4a5fc87 --- /dev/null +++ b/target/iphone8/include/target/gpiodef.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iphone8,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO_ID(146) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO_ID(145) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO_ID(144) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO_ID(143) // 71 : GPIO[37] + +/* Miscellaneous Pins */ +#define GPIO_DISPLAY_ID1 GPIO( 4, 0) // 32 : UART7_TXD -> DISPLAY_TO_AP_ID0 (DEV BOARD only) +#define GPIO_DISPLAY_ID0 GPIO( 4, 1) // 33 : UART7_RXD -> DISPLAY_TO_AP_ID1 (DEV BOARD only) +#define GPIO_PROX_SELECT GPIO( 4, 1) // 32 : UART7_RXD -> PROX_SELECT (AP BOARD only) + +/* Display reset */ +#define GPIO_LCD_RST GPIO( 9, 4) // GPIO[12] -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + +/* Ringer Switch */ +#define GPIO_RINGER_AB GPIO(16, 3) // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + +#define GPIO_S3E_BOOT_FROM_HOST GPIO_ID(141) // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (1) + +#define DISPLAY_PMU_IIC_BUS (0) + +#define GPIO_PMU_NAND_LOW_POWER_MODE (5) // PMU_TO_NAND_LOW_BATT_BOOT + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/iphone8/include/target/powerconfig.h b/target/iphone8/include/target/powerconfig.h new file mode 100644 index 0000000..78cac39 --- /dev/null +++ b/target/iphone8/include/target/powerconfig.h @@ -0,0 +1,142 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 1 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2255_EN_CMD0, (1<<7)|(1<<2)|(1<<1)|(1<<0) }, + { PMU_IIC_BUS, kD2255_EN_CMD1, (1<<0) }, // buck8 + { PMU_IIC_BUS, kD2255_SPI_CTRL, 1 }, // enable SPI access + + { PMU_IIC_BUS, kD2255_LDO9_VSEL, 0x5A}, // iBoot, N71 Proto 2: PMU_VLDO9 = 2.85V, not 2.95V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// IO_CONFIG[7:6] 0=I 1=O_OD 2=O_PP 3=SS +// IO_TYPE[5:3] O 0=L 1=32K 2=nR 3=TI 4=L +// PUPD[2:1] O 0=NP 1=PU 2=NP 3=<0> +// WAKE_LVL[0] O 0=low 1=high +// IO_TYPE[5:3] I 0=L_AH 1=L_AL 2=RE 3=FE 4=AE +// PUPD[2:1] I 0=NP 1=PU 2=PD_GND 3=<0> +// WAKE_LVL[0] I 0=NW 1=W +// +// N71/N66 IO Spreadsheet v25 (PMU) +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2255_GPIO1_CONF1, (0<<6)|(1<<3)|(0<<1)|(1<<0) }, // I.AL.NP.WS TIGRIS_TO_PMU_INT_L + { PMU_IIC_BUS, kD2255_GPIO1_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO2_CONF1, (0<<6)|(1<<3)|(2<<1)|(0<<0) }, // I.AL.PD.NW, BB_TO_PMU_PCIE_HOST_WAKE_L + { PMU_IIC_BUS, kD2255_GPIO2_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO3_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_BB_PMIC_RESET_R_L + { PMU_IIC_BUS, kD2255_GPIO3_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO4_CONF1, (0<<6)|(0<<3)|(2<<1)|(1<<0) }, // I.AH.PD.WS TRISTAR_TO_AP_INT + { PMU_IIC_BUS, kD2255_GPIO4_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO5_CONF1, (0<<6)|(0<<3)|(2<<1)|(1<<0) }, // I.AH.PD.WS STOCKHOLM_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2255_GPIO5_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO6_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_NAND_LOW_BATT_BOOT_L + { PMU_IIC_BUS, kD2255_GPIO6_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO7_CONF1, (0<<6)|(0<<3)|(2<<1)|(1<<0) }, // I.AH.PD.WS WLAN_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2255_GPIO7_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO8_CONF1, (0<<6)|(4<<3)|(1<<1)|(1<<0) }, // I.AE.PU.WS CODEC_TO_PMU_MIKEY_INT_L + { PMU_IIC_BUS, kD2255_GPIO8_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO9_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_BT_REG_ON + { PMU_IIC_BUS, kD2255_GPIO9_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO10_CONF1, (0<<6)|(2<<3)|(0<<1)|(1<<0) }, // I.RE.NP.WS BT_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2255_GPIO10_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO11_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_WLAN_REG_ON + { PMU_IIC_BUS, kD2255_GPIO11_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO12_CONF1, (1<<6)|(2<<3)|(0<<1)|(0<<0) }, // NC - O_OD.n.NP.0 + { PMU_IIC_BUS, kD2255_GPIO12_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO13_CONF1, (1<<6)|(0<<3)|(1<<1)|(0<<0) }, // O_OD.L.PU.0 PMU_TO_CODEC_DIGLDO_PULLDN + { PMU_IIC_BUS, kD2255_GPIO13_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO14_CONF1, (0<<6)|(3<<3)|(1<<1)|(0<<0) }, // I.FE.PU.NW CODEC_TO_AP_PMU_INT_L + { PMU_IIC_BUS, kD2255_GPIO14_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO15_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_BB_USB_VBUS_DETECT + { PMU_IIC_BUS, kD2255_GPIO15_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO16_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_STOCKHOLM_EN + { PMU_IIC_BUS, kD2255_GPIO16_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO17_CONF1, (3<<6)|(2<<3)|(2<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO17_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO18_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO18_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO19_CONF1, (2<<6)|(0<<3)|(0<<1)|(1<<0) }, // O_PP.L.NP.1 PMU_TO_LCM_PANICB use OTP-AJ..AG setting rdar://19987012 + { PMU_IIC_BUS, kD2255_GPIO19_CONF2, (2<<3)|(2<<0) }, // VBUCK3_SW1, 10ms + { PMU_IIC_BUS, kD2255_GPIO20_CONF1, (3<<6)|(2<<3)|(2<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO20_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO21_CONF1, (1<<6)|(0<<3)|(0<<1)|(1<<0) }, // O_OD.L.NP.1 I2C0_AP_SCL + { PMU_IIC_BUS, kD2255_GPIO21_CONF2, (2<<3)|(2<<0) }, // VBUCK3_SW1, 10ms + + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA }, // enable test register access + // Fix Slew Rate on Buck2 + { PMU_IIC_BUS, kD2255_BUCK2_FSM_TRIM6, 0 }, + { PMU_IIC_BUS, kD2255_BUCK2_FSM_TRIM7, 0 }, + { PMU_IIC_BUS, kD2255_PWRONOFF_OUT_32K_EN, 0x7 }, // OUT_32K active in ACTIVE, SLEEP1,2 + { PMU_IIC_BUS, kD2255_BUCK2_MINV, 0x8 }, // Lower BUCK2_MINV + { PMU_IIC_BUS, kD2255_SYSCTL_PRE_UVLO_CTRL, 0x46 }, // + + // Set Buck5 Current +#if SUB_PLATFORM_S8003 + { PMU_IIC_BUS, kD2255_BUCK5_ANA_TRIM14, 0x36 }, // ILIM at 1.80A Max Load at 1.43 rdar://19846032 +#else + { PMU_IIC_BUS, kD2255_BUCK5_ANA_TRIM14, 0x39 }, // ILIM at 1.89A Max Load at 1.52 rdar://19724394 +#endif + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS }, // disabled test register access + + { PMU_IIC_BUS, kD2255_OUT_32K, 0x49 }, // OUT_32K active, VBUCK3, PP + +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK0_VSEL } +}; + +// it's VDD FIXED! used for RAM inside the SOC +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK5_VSEL } +}; + +// this is indexed with POWER_RAIL_*, I really just need to use the index in LDO[] +target_rails_t target_rails = { + { 0x0F, 500, 1296, 3125 }, // POWER_RAIL_CPU, BUCK0 + { 0x14, 600, 1396, 3125 }, // POWER_RAIL_VDD_FIXED BUCK5 + { 0x11, 600, 1396, 3125 }, // POWER_RAIL_SOC, BUCK2 + + { 0x16, 600, 1396, 3125 }, // POWER_RAIL_CPU_RAM, BUCK7 + { 0x10, 500, 1296, 3125 }, // POWER_RAIL_GPU, BUCK1 + { 0x17, 600, 1396, 3125 }, // POWER_RAIL_GPU_RAM, BUCK8 +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_POWER_NEEDS_BATTERY_PROTECTION_RESET 1 + +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/iphone8/include/target/uartconfig.h b/target/iphone8/include/target/uartconfig.h new file mode 100644 index 0000000..f81b712 --- /dev/null +++ b/target/iphone8/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/iphone8/init.c b/target/iphone8/init.c new file mode 100644 index 0000000..0b684de --- /dev/null +++ b/target/iphone8/init.c @@ -0,0 +1,1036 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#endif + +// Board rev encodings. The voltages are treated as active +// low (so 1.8V is a binary 1 and 0 V is a binary 0) so that +// the numbers count naturally +#define BOARD_REV_AP_PROTO1 0x0 +#define BOARD_REV_AP_PROTO2 0x1 +#define BOARD_REV_AP_EVT 0x2 +#define BOARD_REV_AP_EVT_MD 0x3 +#define BOARD_REV_AP_CARRIER1 0x4 +#define BOARD_REV_AP_CARRIER2 0x5 +#define BOARD_REV_AP_DVT_N66 0x6 + +#define BOARD_REV_DEV1 0x0 +#define BOARD_REV_DEV2 0x1 +#define BOARD_REV_DEV3 0x2 + +static uint32_t iphone8_get_board_rev(void); +static void iphone8_assert_display_type(void); + +#if WITH_HW_LM3534 +static void iphone8_get_backlight_i2c_address(uint32_t oid __unused, void *arg __unused, void *data); + +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_FUNCTION(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, iphone8_get_backlight_i2c_address, NULL); +#if TARGET_DISPLAY_D620 +MIB_CONSTANT(kMIBTargetBacklight1I2CBus, kOIDTypeUInt32, 2); +MIB_FUNCTION(kMIBTargetBacklight1I2CAddress, kOIDTypeUInt32, iphone8_get_backlight_i2c_address, NULL); +#endif +#endif + +#if TARGET_DISPLAY_D620 +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 3); +#else +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +#endif +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +/* Used to indicate to lm3534 driver to over-ride auto-frequency threshold */ +MIB_CONSTANT(kMIBTargetBacklightAutoFreqThresh, kOIDTypeUInt32, 0xc8); // This will change threshold from 8mA to 6.592mA + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; + +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +static mipi_t display_panel_configurations = { +#if TARGET_DISPLAY_D520 + .lanes = 2, + .esc_div = 8, + .pll_n = 0x0, + .pll_m = 0x30, + .pll_p = 0x0, + .hsfreq = 0x1b, + .target_phy_settings = { 4, {{0x44, 1, {0x36}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //1200 Mhz +#elif TARGET_DISPLAY_D620 + .lanes = 4, + .esc_div = 8, + .pll_n = 0x0, + .pll_m = 0x30, + .pll_p = 0x0, + .hsfreq = 0x1b, + .target_phy_settings = { 4, {{0x44, 1, {0x36}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //1200 Mhz +#endif +}; +#endif + +// Read the board rev GPIOs. Note that the encoding is done +// with active-low GPIOs, so we need to invert the values +// we read from the GPIOs +static uint32_t iphone8_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + // Invert + gpio_board_rev ^= 0xf; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + +#if WITH_ENV + env_set_uint("board-rev", gpio_board_rev, 0); +#endif + } + + return gpio_board_rev; +} + +#define TRISTATE_PULLDN (0) +#define TRISTATE_FLOAT (1) +#define TRISTATE_PULLUP (2) + +// reads a gpio that could be pulled up, pulled down, or floating +static uint32_t iphone8_read_tristate(gpio_t gpio) +{ + uint32_t val1; + uint32_t val2; + + gpio_configure(gpio, GPIO_CFG_IN); + gpio_configure_pupdn(gpio, GPIO_PDN); + + spin(100); // Wait 100us + + val1 = gpio_read(gpio); + + gpio_configure_pupdn(gpio, GPIO_PUP); + + spin(100); // Wait 100us + + val2 = gpio_read(gpio); + + gpio_configure(gpio, GPIO_CFG_DFLT); + + if (val1 == 0 && val2 == 0) + return TRISTATE_PULLDN; // pulled down + else if (val1 == 0 && val2 == 1) + return TRISTATE_FLOAT; // floating + else if (val1 == 1 && val2 == 1) + return TRISTATE_PULLUP; // pulled up + else + panic("unexpected result from gpio %u tristate read %u, %u", gpio, val1, val2); + +} + +// Display IDs are constructed with the formula (ID1 << 4 | ID0) where +// ID is 0 for grounded, 1 for floating, and 2 for pulled up +// Both pins floating means no card is connected +#define IPHONE8_DISPLAY_ID_TOF_PROX (1 << 8) + +#define IPHONE8_DISPLAY_ID_EMPTY (TRISTATE_FLOAT << 4 | TRISTATE_FLOAT << 0) + +#define IPHONE8_DISPLAY_ID_N71_P1 (TRISTATE_PULLDN << 4 | TRISTATE_PULLDN << 0) +#define IPHONE8_DISPLAY_ID_N71_P1_MUON (TRISTATE_PULLUP << 4 | TRISTATE_PULLDN << 0) +#define IPHONE8_DISPLAY_ID_N71 (TRISTATE_FLOAT << 4 | TRISTATE_PULLUP << 0) +#define IPHONE8_DISPLAY_ID_N71_TOF_PROX (IPHONE8_DISPLAY_ID_TOF_PROX | IPHONE8_DISPLAY_ID_N71) + +#define IPHONE8_DISPLAY_ID_N66_P1 (TRISTATE_PULLUP << 4 | TRISTATE_PULLUP << 0) +#define IPHONE8_DISPLAY_ID_N66 (TRISTATE_PULLUP << 4 | TRISTATE_FLOAT << 0) +#define IPHONE8_DISPLAY_ID_N66_TOF_PROX (IPHONE8_DISPLAY_ID_TOF_PROX | IPHONE8_DISPLAY_ID_N66) + +#if TARGET_DISPLAY_D520 +#define IPHONE8_DISPLAY_ID_DEFAULT_P1 IPHONE8_DISPLAY_ID_N71_P1 +#define IPHONE8_DISPLAY_ID_DEFAULT IPHONE8_DISPLAY_ID_N71 +#elif TARGET_DISPLAY_D620 +#define IPHONE8_DISPLAY_ID_DEFAULT_P1 IPHONE8_DISPLAY_ID_N66_P1 +#define IPHONE8_DISPLAY_ID_DEFAULT IPHONE8_DISPLAY_ID_N66 +#else +#error "Unknown display type" +#endif + +static const char* iphone8_get_display_id_pull(uint32_t id) +{ + switch (id) { + case TRISTATE_PULLDN: + return "pd"; + case TRISTATE_FLOAT: + return "op"; + case TRISTATE_PULLUP: + return "pu"; + default: + return "?"; + } +} + +static uint32_t iphone8_get_display_type(void) +{ + static bool display_id_valid = false; + static uint32_t display_id; + uint32_t prox; + uint32_t board_rev = iphone8_get_board_rev(); + uint32_t id0, id1; + + if (!display_id_valid) { + // for now, all proto hardware will have D520/D620. + if (target_config_ap()) { + // Display types for form-factor devices are determined + // by the board id and rev and the PROX_SELECT GPIO. + if (board_rev < BOARD_REV_AP_PROTO2) { + display_id = IPHONE8_DISPLAY_ID_DEFAULT_P1; + + dprintf(DEBUG_INFO, "Display ID: 0x%x\n", display_id); + } else { + prox = iphone8_read_tristate(GPIO_PROX_SELECT); + // PROX_SELECT must be pulled up (analog prox) or + // floating (Doppler prox). It cannot be pulled down. + ASSERT(prox != TRISTATE_PULLDN); + display_id = IPHONE8_DISPLAY_ID_DEFAULT; + if (prox == TRISTATE_FLOAT) { + display_id |= IPHONE8_DISPLAY_ID_TOF_PROX; + } + dprintf(DEBUG_INFO, "Display ID: 0x%x (prox=%s)\n", display_id, + iphone8_get_display_id_pull(prox)); + } + } else { + id0 = iphone8_read_tristate(GPIO_DISPLAY_ID0); + id1 = iphone8_read_tristate(GPIO_DISPLAY_ID1); + display_id = (id1 << 4) | id0; + + dprintf(DEBUG_INFO, "Display ID: 0x%x (id1/id0=%s/%s)\n", display_id, + iphone8_get_display_id_pull(id1), + iphone8_get_display_id_pull(id0)); + + switch (display_id) { + // No display is always supported + case IPHONE8_DISPLAY_ID_EMPTY: + display_id = IPHONE8_DISPLAY_ID_DEFAULT; + break; +#if TARGET_DISPLAY_D520 + // D500 and D520 displays are only supported on targets that support D520 (N71, basically) + case IPHONE8_DISPLAY_ID_N71_P1: + case IPHONE8_DISPLAY_ID_N71_P1_MUON: + case IPHONE8_DISPLAY_ID_N71: + break; +#elif TARGET_DISPLAY_D620 + // D600 and D620 displays are only supported on targets that support D620 (N66, basically) + case IPHONE8_DISPLAY_ID_N66_P1: + case IPHONE8_DISPLAY_ID_N66: + break; +#endif + default: + panic("unsupported display ID 0x%x (id1/id0=%s/%s)", + display_id, + iphone8_get_display_id_pull(id1), + iphone8_get_display_id_pull(id0)); + } + } + display_id_valid = true; + } + + return display_id; +} + +int target_get_boot_battery_capacity(void) +{ + int temp=0; +#if WITH_HW_GASGAUGE + if ( gasgauge_read_temperature(&temp) != 0 ) temp=0; // defensive +#endif + + const uint32_t charge_current=power_get_available_charge_current(); + if ( temp>500 && charge_current>500 ) return 0; // rely on SOC1 clear only + + return 50; // @see rdar://16587240 +} + + +int target_precharge_gg_flag_mask(void) +{ +#if (PRODUCT_IBSS || PRODUCT_LLB) + return kHDQRegFlagsMaskSOC1; // not available in iBSS or LLB (env is not there) +#else + static int gg_flag_mask=0; + + if ( gg_flag_mask==0 ) { + const char *boot_args = env_get("boot-args"); + if ( boot_args == NULL ) { + // nothing to do... + } else { + + char *arg_str= strstr(boot_args, "precharge-gg-flag-mask="); + if ( arg_str != NULL ) { + while ( *arg_str!='=' ) arg_str++; + + gg_flag_mask=strtoul( arg_str+1, NULL, 0 ); + if ( gg_flag_mask==0 ) gg_flag_mask=kHDQRegFlagsMaskSOC1; + } + + } + } + + return gg_flag_mask; +#endif +} + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + iphone8_get_board_rev(); + + if (target_config_ap() && iphone8_get_board_rev() < BOARD_REV_AP_PROTO2) { + dprintf(DEBUG_INFO, "Proto1 is deprecated\n"); + platform_not_supported(); + } + if (target_config_dev() && iphone8_get_board_rev() < BOARD_REV_DEV3) { + dprintf(DEBUG_INFO, "Dev1 and Dev2 are deprecated\n"); + platform_not_supported(); + } + + power_set_gpio(GPIO_PMU_NAND_LOW_POWER_MODE, 1, 1); +} + +bool iphone8_use_stockholm_gpio(void) +{ +#if SUB_TARGET_N71 + if (target_config_ap() && iphone8_get_board_rev() < BOARD_REV_AP_PROTO2) + return true; +#endif + return false; +} + +void target_init(void) +{ + uint32_t board_rev = iphone8_get_board_rev(); +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + dprintf(DEBUG_INFO, "board rev 0x%x (raw 0x%x)\n", board_rev, board_rev ^ 0xf); + iphone8_get_display_type(); + + // All devboards and N71 Proto1 use a GPIO to enable Stockholm +#if (PRODUCT_IBSS || PRODUCT_LLB) + bool use_stockholm_gpio = iphone8_use_stockholm_gpio(); + if (use_stockholm_gpio) { + static const uint32_t fixup_list[] = { + GPIO_ID(151), CFG_IN | PULL_DOWN | SLOW_SLEW, // 151 : GPIO[42] -> AP_TO_STOCKHOLM_EN + UINT32_MAX, UINT32_MAX + }; + + dprintf(DEBUG_INFO, "Fixing up GPIOs for DEV/pre-PROTO2 devices\n"); + + gpio_fixup_pinconfig(fixup_list); + } + if(target_config_dev() || iphone8_get_board_rev() < BOARD_REV_AP_EVT_MD) { + /* GPIO 42 is OFF for pre-EVT-MD revisions */ + static const uint32_t fixup_list[] = { + GPIO_ID(151), CFG_OUT_0 | SLOW_SLEW, // 151 : GPIO[42] (controls new external Orb LDO, replacement of LDO8) + UINT32_MAX, UINT32_MAX + }; + dprintf(DEBUG_INFO, "Disabling LDO via GPIO42\n"); + + gpio_fixup_pinconfig(fixup_list); + } else { + /* EVT-MD and Future will turn off LDO8 */ +#if WITH_HW_POWER +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); + + // in addition we need to disable LDO8 now that no one is using it [N71/N66] turn off LDO8 for EVT-MD + int rc=pmu_set_data(0, 0x0310, 0 , 1); + if ( rc<0 ) dprintf(DEBUG_INFO, "cannot change kD2255_PWRONOFF_LDO8_EN (%d)\n", rc); + +#endif + } +#if SUB_TARGET_N66 || SUB_TARGET_N66M + if(target_config_ap() && iphone8_get_board_rev() < BOARD_REV_AP_DVT_N66) { + /* N66 IO Spreadsheet v27a (for N66 DVT and older only) */ + static const uint32_t fixup_list[] = { + GPIO_ID(41), CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, + GPIO_ID(42), CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, + UINT32_MAX, UINT32_MAX + }; + dprintf(DEBUG_INFO, "Applying SPI2 workaround from v27a\n"); + gpio_fixup_pinconfig(fixup_list); + } +#endif +#endif + +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + return ((void *)(&display_panel_configurations)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); +#if TARGET_DISPLAY_D520 + env_set("display-timing", "D520", 0); + env_set("adbe-tunables", "D520", 0); + env_set("adfe-tunables", "D520", 0); +#elif TARGET_DISPLAY_D620 + env_set("display-timing", "D620", 0); + env_set("adbe-tunables", "D620", 0); + env_set("adfe-tunables", "D620", 0); +#endif +} + +#endif + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); +} +#endif + +#if WITH_HW_LM3534 + +// Do we use the legacy LM3534 (Meson) backlight, or the POR LM3539 (Muon) one? +static bool iphone8_use_lm3534(void) +{ + if (target_config_dev()) { + switch (iphone8_get_display_type()) { + case IPHONE8_DISPLAY_ID_N66_P1: + case IPHONE8_DISPLAY_ID_N71_P1: + // LM3534 + return true; + default: + // LM3539 + return false; + } + } else { + if (iphone8_get_board_rev() < BOARD_REV_AP_EVT) { + return true; + } else { + return false; + } + } +} + +static void iphone8_get_backlight_i2c_address(uint32_t oid __unused, void *arg __unused, void *data) +{ + uint32_t *resptr = (uint32_t *)data; + + if (iphone8_use_lm3534()) { + *resptr = 0xc6; + } else { + *resptr = 0xc4; + } +} + + +uint8_t target_lm3534_gpr(uint32_t ctlr) +{ + // auto mode, ramp disable, chip enable + uint8_t gpr = (1 << 4) | (1 << 1) | (1 << 0); + + return gpr; +} +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *disp0_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Start with hacks for prototypes and devboard, POR stuff is below the hacks + + if (FindNode(0, "arm-io/uart3/stockholm", &node)) { + propName = "function-enable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + char *propName_gpio; + void *propData_gpio; + uint32_t propSize_gpio; + + propName_gpio = "function-enable-gpio"; + if (FindProperty(node, &propName_gpio, &propData_gpio, &propSize_gpio)) { + bool use_stockholm_gpio = iphone8_use_stockholm_gpio(); + + if (use_stockholm_gpio) { + // Fixup AP_TO_STOCKHOLM_EN for older boards. + propName[0] = '~'; + propName_gpio[15] = 0; + } else { + propName_gpio[0] = '~'; + } + } + } + } + + // GPIO[42] is an additional enable for the rear camera's AVDD LDO on some + // configs of Proto2 and newer. On Proto1 it was the stockholm enable GPIO + // + // + // Additionally, this GPIO is repurposed for a DOE () + // For this DOE, we remove this function from the camera as well, + // and drive GPIO42 high at boot (see target_init()) + if (target_config_dev() || iphone8_get_board_rev() < BOARD_REV_AP_PROTO2) { + if (FindNode(0, "arm-io/isp", &node)) { + propName = "function-cam_avdd_gpio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + } + /* Based on , BOARD_REV_AP_PROTO2 needs to keep function-cam_avdd_gpio */ + if(target_config_ap() && (iphone8_get_board_rev() == BOARD_REV_AP_PROTO2 || iphone8_get_board_rev() == BOARD_REV_AP_EVT)) { + if (FindNode(0, "arm-io/isp", &node)) { + propName = "function-cam_avdd_gpio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + // [0-7]: String + // [8-11]: GPIO number + // [12-15]: GPIO pin setting + ((uint8_t*)propData)[8] = 151; + } + } + } + +#if TARGET_DISPLAY_D520 + // This mess is dictated by Update Merge Personalities for N71 + // See also Implement compatible field updates for N66 doppler prox + // See also XXX new radar here + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + uint32_t display_type = iphone8_get_display_type(); + + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (display_type == IPHONE8_DISPLAY_ID_N71_P1) { + strlcpy(propData, "multi-touch,t162", propSize); + } else if (display_type == IPHONE8_DISPLAY_ID_N71_P1_MUON) { + strlcpy(propData, "multi-touch,t162", propSize); + } else if (display_type == IPHONE8_DISPLAY_ID_N71) { + strlcpy(propData, "multi-touch,n71", propSize); + } else if (display_type == IPHONE8_DISPLAY_ID_N71_TOF_PROX) { + strlcpy(propData, "multi-touch,n71,2", propSize); + } else { + panic("Unknown/unsupported display 0x%x", display_type); + } + } + } +#endif +#if TARGET_DISPLAY_D620 + // Implement compatible field updates for N66 doppler prox + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + uint32_t display_type = iphone8_get_display_type(); + + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (display_type == IPHONE8_DISPLAY_ID_N66_P1) { + strlcpy(propData, "multi-touch,n66-p1", propSize); + } else if (display_type == IPHONE8_DISPLAY_ID_N66) { + strlcpy(propData, "multi-touch,n66", propSize); + } else if (display_type == IPHONE8_DISPLAY_ID_N66_TOF_PROX) { + strlcpy(propData, "multi-touch,n66,2", propSize); + } else { + panic("Unknown/unsupported display 0x%x", display_type); + } + } + } +#endif + + if (iphone8_use_lm3534()) { + if (dt_find_node(0, "arm-io/i2c0/lm3539", &node)) { + if (dt_has_prop(node, "reg-lm3534")) { + dt_remove_prop(node, "reg"); + dt_remove_prop(node, "compatible"); + dt_rename_prop(node, "reg-lm3534", "reg"); + dt_rename_prop(node, "compatible-lm3534", "compatible"); + dt_set_prop_str(node, "name", "lm3534"); + } + } +#if SUB_TARGET_N66 || SUB_TARGET_N66M + if (dt_find_node(0, "arm-io/i2c1/lm3539-1", &node)) { + if (dt_has_prop(node, "reg-lm3534")) { + dt_remove_prop(node, "reg"); + dt_remove_prop(node, "compatible"); + dt_rename_prop(node, "reg-lm3534", "reg"); + dt_rename_prop(node, "compatible-lm3534", "compatible"); + dt_set_prop_str(node, "name", "lm3534-1"); + } + } + if (dt_find_node(0, "arm-io/i2c2/lm3539-1", &node)) { + if (dt_has_prop(node, "reg-lm3534")) { + dt_remove_prop(node, "reg"); + dt_remove_prop(node, "compatible"); + dt_rename_prop(node, "reg-lm3534", "reg"); + dt_rename_prop(node, "compatible-lm3534", "compatible"); + dt_set_prop_str(node, "name", "lm3534-1"); + } + } +#endif + } + + // POR stuff below + +#if WITH_HW_DISPLAY_PINOT + // Find the DISP0 (display-subsystem 0) node + FindNode(0, "arm-io/disp0", &disp0_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, disp0_node, backlight_node); + } +#endif + +#if WITH_HW_MIPI_DSIM + // Find the mipi node + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + extern int mipi_update_device_tree(DTNode *mipi_node); + mipi_update_device_tree(node); + } +#endif + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + /* + VBCA Value: 0x00000009 0x0000000A 0x00000005 0x00000009 0x00000001 + + */ + uint8_t vbca[20]; + if (syscfgCopyDataForTag('VBCA', vbca, sizeof(vbca)) == sizeof(vbca)) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | ( (vbca[4]) & 0x1f); // Spkr VPBR + ((uint8_t *)propData)[16] = vbca[0]; // Spkr VBST + } + } + + propName = "acoustic-trim-gains"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ATGa', propData, propSize); + } + } + + if (FindNode(0, "arm-io/i2c1/audio-actuator", &node)) { + propName = "actuator-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('TCal', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + /* + VBCA Value: 0x00000009 0x0000000A 0x00000005 0x00000009 0x00000001 + + */ + uint8_t vbca[20]; + if (syscfgCopyDataForTag('VBCA', vbca, sizeof(vbca)) == sizeof(vbca)) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vbca[12] & 0x1f); // Arc VPBR + ((uint8_t *)propData)[16] = vbca[8]; // Arc VBST + } + } + } + + // Update the codec with acoustic transducer scale data + if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { + propName = "acoustic-trim-gains"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ATGa', propData, propSize); + } + + if (target_config_dev() || iphone8_get_board_rev() < BOARD_REV_AP_EVT) { + // For DEV and pre-EVT AP, switch in the old device tree properties + if (dt_remove_prop(node, "smic-mic")) { + dt_rename_prop(node, "smic-mic-preevt", "smic-mic"); + } + + if (dt_remove_prop(node, "lmic-mic")) { + dt_rename_prop(node, "lmic-mic-preevt", "lmic-mic"); + } + + if (dt_remove_prop(node, "smic-micbias")) { + dt_rename_prop(node, "smic-micbias-preevt", "smic-micbias"); + } + + if (dt_remove_prop(node, "lmic-micbias")) { + dt_rename_prop(node, "lmic-micbias-preevt", "lmic-micbias"); + } + } else { + // For EVT+ AP, delete pre-evt device tree properties + dt_remove_prop(node, "smic-mic-preevt"); + dt_remove_prop(node, "lmic-mic-preevt"); + dt_remove_prop(node, "smic-micbias-preevt"); + dt_remove_prop(node, "lmic-micbias-preevt"); + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + propName = "compass-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CRot', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/accel", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('PxCl', propData, propSize); + propName = "orb-gap-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('OrbG', propData, propSize); + propName = "orb-accel-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('OICo', propData, propSize); + propName = "orb-force-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('OFCl', propData, propSize); + propName = "orb-dynamic-accel-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('FDAC', propData, propSize); + } + + // Stockholm calibration + if (FindNode(0, "arm-io/uart3/stockholm", &node)) { + propName = "calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('NFCl', propData, propSize); + } + + // Update the X162 calibration data + if (FindNode(0, "arm-io/spi3/mesa", &node)) { + propName = "calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FSCl', propData, propSize); + } + propName = "modulation-ratio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('NvMR', propData, propSize); + } + } + +#if SUB_TARGET_N66 || SUB_TARGET_N66M + // Update rear camera tilt and rotation data + if (FindNode(0, "arm-io/isp", &node)) { + propName = "back-camera-tilt-and-rotation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BCTR', propData, propSize); + } + } +#endif + + // Update cover glass type + if (FindNode(0, "product", &node)) { + propName = "cover-glass"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CGSp', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('CBAT', propData, propSize); + } + + // Update Vibe calibration data + if (FindNode(0, "arm-io/i2c1/vib-pwm", &node)) { + propName = "calibration-data"; + if (FindProperty(node, &propName, &propData, &propSize)) { + const uint32_t count=syscfgCopyDataForTag('VbCl', propData, propSize); + if ( count!=propSize ) *((uint32_t*)propData)=0x00a46d0d; + } + } + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 00020000B9B5B4003C3B3B0000000000 +// gold/white: setenv DClr_override 00020000B5CCE100E3E4E10000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 39, 39, 40), false }, // Blacker - black background, white logo + { RGB(228, 231, 232), true }, // Whiter - white background, black logo + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +uint32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(uint8_t key, uint8_t *data) +{ + return -1; +} + +int power_set_nvram(uint8_t key, uint8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/iphone8/pinconfig.c b/target/iphone8/pinconfig.c new file mode 100644 index 0000000..16728f3 --- /dev/null +++ b/target/iphone8/pinconfig.c @@ -0,0 +1,648 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v29 + I/O Spreadsheet tracker: rdar://23054302 + + Generated with oldskool_csvtopinconfig.py. For new projects, use the regular csvtopinconfig.py + Conversion command: ./tools/oldskool_csvtopinconfig.py --soc h8p --copyright 2015 --radar rdar://23054302 --sheet Maui +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | SLOW_SLEW, // 0 : SWD_TMS2 -> SWD_AP_BI_NAND_SWDIO + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 1 : SWD_TMS3 -> NC + CFG_FUNC0 | SLOW_SLEW, // 2 : UART5_RTXD -> SWI_AP_BI_TIGRIS + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 3 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 4 : I2S4_BCLK -> I2S_AP_TO_CODEC_MSP_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 5 : I2S4_LRCK -> I2S_AP_TO_CODEC_MSP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 6 : I2S4_DIN -> I2S_CODEC_TO_AP_MSP_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 7 : I2S4_DOUT -> I2S_AP_TO_CODEC_MSP_DOUT + +/* Port 1 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 8 : I2S2_MCK -> I2S_AP_TO_SPEAKERAMP_MCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 9 : I2S2_BCLK -> I2S_AP_TO_CODEC_ASP_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 10 : I2S2_LRCK -> I2S_AP_TO_CODEC_ASP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 11 : I2S2_DIN -> I2S_CODEC_TO_AP_ASP_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 12 : I2S2_DOUT -> I2S_AP_TO_CODEC_ASP_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_SCLK -> SPI_AP_TO_CODEC_SCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 14 : SPI1_MOSI -> SPI_AP_TO_CODEC_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 15 : SPI1_MISO -> SPI_CODEC_TO_AP_MISO + +/* Port 2 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 16 : SPI1_SSIN -> SPI_AP_TO_CODEC_CS_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 17 : I2S0_MCK -> I2S_AP_TO_CODEC_MCLK_R + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 18 : I2S0_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 19 : I2S0_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 20 : I2S0_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 21 : I2S0_DOUT -> I2S_AP_TO_CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 22 : I2C2_SDA -> I2C2_AP_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 23 : I2C2_SCL -> I2C2_AP_SCL + +/* Port 3 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 24 : UART1_TXD -> UART_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 25 : UART1_RXD -> UART_BT_TO_AP_RXD + CFG_OUT_1 | SLOW_SLEW, // 26 : UART1_RTS_L -> UART_AP_TO_BT_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 27 : UART1_CTS_L -> UART_BT_TO_AP_CTS_L + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 28 : UART4_TXD -> UART_AP_TO_WLAN_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 29 : UART4_RXD -> UART_WLAN_TO_AP_RXD + CFG_OUT_1 | SLOW_SLEW, // 30 : UART4_RTS_L -> UART_AP_TO_WLAN_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 31 : UART4_CTS_L -> UART_WLAN_TO_AP_CTS_L + +/* Port 4 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 32 : UART7_TXD -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 33 : UART7_RXD -> PROX_SELECT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 34 : CLK32K_OUT -> AP_TO_TOUCH_CLK32K_RESET_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 35 : DP_WAKEUP -> NC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 36 : MIPICSI_MUXSEL -> NC + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 37 : ISP_I2C1_SDA -> I2C_ISP_BI_FCAM_SDA + CFG_FUNC0 | SLOW_SLEW, // 38 : ISP_I2C1_SCL -> I2C_ISP_TO_FCAM_SCL + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 39 : ISP_I2C0_SDA -> I2C_ISP_BI_RCAM_SDA + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : ISP_I2C0_SCL -> I2C_ISP_TO_RCAM_SCL + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 41 : SPI2_SCLK -> SPI_AP_TO_TOUCH_SCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 42 : SPI2_MOSI -> SPI_AP_TO_TOUCH_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 43 : SPI2_MISO -> SPI_TOUCH_TO_AP_MISO + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 44 : SPI2_SSIN -> SPI_AP_TO_TOUCH_CS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2C0_SDA -> I2C0_AP_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 46 : I2C0_SCL -> I2C0_AP_SCL + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 47 : SENSOR0_ISTRB -> NC + +/* Port 6 */ + CFG_OUT_0 | SLOW_SLEW, // 48 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN_L + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 49 : SENSOR0_CLK -> AP_TO_RCAM_CLK_R + CFG_IN | SLOW_SLEW, // 50 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQUEST + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 51 : SENSOR1_ISTRB -> NC + CFG_OUT_0 | SLOW_SLEW, // 52 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN_L + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 53 : SENSOR1_CLK -> AP_TO_FCAM_CLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 54 : SENSOR1_XSHUTDOWN -> AP_TO_MUON_BL_STROBE_EN + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 64 : GPIO[0] -> AP_TO_HP_HS3_CTRL + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 65 : GPIO[1] -> AP_TO_HP_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 66 : GPIO[2] -> BUTTON_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 67 : GPIO[3] -> BUTTON_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 68 : GPIO[4] -> SPEAKERAMP_TO_AP_INT_L + CFG_OUT_0 | SLOW_SLEW, // 69 : GPIO[5] -> AP_TO_SPEAKERAMP_STAYIN_ALIVE + CFG_OUT_0 | SLOW_SLEW, // 70 : GPIO[6] -> AP_TO_SPEAKERAMP_RESET_L + CFG_OUT_0 | SLOW_SLEW, // 71 : GPIO[7] -> AP_TO_BT_WAKE + +/* Port 9 */ + CFG_DISABLED | SLOW_SLEW, // 72 : GPIO[8] -> AP_TO_BB_RESET_L + CFG_OUT_0 | SLOW_SLEW, // 73 : GPIO[9] -> PCIE_AP_TO_WLAN_DEV_WAKE + CFG_OUT_0 | SLOW_SLEW, // 74 : GPIO[10] -> AP_TO_LED_DRIVER_EN + CFG_OUT_0 | SLOW_SLEW, // 75 : GPIO[11] -> AP_TO_TOUCH_RESET_L + CFG_OUT_0 | SLOW_SLEW, // 76 : GPIO[12] -> AP_TO_LCM_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 77 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 78 : GPIO[14] -> AP_TO_BB_PCIE_DEV_WAKE + CFG_OUT_0 | SLOW_SLEW, // 79 : GPIO[15] -> AP_TO_STOCKHOLM_DEV_WAKE + +/* Port 10 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 80 : GPIO[16] -> BOARD_ID3 + CFG_DISABLED | SLOW_SLEW, // 81 : GPIO[17] -> NC_AP_TO_STOCKHOLM_SIM_SEL + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 82 : GPIO[18] -> BOOT_CONFIG0 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 83 : I2S1_MCK -> I2S_AP_TO_ARC_MCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 84 : I2S1_BCLK -> I2S_AP_TO_BT_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 85 : I2S1_LRCK -> I2S_AP_TO_BT_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 86 : I2S1_DIN -> I2S_BT_TO_AP_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 87 : I2S1_DOUT -> I2S_AP_TO_BT_DOUT + +/* Port 11 */ + CFG_IN | PULL_UP | SLOW_SLEW, // 88 : UART3_TXD -> UART_AP_TO_STOCKHOLM_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 89 : UART3_RXD -> UART_STOCKHOLM_TO_AP_RXD + CFG_IN | PULL_UP | SLOW_SLEW, // 90 : UART3_RTS_L -> UART_AP_TO_STOCKHOLM_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 91 : UART3_CTS_L -> UART_STOCKHOLM_TO_AP_CTS_L + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : MENU_KEY_L -> BUTTON_MENU_KEY_L + CFG_FUNC0 | SLOW_SLEW, // 97 : HOLD_KEY_L -> BUTTON_HOLD_KEY_L + CFG_DISABLED | PULL_DOWN, // 98 : SKEY_L -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 99 : SPI3_SCLK -> SPI_AP_TO_MESA_SCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 100 : SPI3_MOSI -> SPI_AP_TO_MESA_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 101 : SPI3_MISO -> SPI_MESA_TO_AP_MISO + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 102 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 103 : SPI0_SCLK -> BOARD_ID0 + +/* Port 13 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 104 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 105 : SPI0_MISO -> BOARD_ID2 + CFG_OUT_1 | PULL_UP | SLOW_SLEW, // 106 : SPI0_SSIN -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 107 : UART0_TXD -> UART_AP_DEBUG_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 108 : UART0_RXD -> UART_AP_DEBUG_RXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 109 : UART6_TXD -> UART_AP_TO_ACCESSORY_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 110 : UART6_RXD -> UART_ACCESSORY_TO_AP_RXD + CFG_OUT_0 | SLOW_SLEW, // 111 : TMR32_PWM0 -> NC + +/* Port 14 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 112 : TMR32_PWM1 -> NC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 113 : TMR32_PWM2 -> NC + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 114 : I2C1_SDA -> I2C1_AP_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 115 : I2C1_SCL -> I2C1_AP_SCL + CFG_OUT_0 | SLOW_SLEW, // 116 : GPIO[19] -> AP_TO_ARC_RESET_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[20] -> LCM_TO_OWL_BSYNC + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 118 : GPIO[21] -> ARC_TO_AP_INT_L + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 119 : GPIO[22] -> BB_TO_AP_GPS_TIME_MARK + +/* Port 15 */ + CFG_OUT_0 | SLOW_SLEW, // 120 : GPIO[23] -> AP_TO_ARC_STAYIN_ALIVE + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 121 : GPIO[24] -> BB_TO_AP_RESET_DETECT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 122 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 123 : GPIO[26] -> FORCE_DFU + CFG_FUNC0 | SLOW_SLEW, // 124 : PMGR_MOSI -> DWI_PMGR_TO_PMU_BACKLIGHT_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 125 : PMGR_MISO -> DWI_PMU_TO_PMGR_MISO + CFG_FUNC0 | SLOW_SLEW, // 126 : PMGR_SCLK0 -> DWI_PMGR_TO_PMU_SCLK + CFG_FUNC0 | SLOW_SLEW, // 127 : PMGR_SSCLK1 -> DWI_PMGR_TO_BACKLIGHT_SCLK + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 128 : SOCHOT0 -> PMU_TO_AP_SOCHOT0_R_L + CFG_FUNC0 | SLOW_SLEW, // 129 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 130 : EDP_HPD -> NC + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 131 : I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2S3_BCLK -> I2S_AP_TO_BB_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2S3_LRCK -> I2S_AP_TO_BB_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 134 : I2S3_DOUT -> I2S_AP_TO_BB_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S3_DIN -> I2S_BB_TO_AP_DIN + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 136 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 137 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 139 : GPIO[30] -> CODEC_TO_AP_PMU_INT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 140 : GPIO[31] -> AP_TO_BB_RADIO_ON_L + CFG_OUT_0 | SLOW_SLEW, // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 142 : GPIO[33] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 143 : GPIO[34] -> BOARD_REV3 + +/* Port 18 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 144 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 145 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 146 : GPIO[37] -> BOARD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 147 : GPIO[38] -> AP_TO_BB_COREDUMP + CFG_DISABLED | SLOW_SLEW, // 148 : GPIO[39] -> BB_IPC_GPIO + CFG_IN | SLOW_SLEW, // 149 : GPIO[40] -> BUTTON_RINGER_A + CFG_DISABLED | SLOW_SLEW, // 150 : GPIO[41] -> AP_TO_BB_MESA_UP_L + CFG_OUT_1 | SLOW_SLEW, // 151 : GPIO[42] -> MAMBA_EXT_LDO_EN + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_IN | SLOW_SLEW, // 160 : PCIE_PERST0_L -> PCIE_AP_TO_NAND_RESET_L + CFG_IN | SLOW_SLEW, // 161 : PCIE_PERST1_L -> PCIE_AP_TO_WLAN_RESET_L + CFG_IN | SLOW_SLEW, // 162 : PCIE_PERST2_L -> PCIE_AP_TO_BB_RESET_L + CFG_IN | PULL_DOWN | SLOW_SLEW, // 163 : PCIE_PERST3_L -> NC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 164 : PCIE_CLKREQ0_L -> PCIE_NAND_TO_AP_CLKREQ_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 165 : PCIE_CLKREQ1_L -> PCIE_WLAN_TO_AP_CLKREQ_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 166 : PCIE_CLKREQ2_L -> PCIE_BB_BI_AP_CLKREQ_L + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 167 : PCIE_CLKREQ3_L -> NC + +/* Port 21 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 192 : UART2_TXD -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 193 : UART2_RXD -> NC + CFG_OUT_0 | SLOW_SLEW, // 194 : UART2_RTS_L -> CAM_EXT_LDO_EN + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 195 : UART2_CTS_L -> NC + CFG_FUNC0 | SLOW_SLEW, // 196 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + CFG_FUNC0 | SLOW_SLEW, // 197 : S3E_RESET_L -> AP_TO_NAND_RESET_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 198 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED, +}; + +static const uint32_t pinconfig_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 0 : OWL_SPI_SCLK -> SPI_OWL_TO_IMU_SCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 1 : OWL_SPI_MOSI -> SPI_OWL_TO_IMU_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 2 : OWL_SPI_MISO -> SPI_IMU_TO_OWL_MISO + CFG_OUT_0 | SLOW_SLEW, // 3 : OWL_UART1_TXD -> OWL_TO_WLAN_CONTEXT_A + CFG_OUT_0 | SLOW_SLEW, // 4 : OWL_UART1_RXD -> OWL_TO_WLAN_CONTEXT_B + CFG_OUT_0 | SLOW_SLEW, // 5 : OWL_UART0_TXD -> UART_OWL_TO_BB_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 6 : OWL_UART0_RXD -> UART_BB_TO_OWL_RXD + CFG_FUNC0 | SLOW_SLEW, // 7 : OWL_UART2_TXD -> UART_OWL_TO_TOUCH_TXD + +/* Port 1 */ + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 8 : OWL_UART2_RXD -> TOUCH_TO_OWL_ACCEL_DATA_REQUEST + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 9 : OWL_I2CM_SDA -> DISCRETE_ACCEL_TO_OWL_INT1 + CFG_FUNC0 | SLOW_SLEW, // 10 : OWL_I2CM_SCL -> SPI_OWL_TO_DISCRETE_ACCEL_CS_L + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 11 : OWL_FUNC[0] -> SPI_OWL_TO_COMPASS_CS_L + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 12 : OWL_FUNC[1] -> COMPASS_TO_OWL_INT + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 13 : OWL_FUNC[2] -> DISCRETE_ACCEL_TO_OWL_INT2 + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 14 : OWL_FUNC[3] -> ACCEL_GYRO_TO_OWL_INT1 + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 15 : OWL_FUNC[4] -> SPI_OWL_TO_ACCEL_GYRO_CS_L + +/* Port 2 */ + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 16 : OWL_FUNC[5] -> ACCEL_GYRO_TO_OWL_INT2 + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 17 : OWL_FUNC[6] -> SPI_OWL_TO_PHOSPHOROUS_CS_L + CFG_IN | PULL_DOWN | SLOW_SLEW, // 18 : OWL_FUNC[7] -> LCM_TO_OWL_BSYNC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 19 : OWL_FUNC[8] -> OWL_TO_PMU_SHDN_BI_TIGRIS_SWI + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 20 : OWL_FUNC[9] -> PHOSPHORUS_TO_OWL_IRQ + CFG_FUNC0 | SLOW_SLEW, // 21 : OWL_SWD_TCK_OUT -> SWD_AP_PERIPHERAL_SWCLK + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 22 : OWL_SWD_TMS0 -> NC + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 23 : OWL_SWD_TMS1 -> SWD_AP_BI_BB_SWDIO + +/* Port 3 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 24 : OWL_I2S_MCK -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 25 : OWL_I2S_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 26 : OWL_I2S_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 27 : OWL_I2S_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 0 : SWD_TMS2 -> SWD_AP_BI_NAND_SWDIO + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 1 : SWD_TMS3 -> NC + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : UART5_RTXD -> SWI_AP_BI_TIGRIS + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 3 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 4 : I2S4_BCLK -> I2S_AP_TO_CODEC_MSP_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 5 : I2S4_LRCK -> I2S_AP_TO_CODEC_MSP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 6 : I2S4_DIN -> I2S_CODEC_TO_AP_MSP_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 7 : I2S4_DOUT -> I2S_AP_TO_CODEC_MSP_DOUT + +/* Port 1 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 8 : I2S2_MCK -> I2S_AP_TO_SPEAKERAMP_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 9 : I2S2_BCLK -> I2S_AP_TO_CODEC_ASP_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 10 : I2S2_LRCK -> I2S_AP_TO_CODEC_ASP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 11 : I2S2_DIN -> I2S_CODEC_TO_AP_ASP_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 12 : I2S2_DOUT -> I2S_AP_TO_CODEC_ASP_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_SCLK -> SPI_AP_TO_CODEC_SCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 14 : SPI1_MOSI -> SPI_AP_TO_CODEC_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 15 : SPI1_MISO -> SPI_CODEC_TO_AP_MISO + +/* Port 2 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 16 : SPI1_SSIN -> SPI_AP_TO_CODEC_CS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 17 : I2S0_MCK -> I2S_AP_TO_CODEC_MCLK_R + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 18 : I2S0_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 19 : I2S0_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 20 : I2S0_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 21 : I2S0_DOUT -> I2S_AP_TO_CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 22 : I2C2_SDA -> I2C2_AP_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 23 : I2C2_SCL -> I2C2_AP_SCL + +/* Port 3 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 24 : UART1_TXD -> UART_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 25 : UART1_RXD -> UART_BT_TO_AP_RXD + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 26 : UART1_RTS_L -> UART_AP_TO_BT_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 27 : UART1_CTS_L -> UART_BT_TO_AP_CTS_L + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 28 : UART4_TXD -> UART_AP_TO_WLAN_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 29 : UART4_RXD -> UART_WLAN_TO_AP_RXD + CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, // 30 : UART4_RTS_L -> UART_AP_TO_WLAN_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 31 : UART4_CTS_L -> UART_WLAN_TO_AP_CTS_L + +/* Port 4 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 32 : UART7_TXD -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 33 : UART7_RXD -> PROX_SELECT + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 34 : CLK32K_OUT -> AP_TO_TOUCH_CLK32K_RESET_L + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 35 : DP_WAKEUP -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 36 : MIPICSI_MUXSEL -> NC + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 37 : ISP_I2C1_SDA -> I2C_ISP_BI_FCAM_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : ISP_I2C1_SCL -> I2C_ISP_TO_FCAM_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 39 : ISP_I2C0_SDA -> I2C_ISP_BI_RCAM_SDA + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 40 : ISP_I2C0_SCL -> I2C_ISP_TO_RCAM_SCL + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 41 : SPI2_SCLK -> SPI_AP_TO_TOUCH_SCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : SPI2_MOSI -> SPI_AP_TO_TOUCH_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 43 : SPI2_MISO -> SPI_TOUCH_TO_AP_MISO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 44 : SPI2_SSIN -> SPI_AP_TO_TOUCH_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2C0_SDA -> I2C0_AP_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 46 : I2C0_SCL -> I2C0_AP_SCL + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 47 : SENSOR0_ISTRB -> NC + +/* Port 6 */ + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 48 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 49 : SENSOR0_CLK -> AP_TO_RCAM_CLK_R + CFG_IN | SLOW_SLEW, // 50 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQUEST + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 51 : SENSOR1_ISTRB -> NC + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 52 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 53 : SENSOR1_CLK -> AP_TO_FCAM_CLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 54 : SENSOR1_XSHUTDOWN -> AP_TO_MUON_BL_STROBE_EN + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 64 : GPIO[0] -> AP_TO_HP_HS3_CTRL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 65 : GPIO[1] -> AP_TO_HP_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 66 : GPIO[2] -> BUTTON_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 67 : GPIO[3] -> BUTTON_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 68 : GPIO[4] -> SPEAKERAMP_TO_AP_INT_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 69 : GPIO[5] -> AP_TO_SPEAKERAMP_STAYIN_ALIVE + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 70 : GPIO[6] -> AP_TO_SPEAKERAMP_RESET_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 71 : GPIO[7] -> AP_TO_BT_WAKE + +/* Port 9 */ + CFG_DISABLED | SLOW_SLEW, // 72 : GPIO[8] -> AP_TO_BB_RESET_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 73 : GPIO[9] -> PCIE_AP_TO_WLAN_DEV_WAKE + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 74 : GPIO[10] -> AP_TO_LED_DRIVER_EN + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[11] -> AP_TO_TOUCH_RESET_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 76 : GPIO[12] -> AP_TO_LCM_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 77 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 78 : GPIO[14] -> AP_TO_BB_PCIE_DEV_WAKE + CFG_OUT_0 | SLOW_SLEW, // 79 : GPIO[15] -> AP_TO_STOCKHOLM_DEV_WAKE + +/* Port 10 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 80 : GPIO[16] -> BOARD_ID3 + CFG_DISABLED | SLOW_SLEW, // 81 : GPIO[17] -> NC_AP_TO_STOCKHOLM_SIM_SEL + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 82 : GPIO[18] -> BOOT_CONFIG0 + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 83 : I2S1_MCK -> I2S_AP_TO_ARC_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 84 : I2S1_BCLK -> I2S_AP_TO_BT_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 85 : I2S1_LRCK -> I2S_AP_TO_BT_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 86 : I2S1_DIN -> I2S_BT_TO_AP_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2S1_DOUT -> I2S_AP_TO_BT_DOUT + +/* Port 11 */ + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 88 : UART3_TXD -> UART_AP_TO_STOCKHOLM_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 89 : UART3_RXD -> UART_STOCKHOLM_TO_AP_RXD + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 90 : UART3_RTS_L -> UART_AP_TO_STOCKHOLM_RTS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 91 : UART3_CTS_L -> UART_STOCKHOLM_TO_AP_CTS_L + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : MENU_KEY_L -> BUTTON_MENU_KEY_L + CFG_FUNC0 | SLOW_SLEW, // 97 : HOLD_KEY_L -> BUTTON_HOLD_KEY_L + CFG_DISABLED | PULL_DOWN | DRIVE_X2, // 98 : SKEY_L -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X6 | SLOW_SLEW | INPUT_SCHMITT, // 99 : SPI3_SCLK -> SPI_AP_TO_MESA_SCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 100 : SPI3_MOSI -> SPI_AP_TO_MESA_MOSI + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 101 : SPI3_MISO -> SPI_MESA_TO_AP_MISO + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 102 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 103 : SPI0_SCLK -> BOARD_ID0 + +/* Port 13 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 104 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 105 : SPI0_MISO -> BOARD_ID2 + CFG_OUT_1 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 106 : SPI0_SSIN -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 107 : UART0_TXD -> UART_AP_DEBUG_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 108 : UART0_RXD -> UART_AP_DEBUG_RXD + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 109 : UART6_TXD -> UART_AP_TO_ACCESSORY_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 110 : UART6_RXD -> UART_ACCESSORY_TO_AP_RXD + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 111 : TMR32_PWM0 -> NC + +/* Port 14 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 112 : TMR32_PWM1 -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 113 : TMR32_PWM2 -> NC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 114 : I2C1_SDA -> I2C1_AP_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 115 : I2C1_SCL -> I2C1_AP_SCL + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 116 : GPIO[19] -> AP_TO_ARC_RESET_L + CFG_IN | SLOW_SLEW, // 117 : GPIO[20] -> LCM_TO_OWL_BSYNC + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 118 : GPIO[21] -> ARC_TO_AP_INT_L + CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 119 : GPIO[22] -> BB_TO_AP_GPS_TIME_MARK + +/* Port 15 */ + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 120 : GPIO[23] -> AP_TO_ARC_STAYIN_ALIVE + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 121 : GPIO[24] -> BB_TO_AP_RESET_DETECT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 122 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 123 : GPIO[26] -> FORCE_DFU + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 124 : PMGR_MOSI -> DWI_PMGR_TO_PMU_BACKLIGHT_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 125 : PMGR_MISO -> DWI_PMU_TO_PMGR_MISO + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 126 : PMGR_SCLK0 -> DWI_PMGR_TO_PMU_SCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 127 : PMGR_SSCLK1 -> DWI_PMGR_TO_BACKLIGHT_SCLK + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 128 : SOCHOT0 -> PMU_TO_AP_SOCHOT0_R_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 129 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 130 : EDP_HPD -> NC + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 131 : I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2S3_BCLK -> I2S_AP_TO_BB_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2S3_LRCK -> I2S_AP_TO_BB_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 134 : I2S3_DOUT -> I2S_AP_TO_BB_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S3_DIN -> I2S_BB_TO_AP_DIN + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 136 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 137 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + CFG_IN | SLOW_SLEW | INPUT_SCHMITT, // 139 : GPIO[30] -> CODEC_TO_AP_PMU_INT_L + CFG_DISABLED | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 140 : GPIO[31] -> AP_TO_BB_RADIO_ON_L + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 142 : GPIO[33] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 143 : GPIO[34] -> BOARD_REV3 + +/* Port 18 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 144 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 145 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 146 : GPIO[37] -> BOARD_REV0 + CFG_OUT_0 | SLOW_SLEW, // 147 : GPIO[38] -> AP_TO_BB_COREDUMP + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 148 : GPIO[39] -> BB_IPC_GPIO + CFG_IN | SLOW_SLEW, // 149 : GPIO[40] -> BUTTON_RINGER_A + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 150 : GPIO[41] -> AP_TO_BB_MESA_UP_L + CFG_OUT_1 | SLOW_SLEW, // 151 : GPIO[42] -> MAMBA_EXT_LDO_EN + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 160 : PCIE_PERST0_L -> PCIE_AP_TO_NAND_RESET_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 161 : PCIE_PERST1_L -> PCIE_AP_TO_WLAN_RESET_L + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 162 : PCIE_PERST2_L -> PCIE_AP_TO_BB_RESET_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 163 : PCIE_PERST3_L -> NC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 164 : PCIE_CLKREQ0_L -> PCIE_NAND_TO_AP_CLKREQ_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 165 : PCIE_CLKREQ1_L -> PCIE_WLAN_TO_AP_CLKREQ_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 166 : PCIE_CLKREQ2_L -> PCIE_BB_BI_AP_CLKREQ_L + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 167 : PCIE_CLKREQ3_L -> NC + +/* Port 21 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 192 : UART2_TXD -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 193 : UART2_RXD -> NC + CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, // 194 : UART2_RTS_L -> CAM_EXT_LDO_EN + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 195 : UART2_CTS_L -> NC + CFG_FUNC0 | DRIVE_X6 | SLOW_SLEW, // 196 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 197 : S3E_RESET_L -> AP_TO_NAND_RESET_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 198 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 0 : OWL_SPI_SCLK -> SPI_OWL_TO_IMU_SCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 1 : OWL_SPI_MOSI -> SPI_OWL_TO_IMU_MOSI + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 2 : OWL_SPI_MISO -> SPI_IMU_TO_OWL_MISO + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 3 : OWL_UART1_TXD -> OWL_TO_WLAN_CONTEXT_A + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : OWL_UART1_RXD -> OWL_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : OWL_UART0_TXD -> UART_OWL_TO_BB_TXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : OWL_UART0_RXD -> UART_BB_TO_OWL_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 7 : OWL_UART2_TXD -> UART_OWL_TO_TOUCH_TXD + +/* Port 1 */ + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 8 : OWL_UART2_RXD -> TOUCH_TO_OWL_ACCEL_DATA_REQUEST + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 9 : OWL_I2CM_SDA -> DISCRETE_ACCEL_TO_OWL_INT1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 10 : OWL_I2CM_SCL -> SPI_OWL_TO_DISCRETE_ACCEL_CS_L + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 11 : OWL_FUNC[0] -> SPI_OWL_TO_COMPASS_CS_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 12 : OWL_FUNC[1] -> COMPASS_TO_OWL_INT + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 13 : OWL_FUNC[2] -> DISCRETE_ACCEL_TO_OWL_INT2 + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 14 : OWL_FUNC[3] -> ACCEL_GYRO_TO_OWL_INT1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 15 : OWL_FUNC[4] -> SPI_OWL_TO_ACCEL_GYRO_CS_L + +/* Port 2 */ + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 16 : OWL_FUNC[5] -> ACCEL_GYRO_TO_OWL_INT2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 17 : OWL_FUNC[6] -> SPI_OWL_TO_PHOSPHOROUS_CS_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 18 : OWL_FUNC[7] -> LCM_TO_OWL_BSYNC + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 19 : OWL_FUNC[8] -> OWL_TO_PMU_SHDN_BI_TIGRIS_SWI + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 20 : OWL_FUNC[9] -> PHOSPHORUS_TO_OWL_IRQ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 21 : OWL_SWD_TCK_OUT -> SWD_AP_PERIPHERAL_SWCLK + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 22 : OWL_SWD_TMS0 -> NC + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 23 : OWL_SWD_TMS1 -> SWD_AP_BI_BB_SWDIO + +/* Port 3 */ + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 24 : OWL_I2S_MCK -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 25 : OWL_I2S_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 26 : OWL_I2S_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 27 : OWL_I2S_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0, pinconfig_ap_1 } }, + { 1, 1, { pinconfig_dev_0, pinconfig_dev_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/iphone8/rules.mk b/target/iphone8/rules.mk new file mode 100644 index 0000000..ce6700f --- /dev/null +++ b/target/iphone8/rules.mk @@ -0,0 +1,50 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2255=1 \ + TARGET_CHESTNUT_VNEG_CONTROL=0x05 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_PLL_VCO_CAP=0 \ + WITH_HW_AGC_MIPI_V2=1 \ + TARGET_AGILE_LINECOUNT=0xFFFF \ + TARGET_AGILE_SEQ1=0x2010002 \ + TARGET_AGILE_SEQ2=0x6010231 \ + TARGET_AGILE_CTRL=0x1800 \ + TARGET_HS_2_LP_DATA_TIME=35 \ + TARGET_LP_2_HS_DATA_TIME=60 \ + TARGET_HS_2_LP_CLOCK_TIME=67 \ + TARGET_LP_2_HS_CLOCK_TIME=159 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_IPHONE_TUNABLES=1 \ + DPB_DETECT_VIB_CONTROL_TUNABLE=0xa4830001 \ + DCS_NUM_RANKS=1 \ + DCS_NUM_CHANNELS=4 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi2/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart4/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o + +ALL_OBJS += $(LOCAL_DIR)/pinconfig.o diff --git a/target/ipod6/include/target/adbe_settings.h b/target/ipod6/include/target/adbe_settings.h new file mode 100644 index 0000000..3645830 --- /dev/null +++ b/target/ipod6/include/target/adbe_settings.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v3_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_tunable_nrt_ctl = (ADBE_NRT_CTL_ADISP_CLK_GATE_ENABLE | ADBE_NRT_CTL_ADBE_CLK_GATE_ENABLE | ADBE_NRT_CTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 0, + }, +}; + +#endif diff --git a/target/ipod6/include/target/amcconfig.h b/target/ipod6/include/target/amcconfig.h new file mode 100644 index 0000000..3446281 --- /dev/null +++ b/target/ipod6/include/target/amcconfig.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if SUPPORT_FPGA + +static const struct amc_param amc_params = { + .flags = FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_ENABLE_AIU | FLAG_AMC_PARAM_LEGACY | FLAG_AMC_PARAM_ZQCL, + + .freqsel = 3, + .tREFi = 0x28, + .longsrcnt = 0x2008, + .srextrarefcnt = (0x2 << 16), + .rdlat = 4, + .wrlat = 2, + .phyrdlat = 6, + .phywrlat = 1, + .pdn = 0x22000103, + .read = 0x00000101, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .derate = 0x08210212, + .mcphyupdate = 0x05030000, + .mcphyupdate1 = 0x00000004, + .autoref_params = 0x1a1a1a1a, + .chnldec = 0x00050001, + .qbrparam = 0x00510000, + .odts = 0x190, + .aref_freq0 = 0x00000110, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01803000, + .schen_default = 0x00000110, + .pwrmngten_default = 0x00100100, + .addrcfg = 0x00020201, + .bankhash0 = 0x00006db6, + .bankhash1 = 0x00005b6d, + .bankhash2 = 0x000036db, + .bootclkdivsr = 1, + .mr1 = 0xc4, + .mr3 = 0x2, + .mr2 = 0x6, + .mr63 = 0xfc, + + .freq = { + { // 533MHz + .cas = 0x00000202, + .pch = 0x00010202, + .act = 0x04010202, + .autoref = 0x02030000, + .selfref = 0x00003040, + .modereg = 0x20020722, + .arefparam = 0x0c022131, + .mifcassch = 0x00000110, + .trefbwbasecyc = 0x0000002d, + }, + { // -- unused + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02030000, + .selfref = 0x00003000, + .modereg = 0x00020000, + .arefparam = 0x00000101, + .mifcassch = 0x00000000, + .trefbwbasecyc = 0x00000017, + }, + { // -- unused + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02030000, + .selfref = 0x00003000, + .modereg = 0x00020000, + .arefparam = 0x00000101, + .mifcassch = 0x00000000, + .trefbwbasecyc = 0x0000000c, + }, + { // 24MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02030000, + .selfref = 0x00003000, + .modereg = 0x00020000, + .arefparam = 0x00000101, + .mifcassch = 0x00000010, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_AIUPRT_CFG, 0x00070000}, + { &rAMC_AIUPRT_RD_GEN, 0x80000018}, + { &rAMC_AIU_CHNLTM, 0x40003101}, + { &rAMC_AIU_RDBRSTLEN, 0x01010101}, + { &rAMC_AIU_RDMAXCRD, 0x3012097f}, + { &rAMC_AIU_RDREFL, 0x280f087f}, + { &rAMC_AIU_WRBRSTLEN, 0x01010101}, + { &rAMC_AIU_WRMAXCRD, 0x3012097f}, + { &rAMC_AIU_WRREFL, 0x280f087f}, + { &rAMC_AIU_CPUSPCREQ, 0x00000013}, + { &rAMC_AIU_GFXSPCREQ, 0x00000019}, + { &rAMC_AIU_NRTSPCREQ, 0x00000019}, + { &rAMC_AIU_RTSPCREQ, 0x00000013}, + { &rAMC_AIU_WPQSCH, 0x08000800}, + { &rAMC_AIU_THOTLEN, 0x00000030}, + { &rAMC_AIU_THOTLCPUPARAM, 0x00000084}, + { &rAMC_AIU_THOTLRTPARAM, 0x00000084}, + { &rAMC_AIU_THOTLNRTPARAM, 0x00000080}, + { &rAMC_AIU_THOTLGFXPARAM, 0x00000080}, + { &rAMC_AIU_PUSHEN, 0x00001100}, + { &rAMC_AIU_THOTLCPUPARAM2, 0x00c00040}, + { &rAMC_AIU_THOTLRTPARAM2, 0x00c00040}, + { &rAMC_AIU_THOTLNRTPARAM2, 0x00000040}, + { &rAMC_AIU_THOTLGFXPARAM2, 0x00000040}, + { &rAMC_AIU_LLTSCHCTL, 0x00000001}, + { &rAMC_OPIDLETMR, 0x00200000}, + { &rAMC_OPTMRADJPARAM, 0x20400064}, + { &rAMC_MIFACTSCH, 0x00000001}, + { &rAMC_PSQRQCTL0, 0x01010000}, + { &rAMC_PSQRQCTL1, 0x0000132a}, + { &rAMC_PSQRQTIMER0, 0x00000018}, + { &rAMC_PSQRQTIMER1, 0x00000006}, + { &rAMC_PSQRQTIMER2, 0x00000020}, + { &rAMC_PSQRQBRST, 0x040c040c}, + { &rAMC_PSQRQSCHCRD, 0x002028f5}, + { &rAMC_PSQWQCTL1, 0x00000180}, + { &rAMC_PSQWQBRST, 0x02020208}, + { &rAMC_PSQWQSCHCRD, 0x000405f5}, + { &rAMC_MCUQOS, 0x00010f04}, + { &rAMC_MCUQOSLLT, 0x00010108}, + + {0, 0}, +}; + +#else + +#error "Not supported for this target" + +#endif diff --git a/target/ipod6/include/target/ampconfig.h b/target/ipod6/include/target/ampconfig.h new file mode 100644 index 0000000..e25eeaa --- /dev/null +++ b/target/ipod6/include/target/ampconfig.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amp/amp.h, and this + * file should only by included from that amp.c. + */ + +#if SUPPORT_FPGA + +static struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x21020304 + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x31020307 + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x51020305 + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61020304 + } + }, + .drive_strength = 0x12121212, +}; + +#else + +#error "Not supported for this target" + +#endif diff --git a/target/ipod6/include/target/aspnandconfig.h b/target/ipod6/include/target/aspnandconfig.h new file mode 100644 index 0000000..2bb0417 --- /dev/null +++ b/target/ipod6/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 1 +#define ASPNAND_READ_DIES_IN_PARALLEL 1 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 1 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 1 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/ipod6/include/target/cjay.h b/target/ipod6/include/target/cjay.h new file mode 100644 index 0000000..0b1a5b2 --- /dev/null +++ b/target/ipod6/include/target/cjay.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef _Cjay_h_ +#define _Cjay_h_ + +// Seajay calibration +typedef struct __attribute__((packed)) { + uint8_t Version; + uint16_t Magic; + uint8_t IsNotCalibrated; + uint32_t NumOfItems; + uint32_t SizeOfItems; +} SeajayCalHdr; + +typedef struct __attribute__((packed)) { + uint32_t Status; + uint32_t Offset; // Q15.16 fixed point, 4 bytes + uint32_t pad1; + uint32_t Gain; // Q15.16 fixed point, 4 bytes + uint32_t pad2; +} SeajayCalItem; + +typedef struct __attribute__((packed)) { + SeajayCalHdr Hdr; + SeajayCalItem Item; +} SeajayCal; + +enum { + kCalStatus_NoCal = 0x0, /* This means that we haven't done any calibration */ + kCalStatus_Offset = 0x1, /* Offset has been calibrated */ + kCalStatus_Gain = 0x2, /* Gain has been calibrated */ + kCalStatus_All = 0x3, /* Both gain & offset have been calibrated */ +}; + +#define SEAJAY_CAL_VERSION 0x2 +#define SEAJAY_CAL_MAGIC 0xabcd + +#endif /* _Cjay_h_ */ diff --git a/target/ipod6/include/target/display_gamma_tables.h b/target/ipod6/include/target/display_gamma_tables.h new file mode 100644 index 0000000..3839e12 --- /dev/null +++ b/target/ipod6/include/target/display_gamma_tables.h @@ -0,0 +1,615 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_DISPLAY_GAMMA_TABLES_H +#define __TARGET_DISPLAY_GAMMA_TABLES_H + +/* display gamma tables */ + +static const uint32_t target_gp_csc_matrix[3][3] = { + { 0x0c66, 0x0399, 0x0000 }, + { 0x002f, 0x0fd0, 0x0000 }, + { 0x0046, 0x0144, 0x0e74 }, +}; + +/* + * The table is auto generated by a tool in iOS. + * Unfortunately it includes one more entry than needed for degamma LUT entry. + * Hence the code should accomodate it + */ +#define ADP_CM_DEGAMMA_PAIRED_LUT_COUNT 65 +#define ADP_CM_DEGAMMA_PAIRED_LUT_SIZE (ADP_CM_DEGAMMA_PAIRED_LUT_COUNT - 1) +static const uint32_t target_gp_degamma_tables[ADP_CM_DEGAMMA_PAIRED_LUT_COUNT] = { + 0x00000000, // LUT[0000] 0x0000 (0.00000000) -> 0x0000 (0.00000000) | LUT[0001] 0x0008 (0.00782014) -> 0x0000 (0.00002318) + 0x00020001, // LUT[0002] 0x0010 (0.01564027) -> 0x0001 (0.00010650) | LUT[0003] 0x0018 (0.02346041) -> 0x0002 (0.00025986) + 0x00070004, // LUT[0004] 0x0020 (0.03128055) -> 0x0004 (0.00048933) | LUT[0005] 0x0028 (0.03910068) -> 0x0007 (0.00079948) + 0x000e000a, // LUT[0006] 0x0030 (0.04692082) -> 0x000a (0.00119400) | LUT[0007] 0x0038 (0.05474096) -> 0x000e (0.00167605) + 0x00180012, // LUT[0008] 0x0040 (0.06256109) -> 0x0012 (0.00224838) | LUT[0009] 0x0048 (0.07038123) -> 0x0018 (0.00291343) + 0x0025001e, // LUT[0010] 0x0050 (0.07820137) -> 0x001e (0.00367343) | LUT[0011] 0x0058 (0.08602151) -> 0x0025 (0.00453039) + 0x0036002d, // LUT[0012] 0x0060 (0.09384164) -> 0x002d (0.00548618) | LUT[0013] 0x0068 (0.10166178) -> 0x0036 (0.00654255) + 0x0049003f, // LUT[0014] 0x0070 (0.10948192) -> 0x003f (0.00770111) | LUT[0015] 0x0078 (0.11730205) -> 0x0049 (0.00896339) + 0x00610055, // LUT[0016] 0x0080 (0.12512219) -> 0x0055 (0.01033084) | LUT[0017] 0x0088 (0.13294233) -> 0x0061 (0.01180482) + 0x007b006e, // LUT[0018] 0x0090 (0.14076246) -> 0x006e (0.01338662) | LUT[0019] 0x0098 (0.14858260) -> 0x007b (0.01507751) + 0x009a008a, // LUT[0020] 0x00a0 (0.15640274) -> 0x008a (0.01687864) | LUT[0021] 0x00a8 (0.16422287) -> 0x009a (0.01879118) + 0x00bc00ab, // LUT[0022] 0x00b0 (0.17204301) -> 0x00ab (0.02081620) | LUT[0023] 0x00b8 (0.17986315) -> 0x00bc (0.02295476) + 0x00e200ce, // LUT[0024] 0x00c0 (0.18768328) -> 0x00ce (0.02520788) | LUT[0025] 0x00c8 (0.19550342) -> 0x00e2 (0.02757653) + 0x010c00f6, // LUT[0026] 0x00d0 (0.20332356) -> 0x00f6 (0.03006166) | LUT[0027] 0x00d8 (0.21114370) -> 0x010c (0.03266419) + 0x01390122, // LUT[0028] 0x00e0 (0.21896383) -> 0x0122 (0.03538500) | LUT[0029] 0x00e8 (0.22678397) -> 0x0139 (0.03822497) + 0x016b0151, // LUT[0030] 0x00f0 (0.23460411) -> 0x0151 (0.04118493) | LUT[0031] 0x00f8 (0.24242424) -> 0x016b (0.04426570) + 0x01a00185, // LUT[0032] 0x0100 (0.25024438) -> 0x0185 (0.04746807) | LUT[0033] 0x0108 (0.25806452) -> 0x01a0 (0.05079281) + 0x01da01bc, // LUT[0034] 0x0110 (0.26588465) -> 0x01bc (0.05424069) | LUT[0035] 0x0118 (0.27370479) -> 0x01da (0.05781244) + 0x021701f8, // LUT[0036] 0x0120 (0.28152493) -> 0x01f8 (0.06150878) | LUT[0037] 0x0128 (0.28934506) -> 0x0217 (0.06533041) + 0x02590237, // LUT[0038] 0x0130 (0.29716520) -> 0x0237 (0.06927802) | LUT[0039] 0x0138 (0.30498534) -> 0x0259 (0.07335230) + 0x029f027b, // LUT[0040] 0x0140 (0.31280547) -> 0x027b (0.07755388) | LUT[0041] 0x0148 (0.32062561) -> 0x029f (0.08188344) + 0x02e902c3, // LUT[0042] 0x0150 (0.32844575) -> 0x02c3 (0.08634158) | LUT[0043] 0x0158 (0.33626588) -> 0x02e9 (0.09092895) + 0x0337030f, // LUT[0044] 0x0160 (0.34408602) -> 0x030f (0.09564614) | LUT[0045] 0x0168 (0.35190616) -> 0x0337 (0.10049376) + 0x038a0360, // LUT[0046] 0x0170 (0.35972630) -> 0x0360 (0.10547239) | LUT[0047] 0x0178 (0.36754643) -> 0x038a (0.11058262) + 0x03e103b5, // LUT[0048] 0x0180 (0.37536657) -> 0x03b5 (0.11582500) | LUT[0049] 0x0188 (0.38318671) -> 0x03e1 (0.12120009) + 0x043c040e, // LUT[0050] 0x0190 (0.39100684) -> 0x040e (0.12670845) | LUT[0051] 0x0198 (0.39882698) -> 0x043c (0.13235062) + 0x049c046b, // LUT[0052] 0x01a0 (0.40664712) -> 0x046b (0.13812711) | LUT[0053] 0x01a8 (0.41446725) -> 0x049c (0.14403847) + 0x050004cd, // LUT[0054] 0x01b0 (0.42228739) -> 0x04cd (0.15008519) | LUT[0055] 0x01b8 (0.43010753) -> 0x0500 (0.15626780) + 0x05690534, // LUT[0056] 0x01c0 (0.43792766) -> 0x0534 (0.16258678) | LUT[0057] 0x01c8 (0.44574780) -> 0x0569 (0.16904264) + 0x05d6059f, // LUT[0058] 0x01d0 (0.45356794) -> 0x059f (0.17563585) | LUT[0059] 0x01d8 (0.46138807) -> 0x05d6 (0.18236689) + 0x0647060e, // LUT[0060] 0x01e0 (0.46920821) -> 0x060e (0.18923625) | LUT[0061] 0x01e8 (0.47702835) -> 0x0647 (0.19624437) + 0x06be0682, // LUT[0062] 0x01f0 (0.48484848) -> 0x0682 (0.20339173) | LUT[0063] 0x01f8 (0.49266862) -> 0x06be (0.21067878) + 0x073806fb, // LUT[0064] 0x0200 (0.50048876) -> 0x06fb (0.21810595) | LUT[0065] 0x0208 (0.50830890) -> 0x0738 (0.22567371) + 0x07b80778, // LUT[0066] 0x0210 (0.51612903) -> 0x0778 (0.23338247) | LUT[0067] 0x0218 (0.52394917) -> 0x07b8 (0.24123268) + 0x083c07f9, // LUT[0068] 0x0220 (0.53176931) -> 0x07f9 (0.24922476) | LUT[0069] 0x0228 (0.53958944) -> 0x083c (0.25735913) + 0x08c50880, // LUT[0070] 0x0230 (0.54740958) -> 0x0880 (0.26563620) | LUT[0071] 0x0238 (0.55522972) -> 0x08c5 (0.27405640) + 0x0952090b, // LUT[0072] 0x0240 (0.56304985) -> 0x090b (0.28262012) | LUT[0073] 0x0248 (0.57086999) -> 0x0952 (0.29132776) + 0x09e4099b, // LUT[0074] 0x0250 (0.57869013) -> 0x099b (0.30017973) | LUT[0075] 0x0258 (0.58651026) -> 0x09e4 (0.30917641) + 0x0a7b0a2f, // LUT[0076] 0x0260 (0.59433040) -> 0x0a2f (0.31831821) | LUT[0077] 0x0268 (0.60215054) -> 0x0a7b (0.32760549) + 0x0b170ac9, // LUT[0078] 0x0270 (0.60997067) -> 0x0ac9 (0.33703865) | LUT[0079] 0x0278 (0.61779081) -> 0x0b17 (0.34661805) + 0x0bb80b67, // LUT[0080] 0x0280 (0.62561095) -> 0x0b67 (0.35634408) | LUT[0081] 0x0288 (0.63343109) -> 0x0bb8 (0.36621710) + 0x0c5d0c0a, // LUT[0082] 0x0290 (0.64125122) -> 0x0c0a (0.37623748) | LUT[0083] 0x0298 (0.64907136) -> 0x0c5d (0.38640557) + 0x0d070cb2, // LUT[0084] 0x02a0 (0.65689150) -> 0x0cb2 (0.39672175) | LUT[0085] 0x02a8 (0.66471163) -> 0x0d07 (0.40718635) + 0x0db60d5e, // LUT[0086] 0x02b0 (0.67253177) -> 0x0d5e (0.41779974) | LUT[0087] 0x02b8 (0.68035191) -> 0x0db6 (0.42856227) + 0x0e6a0e10, // LUT[0088] 0x02c0 (0.68817204) -> 0x0e10 (0.43947427) | LUT[0089] 0x02c8 (0.69599218) -> 0x0e6a (0.45053610) + 0x0f230ec6, // LUT[0090] 0x02d0 (0.70381232) -> 0x0ec6 (0.46174808) | LUT[0091] 0x02d8 (0.71163245) -> 0x0f23 (0.47311056) + 0x0fe10f82, // LUT[0092] 0x02e0 (0.71945259) -> 0x0f82 (0.48462387) | LUT[0093] 0x02e8 (0.72727273) -> 0x0fe1 (0.49628833) + 0x10a41042, // LUT[0094] 0x02f0 (0.73509286) -> 0x1042 (0.50810428) | LUT[0095] 0x02f8 (0.74291300) -> 0x10a4 (0.52007204) + 0x116c1107, // LUT[0096] 0x0300 (0.75073314) -> 0x1107 (0.53219194) | LUT[0097] 0x0308 (0.75855327) -> 0x116c (0.54446428) + 0x123911d1, // LUT[0098] 0x0310 (0.76637341) -> 0x11d1 (0.55688939) | LUT[0099] 0x0318 (0.77419355) -> 0x1239 (0.56946758) + 0x130a12a1, // LUT[0100] 0x0320 (0.78201369) -> 0x12a1 (0.58219916) | LUT[0101] 0x0328 (0.78983382) -> 0x130a (0.59508445) + 0x13e11375, // LUT[0102] 0x0330 (0.79765396) -> 0x1375 (0.60812374) | LUT[0103] 0x0338 (0.80547410) -> 0x13e1 (0.62131734) + 0x14bd144f, // LUT[0104] 0x0340 (0.81329423) -> 0x144f (0.63466555) | LUT[0105] 0x0348 (0.82111437) -> 0x14bd (0.64816867) + 0x159e152d, // LUT[0106] 0x0350 (0.82893451) -> 0x152d (0.66182700) | LUT[0107] 0x0358 (0.83675464) -> 0x159e (0.67564083) + 0x16841611, // LUT[0108] 0x0360 (0.84457478) -> 0x1611 (0.68961046) | LUT[0109] 0x0368 (0.85239492) -> 0x1684 (0.70373617) + 0x177016f9, // LUT[0110] 0x0370 (0.86021505) -> 0x16f9 (0.71801825) | LUT[0111] 0x0378 (0.86803519) -> 0x1770 (0.73245699) + 0x186017e7, // LUT[0112] 0x0380 (0.87585533) -> 0x17e7 (0.74705268) | LUT[0113] 0x0388 (0.88367546) -> 0x1860 (0.76180559) + 0x195618da, // LUT[0114] 0x0390 (0.89149560) -> 0x18da (0.77671600) | LUT[0115] 0x0398 (0.89931574) -> 0x1956 (0.79178419) + 0x1a5019d2, // LUT[0116] 0x03a0 (0.90713587) -> 0x19d2 (0.80701044) | LUT[0117] 0x03a8 (0.91495601) -> 0x1a50 (0.82239502) + 0x1b501ad0, // LUT[0118] 0x03b0 (0.92277615) -> 0x1ad0 (0.83793821) | LUT[0119] 0x03b8 (0.93059629) -> 0x1b50 (0.85364027) + 0x1c551bd2, // LUT[0120] 0x03c0 (0.93841642) -> 0x1bd2 (0.86950147) | LUT[0121] 0x03c8 (0.94623656) -> 0x1c55 (0.88552207) + 0x1d601cda, // LUT[0122] 0x03d0 (0.95405670) -> 0x1cda (0.90170236) | LUT[0123] 0x03d8 (0.96187683) -> 0x1d60 (0.91804257) + 0x1e6f1de7, // LUT[0124] 0x03e0 (0.96969697) -> 0x1de7 (0.93454299) | LUT[0125] 0x03e8 (0.97751711) -> 0x1e6f (0.95120386) + 0x1f841ef9, // LUT[0126] 0x03f0 (0.98533724) -> 0x1ef9 (0.96802545) | LUT[0127] 0x03f8 (0.99315738) -> 0x1f84 (0.98500801) + 0x29782011, // LUT[0128] 0x0400 (1.00097752) -> 0x2011 (1.00215180) | LUT[0129] 0x047f (1.12512219) -> 0x2978 (1.29610241) +}; + +#define ADP_CM_ENGAMMA_PAIRED_LUT_COUNT 513 +#define ADP_CM_ENGAMMA_PAIRED_LUT_SIZE (ADP_CM_ENGAMMA_PAIRED_LUT_COUNT - 1) +static const uint32_t target_gp_engamma_tables[ADP_CM_ENGAMMA_PAIRED_LUT_COUNT] = { + 0x002c0000, // LUT[0000] 0x0000 (0.00000000) -> 0x0000 (0.00000000) | LUT[0001] 0x0008 (0.00097668) -> 0x002c (0.04282584) + 0x0048003c, // LUT[0002] 0x0010 (0.00195336) -> 0x003c (0.05868644) | LUT[0003] 0x0018 (0.00293005) -> 0x0048 (0.07056336) + 0x005b0052, // LUT[0004] 0x0020 (0.00390673) -> 0x0052 (0.08042102) | LUT[0005] 0x0028 (0.00488341) -> 0x005b (0.08900606) + 0x006a0063, // LUT[0006] 0x0030 (0.00586009) -> 0x0063 (0.09669657) | LUT[0007] 0x0038 (0.00683677) -> 0x006a (0.10371496) + 0x00770071, // LUT[0008] 0x0040 (0.00781345) -> 0x0071 (0.11020502) | LUT[0009] 0x0048 (0.00879014) -> 0x0077 (0.11626595) + 0x0082007d, // LUT[0010] 0x0050 (0.00976682) -> 0x007d (0.12196954) | LUT[0011] 0x0058 (0.01074350) -> 0x0082 (0.12736974) + 0x008d0088, // LUT[0012] 0x0060 (0.01172018) -> 0x0088 (0.13250823) | LUT[0013] 0x0068 (0.01269686) -> 0x008d (0.13741806) + 0x00960091, // LUT[0014] 0x0070 (0.01367354) -> 0x0091 (0.14212590) | LUT[0015] 0x0078 (0.01465023) -> 0x0096 (0.14665365) + 0x009f009a, // LUT[0016] 0x0080 (0.01562691) -> 0x009a (0.15101956) | LUT[0017] 0x0088 (0.01660359) -> 0x009f (0.15523902) + 0x00a700a3, // LUT[0018] 0x0090 (0.01758027) -> 0x00a3 (0.15932515) | LUT[0019] 0x0098 (0.01855695) -> 0x00a7 (0.16328924) + 0x00af00ab, // LUT[0020] 0x00a0 (0.01953363) -> 0x00ab (0.16714108) | LUT[0021] 0x00a8 (0.02051032) -> 0x00af (0.17088924) + 0x00b600b3, // LUT[0022] 0x00b0 (0.02148700) -> 0x00b3 (0.17454124) | LUT[0023] 0x00b8 (0.02246368) -> 0x00b6 (0.17810378) + 0x00bd00ba, // LUT[0024] 0x00c0 (0.02344036) -> 0x00ba (0.18158279) | LUT[0025] 0x00c8 (0.02441704) -> 0x00bd (0.18498359) + 0x00c400c1, // LUT[0026] 0x00d0 (0.02539372) -> 0x00c1 (0.18831098) | LUT[0027] 0x00d8 (0.02637041) -> 0x00c4 (0.19156926) + 0x00ca00c7, // LUT[0028] 0x00e0 (0.02734709) -> 0x00c7 (0.19476237) | LUT[0029] 0x00e8 (0.02832377) -> 0x00ca (0.19789385) + 0x00d100ce, // LUT[0030] 0x00f0 (0.02930045) -> 0x00ce (0.20096697) | LUT[0031] 0x00f8 (0.03027713) -> 0x00d1 (0.20398471) + 0x00d700d4, // LUT[0032] 0x0100 (0.03125382) -> 0x00d4 (0.20694980) | LUT[0033] 0x0108 (0.03223050) -> 0x00d7 (0.20986477) + 0x00dd00da, // LUT[0034] 0x0110 (0.03320718) -> 0x00da (0.21273195) | LUT[0035] 0x0118 (0.03418386) -> 0x00dd (0.21555348) + 0x00e200df, // LUT[0036] 0x0120 (0.03516054) -> 0x00df (0.21833138) | LUT[0037] 0x0128 (0.03613722) -> 0x00e2 (0.22106750) + 0x00e800e5, // LUT[0038] 0x0130 (0.03711391) -> 0x00e5 (0.22376357) | LUT[0039] 0x0138 (0.03809059) -> 0x00e8 (0.22642122) + 0x00ed00ea, // LUT[0040] 0x0140 (0.03906727) -> 0x00ea (0.22904195) | LUT[0041] 0x0148 (0.04004395) -> 0x00ed (0.23162717) + 0x00f200f0, // LUT[0042] 0x0150 (0.04102063) -> 0x00f0 (0.23417823) | LUT[0043] 0x0158 (0.04199731) -> 0x00f2 (0.23669637) + 0x00f700f5, // LUT[0044] 0x0160 (0.04297400) -> 0x00f5 (0.23918276) | LUT[0045] 0x0168 (0.04395068) -> 0x00f7 (0.24163852) + 0x00fc00fa, // LUT[0046] 0x0170 (0.04492736) -> 0x00fa (0.24406469) | LUT[0047] 0x0178 (0.04590404) -> 0x00fc (0.24646225) + 0x010100ff, // LUT[0048] 0x0180 (0.04688072) -> 0x00ff (0.24883215) | LUT[0049] 0x0188 (0.04785740) -> 0x0101 (0.25117527) + 0x01060103, // LUT[0050] 0x0190 (0.04883409) -> 0x0103 (0.25349245) | LUT[0051] 0x0198 (0.04981077) -> 0x0106 (0.25578449) + 0x010a0108, // LUT[0052] 0x01a0 (0.05078745) -> 0x0108 (0.25805214) | LUT[0053] 0x01a8 (0.05176413) -> 0x010a (0.26029612) + 0x010f010d, // LUT[0054] 0x01b0 (0.05274081) -> 0x010d (0.26251713) | LUT[0055] 0x01b8 (0.05371749) -> 0x010f (0.26471581) + 0x01130111, // LUT[0056] 0x01c0 (0.05469418) -> 0x0111 (0.26689280) | LUT[0057] 0x01c8 (0.05567086) -> 0x0113 (0.26904868) + 0x01180115, // LUT[0058] 0x01d0 (0.05664754) -> 0x0115 (0.27118403) | LUT[0059] 0x01d8 (0.05762422) -> 0x0118 (0.27329939) + 0x011c011a, // LUT[0060] 0x01e0 (0.05860090) -> 0x011a (0.27539529) | LUT[0061] 0x01e8 (0.05957759) -> 0x011c (0.27747221) + 0x0120011e, // LUT[0062] 0x01f0 (0.06055427) -> 0x011e (0.27953065) | LUT[0063] 0x01f8 (0.06153095) -> 0x0120 (0.28157105) + 0x01240122, // LUT[0064] 0x0200 (0.06250763) -> 0x0122 (0.28359387) | LUT[0065] 0x0208 (0.06348431) -> 0x0124 (0.28559951) + 0x01280126, // LUT[0066] 0x0210 (0.06446099) -> 0x0126 (0.28758840) | LUT[0067] 0x0218 (0.06543768) -> 0x0128 (0.28956091) + 0x012c012a, // LUT[0068] 0x0220 (0.06641436) -> 0x012a (0.29151743) | LUT[0069] 0x0228 (0.06739104) -> 0x012c (0.29345832) + 0x0130012e, // LUT[0070] 0x0230 (0.06836772) -> 0x012e (0.29538393) | LUT[0071] 0x0238 (0.06934440) -> 0x0130 (0.29729459) + 0x01340132, // LUT[0072] 0x0240 (0.07032108) -> 0x0132 (0.29919062) | LUT[0073] 0x0248 (0.07129777) -> 0x0134 (0.30107235) + 0x01380136, // LUT[0074] 0x0250 (0.07227445) -> 0x0136 (0.30294007) | LUT[0075] 0x0258 (0.07325113) -> 0x0138 (0.30479407) + 0x013c013a, // LUT[0076] 0x0260 (0.07422781) -> 0x013a (0.30663463) | LUT[0077] 0x0268 (0.07520449) -> 0x013c (0.30846204) + 0x013f013d, // LUT[0078] 0x0270 (0.07618117) -> 0x013d (0.31027654) | LUT[0079] 0x0278 (0.07715786) -> 0x013f (0.31207840) + 0x01430141, // LUT[0080] 0x0280 (0.07813454) -> 0x0141 (0.31386786) | LUT[0081] 0x0288 (0.07911122) -> 0x0143 (0.31564515) + 0x01470145, // LUT[0082] 0x0290 (0.08008790) -> 0x0145 (0.31741053) | LUT[0083] 0x0298 (0.08106458) -> 0x0147 (0.31916419) + 0x014a0148, // LUT[0084] 0x02a0 (0.08204126) -> 0x0148 (0.32090637) | LUT[0085] 0x02a8 (0.08301795) -> 0x014a (0.32263727) + 0x014e014c, // LUT[0086] 0x02b0 (0.08399463) -> 0x014c (0.32435710) | LUT[0087] 0x02b8 (0.08497131) -> 0x014e (0.32606606) + 0x0151014f, // LUT[0088] 0x02c0 (0.08594799) -> 0x014f (0.32776434) | LUT[0089] 0x02c8 (0.08692467) -> 0x0151 (0.32945212) + 0x01540153, // LUT[0090] 0x02d0 (0.08790136) -> 0x0153 (0.33112959) | LUT[0091] 0x02d8 (0.08887804) -> 0x0154 (0.33279692) + 0x01580156, // LUT[0092] 0x02e0 (0.08985472) -> 0x0156 (0.33445429) | LUT[0093] 0x02e8 (0.09083140) -> 0x0158 (0.33610186) + 0x015b015a, // LUT[0094] 0x02f0 (0.09180808) -> 0x015a (0.33773979) | LUT[0095] 0x02f8 (0.09278476) -> 0x015b (0.33936825) + 0x015e015d, // LUT[0096] 0x0300 (0.09376145) -> 0x015d (0.34098739) | LUT[0097] 0x0308 (0.09473813) -> 0x015e (0.34259735) + 0x01620160, // LUT[0098] 0x0310 (0.09571481) -> 0x0160 (0.34419828) | LUT[0099] 0x0318 (0.09669149) -> 0x0162 (0.34579033) + 0x01650163, // LUT[0100] 0x0320 (0.09766817) -> 0x0163 (0.34737363) | LUT[0101] 0x0328 (0.09864485) -> 0x0165 (0.34894832) + 0x01680167, // LUT[0102] 0x0330 (0.09962154) -> 0x0167 (0.35051452) | LUT[0103] 0x0338 (0.10059822) -> 0x0168 (0.35207237) + 0x016b016a, // LUT[0104] 0x0340 (0.10157490) -> 0x016a (0.35362200) | LUT[0105] 0x0348 (0.10255158) -> 0x016b (0.35516352) + 0x016e016d, // LUT[0106] 0x0350 (0.10352826) -> 0x016d (0.35669705) | LUT[0107] 0x0358 (0.10450494) -> 0x016e (0.35822270) + 0x01720170, // LUT[0108] 0x0360 (0.10548163) -> 0x0170 (0.35974061) | LUT[0109] 0x0368 (0.10645831) -> 0x0172 (0.36125086) + 0x01750173, // LUT[0110] 0x0370 (0.10743499) -> 0x0173 (0.36275358) | LUT[0111] 0x0378 (0.10841167) -> 0x0175 (0.36424886) + 0x01780176, // LUT[0112] 0x0380 (0.10938835) -> 0x0176 (0.36573681) | LUT[0113] 0x0388 (0.11036503) -> 0x0178 (0.36721754) + 0x017b0179, // LUT[0114] 0x0390 (0.11134172) -> 0x0179 (0.36869113) | LUT[0115] 0x0398 (0.11231840) -> 0x017b (0.37015769) + 0x017e017c, // LUT[0116] 0x03a0 (0.11329508) -> 0x017c (0.37161731) | LUT[0117] 0x03a8 (0.11427176) -> 0x017e (0.37307008) + 0x0181017f, // LUT[0118] 0x03b0 (0.11524844) -> 0x017f (0.37451609) | LUT[0119] 0x03b8 (0.11622513) -> 0x0181 (0.37595544) + 0x01840182, // LUT[0120] 0x03c0 (0.11720181) -> 0x0182 (0.37738820) | LUT[0121] 0x03c8 (0.11817849) -> 0x0184 (0.37881447) + 0x01860185, // LUT[0122] 0x03d0 (0.11915517) -> 0x0185 (0.38023432) | LUT[0123] 0x03d8 (0.12013185) -> 0x0186 (0.38164784) + 0x01890188, // LUT[0124] 0x03e0 (0.12110853) -> 0x0188 (0.38305510) | LUT[0125] 0x03e8 (0.12208522) -> 0x0189 (0.38445618) + 0x018c018b, // LUT[0126] 0x03f0 (0.12306190) -> 0x018b (0.38585117) | LUT[0127] 0x03f8 (0.12403858) -> 0x018c (0.38724013) + 0x018f018e, // LUT[0128] 0x0400 (0.12501526) -> 0x018e (0.38862313) | LUT[0129] 0x0408 (0.12599194) -> 0x018f (0.39000026) + 0x01920190, // LUT[0130] 0x0410 (0.12696862) -> 0x0190 (0.39137157) | LUT[0131] 0x0418 (0.12794531) -> 0x0192 (0.39273715) + 0x01950193, // LUT[0132] 0x0420 (0.12892199) -> 0x0193 (0.39409704) | LUT[0133] 0x0428 (0.12989867) -> 0x0195 (0.39545134) + 0x01970196, // LUT[0134] 0x0430 (0.13087535) -> 0x0196 (0.39680008) | LUT[0135] 0x0438 (0.13185203) -> 0x0197 (0.39814335) + 0x019a0199, // LUT[0136] 0x0440 (0.13282871) -> 0x0199 (0.39948120) | LUT[0137] 0x0448 (0.13380540) -> 0x019a (0.40081370) + 0x019d019b, // LUT[0138] 0x0450 (0.13478208) -> 0x019b (0.40214090) | LUT[0139] 0x0458 (0.13575876) -> 0x019d (0.40346287) + 0x019f019e, // LUT[0140] 0x0460 (0.13673544) -> 0x019e (0.40477966) | LUT[0141] 0x0468 (0.13771212) -> 0x019f (0.40609133) + 0x01a201a1, // LUT[0142] 0x0470 (0.13868880) -> 0x01a1 (0.40739793) | LUT[0143] 0x0478 (0.13966549) -> 0x01a2 (0.40869953) + 0x01a501a3, // LUT[0144] 0x0480 (0.14064217) -> 0x01a3 (0.40999617) | LUT[0145] 0x0488 (0.14161885) -> 0x01a5 (0.41128790) + 0x01a701a6, // LUT[0146] 0x0490 (0.14259553) -> 0x01a6 (0.41257479) | LUT[0147] 0x0498 (0.14357221) -> 0x01a7 (0.41385688) + 0x01aa01a9, // LUT[0148] 0x04a0 (0.14454890) -> 0x01a9 (0.41513422) | LUT[0149] 0x04a8 (0.14552558) -> 0x01aa (0.41640686) + 0x01ad01ab, // LUT[0150] 0x04b0 (0.14650226) -> 0x01ab (0.41767485) | LUT[0151] 0x04b8 (0.14747894) -> 0x01ad (0.41893824) + 0x01af01ae, // LUT[0152] 0x04c0 (0.14845562) -> 0x01ae (0.42019707) | LUT[0153] 0x04c8 (0.14943230) -> 0x01af (0.42145140) + 0x01b201b0, // LUT[0154] 0x04d0 (0.15040899) -> 0x01b0 (0.42270125) | LUT[0155] 0x04d8 (0.15138567) -> 0x01b2 (0.42394670) + 0x01b401b3, // LUT[0156] 0x04e0 (0.15236235) -> 0x01b3 (0.42518776) | LUT[0157] 0x04e8 (0.15333903) -> 0x01b4 (0.42642449) + 0x01b701b5, // LUT[0158] 0x04f0 (0.15431571) -> 0x01b5 (0.42765694) | LUT[0159] 0x04f8 (0.15529239) -> 0x01b7 (0.42888513) + 0x01b901b8, // LUT[0160] 0x0500 (0.15626908) -> 0x01b8 (0.43010912) | LUT[0161] 0x0508 (0.15724576) -> 0x01b9 (0.43132895) + 0x01bc01ba, // LUT[0162] 0x0510 (0.15822244) -> 0x01ba (0.43254465) | LUT[0163] 0x0518 (0.15919912) -> 0x01bc (0.43375626) + 0x01be01bd, // LUT[0164] 0x0520 (0.16017580) -> 0x01bd (0.43496383) | LUT[0165] 0x0528 (0.16115248) -> 0x01be (0.43616738) + 0x01c101bf, // LUT[0166] 0x0530 (0.16212917) -> 0x01bf (0.43736696) | LUT[0167] 0x0538 (0.16310585) -> 0x01c1 (0.43856261) + 0x01c301c2, // LUT[0168] 0x0540 (0.16408253) -> 0x01c2 (0.43975436) | LUT[0169] 0x0548 (0.16505921) -> 0x01c3 (0.44094225) + 0x01c601c4, // LUT[0170] 0x0550 (0.16603589) -> 0x01c4 (0.44212631) | LUT[0171] 0x0558 (0.16701257) -> 0x01c6 (0.44330657) + 0x01c801c7, // LUT[0172] 0x0560 (0.16798926) -> 0x01c7 (0.44448308) | LUT[0173] 0x0568 (0.16896594) -> 0x01c8 (0.44565586) + 0x01ca01c9, // LUT[0174] 0x0570 (0.16994262) -> 0x01c9 (0.44682495) | LUT[0175] 0x0578 (0.17091930) -> 0x01ca (0.44799038) + 0x01cd01cb, // LUT[0176] 0x0580 (0.17189598) -> 0x01cb (0.44915218) | LUT[0177] 0x0588 (0.17287267) -> 0x01cd (0.45031039) + 0x01cf01ce, // LUT[0178] 0x0590 (0.17384935) -> 0x01ce (0.45146503) | LUT[0179] 0x0598 (0.17482603) -> 0x01cf (0.45261615) + 0x01d101d0, // LUT[0180] 0x05a0 (0.17580271) -> 0x01d0 (0.45376375) | LUT[0181] 0x05a8 (0.17677939) -> 0x01d1 (0.45490789) + 0x01d401d3, // LUT[0182] 0x05b0 (0.17775607) -> 0x01d3 (0.45604859) | LUT[0183] 0x05b8 (0.17873276) -> 0x01d4 (0.45718587) + 0x01d601d5, // LUT[0184] 0x05c0 (0.17970944) -> 0x01d5 (0.45831976) | LUT[0185] 0x05c8 (0.18068612) -> 0x01d6 (0.45945030) + 0x01d801d7, // LUT[0186] 0x05d0 (0.18166280) -> 0x01d7 (0.46057751) | LUT[0187] 0x05d8 (0.18263948) -> 0x01d8 (0.46170142) + 0x01db01d9, // LUT[0188] 0x05e0 (0.18361616) -> 0x01d9 (0.46282206) | LUT[0189] 0x05e8 (0.18459285) -> 0x01db (0.46393945) + 0x01dd01dc, // LUT[0190] 0x05f0 (0.18556953) -> 0x01dc (0.46505362) | LUT[0191] 0x05f8 (0.18654621) -> 0x01dd (0.46616459) + 0x01df01de, // LUT[0192] 0x0600 (0.18752289) -> 0x01de (0.46727240) | LUT[0193] 0x0608 (0.18849957) -> 0x01df (0.46837707) + 0x01e101e0, // LUT[0194] 0x0610 (0.18947625) -> 0x01e0 (0.46947861) | LUT[0195] 0x0618 (0.19045294) -> 0x01e1 (0.47057707) + 0x01e401e3, // LUT[0196] 0x0620 (0.19142962) -> 0x01e3 (0.47167245) | LUT[0197] 0x0628 (0.19240630) -> 0x01e4 (0.47276480) + 0x01e601e5, // LUT[0198] 0x0630 (0.19338298) -> 0x01e5 (0.47385412) | LUT[0199] 0x0638 (0.19435966) -> 0x01e6 (0.47494044) + 0x01e801e7, // LUT[0200] 0x0640 (0.19533634) -> 0x01e7 (0.47602379) | LUT[0201] 0x0648 (0.19631303) -> 0x01e8 (0.47710420) + 0x01ea01e9, // LUT[0202] 0x0650 (0.19728971) -> 0x01e9 (0.47818167) | LUT[0203] 0x0658 (0.19826639) -> 0x01ea (0.47925624) + 0x01ec01eb, // LUT[0204] 0x0660 (0.19924307) -> 0x01eb (0.48032792) | LUT[0205] 0x0668 (0.20021975) -> 0x01ec (0.48139674) + 0x01ef01ee, // LUT[0206] 0x0670 (0.20119644) -> 0x01ee (0.48246272) | LUT[0207] 0x0678 (0.20217312) -> 0x01ef (0.48352589) + 0x01f101f0, // LUT[0208] 0x0680 (0.20314980) -> 0x01f0 (0.48458625) | LUT[0209] 0x0688 (0.20412648) -> 0x01f1 (0.48564384) + 0x01f301f2, // LUT[0210] 0x0690 (0.20510316) -> 0x01f2 (0.48669867) | LUT[0211] 0x0698 (0.20607984) -> 0x01f3 (0.48775077) + 0x01f501f4, // LUT[0212] 0x06a0 (0.20705653) -> 0x01f4 (0.48880015) | LUT[0213] 0x06a8 (0.20803321) -> 0x01f5 (0.48984683) + 0x01f701f6, // LUT[0214] 0x06b0 (0.20900989) -> 0x01f6 (0.49089084) | LUT[0215] 0x06b8 (0.20998657) -> 0x01f7 (0.49193218) + 0x01f901f8, // LUT[0216] 0x06c0 (0.21096325) -> 0x01f8 (0.49297089) | LUT[0217] 0x06c8 (0.21193993) -> 0x01f9 (0.49400698) + 0x01fb01fa, // LUT[0218] 0x06d0 (0.21291662) -> 0x01fa (0.49504047) | LUT[0219] 0x06d8 (0.21389330) -> 0x01fb (0.49607138) + 0x01fe01fd, // LUT[0220] 0x06e0 (0.21486998) -> 0x01fd (0.49709972) | LUT[0221] 0x06e8 (0.21584666) -> 0x01fe (0.49812552) + 0x020001ff, // LUT[0222] 0x06f0 (0.21682334) -> 0x01ff (0.49914878) | LUT[0223] 0x06f8 (0.21780002) -> 0x0200 (0.50016954) + 0x02020201, // LUT[0224] 0x0700 (0.21877671) -> 0x0201 (0.50118780) | LUT[0225] 0x0708 (0.21975339) -> 0x0202 (0.50220359) + 0x02040203, // LUT[0226] 0x0710 (0.22073007) -> 0x0203 (0.50321691) | LUT[0227] 0x0718 (0.22170675) -> 0x0204 (0.50422779) + 0x02060205, // LUT[0228] 0x0720 (0.22268343) -> 0x0205 (0.50523625) | LUT[0229] 0x0728 (0.22366011) -> 0x0206 (0.50624230) + 0x02080207, // LUT[0230] 0x0730 (0.22463680) -> 0x0207 (0.50724595) | LUT[0231] 0x0738 (0.22561348) -> 0x0208 (0.50824723) + 0x020a0209, // LUT[0232] 0x0740 (0.22659016) -> 0x0209 (0.50924614) | LUT[0233] 0x0748 (0.22756684) -> 0x020a (0.51024271) + 0x020c020b, // LUT[0234] 0x0750 (0.22854352) -> 0x020b (0.51123695) | LUT[0235] 0x0758 (0.22952021) -> 0x020c (0.51222887) + 0x020e020d, // LUT[0236] 0x0760 (0.23049689) -> 0x020d (0.51321850) | LUT[0237] 0x0768 (0.23147357) -> 0x020e (0.51420584) + 0x0210020f, // LUT[0238] 0x0770 (0.23245025) -> 0x020f (0.51519091) | LUT[0239] 0x0778 (0.23342693) -> 0x0210 (0.51617372) + 0x02120211, // LUT[0240] 0x0780 (0.23440361) -> 0x0211 (0.51715430) | LUT[0241] 0x0788 (0.23538030) -> 0x0212 (0.51813265) + 0x02140213, // LUT[0242] 0x0790 (0.23635698) -> 0x0213 (0.51910878) | LUT[0243] 0x0798 (0.23733366) -> 0x0214 (0.52008272) + 0x02160215, // LUT[0244] 0x07a0 (0.23831034) -> 0x0215 (0.52105448) | LUT[0245] 0x07a8 (0.23928702) -> 0x0216 (0.52202406) + 0x02180217, // LUT[0246] 0x07b0 (0.24026370) -> 0x0217 (0.52299149) | LUT[0247] 0x07b8 (0.24124039) -> 0x0218 (0.52395678) + 0x021a0219, // LUT[0248] 0x07c0 (0.24221707) -> 0x0219 (0.52491993) | LUT[0249] 0x07c8 (0.24319375) -> 0x021a (0.52588097) + 0x021c021b, // LUT[0250] 0x07d0 (0.24417043) -> 0x021b (0.52683991) | LUT[0251] 0x07d8 (0.24514711) -> 0x021c (0.52779676) + 0x021e021d, // LUT[0252] 0x07e0 (0.24612379) -> 0x021d (0.52875153) | LUT[0253] 0x07e8 (0.24710048) -> 0x021e (0.52970424) + 0x0220021f, // LUT[0254] 0x07f0 (0.24807716) -> 0x021f (0.53065489) | LUT[0255] 0x07f8 (0.24905384) -> 0x0220 (0.53160351) + 0x02220221, // LUT[0256] 0x0800 (0.25003052) -> 0x0221 (0.53255010) | LUT[0257] 0x0808 (0.25100720) -> 0x0222 (0.53349467) + 0x02240223, // LUT[0258] 0x0810 (0.25198388) -> 0x0223 (0.53443724) | LUT[0259] 0x0818 (0.25296057) -> 0x0224 (0.53537782) + 0x02260225, // LUT[0260] 0x0820 (0.25393725) -> 0x0225 (0.53631642) | LUT[0261] 0x0828 (0.25491393) -> 0x0226 (0.53725306) + 0x02280227, // LUT[0262] 0x0830 (0.25589061) -> 0x0227 (0.53818774) | LUT[0263] 0x0838 (0.25686729) -> 0x0228 (0.53912047) + 0x02290228, // LUT[0264] 0x0840 (0.25784398) -> 0x0228 (0.54005127) | LUT[0265] 0x0848 (0.25882066) -> 0x0229 (0.54098016) + 0x022b022a, // LUT[0266] 0x0850 (0.25979734) -> 0x022a (0.54190713) | LUT[0267] 0x0858 (0.26077402) -> 0x022b (0.54283220) + 0x022d022c, // LUT[0268] 0x0860 (0.26175070) -> 0x022c (0.54375538) | LUT[0269] 0x0868 (0.26272738) -> 0x022d (0.54467669) + 0x022f022e, // LUT[0270] 0x0870 (0.26370407) -> 0x022e (0.54559613) | LUT[0271] 0x0878 (0.26468075) -> 0x022f (0.54651372) + 0x02310230, // LUT[0272] 0x0880 (0.26565743) -> 0x0230 (0.54742946) | LUT[0273] 0x0888 (0.26663411) -> 0x0231 (0.54834337) + 0x02330232, // LUT[0274] 0x0890 (0.26761079) -> 0x0232 (0.54925545) | LUT[0275] 0x0898 (0.26858747) -> 0x0233 (0.55016572) + 0x02350234, // LUT[0276] 0x08a0 (0.26956416) -> 0x0234 (0.55107418) | LUT[0277] 0x08a8 (0.27054084) -> 0x0235 (0.55198085) + 0x02370236, // LUT[0278] 0x08b0 (0.27151752) -> 0x0236 (0.55288574) | LUT[0279] 0x08b8 (0.27249420) -> 0x0237 (0.55378885) + 0x02380237, // LUT[0280] 0x08c0 (0.27347088) -> 0x0237 (0.55469020) | LUT[0281] 0x08c8 (0.27444756) -> 0x0238 (0.55558980) + 0x023a0239, // LUT[0282] 0x08d0 (0.27542425) -> 0x0239 (0.55648765) | LUT[0283] 0x08d8 (0.27640093) -> 0x023a (0.55738377) + 0x023c023b, // LUT[0284] 0x08e0 (0.27737761) -> 0x023b (0.55827816) | LUT[0285] 0x08e8 (0.27835429) -> 0x023c (0.55917083) + 0x023e023d, // LUT[0286] 0x08f0 (0.27933097) -> 0x023d (0.56006180) | LUT[0287] 0x08f8 (0.28030765) -> 0x023e (0.56095107) + 0x0240023f, // LUT[0288] 0x0900 (0.28128434) -> 0x023f (0.56183865) | LUT[0289] 0x0908 (0.28226102) -> 0x0240 (0.56272455) + 0x02410241, // LUT[0290] 0x0910 (0.28323770) -> 0x0241 (0.56360879) | LUT[0291] 0x0918 (0.28421438) -> 0x0241 (0.56449136) + 0x02430242, // LUT[0292] 0x0920 (0.28519106) -> 0x0242 (0.56537227) | LUT[0293] 0x0928 (0.28616775) -> 0x0243 (0.56625155) + 0x02450244, // LUT[0294] 0x0930 (0.28714443) -> 0x0244 (0.56712918) | LUT[0295] 0x0938 (0.28812111) -> 0x0245 (0.56800519) + 0x02470246, // LUT[0296] 0x0940 (0.28909779) -> 0x0246 (0.56887959) | LUT[0297] 0x0948 (0.29007447) -> 0x0247 (0.56975237) + 0x02490248, // LUT[0298] 0x0950 (0.29105115) -> 0x0248 (0.57062355) | LUT[0299] 0x0958 (0.29202784) -> 0x0249 (0.57149314) + 0x024a024a, // LUT[0300] 0x0960 (0.29300452) -> 0x024a (0.57236114) | LUT[0301] 0x0968 (0.29398120) -> 0x024a (0.57322757) + 0x024c024b, // LUT[0302] 0x0970 (0.29495788) -> 0x024b (0.57409243) | LUT[0303] 0x0978 (0.29593456) -> 0x024c (0.57495573) + 0x024e024d, // LUT[0304] 0x0980 (0.29691124) -> 0x024d (0.57581747) | LUT[0305] 0x0988 (0.29788793) -> 0x024e (0.57667767) + 0x0250024f, // LUT[0306] 0x0990 (0.29886461) -> 0x024f (0.57753633) | LUT[0307] 0x0998 (0.29984129) -> 0x0250 (0.57839347) + 0x02510251, // LUT[0308] 0x09a0 (0.30081797) -> 0x0251 (0.57924908) | LUT[0309] 0x09a8 (0.30179465) -> 0x0251 (0.58010318) + 0x02530252, // LUT[0310] 0x09b0 (0.30277133) -> 0x0252 (0.58095577) | LUT[0311] 0x09b8 (0.30374802) -> 0x0253 (0.58180686) + 0x02550254, // LUT[0312] 0x09c0 (0.30472470) -> 0x0254 (0.58265647) | LUT[0313] 0x09c8 (0.30570138) -> 0x0255 (0.58350458) + 0x02570256, // LUT[0314] 0x09d0 (0.30667806) -> 0x0256 (0.58435122) | LUT[0315] 0x09d8 (0.30765474) -> 0x0257 (0.58519640) + 0x02580258, // LUT[0316] 0x09e0 (0.30863142) -> 0x0258 (0.58604011) | LUT[0317] 0x09e8 (0.30960811) -> 0x0258 (0.58688236) + 0x025a0259, // LUT[0318] 0x09f0 (0.31058479) -> 0x0259 (0.58772317) | LUT[0319] 0x09f8 (0.31156147) -> 0x025a (0.58856253) + 0x025c025b, // LUT[0320] 0x0a00 (0.31253815) -> 0x025b (0.58940046) | LUT[0321] 0x0a08 (0.31351483) -> 0x025c (0.59023697) + 0x025e025d, // LUT[0322] 0x0a10 (0.31449152) -> 0x025d (0.59107205) | LUT[0323] 0x0a18 (0.31546820) -> 0x025e (0.59190572) + 0x025f025e, // LUT[0324] 0x0a20 (0.31644488) -> 0x025e (0.59273799) | LUT[0325] 0x0a28 (0.31742156) -> 0x025f (0.59356885) + 0x02610260, // LUT[0326] 0x0a30 (0.31839824) -> 0x0260 (0.59439832) | LUT[0327] 0x0a38 (0.31937492) -> 0x0261 (0.59522640) + 0x02630262, // LUT[0328] 0x0a40 (0.32035161) -> 0x0262 (0.59605311) | LUT[0329] 0x0a48 (0.32132829) -> 0x0263 (0.59687844) + 0x02640263, // LUT[0330] 0x0a50 (0.32230497) -> 0x0263 (0.59770240) | LUT[0331] 0x0a58 (0.32328165) -> 0x0264 (0.59852500) + 0x02660265, // LUT[0332] 0x0a60 (0.32425833) -> 0x0265 (0.59934625) | LUT[0333] 0x0a68 (0.32523501) -> 0x0266 (0.60016615) + 0x02680267, // LUT[0334] 0x0a70 (0.32621170) -> 0x0267 (0.60098471) | LUT[0335] 0x0a78 (0.32718838) -> 0x0268 (0.60180193) + 0x02690268, // LUT[0336] 0x0a80 (0.32816506) -> 0x0268 (0.60261782) | LUT[0337] 0x0a88 (0.32914174) -> 0x0269 (0.60343239) + 0x026b026a, // LUT[0338] 0x0a90 (0.33011842) -> 0x026a (0.60424564) | LUT[0339] 0x0a98 (0.33109510) -> 0x026b (0.60505758) + 0x026d026c, // LUT[0340] 0x0aa0 (0.33207179) -> 0x026c (0.60586822) | LUT[0341] 0x0aa8 (0.33304847) -> 0x026d (0.60667755) + 0x026e026d, // LUT[0342] 0x0ab0 (0.33402515) -> 0x026d (0.60748560) | LUT[0343] 0x0ab8 (0.33500183) -> 0x026e (0.60829235) + 0x0270026f, // LUT[0344] 0x0ac0 (0.33597851) -> 0x026f (0.60909782) | LUT[0345] 0x0ac8 (0.33695519) -> 0x0270 (0.60990202) + 0x02720271, // LUT[0346] 0x0ad0 (0.33793188) -> 0x0271 (0.61070494) | LUT[0347] 0x0ad8 (0.33890856) -> 0x0272 (0.61150661) + 0x02730272, // LUT[0348] 0x0ae0 (0.33988524) -> 0x0272 (0.61230701) | LUT[0349] 0x0ae8 (0.34086192) -> 0x0273 (0.61310616) + 0x02750274, // LUT[0350] 0x0af0 (0.34183860) -> 0x0274 (0.61390406) | LUT[0351] 0x0af8 (0.34281529) -> 0x0275 (0.61470071) + 0x02760276, // LUT[0352] 0x0b00 (0.34379197) -> 0x0276 (0.61549613) | LUT[0353] 0x0b08 (0.34476865) -> 0x0276 (0.61629032) + 0x02780277, // LUT[0354] 0x0b10 (0.34574533) -> 0x0277 (0.61708329) | LUT[0355] 0x0b18 (0.34672201) -> 0x0278 (0.61787503) + 0x027a0279, // LUT[0356] 0x0b20 (0.34769869) -> 0x0279 (0.61866555) | LUT[0357] 0x0b28 (0.34867538) -> 0x027a (0.61945487) + 0x027b027b, // LUT[0358] 0x0b30 (0.34965206) -> 0x027b (0.62024298) | LUT[0359] 0x0b38 (0.35062874) -> 0x027b (0.62102989) + 0x027d027c, // LUT[0360] 0x0b40 (0.35160542) -> 0x027c (0.62181561) | LUT[0361] 0x0b48 (0.35258210) -> 0x027d (0.62260013) + 0x027f027e, // LUT[0362] 0x0b50 (0.35355878) -> 0x027e (0.62338348) | LUT[0363] 0x0b58 (0.35453547) -> 0x027f (0.62416564) + 0x0280027f, // LUT[0364] 0x0b60 (0.35551215) -> 0x027f (0.62494663) | LUT[0365] 0x0b68 (0.35648883) -> 0x0280 (0.62572645) + 0x02820281, // LUT[0366] 0x0b70 (0.35746551) -> 0x0281 (0.62650510) | LUT[0367] 0x0b78 (0.35844219) -> 0x0282 (0.62728260) + 0x02830283, // LUT[0368] 0x0b80 (0.35941887) -> 0x0283 (0.62805894) | LUT[0369] 0x0b88 (0.36039556) -> 0x0283 (0.62883413) + 0x02850284, // LUT[0370] 0x0b90 (0.36137224) -> 0x0284 (0.62960817) | LUT[0371] 0x0b98 (0.36234892) -> 0x0285 (0.63038108) + 0x02860286, // LUT[0372] 0x0ba0 (0.36332560) -> 0x0286 (0.63115285) | LUT[0373] 0x0ba8 (0.36430228) -> 0x0286 (0.63192349) + 0x02880287, // LUT[0374] 0x0bb0 (0.36527896) -> 0x0287 (0.63269300) | LUT[0375] 0x0bb8 (0.36625565) -> 0x0288 (0.63346139) + 0x028a0289, // LUT[0376] 0x0bc0 (0.36723233) -> 0x0289 (0.63422866) | LUT[0377] 0x0bc8 (0.36820901) -> 0x028a (0.63499483) + 0x028b028a, // LUT[0378] 0x0bd0 (0.36918569) -> 0x028a (0.63575988) | LUT[0379] 0x0bd8 (0.37016237) -> 0x028b (0.63652383) + 0x028d028c, // LUT[0380] 0x0be0 (0.37113906) -> 0x028c (0.63728668) | LUT[0381] 0x0be8 (0.37211574) -> 0x028d (0.63804844) + 0x028e028e, // LUT[0382] 0x0bf0 (0.37309242) -> 0x028e (0.63880911) | LUT[0383] 0x0bf8 (0.37406910) -> 0x028e (0.63956869) + 0x0290028f, // LUT[0384] 0x0c00 (0.37504578) -> 0x028f (0.64032720) | LUT[0385] 0x0c08 (0.37602246) -> 0x0290 (0.64108462) + 0x02910291, // LUT[0386] 0x0c10 (0.37699915) -> 0x0291 (0.64184098) | LUT[0387] 0x0c18 (0.37797583) -> 0x0291 (0.64259626) + 0x02930292, // LUT[0388] 0x0c20 (0.37895251) -> 0x0292 (0.64335048) | LUT[0389] 0x0c28 (0.37992919) -> 0x0293 (0.64410364) + 0x02940294, // LUT[0390] 0x0c30 (0.38090587) -> 0x0294 (0.64485575) | LUT[0391] 0x0c38 (0.38188255) -> 0x0294 (0.64560680) + 0x02960295, // LUT[0392] 0x0c40 (0.38285924) -> 0x0295 (0.64635681) | LUT[0393] 0x0c48 (0.38383592) -> 0x0296 (0.64710578) + 0x02980297, // LUT[0394] 0x0c50 (0.38481260) -> 0x0297 (0.64785370) | LUT[0395] 0x0c58 (0.38578928) -> 0x0298 (0.64860060) + 0x02990298, // LUT[0396] 0x0c60 (0.38676596) -> 0x0298 (0.64934646) | LUT[0397] 0x0c68 (0.38774264) -> 0x0299 (0.65009129) + 0x029b029a, // LUT[0398] 0x0c70 (0.38871933) -> 0x029a (0.65083510) | LUT[0399] 0x0c78 (0.38969601) -> 0x029b (0.65157790) + 0x029c029b, // LUT[0400] 0x0c80 (0.39067269) -> 0x029b (0.65231968) | LUT[0401] 0x0c88 (0.39164937) -> 0x029c (0.65306044) + 0x029e029d, // LUT[0402] 0x0c90 (0.39262605) -> 0x029d (0.65380020) | LUT[0403] 0x0c98 (0.39360273) -> 0x029e (0.65453896) + 0x029f029e, // LUT[0404] 0x0ca0 (0.39457942) -> 0x029e (0.65527672) | LUT[0405] 0x0ca8 (0.39555610) -> 0x029f (0.65601348) + 0x02a102a0, // LUT[0406] 0x0cb0 (0.39653278) -> 0x02a0 (0.65674925) | LUT[0407] 0x0cb8 (0.39750946) -> 0x02a1 (0.65748404) + 0x02a202a1, // LUT[0408] 0x0cc0 (0.39848614) -> 0x02a1 (0.65821784) | LUT[0409] 0x0cc8 (0.39946283) -> 0x02a2 (0.65895066) + 0x02a402a3, // LUT[0410] 0x0cd0 (0.40043951) -> 0x02a3 (0.65968250) | LUT[0411] 0x0cd8 (0.40141619) -> 0x02a4 (0.66041337) + 0x02a502a4, // LUT[0412] 0x0ce0 (0.40239287) -> 0x02a4 (0.66114327) | LUT[0413] 0x0ce8 (0.40336955) -> 0x02a5 (0.66187220) + 0x02a702a6, // LUT[0414] 0x0cf0 (0.40434623) -> 0x02a6 (0.66260018) | LUT[0415] 0x0cf8 (0.40532292) -> 0x02a7 (0.66332719) + 0x02a802a7, // LUT[0416] 0x0d00 (0.40629960) -> 0x02a7 (0.66405325) | LUT[0417] 0x0d08 (0.40727628) -> 0x02a8 (0.66477836) + 0x02aa02a9, // LUT[0418] 0x0d10 (0.40825296) -> 0x02a9 (0.66550252) | LUT[0419] 0x0d18 (0.40922964) -> 0x02aa (0.66622573) + 0x02ab02aa, // LUT[0420] 0x0d20 (0.41020632) -> 0x02aa (0.66694801) | LUT[0421] 0x0d28 (0.41118301) -> 0x02ab (0.66766934) + 0x02ac02ac, // LUT[0422] 0x0d30 (0.41215969) -> 0x02ac (0.66838975) | LUT[0423] 0x0d38 (0.41313637) -> 0x02ac (0.66910922) + 0x02ae02ad, // LUT[0424] 0x0d40 (0.41411305) -> 0x02ad (0.66982776) | LUT[0425] 0x0d48 (0.41508973) -> 0x02ae (0.67054538) + 0x02af02af, // LUT[0426] 0x0d50 (0.41606641) -> 0x02af (0.67126209) | LUT[0427] 0x0d58 (0.41704310) -> 0x02af (0.67197787) + 0x02b102b0, // LUT[0428] 0x0d60 (0.41801978) -> 0x02b0 (0.67269274) | LUT[0429] 0x0d68 (0.41899646) -> 0x02b1 (0.67340670) + 0x02b202b2, // LUT[0430] 0x0d70 (0.41997314) -> 0x02b2 (0.67411975) | LUT[0431] 0x0d78 (0.42094982) -> 0x02b2 (0.67483190) + 0x02b402b3, // LUT[0432] 0x0d80 (0.42192650) -> 0x02b3 (0.67554315) | LUT[0433] 0x0d88 (0.42290319) -> 0x02b4 (0.67625350) + 0x02b502b5, // LUT[0434] 0x0d90 (0.42387987) -> 0x02b5 (0.67696296) | LUT[0435] 0x0d98 (0.42485655) -> 0x02b5 (0.67767152) + 0x02b702b6, // LUT[0436] 0x0da0 (0.42583323) -> 0x02b6 (0.67837920) | LUT[0437] 0x0da8 (0.42680991) -> 0x02b7 (0.67908599) + 0x02b802b7, // LUT[0438] 0x0db0 (0.42778660) -> 0x02b7 (0.67979190) | LUT[0439] 0x0db8 (0.42876328) -> 0x02b8 (0.68049693) + 0x02ba02b9, // LUT[0440] 0x0dc0 (0.42973996) -> 0x02b9 (0.68120109) | LUT[0441] 0x0dc8 (0.43071664) -> 0x02ba (0.68190438) + 0x02bb02ba, // LUT[0442] 0x0dd0 (0.43169332) -> 0x02ba (0.68260679) | LUT[0443] 0x0dd8 (0.43267000) -> 0x02bb (0.68330834) + 0x02bc02bc, // LUT[0444] 0x0de0 (0.43364669) -> 0x02bc (0.68400903) | LUT[0445] 0x0de8 (0.43462337) -> 0x02bc (0.68470885) + 0x02be02bd, // LUT[0446] 0x0df0 (0.43560005) -> 0x02bd (0.68540782) | LUT[0447] 0x0df8 (0.43657673) -> 0x02be (0.68610593) + 0x02bf02bf, // LUT[0448] 0x0e00 (0.43755341) -> 0x02bf (0.68680320) | LUT[0449] 0x0e08 (0.43853009) -> 0x02bf (0.68749961) + 0x02c102c0, // LUT[0450] 0x0e10 (0.43950678) -> 0x02c0 (0.68819518) | LUT[0451] 0x0e18 (0.44048346) -> 0x02c1 (0.68888990) + 0x02c202c1, // LUT[0452] 0x0e20 (0.44146014) -> 0x02c1 (0.68958379) | LUT[0453] 0x0e28 (0.44243682) -> 0x02c2 (0.69027684) + 0x02c402c3, // LUT[0454] 0x0e30 (0.44341350) -> 0x02c3 (0.69096905) | LUT[0455] 0x0e38 (0.44439018) -> 0x02c4 (0.69166044) + 0x02c502c4, // LUT[0456] 0x0e40 (0.44536687) -> 0x02c4 (0.69235099) | LUT[0457] 0x0e48 (0.44634355) -> 0x02c5 (0.69304072) + 0x02c602c6, // LUT[0458] 0x0e50 (0.44732023) -> 0x02c6 (0.69372963) | LUT[0459] 0x0e58 (0.44829691) -> 0x02c6 (0.69441772) + 0x02c802c7, // LUT[0460] 0x0e60 (0.44927359) -> 0x02c7 (0.69510499) | LUT[0461] 0x0e68 (0.45025027) -> 0x02c8 (0.69579145) + 0x02c902c8, // LUT[0462] 0x0e70 (0.45122696) -> 0x02c8 (0.69647709) | LUT[0463] 0x0e78 (0.45220364) -> 0x02c9 (0.69716192) + 0x02cb02ca, // LUT[0464] 0x0e80 (0.45318032) -> 0x02ca (0.69784595) | LUT[0465] 0x0e88 (0.45415700) -> 0x02cb (0.69852918) + 0x02cc02cb, // LUT[0466] 0x0e90 (0.45513368) -> 0x02cb (0.69921160) | LUT[0467] 0x0e98 (0.45611037) -> 0x02cc (0.69989323) + 0x02cd02cd, // LUT[0468] 0x0ea0 (0.45708705) -> 0x02cd (0.70057406) | LUT[0469] 0x0ea8 (0.45806373) -> 0x02cd (0.70125410) + 0x02cf02ce, // LUT[0470] 0x0eb0 (0.45904041) -> 0x02ce (0.70193334) | LUT[0471] 0x0eb8 (0.46001709) -> 0x02cf (0.70261180) + 0x02d002cf, // LUT[0472] 0x0ec0 (0.46099377) -> 0x02cf (0.70328947) | LUT[0473] 0x0ec8 (0.46197046) -> 0x02d0 (0.70396637) + 0x02d202d1, // LUT[0474] 0x0ed0 (0.46294714) -> 0x02d1 (0.70464248) | LUT[0475] 0x0ed8 (0.46392382) -> 0x02d2 (0.70531781) + 0x02d302d2, // LUT[0476] 0x0ee0 (0.46490050) -> 0x02d2 (0.70599237) | LUT[0477] 0x0ee8 (0.46587718) -> 0x02d3 (0.70666615) + 0x02d402d4, // LUT[0478] 0x0ef0 (0.46685386) -> 0x02d4 (0.70733917) | LUT[0479] 0x0ef8 (0.46783055) -> 0x02d4 (0.70801142) + 0x02d602d5, // LUT[0480] 0x0f00 (0.46880723) -> 0x02d5 (0.70868290) | LUT[0481] 0x0f08 (0.46978391) -> 0x02d6 (0.70935362) + 0x02d702d6, // LUT[0482] 0x0f10 (0.47076059) -> 0x02d6 (0.71002358) | LUT[0483] 0x0f18 (0.47173727) -> 0x02d7 (0.71069278) + 0x02d802d8, // LUT[0484] 0x0f20 (0.47271395) -> 0x02d8 (0.71136123) | LUT[0485] 0x0f28 (0.47369064) -> 0x02d8 (0.71202892) + 0x02da02d9, // LUT[0486] 0x0f30 (0.47466732) -> 0x02d9 (0.71269587) | LUT[0487] 0x0f38 (0.47564400) -> 0x02da (0.71336206) + 0x02db02da, // LUT[0488] 0x0f40 (0.47662068) -> 0x02da (0.71402751) | LUT[0489] 0x0f48 (0.47759736) -> 0x02db (0.71469222) + 0x02dc02dc, // LUT[0490] 0x0f50 (0.47857404) -> 0x02dc (0.71535619) | LUT[0491] 0x0f58 (0.47955073) -> 0x02dc (0.71601941) + 0x02de02dd, // LUT[0492] 0x0f60 (0.48052741) -> 0x02dd (0.71668190) | LUT[0493] 0x0f68 (0.48150409) -> 0x02de (0.71734366) + 0x02df02df, // LUT[0494] 0x0f70 (0.48248077) -> 0x02df (0.71800468) | LUT[0495] 0x0f78 (0.48345745) -> 0x02df (0.71866498) + 0x02e102e0, // LUT[0496] 0x0f80 (0.48443414) -> 0x02e0 (0.71932455) | LUT[0497] 0x0f88 (0.48541082) -> 0x02e1 (0.71998339) + 0x02e202e1, // LUT[0498] 0x0f90 (0.48638750) -> 0x02e1 (0.72064151) | LUT[0499] 0x0f98 (0.48736418) -> 0x02e2 (0.72129891) + 0x02e302e3, // LUT[0500] 0x0fa0 (0.48834086) -> 0x02e3 (0.72195559) | LUT[0501] 0x0fa8 (0.48931754) -> 0x02e3 (0.72261156) + 0x02e502e4, // LUT[0502] 0x0fb0 (0.49029423) -> 0x02e4 (0.72326681) | LUT[0503] 0x0fb8 (0.49127091) -> 0x02e5 (0.72392135) + 0x02e602e5, // LUT[0504] 0x0fc0 (0.49224759) -> 0x02e5 (0.72457518) | LUT[0505] 0x0fc8 (0.49322427) -> 0x02e6 (0.72522830) + 0x02e702e7, // LUT[0506] 0x0fd0 (0.49420095) -> 0x02e7 (0.72588072) | LUT[0507] 0x0fd8 (0.49517763) -> 0x02e7 (0.72653244) + 0x02e902e8, // LUT[0508] 0x0fe0 (0.49615432) -> 0x02e8 (0.72718345) | LUT[0509] 0x0fe8 (0.49713100) -> 0x02e9 (0.72783377) + 0x02ea02e9, // LUT[0510] 0x0ff0 (0.49810768) -> 0x02e9 (0.72848339) | LUT[0511] 0x0ff8 (0.49908436) -> 0x02ea (0.72913231) + 0x02eb02eb, // LUT[0512] 0x1000 (0.50006104) -> 0x02eb (0.72978055) | LUT[0513] 0x1008 (0.50103772) -> 0x02eb (0.73042809) + 0x02ed02ec, // LUT[0514] 0x1010 (0.50201441) -> 0x02ec (0.73107494) | LUT[0515] 0x1018 (0.50299109) -> 0x02ed (0.73172111) + 0x02ee02ed, // LUT[0516] 0x1020 (0.50396777) -> 0x02ed (0.73236660) | LUT[0517] 0x1028 (0.50494445) -> 0x02ee (0.73301140) + 0x02ef02ef, // LUT[0518] 0x1030 (0.50592113) -> 0x02ef (0.73365552) | LUT[0519] 0x1038 (0.50689781) -> 0x02ef (0.73429897) + 0x02f102f0, // LUT[0520] 0x1040 (0.50787450) -> 0x02f0 (0.73494174) | LUT[0521] 0x1048 (0.50885118) -> 0x02f1 (0.73558383) + 0x02f202f1, // LUT[0522] 0x1050 (0.50982786) -> 0x02f1 (0.73622525) | LUT[0523] 0x1058 (0.51080454) -> 0x02f2 (0.73686601) + 0x02f302f2, // LUT[0524] 0x1060 (0.51178122) -> 0x02f2 (0.73750609) | LUT[0525] 0x1068 (0.51275791) -> 0x02f3 (0.73814551) + 0x02f402f4, // LUT[0526] 0x1070 (0.51373459) -> 0x02f4 (0.73878427) | LUT[0527] 0x1078 (0.51471127) -> 0x02f4 (0.73942236) + 0x02f602f5, // LUT[0528] 0x1080 (0.51568795) -> 0x02f5 (0.74005979) | LUT[0529] 0x1088 (0.51666463) -> 0x02f6 (0.74069657) + 0x02f702f6, // LUT[0530] 0x1090 (0.51764131) -> 0x02f6 (0.74133269) | LUT[0531] 0x1098 (0.51861800) -> 0x02f7 (0.74196815) + 0x02f802f8, // LUT[0532] 0x10a0 (0.51959468) -> 0x02f8 (0.74260296) | LUT[0533] 0x10a8 (0.52057136) -> 0x02f8 (0.74323713) + 0x02fa02f9, // LUT[0534] 0x10b0 (0.52154804) -> 0x02f9 (0.74387064) | LUT[0535] 0x10b8 (0.52252472) -> 0x02fa (0.74450351) + 0x02fb02fa, // LUT[0536] 0x10c0 (0.52350140) -> 0x02fa (0.74513573) | LUT[0537] 0x10c8 (0.52447809) -> 0x02fb (0.74576730) + 0x02fc02fc, // LUT[0538] 0x10d0 (0.52545477) -> 0x02fc (0.74639824) | LUT[0539] 0x10d8 (0.52643145) -> 0x02fc (0.74702854) + 0x02fd02fd, // LUT[0540] 0x10e0 (0.52740813) -> 0x02fd (0.74765820) | LUT[0541] 0x10e8 (0.52838481) -> 0x02fd (0.74828722) + 0x02ff02fe, // LUT[0542] 0x10f0 (0.52936149) -> 0x02fe (0.74891561) | LUT[0543] 0x10f8 (0.53033818) -> 0x02ff (0.74954337) + 0x030002ff, // LUT[0544] 0x1100 (0.53131486) -> 0x02ff (0.75017050) | LUT[0545] 0x1108 (0.53229154) -> 0x0300 (0.75079700) + 0x03010301, // LUT[0546] 0x1110 (0.53326822) -> 0x0301 (0.75142287) | LUT[0547] 0x1118 (0.53424490) -> 0x0301 (0.75204812) + 0x03030302, // LUT[0548] 0x1120 (0.53522158) -> 0x0302 (0.75267275) | LUT[0549] 0x1128 (0.53619827) -> 0x0303 (0.75329675) + 0x03040303, // LUT[0550] 0x1130 (0.53717495) -> 0x0303 (0.75392013) | LUT[0551] 0x1138 (0.53815163) -> 0x0304 (0.75454290) + 0x03050305, // LUT[0552] 0x1140 (0.53912831) -> 0x0305 (0.75516505) | LUT[0553] 0x1148 (0.54010499) -> 0x0305 (0.75578658) + 0x03060306, // LUT[0554] 0x1150 (0.54108168) -> 0x0306 (0.75640751) | LUT[0555] 0x1158 (0.54205836) -> 0x0306 (0.75702782) + 0x03080307, // LUT[0556] 0x1160 (0.54303504) -> 0x0307 (0.75764752) | LUT[0557] 0x1168 (0.54401172) -> 0x0308 (0.75826661) + 0x03090308, // LUT[0558] 0x1170 (0.54498840) -> 0x0308 (0.75888510) | LUT[0559] 0x1178 (0.54596508) -> 0x0309 (0.75950299) + 0x030a030a, // LUT[0560] 0x1180 (0.54694177) -> 0x030a (0.76012027) | LUT[0561] 0x1188 (0.54791845) -> 0x030a (0.76073695) + 0x030b030b, // LUT[0562] 0x1190 (0.54889513) -> 0x030b (0.76135303) | LUT[0563] 0x1198 (0.54987181) -> 0x030b (0.76196851) + 0x030d030c, // LUT[0564] 0x11a0 (0.55084849) -> 0x030c (0.76258340) | LUT[0565] 0x11a8 (0.55182517) -> 0x030d (0.76319769) + 0x030e030d, // LUT[0566] 0x11b0 (0.55280186) -> 0x030d (0.76381139) | LUT[0567] 0x11b8 (0.55377854) -> 0x030e (0.76442450) + 0x030f030f, // LUT[0568] 0x11c0 (0.55475522) -> 0x030f (0.76503702) | LUT[0569] 0x11c8 (0.55573190) -> 0x030f (0.76564896) + 0x03110310, // LUT[0570] 0x11d0 (0.55670858) -> 0x0310 (0.76626030) | LUT[0571] 0x11d8 (0.55768526) -> 0x0311 (0.76687106) + 0x03120311, // LUT[0572] 0x11e0 (0.55866195) -> 0x0311 (0.76748124) | LUT[0573] 0x11e8 (0.55963863) -> 0x0312 (0.76809084) + 0x03130312, // LUT[0574] 0x11f0 (0.56061531) -> 0x0312 (0.76869985) | LUT[0575] 0x11f8 (0.56159199) -> 0x0313 (0.76930829) + 0x03140314, // LUT[0576] 0x1200 (0.56256867) -> 0x0314 (0.76991615) | LUT[0577] 0x1208 (0.56354535) -> 0x0314 (0.77052343) + 0x03150315, // LUT[0578] 0x1210 (0.56452204) -> 0x0315 (0.77113015) | LUT[0579] 0x1218 (0.56549872) -> 0x0315 (0.77173629) + 0x03170316, // LUT[0580] 0x1220 (0.56647540) -> 0x0316 (0.77234185) | LUT[0581] 0x1228 (0.56745208) -> 0x0317 (0.77294685) + 0x03180317, // LUT[0582] 0x1230 (0.56842876) -> 0x0317 (0.77355128) | LUT[0583] 0x1238 (0.56940545) -> 0x0318 (0.77415515) + 0x03190319, // LUT[0584] 0x1240 (0.57038213) -> 0x0319 (0.77475845) | LUT[0585] 0x1248 (0.57135881) -> 0x0319 (0.77536119) + 0x031a031a, // LUT[0586] 0x1250 (0.57233549) -> 0x031a (0.77596336) | LUT[0587] 0x1258 (0.57331217) -> 0x031a (0.77656498) + 0x031c031b, // LUT[0588] 0x1260 (0.57428885) -> 0x031b (0.77716604) | LUT[0589] 0x1268 (0.57526554) -> 0x031c (0.77776653) + 0x031d031c, // LUT[0590] 0x1270 (0.57624222) -> 0x031c (0.77836648) | LUT[0591] 0x1278 (0.57721890) -> 0x031d (0.77896587) + 0x031e031d, // LUT[0592] 0x1280 (0.57819558) -> 0x031d (0.77956470) | LUT[0593] 0x1288 (0.57917226) -> 0x031e (0.78016299) + 0x031f031f, // LUT[0594] 0x1290 (0.58014894) -> 0x031f (0.78076072) | LUT[0595] 0x1298 (0.58112563) -> 0x031f (0.78135791) + 0x03210320, // LUT[0596] 0x12a0 (0.58210231) -> 0x0320 (0.78195455) | LUT[0597] 0x12a8 (0.58307899) -> 0x0321 (0.78255064) + 0x03220321, // LUT[0598] 0x12b0 (0.58405567) -> 0x0321 (0.78314619) | LUT[0599] 0x12b8 (0.58503235) -> 0x0322 (0.78374119) + 0x03230322, // LUT[0600] 0x12c0 (0.58600903) -> 0x0322 (0.78433566) | LUT[0601] 0x12c8 (0.58698572) -> 0x0323 (0.78492958) + 0x03240324, // LUT[0602] 0x12d0 (0.58796240) -> 0x0324 (0.78552297) | LUT[0603] 0x12d8 (0.58893908) -> 0x0324 (0.78611581) + 0x03250325, // LUT[0604] 0x12e0 (0.58991576) -> 0x0325 (0.78670813) | LUT[0605] 0x12e8 (0.59089244) -> 0x0325 (0.78729990) + 0x03270326, // LUT[0606] 0x12f0 (0.59186912) -> 0x0326 (0.78789115) | LUT[0607] 0x12f8 (0.59284581) -> 0x0327 (0.78848186) + 0x03280327, // LUT[0608] 0x1300 (0.59382249) -> 0x0327 (0.78907204) | LUT[0609] 0x1308 (0.59479917) -> 0x0328 (0.78966169) + 0x03290328, // LUT[0610] 0x1310 (0.59577585) -> 0x0328 (0.79025082) | LUT[0611] 0x1318 (0.59675253) -> 0x0329 (0.79083941) + 0x032a032a, // LUT[0612] 0x1320 (0.59772921) -> 0x032a (0.79142749) | LUT[0613] 0x1328 (0.59870590) -> 0x032a (0.79201503) + 0x032b032b, // LUT[0614] 0x1330 (0.59968258) -> 0x032b (0.79260206) | LUT[0615] 0x1338 (0.60065926) -> 0x032b (0.79318856) + 0x032d032c, // LUT[0616] 0x1340 (0.60163594) -> 0x032c (0.79377455) | LUT[0617] 0x1348 (0.60261262) -> 0x032d (0.79436001) + 0x032e032d, // LUT[0618] 0x1350 (0.60358931) -> 0x032d (0.79494496) | LUT[0619] 0x1358 (0.60456599) -> 0x032e (0.79552940) + 0x032f032e, // LUT[0620] 0x1360 (0.60554267) -> 0x032e (0.79611331) | LUT[0621] 0x1368 (0.60651935) -> 0x032f (0.79669672) + 0x03300330, // LUT[0622] 0x1370 (0.60749603) -> 0x0330 (0.79727961) | LUT[0623] 0x1378 (0.60847271) -> 0x0330 (0.79786199) + 0x03310331, // LUT[0624] 0x1380 (0.60944940) -> 0x0331 (0.79844386) | LUT[0625] 0x1388 (0.61042608) -> 0x0331 (0.79902523) + 0x03330332, // LUT[0626] 0x1390 (0.61140276) -> 0x0332 (0.79960608) | LUT[0627] 0x1398 (0.61237944) -> 0x0333 (0.80018643) + 0x03340333, // LUT[0628] 0x13a0 (0.61335612) -> 0x0333 (0.80076628) | LUT[0629] 0x13a8 (0.61433280) -> 0x0334 (0.80134562) + 0x03350334, // LUT[0630] 0x13b0 (0.61530949) -> 0x0334 (0.80192446) | LUT[0631] 0x13b8 (0.61628617) -> 0x0335 (0.80250280) + 0x03360336, // LUT[0632] 0x13c0 (0.61726285) -> 0x0336 (0.80308064) | LUT[0633] 0x13c8 (0.61823953) -> 0x0336 (0.80365798) + 0x03370337, // LUT[0634] 0x13d0 (0.61921621) -> 0x0337 (0.80423482) | LUT[0635] 0x13d8 (0.62019289) -> 0x0337 (0.80481117) + 0x03380338, // LUT[0636] 0x13e0 (0.62116958) -> 0x0338 (0.80538702) | LUT[0637] 0x13e8 (0.62214626) -> 0x0338 (0.80596238) + 0x033a0339, // LUT[0638] 0x13f0 (0.62312294) -> 0x0339 (0.80653724) | LUT[0639] 0x13f8 (0.62409962) -> 0x033a (0.80711162) + 0x033b033a, // LUT[0640] 0x1400 (0.62507630) -> 0x033a (0.80768550) | LUT[0641] 0x1408 (0.62605298) -> 0x033b (0.80825890) + 0x033c033b, // LUT[0642] 0x1410 (0.62702967) -> 0x033b (0.80883181) | LUT[0643] 0x1418 (0.62800635) -> 0x033c (0.80940423) + 0x033d033d, // LUT[0644] 0x1420 (0.62898303) -> 0x033d (0.80997617) | LUT[0645] 0x1428 (0.62995971) -> 0x033d (0.81054762) + 0x033e033e, // LUT[0646] 0x1430 (0.63093639) -> 0x033e (0.81111859) | LUT[0647] 0x1438 (0.63191308) -> 0x033e (0.81168908) + 0x0340033f, // LUT[0648] 0x1440 (0.63288976) -> 0x033f (0.81225908) | LUT[0649] 0x1448 (0.63386644) -> 0x0340 (0.81282861) + 0x03410340, // LUT[0650] 0x1450 (0.63484312) -> 0x0340 (0.81339766) | LUT[0651] 0x1458 (0.63581980) -> 0x0341 (0.81396623) + 0x03420341, // LUT[0652] 0x1460 (0.63679648) -> 0x0341 (0.81453432) | LUT[0653] 0x1468 (0.63777317) -> 0x0342 (0.81510194) + 0x03430342, // LUT[0654] 0x1470 (0.63874985) -> 0x0342 (0.81566909) | LUT[0655] 0x1478 (0.63972653) -> 0x0343 (0.81623576) + 0x03440344, // LUT[0656] 0x1480 (0.64070321) -> 0x0344 (0.81680196) | LUT[0657] 0x1488 (0.64167989) -> 0x0344 (0.81736769) + 0x03450345, // LUT[0658] 0x1490 (0.64265657) -> 0x0345 (0.81793296) | LUT[0659] 0x1498 (0.64363326) -> 0x0345 (0.81849775) + 0x03460346, // LUT[0660] 0x14a0 (0.64460994) -> 0x0346 (0.81906207) | LUT[0661] 0x14a8 (0.64558662) -> 0x0346 (0.81962593) + 0x03480347, // LUT[0662] 0x14b0 (0.64656330) -> 0x0347 (0.82018933) | LUT[0663] 0x14b8 (0.64753998) -> 0x0348 (0.82075226) + 0x03490348, // LUT[0664] 0x14c0 (0.64851666) -> 0x0348 (0.82131473) | LUT[0665] 0x14c8 (0.64949335) -> 0x0349 (0.82187673) + 0x034a0349, // LUT[0666] 0x14d0 (0.65047003) -> 0x0349 (0.82243828) | LUT[0667] 0x14d8 (0.65144671) -> 0x034a (0.82299936) + 0x034b034b, // LUT[0668] 0x14e0 (0.65242339) -> 0x034b (0.82355999) | LUT[0669] 0x14e8 (0.65340007) -> 0x034b (0.82412016) + 0x034c034c, // LUT[0670] 0x14f0 (0.65437675) -> 0x034c (0.82467987) | LUT[0671] 0x14f8 (0.65535344) -> 0x034c (0.82523912) + 0x034d034d, // LUT[0672] 0x1500 (0.65633012) -> 0x034d (0.82579793) | LUT[0673] 0x1508 (0.65730680) -> 0x034d (0.82635628) + 0x034f034e, // LUT[0674] 0x1510 (0.65828348) -> 0x034e (0.82691417) | LUT[0675] 0x1518 (0.65926016) -> 0x034f (0.82747162) + 0x0350034f, // LUT[0676] 0x1520 (0.66023685) -> 0x034f (0.82802861) | LUT[0677] 0x1528 (0.66121353) -> 0x0350 (0.82858516) + 0x03510350, // LUT[0678] 0x1530 (0.66219021) -> 0x0350 (0.82914126) | LUT[0679] 0x1538 (0.66316689) -> 0x0351 (0.82969691) + 0x03520351, // LUT[0680] 0x1540 (0.66414357) -> 0x0351 (0.83025211) | LUT[0681] 0x1548 (0.66512025) -> 0x0352 (0.83080687) + 0x03530352, // LUT[0682] 0x1550 (0.66609694) -> 0x0352 (0.83136118) | LUT[0683] 0x1558 (0.66707362) -> 0x0353 (0.83191506) + 0x03540354, // LUT[0684] 0x1560 (0.66805030) -> 0x0354 (0.83246848) | LUT[0685] 0x1568 (0.66902698) -> 0x0354 (0.83302147) + 0x03550355, // LUT[0686] 0x1570 (0.67000366) -> 0x0355 (0.83357402) | LUT[0687] 0x1578 (0.67098034) -> 0x0355 (0.83412613) + 0x03560356, // LUT[0688] 0x1580 (0.67195703) -> 0x0356 (0.83467780) | LUT[0689] 0x1588 (0.67293371) -> 0x0356 (0.83522903) + 0x03580357, // LUT[0690] 0x1590 (0.67391039) -> 0x0357 (0.83577983) | LUT[0691] 0x1598 (0.67488707) -> 0x0358 (0.83633019) + 0x03590358, // LUT[0692] 0x15a0 (0.67586375) -> 0x0358 (0.83688012) | LUT[0693] 0x15a8 (0.67684043) -> 0x0359 (0.83742962) + 0x035a0359, // LUT[0694] 0x15b0 (0.67781712) -> 0x0359 (0.83797868) | LUT[0695] 0x15b8 (0.67879380) -> 0x035a (0.83852731) + 0x035b035a, // LUT[0696] 0x15c0 (0.67977048) -> 0x035a (0.83907551) | LUT[0697] 0x15c8 (0.68074716) -> 0x035b (0.83962328) + 0x035c035b, // LUT[0698] 0x15d0 (0.68172384) -> 0x035b (0.84017062) | LUT[0699] 0x15d8 (0.68270052) -> 0x035c (0.84071754) + 0x035d035d, // LUT[0700] 0x15e0 (0.68367721) -> 0x035d (0.84126403) | LUT[0701] 0x15e8 (0.68465389) -> 0x035d (0.84181009) + 0x035e035e, // LUT[0702] 0x15f0 (0.68563057) -> 0x035e (0.84235573) | LUT[0703] 0x15f8 (0.68660725) -> 0x035e (0.84290094) + 0x035f035f, // LUT[0704] 0x1600 (0.68758393) -> 0x035f (0.84344573) | LUT[0705] 0x1608 (0.68856062) -> 0x035f (0.84399010) + 0x03610360, // LUT[0706] 0x1610 (0.68953730) -> 0x0360 (0.84453405) | LUT[0707] 0x1618 (0.69051398) -> 0x0361 (0.84507758) + 0x03620361, // LUT[0708] 0x1620 (0.69149066) -> 0x0361 (0.84562069) | LUT[0709] 0x1628 (0.69246734) -> 0x0362 (0.84616338) + 0x03630362, // LUT[0710] 0x1630 (0.69344402) -> 0x0362 (0.84670565) | LUT[0711] 0x1638 (0.69442071) -> 0x0363 (0.84724751) + 0x03640363, // LUT[0712] 0x1640 (0.69539739) -> 0x0363 (0.84778895) | LUT[0713] 0x1648 (0.69637407) -> 0x0364 (0.84832998) + 0x03650364, // LUT[0714] 0x1650 (0.69735075) -> 0x0364 (0.84887059) | LUT[0715] 0x1658 (0.69832743) -> 0x0365 (0.84941079) + 0x03660365, // LUT[0716] 0x1660 (0.69930411) -> 0x0365 (0.84995058) | LUT[0717] 0x1668 (0.70028080) -> 0x0366 (0.85048996) + 0x03670367, // LUT[0718] 0x1670 (0.70125748) -> 0x0367 (0.85102892) | LUT[0719] 0x1678 (0.70223416) -> 0x0367 (0.85156748) + 0x03680368, // LUT[0720] 0x1680 (0.70321084) -> 0x0368 (0.85210563) | LUT[0721] 0x1688 (0.70418752) -> 0x0368 (0.85264337) + 0x03690369, // LUT[0722] 0x1690 (0.70516420) -> 0x0369 (0.85318071) | LUT[0723] 0x1698 (0.70614089) -> 0x0369 (0.85371764) + 0x036a036a, // LUT[0724] 0x16a0 (0.70711757) -> 0x036a (0.85425416) | LUT[0725] 0x16a8 (0.70809425) -> 0x036a (0.85479028) + 0x036c036b, // LUT[0726] 0x16b0 (0.70907093) -> 0x036b (0.85532600) | LUT[0727] 0x16b8 (0.71004761) -> 0x036c (0.85586131) + 0x036d036c, // LUT[0728] 0x16c0 (0.71102429) -> 0x036c (0.85639623) | LUT[0729] 0x16c8 (0.71200098) -> 0x036d (0.85693074) + 0x036e036d, // LUT[0730] 0x16d0 (0.71297766) -> 0x036d (0.85746485) | LUT[0731] 0x16d8 (0.71395434) -> 0x036e (0.85799857) + 0x036f036e, // LUT[0732] 0x16e0 (0.71493102) -> 0x036e (0.85853188) | LUT[0733] 0x16e8 (0.71590770) -> 0x036f (0.85906480) + 0x0370036f, // LUT[0734] 0x16f0 (0.71688439) -> 0x036f (0.85959732) | LUT[0735] 0x16f8 (0.71786107) -> 0x0370 (0.86012945) + 0x03710370, // LUT[0736] 0x1700 (0.71883775) -> 0x0370 (0.86066118) | LUT[0737] 0x1708 (0.71981443) -> 0x0371 (0.86119252) + 0x03720372, // LUT[0738] 0x1710 (0.72079111) -> 0x0372 (0.86172347) | LUT[0739] 0x1718 (0.72176779) -> 0x0372 (0.86225402) + 0x03730373, // LUT[0740] 0x1720 (0.72274448) -> 0x0373 (0.86278418) | LUT[0741] 0x1728 (0.72372116) -> 0x0373 (0.86331395) + 0x03740374, // LUT[0742] 0x1730 (0.72469784) -> 0x0374 (0.86384333) | LUT[0743] 0x1738 (0.72567452) -> 0x0374 (0.86437232) + 0x03750375, // LUT[0744] 0x1740 (0.72665120) -> 0x0375 (0.86490093) | LUT[0745] 0x1748 (0.72762788) -> 0x0375 (0.86542914) + 0x03760376, // LUT[0746] 0x1750 (0.72860457) -> 0x0376 (0.86595697) | LUT[0747] 0x1758 (0.72958125) -> 0x0376 (0.86648442) + 0x03770377, // LUT[0748] 0x1760 (0.73055793) -> 0x0377 (0.86701147) | LUT[0749] 0x1768 (0.73153461) -> 0x0377 (0.86753815) + 0x03790378, // LUT[0750] 0x1770 (0.73251129) -> 0x0378 (0.86806444) | LUT[0751] 0x1778 (0.73348797) -> 0x0379 (0.86859035) + 0x037a0379, // LUT[0752] 0x1780 (0.73446466) -> 0x0379 (0.86911587) | LUT[0753] 0x1788 (0.73544134) -> 0x037a (0.86964102) + 0x037b037a, // LUT[0754] 0x1790 (0.73641802) -> 0x037a (0.87016579) | LUT[0755] 0x1798 (0.73739470) -> 0x037b (0.87069017) + 0x037c037b, // LUT[0756] 0x17a0 (0.73837138) -> 0x037b (0.87121418) | LUT[0757] 0x17a8 (0.73934806) -> 0x037c (0.87173781) + 0x037d037c, // LUT[0758] 0x17b0 (0.74032475) -> 0x037c (0.87226106) | LUT[0759] 0x17b8 (0.74130143) -> 0x037d (0.87278394) + 0x037e037d, // LUT[0760] 0x17c0 (0.74227811) -> 0x037d (0.87330644) | LUT[0761] 0x17c8 (0.74325479) -> 0x037e (0.87382856) + 0x037f037e, // LUT[0762] 0x17d0 (0.74423147) -> 0x037e (0.87435031) | LUT[0763] 0x17d8 (0.74520816) -> 0x037f (0.87487169) + 0x03800380, // LUT[0764] 0x17e0 (0.74618484) -> 0x0380 (0.87539269) | LUT[0765] 0x17e8 (0.74716152) -> 0x0380 (0.87591333) + 0x03810381, // LUT[0766] 0x17f0 (0.74813820) -> 0x0381 (0.87643359) | LUT[0767] 0x17f8 (0.74911488) -> 0x0381 (0.87695348) + 0x03820382, // LUT[0768] 0x1800 (0.75009156) -> 0x0382 (0.87747300) | LUT[0769] 0x1808 (0.75106825) -> 0x0382 (0.87799216) + 0x03830383, // LUT[0770] 0x1810 (0.75204493) -> 0x0383 (0.87851094) | LUT[0771] 0x1818 (0.75302161) -> 0x0383 (0.87902936) + 0x03840384, // LUT[0772] 0x1820 (0.75399829) -> 0x0384 (0.87954741) | LUT[0773] 0x1828 (0.75497497) -> 0x0384 (0.88006510) + 0x03850385, // LUT[0774] 0x1830 (0.75595165) -> 0x0385 (0.88058242) | LUT[0775] 0x1838 (0.75692834) -> 0x0385 (0.88109937) + 0x03860386, // LUT[0776] 0x1840 (0.75790502) -> 0x0386 (0.88161597) | LUT[0777] 0x1848 (0.75888170) -> 0x0386 (0.88213219) + 0x03870387, // LUT[0778] 0x1850 (0.75985838) -> 0x0387 (0.88264806) | LUT[0779] 0x1858 (0.76083506) -> 0x0387 (0.88316357) + 0x03890388, // LUT[0780] 0x1860 (0.76181174) -> 0x0388 (0.88367871) | LUT[0781] 0x1868 (0.76278843) -> 0x0389 (0.88419350) + 0x038a0389, // LUT[0782] 0x1870 (0.76376511) -> 0x0389 (0.88470792) | LUT[0783] 0x1878 (0.76474179) -> 0x038a (0.88522199) + 0x038b038a, // LUT[0784] 0x1880 (0.76571847) -> 0x038a (0.88573570) | LUT[0785] 0x1888 (0.76669515) -> 0x038b (0.88624905) + 0x038c038b, // LUT[0786] 0x1890 (0.76767183) -> 0x038b (0.88676204) | LUT[0787] 0x1898 (0.76864852) -> 0x038c (0.88727468) + 0x038d038c, // LUT[0788] 0x18a0 (0.76962520) -> 0x038c (0.88778696) | LUT[0789] 0x18a8 (0.77060188) -> 0x038d (0.88829889) + 0x038e038d, // LUT[0790] 0x18b0 (0.77157856) -> 0x038d (0.88881047) | LUT[0791] 0x18b8 (0.77255524) -> 0x038e (0.88932169) + 0x038f038e, // LUT[0792] 0x18c0 (0.77353193) -> 0x038e (0.88983256) | LUT[0793] 0x18c8 (0.77450861) -> 0x038f (0.89034308) + 0x0390038f, // LUT[0794] 0x18d0 (0.77548529) -> 0x038f (0.89085324) | LUT[0795] 0x18d8 (0.77646197) -> 0x0390 (0.89136306) + 0x03910390, // LUT[0796] 0x18e0 (0.77743865) -> 0x0390 (0.89187253) | LUT[0797] 0x18e8 (0.77841533) -> 0x0391 (0.89238164) + 0x03920391, // LUT[0798] 0x18f0 (0.77939202) -> 0x0391 (0.89289041) | LUT[0799] 0x18f8 (0.78036870) -> 0x0392 (0.89339884) + 0x03930392, // LUT[0800] 0x1900 (0.78134538) -> 0x0392 (0.89390691) | LUT[0801] 0x1908 (0.78232206) -> 0x0393 (0.89441464) + 0x03940394, // LUT[0802] 0x1910 (0.78329874) -> 0x0394 (0.89492202) | LUT[0803] 0x1918 (0.78427542) -> 0x0394 (0.89542906) + 0x03950395, // LUT[0804] 0x1920 (0.78525211) -> 0x0395 (0.89593575) | LUT[0805] 0x1928 (0.78622879) -> 0x0395 (0.89644210) + 0x03960396, // LUT[0806] 0x1930 (0.78720547) -> 0x0396 (0.89694811) | LUT[0807] 0x1938 (0.78818215) -> 0x0396 (0.89745378) + 0x03970397, // LUT[0808] 0x1940 (0.78915883) -> 0x0397 (0.89795910) | LUT[0809] 0x1948 (0.79013551) -> 0x0397 (0.89846408) + 0x03980398, // LUT[0810] 0x1950 (0.79111220) -> 0x0398 (0.89896872) | LUT[0811] 0x1958 (0.79208888) -> 0x0398 (0.89947302) + 0x03990399, // LUT[0812] 0x1960 (0.79306556) -> 0x0399 (0.89997699) | LUT[0813] 0x1968 (0.79404224) -> 0x0399 (0.90048061) + 0x039a039a, // LUT[0814] 0x1970 (0.79501892) -> 0x039a (0.90098390) | LUT[0815] 0x1978 (0.79599560) -> 0x039a (0.90148685) + 0x039b039b, // LUT[0816] 0x1980 (0.79697229) -> 0x039b (0.90198946) | LUT[0817] 0x1988 (0.79794897) -> 0x039b (0.90249174) + 0x039c039c, // LUT[0818] 0x1990 (0.79892565) -> 0x039c (0.90299368) | LUT[0819] 0x1998 (0.79990233) -> 0x039c (0.90349529) + 0x039d039d, // LUT[0820] 0x19a0 (0.80087901) -> 0x039d (0.90399656) | LUT[0821] 0x19a8 (0.80185570) -> 0x039d (0.90449750) + 0x039e039e, // LUT[0822] 0x19b0 (0.80283238) -> 0x039e (0.90499811) | LUT[0823] 0x19b8 (0.80380906) -> 0x039e (0.90549839) + 0x039f039f, // LUT[0824] 0x19c0 (0.80478574) -> 0x039f (0.90599833) | LUT[0825] 0x19c8 (0.80576242) -> 0x039f (0.90649794) + 0x03a003a0, // LUT[0826] 0x19d0 (0.80673910) -> 0x03a0 (0.90699723) | LUT[0827] 0x19d8 (0.80771579) -> 0x03a0 (0.90749618) + 0x03a103a1, // LUT[0828] 0x19e0 (0.80869247) -> 0x03a1 (0.90799480) | LUT[0829] 0x19e8 (0.80966915) -> 0x03a1 (0.90849310) + 0x03a203a2, // LUT[0830] 0x19f0 (0.81064583) -> 0x03a2 (0.90899107) | LUT[0831] 0x19f8 (0.81162251) -> 0x03a2 (0.90948871) + 0x03a303a3, // LUT[0832] 0x1a00 (0.81259919) -> 0x03a3 (0.90998602) | LUT[0833] 0x1a08 (0.81357588) -> 0x03a3 (0.91048301) + 0x03a403a4, // LUT[0834] 0x1a10 (0.81455256) -> 0x03a4 (0.91097967) | LUT[0835] 0x1a18 (0.81552924) -> 0x03a4 (0.91147601) + 0x03a503a5, // LUT[0836] 0x1a20 (0.81650592) -> 0x03a5 (0.91197203) | LUT[0837] 0x1a28 (0.81748260) -> 0x03a5 (0.91246772) + 0x03a603a6, // LUT[0838] 0x1a30 (0.81845928) -> 0x03a6 (0.91296309) | LUT[0839] 0x1a38 (0.81943597) -> 0x03a6 (0.91345813) + 0x03a703a7, // LUT[0840] 0x1a40 (0.82041265) -> 0x03a7 (0.91395286) | LUT[0841] 0x1a48 (0.82138933) -> 0x03a7 (0.91444726) + 0x03a803a8, // LUT[0842] 0x1a50 (0.82236601) -> 0x03a8 (0.91494134) | LUT[0843] 0x1a58 (0.82334269) -> 0x03a8 (0.91543510) + 0x03a903a9, // LUT[0844] 0x1a60 (0.82431937) -> 0x03a9 (0.91592855) | LUT[0845] 0x1a68 (0.82529606) -> 0x03a9 (0.91642167) + 0x03ab03aa, // LUT[0846] 0x1a70 (0.82627274) -> 0x03aa (0.91691448) | LUT[0847] 0x1a78 (0.82724942) -> 0x03ab (0.91740696) + 0x03ac03ab, // LUT[0848] 0x1a80 (0.82822610) -> 0x03ab (0.91789914) | LUT[0849] 0x1a88 (0.82920278) -> 0x03ac (0.91839099) + 0x03ad03ac, // LUT[0850] 0x1a90 (0.83017947) -> 0x03ac (0.91888253) | LUT[0851] 0x1a98 (0.83115615) -> 0x03ad (0.91937375) + 0x03ae03ad, // LUT[0852] 0x1aa0 (0.83213283) -> 0x03ad (0.91986466) | LUT[0853] 0x1aa8 (0.83310951) -> 0x03ae (0.92035526) + 0x03af03ae, // LUT[0854] 0x1ab0 (0.83408619) -> 0x03ae (0.92084554) | LUT[0855] 0x1ab8 (0.83506287) -> 0x03af (0.92133550) + 0x03b003af, // LUT[0856] 0x1ac0 (0.83603956) -> 0x03af (0.92182516) | LUT[0857] 0x1ac8 (0.83701624) -> 0x03b0 (0.92231450) + 0x03b103b0, // LUT[0858] 0x1ad0 (0.83799292) -> 0x03b0 (0.92280353) | LUT[0859] 0x1ad8 (0.83896960) -> 0x03b1 (0.92329226) + 0x03b203b1, // LUT[0860] 0x1ae0 (0.83994628) -> 0x03b1 (0.92378067) | LUT[0861] 0x1ae8 (0.84092296) -> 0x03b2 (0.92426877) + 0x03b303b2, // LUT[0862] 0x1af0 (0.84189965) -> 0x03b2 (0.92475656) | LUT[0863] 0x1af8 (0.84287633) -> 0x03b3 (0.92524404) + 0x03b403b3, // LUT[0864] 0x1b00 (0.84385301) -> 0x03b3 (0.92573122) | LUT[0865] 0x1b08 (0.84482969) -> 0x03b4 (0.92621809) + 0x03b503b4, // LUT[0866] 0x1b10 (0.84580637) -> 0x03b4 (0.92670465) | LUT[0867] 0x1b18 (0.84678305) -> 0x03b5 (0.92719091) + 0x03b603b5, // LUT[0868] 0x1b20 (0.84775974) -> 0x03b5 (0.92767685) | LUT[0869] 0x1b28 (0.84873642) -> 0x03b6 (0.92816250) + 0x03b703b6, // LUT[0870] 0x1b30 (0.84971310) -> 0x03b6 (0.92864784) | LUT[0871] 0x1b38 (0.85068978) -> 0x03b7 (0.92913287) + 0x03b703b7, // LUT[0872] 0x1b40 (0.85166646) -> 0x03b7 (0.92961760) | LUT[0873] 0x1b48 (0.85264314) -> 0x03b7 (0.93010203) + 0x03b803b8, // LUT[0874] 0x1b50 (0.85361983) -> 0x03b8 (0.93058616) | LUT[0875] 0x1b58 (0.85459651) -> 0x03b8 (0.93106998) + 0x03b903b9, // LUT[0876] 0x1b60 (0.85557319) -> 0x03b9 (0.93155350) | LUT[0877] 0x1b68 (0.85654987) -> 0x03b9 (0.93203672) + 0x03ba03ba, // LUT[0878] 0x1b70 (0.85752655) -> 0x03ba (0.93251964) | LUT[0879] 0x1b78 (0.85850324) -> 0x03ba (0.93300227) + 0x03bb03bb, // LUT[0880] 0x1b80 (0.85947992) -> 0x03bb (0.93348459) | LUT[0881] 0x1b88 (0.86045660) -> 0x03bb (0.93396661) + 0x03bc03bc, // LUT[0882] 0x1b90 (0.86143328) -> 0x03bc (0.93444833) | LUT[0883] 0x1b98 (0.86240996) -> 0x03bc (0.93492976) + 0x03bd03bd, // LUT[0884] 0x1ba0 (0.86338664) -> 0x03bd (0.93541089) | LUT[0885] 0x1ba8 (0.86436333) -> 0x03bd (0.93589172) + 0x03be03be, // LUT[0886] 0x1bb0 (0.86534001) -> 0x03be (0.93637226) | LUT[0887] 0x1bb8 (0.86631669) -> 0x03be (0.93685250) + 0x03bf03bf, // LUT[0888] 0x1bc0 (0.86729337) -> 0x03bf (0.93733244) | LUT[0889] 0x1bc8 (0.86827005) -> 0x03bf (0.93781209) + 0x03c003c0, // LUT[0890] 0x1bd0 (0.86924673) -> 0x03c0 (0.93829145) | LUT[0891] 0x1bd8 (0.87022342) -> 0x03c0 (0.93877051) + 0x03c103c1, // LUT[0892] 0x1be0 (0.87120010) -> 0x03c1 (0.93924928) | LUT[0893] 0x1be8 (0.87217678) -> 0x03c1 (0.93972776) + 0x03c203c2, // LUT[0894] 0x1bf0 (0.87315346) -> 0x03c2 (0.94020594) | LUT[0895] 0x1bf8 (0.87413014) -> 0x03c2 (0.94068383) + 0x03c303c3, // LUT[0896] 0x1c00 (0.87510682) -> 0x03c3 (0.94116143) | LUT[0897] 0x1c08 (0.87608351) -> 0x03c3 (0.94163875) + 0x03c403c4, // LUT[0898] 0x1c10 (0.87706019) -> 0x03c4 (0.94211577) | LUT[0899] 0x1c18 (0.87803687) -> 0x03c4 (0.94259250) + 0x03c503c5, // LUT[0900] 0x1c20 (0.87901355) -> 0x03c5 (0.94306894) | LUT[0901] 0x1c28 (0.87999023) -> 0x03c5 (0.94354509) + 0x03c603c6, // LUT[0902] 0x1c30 (0.88096691) -> 0x03c6 (0.94402096) | LUT[0903] 0x1c38 (0.88194360) -> 0x03c6 (0.94449653) + 0x03c703c7, // LUT[0904] 0x1c40 (0.88292028) -> 0x03c7 (0.94497182) | LUT[0905] 0x1c48 (0.88389696) -> 0x03c7 (0.94544683) + 0x03c803c8, // LUT[0906] 0x1c50 (0.88487364) -> 0x03c8 (0.94592155) | LUT[0907] 0x1c58 (0.88585032) -> 0x03c8 (0.94639598) + 0x03c903c9, // LUT[0908] 0x1c60 (0.88682701) -> 0x03c9 (0.94687012) | LUT[0909] 0x1c68 (0.88780369) -> 0x03c9 (0.94734398) + 0x03ca03ca, // LUT[0910] 0x1c70 (0.88878037) -> 0x03ca (0.94781756) | LUT[0911] 0x1c78 (0.88975705) -> 0x03ca (0.94829086) + 0x03cb03cb, // LUT[0912] 0x1c80 (0.89073373) -> 0x03cb (0.94876387) | LUT[0913] 0x1c88 (0.89171041) -> 0x03cb (0.94923659) + 0x03cc03cc, // LUT[0914] 0x1c90 (0.89268710) -> 0x03cc (0.94970904) | LUT[0915] 0x1c98 (0.89366378) -> 0x03cc (0.95018120) + 0x03cd03cd, // LUT[0916] 0x1ca0 (0.89464046) -> 0x03cd (0.95065308) | LUT[0917] 0x1ca8 (0.89561714) -> 0x03cd (0.95112468) + 0x03ce03cd, // LUT[0918] 0x1cb0 (0.89659382) -> 0x03cd (0.95159601) | LUT[0919] 0x1cb8 (0.89757050) -> 0x03ce (0.95206705) + 0x03cf03ce, // LUT[0920] 0x1cc0 (0.89854719) -> 0x03ce (0.95253781) | LUT[0921] 0x1cc8 (0.89952387) -> 0x03cf (0.95300829) + 0x03d003cf, // LUT[0922] 0x1cd0 (0.90050055) -> 0x03cf (0.95347849) | LUT[0923] 0x1cd8 (0.90147723) -> 0x03d0 (0.95394842) + 0x03d103d0, // LUT[0924] 0x1ce0 (0.90245391) -> 0x03d0 (0.95441807) | LUT[0925] 0x1ce8 (0.90343059) -> 0x03d1 (0.95488744) + 0x03d203d1, // LUT[0926] 0x1cf0 (0.90440728) -> 0x03d1 (0.95535653) | LUT[0927] 0x1cf8 (0.90538396) -> 0x03d2 (0.95582535) + 0x03d303d2, // LUT[0928] 0x1d00 (0.90636064) -> 0x03d2 (0.95629389) | LUT[0929] 0x1d08 (0.90733732) -> 0x03d3 (0.95676216) + 0x03d403d3, // LUT[0930] 0x1d10 (0.90831400) -> 0x03d3 (0.95723015) | LUT[0931] 0x1d18 (0.90929068) -> 0x03d4 (0.95769786) + 0x03d503d4, // LUT[0932] 0x1d20 (0.91026737) -> 0x03d4 (0.95816531) | LUT[0933] 0x1d28 (0.91124405) -> 0x03d5 (0.95863248) + 0x03d603d5, // LUT[0934] 0x1d30 (0.91222073) -> 0x03d5 (0.95909937) | LUT[0935] 0x1d38 (0.91319741) -> 0x03d6 (0.95956600) + 0x03d703d6, // LUT[0936] 0x1d40 (0.91417409) -> 0x03d6 (0.96003235) | LUT[0937] 0x1d48 (0.91515078) -> 0x03d7 (0.96049843) + 0x03d803d7, // LUT[0938] 0x1d50 (0.91612746) -> 0x03d7 (0.96096424) | LUT[0939] 0x1d58 (0.91710414) -> 0x03d8 (0.96142978) + 0x03d803d8, // LUT[0940] 0x1d60 (0.91808082) -> 0x03d8 (0.96189505) | LUT[0941] 0x1d68 (0.91905750) -> 0x03d8 (0.96236005) + 0x03d903d9, // LUT[0942] 0x1d70 (0.92003418) -> 0x03d9 (0.96282477) | LUT[0943] 0x1d78 (0.92101087) -> 0x03d9 (0.96328923) + 0x03da03da, // LUT[0944] 0x1d80 (0.92198755) -> 0x03da (0.96375342) | LUT[0945] 0x1d88 (0.92296423) -> 0x03da (0.96421735) + 0x03db03db, // LUT[0946] 0x1d90 (0.92394091) -> 0x03db (0.96468100) | LUT[0947] 0x1d98 (0.92491759) -> 0x03db (0.96514439) + 0x03dc03dc, // LUT[0948] 0x1da0 (0.92589427) -> 0x03dc (0.96560751) | LUT[0949] 0x1da8 (0.92687096) -> 0x03dc (0.96607037) + 0x03dd03dd, // LUT[0950] 0x1db0 (0.92784764) -> 0x03dd (0.96653296) | LUT[0951] 0x1db8 (0.92882432) -> 0x03dd (0.96699528) + 0x03de03de, // LUT[0952] 0x1dc0 (0.92980100) -> 0x03de (0.96745734) | LUT[0953] 0x1dc8 (0.93077768) -> 0x03de (0.96791913) + 0x03df03df, // LUT[0954] 0x1dd0 (0.93175436) -> 0x03df (0.96838066) | LUT[0955] 0x1dd8 (0.93273105) -> 0x03df (0.96884193) + 0x03e003e0, // LUT[0956] 0x1de0 (0.93370773) -> 0x03e0 (0.96930293) | LUT[0957] 0x1de8 (0.93468441) -> 0x03e0 (0.96976367) + 0x03e103e1, // LUT[0958] 0x1df0 (0.93566109) -> 0x03e1 (0.97022414) | LUT[0959] 0x1df8 (0.93663777) -> 0x03e1 (0.97068436) + 0x03e203e1, // LUT[0960] 0x1e00 (0.93761445) -> 0x03e1 (0.97114431) | LUT[0961] 0x1e08 (0.93859114) -> 0x03e2 (0.97160400) + 0x03e303e2, // LUT[0962] 0x1e10 (0.93956782) -> 0x03e2 (0.97206343) | LUT[0963] 0x1e18 (0.94054450) -> 0x03e3 (0.97252260) + 0x03e403e3, // LUT[0964] 0x1e20 (0.94152118) -> 0x03e3 (0.97298151) | LUT[0965] 0x1e28 (0.94249786) -> 0x03e4 (0.97344016) + 0x03e503e4, // LUT[0966] 0x1e30 (0.94347455) -> 0x03e4 (0.97389856) | LUT[0967] 0x1e38 (0.94445123) -> 0x03e5 (0.97435669) + 0x03e603e5, // LUT[0968] 0x1e40 (0.94542791) -> 0x03e5 (0.97481456) | LUT[0969] 0x1e48 (0.94640459) -> 0x03e6 (0.97527218) + 0x03e703e6, // LUT[0970] 0x1e50 (0.94738127) -> 0x03e6 (0.97572954) | LUT[0971] 0x1e58 (0.94835795) -> 0x03e7 (0.97618664) + 0x03e803e7, // LUT[0972] 0x1e60 (0.94933464) -> 0x03e7 (0.97664348) | LUT[0973] 0x1e68 (0.95031132) -> 0x03e8 (0.97710007) + 0x03e903e8, // LUT[0974] 0x1e70 (0.95128800) -> 0x03e8 (0.97755641) | LUT[0975] 0x1e78 (0.95226468) -> 0x03e9 (0.97801248) + 0x03e903e9, // LUT[0976] 0x1e80 (0.95324136) -> 0x03e9 (0.97846831) | LUT[0977] 0x1e88 (0.95421804) -> 0x03e9 (0.97892387) + 0x03ea03ea, // LUT[0978] 0x1e90 (0.95519473) -> 0x03ea (0.97937919) | LUT[0979] 0x1e98 (0.95617141) -> 0x03ea (0.97983425) + 0x03eb03eb, // LUT[0980] 0x1ea0 (0.95714809) -> 0x03eb (0.98028905) | LUT[0981] 0x1ea8 (0.95812477) -> 0x03eb (0.98074361) + 0x03ec03ec, // LUT[0982] 0x1eb0 (0.95910145) -> 0x03ec (0.98119791) | LUT[0983] 0x1eb8 (0.96007813) -> 0x03ec (0.98165196) + 0x03ed03ed, // LUT[0984] 0x1ec0 (0.96105482) -> 0x03ed (0.98210575) | LUT[0985] 0x1ec8 (0.96203150) -> 0x03ed (0.98255930) + 0x03ee03ee, // LUT[0986] 0x1ed0 (0.96300818) -> 0x03ee (0.98301259) | LUT[0987] 0x1ed8 (0.96398486) -> 0x03ee (0.98346563) + 0x03ef03ef, // LUT[0988] 0x1ee0 (0.96496154) -> 0x03ef (0.98391843) | LUT[0989] 0x1ee8 (0.96593822) -> 0x03ef (0.98437097) + 0x03f003ef, // LUT[0990] 0x1ef0 (0.96691491) -> 0x03ef (0.98482326) | LUT[0991] 0x1ef8 (0.96789159) -> 0x03f0 (0.98527531) + 0x03f103f0, // LUT[0992] 0x1f00 (0.96886827) -> 0x03f0 (0.98572710) | LUT[0993] 0x1f08 (0.96984495) -> 0x03f1 (0.98617865) + 0x03f203f1, // LUT[0994] 0x1f10 (0.97082163) -> 0x03f1 (0.98662995) | LUT[0995] 0x1f18 (0.97179832) -> 0x03f2 (0.98708100) + 0x03f303f2, // LUT[0996] 0x1f20 (0.97277500) -> 0x03f2 (0.98753180) | LUT[0997] 0x1f28 (0.97375168) -> 0x03f3 (0.98798236) + 0x03f403f3, // LUT[0998] 0x1f30 (0.97472836) -> 0x03f3 (0.98843267) | LUT[0999] 0x1f38 (0.97570504) -> 0x03f4 (0.98888274) + 0x03f503f4, // LUT[1000] 0x1f40 (0.97668172) -> 0x03f4 (0.98933256) | LUT[1001] 0x1f48 (0.97765841) -> 0x03f5 (0.98978213) + 0x03f503f5, // LUT[1002] 0x1f50 (0.97863509) -> 0x03f5 (0.99023146) | LUT[1003] 0x1f58 (0.97961177) -> 0x03f5 (0.99068054) + 0x03f603f6, // LUT[1004] 0x1f60 (0.98058845) -> 0x03f6 (0.99112938) | LUT[1005] 0x1f68 (0.98156513) -> 0x03f6 (0.99157798) + 0x03f703f7, // LUT[1006] 0x1f70 (0.98254181) -> 0x03f7 (0.99202633) | LUT[1007] 0x1f78 (0.98351850) -> 0x03f7 (0.99247444) + 0x03f803f8, // LUT[1008] 0x1f80 (0.98449518) -> 0x03f8 (0.99292231) | LUT[1009] 0x1f88 (0.98547186) -> 0x03f8 (0.99336994) + 0x03f903f9, // LUT[1010] 0x1f90 (0.98644854) -> 0x03f9 (0.99381732) | LUT[1011] 0x1f98 (0.98742522) -> 0x03f9 (0.99426446) + 0x03fa03fa, // LUT[1012] 0x1fa0 (0.98840190) -> 0x03fa (0.99471136) | LUT[1013] 0x1fa8 (0.98937859) -> 0x03fa (0.99515802) + 0x03fb03fb, // LUT[1014] 0x1fb0 (0.99035527) -> 0x03fb (0.99560444) | LUT[1015] 0x1fb8 (0.99133195) -> 0x03fb (0.99605062) + 0x03fc03fb, // LUT[1016] 0x1fc0 (0.99230863) -> 0x03fb (0.99649656) | LUT[1017] 0x1fc8 (0.99328531) -> 0x03fc (0.99694226) + 0x03fd03fc, // LUT[1018] 0x1fd0 (0.99426199) -> 0x03fc (0.99738772) | LUT[1019] 0x1fd8 (0.99523868) -> 0x03fd (0.99783294) + 0x03fe03fd, // LUT[1020] 0x1fe0 (0.99621536) -> 0x03fd (0.99827793) | LUT[1021] 0x1fe8 (0.99719204) -> 0x03fe (0.99872268) + 0x03ff03fe, // LUT[1022] 0x1ff0 (0.99816872) -> 0x03fe (0.99916718) | LUT[1023] 0x1ff8 (0.99914540) -> 0x03ff (0.99961146) + 0x043703ff, // LUT[1024] 0x2000 (1.00012209) -> 0x03ff (1.00005549) | LUT[1025] 0x23ff (1.12501526) -> 0x0437 (1.05500332) +}; + +#endif diff --git a/target/ipod6/include/target/gpiodef.h b/target/ipod6/include/target/gpiodef.h new file mode 100644 index 0000000..cf9b07f --- /dev/null +++ b/target/ipod6/include/target/gpiodef.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPod6,x specific gpio -> pin mappings */ + +#include + +/* BOARD_REV mapping */ +#define BOARD_REV_DEV4 0x0e +#define BOARD_REV_PROTO2A 0x0e +#define BOARD_REV_PROTO2B 0x0d +#define BOARD_REV_PROTO2X_CARDINAL 0x0c +#define BOARD_REV_PROTO2B_ALT_CARBON 0x0b +#define BOARD_REV_PROTO2D 0x0a +#define BOARD_REV_PROTO2F 0x09 +#define BOARD_REV_EVT 0x08 +#define BOARD_REV_EVT_ALT_CARBON 0x07 +#define BOARD_REV_DVTb_ALT_CARBON 0x06 +#define BOARD_REV_DVTb_CARDINAL 0x05 +#define BOARD_REV_PVT_OPA2376 0x03 + +extern uint32_t ipod6_get_board_rev(); + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_ALT_BOOST_ID GPIOC(GPIO_AP, 5, 3) // GPIO11 +#define GPIO_SPU_TO_OPAL_CS_L GPIOC(GPIO_SPU, 5, 1) // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + +/* which IICs to initialize */ +#define IICS_MASK (3) + +#define TRISTAR_IIC_BUS (0) + +#define DISPLAY_PMU_IIC_BUS (1) + +/* Miscellaneous Pins */ +#define GPIO_PMU_LCD_RST (11) +#define PMU_LCD_PWR_VCI (5) +#define PMU_LCD_PWR_DVDD (0xe) +#define PMU_LDO_OPAL (0x8) + +/* + * support of video or command mode + */ +extern bool product_target_is_display_in_video_mode(); +extern uint32_t product_target_get_ulps_in_delay(void); +extern uint32_t product_target_get_ulps_end_delay(void); +extern uint32_t product_target_get_ulps_out_delay(void); +extern bool product_target_no_burst_mode(); + +#define TARGET_DISP_VIDEO_MODE product_target_is_display_in_video_mode() +#define TARGET_DSI_ULPS_IN_DELAY product_target_get_ulps_in_delay() +#define TARGET_DSI_ULPS_END_DELAY product_target_get_ulps_end_delay() +#define TARGET_DSI_ULPS_OUT_DELAY product_target_get_ulps_out_delay() +#define TARGET_NO_BURST_MODE product_target_no_burst_mode() +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/ipod6/include/target/powerconfig.h b/target/ipod6/include/target/powerconfig.h new file mode 100644 index 0000000..9463946 --- /dev/null +++ b/target/ipod6/include/target/powerconfig.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2238_BUCK2_VSEL, 0xc0 }, // M7 - Memory VDDQ and VDD2 Nominal Voltage +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2238_ALL_RAILS_CONF, 0x00 }, // enable SOC_VDD_ALL_RAILS_ON processing + { PMU_IIC_BUS, kD2238_GPIO14_CONF1, 0x93 }, // PMU register 0x041A needs to be changed to 0x93 during boot-up + { PMU_IIC_BUS, kD2238_GPIO12_CONF1, 0x00 }, // Display needs to be in reset + { PMU_IIC_BUS, kDIALOG_CHARGE_CONTROL_VSET, 0x3f }, // n27: PMU CV voltage needs to be changed from POR + { PMU_IIC_BUS, kD2238_SLOT_TIMINGS_PWR_HALT_UP5, 0x0 }, // HALT to ACTIVE power sequence 7ms instead of 4ms + { PMU_IIC_BUS, kD2238_SLOT_TIMINGS_PWR_HALT_UP6, 0x3 }, + { PMU_IIC_BUS, kD2238_BUCK2_VSEL_HALT, 0xB3 }, // M7 - Memory VDDQ and VDD2 Voltage changes to 1.16V in Halt/Hibernate +}; + +static const struct core_rails_struct soc_rails[] = +{ +}; + +static const struct core_rails_struct cpu_rails[] = +{ +}; + +static const struct core_rails_struct ram_rails[] = +{ +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 0 // rely on SOCF flag only +#define TARGET_PRECHARGE_GG_FLAG_MASK kHDQRegFlagsMaskSOCF +#define PRECHARGE_BACKLIGHT_LEVEL 517 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_FORCE_DEBUG_PRECHARGE 1 // always precharge if "debug" precharge bit set + +#define TARGET_CHARGER_HEADROOM 150 +#define TARGET_CHARGER_MAX_VRECT 7500 +#define TARGET_CHARGER_NEEDS_MAX_VRECT(rem_cap, max_cap) (((rem_cap) * 1000) <= ((max_cap) * 15)) /* 1.5% or lower */ + +#define ACC_PWR_LDO (0) // ACC_PWR not connected + +#endif diff --git a/target/ipod6/include/target/uartconfig.h b/target/ipod6/include/target/uartconfig.h new file mode 100644 index 0000000..517f4f8 --- /dev/null +++ b/target/ipod6/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (3) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/ipod6/init.c b/target/ipod6/init.c new file mode 100644 index 0000000..438b18d --- /dev/null +++ b/target/ipod6/init.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "init_fpga.h" +#include "init_product.h" +#include "init_sim.h" + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +#if !CONFIG_FPGA && !CONFIG_SIM + product_target_early_init(); +#endif +} + +void target_late_init(void) +{ +#if !CONFIG_FPGA && !CONFIG_SIM + product_target_late_init(); +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ +#if CONFIG_SIM + return sim_target_should_recover(); +#elif CONFIG_FPGA + return fpga_target_should_recover(); +#else + return product_target_should_recover(); +#endif +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if CONFIG_SIM + return sim_target_should_poweron(cold_button_boot); +#elif CONFIG_FPGA + return fpga_target_should_poweron(cold_button_boot); +#else + return product_target_should_poweron(cold_button_boot); +#endif +} + +bool target_should_poweroff(bool at_boot) +{ +#if CONFIG_SIM + return sim_target_should_poweroff(at_boot); +#elif CONFIG_FPGA + return fpga_target_should_poweroff(at_boot); +#else + return product_target_should_poweroff(at_boot); +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ +#if CONFIG_SIM + sim_target_setup_default_environment(); +#elif CONFIG_FPGA + fpga_target_setup_default_environment(); +#else + product_target_setup_default_environment(); +#endif +} + +#endif // WITH_ENV + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if CONFIG_SIM + return sim_target_update_device_tree(); +#elif CONFIG_FPGA + return fpga_target_update_device_tree(); +#else + return product_target_update_device_tree(); +#endif +} + +#endif // WITH_DEVICETREE diff --git a/target/ipod6/init_fpga.c b/target/ipod6/init_fpga.c new file mode 100644 index 0000000..8d57984 --- /dev/null +++ b/target/ipod6/init_fpga.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool fpga_target_should_recover(void) +{ + return false; +} + +bool fpga_target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool fpga_target_should_poweroff(bool at_boot) +{ + return false; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +#if WITH_ENV + +void fpga_target_setup_default_environment(void) +{ + env_set("boot-args", " debug=0x14e serial=3 amfi_unrestrict_task_for_pid=1 amfi_allow_any_signature=1 amfi_get_out_of_my_way=1 cs_enforcement_disable=1 no-dockfifo-uart=1", 0); + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "fpga-wsvga", 0); /* defaults to no display support */ + env_set("ramdisk-delay", "180000000", 0); /* This tells PurpleRestore to slow down; rdar://6345846 */ + env_set("idle-off", "false", 0); + env_set("bootdelay", "3", 0); + env_set("debug-uarts", "3", 0); +} + +#endif + +#if WITH_DEVICETREE + +int fpga_target_update_device_tree(void) +{ + return 0; +} + +#endif + +bool target_do_chargetrap(void) +{ + return false; +} + +bool target_needs_chargetrap(void) +{ + return false; +} + +#if !WITH_HW_POWER + +bool power_needs_thermal_trap(void) +{ + return false; +} + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/ipod6/init_fpga.h b/target/ipod6/init_fpga.h new file mode 100644 index 0000000..28cc1b3 --- /dev/null +++ b/target/ipod6/init_fpga.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _TARGET_INIT_FPGA_H +#define _TARGET_INIT_FPGA_H + +bool fpga_target_should_recover(void); +bool fpga_target_should_poweron(bool *cold_button_boot); +bool fpga_target_should_poweroff(bool at_boot); +void fpga_target_setup_default_environment(void); +int fpga_target_update_device_tree(void); + +#endif /* ! _TARGET_INIT_FPGA_H */ diff --git a/target/ipod6/init_product.c b/target/ipod6/init_product.c new file mode 100644 index 0000000..e825488 --- /dev/null +++ b/target/ipod6/init_product.c @@ -0,0 +1,1261 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#if WITH_HW_DOCKFIFO_UART || WITH_HW_DOCKFIFO_BULK +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOARD_TYPE_N27_AP (0xA) +#define BOARD_TYPE_N28_AP (0xC) +#define BOARD_TYPE_N27A_AP (0x2) +#define BOARD_TYPE_N28A_AP (0x4) + +#define BOARD_TYPE_N27_DEV (0xB) +#define BOARD_TYPE_N28_DEV (0xD) +#define BOARD_TYPE_N27A_DEV (0x3) +#define BOARD_TYPE_N28A_DEV (0x5) + +// Display panel type +typedef enum { + DISPLAY_PANEL_TYPE_UNKNOWN = 0, + DISPLAY_PANEL_TYPE_C1_DC, + DISPLAY_PANEL_TYPE_SLTSID, + DISPLAY_PANEL_TYPE_CRADLE, + DISPLAY_PANEL_TYPE_ALT_DISP_POC1, + DISPLAY_PANEL_TYPE_POR_DISP_S, + DISPLAY_PANEL_TYPE_POR_DISP_B, + DISPLAY_PANEL_TYPE_ALT_DISP_N31, + DISPLAY_PANEL_TYPE_POR_DISP_B_VID, + // Metadata + DISPLAY_PANEL_TYPE_COUNT +} display_panel_type; + +static const char *display_panel_types[] = { + "UNKNOWN", + "C1", + "C1", + "C1", + "C1", + "POR_DISP_S", + "POR_DISP_B", + "ALT_DISP_N31", + "POR_DISP_B_VID" +}; + +typedef enum { + DISPLAY_TOUCH_TYPE_UNKNOWN = 0, + DISPLAY_TOUCH_TYPE_T126_SALTYSID, + DISPLAY_TOUCH_TYPE_A1N27A_1_POC1, + DISPLAY_TOUCH_TYPE_A1N27A_1_PROTO2, + DISPLAY_TOUCH_TYPE_A1N28A_1_PROTO2, + // Metadata + DISPLAY_TOUCH_TYPE_COUNT +} display_touch_type; + +static const char *display_touch_types[] = { + "UNKNOWN", + "multi-touch,t126-saltysid", + "A1N27A,1-POC1", + "A1N27A,1-Proto2", + "A1N28A,1-Proto2" +}; + +// Display panel id sense pins +#define DISPLAY_TO_AP_ID0 GPIO( 17, 1) // RMII_CRSDV +#define DISPLAY_TO_AP_ID1 GPIO( 16, 7) // RMII_RXD_0 +#define DISPLAY_TO_AP_ID2 GPIO( 17, 0) // RMII_RXD_1 +#define DISPLAY_TO_AP_ID3 GPIO( 16, 4) // RMII_CLK + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; +static bool gpio_display_id_valid; +static display_panel_type display_panel; +static display_touch_type display_touch; + +static uint32_t display_config; + +uint32_t ipod6_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +bool ipod6_is_beryllium_supported() +{ + bool result = true; + + // On M7 DEV board configs, read ALT_BOOST_ID pin to check if Beryllium daughter card exists. + // DEV config: board-id == 1 + if (((rPMGR_SCRATCH0 >> 16) & 0xf) == 1) + result = gpio_read(GPIO_ALT_BOOST_ID); + + return result; +} + +static void ipod6_power_display(bool enable) +{ +#ifdef GPIO_PMU_LCD_PWR_EN + power_set_gpio(GPIO_PMU_LCD_PWR_EN, 1, 1); +#endif +#ifdef PMU_LCD_PWR_DVDD +#ifdef PMU_LCD_PWR_VCI + power_enable_ldo(PMU_LCD_PWR_DVDD, enable); + power_enable_ldo(PMU_LCD_PWR_VCI, enable); +#endif // PMU_LCD_PWR_VCI +#endif // PMU_LCD_PWR_DVDD +#ifdef GPIO_LCD_PWR_EN + gpio_write(GPIO_LCD_PWR_EN, enable); +#endif +} + +// The panel id pin mappings are desribed by the following id pin states: + +// ID0 ID1 ID2 ID3 Panel TOUCH +// ---- ---- ---- ---- ----- ------ +// PD PU PU X C1_DC +// PU PD PD X SLTSID +// PU PD PU X CRADLE +// PU PU PD PD ALT_DISP_POC1 +// PU PU PD PU POR_DISP_S +// PU PU PU PD POR_DISP_B +// PU PU PU PU ALT_DISP_N31 +// PD PU PU PD POR_DISP_B_VID + +static void ipod6_get_display_info(void) +{ + const char *id0; + const char *id1; + const char *id2; + const char *id3; + + if (target_config_ap()) { + switch (platform_get_board_id()) { + case BOARD_TYPE_N27_AP: + case BOARD_TYPE_N27A_AP: + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_S; + display_touch = DISPLAY_TOUCH_TYPE_A1N27A_1_PROTO2; + return; + case BOARD_TYPE_N28_AP: + case BOARD_TYPE_N28A_AP: + // Special case Cardinal BOARD_REV's display. + if ((ipod6_get_board_rev() == BOARD_REV_PROTO2X_CARDINAL) || + (ipod6_get_board_rev() == BOARD_REV_DVTb_CARDINAL)) + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B_VID; + else + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B; + + display_touch = DISPLAY_TOUCH_TYPE_A1N28A_1_PROTO2; + return; + } + } + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_IN); + gpio_configure(DISPLAY_TO_AP_ID1, GPIO_CFG_IN); + gpio_configure(DISPLAY_TO_AP_ID2, GPIO_CFG_IN); + gpio_configure(DISPLAY_TO_AP_ID3, GPIO_CFG_IN); + + gpio_configure_pupdn(DISPLAY_TO_AP_ID0, GPIO_PDN); + gpio_configure_pupdn(DISPLAY_TO_AP_ID1, GPIO_PDN); + gpio_configure_pupdn(DISPLAY_TO_AP_ID2, GPIO_PDN); + gpio_configure_pupdn(DISPLAY_TO_AP_ID3, GPIO_PDN); + + spin(100); // Wait 100us + + if (!gpio_read(DISPLAY_TO_AP_ID0)) { + id0 = "pd"; + if (gpio_read(DISPLAY_TO_AP_ID1)) { + id1 = "pu"; + if (gpio_read(DISPLAY_TO_AP_ID2)) { + id2 = "pu"; + if (!gpio_read(DISPLAY_TO_AP_ID3)) { + id3 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B_VID; + display_touch = DISPLAY_TOUCH_TYPE_A1N28A_1_PROTO2; + gpio_display_id_valid = true; + } else { + id3 = "pu"; + } + } else { + id2 = "pd"; + id3 = "not read"; + } + } else { + id1 = "pu"; + id2 = "not read"; + id3 = "not read"; + display_panel = DISPLAY_PANEL_TYPE_C1_DC; + display_touch = DISPLAY_TOUCH_TYPE_UNKNOWN; + gpio_display_id_valid = true; + } + } else { + id0 = "pu"; + + if (!gpio_read(DISPLAY_TO_AP_ID1)) { + id1 = "pd"; + id3 = "not read"; + if (!gpio_read(DISPLAY_TO_AP_ID2)) { + id2 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_SLTSID; + display_touch = DISPLAY_TOUCH_TYPE_T126_SALTYSID; + gpio_display_id_valid = true; + } else { + id2 = "pu"; + display_panel = DISPLAY_PANEL_TYPE_CRADLE; + display_touch = DISPLAY_TOUCH_TYPE_T126_SALTYSID; + gpio_display_id_valid = true; + } + } else { + id1 = "pu"; + if (!gpio_read(DISPLAY_TO_AP_ID2)) { + id2 = "pd"; + + if (!gpio_read(DISPLAY_TO_AP_ID3)) { + id3 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_ALT_DISP_POC1; + display_touch = DISPLAY_TOUCH_TYPE_A1N27A_1_POC1; + gpio_display_id_valid = true; + } else { + id3 = "pu"; + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_S; + display_touch = DISPLAY_TOUCH_TYPE_A1N27A_1_PROTO2; + gpio_display_id_valid = true; + } + } else { + id2 = "pu"; + if (!gpio_read(DISPLAY_TO_AP_ID3)) { + id3 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B; + display_touch = DISPLAY_TOUCH_TYPE_A1N28A_1_PROTO2; + gpio_display_id_valid = true; + } else { + id3 = "pu"; + display_panel = DISPLAY_PANEL_TYPE_ALT_DISP_N31; + display_touch = DISPLAY_TOUCH_TYPE_UNKNOWN; + gpio_display_id_valid = true; + } + } + } + } + + dprintf(DEBUG_INFO, "%s panel id pin state: id0=%s, id1=%s, id2=%s, id3=%s\n", + gpio_display_id_valid ? "" : "Unknown", id0, id1, id2, id3); + + ASSERT(display_panel < DISPLAY_PANEL_TYPE_COUNT); + ASSERT(display_touch < DISPLAY_TOUCH_TYPE_COUNT); + + dprintf(DEBUG_INFO, "Display panel = %s\nDisplay switch = %s\n", + display_panel_types[display_panel], + display_touch_types[display_touch]); + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_DFLT); + gpio_configure(DISPLAY_TO_AP_ID1, GPIO_CFG_DFLT); + gpio_configure(DISPLAY_TO_AP_ID2, GPIO_CFG_DFLT); + gpio_configure(DISPLAY_TO_AP_ID3, GPIO_CFG_DFLT); +} + +uint32_t target_get_display_panel_type(void) +{ + if (!gpio_display_id_valid) { + ipod6_get_display_info(); + } + + return display_panel; +} + +uint32_t target_get_display_touch_type(void) +{ + if (!gpio_display_id_valid) { + ipod6_get_display_info(); + } + + return display_touch; +} + +#if WITH_HW_POWER +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); +int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); + +static int product_pmu_gpiocfg(int gpiono, uint8_t conf1, uint8_t conf2) +{ + const uint16_t base=0x0400+(gpiono-1)*2; + + int rc=pmu_set_data( 0, base, conf1, 0 ); + if ( rc==0 ) rc=pmu_set_data( 0, base+1, conf2, 0 ); + + return rc; +} +#endif + +void product_target_early_init(void) +{ + // Get the display panel type. + //The display IDs need the display's rails to be turned on + ipod6_power_display(true); + ipod6_get_display_info(); + +#if WITH_HW_POWER + // M7: Configure binned voltages for M7 A1 parts + const uint32_t frev=chipid_get_fuse_revision(); + const uint32_t crev=chipid_get_chip_revision(); + if ( crev>=0x01 && frev>=0x03 ) { + uint8_t vsel=0; + + // bin is at bits 37-43 in fuse (or 7 bits in rCFG_FUSE1[5-11] ) + uint8_t bin=(rCFG_FUSE1>>5)&0x7f; + switch ( bin ) { + case 0x34: vsel=0x54; break; // bin1 + case 0x2f: vsel=0x4c; break; // bin2 + case 0x2a: vsel=0x44; break; // bin3 + default: /* warn? maybe... */ break; + } + + if ( vsel ) { + int rc=pmu_set_data( 0, 0x100, vsel, 1); // buck0_vsel + if ( rc==0 ) rc=pmu_set_data( 0, 0x101, vsel-0x10, 1); // buck0_vsel_alt, vsel-50mV + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: cannot change buck0_vsel* (%d)\n", rc); + } + } +#endif +} + +#define ENVAR_PWR_PATH "pwr-path" + +void product_target_late_init(void) +{ +#if WITH_HW_POWER + const uint32_t rev=ipod6_get_board_rev(); + + // Change behavior of PMU GPIO 13 (GPIO_DISABLE_PWR_PATH) + if ( rev<=BOARD_REV_PROTO2A ) { + + uint8_t level=0; +#if RELEASE_BUILD && PRODUCT_IBOOT + level=1; // disable debug power on customer builds by default +#endif + +#if WITH_ENV && PRODUCT_IBOOT + const char *boot_args = env_get("boot-args"); + if ( boot_args != NULL ) { + char *arg_str = strstr(boot_args, ENVAR_PWR_PATH"="); + if ( arg_str != NULL ) { + level = ( arg_str[strlen(ENVAR_PWR_PATH"=")] == '1' ); + } + } + // override with nvram environment variable (if it exists) + level = env_get_bool(ENVAR_PWR_PATH, level); + dprintf(DEBUG_CRITICAL, "PMU: pwr-path=%d\n", level); +#endif + int rc=product_pmu_gpiocfg(13, ( level<<1 ) | 0x1, 0x2 ); + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: pwr_path failed (%d)\n", rc); + } + + // PCVB syscfg key (radar 18950042) + // bytes 0-3 : Version number = 3 + // bytes 4-7 : CV offset in Volts, 4 byte fixed point decimal + // bytes 8-11 : buck0 offset in Volts, 4 byte fixed point decimal + // bytes 12-15 : buck1 offset in Volts, 4 byte fixed point decimal + SInt32 cal_data[4] = {0}; + syscfgCopyDataForTag('PCVB', (void*)&cal_data, 4*sizeof(SInt32)); + // Check key version + if (cal_data[0] >= 3) { + uint8_t data = 0; + SInt32 offset = 0; + // "CHG_CTRL_E = CHG_TRIM2 - ceiling[CV_offset*160]" + if (cal_data[1] > 0 && pmu_get_data(0, 0x4cb, &data) == 0) { + offset = cal_data[1] * 160; + data = (offset & 0xFFFF) ? data-(offset>>16)-1 : data-(offset>>16); + int rc=pmu_set_data(0, 0x4c4, data, 1); + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: cannot change chg_ctrl_e (%d)\n", rc); + } + // "BUCK0_VSEL = BUCK0_VSEL + ceiling[Buck0_offset*320]" + if (cal_data[2] > 0 && pmu_get_data(0, 0x100, &data) == 0) { + offset = cal_data[2] * 320; + data = (offset & 0xFFFF) ? data+(offset>>16)+1 : data+(offset>>16); + int rc=pmu_set_data(0, 0x100, data, 1); + if ( rc==0 ) rc=pmu_set_data( 0, 0x101, data-0x10, 1); // buck0_vsel_alt, vsel-50mV + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: cannot change buck0_vsel (%d)\n", rc); + } + // "BUCK1_VSEL = BUCK1_VSEL + ceiling[Buck1_offset*320]" + if (cal_data[3] > 0 && pmu_get_data(0, 0x120, &data) == 0) { + offset = cal_data[3] * 320; + data = (offset & 0xFFFF) ? data+(offset>>16)+1 : data+(offset>>16); + int rc=pmu_set_data(0, 0x120, data, 1); + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: cannot change buck1_vsel (%d)\n", rc); + } + } + + + // iBoot: need to dynamicall change UART2_BERMUDA_TO_AP_CTS_L from pulldown to pullup + // toggle VDD_MAIN_SW4 for bermuda, + if ( target_config_ap() && ( rev<=BOARD_REV_EVT ) ) { + int rc; + uint8_t data=0x7f; + + rc=pmu_set_data(0, 0x0085, data, 1); + if ( rc<0 ) { + dprintf(DEBUG_CRITICAL, "PMU: cannot enable VDD_MAIN_SW4 (%d)\n", rc); + } else { + task_sleep( 2 * 1000 ); // settle time + + data=0x3f; + rc=pmu_set_data(0, 0x0085, data, 1); + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: cannot disable VDD_MAIN_SW4 (%d)\n", rc); + + gpio_configure_pupdn(GPIO_BERMUDA_TO_AP_CTS, GPIO_PUP); + } + } + +#endif + + // Turn on DockFIFO clock gating + for(int i = 0; i < 8; i++) + { + dockfifo_enable_clock_gating(i); + } + + target_init_boot_manifest(); + + + // Cache Dali info into NVRAM + // platform_late_init() only occurs if we didn't chargetrap, so by this point + // we know for sure we have ASP NVRAM. + extern void target_init_fast_dali(); + target_init_fast_dali(); +} + +bool product_target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool product_target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + int result; + uint8_t error_stage; + + // in special case of rebooting from Dali, ignore button press + result = power_get_nvram(kPowerNVRAMiBootErrorStageKey, &error_stage); + if (result == 0 && error_stage == kPowerNVRAMiBootStagePrechargeReboot) { + boot_clear_error_count(); // don't generate a crash log for this + return true; + } + + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool product_target_should_poweroff(bool at_boot) +{ + static bool was_precharge_reboot = false; + +#if WITH_HW_POWER + // + // + // If rebooting out of Dali mode, the user could've initiated this action by holding down the power button. + // We do not want an extra-long hold of the power button to result in the device turning off. + + int result; + uint8_t error_stage; + + result = power_get_nvram(kPowerNVRAMiBootErrorStageKey, &error_stage); + + if (was_precharge_reboot || (result == 0 && error_stage == kPowerNVRAMiBootStagePrechargeReboot)) { + boot_clear_error_count(); // don't generate a crash log for this + +#if PRODUCT_IBOOT || PRODUCT_IBEC + // The error stage needs to be cleared because precharge reboot really isn't an error, + // but since this is called in a loop by the idleoff_task we need to remember that we are + // rebooting from Dali. + // + // Only clear the key in iBoot. In LLB, we need to preserve the error stage key as-is for the next stage. + was_precharge_reboot = true; + power_set_nvram(kPowerNVRAMiBootErrorStageKey, kPowerNVRAMiBootStageOff); +#endif + return false; + } +#endif + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +void * target_get_display_configuration(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + display_config = 0x00000971; + break; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + case DISPLAY_PANEL_TYPE_POR_DISP_B: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + display_config = 0x00000951; + break; + } + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void product_target_setup_default_environment(void) +{ + uint32_t panel_type_index; + + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + panel_type_index = target_get_display_panel_type(); + env_set("display-timing", display_panel_types[panel_type_index], 0); +#if !RELEASE_BUILD + env_set("diags-path", "/AppleInternal/Diags/bin/diag.img4", 0); + env_set("diags-vendor-path", "/AppleInternal/Diags/bin/diag-vendor.img4", 0); +#endif // !RELEASE_BUILD +} + +#endif // WITH_ENV + +bool product_target_is_display_in_video_mode(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return true; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + case DISPLAY_PANEL_TYPE_POR_DISP_B: + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return false; + } + + return false; +} + +bool product_target_no_burst_mode(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return true; + } + + return false; +} + +//The following 3 fuctions uses the values as defined in https://seg-docs.ecs.apple.com/projects/m7//release/specs/Apple/Top/M7_display_timing.xls +//“M7 Command Mode Timing†+// +uint32_t product_target_get_ulps_in_delay(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return 0; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + return 13056; + case DISPLAY_PANEL_TYPE_POR_DISP_B: + return 14976; + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return 19680; + } + + return false; +} + +uint32_t product_target_get_ulps_end_delay(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return 0; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + return 722538; + case DISPLAY_PANEL_TYPE_POR_DISP_B: + return 637035; + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return 584135; + } + + return false; +} + +uint32_t product_target_get_ulps_out_delay(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return 0; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + return 655913; + case DISPLAY_PANEL_TYPE_POR_DISP_B: + return 570410; + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return 517510; + } + + return false; +} + +#if WITH_DEVICETREE + +void display_update_device_tree() +{ +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c1/display-pmu"); +#endif + DTNode *disp0_node; + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + bool video_mode; + + video_mode = product_target_is_display_in_video_mode(); + // Find the DISP0 (display-subsystem 0) node + if (FindNode(0, "arm-io/disp0", &disp0_node)) { + propName = "video-mode"; + if (FindProperty(disp0_node, &propName, &propData, &propSize)) { + *((bool*)propData) = video_mode; + } + + propName = "esd-workaround"; + if (FindProperty(disp0_node, &propName, &propData, &propSize)) { + bool enable_esd_workaround = (target_config_ap() && ipod6_get_board_rev() <= BOARD_REV_EVT); + *((uint32_t*)propData) = enable_esd_workaround; + } + } + if (video_mode) { + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + propName = "supports-auto-ulps"; + //Do not turn on Auto ULPS on when on video mode + if (FindProperty(node, &propName, &propData, &propSize)) { + *((bool*)propData) = false; + } + } + } + +#if WITH_HW_DISPLAY_SUMMIT + DTNode *backlight_node; + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int summit_update_device_tree(DTNode *summit_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "backlight", &backlight_node); + summit_update_device_tree(node, disp0_node, backlight_node); + } +#endif //WITH_HW_DISPLAY_SUMMIT +} +void hid_update_device_tree() +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, MULTITOUCH_DTPATH, &node)) { + propName = "hid-fw-personality"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + strlcpy(propData, display_touch_types[display_touch], propSize); + } + propName = "orb-f-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('OFCl', propData, propSize); + } + propName = "orb-o-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('OOCl', propData, propSize); + } + propName = "orb-i-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('OICo', propData, propSize); + } + } +} + +static void spu_update_device_tree(void) +{ + const char* accel_path = "arm-io/spu/iop-spu-nub/accel"; + const char* gyro_path = "arm-io/spu/iop-spu-nub/gyro"; + const char* als_path = "arm-io/spu/iop-spu-nub/als"; + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + /* Accel Calibration */ + if (FindNode(0, accel_path, &node)) { + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('AICl', propData, propSize); + } + + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('ASCl', propData, propSize); + } + + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('ARot', propData, propSize); + } + + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('LTAO', propData, propSize); + } + + } + + /* Gyro Calibration */ + if (FindNode(0, gyro_path, &node)) { + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GICl', propData, propSize); + } + + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GSCl', propData, propSize); + } + + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GRot', propData, propSize); + } + + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GYTT', propData, propSize); + } + + propName = "gyro-trim-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GTCl', propData, propSize); + } + } + + /* ALS Calibration */ + if (FindNode(0, als_path, &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } +} + +static void opal_update_device_tree(void) +{ + const char* opal_path = "arm-io/opal"; + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, opal_path, &node)) { + propName = "li-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('LiCl', propData, propSize); + } + + propName = "pt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('PlCl', propData, propSize); + } + + propName = "device-board-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t*)(propData) = ipod6_get_board_rev(); + } + } +} + +static void audio_update_device_tree(const char* dtpath) +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, dtpath, &node)) { + propName = "actuator-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('TCal', propData, propSize); + } + propName = "codec-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('CCal', propData, propSize); + } + } +} + +static void charger_update_device_tree(void) +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, "arm-io/i2c0/ext-charger", &node)) { + // Cjay syscfg key (radar 18717802) + SeajayCal calData = { {0,0,0,0,0},{0,0,0,0,0} }; + syscfgCopyDataForTag('Cjay', (void*)&calData, sizeof(SeajayCal)); + // Check key version + if (calData.Hdr.Version >= SEAJAY_CAL_VERSION && calData.Hdr.Magic == SEAJAY_CAL_MAGIC && calData.Hdr.IsNotCalibrated == 0) { + if (calData.Item.Status & kCalStatus_Offset) { + propName = "vrect-calibrate-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + *((uint32_t*)propData) = calData.Item.Offset; + } + } + if (calData.Item.Status & kCalStatus_Gain) { + propName = "vrect-calibrate-gain"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + *((uint32_t*)propData) = calData.Item.Gain; + } + } + } + } +} + +static void device_material_update_device_tree(void) +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + DMin_t Dmin; + bzero(&Dmin, sizeof(Dmin)); + + // Look up the 'DMin' tag from syscfg. + // + // Determining which DMin to use: Pre-Monarch companion SW can't handle + // the N2xB configurations, so we had to "lie" in syscfg about the enclosure material + // + // On such configurations, the factory has put the true color in a DMin Override key 'DMnO'. + // If this key is present, we should use it instead of DMin. + int result = -1; + result = syscfgCopyDataForTag('DMnO', (uint8_t*)&Dmin, sizeof(Dmin)); + if (result > 0) { + // If we copied more than 0 bytes, DMnO was present. We should use it + dprintf(DEBUG_INFO, "DMin override key 'DMnO' found. Using it instead of DMin\n"); + } else { + result = syscfgCopyDataForTag('DMin', (uint8_t*)&Dmin, sizeof(Dmin)); + if (result < 0) { + dprintf(DEBUG_CRITICAL, "Unable to find DMin key in syscfg.\n"); + return; + } + } + if (Dmin.version != DMIN_VERSION_2) { + dprintf(DEBUG_CRITICAL, "DMin version %u is unspported.\n", (unsigned int)Dmin.version); + return; + } + if (FindNode(0, MULTITOUCH_DTPATH, &node)) { + /** + * DT property dmin key + * + * enc-top-type topEnclosure + * enc-bot-type botEnclosure + * fcm-type fcmType + * fcm-arcoated-type fcmARCoated + * fcm-inkcolor-type fcmInkColor + **/ + + propName = "enc-top-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.topEnclosure; + } + propName = "enc-bot-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.botEnclosure; + } + propName = "fcm-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.fcmType; + } + propName = "fcm-arcoated-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.fcmARCoated; + } + propName = "fcm-inkcolor-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.fcmInkColor; + } + + } + + const char* opal_path = "arm-io/opal"; + + if (FindNode(0, opal_path, &node)) { + /** + * Device Tree Key DMin Field + enc-top-type topEnclosure + enc-bot-type botEnclosure + bcm-window-type bcmWindow + bcm-lens-type bcmLens + pt-sensor-type bcmPTSensorType + pt-led-type bcmPTLEDType + lisa-opamp-type lisaOAType + lisa-sensor-ic lisaSensorIC + lisa-encoder-wheel lisaEncoderWheel + lisa-knurl lisaKnurl + **/ + propName = "enc-top-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.topEnclosure; + } + propName = "enc-bot-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.botEnclosure; + } + propName = "bcm-window-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmWindow; + } + propName = "bcm-lens-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmLens; + } + propName = "pt-sensor-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmPTSensorType; + } + propName = "pt-led-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmPTLEDType; + } + propName = "lisa-opamp-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaOAType; + } + propName = "lisa-sensor-ic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaSensorIC; + } + propName = "lisa-encoder-wheel"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaEncoderWheel; + } + propName = "lisa-knurl"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaKnurl; + } + + } + + const char* spu_path = "arm-io/spu"; + + if (FindNode(0, spu_path, &node)) { + propName = "pt-led-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmPTLEDType; + } + } + + if (FindNode(0, WIFI_DTPATH, &node)) { + /** + * DT property dmin key + * + * enc-top-type topEnclosure + * enc-bot-type botEnclosure + * fcm-type fcmType + **/ + + propName = "enc-top-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.topEnclosure; + } + propName = "enc-bot-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.botEnclosure; + } + propName = "fcm-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.fcmType; + } + + } + +} + +static void aggd_update_device_tree(void) +{ + // Add HW config info to allow for better data analysis + // + // We want carry aggd data correlated with hardware revision + // If we are building DEBUG/DEVELOPMENT, populate the DT with this info. + + DTNodePtr chosen; + uint32_t propSize; + char *propName; + void *propData; + + if (FindNode(0, "chosen", &chosen)) { + propName = "debug-board-revision"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { +#if !RELEASE_BUILD + *((uint32_t*)(propData)) = ipod6_get_board_rev(); +#else + propName[0] = '~'; +#endif + } + } +} + +static void stockholm_update_device_tree(void) +{ + DTNodePtr node; + uint32_t propSize; + char *propName; + void *propData; + + // Stockholm calibration + if (FindNode(0, "arm-io/uart2/stockholm", &node)) { + propName = "calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('NFCl', propData, propSize); + } + + // Bermuda dynamic CTS doesn't apply to DEV boards or pre-EVT devices. We will delete + // the dynamic pin assignment in that case. + if (!target_config_ap() || ipod6_get_board_rev() > BOARD_REV_EVT) { + if (FindNode(0, "arm-io/uart2", &node)) { + propName = "function-cts"; + if (FindProperty(node, &propName, &propData, &propSize)) + propName[0] = '~'; + } + } +} + +static void asp_update_device_tree(void) +{ + // hung writing large images to ASP boot block + + DTNodePtr chosen; + uint32_t propSize; + char *propName; + void *propData; + + if (FindNode(0, "defaults", &chosen)) { + propName = "llb-num-blks"; + if (FindProperty(chosen, &propName, &propData, &propSize)) { + *((uint32_t*)(propData)) = ASP_LLB_OVERRIDE_NUM_BLKS; + } + } +} + +int product_target_update_device_tree(void) +{ + + display_update_device_tree(); + + hid_update_device_tree(); + opal_update_device_tree(); + spu_update_device_tree(); + charger_update_device_tree(); + + audio_update_device_tree("arm-io/mca0/audio-actuator0"); + + device_material_update_device_tree(); + aggd_update_device_tree(); + stockholm_update_device_tree(); + asp_update_device_tree(); + + return target_pass_boot_manifest(); +} + +#endif // WITH_DEVICETREE + +bool target_needs_chargetrap(void) +{ + // Dali powertrap should only be considered in iBoot + return power_needs_precharge() || power_needs_thermal_trap(); +} + + +bool target_do_chargetrap(void) +{ +#if APPLICATION_IBOOT && PRODUCT_IBOOT + // Dali powertrap should only be considered in iBoot + if (target_needs_chargetrap()) { + dprintf(DEBUG_INFO, "Charge trap requested"); + + // Currently, Dali expects us to initialize the display. + // This requires two consecutive calls, just like in the main.c boot path. + platform_init_display(); + platform_init_display(); + int boot_dali_flash(void); + if (boot_dali_flash() < 0) + { + panic("Failed to boot dali but chargetrap was requested\n"); + } + return true; + } +#endif + return false; +} + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/ipod6/init_product.h b/target/ipod6/init_product.h new file mode 100644 index 0000000..83a04a8 --- /dev/null +++ b/target/ipod6/init_product.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _TARGET_INIT_PRODUCT_H +#define _TARGET_INIT_PRODUCT_H + +bool product_target_should_recover(void); +bool product_target_should_poweron(bool *cold_button_boot); +bool product_target_should_poweroff(bool at_boot); +void product_target_early_init(void); +void product_target_late_init(void); +void product_target_setup_default_environment(void); +int product_target_update_device_tree(void); + +#endif /* ! _TARGET_INIT_PRODUCT_H */ diff --git a/target/ipod6/init_sim.c b/target/ipod6/init_sim.c new file mode 100644 index 0000000..21efcc7 --- /dev/null +++ b/target/ipod6/init_sim.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool sim_target_should_recover(void) +{ + return false; +} + +bool sim_target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool sim_target_should_poweroff(bool at_boot) +{ + return false; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +#if WITH_ENV + +void sim_target_setup_default_environment(void) +{ + env_set("boot-args", "debug=0x14e serial=3 amfi=0x83 cs_enforcement_disable=1 -disable_aslr", ENV_PERSISTENT); + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "POR_DISP_B_VID", 0); + env_set("idle-off", "false", 0); +// env_set("kaslr-slide", "0x10000000", 0); + env_set("kaslr-off", "true", 0); + env_set("wifiaddr", "12:22:33:44:55:66", 0); + env_set("ethaddr", "12:22:33:44:55:77", 0); + env_set("btaddr", "00:00:00:00:00:00", 0); +} + +#endif + +bool product_target_is_display_in_video_mode(void) +{ + return true; +} + +#if WITH_DEVICETREE + +#define ROOT_DTPATH "" +int sim_target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Overwrite the serial-number with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "serial-number property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *serial = (uint64_t *)propData; + serial[0] = *(volatile uint64_t *)0x4a000040; + serial[1] = *(volatile uint64_t *)0x4a000048; + serial[2] = *(volatile uint64_t *)0x4a000050; + serial[3] = *(volatile uint64_t *)0x4a000058; + } + } + + // Overwrite the region-info with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "region-info"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "region-info property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *region = (uint64_t *)propData; + region[0] = *(volatile uint64_t *)0x4a000060; + region[1] = *(volatile uint64_t *)0x4a000068; + region[2] = *(volatile uint64_t *)0x4a000070; + region[3] = *(volatile uint64_t *)0x4a000078; + } + } + + if (FindNode(0, "arm-io/spu/iop-spu-nub", &node)) { + propName = "AAPL,ignore"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + + return 0; +} + +#endif + +bool target_do_chargetrap(void) +{ + return false; +} +bool target_needs_chargetrap(void) +{ + return false; +} + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} +bool power_needs_thermal_trap(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/ipod6/init_sim.h b/target/ipod6/init_sim.h new file mode 100644 index 0000000..46b0fda --- /dev/null +++ b/target/ipod6/init_sim.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _TARGET_INIT_SIM_H +#define _TARGET_INIT_SIM_H + +bool sim_target_should_recover(void); +bool sim_target_should_poweron(bool *cold_button_boot); +bool sim_target_should_poweroff(bool at_boot); +void sim_target_setup_default_environment(void); +int sim_target_update_device_tree(void); + +#endif /* ! _TARGET_INIT_SIM_H */ diff --git a/target/ipod6/pinconfig_evt.c b/target/ipod6/pinconfig_evt.c new file mode 100644 index 0000000..b62e3d6 --- /dev/null +++ b/target/ipod6/pinconfig_evt.c @@ -0,0 +1,566 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.4.1 + I/O Spreadsheet tracker: 15171729 + Conversion command: csvtopinconfig.py --radar 15171729 --soc m7 --prefix evt --copyright 2014-2015 +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_evt_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_DISABLED | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_OUT_0 | SLOW_SLEW, // 71 : GPIO[16] -> AP_TO_SEAJAY_I2C_SDA_ENABLE + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> GPIO_AP_TO_BSYNC_RESET_EN_L + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_IN | INPUT_SCHMITT, // 75 : TMR32_PWM2 -> DISP_BSYNC + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0 | INPUT_SCHMITT, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_evt_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_evt_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_DISABLED | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 71 : GPIO[16] -> AP_TO_SEAJAY_I2C_SDA_ENABLE + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> GPIO_AP_TO_BSYNC_RESET_EN_L + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_IN | INPUT_SCHMITT, // 75 : TMR32_PWM2 -> DISP_BSYNC + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0 | INPUT_SCHMITT, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_evt_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_evt_ap_0, pinconfig_evt_ap_1 } }, + { 1, 1, { pinconfig_evt_dev_0, pinconfig_evt_dev_1 } }, +}; + +const uint32_t * target_get_evt_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipod6/pinconfig_fpga.c b/target/ipod6/pinconfig_fpga.c new file mode 100644 index 0000000..7cbf29b --- /dev/null +++ b/target/ipod6/pinconfig_fpga.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +/* S7002 Target Pin Configuration */ + +static const uint32_t gpio_default_cfg[GPIO_0_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // SD_CLKOUT -> + CFG_DISABLED, // SD_CMD_IO -> + CFG_DISABLED, // SD_DATA_IO[0] -> + CFG_DISABLED, // SD_DATA_IO[1] -> + CFG_DISABLED, // SD_DATA_IO[2] -> + CFG_DISABLED, // SD_DATA_IO[3] -> + +/* Port 1 */ + CFG_DISABLED, // SDIO_IRQ -> + CFG_DISABLED, // WL_HOST_WAKE -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO3 -> BOOT_CONFIG[1] + CFG_DISABLED, // GPIO4 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO5 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO6 -> BOARD_ID[3] + CFG_DISABLED, // GPIO7 -> + +/* Port 5 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 6 */ + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + +/* Port 7 */ + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + +/* Port 8 */ + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART3_RTXD -> + CFG_DISABLED, // CLK32K_OUT -> + CFG_DISABLED, // TEST_CLKOUT -> + CFG_DISABLED, // GPIO16 -> + +/* Port 9 */ + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // TMR32_PWM3 -> + CFG_DISABLED, // DISP_TE -> + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // NAND_CEN[0] -> + +/* Port 10 */ + CFG_DISABLED, // NAND_CEN[1] -> + CFG_DISABLED, // NAND_IO[7] -> + CFG_DISABLED, // NAND_IO[6] -> + CFG_DISABLED, // NAND_IO[5] -> + CFG_DISABLED, // NAND_IO[4] -> + CFG_DISABLED, // NAND_DQS -> + CFG_DISABLED, // NAND_REN -> + CFG_DISABLED, // NAND_IO[3] -> + +/* Port 11 */ + CFG_DISABLED, // NAND_IO[2] -> + CFG_DISABLED, // NAND_IO[1] -> + CFG_DISABLED, // NAND_IO[0] -> + CFG_DISABLED, // NAND_WEN -> + CFG_DISABLED, // NAND_CLE -> + CFG_DISABLED, // NAND_ALE -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + +/* Port 12 */ + CFG_DISABLED, // DISPLAY_SYNC -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // SPI1_SCLK -> + +/* Port 13 */ + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // GPIO24 -> + +/* Port 14 */ + CFG_DISABLED, // GPIO25 -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 15 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_DISABLED, // ENET_MDC -> + CFG_DISABLED, // ENET_MDIO -> + CFG_DISABLED, // RMII_RXER -> + CFG_DISABLED, // RMII_TXEN -> + CFG_DISABLED, // RMII_CLK -> + CFG_DISABLED, // RMII_TXD[0] -> + CFG_DISABLED, // RMII_TXD[1] -> + CFG_DISABLED, // RMII_RXD[0] -> + +/* Port 17 */ + CFG_DISABLED, // RMII_RXD[1] -> + CFG_DISABLED, // RMII_RXD[0] -> + CFG_DISABLED, // RMII_CRSDV -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // REQUEST_DFU1 -> + CFG_DISABLED, // REQUEST_DFU2 -> + CFG_DISABLED, // DOCK_CONNECT -> + CFG_DISABLED, // CLK32K_IN -> + CFG_DISABLED, // SPU_UART0_TXD -> + CFG_DISABLED, // SPU_UART0_RXD -> + CFG_DISABLED, // SPU_UART0_RTSN -> + CFG_DISABLED, // SPU_UART0_CTSN -> + +/* Port 1 */ + CFG_DISABLED, // SPU_UART1_TXD -> + CFG_DISABLED, // SPU_UART1_RXD -> + CFG_DISABLED, // SPU_UART1_RTSN -> + CFG_DISABLED, // SPU_UART1_CTSN -> + CFG_DISABLED, // SPU_GPIO[0] -> + CFG_DISABLED, // SPU_GPIO[1] -> + CFG_DISABLED, // SPU_GPIO[2] -> + CFG_DISABLED, // SPU_GPIO[3] -> + +/* Port 2 */ + CFG_DISABLED, // SPU_GPIO[4] -> + CFG_DISABLED, // SPU_GPIO[5] -> + CFG_DISABLED, // SPU_GPIO[6] -> + CFG_DISABLED, // SPU_GPIO[7] -> + CFG_DISABLED, // SPU_GPIO[8] -> + CFG_DISABLED, // DFU_STATUS -> + CFG_DISABLED, // FORCE_DFU -> + CFG_DISABLED, // POWER_GOOD -> + +/* Port 3 */ + CFG_DISABLED, // SOC_VDD_HI_LO -> + CFG_DISABLED, // SOC_VDD_ALL_ON -> + CFG_DISABLED, // DOCK_ATTENTION -> + CFG_DISABLED, // PMU_HOST_WAKE -> + CFG_DISABLED, // SPU_SPI_SCLK -> + CFG_DISABLED, // SPU_SPI_MOSI -> + CFG_DISABLED, // SPU_SPI_MISO -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[0] -> + +/* Port 4 */ + CFG_DISABLED, // SPU_SPI_CS_TRIG[1] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[2] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[3] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[4] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[5] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[6] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[7] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[8] -> + +/* Port 5 */ + CFG_DISABLED, // SPU_SPI_CS_TRIG[9] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[10] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[11] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[12] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[13] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[14] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[15] -> + CFG_DISABLED, // SPU_GPIO[9] -> + +/* Port 6 */ + CFG_DISABLED, // SPU_I2C_SDA -> + CFG_DISABLED, // SPU_I2C_SCL -> + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 7 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 8 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // RESETN -> RESET_L + CFG_DISABLED, // JTAG_TRSTN -> + CFG_DISABLED, // JTAG_SEL -> + CFG_DISABLED, // JTAG_TCK -> + CFG_DISABLED, // JTAG_TMS -> + CFG_DISABLED, // JTAG_TRTCK -> + CFG_DISABLED, // JTAG_TDO -> + +/* Port 9 */ + CFG_DISABLED, // JTAG_TDI -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + switch (gpioc) { + case 0: + return gpio_default_cfg; + case 1: + return gpio_1_default_cfg; + default: + panic("unknown GPIO controller"); + } +} diff --git a/target/ipod6/pinconfig_product.c b/target/ipod6/pinconfig_product.c new file mode 100644 index 0000000..ea7d3ef --- /dev/null +++ b/target/ipod6/pinconfig_product.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +extern const uint32_t* target_get_proto2a_gpio_cfg(uint32_t gpioc); +extern const uint32_t* target_get_proto2b_gpio_cfg(uint32_t gpioc); +extern const uint32_t* target_get_evt_gpio_cfg(uint32_t gpioc); + +static bool board_rev_determined; +static bool use_dummy_pinconfig; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + // HACK: -- the first call into target_get_default_gpio_cfg() reads + // and attempts to restore BOARD_REV[3:0] to GPIO_CFG_DEFAULT. + // + // This will result in a recursive call back into target_get_default_gpio_cfg. + // To break the recursion, while determining board rev we can reply with any pinconfig + // since it's only being used for BOARD_REV[3:0] and it's CFG_DISABLED in all pinconfigs + // + // Remove this after we no longer have BOARD_REV-dependent pinconfigs. + if (use_dummy_pinconfig) + { + return target_get_proto2a_gpio_cfg(gpioc); + } + if (!board_rev_determined) + { + use_dummy_pinconfig = true; + (void)ipod6_get_board_rev(); + use_dummy_pinconfig = false; + + board_rev_determined = true; + } + + if (target_config_dev()) { + // Per radar 18904522 - dev board 0xF (dev3 board) has been depreciated, but this board + // rev settings will default to dev board 0xE (dev4 board) configuration + // Dev boards 0xE through 0xA are currently all based off the proto2b Dev config, per + // Board Rev tracker and email clarification from HW EE + if (ipod6_get_board_rev() >= 0xA) + return target_get_proto2b_gpio_cfg(gpioc); + else + panic("Unknown BOARD_REV 0x%x", ipod6_get_board_rev()); + } else { + // Per radar 18904522 - ProtoN AP products have been depreciated + // All that remains are post-ProtoN AP products. + // The story gets more complicated here -- see Board Rev tracker spreadsheet + switch (ipod6_get_board_rev()) + { + case BOARD_REV_PROTO2A: + return target_get_proto2a_gpio_cfg(gpioc); + break; + + case BOARD_REV_PROTO2B: + case BOARD_REV_PROTO2X_CARDINAL: + case BOARD_REV_PROTO2B_ALT_CARBON: + case BOARD_REV_PROTO2D: + case BOARD_REV_PROTO2F: + return target_get_proto2b_gpio_cfg(gpioc); + break; + case 0 ... BOARD_REV_EVT: + // For anything EVT or newer, use EVT pinconfig for now. + return target_get_evt_gpio_cfg(gpioc); + break; + default: + panic("Unknown board revision 0x%x", ipod6_get_board_rev()); + } + } + +} diff --git a/target/ipod6/pinconfig_proto2a.c b/target/ipod6/pinconfig_proto2a.c new file mode 100644 index 0000000..ac68c92 --- /dev/null +++ b/target/ipod6/pinconfig_proto2a.c @@ -0,0 +1,566 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.3.0 + I/O Spreadsheet tracker: None + Conversion command: csvtopinconfig.py --soc m7 --prefix proto2a +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_proto2a_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 46 : GPIO[14] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_IN, // 72 : GPIO[17] -> GPIO_SEAJAY_CLOAK_EN + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2a_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_DISABLED, // 17 : SPU_GPIO[5] -> NC_SPU_GPIO5 + CFG_OUT_0 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2a_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 46 : GPIO[14] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_IN, // 72 : GPIO[17] -> GPIO_SEAJAY_CLOAK_EN + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2a_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_DISABLED, // 17 : SPU_GPIO[5] -> NC_SPU_GPIO5 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_proto2a_ap_0, pinconfig_proto2a_ap_1 } }, + { 1, 1, { pinconfig_proto2a_dev_0, pinconfig_proto2a_dev_1 } }, +}; + +const uint32_t * target_get_proto2a_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipod6/pinconfig_proto2b.c b/target/ipod6/pinconfig_proto2b.c new file mode 100644 index 0000000..07d6c32 --- /dev/null +++ b/target/ipod6/pinconfig_proto2b.c @@ -0,0 +1,566 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.3.6 + I/O Spreadsheet tracker: 15171729 + Conversion command: csvtopinconfig.py --soc m7 --radar 15171729 --prefix proto2b +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_proto2b_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> TP_AP_GPIO17 + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2b_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | INPUT_SCHMITT, // 3 : CLK32K_IN -> GPIO_PMU_TO_SPU_CLK32K_IN + CFG_OUT_0 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2b_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> TP_AP_GPIO17 + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2b_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | INPUT_SCHMITT, // 3 : CLK32K_IN -> GPIO_PMU_TO_SPU_CLK32K_IN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_proto2b_ap_0, pinconfig_proto2b_ap_1 } }, + { 1, 1, { pinconfig_proto2b_dev_0, pinconfig_proto2b_dev_1 } }, +}; + +const uint32_t * target_get_proto2b_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/ipod6/pinconfig_sim.c b/target/ipod6/pinconfig_sim.c new file mode 100644 index 0000000..c2917c8 --- /dev/null +++ b/target/ipod6/pinconfig_sim.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +/* S7002 Target Pin Configuration */ + +static const uint32_t gpio_default_cfg[GPIO_0_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // SD_CLKOUT -> + CFG_DISABLED, // SD_CMD_IO -> + CFG_DISABLED, // SD_DATA_IO[0] -> + CFG_DISABLED, // SD_DATA_IO[1] -> + CFG_DISABLED, // SD_DATA_IO[2] -> + CFG_DISABLED, // SD_DATA_IO[3] -> + +/* Port 1 */ + CFG_DISABLED, // SDIO_IRQ -> + CFG_DISABLED, // WL_HOST_WAKE -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO3 -> BOOT_CONFIG[1] + CFG_DISABLED, // GPIO4 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO5 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO6 -> BOARD_ID[3] + CFG_DISABLED, // GPIO7 -> + +/* Port 5 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 6 */ + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + +/* Port 7 */ + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + +/* Port 8 */ + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART3_RTXD -> + CFG_DISABLED, // CLK32K_OUT -> + CFG_DISABLED, // TEST_CLKOUT -> + CFG_DISABLED, // GPIO16 -> + +/* Port 9 */ + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // TMR32_PWM3 -> + CFG_DISABLED, // DISP_TE -> + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // NAND_CEN[0] -> + +/* Port 10 */ + CFG_DISABLED, // NAND_CEN[1] -> + CFG_DISABLED, // NAND_IO[7] -> + CFG_DISABLED, // NAND_IO[6] -> + CFG_DISABLED, // NAND_IO[5] -> + CFG_DISABLED, // NAND_IO[4] -> + CFG_DISABLED, // NAND_DQS -> + CFG_DISABLED, // NAND_REN -> + CFG_DISABLED, // NAND_IO[3] -> + +/* Port 11 */ + CFG_DISABLED, // NAND_IO[2] -> + CFG_DISABLED, // NAND_IO[1] -> + CFG_DISABLED, // NAND_IO[0] -> + CFG_DISABLED, // NAND_WEN -> + CFG_DISABLED, // NAND_CLE -> + CFG_DISABLED, // NAND_ALE -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + +/* Port 12 */ + CFG_DISABLED, // DISPLAY_SYNC -> + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> + CFG_DISABLED, // UART0_TXD -> + CFG_DISABLED, // UART0_RXD -> + CFG_DISABLED, // SPI1_SCLK -> + +/* Port 13 */ + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // GPIO24 -> + +/* Port 14 */ + CFG_DISABLED, // GPIO25 -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 15 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_DISABLED, // ENET_MDC -> + CFG_DISABLED, // ENET_MDIO -> + CFG_DISABLED, // RMII_RXER -> + CFG_DISABLED, // RMII_TXEN -> + CFG_DISABLED, // RMII_CLK -> + CFG_DISABLED, // RMII_TXD[0] -> + CFG_DISABLED, // RMII_TXD[1] -> + CFG_DISABLED, // RMII_RXD[0] -> + +/* Port 17 */ + CFG_DISABLED, // RMII_RXD[1] -> + CFG_DISABLED, // RMII_RXD[0] -> + CFG_DISABLED, // RMII_CRSDV -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_DISABLED, // REQUEST_DFU1 -> + CFG_DISABLED, // REQUEST_DFU2 -> + CFG_DISABLED, // DOCK_CONNECT -> + CFG_DISABLED, // CLK32K_IN -> + CFG_DISABLED, // SPU_UART0_TXD -> + CFG_DISABLED, // SPU_UART0_RXD -> + CFG_DISABLED, // SPU_UART0_RTSN -> + CFG_DISABLED, // SPU_UART0_CTSN -> + +/* Port 1 */ + CFG_DISABLED, // SPU_UART1_TXD -> + CFG_DISABLED, // SPU_UART1_RXD -> + CFG_DISABLED, // SPU_UART1_RTSN -> + CFG_DISABLED, // SPU_UART1_CTSN -> + CFG_DISABLED, // SPU_GPIO[0] -> + CFG_DISABLED, // SPU_GPIO[1] -> + CFG_DISABLED, // SPU_GPIO[2] -> + CFG_DISABLED, // SPU_GPIO[3] -> + +/* Port 2 */ + CFG_DISABLED, // SPU_GPIO[4] -> + CFG_DISABLED, // SPU_GPIO[5] -> + CFG_DISABLED, // SPU_GPIO[6] -> + CFG_DISABLED, // SPU_GPIO[7] -> + CFG_DISABLED, // SPU_GPIO[8] -> + CFG_DISABLED, // DFU_STATUS -> + CFG_DISABLED, // FORCE_DFU -> + CFG_DISABLED, // POWER_GOOD -> + +/* Port 3 */ + CFG_DISABLED, // SOC_VDD_HI_LO -> + CFG_DISABLED, // SOC_VDD_ALL_ON -> + CFG_DISABLED, // DOCK_ATTENTION -> + CFG_DISABLED, // PMU_HOST_WAKE -> + CFG_DISABLED, // SPU_SPI_SCLK -> + CFG_DISABLED, // SPU_SPI_MOSI -> + CFG_DISABLED, // SPU_SPI_MISO -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[0] -> + +/* Port 4 */ + CFG_DISABLED, // SPU_SPI_CS_TRIG[1] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[2] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[3] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[4] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[5] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[6] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[7] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[8] -> + +/* Port 5 */ + CFG_DISABLED, // SPU_SPI_CS_TRIG[9] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[10] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[11] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[12] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[13] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[14] -> + CFG_DISABLED, // SPU_SPI_CS_TRIG[15] -> + CFG_DISABLED, // SPU_GPIO[9] -> + +/* Port 6 */ + CFG_DISABLED, // SPU_I2C_SDA -> + CFG_DISABLED, // SPU_I2C_SCL -> + CFG_DISABLED, // WDOG -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 7 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 8 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // RESETN -> RESET_L + CFG_DISABLED, // JTAG_TRSTN -> + CFG_DISABLED, // JTAG_SEL -> + CFG_DISABLED, // JTAG_TCK -> + CFG_DISABLED, // JTAG_TMS -> + CFG_DISABLED, // JTAG_TRTCK -> + CFG_DISABLED, // JTAG_TDO -> + +/* Port 9 */ + CFG_DISABLED, // JTAG_TDI -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + switch (gpioc) { + case 0: + return gpio_default_cfg; + case 1: + return gpio_1_default_cfg; + default: + panic("unknown GPIO controller"); + } +} diff --git a/target/ipod6/properties.c b/target/ipod6/properties.c new file mode 100644 index 0000000..1ac9897 --- /dev/null +++ b/target/ipod6/properties.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/ipod6/rules.mk b/target/ipod6/rules.mk new file mode 100644 index 0000000..1d76b8c --- /dev/null +++ b/target/ipod6/rules.mk @@ -0,0 +1,98 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2238=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_PMU_DEV_ID=0x78 \ + AMC_NUM_CHANNELS=1 \ + AMC_NUM_RANKS=1 \ + TARGET_DSIM_DPHYCTL=0x00003000 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_UP_CODE=0x1 \ + TARGET_DSIM_DOWN_CODE=0x1 \ + TARGET_DSIM_SUPPRESS=0x1 \ + TARGET_USES_GP_CM=1 \ + WITH_TARGET_CHARGETRAP=1 \ + WITH_DALI=1 \ + WIFI_DTPATH=\"arm-io/sdio\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + MULTITOUCH_DTPATH=\"arm-io/multi-touch\" + +ifeq ($(CONFIG_SIM),true) + OPTIONS += \ + CONFIG_SIM=1 \ + AMP_CALIBRATION_SKIP=1 +endif + +ifeq ($(CONFIG_FPGA),true) + OPTIONS += \ + CONFIG_FPGA=1 \ + DISPLAY_FPGA_TUNABLES=1 \ + SUPPORT_FPGA=1 \ + AMP_CALIBRATION_SKIP=1 \ + WITH_TARGET_AMC_PARAMS=1 \ + WITH_TARGET_AMP_PARAMS=1 +endif + +ifeq ($(NO_WFI),true) +OPTIONS += \ + NO_ARM_HALT=1 +endif + +ifeq ($(RECOVERY_MODE_IBSS),true) +OPTIONS += \ + WITH_RECOVERY_MODE_IBSS=1 +endif + +ifeq ($(PRODUCT),LLB) +# iBoot on M7 is in block 0, so LLB needs to expose the "anc_llb" block device. +OPTIONS += \ + WITH_LLB_BLKDEV=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/target_prepare_dali.o + +ifeq ($(CONFIG_SIM),true) + ALL_OBJS += $(LOCAL_DIR)/init_sim.o \ + $(LOCAL_DIR)/pinconfig_sim.o +else + ifeq ($(CONFIG_FPGA),true) + ALL_OBJS += $(LOCAL_DIR)/init_fpga.o \ + $(LOCAL_DIR)/pinconfig_fpga.o + else + + ALL_OBJS += $(LOCAL_DIR)/init_product.o \ + $(LOCAL_DIR)/pinconfig_product.o \ + $(LOCAL_DIR)/pinconfig_proto2a.o \ + $(LOCAL_DIR)/pinconfig_proto2b.o \ + $(LOCAL_DIR)/pinconfig_evt.o + + ifneq ($(PRODUCT),LLB) + ALL_OBJS += \ + $(LOCAL_DIR)/properties.o + endif + + endif +endif + +ifeq ($(PRODUCT),iBoot) +# Fast NVRAM driver may be used by iBoot +OPTIONS += \ + WITH_LLB_NVRAM=1 \ + WITH_LLB_BLKDEV=1 +endif diff --git a/target/ipod6/target_prepare_dali.c b/target/ipod6/target_prepare_dali.c new file mode 100644 index 0000000..00142b3 --- /dev/null +++ b/target/ipod6/target_prepare_dali.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + kRTKitArgBlockVersion1 = 'RTK1', + kDaliFWArgVersion1 = 'DAL1', + kDaliFWArgVersion2 = 'DAL2', + kDaliFWArgVersion3 = 'DAL3', + kDaliFWArgVersion4 = 'DAL4' +}; + + +enum +{ + kMode24hEnabledOffset = 0, + kRotateScreenOffset = 1, + kDaliDarkWakeOffset = 2, /* 0 = normal wake, 1 = scheduled thermal wake, don't paint screen */ + kPmuDebugOffset = 3, + kIsChargerConnectedOffset = 4, + kPrechargeNeededOffset = 5 +}; + +#define kUTCOffsetUnsetValue 0x7fffffffffffffffLL /* INT64_MAX. There's only 86400 seconds in a day */ + +typedef struct dali_payload_t { + uint32_t magic; /* = kDaliFWArgVersion3 */ + uint32_t reserved; + uint8_t charFlags[8]; + int64_t utcOffset; /* Set to either a valid offset, or kUTCOffsetUnsetValue if unset */ + + DMin_t dmin; +} dali_payload_t; + +typedef struct dali_args_t { + uint32_t magic; /* = kRTKitArgBlockVersion1 */ + uint32_t size; /* size of pending payload */ + dali_payload_t payload; +} dali_args_t; + +#define kDMinNVRAMKey "device-material" + +static void save_dmin_to_nvram(const DMin_t* dmin) +{ + #if WITH_LLB_NVRAM + if (target_needs_chargetrap()) + panic("LLB NVRAM is read-only, it's a logic error to cache NVRAM here"); + #endif + char dmin_ascii[2*sizeof(DMin_t) + 1]; + const char* dmin_buffer = (const char*)(dmin); + + for(unsigned long i = 0; i < sizeof(DMin_t); i++) + { + snprintf(dmin_ascii + 2*i, sizeof(dmin_ascii) - 2*i, "%02X", dmin_buffer[i]); + } + dmin_ascii[2*sizeof(DMin_t)] = '\0'; + env_set(kDMinNVRAMKey, dmin_ascii, ENV_PERSISTENT); + // dprintf(DEBUG_INFO, "save_dmin_to_nvram: Set kDMinNVRAMKey = %s\n", dmin_ascii); +} + +static int get_dmin_from_nvram(DMin_t* dest_dmin) +{ + char* dest_buf = (char*)(dest_dmin); + const char* dmin_val = env_get(kDMinNVRAMKey); + + if (dmin_val == NULL) { + // dprintf(DEBUG_INFO, "No DMin cached in NVRAM yet\n"); + return -1; + } + + unsigned int dmin_len = (unsigned int)strlen(dmin_val); + + if (dmin_len > 2*sizeof(DMin_t) || (dmin_len & 0x1)) { + dprintf(DEBUG_CRITICAL, "Unexpected DMin key length %u, expected even and <= %zu\n", dmin_len, 2*sizeof(DMin_t)); + return -2; + } + + unsigned long i = 0; + unsigned long p = 0; + while ( i < dmin_len ) { + unsigned char byte = 0; + for (int j = 0; j < 2; j++) { + int shift_factor = 4*(1-j); + + switch(dmin_val[i]) { + case '0' ... '9': + byte += (dmin_val[i] - '0') << shift_factor; + break; + case 'A' ... 'F': + byte += ((dmin_val[i] - 'A') + 10) << shift_factor; + break; + default: + dprintf(DEBUG_CRITICAL, "Non-hex digit in DMin NVRAM key: 0x%x\n", dmin_val[i]); + return -3; + } + i++; + } + dest_buf[p++] = byte; + } + return 0; +} + +void +target_init_fast_dali() +{ + DMin_t dmin; + bzero(&dmin, sizeof(DMin_t)); + syscfgCopyDataForTag('DMin', (uint8_t*)&(dmin), sizeof(DMin_t)); + save_dmin_to_nvram(&dmin); +} + + + +static bool is_dark_wake() +{ + bool powersupply_change_event, button_event, other_wake_event; + pmu_check_events(&powersupply_change_event, &button_event, &other_wake_event); + dprintf(DEBUG_INFO, "is_dark_wake: ps_changed = %d, button = %d, other = %d\n", powersupply_change_event, button_event, other_wake_event); + return !powersupply_change_event && !button_event; +} + +void* +target_prepare_dali(void) +{ +#if defined(PMU_LDO_OPAL) && WITH_HW_POWER + // Interim Solution: Turn off LDO8 in Dali mode/iBoot + // Opal uses a lot of power when held in reset. For sure we don't need it in Dali. + power_enable_ldo(PMU_LDO_OPAL, false); +#endif +#ifdef GPIO_SPU_TO_OPAL_CS_L + gpio_configure(GPIO_SPU_TO_OPAL_CS_L, GPIO_CFG_IN); +#endif + dali_args_t* args = (dali_args_t *)PANIC_BASE; + bzero(args, sizeof(dali_args_t)); + + args->magic = kRTKitArgBlockVersion1; + args->size = sizeof(dali_payload_t); + + args->payload.magic = kDaliFWArgVersion3; + args->payload.charFlags[kMode24hEnabledOffset] = (env_get_uint("dali-24h-mode", 0) == 1); + args->payload.charFlags[kRotateScreenOffset] = (env_get_uint("display-rotation", 0) == 1); + args->payload.charFlags[kPmuDebugOffset] = (env_get_uint("dali-pmu-debug", 0) == 1); +#if WITH_HW_POWER + args->payload.charFlags[kDaliDarkWakeOffset] = (is_dark_wake()); + args->payload.charFlags[kIsChargerConnectedOffset] = (power_has_usb()); + args->payload.charFlags[kPrechargeNeededOffset] = (power_needs_precharge()); + dprintf(DEBUG_INFO, "Charger Connected: %d, Precharge needed: %d\n", (int)args->payload.charFlags[kIsChargerConnectedOffset], (int)args->payload.charFlags[kPrechargeNeededOffset]); +#endif + + if (get_dmin_from_nvram(&(args->payload.dmin)) < 0) { + dprintf(DEBUG_CRITICAL, "Unable to find DMin in NVRAM; booting into Dali mode with potentially incorrect DMin information!\n"); + } + + args->payload.utcOffset = kUTCOffsetUnsetValue; + const char* utcOffsetStr = env_get("utc-offset"); + if (utcOffsetStr) { + args->payload.utcOffset = atoi(utcOffsetStr); + } + + return args; +} diff --git a/target/j105/include/target/adbe_settings.h b/target/j105/include/target/adbe_settings.h new file mode 100644 index 0000000..9436504 --- /dev/null +++ b/target/j105/include/target/adbe_settings.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x000e, + .adbe0_vblank_clk_gate_wakeup = 0x000e, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/j105/include/target/aspnandconfig.h b/target/j105/include/target/aspnandconfig.h new file mode 100644 index 0000000..ebe12ed --- /dev/null +++ b/target/j105/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/j105/include/target/gpiodef.h b/target/j105/include/target/gpiodef.h new file mode 100644 index 0000000..8a2b65d --- /dev/null +++ b/target/j105/include/target/gpiodef.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* j105 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 26, 0) // 208 : GPIO[34] -> SOC_BRD_REV0 +#define GPIO_BOARD_REV1 GPIO( 26, 1) // 209 : GPIO[35] -> SOC_BRD_REV1 +#define GPIO_BOARD_REV2 GPIO( 26, 2) // 210 : GPIO[36] -> SOC_BRD_REV2 +#define GPIO_BOARD_REV3 GPIO( 26, 3) // 211 : GPIO[37] -> SOC_BRD_REV3 + +#define GPIO_S3E_BOOT_FROM_HOST GPIO_ID(31) // 31 : GPIO[43] -> SOC_NAND_FW_STRAP + +/* which IICs to initialize */ +#define IICS_MASK (0xF) // i2c0, i2c1, i2c2, i2c3 + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/j105/include/target/powerconfig.h b/target/j105/include/target/powerconfig.h new file mode 100644 index 0000000..6e210c8 --- /dev/null +++ b/target/j105/include/target/powerconfig.h @@ -0,0 +1,85 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 1 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + // j105: make sure spi control of buck1 is enabled + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA }, // Enable Test Mode + { PMU_IIC_BUS, kD2255_EN_CMD3, 0xfd}, // Enable SPI access for BUCK1 + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS }, // Disable Test Mode + { PMU_IIC_BUS, kD2255_EN_CMD0, 0x02}, // enable control of Buck1 via spi (dwi) + { PMU_IIC_BUS, kD2255_SPI_CTRL, 0x01}, // global dwi control enable + + // j105: update iBoot PMU overrides in IO spreadsheet + { PMU_IIC_BUS, kD2255_OUT_32K, 0x49 }, // OUT_32K active, VBUCK3, PP +}; + +// PMU Power overview docs can be found at: +// J105: ERS Power Chapter Tracker + +// For now we rely on the OTP settings being right and don't override these + +static const struct core_rails_struct soc_rails[] = +{ +}; + +static const struct core_rails_struct cpu_rails[] = +{ +}; + +// it's VDD FIXED! used for RAM inside the SOC +static const struct core_rails_struct ram_rails[] = +{ +}; + +// CLPC does power management using this table via the +// power_get_rail_value api +// +// 1st field is index into the ldo_params array in the pmu specific header file. +// 2nd field is low value in millivolts +// 3rd field is high value in millivoltes +// 4th is step size in microvolts +// +// this is indexed with POWER_RAIL_*, I really just need to use the index in LDO[] +target_rails_t target_rails = { + { 0x0F, 500, 1296, 3125 }, // POWER_RAIL_CPU, BUCK0 + { 0x14, 600, 1396, 3125 }, // POWER_RAIL_VDD_FIXED BUCK5 + { 0x11, 600, 1396, 3125 }, // POWER_RAIL_SOC, BUCK2 + + { 0x16, 600, 1396, 3125 }, // POWER_RAIL_CPU_RAM, BUCK7 + { 0x10, 500, 1296, 3125 }, // POWER_RAIL_GPU, BUCK1 + { 0x17, 600, 1396, 3125 }, // POWER_RAIL_GPU_RAM, BUCK8 +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 + +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/j105/include/target/uartconfig.h b/target/j105/include/target/uartconfig.h new file mode 100644 index 0000000..1ac4380 --- /dev/null +++ b/target/j105/include/target/uartconfig.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +//#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/j105/init.c b/target/j105/init.c new file mode 100644 index 0000000..159a262 --- /dev/null +++ b/target/j105/init.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Board ids +#define J105_AP_BOARD_ID (0x04) +#define J105_DEV_BOARD_ID (0x05) + +// Board revs +//#define J105_DEV0_BOARD_REV (0x0) + +// Do not delay iBoot by more than this amount from power on (microseconds). +// Give up waiting for a boot logo and carry on at this point. +#define kDPDeviceStartTimeout (8 * 1000 * 1000) +extern utime_t gPowerOnTime; +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#if WITH_HW_DISPLAY_DISPLAYPORT +static dp_t dp_link_config = { + .mode = kDPControllerMode_Slave, + .type = kDPControllerType_DP, + .min_link_rate = kLinkRate270Gbps, + .max_link_rate = kLinkRate270Gbps, + .lanes = 2, + .ssc = 0, + .alpm = 0, + .vrr_enable = 0, + .vrr_on = 0, + .fast_link_training = true, +}; +#endif +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static uint32_t j105_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + + printf("board_rev 0x%x\n", gpio_board_rev); + + } + + return gpio_board_rev; +} + +void target_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + dprintf(DEBUG_INFO, "%s: chip rev: %d, fuse: %d\n", __func__, + chipid_get_chip_revision(), chipid_get_fuse_revision()); + + // target_fixup_pmu(); +#endif +} + +void target_late_init(void) +{ +#if 0 + if (target_config_dev() && j105_get_board_rev() > J105_DEV_BOARD_LAST) { + platform_not_supported(); + } + if (target_config_ap() && j105_get_board_rev() < J105_AP_BOARD_FIRST) { + platform_not_supported(); + } +#endif + +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#if WITH_HW_DISPLAY_DISPLAYPORT + // Backgrounded. See dp_device_wait_started() call below. + displayport_init(&dp_link_config); +#endif +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_debug_init(void) +{ + return 0; +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DIAGS: +#if WITH_HW_DISPLAY_DISPLAYPORT && PRODUCT_IBOOT + /* Potentially delay boot so we have a + * logo. We might have to do this if a + * connected TV is particularly slow at + * responding to EDID. Sorry. */ + dp_device_wait_started(gPowerOnTime + kDPDeviceStartTimeout); +#endif + break; + case BOOT_DARWIN_RESTORE: + break; + default: + // do nothing + break; + } + + return 0; +} + +bool target_should_recover(void) +{ + // trigger recovery mode whenever USB is attached, unless + // environment variable says otherwise. + + return power_has_usb() && !env_get_bool("auto-boot-usb", true); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + // always powers on + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + // never power off + return false; +} + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#if WITH_HW_DISPLAY_DISPLAYPORT + return ((void *)(&dp_link_config)); +#endif +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "720p", 0); + env_set("idle-off", "false", 0); // do not idle off; there is no battery and this will just reboot (8035422) + env_set("adbe-tunables", "default", 0); + env_set("adfe-tunables", "720p", 0); +} + +#endif // WITH_ENV + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Update the pmu node with the actual vcore values + if (FindNode(0, "arm-io/i2c1/pmu", &node)) { + propName = "swi-vcores"; + if (FindProperty(node, &propName, &propData, &propSize)) { + platform_get_soc_voltages(propSize / sizeof(u_int32_t), propData); + } + } + + // Store RBDA (Remote Bluetooth Device Address) into products node + if (FindNode(0, "product", &node)) { + propName = "bluetooth-dev-addr0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("rbdaddr0")) { + env_get_ethaddr("rbdaddr0", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_BLUETOOTH_DEV_MACADDR0, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + return 0; +} + +#endif // WITH_DEVICETREE + diff --git a/target/j105/pinconfig.c b/target/j105/pinconfig.c new file mode 100644 index 0000000..2e002a1 --- /dev/null +++ b/target/j105/pinconfig.c @@ -0,0 +1,706 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v16 + I/O Spreadsheet tracker: + Conversion command: csvtopinconfig.py --soc elba --copyright 2015 --radar '' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : SPI1_SCLK -> NC + CFG_DISABLED, // 1 : SPI1_MOSI -> NC + CFG_DISABLED, // 2 : SPI1_MISO -> NC + CFG_DISABLED, // 3 : SPI1_SSIN -> NC + CFG_DISABLED, // 4 : ISP_I2C1_SDA -> NC + CFG_DISABLED, // 5 : ISP_I2C1_SCL -> NC + CFG_DISABLED, // 6 : ISP_I2C0_SDA -> NC + CFG_DISABLED, // 7 : ISP_I2C0_SCL -> NC + +/* Port 1 */ + CFG_DISABLED, // 8 : SENSOR0_ISTRB -> NC + CFG_DISABLED, // 9 : SENSOR0_RST -> NC + CFG_DISABLED, // 10 : SENSOR0_CLK -> NC + CFG_DISABLED, // 11 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 12 : SENSOR1_ISTRB -> NC + CFG_DISABLED, // 13 : SENSOR1_RST -> NC + CFG_DISABLED, // 14 : SENSOR1_CLK -> NC + CFG_DISABLED, // 15 : SENSOR1_XSHUTDOWN -> NC + +/* Port 2 */ + CFG_IN | PULL_DOWN, // 16 : GPIO[16] -> SOC_BRD_ID3 + CFG_IN, // 17 : GPIO[17] -> PMU_SOC_IRQ_L + CFG_IN | PULL_DOWN, // 18 : GPIO[18] -> SOC_BOOT_CFG0 + CFG_DISABLED, // 19 : I2S1_MCK -> NC + CFG_DISABLED, // 20 : I2S1_BCLK -> NC + CFG_DISABLED, // 21 : I2S1_LRCK -> NC + CFG_DISABLED, // 22 : I2S1_DIN -> NC + CFG_DISABLED, // 23 : I2S1_DOUT -> NC + +/* Port 3 */ + CFG_FUNC0 | DRIVE_S8 | SLOW_SLEW, // 24 : NAND_SYS_CLK -> SOC_CLK24M_NAND_R + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 25 : S3E0_RESETN -> SOC_NAND_RESET0_L + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 26 : S3E1_RESETN -> SOC_NAND_RESET1_L + CFG_DISABLED, // 27 : UART1_TXD -> NC + CFG_DISABLED, // 28 : UART1_RXD -> NC + CFG_DISABLED, // 29 : UART1_RTSN -> NC + CFG_DISABLED, // 30 : UART1_CTSN -> NC + CFG_OUT_0 | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 31 : GPIO[43] -> SOC_NAND_FW_STRAP + +/* Port 4 */ + CFG_DISABLED, // 32 : I2S0_BCLK -> NC + CFG_DISABLED, // 33 : I2S0_LRCK -> NC + CFG_DISABLED, // 34 : I2S0_DIN -> NC + CFG_DISABLED, // 35 : I2S0_DOUT -> NC + CFG_DISABLED, // 36 : I2S0_MCK -> NC + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 5 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : I2S4_MCK -> NC + CFG_DISABLED, // 65 : I2S4_BCLK -> NC + CFG_DISABLED, // 66 : I2S4_LRCK -> NC + CFG_DISABLED, // 67 : I2S4_DIN -> NC + CFG_DISABLED, // 68 : I2S4_DOUT -> NC + CFG_DISABLED, // 69 : I2S2_MCK -> NC + CFG_DISABLED, // 70 : I2S2_BCLK -> NC + CFG_DISABLED, // 71 : I2S2_LRCK -> NC + +/* Port 9 */ + CFG_DISABLED, // 72 : I2S2_DIN -> NC + CFG_DISABLED, // 73 : I2S2_DOUT -> NC + CFG_IN, // 74 : GPIO[0] -> HDMI_SOC_5V_OCP_FAULT_L + CFG_DISABLED, // 75 : GPIO[1] -> NC + CFG_DISABLED, // 76 : GPIO[2] -> NC + CFG_DISABLED, // 77 : GPIO[3] -> NC + CFG_DISABLED, // 78 : GPIO[4] -> NC + CFG_DISABLED, // 79 : GPIO[5] -> NC + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[6] -> NC + CFG_DISABLED, // 81 : GPIO[7] -> NC + CFG_DISABLED, // 82 : GPIO[8] -> NC + CFG_DISABLED, // 83 : GPIO[9] -> NC + CFG_IN, // 84 : GPIO[10] -> USBCCTRL_SOC_IRQ + CFG_DISABLED, // 85 : GPIO[11] -> NC + CFG_DISABLED | PULL_DOWN, // 86 : GPIO[12] -> SOC_WLAN_DEVICE_WAKE + CFG_DISABLED, // 87 : GPIO[13] -> NC + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[14] -> NC + CFG_DISABLED, // 89 : GPIO[15] -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 90 : UART3_TXD -> UART3_TXD + CFG_FUNC0, // 91 : UART3_RXD -> UART3_RXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 92 : UART3_RTSN -> UART3_RTS_L + CFG_FUNC0, // 93 : UART3_CTSN -> UART3_CTS_L + CFG_IN | PULL_UP, // 94 : SPI0_SCLK -> SOC_BRD_ID0 + CFG_IN | PULL_UP, // 95 : SPI0_MOSI -> SOC_BRD_ID1 + +/* Port 12 */ + CFG_IN | PULL_UP, // 96 : SPI0_MISO -> SOC_BRD_ID2 + CFG_DISABLED, // 97 : SPI0_SSIN -> NC + CFG_IN, // 98 : PCIE_PERST0_N -> PCIE0_RESET_L + CFG_IN, // 99 : PCIE_PERST1_N -> PCIE1_RESET_L + CFG_IN, // 100 : PCIE_PERST2_N -> PCIE2_RESET_L + CFG_IN, // 101 : PCIE_PERST3_N -> PCIE3_RESET_L + CFG_IN, // 102 : PCIE_PERST4_N -> PCIE4_RESET_L + CFG_IN, // 103 : PCIE_PERST5_N -> PCIE5_RESET_L + +/* Port 13 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 104 : PCIE_CLKREQ0_N -> PCIE0_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> PCIE1_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 106 : PCIE_CLKREQ2_N -> PCIE2_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 107 : PCIE_CLKREQ3_N -> PCIE3_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 108 : PCIE_CLKREQ4_N -> PCIE4_CLKREQ_L + CFG_DISABLED, // 109 : PCIE_CLKREQ5_N -> PCIE5_CLKREQ_L + CFG_DISABLED, // 110 : UART2_TXD -> NC + CFG_DISABLED, // 111 : UART2_RXD -> NC + +/* Port 14 */ + CFG_DISABLED, // 112 : UART2_RTSN -> NC + CFG_DISABLED, // 113 : UART2_CTSN -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 114 : I2C3_SDA -> I2C3_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 115 : I2C3_SCL -> I2C3_SCL + CFG_DISABLED, // 116 : GPIO[44] -> NC + CFG_IN, // 117 : GPIO[45] -> USB3CTRL_SOC_SMI_L + CFG_DISABLED, // 118 : GPIO[46] -> NC + CFG_OUT_0 | DRIVE_S4 | SLOW_SLEW, // 119 : GPIO[47] -> SOC_RDRVR_PD_L + +/* Port 15 */ + CFG_DISABLED, // 120 : GPIO[48] -> NC + CFG_IN | PULL_UP, // 121 : GPIO[49] -> USB3CTRL_SOC_WAKE_L + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED, // 128 : SWD_TMS2 -> AOP_NAND_SWD_SWDIO + CFG_DISABLED, // 129 : SWD_TMS3 -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 130 : UART5_RTXD -> UART5_RTXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 131 : I2C2_SDA -> I2C2_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 132 : I2C2_SCL -> I2C2_SCL + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 133 : UART4_TXD -> UART4_TXD + CFG_FUNC0, // 134 : UART4_RXD -> UART4_RXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 135 : UART4_RTSN -> UART4_RTS_L + +/* Port 17 */ + CFG_FUNC0, // 136 : UART4_CTSN -> UART4_CTS_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 137 : UART7_TXD -> UART7_TXD + CFG_FUNC0, // 138 : UART7_RXD -> UART7_RXD + CFG_DISABLED, // 139 : CLK32K_OUT -> NC + CFG_DISABLED, // 140 : DP_WAKEUP0 -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 141 : DP_WAKEUP1 -> SOC_USBCCTRL_AUX_OE + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : SPI2_SCLK -> NC + CFG_DISABLED, // 161 : SPI2_MOSI -> NC + CFG_DISABLED, // 162 : SPI2_MISO -> NC + CFG_DISABLED, // 163 : SPI2_SSIN -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 164 : I2C0_SDA -> I2C0_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 165 : I2C0_SCL -> I2C0_SCL + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 166 : SPI3_SCLK -> SPI3_SCLK + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 167 : SPI3_MOSI -> SPI3_MOSI + +/* Port 21 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 168 : SPI3_MISO -> SPI3_MISO + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 169 : SPI3_SSIN -> SPI3_SSIN + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 170 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 171 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 172 : UART6_TXD -> NC + CFG_DISABLED, // 173 : UART6_RXD -> NC + CFG_IN, // 174 : TMR32_PWM0 -> FAN_SOC_TACH + CFG_IN, // 175 : TMR32_PWM1 -> WLAN_SOC_ATSP + +/* Port 22 */ + CFG_DISABLED, // 176 : TMR32_PWM2 -> SOC_FAN_PWM + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 177 : I2C1_SDA -> I2C1_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 178 : I2C1_SCL -> I2C1_SCL + CFG_DISABLED, // 179 : GPIO[19] -> NC + CFG_IN | PULL_DOWN, // 180 : GPIO[20] -> SOC_GPIO_20 + CFG_DISABLED, // 181 : GPIO[21] -> SOC_GPU_ALTV_VID + CFG_IN, // 182 : GPIO[22] -> GPU_SOC_PGOOD + CFG_DISABLED, // 183 : GPIO[23] -> SOC_SIL_PT + +/* Port 23 */ + CFG_DISABLED, // 184 : GPIO[24] -> NC + CFG_IN | PULL_DOWN, // 185 : GPIO[25] -> SOC_BOOT_CFG1 + CFG_IN, // 186 : GPIO[26] -> SOC_FORCE_DFU + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 187 : PSPI_MOSI -> PMGR_SPI_MOSI + CFG_DISABLED, // 188 : DWI_DO -> NC + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 189 : PMGR_MISO -> PMGR_SPI_MISO + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 190 : PMGR_SCLK0 -> PMGR_SPI_CLK + CFG_DISABLED, // 191 : PMGR_SSCLK1 -> NC + +/* Port 24 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 192 : DROOP -> COMP_SOC_DROOP_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 193 : SOCHOT1 -> SOC_PMU_SOCHOT_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 194 : EDP_HPD0 -> DP2HDMI_LPDP0_HPD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 195 : EDP_HPD1 -> USBCCTRL_SOC_RDRVR_HPD + CFG_DISABLED, // 196 : I2S3_MCK -> NC + CFG_DISABLED, // 197 : I2S3_BCLK -> NC + CFG_DISABLED, // 198 : I2S3_LRCK -> NC + CFG_DISABLED, // 199 : I2S3_DOUT -> NC + +/* Port 25 */ + CFG_DISABLED, // 200 : I2S3_DIN -> NC + CFG_DISABLED, // 201 : GPIO[27] -> SOC_DFU_STATUS + CFG_IN | PULL_UP, // 202 : GPIO[28] -> SOC_BOOT_CFG2 + CFG_IN | PULL_UP, // 203 : GPIO[29] -> SOC_BRD_ID4 + CFG_DISABLED, // 204 : GPIO[30] -> SOC_SIL_CTRL1 + CFG_DISABLED, // 205 : GPIO[31] -> SOC_SIL_CTRL2 + CFG_DISABLED, // 206 : GPIO[32] -> NC + CFG_DISABLED, // 207 : GPIO[33] -> SOC_SIL_CTRL0 + +/* Port 26 */ + CFG_IN | PULL_DOWN, // 208 : GPIO[34] -> SOC_BRD_REV0 + CFG_IN | PULL_DOWN, // 209 : GPIO[35] -> SOC_BRD_REV1 + CFG_IN | PULL_DOWN, // 210 : GPIO[36] -> SOC_BRD_REV2 + CFG_IN | PULL_DOWN, // 211 : GPIO[37] -> SOC_BRD_REV3 + CFG_DISABLED, // 212 : GPIO[38] -> NC + CFG_DISABLED, // 213 : GPIO[39] -> NC + CFG_DISABLED, // 214 : GPIO[40] -> NC + CFG_DISABLED | PULL_DOWN, // 215 : GPIO[41] -> SOC_BT_DEVICE_WAKE + +/* Port 27 */ + CFG_DISABLED, // 216 : GPIO[42] -> NC + CFG_DISABLED, // 217 : TST_CLKOUT -> SOC_PMU_TEST_CLKOUT + CFG_DISABLED, // 218 : GPU_TRIGGER1 -> NC + CFG_DISABLED, // 219 : GPU_TRIGGER2 -> NC + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 0 : AOP_SPI_SCLK -> AOP_SPI_SCLK + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 1 : AOP_SPI_MOSI -> AOP_SPI_MOSI + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 2 : AOP_SPI_MISO -> AOP_SPI_MISO + CFG_DISABLED, // 3 : AOP_UART1_TXD -> NC + CFG_DISABLED, // 4 : AOP_UART1_RXD -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 5 : AOP_UART0_TXD -> AOP_UART0_TXD + CFG_FUNC0, // 6 : AOP_UART0_RXD -> AOP_UART0_RXD + CFG_DISABLED, // 7 : AOP_UART2_TXD -> NC + +/* Port 1 */ + CFG_DISABLED, // 8 : AOP_UART2_RXD -> NC + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 9 : AOP_I2CM_SDA -> AOP_I2C_SDA + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 10 : AOP_I2CM_SCL -> AOP_I2C_SCL + CFG_IN, // 11 : AOP_FUNC[0] -> AOP_DFU_REQ_L + CFG_DISABLED, // 12 : AOP_FUNC[1] -> AOP_DFU_REQCLR + CFG_IN, // 13 : AOP_FUNC[2] -> DP2HDMI_AOP_VDD12ON + CFG_IN, // 14 : AOP_FUNC[3] -> AOP_FUNC_3 + CFG_IN, // 15 : AOP_FUNC[4] -> HDMI_AOP_HPD + +/* Port 2 */ + CFG_DISABLED, // 16 : AOP_FUNC[5] -> AOP_HDMI_CEC + CFG_DISABLED, // 17 : AOP_FUNC[6] -> IRRCVR_OUT_RC_1V8 + CFG_DISABLED, // 18 : AOP_FUNC[7] -> IRRCVR_OUT_RC_1V8 + CFG_IN, // 19 : AOP_FUNC[8] -> DP2HDMI_PMU_CEC_IRQ + CFG_DISABLED, // 20 : AOP_FUNC[9] -> HDMI_AOP_CEC + CFG_IN, // 21 : AOP_SWD_TCK_OUT -> AOP_SWD_SWCLK + CFG_DISABLED, // 22 : AOP_SWD_TMS0 -> NC + CFG_DISABLED, // 23 : AOP_SWD_TMS1 -> NC + +/* Port 3 */ + CFG_DISABLED, // 24 : AOP_I2S_MCK -> AOP_I2S_MCK + CFG_DISABLED, // 25 : AOP_I2S_BCLK -> AOP_I2S_BCLK + CFG_DISABLED, // 26 : AOP_I2S_LRCK -> AOP_I2S_LRCK + CFG_DISABLED, // 27 : AOP_I2S_DIN -> AOP_I2S_DIN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : SPI1_SCLK -> NC + CFG_DISABLED, // 1 : SPI1_MOSI -> NC + CFG_DISABLED, // 2 : SPI1_MISO -> NC + CFG_DISABLED, // 3 : SPI1_SSIN -> NC + CFG_DISABLED, // 4 : ISP_I2C1_SDA -> NC + CFG_DISABLED, // 5 : ISP_I2C1_SCL -> NC + CFG_DISABLED, // 6 : ISP_I2C0_SDA -> NC + CFG_DISABLED, // 7 : ISP_I2C0_SCL -> NC + +/* Port 1 */ + CFG_DISABLED, // 8 : SENSOR0_ISTRB -> NC + CFG_DISABLED, // 9 : SENSOR0_RST -> NC + CFG_DISABLED, // 10 : SENSOR0_CLK -> NC + CFG_DISABLED, // 11 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED, // 12 : SENSOR1_ISTRB -> NC + CFG_DISABLED, // 13 : SENSOR1_RST -> NC + CFG_DISABLED, // 14 : SENSOR1_CLK -> NC + CFG_DISABLED, // 15 : SENSOR1_XSHUTDOWN -> NC + +/* Port 2 */ + CFG_IN | PULL_DOWN, // 16 : GPIO[16] -> SOC_BRD_ID3 + CFG_IN, // 17 : GPIO[17] -> PMU_SOC_IRQ_L + CFG_IN | PULL_DOWN, // 18 : GPIO[18] -> SOC_BOOT_CFG0 + CFG_DISABLED, // 19 : I2S1_MCK -> NC + CFG_DISABLED, // 20 : I2S1_BCLK -> NC + CFG_DISABLED, // 21 : I2S1_LRCK -> NC + CFG_DISABLED, // 22 : I2S1_DIN -> NC + CFG_DISABLED, // 23 : I2S1_DOUT -> NC + +/* Port 3 */ + CFG_FUNC0 | DRIVE_S8 | SLOW_SLEW, // 24 : NAND_SYS_CLK -> SOC_CLK24M_NAND_R + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 25 : S3E0_RESETN -> SOC_NAND_RESET0_L + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 26 : S3E1_RESETN -> SOC_NAND_RESET1_L + CFG_DISABLED, // 27 : UART1_TXD -> NC + CFG_DISABLED, // 28 : UART1_RXD -> NC + CFG_DISABLED, // 29 : UART1_RTSN -> NC + CFG_DISABLED, // 30 : UART1_CTSN -> NC + CFG_OUT_0 | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 31 : GPIO[43] -> SOC_NAND_FW_STRAP + +/* Port 4 */ + CFG_DISABLED, // 32 : I2S0_BCLK -> NC + CFG_DISABLED, // 33 : I2S0_LRCK -> NC + CFG_DISABLED, // 34 : I2S0_DIN -> NC + CFG_DISABLED, // 35 : I2S0_DOUT -> NC + CFG_DISABLED, // 36 : I2S0_MCK -> NC + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 5 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : I2S4_MCK -> NC + CFG_DISABLED, // 65 : I2S4_BCLK -> NC + CFG_DISABLED, // 66 : I2S4_LRCK -> NC + CFG_DISABLED, // 67 : I2S4_DIN -> NC + CFG_DISABLED, // 68 : I2S4_DOUT -> NC + CFG_DISABLED, // 69 : I2S2_MCK -> NC + CFG_DISABLED, // 70 : I2S2_BCLK -> NC + CFG_DISABLED, // 71 : I2S2_LRCK -> NC + +/* Port 9 */ + CFG_DISABLED, // 72 : I2S2_DIN -> NC + CFG_DISABLED, // 73 : I2S2_DOUT -> NC + CFG_IN, // 74 : GPIO[0] -> HDMI_SOC_5V_OCP_FAULT_L + CFG_DISABLED, // 75 : GPIO[1] -> NC + CFG_DISABLED, // 76 : GPIO[2] -> NC + CFG_DISABLED, // 77 : GPIO[3] -> NC + CFG_DISABLED, // 78 : GPIO[4] -> NC + CFG_DISABLED, // 79 : GPIO[5] -> NC + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[6] -> NC + CFG_DISABLED, // 81 : GPIO[7] -> NC + CFG_DISABLED, // 82 : GPIO[8] -> NC + CFG_DISABLED, // 83 : GPIO[9] -> NC + CFG_IN, // 84 : GPIO[10] -> USBCCTRL_SOC_IRQ + CFG_DISABLED, // 85 : GPIO[11] -> NC + CFG_DISABLED | PULL_DOWN, // 86 : GPIO[12] -> SOC_WLAN_DEVICE_WAKE + CFG_DISABLED, // 87 : GPIO[13] -> NC + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[14] -> NC + CFG_DISABLED, // 89 : GPIO[15] -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 90 : UART3_TXD -> UART3_TXD + CFG_FUNC0, // 91 : UART3_RXD -> UART3_RXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 92 : UART3_RTSN -> UART3_RTS_L + CFG_FUNC0, // 93 : UART3_CTSN -> UART3_CTS_L + CFG_IN | PULL_UP, // 94 : SPI0_SCLK -> SOC_BRD_ID0 + CFG_IN | PULL_UP, // 95 : SPI0_MOSI -> SOC_BRD_ID1 + +/* Port 12 */ + CFG_IN | PULL_UP, // 96 : SPI0_MISO -> SOC_BRD_ID2 + CFG_DISABLED, // 97 : SPI0_SSIN -> NC + CFG_IN, // 98 : PCIE_PERST0_N -> PCIE0_RESET_L + CFG_IN, // 99 : PCIE_PERST1_N -> PCIE1_RESET_L + CFG_IN, // 100 : PCIE_PERST2_N -> PCIE2_RESET_L + CFG_IN, // 101 : PCIE_PERST3_N -> PCIE3_RESET_L + CFG_IN, // 102 : PCIE_PERST4_N -> PCIE4_RESET_L + CFG_IN, // 103 : PCIE_PERST5_N -> PCIE5_RESET_L + +/* Port 13 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 104 : PCIE_CLKREQ0_N -> PCIE0_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 105 : PCIE_CLKREQ1_N -> PCIE1_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 106 : PCIE_CLKREQ2_N -> PCIE2_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 107 : PCIE_CLKREQ3_N -> PCIE3_CLKREQ_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 108 : PCIE_CLKREQ4_N -> PCIE4_CLKREQ_L + CFG_DISABLED, // 109 : PCIE_CLKREQ5_N -> PCIE5_CLKREQ_L + CFG_DISABLED, // 110 : UART2_TXD -> NC + CFG_DISABLED, // 111 : UART2_RXD -> NC + +/* Port 14 */ + CFG_DISABLED, // 112 : UART2_RTSN -> NC + CFG_DISABLED, // 113 : UART2_CTSN -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 114 : I2C3_SDA -> I2C3_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 115 : I2C3_SCL -> I2C3_SCL + CFG_DISABLED, // 116 : GPIO[44] -> NC + CFG_IN, // 117 : GPIO[45] -> USB3CTRL_SOC_SMI_L + CFG_DISABLED, // 118 : GPIO[46] -> NC + CFG_OUT_0 | DRIVE_S4 | SLOW_SLEW, // 119 : GPIO[47] -> SOC_RDRVR_PD_L + +/* Port 15 */ + CFG_DISABLED, // 120 : GPIO[48] -> NC + CFG_IN | PULL_UP, // 121 : GPIO[49] -> USB3CTRL_SOC_WAKE_L + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED, // 128 : SWD_TMS2 -> AOP_NAND_SWD_SWDIO + CFG_DISABLED, // 129 : SWD_TMS3 -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 130 : UART5_RTXD -> UART5_RTXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 131 : I2C2_SDA -> I2C2_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 132 : I2C2_SCL -> I2C2_SCL + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 133 : UART4_TXD -> UART4_TXD + CFG_FUNC0, // 134 : UART4_RXD -> UART4_RXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 135 : UART4_RTSN -> UART4_RTS_L + +/* Port 17 */ + CFG_FUNC0, // 136 : UART4_CTSN -> UART4_CTS_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 137 : UART7_TXD -> UART7_TXD + CFG_FUNC0, // 138 : UART7_RXD -> UART7_RXD + CFG_DISABLED, // 139 : CLK32K_OUT -> NC + CFG_DISABLED, // 140 : DP_WAKEUP0 -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 141 : DP_WAKEUP1 -> SOC_USBCCTRL_AUX_OE + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : SPI2_SCLK -> NC + CFG_DISABLED, // 161 : SPI2_MOSI -> NC + CFG_DISABLED, // 162 : SPI2_MISO -> NC + CFG_DISABLED, // 163 : SPI2_SSIN -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 164 : I2C0_SDA -> I2C0_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 165 : I2C0_SCL -> I2C0_SCL + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 166 : SPI3_SCLK -> SPI3_SCLK + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 167 : SPI3_MOSI -> SPI3_MOSI + +/* Port 21 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 168 : SPI3_MISO -> SPI3_MISO + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 169 : SPI3_SSIN -> SPI3_SSIN + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 170 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 171 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 172 : UART6_TXD -> NC + CFG_DISABLED, // 173 : UART6_RXD -> NC + CFG_IN, // 174 : TMR32_PWM0 -> FAN_SOC_TACH + CFG_IN, // 175 : TMR32_PWM1 -> WLAN_SOC_ATSP + +/* Port 22 */ + CFG_DISABLED, // 176 : TMR32_PWM2 -> SOC_FAN_PWM + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 177 : I2C1_SDA -> I2C1_SDA + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 178 : I2C1_SCL -> I2C1_SCL + CFG_DISABLED, // 179 : GPIO[19] -> NC + CFG_IN | PULL_DOWN, // 180 : GPIO[20] -> SOC_GPIO_20 + CFG_DISABLED, // 181 : GPIO[21] -> SOC_GPU_ALTV_VID + CFG_IN, // 182 : GPIO[22] -> GPU_SOC_PGOOD + CFG_DISABLED, // 183 : GPIO[23] -> SOC_SIL_PT + +/* Port 23 */ + CFG_DISABLED, // 184 : GPIO[24] -> NC + CFG_IN | PULL_DOWN, // 185 : GPIO[25] -> SOC_BOOT_CFG1 + CFG_IN, // 186 : GPIO[26] -> SOC_FORCE_DFU + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 187 : PSPI_MOSI -> PMGR_SPI_MOSI + CFG_DISABLED, // 188 : DWI_DO -> NC + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 189 : PMGR_MISO -> PMGR_SPI_MISO + CFG_FUNC0 | DRIVE_S7 | SLOW_SLEW, // 190 : PMGR_SCLK0 -> PMGR_SPI_CLK + CFG_DISABLED, // 191 : PMGR_SSCLK1 -> NC + +/* Port 24 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 192 : DROOP -> COMP_SOC_DROOP_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 193 : SOCHOT1 -> SOC_PMU_SOCHOT_L + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 194 : EDP_HPD0 -> DP2HDMI_LPDP0_HPD + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 195 : EDP_HPD1 -> USBCCTRL_SOC_RDRVR_HPD + CFG_DISABLED, // 196 : I2S3_MCK -> NC + CFG_DISABLED, // 197 : I2S3_BCLK -> NC + CFG_DISABLED, // 198 : I2S3_LRCK -> NC + CFG_DISABLED, // 199 : I2S3_DOUT -> NC + +/* Port 25 */ + CFG_DISABLED, // 200 : I2S3_DIN -> NC + CFG_DISABLED, // 201 : GPIO[27] -> SOC_DFU_STATUS + CFG_IN | PULL_UP, // 202 : GPIO[28] -> SOC_BOOT_CFG2 + CFG_IN | PULL_UP, // 203 : GPIO[29] -> SOC_BRD_ID4 + CFG_DISABLED, // 204 : GPIO[30] -> SOC_SIL_CTRL1 + CFG_DISABLED, // 205 : GPIO[31] -> SOC_SIL_CTRL2 + CFG_DISABLED, // 206 : GPIO[32] -> NC + CFG_DISABLED, // 207 : GPIO[33] -> SOC_SIL_CTRL0 + +/* Port 26 */ + CFG_IN | PULL_DOWN, // 208 : GPIO[34] -> SOC_BRD_REV0 + CFG_IN | PULL_DOWN, // 209 : GPIO[35] -> SOC_BRD_REV1 + CFG_IN | PULL_DOWN, // 210 : GPIO[36] -> SOC_BRD_REV2 + CFG_IN | PULL_DOWN, // 211 : GPIO[37] -> SOC_BRD_REV3 + CFG_DISABLED, // 212 : GPIO[38] -> NC + CFG_DISABLED, // 213 : GPIO[39] -> NC + CFG_DISABLED, // 214 : GPIO[40] -> NC + CFG_DISABLED | PULL_DOWN, // 215 : GPIO[41] -> SOC_BT_DEVICE_WAKE + +/* Port 27 */ + CFG_DISABLED, // 216 : GPIO[42] -> NC + CFG_DISABLED, // 217 : TST_CLKOUT -> SOC_PMU_TEST_CLKOUT + CFG_DISABLED, // 218 : GPU_TRIGGER1 -> NC + CFG_DISABLED, // 219 : GPU_TRIGGER2 -> NC + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 0 : AOP_SPI_SCLK -> AOP_SPI_SCLK + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 1 : AOP_SPI_MOSI -> AOP_SPI_MOSI + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 2 : AOP_SPI_MISO -> AOP_SPI_MISO + CFG_DISABLED, // 3 : AOP_UART1_TXD -> NC + CFG_DISABLED, // 4 : AOP_UART1_RXD -> NC + CFG_FUNC0 | DRIVE_S4 | SLOW_SLEW, // 5 : AOP_UART0_TXD -> AOP_UART0_TXD + CFG_FUNC0, // 6 : AOP_UART0_RXD -> AOP_UART0_RXD + CFG_DISABLED, // 7 : AOP_UART2_TXD -> NC + +/* Port 1 */ + CFG_DISABLED, // 8 : AOP_UART2_RXD -> NC + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 9 : AOP_I2CM_SDA -> AOP_I2C_SDA + CFG_FUNC0 | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 10 : AOP_I2CM_SCL -> AOP_I2C_SCL + CFG_IN, // 11 : AOP_FUNC[0] -> AOP_DFU_REQ_L + CFG_DISABLED, // 12 : AOP_FUNC[1] -> AOP_DFU_REQCLR + CFG_IN, // 13 : AOP_FUNC[2] -> DP2HDMI_AOP_VDD12ON + CFG_IN, // 14 : AOP_FUNC[3] -> AOP_FUNC_3 + CFG_IN, // 15 : AOP_FUNC[4] -> HDMI_AOP_HPD + +/* Port 2 */ + CFG_DISABLED, // 16 : AOP_FUNC[5] -> AOP_HDMI_CEC + CFG_DISABLED, // 17 : AOP_FUNC[6] -> IRRCVR_OUT_RC_1V8 + CFG_DISABLED, // 18 : AOP_FUNC[7] -> IRRCVR_OUT_RC_1V8 + CFG_IN, // 19 : AOP_FUNC[8] -> DP2HDMI_PMU_CEC_IRQ + CFG_DISABLED, // 20 : AOP_FUNC[9] -> HDMI_AOP_CEC + CFG_IN, // 21 : AOP_SWD_TCK_OUT -> AOP_SWD_SWCLK + CFG_DISABLED, // 22 : AOP_SWD_TMS0 -> NC + CFG_DISABLED, // 23 : AOP_SWD_TMS1 -> NC + +/* Port 3 */ + CFG_DISABLED, // 24 : AOP_I2S_MCK -> AOP_I2S_MCK + CFG_DISABLED, // 25 : AOP_I2S_BCLK -> AOP_I2S_BCLK + CFG_DISABLED, // 26 : AOP_I2S_LRCK -> AOP_I2S_LRCK + CFG_DISABLED, // 27 : AOP_I2S_DIN -> AOP_I2S_DIN + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0, pinconfig_ap_1 } }, + { 1, 1, { pinconfig_dev_0, pinconfig_dev_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/j105/properties.c b/target/j105/properties.c new file mode 100644 index 0000000..4543828 --- /dev/null +++ b/target/j105/properties.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/j105/rules.mk b/target/j105/rules.mk new file mode 100644 index 0000000..fe36007 --- /dev/null +++ b/target/j105/rules.mk @@ -0,0 +1,75 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2255=1 + +# XXX darrin -- These aren't correct. +# However, they aren't used unless doing clpc, +# which we don't expect to do on this platform +OPTIONS +=\ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + +# XXX darrin -- These haven't been reviewed yet +OPTIONS+= \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 + +# VID0 is 74.25MHz pixel clock from SPARE0 (PLL2) = (24/2•99)/(15+1) +OPTIONS+= \ + TARGET_SPARE0_CLK_CFG=0x82000001 \ + TARGET_VID0_CLK_CFG=0x81100000 \ + PLL2_T=1 \ + PLL2_P=2 \ + PLL2_M=99 \ + PLL2_S=15 \ + +OPTIONS+= \ + DISPLAY_APPLE_TV_TUNABLES=1 \ + TARGET_DITHER_TYPE=DITHER_BLUE_NOISE \ + WITH_HW_DISPLAY_DISPLAYPORT=1 \ + DP_DTPATH=\"arm-io/displayport0\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy0\" \ + +xOPTIONS+= \ + \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + +OPTIONS+= \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + +OPTIONS+= \ + BT_DTPATH=\"arm-io/uart4/bluetooth\" \ + WIFI_DTPATH=\"arm-io/uart3/wlan\" \ + ETHERNET_DTPATH=\"arm-io/apcie/pci-bridge2/lan0\" + +OPTIONS += \ + DCS_NUM_RANKS=1 \ + DCS_NUM_CHANNELS=8 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/j33/include/target/amcconfig.h b/target/j33/include/target/amcconfig.h new file mode 100644 index 0000000..23bd9fb --- /dev/null +++ b/target/j33/include/target/amcconfig.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amc/amc.h, and this + * file should only by included from amc.c. + * + */ + +static const struct amc_param amc_params = { + .flags = FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_RECONFIG | FLAG_AMC_PARAM_ENABLE_AIU, + + .freqsel = 0, + .tREFi = 0x5d, + .longsrcnt = 0x0802, + .srextrarefcnt = 0x00010000, + .tREFi_1Gb = 0xbb, + .longsrcnt_1Gb = 0x0401, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 6, // rdlat + .phywrlat = 3, + .pdn = 0x33000303, + .read = 0x00000102, + .bustat = 0x00020002, + .derate = 0x18620c46, + .mcphyupdate = 0x00000009, // + .pwrmngtparam_small = 0x00013000, + .pwrmngtparam_guided = 0x00fa3000, + .bootclkdivsr = 8, + .aref_freq0 = 0x00100000, + .aref_freq1 = 0x00000000, + .chnldec = 0x00000F00, + .arefparam = 0x06000000, + .readleveling = 0x02000301, + + .freq = { + { // 256MHz + .cas = 0x00000205, + .pch = 0x0002040b, + .act = 0x0d030605, + .autoref = 0x1022a000, + .selfref = 0x00024040, + .modereg = 0x00180502, + .mifcassch = 0x001f0101, + .mifqmaxctrl = 0x00000000, + }, + { // 128.5MHz + .cas = 0x00000003, + .pch = 0x00000006, + .act = 0x08020303, + .autoref = 0x08110000, + .selfref = 0x00012000, + .modereg = 0x000c0000, + .mifcassch = 0x00000000, + .mifqmaxctrl = 0x00000000, + }, + { // 64.13MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x04090000, + .selfref = 0x00009000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + .mifqmaxctrl = 0x00000001, + }, + { // 50 & 24MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x03070000, + .selfref = 0x00007000, + .modereg = 0x00060000, + .mifcassch = 0x00000010, + .mifqmaxctrl = 0x00000001, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + // These settings are common across all H4x and H5P. Channel decode and hashing + // is done in mainline init code. Any tunables that match hardware defaults are + // omitted here. + + { &rAMC_AIUPRT_CFG, 0x00070000 }, // address error enable + { &rAMC_AIUPRT_RD_GEN, 0x00000018 }, // fence read detect on GFX + { &rAMC_AIUPRT_WR, 0x00000001 }, // out-of-order write, ignore B-bit + + { &rAMC_AIU_RDBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_RDMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRBRSTLEN, 0x01010101 }, // burst len is 64B + { &rAMC_AIU_WRMINCRD, 0x7B7B7C7B }, // RT:NRT:CPU:GFX = 40:40:5:10 + + { &rAMC_AIU_CPUSPCREQ, 0x00000019 }, // CPU ageout timer + { &rAMC_AIU_GFXSPCREQ, 0x00000032 }, // GFX ageout timer + { &rAMC_AIU_NRTSPCREQ, 0x00000032 }, // Hperf-NRT ageout timer + { &rAMC_AIU_RTSPCREQ, 0x00000019 }, // Hperf-RT ageout timer + { &rAMC_AIU_WPQSCH, 0x10001000 }, // only supported for Hperf-RT + { &rAMC_AIU_THOTLCPUPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLRTPARAM, 0x0A4640C4 }, + { &rAMC_AIU_THOTLNRTPARAM, 0x00000000 }, + { &rAMC_AIU_THOTLGFXPARAM, 0x00000000 }, + { &rAMC_AIU_PUSHEN, 0x00001100 }, // only supported for Hperf-RT + + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJEN, 0x00000001 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + + { &rAMC_MIFACTSCH, 0x00000001 }, + + { &rAMC_PSQRQTIMER0, 0x00000040 }, // RTG bypass up to 64 transactions + { &rAMC_PSQRQTIMER1, 0x00000018 }, // RTY bypass up to 24 transactions + { &rAMC_PSQRQTIMER2, 0x00000020 }, // RTG bypass up to 32 transactions + { &rAMC_PSQRQBRST, 0x040c040c }, // RTR transactions don't affect read burst size + { &rAMC_PSQRQSCHCRD, 0x002028f5 }, // read credits = 2 * write credits + { &rAMC_PSQWQBRST, 0x0208040c }, // RTR reads cause reduced write burst size + { &rAMC_PSQWQSCHCRD, 0x001014f5 }, // write credits = 1/2 * read credits + { &rAMC_MCUQOS, 0x00010f04 }, // RTG=4, RTY=15, enable pick-oldest-RTY + + // Platform specific + + { &rAMC_AIU_RDMAXCRD, 0x2828050a }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_RDREFL, 0x21210408 }, // 5/6 of AIURDMAXCRD fields + { &rAMC_AIU_WRMAXCRD, 0x2828050a }, // RT:NRT:CPU:GFX = 40:40:5:10 + { &rAMC_AIU_WRREFL, 0x21210408 }, // 5/6 of AIUWRMAXCRD fields + { &rAMC_AIU_THOTLEN, 0x00001111 }, // enable throttling + { &rAMC_PSQWQCTL1, 0x000000C0 }, // ages write out faster than default (1/2 SelfRef) + { &rAMC_MCUQOSLLT, 0x00010104 }, + + // There is a bug around write merge, which we believe is avoided + // in current drivers: + // Power and performance measurements of disabling write merging were + // done: + { &rAMC_PSQWQCTL0, 0x00010100 }, // Write merge enable + + { &rAMC_AIUPRT_ROTT_D1, 0x000C0000 }, + { &rAMC_AIUPRT_ROTT_D2, 0x00000C0C }, + { &rAMC_AIU_CHNLTM, 0x000000E1 }, + { &rAMC_PSQWQTHR, 0x00171710 }, + { &rAMC_PSQWQBRST, 0x01050105 }, +}; diff --git a/target/j33/include/target/amgconfig.h b/target/j33/include/target/amgconfig.h new file mode 100644 index 0000000..33709fb --- /dev/null +++ b/target/j33/include/target/amgconfig.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amg_param struct is defined in drivers/apple/amg/amg.h, and this + * file should only by included from amg.c. + */ + +static const struct amg_params amc_phy_params = { + .flags = 0, + .core_config = 0x00001053, + .read_latency = 0x0000669b, + .gate_offset = 0x08080808, + .freq_scale = 0x00e40488, + .bit_time_ps = 3900, +}; diff --git a/target/j33/include/target/gpiodef.h b/target/j33/include/target/gpiodef.h new file mode 100644 index 0000000..f6a7593 --- /dev/null +++ b/target/j33/include/target/gpiodef.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* J33 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#define GPIO_BOARD_REV0 GPIO(4, 5) +#define GPIO_BOARD_REV1 GPIO(4, 6) +#define GPIO_BOARD_REV2 GPIO(4, 7) +#define GPIO_BOARD_REV3 GPIO(7, 5) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/j33/include/target/nand_spec_tables.h b/target/j33/include/target/nand_spec_tables.h new file mode 100644 index 0000000..535ecc1 --- /dev/null +++ b/target/j33/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 3, + /* socToNandFallNanosecs */ 3, + /* nandToSocRiseNanosecs */ 3, + /* nandToSocFallNanosecs */ 4, + + /* landing map */ + { + 0x00003333 + }, + + /* useToggleMode */ FALSE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ FALSE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ FALSE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/j33/include/target/powerconfig.h b/target/j33/include/target/powerconfig.h new file mode 100644 index 0000000..17f5335 --- /dev/null +++ b/target/j33/include/target/powerconfig.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +// XXX derived from values read from regs on K66 Dev 0 board; need to +// reconcile these with OTP doc (which appears to differ) and intended +// settings + +// XXX also, need to reconcile OTP settings between K66 Dev 0 and K66 Proto 0 + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kD1815_LDO1, 0x00 }, // PP2V5_BS 2.50V + { PMU_IIC_BUS, kD1815_LDO2, 0x1E }, // PP1V8_AP_PVDDP 1.80V + { PMU_IIC_BUS, kD1815_LDO3, 0x0A }, // PP3V0_USBMUX 3.00V + { PMU_IIC_BUS, kD1815_LDO4, 0x00 }, // PP1V8_AP_DAC 3.00V + { PMU_IIC_BUS, kD1815_LDO5, 0x0A }, // PPNNAD 3.00V + { PMU_IIC_BUS, kD1815_LDO6, 0x0A }, // PP3V0_MCU 3.00V + { PMU_IIC_BUS, kD1815_LDO7, 0x03 }, // PP1V8_AP_VDD 1.80V + { PMU_IIC_BUS, kD1815_LDO8, 0x00 }, // PP3V0_CPU 2.00V + { PMU_IIC_BUS, kD1815_LDO9, 0x00 }, // PP1V2_HSIC 1.20V + { PMU_IIC_BUS, kD1815_LDO10, 0x0A }, // PP3V0_IO 3.00V + { PMU_IIC_BUS, kD1815_LDO11, 0x02 }, // PP1V8_AP_VIDEO 1.80V + { PMU_IIC_BUS, kD1815_LDO12, 0x10 }, // PP1V0_AP 1.00V + + { PMU_IIC_BUS, kD1815_LCM_CONTROL1, 0x05 }, // unused + { PMU_IIC_BUS, kD1815_LCM_CONTROL2, 0x0E }, // unused + { PMU_IIC_BUS, kD1815_LCM_CONTROL3, 0x00 }, // VBOOST_LCM 5.10V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Leave bypass off +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1815_ACTIVE1, 0xFF }, // + { PMU_IIC_BUS, kD1815_ACTIVE2, 0x3F }, // + { PMU_IIC_BUS, kD1815_ACTIVE3, 0x0C }, // VBOOST_LCM, CPU_SW, WDig +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL, 0 }, // Disable SWI by default + { PMU_IIC_BUS, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS }, + + { PMU_IIC_BUS, kDIALOG_BUCK_CONTROL2, 0xAA }, + + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_A, 0xC0 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_B, 0xFF }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_C, 0xBF }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_D, 0xFF }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_E, 0xAE }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_F, 0xFF }, +}; + +// XXX: review setup for each GPIO and add back decoded description of each config +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD1815_SYS_GPIO_1, 0xB9 }, // ENBL_USB_BUFF_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_2, 0xBA }, // LAN_PME_PMU + { PMU_IIC_BUS, kD1815_SYS_GPIO_3, 0xBA }, // WLAN_WAKE_HOST + { PMU_IIC_BUS, kD1815_SYS_GPIO_4, 0x03 }, // ENET_PWR_EN_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_5, 0x01 }, // WLAN_PWR_EN_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_6, 0xFA }, // VBAT_DETECT + { PMU_IIC_BUS, kD1815_SYS_GPIO_7, 0xBA }, // BT_HOST_WAKE + { PMU_IIC_BUS, kD1815_SYS_GPIO_8, 0x18 }, // WLAN_RESET_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_TEMP, 0x18 }, // LAN_RESET_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_SPARE, 0x4B }, // WLAN_CLK32K_R + { PMU_IIC_BUS, kD1815_SYS_GPIO_DEB6, 0x80 }, // enable 32kHz clocks in hibernate +}; + +static const struct core_rails_struct soc_rails[] = +{ +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_POWER_NO_BATTERY 1 +#define TARGET_POWER_USB_MASK STATUS_FLAG_MAKE(0, kD1815_STATUS_A_VBUS_EXT) +#define ALWAYS_BOOT_BATTERY_VOLTAGE (3000) +#define PRECHARGE_BACKLIGHT_LEVEL 103 + +#endif diff --git a/target/j33/include/target/uartconfig.h b/target/j33/include/target/uartconfig.h new file mode 100644 index 0000000..ad1a286 --- /dev/null +++ b/target/j33/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (2) + +#define MCU_SERIAL_PORT (4) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/j33/init.c b/target/j33/init.c new file mode 100644 index 0000000..ba1f7fe --- /dev/null +++ b/target/j33/init.c @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2009-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#if (APPLICATION_IBOOT && PRODUCT_IBOOT) +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Do not delay iBoot by more than this amount from power on (microseconds). +// Give up waiting for a boot logo and carry on at this point. +#define kDPDeviceStartTimeout (8 * 1000 * 1000) + +static u_int32_t j33_get_board_rev(void); +extern utime_t gPowerOnTime; +#if (APPLICATION_IBOOT && PRODUCT_IBOOT ) +#if WITH_HW_DISPLAY_DISPLAYPORT +static dp_t dp_link_config = { + .mode = 0, + .type = 0, + .min_link_rate = 0x6, + .max_link_rate = 0x6, + .lanes = 2, + .ssc = 0, + .alpm = 0, + .vrr_enable = 0, + .vrr_on = 0, +}; +#endif +#endif //(APPLICATION_IBOOT && PRODUCT_IBOOT) + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + +#if WITH_HW_MCU + // Late display initialization. Needed to wait for MCU. + mcu_init(); +#if WITH_HW_DISPLAY_DISPLAYPORT + // Backgrounded. See dp_device_wait_started() call below. + displayport_init(&dp_link_config); +#endif +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ + +#if WITH_HW_MCU + // radar 9746416 -- UART4 left in interrupt mode will cause kernel panic + mcu_quiesce_uart(); +#endif +} + +void target_poweroff(void) +{ +} + +int target_debug_init(void) +{ +#if WITH_HW_MCU + mcu_start_recover(); +#endif + + return 0; +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DIAGS: +#if WITH_HW_MCU +#if WITH_HW_DISPLAY_DISPLAYPORT && PRODUCT_IBOOT + /* Potentially delay boot so we have a + * logo. We might have to do this if a + * connected TV is particularly slow at + * responding to EDID. Sorry. */ + dp_device_wait_started(gPowerOnTime + kDPDeviceStartTimeout); +#endif + mcu_start_boot(); +#endif + break; + case BOOT_DARWIN_RESTORE: + break; + default: + // do nothing + break; + } + + return 0; +} + +bool target_should_recover(void) +{ + // trigger recovery mode whenever USB is attached, unless + // environment variable says otherwise. + + return power_has_usb() && !env_get_bool("auto-boot-usb", true); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + // always powers on + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + // never power off + return false; +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ +// u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); +// gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && PRODUCT_IBOOT) +#if WITH_HW_DISPLAY_DISPLAYPORT + return ((void *)(&dp_link_config)); +#endif +#else + return NULL; +#endif //(APPLICATION_IBOOT && PRODUCT_IBOOT) +} +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "720p", 0); + env_set("idle-off", "false", 0); // do not idle off; there is no battery and this will just reboot (8035422) +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Update the pmu node with the actual vcore values + if (FindNode(0, "arm-io/i2c0/pmu", &node)) { + propName = "swi-vcores"; + if (FindProperty(node, &propName, &propData, &propSize)) { + platform_get_soc_voltages(propSize / sizeof(u_int32_t), propData); + } + } + + if (FindNode(0, "arm-io/mcu0", &node)) { + propName = "board-rev"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((u_int32_t *)propData)[0] = j33_get_board_rev(); + } + + return 0; +} + +#endif + + +static u_int32_t j33_get_board_rev(void) +{ + u_int32_t gpio_board_rev; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + return (gpio_board_rev &0xF); +} diff --git a/target/j33/pinconfig.c b/target/j33/pinconfig.c new file mode 100644 index 0000000..c44b38a --- /dev/null +++ b/target/j33/pinconfig.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* S5L8942X FPGA Pin Configuration */ +#define DFU_STATUS_DRIVE_STR DRIVE_X1 +#define FMI_DRIVE_STR DRIVE_X2 + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 1 */ + CFG_OUT_1, // GPIO8 -> BT_EN + CFG_IN, // GPIO9 -> BT_WAKE + CFG_DISABLED, // GPIO10 -> + CFG_IN, // GPIO11 -> LAN_HSIC_DEVICE_RDY + CFG_DISABLED, // GPIO12 -> + CFG_IN | PULL_UP, // GPIO13 -> PMU_IRQ_L + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 2 */ + CFG_IN | PULL_DOWN, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_IN | PULL_DOWN, // GPIO18 -> BOOT_CONFIG[0] + CFG_OUT_0, // GPIO19 -> KEEPACT + CFG_IN, // GPIO20 -> WLAN0_HSIC_DEVICE_READY + CFG_IN, // GPIO21 -> USB_DEVMUX_SEL_C0 + CFG_IN, // GPIO22 -> USB_DEVMUX_SEL_C0 + CFG_DISABLED, // GPIO23 -> + +/* Port 3 */ + CFG_DISABLED, // GPIO24 -> + CFG_IN | PULL_DOWN, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_OUT_0 | DFU_STATUS_DRIVE_STR | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_IN | PULL_DOWN, // GPIO28 -> BOOT_CONFIG[2] + CFG_IN | PULL_DOWN, // GPIO29 -> BOOT_CONFIG[3] + CFG_DISABLED, // GPIO30 -> + CFG_OUT, // GPIO31 -> WLAN0_HSIC_HOST_READY + +/* Port 4 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_IN, // GPIO35 -> LAN_PHY_INT + CFG_DISABLED, // GPIO36 -> + CFG_IN | PULL_DOWN, // EHCI_PORT_PWR[0] -> BOARD_REV[0] + CFG_IN | PULL_DOWN, // EHCI_PORT_PWR[1] -> BOARD_REV[1] + CFG_IN | PULL_DOWN, // EHCI_PORT_PWR[2] -> BOARD_REV[2] + +/* Port 5 */ + CFG_FUNC0, // UART1_TXD -> BT_UART_TXD + CFG_FUNC0, // UART1_RXD -> BT_UART_RXD + CFG_OUT_1, // UART1_RTSN -> BT_UART_RTSN + CFG_FUNC0, // UART1_CTSN -> BT_UART_CTSN + CFG_FUNC0, // UART2_TXD -> AP_UART2_TXD + CFG_FUNC0, // UART2_RXD -> AP_UART2_RXD + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + +/* Port 6 */ + CFG_FUNC1, // UART3_TXD -> AP_SPDIF_OUT_1V8 + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_FUNC0, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + +/* Port 7 */ + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // UART5_TXD/MIPI_VSYNC -> + CFG_IN | PULL_DOWN, // TMR32_PWM0 -> BOARD_REV[3] + CFG_DISABLED, // TMR32_PWM1 -> IRRCVR_OUT_TO_AP_AMR_R + CFG_DISABLED, // TMR32_PWM2 + +/* Port 8 */ + CFG_FUNC0, // SWI_DATA -> SWI_AP + CFG_DISABLED, // DWI_DI -> + CFG_DISABLED, // DWI_DO -> + CFG_DISABLED, // DWI_CLK -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + +/* Port 9 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_DISABLED, // I2S0_MCK -> + CFG_FUNC0, // I2S0_LRCK -> AP_I2S0_LRCK + CFG_FUNC0, // I2S0_SCLK -> AP_I2S0_SCLK + CFG_FUNC0, // I2S0_DOUT -> AP_I2S0_DOUT + +/* Port 10 */ + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_SCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S2_LRCK -> + +/* Port 11 */ + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + +/* Port 12 */ + CFG_IN | PULL_DOWN, // SPI0_SCLK -> BOARD_ID[0] + CFG_IN | PULL_DOWN, // SPI0_MOSI -> BOARD_ID[1] + CFG_IN | PULL_DOWN, // SPI0_MISO -> BOARD_ID[2] + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 13 */ + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_FUNC0, // UART4_TXD -> UART4_TXD + CFG_FUNC0, // UART4_RXD -> UART4_RXD + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + CFG_IN, // SDIO0_DATA3 -> AP_MCU_RESET + CFG_IN, // SDIO0_DATA2 -> AP_MCU_INT + CFG_OUT, // SDIO0_DATA1 -> PME_MODE_SEL + CFG_IN, // SDIO0_DATA0 -> AP_MCU_TCK_3V0 + +/* Port 17 */ + CFG_DISABLED, // SDIO0_CMD -> + CFG_DISABLED, // SDIO0_CLK -> + CFG_DISABLED, // FMI0_CEN3 -> + CFG_DISABLED, // FMI0_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN1 -> FMI0_CEN1 + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN0 -> FMI0_CEN0 + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CLE -> FMI0_CLE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_ALE -> FMI0_ALE + +/* Port 18 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_REN -> FMI0_REN + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_WEN -> FMI0_WEN + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO7 -> FMI0_IO7 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO6 -> FMI0_IO6 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO5 -> FMI0_IO5 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO4 -> FMI0_IO4 + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 19 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 20 */ + CFG_DISABLED | PULL_DOWN, // FMI0_DQS -> FMI0_DQS + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO3 -> FMI0_IO3 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO2 -> FMI0_IO2 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO1 -> FMI0_IO1 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO0 -> FMI0_IO0 + CFG_DISABLED, // FMI1_CEN3 -> + CFG_DISABLED, // FMI1_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN1 -> FMI1_CEN1 + +/* Port 21 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN0 -> FMI1_CEN0 + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CLE -> FMI1_CLE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_ALE -> FMI1_ALE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_REN -> FMI1_REN + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_WEN -> FMI1_WEN + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO7 -> FMI1_IO7 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO6 -> FMI1_IO6 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO5 -> FMI1_IO5 + +/* Port 22 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO4 -> FMI1_IO4 + CFG_DISABLED | PULL_DOWN, // FMI1_DQS -> FMI1_DQS + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO3 -> FMI1_IO3 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO2 -> FMI1_IO2 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO1 -> FMI1_IO1 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO0 -> FMI1_IO7 + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 23 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 24 */ + CFG_FUNC0, // I2C2_SDA -> I2C2_SDA_3V0 + CFG_FUNC0, // I2C2_SCL -> I2C2_SCL_3V0 + CFG_FUNC0, // UART0_TXD -> AP_UART0_TXD + CFG_FUNC0, // UART0_RXD -> AP_UART0_RXD + CFG_FUNC0, // UART5_RTXD -> + CFG_FUNC0, // DP_HPD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 25 */ + CFG_FUNC0, // WDOG -> AP_WDOG + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/j33/rules.mk b/target/j33/rules.mk new file mode 100644 index 0000000..d580b35 --- /dev/null +++ b/target/j33/rules.mk @@ -0,0 +1,58 @@ +# Copyright (C) 2009-2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1815=1 \ + WITH_SWI_BACKLIGHT=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_MED \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_EMA_CTL_CPU_SEL=2 \ + TARGET_CPU_SOURCE=2 \ + TARGET_CPU_850M=1 \ + TARGET_DDR_256M=1 \ + TARGET_MIPI_DSI_SOURCE=1 \ + WITH_HW_BS=1 \ + TARGET_MANAGED2H_SOURCE=1 \ + TARGET_MANAGED2L_SOURCE=1 \ + TARGET_MANAGED2H_DIV=2 \ + TARGET_MANAGED2L_DIV=2 \ + TARGET_PCLK1_SOURCE=2 \ + TARGET_PCLK1_DIV=6 \ + TARGET_GFX_SOURCE=2 \ + TARGET_GFX_SLC_SOURCE=2 \ + TARGET_IOP_SOURCE=3 \ + TARGET_LPERFS_SOURCE=3 \ + TARGET_HPERFNRT_SOURCE=0 \ + TARGET_DSIM_DPHYCTL=0x30 \ + TARGET_USE_HSIC=1 \ + TARGET_USB_DEVICE_SELF_POWERED=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + ETHERNET_DTPATH=\"arm-io/usb-complex/usb-ehci/lan0\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci/wlan\" \ + WITH_TARGET_AMC_PARAMS=1 \ + WITH_TARGET_AMG_PARAMS=1 + +ifeq ($(PRODUCT),iBoot) +OPTIONS += \ + DP_DTPATH=\"arm-io/displayport\" \ + WITH_HW_DISPLAY_DISPLAYPORT=1 +endif + + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/j33i/include/target/gpiodef.h b/target/j33i/include/target/gpiodef.h new file mode 100644 index 0000000..9c2f51a --- /dev/null +++ b/target/j33i/include/target/gpiodef.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* J33i specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#define GPIO_BOARD_REV0 GPIO(12, 3) +#define GPIO_BOARD_REV1 GPIO(12, 4) +#define GPIO_BOARD_REV2 GPIO(12, 5) +#define GPIO_BOARD_REV3 GPIO(12, 6) + +#define HDMI_DDC_IIC_BUS 2 + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/j33i/include/target/nand_spec_tables.h b/target/j33i/include/target/nand_spec_tables.h new file mode 100644 index 0000000..5a23070 --- /dev/null +++ b/target/j33i/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 3, + /* socToNandFallNanosecs */ 3, + /* nandToSocRiseNanosecs */ 3, + /* nandToSocFallNanosecs */ 4, + + /* landing map */ + { + 0x00000001 + }, + + /* useToggleMode */ TRUE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ TRUE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ TRUE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/j33i/include/target/powerconfig.h b/target/j33i/include/target/powerconfig.h new file mode 100644 index 0000000..c797d2b --- /dev/null +++ b/target/j33i/include/target/powerconfig.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2009-2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +// XXX derived from values read from regs on K66 Dev 0 board; need to +// reconcile these with OTP doc (which appears to differ) and intended +// settings + +// XXX also, need to reconcile OTP settings between K66 Dev 0 and K66 Proto 0 + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kD1815_LDO1, 0x00 }, // PP2V5_BS 2.50V + { PMU_IIC_BUS, kD1815_LDO2, 0x1E }, // PP1V8_AP_PVDDP 1.80V + { PMU_IIC_BUS, kD1815_LDO3, 0x0A }, // PP3V0_USBMUX 3.00V + { PMU_IIC_BUS, kD1815_LDO4, 0x00 }, // PP1V8_AP_DAC 3.00V + { PMU_IIC_BUS, kD1815_LDO5, 0x0A }, // PPNNAD 3.00V + { PMU_IIC_BUS, kD1815_LDO6, 0x0A }, // PP3V0_MCU 3.00V + { PMU_IIC_BUS, kD1815_LDO7, 0x03 }, // PP1V8_AP_VDD 1.80V + { PMU_IIC_BUS, kD1815_LDO8, 0x00 }, // PP3V0_CPU 2.00V + { PMU_IIC_BUS, kD1815_LDO9, 0x00 }, // PP1V2_HSIC 1.20V + { PMU_IIC_BUS, kD1815_LDO10, 0x0A }, // PP3V0_IO 3.00V + { PMU_IIC_BUS, kD1815_LDO11, 0x02 }, // PP1V8_AP_VIDEO 1.80V + { PMU_IIC_BUS, kD1815_LDO12, 0x10 }, // PP1V0_AP 1.00V + + { PMU_IIC_BUS, kD1815_LCM_CONTROL1, 0x05 }, // unused + { PMU_IIC_BUS, kD1815_LCM_CONTROL2, 0x0E }, // unused + { PMU_IIC_BUS, kD1815_LCM_CONTROL3, 0x00 }, // VBOOST_LCM 5.10V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Leave bypass off +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1815_ACTIVE1, 0xFF }, // + { PMU_IIC_BUS, kD1815_ACTIVE2, 0x3F }, // + { PMU_IIC_BUS, kD1815_ACTIVE3, 0x0C }, // VBOOST_LCM, CPU_SW, WDig +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL, 0 }, // Disable SWI by default + { PMU_IIC_BUS, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS }, + + // J33i: Configure PMU Register 0x2a to 0xa8 for iBoot, iOS + { PMU_IIC_BUS, kDIALOG_BUCK_CONTROL2, 0xA8 }, + + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_A, 0xC0 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_B, 0xFF }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_C, 0xBF }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_D, 0xFF }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_E, 0xAE }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_F, 0xFF }, +}; + +// XXX: review setup for each GPIO and add back decoded description of each config +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD1815_SYS_GPIO_1, 0xB9 }, // ENBL_USB_BUFF_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_2, 0xBA }, // LAN_PME_PMU + { PMU_IIC_BUS, kD1815_SYS_GPIO_3, 0xBA }, // WLAN_WAKE_HOST + { PMU_IIC_BUS, kD1815_SYS_GPIO_4, 0x03 }, // ENET_PWR_EN_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_5, 0x01 }, // WLAN_PWR_EN_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_6, 0xFA }, // VBAT_DETECT + { PMU_IIC_BUS, kD1815_SYS_GPIO_7, 0xBA }, // BT_HOST_WAKE + { PMU_IIC_BUS, kD1815_SYS_GPIO_8, 0x18 }, // WLAN_RESET_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_TEMP, 0x18 }, // LAN_RESET_L + { PMU_IIC_BUS, kD1815_SYS_GPIO_SPARE, 0x4B }, // WLAN_CLK32K_R + { PMU_IIC_BUS, kD1815_SYS_GPIO_DEB6, 0x80 }, // enable 32kHz clocks in hibernate +}; + +static const struct core_rails_struct soc_rails[] = +{ +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_POWER_NO_BATTERY 1 +#define TARGET_POWER_USB_MASK STATUS_FLAG_MAKE(0, kD1815_STATUS_A_VBUS_EXT) +#define ALWAYS_BOOT_BATTERY_VOLTAGE (3000) +#define PRECHARGE_BACKLIGHT_LEVEL 103 + +#endif diff --git a/target/j33i/include/target/uartconfig.h b/target/j33i/include/target/uartconfig.h new file mode 100644 index 0000000..5b99043 --- /dev/null +++ b/target/j33i/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (3) + +#define MCU_SERIAL_PORT (1) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/j33i/init.c b/target/j33i/init.c new file mode 100644 index 0000000..1991074 --- /dev/null +++ b/target/j33i/init.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2009-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static u_int32_t j33i_get_board_rev(void); + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); +static uint32_t display_config; + +void target_early_init(void) +{ + // J33i: HDMI DDC - change tSU;STA interval (iOS & iBoot). + iic_set_filter(2, 0x4A334009); + + // J33i: iBoot DDC speed should be ~50 kHz + iic_set_frequency(2, 50000); +} + +void target_late_init(void) +{ +#if WITH_HW_MCU + // Late display initialization. Needed to wait for MCU. + mcu_init(); +#endif +#if WITH_HW_DISPLAY_HDMI + // Backgrounded. See hdmi_device_wait_started() call below. + hdmi_init(); +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ + +#if WITH_HW_MCU + // radar 9746416 -- UART4 left in interrupt mode will cause kernel panic + mcu_quiesce_uart(); +#endif +} + +void target_poweroff(void) +{ +} + +int target_debug_init(void) +{ +#if WITH_HW_MCU + mcu_start_recover(); +#endif + + return 0; +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DIAGS: +#if WITH_HW_MCU +#if WITH_HW_DISPLAY_HDMI && PRODUCT_IBOOT + /* Potentially delay boot so we have a + * logo. We might have to do this if a + * connected TV is particularly slow at + * responding to EDID. Sorry. */ + hdmi_device_wait_started(); +#endif + mcu_start_boot(); +#endif + break; + case BOOT_DARWIN_RESTORE: + break; + default: + // do nothing + break; + } + + return 0; +} + +bool target_should_recover(void) +{ + // trigger recovery mode whenever USB is attached, unless + // environment variable says otherwise. + + return power_has_usb() && !env_get_bool("auto-boot-usb", true); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + // always powers on + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + // never power off + return false; +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ +// u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); +// gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000000; + return ((void *)&display_config); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "720p-hdmi", 0); + env_set("idle-off", "false", 0); // do not idle off; there is no battery and this will just reboot (8035422) +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Update the pmu node with the actual vcore values + if (FindNode(0, "arm-io/i2c0/pmu", &node)) { + propName = "swi-vcores"; + if (FindProperty(node, &propName, &propData, &propSize)) { + platform_get_soc_voltages(propSize / sizeof(u_int32_t), propData); + } + } + + if (FindNode(0, "arm-io/mcu0", &node)) { + propName = "board-rev"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((u_int32_t *)propData)[0] = j33i_get_board_rev(); + } + + return 0; +} + +#endif + + +static u_int32_t j33i_get_board_rev(void) +{ + u_int32_t gpio_board_rev; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + return (gpio_board_rev &0xF); +} diff --git a/target/j33i/pinconfig.c b/target/j33i/pinconfig.c new file mode 100644 index 0000000..d8bb00f --- /dev/null +++ b/target/j33i/pinconfig.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* S5L8947X FPGA Pin Configuration */ +#define DFU_STATUS_DRIVE_STR DRIVE_X1 +#define FMI_DRIVE_STR DRIVE_X2 + +static const u_int32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // 00/I2S0_MCK -> AP_TO_MCU_RESET_3V0_L + CFG_IN, // 01/I2S0_LRCK -> AP_TO_MCU_TCK_3V0 + CFG_IN, // 02/I2S0_BCLK -> AP_MCU_INT + CFG_DISABLED, // 03/I2S0_DOUT -> + CFG_OUT, // 04/I2S0_DIN -> VCORE_ADJ_R + CFG_FUNC0, // 05/UART0_TXD -> UART0_TXD + CFG_FUNC0, // 06/UART0_RXD -> UART0_RXD + CFG_FUNC0, // 07/UART1_TXD -> UART1_TXD +/* Port 1 */ + CFG_FUNC0, // 08/UART1_RXD -> UART1_RXD + CFG_FUNC0, // 09/I2C1_SDA -> I2C1_SDA_3V0 + CFG_FUNC0, // 10/I2C1_SCL -> I2C1_SCL_3V0 + CFG_FUNC0, // 11/HDMI_HPD -> HDMI_HDP + CFG_FUNC0, // 12/HDMI_CEC -> HDMI_CEC + CFG_FUNC0, // 13/I2C2_SDA -> AP_DDC_DATA_3V0 + CFG_FUNC0, // 14/I2C2_SCL -> AP_DDC_CLK_3V0 + CFG_FUNC0, // 15/SPDIF -> AP_SPDIF_OUT_R_3V0 +/* Port 2 */ + CFG_IN, // 16/GPIO22 -> USB_DEVMUX_SEL_C0, + CFG_DISABLED, // 17/GPIO23 -> + CFG_FUNC0, // 18/UART2_TXD -> AP_UART2_TXD + CFG_FUNC0, // 19/UART2_RXD -> AP_UART2_RXD + CFG_OUT_1, // 20/UART2_RTSN -> AP_UART2_RTS_L + CFG_FUNC0, // 21/UART2_CTSN -> AP_UART2_CTS_L + CFG_FUNC0, // 22/UART3_TXD -> UART3_TXD + CFG_FUNC0, // 23/UART3_RXD -> UART3_RXD +/* Port 3 */ + CFG_FUNC0, // 24/UART4_TXD -> UART4_TXD + CFG_FUNC0, // 25/UART4_RXD -> UART4_RXD + CFG_DISABLED, // 26/TST_CLKOUT -> + CFG_DISABLED, // 27/TST_STPCLK -> + CFG_FUNC0, // 28/WDOG -> AP_WDOG + CFG_DISABLED, // 29 + CFG_DISABLED, // 30 + CFG_DISABLED, // 31 +/* Port 4 */ + CFG_FUNC0, // 32/ENET_MDC -> ENET_MDC + CFG_FUNC0, // 33/ENET_MDIO -> ENET_MDIO + CFG_FUNC0, // 34/RMII_CLK -> RMII_CLK + CFG_FUNC0, // 35/RMII_RXER -> RMII_RXER + CFG_FUNC0, // 36/RMII_TXD0 -> RMII_TXD0 + CFG_FUNC0, // 37/RMII_CRSDV -> RMII_CRSDV + CFG_FUNC0, // 38/RMII_RXD0 -> RMII_RXD0 + CFG_FUNC0, // 39/RMII_RXD1 -> RMII_RXD1 +/* Port 5 */ + CFG_FUNC0, // 40/RMII_TXD1 -> RMII_TXD1 + CFG_FUNC0, // 41/RMII_TXEN -> RMII_TXEN + CFG_FUNC0 | FMI_DRIVE_STR, // 42/FMI0_CEN1 -> FMI0_CEN1 + CFG_FUNC0 | FMI_DRIVE_STR, // 43/FMI0_CEN0 -> FMI0_CEN0 + CFG_FUNC0 | FMI_DRIVE_STR, // 44/FMI0_CLE -> FMI0_CLE + CFG_FUNC0 | FMI_DRIVE_STR, // 45/FMI0_ALE -> FMI0_ALE + CFG_FUNC0 | FMI_DRIVE_STR, // 46/FMI0_REN -> FMI0_REN + CFG_FUNC0 | FMI_DRIVE_STR, // 47/FMI0_WEN -> FMI0_WEN +/* Port 6 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 48/FMI0_IO7 -> FMI0_IO7 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 49/FMI0_IO6 -> FMI0_IO6 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 50/FMI0_IO5 -> FMI0_IO5 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 51/FMI0_IO4 -> FMI0_IO4 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 52/FMI0_DQS -> FMI0_DQS + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 53/FMI0_IO3 -> FMI0_IO3 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 54/FMI0_IO2 -> FMI0_IO2 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 55/FMI0_IO1 -> FMI0_IO1 +/* Port 7 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 56/FMI0_IO0 -> FMI0_IO0 + CFG_FUNC0 | FMI_DRIVE_STR, // 57/FMI1_CEN1 -> FMI1_CEN1 + CFG_FUNC0 | FMI_DRIVE_STR, // 58/FMI1_CEN0 -> FMI1_CEN0 + CFG_FUNC0 | FMI_DRIVE_STR, // 59/FMI1_CLE -> FMI1_CLE + CFG_FUNC0 | FMI_DRIVE_STR, // 60/FMI1_ALE -> FMI1_ALE + CFG_FUNC0 | FMI_DRIVE_STR, // 61/FMI1_REN -> FMI1_REN + CFG_FUNC0 | FMI_DRIVE_STR, // 62/FMI1_WEN -> FMI1_WEN + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 63/FMI1_IO7 -> FMI1_IO7 +/* Port 8 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 64/FMI1_IO6 -> FMI1_IO6 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 65/FMI1_IO5 -> FMI1_IO5 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 66/FMI1_IO4 -> FMI1_IO4 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 67/FMI1_DQS -> FMI1_DQS + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 68/FMI1_IO3 -> FMI1_IO3 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 69/FMI1_IO2 -> FMI1_IO2 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 70/FMI1_IO1 -> FMI1_IO1 + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // 71/FMI1_IO0 -> FMI1_IO0 +/* Port 9 */ + CFG_DISABLED, // 72 + CFG_DISABLED, // 73 + CFG_DISABLED, // 74 + CFG_DISABLED, // 75 + CFG_DISABLED, // 76 + CFG_DISABLED, // 77 + CFG_DISABLED, // 78 + CFG_DISABLED, // 79 +/* Port 10 */ + CFG_DISABLED, // 80 + CFG_DISABLED, // 81 + CFG_DISABLED, // 82 + CFG_DISABLED, // 83 + CFG_DISABLED, // 84 + CFG_DISABLED, // 85 + CFG_DISABLED, // 86 + CFG_DISABLED, // 87 +/* Port 11 */ + CFG_DISABLED, // 88 + CFG_DISABLED, // 89 + CFG_DISABLED, // 90 + CFG_DISABLED, // 91 + CFG_DISABLED, // 92 + CFG_DISABLED, // 93 + CFG_DISABLED, // 94 + CFG_DISABLED, // 95 +/* Port 12 */ + CFG_IN, // 96/GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // 97/GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // 98/GPIO2 -> + CFG_IN | PULL_DOWN, // 99/GPIO3 -> BOARD_REV[0] + CFG_IN | PULL_DOWN, // 00/GPIO4 -> BOARD_REV[1] + CFG_IN | PULL_DOWN, // 01/GPIO5 -> BOARD_REV[2] + CFG_IN | PULL_DOWN, // 02/GPIO6 -> BOARD_REV[3] + CFG_DISABLED, // 03/GPIO7 -> +/* Port 13 */ + CFG_OUT_1, // 04/GPIO8 -> BT_EN + CFG_IN, // 05/GPIO9 -> BT_WAKE + CFG_DISABLED, // 06/GPIO10 -> + CFG_IN, // 07/GPIO11 -> LAN_HSIC_DEVICE_RDY + CFG_DISABLED, // 08/GPIO12 -> + CFG_IN | PULL_UP, // 09/GPIO13 -> PMU_IRQ_L + CFG_DISABLED, // 10/GPIO14 -> + CFG_DISABLED, // 11/GPIO15 -> +/* Port 14 */ + CFG_IN | PULL_DOWN, // 12/GPIO16 -> BOARD_ID[3] + CFG_OUT, // 13/GPIO17 -> WLAN0_HSIC_HOST_READY + CFG_IN | PULL_DOWN, // 14/GPIO18 -> BOOT_CONFIG[0] + CFG_OUT_0, // 15/GPIO19 -> KEEPACT + CFG_DISABLED, // 16 + CFG_DISABLED, // 17 + CFG_DISABLED, // 18 + CFG_DISABLED, // 19 +/* Port 15 */ + CFG_DISABLED, // 20 + CFG_DISABLED, // 21 + CFG_DISABLED, // 22 + CFG_DISABLED, // 23 + CFG_DISABLED, // 24 + CFG_DISABLED, // 25 + CFG_DISABLED, // 26 + CFG_DISABLED, // 27 +/* Port 16 */ + CFG_IN, // 28/GPIO20 -> WLAN0_HSIC_DEVICE_READY + CFG_IN, // 29/GPIO21 -> USB_DEVMUX_SEL_C0 + CFG_DISABLED, // 30/GPIO24 -> + CFG_IN | PULL_DOWN, // 31/GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // 32/GPIO26 -> FORCE_DFU + CFG_OUT_0 | DFU_STATUS_DRIVE_STR | PULL_DOWN, // 33/GPIO27 -> DFU_STATUS + CFG_IN | PULL_DOWN, // 34/GPIO28 -> BOOT_CONFIG[2] + CFG_IN | PULL_DOWN, // 35/GPIO29 -> BOOT_CONFIG[3] +/* Port 17 */ + CFG_FUNC0, // 36/I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0, // 37/I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED, // 38/TMR32_PWM0 -> + CFG_IN | PULL_DOWN, // 39/SPI0_SCLK -> BOARD_ID[0] + CFG_IN | PULL_DOWN, // 40/SPI0_MOSI -> BOARD_ID[1] + CFG_IN | PULL_DOWN, // 41/SPI0_MISO -> BOARD_ID[2] + CFG_DISABLED | PULL_UP, // 42/SPI0_SSIN -> + CFG_FUNC0, // 43/SWI_DATA -> SWI_AP +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/j33i/rules.mk b/target/j33i/rules.mk new file mode 100644 index 0000000..bf075b1 --- /dev/null +++ b/target/j33i/rules.mk @@ -0,0 +1,52 @@ +# Copyright (C) 2009-2010 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1815=1 \ + WITH_SWI_BACKLIGHT=1 \ + TARGET_CPU_SOURCE=2 \ + TARGET_CPU_850M=1 \ + TARGET_DDR_533M=1 \ + TARGET_MIPI_DSI_SOURCE=0 \ + WITH_HW_BS=1 \ + TARGET_MANAGED2H_SOURCE=1 \ + TARGET_MANAGED2L_SOURCE=1 \ + TARGET_MANAGED2H_DIV=2 \ + TARGET_MANAGED2L_DIV=2 \ + TARGET_PCLK1_SOURCE=2 \ + TARGET_PCLK1_DIV=10 \ + TARGET_GFX_SOURCE=3 \ + TARGET_GFX_SLC_SOURCE=3 \ + TARGET_IOP_SOURCE=0 \ + TARGET_LPERFS_SOURCE=0 \ + TARGET_HPERFNRT_SOURCE=2 \ + TARGET_USE_PREDIV4=1 \ + TARGET_PREDIV4_DIV=2 \ + TARGET_PREDIV4_SOURCE=3 \ + TARGET_USE_HSIC=1 \ + TARGET_USB_DEVICE_SELF_POWERED=1 \ + AMC_NUM_CHANNELS=1 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + BT_DTPATH=\"arm-io/uart2/bluetooth\" \ + ETHERNET_DTPATH=\"arm-io/ethernet\" \ + WIFI_DTPATH=\"arm-io/usb0-complex/usb0-ehci/wlan\" + +ifeq ($(PRODUCT),iBoot) +OPTIONS += \ + WITH_HW_DISPLAY_HDMI=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/j34/include/target/adbe_settings.h b/target/j34/include/target/adbe_settings.h new file mode 100644 index 0000000..a4b9be1 --- /dev/null +++ b/target/j34/include/target/adbe_settings.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + + /* + * disable all clock gating until SEG resolves: + * J34: adbe dynamic clock gating causes no video on dp_tx + */ + .adbe0_tunable_mode_ctrl = 0, + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/j34/include/target/amcconfig.h b/target/j34/include/target/amcconfig.h new file mode 100644 index 0000000..e224683 --- /dev/null +++ b/target/j34/include/target/amcconfig.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_ZQCL), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00020000, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 10, + .phywrlat = 2, + .pdn = 0x22000403, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .derate = 0x2483135b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x00000021, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00050000, + .aref_freq0 = 0x00000110, + .schen_default = 0x00000110, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x01, + .pwrmngten_default = 0x00100100, + .mcphyupdate1 = 0x00000001, + .odts = 0x190, + .readleveling = 0x00000300, + .offset_shift_hynix = 0, + .offset_shift_elpida = 1, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + .mifcassch = 0x00000110, + .arefparam = 0x0c022131, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 50MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001728 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQBRST, 0x04100410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOS, 0x00001919 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +}; diff --git a/target/j34/include/target/aspnandconfig.h b/target/j34/include/target/aspnandconfig.h new file mode 100644 index 0000000..6bb9e47 --- /dev/null +++ b/target/j34/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/j34/include/target/gpiodef.h b/target/j34/include/target/gpiodef.h new file mode 100644 index 0000000..dd8cd87 --- /dev/null +++ b/target/j34/include/target/gpiodef.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* j34 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 6) +#define GPIO_BOARD_REV1 GPIO(14, 5) +#define GPIO_BOARD_REV2 GPIO(14, 4) +#define GPIO_BOARD_REV3 GPIO(14, 3) + +/* which IICs to initialize */ +#define IICS_MASK (0xD) + +#define TRISTAR_IIC_BUS (2) + +/* D2089 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(12, 6) + +#define POWER_GPIO_HVR_RESET_L (5) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/j34/include/target/powerconfig.h b/target/j34/include/target/powerconfig.h new file mode 100644 index 0000000..726b7b6 --- /dev/null +++ b/target/j34/include/target/powerconfig.h @@ -0,0 +1,84 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2089_ACTIVE2, 0x03 }, // WLEDA/B BST +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* GPIO configuration from I/O spreadsheet. + J34: IOSpreadsheet + Request spreadsheet update before modifying + */ + { PMU_IIC_BUS, kD2089_GPIO2, 0xA3 }, // PMU_MOCA2PMU_HOST_WAKE In, R Edge, Wake, PD, VCC_MAIN + { PMU_IIC_BUS, kD2089_GPIO3, 0x09 }, // PMU_GPIO_BT_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO4, 0x09 }, // PMU_GPIO_WLAN_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO6, 0x18 }, // PMU_HVR_RESET_L Out 0, Open-Drain, No PU + { PMU_IIC_BUS, kD2089_GPIO7, 0xBA }, // PMU_GPIO_BT2PMU_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO8, 0xBA }, // PMU_GPIO_WLAN2PMU_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO9, 0xA3 }, // LAN_PME_PMU In, R Edge, Wake, PD, VCC_MAIN + { PMU_IIC_BUS, kD2089_GPIO10, 0x18 }, // MOCA_PWRON Out 0, Open-Drain, No PU + { PMU_IIC_BUS, kD2089_GPIO11, 0x18 }, // PMU_LAN_RESET_L Out 0, Open-Drain, No PU + { PMU_IIC_BUS, kD2089_GPIO12, 0x7B }, // GPIO_TS2SOC2PMU_INT In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO13, 0x18 }, // PMU_MOCA_RESET_L Out 0, Open-Drain, No PU + { PMU_IIC_BUS, kD2089_GPIO15, 0xA3 }, // LAN2_PME_PMU In, R Edge, Wake, PD, VCC_MAIN + { PMU_IIC_BUS, kD2089_GPIO16, 0x18 }, // PMU_LAN2_RESET_L Out 0, Open-Drain, No PU + { PMU_IIC_BUS, kD2089_GPIO17, 0xA1 }, // VBAT_DETECT In, R Edge, PD, VCC_MAIN + + { PMU_IIC_BUS, kD2089_BUCK_DWI_CTRL0, 0x03 }, // enable DWI for BUCK0, BUCK1 + { PMU_IIC_BUS, kD2089_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + + { PMU_IIC_BUS, kD2089_RESET_IN3_CONF, 0x11 }, // Disable RESET_IN3 for SOCHOT1 +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_POWER_NO_BATTERY 1 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (3000) +#define PRECHARGE_BACKLIGHT_LEVEL 103 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/j34/include/target/uartconfig.h b/target/j34/include/target/uartconfig.h new file mode 100644 index 0000000..1197661 --- /dev/null +++ b/target/j34/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (3) + +#define MCU_SERIAL_PORT (1) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/j34/include/target/usbconfig.h b/target/j34/include/target/usbconfig.h new file mode 100644 index 0000000..0fba0e5 --- /dev/null +++ b/target/j34/include/target/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_OTGTUNE0 + +#undef USBPHY_OTGTUNE0 +#define USBPHY_OTGTUNE0 (0x37449373) + +#endif /* USBPHY_OTGTUNE0 */ + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/j34/init.c b/target/j34/init.c new file mode 100644 index 0000000..b1896e5 --- /dev/null +++ b/target/j34/init.c @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define J34_DEV0A_BOARD (0xF) //Has Hoover and Bluesteel +#define J34_DEV0B_BOARD (0xE) //Has Hoover and Bluesteel +#define J34_DEV1_BOARD (0xD) //Hoover Only + +#define J34_POC_BOARD (0x8) //Hoover Only +#define J34_PROTO1_BOARD (0x9) //Hoover Only +#define J34_PROTO2_BOARD (0xA) //Hoover Only +#define J34_EVT_BOARD (0xB) //Hoover Only +#define J34_DVT_BOARD (0xC) //Hoover Only +#define J34_PVT_BOARD (0xF) //Hoover Only + +// Do not delay iBoot by more than this amount from power on (microseconds). +// Give up waiting for a boot logo and carry on at this point. +#define kDPDeviceStartTimeout (8 * 1000 * 1000) +extern utime_t gPowerOnTime; +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; +#if WITH_HW_DISPLAY_DISPLAYPORT +static dp_t dp_link_config = { + .mode = 1, + .type = 0, + .min_link_rate = 0xa, + .max_link_rate = 0xa, + .lanes = 4, + .ssc = 0, + .alpm = 0, + .vrr_enable = 0, + .vrr_on = 0, +}; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static u_int32_t j34_get_board_rev(void) +{ + + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + if (target_config_ap()) { + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + } else { + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + } + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + printf("board_rev 0x%x\n", gpio_board_rev); + + return gpio_board_rev; +} + +static void j34_reset_hoover(bool reset) +{ + power_set_gpio(POWER_GPIO_HVR_RESET_L, 1, !reset); +} + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + if (target_config_dev() && j34_get_board_rev() == J34_DEV0A_BOARD) { + platform_not_supported(); + } + +#if WITH_HW_MCU + // Late display initialization. Needed to wait for MCU. + mcu_init(); +#if WITH_HW_DISPLAY_DISPLAYPORT + // Backgrounded. See dp_device_wait_started() call below. + displayport_init(&dp_link_config); + j34_reset_hoover(false); +#endif +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +#if WITH_HW_MCU + // radar 9746416 -- UART4 left in interrupt mode will cause kernel panic + mcu_quiesce_uart(); +#endif +} + +void target_poweroff(void) +{ +} + +int target_debug_init(void) +{ +#if WITH_HW_MCU + mcu_start_recover(); +#endif + + return 0; +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DIAGS: +#if WITH_HW_MCU +#if WITH_HW_DISPLAY_DISPLAYPORT && PRODUCT_IBOOT + /* Potentially delay boot so we have a + * logo. We might have to do this if a + * connected TV is particularly slow at + * responding to EDID. Sorry. */ + dp_device_wait_started(gPowerOnTime + kDPDeviceStartTimeout); +#endif + mcu_start_boot(); +#endif + break; + case BOOT_DARWIN_RESTORE: + break; + default: + // do nothing + break; + } + + return 0; +} + +bool target_should_recover(void) +{ + // trigger recovery mode whenever USB is attached, unless + // environment variable says otherwise. + + return power_has_usb() && !env_get_bool("auto-boot-usb", true); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + // always powers on + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + // never power off + return false; +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if WITH_HW_DISPLAY_DISPLAYPORT + return ((void *)(&dp_link_config)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "720p-j34", 0); + env_set("idle-off", "false", 0); // do not idle off; there is no battery and this will just reboot (8035422) +} + +#endif // WITH_ENV + +bool target_has_tristar2(void) +{ + return false; +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Update the pmu node with the actual vcore values + if (FindNode(0, "arm-io/i2c0/pmu", &node)) { + propName = "swi-vcores"; + if (FindProperty(node, &propName, &propData, &propSize)) { + platform_get_soc_voltages(propSize / sizeof(u_int32_t), propData); + } + } + // + // TriStar 1 on older systems + if (!target_has_tristar2()) { + if (FindNode(0, "arm-io/i2c2/tristar", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "tristar,cbtl1608", kPropNameLength); + } + } + } + + if (FindNode(0, "arm-io/mcu0", &node)) { + propName = "board-rev"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((u_int32_t *)propData)[0] = j34_get_board_rev(); + } + + // Store pinto mac address into products node + if (FindNode(0, "product", &node)) { + propName = "mac-address-pinto0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("pintoaddr")) { + env_get_ethaddr("pintoaddr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_PINTO_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + // Store pinto mac address into pinto node + if (FindNode(0, "arm-io/spi1/pinto", &node)) { + propName = "local-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("pintoaddr")) { + env_get_ethaddr("pintoaddr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_PINTO_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + // Store RBDA (Remote Bluetooth Device Address) into products node + if (FindNode(0, "product", &node)) { + propName = "bluetooth-dev-addr0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("rbdaddr0")) { + env_get_ethaddr("rbdaddr0", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_BLUETOOTH_DEV_MACADDR0, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + return 0; +} +#endif diff --git a/target/j34/pinconfig.c b/target/j34/pinconfig.c new file mode 100644 index 0000000..aac983b --- /dev/null +++ b/target/j34/pinconfig.c @@ -0,0 +1,271 @@ +/* + * Copyright (C) YEAR Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: version 1.02 + I/O Spreadsheet tracker: 14986084 +*/ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO0 -> MCU_AP_RECOVERY_MODE_L + CFG_IN, // 3 : GPIO1 -> MCU_PMU_WAKE_L + CFG_IN, // 4 : GPIO2 -> GPIO_BTN_VOL_DOWN_L + CFG_IN, // 5 : GPIO3 -> GPIO_BTN_VOL_UP_L + CFG_DISABLED, // 6 : GPIO4 -> NC_GPIO_MOCA_PLUG_DETECT + CFG_OUT_0 | FAST_SLEW, // 7 : GPIO5 -> GPIO_SOC2BT_WAKE + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO6 -> AP_MCU_INT_1V8 + CFG_IN | PULL_UP, // 9 : GPIO7 -> AP_TO_MCU_TCK_1V8 + CFG_IN, // 10 : GPIO8 -> LAN_PHY_INT_1V8 + CFG_IN, // 11 : GPIO9 -> LAN2_PHY_INT_1V8 + CFG_OUT_0 | FAST_SLEW, // 12 : GPIO10 -> LAN_PME_MODE_SEL_AP_1V8 + CFG_OUT_0 | FAST_SLEW, // 13 : GPIO11 -> LAN2_PME_MODE_SEL_AP_1V8 + CFG_IN, // 14 : GPIO12 -> HVR_IRQ + CFG_IN | PULL_DOWN, // 15 : GPIO13 -> LAN_HSIC_DEVICE_READY_1V8 + +/* Port 2 */ + CFG_IN | PULL_DOWN, // 16 : GPIO14 -> LAN2_HSIC_DEVICE_READY_1V8 + CFG_IN, // 17 : GPIO15 -> MOCA_IRQ_1V8 + CFG_IN | PULL_DOWN, // 18 : GPIO16 -> GPIO_BOARD_ID_3 + CFG_IN, // 19 : GPIO17 -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_DOWN, // 20 : GPIO18 -> GPIO_BOOT_CONFIG_0 + CFG_OUT_0 | FAST_SLEW, // 21 : GPIO19 -> PMON_SWCLK + CFG_IN, // 22 : GPIO20 -> PMON_MCU_TO_SOC_2V05_1 + CFG_IN | FAST_SLEW, // 23 : GPIO21 -> PMON_SWDIO + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | FAST_SLEW, // 32 : UART1_TXD -> AP_UART1_TXD_1V8 + CFG_FUNC0, // 33 : UART1_RXD -> AP_UART1_RXD_1V8 + CFG_DISABLED, // 34 : UART1_RTSN -> NC_UART1_RTS_L + CFG_DISABLED, // 35 : UART1_CTSN -> NC_UART1_RTS_L + CFG_FUNC0 | FAST_SLEW, // 36 : UART2_TXD -> UART2_SOC_TO_PMON_R + CFG_FUNC0, // 37 : UART2_RXD -> UART2_PMON_TO_SOC + CFG_DISABLED, // 38 : UART2_RTSN -> NC_GPIO_UART2_RTSN + CFG_DISABLED, // 39 : UART2_CTSN -> NC_GPIO_UART2_CTSN + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 40 : UART3_TXD -> AP_UART3_TXD_1V8 + CFG_FUNC0, // 41 : UART3_RXD -> AP_UART3_RXD_1V8 + CFG_DISABLED, // 42 : UART3_RTSN -> NC_UART3_BB_RTS_L + CFG_DISABLED, // 43 : UART3_CTSN -> NC_UART3_BB_CTS_: + CFG_FUNC0, // 44 : UART5_RTXD -> NC_UART5 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_FUNC0 | FAST_SLEW, // 64 : UART4_TXD -> UART4_BT_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_BT_RXD + CFG_FUNC0 | FAST_SLEW, // 66 : UART4_RTSN -> UART4_BT_RTS_L + CFG_FUNC0, // 67 : UART4_CTSN -> UART4_BT_CTS_L + CFG_FUNC0 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_SOC_SCLK_1V8 + CFG_FUNC0 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_SOC_MOSI_1V8 + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_SOC_MISO_1V8 + CFG_FUNC0 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_SOC_CS_L_1V8 + +/* Port 9 */ + CFG_IN | PULL_DOWN, // 72 : SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_IN | PULL_DOWN, // 73 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_IN | PULL_DOWN, // 74 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_DISABLED, // 76 : SPI2_SCLK -> NC_SPI2_SCLK + CFG_DISABLED, // 77 : SPI2_MOSI -> NC_SPI2_MOSI + CFG_DISABLED, // 78 : SPI2_MISO -> NC_SPI2_MISO + CFG_DISABLED, // 79 : SPI2_SSIN -> NC_SPI2_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 82 : I2C1_SDA -> I2C1_HOOVR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 83 : I2C1_SCL -> I2C1_HOOVR_SCL + CFG_DISABLED, // 84 : ISP0_SDA -> TP_ISP0_CAM_REAR_SDA + CFG_DISABLED, // 85 : ISP0_SCL -> TP_ISP0_CAM_REAR_SCL + CFG_DISABLED, // 86 : ISP1_SDA -> TP_ISP1_CAM_FRONT_SDA + CFG_DISABLED, // 87 : ISP1_SCL -> TP_ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_DISABLED, // 88 : SENSOR0_RST -> NC_ISP0_CAM_REAR_CLK + CFG_DISABLED, // 89 : SENSOR0_CLK -> NC_ISP0_CAM_REAR_SHUTDOWN + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC_SENSOR0_ISTRB + CFG_DISABLED, // 92 : SENSOR1_RST -> NC_ISP1_CAM_FRONT_SHUTDOWN_L + CFG_DISABLED, // 93 : SENSOR1_CLK -> NC_ISP1_CAM_FRONT_CLK + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> NC_SENSOR1_XSHUTDOWN + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> NC_SENSOR1_ISTRB + +/* Port 12 */ + CFG_DISABLED, // 96 : SPI3_MOSI -> NC_SPI3_MOSI + CFG_DISABLED, // 97 : SPI3_MISO -> NC_SPI3_MISO + CFG_DISABLED, // 98 : SPI3_SCLK -> NC_SPI3_SCLK + CFG_DISABLED, // 99 : SPI3_SSIN -> NC_SPI3_CS_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_OUT_0 | FAST_SLEW, // 102 : GPIO22 -> GPIO_SOC2PMU_KEEPACT + CFG_IN | PULL_UP, // 103 : GPIO23 -> GPIO_PMU2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED, // 104 : GPIO24 -> NC_GPIO24 + CFG_IN | PULL_DOWN, // 105 : GPIO25 -> GPIO_BOOT_CONFIG_1 + CFG_IN, // 106 : GPIO26 -> GPIO_FORCE_DFU + CFG_OUT_0 | FAST_SLEW, // 107 : GPIO27 -> MCU_DFU_STATUS_1V8 + CFG_IN | PULL_DOWN, // 108 : GPIO28 -> GPIO_BOOT_CONFIG_2 + CFG_IN | PULL_DOWN, // 109 : GPIO29 -> GPIO_BOOT_CONFIG_3 + CFG_IN, // 110 : GPIO30 -> GPIO_BTN_SRL_L + CFG_IN, // 111 : GPIO31 -> SOC_TO_PMON_RESET_1V8_L + +/* Port 14 */ + CFG_DISABLED, // 112 : GPIO32 -> NC_GPIO32 + CFG_IN, // 113 : GPIO33 -> PMON_ISP_EN_N + CFG_IN, // 114 : GPIO34 -> SOC_TO_MCU_RESET_1V8_L + CFG_IN | PULL_DOWN, // 115 : GPIO35 -> GPIO_BRD_REV3 + CFG_IN | PULL_DOWN, // 116 : GPIO36 -> GPIO_BRD_REV2 + CFG_IN | PULL_DOWN, // 117 : GPIO37 -> GPIO_BRD_REV1 + CFG_IN | PULL_DOWN, // 118 : GPIO38 -> GPIO_BRD_REV0 + CFG_DISABLED, // 119 : DISP_VSYNC -> NC_DISPLAY_SYNC + +/* Port 15 */ + CFG_IN, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_OUT_0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0, // 122 : UART0_TXD -> AP_UART0_TXD_1V8 + CFG_FUNC0, // 123 : UART0_RXD -> AP_UART0_RXD_1V8 + CFG_OUT_0, // 124 : DWI_DI -> SOC_TST_CPUSWITCH_OUT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 125 : DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_HOOVR_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_HOOVR_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_HOOVR_DOUT + CFG_DISABLED, // 131 : I2S0_DIN -> TP_I2S0_DIN + CFG_DISABLED, // 132 : I2S1_MCK -> NC_I2S1_MCK + CFG_DISABLED, // 133 : I2S1_LRCK -> TP_I2S1_LRCK + CFG_DISABLED, // 134 : I2S1_BCLK -> TP_I2S1_BCLK + CFG_DISABLED, // 135 : I2S1_DOUT -> TP_I2S1_DOUT + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S1_DIN -> TP_I2S1_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> TP_I2S2_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> TP_I2S2_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> TP_I2S2_DOUT + CFG_DISABLED, // 140 : I2S2_DIN -> TP_I2S2_DIN + CFG_DISABLED, // 141 : I2S3_MCK -> TP_I2S3_MCK + CFG_DISABLED, // 142 : I2S3_LRCK -> TP_I2S3_LRCK + CFG_DISABLED, // 143 : I2S3_BCLK -> TP_I2S3_BCLK + +/* Port 18 */ + CFG_FUNC0 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_WLAN_TXD + CFG_DISABLED, // 145 : I2S3_DIN -> TP_I2S3_DIN + CFG_DISABLED, // 146 : I2S4_MCK -> NC_I2S4_MCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 147 : I2S4_LRCK -> I2S4_BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 148 : I2S4_BCLK -> I2S4_BT_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 149 : I2S4_DOUT -> I2S4_BT_DOUT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 150 : I2S4_DIN -> I2S4_BT_DIN + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : TMR32_PWM0 -> NC_TMR32_PWM0 + CFG_DISABLED, // 161 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 162 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_OUT_0 | FAST_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_DISABLED, // 166 : SIO_7816UART1_SDA -> NC_SIO_SDA + CFG_DISABLED, // 167 : SIO_7816UART1_SCL -> NC_SIO_SCL + +/* Port 21 */ + CFG_DISABLED, // 168 : SIO_7816UART1_RST -> NC_SIO_RST + CFG_FUNC0 | FAST_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_DISABLED, // 171 : I2C3_SDA -> NC_I2C3_SDA_1V8 + CFG_DISABLED, // 172 : I2C3_SCL -> NC_I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | FAST_SLEW, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_HOOVR_MCK + CFG_DISABLED, // 194 : I2S2_MCK -> TP_I2S2_MCK +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/j34/properties.c b/target/j34/properties.c new file mode 100644 index 0000000..3129d11 --- /dev/null +++ b/target/j34/properties.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/j34/rules.mk b/target/j34/rules.mk new file mode 100644 index 0000000..8678270 --- /dev/null +++ b/target/j34/rules.mk @@ -0,0 +1,54 @@ +# Copyright (C) 2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2089=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_SPARE0_CLK_CFG=0x81000001 \ + TARGET_VID0_CLK_CFG=0x81000000 \ + WITH_HW_HOOVER=1 \ + DISPLAY_APPLE_TV_TUNABLES=1 \ + TARGET_DITHER_TYPE=DITHER_NONE \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + WITH_TARGET_AMC_PARAMS=1 \ + TARGET_USE_HSIC=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_USB_DEVICE_SELF_POWERED=1 \ + TARGET_ADBE0_VBLANK_POSITION=0xF0000 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_CPU_APSC=1 \ + BT_DTPATH=\"arm-io/uart4/bluetooth\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci0/wlan\" \ + PINTO_DTPATH=\"arm-io/usb-complex/usb-ehci0/lan1\" \ + ETHERNET_DTPATH=\"arm-io/usb-complex/usb-ehci1/lan0\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ifeq ($(PRODUCT),iBoot) +OPTIONS += \ + DP_DTPATH=\"arm-io/displayport\" \ + WITH_HW_DISPLAY_DISPLAYPORT=1 +endif + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/j34m/include/target/adbe_settings.h b/target/j34m/include/target/adbe_settings.h new file mode 100644 index 0000000..a4b9be1 --- /dev/null +++ b/target/j34m/include/target/adbe_settings.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v1_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_blk_idle_dpb = 0x0000, + .adbe0_vblank_blk_idle_aap = 0x0000, + + /* + * disable all clock gating until SEG resolves: + * J34: adbe dynamic clock gating causes no video on dp_tx + */ + .adbe0_tunable_mode_ctrl = 0, + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/j34m/include/target/amcconfig.h b/target/j34m/include/target/amcconfig.h new file mode 100644 index 0000000..fa99897 --- /dev/null +++ b/target/j34m/include/target/amcconfig.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static const struct amc_param amc_params = { + .flags = (FLAG_AMC_PARAM_BUSTAT23 | FLAG_AMC_PARAM_SLOW_BOOT | FLAG_AMC_PARAM_ZQCL), + + .tREFi = 0x5d, + .longsrcnt = 0x2008, + .srextrarefcnt = 0x00020000, + .rdlat = 6, + .wrlat = 3, + .phyrdlat = 10, + .phywrlat = 2, + .pdn = 0x22000403, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .derate = 0x2483135b, + .mcphyupdate = 0x05030000, + .autoref_params = 0x00000021, + .pwrmngtparam_small = 0x00011000, + .pwrmngtparam_guided = 0x01801000, + .chnldec = 0x00050000, + .aref_freq0 = 0x00000110, + .schen_default = 0x00000110, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x01, + .pwrmngten_default = 0x00100100, + .mcphyupdate1 = 0x00000001, + .odts = 0x190, + .readleveling = 0x00000300, + .offset_shift_hynix = 0, + .offset_shift_elpida = 1, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + .mifcassch = 0x00000110, + .arefparam = 0x0c022131, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x08020303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + }, + { // 50MHz + .cas = 0x00000003, + .pch = 0x00000003, + .act = 0x08020303, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + .mifcassch = 0x00000000, + .arefparam = 0x00000101, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001728 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQBRST, 0x04100410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOS, 0x00001919 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +}; diff --git a/target/j34m/include/target/aspnandconfig.h b/target/j34m/include/target/aspnandconfig.h new file mode 100644 index 0000000..e6ec918 --- /dev/null +++ b/target/j34m/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/j34m/include/target/gpiodef.h b/target/j34m/include/target/gpiodef.h new file mode 100644 index 0000000..c44fa5a --- /dev/null +++ b/target/j34m/include/target/gpiodef.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* j34m specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO(14, 6) +#define GPIO_BOARD_REV1 GPIO(14, 5) +#define GPIO_BOARD_REV2 GPIO(14, 4) +#define GPIO_BOARD_REV3 GPIO(14, 3) + +/* which IICs to initialize */ +#define IICS_MASK (0xD) + +#define TRISTAR_IIC_BUS (2) + +/* D2089 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(12, 6) + +#define POWER_GPIO_HVR_RESET_L (5) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/j34m/include/target/powerconfig.h b/target/j34m/include/target/powerconfig.h new file mode 100644 index 0000000..62c1823 --- /dev/null +++ b/target/j34m/include/target/powerconfig.h @@ -0,0 +1,83 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2089_ACTIVE2, 0x03 }, // WLEDA/B BST + + { PMU_IIC_BUS, kD2089_BUCK4_VSEL, 0xD0 }, // rdar:// 15918274 PP1V2_S2R + { PMU_IIC_BUS, kD2089_BUCK4_VSEL_ALT, 0xD0 }, // +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* GPIO configuration from I/O spreadsheet. + J34m: IO spreadsheet + Request spreadsheet update before modifying + update GPIO1,15 and remove dup of OTP per J34m: set iBoot PMU GPIOs to IOSpreadsheet + update GPIO1 per J34m: PMU register for GPIO1 not set properly + */ + { PMU_IIC_BUS, kD2089_GPIO1, 0x01 }, // PHY_SEL Out 0, Push-Pull, no PU + { PMU_IIC_BUS, kD2089_GPIO3, 0x09 }, // PMU_GPIO_BT_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO4, 0x09 }, // PMU_GPIO_WLAN_REG_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO7, 0xBA }, // PMU_GPIO_BT2PMU_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO8, 0xBA }, // PMU_GPIO_WLAN2PMU_HOST_WAKE In, R Edge, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO12, 0x7B }, // GPIO_TS2SOC2PMU_INT In, Hi level, Wake, PD + { PMU_IIC_BUS, kD2089_GPIO15, 0x88 }, // MOCA_LINK_L In, Lo level, PU, VBUCK3 + { PMU_IIC_BUS, kD2089_GPIO16, 0x18 }, // PMU_LAN2_RESET_L Out 0, Open-Drain, No PU + { PMU_IIC_BUS, kD2089_GPIO17, 0xA1 }, // VBAT_DETECT In, R Edge, PD, VCC_MAIN + + { PMU_IIC_BUS, kD2089_GPIO_DEB3, 0x20 }, // GPIO5_DEBOUNCE=0, rdar://16735592 Debounce of ENET_DET needs to be disabled + { PMU_IIC_BUS, kD2089_BUCK_DWI_CTRL0, 0x03 }, // enable DWI for BUCK0, BUCK1 + { PMU_IIC_BUS, kD2089_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2089_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_POWER_NO_BATTERY 1 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (3000) +#define PRECHARGE_BACKLIGHT_LEVEL 103 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/j34m/include/target/uartconfig.h b/target/j34m/include/target/uartconfig.h new file mode 100644 index 0000000..e5b1a81 --- /dev/null +++ b/target/j34m/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (3) + +#define MCU_SERIAL_PORT (1) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/j34m/include/target/usbconfig.h b/target/j34m/include/target/usbconfig.h new file mode 100644 index 0000000..30515ac --- /dev/null +++ b/target/j34m/include/target/usbconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_OTGTUNE0 + +#undef USBPHY_OTGTUNE0 +#define USBPHY_OTGTUNE0 (0x37449373) + +#endif /* USBPHY_OTGTUNE0 */ + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/j34m/init.c b/target/j34m/init.c new file mode 100644 index 0000000..77ab4bf --- /dev/null +++ b/target/j34m/init.c @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// DEV Boards +#define J34M_DEV0_BOARD (0x0) //Hoover Only +#define J34M_DEV1_BOARD (0x1) //Hoover Only +#define J34M_DEV2_BOARD (0x2) //Hoover Only +// ...define other DEV Boards here... +#define J34M_DEV_BOARD_LAST (0x7) //Hoover Only + +// AP Boards +#define J34M_AP_BOARD_FIRST (0x8) //Hoover Only +// ...define AP Boards here... +#define J34M_DVT_BOARD (0xC) //Hoover Only +#define J34M_PVT_BOARD (0xF) //Hoover Only + +// Do not delay iBoot by more than this amount from power on (microseconds). +// Give up waiting for a boot logo and carry on at this point. +#define kDPDeviceStartTimeout (8 * 1000 * 1000) +extern utime_t gPowerOnTime; +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; +#if WITH_HW_DISPLAY_DISPLAYPORT +static dp_t dp_link_config = { + .mode = 1, + .type = 0, + .min_link_rate = 0xa, + .max_link_rate = 0xa, + .lanes = 4, + .ssc = 0, + .alpm = 0, + .vrr_enable = 0, + .vrr_on = 0, +}; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static u_int32_t j34m_get_board_rev(void) +{ + + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PUP); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PUP); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + printf("board_rev 0x%x\n", gpio_board_rev); + + return gpio_board_rev; +} + +static void j34m_reset_hoover(bool reset) +{ + power_set_gpio(POWER_GPIO_HVR_RESET_L, 1, !reset); +} + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + if (target_config_dev() && j34m_get_board_rev() > J34M_DEV_BOARD_LAST) { + platform_not_supported(); + } + if (target_config_ap() && j34m_get_board_rev() < J34M_AP_BOARD_FIRST) { + platform_not_supported(); + } + +#if WITH_HW_MCU + // Late display initialization. Needed to wait for MCU. + mcu_init(); +#if WITH_HW_DISPLAY_DISPLAYPORT + // Backgrounded. See dp_device_wait_started() call below. + displayport_init(&dp_link_config); + j34m_reset_hoover(false); +#endif +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +#if WITH_HW_MCU + // radar 9746416 -- UART4 left in interrupt mode will cause kernel panic + mcu_quiesce_uart(); +#endif +} + +void target_poweroff(void) +{ +} + +int target_debug_init(void) +{ +#if WITH_HW_MCU + mcu_start_recover(); +#endif + + return 0; +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DIAGS: +#if WITH_HW_MCU +#if WITH_HW_DISPLAY_DISPLAYPORT && PRODUCT_IBOOT + /* Potentially delay boot so we have a + * logo. We might have to do this if a + * connected TV is particularly slow at + * responding to EDID. Sorry. */ + dp_device_wait_started(gPowerOnTime + kDPDeviceStartTimeout); +#endif + mcu_start_boot(); +#endif + break; + case BOOT_DARWIN_RESTORE: + break; + default: + // do nothing + break; + } + + return 0; +} + +bool target_should_recover(void) +{ + // trigger recovery mode whenever USB is attached, unless + // environment variable says otherwise. + + return power_has_usb() && !env_get_bool("auto-boot-usb", true); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + // always powers on + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + // never power off + return false; +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if WITH_HW_DISPLAY_DISPLAYPORT + return ((void *)(&dp_link_config)); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "720p-j34", 0); + env_set("idle-off", "false", 0); // do not idle off; there is no battery and this will just reboot (8035422) +} + +#endif // WITH_ENV + +bool target_has_tristar2(void) +{ + return false; +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Update the pmu node with the actual vcore values + if (FindNode(0, "arm-io/i2c0/pmu", &node)) { + propName = "swi-vcores"; + if (FindProperty(node, &propName, &propData, &propSize)) { + platform_get_soc_voltages(propSize / sizeof(u_int32_t), propData); + } + } + // + // TriStar 1 on older systems + if (!target_has_tristar2()) { + if (FindNode(0, "arm-io/i2c2/tristar", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "tristar,cbtl1608", kPropNameLength); + } + } + } + + if (FindNode(0, "arm-io/mcu0", &node)) { + propName = "board-rev"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((u_int32_t *)propData)[0] = j34m_get_board_rev(); + } + + // Store pinto mac address into products node + if (FindNode(0, "product", &node)) { + propName = "mac-address-pinto0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("pintoaddr")) { + env_get_ethaddr("pintoaddr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_PINTO_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + // Store pinto mac address into pinto node + if (FindNode(0, "arm-io/spi1/pinto", &node)) { + propName = "local-mac-address"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("pintoaddr")) { + env_get_ethaddr("pintoaddr", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_PINTO_MACADDR, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + // Store RBDA (Remote Bluetooth Device Address) into products node + if (FindNode(0, "product", &node)) { + propName = "bluetooth-dev-addr0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("rbdaddr0")) { + env_get_ethaddr("rbdaddr0", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_BLUETOOTH_DEV_MACADDR0, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + return 0; +} +#endif diff --git a/target/j34m/pinconfig.c b/target/j34m/pinconfig.c new file mode 100644 index 0000000..72b3dca --- /dev/null +++ b/target/j34m/pinconfig.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.40 + I/O Spreadsheet tracker: 16419127 +*/ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : TST_CLKOUT -> + CFG_FUNC0 | FAST_SLEW, // 1 : WDOG -> WDOG_SOC + CFG_IN, // 2 : GPIO0 -> MCU_AP_RECOVERY_MODE_L + CFG_IN, // 3 : GPIO1 -> MCU_PMU_WAKE_L + CFG_DISABLED, // 4 : GPIO2 -> GPIO_BTN_VOL_DOWN_L + CFG_DISABLED, // 5 : GPIO3 -> GPIO_BTN_VOL_UP_L + CFG_DISABLED, // 6 : GPIO4 -> NC_GPIO_MOCA_PLUG_DETECT + CFG_OUT_0 | FAST_SLEW, // 7 : GPIO5 -> GPIO_SOC2BT_WAKE + +/* Port 1 */ + CFG_OUT_0 | FAST_SLEW, // 8 : GPIO6 -> AP_MCU_INT_1V8 + CFG_OUT_0 | PULL_UP, // 9 : GPIO7 -> AP_TO_MCU_TCK_1V8 + CFG_IN, // 10 : GPIO8 -> LAN_PHY_INT_1V8 + CFG_DISABLED, // 11 : GPIO9 -> + CFG_OUT_0 | FAST_SLEW, // 12 : GPIO10 -> LAN_PME_MODE_SEL_AP_1V8 + CFG_DISABLED, // 13 : GPIO11 -> + CFG_IN, // 14 : GPIO12 -> HVR_IRQ + CFG_IN | PULL_DOWN, // 15 : GPIO13 -> LAN_HSIC_DEVICE_READY_1V8 + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO14 -> + CFG_IN, // 17 : GPIO15 -> MOCA_IRQ_1.8V + CFG_IN | PULL_DOWN, // 18 : GPIO16 -> GPIO_BOARD_ID_3 + CFG_IN, // 19 : GPIO17 -> GPIO_TS2SOC2PMU_INT + CFG_IN | PULL_DOWN, // 20 : GPIO18 -> GPIO_BOOT_CONFIG_0 + CFG_OUT_0 | FAST_SLEW, // 21 : GPIO19 -> PMON_SWCLK + CFG_IN, // 22 : GPIO20 -> PMON_MCU_TO_SOC_2V05_1 + CFG_IN | FAST_SLEW, // 23 : GPIO21 -> PMON_SWDIO + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_FUNC0 | FAST_SLEW, // 32 : UART1_TXD -> AP_UART1_TXD_1V8 + CFG_FUNC0, // 33 : UART1_RXD -> AP_UART1_RXD_1V8 + CFG_DISABLED, // 34 : UART1_RTSN -> NC_UART1_RTS_L + CFG_DISABLED, // 35 : UART1_CTSN -> NC_UART1_RTS_L + CFG_FUNC0 | FAST_SLEW, // 36 : UART2_TXD -> UART2_SOC_TO_PMON_R + CFG_FUNC0, // 37 : UART2_RXD -> UART2_PMON_TO_SOC + CFG_DISABLED, // 38 : UART2_RTSN -> NC_GPIO_UART2_RTSN + CFG_DISABLED, // 39 : UART2_CTSN -> NC_GPIO_UART2_CTSN + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 40 : UART3_TXD -> AP_UART3_TXD_1V8 + CFG_FUNC0, // 41 : UART3_RXD -> AP_UART3_RXD_1V8 + CFG_DISABLED, // 42 : UART3_RTSN -> NC_UART3_BB_RTS_L + CFG_DISABLED, // 43 : UART3_CTSN -> NC_UART3_BB_CTS_: + CFG_FUNC0, // 44 : UART5_RTXD -> UART5_WLAN_RXD + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_FUNC0 | FAST_SLEW, // 64 : UART4_TXD -> UART4_BT_TXD + CFG_FUNC0, // 65 : UART4_RXD -> UART4_BT_RXD + CFG_FUNC0 | FAST_SLEW, // 66 : UART4_RTSN -> UART4_BT_RTS_L + CFG_FUNC0, // 67 : UART4_CTSN -> UART4_BT_CTS_L + CFG_FUNC0 | FAST_SLEW, // 68 : SPI1_SCLK -> SPI1_SOC_SCLK_1V8 + CFG_FUNC0 | FAST_SLEW, // 69 : SPI1_MOSI -> SPI1_SOC_MOSI_1V8 + CFG_FUNC0, // 70 : SPI1_MISO -> SPI1_SOC_MISO_1V8 + CFG_FUNC0 | FAST_SLEW, // 71 : SPI1_SSIN -> SPI1_SOC_CS_L_1V8 + +/* Port 9 */ + CFG_IN | PULL_DOWN, // 72 : SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_IN | PULL_DOWN, // 73 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_IN | PULL_DOWN, // 74 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 75 : SPI0_SSIN -> NC_SPI0_SSIN + CFG_DISABLED, // 76 : SPI2_SCLK -> NC_SPI2_SCLK + CFG_DISABLED, // 77 : SPI2_MOSI -> NC_SPI2_MOSI + CFG_DISABLED, // 78 : SPI2_MISO -> NC_SPI2_MISO + CFG_DISABLED, // 79 : SPI2_SSIN -> NC_SPI2_CS_L + +/* Port 10 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 80 : I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 81 : I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 82 : I2C1_SDA -> I2C1_HOOVR_SDA + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 83 : I2C1_SCL -> I2C1_HOOVR_SCL + CFG_DISABLED, // 84 : ISP0_SDA -> TP_ISP0_CAM_REAR_SDA + CFG_DISABLED, // 85 : ISP0_SCL -> TP_ISP0_CAM_REAR_SCL + CFG_DISABLED, // 86 : ISP1_SDA -> TP_ISP1_CAM_FRONT_SDA + CFG_DISABLED, // 87 : ISP1_SCL -> TP_ISP1_CAM_FRONT_SCL + +/* Port 11 */ + CFG_DISABLED, // 88 : SENSOR0_RST -> NC_ISP0_CAM_REAR_CLK + CFG_DISABLED, // 89 : SENSOR0_CLK -> NC_ISP0_CAM_REAR_SHUTDOWN + CFG_DISABLED, // 90 : SENSOR0_XSHUTDOWN -> NC_SENSOR0_XSHUTDOWN + CFG_DISABLED, // 91 : SENSOR0_ISTRB -> NC_SENSOR0_ISTRB + CFG_DISABLED, // 92 : SENSOR1_RST -> NC_ISP1_CAM_FRONT_SHUTDOWN_L + CFG_DISABLED, // 93 : SENSOR1_CLK -> NC_ISP1_CAM_FRONT_CLK + CFG_DISABLED, // 94 : SENSOR1_XSHUTDOWN -> NC_SENSOR1_XSHUTDOWN + CFG_DISABLED, // 95 : SENSOR1_ISTRB -> NC_SENSOR1_ISTRB + +/* Port 12 */ + CFG_DISABLED, // 96 : SPI3_MOSI -> NC_SPI3_MOSI + CFG_DISABLED, // 97 : SPI3_MISO -> NC_SPI3_MISO + CFG_DISABLED, // 98 : SPI3_SCLK -> NC_SPI3_SCLK + CFG_DISABLED, // 99 : SPI3_SSIN -> NC_SPI3_CS_L + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 100 : I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 101 : I2C2_SCL -> I2C2_SCL_1V8 + CFG_OUT_0 | FAST_SLEW, // 102 : GPIO22 -> GPIO_SOC2PMU_KEEPACT + CFG_IN | PULL_UP, // 103 : GPIO23 -> GPIO_PMU2SOC_IRQ_L + +/* Port 13 */ + CFG_DISABLED, // 104 : GPIO24 -> NC_GPIO24 + CFG_IN | PULL_DOWN, // 105 : GPIO25 -> GPIO_BOOT_CONFIG_1 + CFG_IN, // 106 : GPIO26 -> GPIO_FORCE_DFU + CFG_OUT_0 | FAST_SLEW, // 107 : GPIO27 -> MCU_DFU_STATUS_1V8 + CFG_IN | PULL_DOWN, // 108 : GPIO28 -> GPIO_BOOT_CONFIG_2 + CFG_IN | PULL_DOWN, // 109 : GPIO29 -> GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 110 : GPIO30 -> GPIO_BTN_SRL_L + CFG_OUT_0, // 111 : GPIO31 -> SOC_TO_PMON_RESET_1V8_L + +/* Port 14 */ + CFG_DISABLED, // 112 : GPIO32 -> NC + CFG_OUT_0, // 113 : GPIO33 -> PMON_ISP_EN_L + CFG_IN, // 114 : GPIO34 -> SOC_TO_MCU_RESET_1V8_L + CFG_IN | PULL_DOWN, // 115 : GPIO35 -> GPIO_BRD_REV3 + CFG_IN | PULL_DOWN, // 116 : GPIO36 -> GPIO_BRD_REV2 + CFG_IN | PULL_DOWN, // 117 : GPIO37 -> GPIO_BRD_REV1 + CFG_IN | PULL_DOWN, // 118 : GPIO38 -> GPIO_BRD_REV0 + CFG_DISABLED, // 119 : DISP_VSYNC -> NC_DISPLAY_SYNC + +/* Port 15 */ + CFG_FUNC0, // 120 : SOCHOT0 -> SOCHOT0_L + CFG_FUNC0 | FAST_SLEW, // 121 : SOCHOT1 -> SOCHOT1_L + CFG_FUNC0, // 122 : UART0_TXD -> AP_UART0_TXD_1V8 + CFG_FUNC0, // 123 : UART0_RXD -> AP_UART0_RXD_1V8 + CFG_OUT_0, // 124 : DWI_DI -> SOC_TST_CPUSWITCH_OUT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 125 : DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 126 : DWI_CLK -> DWI_AP_CLK + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 128 : I2S0_LRCK -> I2S0_HOOVR_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 129 : I2S0_BCLK -> I2S0_HOOVR_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 130 : I2S0_DOUT -> I2S0_HOOVR_DOUT + CFG_DISABLED, // 131 : I2S0_DIN -> TP_I2S0_DIN + CFG_DISABLED, // 132 : I2S1_MCK -> NC_I2S1_MCK + CFG_DISABLED, // 133 : I2S1_LRCK -> TP_I2S1_LRCK + CFG_DISABLED, // 134 : I2S1_BCLK -> TP_I2S1_BCLK + CFG_DISABLED, // 135 : I2S1_DOUT -> TP_I2S1_DOUT + +/* Port 17 */ + CFG_DISABLED, // 136 : I2S1_DIN -> TP_I2S1_DIN + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 137 : I2S2_LRCK -> TP_I2S2_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 138 : I2S2_BCLK -> TP_I2S2_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 139 : I2S2_DOUT -> TP_I2S2_DOUT + CFG_DISABLED, // 140 : I2S2_DIN -> TP_I2S2_DIN + CFG_DISABLED, // 141 : I2S3_MCK -> TP_I2S3_MCK + CFG_DISABLED, // 142 : I2S3_LRCK -> TP_I2S3_LRCK + CFG_DISABLED, // 143 : I2S3_BCLK -> TP_I2S3_BCLK + +/* Port 18 */ + CFG_FUNC0 | FAST_SLEW, // 144 : I2S3_DOUT -> I2S3_WLAN_TXD + CFG_DISABLED, // 145 : I2S3_DIN -> TP_I2S3_DIN + CFG_DISABLED, // 146 : I2S4_MCK -> NC_I2S4_MCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 147 : I2S4_LRCK -> I2S4_BT_LRCK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 148 : I2S4_BCLK -> I2S4_BT_BCLK + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 149 : I2S4_DOUT -> I2S4_BT_DOUT + CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, // 150 : I2S4_DIN -> I2S4_BT_DIN + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : TMR32_PWM0 -> NC_TMR32_PWM0 + CFG_DISABLED, // 161 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 162 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_OUT_0 | FAST_SLEW, // 163 : SIO_7816UART0_SDA -> HSIC1_SOC2WLAN_HOST_RDY + CFG_IN, // 164 : SIO_7816UART0_SCL -> HSIC1_WLAN2SOC_DEVICE_RDY + CFG_IN, // 165 : SIO_7816UART0_RST -> HSIC1_WLAN2SOC_REMOTE_WAKE + CFG_DISABLED, // 166 : SIO_7816UART1_SDA -> NC_SIO_SDA + CFG_DISABLED, // 167 : SIO_7816UART1_SCL -> NC_SIO_SCL + +/* Port 21 */ + CFG_DISABLED, // 168 : SIO_7816UART1_RST -> NC_SIO_RST + CFG_FUNC0 | FAST_SLEW, // 169 : UART6_TXD -> UART6_TS_ACC_TXD + CFG_FUNC0, // 170 : UART6_RXD -> UART6_TS_ACC_RXD + CFG_DISABLED, // 171 : I2C3_SDA -> NC_I2C3_SDA_1V8 + CFG_DISABLED, // 172 : I2C3_SCL -> NC_I2C3_SCL_1V8 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | FAST_SLEW, // 192 : EDP_HPD -> EDP_HPD + CFG_FUNC0 | FAST_SLEW, // 193 : I2S0_MCK -> I2S0_HOOVR_MCK + CFG_DISABLED, // 194 : I2S2_MCK -> TP_I2S2_MCK + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/j34m/properties.c b/target/j34m/properties.c new file mode 100644 index 0000000..4543828 --- /dev/null +++ b/target/j34m/properties.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/j34m/rules.mk b/target/j34m/rules.mk new file mode 100644 index 0000000..5d5beec --- /dev/null +++ b/target/j34m/rules.mk @@ -0,0 +1,56 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2089=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_SPARE0_CLK_CFG=0x81000001 \ + TARGET_VID0_CLK_CFG=0x81000000 \ + WITH_HW_HOOVER=1 \ + DISPLAY_APPLE_TV_TUNABLES=1 \ + TARGET_DITHER_TYPE=DITHER_NONE \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMP_SWIZZLE=2 \ + WITH_TARGET_AMC_PARAMS=1 \ + TARGET_USE_HSIC=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + TARGET_USB_DEVICE_SELF_POWERED=1 \ + TARGET_ADBE0_VBLANK_POSITION=0xF0000 \ + BUCK_CPU=0 \ + BUCK_GPU=1 \ + WITH_CPU_APSC=1 \ + BT_DTPATH=\"arm-io/uart4/bluetooth\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci0/wlan\" \ + PINTO_DTPATH=\"arm-io/usb-complex/usb-ehci0/lan1\" \ + ETHERNET_DTPATH=\"arm-io/usb-complex/usb-ehci1/lan0\" \ + WITH_TARGET_USB_CONFIG=1 \ + TARGET_DDR_784M=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ifeq ($(PRODUCT),iBoot) +OPTIONS += \ + DP_DTPATH=\"arm-io/displayport\" \ + WITH_HW_DISPLAY_DISPLAYPORT=1 +endif + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/j42/include/target/adbe_settings.h b/target/j42/include/target/adbe_settings.h new file mode 100644 index 0000000..933db49 --- /dev/null +++ b/target/j42/include/target/adbe_settings.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0001, + .adbe0_vblank_clk_gate_wakeup = 0x000e, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/j42/include/target/amcconfig.h b/target/j42/include/target/amcconfig.h new file mode 100644 index 0000000..8f52b8b --- /dev/null +++ b/target/j42/include/target/amcconfig.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Memory settings for j42d only (2 GB) */ +static const struct amc_param amc_params = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x03, + .addrcfg = 0x00030201, + .mccchnldec = 0x00060010, + .mcuchnhash = 0x0ffffd54, + .mcschnldec = 0x00010200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000601, + .readleveling = 0x00000300, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x25550000, + .selfref = 0x00059060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x132b0000, + .selfref = 0x0002d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x0a160000, + .selfref = 0x00017000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x03050000, + .selfref = 0x00006000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, +#if DISPLAY_D600_TUNABLES + { &rAMC_PSQWQCTL1, 0x00000bd4 }, +#else + { &rAMC_PSQWQCTL1, 0x00000158 }, +#endif + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, +#if DISPLAY_D600_TUNABLES + { &rAMC_PWRMNGTPARAM, 0x0c003000 }, +#else + { &rAMC_PWRMNGTPARAM, 0x01803000 }, +#endif +}; diff --git a/target/j42/include/target/aspnandconfig.h b/target/j42/include/target/aspnandconfig.h new file mode 100644 index 0000000..21b0897 --- /dev/null +++ b/target/j42/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/j42/include/target/gpiodef.h b/target/j42/include/target/gpiodef.h new file mode 100644 index 0000000..c9f5547 --- /dev/null +++ b/target/j42/include/target/gpiodef.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* j42 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 9, 2) // 74 : GPIO[37] -> GPIO_BRD_REV0 +#define GPIO_BOARD_REV1 GPIO( 9, 1) // 73 : GPIO[36] -> GPIO_BRD_REV1 +#define GPIO_BOARD_REV2 GPIO( 9, 0) // 72 : GPIO[35] -> GPIO_BRD_REV2 +#define GPIO_BOARD_REV3 GPIO( 8, 7) // 71 : GPIO[34] -> GPIO_BRD_REV3 + +/* D2186 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO( 8, 2) // 66 : GPIO[22] -> GPIO_SOC2PMU_KEEPACT + +/* which IICs to initialize */ +#define IICS_MASK (0xD) // i2c0, i2c2, i2c3 + +#define TRISTAR_IIC_BUS (2) + +#define POWER_GPIO_HVR_RESET_L (5) + +#define POWER_GPIO_VBUS_PROT_2V5 (19) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/j42/include/target/powerconfig.h b/target/j42/include/target/powerconfig.h new file mode 100644 index 0000000..e840845 --- /dev/null +++ b/target/j42/include/target/powerconfig.h @@ -0,0 +1,87 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2186_ACTIVE1, 0x3f }, // J42: Enable GPU in iBoot + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x11 }, // J42: DEV1 PMU OTP Change - Disable BUCK4_SW2 in HIB and ACT + { PMU_IIC_BUS, kD2186_HIBERNATE6, 0x00 }, // J42: DEV1 PMU OTP Change - Disable BUCK4_SW2 in HIB and ACT +}; + + +#define PMU_LDO_COLD_SETUP_AP_DEV 1 + +static const struct pmu_setup_struct pmu_ldo_cold_setup_dev[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup_ap[] = +{ + // J42: PMU PreProto OTP Override [URGENT!] + { PMU_IIC_BUS, kD2186_ACTIVE4, 0x0f }, // (LDO9 enabled in Active) + { PMU_IIC_BUS, kD2186_HIBERNATE3, 0x44 }, // (LDO5 disabled in Hibernate) + { PMU_IIC_BUS, kD2186_HIBERNATE4, 0x03 }, // (LDO9 enabled in Hibernate) + { PMU_IIC_BUS, kD2186_LDO9_VSEL, 0x54 }, // (LDO9 set to 3.3V) + { PMU_IIC_BUS, kD2186_BUCK5_SLOT, 0x33 }, // (BUCK5 slot 3) + { PMU_IIC_BUS, kD2186_LDO9_SLOT, 0x33 }, // (LDO9 slot 3) + { PMU_IIC_BUS, kD2186_LDO10_SLOT, 0x44 }, // (LDO10 slot 4) +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + + { PMU_IIC_BUS, kD2186_GPIO3_CONF1, 0x00 }, // J42 IOKit / wlan / Match Timeout [iBoot BT_REG_ON] + { PMU_IIC_BUS, kD2186_GPIO4_CONF1, 0x00 }, // J42: DEV1 OTP Change - WLAN_REG_ON should be low + { PMU_IIC_BUS, kD2186_GPIO6_CONF1, 0x00 }, // J42: DEV1 PMU OTP Change - Assert HVR_RESET_L + { PMU_IIC_BUS, kD2186_GPIO7_CONF1, 0x92 }, // GPIO_BT2PMU_HOST_WAKE In, R Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO7_CONF2, 0x72 }, // GPIO_BT2PMU_HOST_WAKE PU Disabled + { PMU_IIC_BUS, kD2186_GPIO12_CONF1, 0x81 }, // j42: disable wake on tristar pmu gpio 12 + { PMU_IIC_BUS, kD2186_GPIO17_CONF1, 0x93 }, // J42: DEV1 PMU OTP Change - GPIO17 Wake on Rising Edge + { PMU_IIC_BUS, kD2186_GPIO20_CONF1, 0xa1 }, // J42: PMU kD2186_GPIO20_CONF1 needs to be updated to 0xa1 + { PMU_IIC_BUS, kD2186_BUCK_DWI_CTRL0, 0x07 }, // enable DWI for BUCK0, BUCK1, BUCK2 + { PMU_IIC_BUS, kD2186_SYS_CTRL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + +// TODO: verify + { PMU_IIC_BUS, kD2186_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_POWER_NO_BATTERY 1 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (3000) +#define PRECHARGE_BACKLIGHT_LEVEL 103 +#define TARGET_MAX_USB_INPUT_CURRENT 2400 + +#define ACC_PWR_LDO (0) // J42: PMU LDO config wrong in iBoot + +#endif diff --git a/target/j42/include/target/uartconfig.h b/target/j42/include/target/uartconfig.h new file mode 100644 index 0000000..9cf4425 --- /dev/null +++ b/target/j42/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (6) + +#define MCU_SERIAL_PORT (3) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/j42/init.c b/target/j42/init.c new file mode 100644 index 0000000..1f857c3 --- /dev/null +++ b/target/j42/init.c @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#if (APPLICATION_IBOOT && PRODUCT_IBOOT) +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Board ids +#define J42_AP_BOARD_ID (0x14) +#define J42_DEV_BOARD_ID (0x15) +#define J42M_AP_BOARD_ID (0x16) +#define J42M_DEV_BOARD_ID (0x17) +#define J42D_AP_BOARD_ID (0x34) +#define J42D_DEV_BOARD_ID (0x35) + +// Board revs +#define J42_DEV1_BOARD_REV (0x7) +#define J42_PROTO1_BOARD_REV (0x6) +#define J42_EVT1_BOARD_REV (0x4) + +// Do not delay iBoot by more than this amount from power on (microseconds). +// Give up waiting for a boot logo and carry on at this point. +#define kDPDeviceStartTimeout (10 * 1000 * 1000) +extern utime_t gPowerOnTime; +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; +#if WITH_HW_DISPLAY_DISPLAYPORT +static dp_t dp_link_config = { + .mode = 1, + .type = 0, + .min_link_rate = 0xa, + .max_link_rate = 0xa, + .lanes = 4, + .ssc = 0, + .alpm = 0, + .vrr_enable = 0, + .vrr_on = 0, + .fast_link_training = true, +}; +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static uint32_t j42_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + + printf("board_rev 0x%x\n", gpio_board_rev); + + } + + return gpio_board_rev; +} + +static void j42_reset_hoover(bool reset) +{ + power_set_gpio(POWER_GPIO_HVR_RESET_L, 1, !reset); +} + +void target_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + dprintf(DEBUG_INFO, "%s: chip rev: %d, fuse: %d\n", __func__, + chipid_get_chip_revision(), chipid_get_fuse_revision()); + + // target_fixup_pmu(); +#endif +} + +void target_late_init(void) +{ +#if 0 + if (target_config_dev() && j42_get_board_rev() > J42_DEV_BOARD_LAST) { + platform_not_supported(); + } + if (target_config_ap() && j42_get_board_rev() < J42_AP_BOARD_FIRST) { + platform_not_supported(); + } +#endif + +#if WITH_HW_MCU + // Late display initialization. Needed to wait for MCU. + mcu_init(); +#if WITH_HW_DISPLAY_DISPLAYPORT + // Backgrounded. See dp_device_wait_started() call below. + displayport_init(&dp_link_config); + j42_reset_hoover(false); +#endif +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +#if WITH_HW_MCU + // radar 9746416 -- UART4 left in interrupt mode will cause kernel panic + mcu_quiesce_uart(); +#endif +} + +void target_poweroff(void) +{ +} + +int target_debug_init(void) +{ +#if WITH_HW_MCU + mcu_start_recover(); +#endif + + return 0; +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DIAGS: +#if WITH_HW_MCU +#if WITH_HW_DISPLAY_DISPLAYPORT && PRODUCT_IBOOT + /* Potentially delay boot so we have a + * logo. We might have to do this if a + * connected TV is particularly slow at + * responding to EDID. Sorry. */ + dp_device_wait_started(gPowerOnTime + kDPDeviceStartTimeout); +#endif + mcu_start_boot(); +#endif + break; + case BOOT_DARWIN_RESTORE: + break; + default: + // do nothing + break; + } + + return 0; +} + +bool target_should_recover(void) +{ + // trigger recovery mode whenever USB is attached, unless + // environment variable says otherwise. + + // J42: USB VBUS detection should be changed from PMU to PMU GPIO + return power_get_gpio(POWER_GPIO_VBUS_PROT_2V5) && !env_get_bool("auto-boot-usb", true); +} + +bool target_should_poweron(bool *cold_button_boot) +{ + // always powers on + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + // never power off + return false; +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if WITH_HW_DISPLAY_DISPLAYPORT + return ((void *)(&dp_link_config)); +#else + return (NULL); +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "720p", 0); // XXX DBJ do we need updated timing table in platform/t7000/include/platform/soc/display_timings.h for j42? + env_set("idle-off", "false", 0); // do not idle off; there is no battery and this will just reboot (8035422) + env_set("adbe-tunables", "default", 0); + env_set("adfe-tunables", "default", 0); +} + +#endif // WITH_ENV + +bool target_has_tristar2(void) +{ + return false; +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Update the pmu node with the actual vcore values + if (FindNode(0, "arm-io/i2c0/pmu", &node)) { + propName = "swi-vcores"; + if (FindProperty(node, &propName, &propData, &propSize)) { + platform_get_soc_voltages(propSize / sizeof(u_int32_t), propData); + } + } + + if (FindNode(0, "arm-io/mcu0", &node)) { + propName = "board-rev"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((u_int32_t *)propData)[0] = j42_get_board_rev(); + } + + // Store RBDA (Remote Bluetooth Device Address) into products node + if (FindNode(0, "product", &node)) { + propName = "bluetooth-dev-addr0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (env_get("rbdaddr0")) { + env_get_ethaddr("rbdaddr0", propData); + } else { + int retlen = 0; + if (!target_get_property(TARGET_PROPERTY_BLUETOOTH_DEV_MACADDR0, propData, 6, &retlen)) { + propName[0] = '~'; + } + } + } + } + + return 0; +} + +#endif // WITH_DEVICETREE + diff --git a/target/j42/pinconfig.c b/target/j42/pinconfig.c new file mode 100644 index 0000000..6339301 --- /dev/null +++ b/target/j42/pinconfig.c @@ -0,0 +1,692 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 2v7 + I/O Spreadsheet tracker: J42d: GPIO 178 Configuration Change + Conversion command: ./tools/csvtopinconfig.py --soc fiji --radar ' J42d: GPIO 178 Configuration Change' --copyright 2014-2015 +*/ + +#include +#include +#include +#include +#include + +enum { + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED_DRIVE_X4_FAST_SLEW, + GPIOCFG_CFG_DISABLED_FAST_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_SLOW_SLEW, + GPIOCFG_CFG_FUNC0, + GPIOCFG_CFG_FUNC0_DRIVE_X2_FAST_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_X2_FAST_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_X4, + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_FAST_SLEW, + GPIOCFG_CFG_FUNC0_FAST_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_FAST_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_FAST_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_FAST_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_FAST_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW, + GPIOCFG_CFG_IN_SLOW_SLEW, + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_SLOW_SLEW, +}; + + +static const uint32_t enum_map[] = { + [GPIOCFG_CFG_DISABLED] = CFG_DISABLED, + [GPIOCFG_CFG_DISABLED_DRIVE_X4_FAST_SLEW] = CFG_DISABLED | DRIVE_X4 | FAST_SLEW, + [GPIOCFG_CFG_DISABLED_FAST_SLEW] = CFG_DISABLED | FAST_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_UP | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW] = CFG_DISABLED | PULL_UP | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_SLOW_SLEW] = CFG_DISABLED | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0] = CFG_FUNC0, + [GPIOCFG_CFG_FUNC0_DRIVE_X2_FAST_SLEW] = CFG_FUNC0 | DRIVE_X2 | FAST_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_X2_FAST_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_X2 | FAST_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_X4] = CFG_FUNC0 | DRIVE_X4, + [GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW] = CFG_FUNC0 | DRIVE_X4 | FAST_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_X4 | FAST_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW] = CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_FAST_SLEW] = CFG_FUNC0 | FAST_SLEW, + [GPIOCFG_CFG_FUNC0_FAST_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | FAST_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_FAST_SLEW] = CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | FAST_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_FAST_SLEW] = CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | FAST_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW] = CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW] = CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_FAST_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_X4 | FAST_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_FAST_SLEW] = CFG_FUNC0 | PULL_UP | FAST_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_SLOW_SLEW] = CFG_FUNC0 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW] = CFG_IN | PULL_DOWN | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_X4_SLOW_SLEW] = CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW] = CFG_IN | PULL_UP | SLOW_SLEW, + [GPIOCFG_CFG_IN_SLOW_SLEW] = CFG_IN | SLOW_SLEW, + [GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW] = CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_SLOW_SLEW] = CFG_OUT_0 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW] = CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_SLOW_SLEW] = CFG_OUT_1 | SLOW_SLEW, +}; + + +static const uint8_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 0 : ULPI_DIR -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 1 : ULPI_STP -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 2 : ULPI_NXT -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 3 : ULPI_DATA[7] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 7 : ULPI_CLK -> NC + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 8 : ULPI_DATA[3] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 10 : ULPI_DATA[1] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 11 : ULPI_DATA[0] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 12 : SPI1_SCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 13 : SPI1_MOSI -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 14 : SPI1_MISO -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 15 : SPI1_SSIN -> NC + +/* Port 2 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 3 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 4 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 32 : GPIO[11] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 33 : GPIO[12] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 34 : I2S3_MCK -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 35 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 36 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 37 : I2S3_DOUT -> I2S3_SOC2BT_DOUT + GPIOCFG_CFG_FUNC0, // 38 : I2S3_DIN -> I2S3_BT2SOC_DIN + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 39 : CLK32K_OUT -> NC + +/* Port 5 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC_PCIE0_DEBUG2SOC_CLKREQ_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> PCIE1_WLAN2SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 43 : GPIO[0] -> NC + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 44 : GPIO[1] -> MCU_PMU_WAKE_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 45 : GPIO[2] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 46 : GPIO[3] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 47 : GPIO[4] -> NC + +/* Port 6 */ + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 48 : GPIO[5] -> GPIO_SOC2BT_WAKE + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 49 : GPIO[6] -> AP_MCU_INT_1V8 + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_MCU_TCK_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 51 : GPIO[14] -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 52 : GPIO[16] -> GPIO_BOARD_ID_3 + GPIOCFG_CFG_IN_SLOW_SLEW, // 53 : GPIO[17] -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 54 : GPIO[18] -> GPIO_BOOT_CONFIG_0 + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 55 : GPIO[20] -> PMON_TO_SOC_INT_1V8_L + +/* Port 7 */ + GPIOCFG_CFG_DISABLED_FAST_SLEW, // 56 : GPIO[21] -> NC + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 57 : UART5_RTXD -> AP_UART5_SIL_TUNING_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 58 : UART8_TXD -> NC_AP_UART8_TXD_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 59 : UART8_RXD -> NC_AP_UART8_RXD_1V8 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 60 : SPI0_SCLK -> GPIO_BOARD_ID_0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 61 : SPI0_MOSI -> GPIO_BOARD_ID_1 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 62 : SPI0_MISO -> GPIO_BOARD_ID_2 + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 63 : SPI0_SSIN -> GPIO_SOC2WLAN_WAKE + +/* Port 8 */ + GPIOCFG_CFG_FUNC0_DRIVE_X2_FAST_SLEW_INPUT_SCHMITT, // 64 : I2C2_SDA -> I2C2_DEBUG_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X2_FAST_SLEW_INPUT_SCHMITT, // 65 : I2C2_SCL -> I2C2_DEBUG_SCL + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 66 : GPIO[22] -> GPIO_SOC2PMU_KEEPACT + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 67 : GPIO[23] -> GPIO_PMU2SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 68 : GPIO[25] -> GPIO_BOOT_CONFIG_1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 69 : GPIO[28] -> GPIO_BOOT_CONFIG_2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 70 : GPIO[29] -> GPIO_BOARD_ID_4 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 71 : GPIO[34] -> GPIO_BRD_REV3 + +/* Port 9 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 72 : GPIO[35] -> GPIO_BRD_REV2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 73 : GPIO[36] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 74 : GPIO[37] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 75 : GPIO[39] -> NC_AP_TO_PCIE0_RST_1V8_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 76 : GPIO[42] -> NC + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 77 : GPIO[43] -> PCIE1_SOC2WLAN_RESET_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 78 : DISP_VSYNC -> NC + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 79 : UART0_TXD -> AP_UART0_MCU_BSL_TXD_1V8 + +/* Port 10 */ + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 80 : UART0_RXD -> AP_UART0_MCU_BSL_RXD_1V8_R + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 81 : TMR32_PWM0 -> WLAN_TO_AP_TMR32_PWM0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 82 : TMR32_PWM1 -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 84 : UART6_TXD -> AP_UART6_DEBUG_TXD_1V8 + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 85 : UART6_RXD -> AP_UART6_DEBUG_RXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 86 : I2C3_SDA -> I2C3_HOOVR_SDA + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 87 : I2C3_SCL -> I2C3_HOOVR_SCL + +/* Port 11 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 12 */ + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 96 : I2C0_SDA -> I2C0_PMU_SDA + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 97 : I2C0_SCL -> I2C0_PMU_SCL + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 98 : GPIO[38] -> AP_MCU_REQUEST_DFU_1V8 + GPIOCFG_CFG_FUNC0_FAST_SLEW, // 99 : UART2_TXD -> AP_UART2_WLAN_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 100 : UART2_RXD -> AP_UART2_WLAN_RXD_1V8 + GPIOCFG_CFG_OUT_1_SLOW_SLEW, // 101 : UART2_RTSN -> AP_UART2_WLAN_RTS_1V8_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 102 : UART2_CTSN -> AP_UART2_WLAN_CTS_1V8_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_FAST_SLEW, // 103 : DWI_DO -> DWI_AP_DO + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_FAST_SLEW, // 104 : DWI_CLK -> DWI_AP_CLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 105 : WDOG -> WDOG_SOC2PMU_RESET_IN + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 106 : GPIO[13] -> HVR_IRQ + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 107 : GPIO[19] -> PMON_SWCLK + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 108 : GPIO[26] -> MCU2SOC_FORCE_DFU_1V8 + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 109 : GPIO[27] -> MCU_DFU_STATUS_1V8 + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 110 : SOCHOT0 -> SOCHOT0_L + GPIOCFG_CFG_FUNC0_FAST_SLEW_INPUT_SCHMITT, // 111 : SOCHOT1 -> SOCHOT1_L + +/* Port 14 */ + GPIOCFG_CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 114 : GPIO[8] -> LAN_PHY_INT_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 115 : GPIO[9] -> GPIO9_TEST_POINT + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 116 : GPIO[10] -> SOC2LAN_PME_MODE_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 117 : GPIO[15] -> PMON_SWDIO + GPIOCFG_CFG_FUNC0_PULL_UP_FAST_SLEW, // 118 : UART4_TXD -> AP_UART4_PMON_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 119 : UART4_RXD -> AP_UART4_PMON_RXD_1V8 + +/* Port 15 */ + GPIOCFG_CFG_DISABLED_FAST_SLEW, // 120 : UART4_RTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 121 : UART4_CTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 122 : SPI3_MOSI -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 123 : SPI3_MISO -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 124 : SPI3_SCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 125 : SPI3_SSIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 126 : GPIO[24] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 127 : GPIO[30] -> NC + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 128 : GPIO[31] -> PMON_RST_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 129 : GPIO[32] -> PMON_ISP_EN_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 130 : GPIO[33] -> SOC_TO_MCU_RESET_1V8_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 131 : GPIO[40] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 132 : GPIO[41] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 133 : I2S4_MCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 134 : I2S4_LRCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 135 : I2S4_BCLK -> NC + +/* Port 17 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 136 : I2S4_DOUT -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 137 : I2S4_DIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 138 : I2C1_SDA -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 139 : I2C1_SCL -> NC + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 160 : I2S0_LRCK -> I2S0_HOOVR_LRCK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 161 : I2S0_BCLK -> I2S0_HOOVR_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 162 : I2S0_DOUT -> I2S0_HOOVR_DOUT + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 163 : I2S0_DIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 164 : I2S1_MCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 165 : I2S1_LRCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 166 : I2S1_BCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 167 : I2S1_DOUT -> NC + +/* Port 21 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 168 : I2S1_DIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 169 : I2S2_LRCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 170 : I2S2_BCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 171 : I2S2_DOUT -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 172 : I2S2_DIN -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 173 : UART1_TXD -> AP_UART1_BT_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 174 : UART1_RXD -> AP_UART1_BT_RXD_1V8 + GPIOCFG_CFG_OUT_1_SLOW_SLEW, // 175 : UART1_RTSN -> AP_UART1_BT_RTS_1V8_L + +/* Port 22 */ + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 176 : UART1_CTSN -> AP_UART1_BT_CTS_1V8_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 177 : EDP_HPD -> EPD_HPD_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_X2_FAST_SLEW, // 178 : UART3_TXD -> AP_UART3_MCU_COMMS_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 179 : UART3_RXD -> AP_UART3_MCU_COMMS_RXD_1V8_R + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 180 : UART3_RTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 181 : UART3_CTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 182 : SPI2_SCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 183 : SPI2_MOSI -> NC + +/* Port 23 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 184 : SPI2_MISO -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 185 : SPI2_SSIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 186 : ISP0_SDA -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 187 : ISP0_SCL -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 188 : ISP1_SDA -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 189 : ISP1_SCL -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 190 : SENSOR0_RST -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 191 : SENSOR0_CLK -> NC + +/* Port 24 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 194 : ISP_UART0_TXD -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 195 : ISP_UART0_RXD -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 196 : SENSOR1_RST -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 197 : SENSOR1_CLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 200 : UART7_TXD -> NC_AP_UART7_ASTRIS_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 201 : UART7_RXD -> NC_AP_UART7_ASTRIS_RXD_1V8 + GPIOCFG_CFG_FUNC0_FAST_SLEW, // 202 : I2S0_MCK -> I2S0_HOOVR_MCK + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 203 : I2S2_MCK -> NC + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 0 : ULPI_DIR -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 1 : ULPI_STP -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 2 : ULPI_NXT -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 3 : ULPI_DATA[7] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 7 : ULPI_CLK -> NC + +/* Port 1 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 8 : ULPI_DATA[3] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 10 : ULPI_DATA[1] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 11 : ULPI_DATA[0] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 12 : SPI1_SCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 13 : SPI1_MOSI -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 14 : SPI1_MISO -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 15 : SPI1_SSIN -> NC + +/* Port 2 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 3 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 4 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 32 : GPIO[11] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 33 : GPIO[12] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 34 : I2S3_MCK -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 35 : I2S3_LRCK -> I2S3_SOC2BT_LRCK + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 36 : I2S3_BCLK -> I2S3_SOC2BT_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 37 : I2S3_DOUT -> I2S3_SOC2BT_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_X4, // 38 : I2S3_DIN -> I2S3_BT2SOC_DIN + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 39 : CLK32K_OUT -> NC + +/* Port 5 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC_PCIE0_DEBUG2SOC_CLKREQ_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> PCIE1_WLAN2SOC_CLKREQ_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 43 : GPIO[0] -> NC + GPIOCFG_CFG_IN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 44 : GPIO[1] -> MCU_PMU_WAKE_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 45 : GPIO[2] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 46 : GPIO[3] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 47 : GPIO[4] -> NC + +/* Port 6 */ + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 48 : GPIO[5] -> GPIO_SOC2BT_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 49 : GPIO[6] -> AP_MCU_INT_1V8 + GPIOCFG_CFG_IN_PULL_UP_DRIVE_X4_SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_MCU_TCK_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 51 : GPIO[14] -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 52 : GPIO[16] -> GPIO_BOARD_ID_3 + GPIOCFG_CFG_IN_SLOW_SLEW, // 53 : GPIO[17] -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 54 : GPIO[18] -> GPIO_BOOT_CONFIG_0 + GPIOCFG_CFG_IN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 55 : GPIO[20] -> PMON_TO_SOC_INT_1V8_L + +/* Port 7 */ + GPIOCFG_CFG_DISABLED_DRIVE_X4_FAST_SLEW, // 56 : GPIO[21] -> NC + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 57 : UART5_RTXD -> AP_UART5_SIL_TUNING_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 58 : UART8_TXD -> NC_AP_UART8_TXD_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 59 : UART8_RXD -> NC_AP_UART8_RXD_1V8 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 60 : SPI0_SCLK -> GPIO_BOARD_ID_0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 61 : SPI0_MOSI -> GPIO_BOARD_ID_1 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 62 : SPI0_MISO -> GPIO_BOARD_ID_2 + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 63 : SPI0_SSIN -> GPIO_SOC2WLAN_WAKE + +/* Port 8 */ + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW_INPUT_SCHMITT, // 64 : I2C2_SDA -> I2C2_DEBUG_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW_INPUT_SCHMITT, // 65 : I2C2_SCL -> I2C2_DEBUG_SCL + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 66 : GPIO[22] -> GPIO_SOC2PMU_KEEPACT + GPIOCFG_CFG_IN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 67 : GPIO[23] -> GPIO_PMU2SOC_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 68 : GPIO[25] -> GPIO_BOOT_CONFIG_1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 69 : GPIO[28] -> GPIO_BOOT_CONFIG_2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 70 : GPIO[29] -> GPIO_BOARD_ID_4 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 71 : GPIO[34] -> GPIO_BRD_REV3 + +/* Port 9 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 72 : GPIO[35] -> GPIO_BRD_REV2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 73 : GPIO[36] -> GPIO_BRD_REV1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 74 : GPIO[37] -> GPIO_BRD_REV0 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 75 : GPIO[39] -> NC_AP_TO_PCIE0_RST_1V8_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 76 : GPIO[42] -> NC + GPIOCFG_CFG_IN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 77 : GPIO[43] -> PCIE1_SOC2WLAN_RESET_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 78 : DISP_VSYNC -> NC + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, // 79 : UART0_TXD -> AP_UART0_MCU_BSL_TXD_1V8 + +/* Port 10 */ + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 80 : UART0_RXD -> AP_UART0_MCU_BSL_RXD_1V8_R + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 81 : TMR32_PWM0 -> WLAN_TO_AP_TMR32_PWM0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 82 : TMR32_PWM1 -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, // 84 : UART6_TXD -> AP_UART6_DEBUG_TXD_1V8 + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 85 : UART6_RXD -> AP_UART6_DEBUG_RXD_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 86 : I2C3_SDA -> I2C3_HOOVR_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 87 : I2C3_SCL -> I2C3_HOOVR_SCL + +/* Port 11 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 12 */ + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 96 : I2C0_SDA -> I2C0_PMU_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 97 : I2C0_SCL -> I2C0_PMU_SCL + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 98 : GPIO[38] -> AP_MCU_REQUEST_DFU_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW, // 99 : UART2_TXD -> AP_UART2_WLAN_TXD_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 100 : UART2_RXD -> AP_UART2_WLAN_RXD_1V8 + GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW, // 101 : UART2_RTSN -> AP_UART2_WLAN_RTS_1V8_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 102 : UART2_CTSN -> AP_UART2_WLAN_CTS_1V8_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_FAST_SLEW, // 103 : DWI_DO -> DWI_AP_DO + +/* Port 13 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_FAST_SLEW, // 104 : DWI_CLK -> DWI_AP_CLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 105 : WDOG -> WDOG_SOC2PMU_RESET_IN + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 106 : GPIO[13] -> HVR_IRQ + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 107 : GPIO[19] -> PMON_SWCLK + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 108 : GPIO[26] -> MCU2SOC_FORCE_DFU_1V8 + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 109 : GPIO[27] -> MCU_DFU_STATUS_1V8 + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 110 : SOCHOT0 -> SOCHOT0_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW_INPUT_SCHMITT, // 111 : SOCHOT1 -> SOCHOT1_L + +/* Port 14 */ + GPIOCFG_CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 114 : GPIO[8] -> LAN_PHY_INT_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 115 : GPIO[9] -> GPIO9_TEST_POINT + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 116 : GPIO[10] -> SOC2LAN_PME_MODE_1V8 + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 117 : GPIO[15] -> PMON_SWDIO + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_FAST_SLEW, // 118 : UART4_TXD -> AP_UART4_PMON_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 119 : UART4_RXD -> AP_UART4_PMON_RXD_1V8 + +/* Port 15 */ + GPIOCFG_CFG_DISABLED_FAST_SLEW, // 120 : UART4_RTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 121 : UART4_CTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 122 : SPI3_MOSI -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 123 : SPI3_MISO -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 124 : SPI3_SCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 125 : SPI3_SSIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 126 : GPIO[24] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 127 : GPIO[30] -> NC + +/* Port 16 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 128 : GPIO[31] -> PMON_RST_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 129 : GPIO[32] -> PMON_ISP_EN_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 130 : GPIO[33] -> SOC_TO_MCU_RESET_1V8_L + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 131 : GPIO[40] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 132 : GPIO[41] -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 133 : I2S4_MCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 134 : I2S4_LRCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 135 : I2S4_BCLK -> NC + +/* Port 17 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 136 : I2S4_DOUT -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 137 : I2S4_DIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 138 : I2C1_SDA -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 139 : I2C1_SCL -> NC + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 18 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 160 : I2S0_LRCK -> I2S0_HOOVR_LRCK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 161 : I2S0_BCLK -> I2S0_HOOVR_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 162 : I2S0_DOUT -> I2S0_HOOVR_DOUT + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 163 : I2S0_DIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 164 : I2S1_MCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 165 : I2S1_LRCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 166 : I2S1_BCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 167 : I2S1_DOUT -> NC + +/* Port 21 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 168 : I2S1_DIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 169 : I2S2_LRCK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 170 : I2S2_BCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 171 : I2S2_DOUT -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 172 : I2S2_DIN -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 173 : UART1_TXD -> AP_UART1_BT_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 174 : UART1_RXD -> AP_UART1_BT_RXD_1V8 + GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW, // 175 : UART1_RTSN -> AP_UART1_BT_RTS_1V8_L + +/* Port 22 */ + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 176 : UART1_CTSN -> AP_UART1_BT_CTS_1V8_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 177 : EDP_HPD -> EPD_HPD_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW, // 178 : UART3_TXD -> AP_UART3_MCU_COMMS_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 179 : UART3_RXD -> AP_UART3_MCU_COMMS_RXD_1V8_R + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 180 : UART3_RTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 181 : UART3_CTSN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 182 : SPI2_SCLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 183 : SPI2_MOSI -> NC + +/* Port 23 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 184 : SPI2_MISO -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 185 : SPI2_SSIN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 186 : ISP0_SDA -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 187 : ISP0_SCL -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 188 : ISP1_SDA -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 189 : ISP1_SCL -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 190 : SENSOR0_RST -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 191 : SENSOR0_CLK -> NC + +/* Port 24 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 194 : ISP_UART0_TXD -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 195 : ISP_UART0_RXD -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 196 : SENSOR1_RST -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 197 : SENSOR1_CLK -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> NC + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 200 : UART7_TXD -> NC_AP_UART7_ASTRIS_TXD_1V8 + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 201 : UART7_RXD -> NC_AP_UART7_ASTRIS_RXD_1V8 + GPIOCFG_CFG_FUNC0_DRIVE_X4_FAST_SLEW, // 202 : I2S0_MCK -> I2S0_HOOVR_MCK + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 203 : I2S2_MCK -> NC + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint8_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0 } }, + { 1, 1, { pinconfig_dev_0 } }, +}; + +static uint32_t *expanded_pinconfigs[GPIOC_COUNT]; + +static const uint32_t controller_pins[GPIOC_COUNT] = { + GPIO_GROUP_COUNT * GPIOPADPINS, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + /* Cannot use malloc as chunk manager is yet to be intialized */ + static uint32_t pinconfig_buf[GPIO_GROUP_COUNT * GPIOPADPINS]; + expanded_pinconfigs[0] = pinconfig_buf; + + ASSERT(gpioc < GPIOC_COUNT); + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + + for (unsigned i = 0; i < GPIOC_COUNT; i++) { + uint32_t num_pins = controller_pins[i]; + + for (uint32_t j = 0; j < num_pins; j++) { + uint8_t enum_key = selected_map->pinconfigs[i][j]; + expanded_pinconfigs[i][j] = enum_map[enum_key]; + } + } + } + + return expanded_pinconfigs[gpioc]; +} diff --git a/target/j42/properties.c b/target/j42/properties.c new file mode 100644 index 0000000..4543828 --- /dev/null +++ b/target/j42/properties.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/j42/rules.mk b/target/j42/rules.mk new file mode 100644 index 0000000..6143f62 --- /dev/null +++ b/target/j42/rules.mk @@ -0,0 +1,65 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2186=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_HAS_BASEBAND=$(TARGET_HAS_BASEBAND) \ + \ + TARGET_SPARE0_CLK_CFG=0x81000001 \ + TARGET_VID0_CLK_CFG=0x81100000 \ + PLL2_T=1 \ + PLL2_P=2 \ + PLL2_M=99 \ + PLL2_S=15 \ + \ + WITH_HW_HOOVER=1 \ + DISPLAY_APPLE_TV_TUNABLES=1 \ + TARGET_DITHER_TYPE=DITHER_BLUE_NOISE \ + \ + TARGET_CORE_PHY_TMR_LPCLK_CFG=0x00330087 \ + TARGET_CORE_PHY_TMR_CFG=0x256f0000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + DP_DTPATH=\"arm-io/displayport\" \ + DPPHY_DTPATH=\"arm-io/lpdp-phy\" \ + WIFI_DTPATH=\"arm-io/uart2/wlan\" \ + ETHERNET_DTPATH=\"arm-io/usb-complex/usb-ehci2/lan0\" + +ifeq ($(SUB_TARGET),j42d) +OPTIONS += \ + WITH_TARGET_AMC_PARAMS=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ifeq ($(PRODUCT),iBoot) +OPTIONS += \ + WITH_HW_DISPLAY_DISPLAYPORT=1 +endif + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o + +ifneq ($(PRODUCT),LLB) +ALL_OBJS += \ + $(LOCAL_DIR)/properties.o +endif diff --git a/target/k93a/include/target/display_gamma_tables.h b/target/k93a/include/target/display_gamma_tables.h new file mode 100644 index 0000000..bf955f2 --- /dev/null +++ b/target/k93a/include/target/display_gamma_tables.h @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2010, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_DISPLAY_GAMMA_TABLES_H +#define __TARGET_DISPLAY_GAMMA_TABLES_H + +/* K9x display gamma tables */ + +static const display_gamma_table k93a_display_gamma_tables[] = +{ + { + 0x00960C49, 0x00FFFF7F, // LGD P5 table V0 + { + 0x62, 0xca, 0x1d, 0xd0, 0x1d, 0x00, 0x00, 0x0d, + 0x0d, 0x00, 0xc0, 0x1d, 0x77, 0xd3, 0x1d, 0x1c, + 0xc7, 0x71, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0x40, 0x03, 0x0d, 0x34, 0x34, + 0x0d, 0x0d, 0x00, 0x1c, 0x77, 0xdc, 0x71, 0x1c, + 0xc7, 0x71, 0xc7, 0xc1, 0x01, 0x70, 0xc0, 0x01, + 0x07, 0xc0, 0x01, 0x40, 0x00, 0x1c, 0x00, 0x1c, + 0x1c, 0xc7, 0xdd, 0x4d, 0xd3, 0x4d, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0xc7, 0x01, 0xd0, 0xd0, + 0x00, 0x00, 0x70, 0x77, 0x37, 0xdd, 0x74, 0xdc, + 0x71, 0xdc, 0x1d, 0x07, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x40, 0x03, 0x0d, + 0x4d, 0x43, 0x03, 0x1c, 0xc7, 0x1d, 0x77, 0x1c, + 0x07, 0xc7, 0xc1, 0x71, 0x00, 0x70, 0x00, 0x70, + 0x00, 0x00, 0x1c, 0xd0, 0x01, 0x00, 0x00, 0xc0, + 0x01, 0x07, 0x77, 0x77, 0x77, 0x13, 0x07, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0x77, 0x00, 0x40, 0x43, + 0x03, 0x0d, 0x07, 0x07, 0xc7, 0x1d, 0x07, 0x07, + 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, + 0x00, 0x0d, 0xd0, 0x34, 0x34, 0x0d, 0x4d, 0xd3, + 0x0d, 0x0d, 0xc0, 0x71, 0x1c, 0xc7, 0x71, 0x70, + 0x70, 0x1c, 0x1c, 0x00, 0x07, 0xc0, 0x01, 0x70, + 0x00, 0x1c, 0x00, 0x01, 0x1c, 0x00, 0x1c, 0x77, + 0xdc, 0x4d, 0x03, 0x0d, 0x00, 0x34, 0x4d, 0xd3, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00950C49, 0x00FFFF7F, // LGD P6 table V0 (same as P5) + { + 0x62, 0xca, 0x1d, 0xd0, 0x1d, 0x00, 0x00, 0x0d, + 0x0d, 0x00, 0xc0, 0x1d, 0x77, 0xd3, 0x1d, 0x1c, + 0xc7, 0x71, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0x40, 0x03, 0x0d, 0x34, 0x34, + 0x0d, 0x0d, 0x00, 0x1c, 0x77, 0xdc, 0x71, 0x1c, + 0xc7, 0x71, 0xc7, 0xc1, 0x01, 0x70, 0xc0, 0x01, + 0x07, 0xc0, 0x01, 0x40, 0x00, 0x1c, 0x00, 0x1c, + 0x1c, 0xc7, 0xdd, 0x4d, 0xd3, 0x4d, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0xc7, 0x01, 0xd0, 0xd0, + 0x00, 0x00, 0x70, 0x77, 0x37, 0xdd, 0x74, 0xdc, + 0x71, 0xdc, 0x1d, 0x07, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x40, 0x03, 0x0d, + 0x4d, 0x43, 0x03, 0x1c, 0xc7, 0x1d, 0x77, 0x1c, + 0x07, 0xc7, 0xc1, 0x71, 0x00, 0x70, 0x00, 0x70, + 0x00, 0x00, 0x1c, 0xd0, 0x01, 0x00, 0x00, 0xc0, + 0x01, 0x07, 0x77, 0x77, 0x77, 0x13, 0x07, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x40, 0x77, 0x00, 0x40, 0x43, + 0x03, 0x0d, 0x07, 0x07, 0xc7, 0x1d, 0x07, 0x07, + 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, + 0x00, 0x0d, 0xd0, 0x34, 0x34, 0x0d, 0x4d, 0xd3, + 0x0d, 0x0d, 0xc0, 0x71, 0x1c, 0xc7, 0x71, 0x70, + 0x70, 0x1c, 0x1c, 0x00, 0x07, 0xc0, 0x01, 0x70, + 0x00, 0x1c, 0x00, 0x01, 0x1c, 0x00, 0x1c, 0x77, + 0xdc, 0x4d, 0x03, 0x0d, 0x00, 0x34, 0x4d, 0xd3, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00970C49, 0x00FFFF7F, // LGD P3 table V0 + { + 0x62, 0xca, 0x04, 0x00, 0x71, 0x00, 0x40, 0x03, + 0x0d, 0x00, 0x70, 0xdc, 0xdd, 0xdd, 0x1d, 0x07, + 0x07, 0xc7, 0x01, 0xd7, 0x00, 0x00, 0x00, 0xd0, + 0xd0, 0x40, 0x43, 0x37, 0xdd, 0x34, 0xdd, 0x74, + 0x37, 0x0d, 0x00, 0xc7, 0x1d, 0x77, 0x1c, 0x1c, + 0x1c, 0xc7, 0xc1, 0x01, 0x70, 0xc0, 0x01, 0x07, + 0xc0, 0x01, 0x47, 0x07, 0x00, 0x1c, 0xc0, 0x1d, + 0xc7, 0xdd, 0x40, 0x03, 0xd0, 0x40, 0x77, 0x77, + 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x74, 0xd0, 0x04, 0x07, 0x00, 0x0d, + 0x00, 0x00, 0x70, 0x77, 0x77, 0xd3, 0xdd, 0x71, + 0x70, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x03, 0x0d, 0x34, 0x74, 0xd3, 0x34, 0xdd, 0x74, + 0x77, 0xd3, 0x00, 0xc7, 0x71, 0xc7, 0x71, 0x70, + 0x70, 0x1c, 0x1c, 0x70, 0x00, 0x70, 0x00, 0x70, + 0x00, 0x70, 0x00, 0x04, 0x00, 0x00, 0x70, 0x70, + 0x1c, 0x77, 0x37, 0x34, 0xd0, 0xd0, 0xdd, 0xdd, + 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x74, 0x0d, 0x1d, 0x07, 0xd0, 0x40, + 0x03, 0x00, 0x00, 0x07, 0x1c, 0xc7, 0x01, 0xc0, + 0x01, 0xc0, 0x01, 0x0d, 0x34, 0x00, 0x34, 0x4d, + 0x37, 0x4d, 0xd3, 0xdd, 0xdd, 0xdd, 0x1d, 0x77, + 0x37, 0x7d, 0x70, 0x1c, 0x1c, 0xc7, 0x01, 0x07, + 0x1c, 0x1c, 0x00, 0x1c, 0xc0, 0x01, 0x1c, 0xc0, + 0x01, 0x1c, 0x1d, 0x00, 0x70, 0x70, 0xdc, 0x4d, + 0x37, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00E40C49, 0x00FFFF7F, // Samsung 6mask table V0 + { + 0x62, 0xca, 0x74, 0xd0, 0x04, 0x07, 0x00, 0x0d, + 0xd0, 0x00, 0x1c, 0x1c, 0x1c, 0x77, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0x43, 0x43, 0x43, 0xd3, + 0x40, 0x03, 0x0d, 0x34, 0x00, 0x0d, 0x00, 0x34, + 0x00, 0x00, 0x34, 0x00, 0x34, 0x00, 0x1c, 0x70, + 0x70, 0x1c, 0x1c, 0x07, 0xc7, 0x71, 0x77, 0x77, + 0xd3, 0x74, 0xd3, 0x01, 0x00, 0x00, 0x40, 0x43, + 0x77, 0x77, 0x77, 0x07, 0xc7, 0xc1, 0x41, 0x43, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x04, 0x00, 0x1d, 0xb0, 0x32, 0x00, + 0x0d, 0x40, 0x1f, 0x70, 0xdc, 0x71, 0xc7, 0x01, + 0x1c, 0x00, 0x07, 0x40, 0x43, 0x03, 0x34, 0x40, + 0x03, 0x0d, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x70, + 0x70, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x77, + 0x77, 0xd3, 0x4d, 0x77, 0x07, 0x00, 0x00, 0xd0, + 0x74, 0x77, 0x1c, 0x07, 0x1c, 0x00, 0xd0, 0xdd, + 0x71, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x74, 0x00, 0xdd, 0x01, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x34, + 0x40, 0x03, 0x74, 0x37, 0xdd, 0x74, 0x37, 0xdd, + 0x34, 0x4d, 0xd3, 0xd0, 0x40, 0x43, 0x03, 0x0d, + 0xd0, 0x40, 0x03, 0x0d, 0x34, 0x1c, 0xc0, 0x01, + 0x07, 0x1c, 0x1c, 0x1c, 0x1c, 0x77, 0x37, 0xdd, + 0x4d, 0x77, 0x07, 0x00, 0x00, 0x00, 0x40, 0xd3, + 0x34, 0x34, 0xdd, 0x34, 0x4d, 0xd3, 0x34, 0xdd, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00E30C49, 0x00FFFF7F, // Samsung 5mask table V0 + { + 0x22, 0xce, 0x4d, 0x07, 0xd0, 0x74, 0x1c, 0x1c, + 0x1c, 0x1c, 0xd3, 0xdd, 0xdd, 0x34, 0xdd, 0x74, + 0x07, 0x1c, 0x1c, 0x1c, 0x00, 0x0d, 0xd0, 0x00, + 0x34, 0x0d, 0x0d, 0x34, 0xd0, 0x40, 0x03, 0x34, + 0xd0, 0x40, 0x03, 0x34, 0x34, 0x0d, 0x0d, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0xc0, 0x71, + 0x1c, 0x77, 0xc7, 0x1d, 0x00, 0xd0, 0x00, 0x4d, + 0x07, 0x07, 0x1c, 0x00, 0x00, 0x00, 0xd0, 0x1d, + 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0xce, 0x4d, 0x07, 0x40, 0x77, 0x07, 0x07, + 0xc7, 0x71, 0x37, 0xdd, 0x74, 0xd3, 0x34, 0x74, + 0xc7, 0xc1, 0x71, 0x07, 0x07, 0x0d, 0x00, 0x40, + 0x03, 0x34, 0x40, 0x03, 0xd0, 0x00, 0x0d, 0x00, + 0x0d, 0xd0, 0x00, 0x34, 0xd0, 0xd0, 0x40, 0x03, + 0x00, 0x07, 0xc0, 0x01, 0x00, 0x1c, 0x00, 0x07, + 0xc7, 0x1d, 0x77, 0xdc, 0x41, 0x43, 0x43, 0xd3, + 0x71, 0x00, 0x1c, 0x00, 0x0d, 0xd0, 0xc4, 0x01, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0xce, 0x0d, 0x01, 0x40, 0x13, 0x77, 0x70, + 0xc0, 0xc1, 0x1d, 0xc7, 0x71, 0xc7, 0xdd, 0x71, + 0x00, 0x00, 0x07, 0x00, 0x4d, 0xd3, 0xd0, 0x34, + 0x4d, 0x37, 0x4d, 0xd3, 0x34, 0x34, 0x34, 0x4d, + 0x43, 0xd3, 0xd0, 0x74, 0xd3, 0x34, 0x00, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x07, 0x70, 0xdc, + 0x1d, 0x77, 0x07, 0x00, 0x00, 0x0d, 0xd0, 0x74, + 0xdc, 0xdd, 0x1d, 0x77, 0xdc, 0x71, 0x1c, 0x77, + 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00890C49, 0x00FFFF7F, // CMI T1 table V0 + { + 0x62, 0xca, 0x01, 0x74, 0x00, 0xd0, 0xdd, 0x1d, + 0x77, 0x4c, 0x43, 0x03, 0x40, 0xd3, 0xdd, 0xdd, + 0x1d, 0xc7, 0xc1, 0x1d, 0xc7, 0x71, 0x77, 0x77, + 0x77, 0xd3, 0x34, 0x0d, 0x0d, 0x0d, 0x34, 0xd0, + 0x00, 0x34, 0x00, 0x70, 0x70, 0xc7, 0x71, 0xdc, + 0x1d, 0x77, 0x77, 0x77, 0x43, 0x03, 0xd0, 0x00, + 0xd0, 0x74, 0x1c, 0x77, 0xdc, 0xc1, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x4d, 0xd3, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x01, 0x74, 0x00, 0xd0, 0x74, 0xdc, + 0x71, 0xd3, 0x34, 0x00, 0xd0, 0xd0, 0xdd, 0xdd, + 0xdd, 0x1d, 0x1c, 0xc7, 0x1d, 0xc7, 0xdd, 0xdd, + 0xdd, 0x74, 0x43, 0xd3, 0x34, 0x34, 0x34, 0x40, + 0x03, 0x34, 0x00, 0xc0, 0x71, 0x1c, 0xc7, 0x71, + 0xc7, 0xdd, 0x1d, 0x37, 0x0d, 0x34, 0x40, 0x03, + 0xd0, 0x74, 0x1c, 0x77, 0x1c, 0x07, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x40, 0xd3, 0x34, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xca, 0x01, 0x74, 0x00, 0xd0, 0x74, 0xdc, + 0x71, 0x77, 0xd3, 0xd0, 0xd0, 0x74, 0xdc, 0x1d, + 0x77, 0x70, 0x70, 0x70, 0x1c, 0x1c, 0x77, 0xdc, + 0xdd, 0x4d, 0x37, 0x4d, 0xd3, 0x34, 0x34, 0x0d, + 0x0d, 0x34, 0x00, 0x70, 0x1c, 0x07, 0xc7, 0x1d, + 0xc7, 0x1d, 0x77, 0x37, 0x34, 0xd0, 0x00, 0x0d, + 0x74, 0xc7, 0x71, 0xc7, 0x71, 0x00, 0x07, 0x00, + 0x1c, 0x00, 0x70, 0x00, 0x1c, 0x00, 0xc0, 0x01, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, + { + 0x00900C49, 0x00FFFF7F, // CMI T1x table V0 + { + 0x26, 0x11, 0x07, 0xd0, 0x1d, 0x00, 0x00, 0xdd, + 0xdd, 0xc1, 0x01, 0x07, 0x1c, 0x1c, 0xc7, 0xdd, + 0x34, 0x34, 0xd0, 0x00, 0x0d, 0x34, 0x00, 0x0d, + 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x70, 0xc0, 0xc1, 0xc1, 0xc1, + 0xc1, 0x71, 0x1c, 0x77, 0xdc, 0x71, 0x1c, 0x07, + 0xc7, 0x71, 0x70, 0x1c, 0x1c, 0x40, 0x1c, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0xd1, 0x1d, 0xd0, 0x74, 0x1c, 0x00, 0x34, + 0x4d, 0xc7, 0x1d, 0xc7, 0x1d, 0x77, 0x77, 0xd3, + 0xd0, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x07, 0x70, + 0xc0, 0x01, 0x00, 0x07, 0x70, 0x00, 0x07, 0xc0, + 0x01, 0x1c, 0xc0, 0x01, 0x07, 0x1c, 0xc7, 0x71, + 0x1c, 0x77, 0xdc, 0x1d, 0x77, 0x77, 0x77, 0xc7, + 0xdd, 0x71, 0x77, 0xdc, 0x71, 0xc7, 0x1d, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x41, 0x77, 0x00, 0x74, 0x77, 0x00, 0x00, + 0x40, 0xd3, 0x4d, 0x77, 0x37, 0xdd, 0x34, 0x0d, + 0x40, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xc0, + 0x01, 0x70, 0x00, 0x1c, 0x70, 0xc0, 0xc1, 0x71, + 0x1c, 0xc7, 0xc1, 0xc1, 0x71, 0x1c, 0xc7, 0xc1, + 0x71, 0x1c, 0x1c, 0x77, 0x1c, 0x77, 0xdc, 0xdd, + 0x31, 0xdd, 0xdd, 0x4d, 0x37, 0x4d, 0x43, 0xd3, + 0x34, 0x4d, 0xd3, 0xd0, 0x34, 0x34, 0x34, 0x34, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + } + }, +}; + +#endif diff --git a/target/k93a/include/target/gpiodef.h b/target/k93a/include/target/gpiodef.h new file mode 100644 index 0000000..4e3220f --- /dev/null +++ b/target/k93a/include/target/gpiodef.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* K93a specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_RST GPIO(16, 0) +#define GPIO_LCD_RST_POLARITY (0) +#define GPIO_LCD_PWR_EN GPIO(16, 1) + +#define GPIO_RINGER_AB GPIO( 0, 4) + +#define POWER_GPIO_BATTERY_SWI (5) +#define POWER_GPIO_BATTERY_SWI_CONFIG_OUTPUT 0x0B +#define POWER_GPIO_BATTERY_SWI_CONFIG_INPUT 0xD8 + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 4, 5) +#define GPIO_BOARD_REV1 GPIO( 4, 6) +#define GPIO_BOARD_REV2 GPIO( 4, 7) + +/* which IICs to initialize */ +#define IICS_MASK (7) + +/* D1946 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/k93a/include/target/nand_spec_tables.h b/target/k93a/include/target/nand_spec_tables.h new file mode 100644 index 0000000..61ff759 --- /dev/null +++ b/target/k93a/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000101 + }, + + /* useToggleMode */ FALSE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ FALSE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ FALSE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/k93a/include/target/pinconfig.h b/target/k93a/include/target/pinconfig.h new file mode 100644 index 0000000..9884c7f --- /dev/null +++ b/target/k93a/include/target/pinconfig.h @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default K93a SoC Pin Configuration */ + +/* Same drive strength for AP and DEV */ +#define AUD_SPKRAMP_MUTE_L_DRIVE_STR DRIVE_X1 +#define DFU_STATUS_DRIVE_STR DRIVE_X1 +#define DWI_DRIVE_STR DRIVE_X2 +#define FMI_DRIVE_STR DRIVE_X1 // SecureROM is X2 +#define GRAPE_DRIVE_STR DRIVE_X1 +#define MLC_DRIVE_STR DRIVE_X1 +#define PM_BT_WAKE_DRIVE_STR DRIVE_X2 +#define PM_CAM_SHUTDOWN_DRIVE_STR DRIVE_X1 +#define CLK_CAM_DRIVE_STR DRIVE_X3 +#define PM_KEEPACT_DRIVE_STR DRIVE_X1 +#define RST_PMU_IN_DRIVE_STR DRIVE_X1 +#define SDIO_WL_DRIVE_STR DRIVE_X1 +#define VIDEO_AMP_EN_DRIVE_STR DRIVE_X1 +#define I2C_DRIVE_STR DRIVE_X2 +#define UART_5_DRIVE_STR DRIVE_X2 +#define I2S_DRIVE_STR DRIVE_X2 +#define I2S_MCK_DRIVE_STR DRIVE_X3 +#define SPI_CS_DRIVE_STR DRIVE_X1 +#define SPI_DATA_DRIVE_STR DRIVE_X2 + +/* Different drive strength for AP and DEV. // AP DEV */ +#if PIN_CFG_AP +#define BT_UART_DRIVE_STR DRIVE_X2 // X2 X3 +#define UART_0_DRIVE_STR DRIVE_X1 // X2 X3 +#else +#define BT_UART_DRIVE_STR DRIVE_X3 // X2 X3 +#define UART_0_DRIVE_STR DRIVE_X2 // X2 X2 +#endif + +#define FMI_SLEW_RATE SLEW_RATE_SLOW + +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_IN | PULL_UP, // GPIO2 -> AUD_VOL_UP_L + CFG_IN | PULL_UP, // GPIO3 -> AUD_VOL_DOWN_L + CFG_IN, // GPIO4 -> SRL_L + CFG_OUT_0 | AUD_SPKRAMP_MUTE_L_DRIVE_STR, // GPIO5 -> AUD_SPKRAMP_MUTE_L + CFG_DISABLED, // GPIO6 -> + CFG_OUT_0 | PM_BT_WAKE_DRIVE_STR, // GPIO7 -> PM_BT_WAKE + +/* Port 1 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_IN | PULL_UP, // GPIO13 -> IRQ_PMU_L + CFG_OUT_1 | GRAPE_DRIVE_STR, // GPIO14 -> GRAPE_FW_DNLD_EN_L + CFG_IN | PULL_UP, // GPIO15 -> IRQ_CODEC_L + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID_3 + CFG_IN | PULL_DOWN, // GPIO17 -> IRQ_GYRO_INT2 + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG_0 + CFG_OUT_0 | PM_KEEPACT_DRIVE_STR, // GPIO19 -> PM_KEEPACT + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_OUT_0 | GRAPE_DRIVE_STR, // GPIO22 -> RST_GRAPE_L + CFG_DISABLED, // GPIO23 -> + +/* Port 3 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG_1 + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_OUT_0 | DFU_STATUS_DRIVE_STR | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG_2 + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG_3 + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> + +/* Port 4 */ + CFG_DISABLED, // GPIO32 -> + CFG_IN | PULL_DOWN, // GPIO33 -> IRQ_GYRO_INT1 + CFG_IN | PULL_UP, // GPIO34 -> IRQ_ALS_INT_L + CFG_IN | PULL_UP, // GPIO35 -> IRQ_ACCEL_INT2_L + CFG_IN | PULL_UP, // GPIO36 -> IRQ_ACCEL_INT1_L + CFG_DISABLED, // EHCI_PORT_PWR[0] -> AP_GPIO37_BRD_REV0 + CFG_DISABLED, // EHCI_PORT_PWR[1] -> AP_GPIO38_BRD_REV1 + CFG_DISABLED, // EHCI_PORT_PWR[2] -> AP_GPIO39_BRD_REV2 + +/* Port 5 */ + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + +/* Port 6 */ + CFG_FUNC0 | BT_UART_DRIVE_STR, // UART3_TXD -> UART_3_TXD + CFG_FUNC0, // UART3_RXD -> UART_3_RXD + CFG_OUT_1 | BT_UART_DRIVE_STR, // UART3_RTSN -> UART_3_RTS_L + CFG_FUNC0, // UART3_CTSN -> UART_3_CTS_L + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED, // I2C1_SDA -> I2C1_SDA_1V8 + CFG_DISABLED, // I2C1_SCL -> I2C1_SCL_1V8 + +/* Port 7 */ + CFG_FUNC0 | I2C_DRIVE_STR, // ISP0_SDA -> ISP_AP_0_SDA + CFG_FUNC0 | I2C_DRIVE_STR, // ISP0_SCL -> ISP_AP_0_SCL + CFG_FUNC0 | I2C_DRIVE_STR, // ISP1_SDA -> ISP_AP_1_SDA + CFG_FUNC0 | I2C_DRIVE_STR, // ISP1_SCL -> ISP_AP_1_SCL + CFG_DISABLED, // UART5_TXD/MIPI_VSYNC -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + +/* Port 8 */ + CFG_DISABLED, // SWI_DATA -> + CFG_FUNC0 | PULL_DOWN, // DWI_DI -> DWI_AP_DI + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> DWI_AP_CLK + CFG_OUT_0 | PM_CAM_SHUTDOWN_DRIVE_STR, // SENSOR0_RST -> PM_REAR_CAM_SHUTDOWN_L + CFG_OUT_0 | CLK_CAM_DRIVE_STR, // SENSOR0_CLK -> CLK_CAM_RF + CFG_OUT_1 | PM_CAM_SHUTDOWN_DRIVE_STR, // SENSOR1_RST -> PM_FRONT_CAM_SHUTDOWN + CFG_OUT_0 | CLK_CAM_DRIVE_STR, // SENSOR1_CLK -> CLK_CAM_FF + +/* Port 9 */ + CFG_DISABLED, // ISP0_PRE_FLASH -> + CFG_DISABLED, // ISP0_FLASH -> + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_DISABLED, // ISP1_FLASH -> + CFG_FUNC0 | I2S_MCK_DRIVE_STR, // I2S0_MCK -> I2S_AP_0_MCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> I2S_AP_0_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_SCLK -> I2S_AP_0_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> I2S_AP_0_DOUT + +/* Port 10 */ + CFG_FUNC0, // I2S0_DIN -> I2S_AP_0_DIN + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_SCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> I2S_AP_2_LRCK + +/* Port 11 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> I2S_AP_2_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> I2S_AP_2_DOUT + CFG_FUNC0, // I2S2_DIN -> I2S_AP_2_DIN + CFG_DISABLED, // I2S2_MCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> I2S_AP_3_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> I2S_AP_3_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> I2S_AP_3_DOUT + CFG_FUNC0, // I2S3_DIN -> I2S_AP_3_DIN + +/* Port 12 */ + CFG_DISABLED, // SPI0_SCLK -> BOARD_ID_0_SPI_FLASH_CLK + CFG_DISABLED, // SPI0_MOSI -> BOARD_ID_1_SPI_FLASH_DIN + CFG_DISABLED, // SPI0_MISO -> BOARD_ID_2_SPI_FLASH_DOUT + CFG_DISABLED | PULL_UP, // SPI0_SSIN -> + CFG_FUNC0 | SPI_DATA_DRIVE_STR, // SPI1_SCLK -> SPI_GRAPE_SCLK + CFG_FUNC0 | SPI_DATA_DRIVE_STR, // SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // SPI1_MISO -> SPI_GRAPE_MISO + CFG_OUT_1 | SPI_CS_DRIVE_STR, // SPI1_SSIN -> SPI_GRAPE_CS_L + +/* Port 13 */ + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 14 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 15 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 16 */ + CFG_OUT_0 | MLC_DRIVE_STR, // UART4_TXD -> RST_MLC_L + CFG_OUT_0 | MLC_DRIVE_STR, // UART4_RXD -> PM_MLC_PWR_EN + CFG_OUT_0 | VIDEO_AMP_EN_DRIVE_STR, // UART4_RTSN -> VIDEO_AMP_EN + CFG_IN | PULL_UP, // UART4_CTSN -> IRQ_GRAPE_HOST_INT_L + CFG_FUNC0 | SDIO_WL_DRIVE_STR | PULL_UP, // SDIO0_DATA3 -> SDIO_WL_DATA<3> + CFG_FUNC0 | SDIO_WL_DRIVE_STR | PULL_UP, // SDIO0_DATA2 -> SDIO_WL_DATA<2> + CFG_FUNC0 | SDIO_WL_DRIVE_STR | PULL_UP, // SDIO0_DATA1 -> SDIO_WL_DATA<1> + CFG_FUNC0 | SDIO_WL_DRIVE_STR | PULL_UP, // SDIO0_DATA0 -> SDIO_WL_DATA<0> + +/* Port 17 */ + CFG_FUNC0 | SDIO_WL_DRIVE_STR | PULL_UP, // SDIO0_CMD -> SDIO_WL_CMD + CFG_FUNC0 | SDIO_WL_DRIVE_STR, // SDIO0_CLK -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN3 -> F0CE3_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN2 -> F0CE2_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN1 -> F0CE1_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN0 -> F0CE0_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CLE -> F0CLE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_ALE -> F0ALE + +/* Port 18 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_REN -> F0RE_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_WEN -> F0WE_L + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO7 -> F0AD<7> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO6 -> F0AD<6> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO5 -> F0AD<5> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO4 -> F0AD<4> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 19 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 20 */ + CFG_DISABLED | PULL_DOWN, // FMI0_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO3 -> F0AD<3> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO2 -> F0AD<2> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO1 -> F0AD<1> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO0 -> F0AD<0> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN3 -> F1CE3_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN2 -> F1CE2_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN1 -> F1CE1_L + +/* Port 21 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN0 -> F1CE0_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CLE -> F1CLE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_ALE -> F1ALE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_REN -> F1RE_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_WEN -> F1WE_L + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO7 -> F1AD<7> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO6 -> F1AD<6> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO5 -> F1AD<5> + +/* Port 22 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO4 -> F1AD<4> + CFG_DISABLED | PULL_DOWN, // FMI1_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO3 -> F1AD<3> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO2 -> F1AD<2> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO1 -> F1AD<1> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO0 -> F1AD<0> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 23 */ + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + +/* Port 24 */ + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SCL -> I2C2_SCL_1V8 + CFG_FUNC0 | UART_0_DRIVE_STR, // UART0_TXD -> UART_0_TXD + CFG_FUNC0 | UART_0_DRIVE_STR, // UART0_RXD -> UART_0_RXD + CFG_FUNC0 | UART_5_DRIVE_STR, // UART5_RTXD -> UART_5_RTXD + CFG_FUNC0, // DP_HPD -> DP_AP_HPD + CFG_DISABLED, // TST_CLKOUT -> TP_AP_TST_CLKOUT + CFG_DISABLED, // TST_STPCLK -> + +/* Port 25 */ + CFG_FUNC0 | RST_PMU_IN_DRIVE_STR, // WDOG -> RST_PMU_IN + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#undef AUD_SPKRAMP_MUTE_L_DRIVE_STR +#undef DFU_STATUS_DRIVE_STR +#undef DWI_DRIVE_STR +#undef FMI_DRIVE_STR +#undef GRAPE_DRIVE_STR +#undef MLC_DRIVE_STR +#undef PM_BT_WAKE_DRIVE_STR +#undef PM_CAM_SHUTDOWN_DRIVE_STR +#undef CLK_CAM_DRIVE_STR +#undef PM_KEEPACT_DRIVE_STR +#undef RST_PMU_IN_DRIVE_STR +#undef SDIO_WL_DRIVE_STR +#undef VIDEO_AMP_EN_DRIVE_STR +#undef I2C_DRIVE_STR +#undef UART_5_DRIVE_STR +#undef I2S_DRIVE_STR +#undef I2S_MCK_DRIVE_STR +#undef SPI_CS_DRIVE_STR +#undef SPI_DATA_DRIVE_STR +#undef BT_UART_DRIVE_STR +#undef UART_0_DRIVE_STR + +#undef FMI_SLEW_RATE diff --git a/target/k93a/include/target/powerconfig.h b/target/k93a/include/target/powerconfig.h new file mode 100644 index 0000000..954fb9c --- /dev/null +++ b/target/k93a/include/target/powerconfig.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Force bypass off + { PMU_IIC_BUS, kD1946_LDO1, 0x0A }, // PP3V0_GRAPE 3.00V + { PMU_IIC_BUS, kD1946_LDO2, 0x0A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1946_LDO3, 0x0A }, // PP3V0_VIDEO 3.00V + { PMU_IIC_BUS, kD1946_LDO4, 0x18 }, // PP3V0_OPTICAL 3.00V + { PMU_IIC_BUS, kD1946_LDO5, 0x0E }, // PP3V2_SD 3.20V + { PMU_IIC_BUS, kD1946_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1946_LDO7, 0x03 }, // PP1V8_VIDEO 1.80V + { PMU_IIC_BUS, kD1946_LDO8, 0x18 }, // PP3V2_S2R_USBMUX 3.20V + { PMU_IIC_BUS, kD1946_LDO9, 0x12 }, // PP3V0_IO 3.00V + { PMU_IIC_BUS, kD1946_LDO10, 0x0A }, // PP3V2_SD_CTRL 3.00V + { PMU_IIC_BUS, kD1946_LDO11, 0x17 }, // PP2V85_CAM 2.85V + { PMU_IIC_BUS, kD1946_LDO12, 0x10 }, // PP1V0 1.00V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // Leave bypass off +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1946_ACTIVE1, 0xDD }, // Everything but BUCK1 and LDO1 + { PMU_IIC_BUS, kD1946_ACTIVE2, 0xE9 }, // Everything but SD and ACC, LDO8 + { PMU_IIC_BUS, kD1946_ACTIVE3, 0x61 }, // BUCK5, VBOOST_LCM, PP1V1 + { PMU_IIC_BUS, kD1946_ACTIVE4, 0xA0 }, // CPU1V8_SW and CPU1V2_SW + { PMU_IIC_BUS, kD1946_LCM_CONTROL1, 0x02 }, // unused 5.10V + { PMU_IIC_BUS, kD1946_LCM_CONTROL2, 0x0E }, // unused 5.70V + { PMU_IIC_BUS, kD1946_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1946_LCM_BST_CONTROL, 0x14 }, // VBOOST_LCM 6.00V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // HIB_32K on, DWI off + + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_A, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_B, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_C, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_D, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_E, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_F, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_G, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_H, 0x00 }, + { PMU_IIC_BUS, kDIALOG_IRQ_MASK_K, 0x00 }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD1946_BUCK4, 0x9B }, // BUCK4 1.21V + { PMU_IIC_BUS, kD1946_BUCK4_HIB, 0x9B }, // BUCK4_HIB 1.21V + + { PMU_IIC_BUS, kD1946_SYS_GPIO_1, 0x11 }, // CLK_32K_PMU Out 0, Push-Pull, CPU_1V8 + { PMU_IIC_BUS, kD1946_SYS_GPIO_2, 0x49 }, // CLK_32K_WLAN CLK32K, Pull Down, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_3, 0x09 }, // RST_BT_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_4, 0x09 }, // RST_WLAN_L Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_5, 0x09 }, // RST_BB_PMU_L Out 0, Push-pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_6, 0xDA }, // BATTERY_SWI In, F Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_7, 0xBB }, // PM_BT_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_8, 0xBB }, // PM_WLAN_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_9, 0xBB }, // PM_BB_HOST_WAKE In, R Edge, Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_10, 0xEA }, // AUD_MIK_HS1_INT_L In, Change, Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_11, 0x09 }, // DOCK_BB_EN Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_12, 0x49 }, // CLK_32K_GPS CLK32K, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_13, 0xB9 }, // SD_CON_CD In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_14, 0xC8 }, // RST_L63_L In, F Edge, No Wake, Pull Up, VBUCK3 + { PMU_IIC_BUS, kD1946_SYS_GPIO_15, 0xFA }, // HALL_IRQ In, E Edge, Wake, Pull Up, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_16, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_17, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + { PMU_IIC_BUS, kD1946_SYS_GPIO_18, 0xB9 }, // unused In, R Edge, No Wake, Pull Down, Disable Pull-Up + + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB1, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB2, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB3, 0x02 }, // no debounce on GPIO6 + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB4, 0x10 }, // no debounce on GPIO7 + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB5, 0x02 }, // no debounce on GPIO10 + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB6, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB7, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB8, 0x12 }, // 10ms debounce + { PMU_IIC_BUS, kD1946_SYS_GPIO_DEB9, 0x12 }, // 10ms debounce + + // + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x02 }, + { PMU_IIC_BUS, kD1946_TEST_MODE, 0x01 }, // Enable test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, + { PMU_IIC_BUS, kD1946_WLED_CONTROL5, 0x00 }, // set WLED to IDAC always + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x02 }, + { PMU_IIC_BUS, kD1946_TEST_MODE, 0x00 }, // Disable test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, + + // + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, // Select Bank 1 + { PMU_IIC_BUS, kD1946_BUCK_CONTROL1, 0x0e }, // Force Buck0 into PWM Mode + { PMU_IIC_BUS, kD1946_BUCK_CONTROL3, 0x0e }, // Force Buck2 into PWM Mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, // Select Bank 0 +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xD4 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x00 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable all LED strings + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | + kDIALOG_WLED_CONTROL_WLED_ENABLE2 | + kDIALOG_WLED_CONTROL_WLED_ENABLE3 | + kDIALOG_WLED_CONTROL_WLED_ENABLE4 | + kDIALOG_WLED_CONTROL_WLED_ENABLE5 | + kDIALOG_WLED_CONTROL_WLED_ENABLE6) }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL2, // enable LED Power + (kDIALOG_WLED_CONTROL2_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL2_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define TARGET_USE_CHARGE_TABLE 1 +static const struct power_charge_limits pmu_charge_table[16] = { // gas gauge can have up to 16 entries + { 4000, 1000, 1600, 3000 }, // 10 - 16C 0.44C + { 4100, 1000, 1600, 1375 }, // 0.2C + { USHRT_MAX, 1000, 1600, 750 }, // 0.11C + { 4000, 1500, 2100, 3000 }, // 15 - 21C 0.44C + { 4100, 1500, 2100, 2000 }, // 0.29C + { USHRT_MAX, 1500, 2100, 1375 }, // 0.2C + { 4000, 2000, 3500, 3000 }, // 20 - 35C 0.44C + { 4100, 2000, 3500, 3000 }, // 0.44C + { USHRT_MAX, 2000, 3500, 2000 }, // 0.29C + { 4000, 3400, 4500, 3000 }, // 34 - 45C 0.44C + { 4100, 3400, 4500, 3000 }, // 0.44C + { USHRT_MAX, 3400, 4500, 3000 }, // 0.44C +}; + +// matches OTP for ICHG_TBAT_x +#define TARGET_ICHG_TBAT_MAX { 0x00, 0x00, 0x3f, 0x3f, 0x3f } + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 1287 /* 10% brightness */ +#define TARGET_PRECHARGE_ALWAYS_DISPLAY_IDLE 1 +#define TARGET_MAX_USB_INPUT_CURRENT 2100 + +#define TARGET_BRICKID_FULL_SCALE (5000 * 3) // H4A has resistor divider for USB monitor + +#define GASGAUGE_BATTERYID_BLOCK 1 +#define GASGAUGE_CHARGETABLE_BLOCK 3 +static const unsigned int atv_voltage_limit[16] = { 3600, 3650, 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350 }; +static const unsigned int atv_current_limit[16] = { 0, 0, 625, 750, 875, 1000, 1125, 1250, 1375, 1500, 1750, 2000, 2250, 2500, 2750, 3000 }; + +#endif diff --git a/target/k93a/include/target/uartconfig.h b/target/k93a/include/target/uartconfig.h new file mode 100644 index 0000000..b48b06b --- /dev/null +++ b/target/k93a/include/target/uartconfig.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/k93a/init.c b/target/k93a/init.c new file mode 100644 index 0000000..8caa2bb --- /dev/null +++ b/target/k93a/init.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT_PTR(kMIBTargetDisplayGammaTablePtr,kOIDTypeStruct, (void *)k93a_display_gamma_tables); +MIB_CONSTANT(kMIBTargetDisplayGammaTableCount, kOIDTypeUInt32, ARRAY_SIZE(k93a_display_gamma_tables)); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 90); + +static uint32_t display_config; + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000644; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "k48", 0); +} + +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + DTNode *node, *clcd_node, *backlight_node; + uint32_t propSize, propCnt; + char *propName; + void *propData; + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + } + + // Find the CLCD node + FindNode(0, "arm-io/clcd", &clcd_node); + +#if WITH_HW_DISPLAY_PINOT + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, clcd_node, backlight_node); + } +#endif + + // Update the bottom prox calibration data + if (FindNode(0, "arm-io/i2c1/prox", &node)) { + propName = "prox-bottom-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBCl', propData, propSize); + } + propName = "prox-temp-base"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBTb', propData, propSize); + } + propName = "prox-centerpoint-base"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PBCb', propData, propSize); + } + propName = "prox-calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPCl', propData, propSize); + } + } + + // Update als node with calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "backlight-leakage-channel0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC0', propData, propSize); + } + propName = "backlight-leakage-channel1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC1', propData, propSize); + } + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + } + + // Update camera calibration data + if (FindNode(0, "arm-io/isp", &node)) { + propName = "camera-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CmCl', propData, propSize); + } + } + + // Update USB input current limit + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-max"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = TARGET_MAX_USB_INPUT_CURRENT; + } + } + + return 0; +} + +#endif diff --git a/target/k93a/pinconfig.c b/target/k93a/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/k93a/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/k93a/properties.c b/target/k93a/properties.c new file mode 100644 index 0000000..1420ad7 --- /dev/null +++ b/target/k93a/properties.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2011-2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include + +#if WITH_DEVICETREE + +bool +target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + int length = 0; + bool result = false; + + if ((result = target_get_property_base(prop, data, maxdata, retlen)) == false) { + switch(prop) { + case TARGET_PROPERTY_RESTORE_BACKLIGHT_LEVEL: + // fix the restore backlight level at the precharge level, + // to make sure the backlight does not cause the battery to + // drain during restore + if (maxdata >= (ssize_t)sizeof(uint32_t)) { + result = true; + length = sizeof(uint32_t); + *(uint32_t *)data = PRECHARGE_BACKLIGHT_LEVEL; + } + break; + + default: + break; + } + } + + if (retlen != NULL) *retlen = length; + + return result; +} + +#endif diff --git a/target/k93a/rules.mk b/target/k93a/rules.mk new file mode 100644 index 0000000..920cdb5 --- /dev/null +++ b/target/k93a/rules.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1946=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_HIGH \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_HIGH \ + TARGET_CPU_VOLTAGE_MASK=5 \ + TARGET_EMA_CTL_CPU_SEL=2 \ + TARGET_CPU_SOURCE=1 \ + TARGET_MIPI_DSI_SOURCE=2 \ + TARGET_MANAGED2H_SOURCE=1 \ + TARGET_MANAGED2L_SOURCE=2 \ + TARGET_MANAGED2H_DIV=2 \ + TARGET_MANAGED2L_DIV=3 \ + TARGET_PCLK1_SOURCE=2 \ + TARGET_PCLK1_DIV=6 \ + TARGET_GFX_SOURCE=2 \ + TARGET_GFX_SLC_SOURCE=2 \ + TARGET_SPI2_SOURCE=0 \ + TARGET_IOP_SOURCE=3 \ + TARGET_LPERFS_SOURCE=3 \ + TARGET_HPERFNRT_SOURCE=0 \ + TARGET_CLCD_VSPP=0 \ + TARGET_DSIM_CONFIG=0x00800000 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/m7ref/include/target/aspnandconfig.h b/target/m7ref/include/target/aspnandconfig.h new file mode 100644 index 0000000..2bb0417 --- /dev/null +++ b/target/m7ref/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 1 +#define ASPNAND_READ_DIES_IN_PARALLEL 1 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 1 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 1 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/m7ref/include/target/gpiodef.h b/target/m7ref/include/target/gpiodef.h new file mode 100644 index 0000000..174950b --- /dev/null +++ b/target/m7ref/include/target/gpiodef.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPod6,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_ALT_BOOST_ID GPIOC(GPIO_AP, 5, 3) // GPIO11 + +/* which IICs to initialize */ +#define IICS_MASK (3) + +#define DISPLAY_PMU_IIC_BUS (1) + +/* Miscellaneous Pins */ +#define GPIO_PMU_LCD_RST (12) + +/* + * support of video or command mode + */ +extern bool product_target_is_display_in_video_mode(); +#define TARGET_DISP_VIDEO_MODE product_target_is_display_in_video_mode() +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/m7ref/include/target/powerconfig.h b/target/m7ref/include/target/powerconfig.h new file mode 100644 index 0000000..c33e928 --- /dev/null +++ b/target/m7ref/include/target/powerconfig.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +//#define CHARGER_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2238_ALL_RAILS_CONF, 0x00 }, // enable SOC_VDD_ALL_RAILS_ON processing + { PMU_IIC_BUS, kD2238_GPIO14_CONF1, 0x93 }, // PMU register 0x041A needs to be changed to 0x93 during boot-up + { PMU_IIC_BUS, kD2238_GPIO12_CONF1, 0x00 }, // Display needs to be in reset + { PMU_IIC_BUS, kDIALOG_CHARGE_CONTROL_VSET, 0x3f }, // n27: PMU CV voltage needs to be changed from POR +}; + +static const struct core_rails_struct soc_rails[] = +{ +}; + +static const struct core_rails_struct cpu_rails[] = +{ +}; + +static const struct core_rails_struct ram_rails[] = +{ +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 0 // rely on SOCF flag only +#define TARGET_PRECHARGE_GG_FLAG_MASK kHDQRegFlagsMaskSOCF +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_FORCE_DEBUG_PRECHARGE 1 // always precharge if "debug" precharge bit set + +#define TARGET_CHARGER_HEADROOM 150 +#define TARGET_CHARGER_MAX_VRECT 7500 +#define TARGET_CHARGER_NEEDS_MAX_VRECT(rem_cap, max_cap) (((rem_cap) * 1000) <= ((max_cap) * 15)) /* 1.5% or lower */ + +#define ACC_PWR_LDO (0) // ACC_PWR not connected + +#endif diff --git a/target/m7ref/include/target/uartconfig.h b/target/m7ref/include/target/uartconfig.h new file mode 100644 index 0000000..517f4f8 --- /dev/null +++ b/target/m7ref/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (3) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/m7ref/init.c b/target/m7ref/init.c new file mode 100644 index 0000000..a344e1e --- /dev/null +++ b/target/m7ref/init.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", " debug=0x14e serial=3 amfi_unrestrict_task_for_pid=1 amfi_allow_any_signature=1 amfi_get_out_of_my_way=1 cs_enforcement_disable=1 no-dockfifo-uart=1", 0); + env_set("boot-device", "asp_nand", 0); + env_set("diags-path", "/AppleInternal/Diags/bin/diag.img4", 0); + env_set("diags-vendor-path", "/AppleInternal/Diags/bin/diag-vendor.img4", 0); +} + +#endif // WITH_ENV + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + return 0; +} + +#endif // WITH_DEVICETREE + +#if !WITH_HW_POWER + +bool power_load_memory_calibration(void *settings, uint32_t settingsSize) +{ + return true; +} +bool power_store_memory_calibration(void *settings, uint32_t settingsSize) +{ + return true; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +void power_cancel_buttonwait(void) +{ +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +bool force_usb_power = false; + +bool power_has_usb(void) +{ + return false; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +bool power_needs_precharge(void) +{ + return false; +} + +bool power_do_chargetrap(void) +{ + return false; +} + +#endif /* ! WITH_HW_POWER */ + +bool charger_has_external(int dock) +{ + // external charge not supported + return false; +} + +void charger_set_charging(int dock, uint32_t input_current_limit, uint32_t *charge_current_ma) +{ +} + diff --git a/target/m7ref/pinconfig.c b/target/m7ref/pinconfig.c new file mode 100644 index 0000000..579dd83 --- /dev/null +++ b/target/m7ref/pinconfig.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.2.1 + I/O Spreadsheet tracker: M7 GPIO Spreadsheet +*/ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_IRQ + CFG_DISABLED, // 9 : WL_HOST_WAKE -> NC_WL_HOST_WAKE + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> GPIO_BOOT_CONFIG_1 + CFG_DISABLED, // 36 : GPIO[4] -> GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 46 : GPIO[14] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> NC_AP_GPIO17 + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_IN, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_IRQ + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_SPU_TO_COMPASS_TRG + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 20 : SPU_GPIO[8] -> GPIO_OPAL_TO_SPU_INT_L + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_DISABLED, // 33 : SPU_SPI_CS_TRIG[2] -> NC_SPU_SPI_CS_TRIG2 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : SPU_SPI_CS_TRIG[7] -> SCM_SPU_TO_COMPASS_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 39 : SPU_SPI_CS_TRIG[8] -> SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_DISABLED, // 47 : SPU_GPIO[9] -> NC_GPIO_SPU_TO_OPAL_RESET_L + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + switch (gpioc) { + case 0: + return gpio_default_cfg; + case 1: + return gpio_1_default_cfg; + default: + panic("unknown gpio controller %u", gpioc); + } +} diff --git a/target/m7ref/rules.mk b/target/m7ref/rules.mk new file mode 100644 index 0000000..242965d --- /dev/null +++ b/target/m7ref/rules.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2238=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + AMC_NUM_CHANNELS=1 \ + AMC_NUM_RANKS=1 + +ifeq ($(NO_WFI),true) +OPTIONS += \ + NO_ARM_HALT=1 +endif + +ifeq ($(RECOVERY_MODE_IBSS),true) +OPTIONS += \ + WITH_RECOVERY_MODE_IBSS=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/mauiref/include/target/adbe_settings.h b/target/mauiref/include/target/adbe_settings.h new file mode 100644 index 0000000..6a7c4bd --- /dev/null +++ b/target/mauiref/include/target/adbe_settings.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_PMGR_CLK_GATE_ENABLE | DBEMODECNTL_DYN_CLK_GATE_ENABLE | DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, + + { + .name = "D620", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x030b, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + }, +}; + +#endif diff --git a/target/mauiref/include/target/aspnandconfig.h b/target/mauiref/include/target/aspnandconfig.h new file mode 100644 index 0000000..2b5ca83 --- /dev/null +++ b/target/mauiref/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/mauiref/include/target/display_gamma_tables.h b/target/mauiref/include/target/display_gamma_tables.h new file mode 100644 index 0000000..7891789 --- /dev/null +++ b/target/mauiref/include/target/display_gamma_tables.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_DISPLAY_GAMMA_TABLES_H +#define __TARGET_DISPLAY_GAMMA_TABLES_H + +#define TARGET_OS_PICTURE_SCALE (2) + +static const display_gamma_table target_display_gamma_tables[] = +{ +}; + +#endif diff --git a/target/mauiref/include/target/gpiodef.h b/target/mauiref/include/target/gpiodef.h new file mode 100644 index 0000000..582aaeb --- /dev/null +++ b/target/mauiref/include/target/gpiodef.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/*  maltese specific gpio -> pin mappings */ +/* TODO! change as actual schematic is available */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 20, 1) // 161 : ULPI_NXT +#define GPIO_BOARD_REV1 GPIO( 19, 7) // 159 : ULPI_DIR +#define GPIO_BOARD_REV2 GPIO( 21, 0) // 168 : ULPI_DATA[2] +#define GPIO_BOARD_REV3 GPIO( 20, 3) // 163 : ULPI_DATA[6] + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define BACKLIGHT_IIC_BUS (0) +#define BACKLIGHT2_IIC_BUS (1) +#define DISPLAY_PMU_IIC_BUS (0) +#define TRISTAR_IIC_BUS (0) + +/* Display reset */ +#define GPIO_LCD_RST GPIO( 9, 4) // GPIO[12] -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + + +#define GPIO_PMU_NAND_LOW_POWER_MODE (5) // PMU_TO_NAND_LOW_BATT_BOOT + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/mauiref/include/target/powerconfig.h b/target/mauiref/include/target/powerconfig.h new file mode 100644 index 0000000..74d7803 --- /dev/null +++ b/target/mauiref/include/target/powerconfig.h @@ -0,0 +1,123 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* maltese board uses antigua (D2255) dialog PMU chip */ +/* TODO! check schematic and ipdate GPIO/BUCK definitions */ + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 1 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2255_EN_CMD0, (1<<7)|(1<<2)|(1<<1)|(1<<0) }, + { PMU_IIC_BUS, kD2255_EN_CMD1, (1<<0) }, // buck8 + { PMU_IIC_BUS, kD2255_SPI_CTRL, 1 }, // enable SPI access +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// TODO! this is for N71/N66. Fix up with Maltese/Hana spreadsheet +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2255_GPIO1_CONF1, (0<<6)|(1<<3)|(0<<1)|(1<<0) }, // I.AL.NP.WS TIGRIS_TO_PMU_INT_L + { PMU_IIC_BUS, kD2255_GPIO1_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO2_CONF1, (0<<6)|(3<<3)|(1<<1)|(0<<0) }, // I.FE.PU.NW, BB_TO_PMU_PCIE_HOST_WAKE_L + { PMU_IIC_BUS, kD2255_GPIO2_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO3_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_BB_PMIC_RESET_R_L + { PMU_IIC_BUS, kD2255_GPIO3_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO4_CONF1, (0<<6)|(2<<3)|(1<<1)|(0<<0) }, // I.RE.PD.NW TRISTAR_TO_AP_INT + { PMU_IIC_BUS, kD2255_GPIO4_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO5_CONF1, (0<<6)|(0<<3)|(2<<1)|(1<<0) }, // I.AH.PD.WS STOCKHOLM_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2255_GPIO5_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO6_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_NAND_LOW_BATT_BOOT + { PMU_IIC_BUS, kD2255_GPIO6_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO7_CONF1, (0<<6)|(2<<3)|(2<<1)|(0<<0) }, // I.RE.PD.NW WLAN_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2255_GPIO7_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO8_CONF1, (0<<6)|(3<<3)|(1<<1)|(0<<0) }, // I.FE.PU.NW CODEC_TO_PMU_MIKEY_INT_L + { PMU_IIC_BUS, kD2255_GPIO8_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO9_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_BT_REG_ON + { PMU_IIC_BUS, kD2255_GPIO9_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO10_CONF1, (0<<6)|(2<<3)|(1<<1)|(0<<0) }, // I.RE.PU.NW BT_TO_PMU_HOST_WAKE + { PMU_IIC_BUS, kD2255_GPIO10_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO11_CONF1, (1<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_OD.L.NP.0 PMU_TO_WLAN_REG_ON + { PMU_IIC_BUS, kD2255_GPIO11_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO12_CONF1, (1<<6)|(2<<3)|(0<<1)|(0<<0) }, // O_OD.n.NP.0 I2C0_AP_SCL + { PMU_IIC_BUS, kD2255_GPIO12_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO13_CONF1, (1<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_OD.L.NP.0 PMU_TO_CODEC_DIGLDO_PULLDN + { PMU_IIC_BUS, kD2255_GPIO13_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO14_CONF1, (0<<6)|(3<<3)|(1<<1)|(0<<0) }, // I.FE.PU.NW CODEC_TO_AP_PMU_INT_L + { PMU_IIC_BUS, kD2255_GPIO14_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO15_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_BB_USB_VBUS_DETECT + { PMU_IIC_BUS, kD2255_GPIO15_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO16_CONF1, (3<<6)|(2<<3)|(2<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO16_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO17_CONF1, (3<<6)|(2<<3)|(2<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO17_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO18_CONF1, (2<<6)|(0<<3)|(0<<1)|(0<<0) }, // O_PP.L.NP.0 PMU_TO_ACC_SW_ON + { PMU_IIC_BUS, kD2255_GPIO18_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO19_CONF1, (3<<6)|(2<<3)|(2<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO19_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO20_CONF1, (3<<6)|(2<<3)|(2<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO20_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + { PMU_IIC_BUS, kD2255_GPIO21_CONF1, (3<<6)|(2<<3)|(2<<1)|(0<<0) }, // NC + { PMU_IIC_BUS, kD2255_GPIO21_CONF2, (1<<3)|(2<<0) }, // VBUCK3, 10ms + + // Fix Slew Rate on Buck2 + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA }, // enable test register access + { PMU_IIC_BUS, kD2255_BUCK2_FSM_TRIM6, 0 }, + { PMU_IIC_BUS, kD2255_BUCK2_FSM_TRIM7, 0 }, + { PMU_IIC_BUS, kD2255_PWRONOFF_OUT_32K_EN, 0x7 }, // OUT_32K active in ACTIVE, SLEEP1,2 + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS }, // disabled test register access + + { PMU_IIC_BUS, kD2255_OUT_32K, 0x49 }, // // OUT_32K active, VBUCK3, PP +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK5_VSEL } +}; + +// this is indexed with POWER_RAIL_*, I really just need to use the index in LDO[] +target_rails_t target_rails = { + { 0x0F, 500, 1296, 3125 }, // POWER_RAIL_CPU, BUCK0 + { 0x14, 600, 1396, 3125 }, // POWER_RAIL_VDD_FIXED BUCK5 + { 0x11, 600, 1396, 3125 }, // POWER_RAIL_SOC, BUCK2 + + { 0x16, 600, 1396, 3125 }, // POWER_RAIL_CPU_RAM, BUCK7 + { 0x17, 500, 1296, 3125 }, // POWER_RAIL_GPU, BUCK1 + { 0x17, 600, 1396, 3125 }, // POWER_RAIL_GPU_RAM, BUCK8 +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/mauiref/include/target/uartconfig.h b/target/mauiref/include/target/uartconfig.h new file mode 100644 index 0000000..6edc162 --- /dev/null +++ b/target/mauiref/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA || SUPPORT_PALLADIUM +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/mauiref/init.c b/target/mauiref/init.c new file mode 100644 index 0000000..c0a90c0 --- /dev/null +++ b/target/mauiref/init.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if WITH_HW_LM3534 +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, BACKLIGHT_IIC_BUS); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xc6); +MIB_CONSTANT(kMIBTargetBacklight1I2CBus, kOIDTypeUInt32, BACKLIGHT2_IIC_BUS); +MIB_CONSTANT(kMIBTargetBacklight1I2CAddress, kOIDTypeUInt32, 0xc6); +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 3); +#if TARGET_DISPLAY_D620 +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +static mipi_t display_panel_configurations[] = { + { + .lanes = 4, + .esc_div = 8, + .pll_n = 0x0, + .pll_m = 0x30, + .pll_p = 0x0, + .hsfreq = 0x1b, + .target_phy_settings = { 4, {{0x44, 1, {0x36}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //1200 Mhz + }, +}; +#endif +#endif +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ + power_set_gpio(GPIO_PMU_NAND_LOW_POWER_MODE, 1, 1); +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +void * target_get_display_configuration(void) +{ +#if (TARGET_DISPLAY_D620 && APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + return ((void *)(&display_panel_configurations[0])); +#else + return NULL; +#endif +} + +#if WITH_ENV +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("boot-partition", "0", 0); + env_set("boot-path", "/System/Library/Caches/com.apple.kernelcaches/kernelcache", 0); + env_set("wifiaddr", "7E:77:77:77:77:77", 0); + env_set("display-color-space","RGB888", 0); +#if TARGET_DISPLAY_D620 + env_set("display-timing", "D620", 0); + env_set("adbe-tunables", "D620", 0); + env_set("adfe-tunables", "D620", 0); +#endif +} +#endif + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); +} +#endif + +#if WITH_DEVICETREE +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *disp0_node, *backlight_node; +#endif +#if WITH_HW_MIPI_DSIM + DTNode *node; +#endif + +#if WITH_HW_DISPLAY_PINOT + // Find the DISP0 (display-subsystem 0) node + FindNode(0, "arm-io/disp0", &disp0_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, disp0_node, backlight_node); + } +#endif + +#if WITH_HW_MIPI_DSIM + // Find the mipi node + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + extern int mipi_update_device_tree(DTNode *mipi_node); + mipi_update_device_tree(node); + } +#endif + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} +#endif // WITH_DEVICETREE + +bool charger_set_usb_brick_detect(int dock, int select) +{ + return platform_set_usb_brick_detect(select); +} diff --git a/target/mauiref/pinconfig.c b/target/mauiref/pinconfig.c new file mode 100644 index 0000000..b3d6d02 --- /dev/null +++ b/target/mauiref/pinconfig.c @@ -0,0 +1,646 @@ +/* + * Copyright (C) YEAR Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v2 + I/O Spreadsheet tracker: None + Conversion command: csvtopinconfig.py --soc maui +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | SLOW_SLEW, // 0 : SWD_TMS2 -> SWD_AP_TO_NAND_SWDIO + CFG_DISABLED | SLOW_SLEW, // 1 : SWD_TMS3 -> - + CFG_DISABLED | SLOW_SLEW, // 2 : UART5_RTXD -> - + CFG_IN | SLOW_SLEW, // 3 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 4 : I2S4_BCLK -> I2S_AP_TO_CODEC_MSP_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 5 : I2S4_LRCK -> I2S_AP_TO_CODEC_MSP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 6 : I2S4_DIN -> I2S_CODEC_TO_AP_MSP_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 7 : I2S4_DOUT -> I2S_AP_TO_CODEC_MSP_DOUT + +/* Port 1 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 8 : I2S2_MCK -> I2S_AP_TO_SPEAKERAMP_MCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 9 : I2S2_BCLK -> I2S_AP_TO_CODEC_ASP_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 10 : I2S2_LRCK -> I2S_AP_TO_CODEC_ASP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 11 : I2S2_DIN -> I2S_CODEC_TO_AP_ASP_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 12 : I2S2_DOUT -> I2S_AP_TO_CODEC_ASP_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 13 : SPI1_SCLK -> SPI_AP_TO_CODEC_SCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 14 : SPI1_MOSI -> SPI_AP_TO_CODEC_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 15 : SPI1_MISO -> SPI_CODEC_TO_AP_MISO + +/* Port 2 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 16 : SPI1_SSIN -> SPI_AP_TO_CODEC_CS_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 17 : I2S0_MCK -> I2S_AP_TO_CODEC_MCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 18 : I2S0_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 19 : I2S0_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 20 : I2S0_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 21 : I2S0_DOUT -> I2S_AP_TO_CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 22 : I2C2_SDA -> I2C2_AP_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 23 : I2C2_SCL -> I2C2_AP_SCL + +/* Port 3 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 24 : UART1_TXD -> UART_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 25 : UART1_RXD -> UART_BT_TO_AP_RXD + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 26 : UART1_RTS_L -> UART_AP_TO_BT_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 27 : UART1_CTS_L -> UART_BT_TO_AP_CTS_L + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 28 : UART4_TXD -> OSCAR_UART2_RXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 29 : UART4_RXD -> OSCAR_UART2_TXD + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 30 : UART4_RTS_L -> - + CFG_DISABLED | SLOW_SLEW, // 31 : UART4_CTS_L -> - + +/* Port 4 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 32 : UART7_TXD -> OSCAR_UART0_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 33 : UART7_RXD -> OSCAR_UART0_TXD + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 34 : CLK32K_OUT -> AP_TO_TOUCH_CLK32K_RESET_L + CFG_DISABLED | SLOW_SLEW, // 35 : DP_WAKEUP -> - + CFG_DISABLED | SLOW_SLEW, // 36 : MIPICSI_MUXSEL -> - + CFG_FUNC0 | SLOW_SLEW, // 37 : ISP_I2C1_SDA -> I2C_ISP_BI_FCAM_SDA + CFG_FUNC0 | SLOW_SLEW, // 38 : ISP_I2C1_SCL -> I2C_ISP_TO_FCAM_SCL + CFG_FUNC0 | SLOW_SLEW, // 39 : ISP_I2C0_SDA -> I2C_ISP_BI_RCAM_SDA + +/* Port 5 */ + CFG_FUNC0 | SLOW_SLEW, // 40 : ISP_I2C0_SCL -> I2C_ISP_TO_RCAM_SCL + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 41 : SPI2_SCLK -> DUT_SPI2_SCLK_TOU + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : SPI2_MOSI -> DUT_SPI2_MOSI_TOU + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 43 : SPI2_MISO -> DUT_SPI2_MISO_TOU + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 44 : SPI2_SSIN -> SPI_AP_TO_TOUCH_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2C0_SDA -> I2C0_AP_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 46 : I2C0_SCL -> I2C0_AP_SCL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 47 : SENSOR0_ISTRB -> - + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 48 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 49 : SENSOR0_CLK -> AP_TO_RCAM_CLK_R + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 50 : SENSOR0_XSHUTDOWN -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 51 : SENSOR1_ISTRB -> - + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 52 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 53 : SENSOR1_CLK -> AP_TO_FCAM_CLK_R + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 54 : SENSOR1_XSHUTDOWN -> - + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 64 : GPIO[0] -> NC_AP_TO_HP_HS3_CTRL + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 65 : GPIO[1] -> NC_AP_TO_HP_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW, // 66 : GPIO[2] -> BUTTON_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 67 : GPIO[3] -> BUTTON_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 68 : GPIO[4] -> SPEAKERAMP_TO_AP_INT_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 69 : GPIO[5] -> AP_TO_SPEAKERAMP_STAYIN_ALIVE + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 70 : GPIO[6] -> AP_TO_SPEAKERAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 71 : GPIO[7] -> - + +/* Port 9 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 72 : GPIO[8] -> - + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 73 : GPIO[9] -> PCIE_AP_TO_WLAN_DEV_WAKE + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 74 : GPIO[10] -> AP_TO_LED_DRIVER_EN + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 75 : GPIO[11] -> AP_TO_TOUCH_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 76 : GPIO[12] -> AP_TO_LCM_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 77 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 78 : GPIO[14] -> AP_TO_BB_PCIE_DEV_WAKE + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 79 : GPIO[15] -> - + +/* Port 10 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 80 : GPIO[16] -> BOARD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 81 : GPIO[17] -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 82 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 83 : I2S1_MCK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 84 : I2S1_BCLK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 85 : I2S1_LRCK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 86 : I2S1_DIN -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 87 : I2S1_DOUT -> - + +/* Port 11 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 88 : UART3_TXD -> - + CFG_DISABLED | SLOW_SLEW | INPUT_SCHMITT, // 89 : UART3_RXD -> - + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 90 : UART3_RTS_L -> UART_AP_TO_STOCKHOLM_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 91 : UART3_CTS_L -> UART_STOCKHOLM_TO_AP_CTS_L + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : MENU_KEY_L -> BUTTON_MENU_KEY_L + CFG_FUNC0 | SLOW_SLEW, // 97 : HOLD_KEY_L -> BUTTON_HOLD_KEY_L + CFG_DISABLED | PULL_DOWN, // 98 : SKEY_L -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 99 : SPI3_SCLK -> SPI_AP_TO_MESA_SCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 100 : SPI3_MOSI -> SPI_AP_TO_MESA_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 101 : SPI3_MISO -> SPI_MESA_TO_AP_MISO + CFG_IN | PULL_DOWN | SLOW_SLEW, // 102 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 103 : SPI0_SCLK -> BOARD_ID0 + +/* Port 13 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 104 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 105 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 106 : SPI0_SSIN -> - + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 107 : UART0_TXD -> UART_AP_DEBUG_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 108 : UART0_RXD -> UART_AP_DEBUG_RXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 109 : UART6_TXD -> UART_AP_TO_ACCESSORY_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 110 : UART6_RXD -> UART_ACCESSORY_TO_AP_RXD + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 111 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + +/* Port 14 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 112 : TMR32_PWM1 -> AP_TO_VIBE_TRIGGER + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 113 : TMR32_PWM2 -> - + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 114 : I2C1_SDA -> I2C1_AP_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 115 : I2C1_SCL -> I2C1_AP_SCL + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 116 : GPIO[19] -> - + CFG_IN | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[20] -> LCM_TO_OWL_BSYNC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 118 : GPIO[21] -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 119 : GPIO[22] -> - + +/* Port 15 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 120 : GPIO[23] -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 121 : GPIO[24] -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 122 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 123 : GPIO[26] -> FORCE_DFU + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 124 : PMGR_MOSI -> DWI_PMGR_TO_PMU_BACKLIGHT_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 125 : PMGR_MISO -> DWI_PMU_TO_PMGR_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 126 : PMGR_SCLK0 -> DWI_PMGR_TO_PMU_SCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 127 : PMGR_SSCLK1 -> DWI_PMGR_TO_BACKLIGHT_SCLK + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : SOCHOT0 -> PMU_TO_AP_SOCHOT0_R_L + CFG_FUNC0 | SLOW_SLEW, // 129 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_R_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 130 : EDP_HPD -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 131 : I2S3_MCK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2S3_BCLK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2S3_LRCK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 134 : I2S3_DOUT -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S3_DIN -> - + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 136 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 137 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + CFG_IN | SLOW_SLEW, // 139 : GPIO[30] -> CODEC_TO_AP_PMU_INT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 140 : GPIO[31] -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + CFG_IN | PULL_UP | SLOW_SLEW, // 142 : GPIO[33] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 143 : GPIO[34] -> BOARD_REV3 + +/* Port 18 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 144 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 145 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 146 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | SLOW_SLEW, // 147 : GPIO[38] -> - + CFG_DISABLED | SLOW_SLEW, // 148 : GPIO[39] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_IN | SLOW_SLEW, // 149 : GPIO[40] -> BUTTON_RINGER_A + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 150 : GPIO[41] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 151 : GPIO[42] -> AP_TO_VIBE_EN + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | SLOW_SLEW, // 160 : PCIE_PERST0_L -> PCIE_AP_TO_NAND_RESET_L + CFG_FUNC0 | SLOW_SLEW, // 161 : PCIE_PERST1_L -> PCIE_AP_TO_WLAN_RESET_L + CFG_FUNC0 | SLOW_SLEW, // 162 : PCIE_PERST2_L -> PCIE_AP_TO_BB_RESET_L + CFG_FUNC0 | SLOW_SLEW, // 163 : PCIE_PERST3_L -> - + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 164 : PCIE_CLKREQ0_L -> PCIE_NAND_TO_AP_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 165 : PCIE_CLKREQ1_L -> PCIE_WLAN_TO_AP_CLKREQ_L + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 166 : PCIE_CLKREQ2_L -> PCIE_BB_BI_AP_CLKREQ_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 167 : PCIE_CLKREQ3_L -> - + +/* Port 21 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 192 : UART2_TXD -> - + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 193 : UART2_RXD -> - + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 194 : UART2_RTS_L -> - + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 195 : UART2_CTS_L -> - + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 196 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 197 : S3E_RESET_L -> AP_TO_NAND_RESET_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 198 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED, +}; + +static const uint32_t pinconfig_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 0 : OWL_SPI_SCLK -> SPI_OWL_TO_IMU_SCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 1 : OWL_SPI_MOSI -> SPI_OWL_TO_IMU_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 2 : OWL_SPI_MISO -> SPI_IMU_TO_OWL_MISO + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 3 : OWL_UART1_TXD -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 4 : OWL_UART1_RXD -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 5 : OWL_UART0_TXD -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 6 : OWL_UART0_RXD -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 7 : OWL_UART2_TXD -> - + +/* Port 1 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 8 : OWL_UART2_RXD -> - + CFG_FUNC0 | SLOW_SLEW, // 9 : OWL_I2CM_SDA -> TP_I2C_OWL_SDA + CFG_FUNC0 | SLOW_SLEW, // 10 : OWL_I2CM_SCL -> TP_I2C_OWL_SCL + CFG_OUT_1 | PULL_UP | SLOW_SLEW, // 11 : OWL_FUNC[0] -> SPI_OWL_TO_COMPASS_CS_L + CFG_IN | PULL_DOWN | SLOW_SLEW, // 12 : OWL_FUNC[1] -> COMPASS_TO_OWL_INT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 13 : OWL_FUNC[2] -> NC + CFG_IN | PULL_DOWN | SLOW_SLEW, // 14 : OWL_FUNC[3] -> ACCEL_GYRO_TO_OWL_INT1 + CFG_OUT_1 | PULL_UP | SLOW_SLEW, // 15 : OWL_FUNC[4] -> SPI_OWL_TO_ACCEL_GYRO_CS_L + +/* Port 2 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 16 : OWL_FUNC[5] -> ACCEL_GYRO_TO_OWL_INT2 + CFG_OUT_1 | PULL_UP | SLOW_SLEW, // 17 : OWL_FUNC[6] -> SPI_OWL_TO_PHOSPHOROUS_CS_L + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 18 : OWL_FUNC[7] -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 19 : OWL_FUNC[8] -> - + CFG_IN | PULL_DOWN | SLOW_SLEW, // 20 : OWL_FUNC[9] -> OWL_LPO_BACKUP_CLK_48M + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 21 : OWL_SWD_TCK_OUT -> SWD_AP_PERIPHERAL_SWCLK + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 22 : OWL_SWD_TMS0 -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 23 : OWL_SWD_TMS1 -> - + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 24 : OWL_I2S_MCK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 25 : OWL_I2S_BCLK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 26 : OWL_I2S_LRCK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 27 : OWL_I2S_DIN -> - + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 0 : SWD_TMS2 -> SWD_AP_TO_NAND_SWDIO + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 1 : SWD_TMS3 -> - + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 2 : UART5_RTXD -> - + CFG_IN | SLOW_SLEW, // 3 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 4 : I2S4_BCLK -> I2S_AP_TO_CODEC_MSP_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 5 : I2S4_LRCK -> I2S_AP_TO_CODEC_MSP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 6 : I2S4_DIN -> I2S_CODEC_TO_AP_MSP_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 7 : I2S4_DOUT -> I2S_AP_TO_CODEC_MSP_DOUT + +/* Port 1 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 8 : I2S2_MCK -> I2S_AP_TO_SPEAKERAMP_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 9 : I2S2_BCLK -> I2S_AP_TO_CODEC_ASP_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 10 : I2S2_LRCK -> I2S_AP_TO_CODEC_ASP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 11 : I2S2_DIN -> I2S_CODEC_TO_AP_ASP_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 12 : I2S2_DOUT -> I2S_AP_TO_CODEC_ASP_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 13 : SPI1_SCLK -> SPI_AP_TO_CODEC_SCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 14 : SPI1_MOSI -> SPI_AP_TO_CODEC_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 15 : SPI1_MISO -> SPI_CODEC_TO_AP_MISO + +/* Port 2 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 16 : SPI1_SSIN -> SPI_AP_TO_CODEC_CS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 17 : I2S0_MCK -> I2S_AP_TO_CODEC_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 18 : I2S0_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 19 : I2S0_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 20 : I2S0_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 21 : I2S0_DOUT -> I2S_AP_TO_CODEC_XSP_DOUT + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 22 : I2C2_SDA -> I2C2_AP_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 23 : I2C2_SCL -> I2C2_AP_SCL + +/* Port 3 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 24 : UART1_TXD -> UART_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 25 : UART1_RXD -> UART_BT_TO_AP_RXD + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 26 : UART1_RTS_L -> UART_AP_TO_BT_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 27 : UART1_CTS_L -> UART_BT_TO_AP_CTS_L + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 28 : UART4_TXD -> OSCAR_UART2_RXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 29 : UART4_RXD -> OSCAR_UART2_TXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 30 : UART4_RTS_L -> - + CFG_DISABLED | SLOW_SLEW, // 31 : UART4_CTS_L -> - + +/* Port 4 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 32 : UART7_TXD -> OSCAR_UART0_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 33 : UART7_RXD -> OSCAR_UART0_TXD + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 34 : CLK32K_OUT -> AP_TO_TOUCH_CLK32K_RESET_L + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 35 : DP_WAKEUP -> - + CFG_DISABLED | DRIVE_X2 | SLOW_SLEW, // 36 : MIPICSI_MUXSEL -> - + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 37 : ISP_I2C1_SDA -> I2C_ISP_BI_FCAM_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 38 : ISP_I2C1_SCL -> I2C_ISP_TO_FCAM_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 39 : ISP_I2C0_SDA -> I2C_ISP_BI_RCAM_SDA + +/* Port 5 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 40 : ISP_I2C0_SCL -> I2C_ISP_TO_RCAM_SCL + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 41 : SPI2_SCLK -> SPI_AP_TO_TOUCH_SCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : SPI2_MOSI -> SPI_AP_TO_TOUCH_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 43 : SPI2_MISO -> SPI_TOUCH_TO_AP_MISO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 44 : SPI2_SSIN -> SPI_AP_TO_TOUCH_CS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 45 : I2C0_SDA -> I2C0_AP_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 46 : I2C0_SCL -> I2C0_AP_SCL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 47 : SENSOR0_ISTRB -> - + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 48 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 49 : SENSOR0_CLK -> AP_TO_RCAM_CLK_R + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 50 : SENSOR0_XSHUTDOWN -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 51 : SENSOR1_ISTRB -> - + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 52 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 53 : SENSOR1_CLK -> AP_TO_FCAM_CLK_R + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 54 : SENSOR1_XSHUTDOWN -> - + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 64 : GPIO[0] -> NC_AP_TO_HP_HS3_CTRL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 65 : GPIO[1] -> NC_AP_TO_HP_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW, // 66 : GPIO[2] -> BUTTON_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 67 : GPIO[3] -> BUTTON_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 68 : GPIO[4] -> SPEAKERAMP_TO_AP_INT_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 69 : GPIO[5] -> AP_TO_SPEAKERAMP_STAYIN_ALIVE + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 70 : GPIO[6] -> AP_TO_SPEAKERAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 71 : GPIO[7] -> - + +/* Port 9 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 72 : GPIO[8] -> - + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 73 : GPIO[9] -> PCIE_AP_TO_WLAN_DEV_WAKE + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 74 : GPIO[10] -> AP_TO_LED_DRIVER_EN + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[11] -> AP_TO_TOUCH_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 76 : GPIO[12] -> AP_TO_LCM_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 77 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 78 : GPIO[14] -> AP_TO_BB_PCIE_DEV_WAKE + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 79 : GPIO[15] -> - + +/* Port 10 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 80 : GPIO[16] -> BOARD_ID3 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 81 : GPIO[17] -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 82 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : I2S1_MCK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 84 : I2S1_BCLK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 85 : I2S1_LRCK -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 86 : I2S1_DIN -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2S1_DOUT -> - + +/* Port 11 */ + CFG_DISABLED | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 88 : UART3_TXD -> - + CFG_DISABLED | SLOW_SLEW | INPUT_SCHMITT, // 89 : UART3_RXD -> - + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 90 : UART3_RTS_L -> UART_AP_TO_STOCKHOLM_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 91 : UART3_CTS_L -> UART_STOCKHOLM_TO_AP_CTS_L + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW, // 96 : MENU_KEY_L -> BUTTON_MENU_KEY_L + CFG_FUNC0 | SLOW_SLEW, // 97 : HOLD_KEY_L -> BUTTON_HOLD_KEY_L + CFG_DISABLED | PULL_DOWN | DRIVE_X2, // 98 : SKEY_L -> - + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 99 : SPI3_SCLK -> SPI_AP_TO_MESA_SCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 100 : SPI3_MOSI -> SPI_AP_TO_MESA_MOSI + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 101 : SPI3_MISO -> SPI_MESA_TO_AP_MISO + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 102 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 103 : SPI0_SCLK -> BOARD_ID0 + +/* Port 13 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 104 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 105 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 106 : SPI0_SSIN -> - + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 107 : UART0_TXD -> UART_AP_DEBUG_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 108 : UART0_RXD -> UART_AP_DEBUG_RXD + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 109 : UART6_TXD -> UART_AP_TO_ACCESSORY_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 110 : UART6_RXD -> UART_ACCESSORY_TO_AP_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 111 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + +/* Port 14 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 112 : TMR32_PWM1 -> AP_TO_VIBE_TRIGGER + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 113 : TMR32_PWM2 -> - + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 114 : I2C1_SDA -> I2C1_AP_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 115 : I2C1_SCL -> I2C1_AP_SCL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 116 : GPIO[19] -> - + CFG_IN | PULL_DOWN | SLOW_SLEW, // 117 : GPIO[20] -> LCM_TO_OWL_BSYNC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 118 : GPIO[21] -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 119 : GPIO[22] -> - + +/* Port 15 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 120 : GPIO[23] -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 121 : GPIO[24] -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 122 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 123 : GPIO[26] -> FORCE_DFU + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 124 : PMGR_MOSI -> DWI_PMGR_TO_PMU_BACKLIGHT_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 125 : PMGR_MISO -> DWI_PMU_TO_PMGR_MISO + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 126 : PMGR_SCLK0 -> DWI_PMGR_TO_PMU_SCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 127 : PMGR_SSCLK1 -> DWI_PMGR_TO_BACKLIGHT_SCLK + +/* Port 16 */ + CFG_FUNC0 | SLOW_SLEW, // 128 : SOCHOT0 -> PMU_TO_AP_SOCHOT0_R_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 129 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_R_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 130 : EDP_HPD -> - + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 131 : I2S3_MCK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 132 : I2S3_BCLK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 133 : I2S3_LRCK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 134 : I2S3_DOUT -> - + CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S3_DIN -> - + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 136 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 137 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + CFG_IN | SLOW_SLEW, // 139 : GPIO[30] -> CODEC_TO_AP_PMU_INT_L + CFG_DISABLED | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 140 : GPIO[31] -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + CFG_IN | PULL_UP | SLOW_SLEW, // 142 : GPIO[33] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 143 : GPIO[34] -> BOARD_REV3 + +/* Port 18 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 144 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 145 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 146 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | SLOW_SLEW, // 147 : GPIO[38] -> - + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 148 : GPIO[39] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_IN | SLOW_SLEW, // 149 : GPIO[40] -> BUTTON_RINGER_A + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 150 : GPIO[41] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 151 : GPIO[42] -> AP_TO_VIBE_EN + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 160 : PCIE_PERST0_L -> PCIE_AP_TO_NAND_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 161 : PCIE_PERST1_L -> PCIE_AP_TO_WLAN_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 162 : PCIE_PERST2_L -> PCIE_AP_TO_BB_RESET_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 163 : PCIE_PERST3_L -> - + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 164 : PCIE_CLKREQ0_L -> PCIE_NAND_TO_AP_CLKREQ_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 165 : PCIE_CLKREQ1_L -> PCIE_WLAN_TO_AP_CLKREQ_L + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 166 : PCIE_CLKREQ2_L -> PCIE_BB_BI_AP_CLKREQ_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 167 : PCIE_CLKREQ3_L -> - + +/* Port 21 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 192 : UART2_TXD -> - + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 193 : UART2_RXD -> - + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 194 : UART2_RTS_L -> - + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 195 : UART2_CTS_L -> - + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 196 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 197 : S3E_RESET_L -> AP_TO_NAND_RESET_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 198 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 0 : OWL_SPI_SCLK -> SPI_OWL_TO_IMU_SCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 1 : OWL_SPI_MOSI -> SPI_OWL_TO_IMU_MOSI + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 2 : OWL_SPI_MISO -> SPI_IMU_TO_OWL_MISO + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 3 : OWL_UART1_TXD -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 4 : OWL_UART1_RXD -> - + CFG_DISABLED | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 5 : OWL_UART0_TXD -> - + CFG_DISABLED | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 6 : OWL_UART0_RXD -> - + CFG_DISABLED | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 7 : OWL_UART2_TXD -> - + +/* Port 1 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 8 : OWL_UART2_RXD -> - + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 9 : OWL_I2CM_SDA -> TP_I2C_OWL_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 10 : OWL_I2CM_SCL -> TP_I2C_OWL_SCL + CFG_OUT_1 | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 11 : OWL_FUNC[0] -> SPI_OWL_TO_COMPASS_CS_L + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 12 : OWL_FUNC[1] -> COMPASS_TO_OWL_INT + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 13 : OWL_FUNC[2] -> NC + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 14 : OWL_FUNC[3] -> ACCEL_GYRO_TO_OWL_INT1 + CFG_OUT_1 | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 15 : OWL_FUNC[4] -> SPI_OWL_TO_ACCEL_GYRO_CS_L + +/* Port 2 */ + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 16 : OWL_FUNC[5] -> ACCEL_GYRO_TO_OWL_INT2 + CFG_OUT_1 | PULL_UP | DRIVE_X2 | SLOW_SLEW, // 17 : OWL_FUNC[6] -> SPI_OWL_TO_PHOSPHOROUS_CS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 18 : OWL_FUNC[7] -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 19 : OWL_FUNC[8] -> - + CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 20 : OWL_FUNC[9] -> OWL_LPO_BACKUP_CLK_48M + CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 21 : OWL_SWD_TCK_OUT -> SWD_AP_PERIPHERAL_SWCLK + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 22 : OWL_SWD_TMS0 -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 23 : OWL_SWD_TMS1 -> - + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 24 : OWL_I2S_MCK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 25 : OWL_I2S_BCLK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 26 : OWL_I2S_LRCK -> - + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 27 : OWL_I2S_DIN -> - + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0, pinconfig_ap_1 } }, + { 1, 1, { pinconfig_dev_0, pinconfig_dev_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/mauiref/rules.mk b/target/mauiref/rules.mk new file mode 100644 index 0000000..3b6968a --- /dev/null +++ b/target/mauiref/rules.mk @@ -0,0 +1,44 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2255=1 \ + TARGET_CHESTNUT_USE_LOW_RIPPLE_MODE=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_PLL_VCO_CAP=0 \ + TARGET_VCO_RANGE=2 \ + TARGET_LPF_CTRL=8 \ + TARGET_ICP_CTR=15 \ + TARGET_HS_2_LP_DATA_TIME=35 \ + TARGET_LP_2_HS_DATA_TIME=60 \ + TARGET_HS_2_LP_CLOCK_TIME=67 \ + TARGET_LP_2_HS_CLOCK_TIME=159 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_IPHONE_TUNABLES=1 \ + DCS_NUM_RANKS=1 \ + DCS_NUM_CHANNELS=4 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi2/multi-touch\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/n102/include/target/adbe_settings.h b/target/n102/include/target/adbe_settings.h new file mode 100644 index 0000000..9f1b4b6 --- /dev/null +++ b/target/n102/include/target/adbe_settings.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = +{ + { + .name = "D410", + .adbe0_vblank_clk_gate_wakeup = 364, + .adbe0_vblank_pos_vbi_pulse = 364, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/n102/include/target/aspnandconfig.h b/target/n102/include/target/aspnandconfig.h new file mode 100644 index 0000000..80dd0ed --- /dev/null +++ b/target/n102/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/n102/include/target/gpiodef.h b/target/n102/include/target/gpiodef.h new file mode 100644 index 0000000..65811f0 --- /dev/null +++ b/target/n102/include/target/gpiodef.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iphone7,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 9, 2) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO( 9, 1) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO( 9, 0) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO( 8, 7) // 71 : GPIO[37] + +/* Miscellaneous Pins */ + +/* Display reset */ +#define GPIO_LCD_RST GPIO( 0, 1) // 1 : ULPI_STP -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + +/* D2186 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(13, 3) // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + +/* which IICs to initialize */ +#define IICS_MASK (3) + +#define TRISTAR_IIC_BUS (0) +#define DISPLAY_PMU_IIC_BUS (0) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/n102/include/target/powerconfig.h b/target/n102/include/target/powerconfig.h new file mode 100644 index 0000000..9fbbfa7 --- /dev/null +++ b/target/n102/include/target/powerconfig.h @@ -0,0 +1,110 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2186_ACTIVE4, 0x04 }, // enable LDO10 + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x17 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1 + { PMU_IIC_BUS, kD2186_ACTIVE3, 0x3E }, // enable LDO4 along with LDO{1,2,3,5} + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x37 }, // enable BUCK4_SW2 N56 and N61: PP1V2_Oscar and PP1V8_Oscar brought up in wrong order during iBoot + { PMU_IIC_BUS, kD2186_HIBERNATE3, 0x18 }, // enable LDO3+LDO4 in hibernate + { PMU_IIC_BUS, kD2186_OUT_32K, 0x49 }, // enable OUT32 clock +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// Settings as of N102 | IOSpreadsheet, version 0v4 +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2186_GPIO1_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO1_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO2_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO2_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO3_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO3_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO4_CONF1, 0x83 }, // TRISTAR_TO_AP_INT In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO4_CONF2, 0x72 }, // TRISTAR_TO_AP_INT POR + { PMU_IIC_BUS, kD2186_GPIO5_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO5_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO6_CONF1, 0x01 }, // PMU_TO_OSCAR_RESET_CLK_32K_L Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO6_CONF2, 0x12 }, // PMU_TO_OSCAR_RESET_CLK_32K_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO7_CONF1, 0x83 }, // WLAN_TO_PMU_HOST_WAKE In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO7_CONF2, 0x72 }, // WLAN_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO8_CONF1, 0xA2 }, // CODEC_TO_PMU_MIKEY_INT_L In, Any Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO8_CONF2, 0x12 }, // CODEC_TO_PMU_MIKEY_INT_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO9_CONF1, 0x01 }, // PMU_TO_BT_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO9_CONF2, 0x12 }, // PMU_TO_BT_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO10_CONF1, 0x92 }, // BT_TO_PMU_HOST_WAKE In, R Edge, Wake, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO10_CONF2, 0x72 }, // BT_TO_PMU_HOST_WAKE Disabled + { PMU_IIC_BUS, kD2186_GPIO11_CONF1, 0x01 }, // PMU_TO_WLAN_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO11_CONF2, 0x12 }, // PMU_TO_WLAN_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO12_CONF1, 0x08 }, // AP_TO_I2C0_SCL Out, nReset, PU + { PMU_IIC_BUS, kD2186_GPIO12_CONF2, 0x72 }, // AP_TO_I2C0_SCL POR + { PMU_IIC_BUS, kD2186_GPIO13_CONF1, 0x83 }, // OSCAR_TO_PMU_HOST_WAKE In, In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO13_CONF2, 0x72 }, // OSCAR_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO14_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO14_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO15_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO15_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO16_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO16_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO17_CONF1, 0x88 }, // WLAN_TO_PMU_PCIE_WAKE_L In, L Low, PU + { PMU_IIC_BUS, kD2186_GPIO17_CONF2, 0x72 }, // WLAN_TO_PMU_PCIE_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO18_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO18_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO19_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO19_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO20_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO20_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO21_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO21_CONF2, 0x72 }, // POR + +// TODO: configure debounce for WAS kD2045_GPIO_DEB2,kD2045_GPIO_DEB5,kD2045_GPIO_DEB6? + + { PMU_IIC_BUS, kD2186_BUCK_DWI_CTRL0, 0x07 }, // enable DWI for BUCK0, BUCK1, BUCK2 + { PMU_IIC_BUS, kD2186_SYS_CTRL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + +// TODO: verify + { PMU_IIC_BUS, kD2186_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/n102/include/target/uartconfig.h b/target/n102/include/target/uartconfig.h new file mode 100644 index 0000000..e98787b --- /dev/null +++ b/target/n102/include/target/uartconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +/* only enable those UARTs required by iBoot - namely debug serial port */ +#define UARTS_MASK (0x01) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/n102/init.c b/target/n102/init.c new file mode 100644 index 0000000..dd267fa --- /dev/null +++ b/target/n102/init.c @@ -0,0 +1,512 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif + +#define N102_AP_BOARD_ID (0x10) // AP board ID +#define N102_DEV_BOARD_ID (0x11) // DEV board ID + +#define N102_DEV_BOARD_REV (0xF) + +// Combined Board Id/Board Revision +// IMPORTANT: IF YOU CHANGE THE ORDER OF THESE ENUMERATORS YOU MUST CHECK +// FOR ANY > or < RELATIONSHIPS THAT MAY NEED TO ALSO CHANGE. +typedef enum { + BOARD_TYPE_UNKNOWN = 0, + BOARD_TYPE_N102 = 1 +} board_type; + +static uint32_t n102_get_board_rev(void); +static board_type n102_get_board_type(void); + +static uint32_t gpio_board_rev; +static bool gpio_board_rev_valid; + +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +static mipi_t display_panel_configurations[] = { + { + .lanes = 4, + .esc_div = 4, + .pll_n = 0, + .pll_m = 0, + .pll_p = 0, + .hsfreq = 0, + .target_phy_settings = { 9, {{0x44, 1, {0xE}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0xA8}}, {0x42, 1, {0x80}}, {0x52, 1, {0x80}}, {0x82, 1, {0x80}}, {0x92, 1, {0x80}}, {0x52, 1, {0x80}}}}, //513 Mhz + }, +}; +#endif + +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xC6); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static uint32_t n102_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +static board_type n102_get_board_type(void) +{ + static board_type board_type = BOARD_TYPE_UNKNOWN; + + if (board_type != BOARD_TYPE_UNKNOWN) { + dprintf(DEBUG_INFO, "%s: board type: %d\n", __func__, board_type); + return (board_type); + } + + uint32_t board_id = platform_get_board_id(); + uint32_t board_rev = n102_get_board_rev(); + + dprintf(DEBUG_INFO, "%s: board id: %d, rev: %d\n", + __func__, board_id, board_rev); + + switch (board_id) { + case N102_AP_BOARD_ID: + case N102_DEV_BOARD_ID: + return (BOARD_TYPE_N102); + + default: + break; + } + + panic("Unknown/unsupported board id/rev combination: 0x%x/0x%x", + board_id, board_rev); + + return (BOARD_TYPE_UNKNOWN); +} + +static void show_pmu_ver(void) +{ +} + +void target_early_init(void) +{ + uint32_t target_mipi_p, target_mipi_m, target_mipi_s; + + // Temporary workaround to set MIPI P/M/S values for display + // D403 (@ 513 MHz) until rdar://problem/17985178 is fixed. + target_mipi_p = 4; + target_mipi_m = 171; + target_mipi_s = 1; + + clock_set_frequency(CLK_MIPI, 0, target_mipi_p, + target_mipi_m, target_mipi_s, 0); + +#if PRODUCT_LLB || PRODUCT_IBSS + dprintf(DEBUG_INFO, "%s: chip rev: %d, fuse: %d\n", __func__, + chipid_get_chip_revision(), chipid_get_fuse_revision()); + +#if WITH_HW_POWER + int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); + + int rc; + uint8_t val; + + if ((rc = pmu_get_data(0, 0x1, &val)) < 0) { // read PMU.OTP version + dprintf(DEBUG_CRITICAL, "PMU: cannot read OTP Version (%d)\n", rc); + } else { + dprintf(DEBUG_INFO, "%s: PMU OTP ver: %x\n", __func__, val); + } +#endif +#endif +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); + +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); +} + +void target_poweroff(void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); +} + + +int target_bootprep(enum boot_target target) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) + *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); + + dprintf(DEBUG_INFO, "%s ...\n", __func__); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + return ((void *)(&display_panel_configurations[0])); +#else + return NULL; +#endif +} + +#if WITH_ENV +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + + env_set("display-timing", "D410", 0); + env_set("adbe-tunables", "D410",0); + env_set("adfe-tunables", "D410", 0); +} +#endif + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ + dprintf(DEBUG_INFO, "%s ...\n", __func__); + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); +} +#endif + +#if WITH_HW_LM3534 +uint8_t target_lm3534_gpr(uint32_t ctlr) +{ + // DISPLAY_PANEL_TYPE_D410 + // default ovp_select setting is 0 (corresponds to 16V OVP) + // (ramp disable) | (chip enable) + return ((1 << 1) | (1 << 0)); +} +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *disp0_node, *backlight_node; +#endif + board_type board = n102_get_board_type(); + DTNode *node; + uint32_t propSize; + char *propName, *propStr; + void *propData; + //const char *nodeName; + + dprintf(DEBUG_INFO, "%s ...\n", __func__); + +#if WITH_HW_DISPLAY_PINOT + // Find the DISP0 (display-subsystem 0) node + FindNode(0, "arm-io/disp0", &disp0_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, + DTNode *clcd_node, + DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, disp0_node, backlight_node); + } +#endif + +#if WITH_HW_MIPI_DSIM + // Find the mipi node + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + extern int mipi_update_device_tree(DTNode *mipi_node); + mipi_update_device_tree(node); + } +#endif + + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propStr = NULL; + switch (board) { + case BOARD_TYPE_N102: + propStr = "multi-touch,n102"; + dprintf(DEBUG_INFO, "%s: multi-touch,n102\n", __func__); + break; + + default: + panic("Unknown display for board type: %d", board); + break; + } + } + } + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = + (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + // Update the codec and speaker nodes with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + propName = "at-scale-fmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[8], sizeof(uint32_t)); + } + propName = "at-scale-rcvr"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[12], sizeof(uint32_t)); + } + } + // Update speaker + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[16], sizeof(uint32_t)); + } + } + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + + // Remove the properties for the second backlight controller + propName = "dual-backlight-controllers"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-backlight_enable1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart8/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + propName = "gyro-trim-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GTCl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart8/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('PxCl', propData, propSize); + } + + // Update cover glass type + if (FindNode(0, "product", &node)) { + propName = "cover-glass"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CGSp', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CBAT', propData, propSize); + if ( ((uint32_t*)propData)[2]==0x1 ) ((uint32_t*)propData)[2]=0x0; // compat + } + } + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries +// (enclosure/cover glass): +// gray/black: setenv DClr_override 00020000B9B5B4003C3B3B0000000000 +// gold/white: setenv DClr_override 00020000B5CCE100E3E4E10000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + {RGB(59, 59, 60), false}, // Black - black background, white logo + {RGB(225, 228, 227), true}, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, + color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + + fail: + return NULL; +} +#endif // WITH_PAINT diff --git a/target/n102/pinconfig.c b/target/n102/pinconfig.c new file mode 100644 index 0000000..6fc786f --- /dev/null +++ b/target/n102/pinconfig.c @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v8 + I/O Spreadsheet tracker: 18673410 + Conversion command: csvtopinconfig.py --soc fiji --radar 18673410 --copyright 2014 +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 0 : ULPI_DIR -> LCM_TO_AP_HIFA_BSYNC + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 1 : ULPI_STP -> AP_TO_LCM_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 2 : ULPI_NXT -> AP_TO_TOUCH_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 3 : ULPI_DATA[7] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + CFG_IN | PULL_DOWN | SLOW_SLEW, // 7 : ULPI_CLK -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 1 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 8 : ULPI_DATA[3] -> AP_TO_LEDDRV_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 10 : ULPI_DATA[1] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 11 : ULPI_DATA[0] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 12 : SPI1_SCLK -> AP_TO_CODEC_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_MOSI -> AP_TO_CODEC_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 14 : SPI1_MISO -> CODEC_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 15 : SPI1_SSIN -> AP_TO_CODEC_SPI_CS_L + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> MENU_KEY_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> HOLD_KEY_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 34 : I2S3_MCK -> NC + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> NC + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 37 : I2S3_DOUT -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 39 : CLK32K_OUT -> 45_AP_TO_TOUCH_CLK32K_RESET_L + +/* Port 5 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> WLAN_TO_AP_PCIE1_CLKREQ_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 43 : GPIO[0] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 44 : GPIO[1] -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 45 : GPIO[2] -> VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 46 : GPIO[3] -> VOL_DWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 47 : GPIO[4] -> SPKAMP_TO_AP_INT_L + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 48 : GPIO[5] -> AP_TO_SPKAMP_BEE_GEES + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 49 : GPIO[6] -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_BT_WAKE + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 51 : GPIO[14] -> NC + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 52 : GPIO[16] -> BOARD_ID3 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 53 : GPIO[17] -> NC + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 54 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : GPIO[20] -> NC + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 56 : GPIO[21] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 57 : UART5_RTXD -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 58 : UART8_TXD -> AP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> OSCAR_TO_AP_UART_RXD + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 60 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 61 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 62 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 63 : SPI0_SSIN -> NC + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> AP_TO_I2C2_SCL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 66 : GPIO[22] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 67 : GPIO[23] -> NC + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 76 : GPIO[42] -> NC + CFG_IN | SLOW_SLEW, // 77 : GPIO[43] -> AP_TO_WLAN_PCIE1_RST_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 78 : DISP_VSYNC -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 79 : UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 81 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 82 : TMR32_PWM1 -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 84 : UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 85 : UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 86 : I2C3_SDA -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2C3_SCL -> NC + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> AP_TO_I2C0_SCL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 98 : GPIO[38] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 99 : UART2_TXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 100 : UART2_RXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 101 : UART2_RTSN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 102 : UART2_CTSN -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 103 : DWI_DO -> 45_AP_TO_PMU_AND_BL_DWI_DO + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 104 : DWI_CLK -> 45_AP_TO_PMU_AND_BL_DWI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 105 : WDOG -> AP_TO_PMU_RESET_IN + CFG_IN | PULL_UP | SLOW_SLEW, // 106 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 108 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 109 : GPIO[27] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_TO_AP_PRE_UVLO_L_R + CFG_FUNC0 | SLOW_SLEW, // 111 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L_R + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 114 : GPIO[8] -> NC + CFG_DISABLED | SLOW_SLEW, // 115 : GPIO[9] -> AP_TO_WLAN_JTAG_SWCLK + CFG_DISABLED | SLOW_SLEW, // 116 : GPIO[10] -> AP_TO_WLAN_JTAG_SWDIO + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 117 : GPIO[15] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 118 : UART4_TXD -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> WLAN_TO_AP_UART4_RXD + +/* Port 15 */ + CFG_OUT_1 | PULL_DOWN | SLOW_SLEW, // 120 : UART4_RTSN -> AP_TO_WLAN_UART4_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> WLAN_TO_AP_UART4_CTS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 122 : SPI3_MOSI -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 123 : SPI3_MISO -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 124 : SPI3_SCLK -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 125 : SPI3_SSIN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 126 : GPIO[24] -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 127 : GPIO[30] -> CODEC_TO_AP_INT_L + +/* Port 16 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 128 : GPIO[31] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 129 : GPIO[32] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 130 : GPIO[33] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 131 : GPIO[40] -> NC + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 132 : GPIO[41] -> AP_TO_TP_DIAGS_CTRL + CFG_IN | SLOW_SLEW, // 133 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2S4_LRCK -> AP_TO_CODEC_XSP_I2S4_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S4_BCLK -> 45_AP_TO_CODEC_XSP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_TO_CODEC_XSP_I2S4_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 137 : I2S4_DIN -> CODEC_TO_AP_XSP_I2S4_DIN + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 138 : I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 139 : I2C1_SCL -> AP_TO_I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 160 : I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 161 : I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 163 : I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2S1_LRCK -> AP_TO_BT_I2S1_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 166 : I2S1_BCLK -> 45_AP_TO_BT_I2S1_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TO_BT_I2S1_DOUT + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 168 : I2S1_DIN -> BT_TO_AP_I2S1_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 169 : I2S2_LRCK -> AP_TO_SPKAMP_I2S2_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 170 : I2S2_BCLK -> 45_AP_TO_SPKAMP_I2S2_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TO_SPKAMP_I2S2_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 172 : I2S2_DIN -> SPKAMP_TO_AP_I2S2_DIN + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 173 : UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1 | PULL_DOWN | SLOW_SLEW, // 175 : UART1_RTSN -> AP_TO_BT_UART1_RTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 176 : UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 177 : EDP_HPD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 178 : UART3_TXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 179 : UART3_RXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 180 : UART3_RTSN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 181 : UART3_CTSN -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 182 : SPI2_SCLK -> AP_TO_TOUCH_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 183 : SPI2_MOSI -> AP_TO_TOUCH_SPI_MOSI + +/* Port 23 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 184 : SPI2_MISO -> TOUCH_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 185 : SPI2_SSIN -> AP_TO_TOUCH_SPI_CS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 186 : ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 187 : ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 188 : ISP1_SDA -> AP_BI_FCAM_I2C_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 189 : ISP1_SCL -> AP_TO_FCAM_I2C_SCL + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 190 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 191 : SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + +/* Port 24 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 194 : ISP_UART0_TXD -> AP_ISP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 195 : ISP_UART0_RXD -> OSCAR_TO_AP_ISP_UART_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 196 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 197 : SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 200 : UART7_TXD -> AP_TO_WLAN_DEVICE_WAKE + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 201 : UART7_RXD -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 202 : I2S0_MCK -> 45_AP_TO_CODEC_I2S0_MCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 203 : I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 0 : ULPI_DIR -> LCM_TO_AP_HIFA_BSYNC + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 1 : ULPI_STP -> AP_TO_LCM_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 2 : ULPI_NXT -> AP_TO_TOUCH_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 3 : ULPI_DATA[7] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + CFG_IN | PULL_DOWN | SLOW_SLEW, // 7 : ULPI_CLK -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 1 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 8 : ULPI_DATA[3] -> AP_TO_LEDDRV_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 10 : ULPI_DATA[1] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 11 : ULPI_DATA[0] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 12 : SPI1_SCLK -> AP_TO_CODEC_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_MOSI -> AP_TO_CODEC_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 14 : SPI1_MISO -> CODEC_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 15 : SPI1_SSIN -> AP_TO_CODEC_SPI_CS_L + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> MENU_KEY_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> HOLD_KEY_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 34 : I2S3_MCK -> NC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> NC + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 37 : I2S3_DOUT -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 39 : CLK32K_OUT -> 45_AP_TO_TOUCH_CLK32K_RESET_L + +/* Port 5 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 41 : PCIE_CLKREQ1_N -> WLAN_TO_AP_PCIE1_CLKREQ_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 43 : GPIO[0] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 44 : GPIO[1] -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 45 : GPIO[2] -> VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 46 : GPIO[3] -> VOL_DWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 47 : GPIO[4] -> SPKAMP_TO_AP_INT_L + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 48 : GPIO[5] -> AP_TO_SPKAMP_BEE_GEES + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 49 : GPIO[6] -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_BT_WAKE + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 51 : GPIO[14] -> NC + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 52 : GPIO[16] -> BOARD_ID3 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 53 : GPIO[17] -> NC + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 54 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : GPIO[20] -> NC + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 56 : GPIO[21] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 57 : UART5_RTXD -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 58 : UART8_TXD -> AP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> OSCAR_TO_AP_UART_RXD + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 60 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 61 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 62 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 63 : SPI0_SSIN -> NC + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> AP_TO_I2C2_SCL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 66 : GPIO[22] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 67 : GPIO[23] -> NC + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> BOOT_CONFIG2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 76 : GPIO[42] -> NC + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 77 : GPIO[43] -> AP_TO_WLAN_PCIE1_RST_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 78 : DISP_VSYNC -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 79 : UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 81 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 82 : TMR32_PWM1 -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 84 : UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 85 : UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 86 : I2C3_SDA -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2C3_SCL -> NC + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> AP_TO_I2C0_SCL + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 98 : GPIO[38] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 99 : UART2_TXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 100 : UART2_RXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 101 : UART2_RTSN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 102 : UART2_CTSN -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 103 : DWI_DO -> 45_AP_TO_PMU_AND_BL_DWI_DO + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 104 : DWI_CLK -> 45_AP_TO_PMU_AND_BL_DWI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 105 : WDOG -> AP_TO_PMU_RESET_IN + CFG_IN | PULL_UP | SLOW_SLEW, // 106 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 108 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 109 : GPIO[27] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_TO_AP_PRE_UVLO_L_R + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 111 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L_R + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 114 : GPIO[8] -> NC + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 115 : GPIO[9] -> AP_TO_WLAN_JTAG_SWCLK + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 116 : GPIO[10] -> AP_TO_WLAN_JTAG_SWDIO + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 117 : GPIO[15] -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 118 : UART4_TXD -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> WLAN_TO_AP_UART4_RXD + +/* Port 15 */ + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 120 : UART4_RTSN -> AP_TO_WLAN_UART4_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> WLAN_TO_AP_UART4_CTS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 122 : SPI3_MOSI -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 123 : SPI3_MISO -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 124 : SPI3_SCLK -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 125 : SPI3_SSIN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 126 : GPIO[24] -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 127 : GPIO[30] -> CODEC_TO_AP_INT_L + +/* Port 16 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 128 : GPIO[31] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 129 : GPIO[32] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 130 : GPIO[33] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 131 : GPIO[40] -> NC + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 132 : GPIO[41] -> AP_TO_TP_DIAGS_CTRL + CFG_IN | SLOW_SLEW, // 133 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2S4_LRCK -> AP_TO_CODEC_XSP_I2S4_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S4_BCLK -> 45_AP_TO_CODEC_XSP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_TO_CODEC_XSP_I2S4_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 137 : I2S4_DIN -> CODEC_TO_AP_XSP_I2S4_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 138 : I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 139 : I2C1_SCL -> AP_TO_I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 160 : I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 161 : I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 163 : I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2S1_LRCK -> AP_TO_BT_I2S1_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 166 : I2S1_BCLK -> 45_AP_TO_BT_I2S1_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TO_BT_I2S1_DOUT + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 168 : I2S1_DIN -> BT_TO_AP_I2S1_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 169 : I2S2_LRCK -> AP_TO_SPKAMP_I2S2_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 170 : I2S2_BCLK -> 45_AP_TO_SPKAMP_I2S2_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TO_SPKAMP_I2S2_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 172 : I2S2_DIN -> SPKAMP_TO_AP_I2S2_DIN + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 173 : UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 175 : UART1_RTSN -> AP_TO_BT_UART1_RTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 176 : UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 177 : EDP_HPD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 178 : UART3_TXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 179 : UART3_RXD -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 180 : UART3_RTSN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 181 : UART3_CTSN -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 182 : SPI2_SCLK -> AP_TO_TOUCH_SPI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 183 : SPI2_MOSI -> AP_TO_TOUCH_SPI_MOSI + +/* Port 23 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 184 : SPI2_MISO -> TOUCH_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 185 : SPI2_SSIN -> AP_TO_TOUCH_SPI_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 186 : ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 187 : ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 188 : ISP1_SDA -> AP_BI_FCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 189 : ISP1_SCL -> AP_TO_FCAM_I2C_SCL + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 190 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + +/* Port 24 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 194 : ISP_UART0_TXD -> AP_ISP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 195 : ISP_UART0_RXD -> OSCAR_TO_AP_ISP_UART_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 196 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 200 : UART7_TXD -> AP_TO_WLAN_DEVICE_WAKE + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 201 : UART7_RXD -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 202 : I2S0_MCK -> 45_AP_TO_CODEC_I2S0_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 203 : I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0 } }, + { 1, 1, { pinconfig_dev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/n102/rules.mk b/target/n102/rules.mk new file mode 100644 index 0000000..3ad572f --- /dev/null +++ b/target/n102/rules.mk @@ -0,0 +1,41 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2186=1 \ + TARGET_CHESTNUT_USE_LOW_RIPPLE_MODE=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_IPHONE_TUNABLES=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi2/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart4/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + WITH_HW_MIPI=1 \ + TARGET_HS_2_LP_DATA_TIME=24 \ + TARGET_LP_2_HS_DATA_TIME=63 \ + TARGET_HS_2_LP_CLOCK_TIME=36 \ + TARGET_LP_2_HS_CLOCK_TIME=79 \ + TARGET_DDR_792M=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o $(LOCAL_DIR)/pinconfig.o diff --git a/target/n59/include/target/adbe_settings.h b/target/n59/include/target/adbe_settings.h new file mode 100644 index 0000000..167db08 --- /dev/null +++ b/target/n59/include/target/adbe_settings.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = +{ + { + .name = "D410", + .adbe0_vblank_clk_gate_wakeup = 364, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/n59/include/target/aspnandconfig.h b/target/n59/include/target/aspnandconfig.h new file mode 100644 index 0000000..2b5ca83 --- /dev/null +++ b/target/n59/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/n59/include/target/gpiodef.h b/target/n59/include/target/gpiodef.h new file mode 100644 index 0000000..1492904 --- /dev/null +++ b/target/n59/include/target/gpiodef.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iphone7,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 9, 2) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO( 9, 1) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO( 9, 0) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO( 8, 7) // 71 : GPIO[37] + +/* Miscellaneous Pins */ + +/* Display reset */ +#define GPIO_LCD_RST GPIO( 0, 1) // 1 : ULPI_STP -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + +/* Ringer Switch */ +#define GPIO_RINGER_AB GPIO(16, 3) // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + +/* D2186 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(13, 3) // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (0) + +#define DISPLAY_PMU_IIC_BUS (0) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/n59/include/target/powerconfig.h b/target/n59/include/target/powerconfig.h new file mode 100644 index 0000000..a8741bf --- /dev/null +++ b/target/n59/include/target/powerconfig.h @@ -0,0 +1,116 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 1 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x17 }, // enable BUCK3_SW1, BUCK3_SW2, BUCK3_SW3, BUCK4_SW1 + { PMU_IIC_BUS, kD2186_ACTIVE3, 0xBE }, // enable LDO4 along with LDO{1,2,3,5,7} + { PMU_IIC_BUS, kD2186_ACTIVE6, 0x37 }, // enable BUCK4_SW2 + { PMU_IIC_BUS, kD2186_HIBERNATE3, 0x18 }, // enable LDO3+LDO4 in hibernate + + { PMU_IIC_BUS, kD2186_OUT_32K, 0x49 }, // enable OUT32 clock + + { PMU_IIC_BUS, kD2186_LDO9_VSEL, 0x39 }, // Request for N59 iBoot LDO9 voltage change +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// Settings as of N59 | IOSpreadsheet, version 0v5 +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2186_GPIO1_CONF1, 0x8a }, // CHG_TO_PMU_INT_L In, L Low, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO1_CONF2, 0x72 }, // CHG_TO_PMU_INT_L POR + { PMU_IIC_BUS, kD2186_GPIO2_CONF1, 0x8a }, // BB_TO_PMU_HOST_WAKE_L In, L Low, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO2_CONF2, 0x72 }, // BB_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO3_CONF1, 0x01 }, // PMU_TO_BB_RST_R_L Out 0, Low , Push-Pull + { PMU_IIC_BUS, kD2186_GPIO3_CONF2, 0x12 }, // PMU_TO_BB_RST_R_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO4_CONF1, 0x83 }, // TRISTAR_TO_AP_INT In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO4_CONF2, 0x72 }, // TRISTAR_TO_AP_INT POR + { PMU_IIC_BUS, kD2186_GPIO5_CONF1, 0x83 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO5_CONF2, 0x72 }, // STOCKHOLM_TO_PMU_HOST_WAKE_L POR + { PMU_IIC_BUS, kD2186_GPIO6_CONF1, 0x01 }, // PMU_TO_OSCAR_RESET_CLK_32K_L Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO6_CONF2, 0x12 }, // PMU_TO_OSCAR_RESET_CLK_32K_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO7_CONF1, 0x83 }, // WLAN_TO_PMU_HOST_WAKE In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO7_CONF2, 0x72 }, // WLAN_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO8_CONF1, 0xA2 }, // CODEC_TO_PMU_MIKEY_INT_L In, Any Edge, Wake, PU + { PMU_IIC_BUS, kD2186_GPIO8_CONF2, 0x12 }, // CODEC_TO_PMU_MIKEY_INT_L VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO9_CONF1, 0x01 }, // PMU_TO_BT_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO9_CONF2, 0x12 }, // PMU_TO_BT_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO10_CONF1, 0x92 }, // BT_TO_PMU_HOST_WAKE In, R Edge, Wake, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO10_CONF2, 0x72 }, // BT_TO_PMU_HOST_WAKE Disabled + { PMU_IIC_BUS, kD2186_GPIO11_CONF1, 0x01 }, // PMU_TO_WLAN_REG_ON_R Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO11_CONF2, 0x12 }, // PMU_TO_WLAN_REG_ON_R VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO12_CONF1, 0x08 }, // AP_TO_I2C0_SCL Out, nReset, PU + { PMU_IIC_BUS, kD2186_GPIO12_CONF2, 0x72 }, // AP_TO_I2C0_SCL POR + { PMU_IIC_BUS, kD2186_GPIO13_CONF1, 0x83 }, // OSCAR_TO_PMU_HOST_WAKE In, In, L High, Wake, PD + { PMU_IIC_BUS, kD2186_GPIO13_CONF2, 0x72 }, // OSCAR_TO_PMU_HOST_WAKE POR + { PMU_IIC_BUS, kD2186_GPIO14_CONF1, 0x01 }, // PMU_TO_STOCKHOLM_EN Out 0, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO14_CONF2, 0x12 }, // PMU_TO_STOCKHOLM_EN VBUCK3 + { PMU_IIC_BUS, kD2186_GPIO15_CONF1, 0x01 }, // PMU_TO_BB_VBUS_DET Out 0, Low, Push-Pull + { PMU_IIC_BUS, kD2186_GPIO15_CONF2, 0x02 }, // PMU_TO_BB_VBUS_DET VCC_MAIN + { PMU_IIC_BUS, kD2186_GPIO16_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO16_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO17_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO17_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO18_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO18_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO19_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO19_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO20_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO20_CONF2, 0x72 }, // POR + { PMU_IIC_BUS, kD2186_GPIO21_CONF1, 0x91 }, // NC + { PMU_IIC_BUS, kD2186_GPIO21_CONF2, 0x72 }, // POR + +// TODO: configure debounce for WAS kD2045_GPIO_DEB2,kD2045_GPIO_DEB5,kD2045_GPIO_DEB6? + + { PMU_IIC_BUS, kD2186_BUCK_DWI_CTRL0, 0x07 }, // enable DWI for BUCK0, BUCK1, BUCK2 + { PMU_IIC_BUS, kD2186_SYS_CTRL2, 0x11 }, // enable HIB_32kHz (for WIFI/BT) and DWI + { PMU_IIC_BUS, kD2186_SYS_CTRL1, 0x24 }, // disable PROT_FET_DIS, BAT_PWR_SUSP rdar://15680815 + +// TODO: verify + { PMU_IIC_BUS, kD2186_ACT_TO_HIB_DLY, 0x03 }, // set ACT_TO_HIB_DLY to 3 (6ms) +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK0_VSEL } +}; + +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2186_BUCK5_VSEL } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 + +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#define TARGET_POWER_NEEDS_BATTERY_PROTECTION_RESET 1 + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/n59/include/target/uartconfig.h b/target/n59/include/target/uartconfig.h new file mode 100644 index 0000000..f81b712 --- /dev/null +++ b/target/n59/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/n59/init.c b/target/n59/init.c new file mode 100644 index 0000000..ffce674 --- /dev/null +++ b/target/n59/init.c @@ -0,0 +1,507 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif + +#define N59_AP_BOARD_ID (0x18) // AP board ID +#define N59_DEV_BOARD_ID (0x19) // DEV board ID + +#define N59_DEV_BOARD_REV (0xF) + +#define N59_PROTOMLB1 (0xF) + +// Combined Board Id/Board Revision +// IMPORTANT: IF YOU CHANGE THE ORDER OF THESE ENUMERATORS YOU MUST CHECK +// FOR ANY > or < RELATIONSHIPS THAT MAY NEED TO ALSO CHANGE. +typedef enum { + BOARD_TYPE_UNKNOWN = 0, + BOARD_TYPE_N59_DEV1 = 1, + BOARD_TYPE_N59_PROTOMLB1 = 2, +} board_type; + +static board_type iphone7_get_board_type(void); +static uint32_t iphone7_get_board_rev(void); + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; + +static uint32_t display_config; + +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xC6); +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static uint32_t iphone7_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +static board_type iphone7_get_board_type(void) +{ + static board_type board_type = BOARD_TYPE_UNKNOWN; + + if (board_type != BOARD_TYPE_UNKNOWN) { + return board_type; + } + + uint32_t board_id = platform_get_board_id(); + uint32_t board_rev = iphone7_get_board_rev(); + + switch (board_id) { + case N59_AP_BOARD_ID: + switch (board_rev) { + case N59_PROTOMLB1: + return BOARD_TYPE_N59_PROTOMLB1; + + default: + goto fail; + } + case N59_DEV_BOARD_ID: + switch (board_rev) { + case N59_DEV_BOARD_REV: + return BOARD_TYPE_N59_DEV1; + + default: + goto fail; + } + + default: + goto fail; + } + +fail: + platform_not_supported(); + return BOARD_TYPE_UNKNOWN; +} + +int target_get_boot_battery_capacity(void) { + return 50; +} + +void target_early_init(void) +{ +#if PRODUCT_LLB || PRODUCT_IBSS + uint32_t target_mipi_p, target_mipi_m, target_mipi_s; + + // Temporary workaround to set MIPI P/M/S values for display + // D410 (@ 513 MHz) until rdar://problem/17985178 is fixed. + target_mipi_p = 4; + target_mipi_m = 171; + target_mipi_s = 1; + + clock_set_frequency(CLK_MIPI, 0, target_mipi_p, target_mipi_m, target_mipi_s, 0); +#endif + +#if PRODUCT_LLB || PRODUCT_IBSS + dprintf(DEBUG_INFO, "%s: chip rev: %d, fuse: %d\n", __func__, + chipid_get_chip_revision(), chipid_get_fuse_revision()); + +#if WITH_HW_POWER + int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); + + int rc; + uint8_t val; + + if ((rc = pmu_get_data(0, 0x1, &val)) < 0) { // read PMU.OTP version + dprintf(DEBUG_CRITICAL, "PMU: cannot read OTP Version (%d)\n", rc); + } else { + dprintf(DEBUG_INFO, "%s: PMU OTP ver: %x\n", __func__, val); + } +#endif +#endif +} + +void target_late_init(void) +{ + clock_gate(CLK_UART7, 0); +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + uint32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000044; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "D410", 0); + env_set("adbe-tunables", "D410", 0); + env_set("adfe-tunables", "D410", 0); +} + +#endif + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); +} +#endif + +#if WITH_HW_LM3534 +uint8_t target_lm3534_gpr(uint32_t ctlr) +{ + // DISPLAY_PANEL_TYPE_D410: + // (ovp_select_21v) | (ramp disable) | (chip enable) + return ((1 << 4) | (1 << 1) | (1 << 0)); +} +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *disp0_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + +#if WITH_HW_DISPLAY_PINOT + // Find the DISP0 (display-subsystem 0) node + FindNode(0, "arm-io/disp0", &disp0_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, disp0_node, backlight_node); + } +#endif + +#if WITH_HW_MIPI_DSIM + // Find the mipi node + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + extern int mipi_update_device_tree(DTNode *mipi_node); + mipi_update_device_tree(node); + } +#endif + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + // Update the codec and speaker nodes with acoustic transducer scale data + { + uint8_t atscData[20]; + + if (syscfgCopyDataForTag('ATSc', atscData, sizeof(atscData)) > 0) { + // Update codec + if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { + propName = "at-scale-imic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[0], sizeof(uint32_t)); + } + propName = "at-scale-smic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[4], sizeof(uint32_t)); + } + propName = "at-scale-fmic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[8], sizeof(uint32_t)); + } + propName = "at-scale-rcvr"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[12], sizeof(uint32_t)); + } + } + // Update speaker + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memcpy(propData, &atscData[16], sizeof(uint32_t)); + } + } + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/uart8/oscar/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + propName = "compass-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CRot', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/uart8/oscar/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/uart8/oscar/accelerometer", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('PxCl', propData, propSize); + } + + // Stockholm calibration + if (FindNode(0, "arm-io/uart3/stockholm", &node)) { + propName = "calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('NFCl', propData, propSize); + } + + // Update the X162 calibration data + if (FindNode(0, "arm-io/spi3/mesa", &node)) { + propName = "calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FSCl', propData, propSize); + } + propName = "modulation-ratio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('NvMR', propData, propSize); + } + } + + // Update cover glass type + if (FindNode(0, "product", &node)) { + propName = "cover-glass"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CGSp', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('CBAT', propData, propSize); + } + + // Update Vibe calibration data + if (FindNode(0, "arm-io/i2c1/vib-pwm", &node)) { + propName = "calibration-data"; + if (FindProperty(node, &propName, &propData, &propSize)) { + const uint32_t count=syscfgCopyDataForTag('VbCl', propData, propSize); + if ( count!=propSize ) *((uint32_t*)propData)=0x00a46d0d; + } + } + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 00020000B9B5B4003C3B3B0000000000 +// gold/white: setenv DClr_override 00020000B5CCE100E3E4E10000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT diff --git a/target/n59/pinconfig.c b/target/n59/pinconfig.c new file mode 100644 index 0000000..52fc143 --- /dev/null +++ b/target/n59/pinconfig.c @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v5 + I/O Spreadsheet tracker: N59 GPIO Spreadsheet + Conversion command: csvtopinconfig.py --soc h7p +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 0 : ULPI_DIR -> LCM_TO_AP_HIFA_BSYNC + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 1 : ULPI_STP -> AP_TO_LCM_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 2 : ULPI_NXT -> AP_TO_TOUCH_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 3 : ULPI_DATA[7] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + CFG_IN | PULL_DOWN | SLOW_SLEW, // 7 : ULPI_CLK -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 1 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 8 : ULPI_DATA[3] -> AP_TO_LEDDRV_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 10 : ULPI_DATA[1] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 11 : ULPI_DATA[0] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 12 : SPI1_SCLK -> AP_TO_CODEC_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_MOSI -> AP_TO_CODEC_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 14 : SPI1_MISO -> CODEC_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 15 : SPI1_SSIN -> AP_TO_CODEC_SPI_CS_L + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> BUTTON_TO_AP_MENU_KEY_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> BUTTON_TO_AP_HOLD_KEY_L + CFG_IN | PULL_UP | SLOW_SLEW, // 34 : I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> AP_TO_BB_I2S3_LRCLK + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> 45_AP_TO_BB_I2S3_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 37 : I2S3_DOUT -> AP_TO_BB_I2S3_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> BB_TO_AP_I2S3_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 39 : CLK32K_OUT -> 45_AP_TO_TOUCH_CLK32K_RESET_L + +/* Port 5 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 41 : PCIE_CLKREQ1_N -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 43 : GPIO[0] -> AP_TO_HEADSET_HS3_CTRL + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 44 : GPIO[1] -> AP_TO_HEADSET_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW, // 45 : GPIO[2] -> BUTTON_TO_AP_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 46 : GPIO[3] -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 47 : GPIO[4] -> SPKAMP_TO_AP_INT_L + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 48 : GPIO[5] -> AP_TO_SPKAMP_BEE_GEES + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 49 : GPIO[6] -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_BT_WAKE + CFG_DISABLED | SLOW_SLEW, // 51 : GPIO[14] -> BB_TO_AP_IPC_GPIO1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 52 : GPIO[16] -> BOARD_ID3 + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 53 : GPIO[17] -> AP_TO_STOCKHOLM_SIM_SEL + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 54 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : GPIO[20] -> NC + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 56 : GPIO[21] -> BB_TO_AP_DEVICE_RDY + CFG_FUNC0 | SLOW_SLEW, // 57 : UART5_RTXD -> AP_TO_TIGRIS_SWI + CFG_IN | PULL_UP | SLOW_SLEW, // 58 : UART8_TXD -> AP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> OSCAR_TO_AP_UART_RXD + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 60 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 61 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 62 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 63 : SPI0_SSIN -> NC + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> AP_TO_I2C2_SCL + CFG_IN | SLOW_SLEW, // 66 : GPIO[22] -> BB_TO_AP_GPS_SYNC + CFG_OUT_0 | SLOW_SLEW, // 67 : GPIO[23] -> AP_TO_BB_HOST_RDY + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> BOOT_CONFIG2 (NC) + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39] -> NC + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 76 : GPIO[42] -> AP_TO_STOCKHOLM_DEV_WAKE + CFG_IN | SLOW_SLEW, // 77 : GPIO[43] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 78 : DISP_VSYNC -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 79 : UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 81 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_IN | PULL_DOWN | SLOW_SLEW, // 82 : TMR32_PWM1 -> AP_TO_VIBE_TRIG + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 84 : UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 85 : UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 86 : I2C3_SDA -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2C3_SCL -> NC + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> AP_TO_I2C0_SCL + CFG_OUT_0 | SLOW_SLEW, // 98 : GPIO[38] -> AP_TO_BB_COREDUMP + CFG_OUT_0 | SLOW_SLEW, // 99 : UART2_TXD -> AP_TO_BB_UART2_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 100 : UART2_RXD -> BB_TO_AP_UART2_RXD + CFG_OUT_0 | SLOW_SLEW, // 101 : UART2_RTSN -> AP_TO_BB_UART2_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 102 : UART2_CTSN -> BB_TO_AP_UART2_CTS_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 103 : DWI_DO -> 45_AP_TO_PMU_AND_BL_DWI_DO + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 104 : DWI_CLK -> 45_AP_TO_PMU_AND_BL_DWI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 105 : WDOG -> AP_TO_PMU_RESET_IN + CFG_IN | PULL_UP | SLOW_SLEW, // 106 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 108 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 109 : GPIO[27] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_TO_AP_PRE_UVLO_L (Netname Change) + CFG_FUNC0 | SLOW_SLEW, // 111 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L (Netname change) + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_IN | SLOW_SLEW, // 114 : GPIO[8] -> AP_TO_BB_RST_L + CFG_DISABLED | SLOW_SLEW, // 115 : GPIO[9] -> AP_TO_WLAN_JTAG_SWCLK + CFG_DISABLED | SLOW_SLEW, // 116 : GPIO[10] -> AP_TO_WLAN_JTAG_SWDIO + CFG_OUT_0 | SLOW_SLEW, // 117 : GPIO[15] -> AP_TO_BB_WAKE_MODEM + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 118 : UART4_TXD -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> WLAN_TO_AP_UART4_RXD + +/* Port 15 */ + CFG_OUT_1 | PULL_DOWN | SLOW_SLEW, // 120 : UART4_RTSN -> AP_TO_WLAN_UART4_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> WLAN_TO_AP_UART4_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 122 : SPI3_MOSI -> AP_TO_MESA_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 123 : SPI3_MISO -> MESA_TO_AP_SPI_MISO + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> AP_TO_MESA_SPI_CLK_R + CFG_IN | SLOW_SLEW, // 125 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 126 : GPIO[24] -> BB_TO_AP_RESET_DET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 127 : GPIO[30] -> CODEC_TO_AP_INT_L + +/* Port 16 */ + CFG_IN | SLOW_SLEW, // 128 : GPIO[31] -> AP_TO_RADIO_ON_L + CFG_OUT_0 | SLOW_SLEW, // 129 : GPIO[32] -> AP_TO_WLAN_HSIC2_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 130 : GPIO[33] -> WLAN_TO_AP_HSIC2_RDY + CFG_IN | SLOW_SLEW, // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + CFG_DISABLED | SLOW_SLEW, // 132 : GPIO[41] -> BB_TO_AP_IPC_GPIO + CFG_IN | SLOW_SLEW, // 133 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2S4_LRCK -> AP_TO_CODEC_VSP_I2S4_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_TO_CODEC_VSP_I2S4_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 137 : I2S4_DIN -> CODEC_TO_AP_VSP_I2S4_DIN + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 138 : I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 139 : I2C1_SCL -> AP_TO_I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 160 : I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 161 : I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 163 : I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> NC + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2S1_LRCK -> AP_TO_BT_I2S1_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 166 : I2S1_BCLK -> 45_AP_TO_BT_I2S1_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TO_BT_I2S1_DOUT + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 168 : I2S1_DIN -> BT_TO_AP_I2S1_DIN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 169 : I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 170 : I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 172 : I2S2_DIN -> CODEC_TO_AP_XSP_I2S2_DIN + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 173 : UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1 | PULL_DOWN | SLOW_SLEW, // 175 : UART1_RTSN -> AP_TO_BT_UART1_RTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 176 : UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_IN | PULL_UP | SLOW_SLEW, // 177 : EDP_HPD -> AP_TO_STOCKHOLM_EN + CFG_IN | PULL_UP | SLOW_SLEW, // 178 : UART3_TXD -> AP_TO_STOCKHOLM_UART3_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 179 : UART3_RXD -> STOCKHOLM_TO_AP_UART3_RXD + CFG_IN | PULL_UP | SLOW_SLEW, // 180 : UART3_RTSN -> AP_TO_STOCKHOLM_UART3_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 181 : UART3_CTSN -> STOCKHOLM_TO_AP_UART3_CTS_L + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 182 : SPI2_SCLK -> AP_TO_TOUCH_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 183 : SPI2_MOSI -> AP_TO_TOUCH_SPI_MOSI + +/* Port 23 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 184 : SPI2_MISO -> TOUCH_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 185 : SPI2_SSIN -> AP_TO_TOUCH_SPI_CS_L + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 186 : ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 187 : ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 188 : ISP1_SDA -> AP_BI_FCAM_I2C_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 189 : ISP1_SCL -> AP_TO_FCAM_I2C_SCL + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 190 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 191 : SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + +/* Port 24 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + CFG_IN | PULL_UP | SLOW_SLEW, // 194 : ISP_UART0_TXD -> AP_ISP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 195 : ISP_UART0_RXD -> OSCAR_TO_AP_ISP_UART_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 196 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 197 : SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 200 : UART7_TXD -> AP_TO_WLAN_DEVICE_WAKE + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 201 : UART7_RXD -> RCAM_EXT_CORE_LDO_EN + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 202 : I2S0_MCK -> 45_AP_TO_CODEC_I2S0_MCLK_R + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 203 : I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 0 : ULPI_DIR -> LCM_TO_AP_HIFA_BSYNC + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 1 : ULPI_STP -> AP_TO_LCM_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 2 : ULPI_NXT -> AP_TO_TOUCH_RESET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 3 : ULPI_DATA[7] -> TOUCH_TO_AP_INT_L + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 4 : ULPI_DATA[6] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 5 : ULPI_DATA[5] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 6 : ULPI_DATA[4] -> NC + CFG_IN | PULL_DOWN | SLOW_SLEW, // 7 : ULPI_CLK -> OSCAR_TO_PMU_HOST_WAKE + +/* Port 1 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 8 : ULPI_DATA[3] -> AP_TO_LEDDRV_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 9 : ULPI_DATA[2] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 10 : ULPI_DATA[1] -> AP_BI_OSCAR_SWDIO_1V8 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 11 : ULPI_DATA[0] -> AP_TO_OSCAR_SWDCLK_1V8 + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 12 : SPI1_SCLK -> AP_TO_CODEC_SPI_CLK + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 13 : SPI1_MOSI -> AP_TO_CODEC_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 14 : SPI1_MISO -> CODEC_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, // 15 : SPI1_SSIN -> AP_TO_CODEC_SPI_CS_L + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_IN | SLOW_SLEW, // 32 : GPIO[11] -> BUTTON_TO_AP_MENU_KEY_L + CFG_IN | SLOW_SLEW, // 33 : GPIO[12] -> BUTTON_TO_AP_HOLD_KEY_L + CFG_IN | PULL_UP | SLOW_SLEW, // 34 : I2S3_MCK -> ALS_TO_AP_INT_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 35 : I2S3_LRCK -> AP_TO_BB_I2S3_LRCLK + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 36 : I2S3_BCLK -> 45_AP_TO_BB_I2S3_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 37 : I2S3_DOUT -> AP_TO_BB_I2S3_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 38 : I2S3_DIN -> BB_TO_AP_I2S3_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 39 : CLK32K_OUT -> 45_AP_TO_TOUCH_CLK32K_RESET_L + +/* Port 5 */ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 40 : PCIE_CLKREQ0_N -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 41 : PCIE_CLKREQ1_N -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 42 : NAND_SYS_CLK -> NC + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 43 : GPIO[0] -> AP_TO_HEADSET_HS3_CTRL + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 44 : GPIO[1] -> AP_TO_HEADSET_HS4_CTRL + CFG_IN | PULL_UP | SLOW_SLEW, // 45 : GPIO[2] -> BUTTON_TO_AP_VOL_UP_L + CFG_IN | PULL_UP | SLOW_SLEW, // 46 : GPIO[3] -> BUTTON_TO_AP_VOL_DOWN_L + CFG_IN | PULL_UP | SLOW_SLEW, // 47 : GPIO[4] -> SPKAMP_TO_AP_INT_L + +/* Port 6 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 48 : GPIO[5] -> AP_TO_SPKAMP_BEE_GEES + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 49 : GPIO[6] -> AP_TO_SPKAMP_RESET_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 50 : GPIO[7] -> AP_TO_BT_WAKE + CFG_DISABLED | SLOW_SLEW, // 51 : GPIO[14] -> BB_TO_AP_IPC_GPIO1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 52 : GPIO[16] -> BOARD_ID3 + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 53 : GPIO[17] -> AP_TO_STOCKHOLM_SIM_SEL + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 54 : GPIO[18] -> BOOT_CONFIG0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 55 : GPIO[20] -> NC + +/* Port 7 */ + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 56 : GPIO[21] -> BB_TO_AP_DEVICE_RDY + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 57 : UART5_RTXD -> AP_TO_TIGRIS_SWI + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 58 : UART8_TXD -> AP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 59 : UART8_RXD -> OSCAR_TO_AP_UART_RXD + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 60 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 61 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 62 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 63 : SPI0_SSIN -> NC + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 64 : I2C2_SDA -> AP_BI_I2C2_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 65 : I2C2_SCL -> AP_TO_I2C2_SCL + CFG_IN | SLOW_SLEW, // 66 : GPIO[22] -> BB_TO_AP_GPS_SYNC + CFG_OUT_0 | SLOW_SLEW, // 67 : GPIO[23] -> AP_TO_BB_HOST_RDY + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 68 : GPIO[25] -> BOOT_CONFIG1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 69 : GPIO[28] -> BOOT_CONFIG2 (NC) + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 70 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 71 : GPIO[34] -> BOARD_REV3 + +/* Port 9 */ + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 72 : GPIO[35] -> BOARD_REV2 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 73 : GPIO[36] -> BOARD_REV1 + CFG_DISABLED | PULL_UP | SLOW_SLEW, // 74 : GPIO[37] -> BOARD_REV0 + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 75 : GPIO[39] -> NC + CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, // 76 : GPIO[42] -> AP_TO_STOCKHOLM_DEV_WAKE + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 77 : GPIO[43] -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 78 : DISP_VSYNC -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 79 : UART0_TXD -> AP_TO_TRISTAR_DEBUG_UART0_TXD + +/* Port 10 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 80 : UART0_RXD -> TRISTAR_TO_AP_DEBUG_UART0_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 81 : TMR32_PWM0 -> OSCAR_BI_AP_TIME_SYNC_HOST_INT + CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 82 : TMR32_PWM1 -> AP_TO_VIBE_TRIG + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 83 : TMR32_PWM2 -> NC + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 84 : UART6_TXD -> AP_TO_TRISTAR_ACC_UART6_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 85 : UART6_RXD -> TRISTAR_TO_AP_ACC_UART6_RXD + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 86 : I2C3_SDA -> NC + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 87 : I2C3_SCL -> NC + +/* Port 11 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 96 : I2C0_SDA -> AP_BI_I2C0_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 97 : I2C0_SCL -> AP_TO_I2C0_SCL + CFG_OUT_0 | SLOW_SLEW, // 98 : GPIO[38] -> AP_TO_BB_COREDUMP + CFG_OUT_0 | SLOW_SLEW, // 99 : UART2_TXD -> AP_TO_BB_UART2_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 100 : UART2_RXD -> BB_TO_AP_UART2_RXD + CFG_OUT_0 | SLOW_SLEW, // 101 : UART2_RTSN -> AP_TO_BB_UART2_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 102 : UART2_CTSN -> BB_TO_AP_UART2_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 103 : DWI_DO -> 45_AP_TO_PMU_AND_BL_DWI_DO + +/* Port 13 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 104 : DWI_CLK -> 45_AP_TO_PMU_AND_BL_DWI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 105 : WDOG -> AP_TO_PMU_RESET_IN + CFG_IN | PULL_UP | SLOW_SLEW, // 106 : GPIO[13] -> PMU_TO_AP_IRQ_L + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 107 : GPIO[19] -> AP_TO_PMU_KEEPACT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 108 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 109 : GPIO[27] -> NC + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 110 : SOCHOT0 -> PMU_TO_AP_PRE_UVLO_L (Netname Change) + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 111 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_L (Netname change) + +/* Port 14 */ + CFG_DISABLED, // 112 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 113 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + CFG_IN | SLOW_SLEW, // 114 : GPIO[8] -> AP_TO_BB_RST_L + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 115 : GPIO[9] -> AP_TO_WLAN_JTAG_SWCLK + CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, // 116 : GPIO[10] -> AP_TO_WLAN_JTAG_SWDIO + CFG_OUT_0 | SLOW_SLEW, // 117 : GPIO[15] -> AP_TO_BB_WAKE_MODEM + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 118 : UART4_TXD -> AP_TO_WLAN_UART4_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 119 : UART4_RXD -> WLAN_TO_AP_UART4_RXD + +/* Port 15 */ + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 120 : UART4_RTSN -> AP_TO_WLAN_UART4_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 121 : UART4_CTSN -> WLAN_TO_AP_UART4_CTS_L + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, // 122 : SPI3_MOSI -> AP_TO_MESA_SPI_MOSI + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 123 : SPI3_MISO -> MESA_TO_AP_SPI_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 124 : SPI3_SCLK -> AP_TO_MESA_SPI_CLK_R + CFG_IN | DRIVE_X2 | SLOW_SLEW, // 125 : SPI3_SSIN -> MESA_TO_AP_INT + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 126 : GPIO[24] -> BB_TO_AP_RESET_DET_L + CFG_IN | PULL_UP | SLOW_SLEW, // 127 : GPIO[30] -> CODEC_TO_AP_INT_L + +/* Port 16 */ + CFG_IN | DRIVE_X4 | SLOW_SLEW, // 128 : GPIO[31] -> AP_TO_RADIO_ON_L + CFG_OUT_0 | SLOW_SLEW, // 129 : GPIO[32] -> AP_TO_WLAN_HSIC2_RDY + CFG_DISABLED | PULL_DOWN | SLOW_SLEW, // 130 : GPIO[33] -> WLAN_TO_AP_HSIC2_RDY + CFG_IN | SLOW_SLEW, // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + CFG_DISABLED | SLOW_SLEW, // 132 : GPIO[41] -> BB_TO_AP_IPC_GPIO + CFG_IN | SLOW_SLEW, // 133 : I2S4_MCK -> TRISTAR_TO_AP_INT + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 134 : I2S4_LRCK -> AP_TO_CODEC_VSP_I2S4_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 135 : I2S4_BCLK -> 45_AP_TO_CODEC_VSP_I2S4_BCLK + +/* Port 17 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 136 : I2S4_DOUT -> AP_TO_CODEC_VSP_I2S4_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 137 : I2S4_DIN -> CODEC_TO_AP_VSP_I2S4_DIN + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 138 : I2C1_SDA -> AP_BI_I2C1_SDA + CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 139 : I2C1_SCL -> AP_TO_I2C1_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 18 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 160 : I2S0_LRCK -> AP_TO_CODEC_ASP_I2S0_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 161 : I2S0_BCLK -> 45_AP_TO_CODEC_ASP_I2S0_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 162 : I2S0_DOUT -> AP_TO_CODEC_ASP_I2S0_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 163 : I2S0_DIN -> CODEC_TO_AP_ASP_I2S0_DIN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 164 : I2S1_MCK -> NC + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 165 : I2S1_LRCK -> AP_TO_BT_I2S1_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 166 : I2S1_BCLK -> 45_AP_TO_BT_I2S1_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 167 : I2S1_DOUT -> AP_TO_BT_I2S1_DOUT + +/* Port 21 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 168 : I2S1_DIN -> BT_TO_AP_I2S1_DIN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 169 : I2S2_LRCK -> AP_TO_CODEC_XSP_I2S2_LRCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 170 : I2S2_BCLK -> 45_AP_TO_CODEC_XSP_I2S2_BCLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 171 : I2S2_DOUT -> AP_TO_CODEC_XSP_I2S2_DOUT + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 172 : I2S2_DIN -> CODEC_TO_AP_XSP_I2S2_DIN + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 173 : UART1_TXD -> AP_TO_BT_UART1_TXD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 174 : UART1_RXD -> BT_TO_AP_UART1_RXD + CFG_OUT_1 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 175 : UART1_RTSN -> AP_TO_BT_UART1_RTS_L + +/* Port 22 */ + CFG_FUNC0 | PULL_UP | SLOW_SLEW, // 176 : UART1_CTSN -> BT_TO_AP_UART1_CTS_L + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 177 : EDP_HPD -> AP_TO_STOCKHOLM_EN + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 178 : UART3_TXD -> AP_TO_STOCKHOLM_UART3_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 179 : UART3_RXD -> STOCKHOLM_TO_AP_UART3_RXD + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 180 : UART3_RTSN -> AP_TO_STOCKHOLM_UART3_RTS_L + CFG_FUNC0 | SLOW_SLEW, // 181 : UART3_CTSN -> STOCKHOLM_TO_AP_UART3_CTS_L + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 182 : SPI2_SCLK -> AP_TO_TOUCH_SPI_CLK + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 183 : SPI2_MOSI -> AP_TO_TOUCH_SPI_MOSI + +/* Port 23 */ + CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, // 184 : SPI2_MISO -> TOUCH_TO_AP_SPI_MISO + CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 185 : SPI2_SSIN -> AP_TO_TOUCH_SPI_CS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 186 : ISP0_SDA -> AP_BI_RCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 187 : ISP0_SCL -> AP_TO_RCAM_I2C_SCL + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 188 : ISP1_SDA -> AP_BI_FCAM_I2C_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 189 : ISP1_SCL -> AP_TO_FCAM_I2C_SCL + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 190 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 191 : SENSOR0_CLK -> 45_AP_TO_RCAM_CLK_R + +/* Port 24 */ + CFG_IN | PULL_DOWN | SLOW_SLEW, // 192 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQ + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 193 : SENSOR0_ISTRB -> NC + CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, // 194 : ISP_UART0_TXD -> AP_ISP_TO_OSCAR_UART_TXD + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 195 : ISP_UART0_RXD -> OSCAR_TO_AP_ISP_UART_RXD + CFG_OUT_0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, // 196 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 197 : SENSOR1_CLK -> 45_AP_TO_FCAM_CLK_R + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 198 : SENSOR1_XSHUTDOWN -> CAM_EXT_LDO_EN + CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 199 : SENSOR1_ISTRB -> NC + +/* Port 25 */ + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 200 : UART7_TXD -> AP_TO_WLAN_DEVICE_WAKE + CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, // 201 : UART7_RXD -> RCAM_EXT_CORE_LDO_EN + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 202 : I2S0_MCK -> 45_AP_TO_CODEC_I2S0_MCLK_R + CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, // 203 : I2S2_MCK -> 45_AP_TO_SPKAMP_I2S2_MCLK_R + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0 } }, + { 1, 1, { pinconfig_dev_0 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/n59/rules.mk b/target/n59/rules.mk new file mode 100644 index 0000000..79b4804 --- /dev/null +++ b/target/n59/rules.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2013-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2186=1 \ + TARGET_CHESTNUT_USE_LOW_RIPPLE_MODE=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x86100000 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_IPHONE_TUNABLES=1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi2/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart4/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + WITH_HW_MIPI=1 \ + TARGET_HS_2_LP_DATA_TIME=41 \ + TARGET_LP_2_HS_DATA_TIME=125 \ + TARGET_HS_2_LP_CLOCK_TIME=57 \ + TARGET_LP_2_HS_CLOCK_TIME=153 + + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o + +ALL_OBJS += $(LOCAL_DIR)/pinconfig.o diff --git a/target/n69/include/target/adbe_settings.h b/target/n69/include/target/adbe_settings.h new file mode 100644 index 0000000..5ae52d1 --- /dev/null +++ b/target/n69/include/target/adbe_settings.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = +{ + { + .name = "D403", + .adbe0_vblank_pos_vbi_pulse = 0x0169, + .adbe0_vblank_clk_gate_wakeup = 0x0007, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(9) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/n69/include/target/aspnandconfig.h b/target/n69/include/target/aspnandconfig.h new file mode 100644 index 0000000..2b5ca83 --- /dev/null +++ b/target/n69/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (4*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY ASPNAND_INDIRECTION_MEMORY + +#endif diff --git a/target/n69/include/target/gpiodef.h b/target/n69/include/target/gpiodef.h new file mode 100644 index 0000000..4a5fc87 --- /dev/null +++ b/target/n69/include/target/gpiodef.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iphone8,x specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO_ID(146) // 74 : GPIO[34] +#define GPIO_BOARD_REV1 GPIO_ID(145) // 73 : GPIO[35] +#define GPIO_BOARD_REV2 GPIO_ID(144) // 72 : GPIO[36] +#define GPIO_BOARD_REV3 GPIO_ID(143) // 71 : GPIO[37] + +/* Miscellaneous Pins */ +#define GPIO_DISPLAY_ID1 GPIO( 4, 0) // 32 : UART7_TXD -> DISPLAY_TO_AP_ID0 (DEV BOARD only) +#define GPIO_DISPLAY_ID0 GPIO( 4, 1) // 33 : UART7_RXD -> DISPLAY_TO_AP_ID1 (DEV BOARD only) +#define GPIO_PROX_SELECT GPIO( 4, 1) // 32 : UART7_RXD -> PROX_SELECT (AP BOARD only) + +/* Display reset */ +#define GPIO_LCD_RST GPIO( 9, 4) // GPIO[12] -> AP_TO_LCM_RESET_L +#define GPIO_LCD_RST_POLARITY (0) // active low + +/* Ringer Switch */ +#define GPIO_RINGER_AB GPIO(16, 3) // 131 : GPIO[40] -> BUTTON_TO_AP_RINGER_A + +#define GPIO_S3E_BOOT_FROM_HOST GPIO_ID(141) // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + +/* which IICs to initialize */ +#define IICS_MASK (7) + +#define TRISTAR_IIC_BUS (1) + +#define DISPLAY_PMU_IIC_BUS (0) + +#define GPIO_PMU_NAND_LOW_POWER_MODE (5) // PMU_TO_NAND_LOW_BATT_BOOT + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/n69/include/target/powerconfig.h b/target/n69/include/target/powerconfig.h new file mode 100644 index 0000000..e09c3aa --- /dev/null +++ b/target/n69/include/target/powerconfig.h @@ -0,0 +1,144 @@ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 1 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2255_EN_CMD0, (1<<7)|(1<<2)|(1<<1)|(1<<0) }, + { PMU_IIC_BUS, kD2255_EN_CMD1, (1<<0) }, // buck8 + { PMU_IIC_BUS, kD2255_SPI_CTRL, 1 }, // enable SPI access + + { PMU_IIC_BUS, kD2255_LDO9_VSEL, 0x1E}, // LDO9 at 2.55V rdar://20437860 +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +// IO_CONFIG[7:6] 0=I 1=O_OD 2=O_PP 3=SS +// IO_TYPE[5:3] O 0=L 1=32K 2=nR 3=TI 4=L +// PUPD[2:1] O 0=NP 1=PU 2=NP 3=<0> +// WAKE_LVL[0] O 0=low 1=high +// IO_TYPE[5:3] I 0=L_AH 1=L_AL 2=RE 3=FE 4=AE +// PUPD[2:1] I 0=NP 1=PU 2=PD_GND 3=<0> +// WAKE_LVL[0] I 0=NW 1=W +// +// N69m iBoot driver update + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_ENA }, // enable test register access + + { PMU_IIC_BUS, kD2255_BUCK1_ANA_TRIM10, 0x69 }, + { PMU_IIC_BUS, kD2255_BUCK1_CLK_TRIM1, 0x01 }, + { PMU_IIC_BUS, kD2255_BUCK1_CLK_TRIM2, 0x05 }, + { PMU_IIC_BUS, kD2255_BUCK1_CLK_TRIM3, 0x0F }, + { PMU_IIC_BUS, kD2255_BUCK2_MINV, 0x8 }, // Lower BUCK2_MINV + + // Set Buck5 Current + { PMU_IIC_BUS, kD2255_BUCK5_ANA_TRIM14, 0x36 }, // Malta ILIM at 1.80A Max Load at 1.43 rdar://19846032 + + { PMU_IIC_BUS, kD2255_PWRONOFF_OUT_32K_EN, 0x7 }, // OUT_32K active in ACTIVE, SLEEP1,2 + + { PMU_IIC_BUS, kDIALOG_TEST_ACCESS, kDIALOG_TEST_ACCESS_DIS }, // disabled test register access + + { PMU_IIC_BUS, kD2255_PWRONOFF_LDO8_EN, 0x1}, // enable Vibrator rdar://20643930 + { PMU_IIC_BUS, kD2255_OUT_32K, 0x49 }, // OUT_32K active, VBUCK3, PP +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK2_VSEL } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK0_VSEL } +}; + +// it's VDD FIXED! used for RAM inside the SOC +static const struct core_rails_struct ram_rails[] = +{ + { PMU_IIC_BUS, 0, kD2255_BUCK5_VSEL } +}; + +// this is indexed with POWER_RAIL_*, I really just need to use the index in LDO[] +target_rails_t target_rails = { + { 0x0F, 500, 1296, 3125 }, // POWER_RAIL_CPU, BUCK0 + { 0x14, 600, 1396, 3125 }, // POWER_RAIL_VDD_FIXED BUCK5 + { 0x11, 600, 1396, 3125 }, // POWER_RAIL_SOC, BUCK2 + + { 0x16, 600, 1396, 3125 }, // POWER_RAIL_CPU_RAM, BUCK7 + { 0x17, 500, 1296, 3125 }, // POWER_RAIL_GPU, BUCK1 + { 0x17, 600, 1396, 3125 }, // POWER_RAIL_GPU_RAM, BUCK8 +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_POWER_NEEDS_BATTERY_PROTECTION_RESET 1 + +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + + +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/n69/include/target/uartconfig.h b/target/n69/include/target/uartconfig.h new file mode 100644 index 0000000..f81b712 --- /dev/null +++ b/target/n69/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (5) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/n69/init.c b/target/n69/init.c new file mode 100644 index 0000000..65db0b9 --- /dev/null +++ b/target/n69/init.c @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif + +#define BOARD_REV_AP_PROTO2 0x2 + +static uint32_t n69_get_board_rev(void); + +#if WITH_HW_LM3534 +MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); +MIB_CONSTANT(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, 0xC4); +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; + +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) +#include +static mipi_t display_panel_configurations[] = { + { + .lanes = 2, + .esc_div = 6, + .pll_n = 0x3, + .pll_m = 0x115, + .pll_p = 0x1, + .hsfreq = 0x29, + .target_phy_settings = {4, {{0x44, 1, {0x52}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //843 Mhz + }, +}; +#endif + +// Read the board rev GPIOs. Note that the encoding is done +// with active-low GPIOs, so we need to invert the values +// we read from the GPIOs +static uint32_t n69_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + // Invert + gpio_board_rev ^= 0xf; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +int target_get_boot_battery_capacity(void) +{ + int temp=0; +#if WITH_HW_GASGAUGE + if ( gasgauge_read_temperature(&temp) != 0 ) temp=0; // defensive +#endif + + const uint32_t charge_current=power_get_available_charge_current(); + if ( temp>500 && charge_current>500 ) return 0; // rely on SOC1 clear only + + return 50; // @see rdar://16587240 +} + +void target_early_init(void) +{ + +} + +void target_late_init(void) +{ + if (target_config_ap() && n69_get_board_rev() < BOARD_REV_AP_PROTO2) { + dprintf(DEBUG_INFO, "Proto1 is deprecated\n"); + platform_not_supported(); + } + + power_set_gpio(GPIO_PMU_NAND_LOW_POWER_MODE, 1, 1); +} + +void target_init(void) +{ + uint32_t board_rev = n69_get_board_rev(); +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + dprintf(DEBUG_INFO, "board rev 0x%x (raw 0x%x)\n", board_rev, board_rev ^ 0xf); +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +void * target_get_display_configuration(void) +{ +#if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) + return ((void *)(&display_panel_configurations[0])); +#else + return NULL; +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "D403", 0); + env_set("adbe-tunables", "D403", 0); + env_set("adfe-tunables", "D403", 0); +} + +#endif + +#if WITH_HW_CHESTNUT +uint8_t target_get_lcm_ldos(void) +{ + return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); +} +#endif + +#if WITH_HW_LM3534 +uint8_t target_lm3534_gpr(uint32_t ctlr) +{ + return ((1 << 1) | (1 << 0) | (1 << 4)); // (ramp disable) | (chip enable) | (auto mode); +} +#endif + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *disp0_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + +#if WITH_HW_DISPLAY_PINOT + // Find the DISP0 (display-subsystem 0) node + FindNode(0, "arm-io/disp0", &disp0_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, disp0_node, backlight_node); + } +#endif + +#if WITH_HW_MIPI_DSIM + // Find the mipi node + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + extern int mipi_update_device_tree(DTNode *mipi_node); + mipi_update_device_tree(node); + } +#endif + + // Update the speaker calibration data + if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-calib"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SpCl', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + if (FindNode(0, "arm-io/i2c1/audio-actuator", &node)) { + propName = "actuator-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('TCal', propData, propSize); + } + } + + // Update the codec with acoustic transducer scale data + if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { + propName = "acoustic-trim-gains"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ATGa', propData, propSize); + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + propName = "compass-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CRot', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/gyro", &node)) { + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GRot', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/accel", &node)) { + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ARot', propData, propSize); + } + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Update pressure sensor calibration data + if (FindNode(0, "arm-io/aop/iop-aop-nub/pressure", &node)) { + propName = "pressure-offset-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SPPO', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('PxCl', propData, propSize); + propName = "orb-gap-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('OrbG', propData, propSize); + propName = "orb-accel-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('OICo', propData, propSize); + propName = "orb-force-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('OFCl', propData, propSize); + propName = "orb-dynamic-accel-cal"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('FDAC', propData, propSize); + } + + // Stockholm calibration + if (FindNode(0, "arm-io/uart2/stockholm", &node)) { + propName = "calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('NFCl', propData, propSize); + } + + // Update the X162 calibration data + if (FindNode(0, "arm-io/spi3/mesa", &node)) { + propName = "calibration-blob"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('FSCl', propData, propSize); + } + propName = "modulation-ratio"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('NvMR', propData, propSize); + } + } + + // Update cover glass type + if (FindNode(0, "product", &node)) { + propName = "cover-glass"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CGSp', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) + syscfgCopyDataForTag('CBAT', propData, propSize); + } + + // vibrator calibration + if (FindNode(0, "arm-io/pwm/vibrator", &node)) { + propName = "duty-cycle"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint32_t pct; + if (syscfgCopyDataForTag('VLSg', (void *)&pct, sizeof(pct)) > 0) { + ((uint32_t *)propData)[0] = ((uint64_t)pct << 32) / 100; + } + } + propName = "intensity-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint32_t pct; + if (syscfgCopyDataForTag('VLWk', (void *)&pct, sizeof(pct)) > 0) { + ((uint32_t *)propData)[1] = ((uint64_t)pct << 32) / 100; + } + } + } + +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); +#endif + + return 0; +} + +#endif // WITH_DEVICETREE + +#if WITH_PAINT + +// The default background is expected to to be black and the artwork is expected +// to be white. This arrangement will be inverted depending upon the cover glass +// color of the device. + +// Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): +// gray/black: setenv DClr_override 00020000B9B5B4003C3B3B0000000000 +// gold/white: setenv DClr_override 00020000B5CCE100E3E4E10000000000 +// silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 + +static color_policy_invert_t target_cover_glass_color_table[] = { + { RGB( 59, 59, 60), false }, // Black - black background, white logo + { RGB(225, 228, 227), true }, // White - white background, black logo + { RGB( 18, 18, 17), false }, // Black - black background, white logo + { RGB(200, 202, 202), true }, // White - white background, black logo +}; + +color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) +{ + // Must have a color policy structure passed in. + if (color_policy == NULL) + goto fail; + + // We only support the RGB888 colorspace. + if (cs != CS_RGB888) + goto fail; + + color_policy->policy_type = COLOR_MAP_POLICY_INVERT; + color_policy->color_table = (void *)target_cover_glass_color_table; + color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); + color_policy->map_color = NULL; // Use standard remapper + + return color_policy; + +fail: + return NULL; +} +#endif // WITH_PAINT + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +uint32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(uint8_t key, uint8_t *data) +{ + return -1; +} + +int power_set_nvram(uint8_t key, uint8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/n69/pinconfig.c b/target/n69/pinconfig.c new file mode 100644 index 0000000..a4d956f --- /dev/null +++ b/target/n69/pinconfig.c @@ -0,0 +1,769 @@ +/* + * Copyright (C) YEAR Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0v21 + I/O Spreadsheet tracker: None + Conversion command: ./tools/csvtopinconfig.py --soc maui --sheet Malta +*/ + +#include +#include +#include +#include +#include + +enum { + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, + GPIOCFG_CFG_DISABLED_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_DRIVE_X6_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X2_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_FUNC0_SLOW_SLEW, + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_DRIVE_X2_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_PULL_UP_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW, + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_IN_SLOW_SLEW, + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, + GPIOCFG_CFG_OUT_0_DRIVE_X2_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_PULL_DOWN_SLOW_SLEW, + GPIOCFG_CFG_OUT_0_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW, + GPIOCFG_CFG_OUT_1_SLOW_SLEW, +}; + + +static const uint32_t enum_map[] = { + [GPIOCFG_CFG_DISABLED] = CFG_DISABLED, + [GPIOCFG_CFG_DISABLED_DRIVE_X4_SLOW_SLEW] = CFG_DISABLED | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN] = CFG_DISABLED | PULL_DOWN, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2] = CFG_DISABLED | PULL_DOWN | DRIVE_X2, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW] = CFG_DISABLED | PULL_DOWN | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT] = CFG_DISABLED | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_X4_SLOW_SLEW] = CFG_DISABLED | PULL_UP | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW] = CFG_DISABLED | PULL_UP | SLOW_SLEW, + [GPIOCFG_CFG_DISABLED_SLOW_SLEW] = CFG_DISABLED | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW] = CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW] = CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_DRIVE_X6_SLOW_SLEW] = CFG_FUNC0 | DRIVE_X6 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW] = CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW] = CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW] = CFG_FUNC0 | PULL_DOWN | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X2_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW] = CFG_FUNC0 | PULL_UP | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_FUNC0_SLOW_SLEW] = CFG_FUNC0 | SLOW_SLEW, + [GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT] = CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_DRIVE_X2_SLOW_SLEW] = CFG_IN | DRIVE_X2 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW] = CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_DOWN | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X4_SLOW_SLEW] = CFG_IN | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW] = CFG_IN | PULL_DOWN | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_DOWN | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_PULL_UP_DRIVE_X4_SLOW_SLEW] = CFG_IN | PULL_UP | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW] = CFG_IN | PULL_UP | SLOW_SLEW, + [GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_IN_SLOW_SLEW] = CFG_IN | SLOW_SLEW, + [GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT] = CFG_IN | SLOW_SLEW | INPUT_SCHMITT, + [GPIOCFG_CFG_OUT_0_DRIVE_X2_SLOW_SLEW] = CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW] = CFG_OUT_0 | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_PULL_DOWN_DRIVE_X4_SLOW_SLEW] = CFG_OUT_0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_PULL_DOWN_SLOW_SLEW] = CFG_OUT_0 | PULL_DOWN | SLOW_SLEW, + [GPIOCFG_CFG_OUT_0_SLOW_SLEW] = CFG_OUT_0 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW] = CFG_OUT_1 | DRIVE_X4 | SLOW_SLEW, + [GPIOCFG_CFG_OUT_1_SLOW_SLEW] = CFG_OUT_1 | SLOW_SLEW, +}; + + +static const uint8_t pinconfig_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 0 : SWD_TMS2 -> SWD_AP_BI_NAND_SWDIO + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 1 : SWD_TMS3 -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 2 : UART5_RTXD -> SWI_AP_BI_TIGRIS + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 3 : I2S4_MCK -> TRISTAR_TO_AP_INT + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 4 : I2S4_BCLK -> I2S_AP_TO_CODEC_MSP_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 5 : I2S4_LRCK -> I2S_AP_TO_CODEC_MSP_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 6 : I2S4_DIN -> I2S_CODEC_TO_AP_MSP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 7 : I2S4_DOUT -> I2S_AP_TO_CODEC_MSP_DOUT + +/* Port 1 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 8 : I2S2_MCK -> I2S_AP_TO_SPEAKERAMP_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 9 : I2S2_BCLK -> I2S_AP_TO_CODEC_ASP_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 10 : I2S2_LRCK -> I2S_AP_TO_CODEC_ASP_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 11 : I2S2_DIN -> I2S_CODEC_TO_AP_ASP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 12 : I2S2_DOUT -> I2S_AP_TO_CODEC_ASP_DOUT + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 13 : SPI1_SCLK -> SPI_AP_TO_CODEC_SCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 14 : SPI1_MOSI -> SPI_CODEC_TO_AP_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 15 : SPI1_MISO -> SPI_CODEC_TO_AP_MISO + +/* Port 2 */ + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 16 : SPI1_SSIN -> SPI_AP_TO_CODEC_CS_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 17 : I2S0_MCK -> I2S_AP_TO_CODEC_MCLK_R + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 18 : I2S0_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 19 : I2S0_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S0_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 21 : I2S0_DOUT -> I2S_AP_TO_CODEC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 22 : I2C2_SDA -> I2C2_AP_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 23 : I2C2_SCL -> I2C2_AP_SCL + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 24 : UART1_TXD -> UART_AP_TO_BT_TXD + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 25 : UART1_RXD -> UART_BT_TO_AP_RXD + GPIOCFG_CFG_OUT_1_SLOW_SLEW, // 26 : UART1_RTS_L -> UART_AP_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 27 : UART1_CTS_L -> UART_BT_TO_AP_CTS_L + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 28 : UART4_TXD -> UART_AP_TO_WLAN_TXD + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 29 : UART4_RXD -> UART_WLAN_TO_AP_RXD + GPIOCFG_CFG_OUT_1_SLOW_SLEW, // 30 : UART4_RTS_L -> UART_AP_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 31 : UART4_CTS_L -> UART_WLAN_TO_AP_CTS_L + +/* Port 4 */ + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 32 : UART7_TXD -> NC + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 33 : UART7_RXD -> PROX_SELECT + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 34 : CLK32K_OUT -> AP_TO_TOUCH_CLK32K_RESET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 35 : DP_WAKEUP -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 36 : MIPICSI_MUXSEL -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 37 : ISP_I2C1_SDA -> I2C_ISP_BI_FCAM_SDA + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 38 : ISP_I2C1_SCL -> I2C_ISP_TO_FCAM_SCL + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 39 : ISP_I2C0_SDA -> I2C_ISP_BI_RCAM_SDA + +/* Port 5 */ + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 40 : ISP_I2C0_SCL -> I2C_ISP_TO_RCAM_SCL + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 41 : SPI2_SCLK -> SPI_AP_TO_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 42 : SPI2_MOSI -> SPI_AP_TO_TOUCH_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 43 : SPI2_MISO -> SPI_TOUCH_TO_AP_MISO + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 44 : SPI2_SSIN -> SPI_AP_TO_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 45 : I2C0_SDA -> I2C0_AP_SDA + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 46 : I2C0_SCL -> I2C0_AP_SCL + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 47 : SENSOR0_ISTRB -> NC + +/* Port 6 */ + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 48 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 49 : SENSOR0_CLK -> AP_TO_RCAM_CLK_R + GPIOCFG_CFG_IN_SLOW_SLEW, // 50 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQUEST + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 51 : SENSOR1_ISTRB -> NC + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 52 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 53 : SENSOR1_CLK -> AP_TO_FCAM_CLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 54 : SENSOR1_XSHUTDOWN -> NC_AP_TO_MUON_BL_STROBE_EN + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 64 : GPIO[0] -> AP_TO_HP_HS3_CTRL + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 65 : GPIO[1] -> AP_TO_HP_HS4_CTRL + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 66 : GPIO[2] -> BUTTON_VOL_UP_L + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 67 : GPIO[3] -> BUTTON_VOL_DOWN_L + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 68 : GPIO[4] -> SPEAKERAMP_TO_AP_INT_L + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 69 : GPIO[5] -> AP_TO_SPEAKERAMP_STAYIN_ALIVE + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 70 : GPIO[6] -> AP_TO_SPEAKERAMP_RESET_L + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 71 : GPIO[7] -> AP_TO_BT_WAKE + +/* Port 9 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 72 : GPIO[8] -> AP_TO_BB_RESET_L + GPIOCFG_CFG_OUT_0_PULL_DOWN_SLOW_SLEW, // 73 : GPIO[9] -> PCIE_AP_TO_WLAN_DEV_WAKE + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 74 : GPIO[10] -> AP_TO_LED_DRIVER_EN + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 75 : GPIO[11] -> AP_TO_TOUCH_RESET_L + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 76 : GPIO[12] -> AP_TO_LCM_RESET_L + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 77 : GPIO[13] -> PMU_TO_AP_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 78 : GPIO[14] -> AP_TO_BB_PCIE_DEV_WAKE + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 79 : GPIO[15] -> AP_TO_STOCKHOLM_DEV_WAKE + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 80 : GPIO[16] -> BOARD_ID3 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 81 : GPIO[17] -> AP_TO_STOCKHOLM_SIM_SEL + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 82 : GPIO[18] -> BOOT_CONFIG0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 83 : I2S1_MCK -> I2S_AP_TO_ARC_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 84 : I2S1_BCLK -> I2S_AP_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 85 : I2S1_LRCK -> I2S_AP_TO_BT_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 86 : I2S1_DIN -> I2S_BT_TO_AP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 87 : I2S1_DOUT -> I2S_AP_TO_BT_DOUT + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 88 : UART3_TXD -> UART_AP_TO_STOCKHOLM_TXD + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 89 : UART3_RXD -> UART_STOCKHOLM_TO_AP_RXD + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 90 : UART3_RTS_L -> UART_AP_TO_STOCKHOLM_RTS_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 91 : UART3_CTS_L -> UART_STOCKHOLM_TO_AP_CTS_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 12 */ + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 96 : MENU_KEY_L -> BUTTON_MENU_KEY_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 97 : HOLD_KEY_L -> BUTTON_HOLD_KEY_L + GPIOCFG_CFG_DISABLED_PULL_DOWN, // 98 : SKEY_L -> NC + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 99 : SPI3_SCLK -> SPI_AP_TO_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 100 : SPI3_MOSI -> SPI_AP_TO_MESA_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 101 : SPI3_MISO -> SPI_MESA_TO_AP_MISO + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 102 : SPI3_SSIN -> MESA_TO_AP_INT + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 103 : SPI0_SCLK -> BOARD_ID0 + +/* Port 13 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 104 : SPI0_MOSI -> BOARD_ID1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 105 : SPI0_MISO -> BOARD_ID2 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 106 : SPI0_SSIN -> USB_RLC_SWITCH_OE_L + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 107 : UART0_TXD -> UART_AP_DEBUG_TXD + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 108 : UART0_RXD -> UART_AP_DEBUG_RXD + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 109 : UART6_TXD -> UART_AP_TO_ACCESSORY_TXD + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 110 : UART6_RXD -> UART_ACCESSORY_TO_AP_RXD + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 111 : TMR32_PWM0 -> NC + +/* Port 14 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 112 : TMR32_PWM1 -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 113 : TMR32_PWM2 -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C1_SDA -> I2C1_AP_SDA + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C1_SCL -> I2C1_AP_SCL + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 116 : GPIO[19] -> AP_TO_ARC_RESET_L + GPIOCFG_CFG_IN_SLOW_SLEW, // 117 : GPIO[20] -> LCM_TO_OWL_BSYNC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 118 : GPIO[21] -> ARC_TO_AP_INT_L + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 119 : GPIO[22] -> BB_TO_AP_GPS_TIME_MARK + +/* Port 15 */ + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 120 : GPIO[23] -> AP_TO_ARC_STAYIN_ALIVE + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 121 : GPIO[24] -> BB_TO_AP_RESET_DETECT_L + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 122 : GPIO[25] -> BOOT_CONFIG1 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 123 : GPIO[26] -> FORCE_DFU + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 124 : PMGR_MOSI -> DWI_PMGR_TO_PMU_BACKLIGHT_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 125 : PMGR_MISO -> DWI_PMU_TO_PMGR_MISO + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 126 : PMGR_SCLK0 -> DWI_PMGR_TO_PMU_SCLK + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 127 : PMGR_SSCLK1 -> DWI_PMGR_TO_BACKLIGHT_SCLK + +/* Port 16 */ + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 128 : SOCHOT0 -> PMU_TO_AP_SOCHOT0_R_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 129 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_R_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 130 : EDP_HPD -> NC + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2S3_MCK -> ALS_TO_AP_INT_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2S3_BCLK -> I2S_AP_TO_BB_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 133 : I2S3_LRCK -> I2S_AP_TO_BB_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 134 : I2S3_DOUT -> I2S_AP_TO_BB_DOUT + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 135 : I2S3_DIN -> I2S_BB_TO_AP_DIN + +/* Port 17 */ + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 136 : GPIO[27] -> DFU_STATUS + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 137 : GPIO[28] -> BOOT_CONFIG2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 139 : GPIO[30] -> CODEC_TO_AP_PMU_INT_L + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 140 : GPIO[31] -> AP_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 142 : GPIO[33] -> TOUCH_TO_AP_INT_L + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 143 : GPIO[34] -> BOARD_REV3 + +/* Port 18 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 144 : GPIO[35] -> BOARD_REV2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 145 : GPIO[36] -> BOARD_REV1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 146 : GPIO[37] -> BOARD_REV0 + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 147 : GPIO[38] -> AP_TO_BB_COREDUMP + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 148 : GPIO[39] -> BB_IPC_GPIO + GPIOCFG_CFG_IN_SLOW_SLEW, // 149 : GPIO[40] -> BUTTON_RINGER_A + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 150 : GPIO[41] -> AP_TO_BB_MESA_ON + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 151 : GPIO[42] -> CAM_EXT_LDO_EN + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_IN_SLOW_SLEW, // 160 : PCIE_PERST0_L -> PCIE_AP_TO_NAND_RESET_L + GPIOCFG_CFG_IN_SLOW_SLEW, // 161 : PCIE_PERST1_L -> PCIE_AP_TO_WLAN_RESET_L + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 162 : PCIE_PERST2_L -> PCIE_AP_TO_BB_RESET_L + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 163 : PCIE_PERST3_L -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 164 : PCIE_CLKREQ0_L -> PCIE_NAND_TO_AP_CLKREQ_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 165 : PCIE_CLKREQ1_L -> PCIE_WLAN_TO_AP_CLKREQ_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 166 : PCIE_CLKREQ2_L -> PCIE_BB_BI_AP_CLKREQ_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 167 : PCIE_CLKREQ3_L -> NC + +/* Port 21 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 22 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 23 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 24 */ + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW, // 192 : UART2_TXD -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 193 : UART2_RXD -> NC + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW, // 194 : UART2_RTS_L -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 195 : UART2_CTS_L -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 196 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 197 : S3E_RESET_L -> AP_TO_NAND_RESET_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 198 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 0 : OWL_SPI_SCLK -> SPI_OWL_TO_IMU_SCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 1 : OWL_SPI_MOSI -> SPI_OWL_TO_IMU_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 2 : OWL_SPI_MISO -> SPI_IMU_TO_OWL_MISO + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 3 : OWL_UART1_TXD -> OWL_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 4 : OWL_UART1_RXD -> OWL_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 5 : OWL_UART0_TXD -> UART_OWL_TO_BB_TXD + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 6 : OWL_UART0_RXD -> UART_BB_TO_OWL_RXD + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 7 : OWL_UART2_TXD -> UART_OWL_TO_TOUCH_TXD + +/* Port 1 */ + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 8 : OWL_UART2_RXD -> TOUCH_TO_OWL_ACCEL_DATA_REQUEST + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 9 : OWL_I2CM_SDA -> TP_I2C_OWL_SDA + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 10 : OWL_I2CM_SCL -> TP_I2C_OWL_SCL + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 11 : OWL_FUNC[0] -> SPI_OWL_TO_COMPASS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 12 : OWL_FUNC[1] -> COMPASS_TO_OWL_INT + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 13 : OWL_FUNC[2] -> OWL_FUNC2 + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 14 : OWL_FUNC[3] -> ACCEL_GYRO_TO_OWL_INT1 + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 15 : OWL_FUNC[4] -> SPI_OWL_TO_ACCEL_GYRO_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 16 : OWL_FUNC[5] -> ACCEL_GYRO_TO_OWL_INT2 + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 17 : OWL_FUNC[6] -> SPI_OWL_TO_PHOSPHOROUS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 18 : OWL_FUNC[7] -> LCM_TO_OWL_BSYNC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 19 : OWL_FUNC[8] -> OWL_TO_PMU_SHDN_BI_TIGRIS_SWI + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 20 : OWL_FUNC[9] -> PHOSPHORUS_TO_OWL_IRQ + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 21 : OWL_SWD_TCK_OUT -> SWD_AP_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 22 : OWL_SWD_TMS0 -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 23 : OWL_SWD_TMS1 -> SWD_AP_BI_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 24 : OWL_I2S_MCK -> NC + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 25 : OWL_I2S_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 26 : OWL_I2S_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 27 : OWL_I2S_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, // 0 : SWD_TMS2 -> SWD_AP_BI_NAND_SWDIO + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 1 : SWD_TMS3 -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, // 2 : UART5_RTXD -> SWI_AP_BI_TIGRIS + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 3 : I2S4_MCK -> TRISTAR_TO_AP_INT + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 4 : I2S4_BCLK -> I2S_AP_TO_CODEC_MSP_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 5 : I2S4_LRCK -> I2S_AP_TO_CODEC_MSP_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 6 : I2S4_DIN -> I2S_CODEC_TO_AP_MSP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 7 : I2S4_DOUT -> I2S_AP_TO_CODEC_MSP_DOUT + +/* Port 1 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 8 : I2S2_MCK -> I2S_AP_TO_SPEAKERAMP_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 9 : I2S2_BCLK -> I2S_AP_TO_CODEC_ASP_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 10 : I2S2_LRCK -> I2S_AP_TO_CODEC_ASP_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 11 : I2S2_DIN -> I2S_CODEC_TO_AP_ASP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 12 : I2S2_DOUT -> I2S_AP_TO_CODEC_ASP_DOUT + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 13 : SPI1_SCLK -> SPI_AP_TO_CODEC_SCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW, // 14 : SPI1_MOSI -> SPI_CODEC_TO_AP_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 15 : SPI1_MISO -> SPI_CODEC_TO_AP_MISO + +/* Port 2 */ + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW, // 16 : SPI1_SSIN -> SPI_AP_TO_CODEC_CS_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 17 : I2S0_MCK -> I2S_AP_TO_CODEC_MCLK_R + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 18 : I2S0_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 19 : I2S0_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 20 : I2S0_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 21 : I2S0_DOUT -> I2S_AP_TO_CODEC_XSP_DOUT + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 22 : I2C2_SDA -> I2C2_AP_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 23 : I2C2_SCL -> I2C2_AP_SCL + +/* Port 3 */ + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, // 24 : UART1_TXD -> UART_AP_TO_BT_TXD + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 25 : UART1_RXD -> UART_BT_TO_AP_RXD + GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW, // 26 : UART1_RTS_L -> UART_AP_TO_BT_RTS_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 27 : UART1_CTS_L -> UART_BT_TO_AP_CTS_L + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, // 28 : UART4_TXD -> UART_AP_TO_WLAN_TXD + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 29 : UART4_RXD -> UART_WLAN_TO_AP_RXD + GPIOCFG_CFG_OUT_1_DRIVE_X4_SLOW_SLEW, // 30 : UART4_RTS_L -> UART_AP_TO_WLAN_RTS_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 31 : UART4_CTS_L -> UART_WLAN_TO_AP_CTS_L + +/* Port 4 */ + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 32 : UART7_TXD -> NC + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW, // 33 : UART7_RXD -> PROX_SELECT + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 34 : CLK32K_OUT -> AP_TO_TOUCH_CLK32K_RESET_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 35 : DP_WAKEUP -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 36 : MIPICSI_MUXSEL -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 37 : ISP_I2C1_SDA -> I2C_ISP_BI_FCAM_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, // 38 : ISP_I2C1_SCL -> I2C_ISP_TO_FCAM_SCL + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 39 : ISP_I2C0_SDA -> I2C_ISP_BI_RCAM_SDA + +/* Port 5 */ + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, // 40 : ISP_I2C0_SCL -> I2C_ISP_TO_RCAM_SCL + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 41 : SPI2_SCLK -> SPI_AP_TO_TOUCH_SCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 42 : SPI2_MOSI -> SPI_AP_TO_TOUCH_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 43 : SPI2_MISO -> SPI_TOUCH_TO_AP_MISO + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, // 44 : SPI2_SSIN -> SPI_AP_TO_TOUCH_CS_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 45 : I2C0_SDA -> I2C0_AP_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 46 : I2C0_SCL -> I2C0_AP_SCL + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 47 : SENSOR0_ISTRB -> NC + +/* Port 6 */ + GPIOCFG_CFG_OUT_0_DRIVE_X2_SLOW_SLEW, // 48 : SENSOR0_RST -> AP_TO_RCAM_SHUTDOWN_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 49 : SENSOR0_CLK -> AP_TO_RCAM_CLK_R + GPIOCFG_CFG_IN_SLOW_SLEW, // 50 : SENSOR0_XSHUTDOWN -> AP_TO_STOCKHOLM_DWLD_REQUEST + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 51 : SENSOR1_ISTRB -> NC + GPIOCFG_CFG_OUT_0_DRIVE_X2_SLOW_SLEW, // 52 : SENSOR1_RST -> AP_TO_FCAM_SHUTDOWN_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 53 : SENSOR1_CLK -> AP_TO_FCAM_CLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 54 : SENSOR1_XSHUTDOWN -> NC_AP_TO_MUON_BL_STROBE_EN + GPIOCFG_CFG_DISABLED, + +/* Port 7 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 8 */ + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 64 : GPIO[0] -> AP_TO_HP_HS3_CTRL + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 65 : GPIO[1] -> AP_TO_HP_HS4_CTRL + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 66 : GPIO[2] -> BUTTON_VOL_UP_L + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 67 : GPIO[3] -> BUTTON_VOL_DOWN_L + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 68 : GPIO[4] -> SPEAKERAMP_TO_AP_INT_L + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 69 : GPIO[5] -> AP_TO_SPEAKERAMP_STAYIN_ALIVE + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 70 : GPIO[6] -> AP_TO_SPEAKERAMP_RESET_L + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 71 : GPIO[7] -> AP_TO_BT_WAKE + +/* Port 9 */ + GPIOCFG_CFG_DISABLED_SLOW_SLEW, // 72 : GPIO[8] -> AP_TO_BB_RESET_L + GPIOCFG_CFG_OUT_0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 73 : GPIO[9] -> PCIE_AP_TO_WLAN_DEV_WAKE + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 74 : GPIO[10] -> AP_TO_LED_DRIVER_EN + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 75 : GPIO[11] -> AP_TO_TOUCH_RESET_L + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 76 : GPIO[12] -> AP_TO_LCM_RESET_L + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 77 : GPIO[13] -> PMU_TO_AP_IRQ_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 78 : GPIO[14] -> AP_TO_BB_PCIE_DEV_WAKE + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 79 : GPIO[15] -> AP_TO_STOCKHOLM_DEV_WAKE + +/* Port 10 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 80 : GPIO[16] -> BOARD_ID3 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 81 : GPIO[17] -> AP_TO_STOCKHOLM_SIM_SEL + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 82 : GPIO[18] -> BOOT_CONFIG0 + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 83 : I2S1_MCK -> I2S_AP_TO_ARC_MCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 84 : I2S1_BCLK -> I2S_AP_TO_BT_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 85 : I2S1_LRCK -> I2S_AP_TO_BT_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 86 : I2S1_DIN -> I2S_BT_TO_AP_DIN + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 87 : I2S1_DOUT -> I2S_AP_TO_BT_DOUT + +/* Port 11 */ + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 88 : UART3_TXD -> UART_AP_TO_STOCKHOLM_TXD + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 89 : UART3_RXD -> UART_STOCKHOLM_TO_AP_RXD + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 90 : UART3_RTS_L -> UART_AP_TO_STOCKHOLM_RTS_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 91 : UART3_CTS_L -> UART_STOCKHOLM_TO_AP_CTS_L + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 12 */ + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 96 : MENU_KEY_L -> BUTTON_MENU_KEY_L + GPIOCFG_CFG_FUNC0_SLOW_SLEW, // 97 : HOLD_KEY_L -> BUTTON_HOLD_KEY_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2, // 98 : SKEY_L -> NC + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 99 : SPI3_SCLK -> SPI_AP_TO_MESA_SCLK_R + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 100 : SPI3_MOSI -> SPI_AP_TO_MESA_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 101 : SPI3_MISO -> SPI_MESA_TO_AP_MISO + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 102 : SPI3_SSIN -> MESA_TO_AP_INT + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 103 : SPI0_SCLK -> BOARD_ID0 + +/* Port 13 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 104 : SPI0_MOSI -> BOARD_ID1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 105 : SPI0_MISO -> BOARD_ID2 + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 106 : SPI0_SSIN -> USB_RLC_SWITCH_OE_L + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, // 107 : UART0_TXD -> UART_AP_DEBUG_TXD + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 108 : UART0_RXD -> UART_AP_DEBUG_RXD + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X4_SLOW_SLEW, // 109 : UART6_TXD -> UART_AP_TO_ACCESSORY_TXD + GPIOCFG_CFG_FUNC0_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 110 : UART6_RXD -> UART_ACCESSORY_TO_AP_RXD + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 111 : TMR32_PWM0 -> NC + +/* Port 14 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 112 : TMR32_PWM1 -> NC + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 113 : TMR32_PWM2 -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 114 : I2C1_SDA -> I2C1_AP_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 115 : I2C1_SCL -> I2C1_AP_SCL + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 116 : GPIO[19] -> AP_TO_ARC_RESET_L + GPIOCFG_CFG_IN_SLOW_SLEW, // 117 : GPIO[20] -> LCM_TO_OWL_BSYNC + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 118 : GPIO[21] -> ARC_TO_AP_INT_L + GPIOCFG_CFG_IN_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 119 : GPIO[22] -> BB_TO_AP_GPS_TIME_MARK + +/* Port 15 */ + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 120 : GPIO[23] -> AP_TO_ARC_STAYIN_ALIVE + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 121 : GPIO[24] -> BB_TO_AP_RESET_DETECT_L + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 122 : GPIO[25] -> BOOT_CONFIG1 + GPIOCFG_CFG_DISABLED_PULL_DOWN_SLOW_SLEW, // 123 : GPIO[26] -> FORCE_DFU + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 124 : PMGR_MOSI -> DWI_PMGR_TO_PMU_BACKLIGHT_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 125 : PMGR_MISO -> DWI_PMU_TO_PMGR_MISO + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 126 : PMGR_SCLK0 -> DWI_PMGR_TO_PMU_SCLK + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 127 : PMGR_SSCLK1 -> DWI_PMGR_TO_BACKLIGHT_SCLK + +/* Port 16 */ + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 128 : SOCHOT0 -> PMU_TO_AP_SOCHOT0_R_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW, // 129 : SOCHOT1 -> AP_TO_PMU_SOCHOT1_R_L + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 130 : EDP_HPD -> NC + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 131 : I2S3_MCK -> ALS_TO_AP_INT_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 132 : I2S3_BCLK -> I2S_AP_TO_BB_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 133 : I2S3_LRCK -> I2S_AP_TO_BB_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 134 : I2S3_DOUT -> I2S_AP_TO_BB_DOUT + GPIOCFG_CFG_FUNC0_PULL_DOWN_SLOW_SLEW_INPUT_SCHMITT, // 135 : I2S3_DIN -> I2S_BB_TO_AP_DIN + +/* Port 17 */ + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 136 : GPIO[27] -> DFU_STATUS + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 137 : GPIO[28] -> BOOT_CONFIG2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + GPIOCFG_CFG_IN_SLOW_SLEW_INPUT_SCHMITT, // 139 : GPIO[30] -> CODEC_TO_AP_PMU_INT_L + GPIOCFG_CFG_DISABLED_PULL_UP_DRIVE_X4_SLOW_SLEW, // 140 : GPIO[31] -> AP_TO_BB_RADIO_ON_L + GPIOCFG_CFG_OUT_0_DRIVE_X4_SLOW_SLEW, // 141 : GPIO[32] -> AP_TO_NAND_FW_STRAP + GPIOCFG_CFG_IN_PULL_UP_SLOW_SLEW_INPUT_SCHMITT, // 142 : GPIO[33] -> TOUCH_TO_AP_INT_L + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 143 : GPIO[34] -> BOARD_REV3 + +/* Port 18 */ + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 144 : GPIO[35] -> BOARD_REV2 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 145 : GPIO[36] -> BOARD_REV1 + GPIOCFG_CFG_DISABLED_PULL_UP_SLOW_SLEW, // 146 : GPIO[37] -> BOARD_REV0 + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 147 : GPIO[38] -> AP_TO_BB_COREDUMP + GPIOCFG_CFG_DISABLED_DRIVE_X4_SLOW_SLEW, // 148 : GPIO[39] -> BB_IPC_GPIO + GPIOCFG_CFG_IN_SLOW_SLEW, // 149 : GPIO[40] -> BUTTON_RINGER_A + GPIOCFG_CFG_DISABLED_DRIVE_X4_SLOW_SLEW, // 150 : GPIO[41] -> AP_TO_BB_MESA_ON + GPIOCFG_CFG_OUT_0_SLOW_SLEW, // 151 : GPIO[42] -> CAM_EXT_LDO_EN + +/* Port 19 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 20 */ + GPIOCFG_CFG_IN_DRIVE_X2_SLOW_SLEW, // 160 : PCIE_PERST0_L -> PCIE_AP_TO_NAND_RESET_L + GPIOCFG_CFG_IN_DRIVE_X2_SLOW_SLEW, // 161 : PCIE_PERST1_L -> PCIE_AP_TO_WLAN_RESET_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 162 : PCIE_PERST2_L -> PCIE_AP_TO_BB_RESET_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 163 : PCIE_PERST3_L -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 164 : PCIE_CLKREQ0_L -> PCIE_NAND_TO_AP_CLKREQ_L + GPIOCFG_CFG_FUNC0_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 165 : PCIE_CLKREQ1_L -> PCIE_WLAN_TO_AP_CLKREQ_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 166 : PCIE_CLKREQ2_L -> PCIE_BB_BI_AP_CLKREQ_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 167 : PCIE_CLKREQ3_L -> NC + +/* Port 21 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 22 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 23 */ + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + +/* Port 24 */ + GPIOCFG_CFG_IN_PULL_UP_DRIVE_X4_SLOW_SLEW, // 192 : UART2_TXD -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 193 : UART2_RXD -> NC + GPIOCFG_CFG_IN_PULL_UP_DRIVE_X4_SLOW_SLEW, // 194 : UART2_RTS_L -> NC + GPIOCFG_CFG_FUNC0_SLOW_SLEW_INPUT_SCHMITT, // 195 : UART2_CTS_L -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X6_SLOW_SLEW, // 196 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, // 197 : S3E_RESET_L -> AP_TO_NAND_RESET_L + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 198 : TST_CLKOUT -> AP_TO_PMU_TEST_CLKOUT + GPIOCFG_CFG_DISABLED, +}; + +static const uint8_t pinconfig_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 0 : OWL_SPI_SCLK -> SPI_OWL_TO_IMU_SCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 1 : OWL_SPI_MOSI -> SPI_OWL_TO_IMU_MOSI + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 2 : OWL_SPI_MISO -> SPI_IMU_TO_OWL_MISO + GPIOCFG_CFG_OUT_0_DRIVE_X2_SLOW_SLEW, // 3 : OWL_UART1_TXD -> OWL_TO_WLAN_CONTEXT_A + GPIOCFG_CFG_OUT_0_DRIVE_X2_SLOW_SLEW, // 4 : OWL_UART1_RXD -> OWL_TO_WLAN_CONTEXT_B + GPIOCFG_CFG_OUT_0_DRIVE_X2_SLOW_SLEW, // 5 : OWL_UART0_TXD -> UART_OWL_TO_BB_TXD + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 6 : OWL_UART0_RXD -> UART_BB_TO_OWL_RXD + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 7 : OWL_UART2_TXD -> UART_OWL_TO_TOUCH_TXD + +/* Port 1 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 8 : OWL_UART2_RXD -> TOUCH_TO_OWL_ACCEL_DATA_REQUEST + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 9 : OWL_I2CM_SDA -> TP_I2C_OWL_SDA + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, // 10 : OWL_I2CM_SCL -> TP_I2C_OWL_SCL + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X2_SLOW_SLEW, // 11 : OWL_FUNC[0] -> SPI_OWL_TO_COMPASS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 12 : OWL_FUNC[1] -> COMPASS_TO_OWL_INT + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 13 : OWL_FUNC[2] -> OWL_FUNC2 + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 14 : OWL_FUNC[3] -> ACCEL_GYRO_TO_OWL_INT1 + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X2_SLOW_SLEW, // 15 : OWL_FUNC[4] -> SPI_OWL_TO_ACCEL_GYRO_CS_L + +/* Port 2 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 16 : OWL_FUNC[5] -> ACCEL_GYRO_TO_OWL_INT2 + GPIOCFG_CFG_FUNC0_PULL_UP_DRIVE_X2_SLOW_SLEW, // 17 : OWL_FUNC[6] -> SPI_OWL_TO_PHOSPHOROUS_CS_L + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 18 : OWL_FUNC[7] -> LCM_TO_OWL_BSYNC + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 19 : OWL_FUNC[8] -> OWL_TO_PMU_SHDN_BI_TIGRIS_SWI + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 20 : OWL_FUNC[9] -> PHOSPHORUS_TO_OWL_IRQ + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW, // 21 : OWL_SWD_TCK_OUT -> SWD_AP_PERIPHERAL_SWCLK + GPIOCFG_CFG_DISABLED_PULL_DOWN_DRIVE_X2_SLOW_SLEW, // 22 : OWL_SWD_TMS0 -> NC + GPIOCFG_CFG_FUNC0_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 23 : OWL_SWD_TMS1 -> SWD_AP_BI_BB_SWDIO + +/* Port 3 */ + GPIOCFG_CFG_IN_PULL_DOWN_DRIVE_X4_SLOW_SLEW, // 24 : OWL_I2S_MCK -> NC + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 25 : OWL_I2S_BCLK -> I2S_AP_OWL_TO_CODEC_XSP_BCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X4_SLOW_SLEW_INPUT_SCHMITT, // 26 : OWL_I2S_LRCK -> I2S_AP_OWL_TO_CODEC_XSP_LRCLK + GPIOCFG_CFG_FUNC0_PULL_DOWN_DRIVE_X2_SLOW_SLEW_INPUT_SCHMITT, // 27 : OWL_I2S_DIN -> I2S_CODEC_TO_AP_OWL_XSP_DIN + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, + GPIOCFG_CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint8_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_ap_0, pinconfig_ap_1 } }, + { 1, 1, { pinconfig_dev_0, pinconfig_dev_1 } }, +}; + +static uint32_t *expanded_pinconfigs[GPIOC_COUNT]; + +static const uint32_t controller_pins[GPIOC_COUNT] = { + GPIO_GROUP_COUNT * GPIOPADPINS, + GPIO_1_GROUP_COUNT * GPIOPADPINS, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + /* Cannot use malloc as chunk manager is yet to be intialized */ + static uint32_t pinconfig_buf[GPIO_GROUP_COUNT * GPIOPADPINS]; + expanded_pinconfigs[0] = pinconfig_buf; + static uint32_t pinconfig_buf_1[GPIO_1_GROUP_COUNT * GPIOPADPINS]; + expanded_pinconfigs[1] = pinconfig_buf_1; + + ASSERT(gpioc < GPIOC_COUNT); + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + + for (unsigned i = 0; i < GPIOC_COUNT; i++) { + uint32_t num_pins = controller_pins[i]; + + for (uint32_t j = 0; j < num_pins; j++) { + uint8_t enum_key = selected_map->pinconfigs[i][j]; + expanded_pinconfigs[i][j] = enum_map[enum_key]; + } + } + } + + return expanded_pinconfigs[gpioc]; +} diff --git a/target/n69/rules.mk b/target/n69/rules.mk new file mode 100644 index 0000000..5912090 --- /dev/null +++ b/target/n69/rules.mk @@ -0,0 +1,55 @@ +# Copyright (C) 2013-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2255=1 \ + TARGET_CHESTNUT_USE_LOW_RIPPLE_MODE=1 \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=3 \ + TARGET_PLL_VCO_CAP=0 \ + TARGET_VCO_RANGE=3 \ + TARGET_LPF_CTRL=8 \ + TARGET_ICP_CTR=6 \ + TARGET_HS_2_LP_DATA_TIME=35 \ + TARGET_LP_2_HS_DATA_TIME=54 \ + TARGET_HS_2_LP_CLOCK_TIME=57 \ + TARGET_LP_2_HS_CLOCK_TIME=119 \ + TARGET_PHY_STOP_WAIT_TIME=0x28 \ + DISPLAY_IPHONE_TUNABLES=1 \ + DPB_DETECT_VIB_CONTROL_TUNABLE=0xa4830001 \ + DCS_NUM_RANKS=1 \ + DCS_NUM_CHANNELS=4 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + MULTITOUCH_DTPATH=\"arm-io/spi2/multi-touch\" \ + WIFI_DTPATH=\"arm-io/uart4/wlan\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" + +# XXX - Needs added for Agile clocking +# WITH_HW_AGC_MIPI_V2=1 \ +# TARGET_AGILE_LINECOUNT=0x9 \ +# TARGET_AGILE_SEQ1=0x2010002 \ +# TARGET_AGILE_SEQ2=0x6010231 \ +# TARGET_AGILE_CTRL=0xC1804 \ + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o + +ALL_OBJS += $(LOCAL_DIR)/pinconfig.o diff --git a/target/n78/include/target/gpiodef.h b/target/n78/include/target/gpiodef.h new file mode 100644 index 0000000..e7dcdeb --- /dev/null +++ b/target/n78/include/target/gpiodef.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* N78 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_LCD_RST GPIO( 2, 6) +#define GPIO_LCD_RST_POLARITY (0) + +#define GPIO_RINGER_AB GPIO( 0, 4) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 4, 5) +#define GPIO_BOARD_REV1 GPIO( 4, 6) +#define GPIO_BOARD_REV2 GPIO( 4, 7) +#define GPIO_BOARD_REV3 GPIO( 2, 1) + +/* Grape ID */ +#define GPIO_GRAPE_ID0 GPIO( 3, 7) +#define GPIO_GRAPE_ID1 GPIO( 4, 0) +#define GPIO_GRAPE_ID2 GPIO( 4, 3) + +/* which IICs to initialize */ +#define IICS_MASK (5) + +#define TRISTAR_IIC_BUS (0) + +/* D1881 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/n78/include/target/nand_spec_tables.h b/target/n78/include/target/nand_spec_tables.h new file mode 100644 index 0000000..e7e91ae --- /dev/null +++ b/target/n78/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000101 + }, + + /* useToggleMode */ TRUE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ TRUE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ TRUE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/n78/include/target/pinconfig.h b/target/n78/include/target/pinconfig.h new file mode 100644 index 0000000..08d80c8 --- /dev/null +++ b/target/n78/include/target/pinconfig.h @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2009-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* Default n78 SoC Pin Configuration */ + +/* Same drive strength for AP and DEV */ +#define AUD_SPKRAMP_MUTE_L_DRIVE_STR DRIVE_X1 +#define DFU_STATUS_DRIVE_STR DRIVE_X1 +#define DWI_DRIVE_STR DRIVE_X1 +#define FMI_DRIVE_STR DRIVE_X2 // SecureROM is X2 +#define GRAPE_DRIVE_STR DRIVE_X1 +#define MLC_DRIVE_STR DRIVE_X1 +#define PM_BT_WAKE_DRIVE_STR DRIVE_X1 +#define PM_CAM_SHUTDOWN_DRIVE_STR DRIVE_X1 +#define CLK_CAM_DRIVE_STR DRIVE_X1 +#define PM_KEEPACT_DRIVE_STR DRIVE_X1 +#define RST_PMU_IN_DRIVE_STR DRIVE_X1 +#define SDIO_WL_DRIVE_STR DRIVE_X1 +#define VIDEO_AMP_EN_DRIVE_STR DRIVE_X1 +#define I2C_DRIVE_STR DRIVE_X1 +#define UART_5_DRIVE_STR DRIVE_X2 +#define I2S_DRIVE_STR DRIVE_X1 +#define I2S_MCK_DRIVE_STR DRIVE_X1 +#define SPI_CS_DRIVE_STR DRIVE_X1 +#define SPI_DATA_DRIVE_STR DRIVE_X1 + +/* Different drive strength for AP and DEV. // AP DEV */ +#if PIN_CFG_AP +#define BT_UART_DRIVE_STR DRIVE_X1 // X2 X3 +#define UART_0_DRIVE_STR DRIVE_X1 // X2 X3 +#else +#define BT_UART_DRIVE_STR DRIVE_X1 // X2 X3 +#define UART_0_DRIVE_STR DRIVE_X1 // X2 X2 +#endif + +#define FMI_SLEW_RATE SLEW_RATE_SLOW + +#if PIN_CFG_AP +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY (REQUEST_DFU1) + CFG_IN | PULL_UP, // GPIO2 -> VOL_UP_L + CFG_IN | PULL_UP, // GPIO3 -> VOL_DOWN_L + CFG_OUT_0, // GPIO4 -> ACC_UHPM_EN + CFG_IN | PULL_UP, // GPIO5 -> SPKR_AMP_INT_L + CFG_IN | PULL_DOWN, // GPIO6 -> WLAN_HSIC_OOB + CFG_OUT_0, // GPIO7 -> BT_WAKE + +/* Port 1 */ + CFG_OUT_0, // GPIO8 -> WLAN_HSIC_AP_RDY + CFG_IN | PULL_DOWN, // GPIO9 -> WLAN_HSIC_DEV_RDY + CFG_OUT_0, // GPIO10 -> STAYIN_ALIVE + CFG_OUT_1, // GPIO11 -> CAM_REAR_EXT_LDO_EN + CFG_OUT_1, // GPIO12 -> CAM_FRONT_EXT_LDO_EN + CFG_IN | PULL_UP, // GPIO13 -> IRQ_PMU_L + CFG_OUT_0, // GPIO14 -> GRAPE_RESET_L + CFG_OUT_0, // GPIO15 -> SPKR_AMP_RESET_L + +/* Port 2 */ + CFG_IN, // GPIO16 -> BOARD_ID_3 + CFG_IN, // GPIO17 -> BRD_REV3 + CFG_IN | PULL_DOWN, // GPIO18 -> BOOT_CONFIG_0 + CFG_OUT_0 | PM_KEEPACT_DRIVE_STR, // GPIO19 -> PM_KEEPACT + CFG_IN, // GPIO20 -> TRISTAR_INT + CFG_IN | PULL_UP, // GPIO21 -> GRAPE_INT_L + CFG_OUT_0 | GRAPE_DRIVE_STR, // GPIO22 -> LCD_RESET_L + CFG_IN, // GPIO23 -> LCD_HIFA_BSYNC + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN, // GPIO24 -> + CFG_IN | PULL_DOWN, // GPIO25 -> BOOT_CONFIG_1 + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_OUT_0 | DFU_STATUS_DRIVE_STR, // GPIO27 -> DFU_STATUS + CFG_IN, // GPIO28 -> BOOT_CONFIG_2 + CFG_IN, // GPIO29 -> BOOT_CONFIG_3 + CFG_IN | PULL_UP, // GPIO30 -> CODEC_INT_L + CFG_DISABLED | PULL_DOWN, // GPIO31 -> + +/* Port 4 */ + CFG_DISABLED | PULL_DOWN, // GPIO32 -> + CFG_IN, // GPIO33 -> IRQ_GYRO_INT1 + CFG_IN, // GPIO34 -> ACC_UHPM_POK + CFG_DISABLED | PULL_DOWN, // GPIO35 -> + CFG_IN, // GPIO36 -> ACCEL_INT2_L + CFG_IN, // EHCI_PORT_PWR[0] -> AP_GPIO37_BRD_REV0 + CFG_IN, // EHCI_PORT_PWR[1] -> AP_GPIO38_BRD_REV1 + CFG_IN, // EHCI_PORT_PWR[2] -> AP_GPIO39_BRD_REV2 + +/* Port 5 */ + CFG_FUNC0, // UART1_TXD -> UART1_TXD_AP_DBG + CFG_FUNC0, // UART1_RXD -> UART1_RXD_AP_DBG + CFG_DISABLED | PULL_DOWN, // UART1_RTSN -> + CFG_DISABLED | PULL_DOWN, // UART1_CTSN -> + CFG_FUNC0, // UART2_TXD -> UART2_TXD_ACC + CFG_FUNC0, // UART2_RXD -> UART2_RXD_ACC + CFG_IN, // UART2_RTSN -> CAM_STROBE_EN + CFG_DISABLED | PULL_DOWN, // UART2_CTSN -> + +/* Port 6 */ + CFG_FUNC0 | BT_UART_DRIVE_STR, // UART3_TXD -> UART_3_TXD_BT + CFG_FUNC0, // UART3_RXD -> UART_3_RXD_BT + CFG_OUT_1 | BT_UART_DRIVE_STR, // UART3_RTSN -> UART_3_CTS_L_BT + CFG_FUNC0, // UART3_CTSN -> UART_3_RTS_L_BT + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // I2C1_SDA -> + CFG_DISABLED | PULL_DOWN, // I2C1_SCL -> + +/* Port 7 */ + CFG_FUNC0 | I2C_DRIVE_STR, // ISP0_SDA -> I2C_CAM_REAR_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // ISP0_SCL -> I2C_CAM_REAR_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // ISP1_SDA -> I2C_FRONT_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // ISP1_SCL -> I2C_FRONT_SCL_1V8 + CFG_DISABLED | PULL_DOWN, // UART5_TXD/MIPI_VSYNC -> + CFG_FUNC0 | PULL_DOWN, // TMR32_PWM0 -> GYRO_INT2 + CFG_FUNC0 | PULL_DOWN, // TMR32_PWM1 -> ACCEL_INT1_L + CFG_FUNC0 | GRAPE_DRIVE_STR, // TMR32_PWM2 -> CLK32K_GRAPE_CLK + +/* Port 8 */ + CFG_DISABLED | PULL_DOWN, // SWI_DATA -> + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DI -> DWI_AP_DI + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> DWI_AP_DO + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> DWI_AP_CLK + CFG_OUT_1 | PM_CAM_SHUTDOWN_DRIVE_STR, // SENSOR0_RST -> PM_REAR_CAM_SHUTDOWN_L + CFG_OUT_0 | CLK_CAM_DRIVE_STR, // SENSOR0_CLK -> CLK_CAM_RF + CFG_OUT_1 | PM_CAM_SHUTDOWN_DRIVE_STR, // SENSOR1_RST -> PM_FRONT_CAM_SHUTDOWN + CFG_OUT_0 | CLK_CAM_DRIVE_STR, // SENSOR1_CLK -> CLK_CAM_FF + +/* Port 9 */ + CFG_OUT_0, // ISP0_PRE_FLASH -> CAM_REAR_TORCH + CFG_DISABLED | PULL_DOWN, // ISP0_FLASH -> CAM_REAR_RESET_L + CFG_DISABLED | PULL_DOWN, // ISP1_PRE_FLASH -> + CFG_DISABLED | PULL_DOWN, // ISP1_FLASH -> CAM_FRONT_RESET_L + CFG_FUNC0 | I2S_MCK_DRIVE_STR, // I2S0_MCK -> I2S_AP_0_MCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> I2S_AP_0_LRCK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_SCLK -> I2S_AP_0_BCLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> I2S_AP_0_DOUT + +/* Port 10 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DIN -> I2S_AP_0_DIN + CFG_DISABLED | PULL_DOWN, // I2S1_MCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_LRCK -> BT_PCM_SYNC + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_SCLK -> BT_PCM_CLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_DOUT -> BT_PCM_IN + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_DIN -> BT_PCM_OUT + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_MCK -> SPKR_AMP_PCM_MCLK_R + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> SPKR_AMP_PCM_FSYNC_R + +/* Port 11 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> SPKR_AMP_PCM_BITCLK_R + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> SPKR_AMP_PCM_DOUT_R + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DIN -> SPKR_AMP_PCM_DIN_R + CFG_DISABLED | PULL_DOWN, // I2S3_MCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> CODEC_XSP_MCLK_R + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> CODEC_XSP_FSYNC_R + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> CODEC_XSP_DOUT_R + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DIN -> CODEC_XSP_DIN_R + +/* Port 12 */ + CFG_IN, // SPI0_SCLK -> BOARD_ID_0 + CFG_IN, // SPI0_MOSI -> BOARD_ID_1 + CFG_IN, // SPI0_MISO -> BOARD_ID_2 + CFG_OUT_1, // SPI0_SSIN -> LCD_PIFA_R + CFG_FUNC0 | SPI_DATA_DRIVE_STR, // SPI1_SCLK -> SPI_GRAPE_SCLK + CFG_FUNC0 | SPI_DATA_DRIVE_STR, // SPI1_MOSI -> SPI_GRAPE_MOSI + CFG_FUNC0, // SPI1_MISO -> SPI_GRAPE_MISO + CFG_FUNC0 | SPI_CS_DRIVE_STR, // SPI1_SSIN -> SPI_GRAPE_CS_L + +/* Port 13 */ + CFG_FUNC0, // SPI2_SCLK -> SPI_CODEC_CLK + CFG_FUNC0, // SPI2_MOSI -> SPI_CODEC_MOSI + CFG_FUNC0, // SPI2_MISO -> SPI_CODEC_MISO + CFG_FUNC0, // SPI2_SSIN -> SPI_CODEC_SSN + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + +/* Port 14 */ + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + +/* Port 15 */ + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + +/* Port 16 */ + CFG_FUNC0 | MLC_DRIVE_STR, // UART4_TXD -> WLAN_DBG_UART_RXD + CFG_FUNC0 | MLC_DRIVE_STR, // UART4_RXD -> WLAN_DBG_UART_TXD + CFG_DISABLED | PULL_DOWN, // UART4_RTSN -> + CFG_OUT_0, // UART4_CTSN -> PMU_AMUX_AY_CTRL + CFG_DISABLED | PULL_DOWN, // SDIO0_DATA3 -> + CFG_DISABLED | PULL_DOWN, // SDIO0_DATA2 -> + CFG_DISABLED | PULL_DOWN, // SDIO0_DATA1 -> + CFG_DISABLED | PULL_DOWN, // SDIO0_DATA0 -> + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN, // SDIO0_CMD -> + CFG_DISABLED | PULL_DOWN, // SDIO0_CLK -> + CFG_DISABLED | PULL_DOWN, // FMI0_CEN3 -> F0CE3_L + CFG_DISABLED | PULL_DOWN, // FMI0_CEN2 -> F0CE2_L + CFG_DISABLED | PULL_DOWN, // FMI0_CEN1 -> F0CE1_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN0 -> F0CE0_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CLE -> F0CLE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_ALE -> F0ALE + +/* Port 18 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_REN -> F0RE_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_WEN -> F0WE_L + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO7 -> F0AD<7> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO6 -> F0AD<6> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO5 -> F0AD<5> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO4 -> F0AD<4> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + +/* Port 19 */ + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + +/* Port 20 */ + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_DQS -> F0DQS + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO3 -> F0AD<3> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO2 -> F0AD<2> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO1 -> F0AD<1> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI0_IO0 -> F0AD<0> + CFG_DISABLED | PULL_DOWN, // FMI1_CEN3 -> + CFG_DISABLED | PULL_DOWN, // FMI1_CEN2 -> + CFG_DISABLED | PULL_DOWN, // FMI1_CEN1 -> + +/* Port 21 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN0 -> F1CE0_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CLE -> F1CLE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_ALE -> F1ALE + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_REN -> F1RE_L + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_WEN -> F1WE_L + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO7 -> F1AD<7> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO6 -> F1AD<6> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO5 -> F1AD<5> + +/* Port 22 */ + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO4 -> F1AD<4> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_DQS -> FMI1DQS + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO3 -> F1AD<3> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO2 -> F1AD<2> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO1 -> F1AD<1> + CFG_FUNC0 | FMI_DRIVE_STR | BUS_HOLD, // FMI1_IO0 -> F1AD<0> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + +/* Port 23 */ + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + +/* Port 24 */ + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SCL -> I2C2_SCL_1V8 + CFG_OUT_0, // UART0_TXD -> CAM_FLASH_EN + CFG_DISABLED | PULL_DOWN, // UART0_RXD -> + CFG_DISABLED | PULL_DOWN, // UART5_RTXD -> + CFG_DISABLED | PULL_DOWN, // DP_HPD -> + CFG_DISABLED | PULL_DOWN, // TST_CLKOUT -> + CFG_DISABLED | PULL_DOWN, // TST_STPCLK -> GND + +/* Port 25 */ + CFG_FUNC0 | RST_PMU_IN_DRIVE_STR, // WDOG -> RST_PMU_IN + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> + CFG_DISABLED | PULL_DOWN, // -> +}; + +#undef AUD_SPKRAMP_MUTE_L_DRIVE_STR +#undef DFU_STATUS_DRIVE_STR +#undef DWI_DRIVE_STR +#undef FMI_DRIVE_STR +#undef GRAPE_DRIVE_STR +#undef MLC_DRIVE_STR +#undef PM_BT_WAKE_DRIVE_STR +#undef PM_CAM_SHUTDOWN_DRIVE_STR +#undef CLK_CAM_DRIVE_STR +#undef PM_KEEPACT_DRIVE_STR +#undef RST_PMU_IN_DRIVE_STR +#undef SDIO_WL_DRIVE_STR +#undef VIDEO_AMP_EN_DRIVE_STR +#undef I2C_DRIVE_STR +#undef UART_5_DRIVE_STR +#undef I2S_DRIVE_STR +#undef I2S_MCK_DRIVE_STR +#undef SPI_CS_DRIVE_STR +#undef SPI_DATA_DRIVE_STR +#undef BT_UART_DRIVE_STR +#undef UART_0_DRIVE_STR +#undef FMI_SLEW_RATE diff --git a/target/n78/include/target/powerconfig.h b/target/n78/include/target/powerconfig.h new file mode 100644 index 0000000..8ec1935 --- /dev/null +++ b/target/n78/include/target/powerconfig.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H +#include + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +/* Matched to D1881B1-OTP-CD-v5 */ + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kD1881_LDO1, 0x0D }, // PP3V0_USB 3.15V + { PMU_IIC_BUS, kD1881_LDO2, 0x0A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1881_LDO3, 0x0A }, // PP3V0_IMU 3.00V + { PMU_IIC_BUS, kD1881_LDO4, 0x16 }, // PP3V0_OPTICAL 2.90V + { PMU_IIC_BUS, kD1881_LDO5, 0x0A }, // PP3V0_NAND 3.00V + { PMU_IIC_BUS, kD1881_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1881_LDO7, 0x0F }, // PP3V3_VIDEO 3.00V + { PMU_IIC_BUS, kD1881_LDO8, 0x14 }, // PP3V0_USBMUX 3.00V + { PMU_IIC_BUS, kD1881_LDO9, 0x01 }, // PP1V5_CAM_AVDD 1.30V + { PMU_IIC_BUS, kD1881_LDO10, 0x01 }, // PP2V8_CAM_AVDD 2.55V + { PMU_IIC_BUS, kD1881_LDO11, 0x02 }, // 1.80V + { PMU_IIC_BUS, kD1881_LDO12, 0x10 }, // PP1V1 1.00V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // no bypass +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1881_ACTIVE1, 0xBD }, // Everything except VBUCK1, LDO2 + { PMU_IIC_BUS, kD1881_ACTIVE2, 0xBB }, // LDO4, LDO5, LDO7, LDO8, LDO9, LDO11 enabled + { PMU_IIC_BUS, kD1881_ACTIVE3, 0x2F }, // LDO12 + { PMU_IIC_BUS, kD1881_ACTIVE4, 0xE0 }, // CPU1V8 & CPU1V2 on, WDIG off + { PMU_IIC_BUS, kD1881_LCM_CONTROL1, 0x02 }, // PP5V1_GRAPE_VDDH 5.10V + { PMU_IIC_BUS, kD1881_LCM_CONTROL2, 0x0E }, // PP5V7_LCD_AVDDH 5.70V + { PMU_IIC_BUS, kD1881_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1881_LCM_BST_CONTROL, 0x1A }, // PP6V3_LCM_VBOOST 6.30V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + /* Note: the following differences from OTP are intentional: + - GPIO 5: Enable CLK32k + - GPIO 8: Enable Codec (Mikey) Wake + - GPIO 7: Enable WiFi Wake + - GPIO 10: Enable Wake amd Pull-Up + */ + { PMU_IIC_BUS, kD1881_SYS_GPIO_1, 0xB9 }, // CLK32K_GRAPE In, R Edge, No Wake, No PU + // Clock is enabled by AppleARMFunction default + { PMU_IIC_BUS, kD1881_SYS_GPIO_2, 0x09 }, // BB_WAKE_AP -- NC + { PMU_IIC_BUS, kD1881_SYS_GPIO_3, 0x09 }, // BB_PMU_FET_ON -- NC + { PMU_IIC_BUS, kD1881_SYS_GPIO_4, 0xBA }, // TRISTAR_INT In, R Edge, Wake, No PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_5, 0x49 }, // CLK32K_WIFI Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_6, 0x09 }, // BATTERY_SWI -- NC + { PMU_IIC_BUS, kD1881_SYS_GPIO_7, 0xBB }, // WLAN_HOST_WAKE In, R Edge, Wake, PD, No PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_8, 0xEA }, // CODEC_HOST_WAKE_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_9, 0x09 }, // BT_REG_ON Out 1, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_10, 0xBA }, // BT_HOST_WAKE In, R Edge, Wake, PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_11, 0x09 }, // WIFI_REG_ON Out 0, Push-Pull, VBUCK3 + + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB1, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB2, 0x02 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB3, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB4, 0x00 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB5, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB6, 0x02 }, + + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // enable HIB_32kHz (for WIFI/BT); DWI disabled + + // turn off buck4 negative current limit + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x01 }, // set bank1 + { PMU_IIC_BUS, kD1881_TEST_MODE, 0x01 }, // enter test mode + { PMU_IIC_BUS, 0xCB, 0x23 }, // turn off negative current limit + { PMU_IIC_BUS, kD1881_TEST_MODE, 0x00 }, // exit test mode + { PMU_IIC_BUS, kDIALOG_BANKSEL, 0x00 }, // set bank0 +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xC8 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x01 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable LED Power + (kDIALOG_WLED_CONTROL_WLED_ENABLE2 | kDIALOG_WLED_CONTROL_WLED_ENABLE1 | kDIALOG_WLED_CONTROL_WLED_RAMP_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) + +#if WITH_HW_TRISTAR +extern bool n78_get_e75(void); +#define TARGET_IGNORE_TRISTAR (!n78_get_e75()) +#define TARGET_BRICKID_FULL_SCALE (5000 * (n78_get_e75() ? 1 : 3)) +#else +#define TARGET_BRICKID_FULL_SCALE (5000 * 3) // H5P has resistor divider for USB monitor +#endif +#define ACC_PWR_LDO (6) + +#endif diff --git a/target/n78/include/target/uartconfig.h b/target/n78/include/target/uartconfig.h new file mode 100644 index 0000000..606b3bb --- /dev/null +++ b/target/n78/include/target/uartconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (1) + +#endif diff --git a/target/n78/include/target/usbconfig.h b/target/n78/include/target/usbconfig.h new file mode 100644 index 0000000..e3fcbcf --- /dev/null +++ b/target/n78/include/target/usbconfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_USBCONFIG_H +#define __TARGET_USBCONFIG_H + +#ifdef USBPHY_UOTGTUNE1 + +#undef USBPHY_UOTGTUNE1 +#define USBPHY_UOTGTUNE1 (0x749) + +#endif /* USBPHY_UOTGTUNE1 */ + +#ifdef USBPHY_UOTGTUNE2 + +#undef USBPHY_UOTGTUNE2 +#define USBPHY_UOTGTUNE2 (0x2FF3) + +#endif /* USBPHY_UOTGTUNE2 */ + + +#endif /* __TARGET_USBCONFIG_H */ diff --git a/target/n78/init.c b/target/n78/init.c new file mode 100644 index 0000000..5985e66 --- /dev/null +++ b/target/n78/init.c @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2011-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// BRD_REV3 is pulled down to 0 until EVT3, but we are inverting its value +#define N78_PROTO0A_BOARD (15) +#define N78_PROTO0B_BOARD (13) +#define N78_PROTO1_BOARD (12) +#define N78_EVT1_BOARD (9) +#define N78_EVT2_BOARD (8) +// Starting with EVT3, BRD_REV3 is pulled up to 1, but we are inverting its value +#define N78_EVT3_BOARD (7) + +static u_int32_t n78_get_board_rev(void); + +static uint32_t display_config; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + // N78 LDO7 needs to be off for units older than EVT3 + // NOTE: A board is EARLIER than an EVT3, because its board ID is larger (according to #defines above) + if (n78_get_board_rev() > N78_EVT3_BOARD) { + + unsigned int i; + + const uint8_t pmu_data[] = { + 0x21, 0xB3, // kD1881_ACTIVE2: LDO4, LDO5, LDO8, LDO9, LDO11 enabled + }; + + for (i = 0; i < sizeof(pmu_data); i += 2) + iic_write(0, 0xe8, &pmu_data[i], 2); + } +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000964; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "n41", 0); +} + +bool n78_get_e75(void) +{ + return env_get_uint("e75", n78_get_board_rev() != N78_PROTO0A_BOARD) != 0; +} + +#endif + +static bool gpio_board_rev_valid; +static u_int32_t gpio_board_rev; + +static u_int32_t n78_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + uint32_t brd_rev3_inverted = (gpio_read(GPIO_BOARD_REV3) ? 0UL : 1UL); + gpio_board_rev = + (brd_rev3_inverted << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if WITH_HW_DISPLAY_PINOT + DTNode *clcd_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize, propCnt; + char *propName; + void *propData; + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + } + +#if WITH_HW_DISPLAY_PINOT + // Find the CLCD node + FindNode(0, "arm-io/clcd", &clcd_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, clcd_node, backlight_node); + } +#endif + + + // Update the backlight calibration data + if (FindNode(0, "backlight", &node)) { + propName = "backlight-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('BLCl', propData, propSize); + } + } + + // Update als node with calibration data + if (FindNode(0, "arm-io/i2c2/als", &node)) { + propName = "backlight-leakage-channel0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC0', propData, propSize); + } + propName = "backlight-leakage-channel1"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ALC1', propData, propSize); + } + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AICl', propData, propSize); + } + } + + // Updte the speaker calibration data + if (FindNode(0, "arm-io/i2c0/audio-speaker", &node)) { + propName = "speaker-rdc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('SRdc', propData, propSize); + } + propName = "speaker-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + uint8_t vpbr; + if (syscfgCopyDataForTag('VPBR', &vpbr, sizeof(vpbr)) == 1) { + ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vpbr & 0x1f); + } + uint8_t vbst; + if (syscfgCopyDataForTag('VBST', &vbst, sizeof(vbst)) == 1) { + ((uint8_t *)propData)[16] = vbst; + } + } + } + + + if (FindNode(0, "product", &node)) { + + // N78a: If the NoBC syscfg key present, and it have bit 0 set + uint32_t sysCfgData; + int result = syscfgCopyDataForTag('NoBC', (uint8_t *)(&sysCfgData), sizeof(sysCfgData)); + + int isn78a = 0; + if (result == sizeof(sysCfgData) && (sysCfgData & 0x1) ) isn78a = 1; + + // this isn't an N78a, so get rid of the n78a-mode property + propName = "n78a-mode"; + if (isn78a==0 && FindProperty(node, &propName, &propData, &propSize) ) propName[0] = '~'; + + if (isn78a && FindNode(0, "product/camera", &node)) { + // isp/camera-rear and other product/camera rear camera related properties + // will be deleted by common code in lib/macho/dt.c. + // Here, remove the product/camera/auto-focus entry + propName = "auto-focus"; + if (FindProperty(node, &propName, &propData, &propSize) ) { + propName[0] = '~'; + } + + propName = "rear-hdr-on"; + if (FindProperty(node, &propName, &propData, &propSize) ) { + //n78a: set rear-hdr-on to 0 + memset(propData, 0, propSize ); + } + + propName = "rear-burst-image-duration"; + if (FindProperty(node, &propName, &propData, &propSize) ) { + //n78a: set rear-burst-image-duration to 0 + memset(propData, 0, propSize ); + } + } + } + + // if E75 config, reconfigure everything + if (n78_get_e75()) { + // enable uart2 + if (FindNode(0, "arm-io/uart2", &node)) { + propName = "AAPL,ignore"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + + // reconfigure uart1 + if (FindNode(0, "arm-io/uart1/iap", &node)) { + propName = "name"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "debug-console", kPropNameLength); + } + propName = "function-dock_parent"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + + // enable tristar + uint32_t tristarPHandle = -1; + if (FindNode(0, "arm-io/i2c0/tristar", &node)) { + propName = "AAPL,ignore"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "AAPL,phandle"; + if (FindProperty(node, &propName, &propData, &propSize)) { + tristarPHandle = *(uint32_t *)propData; + } + } + + // disconnect BRICK_ID from USB + if (FindNode(0, "arm-io/otgphyctrl", &node)) { + propName = "function-dmon_voltage"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + } + + // change dock from 30-pin to 9-pin + uint32_t dockPHandle = -1; + if (FindNode(0, "dock", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propData, "dock,9pin", kPropNameLength); + } + propName = "function-read_acc"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-acc_detect"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "interrupt-parent"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "interrupts"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "AAPL,phandle"; + if (FindProperty(node, &propName, &propData, &propSize)) { + dockPHandle = *(uint32_t *)propData; + } + } + + // use TriStar for brick detect + if (FindNode(0, "charger", &node)) { + propName = "function-usb_dmonitor"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = tristarPHandle; + } + } + } + + // pre-EVT1 Grape clock config + if (n78_get_board_rev() > N78_EVT1_BOARD) { + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "function-clock_enable"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-clock_enable-pmu"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[21] = '\0'; + } + } + + // configure PMU GPIO1 to be Grape clock (off until enabled) + // configure SoC PWM2 to be disabled + power_gpio_configure(0, 0x09); + gpio_configure(GPIO(7, 7), GPIO_CFG_IN); + } + + // pre-EVT2 codec config + if (n78_get_board_rev() > N78_EVT2_BOARD) { + if (FindNode(0, "arm-io/spi2/audio-codec", &node)) { + propName = "class-h-control"; + if (FindProperty(node, &propName, &propData, &propSize)) { + ((uint32_t *)propData)[0] = 0; + } + } + } + + return 0; +} + +#endif diff --git a/target/n78/pinconfig.c b/target/n78/pinconfig.c new file mode 100644 index 0000000..0ff6f3c --- /dev/null +++ b/target/n78/pinconfig.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/n78/rules.mk b/target/n78/rules.mk new file mode 100644 index 0000000..5ad9733 --- /dev/null +++ b/target/n78/rules.mk @@ -0,0 +1,44 @@ +# Copyright (C) 2010-2012 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1881=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_MED \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_CPU_SOURCE=2 \ + TARGET_MIPI_DSI_SOURCE=1 \ + TARGET_MANAGED2H_SOURCE=0 \ + TARGET_MANAGED2L_SOURCE=0 \ + TARGET_MANAGED2H_DIV=1 \ + TARGET_MANAGED2L_DIV=2 \ + TARGET_PCLK1_SOURCE=1 \ + TARGET_PCLK1_DIV=4 \ + TARGET_GFX_SOURCE=2 \ + TARGET_GFX_SLC_SOURCE=3 \ + TARGET_IOP_SOURCE=3 \ + TARGET_LPERFS_SOURCE=3 \ + TARGET_HPERFNRT_SOURCE=0 \ + TARGET_USE_HSIC=1 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_DPHYCTL=0x30 \ + TARGET_DSIM_SUPPRESS=0x1 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci/wlan\" \ + WITH_TARGET_USB_CONFIG=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/n94/include/target/gpiodef.h b/target/n94/include/target/gpiodef.h new file mode 100644 index 0000000..7c648ff --- /dev/null +++ b/target/n94/include/target/gpiodef.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* N94 specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#define GPIO_LCD_RST GPIO( 2, 6) +#define GPIO_LCD_RST_POLARITY (0) +#define GPIO_LCD_CHKSUM GPIO( 2, 7) + +#define GPIO_RINGER_AB GPIO( 0, 4) + +/* Board Revision */ +#define GPIO_BOARD_REV0 GPIO( 5, 0) +#define GPIO_BOARD_REV1 GPIO( 5, 1) +#define GPIO_BOARD_REV2 GPIO( 5, 2) +#define GPIO_BOARD_REV3 GPIO(27, 0) + +/* radio gpios */ +#define GPIO_WLAN_RESET GPIO( 0, 6) +#define GPIO_BT_RESET GPIO( 1, 0) + +#define POWER_GPIO_BATTERY_SWI (5) +#define POWER_GPIO_BATTERY_SWI_CONFIG_OUTPUT 0x03 +#define POWER_GPIO_BATTERY_SWI_CONFIG_INPUT 0xD8 + +/* which IICs to initialize */ +#define IICS_MASK (7) + +/* D1881 watchdog tickle, 'KEEPACT' */ +#define GPIO_WDOG_TICKLE GPIO(2, 3) + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/n94/include/target/nand_spec_tables.h b/target/n94/include/target/nand_spec_tables.h new file mode 100644 index 0000000..d822122 --- /dev/null +++ b/target/n94/include/target/nand_spec_tables.h @@ -0,0 +1,92 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000F0F + }, + + /* useToggleMode */ FALSE32, + /* useDiffDQSMode */ FALSE32, + /* useDiffREMode */ FALSE32, + /* useVref */ FALSE32, + /* useSingleHostChannel */ FALSE32, + /* allowSingleChipEnable */ TRUE32 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 4096 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/n94/include/target/powerconfig.h b/target/n94/include/target/powerconfig.h new file mode 100644 index 0000000..d73cae3 --- /dev/null +++ b/target/n94/include/target/powerconfig.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010-2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +/* Matched to D1881A3-OTP-AO-v4 */ + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ + { PMU_IIC_BUS, kD1881_LDO1, 0x0D }, // PP3V0_USB 3.15V + { PMU_IIC_BUS, kD1881_LDO2, 0x0A }, // PP1V7_VA_VCP 1.70V + { PMU_IIC_BUS, kD1881_LDO3, 0x0A }, // PP3V0_IMU 3.00V + { PMU_IIC_BUS, kD1881_LDO4, 0x18 }, // PP3V0_OPTICAL 3.00V + { PMU_IIC_BUS, kD1881_LDO5, 0x0A }, // PP3V0_NAND 3.00V + { PMU_IIC_BUS, kD1881_LDO6, 0x10 }, // PP3V3_ACC 3.30V + { PMU_IIC_BUS, kD1881_LDO7, 0x0F }, // PP3V3_VIDEO 3.00V + { PMU_IIC_BUS, kD1881_LDO8, 0x14 }, // PP3V0_USBMUX 3.00V + { PMU_IIC_BUS, kD1881_LDO9, 0x12 }, // PP3V0_IO 3.00V + { PMU_IIC_BUS, kD1881_LDO10, 0x06 }, // PP2V8_CAM_AVDD 2.80V + { PMU_IIC_BUS, kD1881_LDO11, 0x16 }, // PP2V8_CAM_AF 2.80V + { PMU_IIC_BUS, kD1881_LDO12, 0x14 }, // PP1V1 1.10V + { PMU_IIC_BUS, kDIALOG_LDO_CONTROL, 0x00 }, // no bypass +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD1881_ACTIVE1, 0xFD }, // Everything except VBUCK1 + { PMU_IIC_BUS, kD1881_ACTIVE2, 0xFB }, // Everything except LDO6 + { PMU_IIC_BUS, kD1881_ACTIVE3, 0x2B }, // WLED_BST, LCM_BST, LDO_LCM2, LDO12 + { PMU_IIC_BUS, kD1881_ACTIVE4, 0xA0 }, // CPU1V8 & CPU1V2 on, WDIG off + { PMU_IIC_BUS, kD1881_LCM_CONTROL1, 0x02 }, // PP5V1_GRAPE_VDDH 5.10V + { PMU_IIC_BUS, kD1881_LCM_CONTROL2, 0x0E }, // PP5V7_LCD_AVDDH 5.70V + { PMU_IIC_BUS, kD1881_LCM_CONTROL3, 0x00 }, // BB_VBUS_DET 5.00V + { PMU_IIC_BUS, kD1881_LCM_BST_CONTROL, 0x14 }, // PP6V0_LCM_VBOOST 6.00V +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ + { PMU_IIC_BUS, kDIALOG_ADC_CONTROL, kDIALOG_ADC_CONTROL_DEFAULTS }, +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kDIALOG_BUCK_CONTROL1, 0x0a }, // buck0 sync mode, 1.25A limit per phase + { PMU_IIC_BUS, kDIALOG_BUCK_CONTROL3, 0x0e }, // buck2 sync mode, 1.55A limit per phase + + /* Note: the following differences from OTP are intentional: + - GPIO2,6,7,8,10 enable wake + - GPIO5 enables CLK32 + - GPIO8 interrupt type + - GPIO9 asserted + - GPIO6,8 no debounce + */ + { PMU_IIC_BUS, kD1881_SYS_GPIO_1, 0x11 }, // CLK32K_GRAPE Out 0, Push-Pull, CPU_1V8 + // Clock is enabled by AppleARMFunction default + { PMU_IIC_BUS, kD1881_SYS_GPIO_2, 0xBA }, // BB_WAKE_AP In, R Edge, Wake, No PU or PD + { PMU_IIC_BUS, kD1881_SYS_GPIO_3, 0x09 }, // BB_PMU_FET_ON Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_4, 0x09 }, // DOCK_BB_USB_SEL Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_5, 0x49 }, // CLK32K_WIFI Out 0, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_6, 0xDA }, // BATTERY_SWI In, F Edge, Out Hib, Wake, PD, No PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_7, 0xBB }, // WLAN_WAKE_AP In, R Edge, Wake, PD, No PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_8, 0xEA }, // MIKEY_INT_L In, Any Edge, Wake, PU, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_9, 0x0B }, // BT_REG_ON Out 1, Push-Pull, VBUCK3 + { PMU_IIC_BUS, kD1881_SYS_GPIO_10, 0xBB }, // BT_WAKE_AP In, R Edge, Wake, PD, No PU + { PMU_IIC_BUS, kD1881_SYS_GPIO_11, 0x09 }, // WIFI_REG_ON Out 0, Push-Pull, VBUCK3 + + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB1, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB2, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB3, 0x02 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB4, 0x02 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB5, 0x12 }, + { PMU_IIC_BUS, kD1881_SYS_GPIO_DEB6, 0x02 }, + + { PMU_IIC_BUS, kDIALOG_SYS_CONTROL2, 0x10 }, // enable HIB_32kHz (for WIFI/BT); DWI disabled +}; + +static const struct pmu_setup_struct pmu_backlight_enable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_ISET, 0xC8 }, // 50% value from OS + { PMU_IIC_BUS, kDIALOG_WLED_ISET2, 0x01 }, + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, // enable LED Power + (kDIALOG_WLED_CONTROL_WLED_ENABLE1 | kDIALOG_WLED_CONTROL_WLED_RAMP_EN | + kDIALOG_WLED_CONTROL_WLED_DITH_EN) } +}; + +static const struct pmu_setup_struct pmu_backlight_disable[] = +{ + { PMU_IIC_BUS, kDIALOG_WLED_CONTROL, 0x0 } // disable LED power +}; + +static const struct core_rails_struct soc_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK2 } +}; + +static const struct core_rails_struct cpu_rails[] = +{ + { PMU_IIC_BUS, 0, kDIALOG_BUCK0 } +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 50 +#define PRECHARGE_BACKLIGHT_LEVEL 824 + +#define TARGET_DISPLAY_VOLTAGE_BASE 6000 +#define TARGET_DISPLAY_VOLTAGE_SCALE 50 +#define TARGET_DISPLAY_BOOST_LDO kD1881_LCM_CONTROL2 +#define TARGET_DISPLAY_BOOST_OFFSET 300 + +#endif diff --git a/target/n94/include/target/radioconfig.h b/target/n94/include/target/radioconfig.h new file mode 100644 index 0000000..32c21ff --- /dev/null +++ b/target/n94/include/target/radioconfig.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_RADIOCONFIG_H +#define __TARGET_RADIOCONFIG_H + +/* configuration per target */ + +#define RADIO_VERIFY_BASEBAND_EXISTS 1 + +static const gpio_t target_radio_quiesce_pins[] = +{ + GPIO_UART1_TXD +}; + +#define RADIO_ENABLE_IMEI_OVERRIDE 0 + +#endif /* ! __TARGET_RADIOCONFIG_H */ diff --git a/target/n94/include/target/uartconfig.h b/target/n94/include/target/uartconfig.h new file mode 100644 index 0000000..4b29946 --- /dev/null +++ b/target/n94/include/target/uartconfig.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +/* define radio serial port */ +#define RADIO_SERIAL_PORT (1) +#define RADIO_MAX_READ_ERRORS (10) + +/* define HDQ serial port */ +#define HDQGAUGE_SERIAL_PORT (5) + +#define UART_FLOWCONTROL_MASK (0x08) + +#endif diff --git a/target/n94/init.c b/target/n94/init.c new file mode 100644 index 0000000..40cab95 --- /dev/null +++ b/target/n94/init.c @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2010-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// These are sequential revision numbers, reordered from the hardware straps +#define N94_ILLEGAL_BOARD (255) +#define N94_PROTO1_BOARD (10) +#define N94_PROTO1a_BOARD (9) +#define N94_PROTO2_BOARD (8) +#define N94_PROTO3_BOARD (7) +#define N94_PROTO3a_BOARD (6) +#define N94_EVT1_BOARD (5) +#define N94_EVT1a_BOARD (4) +#define N94_EVT2_BOARD (3) +#define N94_DVT_BOARD (2) +#define N94_PVT_BOARD (1) +#define N94_PRQ_BOARD (0) + +// Convert the 4-bit hardware board rev to a monotonic software rev +static u_int8_t hw_rev_to_sw[] = { + N94_PRQ_BOARD, + N94_DVT_BOARD, + N94_EVT1_BOARD, + N94_PROTO3a_BOARD, // also DEV3a, N78 D300 DEV + N94_PROTO3_BOARD, // also PreProto3, DEV3 + N94_PROTO2_BOARD, + N94_PROTO1_BOARD, // and DEV2 + N94_PROTO1a_BOARD, // and DEV1 + N94_PVT_BOARD, + N94_ILLEGAL_BOARD, + N94_ILLEGAL_BOARD, + N94_ILLEGAL_BOARD, + N94_ILLEGAL_BOARD, + N94_ILLEGAL_BOARD, + N94_EVT2_BOARD, // and DEV4 (probably) + N94_EVT1a_BOARD, +}; + +static u_int32_t n94_get_board_rev(void); + +static u_int32_t display_config; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ + // OTP-AO matching code for TellurideNanshan DVT: + if (N94_DVT_BOARD == n94_get_board_rev()) { + uint8_t pmu_setup[][2] = { + // buck0 and buck2 controls are set in powerconfig.h for all revs + { 0x18, 0x01 }, // BANKSEL=1 + { 0xe0, 0x01 }, // Enable test mode + { 0xa9, 0x48 }, // 0us blanking time + { 0xd2, 0x33 }, // 0-180 phasing + { 0xa3, 0xa2 }, // reduce charger headroom by 50mV + { 0xe0, 0x00 }, // Disable test mode + { 0x18, 0x00 }, // BANKSEL=0 + }; + int entries = sizeof(pmu_setup) / (2*sizeof(uint8_t)), index; + for (index = 0; index < entries; index++) + iic_write(0, 0xe8, pmu_setup[index], 2); + } +} + +void target_late_init(void) +{ + if (target_config_dev()) { + if (n94_get_board_rev() >= N94_PROTO2_BOARD) + platform_not_supported(); + } else { + if (n94_get_board_rev() >= N94_EVT1_BOARD) + platform_not_supported(); + } +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif + + // All AP and PMU GPIOS for the radios are set by pinconfig.h + // and powerconfig.h. While the AP settings are compatible with wake, + // the BB PMU will be in reset thanks to powerconfig.h providing + // dedicated cold boot settings. The AppleARMFunctions in the device + // tree will take care of the rest for a cold boot. +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + switch (target) { + case BOOT_DARWIN: + case BOOT_DARWIN_RESTORE: + case BOOT_DIAGS: + break; + + default: + ; // do nothing + } + + return 0; +} + +bool target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if APPLICATION_IBOOT +void target_watchdog_tickle(void) +{ + u_int32_t value = gpio_read(GPIO_WDOG_TICKLE); + gpio_write(GPIO_WDOG_TICKLE, value ^ 1); +} +#endif // APPLICATION_IBOOT + +void * target_get_display_configuration(void) +{ + display_config = 0x00000963; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-device", "nand0", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "n94", 0); +} + +#endif + +u_int32_t target_lookup_backlight_cal(int index) +{ + return (index == 2) ? 0x09 : 0; +} + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ + u_int32_t board_rev = n94_get_board_rev(); + +#if WITH_HW_DISPLAY_PINOT + DTNode *clcd_node, *backlight_node; +#endif + DTNode *node; + uint32_t propSize, propCnt; + char *propName; + void *propData; + + // Update the DWI node with the actual voltages + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "voltages-buck0"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_cpu_voltages(propCnt, propData); + platform_convert_voltages(0, propCnt, propData); + } + propName = "voltages-buck2"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propCnt = propSize / sizeof(u_int32_t); + platform_get_soc_voltages(propCnt, propData); + platform_convert_voltages(2, propCnt, propData); + } + } + +#if WITH_HW_DISPLAY_PINOT + // Find the CLCD node + FindNode(0, "arm-io/clcd", &clcd_node); + + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); + + FindNode(0, "backlight", &backlight_node); + pinot_update_device_tree(node, clcd_node, backlight_node); + } +#endif + + if (board_rev > N94_EVT1a_BOARD) + { + // old headset circutry + if (FindNode(0, "arm-io/i2c0/headset-switch", &node)) { + propName = "function-ext_switch"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "unused-ext_switch", kPropNameLength); + } + } + if (FindNode(0, "arm-io/i2c0/audio0", &node)) { + propName = "unused-hpout_ref_control"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-hpout_ref_control", kPropNameLength); + } + } + } + else if (board_rev > N94_EVT1_BOARD) + { + // old headset circutry + if (FindNode(0, "arm-io/i2c0/headset-switch", &node)) { + propName = "switch-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = 0; + } + } + if (FindNode(0, "arm-io/i2c0/audio0", &node)) { + propName = "headphone-pop-workaround"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = 1; + } + } + } + else if (board_rev > N94_DVT_BOARD) + { + if (FindNode(0, "arm-io/i2c0/headset-switch", &node)) { + propName = "switch-config"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData = 0x1a; + } + } + } + + if (board_rev > N94_PRQ_BOARD) + { + if (FindNode(0, "arm-io/i2c0/audio0", &node)) { + propName = "headphone-pop-workaround"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t *)propData |= 0x8; + } + } + } + + if (board_rev > N94_PROTO3a_BOARD) { + // + if (FindNode(0, "arm-io/dwi", &node)) { + propName = "dwi-version"; + if (FindProperty(node, &propName, &propData, &propSize)) + ((u_int32_t *)propData)[0] = 0; + } + // Pulldown on BB_WAKE_AP, removed for + power_gpio_configure(1, 0xBB); + } + + // Update the highland-park node with acoustic transducer scale data + if (FindNode(0, "arm-io/highland-park", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ATSc', propData, propSize); + } + } + if (FindNode(0, "arm-io/i2c0/audio0", &node)) { + propName = "at-scale"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ATSc', propData, propSize); + } + } + + // Update the als calibration data + if (FindNode(0, "arm-io/i2c1/als", &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('AlsC', propData, propSize); + } + propName = "als-colorCfg"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ClrC', propData, propSize); + } + } + + // Update the compass calibration data + if (FindNode(0, "arm-io/i2c1/compass", &node)) { + propName = "compass-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CPAS', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update the gyro calibration data + if (FindNode(0, "arm-io/i2c2/gyro1", &node)) { + propName = "low-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTGO', propData, propSize); + } + propName = "high-temp-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('HTGO', propData, propSize); + } + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GSCl', propData, propSize); + } + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GYTT', propData, propSize); + } + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('GICl', propData, propSize); + } + } + + // Update accelerometer calibration data + if (FindNode(0, "arm-io/i2c2/accelerometer", &node)) { + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('LTAO', propData, propSize); + } + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('ASCl', propData, propSize); + } + } + + // Update prox calibration data + if (FindNode(0, "arm-io/spi1/multi-touch", &node)) { + propName = "prox-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('PxCl', propData, propSize); + } + } + + // Update charger calibration data + if (FindNode(0, "charger", &node)) { + propName = "usb-input-limit-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + syscfgCopyDataForTag('CBAT', propData, propSize); + } + } + + return 0; +} + +#endif + +static u_int32_t n94_get_board_rev(void) +{ + u_int32_t gpio_board_rev; + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + // Convert and sanity-check + gpio_board_rev = hw_rev_to_sw[gpio_board_rev & 0xf]; + if (N94_ILLEGAL_BOARD == gpio_board_rev) + panic("Illegal board revision"); + + return (gpio_board_rev); +} diff --git a/target/n94/pinconfig.c b/target/n94/pinconfig.c new file mode 100644 index 0000000..accd4a0 --- /dev/null +++ b/target/n94/pinconfig.c @@ -0,0 +1,654 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* Default N94 Hardware Pin Configuration - Proto3A */ + +#define BB_UART_DRIVE_STR DRIVE_X3 +#define UMTS_DRIVE_STR DRIVE_X3 +#define BT_UART_DRIVE_STR DRIVE_X3 +#define SWI_UART_DRIVE_STR DRIVE_X3 +#define GPS_UART_DRIVE_STR DRIVE_X3 +#define FMI_DRIVE_STR DRIVE_X3 +#define GRAPE_DRIVE_STR DRIVE_X3 +#define BB_SPI_DRIVE_STR DRIVE_X3 +#define I2C_DRIVE_STR DRIVE_X3 +#define CAM_CLK_DRIVE_STR DRIVE_X3 +#define I2S_DRIVE_STR DRIVE_X3 +#define DOCK_UART_DRIVE_STR DRIVE_X3 +#define IPC_DRIVE_STR DRIVE_X3 + +#define CAM_I2C_DRIVE_STR DRIVE_X2 +#define CAM_STROBE_DRIVE_STR DRIVE_X2 +#define DWI_DRIVE_STR DRIVE_X2 +#define NOR_DRIVE_STR DRIVE_X2 + +static const u_int32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY_BUFF_L (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY_L (REQUEST_DFU1) + CFG_IN | PULL_UP, // GPIO2 -> VOL_DWN_L + CFG_IN | PULL_UP, // GPIO3 -> VOL_UP_L + CFG_IN, // GPIO4 -> RINGER_A + CFG_OUT_0, // GPIO5 -> SPKAMP_RESET_L + CFG_DISABLED, // GPIO6 -> + CFG_OUT_0, // GPIO7 -> BT_WAKE + +/* Port 1 */ + CFG_OUT_1, // GPIO8 -> BT_RESET_L + CFG_DISABLED, // GPIO9 -> + CFG_IN, // GPIO10 -> BB_RESET_L + CFG_IN | PULL_DOWN, // GPIO11 -> BB_RESET_DET_L + CFG_IN | PULL_DOWN, // GPIO12 -> IPC_SRDY + CFG_IN | PULL_UP, // GPIO13 -> PMU_IRQ_L + CFG_IN, // GPIO14 -> RADIO_ON_L + CFG_IN, // GPIO15 -> RESET_BB_PMU_L + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_IN | PULL_DOWN, // GPIO17 -> BB_HSIC_RDY + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_OUT_0, // GPIO19 -> KEEPACT + CFG_IN, // GPIO20 -> BB_EMERGENCY_DWLD_L + CFG_IN | PULL_UP, // GPIO21 -> GRAPE_INT_L + CFG_OUT_0, // GPIO22 -> LCD_RESET_L + CFG_IN | PULL_UP, // GPIO23 -> LCD_HIFA + +/* Port 3 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_IN | PULL_UP, // GPIO30 -> CODEC_INT_L + CFG_IN, // GPIO31 -> WLAN_HSIC_RDY + +/* Port 4 */ + CFG_IN | PULL_DOWN, // GPIO32 -> GYRO_INT2 + CFG_IN | PULL_DOWN, // GPIO33 -> GYRO_INT + CFG_IN | PULL_DOWN, // GPIO34 -> COMPASS_BRD_INT + CFG_DISABLED, // GPIO35 -> + CFG_IN | PULL_UP, // GPIO36 -> ACCEL_INT1_L + CFG_IN | PULL_UP, // GPIO37 -> ACCEL_INT2_L + CFG_IN | PULL_UP, // GPIO38 -> ALS_INT_L + CFG_OUT_0, // GPIO39 -> GRAPE_RESET_L + +/* Port 5 */ + CFG_DISABLED, // EHCI_PORT_PWR[0] -> BOARD_REV[0] + CFG_DISABLED, // EHCI_PORT_PWR[1] -> BOARD_REV[1] + CFG_DISABLED, // EHCI_PORT_PWR[2] -> BOARD_REV[2] + CFG_IN | BB_UART_DRIVE_STR, // UART1_TXD -> (BB USART) + CFG_FUNC0, // UART1_RXD -> + CFG_FUNC0 | BB_UART_DRIVE_STR, // UART1_RTSN -> + CFG_FUNC0, // UART1_CTSN -> + CFG_OUT_0, // UART2_TXD -> HOST_WLAN_HSIC_RDY + +/* Port 6 */ + CFG_IN, // UART2_RXD -> IPC_GPIO4 + CFG_DISABLED, // UART2_RTSN -> PMU_AMUX_AY_CTRL + CFG_DISABLED, // UART2_CTSN -> PMU_AMUX_BY_CTRL + CFG_FUNC0 | BT_UART_DRIVE_STR, // UART3_TXD -> (BT) + CFG_FUNC0, // UART3_RXD -> + CFG_OUT_1 | BT_UART_DRIVE_STR, // UART3_RTSN -> + CFG_FUNC0, // UART3_CTSN -> + CFG_FUNC0 | SWI_UART_DRIVE_STR, // UART5_RTXD -> BATTERY_SWI + +/* Port 7 */ + CFG_OUT_0, // UART6_TXD -> HOST_BB_HSIC_RDY + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // UART6_RTSN -> + CFG_DISABLED, // UART6_CTSN -> + CFG_DISABLED, // UART4_TXD/SPI4_MOSI -> + CFG_DISABLED, // UART4_RXD/SPI4_MISO -> + CFG_DISABLED, // UART4_RTSN/SPI4_SCLK -> + CFG_DISABLED, // UART4_CTSN/SPI4_SSIN -> + +/* Port 8 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_REN -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_WEN -> + +/* Port 9 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED | PULL_DOWN, // FMI0_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO1 -> + +/* Port 10 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_REN -> + +/* Port 11 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_DOWN, // FMI1_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO2 -> + +/* Port 12 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED, // FMI2_CEN3 -> + CFG_DISABLED, // FMI2_CEN2 -> + CFG_DISABLED, // FMI2_CEN1 -> + CFG_DISABLED, // FMI2_CEN0 -> + CFG_DISABLED, // FMI2_CLE -> + CFG_DISABLED, // FMI2_ALE -> + +/* Port 13 */ + CFG_DISABLED, // FMI2_REN -> + CFG_DISABLED, // FMI2_WEN -> + CFG_DISABLED, // FMI2_IO7 -> + CFG_DISABLED, // FMI2_IO6 -> + CFG_DISABLED, // FMI2_IO5 -> + CFG_DISABLED, // FMI2_IO4 -> + CFG_DISABLED, // FMI2_DQS -> + CFG_DISABLED, // FMI2_IO3 -> + +/* Port 14 */ + CFG_DISABLED, // FMI2_IO2 -> + CFG_DISABLED, // FMI2_IO1 -> + CFG_DISABLED, // FMI2_IO0 -> + CFG_DISABLED, // FMI0_CEN7 -> + CFG_DISABLED, // FMI0_CEN6 -> + CFG_DISABLED, // FMI0_CEN5 -> + CFG_DISABLED, // FMI0_CEN4 -> + CFG_DISABLED, // FMI1_CEN7 -> + +/* Port 15 */ + CFG_DISABLED, // FMI1_CEN6 -> + CFG_DISABLED, // FMI1_CEN5 -> + CFG_DISABLED, // FMI1_CEN4 -> + CFG_DISABLED, // FMI3_CEN3 -> + CFG_DISABLED, // FMI3_CEN2 -> + CFG_DISABLED, // FMI3_CEN1 -> + CFG_DISABLED, // FMI3_CEN0 -> + CFG_DISABLED, // FMI3_CLE -> + +/* Port 16 */ + CFG_DISABLED, // FMI3_ALE -> + CFG_DISABLED, // FMI3_REN -> + CFG_DISABLED, // FMI3_WEN -> + CFG_DISABLED, // FMI3_IO7 -> + CFG_DISABLED, // FMI3_IO6 -> + CFG_DISABLED, // FMI3_IO5 -> + CFG_DISABLED, // FMI3_IO4 -> + CFG_DISABLED, // FMI3_DQS -> + +/* Port 17 */ + CFG_DISABLED, // FMI3_IO3 -> + CFG_DISABLED, // FMI3_IO2 -> + CFG_DISABLED, // FMI3_IO1 -> + CFG_DISABLED, // FMI3_IO0 -> + CFG_DISABLED, // FMI2_CEN7 -> + CFG_DISABLED, // FMI2_CEN6 -> + CFG_DISABLED, // FMI2_CEN5 -> + CFG_DISABLED, // FMI2_CEN4 -> + +/* Port 18 */ + CFG_DISABLED, // FMI3_CEN7 -> + CFG_DISABLED, // FMI3_CEN6 -> + CFG_DISABLED, // FMI3_CEN5 -> + CFG_DISABLED, // FMI3_CEN4 -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + +/* Port 19 */ + CFG_OUT_0, // ISP0_PRE_FLASH -> CAM0_VDDCORE_EN + CFG_OUT_0, // ISP0_FLASH -> CAM0_RESET_L + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_OUT_0, // ISP1_FLASH -> CAM1_RESET_L + CFG_FUNC0 | GRAPE_DRIVE_STR, // SPI1_SCLK -> SPI1_SCLK (GRAPE) + CFG_FUNC0 | GRAPE_DRIVE_STR, // SPI1_MOSI -> SPI1_MOSI + CFG_FUNC0, // SPI1_MISO -> SPI1_MISO + CFG_OUT_1 | GRAPE_DRIVE_STR, // SPI1_SSIN -> SPI1_CS_L + +/* Port 20 */ + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> SPI0_SSIN + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 21 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_OUT_0 | BB_SPI_DRIVE_STR, // SPI2_SSIN -> SPI2_MRDY / IPC_MRDY + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SDA -> + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SCL -> + +/* Port 22 */ + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SDA -> + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SCL -> + CFG_DISABLED, // SDIO_CLK -> + CFG_DISABLED, // SDIO_CMD -> + CFG_DISABLED, // SDIO_DATA0 -> + CFG_DISABLED, // SDIO_DATA1 -> + CFG_DISABLED, // SDIO_DATA2 -> + CFG_DISABLED, // SDIO_DATA3 -> + +/* Port 23 */ + CFG_DISABLED, // MIPI_VSYNC -> + CFG_IN, // TMR32_PWM0 -> GYRO_INT2 (also GPIO32) + CFG_IN, // TMR32_PWM1 -> ACCEL_INT2_L (also GPIO37) + CFG_OUT_0 | CAM_STROBE_DRIVE_STR, // TMR32_PWM2 -> CAM_STROBE_EN + CFG_DISABLED, // SWI_DATA -> + CFG_FUNC0 | PULL_DOWN, // DWI_DI -> + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> + +/* Port 24 */ + CFG_OUT_0, // SENSOR0_RST -> CAM0_SHUTDOWN + CFG_OUT_0 | CAM_CLK_DRIVE_STR, // SENSOR0_CLK -> CAM0_CLK + CFG_OUT_1, // SENSOR1_RST -> CAM1_SHUTDOWN + CFG_OUT_0 | CAM_CLK_DRIVE_STR, // SENSOR1_CLK -> CAM1_CLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_MCK -> (codec ASP) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> + +/* Port 25 */ + CFG_FUNC0, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> (BB) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_LRCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_DOUT -> + CFG_FUNC0, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> (codec VSP, bluetooth) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> + +/* Port 26 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> + CFG_FUNC0, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> (codec XSP, Amp) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> + CFG_FUNC0, // I2S3_DIN -> + +/* Port 27 */ + CFG_DISABLED, // SPDIF -> BOARD_REV[3] + CFG_OUT_0, // GPIO217 -> VIDEO_AMP_EN_3V0 + CFG_OUT_1, // GPIO218 -> HPHONE_REF_CTRL + CFG_FUNC0, // DP_HPD -> + CFG_FUNC0 | DOCK_UART_DRIVE_STR, // UART0_TXD -> + CFG_FUNC0, // UART0_RXD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 28 */ + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +#undef BB_UART_DRIVE_STR +#undef UMTS_DRIVE_STR +#undef BT_UART_DRIVE_STR +#undef SWI_UART_DRIVE_STR +#undef GPS_UART_DRIVE_STR +#undef FMI_DRIVE_STR +#undef GRAPE_DRIVE_STR +#undef BB_SPI_DRIVE_STR +#undef I2C_DRIVE_STR +#undef CAM_CLK_DRIVE_STR +#undef I2S_DRIVE_STR +#undef DOCK_UART_DRIVE_STR +#undef IPC_DRIVE_STR + +#define BB_UART_DRIVE_STR DRIVE_X4 +#define UMTS_DRIVE_STR DRIVE_X4 +#define BT_UART_DRIVE_STR DRIVE_X4 +#define SWI_UART_DRIVE_STR DRIVE_X4 +#define GPS_UART_DRIVE_STR DRIVE_X4 +#define FMI_DRIVE_STR DRIVE_X4 +#define GRAPE_DRIVE_STR DRIVE_X4 +#define BB_SPI_DRIVE_STR DRIVE_X4 +#define I2C_DRIVE_STR DRIVE_X4 +#define CAM_CLK_DRIVE_STR DRIVE_X4 +#define I2S_DRIVE_STR DRIVE_X4 +#define DOCK_UART_DRIVE_STR DRIVE_X4 +#define IPC_DRIVE_STR DRIVE_X4 + +static const u_int32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +/* Port 0 */ + CFG_IN, // GPIO0 -> MENU_KEY_BUFF_L (REQUEST_DFU2) + CFG_IN, // GPIO1 -> HOLD_KEY_L (REQUEST_DFU1) + CFG_IN | PULL_UP, // GPIO2 -> VOL_DWN_L + CFG_IN | PULL_UP, // GPIO3 -> VOL_UP_L + CFG_IN, // GPIO4 -> RINGER_A + CFG_OUT_0, // GPIO5 -> SPKAMP_RESET_L + CFG_DISABLED, // GPIO6 -> + CFG_OUT_0, // GPIO7 -> BT_WAKE + +/* Port 1 */ + CFG_OUT_1, // GPIO8 -> BT_RESET_L + CFG_DISABLED, // GPIO9 -> + CFG_IN, // GPIO10 -> BB_RESET_L + CFG_IN | PULL_DOWN, // GPIO11 -> BB_RESET_DET_L + CFG_IN | PULL_DOWN, // GPIO12 -> IPC_SRDY + CFG_IN | PULL_UP, // GPIO13 -> PMU_IRQ_L + CFG_IN, // GPIO14 -> RADIO_ON_L + CFG_IN, // GPIO15 -> RESET_BB_PMU_L + +/* Port 2 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_IN | PULL_DOWN, // GPIO17 -> BB_HSIC_RDY + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_OUT_0, // GPIO19 -> KEEPACT + CFG_IN, // GPIO20 -> BB_EMERGENCY_DWLD_L + CFG_IN | PULL_UP, // GPIO21 -> GRAPE_INT_L + CFG_OUT_0, // GPIO22 -> LCD_RESET_L + CFG_IN | PULL_UP, // GPIO23 -> LCD_HIFA + +/* Port 3 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // GPIO26 -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOOT_CONFIG[3] + CFG_IN | PULL_UP, // GPIO30 -> CODEC_INT_L + CFG_IN, // GPIO31 -> WLAN_HSIC_RDY + +/* Port 4 */ + CFG_IN | PULL_DOWN, // GPIO32 -> GYRO_INT2 + CFG_IN | PULL_DOWN, // GPIO33 -> GYRO_INT + CFG_IN | PULL_DOWN, // GPIO34 -> COMPASS_BRD_INT + CFG_DISABLED, // GPIO35 -> + CFG_IN | PULL_UP, // GPIO36 -> ACCEL_INT1_L + CFG_IN | PULL_UP, // GPIO37 -> ACCEL_INT2_L + CFG_IN | PULL_UP, // GPIO38 -> ALS_INT_L + CFG_OUT_0, // GPIO39 -> GRAPE_RESET_L + +/* Port 5 */ + CFG_DISABLED, // EHCI_PORT_PWR[0] -> BOARD_REV[0] + CFG_DISABLED, // EHCI_PORT_PWR[1] -> BOARD_REV[1] + CFG_DISABLED, // EHCI_PORT_PWR[2] -> BOARD_REV[2] + CFG_IN | BB_UART_DRIVE_STR, // UART1_TXD -> (BB USART) + CFG_FUNC0, // UART1_RXD -> + CFG_FUNC0 | BB_UART_DRIVE_STR, // UART1_RTSN -> + CFG_FUNC0, // UART1_CTSN -> + CFG_OUT_0, // UART2_TXD -> HOST_WLAN_HSIC_RDY + +/* Port 6 */ + CFG_IN, // UART2_RXD -> IPC_GPIO4 + CFG_DISABLED, // UART2_RTSN -> PMU_AMUX_AY_CTRL + CFG_DISABLED, // UART2_CTSN -> PMU_AMUX_BY_CTRL + CFG_FUNC0 | BT_UART_DRIVE_STR, // UART3_TXD -> (BT) + CFG_FUNC0, // UART3_RXD -> + CFG_OUT_1 | BT_UART_DRIVE_STR, // UART3_RTSN -> + CFG_FUNC0, // UART3_CTSN -> + CFG_FUNC0 | SWI_UART_DRIVE_STR, // UART5_RTXD -> BATTERY_SWI + +/* Port 7 */ + CFG_OUT_0, // UART6_TXD -> HOST_BB_HSIC_RDY + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // UART6_RTSN -> + CFG_DISABLED, // UART6_CTSN -> + CFG_DISABLED, // UART4_TXD/SPI4_MOSI -> + CFG_DISABLED, // UART4_RXD/SPI4_MISO -> + CFG_DISABLED, // UART4_RTSN/SPI4_SCLK -> + CFG_DISABLED, // UART4_CTSN/SPI4_SSIN -> + +/* Port 8 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN3 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CEN0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_CLE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_REN -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI0_WEN -> + +/* Port 9 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO7 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO6 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO4 -> + CFG_DISABLED | PULL_DOWN, // FMI0_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO2 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO1 -> + +/* Port 10 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI0_IO0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN3 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN2 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN1 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CEN0 -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_CLE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_ALE -> + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_REN -> + +/* Port 11 */ + CFG_FUNC0 | FMI_DRIVE_STR, // FMI1_WEN -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO7 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO6 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO5 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO4 -> + CFG_DISABLED | PULL_DOWN, // FMI1_DQS -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO3 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO2 -> + +/* Port 12 */ + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO1 -> + CFG_FUNC0 | BUS_HOLD | FMI_DRIVE_STR, // FMI1_IO0 -> + CFG_DISABLED, // FMI2_CEN3 -> + CFG_DISABLED, // FMI2_CEN2 -> + CFG_DISABLED, // FMI2_CEN1 -> + CFG_DISABLED, // FMI2_CEN0 -> + CFG_DISABLED, // FMI2_CLE -> + CFG_DISABLED, // FMI2_ALE -> + +/* Port 13 */ + CFG_DISABLED, // FMI2_REN -> + CFG_DISABLED, // FMI2_WEN -> + CFG_DISABLED, // FMI2_IO7 -> + CFG_DISABLED, // FMI2_IO6 -> + CFG_DISABLED, // FMI2_IO5 -> + CFG_DISABLED, // FMI2_IO4 -> + CFG_DISABLED, // FMI2_DQS -> + CFG_DISABLED, // FMI2_IO3 -> + +/* Port 14 */ + CFG_DISABLED, // FMI2_IO2 -> + CFG_DISABLED, // FMI2_IO1 -> + CFG_DISABLED, // FMI2_IO0 -> + CFG_DISABLED, // FMI0_CEN7 -> + CFG_DISABLED, // FMI0_CEN6 -> + CFG_DISABLED, // FMI0_CEN5 -> + CFG_DISABLED, // FMI0_CEN4 -> + CFG_DISABLED, // FMI1_CEN7 -> + +/* Port 15 */ + CFG_DISABLED, // FMI1_CEN6 -> + CFG_DISABLED, // FMI1_CEN5 -> + CFG_DISABLED, // FMI1_CEN4 -> + CFG_DISABLED, // FMI3_CEN3 -> + CFG_DISABLED, // FMI3_CEN2 -> + CFG_DISABLED, // FMI3_CEN1 -> + CFG_DISABLED, // FMI3_CEN0 -> + CFG_DISABLED, // FMI3_CLE -> + +/* Port 16 */ + CFG_DISABLED, // FMI3_ALE -> + CFG_DISABLED, // FMI3_REN -> + CFG_DISABLED, // FMI3_WEN -> + CFG_DISABLED, // FMI3_IO7 -> + CFG_DISABLED, // FMI3_IO6 -> + CFG_DISABLED, // FMI3_IO5 -> + CFG_DISABLED, // FMI3_IO4 -> + CFG_DISABLED, // FMI3_DQS -> + +/* Port 17 */ + CFG_DISABLED, // FMI3_IO3 -> + CFG_DISABLED, // FMI3_IO2 -> + CFG_DISABLED, // FMI3_IO1 -> + CFG_DISABLED, // FMI3_IO0 -> + CFG_DISABLED, // FMI2_CEN7 -> + CFG_DISABLED, // FMI2_CEN6 -> + CFG_DISABLED, // FMI2_CEN5 -> + CFG_DISABLED, // FMI2_CEN4 -> + +/* Port 18 */ + CFG_DISABLED, // FMI3_CEN7 -> + CFG_DISABLED, // FMI3_CEN6 -> + CFG_DISABLED, // FMI3_CEN5 -> + CFG_DISABLED, // FMI3_CEN4 -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + +/* Port 19 */ + CFG_OUT_0, // ISP0_PRE_FLASH -> CAM0_VDDCORE_EN + CFG_OUT_0, // ISP0_FLASH -> CAM0_RESET_L + CFG_DISABLED, // ISP1_PRE_FLASH -> + CFG_OUT_0, // ISP1_FLASH -> CAM1_RESET_L + CFG_FUNC0 | GRAPE_DRIVE_STR, // SPI1_SCLK -> SPI1_SCLK (GRAPE) + CFG_FUNC0 | GRAPE_DRIVE_STR, // SPI1_MOSI -> SPI1_MOSI + CFG_FUNC0, // SPI1_MISO -> SPI1_MISO + CFG_OUT_1 | GRAPE_DRIVE_STR, // SPI1_SSIN -> SPI1_CS_L + +/* Port 20 */ + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SDA -> I2C2_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C2_SCL -> I2C2_SCL_1V8 + CFG_DISABLED, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_DISABLED, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_DISABLED, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_DISABLED, // SPI0_SSIN -> SPI0_SSIN + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 21 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_OUT_0 | BB_SPI_DRIVE_STR, // SPI2_SSIN -> SPI2_MRDY / IPC_MRDY + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SDA -> I2C0_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C0_SCL -> I2C0_SCL_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SDA -> I2C1_SDA_1V8 + CFG_FUNC0 | I2C_DRIVE_STR, // I2C1_SCL -> I2C1_SCL_1V8 + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SDA -> + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP0_SCL -> + +/* Port 22 */ + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SDA -> + CFG_FUNC0 | CAM_I2C_DRIVE_STR, // ISP1_SCL -> + CFG_DISABLED, // SDIO_CLK -> + CFG_DISABLED, // SDIO_CMD -> + CFG_DISABLED, // SDIO_DATA0 -> + CFG_DISABLED, // SDIO_DATA1 -> + CFG_DISABLED, // SDIO_DATA2 -> + CFG_DISABLED, // SDIO_DATA3 -> + +/* Port 23 */ + CFG_DISABLED, // MIPI_VSYNC -> + CFG_IN, // TMR32_PWM0 -> GYRO_INT2 (also GPIO32) + CFG_IN, // TMR32_PWM1 -> ACCEL_INT2_L (also GPIO37) + CFG_OUT_0 | CAM_STROBE_DRIVE_STR, // TMR32_PWM2 -> CAM_STROBE_EN + CFG_DISABLED, // SWI_DATA -> + CFG_FUNC0 | PULL_DOWN, // DWI_DI -> + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_DO -> + CFG_FUNC0 | DWI_DRIVE_STR, // DWI_CLK -> + +/* Port 24 */ + CFG_OUT_0, // SENSOR0_RST -> CAM0_SHUTDOWN + CFG_OUT_0 | CAM_CLK_DRIVE_STR, // SENSOR0_CLK -> CAM0_CLK + CFG_OUT_1, // SENSOR1_RST -> CAM1_SHUTDOWN + CFG_OUT_0 | CAM_CLK_DRIVE_STR, // SENSOR1_CLK -> CAM1_CLK + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_MCK -> (codec ASP) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_LRCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S0_DOUT -> + +/* Port 25 */ + CFG_FUNC0, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> (BB) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_LRCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S1_DOUT -> + CFG_FUNC0, // I2S1_DIN -> + CFG_DISABLED, // I2S2_MCK -> (codec VSP, bluetooth) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_LRCK -> + +/* Port 26 */ + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S2_DOUT -> + CFG_FUNC0, // I2S2_DIN -> + CFG_DISABLED, // I2S3_MCK -> (codec XSP, Amp) + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_LRCK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_BCLK -> + CFG_FUNC0 | I2S_DRIVE_STR, // I2S3_DOUT -> + CFG_FUNC0, // I2S3_DIN -> + +/* Port 27 */ + CFG_FUNC0, // SPDIF -> BOARD_REV[3] / SPDIF + CFG_OUT_0, // GPIO217 -> VIDEO_AMP_EN_3V0 + CFG_OUT_1, // GPIO218 -> HPHONE_REF_CTRL + CFG_FUNC0, // DP_HPD -> + CFG_FUNC0 | DOCK_UART_DRIVE_STR, // UART0_TXD -> + CFG_FUNC0, // UART0_RXD -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // TST_STPCLK -> + +/* Port 28 */ + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> + CFG_DISABLED, // -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; +} diff --git a/target/n94/rules.mk b/target/n94/rules.mk new file mode 100644 index 0000000..017a119 --- /dev/null +++ b/target/n94/rules.mk @@ -0,0 +1,42 @@ +# Copyright (C) 2010-2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D1881=1 \ + TARGET_HIGH_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_MED \ + TARGET_HIGH_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_CPU_SOURCE=2 \ + TARGET_MIPI_DSI_SOURCE=1 \ + TARGET_MANAGED2H_SOURCE=0 \ + TARGET_MANAGED2L_SOURCE=0 \ + TARGET_MANAGED2H_DIV=1 \ + TARGET_MANAGED2L_DIV=2 \ + TARGET_PCLK1_SOURCE=2 \ + TARGET_PCLK1_DIV=6 \ + TARGET_GFX_SOURCE=2 \ + TARGET_GFX_SLC_SOURCE=3 \ + TARGET_IOP_SOURCE=3 \ + TARGET_LPERFS_SOURCE=3 \ + TARGET_HPERFNRT_SOURCE=0 \ + TARGET_USE_HSIC=1 \ + TARGET_DSIM_DPHYCTL=0x30 \ + AMC_NUM_CHANNELS=2 \ + AMC_NUM_RANKS=1 \ + AMC_CHANNEL_WIDTH=4 \ + MULTITOUCH_DTPATH=\"arm-io/spi1/multi-touch\" \ + BASEBAND_DTPATH=\"baseband\" \ + WIFI_DTPATH=\"arm-io/usb-complex/usb-ehci/wlan\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig.o diff --git a/target/s8000fpga/include/target/adbe_settings.h b/target/s8000fpga/include/target/adbe_settings.h new file mode 100644 index 0000000..128c6f9 --- /dev/null +++ b/target/s8000fpga/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0, + .adbe0_tunable_mode_ctrl = 0, + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/s8000fpga/include/target/aspnandconfig.h b/target/s8000fpga/include/target/aspnandconfig.h new file mode 100644 index 0000000..0800563 --- /dev/null +++ b/target/s8000fpga/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/s8000fpga/include/target/dcsfixup.h b/target/s8000fpga/include/target/dcsfixup.h new file mode 100644 index 0000000..e408163 --- /dev/null +++ b/target/s8000fpga/include/target/dcsfixup.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if SUB_PLATFORM_S8001 +#include +#elif SUB_PLATFORM_S8003 +#include +#else +#include +#endif diff --git a/target/s8000fpga/include/target/dcsfixup_s8000.h b/target/s8000fpga/include/target/dcsfixup_s8000.h new file mode 100644 index 0000000..2892c6a --- /dev/null +++ b/target/s8000fpga/include/target/dcsfixup_s8000.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static inline +void dcs_init_config_fixup_params(dcs_config_params_t *dcs_params, dcs_target_t targtype) +{ + uint32_t chip_rev = platform_get_chip_revision(); + + if(chip_rev < CHIP_REVISION_B0) { + dcs_params->freq[0].freqchngctl[1] = 0x000b110c; + dcs_params->freq[1].freqchngctl[1] = 0x000b110c; + dcs_params->freq[0].selfref = 0x02001012; + dcs_params->freq[1].selfref = 0x02001012; + dcs_params->freq[2].selfref = 0x02001012; + dcs_params->freq[3].selfref = 0x02001012; + } else { + dcs_params->freq[0].freqchngctl[2] = 0xb303000b; + dcs_params->freq[1].freqchngctl[2] = 0xf303000b; + dcs_params->freq[0].selfref = 0x28002012; + dcs_params->freq[1].selfref = 0x28002012; + dcs_params->freq[2].selfref = 0x28002012; + dcs_params->freq[3].selfref = 0x28002012; + } + + dcs_params->freq[0].lat = 0x001030c2; + dcs_params->freq[1].lat = 0x001020c2; + dcs_params->freq[0].phyrdwrtim = 0x00010c01; + dcs_params->freq[1].phyrdwrtim = 0x00010b01; + dcs_params->freq[0].caspch = 0x40c20402; + dcs_params->freq[0].act = 0x01020202; + dcs_params->freq[0].autoref = 0x01010078; + dcs_params->modereg = 0x04009024; + dcs_params->freq[1].caspch = 0x40c20402; + dcs_params->freq[1].act = 0x01020202; + dcs_params->freq[1].autoref = 0x01010050; + dcs_params->freq[2].caspch = 0x40c20402; + dcs_params->freq[2].act = 0x01020202; + dcs_params->freq[2].autoref = 0x01010014; + dcs_params->freq[3].act = 0x01020404; + dcs_params->freq[3].autoref = 0x01010005; + dcs_params->autoref_params = 0x00150013; + dcs_params->pdn = 0x21262222; + dcs_params->freq[0].derate = 0x08212082; + dcs_params->freq[1].derate = 0x08212082; + dcs_params->freq[2].derate = 0x08212082; + dcs_params->freq[0].lat2 = 0x001110c2; + dcs_params->freq[1].lat2 = 0x001110c2; + dcs_params->freq[0].tat = 0x01212222; + dcs_params->freq[1].tat = 0x01212222; + dcs_params->freq[3].mifqmaxctrl = 0x00000003; + dcs_params->freq[0].odt_enable = 0x00000000; + dcs_params->freq[1].odt_enable = 0x00000000; + dcs_params->freq[0].rdcapcfg = 0x01000606; + dcs_params->freq[1].rdcapcfg = 0x21000606; + dcs_params->freq[2].rdcapcfg = 0x41000606; + dcs_params->freq[3].rdcapcfg = 0x61000606; + dcs_params->freq[0].autoref2 = 0x01010001; + dcs_params->freq[1].autoref2 = 0x01010001; + dcs_params->freq[2].autoref2 = 0x01010001; + dcs_params->freq[3].autoref2 = 0x01010001; + dcs_params->autoref_params2 = 0x00170013; + dcs_params->odtszqc = 0x00000000; + dcs_params->odtszqc2 = 0xc0000000; + dcs_params->qbrparam = 0x00006100; + dcs_params->odtszqc3 = 0xc0002320; +}; diff --git a/target/s8000fpga/include/target/dcsfixup_s8001.h b/target/s8000fpga/include/target/dcsfixup_s8001.h new file mode 100644 index 0000000..564f5be --- /dev/null +++ b/target/s8000fpga/include/target/dcsfixup_s8001.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static inline +void dcs_init_config_fixup_params(dcs_config_params_t *dcs_params, dcs_target_t targtype) +{ + dcs_params->freq[0].freqchngctl[2] = 0xb303000b; + dcs_params->freq[1].freqchngctl[2] = 0xd303000b; + dcs_params->freq[0].lat = 0x001030c2; + dcs_params->freq[1].lat = 0x001020c2; + dcs_params->freq[0].phyrdwrtim = 0x00010d01; + dcs_params->freq[1].phyrdwrtim = 0x00010b01; + dcs_params->freq[0].caspch = 0x40c20402; + dcs_params->freq[0].act = 0x01020202; + dcs_params->freq[0].autoref = 0x01010078; + dcs_params->freq[0].selfref = 0x28002012; + dcs_params->modereg = 0x060c5024; + dcs_params->freq[1].caspch = 0x40c20402; + dcs_params->freq[1].act = 0x01020202; + dcs_params->freq[1].autoref = 0x01010050; + dcs_params->freq[1].selfref = 0x28002012; + dcs_params->freq[2].caspch = 0x40c20402; + dcs_params->freq[2].act = 0x01020202; + dcs_params->freq[2].autoref = 0x01010014; + dcs_params->freq[2].selfref = 0x28002012; + dcs_params->freq[3].act = 0x01020404; + dcs_params->freq[3].autoref = 0x01010005; + dcs_params->freq[3].selfref = 0x28002012; + dcs_params->autoref_params = 0x00150013; + dcs_params->pdn = 0x21272222; + dcs_params->freq[0].derate = 0x08212082; + dcs_params->freq[1].derate = 0x08212082; + dcs_params->freq[2].derate = 0x08212082; + dcs_params->freq[0].lat2 = 0x001110c2; + dcs_params->freq[1].lat2 = 0x001110c2; + dcs_params->freq[0].tat = 0x01212222; + dcs_params->freq[1].tat = 0x01212222; + dcs_params->freq[3].mifqmaxctrl = 0x00000003; + dcs_params->freq[0].odt_enable = 0x00000000; + dcs_params->freq[1].odt_enable = 0x00000000; + dcs_params->freq[0].rdcapcfg = 0x01000606; + dcs_params->freq[1].rdcapcfg = 0x21000606; + dcs_params->freq[2].rdcapcfg = 0x41000606; + dcs_params->freq[3].rdcapcfg = 0x61000606; + dcs_params->b0odtctrl = 0x00000000; + dcs_params->b1odtctrl = 0x00000000; + dcs_params->dqs0odtctrl = 0x00000000; + dcs_params->dqs1odtctrl = 0x00000000; + dcs_params->freq[0].autoref2 = 0x01010001; + dcs_params->freq[1].autoref2 = 0x01010001; + dcs_params->freq[2].autoref2 = 0x01010001; + dcs_params->freq[3].autoref2 = 0x01010001; + dcs_params->autoref_params2 = 0x002f0013; + dcs_params->mr13cmd_step15 = 0x50, + dcs_params->odtszqc = 0x00000000; + dcs_params->odtszqc2 = 0xc0000000; + dcs_params->qbrparam = 0x00000000; +// Commenting the pwrmngten fixup b/c DV thinks this is a mistake in the spec +// dcs_params->pwrmngten = 0x00000132; + dcs_params->odtszqc3 = 0xc0002320; +}; diff --git a/target/s8000fpga/include/target/dcsfixup_s8003.h b/target/s8000fpga/include/target/dcsfixup_s8003.h new file mode 100644 index 0000000..7374bc3 --- /dev/null +++ b/target/s8000fpga/include/target/dcsfixup_s8003.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static inline +void dcs_init_config_fixup_params(dcs_config_params_t *dcs_params, dcs_target_t targtype) +{ + dcs_params->freq[0].freqchngctl[2] = 0xb303000b; + dcs_params->freq[1].freqchngctl[2] = 0xf303000b; + dcs_params->freq[0].lat = 0x001030c2; + dcs_params->freq[1].lat = 0x001020c2; + dcs_params->freq[0].phyrdwrtim = 0x00010d01; + dcs_params->freq[1].phyrdwrtim = 0x00010c01; + dcs_params->freq[0].caspch = 0x40c20402; + dcs_params->freq[0].act = 0x01020202; + dcs_params->freq[0].autoref = 0x01010078; + dcs_params->freq[0].selfref = 0x28002012; + dcs_params->modereg = 0x060a9024; + dcs_params->freq[1].caspch = 0x40c20402; + dcs_params->freq[1].act = 0x01020202; + dcs_params->freq[1].autoref = 0x01010050; + dcs_params->freq[1].selfref = 0x28002012; + dcs_params->freq[2].caspch = 0x40c20402; + dcs_params->freq[2].act = 0x01020202; + dcs_params->freq[2].autoref = 0x01010014; + dcs_params->freq[2].selfref = 0x28002012; + dcs_params->freq[3].act = 0x01020404; + dcs_params->freq[3].autoref = 0x01010005; + dcs_params->freq[3].selfref = 0x28002012; + dcs_params->autoref_params = 0x00150013; + dcs_params->pdn = 0x21262222; + dcs_params->freq[0].derate = 0x08212082; + dcs_params->freq[1].derate = 0x08212082; + dcs_params->freq[2].derate = 0x08212082; + dcs_params->freq[0].lat2 = 0x001110c2; + dcs_params->freq[1].lat2 = 0x001110c2; + dcs_params->freq[0].tat = 0x01212222; + dcs_params->freq[1].tat = 0x01212222; + dcs_params->freq[3].mifqmaxctrl = 0x00000003; + dcs_params->freq[0].odt_enable = 0x00000000; + dcs_params->freq[1].odt_enable = 0x00000000; + dcs_params->freq[0].rdcapcfg = 0x01000606; + dcs_params->freq[1].rdcapcfg = 0x21000606; + dcs_params->freq[2].rdcapcfg = 0x41000606; + dcs_params->freq[3].rdcapcfg = 0x61000606; + dcs_params->b0odtctrl = 0x00000000; + dcs_params->b1odtctrl = 0x00000000; + dcs_params->dqs0odtctrl = 0x00000000; + dcs_params->dqs1odtctrl = 0x00000000; + dcs_params->freq[0].autoref2 = 0x01010001; + dcs_params->freq[1].autoref2 = 0x01010001; + dcs_params->freq[2].autoref2 = 0x01010001; + dcs_params->freq[3].autoref2 = 0x01010001; + dcs_params->autoref_params2 = 0x00170013; + dcs_params->odtszqc = 0x00000000; + dcs_params->odtszqc2 = 0xc0000000; + dcs_params->qbrparam = 0x00006100; + dcs_params->odtszqc3 = 0xc0002320; +}; diff --git a/target/s8000fpga/include/target/gpiodef.h b/target/s8000fpga/include/target/gpiodef.h new file mode 100644 index 0000000..b561bc6 --- /dev/null +++ b/target/s8000fpga/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* S8000FPGA specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/s8000fpga/include/target/uartconfig.h b/target/s8000fpga/include/target/uartconfig.h new file mode 100644 index 0000000..c60bd47 --- /dev/null +++ b/target/s8000fpga/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/s8000fpga/init.c b/target/s8000fpga/init.c new file mode 100644 index 0000000..d305c6f --- /dev/null +++ b/target/s8000fpga/init.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !SUPPORT_FPGA +#error "FPGA target without SUPPORT_FPGA set" +#endif + +static uint32_t display_config; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +void * target_get_display_configuration(void) +{ + display_config = 0x00000000; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", " debug=0x14e serial=3 amfi=3 amfi_get_out_of_my_way=1 cs_enforcement_disable=1 fips_mode=0", 0); + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "fpga-wsvga", 0); + env_set("ramdisk-delay", "30000000", 0); /* This tells PurpleRestore to slow down; rdar://6345846 */ + env_set("idle-off", "false", 0); + env_set("bootdelay", "3", 0); + env_set("debug-uarts", "3", 0); +} + +#endif + +#if WITH_DEVICETREE + +#define MAX_NODES_PER_DEVICE 3 +struct fpgaNode_t +{ + uint32_t mask; // Block enable mask + const char *nodeName[MAX_NODES_PER_DEVICE]; // Device tree nodes to disable if block is absent +}; + +// Devices tree nodes to disable based upon FPGA block instantiation +struct fpgaNode_t fpgaNodes[] = { + { FPGA_HAS_VXD, { "arm-io/vxd", NULL, NULL }}, + { FPGA_HAS_AVE, { "arm-io/ave", "arm-io/dart-ave", "arm-io/dart-ave/mapper-ave" }}, + { FPGA_HAS_ISP, { "arm-io/isp", "arm-io/dart-isp", "arm-io/dart-isp/mapper-isp" }}, + { FPGA_HAS_DISP, { "arm-io/disp0", "arm-io/dart-disp0", "arm-io/dart-disp0/mapper-disp0" }}, + { FPGA_HAS_MSR, { "arm-io/scaler0", "arm-io/dart-scaler", "arm-io/dart-scaler/mapper-scaler" }}, + { FPGA_HAS_JPEG, { "arm-io/jpeg", "arm-io/dart-jpeg", "arm-io/dart-jpeg/mapper-jpeg" }}, + { FPGA_HAS_GFX, { "arm-io/sgx", NULL, NULL }}, +}; + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + uint32_t i, j; + + // Get the hardware blocks that are instantiated on this FPGA. + uint32_t fpgaBlocks = chipid_get_fpga_block_instantiation(); + dprintf(DEBUG_SPEW, "FPGA block instantiation mask = 0x%X\n", fpgaBlocks); + + for (i = 0; i < sizeof(fpgaNodes)/sizeof(fpgaNodes[0]); i++) { + if ((fpgaBlocks & fpgaNodes[i].mask) == 0) { + for (j = 0; j < MAX_NODES_PER_DEVICE; j++) { + if (fpgaNodes[i].nodeName[j] == NULL) { + break; + } + if (FindNode(0, fpgaNodes[i].nodeName[j], &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (j == 0) { + dprintf(DEBUG_INFO, + "FPGA block not instantiated: disabling %s\n", + fpgaNodes[i].nodeName[j]); + } + propName[0] = '~'; + } else { + dprintf(DEBUG_SPEW, + "FPGA: Could not find 'compatible' property for %s DT node\n", + fpgaNodes[i].nodeName[j]); + } + } else { + dprintf(DEBUG_SPEW, + "FPGA: Could not find %s DT node\n", + fpgaNodes[i].nodeName[j]); + } + } + } + } + return 0; +} +#endif + + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/s8000fpga/pinconfig_s8000fpga.c b/target/s8000fpga/pinconfig_s8000fpga.c new file mode 100644 index 0000000..05d4e96 --- /dev/null +++ b/target/s8000fpga/pinconfig_s8000fpga.c @@ -0,0 +1,325 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! +*/ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : SWD_TMS2 -> + CFG_DISABLED, // 1 : SWD_TMS3 -> + CFG_DISABLED, // 2 : UART5_RTXD -> + CFG_DISABLED, // 3 : I2S4_MCK -> + CFG_DISABLED, // 4 : I2S4_BCLK -> + CFG_DISABLED, // 5 : I2S4_LRCK -> + CFG_DISABLED, // 6 : I2S4_DIN -> + CFG_DISABLED, // 7 : I2S4_DOUT -> + +/* Port 1 */ + CFG_DISABLED, // 8 : I2S2_MCK -> + CFG_DISABLED, // 9 : I2S2_BCLK -> + CFG_DISABLED, // 10 : I2S2_LRCK -> + CFG_DISABLED, // 11 : I2S2_DIN -> + CFG_DISABLED, // 12 : I2S2_DOUT -> + CFG_DISABLED, // 13 : SPI1_SCLK -> + CFG_DISABLED, // 14 : SPI1_MOSI -> + CFG_DISABLED, // 15 : SPI1_MISO -> + +/* Port 2 */ + CFG_DISABLED, // 16 : SPI1_SSIN -> + CFG_DISABLED, // 17 : I2S0_MCK -> + CFG_DISABLED, // 18 : I2S0_BCLK -> + CFG_DISABLED, // 19 : I2S0_LRCK -> + CFG_DISABLED, // 20 : I2S0_DIN -> + CFG_DISABLED, // 21 : I2S0_DOUT -> + CFG_DISABLED, // 22 : I2C2_SDA -> + CFG_DISABLED, // 23 : I2C2_SCL -> + +/* Port 3 */ + CFG_DISABLED, // 24 : UART1_TXD -> + CFG_DISABLED, // 25 : UART1_RXD -> + CFG_DISABLED, // 26 : UART1_RTSN -> + CFG_DISABLED, // 27 : UART1_CTSN -> + CFG_DISABLED, // 28 : UART4_TXD -> + CFG_DISABLED, // 29 : UART4_RXD -> + CFG_DISABLED, // 30 : UART4_RTSN -> + CFG_DISABLED, // 31 : UART4_CTSN -> + +/* Port 4 */ + CFG_DISABLED, // 32 : UART7_TXD -> + CFG_DISABLED, // 33 : UART7_RXD -> + CFG_DISABLED, // 34 : CLK32K_OUT -> + CFG_DISABLED, // 35 : DP_WAKEUP -> + CFG_DISABLED, // 36 : MIPICSI_MUXSEL -> + CFG_DISABLED, // 37 : ISP_I2C1_SDA -> + CFG_DISABLED, // 38 : ISP_I2C1_SCL -> + CFG_DISABLED, // 39 : ISP_I2C0_SDA -> + +/* Port 5 */ + CFG_DISABLED, // 40 : ISP_I2C0_SCL -> + CFG_DISABLED, // 41 : SPI2_SCLK -> + CFG_DISABLED, // 42 : SPI2_MOSI -> + CFG_DISABLED, // 43 : SPI2_MISO -> + CFG_DISABLED, // 44 : SPI2_SSIN -> + CFG_DISABLED, // 45 : I2C0_SDA -> + CFG_DISABLED, // 46 : I2C0_SCL -> + CFG_DISABLED, // 47 : SENSOR0_ISTRB -> + +/* Port 6 */ + CFG_DISABLED, // 48 : SENSOR0_RST -> + CFG_DISABLED, // 49 : SENSOR0_CLK -> + CFG_DISABLED, // 50 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 51 : SENSOR1_ISTRB -> + CFG_DISABLED, // 52 : SENSOR1_RST -> + CFG_DISABLED, // 53 : SENSOR1_CLK -> + CFG_DISABLED, // 54 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : GPIO[0] -> + CFG_DISABLED, // 65 : GPIO[1] -> + CFG_DISABLED, // 66 : GPIO[2] -> + CFG_DISABLED, // 67 : GPIO[3] -> + CFG_DISABLED, // 68 : GPIO[4] -> + CFG_DISABLED, // 69 : GPIO[5] -> + CFG_DISABLED, // 70 : GPIO[6] -> + CFG_DISABLED, // 71 : GPIO[7] -> + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[8] -> + CFG_DISABLED, // 73 : GPIO[9] -> + CFG_DISABLED, // 74 : GPIO[10] -> + CFG_DISABLED, // 75 : GPIO[11] -> + CFG_DISABLED, // 76 : GPIO[12] -> + CFG_DISABLED, // 77 : GPIO[13] -> + CFG_DISABLED, // 78 : GPIO[14] -> + CFG_DISABLED, // 79 : GPIO[15] -> + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[16] -> BOARD_ID[3] + CFG_DISABLED, // 81 : GPIO[17] -> + CFG_DISABLED, // 82 : GPIO[18] -> BOOT_CONFIG[0] + CFG_DISABLED, // 83 : I2S1_MCK -> + CFG_DISABLED, // 84 : I2S1_BCLK -> + CFG_DISABLED, // 85 : I2S1_LRCK -> + CFG_DISABLED, // 86 : I2S1_DIN -> + CFG_DISABLED, // 87 : I2S1_DOUT -> + +/* Port 11 */ + CFG_DISABLED, // 88 : UART3_TXD -> + CFG_DISABLED, // 89 : UART3_RXD -> + CFG_DISABLED, // 90 : UART3_RTSN -> + CFG_DISABLED, // 91 : UART3_CTSN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_IN, // 96 : MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // 97 : HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // 98 : SKEY_L -> + CFG_DISABLED, // 99 : SPI3_SCLK -> + CFG_DISABLED, // 100 : SPI3_MOSI -> + CFG_DISABLED, // 101 : SPI3_MISO -> + CFG_DISABLED, // 102 : SPI3_SSIN -> + CFG_FUNC0, // 103 : SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + +/* Port 13 */ + CFG_FUNC0, // 104 : SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_FUNC0, // 105 : SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1, // 106 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 107 : UART0_TXD -> + CFG_DISABLED, // 108 : UART0_RXD -> + CFG_DISABLED, // 109 : UART6_TXD -> + CFG_DISABLED, // 110 : UART6_RXD -> + CFG_DISABLED, // 111 : TMR32_PWM0 -> + +/* Port 14 */ + CFG_DISABLED, // 112 : TMR32_PWM1 -> + CFG_DISABLED, // 113 : TMR32_PWM2 -> + CFG_DISABLED, // 114 : I2C1_SDA -> + CFG_DISABLED, // 115 : I2C1_SCL -> + CFG_DISABLED, // 116 : GPIO[19] -> + CFG_DISABLED, // 117 : GPIO[20] -> + CFG_DISABLED, // 118 : GPIO[21] -> + CFG_DISABLED, // 119 : GPIO[22] -> + +/* Port 15 */ + CFG_DISABLED, // 120 : GPIO[23] -> + CFG_DISABLED, // 121 : GPIO[24] -> + CFG_DISABLED, // 122 : GPIO[25] -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // 123 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // 124 : PMGR_MOSI -> DFU_STATUS + CFG_DISABLED, // 125 : PMGR_MISO -> + CFG_DISABLED, // 126 : PMGR_SCLK0 -> + CFG_DISABLED, // 127 : PMGR_SSCLK1 -> + +/* Port 16 */ + CFG_DISABLED, // 128 : SOCHOT0 -> + CFG_DISABLED, // 129 : SOCHOT1 -> + CFG_DISABLED, // 130 : EDP_HPD -> + CFG_DISABLED, // 131 : I2S3_MCK -> + CFG_DISABLED, // 132 : I2S3_BCLK -> + CFG_DISABLED, // 133 : I2S3_LRCK -> + CFG_DISABLED, // 134 : I2S3_DOUT -> + CFG_DISABLED, // 135 : I2S3_DIN -> + +/* Port 17 */ + CFG_DISABLED, // 136 : GPIO[27] -> + CFG_DISABLED, // 137 : GPIO[28] -> BOOT_CONFIG[2] + CFG_DISABLED, // 138 : GPIO[29] -> BOARD_ID[4] + CFG_DISABLED, // 139 : GPIO[30] -> + CFG_DISABLED, // 140 : GPIO[31] -> + CFG_DISABLED, // 141 : GPIO[32] -> + CFG_DISABLED, // 142 : GPIO[33] -> + CFG_DISABLED, // 143 : GPIO[34] -> + +/* Port 18 */ + CFG_DISABLED, // 144 : GPIO[35] -> + CFG_DISABLED, // 145 : GPIO[36] -> + CFG_DISABLED, // 146 : GPIO[37] -> + CFG_DISABLED, // 147 : GPIO[38] -> + CFG_DISABLED, // 148 : GPIO[39] -> + CFG_DISABLED, // 149 : GPIO[40] -> + CFG_DISABLED, // 150 : GPIO[41] -> + CFG_DISABLED, // 151 : GPIO[42] -> + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : PCIE_PERST0_N -> NAND_PERST + CFG_DISABLED, // 161 : PCIE_PERST1_N -> + CFG_DISABLED, // 162 : PCIE_PERST2_N -> + CFG_DISABLED, // 163 : PCIE_PERST3_N -> + CFG_DISABLED, // 164 : PCIE_CLKREQ0_N -> NAND_CLKREQ + CFG_DISABLED, // 165 : PCIE_CLKREQ1_N -> + CFG_DISABLED, // 166 : PCIE_CLKREQ2_N -> + CFG_DISABLED, // 167 : PCIE_CLKREQ3_N -> + +/* Port 21 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_DISABLED, // 192 : UART2_TXD -> + CFG_DISABLED, // 193 : UART2_RXD -> + CFG_DISABLED, // 194 : UART2_RTSN -> + CFG_DISABLED, // 195 : UART2_CTSN -> + CFG_DISABLED, // 196 : NAND_SYS_CLK -> NAND_SYS_CLK + CFG_DISABLED, // 197 : S3E_RESETN -> NAND_RESET + CFG_DISABLED, // 198 : TST_CLKOUT -> + CFG_DISABLED, +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED, // 2 : AOP_SPI_MISO -> + CFG_DISABLED, // 3 : AOP_UART1_TXD -> + CFG_DISABLED, // 4 : AOP_UART1_RXD -> + CFG_DISABLED, // 5 : AOP_UART0_TXD -> + CFG_DISABLED, // 6 : AOP_UART0_RXD -> + CFG_DISABLED, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED, // 8 : AOP_UART2_RXD -> + CFG_DISABLED, // 9 : AOP_I2CM_SDA -> + CFG_DISABLED, // 10 : AOP_I2CM_SCL -> + CFG_DISABLED, // 11 : AOP_FUNC[0] -> + CFG_DISABLED, // 12 : AOP_FUNC[1] -> + CFG_DISABLED, // 13 : AOP_FUNC[2] -> + CFG_DISABLED, // 14 : AOP_FUNC[3] -> + CFG_DISABLED, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : AOP_FUNC[5] -> + CFG_DISABLED, // 17 : AOP_FUNC[6] -> + CFG_DISABLED, // 18 : AOP_FUNC[7] -> + CFG_DISABLED, // 19 : AOP_FUNC[8] -> + CFG_DISABLED, // 20 : AOP_FUNC[9] -> + CFG_DISABLED, // 21 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 22 : AOP_SWD_TMS0 -> + CFG_DISABLED, // 23 : AOP_SWD_TMS1 -> + +/* Port 3 */ + CFG_DISABLED, // 24 : AOP_I2S_MCK -> + CFG_DISABLED, // 25 : AOP_I2S_BCLK -> + CFG_DISABLED, // 26 : AOP_I2S_LRCK -> + CFG_DISABLED, // 27 : AOP_I2S_DIN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + switch (gpioc) { + case 0: + return gpio_default_cfg; + case 1: + return gpio_1_default_cfg; + default: + panic("unknown gpio controller %u", gpioc); + } +} diff --git a/target/s8000fpga/pinconfig_s8001fpga.c b/target/s8000fpga/pinconfig_s8001fpga.c new file mode 100644 index 0000000..2e8c657 --- /dev/null +++ b/target/s8000fpga/pinconfig_s8001fpga.c @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : SPI1_SCLK -> + CFG_DISABLED, // 1 : SPI1_MOSI -> + CFG_DISABLED, // 2 : SPI1_MISO -> + CFG_DISABLED, // 3 : SPI1_SSIN -> + CFG_DISABLED, // 4 : ISP_I2C0_SDA -> + CFG_DISABLED, // 5 : ISP_I2C0_SCL -> + CFG_DISABLED, // 6 : ISP_I2C0_SDA -> + CFG_DISABLED, // 7 : ISP_I2C0_SCL -> + +/* Port 1 */ + CFG_DISABLED, // 8 : SENSOR0_ISTRB -> + CFG_DISABLED, // 9 : SENSOR0_RST -> + CFG_DISABLED, // 10 : SENSOR0_CLK -> + CFG_DISABLED, // 11 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 12 : SENSOR1_ISTRB -> + CFG_DISABLED, // 13 : SENSOR1_RST -> + CFG_DISABLED, // 14 : SENSOR1_CLK -> + CFG_DISABLED, // 15 : SENSOR1_XSHUTDOWN -> + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[16] -> BOARD_ID[3] + CFG_DISABLED, // 17 : GPIO[17] -> + CFG_DISABLED, // 18 : GPIO[18] -> BOOT_CONFIG[0] + CFG_DISABLED, // 19 : I2S1_MCK -> + CFG_DISABLED, // 20 : I2S1_BLCK -> + CFG_DISABLED, // 21 : I2S1_LRCK -> + CFG_DISABLED, // 22 : I2S1_DIN -> + CFG_DISABLED, // 23 : I2S1_DOUT -> + +/* Port 3 */ + CFG_DISABLED, // 24 : NAND_SYS_CLK -> + CFG_DISABLED, // 25 : S3E0_RESETN -> + CFG_DISABLED, // 26 : S3E1_RESETN -> + CFG_DISABLED, // 27 : UART1_TXD -> + CFG_DISABLED, // 28 : UART1_RXD -> + CFG_DISABLED, // 29 : UART1_RTSN -> + CFG_DISABLED, // 30 : UART1_CTSN -> + CFG_DISABLED, // 31 : GPIO43 -> + +/* Port 4 */ + CFG_DISABLED, // 32 : I2S0_BCLK -> + CFG_DISABLED, // 33 : I2S0_LRCK -> + CFG_DISABLED, // 34 : I2S0_DIN -> + CFG_DISABLED, // 35 : I2S0_DOUT -> + CFG_DISABLED, // 36 : I2S0_MCK -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 5 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : I2S4_MCK -> + CFG_DISABLED, // 65 : I2S4_BCLK -> + CFG_DISABLED, // 66 : I2S4_LRCK -> + CFG_DISABLED, // 67 : I2S4_DIN -> + CFG_DISABLED, // 68 : I2S4_DOUT -> + CFG_DISABLED, // 69 : I2S2_MCK -> + CFG_DISABLED, // 70 : I2S2_BCLK -> + CFG_DISABLED, // 71 : I2S2_LRCK -> + +/* Port 9 */ + CFG_DISABLED, // 72 : I2S2_DIN -> + CFG_DISABLED, // 73 : I2S2_DOUT -> + CFG_DISABLED, // 74 : GPIO[0] -> + CFG_DISABLED, // 75 : GPIO[1] -> + CFG_DISABLED, // 76 : GPIO[2] -> + CFG_DISABLED, // 77 : GPIO[3] -> + CFG_DISABLED, // 78 : GPIO[4] -> + CFG_DISABLED, // 79 : GPIO[5] -> + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[6] -> + CFG_DISABLED, // 81 : GPIO[7] -> + CFG_DISABLED, // 82 : GPIO[8] -> + CFG_DISABLED, // 83 : GPIO[9] -> + CFG_DISABLED, // 84 : GPIO[10] -> + CFG_DISABLED, // 85 : GPIO[11] -> + CFG_DISABLED, // 86 : GPIO[12] -> + CFG_DISABLED, // 87 : GPIO[13] -> + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[14] -> + CFG_DISABLED, // 89 : GPIO[15] -> + CFG_DISABLED, // 90 : UART3_TXD -> + CFG_DISABLED, // 91 : UART3_RXD -> + CFG_DISABLED, // 92 : UART3_RTSN -> + CFG_DISABLED, // 93 : UART3_CTSN -> + CFG_FUNC0, // 94 : SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_FUNC0, // 95 : SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + +/* Port 12 */ + CFG_FUNC0, // 96 : SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1, // 97 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 98 : PCIE_PERST0_N -> NAND_PERST + CFG_DISABLED, // 99 : PCIE_PERST1_N -> + CFG_DISABLED, // 100 : PCIE_PERST2_N -> + CFG_DISABLED, // 101 : PCIE_PERST3_N -> + CFG_DISABLED, // 102 : PCIE_PERST4_N -> + CFG_DISABLED, // 103 : PCIE_PERST5_N -> + +/* Port 13 */ + CFG_DISABLED, // 104 : PCIE_CLKREQ0_N -> NAND_CLKREQ + CFG_DISABLED, // 105 : PCIE_CLKREQ1_N -> + CFG_DISABLED, // 106 : PCIE_CLKREQ2_N -> + CFG_DISABLED, // 107 : PCIE_CLKREQ3_N -> + CFG_DISABLED, // 108 : PCIE_CLKREQ4_N -> + CFG_DISABLED, // 109 : PCIE_CLKREQ5_N -> + CFG_DISABLED, // 110 : UART2_TXD -> + CFG_DISABLED, // 111 : UART2_RXD -> + +/* Port 14 */ + CFG_DISABLED, // 112 : UART2_RTSN -> + CFG_DISABLED, // 113 : UART2_CTSN -> + CFG_DISABLED, // 114 : I2C3_SDA -> + CFG_DISABLED, // 115 : I2C3_SCL -> + CFG_DISABLED, // 116 : GPIO[44] -> + CFG_DISABLED, // 117 : GPIO[45] -> + CFG_DISABLED, // 118 : GPIO[46] -> + CFG_DISABLED, // 119 : GPIO[47] -> + +/* Port 15 */ + CFG_DISABLED, // 120 : GPIO[48] -> + CFG_DISABLED, // 121 : GPIO[49] -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_IN, // 128 : MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // 129 : HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // 130 : SKEY_L -> + CFG_DISABLED, // 131 : SWD_TMS2 -> + CFG_DISABLED, // 132 : SWD_TMS3 -> + CFG_DISABLED, // 133 : UART5_RTXD -> + CFG_DISABLED, // 134 : I2C2_SDA -> + CFG_DISABLED, // 135 : I2C2_SCL -> + +/* Port 17 */ + CFG_DISABLED, // 136 : UART4_TXD -> + CFG_DISABLED, // 137 : UART4_RXD -> + CFG_DISABLED, // 138 : UART4_RTSN -> + CFG_DISABLED, // 139 : UART4_CTSN -> + CFG_DISABLED, // 140 : UART7_TXD -> + CFG_DISABLED, // 141 : UART7_RXD -> + CFG_DISABLED, // 142 : CLK32K_OUT -> + CFG_DISABLED, // 143 : DP_WAKEUP0 -> + +/* Port 18 */ + CFG_DISABLED, // 144 : DP_WAKEUP0 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : SPI2_SCLK -> + CFG_DISABLED, // 161 : SPI2_MOSI -> + CFG_DISABLED, // 162 : SPI2_MISO -> + CFG_DISABLED, // 163 : SPI2_SSIN -> + CFG_DISABLED, // 164 : I2C0_SDA -> + CFG_DISABLED, // 165 : I2C0_SCL -> + CFG_DISABLED, // 166 : SPI3_SCLK -> + CFG_DISABLED, // 167 : SPI3_MOSI -> + +/* Port 21 */ + CFG_DISABLED, // 168 : SPI3_MISO -> + CFG_DISABLED, // 169 : SPI3_SSIN -> + CFG_DISABLED, // 170 : UART0_TXD -> + CFG_DISABLED, // 171 : UART0_RXD -> + CFG_DISABLED, // 172 : UART6_TXD -> + CFG_DISABLED, // 173 : UART6_RXD -> + CFG_DISABLED, // 174 : TMR32_PWM0 -> + CFG_DISABLED, // 175 : TMR32_PWM1 -> + +/* Port 22 */ + CFG_DISABLED, // 176 : TMR32_PWM2 -> + CFG_DISABLED, // 177 : I2C1_SDA -> + CFG_DISABLED, // 178 : I2C1_SCL -> + CFG_DISABLED, // 179 : GPIO[19] -> + CFG_DISABLED, // 180 : GPIO[20] -> + CFG_DISABLED, // 181 : GPIO[21] -> + CFG_DISABLED, // 182 : GPIO[22] -> + CFG_DISABLED, // 183 : GPIO[23] -> + +/* Port 23 */ + CFG_DISABLED, // 184 : GPIO[24] -> + CFG_DISABLED, // 185 : GPIO[25] -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // 186 : GPIO[26] -> FORCE_DFU + CFG_DISABLED, // 187 : PSPI_MOSI -> + CFG_DISABLED, // 188 : DWI_DO -> + CFG_DISABLED, // 189 : PMGR_MISO -> + CFG_DISABLED, // 190 : PMGR_SCLK0 -> + CFG_DISABLED, // 191 : PMGR_SSCLK1 -> + +/* Port 24 */ + CFG_DISABLED, // 192 : DROOP -> + CFG_DISABLED, // 193 : SOCHOT1 -> + CFG_DISABLED, // 194 : EDP_HPD0 -> + CFG_DISABLED, // 195 : EDP_HPD1 -> + CFG_DISABLED, // 196 : I2S3_MCK -> + CFG_DISABLED, // 197 : I2S3_BCLK -> + CFG_DISABLED, // 198 : I2S3_LRCK -> + CFG_DISABLED, // 199 : I2S3_DOUT -> + +/* Port 25 */ + CFG_DISABLED, // 200 : I2S3_DIN -> + CFG_DISABLED | PULL_DOWN, // 201 : GPIO[27] -> DFU_STATUS + CFG_DISABLED, // 202 : GPIO[28] -> BOOT_CONFIG[2] + CFG_DISABLED, // 203 : GPIO[29] -> BOARD_ID[4] + CFG_DISABLED, // 204 : GPIO[30] -> + CFG_DISABLED, // 205 : GPIO[31] -> + CFG_DISABLED, // 206 : GPIO[32] -> + CFG_DISABLED, // 207 : GPIO[33] -> + +/* Port 26 */ + CFG_DISABLED, // 208 : GPIO[34] -> + CFG_DISABLED, // 209 : GPIO[35] -> + CFG_DISABLED, // 210 : GPIO[36] -> + CFG_DISABLED, // 211 : GPIO[37] -> + CFG_DISABLED, // 212 : GPIO[38] -> + CFG_DISABLED, // 213 : GPIO[39] -> + CFG_DISABLED, // 214 : GPIO[40] -> + CFG_DISABLED, // 215 : GPIO[41] -> + +/* Port 27 */ + CFG_DISABLED, // 216 : GPIO[42] -> + CFG_DISABLED, // 217 : TST_CLKOUT -> + CFG_DISABLED, // 218 : GPU_TRIGGER1 -> + CFG_DISABLED, // 219 : GPU_TRIGGER2 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED, // 2 : AOP_SPI_MISO -> + CFG_DISABLED, // 3 : AOP_UART1_TXD -> + CFG_DISABLED, // 4 : AOP_UART1_RXD -> + CFG_DISABLED, // 5 : AOP_UART0_TXD -> + CFG_DISABLED, // 6 : AOP_UART0_RXD -> + CFG_DISABLED, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED, // 8 : AOP_UART2_RXD -> + CFG_DISABLED, // 9 : AOP_I2CM_SDA -> + CFG_DISABLED, // 10 : AOP_I2CM_SCL -> + CFG_DISABLED, // 11 : AOP_FUNC[0] -> + CFG_DISABLED, // 12 : AOP_FUNC[1] -> + CFG_DISABLED, // 13 : AOP_FUNC[2] -> + CFG_DISABLED, // 14 : AOP_FUNC[3] -> + CFG_DISABLED, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : AOP_FUNC[5] -> + CFG_DISABLED, // 17 : AOP_FUNC[6] -> + CFG_DISABLED, // 18 : AOP_FUNC[7] -> + CFG_DISABLED, // 19 : AOP_FUNC[8] -> + CFG_DISABLED, // 20 : AOP_FUNC[9] -> + CFG_DISABLED, // 21 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 22 : AOP_SWD_TMS0 -> + CFG_DISABLED, // 23 : AOP_SWD_TMS1 -> + +/* Port 3 */ + CFG_DISABLED, // 24 : AOP_I2S_MCK -> + CFG_DISABLED, // 25 : AOP_I2S_BCLK -> + CFG_DISABLED, // 26 : AOP_I2S_LRCK -> + CFG_DISABLED, // 27 : AOP_I2S_DIN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + switch (gpioc) { + case 0: + return gpio_default_cfg; + case 1: + return gpio_1_default_cfg; + default: + panic("unknown gpio controller %u", gpioc); + } +} diff --git a/target/s8000fpga/rules.mk b/target/s8000fpga/rules.mk new file mode 100644 index 0000000..e0ad6eb --- /dev/null +++ b/target/s8000fpga/rules.mk @@ -0,0 +1,50 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + DISPLAY_FPGA_TUNABLES=1 \ + DCS_RUN_AT_50MHZ=1 \ + DCS_NUM_RANKS=1 \ + AMP_CALIBRATION_SKIP=1 \ + DCS_FIXUP_PARAMS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 + +OPTIONS += \ + SUPPORT_FPGA=1 + +ifeq ($(SUB_PLATFORM),s8001) +OPTIONS += \ + DCS_NUM_CHANNELS=8 +else +OPTIONS += \ + DCS_NUM_CHANNELS=4 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o + +ifeq ($(SUB_PLATFORM),s8003) +ALL_OBJS += $(LOCAL_DIR)/pinconfig_s8000fpga.o +else +ALL_OBJS += $(LOCAL_DIR)/pinconfig_$(SUB_TARGET).o +endif diff --git a/target/s8000sim/include/target/adbe_settings.h b/target/s8000sim/include/target/adbe_settings.h new file mode 100644 index 0000000..fec3542 --- /dev/null +++ b/target/s8000sim/include/target/adbe_settings.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/s8000sim/include/target/aspnandconfig.h b/target/s8000sim/include/target/aspnandconfig.h new file mode 100644 index 0000000..18774a9 --- /dev/null +++ b/target/s8000sim/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/s8000sim/include/target/gpiodef.h b/target/s8000sim/include/target/gpiodef.h new file mode 100644 index 0000000..5a345b7 --- /dev/null +++ b/target/s8000sim/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* Typhonic specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/s8000sim/include/target/nand_spec_tables.h b/target/s8000sim/include/target/nand_spec_tables.h new file mode 100644 index 0000000..029be11 --- /dev/null +++ b/target/s8000sim/include/target/nand_spec_tables.h @@ -0,0 +1,153 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* blocksPerCS */ 4100, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_TOSHIBA_MLC, + /* diesPerCS */ 1 + } +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + } +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Toshiba" + } +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ + { + /* packageId */ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + }, + /* appleName */ "335S0700", + /* vendor_part_num */ "TH58NVG6D2FLA49", + /* package_type */ "DDP", + /* package_size */ "1.00mm LGA" + } +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + } +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000303 + }, + + /* useToggleMode */ 0, + /* useDiffDQSMode */ 0, + /* useDiffREMode */ 0, + /* useVref */ 0 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 0 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/s8000sim/include/target/powerconfig.h b/target/s8000sim/include/target/powerconfig.h new file mode 100644 index 0000000..e258978 --- /dev/null +++ b/target/s8000sim/include/target/powerconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +// Minimal definitions to make lib/power.c happy +#define TARGET_POWER_NO_BATTERY 1 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (5000) + +// This fake SoC block takes the place of the external PMU in Fastsim +#define SWIFTER_PMU_BASE 0x20F050000 + +#endif diff --git a/target/s8000sim/include/target/uartconfig.h b/target/s8000sim/include/target/uartconfig.h new file mode 100644 index 0000000..8dbadc2 --- /dev/null +++ b/target/s8000sim/include/target/uartconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#endif diff --git a/target/s8000sim/init.c b/target/s8000sim/init.c new file mode 100644 index 0000000..79cfbf6 --- /dev/null +++ b/target/s8000sim/init.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +void * target_get_display_configuration(void) +{ + return NULL; +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", "debug=0x14e serial=3 amfi=0x83 cs_enforcement_disable=1 fips_mode=0 -disable_aslr", ENV_PERSISTENT); + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("idle-off", "false", 0); + env_set("kaslr-slide", "0x10000000", 0); + env_set("wifiaddr", "12:22:33:44:55:66", 0); + env_set("ethaddr", "12:22:33:44:55:77", 0); + env_set("btaddr", "00:00:00:00:00:00", 0); +#if SUB_TARGET_S8001SIM + env_set("display-timing", "ipad6", 0); + env_set("adfe-tunables", "ipad6", 0); +#else + env_set("display-timing", "D520", 0); + env_set("adfe-tunables", "D520", 0); +#endif +} + +#endif + +#if WITH_DEVICETREE + +#define ROOT_DTPATH "" +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Overwrite the serial-number with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "serial-number property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *serial = (uint64_t *)propData; + serial[0] = *(volatile uint64_t *)0x20f050040; + serial[1] = *(volatile uint64_t *)0x20f050048; + serial[2] = *(volatile uint64_t *)0x20f050050; + serial[3] = *(volatile uint64_t *)0x20f050058; + } + } + + // Overwrite the region-info with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "region-info"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "region-info property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *region = (uint64_t *)propData; + region[0] = *(volatile uint64_t *)0x20f050060; + region[1] = *(volatile uint64_t *)0x20f050068; + region[2] = *(volatile uint64_t *)0x20f050070; + region[3] = *(volatile uint64_t *)0x20f050078; + } + } + + return 0; +} + +#endif + + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/s8000sim/pinconfig_s8000sim.c b/target/s8000sim/pinconfig_s8000sim.c new file mode 100644 index 0000000..adb62a9 --- /dev/null +++ b/target/s8000sim/pinconfig_s8000sim.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : SWD_TMS2 -> + CFG_DISABLED, // 1 : SWD_TMS3 -> + CFG_DISABLED, // 2 : UART5_RTXD -> + CFG_DISABLED, // 3 : I2S4_MCK -> + CFG_DISABLED, // 4 : I2S4_BCLK -> + CFG_DISABLED, // 5 : I2S4_LRCK -> + CFG_DISABLED, // 6 : I2S4_DIN -> + CFG_DISABLED, // 7 : I2S4_DOUT -> + +/* Port 1 */ + CFG_DISABLED, // 8 : I2S2_MCK -> + CFG_DISABLED, // 9 : I2S2_BCLK -> + CFG_DISABLED, // 10 : I2S2_LRCK -> + CFG_DISABLED, // 11 : I2S2_DIN -> + CFG_DISABLED, // 12 : I2S2_DOUT -> + CFG_DISABLED, // 13 : SPI1_SCLK -> + CFG_DISABLED, // 14 : SPI1_MOSI -> + CFG_DISABLED, // 15 : SPI1_MISO -> + +/* Port 2 */ + CFG_DISABLED, // 16 : SPI1_SSIN -> + CFG_DISABLED, // 17 : I2S0_MCK -> + CFG_DISABLED, // 18 : I2S0_BCLK -> + CFG_DISABLED, // 19 : I2S0_LRCK -> + CFG_DISABLED, // 20 : I2S0_DIN -> + CFG_DISABLED, // 21 : I2S0_DOUT -> + CFG_DISABLED, // 22 : I2C2_SDA -> + CFG_DISABLED, // 23 : I2C2_SCL -> + +/* Port 3 */ + CFG_DISABLED, // 24 : UART1_TXD -> + CFG_DISABLED, // 25 : UART1_RXD -> + CFG_DISABLED, // 26 : UART1_RTSN -> + CFG_DISABLED, // 27 : UART1_CTSN -> + CFG_DISABLED, // 28 : UART4_TXD -> + CFG_DISABLED, // 29 : UART4_RXD -> + CFG_DISABLED, // 30 : UART4_RTSN -> + CFG_DISABLED, // 31 : UART4_CTSN -> + +/* Port 4 */ + CFG_DISABLED, // 32 : UART7_TXD -> + CFG_DISABLED, // 33 : UART7_RXD -> + CFG_DISABLED, // 34 : CLK32K_OUT -> + CFG_DISABLED, // 35 : DP_WAKEUP -> + CFG_DISABLED, // 36 : MIPICSI_MUXSEL -> + CFG_DISABLED, // 37 : ISP_I2C1_SDA -> + CFG_DISABLED, // 38 : ISP_I2C1_SCL -> + CFG_DISABLED, // 39 : ISP_I2C0_SDA -> + +/* Port 5 */ + CFG_DISABLED, // 40 : ISP_I2C0_SCL -> + CFG_DISABLED, // 41 : SPI2_SCLK -> + CFG_DISABLED, // 42 : SPI2_MOSI -> + CFG_DISABLED, // 43 : SPI2_MISO -> + CFG_DISABLED, // 44 : SPI2_SSIN -> + CFG_DISABLED, // 45 : I2C0_SDA -> + CFG_DISABLED, // 46 : I2C0_SCL -> + CFG_DISABLED, // 47 : SENSOR0_ISTRB -> + +/* Port 6 */ + CFG_DISABLED, // 48 : SENSOR0_RST -> + CFG_DISABLED, // 49 : SENSOR0_CLK -> + CFG_DISABLED, // 50 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 51 : SENSOR1_ISTRB -> + CFG_DISABLED, // 52 : SENSOR1_RST -> + CFG_DISABLED, // 53 : SENSOR1_CLK -> + CFG_DISABLED, // 54 : SENSOR1_XSHUTDOWN -> + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : GPIO[0] -> + CFG_DISABLED, // 65 : GPIO[1] -> + CFG_DISABLED, // 66 : GPIO[2] -> + CFG_DISABLED, // 67 : GPIO[3] -> + CFG_DISABLED, // 68 : GPIO[4] -> + CFG_DISABLED, // 69 : GPIO[5] -> + CFG_DISABLED, // 70 : GPIO[6] -> + CFG_DISABLED, // 71 : GPIO[7] -> + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[8] -> + CFG_DISABLED, // 73 : GPIO[9] -> + CFG_DISABLED, // 74 : GPIO[10] -> + CFG_DISABLED, // 75 : GPIO[11] -> + CFG_DISABLED, // 76 : GPIO[12] -> + CFG_DISABLED, // 77 : GPIO[13] -> + CFG_DISABLED, // 78 : GPIO[14] -> + CFG_DISABLED, // 79 : GPIO[15] -> + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[16] -> BOARD_ID[3] + CFG_DISABLED, // 81 : GPIO[17] -> + CFG_DISABLED, // 82 : GPIO[18] -> BOOT_CONFIG[0] + CFG_DISABLED, // 83 : I2S1_MCK -> + CFG_DISABLED, // 84 : I2S1_BCLK -> + CFG_DISABLED, // 85 : I2S1_LRCK -> + CFG_DISABLED, // 86 : I2S1_DIN -> + CFG_DISABLED, // 87 : I2S1_DOUT -> + +/* Port 11 */ + CFG_DISABLED, // 88 : UART3_TXD -> + CFG_DISABLED, // 89 : UART3_RXD -> + CFG_DISABLED, // 90 : UART3_RTSN -> + CFG_DISABLED, // 91 : UART3_CTSN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_IN, // 96 : MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // 97 : HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // 98 : SKEY_L -> + CFG_DISABLED, // 99 : SPI3_SCLK -> + CFG_DISABLED, // 100 : SPI3_MOSI -> + CFG_DISABLED, // 101 : SPI3_MISO -> + CFG_DISABLED, // 102 : SPI3_SSIN -> + CFG_FUNC0, // 103 : SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + +/* Port 13 */ + CFG_FUNC0, // 104 : SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_FUNC0, // 105 : SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1, // 106 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 107 : UART0_TXD -> + CFG_DISABLED, // 108 : UART0_RXD -> + CFG_DISABLED, // 109 : UART6_TXD -> + CFG_DISABLED, // 110 : UART6_RXD -> + CFG_DISABLED, // 111 : TMR32_PWM0 -> + +/* Port 14 */ + CFG_DISABLED, // 112 : TMR32_PWM1 -> + CFG_DISABLED, // 113 : TMR32_PWM2 -> + CFG_DISABLED, // 114 : I2C1_SDA -> + CFG_DISABLED, // 115 : I2C1_SCL -> + CFG_DISABLED, // 116 : GPIO[19] -> + CFG_DISABLED, // 117 : GPIO[20] -> + CFG_DISABLED, // 118 : GPIO[21] -> + CFG_DISABLED, // 119 : GPIO[22] -> + +/* Port 15 */ + CFG_DISABLED, // 120 : GPIO[23] -> + CFG_DISABLED, // 121 : GPIO[24] -> + CFG_DISABLED, // 122 : GPIO[25] -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // 123 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN, // 124 : PMGR_MOSI -> DFU_STATUS + CFG_DISABLED, // 125 : PMGR_MISO -> + CFG_DISABLED, // 126 : PMGR_SCLK0 -> + CFG_DISABLED, // 127 : PMGR_SSCLK1 -> + +/* Port 16 */ + CFG_DISABLED, // 128 : SOCHOT0 -> + CFG_DISABLED, // 129 : SOCHOT1 -> + CFG_DISABLED, // 130 : EDP_HPD -> + CFG_DISABLED, // 131 : I2S3_MCK -> + CFG_DISABLED, // 132 : I2S3_BCLK -> + CFG_DISABLED, // 133 : I2S3_LRCK -> + CFG_DISABLED, // 134 : I2S3_DOUT -> + CFG_DISABLED, // 135 : I2S3_DIN -> + +/* Port 17 */ + CFG_DISABLED, // 136 : GPIO[27] -> + CFG_DISABLED, // 137 : GPIO[28] -> BOOT_CONFIG[2] + CFG_DISABLED, // 138 : GPIO[29] -> BOARD_ID[4] + CFG_DISABLED, // 139 : GPIO[30] -> + CFG_DISABLED, // 140 : GPIO[31] -> + CFG_DISABLED, // 141 : GPIO[32] -> + CFG_DISABLED, // 142 : GPIO[33] -> + CFG_DISABLED, // 143 : GPIO[34] -> + +/* Port 18 */ + CFG_DISABLED, // 144 : GPIO[35] -> + CFG_DISABLED, // 145 : GPIO[36] -> + CFG_DISABLED, // 146 : GPIO[37] -> + CFG_DISABLED, // 147 : GPIO[38] -> + CFG_DISABLED, // 148 : GPIO[39] -> + CFG_DISABLED, // 149 : GPIO[40] -> + CFG_DISABLED, // 150 : GPIO[41] -> + CFG_DISABLED, // 151 : GPIO[42] -> + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : PCIE_PERST0_N -> NAND_PERST + CFG_DISABLED, // 161 : PCIE_PERST1_N -> + CFG_DISABLED, // 162 : PCIE_PERST2_N -> + CFG_DISABLED, // 163 : PCIE_PERST3_N -> + CFG_DISABLED, // 164 : PCIE_CLKREQ0_N -> NAND_CLKREQ + CFG_DISABLED, // 165 : PCIE_CLKREQ1_N -> + CFG_DISABLED, // 166 : PCIE_CLKREQ2_N -> + CFG_DISABLED, // 167 : PCIE_CLKREQ3_N -> + +/* Port 21 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 22 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 23 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_DISABLED, // 192 : UART2_TXD -> + CFG_DISABLED, // 193 : UART2_RXD -> + CFG_DISABLED, // 194 : UART2_RTSN -> + CFG_DISABLED, // 195 : UART2_CTSN -> + CFG_DISABLED, // 196 : NAND_SYS_CLK -> NAND_SYS_CLK + CFG_DISABLED, // 197 : S3E_RESETN -> NAND_RESET + CFG_DISABLED, // 198 : TST_CLKOUT -> + CFG_DISABLED, +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED, // 2 : AOP_SPI_MISO -> + CFG_DISABLED, // 3 : AOP_UART1_TXD -> + CFG_DISABLED, // 4 : AOP_UART1_RXD -> + CFG_DISABLED, // 5 : AOP_UART0_TXD -> + CFG_DISABLED, // 6 : AOP_UART0_RXD -> + CFG_DISABLED, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED, // 8 : AOP_UART2_RXD -> + CFG_DISABLED, // 9 : AOP_I2CM_SDA -> + CFG_DISABLED, // 10 : AOP_I2CM_SCL -> + CFG_DISABLED, // 11 : AOP_FUNC[0] -> + CFG_DISABLED, // 12 : AOP_FUNC[1] -> + CFG_DISABLED, // 13 : AOP_FUNC[2] -> + CFG_DISABLED, // 14 : AOP_FUNC[3] -> + CFG_DISABLED, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : AOP_FUNC[5] -> + CFG_DISABLED, // 17 : AOP_FUNC[6] -> + CFG_DISABLED, // 18 : AOP_FUNC[7] -> + CFG_DISABLED, // 19 : AOP_FUNC[8] -> + CFG_DISABLED, // 20 : AOP_FUNC[9] -> + CFG_DISABLED, // 21 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 22 : AOP_SWD_TMS0 -> + CFG_DISABLED, // 23 : AOP_SWD_TMS1 -> + +/* Port 3 */ + CFG_DISABLED, // 24 : AOP_I2S_MCK -> + CFG_DISABLED, // 25 : AOP_I2S_BCLK -> + CFG_DISABLED, // 26 : AOP_I2S_LRCK -> + CFG_DISABLED, // 27 : AOP_I2S_DIN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + switch (gpioc) { + case 0: + return gpio_default_cfg; + case 1: + return gpio_1_default_cfg; + default: + panic("unknown gpio controller %u", gpioc); + } +} diff --git a/target/s8000sim/pinconfig_s8001sim.c b/target/s8000sim/pinconfig_s8001sim.c new file mode 100644 index 0000000..2e8c657 --- /dev/null +++ b/target/s8000sim/pinconfig_s8001sim.c @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include + + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : SPI1_SCLK -> + CFG_DISABLED, // 1 : SPI1_MOSI -> + CFG_DISABLED, // 2 : SPI1_MISO -> + CFG_DISABLED, // 3 : SPI1_SSIN -> + CFG_DISABLED, // 4 : ISP_I2C0_SDA -> + CFG_DISABLED, // 5 : ISP_I2C0_SCL -> + CFG_DISABLED, // 6 : ISP_I2C0_SDA -> + CFG_DISABLED, // 7 : ISP_I2C0_SCL -> + +/* Port 1 */ + CFG_DISABLED, // 8 : SENSOR0_ISTRB -> + CFG_DISABLED, // 9 : SENSOR0_RST -> + CFG_DISABLED, // 10 : SENSOR0_CLK -> + CFG_DISABLED, // 11 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // 12 : SENSOR1_ISTRB -> + CFG_DISABLED, // 13 : SENSOR1_RST -> + CFG_DISABLED, // 14 : SENSOR1_CLK -> + CFG_DISABLED, // 15 : SENSOR1_XSHUTDOWN -> + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[16] -> BOARD_ID[3] + CFG_DISABLED, // 17 : GPIO[17] -> + CFG_DISABLED, // 18 : GPIO[18] -> BOOT_CONFIG[0] + CFG_DISABLED, // 19 : I2S1_MCK -> + CFG_DISABLED, // 20 : I2S1_BLCK -> + CFG_DISABLED, // 21 : I2S1_LRCK -> + CFG_DISABLED, // 22 : I2S1_DIN -> + CFG_DISABLED, // 23 : I2S1_DOUT -> + +/* Port 3 */ + CFG_DISABLED, // 24 : NAND_SYS_CLK -> + CFG_DISABLED, // 25 : S3E0_RESETN -> + CFG_DISABLED, // 26 : S3E1_RESETN -> + CFG_DISABLED, // 27 : UART1_TXD -> + CFG_DISABLED, // 28 : UART1_RXD -> + CFG_DISABLED, // 29 : UART1_RTSN -> + CFG_DISABLED, // 30 : UART1_CTSN -> + CFG_DISABLED, // 31 : GPIO43 -> + +/* Port 4 */ + CFG_DISABLED, // 32 : I2S0_BCLK -> + CFG_DISABLED, // 33 : I2S0_LRCK -> + CFG_DISABLED, // 34 : I2S0_DIN -> + CFG_DISABLED, // 35 : I2S0_DOUT -> + CFG_DISABLED, // 36 : I2S0_MCK -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 5 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : I2S4_MCK -> + CFG_DISABLED, // 65 : I2S4_BCLK -> + CFG_DISABLED, // 66 : I2S4_LRCK -> + CFG_DISABLED, // 67 : I2S4_DIN -> + CFG_DISABLED, // 68 : I2S4_DOUT -> + CFG_DISABLED, // 69 : I2S2_MCK -> + CFG_DISABLED, // 70 : I2S2_BCLK -> + CFG_DISABLED, // 71 : I2S2_LRCK -> + +/* Port 9 */ + CFG_DISABLED, // 72 : I2S2_DIN -> + CFG_DISABLED, // 73 : I2S2_DOUT -> + CFG_DISABLED, // 74 : GPIO[0] -> + CFG_DISABLED, // 75 : GPIO[1] -> + CFG_DISABLED, // 76 : GPIO[2] -> + CFG_DISABLED, // 77 : GPIO[3] -> + CFG_DISABLED, // 78 : GPIO[4] -> + CFG_DISABLED, // 79 : GPIO[5] -> + +/* Port 10 */ + CFG_DISABLED, // 80 : GPIO[6] -> + CFG_DISABLED, // 81 : GPIO[7] -> + CFG_DISABLED, // 82 : GPIO[8] -> + CFG_DISABLED, // 83 : GPIO[9] -> + CFG_DISABLED, // 84 : GPIO[10] -> + CFG_DISABLED, // 85 : GPIO[11] -> + CFG_DISABLED, // 86 : GPIO[12] -> + CFG_DISABLED, // 87 : GPIO[13] -> + +/* Port 11 */ + CFG_DISABLED, // 88 : GPIO[14] -> + CFG_DISABLED, // 89 : GPIO[15] -> + CFG_DISABLED, // 90 : UART3_TXD -> + CFG_DISABLED, // 91 : UART3_RXD -> + CFG_DISABLED, // 92 : UART3_RTSN -> + CFG_DISABLED, // 93 : UART3_CTSN -> + CFG_FUNC0, // 94 : SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_FUNC0, // 95 : SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + +/* Port 12 */ + CFG_FUNC0, // 96 : SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1, // 97 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 98 : PCIE_PERST0_N -> NAND_PERST + CFG_DISABLED, // 99 : PCIE_PERST1_N -> + CFG_DISABLED, // 100 : PCIE_PERST2_N -> + CFG_DISABLED, // 101 : PCIE_PERST3_N -> + CFG_DISABLED, // 102 : PCIE_PERST4_N -> + CFG_DISABLED, // 103 : PCIE_PERST5_N -> + +/* Port 13 */ + CFG_DISABLED, // 104 : PCIE_CLKREQ0_N -> NAND_CLKREQ + CFG_DISABLED, // 105 : PCIE_CLKREQ1_N -> + CFG_DISABLED, // 106 : PCIE_CLKREQ2_N -> + CFG_DISABLED, // 107 : PCIE_CLKREQ3_N -> + CFG_DISABLED, // 108 : PCIE_CLKREQ4_N -> + CFG_DISABLED, // 109 : PCIE_CLKREQ5_N -> + CFG_DISABLED, // 110 : UART2_TXD -> + CFG_DISABLED, // 111 : UART2_RXD -> + +/* Port 14 */ + CFG_DISABLED, // 112 : UART2_RTSN -> + CFG_DISABLED, // 113 : UART2_CTSN -> + CFG_DISABLED, // 114 : I2C3_SDA -> + CFG_DISABLED, // 115 : I2C3_SCL -> + CFG_DISABLED, // 116 : GPIO[44] -> + CFG_DISABLED, // 117 : GPIO[45] -> + CFG_DISABLED, // 118 : GPIO[46] -> + CFG_DISABLED, // 119 : GPIO[47] -> + +/* Port 15 */ + CFG_DISABLED, // 120 : GPIO[48] -> + CFG_DISABLED, // 121 : GPIO[49] -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_IN, // 128 : MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // 129 : HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // 130 : SKEY_L -> + CFG_DISABLED, // 131 : SWD_TMS2 -> + CFG_DISABLED, // 132 : SWD_TMS3 -> + CFG_DISABLED, // 133 : UART5_RTXD -> + CFG_DISABLED, // 134 : I2C2_SDA -> + CFG_DISABLED, // 135 : I2C2_SCL -> + +/* Port 17 */ + CFG_DISABLED, // 136 : UART4_TXD -> + CFG_DISABLED, // 137 : UART4_RXD -> + CFG_DISABLED, // 138 : UART4_RTSN -> + CFG_DISABLED, // 139 : UART4_CTSN -> + CFG_DISABLED, // 140 : UART7_TXD -> + CFG_DISABLED, // 141 : UART7_RXD -> + CFG_DISABLED, // 142 : CLK32K_OUT -> + CFG_DISABLED, // 143 : DP_WAKEUP0 -> + +/* Port 18 */ + CFG_DISABLED, // 144 : DP_WAKEUP0 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 19 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED, // 160 : SPI2_SCLK -> + CFG_DISABLED, // 161 : SPI2_MOSI -> + CFG_DISABLED, // 162 : SPI2_MISO -> + CFG_DISABLED, // 163 : SPI2_SSIN -> + CFG_DISABLED, // 164 : I2C0_SDA -> + CFG_DISABLED, // 165 : I2C0_SCL -> + CFG_DISABLED, // 166 : SPI3_SCLK -> + CFG_DISABLED, // 167 : SPI3_MOSI -> + +/* Port 21 */ + CFG_DISABLED, // 168 : SPI3_MISO -> + CFG_DISABLED, // 169 : SPI3_SSIN -> + CFG_DISABLED, // 170 : UART0_TXD -> + CFG_DISABLED, // 171 : UART0_RXD -> + CFG_DISABLED, // 172 : UART6_TXD -> + CFG_DISABLED, // 173 : UART6_RXD -> + CFG_DISABLED, // 174 : TMR32_PWM0 -> + CFG_DISABLED, // 175 : TMR32_PWM1 -> + +/* Port 22 */ + CFG_DISABLED, // 176 : TMR32_PWM2 -> + CFG_DISABLED, // 177 : I2C1_SDA -> + CFG_DISABLED, // 178 : I2C1_SCL -> + CFG_DISABLED, // 179 : GPIO[19] -> + CFG_DISABLED, // 180 : GPIO[20] -> + CFG_DISABLED, // 181 : GPIO[21] -> + CFG_DISABLED, // 182 : GPIO[22] -> + CFG_DISABLED, // 183 : GPIO[23] -> + +/* Port 23 */ + CFG_DISABLED, // 184 : GPIO[24] -> + CFG_DISABLED, // 185 : GPIO[25] -> BOOT_CONFIG[1] + CFG_IN | PULL_DOWN, // 186 : GPIO[26] -> FORCE_DFU + CFG_DISABLED, // 187 : PSPI_MOSI -> + CFG_DISABLED, // 188 : DWI_DO -> + CFG_DISABLED, // 189 : PMGR_MISO -> + CFG_DISABLED, // 190 : PMGR_SCLK0 -> + CFG_DISABLED, // 191 : PMGR_SSCLK1 -> + +/* Port 24 */ + CFG_DISABLED, // 192 : DROOP -> + CFG_DISABLED, // 193 : SOCHOT1 -> + CFG_DISABLED, // 194 : EDP_HPD0 -> + CFG_DISABLED, // 195 : EDP_HPD1 -> + CFG_DISABLED, // 196 : I2S3_MCK -> + CFG_DISABLED, // 197 : I2S3_BCLK -> + CFG_DISABLED, // 198 : I2S3_LRCK -> + CFG_DISABLED, // 199 : I2S3_DOUT -> + +/* Port 25 */ + CFG_DISABLED, // 200 : I2S3_DIN -> + CFG_DISABLED | PULL_DOWN, // 201 : GPIO[27] -> DFU_STATUS + CFG_DISABLED, // 202 : GPIO[28] -> BOOT_CONFIG[2] + CFG_DISABLED, // 203 : GPIO[29] -> BOARD_ID[4] + CFG_DISABLED, // 204 : GPIO[30] -> + CFG_DISABLED, // 205 : GPIO[31] -> + CFG_DISABLED, // 206 : GPIO[32] -> + CFG_DISABLED, // 207 : GPIO[33] -> + +/* Port 26 */ + CFG_DISABLED, // 208 : GPIO[34] -> + CFG_DISABLED, // 209 : GPIO[35] -> + CFG_DISABLED, // 210 : GPIO[36] -> + CFG_DISABLED, // 211 : GPIO[37] -> + CFG_DISABLED, // 212 : GPIO[38] -> + CFG_DISABLED, // 213 : GPIO[39] -> + CFG_DISABLED, // 214 : GPIO[40] -> + CFG_DISABLED, // 215 : GPIO[41] -> + +/* Port 27 */ + CFG_DISABLED, // 216 : GPIO[42] -> + CFG_DISABLED, // 217 : TST_CLKOUT -> + CFG_DISABLED, // 218 : GPU_TRIGGER1 -> + CFG_DISABLED, // 219 : GPU_TRIGGER2 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t gpio_1_default_cfg[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED, // 2 : AOP_SPI_MISO -> + CFG_DISABLED, // 3 : AOP_UART1_TXD -> + CFG_DISABLED, // 4 : AOP_UART1_RXD -> + CFG_DISABLED, // 5 : AOP_UART0_TXD -> + CFG_DISABLED, // 6 : AOP_UART0_RXD -> + CFG_DISABLED, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED, // 8 : AOP_UART2_RXD -> + CFG_DISABLED, // 9 : AOP_I2CM_SDA -> + CFG_DISABLED, // 10 : AOP_I2CM_SCL -> + CFG_DISABLED, // 11 : AOP_FUNC[0] -> + CFG_DISABLED, // 12 : AOP_FUNC[1] -> + CFG_DISABLED, // 13 : AOP_FUNC[2] -> + CFG_DISABLED, // 14 : AOP_FUNC[3] -> + CFG_DISABLED, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : AOP_FUNC[5] -> + CFG_DISABLED, // 17 : AOP_FUNC[6] -> + CFG_DISABLED, // 18 : AOP_FUNC[7] -> + CFG_DISABLED, // 19 : AOP_FUNC[8] -> + CFG_DISABLED, // 20 : AOP_FUNC[9] -> + CFG_DISABLED, // 21 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 22 : AOP_SWD_TMS0 -> + CFG_DISABLED, // 23 : AOP_SWD_TMS1 -> + +/* Port 3 */ + CFG_DISABLED, // 24 : AOP_I2S_MCK -> + CFG_DISABLED, // 25 : AOP_I2S_BCLK -> + CFG_DISABLED, // 26 : AOP_I2S_LRCK -> + CFG_DISABLED, // 27 : AOP_I2S_DIN -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + switch (gpioc) { + case 0: + return gpio_default_cfg; + case 1: + return gpio_1_default_cfg; + default: + panic("unknown gpio controller %u", gpioc); + } +} diff --git a/target/s8000sim/rules.mk b/target/s8000sim/rules.mk new file mode 100644 index 0000000..e927902 --- /dev/null +++ b/target/s8000sim/rules.mk @@ -0,0 +1,46 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +# TBD - BUCK_* + +OPTIONS += \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + DCS_NUM_RANKS=1 \ + AMP_CALIBRATION_SKIP=1 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + WIFI_DTPATH=\"arm-io/wlan\" + +ifeq ($(SUB_PLATFORM),s8001) +OPTIONS += \ + DCS_NUM_CHANNELS=8 \ + DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 +else +OPTIONS += \ + DCS_NUM_CHANNELS=4 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o + +ifeq ($(SUB_PLATFORM),s8003) +ALL_OBJS += $(LOCAL_DIR)/pinconfig_s8000sim.o +else +ALL_OBJS += $(LOCAL_DIR)/pinconfig_$(SUB_TARGET).o +endif diff --git a/target/t7000fpga/include/target/adbe_settings.h b/target/t7000fpga/include/target/adbe_settings.h new file mode 100644 index 0000000..128c6f9 --- /dev/null +++ b/target/t7000fpga/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0, + .adbe0_tunable_mode_ctrl = 0, + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/t7000fpga/include/target/amcconfig.h b/target/t7000fpga/include/target/amcconfig.h new file mode 100644 index 0000000..31c19be --- /dev/null +++ b/target/t7000fpga/include/target/amcconfig.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if SUB_PLATFORM_T7000 +#include +#elif SUB_PLATFORM_T7001 +#include +#endif diff --git a/target/t7000fpga/include/target/amcconfig_t7000.h b/target/t7000fpga/include/target/amcconfig_t7000.h new file mode 100644 index 0000000..dd5ffc5 --- /dev/null +++ b/target/t7000fpga/include/target/amcconfig_t7000.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amc/amc.h, and this + * file should only by included from amc.c. + */ + +#define AMC_PARAMS_AP_DEV (1) + +static const struct amc_param amc_params_dev = { + .lat = 0x00040200, + .phyrdwrtim = 0x00010802, + .tREFi = 0x11, + .pdn = 0x22000203, + .derate = 0x04110111, + .read = 0x00000101, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x84, + .mr2 = 0x06, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050010, + .mcuchnhash = 0x0ffffd54, + .mcschnldec = 0x00010200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000601, + + .freq = { + { // 800MHz + .cas = 0x00000202, + .pch = 0x00020202, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002020, + .modereg = 0x20010722, + }, + { // 400MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + }, + { // 200MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + } + } +}; + +static const struct amc_param amc_params_ap = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050010, + .mcuchnhash = 0x0ffffd54, + .mcschnldec = 0x00010200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000601, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQCTL1, 0x00000158 }, + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, + { &rAMC_PWRMNGTPARAM, 0x01803000 }, +}; diff --git a/target/t7000fpga/include/target/amcconfig_t7001.h b/target/t7000fpga/include/target/amcconfig_t7001.h new file mode 100644 index 0000000..dd7fdc7 --- /dev/null +++ b/target/t7000fpga/include/target/amcconfig_t7001.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amc/amc.h, and this + * file should only by included from amc.c. + */ + +#define AMC_PARAMS_AP_DEV (1) + +static const struct amc_param amc_params_dev = { + .lat = 0x00040200, + .phyrdwrtim = 0x00010802, + .tREFi = 0x11, + .pdn = 0x22000203, + .derate = 0x04110111, + .read = 0x00000101, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x84, + .mr2 = 0x06, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050020, + .mcuchnhash = 0x0ffffd54, + .mcuchnhash2 = 0x0aaaaaa8, + .mcschnldec = 0x00020200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000501, + + .freq = { + { // 800MHz + .cas = 0x00000202, + .pch = 0x00020202, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002020, + .modereg = 0x20010722, + }, + { // 400MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + }, + { // 200MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x01020000, + .selfref = 0x00002000, + .modereg = 0x00010000, + } + } +}; + +static const struct amc_param amc_params_ap = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000001, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050020, + .mcuchnhash = 0x0ffffd54, + .mcuchnhash2 = 0x0aaaaaa8, + .mcschnldec = 0x00020200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000501, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQCTL1, 0x00000336 }, + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, + { &rAMC_PWRMNGTPARAM, 0x03523000 }, +}; diff --git a/target/t7000fpga/include/target/ampconfig.h b/target/t7000fpga/include/target/ampconfig.h new file mode 100644 index 0000000..597a304 --- /dev/null +++ b/target/t7000fpga/include/target/ampconfig.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_phy_params struct is defined in drivers/apple/amp_v3/amp_v3.h, and this + * file should only by included from amp_v3.c. + */ + +static const struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, + .rdcapcfg = 0x01010304, + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x21010309, + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x41010306, + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61010304, + }, + }, + .ampclk = 0x00010000, +}; diff --git a/target/t7000fpga/include/target/aspnandconfig.h b/target/t7000fpga/include/target/aspnandconfig.h new file mode 100644 index 0000000..0800563 --- /dev/null +++ b/target/t7000fpga/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/t7000fpga/include/target/gpiodef.h b/target/t7000fpga/include/target/gpiodef.h new file mode 100644 index 0000000..2a0230f --- /dev/null +++ b/target/t7000fpga/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* T7000FPGA specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/t7000fpga/include/target/pinconfig.h b/target/t7000fpga/include/target/pinconfig.h new file mode 100644 index 0000000..a551deb --- /dev/null +++ b/target/t7000fpga/include/target/pinconfig.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#if SUB_PLATFORM_T7000 +#include +#elif SUB_PLATFORM_T7001 +#include +#endif diff --git a/target/t7000fpga/include/target/uartconfig.h b/target/t7000fpga/include/target/uartconfig.h new file mode 100644 index 0000000..7d1cd6f --- /dev/null +++ b/target/t7000fpga/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012, 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/t7000fpga/init.c b/target/t7000fpga/init.c new file mode 100644 index 0000000..0933cb4 --- /dev/null +++ b/target/t7000fpga/init.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !SUPPORT_FPGA +#error "FPGA target without SUPPORT_FPGA set" +#endif + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +void * target_get_display_configuration(void) +{ + return ((void *)(NULL)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", " debug=0x14e serial=3 amfi_unrestrict_task_for_pid=1 amfi_allow_any_signature=1 amfi_get_out_of_my_way=1 cs_enforcement_disable=1 fips_mode=0", 0); + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "fpga-wsvga", 0); + env_set("ramdisk-delay", "30000000", 0); /* This tells PurpleRestore to slow down; rdar://6345846 */ + env_set("idle-off", "false", 0); + env_set("bootdelay", "3", 0); + env_set("debug-uarts", "3", 0); +} + +#endif + +#if WITH_DEVICETREE + +#define MAX_NODES_PER_DEVICE 3 +struct fpgaNode_t +{ + uint32_t mask; // Block enable mask + const char *nodeName[MAX_NODES_PER_DEVICE]; // Device tree nodes to disable if block is absent +}; + +// Devices tree nodes to disable based upon FPGA block instantiation +struct fpgaNode_t fpgaNodes[] = { + { FPGA_HAS_PCIE, { "arm-io/apcie", "arm-io/dart-apcie0", "arm-io/dart-apcie0/mapper-apcie0" }}, + { FPGA_HAS_PCIE, { "arm-io/apcie", "arm-io/dart-apcie1", "arm-io/dart-apcie1/mapper-apcie1" }}, + { FPGA_HAS_VXD, { "arm-io/vxd", NULL, NULL }}, + { FPGA_HAS_AVE, { "arm-io/ave", "arm-io/dart-ave", "arm-io/dart-ave/mapper-ave" }}, + { FPGA_HAS_ISP, { "arm-io/isp", "arm-io/dart-isp", "arm-io/dart-isp/mapper-isp" }}, + { FPGA_HAS_DISP0, { "arm-io/disp0", "arm-io/dart-disp0", "arm-io/dart-disp0/mapper-disp0" }}, + { FPGA_HAS_DISP1, { "arm-io/disp1", "arm-io/dart-disp1", "arm-io/dart-disp1/mapper-disp1" }}, + { FPGA_HAS_MSR, { "arm-io/scaler0", "arm-io/dart-scaler", "arm-io/dart-scaler/mapper-scaler" }}, + { FPGA_HAS_JPEG, { "arm-io/jpeg", "arm-io/dart-jpeg", "arm-io/dart-jpeg/mapper-jpeg" }}, + { FPGA_HAS_GFX, { "arm-io/sgx", NULL, NULL }}, +}; + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + uint32_t i, j; + + // Get the hardware blocks that are instantiated on this FPGA. + uint32_t fpgaBlocks = chipid_get_fpga_block_instantiation(); + dprintf(DEBUG_SPEW, "FPGA block instantiation mask = 0x%X\n", fpgaBlocks); + + for (i = 0; i < sizeof(fpgaNodes)/sizeof(fpgaNodes[0]); i++) { + if ((fpgaBlocks & fpgaNodes[i].mask) == 0) { + for (j = 0; j < MAX_NODES_PER_DEVICE; j++) { + if (fpgaNodes[i].nodeName[j] == NULL) { + break; + } + if (FindNode(0, fpgaNodes[i].nodeName[j], &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (j == 0) { + dprintf(DEBUG_INFO, + "FPGA block not instantiated: disabling %s\n", + fpgaNodes[i].nodeName[j]); + } + propName[0] = '~'; + } else { + dprintf(DEBUG_SPEW, + "FPGA: Could not find 'compatible' property for %s DT node\n", + fpgaNodes[i].nodeName[j]); + } + } else { + dprintf(DEBUG_SPEW, + "FPGA: Could not find %s DT node\n", + fpgaNodes[i].nodeName[j]); + } + } + } + } + return 0; +} +#endif + + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/t7000fpga/pinconfig_t7000fpga.c b/target/t7000fpga/pinconfig_t7000fpga.c new file mode 100644 index 0000000..2cea62a --- /dev/null +++ b/target/t7000fpga/pinconfig_t7000fpga.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* Pin configuration for FPGA - Fiji I/O Spreadsheet v9.3 */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // ULPI_DIR -> + CFG_DISABLED, // ULPI_STP -> + CFG_DISABLED, // ULPI_NXT -> + CFG_DISABLED, // ULPI_DATA7 -> + CFG_DISABLED, // ULPI_DATA6 -> + CFG_DISABLED, // ULPI_DATA5 -> + CFG_DISABLED, // ULPI_DATA4 -> + CFG_DISABLED, // ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // ULPI_DATA3 -> + CFG_DISABLED, // ULPI_DATA2 -> + CFG_DISABLED, // ULPI_DATA1 -> + CFG_DISABLED, // ULPI_DATA0 -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // GPIO11 -> + CFG_IN, // GPIO12 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // CLK32K_OUT -> + +/* Port 5 */ + CFG_DISABLED, // PCIE_CLKREQ0_N -> + CFG_DISABLED, // PCIE_CLKREQ1_N -> + CFG_DISABLED, // NAND_SYS_CLK -> + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> + CFG_IN, // GPIO3 -> MENU_KEY (REQUEST_DFU2) + CFG_DISABLED, // GPIO4 -> + +/* Port 6 */ + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO20 -> + +/* Port 7 */ + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // UART5_RTXD -> + CFG_DISABLED, // UART8_TXD -> + CFG_DISABLED, // UART8_RXD -> + CFG_FUNC0, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_FUNC0, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_FUNC0, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1, // SPI0_SSIN -> + +/* Port 8 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOARD_ID[4] + CFG_DISABLED, // GPIO34 -> + +/* Port 9 */ + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO39 -> + CFG_DISABLED, // GPIO42 -> + CFG_DISABLED, // GPIO43 -> + CFG_DISABLED, // DISP_VSYNC -> + CFG_FUNC0, // UART0_TXD -> + +/* Port 10 */ + CFG_FUNC0, // UART0_RXD -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + +/* Port 11 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 12 */ + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // DWI_DO -> + +/* Port 13 */ + CFG_DISABLED, // DWI_CLK -> + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO19 -> + CFG_IN, // GPIO26 -> FORCE_DFU + CFG_DISABLED, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + +/* Port 14 */ + CFG_DISABLED, // CPU_SLEEP_STATUS -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO15 -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + +/* Port 15 */ + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO30 -> + +/* Port 16 */ + CFG_DISABLED, // GPIO31 -> + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO40 -> + CFG_DISABLED, // GPIO41 -> + CFG_DISABLED, // I2S4_MCK -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + +/* Port 17 */ + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 18 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 19 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 20 */ + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + +/* Port 21 */ + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + +/* Port 22 */ + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // EDP_HPD -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 23 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + +/* Port 24 */ + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // ISP_UART0_TXD -> + CFG_DISABLED, // ISP_UART0_RXD -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_DISABLED, // UART7_TXD -> + CFG_DISABLED, // UART7_RXD -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/t7000fpga/pinconfig_t7001fpga.c b/target/t7000fpga/pinconfig_t7001fpga.c new file mode 100644 index 0000000..64391e0 --- /dev/null +++ b/target/t7000fpga/pinconfig_t7001fpga.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* Default T7001 FPGA Pin Configuration - Capri I/O Spreadsheet v10.29 */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + +/* Port 1 */ + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RTXD -> + CFG_DISABLED, // DWI0_DO -> + CFG_DISABLED, // DWI0_CLK -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2S0_LRCK -> + +/* Port 5 */ + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + +/* Port 6 */ + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // DISP_VSYNC -> + +/* Port 7 */ + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + CFG_DISABLED, // CPU_SLEEP_STATUS -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // ISP_UART0_TXD -> + CFG_DISABLED, // ISP_UART0_RXD -> + CFG_DISABLED, // UART7_TXD -> + +/* Port 8 */ + CFG_DISABLED, // UART7_RXD -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_FUNC0, // SPI0_SCLK -> BOARD_ID0 + CFG_FUNC0, // SPI0_MOSI -> BOARD_ID1 + CFG_FUNC0, // SPI0_MISO -> BOARD_ID2 + CFG_OUT_1, // SPI0_SSIN -> + CFG_DISABLED, // I2S3_MCK -> + +/* Port 9 */ + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + +/* Port 10 */ + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 11 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 12 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID3 + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG0 + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 13 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG1 + CFG_IN, // GPIO26 -> FORCE_DFU + CFG_DISABLED, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG2 + CFG_DISABLED, // GPIO29 -> BOARD_ID4 + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> BOOT_CONFIG3 + +/* Port 14 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 15 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // UART8_TXD -> + CFG_DISABLED, // UART8_RXD -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_FUNC0, // UART0_TXD -> + CFG_FUNC0, // UART0_RXD -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + +/* Port 17 */ + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + +/* Port 18 */ + CFG_DISABLED, // EDP_HPD -> + CFG_DISABLED, // I2S4_MCK -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + +/* Port 19 */ + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + CFG_DISABLED, // CLK32K_OUT -> + CFG_DISABLED, // ULPI_DIR -> + +/* Port 20 */ + CFG_DISABLED, // ULPI_STP -> + CFG_DISABLED, // ULPI_NXT -> + CFG_DISABLED, // ULPI_DATA7 -> + CFG_DISABLED, // ULPI_DATA6 -> + CFG_DISABLED, // ULPI_DATA5 -> + CFG_DISABLED, // ULPI_DATA4 -> + CFG_DISABLED, // ULPI_CLK -> + CFG_DISABLED, // ULPI_DATA3 -> + +/* Port 21 */ + CFG_DISABLED, // ULPI_DATA2 -> + CFG_DISABLED, // ULPI_DATA1 -> + CFG_DISABLED, // ULPI_DATA0 -> + CFG_DISABLED, // DWI1_DO -> + CFG_DISABLED, // DWI1_CLK -> + CFG_DISABLED, // PCIE_CLKREQ0_N -> + CFG_DISABLED, // PCIE_CLKREQ1_N -> + CFG_DISABLED, // PCIE_CLKREQ2_N -> + +/* Port 22 */ + CFG_DISABLED, // PCIE_CLKREQ3_N -> + CFG_DISABLED, // NAND_SYS_CLK -> + CFG_DISABLED, // PCIE_PERST0_N -> + CFG_DISABLED, // PCIE_PERST1_N -> + CFG_DISABLED, // PCIE_PERST2_N -> + CFG_DISABLED, // PCIE_PERST3_N -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/t7000fpga/rules.mk b/target/t7000fpga/rules.mk new file mode 100644 index 0000000..49b885e --- /dev/null +++ b/target/t7000fpga/rules.mk @@ -0,0 +1,41 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x85100000 \ + DISPLAY_FPGA_TUNABLES=1 \ + AMC_NUM_RANKS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + WITH_TARGET_AMC_PARAMS=1 \ + WITH_TARGET_AMP_PARAMS=1 + +ifeq ($(SUB_PLATFORM),t7000) +OPTIONS += AMC_NUM_CHANNELS=2 +else +OPTIONS += AMC_NUM_CHANNELS=4 +OPTIONS += BUCK_RAM=2 +endif + +OPTIONS += \ + SUPPORT_FPGA=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig_$(SUB_TARGET).o diff --git a/target/t8010fpga/include/target/adbe_settings.h b/target/t8010fpga/include/target/adbe_settings.h new file mode 100644 index 0000000..87b1b1e --- /dev/null +++ b/target/t8010fpga/include/target/adbe_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_pos_vbi_pulse = 0x0000, + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_vblank_busy_finish = 0, + .adbe0_tunable_mode_ctrl = 0, + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/t8010fpga/include/target/dcsfixup.h b/target/t8010fpga/include/target/dcsfixup.h new file mode 100644 index 0000000..fffc991 --- /dev/null +++ b/target/t8010fpga/include/target/dcsfixup.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include SUB_PLATFORM_TARGET_HEADER(dcsfixup) + diff --git a/target/t8010fpga/include/target/dcsfixup_t8010.h b/target/t8010fpga/include/target/dcsfixup_t8010.h new file mode 100644 index 0000000..78c168b --- /dev/null +++ b/target/t8010fpga/include/target/dcsfixup_t8010.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static inline +void dcs_init_config_fixup_params(dcs_config_params_t *dcs_params, dcs_target_t targtype) +{ + dcs_params->freq[0].freqchngctl[2] = 0xa303000b; + dcs_params->freq[1].freqchngctl[2] = 0xd303000b; + dcs_params->freq[0].lat = 0x001130c2; + dcs_params->freq[1].lat = 0x001020c2; + dcs_params->freq[0].phyrdwrtim = 0x00010d01; + dcs_params->freq[1].phyrdwrtim = 0x00010c01; + dcs_params->freq[3].phyrdwrtim = 0x00010b01; + dcs_params->freq[0].caspch = 0x40c20402; + dcs_params->freq[0].act = 0x01020202; + dcs_params->freq[0].autoref = 0x010100a0; + dcs_params->freq[0].selfref = 0x28002012; + dcs_params->freq[0].pdn = 0x00000033; + dcs_params->modereg = 0x060c5024; + dcs_params->modereg1 = 0x00000005; + dcs_params->freq[1].caspch = 0x40c20402; + dcs_params->freq[1].act = 0x01020202; + dcs_params->freq[1].autoref = 0x0101006b; + dcs_params->freq[1].selfref = 0x28002012; + dcs_params->freq[1].pdn = 0x00000033; + dcs_params->freq[2].caspch = 0x40c20402; + dcs_params->freq[2].act = 0x01020202; + dcs_params->freq[2].autoref = 0x01010014; + dcs_params->freq[2].selfref = 0x28002012; + dcs_params->freq[3].act = 0x01020404; + dcs_params->freq[3].autoref = 0x01010005; + dcs_params->freq[3].selfref = 0x28002012; + dcs_params->autoref_params = 0x00150013; + dcs_params->pdn = 0x31276222; + dcs_params->freq[0].derate = 0x08212082; + dcs_params->freq[1].derate = 0x08212082; + dcs_params->freq[2].derate = 0x08212082; + dcs_params->freq[0].lat2 = 0x001110c2; + dcs_params->freq[1].lat2 = 0x001110c2; + dcs_params->freq[0].tat = 0x01212222; + dcs_params->freq[1].tat = 0x01212222; + dcs_params->freq[3].mifqmaxctrl = 0x00000003; + dcs_params->freq[0].rdcapcfg = 0x00000606; + dcs_params->freq[1].rdcapcfg = 0x20000606; + dcs_params->freq[2].rdcapcfg = 0x40000606; + dcs_params->freq[3].rdcapcfg = 0x60000606; + dcs_params->b0odtctrl = 0x00000000; + dcs_params->b1odtctrl = 0x00000000; + dcs_params->dqs0odtctrl = 0x00000000; + dcs_params->dqs1odtctrl = 0x00000000; + dcs_params->freq[0].autoref2 = 0x01010001; + dcs_params->freq[1].autoref2 = 0x01010001; + dcs_params->freq[2].autoref2 = 0x01010001; + dcs_params->freq[3].autoref2 = 0x01010001; + dcs_params->autoref_params2 = 0x00170013; + dcs_params->odtszqc = 0x00000000; + dcs_params->odtszqc2 = 0xc0000000; + dcs_params->qbrparam = 0x00001000; + dcs_params->odtszqc3 = 0xc0002320; +}; diff --git a/target/t8010fpga/include/target/gpiodef.h b/target/t8010fpga/include/target/gpiodef.h new file mode 100644 index 0000000..dc79ebb --- /dev/null +++ b/target/t8010fpga/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* T8010FPGA specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/t8010fpga/include/target/uartconfig.h b/target/t8010fpga/include/target/uartconfig.h new file mode 100644 index 0000000..c60bd47 --- /dev/null +++ b/target/t8010fpga/include/target/uartconfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/t8010fpga/init.c b/target/t8010fpga/init.c new file mode 100644 index 0000000..72d70d9 --- /dev/null +++ b/target/t8010fpga/init.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !SUPPORT_FPGA +#error "FPGA target without SUPPORT_FPGA set" +#endif + +static uint32_t display_config; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 1); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +void * target_get_display_configuration(void) +{ + display_config = 0x00000000; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", " debug=0x14e serial=3 amfi=3 amfi_get_out_of_my_way=1 cs_enforcement_disable=1 fips_mode=0", 0); + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "fpga-wsvga", 0); + env_set("ramdisk-delay", "60000000", 0); /* This tells PurpleRestore to slow down; rdar://6345846 */ + env_set("idle-off", "false", 0); + env_set("bootdelay", "3", 0); + env_set("debug-uarts", "3", 0); +} + +#endif + +#if WITH_DEVICETREE + +#define MAX_NODES_PER_DEVICE 3 +struct fpgaNode_t +{ + uint32_t mask; // Block enable mask + const char *nodeName[MAX_NODES_PER_DEVICE]; // Device tree nodes to disable if block is absent +}; + +// Devices tree nodes to disable based upon FPGA block instantiation +struct fpgaNode_t fpgaNodes[] = { + { FPGA_HAS_VXD, { "arm-io/vxd", NULL, NULL }}, + { FPGA_HAS_AVE, { "arm-io/ave", "arm-io/dart-ave", "arm-io/dart-ave/mapper-ave" }}, + { FPGA_HAS_ISP, { "arm-io/isp", "arm-io/dart-isp", "arm-io/dart-isp/mapper-isp" }}, + { FPGA_HAS_DISP, { "arm-io/disp0", "arm-io/dart-disp0", "arm-io/dart-disp0/mapper-disp0" }}, + { FPGA_HAS_MSR, { "arm-io/scaler0", "arm-io/dart-scaler", "arm-io/dart-scaler/mapper-scaler" }}, + { FPGA_HAS_JPEG, { "arm-io/jpeg0", "arm-io/dart-jpeg0", "arm-io/dart-jpeg0/mapper-jpeg0" }}, + { FPGA_HAS_JPEG, { "arm-io/jpeg1", "arm-io/dart-jpeg1", "arm-io/dart-jpeg1/mapper-jpeg1" }}, + { FPGA_HAS_GFX, { "arm-io/sgx", NULL, NULL }}, +}; + +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + uint32_t i, j; + + // Get the hardware blocks that are instantiated on this FPGA. + uint32_t fpgaBlocks = chipid_get_fpga_block_instantiation(); + dprintf(DEBUG_SPEW, "FPGA block instantiation mask = 0x%X\n", fpgaBlocks); + + for (i = 0; i < sizeof(fpgaNodes)/sizeof(fpgaNodes[0]); i++) { + if ((fpgaBlocks & fpgaNodes[i].mask) == 0) { + for (j = 0; j < MAX_NODES_PER_DEVICE; j++) { + if (fpgaNodes[i].nodeName[j] == NULL) { + break; + } + if (FindNode(0, fpgaNodes[i].nodeName[j], &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (j == 0) { + dprintf(DEBUG_INFO, + "FPGA block not instantiated: disabling %s\n", + fpgaNodes[i].nodeName[j]); + } + propName[0] = '~'; + } else { + dprintf(DEBUG_SPEW, + "FPGA: Could not find 'compatible' property for %s DT node\n", + fpgaNodes[i].nodeName[j]); + } + } else { + dprintf(DEBUG_SPEW, + "FPGA: Could not find %s DT node\n", + fpgaNodes[i].nodeName[j]); + } + } + } + } + return 0; +} +#endif + + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/t8010fpga/pinconfig_t8010fpga.c b/target/t8010fpga/pinconfig_t8010fpga.c new file mode 100644 index 0000000..732d564 --- /dev/null +++ b/target/t8010fpga/pinconfig_t8010fpga.c @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: cayman io list. ver 3.13 + I/O Spreadsheet tracker: H9: Update SecureROM pin configuration to I/O spreadsheet v3.13 + Conversion command: csvtopinconfig.py --rom --soc h9p --pupd-column 'Default pull-up/pull-down' --netname-column D1x_Net --copyright 2015 --radar ' H9: Update SecureROM pin configuration to I/O spreadsheet v3.13' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 0 : I2S0_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 1 : I2S0_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 2 : I2S0_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 3 : I2S0_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 4 : I2S0_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 5 : I2S2_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 6 : I2S2_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 7 : I2S2_LRCK -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 8 : I2S2_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 9 : I2S2_DOUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 10 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 11 : S3E_RESETN -> AP_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 12 : PCIE_PERST0_N -> PCIE_AP_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 13 : PCIE_PERST1_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 14 : PCIE_PERST2_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 15 : PCIE_PERST3_N -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 16 : PCIE_CLKREQ0_N -> PCIE_NAND_BI_AP_CLKREQ_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 17 : PCIE_CLKREQ1_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 18 : PCIE_CLKREQ2_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 19 : PCIE_CLKREQ3_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 20 : GPIO[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : GPIO[1] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : GPIO[2] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 23 : GPIO[3] -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 24 : GPIO[4] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 25 : GPIO[5] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 26 : GPIO[6] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 27 : GPIO[7] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 28 : GPIO[8] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 29 : GPIO[9] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 30 : GPIO[10] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 31 : GPIO[11] -> + +/* Port 4 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 32 : CLK32K_OUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 33 : DWI_DO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 34 : DWI_CLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 35 : PMU_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 36 : PMU_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 37 : PMU_SCLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 38 : GPIO[12] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 39 : I2C1_SDA -> + +/* Port 5 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 40 : I2C1_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 41 : I2C3_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 42 : I2C3_SCL -> + CFG_DISABLED, // 43 : SENSOR2_RST -> + CFG_DISABLED, // 44 : SENSOR3_RST -> + CFG_DISABLED, // 45 : SENSOR4_RST -> + CFG_DISABLED, // 46 : SENSOR_INT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 47 : ISP_I2C3_SDA -> + +/* Port 6 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 48 : ISP_I2C3_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 49 : ISP_I2C2_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 50 : ISP_I2C2_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 51 : ISP_I2C1_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 52 : ISP_I2C1_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 53 : ISP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 54 : ISP_I2C0_SCL -> + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 64 : SENSOR0_ISTRB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 65 : SENSOR0_RST -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 66 : SENSOR0_CLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 67 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 68 : SENSOR1_ISTRB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 69 : SENSOR1_RST -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 70 : SENSOR1_CLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 71 : SENSOR1_XSHUTDOWN -> + +/* Port 9 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 72 : SENSOR2_CLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 73 : I2S1_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 74 : I2S1_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 75 : I2S1_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 76 : I2S1_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 77 : I2S1_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 78 : SPI2_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 79 : SPI2_MOSI -> + +/* Port 10 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 80 : SPI2_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 81 : SPI2_SSIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 82 : SPI3_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 83 : SPI3_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 84 : SPI3_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 85 : SPI3_SSIN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 86 : GPIO[31] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 87 : GPIO[32] -> + +/* Port 11 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 88 : GPIO[33] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 89 : GPIO[34] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 90 : GPIO[35] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 91 : GPIO[36] -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 96 : UART1_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 97 : UART1_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 98 : UART1_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 99 : UART1_CTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 100 : UART4_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 101 : UART4_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 102 : UART4_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 103 : UART4_CTSN -> + +/* Port 13 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 14 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 15 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 128 : SPI1_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 129 : SPI1_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 130 : SPI1_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 131 : SPI1_SSIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 132 : I2C2_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 133 : I2C2_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 134 : UART3_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 135 : UART3_RXD -> + +/* Port 17 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 136 : UART3_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 137 : UART3_CTSN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 139 : GPIO[30] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 140 : GPIO[13] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 141 : GPIO[14] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 142 : GPIO[15] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 143 : DROOP -> + +/* Port 18 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 144 : SOCHOT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 145 : TMR32_PWM0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 146 : TMR32_PWM1 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 147 : TMR32_PWM2 -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 148 : UART2_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 149 : UART2_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 150 : UART2_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 151 : UART2_CTSN -> + +/* Port 19 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 152 : UART7_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 153 : UART7_RXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 154 : DP_WAKEUP -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 160 : GPIO[37] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 161 : GPIO[38] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 162 : GPIO[39] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 163 : GPIO[40] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 164 : GPIO[41] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 165 : GPIO[16] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 166 : GPIO[17] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 167 : GPIO[18] -> BOOT_CONFIG0 + +/* Port 21 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 168 : GPIO[19] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 169 : GPIO[20] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 170 : GPIO[21] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 171 : GPIO[22] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 172 : GPIO[23] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 173 : UART5_RTXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 174 : TST_CLKOUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 175 : EDP_HPD -> + +/* Port 22 */ + CFG_DISABLED, // 176 : DISP_TOUCH_BSYNC0 -> + CFG_DISABLED, // 177 : DISP_TOUCH_BSYNC1 -> + CFG_DISABLED, // 178 : DISP_TOUCH_EB -> + CFG_IN, // 179 : REQUEST_DFU1 -> PMU_TO_AP_BUF_BUTTON1 + CFG_IN, // 180 : REQUEST_DFU2 -> PMU_TO_AP_BUF_BUTTON2 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 181 : SWD_TMS2 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 182 : SWD_TMS3 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 183 : GPU_TRIGGER -> + +/* Port 23 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 184 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 185 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 186 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 187 : SPI0_SSIN -> BOARD_ID3 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 192 : UART0_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 193 : UART0_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 194 : UART6_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 195 : UART6_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 196 : I2C0_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 197 : I2C0_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 198 : I2S3_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 199 : I2S3_BCLK -> + +/* Port 25 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 200 : I2S3_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 201 : I2S3_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 202 : I2S3_DIN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 203 : GPIO[24] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 204 : GPIO[25] -> BOOT_CONFIG1 + CFG_IN | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 205 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 206 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 207 : GPIO[28] -> BOOT_CONFIG2 +}; + +static const uint32_t pinconfig_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 2 : AOP_SPI_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 3 : AOP_UART0_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 4 : AOP_UART0_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 5 : AOP_UART1_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 6 : AOP_UART1_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 8 : AOP_UART2_RXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 9 : AOP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 10 : AOP_I2C0_SCL -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 11 : AOP_FUNC[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 12 : AOP_FUNC[1] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 13 : AOP_FUNC[2] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 14 : AOP_FUNC[3] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 16 : AOP_FUNC[5] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 17 : AOP_FUNC[6] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 18 : AOP_FUNC[7] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 19 : AOP_FUNC[8] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 20 : AOP_FUNC[9] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : AOP_FUNC[10] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : AOP_FUNC[11] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 23 : AOP_FUNC[12] -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 24 : AOP_FUNC[13] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 25 : AOP_FUNC[14] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 26 : AOP_FUNC[15] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 27 : AOP_SWD_TCK_OUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 28 : AOP_SWD_TMS0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 29 : AOP_SWD_TMS1 -> + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 32 : AOP_I2S_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 33 : AOP_I2S_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 34 : AOP_I2S_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 35 : AOP_I2S_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 36 : AOP_I2S_MCK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 37 : DOCK_CONNECT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 38 : DOCK_ATTENTION -> + CFG_DISABLED, // 39 : AOP_PDM_CLK0 -> + +/* Port 5 */ + CFG_DISABLED, // 40 : AOP_PDM_DATA0 -> + CFG_DISABLED, // 41 : AOP_PDM_DATA1 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : XI0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 65 : XO0 -> + CFG_DISABLED, // 66 : ANALOGMUX_OUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 67 : CFSB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 68 : HOLD_RESET -> + CFG_DISABLED, // 69 : TESTMODE -> + CFG_DISABLED, // 70 : PACKAGED_N -> + CFG_DISABLED, // 71 : CFSB_AOP -> + +/* Port 9 */ + CFG_DISABLED, // 72 : COLD_RESETN -> + CFG_DISABLED, // 73 : JTAG_TRSTN -> + CFG_DISABLED, // 74 : JTAG_SEL -> + CFG_DISABLED, // 75 : JTAG_TMS -> + CFG_DISABLED, // 76 : JTAG_TDI -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 77 : JTAG_TDO -> + CFG_DISABLED, // 78 : JTAG_TCK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 79 : AOP_DDR_REQ -> + +/* Port 10 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 80 : AOP_DDR_RESETN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 81 : AWAKE_REQ -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 82 : AWAKE_RESETN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 83 : WDOG -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 84 : RT_CLK32768 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 0, { pinconfig_0, pinconfig_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/t8010fpga/rules.mk b/target/t8010fpga/rules.mk new file mode 100644 index 0000000..ab90562 --- /dev/null +++ b/target/t8010fpga/rules.mk @@ -0,0 +1,38 @@ +# Copyright (C) 2012-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + DISPLAY_FPGA_TUNABLES=1 \ + DCS_RUN_AT_50MHZ=1 \ + DCS_NUM_CHANNELS=4 \ + DCS_NUM_RANKS=1 \ + AMP_CALIBRATION_SKIP=1 \ + DCS_FIXUP_PARAMS=1 \ + TARGET_DWI_FREQUENCY=24000000 \ + TARGET_DWI_TRANSFER_GAP_US=2.5 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 + +OPTIONS += \ + SUPPORT_FPGA=1 + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o +ALL_OBJS += $(LOCAL_DIR)/pinconfig_$(SUB_TARGET).o diff --git a/target/t8010sim/include/target/gpiodef.h b/target/t8010sim/include/target/gpiodef.h new file mode 100644 index 0000000..a4f3e87 --- /dev/null +++ b/target/t8010sim/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* Typhonic specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/t8010sim/include/target/nand_spec_tables.h b/target/t8010sim/include/target/nand_spec_tables.h new file mode 100644 index 0000000..029be11 --- /dev/null +++ b/target/t8010sim/include/target/nand_spec_tables.h @@ -0,0 +1,153 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* blocksPerCS */ 4100, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_TOSHIBA_MLC, + /* diesPerCS */ 1 + } +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + } +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Toshiba" + } +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ + { + /* packageId */ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + }, + /* appleName */ "335S0700", + /* vendor_part_num */ "TH58NVG6D2FLA49", + /* package_type */ "DDP", + /* package_size */ "1.00mm LGA" + } +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + } +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000303 + }, + + /* useToggleMode */ 0, + /* useDiffDQSMode */ 0, + /* useDiffREMode */ 0, + /* useVref */ 0 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 0 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/t8010sim/include/target/powerconfig.h b/target/t8010sim/include/target/powerconfig.h new file mode 100644 index 0000000..74168da --- /dev/null +++ b/target/t8010sim/include/target/powerconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +// Minimal definitions to make lib/power.c happy +#define TARGET_POWER_NO_BATTERY (1) +#define PRECHARGE_BACKLIGHT_LEVEL (824) +#define ALWAYS_BOOT_BATTERY_VOLTAGE (5000) + +// This fake SoC block takes the place of the external PMU in Fastsim +#define SWIFTER_PMU_BASE (0x20F050000) + +#endif diff --git a/target/t8010sim/include/target/uartconfig.h b/target/t8010sim/include/target/uartconfig.h new file mode 100644 index 0000000..753c38b --- /dev/null +++ b/target/t8010sim/include/target/uartconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2011-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#endif diff --git a/target/t8010sim/init.c b/target/t8010sim/init.c new file mode 100644 index 0000000..cd4bf0d --- /dev/null +++ b/target/t8010sim/init.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uint32_t display_config; + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +void * target_get_display_configuration(void) +{ + display_config = 0x00000000; + return ((void *)(&display_config)); +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", "debug=0x14e serial=3 amfi=0x83 cs_enforcement_disable=1 fips_mode=0 -disable_aslr", ENV_PERSISTENT); + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "fpga-wsvga", 0); + env_set("idle-off", "false", 0); + env_set("kaslr-slide", "0x10000000", 0); + env_set("wifiaddr", "12:22:33:44:55:66", 0); + env_set("ethaddr", "12:22:33:44:55:77", 0); + env_set("btaddr", "00:00:00:00:00:00", 0); +} + +#endif + +#if WITH_DEVICETREE + +#define ROOT_DTPATH "" +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Overwrite the serial-number with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "serial-number property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *serial = (uint64_t *)propData; + serial[0] = *(volatile uint64_t *)0x20f050040; + serial[1] = *(volatile uint64_t *)0x20f050048; + serial[2] = *(volatile uint64_t *)0x20f050050; + serial[3] = *(volatile uint64_t *)0x20f050058; + } + } + + // Overwrite the region-info with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "region-info"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "region-info property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *region = (uint64_t *)propData; + region[0] = *(volatile uint64_t *)0x20f050060; + region[1] = *(volatile uint64_t *)0x20f050068; + region[2] = *(volatile uint64_t *)0x20f050070; + region[3] = *(volatile uint64_t *)0x20f050078; + } + } + + return 0; +} + +#endif + + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/t8010sim/pinconfig_t8010sim.c b/target/t8010sim/pinconfig_t8010sim.c new file mode 100644 index 0000000..732d564 --- /dev/null +++ b/target/t8010sim/pinconfig_t8010sim.c @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: cayman io list. ver 3.13 + I/O Spreadsheet tracker: H9: Update SecureROM pin configuration to I/O spreadsheet v3.13 + Conversion command: csvtopinconfig.py --rom --soc h9p --pupd-column 'Default pull-up/pull-down' --netname-column D1x_Net --copyright 2015 --radar ' H9: Update SecureROM pin configuration to I/O spreadsheet v3.13' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 0 : I2S0_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 1 : I2S0_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 2 : I2S0_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 3 : I2S0_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 4 : I2S0_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 5 : I2S2_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 6 : I2S2_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 7 : I2S2_LRCK -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 8 : I2S2_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 9 : I2S2_DOUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 10 : NAND_SYS_CLK -> AP_TO_NAND_SYS_CLK_R + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 11 : S3E_RESETN -> AP_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 12 : PCIE_PERST0_N -> PCIE_AP_TO_NAND_RESET_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 13 : PCIE_PERST1_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 14 : PCIE_PERST2_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 15 : PCIE_PERST3_N -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 16 : PCIE_CLKREQ0_N -> PCIE_NAND_BI_AP_CLKREQ_L + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 17 : PCIE_CLKREQ1_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 18 : PCIE_CLKREQ2_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 19 : PCIE_CLKREQ3_N -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 20 : GPIO[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : GPIO[1] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : GPIO[2] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 23 : GPIO[3] -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 24 : GPIO[4] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 25 : GPIO[5] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 26 : GPIO[6] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 27 : GPIO[7] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 28 : GPIO[8] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 29 : GPIO[9] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 30 : GPIO[10] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 31 : GPIO[11] -> + +/* Port 4 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 32 : CLK32K_OUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 33 : DWI_DO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 34 : DWI_CLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 35 : PMU_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 36 : PMU_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 37 : PMU_SCLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 38 : GPIO[12] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 39 : I2C1_SDA -> + +/* Port 5 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 40 : I2C1_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 41 : I2C3_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 42 : I2C3_SCL -> + CFG_DISABLED, // 43 : SENSOR2_RST -> + CFG_DISABLED, // 44 : SENSOR3_RST -> + CFG_DISABLED, // 45 : SENSOR4_RST -> + CFG_DISABLED, // 46 : SENSOR_INT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 47 : ISP_I2C3_SDA -> + +/* Port 6 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 48 : ISP_I2C3_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 49 : ISP_I2C2_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 50 : ISP_I2C2_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 51 : ISP_I2C1_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 52 : ISP_I2C1_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 53 : ISP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 54 : ISP_I2C0_SCL -> + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 64 : SENSOR0_ISTRB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 65 : SENSOR0_RST -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 66 : SENSOR0_CLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 67 : SENSOR0_XSHUTDOWN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 68 : SENSOR1_ISTRB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 69 : SENSOR1_RST -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 70 : SENSOR1_CLK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 71 : SENSOR1_XSHUTDOWN -> + +/* Port 9 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 72 : SENSOR2_CLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 73 : I2S1_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 74 : I2S1_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 75 : I2S1_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 76 : I2S1_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 77 : I2S1_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 78 : SPI2_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 79 : SPI2_MOSI -> + +/* Port 10 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 80 : SPI2_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 81 : SPI2_SSIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 82 : SPI3_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 83 : SPI3_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 84 : SPI3_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 85 : SPI3_SSIN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 86 : GPIO[31] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 87 : GPIO[32] -> + +/* Port 11 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 88 : GPIO[33] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 89 : GPIO[34] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 90 : GPIO[35] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 91 : GPIO[36] -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 12 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 96 : UART1_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 97 : UART1_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 98 : UART1_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 99 : UART1_CTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 100 : UART4_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 101 : UART4_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 102 : UART4_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 103 : UART4_CTSN -> + +/* Port 13 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 14 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 15 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 128 : SPI1_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 129 : SPI1_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 130 : SPI1_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 131 : SPI1_SSIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 132 : I2C2_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 133 : I2C2_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 134 : UART3_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 135 : UART3_RXD -> + +/* Port 17 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 136 : UART3_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 137 : UART3_CTSN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 138 : GPIO[29] -> BOARD_ID4 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 139 : GPIO[30] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 140 : GPIO[13] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 141 : GPIO[14] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 142 : GPIO[15] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 143 : DROOP -> + +/* Port 18 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 144 : SOCHOT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 145 : TMR32_PWM0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 146 : TMR32_PWM1 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 147 : TMR32_PWM2 -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 148 : UART2_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 149 : UART2_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 150 : UART2_RTSN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 151 : UART2_CTSN -> + +/* Port 19 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 152 : UART7_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 153 : UART7_RXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 154 : DP_WAKEUP -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 20 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 160 : GPIO[37] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 161 : GPIO[38] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 162 : GPIO[39] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 163 : GPIO[40] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 164 : GPIO[41] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 165 : GPIO[16] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 166 : GPIO[17] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 167 : GPIO[18] -> BOOT_CONFIG0 + +/* Port 21 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 168 : GPIO[19] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 169 : GPIO[20] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 170 : GPIO[21] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 171 : GPIO[22] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 172 : GPIO[23] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 173 : UART5_RTXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 174 : TST_CLKOUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 175 : EDP_HPD -> + +/* Port 22 */ + CFG_DISABLED, // 176 : DISP_TOUCH_BSYNC0 -> + CFG_DISABLED, // 177 : DISP_TOUCH_BSYNC1 -> + CFG_DISABLED, // 178 : DISP_TOUCH_EB -> + CFG_IN, // 179 : REQUEST_DFU1 -> PMU_TO_AP_BUF_BUTTON1 + CFG_IN, // 180 : REQUEST_DFU2 -> PMU_TO_AP_BUF_BUTTON2 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 181 : SWD_TMS2 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 182 : SWD_TMS3 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 183 : GPU_TRIGGER -> + +/* Port 23 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 184 : SPI0_SCLK -> BOARD_ID0 + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 185 : SPI0_MOSI -> BOARD_ID1 + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 186 : SPI0_MISO -> BOARD_ID2 + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 187 : SPI0_SSIN -> BOARD_ID3 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 24 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 192 : UART0_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 193 : UART0_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 194 : UART6_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 195 : UART6_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 196 : I2C0_SDA -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 197 : I2C0_SCL -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 198 : I2S3_MCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 199 : I2S3_BCLK -> + +/* Port 25 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 200 : I2S3_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 201 : I2S3_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 202 : I2S3_DIN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 203 : GPIO[24] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 204 : GPIO[25] -> BOOT_CONFIG1 + CFG_IN | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 205 : GPIO[26] -> FORCE_DFU + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 206 : GPIO[27] -> DFU_STATUS + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 207 : GPIO[28] -> BOOT_CONFIG2 +}; + +static const uint32_t pinconfig_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 0 : AOP_SPI_SCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 1 : AOP_SPI_MOSI -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 2 : AOP_SPI_MISO -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 3 : AOP_UART0_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 4 : AOP_UART0_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 5 : AOP_UART1_TXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 6 : AOP_UART1_RXD -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 7 : AOP_UART2_TXD -> + +/* Port 1 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 8 : AOP_UART2_RXD -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 9 : AOP_I2C0_SDA -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 10 : AOP_I2C0_SCL -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 11 : AOP_FUNC[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 12 : AOP_FUNC[1] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 13 : AOP_FUNC[2] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 14 : AOP_FUNC[3] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 15 : AOP_FUNC[4] -> + +/* Port 2 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 16 : AOP_FUNC[5] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 17 : AOP_FUNC[6] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 18 : AOP_FUNC[7] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 19 : AOP_FUNC[8] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 20 : AOP_FUNC[9] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : AOP_FUNC[10] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : AOP_FUNC[11] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 23 : AOP_FUNC[12] -> + +/* Port 3 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 24 : AOP_FUNC[13] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 25 : AOP_FUNC[14] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 26 : AOP_FUNC[15] -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 27 : AOP_SWD_TCK_OUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 28 : AOP_SWD_TMS0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 29 : AOP_SWD_TMS1 -> + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 32 : AOP_I2S_DOUT -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 33 : AOP_I2S_BCLK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 34 : AOP_I2S_LRCK -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 35 : AOP_I2S_DIN -> + CFG_DISABLED | DRIVE_S8 | SLOW_SLEW, // 36 : AOP_I2S_MCK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 37 : DOCK_CONNECT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 38 : DOCK_ATTENTION -> + CFG_DISABLED, // 39 : AOP_PDM_CLK0 -> + +/* Port 5 */ + CFG_DISABLED, // 40 : AOP_PDM_DATA0 -> + CFG_DISABLED, // 41 : AOP_PDM_DATA1 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 6 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 7 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 8 */ + CFG_DISABLED, // 64 : XI0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 65 : XO0 -> + CFG_DISABLED, // 66 : ANALOGMUX_OUT -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 67 : CFSB -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 68 : HOLD_RESET -> + CFG_DISABLED, // 69 : TESTMODE -> + CFG_DISABLED, // 70 : PACKAGED_N -> + CFG_DISABLED, // 71 : CFSB_AOP -> + +/* Port 9 */ + CFG_DISABLED, // 72 : COLD_RESETN -> + CFG_DISABLED, // 73 : JTAG_TRSTN -> + CFG_DISABLED, // 74 : JTAG_SEL -> + CFG_DISABLED, // 75 : JTAG_TMS -> + CFG_DISABLED, // 76 : JTAG_TDI -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 77 : JTAG_TDO -> + CFG_DISABLED, // 78 : JTAG_TCK -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 79 : AOP_DDR_REQ -> + +/* Port 10 */ + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 80 : AOP_DDR_RESETN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 81 : AWAKE_REQ -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 82 : AWAKE_RESETN -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 83 : WDOG -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 84 : RT_CLK32768 -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 0, { pinconfig_0, pinconfig_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/t8010sim/rules.mk b/target/t8010sim/rules.mk new file mode 100644 index 0000000..587667a --- /dev/null +++ b/target/t8010sim/rules.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2012-2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +# TBD - BUCK_* + +OPTIONS += \ + TARGET_BOOT_CPU_VOLTAGE=0 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + DCS_NUM_CHANNELS=4 \ + DCS_NUM_RANKS=1 \ + AMP_CALIBRATION_SKIP=1 \ + BUCK_CPU=0 \ + BUCK_CPU_RAM=7 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + BUCK_GPU_RAM=8 \ + WITH_CPU_APSC=1 \ + WIFI_DTPATH=\"arm-io/wlan\" + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o +ALL_OBJS += $(LOCAL_DIR)/pinconfig_$(SUB_TARGET).o diff --git a/target/typhonic/include/target/adbe_settings.h b/target/typhonic/include/target/adbe_settings.h new file mode 100644 index 0000000..b37b8d3 --- /dev/null +++ b/target/typhonic/include/target/adbe_settings.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v2_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0000, + .adbe0_vblank_busy_finish = 0x2, + .adbe0_tunable_mode_ctrl = (DBEMODECNTL_DPB_BUSY_MASK | \ + DBEMODECNTL_PMGR_CLK_GATE_ENABLE | \ + DBEMODECNTL_DYN_CLK_GATE_ENABLE | \ + DBEMODECNTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 1, + .adbe0_aap_format_control_reg1 = (AAP_FORMAT_CONTROL_REG1_AUTOPOS | AAP_FORMAT_CONTROL_REG1_RSVD(8) | AAP_FORMAT_CONTROL_REG1_VS_POL), + }, +}; + +#endif diff --git a/target/typhonic/include/target/amcconfig.h b/target/typhonic/include/target/amcconfig.h new file mode 100644 index 0000000..31c19be --- /dev/null +++ b/target/typhonic/include/target/amcconfig.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if SUB_PLATFORM_T7000 +#include +#elif SUB_PLATFORM_T7001 +#include +#endif diff --git a/target/typhonic/include/target/amcconfig_t7000.h b/target/typhonic/include/target/amcconfig_t7000.h new file mode 100644 index 0000000..a7366de --- /dev/null +++ b/target/typhonic/include/target/amcconfig_t7000.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amc/amc.h, and this + * file should only by included from amc.c. + */ + +static const struct amc_param amc_params = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050010, + .mcuchnhash = 0x0ffffd54, + .mcschnldec = 0x00010200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000601, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQCTL1, 0x00000158 }, + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, + { &rAMC_PWRMNGTPARAM, 0x01803000 }, +}; diff --git a/target/typhonic/include/target/amcconfig_t7001.h b/target/typhonic/include/target/amcconfig_t7001.h new file mode 100644 index 0000000..c31f710 --- /dev/null +++ b/target/typhonic/include/target/amcconfig_t7001.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_param struct is defined in drivers/apple/amc/amc.h, and this + * file should only by included from amc.c. + */ + +static const struct amc_param amc_params = { + .lat = 0x00060300, + .phyrdwrtim = 0x00020a04, + .tREFi = 0x5d, + .pdn = 0x22000403, + .derate = 0x24831359, + .read = 0x00000203, + .bustat = 0x00222209, + .bustat2 = 0x00222209, + .pwrmngten_default = 0x00100100, + .schen_default = 0x00001110, + .mcphyupdate = 0x15030000, + .mcphyupdate1 = 0x00000003, + .arefparam = 0x0ca2b532, + .longsr = 0x05022008, + .mr1 = 0x44, + .mr2 = 0x1a, + .mr3 = 0x03, + .addrcfg = 0x00020201, + .mccchnldec = 0x00050020, + .mcuchnhash = 0x0ffffd54, + .mcuchnhash2 = 0x0aaaaaa8, + .mcschnldec = 0x00020200, + .qbrparam = 0x00050200, + .odts = 0x00000320, + .addrmapmode = 0x00000501, + + .freq = { + { // 800MHz + .cas = 0x00000308, + .pch = 0x00030612, + .act = 0x12040908, + .autoref = 0x19350000, + .selfref = 0x00039060, + .modereg = 0x20250782, + }, + { // 400MHz + .cas = 0x00000005, + .pch = 0x00000009, + .act = 0x09020505, + .autoref = 0x0d1b0000, + .selfref = 0x0001d000, + .modereg = 0x00130000, + }, + { // 200MHz + .cas = 0x00000003, + .pch = 0x00000005, + .act = 0x05010303, + .autoref = 0x070e0000, + .selfref = 0x0000f000, + .modereg = 0x000a0000, + }, + { // 50MHz + .cas = 0x00000002, + .pch = 0x00000002, + .act = 0x04010202, + .autoref = 0x02040000, + .selfref = 0x00004000, + .modereg = 0x00030000, + } + } +}; + +static const struct amc_tunable amc_tunables[] = { + { &rAMC_MCSARBCFG, 0x00000001 }, + { &rAMC_OPIDLETMR, 0x00200000 }, + { &rAMC_OPTMRADJPARAM, 0x20400064 }, + { &rAMC_MIFACTSCH, 0x00000001 }, + { &rAMC_MIFCASSCH_FREQ(0), 0x10000010 }, + { &rAMC_PSQRQCTL0, 0xff010110 }, + { &rAMC_PSQRQCTL1, 0x00001700 }, + { &rAMC_PSQRQTIMER0, 0x00000040 }, + { &rAMC_PSQRQTIMER1, 0x00000014 }, + { &rAMC_PSQRQTIMER2, 0x00000040 }, + { &rAMC_PSQRQBRST, 0x04100410 }, + { &rAMC_PSQRQSCHCRD, 0x00101400 }, + { &rAMC_PSQWQCTL0, 0x00010100 }, + { &rAMC_PSQWQCTL1, 0x00000336 }, + { &rAMC_PSQWQBRST, 0x04080410 }, + { &rAMC_PSQWQSCHCRD, 0x00101400 }, + { &rAMC_MCUQOSLLT, 0x0000011f }, + { &rAMC_PWRMNGTPARAM, 0x03523000 }, +}; diff --git a/target/typhonic/include/target/ampconfig.h b/target/typhonic/include/target/ampconfig.h new file mode 100644 index 0000000..024f5e8 --- /dev/null +++ b/target/typhonic/include/target/ampconfig.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* + * The amc_phy_params struct is defined in drivers/apple/amp_v3/amp_v3.h, and this + * file should only by included from amp_v3.c. + */ + +static const struct amp_params amc_phy_params = { + .freq = { + { + .caoutdllscl = 0x00000008, + .dqsindllscl = 0x00000008, +#if SUB_PLATFORM_T7000 + .rdcapcfg = 0x0101050f, +#elif SUB_PLATFORM_T7001 + .rdcapcfg = 0x0101050e, +#endif + }, + { + .caoutdllscl = 0x00000010, + .dqsindllscl = 0x00000010, + .rdcapcfg = 0x21010509, + }, + { + .caoutdllscl = 0x00000020, + .dqsindllscl = 0x00000020, + .rdcapcfg = 0x41010506, + }, + { + .caoutdllscl = 0x0000003f, + .dqsindllscl = 0x0000003f, + .rdcapcfg = 0x61010504, + }, + }, + .dqdqsds = 0x00001212, + .nondqds = 0x12124a52, +#if SUB_PLATFORM_T7000 + .ampclk = 0x00010000, +#endif +}; diff --git a/target/typhonic/include/target/aspnandconfig.h b/target/typhonic/include/target/aspnandconfig.h new file mode 100644 index 0000000..18774a9 --- /dev/null +++ b/target/typhonic/include/target/aspnandconfig.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 4 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 4 +#define ASPNAND_READ_DIES_IN_PARALLEL 4 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 8 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 2 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 2 + +// rdar://problem/18371949 - these values should be the same for post-OkemoTaos targets +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/typhonic/include/target/gpiodef.h b/target/typhonic/include/target/gpiodef.h new file mode 100644 index 0000000..5a345b7 --- /dev/null +++ b/target/typhonic/include/target/gpiodef.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* Typhonic specific gpio -> pin mappings */ + +#include + +/* define target-specific gpios in a generic fashion here. */ + +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/typhonic/include/target/nand_spec_tables.h b/target/typhonic/include/target/nand_spec_tables.h new file mode 100644 index 0000000..029be11 --- /dev/null +++ b/target/typhonic/include/target/nand_spec_tables.h @@ -0,0 +1,153 @@ + +// Copyright (C) 2008-2010 Apple, Inc. All rights reserved. +// +// This document is the property of Apple, Inc. +// It is considered confidential and proprietary. +// +// This document may not be reproduced or transmitted in any form, +// in whole or in part, without the express written permission of +// Apple, Inc. +// +// NOTE: This is a generated file and should not be hand-edited! +// + +// ============================================================================= +// Nand Geometry Table + +static NandGeometry _nandGeometryTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* blocksPerCS */ 4100, + /* pagesPerBlock */ 128, + /* dataBytesPerPage */ 8192, + /* spareBytesPerPage */ 448, + /* eccPer512Bytes */ 16, + /* initialBBType */ INIT_BBT_TOSHIBA_MLC, + /* diesPerCS */ 1 + } +}; + +// ============================================================================= +// Nand Timing Table + +static NandTiming _nandTimingTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* writeCycleNanosecs */ 25, + /* writeSetupNanosecs */ 12, + /* writeHoldNanosecs */ 10, + /* readCycleNanosecs */ 25, + /* readSetupNanosecs */ 12, + /* readHoldNanosecs */ 10, + /* readDelayNanosecs */ 20, + /* readValidNanosecs */ 25 + } +}; + +#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) +// ============================================================================= +// NandChipId Description +const NandChipIdDescription _nandChipIdDescriptionTable[] = +{ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* die */ "32nm", + /* vendor_name */ "Toshiba" + } +}; + +// ============================================================================= +// Nand Description Table + +static const NandDescription _nandDescriptionTable[] = +{ + { + /* packageId */ + { + /* chipId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + }, + /* appleName */ "335S0700", + /* vendor_part_num */ "TH58NVG6D2FLA49", + /* package_type */ "DDP", + /* package_size */ "1.00mm LGA" + } +}; +const UInt32 _nandDescriptionTableSize = sizeof(_nandDescriptionTable) / sizeof(NandDescription); + +#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT) + +// ============================================================================= +// Nand Board Support Table + +static NandBoardSupport _nandBoardSupportTable[] = +{ + { + /* configId */ + { + /* connectedBusCnt */ 2, + /* packageCnt */ 1, + /* packageIds[] */ + { + { + /* deviceId */ { 0x98, 0xE7, 0x94, 0x32 }, + /* ceCnt */ 2 + } + } + }, + /* vsType */ FIL_VS_TOSHIBA_2P_EXT + } +}; + +// ============================================================================= +// Nand Board Timing Table + +static NandBoardInfo _nandBoardInfo = +{ + /* controlDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* dataDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + /* chipEnableDstr */ NAND_DRIVE_STRENGTH_DEFAULT, + + /* socToNandRiseNanosecs */ 10, + /* socToNandFallNanosecs */ 10, + /* nandToSocRiseNanosecs */ 10, + /* nandToSocFallNanosecs */ 10, + + /* landing map */ + { + 0x00000303 + }, + + /* useToggleMode */ 0, + /* useDiffDQSMode */ 0, + /* useDiffREMode */ 0, + /* useVref */ 0 +}; + +static NandFormat _nandFormatPpn = +{ + /* metaPerLogicalPage */ 16, + /* validMetaPerLogicalPage */ 16, + /* logicalPageSize */ 0 +}; + +static NandFormat _nandFormatRaw = +{ + /* metaPerLogicalPage */ 12, + /* validMetaPerLogicalPage */ 10, + /* logicalPageSize */ 0 +}; + diff --git a/target/typhonic/include/target/pinconfig.h b/target/typhonic/include/target/pinconfig.h new file mode 100644 index 0000000..e4aaf98 --- /dev/null +++ b/target/typhonic/include/target/pinconfig.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#if SUB_PLATFORM_T7000 +#include +#elif SUB_PLATFORM_T7001 +#include +#endif diff --git a/target/typhonic/include/target/powerconfig.h b/target/typhonic/include/target/powerconfig.h new file mode 100644 index 0000000..e258978 --- /dev/null +++ b/target/typhonic/include/target/powerconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +// Minimal definitions to make lib/power.c happy +#define TARGET_POWER_NO_BATTERY 1 +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (5000) + +// This fake SoC block takes the place of the external PMU in Fastsim +#define SWIFTER_PMU_BASE 0x20F050000 + +#endif diff --git a/target/typhonic/include/target/uartconfig.h b/target/typhonic/include/target/uartconfig.h new file mode 100644 index 0000000..8dbadc2 --- /dev/null +++ b/target/typhonic/include/target/uartconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define two debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#endif diff --git a/target/typhonic/init.c b/target/typhonic/init.c new file mode 100644 index 0000000..4944e88 --- /dev/null +++ b/target/typhonic/init.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +} + +void target_late_init(void) +{ +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ + return 0; +} + +bool target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool target_should_poweroff(bool at_boot) +{ + return 0; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +void * target_get_display_configuration(void) +{ + return NULL; +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ + env_set("boot-args", "debug=0x14e serial=3 amfi=0x83 cs_enforcement_disable=1 fips_mode=0 -disable_aslr", ENV_PERSISTENT); + // boot-device is set in platform's init.c + env_set("display-color-space","RGB888", 0); +#if SUB_TARGET_T7001PADSIM + env_set("display-timing", "ipad4", 0); +#else + env_set("display-timing", "D403", 0); + env_set("adfe-tunables", "D403", 0); +#endif + env_set("idle-off", "false", 0); + env_set("kaslr-slide", "0x10000000", 0); + env_set("wifiaddr", "12:22:33:44:55:66", 0); + env_set("ethaddr", "12:22:33:44:55:77", 0); + env_set("btaddr", "00:00:00:00:00:00", 0); +} + +#endif + +#if WITH_DEVICETREE + +#define ROOT_DTPATH "" +int target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Overwrite the serial-number with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "serial-number property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *serial = (uint64_t *)propData; + serial[0] = *(volatile uint64_t *)0x20f050040; + serial[1] = *(volatile uint64_t *)0x20f050048; + serial[2] = *(volatile uint64_t *)0x20f050050; + serial[3] = *(volatile uint64_t *)0x20f050058; + } + } + + // Overwrite the region-info with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "region-info"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "region-info property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *region = (uint64_t *)propData; + region[0] = *(volatile uint64_t *)0x20f050060; + region[1] = *(volatile uint64_t *)0x20f050068; + region[2] = *(volatile uint64_t *)0x20f050070; + region[3] = *(volatile uint64_t *)0x20f050078; + } + } + + return 0; +} + +#endif + + +#if !WITH_HW_POWER + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +u_int32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(u_int8_t key, u_int8_t *data) +{ + return -1; +} + +int power_set_nvram(u_int8_t key, u_int8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(u_int32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/typhonic/pinconfig_t7001padsim.c b/target/typhonic/pinconfig_t7001padsim.c new file mode 100644 index 0000000..5042e99 --- /dev/null +++ b/target/typhonic/pinconfig_t7001padsim.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* Default t7001padsim Pin Configuration - Capri I/O Spreadsheet v10.29 */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN, // MENU_KEY_L -> REQUEST_DFU2 + CFG_IN, // HOLD_KEY_L -> REQUEST_DFU1 + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + +/* Port 1 */ + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // UART5_RTXD -> + CFG_DISABLED, // DWI0_DO -> + CFG_DISABLED, // DWI0_CLK -> + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // I2S0_LRCK -> + +/* Port 5 */ + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + CFG_DISABLED, // I2S1_DIN -> + +/* Port 6 */ + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // DISP_VSYNC -> + +/* Port 7 */ + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + CFG_DISABLED, // CPU_SLEEP_STATUS -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // ISP_UART0_TXD -> + CFG_DISABLED, // ISP_UART0_RXD -> + CFG_DISABLED, // UART7_TXD -> + +/* Port 8 */ + CFG_DISABLED, // UART7_RXD -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_FUNC0, // SPI0_SCLK -> BOARD_ID0 + CFG_FUNC0, // SPI0_MOSI -> BOARD_ID1 + CFG_FUNC0, // SPI0_MISO -> BOARD_ID2 + CFG_OUT_1, // SPI0_SSIN -> + CFG_DISABLED, // I2S3_MCK -> + +/* Port 9 */ + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + +/* Port 10 */ + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> + CFG_DISABLED, // GPIO3 -> + CFG_DISABLED, // GPIO4 -> + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + +/* Port 11 */ + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO11 -> + CFG_DISABLED, // GPIO12 -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO15 -> + +/* Port 12 */ + CFG_DISABLED, // GPIO16 -> BOARD_ID3 + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG0 + CFG_DISABLED, // GPIO19 -> + CFG_DISABLED, // GPIO20 -> + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + +/* Port 13 */ + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG1 + CFG_IN, // GPIO26 -> FORCE_DFU + CFG_DISABLED, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG2 + CFG_DISABLED, // GPIO29 -> BOARD_ID4 + CFG_DISABLED, // GPIO30 -> + CFG_DISABLED, // GPIO31 -> BOOT_CONFIG3 + +/* Port 14 */ + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO34 -> + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 15 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // UART8_TXD -> + CFG_DISABLED, // UART8_RXD -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 16 */ + CFG_FUNC0, // UART0_TXD -> + CFG_FUNC0, // UART0_RXD -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + +/* Port 17 */ + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + CFG_DISABLED, // UART1_CTSN -> + +/* Port 18 */ + CFG_DISABLED, // EDP_HPD -> + CFG_DISABLED, // I2S4_MCK -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + +/* Port 19 */ + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + CFG_DISABLED, // CLK32K_OUT -> + CFG_DISABLED, // ULPI_DIR -> + +/* Port 20 */ + CFG_DISABLED, // ULPI_STP -> + CFG_DISABLED, // ULPI_NXT -> + CFG_DISABLED, // ULPI_DATA7 -> + CFG_DISABLED, // ULPI_DATA6 -> + CFG_DISABLED, // ULPI_DATA5 -> + CFG_DISABLED, // ULPI_DATA4 -> + CFG_DISABLED, // ULPI_CLK -> + CFG_DISABLED, // ULPI_DATA3 -> + +/* Port 21 */ + CFG_DISABLED, // ULPI_DATA2 -> + CFG_DISABLED, // ULPI_DATA1 -> + CFG_DISABLED, // ULPI_DATA0 -> + CFG_DISABLED, // DWI1_DO -> + CFG_DISABLED, // DWI1_CLK -> + CFG_DISABLED, // PCIE_CLKREQ0_N -> + CFG_DISABLED, // PCIE_CLKREQ1_N -> + CFG_DISABLED, // PCIE_CLKREQ2_N -> + +/* Port 22 */ + CFG_DISABLED, // PCIE_CLKREQ3_N -> + CFG_DISABLED, // NAND_SYS_CLK -> + CFG_DISABLED, // PCIE_PERST0_N -> + CFG_DISABLED, // PCIE_PERST1_N -> + CFG_DISABLED, // PCIE_PERST2_N -> + CFG_DISABLED, // PCIE_PERST3_N -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/typhonic/pinconfig_typhonic.c b/target/typhonic/pinconfig_typhonic.c new file mode 100644 index 0000000..3ff3e89 --- /dev/null +++ b/target/typhonic/pinconfig_typhonic.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2012-2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +/* Pin configuration for Typhonic - Fiji I/O Spreadsheet v9.3 */ + +static const uint32_t gpio_default_cfg[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // ULPI_DIR -> + CFG_DISABLED, // ULPI_STP -> + CFG_DISABLED, // ULPI_NXT -> + CFG_DISABLED, // ULPI_DATA7 -> + CFG_DISABLED, // ULPI_DATA6 -> + CFG_DISABLED, // ULPI_DATA5 -> + CFG_DISABLED, // ULPI_DATA4 -> + CFG_DISABLED, // ULPI_CLK -> + +/* Port 1 */ + CFG_DISABLED, // ULPI_DATA3 -> + CFG_DISABLED, // ULPI_DATA2 -> + CFG_DISABLED, // ULPI_DATA1 -> + CFG_DISABLED, // ULPI_DATA0 -> + CFG_DISABLED, // SPI1_SCLK -> + CFG_DISABLED, // SPI1_MOSI -> + CFG_DISABLED, // SPI1_MISO -> + CFG_DISABLED, // SPI1_SSIN -> + +/* Port 2 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 3 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 4 */ + CFG_DISABLED, // GPIO11 -> + CFG_IN, // GPIO12 -> HOLD_KEY (REQUEST_DFU1) + CFG_DISABLED, // I2S3_MCK -> + CFG_DISABLED, // I2S3_LRCK -> + CFG_DISABLED, // I2S3_BCLK -> + CFG_DISABLED, // I2S3_DOUT -> + CFG_DISABLED, // I2S3_DIN -> + CFG_DISABLED, // CLK32K_OUT -> + +/* Port 5 */ + CFG_DISABLED, // PCIE_CLKREQ0_N -> + CFG_DISABLED, // PCIE_CLKREQ1_N -> + CFG_DISABLED, // NAND_SYS_CLK -> + CFG_DISABLED, // GPIO0 -> + CFG_DISABLED, // GPIO1 -> + CFG_DISABLED, // GPIO2 -> + CFG_IN, // GPIO3 -> MENU_KEY (REQUEST_DFU2) + CFG_DISABLED, // GPIO4 -> + +/* Port 6 */ + CFG_DISABLED, // GPIO5 -> + CFG_DISABLED, // GPIO6 -> + CFG_DISABLED, // GPIO7 -> + CFG_DISABLED, // GPIO14 -> + CFG_DISABLED, // GPIO16 -> BOARD_ID[3] + CFG_DISABLED, // GPIO17 -> + CFG_DISABLED, // GPIO18 -> BOOT_CONFIG[0] + CFG_DISABLED, // GPIO20 -> + +/* Port 7 */ + CFG_DISABLED, // GPIO21 -> + CFG_DISABLED, // UART5_RTXD -> + CFG_DISABLED, // UART8_TXD -> + CFG_DISABLED, // UART8_RXD -> + CFG_FUNC0, // SPI0_SCLK -> SPI0_SCLK/BOARD_ID[0] + CFG_FUNC0, // SPI0_MOSI -> SPI0_MOSI/BOARD_ID[1] + CFG_FUNC0, // SPI0_MISO -> SPI0_MISO/BOARD_ID[2] + CFG_OUT_1, // SPI0_SSIN -> + +/* Port 8 */ + CFG_DISABLED, // I2C2_SDA -> + CFG_DISABLED, // I2C2_SCL -> + CFG_DISABLED, // GPIO22 -> + CFG_DISABLED, // GPIO23 -> + CFG_DISABLED, // GPIO25 -> BOOT_CONFIG[1] + CFG_DISABLED, // GPIO28 -> BOOT_CONFIG[2] + CFG_DISABLED, // GPIO29 -> BOARD_ID[4] + CFG_DISABLED, // GPIO34 -> + +/* Port 9 */ + CFG_DISABLED, // GPIO35 -> + CFG_DISABLED, // GPIO36 -> + CFG_DISABLED, // GPIO37 -> + CFG_DISABLED, // GPIO39 -> + CFG_DISABLED, // GPIO42 -> + CFG_DISABLED, // GPIO43 -> + CFG_DISABLED, // DISP_VSYNC -> + CFG_FUNC0, // UART0_TXD -> + +/* Port 10 */ + CFG_FUNC0, // UART0_RXD -> + CFG_DISABLED, // TMR32_PWM0 -> + CFG_DISABLED, // TMR32_PWM1 -> + CFG_DISABLED, // TMR32_PWM2 -> + CFG_DISABLED, // UART6_TXD -> + CFG_DISABLED, // UART6_RXD -> + CFG_DISABLED, // I2C3_SDA -> + CFG_DISABLED, // I2C3_SCL -> + +/* Port 11 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 12 */ + CFG_DISABLED, // I2C0_SDA -> + CFG_DISABLED, // I2C0_SCL -> + CFG_DISABLED, // GPIO38 -> + CFG_DISABLED, // UART2_TXD -> + CFG_DISABLED, // UART2_RXD -> + CFG_DISABLED, // UART2_RTSN -> + CFG_DISABLED, // UART2_CTSN -> + CFG_DISABLED, // DWI_DO -> + +/* Port 13 */ + CFG_DISABLED, // DWI_CLK -> + CFG_FUNC0, // WDOG -> + CFG_DISABLED, // GPIO13 -> + CFG_DISABLED, // GPIO19 -> + CFG_IN, // GPIO26 -> FORCE_DFU + CFG_DISABLED, // GPIO27 -> DFU_STATUS + CFG_DISABLED, // SOCHOT0 -> + CFG_DISABLED, // SOCHOT1 -> + +/* Port 14 */ + CFG_DISABLED, // CPU_SLEEP_STATUS -> + CFG_DISABLED, // TST_CLKOUT -> + CFG_DISABLED, // GPIO8 -> + CFG_DISABLED, // GPIO9 -> + CFG_DISABLED, // GPIO10 -> + CFG_DISABLED, // GPIO15 -> + CFG_DISABLED, // UART4_TXD -> + CFG_DISABLED, // UART4_RXD -> + +/* Port 15 */ + CFG_DISABLED, // UART4_RTSN -> + CFG_DISABLED, // UART4_CTSN -> + CFG_DISABLED, // SPI3_MOSI -> + CFG_DISABLED, // SPI3_MISO -> + CFG_DISABLED, // SPI3_SCLK -> + CFG_DISABLED, // SPI3_SSIN -> + CFG_DISABLED, // GPIO24 -> + CFG_DISABLED, // GPIO30 -> + +/* Port 16 */ + CFG_DISABLED, // GPIO31 -> + CFG_DISABLED, // GPIO32 -> + CFG_DISABLED, // GPIO33 -> + CFG_DISABLED, // GPIO40 -> + CFG_DISABLED, // GPIO41 -> + CFG_DISABLED, // I2S4_MCK -> + CFG_DISABLED, // I2S4_LRCK -> + CFG_DISABLED, // I2S4_BCLK -> + +/* Port 17 */ + CFG_DISABLED, // I2S4_DOUT -> + CFG_DISABLED, // I2S4_DIN -> + CFG_DISABLED, // I2C1_SDA -> + CFG_DISABLED, // I2C1_SCL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 18 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 19 */ + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + +/* Port 20 */ + CFG_DISABLED, // I2S0_LRCK -> + CFG_DISABLED, // I2S0_BCLK -> + CFG_DISABLED, // I2S0_DOUT -> + CFG_DISABLED, // I2S0_DIN -> + CFG_DISABLED, // I2S1_MCK -> + CFG_DISABLED, // I2S1_LRCK -> + CFG_DISABLED, // I2S1_BCLK -> + CFG_DISABLED, // I2S1_DOUT -> + +/* Port 21 */ + CFG_DISABLED, // I2S1_DIN -> + CFG_DISABLED, // I2S2_LRCK -> + CFG_DISABLED, // I2S2_BCLK -> + CFG_DISABLED, // I2S2_DOUT -> + CFG_DISABLED, // I2S2_DIN -> + CFG_DISABLED, // UART1_TXD -> + CFG_DISABLED, // UART1_RXD -> + CFG_DISABLED, // UART1_RTSN -> + +/* Port 22 */ + CFG_DISABLED, // UART1_CTSN -> + CFG_DISABLED, // EDP_HPD -> + CFG_DISABLED, // UART3_TXD -> + CFG_DISABLED, // UART3_RXD -> + CFG_DISABLED, // UART3_RTSN -> + CFG_DISABLED, // UART3_CTSN -> + CFG_DISABLED, // SPI2_SCLK -> + CFG_DISABLED, // SPI2_MOSI -> + +/* Port 23 */ + CFG_DISABLED, // SPI2_MISO -> + CFG_DISABLED, // SPI2_SSIN -> + CFG_DISABLED, // ISP0_SDA -> + CFG_DISABLED, // ISP0_SCL -> + CFG_DISABLED, // ISP1_SDA -> + CFG_DISABLED, // ISP1_SCL -> + CFG_DISABLED, // SENSOR0_RST -> + CFG_DISABLED, // SENSOR0_CLK -> + +/* Port 24 */ + CFG_DISABLED, // SENSOR0_XSHUTDOWN -> + CFG_DISABLED, // SENSOR0_ISTRB -> + CFG_DISABLED, // ISP_UART0_TXD -> + CFG_DISABLED, // ISP_UART0_RXD -> + CFG_DISABLED, // SENSOR1_RST -> + CFG_DISABLED, // SENSOR1_CLK -> + CFG_DISABLED, // SENSOR1_XSHUTDOWN -> + CFG_DISABLED, // SENSOR1_ISTRB -> + +/* Port 25 */ + CFG_DISABLED, // UART7_TXD -> + CFG_DISABLED, // UART7_RXD -> + CFG_DISABLED, // I2S0_MCK -> + CFG_DISABLED, // I2S2_MCK -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> + CFG_DISABLED, // NULL -> +}; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + return gpio_default_cfg; +} diff --git a/target/typhonic/rules.mk b/target/typhonic/rules.mk new file mode 100644 index 0000000..433f318 --- /dev/null +++ b/target/typhonic/rules.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2012-2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +# BUCK_CPU, BUCK_GPU and BUCK_RAM should be reviewed +# if any changed happen in drivers/dialog/pmu/power.c:power_get_buck_value() + +OPTIONS += \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_V2 \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=CHIPID_SOC_VOLTAGE_VMIN \ + TARGET_VID0_CLK_CFG=0x85100000 \ + AMC_NUM_RANKS=1 \ + AMP_CALIBRATION_SKIP=1 \ + BUCK_CPU=0 \ + BUCK_SOC=2 \ + BUCK_GPU=1 \ + WITH_TARGET_AMC_PARAMS=1 \ + WITH_TARGET_AMP_PARAMS=1 \ + WIFI_DTPATH=\"arm-io/wlan\" + +ifeq ($(SUB_PLATFORM),t7000) +OPTIONS += AMC_NUM_CHANNELS=2 +OPTIONS += DISPLAY_IPHONE_TUNABLES=1 +OPTIONS += DISPLAY_D403_TUNABLES=1 +else +OPTIONS += AMC_NUM_CHANNELS=4 +OPTIONS += BUCK_RAM=1 +OPTIONS += DISPLAY_LANDSCAPE_IPAD_TUNABLES=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/pinconfig_$(SUB_TARGET).o diff --git a/target/watch2/include/target/adbe_settings.h b/target/watch2/include/target/adbe_settings.h new file mode 100644 index 0000000..3645830 --- /dev/null +++ b/target/watch2/include/target/adbe_settings.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ADBE_SETTINGS_H +#define __TARGET_ADBE_SETTINGS_H + +static struct adbe_v3_tuneable adbe_tuneables[] = { + { + .name = "default", + .adbe0_vblank_clk_gate_wakeup = 0x0000, + .adbe0_vblank_clk_gate_idle = 0x0001, + .adbe0_tunable_nrt_ctl = (ADBE_NRT_CTL_ADISP_CLK_GATE_ENABLE | ADBE_NRT_CTL_ADBE_CLK_GATE_ENABLE | ADBE_NRT_CTL_BLK_CLK_GATE_ENABLE), + .adbe0_aap_support = 0, + }, +}; + +#endif diff --git a/target/watch2/include/target/aspnandconfig.h b/target/watch2/include/target/aspnandconfig.h new file mode 100644 index 0000000..6015b86 --- /dev/null +++ b/target/watch2/include/target/aspnandconfig.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_ASPNANDCONFIG_H +#define __TARGET_ASPNANDCONFIG_H + +//MLC devices +#define ASPNAND_MLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_SLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_ERASE_DIES_IN_PARALLEL 1 +#define ASPNAND_READ_DIES_IN_PARALLEL 1 +#define ASPNAND_MLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_ERASE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_READ_LOW_POWER_DIES_IN_PARALLEL 1 + +//TLC devices +#define ASPNAND_TLC_TLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_SLC_WRITE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_ERASE_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_READ_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_TLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_SLC_WRITE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_ERASE_LOW_POWER_DIES_IN_PARALLEL 1 +#define ASPNAND_TLC_READ_LOW_POWER_DIES_IN_PARALLEL 1 + +#define ASPNAND_INDIRECTION_MEMORY (2*1024*1024) +#define ASPNAND_LEGACY_INDIRECTION_MEMORY (2*1024*1024) + +#endif diff --git a/target/watch2/include/target/dcsfixup.h b/target/watch2/include/target/dcsfixup.h new file mode 100644 index 0000000..d57b6c7 --- /dev/null +++ b/target/watch2/include/target/dcsfixup.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +static inline +void dcs_init_config_fixup_params(dcs_config_params_t *dcs_params, dcs_target_t targtype) +{ + dcs_params->freq[0].freqchngctl[2] = 0xb203000b; + dcs_params->freq[1].freqchngctl[2] = 0xd303000b; + dcs_params->freq[3].freqchngctl[2] = 0xf203000b; + dcs_params->freq[0].lat = 0x001030c2; + dcs_params->freq[1].lat = 0x001020c2; + dcs_params->freq[0].phyrdwrtim = 0x00010c01; + dcs_params->freq[1].phyrdwrtim = 0x00010b01; + dcs_params->freq[0].caspch = 0x40c20402; + dcs_params->freq[0].act = 0x01020202; + dcs_params->freq[0].autoref = 0x01010078; + dcs_params->freq[0].selfref = 0x28001012; + dcs_params->modereg = 0x060c5024; + dcs_params->freq[1].caspch = 0x40c20402; + dcs_params->freq[1].act = 0x01020202; + dcs_params->freq[1].autoref = 0x01010050; + dcs_params->freq[1].selfref = 0x28001012; + dcs_params->freq[2].caspch = 0x40c20402; + dcs_params->freq[2].act = 0x01020202; + dcs_params->freq[2].autoref = 0x01010014; + dcs_params->freq[2].selfref = 0x28001012; + dcs_params->freq[3].autoref = 0x01010005; + dcs_params->freq[3].selfref = 0x28001012; + dcs_params->autoref_params = 0x00150013; + dcs_params->pdn = 0x32272222; + dcs_params->freq[0].derate = 0x08212082; + dcs_params->freq[1].derate = 0x08212082; + dcs_params->freq[2].derate = 0x08212082; + dcs_params->freq[0].lat2 = 0x001110c2; + dcs_params->freq[1].lat2 = 0x00111206; + dcs_params->freq[0].tat = 0x01212222; + dcs_params->freq[1].tat = 0x01212222; + dcs_params->freq[3].mifqmaxctrl = 0x00000003; + dcs_params->freq[0].odt_enable = 0x00000000; + dcs_params->freq[1].odt_enable = 0x00000000; + dcs_params->freq[0].rdcapcfg = 0x01000606; + dcs_params->freq[1].rdcapcfg = 0x21000606; + dcs_params->freq[2].rdcapcfg = 0x41000606; + dcs_params->freq[3].rdcapcfg = 0x61000606; + dcs_params->b0odtctrl = 0x00000000; + dcs_params->b1odtctrl = 0x00000000; + dcs_params->dqs0odtctrl = 0x00000000; + dcs_params->dqs1odtctrl = 0x00000000; + dcs_params->freq[0].autoref2 = 0x01010001; + dcs_params->freq[1].autoref2 = 0x01010001; + dcs_params->freq[2].autoref2 = 0x01010001; + dcs_params->freq[3].autoref2 = 0x01010001; + dcs_params->autoref_params2 = 0x00200013; + dcs_params->mr13cmd_step15 = 0x50, + dcs_params->odtszqc = 0x00002000; + dcs_params->odtszqc2 = 0xc0002000; + dcs_params->odtszqc3 = 0xc0002320; +}; diff --git a/target/watch2/include/target/gpiodef.h b/target/watch2/include/target/gpiodef.h new file mode 100644 index 0000000..223b74c --- /dev/null +++ b/target/watch2/include/target/gpiodef.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_GPIODEF_H +#define __TARGET_GPIODEF_H + +/* iPod6,x specific gpio -> pin mappings */ + +#include + + /* BOARD_REV mapping */ +#define BOARD_REV_PROTON 0x0f +#define BOARD_REV_DEV3 0x0f +#define BOARD_REV_DEV4 0x0e +#define BOARD_REV_PROTO2A 0x0e +#define BOARD_REV_PROTO2B 0x0d +#define BOARD_REV_PROTO2X_CARDINAL 0x0c +#define BOARD_REV_PROTO2B_ALT_CARBON 0x0b +#define BOARD_REV_PROTO2D 0x0a +#define BOARD_REV_PROTO2F 0x09 +#define BOARD_REV_EVT 0x08 +#define BOARD_REV_EVT_ALT_CARBON 0x07 + +extern uint32_t ipod6_get_board_rev(); + +/* define target-specific gpios in a generic fashion here. */ +#define GPIO_ALT_BOOST_ID GPIOC(GPIO_AP, 5, 3) // GPIO11 + +/* which IICs to initialize */ +#define IICS_MASK (3) + +#define TRISTAR_IIC_BUS (0) + +#define DISPLAY_PMU_IIC_BUS (1) + +/* Miscellaneous Pins */ +#define GPIO_PMU_LCD_RST (11) +#define PMU_LCD_PWR_VCI (5) +#define PMU_LCD_PWR_DVDD (0xe) +#define PMU_LDO_OPAL (0x8) + +/* + * support of video or command mode + */ +extern bool product_target_is_display_in_video_mode(); +extern uint32_t product_target_get_ulps_in_delay(void); +extern uint32_t product_target_get_ulps_end_delay(void); +extern uint32_t product_target_get_ulps_out_delay(void); +extern bool product_target_no_burst_mode(); + +#define TARGET_DISP_VIDEO_MODE product_target_is_display_in_video_mode() +#define TARGET_DSI_ULPS_IN_DELAY product_target_get_ulps_in_delay() +#define TARGET_DSI_ULPS_END_DELAY product_target_get_ulps_end_delay() +#define TARGET_DSI_ULPS_OUT_DELAY product_target_get_ulps_out_delay() +#define TARGET_NO_BURST_MODE product_target_no_burst_mode() +#endif /* ! __TARGET_GPIODEF_H */ diff --git a/target/watch2/include/target/pinconfig.h b/target/watch2/include/target/pinconfig.h new file mode 100644 index 0000000..0136af5 --- /dev/null +++ b/target/watch2/include/target/pinconfig.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#if CONFIG_FPGA +#include +#elif CONFIG_SIM +#include +#else +#include +#endif diff --git a/target/watch2/include/target/pinconfig_product.h b/target/watch2/include/target/pinconfig_product.h new file mode 100644 index 0000000..166e306 --- /dev/null +++ b/target/watch2/include/target/pinconfig_product.h @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS STRUCT IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.2.5 + I/O Spreadsheet tracker: M7 GPIO Spreadsheet +*/ + + +/* Different drive strength for AP and DEV. */ +#if PIN_CFG_AP +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##ap +#elif PIN_CFG_DEV +#define AP_DEV_DRIVE_STR(ap, dev) DRIVE_##dev +#endif + +/* Different slew rate for AP and DEV. */ +#if PIN_CFG_AP +#define AP_DEV_SLEW_RATE(ap, dev) ap##_SLEW +#elif PIN_CFG_DEV +#define AP_DEV_SLEW_RATE(ap, dev) dev##_SLEW +#endif + +#if PIN_CFG_AP +static const uint32_t gpio_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const uint32_t gpio_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_IRQ + CFG_DISABLED, // 9 : WL_HOST_WAKE -> NC_WL_HOST_WAKE + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> GPIO_BOOT_CONFIG_1 + CFG_DISABLED, // 36 : GPIO[4] -> GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 46 : GPIO[14] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> NC_AP_GPIO17 + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 +}; + +#if PIN_CFG_AP +static const uint32_t gpio_1_default_cfg_ap[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#elif PIN_CFG_DEV +static const uint32_t gpio_1_default_cfg_dev[GPIO_GROUP_COUNT * GPIOPADPINS] = { +#endif + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | INPUT_SCHMITT, // 3 : CLK32K_IN -> GPIO_PMU_TO_SPU_CLK32K_IN + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_SPU_TO_COMPASS_TRG + CFG_OUT_0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 20 : SPU_GPIO[8] -> GPIO_OPAL_TO_SPU_INT_L + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_DISABLED, // 33 : SPU_SPI_CS_TRIG[2] -> NC_SPU_SPI_CS_TRIG2 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 38 : SPU_SPI_CS_TRIG[7] -> SCM_SPU_TO_COMPASS_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 39 : SPU_SPI_CS_TRIG[8] -> SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_DISABLED, // 47 : SPU_GPIO[9] -> NC_GPIO_SPU_TO_OPAL_RESET_L + +/* Port 6 */ + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | AP_DEV_DRIVE_STR(X1, X2) | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL +}; + + +#undef AP_DEV_SLEW_RATE +#undef AP_DEV_DRIVE_STR diff --git a/target/watch2/include/target/powerconfig.h b/target/watch2/include/target/powerconfig.h new file mode 100644 index 0000000..1f96501 --- /dev/null +++ b/target/watch2/include/target/powerconfig.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Computer, Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef __TARGET_POWERCONFIG_H +#define __TARGET_POWERCONFIG_H + +/* configuration per target */ + +#define PMU_IIC_BUS 0 +#define CHARGER_IIC_BUS 0 + +/* this configuration is very PMU specific and must be included exactly once in power.c */ +#ifdef POWERCONFIG_PMU_SETUP + +static const struct pmu_setup_struct pmu_ldo_warm_setup[] = +{ +}; + +static const struct pmu_setup_struct pmu_ldo_cold_setup[] = +{ + { PMU_IIC_BUS, kD2238_BUCK2_VSEL, 0xc0 }, // M7 - Memory VDDQ and VDD2 Nominal Voltage +}; + +static const struct pmu_setup_struct pmu_warm_init[] = +{ +}; + +static const struct pmu_setup_struct pmu_cold_init[] = +{ + { PMU_IIC_BUS, kD2238_ALL_RAILS_CONF, 0x00 }, // enable SOC_VDD_ALL_RAILS_ON processing + { PMU_IIC_BUS, kD2238_GPIO14_CONF1, 0x93 }, // PMU register 0x041A needs to be changed to 0x93 during boot-up + { PMU_IIC_BUS, kD2238_GPIO12_CONF1, 0x00 }, // Display needs to be in reset + { PMU_IIC_BUS, kDIALOG_CHARGE_CONTROL_VSET, 0x3f }, // n27: PMU CV voltage needs to be changed from POR +}; + +static const struct core_rails_struct soc_rails[] = +{ +}; + +static const struct core_rails_struct cpu_rails[] = +{ +}; + +static const struct core_rails_struct ram_rails[] = +{ +}; + +#endif /* POWERCONFIG_PMU_SETUP */ + +#define NO_BATTERY_VOLTAGE 2700 +#define MIN_BOOT_BATTERY_VOLTAGE 3600 +#define TARGET_BOOT_BATTERY_VOLTAGE 3700 +#define TARGET_BOOT_BATTERY_CAPACITY 0 // rely on SOCF flag only +#define TARGET_PRECHARGE_GG_FLAG_MASK kHDQRegFlagsMaskSOCF +#define PRECHARGE_BACKLIGHT_LEVEL 824 +#define ALWAYS_BOOT_BATTERY_VOLTAGE (TARGET_BOOT_BATTERY_VOLTAGE + 100) +#define TARGET_FORCE_DEBUG_PRECHARGE 1 // always precharge if "debug" precharge bit set + +#define TARGET_CHARGER_HEADROOM 150 +#define TARGET_CHARGER_MAX_VRECT 7500 +#define TARGET_CHARGER_NEEDS_MAX_VRECT(rem_cap, max_cap) (((rem_cap) * 1000) <= ((max_cap) * 15)) /* 1.5% or lower */ + +#define ACC_PWR_LDO (0) // ACC_PWR not connected + +#endif diff --git a/target/watch2/include/target/uartconfig.h b/target/watch2/include/target/uartconfig.h new file mode 100644 index 0000000..517f4f8 --- /dev/null +++ b/target/watch2/include/target/uartconfig.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef __TARGET_UARTCONFIG_H +#define __TARGET_UARTCONFIG_H + +/* define one debug serial ports */ +#define DEBUG_SERIAL_PORT (0) + +#define HDQGAUGE_SERIAL_PORT (3) + +#if SUPPORT_FPGA +#define UART_OVERSAMPLE_OVERRIDE (11) +#endif + +#endif diff --git a/target/watch2/init.c b/target/watch2/init.c new file mode 100644 index 0000000..19f683f --- /dev/null +++ b/target/watch2/init.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "init_fpga.h" +#include "init_product.h" +#include "init_sim.h" + +MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); +MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); + +void target_early_init(void) +{ +#if !CONFIG_FPGA && !CONFIG_SIM + product_target_early_init(); +#endif +} + +void target_late_init(void) +{ +#if !CONFIG_FPGA && !CONFIG_SIM + product_target_late_init(); +#endif +} + +void target_init(void) +{ +#if WITH_HW_FLASH_NOR + flash_nor_init(SPI_NOR0); +#endif +} + +void target_quiesce_hardware(void) +{ +} + +void target_poweroff(void) +{ +} + + +int target_bootprep(enum boot_target target) +{ + return 0; +} + +bool target_should_recover(void) +{ +#if CONFIG_SIM + return sim_target_should_recover(); +#elif CONFIG_FPGA + return fpga_target_should_recover(); +#else + return product_target_should_recover(); +#endif +} + +bool target_should_poweron(bool *cold_button_boot) +{ +#if CONFIG_SIM + return sim_target_should_poweron(cold_button_boot); +#elif CONFIG_FPGA + return fpga_target_should_poweron(cold_button_boot); +#else + return product_target_should_poweron(cold_button_boot); +#endif +} + +bool target_should_poweroff(bool at_boot) +{ +#if CONFIG_SIM + return sim_target_should_poweroff(at_boot); +#elif CONFIG_FPGA + return fpga_target_should_poweroff(at_boot); +#else + return product_target_should_poweroff(at_boot); +#endif +} + +#if WITH_ENV + +void target_setup_default_environment(void) +{ +#if CONFIG_SIM + sim_target_setup_default_environment(); +#elif CONFIG_FPGA + fpga_target_setup_default_environment(); +#else + product_target_setup_default_environment(); +#endif +} + +#endif // WITH_ENV + +#if WITH_DEVICETREE + +int target_update_device_tree(void) +{ +#if CONFIG_SIM + return sim_target_update_device_tree(); +#elif CONFIG_FPGA + return fpga_target_update_device_tree(); +#else + return product_target_update_device_tree(); +#endif +} + +#endif // WITH_DEVICETREE diff --git a/target/watch2/init_fpga.c b/target/watch2/init_fpga.c new file mode 100644 index 0000000..7a9b48e --- /dev/null +++ b/target/watch2/init_fpga.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool fpga_target_should_recover(void) +{ + return false; +} + +bool fpga_target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool fpga_target_should_poweroff(bool at_boot) +{ + return false; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +#if WITH_ENV + +void fpga_target_setup_default_environment(void) +{ + env_set("boot-args", " debug=0x14e serial=3 amfi_unrestrict_task_for_pid=1 amfi_allow_any_signature=1 amfi_get_out_of_my_way=1 cs_enforcement_disable=1 no-dockfifo-uart=1", 0); + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "fpga-wsvga", 0); /* defaults to no display support */ + env_set("ramdisk-delay", "600000000", 0); /* This tells PurpleRestore to slow down; rdar://6345846; rdar://problem/20524682 */ + env_set("idle-off", "false", 0); + env_set("bootdelay", "3", 0); + env_set("debug-uarts", "3", 0); +} + +#endif + +#if WITH_DEVICETREE + +int fpga_target_update_device_tree(void) +{ + return 0; +} + +#endif + +bool target_needs_chargetrap(void) +{ + return false; +} + +bool target_do_chargetrap(void) +{ + return false; +} + +#if !WITH_HW_POWER +bool power_needs_thermal_trap(void) +{ + return false; +} + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +uint32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(uint8_t key, uint8_t *data) +{ + return -1; +} + +int power_set_nvram(uint8_t key, uint8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/watch2/init_fpga.h b/target/watch2/init_fpga.h new file mode 100644 index 0000000..28cc1b3 --- /dev/null +++ b/target/watch2/init_fpga.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _TARGET_INIT_FPGA_H +#define _TARGET_INIT_FPGA_H + +bool fpga_target_should_recover(void); +bool fpga_target_should_poweron(bool *cold_button_boot); +bool fpga_target_should_poweroff(bool at_boot); +void fpga_target_setup_default_environment(void); +int fpga_target_update_device_tree(void); + +#endif /* ! _TARGET_INIT_FPGA_H */ diff --git a/target/watch2/init_product.c b/target/watch2/init_product.c new file mode 100644 index 0000000..dda65b4 --- /dev/null +++ b/target/watch2/init_product.c @@ -0,0 +1,1150 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#if WITH_HW_DISPLAY_PMU +#include +#endif +#if WITH_HW_DOCKFIFO_UART || WITH_HW_DOCKFIFO_BULK +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOARD_TYPE_N27_AP (0xA) +#define BOARD_TYPE_N28_AP (0xC) +#define BOARD_TYPE_N27A_AP (0x2) +#define BOARD_TYPE_N28A_AP (0x4) + +#define BOARD_TYPE_N27_DEV (0xB) +#define BOARD_TYPE_N28_DEV (0xD) +#define BOARD_TYPE_N27A_DEV (0x3) +#define BOARD_TYPE_N28A_DEV (0x5) + +// Display panel type +typedef enum { + DISPLAY_PANEL_TYPE_UNKNOWN = 0, + DISPLAY_PANEL_TYPE_C1_DC, + DISPLAY_PANEL_TYPE_SLTSID, + DISPLAY_PANEL_TYPE_CRADLE, + DISPLAY_PANEL_TYPE_ALT_DISP_POC1, + DISPLAY_PANEL_TYPE_POR_DISP_S, + DISPLAY_PANEL_TYPE_POR_DISP_B, + DISPLAY_PANEL_TYPE_ALT_DISP_N31, + DISPLAY_PANEL_TYPE_POR_DISP_B_VID, + // Metadata + DISPLAY_PANEL_TYPE_COUNT +} display_panel_type; + +static const char *display_panel_types[] = { + "UNKNOWN", + "C1", + "C1", + "C1", + "C1", + "POR_DISP_S", + "POR_DISP_B", + "ALT_DISP_N31", + "POR_DISP_B_VID" +}; + +typedef enum { + DISPLAY_TOUCH_TYPE_UNKNOWN = 0, + DISPLAY_TOUCH_TYPE_T126_SALTYSID, + DISPLAY_TOUCH_TYPE_A1N27A_1_POC1, + DISPLAY_TOUCH_TYPE_A1N27A_1_PROTON, + DISPLAY_TOUCH_TYPE_A1N28A_1_PROTON, + DISPLAY_TOUCH_TYPE_A1N27A_1_PROTO2, + DISPLAY_TOUCH_TYPE_A1N28A_1_PROTO2, + // Metadata + DISPLAY_TOUCH_TYPE_COUNT +} display_touch_type; + +static const char *display_touch_types[] = { + "UNKNOWN", + "multi-touch,t126-saltysid", + "A1N27A,1-POC1", + "A1N27A,1-ProtoN", + "A1N28A,1-ProtoN", + "A1N27A,1-Proto2", + "A1N28A,1-Proto2" +}; + +// Display panel id sense pins +#define DISPLAY_TO_AP_ID0 GPIO( 17, 1) // RMII_CRSDV +#define DISPLAY_TO_AP_ID1 GPIO( 16, 7) // RMII_RXD_0 +#define DISPLAY_TO_AP_ID2 GPIO( 17, 0) // RMII_RXD_1 +#define DISPLAY_TO_AP_ID3 GPIO( 16, 4) // RMII_CLK + +static bool gpio_board_rev_valid; +static uint32_t gpio_board_rev; +static bool gpio_display_id_valid; +static display_panel_type display_panel; +static display_touch_type display_touch; + +uint32_t ipod6_get_board_rev(void) +{ + if (!gpio_board_rev_valid) { + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); + + gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); + gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); + + spin(100); // Wait 100us + + gpio_board_rev = + (gpio_read(GPIO_BOARD_REV3) << 3) | + (gpio_read(GPIO_BOARD_REV2) << 2) | + (gpio_read(GPIO_BOARD_REV1) << 1) | + (gpio_read(GPIO_BOARD_REV0) << 0); + + gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); + gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); + + gpio_board_rev_valid = true; + } + + return gpio_board_rev; +} + +bool ipod6_is_beryllium_supported() +{ + bool result = true; + + // On M7 DEV board configs, read ALT_BOOST_ID pin to check if Beryllium daughter card exists. + // DEV config: board-id == 1 + if (((rPMGR_SCRATCH0 >> 16) & 0xf) == 1) + result = gpio_read(GPIO_ALT_BOOST_ID); + + return result; +} + +static void ipod6_power_display(bool enable) +{ +#ifdef GPIO_PMU_LCD_PWR_EN + power_set_gpio(GPIO_PMU_LCD_PWR_EN, 1, 1); +#endif +#ifdef PMU_LCD_PWR_DVDD +#ifdef PMU_LCD_PWR_VCI + power_enable_ldo(PMU_LCD_PWR_DVDD, enable); + power_enable_ldo(PMU_LCD_PWR_VCI, enable); +#endif // PMU_LCD_PWR_VCI +#endif // PMU_LCD_PWR_DVDD +#ifdef GPIO_LCD_PWR_EN + gpio_write(GPIO_LCD_PWR_EN, enable); +#endif +} + +// The panel id pin mappings are desribed by the following id pin states: + +// ID0 ID1 ID2 ID3 Panel TOUCH +// ---- ---- ---- ---- ----- ------ +// PD PU PU X C1_DC +// PU PD PD X SLTSID +// PU PD PU X CRADLE +// PU PU PD PD ALT_DISP_POC1 +// PU PU PD PU POR_DISP_S +// PU PU PU PD POR_DISP_B +// PU PU PU PU ALT_DISP_N31 +// PD PU PU PD POR_DISP_B_VID + +static void ipod6_get_display_info(void) +{ + const char *id0; + const char *id1; + const char *id2; + const char *id3; + + if (target_config_ap()) { + switch (platform_get_board_id()) { + case BOARD_TYPE_N27_AP: + case BOARD_TYPE_N27A_AP: + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_S; + if (ipod6_get_board_rev() >= BOARD_REV_PROTON) + display_touch = DISPLAY_TOUCH_TYPE_A1N27A_1_PROTON; + else + display_touch = DISPLAY_TOUCH_TYPE_A1N27A_1_PROTO2; + + return; + case BOARD_TYPE_N28_AP: + case BOARD_TYPE_N28A_AP: + // Special case Cardinal BOARD_REV's display. + if (ipod6_get_board_rev() == BOARD_REV_PROTO2X_CARDINAL) + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B_VID; + else + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B; + + + if (ipod6_get_board_rev() >= BOARD_REV_PROTON) + display_touch = DISPLAY_TOUCH_TYPE_A1N28A_1_PROTON; + else + display_touch = DISPLAY_TOUCH_TYPE_A1N28A_1_PROTO2; + return; + } + } + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_IN); + gpio_configure(DISPLAY_TO_AP_ID1, GPIO_CFG_IN); + gpio_configure(DISPLAY_TO_AP_ID2, GPIO_CFG_IN); + gpio_configure(DISPLAY_TO_AP_ID3, GPIO_CFG_IN); + + gpio_configure_pupdn(DISPLAY_TO_AP_ID0, GPIO_PDN); + gpio_configure_pupdn(DISPLAY_TO_AP_ID1, GPIO_PDN); + gpio_configure_pupdn(DISPLAY_TO_AP_ID2, GPIO_PDN); + gpio_configure_pupdn(DISPLAY_TO_AP_ID3, GPIO_PDN); + + spin(100); // Wait 100us + + if (!gpio_read(DISPLAY_TO_AP_ID0)) { + id0 = "pd"; + if (gpio_read(DISPLAY_TO_AP_ID1)) { + id1 = "pu"; + if (gpio_read(DISPLAY_TO_AP_ID2)) { + id2 = "pu"; + if (!gpio_read(DISPLAY_TO_AP_ID3)) { + id3 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B_VID; + display_touch = DISPLAY_TOUCH_TYPE_A1N28A_1_PROTON; + gpio_display_id_valid = true; + } else { + id3 = "pu"; + } + } else { + id2 = "pd"; + id3 = "not read"; + } + } else { + id1 = "pu"; + id2 = "not read"; + id3 = "not read"; + display_panel = DISPLAY_PANEL_TYPE_C1_DC; + display_touch = DISPLAY_TOUCH_TYPE_UNKNOWN; + gpio_display_id_valid = true; + } + } else { + id0 = "pu"; + + if (!gpio_read(DISPLAY_TO_AP_ID1)) { + id1 = "pd"; + id3 = "not read"; + if (!gpio_read(DISPLAY_TO_AP_ID2)) { + id2 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_SLTSID; + display_touch = DISPLAY_TOUCH_TYPE_T126_SALTYSID; + gpio_display_id_valid = true; + } else { + id2 = "pu"; + display_panel = DISPLAY_PANEL_TYPE_CRADLE; + display_touch = DISPLAY_TOUCH_TYPE_T126_SALTYSID; + gpio_display_id_valid = true; + } + } else { + id1 = "pu"; + if (!gpio_read(DISPLAY_TO_AP_ID2)) { + id2 = "pd"; + + if (!gpio_read(DISPLAY_TO_AP_ID3)) { + id3 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_ALT_DISP_POC1; + display_touch = DISPLAY_TOUCH_TYPE_A1N27A_1_POC1; + gpio_display_id_valid = true; + } else { + id3 = "pu"; + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_S; + display_touch = DISPLAY_TOUCH_TYPE_A1N27A_1_PROTON; + gpio_display_id_valid = true; + } + } else { + id2 = "pu"; + if (!gpio_read(DISPLAY_TO_AP_ID3)) { + id3 = "pd"; + display_panel = DISPLAY_PANEL_TYPE_POR_DISP_B; + display_touch = DISPLAY_TOUCH_TYPE_A1N28A_1_PROTON; + gpio_display_id_valid = true; + } else { + id3 = "pu"; + display_panel = DISPLAY_PANEL_TYPE_ALT_DISP_N31; + display_touch = DISPLAY_TOUCH_TYPE_UNKNOWN; + gpio_display_id_valid = true; + } + } + } + } + + dprintf(DEBUG_INFO, "%s panel id pin state: id0=%s, id1=%s, id2=%s, id3=%s\n", + gpio_display_id_valid ? "" : "Unknown", id0, id1, id2, id3); + + ASSERT(display_panel < DISPLAY_PANEL_TYPE_COUNT); + ASSERT(display_touch < DISPLAY_TOUCH_TYPE_COUNT); + + dprintf(DEBUG_INFO, "Display panel = %s\nDisplay switch = %s\n", + display_panel_types[display_panel], + display_touch_types[display_touch]); + + gpio_configure(DISPLAY_TO_AP_ID0, GPIO_CFG_DFLT); + gpio_configure(DISPLAY_TO_AP_ID1, GPIO_CFG_DFLT); + gpio_configure(DISPLAY_TO_AP_ID2, GPIO_CFG_DFLT); + gpio_configure(DISPLAY_TO_AP_ID3, GPIO_CFG_DFLT); +} + +uint32_t target_get_display_panel_type(void) +{ + if (!gpio_display_id_valid) { + ipod6_get_display_info(); + } + + return display_panel; +} + +uint32_t target_get_display_touch_type(void) +{ + if (!gpio_display_id_valid) { + ipod6_get_display_info(); + } + + return display_touch; +} + +#if WITH_HW_POWER +int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); +int pmu_get_data(int dev, uint16_t reg, uint8_t *byte); + +static int product_pmu_gpiocfg(int gpiono, uint8_t conf1, uint8_t conf2) +{ + const uint16_t base=0x0400+(gpiono-1)*2; + + int rc=pmu_set_data( 0, base, conf1, 0 ); + if ( rc==0 ) rc=pmu_set_data( 0, base+1, conf2, 0 ); + + return rc; +} +#endif + +void product_target_early_init(void) +{ + // Get the display panel type. + //The display IDs need the display's rails to be turned on + ipod6_power_display(true); + ipod6_get_display_info(); + +#if WITH_HW_POWER + // M7: Configure binned voltages for M7 A1 parts + const uint32_t frev=chipid_get_fuse_revision(); + const uint32_t crev=chipid_get_chip_revision(); + if ( crev>=0x01 && frev>=0x03 ) { + uint8_t vsel=0; + + // bin is at bits 37-43 in fuse (or 7 bits in rCFG_FUSE1[5-11] ) + uint8_t bin=(rCFG_FUSE1>>5)&0x7f; + switch ( bin ) { + case 0x34: vsel=0x54; break; // bin1 + case 0x2f: vsel=0x4c; break; // bin2 + case 0x2a: vsel=0x44; break; // bin3 + default: /* warn? maybe... */ break; + } + + if ( vsel ) { + int rc=pmu_set_data( 0, 0x100, vsel, 1); // buck0_vsel + if ( rc==0 ) rc=pmu_set_data( 0, 0x101, vsel-0x10, 1); // buck0_vsel_alt, vsel-50mV + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: cannot change buck0_vsel* (%d)\n", rc); + } + } + + // override PMU OTP for charger if necessary + if (ipod6_get_board_rev() <= BOARD_REV_PROTO2A && ipod6_get_board_rev() >= BOARD_REV_PROTO2F) { + uint8_t hr_lookup_i; + switch (platform_get_board_id()) { + case BOARD_TYPE_N27_AP: + case BOARD_TYPE_N27_DEV: + case BOARD_TYPE_N27A_AP: + case BOARD_TYPE_N27A_DEV: + hr_lookup_i = 0x17; + break; + case BOARD_TYPE_N28_AP: + case BOARD_TYPE_N28A_AP: + case BOARD_TYPE_N28_DEV: + case BOARD_TYPE_N28A_DEV: + hr_lookup_i = 0x1b; + break; + default: + hr_lookup_i = 0x00; + break; + } + + // PMU into test mode + pmu_set_data(0, 0x7000, 0x1d, 1); + // adjust HR_LOOKUP_Ix values + uint16_t hr_lookup_regs[] = { 0x4de, 0x4e0, 0x4e2, 0x4e4, 0x4e6, 0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4ef }; + for (unsigned i = 0 ; i < (sizeof(hr_lookup_regs) / sizeof(uint16_t)); i++) { + uint8_t data; + if (pmu_get_data(0, hr_lookup_regs[i], &data) == 0 && data < hr_lookup_i) { + pmu_set_data(0, hr_lookup_regs[i], hr_lookup_i, 1); + } + } + // out of test mode + pmu_set_data(0, 0x7000, 0x00, 0); + } + + // Need to use control signal GPIO16 for I2C isolator to Seajay + // TODO: remove this hack after all drivers have proper support + #define GPIO_SEAJAY_I2C_SDA_ENABLE GPIOC(GPIO_AP, 8, 71) + gpio_configure(GPIO_SEAJAY_I2C_SDA_ENABLE, GPIO_CFG_OUT_0); + spin(100); // Wait 100us + gpio_write(GPIO_SEAJAY_I2C_SDA_ENABLE, 1); +#endif +} + +static int product_board_typeid(void) +{ + switch ( platform_get_board_id() ) { + case BOARD_TYPE_N27_AP: + case BOARD_TYPE_N28_AP: + case BOARD_TYPE_N27A_AP: + case BOARD_TYPE_N28A_AP: + return 0; + case BOARD_TYPE_N27_DEV: + case BOARD_TYPE_N28_DEV: + case BOARD_TYPE_N27A_DEV: + case BOARD_TYPE_N28A_DEV: + return 1; + default: break; + } + + return -1; +} + +#define ENVAR_PWR_PATH "pwr-path" + +void product_target_late_init(void) +{ +#if WITH_HW_POWER + const uint32_t rev=ipod6_get_board_rev(); + if ( rev==BOARD_REV_PROTON ) { + int rc; + + // Change PMU_VDD_OK from Open Drain to push pull + rc=pmu_set_data(0, 0x7000, 0x1d, 0); // test mode + if ( rc<0 ) { + dprintf(DEBUG_INFO, "PMU: test mode (%d)\n", rc); + } else { + rc=pmu_set_data(0, 0x0466, 0x10, 1); + if ( rc<0 ) dprintf(DEBUG_INFO, "VDD_OK_CONF (%d)\n", rc); + + rc=pmu_set_data(0, 0x7000, 0x00, 0); + if ( rc<0 ) panic("PMU: test mode (%d)", rc); + } + } + + // Change behavior of PMU GPIO 13 (GPIO_DISABLE_PWR_PATH) + if ( rev<=BOARD_REV_PROTO2A ) { + uint8_t level=0; + + const int typeid=product_board_typeid(); + if ( typeid==0 ) { // AP set GPIO13 high on Release Build +#if RELEASE_BUILD + level=1; +#endif + } else if ( typeid==1 ) { // DEV set GPIO13 Low unless boot arg is set +#if WITH_ENV + const char *boot_args = env_get("boot-args"); + if ( boot_args != NULL ) { + char *arg_str = strstr(boot_args, ENVAR_PWR_PATH"="); + if ( arg_str != NULL ) { + level = ( arg_str[strlen(ENVAR_PWR_PATH"=")] == '1' ); + dprintf(DEBUG_CRITICAL, "PMU: forcing pwr-path=%d\n", level); + } + } else if ( env_get_bool(ENVAR_PWR_PATH, 0) ) { + dprintf(DEBUG_CRITICAL, "PMU: forcing pwr-path=1\n"); + level=1; + } +#endif + } + + int rc=product_pmu_gpiocfg(13, ( level<<1 ) | 0x1, 0x2 ); + if ( rc<0 ) dprintf(DEBUG_CRITICAL, "PMU: pwr_path failed (%d)\n", rc); + } + +#endif + + target_init_boot_manifest(); +} + +bool product_target_should_recover(void) +{ + return platform_get_request_dfu2() && power_has_usb(); +} + +bool product_target_should_poweron(bool *cold_button_boot) +{ +#if WITH_HW_POWER + if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; +#else + *cold_button_boot = false; +#endif // WITH_HW_POWER + + return !*cold_button_boot || platform_get_request_dfu1(); +} + +bool product_target_should_poweroff(bool at_boot) +{ + return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); +} + +#if WITH_ENV + +void product_target_setup_default_environment(void) +{ + uint32_t panel_type_index; + + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + panel_type_index = target_get_display_panel_type(); + env_set("display-timing", display_panel_types[panel_type_index], 0); +#if !RELEASE_BUILD + env_set("diags-path", "/AppleInternal/Diags/bin/diag.img4", 0); + env_set("diags-vendor-path", "/AppleInternal/Diags/bin/diag-vendor.img4", 0); +#endif // !RELEASE_BUILD +} + +#endif // WITH_ENV + +bool product_target_is_display_in_video_mode(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return true; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + case DISPLAY_PANEL_TYPE_POR_DISP_B: + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return false; + } + + return false; +} + +bool product_target_no_burst_mode(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return true; + } + + return false; +} + +//The following 3 fuctions uses the values as defined in https://seg-docs.ecs.apple.com/projects/m7//release/specs/Apple/Top/M7_display_timing.xls +//“M7 Command Mode Timing†+// +uint32_t product_target_get_ulps_in_delay(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return 0; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + return 13056; + case DISPLAY_PANEL_TYPE_POR_DISP_B: + return 14976; + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return 19680; + } + + return false; +} + +uint32_t product_target_get_ulps_end_delay(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return 0; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + return 722538; + case DISPLAY_PANEL_TYPE_POR_DISP_B: + return 637035; + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return 584135; + } + + return false; +} + +uint32_t product_target_get_ulps_out_delay(void) +{ + switch(target_get_display_panel_type()){ + case DISPLAY_PANEL_TYPE_C1_DC: + case DISPLAY_PANEL_TYPE_SLTSID: + case DISPLAY_PANEL_TYPE_CRADLE: + case DISPLAY_PANEL_TYPE_ALT_DISP_POC1: + case DISPLAY_PANEL_TYPE_POR_DISP_B_VID: + return 0; + case DISPLAY_PANEL_TYPE_POR_DISP_S: + return 655913; + case DISPLAY_PANEL_TYPE_POR_DISP_B: + return 570410; + case DISPLAY_PANEL_TYPE_ALT_DISP_N31: + return 517510; + } + + return false; +} + +#if WITH_DEVICETREE + +void display_update_device_tree() +{ +#if WITH_HW_DISPLAY_PMU + display_pmu_update_device_tree("arm-io/i2c1/display-pmu"); +#endif + DTNode *disp0_node; + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + bool video_mode; + + video_mode = product_target_is_display_in_video_mode(); + // Find the DISP0 (display-subsystem 0) node + if (FindNode(0, "arm-io/disp0", &disp0_node)) { + propName = "video-mode"; + if (FindProperty(disp0_node, &propName, &propData, &propSize)) { + *((bool*)propData) = video_mode; + } + } + if (video_mode) { + if (FindNode(0, "arm-io/mipi-dsim", &node)) { + propName = "supports-auto-ulps"; + //Do not turn on Auto ULPS on when on video mode + if (FindProperty(node, &propName, &propData, &propSize)) { + *((bool*)propData) = false; + } + } + } + +#if WITH_HW_DISPLAY_SUMMIT + DTNode *backlight_node; + if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { + extern int summit_update_device_tree(DTNode *summit_node, DTNode *clcd_node, DTNode *backlight_node); + FindNode(0, "backlight", &backlight_node); + summit_update_device_tree(node, disp0_node, backlight_node); + } +#endif //WITH_HW_DISPLAY_SUMMIT +} +void hid_update_device_tree() +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, MULTITOUCH_DTPATH, &node)) { + propName = "hid-fw-personality"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + strlcpy(propData, display_touch_types[display_touch], propSize); + } + propName = "orb-f-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('OFCl', propData, propSize); + } + propName = "orb-o-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('OOCl', propData, propSize); + } + propName = "orb-i-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('OICo', propData, propSize); + } + } +} + +static void spu_update_device_tree(void) +{ + const char* accel_path = "arm-io/spu/accel"; + const char* gyro_path = "arm-io/spu/gyro"; + const char* als_path = "arm-io/spu/als"; + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (ipod6_get_board_rev() == BOARD_REV_PROTO2B_ALT_CARBON || ipod6_get_board_rev() == BOARD_REV_PROTO2F || ipod6_get_board_rev() == BOARD_REV_EVT_ALT_CARBON) { + // iPod6 Proto2: Muck with SPU personality based off BOARD_REV + // (requests 0x2F to be SPU2 as well) + if (!target_config_ap()) { + // ST IMU on dev3 currently doesn't get recognized by iBoot + // For Dev boards, we rely on the user to select the right BOARD_REV jumper. Try to provide a + // clear log message in serial to alert the user and also help with triaging SPU personality issues. + dprintf(DEBUG_CRITICAL, + "*********\nNOTICE: Dev board's BOARD_REV jumpered for 'spu2' personality. Make sure you have the right IMU daughtercard for this!\n********\n"); + } + dprintf(DEBUG_INFO, "Using alternate SPU personality\n"); + if (FindNode(0, "arm-io/spu", &node)) { + propName = "compatible"; + if (FindProperty(node, &propName, &propData, &propSize)) { + const char* alt_name = "iop-spu2,s5l8960x"; + if (propSize < strlen(alt_name)+1) { + panic("arm-io/spu compatible: propSize is insufficient to hold personality %s", alt_name); + } + bzero(propData, propSize); + snprintf(propData, propSize, "%s", alt_name); + } else { + panic("Cannot find arm-io/spu compatible: property"); + } + } else { + panic("Can't find arm-io:/spu"); + } + + } + if ((target_config_ap() && ipod6_get_board_rev() >= BOARD_REV_PROTON) || (target_config_dev() && ipod6_get_board_rev() >= BOARD_REV_DEV3)) { + // iBoot - Add SCM support to Osmium for proto2 + // Proto2 and beyond, and DEV4 and beyond is osmium_revision 1. + if (FindNode(0, "arm-io/spu", &node)) { + propName = "osmium-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t*)propData = 0x0; + } + } + + } + + /* Accel Calibration */ + if (FindNode(0, accel_path, &node)) { + propName = "accel-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('AICl', propData, propSize); + } + + propName = "accel-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('ASCl', propData, propSize); + } + + propName = "accel-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('ARot', propData, propSize); + } + + propName = "low-temp-accel-offset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('LTAO', propData, propSize); + } + + } + + /* Gyro Calibration */ + if (FindNode(0, gyro_path, &node)) { + propName = "gyro-interrupt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GICl', propData, propSize); + } + + propName = "gyro-sensitivity-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GSCl', propData, propSize); + } + + propName = "gyro-orientation"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GRot', propData, propSize); + } + + propName = "gyro-temp-table"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('GYTT', propData, propSize); + } + + } + + /* ALS Calibration */ + if (FindNode(0, als_path, &node)) { + propName = "alsCalibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('LSCI', propData, propSize); + } + } +} + +static void opal_update_device_tree(void) +{ + const char* opal_path = "arm-io/opal"; + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, opal_path, &node)) { + propName = "li-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('LiCl', propData, propSize); + } + + propName = "pt-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('PlCl', propData, propSize); + } + + propName = "device-board-revision"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *(uint32_t*)(propData) = ipod6_get_board_rev(); + } + } +} + +static void audio_update_device_tree(const char* dtpath) +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, dtpath, &node)) { + propName = "actuator-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('TCal', propData, propSize); + } + propName = "codec-calibration"; + if (FindProperty(node, &propName, &propData, &propSize)) { + memset(propData, 0, propSize); + syscfgCopyDataForTag('CCal', propData, propSize); + } + } +} + +static void charger_update_device_tree(void) +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + if (FindNode(0, "arm-io/i2c0/ext-charger", &node)) { + if (ipod6_get_board_rev() > BOARD_REV_PROTO2A) { + propName = "interrupts"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "interrupt-parent"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-ping_detect"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "proton-open-loop"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "open-loop", kPropNameLength); + } + } + if (ipod6_get_board_rev() > BOARD_REV_PROTO2B) { + propName = "function-reset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + propName[0] = '~'; + } + propName = "function-proton_reset"; + if (FindProperty(node, &propName, &propData, &propSize)) { + strlcpy(propName, "function-reset", propSize); + } + } + } +} + +static void device_material_update_device_tree(void) +{ + DTNode *node; + char *propName; + uint32_t propSize; + void *propData; + + DMin_t Dmin; + bzero(&Dmin, sizeof(Dmin)); + + // Look up the 'DMin' tag from syscfg. + int result = syscfgCopyDataForTag('DMin', (uint8_t*)&Dmin, sizeof(Dmin)); + if (result < 0) { + dprintf(DEBUG_CRITICAL, "Unable to find DMin key in syscfg.\n"); + return; + } + + if (Dmin.version != DMIN_VERSION_2) { + dprintf(DEBUG_CRITICAL, "DMin version %u is unspported.\n", (unsigned int)Dmin.version); + return; + } + if (FindNode(0, MULTITOUCH_DTPATH, &node)) { + /** + * DT property dmin key + * + * enc-top-type topEnclosure + * enc-bot-type botEnclosure + * fcm-type fcmType + * fcm-arcoated-type fcmARCoated + * fcm-inkcolor-type fcmInkColor + **/ + + propName = "enc-top-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.topEnclosure; + } + propName = "enc-bot-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.botEnclosure; + } + propName = "fcm-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.fcmType; + } + propName = "fcm-arcoated-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.fcmARCoated; + } + propName = "fcm-inkcolor-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.fcmInkColor; + } + + } + + const char* opal_path = "arm-io/opal"; + + if (FindNode(0, opal_path, &node)) { + /** + * Device Tree Key DMin Field + enc-top-type topEnclosure + enc-bot-type botEnclosure + bcm-window-type bcmWindow + bcm-lens-type bcmLens + pt-sensor-type bcmPTSensorType + pt-led-type bcmPTLEDType + lisa-opamp-type lisaOAType + lisa-sensor-ic lisaSensorIC + lisa-encoder-wheel lisaEncoderWheel + lisa-knurl lisaKnurl + **/ + propName = "enc-top-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.topEnclosure; + } + propName = "enc-bot-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.botEnclosure; + } + propName = "bcm-window-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmWindow; + } + propName = "bcm-lens-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmLens; + } + propName = "pt-sensor-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmPTSensorType; + } + propName = "pt-led-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.bcmPTLEDType; + } + propName = "lisa-opamp-type"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaOAType; + } + propName = "lisa-sensor-ic"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaSensorIC; + } + propName = "lisa-encoder-wheel"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaEncoderWheel; + } + propName = "lisa-knurl"; + if (FindProperty(node, &propName, &propData, &propSize)) { + *((uint32_t*)propData) = Dmin.v2.lisaKnurl; + } + + } +} + +int product_target_update_device_tree(void) +{ + + display_update_device_tree(); + + hid_update_device_tree(); + opal_update_device_tree(); + spu_update_device_tree(); + charger_update_device_tree(); + + audio_update_device_tree("arm-io/mca0/audio-actuator0"); + + device_material_update_device_tree(); + + return target_pass_boot_manifest(); +} + +#endif // WITH_DEVICETREE + +bool target_needs_chargetrap(void) +{ + return power_need_precharge() || power_needs_thermal_trap(); +} + +bool target_do_chargetrap(void) +{ +#if APPLICATION_IBOOT && PRODUCT_IBOOT + // Dali powertrap should only be considered in iBoot + if (target_needs_chargetrap()) { + dprintf(DEBUG_INFO, "Charge trap requested"); + + // Currently, Dali expects us to initialize the display. + // This requires two consecutive calls, just like in the main.c boot path. + platform_init_display(); + platform_init_display(); + int boot_dali_flash(void); + if (boot_dali_flash() < 0) + { + panic("Failed to boot dali but chargetrap was requested\n"); + } + return true; + } +#endif + return false; +} + +#if !WITH_HW_POWER + +bool power_needs_thermal_trap(void) +{ + return false; +} + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +uint32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(uint8_t key, uint8_t *data) +{ + return -1; +} + +int power_set_nvram(uint8_t key, uint8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/watch2/init_product.h b/target/watch2/init_product.h new file mode 100644 index 0000000..83a04a8 --- /dev/null +++ b/target/watch2/init_product.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _TARGET_INIT_PRODUCT_H +#define _TARGET_INIT_PRODUCT_H + +bool product_target_should_recover(void); +bool product_target_should_poweron(bool *cold_button_boot); +bool product_target_should_poweroff(bool at_boot); +void product_target_early_init(void); +void product_target_late_init(void); +void product_target_setup_default_environment(void); +int product_target_update_device_tree(void); + +#endif /* ! _TARGET_INIT_PRODUCT_H */ diff --git a/target/watch2/init_sim.c b/target/watch2/init_sim.c new file mode 100644 index 0000000..13e159d --- /dev/null +++ b/target/watch2/init_sim.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool sim_target_should_recover(void) +{ + return false; +} + +bool sim_target_should_poweron(bool *cold_button_boot) +{ + *cold_button_boot = true; + return true; +} + +bool sim_target_should_poweroff(bool at_boot) +{ + return false; +} + +#if !PRODUCT_LLB +bool target_get_property(enum target_property prop, void *data, int maxdata, int *retlen) +{ + return false; +} +#endif + +#if WITH_ENV + +void sim_target_setup_default_environment(void) +{ + env_set("boot-args", "debug=0x14e serial=3 amfi=0x83 cs_enforcement_disable=1 -disable_aslr no-dockfifo-uart=1", ENV_PERSISTENT); + env_set("boot-device", "asp_nand", 0); + env_set("display-color-space","RGB888", 0); + env_set("display-timing", "fpga-wsvga", 0); + env_set("idle-off", "false", 0); +// env_set("kaslr-slide", "0x10000000", 0); + env_set("kaslr-off", "true", 0); + env_set("wifiaddr", "12:22:33:44:55:66", 0); + env_set("ethaddr", "12:22:33:44:55:77", 0); + env_set("btaddr", "00:00:00:00:00:00", 0); +} + +#endif + +#if WITH_DEVICETREE + +#define ROOT_DTPATH "" +int sim_target_update_device_tree(void) +{ + DTNode *node; + uint32_t propSize; + char *propName; + void *propData; + + // Overwrite the serial-number with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "serial-number"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "serial-number property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *serial = (uint64_t *)propData; + serial[0] = *(volatile uint64_t *)0x4e000040; + serial[1] = *(volatile uint64_t *)0x4e000048; + serial[2] = *(volatile uint64_t *)0x4e000050; + serial[3] = *(volatile uint64_t *)0x4e000058; + } + } + + // Overwrite the region-info with data from the simplertc fastsim model + if (FindNode(0, ROOT_DTPATH, &node)) { + propName = "region-info"; + if (FindProperty(node, &propName, &propData, &propSize)) { + if (propSize != 0x20) { + dprintf(DEBUG_CRITICAL, "region-info property size 0x%x (expected 0x20)\n", propSize); + return -1; + } + uint64_t *region = (uint64_t *)propData; + region[0] = *(volatile uint64_t *)0x4e000060; + region[1] = *(volatile uint64_t *)0x4e000068; + region[2] = *(volatile uint64_t *)0x4e000070; + region[3] = *(volatile uint64_t *)0x4e000078; + } + } + + return 0; +} + +#endif + +bool target_needs_chargetrap(void) +{ + return false; +} + +bool target_do_chargetrap(void) +{ + return false; +} + +#if !WITH_HW_POWER + +bool power_needs_thermal_trap(void) +{ + return false; +} + +bool power_needs_precharge(void) +{ + return false; +} + +void power_cancel_buttonwait(void) +{ +} + +bool power_do_chargetrap(void) +{ + return false; +} + +bool power_is_suspended(void) +{ + return false; +} + +void power_will_resume(void) +{ +} + +bool power_has_usb(void) +{ + return false; +} + +int power_read_dock_id(unsigned *id) +{ + return -1; +} + +bool power_get_diags_dock(void) +{ + return false; +} + +uint32_t power_get_boot_battery_level(void) +{ + return 0; +} + +int power_get_nvram(uint8_t key, uint8_t *data) +{ + return -1; +} + +int power_set_nvram(uint8_t key, uint8_t data) +{ + return -1; +} + +int power_set_soc_voltage(unsigned mv, int override) +{ + return -1; +} + +bool force_usb_power = false; + +void power_set_usb_state(bool configured, bool suspended) +{ +} + +int power_backlight_enable(uint32_t backlight_level) +{ + return 0; +} + +#endif /* ! WITH_HW_POWER */ diff --git a/target/watch2/init_sim.h b/target/watch2/init_sim.h new file mode 100644 index 0000000..46b0fda --- /dev/null +++ b/target/watch2/init_sim.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef _TARGET_INIT_SIM_H +#define _TARGET_INIT_SIM_H + +bool sim_target_should_recover(void); +bool sim_target_should_poweron(bool *cold_button_boot); +bool sim_target_should_poweroff(bool at_boot); +void sim_target_setup_default_environment(void); +int sim_target_update_device_tree(void); + +#endif /* ! _TARGET_INIT_SIM_H */ diff --git a/target/watch2/pinconfig_evt.c b/target/watch2/pinconfig_evt.c new file mode 100644 index 0000000..468e8dd --- /dev/null +++ b/target/watch2/pinconfig_evt.c @@ -0,0 +1,566 @@ +/* + * Copyright (C) YEAR Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.4.0 + I/O Spreadsheet tracker: 15171729 + Conversion command: csvtopinconfig.py --soc m7 --radar 15171729 --prefix evt +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_evt_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_OUT_0 | SLOW_SLEW, // 71 : GPIO[16] -> AP_TO_SEAJAY_I2C_SDA_ENABLE + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> GPIO_AP_TO_BSYNC_RESET_EN_L + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_IN | INPUT_SCHMITT, // 75 : TMR32_PWM2 -> DISP_BSYNC + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0 | INPUT_SCHMITT, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_evt_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_evt_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 71 : GPIO[16] -> AP_TO_SEAJAY_I2C_SDA_ENABLE + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> GPIO_AP_TO_BSYNC_RESET_EN_L + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_IN | INPUT_SCHMITT, // 75 : TMR32_PWM2 -> DISP_BSYNC + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0 | INPUT_SCHMITT, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_evt_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_evt_ap_0, pinconfig_evt_ap_1 } }, + { 1, 1, { pinconfig_evt_dev_0, pinconfig_evt_dev_1 } }, +}; + +const uint32_t * target_get_evt_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/watch2/pinconfig_fpga.c b/target/watch2/pinconfig_fpga.c new file mode 100644 index 0000000..5c768f4 --- /dev/null +++ b/target/watch2/pinconfig_fpga.c @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: m8 io list. version 148 + I/O Spreadsheet tracker: 20260553 + Conversion command: csvtopinconfig.py --rom --soc m8 --config-column 'SecureROM config' --pupd-column PU/PD --copyright 2015 --radar 20260553 --netname-column 'ROM Config' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : GPIO[0] -> + CFG_DISABLED, // 1 : GPIO[1] -> + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 2 : GPIO[2] -> Boot_config[0] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 3 : GPIO[3] -> Boot_config[1] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 4 : GPIO[4] -> Boot_config[2] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 5 : GPIO[5] -> Boot_config[3] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 6 : GPIO[6] -> Board_ID[3] + CFG_DISABLED, // 7 : GPIO[7] -> + +/* Port 1 */ + CFG_DISABLED, // 8 : GPIO[8] -> + CFG_DISABLED, // 9 : GPIO[9] -> + CFG_DISABLED, // 10 : GPIO[10] -> + CFG_DISABLED, // 11 : GPIO[11] -> + CFG_DISABLED, // 12 : GPIO[12] -> + CFG_DISABLED, // 13 : GPIO[13] -> + CFG_DISABLED, // 14 : GPIO[14] -> + CFG_DISABLED, // 15 : GPIO[15] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[16] -> + CFG_DISABLED, // 17 : GPIO[17] -> + CFG_DISABLED, // 18 : TMR32_PWM1 -> + CFG_DISABLED, // 19 : TMR32_PWM2 -> + CFG_DISABLED, // 20 : TMR32_PWM0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : NAND_CEN[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : NAND_CEN[1] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 23 : NAND_IO[7] -> + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 24 : NAND_IO[6] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 25 : NAND_IO[5] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 26 : NAND_IO[4] -> + CFG_DISABLED | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 27 : NAND_REN -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 28 : NAND_IO[3] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 29 : NAND_IO[2] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 30 : NAND_IO[1] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 31 : NAND_IO[0] -> + +/* Port 4 */ + CFG_DISABLED | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 32 : NAND_WEN -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 33 : NAND_CLE -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 34 : NAND_ALE -> + CFG_DISABLED, // 35 : I2S0_LRCK -> + CFG_DISABLED, // 36 : I2S0_BCLK -> + CFG_DISABLED, // 37 : I2S0_DOUT -> + CFG_DISABLED, // 38 : I2S0_DIN -> + CFG_DISABLED, // 39 : I2S1_LRCK -> + +/* Port 5 */ + CFG_DISABLED, // 40 : I2S1_BCLK -> + CFG_DISABLED, // 41 : I2S1_DOUT -> + CFG_DISABLED, // 42 : I2S1_DIN -> + CFG_DISABLED, // 43 : I2S2_LRCK -> + CFG_DISABLED, // 44 : I2S2_BCLK -> + CFG_DISABLED, // 45 : I2S2_DOUT -> + CFG_DISABLED, // 46 : I2S2_DIN -> + CFG_DISABLED, // 47 : SD_CLKOUT -> + +/* Port 6 */ + CFG_DISABLED, // 48 : sDIO_IRQ -> + CFG_DISABLED, // 49 : SD_DATA_IO[0] -> + CFG_DISABLED, // 50 : SD_DATA_IO[1] -> + CFG_DISABLED, // 51 : SD_DATA_IO[2] -> + CFG_DISABLED, // 52 : SD_DATA_IO[3] -> + CFG_DISABLED, // 53 : SDIO_IRQ -> + CFG_DISABLED, // 54 : WL_HOST_WAKE -> + CFG_DISABLED, // 55 : ENET_MDC -> + +/* Port 7 */ + CFG_DISABLED, // 56 : ENET_MDIO -> + CFG_DISABLED, // 57 : RMII_RXER -> + CFG_DISABLED, // 58 : RMII_TXEN -> + CFG_DISABLED, // 59 : RMII_CLK -> + CFG_DISABLED, // 60 : RMII_TXD[0] -> + CFG_DISABLED, // 61 : RMII_TXD[1] -> + CFG_DISABLED, // 62 : RMII_RXD[0] -> + CFG_DISABLED, // 63 : RMII_RXD[1] -> + +/* Port 8 */ + CFG_DISABLED, // 64 : RMII_CRSDV -> + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 65 : SPI0_SCLK -> SPI0_SCLK/Board_ID[0] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 66 : SPI0_MOSI -> SPI0_MOSI/Board_ID[1] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 67 : SPI0_MISO -> SPI0_MISO/Board_ID[2] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 68 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 69 : SPI1_SCLK -> + CFG_DISABLED, // 70 : SPI1_MOSI -> + CFG_DISABLED, // 71 : SPI1_MISO -> + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI1_SSIN -> + CFG_DISABLED, // 73 : I2C0_SDA -> + CFG_DISABLED, // 74 : I2C0_SCL -> + CFG_DISABLED, // 75 : I2C1_SDA -> + CFG_DISABLED, // 76 : I2C1_SCL -> + CFG_DISABLED, // 77 : I2C2_0_SDA -> + CFG_DISABLED, // 78 : I2C2_0_SCL -> + CFG_DISABLED, // 79 : I2C2_1_SDA -> + +/* Port 10 */ + CFG_DISABLED, // 80 : I2C2_1_SCL -> + CFG_DISABLED, // 81 : UART0_TXD -> + CFG_DISABLED, // 82 : UART0_RXD -> + CFG_DISABLED, // 83 : UART3_RTXD -> + CFG_DISABLED, // 84 : UART4_TXD -> + CFG_DISABLED, // 85 : UART4_RXD -> + CFG_DISABLED, // 86 : UART5_TXD -> + CFG_DISABLED, // 87 : UART5_RXD -> + +/* Port 11 */ + CFG_DISABLED, // 88 : UART2_TXD -> + CFG_DISABLED, // 89 : UART2_RXD -> + CFG_DISABLED, // 90 : UART2_RTSN -> + CFG_DISABLED, // 91 : UART2_CTSN -> + CFG_DISABLED, // 92 : UART1_TXD -> + CFG_DISABLED, // 93 : UART1_RXD -> + CFG_DISABLED, // 94 : UART1_RTSN -> + CFG_DISABLED, // 95 : UART1_CTSN -> + +/* Port 12 */ + CFG_DISABLED, // 96 : ISP0_SDA -> + CFG_DISABLED, // 97 : ISP0_SCL -> + CFG_DISABLED, // 98 : DISP_TE -> + CFG_DISABLED, // 99 : DISP_VSYNC -> + CFG_IN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 100 : REQUEST_DFU1 -> REQUEST_DFU1 + CFG_IN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 101 : REQUEST_DFU2 -> REQUEST_DFU2 + CFG_IN | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 102 : FORCE_DFU -> FORCE_DFU + CFG_DISABLED, // 103 : SWD_TMS2 -> + +/* Port 13 */ + CFG_DISABLED, // 104 : SWD_TMS3 -> + CFG_DISABLED, // 105 : CLK32K_OUT -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 14 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 15 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED, // 128 : MON[0] -> + CFG_DISABLED, // 129 : MON[1] -> + CFG_DISABLED, // 130 : MON[2] -> + CFG_DISABLED, // 131 : MON[3] -> + CFG_DISABLED, // 132 : MON[4] -> + CFG_DISABLED, // 133 : MON[5] -> + CFG_DISABLED, // 134 : MON[6] -> + CFG_DISABLED, // 135 : MON[7] -> + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW, // 136 : DFU_STATUS -> DFU_STATUS + CFG_DISABLED, // 137 : DROOP_N -> + CFG_DISABLED, // 138 : TST_CLKOUT -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_I2S1_MCK -> + CFG_DISABLED, // 1 : AOP_I2S0_MCK -> + CFG_DISABLED, // 2 : AOP_PDM_CLK -> + CFG_DISABLED, // 3 : AOP_PDM_DAT -> + CFG_DISABLED, // 4 : AOP_PLED[0] -> + CFG_DISABLED, // 5 : AOP_PLED[1] -> + CFG_FUNC0 | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 6 : AOP_DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW, // 7 : AOP_DOCK_ATTENTION -> + +/* Port 1 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : AOP_PLED[2] -> + CFG_DISABLED, // 33 : AOP_PLED[3] -> + CFG_DISABLED, // 34 : AOP_PLED[4] -> + CFG_DISABLED, // 35 : AOP_PLED[5] -> + CFG_DISABLED, // 36 : AOP_PLED[6] -> + CFG_DISABLED, // 37 : AOP_PLED[7] -> + CFG_DISABLED, // 38 : AOP_MON[0] -> + CFG_DISABLED, // 39 : AOP_MON[1] -> + +/* Port 5 */ + CFG_DISABLED, // 40 : AOP_MON[2] -> + CFG_DISABLED, // 41 : AOP_MON[3] -> + CFG_DISABLED, // 42 : AOP_MON[4] -> + CFG_DISABLED, // 43 : AOP_MON[5] -> + CFG_DISABLED, // 44 : AOP_MON[6] -> + CFG_DISABLED, // 45 : AOP_MON[7] -> + CFG_DISABLED, // 46 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 47 : AOP_SWD_TMS0 -> + +/* Port 6 */ + CFG_DISABLED, // 48 : AOP_SWD_TMS1 -> + CFG_DISABLED, // 49 : AOP_UART0_TXD -> + CFG_DISABLED, // 50 : AOP_UART0_RXD -> + CFG_DISABLED, // 51 : AOP_UART0_RTSN -> + CFG_DISABLED, // 52 : AOP_UART0_CTSN -> + CFG_DISABLED, // 53 : AOP_UART1_TXD -> + CFG_DISABLED, // 54 : AOP_UART1_RXD -> + CFG_DISABLED, // 55 : AOP_UART1_RTSN -> + +/* Port 7 */ + CFG_DISABLED, // 56 : AOP_UART1_CTSN -> + CFG_DISABLED, // 57 : AOP_UART2_TXD -> + CFG_DISABLED, // 58 : AOP_UART2_RXD -> + CFG_DISABLED, // 59 : AOP_SPI_CS_TRIG[0] -> + CFG_DISABLED, // 60 : AOP_SPI_CS_TRIG[1] -> + CFG_DISABLED, // 61 : AOP_SPI_CS_TRIG[2] -> + CFG_DISABLED, // 62 : AOP_SPI_CS_TRIG[3] -> + CFG_DISABLED, // 63 : AOP_SPI_CS_TRIG[4] -> + +/* Port 8 */ + CFG_DISABLED, // 64 : AOP_SPI_CS_TRIG[5] -> + CFG_DISABLED, // 65 : AOP_SPI_CS_TRIG[6] -> + CFG_DISABLED, // 66 : AOP_SPI_CS_TRIG[7] -> + CFG_DISABLED, // 67 : AOP_SPI_CS_TRIG[8] -> + CFG_DISABLED, // 68 : AOP_SPI_CS_TRIG[9] -> + CFG_DISABLED, // 69 : AOP_SPI_CS_TRIG[10] -> + CFG_DISABLED, // 70 : AOP_SPI_CS_TRIG[11] -> + CFG_DISABLED, // 71 : AOP_SPI_CS_TRIG[12] -> + +/* Port 9 */ + CFG_DISABLED, // 72 : AOP_SPI_CS_TRIG[13] -> + CFG_DISABLED, // 73 : AOP_SPI_CS_TRIG[14] -> + CFG_DISABLED, // 74 : AOP_SPI_CS_TRIG[15] -> + CFG_DISABLED, // 75 : AOP_I2C0_SDA -> + CFG_DISABLED, // 76 : AOP_I2C0_SCL -> + CFG_DISABLED, // 77 : AOP_I2C1_SDA -> + CFG_DISABLED, // 78 : AOP_I2C1_SCL -> + CFG_DISABLED, // 79 : AOP_SPI0_SCLK -> + +/* Port 10 */ + CFG_DISABLED, // 80 : AOP_SPI0_MOSI -> + CFG_DISABLED, // 81 : AOP_SPI0_MISO -> + CFG_DISABLED, // 82 : AOP_PSPI_CS_TRIG[3] -> + CFG_DISABLED, // 83 : AOP_PSPI_CS_TRIG[4] -> + CFG_DISABLED, // 84 : AOP_PSPI_SCLK -> + CFG_DISABLED, // 85 : AOP_PSPI_MOSI -> + CFG_DISABLED, // 86 : AOP_PSPI_MISO -> + CFG_DISABLED, // 87 : AOP_LSPI_SCLK -> + +/* Port 11 */ + CFG_DISABLED, // 88 : AOP_LSPI_MOSI -> + CFG_DISABLED, // 89 : AOP_LSPI_MISO -> + CFG_DISABLED, // 90 : AOP_DETECT[0] -> + CFG_DISABLED, // 91 : AOP_DETECT[1] -> + CFG_DISABLED, // 92 : AOP_PSENSE_CTRL[4] -> + CFG_DISABLED, // 93 : AOP_PSENSE_CTRL[5] -> + CFG_DISABLED, // 94 : AOP_PSENSE_CTRL[6] -> + CFG_DISABLED, // 95 : AOP_PSENSE_CTRL[7] -> +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 0, { pinconfig_0, pinconfig_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/watch2/pinconfig_product.c b/target/watch2/pinconfig_product.c new file mode 100644 index 0000000..5aaa15f --- /dev/null +++ b/target/watch2/pinconfig_product.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2009-2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include + +#define PIN_CFG_AP 1 +#include +#undef PIN_CFG_AP + +#define PIN_CFG_DEV 1 +#include +#undef PIN_CFG_DEV + +extern const uint32_t* target_get_proto2a_gpio_cfg(uint32_t gpioc); +extern const uint32_t* target_get_proto2b_gpio_cfg(uint32_t gpioc); +extern const uint32_t* target_get_evt_gpio_cfg(uint32_t gpioc); + +static bool board_rev_determined; +static bool use_dummy_pinconfig; + +const uint32_t *target_get_default_gpio_cfg(uint32_t gpioc) +{ + // HACK: -- the first call into target_get_default_gpio_cfg() reads + // and attempts to restore BOARD_REV[3:0] to GPIO_CFG_DEFAULT. + // + // This will result in a recursive call back into target_get_default_gpio_cfg. + // To break the recursion, while determining board rev we can reply with any pinconfig + // since it's only being used for BOARD_REV[3:0] and it's CFG_DISABLED in all pinconfigs + // + // Remove this after we no longer have BOARD_REV-dependent pinconfigs. + if (use_dummy_pinconfig) + { + return gpio_default_cfg_ap; + } + if (!board_rev_determined) + { + use_dummy_pinconfig = true; + (void)ipod6_get_board_rev(); + use_dummy_pinconfig = false; + + board_rev_determined = true; + } + + if (ipod6_get_board_rev() == BOARD_REV_PROTON /* BOARD_REV_DEV4 == BOARD_REV_PROTON == 0xF */) + { + // ProtoN and Dev3 share a GPIO spreadsheet. Fortunately they both have the same BOARD_REV + switch (gpioc) + { + case 0: + if (target_config_ap()) + return gpio_default_cfg_ap; + else + return gpio_default_cfg_dev; + break; + case 1: + if (target_config_ap()) + return gpio_1_default_cfg_ap; + else + return gpio_1_default_cfg_dev; + break; + default: + panic("unknown gpio controller"); + } + } else if (target_config_dev()) { + // Dev boards 0xE through 0xA are currently all based off the proto2b Dev config, per + // Board Rev tracker and email clarification from HW EE + // + if (ipod6_get_board_rev() >= 0xA) + return target_get_proto2b_gpio_cfg(gpioc); + else + panic("Unknown BOARD_REV 0x%x", ipod6_get_board_rev()); + } else { + // All that remains are post-ProtoN AP products. + // The story gets more complicated here -- see Board Rev tracker spreadsheet + switch (ipod6_get_board_rev()) + { + case BOARD_REV_PROTO2A: + return target_get_proto2a_gpio_cfg(gpioc); + break; + + case BOARD_REV_PROTO2B: + case BOARD_REV_PROTO2X_CARDINAL: + case BOARD_REV_PROTO2B_ALT_CARBON: + case BOARD_REV_PROTO2D: + case BOARD_REV_PROTO2F: + return target_get_proto2b_gpio_cfg(gpioc); + break; + case BOARD_REV_EVT: + case BOARD_REV_EVT_ALT_CARBON: + return target_get_evt_gpio_cfg(gpioc); + break; + default: + panic("Unknown board revision 0x%x", ipod6_get_board_rev()); + } + } + +} diff --git a/target/watch2/pinconfig_proto2a.c b/target/watch2/pinconfig_proto2a.c new file mode 100644 index 0000000..ac68c92 --- /dev/null +++ b/target/watch2/pinconfig_proto2a.c @@ -0,0 +1,566 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.3.0 + I/O Spreadsheet tracker: None + Conversion command: csvtopinconfig.py --soc m7 --prefix proto2a +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_proto2a_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 46 : GPIO[14] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_IN, // 72 : GPIO[17] -> GPIO_SEAJAY_CLOAK_EN + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2a_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_DISABLED, // 17 : SPU_GPIO[5] -> NC_SPU_GPIO5 + CFG_OUT_0 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2a_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 46 : GPIO[14] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_IN, // 72 : GPIO[17] -> GPIO_SEAJAY_CLOAK_EN + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2a_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED, // 3 : UNSPECIFIED -> UNSPECIFIED + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_DISABLED, // 17 : SPU_GPIO[5] -> NC_SPU_GPIO5 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_proto2a_ap_0, pinconfig_proto2a_ap_1 } }, + { 1, 1, { pinconfig_proto2a_dev_0, pinconfig_proto2a_dev_1 } }, +}; + +const uint32_t * target_get_proto2a_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/watch2/pinconfig_proto2b.c b/target/watch2/pinconfig_proto2b.c new file mode 100644 index 0000000..07d6c32 --- /dev/null +++ b/target/watch2/pinconfig_proto2b.c @@ -0,0 +1,566 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: rev 0.3.6 + I/O Spreadsheet tracker: 15171729 + Conversion command: csvtopinconfig.py --soc m7 --radar 15171729 --prefix proto2b +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_proto2b_ap_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> TP_AP_GPIO17 + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2b_ap_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | INPUT_SCHMITT, // 3 : CLK32K_IN -> GPIO_PMU_TO_SPU_CLK32K_IN + CFG_OUT_0 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2b_dev_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : I2S0_MCK -> GPIO_AP_TO_BERMUDA_CLK_XTAL1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 1 : I2S1_MCK -> I2S1_AP_TO_CODEC_MCLK_12M + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 2 : SD_CLKOUT -> SDIO_AP_TO_WLAN_CLK + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 3 : SD_CMD_IO -> SDIO_AP_BI_WLAN_CMD + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 4 : SD_DATA_IO[0] -> SDIO_AP_BI_WLAN_DATA0 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 5 : SD_DATA_IO[1] -> SDIO_AP_BI_WLAN_DATA1 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 6 : SD_DATA_IO[2] -> SDIO_AP_BI_WLAN_DATA2 + CFG_FUNC0 | PULL_UP | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 7 : SD_DATA_IO[3] -> SDIO_AP_BI_WLAN_DATA3 + +/* Port 1 */ + CFG_FUNC0 | INPUT_SCHMITT, // 8 : SDIO_IRQ -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 9 : WL_HOST_WAKE -> GPIO_WLAN_TO_AP_IRQ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : GPIO[0] -> NC_AP_GPIO0 + CFG_DISABLED, // 33 : GPIO[1] -> NC_AP_GPIO1 + CFG_DISABLED, // 34 : GPIO[2] -> GPIO_BOOT_CONFIG_0 + CFG_DISABLED, // 35 : GPIO[3] -> PP1V8_SW3C_SNS + CFG_DISABLED, // 36 : GPIO[4] -> NC_GPIO_BOOT_CONFIG_2 + CFG_DISABLED, // 37 : GPIO[5] -> NC_GPIO_BOOT_CONFIG_3 + CFG_DISABLED, // 38 : GPIO[6] -> GPIO_BOARD_ID_3 + CFG_DISABLED, // 39 : GPIO[7] -> GPIO_BOARD_REV_0 + +/* Port 5 */ + CFG_DISABLED, // 40 : GPIO[8] -> GPIO_BOARD_REV_1 + CFG_DISABLED, // 41 : GPIO[9] -> GPIO_BOARD_REV_2 + CFG_DISABLED, // 42 : GPIO[10] -> GPIO_BOARD_REV_3 + CFG_DISABLED, // 43 : GPIO[11] -> NC_GPIO_DEV_BOOST_ALT_ID + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 44 : GPIO[12] -> GPIO_AP_TO_BT_DEVICE_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 45 : GPIO[13] -> GPIO_CODEC_TO_AP_IRQ_L + CFG_DISABLED, // 46 : GPIO[14] -> NC_AP_GPIO14 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 47 : GPIO[15] -> GPIO_AP_TO_BERMUDA_FW_DWLD_REQ + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : I2C1_SDA -> I2C1_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : I2C1_SCL -> I2C1_AP_1V8_SCL + CFG_DISABLED, // 50 : I2S0_LRCK -> NC_I2S0_LRCLK + CFG_DISABLED, // 51 : I2S0_BCLK -> NC_I2S0_BCLK + CFG_DISABLED, // 52 : I2S0_DOUT -> NC_I2S0_DOUT + CFG_DISABLED, // 53 : I2S0_DIN -> NC_I2S0_DIN + CFG_FUNC0, // 54 : I2S1_LRCK -> I2S1_CODEC_TO_AP_WCLK + CFG_FUNC0, // 55 : I2S1_BCLK -> I2S1_CODEC_TO_AP_BCLK + +/* Port 7 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 56 : I2S1_DOUT -> I2S1_AP_TO_CODEC_DATA + CFG_FUNC0, // 57 : I2S1_DIN -> I2S1_CODEC_TO_AP_DATA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 58 : UART1_TXD -> UART1_AP_TO_BT_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 59 : UART1_RXD -> UART1_BT_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 60 : UART1_RTSN -> UART1_AP_TO_BT_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 61 : UART1_CTSN -> UART1_BT_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 62 : UART2_TXD -> UART2_AP_TO_BERMUDA_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 63 : UART2_RXD -> UART2_BERMUDA_TO_AP_RXD + +/* Port 8 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 64 : UART2_RTSN -> UART2_AP_TO_BERMUDA_RTS_L + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 65 : UART2_CTSN -> UART2_BERMUDA_TO_AP_CTS_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 66 : UART4_TXD -> UART4_AP_TO_WLAN_TXD + CFG_FUNC0 | PULL_UP | INPUT_SCHMITT, // 67 : UART4_RXD -> UART4_WLAN_TO_AP_RXD + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 68 : UART3_RTXD -> UART3_AP_BI_GG_SWI + CFG_DISABLED, // 69 : CLK32K_OUT -> NC_CLK32K_OUT + CFG_DISABLED, // 70 : TST_CLKOUT -> AP_TST_CLKOUT + CFG_DISABLED, // 71 : GPIO[16] -> NC_AP_GPIO16 + +/* Port 9 */ + CFG_DISABLED, // 72 : GPIO[17] -> TP_AP_GPIO17 + CFG_DISABLED, // 73 : GPIO[18] -> GPIO_GRAPE_SWDCLK + CFG_DISABLED, // 74 : TMR32_PWM1 -> NC_TMR32_PWM1 + CFG_DISABLED, // 75 : TMR32_PWM2 -> NC_TMR32_PWM2 + CFG_FUNC0, // 76 : TMR32_PWM0 -> PMU_VDD_OK + CFG_FUNC0, // 77 : DISP_TE -> DISP_BSYNC + CFG_DISABLED, // 78 : GPIO[19] -> GPIO_GRAPE_SWDIO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 79 : NAND_CEN[0] -> ANC_AP_TO_NAND_CEN<0> + +/* Port 10 */ + CFG_DISABLED, // 80 : NAND_CEN[1] -> NC_NAND_CEN1 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 81 : NAND_IO[7] -> ANC_AP_BI_NAND_IO<7> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 82 : NAND_IO[6] -> ANC_AP_BI_NAND_IO<6> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 83 : NAND_IO[5] -> ANC_AP_BI_NAND_IO<5> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 84 : NAND_IO[4] -> ANC_AP_BI_NAND_IO<4> + CFG_DISABLED, // 85 : NAND_DQS -> NC_NAND_DQS + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 86 : NAND_REN -> ANC_AP_TO_NAND_RE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 87 : NAND_IO[3] -> ANC_AP_BI_NAND_IO<3> + +/* Port 11 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 88 : NAND_IO[2] -> ANC_AP_BI_NAND_IO<2> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 89 : NAND_IO[1] -> ANC_AP_BI_NAND_IO<1> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 90 : NAND_IO[0] -> ANC_AP_BI_NAND_IO<0> + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 91 : NAND_WEN -> ANC_AP_TO_NAND_WE_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 92 : NAND_CLE -> ANC_AP_TO_NAND_CLE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 93 : NAND_ALE -> ANC_AP_TO_NAND_ALE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 94 : I2C0_SDA -> I2C0_AP_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 95 : I2C0_SCL -> I2C0_AP_1V8_SCL + +/* Port 12 */ + CFG_DISABLED, // 96 : DISP_VSYNC -> NC_DISP_VSYNC + CFG_DISABLED, // 97 : SPI0_SCLK -> NC_GPIO_BOARD_ID_0 + CFG_DISABLED, // 98 : SPI0_MOSI -> GPIO_BOARD_ID_1 + CFG_DISABLED, // 99 : SPI0_MISO -> GPIO_BOARD_ID_2 + CFG_DISABLED, // 100 : SPI0_SSIN -> NC_SPI0_MCK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 101 : UART0_TXD -> UART0_TXD + CFG_FUNC0 | PULL_DOWN | INPUT_SCHMITT, // 102 : UART0_RXD -> UART0_RXD + CFG_DISABLED, // 103 : SPI1_SCLK -> NC_SPI1_SCLK + +/* Port 13 */ + CFG_DISABLED, // 104 : SPI1_MOSI -> NC_SPI1_MOSI + CFG_DISABLED, // 105 : SPI1_MISO -> NC_SPI1_MISO + CFG_DISABLED, // 106 : SPI1_SSIN -> NC_SPI1_SSIN + CFG_DISABLED, // 107 : GPIO[20] -> NC_AP_GPIO20 + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 108 : GPIO[21] -> GPIO_AP_TO_WLAN_DEVICE_WAKE + CFG_IN | INPUT_SCHMITT, // 109 : GPIO[22] -> GPIO_TRISTAR_INT + CFG_DISABLED, // 110 : GPIO[23] -> GPIO_AP_TO_OPAL_LVBOOST_BUSY_L + CFG_IN, // 111 : GPIO[24] -> GPIO_OPAL_SWDIO + +/* Port 14 */ + CFG_IN, // 112 : GPIO[25] -> GPIO_OPAL_SWDCLK + CFG_DISABLED, // 113 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 114 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 115 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 116 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 117 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 118 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 119 : UNSPECIFIED -> UNSPECIFIED + +/* Port 15 */ + CFG_DISABLED, // 120 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 121 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 122 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 123 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 124 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 125 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 126 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 127 : UNSPECIFIED -> UNSPECIFIED + +/* Port 16 */ + CFG_DISABLED, // 128 : ENET_MDC -> NC_ENET_MDC + CFG_DISABLED, // 129 : ENET_MDIO -> NC_ENET_MDIO + CFG_DISABLED, // 130 : RMII_RXER -> GPIO_AP_TO_ORB_DEBUG + CFG_DISABLED, // 131 : RMII_TXEN -> NC_RMII_TXEN + CFG_DISABLED, // 132 : RMII_CLK -> NC_GPIO_DEV_DISPLAY_TO_AP_ID3 + CFG_DISABLED, // 133 : RMII_TXD[0] -> NC_RMII_TXD0 + CFG_DISABLED, // 134 : RMII_TXD[1] -> NC_FPGA_WL_REG_ON + CFG_DISABLED, // 135 : RMII_RXD[0] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID1 + +/* Port 17 */ + CFG_DISABLED, // 136 : RMII_RXD[1] -> NC_GPIO_DEV_DISPLAY_TO_AP_ID2 + CFG_DISABLED, // 137 : RMII_CRSDV -> NC_GPIO_DEV_DISPLAY_TO_AP_ID0 + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_proto2b_dev_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_IN | INPUT_SCHMITT, // 0 : REQUEST_DFU1 -> BUTTON1_BUFF_L + CFG_IN | INPUT_SCHMITT, // 1 : REQUEST_DFU2 -> LISA_BTN_BUFF_L + CFG_FUNC0 | INPUT_SCHMITT, // 2 : DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | INPUT_SCHMITT, // 3 : CLK32K_IN -> GPIO_PMU_TO_SPU_CLK32K_IN + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 4 : SPU_UART0_TXD -> GPIO_SPU_TO_WLAN_CONTEXT_B + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 5 : SPU_UART0_RXD -> GPIO_SPU_TO_WLAN_CONTEXT_A + CFG_DISABLED, // 6 : SPU_UART0_RTSN -> NC_SPU_UART0_RTSN + CFG_DISABLED, // 7 : SPU_UART0_CTSN -> NC_SPU_UART0_CTSN + +/* Port 1 */ + CFG_DISABLED, // 8 : SPU_UART1_TXD -> NC_SPU_UART1_TXD + CFG_DISABLED, // 9 : SPU_UART1_RXD -> NC_SPU_UART1_RXD + CFG_DISABLED, // 10 : SPU_UART1_RTSN -> NC_SPU_UART1_RTSN + CFG_DISABLED, // 11 : SPU_UART1_CTSN -> NC_SPU_UART1_CTSN + CFG_DISABLED, // 12 : SPU_GPIO[0] -> NC_SPU_GPIO0 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 13 : SPU_GPIO[1] -> GPIO_WLAN_TO_SPU_HOST_WAKE_SDIO_IRQ + CFG_IN | INPUT_SCHMITT, // 14 : SPU_GPIO[2] -> GPIO_BT_TO_SPU_HOST_WAKE + CFG_IN | PULL_UP | INPUT_SCHMITT, // 15 : SPU_GPIO[3] -> GPIO_SUNFISH_TO_SPU_INT_L + +/* Port 2 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 16 : SPU_GPIO[4] -> GPIO_PMU_TO_SPU_IRQ_L + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 17 : SPU_GPIO[5] -> GPIO_AP_TO_SEAJAY_RESET + CFG_OUT_0 | DRIVE_X2 | SLOW_SLEW, // 18 : SPU_GPIO[6] -> GPIO_SPU_TO_LVBOOST_EN + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 19 : SPU_GPIO[7] -> GPIO_BERMUDA_TO_SPU_HOST_WAKE + CFG_DISABLED, // 20 : SPU_GPIO[8] -> NC_SPU_GPIO8 + CFG_OUT_0, // 21 : DFU_STATUS -> TP_DFU_STATUS + CFG_IN | PULL_DOWN, // 22 : FORCE_DFU -> TP_FORCE_DFU + CFG_FUNC0 | INPUT_SCHMITT, // 23 : PWR_GOOD -> PMU_TO_SPU_PWR_GOOD + +/* Port 3 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 24 : SOC_VDD_HI_LO -> SPU_TO_PMU_VDD_HI_LO + CFG_DISABLED, // 25 : UNSPECIFIED -> UNSPECIFIED + CFG_DISABLED, // 26 : DOCK_ATTENTION -> NC_DOCK_ATTENTION + CFG_DISABLED, // 27 : PMU_HOST_WAKE -> NC_PMU_HOST_WAKE + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 28 : SPU_SPI_SCLK -> SPI_SPU_SCLK + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 29 : SPU_SPI_MOSI -> SPI_SPU_MOSI + CFG_FUNC0 | PULL_DOWN, // 30 : SPU_SPI_MISO -> SPI_SPU_MISO + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 31 : SPU_SPI_CS_TRIG[0] -> SCM_SPU_TO_GRAPE_CS_L + +/* Port 4 */ + CFG_IN | PULL_UP | INPUT_SCHMITT, // 32 : SPU_SPI_CS_TRIG[1] -> SCM_GRAPE_TO_SPU_HINT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 33 : SPU_SPI_CS_TRIG[2] -> SCM_OSMIUM_TO_SPU_INT_L + CFG_IN | PULL_UP | INPUT_SCHMITT, // 34 : SPU_SPI_CS_TRIG[3] -> SCM_LISA_TO_SPU_INT_L + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 35 : SPU_SPI_CS_TRIG[4] -> SCM_SPU_TO_CARBON_CS_L + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 36 : SPU_SPI_CS_TRIG[5] -> SCM_CARBON_TO_SPU_INT1 + CFG_IN | PULL_DOWN | INPUT_SCHMITT, // 37 : SPU_SPI_CS_TRIG[6] -> SCM_CARBON_TO_SPU_INT2 + CFG_DISABLED, // 38 : SPU_SPI_CS_TRIG[7] -> NC_SCM_SPU_TO_COMPASS_CS_L + CFG_DISABLED, // 39 : SPU_SPI_CS_TRIG[8] -> NC_SCM_COMPASS_TO_SPU_INT + +/* Port 5 */ + CFG_DISABLED, // 40 : SPU_SPI_CS_TRIG[9] -> NC_SPU_SPI_CS_TRIG9 + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW, // 41 : SPU_SPI_CS_TRIG[10] -> SCM_SPU_TO_OPAL_CS_L + CFG_DISABLED, // 42 : SPU_SPI_CS_TRIG[11] -> NC_SPU_SPI_CS_TRIG11 + CFG_IN | PULL_UP | INPUT_SCHMITT, // 43 : SPU_SPI_CS_TRIG[12] -> SCM_PT_TO_SPU_INT_L + CFG_DISABLED, // 44 : SPU_SPI_CS_TRIG[13] -> NC_SPU_SPI_CS_TRIG13 + CFG_DISABLED, // 45 : SPU_SPI_CS_TRIG[14] -> NC_SPU_SPI_CS_TRIG14 + CFG_DISABLED, // 46 : SPU_SPI_CS_TRIG[15] -> NC_SPU_SPI_CS_TRIG15 + CFG_IN | PULL_UP, // 47 : SPU_GPIO[9] -> GPIO_SEAJAY_TO_SPU_PING_DET_L + +/* Port 6 */ + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 48 : SPU_I2C_SDA -> I2C_SPU_1V8_SDA + CFG_FUNC0 | DRIVE_X2 | SLOW_SLEW | INPUT_SCHMITT, // 49 : SPU_I2C_SCL -> I2C_SPU_1V8_SCL + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 1, { pinconfig_proto2b_ap_0, pinconfig_proto2b_ap_1 } }, + { 1, 1, { pinconfig_proto2b_dev_0, pinconfig_proto2b_dev_1 } }, +}; + +const uint32_t * target_get_proto2b_gpio_cfg(int gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/watch2/pinconfig_sim.c b/target/watch2/pinconfig_sim.c new file mode 100644 index 0000000..5c768f4 --- /dev/null +++ b/target/watch2/pinconfig_sim.c @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT! + I/O Spreadsheet version: m8 io list. version 148 + I/O Spreadsheet tracker: 20260553 + Conversion command: csvtopinconfig.py --rom --soc m8 --config-column 'SecureROM config' --pupd-column PU/PD --copyright 2015 --radar 20260553 --netname-column 'ROM Config' +*/ + +#include +#include +#include +#include +#include + +static const uint32_t pinconfig_0[GPIO_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : GPIO[0] -> + CFG_DISABLED, // 1 : GPIO[1] -> + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 2 : GPIO[2] -> Boot_config[0] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 3 : GPIO[3] -> Boot_config[1] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 4 : GPIO[4] -> Boot_config[2] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 5 : GPIO[5] -> Boot_config[3] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 6 : GPIO[6] -> Board_ID[3] + CFG_DISABLED, // 7 : GPIO[7] -> + +/* Port 1 */ + CFG_DISABLED, // 8 : GPIO[8] -> + CFG_DISABLED, // 9 : GPIO[9] -> + CFG_DISABLED, // 10 : GPIO[10] -> + CFG_DISABLED, // 11 : GPIO[11] -> + CFG_DISABLED, // 12 : GPIO[12] -> + CFG_DISABLED, // 13 : GPIO[13] -> + CFG_DISABLED, // 14 : GPIO[14] -> + CFG_DISABLED, // 15 : GPIO[15] -> + +/* Port 2 */ + CFG_DISABLED, // 16 : GPIO[16] -> + CFG_DISABLED, // 17 : GPIO[17] -> + CFG_DISABLED, // 18 : TMR32_PWM1 -> + CFG_DISABLED, // 19 : TMR32_PWM2 -> + CFG_DISABLED, // 20 : TMR32_PWM0 -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 21 : NAND_CEN[0] -> + CFG_DISABLED | DRIVE_S4 | SLOW_SLEW, // 22 : NAND_CEN[1] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 23 : NAND_IO[7] -> + +/* Port 3 */ + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 24 : NAND_IO[6] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 25 : NAND_IO[5] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 26 : NAND_IO[4] -> + CFG_DISABLED | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 27 : NAND_REN -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 28 : NAND_IO[3] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 29 : NAND_IO[2] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 30 : NAND_IO[1] -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW | INPUT_SCHMITT, // 31 : NAND_IO[0] -> + +/* Port 4 */ + CFG_DISABLED | PULL_UP | DRIVE_S4 | SLOW_SLEW, // 32 : NAND_WEN -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 33 : NAND_CLE -> + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | SLOW_SLEW, // 34 : NAND_ALE -> + CFG_DISABLED, // 35 : I2S0_LRCK -> + CFG_DISABLED, // 36 : I2S0_BCLK -> + CFG_DISABLED, // 37 : I2S0_DOUT -> + CFG_DISABLED, // 38 : I2S0_DIN -> + CFG_DISABLED, // 39 : I2S1_LRCK -> + +/* Port 5 */ + CFG_DISABLED, // 40 : I2S1_BCLK -> + CFG_DISABLED, // 41 : I2S1_DOUT -> + CFG_DISABLED, // 42 : I2S1_DIN -> + CFG_DISABLED, // 43 : I2S2_LRCK -> + CFG_DISABLED, // 44 : I2S2_BCLK -> + CFG_DISABLED, // 45 : I2S2_DOUT -> + CFG_DISABLED, // 46 : I2S2_DIN -> + CFG_DISABLED, // 47 : SD_CLKOUT -> + +/* Port 6 */ + CFG_DISABLED, // 48 : sDIO_IRQ -> + CFG_DISABLED, // 49 : SD_DATA_IO[0] -> + CFG_DISABLED, // 50 : SD_DATA_IO[1] -> + CFG_DISABLED, // 51 : SD_DATA_IO[2] -> + CFG_DISABLED, // 52 : SD_DATA_IO[3] -> + CFG_DISABLED, // 53 : SDIO_IRQ -> + CFG_DISABLED, // 54 : WL_HOST_WAKE -> + CFG_DISABLED, // 55 : ENET_MDC -> + +/* Port 7 */ + CFG_DISABLED, // 56 : ENET_MDIO -> + CFG_DISABLED, // 57 : RMII_RXER -> + CFG_DISABLED, // 58 : RMII_TXEN -> + CFG_DISABLED, // 59 : RMII_CLK -> + CFG_DISABLED, // 60 : RMII_TXD[0] -> + CFG_DISABLED, // 61 : RMII_TXD[1] -> + CFG_DISABLED, // 62 : RMII_RXD[0] -> + CFG_DISABLED, // 63 : RMII_RXD[1] -> + +/* Port 8 */ + CFG_DISABLED, // 64 : RMII_CRSDV -> + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 65 : SPI0_SCLK -> SPI0_SCLK/Board_ID[0] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 66 : SPI0_MOSI -> SPI0_MOSI/Board_ID[1] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 67 : SPI0_MISO -> SPI0_MISO/Board_ID[2] + CFG_DISABLED | DRIVE_S4 | VERY_FAST_SLEW, // 68 : SPI0_SSIN -> SPI0_CS + CFG_DISABLED, // 69 : SPI1_SCLK -> + CFG_DISABLED, // 70 : SPI1_MOSI -> + CFG_DISABLED, // 71 : SPI1_MISO -> + +/* Port 9 */ + CFG_DISABLED, // 72 : SPI1_SSIN -> + CFG_DISABLED, // 73 : I2C0_SDA -> + CFG_DISABLED, // 74 : I2C0_SCL -> + CFG_DISABLED, // 75 : I2C1_SDA -> + CFG_DISABLED, // 76 : I2C1_SCL -> + CFG_DISABLED, // 77 : I2C2_0_SDA -> + CFG_DISABLED, // 78 : I2C2_0_SCL -> + CFG_DISABLED, // 79 : I2C2_1_SDA -> + +/* Port 10 */ + CFG_DISABLED, // 80 : I2C2_1_SCL -> + CFG_DISABLED, // 81 : UART0_TXD -> + CFG_DISABLED, // 82 : UART0_RXD -> + CFG_DISABLED, // 83 : UART3_RTXD -> + CFG_DISABLED, // 84 : UART4_TXD -> + CFG_DISABLED, // 85 : UART4_RXD -> + CFG_DISABLED, // 86 : UART5_TXD -> + CFG_DISABLED, // 87 : UART5_RXD -> + +/* Port 11 */ + CFG_DISABLED, // 88 : UART2_TXD -> + CFG_DISABLED, // 89 : UART2_RXD -> + CFG_DISABLED, // 90 : UART2_RTSN -> + CFG_DISABLED, // 91 : UART2_CTSN -> + CFG_DISABLED, // 92 : UART1_TXD -> + CFG_DISABLED, // 93 : UART1_RXD -> + CFG_DISABLED, // 94 : UART1_RTSN -> + CFG_DISABLED, // 95 : UART1_CTSN -> + +/* Port 12 */ + CFG_DISABLED, // 96 : ISP0_SDA -> + CFG_DISABLED, // 97 : ISP0_SCL -> + CFG_DISABLED, // 98 : DISP_TE -> + CFG_DISABLED, // 99 : DISP_VSYNC -> + CFG_IN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 100 : REQUEST_DFU1 -> REQUEST_DFU1 + CFG_IN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 101 : REQUEST_DFU2 -> REQUEST_DFU2 + CFG_IN | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 102 : FORCE_DFU -> FORCE_DFU + CFG_DISABLED, // 103 : SWD_TMS2 -> + +/* Port 13 */ + CFG_DISABLED, // 104 : SWD_TMS3 -> + CFG_DISABLED, // 105 : CLK32K_OUT -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 14 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 15 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 16 */ + CFG_DISABLED, // 128 : MON[0] -> + CFG_DISABLED, // 129 : MON[1] -> + CFG_DISABLED, // 130 : MON[2] -> + CFG_DISABLED, // 131 : MON[3] -> + CFG_DISABLED, // 132 : MON[4] -> + CFG_DISABLED, // 133 : MON[5] -> + CFG_DISABLED, // 134 : MON[6] -> + CFG_DISABLED, // 135 : MON[7] -> + +/* Port 17 */ + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW, // 136 : DFU_STATUS -> DFU_STATUS + CFG_DISABLED, // 137 : DROOP_N -> + CFG_DISABLED, // 138 : TST_CLKOUT -> + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, +}; + +static const uint32_t pinconfig_1[GPIO_1_GROUP_COUNT * GPIOPADPINS] = { + +/* Port 0 */ + CFG_DISABLED, // 0 : AOP_I2S1_MCK -> + CFG_DISABLED, // 1 : AOP_I2S0_MCK -> + CFG_DISABLED, // 2 : AOP_PDM_CLK -> + CFG_DISABLED, // 3 : AOP_PDM_DAT -> + CFG_DISABLED, // 4 : AOP_PLED[0] -> + CFG_DISABLED, // 5 : AOP_PLED[1] -> + CFG_FUNC0 | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW | INPUT_SCHMITT, // 6 : AOP_DOCK_CONNECT -> DOCK_CONNECT + CFG_DISABLED | PULL_DOWN | DRIVE_S4 | VERY_FAST_SLEW, // 7 : AOP_DOCK_ATTENTION -> + +/* Port 1 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 2 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 3 */ + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + CFG_DISABLED, + +/* Port 4 */ + CFG_DISABLED, // 32 : AOP_PLED[2] -> + CFG_DISABLED, // 33 : AOP_PLED[3] -> + CFG_DISABLED, // 34 : AOP_PLED[4] -> + CFG_DISABLED, // 35 : AOP_PLED[5] -> + CFG_DISABLED, // 36 : AOP_PLED[6] -> + CFG_DISABLED, // 37 : AOP_PLED[7] -> + CFG_DISABLED, // 38 : AOP_MON[0] -> + CFG_DISABLED, // 39 : AOP_MON[1] -> + +/* Port 5 */ + CFG_DISABLED, // 40 : AOP_MON[2] -> + CFG_DISABLED, // 41 : AOP_MON[3] -> + CFG_DISABLED, // 42 : AOP_MON[4] -> + CFG_DISABLED, // 43 : AOP_MON[5] -> + CFG_DISABLED, // 44 : AOP_MON[6] -> + CFG_DISABLED, // 45 : AOP_MON[7] -> + CFG_DISABLED, // 46 : AOP_SWD_TCK_OUT -> + CFG_DISABLED, // 47 : AOP_SWD_TMS0 -> + +/* Port 6 */ + CFG_DISABLED, // 48 : AOP_SWD_TMS1 -> + CFG_DISABLED, // 49 : AOP_UART0_TXD -> + CFG_DISABLED, // 50 : AOP_UART0_RXD -> + CFG_DISABLED, // 51 : AOP_UART0_RTSN -> + CFG_DISABLED, // 52 : AOP_UART0_CTSN -> + CFG_DISABLED, // 53 : AOP_UART1_TXD -> + CFG_DISABLED, // 54 : AOP_UART1_RXD -> + CFG_DISABLED, // 55 : AOP_UART1_RTSN -> + +/* Port 7 */ + CFG_DISABLED, // 56 : AOP_UART1_CTSN -> + CFG_DISABLED, // 57 : AOP_UART2_TXD -> + CFG_DISABLED, // 58 : AOP_UART2_RXD -> + CFG_DISABLED, // 59 : AOP_SPI_CS_TRIG[0] -> + CFG_DISABLED, // 60 : AOP_SPI_CS_TRIG[1] -> + CFG_DISABLED, // 61 : AOP_SPI_CS_TRIG[2] -> + CFG_DISABLED, // 62 : AOP_SPI_CS_TRIG[3] -> + CFG_DISABLED, // 63 : AOP_SPI_CS_TRIG[4] -> + +/* Port 8 */ + CFG_DISABLED, // 64 : AOP_SPI_CS_TRIG[5] -> + CFG_DISABLED, // 65 : AOP_SPI_CS_TRIG[6] -> + CFG_DISABLED, // 66 : AOP_SPI_CS_TRIG[7] -> + CFG_DISABLED, // 67 : AOP_SPI_CS_TRIG[8] -> + CFG_DISABLED, // 68 : AOP_SPI_CS_TRIG[9] -> + CFG_DISABLED, // 69 : AOP_SPI_CS_TRIG[10] -> + CFG_DISABLED, // 70 : AOP_SPI_CS_TRIG[11] -> + CFG_DISABLED, // 71 : AOP_SPI_CS_TRIG[12] -> + +/* Port 9 */ + CFG_DISABLED, // 72 : AOP_SPI_CS_TRIG[13] -> + CFG_DISABLED, // 73 : AOP_SPI_CS_TRIG[14] -> + CFG_DISABLED, // 74 : AOP_SPI_CS_TRIG[15] -> + CFG_DISABLED, // 75 : AOP_I2C0_SDA -> + CFG_DISABLED, // 76 : AOP_I2C0_SCL -> + CFG_DISABLED, // 77 : AOP_I2C1_SDA -> + CFG_DISABLED, // 78 : AOP_I2C1_SCL -> + CFG_DISABLED, // 79 : AOP_SPI0_SCLK -> + +/* Port 10 */ + CFG_DISABLED, // 80 : AOP_SPI0_MOSI -> + CFG_DISABLED, // 81 : AOP_SPI0_MISO -> + CFG_DISABLED, // 82 : AOP_PSPI_CS_TRIG[3] -> + CFG_DISABLED, // 83 : AOP_PSPI_CS_TRIG[4] -> + CFG_DISABLED, // 84 : AOP_PSPI_SCLK -> + CFG_DISABLED, // 85 : AOP_PSPI_MOSI -> + CFG_DISABLED, // 86 : AOP_PSPI_MISO -> + CFG_DISABLED, // 87 : AOP_LSPI_SCLK -> + +/* Port 11 */ + CFG_DISABLED, // 88 : AOP_LSPI_MOSI -> + CFG_DISABLED, // 89 : AOP_LSPI_MISO -> + CFG_DISABLED, // 90 : AOP_DETECT[0] -> + CFG_DISABLED, // 91 : AOP_DETECT[1] -> + CFG_DISABLED, // 92 : AOP_PSENSE_CTRL[4] -> + CFG_DISABLED, // 93 : AOP_PSENSE_CTRL[5] -> + CFG_DISABLED, // 94 : AOP_PSENSE_CTRL[6] -> + CFG_DISABLED, // 95 : AOP_PSENSE_CTRL[7] -> +}; + +struct pinconfig_map { + uint32_t board_id; + uint32_t board_id_mask; + const uint32_t *pinconfigs[GPIOC_COUNT]; +}; + +static const struct pinconfig_map cfg_map[] = { + { 0, 0, { pinconfig_0, pinconfig_1 } }, +}; + +const uint32_t * target_get_default_gpio_cfg(uint32_t gpioc) +{ + static const struct pinconfig_map *selected_map = NULL; + + if (selected_map == NULL) { + uint32_t board_id = platform_get_board_id(); + for (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) { + if ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) { + selected_map = &cfg_map[i]; + break; + } + } + + if (selected_map == NULL) + panic("no default pinconfig for board id %u", board_id); + } + + ASSERT(gpioc < GPIOC_COUNT); + return selected_map->pinconfigs[gpioc]; +} diff --git a/target/watch2/rules.mk b/target/watch2/rules.mk new file mode 100644 index 0000000..586ec5f --- /dev/null +++ b/target/watch2/rules.mk @@ -0,0 +1,77 @@ +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# +LOCAL_DIR := $(GET_LOCAL_DIR) +TARGET_DIR := $(LOCAL_DIR) + +OPTIONS += \ + DIALOG_D2238=1 \ + TARGET_BOOT_CPU_VOLTAGE=CHIPID_CPU_VOLTAGE_MED \ + TARGET_BOOT_RAM_VOLTAGE=0 \ + TARGET_BOOT_SOC_VOLTAGE=0 \ + TARGET_PMU_DEV_ID=0x78 \ + DCS_NUM_CHANNELS=1 \ + DCS_NUM_RANKS=1 \ + TARGET_DSIM_DPHYCTL=0x00003000 \ + TARGET_DSIM_CONFIG=0x00400000 \ + TARGET_DSIM_UP_CODE=0x1 \ + TARGET_DSIM_DOWN_CODE=0x1 \ + TARGET_DSIM_SUPPRESS=0x1 \ + WITH_TARGET_CHARGETRAP=1 \ + WITH_DALI=1 \ + WIFI_DTPATH=\"arm-io/sdio\" \ + BT_DTPATH=\"arm-io/uart1/bluetooth\" \ + MULTITOUCH_DTPATH=\"arm-io/multi-touch\" + +ifeq ($(CONFIG_SIM),true) + OPTIONS += \ + CONFIG_SIM=1 \ + AMP_CALIBRATION_SKIP=1 +endif + +ifeq ($(CONFIG_FPGA),true) + OPTIONS += \ + CONFIG_FPGA=1 \ + DISPLAY_FPGA_TUNABLES=1 \ + SUPPORT_FPGA=1 \ + AMP_CALIBRATION_SKIP=1 \ + DCS_FIXUP_PARAMS=1 \ + DCS_RUN_AT_50MHZ=1 +endif + +ifeq ($(NO_WFI),true) +OPTIONS += \ + NO_ARM_HALT=1 +endif + +ifeq ($(RECOVERY_MODE_IBSS),true) +OPTIONS += \ + WITH_RECOVERY_MODE_IBSS=1 +endif + +GLOBAL_INCLUDES += $(LOCAL_DIR)/include + +ALL_OBJS += $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/target_prepare_dali.o + +ifeq ($(CONFIG_SIM),true) + ALL_OBJS += $(LOCAL_DIR)/init_sim.o \ + $(LOCAL_DIR)/pinconfig_sim.o +else + ifeq ($(CONFIG_FPGA),true) + ALL_OBJS += $(LOCAL_DIR)/init_fpga.o \ + $(LOCAL_DIR)/pinconfig_fpga.o + else + ALL_OBJS += $(LOCAL_DIR)/init_product.o \ + $(LOCAL_DIR)/pinconfig_product.o \ + $(LOCAL_DIR)/pinconfig_proto2a.o \ + $(LOCAL_DIR)/pinconfig_proto2b.o \ + $(LOCAL_DIR)/pinconfig_evt.o + endif +endif diff --git a/target/watch2/target_prepare_dali.c b/target/watch2/target_prepare_dali.c new file mode 100644 index 0000000..1ac202d --- /dev/null +++ b/target/watch2/target_prepare_dali.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + kRTKitArgBlockVersion1 = 'RTK1', + kDaliFWArgVersion1 = 'DAL1', + kDaliFWArgVersion2 = 'DAL2' +}; + + +enum +{ + kMode24hEnabledOffset = 0, + kRotateScreenOffset = 1, + kDaliDarkWakeOffset = 2, /* 0 = normal wake, 1 = scheduled thermal wake, don't paint screen */ + kPmuDebugOffset = 3 +}; + +typedef struct dali_payload_t { + uint32_t magic; /* = kDaliFWArgVersion2 */ + uint32_t reserved; + uint8_t charFlags[8]; + int64_t utcOffset; + + DMin_t dmin; +} dali_payload_t; + +typedef struct dali_args_t { + uint32_t magic; /* = kRTKitArgBlockVersion1 */ + uint32_t size; /* size of pending payload */ + dali_payload_t payload; +} dali_args_t; + +void* +target_prepare_dali(void) +{ +#if defined(PMU_LDO_OPAL) && WITH_HW_POWER + // Interim Solution: Turn off LDO8 in Dali mode/iBoot + // Opal uses a lot of power when held in reset. For sure we don't need it in Dali. + power_enable_ldo(PMU_LDO_OPAL, false); +#endif +#ifdef GPIO_SPU_TO_OPAL_CS_L + gpio_configure(GPIO_SPU_TO_OPAL_CS_L, GPIO_CFG_IN); +#endif + dali_args_t* args = (dali_args_t *)PANIC_BASE; + bzero(args, sizeof(dali_args_t)); + + args->magic = kRTKitArgBlockVersion1; + args->size = sizeof(dali_payload_t); + + args->payload.magic = kDaliFWArgVersion2; + args->payload.charFlags[kMode24hEnabledOffset] = (env_get_uint("dali-24h-mode", 0) == 1); + args->payload.charFlags[kRotateScreenOffset] = (env_get_uint("display-rotation", 0) == 1); + args->payload.charFlags[kPmuDebugOffset] = (env_get_uint("dali-pmu-debug", 0) == 1); + + syscfgCopyDataForTag('DMin', (uint8_t*)&(args->payload.dmin), sizeof(DMin_t)); + + const char* utcOffsetStr = env_get("utc-offset"); + if (utcOffsetStr) { + args->payload.utcOffset = atoi(utcOffsetStr); + } + + return args; +} diff --git a/tests/fuzz-main.c b/tests/fuzz-main.c new file mode 100644 index 0000000..7b856eb --- /dev/null +++ b/tests/fuzz-main.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +// The module under test defines the fuzz main function which we call with +// the filename of the fuzzer input +extern int fuzz_main(const char *filename); + + +int main(int argc, char *argv[]) +{ + if (argc < 2) + return -1; + + return fuzz_main(argv[1]); +} + +// Need a mock panic function because the module under test doesn't expect panic() to return +void _panic(const char *function, const char *str, ...) +{ + va_list ap; + + printf("panic: %s: ", function); + + va_start(ap, str); + vprintf(str, ap); + va_end(ap); + + exit(1); +} + +// And we need a mock test assert fail in case the module under test uses any of +// the modules from tests/mocks that make test assertions +void test_assert_fail(const char *file, const char *func, unsigned line, const char *fmt, ...) +{ + va_list ap; + + printf("%s:%s:%u: assertion failed: ", file, func, line); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + + exit(1); +} diff --git a/tests/include/linux-support.h b/tests/include/linux-support.h new file mode 100644 index 0000000..90aefa4 --- /dev/null +++ b/tests/include/linux-support.h @@ -0,0 +1,19 @@ +/* +* Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef IBOOT_LINUX_H +#define IBOOT_LINUX_H + +#include + +size_t strlcpy(char * restrict dst, const char * restrict src, size_t size); +size_t strlcat(char * restrict dst, const char * restrict src, size_t size); + +#endif diff --git a/tests/include/mock_syscfg.h b/tests/include/mock_syscfg.h new file mode 100644 index 0000000..e3d72a2 --- /dev/null +++ b/tests/include/mock_syscfg.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2014-2015 Apple Computer, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef MOCK_SYSCFG_H +#define MOCK_SYSCFG_H + +#include + +void mock_syscfg_add(uint32_t tag, void *data, uint32_t size); +void mock_syscfg_reset(void); + +#endif diff --git a/tests/include/non-posix.h b/tests/include/non-posix.h new file mode 100644 index 0000000..a403dba --- /dev/null +++ b/tests/include/non-posix.h @@ -0,0 +1,19 @@ +/* +* Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#ifndef IBOOT_NON_POSIX_H +#define IBOOT_NON_POSIX_H + +#include + +size_t strlcpy(char * restrict dst, const char * restrict src, size_t size); +size_t strlcat(char * restrict dst, const char * restrict src, size_t size); + +#endif diff --git a/tests/include/unittest.h b/tests/include/unittest.h new file mode 100644 index 0000000..286ab3d --- /dev/null +++ b/tests/include/unittest.h @@ -0,0 +1,228 @@ +#ifndef UNITTEST_H +#define UNITTEST_H + +#include +#include +#include +#include +#include + +// Used for logging progress during tests +#define TEST_SILENT (0) +#define TEST_FAILURE (10) +#define TEST_INFO (20) +#define TEST_SPEW (30) +void tprintf(int verbosity, const char *fmt, ...) __printflike(2, 3); + +typedef void (*test_case_func_t)(uintptr_t); +typedef void (*test_suite_setup_func_t)(void); +typedef void (*test_suite_cleanup_func_t)(void); + +struct test_case { + const char *name; + test_case_func_t function; + uintptr_t context; + const char *description; +}; + +struct test_suite { + const char *name; + const char *description; + test_suite_setup_func_t setup_function; + test_suite_cleanup_func_t cleanup_function; + struct test_case test_cases[]; +}; + +#define TEST_CASE_LAST \ + { NULL, NULL, 0, NULL } + +#define TEST_SUITE(_suite) LINKER_SET_ENTRY(unit_test_suite, _suite) + +#define TEST_SETUP_HOOK(_func) LINKER_SET_ENTRY(test_setup_hooks, _func) + +// constructs a literal array that can be passed into the assert macros +#define TEST_ARRAY(type, params...) &(const type[]){params} + +// generates the appropriate printf format string for _val's type +#define _FMT(_val) \ + _Generic(_val, \ + bool: "%u", \ + unsigned char: "%u", \ + const unsigned char: "%u", \ + signed char: "%d", \ + const signed char: "%d", \ + unsigned short: "%u", \ + const unsigned short: "%u", \ + signed short: "%d", \ + const signed short: "%d", \ + unsigned int: "%u", \ + const unsigned int: "%u", \ + signed int: "%d", \ + const signed int: "%d", \ + unsigned long: "%lu", \ + const unsigned long: "%lu", \ + signed long: "%ld", \ + const signed long: "%ld", \ + unsigned long long: "%llu", \ + const unsigned long long: "%llu", \ + signed long long: "%llu", \ + const signed long long: "%llu" \ + ) + +#define TEST_ASSERT(_a) \ + do { \ + if (!(_a)) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "%s", #_a); \ + } \ + } while (0) + +// For equality testing, we just coerce everything to uint64_t to avoid spurious +// comparison of signed and unsigned errors; we don't do this for > and friends +// because that would change the sense of the comparison +#define TEST_ASSERT_REL_EQ(_a, _rel, _b) \ + do { \ + typeof(_a) _val_a = (_a); \ + typeof(_b) _val_b = (_b); \ + uint64_t _unsigned_a = (uint64_t)_val_a; \ + uint64_t _unsigned_b = (uint64_t)_val_b; \ + if (!(_unsigned_a _rel _unsigned_b)) { \ + char _str_a[40], _str_b[40]; \ + snprintf(_str_a, sizeof(_str_a), _FMT(_a), _val_a); \ + snprintf(_str_b, sizeof(_str_b), _FMT(_b), _val_b); \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"%s %s %s\" (%s %s %s)", \ + #_a, #_rel, #_b, _str_a, #_rel, _str_b); \ + } \ + } while(0) + +#define TEST_ASSERT_EQ(_a, _b) TEST_ASSERT_REL_EQ(_a, ==, _b) +#define TEST_ASSERT_NEQ(_a, _b) TEST_ASSERT_REL_EQ(_a, !=, _b) + +#define TEST_ASSERT_REL(_a, _rel, _b) \ + do { \ + typeof(_a) _val_a = (_a); \ + typeof(_b) _val_b = (_b); \ + if (!(_val_a _rel _val_b)) { \ + char _str_a[40], _str_b[40]; \ + snprintf(_str_a, sizeof(_str_a), _FMT(_a), _val_a); \ + snprintf(_str_b, sizeof(_str_b), _FMT(_b), _val_b); \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"%s %s %s\" (%s %s %s)", \ + #_a, #_rel, #_b, _str_a, #_rel, _str_b); \ + } \ + } while(0) + +#define TEST_ASSERT_GT(_a, _b) TEST_ASSERT_REL(_a, >, _b) +#define TEST_ASSERT_GTE(_a, _b) TEST_ASSERT_REL(_a, >=, _b) +#define TEST_ASSERT_LT(_a, _b) TEST_ASSERT_REL(_a, <, _b) +#define TEST_ASSERT_LTE(_a, _b) TEST_ASSERT_REL(_a, <=, _b) + +#define TEST_ASSERT_PTR_EQ(_a, _b) \ + do { \ + const void *_val_a = (_a); \ + const void *_val_b = (_b); \ + if (!(_val_a == _val_b)) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"%s == %s\" (%p == %p)", \ + #_a, #_b, _val_a, _val_b); \ + } \ + } while(0) + +#define TEST_ASSERT_PTR_NEQ(_a, _b) \ + do { \ + const void *_val_a = (_a); \ + const void *_val_b = (_b); \ + if (!(_val_a != _val_b)) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"%s != %s\" (%p == %p)", \ + #_a, #_b, _val_a, _val_b); \ + } \ + } while(0) + +#define TEST_ASSERT_STR_EQ(_a, _b) \ + do { \ + const char *_val_a = (_a); \ + const char *_val_b = (_b); \ + if (_val_a == NULL || _val_b == NULL || strcmp(_val_a, _val_b) != 0) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"strcmp(%s, %s) == 0\" (strcmp(\"%s\", \"%s\"))", \ + #_a, #_b, _val_a, _val_b); \ + } \ + } while (0) + + +#define TEST_ASSERT_STR_NEQ(_a, _b) \ + do { \ + const char *_val_a = (_a); \ + const char *_val_b = (_b); \ + if (strcmp(_val_a, _val_b) == 0) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"strcmp(%s, %s) != 0\" (!strcmp(%s, %s))", \ + #_a, #_b, _val_a, _val_b); \ + } \ + } while (0) + + +#define TEST_ASSERT_MEM_EQ(_a, _b, _size) \ + do { \ + const uint8_t *_val_a = (const uint8_t *)(_a); \ + const uint8_t *_val_b = (const uint8_t *)(_b); \ + unsigned long long _val_size = (_size); \ + unsigned long long _i; \ + for (_i = 0; _i < _val_size; _i++) { \ + if (_val_a[_i] != _val_b[_i]) \ + break; \ + } \ + if (_i != _val_size) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"memcmp(%s, %s, %llu) == 0\" " \ + "(differs at byte %llu, 0x%02x vs 0x%02x)", \ + #_a, #_b, _val_size, _i, _val_a[_i], _val_b[_i]); \ + } \ + } while (0) + + +#define TEST_ASSERT_MEM_NEQ(_a, _b, _size) \ + do { \ + const void *_val_a = (const uint8_t *)(_a); \ + const void *_val_b = (const uint8_t *)(_b); \ + unsigned long long _val_size = (_size); \ + if (memcmp(_val_a, _val_b, _val_size) == 0) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"memcmp(%s, %s, %llu) != 0\"", \ + #_a, #_b, _val_size); \ + } \ + } while (0) + +#define TEST_ASSERT_NOT_NULL(_a) \ + do { \ + const void *_val = (const void *)_a; \ + if (!(_val != NULL)) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"%s != NULL\" (%p == NULL)", #_a, _val); \ + } \ + } while (0) + +#define TEST_ASSERT_NULL(_a) \ + do { \ + const void *_val = (const void *)_a; \ + if (!(_val == NULL)) { \ + test_assert_fail(__FILE__, __FUNCTION__, __LINE__, \ + "\"%s == NULL\" (%p == NULL)", #_a, _val); \ + } \ + } while (0) + + +#define TEST_EXPECT_PANIC() test_expect_panic(__FILE__, __FUNCTION__, __LINE__) + +#define TEST_EXPECT_PANICKED() test_expect_panicked(__FILE__, __FUNCTION__, __LINE__) + +#define TEST_FAIL(args...) test_assert_fail(__FILE__, __FUNCTION__, __LINE__, args) + +// helper functions for the assertion macros above; don't call directly +void test_assert_fail(const char *file, const char *func, unsigned line, const char *fmt, ...) __noreturn; +void test_expect_panic(const char *file, const char *func, unsigned line); +void test_expect_panicked(const char *file, const char *func, unsigned line) __noreturn; + +#endif diff --git a/tests/mocks/blockdev.c b/tests/mocks/blockdev.c new file mode 100644 index 0000000..454b279 --- /dev/null +++ b/tests/mocks/blockdev.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +struct mock_blockdev { + struct blockdev bdev; + + /* local data */ + FILE *backing; +}; + +static int mock_blockdev_read_block(struct blockdev *bdev, void *ptr, block_addr block, uint32_t count) +{ + struct mock_blockdev *mdev = (struct mock_blockdev *)bdev; + int result; + +#if !NO_MOCK_ASSERTS + // no overflow + TEST_ASSERT_GTE(block + count, block); + + // buffer must be properly aligned + TEST_ASSERT_EQ((uintptr_t)ptr & (bdev->alignment - 1), 0); + + TEST_ASSERT_GT(count, 0u); + TEST_ASSERT_LT(block, mdev->bdev.block_count); + TEST_ASSERT_LTE(block + count, mdev->bdev.block_count); +#endif + + result = fseek(mdev->backing, block << mdev->bdev.block_shift, SEEK_SET); +#if !NO_MOCK_ASSERTS + TEST_ASSERT_EQ(result, 0); +#endif + result = fread(ptr, 1 << mdev->bdev.block_shift, count, mdev->backing); +#if !NO_MOCK_ASSERTS + TEST_ASSERT_EQ(result, count); +#endif + + return count; +} + +struct blockdev *create_mock_blockdev(const char *name, const char *filename, uint32_t block_size) +{ + struct mock_blockdev *mdev; + struct stat st; + FILE *f; + int result; + + result = stat(filename, &st); + TEST_ASSERT_EQ(result, 0); + + f = fopen(filename, "r"); + TEST_ASSERT_NOT_NULL(f); + + mdev = malloc(sizeof(struct mock_blockdev)); + + construct_blockdev(&mdev->bdev, name, st.st_size, block_size); + mdev->backing = f; + mdev->bdev.read_block_hook = &mock_blockdev_read_block; + + return &mdev->bdev; +} diff --git a/tests/mocks/sys/lock.c b/tests/mocks/sys/lock.c new file mode 100644 index 0000000..e343452 --- /dev/null +++ b/tests/mocks/sys/lock.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include + +static int irq_disable_count; + +#if DEBUG_CRITICAL_SECTIONS +void _enter_critical_section(const char *from) +{ +#else +void enter_critical_section(void) +{ +#endif + irq_disable_count++; +} + +#if DEBUG_CRITICAL_SECTIONS +void _exit_critical_section(const char *from) +{ +#else +void exit_critical_section(void) +{ +#endif + TEST_ASSERT_GT(irq_disable_count, 0); + irq_disable_count--; +} + +void reset_critical_section(void) +{ + irq_disable_count = 0; +} + +TEST_SETUP_HOOK(reset_critical_section); diff --git a/tests/mocks/sys/security.c b/tests/mocks/sys/security.c new file mode 100644 index 0000000..22c5ffc --- /dev/null +++ b/tests/mocks/sys/security.c @@ -0,0 +1,13 @@ +#include +#include +#include + +bool security_allow_memory(const void *address, size_t length) +{ + return true; +} + +bool security_allow_modes(uint32_t modes) +{ + return true; +} diff --git a/tests/mocks/syscfg.c b/tests/mocks/syscfg.c new file mode 100644 index 0000000..895103c --- /dev/null +++ b/tests/mocks/syscfg.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +struct mock_syscfg_value { + struct list_node list_node; + + struct syscfgMemEntry entry; +}; + +struct list_node mock_syscfg_list = LIST_INITIAL_VALUE(mock_syscfg_list); + +void mock_syscfg_add(uint32_t tag, void *data, uint32_t size) +{ + struct mock_syscfg_value *new_value; + + new_value = calloc(1, sizeof(*new_value)); + new_value->entry.seTag = tag; + new_value->entry.seDataSize = size; + // store the pointer itself in the array for inline data... dirty but it works + memcpy(new_value->entry.seData, &data, sizeof(data)); + + list_add_tail(&mock_syscfg_list, &new_value->list_node); +} + +void mock_syscfg_reset(void) +{ + struct mock_syscfg_value *value; + + while ((value = list_remove_tail_type(&mock_syscfg_list, struct mock_syscfg_value, list_node)) != NULL) { + free(value); + } +} + +bool syscfgFindByTag(uint32_t tag, struct syscfgMemEntry *entry) +{ + struct mock_syscfg_value *value; + + list_for_every_entry(&mock_syscfg_list, value, struct mock_syscfg_value, list_node) { + if (value->entry.seTag == tag) { + memcpy(entry, &value->entry, sizeof(*entry)); + return true; + } + } + + return false; +} + +void *syscfgGetData(struct syscfgMemEntry *entry) +{ + void *ptr; + + memcpy(&ptr, entry->seData, sizeof(ptr)); + + return ptr; +} + +uint32_t syscfgGetSize(struct syscfgMemEntry *entry) +{ + return entry->seDataSize; +} + +bool +syscfg_find_tag(uint32_t tag, void **data_out, uint32_t *size_out) +{ + static struct syscfgMemEntry result; + + if (syscfgFindByTag(tag, &result)) { + if (data_out) { + *data_out = syscfgGetData(&result); + } + if (size_out) { + *size_out = syscfgGetSize(&result); + } + + return true; + } else { + return false; + } +} diff --git a/tests/non-posix.c b/tests/non-posix.c new file mode 100644 index 0000000..ee76100 --- /dev/null +++ b/tests/non-posix.c @@ -0,0 +1,44 @@ +/* +* Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include + +size_t strlcpy(char * restrict dst, const char * restrict src, size_t s) +{ + size_t i= 0; + + if(!s) { + return strlen(src); + } + + for(i= 0; ((i< s-1) && src[i]); i++) { + dst[i]= src[i]; + } + + dst[i]= 0; + + return i + strlen(src+i); +} + +size_t strlcat(char * restrict dst, const char * restrict src, size_t maxlen) +{ + const size_t srclen = strlen(src); + const size_t dstlen = strnlen(dst, maxlen); + if (dstlen == maxlen) return maxlen+srclen; + if (srclen < maxlen-dstlen) { + memcpy(dst+dstlen, src, srclen+1); + } else { + memcpy(dst+dstlen, src, maxlen-dstlen-1); + dst[maxlen-1] = '\0'; + } + return dstlen + srclen; +} diff --git a/tests/unittest-main.c b/tests/unittest-main.c new file mode 100644 index 0000000..3621a16 --- /dev/null +++ b/tests/unittest-main.c @@ -0,0 +1,759 @@ +/* +* Copyright (C) 2014 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#if UNITTEST_UNITTESTS +#include +#endif + +#define DEFAULT_VERBOSITY (TEST_FAILURE) + +static void test_unwind(void) __attribute__((noreturn)); + +struct test_context { + bool assertion_failed; + const char *assertion_file; + const char *assertion_function; + unsigned assertion_line; + + bool expect_panic; + const char *expect_panic_file; + const char *expect_panic_function; + unsigned expect_panic_line; + + bool panic_occurred; + const char *panic_function; + const char *panic_string; + + jmp_buf jmp_env; + + // nested contexts allow testing of the test functions + struct test_context *outer_context; + int depth; +}; + +static struct test_context *current_context; + +int tprintf_verbosity; + +static bool run_test_case(struct test_suite *suite, struct test_case *test_case, int verbosity) { + void **cursor; + bool test_result; + + struct test_context test_context; + + // Set up a context for handling of panics and assertion failures + memset(&test_context, 0, sizeof(test_context)); + test_context.outer_context = current_context; + if (current_context != NULL) + test_context.depth = current_context->depth + 1; + current_context = &test_context; + + // call any setup hooks that got registered, intended to be used + // by mocks so that test suites don't need to worry about any + // setup the mocks may need + LINKER_SET_FOREACH(cursor, test_setup_hooks) { + void (*setup_hook)(void); + setup_hook = *cursor; + + setup_hook(); + } + + if (suite->setup_function != NULL) + suite->setup_function(); + + if (setjmp(test_context.jmp_env) == 0) { + test_case->function(test_case->context); + + if (test_context.expect_panic) { + // we should never return from a test that expected to panic; + // those tests should always panic and therefore do an unwind + tprintf(TEST_FAILURE, "!!! test returned without panic expected by %s:%s:%u\n", + current_context->expect_panic_file, current_context->expect_panic_function, + current_context->expect_panic_line); + test_result = false; + } else { + // if the test returned normally (didn't call unwind), it's a pass + test_result = true; + } + } else { + if (!(test_context.expect_panic && test_context.panic_occurred)) { + // if we get here, someone called longjmp, which means the + // test failed because of a panic or assertion failure + test_result = false; + } else { + // There was a panic, but it was required by the test + test_result = true; + } + } + + if (suite->cleanup_function != NULL) { + suite->cleanup_function(); + } + + // pop the context + current_context = current_context->outer_context; + + return test_result; +} + +static bool run_test_suite(struct test_suite *suite, int verbosity) +{ + bool result = true; + struct test_case *test_case; + int old_verbosity = tprintf_verbosity; + + tprintf_verbosity = verbosity; + + tprintf(TEST_INFO, "\n# Begin test suite: %s\n", suite->name); + + for (test_case = &suite->test_cases[0]; test_case->name != NULL; test_case++) { + bool test_result; + tprintf(TEST_INFO, "\n## Begin test case: %s.%s\n", suite->name, test_case->name); + + test_result = run_test_case(suite, test_case, verbosity); + result &= test_result; + + + if (test_result) + tprintf(TEST_INFO, "## PASSED test case: %s.%s\n", suite->name, test_case->name); + else + tprintf(TEST_FAILURE, "## FAILED test case: %s.%s\n", suite->name, test_case->name); + } + + tprintf(TEST_INFO, "# End test suite: %s\n", suite->name); + + tprintf_verbosity = old_verbosity; + + return result; +} + +// Stops the linker from complaining about the setup hook section not being present +// for test binaries that don't have setup hooks +static void dummy_test_setup_hook(void) +{ +} +TEST_SETUP_HOOK(dummy_test_setup_hook); + +#if !UNITTEST_UNITTESTS + +unsigned int verbosity = DEFAULT_VERBOSITY; + +int main(int argc, char *argv[]) +{ + bool result = true; + void **cursor; + struct test_suite *suite; + int opt; + + while ((opt = getopt(argc, argv, "v")) != -1) { + switch (opt) { + case 'v': + verbosity += 10; + } + } + + LINKER_SET_FOREACH(cursor, unit_test_suite) { + suite = *((struct test_suite **)cursor); + bool suite_result; + + suite_result = run_test_suite(suite, verbosity); + + result &= suite_result; + } + + return result ? 0 : -1; +} +#endif + +static void tvprintf(int verbosity, const char *fmt, va_list ap) +{ + if (tprintf_verbosity >= verbosity) { + if (verbosity == TEST_FAILURE) + printf("\x1b[1;31m"); + vprintf(fmt, ap); + if (verbosity == TEST_FAILURE) + printf("\x1b[m"); + } +} + +void tprintf(int verbosity, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + tvprintf(verbosity, fmt, ap); + va_end(ap); +} + +static void test_unwind(void) +{ + longjmp(current_context->jmp_env, 1); +} + +void _panic(const char *function, const char *str, ...) +{ + va_list ap; + bool expected; + char *tag; + int threshold; + + current_context->panic_occurred = true; + current_context->panic_function = function; + current_context->panic_string = str; + + expected = current_context->expect_panic; + + if (expected) { + threshold = TEST_INFO; + tag = "ignored panic"; + } else { + threshold = TEST_FAILURE; + tag = "!!! panic"; + } + + tprintf(threshold, "%s: ", tag); + va_start(ap, str); + tvprintf(threshold, str, ap); + va_end(ap); + tprintf(threshold, "\n"); + + test_unwind(); +} + +void test_assert_fail(const char *file, const char *func, unsigned line, const char *fmt, ...) +{ + va_list ap; + + current_context->assertion_failed = true; + current_context->assertion_file = file; + current_context->assertion_function = func; + current_context->assertion_line = line; + + tprintf(TEST_FAILURE, "!!! %s:%s:%u: assertion failed: ", file, func, line); + va_start(ap, fmt); + tvprintf(TEST_FAILURE, fmt, ap); + va_end(ap); + tprintf(TEST_FAILURE, "\n"); + + test_unwind(); +} + +void test_expect_panic(const char *file, const char *func, unsigned line) +{ + current_context->expect_panic = true; + current_context->expect_panic_file = file; + current_context->expect_panic_function = func; + current_context->expect_panic_line = line; +} + + +void test_expect_panicked(const char *file, const char *func, unsigned line) +{ + tprintf(TEST_FAILURE, "!!! panic expected by %s:%s:%u did not occur\n", + current_context->expect_panic_file, current_context->expect_panic_function, + current_context->expect_panic_line); + + // unwind via longjmp because this function is marked as noreturn + test_unwind(); +} + +// Qui proba probatorem? + +#if UNITTEST_UNITTESTS +static void test_test_success(uintptr_t context) +{ + if (!context) + TEST_FAIL("expected failure"); +} + +static void test_test_assert_mem_eq(uintptr_t context) +{ + switch (context) { + case 0: + TEST_ASSERT_MEM_EQ("a", "b", 0); + TEST_ASSERT_MEM_EQ("a", "a", 1); + TEST_ASSERT_MEM_EQ("a", "a", 2); + TEST_ASSERT_MEM_EQ("\0a", "\0a", 3); + TEST_ASSERT_MEM_EQ("aaaa", "aaab", 3); + TEST_ASSERT_MEM_EQ("\x00\xff\x80", "\x00\xff\x80", 4); + break; + case 1: + TEST_ASSERT_MEM_EQ("a", "b", 1); + break; + case 2: + TEST_ASSERT_MEM_EQ("a", "b", 2); + break; + case 3: + TEST_ASSERT_MEM_EQ("a", "", 1); + break; + default: + TEST_FAIL("invalid context value"); + } +} + +static void test_test_assert_mem_neq(uintptr_t context) +{ + switch (context) { + case 0: + TEST_ASSERT_MEM_NEQ("a", "b", 1); + TEST_ASSERT_MEM_NEQ("a", "b", 2); + TEST_ASSERT_MEM_NEQ("a", "", 1); + break; + case 1: + TEST_ASSERT_MEM_NEQ("a", "b", 0); + break; + case 2: + TEST_ASSERT_MEM_NEQ("a", "a", 1); + break; + case 3: + TEST_ASSERT_MEM_NEQ("a", "a", 2); + break; + case 4: + TEST_ASSERT_MEM_NEQ("\0a", "\0a", 3); + break; + case 5: + TEST_ASSERT_MEM_NEQ("aaaa", "aaab", 3); + break; + case 6: + TEST_ASSERT_MEM_NEQ("\x00\xff\x80", "\x00\xff\x80", 4); + break; + default: + TEST_FAIL("invalid context value"); + } +} + +static void test_test_assert_not_null(uintptr_t context) +{ + TEST_ASSERT_NOT_NULL(context); +} + +static void test_test_assert_null(uintptr_t context) +{ + TEST_ASSERT_NULL(context); +} + +static void test_test_assert_ptr_eq(uintptr_t context) +{ + void *ptr1 = (void *)0x10000000; + void *ptr2 = (void *)0x10000000; + void *ptr3 = (void *)0x10000100; + + switch (context) { + case 0: + TEST_ASSERT_PTR_EQ(ptr1, ptr1); + break; + case 1: + TEST_ASSERT_PTR_EQ(ptr1, ptr2); + break; + case 2: + TEST_ASSERT_PTR_EQ(ptr2, ptr3); + break; + default: + TEST_FAIL("invalid context value"); + } +} + +static void test_test_assert_ptr_neq(uintptr_t context) +{ + void *ptr1 = (void *)0x10000000; + void *ptr2 = (void *)0x10000000; + void *ptr3 = (void *)0x10000100; + + switch (context) { + case 0: + TEST_ASSERT_PTR_NEQ(ptr1, ptr1); + break; + case 1: + TEST_ASSERT_PTR_NEQ(ptr1, ptr2); + break; + case 2: + TEST_ASSERT_PTR_NEQ(ptr2, ptr3); + break; + default: + TEST_FAIL("invalid context value"); + } +} + +static void test_test_assert_str_eq(uintptr_t context) +{ + switch (context) { + case 0: + TEST_ASSERT_STR_EQ("", ""); + TEST_ASSERT_STR_EQ("a", "a"); + TEST_ASSERT_STR_EQ("\0a", "\0b"); + TEST_ASSERT_STR_EQ("\xff\x80\x01", "\xff\x80\x01"); + break; + case 1: + TEST_ASSERT_STR_EQ("aa", "ab"); + break; + case 2: + TEST_ASSERT_STR_EQ("aa", "ba"); + break; + case 3: + TEST_ASSERT_STR_EQ("aa", "a"); + break; + case 4: + TEST_ASSERT_STR_EQ("a", "aa"); + break; + default: + TEST_FAIL("invalid context value"); + } +} + +static void test_test_assert_str_neq(uintptr_t context) +{ + switch (context) { + case 0: + TEST_ASSERT_STR_NEQ("aa", "ab"); + TEST_ASSERT_STR_NEQ("aa", "ba"); + TEST_ASSERT_STR_NEQ("aa", "a"); + TEST_ASSERT_STR_NEQ("a", "aa"); + + break; + case 1: + TEST_ASSERT_STR_NEQ("", ""); + break; + case 2: + TEST_ASSERT_STR_NEQ("a", "a"); + break; + case 3: + TEST_ASSERT_STR_NEQ("\0a", "\0b"); + break; + case 4: + TEST_ASSERT_STR_NEQ("\xff\x80\x01", "\xff\x80\x01"); + break; + default: + TEST_FAIL("invalid context value"); + } +} + +static void test_test_assert_rel_eq(uintptr_t context) +{ + TEST_ASSERT_REL(context, ==, 50u); + + TEST_ASSERT_EQ(context, 50u); +} + +static void test_test_assert_rel_neq(uintptr_t context) +{ + TEST_ASSERT_REL(context, !=, 50u); + + TEST_ASSERT_NEQ(context, 50u); +} + +static void test_test_assert_rel_gt(uintptr_t context) +{ + TEST_ASSERT_REL(context, >, 50u); + TEST_ASSERT_GT(context, 50u); +} + +static void test_test_assert_rel_lt(uintptr_t context) +{ + TEST_ASSERT_REL(context, <, 50u); + TEST_ASSERT_LT(context, 50u); +} + +static void test_test_assert_rel_uint8(uintptr_t context) +{ + TEST_ASSERT_REL((uint8_t)context, ==, (const uint8_t)50); +} + +static void test_test_assert_rel_int8(uintptr_t context) +{ + TEST_ASSERT_REL((int8_t)context, ==, (const int8_t)50); +} + +static void test_test_assert_rel_uint16(uintptr_t context) +{ + TEST_ASSERT_REL((uint16_t)context, ==, (const uint16_t)50); +} + +static void test_test_assert_rel_int16(uintptr_t context) +{ + TEST_ASSERT_REL((int16_t)context, ==, (const int16_t)50); +} + +static void test_test_assert_rel_uint32(uintptr_t context) +{ + TEST_ASSERT_REL((uint32_t)context, ==, (const uint32_t)50); +} + +static void test_test_assert_rel_int32(uintptr_t context) +{ + TEST_ASSERT_REL((int32_t)context, ==, (const int32_t)50); +} + +static void test_test_assert_rel_uint64(uintptr_t context) +{ + TEST_ASSERT_REL((uint64_t)context, ==, (const uint64_t)50); +} + +static void test_test_assert_rel_int64(uintptr_t context) +{ + TEST_ASSERT_REL((int64_t)context, ==, (const int64_t)50); +} + +static void test_test_expect_panic(uintptr_t context) +{ + TEST_EXPECT_PANIC(); + + if (context) { + panic("test panic"); + } + + TEST_EXPECT_PANICKED(); +} + +static void test_test_expect_panic2(uintptr_t context) +{ + TEST_EXPECT_PANIC(); + + if (context) { + panic("test panic"); + } +} + +static void test_test_fail(uintptr_t context) +{ + TEST_FAIL("expected failure"); +} + +static void test_test_panic(uintptr_t context) +{ + if (context) { + panic("test panic"); + } +} + +#define TEST_TEST_CASE(_func, _context, _should_succeed) \ + { #_func "," #_context, _func, _context, _should_succeed } + +struct test_test_case { + const char *name; + test_case_func_t function; + uintptr_t context; + bool should_succeed; +} test_test_cases[] = { + TEST_TEST_CASE(test_test_assert_mem_eq, 0, true), + TEST_TEST_CASE(test_test_assert_mem_eq, 1, false), + TEST_TEST_CASE(test_test_assert_mem_eq, 2, false), + TEST_TEST_CASE(test_test_assert_mem_eq, 3, false), + TEST_TEST_CASE(test_test_assert_mem_neq, 0, true), + TEST_TEST_CASE(test_test_assert_mem_neq, 1, false), + TEST_TEST_CASE(test_test_assert_mem_neq, 2, false), + TEST_TEST_CASE(test_test_assert_mem_neq, 3, false), + TEST_TEST_CASE(test_test_assert_mem_neq, 4, false), + TEST_TEST_CASE(test_test_assert_mem_neq, 5, false), + TEST_TEST_CASE(test_test_assert_mem_neq, 6, false), + + TEST_TEST_CASE(test_test_assert_not_null, 0, false), + TEST_TEST_CASE(test_test_assert_not_null, 1, true), + TEST_TEST_CASE(test_test_assert_null, 0, true), + TEST_TEST_CASE(test_test_assert_null, 1, false), + + TEST_TEST_CASE(test_test_assert_ptr_eq, 0, true), + TEST_TEST_CASE(test_test_assert_ptr_eq, 1, true), + TEST_TEST_CASE(test_test_assert_ptr_eq, 2, false), + TEST_TEST_CASE(test_test_assert_ptr_neq, 0, false), + TEST_TEST_CASE(test_test_assert_ptr_neq, 1, false), + TEST_TEST_CASE(test_test_assert_ptr_neq, 2, true), + + TEST_TEST_CASE(test_test_assert_str_eq, 0, true), + TEST_TEST_CASE(test_test_assert_str_eq, 1, false), + TEST_TEST_CASE(test_test_assert_str_eq, 2, false), + TEST_TEST_CASE(test_test_assert_str_eq, 3, false), + TEST_TEST_CASE(test_test_assert_str_eq, 4, false), + TEST_TEST_CASE(test_test_assert_str_neq, 0, true), + TEST_TEST_CASE(test_test_assert_str_neq, 1, false), + TEST_TEST_CASE(test_test_assert_str_neq, 2, false), + TEST_TEST_CASE(test_test_assert_str_neq, 3, false), + TEST_TEST_CASE(test_test_assert_str_neq, 4, false), + + TEST_TEST_CASE(test_test_assert_rel_eq, 0, false), + TEST_TEST_CASE(test_test_assert_rel_eq, 1, false), + TEST_TEST_CASE(test_test_assert_rel_eq, 50, true), + TEST_TEST_CASE(test_test_assert_rel_eq, 51, false), + TEST_TEST_CASE(test_test_assert_rel_neq, 0, true), + TEST_TEST_CASE(test_test_assert_rel_neq, 1, true), + TEST_TEST_CASE(test_test_assert_rel_neq, 50, false), + TEST_TEST_CASE(test_test_assert_rel_neq, 51, true), + TEST_TEST_CASE(test_test_assert_rel_gt, 0, false), + TEST_TEST_CASE(test_test_assert_rel_gt, 1, false), + TEST_TEST_CASE(test_test_assert_rel_gt, 50, false), + TEST_TEST_CASE(test_test_assert_rel_gt, 51, true), + TEST_TEST_CASE(test_test_assert_rel_lt, 0, true), + TEST_TEST_CASE(test_test_assert_rel_lt, 1, true), + TEST_TEST_CASE(test_test_assert_rel_lt, 50, false), + TEST_TEST_CASE(test_test_assert_rel_lt, 51, false), + TEST_TEST_CASE(test_test_assert_rel_uint8, 50, true), + TEST_TEST_CASE(test_test_assert_rel_uint8, 51, false), + TEST_TEST_CASE(test_test_assert_rel_int8, 50, true), + TEST_TEST_CASE(test_test_assert_rel_int8, 51, false), + TEST_TEST_CASE(test_test_assert_rel_uint16, 50, true), + TEST_TEST_CASE(test_test_assert_rel_uint16, 51, false), + TEST_TEST_CASE(test_test_assert_rel_int16, 50, true), + TEST_TEST_CASE(test_test_assert_rel_int16, 51, false), + TEST_TEST_CASE(test_test_assert_rel_uint32, 50, true), + TEST_TEST_CASE(test_test_assert_rel_uint32, 51, false), + TEST_TEST_CASE(test_test_assert_rel_int32, 50, true), + TEST_TEST_CASE(test_test_assert_rel_int32, 51, false), + TEST_TEST_CASE(test_test_assert_rel_uint64, 50, true), + TEST_TEST_CASE(test_test_assert_rel_int64, 51, false), + + TEST_TEST_CASE(test_test_expect_panic, 0, false), + TEST_TEST_CASE(test_test_expect_panic, 1, true), + TEST_TEST_CASE(test_test_expect_panic2, 0, false), + TEST_TEST_CASE(test_test_expect_panic2, 1, true), + + TEST_TEST_CASE(test_test_fail, 0, false), + + TEST_TEST_CASE(test_test_panic, 0, true), + TEST_TEST_CASE(test_test_panic, 1, false), +}; + +static void run_test_test_case(uintptr_t context) +{ + bool result; + struct test_test_case *test_test_case; + + test_test_case = (struct test_test_case *)context; + + struct test_suite *suite = calloc(sizeof(*suite) + 2 * sizeof(suite->test_cases[0]), 1); + + suite->name = "synth"; + suite->description = "synthesized test case suite"; + suite->setup_function = NULL; + suite->test_cases[0].name = "synth"; + suite->test_cases[0].function = test_test_case->function; + suite->test_cases[0].context = test_test_case->context; + suite->test_cases[0].description = "synthesized test case"; + + result = run_test_suite(suite, TEST_SILENT); + + if (result && !test_test_case->should_succeed) + TEST_FAIL("test passed that should have failed"); + if (!result && test_test_case->should_succeed) + TEST_FAIL("test failed that should have passed"); + // returning from the bottom of a test function indicates success +} + + +static struct test_suite test_test_suite = { + .name = "unittest-simple", + .description = "simple single test suites", + .setup_function = NULL, + .cleanup_function = NULL, + .test_cases = { + TEST_CASE_LAST, + TEST_CASE_LAST, + TEST_CASE_LAST, + } +}; + +// Test the test functions themselves +int main(int argc, char *argv[]) +{ + bool suite_result; + bool result = true; + struct test_suite *suite; + int verbosity = DEFAULT_VERBOSITY; + + // First confirm simple tests work as expected + // We drive these ones manually since we need to prove + // test suites do the expected things before we start + // relying on them for our other tests + + test_test_suite.name = "simple"; + test_test_suite.description = "verifies test results get carried into suites correctly"; + test_test_suite.test_cases[0].function = test_test_success; + test_test_suite.test_cases[0].description = ""; + test_test_suite.test_cases[1].function = test_test_success; + test_test_suite.test_cases[1].description = ""; + + test_test_suite.test_cases[0].name = "success"; + test_test_suite.test_cases[0].context = 1; + test_test_suite.test_cases[1].name = NULL; + suite_result = run_test_suite(&test_test_suite, TEST_SILENT) == true; + + result &= suite_result; + + if (suite_result) + tprintf(TEST_INFO, "## PASSED test case: simple.success\n"); + else + tprintf(TEST_FAILURE, "## !!! FAILED test case: simple.success\n"); + + test_test_suite.test_cases[0].name = "failure"; + test_test_suite.test_cases[0].context = 0; + test_test_suite.test_cases[1].name = NULL; + suite_result = run_test_suite(&test_test_suite, TEST_SILENT) == false; + + result &= suite_result; + + if (suite_result) + tprintf(TEST_INFO, "## PASSED test case: simple.failure\n"); + else + tprintf(TEST_FAILURE, "## !!! FAILED test case: simple.failure\n"); + + test_test_suite.test_cases[0].name = "success"; + test_test_suite.test_cases[0].context = 1; + test_test_suite.test_cases[1].name = "success2"; + test_test_suite.test_cases[1].context = 1; + suite_result = run_test_suite(&test_test_suite, TEST_SILENT) == true; + + result &= suite_result; + + if (suite_result) + tprintf(TEST_INFO, "## PASSED test case: simple.success2\n"); + else + tprintf(TEST_FAILURE, "## !!! FAILED test case: simple.success2\n"); + + test_test_suite.test_cases[0].name = "success"; + test_test_suite.test_cases[0].context = 1; + test_test_suite.test_cases[1].name = "failure"; + test_test_suite.test_cases[1].context = 0; + suite_result = run_test_suite(&test_test_suite, TEST_SILENT) == false; + + result &= suite_result; + + if (suite_result) + tprintf(TEST_INFO, "## PASSED test case: simple.successfailure\n"); + else + tprintf(TEST_FAILURE, "## !!! FAILED test case: simple.successfailure\n"); + + // Now that we've verified that the test suites do the right thing, + // start-running table-driven test suites to test the assertion macros + size_t num_cases = sizeof(test_test_cases) / sizeof(test_test_cases[0]); + + suite = calloc(sizeof(*suite) + sizeof(suite->test_cases[0]) * (num_cases + 1), 1); + + suite->name = "assertions"; + suite->description = "tests the assertion macros"; + + for (size_t i = 0; i < num_cases; i++) { + suite->test_cases[i].name = test_test_cases[i].name; + suite->test_cases[i].function = run_test_test_case; + suite->test_cases[i].context = (uintptr_t)&test_test_cases[i]; + suite->test_cases[i].description = test_test_cases[i].name; + } + + result &= run_test_suite(suite, verbosity); + + return result ? 0 : 1; +} + +#endif diff --git a/tests/unittest-tests.mk b/tests/unittest-tests.mk new file mode 100644 index 0000000..ca7ae01 --- /dev/null +++ b/tests/unittest-tests.mk @@ -0,0 +1,18 @@ +# Copyright (C) 2014 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +TEST_NAME := unittests + +TEST_OBJS := \ + tests/unittest-main.o + +TEST_CFLAGS := -DUNITTEST_UNITTESTS=1 diff --git a/tools/BootX2Bin.cpp b/tools/BootX2Bin.cpp new file mode 100644 index 0000000..d94384f --- /dev/null +++ b/tools/BootX2Bin.cpp @@ -0,0 +1,908 @@ +/* + * Copyright (C) 2009, 2013 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Buffer.h" +#include "DeviceTreePatcher.h" +#include "Kernelcache.h" +#include "LoadMachO.h" + +#include +#include + +#define DEFAULT_SDRAM_BASE 0x00000000 +#define DEFAULT_SDRAM_LEN (256 * 1024 * 1024) +#define TARGET_MMU_BASE_ALIGN 16384 + +#define ARM_B_POS_0x40 0xea00000e // b pc+0x40 +#define ARM_LDR_R0_PC 0xe59f0000 // ldr r0, [pc] (here+8) +#define ARM_LDR_PC_PC 0xe59ff000 // ldr pc, [pc] (here+8) + +#define ARM64_BOARD_SECURITY_EPOCH 0 + +// An arbitrarily sized framebuffer. +#define FRAMEBUFFER_WIDTH 640 +#define FRAMEBUFFER_HEIGHT 960 +#define FRAMEBUFFER_DEPTH_BITS 32 +#define FRAMEBUFFER_STRIDE_BYTES \ + (FRAMEBUFFER_WIDTH * FRAMEBUFFER_DEPTH_BITS / 8) +#define FRAMEBUFFER_SIZE_BYTES \ + (FRAMEBUFFER_STRIDE_BYTES * FRAMEBUFFER_HEIGHT * 3) + +#define PANIC_SIZE 16384 + +#define PACKED __attribute__((packed)) + +#define USE_L4 + +#ifdef USE_L4 +#define MONITOR_SIZE (0x00800000) +#endif + +/* Just to make sure we get the alignment right */ +typedef uint64_t arm64_ptr_t __attribute__((aligned(8))); +typedef uint64_t arm64_uint64_t __attribute__((aligned(8))); + +// lib/macho/boot.h +// This isn't taken verbatim: changed host-varying types to exact width, +// as they would otherwise not work on 64 bit hosts. + +/* + * Video information.. + */ + +#define BOOT_LINE_LENGTH 256 + +struct Boot_Video { + uint32_t v_baseAddr; /* Base address of video memory */ + uint32_t v_display; /* Display Code (if Applicable */ + uint32_t v_rowBytes; /* Number of bytes per pixel row */ + uint32_t v_width; /* Width */ + uint32_t v_height; /* Height */ + uint32_t v_depth; /* Pixel Depth */ +} PACKED; + +struct Boot_Video_64 { + arm64_ptr_t v_baseAddr;/* Base address of video memory */ + arm64_ptr_t v_display; /* Display Code (if Applicable */ + arm64_uint64_t v_rowBytes; /* Number of bytes per pixel row */ + arm64_uint64_t v_width; /* Width */ + arm64_uint64_t v_height; /* Height */ + arm64_uint64_t v_depth; /* Pixel Depth */ +} PACKED; + +/* Boot argument structure - passed into Mach kernel at boot time. + */ +#define kBootArgsRevision 1 +#define kBootArgsVersion1 1 + +struct boot_args { + uint16_t revision; /* Revision of boot_args structure */ + uint16_t version; /* Version of boot_args structure */ + uint32_t virtBase; /* Virtual base of memory */ + uint32_t physBase; /* Physical base of memory */ + uint32_t memSize; /* Size of memory */ + uint32_t topOfKernelData; /* Highest physical address used in kernel data area */ + Boot_Video video; /* Video Information */ + uint32_t machineType; /* Machine Type */ + uint32_t deviceTreeAddr; /* Base of flattened device tree */ + uint32_t deviceTreeLength; /* Length of flattened tree */ + char commandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ +} PACKED; + +typedef struct boot_args_64 { + uint16_t revision; /* Revision of boot_args structure */ + uint16_t version; /* Version of boot_args structure */ + arm64_ptr_t virtBase; /* Virtual base of memory */ + arm64_ptr_t physBase; /* Physical base of memory */ + arm64_uint64_t memSize; /* Size of memory */ + arm64_ptr_t topOfKernelData; /* Highest physical address used in kernel data area */ + Boot_Video_64 video; /* Video Information */ + uint32_t machineType; /* Machine Type */ + arm64_ptr_t deviceTreeAddr; /* Base of flattened device tree */ + uint32_t deviceTreeLength; /* Length of flattened tree */ + char commandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ +} boot_args_64; + +#ifdef USE_L4 +typedef struct monitor_boot_args { + uint64_t version; /* structure version - this is version 1 */ + uint64_t virtBase; /* virtual base of memory assigned to the monitor */ + uint64_t physBase; /* physical address corresponding to the virtual base */ + uint64_t memSize; /* size of memory assigned to the monitor */ + uint64_t kernArgs; /* physical address of the kernel boot_args structure */ + uint64_t kernEntry; /* kernel entrypoint */ +} monitor_boot_args; +#endif + +struct dt_patch_s { + const char *node; + const char *property; + const char *value; + bool str; +}; +typedef struct dt_patch_s dt_patch_t; + +struct Options { + const char *kernelcache_file; + const char *devicetree_file; + const char *ramdisk_file; + const char *output_file; + std::string bootargs_string; + uint64_t sdram_base; + uint32_t sdram_len; + uint64_t virtual_base; + bool override_virtual_base; + bool have_boot_partition_id; + unsigned boot_partition_id; + std::vector dt_patches; + bool page_size_16kb; +#ifdef USE_L4 + const char *l4_path; +#endif + + Options() + : kernelcache_file(NULL), + devicetree_file(NULL), + ramdisk_file(NULL), + output_file(NULL), + bootargs_string(), + sdram_base(DEFAULT_SDRAM_BASE), + sdram_len(DEFAULT_SDRAM_LEN), + virtual_base(0), + override_virtual_base(false), + have_boot_partition_id(false), + boot_partition_id(), + dt_patches(), + page_size_16kb(false), +#ifdef USE_L4 + l4_path(NULL) +#endif + { } + + bool Parse(int argc, char **argv); +}; + +static void Usage(const char *argv0); +static uint64_t RoundToNextPage(const Options &options, uint64_t address); +static uint64_t RoundToNextMmuBase(uint64_t address); +static bool SetFrequenciesInDeviceTree(DeviceTreePatcher *device_tree_patcher); + +int main(int argc, char *argv[]) { + Options options; + if (!options.Parse(argc, argv)) { + Usage(argv[0]); + return 1; + } + + FILE *output_str; + if (!strcmp(options.output_file, "-")) { + // Output to stdout. + output_str = stdout; + } else { + // Output to a file. + output_str = fopen(options.output_file, "wb"); + if (output_str == NULL) { + fprintf(stderr, "Couldn't open output file \"%s\"\n", + options.output_file); + return 1; + } + } + + // Load the kernelcache from an img3 file. + Buffer kernelcache; + if (!kernelcache.loadFromAuto(options.kernelcache_file, + IMAGE_TYPE_KERNELCACHE)) { + fprintf(stderr, "Couldn't load kernel cache %s\n", + options.kernelcache_file); + return 1; + } + + // Decompress the kernel cache to a Mach-O binary. + Buffer macho; + if (!DecompressKernelcache(kernelcache, &macho)) { + fprintf(stderr, "Couldn't decompress kernel cache\n"); + return 1; + } + + // Unpack the Mach-O kernel into the base of 'ram'. + Buffer ram; + ram.alloc(options.sdram_len); + LoadMachO load_macho(macho, &ram); + if (options.override_virtual_base) { + load_macho.OverrideVirtualBase(options.virtual_base); + } + if (!load_macho.Load()) { + fprintf(stderr, "Couldn't unpack Mach-O kernel image\n"); + return 1; + } + uint64_t virtual_base; + if (!load_macho.GetVirtualBase(&virtual_base)) { + fprintf(stderr, "Couldn't infer virtual base of Mach-O kernel image\n"); + return false; + } + uint64_t phys_base = options.sdram_base; + uint64_t image_size = load_macho.LastAddress(); + uint64_t entry_point_phys_offset = load_macho.EntryPointPhysOffset(); + + // Load the device tree from an img3 file. + Buffer devicetree; + if (!devicetree.loadFromAuto(options.devicetree_file, IMAGE_TYPE_DEVTREE)) { + fprintf(stderr, "Couldn't load devicetree %s\n", options.devicetree_file); + return 1; + } + + // Load the ramdisk from an img3 file. + Buffer ramdisk; + if (options.ramdisk_file != NULL && + !ramdisk.loadFromAuto(options.ramdisk_file, IMAGE_TYPE_RAMDISK)) { + fprintf(stderr, "Couldn't load ramdisk %s\n", options.ramdisk_file); + return 1; + } + + fprintf(stderr, + "kernelcache: %u\n" + "macho: %u\n" + "unpacked: %llu\n" + "devicetree: %u\n" + "ramdisk: %u\n", + (unsigned) kernelcache.size(), + (unsigned) macho.size(), + image_size, + (unsigned) devicetree.size(), + (unsigned) ramdisk.size()); + + // Append the device tree to the unpacked Mach-O kernel. + uint64_t devicetree_offset = RoundToNextPage(options, image_size); + if (devicetree_offset + devicetree.size() > ram.size()) { + fprintf(stderr, "Kernel + devicetree too large\n"); + return 1; + } + memcpy((char *) ram.buf() + devicetree_offset, + devicetree.buf(), + devicetree.size()); + + // Append the ramdisk to the device tree. + uint64_t ramdisk_offset = + RoundToNextPage(options, devicetree_offset + devicetree.size()); + memcpy((char *) ram.buf() + ramdisk_offset, ramdisk.buf(), ramdisk.size()); + + // Append bootargs to the device tree. + uint64_t bootargs_offset = + RoundToNextPage(options, ramdisk_offset + ramdisk.size()); + + // Framebuffer at the end of memory, followed by panic ram. + uint64_t framebuffer_offset = + options.sdram_len - PANIC_SIZE - FRAMEBUFFER_SIZE_BYTES; + // Round down to a 1MB segment. MMU table initialization requires this. + framebuffer_offset &= ~((1 << 20) - 1); + + uint64_t end_of_image = 0; + uint64_t end_of_image_offset = 0; + +#ifdef USE_L4 + monitor_boot_args mba; + uint64_t mba_offset; + + if( options.l4_path ) + { + uint64_t monitor_offset = (framebuffer_offset - MONITOR_SIZE) & ~(0x200000ULL - 1); // 2MB-aligned + mba_offset = monitor_offset + MONITOR_SIZE - sizeof(mba); + + mba.version = 1; + mba.virtBase = 0; // L4 doesn't care + mba.physBase = monitor_offset + phys_base; // L4 doesn't care + mba.memSize = MONITOR_SIZE; + mba.kernArgs = bootargs_offset + phys_base; + mba.kernEntry = entry_point_phys_offset + phys_base; + fprintf(stderr, "monitor at %llx\n", monitor_offset); + + end_of_image_offset = + RoundToNextMmuBase(monitor_offset + MONITOR_SIZE); + + Buffer l4; + if (!l4.loadFromAuto(options.l4_path, + IMAGE_TYPE_MONITOR)) { + fprintf(stderr, "Couldn't open monitor image\n"); + return 1; + } + + fprintf(stderr, "Opened monitor image\n"); + LoadMachO load_l4(l4, &ram); + fprintf(stderr, "loaded monitor image\n"); + + // L4 in 16KB mode is just a mini monitor with a different + // link address. + uint64_t l4_link_base = + options.page_size_16kb + ? 0x0000004000000000ULL + : 0x0000004100000000ULL; + load_l4.OverrideVirtualBase(l4_link_base - monitor_offset); + if (options.override_virtual_base) { + fprintf(stderr, "overriding virt base\n"); + load_l4.OverrideVirtualBase(options.virtual_base); + fprintf(stderr, "overrode virt base\n"); + } + fprintf(stderr, "about to load\n"); + if (!load_l4.Load()) { + fprintf(stderr, "Couldn't unpack Mach-O kernel image\n"); + return 1; + } + + /* re-set the entry point now to use L4's */ + entry_point_phys_offset = load_l4.EntryPointPhysOffset(); + fprintf(stderr, "Loaded l4: ept %llx\n", entry_point_phys_offset); + } + else +#endif + end_of_image_offset = + RoundToNextMmuBase(bootargs_offset + sizeof(boot_args)); + + end_of_image = phys_base + end_of_image_offset; + if (end_of_image_offset > framebuffer_offset) { + fprintf(stderr, "Image size runs into framebuffer ram (%llx vs %llx)\n", + end_of_image_offset, framebuffer_offset); + + return 1; + } + + + // Place a bootstrap to load r0 with the offset of the boot args, + // and jump to the entry point. + if (load_macho.Is64Bit()) { + // Don't need to use exception vector to get started on ARM64 + + // [~] $ cat bootstrap.s + // adr x0, Lboot_args_addr + // adr x1, Lentry_addr + // ldr x0, [x0] /* Load boot args address */ + // ldr x1, [x1] /* Load entry point */ + // br x1 /* Jump to entry point */ + // .long 0 /* Padding */ + // Lboot_args_addr: + // .quad 0xfeedbeef + // Lentry_addr: + // .quad 0xabcdef11 + // + // [~] $ xcrun -sdk iphoneos clang -arch arm64 -c bootstrap.s + // [~] $ otool -t bootstrap.o + // bootstrap.o: + // (__TEXT,__text) section + // 00000000 100000c0 100000e1 f9400000 f9400021 + // 00000010 d61f0020 00000000 feedbeef 00000000 + // 00000020 abcdef11 00000000 + + // Validated by hand that "adr" instructions are encoded as desired. + uint64_t entry_point_phys = phys_base + entry_point_phys_offset; + uint64_t boot_args_phys = phys_base + bootargs_offset; + + uint32_t bootstrap[] = { + 0xd5034fdf, // msr DAIFSet, #15 + 0xd5033fdf, // isb sy + 0x100000c0, // Get location of boot args address: adr x0, Lboot_args_addr (pc + 24) + 0x100000e1, // Get location of entry point: adr x1, Lentry_addr (pc + 32) + 0xf9400000, // Load address of boot args: ldr x0, [x0] + 0xf9400021, // Load entry point: ldr x1, [x1] + 0xd61f0020, // Jump to entry point + 0, // Padding for proper alignment (we reset with all memory as "device") + (uint32_t) boot_args_phys, // Boot args address (low 32 bit) + (uint32_t) (boot_args_phys >> 32), // Boot args address (high 32 bits) + (uint32_t) entry_point_phys, // Entry address (low 32 bits) + (uint32_t) (entry_point_phys >> 32), // Entry address (high 32 bits) + 0 + }; + +#ifdef USE_L4 + if( options.l4_path ) { + memcpy((char *)ram.buf() + (uintptr_t)mba_offset, &mba, sizeof(mba)); + uint64_t mba_phys = phys_base + mba_offset; + bootstrap[8] = (uint32_t) mba_phys; /* Pointer to monitor_boot_args */ + bootstrap[9] = (uint32_t) (mba_phys >> 32); + } +#endif + memcpy(ram.buf(), bootstrap, sizeof(bootstrap)); + + } else { + uint32_t bootstrap[] = { + ARM_B_POS_0x40, // 0x00: b 0x40 + 0, // undef exception + 0, // swi exception + 0, // pabt exception + 0, // dabt exception + 0, // reserved exception + 0, // irq exception + 0, // fiq exception + 0, // 0x20: exception vector table + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ARM_LDR_R0_PC, // 0x40: ldr r0, [pc] ; ldr r0, [0x48] + ARM_LDR_PC_PC, // 0x44: ldr pc, [pc] ; ldr pc, [0x4c] + (uint32_t) phys_base + (uint32_t) bootargs_offset,// 0x48: .word bootargs_offset + (uint32_t) (phys_base + entry_point_phys_offset) // 0x4c: .word entry_point + }; + + assert(phys_base == (uint32_t)phys_base); + assert(bootargs_offset == (uint32_t)bootargs_offset); + assert((phys_base + bootargs_offset) == (uint32_t)(phys_base + bootargs_offset)); + + memcpy(ram.buf(), bootstrap, sizeof(bootstrap)); + } + + // Place the boot args into memory now that we have the location of + // everything. + if (load_macho.Is64Bit()) { + printf("doing 64-bit boot-args.\n"); + boot_args_64 bootArgs; + + memset(&bootArgs, 0, sizeof(bootArgs)); + bootArgs.revision = kBootArgsRevision; + bootArgs.version = kBootArgsVersion1 + ARM64_BOARD_SECURITY_EPOCH; + bootArgs.virtBase = virtual_base; + bootArgs.physBase = phys_base; + bootArgs.memSize = framebuffer_offset; // Must be 1MB aligned. + // Physical address of "video" ram. + bootArgs.video.v_baseAddr = phys_base + framebuffer_offset; + bootArgs.video.v_display = 1; // Display code is just 1 + bootArgs.video.v_rowBytes = FRAMEBUFFER_STRIDE_BYTES; + bootArgs.video.v_width = FRAMEBUFFER_WIDTH; + bootArgs.video.v_height = FRAMEBUFFER_HEIGHT; + bootArgs.video.v_depth = FRAMEBUFFER_DEPTH_BITS; + // Physical address. MMU L1 tables are built here. +#ifdef USE_L4 + if( options.l4_path ) + bootArgs.topOfKernelData = RoundToNextMmuBase(phys_base + bootargs_offset + sizeof(boot_args)); + else +#endif + bootArgs.topOfKernelData = end_of_image; + // Virtual address of device tree. + bootArgs.deviceTreeAddr = virtual_base + devicetree_offset; + bootArgs.deviceTreeLength = devicetree.size(); + memcpy(bootArgs.commandLine, + options.bootargs_string.data(), + options.bootargs_string.size()); + memcpy((char *) ram.buf() + bootargs_offset, &bootArgs, sizeof(bootArgs)); + } else { + boot_args bootArgs; + + memset(&bootArgs, 0, sizeof(bootArgs)); + bootArgs.revision = kBootArgsRevision; + bootArgs.version = kBootArgsVersion1; + bootArgs.virtBase = (uint32_t)virtual_base; + bootArgs.physBase = (uint32_t)phys_base; + bootArgs.memSize = (uint32_t)framebuffer_offset; // Must be 1MB aligned. + // Physical address of "video" ram. + bootArgs.video.v_baseAddr = (uint32_t)(phys_base + framebuffer_offset); + bootArgs.video.v_display = 1; // Display code is just 1 + bootArgs.video.v_rowBytes = FRAMEBUFFER_STRIDE_BYTES; + bootArgs.video.v_width = FRAMEBUFFER_WIDTH; + bootArgs.video.v_height = FRAMEBUFFER_HEIGHT; + bootArgs.video.v_depth = FRAMEBUFFER_DEPTH_BITS; + // Physical address. MMU L1 tables are built here. + bootArgs.topOfKernelData = (uint32_t)end_of_image; + // Virtual address of device tree. + bootArgs.deviceTreeAddr = (uint32_t)(virtual_base + devicetree_offset); + bootArgs.deviceTreeLength = devicetree.size(); + memcpy(bootArgs.commandLine, + options.bootargs_string.data(), + options.bootargs_string.size()); + memcpy((char *) ram.buf() + bootargs_offset, &bootArgs, sizeof(bootArgs)); + } + + // Patch the device tree with the location of loaded segments. + DeviceTreePatcher device_tree_patcher((char *) ram.buf() + devicetree_offset, devicetree.size()); + + // There's a large number of properties not being set here, such as + // 'firmware-version', 'pram', 'vram', but these are not necessary + // yet. + + // Patch the location of the device tree itself. + if (!device_tree_patcher.AllocateMemoryRange("DeviceTree", + phys_base + devicetree_offset, + devicetree.size())) { + return 1; + } + + // Patch the location of the ramdisk, if used. + if (options.ramdisk_file != NULL && + !device_tree_patcher.AllocateMemoryRange("RAMDisk", + phys_base + ramdisk_offset, + ramdisk.size())) { + return 1; + } + + // Patch the location of the bootargs. + if (!device_tree_patcher.AllocateMemoryRange("BootArgs", + phys_base + bootargs_offset, + sizeof(boot_args))) { + return 1; + } + + // Patch KernelCache segments into the device tree. + for (LoadMachO::SegmentListIterator it = load_macho.SegmentListBegin(); + it != load_macho.SegmentListEnd(); + ++it) { + if (!device_tree_patcher.AllocateMemoryRange(it->name.c_str(), + it->pmaddr, + it->size)) { + return 1; + } + // Also check that no segment overlaps the first 4KB page of + // memory. That would mean the bootstrap overwrote something. + if (it->pmaddr < 4096 && it->size != 0) { + fprintf(stderr, "KernelCache segment \"%s\" overlaps first 4KB\n", + it->name.c_str()); + return 1; + } + } + + // Set /chosen:debug-enabled=1. + if (!device_tree_patcher.SetPropertyInt("chosen", "debug-enabled", 1)) { + fprintf(stderr, "Couldn't set /chosen:debug-enabled=1\n"); + return 1; + } + + // Set (arbitrary) core and peripheral frequencies in the device tree. + if (!SetFrequenciesInDeviceTree(&device_tree_patcher)) { + fprintf(stderr, "Couldn't set device frequencies\n"); + return 1; + } + + if (options.have_boot_partition_id) { + // Set /chosen/root-matching=...boot_partition_id.... + char s[256]; + snprintf(s, sizeof(s), + "" + "IOProviderClass" + "IOMedia" + "IOPropertyMatch" + "Partition ID%u" + "", + options.boot_partition_id); + if (!device_tree_patcher.SetPropertyString("chosen", "root-matching", s)) { + fprintf(stderr, "Couldn't set /chosen:root-matching=%s\n", s); + return 1; + } + } + + // Set the location of panic ram. First word physical base, second word size. + uint64_t panic_prop[2]; + bool wide_panic_prop; + + uint64_t vram_prop[2]; + + switch (device_tree_patcher.GetNumAddressCells("")) { // Empty string -> root + case 1: { + wide_panic_prop = false; + panic_prop[0] = ((uint64_t)PANIC_SIZE << 32) | (phys_base + options.sdram_len - PANIC_SIZE); + if (!device_tree_patcher.SetPropertyInt("pram", "reg", panic_prop[0])) { + fprintf(stderr, "Couldn't set /pram:reg=0x%016llx\n", panic_prop[0]); + return 1; + } + + vram_prop[0] = (((uint64_t)FRAMEBUFFER_SIZE_BYTES) << 32) | (phys_base + framebuffer_offset); + if (!device_tree_patcher.SetPropertyInt("vram", "reg", vram_prop[0])) { + fprintf(stderr, "Couldn't set /vram:reg=0x%016llx\n", vram_prop[0]); + return 1; + } + break; + } + case 2: { + wide_panic_prop = true; + panic_prop[0] = phys_base + options.sdram_len - PANIC_SIZE; + panic_prop[1] = ((uint64_t) PANIC_SIZE); + if (!device_tree_patcher.SetPropertyTwoQuads("pram", "reg", panic_prop)) { + fprintf(stderr, "Couldn't set /pram:reg=0x%016llx,0x%016llx\n", panic_prop[0], panic_prop[1]); + return 1; + } + vram_prop[0] = phys_base + framebuffer_offset; + vram_prop[1] = FRAMEBUFFER_SIZE_BYTES; + if (!device_tree_patcher.SetPropertyTwoQuads("vram", "reg", vram_prop)) { + fprintf(stderr, "Couldn't set /vram:reg=0x%016llx,0x%016llx\n", vram_prop[0], vram_prop[1]); + return 1; + } + break; + } + default: { + fprintf(stderr, "Can't set pram address because number of address cells is bad.\n"); + return 1; + } + } + + std::vector::const_iterator patch_iterator; + for (patch_iterator = options.dt_patches.begin(); patch_iterator != options.dt_patches.end(); ++patch_iterator) { + dt_patch_t patch = *patch_iterator; + if (patch.str) { + fprintf(stderr, "Patching /%s:%s=%s\n", patch.node, patch.property, patch.value); + if (!device_tree_patcher.SetPropertyString(patch.node, patch.property, patch.value)) { + fprintf(stderr, "Couldn't set /%s:%s=%s\n", patch.node, patch.property, patch.value); + return 1; + } + } else { + uint64_t value = atoi(patch.value); + fprintf(stderr, "Patching /%s:%s=0x%016llx\n", patch.node, patch.property, value); + if (!device_tree_patcher.SetPropertyInt(patch.node, patch.property, value)) { + fprintf(stderr, "Couldn't set /%s:%s=0x%016llx\n", patch.node, patch.property, value); + return 1; + } + } + } + + assert(end_of_image_offset == (size_t)end_of_image_offset); + fwrite(ram.buf(), (size_t)end_of_image_offset, 1, output_str); + + fprintf(stderr, + "KernelCache: %s\n" + "DeviceTree: %s\n" + "SDRAM size: %uMB\n" + "SDRAM base: 0x%llx\n" + "Virtual base: 0x%016llx\n" + "Top of k. data: 0x%016llx\n" + "Output image: %s\n" + "Boot args: %s\n" + "Ramdisk: %s at 0x%llx, %u\n" + "Framebuffer: 0x%llx %dx%dx%dbpp (%uKB)\n" + "Panic ram: 0x%llx size %lluKB\n" + "Image size: %llu bytes\n" + "Entry point: 0x%016llx\n" + "Boot partition: %s\n", + options.kernelcache_file, + options.devicetree_file, + options.sdram_len / 1024 / 1024, + options.sdram_base, + virtual_base, + end_of_image, + strcmp(options.output_file, "-") ? options.output_file : "", + options.bootargs_string.c_str(), + options.ramdisk_file ? options.ramdisk_file : "(none)", + phys_base + ramdisk_offset, + (unsigned) ramdisk.size(), + phys_base + framebuffer_offset, + FRAMEBUFFER_WIDTH, + FRAMEBUFFER_HEIGHT, + FRAMEBUFFER_DEPTH_BITS, + (unsigned) RoundToNextPage(options, FRAMEBUFFER_SIZE_BYTES) / 1024, + wide_panic_prop ? panic_prop[0] : panic_prop[0] & 0xFFFFFFFF, + wide_panic_prop ? panic_prop[1] / 1024 : (panic_prop[0] & 0xFFFFFFFF00000000ULL) >> 44, + end_of_image - phys_base, + phys_base + entry_point_phys_offset, + options.have_boot_partition_id ? "Root filesystem" : "Ramdisk"); + + if (output_str != stdout) { + fclose(output_str); + } + return 0; +} + +static void Usage(const char *argv0) { + fprintf(stderr, + "Usage:\n" + " %s \n" + "\n" + "Flags are: ('*' denotes mandatory)\n" + "\n" + "* -k \n" + " Specify the kernelcache file to use. This is decompressed\n" + " and the contained Mach-O binary unpacked at the start of\n" + " the resulting image\n" + "* -d \n" + " Specify the devicetree file to use. This is extracted and\n" + " appended to the kernelcache in the resulting image.\n" + " -r \n" + " Specify the ramdisk file to use. This is extracted and\n" + " appended to the devicetree in the resulting image. Optional.\n" + "* -o \n" + " Specify the output file to use. This will contain the image\n" + " to be loaded into memory starting at the base of SDRAM.\n" + " You can use '-' to pipe to standard output.\n" + " -m \n" + " The target's memory size, in MB. This is inserted into the\n" + " boot args structure, and bounds checked when creating the\n" + " image. This does not change the image size.\n" + " Default is %uMB.\n" + " -v \n" + " The target's kernel virtual memory base. This should match\n" + " the layout of he input KernelCache or it will fail to\n" + " translate to the base of SDRAM.\n" + " Default inferred from the layout of the kernelcache.\n" + " -s \n" + " The target's SDRAM memory base. This is the location where\n" + " the output image will be loaded on the target.\n" + " Default is 0x%08x.\n" + " -p \n" + " Patch the devicetree property with the specified integer value.\n" + " -P \n" + " Patch the devicetree property with the specified string value.\n" + " -K\n" + " Tweak offsets for expected kernel layout with 16KB pages.\n" + " -- [...]\n" + " All remaining arguments after '--' are copied into the boot\n" + " args structure as strings separated by spaces.\n" + " Default is an empty string.\n" + "", + argv0, + DEFAULT_SDRAM_LEN / 1024 / 1024, + DEFAULT_SDRAM_BASE); +} + +bool Options::Parse(int argc, char **argv) { + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-k")) { + if (i + 1 >= argc) { + fprintf(stderr, "-k must be followed by the kernel cache file name\n"); + return false; + } + kernelcache_file = argv[++i]; + } else if (!strcmp(argv[i], "-d")) { + if (i + 1 >= argc) { + fprintf(stderr, "-d must be followed by the devicetree file name\n"); + return false; + } + devicetree_file = argv[++i]; + } else if (!strcmp(argv[i], "-r")) { + if (i + 1 >= argc) { + fprintf(stderr, "-r must be followed by the ramdisk file name\n"); + return false; + } + ramdisk_file = argv[++i]; + } else if (!strcmp(argv[i], "-m")) { + if (i + 1 >= argc) { + fprintf(stderr, "-m must be followed by the SDRAM size in MB\n"); + return false; + } + sdram_len = strtoul(argv[++i], NULL, 0) * 1024 * 1024; + } else if (!strcmp(argv[i], "-o")) { + if (i + 1 >= argc) { + fprintf(stderr, "-o must be followed by an output file name\n"); + return false; + } + output_file = argv[++i]; + } else if (!strcmp(argv[i], "-s")) { + if (i + 1 >= argc) { + fprintf(stderr, "-s must be followed by an address\n"); + return false; + } + sdram_base = strtoull(argv[++i], NULL, 0); + } else if (!strcmp(argv[i], "-v")) { + if (i + 1 >= argc) { + fprintf(stderr, "-v must be followed by an address\n"); + return false; + } + virtual_base = strtoull(argv[++i], NULL, 0); + override_virtual_base = true; + } else if (!strcmp(argv[i], "-b")) { + if (i + 1 >= argc) { + fprintf(stderr, "-b must be followed by a partition id\n"); + return false; + } + have_boot_partition_id = true; + boot_partition_id = strtoul(argv[++i], NULL, 0); + } else if (!strcmp(argv[i], "-p")) { + if (i + 3 >= argc) { + fprintf(stderr, "-p must be followed by a node, property, and value\n"); + return false; + } + + dt_patch_t patch = { argv[i+1], argv[i+2], argv[i+3], false }; + dt_patches.push_back(patch); + i += 3; + } else if (!strcmp(argv[i], "-P")) { + if (i + 3 >= argc) { + fprintf(stderr, "-P must be followed by a node, property, and value\n"); + return false; + } + + dt_patch_t patch = { argv[i+1], argv[i+2], argv[i+3], true }; + dt_patches.push_back(patch); + i += 3; + } else if (!strcmp(argv[i], "-K")) { + page_size_16kb = true; +#ifdef USE_L4 + } else if (!strcmp(argv[i], "-l")) { + fprintf(stderr, "got an l4!\n"); + if (i + 1 >= argc) { + fprintf(stderr, "-l must be followed by the L4 file name\n"); + return false; + } + l4_path = argv[++i]; +#endif + } else if (!strcmp(argv[i], "--")) { + // Consume the remaining arguments for bootargs. + for (++i; i < argc; ++i) { + if (!bootargs_string.empty()) bootargs_string += ' '; + bootargs_string += argv[i]; + } + } else { + fprintf(stderr, "Unrecognized option \"%s\"\n", argv[i]); + return false; + } + } + + if (kernelcache_file == NULL || + devicetree_file == NULL || + output_file == NULL) { + fprintf(stderr, "Must specify kernelcache, devicetree and output file\n"); + return false; + } + + if (bootargs_string.size() >= BOOT_LINE_LENGTH) { + fprintf(stderr, "Boot args too long (%u >= %u)\n", + (unsigned) bootargs_string.size(), + (unsigned) BOOT_LINE_LENGTH); + return false; + } + + return true; +} + +void _panic(const char *func, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + fprintf(stderr, "\npanic in %s: ", func); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n\n"); + va_end(args); + exit(1); +} + +static uint64_t RoundToNextPage(const Options &options, uint64_t address) { + // Round an address up to the next page boundary if not aligned (4KB or 16KB) + uint64_t page_size = options.page_size_16kb ? 16384 : 4096; + address += page_size - 1; + address &= ~((uint64_t) page_size - 1); + return address; +} + +static uint64_t RoundToNextMmuBase(uint64_t address) { + // Round an address up to the next MMU base alignment (16KB). + address += TARGET_MMU_BASE_ALIGN - 1; + address &= ~((uint64_t) TARGET_MMU_BASE_ALIGN - 1); + return address; +} + +static bool SetFrequenciesInDeviceTree(DeviceTreePatcher *device_tree_patcher) { + struct { + const char *name; + uint32_t mhz; + } cpu_clocks[] = { + { "clock-frequency", 1000 }, + { "memory-frequency", 500 }, + { "bus-frequency", 250 }, + { "peripheral-frequency", 250 }, + { "fixed-frequency", 24 }, + { "timebase-frequency", 24 }, + }; + for (size_t i = 0; i < sizeof(cpu_clocks) / sizeof(cpu_clocks[0]); ++i) { + assert(cpu_clocks[i].mhz <= UINT32_MAX / 1000000); + if (!device_tree_patcher->SetPropertyInt("cpus/cpu0", + cpu_clocks[i].name, + cpu_clocks[i].mhz * 1000000)) { + fprintf(stderr, "Couldn't set cpus/cpu0:%s = %uMHz\n", + cpu_clocks[i].name, (unsigned) cpu_clocks[i].mhz); + return false; + } + } + return true; +} diff --git a/tools/Buffer.cpp b/tools/Buffer.cpp new file mode 100644 index 0000000..71dac14 --- /dev/null +++ b/tools/Buffer.cpp @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2009 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +#include "Buffer.h" +extern "C" { +#include "drivers/sha1.h" +#include "lib/image/image3/Image3.h" +#include "lib/image/image3/Image3Format.h" +#if BOOTX2BIN_WITH_IMAGE4 +# include +# include +# include +#endif +}; + +extern "C" int image3_load(struct image_info *image_info, + u_int32_t type, + void **load_addr, size_t *load_len); + +void Buffer::alloc(size_t size) { + free(); + _buf = new char[size]; + _size = size; + memset(_buf, 0, _size); +} + +void Buffer::free() { + delete[] _buf; + _buf = NULL; + _size = 0; +} + +void Buffer::swap(Buffer *other) { + std::swap(_buf, other->_buf); + std::swap(_size, other->_size); +} + +void Buffer::crop(size_t newSize) { + assert(newSize <= _size); + _size = newSize; +} + +bool Buffer::loadFromFile(const char *file) { + // Load the contents of a file into a Buffer and return it. + FILE *str = fopen(file, "rb"); + if (!str) { + fprintf(stderr, "Couldn't open \"%s\"\n", file); + return false; + } + fseek(str, 0, SEEK_END); + size_t size = ftell(str); + fseek(str, 0, SEEK_SET); + Buffer file_buf; + file_buf.alloc(size); + int got = fread(file_buf.buf(), file_buf.size(), 1, str); + fclose(str); + if (got != 1) { + fprintf(stderr, "Error reading \"%s\"\n", file); + return false; + } + file_buf.swap(this); + return true; +} + +#if BOOTX2BIN_WITH_IMAGE4 +bool Buffer::loadFromIm4p(const char *file, uint32_t type, bool quiet) { + // Load a payload of expected 'type' from 'file', which is in im4p + // format. Returns a Buffer containing the payload. + Buffer image_buf; + if (!image_buf.loadFromFile(file)) { + fprintf(stderr, "Couldn't load file \"%s\"\n", file); + return false; + } + + // Decode IM4P DER format. + DERItem im4p; + im4p.data = (DERByte *) image_buf.buf(); + im4p.length = image_buf.size(); + DERReturn ret; + DERImg4Payload decoded; + memset(&decoded, 0, sizeof(decoded)); + ret = DERImg4DecodePayload(&im4p, &decoded); + if (ret != DR_Success) { + // This isn't a .im4p + if (!quiet) + fprintf(stderr, "Failed to decode .im4p header: %d\n", (int) ret); + return false; + } + if (decoded.tag.length != 4 || decoded.type.length != 4) { + fprintf(stderr, "Decoded .im4p header has bad tag lengths\n"); + return false; + } + if (memcmp(decoded.tag.data, "IM4P", 4) != 0) { + fprintf(stderr, "DER file schema matches but not an IM4P?\n"); + return false; + } + uint32_t der_type = 0; + ret = DERParseInteger(&decoded.type, &der_type); + if (ret != DR_Success) { + fprintf(stderr, "Failed to decode DER type field: %d\n", (int) ret); + return false; + } + if (der_type != type) { + fprintf(stderr, "DER type 0x%08x mismatches expected 0x%08x\n", + der_type, type); + return false; + } + + // Find the payload. + void *payload_addr = decoded.data.data; + size_t payload_size = decoded.data.length; + + uint8_t *buf_end = (uint8_t *) image_buf.buf() + image_buf.size(); + uint8_t *data_end = (uint8_t *) payload_addr + payload_size; + if (data_end > buf_end) { + fprintf(stderr, "DER data is truncated\n"); + return false; + } + + // Move the data down to the base of the buffer. + memmove(image_buf.buf(), payload_addr, payload_size); + image_buf.crop(payload_size); + image_buf.swap(this); + return true; +} +#endif // BOOTX2BIN_WITH_IMAGE4 + +bool Buffer::loadFromImg3(const char *file, uint32_t type) { + // Load a payload of expected 'type' from 'file', which is in img3 + // format. Returns a Buffer containing the payload. + Buffer image_buf; + if (!image_buf.loadFromFile(file)) { + fprintf(stderr, "Couldn't load file \"%s\"\n", file); + return false; + } + + // Make a handle for the buffer. + Image3ObjectHandle handle; + if (image3InstantiateFromBuffer(&handle, + image_buf.buf(), + image_buf.size(), + false /* copy */)) { + fprintf(stderr, "Image3 instantiation failed\n"); + return false; + } + + // Find the payload. + void *payload_addr = NULL; + size_t payload_size = 0; + if (image3GetTagStruct(handle, + kImage3TagTypeData, + &payload_addr, + &payload_size, + 0)) { + fprintf(stderr, "Couldn't find Image3 payload\n"); + image3Discard(&handle); + return false; + } + + // Move the data down to the base of the buffer. + memmove(image_buf.buf(), payload_addr, payload_size); + image_buf.crop(payload_size); + image_buf.swap(this); + image3Discard(&handle); + return true; +} + +bool Buffer::loadFromAuto(const char *file, uint32_t type) { + // Try raw - in any case we can check the type from there. + if (!loadFromFile(file)) { + fprintf(stderr, "Couldn't load file \"%s\"\n", file); + return false; + } + if (memcmp(buf(), "3gmI", 4)) { +#if BOOTX2BIN_WITH_IMAGE4 + // Try laoding as .im4p - suppress failure message as this is just a test. + if (loadFromIm4p(file, type, true)) { + return true; + } +#endif + fprintf(stderr, "Treating as raw file: %s\n", file); + return true; + } else { + fprintf(stderr, "Treating as img3 file: %s\n", file); + return loadFromImg3(file, type); + } +} + +// Externals used by Image3.c +extern "C" int image3AESDecryptUsingLocalKey(void *buffer, size_t length) { + fprintf(stderr, "Can't personalize\n"); + return -1; +} + +extern "C" void +image3SHA1Generate(void *dataBuffer, size_t dataSize, void *hashBuffer) { + sha1_calculate(dataBuffer, dataSize, hashBuffer); +} + +extern "C" int image3PKIVerifyHash(void *hashBuffer, + size_t hashSize, + void *signedHashBuffer, + size_t signedHashSize, + void *certBlobBuffer, + size_t certBlobSize, + void **certCustomData, + size_t *certCustomDataSize) { + fprintf(stderr, "Can't verify hash\n"); + return -1; +} + +extern "C" int image3TicketVerifyHash(void *hashBuffer, + size_t hashSize, + uint32_t imageType, + uint32_t expectedType) { + fprintf(stderr, "Can't verify hash\n"); + return -1; +} + +extern "C" void *image3Malloc(size_t size) { + return calloc(size, 1); +} + +extern "C" void image3Free(void *ptr, size_t size __unused) { + free(ptr); +} diff --git a/tools/Buffer.h b/tools/Buffer.h new file mode 100644 index 0000000..38e746b --- /dev/null +++ b/tools/Buffer.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2009 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef BUFFER_H +#define BUFFER_H 1 + +#include +#include +#include +#include + +/* + * Encapsulation of a memory buffer. The contained buffer is + * automatically deallocated when the containing Buffer object is + * destructed, which simplifies functions with many early-exit + * cases. To transfer ownership to the caller, swap it with a buffer + * that was passed by reference, e.g: + * + * void my_func(Buffer *ret_buf) { + * Buffer local_buf; + * ... work on local_buf ... + * local_buf.swap(ret_buf); + * } + */ + +class Buffer { + public: + Buffer() : _buf(NULL), _size(0) {} + ~Buffer() { free(); } + + // Allocate a buffer of given 'size'. Deletes any previous contents. + void alloc(size_t size); + + // Allocate and load from a file. + bool loadFromFile(const char *file); + +#if BOOTX2BIN_WITH_IMAGE4 + // Allocate and load a payload from an im4p format file, of expected 'type'. + bool loadFromIm4p(const char *file, uint32_t type, bool quiet = false); +#endif + + // Allocate and load a payload from an img3 format file, of expected 'type'. + bool loadFromImg3(const char *file, uint32_t type); + + // Allocate and load a payload, automatically extracting the payload from + // an im4p or img3 format file if detected, and otherwise raw. Will + // return failure if im4p or img3 is detected but type does not match. + bool loadFromAuto(const char *file, uint32_t type); + + void free(); + void swap(Buffer *other); + void crop(size_t newSize); + + void *buf() { return _buf; } + const void *buf() const { return _buf; } + size_t size() const { return _size; } + + private: + char *_buf; + size_t _size; +}; + +#endif // BUFFER_H diff --git a/tools/DeviceTreePatcher.cpp b/tools/DeviceTreePatcher.cpp new file mode 100644 index 0000000..4310b7c --- /dev/null +++ b/tools/DeviceTreePatcher.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2009, 2013 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#define __STDC_FORMAT_MACROS +#include +#include +#include +#include +#include +#include +#include +#include +#include "DeviceTreePatcher.h" + +struct MemoryMapFileInfo32 { + uint32_t paddr; + uint32_t length; +}; + +struct MemoryMapFileInfo64 { + uint64_t paddr; + uint64_t length; +}; + +DeviceTreePatcher::DeviceTreePatcher(char *base, size_t devtree_size) + : _base(base), _treesize(devtree_size), + _alloc_idx(0) { +} + +uint32_t +DeviceTreePatcher::GetNumAddressCells(const char *node_name) +{ + DTNodePtr node; + if (!FindNode(0, node_name, &node)) { + fprintf(stderr, "GetNumAddressCells: couldn't find \"%s\" node.\n", node_name); + return false; + } + + char addrCellsProp[] = "#address-cells"; + char *addrCellsPropp = &addrCellsProp[0]; + uint32_t *addrCellsData, addrCellsPropSize; + + if (!FindProperty(node, &addrCellsPropp, (void**)&addrCellsData, &addrCellsPropSize)) { + return 0x1; + } else { + return *addrCellsData; + } +} + +bool DeviceTreePatcher::AllocateMemoryRange(const char *name, + uint64_t pmaddr, + uint64_t size) { + set_device_tree((addr_t) _base, _treesize); + bool use_wide_addrs; + uint32_t chosenAddrCells = GetNumAddressCells("chosen"); + + switch(chosenAddrCells) { + case 0x1: + use_wide_addrs = false; + break; + case 0x2: + use_wide_addrs = true; + break; + default: + fprintf(stderr, "AllocateMemoryRange: chosen->#address-cells = %x, which is not valid.\n", chosenAddrCells); + return false; + } + + // Find the memory-map node. + DTNodePtr memory_map; + if (!FindNode(0, "chosen/memory-map", &memory_map)) { + fprintf(stderr, "AllocateMemoryRange: failed to find the /chosen/memory-map node\n"); + return false; + } + + // Find an unused memory map node + union { + MemoryMapFileInfo32 pd32; + MemoryMapFileInfo64 pd64; + } *propData; + + char mapName[kPropNameLength]; + snprintf(mapName, kPropNameLength, "MemoryMapReserved-%d", _alloc_idx); + char *propName = mapName; + + uint32_t propSize; + if (!FindProperty(memory_map, + &propName, + (void **) &propData, + &propSize)) { + fprintf(stderr, "AllocateMemoryRange: failed to find a /chosen/memory-map:%s property\n", mapName); + return false; + } + + fprintf(stderr, "Section %2u: 0x%llx, %llx %s\n", + _alloc_idx, pmaddr, size, name); + strlcpy(propName, name, kPropNameLength); + + if (use_wide_addrs) { + assert(propSize == 16); + propData->pd64.paddr = pmaddr; + propData->pd64.length = size; + } else { + assert(propSize == 8); + propData->pd32.paddr = (uint32_t)pmaddr; + propData->pd32.length = (uint32_t)size; + } + + assert(size == (uint32_t)size); + ++_alloc_idx; + return true; +} + +bool DeviceTreePatcher::GetPropertyBuffer(const char *node_name, + const char *property_name, + void **ret_data, + uint32_t *ret_size) { + DTNodePtr node; + if (!FindNode(0, node_name, &node)) { + fprintf(stderr, "Couldn't find node %s\n", node_name); + return false; + } + void *data; + uint32_t size; + if (!FindProperty(node, const_cast(&property_name), &data, &size)) { + fprintf(stderr, "Couldn't find property %s:%s\n", node_name, property_name); + return false; + } + *ret_data = data; + *ret_size = size; + return true; +} + +bool DeviceTreePatcher::SetPropertyInt(const char *node_name, + const char *property_name, + uint64_t value) { + void *data; + uint32_t size; + if (!GetPropertyBuffer(node_name, property_name, &data, &size)) return false; + // Little-endian properties. + char *p = (char *) data; + for (uint32_t i = 0; i < size; ++i) { + p[i] = value & 255; + value >>= 8; + } + if (value != 0) { + fprintf(stderr, + "Property %s:%s size %u too small for value 0x%" PRIX64 "\n", + node_name, property_name, (unsigned) size, value); + return false; + } + return true; +} + +bool DeviceTreePatcher::SetPropertyTwoQuads(const char *node_name, const char *property_name, uint64_t *values) +{ + void *data; + uint32_t size; + uint64_t value; + if (!GetPropertyBuffer(node_name, property_name, &data, &size)) return false; + + if (size != 16) { + fprintf(stderr, + "Property %s:%s size %u too small for value 0x%016llx,0x%016llx\n", + node_name, property_name, (unsigned) size, values[0], values[1]); + return false; + } + + // Little-endian properties. + char *p = (char *) data; + value = values[0]; + for (uint32_t i = 0; i < size/2; ++i) { + p[i] = value & 255; + value >>= 8; + } + + value = values[1]; + for (uint32_t i = 0; i < size/2; ++i) { + p[i+8] = value & 255; + value >>= 8; + } + + if (value != 0) { + fprintf(stderr, + "Property %s:%s size %u too small for value 0x%" PRIX64 "\n", + node_name, property_name, (unsigned) size, value); + return false; + } + return true; + +} + +bool DeviceTreePatcher::SetPropertyString(const char *node_name, + const char *property_name, + const char *s) { + void *data; + uint32_t size; + if (!GetPropertyBuffer(node_name, property_name, &data, &size)) return false; + char *p = (char *) data; + uint32_t i; + for (i = 0; i < size; ++i) { + p[i] = s[i]; + if (s[i] == '\0') break; + } + if (i == size && s[i] != '\0') { + fprintf(stderr, + "Property %s:%s size %u too small for string of length %u\n", + node_name, property_name, (unsigned) size, + (unsigned) strlen(s) + 1); + return false; + } + return true; +} diff --git a/tools/DeviceTreePatcher.h b/tools/DeviceTreePatcher.h new file mode 100644 index 0000000..abef438 --- /dev/null +++ b/tools/DeviceTreePatcher.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009,2013 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef DEVICE_TREE_PATCHER_H +#define DEVICE_TREE_PATCHER_H 1 + +#include + +// Helper for patching a device tree. Beware that this modifies +// globals (e.g gDeviceTree) as a side-effect of its methods. +class DeviceTreePatcher { + public: + DeviceTreePatcher(char *base, size_t devtree_size); + + // Use one of the reserved chosen/memory-map nodes to record the location + // of a loaded or allocated memory section. Returns true on success, or + // false if this fails to claim an unused reserved node. + bool AllocateMemoryRange(const char *name, uint64_t pmaddr, uint64_t size); + + // Set an integer property. Returns true on success, or false if the + // property cannot be found, or the value is too large to fit. + bool SetPropertyInt(const char *node, const char *property, uint64_t value); + + // Set an integer property. Returns true on success, or false if the + // property cannot be found, or the value is too large to fit. + bool SetPropertyTwoQuads(const char *node, const char *property, uint64_t *value); + + // Set a string property. Returns true on success, or false if the + // property cannot be found, or the value is too large to fit. + bool SetPropertyString(const char *node, const char *property, const char *s); + + uint32_t GetNumAddressCells(const char *node_name); + + private: + // Get a pointer to the storage area for a property. Returns true + // and fills in 'data' and 'size' if found. Returns false and does + // not modify the return arguments if not found. + bool GetPropertyBuffer(const char *node_name, + const char *property_name, + void **data, + uint32_t *size); + + char *_base; + size_t _treesize; + uint32_t _alloc_idx; +}; + +#endif // DEVICE_TREE_PATCHER_H diff --git a/tools/Kernelcache.cpp b/tools/Kernelcache.cpp new file mode 100644 index 0000000..5c80637 --- /dev/null +++ b/tools/Kernelcache.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2009 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +#include "sys.h" +#include "Buffer.h" +#include "Kernelcache.h" +#include "lib/cksum.h" +#include "lib/lzss.h" + +/* Constant for the magic field of the mach_header (32-bit architectures) */ +#define MH_MAGIC 0xfeedface /* the mach magic number */ +#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ + +struct compressed_kernel_header { + uint32_t signature; + uint32_t compress_type; + uint32_t adler32; + uint32_t uncompressed_size; + uint32_t compressed_size; + uint32_t reserved[11]; + uint8_t platform_name[64]; + uint8_t root_path[256]; + uint8_t data[]; +} __attribute__((packed)); + +bool DecompressKernelcache(const Buffer &kernelcache, Buffer *ret_macho) { + if (kernelcache.size() < sizeof(compressed_kernel_header)) { + fprintf(stderr, "Runt image (only %u bytes)\n", + (unsigned) kernelcache.size()); + return false; + } + compressed_kernel_header *header = + (compressed_kernel_header *) kernelcache.buf(); + if (ntohl(header->signature) != 'comp' || + ntohl(header->compress_type) != 'lzss') { + fprintf(stderr, "File does not contain a compressed kernelcache\n"); + return false; + } + fprintf(stderr, "Found compressed kernelcache header\n"); + uint32_t decompressed_size = ntohl(header->uncompressed_size); + uint32_t compressed_size = ntohl(header->compressed_size); + if (compressed_size + sizeof(compressed_kernel_header) > kernelcache.size()) { + fprintf(stderr, "Compressed image size (%u) greater than image (%u)\n", + (unsigned) compressed_size, + (unsigned) (kernelcache.size() - sizeof(compressed_kernel_header))); + return false; + } + fprintf(stderr, "Decompress %u -> %u\n", compressed_size, decompressed_size); + Buffer decompressed; + decompressed.alloc(decompressed_size); + uint32_t actual_size = decompress_lzss((uint8_t *) decompressed.buf(), + decompressed.size(), + (uint8_t *) &header->data[0], + compressed_size); + if (actual_size != decompressed.size()) { + fprintf(stderr, "Decompressed size mismatch, expected %u got %u\n", + (unsigned) decompressed.size(), (unsigned) actual_size); + return false; + } + if (adler32((const uint8_t *) decompressed.buf(), + decompressed_size) != ntohl(header->adler32)) { + fprintf(stderr, "Adler32 mismatch\n"); + return false; + } + uint32_t macho_got_magic; + memcpy(&macho_got_magic, decompressed.buf(), 4); + if (macho_got_magic != MH_MAGIC && macho_got_magic != MH_MAGIC_64) { + fprintf(stderr, "Decompressed kernelcache not in Mach-O format\n"); + return false; + } + decompressed.swap(ret_macho); + return true; +} diff --git a/tools/Kernelcache.h b/tools/Kernelcache.h new file mode 100644 index 0000000..a6be4f3 --- /dev/null +++ b/tools/Kernelcache.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2009 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef KERNELCACHE_H +#define KERNELCACHE_H 1 + +class Buffer; + +bool DecompressKernelcache(const Buffer &kernelcache, Buffer *ret_macho); + +#endif // KERNELCACHE_H diff --git a/tools/LoadMachO.cpp b/tools/LoadMachO.cpp new file mode 100644 index 0000000..5dfd692 --- /dev/null +++ b/tools/LoadMachO.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2009 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include + +#include "sys.h" +#include "Buffer.h" +#include "LoadMachO.h" + +#define PACKED __attribute__((packed)) + +// mach-o/fat.h + +typedef uint32_t cpu_type_t; +typedef uint32_t cpu_subtype_t; + +struct load_command { + uint32_t cmd; + uint32_t cmdsize; +}; + +// mach-o/loader.h + +struct mach_header { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ +} PACKED; + +struct mach_header_64 { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ + uint32_t reserved; /* reserved */ +}; + +/* Constant for the magic field of the mach_header (32-bit architectures) */ +#define MH_MAGIC 0xfeedface /* the mach magic number */ +#define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ +#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ +#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */ + +/* Constants for the cmd field of all load commands, the type */ +#define LC_SEGMENT 0x1 /* segment of this file to be mapped */ +#define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ +#define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ + +#define LC_THREAD 0x4 /* thread */ +#define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ +#define LC_SEGMENT_64 0x19 + +typedef int32_t vm_prot_t; + +struct segment_command { /* for 32-bit architectures */ + uint32_t cmd; /* LC_SEGMENT */ + uint32_t cmdsize; /* includes sizeof section structs */ + char segname[16]; /* segment name */ + uint32_t vmaddr; /* memory address of this segment */ + uint32_t vmsize; /* memory size of this segment */ + uint32_t fileoff; /* file offset of this segment */ + uint32_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +} PACKED; + +struct segment_command_64 { /* for 64-bit architectures */ + uint32_t cmd; /* LC_SEGMENT_64 */ + uint32_t cmdsize; /* includes sizeof section_64 structs */ + char segname[16]; /* segment name */ + uint64_t vmaddr; /* memory address of this segment */ + uint64_t vmsize; /* memory size of this segment */ + uint64_t fileoff; /* file offset of this segment */ + uint64_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +}; + +struct thread_command { + uint32_t cmd; /* LC_THREAD or LC_UNIXTHREAD */ + uint32_t cmdsize; /* total size of this command */ + /* uint32_t flavor flavor of thread state */ + /* uint32_t count count of longs in thread state */ + /* struct XXX_thread_state state thread state for this flavor */ + /* ... */ +} PACKED; + +// arm/_types.h + +struct arm_thread_state +{ + uint32_t r[13]; /* General purpose register r0-r12 */ + uint32_t sp; /* Stack pointer r13 */ + uint32_t lr; /* Link regisster r14 */ + uint32_t pc; /* Program counter r15 */ + uint32_t cpsr; /* Current program status register */ +} PACKED; + +struct arm_thread_state_64 { + uint64_t x[29]; /* General purpose registers x0-x28 */ + uint64_t fp; /* Frame pointer x29 */ + uint64_t lr; /* Link register x30 */ + uint64_t sp; /* Stack pointer x31 */ + uint64_t pc; /* Program counter */ + uint32_t cpsr; /* Current program status register */ +} __attribute__((aligned(8))); + +LoadMachO::LoadMachO(const Buffer &macho, + Buffer *ram) + : _segment_list(), + _last_address(0), + _entry_point_phys_offset(0), + _macho(macho), + _virtual_base(0), + _have_virtual_base(false), + _ram(ram) { +} + +void LoadMachO::OverrideVirtualBase(uint64_t virtual_base) { + _virtual_base = virtual_base; + _have_virtual_base = true; +} + +bool LoadMachO::GetVirtualBase(uint64_t *virtual_base) const { + if (_have_virtual_base) { + *virtual_base = _virtual_base; + return true; + } else { + return false; + } +} + +bool LoadMachO::Load() { + struct mach_header *mH = (struct mach_header *) _macho.buf(); + uint32_t ncmds = mH->ncmds; + char *cmdBase; + + _is_64_bit = mH->magic == MH_MAGIC_64 ? true : false; + if (_is_64_bit) { + cmdBase = (char *) (((struct mach_header_64*)mH) + 1); + } else { + cmdBase = (char *) (mH + 1); + } + + for (uint32_t cnt = 0; cnt < ncmds; cnt++) { + uint32_t cmd, cmdsize; + memcpy(&cmd, cmdBase, 4); + memcpy(&cmdsize, cmdBase + 4, 4); + bool ok; + + //fprintf(stdout, "Current command has cmd %x, size %d\n", cmd, cmdsize); + + switch (cmd) { + case LC_SEGMENT: + if (_is_64_bit) { + fprintf(stderr, "Found LC_SEGMENT in 64-bit Mach-O?"); + ok = false; + break; + } + // Copy a segment into ram. + ok = DecodeSegment(cmdBase); + break; + case LC_SEGMENT_64: + if (!_is_64_bit) { + fprintf(stderr, "Found LC_SEGMENT64 in 32-bit Mach-O?"); + ok = false; + break; + } + // Copy a segment into ram. + ok = DecodeSegment(cmdBase); + break; + case LC_UNIXTHREAD: + // Get entry point. + ok = DecodeUnixThread(cmdBase); + break; + + case LC_SYMTAB: + // Don't do anything useful with symbol tables. + ok = true; + break; + + default: + fprintf(stderr, "Ignoring cmd type %d.\n", (int) cmd); + ok = true; + } + + if (!ok) return false; + + cmdBase += cmdsize; + } + + return true; +} + + +static inline void +widen_segment_command(const struct segment_command *scp32, + struct segment_command_64 *scp) +{ + scp->cmd = scp32->cmd; + scp->cmdsize = scp32->cmdsize; + bcopy(scp32->segname, scp->segname, sizeof(scp->segname)); + scp->vmaddr = scp32->vmaddr; + scp->vmsize = scp32->vmsize; + scp->fileoff = scp32->fileoff; + scp->filesize = scp32->filesize; + scp->maxprot = scp32->maxprot; + scp->initprot = scp32->initprot; + scp->nsects = scp32->nsects; + scp->flags = scp32->flags; +} + + +bool LoadMachO::DecodeSegment(const char *cmdBase) { + const char *src; + char *dst; + uint64_t phys_offset; + uint64_t vmsize, filesize; + struct segment_command_64 segment_command, *scp; + size_t segment_command_size; + struct load_command *lcp = (struct load_command*)cmdBase; + + if (LC_SEGMENT_64 == lcp->cmd) { + segment_command_size = sizeof(struct segment_command_64); + } else { + segment_command_size = sizeof(struct segment_command); + } + + if (lcp->cmdsize < segment_command_size) + return false; + + if (LC_SEGMENT_64 == lcp->cmd) { + scp = (struct segment_command_64 *)lcp; + } else { + scp = &segment_command; + widen_segment_command((struct segment_command *)cmdBase, scp); + } + + if (!_have_virtual_base) { + // Assume the virtual address base is the top bits of the first + // segment we encounter, aligned to 2MB + _have_virtual_base = true; + _virtual_base = scp->vmaddr; + _virtual_base -= _virtual_base % (1<<21); + fprintf(stderr, "inferring virtual base is 0x%016llx\n", _virtual_base); + } + + phys_offset = scp->vmaddr - _virtual_base; + vmsize = scp->vmsize; + + fprintf(stdout, "Handling %d-bit segment with vmaddr %llx, vmsize %llx, fileoff %lld, filesize %lld, maxprot %d, nsects %d\n", + lcp->cmd == LC_SEGMENT_64 ? 64 : 32, scp->vmaddr, scp->vmsize, scp->fileoff, scp->filesize, scp->maxprot, scp->nsects); + fprintf(stdout, "Placing at phys offset %llx\n", phys_offset); + + if (phys_offset + vmsize > _ram->size()) { + fprintf(stderr, "segment overruns end of memory (0x%016llx vs 0x%08x)\n", + (phys_offset + vmsize), + (unsigned)_ram->size()); + return false; + } + + src = (const char *) _macho.buf() + scp->fileoff; + dst = (char *) _ram->buf() + phys_offset; + filesize = scp->filesize; + if (scp->fileoff + filesize > _macho.size()) { + fprintf(stderr, + "segment in Mach-O image past end of file (0x%016llx vs 0x%08x)\n", + (scp->fileoff + filesize), + (unsigned) _macho.size()); + return false; + } + + uint64_t cpysize = std::min(filesize, vmsize); + assert(cpysize == (size_t)cpysize); + memcpy(dst, src, (size_t)cpysize); + + if (vmsize > filesize) { + assert((vmsize - filesize) == (size_t)(vmsize - filesize)); + memset(dst + filesize, 0, (size_t)(vmsize - filesize)); + } + + // Adjust the last address used by the kernel + if (phys_offset + vmsize > _last_address) { + _last_address = phys_offset + vmsize; + } + + // Record the segment in the list. + Segment segment; + segment.name = scp->segname; + segment.pmaddr = phys_offset; + segment.size = vmsize; + _segment_list.push_back(segment); + return true; +} + +bool LoadMachO::DecodeUnixThread(const char *cmdBase) { + // The ARM Thread State starts after the thread command stuct plus, + // 2 longs for the flaver an num longs. + if (!_have_virtual_base) { + fprintf(stderr, + "got unix thread load command but don't know the virtual base\n"); + return false; + } + if (_is_64_bit) { + const struct arm_thread_state_64 *armThreadState = + (const struct arm_thread_state_64 *) + (cmdBase + sizeof(struct thread_command) + 8); + _entry_point_phys_offset = armThreadState->pc - _virtual_base; + fprintf(stdout, "Setting 64-bit thread entry point (phys offset) to 0x%llx (pc %llx)\n", _entry_point_phys_offset, armThreadState->pc); + } else { + const struct arm_thread_state *armThreadState = + (const struct arm_thread_state *) + (cmdBase + sizeof(struct thread_command) + 8); + _entry_point_phys_offset = armThreadState->pc - _virtual_base; + fprintf(stdout, "Setting 32-bit thread entry point (phys offset) to 0x%x (pc %x)\n", (unsigned)_entry_point_phys_offset, armThreadState->pc); + } + + return true; +} diff --git a/tools/LoadMachO.h b/tools/LoadMachO.h new file mode 100644 index 0000000..4bb60e0 --- /dev/null +++ b/tools/LoadMachO.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#ifndef LOAD_MACH_O_H +#define LOAD_MACH_O_H 1 + +#include +#include +#include +#include + +class Buffer; + +class LoadMachO { + public: + struct Segment { + std::string name; + uint64_t pmaddr; + uint64_t size; + }; + typedef std::list SegmentList; + typedef SegmentList::iterator SegmentListIterator; + + LoadMachO(const Buffer &macho, Buffer *ram); + void OverrideVirtualBase(uint64_t virtual_base); + bool GetVirtualBase(uint64_t *virtual_base) const; + bool Load(); + + SegmentListIterator SegmentListBegin() { return _segment_list.begin(); } + SegmentListIterator SegmentListEnd() { return _segment_list.end(); } + uint64_t LastAddress() const { return _last_address; } + uint64_t EntryPointPhysOffset() const { return _entry_point_phys_offset; } + bool Is64Bit() const { return _is_64_bit; } + + private: + bool DecodeSegment(const char *cmdBase); + bool DecodeUnixThread(const char *cmdBase); + + SegmentList _segment_list; + uint64_t _last_address; + uint64_t _entry_point_phys_offset; + const Buffer &_macho; + uint64_t _virtual_base; + bool _have_virtual_base; + bool _is_64_bit; + Buffer *_ram; +}; + +#endif // LOAD_MACH_O_H diff --git a/tools/Macho2Bin.c b/tools/Macho2Bin.c new file mode 100644 index 0000000..eda9bd6 --- /dev/null +++ b/tools/Macho2Bin.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2009 Apple, Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ +/* + * Extract the interesting parts of a Mach-O binary into a preloaded memory image. + * + * We assume that we want all of the __TEXT segment, and anything in __DATA that + * isn't zero-filled. + * + * We expect that the linker will have laid out the data in this object file with + * sections appropriately sized and aligned for directly transferring to memory. + * This is normally the case for MH_PRELOAD objects. + * + * Currently only supports 32-bit Mach-O. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void output_sections(int fd, unsigned char *buf, struct section *sect, uint32_t nsects); +void usage(void); + +int +main(int argc, char *argv[]) +{ + int src, dst; + unsigned char *buf; + struct mach_header *mh; + struct stat s; + unsigned char *cursor; + uint32_t cmdcount; + struct load_command *cmd; + struct segment_command *seg; + + /* check args, open files */ + if (3 != argc) + usage(); + if ((src = open(argv[1], O_RDONLY)) < 0) + err(1, "can't open '%s'", argv[1]); + if (!strcmp(argv[2], "-")) { + dst = STDOUT_FILENO; + } else { + if ((dst = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0) + err(1, "can't open '%s'", argv[2]); + } + + /* read the source file */ + if (fstat(src, &s) < 0) + err(1, "can't stat '%s'", argv[1]); + if (NULL == (buf = (unsigned char *)malloc(s.st_size))) + errx(1, "can't allocate %llu bytes for input file", s.st_size); + if (read(src, buf, s.st_size) != s.st_size) + err(1, "can't read %llu bytes from input file", s.st_size); + close(src); + + /* do some quick sanity on the input */ + mh = (struct mach_header *)buf; + if (mh->magic != MH_MAGIC) + errx(1, "unsupported file type (magic 0x%08x)", mh->magic); + if (mh->filetype != MH_PRELOAD) + errx(1, "unsupported file type (filetype 0x%08x)", mh->filetype); + if (!(mh->flags & MH_NOUNDEFS)) + errx(1, "file has undefined symbols"); + + /* process load commands */ + cursor = (unsigned char *)(mh + 1); + cmdcount = mh->ncmds; + + while (cmdcount-- > 0) { + cmd = (struct load_command *)cursor; + + /* is this a segment command? */ + if (cmd->cmd == LC_SEGMENT) { + seg = (struct segment_command *)cmd; + if (!strcmp("__TEXT", seg->segname)) { + /* emit all of the sections in this segment, back to back */ + output_sections(dst, buf, (struct section *)(seg + 1), seg->nsects); + + } + if (!strcmp("__DATA", seg->segname)) { + /* emit sections in this segment, stopping if/when we hit a zero-fill section */ + output_sections(dst, buf, (struct section *)(seg + 1), seg->nsects); + } + } + cursor += cmd->cmdsize; + } + free(buf); + if (STDOUT_FILENO != dst) + close(dst); + return(0); +} + +void +output_sections(int fd, unsigned char *buf, struct section *sect, uint32_t nsects) +{ + + while (nsects-- > 0) { + /* some linkers forget to set the S_ZEROFILL flag on zerofill sections */ + if ((sect->flags & S_ZEROFILL) || + !strcmp(sect->sectname, "__common") || + !strcmp(sect->sectname, "__bss")) + return; + + //warnx("writing %s,%s", sect->segname, sect->sectname); + + /* write section data from memory to output */ + if (write(fd, buf + sect->offset, sect->size) != sect->size) + err(1, "error writing to output file"); + sect++; + } +} + +void +usage(void) +{ + warnx("usage:"); + fprintf(stderr, "\n %s {|-}\n\n", getprogname()); + exit(1); +} + diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..f2baa05 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,120 @@ +# Copyright (C) 2007 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. + +# Makefile for build/install-time tools + +include makefiles/macros.mk + +HOST_ARCH := $(shell uname -m) +BHC := $(call TOTOOLSDIR,bhc) +MACHO2BIN := $(call TOTOOLSDIR,Macho2Bin) +BOOTX2BIN := $(call TOTOOLSDIR,BootX2Bin) + +# Host libImg4Decode.a is *sometimes* installed to your root filesystem. +# Sometimes it's in your platform. Who knows. Who cares. Let's try a +# few places because I'm sick of filling in TPS reports to get it fixed. + +HOST_IMG4_SEARCH := \ + $(PLATFORMROOT)/usr/local \ + $(PLATFORMROOT)/../../../usr/local \ + /usr/local + +HOST_IMG4_FOUND := \ + $(firstword $(foreach path,\ + $(HOST_IMG4_SEARCH),\ + $(if $(realpath $(path)/include/amd/Img4Decode.h),\ + $(realpath $(path))))) + +HOST_IMG4_INCLUDE := $(HOST_IMG4_FOUND)/include/amd/Img4Decode.h +HOST_IMG4_LIB := $(HOST_IMG4_FOUND)/lib/amd/libImg4Decode.a +ifeq ($(and $(realpath $(HOST_IMG4_INCLUDE)),$(realpath $(HOST_IMG4_LIB))),) +$(info Host Image4 installation broken. Something is missing.) +HOST_IMG4_FOUND := +endif + +ifneq ($(HOST_IMG4_FOUND),) +$(info Host Image4 installation found under $(HOST_IMG4_FOUND)) +else +$(info Host Image4 installation not found, omitting support) +endif + +BOOTX2BIN_INCLUDES := . include lib/pki +BOOTX2BIN_PREBUILT := +BOOTX2BIN_FLAGS := -Wall -O -g -Wformat -DDEBUG + +# Optional Image4 support. +ifneq ($(HOST_IMG4_FOUND),) +BOOTX2BIN_FLAGS += -DBOOTX2BIN_WITH_IMAGE4=1 +BOOTX2BIN_INCLUDES += $(HOST_IMG4_FOUND)/include/amd +BOOTX2BIN_PREBUILT += $(HOST_IMG4_LIB) +endif + +# Add includes to flags. +BOOTX2BIN_FLAGS += $(foreach inc,$(BOOTX2BIN_INCLUDES),-I$(inc)) + +build-tools: destdir $(BHC) $(MACHO2BIN) $(BOOTX2BIN) + +install-tools: destdir $(BHC) $(MACHO2BIN) $(BOOTX2BIN) + +clean-tools: + @rm -f $(BHC) + @rm -f $(MACHO2BIN) + @rm -f $(BOOTX2BIN) + @rm -rf $(TOOLS_BIN) + +destdir: + $(v_)-mkdir -p $(TOOLS_BIN) + + +$(BHC): $(SRCROOT)/tools/bhc.c + @echo HOST_CC $@ + $(_v)${HOST_CC} -isysroot $(HOST_SDKROOT) -o $@ $< + +$(MACHO2BIN): $(SRCROOT)/tools/Macho2Bin.c + @echo HOST_CC $@ + $(_v)${HOST_CC} -isysroot $(HOST_SDKROOT) -o $@ $< + +$(call TOTOOLSDIR,%.o): $(SRCROOT)/%.c + @echo HOST_CC $@ + @mkdir -p $(dir $@) + $(_v)${HOST_CC} -isysroot $(HOST_SDKROOT) -c -o $@ $< $(BOOTX2BIN_FLAGS) + +$(call TOTOOLSDIR,%.o): $(SRCROOT)/%.cpp + @echo HOST_CPP $@ + @mkdir -p $(dir $@) + $(_v)${HOST_CPP} -isysroot $(HOST_SDKROOT) -c -o $@ $< $(BOOTX2BIN_FLAGS) + +LIBDER_SRCS := \ + lib/pki/libDER/DER_CertCrl.c \ + lib/pki/libDER/DER_Decode.c \ + lib/pki/libDER/DER_Digest.c \ + lib/pki/libDER/DER_Encode.c \ + lib/pki/libDER/DER_Keys.c \ + lib/pki/libDER/oids.c + +BOOTX2BIN_SRCS := \ + tools/BootX2Bin.cpp \ + tools/Buffer.cpp \ + tools/DeviceTreePatcher.cpp \ + tools/Kernelcache.cpp \ + tools/LoadMachO.cpp \ + drivers/sha1/mozilla_sha.c \ + drivers/sha1/sha1.c \ + lib/cksum/adler32.c \ + lib/devicetree/devicetree.c \ + lib/image/image3/Image3.c \ + lib/lzss/lzss.c \ + $(LIBDER_SRCS) \ + $(NULL) +BOOTX2BIN_OBJS := $(patsubst %.c,$(call TOTOOLSDIR,%.o),$(BOOTX2BIN_SRCS)) +BOOTX2BIN_OBJS := $(patsubst %.cpp,$(call TOTOOLSDIR,%.o),$(BOOTX2BIN_OBJS)) + +$(BOOTX2BIN): $(BOOTX2BIN_OBJS) $(BOOTX2BIN_PREBUILT) + @echo HOST_LD $@ + $(_v)${HOST_CPP} -isysroot $(HOST_SDKROOT) -o $@ $^ diff --git a/tools/analyzer-report.py b/tools/analyzer-report.py new file mode 100644 index 0000000..c085c01 --- /dev/null +++ b/tools/analyzer-report.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# +# Copyright (c) 2011 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +import os +import sys +import linecache +import cgi +import operator +import xml.sax.saxutils as saxutils + + +Usage=''' +analyzer-report build_output_dir suppressfile +''' +ignored_hashes = None +def get_source_line(filename, linenum): + return linecache.getline(filename, int(linenum)).strip(); + +def process_report_file(filename): + buginfo={} + def populate(comment_name, friendly_name, line): + if friendly_name not in buginfo and comment_name in line: + front_slice = len("") + buginfo[friendly_name] = line[front_slice:-end_slice].strip() + return True; + return False; + actions = { "*****Not a filename*******": "report_file", "BUGDESC": "description", "BUGTYPE": "type", + "BUGCATEGORY": "category", "BUGFILE": "source_file", + "BUGLINE": "line_num"} + buginfo['report_file'] = filename + with open(filename) as f: + for line in f: + try: + for (cn, fn) in actions.items(): + if populate(cn, fn, line): raise ValueError, "Continue" + except ValueError: continue # Lazy hack. Nothing in here uses ValueError. + if set(actions.values()) == set(buginfo.keys()): + buginfo["source_line"] = get_source_line(buginfo['source_file'], buginfo['line_num']); + return buginfo + return None + + +''' +Turns a buginfo dict into a "stable" bug hash. This is meant to be used to +mark problems as ignored. +''' +def bughash(buginfo): + return "[%s # %s # %s]" % (buginfo['description'], buginfo['source_line'], os.path.basename(buginfo['source_file'])) + + +def generate_report_file(buginfos, misc, outfile): + with(open(outfile, "w")) as out: + print >>out, "Clang analyzer report for %s" % sys.argv[1] + print >>out, "
DescriptionRegister ProgrammingAOP AWAKEResume BootAOP DDR
+ +
    amcc_mcccfg_MccGen = 0x00000124
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x0 *read-only
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x0 *read-only
       SpecRdNum = 0x1 *read-only
---
Program AF Allocation Hints, allocation does not happen unless there is a hint as the generic allocation policy + +
    amcc_mcccfg_MccAlcHint = 0x00001110
       MccAlcHintEn = 0x1
       MccGenericAlc = 0x0 *read-only
       MccSclDtyEn = 0x1
       MccStickyEn = 0x1
---
Poll mcccfg MccPwrOnWayCntStatus + +
Poll: mcccfg_MccPwrOnWayCntStatus
+    Mcc0CurDatWayOnCnt
+    Mcc0CurWayCnt
+    Mcc0TgtWayCnt
+    Mcc1CurDatWayOnCnt
+    Mcc1CurWayCnt
+    Mcc1TgtWayCnt
+   while((CSR(amcc_mcccfg_MccPwrOnWayCntStatus) & 0x7fff7fff) != 0x42104210)
+
---
Maximum Number of Powered Ways. + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000110
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x1 *read-only
---
Turn on the MCC + +
    amcc_mcccfg_MccGen = 0x00000195
       DramAccessEn = 0x1
       EccEn = 0x1 *read-only
       HitBypassEcc = 0x0 *read-only
       MccEn = 0x1
       MccRamEn = 0x0
       MccRamEnLock = 0x0 *read-only
       MccStop = 0x0 *read-only
       SpecRdEn = 0x1
       SpecRdNum = 0x4
---
Set Dynamic Way PowerGating + +
    amcc_mcccfg_MccPwrOnWayCntCtrl = 0x00000010
       MccMaxWayOnCnt = 0x10
       MccMaxWayOnExact = 0x0
---
" + for bug in sorted(buginfos, key=operator.itemgetter('source_file', 'description')): + if is_ignored(bughash(bug)): continue + print >>out, " \n" + print >>out, " \n".format(saxutils.quoteattr(bug['report_file']), saxutils.escape(bug['source_file'])) + print >>out, " \n".format(saxutils.escape(bug['description'])) + print >>out, " \n".format(saxutils.quoteattr(bughash(bug))) + print >>out, " \n" + print >>out, "
Source fileBug descriptionbughash
{}{}

%s
" % saxutils.escape(misc) +def is_ignored(i): + global ignored_hashes + if ignored_hashes is None: + ignored_hashes = set() + for line in open(ignorefile): + if line.strip() and not line.startswith("#"): + ignored_hashes.add(line.strip()) + return i in ignored_hashes +def run_misc(buginfos): + import cStringIO + s = cStringIO.StringIO() + ignored = [bughash(i) for i in buginfos if is_ignored(bughash(i))] + not_ignored = [bughash(i) for i in buginfos if not is_ignored(bughash(i))] + print >>s, "Ignored %d bug(s) because of suppress file" % len(ignored) + + if ignored_hashes: + for h in ignored_hashes: + if h not in ignored: + print >>s, "Warning: Possible stale bughash in suppress file: %s" % h + return s.getvalue() + +ignorefile = os.path.abspath(sys.argv[2]) +os.chdir(sys.argv[1]) +buginfos=[] +for folder, subs, files in os.walk("."): + for fn in files: + if fn.endswith(".html"): + buginfo = process_report_file(os.path.join(folder,fn)) + if(buginfo): + buginfos.append(buginfo) + + +generate_report_file(buginfos, run_misc(buginfos), "index.html") diff --git a/tools/analyzer-suppress.txt b/tools/analyzer-suppress.txt new file mode 100644 index 0000000..690e92b --- /dev/null +++ b/tools/analyzer-suppress.txt @@ -0,0 +1,14 @@ +# Clang analyzer ignore file: +# Lines starting with "#" or blank lines are ignored +# "bughashes" are [ error # line_of_code # filename ] pairs +# They are printed in a textbox in the report.html file the analyzer prints +# out. + +# Clang analyzer report of reading uninitialized value relies on mutual inconsistent assumptions +[The right operand of '&' is a garbage value # ret_val |= (cal_bits[(*byte_pos) + 1] & remainder_mask) << space_in_this_byte; # dcs_calibration.c] +[Function call argument is an uninitialized value # dprintf(DEBUG_CRITICAL, "gg charger: 0x%x=0x%x 0x%x=0x%x 0x%x=0x%x 0x%x=0x%x 0x%x=0x%x\n", # hdqgauge.c] + +# The following are benign (no security implications) errors in code that's +# considered "legacy". If we were actively maintaining this code and using it +# in new targets, these issues would be worth fixing, but we're not so we won't +[Potential leak of memory pointed to by 'device' # } # effaceable_nand.c] diff --git a/tools/bhc.c b/tools/bhc.c new file mode 100644 index 0000000..7393fde --- /dev/null +++ b/tools/bhc.c @@ -0,0 +1,231 @@ +/* bhc.c ...Binary data <-> Intel Hex data Converter Ver 1.0.3 */ +/* Suport ROM size 16k,32k,64k,128k,256k,512k,1024k */ +/* 1998/9/12 Kazuhiko Mori(COW) (C)Cow Project Workshop */ +/* e-mail:cow@he.mirai.ne.jp */ +/* This Program is Free Soft */ +/* This version for Unix,Win32,OS/2 */ + +#include +#include +#include +#include +#include + +/* function prototype */ +int b2h(char *in,char *out, char *bufs); +int h2b(char *in,char *out, char *bufs); +int scnv(char *size_ch); +int ch2num(char ch1,char ch2); + +int main(int argc,char *argv[])/*Main routine*/ +{ + int i; + char inf[255],outf[255],flg[8],bufs[8]; + + i = 0;/*Set return code*/ + printf("bhc Ver1.0.3 Binary data <-> Intel Hex data Converter.\n"); + printf("(C)1997-1998 Cow Project Workshop.\n"); + if(argc == 5){ /* Parameter check*/ + strcpy(flg,argv[1]); + strcpy(inf,argv[2]); + strcpy(outf,argv[3]); + strcpy(bufs,argv[4]); + printf("Convert flag %s\nInput file %s\nOutput file %s\n\n",flg,inf,outf); + flg[1] = tolower(flg[1]); + if(0 == strcmp(flg,"-h")){ + printf("Making Intel Hex file.\n"); + i = b2h(inf,outf,bufs); + } + else { + if(0 == strcmp(flg,"-b")){ + printf("Making Binary file.\n"); + i = h2b(inf,outf,bufs); + } + else { + printf("Flag Error!\n"); + i = 3; + } + } + printf("Finished!\n"); + return i; + } + else { /*Error Infomation*/ + printf("Parameter Error!\n\nUsage: bhc flag input_file output_file ROM_size\n\n"); + printf(" flag: -h Convert to Intel Hex data.\n" + " -b Convert to Binary data.\n\n" + " ROM_size: 16k,32k,64k,128k,256k,512k,1024k\n\nTry again!\n"); + return -1; + } +} + +int b2h(char *in,char *out,char *bufs)/*Binary to Hex convert*/ +{ + FILE *inp, *outp; + int ch,cnt,csum,ofsa; + struct stat statbuf; + long int fsize,fpoint,fsub,adrs; + + /*Open file check*/ + if((inp = fopen(in, "rb")) == NULL){ + printf("Cannot open input file.\n"); + return 1; + } + if((outp = fopen(out, "wt")) == NULL){ + printf("Cannot open output file.\n"); + return 1; + } + fstat(fileno(inp), &statbuf); + printf("Input file size=%lld\n",statbuf.st_size); + fsize = (long int)statbuf.st_size; + + if(fsize > scnv(bufs)){ /* File size check*/ + printf("File size error.\n"); + fclose(inp); + fclose(outp); + return 2; + } + + cnt = 0; ofsa = 0; adrs = 0; fpoint = 0; + fprintf(outp,":020000020000FC\n");/*Start Header*/ + fsub = fsize - fpoint; + if (fsub > 0x20) { + fprintf(outp,":20%04X00",(unsigned int)adrs);/*Hex line Header*/ + csum = 0x20 + (adrs>>8) + (adrs & 0xFF); + adrs = 0x20; + } + else { + fprintf(outp, ":%02X%04X00", (unsigned int)fsub,(unsigned int)adrs);/*Hex line Header*/ + csum = fsub + (adrs>>8) + (adrs & 0xFF); + adrs = fsub; + } + while (fsub > 0){ + ch = fgetc(inp); + fprintf(outp,"%02X",ch);/*Put data*/ + cnt++; fpoint++; + fsub = fsize - fpoint; + csum = ch + csum; + if((fsub == 0)||(cnt == 0x20)){ + cnt = 0; csum = 0xFF & (~csum + 1); + fprintf(outp,"%02X\n",csum);/*Put checksum*/ + if(fsub == 0) break; + if(adrs > 0xFFFF){ + ofsa = 0x1000 + ofsa; + adrs = 0; + fprintf(outp,":02000002%04X",(unsigned int)ofsa);/*Change offset address*/ + csum = 0x02 + 0x02 + (ofsa>>8) + (ofsa & 0xFF); + csum = 0xFF & (~csum + 1); + fprintf(outp,"%02X\n", csum); + } + adrs = 0xFFFF & adrs; + if (fsub > 0x20) { + fprintf(outp,":20%04X00",(unsigned int)adrs);/*Next Hex line Header*/ + csum = 0x20 + (adrs>>8) + (adrs & 0xFF); + adrs = adrs + 0x20; + } + else { + if(fsub > 0){ + fprintf(outp, ":%02X%04X00", (unsigned int)fsub,(unsigned int)adrs);/*Next Hex line Header*/ + csum = fsub + (adrs>>8) + (adrs & 0xFF); + adrs = adrs + fsub; + } + } + } + } + fprintf(outp,":00000001FF\n");/*End footer*/ + + fstat(fileno(outp), &statbuf); + printf("Output file size=%lld\n",statbuf.st_size); + + fclose(inp); + fclose(outp); + return 0; +} + +int h2b(char *in,char *out,char *bufs)/*Hex to Binary convert*/ +{ + FILE *inp, *outp; + int lsize,dmode; + char buf[1048576],lbuf[256]; + struct stat statbuf; + long fsize,po,adrs,ofsa,abadrs; + + /*Open file check*/ + if((inp = fopen(in, "rt")) == NULL){ + printf("Cannot open input file.\n"); + return 1; + } + if((outp = fopen(out, "wb")) == NULL){ + printf("Cannot open output file.\n"); + return 1; + } + fstat(fileno(inp), &statbuf); + printf("Input file size=%lld\n",statbuf.st_size); + + fsize = scnv(bufs); + + for(po = 0;po < 1048576;po++) buf[po] = 0xFF;/*Fill Buffer 0xFF data*/ + + adrs = 0; ofsa = 0; + while (NULL != fgets(lbuf,254,inp)){/*Loop until end of file*/ + if((lbuf[0] != ':')||(!isalnum(lbuf[1]))||(!isalnum(lbuf[2]))) { + continue; + } + lsize = ch2num(lbuf[1],lbuf[2]) * 2; + adrs = (long)(ch2num(lbuf[3],lbuf[4])) * 0x100L + + (long)(ch2num(lbuf[5],lbuf[6])); + if(fsize < (ofsa + adrs)) {/*Address check*/ + printf("Address error!\n"); + fclose(inp); + fclose(outp); + return 5; + } + + dmode = ch2num(lbuf[7],lbuf[8]);/*Get data mode */ + if(dmode == 2) {/*Get offset address*/ + ofsa = ((long)ch2num(lbuf[9],lbuf[10]) * 0x100L + + (long)ch2num(lbuf[11],lbuf[12])) * 0x10L; + continue; + } + if(dmode == 0){/*Get binary data*/ + abadrs = ofsa + adrs; + for(po = 9;po < (lsize+9);po=po+2){ + buf[abadrs++] = ch2num(lbuf[po],lbuf[po+1]);/*Write data to buffer*/ + } + } + } + + for(po = 0;po < fsize;po++){/*Write buffer data to file*/ + putc(buf[po],outp); + } + + fstat(fileno(outp), &statbuf); + printf("Output file size=%lld\n",statbuf.st_size); + + fclose(inp); + fclose(outp); + return 0; +} + +int scnv(char *size_ch)/* Size character converte to Integer*/ +{ + if(strcmp(size_ch,"16k") == 0) return 16384; + if(strcmp(size_ch,"32k") == 0) return 32768; + if(strcmp(size_ch,"64k") == 0) return 65536; + if(strcmp(size_ch,"128k") == 0) return 131072; + if(strcmp(size_ch,"256k") == 0) return 262144; + if(strcmp(size_ch,"512k") == 0) return 524288; + if(strcmp(size_ch,"1024k") == 0) return 1048576; + return 1048576; +} + +int ch2num(char ch1,char ch2) +{ + int nout; + + if((ch1 >= '0')&&('9' >= ch1)) nout = (ch1 & 0xf) * 0x10; + else nout = ((ch1 & 0xf) + 9) * 0x10; + if((ch2 >= '0')&&('9' >= ch2)) return (ch2 & 0xf) + nout; + else return ((ch2 & 0xf) + 9) + nout; +} +/* Thanks to KITA (QZE01066@nifty.ne.jp) */ +/* End of file*/ diff --git a/tools/check_liblist.py b/tools/check_liblist.py new file mode 100644 index 0000000..24ec55d --- /dev/null +++ b/tools/check_liblist.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python2.7 + +# Check generated build/library_list for any library~arch which will be +# built with more than one set of flags. The flags are not used to +# uniquely identify a built library, so we instead end up with a +# non-deterministic build where one set of flags builds last, and ends +# up linked into all application/product executables. + +import sys + +def main(): + lib_flags_sets = {} + for line in open(sys.argv[1], 'r').readlines(): + # Split each line by '~' delimiter + parts = line.strip().split('~') + # Re-join first two components in target library + lib = ' '.join(parts[0:2]) + # All other components into flags + flags = ' '.join(parts[2:]) + # Note that this lib has these flags in use + lib_flags_sets.setdefault(lib, {})[flags] = None + # Check if any library is attempting to be built with more than one + # set of flags. + ok = True + for lib, flags_set in lib_flags_sets.items(): + if len(flags_set) == 1: + continue + ok = False + sys.stderr.write('Multiple flag sets for library %s:\n' % lib) + for flags in flags_set.keys(): + sys.stderr.write(' %s \n' % flags) + return 0 if ok else 1 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tools/check_product_size b/tools/check_product_size new file mode 100644 index 0000000..2a75255 --- /dev/null +++ b/tools/check_product_size @@ -0,0 +1,25 @@ +#!/bin/bash -e + +# Simple helper script for enforcing file size +# +# This is a bit too cluttered in a Makefile rule. + +if [ $# -ne 3 ]; then + echo "Usage: $0 filename max_size name_of_check" + exit 1 +fi + +FILENAME=$1 +MAXSIZE=$(( $2 )) +NAME=$3 + +SIZE=`stat -f '%z' "$FILENAME"` + +if [ $SIZE -gt $MAXSIZE ]; then + echo "[check_product_size $NAME]: $FILENAME is too big! Built size: $SIZE bytes, limit: $MAXSIZE bytes, oversized by $(( $SIZE - $MAXSIZE )) bytes." 1>&2 + exit 1 +fi + +echo "[check_product_size $NAME]: $FILENAME PASSED. Usage: $SIZE/$MAXSIZE bytes" + +exit 0 diff --git a/tools/code_sizer b/tools/code_sizer new file mode 100644 index 0000000..0fb5ae0 --- /dev/null +++ b/tools/code_sizer @@ -0,0 +1,184 @@ +#!/usr/bin/tclsh +################################################################################ +# +# Given a mach-o binary, use nm and gdb to size all the functions it contains +# + + +proc main { } { + global argv + + set binfile [lindex $argv 0] + if {![file readable $binfile]} { + puts "can't read '$binfile'" + exit 1 + } + + # run nm and parse the output + do_nm $binfile + + # compute text symbol sizes + do_sizing + + # now ask GDB for the file(s) containing each symbol + do_gdb $binfile + + # and emit results + do_emit_sized + do_emit_files +} + + +proc do_nm {binfile} { + + global symbol_addresses + global text_symbols + + set lines [exec nm -n $binfile] + + foreach {addr type _sym} $lines { + # record the fact that there is a symbol boundary at this address + lappend addresses "0x$addr" + + # if the symbol is a text symbol, record its address + # this could be "tds" to get data symbols too.. + if {[string match \[tT\] $type]} { + # ignore the first leading underscore in the symbol name + set sym [string range $_sym 1 end] + + # save the text symbol and its address + set text_symbols($sym) "0x$addr" + } + } + set symbol_addresses [lsort -integer -unique $addresses] + puts "[llength [array names text_symbols]] text symbols" +} + + +proc do_sizing {} { + + global symbol_addresses + global text_symbols + global text_symbol_sizes + global text_size_symbols + + # walk the array of text symbols + foreach sym [array names text_symbols] { + + # get the address of the symbol + set addr $text_symbols($sym) + + # find the address in the global list of symbol addresses + set index [lsearch $symbol_addresses $addr] + + # find the next symbol boundary + set nextaddr [lindex $symbol_addresses [expr $index + 1]] + + # size is the distance between the two + set size [expr $nextaddr - $addr] + set text_symbol_sizes($sym) $size + + # index symbols by size + lappend text_size_symbols($size) $sym + } +} + + +proc do_gdb {binfile} { + + global symbol_filenames + global file_symbols + + # ask GDB for the output of "info functions" + set lines [exec echo "info functions" | xcrun -sdk iphoneos.internal gdb --quiet $binfile 2>/dev/null] + + # Output from GDB includes lines announcing files, and lines describing functions + # within those files. + foreach line [split $lines "\n"] { + # new file announcement + if {[string match "File *" $line]} { + set current_file [string range $line 5 end-1] + } + + # function within a file + set paren [string first "(" $line] + if {$paren > 0} { + + # function name is last token before ( in the line + set frag [string range $line 0 [expr $paren - 1]] + set sym [string trimleft [lindex [split $frag] end] "*"] + + # index filesnames by symbol + lappend symbol_filenames($sym) $current_file + + # index symbols by filename + lappend file_symbols($current_file) $sym + } + } +} + + +proc do_emit_sized {} { + + global text_size_symbols + global symbol_filenames + + puts "Symbols by size" + puts "===============" + foreach size [lsort -integer [array names text_size_symbols]] { + foreach sym $text_size_symbols($size) { + if {[llength [array names symbol_filenames -exact $sym]] > 0} { + puts [format "%8d %-50s %s" $size $sym $symbol_filenames($sym)] + } else { + puts [format "%8d %-50s" $size $sym] + } + } + } + puts "" +} + +proc do_emit_files {} { + + global file_symbols + global text_symbol_sizes + + puts "Symbols by file size" + puts "====================" + foreach fn [array names file_symbols] { + set size 0 + foreach sym $file_symbols($fn) { + if {[array names text_symbol_sizes $sym] != ""} { + incr size $text_symbol_sizes($sym) + } else { + puts "WARNING: no size information for '$sym' - nm didn't see it." + } + } + lappend size_files($size) $fn + } + + foreach size [lsort -integer [array names size_files]] { + foreach fn $size_files($size) { + puts "$fn: ($size)" + set lines [list] + foreach sym $file_symbols($fn) { + if {[array names text_symbol_sizes $sym] != ""} { + lappend lines [list $text_symbol_sizes($sym) $sym] + } + } + foreach ent [lsort -index 0 -integer $lines] { + puts [format "%8d %-50s" [lindex $ent 0] [lindex $ent 1]] + } + puts "" + } + } +} + + + + + + + + +################################################################################ +main \ No newline at end of file diff --git a/tools/config_debug.tcl b/tools/config_debug.tcl new file mode 100644 index 0000000..7c26881 --- /dev/null +++ b/tools/config_debug.tcl @@ -0,0 +1,115 @@ +#!/usr/local/bin/astris +# -*-Tcl-*- + +# Read out cfg engine state and debug registers + +set soc_cfg_error [mem -memap 4 0x210480000] +puts [format "SOC CFG ERROR(0x210480000) 0x%x" $soc_cfg_error] + +set wr_resp_err_in_flight [expr ($soc_cfg_error>>24) & 0x3F] +set wr_resp_err [expr ($soc_cfg_error>>20) & 0x3] +set rd_timeout_err [expr ($soc_cfg_error>>16) & 0x1] +set rd_resp_err [expr ($soc_cfg_error>>12) & 0x3] +set unknown_cmd_err [expr ($soc_cfg_error>>8) & 0x1] +set spec_access_err [expr ($soc_cfg_error>>4) & 0x3] +set table_access_err [expr $soc_cfg_error & 0x3] + +if {$wr_resp_err_in_flight} {puts [format "\twr_resp_err_in_flight: 0x%x" $wr_resp_err_in_flight]} +if {$wr_resp_err} {puts [format "\twr_resp_err: 0x%x" $wr_resp_err]} +if {$rd_timeout_err} {puts [format "\trd_timeout_err: 0x%x" $rd_timeout_err]} +if {$rd_resp_err} {puts [format "\trd_resp_err: 0x%x" $rd_resp_err]} +if {$unknown_cmd_err} {puts [format "\tunknown_cmd_err: 0x%x" $unknown_cmd_err]} +if {$spec_access_err} {puts [format "\tspec_access_err: 0x%x" $spec_access_err]} +if {$table_access_err} {puts [format "\ttable_access_err: 0x%x" $table_access_err]} + +set last_fetch_rd_addr [mem -memap 4 0x21048000c] +set last_proc_rd_addr [mem -memap 4 0x210480010] +set last_proc_wr_addr [mem -memap 4 0x210480014] +puts [format "last_fetch_rd_addr(0x21048000c) 0x%x" $last_fetch_rd_addr] +puts [format "last_proc_rd_addr(0x210480010) 0x%x" $last_proc_rd_addr] +puts [format "last_proc_wr_addr(0x210480014) 0x%x" $last_proc_wr_addr] + + +set aop_state [mem -memap 4 0x210000008] +puts [format "AOP STATE(0x210000008) 0x%x" $aop_state] +set pmu_if [expr $aop_state & 0x1F] +if {$pmu_if == 0x0} {puts "\tRESET - cold boot wait state until minipmgr_aop_awake_ack_sync"} +if {$pmu_if == 0x1} {puts "\tAWAKE - in the AWAKE state"} +if {$pmu_if == 0x2} {puts "\tAWAKE_exit_delay - counter delay before exiting from AWAKE"} +if {$pmu_if == 0x3} {puts "\tAWAKE_exit_pre - executing preamble"} +if {$pmu_if == 0x4} {puts "\tAWAKE_exit_HS - handshake with miniPMGR"} +if {$pmu_if == 0x5} {puts "\tAWAKE_exit_post - executing postamble"} +if {$pmu_if == 0x6} {puts "\tAWAKE_exit_PMU - handshake with PMU"} +if {$pmu_if == 0x7} {puts "\tOFF - in the OFF state"} +if {$pmu_if == 0x8} {puts "\tS2R_NOAOP - in the S2R_NOAOP state"} +if {$pmu_if == 0x9} {puts "\tAOP_DDR - in the AOP_DDR state"} +if {$pmu_if == 0xA} {puts "\tS2R_AOP - in the S2R_AOP state"} +if {$pmu_if == 0xB} {puts "\tgoAWAKE_rst - heading from AOP_DDR to AWAKE, waiting for AWAKE_RESETN"} +if {$pmu_if == 0xC} {puts "\tgoAWAKE_pre - preamble for AOP_DDR to AWAKE"} +if {$pmu_if == 0xD} {puts "\tgoAWAKE_HS - handshake with miniPMGR"} +if {$pmu_if == 0xE} {puts "\tgoAWAKE_post - postamble for AOP_DDR to AWAKE"} +if {$pmu_if == 0xF} {puts "\tgoS2R_pre - preamble for AOP_DDR to S2R_AOP"} +if {$pmu_if == 0x10} {puts "\tgoS2R_HS - handshake with miniPMGR"} +if {$pmu_if == 0x11} {puts "\tgoS2R_post - postamble for AOP_DDR to S2R_AOP"} +if {$pmu_if == 0x12} {puts "\tgoS2R_PMU - handshake with PMU"} +if {$pmu_if == 0x13} {puts "\tgoDDR_pre - preamble for S2R_AOP to AOP_DDR"} +if {$pmu_if == 0x14} {puts "\tgoDDR_PMU - handshake with PMU"} +if {$pmu_if == 0x15} {puts "\tgoDDR_HS - handshake with miniPMGR"} +if {$pmu_if == 0x16} {puts "\tgoDDR_post - postamble for S2R_AOP to AOP_DDR"} + +#soc cfg +set table_base [mem -memap 4 0x210000200] +set cfg_table_address [expr $table_base | 0x210e00000] + +set s2r_aop_to_aop_ddr [mem -memap 4 0x210000204] +set s2r_aop_to_aop_ddr_pre_enable [expr ($s2r_aop_to_aop_ddr>>8) & 0x1] +set s2r_aop_to_aop_ddr_pre_index [expr ($s2r_aop_to_aop_ddr>>0) & 0x1F] +set s2r_aop_to_aop_ddr_post_enable [expr ($s2r_aop_to_aop_ddr>>24) & 0x1] +set s2r_aop_to_aop_ddr_post_index [expr ($s2r_aop_to_aop_ddr>>16) & 0x1F] + +set aop_ddr_to_s2r_aop [mem -memap 4 0x210000208] +set aop_ddr_to_s2r_aop_pre_enable [expr ($aop_ddr_to_s2r_aop>>8) & 0x1] +set aop_ddr_to_s2r_aop_pre_index [expr ($aop_ddr_to_s2r_aop>>0) & 0x1F] +set aop_ddr_to_s2r_aop_post_enable [expr ($aop_ddr_to_s2r_aop>>24) & 0x1] +set aop_ddr_to_s2r_aop_post_index [expr ($aop_ddr_to_s2r_aop>>16) & 0x1F] + +set aop_ddr_to_awake [mem -memap 4 0x21000020c] +set aop_ddr_to_awake_pre_enable [expr ($aop_ddr_to_awake>>8) & 0x1] +set aop_ddr_to_awake_pre_index [expr ($aop_ddr_to_awake>>0) & 0x1F] +set aop_ddr_to_awake_post_enable [expr ($aop_ddr_to_awake>>24) & 0x1] +set aop_ddr_to_awake_post_index [expr ($aop_ddr_to_awake>>16) & 0x1F] + +set awake_to_aop_ddr [mem -memap 4 0x210000210] +set awake_to_aop_ddr_pre_enable [expr ($awake_to_aop_ddr>>8) & 0x1] +set awake_to_aop_ddr_pre_index [expr ($awake_to_aop_ddr>>0) & 0x1F] +set awake_to_aop_ddr_post_enable [expr ($awake_to_aop_ddr>>24) & 0x1] +set awake_to_aop_ddr_post_index [expr ($awake_to_aop_ddr>>16) & 0x1F] + +puts [format "table_base(0x210000200) 0x%x" $table_base] +puts [format "\tConfig Table Address: 0x%x" $cfg_table_address] +puts "Config table entries" +md32 -memap 4 $cfg_table_address 40 + +puts [format "awake_to_aop_ddr(0x210000210) 0x%x" $awake_to_aop_ddr] +puts [format "\tpre enable 0x%x" $awake_to_aop_ddr_pre_enable] +puts [format "\tpre index 0x%x" $awake_to_aop_ddr_pre_index] +puts [format "\tpost enable 0x%x" $awake_to_aop_ddr_post_enable] +puts [format "\tpost index 0x%x" $awake_to_aop_ddr_post_index] +puts [format "aop_ddr_to_s2r_aop(0x210000208) 0x%x" $aop_ddr_to_s2r_aop] +puts [format "\tpre enable 0x%x" $aop_ddr_to_s2r_aop_pre_enable] +puts [format "\tpre index 0x%x" $aop_ddr_to_s2r_aop_pre_index] +puts [format "\tpost enable 0x%x" $aop_ddr_to_s2r_aop_post_enable] +puts [format "\tpost index 0x%x" $aop_ddr_to_s2r_aop_post_index] +puts [format "s2r_aop_to_aop_ddr(0x210000204) 0x%x" $s2r_aop_to_aop_ddr] +puts [format "\tpre enable 0x%x" $s2r_aop_to_aop_ddr_pre_enable] +puts [format "\tpre index 0x%x" $s2r_aop_to_aop_ddr_pre_index] +puts [format "\tpost enable 0x%x" $s2r_aop_to_aop_ddr_post_enable] +puts [format "\tpost index 0x%x" $s2r_aop_to_aop_ddr_post_index] +puts [format "aop_ddr_to_awake(0x21000020c) 0x%x" $aop_ddr_to_awake] +puts [format "\tpre enable 0x%x" $aop_ddr_to_awake_pre_enable] +puts [format "\tpre index 0x%x" $aop_ddr_to_awake_pre_index] +puts [format "\tpost enable 0x%x" $aop_ddr_to_awake_post_enable] +puts [format "\tpost index 0x%x" $aop_ddr_to_awake_post_index] + +puts "Trace Entry" +mem -memap 4 0x210E9E500 diff --git a/tools/config_seq.py b/tools/config_seq.py new file mode 100644 index 0000000..f048042 --- /dev/null +++ b/tools/config_seq.py @@ -0,0 +1,105 @@ +#!/usr/bin/python +import argparse +import collections +import pipes +import sys + +WRITE_COMMAND = 0 +WRITE_COMPRESSED_COMMAND = 1 +READ_COMMAND = 2 +WRITE64_COMMAND = 3 +DELAY_COMMAND = 4 + +def find_string(line, word): + t = line.split() + for x in t: + if word in x: + s = x.find('=') + addr = x[s+1:] + return addr + +def convert_seqto_struct(filename, sequence): + a = [] + with open (filename, 'rb') as config_seq_file: + for line in config_seq_file: + if sequence in line and 'comment' not in line: + for line in config_seq_file: + if 'cfg_end' in line: + break + elif 'comment' in line or 'write_start' in line or 'write_end' in line: + continue + elif 'poll' in line: + # poll command + addr = find_string(line, 'reg_addr') + value = find_string(line, 'reg_value') + mask = find_string(line, 'reg_mask') + retryEnable = find_string(line, 'retry_en') + retryCnt = find_string(line, 'retry_cnt') + a.append((addr, value, READ_COMMAND, mask, retryEnable, retryCnt)) + elif 'write64' in line: + # 64 BIT write commands + addr = find_string(line, 'reg_addr') + value = find_string(line, 'reg_value') + a.append((addr, value, WRITE64_COMMAND)) + elif 'cfg_cnt' in line: + value = line.split()[1] + a.append((0, value, DELAY_COMMAND)) + else: + # write commands + addr = find_string(line, 'reg_addr') + value = find_string(line, 'reg_value') + a.append((addr, value, WRITE_COMMAND)) + + + j = 0 + print 'uint32_t %s[] = {' % (sequence.split()[1]) + for i in xrange(len(a)): + if WRITE_COMMAND == a[i][2]: + wrCommand = ((int(a[i][0], 16)>>10)<<6) | (1) + offCommand = (int(a[i][0], 16)>>2) & 0xff + wrDword = int(a[i][1], 16) + print '\t0x{:X}, 0x{:X}, 0x{:X},\t\t\t\t// Write'.format(wrCommand, offCommand, wrDword) + j += 3 + elif READ_COMMAND == a[i][2]: + rdCommand = ((int(a[i][0], 16)>>10)<<6) | (2) + offCommand = (int(a[i][4], 16)<<16) | ((int(a[i][5], 16) & 0xFF)<<8) | ((int(a[i][0], 16)>>2) & 0xFF) + rdDataMask = int(a[i][3], 16) + rdDword = int(a[i][1], 16) + print '\t0x{:X}, 0x{:X}, 0x{:X}, 0x{:X},\t\t// Read'.format(rdCommand, offCommand, rdDataMask, rdDword) + j += 4 + elif WRITE64_COMMAND == a[i][2]: + wrCommand = ((int(a[i][0], 16)>>10)<<6) | (1<<1) | (1) + offCommand = (int(a[i][0], 16)>>2) & 0xff + wrDwordLow = int(a[i][1], 16) & 0xFFFFFFFF + wrDwordHigh = (int(a[i][1], 16) >> 32) & 0xFFFFFFFF + if ((j+2) % 8) : + print '\t0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X},\t\t\t\t// Write'.format(wrCommand, offCommand, 0x0, wrDwordLow, wrDwordHigh) + j += 5 + else: + print '\t0x{:X}, 0x{:X}, 0x{:X}, 0x{:X},\t\t\t\t// Write'.format(wrCommand, offCommand, wrDwordLow, wrDwordHigh) + j += 4 + elif DELAY_COMMAND == a[i][2]: + delayCommand = (int(a[i][1], 16)<<6) | 4 + print '\t0x{:X}, \t\t// Delay'.format(delayCommand) + j += 1 + + + print '};' + +def main(): + argparser = argparse.ArgumentParser(description='Converts config sequence to data structures to to be programmed') + argparser.add_argument('filename') + args = argparser.parse_args() + + convert_seqto_struct(args.filename, 'seq_name: awake_to_aop_ddr_pre') + convert_seqto_struct(args.filename, 'seq_name: awake_to_aop_ddr_post') + convert_seqto_struct(args.filename, 'seq_name: aop_ddr_to_s2r_aop_pre') + convert_seqto_struct(args.filename, 'seq_name: s2r_aop_to_aop_ddr_post') + convert_seqto_struct(args.filename, 'seq_name: aop_ddr_to_awake_pre') + convert_seqto_struct(args.filename, 'seq_name: aop_ddr_to_awake_post') + + return 0 + +if __name__ == '__main__': + main() + diff --git a/tools/csvtopinconfig.py b/tools/csvtopinconfig.py new file mode 100644 index 0000000..6336238 --- /dev/null +++ b/tools/csvtopinconfig.py @@ -0,0 +1,988 @@ +#!/usr/bin/python +import argparse +import collections +import csv +import pipes +import sys + +try: + import openpyxl +except ImportError: + openpyxl = None + +class ParseError(Exception): pass + +''' +Representation of one pin in the GPIO config +''' +class BasePin(object): + default_drive = 'X1' + valid_pupdn = set(["PULL_UP", "PULL_DOWN", ""]) + valid_drive_strength = set() + def __init__(self, gpio_pin_number): + self.gpio_pin_number = int(gpio_pin_number) + self.bump_name = None + self.net_name = None + self.function = None + self.drive_strength = 'X1' + self.pupd = None + self.bus_hold = None + self.input_mode = None + self.row_number = None + self.slew_rate = '' + self.rom = None + + @property + def non_empty_props(self): + if self.drive_strength == self.default_drive: + drive_strength = '' + else: + drive_strength = "DRIVE_{}".format(self.drive_strength) + + if self.slew_rate == '': + slew_rate = '' + else: + slew_rate = "{}_SLEW".format(self.slew_rate) + + return [i for i in [self.function, self.pupd, drive_strength, slew_rate, self.bus_hold, self.input_mode] if i] + + def to_enum_key(self): + return 'GPIOCFG_' + '_'.join(self.non_empty_props) + + def to_enum_value(self): + return ' | '.join(self.non_empty_props) + + def to_pinconfig_line(self, use_enum): + if None in (self.bump_name, self.net_name, self.function, self.drive_strength, self.pupd): + raise ParseError, "Some attributes were unset for pin %d: %s" % (self.gpio_pin_number, (self.bump_name, self.net_name, self.function, self.drive_strength, self.pupd)) + + if use_enum: + args = '{},'.format(self.to_enum_key()) + else: + args = '{},'.format(self.to_enum_value()) + + gpio_comment = '// {:>3} : {}'.format(self.gpio_pin_number, self.bump_name) + net_name_comment = '-> {}'.format(self.net_name) + return [args, gpio_comment, net_name_comment] + + def set_function(self, fn): + cfg_map = { 'in': 'CFG_IN', + 'input': 'CFG_IN', + 'out0': 'CFG_OUT_0', + 'out 0': 'CFG_OUT_0', + 'out1': 'CFG_OUT_1', + 'out 1': 'CFG_OUT_1', + 'alt func 0': 'CFG_FUNC0', + 'alt func 1': 'CFG_FUNC1', + 'alt func 2': 'CFG_FUNC2', + 'int rising': 'CFG_IN', + 'int falling': 'CFG_IN', + 'int any': 'CFG_IN', + 'disable': 'CFG_DISABLED', + 'disabled': 'CFG_DISABLED', + # The numbering offset isn't a typo, these are legacy + 'function 1': 'CFG_FUNC0', + 'function 2': 'CFG_FUNC1', + 'function 3': 'CFG_FUNC2', + } + self.function = cfg_map[fn.lower()] + + def set_net_name(self, name): + self.net_name = name.strip() + + def set_bump_name(self, name): + self.bump_name = name.strip() + + def set_drive_strength(self, strength): + if strength == '': + strength = self.default_drive + else: + strength = strength.upper() + + if strength.isdigit(): + strength = self.drive_strength_prefix + strength + + if not strength in self.valid_drive_strength: + sorted_drive_strengths = sorted(self.valid_drive_strength, key=lambda item: (int(item[1:]))) + raise ParseError, "drive strength '{}' not valid (options are {})".format(strength.upper(), sorted_drive_strengths) + self.drive_strength = strength + + def set_pupd(self, pupd): + pupd_map = { 'pullup strong' : 'PULL_UP_STRONG', + 'spu' : 'PULL_UP_STRONG', + 'pullup': 'PULL_UP', + 'pu': 'PULL_UP', + 'pulldown': 'PULL_DOWN', + 'pd': 'PULL_DOWN', + 'disable': '', + '': ''} + if not pupd_map[pupd.lower()] in self.valid_pupdn: + pretty_pupdn = filter(lambda x : pupd_map[x] in self.valid_pupdn , pupd_map.keys()) + raise ParseError, "pu/pd value '{}' not valid (options are {})".format(pupd, pretty_pupdn) + self.pupd = pupd_map[pupd.lower()] + + +class PinV1(BasePin): + valid_drive_strength = set(["X1", "X2", "X3", "X4"]) + drive_strength_prefix = 'X' + + def set_bus_hold(self, hold): + bus_hold_map = { '': '', '0': '', None: '', 'y': 'BUS_HOLD', 'yes': 'BUS_HOLD', '1': 'BUS_HOLD'} + self.bus_hold = bus_hold_map[hold.lower()] + +class PinV2(BasePin): + valid_drive_strength = set(["X1", "X2", "X4", "X6"]) + drive_strength_prefix = 'X' + + def set_bus_hold(self, hold): + bus_hold_map = { '': '', '0': '', None: '', 'y': 'BUS_HOLD', 'yes': 'BUS_HOLD', '1': 'BUS_HOLD'} + self.bus_hold = bus_hold_map[hold.lower()] + +class PinV3(BasePin): + valid_drive_strength = set(["X1", "X2", "X4", "X6"]) + drive_strength_prefix = 'X' + + def set_slew_rate(self, slew): + slew_map = { '': '', None: '', "fast": "FAST", "slow": "SLOW" } + self.slew_rate = slew_map[slew.lower()] + +class PinV4(PinV3): + def set_input_mode(self, mode): + mode_map = { '': '', None: '', 'cmos': '', 'schmitt': 'INPUT_SCHMITT', 'Schmitt': 'INPUT_SCHMITT'} + self.input_mode = mode_map[mode] + +class PinV5(PinV4): + default_drive = 'S0' + valid_drive_strength = set(["S0", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "S12", "S13", "S14", "S15"]) + drive_strength_prefix = 'S' + valid_pupdn = set(["PULL_UP_STRONG", "PULL_UP", "PULL_DOWN", ""]) + + def set_slew_rate(self, slew): + slew_map = { '': '', None: '', "fast": "FAST", "slow": "SLOW", "very fast": "VERY_FAST" } + self.slew_rate = slew_map[slew.lower()] + + +class ReservedPin(object): + def to_pinconfig_line(self, use_enum): + return ['{},'.format(self.to_enum_key() if use_enum else self.to_enum_value())] + + def to_enum_key(self): + return 'GPIOCFG_CFG_DISABLED' + + def to_enum_value(self): + return 'CFG_DISABLED' + +class GPIODomainInfo(object): + def __init__(self, offset, count, reserved): + self.id_offset = offset + self.pin_count = count + self.reserved_pins = reserved + +class GPIODomain(object): + def __init__(self, info, pin_class): + self.id_offset = info.id_offset + self.pin_count = info.pin_count + self.reserved_pins = info.reserved_pins + + # GPIO domains must start and end on 8-pin boundaries + assert self.id_offset % 8 == 0 + if self.pin_count % 8 != 0: + new_pin_count = self.pin_count + 8 - self.pin_count % 8 + self.reserved_pins |= set(range(self.id_offset + self.pin_count, self.id_offset + new_pin_count)) + self.pin_count = new_pin_count + + self.pins = [None] * self.pin_count + + for i in range(self.pin_count): + if not i + self.id_offset in self.reserved_pins: + pin = pin_class(i) + pin.set_bump_name("UNSPECIFIED") + pin.set_net_name("UNSPECIFIED") + pin.set_function("disable") + pin.set_pupd("disable") + pin.set_drive_strength('') + else: + pin = ReservedPin() + self.pins[i] = pin + + def has_pin_id(self, pin_id): + return pin_id >= self.id_offset and pin_id < self.id_offset + self.pin_count + + def get_pin(self, pin_id): + if not self.has_pin_id(pin_id): + raise IndexError + return self.pins[pin_id - self.id_offset] + +class BasePinConfig(object): + # Should be overridden in subclasses to a subclass of BasePin + pin_class = None + domain_info = None + + def __init__(self): + self.domains = [GPIODomain(info, self.pin_class) for info in self.domain_info] + + def get_pin(self, pin_id): + for d in self.domains: + if d.has_pin_id(pin_id): + return d.get_pin(pin_id) + raise IndexError + + def array_size(self, domain_index): + if domain_index == 0: + count_label = '' + else: + count_label = '_{}'.format(domain_index) + return 'GPIO{}_GROUP_COUNT * GPIOPADPINS'.format(count_label) + + def array_declaration(self, array_type, name, domain_index): + if domain_index == 0: + count_label = '' + else: + count_label = '_{}'.format(domain_index) + templ = 'static const {} {}_{}[{}] = {{' + return templ.format(array_type, name, domain_index, self.array_size(domain_index)) + + def to_size_array(self, max_domains): + lines = [] + lines += ['static const uint32_t controller_pins[GPIOC_COUNT] = {'] + for domain_idx in range(min(len(self.domains), max_domains)): + lines += ['\t{},'.format(self.array_size(domain_idx))] + lines += ['};'] + return '\n'.join(lines) + + def to_pinconfig_struct(self, name, array_type, max_domains, use_enum): + lines = [] + + for domain_idx in range(min(len(self.domains), max_domains)): + domain = self.domains[domain_idx] + + pin_matrix = [domain.pins[i].to_pinconfig_line(use_enum) for i in range(domain.pin_count)] + pin_matrix = tab_align(pin_matrix, min_column_tabs={0: 8}) + + lines.append(self.array_declaration(array_type, name, domain_idx)) + + rownum = 0 + for row in pin_matrix: + if (rownum % 8) == 0: + lines.append("\n/* Port {:2} */".format(rownum/8)) + lines.append("\t"+"".join(row)) + rownum += 1 + lines.append("};") + lines.append('') + return "\n".join(lines) + + def to_enum_items(self): + items = set() + + for domain in self.domains: + for pin in domain.pins: + items.add((pin.to_enum_key(), pin.to_enum_value())) + return items + +class BasePinConfigV1(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV1 + +class BasePinConfigV2(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV2 + +class BasePinConfigV3(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV3 + +class BasePinConfigV4(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV4 + +class BasePinConfigV5(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV5 + +class H4APinConfig(BasePinConfigV1): + domain_info = [GPIODomainInfo(offset=0, count=208, reserved=set())] + +class H5PPinConfig(BasePinConfigV2): + domain_info = [GPIODomainInfo(offset=0, count=232, reserved=set())] + +class H5GPinConfig(BasePinConfigV2): + reserved_pins = set(range(14, 32) + range(140, 160) + range(212, 224) + range(241, 248)) + domain_info = [GPIODomainInfo(offset=0, count=248, reserved=reserved_pins)] + +class AlcatrazPinConfig(BasePinConfigV3): + reserved_pins = set(range(24, 32) + range(45, 64) + range(151, 160) + range(173, 192)) + domain_info = [GPIODomainInfo(offset=0, count=195, reserved=reserved_pins)] + +class FijiPinConfig(BasePinConfigV4): + reserved_pins = set(range(16, 32) + range(88, 96) + range(140, 160)) + domain_info = [GPIODomainInfo(offset=0, count=204, reserved=reserved_pins)] + +class CapriPinConfig(BasePinConfigV4): + reserved_pins = set(range(16, 32)) + domain_info = [GPIODomainInfo(offset=0, count=184, reserved=reserved_pins)] + +class M7PinConfig(BasePinConfigV4): + reserved_pins = set(range(10, 32)) + domain_info = [GPIODomainInfo(offset=0, count=138, reserved=reserved_pins), + GPIODomainInfo(offset=160, count=50, reserved=set())] + +class MauiPinConfig(BasePinConfigV4): + reserved_pins = set(range(55, 64) + range(92, 96) + range(152, 160) + range(168, 192)) + domain_info = [GPIODomainInfo(offset=0, count=199, reserved=reserved_pins), + GPIODomainInfo(offset=288, count=28, reserved=set())] + +class ElbaPinConfig(BasePinConfigV5): + reserved_pins = set(range(37, 64) + range(125, 128) + range(142, 160)) + domain_info = [GPIODomainInfo(offset=0, count=220, reserved=reserved_pins), + GPIODomainInfo(offset=288, count=28, reserved=set())] + +class CaymanPinConfig(BasePinConfigV5): + ap_reserved_pins = set(range(55, 64) + range(92, 96) + range(104, 128) + range(155, 160) + range(188, 192)) + aop_reserved_pins = set(range(318, 320) + range(330, 352)) + domain_info = [GPIODomainInfo(offset=0, count=208, reserved=ap_reserved_pins), # AP + GPIODomainInfo(offset=288, count=85, reserved=aop_reserved_pins), # AOP + GPIODomainInfo(offset=256, count=7, reserved=set())] # SEP + output_domains = 2 + +class M8PinConfig(BasePinConfigV5): + ap_reserved_pins = set(range(138, 160)) + aop_reserved_pins = set(range(264, 288)) + domain_info = [GPIODomainInfo(offset=32, count=139, reserved=ap_reserved_pins), # AP + GPIODomainInfo(offset=256, count=96, reserved=aop_reserved_pins), # AOP + GPIODomainInfo(offset=0, count=7, reserved=set()), + GPIODomainInfo(offset=192, count=96, reserved=set())] + output_domains = 2 + +def excel_reader(filename, sheet): + try: + workbook = openpyxl.load_workbook(filename, data_only=True) + except IOError: + sys.stderr.write('Could not open workbook {}\n'.format(filename)) + return None + try: + worksheet = workbook.get_sheet_by_name(sheet) + except KeyError: + sys.stderr.write('Could not open worksheet {}\n'.format(sheet)) + return None + + def row_generator(ws): + def cell_to_str(cell): + value = cell.value + if value is None: + value = '' + return unicode(value) + + for row in ws.rows: + yield [cell_to_str(cell) for cell in row] + + return row_generator(worksheet) + +def try_parse_hex(i): + try: + return int(i, 16) + except ValueError: + return None + +def row_is_empty(row): + for col in row: + if not col is None and len(col.strip()) > 0: + return False + return True + +def row_is_footer(row): + for col in row: + if not col is None: + stripped = col.strip() + if len(stripped) > 0 and stripped != '--': + return False + return True + +class CSVParser(object): + def __init__(self, pinconfig_class, per_target_headers): + self.pinconfig_class = pinconfig_class + self.per_target_headers = per_target_headers + self.targets = per_target_headers.keys() + # Map the standardized name for a property to a list of acceptable names + self.header_name_map = { 'gpio_id': ['gpio id', 'id'], + 'net_name': ['net name', 'net names'], + 'bump_name': ['ball name', 'pad name'], + 'configurable': ['gpio configurable'], + 'drive_strength': ['drive strength', 'drive strength (ma)'], + 'drive_strength_ap': ['drive strength form factor', 'drive strength ap'], + 'drive_strength_dev': ['drive strength dev'], + 'pupd': ['pu/pd', 'pullup/pulldown', 'pull-up/pull-down'], + 'function': ['config', 'dir', 'SecureROM config'], + 'rom': ['rom function']} + + if callable(getattr(self.pinconfig_class.pin_class, 'set_slew_rate', None)): + self.header_name_map['slew_rate'] = ['slew rate', 'gpio_sr'] + self.header_name_map['slew_rate_ap'] = ['slew rate form factor', 'gpio_sr ap'] + self.header_name_map['slew_rate_dev'] = ['slew rate dev', 'gpio_sr dev'] + + if callable(getattr(self.pinconfig_class.pin_class, 'set_bus_hold', None)): + self.header_name_map['bus_hold'] = ['bus hold', 'gpio_bh'] + + if callable(getattr(self.pinconfig_class.pin_class, 'set_input_mode', None)): + self.header_name_map['input_mode'] = ['input mode', 'input select', 'gpio_is'] + + def create_pinconfig(self): + return self.pinconfig_class() + + def parse_version(self, row): + for col in row: + lowercase_col = col.lower() + if 'rev' in lowercase_col or 'version' in lowercase_col or 'ver' in lowercase_col: + return lowercase_col + return None + + def canonical_header(self, header): + for canonical, options in self.header_name_map.iteritems(): + if header.lower() in options: + return canonical + return None + + def find_headers(self, row, rom): + lowercase_row = map(lambda x: x.lower(), row) + columns_per_target = {} + columns_per_config = collections.defaultdict(dict) + per_config_columns = set() + ignore_missing_keys = set() + missing_keys = set() + + # create a mapping from canonical header names to column indices + header_map = {} + for idx in range(len(lowercase_row)): + header = lowercase_row[idx] + canonical = self.canonical_header(header) + if canonical is None: + continue + header_map[canonical] = idx + + # some parameters can be specified per config (ap/dev). figure out + # which if any are done that way for this spreadsheet + config_names = ['ap', 'dev'] + for key in ['drive_strength', 'slew_rate', 'net_name']: + config_to_key_map = {x: '{}_{}'.format(key, x) for x in config_names} + per_config_keys = set(config_to_key_map.values()) + + if per_config_keys <= set(header_map): + assert True, 'error message' # XXX + # used in the loop below to skip over columns that are per config + per_config_columns.update(per_config_keys) + # passed back to the caller for use in parsing rows + for config in config_names: + columns_per_config[config][key] = header_map[config_to_key_map[config]] + ignore_missing_keys.add(key) + elif not per_config_keys.isdisjoint(set(header_map)): + # either all or none of per-config columns should be present + found = ', '.join(sorted(set(header_map) & per_config_keys)) + raise ParseError('All or none of the per-config {} columns must be specified (found {})'.format(key, found)) + else: + # this key isn't per config, so fall through to the logic below, but + # let the missing column checker know the per-config columns won't be present + ignore_missing_keys.update(per_config_keys) + + # If no per-config columns were set, then there's only one configuration. + # Set up the key map accordingly + if len(columns_per_config) == 0: + for key in ['drive_strength', 'slew_rate']: + columns_per_config['all'][key] = header_map[key] + + for target in self.targets: + target_header_name_map = self.per_target_headers[target] + columns_per_target[target] = {} + for key in self.header_name_map.keys(): + if key in per_config_columns: + continue + if key in target_header_name_map: + header = target_header_name_map[key] + # This value has a column per target, so find the per-target header in the row + try: + idx = lowercase_row.index(header.lower()) + except ValueError: + sys.stderr.write('Could not find target {}\'s "{}" column "{}"\n'.format(target, key, header)) + missing_keys.add(key) + columns_per_target[target][key] = idx + else: + # This value has one column for all targets, so find one of the standard headers in the row + for header in self.header_name_map[key]: + if header.lower() in lowercase_row: + idx = lowercase_row.index(header.lower()) + columns_per_target[target][key] = idx + break + else: + missing_keys.add(key) + + if rom: + for key, value in target_header_name_map.iteritems(): + if key == 'function' and value.lower() != 'SecureROM Config'.lower(): + sys.stderr.write('ROM pins should have SecureROM Config column defined\n') + missing_keys.add(key) + + # Some columns are optional + missing_keys -= set(['configurable', 'input_mode']) + # ROM Function is optional if not --rom + if not rom: + missing_keys -= set(['rom']) + # Marked as being unneeded by the per-config column logic + missing_keys -= ignore_missing_keys + + if len(missing_keys) == 0: + missing_keys = None + + return columns_per_target, columns_per_config, missing_keys + + def parse(self, filename, force=False, rom=False, sheet=None): + if filename.endswith('.xlsx'): + if openpyxl is None: + sys.stderr.write('To import Excel sheets, install the openpyxl package\n') + return None, None + if sheet is None: + sys.stderr.write('To import Excel sheets, specify the --sheet option\n') + return None, None + reader = excel_reader(filename, sheet) + if reader is None: + return None, None + else: + reader = csv.reader(open(filename, "rU")) + cnt=0 + row_number = 0 + + # top row has version number + row0 = reader.next() + row_number += 1 + # next non-blank row has headers + while True: + row1 = reader.next() + row_number += 1 + if len(filter(lambda x: len(x.strip()) > 0, row1)) > 0: + break + + version = self.parse_version(row0) + if version is None: + sys.stderr.write('Could not find version in 1st row\n') + return None, None + + try: + columns_per_target, columns_per_config, missing = self.find_headers(row1, rom) + except ParseError as e: + sys.stderr.write('{}\n'.format(e)) + return None, None + + if not missing is None: + missing_options = {"{} ({})".format(col, " or ".join(self.header_name_map[col])) for col in missing} + sys.stderr.write('Missing columns:\n{}\n'.format('\n '.join(missing_options))) + return None, None + + if len(columns_per_config) == 1: + configs = ['all'] + else: + configs = ['ap', 'dev'] + + pinconfigs = {} + for target in self.targets: + pinconfigs[target] = {} + for config in configs: + pinconfigs[target][config] = self.create_pinconfig() + + have_error = False + + for row in reader: + row_number += 1 + if row_is_empty(row): + continue + if row_is_footer(row): + break + + for target, target_columns in columns_per_target.iteritems(): + for config, config_columns in columns_per_config.iteritems(): + columns = {} + columns.update(config_columns) + columns.update(target_columns) + + try: + parsed_props = {prop: row[column].strip() for prop, column in columns.iteritems()} + + # If the optional 'GPIO Configurable' column is present, make sure it says y or yes + try: + if not parsed_props['configurable'].lower() in ('y', 'yes'): + continue + # And then get rid of the column, because the code below can't do anything with it + del parsed_props['configurable'] + except KeyError: + pass + + try: + gpio_id = int(parsed_props['gpio_id']) + except ValueError: + if rom and parsed_props['gpio_id'] == '': + continue + else: + raise ParseError('Invalid GPIO ID "{}"'.format(parsed_props['gpio_id'])) + + pinconfig = pinconfigs[target][config] + try: + pin = pinconfig.get_pin(gpio_id) + except IndexError: + raise ParseError('GPIO ID {} is out of range'.format(gpio_id)) + + if isinstance(pin, ReservedPin): + raise ParseError('GPIO ID {} is reserved pin'.format(gpio_id)) + elif not pin.row_number is None: + raise ParseError('GPIO ID {} redefined (previously defined on row {})'.format(pin.gpio_id, pin.row_number)) + pin.row_number = row_number + + # The setters for all of the columns are predictable based on their name + for prop, value in parsed_props.iteritems(): + if rom: + if prop == 'function': + if parsed_props['rom'].lower() in ('y', 'yes'): + value = parsed_props['function'] + else: + value = 'disabled' + if prop == 'net_name': + if not parsed_props['rom'].lower() in ('y', 'yes'): + value = '' + if prop != 'gpio_id' and prop != 'rom': + setter = getattr(pin, 'set_' + prop) + try: + setter(value) + except KeyError: + raise ParseError('Invalid value "{}" for key {} in column "{}"'.format(value, prop, row1[columns[prop]])) + except ParseError as e: + sys.stderr.write('Row {:3}, Config {:3}: {}\n'.format(row_number, config, e)) + have_error = True + + if not have_error or force: + return version, pinconfigs + else: + return None, None + +def tab_align(data_matrix, tabwidth=8, min_spacing_slack=1, min_column_tabs={}): + def rounduptab(x): + return int(((x + float(tabwidth-1))/tabwidth))*tabwidth + def tab(x): + if x % tabwidth: + return rounduptab(x) + else: + return x+tabwidth + num_cols = max(map(len, data_matrix)) + + # Compute max number of characters seen for each column + max_char_counts = [0]*num_cols + for column, min_width in min_column_tabs.iteritems(): + max_char_counts[column] = min_width*tabwidth + def grow_count(new_row): + for i in range(len(new_row)): + max_char_counts[i] = max(max_char_counts[i], rounduptab(len(new_row[i]) + min_spacing_slack)) + for row in data_matrix: + grow_count(row) + + def pad_tabs(item, required_length): + length = len(item) + tabcount = 0 + while length < required_length: + tabcount+=1 + length=tab(length) + return "%s%s" % (item, '\t'*tabcount) + def format_row(row): + return "".join([pad_tabs(a, b) for (a,b) in zip(row, max_char_counts)]).rstrip() + return [ format_row(x) for x in data_matrix ] + +def print_pinconfigs(target_config_pinconfigs, pinconfig_class, version, radar, copyright, commandline, prefix, rom, header): + array_type = pinconfig_class.array_type + num_domains = len(pinconfig_class.domain_info) + if hasattr(pinconfig_class, 'output_domains'): + if pinconfig_class.output_domains < num_domains: + num_domains = pinconfig_class.output_domains + + targets = sorted(target_config_pinconfigs.keys()) + configs = sorted(target_config_pinconfigs[targets[0]].keys()) + + if header: + pinconfig_prefix = 'gpio_default_cfg' + else: + pinconfig_prefix = 'pinconfig' + + if not prefix is None: + pinconfig_prefix = "{}_{}".format(pinconfig_prefix, prefix) + + if rom: + assert header + assert configs == ['all'] + assert len(targets) == 1 + assert len(configs) == 1 + else: + assert configs == ['ap', 'dev'] or configs == ['all'] + + print "/*" + print " * Copyright (C) {} Apple Inc. All rights reserved.".format(copyright) + print " *" + print " * This document is the property of Apple Inc." + print " * It is considered confidential and proprietary." + print " *" + print " * This document may not be reproduced or transmitted in any form," + print " * in whole or in part, without the express written permission of" + print " * Apple Inc." + print " */" + print "" + print "/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT!" + print " I/O Spreadsheet version: {}".format(version) + print " I/O Spreadsheet tracker: {}".format(radar) + print " Conversion command: {}".format(commandline) + print "*/" + print "" + + if header: + print "#ifndef __PLATFORM_PINCONFIG_H" + print "#define __PLATFORM_PINCONFIG_H" + print "" + else: + print "#include " + print "#include " + print "#include " + print "#include " + print "#include " + if len(targets) > 1: + print "#include " + print "" + + # Create a mapping from enumeration values (8-bit) to the real value for the pin (32-bit) + enum_map = {} + for target in targets: + for config in configs: + enum_items = target_config_pinconfigs[target][config].to_enum_items() + for key, value in enum_items: + if key not in enum_map: + enum_map[key] = value + else: + assert(enum_map[key] == value) + + assert(len(enum_map) < 256) + + # print the enumeration that will be used to index into the map + print 'enum {' + for key in sorted(enum_map.keys()): + print '\t{},'.format(key) + print '};\n\n' + + # print the map itself + print 'static const {} enum_map[] = {{'.format(array_type) + for key in sorted(enum_map.keys()): + print '\t[{}] = {},'.format(key, enum_map[key]) + print '};\n\n' + + # print the pinconfigs, using the enumeration keys as the array items + for target in targets: + for config in configs: + if len(targets) == 1: + if len(configs) == 1: + name = pinconfig_prefix + else: + name = '{}_{}'.format(pinconfig_prefix, config.lower()) + else: + if len(configs) == 1: + name = '{}_{}'.format(pinconfig_prefix, target.lower()) + else: + name = '{}_{}{}'.format(pinconfig_prefix, target.lower(), config.lower()) + print target_config_pinconfigs[target][config].to_pinconfig_struct(name, 'uint8_t', num_domains, not header) + + if header: + print "" + print "#endif /* __PLATFORM_PINCONFIG_H */" + else: + print 'struct pinconfig_map {' + print '\tuint32_t board_id;' + print '\tuint32_t board_id_mask;' + print '\tconst uint8_t *pinconfigs[GPIOC_COUNT];' + print '};' + print '' + print 'static const struct pinconfig_map cfg_map[] = {' + if len(targets) == 1: + if len(configs) == 1: + # just one target and one config, so make a map that spits out the same pinconfig + # for all board IDs + pinconfigs = ', '.join(map(lambda x: '{}_{}'.format(pinconfig_prefix, x), range(num_domains))) + print '\t{{ 0, 0, {{ {} }} }},'.format(pinconfigs) + elif len(configs) == 2: + # One target, but ap/dev configs, so make a map that selects ap/dev based on the lsb + # of the board ID + pinconfigs = ', '.join(map(lambda x: '{}_ap_{}'.format(pinconfig_prefix, x), range(num_domains))) + print '\t{{ 0, 1, {{ {} }} }},'.format(pinconfigs) + pinconfigs = ', '.join(map(lambda x: '{}_dev_{}'.format(pinconfig_prefix, x), range(num_domains))) + print '\t{{ 1, 1, {{ {} }} }},'.format(pinconfigs) + else: + assert False, 'Can\'t handle more than 2 configs per target' + else: + for target in targets: + if len(configs) == 1: + pinconfigs = ', '.join(map(lambda x: '{}_{}_{}'.format(pinconfig_prefix, target.lower(), x), range(num_domains))) + print '\t{{ TARGET_BOARD_ID_{}AP, ~1, {{ {} }} }},'.format(target.upper(), pinconfigs) + elif len(configs) == 2: + pinconfigs = ', '.join(map(lambda x: '{}_{}ap_{}'.format(pinconfig_prefix, target.lower(), x), range(num_domains))) + print '\t{{ TARGET_BOARD_ID_{}AP, ~0, {{ {} }} }},'.format(target.upper(), pinconfigs) + pinconfigs = ', '.join(map(lambda x: '{}_{}dev_{}'.format(pinconfig_prefix, target.lower(), x), range(num_domains))) + print '\t{{ TARGET_BOARD_ID_{}DEV, ~0, {{ {} }} }},'.format(target.upper(), pinconfigs) + else: + assert False, 'Can\'t handle more than 2 configs per target' + print '};' + print '' + print 'static {} *expanded_pinconfigs[GPIOC_COUNT];'.format(array_type) + print '' + print target_config_pinconfigs[targets[0]][configs[0]].to_size_array(num_domains) + print '' + if prefix is None: + print 'const {} * target_get_default_gpio_cfg(uint32_t gpioc)'.format(array_type) + else: + print 'const {} * target_get_{}_gpio_cfg(int gpioc)'.format(array_type, prefix) + print '{' + print '\tstatic const struct pinconfig_map *selected_map = NULL;' + print '' + + print '\t/* Cannot use malloc as chunk manager is yet to be intialized */' + + for domain_idx in range(num_domains): + if domain_idx == 0: + count_label = '' + else: + count_label = '_{}'.format(domain_idx) + print '\tstatic {} pinconfig_buf{}[GPIO{}_GROUP_COUNT * GPIOPADPINS];'.format(array_type, count_label, count_label) + print '\texpanded_pinconfigs[{}] = pinconfig_buf{};'.format(domain_idx, count_label) + + print '' + print '\tASSERT(gpioc < GPIOC_COUNT);' + print '' + print '\tif (selected_map == NULL) {'; + print '\t\tuint32_t board_id = platform_get_board_id();' + print '\t\tfor (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) {' + print '\t\t\tif ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) {' + print '\t\t\t\tselected_map = &cfg_map[i];' + print '\t\t\t\tbreak;' + print '\t\t\t}' + print '\t\t}' + print '' + print '\t\tif (selected_map == NULL)' + print '\t\t\tpanic("no default pinconfig for board id %u", board_id);' + print '' + print '\t\tfor (unsigned i = 0; i < GPIOC_COUNT; i++) {' + print '\t\t\tuint32_t num_pins = controller_pins[i];' + print '' + print '\t\t\tfor (uint32_t j = 0; j < num_pins; j++) {' + print '\t\t\t\tuint8_t enum_key = selected_map->pinconfigs[i][j];' + print '\t\t\t\texpanded_pinconfigs[i][j] = enum_map[enum_key];' + print '\t\t\t}' + print '\t\t}' + print '\t}' + print '' + print '\treturn expanded_pinconfigs[gpioc];' + print '}' + + +def main(): + soc_classes = collections.OrderedDict() + soc_classes['h4a'] = H4APinConfig + soc_classes['h5p'] = H5PPinConfig + soc_classes['h5g'] = H5GPinConfig + soc_classes['alcatraz'] = AlcatrazPinConfig + soc_classes['h6'] = AlcatrazPinConfig + soc_classes['h6p'] = AlcatrazPinConfig + soc_classes['fiji'] = FijiPinConfig + soc_classes['h7p'] = FijiPinConfig + soc_classes['capri'] = CapriPinConfig + soc_classes['h7g'] = CapriPinConfig + soc_classes['m7'] = M7PinConfig + soc_classes['h8p'] = MauiPinConfig + soc_classes['maui'] = MauiPinConfig + soc_classes['h8g'] = ElbaPinConfig + soc_classes['elba'] = ElbaPinConfig + soc_classes['h9p'] = CaymanPinConfig + soc_classes['cayman'] = CaymanPinConfig + soc_classes['m8'] = M8PinConfig + + argparser = argparse.ArgumentParser(description='Converts CSV file to iBoot pinconfig.h format') + argparser.add_argument('--soc', required=True, choices=soc_classes.keys()) + argparser.add_argument('--config-column', type=str, action='append') + argparser.add_argument('--pupd-column', type=str, action='append') + argparser.add_argument('--prefix', type=str, help='prefix for auto-generated variable and function names') + argparser.add_argument('--copyright', type=str, default='YEAR', help='Year(s) to put in copyright notice') + argparser.add_argument('--netname-column', type=str, action='append') + argparser.add_argument('--radar', type=str, help='Link to spreadsheet tracker radar') + argparser.add_argument('--force', action="store_true", help='attempt ouput even when there are parsing errors') + argparser.add_argument('--rom', action="store_true", help='all pins except ROM function pins are disabled') + argparser.add_argument('--header', action="store_true", help='generate a C header file instead of a C source file') + argparser.add_argument('--sheet', default=None, help='sheet to read from when reading Excel files') + argparser.add_argument('filename') + + args = argparser.parse_args() + + pinconfig_class = soc_classes[args.soc] + + per_target_headers = collections.defaultdict(dict) + + if not args.config_column is None: + for item in map(lambda x: x.split(":"), args.config_column): + if len(item) == 1: + target = None + column = item[0] + elif len(item) == 2: + target = item[0].upper() + column = item[1] + else: + sys.stderr.write("Invalid config-column parameter\n") + sys.exit(1) + if 'function' in per_target_headers[target]: + sys.stderr.write("Duplicate target in --config-column: \"{}\"".format(target)) + sys.exit(1) + per_target_headers[target]['function'] = column + + if not args.pupd_column is None: + for item in map(lambda x: x.split(":"), args.pupd_column): + if len(item) == 1: + target = None + column = item[0] + elif len(item) == 2: + target = item[0].upper() + column = item[1] + else: + sys.stderr.write("Invalid pupd-column parameter\n") + sys.exit(1) + if 'pupd' in per_target_headers[target]: + sys.stderr.write("Duplicate target in --pupd-column: \"{}\"".format(target)) + sys.exit(1) + per_target_headers[target]['pupd'] = column + + if not args.netname_column is None: + for item in map(lambda x: x.split(":"), args.netname_column): + if len(item) == 1: + target = None + column = item[0] + elif len(item) == 2: + target = item[0].upper() + column = item[1] + else: + sys.stderr.write("Invalid netname-column parameter\n") + sys.exit(1) + if 'net_name' in per_target_headers[target]: + sys.stderr.write("Duplicate target in --netname-column: \"{}\"".format(target)) + sys.exit(1) + per_target_headers[target]['net_name'] = column + + if not per_target_headers: + per_target_headers[None] = {} + + parser = CSVParser(pinconfig_class, per_target_headers) + version, pinconfigs = parser.parse(args.filename, force=args.force, rom=args.rom, sheet=args.sheet) + if pinconfigs is None: + sys.exit(1) + + def pretty_arg(arg): + if arg == args.filename: + return '' + else: + return pipes.quote(arg) + commandline = './tools/csvtopinconfig.py {}'.format(' '.join(pretty_arg(a) for a in sys.argv[1:])) + + print_pinconfigs(pinconfigs, pinconfig_class=pinconfig_class, version=version, radar=args.radar, copyright=args.copyright, commandline=commandline, prefix=args.prefix, rom=args.rom, header=args.header) + +if __name__ == '__main__': + main() diff --git a/tools/gcovr b/tools/gcovr new file mode 100644 index 0000000..387e626 --- /dev/null +++ b/tools/gcovr @@ -0,0 +1,2185 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# +# A report generator for gcov 3.4 +# +# This routine generates a format that is similar to the format generated +# by the Python coverage.py module. This code is similar to the +# data processing performed by lcov's geninfo command. However, we +# don't worry about parsing the *.gcna files, and backwards compatibility for +# older versions of gcov is not supported. +# +# Outstanding issues +# - verify that gcov 3.4 or newer is being used +# - verify support for symbolic links +# +# gcovr is a FAST project. For documentation, bug reporting, and +# updates, see https://software.sandia.gov/trac/fast/wiki/gcovr +# +# _________________________________________________________________________ +# +# Gcovr: A parsing and reporting tool for gcov +# Copyright (c) 2013 Sandia Corporation. +# This software is distributed under the BSD License. +# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +# the U.S. Government retains certain rights in this software. +# For more information, see the README.md file. +# _________________________________________________________________________ +# +# $Revision$ +# $Date$ +# + +try: + import html +except: + import cgi as html +import copy +import os +import re +import subprocess +import sys +import time +import xml.dom.minidom +import datetime +import posixpath + +from optparse import OptionParser +from string import Template +from os.path import normpath + +medium_coverage = 75.0 +high_coverage = 90.0 +low_color = "LightPink" +medium_color = "#FFFF55" +high_color = "LightGreen" +covered_color = "LightGreen" +uncovered_color = "LightPink" + +__version__ = "3.3-prerelease" +src_revision = "$Revision$" + +output_re = re.compile("[Cc]reating [`'](.*)'$") +source_re = re.compile("[Cc]annot open (source|graph) file") + +starting_dir = os.getcwd() + +exclude_line_flag = "_EXCL_" +exclude_line_pattern = re.compile('([GL]COVR?)_EXCL_(LINE|START|STOP)') + +c_style_comment_pattern = re.compile('/\*.*?\*/') +cpp_style_comment_pattern = re.compile('//.*?$') + + +def version_str(): + ans = __version__ + m = re.match('\$Revision:\s*(\S+)\s*\$', src_revision) + if m: + ans = ans + " (r%s)" % (m.group(1)) + return ans + + +# +# Container object for coverage statistics +# +class CoverageData(object): + + def __init__( + self, fname, uncovered, uncovered_exceptional, covered, branches, + noncode): + self.fname = fname + # Shallow copies are cheap & "safe" because the caller will + # throw away their copies of covered & uncovered after calling + # us exactly *once* + self.uncovered = copy.copy(uncovered) + self.uncovered_exceptional = copy.copy(uncovered_exceptional) + self.covered = copy.copy(covered) + self.noncode = copy.copy(noncode) + # But, a deep copy is required here + self.all_lines = copy.deepcopy(uncovered) + self.all_lines.update(uncovered_exceptional) + self.all_lines.update(covered.keys()) + self.branches = copy.deepcopy(branches) + + def update( + self, uncovered, uncovered_exceptional, covered, branches, + noncode): + self.all_lines.update(uncovered) + self.all_lines.update(uncovered_exceptional) + self.all_lines.update(covered.keys()) + self.uncovered.update(uncovered) + self.uncovered_exceptional.update(uncovered_exceptional) + self.noncode.intersection_update(noncode) + for k in covered.keys(): + self.covered[k] = self.covered.get(k, 0) + covered[k] + for k in branches.keys(): + for b in branches[k]: + d = self.branches.setdefault(k, {}) + d[b] = d.get(b, 0) + branches[k][b] + self.uncovered.difference_update(self.covered.keys()) + self.uncovered_exceptional.difference_update(self.covered.keys()) + + def uncovered_str(self, exceptional): + if options.show_branch: + # + # Don't do any aggregation on branch results + # + tmp = [] + for line in self.branches.keys(): + for branch in self.branches[line]: + if self.branches[line][branch] == 0: + tmp.append(line) + break + tmp.sort() + return ",".join([str(x) for x in tmp]) or "" + + if exceptional: + tmp = list(self.uncovered_exceptional) + else: + tmp = list(self.uncovered) + if len(tmp) == 0: + return "" + + # + # Walk through the uncovered lines in sorted order. + # Find blocks of consecutive uncovered lines, and return + # a string with that information. + # + tmp.sort() + first = None + last = None + ranges = [] + for item in tmp: + if last is None: + first = item + last = item + elif item == (last + 1): + last = item + else: + # + # Should we include noncode lines in the range of lines + # to be covered??? This simplifies the ranges summary, but it + # provides a counterintuitive listing. + # + #if len(self.noncode.intersection(range(last+1,item))) \ + # == item - last - 1: + # last = item + # continue + # + if first == last: + ranges.append(str(first)) + else: + ranges.append(str(first) + "-" + str(last)) + first = item + last = item + if first == last: + ranges.append(str(first)) + else: + ranges.append(str(first) + "-" + str(last)) + return ",".join(ranges) + + def coverage(self): + if options.show_branch: + total = 0 + cover = 0 + for line in self.branches.keys(): + for branch in self.branches[line].keys(): + total += 1 + cover += self.branches[line][branch] > 0 and 1 or 0 + else: + total = len(self.all_lines) + cover = len(self.covered) + + percent = total and str(int(100.0 * cover / total)) or "--" + return (total, cover, percent) + + def summary(self): + tmp = options.root_filter.sub('', self.fname) + if not self.fname.endswith(tmp): + # Do no truncation if the filter does not start matching at + # the beginning of the string + tmp = self.fname + tmp = tmp.ljust(40) + if len(tmp) > 40: + tmp = tmp + "\n" + " " * 40 + + (total, cover, percent) = self.coverage() + uncovered_lines = self.uncovered_str(False) + if not options.show_branch: + t = self.uncovered_str(True) + if len(t): + uncovered_lines += " [* " + t + "]" + return (total, cover, + tmp + str(total).rjust(8) + str(cover).rjust(8) + + percent.rjust(6) + "% " + uncovered_lines) + + +def resolve_symlinks(orig_path): + """ + Return the normalized absolute path name with all symbolic links resolved + """ + return os.path.realpath(orig_path) + # WEH - why doesn't os.path.realpath() suffice here? + # + drive, tmp = os.path.splitdrive(os.path.abspath(orig_path)) + if not drive: + drive = os.path.sep + parts = tmp.split(os.path.sep) + actual_path = [drive] + while parts: + actual_path.append(parts.pop(0)) + if not os.path.islink(os.path.join(*actual_path)): + continue + actual_path[-1] = os.readlink(os.path.join(*actual_path)) + tmp_drive, tmp_path = os.path.splitdrive( + resolve_symlinks(os.path.join(*actual_path))) + if tmp_drive: + drive = tmp_drive + actual_path = [drive] + tmp_path.split(os.path.sep) + return os.path.join(*actual_path) + + +# +# Class that creates path aliases +# +class PathAliaser(object): + + def __init__(self): + self.aliases = {} + self.master_targets = set() + self.preferred_name = {} + + def path_startswith(self, path, base): + return path.startswith(base) and ( + len(base) == len(path) or path[len(base)] == os.path.sep) + + def master_path(self, path): + match_found = False + while True: + for base, alias in self.aliases.items(): + if self.path_startswith(path, base): + path = alias + path[len(base):] + match_found = True + break + for master_base in self.master_targets: + if self.path_startswith(path, master_base): + return path, master_base, True + if match_found: + sys.stderr.write( + "(ERROR) violating fundamental assumption while walking " + "directory tree.\n\tPlease report this to the gcovr " + "developers.\n") + return path, None, match_found + + def unalias_path(self, path): + path = resolve_symlinks(path) + path, master_base, known_path = self.master_path(path) + if not known_path: + return path + # Try and resolve the preferred name for this location + if master_base in self.preferred_name: + return self.preferred_name[master_base] + path[len(master_base):] + return path + + def add_master_target(self, master): + self.master_targets.add(master) + + def add_alias(self, target, master): + self.aliases[target] = master + + def set_preferred(self, master, preferred): + self.preferred_name[master] = preferred + +aliases = PathAliaser() + + +# This is UGLY. Here's why: UNIX resolves symbolic links by walking the +# entire directory structure. What that means is that relative links +# are always relative to the actual directory inode, and not the +# "virtual" path that the user might have traversed (over symlinks) on +# the way to that directory. Here's the canonical example: +# +# a / b / c / testfile +# a / d / e --> ../../a/b +# m / n --> /a +# x / y / z --> /m/n/d +# +# If we start in "y", we will see the following directory structure: +# y +# |-- z +# |-- e +# |-- c +# |-- testfile +# +# The problem is that using a simple traversal based on the Python +# documentation: +# +# (os.path.join(os.path.dirname(path), os.readlink(result))) +# +# will not work: we will see a link to /m/n/d from /x/y, but completely +# miss the fact that n is itself a link. If we then naively attempt to +# apply the "c" relative link, we get an intermediate path that looks +# like "/m/n/d/e/../../a/b", which would get normalized to "/m/n/a/b"; a +# nonexistant path. The solution is that we need to walk the original +# path, along with the full path of all links 1 directory at a time and +# check for embedded symlinks. +# +# +# NB: Users have complained that this code causes a performance issue. +# I have replaced this logic with os.walk(), which works for Python >= 2.6 +# +def link_walker(path): + if sys.version_info >= (2, 6): + for root, dirs, files in os.walk( + os.path.abspath(path), followlinks=True + ): + yield (os.path.abspath(os.path.realpath(root)), dirs, files) + else: + targets = [os.path.abspath(path)] + while targets: + target_dir = targets.pop(0) + actual_dir = resolve_symlinks(target_dir) + #print "target dir: %s (%s)" % (target_dir, actual_dir) + master_name, master_base, visited = aliases.master_path(actual_dir) + if visited: + #print " ...root already visited as %s" % master_name + aliases.add_alias(target_dir, master_name) + continue + if master_name != target_dir: + aliases.set_preferred(master_name, target_dir) + aliases.add_alias(target_dir, master_name) + aliases.add_master_target(master_name) + #print " ...master name = %s" % master_name + #print " ...walking %s" % target_dir + for root, dirs, files in os.walk(target_dir, topdown=True): + #print " ...reading %s" % root + for d in dirs: + tmp = os.path.abspath(os.path.join(root, d)) + #print " ...checking %s" % tmp + if os.path.islink(tmp): + #print " ...buffering link %s" % tmp + targets.append(tmp) + yield (root, dirs, files) + + +def search_file(expr, path): + """ + Given a search path, recursively descend to find files that match a + regular expression. + """ + ans = [] + pattern = re.compile(expr) + if path is None or path == ".": + path = os.getcwd() + elif not os.path.exists(path): + raise IOError("Unknown directory '" + path + "'") + for root, dirs, files in link_walker(path): + for name in files: + if pattern.match(name): + name = os.path.join(root, name) + if os.path.islink(name): + ans.append(os.path.abspath(os.readlink(name))) + else: + ans.append(os.path.abspath(name)) + return ans + + +# +# Get the list of datafiles in the directories specified by the user +# +def get_datafiles(flist, options): + allfiles = set() + for dir_ in flist: + if options.gcov_files: + if options.verbose: + sys.stdout.write( + "Scanning directory %s for gcov files...\n" % (dir_, ) + ) + files = search_file(".*\.gcov$", dir_) + gcov_files = [file for file in files if file.endswith('gcov')] + if options.verbose: + sys.stdout.write( + "Found %d files (and will process %d)\n" % + (len(files), len(gcov_files)) + ) + allfiles.update(gcov_files) + else: + if options.verbose: + sys.stdout.write( + "Scanning directory %s for gcda/gcno files...\n" % (dir_, ) + ) + files = search_file(".*\.gc(da|no)$", dir_) + # gcno files will *only* produce uncovered results; however, + # that is useful information for the case where a compilation + # unit is never actually exercised by the test code. So, we + # will process gcno files, but ONLY if there is no corresponding + # gcda file. + gcda_files = [ + filenm for filenm in files if filenm.endswith('gcda') + ] + tmp = set(gcda_files) + gcno_files = [ + filenm for filenm in files if + filenm.endswith('gcno') and filenm[:-2] + 'da' not in tmp + ] + if options.verbose: + sys.stdout.write( + "Found %d files (and will process %d)\n" % + (len(files), len(gcda_files) + len(gcno_files))) + allfiles.update(gcda_files) + allfiles.update(gcno_files) + return allfiles + + +# +# Process a single gcov datafile +# +def process_gcov_data(data_fname, covdata, options): + INPUT = open(data_fname, "r") + # + # Get the filename + # + line = INPUT.readline() + segments = line.split(':', 3) + if len(segments) != 4 or not \ + segments[2].lower().strip().endswith('source'): + raise RuntimeError( + 'Fatal error parsing gcov file, line 1: \n\t"%s"' % line.rstrip() + ) + currdir = os.getcwd() + os.chdir(starting_dir) + if sys.version_info >= (2, 6): + fname = os.path.abspath((segments[-1]).strip()) + else: + fname = aliases.unalias_path(os.path.abspath((segments[-1]).strip())) + os.chdir(currdir) + if options.verbose: + sys.stdout.write("Parsing coverage data for file %s\n" % fname) + # + # Return if the filename does not match the filter + # + filtered_fname = None + for i in range(0, len(options.filter)): + if options.filter[i].match(fname): + filtered_fname = options.root_filter.sub('', fname) + break + if filtered_fname is None: + if options.verbose: + sys.stdout.write(" Filtering coverage data for file %s\n" % fname) + return + # + # Return if the filename matches the exclude pattern + # + for exc in options.exclude: + if (filtered_fname is not None and exc.match(filtered_fname)) or \ + exc.match(fname) or \ + exc.match(os.path.abspath(fname)): + if options.verbose: + sys.stdout.write( + " Excluding coverage data for file %s\n" % fname + ) + return + # + # Parse each line, and record the lines + # that are uncovered + # + excluding = [] + noncode = set() + uncovered = set() + uncovered_exceptional = set() + covered = {} + branches = {} + #first_record=True + lineno = 0 + last_code_line = "" + last_code_lineno = 0 + last_code_line_excluded = False + for line in INPUT: + segments = line.split(":", 2) + #print "\t","Y", segments + tmp = segments[0].strip() + if len(segments) > 1: + try: + lineno = int(segments[1].strip()) + except: + pass # keep previous line number! + + if exclude_line_flag in line: + excl_line = False + for header, flag in exclude_line_pattern.findall(line): + if flag == 'START': + excluding.append((header, lineno)) + elif flag == 'STOP': + if excluding: + _header, _line = excluding.pop() + if _header != header: + sys.stderr.write( + "(WARNING) %s_EXCL_START found on line %s " + "was terminated by %s_EXCL_STOP on line %s, " + "when processing %s\n" + % (_header, _line, header, lineno, fname) + ) + else: + sys.stderr.write( + "(WARNING) mismatched coverage exclusion flags.\n" + "\t%s_EXCL_STOP found on line %s without " + "corresponding %s_EXCL_START, when processing %s\n" + % (header, lineno, header, fname) + ) + elif flag == 'LINE': + # We buffer the line exclusion so that it is always + # the last thing added to the exclusion list (and so + # only ONE is ever added to the list). This guards + # against cases where puts a _LINE and _START (or + # _STOP) on the same line... it also guards against + # duplicate _LINE flags. + excl_line = True + if excl_line: + excluding.append(False) + + is_code_statement = False + if tmp[0] == '-' or (excluding and tmp[0] in "#=0123456789"): + is_code_statement = True + code = segments[2].strip() + # remember certain non-executed lines + if excluding or len(code) == 0 or code == "{" or code == "}" or \ + code.startswith("//") or code == 'else': + noncode.add(lineno) + elif tmp[0] == '#': + is_code_statement = True + uncovered.add(lineno) + elif tmp[0] == '=': + is_code_statement = True + uncovered_exceptional.add(lineno) + elif tmp[0] in "0123456789": + is_code_statement = True + covered[lineno] = int(segments[0].strip()) + elif tmp.startswith('branch'): + exclude_branch = False + if options.exclude_unreachable_branches and \ + lineno == last_code_lineno: + if last_code_line_excluded: + exclude_branch = True + exclude_reason = "marked with exclude pattern" + else: + code = last_code_line + code = re.sub(cpp_style_comment_pattern, '', code) + code = re.sub(c_style_comment_pattern, '', code) + code = code.strip() + code_nospace = code.replace(' ', '') + exclude_branch = \ + code in ['', '{', '}'] or code_nospace == '{}' + exclude_reason = "detected as compiler-generated code" + + if exclude_branch: + if options.verbose: + sys.stdout.write( + "Excluding unreachable branch on line %d " + "in file %s (%s).\n" + % (lineno, fname, exclude_reason) + ) + else: + fields = line.split() + try: + count = int(fields[3]) + except: + count = 0 + branches.setdefault(lineno, {})[int(fields[1])] = count + elif tmp.startswith('call'): + pass + elif tmp.startswith('function'): + pass + elif tmp[0] == 'f': + pass + #if first_record: + #first_record=False + #uncovered.add(prev) + #if prev in uncovered: + #tokens=re.split('[ \t]+',tmp) + #if tokens[3] != "0": + #uncovered.remove(prev) + #prev = int(segments[1].strip()) + #first_record=True + else: + sys.stderr.write( + "(WARNING) Unrecognized GCOV output: '%s'\n" + "\tThis is indicitive of a gcov output parse error.\n" + "\tPlease report this to the gcovr developers." % tmp + ) + + # save the code line to use it later with branches + if is_code_statement: + last_code_line = "".join(segments[2:]) + last_code_lineno = lineno + last_code_line_excluded = False + if excluding: + last_code_line_excluded = True + + # clear the excluding flag for single-line excludes + if excluding and not excluding[-1]: + excluding.pop() + + ##print 'uncovered',uncovered + ##print 'covered',covered + ##print 'branches',branches + ##print 'noncode',noncode + # + # If the file is already in covdata, then we + # remove lines that are covered here. Otherwise, + # initialize covdata + # + if not fname in covdata: + covdata[fname] = CoverageData( + fname, uncovered, uncovered_exceptional, covered, branches, noncode + ) + else: + covdata[fname].update( + uncovered, uncovered_exceptional, covered, branches, noncode + ) + INPUT.close() + + for header, line in excluding: + sys.stderr.write("(WARNING) The coverage exclusion region start flag " + "%s_EXCL_START\n\ton line %d did not have " + "corresponding %s_EXCL_STOP flag\n\t in file %s.\n" + % (header, line, header, fname)) + + +# +# Process a datafile (generated by running the instrumented application) +# and run gcov with the corresponding arguments +# +# This is trickier than it sounds: The gcda/gcno files are stored in the +# same directory as the object files; however, gcov must be run from the +# same directory where gcc/g++ was run. Normally, the user would know +# where gcc/g++ was invoked from and could tell gcov the path to the +# object (and gcda) files with the --object-directory command. +# Unfortunately, we do everything backwards: gcovr looks for the gcda +# files and then has to infer the original gcc working directory. +# +# In general, (but not always) we can assume that the gcda file is in a +# subdirectory of the original gcc working directory, so we will first +# try ".", and on error, move up the directory tree looking for the +# correct working directory (letting gcov's own error codes dictate when +# we hit the right directory). This covers 90+% of the "normal" cases. +# The exception to this is if gcc was invoked with "-o ../[...]" (i.e., +# the object directory was a peer (not a parent/child) of the cwd. In +# this case, things are really tough. We accept an argument +# (--object-directory) that SHOULD BE THE SAME as the one povided to +# gcc. We will then walk that path (backwards) in the hopes of +# identifying the original gcc working directory (there is a bit of +# trial-and-error here) +# +def process_datafile(filename, covdata, options): + #print "" + #print "PROCESS",filename + # + # Launch gcov + # + abs_filename = os.path.abspath(filename) + dirname, fname = os.path.split(abs_filename) + #(name,ext) = os.path.splitext(base) + + potential_wd = [] + errors = [] + Done = False + + if options.objdir: + #print "X - objdir" + src_components = abs_filename.split(os.sep) + components = normpath(options.objdir).split(os.sep) + idx = 1 + while idx <= len(components): + if idx > len(src_components): + break + if components[-1 * idx] != src_components[-1 * idx]: + break + idx += 1 + if idx > len(components): + pass # a parent dir; the normal process will find it + elif components[-1 * idx] == '..': + # NB: os.path.join does not re-add leading '/' characters!?! + dirs = [ + os.path.sep.join(src_components[:len(src_components) - idx]) + ] + while idx <= len(components) and components[-1 * idx] == '..': + tmp = [] + for d in dirs: + for f in os.listdir(d): + x = os.path.join(d, f) + if os.path.isdir(x): + tmp.append(x) + dirs = tmp + idx += 1 + potential_wd = dirs + else: + if components[0] == '': + # absolute path + tmp = [options.objdir] + else: + # relative path: check relative to both the cwd and the + # gcda file + tmp = [ + os.path.join(x, options.objdir) for x in + [os.path.dirname(abs_filename), os.getcwd()] + ] + potential_wd = [ + testdir for testdir in tmp if os.path.isdir(testdir) + ] + if len(potential_wd) == 0: + errors.append("ERROR: cannot identify the location where GCC " + "was run using --object-directory=%s\n" % + options.objdir) + # Revert to the normal + #sys.exit(1) + + # no objdir was specified (or it was a parent dir); walk up the dir tree + if len(potential_wd) == 0: + potential_wd.append(root_dir) + #print "X - potential_wd", root_dir + wd = os.path.split(abs_filename)[0] + while True: + potential_wd.append(wd) + wd = os.path.split(wd)[0] + if wd == potential_wd[-1]: + # + # Stop at the root of the file system + # + break + + cmd = [ + options.gcov_cmd, abs_filename, + "--branch-counts", "--branch-probabilities", "--preserve-paths", + '--object-directory', dirname + ] + + # NB: Currently, we will only parse English output + env = dict(os.environ) + env['LC_ALL'] = 'en_US' + + #print "HERE", potential_wd + while len(potential_wd) > 0 and not Done: + # NB: either len(potential_wd) == 1, or all entires are absolute + # paths, so we don't have to chdir(starting_dir) at every + # iteration. + + # + # Iterate from the end of the potential_wd list, which is the root + # directory + # + dir_ = potential_wd.pop(0) + #print "X DIR:", dir_ + os.chdir(dir_) + + if options.verbose: + sys.stdout.write( + "Running gcov: '%s' in '%s'\n" % (' '.join(cmd), os.getcwd()) + ) + out, err = subprocess.Popen( + cmd, env=env, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + out = out.decode('utf-8') + err = err.decode('utf-8') + + # find the files that gcov created + gcov_files = {'active' : [], 'filter' : [], 'exclude' : []} + for line in out.splitlines(): + found = output_re.search(line.strip()) + if found is not None: + fname = found.group(1) + if not options.gcov_filter.match(fname): + if options.verbose: + sys.stdout.write("Filtering gcov file %s\n" % fname) + gcov_files['filter'].append(fname) + continue + exclude = False + for exc in options.gcov_exclude: + if exc.match(options.gcov_filter.sub('', fname)) or \ + exc.match(fname) or \ + exc.match(os.path.abspath(fname)): + exclude = True + break + if not exclude: + gcov_files['active'].append(fname) + elif options.verbose: + sys.stdout.write("Excluding gcov file %s\n" % fname) + gcov_files['exclude'].append(fname) + + #print "HERE", err, "XXX", source_re.search(err) + if source_re.search(err): + # + # gcov tossed errors: try the next potential_wd + # + errors.append(err) + else: + # + # Process *.gcov files + # + for fname in gcov_files['active']: + process_gcov_data(fname, covdata, options) + Done = True + + if not options.keep: + for group in gcov_files.values(): + for fname in group: + if os.path.exists(fname): + # Only remove files that actually exist. + os.remove(fname) + + os.chdir(starting_dir) + if options.delete: + if not abs_filename.endswith('gcno'): + os.remove(abs_filename) + + if not Done: + sys.stderr.write( + "(WARNING) GCOV produced the following errors processing %s:\n" + "\t %s" + "\t(gcovr could not infer a working directory that resolved it.)\n" + % (filename, "\t ".join(errors)) + ) + + +# +# Process Already existing gcov files +# +def process_existing_gcov_file(filename, covdata, options): + if not options.gcov_filter.match(filename): + if options.verbose: + sys.stdout.write("Filtering gcov file %s\n" % filename) + return + + for exc in options.gcov_exclude: + if exc.match(options.gcov_filter.sub('', filename)) or \ + exc.match(filename) or \ + exc.match(os.path.abspath(filename)): + if options.verbose: + sys.stdout.write("Excluding gcov file %s\n" % filename) + return + + process_gcov_data(filename, covdata, options) + + if not options.keep: + if os.path.exists(filename): + # Only remove files that actually exist. + os.remove(filename) + + +# +# Produce the classic gcovr text report +# +def print_text_report(covdata): + def _num_uncovered(key): + (total, covered, percent) = covdata[key].coverage() + return total - covered + + def _percent_uncovered(key): + (total, covered, percent) = covdata[key].coverage() + if covered: + return -1.0 * covered / total + else: + return total or 1e6 + + def _alpha(key): + return key + + if options.output: + OUTPUT = open(options.output, 'w') + else: + OUTPUT = sys.stdout + total_lines = 0 + total_covered = 0 + + # Header + OUTPUT.write("-" * 78 + '\n') + OUTPUT.write(" " * 27 + "GCC Code Coverage Report\n") + OUTPUT.write("Directory: " + options.root + "\n") + OUTPUT.write("-" * 78 + '\n') + a = options.show_branch and "Branches" or "Lines" + b = options.show_branch and "Taken" or "Exec" + c = "Missing" + OUTPUT.write( + "File".ljust(40) + a.rjust(8) + b.rjust(8) + " Cover " + c + "\n" + ) + OUTPUT.write("-" * 78 + '\n') + + # Data + keys = list(covdata.keys()) + keys.sort( + key=options.sort_uncovered and _num_uncovered or + options.sort_percent and _percent_uncovered or _alpha + ) + for key in keys: + (t, n, txt) = covdata[key].summary() + total_lines += t + total_covered += n + OUTPUT.write(txt + '\n') + + # Footer & summary + OUTPUT.write("-" * 78 + '\n') + percent = total_lines and str(int(100.0 * total_covered / total_lines)) \ + or "--" + OUTPUT.write( + "TOTAL".ljust(40) + str(total_lines).rjust(8) + + str(total_covered).rjust(8) + str(percent).rjust(6) + "%" + '\n' + ) + OUTPUT.write("-" * 78 + '\n') + + # Close logfile + if options.output: + OUTPUT.close() + + +# +# Prints a small report to the standard output +# +def print_summary(covdata): + lines_total = 0 + lines_covered = 0 + branches_total = 0 + branches_covered = 0 + + keys = list(covdata.keys()) + + for key in keys: + options.show_branch = False + (t, n, txt) = covdata[key].coverage() + lines_total += t + lines_covered += n + + options.show_branch = True + (t, n, txt) = covdata[key].coverage() + branches_total += t + branches_covered += n + + percent = lines_total and (100.0 * lines_covered / lines_total) + percent_branches = branches_total and \ + (100.0 * branches_covered / branches_total) + + lines_out = "lines: %0.1f%% (%s out of %s)\n" % ( + percent, lines_covered, lines_total + ) + branches_out = "branches: %0.1f%% (%s out of %s)\n" % ( + percent_branches, branches_covered, branches_total + ) + + sys.stdout.write(lines_out) + sys.stdout.write(branches_out) + +# +# CSS declarations for the HTML output +# +css = Template(''' + body + { + color: #000000; + background-color: #FFFFFF; + } + + /* Link formats: use maroon w/underlines */ + a:link + { + color: navy; + text-decoration: underline; + } + a:visited + { + color: maroon; + text-decoration: underline; + } + a:active + { + color: navy; + text-decoration: underline; + } + + /*** TD formats ***/ + td + { + font-family: sans-serif; + } + td.title + { + text-align: center; + padding-bottom: 10px; + font-size: 20pt; + font-weight: bold; + } + + /* TD Header Information */ + td.headerName + { + text-align: right; + color: black; + padding-right: 6px; + font-weight: bold; + vertical-align: top; + white-space: nowrap; + } + td.headerValue + { + text-align: left; + color: blue; + font-weight: bold; + white-space: nowrap; + } + td.headerTableEntry + { + text-align: right; + color: black; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: LightBlue; + } + td.headerValueLeg + { + text-align: left; + color: black; + font-size: 80%; + white-space: nowrap; + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + } + + /* Color of horizontal ruler */ + td.hr + { + background-color: navy; + height:3px; + } + /* Footer format */ + td.footer + { + text-align: center; + padding-top: 3px; + font-family: sans-serif; + } + + /* Coverage Table */ + + td.coverTableHead + { + text-align: center; + color: white; + background-color: SteelBlue; + font-family: sans-serif; + font-size: 120%; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; + } + td.coverFile + { + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: black; + background-color: LightBlue; + font-family: monospace; + font-weight: bold; + font-size: 110%; + } + td.coverBar + { + padding-left: 10px; + padding-right: 10px; + background-color: LightBlue; + } + td.coverBarOutline + { + background-color: white; + } + td.coverValue + { + padding-top: 2px; + text-align: right; + padding-left: 10px; + padding-right: 10px; + font-family: sans-serif; + white-space: nowrap; + font-weight: bold; + } + + /* Link Details */ + a.detail:link + { + color: #B8D0FF; + font-size:80%; + } + a.detail:visited + { + color: #B8D0FF; + font-size:80%; + } + a.detail:active + { + color: #FFFFFF; + font-size:80%; + } + + .graphcont{ + color:#000; + font-weight:700; + float:left + } + + .graph{ + float:left; + background-color: white; + position:relative; + width:280px; + padding:0 + } + + .graph .bar{ + display:block; + position:relative; + border:black 1px solid; + text-align:center; + color:#fff; + height:10px; + font-family:Arial,Helvetica,sans-serif; + font-size:12px; + line-height:1.9em + } + + .graph .bar span{ + position:absolute; + left:1em + } + + td.coveredLine, + span.coveredLine + { + background-color: ${covered_color}!important; + } + + td.uncoveredLine, + span.uncoveredLine + { + background-color: ${uncovered_color}!important; + } + + .linecount + { + border-right: 1px gray solid; + background-color: lightgray; + } + + .src + { + padding-left: 12px; + } + + .srcHeader + { + font-family: monospace; + font-weight: bold; + } + + pre + { + height : 15px; + margin-top: 0; + margin-bottom: 0; + } + + .lineno + { + background-color: #EFE383; + border-right: 1px solid #BBB15F; + } +''') + +# +# A string template for the root HTML output +# +root_page = Template(''' + + + + + ${HEAD} + + + + + + + + + + + + + + +
GCC Code Coverage Report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Directory:${DIRECTORY}ExecTotalCoverage
Date:${DATE}Lines:${LINES_EXEC}${LINES_TOTAL}${LINES_COVERAGE} %
Legend: + low: < ${COVERAGE_MED} % + medium: >= ${COVERAGE_MED} % + high: >= ${COVERAGE_HIGH} % + Branches:${BRANCHES_EXEC}${BRANCHES_TOTAL}${BRANCHES_COVERAGE} %
+
+ +
+ + + + + + + + + + + + + + + + ${ROWS} + + + + + + + + + +

FileLinesBranches

+
+ + + + +
+
+ + + + +''') + +# +# A string template for the source file HTML output +# +source_page = Template(''' + + + + + ${HEAD} + + + + + + + + + + + + + + +
GCC Code Coverage Report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Directory:${DIRECTORY}ExecTotalCoverage
File:${FILENAME}Lines:${LINES_EXEC}${LINES_TOTAL}${LINES_COVERAGE} %
Date:${DATE}Branches:${BRANCHES_EXEC}${BRANCHES_TOTAL}${BRANCHES_COVERAGE} %
+
+ +
+ + + + + + + + ${ROWS} + +
LineExecSource
+
+ + + + +
+
+ + + + +''') + + +# +# Produce an HTML report +# +def print_html_report(covdata, details): + def _num_uncovered(key): + (total, covered, percent) = covdata[key].coverage() + return total - covered + + def _percent_uncovered(key): + (total, covered, percent) = covdata[key].coverage() + if covered: + return -1.0 * covered / total + else: + return total or 1e6 + + def _alpha(key): + return key + + if options.output is None: + details = False + data = {} + data['HEAD'] = "Head" + data['VERSION'] = version_str() + data['TIME'] = str(int(time.time())) + data['DATE'] = datetime.date.today().isoformat() + data['ROWS'] = [] + data['low_color'] = low_color + data['medium_color'] = medium_color + data['high_color'] = high_color + data['COVERAGE_MED'] = medium_coverage + data['COVERAGE_HIGH'] = high_coverage + data['CSS'] = css.substitute( + low_color=low_color, medium_color=medium_color, high_color=high_color, + covered_color=covered_color, uncovered_color=uncovered_color + ) + data['DIRECTORY'] = '' + + branchTotal = 0 + branchCovered = 0 + options.show_branch = True + for key in covdata.keys(): + (total, covered, percent) = covdata[key].coverage() + branchTotal += total + branchCovered += covered + data['BRANCHES_EXEC'] = str(branchCovered) + data['BRANCHES_TOTAL'] = str(branchTotal) + coverage = 0.0 if branchTotal == 0 else \ + round(100.0 * branchCovered / branchTotal, 1) + data['BRANCHES_COVERAGE'] = str(coverage) + if coverage < medium_coverage: + data['BRANCHES_COLOR'] = low_color + elif coverage < high_coverage: + data['BRANCHES_COLOR'] = medium_color + else: + data['BRANCHES_COLOR'] = high_color + + lineTotal = 0 + lineCovered = 0 + options.show_branch = False + for key in covdata.keys(): + (total, covered, percent) = covdata[key].coverage() + lineTotal += total + lineCovered += covered + data['LINES_EXEC'] = str(lineCovered) + data['LINES_TOTAL'] = str(lineTotal) + coverage = 0.0 if lineTotal == 0 else \ + round(100.0 * lineCovered / lineTotal, 1) + data['LINES_COVERAGE'] = str(coverage) + if coverage < medium_coverage: + data['LINES_COLOR'] = low_color + elif coverage < high_coverage: + data['LINES_COLOR'] = medium_color + else: + data['LINES_COLOR'] = high_color + + # Generate the coverage output (on a per-package basis) + #source_dirs = set() + files = [] + filtered_fname = '' + keys = list(covdata.keys()) + keys.sort( + key=options.sort_uncovered and _num_uncovered or + options.sort_percent and _percent_uncovered or _alpha + ) + for f in keys: + cdata = covdata[f] + filtered_fname = options.root_filter.sub('', f) + files.append(filtered_fname) + cdata._filename = filtered_fname + ttmp = os.path.abspath(options.output).split('.') + if len(ttmp) > 1: + cdata._sourcefile = \ + '.'.join(ttmp[:-1]) + \ + '.' + cdata._filename.replace('/', '_') + \ + '.' + ttmp[-1] + else: + cdata._sourcefile = \ + ttmp[0] + '.' + cdata._filename.replace('/', '_') + '.html' + # Define the common root directory, which may differ from options.root + # when source files share a common prefix. + if len(files) > 1: + commondir = posixpath.commonprefix(files) + if commondir != '': + data['DIRECTORY'] = commondir + else: + dir_, file_ = os.path.split(filtered_fname) + if dir_ != '': + data['DIRECTORY'] = dir_ + os.sep + + for f in keys: + cdata = covdata[f] + class_lines = 0 + class_hits = 0 + class_branches = 0 + class_branch_hits = 0 + for line in cdata.all_lines: + hits = cdata.covered.get(line, 0) + class_lines += 1 + if hits > 0: + class_hits += 1 + branches = cdata.branches.get(line) + if branches is None: + pass + else: + b_hits = 0 + for v in branches.values(): + if v > 0: + b_hits += 1 + coverage = 100 * b_hits / len(branches) + class_branch_hits += b_hits + class_branches += len(branches) + + lines_covered = 100.0 if class_lines == 0 else \ + 100.0 * class_hits / class_lines + branches_covered = 100.0 if class_branches == 0 else \ + 100.0 * class_branch_hits / class_branches + + data['ROWS'].append(html_row( + details, cdata._sourcefile, + directory=data['DIRECTORY'], + filename=cdata._filename, + LinesExec=class_hits, + LinesTotal=class_lines, + LinesCoverage=lines_covered, + BranchesExec=class_branch_hits, + BranchesTotal=class_branches, + BranchesCoverage=branches_covered + )) + data['ROWS'] = '\n'.join(data['ROWS']) + + if data['DIRECTORY'] == '': + data['DIRECTORY'] = "." + + htmlString = root_page.substitute(**data) + + if options.output is None: + sys.stdout.write(htmlString + '\n') + else: + OUTPUT = open(options.output, 'w') + OUTPUT.write(htmlString + '\n') + OUTPUT.close() + + # Return, if no details are requested + if not details: + return + + # + # Generate an HTML file for every source file + # + for f in keys: + cdata = covdata[f] + + data['FILENAME'] = cdata._filename + data['ROWS'] = '' + + options.show_branch = True + branchTotal, branchCovered, tmp = cdata.coverage() + data['BRANCHES_EXEC'] = str(branchCovered) + data['BRANCHES_TOTAL'] = str(branchTotal) + coverage = 0.0 if branchTotal == 0 else \ + round(100.0 * branchCovered / branchTotal, 1) + data['BRANCHES_COVERAGE'] = str(coverage) + if coverage < medium_coverage: + data['BRANCHES_COLOR'] = low_color + elif coverage < high_coverage: + data['BRANCHES_COLOR'] = medium_color + else: + data['BRANCHES_COLOR'] = high_color + + options.show_branch = False + lineTotal, lineCovered, tmp = cdata.coverage() + data['LINES_EXEC'] = str(lineCovered) + data['LINES_TOTAL'] = str(lineTotal) + coverage = 0.0 if lineTotal == 0 else \ + round(100.0 * lineCovered / lineTotal, 1) + data['LINES_COVERAGE'] = str(coverage) + if coverage < medium_coverage: + data['LINES_COLOR'] = low_color + elif coverage < high_coverage: + data['LINES_COLOR'] = medium_color + else: + data['LINES_COLOR'] = high_color + + data['ROWS'] = [] + currdir = os.getcwd() + os.chdir(root_dir) + INPUT = open(data['FILENAME'], 'r') + ctr = 1 + for line in INPUT: + data['ROWS'].append( + source_row(ctr, line.rstrip(), cdata) + ) + ctr += 1 + INPUT.close() + os.chdir(currdir) + data['ROWS'] = '\n'.join(data['ROWS']) + + htmlString = source_page.substitute(**data) + OUTPUT = open(cdata._sourcefile, 'w') + OUTPUT.write(htmlString + '\n') + OUTPUT.close() + + +def source_row(lineno, source, cdata): + rowstr = Template(''' + +
${lineno}
+
${linecount}
+
${source}
+ ''') + kwargs = {} + kwargs['lineno'] = str(lineno) + if lineno in cdata.covered: + kwargs['covclass'] = 'coveredLine' + kwargs['linecount'] = str(cdata.covered.get(lineno, 0)) + elif lineno in cdata.uncovered: + kwargs['covclass'] = 'uncoveredLine' + kwargs['linecount'] = '' + else: + kwargs['covclass'] = '' + kwargs['linecount'] = '' + kwargs['source'] = html.escape(source) + return rowstr.substitute(**kwargs) + +# +# Generate the table row for a single file +# +nrows = 0 + + +def html_row(details, sourcefile, **kwargs): + if options.relative_anchors: + sourcefile = os.path.basename(sourcefile) + rowstr = Template(''' + + ${filename} + +
+
+
+ + ${LinesCoverage} % + ${LinesExec} / ${LinesTotal} + ${BranchesCoverage} % + ${BranchesExec} / ${BranchesTotal} + +''') + global nrows + nrows += 1 + if nrows % 2 == 0: + kwargs['altstyle'] = 'style="background-color:LightSteelBlue"' + else: + kwargs['altstyle'] = '' + if details: + kwargs['filename'] = '
%s' % ( + sourcefile, kwargs['filename'][len(kwargs['directory']):] + ) + else: + kwargs['filename'] = kwargs['filename'][len(kwargs['directory']):] + kwargs['LinesCoverage'] = round(kwargs['LinesCoverage'], 1) + # Disable the border if the bar is too short to see the color + if kwargs['LinesCoverage'] < 1e-7: + kwargs['BarBorder'] = "border:white; " + else: + kwargs['BarBorder'] = "" + if kwargs['LinesCoverage'] < medium_coverage: + kwargs['LinesColor'] = low_color + kwargs['LinesBar'] = 'red' + elif kwargs['LinesCoverage'] < high_coverage: + kwargs['LinesColor'] = medium_color + kwargs['LinesBar'] = 'yellow' + else: + kwargs['LinesColor'] = high_color + kwargs['LinesBar'] = 'green' + + kwargs['BranchesCoverage'] = round(kwargs['BranchesCoverage'], 1) + if kwargs['BranchesCoverage'] < medium_coverage: + kwargs['BranchesColor'] = low_color + kwargs['BranchesBar'] = 'red' + elif kwargs['BranchesCoverage'] < high_coverage: + kwargs['BranchesColor'] = medium_color + kwargs['BranchesBar'] = 'yellow' + else: + kwargs['BranchesColor'] = high_color + kwargs['BranchesBar'] = 'green' + + return rowstr.substitute(**kwargs) + + +# +# Produce an XML report in the Cobertura format +# +def print_xml_report(covdata): + branchTotal = 0 + branchCovered = 0 + lineTotal = 0 + lineCovered = 0 + + options.show_branch = True + for key in covdata.keys(): + (total, covered, percent) = covdata[key].coverage() + branchTotal += total + branchCovered += covered + + options.show_branch = False + for key in covdata.keys(): + (total, covered, percent) = covdata[key].coverage() + lineTotal += total + lineCovered += covered + + impl = xml.dom.minidom.getDOMImplementation() + docType = impl.createDocumentType( + "coverage", None, + "http://cobertura.sourceforge.net/xml/coverage-03.dtd" + ) + doc = impl.createDocument(None, "coverage", docType) + root = doc.documentElement + root.setAttribute( + "line-rate", lineTotal == 0 and '0.0' or + str(float(lineCovered) / lineTotal) + ) + root.setAttribute( + "branch-rate", branchTotal == 0 and '0.0' or + str(float(branchCovered) / branchTotal) + ) + root.setAttribute( + "timestamp", str(int(time.time())) + ) + root.setAttribute( + "version", "gcovr %s" % (version_str(),) + ) + + # Generate the element: this is either the root directory + # (specified by --root), or the CWD. + sources = doc.createElement("sources") + root.appendChild(sources) + + # Generate the coverage output (on a per-package basis) + packageXml = doc.createElement("packages") + root.appendChild(packageXml) + packages = {} + source_dirs = set() + + keys = list(covdata.keys()) + keys.sort() + for f in keys: + data = covdata[f] + directory = options.root_filter.sub('', f) + if f.endswith(directory): + src_path = f[:-1 * len(directory)] + if len(src_path) > 0: + while directory.startswith(os.path.sep): + src_path += os.path.sep + directory = directory[len(os.path.sep):] + source_dirs.add(src_path) + else: + # Do no truncation if the filter does not start matching at + # the beginning of the string + directory = f + directory, fname = os.path.split(directory) + + package = packages.setdefault( + directory, [doc.createElement("package"), {}, 0, 0, 0, 0] + ) + c = doc.createElement("class") + # The Cobertura DTD requires a methods section, which isn't + # trivial to get from gcov (so we will leave it blank) + c.appendChild(doc.createElement("methods")) + lines = doc.createElement("lines") + c.appendChild(lines) + + class_lines = 0 + class_hits = 0 + class_branches = 0 + class_branch_hits = 0 + for line in data.all_lines: + hits = data.covered.get(line, 0) + class_lines += 1 + if hits > 0: + class_hits += 1 + l = doc.createElement("line") + l.setAttribute("number", str(line)) + l.setAttribute("hits", str(hits)) + branches = data.branches.get(line) + if branches is None: + l.setAttribute("branch", "false") + else: + b_hits = 0 + for v in branches.values(): + if v > 0: + b_hits += 1 + coverage = 100 * b_hits / len(branches) + l.setAttribute("branch", "true") + l.setAttribute( + "condition-coverage", + "%i%% (%i/%i)" % (coverage, b_hits, len(branches)) + ) + cond = doc.createElement('condition') + cond.setAttribute("number", "0") + cond.setAttribute("type", "jump") + cond.setAttribute("coverage", "%i%%" % (coverage)) + class_branch_hits += b_hits + class_branches += float(len(branches)) + conditions = doc.createElement("conditions") + conditions.appendChild(cond) + l.appendChild(conditions) + + lines.appendChild(l) + + className = fname.replace('.', '_') + c.setAttribute("name", className) + c.setAttribute("filename", os.path.join(directory, fname)) + c.setAttribute( + "line-rate", + str(class_hits / (1.0 * class_lines or 1.0)) + ) + c.setAttribute( + "branch-rate", + str(class_branch_hits / (1.0 * class_branches or 1.0)) + ) + c.setAttribute("complexity", "0.0") + + package[1][className] = c + package[2] += class_hits + package[3] += class_lines + package[4] += class_branch_hits + package[5] += class_branches + + keys = list(packages.keys()) + keys.sort() + for packageName in keys: + packageData = packages[packageName] + package = packageData[0] + packageXml.appendChild(package) + classes = doc.createElement("classes") + package.appendChild(classes) + classNames = list(packageData[1].keys()) + classNames.sort() + for className in classNames: + classes.appendChild(packageData[1][className]) + package.setAttribute("name", packageName.replace(os.sep, '.')) + package.setAttribute( + "line-rate", str(packageData[2] / (1.0 * packageData[3] or 1.0)) + ) + package.setAttribute( + "branch-rate", str(packageData[4] / (1.0 * packageData[5] or 1.0)) + ) + package.setAttribute("complexity", "0.0") + + # Populate the element: this is either the root directory + # (specified by --root), or relative directories based + # on the filter, or the CWD + if options.root is not None: + source = doc.createElement("source") + source.appendChild(doc.createTextNode(options.root.strip())) + sources.appendChild(source) + elif len(source_dirs) > 0: + cwd = os.getcwd() + for d in source_dirs: + source = doc.createElement("source") + if d.startswith(cwd): + reldir = d[len(cwd):].lstrip(os.path.sep) + elif cwd.startswith(d): + i = 1 + while normpath(d) != \ + normpath(os.path.join(*tuple([cwd] + ['..'] * i))): + i += 1 + reldir = os.path.join(*tuple(['..'] * i)) + else: + reldir = d + source.appendChild(doc.createTextNode(reldir.strip())) + sources.appendChild(source) + else: + source = doc.createElement("source") + source.appendChild(doc.createTextNode('.')) + sources.appendChild(source) + + if options.prettyxml: + import textwrap + lines = doc.toprettyxml(" ").split('\n') + for i in xrange(len(lines)): + n = 0 + while n < len(lines[i]) and lines[i][n] == " ": + n += 1 + lines[i] = "\n".join(textwrap.wrap( + lines[i], 78, + break_long_words=False, + break_on_hyphens=False, + subsequent_indent=" " + n * " " + )) + xmlString = "\n".join(lines) + #print textwrap.wrap(doc.toprettyxml(" "), 80) + else: + xmlString = doc.toprettyxml(indent="") + if options.output is None: + sys.stdout.write(xmlString + '\n') + else: + OUTPUT = open(options.output, 'w') + OUTPUT.write(xmlString + '\n') + OUTPUT.close() + + +## +## MAIN +## + +# +# Create option parser +# +parser = OptionParser() +parser.add_option( + "--version", + help="Print the version number, then exit", + action="store_true", + dest="version", + default=False +) +parser.add_option( + "-v", "--verbose", + help="Print progress messages", + action="store_true", + dest="verbose", + default=False +) +parser.add_option( + '--object-directory', + help="Specify the directory that contains the gcov data files. gcovr " + "must be able to identify the path between the *.gcda files and the " + "directory where gcc was originally run. Normally, gcovr can guess " + "correctly. This option overrides gcovr's normal path detection and " + "can specify either the path from gcc to the gcda file (i.e. what " + "was passed to gcc's '-o' option), or the path from the gcda file to " + "gcc's original working directory.", + action="store", + dest="objdir", + default=None +) +parser.add_option( + "-o", "--output", + help="Print output to this filename", + action="store", + dest="output", + default=None +) +parser.add_option( + "-k", "--keep", + help="Keep the temporary *.gcov files generated by gcov. " + "By default, these are deleted.", + action="store_true", + dest="keep", + default=False +) +parser.add_option( + "-d", "--delete", + help="Delete the coverage files after they are processed. " + "These are generated by the users's program, and by default gcovr " + "does not remove these files.", + action="store_true", + dest="delete", + default=False +) +parser.add_option( + "-f", "--filter", + help="Keep only the data files that match this regular expression", + action="append", + dest="filter", + default=[] +) +parser.add_option( + "-e", "--exclude", + help="Exclude data files that match this regular expression", + action="append", + dest="exclude", + default=[] +) +parser.add_option( + "--gcov-filter", + help="Keep only gcov data files that match this regular expression", + action="store", + dest="gcov_filter", + default=None +) +parser.add_option( + "--gcov-exclude", + help="Exclude gcov data files that match this regular expression", + action="append", + dest="gcov_exclude", + default=[] +) +parser.add_option( + "-r", "--root", + help="Defines the root directory for source files. " + "This is also used to filter the files, and to standardize " + "the output.", + action="store", + dest="root", + default=None +) +parser.add_option( + "-x", "--xml", + help="Generate XML instead of the normal tabular output.", + action="store_true", + dest="xml", + default=False +) +parser.add_option( + "--xml-pretty", + help="Generate pretty XML instead of the normal dense format.", + action="store_true", + dest="prettyxml", + default=False +) +parser.add_option( + "--html", + help="Generate HTML instead of the normal tabular output.", + action="store_true", + dest="html", + default=False +) +parser.add_option( + "--html-details", + help="Generate HTML output for source file coverage.", + action="store_true", + dest="html_details", + default=False +) +parser.add_option( + "--html-absolute-paths", + help="Set the paths in the HTML report to be absolute instead of relative", + action="store_false", + dest="relative_anchors", + default=True +) +parser.add_option( + "-b", "--branches", + help="Tabulate the branch coverage instead of the line coverage.", + action="store_true", + dest="show_branch", + default=None +) +parser.add_option( + "-u", "--sort-uncovered", + help="Sort entries by increasing number of uncovered lines.", + action="store_true", + dest="sort_uncovered", + default=None +) +parser.add_option( + "-p", "--sort-percentage", + help="Sort entries by decreasing percentage of covered lines.", + action="store_true", + dest="sort_percent", + default=None +) +parser.add_option( + "--gcov-executable", + help="Defines the name/path to the gcov executable [defaults to the " + "GCOV environment variable, if present; else 'gcov'].", + action="store", + dest="gcov_cmd", + default=os.environ.get('GCOV', 'gcov') +) +parser.add_option( + "--exclude-unreachable-branches", + help="Exclude from coverage branches which are marked to be excluded by " + "LCOV/GCOV markers or are determined to be from lines containing " + "only compiler-generated \"dead\" code.", + action="store_true", + dest="exclude_unreachable_branches", + default=False +) +parser.add_option( + "-g", "--use-gcov-files", + help="Use preprocessed gcov files for analysis.", + action="store_true", + dest="gcov_files", + default=False +) +parser.add_option( + "-s", "--print-summary", + help="Prints a small report to stdout with line & branch " + "percentage coverage", + action="store_true", + dest="print_summary", + default=False +) +parser.usage = "gcovr [options]" +parser.description = \ + "A utility to run gcov and generate a simple report that summarizes " \ + "the coverage" +# +# Process options +# +options, args = parser.parse_args(args=sys.argv) +if options.version: + sys.stdout.write( + "gcovr %s\n" + "\n" + "Copyright (2013) Sandia Corporation. Under the terms of Contract\n" + "DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government\n" + "retains certain rights in this software.\n" + % (version_str(), ) + ) + sys.exit(0) +if options.objdir: + tmp = options.objdir.replace('/', os.sep).replace('\\', os.sep) + while os.sep + os.sep in tmp: + tmp = tmp.replace(os.sep + os.sep, os.sep) + if normpath(options.objdir) != tmp: + sys.stderr.write( + "(WARNING) relative referencing in --object-directory.\n" + "\tthis could cause strange errors when gcovr attempts to\n" + "\tidentify the original gcc working directory.\n") + if not os.path.exists(normpath(options.objdir)): + sys.stderr.write( + "(ERROR) Bad --object-directory option.\n" + "\tThe specified directory does not exist.\n") + sys.exit(1) +# +# Setup filters +# +for i in range(0, len(options.exclude)): + options.exclude[i] = re.compile(options.exclude[i]) + +if options.root is not None: + if not options.root: + sys.stderr.write( + "(ERROR) empty --root option.\n" + "\tRoot specifies the path to the root " + "directory of your project.\n" + "\tThis option cannot be an empty string.\n" + ) + sys.exit(1) + root_dir = os.path.abspath(options.root) + options.root_filter = re.compile(re.escape(root_dir + os.sep)) +else: + options.root_filter = re.compile('') + root_dir = starting_dir + +for i in range(0, len(options.filter)): + options.filter[i] = re.compile(options.filter[i]) +if len(options.filter) == 0: + options.filter.append(options.root_filter) + +for i in range(0, len(options.gcov_exclude)): + options.gcov_exclude[i] = re.compile(options.gcov_exclude[i]) +if options.gcov_filter is not None: + options.gcov_filter = re.compile(options.gcov_filter) +else: + options.gcov_filter = re.compile('') +# +# Get data files +# +if len(args) == 1: + if options.root is None: + datafiles = get_datafiles(["."], options) + else: + datafiles = get_datafiles([options.root], options) +else: + datafiles = get_datafiles(args[1:], options) +# +# Get coverage data +# +covdata = {} +for file_ in datafiles: + if options.gcov_files: + process_existing_gcov_file(file_, covdata, options) + else: + process_datafile(file_, covdata, options) +if options.verbose: + sys.stdout.write( + "Gathered coveraged data for " + str(len(covdata)) + " files\n" + ) +# +# Print report +# +if options.xml or options.prettyxml: + print_xml_report(covdata) +elif options.html: + print_html_report(covdata, options.html_details) +else: + print_text_report(covdata) + +if options.print_summary: + print_summary(covdata) \ No newline at end of file diff --git a/tools/generate_debug_hashes.py b/tools/generate_debug_hashes.py new file mode 100644 index 0000000..84d91eb --- /dev/null +++ b/tools/generate_debug_hashes.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +import os +import hashlib +import hmac +import argparse +import sys + +argparser = argparse.ArgumentParser(description='Generates obfuscated logging file IDs for iBoot release builds') +argparser.add_argument('--src', required=True, help='iBoot source tree') + +args = argparser.parse_args() + +id_file_map = {} + +directory = args.src + +base_hmac = hmac.new('obfuscation of filename for release build logging', '', hashlib.sha1) + +for (path, dirnames, filenames) in os.walk(directory): + # strip the part of the pathname we supplied off the pathname + shortened_path = path[len(directory)+1:] + # don't iterate into paths we don't care about + + thisdir = os.path.split(shortened_path)[1] + + if thisdir in ['build', '.git', '.svn']: + del dirnames[:] + continue + for filename in filenames: + # ignore file types we don't care about + extension = os.path.splitext(filename)[1] + if extension not in ['.c', '.cpp', '.s', '.S', '.h']: + continue + + full_path = os.path.join(shortened_path, filename) + + current_hmac = base_hmac.copy() + current_hmac.update(full_path) + + file_id = current_hmac.hexdigest()[:16] + + if file_id in id_file_map and id_file_map[file_id] != full_path: + print >> sys.stderr, 'Error: Files "{}" and "{}" both have the same ID {}'.format(full_path, id_file_map[file_id], file_id) + sys.exit(1) + else: + id_file_map[file_id] = full_path + print '{}:{}'.format(full_path, file_id) diff --git a/tools/igmacros b/tools/igmacros new file mode 100644 index 0000000..dbb03ad --- /dev/null +++ b/tools/igmacros @@ -0,0 +1,250 @@ +# iBoot gdb macros +# +# Vaguely inspired by the 'kgm' package. +# + +set print asm-demangle on +set cp-abi gnu-v2 +set kaslr-memory-search off + +echo Loading iBoot GDB macros package. Type "help igm" for more info.\n + +define igm +printf "" +echo These are the gdb macros for iBoot debugging. Type "help igm" for more info.\n +end + +document igm +| These are the iBoot gdb macros. These gdb macros are intended to be +| used when debugging iBoot via jtag. +| +| The following macros are available in this package: +| +| showtasks Display a list of tasks +| switchtotask Switch to different task +| showallstacks Show stack of each tasks +| +| showheap Show blocks allocated in the heap +| +| Type "help " for more specific help on a particular macro. +| Type "show user " to see what the macro is really doing. +end + +set $igm_mtype = sizeof(void *) +set $igm_lp64 = ($igm_mtype == 8) + +# Print a pointer +define showptr + if ($igm_lp64) + printf "0x%016llx", $arg0 + else + printf "0x%08x", $arg0 + end +end + +# Traverse a list expected to be the queue_entry list from a task, and print anything +# found on the list that is not a task; it should be the event being waited on. +define print_non_tasks_in_list + set $igm_ntil_terminal = (struct list_node *)$arg0 + set $igm_ntil_cursor = $igm_ntil_terminal->next + while ($igm_ntil_cursor != $igm_ntil_terminal) + if ($igm_lp64) + set $igm_ntil_task = (struct task *)((void *)$igm_ntil_cursor - 20) + if ($igm_ntil_task != 0x7461736b) + set $igm_ntil_event = (struct task_event *)((void *)$igm_ntil_cursor - 8) + showptr $igm_ntil_event + end + else + set $igm_ntil_task = (struct task *)((void *)$igm_ntil_cursor - 12) + if ($igm_ntil_task != 0x7461736b) + set $igm_ntil_event = (struct task_event *)((void *)$igm_ntil_cursor - 8) + showptr $igm_ntil_event + end + end + set $igm_ntil_cursor = $igm_ntil_cursor->next + end +end + + +define showtask + showptr $arg0 + set $igm_task = (struct task *)$arg0 + if (($igm_task->magic != 0x7461736b) || ($igm_task->magic2 != 0x74736b32)) + printf " not a valid task\n" + else + printf " %16s: ", &$igm_task->name + if ($igm_task->state == 0) + printf "INITIAL" + end + if ($igm_task->state == 1) + printf "READY" + end + if ($igm_task->state == 2) + printf "RUNNING" + end + if ($igm_task->state == 3) + printf "BLOCKED on event " + print_non_tasks_in_list &$igm_task->queue_node + end + if ($igm_task->state == 4) + printf "SLEEPING for " + printf "%lluus ", $igm_task->sleep_callout.delay + printf "@ 0x%016llx", $igm_task->sleep_callout.sched_ticks + end + if ($igm_task->state == 5) + printf "FINISHED" + end + printf "\n" + end +end + +define showtasks + showtask &bootstrap_task + set $igm_task_cursor = (struct list_node *)task_list->next + while $igm_task_cursor != &task_list + if ($igm_lp64) + set $igm_task_task = ((void *)$igm_task_cursor - 8) + else + set $igm_task_task = ((void *)$igm_task_cursor - 4) + end + showtask $igm_task_task + set $igm_task_cursor = $igm_task_cursor->next + end +end + +document showtasks +| Print a summary listing of all tasks. +end + +define dobacktrace + set $_task = (struct task*)$arg0 + set $_fp = (void **)$_task->arch.fp + printf "%s: \n", $_task->name + while $_fp != 0 + set $_pc = *($_fp + 1) + x/i $_pc + set $_fp = (void**)*$_fp + end +end + +define showallstacks + if ($igm_lp64) + set $igm_task_cursor = (struct list_node *)task_list->next + while $igm_task_cursor != &task_list + if ($igm_lp64) + set $igm_task_task = ((void *)$igm_task_cursor - 8) + else + set $igm_task_task = ((void *)$igm_task_cursor - 4) + end + dobacktrace $igm_task_task + printf "-------------------------------------\n" + set $igm_task_cursor = $igm_task_cursor->next + end + else + printf "XXX Not supported yet\n" + end +end + +document showallstacks +| Routine to print out the stack for each tasks in the system. +end + +# XXX doesn't seems to work +define switchtotask + printf "XXX Not supported yet\n" + set $igm_newtask = (struct task *)$arg0 + if (($igm_newtask->magic != 0x7461736b) || ($igm_newtask->magic2 != 0x74736b32)) + printf "not a valid task\n" + else + if ($igm_lp64) + set $igm_arch_state = &$igm_newtask->arch + set $r16 = $igm_arch_state->regs[15] + set $r17 = $igm_arch_state->regs[16] + set $r19 = $igm_arch_state->regs[18] + set $r20 = $igm_arch_state->regs[19] + set $r21 = $igm_arch_state->regs[20] + set $r22 = $igm_arch_state->regs[21] + set $r23 = $igm_arch_state->regs[22] + set $r24 = $igm_arch_state->regs[23] + set $r25 = $igm_arch_state->regs[24] + set $r26 = $igm_arch_state->regs[25] + set $r27 = $igm_arch_state->regs[26] + set $r28 = $igm_arch_state->regs[27] + set $r29 = $igm_arch_state->fp + set $r30 = $igm_arch_state->lr + set $r31 = $igm_arch_state->sp + flushregs + flushstack + else + set $igm_arch_state = &$igm_newtask->arch + set $r4 = $igm_arch_state->regs[0] + set $r5 = $igm_arch_state->regs[1] + set $r6 = $igm_arch_state->regs[2] + set $r7 = $igm_arch_state->regs[3] + set $r8 = $igm_arch_state->regs[4] + set $r9 = $igm_arch_state->regs[5] + set $r10 = $igm_arch_state->regs[6] + set $r11 = $igm_arch_state->regs[7] + set $r13 = $igm_arch_state->regs[8] + set $r14 = $igm_arch_state->regs[9] + flushregs + flushstack + end + end +end + +document switchtotask +Syntax: switchtotask +| Sets GDB's idea of the current task to +end + +define show_heap_chunk + set $chunk_ptr = (struct chunk_data *)$arg0 + printf "chunk @" + showptr $chunk_ptr->chunk_base + printf "/0x%x\n", $chunk_ptr->chunk_size + + printf " block size type ptr len\n" + set $index = 1 + while $index != 0 + + # compute the block pointer from the index + set $block_ptr = (struct heap_block *)($chunk_ptr->chunk_base + $index) + + if $block_ptr->this_size == 1 + # this is the end of the chunk + loop_break + end + + # print block address and size + showptr $block_ptr + printf " 0x%08x", $block_ptr->this_size + + # decode and print block contents + if $block_ptr->this_free != 0 + printf " free " + else + printf " malloc " + showptr $block_ptr + 1 + end + printf " 0x%08x\n", ($block_ptr->this_size - 1) * sizeof(struct heap_block) + + # XXX range-check + set $index = $index + $block_ptr->this_size + end + +end + +define showheap + # Iterate chunks and print these first + # XXX might be good to have the heap use more unique names + set $chunk_iterator = 0 + while $chunk_iterator < chunk_count + show_heap_chunk &lead[$chunk_iterator] + set $chunk_iterator = $chunk_iterator + 1 + end +end + +document showheap +| Print the contents of the heap. +end diff --git a/tools/iop_stitcher.c b/tools/iop_stitcher.c new file mode 100644 index 0000000..afd8bc7 --- /dev/null +++ b/tools/iop_stitcher.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * This document is the property of Apple Inc. + * It is considered confidential and proprietary. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Apple Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct task { + uint32_t cmd; /* LC_THREAD or LC_UNIXTHREAD */ + uint32_t cmdsize; /* total size of this command */ + uint32_t flavor; /* flavor of thread state */ + uint32_t count; /* count of longs in thread state */ + arm_thread_state_t arm_state; /* thread state for this flavor */ +}; + + +int main (int argc, const char *argv[]) +{ + FILE *out; + FILE *in; + DIR *dir; + const char* src_dir; + int num_segments; + u_int32_t data_cursor; + struct dirent *ep; + struct mach_header header = + { + MH_MAGIC, + CPU_TYPE_ARM, + CPU_SUBTYPE_ARM_V4T, + MH_CORE + }; + struct task thread = {0}; + + if (argc != 3) + { + printf("%s \n", argv[0]); + return -1; + } + + // Open directory + src_dir = argv[1]; + dir = opendir(src_dir); + if (!dir) + return -2; + + // Open output core file + out = fopen(argv[2], "wb"); + if (!out) + return -3; + + // Lay down a heder (to be updated later) + fwrite(&header, 1, sizeof(header), out); + + // Lay down some thread context + thread.cmd = LC_THREAD; + thread.cmdsize = sizeof(thread); + + thread.flavor = ARM_THREAD_STATE; + thread.count = ARM_THREAD_STATE_COUNT; + + // XXX fill in registers + // thread.arm_state.r[13] = + // thread.arm_state.sp = + // thread.arm_state.lr = + // thread.arm_state.pc = + // thread.arm_state.cpsr = + + fwrite(&thread, 1, sizeof(thread), out); + + header.ncmds += 1; + header.sizeofcmds += sizeof(thread); + + // To make life easier below, count the number of segments we're going to have + num_segments = 0; + while(ep = readdir(dir)) + { + int addr; + if (1 == sscanf(ep->d_name, "%x.bin", &addr)) + num_segments += 1; + } + // Rewind to actually process these files now + // XXX assume contents will not change from the scan above + closedir(dir); + dir = opendir(src_dir); + + // For each file, create a segment based on its filename + chdir(src_dir); + data_cursor = sizeof(header) + + header.sizeofcmds + + (num_segments * sizeof(struct segment_command)); + while(ep = readdir(dir)) + { + struct segment_command sc = {0}; + + // Filenames are
.bin + if (1 == sscanf(ep->d_name, "%x.bin", &sc.vmaddr)) + { + // Create a segment with the given address and file contents + in = fopen(ep->d_name, "rb"); + if (in) + { + void * data; + int old_pos; + + // Record how big the source file is + fseek(in, 0, SEEK_END); + sc.vmsize = ftell(in); + fseek(in, 0, SEEK_SET); + + // Set up a zero-section text segment load command + sc.cmd = LC_SEGMENT; + sc.cmdsize = sizeof(sc); + strcpy(sc.segname, SEG_TEXT); + + // Populate the entire segment, no gaps + // Use the data cursor pointing past the end of the load commands + sc.filesize = sc.vmsize; + sc.fileoff = data_cursor; + data_cursor += sc.filesize; + + // Write out the load command + fwrite(&sc, 1, sizeof(sc), out); + + + // Read out the data + data = malloc(sc.vmsize); + if (!data) + return -4; + fread(data, 1, sc.vmsize, in); + fclose(in); + + // Put the data at the current cursor command + old_pos = ftell(out); + if (fseek(out, sc.fileoff, SEEK_SET)) + return -5; + fwrite(data, 1, sc.vmsize, out); + free(data); + + // Put the cursor back for the next load command + fseek(out, old_pos, SEEK_SET); + + // Increment the number of load commands in the mach header + header.ncmds += 1; + header.sizeofcmds += sizeof(sc); + } + else + { + fprintf(stderr, "can't open %s\n", ep->d_name); + } + } + } + closedir(dir); + + // Update the header with how many segments we actually generated + fseek(out, 0, SEEK_SET); + fwrite(&header, 1, sizeof(header), out); + fclose(out); + + + return 0; +} diff --git a/tools/lldb_init_iboot.py b/tools/lldb_init_iboot.py new file mode 100644 index 0000000..35ee6b4 --- /dev/null +++ b/tools/lldb_init_iboot.py @@ -0,0 +1,10 @@ +def __lldb_init_module(debugger, internal_dict): + print "Loading iBoot debugging from %s" % __file__ + self_path = str(__file__) + base_dir_name = self_path[:self_path.rfind("/")] + core_os_plugin = base_dir_name + "/lldb_os_iboot.py" + osplugin_cmd = "settings set target.process.python-os-plugin-path \"%s\"" % core_os_plugin + print osplugin_cmd + debugger.HandleCommand(osplugin_cmd) + thread_fmt_cmd = 'settings set thread-format thread #${thread.index}{ "${thread.name}"}: tid = ${thread.id}{, ${frame.pc}}{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}{ at ${line.file.basename}:${line.number}}{, stop reason = ${thread.stop-reason}}{\nReturn value: ${thread.return-value}}\n' + debugger.HandleCommand(thread_fmt_cmd) diff --git a/tools/lldb_os_iboot.py b/tools/lldb_os_iboot.py new file mode 100644 index 0000000..d7dfb96 --- /dev/null +++ b/tools/lldb_os_iboot.py @@ -0,0 +1,199 @@ +#!/usr/bin/python + +import lldb +import struct + +def __lldb_init_module(debugger, internal_dict): + debugger.HandleCommand("command script add -f lldb_os_iboot.iboot_tasks iboot_tasks") + +def iboot_tasks(debugger, command, result, internal_dict): + """Print the list of tasks maintained by the iBoot runtime""" + process = debugger.GetSelectedTarget().GetProcess() + if not process or not process.target: + print 'Not connected' + return + + plugin = OperatingSystemPlugIn(process) + + current_task = plugin.get_global('current_task') + assert current_task is not None + current_task_addr = current_task.GetValueAsUnsigned() + + tasks = plugin.get_task_dict().itervalues() + print ' TID Task Name Address' + print ' ------ ---- ---------------- ------------------' + for t in tasks: + task_addr = t.AddressOf().GetValueAsUnsigned() + current = "*" if task_addr == current_task_addr else " " + + tv = lldb.value(t) + task_id = int(tv.task_id) + tid = task_id + plugin.TID_OFFSET + name = plugin.value_to_str(tv.name.sbvalue) + + print '{} {:#06x} {:<4} {:<16} {:#018x}'.format(current, tid, task_id, name, task_addr) + +class OperatingSystemPlugIn(object): + """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class""" + + TID_OFFSET = 0x1000 + + def __init__(self, process): + '''Initialization needs a valid.SBProcess object''' + self.process = None + self.registers = None + self.task_dict = None + self.arch = None + if type(process) is lldb.SBProcess and process.IsValid(): + self.process = process + triple = process.target.triple + if triple: + self.arch = triple.split('-')[0] + + def get_global(self, name): + return self.process.target.FindGlobalVariables(name, 1)[0] + + def iboot_task_iter(self, head, skip_task=None): + task_type = self.process.target.FindFirstType('task') + task_members = { member.name : member for member in task_type.get_members_array() } + list_offset = task_members['task_list_node'].byte_offset + + if not skip_task is None: + skip_addr = skip_task.GetValueAsUnsigned() + else: + skip_addr = 0 + + for node in head.AddressOf().linked_list_iter('next'): + task_addr = node.GetValueAsUnsigned() - list_offset + if task_addr == skip_addr: + continue + task = node.CreateValueFromAddress('task', task_addr, task_type) + tid = int(lldb.value(task).task_id) + yield tid, task + + def summarize_iboot_task(self, task): + task_value = lldb.value(task) + return { + 'name': self.value_to_str(task_value.name.sbvalue).ljust(15), + 'tid': int(task_value.task_id) + self.TID_OFFSET, + 'state': 'stopped', + 'stop_reason': 'none' + } + + def get_task_dict(self, skip_current=False): + if self.task_dict is None: + task_list = self.get_global('task_list') + assert task_list is not None + + if skip_current: + skip_task = self.get_global('current_task') + else: + skip_task = None + + task_tuples = list(self.iboot_task_iter(task_list, skip_task)) + # The first entry in the list isn't a task, so remove it from the list + task_tuples = task_tuples[1:] + + # If there aren't any tasks in the list, we must still be + # in the bootstrap task, which we can get through current_task + if len(task_tuples) == 0 and not skip_current: + current_task = self.get_global('current_task').Dereference() + current_tid = int(lldb.value(current_task).task_id) + task_tuples = [(current_tid, current_task)] + + self.task_dict = {tid : thread for tid,thread in task_tuples} + return self.task_dict + + @staticmethod + def value_to_str(value): + return "".join([chr(x) for x in value.GetData().uint8s if x != 0]) + + @staticmethod + def value_to_bytes(value): + return "".join([chr(x) for x in value.GetData().uint8s]) + + def get_thread_info(self): + task_iter = self.get_task_dict(skip_current=True).itervalues() + return map(lambda x: self.summarize_iboot_task(x), task_iter) + + def get_register_data(self, tid): + assert tid >= self.TID_OFFSET + tasks = self.get_task_dict() + task = tasks[tid - self.TID_OFFSET] + + task_arch_value = lldb.value(task).arch + + if self.arch == 'arm64': + regs = task_arch_value.regs.sbvalue + fp = task_arch_value.fp.sbvalue + lr = task_arch_value.lr.sbvalue + sp = task_arch_value.sp.sbvalue + # We don't know the PC, so use the LR instead to keep LLDB happy + pc = task_arch_value.lr.sbvalue + registers = [regs, fp, lr, sp, pc] + else: + regs = task_arch_value.regs.sbvalue + # We don't know the PC, so use the LR instead to keep LLDB happy + pc = task_arch_value.regs[9].sbvalue + registers = [regs, pc] + + result = "".join(map(self.value_to_bytes, registers)) + return result + + def get_register_info(self): + if self.registers == None: + self.registers = dict() + if self.arch == 'arm64': + self.registers['sets'] = ['GPR'] + self.registers['registers'] = [ + { 'name':'x0' , 'bitsize' : 64, 'offset' : 0x00, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 0, 'dwarf' : 0}, + { 'name':'x1' , 'bitsize' : 64, 'offset' : 0x08, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 1, 'dwarf' : 1}, + { 'name':'x2' , 'bitsize' : 64, 'offset' : 0x10, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 2, 'dwarf' : 2}, + { 'name':'x3' , 'bitsize' : 64, 'offset' : 0x18, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 3, 'dwarf' : 3}, + { 'name':'x4' , 'bitsize' : 64, 'offset' : 0x20, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 4, 'dwarf' : 4}, + { 'name':'x5' , 'bitsize' : 64, 'offset' : 0x28, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 5, 'dwarf' : 5}, + { 'name':'x6' , 'bitsize' : 64, 'offset' : 0x30, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 6, 'dwarf' : 6}, + { 'name':'x7' , 'bitsize' : 64, 'offset' : 0x38, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 7, 'dwarf' : 7}, + { 'name':'x8' , 'bitsize' : 64, 'offset' : 0x40, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 8, 'dwarf' : 8}, + { 'name':'x9' , 'bitsize' : 64, 'offset' : 0x48, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 9, 'dwarf' : 9}, + { 'name':'x10' , 'bitsize' : 64, 'offset' : 0x50, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 10, 'dwarf' : 10}, + { 'name':'x11' , 'bitsize' : 64, 'offset' : 0x58, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 11, 'dwarf' : 11}, + { 'name':'x12' , 'bitsize' : 64, 'offset' : 0x60, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 12, 'dwarf' : 12}, + { 'name':'x13' , 'bitsize' : 64, 'offset' : 0x68, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 13, 'dwarf' : 13}, + { 'name':'x14' , 'bitsize' : 64, 'offset' : 0x70, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 14, 'dwarf' : 14}, + { 'name':'x15' , 'bitsize' : 64, 'offset' : 0x78, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 15, 'dwarf' : 15}, + { 'name':'x16' , 'bitsize' : 64, 'offset' : 0x80, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 16, 'dwarf' : 16}, + { 'name':'x17' , 'bitsize' : 64, 'offset' : 0x88, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 17, 'dwarf' : 17}, + { 'name':'x18' , 'bitsize' : 64, 'offset' : 0x90, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 18, 'dwarf' : 18}, + { 'name':'x19' , 'bitsize' : 64, 'offset' : 0x98, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 19, 'dwarf' : 19}, + { 'name':'x20' , 'bitsize' : 64, 'offset' : 0xa0, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 20, 'dwarf' : 20}, + { 'name':'x21' , 'bitsize' : 64, 'offset' : 0xa8, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 21, 'dwarf' : 21}, + { 'name':'x22' , 'bitsize' : 64, 'offset' : 0xb0, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 22, 'dwarf' : 22}, + { 'name':'x23' , 'bitsize' : 64, 'offset' : 0xb8, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 23, 'dwarf' : 23}, + { 'name':'x24' , 'bitsize' : 64, 'offset' : 0xc0, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 24, 'dwarf' : 24}, + { 'name':'x25' , 'bitsize' : 64, 'offset' : 0xc8, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 25, 'dwarf' : 25}, + { 'name':'x26' , 'bitsize' : 64, 'offset' : 0xd0, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 26, 'dwarf' : 26}, + { 'name':'x27' , 'bitsize' : 64, 'offset' : 0xd8, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 27, 'dwarf' : 27}, + { 'name':'x28' , 'bitsize' : 64, 'offset' : 0xe0, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 28, 'dwarf' : 28}, + { 'name':'fp' , 'bitsize' : 64, 'offset' : 0xe8, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 29, 'dwarf' : 29, 'generic':'fp'}, + { 'name':'lr' , 'bitsize' : 64, 'offset' : 0xf0, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 30, 'dwarf' : 30, 'generic':'lr'}, + { 'name':'sp' , 'bitsize' : 64, 'offset' : 0xf8, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 31, 'dwarf' : 31, 'generic':'sp'}, + { 'name':'pc' , 'bitsize' : 64, 'offset' : 0x100, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 32, 'dwarf' : 32, 'generic':'pc'}, + ] + else: + self.registers['sets'] = ['GPR'] + self.registers['registers'] = [ + { 'name':'r4' , 'bitsize' : 32, 'offset' : 0x00, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 4, 'dwarf' : 4}, + { 'name':'r5' , 'bitsize' : 32, 'offset' : 0x04, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 5, 'dwarf' : 5}, + { 'name':'r6' , 'bitsize' : 32, 'offset' : 0x08, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 6, 'dwarf' : 6}, + { 'name':'r7' , 'bitsize' : 32, 'offset' : 0x0c, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'fp'}, + { 'name':'r8' , 'bitsize' : 32, 'offset' : 0x10, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 8, 'dwarf' : 8}, + { 'name':'r9' , 'bitsize' : 32, 'offset' : 0x14, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 9, 'dwarf' : 9}, + { 'name':'r10' , 'bitsize' : 32, 'offset' : 0x18, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 10, 'dwarf' : 10}, + { 'name':'r11' , 'bitsize' : 32, 'offset' : 0x1c, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 11, 'dwarf' : 11}, + { 'name':'r13' , 'bitsize' : 32, 'offset' : 0x20, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 13, 'dwarf' : 13, 'generic':'sp'}, + { 'name':'r14' , 'bitsize' : 32, 'offset' : 0x24, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 14, 'dwarf' : 14, 'generic':'lr'}, + { 'name':'pc' , 'bitsize' : 32, 'offset' : 0x28, 'encoding':'uint' , 'format':'hex', 'set': 0, 'gcc' : 15, 'dwarf' : 15, 'generic':'pc'}, + ] + return self.registers + diff --git a/tools/macho.py b/tools/macho.py new file mode 100644 index 0000000..45cee96 --- /dev/null +++ b/tools/macho.py @@ -0,0 +1,946 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +# +# A module for manipulating statically linked mach-o files. +# +# Load information from a mach-o file: +# +# f = macho.File(pathname) +# +# Search for non-debug global text symbols starting with 'a' : +# +# m = { "name": "^_a.*", "section": "__TEXT,.*", n_type": (N_STAB | N_EXT, N_EXT, N_STAB)} +# l = f.symtab.matching(m) +# +# Read a structure pointed to by a symbol +# +# d = l.unpack("IIQ") +# +# Write changes back to the file +# +# f.update +# +# Specific things this module does not support: +# - moving anything +# - adding, resizing or removing sections or segments +# +# + +import io +import struct +import re + +# section types/attributes +SECTION_TYPE = 0x000000ff # 256 section types +SECTION_ATTRIBUTES = 0xffffff00 # 24 section attributes + +S_REGULAR = 0x00 # regular section +S_ZEROFILL = 0x01 # zero fill on demand section +S_CSTRING_LITERALS = 0x02 # section with only literal C strings +S_4BYTE_LITERALS = 0x03 # section with only 4 byte literals +S_8BYTE_LITERALS = 0x04 # section with only 8 byte literals +S_LITERAL_POINTERS = 0x05 # section with only pointers to +S_NON_LAZY_SYMBOL_POINTERS = 0x06 # section with only non-lazy symbol pointers +S_LAZY_SYMBOL_POINTERS = 0x07 # section with only lazy symbol pointers +S_SYMBOL_STUBS = 0x08 # section with only symbol stubs, byte size of stub in the reserved2 field +S_MOD_INIT_FUNC_POINTERS = 0x09 # section with only function pointers for initializatio +S_MOD_TERM_FUNC_POINTERS = 0x0a # section with only function pointers for termination +S_COALESCED = 0x0b # section contains symbols that are to be coalesced +S_GB_ZEROFILL = 0x0c # zero fill on demand section (that can be larger than 4 gigabytes) +S_INTERPOSING = 0x0d # section with only pairs of function pointers for interposing +S_16BYTE_LITERALS = 0x0e # section with only 16 byte literals +S_DTRACE_DOF = 0x0f # section contains DTrace Object Format +S_THREAD_LOCAL_REGULAR = 0x11 # template of initial values for TLVs +S_THREAD_LOCAL_ZEROFILL = 0x12 # template of initial values for TLVs +S_THREAD_LOCAL_VARIABLES = 0x13 # TLV descriptors +S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14 # pointers to TLV descriptors +S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15 # functions to call to initialize TLV values + +SECTION_ATTRIBUTES_USR = 0xff000000 # User setable attributes +S_ATTR_PURE_INSTRUCTIONS = 0x80000000 # section contains only true machine instructions +S_ATTR_NO_TOC = 0x40000000 # section contains coalesced symbols that are not to be in a ranlib table of contents +S_ATTR_STRIP_STATIC_SYMS = 0x20000000 # ok to strip static symbols in this section in files with the MH_DYLDLINK flag +S_ATTR_NO_DEAD_STRIP = 0x10000000 # no dead stripping +S_ATTR_LIVE_SUPPORT = 0x08000000 # blocks are live if they reference live blocks +S_ATTR_SELF_MODIFYING_CODE = 0x04000000 # Used with i386 code stubs written on by dyld +S_ATTR_DEBUG = 0x02000000 # a debug section +SECTION_ATTRIBUTES_SYS = 0x00ffff00 # system setable attributes +S_ATTR_SOME_INSTRUCTIONS = 0x00000400 # section contains some machine instructions +S_ATTR_EXT_RELOC = 0x00000200 # section has external relocation entries +S_ATTR_LOC_RELOC = 0x00000100 # section has local relocation entries + +SEG_PAGEZERO = "__PAGEZERO" # the pagezero segment which has no protections and catches NULL references +SEG_TEXT = "__TEXT" # the tradition UNIX text segment */ +SECT_TEXT = "__text" # the real text part of the text section no headers, and no padding */ +SEG_DATA = "__DATA" # the tradition UNIX data segment */ +SECT_DATA = "__data" # the real initialized data section, no padding, no bss overlap */ +SECT_BSS = "__bss" # the real uninitialized data section, no padding */ +SECT_COMMON = "__common" # the section common symbols are allocated in by the link editor */ + +# not-a-section value for n_sect +NO_SECT = 0x00 # section numbers start at 1 + +# nlist n_type values +N_STAB = 0xe0 # mask for debugger symbols +N_TYPE = 0x0e # mask for symbol type + +N_PEXT = 0x10 # symbol is private-extern +N_EXT = 0x01 # symbol is external + +N_UNDF = 0x00 # symbol is undefined +N_ABS = 0x02 # absolute (n_sect is NO_SECT) +#N_TEXT = 0x04 # text symbol +N_DATA = 0x06 # data symbol +#N_BSS = 0x08 # bss symbol +N_INDR = 0x0a # symbol is indirect (n_value is string table index) +N_SECT = 0x0e # symbol is in n_sect +#N_COMM = 0x12 # common symbol +#N_FN = 0x1e # filename + +# nlist n_desc values +N_WEAK_REF = 0x40 # weak reference (value may be zero) +N_WEAK_DEF = 0x80 # weak definition +N_ARM_THUMB_DEF = 0x0008 # Thumb function + +# selected STAB symbol types +# fields listed here are n_name, n_sect, n_desc, n_value +N_GSYM = 0x20 # global symbol: name,NO_SECT,type,0 +N_FUN = 0x24 # procedure: name,n_sect,linenumber,address +N_STSYM = 0x26 # static symbol: name,n_sect,type,address +N_LCSYM = 0x28 # .lcomm symbol: name,n_sect,type,address +N_BNSYM = 0x2e # begin nsect sym: 0,n_sect,0,address +N_OPT = 0x3c # emitted with gcc2_compiled and in gcc source +N_RSYM = 0x40 # register sym: name,NO_SECT,type,register +N_SLINE = 0x44 # src line: 0,n_sect,linenumber,address +N_ENSYM = 0x4e # end nsect sym: 0,n_sect,0,address +N_SSYM = 0x60 # structure elt: name,NO_SECT,type,struct_offset +N_SO = 0x64 # source file name: name,n_sect,0,address +N_OSO = 0x66 # object file name: name,0,0,st_mtime +N_LSYM = 0x80 # local sym: name,NO_SECT,type,offset +N_BINCL = 0x82 # include file beginning: name,NO_SECT,0,sum +N_SOL = 0x84 # #included file name: name,n_sect,0,address +N_PARAMS = 0x86 # compiler parameters: name,NO_SECT,0,0 +N_VERSION = 0x88 # compiler version: name,NO_SECT,0,0 +N_OLEVEL = 0x8A # compiler -O level: name,NO_SECT,0,0 +N_PSYM = 0xa0 # parameter: name,NO_SECT,type,offset +N_EINCL = 0xa2 # include file end: name,NO_SECT,0,0 +N_ENTRY = 0xa4 # alternate entry: name,n_sect,linenumber,address +N_LBRAC = 0xc0 # left bracket: 0,NO_SECT,nesting level,address +N_EXCL = 0xc2 # deleted include file: name,NO_SECT,0,sum +N_RBRAC = 0xe0 # right bracket: 0,NO_SECT,nesting level,address +N_BCOMM = 0xe2 # begin common: name,NO_SECT,0,0 +N_ECOMM = 0xe4 # end common: name,n_sect,0,0 +N_ECOML = 0xe8 # end common (local name): 0,n_sect,0,address +N_LENG = 0xfe # second stab entry with length information + + +def dict_from_struct(with_bytes, using_struct, to_names): + result = {} + + # unpack + values = using_struct.unpack(str(with_bytes)) + + # walk the unpacked values + keys = to_names.split(" ") + for i in range(0, len(keys)): + result[keys[i]] = values[i] + return result + + +class File(object): + """toplevel object representing a mach-o file""" + # struct mach_header + # { + # uint32_t magic; + # cpu_type_t cputype; + # cpu_subtype_t cpusubtype; + # uint32_t filetype; + # uint32_t ncmds; + # uint32_t sizeofcmds; + # uint32_t flags; + # }; + # struct mach_header_64 + # { + # uint32_t magic; + # cpu_type_t cputype; + # cpu_subtype_t cpusubtype; + # uint32_t filetype; + # uint32_t ncmds; + # uint32_t sizeofcmds; + # uint32_t flags; + # uint32_t reserved; + # }; + mach_header_magic32 = 0xfeedface + mach_header_magic64 = 0xfeedfacf + mach_header_f = "IiiIIII" + mach_header_n = "magic cputype cpusubtype filetype ncmds sizeofcmds flags" + + def __init__(self, file, debug=False): + self._symtab = None + self._stringtab = None + self._segments = {} + self._sections = {} + self._section_index = 1 + self._uuid = None + self._debug = debug + + # stash the file and the header offset + self._file = file + + # read the file header + self._properties = self.unpack(self.mach_header_f, self.mach_header_n) + + # skip the reserved field in a 64-bit header + if self['magic'] == self.mach_header_magic64: + self._file.seek(4, io.SEEK_CUR) + elif self['magic'] != self.mach_header_magic32: + raise RuntimeError("bad magic number {:#010x} in mach-o header".format(self['magic'])) + + # read load commands + for i in range(1, self['ncmds']): + cmd = LoadCommand.from_file(self) + + # reset the file pointer to the next load command +# print "seek to load command at {} + {}".format(cmd['__offset'], cmd['cmdsize']) + self._file.seek(cmd['__offset'] + cmd['cmdsize']) + + def debug(self, str): + if self._debug is not False: + print str + + # access to the UUID + @property + def uuid(self): + return self._uuid + + @uuid.setter + def uuid(self, value): + self._uuid = value + + # access to the symbol table + @property + def symtab(self): + return self._symtab + + @symtab.setter + def symtab(self, value): + self._symtab = value + + # access to the string table + @property + def stringtab(self): + return self._stringtab + + @stringtab.setter + def stringtab(self, value): + self._stringtab = value + + # access to the segment list + @property + def segments(self): + return self._segments + + # segments call this to self-register + def add_segment(self, segment): + self.debug("segment " + segment['segname']) + self._segments[segment['segname']] = segment + + # access to the section list + @property + def sections(self): + return self._sections + + def sections_inorder(self): + '''iterate sections in file order''' + for i in range(1, self._section_index - 1): + yield self._sections[i] + + # sections call this to self-register + def add_section(self, section): + sectionname = "{},{}".format(section['segname'], section['sectname']) + self.debug("section {}:{} @ {}".format(self._section_index, sectionname, section['offset'])) + self._sections[self._section_index] = section + self._section_index += 1 + self._sections[sectionname] = section + + # get the object file flavor (32/64) + @property + def flavor(self): + if self['magic'] == self.mach_header_magic32: + return 32 + return 64 + + # allow properties to be fetched by indexing us + def __getitem__(self, index): + if index in self._properties: + return self._properties[index] + else: + return None + + # unpack a structure from the file + def unpack(self, format, names, offset=-1, rewind=False): + + # if we are told to seek, do that now + if offset != -1: + self._file.seek(offset) + + # remember where we read from + pre_offset = self._file.tell() + + # fetch the data and unpack it + s = struct.Struct(format) + bytes = self.readbytes(s.size, offset, rewind) + result = dict_from_struct(bytes, s, names) + + # default result dict entries + result['__offset'] = pre_offset + result['__dirty'] = False + + # if we were asked to rewind + if rewind is True: + self._file.seek(pre_offset) + + return result + + # repack a structure into the file + def repack(self, format, names, props): + + # make a list of the property arguments for the format + values = [props[key] for key in names.split()] + s = struct.Struct(format) + bytes = s.pack(*values) + + self.writebytes(bytes, props['__offset']) + + # read bytes from the file + def readbytes(self, size, offset=-1, rewind=False): + o_offset = self._file.tell() + if offset != -1: + self._file.seek(offset) + bytes = self._file.read(size) + if rewind is True: + self._file.seek(o_offset) + return bytearray(bytes) + + # write bytes to the file + def writebytes(self, bytes, offset=-1): + if offset != -1: + self._file.seek(offset) + count = len(bytes) + wrote = self._file.write(bytes) + if wrote != count: + raise RuntimeError("tried to write {} bytes, only wrote {} bytes".format(count, wrote)) + + # push any updates out to the file + def update(self): + updated = False + for i in range(1, self._section_index): + if self._sections[i].update(): + updated = True + if updated: + self._file.flush() + return updated + + # locate a segment by name + def segment_for_name(self, name): + if name in self._segments: + return self._segments[name] + return None + + # locate the section that contains data for a given address range + def section_for_address(self, addr): + for sect in self._sections.itervalues(): + saddr = sect['addr'] + send = saddr + sect['size'] + if (saddr <= addr) and (send > addr): + return sect + return None + + # locate a section by name + def section_for_name(self, name): + if name in self._sections: + return self._sections[name] + return None + + # locate symbols in a section + def symbols_in_section(self, name): + matching = {'section': name} + return self._symtab.matching(matching) + + # locate symbols referencing an address + def symbols_for_address(self, addr): + matching = {'n_value': addr, 'n_type': N_ABS} + return self._symtab.matching(matching) + + +class LoadCommand(object): + """base class for load commands""" + + # struct load_command + # { + # uint32_t cmd; + # uint32_t cmdsize; + # }; + lc_names = { + 0x00000001: "LC_SEGMENT", + 0x00000002: "LC_SYMTAB", + 0x00000019: "LC_SEGMENT_64", + 0x0000001b: "LC_UUID", + 0x00000026: "LC_FUNCTION_STARTS", + 0x00000029: "LC_DATA_IN_CODE", + 0x0000002A: "LC_SOURCE_VERSION", + } + load_command_f = "II" + load_command_n = "cmd cmdsize" + + @classmethod + def from_file(cls, parent): + + # read the header and reset the file pointer so that a subclass + # will get the whole thing + properties = parent.unpack(cls.load_command_f, cls.load_command_n, rewind=True) + + # hand off to the first subclass that is interested in it + obj = None + for subcls in cls.__subclasses__(): + obj = subcls.for_load_command(properties['cmd'], parent) + if obj is not None: + break + + # if we didn't find a subclass, return a dummy so that it can be skipped + if obj is None: +# print "ignoring unhandled section {}".format(properties['cmd']) + obj = LoadCommand(parent) + + return obj + + def __init__(self, parent): + self._properties = parent.unpack(self.load_command_f, self.load_command_n) + + # allow properties to be fetched by indexing us + def __getitem__(self, index): + if index in self._properties: + return self._properties[index] + else: + return None + + +class Segment(LoadCommand): + """handles segment commands""" + + # struct segment_command + # { + # uint32_t cmd; + # uint32_t cmdsize; + # char segname[16]; + # uint32_t vmaddr; + # uint32_t vmsize; + # uint32_t fileoff; + # uint32_t filesize; + # vm_prot_t maxprot; + # vm_prot_t initprot; + # uint32_t nsects; + # uint32_t flags; + # }; + # struct segment_command_64 + # { + # uint32_t cmd; + # uint32_t cmdsize; + # char segname[16]; + # uint64_t vmaddr; + # uint64_t vmsize; + # uint64_t fileoff; + # uint64_t filesize; + # vm_prot_t maxprot; + # vm_prot_t initprot; + # uint32_t nsects; + # uint32_t flags; + # }; + segment_command32_f = "II16sIIIIiiII" + segment_command64_f = "II16sQQQQiiII" + segment_command_n = "cmd cmdsize segname vmaddr vmsize fileoff filesize maxprot initprot nsects flags" + + @classmethod + def for_load_command(cls, cmd, parent): + if cmd in cls.lc_names: + if cls.lc_names[cmd] == "LC_SEGMENT": + return cls(cmd, parent, 32) + if cls.lc_names[cmd] == "LC_SEGMENT_64": + return cls(cmd, parent, 64) + return None + + def __init__(self, cmd, parent, flavor): + if flavor == 32: + self._properties = parent.unpack(self.segment_command32_f, self.segment_command_n) + else: + self._properties = parent.unpack(self.segment_command64_f, self.segment_command_n) + + # strip NULs from the segment name + self._properties['segname'] = self._properties['segname'].rstrip("\x00") + + # advertise to the parent + parent.add_segment(self) + + # iterate sections + for i in range(0, self['nsects']): + Section(parent, flavor) + + +class Section(object): + """base class for text/data sections""" + + # struct section + # { + # char sectname[16]; + # char segname[16]; + # uint32_t addr; + # uint32_t size; + # uint32_t offset; + # uint32_t align; + # uint32_t reloff; + # uint32_t nreloc; + # uint32_t flags; + # uint32_t reserved1; /* offset or index */ + # uint32_t reserved2; /* count or sizeof */ + # }; + # struct section_64 + # { + # char sectname[16]; + # char segname[16]; + # uint64_t addr; + # uint64_t size; + # uint32_t offset; + # uint32_t align; + # uint32_t reloff; + # uint32_t nreloc; + # uint32_t flags; + # uint32_t reserved1; /* offset or index */ + # uint32_t reserved2; /* count or sizeof */ + # uint32_t reserved3; + # }; + section32_f = "16s16sIIIIIIIII" + section64_f = "16s16sQQIIIIIIII" + section_n = "sectname segname addr size offset align reloff nreloc flags index count" + + def __init__(self, parent, flavor): + if flavor == 32: + self._properties = parent.unpack(self.section32_f, self.section_n) + else: + self._properties = parent.unpack(self.section64_f, self.section_n) + + # strip NULs from the segment and section names + self._properties['segname'] = self._properties['segname'].rstrip("\x00") + self._properties['sectname'] = self._properties['sectname'].rstrip("\x00") + + # give ourselves a canonical name + self._properties['name'] = "{},{}".format(self['segname'], self['sectname']) + + # register so that we can be found by either name or index + self._parent = parent + parent.add_section(self) + + # allow properties to be fetched by indexing us + # and for a slice to index the 'bytes' property + def __getitem__(self, index): + + if isinstance(index, slice): + return self['bytes'][index] + + if index not in self._properties: + if index == 'bytes': + # can't mess with bytes in a zerofill section + if (self['flags'] & SECTION_TYPE) == S_ZEROFILL: + return None +# self._parent.debug("read {}/{}".format(self['offset'], self['size'])) + v = self._parent.readbytes(self['size'], offset=self['offset']) +# print ord(v[0]), ord(v[1]), ord(v[2]), ord(v[3]) + elif index == 'end': + v = self['addr'] + self['size'] - 1 + else: + return None + self._properties[index] = v + return self._properties[index] + + # allow some properties to be changed + def __setitem__(self, index, value): + if isinstance(index, slice): + # prefetch the 'bytes' property + value = self['bytes'] + self._properties['bytes'][index] = value + + if index == 'bytes': + if len(value) != self['size']: + raise RuntimeError("wrong size for section data") + self._properties['bytes'] = value + self._properties['__dirty'] = True + else: + raise RuntimeError("section attribute '{}' is not writable", index) + + # if we have been dirtied by e.g. variable patching, write our bytes back + def update(self): + if self['__dirty']: + self._parent.writebytes(self['bytes'], self['offset']) + self._properties['__dirty'] = False + return True + return False + +class Symtab(LoadCommand): + """symbol table""" + + # struct symtab_command + # { + # uint_32 cmd; + # uint_32 cmdsize; + # uint_32 symoff; + # uint_32 nsyms; + # uint_32 stroff; + # uint_32 strsize; + # }; + symtab_f = "IIIIII" + symtab_n = "cmd cmdsize symoff nsyms stroff strsize" + + @classmethod + def for_load_command(cls, cmd, parent): + if cmd in cls.lc_names: + if cls.lc_names[cmd] in ("LC_SYMTAB"): + return cls(parent) + return None + + def __init__(self, parent): + self._nlist = [] + + # read the symtab header + self._properties = parent.unpack(self.symtab_f, self.symtab_n) + + # read the string table first + parent.stringtab = StringTable(parent, self['stroff'], self['strsize']) + + # read the name list + self._nlist.append(Nlist(parent, self['symoff'])) + for n in range(2, self['nsyms']): + self._nlist.append(Nlist(parent)) + +# print "symtab: {} symbols".format(len(self._nlist)) + + parent.symtab = self + + # find symbols matching a dictionary + def matching(self, matching_dict): + result = [] + + # walk the symbol set looking for matches + for sym in self._nlist: +# print " {}:".format(sym['name']) + + if sym.matches(matching_dict): + result.append(sym) + + return result + + +class StringTable(object): + """a string table""" + + _strings = {} + + def __init__(self, parent, offset, size): + # read the raw string table from the file + bytes = parent.readbytes(size, offset=offset) + + # parse out NUL-separate strings and index them + index = 0 + ptr = -1 + s = "" + for c in bytes: + ptr += 1 + if c == 0: + if len(s) > 0: +# print "strtab: {} '{}'".format(index, s) + self._strings[index] = s + parent.debug("string {}:'{}'".format(index, s)) + s = "" + else: + if len(s) == 0: + index = ptr; + s += chr(c) + + def __getitem__(self, index): + if index in self._strings: + return self._strings[index] + elif index == 0: + return "" + else: + return None + +class UUIDCommand(LoadCommand): + """handles segment commands""" + + # struct uuid_command + # { + # uint32_t cmd; + # uint32_t cmdsize; + # uint8_t uuid[16]; + # }; + uuid_command_f = "II16s" + uuid_command_n = "cmd cmdsize uuid" + + @classmethod + def for_load_command(cls, cmd, parent): + if cmd in cls.lc_names: + if cls.lc_names[cmd] == "LC_UUID": + return cls(cmd, parent) + return None + + def __init__(self, cmd, parent): + self._properties = parent.unpack(self.uuid_command_f, self.uuid_command_n) + + parent.debug('uuid: {}'.format(self._properties)) + + # advertise to the parent + parent.uuid = self._properties['uuid'] + +class Nlist(object): + """a symbol table entry""" + + # struct nlist + # { + # union { + # int32_t n_strx; /* string table offset */ + # } n_un; + # uint8_t n_type; /* symbol type */ + # uint8_t n_sect; /* section index */ + # int16_t n_desc; /* debug description */ + # uint32_t n_value; /* address/value */ + # }; + # struct nlist_64 + # { + # union { + # uint32_t n_strx; + # } n_un; + # uint8_t n_type; + # uint8_t n_sect; + # uint16_t n_desc; + # uint64_t n_value; + # }; + nlist32_f = "IBBHI" + nlist64_f = "IBBHQ" + nlist_n = "n_strx n_type n_sect n_desc n_value" + + def __init__(self, parent, offset=-1): + if parent.flavor == 32: + self._properties = parent.unpack(self.nlist32_f, self.nlist_n, offset=offset) + elif parent.flavor == 64: + self._properties = parent.unpack(self.nlist64_f, self.nlist_n, offset=offset) + else: + raise RuntimeError("bad nlist flavor") + + # save a reference to the parent, we need it for lazy name evaluation + self._parent = parent + self['name'] + parent.debug("symbol {}".format(self._properties)) + + # match the symbol against a dictionary of same + def matches(self, matching_dict): + + # walk the matching dictionary + for key in matching_dict: + + # fetch the symbol's value for this key; if we don't + # have a value we cannot match + v = self[key] + if v is None: + return False + c = matching_dict[key] + + # simple integer match? + if isinstance(c, int): + if c != v: + return False + continue + + # integer masking match? + if isinstance(c, tuple) and (len(c) == 3): + mask, require, prohibit = c + v &= mask + if (v & prohibit) != 0: + return False + if (v & require) != require: + return False + continue + + # string match? + if isinstance(c, str): + r = re.compile(c) + m = r.match(v) + if m is None: + return False + continue + + # don't actually know how to handle this... + raise RuntimeError("don't know how to match '{}' using '{}'".format(key, v)) + + return True + + # Allow properties to be fetched by indexing us + # + # As some properties aren't known as parse time (e.g. section names) + # we look them up lazily. + # + def __getitem__(self, index): + if index not in self._properties: + v = None + if index == 'name': + v = self._parent.stringtab[self['n_strx']] + elif index == 'sectname': + i = self['n_sect'] + if i not in self._parent.sections: + return None + v = self._parent.sections[i]['name'] + elif index == 'section': + stype = self._properties['n_type'] & N_TYPE + if stype == N_ABS or stype == N_DATA: + v = self._parent.section_for_address(self['n_value']) + elif stype == N_SECT: + v = self._parent.sections[self['n_sect']] + self._properties[index] = v + return self._properties[index] + + # Read from whatever the symbol points to + def unpack(self, format, names): + + # look up the section we're operating on + sect = self['section'] + addr = self['n_value'] + offset = addr - sect['addr'] +# self._parent.debug("addr 0x{:x} section addr 0x{:x} offset 0x{:x}".format(addr, sect['addr'], offset)) + bytes = sect['bytes'] + + if format == 'C': # Non-standard C String format + chunk = bytes[offset:bytes.index('\0', offset)] + s = struct.Struct('%ds' % len(chunk)) + else: + # slice the requested range and decode + s = struct.Struct(format) +# print "{}:{}".format(offset, offset + s.size) + chunk = bytes[offset:(offset + s.size)] + + return dict_from_struct(chunk, s, names) + + # write to whatever the symbol points to + # + # XXX needs to be updated to take a dict as argument + def pack(self, format, values): + + # look up the section we're operating on + sect = self['section'] + addr = self['n_value'] + offset = addr - sect['addr'] + + # encode the values + self._parent.debug("packing {}".format(values)) + s = struct.Struct(format) + chunk = s.pack(*values) + + # and update the section + bytes = sect['bytes'] + bytes[offset:(offset + s.size)] = chunk + sect['bytes'] = bytes + + # dereference the symbol and get a single value it points to + def deref(self, format): + contents = self.unpack(format, 'value') + return contents['value'] + + # assign a value to the thing the symbol references + def assign(self, format, value): + self.pack(format, [value]) + + +def to_binary(macho, output, verbose=False): + '''emit a compact in-memory binary representation of the mach-o file''' + + output.seek(0) + data_offset = 0 + for section in macho.sections_inorder(): + + # We assume that we simply want to pack all of the + # text/data sections in the input file into the output, and + # that we should stop once we hit a zero-filled section because + # we've run out of data. + + if (((section['flags'] & S_ZEROFILL) != 0) or + (section['sectname'] == '__common') or + (section['sectname'] == '__bss')): + break + + # Make a note of where we are in the output file when + # we start processing sections in the __DATA segment + if data_offset == 0 and section['segname'] == '__DATA': + data_offset = output.tell() + + # pad sections to maintain alignment + alignment = 1 << section['align'] + if section['segname'] == '__DATA': + skew = data_offset + else: + skew = 0 + padding = (alignment - ((output.tell() - skew) % alignment)) % alignment + + zeros = bytearray.fromhex('00' * padding) + output.write(zeros) + + # write the section contents + if section['size'] > 0: + if verbose is True: + print '{}/{} 0x{:x}/0x{:x} @ 0x{:x}'.format(section['segname'], + section['sectname'], + section['addr'], + section['size'], + output.tell()) + output.write(section['bytes']) + + +# +# Be a useful utility. +# +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description='mach-o utility') + parser.add_argument('-m', '--macho', required=True, + help='path to the mach-o file') + parser.add_argument('-o', '--output', + help='path to the output file') + parser.add_argument('-c', '--convert', dest='format', choices=['binary', 'TBD'], + help='convert to the specified format') + parser.add_argument('-v', '--verbose', default=False, action='store_true', + help='enable verbose output') + parser.add_argument('-d', '--debug', default=False, action='store_true', + help='enable debug output') + + args = parser.parse_args() + + try: + f = File(io.open(args.macho, 'rb'), args.debug) + except: + print "macho: failed opening " + args.macho + raise + + if args.format == 'binary' or args.format == 'objcopy': + if args.output is None: + raise RuntimeError("missing -o argument to specify output name") + o = io.open(args.output, 'wb') + + to_binary(f, o, args.verbose) + o.close() + diff --git a/tools/macho_post_process.py b/tools/macho_post_process.py new file mode 100644 index 0000000..af04c5d --- /dev/null +++ b/tools/macho_post_process.py @@ -0,0 +1,137 @@ +#!/usr/bin/python +# +# Copyright (C) 2013-2015 Apple Inc. All rights reserved. +# +# This document is the property of Apple Inc. +# It is considered confidential and proprietary. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Apple Inc. +# + +# +# RTXC Mach-o post processing +# + +from __future__ import print_function +from argparse import ArgumentParser +import macho +import io +from struct import Struct +import subprocess +from uuid import UUID + + +def memory_slices(data, size): + m = memoryview(data) + + for index in xrange(0, len(data), size): + yield m[index:index+size] + + +def hexdump(bytes, stride=16): + for i, data in enumerate(memory_slices(bytes, stride)): + dataString = ' '.join(map('{:02X}'.format, data.tolist())) + print('{:04x}: {}'.format(i * stride, dataString)) + +from collections import namedtuple + +def magicToInt(string, format=' 0} { + parse_line $line +} diff --git a/tools/ofile_cstring_sizes b/tools/ofile_cstring_sizes new file mode 100644 index 0000000..54a16a7 --- /dev/null +++ b/tools/ofile_cstring_sizes @@ -0,0 +1,57 @@ +#!/usr/bin/python + +import string +import subprocess +import sys +import os.path + +def ofile_section_info(path): + sections = [] + otool_output = subprocess.Popen(["otool", "-l", path], stdout=subprocess.PIPE).communicate()[0] + for section_text in string.split(otool_output, "Section\n")[1:]: + section = {} + for field_text in string.split(section_text, "\n"): + field_list = string.rsplit(string.strip(field_text)) + if len(field_list) == 2: + section[field_list[0]] = field_list[1] + sections.append(section) + return sections + +def ofile_cstring_size(path): + sections = ofile_section_info(path) + size = "0x00000000" + for section in sections: + if section['sectname'] == "__cstring" and section['segname'] == "__TEXT": + size = section['size'] + pair = (size, path) + return pair + +def is_ofile(path): + return os.path.isfile(path) and os.path.splitext(path)[1] == ".o" + +def dir_visitor(size_path_pairs, dir_path, names): + size_path_pairs.extend(map(ofile_cstring_size, + filter(is_ofile, + map(lambda n: os.path.join(dir_path, n), names)))) + +def main(paths): + size_path_pairs = [] + for path in paths: + if os.path.isdir(path): + os.path.walk(path, dir_visitor, size_path_pairs) + elif is_ofile(path): + size_path_pairs.append(ofile_cstring_size(path)) + for (ofile_size, ofile_path) in size_path_pairs: + sys.stdout.write("%s\t%s\n" % (ofile_size, ofile_path)); + +def usage(): + sys.stdout.write("%s path(s)...\n\n" % os.path.basename(sys.argv[0])) + sys.stdout.write("\tReport the cstring section sizes for each .o" + " file specified and for all .o files recursively" + " found under each specified directory.\n") + +if __name__ == "__main__": + if len(sys.argv) < 2: + usage() + else: + main(sys.argv[1:]) diff --git a/tools/oldskool_csvtopinconfig.py b/tools/oldskool_csvtopinconfig.py new file mode 100644 index 0000000..c226df7 --- /dev/null +++ b/tools/oldskool_csvtopinconfig.py @@ -0,0 +1,893 @@ +#!/usr/bin/python +import argparse +import collections +import csv +import pipes +import sys + +try: + import openpyxl +except ImportError: + openpyxl = None + +class ParseError(Exception): pass + +''' +Representation of one pin in the GPIO config +''' +class BasePin(object): + default_drive = 'X1' + valid_pupdn = set(["PULL_UP", "PULL_DOWN", ""]) + valid_drive_strength = set() + def __init__(self, gpio_pin_number): + self.gpio_pin_number = int(gpio_pin_number) + self.bump_name = None + self.net_name = None + self.function = None + self.drive_strength = 'X1' + self.pupd = None + self.bus_hold = None + self.input_mode = None + self.row_number = None + self.slew_rate = '' + self.rom = None + + def to_pinconfig_line(self): + if None in (self.bump_name, self.net_name, self.function, self.drive_strength, self.pupd): + raise ParseError, "Some attributes were unset for pin %d: %s" % (self.gpio_pin_number, (self.bump_name, self.net_name, self.function, self.drive_strength, self.pupd)) + + if self.drive_strength == self.default_drive: + drive_strength = '' + else: + drive_strength = "DRIVE_{}".format(self.drive_strength) + + if self.slew_rate == '': + slew_rate = '' + else: + slew_rate = "{}_SLEW".format(self.slew_rate) + + non_empty_props = [i for i in [self.function, self.pupd, drive_strength, slew_rate, self.bus_hold, self.input_mode] if i] + args = " | ".join(non_empty_props) + "," + return [args, "// {:>3} : {}".format(self.gpio_pin_number, self.bump_name), "-> " + self.net_name] + + def set_function(self, fn): + cfg_map = { 'in': 'CFG_IN', + 'input': 'CFG_IN', + 'out0': 'CFG_OUT_0', + 'out 0': 'CFG_OUT_0', + 'out1': 'CFG_OUT_1', + 'out 1': 'CFG_OUT_1', + 'alt func 0': 'CFG_FUNC0', + 'alt func 1': 'CFG_FUNC1', + 'alt func 2': 'CFG_FUNC2', + 'int rising': 'CFG_IN', + 'int falling': 'CFG_IN', + 'int any': 'CFG_IN', + 'disable': 'CFG_DISABLED', + 'disabled': 'CFG_DISABLED', + # The numbering offset isn't a typo, these are legacy + 'function 1': 'CFG_FUNC0', + 'function 2': 'CFG_FUNC1', + 'function 3': 'CFG_FUNC2', + } + self.function = cfg_map[fn.lower()] + + def set_net_name(self, name): + self.net_name = name.strip() + + def set_bump_name(self, name): + self.bump_name = name.strip() + + def set_drive_strength(self, strength): + if strength == '': + strength = self.default_drive + else: + strength = strength.upper() + + if strength.isdigit(): + strength = self.drive_strength_prefix + strength + + if not strength in self.valid_drive_strength: + sorted_drive_strengths = sorted(self.valid_drive_strength, key=lambda item: (int(item[1:]))) + raise ParseError, "drive strength '{}' not valid (options are {})".format(strength.upper(), sorted_drive_strengths) + self.drive_strength = strength + + def set_pupd(self, pupd): + pupd_map = { 'pullup strong' : 'PULL_UP_STRONG', + 'spu' : 'PULL_UP_STRONG', + 'pullup': 'PULL_UP', + 'pu': 'PULL_UP', + 'pulldown': 'PULL_DOWN', + 'pd': 'PULL_DOWN', + 'disable': '', + '': ''} + if not pupd_map[pupd.lower()] in self.valid_pupdn: + pretty_pupdn = filter(lambda x : pupd_map[x] in self.valid_pupdn , pupd_map.keys()) + raise ParseError, "pu/pd value '{}' not valid (options are {})".format(pupd, pretty_pupdn) + self.pupd = pupd_map[pupd.lower()] + + +class PinV1(BasePin): + valid_drive_strength = set(["X1", "X2", "X3", "X4"]) + drive_strength_prefix = 'X' + + def set_bus_hold(self, hold): + bus_hold_map = { '': '', '0': '', None: '', 'y': 'BUS_HOLD', 'yes': 'BUS_HOLD', '1': 'BUS_HOLD'} + self.bus_hold = bus_hold_map[hold.lower()] + +class PinV2(BasePin): + valid_drive_strength = set(["X1", "X2", "X4", "X6"]) + drive_strength_prefix = 'X' + + def set_bus_hold(self, hold): + bus_hold_map = { '': '', '0': '', None: '', 'y': 'BUS_HOLD', 'yes': 'BUS_HOLD', '1': 'BUS_HOLD'} + self.bus_hold = bus_hold_map[hold.lower()] + +class PinV3(BasePin): + valid_drive_strength = set(["X1", "X2", "X4", "X6"]) + drive_strength_prefix = 'X' + + def set_slew_rate(self, slew): + slew_map = { '': '', None: '', "fast": "FAST", "slow": "SLOW" } + self.slew_rate = slew_map[slew.lower()] + +class PinV4(PinV3): + def set_input_mode(self, mode): + mode_map = { '': '', None: '', 'cmos': '', 'schmitt': 'INPUT_SCHMITT', 'Schmitt': 'INPUT_SCHMITT'} + self.input_mode = mode_map[mode] + +class PinV5(PinV4): + default_drive = 'S0' + valid_drive_strength = set(["S0", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "S12", "S13", "S14", "S15"]) + drive_strength_prefix = 'S' + valid_pupdn = set(["PULL_UP_STRONG", "PULL_UP", "PULL_DOWN", ""]) + + def set_slew_rate(self, slew): + slew_map = { '': '', None: '', "fast": "FAST", "slow": "SLOW", "very fast": "VERY_FAST" } + self.slew_rate = slew_map[slew.lower()] + + +class ReservedPin(object): + def to_pinconfig_line(self): + return ["CFG_DISABLED,"] + +class GPIODomainInfo(object): + def __init__(self, offset, count, reserved): + self.id_offset = offset + self.pin_count = count + self.reserved_pins = reserved + +class GPIODomain(object): + def __init__(self, info, pin_class): + self.id_offset = info.id_offset + self.pin_count = info.pin_count + self.reserved_pins = info.reserved_pins + + # GPIO domains must start and end on 8-pin boundaries + assert self.id_offset % 8 == 0 + if self.pin_count % 8 != 0: + new_pin_count = self.pin_count + 8 - self.pin_count % 8 + self.reserved_pins |= set(range(self.id_offset + self.pin_count, self.id_offset + new_pin_count)) + self.pin_count = new_pin_count + + self.pins = [None] * self.pin_count + + for i in range(self.pin_count): + if not i + self.id_offset in self.reserved_pins: + pin = pin_class(i) + pin.set_bump_name("UNSPECIFIED") + pin.set_net_name("UNSPECIFIED") + pin.set_function("disable") + pin.set_pupd("disable") + pin.set_drive_strength('') + else: + pin = ReservedPin() + self.pins[i] = pin + + def has_pin_id(self, pin_id): + return pin_id >= self.id_offset and pin_id < self.id_offset + self.pin_count + + def get_pin(self, pin_id): + if not self.has_pin_id(pin_id): + raise IndexError + return self.pins[pin_id - self.id_offset] + +class BasePinConfig(object): + # Should be overridden in subclasses to a subclass of BasePin + pin_class = None + domain_info = None + + def __init__(self): + self.domains = [GPIODomain(info, self.pin_class) for info in self.domain_info] + + def get_pin(self, pin_id): + for d in self.domains: + if d.has_pin_id(pin_id): + return d.get_pin(pin_id) + raise IndexError + + def array_declaration(self, array_type, name, domain_index): + if domain_index == 0: + count_label = '' + else: + count_label = '_{}'.format(domain_index) + templ = 'static const {} {}_{}[GPIO{}_GROUP_COUNT * GPIOPADPINS] = {{' + return templ.format(array_type, name, domain_index, count_label) + + def to_pinconfig_struct(self, name, array_type, max_domains): + lines = [] + + for domain_idx in range(min(len(self.domains), max_domains)): + domain = self.domains[domain_idx] + + pin_matrix = [domain.pins[i].to_pinconfig_line() for i in range(domain.pin_count)] + pin_matrix = tab_align(pin_matrix, min_column_tabs={0: 8}) + + lines.append(self.array_declaration(array_type, name, domain_idx)) + + rownum = 0 + for row in pin_matrix: + if (rownum % 8) == 0: + lines.append("\n/* Port {:2} */".format(rownum/8)) + lines.append("\t"+"".join(row)) + rownum += 1 + lines.append("};") + lines.append('') + return "\n".join(lines) + +class BasePinConfigV1(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV1 + +class BasePinConfigV2(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV2 + +class BasePinConfigV3(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV3 + +class BasePinConfigV4(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV4 + +class BasePinConfigV5(BasePinConfig): + array_type = 'uint32_t' + pin_class = PinV5 + +class H4APinConfig(BasePinConfigV1): + domain_info = [GPIODomainInfo(offset=0, count=208, reserved=set())] + +class H5PPinConfig(BasePinConfigV2): + domain_info = [GPIODomainInfo(offset=0, count=232, reserved=set())] + +class H5GPinConfig(BasePinConfigV2): + reserved_pins = set(range(14, 32) + range(140, 160) + range(212, 224) + range(241, 248)) + domain_info = [GPIODomainInfo(offset=0, count=248, reserved=reserved_pins)] + +class AlcatrazPinConfig(BasePinConfigV3): + reserved_pins = set(range(24, 32) + range(45, 64) + range(151, 160) + range(173, 192)) + domain_info = [GPIODomainInfo(offset=0, count=195, reserved=reserved_pins)] + +class FijiPinConfig(BasePinConfigV4): + reserved_pins = set(range(16, 32) + range(88, 96) + range(140, 160)) + domain_info = [GPIODomainInfo(offset=0, count=204, reserved=reserved_pins)] + +class CapriPinConfig(BasePinConfigV4): + reserved_pins = set(range(16, 32)) + domain_info = [GPIODomainInfo(offset=0, count=184, reserved=reserved_pins)] + +class M7PinConfig(BasePinConfigV4): + reserved_pins = set(range(10, 32)) + domain_info = [GPIODomainInfo(offset=0, count=138, reserved=reserved_pins), + GPIODomainInfo(offset=160, count=50, reserved=set())] + +class MauiPinConfig(BasePinConfigV4): + reserved_pins = set(range(55, 64) + range(92, 96) + range(152, 160) + range(168, 192)) + domain_info = [GPIODomainInfo(offset=0, count=199, reserved=reserved_pins), + GPIODomainInfo(offset=288, count=28, reserved=set())] + +class ElbaPinConfig(BasePinConfigV5): + reserved_pins = set(range(37, 64) + range(125, 128) + range(142, 160)) + domain_info = [GPIODomainInfo(offset=0, count=220, reserved=reserved_pins), + GPIODomainInfo(offset=288, count=28, reserved=set())] + +class CaymanPinConfig(BasePinConfigV5): + ap_reserved_pins = set(range(55, 64) + range(92, 96) + range(104, 128) + range(155, 160) + range(188, 192)) + aop_reserved_pins = set(range(318, 320) + range(330, 352)) + domain_info = [GPIODomainInfo(offset=0, count=208, reserved=ap_reserved_pins), # AP + GPIODomainInfo(offset=288, count=85, reserved=aop_reserved_pins), # AOP + GPIODomainInfo(offset=256, count=7, reserved=set())] # SEP + output_domains = 2 + +class M8PinConfig(BasePinConfigV5): + ap_reserved_pins = set(range(138, 160)) + aop_reserved_pins = set(range(264, 288)) + domain_info = [GPIODomainInfo(offset=32, count=139, reserved=ap_reserved_pins), # AP + GPIODomainInfo(offset=256, count=96, reserved=aop_reserved_pins), # AOP + GPIODomainInfo(offset=0, count=7, reserved=set()), + GPIODomainInfo(offset=192, count=96, reserved=set())] + output_domains = 2 + +def excel_reader(filename, sheet): + try: + workbook = openpyxl.load_workbook(filename, data_only=True) + except IOError: + sys.stderr.write('Could not open workbook {}\n'.format(filename)) + return None + try: + worksheet = workbook.get_sheet_by_name(sheet) + except KeyError: + sys.stderr.write('Could not open worksheet {}\n'.format(sheet)) + return None + + def row_generator(ws): + def cell_to_str(cell): + value = cell.value + if value is None: + value = '' + return unicode(value) + + for row in ws.rows: + yield [cell_to_str(cell) for cell in row] + + return row_generator(worksheet) + +def try_parse_hex(i): + try: + return int(i, 16) + except ValueError: + return None + +def row_is_empty(row): + for col in row: + if not col is None and len(col.strip()) > 0: + return False + return True + +def row_is_footer(row): + for col in row: + if not col is None: + stripped = col.strip() + if len(stripped) > 0 and stripped != '--': + return False + return True + +class CSVParser(object): + def __init__(self, pinconfig_class, per_target_headers): + self.pinconfig_class = pinconfig_class + self.per_target_headers = per_target_headers + self.targets = per_target_headers.keys() + # Map the standardized name for a property to a list of acceptable names + self.header_name_map = { 'gpio_id': ['gpio id', 'id'], + 'net_name': ['net name', 'net names'], + 'bump_name': ['ball name', 'pad name'], + 'configurable': ['gpio configurable'], + 'drive_strength': ['drive strength', 'drive strength (ma)'], + 'drive_strength_ap': ['drive strength form factor', 'drive strength ap'], + 'drive_strength_dev': ['drive strength dev'], + 'pupd': ['pu/pd', 'pullup/pulldown', 'pull-up/pull-down'], + 'function': ['config', 'dir', 'SecureROM config'], + 'rom': ['rom function']} + + if callable(getattr(self.pinconfig_class.pin_class, 'set_slew_rate', None)): + self.header_name_map['slew_rate'] = ['slew rate', 'gpio_sr'] + self.header_name_map['slew_rate_ap'] = ['slew rate form factor', 'gpio_sr ap'] + self.header_name_map['slew_rate_dev'] = ['slew rate dev', 'gpio_sr dev'] + + if callable(getattr(self.pinconfig_class.pin_class, 'set_bus_hold', None)): + self.header_name_map['bus_hold'] = ['bus hold', 'gpio_bh'] + + if callable(getattr(self.pinconfig_class.pin_class, 'set_input_mode', None)): + self.header_name_map['input_mode'] = ['input mode', 'input select', 'gpio_is'] + + def create_pinconfig(self): + return self.pinconfig_class() + + def parse_version(self, row): + for col in row: + lowercase_col = col.lower() + if 'rev' in lowercase_col or 'version' in lowercase_col or 'ver' in lowercase_col: + return lowercase_col + return None + + def canonical_header(self, header): + for canonical, options in self.header_name_map.iteritems(): + if header.lower() in options: + return canonical + return None + + def find_headers(self, row, rom): + lowercase_row = map(lambda x: x.lower(), row) + columns_per_target = {} + columns_per_config = collections.defaultdict(dict) + per_config_columns = set() + ignore_missing_keys = set() + missing_keys = set() + + # create a mapping from canonical header names to column indices + header_map = {} + for idx in range(len(lowercase_row)): + header = lowercase_row[idx] + canonical = self.canonical_header(header) + if canonical is None: + continue + header_map[canonical] = idx + + # some parameters can be specified per config (ap/dev). figure out + # which if any are done that way for this spreadsheet + config_names = ['ap', 'dev'] + for key in ['drive_strength', 'slew_rate', 'net_name']: + config_to_key_map = {x: '{}_{}'.format(key, x) for x in config_names} + per_config_keys = set(config_to_key_map.values()) + + if per_config_keys <= set(header_map): + assert True, 'error message' # XXX + # used in the loop below to skip over columns that are per config + per_config_columns.update(per_config_keys) + # passed back to the caller for use in parsing rows + for config in config_names: + columns_per_config[config][key] = header_map[config_to_key_map[config]] + ignore_missing_keys.add(key) + elif not per_config_keys.isdisjoint(set(header_map)): + # either all or none of per-config columns should be present + found = ', '.join(sorted(set(header_map) & per_config_keys)) + raise ParseError('All or none of the per-config {} columns must be specified (found {})'.format(key, found)) + else: + # this key isn't per config, so fall through to the logic below, but + # let the missing column checker know the per-config columns won't be present + ignore_missing_keys.update(per_config_keys) + + # If no per-config columns were set, then there's only one configuration. + # Set up the key map accordingly + if len(columns_per_config) == 0: + for key in ['drive_strength', 'slew_rate']: + columns_per_config['all'][key] = header_map[key] + + for target in self.targets: + target_header_name_map = self.per_target_headers[target] + columns_per_target[target] = {} + for key in self.header_name_map.keys(): + if key in per_config_columns: + continue + if key in target_header_name_map: + header = target_header_name_map[key] + # This value has a column per target, so find the per-target header in the row + try: + idx = lowercase_row.index(header.lower()) + except ValueError: + sys.stderr.write('Could not find target {}\'s "{}" column "{}"\n'.format(target, key, header)) + missing_keys.add(key) + columns_per_target[target][key] = idx + else: + # This value has one column for all targets, so find one of the standard headers in the row + for header in self.header_name_map[key]: + if header.lower() in lowercase_row: + idx = lowercase_row.index(header.lower()) + columns_per_target[target][key] = idx + break + else: + missing_keys.add(key) + + if rom: + for key, value in target_header_name_map.iteritems(): + if key == 'function' and value.lower() != 'SecureROM Config'.lower(): + sys.stderr.write('ROM pins should have SecureROM Config column defined\n') + missing_keys.add(key) + + # Some columns are optional + missing_keys -= set(['configurable', 'input_mode']) + # ROM Function is optional if not --rom + if not rom: + missing_keys -= set(['rom']) + # Marked as being unneeded by the per-config column logic + missing_keys -= ignore_missing_keys + + if len(missing_keys) == 0: + missing_keys = None + + return columns_per_target, columns_per_config, missing_keys + + def parse(self, filename, force=False, rom=False, sheet=None): + if filename.endswith('.xlsx'): + if openpyxl is None: + sys.stderr.write('To import Excel sheets, install the openpyxl package\n') + return None, None + if sheet is None: + sys.stderr.write('To import Excel sheets, specify the --sheet option\n') + return None, None + reader = excel_reader(filename, sheet) + if reader is None: + return None, None + else: + reader = csv.reader(open(filename, "rU")) + cnt=0 + row_number = 0 + + # top row has version number + row0 = reader.next() + row_number += 1 + # next non-blank row has headers + while True: + row1 = reader.next() + row_number += 1 + if len(filter(lambda x: len(x.strip()) > 0, row1)) > 0: + break + + version = self.parse_version(row0) + if version is None: + sys.stderr.write('Could not find version in 1st row\n') + return None, None + + try: + columns_per_target, columns_per_config, missing = self.find_headers(row1, rom) + except ParseError as e: + sys.stderr.write('{}\n'.format(e)) + return None, None + + if not missing is None: + missing_options = {"{} ({})".format(col, " or ".join(self.header_name_map[col])) for col in missing} + sys.stderr.write('Missing columns:\n{}\n'.format('\n '.join(missing_options))) + return None, None + + if len(columns_per_config) == 1: + configs = ['all'] + else: + configs = ['ap', 'dev'] + + pinconfigs = {} + for target in self.targets: + pinconfigs[target] = {} + for config in configs: + pinconfigs[target][config] = self.create_pinconfig() + + have_error = False + + for row in reader: + row_number += 1 + if row_is_empty(row): + continue + if row_is_footer(row): + break + + for target, target_columns in columns_per_target.iteritems(): + for config, config_columns in columns_per_config.iteritems(): + columns = {} + columns.update(config_columns) + columns.update(target_columns) + + try: + parsed_props = {prop: row[column].strip() for prop, column in columns.iteritems()} + + # If the optional 'GPIO Configurable' column is present, make sure it says y or yes + try: + if not parsed_props['configurable'].lower() in ('y', 'yes'): + continue + # And then get rid of the column, because the code below can't do anything with it + del parsed_props['configurable'] + except KeyError: + pass + + try: + gpio_id = int(parsed_props['gpio_id']) + except ValueError: + if rom and parsed_props['gpio_id'] == '': + continue + else: + raise ParseError('Invalid GPIO ID "{}"'.format(parsed_props['gpio_id'])) + + pinconfig = pinconfigs[target][config] + try: + pin = pinconfig.get_pin(gpio_id) + except IndexError: + raise ParseError('GPIO ID {} is out of range'.format(gpio_id)) + + if isinstance(pin, ReservedPin): + raise ParseError('GPIO ID {} is reserved pin'.format(gpio_id)) + elif not pin.row_number is None: + raise ParseError('GPIO ID {} redefined (previously defined on row {})'.format(pin.gpio_id, pin.row_number)) + pin.row_number = row_number + + # The setters for all of the columns are predictable based on their name + for prop, value in parsed_props.iteritems(): + if rom: + if prop == 'function': + if parsed_props['rom'].lower() in ('y', 'yes'): + value = parsed_props['function'] + else: + value = 'disabled' + if prop == 'net_name': + if not parsed_props['rom'].lower() in ('y', 'yes'): + value = '' + if prop != 'gpio_id' and prop != 'rom': + setter = getattr(pin, 'set_' + prop) + try: + setter(value) + except KeyError: + raise ParseError('Invalid value "{}" for key {} in column "{}"'.format(value, prop, row1[columns[prop]])) + except ParseError as e: + sys.stderr.write('Row {:3}, Config {:3}: {}\n'.format(row_number, config, e)) + have_error = True + + if not have_error or force: + return version, pinconfigs + else: + return None, None + +def tab_align(data_matrix, tabwidth=8, min_spacing_slack=1, min_column_tabs={}): + def rounduptab(x): + return int(((x + float(tabwidth-1))/tabwidth))*tabwidth + def tab(x): + if x % tabwidth: + return rounduptab(x) + else: + return x+tabwidth + num_cols = max(map(len, data_matrix)) + + # Compute max number of characters seen for each column + max_char_counts = [0]*num_cols + for column, min_width in min_column_tabs.iteritems(): + max_char_counts[column] = min_width*tabwidth + def grow_count(new_row): + for i in range(len(new_row)): + max_char_counts[i] = max(max_char_counts[i], rounduptab(len(new_row[i]) + min_spacing_slack)) + for row in data_matrix: + grow_count(row) + + def pad_tabs(item, required_length): + length = len(item) + tabcount = 0 + while length < required_length: + tabcount+=1 + length=tab(length) + return "%s%s" % (item, '\t'*tabcount) + def format_row(row): + return "".join([pad_tabs(a, b) for (a,b) in zip(row, max_char_counts)]).rstrip() + return [ format_row(x) for x in data_matrix ] + +def print_pinconfigs(target_config_pinconfigs, pinconfig_class, version, radar, copyright, commandline, prefix, rom, header): + array_type = pinconfig_class.array_type + num_domains = len(pinconfig_class.domain_info) + if hasattr(pinconfig_class, 'output_domains'): + if pinconfig_class.output_domains < num_domains: + num_domains = pinconfig_class.output_domains + + targets = sorted(target_config_pinconfigs.keys()) + configs = sorted(target_config_pinconfigs[targets[0]].keys()) + + if header: + pinconfig_prefix = 'gpio_default_cfg' + else: + pinconfig_prefix = 'pinconfig' + + if not prefix is None: + pinconfig_prefix = "{}_{}".format(pinconfig_prefix, prefix) + + if rom: + assert configs == ['all'] + assert len(targets) == 1 + assert len(configs) == 1 + else: + assert configs == ['ap', 'dev'] or configs == ['all'] + + print "/*" + print " * Copyright (C) {} Apple Inc. All rights reserved.".format(copyright) + print " *" + print " * This document is the property of Apple Inc." + print " * It is considered confidential and proprietary." + print " *" + print " * This document may not be reproduced or transmitted in any form," + print " * in whole or in part, without the express written permission of" + print " * Apple Inc." + print " */" + print "" + print "/* THIS FILE IS AUTOMATICALLY GENERATED BY tools/csvtopinconfig.py. DO NOT EDIT!" + print " I/O Spreadsheet version: {}".format(version) + print " I/O Spreadsheet tracker: {}".format(radar) + print + print " Generated with oldskool_csvtopinconfig.py. For new projects, use the regular csvtopinconfig.py" + print " Conversion command: {}".format(commandline) + print "*/" + print "" + + if header: + print "#ifndef __PLATFORM_PINCONFIG_H" + print "#define __PLATFORM_PINCONFIG_H" + print "" + else: + print "#include " + print "#include " + print "#include " + print "#include " + print "#include " + if len(targets) > 1: + print "#include " + print "" + + for target in targets: + for config in configs: + if len(targets) == 1: + if len(configs) == 1: + name = pinconfig_prefix + else: + name = '{}_{}'.format(pinconfig_prefix, config.lower()) + else: + if len(configs) == 1: + name = '{}_{}'.format(pinconfig_prefix, target.lower()) + else: + name = '{}_{}{}'.format(pinconfig_prefix, target.lower(), config.lower()) + print target_config_pinconfigs[target][config].to_pinconfig_struct(name, array_type, num_domains) + + if header: + print "" + print "#endif /* __PLATFORM_PINCONFIG_H */" + else: + print 'struct pinconfig_map {' + print '\tuint32_t board_id;' + print '\tuint32_t board_id_mask;' + print '\tconst {} *pinconfigs[GPIOC_COUNT];'.format(array_type) + print '};' + print '' + print 'static const struct pinconfig_map cfg_map[] = {' + if len(targets) == 1: + if len(configs) == 1: + # just one target and one config, so make a map that spits out the same pinconfig + # for all board IDs + pinconfigs = ', '.join(map(lambda x: '{}_{}'.format(pinconfig_prefix, x), range(num_domains))) + print '\t{{ 0, 0, {{ {} }} }},'.format(pinconfigs) + elif len(configs) == 2: + # One target, but ap/dev configs, so make a map that selects ap/dev based on the lsb + # of the board ID + pinconfigs = ', '.join(map(lambda x: '{}_ap_{}'.format(pinconfig_prefix, x), range(num_domains))) + print '\t{{ 0, 1, {{ {} }} }},'.format(pinconfigs) + pinconfigs = ', '.join(map(lambda x: '{}_dev_{}'.format(pinconfig_prefix, x), range(num_domains))) + print '\t{{ 1, 1, {{ {} }} }},'.format(pinconfigs) + else: + assert False, 'Can\'t handle more than 2 configs per target' + else: + for target in targets: + if len(configs) == 1: + pinconfigs = ', '.join(map(lambda x: '{}_{}_{}'.format(pinconfig_prefix, target.lower(), x), range(num_domains))) + print '\t{{ TARGET_BOARD_ID_{}AP, ~1, {{ {} }} }},'.format(target.upper(), pinconfigs) + elif len(configs) == 2: + pinconfigs = ', '.join(map(lambda x: '{}_{}ap_{}'.format(pinconfig_prefix, target.lower(), x), range(num_domains))) + print '\t{{ TARGET_BOARD_ID_{}AP, ~0, {{ {} }} }},'.format(target.upper(), pinconfigs) + pinconfigs = ', '.join(map(lambda x: '{}_{}dev_{}'.format(pinconfig_prefix, target.lower(), x), range(num_domains))) + print '\t{{ TARGET_BOARD_ID_{}DEV, ~0, {{ {} }} }},'.format(target.upper(), pinconfigs) + else: + assert False, 'Can\'t handle more than 2 configs per target' + print '};' + print '' + if prefix is None: + print 'const {} * target_get_default_gpio_cfg(uint32_t gpioc)'.format(array_type) + else: + print 'const {} * target_get_{}_gpio_cfg(int gpioc)'.format(array_type, prefix) + print '{' + print '\tstatic const struct pinconfig_map *selected_map = NULL;' + print '' + print '\tif (selected_map == NULL) {'; + print '\t\tuint32_t board_id = platform_get_board_id();' + print '\t\tfor (unsigned i = 0; i < sizeof(cfg_map)/sizeof(cfg_map[0]); i++) {' + print '\t\t\tif ((board_id & cfg_map[i].board_id_mask) == cfg_map[i].board_id) {' + print '\t\t\t\tselected_map = &cfg_map[i];' + print '\t\t\t\tbreak;' + print '\t\t\t}' + print '\t\t}' + print '' + print '\t\tif (selected_map == NULL)' + print '\t\t\tpanic("no default pinconfig for board id %u", board_id);' + print '\t}' + print '' + print '\tASSERT(gpioc < GPIOC_COUNT);' + print '\treturn selected_map->pinconfigs[gpioc];' + print '}' + + +def main(): + soc_classes = collections.OrderedDict() + soc_classes['h4a'] = H4APinConfig + soc_classes['h5p'] = H5PPinConfig + soc_classes['h5g'] = H5GPinConfig + soc_classes['alcatraz'] = AlcatrazPinConfig + soc_classes['h6'] = AlcatrazPinConfig + soc_classes['h6p'] = AlcatrazPinConfig + soc_classes['fiji'] = FijiPinConfig + soc_classes['h7p'] = FijiPinConfig + soc_classes['capri'] = CapriPinConfig + soc_classes['h7g'] = CapriPinConfig + soc_classes['m7'] = M7PinConfig + soc_classes['h8p'] = MauiPinConfig + soc_classes['maui'] = MauiPinConfig + soc_classes['h8g'] = ElbaPinConfig + soc_classes['elba'] = ElbaPinConfig + soc_classes['h9p'] = CaymanPinConfig + soc_classes['cayman'] = CaymanPinConfig + soc_classes['m8'] = M8PinConfig + + argparser = argparse.ArgumentParser(description='Converts CSV file to iBoot pinconfig.h format') + argparser.add_argument('--soc', required=True, choices=soc_classes.keys()) + argparser.add_argument('--config-column', type=str, action='append') + argparser.add_argument('--pupd-column', type=str, action='append') + argparser.add_argument('--prefix', type=str, help='prefix for auto-generated variable and function names') + argparser.add_argument('--copyright', type=str, default='YEAR', help='Year(s) to put in copyright notice') + argparser.add_argument('--netname-column', type=str, action='append') + argparser.add_argument('--radar', type=str, help='Link to spreadsheet tracker radar') + argparser.add_argument('--force', action="store_true", help='attempt ouput even when there are parsing errors') + argparser.add_argument('--rom', action="store_true", help='all pins except ROM function pins are disabled') + argparser.add_argument('--header', action="store_true", help='generate a C header file instead of a C source file') + argparser.add_argument('--sheet', default=None, help='sheet to read from when reading Excel files') + argparser.add_argument('filename') + + args = argparser.parse_args() + + pinconfig_class = soc_classes[args.soc] + + per_target_headers = collections.defaultdict(dict) + + if not args.config_column is None: + for item in map(lambda x: x.split(":"), args.config_column): + if len(item) == 1: + target = None + column = item[0] + elif len(item) == 2: + target = item[0].upper() + column = item[1] + else: + sys.stderr.write("Invalid config-column parameter\n") + sys.exit(1) + if 'function' in per_target_headers[target]: + sys.stderr.write("Duplicate target in --config-column: \"{}\"".format(target)) + sys.exit(1) + per_target_headers[target]['function'] = column + + if not args.pupd_column is None: + for item in map(lambda x: x.split(":"), args.pupd_column): + if len(item) == 1: + target = None + column = item[0] + elif len(item) == 2: + target = item[0].upper() + column = item[1] + else: + sys.stderr.write("Invalid pupd-column parameter\n") + sys.exit(1) + if 'pupd' in per_target_headers[target]: + sys.stderr.write("Duplicate target in --pupd-column: \"{}\"".format(target)) + sys.exit(1) + per_target_headers[target]['pupd'] = column + + if not args.netname_column is None: + for item in map(lambda x: x.split(":"), args.netname_column): + if len(item) == 1: + target = None + column = item[0] + elif len(item) == 2: + target = item[0].upper() + column = item[1] + else: + sys.stderr.write("Invalid netname-column parameter\n") + sys.exit(1) + if 'net_name' in per_target_headers[target]: + sys.stderr.write("Duplicate target in --netname-column: \"{}\"".format(target)) + sys.exit(1) + per_target_headers[target]['net_name'] = column + + if not per_target_headers: + per_target_headers[None] = {} + + parser = CSVParser(pinconfig_class, per_target_headers) + version, pinconfigs = parser.parse(args.filename, force=args.force, rom=args.rom, sheet=args.sheet) + if pinconfigs is None: + sys.exit(1) + + def pretty_arg(arg): + if arg == args.filename: + return '' + else: + return pipes.quote(arg) + commandline = './tools/oldskool_csvtopinconfig.py {}'.format(' '.join(pretty_arg(a) for a in sys.argv[1:])) + + print_pinconfigs(pinconfigs, pinconfig_class=pinconfig_class, version=version, radar=args.radar, copyright=args.copyright, commandline=commandline, prefix=args.prefix, rom=args.rom, header=args.header) + +if __name__ == '__main__': + main() diff --git a/tools/parse_release_log.py b/tools/parse_release_log.py new file mode 100644 index 0000000..a869225 --- /dev/null +++ b/tools/parse_release_log.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +import re +import os +import hashlib +import hmac +import argparse +import sys + +argparser = argparse.ArgumentParser(description='Parses obfuscated logging from iBoot release builds') +argparser.add_argument('--src', required=True, help='iBoot source tree corresponding to log') +argparser.add_argument('-v', '--verbose', action='store_true', default=False, help='Attempts to load log string from source file instead of simplying printing the source file and line number') +argparser.add_argument('filename', nargs='?', default=None, help='File to read log from (omit for stdin)') + +args = argparser.parse_args() + +id_file_map = {} + +directory = args.src + +base_hmac = hmac.new('obfuscation of filename for release build logging', '', hashlib.sha1) + +for (path, dirnames, filenames) in os.walk(directory): + # strip the part of the pathname we supplied off the pathname + shortened_path = path[len(directory)+1:] + # don't iterate into paths we don't care about + try: + dirnames.remove('.svn') + except ValueError: + pass + # only look at .c and .cpp files in the build directory, be more permissive elsewhere + if shortened_path.startswith('build/'): + filenames = [x for x in filenames if x.endswith('.c') or x.endswith('.cpp')] + for filename in filenames: + full_path = os.path.join(shortened_path, filename) + + current_hmac = base_hmac.copy() + current_hmac.update(full_path) + + file_id = current_hmac.hexdigest()[:16] + + if file_id in id_file_map and id_file_map[file_id] != full_path: + print 'Warning: Files "{}" and "{}" both have the same ID {}'.format(full_path, id_file_map[file_id], file_id) + else: + id_file_map[file_id] = full_path + +file_cache = {} +def get_src_line(filename, line_number): + + if filename not in file_cache: + file_path = os.path.join(directory, filename) + with open(file_path) as f: + lines = [x.strip() for x in f] + file_cache[filename] = lines + + return file_cache[filename][line_number - 1] + +def parse_src_line(src_line): + result = re.match(r'dprintf\s*\(\s*[a-zA-Z0-9_]+,\s*"([^"]*)".*', src_line) + + if result is not None: + return result.group(1) + else: + return src_line + +def parse_log(f): + log_re = re.compile(r'^(.*\|)?([0-9a-f]{16}):(\d+)$') + for line in f: + line = line.rstrip() + result = log_re.match(line) + if result is not None: + timestamp = result.group(1) or '' + file_id = result.group(2) + line_number = int(result.group(3)) + if file_id in id_file_map: + filename = id_file_map[file_id] + if args.verbose: + src_line = get_src_line(filename, line_number) + print '{}{} [{}:{}]'.format(timestamp, parse_src_line(src_line), filename, line_number) + else: + print '{}{}:{}'.format(timestamp, filename, line_number) + continue + print line + +if args.filename is not None: + with open(args.filename) as f: + parse_log(f) +else: + parse_log(sys.stdin) diff --git a/tools/pctrace-decoder b/tools/pctrace-decoder new file mode 100644 index 0000000..92826be --- /dev/null +++ b/tools/pctrace-decoder @@ -0,0 +1,193 @@ +#!/usr/bin/tclsh +# +# Takes a PC trace from simulation and annotates it with function/line number information +# +# The PC trace is assumed to have one PC per line; the first likely-looking number on each line is assumed to be the PC. +# +# usage: pctrace-decoder +# + +package require log +package require fileutil + +################################################################################ +# utilities + +proc fatal {msg} { + global errorInfo + + ::log::log error $msg +# if {$errorInfo != ""} { +# ::log::log debug $errorInfo +# } + exit 1 +} + + +################################################################################ +proc generateBatch {pctrace batchfile} { + + ::log::log debug "parsing trace $pctrace" + + ::fileutil::foreachLine inputLine $pctrace { + foreach tok $inputLine { + switch -glob $tok { + [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] { + set addresses($tok) "" + break + } + + 0x[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] { + # hex number + set addresses([string range $tok 2 end]) "" + break + } + + default { + continue + } + } + } + } + + if {![array exists addresses]} { + fatal "no recognisable data in '$pctrace' (maybe need a smarter parser?)" + } + + set batch [open $batchfile w] + + ::log::log debug "generating batchfile $batchfile" + foreach address [array names addresses] { + puts $batch [format "echo &%s&" $address] + puts $batch [format "info line *0x%s" $address] + } + + close $batch +} + +################################################################################ +proc runBatch {symfile batchfile batchresult} { + + ::log::log debug "generating symbol data $batchresult" + + if {[catch {exec gdb -n -batch -x $batchfile $symfile > $batchresult} result]} { + fatal "gdb failed: $result" + } +} + +################################################################################ +proc annotateTrace {pctrace batchresult traceoutput condensed} { + + ::log::log debug "reading batch results" + + ::fileutil::foreachLine inputLine $batchresult { + + if {[scan $inputLine "&%\[^&\]&Line %d of \"%\[^\"\]\" starts at address %x <%\[^>\]> and ends at %x <%\[^>\]>" key lineNumber fileName startAddr startSym endAddr endSym] == 7} { + if {[scan $startSym "%\[^+\]+%x" sym addr] == 2} { + set startSym $sym + } + if {[scan $endSym "%\[^+\]+%x" sym addr] == 2} { + set endSym $sym + } + + if {$startSym == $endSym} { + set addrinfo($key) [format "%s:%s:%d" $fileName $startSym $lineNumber] + } else { + set addrinfo($key) [format "%s:%s/%s:%d" $fileName $startSym $endSym $lineNumber] + } + continue + } + + if {[scan $inputLine "&%\[^&\]&No line number information available for address %x <%\[^>\]>" key address addrSym] == 3} { + if {[scan $addrSym "%\[^+\]+%x" sym addr] == 2} { + set addrSym $sym + } + set addrinfo($key) [format "%s" $addrSym] + continue + } + + log::log warning "unexpected batch result '$inputLine'" + } + + set out [open $traceoutput w] + set cout [open $condensed w] + ::log::log debug "annotating trace" + + set lastSuffix "" + ::fileutil::foreachLine inputLine $pctrace { + set address "" + foreach tok $inputLine { + switch -glob $tok { + [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] { + set address $tok + break + } + + 0x[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] { + # hex number + set address [string range $tok 2 end] + break + } + + default { + continue + } + } + } + if {($address != "") && ([array names addrinfo -exact $address] != "")} { + set suffix $addrinfo($address) + if {$suffix != $lastSuffix} { + puts $cout $suffix + set lastSuffix $suffix + } + } else { + set suffix "" + } + puts $out [format "%s -- %s" $inputLine $suffix] + } + close $out + close $cout +} + +################################################################################ + +proc main {} { + + global argv + + # logging + ::log::lvSuppress error 0 + ::log::lvSuppress warning 0 + ::log::lvSuppress notice 0 + ::log::lvSuppress debug 1 + + set pctrace [lindex $argv 0] + set symfile [lindex $argv 1] + + if {![file readable $pctrace]} { + fatal "missing or unreadable PC trace file '$pctrace'" + } + if {![file readable $symfile]} { + fatal "missing or unreadable symbol file '$symfile'" + } + + # generate a gdb batch file + ::log::log notice "generating gdb batch from PC trace..." + set batchfile [::fileutil::tempfile ptrace_decoder_batch_] + generateBatch $pctrace $batchfile + + # invoke gdb against the batch file + ::log::log notice "processing batch..." + set batchresult [::fileutil::tempfile ptrace_decoder_result_] + runBatch $symfile $batchfile $batchresult + file delete $batchfile + + # annotate the pctrace with results from the result file + ::log::log notice "annotating trace..." + set traceoutput [format "%s.annotated" $pctrace] + set condensed [format "%s.condensed" $pctrace] + annotateTrace $pctrace $batchresult $traceoutput $condensed + file delete $batchresult + ::log::log notice "Annotated output in '$traceoutput', condensed output in '$condensed'" +} +main diff --git a/tools/pickfiles.sh b/tools/pickfiles.sh new file mode 100644 index 0000000..fa306e6 --- /dev/null +++ b/tools/pickfiles.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +# Find .d files that are produced by compilation and produce a list of all the files they represent +# + +# Find source and headers that were built +rm -f built.list built.tmp +for dfile in `find build -name "*.d"`; do + echo "parsing $dfile" + cat $dfile | tr : \\n | tail +2 | tr -d \\ | tr ' ' \\n | grep \^\[a-z\] >> built.tmp +done +cat built.tmp | sort | uniq > built.list + +# Find all sources +echo "finding base sources" +rm -f all.list +find . -name "*.[chS]" | cut -c 3-1000 > all.list + +# Make a list of what's not used +rm -f delete.list +for file in `cat all.list`; do + /bin/echo -n "checking for $file ... " + if grep -q $file built.list; then + echo "found, keeping" + else + # handle exceptions + case $file in + platform/defaults/template.c ) echo "protected" ;; + platform/generic/template.c ) echo "protected" ;; + tools/bhc.c ) echo "protected" ;; + + * ) + echo "not found, deleting" + echo $file >> delete.list + ;; + esac + fi +done + +# Delete unwanted files +for file in `cat delete.list`; do + rm $file +done + +rm -f built.list built.tmp all.list delete.list diff --git a/tools/ppnfw_asn1.rb b/tools/ppnfw_asn1.rb new file mode 100644 index 0000000..1f0f693 --- /dev/null +++ b/tools/ppnfw_asn1.rb @@ -0,0 +1,21 @@ +#!/usr/bin/ruby + +require 'openssl' + +if ARGV.length < 2 + print File.basename(__FILE__) + " ppn-fw= [ ppn-fw-args= ]\n" + exit 1 +end + +outFn = ARGV[0] +inPairs = ARGV[1..-1] + +blob = OpenSSL::ASN1::Sequence([], 1, :IMPLICIT, :APPLICATION) +inPairs.each do |pair| + key, val = pair.split('=', 2) + + blob.value << OpenSSL::ASN1::UTF8String(key) + blob.value << OpenSSL::ASN1::OctetString(File.read(val)) +end + +File.open(outFn, 'w') {|f| f.write(blob.to_der) } diff --git a/tools/rom-release b/tools/rom-release new file mode 100644 index 0000000..937d294 --- /dev/null +++ b/tools/rom-release @@ -0,0 +1,45 @@ +#!/usr/bin/perl -w + +if (@ARGV < 1) { + print "USAGE: rom_release \n"; + exit(0); +} + +$soc = shift @ARGV; +$soc = lc($soc); + +print "Building SecureROM\n"; +system("sudo ~rc/bin/buildit -arch armv7 -project rom -noverify . -- APPLICATIONS=SecureROM TARGETS=$soc > /tmp/buildit.log 2> /tmp/buildit.error"); + +print "Generating tarball\n"; +$user = getlogin(); +system("sudo chown -R $user:apple_ga /tmp/rom.roots"); +system("sudo chmod -R oga+w /tmp/rom.roots/rom"); +system("tar -C /tmp -zcvf rom.roots.tgz rom.roots 2> /tmp/rom.tgz.log"); +system("mv ./rom.roots.tgz /tmp"); + +$dropbox = "/Volumes/CoreOS/SecureROM-Drops"; + +print "Copying to DropBox\n"; +$seq = 1; +if (-d "$dropbox/$soc") { + system("ls -ltU ". "$dropbox/$soc" . " | awk '{ if(substr(\$NF,11,1) > max) {max=substr(\$NF,11,1);} } END {print max\}' > /tmp/awk.out"); + open(FILE, ") { + chomp($_); + $seq = $_; + $seq = $seq + 1; + } +} +else { + print "First release, setting up directory structure\n"; + system("mkdir $dropbox/$soc"); +} +system("mkdir $dropbox/$soc/SecureROM-$seq"); +system("cp /tmp/rom.roots.tgz $dropbox/$soc/SecureROM-$seq"); + +print "Moving files\n"; +system("cp /tmp/rom.roots/rom~sym/build/"."$soc"."si-SecureROM-RELEASE/SecureROM.bin $dropbox/$soc/SecureROM-$seq/"); +system("cp /tmp/rom.roots/rom~sym/build/"."$soc"."si-SecureROM-RELEASE/SecureROM.sys $dropbox/$soc/SecureROM-$seq/"); + +print "Done.\n"; diff --git a/tools/scrub-SecureROM.sh b/tools/scrub-SecureROM.sh new file mode 100644 index 0000000..4bbea38 --- /dev/null +++ b/tools/scrub-SecureROM.sh @@ -0,0 +1,183 @@ +#!/bin/sh +# +# After pickfiles, scrub the iBoot tree of anything not relevant to the current secure ROM +# + +supported_platforms="t8002 t8010" +unwanted_dirs_files_list="target docs build BuildiBoot.sh" + +if [ $# -ne "1" ] ; then + echo "USAGE: scrub_SecureROM " + exit +fi + +found=0 +for word in $supported_platforms; do + if [ $1 == $word ] ; then + found=1 + fi +done + +if [ $found != 1 ]; then + echo "Unsupported platform $1" + exit +fi + +# init variables +securerom_platform=$1 +new_working_dir="/tmp/iBoot.$securerom_platform.scrubbed" + +# setup new working dir +rm -rf $new_working_dir +cp -R $PWD $new_working_dir + +# switch to new working dir +pushd $new_working_dir > /dev/null + +# other apps +for dir in `ls -d apps/*`; do + case $dir in + apps/SecureROM ) + ;; + * ) + echo removing directory $dir + rm -rf $dir + ;; + esac +done + +# other platforms +for dir in `ls -d platform/*`; do + case $dir in + platform/generic ) + ;; + platform/defaults ) + ;; + platform/$securerom_platform ) + ;; + * ) + echo removing directory $dir + rm -rf $dir + ;; + esac +done + +# all targets +rm -rf targets + +# whitelist Makefiles +for mk in `find makefiles -type f`; do + case $mk in + makefiles/build.mk ) + ;; + makefiles/config.mk ) + ;; + makefiles/device_map.mk ) + ;; + makefiles/headers.mk ) + ;; + makefiles/lib.mk ) + ;; + makefiles/libraries.mk ) + ;; + makefiles/macros.mk ) + ;; + makefiles/main.mk ) + ;; + makefiles/main-nested-module.mk ) + ;; + makefiles/macros.mk ) + ;; + makefiles/tools.mk ) + ;; + makefiles/SecureROM.mk ) + ;; + * ) + echo removing file $mk + rm -f $mk + ;; + esac +done + +# whitelist tools +for tool in `find tools -type f`; do + case $tool in + tools/check_liblist.py ) + ;; + tools/lldb_init_iboot.py ) + ;; + tools/lldb_os_iboot.py ) + ;; + tools/generate_debug_hashes.py ) + ;; + tools/macho_post_process.py ) + ;; + tools/macho.py ) + ;; + * ) + echo removing file $tool + rm -f $tool + ;; + esac +done + +# anything referring to other architectures +for word in $supported_platforms; do + if [ $word != $securerom_platform ] ; then + find . -name "*$word*" -delete + fi +done + +# version control directories +rm -rf `find . -name ".svn" -type dir` + +# strip bad words +for word in $supported_platforms; do + if [ $word != $securerom_platform ] ; then + files=`find . -type f | xargs grep -l $word` + for file in $files; do + tfile=`mktemp scrub.XXXX` + sed -e "s/$word//g" < $file > $tfile + cat $tfile > $file + rm $tfile + done + fi + + # strip irrelevant test files + dir="apps/SecureROM/tests/images_$word" + if [ -d "$dir" ] ; then + echo removing directory $dir + rm -r "$dir" + fi +done + + +# rules.mk with no adjacent sources +for mk in `find . -name rules.mk`; do + dir=`dirname $mk` + files=`find $dir -name "*.[chS]"` + if [ -z "$files" ]; then + echo removing file $mk + rm -f $mk + fi +done + +# empty directories +for dir in `find -d . -type dir`; do + files=`ls -1 $dir` + if [ -z "$files" ]; then + echo removing empty directory $dir + rmdir $dir + fi +done + +# remove all unwanted directories +for word in $unwanted_dirs_files_list; do + echo removing directory $word + rm -rf $word +done + +# back to original working dir +popd > /dev/null + +echo "Scrubbed iBoot -> $new_working_dir" diff --git a/tools/symbolicate-panic b/tools/symbolicate-panic new file mode 100644 index 0000000..2e47cc7 --- /dev/null +++ b/tools/symbolicate-panic @@ -0,0 +1,100 @@ +#!/usr/bin/tclsh +################################################################################ +# +# Given a path to a mach-o binary and input that includes stack backtraces in +# the format printed by iBoot's arch_backtrace_task, annotate the backtraces +# with symbol names +# +# Lines in the backtrace have the form +# +# +# or +# +# + +proc main { } { + global argv + + set binfile [lindex $argv 0] + if {![file readable $binfile]} { + puts "can't read '$binfile'" + exit 1 + } + + # run nm and parse the output + do_nm $binfile + + # read input lines + while {[gets stdin line] != -1} { + puts -nonewline $line + if {([scan $line " %s %x %x%n" pad pc lr len] == 4) || ([scan $line " %x %x%n" pc lr len] == 3)} { + if {$len == [string length $line]} { + set detail [find_sym $pc] + if {$detail != ""} { + puts -nonewline " ($detail)" + } + } + } + puts "" + } +} + +proc do_nm {binfile} { + + global symbols + global symbol_index + +# puts "reading symbols from $binfile" + + set lines [exec nm -n $binfile] + + foreach {_addr type _sym} $lines { + set sym [string range $_sym 1 end] + set addr "0x$_addr" + set symbols($addr) $sym + } + set symbol_index [lsort -integer [array names symbols]] + +# puts "[llength [array names symbols]] symbols" +} + +proc find_sym {pc} { + + global symbols + global symbol_index + +# puts "looking for $pc" + + set candidate [lindex $symbol_index 0] + + # if the pc is before the first symbol, it's not in the object file + if {$pc < $candidate} { +# puts "too low (less than $candidate)" + return "" + } + + foreach addr [lrange $symbol_index 1 end] { + +# puts "trying $addr" + + # if the next symbol is above the pc, the candidate is where we are + if {$pc < $addr} { + break + } + + # advance the candidate + set candidate $addr + } + + # the last symbol is a sentinel, if the PC is above it, it's not in the object file + if {$pc > $addr} { +# puts "too high" + return "" + } + + set key [format 0x%08x $candidate] + set offset [format 0x%x [expr $addr - $key]] + return "$symbols($key)+$offset" +} + +main